From 4c7f8900f1d8a0e464e7092f132a7e93f7c20f2f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sat, 23 Feb 2008 07:06:55 +0100 Subject: x86: stackprotector & PARAVIRT fix on paravirt enabled 64-bit kernels the paravirt ops do function calls themselves - which is bad with the stackprotector - for example pda_init() loads 0 into %gs and then does MSR_GS_BASE write (which modifies gs.base) - but that MSR write is a function call on paravirt, which with stackprotector tries to read the stack canary from the PDA ... crashing the bootup. the solution was suggested by Arjan van de Ven: to exclude paravirt.c from stackprotector, too many lowlevel functionality is in it. It's not like we'll have paravirt functions with character arrays on their stack anyway... Signed-off-by: Arjan van de Ven Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 5e618c3b472..8161e5a91ca 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -14,6 +14,7 @@ nostackp := $(call cc-option, -fno-stack-protector) CFLAGS_vsyscall_64.o := $(PROFILING) -g0 $(nostackp) CFLAGS_hpet.o := $(nostackp) CFLAGS_tsc_64.o := $(nostackp) +CFLAGS_paravirt.o := $(nostackp) obj-y := process_$(BITS).o signal_$(BITS).o entry_$(BITS).o obj-y += traps_$(BITS).o irq_$(BITS).o -- cgit From e00320875d0cc5f8099a7227b2f25fbb3231268d Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 14 Feb 2008 08:48:23 +0100 Subject: x86: fix stackprotector canary updates during context switches fix a bug noticed and fixed by pageexec@freemail.hu. if built with -fstack-protector-all then we'll have canary checks built into the __switch_to() function. That does not work well with the canary-switching code there: while we already use the %rsp of the new task, we still call __switch_to() whith the previous task's canary value in the PDA, hence the __switch_to() ssp prologue instructions will store the previous canary. Then we update the PDA and upon return from __switch_to() the canary check triggers and we panic. so update the canary after we have called __switch_to(), where we are at the same stackframe level as the last stackframe of the next (and now freshly current) task. Note: this means that we call __switch_to() [and its sub-functions] still with the old canary, but that is not a problem, both the previous and the next task has a high-quality canary. The only (mostly academic) disadvantage is that the canary of one task may leak onto the stack of another task, increasing the risk of information leaks, were an attacker able to read the stack of specific tasks (but not that of others). To solve this we'll have to reorganize the way we switch tasks, and move the PDA setting into the switch_to() assembly code. That will happen in another patch. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/process_64.c | 1 - include/asm-x86/pda.h | 2 -- include/asm-x86/system.h | 6 +++++- include/linux/sched.h | 3 +-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index e2319f39988..d8640388039 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -640,7 +640,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) write_pda(kernelstack, (unsigned long)task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET); #ifdef CONFIG_CC_STACKPROTECTOR - write_pda(stack_canary, next_p->stack_canary); /* * Build time only check to make sure the stack_canary is at * offset 40 in the pda; this is a gcc ABI requirement diff --git a/include/asm-x86/pda.h b/include/asm-x86/pda.h index 101fb9e1195..62b734986a4 100644 --- a/include/asm-x86/pda.h +++ b/include/asm-x86/pda.h @@ -16,11 +16,9 @@ struct x8664_pda { unsigned long oldrsp; /* 24 user rsp for system call */ int irqcount; /* 32 Irq nesting counter. Starts -1 */ unsigned int cpunumber; /* 36 Logical CPU number */ -#ifdef CONFIG_CC_STACKPROTECTOR unsigned long stack_canary; /* 40 stack canary value */ /* gcc-ABI: this canary MUST be at offset 40!!! */ -#endif char *irqstackptr; unsigned int __softirq_pending; unsigned int __nmi_count; /* number of NMI on this CPUs */ diff --git a/include/asm-x86/system.h b/include/asm-x86/system.h index a2f04cd79b2..172f5418509 100644 --- a/include/asm-x86/system.h +++ b/include/asm-x86/system.h @@ -92,6 +92,8 @@ do { \ ".globl thread_return\n" \ "thread_return:\n\t" \ "movq %%gs:%P[pda_pcurrent],%%rsi\n\t" \ + "movq %P[task_canary](%%rsi),%%r8\n\t" \ + "movq %%r8,%%gs:%P[pda_canary]\n\t" \ "movq %P[thread_info](%%rsi),%%r8\n\t" \ LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \ "movq %%rax,%%rdi\n\t" \ @@ -103,7 +105,9 @@ do { \ [ti_flags] "i" (offsetof(struct thread_info, flags)), \ [tif_fork] "i" (TIF_FORK), \ [thread_info] "i" (offsetof(struct task_struct, stack)), \ - [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \ + [task_canary] "i" (offsetof(struct task_struct, stack_canary)),\ + [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)), \ + [pda_canary] "i" (offsetof(struct x8664_pda, stack_canary))\ : "memory", "cc" __EXTRA_CLOBBER) #endif diff --git a/include/linux/sched.h b/include/linux/sched.h index 5395a6176f4..d6a51515878 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1096,10 +1096,9 @@ struct task_struct { pid_t pid; pid_t tgid; -#ifdef CONFIG_CC_STACKPROTECTOR /* Canary value for the -fstack-protector gcc feature */ unsigned long stack_canary; -#endif + /* * pointers to (original) parent process, youngest child, younger sibling, * older sibling, respectively. (p->father can be replaced with -- cgit From ce22bd92cba0958e052cb1ce0f89f1d3a02b60a7 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Mon, 12 May 2008 15:44:31 +0200 Subject: x86: setup stack canary for the idle threads The idle threads for non-boot CPUs are a bit special in how they are created; the result is that these don't have the stack canary set up properly in their PDA. Easiest fix is to just always set the PDA up correctly when entering the idle thread; this is a NOP for the boot cpu. Signed-off-by: Arjan van de Ven Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/process_64.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index d8640388039..9e69e223023 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -146,6 +146,15 @@ static inline void play_dead(void) void cpu_idle(void) { current_thread_info()->status |= TS_POLLING; + +#ifdef CONFIG_CC_STACKPROTECTOR + /* + * If we're the non-boot CPU, nothing set the PDA stack + * canary up for us. This is as good a place as any for + * doing that. + */ + write_pda(stack_canary, current->stack_canary); +#endif /* endless idle loop with no priority at all */ while (1) { tick_nohz_stop_sched_tick(); -- cgit From 7e09b2a02dae4616a5a26000169964b32f86cd35 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 14 Feb 2008 09:22:34 +0100 Subject: x86: fix canary of the boot CPU's idle task the boot CPU's idle task has a zero stackprotector canary value. this is a special task that is never forked, so the fork code does not randomize its canary. Do it when we hit cpu_idle(). Academic sidenote: this means that the early init code runs with a zero canary and hence the canary becomes predictable for this short, boot-only amount of time. Although attack vectors against early init code are very rare, it might make sense to move this initialization to an earlier point. (to one of the early init functions that never return - such as start_kernel()) Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/process_64.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 9e69e223023..d4c7ac7aa43 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -150,9 +150,13 @@ void cpu_idle(void) #ifdef CONFIG_CC_STACKPROTECTOR /* * If we're the non-boot CPU, nothing set the PDA stack - * canary up for us. This is as good a place as any for - * doing that. + * canary up for us - and if we are the boot CPU we have + * a 0 stack canary. This is a good place for updating + * it, as we wont ever return from this function (so the + * invalid canaries already on the stack wont ever + * trigger): */ + current->stack_canary = get_random_int(); write_pda(stack_canary, current->stack_canary); #endif /* endless idle loop with no priority at all */ -- cgit From 517a92c4e19fcea815332d3155e9fb7723251274 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 14 Feb 2008 09:02:13 +0100 Subject: panic: print more informative messages on stackprotect failure pointed out by pageexec@freemail.hu: we just simply panic() when there's a stackprotector attack - giving the attacked person no information about what kernel code the attack went against. print out the attacked function. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/panic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/panic.c b/kernel/panic.c index 425567f45b9..f236001cc4d 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -327,7 +327,8 @@ EXPORT_SYMBOL(warn_on_slowpath); */ void __stack_chk_fail(void) { - panic("stack-protector: Kernel stack is corrupted"); + panic("stack-protector: Kernel stack is corrupted in: %p\n", + __builtin_return_address(0)); } EXPORT_SYMBOL(__stack_chk_fail); #endif -- cgit From 5cb273013e182a35e7db614d3e20a144cba71e53 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 14 Feb 2008 09:07:01 +0100 Subject: panic: print out stacktrace if DEBUG_BUGVERBOSE if CONFIG_DEBUG_BUGVERBOSE is set then the user most definitely wanted to see as much information about kernel crashes as possible - so give them at least a stack dump. this is particularly useful for stackprotector related panics, where the stacktrace can give us the exact location of the (attempted) attack. Pointed out by pageexec@freemail.hu in the stackprotector breakage threads. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/panic.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/panic.c b/kernel/panic.c index f236001cc4d..17aad578a2f 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -80,6 +80,9 @@ NORET_TYPE void panic(const char * fmt, ...) vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf); +#ifdef CONFIG_DEBUG_BUGVERBOSE + dump_stack(); +#endif bust_spinlocks(0); /* -- cgit From 72370f2a5b227bd3817593a6b15ea3f53f51dfcb Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 13 Feb 2008 16:15:34 +0100 Subject: x86: if stackprotector is enabled, thn use stack-protector-all by default also enable the rodata and nx tests. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/Kconfig | 3 ++- arch/x86/Kconfig.debug | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index dcbec34154c..83d8392c133 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1142,7 +1142,7 @@ config SECCOMP config CC_STACKPROTECTOR bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" - depends on X86_64 && EXPERIMENTAL && BROKEN + depends on X86_64 help This option turns on the -fstack-protector GCC feature. This feature puts, at the beginning of critical functions, a canary @@ -1159,6 +1159,7 @@ config CC_STACKPROTECTOR config CC_STACKPROTECTOR_ALL bool "Use stack-protector for all functions" depends on CC_STACKPROTECTOR + default y help Normally, GCC only inserts the canary value protection for functions that use large-ish on-stack buffers. By enabling diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index ac1e31ba479..b5c5b55d043 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -102,6 +102,7 @@ config DIRECT_GBPAGES config DEBUG_RODATA_TEST bool "Testcase for the DEBUG_RODATA feature" depends on DEBUG_RODATA + default y help This option enables a testcase for the DEBUG_RODATA feature as well as for the change_page_attr() infrastructure. -- cgit From 9b5609fd773e6ac0b1d6d6e1bf68f32cca64e06b Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 14 Feb 2008 09:41:09 +0100 Subject: stackprotector: include files create for core kernel files to include. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/stackprotector.h | 4 ++++ include/linux/stackprotector.h | 8 ++++++++ init/main.c | 1 + 3 files changed, 13 insertions(+) create mode 100644 include/asm-x86/stackprotector.h create mode 100644 include/linux/stackprotector.h diff --git a/include/asm-x86/stackprotector.h b/include/asm-x86/stackprotector.h new file mode 100644 index 00000000000..dcac7a6bdba --- /dev/null +++ b/include/asm-x86/stackprotector.h @@ -0,0 +1,4 @@ +#ifndef _ASM_STACKPROTECTOR_H +#define _ASM_STACKPROTECTOR_H 1 + +#endif diff --git a/include/linux/stackprotector.h b/include/linux/stackprotector.h new file mode 100644 index 00000000000..d3e8bbe602f --- /dev/null +++ b/include/linux/stackprotector.h @@ -0,0 +1,8 @@ +#ifndef _LINUX_STACKPROTECTOR_H +#define _LINUX_STACKPROTECTOR_H 1 + +#ifdef CONFIG_CC_STACKPROTECTOR +# include +#endif + +#endif diff --git a/init/main.c b/init/main.c index f7fb20021d4..a84322ca64a 100644 --- a/init/main.c +++ b/init/main.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include -- cgit From 18aa8bb12dcb10adc3d7c9d69714d53667c0ab7f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 14 Feb 2008 09:42:02 +0100 Subject: stackprotector: add boot_init_stack_canary() add the boot_init_stack_canary() and make the secondary idle threads use it. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/process_64.c | 6 ++---- include/asm-x86/stackprotector.h | 20 ++++++++++++++++++++ include/linux/stackprotector.h | 4 ++++ 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index d4c7ac7aa43..5107cb214c7 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -147,7 +147,6 @@ void cpu_idle(void) { current_thread_info()->status |= TS_POLLING; -#ifdef CONFIG_CC_STACKPROTECTOR /* * If we're the non-boot CPU, nothing set the PDA stack * canary up for us - and if we are the boot CPU we have @@ -156,9 +155,8 @@ void cpu_idle(void) * invalid canaries already on the stack wont ever * trigger): */ - current->stack_canary = get_random_int(); - write_pda(stack_canary, current->stack_canary); -#endif + boot_init_stack_canary(); + /* endless idle loop with no priority at all */ while (1) { tick_nohz_stop_sched_tick(); diff --git a/include/asm-x86/stackprotector.h b/include/asm-x86/stackprotector.h index dcac7a6bdba..0f91f7a2688 100644 --- a/include/asm-x86/stackprotector.h +++ b/include/asm-x86/stackprotector.h @@ -1,4 +1,24 @@ #ifndef _ASM_STACKPROTECTOR_H #define _ASM_STACKPROTECTOR_H 1 +/* + * Initialize the stackprotector canary value. + * + * NOTE: this must only be called from functions that never return, + * and it must always be inlined. + */ +static __always_inline void boot_init_stack_canary(void) +{ + /* + * If we're the non-boot CPU, nothing set the PDA stack + * canary up for us - and if we are the boot CPU we have + * a 0 stack canary. This is a good place for updating + * it, as we wont ever return from this function (so the + * invalid canaries already on the stack wont ever + * trigger): + */ + current->stack_canary = get_random_int(); + write_pda(stack_canary, current->stack_canary); +} + #endif diff --git a/include/linux/stackprotector.h b/include/linux/stackprotector.h index d3e8bbe602f..422e71aafd0 100644 --- a/include/linux/stackprotector.h +++ b/include/linux/stackprotector.h @@ -3,6 +3,10 @@ #ifdef CONFIG_CC_STACKPROTECTOR # include +#else +static inline void boot_init_stack_canary(void) +{ +} #endif #endif -- cgit From 420594296838fdc9a674470d710cda7d1487f9f4 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 14 Feb 2008 09:44:08 +0100 Subject: x86: fix the stackprotector canary of the boot CPU Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/process_64.c | 1 + include/linux/stackprotector.h | 4 ++++ init/main.c | 6 ++++++ 3 files changed, 11 insertions(+) diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 5107cb214c7..cce47f7fbf2 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -16,6 +16,7 @@ #include +#include #include #include #include diff --git a/include/linux/stackprotector.h b/include/linux/stackprotector.h index 422e71aafd0..6f3e54c704c 100644 --- a/include/linux/stackprotector.h +++ b/include/linux/stackprotector.h @@ -1,6 +1,10 @@ #ifndef _LINUX_STACKPROTECTOR_H #define _LINUX_STACKPROTECTOR_H 1 +#include +#include +#include + #ifdef CONFIG_CC_STACKPROTECTOR # include #else diff --git a/init/main.c b/init/main.c index a84322ca64a..b44e4eb0f5e 100644 --- a/init/main.c +++ b/init/main.c @@ -546,6 +546,12 @@ asmlinkage void __init start_kernel(void) unwind_init(); lockdep_init(); debug_objects_early_init(); + + /* + * Set up the the initial canary ASAP: + */ + boot_init_stack_canary(); + cgroup_init_early(); local_irq_disable(); -- cgit From 960a672bd9f1ec06e8f197cf81a50fd07ea02e7f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 14 Feb 2008 09:56:04 +0100 Subject: x86: stackprotector: mix TSC to the boot canary mix the TSC to the boot canary. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/asm-x86/stackprotector.h | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/include/asm-x86/stackprotector.h b/include/asm-x86/stackprotector.h index 0f91f7a2688..3baf7ad89be 100644 --- a/include/asm-x86/stackprotector.h +++ b/include/asm-x86/stackprotector.h @@ -1,6 +1,8 @@ #ifndef _ASM_STACKPROTECTOR_H #define _ASM_STACKPROTECTOR_H 1 +#include + /* * Initialize the stackprotector canary value. * @@ -9,16 +11,28 @@ */ static __always_inline void boot_init_stack_canary(void) { + u64 canary; + u64 tsc; + /* * If we're the non-boot CPU, nothing set the PDA stack * canary up for us - and if we are the boot CPU we have * a 0 stack canary. This is a good place for updating * it, as we wont ever return from this function (so the * invalid canaries already on the stack wont ever - * trigger): + * trigger). + * + * We both use the random pool and the current TSC as a source + * of randomness. The TSC only matters for very early init, + * there it already has some randomness on most systems. Later + * on during the bootup the random pool has true entropy too. */ - current->stack_canary = get_random_int(); - write_pda(stack_canary, current->stack_canary); + get_random_bytes(&canary, sizeof(canary)); + tsc = __native_read_tsc(); + canary += tsc + (tsc << 32UL); + + current->stack_canary = canary; + write_pda(stack_canary, canary); } #endif -- cgit From 113c5413cf9051cc50b88befdc42e3402bb92115 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 14 Feb 2008 10:36:03 +0100 Subject: x86: unify stackprotector features streamline the stackprotector features under a single option and make the stronger feature the one accessible. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/Kconfig | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 83d8392c133..0cd1695c24f 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1140,13 +1140,17 @@ config SECCOMP If unsure, say Y. Only embedded should say N here. +config CC_STACKPROTECTOR_ALL + bool + config CC_STACKPROTECTOR bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" depends on X86_64 + select CC_STACKPROTECTOR_ALL help - This option turns on the -fstack-protector GCC feature. This - feature puts, at the beginning of critical functions, a canary - value on the stack just before the return address, and validates + This option turns on the -fstack-protector GCC feature. This + feature puts, at the beginning of functions, a canary value on + the stack just before the return address, and validates the value just before actually returning. Stack based buffer overflows (that need to overwrite this return address) now also overwrite the canary, which gets detected and the attack is then @@ -1154,16 +1158,8 @@ config CC_STACKPROTECTOR This feature requires gcc version 4.2 or above, or a distribution gcc with the feature backported. Older versions are automatically - detected and for those versions, this configuration option is ignored. - -config CC_STACKPROTECTOR_ALL - bool "Use stack-protector for all functions" - depends on CC_STACKPROTECTOR - default y - help - Normally, GCC only inserts the canary value protection for - functions that use large-ish on-stack buffers. By enabling - this option, GCC will be asked to do this for ALL functions. + detected and for those versions, this configuration option is + ignored. (and a warning is printed during bootup) source kernel/Kconfig.hz -- cgit From 54371a43a66f4477889769b4fa00df936855dc8f Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Fri, 15 Feb 2008 15:33:12 -0800 Subject: x86: add CONFIG_CC_STACKPROTECTOR self-test This patch adds a simple self-test capability to the stackprotector feature. The test deliberately overflows a stack buffer and then checks if the canary trap function gets called. Signed-off-by: Arjan van de Ven Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/panic.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/kernel/panic.c b/kernel/panic.c index 17aad578a2f..50cf9257b23 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -324,14 +324,82 @@ EXPORT_SYMBOL(warn_on_slowpath); #endif #ifdef CONFIG_CC_STACKPROTECTOR + +static unsigned long __stack_check_testing; +/* + * Self test function for the stack-protector feature. + * This test requires that the local variable absolutely has + * a stack slot, hence the barrier()s. + */ +static noinline void __stack_chk_test_func(void) +{ + unsigned long foo; + barrier(); + /* + * we need to make sure we're not about to clobber the return address, + * while real exploits do this, it's unhealthy on a running system. + * Besides, if we would, the test is already failed anyway so + * time to pull the emergency brake on it. + */ + if ((unsigned long)__builtin_return_address(0) == + *(((unsigned long *)&foo)+1)) { + printk(KERN_ERR "No -fstack-protector-stack-frame!\n"); + return; + } +#ifdef CONFIG_FRAME_POINTER + /* We also don't want to clobber the frame pointer */ + if ((unsigned long)__builtin_return_address(0) == + *(((unsigned long *)&foo)+2)) { + printk(KERN_ERR "No -fstack-protector-stack-frame!\n"); + return; + } +#endif + barrier(); + if (current->stack_canary == *(((unsigned long *)&foo)+1)) + *(((unsigned long *)&foo)+1) = 0; + else + printk(KERN_ERR "No -fstack-protector canary found\n"); + barrier(); +} + +static int __stack_chk_test(void) +{ + printk(KERN_INFO "Testing -fstack-protector-all feature\n"); + __stack_check_testing = (unsigned long)&__stack_chk_test_func; + __stack_chk_test_func(); + if (__stack_check_testing) { + printk(KERN_ERR "-fstack-protector-all test failed\n"); + WARN_ON(1); + } + return 0; +} /* * Called when gcc's -fstack-protector feature is used, and * gcc detects corruption of the on-stack canary value */ void __stack_chk_fail(void) { + if (__stack_check_testing == (unsigned long)&__stack_chk_test_func) { + long delta; + + delta = (unsigned long)__builtin_return_address(0) - + __stack_check_testing; + /* + * The test needs to happen inside the test function, so + * check if the return address is close to that function. + * The function is only 2 dozen bytes long, but keep a wide + * safety margin to avoid panic()s for normal users regardless + * of the quality of the compiler. + */ + if (delta >= 0 && delta <= 400) { + __stack_check_testing = 0; + return; + } + } panic("stack-protector: Kernel stack is corrupted in: %p\n", __builtin_return_address(0)); } EXPORT_SYMBOL(__stack_chk_fail); + +late_initcall(__stack_chk_test); #endif -- cgit From b719ac56c0032bc1602914c6ea70b0f1581b08c7 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Mon, 14 Apr 2008 10:03:50 -0700 Subject: panic.c: fix whitespace additions trivial: remove white space addition in stack protector Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- kernel/panic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/panic.c b/kernel/panic.c index 50cf9257b23..866be9b72e4 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -341,14 +341,14 @@ static noinline void __stack_chk_test_func(void) * Besides, if we would, the test is already failed anyway so * time to pull the emergency brake on it. */ - if ((unsigned long)__builtin_return_address(0) == + if ((unsigned long)__builtin_return_address(0) == *(((unsigned long *)&foo)+1)) { printk(KERN_ERR "No -fstack-protector-stack-frame!\n"); return; } #ifdef CONFIG_FRAME_POINTER /* We also don't want to clobber the frame pointer */ - if ((unsigned long)__builtin_return_address(0) == + if ((unsigned long)__builtin_return_address(0) == *(((unsigned long *)&foo)+2)) { printk(KERN_ERR "No -fstack-protector-stack-frame!\n"); return; -- cgit From b40a4392a3c262e0d1b5379b4e142a8eefa63439 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Fri, 18 Apr 2008 06:16:45 -0700 Subject: stackprotector: turn not having the right gcc into a #warning If the user selects the stack-protector config option, but does not have a gcc that has the right bits enabled (for example because it isn't build with a glibc that supports TLS, as is common for cross-compilers, but also because it may be too old), then the runtime test fails right now. This patch adds a warning message for this scenario. This warning accomplishes two goals 1) the user is informed that the security option he selective isn't available 2) the user is suggested to turn of the CONFIG option that won't work for him, and would make the runtime test fail anyway. Signed-off-by: Arjan van de Ven Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/Makefile | 2 +- kernel/panic.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 3cff3c894cf..c3e0eeeb1dd 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -73,7 +73,7 @@ else stackp := $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh stackp-$(CONFIG_CC_STACKPROTECTOR) := $(shell $(stackp) \ - "$(CC)" -fstack-protector ) + "$(CC)" "-fstack-protector -DGCC_HAS_SP" ) stackp-$(CONFIG_CC_STACKPROTECTOR_ALL) += $(shell $(stackp) \ "$(CC)" -fstack-protector-all ) diff --git a/kernel/panic.c b/kernel/panic.c index 866be9b72e4..6729e3f4ebc 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -325,6 +325,9 @@ EXPORT_SYMBOL(warn_on_slowpath); #ifdef CONFIG_CC_STACKPROTECTOR +#ifndef GCC_HAS_SP +#warning You have selected the CONFIG_CC_STACKPROTECTOR option, but the gcc used does not support this. +#endif static unsigned long __stack_check_testing; /* * Self test function for the stack-protector feature. -- cgit From 7c9f8861e6c9c839f913e49b98c3854daca18f27 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Tue, 22 Apr 2008 16:38:23 -0500 Subject: stackprotector: use canary at end of stack to indicate overruns at oops time (Updated with a common max-stack-used checker that knows about the canary, as suggested by Joe Perches) Use a canary at the end of the stack to clearly indicate at oops time whether the stack has ever overflowed. This is a very simple implementation with a couple of drawbacks: 1) a thread may legitimately use exactly up to the last word on the stack -- but the chances of doing this and then oopsing later seem slim 2) it's possible that the stack usage isn't dense enough that the canary location could get skipped over -- but the worst that happens is that we don't flag the overrun -- though this happens fairly often in my testing :( With the code in place, an intentionally-bloated stack oops might do: BUG: unable to handle kernel paging request at ffff8103f84cc680 IP: [] update_curr+0x9a/0xa8 PGD 8063 PUD 0 Thread overran stack or stack corrupted Oops: 0000 [1] SMP CPU 0 ... ... unless the stack overrun is so bad that it corrupts some other thread. Signed-off-by: Eric Sandeen Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/mm/fault.c | 7 +++++++ include/linux/magic.h | 1 + include/linux/sched.h | 13 +++++++++++++ kernel/exit.c | 5 +---- kernel/fork.c | 5 +++++ kernel/sched.c | 7 +------ 6 files changed, 28 insertions(+), 10 deletions(-) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index fd7e1798c75..1f524df68b9 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -581,6 +582,8 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) unsigned long address; int write, si_code; int fault; + unsigned long *stackend; + #ifdef CONFIG_X86_64 unsigned long flags; #endif @@ -850,6 +853,10 @@ no_context: show_fault_oops(regs, error_code, address); + stackend = end_of_stack(tsk); + if (*stackend != STACK_END_MAGIC) + printk(KERN_ALERT "Thread overran stack, or stack corrupted\n"); + tsk->thread.cr2 = address; tsk->thread.trap_no = 14; tsk->thread.error_code = error_code; diff --git a/include/linux/magic.h b/include/linux/magic.h index 1fa0c2ce4de..74e68e20116 100644 --- a/include/linux/magic.h +++ b/include/linux/magic.h @@ -42,4 +42,5 @@ #define FUTEXFS_SUPER_MAGIC 0xBAD1DEA #define INOTIFYFS_SUPER_MAGIC 0x2BAD1DEA +#define STACK_END_MAGIC 0x57AC6E9D #endif /* __LINUX_MAGIC_H__ */ diff --git a/include/linux/sched.h b/include/linux/sched.h index d6a51515878..c5181e77f30 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1969,6 +1969,19 @@ static inline unsigned long *end_of_stack(struct task_struct *p) extern void thread_info_cache_init(void); +#ifdef CONFIG_DEBUG_STACK_USAGE +static inline unsigned long stack_not_used(struct task_struct *p) +{ + unsigned long *n = end_of_stack(p); + + do { /* Skip over canary */ + n++; + } while (!*n); + + return (unsigned long)n - (unsigned long)end_of_stack(p); +} +#endif + /* set thread flags in other task's structures * - see asm/thread_info.h for TIF_xxxx flags available */ diff --git a/kernel/exit.c b/kernel/exit.c index 8f6185e69b6..fb8de6cbf2c 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -899,12 +899,9 @@ static void check_stack_usage(void) { static DEFINE_SPINLOCK(low_water_lock); static int lowest_to_date = THREAD_SIZE; - unsigned long *n = end_of_stack(current); unsigned long free; - while (*n == 0) - n++; - free = (unsigned long)n - (unsigned long)end_of_stack(current); + free = stack_not_used(current); if (free >= lowest_to_date) return; diff --git a/kernel/fork.c b/kernel/fork.c index 19908b26cf8..d428336e7aa 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -54,6 +54,7 @@ #include #include #include +#include #include #include @@ -186,6 +187,8 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) { struct task_struct *tsk; struct thread_info *ti; + unsigned long *stackend; + int err; prepare_to_copy(orig); @@ -211,6 +214,8 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) goto out; setup_thread_stack(tsk, orig); + stackend = end_of_stack(tsk); + *stackend = STACK_END_MAGIC; /* for overflow detection */ #ifdef CONFIG_CC_STACKPROTECTOR tsk->stack_canary = get_random_int(); diff --git a/kernel/sched.c b/kernel/sched.c index cfa222a9153..a964ed94509 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -5748,12 +5748,7 @@ void sched_show_task(struct task_struct *p) printk(KERN_CONT " %016lx ", thread_saved_pc(p)); #endif #ifdef CONFIG_DEBUG_STACK_USAGE - { - unsigned long *n = end_of_stack(p); - while (!*n) - n++; - free = (unsigned long)n - (unsigned long)end_of_stack(p); - } + free = stack_not_used(p); #endif printk(KERN_CONT "%5lu %5d %6d\n", free, task_pid_nr(p), task_pid_nr(p->real_parent)); -- cgit From aa92db14270b79f0f91a9060b547a46f9e2639da Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Fri, 11 Jul 2008 05:09:55 -0700 Subject: stackprotector: better self-test check stackprotector functionality by manipulating the canary briefly during bootup. far more robust than trying to overflow the stack. (which is architecture dependent, etc.) Signed-off-by: Ingo Molnar --- kernel/panic.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/kernel/panic.c b/kernel/panic.c index 6729e3f4ebc..28153aec710 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -347,22 +347,18 @@ static noinline void __stack_chk_test_func(void) if ((unsigned long)__builtin_return_address(0) == *(((unsigned long *)&foo)+1)) { printk(KERN_ERR "No -fstack-protector-stack-frame!\n"); - return; } #ifdef CONFIG_FRAME_POINTER /* We also don't want to clobber the frame pointer */ if ((unsigned long)__builtin_return_address(0) == *(((unsigned long *)&foo)+2)) { printk(KERN_ERR "No -fstack-protector-stack-frame!\n"); - return; } #endif - barrier(); - if (current->stack_canary == *(((unsigned long *)&foo)+1)) - *(((unsigned long *)&foo)+1) = 0; - else + if (current->stack_canary != *(((unsigned long *)&foo)+1)) printk(KERN_ERR "No -fstack-protector canary found\n"); - barrier(); + + current->stack_canary = ~current->stack_canary; } static int __stack_chk_test(void) @@ -373,7 +369,8 @@ static int __stack_chk_test(void) if (__stack_check_testing) { printk(KERN_ERR "-fstack-protector-all test failed\n"); WARN_ON(1); - } + }; + current->stack_canary = ~current->stack_canary; return 0; } /* -- cgit From af9ff7868f0f76d3364351b1641b9dfa99588e77 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Sat, 12 Jul 2008 09:36:38 -0700 Subject: x86: simplify stackprotector self-check Clean up the code by removing no longer needed code; make sure the pda is updated and kept in sync Signed-off-by: Arjan van de Ven Signed-off-by: Ingo Molnar --- include/asm-x86/pda.h | 1 + kernel/panic.c | 29 +++++++---------------------- 2 files changed, 8 insertions(+), 22 deletions(-) diff --git a/include/asm-x86/pda.h b/include/asm-x86/pda.h index 62b734986a4..a5ff5bb7629 100644 --- a/include/asm-x86/pda.h +++ b/include/asm-x86/pda.h @@ -131,4 +131,5 @@ do { \ #define PDA_STACKOFFSET (5*8) +#define refresh_stack_canary() write_pda(stack_canary, current->stack_canary) #endif diff --git a/kernel/panic.c b/kernel/panic.c index 28153aec710..87445a894c3 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -328,37 +328,21 @@ EXPORT_SYMBOL(warn_on_slowpath); #ifndef GCC_HAS_SP #warning You have selected the CONFIG_CC_STACKPROTECTOR option, but the gcc used does not support this. #endif + static unsigned long __stack_check_testing; + /* * Self test function for the stack-protector feature. * This test requires that the local variable absolutely has - * a stack slot, hence the barrier()s. + * a stack slot. */ static noinline void __stack_chk_test_func(void) { - unsigned long foo; - barrier(); - /* - * we need to make sure we're not about to clobber the return address, - * while real exploits do this, it's unhealthy on a running system. - * Besides, if we would, the test is already failed anyway so - * time to pull the emergency brake on it. - */ - if ((unsigned long)__builtin_return_address(0) == - *(((unsigned long *)&foo)+1)) { - printk(KERN_ERR "No -fstack-protector-stack-frame!\n"); - } -#ifdef CONFIG_FRAME_POINTER - /* We also don't want to clobber the frame pointer */ - if ((unsigned long)__builtin_return_address(0) == - *(((unsigned long *)&foo)+2)) { - printk(KERN_ERR "No -fstack-protector-stack-frame!\n"); - } -#endif - if (current->stack_canary != *(((unsigned long *)&foo)+1)) - printk(KERN_ERR "No -fstack-protector canary found\n"); + unsigned long dummy_buffer[64]; /* force gcc to use the canary */ current->stack_canary = ~current->stack_canary; + refresh_stack_canary(); + dummy_buffer[3] = 1; /* fool gcc into keeping the variable */ } static int __stack_chk_test(void) @@ -371,6 +355,7 @@ static int __stack_chk_test(void) WARN_ON(1); }; current->stack_canary = ~current->stack_canary; + refresh_stack_canary(); return 0; } /* -- cgit From 4f962d4d65923d7b722192e729840cfb79af0a5a Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 13 Jul 2008 21:42:44 +0200 Subject: stackprotector: remove self-test turns out gcc generates such stackprotector-failure sequences in certain circumstances: movq -8(%rbp), %rax # D.16032, xorq %gs:40, %rax #, jne .L17 #, leave ret .L17: call __stack_chk_fail # .size __stack_chk_test_func, .-__stack_chk_test_func .section .init.text,"ax",@progbits .type panic_setup, @function panic_setup: pushq %rbp # note that there's no jump back to the failing context after the call to __stack_chk_fail - i.e. it has a ((noreturn)) attribute. Which is fair enough in the normal case but kills the self-test. (as we cannot reliably return in the self-test) Signed-off-by: Ingo Molnar --- kernel/panic.c | 47 ----------------------------------------------- 1 file changed, 47 deletions(-) diff --git a/kernel/panic.c b/kernel/panic.c index 87445a894c3..c35c9eca3eb 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -329,62 +329,15 @@ EXPORT_SYMBOL(warn_on_slowpath); #warning You have selected the CONFIG_CC_STACKPROTECTOR option, but the gcc used does not support this. #endif -static unsigned long __stack_check_testing; - -/* - * Self test function for the stack-protector feature. - * This test requires that the local variable absolutely has - * a stack slot. - */ -static noinline void __stack_chk_test_func(void) -{ - unsigned long dummy_buffer[64]; /* force gcc to use the canary */ - - current->stack_canary = ~current->stack_canary; - refresh_stack_canary(); - dummy_buffer[3] = 1; /* fool gcc into keeping the variable */ -} - -static int __stack_chk_test(void) -{ - printk(KERN_INFO "Testing -fstack-protector-all feature\n"); - __stack_check_testing = (unsigned long)&__stack_chk_test_func; - __stack_chk_test_func(); - if (__stack_check_testing) { - printk(KERN_ERR "-fstack-protector-all test failed\n"); - WARN_ON(1); - }; - current->stack_canary = ~current->stack_canary; - refresh_stack_canary(); - return 0; -} /* * Called when gcc's -fstack-protector feature is used, and * gcc detects corruption of the on-stack canary value */ void __stack_chk_fail(void) { - if (__stack_check_testing == (unsigned long)&__stack_chk_test_func) { - long delta; - - delta = (unsigned long)__builtin_return_address(0) - - __stack_check_testing; - /* - * The test needs to happen inside the test function, so - * check if the return address is close to that function. - * The function is only 2 dozen bytes long, but keep a wide - * safety margin to avoid panic()s for normal users regardless - * of the quality of the compiler. - */ - if (delta >= 0 && delta <= 400) { - __stack_check_testing = 0; - return; - } - } panic("stack-protector: Kernel stack is corrupted in: %p\n", __builtin_return_address(0)); } EXPORT_SYMBOL(__stack_chk_fail); -late_initcall(__stack_chk_test); #endif -- cgit From 2eda344546caaf9168e778a4007f4609e95106e0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 11 Aug 2008 10:18:39 +0200 Subject: ALSA: hda - Add a new function to seek for a codec ID Gateway notebooks have their ID inside codec vendor ID, not at PCI ID. Due to that, model auto-detection were not possible with the standard seek method. This is what is found at lspci -vnn: 00:14.2 Audio device [0403]: ATI Technologies Inc SB450 HDA Audio [1002:437b] (rev 01) Subsystem: ATI Technologies Inc SB450 HDA Audio [1002:437b] Yet, autodetection is possible, since the codec properly reflects the vendor at the Subsystem ID: $ cat /proc/asound/card0/codec#0 |head -4 Codec: SigmaTel STAC9250 Address: 0 Vendor Id: 0x83847634 Subsystem Id: 0x107b0367 This patch adds a new autodetection function that seeks for codec subsystem ID. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++ sound/pci/hda/hda_local.h | 3 +++ 2 files changed, 64 insertions(+) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 004344825e9..9c1af0101dd 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2704,6 +2704,67 @@ int snd_hda_check_board_config(struct hda_codec *codec, } EXPORT_SYMBOL_HDA(snd_hda_check_board_config); +/** + * snd_hda_check_board_codec_sid_config - compare the current codec + subsystem ID with the + config table + + This is important for Gateway notebooks with SB450 HDA Audio + where the vendor ID of the PCI device is: + ATI Technologies Inc SB450 HDA Audio [1002:437b] + and the vendor/subvendor are found only at the codec. + + * @codec: the HDA codec + * @num_configs: number of config enums + * @models: array of model name strings + * @tbl: configuration table, terminated by null entries + * + * Compares the modelname or PCI subsystem id of the current codec with the + * given configuration table. If a matching entry is found, returns its + * config value (supposed to be 0 or positive). + * + * If no entries are matching, the function returns a negative value. + */ +int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, + int num_configs, const char **models, + const struct snd_pci_quirk *tbl) +{ + const struct snd_pci_quirk *q; + + /* Search for codec ID */ + for (q = tbl; q->subvendor; q++) { + unsigned long vendorid = (q->subdevice) | (q->subvendor << 16); + + if (vendorid == codec->subsystem_id) + break; + } + + if (!q->subvendor) + return -1; + + tbl = q; + + if (tbl->value >= 0 && tbl->value < num_configs) { +#ifdef CONFIG_SND_DEBUG_DETECT + char tmp[10]; + const char *model = NULL; + if (models) + model = models[tbl->value]; + if (!model) { + sprintf(tmp, "#%d", tbl->value); + model = tmp; + } + snd_printdd(KERN_INFO "hda_codec: model '%s' is selected " + "for config %x:%x (%s)\n", + model, tbl->subvendor, tbl->subdevice, + (tbl->name ? tbl->name : "Unknown device")); +#endif + return tbl->value; + } + return -1; +} +EXPORT_SYMBOL_HDA(snd_hda_check_board_codec_sid_config); + /** * snd_hda_add_new_ctls - create controls from the array * @codec: the HDA codec diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 6f2fe0f9fdd..1dd8716c387 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -296,6 +296,9 @@ void snd_print_pcm_bits(int pcm, char *buf, int buflen); int snd_hda_check_board_config(struct hda_codec *codec, int num_configs, const char **modelnames, const struct snd_pci_quirk *pci_list); +int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, + int num_configs, const char **models, + const struct snd_pci_quirk *tbl); int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew); -- cgit From 9cb36c2afc298a2f2085ae0071924b7e3f55e72d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 11 Aug 2008 10:18:39 +0200 Subject: ALSA: patch_sigmatel: Add missing Gateway entries and autodetection Gateway autodetection and entries are incomplete. This patch adds the entries found at the .INI file for their driver version 5.10.5082.0. It also uses the proper code to seek for notebook ID, since this is based on codec subsystem ID on those devices. This should provide a proper pinup for several gateways notebooks: Gateway M465-E Notebook [Part #1008637] Gateway M465-G Notebook [Part #1008667] Gateway NX260X Notebook [Part #1008794] Gateway NX100X Notebook [Part #1008798] Gateway E-100M Notebook [Part #1008799] Gateway E-100M G Notebook [Part #1008800] Gateway M255-E Notebook [Part #1008801] Gateway M255-G Notebook [Part #1008803] Gateway M285-E Convertible Notebook [Part #1008804] Gateway M285-G Convertible Notebook [Part #1008805] Gateway CX210S Convertible Notebook [Part #1008807] Gateway CX210X Convertible Notebook [Part #1008808] Gateway E-100M SB Notebook [Part #1008973] Gateway M255-E SB Notebook [Part #1008989] Gateway M285-E SB Convertible Notebook [Part #1008990] Gateway M465-E Notebook [Part #1009022] Gateway CX2724 Convertible Notebook [Part #1009036] Gateway MX1025 Notebook [Part #1009046] Gateway CX2720 Convertible Notebook [Part #1009063] Gateway CX2724h Convertible Notebook [Part #1009089] Gateway MX1023 Notebook [Part #1009097] Gateway MX1023h Notebook [Part #1009098] Gateway NX260X Notebook [Part #1009112] Gateway E-100M Notebook [Part #1009126] Gateway MX7533 Notebook [Part #1009146] [Part #1009163] Gateway CX210X Convertible Notebook [Part #1009346] Gateway NX570X Notebook [Part #1009442] Gateway NX570X Notebook [Part #1009448] Gateway NX270S Notebook [Part #1009550] Gateway MX6448 Notebook [Part #1013912R] Gateway MX6453 Notebook [Part #1013913R] Gateway MX6216 Notebook [Part #1013916R] Gateway MX6931 Notebook [Part #1013918R] Gateway CX2726 Convertible Notebook [Part #1013921R] Gateway MP8708 Notebook [Part #1013924R] Gateway MX6446 Notebook [Part #1013927R] Gateway MX6930 Notebook [Part #1013928R] Gateway MX6447 Notebook [Part #1013932R] Gateway MX6454 Notebook [Part #1013943R] Gateway MX6439 Notebook [Part #1013947R] [Part #1013955R] [Part #1013971R] Gateway MX6930h Notebook [Part #1013973R] [Part #1013974R] [Part #1013975R] Gateway MX6955 Notebook [Part #1014028R] Gateway MX6956 Notebook [Part #1014033R] Gateway MX6959 Notebook [Part #1014061R] Gateway MX6957 Notebook [Part #1014065R] Gateway MX6960 Notebook [Part #1014068R] Gateway MX6958 Notebook [Part #1014072R] Gateway NX570X Notebook [Part #1014077R] Gateway NX570XL Notebook [Part #1014078R] Gateway NX570QS Notebook [Part #1014079R] Gateway MX6961 Notebook [Part #1014080R] [Part #1014106R] Gateway MX6961h Notebook [Part #1014112R] Gateway NX270S Notebook [Part #1014120R] Gateway MX6431 Notebook [Part #1014121R] Gateway MX8710 Notebook [Part #2905895R] Gateway MX3702 Notebook [Part #2905898R] Blade-K8F GW UMA Single Core Motherboard w/RS485M and 1394 - Quanta (FRU) [Part #4006133R] Since some entries conflict with existing pinups, I'm providing a separate patch to fix those entries. Tested only with Gateway MX6453. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 89 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 81 insertions(+), 8 deletions(-) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 9e07f44ab28..e70ef050530 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -93,7 +93,13 @@ enum { enum { STAC_925x_REF, + STAC_M1, + STAC_M1_2, + STAC_M2, STAC_M2_2, + STAC_M3, + STAC_M5, + STAC_M6, STAC_MA6, STAC_PA6, STAC_925x_MODELS @@ -1600,11 +1606,40 @@ static unsigned int ref925x_pin_configs[8] = { 0x90a70320, 0x02214210, 0x01019020, 0x9033032e, }; +static unsigned int stac925xM1_pin_configs[8] = { + 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, + 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, +}; +static unsigned int stac925xM1_2_pin_configs[8] = { + 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, + 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, +}; +static unsigned int stac925xM2_pin_configs[8] = { + 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, + 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, +}; + +static unsigned int stac925xM3_pin_configs[8] = { + 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, + 0x40a000f0, 0x90100210, 0x400003f1, 0x503303f3, +}; +static unsigned int stac925xM5_pin_configs[8] = { + 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, + 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, +}; + +/* Original M6 entry at .ini file */ +static unsigned int stac925xM6_pin_configs[8] = { + 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, + 0x40a000f0, 0x90100210, 0x400003f1, 0x90330320, +}; + static unsigned int stac925x_MA6_pin_configs[8] = { 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, 0x90a70320, 0x90100211, 0x400003f1, 0x9033032e, }; +/* This entry should be M2 */ static unsigned int stac925x_PA6_pin_configs[8] = { 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, 0x50a103f0, 0x90100211, 0x400003f1, 0x9033032e, @@ -1617,27 +1652,55 @@ static unsigned int stac925xM2_2_pin_configs[8] = { static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = { [STAC_REF] = ref925x_pin_configs, + [STAC_M1] = stac925xM1_pin_configs, + [STAC_M1_2] = stac925xM1_2_pin_configs, + [STAC_M2] = stac925xM2_pin_configs, [STAC_M2_2] = stac925xM2_2_pin_configs, + [STAC_M3] = stac925xM3_pin_configs, + [STAC_M5] = stac925xM5_pin_configs, + [STAC_M6] = stac925xM6_pin_configs, [STAC_MA6] = stac925x_MA6_pin_configs, [STAC_PA6] = stac925x_PA6_pin_configs, }; static const char *stac925x_models[STAC_925x_MODELS] = { [STAC_REF] = "ref", + [STAC_M1] = "m1", + [STAC_M1_2] = "m1-2", + [STAC_M2] = "m2", [STAC_M2_2] = "m2-2", - [STAC_MA6] = "m6", + [STAC_M3] = "m3", + [STAC_M5] = "m5", + [STAC_M6] = "m6", + [STAC_MA6] = "ma6", [STAC_PA6] = "pa6", }; -static struct snd_pci_quirk stac925x_cfg_tbl[] = { - /* SigmaTel reference board */ - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF), - SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF), +static struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = { SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_REF), SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_REF), + SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_MA6), SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_PA6), - SND_PCI_QUIRK(0x1002, 0x437b, "Gateway MX6453", STAC_M2_2), + SND_PCI_QUIRK(0x107b, 0x0367, "Gateway MX6453", STAC_M1_2), + + /* Not sure about the brand name for those */ + SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M1), + SND_PCI_QUIRK(0x107b, 0x0507, "Gateway mobile", STAC_M3), + SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M6), + SND_PCI_QUIRK(0x107b, 0x0685, "Gateway mobile", STAC_M2_2), + + {} /* terminator */ +}; + +static struct snd_pci_quirk stac925x_cfg_tbl[] = { + /* SigmaTel reference board */ + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF), + SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF), + + /* Default table for unknown ID */ + SND_PCI_QUIRK(0x1002, 0x437b, "Gateway mobile", STAC_M2_2), + {} /* terminator */ }; @@ -4371,12 +4434,22 @@ static int patch_stac925x(struct hda_codec *codec) codec->spec = spec; spec->num_pins = ARRAY_SIZE(stac925x_pin_nids); spec->pin_nids = stac925x_pin_nids; - spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS, + + /* Check first for codec ID */ + spec->board_config = snd_hda_check_board_codec_sid_config(codec, + STAC_925x_MODELS, + stac925x_models, + stac925x_codec_id_cfg_tbl); + + /* Now checks for PCI ID, if codec ID is not found */ + if (spec->board_config < 0) + spec->board_config = snd_hda_check_board_config(codec, + STAC_925x_MODELS, stac925x_models, stac925x_cfg_tbl); again: if (spec->board_config < 0) { - snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x," + snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x," "using BIOS defaults\n"); err = stac92xx_save_bios_config_regs(codec); } else -- cgit From 58eec4235d63e07b98544527e031e7ae807e15df Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 11 Aug 2008 10:18:39 +0200 Subject: ALSA: hda - More fixes on Gateway entries Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 72 +++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 39 deletions(-) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index e70ef050530..c05d4643afd 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -55,7 +55,8 @@ enum { STAC_9200_DELL_M25, STAC_9200_DELL_M26, STAC_9200_DELL_M27, - STAC_9200_GATEWAY, + STAC_9200_M4, + STAC_9200_M4_2, STAC_9200_PANASONIC, STAC_9200_MODELS }; @@ -100,8 +101,6 @@ enum { STAC_M3, STAC_M5, STAC_M6, - STAC_MA6, - STAC_PA6, STAC_925x_MODELS }; @@ -1375,7 +1374,16 @@ static unsigned int ref9200_pin_configs[8] = { 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, }; -/* +static unsigned int gateway9200_m4_pin_configs[8] = { + 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010, + 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3, +}; +static unsigned int gateway9200_m4_2_pin_configs[8] = { + 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010, + 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3, +}; + +/* STAC 9200 pin configs for 102801A8 102801DE @@ -1505,6 +1513,8 @@ static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = { [STAC_9200_DELL_M25] = dell9200_m25_pin_configs, [STAC_9200_DELL_M26] = dell9200_m26_pin_configs, [STAC_9200_DELL_M27] = dell9200_m27_pin_configs, + [STAC_9200_M4] = gateway9200_m4_pin_configs, + [STAC_9200_M4_2] = gateway9200_m4_2_pin_configs, [STAC_9200_PANASONIC] = ref9200_pin_configs, }; @@ -1521,7 +1531,8 @@ static const char *stac9200_models[STAC_9200_MODELS] = { [STAC_9200_DELL_M25] = "dell-m25", [STAC_9200_DELL_M26] = "dell-m26", [STAC_9200_DELL_M27] = "dell-m27", - [STAC_9200_GATEWAY] = "gateway", + [STAC_9200_M4] = "gateway-m4", + [STAC_9200_M4_2] = "gateway-m4-2", [STAC_9200_PANASONIC] = "panasonic", }; @@ -1591,11 +1602,9 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = { /* Panasonic */ SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC), /* Gateway machines needs EAPD to be set on resume */ - SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_GATEWAY), - SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*", - STAC_9200_GATEWAY), - SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707", - STAC_9200_GATEWAY), + SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_M4), + SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*", STAC_9200_M4_2), + SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707", STAC_9200_M4_2), /* OQO Mobile */ SND_PCI_QUIRK(0x1106, 0x3288, "OQO Model 2", STAC_9200_OQO), {} /* terminator */ @@ -1610,46 +1619,37 @@ static unsigned int stac925xM1_pin_configs[8] = { 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, }; + static unsigned int stac925xM1_2_pin_configs[8] = { 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, }; + static unsigned int stac925xM2_pin_configs[8] = { 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, }; +static unsigned int stac925xM2_2_pin_configs[8] = { + 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, + 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, +}; + static unsigned int stac925xM3_pin_configs[8] = { 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 0x40a000f0, 0x90100210, 0x400003f1, 0x503303f3, }; + static unsigned int stac925xM5_pin_configs[8] = { 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, }; -/* Original M6 entry at .ini file */ static unsigned int stac925xM6_pin_configs[8] = { 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 0x40a000f0, 0x90100210, 0x400003f1, 0x90330320, }; -static unsigned int stac925x_MA6_pin_configs[8] = { - 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, - 0x90a70320, 0x90100211, 0x400003f1, 0x9033032e, -}; - -/* This entry should be M2 */ -static unsigned int stac925x_PA6_pin_configs[8] = { - 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, - 0x50a103f0, 0x90100211, 0x400003f1, 0x9033032e, -}; - -static unsigned int stac925xM2_2_pin_configs[8] = { - 0x40c003f3, 0x424503f2, 0x04180011, 0x02a19020, - 0x50a103f0, 0x90100212, 0x400003f1, 0x9033032e, -}; - static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = { [STAC_REF] = ref925x_pin_configs, [STAC_M1] = stac925xM1_pin_configs, @@ -1659,8 +1659,6 @@ static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = { [STAC_M3] = stac925xM3_pin_configs, [STAC_M5] = stac925xM5_pin_configs, [STAC_M6] = stac925xM6_pin_configs, - [STAC_MA6] = stac925x_MA6_pin_configs, - [STAC_PA6] = stac925x_PA6_pin_configs, }; static const char *stac925x_models[STAC_925x_MODELS] = { @@ -1672,24 +1670,19 @@ static const char *stac925x_models[STAC_925x_MODELS] = { [STAC_M3] = "m3", [STAC_M5] = "m5", [STAC_M6] = "m6", - [STAC_MA6] = "ma6", - [STAC_PA6] = "pa6", }; static struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = { - SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_REF), - SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_REF), - - SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_MA6), - SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_PA6), + SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2), + SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5), + SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1), + SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_M2), SND_PCI_QUIRK(0x107b, 0x0367, "Gateway MX6453", STAC_M1_2), - /* Not sure about the brand name for those */ SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M1), SND_PCI_QUIRK(0x107b, 0x0507, "Gateway mobile", STAC_M3), SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M6), SND_PCI_QUIRK(0x107b, 0x0685, "Gateway mobile", STAC_M2_2), - {} /* terminator */ }; @@ -4399,7 +4392,8 @@ static int patch_stac9200(struct hda_codec *codec) spec->num_adcs = 1; spec->num_pwrs = 0; - if (spec->board_config == STAC_9200_GATEWAY || + if (spec->board_config == STAC_9200_M4 || + spec->board_config == STAC_9200_M4_2 || spec->board_config == STAC_9200_OQO) spec->init = stac9200_eapd_init; else -- cgit From bc22c17e12c130dc929218a95aa347e0f3fd05dc Mon Sep 17 00:00:00 2001 From: Alain Knaff Date: Sun, 4 Jan 2009 22:46:16 +0100 Subject: bzip2/lzma: library support for gzip, bzip2 and lzma decompression Impact: Replaces inflate.c with a wrapper around zlib_inflate; new library code This is the first part of the bzip2/lzma patch The bzip patch is based on an idea by Christian Ludwig, includes support for compressing the kernel with bzip2 or lzma rather than gzip. Both compressors give smaller sizes than gzip. Lzma's decompresses faster than bzip2. It also supports ramdisks and initramfs' compressed using these two compressors. The functionality has been successfully used for a couple of years by the udpcast project This version applies to "tip" kernel 2.6.28 This part contains: - changed inflate.c to accomodate rest of patch - implementation of bzip2 compression (not used at this stage yet) - implementation of lzma compression (not used at this stage yet) - Makefile routines to support bzip2 and lzma kernel compression Signed-off-by: Alain Knaff Signed-off-by: H. Peter Anvin --- include/linux/decompress/bunzip2.h | 10 + include/linux/decompress/generic.h | 30 ++ include/linux/decompress/inflate.h | 13 + include/linux/decompress/mm.h | 87 +++++ include/linux/decompress/unlzma.h | 12 + lib/decompress_bunzip2.c | 735 +++++++++++++++++++++++++++++++++++++ lib/decompress_inflate.c | 167 +++++++++ lib/decompress_unlzma.c | 647 ++++++++++++++++++++++++++++++++ lib/zlib_inflate/inflate.h | 4 + lib/zlib_inflate/inftrees.h | 4 + scripts/Makefile.lib | 14 + scripts/bin_size | 10 + 12 files changed, 1733 insertions(+) create mode 100644 include/linux/decompress/bunzip2.h create mode 100644 include/linux/decompress/generic.h create mode 100644 include/linux/decompress/inflate.h create mode 100644 include/linux/decompress/mm.h create mode 100644 include/linux/decompress/unlzma.h create mode 100644 lib/decompress_bunzip2.c create mode 100644 lib/decompress_inflate.c create mode 100644 lib/decompress_unlzma.c create mode 100644 scripts/bin_size diff --git a/include/linux/decompress/bunzip2.h b/include/linux/decompress/bunzip2.h new file mode 100644 index 00000000000..115272137a9 --- /dev/null +++ b/include/linux/decompress/bunzip2.h @@ -0,0 +1,10 @@ +#ifndef DECOMPRESS_BUNZIP2_H +#define DECOMPRESS_BUNZIP2_H + +int bunzip2(unsigned char *inbuf, int len, + int(*fill)(void*, unsigned int), + int(*flush)(void*, unsigned int), + unsigned char *output, + int *pos, + void(*error)(char *x)); +#endif diff --git a/include/linux/decompress/generic.h b/include/linux/decompress/generic.h new file mode 100644 index 00000000000..f847f514f78 --- /dev/null +++ b/include/linux/decompress/generic.h @@ -0,0 +1,30 @@ +#ifndef DECOMPRESS_GENERIC_H +#define DECOMPRESS_GENERIC_H + +/* Minimal chunksize to be read. + *Bzip2 prefers at least 4096 + *Lzma prefers 0x10000 */ +#define COMPR_IOBUF_SIZE 4096 + +typedef int (*decompress_fn) (unsigned char *inbuf, int len, + int(*fill)(void*, unsigned int), + int(*writebb)(void*, unsigned int), + unsigned char *output, + int *posp, + void(*error)(char *x)); + +/* inbuf - input buffer + *len - len of pre-read data in inbuf + *fill - function to fill inbuf if empty + *writebb - function to write out outbug + *posp - if non-null, input position (number of bytes read) will be + * returned here + * + *If len != 0, the inbuf is initialized (with as much data), and fill + *should not be called + *If len = 0, the inbuf is allocated, but empty. Its size is IOBUF_SIZE + *fill should be called (repeatedly...) to read data, at most IOBUF_SIZE + */ + + +#endif diff --git a/include/linux/decompress/inflate.h b/include/linux/decompress/inflate.h new file mode 100644 index 00000000000..f9b06ccc3e5 --- /dev/null +++ b/include/linux/decompress/inflate.h @@ -0,0 +1,13 @@ +#ifndef INFLATE_H +#define INFLATE_H + +/* Other housekeeping constants */ +#define INBUFSIZ 4096 + +int gunzip(unsigned char *inbuf, int len, + int(*fill)(void*, unsigned int), + int(*flush)(void*, unsigned int), + unsigned char *output, + int *pos, + void(*error_fn)(char *x)); +#endif diff --git a/include/linux/decompress/mm.h b/include/linux/decompress/mm.h new file mode 100644 index 00000000000..12ff8c3f1d0 --- /dev/null +++ b/include/linux/decompress/mm.h @@ -0,0 +1,87 @@ +/* + * linux/compr_mm.h + * + * Memory management for pre-boot and ramdisk uncompressors + * + * Authors: Alain Knaff + * + */ + +#ifndef DECOMPR_MM_H +#define DECOMPR_MM_H + +#ifdef STATIC + +/* Code active when included from pre-boot environment: */ + +/* A trivial malloc implementation, adapted from + * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 + */ +static unsigned long malloc_ptr; +static int malloc_count; + +static void *malloc(int size) +{ + void *p; + + if (size < 0) + error("Malloc error"); + if (!malloc_ptr) + malloc_ptr = free_mem_ptr; + + malloc_ptr = (malloc_ptr + 3) & ~3; /* Align */ + + p = (void *)malloc_ptr; + malloc_ptr += size; + + if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr) + error("Out of memory"); + + malloc_count++; + return p; +} + +static void free(void *where) +{ + malloc_count--; + if (!malloc_count) + malloc_ptr = free_mem_ptr; +} + +#define large_malloc(a) malloc(a) +#define large_free(a) free(a) + +#define set_error_fn(x) + +#define INIT + +#else /* STATIC */ + +/* Code active when compiled standalone for use when loading ramdisk: */ + +#include +#include +#include +#include + +/* Use defines rather than static inline in order to avoid spurious + * warnings when not needed (indeed large_malloc / large_free are not + * needed by inflate */ + +#define malloc(a) kmalloc(a, GFP_KERNEL) +#define free(a) kfree(a) + +#define large_malloc(a) vmalloc(a) +#define large_free(a) vfree(a) + +static void(*error)(char *m); +#define set_error_fn(x) error = x; + +#define INIT __init +#define STATIC + +#include + +#endif /* STATIC */ + +#endif /* DECOMPR_MM_H */ diff --git a/include/linux/decompress/unlzma.h b/include/linux/decompress/unlzma.h new file mode 100644 index 00000000000..7796538f1bf --- /dev/null +++ b/include/linux/decompress/unlzma.h @@ -0,0 +1,12 @@ +#ifndef DECOMPRESS_UNLZMA_H +#define DECOMPRESS_UNLZMA_H + +int unlzma(unsigned char *, int, + int(*fill)(void*, unsigned int), + int(*flush)(void*, unsigned int), + unsigned char *output, + int *posp, + void(*error)(char *x) + ); + +#endif diff --git a/lib/decompress_bunzip2.c b/lib/decompress_bunzip2.c new file mode 100644 index 00000000000..5d3ddb5fcfd --- /dev/null +++ b/lib/decompress_bunzip2.c @@ -0,0 +1,735 @@ +/* vi: set sw = 4 ts = 4: */ +/* Small bzip2 deflate implementation, by Rob Landley (rob@landley.net). + + Based on bzip2 decompression code by Julian R Seward (jseward@acm.org), + which also acknowledges contributions by Mike Burrows, David Wheeler, + Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten, + Robert Sedgewick, and Jon L. Bentley. + + This code is licensed under the LGPLv2: + LGPL (http://www.gnu.org/copyleft/lgpl.html +*/ + +/* + Size and speed optimizations by Manuel Novoa III (mjn3@codepoet.org). + + More efficient reading of Huffman codes, a streamlined read_bunzip() + function, and various other tweaks. In (limited) tests, approximately + 20% faster than bzcat on x86 and about 10% faster on arm. + + Note that about 2/3 of the time is spent in read_unzip() reversing + the Burrows-Wheeler transformation. Much of that time is delay + resulting from cache misses. + + I would ask that anyone benefiting from this work, especially those + using it in commercial products, consider making a donation to my local + non-profit hospice organization in the name of the woman I loved, who + passed away Feb. 12, 2003. + + In memory of Toni W. Hagan + + Hospice of Acadiana, Inc. + 2600 Johnston St., Suite 200 + Lafayette, LA 70503-3240 + + Phone (337) 232-1234 or 1-800-738-2226 + Fax (337) 232-1297 + + http://www.hospiceacadiana.com/ + + Manuel + */ + +/* + Made it fit for running in Linux Kernel by Alain Knaff (alain@knaff.lu) +*/ + + +#ifndef STATIC +#include +#endif /* !STATIC */ + +#include + +#ifndef INT_MAX +#define INT_MAX 0x7fffffff +#endif + +/* Constants for Huffman coding */ +#define MAX_GROUPS 6 +#define GROUP_SIZE 50 /* 64 would have been more efficient */ +#define MAX_HUFCODE_BITS 20 /* Longest Huffman code allowed */ +#define MAX_SYMBOLS 258 /* 256 literals + RUNA + RUNB */ +#define SYMBOL_RUNA 0 +#define SYMBOL_RUNB 1 + +/* Status return values */ +#define RETVAL_OK 0 +#define RETVAL_LAST_BLOCK (-1) +#define RETVAL_NOT_BZIP_DATA (-2) +#define RETVAL_UNEXPECTED_INPUT_EOF (-3) +#define RETVAL_UNEXPECTED_OUTPUT_EOF (-4) +#define RETVAL_DATA_ERROR (-5) +#define RETVAL_OUT_OF_MEMORY (-6) +#define RETVAL_OBSOLETE_INPUT (-7) + +/* Other housekeeping constants */ +#define BZIP2_IOBUF_SIZE 4096 + +/* This is what we know about each Huffman coding group */ +struct group_data { + /* We have an extra slot at the end of limit[] for a sentinal value. */ + int limit[MAX_HUFCODE_BITS+1]; + int base[MAX_HUFCODE_BITS]; + int permute[MAX_SYMBOLS]; + int minLen, maxLen; +}; + +/* Structure holding all the housekeeping data, including IO buffers and + memory that persists between calls to bunzip */ +struct bunzip_data { + /* State for interrupting output loop */ + int writeCopies, writePos, writeRunCountdown, writeCount, writeCurrent; + /* I/O tracking data (file handles, buffers, positions, etc.) */ + int (*fill)(void*, unsigned int); + int inbufCount, inbufPos /*, outbufPos*/; + unsigned char *inbuf /*,*outbuf*/; + unsigned int inbufBitCount, inbufBits; + /* The CRC values stored in the block header and calculated from the + data */ + unsigned int crc32Table[256], headerCRC, totalCRC, writeCRC; + /* Intermediate buffer and its size (in bytes) */ + unsigned int *dbuf, dbufSize; + /* These things are a bit too big to go on the stack */ + unsigned char selectors[32768]; /* nSelectors = 15 bits */ + struct group_data groups[MAX_GROUPS]; /* Huffman coding tables */ + int io_error; /* non-zero if we have IO error */ +}; + + +/* Return the next nnn bits of input. All reads from the compressed input + are done through this function. All reads are big endian */ +static unsigned int INIT get_bits(struct bunzip_data *bd, char bits_wanted) +{ + unsigned int bits = 0; + + /* If we need to get more data from the byte buffer, do so. + (Loop getting one byte at a time to enforce endianness and avoid + unaligned access.) */ + while (bd->inbufBitCount < bits_wanted) { + /* If we need to read more data from file into byte buffer, do + so */ + if (bd->inbufPos == bd->inbufCount) { + if (bd->io_error) + return 0; + bd->inbufCount = bd->fill(bd->inbuf, BZIP2_IOBUF_SIZE); + if (bd->inbufCount <= 0) { + bd->io_error = RETVAL_UNEXPECTED_INPUT_EOF; + return 0; + } + bd->inbufPos = 0; + } + /* Avoid 32-bit overflow (dump bit buffer to top of output) */ + if (bd->inbufBitCount >= 24) { + bits = bd->inbufBits&((1 << bd->inbufBitCount)-1); + bits_wanted -= bd->inbufBitCount; + bits <<= bits_wanted; + bd->inbufBitCount = 0; + } + /* Grab next 8 bits of input from buffer. */ + bd->inbufBits = (bd->inbufBits << 8)|bd->inbuf[bd->inbufPos++]; + bd->inbufBitCount += 8; + } + /* Calculate result */ + bd->inbufBitCount -= bits_wanted; + bits |= (bd->inbufBits >> bd->inbufBitCount)&((1 << bits_wanted)-1); + + return bits; +} + +/* Unpacks the next block and sets up for the inverse burrows-wheeler step. */ + +static int INIT get_next_block(struct bunzip_data *bd) +{ + struct group_data *hufGroup = NULL; + int *base = NULL; + int *limit = NULL; + int dbufCount, nextSym, dbufSize, groupCount, selector, + i, j, k, t, runPos, symCount, symTotal, nSelectors, + byteCount[256]; + unsigned char uc, symToByte[256], mtfSymbol[256], *selectors; + unsigned int *dbuf, origPtr; + + dbuf = bd->dbuf; + dbufSize = bd->dbufSize; + selectors = bd->selectors; + + /* Read in header signature and CRC, then validate signature. + (last block signature means CRC is for whole file, return now) */ + i = get_bits(bd, 24); + j = get_bits(bd, 24); + bd->headerCRC = get_bits(bd, 32); + if ((i == 0x177245) && (j == 0x385090)) + return RETVAL_LAST_BLOCK; + if ((i != 0x314159) || (j != 0x265359)) + return RETVAL_NOT_BZIP_DATA; + /* We can add support for blockRandomised if anybody complains. + There was some code for this in busybox 1.0.0-pre3, but nobody ever + noticed that it didn't actually work. */ + if (get_bits(bd, 1)) + return RETVAL_OBSOLETE_INPUT; + origPtr = get_bits(bd, 24); + if (origPtr > dbufSize) + return RETVAL_DATA_ERROR; + /* mapping table: if some byte values are never used (encoding things + like ascii text), the compression code removes the gaps to have fewer + symbols to deal with, and writes a sparse bitfield indicating which + values were present. We make a translation table to convert the + symbols back to the corresponding bytes. */ + t = get_bits(bd, 16); + symTotal = 0; + for (i = 0; i < 16; i++) { + if (t&(1 << (15-i))) { + k = get_bits(bd, 16); + for (j = 0; j < 16; j++) + if (k&(1 << (15-j))) + symToByte[symTotal++] = (16*i)+j; + } + } + /* How many different Huffman coding groups does this block use? */ + groupCount = get_bits(bd, 3); + if (groupCount < 2 || groupCount > MAX_GROUPS) + return RETVAL_DATA_ERROR; + /* nSelectors: Every GROUP_SIZE many symbols we select a new + Huffman coding group. Read in the group selector list, + which is stored as MTF encoded bit runs. (MTF = Move To + Front, as each value is used it's moved to the start of the + list.) */ + nSelectors = get_bits(bd, 15); + if (!nSelectors) + return RETVAL_DATA_ERROR; + for (i = 0; i < groupCount; i++) + mtfSymbol[i] = i; + for (i = 0; i < nSelectors; i++) { + /* Get next value */ + for (j = 0; get_bits(bd, 1); j++) + if (j >= groupCount) + return RETVAL_DATA_ERROR; + /* Decode MTF to get the next selector */ + uc = mtfSymbol[j]; + for (; j; j--) + mtfSymbol[j] = mtfSymbol[j-1]; + mtfSymbol[0] = selectors[i] = uc; + } + /* Read the Huffman coding tables for each group, which code + for symTotal literal symbols, plus two run symbols (RUNA, + RUNB) */ + symCount = symTotal+2; + for (j = 0; j < groupCount; j++) { + unsigned char length[MAX_SYMBOLS], temp[MAX_HUFCODE_BITS+1]; + int minLen, maxLen, pp; + /* Read Huffman code lengths for each symbol. They're + stored in a way similar to mtf; record a starting + value for the first symbol, and an offset from the + previous value for everys symbol after that. + (Subtracting 1 before the loop and then adding it + back at the end is an optimization that makes the + test inside the loop simpler: symbol length 0 + becomes negative, so an unsigned inequality catches + it.) */ + t = get_bits(bd, 5)-1; + for (i = 0; i < symCount; i++) { + for (;;) { + if (((unsigned)t) > (MAX_HUFCODE_BITS-1)) + return RETVAL_DATA_ERROR; + + /* If first bit is 0, stop. Else + second bit indicates whether to + increment or decrement the value. + Optimization: grab 2 bits and unget + the second if the first was 0. */ + + k = get_bits(bd, 2); + if (k < 2) { + bd->inbufBitCount++; + break; + } + /* Add one if second bit 1, else + * subtract 1. Avoids if/else */ + t += (((k+1)&2)-1); + } + /* Correct for the initial -1, to get the + * final symbol length */ + length[i] = t+1; + } + /* Find largest and smallest lengths in this group */ + minLen = maxLen = length[0]; + + for (i = 1; i < symCount; i++) { + if (length[i] > maxLen) + maxLen = length[i]; + else if (length[i] < minLen) + minLen = length[i]; + } + + /* Calculate permute[], base[], and limit[] tables from + * length[]. + * + * permute[] is the lookup table for converting + * Huffman coded symbols into decoded symbols. base[] + * is the amount to subtract from the value of a + * Huffman symbol of a given length when using + * permute[]. + * + * limit[] indicates the largest numerical value a + * symbol with a given number of bits can have. This + * is how the Huffman codes can vary in length: each + * code with a value > limit[length] needs another + * bit. + */ + hufGroup = bd->groups+j; + hufGroup->minLen = minLen; + hufGroup->maxLen = maxLen; + /* Note that minLen can't be smaller than 1, so we + adjust the base and limit array pointers so we're + not always wasting the first entry. We do this + again when using them (during symbol decoding).*/ + base = hufGroup->base-1; + limit = hufGroup->limit-1; + /* Calculate permute[]. Concurently, initialize + * temp[] and limit[]. */ + pp = 0; + for (i = minLen; i <= maxLen; i++) { + temp[i] = limit[i] = 0; + for (t = 0; t < symCount; t++) + if (length[t] == i) + hufGroup->permute[pp++] = t; + } + /* Count symbols coded for at each bit length */ + for (i = 0; i < symCount; i++) + temp[length[i]]++; + /* Calculate limit[] (the largest symbol-coding value + *at each bit length, which is (previous limit << + *1)+symbols at this level), and base[] (number of + *symbols to ignore at each bit length, which is limit + *minus the cumulative count of symbols coded for + *already). */ + pp = t = 0; + for (i = minLen; i < maxLen; i++) { + pp += temp[i]; + /* We read the largest possible symbol size + and then unget bits after determining how + many we need, and those extra bits could be + set to anything. (They're noise from + future symbols.) At each level we're + really only interested in the first few + bits, so here we set all the trailing + to-be-ignored bits to 1 so they don't + affect the value > limit[length] + comparison. */ + limit[i] = (pp << (maxLen - i)) - 1; + pp <<= 1; + base[i+1] = pp-(t += temp[i]); + } + limit[maxLen+1] = INT_MAX; /* Sentinal value for + * reading next sym. */ + limit[maxLen] = pp+temp[maxLen]-1; + base[minLen] = 0; + } + /* We've finished reading and digesting the block header. Now + read this block's Huffman coded symbols from the file and + undo the Huffman coding and run length encoding, saving the + result into dbuf[dbufCount++] = uc */ + + /* Initialize symbol occurrence counters and symbol Move To + * Front table */ + for (i = 0; i < 256; i++) { + byteCount[i] = 0; + mtfSymbol[i] = (unsigned char)i; + } + /* Loop through compressed symbols. */ + runPos = dbufCount = symCount = selector = 0; + for (;;) { + /* Determine which Huffman coding group to use. */ + if (!(symCount--)) { + symCount = GROUP_SIZE-1; + if (selector >= nSelectors) + return RETVAL_DATA_ERROR; + hufGroup = bd->groups+selectors[selector++]; + base = hufGroup->base-1; + limit = hufGroup->limit-1; + } + /* Read next Huffman-coded symbol. */ + /* Note: It is far cheaper to read maxLen bits and + back up than it is to read minLen bits and then an + additional bit at a time, testing as we go. + Because there is a trailing last block (with file + CRC), there is no danger of the overread causing an + unexpected EOF for a valid compressed file. As a + further optimization, we do the read inline + (falling back to a call to get_bits if the buffer + runs dry). The following (up to got_huff_bits:) is + equivalent to j = get_bits(bd, hufGroup->maxLen); + */ + while (bd->inbufBitCount < hufGroup->maxLen) { + if (bd->inbufPos == bd->inbufCount) { + j = get_bits(bd, hufGroup->maxLen); + goto got_huff_bits; + } + bd->inbufBits = + (bd->inbufBits << 8)|bd->inbuf[bd->inbufPos++]; + bd->inbufBitCount += 8; + }; + bd->inbufBitCount -= hufGroup->maxLen; + j = (bd->inbufBits >> bd->inbufBitCount)& + ((1 << hufGroup->maxLen)-1); +got_huff_bits: + /* Figure how how many bits are in next symbol and + * unget extras */ + i = hufGroup->minLen; + while (j > limit[i]) + ++i; + bd->inbufBitCount += (hufGroup->maxLen - i); + /* Huffman decode value to get nextSym (with bounds checking) */ + if ((i > hufGroup->maxLen) + || (((unsigned)(j = (j>>(hufGroup->maxLen-i))-base[i])) + >= MAX_SYMBOLS)) + return RETVAL_DATA_ERROR; + nextSym = hufGroup->permute[j]; + /* We have now decoded the symbol, which indicates + either a new literal byte, or a repeated run of the + most recent literal byte. First, check if nextSym + indicates a repeated run, and if so loop collecting + how many times to repeat the last literal. */ + if (((unsigned)nextSym) <= SYMBOL_RUNB) { /* RUNA or RUNB */ + /* If this is the start of a new run, zero out + * counter */ + if (!runPos) { + runPos = 1; + t = 0; + } + /* Neat trick that saves 1 symbol: instead of + or-ing 0 or 1 at each bit position, add 1 + or 2 instead. For example, 1011 is 1 << 0 + + 1 << 1 + 2 << 2. 1010 is 2 << 0 + 2 << 1 + + 1 << 2. You can make any bit pattern + that way using 1 less symbol than the basic + or 0/1 method (except all bits 0, which + would use no symbols, but a run of length 0 + doesn't mean anything in this context). + Thus space is saved. */ + t += (runPos << nextSym); + /* +runPos if RUNA; +2*runPos if RUNB */ + + runPos <<= 1; + continue; + } + /* When we hit the first non-run symbol after a run, + we now know how many times to repeat the last + literal, so append that many copies to our buffer + of decoded symbols (dbuf) now. (The last literal + used is the one at the head of the mtfSymbol + array.) */ + if (runPos) { + runPos = 0; + if (dbufCount+t >= dbufSize) + return RETVAL_DATA_ERROR; + + uc = symToByte[mtfSymbol[0]]; + byteCount[uc] += t; + while (t--) + dbuf[dbufCount++] = uc; + } + /* Is this the terminating symbol? */ + if (nextSym > symTotal) + break; + /* At this point, nextSym indicates a new literal + character. Subtract one to get the position in the + MTF array at which this literal is currently to be + found. (Note that the result can't be -1 or 0, + because 0 and 1 are RUNA and RUNB. But another + instance of the first symbol in the mtf array, + position 0, would have been handled as part of a + run above. Therefore 1 unused mtf position minus 2 + non-literal nextSym values equals -1.) */ + if (dbufCount >= dbufSize) + return RETVAL_DATA_ERROR; + i = nextSym - 1; + uc = mtfSymbol[i]; + /* Adjust the MTF array. Since we typically expect to + *move only a small number of symbols, and are bound + *by 256 in any case, using memmove here would + *typically be bigger and slower due to function call + *overhead and other assorted setup costs. */ + do { + mtfSymbol[i] = mtfSymbol[i-1]; + } while (--i); + mtfSymbol[0] = uc; + uc = symToByte[uc]; + /* We have our literal byte. Save it into dbuf. */ + byteCount[uc]++; + dbuf[dbufCount++] = (unsigned int)uc; + } + /* At this point, we've read all the Huffman-coded symbols + (and repeated runs) for this block from the input stream, + and decoded them into the intermediate buffer. There are + dbufCount many decoded bytes in dbuf[]. Now undo the + Burrows-Wheeler transform on dbuf. See + http://dogma.net/markn/articles/bwt/bwt.htm + */ + /* Turn byteCount into cumulative occurrence counts of 0 to n-1. */ + j = 0; + for (i = 0; i < 256; i++) { + k = j+byteCount[i]; + byteCount[i] = j; + j = k; + } + /* Figure out what order dbuf would be in if we sorted it. */ + for (i = 0; i < dbufCount; i++) { + uc = (unsigned char)(dbuf[i] & 0xff); + dbuf[byteCount[uc]] |= (i << 8); + byteCount[uc]++; + } + /* Decode first byte by hand to initialize "previous" byte. + Note that it doesn't get output, and if the first three + characters are identical it doesn't qualify as a run (hence + writeRunCountdown = 5). */ + if (dbufCount) { + if (origPtr >= dbufCount) + return RETVAL_DATA_ERROR; + bd->writePos = dbuf[origPtr]; + bd->writeCurrent = (unsigned char)(bd->writePos&0xff); + bd->writePos >>= 8; + bd->writeRunCountdown = 5; + } + bd->writeCount = dbufCount; + + return RETVAL_OK; +} + +/* Undo burrows-wheeler transform on intermediate buffer to produce output. + If start_bunzip was initialized with out_fd =-1, then up to len bytes of + data are written to outbuf. Return value is number of bytes written or + error (all errors are negative numbers). If out_fd!=-1, outbuf and len + are ignored, data is written to out_fd and return is RETVAL_OK or error. +*/ + +static int INIT read_bunzip(struct bunzip_data *bd, char *outbuf, int len) +{ + const unsigned int *dbuf; + int pos, xcurrent, previous, gotcount; + + /* If last read was short due to end of file, return last block now */ + if (bd->writeCount < 0) + return bd->writeCount; + + gotcount = 0; + dbuf = bd->dbuf; + pos = bd->writePos; + xcurrent = bd->writeCurrent; + + /* We will always have pending decoded data to write into the output + buffer unless this is the very first call (in which case we haven't + Huffman-decoded a block into the intermediate buffer yet). */ + + if (bd->writeCopies) { + /* Inside the loop, writeCopies means extra copies (beyond 1) */ + --bd->writeCopies; + /* Loop outputting bytes */ + for (;;) { + /* If the output buffer is full, snapshot + * state and return */ + if (gotcount >= len) { + bd->writePos = pos; + bd->writeCurrent = xcurrent; + bd->writeCopies++; + return len; + } + /* Write next byte into output buffer, updating CRC */ + outbuf[gotcount++] = xcurrent; + bd->writeCRC = (((bd->writeCRC) << 8) + ^bd->crc32Table[((bd->writeCRC) >> 24) + ^xcurrent]); + /* Loop now if we're outputting multiple + * copies of this byte */ + if (bd->writeCopies) { + --bd->writeCopies; + continue; + } +decode_next_byte: + if (!bd->writeCount--) + break; + /* Follow sequence vector to undo + * Burrows-Wheeler transform */ + previous = xcurrent; + pos = dbuf[pos]; + xcurrent = pos&0xff; + pos >>= 8; + /* After 3 consecutive copies of the same + byte, the 4th is a repeat count. We count + down from 4 instead *of counting up because + testing for non-zero is faster */ + if (--bd->writeRunCountdown) { + if (xcurrent != previous) + bd->writeRunCountdown = 4; + } else { + /* We have a repeated run, this byte + * indicates the count */ + bd->writeCopies = xcurrent; + xcurrent = previous; + bd->writeRunCountdown = 5; + /* Sometimes there are just 3 bytes + * (run length 0) */ + if (!bd->writeCopies) + goto decode_next_byte; + /* Subtract the 1 copy we'd output + * anyway to get extras */ + --bd->writeCopies; + } + } + /* Decompression of this block completed successfully */ + bd->writeCRC = ~bd->writeCRC; + bd->totalCRC = ((bd->totalCRC << 1) | + (bd->totalCRC >> 31)) ^ bd->writeCRC; + /* If this block had a CRC error, force file level CRC error. */ + if (bd->writeCRC != bd->headerCRC) { + bd->totalCRC = bd->headerCRC+1; + return RETVAL_LAST_BLOCK; + } + } + + /* Refill the intermediate buffer by Huffman-decoding next + * block of input */ + /* (previous is just a convenient unused temp variable here) */ + previous = get_next_block(bd); + if (previous) { + bd->writeCount = previous; + return (previous != RETVAL_LAST_BLOCK) ? previous : gotcount; + } + bd->writeCRC = 0xffffffffUL; + pos = bd->writePos; + xcurrent = bd->writeCurrent; + goto decode_next_byte; +} + +static int INIT nofill(void *buf, unsigned int len) +{ + return -1; +} + +/* Allocate the structure, read file header. If in_fd ==-1, inbuf must contain + a complete bunzip file (len bytes long). If in_fd!=-1, inbuf and len are + ignored, and data is read from file handle into temporary buffer. */ +static int INIT start_bunzip(struct bunzip_data **bdp, void *inbuf, int len, + int (*fill)(void*, unsigned int)) +{ + struct bunzip_data *bd; + unsigned int i, j, c; + const unsigned int BZh0 = + (((unsigned int)'B') << 24)+(((unsigned int)'Z') << 16) + +(((unsigned int)'h') << 8)+(unsigned int)'0'; + + /* Figure out how much data to allocate */ + i = sizeof(struct bunzip_data); + + /* Allocate bunzip_data. Most fields initialize to zero. */ + bd = *bdp = malloc(i); + memset(bd, 0, sizeof(struct bunzip_data)); + /* Setup input buffer */ + bd->inbuf = inbuf; + bd->inbufCount = len; + if (fill != NULL) + bd->fill = fill; + else + bd->fill = nofill; + + /* Init the CRC32 table (big endian) */ + for (i = 0; i < 256; i++) { + c = i << 24; + for (j = 8; j; j--) + c = c&0x80000000 ? (c << 1)^0x04c11db7 : (c << 1); + bd->crc32Table[i] = c; + } + + /* Ensure that file starts with "BZh['1'-'9']." */ + i = get_bits(bd, 32); + if (((unsigned int)(i-BZh0-1)) >= 9) + return RETVAL_NOT_BZIP_DATA; + + /* Fourth byte (ascii '1'-'9'), indicates block size in units of 100k of + uncompressed data. Allocate intermediate buffer for block. */ + bd->dbufSize = 100000*(i-BZh0); + + bd->dbuf = large_malloc(bd->dbufSize * sizeof(int)); + return RETVAL_OK; +} + +/* Example usage: decompress src_fd to dst_fd. (Stops at end of bzip2 data, + not end of file.) */ +STATIC int INIT bunzip2(unsigned char *buf, int len, + int(*fill)(void*, unsigned int), + int(*flush)(void*, unsigned int), + unsigned char *outbuf, + int *pos, + void(*error_fn)(char *x)) +{ + struct bunzip_data *bd; + int i = -1; + unsigned char *inbuf; + + set_error_fn(error_fn); + if (flush) + outbuf = malloc(BZIP2_IOBUF_SIZE); + else + len -= 4; /* Uncompressed size hack active in pre-boot + environment */ + if (!outbuf) { + error("Could not allocate output bufer"); + return -1; + } + if (buf) + inbuf = buf; + else + inbuf = malloc(BZIP2_IOBUF_SIZE); + if (!inbuf) { + error("Could not allocate input bufer"); + goto exit_0; + } + i = start_bunzip(&bd, inbuf, len, fill); + if (!i) { + for (;;) { + i = read_bunzip(bd, outbuf, BZIP2_IOBUF_SIZE); + if (i <= 0) + break; + if (!flush) + outbuf += i; + else + if (i != flush(outbuf, i)) { + i = RETVAL_UNEXPECTED_OUTPUT_EOF; + break; + } + } + } + /* Check CRC and release memory */ + if (i == RETVAL_LAST_BLOCK) { + if (bd->headerCRC != bd->totalCRC) + error("Data integrity error when decompressing."); + else + i = RETVAL_OK; + } else if (i == RETVAL_UNEXPECTED_OUTPUT_EOF) { + error("Compressed file ends unexpectedly"); + } + if (bd->dbuf) + large_free(bd->dbuf); + if (pos) + *pos = bd->inbufPos; + free(bd); + if (!buf) + free(inbuf); +exit_0: + if (flush) + free(outbuf); + return i; +} + +#define decompress bunzip2 diff --git a/lib/decompress_inflate.c b/lib/decompress_inflate.c new file mode 100644 index 00000000000..163e66aea5f --- /dev/null +++ b/lib/decompress_inflate.c @@ -0,0 +1,167 @@ +#ifdef STATIC +/* Pre-boot environment: included */ + +/* prevent inclusion of _LINUX_KERNEL_H in pre-boot environment: lots + * errors about console_printk etc... on ARM */ +#define _LINUX_KERNEL_H + +#include "zlib_inflate/inftrees.c" +#include "zlib_inflate/inffast.c" +#include "zlib_inflate/inflate.c" + +#else /* STATIC */ +/* initramfs et al: linked */ + +#include + +#include "zlib_inflate/inftrees.h" +#include "zlib_inflate/inffast.h" +#include "zlib_inflate/inflate.h" + +#include "zlib_inflate/infutil.h" + +#endif /* STATIC */ + +#include + +#define INBUF_LEN (16*1024) + +/* Included from initramfs et al code */ +STATIC int INIT gunzip(unsigned char *buf, int len, + int(*fill)(void*, unsigned int), + int(*flush)(void*, unsigned int), + unsigned char *out_buf, + int *pos, + void(*error_fn)(char *x)) { + u8 *zbuf; + struct z_stream_s *strm; + int rc; + size_t out_len; + + set_error_fn(error_fn); + rc = -1; + if (flush) { + out_len = 0x8100; /* 32 K */ + out_buf = malloc(out_len); + } else { + out_len = 0x7fffffff; /* no limit */ + } + if (!out_buf) { + error("Out of memory while allocating output buffer"); + goto gunzip_nomem1; + } + + if (buf) + zbuf = buf; + else { + zbuf = malloc(INBUF_LEN); + len = 0; + } + if (!zbuf) { + error("Out of memory while allocating input buffer"); + goto gunzip_nomem2; + } + + strm = malloc(sizeof(*strm)); + if (strm == NULL) { + error("Out of memory while allocating z_stream"); + goto gunzip_nomem3; + } + + strm->workspace = malloc(flush ? zlib_inflate_workspacesize() : + sizeof(struct inflate_state)); + if (strm->workspace == NULL) { + error("Out of memory while allocating workspace"); + goto gunzip_nomem4; + } + + if (len == 0) + len = fill(zbuf, INBUF_LEN); + + /* verify the gzip header */ + if (len < 10 || + zbuf[0] != 0x1f || zbuf[1] != 0x8b || zbuf[2] != 0x08) { + if (pos) + *pos = 0; + error("Not a gzip file"); + goto gunzip_5; + } + + /* skip over gzip header (1f,8b,08... 10 bytes total + + * possible asciz filename) + */ + strm->next_in = zbuf + 10; + /* skip over asciz filename */ + if (zbuf[3] & 0x8) { + while (strm->next_in[0]) + strm->next_in++; + strm->next_in++; + } + strm->avail_in = len - 10; + + strm->next_out = out_buf; + strm->avail_out = out_len; + + rc = zlib_inflateInit2(strm, -MAX_WBITS); + + if (!flush) { + WS(strm)->inflate_state.wsize = 0; + WS(strm)->inflate_state.window = NULL; + } + + while (rc == Z_OK) { + if (strm->avail_in == 0) { + /* TODO: handle case where both pos and fill are set */ + len = fill(zbuf, INBUF_LEN); + if (len < 0) { + rc = -1; + error("read error"); + break; + } + strm->next_in = zbuf; + strm->avail_in = len; + } + rc = zlib_inflate(strm, 0); + + /* Write any data generated */ + if (flush && strm->next_out > out_buf) { + int l = strm->next_out - out_buf; + if (l != flush(out_buf, l)) { + rc = -1; + error("write error"); + break; + } + strm->next_out = out_buf; + strm->avail_out = out_len; + } + + /* after Z_FINISH, only Z_STREAM_END is "we unpacked it all" */ + if (rc == Z_STREAM_END) { + rc = 0; + break; + } else if (rc != Z_OK) { + error("uncompression error"); + rc = -1; + } + } + + zlib_inflateEnd(strm); + if (pos) + /* add + 8 to skip over trailer */ + *pos = strm->next_in - zbuf+8; + +gunzip_5: + free(strm->workspace); +gunzip_nomem4: + free(strm); +gunzip_nomem3: + if (!buf) + free(zbuf); +gunzip_nomem2: + if (flush) + free(out_buf); +gunzip_nomem1: + return rc; /* returns Z_OK (0) if successful */ +} + +#define decompress gunzip diff --git a/lib/decompress_unlzma.c b/lib/decompress_unlzma.c new file mode 100644 index 00000000000..546f2f4c157 --- /dev/null +++ b/lib/decompress_unlzma.c @@ -0,0 +1,647 @@ +/* Lzma decompressor for Linux kernel. Shamelessly snarfed + *from busybox 1.1.1 + * + *Linux kernel adaptation + *Copyright (C) 2006 Alain < alain@knaff.lu > + * + *Based on small lzma deflate implementation/Small range coder + *implementation for lzma. + *Copyright (C) 2006 Aurelien Jacobs < aurel@gnuage.org > + * + *Based on LzmaDecode.c from the LZMA SDK 4.22 (http://www.7-zip.org/) + *Copyright (C) 1999-2005 Igor Pavlov + * + *Copyrights of the parts, see headers below. + * + * + *This program 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. + * + *This program 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 this library; if not, write to the Free Software + *Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef STATIC +#include +#endif /* STATIC */ + +#include + +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +static long long INIT read_int(unsigned char *ptr, int size) +{ + int i; + long long ret = 0; + + for (i = 0; i < size; i++) + ret = (ret << 8) | ptr[size-i-1]; + return ret; +} + +#define ENDIAN_CONVERT(x) \ + x = (typeof(x))read_int((unsigned char *)&x, sizeof(x)) + + +/* Small range coder implementation for lzma. + *Copyright (C) 2006 Aurelien Jacobs < aurel@gnuage.org > + * + *Based on LzmaDecode.c from the LZMA SDK 4.22 (http://www.7-zip.org/) + *Copyright (c) 1999-2005 Igor Pavlov + */ + +#include + +#define LZMA_IOBUF_SIZE 0x10000 + +struct rc { + int (*fill)(void*, unsigned int); + uint8_t *ptr; + uint8_t *buffer; + uint8_t *buffer_end; + int buffer_size; + uint32_t code; + uint32_t range; + uint32_t bound; +}; + + +#define RC_TOP_BITS 24 +#define RC_MOVE_BITS 5 +#define RC_MODEL_TOTAL_BITS 11 + + +/* Called twice: once at startup and once in rc_normalize() */ +static void INIT rc_read(struct rc *rc) +{ + rc->buffer_size = rc->fill((char *)rc->buffer, LZMA_IOBUF_SIZE); + if (rc->buffer_size <= 0) + error("unexpected EOF"); + rc->ptr = rc->buffer; + rc->buffer_end = rc->buffer + rc->buffer_size; +} + +/* Called once */ +static inline void INIT rc_init(struct rc *rc, + int (*fill)(void*, unsigned int), + char *buffer, int buffer_size) +{ + rc->fill = fill; + rc->buffer = (uint8_t *)buffer; + rc->buffer_size = buffer_size; + rc->buffer_end = rc->buffer + rc->buffer_size; + rc->ptr = rc->buffer; + + rc->code = 0; + rc->range = 0xFFFFFFFF; +} + +static inline void INIT rc_init_code(struct rc *rc) +{ + int i; + + for (i = 0; i < 5; i++) { + if (rc->ptr >= rc->buffer_end) + rc_read(rc); + rc->code = (rc->code << 8) | *rc->ptr++; + } +} + + +/* Called once. TODO: bb_maybe_free() */ +static inline void INIT rc_free(struct rc *rc) +{ + free(rc->buffer); +} + +/* Called twice, but one callsite is in inline'd rc_is_bit_0_helper() */ +static void INIT rc_do_normalize(struct rc *rc) +{ + if (rc->ptr >= rc->buffer_end) + rc_read(rc); + rc->range <<= 8; + rc->code = (rc->code << 8) | *rc->ptr++; +} +static inline void INIT rc_normalize(struct rc *rc) +{ + if (rc->range < (1 << RC_TOP_BITS)) + rc_do_normalize(rc); +} + +/* Called 9 times */ +/* Why rc_is_bit_0_helper exists? + *Because we want to always expose (rc->code < rc->bound) to optimizer + */ +static inline uint32_t INIT rc_is_bit_0_helper(struct rc *rc, uint16_t *p) +{ + rc_normalize(rc); + rc->bound = *p * (rc->range >> RC_MODEL_TOTAL_BITS); + return rc->bound; +} +static inline int INIT rc_is_bit_0(struct rc *rc, uint16_t *p) +{ + uint32_t t = rc_is_bit_0_helper(rc, p); + return rc->code < t; +} + +/* Called ~10 times, but very small, thus inlined */ +static inline void INIT rc_update_bit_0(struct rc *rc, uint16_t *p) +{ + rc->range = rc->bound; + *p += ((1 << RC_MODEL_TOTAL_BITS) - *p) >> RC_MOVE_BITS; +} +static inline void rc_update_bit_1(struct rc *rc, uint16_t *p) +{ + rc->range -= rc->bound; + rc->code -= rc->bound; + *p -= *p >> RC_MOVE_BITS; +} + +/* Called 4 times in unlzma loop */ +static int INIT rc_get_bit(struct rc *rc, uint16_t *p, int *symbol) +{ + if (rc_is_bit_0(rc, p)) { + rc_update_bit_0(rc, p); + *symbol *= 2; + return 0; + } else { + rc_update_bit_1(rc, p); + *symbol = *symbol * 2 + 1; + return 1; + } +} + +/* Called once */ +static inline int INIT rc_direct_bit(struct rc *rc) +{ + rc_normalize(rc); + rc->range >>= 1; + if (rc->code >= rc->range) { + rc->code -= rc->range; + return 1; + } + return 0; +} + +/* Called twice */ +static inline void INIT +rc_bit_tree_decode(struct rc *rc, uint16_t *p, int num_levels, int *symbol) +{ + int i = num_levels; + + *symbol = 1; + while (i--) + rc_get_bit(rc, p + *symbol, symbol); + *symbol -= 1 << num_levels; +} + + +/* + * Small lzma deflate implementation. + * Copyright (C) 2006 Aurelien Jacobs < aurel@gnuage.org > + * + * Based on LzmaDecode.c from the LZMA SDK 4.22 (http://www.7-zip.org/) + * Copyright (C) 1999-2005 Igor Pavlov + */ + + +struct lzma_header { + uint8_t pos; + uint32_t dict_size; + uint64_t dst_size; +} __attribute__ ((packed)) ; + + +#define LZMA_BASE_SIZE 1846 +#define LZMA_LIT_SIZE 768 + +#define LZMA_NUM_POS_BITS_MAX 4 + +#define LZMA_LEN_NUM_LOW_BITS 3 +#define LZMA_LEN_NUM_MID_BITS 3 +#define LZMA_LEN_NUM_HIGH_BITS 8 + +#define LZMA_LEN_CHOICE 0 +#define LZMA_LEN_CHOICE_2 (LZMA_LEN_CHOICE + 1) +#define LZMA_LEN_LOW (LZMA_LEN_CHOICE_2 + 1) +#define LZMA_LEN_MID (LZMA_LEN_LOW \ + + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_LOW_BITS))) +#define LZMA_LEN_HIGH (LZMA_LEN_MID \ + +(1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_MID_BITS))) +#define LZMA_NUM_LEN_PROBS (LZMA_LEN_HIGH + (1 << LZMA_LEN_NUM_HIGH_BITS)) + +#define LZMA_NUM_STATES 12 +#define LZMA_NUM_LIT_STATES 7 + +#define LZMA_START_POS_MODEL_INDEX 4 +#define LZMA_END_POS_MODEL_INDEX 14 +#define LZMA_NUM_FULL_DISTANCES (1 << (LZMA_END_POS_MODEL_INDEX >> 1)) + +#define LZMA_NUM_POS_SLOT_BITS 6 +#define LZMA_NUM_LEN_TO_POS_STATES 4 + +#define LZMA_NUM_ALIGN_BITS 4 + +#define LZMA_MATCH_MIN_LEN 2 + +#define LZMA_IS_MATCH 0 +#define LZMA_IS_REP (LZMA_IS_MATCH + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)) +#define LZMA_IS_REP_G0 (LZMA_IS_REP + LZMA_NUM_STATES) +#define LZMA_IS_REP_G1 (LZMA_IS_REP_G0 + LZMA_NUM_STATES) +#define LZMA_IS_REP_G2 (LZMA_IS_REP_G1 + LZMA_NUM_STATES) +#define LZMA_IS_REP_0_LONG (LZMA_IS_REP_G2 + LZMA_NUM_STATES) +#define LZMA_POS_SLOT (LZMA_IS_REP_0_LONG \ + + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)) +#define LZMA_SPEC_POS (LZMA_POS_SLOT \ + +(LZMA_NUM_LEN_TO_POS_STATES << LZMA_NUM_POS_SLOT_BITS)) +#define LZMA_ALIGN (LZMA_SPEC_POS \ + + LZMA_NUM_FULL_DISTANCES - LZMA_END_POS_MODEL_INDEX) +#define LZMA_LEN_CODER (LZMA_ALIGN + (1 << LZMA_NUM_ALIGN_BITS)) +#define LZMA_REP_LEN_CODER (LZMA_LEN_CODER + LZMA_NUM_LEN_PROBS) +#define LZMA_LITERAL (LZMA_REP_LEN_CODER + LZMA_NUM_LEN_PROBS) + + +struct writer { + uint8_t *buffer; + uint8_t previous_byte; + size_t buffer_pos; + int bufsize; + size_t global_pos; + int(*flush)(void*, unsigned int); + struct lzma_header *header; +}; + +struct cstate { + int state; + uint32_t rep0, rep1, rep2, rep3; +}; + +static inline size_t INIT get_pos(struct writer *wr) +{ + return + wr->global_pos + wr->buffer_pos; +} + +static inline uint8_t INIT peek_old_byte(struct writer *wr, + uint32_t offs) +{ + if (!wr->flush) { + int32_t pos; + while (offs > wr->header->dict_size) + offs -= wr->header->dict_size; + pos = wr->buffer_pos - offs; + return wr->buffer[pos]; + } else { + uint32_t pos = wr->buffer_pos - offs; + while (pos >= wr->header->dict_size) + pos += wr->header->dict_size; + return wr->buffer[pos]; + } + +} + +static inline void INIT write_byte(struct writer *wr, uint8_t byte) +{ + wr->buffer[wr->buffer_pos++] = wr->previous_byte = byte; + if (wr->flush && wr->buffer_pos == wr->header->dict_size) { + wr->buffer_pos = 0; + wr->global_pos += wr->header->dict_size; + wr->flush((char *)wr->buffer, wr->header->dict_size); + } +} + + +static inline void INIT copy_byte(struct writer *wr, uint32_t offs) +{ + write_byte(wr, peek_old_byte(wr, offs)); +} + +static inline void INIT copy_bytes(struct writer *wr, + uint32_t rep0, int len) +{ + do { + copy_byte(wr, rep0); + len--; + } while (len != 0 && wr->buffer_pos < wr->header->dst_size); +} + +static inline void INIT process_bit0(struct writer *wr, struct rc *rc, + struct cstate *cst, uint16_t *p, + int pos_state, uint16_t *prob, + int lc, uint32_t literal_pos_mask) { + int mi = 1; + rc_update_bit_0(rc, prob); + prob = (p + LZMA_LITERAL + + (LZMA_LIT_SIZE + * (((get_pos(wr) & literal_pos_mask) << lc) + + (wr->previous_byte >> (8 - lc)))) + ); + + if (cst->state >= LZMA_NUM_LIT_STATES) { + int match_byte = peek_old_byte(wr, cst->rep0); + do { + int bit; + uint16_t *prob_lit; + + match_byte <<= 1; + bit = match_byte & 0x100; + prob_lit = prob + 0x100 + bit + mi; + if (rc_get_bit(rc, prob_lit, &mi)) { + if (!bit) + break; + } else { + if (bit) + break; + } + } while (mi < 0x100); + } + while (mi < 0x100) { + uint16_t *prob_lit = prob + mi; + rc_get_bit(rc, prob_lit, &mi); + } + write_byte(wr, mi); + if (cst->state < 4) + cst->state = 0; + else if (cst->state < 10) + cst->state -= 3; + else + cst->state -= 6; +} + +static inline void INIT process_bit1(struct writer *wr, struct rc *rc, + struct cstate *cst, uint16_t *p, + int pos_state, uint16_t *prob) { + int offset; + uint16_t *prob_len; + int num_bits; + int len; + + rc_update_bit_1(rc, prob); + prob = p + LZMA_IS_REP + cst->state; + if (rc_is_bit_0(rc, prob)) { + rc_update_bit_0(rc, prob); + cst->rep3 = cst->rep2; + cst->rep2 = cst->rep1; + cst->rep1 = cst->rep0; + cst->state = cst->state < LZMA_NUM_LIT_STATES ? 0 : 3; + prob = p + LZMA_LEN_CODER; + } else { + rc_update_bit_1(rc, prob); + prob = p + LZMA_IS_REP_G0 + cst->state; + if (rc_is_bit_0(rc, prob)) { + rc_update_bit_0(rc, prob); + prob = (p + LZMA_IS_REP_0_LONG + + (cst->state << + LZMA_NUM_POS_BITS_MAX) + + pos_state); + if (rc_is_bit_0(rc, prob)) { + rc_update_bit_0(rc, prob); + + cst->state = cst->state < LZMA_NUM_LIT_STATES ? + 9 : 11; + copy_byte(wr, cst->rep0); + return; + } else { + rc_update_bit_1(rc, prob); + } + } else { + uint32_t distance; + + rc_update_bit_1(rc, prob); + prob = p + LZMA_IS_REP_G1 + cst->state; + if (rc_is_bit_0(rc, prob)) { + rc_update_bit_0(rc, prob); + distance = cst->rep1; + } else { + rc_update_bit_1(rc, prob); + prob = p + LZMA_IS_REP_G2 + cst->state; + if (rc_is_bit_0(rc, prob)) { + rc_update_bit_0(rc, prob); + distance = cst->rep2; + } else { + rc_update_bit_1(rc, prob); + distance = cst->rep3; + cst->rep3 = cst->rep2; + } + cst->rep2 = cst->rep1; + } + cst->rep1 = cst->rep0; + cst->rep0 = distance; + } + cst->state = cst->state < LZMA_NUM_LIT_STATES ? 8 : 11; + prob = p + LZMA_REP_LEN_CODER; + } + + prob_len = prob + LZMA_LEN_CHOICE; + if (rc_is_bit_0(rc, prob_len)) { + rc_update_bit_0(rc, prob_len); + prob_len = (prob + LZMA_LEN_LOW + + (pos_state << + LZMA_LEN_NUM_LOW_BITS)); + offset = 0; + num_bits = LZMA_LEN_NUM_LOW_BITS; + } else { + rc_update_bit_1(rc, prob_len); + prob_len = prob + LZMA_LEN_CHOICE_2; + if (rc_is_bit_0(rc, prob_len)) { + rc_update_bit_0(rc, prob_len); + prob_len = (prob + LZMA_LEN_MID + + (pos_state << + LZMA_LEN_NUM_MID_BITS)); + offset = 1 << LZMA_LEN_NUM_LOW_BITS; + num_bits = LZMA_LEN_NUM_MID_BITS; + } else { + rc_update_bit_1(rc, prob_len); + prob_len = prob + LZMA_LEN_HIGH; + offset = ((1 << LZMA_LEN_NUM_LOW_BITS) + + (1 << LZMA_LEN_NUM_MID_BITS)); + num_bits = LZMA_LEN_NUM_HIGH_BITS; + } + } + + rc_bit_tree_decode(rc, prob_len, num_bits, &len); + len += offset; + + if (cst->state < 4) { + int pos_slot; + + cst->state += LZMA_NUM_LIT_STATES; + prob = + p + LZMA_POS_SLOT + + ((len < + LZMA_NUM_LEN_TO_POS_STATES ? len : + LZMA_NUM_LEN_TO_POS_STATES - 1) + << LZMA_NUM_POS_SLOT_BITS); + rc_bit_tree_decode(rc, prob, + LZMA_NUM_POS_SLOT_BITS, + &pos_slot); + if (pos_slot >= LZMA_START_POS_MODEL_INDEX) { + int i, mi; + num_bits = (pos_slot >> 1) - 1; + cst->rep0 = 2 | (pos_slot & 1); + if (pos_slot < LZMA_END_POS_MODEL_INDEX) { + cst->rep0 <<= num_bits; + prob = p + LZMA_SPEC_POS + + cst->rep0 - pos_slot - 1; + } else { + num_bits -= LZMA_NUM_ALIGN_BITS; + while (num_bits--) + cst->rep0 = (cst->rep0 << 1) | + rc_direct_bit(rc); + prob = p + LZMA_ALIGN; + cst->rep0 <<= LZMA_NUM_ALIGN_BITS; + num_bits = LZMA_NUM_ALIGN_BITS; + } + i = 1; + mi = 1; + while (num_bits--) { + if (rc_get_bit(rc, prob + mi, &mi)) + cst->rep0 |= i; + i <<= 1; + } + } else + cst->rep0 = pos_slot; + if (++(cst->rep0) == 0) + return; + } + + len += LZMA_MATCH_MIN_LEN; + + copy_bytes(wr, cst->rep0, len); +} + + + +STATIC inline int INIT unlzma(unsigned char *buf, int in_len, + int(*fill)(void*, unsigned int), + int(*flush)(void*, unsigned int), + unsigned char *output, + int *posp, + void(*error_fn)(char *x) + ) +{ + struct lzma_header header; + int lc, pb, lp; + uint32_t pos_state_mask; + uint32_t literal_pos_mask; + uint16_t *p; + int num_probs; + struct rc rc; + int i, mi; + struct writer wr; + struct cstate cst; + unsigned char *inbuf; + int ret = -1; + + set_error_fn(error_fn); + if (!flush) + in_len -= 4; /* Uncompressed size hack active in pre-boot + environment */ + if (buf) + inbuf = buf; + else + inbuf = malloc(LZMA_IOBUF_SIZE); + if (!inbuf) { + error("Could not allocate input bufer"); + goto exit_0; + } + + cst.state = 0; + cst.rep0 = cst.rep1 = cst.rep2 = cst.rep3 = 1; + + wr.header = &header; + wr.flush = flush; + wr.global_pos = 0; + wr.previous_byte = 0; + wr.buffer_pos = 0; + + rc_init(&rc, fill, inbuf, in_len); + + for (i = 0; i < sizeof(header); i++) { + if (rc.ptr >= rc.buffer_end) + rc_read(&rc); + ((unsigned char *)&header)[i] = *rc.ptr++; + } + + if (header.pos >= (9 * 5 * 5)) + error("bad header"); + + mi = 0; + lc = header.pos; + while (lc >= 9) { + mi++; + lc -= 9; + } + pb = 0; + lp = mi; + while (lp >= 5) { + pb++; + lp -= 5; + } + pos_state_mask = (1 << pb) - 1; + literal_pos_mask = (1 << lp) - 1; + + ENDIAN_CONVERT(header.dict_size); + ENDIAN_CONVERT(header.dst_size); + + if (header.dict_size == 0) + header.dict_size = 1; + + if (output) + wr.buffer = output; + else { + wr.bufsize = MIN(header.dst_size, header.dict_size); + wr.buffer = large_malloc(wr.bufsize); + } + if (wr.buffer == NULL) + goto exit_1; + + num_probs = LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)); + p = (uint16_t *) large_malloc(num_probs * sizeof(*p)); + if (p == 0) + goto exit_2; + num_probs = LZMA_LITERAL + (LZMA_LIT_SIZE << (lc + lp)); + for (i = 0; i < num_probs; i++) + p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1; + + rc_init_code(&rc); + + while (get_pos(&wr) < header.dst_size) { + int pos_state = get_pos(&wr) & pos_state_mask; + uint16_t *prob = p + LZMA_IS_MATCH + + (cst.state << LZMA_NUM_POS_BITS_MAX) + pos_state; + if (rc_is_bit_0(&rc, prob)) + process_bit0(&wr, &rc, &cst, p, pos_state, prob, + lc, literal_pos_mask); + else { + process_bit1(&wr, &rc, &cst, p, pos_state, prob); + if (cst.rep0 == 0) + break; + } + } + + if (posp) + *posp = rc.ptr-rc.buffer; + if (wr.flush) + wr.flush(wr.buffer, wr.buffer_pos); + ret = 0; + large_free(p); +exit_2: + if (!output) + large_free(wr.buffer); +exit_1: + if (!buf) + free(inbuf); +exit_0: + return ret; +} + +#define decompress unlzma diff --git a/lib/zlib_inflate/inflate.h b/lib/zlib_inflate/inflate.h index df8a6c92052..3d17b3d1b21 100644 --- a/lib/zlib_inflate/inflate.h +++ b/lib/zlib_inflate/inflate.h @@ -1,3 +1,6 @@ +#ifndef INFLATE_H +#define INFLATE_H + /* inflate.h -- internal inflate state definition * Copyright (C) 1995-2004 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h @@ -105,3 +108,4 @@ struct inflate_state { unsigned short work[288]; /* work area for code table building */ code codes[ENOUGH]; /* space for code tables */ }; +#endif diff --git a/lib/zlib_inflate/inftrees.h b/lib/zlib_inflate/inftrees.h index 5f5219b1240..b70b4731ac7 100644 --- a/lib/zlib_inflate/inftrees.h +++ b/lib/zlib_inflate/inftrees.h @@ -1,3 +1,6 @@ +#ifndef INFTREES_H +#define INFTREES_H + /* inftrees.h -- header to use inftrees.c * Copyright (C) 1995-2005 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h @@ -53,3 +56,4 @@ typedef enum { extern int zlib_inflate_table (codetype type, unsigned short *lens, unsigned codes, code **table, unsigned *bits, unsigned short *work); +#endif diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index e06365775bd..70b4676e3b9 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -186,3 +186,17 @@ quiet_cmd_gzip = GZIP $@ cmd_gzip = gzip -f -9 < $< > $@ +# Bzip2 +# --------------------------------------------------------------------------- + +# Bzip2 does not include size in file... so we have to fake that +size_append=$(CONFIG_SHELL) $(srctree)/scripts/bin_size + +quiet_cmd_bzip2 = BZIP2 $@ +cmd_bzip2 = (bzip2 -9 < $< ; $(size_append) $<) > $@ || (rm -f $@ ; false) + +# Lzma +# --------------------------------------------------------------------------- + +quiet_cmd_lzma = LZMA $@ +cmd_lzma = (lzma -9 -c $< ; $(size_append) $<) >$@ || (rm -f $@ ; false) diff --git a/scripts/bin_size b/scripts/bin_size new file mode 100644 index 00000000000..43e1b360cee --- /dev/null +++ b/scripts/bin_size @@ -0,0 +1,10 @@ +#!/bin/sh + +if [ $# = 0 ] ; then + echo Usage: $0 file +fi + +size_dec=`stat -c "%s" $1` +size_hex_echo_string=`printf "%08x" $size_dec | + sed 's/\(..\)\(..\)\(..\)\(..\)/\\\\x\4\\\\x\3\\\\x\2\\\\x\1/g'` +/bin/echo -ne $size_hex_echo_string -- cgit From 30d65dbfe3add7f010a075991dc0bfeaebb7d9e1 Mon Sep 17 00:00:00 2001 From: Alain Knaff Date: Sun, 4 Jan 2009 22:46:17 +0100 Subject: bzip2/lzma: config and initramfs support for bzip2/lzma decompression Impact: New code for initramfs decompression, new features This is the second part of the bzip2/lzma patch The bzip patch is based on an idea by Christian Ludwig, includes support for compressing the kernel with bzip2 or lzma rather than gzip. Both compressors give smaller sizes than gzip. Lzma's decompresses faster than bzip2. It also supports ramdisks and initramfs' compressed using these two compressors. The functionality has been successfully used for a couple of years by the udpcast project This version applies to "tip" kernel 2.6.28 This part contains: - support for new compressions (bzip2 and lzma) in initramfs and old-style ramdisk - config dialog for kernel compression (but new kernel compressions not yet supported) Signed-off-by: Alain Knaff Signed-off-by: H. Peter Anvin --- drivers/block/Kconfig | 25 +++++++ init/Kconfig | 50 ++++++++++++++ init/do_mounts_rd.c | 182 ++++++++++++++++++-------------------------------- init/initramfs.c | 123 ++++++++++++---------------------- lib/Makefile | 3 +- 5 files changed, 184 insertions(+), 199 deletions(-) diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 0344a8a8321..79559444242 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -358,6 +358,31 @@ config BLK_DEV_XIP will prevent RAM block device backing store memory from being allocated from highmem (only a problem for highmem systems). +config RD_BZIP2 + bool "Initial ramdisk compressed using bzip2" + default n + depends on BLK_DEV_INITRD=y + help + Support loading of a bzip2 encoded initial ramdisk or cpio buffer + If unsure, say N. + +config RD_LZMA + bool "Initial ramdisk compressed using lzma" + default n + depends on BLK_DEV_INITRD=y + help + Support loading of a lzma encoded initial ramdisk or cpio buffer + If unsure, say N. + +config RD_GZIP + bool "Initial ramdisk compressed using gzip" + default y + depends on BLK_DEV_INITRD=y + select ZLIB_INFLATE + help + Support loading of a gzip encoded initial ramdisk or cpio buffer. + If unsure, say Y. + config CDROM_PKTCDVD tristate "Packet writing on CD/DVD media" depends on !UML diff --git a/init/Kconfig b/init/Kconfig index f6281711166..df84625b137 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -101,6 +101,56 @@ config LOCALVERSION_AUTO which is done within the script "scripts/setlocalversion".) +choice + prompt "Kernel compression mode" + default KERNEL_GZIP + help + The linux kernel is a kind of self-extracting executable. + Several compression algorithms are available, which differ + in efficiency, compression and decompression speed. + Compression speed is only relevant when building a kernel. + Decompression speed is relevant at each boot. + + If you have any problems with bzip2 or lzma compressed + kernels, mail me (Alain Knaff) . (An older + version of this functionality (bzip2 only), for 2.4, was + supplied by Christian Ludwig) + + High compression options are mostly useful for users, who + are low on disk space (embedded systems), but for whom ram + size matters less. + + If in doubt, select 'gzip' + +config KERNEL_GZIP + bool "Gzip" + help + The old and tried gzip compression. Its compression ratio is + the poorest among the 3 choices; however its speed (both + compression and decompression) is the fastest. + +config KERNEL_BZIP2 + bool "Bzip2" + help + Its compression ratio and speed is intermediate. + Decompression speed is slowest among the 3. + The kernel size is about 10 per cent smaller with bzip2, + in comparison to gzip. + Bzip2 uses a large amount of memory. For modern kernels + you will need at least 8MB RAM or more for booting. + +config KERNEL_LZMA + bool "LZMA" + help + The most recent compression algorithm. + Its ratio is best, decompression speed is between the other + 2. Compression is slowest. + The kernel size is about 33 per cent smaller with lzma, + in comparison to gzip. + +endchoice + + config SWAP bool "Support for paging of anonymous memory (swap)" depends on MMU && BLOCK diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index a7c748fa977..dcaeb1f90b3 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -10,6 +10,12 @@ #include "do_mounts.h" +#include + +#include +#include +#include + int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */ static int __init prompt_ramdisk(char *str) @@ -28,7 +34,7 @@ static int __init ramdisk_start_setup(char *str) } __setup("ramdisk_start=", ramdisk_start_setup); -static int __init crd_load(int in_fd, int out_fd); +static int __init crd_load(int in_fd, int out_fd, decompress_fn deco); /* * This routine tries to find a RAM disk image to load, and returns the @@ -44,7 +50,7 @@ static int __init crd_load(int in_fd, int out_fd); * gzip */ static int __init -identify_ramdisk_image(int fd, int start_block) +identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) { const int size = 512; struct minix_super_block *minixsb; @@ -70,6 +76,7 @@ identify_ramdisk_image(int fd, int start_block) sys_lseek(fd, start_block * BLOCK_SIZE, 0); sys_read(fd, buf, size); +#ifdef CONFIG_RD_GZIP /* * If it matches the gzip magic numbers, return 0 */ @@ -77,9 +84,39 @@ identify_ramdisk_image(int fd, int start_block) printk(KERN_NOTICE "RAMDISK: Compressed image found at block %d\n", start_block); + *decompressor = gunzip; + nblocks = 0; + goto done; + } +#endif + +#ifdef CONFIG_RD_BZIP2 + /* + * If it matches the bzip2 magic numbers, return -1 + */ + if (buf[0] == 0x42 && (buf[1] == 0x5a)) { + printk(KERN_NOTICE + "RAMDISK: Bzipped image found at block %d\n", + start_block); + *decompressor = bunzip2; + nblocks = 0; + goto done; + } +#endif + +#ifdef CONFIG_RD_LZMA + /* + * If it matches the lzma magic numbers, return -1 + */ + if (buf[0] == 0x5d && (buf[1] == 0x00)) { + printk(KERN_NOTICE + "RAMDISK: Lzma image found at block %d\n", + start_block); + *decompressor = unlzma; nblocks = 0; goto done; } +#endif /* romfs is at block zero too */ if (romfsb->word0 == ROMSB_WORD0 && @@ -143,6 +180,7 @@ int __init rd_load_image(char *from) int nblocks, i, disk; char *buf = NULL; unsigned short rotate = 0; + decompress_fn decompressor = NULL; #if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES) char rotator[4] = { '|' , '/' , '-' , '\\' }; #endif @@ -155,12 +193,12 @@ int __init rd_load_image(char *from) if (in_fd < 0) goto noclose_input; - nblocks = identify_ramdisk_image(in_fd, rd_image_start); + nblocks = identify_ramdisk_image(in_fd, rd_image_start, &decompressor); if (nblocks < 0) goto done; if (nblocks == 0) { - if (crd_load(in_fd, out_fd) == 0) + if (crd_load(in_fd, out_fd, decompressor) == 0) goto successful_load; goto done; } @@ -259,138 +297,48 @@ int __init rd_load_disk(int n) return rd_load_image("/dev/root"); } -/* - * gzip declarations - */ - -#define OF(args) args - -#ifndef memzero -#define memzero(s, n) memset ((s), 0, (n)) -#endif - -typedef unsigned char uch; -typedef unsigned short ush; -typedef unsigned long ulg; - -#define INBUFSIZ 4096 -#define WSIZE 0x8000 /* window size--must be a power of two, and */ - /* at least 32K for zip's deflate method */ - -static uch *inbuf; -static uch *window; - -static unsigned insize; /* valid bytes in inbuf */ -static unsigned inptr; /* index of next byte to be processed in inbuf */ -static unsigned outcnt; /* bytes in output buffer */ static int exit_code; -static int unzip_error; -static long bytes_out; +static int decompress_error; static int crd_infd, crd_outfd; -#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) - -/* Diagnostic functions (stubbed out) */ -#define Assert(cond,msg) -#define Trace(x) -#define Tracev(x) -#define Tracevv(x) -#define Tracec(c,x) -#define Tracecv(c,x) - -#define STATIC static -#define INIT __init - -static int __init fill_inbuf(void); -static void __init flush_window(void); -static void __init error(char *m); - -#define NO_INFLATE_MALLOC - -#include "../lib/inflate.c" - -/* =========================================================================== - * Fill the input buffer. This is called only when the buffer is empty - * and at least one byte is really needed. - * Returning -1 does not guarantee that gunzip() will ever return. - */ -static int __init fill_inbuf(void) +static int __init compr_fill(void *buf, unsigned int len) { - if (exit_code) return -1; - - insize = sys_read(crd_infd, inbuf, INBUFSIZ); - if (insize == 0) { - error("RAMDISK: ran out of compressed data"); - return -1; - } - - inptr = 1; - - return inbuf[0]; + int r = sys_read(crd_infd, buf, len); + if (r < 0) + printk(KERN_ERR "RAMDISK: error while reading compressed data"); + else if (r == 0) + printk(KERN_ERR "RAMDISK: EOF while reading compressed data"); + return r; } -/* =========================================================================== - * Write the output window window[0..outcnt-1] and update crc and bytes_out. - * (Used for the decompressed data only.) - */ -static void __init flush_window(void) +static int __init compr_flush(void *window, unsigned int outcnt) { - ulg c = crc; /* temporary variable */ - unsigned n, written; - uch *in, ch; - - written = sys_write(crd_outfd, window, outcnt); - if (written != outcnt && unzip_error == 0) { - printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n", - written, outcnt, bytes_out); - unzip_error = 1; - } - in = window; - for (n = 0; n < outcnt; n++) { - ch = *in++; - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); - } - crc = c; - bytes_out += (ulg)outcnt; - outcnt = 0; + int written = sys_write(crd_outfd, window, outcnt); + if (written != outcnt) { + if (decompress_error == 0) + printk(KERN_ERR + "RAMDISK: incomplete write (%d != %d)\n", + written, outcnt); + decompress_error = 1; + return -1; + } + return outcnt; } static void __init error(char *x) { printk(KERN_ERR "%s\n", x); exit_code = 1; - unzip_error = 1; + decompress_error = 1; } -static int __init crd_load(int in_fd, int out_fd) +static int __init crd_load(int in_fd, int out_fd, decompress_fn deco) { int result; - - insize = 0; /* valid bytes in inbuf */ - inptr = 0; /* index of next byte to be processed in inbuf */ - outcnt = 0; /* bytes in output buffer */ - exit_code = 0; - bytes_out = 0; - crc = (ulg)0xffffffffL; /* shift register contents */ - crd_infd = in_fd; crd_outfd = out_fd; - inbuf = kmalloc(INBUFSIZ, GFP_KERNEL); - if (!inbuf) { - printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n"); - return -1; - } - window = kmalloc(WSIZE, GFP_KERNEL); - if (!window) { - printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n"); - kfree(inbuf); - return -1; - } - makecrc(); - result = gunzip(); - if (unzip_error) + result = deco(NULL, 0, compr_fill, compr_flush, NULL, NULL, error); + if (decompress_error) result = 1; - kfree(inbuf); - kfree(window); return result; } diff --git a/init/initramfs.c b/init/initramfs.c index 4f5ba75aaa7..40bd4fb9578 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -389,11 +389,14 @@ static int __init write_buffer(char *buf, unsigned len) return len - count; } -static void __init flush_buffer(char *buf, unsigned len) + +static int __init flush_buffer(void *bufv, unsigned len) { + char *buf = (char *) bufv; int written; + int origLen = len; if (message) - return; + return -1; while ((written = write_buffer(buf, len)) < len && !message) { char c = buf[written]; if (c == '0') { @@ -407,73 +410,14 @@ static void __init flush_buffer(char *buf, unsigned len) } else error("junk in compressed archive"); } + return origLen; } -/* - * gzip declarations - */ - -#define OF(args) args - -#ifndef memzero -#define memzero(s, n) memset ((s), 0, (n)) -#endif - -typedef unsigned char uch; -typedef unsigned short ush; -typedef unsigned long ulg; - -#define WSIZE 0x8000 /* window size--must be a power of two, and */ - /* at least 32K for zip's deflate method */ - -static uch *inbuf; -static uch *window; - -static unsigned insize; /* valid bytes in inbuf */ -static unsigned inptr; /* index of next byte to be processed in inbuf */ -static unsigned outcnt; /* bytes in output buffer */ -static long bytes_out; - -#define get_byte() (inptr < insize ? inbuf[inptr++] : -1) - -/* Diagnostic functions (stubbed out) */ -#define Assert(cond,msg) -#define Trace(x) -#define Tracev(x) -#define Tracevv(x) -#define Tracec(c,x) -#define Tracecv(c,x) - -#define STATIC static -#define INIT __init - -static void __init flush_window(void); -static void __init error(char *m); - -#define NO_INFLATE_MALLOC +static unsigned my_inptr; /* index of next byte to be processed in inbuf */ -#include "../lib/inflate.c" - -/* =========================================================================== - * Write the output window window[0..outcnt-1] and update crc and bytes_out. - * (Used for the decompressed data only.) - */ -static void __init flush_window(void) -{ - ulg c = crc; /* temporary variable */ - unsigned n; - uch *in, ch; - - flush_buffer(window, outcnt); - in = window; - for (n = 0; n < outcnt; n++) { - ch = *in++; - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); - } - crc = c; - bytes_out += (ulg)outcnt; - outcnt = 0; -} +#include +#include +#include static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only) { @@ -482,9 +426,10 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only) header_buf = kmalloc(110, GFP_KERNEL); symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL); name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL); - window = kmalloc(WSIZE, GFP_KERNEL); - if (!window || !header_buf || !symlink_buf || !name_buf) + + if (!header_buf || !symlink_buf || !name_buf) panic("can't allocate buffers"); + state = Start; this_header = 0; message = NULL; @@ -504,22 +449,38 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only) continue; } this_header = 0; - insize = len; - inbuf = buf; - inptr = 0; - outcnt = 0; /* bytes in output buffer */ - bytes_out = 0; - crc = (ulg)0xffffffffL; /* shift register contents */ - makecrc(); - gunzip(); + if (!gunzip(buf, len, NULL, flush_buffer, NULL, + &my_inptr, error) && + message == NULL) + goto ok; + +#ifdef CONFIG_RD_BZIP2 + message = NULL; /* Zero out message, or else cpio will + think an error has already occured */ + if (!bunzip2(buf, len, NULL, flush_buffer, NULL, + &my_inptr, error) && + message == NULL) { + goto ok; + } +#endif + +#ifdef CONFIG_RD_LZMA + message = NULL; /* Zero out message, or else cpio will + think an error has already occured */ + if (!unlzma(buf, len, NULL, flush_buffer, NULL, + &my_inptr, error) && + message == NULL) { + goto ok; + } +#endif +ok: if (state != Reset) - error("junk in gzipped archive"); - this_header = saved_offset + inptr; - buf += inptr; - len -= inptr; + error("junk in compressed archive"); + this_header = saved_offset + my_inptr; + buf += my_inptr; + len -= my_inptr; } dir_utime(); - kfree(window); kfree(name_buf); kfree(symlink_buf); kfree(header_buf); diff --git a/lib/Makefile b/lib/Makefile index 32b0e64ded2..e2a21d5a264 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -11,7 +11,8 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \ rbtree.o radix-tree.o dump_stack.o \ idr.o int_sqrt.o extable.o prio_tree.o \ sha1.o irq_regs.o reciprocal_div.o argv_split.o \ - proportions.o prio_heap.o ratelimit.o show_mem.o is_single_threaded.o + proportions.o prio_heap.o ratelimit.o show_mem.o is_single_threaded.o \ + decompress_inflate.o decompress_bunzip2.o decompress_unlzma.o lib-$(CONFIG_MMU) += ioremap.o lib-$(CONFIG_SMP) += cpumask.o -- cgit From b172fd882d201cf8aa67cddd9c1a023421fd4956 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sun, 4 Jan 2009 14:42:52 -0800 Subject: bzip2/lzma: use a table to search for initramfs compression formats Impact: Code simplification Instead of open-coding testing for initramfs compression formats, use a table. Signed-off-by: H. Peter Anvin --- init/do_mounts_rd.c | 82 +++++++++++++++++++++++------------------------------ 1 file changed, 35 insertions(+), 47 deletions(-) diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index dcaeb1f90b3..9c9d7dbcf9c 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -43,13 +43,31 @@ static int __init crd_load(int in_fd, int out_fd, decompress_fn deco); * numbers could not be found. * * We currently check for the following magic numbers: - * minix - * ext2 + * minix + * ext2 * romfs * cramfs - * gzip + * gzip */ -static int __init +static const struct compress_format { + unsigned char magic[2]; + const char *name; + decompress_fn decompressor; +} compressed_formats[] = { +#ifdef CONFIG_RD_GZIP + { {037, 0213}, "gzip", gunzip }, + { {037, 0236}, "gzip", gunzip }, +#endif +#ifdef CONFIG_RD_BZIP2 + { {0x42, 0x5a}, "bzip2", bunzip2 }, +#endif +#ifdef CONFIG_RD_LZMA + { {0x5d, 0x00}, "lzma", unlzma }, +#endif + { {0, 0}, NULL, NULL } +}; + +static int __init identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) { const int size = 512; @@ -59,6 +77,7 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) struct cramfs_super *cramfsb; int nblocks = -1; unsigned char *buf; + const struct compress_format *cf; buf = kmalloc(size, GFP_KERNEL); if (!buf) @@ -71,52 +90,21 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) memset(buf, 0xe5, size); /* - * Read block 0 to test for gzipped kernel + * Read block 0 to test for compressed kernel */ sys_lseek(fd, start_block * BLOCK_SIZE, 0); sys_read(fd, buf, size); -#ifdef CONFIG_RD_GZIP - /* - * If it matches the gzip magic numbers, return 0 - */ - if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) { - printk(KERN_NOTICE - "RAMDISK: Compressed image found at block %d\n", - start_block); - *decompressor = gunzip; - nblocks = 0; - goto done; - } -#endif - -#ifdef CONFIG_RD_BZIP2 - /* - * If it matches the bzip2 magic numbers, return -1 - */ - if (buf[0] == 0x42 && (buf[1] == 0x5a)) { - printk(KERN_NOTICE - "RAMDISK: Bzipped image found at block %d\n", - start_block); - *decompressor = bunzip2; - nblocks = 0; - goto done; - } -#endif - -#ifdef CONFIG_RD_LZMA - /* - * If it matches the lzma magic numbers, return -1 - */ - if (buf[0] == 0x5d && (buf[1] == 0x00)) { - printk(KERN_NOTICE - "RAMDISK: Lzma image found at block %d\n", - start_block); - *decompressor = unlzma; - nblocks = 0; - goto done; + for (cf = compressed_formats; cf->decompressor; cf++) { + if (buf[0] == cf->magic[0] && buf[1] == cf->magic[1]) { + printk(KERN_NOTICE + "RAMDISK: %s image found at block %d\n", + cf->name, start_block); + *decompressor = cf->decompressor; + nblocks = 0; + goto done; + } } -#endif /* romfs is at block zero too */ if (romfsb->word0 == ROMSB_WORD0 && @@ -165,7 +153,7 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) printk(KERN_NOTICE "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n", start_block); - + done: sys_lseek(fd, start_block * BLOCK_SIZE, 0); kfree(buf); @@ -224,7 +212,7 @@ int __init rd_load_image(char *from) nblocks, rd_blocks); goto done; } - + /* * OK, time to copy in the data */ -- cgit From ae03c49964af5033534e518eebe439c3b90f43a7 Mon Sep 17 00:00:00 2001 From: Alain Knaff Date: Sun, 4 Jan 2009 22:46:17 +0100 Subject: bzip2/lzma: x86 kernel compression support Impact: Replaces x86 kernel decompressor with new code This is the third part of the bzip2/lzma patch The bzip patch is based on an idea by Christian Ludwig, includes support for compressing the kernel with bzip2 or lzma rather than gzip. Both compressors give smaller sizes than gzip. Lzma's decompresses faster than bzip2. It also supports ramdisks and initramfs' compressed using these two compressors. The functionality has been successfully used for a couple of years by the udpcast project This version applies to "tip" kernel 2.6.28 This part contains: - support for new bzip2 and lzma kernel compression for x86 Signed-off-by: Alain Knaff Signed-off-by: H. Peter Anvin --- arch/x86/boot/compressed/Makefile | 21 ++++++- arch/x86/boot/compressed/misc.c | 118 +++++--------------------------------- arch/x86/include/asm/boot.h | 12 +++- 3 files changed, 44 insertions(+), 107 deletions(-) diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 1771c804e02..3ca4c194b8e 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -4,7 +4,7 @@ # create a compressed vmlinux image from the original vmlinux # -targets := vmlinux vmlinux.bin vmlinux.bin.gz head_$(BITS).o misc.o piggy.o +targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma head_$(BITS).o misc.o piggy.o KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 KBUILD_CFLAGS += -fno-strict-aliasing -fPIC @@ -47,18 +47,35 @@ ifeq ($(CONFIG_X86_32),y) ifdef CONFIG_RELOCATABLE $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin.all FORCE $(call if_changed,gzip) +$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin.all FORCE + $(call if_changed,bzip2) +$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin.all FORCE + $(call if_changed,lzma) else $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE $(call if_changed,gzip) +$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE + $(call if_changed,bzip2) +$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE + $(call if_changed,lzma) endif LDFLAGS_piggy.o := -r --format binary --oformat elf32-i386 -T else + $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE $(call if_changed,gzip) +$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE + $(call if_changed,bzip2) +$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE + $(call if_changed,lzma) LDFLAGS_piggy.o := -r --format binary --oformat elf64-x86-64 -T endif -$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE +suffix_$(CONFIG_KERNEL_GZIP) = gz +suffix_$(CONFIG_KERNEL_BZIP2) = bz2 +suffix_$(CONFIG_KERNEL_LZMA) = lzma + +$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix_y) FORCE $(call if_changed,ld) diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index da062216948..e45be73684f 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c @@ -116,71 +116,13 @@ /* * gzip declarations */ - -#define OF(args) args #define STATIC static #undef memset #undef memcpy #define memzero(s, n) memset((s), 0, (n)) -typedef unsigned char uch; -typedef unsigned short ush; -typedef unsigned long ulg; - -/* - * Window size must be at least 32k, and a power of two. - * We don't actually have a window just a huge output buffer, - * so we report a 2G window size, as that should always be - * larger than our output buffer: - */ -#define WSIZE 0x80000000 - -/* Input buffer: */ -static unsigned char *inbuf; - -/* Sliding window buffer (and final output buffer): */ -static unsigned char *window; - -/* Valid bytes in inbuf: */ -static unsigned insize; - -/* Index of next byte to be processed in inbuf: */ -static unsigned inptr; - -/* Bytes in output buffer: */ -static unsigned outcnt; - -/* gzip flag byte */ -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ -#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gz file */ -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ -#define ORIG_NAM 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() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) - -/* Diagnostic functions */ -#ifdef DEBUG -# define Assert(cond, msg) do { if (!(cond)) error(msg); } while (0) -# define Trace(x) do { fprintf x; } while (0) -# 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 int fill_inbuf(void); -static void flush_window(void); static void error(char *m); /* @@ -189,13 +131,8 @@ static void error(char *m); static struct boot_params *real_mode; /* Pointer to real-mode data */ static int quiet; -extern unsigned char input_data[]; -extern int input_len; - -static long bytes_out; - static void *memset(void *s, int c, unsigned n); -static void *memcpy(void *dest, const void *src, unsigned n); +void *memcpy(void *dest, const void *src, unsigned n); static void __putstr(int, const char *); #define putstr(__x) __putstr(0, __x) @@ -213,7 +150,17 @@ static char *vidmem; static int vidport; static int lines, cols; -#include "../../../../lib/inflate.c" +#ifdef CONFIG_KERNEL_GZIP +#include "../../../../lib/decompress_inflate.c" +#endif + +#ifdef CONFIG_KERNEL_BZIP2 +#include "../../../../lib/decompress_bunzip2.c" +#endif + +#ifdef CONFIG_KERNEL_LZMA +#include "../../../../lib/decompress_unlzma.c" +#endif static void scroll(void) { @@ -282,7 +229,7 @@ static void *memset(void *s, int c, unsigned n) return s; } -static void *memcpy(void *dest, const void *src, unsigned n) +void *memcpy(void *dest, const void *src, unsigned n) { int i; const char *s = src; @@ -293,38 +240,6 @@ static void *memcpy(void *dest, const void *src, unsigned n) return dest; } -/* =========================================================================== - * Fill the input buffer. This is called only when the buffer is empty - * and at least one byte is really needed. - */ -static int fill_inbuf(void) -{ - error("ran out of input data"); - return 0; -} - -/* =========================================================================== - * 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) -{ - /* With my window equal to my output buffer - * I only need to compute the crc here. - */ - unsigned long c = crc; /* temporary variable */ - unsigned n; - unsigned char *in, ch; - - in = window; - for (n = 0; n < outcnt; n++) { - ch = *in++; - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); - } - crc = c; - bytes_out += (unsigned long)outcnt; - outcnt = 0; -} static void error(char *x) { @@ -407,12 +322,8 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap, lines = real_mode->screen_info.orig_video_lines; cols = real_mode->screen_info.orig_video_cols; - window = output; /* Output buffer (Normally at 1M) */ free_mem_ptr = heap; /* Heap */ free_mem_end_ptr = heap + BOOT_HEAP_SIZE; - inbuf = input_data; /* Input buffer */ - insize = input_len; - inptr = 0; #ifdef CONFIG_X86_64 if ((unsigned long)output & (__KERNEL_ALIGN - 1)) @@ -430,10 +341,9 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap, #endif #endif - makecrc(); if (!quiet) putstr("\nDecompressing Linux... "); - gunzip(); + decompress(input_data, input_len, NULL, NULL, output, NULL, error); parse_elf(output); if (!quiet) putstr("done.\nBooting the kernel.\n"); diff --git a/arch/x86/include/asm/boot.h b/arch/x86/include/asm/boot.h index dd61616cb73..c0e8e68a31f 100644 --- a/arch/x86/include/asm/boot.h +++ b/arch/x86/include/asm/boot.h @@ -15,11 +15,21 @@ + (CONFIG_PHYSICAL_ALIGN - 1)) \ & ~(CONFIG_PHYSICAL_ALIGN - 1)) +#if (defined CONFIG_KERNEL_BZIP2) +#define BOOT_HEAP_SIZE 0x400000 +#else + #ifdef CONFIG_X86_64 #define BOOT_HEAP_SIZE 0x7000 -#define BOOT_STACK_SIZE 0x4000 #else #define BOOT_HEAP_SIZE 0x4000 +#endif + +#endif + +#ifdef CONFIG_X86_64 +#define BOOT_STACK_SIZE 0x4000 +#else #define BOOT_STACK_SIZE 0x1000 #endif -- cgit From 0f5e2d2484ccd3062bb1f63083bafa37041bc868 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sun, 4 Jan 2009 15:10:40 -0800 Subject: bzip2/lzma: handle failures from bzip2 and lzma correctly Impact: Bug fix If bzip2 or lzma fails (for example, if they aren't installed on the system), we need to propagate the failure out to "make". However, they were masked by being followed by a semicolon. Signed-off-by: H. Peter Anvin --- scripts/Makefile.lib | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 70b4676e3b9..3b949a35447 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -193,10 +193,10 @@ cmd_gzip = gzip -f -9 < $< > $@ size_append=$(CONFIG_SHELL) $(srctree)/scripts/bin_size quiet_cmd_bzip2 = BZIP2 $@ -cmd_bzip2 = (bzip2 -9 < $< ; $(size_append) $<) > $@ || (rm -f $@ ; false) +cmd_bzip2 = (bzip2 -9 < $< && $(size_append) $<) > $@ || (rm -f $@ ; false) # Lzma # --------------------------------------------------------------------------- quiet_cmd_lzma = LZMA $@ -cmd_lzma = (lzma -9 -c $< ; $(size_append) $<) >$@ || (rm -f $@ ; false) +cmd_lzma = (lzma -9 -c $< && $(size_append) $<) >$@ || (rm -f $@ ; false) -- cgit From 2e9f3bddcbc711bb14d86c6f068a779bf3710247 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sun, 4 Jan 2009 15:41:25 -0800 Subject: bzip2/lzma: make config machinery an arch configurable Impact: Bug fix (we should not show this menu on irrelevant architectures) Make the config machinery to drive the gzip/bzip2/lzma selection dependent on the architecture advertising HAVE_KERNEL_* so that we don't display this for architectures where it doesn't matter. Signed-off-by: H. Peter Anvin --- arch/x86/Kconfig | 3 +++ init/Kconfig | 52 +++++++++++++++++++++++++++++++--------------------- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 862adb9bf0d..7b66c34d0aa 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -39,6 +39,9 @@ config X86 select HAVE_GENERIC_DMA_COHERENT if X86_32 select HAVE_EFFICIENT_UNALIGNED_ACCESS select USER_STACKTRACE_SUPPORT + select HAVE_KERNEL_GZIP + select HAVE_KERNEL_BZIP2 + select HAVE_KERNEL_LZMA config ARCH_DEFCONFIG string diff --git a/init/Kconfig b/init/Kconfig index df84625b137..f9633c03cb1 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -101,10 +101,20 @@ config LOCALVERSION_AUTO which is done within the script "scripts/setlocalversion".) +config HAVE_KERNEL_GZIP + bool + +config HAVE_KERNEL_BZIP2 + bool + +config HAVE_KERNEL_LZMA + bool + choice - prompt "Kernel compression mode" - default KERNEL_GZIP - help + prompt "Kernel compression mode" + default KERNEL_GZIP + depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZMA + help The linux kernel is a kind of self-extracting executable. Several compression algorithms are available, which differ in efficiency, compression and decompression speed. @@ -123,34 +133,34 @@ choice If in doubt, select 'gzip' config KERNEL_GZIP - bool "Gzip" - help - The old and tried gzip compression. Its compression ratio is - the poorest among the 3 choices; however its speed (both - compression and decompression) is the fastest. + bool "Gzip" + depends on HAVE_KERNEL_GZIP + help + The old and tried gzip compression. Its compression ratio is + the poorest among the 3 choices; however its speed (both + compression and decompression) is the fastest. config KERNEL_BZIP2 bool "Bzip2" + depends on HAVE_KERNEL_BZIP2 help Its compression ratio and speed is intermediate. - Decompression speed is slowest among the 3. - The kernel size is about 10 per cent smaller with bzip2, - in comparison to gzip. - Bzip2 uses a large amount of memory. For modern kernels - you will need at least 8MB RAM or more for booting. + Decompression speed is slowest among the three. The kernel + size is about 10% smaller with bzip2, in comparison to gzip. + Bzip2 uses a large amount of memory. For modern kernels you + will need at least 8MB RAM or more for booting. config KERNEL_LZMA - bool "LZMA" - help - The most recent compression algorithm. - Its ratio is best, decompression speed is between the other - 2. Compression is slowest. - The kernel size is about 33 per cent smaller with lzma, - in comparison to gzip. + bool "LZMA" + depends on HAVE_KERNEL_LZMA + help + The most recent compression algorithm. + Its ratio is best, decompression speed is between the other + two. Compression is slowest. The kernel size is about 33% + smaller with LZMA in comparison to gzip. endchoice - config SWAP bool "Support for paging of anonymous memory (swap)" depends on MMU && BLOCK -- cgit From c8531ab343dec88ed8005e403b1b304c710b7494 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Mon, 5 Jan 2009 13:48:31 -0800 Subject: bzip2/lzma: proper Kconfig dependencies for the ramdisk options Impact: Partial resolution of build failure Make all the compression algorithms properly configurable, and make sure the ramdisk options pull in the proper compression algorithms, as they should. Signed-off-by: H. Peter Anvin --- drivers/block/Kconfig | 20 +++++++++++--------- lib/Kconfig | 13 +++++++++++++ lib/Makefile | 7 +++++-- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 79559444242..cc9fa69c1ce 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -358,10 +358,20 @@ config BLK_DEV_XIP will prevent RAM block device backing store memory from being allocated from highmem (only a problem for highmem systems). +config RD_GZIP + bool "Initial ramdisk compressed using gzip" + default y + depends on BLK_DEV_INITRD=y + select DECOMPRESS_GZIP + help + Support loading of a gzip encoded initial ramdisk or cpio buffer. + If unsure, say Y. + config RD_BZIP2 bool "Initial ramdisk compressed using bzip2" default n depends on BLK_DEV_INITRD=y + select DECOMPRESS_BZIP2 help Support loading of a bzip2 encoded initial ramdisk or cpio buffer If unsure, say N. @@ -370,19 +380,11 @@ config RD_LZMA bool "Initial ramdisk compressed using lzma" default n depends on BLK_DEV_INITRD=y + select DECOMPRESS_LZMA help Support loading of a lzma encoded initial ramdisk or cpio buffer If unsure, say N. -config RD_GZIP - bool "Initial ramdisk compressed using gzip" - default y - depends on BLK_DEV_INITRD=y - select ZLIB_INFLATE - help - Support loading of a gzip encoded initial ramdisk or cpio buffer. - If unsure, say Y. - config CDROM_PKTCDVD tristate "Packet writing on CD/DVD media" depends on !UML diff --git a/lib/Kconfig b/lib/Kconfig index 03c2c24b908..e37f061fd32 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -97,6 +97,19 @@ config LZO_COMPRESS config LZO_DECOMPRESS tristate +# +# These all provide a common interface (hence the apparent duplication with +# ZLIB_INFLATE; DECOMPRESS_GZIP is just a wrapper.) +# +config DECOMPRESS_GZIP + tristate + +config DECOMPRESS_BZIP2 + tristate + +config DECOMPRESS_LZMA + tristate + # # Generic allocator support is selected if needed # diff --git a/lib/Makefile b/lib/Makefile index e2a21d5a264..d9ac5a414fa 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -11,8 +11,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \ rbtree.o radix-tree.o dump_stack.o \ idr.o int_sqrt.o extable.o prio_tree.o \ sha1.o irq_regs.o reciprocal_div.o argv_split.o \ - proportions.o prio_heap.o ratelimit.o show_mem.o is_single_threaded.o \ - decompress_inflate.o decompress_bunzip2.o decompress_unlzma.o + proportions.o prio_heap.o ratelimit.o show_mem.o is_single_threaded.o lib-$(CONFIG_MMU) += ioremap.o lib-$(CONFIG_SMP) += cpumask.o @@ -66,6 +65,10 @@ obj-$(CONFIG_REED_SOLOMON) += reed_solomon/ obj-$(CONFIG_LZO_COMPRESS) += lzo/ obj-$(CONFIG_LZO_DECOMPRESS) += lzo/ +obj-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o +obj-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o +obj-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o + obj-$(CONFIG_TEXTSEARCH) += textsearch.o obj-$(CONFIG_TEXTSEARCH_KMP) += ts_kmp.o obj-$(CONFIG_TEXTSEARCH_BM) += ts_bm.o -- cgit From 2226b1c219a18804bc40e32a5d53c287a6c925d9 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Tue, 6 Jan 2009 17:55:32 +0000 Subject: uwb: safely remove all reservations When removing all reservations during shutdown, terminate them first and then wait for any pending timeout work to complete. This prevents the timeout work from running after the reservation has been freed. Signed-off-by: David Vrabel --- drivers/uwb/rsv.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/uwb/rsv.c b/drivers/uwb/rsv.c index ec6eecb32f3..886f977cd2e 100644 --- a/drivers/uwb/rsv.c +++ b/drivers/uwb/rsv.c @@ -114,7 +114,8 @@ void uwb_rsv_dump(char *text, struct uwb_rsv *rsv) devaddr = rsv->target.devaddr; uwb_dev_addr_print(target, sizeof(target), &devaddr); - dev_dbg(dev, "rsv %s -> %s: %s\n", owner, target, uwb_rsv_state_str(rsv->state)); + dev_dbg(dev, "rsv %s %s -> %s: %s\n", + text, owner, target, uwb_rsv_state_str(rsv->state)); } static void uwb_rsv_release(struct kref *kref) @@ -511,8 +512,7 @@ void uwb_rsv_remove(struct uwb_rsv *rsv) if (uwb_rsv_is_owner(rsv)) uwb_rsv_put_stream(rsv); - - del_timer_sync(&rsv->timer); + uwb_dev_put(rsv->owner); if (rsv->target.type == UWB_RSV_TARGET_DEV) uwb_dev_put(rsv->target.dev); @@ -943,13 +943,22 @@ void uwb_rsv_remove_all(struct uwb_rc *rc) mutex_lock(&rc->rsvs_mutex); list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) { - uwb_rsv_remove(rsv); + if (rsv->state != UWB_RSV_STATE_NONE) + uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE); + del_timer_sync(&rsv->timer); } /* Cancel any postponed update. */ rc->set_drp_ie_pending = 0; mutex_unlock(&rc->rsvs_mutex); cancel_delayed_work_sync(&rc->rsv_update_work); + flush_workqueue(rc->rsv_workq); + + mutex_lock(&rc->rsvs_mutex); + list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) { + uwb_rsv_remove(rsv); + } + mutex_unlock(&rc->rsvs_mutex); } void uwb_rsv_init(struct uwb_rc *rc) -- cgit From 9a9b1d17ba59b78e4bae67f7a7cf546986a42e7d Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Tue, 6 Jan 2009 17:58:02 +0000 Subject: wusb: return -ENOTCONN when resetting a port with no connected device If reading the device descriptor fails during hub_port_init() fails, then the port is disabled, disconnecting the device. The port is then reset at the start of the next init attempt but there is no device to reset. Signed-off-by: David Vrabel --- drivers/usb/wusbcore/devconnect.c | 1 + drivers/usb/wusbcore/rh.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c index e2e7e4bc846..8e18141bb2e 100644 --- a/drivers/usb/wusbcore/devconnect.c +++ b/drivers/usb/wusbcore/devconnect.c @@ -386,6 +386,7 @@ static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc, | USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED); port->change |= USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE; if (wusb_dev) { + dev_dbg(wusbhc->dev, "disconnecting device from port %d\n", wusb_dev->port_idx); if (!list_empty(&wusb_dev->cack_node)) list_del_init(&wusb_dev->cack_node); /* For the one in cack_add() */ diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c index 95c6fa3bf6b..407a9fcc89c 100644 --- a/drivers/usb/wusbcore/rh.c +++ b/drivers/usb/wusbcore/rh.c @@ -100,6 +100,9 @@ static int wusbhc_rh_port_reset(struct wusbhc *wusbhc, u8 port_idx) struct wusb_port *port = wusb_port_by_idx(wusbhc, port_idx); struct wusb_dev *wusb_dev = port->wusb_dev; + if (wusb_dev == NULL) + return -ENOTCONN; + port->status |= USB_PORT_STAT_RESET; port->change |= USB_PORT_STAT_C_RESET; -- cgit From 7856a16ea03ed9b17860d756ee6473c2e57882b2 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 7 Jan 2009 00:01:43 -0800 Subject: bzip2/lzma: DECOMPRESS_GZIP should select ZLIB_INFLATE Impact: Partial resolution of build failure DECOMPRESS_GZIP is just a common-interface wrapper around the zlib_inflate code; it thus need to select it. Signed-off-by: H. Peter Anvin --- lib/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Kconfig b/lib/Kconfig index e37f061fd32..daa481824d9 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -102,6 +102,7 @@ config LZO_DECOMPRESS # ZLIB_INFLATE; DECOMPRESS_GZIP is just a wrapper.) # config DECOMPRESS_GZIP + select ZLIB_INFLATE tristate config DECOMPRESS_BZIP2 -- cgit From fb9a4ca9820fd4d7c4906bd393004662451e273e Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 7 Jan 2009 00:03:49 -0800 Subject: bzip2/lzma: move initrd/ramfs options out of BLK_DEV Impact: Partial resolution of build failure Move the initrd/initramfs configuration options from drivers/block/Kconfig to usr/Kconfig, since they do not and should not depend on CONFIG_BLK_DEV. This fixes builds when CONFIG_BLK_DEV=n. Signed-off-by: H. Peter Anvin --- drivers/block/Kconfig | 27 --------------------------- usr/Kconfig | 27 +++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index cc9fa69c1ce..0344a8a8321 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -358,33 +358,6 @@ config BLK_DEV_XIP will prevent RAM block device backing store memory from being allocated from highmem (only a problem for highmem systems). -config RD_GZIP - bool "Initial ramdisk compressed using gzip" - default y - depends on BLK_DEV_INITRD=y - select DECOMPRESS_GZIP - help - Support loading of a gzip encoded initial ramdisk or cpio buffer. - If unsure, say Y. - -config RD_BZIP2 - bool "Initial ramdisk compressed using bzip2" - default n - depends on BLK_DEV_INITRD=y - select DECOMPRESS_BZIP2 - help - Support loading of a bzip2 encoded initial ramdisk or cpio buffer - If unsure, say N. - -config RD_LZMA - bool "Initial ramdisk compressed using lzma" - default n - depends on BLK_DEV_INITRD=y - select DECOMPRESS_LZMA - help - Support loading of a lzma encoded initial ramdisk or cpio buffer - If unsure, say N. - config CDROM_PKTCDVD tristate "Packet writing on CD/DVD media" depends on !UML diff --git a/usr/Kconfig b/usr/Kconfig index 86cecb59dd0..a691a8f5898 100644 --- a/usr/Kconfig +++ b/usr/Kconfig @@ -44,3 +44,30 @@ config INITRAMFS_ROOT_GID owned by group root in the initial ramdisk image. If you are not sure, leave it set to "0". + +config RD_GZIP + bool "Initial ramdisk compressed using gzip" + default y + depends on BLK_DEV_INITRD=y + select DECOMPRESS_GZIP + help + Support loading of a gzip encoded initial ramdisk or cpio buffer. + If unsure, say Y. + +config RD_BZIP2 + bool "Initial ramdisk compressed using bzip2" + default n + depends on BLK_DEV_INITRD=y + select DECOMPRESS_BZIP2 + help + Support loading of a bzip2 encoded initial ramdisk or cpio buffer + If unsure, say N. + +config RD_LZMA + bool "Initial ramdisk compressed using lzma" + default n + depends on BLK_DEV_INITRD=y + select DECOMPRESS_LZMA + help + Support loading of a lzma encoded initial ramdisk or cpio buffer + If unsure, say N. -- cgit From a26ee60f90daffe1de6be0d093af86e7279b3dfd Mon Sep 17 00:00:00 2001 From: Alain Knaff Date: Wed, 7 Jan 2009 00:10:27 -0800 Subject: bzip2/lzma: fix built-in initramfs vs CONFIG_RD_GZIP Impact: Resolves build failures in some configurations Makes it possible to disable CONFIG_RD_GZIP . In that case, the built-in initramfs will be compressed by whatever compressor is available (bzip2 or lzma) or left uncompressed if none is available. It also removes a couple of warnings which occur when no ramdisk compression at all is chosen. It also restores the select ZLIB_INFLATE in drivers/block/Kconfig which somehow came missing. This is needed to activate compilation of the stuff in zlib_deflate. Signed-off-by: Alain Knaff Signed-off-by: H. Peter Anvin --- init/initramfs.c | 7 ++++++- scripts/gen_initramfs_list.sh | 17 +++++++++++------ usr/Makefile | 42 ++++++++++++++++++++++++++++++------------ usr/initramfs_data.S | 2 +- usr/initramfs_data.bz2.S | 29 +++++++++++++++++++++++++++++ usr/initramfs_data.gz.S | 29 +++++++++++++++++++++++++++++ usr/initramfs_data.lzma.S | 29 +++++++++++++++++++++++++++++ 7 files changed, 135 insertions(+), 20 deletions(-) create mode 100644 usr/initramfs_data.bz2.S create mode 100644 usr/initramfs_data.gz.S create mode 100644 usr/initramfs_data.lzma.S diff --git a/init/initramfs.c b/init/initramfs.c index 40bd4fb9578..a3ba91cdab8 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -389,7 +389,7 @@ static int __init write_buffer(char *buf, unsigned len) return len - count; } - +#if defined CONFIG_RD_GZIP || defined CONFIG_RD_BZIP2 || defined CONFIG_RD_LZMA static int __init flush_buffer(void *bufv, unsigned len) { char *buf = (char *) bufv; @@ -412,6 +412,7 @@ static int __init flush_buffer(void *bufv, unsigned len) } return origLen; } +#endif static unsigned my_inptr; /* index of next byte to be processed in inbuf */ @@ -449,10 +450,12 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only) continue; } this_header = 0; +#ifdef CONFIG_RD_GZIP if (!gunzip(buf, len, NULL, flush_buffer, NULL, &my_inptr, error) && message == NULL) goto ok; +#endif #ifdef CONFIG_RD_BZIP2 message = NULL; /* Zero out message, or else cpio will @@ -473,7 +476,9 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only) goto ok; } #endif +#if defined CONFIG_RD_GZIP || defined CONFIG_RD_BZIP2 || defined CONFIG_RD_LZMA ok: +#endif if (state != Reset) error("junk in compressed archive"); this_header = saved_offset + my_inptr; diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh index 5f3415f2873..41041e4923f 100644 --- a/scripts/gen_initramfs_list.sh +++ b/scripts/gen_initramfs_list.sh @@ -5,7 +5,7 @@ # Released under the terms of the GNU GPL # # Generate a cpio packed initramfs. It uses gen_init_cpio to generate -# the cpio archive, and gzip to pack it. +# the cpio archive, and then compresses it. # The script may also be used to generate the inputfile used for gen_init_cpio # This script assumes that gen_init_cpio is located in usr/ directory @@ -16,8 +16,8 @@ usage() { cat << EOF Usage: $0 [-o ] [-u ] [-g ] {-d | } ... - -o Create gzipped initramfs file named using - gen_init_cpio and gzip + -o Create compressed initramfs file named using + gen_init_cpio and compressor depending on the extension -u User ID to map to user ID 0 (root). is only meaningful if is a directory. "squash" forces all files to uid 0. @@ -225,6 +225,7 @@ cpio_list= output="/dev/stdout" output_file="" is_cpio_compressed= +compr="gzip -9 -f" arg="$1" case "$arg" in @@ -233,11 +234,15 @@ case "$arg" in echo "deps_initramfs := \\" shift ;; - "-o") # generate gzipped cpio image named $1 + "-o") # generate compressed cpio image named $1 shift output_file="$1" cpio_list="$(mktemp ${TMPDIR:-/tmp}/cpiolist.XXXXXX)" output=${cpio_list} + echo "$output_file" | grep -q "\.gz$" && compr="gzip -9 -f" + echo "$output_file" | grep -q "\.bz2$" && compr="bzip2 -9 -f" + echo "$output_file" | grep -q "\.lzma$" && compr="lzma -9 -f" + echo "$output_file" | grep -q "\.cpio$" && compr="cat" shift ;; esac @@ -274,7 +279,7 @@ while [ $# -gt 0 ]; do esac done -# If output_file is set we will generate cpio archive and gzip it +# If output_file is set we will generate cpio archive and compress it # we are carefull to delete tmp files if [ ! -z ${output_file} ]; then if [ -z ${cpio_file} ]; then @@ -287,7 +292,7 @@ if [ ! -z ${output_file} ]; then if [ "${is_cpio_compressed}" = "compressed" ]; then cat ${cpio_tfile} > ${output_file} else - cat ${cpio_tfile} | gzip -f -9 - > ${output_file} + cat ${cpio_tfile} | ${compr} - > ${output_file} fi [ -z ${cpio_file} ] && rm ${cpio_tfile} fi diff --git a/usr/Makefile b/usr/Makefile index 201f27f8cba..451cdff7dff 100644 --- a/usr/Makefile +++ b/usr/Makefile @@ -5,14 +5,32 @@ klibcdirs:; PHONY += klibcdirs +# Find out "preferred" ramdisk compressor. Order of preference is +# 1. bzip2 efficient, and likely to be present +# 2. gzip former default +# 3. lzma +# 4. none + +# None of the above +suffix_y = + +# Lzma, but no gzip nor bzip2 +suffix_$(CONFIG_RD_LZMA) = .lzma + +# Gzip, but no bzip2 +suffix_$(CONFIG_RD_GZIP) = .gz + +# Bzip2 +suffix_$(CONFIG_RD_BZIP2) = .bz2 + # Generate builtin.o based on initramfs_data.o -obj-$(CONFIG_BLK_DEV_INITRD) := initramfs_data.o +obj-$(CONFIG_BLK_DEV_INITRD) := initramfs_data$(suffix_y).o -# initramfs_data.o contains the initramfs_data.cpio.gz image. +# initramfs_data.o contains the compressed initramfs_data.cpio image. # The image is included using .incbin, a dependency which is not # tracked automatically. -$(obj)/initramfs_data.o: $(obj)/initramfs_data.cpio.gz FORCE +$(obj)/initramfs_data$(suffix_y).o: $(obj)/initramfs_data.cpio$(suffix_y) FORCE ##### # Generate the initramfs cpio archive @@ -25,28 +43,28 @@ ramfs-args := \ $(if $(CONFIG_INITRAMFS_ROOT_UID), -u $(CONFIG_INITRAMFS_ROOT_UID)) \ $(if $(CONFIG_INITRAMFS_ROOT_GID), -g $(CONFIG_INITRAMFS_ROOT_GID)) -# .initramfs_data.cpio.gz.d is used to identify all files included +# .initramfs_data.cpio.d is used to identify all files included # in initramfs and to detect if any files are added/removed. # Removed files are identified by directory timestamp being updated # The dependency list is generated by gen_initramfs.sh -l -ifneq ($(wildcard $(obj)/.initramfs_data.cpio.gz.d),) - include $(obj)/.initramfs_data.cpio.gz.d +ifneq ($(wildcard $(obj)/.initramfs_data.cpio.d),) + include $(obj)/.initramfs_data.cpio.d endif quiet_cmd_initfs = GEN $@ cmd_initfs = $(initramfs) -o $@ $(ramfs-args) $(ramfs-input) -targets := initramfs_data.cpio.gz +targets := initramfs_data.cpio.gz initramfs_data.cpio.bz2 initramfs_data.cpio.lzma initramfs_data.cpio # do not try to update files included in initramfs $(deps_initramfs): ; $(deps_initramfs): klibcdirs -# We rebuild initramfs_data.cpio.gz if: -# 1) Any included file is newer then initramfs_data.cpio.gz +# We rebuild initramfs_data.cpio if: +# 1) Any included file is newer then initramfs_data.cpio # 2) There are changes in which files are included (added or deleted) -# 3) If gen_init_cpio are newer than initramfs_data.cpio.gz +# 3) If gen_init_cpio are newer than initramfs_data.cpio # 4) arguments to gen_initramfs.sh changes -$(obj)/initramfs_data.cpio.gz: $(obj)/gen_init_cpio $(deps_initramfs) klibcdirs - $(Q)$(initramfs) -l $(ramfs-input) > $(obj)/.initramfs_data.cpio.gz.d +$(obj)/initramfs_data.cpio$(suffix_y): $(obj)/gen_init_cpio $(deps_initramfs) klibcdirs + $(Q)$(initramfs) -l $(ramfs-input) > $(obj)/.initramfs_data.cpio.d $(call if_changed,initfs) diff --git a/usr/initramfs_data.S b/usr/initramfs_data.S index c2e1ad424f4..7c6973d8d82 100644 --- a/usr/initramfs_data.S +++ b/usr/initramfs_data.S @@ -26,5 +26,5 @@ SECTIONS */ .section .init.ramfs,"a" -.incbin "usr/initramfs_data.cpio.gz" +.incbin "usr/initramfs_data.cpio" diff --git a/usr/initramfs_data.bz2.S b/usr/initramfs_data.bz2.S new file mode 100644 index 00000000000..bc54d090365 --- /dev/null +++ b/usr/initramfs_data.bz2.S @@ -0,0 +1,29 @@ +/* + initramfs_data includes the compressed binary that is the + filesystem used for early user space. + Note: Older versions of "as" (prior to binutils 2.11.90.0.23 + released on 2001-07-14) dit not support .incbin. + If you are forced to use older binutils than that then the + following trick can be applied to create the resulting binary: + + + ld -m elf_i386 --format binary --oformat elf32-i386 -r \ + -T initramfs_data.scr initramfs_data.cpio.gz -o initramfs_data.o + ld -m elf_i386 -r -o built-in.o initramfs_data.o + + initramfs_data.scr looks like this: +SECTIONS +{ + .init.ramfs : { *(.data) } +} + + The above example is for i386 - the parameters vary from architectures. + Eventually look up LDFLAGS_BLOB in an older version of the + arch/$(ARCH)/Makefile to see the flags used before .incbin was introduced. + + Using .incbin has the advantage over ld that the correct flags are set + in the ELF header, as required by certain architectures. +*/ + +.section .init.ramfs,"a" +.incbin "usr/initramfs_data.cpio.bz2" diff --git a/usr/initramfs_data.gz.S b/usr/initramfs_data.gz.S new file mode 100644 index 00000000000..890c8dd1d6b --- /dev/null +++ b/usr/initramfs_data.gz.S @@ -0,0 +1,29 @@ +/* + initramfs_data includes the compressed binary that is the + filesystem used for early user space. + Note: Older versions of "as" (prior to binutils 2.11.90.0.23 + released on 2001-07-14) dit not support .incbin. + If you are forced to use older binutils than that then the + following trick can be applied to create the resulting binary: + + + ld -m elf_i386 --format binary --oformat elf32-i386 -r \ + -T initramfs_data.scr initramfs_data.cpio.gz -o initramfs_data.o + ld -m elf_i386 -r -o built-in.o initramfs_data.o + + initramfs_data.scr looks like this: +SECTIONS +{ + .init.ramfs : { *(.data) } +} + + The above example is for i386 - the parameters vary from architectures. + Eventually look up LDFLAGS_BLOB in an older version of the + arch/$(ARCH)/Makefile to see the flags used before .incbin was introduced. + + Using .incbin has the advantage over ld that the correct flags are set + in the ELF header, as required by certain architectures. +*/ + +.section .init.ramfs,"a" +.incbin "usr/initramfs_data.cpio.gz" diff --git a/usr/initramfs_data.lzma.S b/usr/initramfs_data.lzma.S new file mode 100644 index 00000000000..e11469e4856 --- /dev/null +++ b/usr/initramfs_data.lzma.S @@ -0,0 +1,29 @@ +/* + initramfs_data includes the compressed binary that is the + filesystem used for early user space. + Note: Older versions of "as" (prior to binutils 2.11.90.0.23 + released on 2001-07-14) dit not support .incbin. + If you are forced to use older binutils than that then the + following trick can be applied to create the resulting binary: + + + ld -m elf_i386 --format binary --oformat elf32-i386 -r \ + -T initramfs_data.scr initramfs_data.cpio.gz -o initramfs_data.o + ld -m elf_i386 -r -o built-in.o initramfs_data.o + + initramfs_data.scr looks like this: +SECTIONS +{ + .init.ramfs : { *(.data) } +} + + The above example is for i386 - the parameters vary from architectures. + Eventually look up LDFLAGS_BLOB in an older version of the + arch/$(ARCH)/Makefile to see the flags used before .incbin was introduced. + + Using .incbin has the advantage over ld that the correct flags are set + in the ELF header, as required by certain architectures. +*/ + +.section .init.ramfs,"a" +.incbin "usr/initramfs_data.cpio.lzma" -- cgit From 04c470adb01c62bb9bd663cfc4875cf0a4eb01ab Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Sun, 4 Jan 2009 11:13:50 +0800 Subject: uwb: remove unused #include 's Remove unused #include 's in file(s) below, drivers/uwb/allocator.c Signed-off-by: Huang Weiyi Signed-off-by: David Vrabel --- drivers/uwb/allocator.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/uwb/allocator.c b/drivers/uwb/allocator.c index c8185e6b0cd..c13cec7dcbc 100644 --- a/drivers/uwb/allocator.c +++ b/drivers/uwb/allocator.c @@ -15,7 +15,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -#include #include #include -- cgit From a5e6ced58d423cb09c4fc0087dcfdb0b5deb5e1c Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Wed, 7 Jan 2009 10:54:22 +0000 Subject: wusb: timeout when waiting for ASL/PZL updates in whci-hcd Timeout if an ASL or PZL update doesn't not complete and reset the hardware. Signed-off-by: David Vrabel --- drivers/usb/host/whci/asl.c | 9 +++++++-- drivers/usb/host/whci/hw.c | 15 +++++++++++++++ drivers/usb/host/whci/pzl.c | 9 +++++++-- drivers/usb/host/whci/whcd.h | 1 + 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c index 577c0d29849..2291c5f5af5 100644 --- a/drivers/usb/host/whci/asl.c +++ b/drivers/usb/host/whci/asl.c @@ -170,12 +170,17 @@ void asl_stop(struct whc *whc) void asl_update(struct whc *whc, uint32_t wusbcmd) { struct wusbhc *wusbhc = &whc->wusbhc; + long t; mutex_lock(&wusbhc->mutex); if (wusbhc->active) { whc_write_wusbcmd(whc, wusbcmd, wusbcmd); - wait_event(whc->async_list_wq, - (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0); + t = wait_event_timeout( + whc->async_list_wq, + (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0, + msecs_to_jiffies(1000)); + if (t == 0) + whc_hw_error(whc, "ASL update timeout"); } mutex_unlock(&wusbhc->mutex); } diff --git a/drivers/usb/host/whci/hw.c b/drivers/usb/host/whci/hw.c index d498e720321..6afa2e37916 100644 --- a/drivers/usb/host/whci/hw.c +++ b/drivers/usb/host/whci/hw.c @@ -87,3 +87,18 @@ out: return ret; } + +/** + * whc_hw_error - recover from a hardware error + * @whc: the WHCI HC that broke. + * @reason: a description of the failure. + * + * Recover from broken hardware with a full reset. + */ +void whc_hw_error(struct whc *whc, const char *reason) +{ + struct wusbhc *wusbhc = &whc->wusbhc; + + dev_err(&whc->umc->dev, "hardware error: %s\n", reason); + wusbhc_reset_all(wusbhc); +} diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c index 2ae5abf69a6..7dc85a0bee7 100644 --- a/drivers/usb/host/whci/pzl.c +++ b/drivers/usb/host/whci/pzl.c @@ -183,12 +183,17 @@ void pzl_stop(struct whc *whc) void pzl_update(struct whc *whc, uint32_t wusbcmd) { struct wusbhc *wusbhc = &whc->wusbhc; + long t; mutex_lock(&wusbhc->mutex); if (wusbhc->active) { whc_write_wusbcmd(whc, wusbcmd, wusbcmd); - wait_event(whc->periodic_list_wq, - (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0); + t = wait_event_timeout( + whc->periodic_list_wq, + (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0, + msecs_to_jiffies(1000)); + if (t == 0) + whc_hw_error(whc, "PZL update timeout"); } mutex_unlock(&wusbhc->mutex); } diff --git a/drivers/usb/host/whci/whcd.h b/drivers/usb/host/whci/whcd.h index 0f3540f04f5..d3543a181dc 100644 --- a/drivers/usb/host/whci/whcd.h +++ b/drivers/usb/host/whci/whcd.h @@ -137,6 +137,7 @@ void whc_clean_up(struct whc *whc); /* hw.c */ void whc_write_wusbcmd(struct whc *whc, u32 mask, u32 val); int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len); +void whc_hw_error(struct whc *whc, const char *reason); /* wusb.c */ int whc_wusbhc_start(struct wusbhc *wusbhc); -- cgit From 7760ec77ab2a9e48bdd0d13341446a8a51f0b9f1 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Wed, 7 Jan 2009 18:10:13 +0530 Subject: x86: smp.h remove obsolete function declaration Impact: cleanup Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/include/asm/smp.h | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index 830b9fcb642..83a4cc07431 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -22,7 +22,6 @@ extern cpumask_t cpu_callout_map; extern cpumask_t cpu_initialized; extern cpumask_t cpu_callin_map; -extern void (*mtrr_hook)(void); extern void zap_low_mappings(void); extern int __cpuinit get_local_pda(int cpu); -- cgit From dacf7333571d770366bff74d10b56aa545434605 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Wed, 7 Jan 2009 17:26:35 +0530 Subject: x86: smp.h move zap_low_mappings declartion to tlbflush.h Impact: cleanup, moving NON-SMP stuff from smp.h Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/include/asm/smp.h | 2 -- arch/x86/include/asm/tlbflush.h | 2 ++ arch/x86/mm/init_32.c | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index 83a4cc07431..64c9e848f13 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -22,8 +22,6 @@ extern cpumask_t cpu_callout_map; extern cpumask_t cpu_initialized; extern cpumask_t cpu_callin_map; -extern void zap_low_mappings(void); - extern int __cpuinit get_local_pda(int cpu); extern int smp_num_siblings; diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h index 0e7bbb54911..aed0b700b83 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h @@ -175,4 +175,6 @@ static inline void flush_tlb_kernel_range(unsigned long start, flush_tlb_all(); } +extern void zap_low_mappings(void); + #endif /* _ASM_X86_TLBFLUSH_H */ diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index f99a6c6c432..a9dd0b7ad61 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c @@ -49,7 +49,6 @@ #include #include #include -#include unsigned int __VMALLOC_RESERVE = 128 << 20; -- cgit From 6e5385d44b2df05e50a8d07ba0e14d3e32685237 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Wed, 7 Jan 2009 18:11:35 +0530 Subject: x86: smp.h move prefill_possible_map declartion to cpu.h Impact: cleanup, moving NON-SMP stuff from smp.h Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/include/asm/cpu.h | 10 ++++++++++ arch/x86/include/asm/smp.h | 6 ------ arch/x86/kernel/setup.c | 2 +- arch/x86/kernel/smpboot.c | 1 - 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h index bae482df603..29aa6d0752b 100644 --- a/arch/x86/include/asm/cpu.h +++ b/arch/x86/include/asm/cpu.h @@ -7,6 +7,16 @@ #include #include +#ifdef CONFIG_SMP + +extern void prefill_possible_map(void); + +#else /* CONFIG_SMP */ + +static inline void prefill_possible_map(void) {} + +#endif /* CONFIG_SMP */ + struct x86_cpu { struct cpu cpu; }; diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index 64c9e848f13..62bd3f68269 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -138,8 +138,6 @@ void play_dead_common(void); void native_send_call_func_ipi(const struct cpumask *mask); void native_send_call_func_single_ipi(int cpu); -extern void prefill_possible_map(void); - void smp_store_cpu_info(int id); #define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu) @@ -148,10 +146,6 @@ static inline int num_booting_cpus(void) { return cpus_weight(cpu_callout_map); } -#else -static inline void prefill_possible_map(void) -{ -} #endif /* CONFIG_SMP */ extern unsigned disabled_cpus __cpuinitdata; diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index ae0d8042cf6..f41c4486c27 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -89,7 +89,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 07576bee03e..f8c885bed18 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -53,7 +53,6 @@ #include #include #include -#include #include #include #include -- cgit From 1433fa7d8da608f59df1f6f381da00958bf5a0b7 Mon Sep 17 00:00:00 2001 From: Jason Jin Date: Thu, 4 Dec 2008 19:14:28 +0800 Subject: powerpc: Fix the ide suspend function in uli1575 The general pci resume code can only restore part of the configuration registers. We need to reconfigure those registers in the FIXUP_RESUME. Signed-off-by: Jason Jin Signed-off-by: Kumar Gala --- arch/powerpc/platforms/fsl_uli1575.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/platforms/fsl_uli1575.c b/arch/powerpc/platforms/fsl_uli1575.c index 8c619963bec..1db6b9e037f 100644 --- a/arch/powerpc/platforms/fsl_uli1575.c +++ b/arch/powerpc/platforms/fsl_uli1575.c @@ -249,6 +249,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, 0x5249, quirk_final_uli5249); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, 0x1575, quirk_final_uli1575); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229); static void __devinit hpcd_quirk_uli1575(struct pci_dev *dev) { -- cgit From be122d6d8b836fec329d740e75bfbdffa96ff6ff Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 6 Jan 2009 10:23:37 -0600 Subject: powerpc/85xx: Fix PCIe error interrupts The PCIe interrupts for 8544ds and 8572ds were incorrect. The 8572 case was found by Liu Yu. Signed-off-by: Kumar Gala --- arch/powerpc/boot/dts/mpc8544ds.dts | 4 ++-- arch/powerpc/boot/dts/mpc8572ds.dts | 4 ++-- arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts | 2 +- arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/boot/dts/mpc8544ds.dts b/arch/powerpc/boot/dts/mpc8544ds.dts index b9da4210506..0668d104877 100644 --- a/arch/powerpc/boot/dts/mpc8544ds.dts +++ b/arch/powerpc/boot/dts/mpc8544ds.dts @@ -313,7 +313,7 @@ 0x1000000 0x0 0x0 0xe1010000 0x0 0x10000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; - interrupts = <26 2>; + interrupts = <25 2>; interrupt-map-mask = <0xf800 0x0 0x0 0x7>; interrupt-map = < /* IDSEL 0x0 */ @@ -350,7 +350,7 @@ 0x1000000 0x0 0x0 0xe1020000 0x0 0x10000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; - interrupts = <25 2>; + interrupts = <26 2>; interrupt-map-mask = <0xf800 0x0 0x0 0x7>; interrupt-map = < /* IDSEL 0x0 */ diff --git a/arch/powerpc/boot/dts/mpc8572ds.dts b/arch/powerpc/boot/dts/mpc8572ds.dts index 21459e161d0..3dcc001b8ed 100644 --- a/arch/powerpc/boot/dts/mpc8572ds.dts +++ b/arch/powerpc/boot/dts/mpc8572ds.dts @@ -724,7 +724,7 @@ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x00010000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; - interrupts = <26 2>; + interrupts = <25 2>; interrupt-map-mask = <0xf800 0x0 0x0 0x7>; interrupt-map = < /* IDSEL 0x0 */ @@ -761,7 +761,7 @@ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x00010000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; - interrupts = <27 2>; + interrupts = <26 2>; interrupt-map-mask = <0xf800 0x0 0x0 0x7>; interrupt-map = < /* IDSEL 0x0 */ diff --git a/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts b/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts index c114c4ee993..fd462efa9e6 100644 --- a/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts +++ b/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts @@ -457,7 +457,7 @@ 0x1000000 0x0 0x0 0xffc10000 0x0 0x10000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; - interrupts = <26 2>; + interrupts = <25 2>; interrupt-map-mask = <0xf800 0x0 0x0 0x7>; interrupt-map = < /* IDSEL 0x0 */ diff --git a/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts b/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts index 04ecda18d20..e35230f2ac9 100644 --- a/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts +++ b/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts @@ -208,7 +208,7 @@ 0x1000000 0x0 0x0 0xffc20000 0x0 0x10000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; - interrupts = <27 2>; + interrupts = <26 2>; interrupt-map-mask = <0xf800 0x0 0x0 0x7>; interrupt-map = < /* IDSEL 0x0 */ -- cgit From fdd4e8152f5f0d6d500b35515265e425acdfd203 Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Tue, 6 Jan 2009 17:12:23 -0600 Subject: powerpc/qe: add Ethernet UPSMR definitions to QE library Add the UCC_GETH_UPSMR_xxx definitions to qe.h. The ucc_geth driver will eventually use these instead of the UPSMR_ macros it currently defines. Signed-off-by: Timur Tabi Signed-off-by: Kumar Gala --- arch/powerpc/include/asm/qe.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/qe.h b/arch/powerpc/include/asm/qe.h index a0a15311d0d..2701753d993 100644 --- a/arch/powerpc/include/asm/qe.h +++ b/arch/powerpc/include/asm/qe.h @@ -624,7 +624,7 @@ struct ucc_slow_pram { #define UCC_GETH_UCCE_RXF1 0x00000002 #define UCC_GETH_UCCE_RXF0 0x00000001 -/* UPSMR, when used as a UART */ +/* UCC Protocol Specific Mode Register (UPSMR), when used for UART */ #define UCC_UART_UPSMR_FLC 0x8000 #define UCC_UART_UPSMR_SL 0x4000 #define UCC_UART_UPSMR_CL_MASK 0x3000 @@ -652,6 +652,23 @@ struct ucc_slow_pram { #define UCC_UART_UPSMR_TPM_EVEN 0x0002 #define UCC_UART_UPSMR_TPM_HIGH 0x0003 +/* UCC Protocol Specific Mode Register (UPSMR), when used for Ethernet */ +#define UCC_GETH_UPSMR_FTFE 0x80000000 +#define UCC_GETH_UPSMR_PTPE 0x40000000 +#define UCC_GETH_UPSMR_ECM 0x04000000 +#define UCC_GETH_UPSMR_HSE 0x02000000 +#define UCC_GETH_UPSMR_PRO 0x00400000 +#define UCC_GETH_UPSMR_CAP 0x00200000 +#define UCC_GETH_UPSMR_RSH 0x00100000 +#define UCC_GETH_UPSMR_RPM 0x00080000 +#define UCC_GETH_UPSMR_R10M 0x00040000 +#define UCC_GETH_UPSMR_RLPB 0x00020000 +#define UCC_GETH_UPSMR_TBIM 0x00010000 +#define UCC_GETH_UPSMR_RES1 0x00002000 +#define UCC_GETH_UPSMR_RMM 0x00001000 +#define UCC_GETH_UPSMR_CAM 0x00000400 +#define UCC_GETH_UPSMR_BRO 0x00000200 + /* UCC Transmit On Demand Register (UTODR) */ #define UCC_SLOW_TOD 0x8000 #define UCC_FAST_TOD 0x8000 -- cgit From 490dea45d00f01847ebebd007685d564aaf2cd98 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 24 Nov 2008 17:06:57 +0100 Subject: itimers: remove the per-cpu-ish-ness Either we bounce once cacheline per cpu per tick, yielding n^2 bounces or we just bounce a single.. Also, using per-cpu allocations for the thread-groups complicates the per-cpu allocator in that its currently aimed to be a fixed sized allocator and the only possible extention to that would be vmap based, which is seriously constrained on 32 bit archs. So making the per-cpu memory requirement depend on the number of processes is an issue. Lastly, it didn't deal with cpu-hotplug, although admittedly that might be fixable. Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- include/linux/init_task.h | 6 ++++ include/linux/sched.h | 29 ++++++++++++-------- kernel/fork.c | 15 +++++----- kernel/posix-cpu-timers.c | 70 ----------------------------------------------- kernel/sched_stats.h | 33 ++++++++++------------ 5 files changed, 46 insertions(+), 107 deletions(-) diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 2f3c2d4ef73..ea0ea1a4c36 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -48,6 +48,12 @@ extern struct fs_struct init_fs; .posix_timers = LIST_HEAD_INIT(sig.posix_timers), \ .cpu_timers = INIT_CPU_TIMERS(sig.cpu_timers), \ .rlim = INIT_RLIMITS, \ + .cputime = { .totals = { \ + .utime = cputime_zero, \ + .stime = cputime_zero, \ + .sum_exec_runtime = 0, \ + .lock = __SPIN_LOCK_UNLOCKED(sig.cputime.totals.lock), \ + }, }, \ } extern struct nsproxy init_nsproxy; diff --git a/include/linux/sched.h b/include/linux/sched.h index 4cae9b81a1f..c20943eabb4 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -450,6 +450,7 @@ struct task_cputime { cputime_t utime; cputime_t stime; unsigned long long sum_exec_runtime; + spinlock_t lock; }; /* Alternate field names when used to cache expirations. */ #define prof_exp stime @@ -465,7 +466,7 @@ struct task_cputime { * used for thread group CPU clock calculations. */ struct thread_group_cputime { - struct task_cputime *totals; + struct task_cputime totals; }; /* @@ -2180,24 +2181,30 @@ static inline int spin_needbreak(spinlock_t *lock) * Thread group CPU time accounting. */ -extern int thread_group_cputime_alloc(struct task_struct *); -extern void thread_group_cputime(struct task_struct *, struct task_cputime *); - -static inline void thread_group_cputime_init(struct signal_struct *sig) +static inline +void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times) { - sig->cputime.totals = NULL; + struct task_cputime *totals = &tsk->signal->cputime.totals; + unsigned long flags; + + spin_lock_irqsave(&totals->lock, flags); + *times = *totals; + spin_unlock_irqrestore(&totals->lock, flags); } -static inline int thread_group_cputime_clone_thread(struct task_struct *curr) +static inline void thread_group_cputime_init(struct signal_struct *sig) { - if (curr->signal->cputime.totals) - return 0; - return thread_group_cputime_alloc(curr); + sig->cputime.totals = (struct task_cputime){ + .utime = cputime_zero, + .stime = cputime_zero, + .sum_exec_runtime = 0, + }; + + spin_lock_init(&sig->cputime.totals.lock); } static inline void thread_group_cputime_free(struct signal_struct *sig) { - free_percpu(sig->cputime.totals); } /* diff --git a/kernel/fork.c b/kernel/fork.c index 7b8f2a78be3..7087d8c0e5e 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -820,14 +820,15 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) int ret; if (clone_flags & CLONE_THREAD) { - ret = thread_group_cputime_clone_thread(current); - if (likely(!ret)) { - atomic_inc(¤t->signal->count); - atomic_inc(¤t->signal->live); - } - return ret; + atomic_inc(¤t->signal->count); + atomic_inc(¤t->signal->live); + return 0; } sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL); + + if (sig) + posix_cpu_timers_init_group(sig); + tsk->signal = sig; if (!sig) return -ENOMEM; @@ -864,8 +865,6 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim); task_unlock(current->group_leader); - posix_cpu_timers_init_group(sig); - acct_init_pacct(&sig->pacct); tty_audit_fork(sig); diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index 157de3a4783..fa07da94d7b 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c @@ -9,76 +9,6 @@ #include #include -/* - * Allocate the thread_group_cputime structure appropriately and fill in the - * current values of the fields. Called from copy_signal() via - * thread_group_cputime_clone_thread() when adding a second or subsequent - * thread to a thread group. Assumes interrupts are enabled when called. - */ -int thread_group_cputime_alloc(struct task_struct *tsk) -{ - struct signal_struct *sig = tsk->signal; - struct task_cputime *cputime; - - /* - * If we have multiple threads and we don't already have a - * per-CPU task_cputime struct (checked in the caller), allocate - * one and fill it in with the times accumulated so far. We may - * race with another thread so recheck after we pick up the sighand - * lock. - */ - cputime = alloc_percpu(struct task_cputime); - if (cputime == NULL) - return -ENOMEM; - spin_lock_irq(&tsk->sighand->siglock); - if (sig->cputime.totals) { - spin_unlock_irq(&tsk->sighand->siglock); - free_percpu(cputime); - return 0; - } - sig->cputime.totals = cputime; - cputime = per_cpu_ptr(sig->cputime.totals, smp_processor_id()); - cputime->utime = tsk->utime; - cputime->stime = tsk->stime; - cputime->sum_exec_runtime = tsk->se.sum_exec_runtime; - spin_unlock_irq(&tsk->sighand->siglock); - return 0; -} - -/** - * thread_group_cputime - Sum the thread group time fields across all CPUs. - * - * @tsk: The task we use to identify the thread group. - * @times: task_cputime structure in which we return the summed fields. - * - * Walk the list of CPUs to sum the per-CPU time fields in the thread group - * time structure. - */ -void thread_group_cputime( - struct task_struct *tsk, - struct task_cputime *times) -{ - struct task_cputime *totals, *tot; - int i; - - totals = tsk->signal->cputime.totals; - if (!totals) { - times->utime = tsk->utime; - times->stime = tsk->stime; - times->sum_exec_runtime = tsk->se.sum_exec_runtime; - return; - } - - times->stime = times->utime = cputime_zero; - times->sum_exec_runtime = 0; - for_each_possible_cpu(i) { - tot = per_cpu_ptr(totals, i); - times->utime = cputime_add(times->utime, tot->utime); - times->stime = cputime_add(times->stime, tot->stime); - times->sum_exec_runtime += tot->sum_exec_runtime; - } -} - /* * Called after updating RLIMIT_CPU to set timer expiration if necessary. */ diff --git a/kernel/sched_stats.h b/kernel/sched_stats.h index f2773b5d122..8ab0cef8eca 100644 --- a/kernel/sched_stats.h +++ b/kernel/sched_stats.h @@ -296,6 +296,7 @@ sched_info_switch(struct task_struct *prev, struct task_struct *next) static inline void account_group_user_time(struct task_struct *tsk, cputime_t cputime) { + struct task_cputime *times; struct signal_struct *sig; /* tsk == current, ensure it is safe to use ->signal */ @@ -303,13 +304,11 @@ static inline void account_group_user_time(struct task_struct *tsk, return; sig = tsk->signal; - if (sig->cputime.totals) { - struct task_cputime *times; + times = &sig->cputime.totals; - times = per_cpu_ptr(sig->cputime.totals, get_cpu()); - times->utime = cputime_add(times->utime, cputime); - put_cpu_no_resched(); - } + spin_lock(×->lock); + times->utime = cputime_add(times->utime, cputime); + spin_unlock(×->lock); } /** @@ -325,6 +324,7 @@ static inline void account_group_user_time(struct task_struct *tsk, static inline void account_group_system_time(struct task_struct *tsk, cputime_t cputime) { + struct task_cputime *times; struct signal_struct *sig; /* tsk == current, ensure it is safe to use ->signal */ @@ -332,13 +332,11 @@ static inline void account_group_system_time(struct task_struct *tsk, return; sig = tsk->signal; - if (sig->cputime.totals) { - struct task_cputime *times; + times = &sig->cputime.totals; - times = per_cpu_ptr(sig->cputime.totals, get_cpu()); - times->stime = cputime_add(times->stime, cputime); - put_cpu_no_resched(); - } + spin_lock(×->lock); + times->stime = cputime_add(times->stime, cputime); + spin_unlock(×->lock); } /** @@ -354,6 +352,7 @@ static inline void account_group_system_time(struct task_struct *tsk, static inline void account_group_exec_runtime(struct task_struct *tsk, unsigned long long ns) { + struct task_cputime *times; struct signal_struct *sig; sig = tsk->signal; @@ -362,11 +361,9 @@ static inline void account_group_exec_runtime(struct task_struct *tsk, if (unlikely(!sig)) return; - if (sig->cputime.totals) { - struct task_cputime *times; + times = &sig->cputime.totals; - times = per_cpu_ptr(sig->cputime.totals, get_cpu()); - times->sum_exec_runtime += ns; - put_cpu_no_resched(); - } + spin_lock(×->lock); + times->sum_exec_runtime += ns; + spin_unlock(×->lock); } -- cgit From f472cdba849cc3d838f3788469316e8572463a8c Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Wed, 7 Jan 2009 21:34:25 +0530 Subject: x86: smp.h move stack_processor_id declartion to cpu.h Impact: cleanup Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/include/asm/cpu.h | 2 ++ arch/x86/include/asm/smp.h | 1 - arch/x86/kernel/cpu/common.c | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h index 29aa6d0752b..f958e7e49c0 100644 --- a/arch/x86/include/asm/cpu.h +++ b/arch/x86/include/asm/cpu.h @@ -15,6 +15,8 @@ extern void prefill_possible_map(void); static inline void prefill_possible_map(void) {} +#define stack_smp_processor_id() 0 + #endif /* CONFIG_SMP */ struct x86_cpu { diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index 62bd3f68269..ed4af9a89cf 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -173,7 +173,6 @@ extern int safe_smp_processor_id(void); #else /* !CONFIG_X86_32_SMP && !CONFIG_X86_64_SMP */ #define cpu_physical_id(cpu) boot_cpu_physical_apicid #define safe_smp_processor_id() 0 -#define stack_smp_processor_id() 0 #endif #ifdef CONFIG_X86_LOCAL_APIC diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 3f95a40f718..f7619a2eaff 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -21,6 +21,7 @@ #include #include #include +#include #ifdef CONFIG_X86_LOCAL_APIC #include #include -- cgit From 96b89dc6598a50e3aac8e2c6d826ae3795b7d030 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Wed, 7 Jan 2009 21:35:48 +0530 Subject: x86: smp.h move safe_smp_processor_id declartion to cpu.h Impact: cleanup Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/include/asm/cpu.h | 1 + arch/x86/include/asm/smp.h | 1 - arch/x86/kernel/crash.c | 2 +- arch/x86/kernel/reboot.c | 1 + arch/x86/mach-voyager/setup.c | 1 + 5 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h index f958e7e49c0..4c16888ffa3 100644 --- a/arch/x86/include/asm/cpu.h +++ b/arch/x86/include/asm/cpu.h @@ -15,6 +15,7 @@ extern void prefill_possible_map(void); static inline void prefill_possible_map(void) {} +#define safe_smp_processor_id() 0 #define stack_smp_processor_id() 0 #endif /* CONFIG_SMP */ diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index ed4af9a89cf..c92b93594ab 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -172,7 +172,6 @@ extern int safe_smp_processor_id(void); #else /* !CONFIG_X86_32_SMP && !CONFIG_X86_64_SMP */ #define cpu_physical_id(cpu) boot_cpu_physical_apicid -#define safe_smp_processor_id() 0 #endif #ifdef CONFIG_X86_LOCAL_APIC diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index c689d19e35a..11b93cabdf7 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 2b46eb41643..f8536fee5c1 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -14,6 +14,7 @@ #include #include #include +#include #ifdef CONFIG_X86_32 # include diff --git a/arch/x86/mach-voyager/setup.c b/arch/x86/mach-voyager/setup.c index a580b9562e7..0ade62555ff 100644 --- a/arch/x86/mach-voyager/setup.c +++ b/arch/x86/mach-voyager/setup.c @@ -9,6 +9,7 @@ #include #include #include +#include void __init pre_intr_init_hook(void) { -- cgit From af8968abf09fe5984bdd206e54e0eeb1dc1fa29c Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Wed, 7 Jan 2009 21:37:33 +0530 Subject: x86: smp.h move cpu_physical_id declartion to cpu.h Impact: cleanup Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/include/asm/cpu.h | 1 + arch/x86/include/asm/smp.h | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h index 4c16888ffa3..89edafb9339 100644 --- a/arch/x86/include/asm/cpu.h +++ b/arch/x86/include/asm/cpu.h @@ -15,6 +15,7 @@ extern void prefill_possible_map(void); static inline void prefill_possible_map(void) {} +#define cpu_physical_id(cpu) boot_cpu_physical_apicid #define safe_smp_processor_id() 0 #define stack_smp_processor_id() 0 diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index c92b93594ab..c975b6f83c6 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -170,8 +170,6 @@ extern int safe_smp_processor_id(void); }) #define safe_smp_processor_id() smp_processor_id() -#else /* !CONFIG_X86_32_SMP && !CONFIG_X86_64_SMP */ -#define cpu_physical_id(cpu) boot_cpu_physical_apicid #endif #ifdef CONFIG_X86_LOCAL_APIC -- cgit From 6d652ea1d056390a0c33db92b44ed219284b71af Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Wed, 7 Jan 2009 21:38:59 +0530 Subject: x86: smp.h move boot_cpu_id declartion to cpu.h Impact: cleanup Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/include/asm/cpu.h | 7 +++++++ arch/x86/include/asm/smp.h | 6 ------ arch/x86/kernel/io_apic.c | 1 + drivers/pci/intr_remapping.c | 1 + 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h index 89edafb9339..f03b23e3286 100644 --- a/arch/x86/include/asm/cpu.h +++ b/arch/x86/include/asm/cpu.h @@ -31,4 +31,11 @@ extern void arch_unregister_cpu(int); #endif DECLARE_PER_CPU(int, cpu_state); + +#ifdef CONFIG_X86_HAS_BOOT_CPU_ID +extern unsigned char boot_cpu_id; +#else +#define boot_cpu_id 0 +#endif + #endif /* _ASM_X86_CPU_H */ diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index c975b6f83c6..74ad9ef6ae0 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -212,11 +212,5 @@ static inline int hard_smp_processor_id(void) #endif /* CONFIG_X86_LOCAL_APIC */ -#ifdef CONFIG_X86_HAS_BOOT_CPU_ID -extern unsigned char boot_cpu_id; -#else -#define boot_cpu_id 0 -#endif - #endif /* __ASSEMBLY__ */ #endif /* _ASM_X86_SMP_H */ diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c index 1c4a1302536..109c91db202 100644 --- a/arch/x86/kernel/io_apic.c +++ b/arch/x86/kernel/io_apic.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c index f78371b2252..5a57753ea9f 100644 --- a/drivers/pci/intr_remapping.c +++ b/drivers/pci/intr_remapping.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "intr_remapping.h" -- cgit From a097a78c1e6e4030fcef3bcab6351b6001662335 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Tue, 6 Jan 2009 22:37:53 -0600 Subject: powerpc/fsl-pci: Better ATMU setup for 85xx/86xx The code that sets up the outbound ATMU windows, which is used to map CPU physical addresses into PCI bus addresses where BARs will be mapped, didn't work so well. For one, it leaked the ioremap() of the ATMU registers. Another small bug was the high 20 bits of the PCI bus address were left as zero. It's legal for prefetchable memory regions to be above 32 bits, so the high 20 bits might not be zero. Mainly, it couldn't handle ranges that were not a power of two in size or were not naturally aligned. The ATMU windows have these requirements (size & alignment), but the code didn't bother to check if the ranges it was programming met them. If they didn't, the windows would silently be programmed incorrectly. This new code can handle ranges which are not power of two sized nor naturally aligned. It simply splits the ranges into multiple valid ATMU windows. As there are only four windows, pooly aligned or sized ranges (which didn't even work before) may run out of windows. In this case an error is printed and an effort is made to disable the unmapped resources. An improvement that could be made would be to make use of the default outbound window. Iff hose->pci_mem_offset is zero, then it's possible that some or all of the ranges might not need an outbound window and could just use the default window. The default ATMU window can support a pci_mem_offset less than zero too, but pci_mem_offset is unsigned. One could say the abilities allowed a powerpc pci_controller is neither subset nor a superset of the abilities of a Freescale PCIe controller. Thankfully, the most useful bits are in the intersection of the two abilities. Signed-off-by: Trent Piepho Signed-off-by: Kumar Gala --- arch/powerpc/sysdev/fsl_pci.c | 104 ++++++++++++++++++++++++++++-------------- 1 file changed, 71 insertions(+), 33 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index f611d0369cc..44bc903ead7 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -28,63 +28,101 @@ #include #if defined(CONFIG_PPC_85xx) || defined(CONFIG_PPC_86xx) +static int __init setup_one_atmu(struct ccsr_pci __iomem *pci, + unsigned int index, const struct resource *res, + resource_size_t offset) +{ + resource_size_t pci_addr = res->start - offset; + resource_size_t phys_addr = res->start; + resource_size_t size = res->end - res->start + 1; + u32 flags = 0x80044000; /* enable & mem R/W */ + unsigned int i; + + pr_debug("PCI MEM resource start 0x%016llx, size 0x%016llx.\n", + (u64)res->start, (u64)size); + + for (i = 0; size > 0; i++) { + unsigned int bits = min(__ilog2(size), + __ffs(pci_addr | phys_addr)); + + if (index + i >= 5) + return -1; + + out_be32(&pci->pow[index + i].potar, pci_addr >> 12); + out_be32(&pci->pow[index + i].potear, (u64)pci_addr >> 44); + out_be32(&pci->pow[index + i].powbar, phys_addr >> 12); + out_be32(&pci->pow[index + i].powar, flags | (bits - 1)); + + pci_addr += (resource_size_t)1U << bits; + phys_addr += (resource_size_t)1U << bits; + size -= (resource_size_t)1U << bits; + } + + return i; +} + /* atmu setup for fsl pci/pcie controller */ static void __init setup_pci_atmu(struct pci_controller *hose, struct resource *rsrc) { struct ccsr_pci __iomem *pci; - int i; + int i, j, n; pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n", (u64)rsrc->start, (u64)rsrc->end - (u64)rsrc->start + 1); pci = ioremap(rsrc->start, rsrc->end - rsrc->start + 1); + if (!pci) { + dev_err(hose->parent, "Unable to map ATMU registers\n"); + return; + } - /* Disable all windows (except powar0 since its ignored) */ + /* Disable all windows (except powar0 since it's ignored) */ for(i = 1; i < 5; i++) out_be32(&pci->pow[i].powar, 0); for(i = 0; i < 3; i++) out_be32(&pci->piw[i].piwar, 0); /* Setup outbound MEM window */ - for(i = 0; i < 3; i++) - if (hose->mem_resources[i].flags & IORESOURCE_MEM){ - resource_size_t pci_addr_start = - hose->mem_resources[i].start - - hose->pci_mem_offset; - pr_debug("PCI MEM resource start 0x%016llx, size 0x%016llx.\n", - (u64)hose->mem_resources[i].start, - (u64)hose->mem_resources[i].end - - (u64)hose->mem_resources[i].start + 1); - out_be32(&pci->pow[i+1].potar, (pci_addr_start >> 12)); - out_be32(&pci->pow[i+1].potear, 0); - out_be32(&pci->pow[i+1].powbar, - (hose->mem_resources[i].start >> 12)); - /* Enable, Mem R/W */ - out_be32(&pci->pow[i+1].powar, 0x80044000 - | (__ilog2(hose->mem_resources[i].end - - hose->mem_resources[i].start + 1) - 1)); - } + for(i = 0, j = 1; i < 3; i++) { + if (!(hose->mem_resources[i].flags & IORESOURCE_MEM)) + continue; + + n = setup_one_atmu(pci, j, &hose->mem_resources[i], + hose->pci_mem_offset); + + if (n < 0 || j >= 5) { + pr_err("Ran out of outbound PCI ATMUs for resource %d!\n", i); + hose->mem_resources[i].flags |= IORESOURCE_DISABLED; + } else + j += n; + } /* Setup outbound IO window */ - if (hose->io_resource.flags & IORESOURCE_IO){ - pr_debug("PCI IO resource start 0x%016llx, size 0x%016llx, " - "phy base 0x%016llx.\n", - (u64)hose->io_resource.start, - (u64)hose->io_resource.end - (u64)hose->io_resource.start + 1, - (u64)hose->io_base_phys); - out_be32(&pci->pow[i+1].potar, (hose->io_resource.start >> 12)); - out_be32(&pci->pow[i+1].potear, 0); - out_be32(&pci->pow[i+1].powbar, (hose->io_base_phys >> 12)); - /* Enable, IO R/W */ - out_be32(&pci->pow[i+1].powar, 0x80088000 - | (__ilog2(hose->io_resource.end - - hose->io_resource.start + 1) - 1)); + if (hose->io_resource.flags & IORESOURCE_IO) { + if (j >= 5) { + pr_err("Ran out of outbound PCI ATMUs for IO resource\n"); + } else { + pr_debug("PCI IO resource start 0x%016llx, size 0x%016llx, " + "phy base 0x%016llx.\n", + (u64)hose->io_resource.start, + (u64)hose->io_resource.end - (u64)hose->io_resource.start + 1, + (u64)hose->io_base_phys); + out_be32(&pci->pow[j].potar, (hose->io_resource.start >> 12)); + out_be32(&pci->pow[j].potear, 0); + out_be32(&pci->pow[j].powbar, (hose->io_base_phys >> 12)); + /* Enable, IO R/W */ + out_be32(&pci->pow[j].powar, 0x80088000 + | (__ilog2(hose->io_resource.end + - hose->io_resource.start + 1) - 1)); + } } /* Setup 2G inbound Memory Window @ 1 */ out_be32(&pci->piw[2].pitar, 0x00000000); out_be32(&pci->piw[2].piwbar,0x00000000); out_be32(&pci->piw[2].piwar, PIWAR_2G); + + iounmap(pci); } static void __init setup_pci_cmd(struct pci_controller *hose) -- cgit From 565f37642c78754a85efe6c20a4a15e18ed21f07 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Wed, 17 Dec 2008 11:43:26 -0800 Subject: powerpc/fsl-pci: Set relaxed ordering on prefetchable ranges Provides a small speedup when accessing pefetchable ranges. To indicate that a memory range is prefetchable, mark it in the dts file with 42000000 instead of 02000000. A powepc pci_controller is allowed three memory ranges, any of which may be prefetchable. However, the PCI-PCI bridge configuration space only has one field for "non-prefetchable memory behind bridge", which has a 32 bit address, and one field for "prefetchable memory behind bridge", which may have a 64 bit address. These are PCI bus addresses, not CPU physical addresses. So really you're only allowed one memory range of each type. And if you want the range at a PCI address above 32 bits you must make it prefetchable. Signed-off-by: Trent Piepho Signed-off-by: Kumar Gala --- arch/powerpc/sysdev/fsl_pci.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 44bc903ead7..9817f63723d 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -41,6 +41,9 @@ static int __init setup_one_atmu(struct ccsr_pci __iomem *pci, pr_debug("PCI MEM resource start 0x%016llx, size 0x%016llx.\n", (u64)res->start, (u64)size); + if (res->flags & IORESOURCE_PREFETCH) + flags |= 0x10000000; /* enable relaxed ordering */ + for (i = 0; size > 0; i++) { unsigned int bits = min(__ilog2(size), __ffs(pci_addr | phys_addr)); -- cgit From 19f5465e823858a2f0b0e9a92e52816ba3ee70bb Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Mon, 8 Dec 2008 19:34:55 -0800 Subject: powerpc/fsl-booke: Don't hard-code size of struct tlbcam Some assembly code in head_fsl_booke.S hard-coded the size of struct tlbcam to 20 when it indexed the TLBCAM table. Anyone changing the size of struct tlbcam would not know to expect that. The kernel already has a system to get the size of C structures into assembly language files, asm-offsets, so let's use it. The definition of the struct gets moved to a header, so that asm-offsets.c can include it. Signed-off-by: Trent Piepho Signed-off-by: Kumar Gala --- arch/powerpc/kernel/asm-offsets.c | 7 +++++++ arch/powerpc/kernel/head_fsl_booke.S | 2 +- arch/powerpc/mm/fsl_booke_mmu.c | 8 +------- arch/powerpc/mm/mmu_decl.h | 9 +++++++++ 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 661d07d2146..06958da94f1 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -56,6 +56,10 @@ #include "head_booke.h" #endif +#if defined(CONFIG_FSL_BOOKE) +#include "../mm/mmu_decl.h" +#endif + int main(void) { DEFINE(THREAD, offsetof(struct task_struct, thread)); @@ -384,6 +388,9 @@ int main(void) DEFINE(PGD_T_LOG2, PGD_T_LOG2); DEFINE(PTE_T_LOG2, PTE_T_LOG2); #endif +#ifdef CONFIG_FSL_BOOKE + DEFINE(TLBCAM_SIZE, sizeof(struct tlbcam)); +#endif return 0; } diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 11b549acc03..805f28d30e4 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -909,7 +909,7 @@ KernelSPE: _GLOBAL(loadcam_entry) lis r4,TLBCAM@ha addi r4,r4,TLBCAM@l - mulli r5,r3,20 + mulli r5,r3,TLBCAM_SIZE add r3,r5,r4 lwz r4,0(r3) mtspr SPRN_MAS0,r4 diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index 23cee39534f..c9ee59af100 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c @@ -61,13 +61,7 @@ static unsigned long __cam0, __cam1, __cam2; #define NUM_TLBCAMS (16) -struct tlbcam { - u32 MAS0; - u32 MAS1; - u32 MAS2; - u32 MAS3; - u32 MAS7; -} TLBCAM[NUM_TLBCAMS]; +struct tlbcam TLBCAM[NUM_TLBCAMS]; struct tlbcamrange { unsigned long start; diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index 4314b39b6fa..6f6ee62c2a0 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h @@ -75,6 +75,15 @@ extern void _tlbia(void); #endif /* CONFIG_PPC_MMU_NOHASH */ #ifdef CONFIG_PPC32 + +struct tlbcam { + u32 MAS0; + u32 MAS1; + u32 MAS2; + u32 MAS3; + u32 MAS7; +}; + extern void mapin_ram(void); extern int map_page(unsigned long va, phys_addr_t pa, int flags); extern void setbat(int index, unsigned long virt, phys_addr_t phys, -- cgit From 6fd8be4bf72879b3039654388e985cabf8449af5 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Mon, 8 Dec 2008 19:34:56 -0800 Subject: powerpc/fsl-booke: Remove num_tlbcam_entries This is a global variable defined in fsl_booke_mmu.c with a value that gets initialized in assembly code in head_fsl_booke.S. It's never used. If some code ever does want to know the number of entries in TLB1, then "numcams = mfspr(SPRN_TLB1CFG) & 0xfff", is a whole lot simpler than a global initialized during kernel boot from assembly. Signed-off-by: Trent Piepho Signed-off-by: Kumar Gala --- arch/powerpc/kernel/head_fsl_booke.S | 4 ---- arch/powerpc/mm/fsl_booke_mmu.c | 1 - arch/powerpc/mm/mmu_decl.h | 2 -- 3 files changed, 7 deletions(-) diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 805f28d30e4..2f32720a44a 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -389,10 +389,6 @@ skpinv: addi r6,r6,1 /* Increment */ #endif #endif - mfspr r3,SPRN_TLB1CFG - andi. r3,r3,0xfff - lis r4,num_tlbcam_entries@ha - stw r3,num_tlbcam_entries@l(r4) /* * Decide what sort of machine this is and initialize the MMU. */ diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index c9ee59af100..1971e4ee3d6 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c @@ -56,7 +56,6 @@ extern void loadcam_entry(unsigned int index); unsigned int tlbcam_index; -unsigned int num_tlbcam_entries; static unsigned long __cam0, __cam1, __cam2; #define NUM_TLBCAMS (16) diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index 6f6ee62c2a0..d0bb69dc627 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h @@ -99,8 +99,6 @@ extern unsigned int rtas_data, rtas_size; struct hash_pte; extern struct hash_pte *Hash, *Hash_end; extern unsigned long Hash_size, Hash_mask; - -extern unsigned int num_tlbcam_entries; #endif extern unsigned long ioremap_bot; -- cgit From 41401db698cbb5d1869776bf336881db267e7d19 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Thu, 8 Jan 2009 15:42:46 +0530 Subject: x86: rename intel_mp_floating to mpf_intel Impact: cleanup, solve 80 columns wrap problems intel_mp_floating should be renamed to mpf_intel. The reason: the 'f' in MPF already means 'floating' which means MP Floating pointer structure - no need to repeat that in the type name. Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/include/asm/mpspec_def.h | 3 ++- arch/x86/kernel/mpparse.c | 12 ++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/mpspec_def.h b/arch/x86/include/asm/mpspec_def.h index 59568bc4767..187dc920193 100644 --- a/arch/x86/include/asm/mpspec_def.h +++ b/arch/x86/include/asm/mpspec_def.h @@ -24,7 +24,8 @@ # endif #endif -struct intel_mp_floating { +/* Intel MP Floating Pointer Structure */ +struct mpf_intel { char mpf_signature[4]; /* "_MP_" */ unsigned int mpf_physptr; /* Configuration table address */ unsigned char mpf_length; /* Our length (paragraphs) */ diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index c0601c2848a..6cea941c4db 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c @@ -569,14 +569,14 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type) } } -static struct intel_mp_floating *mpf_found; +static struct mpf_intel *mpf_found; /* * Scan the memory blocks for an SMP configuration block. */ static void __init __get_smp_config(unsigned int early) { - struct intel_mp_floating *mpf = mpf_found; + struct mpf_intel *mpf = mpf_found; if (!mpf) return; @@ -687,14 +687,14 @@ static int __init smp_scan_config(unsigned long base, unsigned long length, unsigned reserve) { unsigned int *bp = phys_to_virt(base); - struct intel_mp_floating *mpf; + struct mpf_intel *mpf; apic_printk(APIC_VERBOSE, "Scan SMP from %p for %ld bytes.\n", bp, length); BUILD_BUG_ON(sizeof(*mpf) != 16); while (length > 0) { - mpf = (struct intel_mp_floating *)bp; + mpf = (struct mpf_intel *)bp; if ((*bp == SMP_MAGIC_IDENT) && (mpf->mpf_length == 1) && !mpf_checksum((unsigned char *)bp, 16) && @@ -1000,7 +1000,7 @@ static int __init update_mp_table(void) { char str[16]; char oem[10]; - struct intel_mp_floating *mpf; + struct mpf_intel *mpf; struct mpc_table *mpc, *mpc_new; if (!enable_update_mptable) @@ -1052,7 +1052,7 @@ static int __init update_mp_table(void) mpc = mpc_new; /* check if we can modify that */ if (mpc_new_phys - mpf->mpf_physptr) { - struct intel_mp_floating *mpf_new; + struct mpf_intel *mpf_new; /* steal 16 bytes from [0, 1k) */ printk(KERN_INFO "mpf new: %x\n", 0x400 - 16); mpf_new = phys_to_virt(0x400 - 16); -- cgit From 1eb1b3b65dc3e3ffcc6a60e115c085c0c11c1077 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Thu, 8 Jan 2009 15:43:26 +0530 Subject: x86: rename all fields of mpf_intel mpf_X to X Impact: cleanup, solve 80 columns wrap problems It would be cleaner to rename all the mpf->mpf_X fields to mpf->X - that alone would give 4 characters per usage site. (we already know that it's an 'mpf' entity - no need to duplicate that in the field too) Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/include/asm/mpspec_def.h | 20 ++++++++-------- arch/x86/kernel/mpparse.c | 50 +++++++++++++++++++-------------------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/arch/x86/include/asm/mpspec_def.h b/arch/x86/include/asm/mpspec_def.h index 187dc920193..4a7f96d7c18 100644 --- a/arch/x86/include/asm/mpspec_def.h +++ b/arch/x86/include/asm/mpspec_def.h @@ -26,16 +26,16 @@ /* Intel MP Floating Pointer Structure */ struct mpf_intel { - char mpf_signature[4]; /* "_MP_" */ - unsigned int mpf_physptr; /* Configuration table address */ - unsigned char mpf_length; /* Our length (paragraphs) */ - unsigned char mpf_specification;/* Specification version */ - unsigned char mpf_checksum; /* Checksum (makes sum 0) */ - unsigned char mpf_feature1; /* Standard or configuration ? */ - unsigned char mpf_feature2; /* Bit7 set for IMCR|PIC */ - unsigned char mpf_feature3; /* Unused (0) */ - unsigned char mpf_feature4; /* Unused (0) */ - unsigned char mpf_feature5; /* Unused (0) */ + char signature[4]; /* "_MP_" */ + unsigned int physptr; /* Configuration table address */ + unsigned char length; /* Our length (paragraphs) */ + unsigned char specification; /* Specification version */ + unsigned char checksum; /* Checksum (makes sum 0) */ + unsigned char feature1; /* Standard or configuration ? */ + unsigned char feature2; /* Bit7 set for IMCR|PIC */ + unsigned char feature3; /* Unused (0) */ + unsigned char feature4; /* Unused (0) */ + unsigned char feature5; /* Unused (0) */ }; #define MPC_SIGNATURE "PCMP" diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 6cea941c4db..8385d4e7e15 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c @@ -597,9 +597,9 @@ static void __init __get_smp_config(unsigned int early) } printk(KERN_INFO "Intel MultiProcessor Specification v1.%d\n", - mpf->mpf_specification); + mpf->specification); #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_32) - if (mpf->mpf_feature2 & (1 << 7)) { + if (mpf->feature2 & (1 << 7)) { printk(KERN_INFO " IMCR and PIC compatibility mode.\n"); pic_mode = 1; } else { @@ -610,7 +610,7 @@ static void __init __get_smp_config(unsigned int early) /* * Now see if we need to read further. */ - if (mpf->mpf_feature1 != 0) { + if (mpf->feature1 != 0) { if (early) { /* * local APIC has default address @@ -620,16 +620,16 @@ static void __init __get_smp_config(unsigned int early) } printk(KERN_INFO "Default MP configuration #%d\n", - mpf->mpf_feature1); - construct_default_ISA_mptable(mpf->mpf_feature1); + mpf->feature1); + construct_default_ISA_mptable(mpf->feature1); - } else if (mpf->mpf_physptr) { + } else if (mpf->physptr) { /* * Read the physical hardware table. Anything here will * override the defaults. */ - if (!smp_read_mpc(phys_to_virt(mpf->mpf_physptr), early)) { + if (!smp_read_mpc(phys_to_virt(mpf->physptr), early)) { #ifdef CONFIG_X86_LOCAL_APIC smp_found_config = 0; #endif @@ -696,10 +696,10 @@ static int __init smp_scan_config(unsigned long base, unsigned long length, while (length > 0) { mpf = (struct mpf_intel *)bp; if ((*bp == SMP_MAGIC_IDENT) && - (mpf->mpf_length == 1) && + (mpf->length == 1) && !mpf_checksum((unsigned char *)bp, 16) && - ((mpf->mpf_specification == 1) - || (mpf->mpf_specification == 4))) { + ((mpf->specification == 1) + || (mpf->specification == 4))) { #ifdef CONFIG_X86_LOCAL_APIC smp_found_config = 1; #endif @@ -712,7 +712,7 @@ static int __init smp_scan_config(unsigned long base, unsigned long length, return 1; reserve_bootmem_generic(virt_to_phys(mpf), PAGE_SIZE, BOOTMEM_DEFAULT); - if (mpf->mpf_physptr) { + if (mpf->physptr) { unsigned long size = PAGE_SIZE; #ifdef CONFIG_X86_32 /* @@ -721,14 +721,14 @@ static int __init smp_scan_config(unsigned long base, unsigned long length, * the bottom is mapped now. * PC-9800's MPC table places on the very last * of physical memory; so that simply reserving - * PAGE_SIZE from mpg->mpf_physptr yields BUG() + * PAGE_SIZE from mpf->physptr yields BUG() * in reserve_bootmem. */ unsigned long end = max_low_pfn * PAGE_SIZE; - if (mpf->mpf_physptr + size > end) - size = end - mpf->mpf_physptr; + if (mpf->physptr + size > end) + size = end - mpf->physptr; #endif - reserve_bootmem_generic(mpf->mpf_physptr, size, + reserve_bootmem_generic(mpf->physptr, size, BOOTMEM_DEFAULT); } @@ -1013,19 +1013,19 @@ static int __init update_mp_table(void) /* * Now see if we need to go further. */ - if (mpf->mpf_feature1 != 0) + if (mpf->feature1 != 0) return 0; - if (!mpf->mpf_physptr) + if (!mpf->physptr) return 0; - mpc = phys_to_virt(mpf->mpf_physptr); + mpc = phys_to_virt(mpf->physptr); if (!smp_check_mpc(mpc, oem, str)) return 0; printk(KERN_INFO "mpf: %lx\n", virt_to_phys(mpf)); - printk(KERN_INFO "mpf_physptr: %x\n", mpf->mpf_physptr); + printk(KERN_INFO "physptr: %x\n", mpf->physptr); if (mpc_new_phys && mpc->length > mpc_new_length) { mpc_new_phys = 0; @@ -1046,23 +1046,23 @@ static int __init update_mp_table(void) } printk(KERN_INFO "use in-positon replacing\n"); } else { - mpf->mpf_physptr = mpc_new_phys; + mpf->physptr = mpc_new_phys; mpc_new = phys_to_virt(mpc_new_phys); memcpy(mpc_new, mpc, mpc->length); mpc = mpc_new; /* check if we can modify that */ - if (mpc_new_phys - mpf->mpf_physptr) { + if (mpc_new_phys - mpf->physptr) { struct mpf_intel *mpf_new; /* steal 16 bytes from [0, 1k) */ printk(KERN_INFO "mpf new: %x\n", 0x400 - 16); mpf_new = phys_to_virt(0x400 - 16); memcpy(mpf_new, mpf, 16); mpf = mpf_new; - mpf->mpf_physptr = mpc_new_phys; + mpf->physptr = mpc_new_phys; } - mpf->mpf_checksum = 0; - mpf->mpf_checksum -= mpf_checksum((unsigned char *)mpf, 16); - printk(KERN_INFO "mpf_physptr new: %x\n", mpf->mpf_physptr); + mpf->checksum = 0; + mpf->checksum -= mpf_checksum((unsigned char *)mpf, 16); + printk(KERN_INFO "physptr new: %x\n", mpf->physptr); } /* -- cgit From 5619448fc55650cb76cbb825e16e4bb5d1390399 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 8 Jan 2009 15:09:12 -0800 Subject: bzip2/lzma: fix constant in decompress_inflate Impact: Cleanup Fix constant 0x8100 /* 32K */; according to Alain the value 0x8100 was left over test code to test misalignment, the correct value is indeed 0x8000 == 32K. Signed-off-by: H. Peter Anvin --- lib/decompress_inflate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/decompress_inflate.c b/lib/decompress_inflate.c index 163e66aea5f..d2e7c758d1c 100644 --- a/lib/decompress_inflate.c +++ b/lib/decompress_inflate.c @@ -41,7 +41,7 @@ STATIC int INIT gunzip(unsigned char *buf, int len, set_error_fn(error_fn); rc = -1; if (flush) { - out_len = 0x8100; /* 32 K */ + out_len = 0x8000; /* 32 K */ out_buf = malloc(out_len); } else { out_len = 0x7fffffff; /* no limit */ -- cgit From 6c11b12ac6f101732d43b5682f5b3ae4dda4205f Mon Sep 17 00:00:00 2001 From: Alain Knaff Date: Thu, 8 Jan 2009 15:10:19 -0800 Subject: bzip2/lzma: fix decompress_inflate.c vs multi-block-with-embedded-filename Impact: Bug fix Fix gunzip uncompression, so that it also works with files with embedded filenames that are larger than one block. Signed-off-by: Alain Knaff Signed-off-by: H. Peter Anvin --- lib/decompress_inflate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/decompress_inflate.c b/lib/decompress_inflate.c index d2e7c758d1c..839a329b4fc 100644 --- a/lib/decompress_inflate.c +++ b/lib/decompress_inflate.c @@ -97,7 +97,7 @@ STATIC int INIT gunzip(unsigned char *buf, int len, strm->next_in++; strm->next_in++; } - strm->avail_in = len - 10; + strm->avail_in = len - (strm->next_in - zbuf); strm->next_out = out_buf; strm->avail_out = out_len; -- cgit From 889c92d21db40be0b7d22a59395060237895bb85 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 8 Jan 2009 15:14:17 -0800 Subject: bzip2/lzma: centralize format detection Centralize the compression format detection to a common routine in the lib directory, and use it for both initramfs and initrd. Signed-off-by: H. Peter Anvin --- include/linux/decompress/generic.h | 3 +++ init/do_mounts_rd.c | 38 ++++++----------------------- init/initramfs.c | 39 ++++++----------------------- lib/Makefile | 9 ++++--- lib/decompress.c | 50 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 72 insertions(+), 67 deletions(-) create mode 100644 lib/decompress.c diff --git a/include/linux/decompress/generic.h b/include/linux/decompress/generic.h index f847f514f78..6dfb856327b 100644 --- a/include/linux/decompress/generic.h +++ b/include/linux/decompress/generic.h @@ -26,5 +26,8 @@ typedef int (*decompress_fn) (unsigned char *inbuf, int len, *fill should be called (repeatedly...) to read data, at most IOBUF_SIZE */ +/* Utility routine to detect the decompression method */ +decompress_fn decompress_method(const unsigned char *inbuf, int len, + const char **name); #endif diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index 9c9d7dbcf9c..a06ed4f92e0 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -12,9 +12,6 @@ #include -#include -#include -#include int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */ @@ -49,24 +46,6 @@ static int __init crd_load(int in_fd, int out_fd, decompress_fn deco); * cramfs * gzip */ -static const struct compress_format { - unsigned char magic[2]; - const char *name; - decompress_fn decompressor; -} compressed_formats[] = { -#ifdef CONFIG_RD_GZIP - { {037, 0213}, "gzip", gunzip }, - { {037, 0236}, "gzip", gunzip }, -#endif -#ifdef CONFIG_RD_BZIP2 - { {0x42, 0x5a}, "bzip2", bunzip2 }, -#endif -#ifdef CONFIG_RD_LZMA - { {0x5d, 0x00}, "lzma", unlzma }, -#endif - { {0, 0}, NULL, NULL } -}; - static int __init identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) { @@ -77,7 +56,7 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) struct cramfs_super *cramfsb; int nblocks = -1; unsigned char *buf; - const struct compress_format *cf; + const char *compress_name; buf = kmalloc(size, GFP_KERNEL); if (!buf) @@ -95,15 +74,12 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) sys_lseek(fd, start_block * BLOCK_SIZE, 0); sys_read(fd, buf, size); - for (cf = compressed_formats; cf->decompressor; cf++) { - if (buf[0] == cf->magic[0] && buf[1] == cf->magic[1]) { - printk(KERN_NOTICE - "RAMDISK: %s image found at block %d\n", - cf->name, start_block); - *decompressor = cf->decompressor; - nblocks = 0; - goto done; - } + *decompressor = decompress_method(buf, size, &compress_name); + if (*decompressor) { + printk(KERN_NOTICE "RAMDISK: %s image found at block %d\n", + compress_name, start_block); + nblocks = 0; + goto done; } /* romfs is at block zero too */ diff --git a/init/initramfs.c b/init/initramfs.c index a3ba91cdab8..2f42984e558 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -416,13 +416,13 @@ static int __init flush_buffer(void *bufv, unsigned len) static unsigned my_inptr; /* index of next byte to be processed in inbuf */ -#include -#include -#include +#include static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only) { int written; + decompress_fn decompress; + dry_run = check_only; header_buf = kmalloc(110, GFP_KERNEL); symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL); @@ -450,35 +450,10 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only) continue; } this_header = 0; -#ifdef CONFIG_RD_GZIP - if (!gunzip(buf, len, NULL, flush_buffer, NULL, - &my_inptr, error) && - message == NULL) - goto ok; -#endif - -#ifdef CONFIG_RD_BZIP2 - message = NULL; /* Zero out message, or else cpio will - think an error has already occured */ - if (!bunzip2(buf, len, NULL, flush_buffer, NULL, - &my_inptr, error) && - message == NULL) { - goto ok; - } -#endif - -#ifdef CONFIG_RD_LZMA - message = NULL; /* Zero out message, or else cpio will - think an error has already occured */ - if (!unlzma(buf, len, NULL, flush_buffer, NULL, - &my_inptr, error) && - message == NULL) { - goto ok; - } -#endif -#if defined CONFIG_RD_GZIP || defined CONFIG_RD_BZIP2 || defined CONFIG_RD_LZMA -ok: -#endif + decompress = decompress_method(buf, len, NULL); + if (decompress) + decompress(buf, len, NULL, flush_buffer, NULL, + &my_inptr, error); if (state != Reset) error("junk in compressed archive"); this_header = saved_offset + my_inptr; diff --git a/lib/Makefile b/lib/Makefile index d9ac5a414fa..790de7c25d0 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -11,7 +11,8 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \ rbtree.o radix-tree.o dump_stack.o \ idr.o int_sqrt.o extable.o prio_tree.o \ sha1.o irq_regs.o reciprocal_div.o argv_split.o \ - proportions.o prio_heap.o ratelimit.o show_mem.o is_single_threaded.o + proportions.o prio_heap.o ratelimit.o show_mem.o \ + is_single_threaded.o decompress.o lib-$(CONFIG_MMU) += ioremap.o lib-$(CONFIG_SMP) += cpumask.o @@ -65,9 +66,9 @@ obj-$(CONFIG_REED_SOLOMON) += reed_solomon/ obj-$(CONFIG_LZO_COMPRESS) += lzo/ obj-$(CONFIG_LZO_DECOMPRESS) += lzo/ -obj-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o -obj-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o -obj-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o +lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o +lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o +lib-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o obj-$(CONFIG_TEXTSEARCH) += textsearch.o obj-$(CONFIG_TEXTSEARCH_KMP) += ts_kmp.o diff --git a/lib/decompress.c b/lib/decompress.c new file mode 100644 index 00000000000..edac55cc782 --- /dev/null +++ b/lib/decompress.c @@ -0,0 +1,50 @@ +/* + * decompress.c + * + * Detect the decompression method based on magic number + */ + +#include + +#include +#include +#include + +#include +#include + +static const struct compress_format { + unsigned char magic[2]; + const char *name; + decompress_fn decompressor; +} compressed_formats[] = { +#ifdef CONFIG_DECOMPRESS_GZIP + { {037, 0213}, "gzip", gunzip }, + { {037, 0236}, "gzip", gunzip }, +#endif +#ifdef CONFIG_DECOMPRESS_BZIP2 + { {0x42, 0x5a}, "bzip2", bunzip2 }, +#endif +#ifdef CONFIG_DECOMPRESS_LZMA + { {0x5d, 0x00}, "lzma", unlzma }, +#endif + { {0, 0}, NULL, NULL } +}; + +decompress_fn decompress_method(const unsigned char *inbuf, int len, + const char **name) +{ + const struct compress_format *cf; + + if (len < 2) + return NULL; /* Need at least this much... */ + + for (cf = compressed_formats; cf->decompressor; cf++) { + if (!memcmp(inbuf, cf->magic, 2)) + break; + + } + if (name) + *name = cf->name; + return cf->decompressor; +} -- cgit From c9a98553d513dfc82cdce869970d5662c1f22c68 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 1 Jan 2009 14:21:16 -0500 Subject: [XFS] pass XFS_IGET_BULKSTAT to xfs_iget for handle operations NFS clients or users of the handle ioctls can pass us arbitrary inode numbers through the exportfs interface. Make sure we use the XFS_IGET_BULKSTAT so that these don't cause shutdowns due to the corruption checks. Also translate the EINVAL we get back for invalid inode clusters into an ESTALE which is more appropinquate, and remove the useless check for a NULL inode on a successfull xfs_iget return. I have a testcase to reproduce this using the handle interface which I will submit to xfsqa. Reported-by: Mario Becroft Signed-off-by: Christoph Hellwig Reviewed-by: Eric Sandeen Signed-off-by: Lachlan McIlroy --- fs/xfs/linux-2.6/xfs_export.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c index 595751f7835..87b8cbd23d4 100644 --- a/fs/xfs/linux-2.6/xfs_export.c +++ b/fs/xfs/linux-2.6/xfs_export.c @@ -126,11 +126,26 @@ xfs_nfs_get_inode( if (ino == 0) return ERR_PTR(-ESTALE); - error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, 0); - if (error) + /* + * The XFS_IGET_BULKSTAT means that an invalid inode number is just + * fine and not an indication of a corrupted filesystem. Because + * clients can send any kind of invalid file handle, e.g. after + * a restore on the server we have to deal with this case gracefully. + */ + error = xfs_iget(mp, NULL, ino, XFS_IGET_BULKSTAT, + XFS_ILOCK_SHARED, &ip, 0); + if (error) { + /* + * EINVAL means the inode cluster doesn't exist anymore. + * This implies the filehandle is stale, so we should + * translate it here. + * We don't use ESTALE directly down the chain to not + * confuse applications using bulkstat that expect EINVAL. + */ + if (error == EINVAL) + error = ESTALE; return ERR_PTR(-error); - if (!ip) - return ERR_PTR(-EIO); + } if (ip->i_d.di_gen != generation) { xfs_iput_new(ip, XFS_ILOCK_SHARED); -- cgit From 9800b550355e99c9bcaba7ec6540751dce0823d7 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Thu, 1 Jan 2009 16:40:10 -0600 Subject: [XFS] Remove several unused typedefs. Signed-off-by: Eric Sandeen Reviewed-by: Christoph Hellwig Signed-off-by: Lachlan McIlroy --- fs/xfs/linux-2.6/xfs_aops.h | 2 -- fs/xfs/xfs_acl.h | 1 - fs/xfs/xfs_types.h | 2 -- 3 files changed, 5 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_aops.h b/fs/xfs/linux-2.6/xfs_aops.h index 7b26f5ff969..1dd52884975 100644 --- a/fs/xfs/linux-2.6/xfs_aops.h +++ b/fs/xfs/linux-2.6/xfs_aops.h @@ -21,8 +21,6 @@ extern struct workqueue_struct *xfsdatad_workqueue; extern mempool_t *xfs_ioend_pool; -typedef void (*xfs_ioend_func_t)(void *); - /* * xfs_ioend struct manages large extent writes for XFS. * It can manage several multi-page bio's at once. diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index a4e293b93ef..642f1db4def 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h @@ -22,7 +22,6 @@ * Access Control Lists */ typedef __uint16_t xfs_acl_perm_t; -typedef __int32_t xfs_acl_type_t; typedef __int32_t xfs_acl_tag_t; typedef __int32_t xfs_acl_id_t; diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h index 0f5191644ab..baedbd14dc2 100644 --- a/fs/xfs/xfs_types.h +++ b/fs/xfs/xfs_types.h @@ -111,8 +111,6 @@ typedef __uint64_t xfs_fileoff_t; /* block number in a file */ typedef __int64_t xfs_sfiloff_t; /* signed block number in a file */ typedef __uint64_t xfs_filblks_t; /* number of blocks in a file */ -typedef __uint8_t xfs_arch_t; /* architecture of an xfs fs */ - /* * Null values for the types. */ -- cgit From c9fb86a917640d66ba2e0613a12f3a76eda8a30f Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Thu, 1 Jan 2009 16:40:11 -0600 Subject: [XFS] Remove macro-to-function indirections in attr code Signed-off-by: Eric Sandeen Reviewed-by: Christoph Hellwig Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_attr_leaf.c | 72 +++++++++++++++++++++++++------------------------- fs/xfs/xfs_attr_leaf.h | 12 --------- 2 files changed, 36 insertions(+), 48 deletions(-) diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index 79da6b2ea99..6c323f8a4cd 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c @@ -736,7 +736,7 @@ xfs_attr_shortform_allfit(xfs_dabuf_t *bp, xfs_inode_t *dp) continue; /* don't copy partial entries */ if (!(entry->flags & XFS_ATTR_LOCAL)) return(0); - name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, i); + name_loc = xfs_attr_leaf_name_local(leaf, i); if (name_loc->namelen >= XFS_ATTR_SF_ENTSIZE_MAX) return(0); if (be16_to_cpu(name_loc->valuelen) >= XFS_ATTR_SF_ENTSIZE_MAX) @@ -823,7 +823,7 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff) if (!entry->nameidx) continue; ASSERT(entry->flags & XFS_ATTR_LOCAL); - name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, i); + name_loc = xfs_attr_leaf_name_local(leaf, i); nargs.name = (char *)name_loc->nameval; nargs.namelen = name_loc->namelen; nargs.value = (char *)&name_loc->nameval[nargs.namelen]; @@ -1141,14 +1141,14 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex) * as part of this transaction (a split operation for example). */ if (entry->flags & XFS_ATTR_LOCAL) { - name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, args->index); + name_loc = xfs_attr_leaf_name_local(leaf, args->index); name_loc->namelen = args->namelen; name_loc->valuelen = cpu_to_be16(args->valuelen); memcpy((char *)name_loc->nameval, args->name, args->namelen); memcpy((char *)&name_loc->nameval[args->namelen], args->value, be16_to_cpu(name_loc->valuelen)); } else { - name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, args->index); + name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); name_rmt->namelen = args->namelen; memcpy((char *)name_rmt->name, args->name, args->namelen); entry->flags |= XFS_ATTR_INCOMPLETE; @@ -1159,7 +1159,7 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex) args->rmtblkcnt = XFS_B_TO_FSB(mp, args->valuelen); } xfs_da_log_buf(args->trans, bp, - XFS_DA_LOGRANGE(leaf, XFS_ATTR_LEAF_NAME(leaf, args->index), + XFS_DA_LOGRANGE(leaf, xfs_attr_leaf_name(leaf, args->index), xfs_attr_leaf_entsize(leaf, args->index))); /* @@ -1749,10 +1749,10 @@ xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args) /* * Compress the remaining entries and zero out the removed stuff. */ - memset(XFS_ATTR_LEAF_NAME(leaf, args->index), 0, entsize); + memset(xfs_attr_leaf_name(leaf, args->index), 0, entsize); be16_add_cpu(&hdr->usedbytes, -entsize); xfs_da_log_buf(args->trans, bp, - XFS_DA_LOGRANGE(leaf, XFS_ATTR_LEAF_NAME(leaf, args->index), + XFS_DA_LOGRANGE(leaf, xfs_attr_leaf_name(leaf, args->index), entsize)); tmp = (be16_to_cpu(hdr->count) - args->index) @@ -1985,7 +1985,7 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args) continue; } if (entry->flags & XFS_ATTR_LOCAL) { - name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, probe); + name_loc = xfs_attr_leaf_name_local(leaf, probe); if (name_loc->namelen != args->namelen) continue; if (memcmp(args->name, (char *)name_loc->nameval, args->namelen) != 0) @@ -1995,7 +1995,7 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args) args->index = probe; return(XFS_ERROR(EEXIST)); } else { - name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, probe); + name_rmt = xfs_attr_leaf_name_remote(leaf, probe); if (name_rmt->namelen != args->namelen) continue; if (memcmp(args->name, (char *)name_rmt->name, @@ -2035,7 +2035,7 @@ xfs_attr_leaf_getvalue(xfs_dabuf_t *bp, xfs_da_args_t *args) entry = &leaf->entries[args->index]; if (entry->flags & XFS_ATTR_LOCAL) { - name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, args->index); + name_loc = xfs_attr_leaf_name_local(leaf, args->index); ASSERT(name_loc->namelen == args->namelen); ASSERT(memcmp(args->name, name_loc->nameval, args->namelen) == 0); valuelen = be16_to_cpu(name_loc->valuelen); @@ -2050,7 +2050,7 @@ xfs_attr_leaf_getvalue(xfs_dabuf_t *bp, xfs_da_args_t *args) args->valuelen = valuelen; memcpy(args->value, &name_loc->nameval[args->namelen], valuelen); } else { - name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, args->index); + name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); ASSERT(name_rmt->namelen == args->namelen); ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0); valuelen = be32_to_cpu(name_rmt->valuelen); @@ -2143,7 +2143,7 @@ xfs_attr_leaf_moveents(xfs_attr_leafblock_t *leaf_s, int start_s, * off for 6.2, should be revisited later. */ if (entry_s->flags & XFS_ATTR_INCOMPLETE) { /* skip partials? */ - memset(XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), 0, tmp); + memset(xfs_attr_leaf_name(leaf_s, start_s + i), 0, tmp); be16_add_cpu(&hdr_s->usedbytes, -tmp); be16_add_cpu(&hdr_s->count, -1); entry_d--; /* to compensate for ++ in loop hdr */ @@ -2160,11 +2160,11 @@ xfs_attr_leaf_moveents(xfs_attr_leafblock_t *leaf_s, int start_s, entry_d->flags = entry_s->flags; ASSERT(be16_to_cpu(entry_d->nameidx) + tmp <= XFS_LBSIZE(mp)); - memmove(XFS_ATTR_LEAF_NAME(leaf_d, desti), - XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), tmp); + memmove(xfs_attr_leaf_name(leaf_d, desti), + xfs_attr_leaf_name(leaf_s, start_s + i), tmp); ASSERT(be16_to_cpu(entry_s->nameidx) + tmp <= XFS_LBSIZE(mp)); - memset(XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), 0, tmp); + memset(xfs_attr_leaf_name(leaf_s, start_s + i), 0, tmp); be16_add_cpu(&hdr_s->usedbytes, -tmp); be16_add_cpu(&hdr_d->usedbytes, tmp); be16_add_cpu(&hdr_s->count, -1); @@ -2276,12 +2276,12 @@ xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index) ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); if (leaf->entries[index].flags & XFS_ATTR_LOCAL) { - name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, index); - size = XFS_ATTR_LEAF_ENTSIZE_LOCAL(name_loc->namelen, + name_loc = xfs_attr_leaf_name_local(leaf, index); + size = xfs_attr_leaf_entsize_local(name_loc->namelen, be16_to_cpu(name_loc->valuelen)); } else { - name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, index); - size = XFS_ATTR_LEAF_ENTSIZE_REMOTE(name_rmt->namelen); + name_rmt = xfs_attr_leaf_name_remote(leaf, index); + size = xfs_attr_leaf_entsize_remote(name_rmt->namelen); } return(size); } @@ -2297,13 +2297,13 @@ xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, int *local) { int size; - size = XFS_ATTR_LEAF_ENTSIZE_LOCAL(namelen, valuelen); - if (size < XFS_ATTR_LEAF_ENTSIZE_LOCAL_MAX(blocksize)) { + size = xfs_attr_leaf_entsize_local(namelen, valuelen); + if (size < xfs_attr_leaf_entsize_local_max(blocksize)) { if (local) { *local = 1; } } else { - size = XFS_ATTR_LEAF_ENTSIZE_REMOTE(namelen); + size = xfs_attr_leaf_entsize_remote(namelen); if (local) { *local = 0; } @@ -2372,7 +2372,7 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context) if (entry->flags & XFS_ATTR_LOCAL) { xfs_attr_leaf_name_local_t *name_loc = - XFS_ATTR_LEAF_NAME_LOCAL(leaf, i); + xfs_attr_leaf_name_local(leaf, i); retval = context->put_listent(context, entry->flags, @@ -2384,7 +2384,7 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context) return retval; } else { xfs_attr_leaf_name_remote_t *name_rmt = - XFS_ATTR_LEAF_NAME_REMOTE(leaf, i); + xfs_attr_leaf_name_remote(leaf, i); int valuelen = be32_to_cpu(name_rmt->valuelen); @@ -2468,11 +2468,11 @@ xfs_attr_leaf_clearflag(xfs_da_args_t *args) #ifdef DEBUG if (entry->flags & XFS_ATTR_LOCAL) { - name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, args->index); + name_loc = xfs_attr_leaf_name_local(leaf, args->index); namelen = name_loc->namelen; name = (char *)name_loc->nameval; } else { - name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, args->index); + name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); namelen = name_rmt->namelen; name = (char *)name_rmt->name; } @@ -2487,7 +2487,7 @@ xfs_attr_leaf_clearflag(xfs_da_args_t *args) if (args->rmtblkno) { ASSERT((entry->flags & XFS_ATTR_LOCAL) == 0); - name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, args->index); + name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); name_rmt->valueblk = cpu_to_be32(args->rmtblkno); name_rmt->valuelen = cpu_to_be32(args->valuelen); xfs_da_log_buf(args->trans, bp, @@ -2534,7 +2534,7 @@ xfs_attr_leaf_setflag(xfs_da_args_t *args) xfs_da_log_buf(args->trans, bp, XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry))); if ((entry->flags & XFS_ATTR_LOCAL) == 0) { - name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, args->index); + name_rmt = xfs_attr_leaf_name_remote(leaf, args->index); name_rmt->valueblk = 0; name_rmt->valuelen = 0; xfs_da_log_buf(args->trans, bp, @@ -2607,20 +2607,20 @@ xfs_attr_leaf_flipflags(xfs_da_args_t *args) #ifdef DEBUG if (entry1->flags & XFS_ATTR_LOCAL) { - name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf1, args->index); + name_loc = xfs_attr_leaf_name_local(leaf1, args->index); namelen1 = name_loc->namelen; name1 = (char *)name_loc->nameval; } else { - name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf1, args->index); + name_rmt = xfs_attr_leaf_name_remote(leaf1, args->index); namelen1 = name_rmt->namelen; name1 = (char *)name_rmt->name; } if (entry2->flags & XFS_ATTR_LOCAL) { - name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf2, args->index2); + name_loc = xfs_attr_leaf_name_local(leaf2, args->index2); namelen2 = name_loc->namelen; name2 = (char *)name_loc->nameval; } else { - name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf2, args->index2); + name_rmt = xfs_attr_leaf_name_remote(leaf2, args->index2); namelen2 = name_rmt->namelen; name2 = (char *)name_rmt->name; } @@ -2637,7 +2637,7 @@ xfs_attr_leaf_flipflags(xfs_da_args_t *args) XFS_DA_LOGRANGE(leaf1, entry1, sizeof(*entry1))); if (args->rmtblkno) { ASSERT((entry1->flags & XFS_ATTR_LOCAL) == 0); - name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf1, args->index); + name_rmt = xfs_attr_leaf_name_remote(leaf1, args->index); name_rmt->valueblk = cpu_to_be32(args->rmtblkno); name_rmt->valuelen = cpu_to_be32(args->valuelen); xfs_da_log_buf(args->trans, bp1, @@ -2648,7 +2648,7 @@ xfs_attr_leaf_flipflags(xfs_da_args_t *args) xfs_da_log_buf(args->trans, bp2, XFS_DA_LOGRANGE(leaf2, entry2, sizeof(*entry2))); if ((entry2->flags & XFS_ATTR_LOCAL) == 0) { - name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf2, args->index2); + name_rmt = xfs_attr_leaf_name_remote(leaf2, args->index2); name_rmt->valueblk = 0; name_rmt->valuelen = 0; xfs_da_log_buf(args->trans, bp2, @@ -2855,7 +2855,7 @@ xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp) for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { if (be16_to_cpu(entry->nameidx) && ((entry->flags & XFS_ATTR_LOCAL) == 0)) { - name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, i); + name_rmt = xfs_attr_leaf_name_remote(leaf, i); if (name_rmt->valueblk) count++; } @@ -2883,7 +2883,7 @@ xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp) for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { if (be16_to_cpu(entry->nameidx) && ((entry->flags & XFS_ATTR_LOCAL) == 0)) { - name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, i); + name_rmt = xfs_attr_leaf_name_remote(leaf, i); if (name_rmt->valueblk) { lp->valueblk = be32_to_cpu(name_rmt->valueblk); lp->valuelen = XFS_B_TO_FSB(dp->i_mount, diff --git a/fs/xfs/xfs_attr_leaf.h b/fs/xfs/xfs_attr_leaf.h index 83e9af417ca..9c7d22fdcf4 100644 --- a/fs/xfs/xfs_attr_leaf.h +++ b/fs/xfs/xfs_attr_leaf.h @@ -151,8 +151,6 @@ typedef struct xfs_attr_leafblock { /* * Cast typed pointers for "local" and "remote" name/value structs. */ -#define XFS_ATTR_LEAF_NAME_REMOTE(leafp,idx) \ - xfs_attr_leaf_name_remote(leafp,idx) static inline xfs_attr_leaf_name_remote_t * xfs_attr_leaf_name_remote(xfs_attr_leafblock_t *leafp, int idx) { @@ -160,8 +158,6 @@ xfs_attr_leaf_name_remote(xfs_attr_leafblock_t *leafp, int idx) &((char *)leafp)[be16_to_cpu(leafp->entries[idx].nameidx)]; } -#define XFS_ATTR_LEAF_NAME_LOCAL(leafp,idx) \ - xfs_attr_leaf_name_local(leafp,idx) static inline xfs_attr_leaf_name_local_t * xfs_attr_leaf_name_local(xfs_attr_leafblock_t *leafp, int idx) { @@ -169,8 +165,6 @@ xfs_attr_leaf_name_local(xfs_attr_leafblock_t *leafp, int idx) &((char *)leafp)[be16_to_cpu(leafp->entries[idx].nameidx)]; } -#define XFS_ATTR_LEAF_NAME(leafp,idx) \ - xfs_attr_leaf_name(leafp,idx) static inline char *xfs_attr_leaf_name(xfs_attr_leafblock_t *leafp, int idx) { return &((char *)leafp)[be16_to_cpu(leafp->entries[idx].nameidx)]; @@ -181,24 +175,18 @@ static inline char *xfs_attr_leaf_name(xfs_attr_leafblock_t *leafp, int idx) * a "local" name/value structure, a "remote" name/value structure, and * a pointer which might be either. */ -#define XFS_ATTR_LEAF_ENTSIZE_REMOTE(nlen) \ - xfs_attr_leaf_entsize_remote(nlen) static inline int xfs_attr_leaf_entsize_remote(int nlen) { return ((uint)sizeof(xfs_attr_leaf_name_remote_t) - 1 + (nlen) + \ XFS_ATTR_LEAF_NAME_ALIGN - 1) & ~(XFS_ATTR_LEAF_NAME_ALIGN - 1); } -#define XFS_ATTR_LEAF_ENTSIZE_LOCAL(nlen,vlen) \ - xfs_attr_leaf_entsize_local(nlen,vlen) static inline int xfs_attr_leaf_entsize_local(int nlen, int vlen) { return ((uint)sizeof(xfs_attr_leaf_name_local_t) - 1 + (nlen) + (vlen) + XFS_ATTR_LEAF_NAME_ALIGN - 1) & ~(XFS_ATTR_LEAF_NAME_ALIGN - 1); } -#define XFS_ATTR_LEAF_ENTSIZE_LOCAL_MAX(bsize) \ - xfs_attr_leaf_entsize_local_max(bsize) static inline int xfs_attr_leaf_entsize_local_max(int bsize) { return (((bsize) >> 1) + ((bsize) >> 2)); -- cgit From fb82557f16f3700ae4961a4ce599bdaff6a10b1c Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Fri, 9 Jan 2009 15:53:54 +1100 Subject: [XFS] Remove macro-to-function indirections in the mask code Signed-off-by: Eric Sandeen Reviewed-by: Christoph Hellwig Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_ag.h | 2 +- fs/xfs/xfs_bit.h | 10 +----- fs/xfs/xfs_bmap_btree.c | 84 ++++++++++++++++++++++++------------------------- 3 files changed, 44 insertions(+), 52 deletions(-) diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h index f2e21817a22..d3b3cf74299 100644 --- a/fs/xfs/xfs_ag.h +++ b/fs/xfs/xfs_ag.h @@ -231,7 +231,7 @@ typedef struct xfs_perag #define XFS_FSB_TO_AGNO(mp,fsbno) \ ((xfs_agnumber_t)((fsbno) >> (mp)->m_sb.sb_agblklog)) #define XFS_FSB_TO_AGBNO(mp,fsbno) \ - ((xfs_agblock_t)((fsbno) & XFS_MASK32LO((mp)->m_sb.sb_agblklog))) + ((xfs_agblock_t)((fsbno) & xfs_mask32lo((mp)->m_sb.sb_agblklog))) #define XFS_AGB_TO_DADDR(mp,agno,agbno) \ ((xfs_daddr_t)XFS_FSB_TO_BB(mp, \ (xfs_fsblock_t)(agno) * (mp)->m_sb.sb_agblocks + (agbno))) diff --git a/fs/xfs/xfs_bit.h b/fs/xfs/xfs_bit.h index bca7b243c31..f1e3c907044 100644 --- a/fs/xfs/xfs_bit.h +++ b/fs/xfs/xfs_bit.h @@ -23,24 +23,16 @@ */ /* - * masks with n high/low bits set, 32-bit values & 64-bit values + * masks with n high/low bits set, 64-bit values */ -#define XFS_MASK32HI(n) xfs_mask32hi(n) -static inline __uint32_t xfs_mask32hi(int n) -{ - return (__uint32_t)-1 << (32 - (n)); -} -#define XFS_MASK64HI(n) xfs_mask64hi(n) static inline __uint64_t xfs_mask64hi(int n) { return (__uint64_t)-1 << (64 - (n)); } -#define XFS_MASK32LO(n) xfs_mask32lo(n) static inline __uint32_t xfs_mask32lo(int n) { return ((__uint32_t)1 << (n)) - 1; } -#define XFS_MASK64LO(n) xfs_mask64lo(n) static inline __uint64_t xfs_mask64lo(int n) { return ((__uint64_t)1 << (n)) - 1; diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index 8f1ec73725d..ba6b08c2fb0 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c @@ -110,16 +110,16 @@ __xfs_bmbt_get_all( ext_flag = (int)(l0 >> (64 - BMBT_EXNTFLAG_BITLEN)); s->br_startoff = ((xfs_fileoff_t)l0 & - XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; + xfs_mask64lo(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; #if XFS_BIG_BLKNOS - s->br_startblock = (((xfs_fsblock_t)l0 & XFS_MASK64LO(9)) << 43) | + s->br_startblock = (((xfs_fsblock_t)l0 & xfs_mask64lo(9)) << 43) | (((xfs_fsblock_t)l1) >> 21); #else #ifdef DEBUG { xfs_dfsbno_t b; - b = (((xfs_dfsbno_t)l0 & XFS_MASK64LO(9)) << 43) | + b = (((xfs_dfsbno_t)l0 & xfs_mask64lo(9)) << 43) | (((xfs_dfsbno_t)l1) >> 21); ASSERT((b >> 32) == 0 || ISNULLDSTARTBLOCK(b)); s->br_startblock = (xfs_fsblock_t)b; @@ -128,7 +128,7 @@ __xfs_bmbt_get_all( s->br_startblock = (xfs_fsblock_t)(((xfs_dfsbno_t)l1) >> 21); #endif /* DEBUG */ #endif /* XFS_BIG_BLKNOS */ - s->br_blockcount = (xfs_filblks_t)(l1 & XFS_MASK64LO(21)); + s->br_blockcount = (xfs_filblks_t)(l1 & xfs_mask64lo(21)); /* This is xfs_extent_state() in-line */ if (ext_flag) { ASSERT(s->br_blockcount != 0); /* saved for DMIG */ @@ -153,7 +153,7 @@ xfs_filblks_t xfs_bmbt_get_blockcount( xfs_bmbt_rec_host_t *r) { - return (xfs_filblks_t)(r->l1 & XFS_MASK64LO(21)); + return (xfs_filblks_t)(r->l1 & xfs_mask64lo(21)); } /* @@ -164,13 +164,13 @@ xfs_bmbt_get_startblock( xfs_bmbt_rec_host_t *r) { #if XFS_BIG_BLKNOS - return (((xfs_fsblock_t)r->l0 & XFS_MASK64LO(9)) << 43) | + return (((xfs_fsblock_t)r->l0 & xfs_mask64lo(9)) << 43) | (((xfs_fsblock_t)r->l1) >> 21); #else #ifdef DEBUG xfs_dfsbno_t b; - b = (((xfs_dfsbno_t)r->l0 & XFS_MASK64LO(9)) << 43) | + b = (((xfs_dfsbno_t)r->l0 & xfs_mask64lo(9)) << 43) | (((xfs_dfsbno_t)r->l1) >> 21); ASSERT((b >> 32) == 0 || ISNULLDSTARTBLOCK(b)); return (xfs_fsblock_t)b; @@ -188,7 +188,7 @@ xfs_bmbt_get_startoff( xfs_bmbt_rec_host_t *r) { return ((xfs_fileoff_t)r->l0 & - XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; + xfs_mask64lo(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; } xfs_exntst_t @@ -219,7 +219,7 @@ xfs_filblks_t xfs_bmbt_disk_get_blockcount( xfs_bmbt_rec_t *r) { - return (xfs_filblks_t)(be64_to_cpu(r->l1) & XFS_MASK64LO(21)); + return (xfs_filblks_t)(be64_to_cpu(r->l1) & xfs_mask64lo(21)); } /* @@ -230,7 +230,7 @@ xfs_bmbt_disk_get_startoff( xfs_bmbt_rec_t *r) { return ((xfs_fileoff_t)be64_to_cpu(r->l0) & - XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; + xfs_mask64lo(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; } @@ -248,33 +248,33 @@ xfs_bmbt_set_allf( int extent_flag = (state == XFS_EXT_NORM) ? 0 : 1; ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN); - ASSERT((startoff & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0); - ASSERT((blockcount & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0); + ASSERT((startoff & xfs_mask64hi(64-BMBT_STARTOFF_BITLEN)) == 0); + ASSERT((blockcount & xfs_mask64hi(64-BMBT_BLOCKCOUNT_BITLEN)) == 0); #if XFS_BIG_BLKNOS - ASSERT((startblock & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0); + ASSERT((startblock & xfs_mask64hi(64-BMBT_STARTBLOCK_BITLEN)) == 0); r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | ((xfs_bmbt_rec_base_t)startoff << 9) | ((xfs_bmbt_rec_base_t)startblock >> 43); r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) | ((xfs_bmbt_rec_base_t)blockcount & - (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); + (xfs_bmbt_rec_base_t)xfs_mask64lo(21)); #else /* !XFS_BIG_BLKNOS */ if (ISNULLSTARTBLOCK(startblock)) { r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | ((xfs_bmbt_rec_base_t)startoff << 9) | - (xfs_bmbt_rec_base_t)XFS_MASK64LO(9); - r->l1 = XFS_MASK64HI(11) | + (xfs_bmbt_rec_base_t)xfs_mask64lo(9); + r->l1 = xfs_mask64hi(11) | ((xfs_bmbt_rec_base_t)startblock << 21) | ((xfs_bmbt_rec_base_t)blockcount & - (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); + (xfs_bmbt_rec_base_t)xfs_mask64lo(21)); } else { r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | ((xfs_bmbt_rec_base_t)startoff << 9); r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) | ((xfs_bmbt_rec_base_t)blockcount & - (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); + (xfs_bmbt_rec_base_t)xfs_mask64lo(21)); } #endif /* XFS_BIG_BLKNOS */ } @@ -306,11 +306,11 @@ xfs_bmbt_disk_set_allf( int extent_flag = (state == XFS_EXT_NORM) ? 0 : 1; ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN); - ASSERT((startoff & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0); - ASSERT((blockcount & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0); + ASSERT((startoff & xfs_mask64hi(64-BMBT_STARTOFF_BITLEN)) == 0); + ASSERT((blockcount & xfs_mask64hi(64-BMBT_BLOCKCOUNT_BITLEN)) == 0); #if XFS_BIG_BLKNOS - ASSERT((startblock & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0); + ASSERT((startblock & xfs_mask64hi(64-BMBT_STARTBLOCK_BITLEN)) == 0); r->l0 = cpu_to_be64( ((xfs_bmbt_rec_base_t)extent_flag << 63) | @@ -319,17 +319,17 @@ xfs_bmbt_disk_set_allf( r->l1 = cpu_to_be64( ((xfs_bmbt_rec_base_t)startblock << 21) | ((xfs_bmbt_rec_base_t)blockcount & - (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); + (xfs_bmbt_rec_base_t)xfs_mask64lo(21))); #else /* !XFS_BIG_BLKNOS */ if (ISNULLSTARTBLOCK(startblock)) { r->l0 = cpu_to_be64( ((xfs_bmbt_rec_base_t)extent_flag << 63) | ((xfs_bmbt_rec_base_t)startoff << 9) | - (xfs_bmbt_rec_base_t)XFS_MASK64LO(9)); - r->l1 = cpu_to_be64(XFS_MASK64HI(11) | + (xfs_bmbt_rec_base_t)xfs_mask64lo(9)); + r->l1 = cpu_to_be64(xfs_mask64hi(11) | ((xfs_bmbt_rec_base_t)startblock << 21) | ((xfs_bmbt_rec_base_t)blockcount & - (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); + (xfs_bmbt_rec_base_t)xfs_mask64lo(21))); } else { r->l0 = cpu_to_be64( ((xfs_bmbt_rec_base_t)extent_flag << 63) | @@ -337,7 +337,7 @@ xfs_bmbt_disk_set_allf( r->l1 = cpu_to_be64( ((xfs_bmbt_rec_base_t)startblock << 21) | ((xfs_bmbt_rec_base_t)blockcount & - (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); + (xfs_bmbt_rec_base_t)xfs_mask64lo(21))); } #endif /* XFS_BIG_BLKNOS */ } @@ -362,9 +362,9 @@ xfs_bmbt_set_blockcount( xfs_bmbt_rec_host_t *r, xfs_filblks_t v) { - ASSERT((v & XFS_MASK64HI(43)) == 0); - r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64HI(43)) | - (xfs_bmbt_rec_base_t)(v & XFS_MASK64LO(21)); + ASSERT((v & xfs_mask64hi(43)) == 0); + r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)xfs_mask64hi(43)) | + (xfs_bmbt_rec_base_t)(v & xfs_mask64lo(21)); } /* @@ -376,21 +376,21 @@ xfs_bmbt_set_startblock( xfs_fsblock_t v) { #if XFS_BIG_BLKNOS - ASSERT((v & XFS_MASK64HI(12)) == 0); - r->l0 = (r->l0 & (xfs_bmbt_rec_base_t)XFS_MASK64HI(55)) | + ASSERT((v & xfs_mask64hi(12)) == 0); + r->l0 = (r->l0 & (xfs_bmbt_rec_base_t)xfs_mask64hi(55)) | (xfs_bmbt_rec_base_t)(v >> 43); - r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)) | + r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)xfs_mask64lo(21)) | (xfs_bmbt_rec_base_t)(v << 21); #else /* !XFS_BIG_BLKNOS */ if (ISNULLSTARTBLOCK(v)) { - r->l0 |= (xfs_bmbt_rec_base_t)XFS_MASK64LO(9); - r->l1 = (xfs_bmbt_rec_base_t)XFS_MASK64HI(11) | + r->l0 |= (xfs_bmbt_rec_base_t)xfs_mask64lo(9); + r->l1 = (xfs_bmbt_rec_base_t)xfs_mask64hi(11) | ((xfs_bmbt_rec_base_t)v << 21) | - (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); + (r->l1 & (xfs_bmbt_rec_base_t)xfs_mask64lo(21)); } else { - r->l0 &= ~(xfs_bmbt_rec_base_t)XFS_MASK64LO(9); + r->l0 &= ~(xfs_bmbt_rec_base_t)xfs_mask64lo(9); r->l1 = ((xfs_bmbt_rec_base_t)v << 21) | - (r->l1 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); + (r->l1 & (xfs_bmbt_rec_base_t)xfs_mask64lo(21)); } #endif /* XFS_BIG_BLKNOS */ } @@ -403,10 +403,10 @@ xfs_bmbt_set_startoff( xfs_bmbt_rec_host_t *r, xfs_fileoff_t v) { - ASSERT((v & XFS_MASK64HI(9)) == 0); - r->l0 = (r->l0 & (xfs_bmbt_rec_base_t) XFS_MASK64HI(1)) | + ASSERT((v & xfs_mask64hi(9)) == 0); + r->l0 = (r->l0 & (xfs_bmbt_rec_base_t) xfs_mask64hi(1)) | ((xfs_bmbt_rec_base_t)v << 9) | - (r->l0 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(9)); + (r->l0 & (xfs_bmbt_rec_base_t)xfs_mask64lo(9)); } /* @@ -419,9 +419,9 @@ xfs_bmbt_set_state( { ASSERT(v == XFS_EXT_NORM || v == XFS_EXT_UNWRITTEN); if (v == XFS_EXT_NORM) - r->l0 &= XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN); + r->l0 &= xfs_mask64lo(64 - BMBT_EXNTFLAG_BITLEN); else - r->l0 |= XFS_MASK64HI(BMBT_EXNTFLAG_BITLEN); + r->l0 |= xfs_mask64hi(BMBT_EXNTFLAG_BITLEN); } /* -- cgit From e6edbd1c1cbef278d58cdd8b046599ba8ac90cfc Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 8 Jan 2009 13:42:23 -0500 Subject: [XFS] fix compile of xfs_btree_readahead_lblock on m68k Change the left/right variables to the proper always 64bit xfs_dfsbo_t type because otherwise compilation fails for Geert on m68k without CONFIG_LBD: | fs/xfs/xfs_btree.c: In function 'xfs_btree_readahead_lblock': | fs/xfs/xfs_btree.c:736: warning: comparison is always true due to limited range of data type | fs/xfs/xfs_btree.c:741: warning: comparison is always true due to limited range of data type Reported-by: Geert Uytterhoeven Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_btree.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c index 7ed59267420..2c3ef20f884 100644 --- a/fs/xfs/xfs_btree.c +++ b/fs/xfs/xfs_btree.c @@ -730,8 +730,8 @@ xfs_btree_readahead_lblock( struct xfs_btree_block *block) { int rval = 0; - xfs_fsblock_t left = be64_to_cpu(block->bb_u.l.bb_leftsib); - xfs_fsblock_t right = be64_to_cpu(block->bb_u.l.bb_rightsib); + xfs_dfsbno_t left = be64_to_cpu(block->bb_u.l.bb_leftsib); + xfs_dfsbno_t right = be64_to_cpu(block->bb_u.l.bb_rightsib); if ((lr & XFS_BTCUR_LEFTRA) && left != NULLDFSBNO) { xfs_btree_reada_bufl(cur->bc_mp, left, 1); -- cgit From 15440319767942a363f282d6585303d3d75088ba Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 8 Jan 2009 14:00:00 -0500 Subject: [XFS] truncate readdir offsets to signed 32 bit values John Stanley reported EOVERFLOW errors in readdir from his self-build glibc. I traced this down to glibc enabling d_off overflow checks in one of the about five million different getdents implementations. In 2.6.28 Dave Woodhouse moved our readdir double buffering required for NFS4 readdirplus into nfsd and at that point we lost the capping of the directory offsets to 32 bit signed values. Johns glibc used getdents64 to even implement readdir for normal 32 bit offset dirents, and failed with EOVERFLOW only if this happens on the first dirent in a getdents call. I managed to come up with a testcase that uses raw getdents and does the EOVERFLOW check manually. We always hit it with our last entry due to the special end of directory marker. The patch below is a dumb version of just putting back the masking, to make sure we have the same behavior as in 2.6.27 and earlier. I will work on a better and cleaner fix for 2.6.30. Reported-by: John Stanley Tested-by: John Stanley Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_dir2_block.c | 7 ++++--- fs/xfs/xfs_dir2_leaf.c | 6 +++--- fs/xfs/xfs_dir2_sf.c | 15 ++++++++------- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c index e2fa0a1d8e9..e1f0a06aaf0 100644 --- a/fs/xfs/xfs_dir2_block.c +++ b/fs/xfs/xfs_dir2_block.c @@ -517,9 +517,9 @@ xfs_dir2_block_getdents( /* * If it didn't fit, set the final offset to here & return. */ - if (filldir(dirent, dep->name, dep->namelen, cook, + if (filldir(dirent, dep->name, dep->namelen, cook & 0x7fffffff, ino, DT_UNKNOWN)) { - *offset = cook; + *offset = cook & 0x7fffffff; xfs_da_brelse(NULL, bp); return 0; } @@ -529,7 +529,8 @@ xfs_dir2_block_getdents( * Reached the end of the block. * Set the offset to a non-existent block 1 and return. */ - *offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0); + *offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) & + 0x7fffffff; xfs_da_brelse(NULL, bp); return 0; } diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c index 93535992cb6..ef805a374ee 100644 --- a/fs/xfs/xfs_dir2_leaf.c +++ b/fs/xfs/xfs_dir2_leaf.c @@ -1092,7 +1092,7 @@ xfs_dir2_leaf_getdents( * Won't fit. Return to caller. */ if (filldir(dirent, dep->name, dep->namelen, - xfs_dir2_byte_to_dataptr(mp, curoff), + xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff, ino, DT_UNKNOWN)) break; @@ -1108,9 +1108,9 @@ xfs_dir2_leaf_getdents( * All done. Set output offset value to current offset. */ if (curoff > xfs_dir2_dataptr_to_byte(mp, XFS_DIR2_MAX_DATAPTR)) - *offset = XFS_DIR2_MAX_DATAPTR; + *offset = XFS_DIR2_MAX_DATAPTR & 0x7fffffff; else - *offset = xfs_dir2_byte_to_dataptr(mp, curoff); + *offset = xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff; kmem_free(map); if (bp) xfs_da_brelse(NULL, bp); diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c index b46af0013ec..a8a8a6efad5 100644 --- a/fs/xfs/xfs_dir2_sf.c +++ b/fs/xfs/xfs_dir2_sf.c @@ -752,8 +752,8 @@ xfs_dir2_sf_getdents( #if XFS_BIG_INUMS ino += mp->m_inoadd; #endif - if (filldir(dirent, ".", 1, dot_offset, ino, DT_DIR)) { - *offset = dot_offset; + if (filldir(dirent, ".", 1, dot_offset & 0x7fffffff, ino, DT_DIR)) { + *offset = dot_offset & 0x7fffffff; return 0; } } @@ -766,8 +766,8 @@ xfs_dir2_sf_getdents( #if XFS_BIG_INUMS ino += mp->m_inoadd; #endif - if (filldir(dirent, "..", 2, dotdot_offset, ino, DT_DIR)) { - *offset = dotdot_offset; + if (filldir(dirent, "..", 2, dotdot_offset & 0x7fffffff, ino, DT_DIR)) { + *offset = dotdot_offset & 0x7fffffff; return 0; } } @@ -791,14 +791,15 @@ xfs_dir2_sf_getdents( #endif if (filldir(dirent, sfep->name, sfep->namelen, - off, ino, DT_UNKNOWN)) { - *offset = off; + off & 0x7fffffff, ino, DT_UNKNOWN)) { + *offset = off & 0x7fffffff; return 0; } sfep = xfs_dir2_sf_nextentry(sfp, sfep); } - *offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0); + *offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) & + 0x7fffffff; return 0; } -- cgit From 058652a37dd9eac18d6b8c1a311137c679de9dae Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 8 Jan 2009 13:42:25 -0500 Subject: [XFS] make xfs_ino_t an unsigned long long Currently xfs_ino_t is defined as a u64 which can either be an unsigned long long or on some 64 bit platforms and unsigned long. Just making it and unsigned long long mean's it's still always 64 bits wide, but we don't need to resort to cases to print it. Fixes a warning regression on 64 bit powerpc in current git. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Signed-off-by: Lachlan McIlroy --- fs/xfs/xfs_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h index baedbd14dc2..b2f724502f1 100644 --- a/fs/xfs/xfs_types.h +++ b/fs/xfs/xfs_types.h @@ -45,7 +45,7 @@ typedef __uint32_t prid_t; /* project ID */ typedef __uint32_t inst_t; /* an instruction */ typedef __s64 xfs_off_t; /* type */ -typedef __u64 xfs_ino_t; /* type */ +typedef unsigned long long xfs_ino_t; /* type */ typedef __s64 xfs_daddr_t; /* type */ typedef char * xfs_caddr_t; /* type */ typedef __u32 xfs_dev_t; -- cgit From 958f8c0e4fc311e23a40635a530c01aec366a6e8 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Tue, 6 Jan 2009 14:40:44 +1100 Subject: [XFS] remove old vmap cache XFS's vmap batching simply defers a number (up to 64) of vunmaps, and keeps track of them in a list. To purge the batch, it just goes through the list and calls vunamp on each one. This is pretty poor: a global TLB flush is generally still performed on each vunmap, with the most expensive parts of the operation being the broadcast IPIs and locking involved in the SMP callouts, and the locking involved in the vmap management -- none of these are avoided by just batching up the calls. I'm actually surprised it ever made much difference. (Now that the lazy vmap allocator is upstream, this description is not quite right, but the vunmap batching still doesn't seem to do much) Rip all this logic out of XFS completely. I will improve vmap performance and scalability directly in subsequent patch. Signed-off-by: Nick Piggin Reviewed-by: Christoph Hellwig Signed-off-by: Lachlan McIlroy --- fs/xfs/linux-2.6/xfs_buf.c | 75 +--------------------------------------------- 1 file changed, 1 insertion(+), 74 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index cb329edc925..0b2177a9fbd 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -165,75 +165,6 @@ test_page_region( return (mask && (page_private(page) & mask) == mask); } -/* - * Mapping of multi-page buffers into contiguous virtual space - */ - -typedef struct a_list { - void *vm_addr; - struct a_list *next; -} a_list_t; - -static a_list_t *as_free_head; -static int as_list_len; -static DEFINE_SPINLOCK(as_lock); - -/* - * Try to batch vunmaps because they are costly. - */ -STATIC void -free_address( - void *addr) -{ - a_list_t *aentry; - -#ifdef CONFIG_XEN - /* - * Xen needs to be able to make sure it can get an exclusive - * RO mapping of pages it wants to turn into a pagetable. If - * a newly allocated page is also still being vmap()ed by xfs, - * it will cause pagetable construction to fail. This is a - * quick workaround to always eagerly unmap pages so that Xen - * is happy. - */ - vunmap(addr); - return; -#endif - - aentry = kmalloc(sizeof(a_list_t), GFP_NOWAIT); - if (likely(aentry)) { - spin_lock(&as_lock); - aentry->next = as_free_head; - aentry->vm_addr = addr; - as_free_head = aentry; - as_list_len++; - spin_unlock(&as_lock); - } else { - vunmap(addr); - } -} - -STATIC void -purge_addresses(void) -{ - a_list_t *aentry, *old; - - if (as_free_head == NULL) - return; - - spin_lock(&as_lock); - aentry = as_free_head; - as_free_head = NULL; - as_list_len = 0; - spin_unlock(&as_lock); - - while ((old = aentry) != NULL) { - vunmap(aentry->vm_addr); - aentry = aentry->next; - kfree(old); - } -} - /* * Internal xfs_buf_t object manipulation */ @@ -333,7 +264,7 @@ xfs_buf_free( uint i; if ((bp->b_flags & XBF_MAPPED) && (bp->b_page_count > 1)) - free_address(bp->b_addr - bp->b_offset); + vunmap(bp->b_addr - bp->b_offset); for (i = 0; i < bp->b_page_count; i++) { struct page *page = bp->b_pages[i]; @@ -455,8 +386,6 @@ _xfs_buf_map_pages( bp->b_addr = page_address(bp->b_pages[0]) + bp->b_offset; bp->b_flags |= XBF_MAPPED; } else if (flags & XBF_MAPPED) { - if (as_list_len > 64) - purge_addresses(); bp->b_addr = vmap(bp->b_pages, bp->b_page_count, VM_MAP, PAGE_KERNEL); if (unlikely(bp->b_addr == NULL)) @@ -1743,8 +1672,6 @@ xfsbufd( count++; } - if (as_list_len > 0) - purge_addresses(); if (count) blk_run_address_space(target->bt_mapping); -- cgit From 0087167c9d5b1273e7e6bbe39a9ab13bdb9a39bb Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Tue, 6 Jan 2009 14:43:09 +1100 Subject: [XFS] use scalable vmap API Implement XFS's large buffer support with the new vmap APIs. See the vmap rewrite (db64fe02) for some numbers. The biggest improvement that comes from using the new APIs is avoiding the global KVA allocation lock on every call. Signed-off-by: Nick Piggin Reviewed-by: Christoph Hellwig Signed-off-by: Lachlan McIlroy --- fs/xfs/linux-2.6/xfs_buf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 0b2177a9fbd..d71dc44e21e 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -264,7 +264,7 @@ xfs_buf_free( uint i; if ((bp->b_flags & XBF_MAPPED) && (bp->b_page_count > 1)) - vunmap(bp->b_addr - bp->b_offset); + vm_unmap_ram(bp->b_addr - bp->b_offset, bp->b_page_count); for (i = 0; i < bp->b_page_count; i++) { struct page *page = bp->b_pages[i]; @@ -386,8 +386,8 @@ _xfs_buf_map_pages( bp->b_addr = page_address(bp->b_pages[0]) + bp->b_offset; bp->b_flags |= XBF_MAPPED; } else if (flags & XBF_MAPPED) { - bp->b_addr = vmap(bp->b_pages, bp->b_page_count, - VM_MAP, PAGE_KERNEL); + bp->b_addr = vm_map_ram(bp->b_pages, bp->b_page_count, + -1, PAGE_KERNEL); if (unlikely(bp->b_addr == NULL)) return -ENOMEM; bp->b_addr += bp->b_offset; -- cgit From 0335cb76aa3fa913a2164bc9b669e5aef9d56fa3 Mon Sep 17 00:00:00 2001 From: Lachlan McIlroy Date: Wed, 31 Dec 2008 12:10:12 +1100 Subject: [XFS] Update maintainers New maintainer contact and new tree location. Reviewed-by: Bill O`Donnell Signed-off-by: Lachlan McIlroy --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index a01884407fe..5f74bce1854 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4824,11 +4824,11 @@ S: Supported XFS FILESYSTEM P: Silicon Graphics Inc -P: Tim Shimmin +P: Bill O'Donnell M: xfs-masters@oss.sgi.com L: xfs@oss.sgi.com W: http://oss.sgi.com/projects/xfs -T: git git://oss.sgi.com:8090/xfs/xfs-2.6.git +T: git://oss.sgi.com/xfs/xfs.git S: Supported XILINX SYSTEMACE DRIVER -- cgit From 23faf63123e306b4a134f6d6c501813f6c8599dc Mon Sep 17 00:00:00 2001 From: roel kluin Date: Fri, 9 Jan 2009 15:49:04 -0700 Subject: powerpc/mpc5121: fix NULL test in mpc5121_clk_get utility function. strcmp on NULL results in a segmentation fault, also, remove the second, redundant test on dev Signed-off-by: Roel Kluin Signed-off-by: Grant Likely --- arch/powerpc/platforms/512x/clock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/512x/clock.c b/arch/powerpc/platforms/512x/clock.c index f416014ee72..1bcff94eb92 100644 --- a/arch/powerpc/platforms/512x/clock.c +++ b/arch/powerpc/platforms/512x/clock.c @@ -56,12 +56,12 @@ static struct clk *mpc5121_clk_get(struct device *dev, const char *id) int dev_match = 0; int id_match = 0; - if (dev == NULL && id == NULL) + if (dev == NULL || id == NULL) return NULL; mutex_lock(&clocks_mutex); list_for_each_entry(p, &clocks, node) { - if (dev && dev == p->dev) + if (dev == p->dev) dev_match++; if (strcmp(id, p->name) == 0) id_match++; -- cgit From d30239a0ef2000cfae6c60f8e870da2d8dba4d22 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 9 Jan 2009 15:49:05 -0700 Subject: powerpc/mpc52xx: Properly update irq_desc when set_type() is called. The MPC5200 PIC driver doesn't correctly update the .status field of the irq_desc structure when the set_type hook is called. This patch adds the required code. Also cleans up the external IRQ typename field to be something easier to read (very minor). Signed-off-by: Grant Likely --- arch/powerpc/platforms/52xx/mpc52xx_pic.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c index 72865e8e4b5..0a093f03c75 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c @@ -196,6 +196,7 @@ static void mpc52xx_extirq_ack(unsigned int virq) static int mpc52xx_extirq_set_type(unsigned int virq, unsigned int flow_type) { + struct irq_desc *desc = get_irq_desc(virq); u32 ctrl_reg, type; int irq; int l2irq; @@ -222,6 +223,11 @@ static int mpc52xx_extirq_set_type(unsigned int virq, unsigned int flow_type) type = 0; } + desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); + desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; + if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) + desc->status |= IRQ_LEVEL; + ctrl_reg = in_be32(&intr->ctrl); ctrl_reg &= ~(0x3 << (22 - (l2irq * 2))); ctrl_reg |= (type << (22 - (l2irq * 2))); @@ -231,7 +237,7 @@ static int mpc52xx_extirq_set_type(unsigned int virq, unsigned int flow_type) } static struct irq_chip mpc52xx_extirq_irqchip = { - .typename = " MPC52xx IRQ[0-3] ", + .typename = "MPC52xx External", .mask = mpc52xx_extirq_mask, .unmask = mpc52xx_extirq_unmask, .ack = mpc52xx_extirq_ack, -- cgit From ddd527d56a0e635abdc7ffeb688cdde7593ad2d3 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 9 Jan 2009 15:49:05 -0700 Subject: powerpc/mpc52xx: remove dead code from GPIO driver Eliminate duplicate return statements Signed-off-by: Wolfram Sang Signed-off-by: Grant Likely --- arch/powerpc/platforms/52xx/mpc52xx_gpio.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c index 8a455ebce98..07f89ae46d0 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c @@ -363,11 +363,8 @@ static int mpc52xx_gpt_gpio_get(struct gpio_chip *gc, unsigned int gpio) { struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); struct mpc52xx_gpt __iomem *regs = mm_gc->regs; - unsigned int ret; return (in_be32(®s->status) & (1 << (31 - 23))) ? 1 : 0; - - return ret; } static void -- cgit From f5020384e4fa8ab9397aa6fa176e61e9bf7947f7 Mon Sep 17 00:00:00 2001 From: Yuri Tikhonov Date: Fri, 9 Jan 2009 15:49:06 -0700 Subject: powerpc/xsysace: add compatible string for non-ipcore instance Add "xlnx,sysace" compatible string to the of_platform binding table. Platforms which have the SysACE chip on board (e.g. Katmai) instead of via a Xilinx generated IP core will use this value in their device tree. Signed-off-by: Yuri Tikhonov Signed-off-by: Grant Likely --- drivers/block/xsysace.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index 29e1dfafb7c..381d686fc1a 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -1206,6 +1206,7 @@ static struct of_device_id ace_of_match[] __devinitdata = { { .compatible = "xlnx,opb-sysace-1.00.b", }, { .compatible = "xlnx,opb-sysace-1.00.c", }, { .compatible = "xlnx,xps-sysace-1.00.a", }, + { .compatible = "xlnx,sysace", }, {}, }; MODULE_DEVICE_TABLE(of, ace_of_match); -- cgit From 2526c151c31358aec66b63921dd712bbec5ee0cb Mon Sep 17 00:00:00 2001 From: Jon Smirl Date: Fri, 9 Jan 2009 15:49:06 -0700 Subject: drivers/of: Add the of_find_i2c_device_by_node function. The of_find_i2c_device_by_node function allows you to follow a reference in the device tree to an i2c device node and then locate the linux device instantiated by the device tree. Example use: an I2S bus driver finding the i2c_device instance for a codec described by a device tree node. This was waiting for Anton's i2c patches that were just added. Signed-off-by: Jon Smirl Signed-off-by: Grant Likely --- drivers/of/of_i2c.c | 19 +++++++++++++++++++ include/linux/of_i2c.h | 3 +++ 2 files changed, 22 insertions(+) diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index e1b0ad6e918..fa65a2b2ae2 100644 --- a/drivers/of/of_i2c.c +++ b/drivers/of/of_i2c.c @@ -66,4 +66,23 @@ void of_register_i2c_devices(struct i2c_adapter *adap, } EXPORT_SYMBOL(of_register_i2c_devices); +static int of_dev_node_match(struct device *dev, void *data) +{ + return dev_archdata_get_node(&dev->archdata) == data; +} + +/* must call put_device() when done with returned i2c_client device */ +struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) +{ + struct device *dev; + + dev = bus_find_device(&i2c_bus_type, NULL, node, + of_dev_node_match); + if (!dev) + return NULL; + + return to_i2c_client(dev); +} +EXPORT_SYMBOL(of_find_i2c_device_by_node); + MODULE_LICENSE("GPL"); diff --git a/include/linux/of_i2c.h b/include/linux/of_i2c.h index bd2a870ec29..34974b5a76f 100644 --- a/include/linux/of_i2c.h +++ b/include/linux/of_i2c.h @@ -17,4 +17,7 @@ void of_register_i2c_devices(struct i2c_adapter *adap, struct device_node *adap_node); +/* must call put_device() when done with returned i2c_client device */ +struct i2c_client *of_find_i2c_device_by_node(struct device_node *node); + #endif /* __LINUX_OF_I2C_H */ -- cgit From ff82c587a9a4cb8796e7e04377155deba15ae18b Mon Sep 17 00:00:00 2001 From: John Linn Date: Fri, 9 Jan 2009 16:01:53 -0700 Subject: Xilinx: SPI: updated driver for device tree The driver was updated to use the device tree rather than the platform data. Signed-off-by: John Linn --- drivers/spi/xilinx_spi.c | 137 ++++++++++++++++++++++++++++------------------- 1 file changed, 81 insertions(+), 56 deletions(-) diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c index 68d6f4988fb..fe7e5f35e5d 100644 --- a/drivers/spi/xilinx_spi.c +++ b/drivers/spi/xilinx_spi.c @@ -15,12 +15,15 @@ #include #include #include + +#include +#include +#include + #include #include #include -#include - #define XILINX_SPI_NAME "xilinx_spi" /* Register definitions as per "OPB Serial Peripheral Interface (SPI) (v1.00e) @@ -144,23 +147,14 @@ static int xilinx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) { u8 bits_per_word; - u32 hz; - struct xilinx_spi *xspi = spi_master_get_devdata(spi->master); bits_per_word = (t) ? t->bits_per_word : spi->bits_per_word; - hz = (t) ? t->speed_hz : spi->max_speed_hz; if (bits_per_word != 8) { dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n", __func__, bits_per_word); return -EINVAL; } - if (hz && xspi->speed_hz > hz) { - dev_err(&spi->dev, "%s, unsupported clock rate %uHz\n", - __func__, hz); - return -EINVAL; - } - return 0; } @@ -304,32 +298,38 @@ static irqreturn_t xilinx_spi_irq(int irq, void *dev_id) return IRQ_HANDLED; } -static int __init xilinx_spi_probe(struct platform_device *dev) +static int __init xilinx_spi_of_probe(struct of_device *ofdev, + const struct of_device_id *match) { - int ret = 0; struct spi_master *master; struct xilinx_spi *xspi; - struct xspi_platform_data *pdata; - struct resource *r; + struct resource r_irq_struct; + struct resource r_mem_struct; + + struct resource *r_irq = &r_irq_struct; + struct resource *r_mem = &r_mem_struct; + int rc = 0; + const u32 *prop; + int len; /* Get resources(memory, IRQ) associated with the device */ - master = spi_alloc_master(&dev->dev, sizeof(struct xilinx_spi)); + master = spi_alloc_master(&ofdev->dev, sizeof(struct xilinx_spi)); if (master == NULL) { return -ENOMEM; } - platform_set_drvdata(dev, master); - pdata = dev->dev.platform_data; + dev_set_drvdata(&ofdev->dev, master); - if (pdata == NULL) { - ret = -ENODEV; + rc = of_address_to_resource(ofdev->node, 0, r_mem); + if (rc) { + dev_warn(&ofdev->dev, "invalid address\n"); goto put_master; } - r = platform_get_resource(dev, IORESOURCE_MEM, 0); - if (r == NULL) { - ret = -ENODEV; + rc = of_irq_to_resource(ofdev->node, 0, r_irq); + if (rc == NO_IRQ) { + dev_warn(&ofdev->dev, "no IRQ found\n"); goto put_master; } @@ -341,47 +341,57 @@ static int __init xilinx_spi_probe(struct platform_device *dev) xspi->bitbang.master->setup = xilinx_spi_setup; init_completion(&xspi->done); - if (!request_mem_region(r->start, - r->end - r->start + 1, XILINX_SPI_NAME)) { - ret = -ENXIO; + xspi->irq = r_irq->start; + + if (!request_mem_region(r_mem->start, + r_mem->end - r_mem->start + 1, XILINX_SPI_NAME)) { + rc = -ENXIO; + dev_warn(&ofdev->dev, "memory request failure\n"); goto put_master; } - xspi->regs = ioremap(r->start, r->end - r->start + 1); + xspi->regs = ioremap(r_mem->start, r_mem->end - r_mem->start + 1); if (xspi->regs == NULL) { - ret = -ENOMEM; + rc = -ENOMEM; + dev_warn(&ofdev->dev, "ioremap failure\n"); goto put_master; } + xspi->irq = r_irq->start; - ret = platform_get_irq(dev, 0); - if (ret < 0) { - ret = -ENXIO; - goto unmap_io; - } - xspi->irq = ret; + /* dynamic bus assignment */ + master->bus_num = -1; - master->bus_num = pdata->bus_num; - master->num_chipselect = pdata->num_chipselect; - xspi->speed_hz = pdata->speed_hz; + /* number of slave select bits is required */ + prop = of_get_property(ofdev->node, "xlnx,num-ss-bits", &len); + if (!prop || len < sizeof(*prop)) { + dev_warn(&ofdev->dev, "no 'xlnx,num-ss-bits' property\n"); + goto put_master; + } + master->num_chipselect = *prop; /* SPI controller initializations */ xspi_init_hw(xspi->regs); /* Register for SPI Interrupt */ - ret = request_irq(xspi->irq, xilinx_spi_irq, 0, XILINX_SPI_NAME, xspi); - if (ret != 0) + rc = request_irq(xspi->irq, xilinx_spi_irq, 0, XILINX_SPI_NAME, xspi); + if (rc != 0) { + dev_warn(&ofdev->dev, "irq request failure: %d\n", xspi->irq); goto unmap_io; + } - ret = spi_bitbang_start(&xspi->bitbang); - if (ret != 0) { - dev_err(&dev->dev, "spi_bitbang_start FAILED\n"); + rc = spi_bitbang_start(&xspi->bitbang); + if (rc != 0) { + dev_err(&ofdev->dev, "spi_bitbang_start FAILED\n"); goto free_irq; } - dev_info(&dev->dev, "at 0x%08X mapped to 0x%08X, irq=%d\n", - r->start, (u32)xspi->regs, xspi->irq); + dev_info(&ofdev->dev, "at 0x%08X mapped to 0x%08X, irq=%d\n", + (unsigned int)r_mem->start, (u32)xspi->regs, xspi->irq); - return ret; + /* Add any subnodes on the SPI bus */ + of_register_spi_devices(master, ofdev->node); + + return rc; free_irq: free_irq(xspi->irq, xspi); @@ -389,21 +399,21 @@ unmap_io: iounmap(xspi->regs); put_master: spi_master_put(master); - return ret; + return rc; } -static int __devexit xilinx_spi_remove(struct platform_device *dev) +static int __devexit xilinx_spi_remove(struct of_device *ofdev) { struct xilinx_spi *xspi; struct spi_master *master; - master = platform_get_drvdata(dev); + master = platform_get_drvdata(ofdev); xspi = spi_master_get_devdata(master); spi_bitbang_stop(&xspi->bitbang); free_irq(xspi->irq, xspi); iounmap(xspi->regs); - platform_set_drvdata(dev, 0); + dev_set_drvdata(&ofdev->dev, 0); spi_master_put(xspi->bitbang.master); return 0; @@ -412,27 +422,42 @@ static int __devexit xilinx_spi_remove(struct platform_device *dev) /* work with hotplug and coldplug */ MODULE_ALIAS("platform:" XILINX_SPI_NAME); -static struct platform_driver xilinx_spi_driver = { - .probe = xilinx_spi_probe, - .remove = __devexit_p(xilinx_spi_remove), +static int __exit xilinx_spi_of_remove(struct of_device *op) +{ + return xilinx_spi_remove(op); +} + +static struct of_device_id xilinx_spi_of_match[] = { + { .compatible = "xlnx,xps-spi-2.00.a", }, + { .compatible = "xlnx,xps-spi-2.00.b", }, + {} +}; + +MODULE_DEVICE_TABLE(of, xilinx_spi_of_match); + +static struct of_platform_driver xilinx_spi_of_driver = { + .owner = THIS_MODULE, + .name = "xilinx-xps-spi", + .match_table = xilinx_spi_of_match, + .probe = xilinx_spi_of_probe, + .remove = __exit_p(xilinx_spi_of_remove), .driver = { - .name = XILINX_SPI_NAME, + .name = "xilinx-xps-spi", .owner = THIS_MODULE, }, }; static int __init xilinx_spi_init(void) { - return platform_driver_register(&xilinx_spi_driver); + return of_register_platform_driver(&xilinx_spi_of_driver); } module_init(xilinx_spi_init); static void __exit xilinx_spi_exit(void) { - platform_driver_unregister(&xilinx_spi_driver); + of_unregister_platform_driver(&xilinx_spi_of_driver); } module_exit(xilinx_spi_exit); - MODULE_AUTHOR("MontaVista Software, Inc. "); MODULE_DESCRIPTION("Xilinx SPI driver"); MODULE_LICENSE("GPL"); -- cgit From 736f93236ce786d1bcf09ad4dcb38a360d35ea1b Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sat, 10 Jan 2009 12:06:19 +0100 Subject: bzip2/lzma: make flush_buffer() unconditional Impact: build fix flush_buffer() is used unconditionally: init/initramfs.c:456: error: 'flush_buffer' undeclared (first use in this function) init/initramfs.c:456: error: (Each undeclared identifier is reported only once init/initramfs.c:456: error: for each function it appears in.) So remove the decompressor #ifdefs from around it. Signed-off-by: Ingo Molnar --- init/initramfs.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/init/initramfs.c b/init/initramfs.c index f8241e832aa..76f4a012533 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -390,7 +390,6 @@ static int __init write_buffer(char *buf, unsigned len) return len - count; } -#if defined CONFIG_RD_GZIP || defined CONFIG_RD_BZIP2 || defined CONFIG_RD_LZMA static int __init flush_buffer(void *bufv, unsigned len) { char *buf = (char *) bufv; @@ -413,7 +412,6 @@ static int __init flush_buffer(void *bufv, unsigned len) } return origLen; } -#endif static unsigned my_inptr; /* index of next byte to be processed in inbuf */ -- cgit From 068790334cececc3d2d945617ccc585477da2e38 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Sat, 10 Jan 2009 12:17:37 +0530 Subject: x86: smp.h move cpu_callin_mask and cpu_callin_map declartion to cpumask.h Impact: cleanup Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/include/asm/cpumask.h | 19 +++++++++++++++++++ arch/x86/include/asm/smp.h | 3 --- arch/x86/kernel/cpu/common.c | 1 + arch/x86/kernel/setup_percpu.c | 1 + arch/x86/kernel/smpboot.c | 1 + 5 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 arch/x86/include/asm/cpumask.h diff --git a/arch/x86/include/asm/cpumask.h b/arch/x86/include/asm/cpumask.h new file mode 100644 index 00000000000..308dddd5632 --- /dev/null +++ b/arch/x86/include/asm/cpumask.h @@ -0,0 +1,19 @@ +#ifndef _ASM_X86_CPUMASK_H +#define _ASM_X86_CPUMASK_H +#ifndef __ASSEMBLY__ +#include + +#ifdef CONFIG_X86_64 + +extern cpumask_var_t cpu_callin_mask; + +#else /* CONFIG_X86_32 */ + +extern cpumask_t cpu_callin_map; + +#define cpu_callin_mask ((struct cpumask *)&cpu_callin_map) + +#endif /* CONFIG_X86_32 */ + +#endif /* __ASSEMBLY__ */ +#endif /* _ASM_X86_CPUMASK_H */ diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index 1963e27673c..c35aa5c0dd1 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -20,19 +20,16 @@ #ifdef CONFIG_X86_64 -extern cpumask_var_t cpu_callin_mask; extern cpumask_var_t cpu_callout_mask; extern cpumask_var_t cpu_initialized_mask; extern cpumask_var_t cpu_sibling_setup_mask; #else /* CONFIG_X86_32 */ -extern cpumask_t cpu_callin_map; extern cpumask_t cpu_callout_map; extern cpumask_t cpu_initialized; extern cpumask_t cpu_sibling_setup_map; -#define cpu_callin_mask ((struct cpumask *)&cpu_callin_map) #define cpu_callout_mask ((struct cpumask *)&cpu_callout_map) #define cpu_initialized_mask ((struct cpumask *)&cpu_initialized) #define cpu_sibling_setup_mask ((struct cpumask *)&cpu_sibling_setup_map) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 14e543b6fd4..f0025846244 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -22,6 +22,7 @@ #include #include #include +#include #ifdef CONFIG_X86_LOCAL_APIC #include #include diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 55c46074eba..bf63de72b64 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -13,6 +13,7 @@ #include #include #include +#include #ifdef CONFIG_X86_LOCAL_APIC unsigned int num_processors; diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 6c2b8444b83..84ac1cf46d8 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include -- cgit From fb8fd077fbf0de6662acfd240e8e6b25cf3202ca Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Sat, 10 Jan 2009 12:20:24 +0530 Subject: x86: smp.h move cpu_callout_mask and cpu_callout_map declartion to cpumask.h Impact: cleanup Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/include/asm/cpumask.h | 3 +++ arch/x86/include/asm/smp.h | 4 +--- arch/x86/kernel/smpboot.c | 1 - 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/cpumask.h b/arch/x86/include/asm/cpumask.h index 308dddd5632..9933fcad3c8 100644 --- a/arch/x86/include/asm/cpumask.h +++ b/arch/x86/include/asm/cpumask.h @@ -6,12 +6,15 @@ #ifdef CONFIG_X86_64 extern cpumask_var_t cpu_callin_mask; +extern cpumask_var_t cpu_callout_mask; #else /* CONFIG_X86_32 */ extern cpumask_t cpu_callin_map; +extern cpumask_t cpu_callout_map; #define cpu_callin_mask ((struct cpumask *)&cpu_callin_map) +#define cpu_callout_mask ((struct cpumask *)&cpu_callout_map) #endif /* CONFIG_X86_32 */ diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index c35aa5c0dd1..a3afec5cad0 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -17,20 +17,18 @@ #endif #include #include +#include #ifdef CONFIG_X86_64 -extern cpumask_var_t cpu_callout_mask; extern cpumask_var_t cpu_initialized_mask; extern cpumask_var_t cpu_sibling_setup_mask; #else /* CONFIG_X86_32 */ -extern cpumask_t cpu_callout_map; extern cpumask_t cpu_initialized; extern cpumask_t cpu_sibling_setup_map; -#define cpu_callout_mask ((struct cpumask *)&cpu_callout_map) #define cpu_initialized_mask ((struct cpumask *)&cpu_initialized) #define cpu_sibling_setup_mask ((struct cpumask *)&cpu_sibling_setup_map) diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 84ac1cf46d8..6c2b8444b83 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -55,7 +55,6 @@ #include #include #include -#include #include #include #include -- cgit From 493f6ca54e1ea59732dd334e35c5fe2d8e440b06 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Sat, 10 Jan 2009 12:48:22 +0530 Subject: x86: smp.h move cpu_initialized_mask and cpu_initialized declartion to cpumask.h Impact: cleanup Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/include/asm/cpumask.h | 3 +++ arch/x86/include/asm/smp.h | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/asm/cpumask.h b/arch/x86/include/asm/cpumask.h index 9933fcad3c8..d4cfd120b84 100644 --- a/arch/x86/include/asm/cpumask.h +++ b/arch/x86/include/asm/cpumask.h @@ -7,14 +7,17 @@ extern cpumask_var_t cpu_callin_mask; extern cpumask_var_t cpu_callout_mask; +extern cpumask_var_t cpu_initialized_mask; #else /* CONFIG_X86_32 */ extern cpumask_t cpu_callin_map; extern cpumask_t cpu_callout_map; +extern cpumask_t cpu_initialized; #define cpu_callin_mask ((struct cpumask *)&cpu_callin_map) #define cpu_callout_mask ((struct cpumask *)&cpu_callout_map) +#define cpu_initialized_mask ((struct cpumask *)&cpu_initialized) #endif /* CONFIG_X86_32 */ diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index a3afec5cad0..7d2a80319e8 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -21,15 +21,12 @@ #ifdef CONFIG_X86_64 -extern cpumask_var_t cpu_initialized_mask; extern cpumask_var_t cpu_sibling_setup_mask; #else /* CONFIG_X86_32 */ -extern cpumask_t cpu_initialized; extern cpumask_t cpu_sibling_setup_map; -#define cpu_initialized_mask ((struct cpumask *)&cpu_initialized) #define cpu_sibling_setup_mask ((struct cpumask *)&cpu_sibling_setup_map) #endif /* CONFIG_X86_32 */ -- cgit From 52811d8c9beb67da6bc4b770de3c4134376788a1 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Sat, 10 Jan 2009 12:58:50 +0530 Subject: x86: smp.h move cpu_sibling_setup_mask and cpu_sibling_setup_map declartion to cpumask.h Impact: cleanup Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/include/asm/cpumask.h | 3 +++ arch/x86/include/asm/smp.h | 12 ------------ 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/arch/x86/include/asm/cpumask.h b/arch/x86/include/asm/cpumask.h index d4cfd120b84..26c6dad9047 100644 --- a/arch/x86/include/asm/cpumask.h +++ b/arch/x86/include/asm/cpumask.h @@ -8,16 +8,19 @@ extern cpumask_var_t cpu_callin_mask; extern cpumask_var_t cpu_callout_mask; extern cpumask_var_t cpu_initialized_mask; +extern cpumask_var_t cpu_sibling_setup_mask; #else /* CONFIG_X86_32 */ extern cpumask_t cpu_callin_map; extern cpumask_t cpu_callout_map; extern cpumask_t cpu_initialized; +extern cpumask_t cpu_sibling_setup_map; #define cpu_callin_mask ((struct cpumask *)&cpu_callin_map) #define cpu_callout_mask ((struct cpumask *)&cpu_callout_map) #define cpu_initialized_mask ((struct cpumask *)&cpu_initialized) +#define cpu_sibling_setup_mask ((struct cpumask *)&cpu_sibling_setup_map) #endif /* CONFIG_X86_32 */ diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index 7d2a80319e8..a8cea7b0943 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -19,18 +19,6 @@ #include #include -#ifdef CONFIG_X86_64 - -extern cpumask_var_t cpu_sibling_setup_mask; - -#else /* CONFIG_X86_32 */ - -extern cpumask_t cpu_sibling_setup_map; - -#define cpu_sibling_setup_mask ((struct cpumask *)&cpu_sibling_setup_map) - -#endif /* CONFIG_X86_32 */ - extern int __cpuinit get_local_pda(int cpu); extern int smp_num_siblings; -- cgit From 71e0ffa599f54058d9b8724b4b14d0486751681d Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 8 Jan 2009 10:42:15 -0800 Subject: drm/i915: don't enable vblanks on disabled pipes In some cases userland may be confused and try to wait on vblank events from pipes that aren't actually enabled. We shouldn't allow this, so return -EINVAL if the pipe isn't on. Signed-off-by: Jesse Barnes Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/i915_irq.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 0cadafbef41..6290219de6c 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -411,6 +411,12 @@ int i915_enable_vblank(struct drm_device *dev, int pipe) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; unsigned long irqflags; + int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; + u32 pipeconf; + + pipeconf = I915_READ(pipeconf_reg); + if (!(pipeconf & PIPEACONF_ENABLE)) + return -EINVAL; spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); if (IS_I965G(dev)) -- cgit From dc1336ff4fe08ae7cfe8301bfd7f0b2cfd31d20a Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 6 Jan 2009 10:21:24 -0800 Subject: drm/i915: set vblank enabled flag correctly across IRQ install/uninstall In the absence of kernel mode setting, many drivers disable IRQs across VT switch. The core DRM vblank code is missing a check for this case however; even after IRQ disable, the vblank code will still have the vblank_enabled flag set, so unless we track the fact that they're disabled at IRQ uninstall time, when we VT switch back in we won't actually re-enable them, which means any apps waiting on vblank before the switch will hang. This patch does that and also adds a sanity check to the wait condition to look for the irq_enabled flag in general, as well as adding a wakeup to the IRQ uninstall path. Fixes fdo bug #18879 with compiz hangs at VT switch. Signed-off-by: Jesse Barnes Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_irq.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 724e505873c..477caa1b1e4 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -267,7 +267,8 @@ EXPORT_SYMBOL(drm_irq_install); */ int drm_irq_uninstall(struct drm_device * dev) { - int irq_enabled; + unsigned long irqflags; + int irq_enabled, i; if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) return -EINVAL; @@ -277,6 +278,16 @@ int drm_irq_uninstall(struct drm_device * dev) dev->irq_enabled = 0; mutex_unlock(&dev->struct_mutex); + /* + * Wake up any waiters so they don't hang. + */ + spin_lock_irqsave(&dev->vbl_lock, irqflags); + for (i = 0; i < dev->num_crtcs; i++) { + DRM_WAKEUP(&dev->vbl_queue[i]); + dev->vblank_enabled[i] = 0; + } + spin_unlock_irqrestore(&dev->vbl_lock, irqflags); + if (!irq_enabled) return -EINVAL; @@ -652,8 +663,9 @@ int drm_wait_vblank(struct drm_device *dev, void *data, vblwait->request.sequence, crtc); dev->last_vblank_wait[crtc] = vblwait->request.sequence; DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ, - ((drm_vblank_count(dev, crtc) - - vblwait->request.sequence) <= (1 << 23))); + (((drm_vblank_count(dev, crtc) - + vblwait->request.sequence) <= (1 << 23)) || + !dev->irq_enabled)); if (ret != -EINTR) { struct timeval now; -- cgit From 7106a5ab89c50c6b5aadea0850b40323804a922d Mon Sep 17 00:00:00 2001 From: Benjamin LaHaise Date: Sat, 10 Jan 2009 23:00:22 -0500 Subject: x86-64: remove locked instruction from switch_to() Impact: micro-optimization The patch below removes an unnecessary locked instruction from switch_to(). TIF_FORK is only ever set in copy_thread() on initial process creation, and gets cleared during the first scheduling of the process. As such, it is safe to use an unlocked test for the flag within switch_to(). Signed-off-by: Benjamin LaHaise Signed-off-by: Ingo Molnar --- arch/x86/include/asm/system.h | 6 +++--- arch/x86/kernel/entry_64.S | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h index 8e626ea33a1..fa47b1e6a86 100644 --- a/arch/x86/include/asm/system.h +++ b/arch/x86/include/asm/system.h @@ -96,15 +96,15 @@ do { \ "thread_return:\n\t" \ "movq %%gs:%P[pda_pcurrent],%%rsi\n\t" \ "movq %P[thread_info](%%rsi),%%r8\n\t" \ - LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \ "movq %%rax,%%rdi\n\t" \ - "jc ret_from_fork\n\t" \ + "testl %[_tif_fork],%P[ti_flags](%%r8)\n\t" \ + "jnz ret_from_fork\n\t" \ RESTORE_CONTEXT \ : "=a" (last) \ : [next] "S" (next), [prev] "D" (prev), \ [threadrsp] "i" (offsetof(struct task_struct, thread.sp)), \ [ti_flags] "i" (offsetof(struct thread_info, flags)), \ - [tif_fork] "i" (TIF_FORK), \ + [_tif_fork] "i" (_TIF_FORK), \ [thread_info] "i" (offsetof(struct task_struct, stack)), \ [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \ : "memory", "cc" __EXTRA_CLOBBER) diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index e28c7a98779..38dd37458e4 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -408,6 +408,8 @@ END(save_paranoid) ENTRY(ret_from_fork) DEFAULT_FRAME + LOCK ; btr $TIF_FORK,TI_flags(%r8) + push kernel_eflags(%rip) CFI_ADJUST_CFA_OFFSET 8 popf # reset kernel eflags -- cgit From c9cbf3d3b35f198fab39e98d696312dd0b97a69a Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Sat, 10 Jan 2009 23:44:22 -0800 Subject: Input: usbtouchscreen - allow reporting calibrated data This patch adds a module parameter to report either the raw coordinate data or the hardware-calibrated coordinate data for MicroTouch/3M touchscreens. The default is set to the raw coordinates for backwards compatibilty. Signed-off-by: Dan Streetman Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/usbtouchscreen.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 5080b26ba16..6d27a1d661e 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -60,6 +60,10 @@ static int swap_xy; module_param(swap_xy, bool, 0644); MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped."); +static int hwcalib_xy; +module_param(hwcalib_xy, bool, 0644); +MODULE_PARM_DESC(hwcalib_xy, "If set hw-calibrated X/Y are used if available"); + /* device specifc data/functions */ struct usbtouch_usb; struct usbtouch_device_info { @@ -260,8 +264,13 @@ static int panjit_read_data(struct usbtouch_usb *dev, unsigned char *pkt) static int mtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) { - dev->x = (pkt[8] << 8) | pkt[7]; - dev->y = (pkt[10] << 8) | pkt[9]; + if (hwcalib_xy) { + dev->x = (pkt[4] << 8) | pkt[3]; + dev->y = 0xffff - ((pkt[6] << 8) | pkt[5]); + } else { + dev->x = (pkt[8] << 8) | pkt[7]; + dev->y = (pkt[10] << 8) | pkt[9]; + } dev->touch = (pkt[2] & 0x40) ? 1 : 0; return 1; @@ -294,6 +303,12 @@ static int mtouch_init(struct usbtouch_usb *usbtouch) return ret; } + /* Default min/max xy are the raw values, override if using hw-calib */ + if (hwcalib_xy) { + input_set_abs_params(usbtouch->input, ABS_X, 0, 0xffff, 0, 0); + input_set_abs_params(usbtouch->input, ABS_Y, 0, 0xffff, 0, 0); + } + return 0; } #endif -- cgit From 520abcdeb13de23e22b7d4367b1c3b136ef3b108 Mon Sep 17 00:00:00 2001 From: Daniel Mierswa Date: Sat, 10 Jan 2009 23:44:22 -0800 Subject: Input: atkbd - make forced_release_keys[] static Signed-off-by: Andrew Morton Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/atkbd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index f6e9f39a527..6df9ba18612 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -839,7 +839,7 @@ static void atkbd_disconnect(struct serio *serio) */ static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd) { - const unsigned int forced_release_keys[] = { + static const unsigned int forced_release_keys[] = { 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93, }; int i; @@ -856,7 +856,7 @@ static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd) */ static void atkbd_hp_keymap_fixup(struct atkbd *atkbd) { - const unsigned int forced_release_keys[] = { + static const unsigned int forced_release_keys[] = { 0x94, }; int i; -- cgit From 3c0340b774916caa4149892504169d290c8a720a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 10 Jan 2009 23:44:22 -0800 Subject: Input: psmouse - make MOUSE_PS2_LIFEBOOK depend on X86 All Fujitsu-Siemens Lifebook systems are x86-based, so we might as well make MOUSE_PS2_LIFEBOOK depend on X86. This will avoid surprising things like: arch/arm/configs/s3c2410_defconfig:CONFIG_MOUSE_PS2_LIFEBOOK=y Signed-off-by: Jean Delvare Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index 093c8c1bca7..9705f3a00a3 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig @@ -70,7 +70,7 @@ config MOUSE_PS2_SYNAPTICS config MOUSE_PS2_LIFEBOOK bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EMBEDDED default y - depends on MOUSE_PS2 + depends on MOUSE_PS2 && X86 help Say Y here if you have a Fujitsu B-series Lifebook PS/2 TouchScreen connected to your system. -- cgit From 74ca11c2056d01d9ebb3615cd781a148450c3c82 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Sat, 10 Jan 2009 23:44:22 -0800 Subject: Input: uvc - the button on the camera is KEY_CAMERA Cameras should generate KEY_CAMERA, not BTN_0. Also call input_sync() on the device once the button has been pressed. Signed-off-by: Andrew Morton Signed-off-by: Dmitry Torokhov --- drivers/media/video/uvc/uvc_status.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/media/video/uvc/uvc_status.c b/drivers/media/video/uvc/uvc_status.c index 5d60b264d59..fdf7b4187ee 100644 --- a/drivers/media/video/uvc/uvc_status.c +++ b/drivers/media/video/uvc/uvc_status.c @@ -47,8 +47,8 @@ static int uvc_input_init(struct uvc_device *dev) usb_to_input_id(udev, &input->id); input->dev.parent = &dev->intf->dev; - set_bit(EV_KEY, input->evbit); - set_bit(BTN_0, input->keybit); + __set_bit(EV_KEY, input->evbit); + __set_bit(KEY_CAMERA, input->keybit); if ((ret = input_register_device(input)) < 0) goto error; @@ -71,8 +71,10 @@ static void uvc_input_cleanup(struct uvc_device *dev) static void uvc_input_report_key(struct uvc_device *dev, unsigned int code, int value) { - if (dev->input) + if (dev->input) { input_report_key(dev->input, code, value); + input_sync(dev->input); + } } #else @@ -97,7 +99,7 @@ static void uvc_event_streaming(struct uvc_device *dev, __u8 *data, int len) return; uvc_trace(UVC_TRACE_STATUS, "Button (intf %u) %s len %d\n", data[1], data[3] ? "pressed" : "released", len); - uvc_input_report_key(dev, BTN_0, data[3]); + uvc_input_report_key(dev, KEY_CAMERA, data[3]); } else { uvc_trace(UVC_TRACE_STATUS, "Stream %u error event %02x %02x " "len %d.\n", data[1], data[2], data[3], len); -- cgit From 57c1a24ee276a33190008243f986419e122c0dea Mon Sep 17 00:00:00 2001 From: Alexey Korolev Date: Tue, 6 Jan 2009 17:36:09 +0000 Subject: [MTD] [LPDDR] qinfo_probe depends on lpddr Signed-off-by: Alexey Korolev Signed-off-by: David Woodhouse --- drivers/mtd/lpddr/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/lpddr/Kconfig b/drivers/mtd/lpddr/Kconfig index acd4ea9b227..5a401d8047a 100644 --- a/drivers/mtd/lpddr/Kconfig +++ b/drivers/mtd/lpddr/Kconfig @@ -12,6 +12,7 @@ config MTD_LPDDR DDR memories, intended for battery-operated systems. config MTD_QINFO_PROBE + depends on MTD_LPDDR tristate "Detect flash chips by QINFO probe" help Device Information for LPDDR chips is offered through the Overlay -- cgit From 783adf42cf039083dd3c734c07c3bdc707e2bb15 Mon Sep 17 00:00:00 2001 From: Steven Noonan Date: Sun, 11 Jan 2009 01:04:21 -0800 Subject: kernel/fork.c: unused variable 'ret' Removed the unused variable. Signed-off-by: Steven Noonan Signed-off-by: Ingo Molnar --- kernel/fork.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/fork.c b/kernel/fork.c index e995899ea83..81da4aae85c 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -817,7 +817,6 @@ static void posix_cpu_timers_init_group(struct signal_struct *sig) static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) { struct signal_struct *sig; - int ret; if (clone_flags & CLONE_THREAD) { atomic_inc(¤t->signal->count); -- cgit From 5f877607cdfe8b60bf96fb96e527e0ce2a21e68b Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 11 Jan 2009 19:52:19 +0000 Subject: [MTD] map_rom has NULL erase pointer Which means if inftl or similar are loaded with it (which is a dumb thing to do admittedly) it may oops. Closes #8108 [dwmw2: change error to -EROFS to match write-protected flash] Signed-off-by: Alan Cox Signed-off-by: David Woodhouse --- drivers/mtd/chips/map_rom.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/mtd/chips/map_rom.c b/drivers/mtd/chips/map_rom.c index 821d0ed6bae..c76d6e5f47e 100644 --- a/drivers/mtd/chips/map_rom.c +++ b/drivers/mtd/chips/map_rom.c @@ -19,6 +19,7 @@ static int maprom_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *); static void maprom_nop (struct mtd_info *); static struct mtd_info *map_rom_probe(struct map_info *map); +static int maprom_erase (struct mtd_info *mtd, struct erase_info *info); static struct mtd_chip_driver maprom_chipdrv = { .probe = map_rom_probe, @@ -42,6 +43,7 @@ static struct mtd_info *map_rom_probe(struct map_info *map) mtd->read = maprom_read; mtd->write = maprom_write; mtd->sync = maprom_nop; + mtd->erase = maprom_erase; mtd->flags = MTD_CAP_ROM; mtd->erasesize = map->size; mtd->writesize = 1; @@ -71,6 +73,12 @@ static int maprom_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *re return -EIO; } +static int maprom_erase (struct mtd_info *mtd, struct erase_info *info) +{ + /* We do our best 8) */ + return -EROFS; +} + static int __init map_rom_init(void) { register_mtd_chip_driver(&maprom_chipdrv); -- cgit From c225aa57ff4ffe715df4692676b77c815a337236 Mon Sep 17 00:00:00 2001 From: Simon Holm Thøgersen Date: Sun, 11 Jan 2009 22:34:01 -0500 Subject: ext4: fix wrong use of do_div MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the following warning: fs/jbd2/journal.c: In function ‘jbd2_seq_info_show’: fs/jbd2/journal.c:850: warning: format ‘%lu’ expects type ‘long unsigned int’, but argument 3 has type ‘uint32_t’ is caused by wrong usage of do_div that modifies the dividend in-place and returns the quotient. So not only would an incorrect value be displayed, but s->journal->j_average_commit_time would also be changed to a wrong value! Fix it by using div_u64 instead. Signed-off-by: Simon Holm Thøgersen Signed-off-by: "Theodore Ts'o" --- fs/jbd2/journal.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 56675306ed8..eb343008ede 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -37,10 +37,10 @@ #include #include #include +#include #include #include -#include EXPORT_SYMBOL(jbd2_journal_start); EXPORT_SYMBOL(jbd2_journal_restart); @@ -846,8 +846,8 @@ static int jbd2_seq_info_show(struct seq_file *seq, void *v) jiffies_to_msecs(s->stats->u.run.rs_flushing / s->stats->ts_tid)); seq_printf(seq, " %ums logging transaction\n", jiffies_to_msecs(s->stats->u.run.rs_logging / s->stats->ts_tid)); - seq_printf(seq, " %luus average transaction commit time\n", - do_div(s->journal->j_average_commit_time, 1000)); + seq_printf(seq, " %lluus average transaction commit time\n", + div_u64(s->journal->j_average_commit_time, 1000)); seq_printf(seq, " %lu handles per transaction\n", s->stats->u.run.rs_handle_count / s->stats->ts_tid); seq_printf(seq, " %lu blocks per transaction\n", -- cgit From dd3feda7748b4c2739de47daaaa387fb01926c15 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Mon, 12 Jan 2009 14:44:29 +0530 Subject: x86: microcode_intel.c fix style problems Impact: cleanup Fix: WARNING: Use #include instead of ERROR: trailing whitespace ERROR: "(foo*)" should be "(foo *)" total: 3 errors, 1 warnings Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/kernel/microcode_intel.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c index b7f4c929e61..5e9f4fc5138 100644 --- a/arch/x86/kernel/microcode_intel.c +++ b/arch/x86/kernel/microcode_intel.c @@ -87,9 +87,9 @@ #include #include #include +#include #include -#include #include #include @@ -196,7 +196,7 @@ static inline int update_match_cpu(struct cpu_signature *csig, int sig, int pf) return (!sigmatch(sig, csig->sig, pf, csig->pf)) ? 0 : 1; } -static inline int +static inline int update_match_revision(struct microcode_header_intel *mc_header, int rev) { return (mc_header->rev <= rev) ? 0 : 1; @@ -442,8 +442,8 @@ static int request_microcode_fw(int cpu, struct device *device) return ret; } - ret = generic_load_microcode(cpu, (void*)firmware->data, firmware->size, - &get_ucode_fw); + ret = generic_load_microcode(cpu, (void *)firmware->data, + firmware->size, &get_ucode_fw); release_firmware(firmware); @@ -460,7 +460,7 @@ static int request_microcode_user(int cpu, const void __user *buf, size_t size) /* We should bind the task to the CPU */ BUG_ON(cpu != raw_smp_processor_id()); - return generic_load_microcode(cpu, (void*)buf, size, &get_ucode_user); + return generic_load_microcode(cpu, (void *)buf, size, &get_ucode_user); } static void microcode_fini_cpu(int cpu) -- cgit From 448dd2fa3ec915ad4325868ef8bb9b9490d9f6a9 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Mon, 12 Jan 2009 14:45:14 +0530 Subject: x86: msr.c fix style problems Impact: cleanup Fix: WARNING: Use #include instead of total: 0 errors, 1 warnings Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/kernel/msr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index 726266695b2..3cf3413ec62 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c @@ -35,10 +35,10 @@ #include #include #include +#include #include #include -#include #include static struct class *msr_class; -- cgit From e17029ad69c7b1518413c00f793d89bb77b8527b Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Mon, 12 Jan 2009 14:46:03 +0530 Subject: x86: module_32.c fix style problems Impact: cleanup Fix: ERROR: code indent should use tabs where possible ERROR: trailing whitespace ERROR: spaces required around that '=' (ctx:VxW) total: 3 errors, 0 warnings Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/kernel/module_32.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/module_32.c b/arch/x86/kernel/module_32.c index 3db0a5442eb..0edd819050e 100644 --- a/arch/x86/kernel/module_32.c +++ b/arch/x86/kernel/module_32.c @@ -42,7 +42,7 @@ void module_free(struct module *mod, void *module_region) { vfree(module_region); /* FIXME: If module_region == mod->init_region, trim exception - table entries. */ + table entries. */ } /* We don't need anything special. */ @@ -113,13 +113,13 @@ int module_finalize(const Elf_Ehdr *hdr, *para = NULL; char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; - for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) { + for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) { if (!strcmp(".text", secstrings + s->sh_name)) text = s; if (!strcmp(".altinstructions", secstrings + s->sh_name)) alt = s; if (!strcmp(".smp_locks", secstrings + s->sh_name)) - locks= s; + locks = s; if (!strcmp(".parainstructions", secstrings + s->sh_name)) para = s; } -- cgit From 3b9dc9f2f123286aaade54c45fef6723d587c664 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Mon, 12 Jan 2009 14:46:48 +0530 Subject: x86: module_64.c fix style problems Impact: cleanup Fix: ERROR: trailing whitespace ERROR: code indent should use tabs where possible WARNING: %Ld/%Lu are not-standard C, use %lld/%llu WARNING: printk() should include KERN_ facility level ERROR: spaces required around that '=' (ctx:VxW) total: 13 errors, 2 warnings Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/kernel/module_64.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/arch/x86/kernel/module_64.c b/arch/x86/kernel/module_64.c index 6ba87830d4b..c23880b90b5 100644 --- a/arch/x86/kernel/module_64.c +++ b/arch/x86/kernel/module_64.c @@ -30,14 +30,14 @@ #include #include -#define DEBUGP(fmt...) +#define DEBUGP(fmt...) #ifndef CONFIG_UML void module_free(struct module *mod, void *module_region) { vfree(module_region); /* FIXME: If module_region == mod->init_region, trim exception - table entries. */ + table entries. */ } void *module_alloc(unsigned long size) @@ -77,7 +77,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr; Elf64_Sym *sym; void *loc; - u64 val; + u64 val; DEBUGP("Applying relocate section %u to %u\n", relsec, sechdrs[relsec].sh_info); @@ -91,11 +91,11 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, sym = (Elf64_Sym *)sechdrs[symindex].sh_addr + ELF64_R_SYM(rel[i].r_info); - DEBUGP("type %d st_value %Lx r_addend %Lx loc %Lx\n", - (int)ELF64_R_TYPE(rel[i].r_info), - sym->st_value, rel[i].r_addend, (u64)loc); + DEBUGP("type %d st_value %Lx r_addend %Lx loc %Lx\n", + (int)ELF64_R_TYPE(rel[i].r_info), + sym->st_value, rel[i].r_addend, (u64)loc); - val = sym->st_value + rel[i].r_addend; + val = sym->st_value + rel[i].r_addend; switch (ELF64_R_TYPE(rel[i].r_info)) { case R_X86_64_NONE: @@ -113,16 +113,16 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, if ((s64)val != *(s32 *)loc) goto overflow; break; - case R_X86_64_PC32: + case R_X86_64_PC32: val -= (u64)loc; *(u32 *)loc = val; #if 0 if ((s64)val != *(s32 *)loc) - goto overflow; + goto overflow; #endif break; default: - printk(KERN_ERR "module %s: Unknown rela relocation: %Lu\n", + printk(KERN_ERR "module %s: Unknown rela relocation: %llu\n", me->name, ELF64_R_TYPE(rel[i].r_info)); return -ENOEXEC; } @@ -130,7 +130,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, return 0; overflow: - printk(KERN_ERR "overflow in relocation type %d val %Lx\n", + printk(KERN_ERR "overflow in relocation type %d val %Lx\n", (int)ELF64_R_TYPE(rel[i].r_info), val); printk(KERN_ERR "`%s' likely not compiled with -mcmodel=kernel\n", me->name); @@ -143,13 +143,13 @@ int apply_relocate(Elf_Shdr *sechdrs, unsigned int relsec, struct module *me) { - printk("non add relocation not supported\n"); + printk(KERN_ERR "non add relocation not supported\n"); return -ENOSYS; -} +} int module_finalize(const Elf_Ehdr *hdr, - const Elf_Shdr *sechdrs, - struct module *me) + const Elf_Shdr *sechdrs, + struct module *me) { const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL, *para = NULL; @@ -161,7 +161,7 @@ int module_finalize(const Elf_Ehdr *hdr, if (!strcmp(".altinstructions", secstrings + s->sh_name)) alt = s; if (!strcmp(".smp_locks", secstrings + s->sh_name)) - locks= s; + locks = s; if (!strcmp(".parainstructions", secstrings + s->sh_name)) para = s; } -- cgit From 01e3eb82278bf45221fc38b391bc5ee0f6a314d6 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 Jan 2009 13:00:50 +0100 Subject: Revert "sched: improve preempt debugging" This reverts commit 7317d7b87edb41a9135e30be1ec3f7ef817c53dd. This has been reported (and bisected) by Alexey Zaytsev and Kamalesh Babulal to produce annoying warnings during bootup on both x86 and powerpc. kernel_locked() is not a valid test in IRQ context (we update the BKL's ->lock_depth and the preempt count separately and non-atomicalyy), so we cannot put it into the generic preempt debugging checks which can run in IRQ contexts too. Reported-and-bisected-by: Alexey Zaytsev Reported-and-bisected-by: Kamalesh Babulal Signed-off-by: Ingo Molnar --- kernel/sched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched.c b/kernel/sched.c index 8be2c13b50d..3b630d88266 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -4440,7 +4440,7 @@ void __kprobes sub_preempt_count(int val) /* * Underflow? */ - if (DEBUG_LOCKS_WARN_ON(val > preempt_count() - (!!kernel_locked()))) + if (DEBUG_LOCKS_WARN_ON(val > preempt_count())) return; /* * Is the spinlock portion underflowing? -- cgit From 3a03ac1a0223f779a3de313523408ddb099e5679 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 11 Jan 2009 09:03:49 +1000 Subject: drm/i915: setup sarea properly in master_priv If we are running DRI1 userspace, we really need to set the sarea up properly. thanks to Richard for finding/testing this. Signed-off-by: Richard Purdie Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/i915_dma.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 62a4bf7b49d..868f574363a 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -177,6 +177,14 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; + master_priv->sarea = drm_getsarea(dev); + if (master_priv->sarea) { + master_priv->sarea_priv = (drm_i915_sarea_t *) + ((u8 *)master_priv->sarea->handle + init->sarea_priv_offset); + } else { + DRM_DEBUG("sarea not found assuming DRI2 userspace\n"); + } + if (init->ring_size != 0) { if (dev_priv->ring.ring_obj != NULL) { i915_dma_cleanup(dev); -- cgit From 6d612b0f943289856c6e8186c564cda922cd040e Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 12 Jan 2009 12:52:23 +0100 Subject: locking, hpet: annotate false positive warning Alexander Beregalov reported that this warning is caused by the HPET code: > hpet0: at MMIO 0xfed00000, IRQs 2, 8, 0 > hpet0: 3 comparators, 64-bit 14.318180 MHz counter > ODEBUG: object is on stack, but not annotated > ------------[ cut here ]------------ > WARNING: at lib/debugobjects.c:251 __debug_object_init+0x2a4/0x352() > Bisected down to 26afe5f2fbf06ea0765aaa316640c4dd472310c0 > (x86: HPET_MSI Initialise per-cpu HPET timers) The commit is fine - but the on-stack workqueue entry needs annotation. Reported-and-bisected-by: Alexander Beregalov Signed-off-by: Peter Zijlstra Tested-by: Alexander Beregalov Signed-off-by: Ingo Molnar --- arch/x86/kernel/hpet.c | 2 +- include/linux/workqueue.h | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index cd759ad9069..bb2e0f0975a 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -628,7 +628,7 @@ static int hpet_cpuhp_notify(struct notifier_block *n, switch (action & 0xf) { case CPU_ONLINE: - INIT_DELAYED_WORK(&work.work, hpet_work); + INIT_DELAYED_WORK_ON_STACK(&work.work, hpet_work); init_completion(&work.complete); /* FIXME: add schedule_work_on() */ schedule_delayed_work_on(cpu, &work.work, 0); diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index b36291130f2..47151c8495a 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -118,6 +118,12 @@ struct execute_work { init_timer(&(_work)->timer); \ } while (0) +#define INIT_DELAYED_WORK_ON_STACK(_work, _func) \ + do { \ + INIT_WORK(&(_work)->work, (_func)); \ + init_timer_on_stack(&(_work)->timer); \ + } while (0) + #define INIT_DELAYED_WORK_DEFERRABLE(_work, _func) \ do { \ INIT_WORK(&(_work)->work, (_func)); \ -- cgit From 8476a6571005f9440adda08ca4d6c69c7f4db30b Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Tue, 30 Dec 2008 22:49:28 +0100 Subject: Wireless: Fix Kconfig fact error Raytheon cards use 2.4 GHz, not 2.4 MHz. See http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Linux.Wireless.drivers.html#Raylink Signed-off-by: Erik Ekman Signed-off-by: John W. Linville --- drivers/net/wireless/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index ea543fcf268..e4f9f747de8 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -111,7 +111,7 @@ config WLAN_80211 lets you choose drivers. config PCMCIA_RAYCS - tristate "Aviator/Raytheon 2.4MHz wireless support" + tristate "Aviator/Raytheon 2.4GHz wireless support" depends on PCMCIA && WLAN_80211 select WIRELESS_EXT ---help--- -- cgit From d1b29405bd3590bc97c4d3ff2c9139ca55e56ccd Mon Sep 17 00:00:00 2001 From: Andrew Price Date: Fri, 2 Jan 2009 08:05:27 +0000 Subject: rt2x00: Fix radio LED type check Since "rt2x00: Fix LED state handling", rt2x00leds_led_radio wrongly checks that the LED type is LED_TYPE_ASSOC. This patch makes it check for LED_TYPE_RADIO once again. Signed-off-by: Andrew Price Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00leds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.c b/drivers/net/wireless/rt2x00/rt2x00leds.c index 68f4e0fc35b..a0cd35b6beb 100644 --- a/drivers/net/wireless/rt2x00/rt2x00leds.c +++ b/drivers/net/wireless/rt2x00/rt2x00leds.c @@ -97,7 +97,7 @@ void rt2x00leds_led_assoc(struct rt2x00_dev *rt2x00dev, bool enabled) void rt2x00leds_led_radio(struct rt2x00_dev *rt2x00dev, bool enabled) { - if (rt2x00dev->led_radio.type == LED_TYPE_ASSOC) + if (rt2x00dev->led_radio.type == LED_TYPE_RADIO) rt2x00led_led_simple(&rt2x00dev->led_radio, enabled); } -- cgit From 51fb80fefe736db1182551fec6528d1ef095b0ea Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 3 Jan 2009 12:45:12 -0600 Subject: p54usb: Fix to prevent SKB memory allocation errors with 4K page size On x86_64 architecture with 4K page size and SLUB debugging enabled, stress testing on p54usb has resulted in skb allocation failures of O(1) and extreme page fragmentation. Reducing rx_mtu fixes this problem by reducing the size of all receive skb allocations to be of O(0). This change does not impact performance in any way. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54common.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 82354b974a0..06c64744df2 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -138,6 +138,7 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) u8 *fw_version = NULL; size_t len; int i; + int maxlen; if (priv->rx_start) return 0; @@ -195,6 +196,16 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) else priv->rx_mtu = (size_t) 0x620 - priv->tx_hdr_len; + maxlen = priv->tx_hdr_len + /* USB devices */ + sizeof(struct p54_rx_data) + + 4 + /* rx alignment */ + IEEE80211_MAX_FRAG_THRESHOLD; + if (priv->rx_mtu > maxlen && PAGE_SIZE == 4096) { + printk(KERN_INFO "p54: rx_mtu reduced from %d " + "to %d\n", priv->rx_mtu, + maxlen); + priv->rx_mtu = maxlen; + } break; } case BR_CODE_EXPOSED_IF: -- cgit From 3be36ae223271f9c2cfbe7406846c8fdcd2f50c3 Mon Sep 17 00:00:00 2001 From: Stefan Lippers-Hollmann Date: Sun, 4 Jan 2009 01:10:49 +0100 Subject: rt2x00: add USB ID for the Linksys WUSB200. add USB ID for the Linksys WUSB200 Wireless-G Business USB Adapter to rt73usb. Signed-off-by: Stefan Lippers-Hollmann Cc: stable Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt73usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index d638a8a5937..96a8d69f879 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2321,6 +2321,7 @@ static struct usb_device_id rt73usb_device_table[] = { /* Linksys */ { USB_DEVICE(0x13b1, 0x0020), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x13b1, 0x0023), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x13b1, 0x0028), USB_DEVICE_DATA(&rt73usb_ops) }, /* MSI */ { USB_DEVICE(0x0db0, 0x6877), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0db0, 0x6874), USB_DEVICE_DATA(&rt73usb_ops) }, -- cgit From 3ea96463156123cbfd09ac412012a87fef068830 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Sun, 4 Jan 2009 17:33:25 +0100 Subject: rt2x00: Fix TX short preamble detection The short preamble mode was not correctly detected during TX, rt2x00 used the rate->hw_value_short field but mac80211 is not using this field that way. Instead the flag IEEE80211_TX_RC_USE_SHORT_PREAMBLE should be used to determine if the frame should be send out using short preamble or not. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00dev.c | 8 +++----- drivers/net/wireless/rt2x00/rt2x00lib.h | 11 ----------- drivers/net/wireless/rt2x00/rt2x00queue.c | 2 +- 3 files changed, 4 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 6d92542fcf0..87c0f2c8307 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -807,13 +807,11 @@ static void rt2x00lib_rate(struct ieee80211_rate *entry, { entry->flags = 0; entry->bitrate = rate->bitrate; - entry->hw_value = rt2x00_create_rate_hw_value(index, 0); - entry->hw_value_short = entry->hw_value; + entry->hw_value =index; + entry->hw_value_short = index; - if (rate->flags & DEV_RATE_SHORT_PREAMBLE) { + if (rate->flags & DEV_RATE_SHORT_PREAMBLE) entry->flags |= IEEE80211_RATE_SHORT_PREAMBLE; - entry->hw_value_short |= rt2x00_create_rate_hw_value(index, 1); - } } static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 03024327767..86cd26fbf76 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -52,22 +52,11 @@ struct rt2x00_rate { extern const struct rt2x00_rate rt2x00_supported_rates[12]; -static inline u16 rt2x00_create_rate_hw_value(const u16 index, - const u16 short_preamble) -{ - return (short_preamble << 8) | (index & 0xff); -} - static inline const struct rt2x00_rate *rt2x00_get_rate(const u16 hw_value) { return &rt2x00_supported_rates[hw_value & 0xff]; } -static inline int rt2x00_get_rate_preamble(const u16 hw_value) -{ - return (hw_value & 0xff00); -} - /* * Radio control handlers. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index eaec6bd93ed..746a8f36b93 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -313,7 +313,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, * When preamble is enabled we should set the * preamble bit for the signal. */ - if (rt2x00_get_rate_preamble(rate->hw_value)) + if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) txdesc->signal |= 0x08; } } -- cgit From 878e6a432f85690a2c0d88d96f177e54ff1d4a57 Mon Sep 17 00:00:00 2001 From: Michiel Date: Sun, 4 Jan 2009 17:22:28 -0600 Subject: p54usb: Add USB ID for Thomson Speedtouch 121g Add the USB ID for Thomson Speedtouch 121g to p54usb. Signed-off-by: Michiel Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index c44a200059d..8f5c063b854 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -56,6 +56,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */ {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */ {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */ + {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */ -- cgit From 176ddc7dcfe3fd93778f52abf9a947d92932f19e Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 5 Jan 2009 13:51:24 +0200 Subject: ath9k: Enforce module build if rfkill is a module CONFIG_ATH9K=y results in build issues if CONFIG_RFKILL=m since ath9k does not depend on rfkill in kconfig (i.e., CONFIG_RFKILL is used to select whether to enable rfkill in ath9k), but uses its functions if rfkill is enabled. Enforce ath9k to be build as a module if CONFIG_RFKILL=m to avoid this invalid configuration. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath9k/Kconfig b/drivers/net/wireless/ath9k/Kconfig index c43bd321f97..90a8dd87378 100644 --- a/drivers/net/wireless/ath9k/Kconfig +++ b/drivers/net/wireless/ath9k/Kconfig @@ -1,6 +1,7 @@ config ATH9K tristate "Atheros 802.11n wireless cards support" depends on PCI && MAC80211 && WLAN_80211 + depends on RFKILL || RFKILL=n select MAC80211_LEDS select LEDS_CLASS select NEW_LEDS -- cgit From 20953ad68ee522f6420b63c200ac9b23f96d937a Mon Sep 17 00:00:00 2001 From: David Kilroy Date: Wed, 7 Jan 2009 00:23:55 +0000 Subject: orinoco: take the driver lock in the rx tasklet Fix the warning reproduced below. We add to rx_list in interrupt context and remove elements in tasklet context. While removing elements we need to prevent the interrupt modifying the list. Note that "orinoco: Process bulk of receive interrupt in a tasklet" did not preserve locking semantics on what is now orinoco_rx. This patch reinstates the locking semantics and ensures it covers rx_list as well. This leads to additional cleanup required in free_orinocodev. [89479.105038] WARNING: at lib/list_debug.c:30 __list_add+0x8f/0xa0() [89479.105058] list_add corruption. prev->next should be next (dddb3568), but was cbc28978. (prev=dddb3568). [89479.106002] Pid: 15746, comm: X Not tainted 2.6.28-1avb #26 [89479.106020] Call Trace: [89479.106062] [] warn_slowpath+0x60/0x80 [89479.106104] [] ? native_sched_clock+0x20/0x70 [89479.106194] [] ? lock_release_holdtime+0x35/0x200 [89479.106218] [] ? __slab_alloc+0x550/0x560 [89479.106254] [] ? _spin_unlock+0x1d/0x20 [89479.106270] [] ? __slab_alloc+0x550/0x560 [89479.106302] [] ? delay_tsc+0x17/0x24 [89479.106319] [] ? __const_udelay+0x21/0x30 [89479.106376] [] ? hermes_bap_seek+0x112/0x1e0 [hermes] [89479.106396] [] ? trace_hardirqs_off+0xb/0x10 [89479.106418] [] ? __kmalloc_track_caller+0xb7/0x110 [89479.106448] [] ? dev_alloc_skb+0x1c/0x30 [89479.106465] [] ? dev_alloc_skb+0x1c/0x30 [89479.106482] [] __list_add+0x8f/0xa0 [89479.106551] [] orinoco_interrupt+0xcae/0x16c0 [orinoco] [89479.106574] [] ? tick_dev_program_event+0x33/0xb0 [89479.106594] [] ? native_sched_clock+0x20/0x70 [89479.106613] [] ? lock_release_holdtime+0x35/0x200 [89479.106662] [] ? trace_hardirqs_off+0xb/0x10 [89479.106892] [] ? usb_hcd_irq+0x97/0xa0 [usbcore] [89479.106926] [] handle_IRQ_event+0x29/0x60 [89479.106947] [] handle_level_irq+0x69/0xe0 [89479.106963] [] ? handle_level_irq+0x0/0xe0 [89479.106977] [] ? tcp_v4_rcv+0x633/0x6e0 [89479.107025] [] ? common_interrupt+0x28/0x30 [89479.107057] [] ? sk_run_filter+0x320/0x7a0 [89479.107078] [] ? list_del+0x21/0x90 [89479.107106] [] ? orinoco_rx_isr_tasklet+0x2ce/0x480 [orinoco] [89479.107131] [] ? __lock_acquire+0x160/0x1650 [89479.107151] [] ? native_sched_clock+0x20/0x70 [89479.107169] [] ? lock_release_holdtime+0x35/0x200 [89479.107200] [] ? irq_enter+0xa/0x60 [89479.107217] [] ? do_IRQ+0xd2/0x130 [89479.107518] [] ? restore_nocheck_notrace+0x0/0xe [89479.107542] [] ? __do_softirq+0x0/0x110 [89479.107561] [] ? trace_hardirqs_on_caller+0x74/0x140 [89479.107583] [] ? trace_hardirqs_on_thunk+0xc/0x10 [89479.107602] [] ? tasklet_action+0x27/0x90 [89479.107620] [] ? trace_hardirqs_on_caller+0x74/0x140 [89479.107638] [] ? tasklet_action+0x43/0x90 [89479.107655] [] ? __do_softirq+0x6f/0x110 [89479.107674] [] ? __do_softirq+0x0/0x110 [89479.107685] [] ? handle_level_irq+0x0/0xe0 [89479.107715] [] ? irq_exit+0x5d/0x80 [89479.107732] [] ? do_IRQ+0xd2/0x130 [89479.107747] [] ? sysenter_exit+0xf/0x16 [89479.107765] [] ? trace_hardirqs_on_caller+0xfd/0x140 [89479.107782] [] ? common_interrupt+0x28/0x30 [89479.107797] ---[ end trace a1fc0a52df4a729d ]--- Reported-by: Andrey Borzenkov Signed-off-by: David Kilroy Signed-off-by: John W. Linville --- drivers/net/wireless/orinoco/orinoco.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/orinoco/orinoco.c b/drivers/net/wireless/orinoco/orinoco.c index bc84e2792f8..c3bb85e0251 100644 --- a/drivers/net/wireless/orinoco/orinoco.c +++ b/drivers/net/wireless/orinoco/orinoco.c @@ -1610,6 +1610,16 @@ static void orinoco_rx_isr_tasklet(unsigned long data) struct orinoco_rx_data *rx_data, *temp; struct hermes_rx_descriptor *desc; struct sk_buff *skb; + unsigned long flags; + + /* orinoco_rx requires the driver lock, and we also need to + * protect priv->rx_list, so just hold the lock over the + * lot. + * + * If orinoco_lock fails, we've unplugged the card. In this + * case just abort. */ + if (orinoco_lock(priv, &flags) != 0) + return; /* extract desc and skb from queue */ list_for_each_entry_safe(rx_data, temp, &priv->rx_list, list) { @@ -1622,6 +1632,8 @@ static void orinoco_rx_isr_tasklet(unsigned long data) kfree(desc); } + + orinoco_unlock(priv, &flags); } /********************************************************************/ @@ -3645,12 +3657,22 @@ struct net_device void free_orinocodev(struct net_device *dev) { struct orinoco_private *priv = netdev_priv(dev); + struct orinoco_rx_data *rx_data, *temp; - /* No need to empty priv->rx_list: if the tasklet is scheduled - * when we call tasklet_kill it will run one final time, - * emptying the list */ + /* If the tasklet is scheduled when we call tasklet_kill it + * will run one final time. However the tasklet will only + * drain priv->rx_list if the hw is still available. */ tasklet_kill(&priv->rx_tasklet); + /* Explicitly drain priv->rx_list */ + list_for_each_entry_safe(rx_data, temp, &priv->rx_list, list) { + list_del(&rx_data->list); + + dev_kfree_skb(rx_data->skb); + kfree(rx_data->desc); + kfree(rx_data); + } + unregister_pm_notifier(&priv->pm_notifier); orinoco_uncache_fw(priv); -- cgit From 86060f0d691f5ee1b4ef4efe770b683e54ac438d Mon Sep 17 00:00:00 2001 From: Sujith Date: Wed, 7 Jan 2009 14:25:29 +0530 Subject: ath9k: Fix chainmask handling bug The chainmasks have to be updated before setting the channel, since the HW reset routine uses them to set the appropriate registers. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 191eec50dc7..727f067aca4 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -2164,13 +2164,13 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) conf->ht.channel_type); } + ath_update_chainmask(sc, conf->ht.enabled); + if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) { DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n"); mutex_unlock(&sc->mutex); return -EINVAL; } - - ath_update_chainmask(sc, conf->ht.enabled); } if (changed & IEEE80211_CONF_CHANGE_POWER) -- cgit From d732129b25b972c208c9705759c8c64f63a21800 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Thu, 8 Jan 2009 10:20:00 -0800 Subject: iwlwifi: Fix get_cmd_string() for REPLY_3945_RX 0x1b is a 3945 specific command, we should print it too when debugging. Signed-off-by: Samuel Ortiz Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-hcmd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 01a2169cece..8c71ad4f88c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -51,6 +51,7 @@ const char *get_cmd_string(u8 cmd) IWL_CMD(REPLY_REMOVE_STA); IWL_CMD(REPLY_REMOVE_ALL_STA); IWL_CMD(REPLY_WEPKEY); + IWL_CMD(REPLY_3945_RX); IWL_CMD(REPLY_TX); IWL_CMD(REPLY_RATE_SCALE); IWL_CMD(REPLY_LEDS_CMD); -- cgit From 706ea9b66935e341b063d860c9c8f279b37b5578 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Fri, 9 Jan 2009 12:31:48 -0500 Subject: orinoco_cs: add ID for ARtem Onair Comcard 11 Reported by Michael Jarosch Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/orinoco/orinoco_cs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c index f127602670e..0b32215d3f5 100644 --- a/drivers/net/wireless/orinoco/orinoco_cs.c +++ b/drivers/net/wireless/orinoco/orinoco_cs.c @@ -435,6 +435,7 @@ static struct pcmcia_device_id orinoco_cs_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), /* Samsung SWL2000-N 11Mb/s WLAN Card */ PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002), /* AirWay 802.11 Adapter (PCMCIA) */ PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001), /* ARtem Onair */ + PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0003), /* ARtem Onair Comcard 11 */ PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305), /* Buffalo WLI-PCM-S11 */ PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), /* Linksys WPC11 Version 2.5 */ PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), /* Linksys WPC11 Version 3 */ -- cgit From c1d34c1dad76be6d515ef33e24eb92f10547b08b Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 20 Dec 2008 02:21:37 +0100 Subject: p54: crypto offload fixes This patch fixes two small flaws: - restore the original TKIP IV if we altered it. - reserve & initialize ICV with zeros. This is actually only necessary for some obsolete p54usb firmwares. But we don't know yet, if all devices are compatible with the new revisions. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54common.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 06c64744df2..37294a657f8 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -809,6 +809,16 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) info->flags |= IEEE80211_TX_STAT_TX_FILTERED; info->status.ack_signal = p54_rssi_to_dbm(dev, (int)payload->ack_rssi); + + if (entry_data->key_type == P54_CRYPTO_TKIPMICHAEL) { + u8 *iv = (u8 *)(entry_data->align + pad + + entry_data->crypt_offset); + + /* Restore the original TKIP IV. */ + iv[2] = iv[0]; + iv[0] = iv[1]; + iv[1] = (iv[0] | 0x20) & 0x7f; /* WEPSeed - 8.3.2.2 */ + } skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data)); ieee80211_tx_status_irqsafe(dev, entry); goto out; @@ -1394,7 +1404,6 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) hdr->tries = ridx; txhdr->rts_rate_idx = 0; if (info->control.hw_key) { - crypt_offset += info->control.hw_key->iv_len; txhdr->key_type = p54_convert_algo(info->control.hw_key->alg); txhdr->key_len = min((u8)16, info->control.hw_key->keylen); memcpy(txhdr->key, info->control.hw_key->key, txhdr->key_len); @@ -1408,6 +1417,8 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) } /* reserve some space for ICV */ len += info->control.hw_key->icv_len; + memset(skb_put(skb, info->control.hw_key->icv_len), 0, + info->control.hw_key->icv_len); } else { txhdr->key_type = 0; txhdr->key_len = 0; -- cgit From 00627f229c9807e4cb825a7ce36b886e2adf2229 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 20 Dec 2008 02:21:56 +0100 Subject: p54usb: fix random traffic stalls (LM87) All LM87 firmwares need a explicit termination "packet", in oder to finish the pending transfer properly. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 8f5c063b854..6a6a72f6f82 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -285,6 +285,7 @@ static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb) usb_fill_bulk_urb(data_urb, priv->udev, usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), skb->data, skb->len, p54u_tx_cb, skb); + data_urb->transfer_flags |= URB_ZERO_PACKET; usb_anchor_urb(data_urb, &priv->submitted); if (usb_submit_urb(data_urb, GFP_ATOMIC)) { -- cgit From d15cfc3ac77388f1d588c57743d5f26b15eba9a8 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Sat, 20 Dec 2008 11:00:23 +0100 Subject: rt2x00: Fix segementation fault The queue_end() macro points to 1 position after the queue, which means that if we want to know if queue is at the end of the queue we should first increment the position and then check if it is a valid entry. This fixes a segmentation fault which only occurs when the device has enough endpoints to provide a dedicated endpoint for all TX queues (which likely won't happen for rt2500usb and rt73usb, but will happen for rt2800usb). Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00usb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 83df312ac56..0b29d767a25 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -434,11 +434,11 @@ static int rt2x00usb_find_endpoints(struct rt2x00_dev *rt2x00dev) if (usb_endpoint_is_bulk_in(ep_desc)) { rt2x00usb_assign_endpoint(rt2x00dev->rx, ep_desc); - } else if (usb_endpoint_is_bulk_out(ep_desc)) { + } else if (usb_endpoint_is_bulk_out(ep_desc) && + (queue != queue_end(rt2x00dev))) { rt2x00usb_assign_endpoint(queue, ep_desc); + queue = queue_next(queue); - if (queue != queue_end(rt2x00dev)) - queue = queue_next(queue); tx_ep_desc = ep_desc; } } -- cgit From 1061787967db03975dc02030d6815811f4eb9231 Mon Sep 17 00:00:00 2001 From: Daniel Wu Date: Sat, 20 Dec 2008 10:53:29 -0800 Subject: iwlwifi: Fix typo in iwl-commands.h for CCK rate bit range. My first (minor) patch, hopefully this is correct. Fix a typo in iwl-commands.h for CCK rates which needs 7 bits and not 4. Signed-off-by: Daniel Wu Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-commands.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 52966ffbef6..ba997204c8d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -255,7 +255,7 @@ struct iwl_cmd_header { * 0x3) 54 Mbps * * Legacy CCK rate format for bits 7:0 (bit 8 must be "0", bit 9 "1"): - * 3-0: 10) 1 Mbps + * 6-0: 10) 1 Mbps * 20) 2 Mbps * 55) 5.5 Mbps * 110) 11 Mbps -- cgit From b55eae3349ff5d6d088c7ab0151260d5e3dbd26d Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sun, 21 Dec 2008 15:40:33 -0600 Subject: rtl8180: Fix to add STA mode To be compatible with mac80211 following "mac80211: only create default STA interface if supported", rtl8180 needs to set NL80211_IFTYPE_STATION in interface_modes. Signed-off-by: Larry Finger Reported-by: Fabio Rossi Tested-by: Piter PUNK Acked-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8180_dev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c index 5f887fb137a..387c133ec0f 100644 --- a/drivers/net/wireless/rtl818x/rtl8180_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c @@ -897,6 +897,7 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_SIGNAL_UNSPEC; + dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); dev->queues = 1; dev->max_signal = 65; -- cgit From f3d340c1d536fd3e5a104c99ac9c3f8694270d72 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Sun, 21 Dec 2008 23:19:17 +0100 Subject: Fix rt2500usb HW crypto: TKIP rt2500usb doesn't strip the IV/ICV data from received frames, so we don't need to set the RX_FLAG_IV_STRIPPED flag. We do need to set the RX_FLAG_MMIC_STRIPPED flag for all encryption types since the MMIC has been removed from the frame. After this patch TKIP Hardware crypto works for rt2500usb. WEP and AES are still failing. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500usb.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 30028e2422f..065f111f01f 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -376,11 +376,11 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev, /* * The driver does not support the IV/EIV generation - * in hardware. However it doesn't support the IV/EIV - * inside the ieee80211 frame either, but requires it - * to be provided seperately for the descriptor. - * rt2x00lib will cut the IV/EIV data out of all frames - * given to us by mac80211, but we must tell mac80211 + * in hardware. However it demands the data to be provided + * both seperately as well as inside the frame. + * We already provided the CONFIG_CRYPTO_COPY_IV to rt2x00lib + * to ensure rt2x00lib will not strip the data from the + * frame after the copy, now we must tell mac80211 * to generate the IV/EIV data. */ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; @@ -1334,14 +1334,7 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry, /* ICV is located at the end of frame */ - /* - * Hardware has stripped IV/EIV data from 802.11 frame during - * decryption. It has provided the data seperately but rt2x00lib - * should decide if it should be reinserted. - */ - rxdesc->flags |= RX_FLAG_IV_STRIPPED; - if (rxdesc->cipher != CIPHER_TKIP) - rxdesc->flags |= RX_FLAG_MMIC_STRIPPED; + rxdesc->flags |= RX_FLAG_MMIC_STRIPPED; if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS) rxdesc->flags |= RX_FLAG_DECRYPTED; else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC) -- cgit From d3a1db1c67735063921d9186145fc86164cf9781 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Mon, 22 Dec 2008 16:31:58 +0530 Subject: ath9k: Fix incorrect sequence numbering for unaggregated QoS Frame. This patch fixes an issue with the sequence numbers of unaggregated QoS frames, because of which the frames are handled in a different order at the AP and resulted in MLME REPLAYFAILURE. Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/xmit.c | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 3bfc3b90f25..1ea9428c0cd 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -264,25 +264,22 @@ static void assign_aggr_tid_seqno(struct sk_buff *skb, } /* Get seqno */ - - if (ieee80211_is_data(fc) && !is_pae(skb)) { - /* For HT capable stations, we save tidno for later use. - * We also override seqno set by upper layer with the one - * in tx aggregation state. - * - * If fragmentation is on, the sequence number is - * not overridden, since it has been - * incremented by the fragmentation routine. - * - * FIXME: check if the fragmentation threshold exceeds - * IEEE80211 max. - */ - tid = ATH_AN_2_TID(an, bf->bf_tidno); - hdr->seq_ctrl = cpu_to_le16(tid->seq_next << - IEEE80211_SEQ_SEQ_SHIFT); - bf->bf_seqno = tid->seq_next; - INCR(tid->seq_next, IEEE80211_SEQ_MAX); - } + /* For HT capable stations, we save tidno for later use. + * We also override seqno set by upper layer with the one + * in tx aggregation state. + * + * If fragmentation is on, the sequence number is + * not overridden, since it has been + * incremented by the fragmentation routine. + * + * FIXME: check if the fragmentation threshold exceeds + * IEEE80211 max. + */ + tid = ATH_AN_2_TID(an, bf->bf_tidno); + hdr->seq_ctrl = cpu_to_le16(tid->seq_next << + IEEE80211_SEQ_SEQ_SHIFT); + bf->bf_seqno = tid->seq_next; + INCR(tid->seq_next, IEEE80211_SEQ_MAX); } static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb, @@ -1718,11 +1715,10 @@ static int ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf, /* Assign seqno, tidno */ - if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR)) + if (ieee80211_is_data_qos(fc) && (sc->sc_flags & SC_OP_TXAGGR)) assign_aggr_tid_seqno(skb, bf); /* DMA setup */ - bf->bf_mpdu = skb; bf->bf_dmacontext = pci_map_single(sc->pdev, skb->data, -- cgit From d57854bb1d78ba89ffbfdfd1c3e95b52ed7478ff Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Mon, 22 Dec 2008 15:35:31 +0100 Subject: minstrel: fix warning if lowest supported rate index is not 0 This patch fixes the following WARNING (caused by rix_to_ndx): " >WARNING: at net/mac80211/rc80211_minstrel.c:69 minstrel_rate_init+0xd2/0x33a [mac80211]() >[...] >Call Trace: > warn_on_slowpath+0x51/0x75 > _format_mac_addr+0x4c/0x88 > minstrel_rate_init+0xd2/0x33a [mac80211] > print_mac+0x16/0x1b > schedule_hrtimeout_range+0xdc/0x107 > ieee80211_add_station+0x158/0x1bd [mac80211] > nl80211_new_station+0x1b3/0x20b [cfg80211] The reason is that I'm experimenting with "g" only mode on a 802.11 b/g card. Therefore rate_lowest_index returns 4 (= 6Mbit, instead of usual 0 = 1Mbit). Since mi->r array is initialized with zeros in minstrel_alloc_sta, rix_to_ndx has a hard time to find the 6Mbit entry and will trigged the WARNING. Signed-off-by: Christian Lamparter Acked-by: Felix Fietkau Signed-off-by: John W. Linville --- net/mac80211/rc80211_minstrel.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index 2b3b490a607..3824990d340 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c @@ -395,13 +395,15 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, { struct minstrel_sta_info *mi = priv_sta; struct minstrel_priv *mp = priv; - struct minstrel_rate *mr_ctl; + struct ieee80211_local *local = hw_to_local(mp->hw); + struct ieee80211_rate *ctl_rate; unsigned int i, n = 0; unsigned int t_slot = 9; /* FIXME: get real slot time */ mi->lowest_rix = rate_lowest_index(sband, sta); - mr_ctl = &mi->r[rix_to_ndx(mi, mi->lowest_rix)]; - mi->sp_ack_dur = mr_ctl->ack_time; + ctl_rate = &sband->bitrates[mi->lowest_rix]; + mi->sp_ack_dur = ieee80211_frame_duration(local, 10, ctl_rate->bitrate, + !!(ctl_rate->flags & IEEE80211_RATE_ERP_G), 1); for (i = 0; i < sband->n_bitrates; i++) { struct minstrel_rate *mr = &mi->r[n]; @@ -416,7 +418,7 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, mr->rix = i; mr->bitrate = sband->bitrates[i].bitrate / 5; - calc_rate_durations(mi, hw_to_local(mp->hw), mr, + calc_rate_durations(mi, local, mr, &sband->bitrates[i]); /* calculate maximum number of retransmissions before -- cgit From 157ec8768457e8177d281ae099fb1c321c9a16d7 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 22 Dec 2008 16:45:54 +0200 Subject: ath9k: Revert fix to TX status reporting for retries and MCS index This patch reverts "ath9k: Fix TX status reporting for retries and MCS index" because that change ended up breaking ath9k rate control. While the MCS index reporting to mac80211 was indeed fixed by the patch, it did not take into account that the ath9k rate control algorithm was updating private tables based on this index and the index comes through the rate control API call, i.e., based on mac80211 TX status call. In addition, it looks like the "fix" to remove +1 from TX status 'count' field was not correct based on ieee80211_tx_status() implementation that counts the total of count values, but starting from -1, not 0. The TX status reporting for frames using MCS needs to be fixed somehow, but it does not look like there is any easy fix for the ath9k rate control algorithm, so the best option now seems to be to revert the change and bring it back once the rate control code is cleaned up to handle this better. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/xmit.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 1ea9428c0cd..c92f0c6e4ad 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -126,15 +126,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, tx_info->flags |= IEEE80211_TX_STAT_ACK; } - tx_info->status.rates[0].count = tx_status->retries; - if (tx_info->status.rates[0].flags & IEEE80211_TX_RC_MCS) { - /* Change idx from internal table index to MCS index */ - int idx = tx_info->status.rates[0].idx; - struct ath_rate_table *rate_table = sc->cur_rate_table; - if (idx >= 0 && idx < rate_table->rate_cnt) - tx_info->status.rates[0].idx = - rate_table->info[idx].ratecode & 0x7f; - } + tx_info->status.rates[0].count = tx_status->retries + 1; hdrlen = ieee80211_get_hdrlen_from_skb(skb); padsize = hdrlen & 3; -- cgit From 4fb7404e0eaf574c00d01d2b1ce2615229b350cd Mon Sep 17 00:00:00 2001 From: Steve Brown Date: Tue, 23 Dec 2008 07:57:05 -0500 Subject: ath5k: Correct usage of AR5K_CFG_ADHOC This corrects usage of AR5K_CFG_ADHOC introduced in "ath5k: Update PCU code". Also, the name of the indicator is changed to AR5K_CFG_IBSS to more accurately reflect its function. This change restores beaconing in AP and mesh modes. Signed-off-by: Steve Brown Signed-off-by: John W. Linville --- drivers/net/wireless/ath5k/pcu.c | 4 ++-- drivers/net/wireless/ath5k/reg.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath5k/pcu.c b/drivers/net/wireless/ath5k/pcu.c index 0cac05c6a9c..75eb9f43c74 100644 --- a/drivers/net/wireless/ath5k/pcu.c +++ b/drivers/net/wireless/ath5k/pcu.c @@ -65,7 +65,7 @@ int ath5k_hw_set_opmode(struct ath5k_hw *ah) if (ah->ah_version == AR5K_AR5210) pcu_reg |= AR5K_STA_ID1_NO_PSPOLL; else - AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_ADHOC); + AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS); break; case NL80211_IFTYPE_AP: @@ -75,7 +75,7 @@ int ath5k_hw_set_opmode(struct ath5k_hw *ah) if (ah->ah_version == AR5K_AR5210) pcu_reg |= AR5K_STA_ID1_NO_PSPOLL; else - AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_ADHOC); + AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS); break; case NL80211_IFTYPE_STATION: diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath5k/reg.h index 91aaeaf8819..9189ab13286 100644 --- a/drivers/net/wireless/ath5k/reg.h +++ b/drivers/net/wireless/ath5k/reg.h @@ -73,7 +73,7 @@ #define AR5K_CFG_SWRD 0x00000004 /* Byte-swap RX descriptor */ #define AR5K_CFG_SWRB 0x00000008 /* Byte-swap RX buffer */ #define AR5K_CFG_SWRG 0x00000010 /* Byte-swap Register access */ -#define AR5K_CFG_ADHOC 0x00000020 /* AP/Adhoc indication [5211+] */ +#define AR5K_CFG_IBSS 0x00000020 /* 0-BSS, 1-IBSS [5211+] */ #define AR5K_CFG_PHY_OK 0x00000100 /* [5211+] */ #define AR5K_CFG_EEBS 0x00000200 /* EEPROM is busy */ #define AR5K_CFG_CLKGD 0x00000400 /* Clock gated (Disable dynamic clock) */ -- cgit From dcebf45cdc8384be9009b2b9a825054b64742768 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Mon, 22 Dec 2008 16:39:36 -0500 Subject: mac80211: allow mode change if IBSS is not allowed Changing mode on an interface is not allowed if IBSS is disabled for the current channel. That restriction should only apply when switching to the ad-hoc mode, as it was prior to "cfg80211: handle SIOCGIWMODE/SIOCSIWMODE". Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- net/mac80211/iface.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 5abbc3f07dd..b9074824862 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -699,7 +699,8 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, return 0; /* Setting ad-hoc mode on non-IBSS channel is not supported. */ - if (sdata->local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS) + if (sdata->local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS && + type == NL80211_IFTYPE_ADHOC) return -EOPNOTSUPP; /* -- cgit From 124b68e755c2ef9342d5d477142c499fd7901360 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 26 Dec 2008 19:09:45 +0100 Subject: p54: fix WARN_ON at line 2247 of net/mac80211/rx.c This patch hopefully fixes a mac80211<->p54 interaction problem, which was described by Larry Finger (ref: http://marc.info/?l=linux-wireless&m=123009889327707 ) I guess the warning was triggered by pending frames in the receive queue, while we're doing a band change 5GHz. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54common.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 37294a657f8..cba89ed0f57 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -586,6 +586,7 @@ static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb) u16 freq = le16_to_cpu(hdr->freq); size_t header_len = sizeof(*hdr); u32 tsf32; + u8 rate = hdr->rate & 0xf; /* * If the device is in a unspecified state we have to @@ -614,8 +615,11 @@ static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb) rx_status.qual = (100 * hdr->rssi) / 127; if (hdr->rate & 0x10) rx_status.flag |= RX_FLAG_SHORTPRE; - rx_status.rate_idx = (dev->conf.channel->band == IEEE80211_BAND_2GHZ ? - hdr->rate : (hdr->rate - 4)) & 0xf; + if (dev->conf.channel->band == IEEE80211_BAND_5GHZ) + rx_status.rate_idx = (rate < 4) ? 0 : rate - 4; + else + rx_status.rate_idx = rate; + rx_status.freq = freq; rx_status.band = dev->conf.channel->band; rx_status.antenna = hdr->antenna; -- cgit From d6e2be988d5146d1faa8df895cd8b32106d987bd Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 Jan 2009 23:11:26 -0600 Subject: rtl8187: Fix module so that rmmod/insmod does not error Due to misunderstanding of the returned values allowed for the tx callback of mac80211, rtl8187 was using skb's that had been freed. This problem was triggered when the module was sujected to a rmmod/insmod cycle. After that was fixed, the modules would not work after the rmmod/insmod cycle until the USB device was reset. Signed-off-by: Johannes Berg Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187_dev.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 00ce3ef39ab..6ad6bac3770 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -213,7 +213,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { kfree_skb(skb); - return -ENOMEM; + return NETDEV_TX_OK; } flags = skb->len; @@ -281,7 +281,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) } usb_free_urb(urb); - return rc; + return NETDEV_TX_OK; } static void rtl8187_rx_cb(struct urb *urb) @@ -1471,6 +1471,7 @@ static void __devexit rtl8187_disconnect(struct usb_interface *intf) ieee80211_unregister_hw(dev); priv = dev->priv; + usb_reset_device(priv->udev); usb_put_dev(interface_to_usbdev(intf)); ieee80211_free_hw(dev); } -- cgit From 71ef99c8b79ab07e1c79794085481464f9870d62 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Mon, 5 Jan 2009 20:46:34 -0500 Subject: ath5k: fix return values from ath5k_tx Should return NETDEV_TX_{OK,BUSY} instead of 0,-1 (this doesn't change any current functionality). Changes-licensed-under: 3-Clause-BSD Reported-by: Johannes Berg Signed-off-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath5k/base.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 4af2607deec..8ef87356e08 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c @@ -2644,7 +2644,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) if (skb_headroom(skb) < padsize) { ATH5K_ERR(sc, "tx hdrlen not %%4: %d not enough" " headroom to pad %d\n", hdrlen, padsize); - return -1; + return NETDEV_TX_BUSY; } skb_push(skb, padsize); memmove(skb->data, skb->data+padsize, hdrlen); @@ -2655,7 +2655,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) ATH5K_ERR(sc, "no further txbuf available, dropping packet\n"); spin_unlock_irqrestore(&sc->txbuflock, flags); ieee80211_stop_queue(hw, skb_get_queue_mapping(skb)); - return -1; + return NETDEV_TX_BUSY; } bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list); list_del(&bf->list); @@ -2673,10 +2673,10 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) sc->txbuf_len++; spin_unlock_irqrestore(&sc->txbuflock, flags); dev_kfree_skb_any(skb); - return 0; + return NETDEV_TX_OK; } - return 0; + return NETDEV_TX_OK; } static int -- cgit From b973c31a925c6753d84a100673f6b25546ec8b34 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 27 Dec 2008 22:19:49 +0100 Subject: mac80211: initialize RC data for all mesh links upon allocation This patch fixes a panic that might occur, if the device is part of a mesh and tries to send with a higher rate index than "0". kernel BUG at net/mac80211/rate.c:239! invalid opcode: 0000 [#1] SMP [...] Call Trace: <0> ? invoke_tx_handlers+0x474/0xb57 [mac80211] ? __ieee80211_tx_prepare+0x260/0x2a8 [mac80211] ? ieee80211_master_start_xmit+0x300/0x43a [mac80211] ? __qdisc_run+0xde/0x1da ? net_tx_action+0xb4/0x102 Kernel panic - not syncing: Fatal exception in interrupt Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- net/mac80211/mesh_plink.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 929ba542fd7..1159bdb4119 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -107,6 +107,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, sta->flags = WLAN_STA_AUTHORIZED; sta->sta.supp_rates[local->hw.conf.channel->band] = rates; + rate_control_rate_init(sta); return sta; } -- cgit From f1dd2b23badfe8a28910a78be24452c627c4b6f2 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Sat, 3 Jan 2009 16:27:14 +0100 Subject: rt2x00: Fix rt2500usb HW crypto: WEP 128 & AES The TXD_W0_CIPHER field is a 1-bit field. It only acts as boolean value to indicate if the frame must be encrypted or not. The way rt2x00_set_field32() worked it would grab the least signifcant bit from txdesc->cipher and use that as value. Because of that WEP 64 and TKIP worked since they had odd-numbered values, while WEP 128 and AES were even numbers and didn't work. Correctly booleanize the txdecs->cipher value to allow the hardware to encrypt the outgoing data. After this we can enable HW crypto by default again. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 065f111f01f..af6b5847be5 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -38,7 +38,7 @@ /* * Allow hardware encryption to be disabled. */ -static int modparam_nohwcrypt = 1; +static int modparam_nohwcrypt = 0; module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); @@ -1181,7 +1181,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)); rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len); - rt2x00_set_field32(&word, TXD_W0_CIPHER, txdesc->cipher); + rt2x00_set_field32(&word, TXD_W0_CIPHER, !!txdesc->cipher); rt2x00_set_field32(&word, TXD_W0_KEY_ID, txdesc->key_idx); rt2x00_desc_write(txd, 0, word); } -- cgit From 51e99158d261a5ec5772ca89b935c3daa270b07c Mon Sep 17 00:00:00 2001 From: Andrey Yurovsky Date: Mon, 5 Jan 2009 14:37:31 -0800 Subject: libertas_tf: return NETDEV_TX_OK in TX op The TX op should return NETDEV_TX_OK or NETDEV_TX_BUSY. Signed-off-by: Andrey Yurovsky Signed-off-by: John W. Linville --- drivers/net/wireless/libertas_tf/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c index d1fc305de5f..e7289e2e7f1 100644 --- a/drivers/net/wireless/libertas_tf/main.c +++ b/drivers/net/wireless/libertas_tf/main.c @@ -206,7 +206,7 @@ static int lbtf_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) * there are no buffered multicast frames to send */ ieee80211_stop_queues(priv->hw); - return 0; + return NETDEV_TX_OK; } static void lbtf_tx_work(struct work_struct *work) -- cgit From dd59b8537f6cb53ab863fafad86a5828f1e889a2 Mon Sep 17 00:00:00 2001 From: Yuri Tikhonov Date: Mon, 12 Jan 2009 15:17:20 -0700 Subject: dmaengine: fix dependency chaining In dmaengine we track the dependencies between the descriptors using the 'next' pointers of the structure. These pointers are set to NULL as soon as the corresponding descriptor has been submitted to the channel (in dma_run_dependencies()). But, the first 'next' in chain is still remaining set, regardless the fact, that tx->next has been already submitted. This may lead to multiple submissions of the same descriptor. This patch fixes this. Actually, some previous implementation of the xxx_run_dependencies() function already had this fix in place. The fdb..0eaf3 commit, beside the correct things, broke this. Cc: Signed-off-by: Yuri Tikhonov Signed-off-by: Dan Williams --- drivers/dma/dmaengine.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 403dbe78112..6df144a65fe 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -961,6 +961,8 @@ void dma_run_dependencies(struct dma_async_tx_descriptor *tx) if (!dep) return; + /* we'll submit tx->next now, so clear the link */ + tx->next = NULL; chan = dep->chan; /* keep submitting up until a channel switch is detected -- cgit From 6527de6d6d25ebfae7c7572cb7a4ed768e2e20a5 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 12 Jan 2009 15:18:34 -0700 Subject: fsldma: use a valid 'device' for dma_pool_create The dmaengine sysfs implementation was fixed to support proper lifetime rules which means that the current: new_fsl_chan->dev = &new_fsl_chan->common.dev->device; ...retrieves a NULL pointer because new_fsl_chan->common.dev has not been allocated at this point. So, set new_fsl_chan->dev to a valid device. Cc: Li Yang Cc: Zhang Wei Reported-by: Ira Snyder Tested-by: Ira Snyder Signed-off-by: Dan Williams --- drivers/dma/fsldma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index ca70a21afc6..748e140c5a1 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -822,7 +822,7 @@ static int __devinit fsl_dma_chan_probe(struct fsl_dma_device *fdev, */ WARN_ON(fdev->feature != new_fsl_chan->feature); - new_fsl_chan->dev = &new_fsl_chan->common.dev->device; + new_fsl_chan->dev = fdev->dev; new_fsl_chan->reg_base = ioremap(new_fsl_chan->reg.start, new_fsl_chan->reg.end - new_fsl_chan->reg.start + 1); -- cgit From 23a22d57a8962479ca630c9542e62d6f86fdf927 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Mon, 12 Jan 2009 14:24:04 -0800 Subject: bzip2/lzma: comprehensible error messages for missing decompressor Instead of failing to identify a compressed image with a decompressor that we don't have compiled in, identify it and fail with a comprehensible panic message. Signed-off-by: H. Peter Anvin --- init/do_mounts_rd.c | 5 ++++- init/initramfs.c | 12 +++++++++++- lib/decompress.c | 16 ++++++++++------ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index a015e267fd1..91d0cfca507 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -79,9 +79,12 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) sys_read(fd, buf, size); *decompressor = decompress_method(buf, size, &compress_name); - if (*decompressor) { + if (compress_name) { printk(KERN_NOTICE "RAMDISK: %s image found at block %d\n", compress_name, start_block); + if (!*decompressor) + printk(KERN_CRIT "RAMDISK: %s decompressor not configured!\n", + compress_name); nblocks = 0; goto done; } diff --git a/init/initramfs.c b/init/initramfs.c index 76f4a012533..9a7290ec818 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -421,6 +421,8 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only) { int written; decompress_fn decompress; + const char *compress_name; + static __initdata char msg_buf[64]; dry_run = check_only; header_buf = kmalloc(110, GFP_KERNEL); @@ -449,10 +451,18 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only) continue; } this_header = 0; - decompress = decompress_method(buf, len, NULL); + decompress = decompress_method(buf, len, &compress_name); if (decompress) decompress(buf, len, NULL, flush_buffer, NULL, &my_inptr, error); + else if (compress_name) { + if (!message) { + snprintf(msg_buf, sizeof msg_buf, + "compression method %s not configured", + compress_name); + message = msg_buf; + } + } if (state != Reset) error("junk in compressed archive"); this_header = saved_offset + my_inptr; diff --git a/lib/decompress.c b/lib/decompress.c index edac55cc782..961f367320f 100644 --- a/lib/decompress.c +++ b/lib/decompress.c @@ -13,21 +13,25 @@ #include #include +#ifndef CONFIG_DECOMPRESS_GZIP +# define gunzip NULL +#endif +#ifndef CONFIG_DECOMPRESS_BZIP2 +# define bunzip2 NULL +#endif +#ifndef CONFIG_DECOMPRESS_LZMA +# define unlzma NULL +#endif + static const struct compress_format { unsigned char magic[2]; const char *name; decompress_fn decompressor; } compressed_formats[] = { -#ifdef CONFIG_DECOMPRESS_GZIP { {037, 0213}, "gzip", gunzip }, { {037, 0236}, "gzip", gunzip }, -#endif -#ifdef CONFIG_DECOMPRESS_BZIP2 { {0x42, 0x5a}, "bzip2", bunzip2 }, -#endif -#ifdef CONFIG_DECOMPRESS_LZMA { {0x5d, 0x00}, "lzma", unlzma }, -#endif { {0, 0}, NULL, NULL } }; -- cgit From e16459c6b7e9c1390020a3e2a033b5383d1c4f3b Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Fri, 2 Jan 2009 10:46:04 +0000 Subject: powerpc: Make dummy section a valid note header We are declaring the dummy section (used to work around a binutils bug) as PT_NOTE, but we don't have enough bytes for it to be a valid note header, and kexec userspace complains: Warning: Elf Note name is not null terminated Warning: append= option is not passed. Using the first kernel root partition Warning: Elf Note name is not null terminated Instead of using the arbitray value 0xf177 (aka "fill"), declare a no-name no-description note of type 0. Signed-off-by: Milton Miller Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/vmlinux.lds.S | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index 47bf15cd2c9..161b9b9691f 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -87,7 +87,9 @@ SECTIONS /* The dummy segment contents for the bug workaround mentioned above near PHDRS. */ .dummy : AT(ADDR(.dummy) - LOAD_OFFSET) { - LONG(0xf177) + LONG(0) + LONG(0) + LONG(0) } :kernel :dummy /* -- cgit From 66c721e184e594d5761c5db804ade08fab81930d Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Fri, 2 Jan 2009 10:46:15 +0000 Subject: powerpc/kexec: Check crash_base for relocatable kernel Enforce that the crash kernel region never overlaps the current kernel, as it will be written directly on kexec load. Also, default to the previous KDUMP_KERNELBASE if the start is 0. Other architectures (x86, ia64) state that specifying the start address 0 (or omitting it) will result in the kernel allocating it. Before the relocatable patch in 2.6.28, powerpc would adjust any other start value to the hardcoded KDUMP_KERNELBASE of 32M. Signed-off-by: Milton Miller Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/machine_kexec.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index b3abebb7ee6..d59e2b1bdcb 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c @@ -93,10 +93,35 @@ void __init reserve_crashkernel(void) KDUMP_KERNELBASE); crashk_res.start = KDUMP_KERNELBASE; +#else + if (!crashk_res.start) { + /* + * unspecified address, choose a region of specified size + * can overlap with initrd (ignoring corruption when retained) + * ppc64 requires kernel and some stacks to be in first segemnt + */ + crashk_res.start = KDUMP_KERNELBASE; + } + + crash_base = PAGE_ALIGN(crashk_res.start); + if (crash_base != crashk_res.start) { + printk("Crash kernel base must be aligned to 0x%lx\n", + PAGE_SIZE); + crashk_res.start = crash_base; + } + #endif crash_size = PAGE_ALIGN(crash_size); crashk_res.end = crashk_res.start + crash_size - 1; + /* The crash region must not overlap the current kernel */ + if (overlaps_crashkernel(__pa(_stext), _end - _stext)) { + printk(KERN_WARNING + "Crash kernel can not overlap current kernel\n"); + crashk_res.start = crashk_res.end = 0; + return; + } + /* Crash kernel trumps memory limit */ if (memory_limit && memory_limit <= crashk_res.end) { memory_limit = crashk_res.end + 1; -- cgit From fe333321e2a71f706b794d55b6a3dcb5ab240f65 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 6 Jan 2009 14:26:03 +0000 Subject: powerpc: Change u64/s64 to a long long integer type Convert arch/powerpc/ over to long long based u64: -#ifdef __powerpc64__ -# include -#else -# include -#endif +#include This will avoid reoccuring spurious warnings in core kernel code that comes when people test on their own hardware. (i.e. x86 in ~98% of the cases) This is what x86 uses and it generally helps keep 64-bit code 32-bit clean too. [Adjusted to not impact user mode (from paulus) - sfr] Signed-off-by: Ingo Molnar Signed-off-by: Stephen Rothwell Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/rtas.h | 2 +- arch/powerpc/include/asm/types.h | 7 +++++- arch/powerpc/kernel/dma-iommu.c | 4 +-- arch/powerpc/kernel/iommu.c | 12 ++++----- arch/powerpc/kernel/lparcfg.c | 10 ++++---- arch/powerpc/kernel/setup_64.c | 6 ++--- arch/powerpc/mm/stab.c | 4 +-- arch/powerpc/oprofile/op_model_pa6t.c | 6 ++--- arch/powerpc/platforms/cell/beat_interrupt.c | 2 +- arch/powerpc/platforms/cell/celleb_scc_epci.c | 4 +-- arch/powerpc/platforms/cell/iommu.c | 4 +-- arch/powerpc/platforms/cell/ras.c | 8 +++--- arch/powerpc/platforms/cell/spu_base.c | 4 +-- arch/powerpc/platforms/cell/spu_callbacks.c | 2 +- arch/powerpc/platforms/iseries/iommu.c | 4 +-- arch/powerpc/platforms/pseries/iommu.c | 35 +++++++++++++-------------- arch/powerpc/sysdev/mpic.c | 2 +- drivers/net/pasemi_mac.c | 6 ++--- drivers/pcmcia/electra_cf.c | 2 +- drivers/scsi/ibmvscsi/ibmvscsi.c | 12 ++++----- 20 files changed, 70 insertions(+), 66 deletions(-) diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h index e0175beb446..0aa0315fb7e 100644 --- a/arch/powerpc/include/asm/rtas.h +++ b/arch/powerpc/include/asm/rtas.h @@ -18,7 +18,7 @@ */ #define RTAS_UNKNOWN_SERVICE (-1) -#define RTAS_INSTANTIATE_MAX (1UL<<30) /* Don't instantiate rtas at/above this value */ +#define RTAS_INSTANTIATE_MAX (1ULL<<30) /* Don't instantiate rtas at/above this value */ /* Buffer size for ppc_rtas system call. */ #define RTAS_RMOBUF_MAX (64 * 1024) diff --git a/arch/powerpc/include/asm/types.h b/arch/powerpc/include/asm/types.h index c004c13f291..7ce27a52bb3 100644 --- a/arch/powerpc/include/asm/types.h +++ b/arch/powerpc/include/asm/types.h @@ -1,7 +1,12 @@ #ifndef _ASM_POWERPC_TYPES_H #define _ASM_POWERPC_TYPES_H -#ifdef __powerpc64__ +/* + * This is here because we used to use l64 for 64bit powerpc + * and we don't want to impact user mode with our change to ll64 + * in the kernel. + */ +#if defined(__powerpc64__) && !defined(__KERNEL__) # include #else # include diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index 14183af1b3f..2983adac8cc 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c @@ -79,10 +79,10 @@ static int dma_iommu_dma_supported(struct device *dev, u64 mask) "Warning: IOMMU offset too big for device mask\n"); if (tbl) printk(KERN_INFO - "mask: 0x%08lx, table offset: 0x%08lx\n", + "mask: 0x%08llx, table offset: 0x%08lx\n", mask, tbl->it_offset); else - printk(KERN_INFO "mask: 0x%08lx, table unavailable\n", + printk(KERN_INFO "mask: 0x%08llx, table unavailable\n", mask); return 0; } else diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 1bfa706b96e..fd51578e29d 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -239,12 +239,12 @@ static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, if (printk_ratelimit()) { printk(KERN_INFO "iommu_free: invalid entry\n"); printk(KERN_INFO "\tentry = 0x%lx\n", entry); - printk(KERN_INFO "\tdma_addr = 0x%lx\n", (u64)dma_addr); - printk(KERN_INFO "\tTable = 0x%lx\n", (u64)tbl); - printk(KERN_INFO "\tbus# = 0x%lx\n", (u64)tbl->it_busno); - printk(KERN_INFO "\tsize = 0x%lx\n", (u64)tbl->it_size); - printk(KERN_INFO "\tstartOff = 0x%lx\n", (u64)tbl->it_offset); - printk(KERN_INFO "\tindex = 0x%lx\n", (u64)tbl->it_index); + printk(KERN_INFO "\tdma_addr = 0x%llx\n", (u64)dma_addr); + printk(KERN_INFO "\tTable = 0x%llx\n", (u64)tbl); + printk(KERN_INFO "\tbus# = 0x%llx\n", (u64)tbl->it_busno); + printk(KERN_INFO "\tsize = 0x%llx\n", (u64)tbl->it_size); + printk(KERN_INFO "\tstartOff = 0x%llx\n", (u64)tbl->it_offset); + printk(KERN_INFO "\tindex = 0x%llx\n", (u64)tbl->it_index); WARN_ON(1); } return; diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index d051e8cbcd0..182e0f642f3 100644 --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c @@ -240,7 +240,7 @@ static void parse_ppp_data(struct seq_file *m) if (rc) return; - seq_printf(m, "partition_entitled_capacity=%ld\n", + seq_printf(m, "partition_entitled_capacity=%lld\n", ppp_data.entitlement); seq_printf(m, "group=%d\n", ppp_data.group_num); seq_printf(m, "system_active_processors=%d\n", @@ -265,7 +265,7 @@ static void parse_ppp_data(struct seq_file *m) ppp_data.unallocated_weight); seq_printf(m, "capacity_weight=%d\n", ppp_data.weight); seq_printf(m, "capped=%d\n", ppp_data.capped); - seq_printf(m, "unallocated_capacity=%ld\n", + seq_printf(m, "unallocated_capacity=%lld\n", ppp_data.unallocated_entitlement); } @@ -509,10 +509,10 @@ static ssize_t update_ppp(u64 *entitlement, u8 *weight) } else return -EINVAL; - pr_debug("%s: current_entitled = %lu, current_weight = %u\n", + pr_debug("%s: current_entitled = %llu, current_weight = %u\n", __func__, ppp_data.entitlement, ppp_data.weight); - pr_debug("%s: new_entitled = %lu, new_weight = %u\n", + pr_debug("%s: new_entitled = %llu, new_weight = %u\n", __func__, new_entitled, new_weight); retval = plpar_hcall_norets(H_SET_PPP, new_entitled, new_weight); @@ -558,7 +558,7 @@ static ssize_t update_mpp(u64 *entitlement, u8 *weight) pr_debug("%s: current_entitled = %lu, current_weight = %u\n", __func__, mpp_data.entitled_mem, mpp_data.mem_weight); - pr_debug("%s: new_entitled = %lu, new_weight = %u\n", + pr_debug("%s: new_entitled = %llu, new_weight = %u\n", __func__, new_entitled, new_weight); rc = plpar_hcall_norets(H_SET_MPP, new_entitled, new_weight); diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index d8bd2161e73..2d34196bba8 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -434,8 +434,8 @@ void __init setup_system(void) printk("Starting Linux PPC64 %s\n", init_utsname()->version); printk("-----------------------------------------------------\n"); - printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size); - printk("physicalMemorySize = 0x%lx\n", lmb_phys_mem_size()); + printk("ppc64_pft_size = 0x%llx\n", ppc64_pft_size); + printk("physicalMemorySize = 0x%llx\n", lmb_phys_mem_size()); if (ppc64_caches.dline_size != 0x80) printk("ppc64_caches.dcache_line_size = 0x%x\n", ppc64_caches.dline_size); @@ -493,7 +493,7 @@ static void __init emergency_stack_init(void) * bringup, we need to get at them in real mode. This means they * must also be within the RMO region. */ - limit = min(0x10000000UL, lmb.rmo_size); + limit = min(0x10000000ULL, lmb.rmo_size); for_each_possible_cpu(i) { unsigned long sp; diff --git a/arch/powerpc/mm/stab.c b/arch/powerpc/mm/stab.c index 60e6032a808..98cd1dc2ae7 100644 --- a/arch/powerpc/mm/stab.c +++ b/arch/powerpc/mm/stab.c @@ -251,8 +251,8 @@ void __init stabs_alloc(void) paca[cpu].stab_addr = newstab; paca[cpu].stab_real = virt_to_abs(newstab); - printk(KERN_INFO "Segment table for CPU %d at 0x%lx " - "virtual, 0x%lx absolute\n", + printk(KERN_INFO "Segment table for CPU %d at 0x%llx " + "virtual, 0x%llx absolute\n", cpu, paca[cpu].stab_addr, paca[cpu].stab_real); } } diff --git a/arch/powerpc/oprofile/op_model_pa6t.c b/arch/powerpc/oprofile/op_model_pa6t.c index c40de461fd4..42f778dff91 100644 --- a/arch/powerpc/oprofile/op_model_pa6t.c +++ b/arch/powerpc/oprofile/op_model_pa6t.c @@ -132,7 +132,7 @@ static int pa6t_reg_setup(struct op_counter_config *ctr, for (pmc = 0; pmc < cur_cpu_spec->num_pmcs; pmc++) { /* counters are 40 bit. Move to cputable at some point? */ reset_value[pmc] = (0x1UL << 39) - ctr[pmc].count; - pr_debug("reset_value for pmc%u inited to 0x%lx\n", + pr_debug("reset_value for pmc%u inited to 0x%llx\n", pmc, reset_value[pmc]); } @@ -177,7 +177,7 @@ static int pa6t_start(struct op_counter_config *ctr) oprofile_running = 1; - pr_debug("start on cpu %d, mmcr0 %lx\n", smp_processor_id(), mmcr0); + pr_debug("start on cpu %d, mmcr0 %llx\n", smp_processor_id(), mmcr0); return 0; } @@ -193,7 +193,7 @@ static void pa6t_stop(void) oprofile_running = 0; - pr_debug("stop on cpu %d, mmcr0 %lx\n", smp_processor_id(), mmcr0); + pr_debug("stop on cpu %d, mmcr0 %llx\n", smp_processor_id(), mmcr0); } /* handle the perfmon overflow vector */ diff --git a/arch/powerpc/platforms/cell/beat_interrupt.c b/arch/powerpc/platforms/cell/beat_interrupt.c index 192a9350937..72254848a22 100644 --- a/arch/powerpc/platforms/cell/beat_interrupt.c +++ b/arch/powerpc/platforms/cell/beat_interrupt.c @@ -99,7 +99,7 @@ static void beatic_end_irq(unsigned int irq_plug) err = beat_downcount_of_interrupt(irq_plug); if (err != 0) { if ((err & 0xFFFFFFFF) != 0xFFFFFFF5) /* -11: wrong state */ - panic("Failed to downcount IRQ! Error = %16lx", err); + panic("Failed to downcount IRQ! Error = %16llx", err); printk(KERN_ERR "IRQ over-downcounted, plug %d\n", irq_plug); } diff --git a/arch/powerpc/platforms/cell/celleb_scc_epci.c b/arch/powerpc/platforms/cell/celleb_scc_epci.c index 08c285b10e3..48ec88a38a1 100644 --- a/arch/powerpc/platforms/cell/celleb_scc_epci.c +++ b/arch/powerpc/platforms/cell/celleb_scc_epci.c @@ -405,7 +405,7 @@ static int __init celleb_setup_epci(struct device_node *node, hose->cfg_addr = ioremap(r.start, (r.end - r.start + 1)); if (!hose->cfg_addr) goto error; - pr_debug("EPCI: cfg_addr map 0x%016lx->0x%016lx + 0x%016lx\n", + pr_debug("EPCI: cfg_addr map 0x%016llx->0x%016lx + 0x%016llx\n", r.start, (unsigned long)hose->cfg_addr, (r.end - r.start + 1)); if (of_address_to_resource(node, 2, &r)) @@ -413,7 +413,7 @@ static int __init celleb_setup_epci(struct device_node *node, hose->cfg_data = ioremap(r.start, (r.end - r.start + 1)); if (!hose->cfg_data) goto error; - pr_debug("EPCI: cfg_data map 0x%016lx->0x%016lx + 0x%016lx\n", + pr_debug("EPCI: cfg_data map 0x%016llx->0x%016lx + 0x%016llx\n", r.start, (unsigned long)hose->cfg_data, (r.end - r.start + 1)); hose->ops = &celleb_epci_ops; diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index 88d94b59a7c..ee5033eddf0 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -855,7 +855,7 @@ static int __init cell_iommu_init_disabled(void) */ if (np && size < lmb_end_of_DRAM()) { printk(KERN_WARNING "iommu: force-enabled, dma window" - " (%ldMB) smaller than total memory (%ldMB)\n", + " (%ldMB) smaller than total memory (%lldMB)\n", size >> 20, lmb_end_of_DRAM() >> 20); return -ENODEV; } @@ -985,7 +985,7 @@ static void cell_dma_dev_setup_fixed(struct device *dev) addr = cell_iommu_get_fixed_address(dev) + dma_iommu_fixed_base; archdata->dma_data = (void *)addr; - dev_dbg(dev, "iommu: fixed addr = %lx\n", addr); + dev_dbg(dev, "iommu: fixed addr = %llx\n", addr); } static void insert_16M_pte(unsigned long addr, unsigned long *ptab, diff --git a/arch/powerpc/platforms/cell/ras.c b/arch/powerpc/platforms/cell/ras.c index 7b4cefa2199..5f961c464cc 100644 --- a/arch/powerpc/platforms/cell/ras.c +++ b/arch/powerpc/platforms/cell/ras.c @@ -38,16 +38,16 @@ static void dump_fir(int cpu) /* Todo: do some nicer parsing of bits and based on them go down * to other sub-units FIRs and not only IIC */ - printk(KERN_ERR "Global Checkstop FIR : 0x%016lx\n", + printk(KERN_ERR "Global Checkstop FIR : 0x%016llx\n", in_be64(&pregs->checkstop_fir)); - printk(KERN_ERR "Global Recoverable FIR : 0x%016lx\n", + printk(KERN_ERR "Global Recoverable FIR : 0x%016llx\n", in_be64(&pregs->checkstop_fir)); - printk(KERN_ERR "Global MachineCheck FIR : 0x%016lx\n", + printk(KERN_ERR "Global MachineCheck FIR : 0x%016llx\n", in_be64(&pregs->spec_att_mchk_fir)); if (iregs == NULL) return; - printk(KERN_ERR "IOC FIR : 0x%016lx\n", + printk(KERN_ERR "IOC FIR : 0x%016llx\n", in_be64(&iregs->ioc_fir)); } diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index a5bdb89a17c..e487ad68ac1 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -151,7 +151,7 @@ static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb) { struct spu_priv2 __iomem *priv2 = spu->priv2; - pr_debug("%s: adding SLB[%d] 0x%016lx 0x%016lx\n", + pr_debug("%s: adding SLB[%d] 0x%016llx 0x%016llx\n", __func__, slbe, slb->vsid, slb->esid); out_be64(&priv2->slb_index_W, slbe); @@ -221,7 +221,7 @@ static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr) { int ret; - pr_debug("%s, %lx, %lx\n", __func__, dsisr, ea); + pr_debug("%s, %llx, %lx\n", __func__, dsisr, ea); /* * Handle kernel space hash faults immediately. User hash diff --git a/arch/powerpc/platforms/cell/spu_callbacks.c b/arch/powerpc/platforms/cell/spu_callbacks.c index 19f6bfdbb93..fec1495e6b1 100644 --- a/arch/powerpc/platforms/cell/spu_callbacks.c +++ b/arch/powerpc/platforms/cell/spu_callbacks.c @@ -54,7 +54,7 @@ long spu_sys_callback(struct spu_syscall_block *s) long (*syscall)(u64 a1, u64 a2, u64 a3, u64 a4, u64 a5, u64 a6); if (s->nr_ret >= ARRAY_SIZE(spu_syscall_table)) { - pr_debug("%s: invalid syscall #%ld", __func__, s->nr_ret); + pr_debug("%s: invalid syscall #%lld", __func__, s->nr_ret); return -ENOSYS; } diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index bbe828f1b88..6ed75bffc8a 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c @@ -66,7 +66,7 @@ static int tce_build_iSeries(struct iommu_table *tbl, long index, long npages, rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, tce); if (rc) - panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", + panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%llx\n", rc); index++; uaddr += TCE_PAGE_SIZE; @@ -81,7 +81,7 @@ static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages) while (npages--) { rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, 0); if (rc) - panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", + panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%llx\n", rc); index++; } diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index c90817acb47..3ee01b4f425 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -127,10 +127,10 @@ static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum, } if (rc && printk_ratelimit()) { - printk("tce_build_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc); - printk("\tindex = 0x%lx\n", (u64)tbl->it_index); - printk("\ttcenum = 0x%lx\n", (u64)tcenum); - printk("\ttce val = 0x%lx\n", tce ); + printk("tce_build_pSeriesLP: plpar_tce_put failed. rc=%lld\n", rc); + printk("\tindex = 0x%llx\n", (u64)tbl->it_index); + printk("\ttcenum = 0x%llx\n", (u64)tcenum); + printk("\ttce val = 0x%llx\n", tce ); show_stack(current, (unsigned long *)__get_SP()); } @@ -210,10 +210,10 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, } if (rc && printk_ratelimit()) { - printk("tce_buildmulti_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc); - printk("\tindex = 0x%lx\n", (u64)tbl->it_index); - printk("\tnpages = 0x%lx\n", (u64)npages); - printk("\ttce[0] val = 0x%lx\n", tcep[0]); + printk("tce_buildmulti_pSeriesLP: plpar_tce_put failed. rc=%lld\n", rc); + printk("\tindex = 0x%llx\n", (u64)tbl->it_index); + printk("\tnpages = 0x%llx\n", (u64)npages); + printk("\ttce[0] val = 0x%llx\n", tcep[0]); show_stack(current, (unsigned long *)__get_SP()); } return ret; @@ -227,9 +227,9 @@ static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, 0); if (rc && printk_ratelimit()) { - printk("tce_free_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc); - printk("\tindex = 0x%lx\n", (u64)tbl->it_index); - printk("\ttcenum = 0x%lx\n", (u64)tcenum); + printk("tce_free_pSeriesLP: plpar_tce_put failed. rc=%lld\n", rc); + printk("\tindex = 0x%llx\n", (u64)tbl->it_index); + printk("\ttcenum = 0x%llx\n", (u64)tcenum); show_stack(current, (unsigned long *)__get_SP()); } @@ -246,9 +246,9 @@ static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long n if (rc && printk_ratelimit()) { printk("tce_freemulti_pSeriesLP: plpar_tce_stuff failed\n"); - printk("\trc = %ld\n", rc); - printk("\tindex = 0x%lx\n", (u64)tbl->it_index); - printk("\tnpages = 0x%lx\n", (u64)npages); + printk("\trc = %lld\n", rc); + printk("\tindex = 0x%llx\n", (u64)tbl->it_index); + printk("\tnpages = 0x%llx\n", (u64)npages); show_stack(current, (unsigned long *)__get_SP()); } } @@ -261,10 +261,9 @@ static unsigned long tce_get_pSeriesLP(struct iommu_table *tbl, long tcenum) rc = plpar_tce_get((u64)tbl->it_index, (u64)tcenum << 12, &tce_ret); if (rc && printk_ratelimit()) { - printk("tce_get_pSeriesLP: plpar_tce_get failed. rc=%ld\n", - rc); - printk("\tindex = 0x%lx\n", (u64)tbl->it_index); - printk("\ttcenum = 0x%lx\n", (u64)tcenum); + printk("tce_get_pSeriesLP: plpar_tce_get failed. rc=%lld\n", rc); + printk("\tindex = 0x%llx\n", (u64)tbl->it_index); + printk("\ttcenum = 0x%llx\n", (u64)tcenum); show_stack(current, (unsigned long *)__get_SP()); } diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 3e0d89dcdba..a35297dbac2 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -435,7 +435,7 @@ static void __init mpic_scan_ht_msi(struct mpic *mpic, u8 __iomem *devbase, addr = addr | ((u64)readl(base + HT_MSI_ADDR_HI) << 32); } - printk(KERN_DEBUG "mpic: - HT:%02x.%x %s MSI mapping found @ 0x%lx\n", + printk(KERN_DEBUG "mpic: - HT:%02x.%x %s MSI mapping found @ 0x%llx\n", PCI_SLOT(devfn), PCI_FUNC(devfn), flags & HT_MSI_FLAGS_ENABLE ? "enabled" : "disabled", addr); diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 5b7a574ce57..d0349e7d73e 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -712,7 +712,7 @@ static inline void pasemi_mac_rx_error(const struct pasemi_mac *mac, rcmdsta = read_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if)); ccmdsta = read_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(chan->chno)); - printk(KERN_ERR "pasemi_mac: rx error. macrx %016lx, rx status %lx\n", + printk(KERN_ERR "pasemi_mac: rx error. macrx %016llx, rx status %llx\n", macrx, *chan->status); printk(KERN_ERR "pasemi_mac: rcmdsta %08x ccmdsta %08x\n", @@ -730,8 +730,8 @@ static inline void pasemi_mac_tx_error(const struct pasemi_mac *mac, cmdsta = read_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(chan->chno)); - printk(KERN_ERR "pasemi_mac: tx error. mactx 0x%016lx, "\ - "tx status 0x%016lx\n", mactx, *chan->status); + printk(KERN_ERR "pasemi_mac: tx error. mactx 0x%016llx, "\ + "tx status 0x%016llx\n", mactx, *chan->status); printk(KERN_ERR "pasemi_mac: tcmdsta 0x%08x\n", cmdsta); } diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c index a34284b1482..d187ba4c5e0 100644 --- a/drivers/pcmcia/electra_cf.c +++ b/drivers/pcmcia/electra_cf.c @@ -297,7 +297,7 @@ static int __devinit electra_cf_probe(struct of_device *ofdev, goto fail3; } - dev_info(device, "at mem 0x%lx io 0x%lx irq %d\n", + dev_info(device, "at mem 0x%lx io 0x%llx irq %d\n", cf->mem_phys, io.start, cf->irq); cf->active = 1; diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 5c541f7850f..74d07d137da 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -1061,7 +1061,7 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd) } sdev_printk(KERN_INFO, cmd->device, - "aborting command. lun 0x%lx, tag 0x%lx\n", + "aborting command. lun 0x%llx, tag 0x%llx\n", (((u64) lun) << 48), (u64) found_evt); wait_for_completion(&evt->comp); @@ -1082,7 +1082,7 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd) if (rsp_rc) { if (printk_ratelimit()) sdev_printk(KERN_WARNING, cmd->device, - "abort code %d for task tag 0x%lx\n", + "abort code %d for task tag 0x%llx\n", rsp_rc, tsk_mgmt->task_tag); return FAILED; } @@ -1102,12 +1102,12 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd) if (found_evt == NULL) { spin_unlock_irqrestore(hostdata->host->host_lock, flags); - sdev_printk(KERN_INFO, cmd->device, "aborted task tag 0x%lx completed\n", + sdev_printk(KERN_INFO, cmd->device, "aborted task tag 0x%llx completed\n", tsk_mgmt->task_tag); return SUCCESS; } - sdev_printk(KERN_INFO, cmd->device, "successfully aborted task tag 0x%lx\n", + sdev_printk(KERN_INFO, cmd->device, "successfully aborted task tag 0x%llx\n", tsk_mgmt->task_tag); cmd->result = (DID_ABORT << 16); @@ -1182,7 +1182,7 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd) return FAILED; } - sdev_printk(KERN_INFO, cmd->device, "resetting device. lun 0x%lx\n", + sdev_printk(KERN_INFO, cmd->device, "resetting device. lun 0x%llx\n", (((u64) lun) << 48)); wait_for_completion(&evt->comp); @@ -1203,7 +1203,7 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd) if (rsp_rc) { if (printk_ratelimit()) sdev_printk(KERN_WARNING, cmd->device, - "reset code %d for task tag 0x%lx\n", + "reset code %d for task tag 0x%llx\n", rsp_rc, tsk_mgmt->task_tag); return FAILED; } -- cgit From 9477e455b4b3ded3e7add8c96d8293105947eaac Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 6 Jan 2009 14:27:38 +0000 Subject: powerpc: Cleanup from l64 to ll64 change: arch code Signed-off-by: Stephen Rothwell Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/pci_64.c | 6 +++--- arch/powerpc/platforms/cell/spufs/coredump.c | 2 +- arch/powerpc/platforms/cell/spufs/fault.c | 2 +- arch/powerpc/platforms/cell/spufs/file.c | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 586962f65c2..ea8eda8c87c 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -470,7 +470,7 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus) if (bus->self) { pr_debug("IO mapping for PCI-PCI bridge %s\n", pci_name(bus->self)); - pr_debug(" virt=0x%016lx...0x%016lx\n", + pr_debug(" virt=0x%016llx...0x%016llx\n", bus->resource[0]->start + _IO_BASE, bus->resource[0]->end + _IO_BASE); return 0; @@ -502,7 +502,7 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus) hose->io_base_phys - phys_page); pr_debug("IO mapping for PHB %s\n", hose->dn->full_name); - pr_debug(" phys=0x%016lx, virt=0x%p (alloc=0x%p)\n", + pr_debug(" phys=0x%016llx, virt=0x%p (alloc=0x%p)\n", hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc); pr_debug(" size=0x%016lx (alloc=0x%016lx)\n", hose->pci_io_size, size_page); @@ -517,7 +517,7 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus) hose->io_resource.start += io_virt_offset; hose->io_resource.end += io_virt_offset; - pr_debug(" hose->io_resource=0x%016lx...0x%016lx\n", + pr_debug(" hose->io_resource=0x%016llx...0x%016llx\n", hose->io_resource.start, hose->io_resource.end); return 0; diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c index af116aadba1..c4d4a19235e 100644 --- a/arch/powerpc/platforms/cell/spufs/coredump.c +++ b/arch/powerpc/platforms/cell/spufs/coredump.c @@ -42,7 +42,7 @@ static ssize_t do_coredump_read(int num, struct spu_context *ctx, void *buffer, return spufs_coredump_read[num].read(ctx, buffer, size, off); data = spufs_coredump_read[num].get(ctx); - ret = snprintf(buffer, size, "0x%.16lx", data); + ret = snprintf(buffer, size, "0x%.16llx", data); if (ret >= size) return size; return ++ret; /* count trailing NULL */ diff --git a/arch/powerpc/platforms/cell/spufs/fault.c b/arch/powerpc/platforms/cell/spufs/fault.c index f093a581ac7..a4dd3ae7223 100644 --- a/arch/powerpc/platforms/cell/spufs/fault.c +++ b/arch/powerpc/platforms/cell/spufs/fault.c @@ -132,7 +132,7 @@ int spufs_handle_class1(struct spu_context *ctx) spuctx_switch_state(ctx, SPU_UTIL_IOWAIT); - pr_debug("ctx %p: ea %016lx, dsisr %016lx state %d\n", ctx, ea, + pr_debug("ctx %p: ea %016llx, dsisr %016llx state %d\n", ctx, ea, dsisr, ctx->state); ctx->stats.hash_flt++; diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 7106b63d401..0da7f2bf5ee 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -1654,7 +1654,7 @@ out: static int spufs_check_valid_dma(struct mfc_dma_command *cmd) { - pr_debug("queueing DMA %x %lx %x %x %x\n", cmd->lsa, + pr_debug("queueing DMA %x %llx %x %x %x\n", cmd->lsa, cmd->ea, cmd->size, cmd->tag, cmd->cmd); switch (cmd->cmd) { @@ -1671,7 +1671,7 @@ static int spufs_check_valid_dma(struct mfc_dma_command *cmd) } if ((cmd->lsa & 0xf) != (cmd->ea &0xf)) { - pr_debug("invalid DMA alignment, ea %lx lsa %x\n", + pr_debug("invalid DMA alignment, ea %llx lsa %x\n", cmd->ea, cmd->lsa); return -EIO; } @@ -2633,7 +2633,7 @@ static int spufs_show_ctx(struct seq_file *s, void *private) } seq_printf(s, "%c flgs(%lx) sflgs(%lx) pri(%d) ts(%d) spu(%02d)" - " %c %lx %lx %lx %lx %x %x\n", + " %c %llx %llx %llx %llx %x %x\n", ctx->state == SPU_STATE_SAVED ? 'S' : 'R', ctx->flags, ctx->sched_flags, -- cgit From 1901515c79f13d9a1913d246b6c0711318dadb4c Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 6 Jan 2009 14:28:48 +0000 Subject: powerpc: Cleanup from l64 to ll64 change: drivers/char This is a powerpc specific driver. Signed-off-by: Stephen Rothwell Signed-off-by: Benjamin Herrenschmidt --- drivers/char/bsr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c index 977dfb1096a..f6094ae0ef3 100644 --- a/drivers/char/bsr.c +++ b/drivers/char/bsr.c @@ -103,7 +103,7 @@ static ssize_t bsr_len_show(struct device *dev, struct device_attribute *attr, char *buf) { struct bsr_dev *bsr_dev = dev_get_drvdata(dev); - return sprintf(buf, "%lu\n", bsr_dev->bsr_len); + return sprintf(buf, "%llu\n", bsr_dev->bsr_len); } static struct device_attribute bsr_dev_attrs[] = { -- cgit From a1c5a8932bbb75b550deb156d890027827fc9d6e Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 6 Jan 2009 14:40:06 +0000 Subject: powerpc: Cleanup from l64 to ll64 change: drivers/net These are powerpc specific drivers. Signed-off-by: Stephen Rothwell Acked-by: David S. Miller Signed-off-by: Benjamin Herrenschmidt --- drivers/net/ehea/ehea_main.c | 8 ++++---- drivers/net/ehea/ehea_qmr.c | 18 +++++++++--------- drivers/net/ibmveth.c | 16 ++++++++-------- drivers/net/iseries_veth.c | 2 +- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index e3131ea629c..dfe92264e82 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -132,7 +132,7 @@ void ehea_dump(void *adr, int len, char *msg) int x; unsigned char *deb = adr; for (x = 0; x < len; x += 16) { - printk(DRV_NAME " %s adr=%p ofs=%04x %016lx %016lx\n", msg, + printk(DRV_NAME " %s adr=%p ofs=%04x %016llx %016llx\n", msg, deb, x, *((u64 *)&deb[0]), *((u64 *)&deb[8])); deb += 16; } @@ -883,7 +883,7 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param) while (eqe) { qp_token = EHEA_BMASK_GET(EHEA_EQE_QP_TOKEN, eqe->entry); - ehea_error("QP aff_err: entry=0x%lx, token=0x%x", + ehea_error("QP aff_err: entry=0x%llx, token=0x%x", eqe->entry, qp_token); qp = port->port_res[qp_token].qp; @@ -1159,7 +1159,7 @@ static void ehea_parse_eqe(struct ehea_adapter *adapter, u64 eqe) netif_stop_queue(port->netdev); break; default: - ehea_error("unknown event code %x, eqe=0x%lX", ec, eqe); + ehea_error("unknown event code %x, eqe=0x%llX", ec, eqe); break; } } @@ -1971,7 +1971,7 @@ static void ehea_set_multicast_list(struct net_device *dev) } if (dev->mc_count > port->adapter->max_mc_mac) { - ehea_info("Mcast registration limit reached (0x%lx). " + ehea_info("Mcast registration limit reached (0x%llx). " "Use ALLMULTI!", port->adapter->max_mc_mac); goto out; diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c index 225c692b5d9..49d766ebbcf 100644 --- a/drivers/net/ehea/ehea_qmr.c +++ b/drivers/net/ehea/ehea_qmr.c @@ -168,7 +168,7 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, cq->fw_handle, rpage, 1); if (hret < H_SUCCESS) { ehea_error("register_rpage_cq failed ehea_cq=%p " - "hret=%lx counter=%i act_pages=%i", + "hret=%llx counter=%i act_pages=%i", cq, hret, counter, cq->attr.nr_pages); goto out_kill_hwq; } @@ -178,13 +178,13 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, if ((hret != H_SUCCESS) || (vpage)) { ehea_error("registration of pages not " - "complete hret=%lx\n", hret); + "complete hret=%llx\n", hret); goto out_kill_hwq; } } else { if (hret != H_PAGE_REGISTERED) { ehea_error("CQ: registration of page failed " - "hret=%lx\n", hret); + "hret=%llx\n", hret); goto out_kill_hwq; } } @@ -986,15 +986,15 @@ void print_error_data(u64 *data) length = EHEA_PAGESIZE; if (type == 0x8) /* Queue Pair */ - ehea_error("QP (resource=%lX) state: AER=0x%lX, AERR=0x%lX, " - "port=%lX", resource, data[6], data[12], data[22]); + ehea_error("QP (resource=%llX) state: AER=0x%llX, AERR=0x%llX, " + "port=%llX", resource, data[6], data[12], data[22]); if (type == 0x4) /* Completion Queue */ - ehea_error("CQ (resource=%lX) state: AER=0x%lX", resource, + ehea_error("CQ (resource=%llX) state: AER=0x%llX", resource, data[6]); if (type == 0x3) /* Event Queue */ - ehea_error("EQ (resource=%lX) state: AER=0x%lX", resource, + ehea_error("EQ (resource=%llX) state: AER=0x%llX", resource, data[6]); ehea_dump(data, length, "error data"); @@ -1016,11 +1016,11 @@ void ehea_error_data(struct ehea_adapter *adapter, u64 res_handle) rblock); if (ret == H_R_STATE) - ehea_error("No error data is available: %lX.", res_handle); + ehea_error("No error data is available: %llX.", res_handle); else if (ret == H_SUCCESS) print_error_data(rblock); else - ehea_error("Error data could not be fetched: %lX", res_handle); + ehea_error("Error data could not be fetched: %llX", res_handle); kfree(rblock); } diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index ca3bb9f7321..dfa6348ac1d 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -602,7 +602,7 @@ static int ibmveth_open(struct net_device *netdev) if(lpar_rc != H_SUCCESS) { ibmveth_error_printk("h_register_logical_lan failed with %ld\n", lpar_rc); - ibmveth_error_printk("buffer TCE:0x%lx filter TCE:0x%lx rxq desc:0x%lx MAC:0x%lx\n", + ibmveth_error_printk("buffer TCE:0x%llx filter TCE:0x%llx rxq desc:0x%llx MAC:0x%llx\n", adapter->buffer_list_dma, adapter->filter_list_dma, rxq_desc.desc, @@ -1378,13 +1378,13 @@ static int ibmveth_show(struct seq_file *seq, void *v) seq_printf(seq, "Firmware MAC: %pM\n", firmware_mac); seq_printf(seq, "\nAdapter Statistics:\n"); - seq_printf(seq, " TX: vio_map_single failres: %ld\n", adapter->tx_map_failed); - seq_printf(seq, " send failures: %ld\n", adapter->tx_send_failed); - seq_printf(seq, " RX: replenish task cycles: %ld\n", adapter->replenish_task_cycles); - seq_printf(seq, " alloc_skb_failures: %ld\n", adapter->replenish_no_mem); - seq_printf(seq, " add buffer failures: %ld\n", adapter->replenish_add_buff_failure); - seq_printf(seq, " invalid buffers: %ld\n", adapter->rx_invalid_buffer); - seq_printf(seq, " no buffers: %ld\n", adapter->rx_no_buffer); + seq_printf(seq, " TX: vio_map_single failres: %lld\n", adapter->tx_map_failed); + seq_printf(seq, " send failures: %lld\n", adapter->tx_send_failed); + seq_printf(seq, " RX: replenish task cycles: %lld\n", adapter->replenish_task_cycles); + seq_printf(seq, " alloc_skb_failures: %lld\n", adapter->replenish_no_mem); + seq_printf(seq, " add buffer failures: %lld\n", adapter->replenish_add_buff_failure); + seq_printf(seq, " invalid buffers: %lld\n", adapter->rx_invalid_buffer); + seq_printf(seq, " no buffers: %lld\n", adapter->rx_no_buffer); return 0; } diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index c7457f97259..cb793c2bade 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -429,7 +429,7 @@ SIMPLE_PORT_ATTR(promiscuous); SIMPLE_PORT_ATTR(num_mcast); CUSTOM_PORT_ATTR(lpar_map, "0x%X\n", port->lpar_map); CUSTOM_PORT_ATTR(stopped_map, "0x%X\n", port->stopped_map); -CUSTOM_PORT_ATTR(mac_addr, "0x%lX\n", port->mac_addr); +CUSTOM_PORT_ATTR(mac_addr, "0x%llX\n", port->mac_addr); #define GET_PORT_ATTR(_name) (&veth_port_attr_##_name.attr) static struct attribute *veth_port_default_attrs[] = { -- cgit From 9fef3d2d15ae8ca24e4a145f2e189eea145d18c2 Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Thu, 8 Jan 2009 02:14:18 +0000 Subject: hvc_console: Change an mb() to smp_mb() and add some comments I remember some history on this barrier. There was a race between open via /dev/console and the tty being fully setup. Its also why there is a temporary variable and the global is assigned at the end of the function. Signed-off-by: Milton Miller Signed-off-by: Benjamin Herrenschmidt --- drivers/char/hvc_console.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 5a8a4c28c86..f2685b747fb 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c @@ -876,8 +876,11 @@ static int hvc_init(void) goto stop_thread; } - /* FIXME: This mb() seems completely random. Remove it. */ - mb(); + /* + * Make sure tty is fully registered before allowing it to be + * found by hvc_console_device. + */ + smp_mb(); hvc_driver = drv; return 0; -- cgit From c21f7a527f7757a0e246cea521a5dd3b8e1224d5 Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Thu, 8 Jan 2009 02:14:21 +0000 Subject: hvc_console: Call free_irq() only if request_irq() was successful Only call free_irq if we marked the request_irq has having succeeded instead of whenever the the sub-driver identified the interrupt to use. Signed-off-by: Milton Miller Signed-off-by: Benjamin Herrenschmidt --- drivers/char/hvc_irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/hvc_irq.c b/drivers/char/hvc_irq.c index d09e5688d44..2623e177e8d 100644 --- a/drivers/char/hvc_irq.c +++ b/drivers/char/hvc_irq.c @@ -37,7 +37,7 @@ int notifier_add_irq(struct hvc_struct *hp, int irq) void notifier_del_irq(struct hvc_struct *hp, int irq) { - if (!irq) + if (!hp->irq_requested) return; free_irq(irq, hp); hp->irq_requested = 0; -- cgit From da9dc13289fa58dced12f2baff51dfb87c339ba3 Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Thu, 8 Jan 2009 02:14:24 +0000 Subject: hvc_console: Do not set low_latency when using interrupts hvc_console is setting low_latency unconditionally, but some clients are interrupt driven and will call hvc_poll from irq context. This will cause tty_flip_buffer_push to be called from irq context, and it very clearly states it must not be called from IRQ when low_latency is specified. Looking back through history: v2.6.16-rc1 via 33f0f88f1c51ae5c2d593d26960c760ea154c2e2 [PATCH] TTY layer buffering revamp added this new api. v2.6.16-rc3 via 8977d929e49021d9a6e031310aab01fa72f849c2 [PATCH] tty buffering stall fix claims to fix a stall discovered with hvc_console v2.6.16-rc5 via fb5c594c2acc441f0d2d8f457484a0e0e9285db3 [PATCH] Fix race condition in hvc console. said set this flag to avoid a stall problem, and was merged through the powerpc arch tree. Without searching for email discussions, it would appear to be an overlapping "fix", but one that did not consider all users. Signed-off-by: Benjamin Herrenschmidt --- drivers/char/hvc_console.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index f2685b747fb..0e18fdb9ddd 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c @@ -318,7 +318,8 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) } /* else count == 0 */ tty->driver_data = hp; - tty->low_latency = 1; /* Makes flushes to ldisc synchronous. */ + if (!hp->irq_requested) + tty->low_latency = 1; /* Makes flushes to ldisc synchronous. */ hp->tty = tty; -- cgit From 2da7582f7cf5ef5e6adcf42537b6b8be06312152 Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Thu, 8 Jan 2009 02:14:28 +0000 Subject: hvc_console: Use kzalloc() instead of kmalloc() + memset() Replace kmalloc() + memset() with kzalloc(). Signed-off-by: Milton Miller Signed-off-by: Benjamin Herrenschmidt --- drivers/char/hvc_console.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 0e18fdb9ddd..09676b4e5d8 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c @@ -765,13 +765,11 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int data, return ERR_PTR(err); } - hp = kmalloc(ALIGN(sizeof(*hp), sizeof(long)) + outbuf_size, + hp = kzalloc(ALIGN(sizeof(*hp), sizeof(long)) + outbuf_size, GFP_KERNEL); if (!hp) return ERR_PTR(-ENOMEM); - memset(hp, 0x00, sizeof(*hp)); - hp->vtermno = vtermno; hp->data = data; hp->ops = ops; -- cgit From fc7a9feb9c9df50ed6d115514b48c49e8511a4de Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Fri, 9 Jan 2009 13:12:44 +0000 Subject: powerpc/cacheinfo: Rename cache_dir per-cpu variable The per_cpu__ prefix on DECLARE_PER_CPU'd variables is going away; rename cache_dir to cache_dir_pcpu. Signed-off-by: Nathan Lynch Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/cacheinfo.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/kernel/cacheinfo.c b/arch/powerpc/kernel/cacheinfo.c index b33f0417a4b..bb37b1d19a5 100644 --- a/arch/powerpc/kernel/cacheinfo.c +++ b/arch/powerpc/kernel/cacheinfo.c @@ -113,7 +113,7 @@ struct cache { struct cache *next_local; /* next cache of >= level */ }; -static DEFINE_PER_CPU(struct cache_dir *, cache_dir); +static DEFINE_PER_CPU(struct cache_dir *, cache_dir_pcpu); /* traversal/modification of this list occurs only at cpu hotplug time; * access is serialized by cpu hotplug locking @@ -468,9 +468,9 @@ static struct cache_dir *__cpuinit cacheinfo_create_cache_dir(unsigned int cpu_i cache_dir->kobj = kobj; - WARN_ON_ONCE(per_cpu(cache_dir, cpu_id) != NULL); + WARN_ON_ONCE(per_cpu(cache_dir_pcpu, cpu_id) != NULL); - per_cpu(cache_dir, cpu_id) = cache_dir; + per_cpu(cache_dir_pcpu, cpu_id) = cache_dir; return cache_dir; err: @@ -820,13 +820,13 @@ void cacheinfo_cpu_offline(unsigned int cpu_id) /* Prevent userspace from seeing inconsistent state - remove * the sysfs hierarchy first */ - cache_dir = per_cpu(cache_dir, cpu_id); + cache_dir = per_cpu(cache_dir_pcpu, cpu_id); /* careful, sysfs population may have failed */ if (cache_dir) remove_cache_dir(cache_dir); - per_cpu(cache_dir, cpu_id) = NULL; + per_cpu(cache_dir_pcpu, cpu_id) = NULL; /* clear the CPU's bit in its cache chain, possibly freeing * cache objects */ -- cgit From c478b58135e6c9b49c8b80bff8ef910f2ba9b313 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sun, 11 Jan 2009 19:03:45 +0000 Subject: powerpc/powermac: Fix occasional SMP boot failure The PowerMac kernel occasionally fails to bring up the secondary CPUs on SMP, the trigger factor seem to be fairly random and related to location of code and data. This appears to be due to the initial loading of the TOC value by the secondary processor which now happens before we clear HID4:RM_CI (Real Mode Cache Invalidate). This bit should really be cleared before we do any load or store other than fetching code. This fix works based on the assumption that all SMP 64-bit PowerMacs use variants of the 970, which fortunately is true, by explicitely clearing that bit, adding an slbia for good measure as RM_CI mode is known to create bogus ERAT entries. I also removed some spurrious debug output that was left enabled by mistake while at it. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/head_64.S | 9 +++++++++ arch/powerpc/platforms/powermac/smp.c | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index b4bcf5a930f..ebaedafc8e6 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -1518,6 +1518,15 @@ _GLOBAL(pmac_secondary_start) /* turn on 64-bit mode */ bl .enable_64b_mode + li r0,0 + mfspr r3,SPRN_HID4 + rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ + sync + mtspr SPRN_HID4,r3 + isync + sync + slbia + /* get TOC pointer (real address) */ bl .relative_toc diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index 6b0711c15ec..bd8817b00fa 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c @@ -53,7 +53,7 @@ #include #include -#define DEBUG +#undef DEBUG #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) -- cgit From 061b908cf888c1bfd3dd1b91ce6f676e3bc42633 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Mon, 12 Jan 2009 16:30:00 +0000 Subject: powerpc: Enable PS3 options and QPACE in ppc64_defconfig To increase the amount of code that's built for a defconfig build. Signed-off-by: Michael Ellerman Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/configs/ppc64_defconfig | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index 069ae1bbac2..d4685d1c0be 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig @@ -211,11 +211,28 @@ CONFIG_PPC_PASEMI=y CONFIG_PPC_PASEMI_IOMMU=y # CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE is not set CONFIG_PPC_PASEMI_MDIO=y -# CONFIG_PPC_PS3 is not set +CONFIG_PPC_PS3=y + +# +# PS3 Platform Options +# +# CONFIG_PS3_ADVANCED is not set +CONFIG_PS3_HTAB_SIZE=20 +# CONFIG_PS3_DYNAMIC_DMA is not set +CONFIG_PS3_VUART=y +CONFIG_PS3_PS3AV=y +CONFIG_PS3_SYS_MANAGER=y +CONFIG_PS3_STORAGE=m +CONFIG_PS3_DISK=m +CONFIG_PS3_ROM=m +CONFIG_PS3_FLASH=m +CONFIG_PS3_LPM=m CONFIG_PPC_CELL=y +CONFIG_PPC_CELL_COMMON=y CONFIG_PPC_CELL_NATIVE=y CONFIG_PPC_IBM_CELL_BLADE=y CONFIG_PPC_CELLEB=y +CONFIG_PPC_CELL_QPACE=y # # Cell Broadband Engine options @@ -981,6 +998,9 @@ CONFIG_E1000=y CONFIG_TIGON3=y # CONFIG_BNX2 is not set CONFIG_SPIDER_NET=m +CONFIG_GELIC_NET=m +CONFIG_GELIC_WIRELESS=y +# CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE is not set # CONFIG_QLA3XXX is not set # CONFIG_ATL1 is not set # CONFIG_ATL1E is not set @@ -1370,6 +1390,8 @@ CONFIG_FB_RADEON_BACKLIGHT=y # CONFIG_FB_PM3 is not set # CONFIG_FB_CARMINE is not set CONFIG_FB_IBM_GXT4500=y +CONFIG_FB_PS3=m +CONFIG_FB_PS3_DEFAULT_SIZE_M=9 # CONFIG_FB_VIRTUAL is not set # CONFIG_FB_METRONOME is not set CONFIG_BACKLIGHT_LCD_SUPPORT=y @@ -1492,6 +1514,8 @@ CONFIG_SND_PCI=y CONFIG_SND_PPC=y CONFIG_SND_POWERMAC=m CONFIG_SND_POWERMAC_AUTO_DRC=y +CONFIG_SND_PS3=m +CONFIG_SND_PS3_DEFAULT_START_DELAY=2000 CONFIG_SND_AOA=m CONFIG_SND_AOA_FABRIC_LAYOUT=m CONFIG_SND_AOA_ONYX=m -- cgit From d9736749f581abd80c2831244e2659e2e833b0e3 Mon Sep 17 00:00:00 2001 From: Krzysztof Hałasa Date: Mon, 12 Jan 2009 16:31:54 -0800 Subject: WAN: Fix NAPI interface in IXP4xx HSS driver. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Krzysztof Hałasa Signed-off-by: David S. Miller --- drivers/net/wan/ixp4xx_hss.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c index 2dc241689d3..0dbd85b0162 100644 --- a/drivers/net/wan/ixp4xx_hss.c +++ b/drivers/net/wan/ixp4xx_hss.c @@ -622,7 +622,7 @@ static void hss_hdlc_rx_irq(void *pdev) printk(KERN_DEBUG "%s: hss_hdlc_rx_irq\n", dev->name); #endif qmgr_disable_irq(queue_ids[port->id].rx); - netif_rx_schedule(dev, &port->napi); + netif_rx_schedule(&port->napi); } static int hss_hdlc_poll(struct napi_struct *napi, int budget) @@ -651,7 +651,7 @@ static int hss_hdlc_poll(struct napi_struct *napi, int budget) printk(KERN_DEBUG "%s: hss_hdlc_poll" " netif_rx_complete\n", dev->name); #endif - netif_rx_complete(dev, napi); + netif_rx_complete(napi); qmgr_enable_irq(rxq); if (!qmgr_stat_empty(rxq) && netif_rx_reschedule(napi)) { @@ -1069,7 +1069,7 @@ static int hss_hdlc_open(struct net_device *dev) hss_start_hdlc(port); /* we may already have RX data, enables IRQ */ - netif_rx_schedule(dev, &port->napi); + netif_rx_schedule(&port->napi); return 0; err_unlock: -- cgit From 985ebdb5ed54151eba734aa1b307460e8e4267ba Mon Sep 17 00:00:00 2001 From: Krzysztof Hałasa Date: Mon, 12 Jan 2009 16:32:13 -0800 Subject: net: Fix a comment in include/linux/netdevice.h. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix a comment in include/linux/netdevice.h. Signed-off-by: Krzysztof Hałasa Signed-off-by: David S. Miller --- include/linux/netdevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index f2455681337..4647604c7ca 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -467,7 +467,7 @@ struct netdev_queue { * This function is called when network device transistions to the down * state. * - * int (*ndo_hard_start_xmit)(struct sk_buff *skb, struct net_device *dev); + * int (*ndo_start_xmit)(struct sk_buff *skb, struct net_device *dev); * Called when a packet needs to be transmitted. * Must return NETDEV_TX_OK , NETDEV_TX_BUSY, or NETDEV_TX_LOCKED, * Required can not be NULL. -- cgit From 88843104a19d5896bf67ab6bd685e976240dd04a Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 12 Jan 2009 00:06:00 +0000 Subject: netfilter 01/09: remove "happy cracking" message Don't spam logs for locally generated short packets. these can only be generated by root. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv4/netfilter/iptable_filter.c | 7 +------ net/ipv4/netfilter/iptable_mangle.c | 6 +----- net/ipv4/netfilter/iptable_raw.c | 6 +----- net/ipv4/netfilter/iptable_security.c | 6 +----- net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 5 +---- 5 files changed, 5 insertions(+), 25 deletions(-) diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c index c9224310eba..52cb6939d09 100644 --- a/net/ipv4/netfilter/iptable_filter.c +++ b/net/ipv4/netfilter/iptable_filter.c @@ -93,13 +93,8 @@ ipt_local_out_hook(unsigned int hook, { /* root is playing with raw sockets. */ if (skb->len < sizeof(struct iphdr) || - ip_hdrlen(skb) < sizeof(struct iphdr)) { - if (net_ratelimit()) - printk("iptable_filter: ignoring short SOCK_RAW " - "packet.\n"); + ip_hdrlen(skb) < sizeof(struct iphdr)) return NF_ACCEPT; - } - return ipt_do_table(skb, hook, in, out, dev_net(out)->ipv4.iptable_filter); } diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c index 69f2c428714..3929d20b9e4 100644 --- a/net/ipv4/netfilter/iptable_mangle.c +++ b/net/ipv4/netfilter/iptable_mangle.c @@ -132,12 +132,8 @@ ipt_local_hook(unsigned int hook, /* root is playing with raw sockets. */ if (skb->len < sizeof(struct iphdr) - || ip_hdrlen(skb) < sizeof(struct iphdr)) { - if (net_ratelimit()) - printk("iptable_mangle: ignoring short SOCK_RAW " - "packet.\n"); + || ip_hdrlen(skb) < sizeof(struct iphdr)) return NF_ACCEPT; - } /* Save things which could affect route */ mark = skb->mark; diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c index 8faebfe638f..7f65d18333e 100644 --- a/net/ipv4/netfilter/iptable_raw.c +++ b/net/ipv4/netfilter/iptable_raw.c @@ -65,12 +65,8 @@ ipt_local_hook(unsigned int hook, { /* root is playing with raw sockets. */ if (skb->len < sizeof(struct iphdr) || - ip_hdrlen(skb) < sizeof(struct iphdr)) { - if (net_ratelimit()) - printk("iptable_raw: ignoring short SOCK_RAW " - "packet.\n"); + ip_hdrlen(skb) < sizeof(struct iphdr)) return NF_ACCEPT; - } return ipt_do_table(skb, hook, in, out, dev_net(out)->ipv4.iptable_raw); } diff --git a/net/ipv4/netfilter/iptable_security.c b/net/ipv4/netfilter/iptable_security.c index 36f3be3cc42..a52a35f4a58 100644 --- a/net/ipv4/netfilter/iptable_security.c +++ b/net/ipv4/netfilter/iptable_security.c @@ -96,12 +96,8 @@ ipt_local_out_hook(unsigned int hook, { /* Somebody is playing with raw sockets. */ if (skb->len < sizeof(struct iphdr) - || ip_hdrlen(skb) < sizeof(struct iphdr)) { - if (net_ratelimit()) - printk(KERN_INFO "iptable_security: ignoring short " - "SOCK_RAW packet.\n"); + || ip_hdrlen(skb) < sizeof(struct iphdr)) return NF_ACCEPT; - } return ipt_do_table(skb, hook, in, out, dev_net(out)->ipv4.iptable_security); } diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index b2141e11575..4beb04fac58 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c @@ -145,11 +145,8 @@ static unsigned int ipv4_conntrack_local(unsigned int hooknum, { /* root is playing with raw sockets. */ if (skb->len < sizeof(struct iphdr) || - ip_hdrlen(skb) < sizeof(struct iphdr)) { - if (net_ratelimit()) - printk("ipt_hook: happy cracking.\n"); + ip_hdrlen(skb) < sizeof(struct iphdr)) return NF_ACCEPT; - } return nf_conntrack_in(dev_net(out), PF_INET, hooknum, skb); } -- cgit From a2bd40ad3151d4d346fd167e01fb84b06f7247fc Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 12 Jan 2009 00:06:02 +0000 Subject: netfilter 02/09: bridge: Fix handling of non-IP packets in FORWARD/POST_ROUTING Currently the bridge FORWARD/POST_ROUTING chains treats all non-IPv4 packets as IPv6. This packet fixes that by returning NF_ACCEPT on non-IP packets instead, just as is done in PRE_ROUTING. Signed-off-by: Herbert Xu Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/bridge/br_netfilter.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index a65e43a17fb..9a1cd757ec4 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -686,8 +686,11 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb, if (skb->protocol == htons(ETH_P_IP) || IS_VLAN_IP(skb) || IS_PPPOE_IP(skb)) pf = PF_INET; - else + else if (skb->protocol == htons(ETH_P_IPV6) || IS_VLAN_IPV6(skb) || + IS_PPPOE_IPV6(skb)) pf = PF_INET6; + else + return NF_ACCEPT; nf_bridge_pull_encap_header(skb); @@ -828,8 +831,11 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb, if (skb->protocol == htons(ETH_P_IP) || IS_VLAN_IP(skb) || IS_PPPOE_IP(skb)) pf = PF_INET; - else + else if (skb->protocol == htons(ETH_P_IPV6) || IS_VLAN_IPV6(skb) || + IS_PPPOE_IPV6(skb)) pf = PF_INET6; + else + return NF_ACCEPT; #ifdef CONFIG_NETFILTER_DEBUG if (skb->dst == NULL) { -- cgit From 47e0e1ca13d64eeeb687995fbe4e239e743d7544 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 12 Jan 2009 00:06:03 +0000 Subject: netfilter 03/09: bridge: Disable PPPOE/VLAN processing by default The PPPOE/VLAN processing code in the bridge netfilter is broken by design. The VLAN tag and the PPPOE session ID are an integral part of the packet flow information, yet they're completely ignored by the bridge netfilter. This is potentially a security hole as it treats all VLANs and PPPOE sessions as the same. What's more, it's actually broken for PPPOE as the bridge netfilter tries to trim the packets to the IP length without adjusting the PPPOE header (and adjusting the PPPOE header isn't much better since the PPPOE peer may require the padding to be present). Therefore we should disable this by default. It does mean that people relying on this feature may lose networking depending on how their bridge netfilter rules are configured. However, IMHO the problems this code causes are serious enough to warrant this. Signed-off-by: Herbert Xu Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/bridge/br_netfilter.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 9a1cd757ec4..cf754ace0b7 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -58,11 +58,11 @@ static struct ctl_table_header *brnf_sysctl_header; static int brnf_call_iptables __read_mostly = 1; static int brnf_call_ip6tables __read_mostly = 1; static int brnf_call_arptables __read_mostly = 1; -static int brnf_filter_vlan_tagged __read_mostly = 1; -static int brnf_filter_pppoe_tagged __read_mostly = 1; +static int brnf_filter_vlan_tagged __read_mostly = 0; +static int brnf_filter_pppoe_tagged __read_mostly = 0; #else -#define brnf_filter_vlan_tagged 1 -#define brnf_filter_pppoe_tagged 1 +#define brnf_filter_vlan_tagged 0 +#define brnf_filter_pppoe_tagged 0 #endif static inline __be16 vlan_proto(const struct sk_buff *skb) -- cgit From 656caff20e12ba6e07b4bf342641df5ab33b4e49 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 12 Jan 2009 00:06:04 +0000 Subject: netfilter 04/09: x_tables: fix match/target revision lookup Commit 55b69e91 (netfilter: implement NFPROTO_UNSPEC as a wildcard for extensions) broke revision probing for matches and targets that are registered with NFPROTO_UNSPEC. Fix by continuing the search on the NFPROTO_UNSPEC list if nothing is found on the af-specific lists. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/x_tables.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index 89837a4eef7..bfbf521f6ea 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -273,6 +273,10 @@ static int match_revfn(u8 af, const char *name, u8 revision, int *bestp) have_rev = 1; } } + + if (af != NFPROTO_UNSPEC && !have_rev) + return match_revfn(NFPROTO_UNSPEC, name, revision, bestp); + return have_rev; } @@ -289,6 +293,10 @@ static int target_revfn(u8 af, const char *name, u8 revision, int *bestp) have_rev = 1; } } + + if (af != NFPROTO_UNSPEC && !have_rev) + return target_revfn(NFPROTO_UNSPEC, name, revision, bestp); + return have_rev; } -- cgit From d61ba9fd55b52a10b8e0ffd39bbc33587d3bfc8d Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Mon, 12 Jan 2009 00:06:06 +0000 Subject: netfilter 05/09: ebtables: fix inversion in match code Commit 8cc784ee (netfilter: change return types of match functions for ebtables extensions) broke ebtables matches by inverting the sense of match/nomatch. Reported-by: Matt Cross Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/bridge/netfilter/ebtables.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 8a8743d7d6e..820252aee81 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -79,7 +79,7 @@ static inline int ebt_do_match (struct ebt_entry_match *m, { par->match = m->u.match; par->matchinfo = m->data; - return m->u.match->match(skb, par); + return m->u.match->match(skb, par) ? EBT_MATCH : EBT_NOMATCH; } static inline int ebt_dev_check(char *entry, const struct net_device *device) -- cgit From 71320afcdb33b3f0b754ba1fac6a8c77aa469041 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 12 Jan 2009 00:06:07 +0000 Subject: netfilter 06/09: nf_conntrack: fix ICMP/ICMPv6 timeout sysctls on big-endian An old bug crept back into the ICMP/ICMPv6 conntrack protocols: the timeout values are defined as unsigned longs, the sysctl's maxsize is set to sizeof(unsigned int). Use unsigned int for the timeout values as in the other conntrack protocols. Reported-by: Jean-Mickael Guerin Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv4/netfilter/nf_conntrack_proto_icmp.c | 2 +- net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c index 1fd3ef7718b..2a8bee26f43 100644 --- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c @@ -20,7 +20,7 @@ #include #include -static unsigned long nf_ct_icmp_timeout __read_mostly = 30*HZ; +static unsigned int nf_ct_icmp_timeout __read_mostly = 30*HZ; static bool icmp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, struct nf_conntrack_tuple *tuple) diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index bd52151d31e..c455cf4ee75 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c @@ -26,7 +26,7 @@ #include #include -static unsigned long nf_ct_icmpv6_timeout __read_mostly = 30*HZ; +static unsigned int nf_ct_icmpv6_timeout __read_mostly = 30*HZ; static bool icmpv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, -- cgit From cd7fcbf1cb6933bfb9171452b4a370c92923544d Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 12 Jan 2009 00:06:08 +0000 Subject: netfilter 07/09: simplify nf_conntrack_alloc() error handling nf_conntrack_alloc cannot return NULL, so there is no need to check for NULL before using the value. I have also removed the initialization of ct to NULL in nf_conntrack_alloc, since the value is never used, and since perhaps it might lead one to think that return ct at the end might return NULL. The semantic patch that finds this problem is as follows: (http://www.emn.fr/x-info/coccinelle/) // @match exists@ expression x, E; position p1,p2; statement S1, S2; @@ x@p1 = nf_conntrack_alloc(...) ... when != x = E ( if (x@p2 == NULL || ...) S1 else S2 | if (x@p2 == NULL && ...) S1 else S2 ) @other_match exists@ expression match.x, E1, E2; position p1!=match.p1,match.p2; @@ x@p1 = E1 ... when != x = E2 x@p2 @ script:python depends on !other_match@ p1 << match.p1; p2 << match.p2; @@ print "%s: call to nf_conntrack_alloc %s bad test %s" % (p1[0].file,p1[0].line,p2[0].line) // Signed-off-by: Julia Lawall Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/nf_conntrack_core.c | 4 ++-- net/netfilter/nf_conntrack_netlink.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 7e83f74cd5d..90ce9ddb945 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -469,7 +469,7 @@ struct nf_conn *nf_conntrack_alloc(struct net *net, const struct nf_conntrack_tuple *repl, gfp_t gfp) { - struct nf_conn *ct = NULL; + struct nf_conn *ct; if (unlikely(!nf_conntrack_hash_rnd_initted)) { get_random_bytes(&nf_conntrack_hash_rnd, 4); @@ -551,7 +551,7 @@ init_conntrack(struct net *net, } ct = nf_conntrack_alloc(net, tuple, &repl_tuple, GFP_ATOMIC); - if (ct == NULL || IS_ERR(ct)) { + if (IS_ERR(ct)) { pr_debug("Can't allocate conntrack.\n"); return (struct nf_conntrack_tuple_hash *)ct; } diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 00e8c27130f..3dddec6d2f7 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -1134,7 +1134,7 @@ ctnetlink_create_conntrack(struct nlattr *cda[], struct nf_conntrack_helper *helper; ct = nf_conntrack_alloc(&init_net, otuple, rtuple, GFP_ATOMIC); - if (ct == NULL || IS_ERR(ct)) + if (IS_ERR(ct)) return -ENOMEM; if (!cda[CTA_TIMEOUT]) -- cgit From e6210f3be5b13b6cda9c8dad8926818a73c8e6ac Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Mon, 12 Jan 2009 00:06:10 +0000 Subject: netfilter 08/09: xt_time: print timezone for user information netfilter: xt_time: print timezone for user information Let users have a way to figure out if their distro set the kernel timezone at all. Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/xt_time.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/net/netfilter/xt_time.c b/net/netfilter/xt_time.c index 29375ba8db7..93acaa59d10 100644 --- a/net/netfilter/xt_time.c +++ b/net/netfilter/xt_time.c @@ -243,6 +243,17 @@ static struct xt_match xt_time_mt_reg __read_mostly = { static int __init time_mt_init(void) { + int minutes = sys_tz.tz_minuteswest; + + if (minutes < 0) /* east of Greenwich */ + printk(KERN_INFO KBUILD_MODNAME + ": kernel timezone is +%02d%02d\n", + -minutes / 60, -minutes % 60); + else /* west of Greenwich */ + printk(KERN_INFO KBUILD_MODNAME + ": kernel timezone is -%02d%02d\n", + minutes / 60, minutes % 60); + return xt_register_match(&xt_time_mt_reg); } -- cgit From daaf83d2b9277928739f3eb7ea64f49c1254fd62 Mon Sep 17 00:00:00 2001 From: Richard Kennedy Date: Mon, 12 Jan 2009 00:06:11 +0000 Subject: netfilter 09/09: remove padding from struct xt_match on 64bit builds reorder struct xt_match to remove 8 bytes of padding and make its size 128 bytes. This saves a small amount of data space in each of the xt netfilter modules and fits xt_match in one 128 byte cache line. Signed-off-by: Richard Kennedy Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter/x_tables.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index e52ce475d19..c7ee8744d26 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -270,6 +270,7 @@ struct xt_match struct list_head list; const char name[XT_FUNCTION_MAXNAMELEN-1]; + u_int8_t revision; /* Return true or false: return FALSE and set *hotdrop = 1 to force immediate packet drop. */ @@ -302,7 +303,6 @@ struct xt_match unsigned short proto; unsigned short family; - u_int8_t revision; }; /* Registration hooks for targets. */ -- cgit From c08513471911cf33cb50249a7ff12848374f7263 Mon Sep 17 00:00:00 2001 From: Jarek Poplawski Date: Mon, 12 Jan 2009 21:54:16 -0800 Subject: pkt_sched: sch_htb: Consider used jiffies in htb_do_events() Next event time should consider jiffies used for recounting. Otherwise qdisc_watchdog_schedule() triggers hrtimer immediately with the event in the past, and may cause very high ksoftirqd cpu usage (if highres is on). There is also removed checking "event" for zero in htb_dequeue(): it's always true in this place. Signed-off-by: Jarek Poplawski Signed-off-by: David S. Miller --- net/sched/sch_htb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 5070643ce53..9ca8a26ba50 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -685,8 +685,8 @@ static psched_time_t htb_do_events(struct htb_sched *q, int level) if (cl->cmode != HTB_CAN_SEND) htb_add_to_wait_tree(q, cl, diff); } - /* too much load - let's continue on next jiffie */ - return q->now + PSCHED_TICKS_PER_SEC / HZ; + /* too much load - let's continue on next jiffie (including above) */ + return q->now + 2 * PSCHED_TICKS_PER_SEC / HZ; } /* Returns class->node+prio from id-tree where classe's id is >= id. NULL @@ -873,7 +873,7 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch) } else event = q->near_ev_cache[level]; - if (event && next_event > event) + if (next_event > event) next_event = event; m = ~q->row_mask[level]; -- cgit From a73be040650463eacb95f83d2e6673ac57b4fc59 Mon Sep 17 00:00:00 2001 From: Jarek Poplawski Date: Mon, 12 Jan 2009 21:54:40 -0800 Subject: pkt_sched: sch_htb: Break all htb_do_events() after 2 jiffies Currently htb_do_events() breaks events recounting for a level after 2 jiffies, but there is no reason to repeat this for next levels and increase delays even more (with softirqs disabled). htb_dequeue_tree() can add to this too, btw. In such a case q->now time is invalid anyway. Thanks to Patrick McHardy for spotting an error around earlier version of this patch. Signed-off-by: Jarek Poplawski Signed-off-by: David S. Miller --- net/sched/sch_htb.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 9ca8a26ba50..2f0f0b04d3f 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -661,12 +661,13 @@ static void htb_charge_class(struct htb_sched *q, struct htb_class *cl, * next pending event (0 for no event in pq). * Note: Applied are events whose have cl->pq_key <= q->now. */ -static psched_time_t htb_do_events(struct htb_sched *q, int level) +static psched_time_t htb_do_events(struct htb_sched *q, int level, + unsigned long start) { /* don't run for longer than 2 jiffies; 2 is used instead of 1 to simplify things when jiffy is going to be incremented too soon */ - unsigned long stop_at = jiffies + 2; + unsigned long stop_at = start + 2; while (time_before(jiffies, stop_at)) { struct htb_class *cl; long diff; @@ -845,6 +846,7 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch) struct htb_sched *q = qdisc_priv(sch); int level; psched_time_t next_event; + unsigned long start_at; /* try to dequeue direct packets as high prio (!) to minimize cpu work */ skb = __skb_dequeue(&q->direct_queue); @@ -857,6 +859,7 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch) if (!sch->q.qlen) goto fin; q->now = psched_get_time(); + start_at = jiffies; next_event = q->now + 5 * PSCHED_TICKS_PER_SEC; @@ -866,7 +869,7 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch) psched_time_t event; if (q->now >= q->near_ev_cache[level]) { - event = htb_do_events(q, level); + event = htb_do_events(q, level, start_at); if (!event) event = q->now + PSCHED_TICKS_PER_SEC; q->near_ev_cache[level] = event; -- cgit From b74f62c1e736ea01c660355526dd54132d241ca9 Mon Sep 17 00:00:00 2001 From: Denis Joseph Barrow Date: Mon, 12 Jan 2009 21:56:49 -0800 Subject: hso: driver fix for big endian machines. Filip Aben says this fix is neccessary for big endian machines. Signed-off-by: Denis Joseph Barrow Signed-off-by: David S. Miller --- drivers/net/usb/hso.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index c4918b86ed1..d17dc5214c9 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1792,8 +1792,8 @@ static int mux_device_request(struct hso_serial *serial, u8 type, u16 port, /* initialize */ ctrl_req->wValue = 0; - ctrl_req->wIndex = hso_port_to_mux(port); - ctrl_req->wLength = size; + ctrl_req->wIndex = cpu_to_le16(hso_port_to_mux(port)); + ctrl_req->wLength = cpu_to_le16(size); if (type == USB_CDC_GET_ENCAPSULATED_RESPONSE) { /* Reading command */ -- cgit From a6d0b91ae5dd01263530c96f9b29001cb1ed58b0 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Mon, 12 Jan 2009 21:57:34 -0800 Subject: gianfar: Fix soft lockup with multi-interrupt TSECs This patch fixes following bug: BUG: soft lockup - CPU#0 stuck for 61s! [S03mountvirtfs-:922] Modules linked in: NIP: c006505c LR: c00675f0 CTR: c0020438 REGS: c7a1db90 TRAP: 0901 Not tainted (2.6.28-rc8-01311-g8c7396a) MSR: 00009032 CR: 28248442 XER: 20000000 TASK = c7a288a0[922] 'S03mountvirtfs-' THREAD: c7a1c000 GPR00: 00009032 c7a1dc40 c7a288a0 00000024 c79a1840 00000000 00000300 00000020 GPR08: c035f97c 00000000 00004008 c04d5210 00000000 NIP [c006505c] handle_IRQ_event+0x34/0xb0 LR [c00675f0] handle_level_irq+0xa8/0x144 Call Trace: [c7a1dc40] [c00204d8] ipic_mask_irq+0xa0/0xb4 (unreliable) [c7a1dc60] [c00675f0] handle_level_irq+0xa8/0x144 [c7a1dc80] [c00067f8] do_IRQ+0x78/0x108 [c7a1dc90] [c0014d7c] ret_from_except+0x0/0x14 --- Exception: 501 at gfar_schedule_cleanup+0x54/0x7c LR = gfar_transmit+0x14/0x28 [c7a1dd50] [c0352a3c] _spin_unlock_irqrestore+0x18/0x30 (unreliable) [c7a1dd60] [c01f49a8] gfar_transmit+0x14/0x28 [c7a1dd70] [c0065084] handle_IRQ_event+0x5c/0xb0 [c7a1dd90] [c00675f0] handle_level_irq+0xa8/0x144 [c7a1ddb0] [c00067f8] do_IRQ+0x78/0x108 [c7a1ddc0] [c0014d7c] ret_from_except+0x0/0x14 --- Exception: 501 at up_read+0x10/0x48 LR = do_page_fault+0x2b0/0x3e0 [c7a1de80] [c7a177e8] 0xc7a177e8 (unreliable) [c7a1de90] [c0017964] do_page_fault+0x2b0/0x3e0 [c7a1df40] [c0014b14] handle_page_fault+0xc/0x80 --- Exception: 301 at 0xfe98b7c LR = 0xfe989c0 Instruction dump: 7c0802a6 bf810010 7c9f2378 7c7c1b78 90010024 80040004 70090020 40820010 7c0000a6 60008000 7c000124 3bc00000 <3ba00000> 48000010 83ff0014 2f9f0000 The bug introduced by commit 8c7396aebb68994c0519e438eecdf4d5fa9c7844 ("gianfar: Merge Tx and Rx interrupt for scheduling clean up ring"). The commit merged TX and RX interrupt code into a single routine that schedules NAPI, but no locks were introduced. This causes irq races, so when irqs are enabled and netif_rx_schedule_prep() returns 0, nobody disable the interrupts again. This leads to interrupt storm and finally to the lockup. Signed-off-by: Anton Vorontsov Signed-off-by: David S. Miller --- drivers/net/gianfar.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index efcbeb6c867..ea530673236 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -1622,10 +1622,18 @@ static int gfar_clean_tx_ring(struct net_device *dev) static void gfar_schedule_cleanup(struct net_device *dev) { struct gfar_private *priv = netdev_priv(dev); + unsigned long flags; + + spin_lock_irqsave(&priv->txlock, flags); + spin_lock(&priv->rxlock); + if (netif_rx_schedule_prep(&priv->napi)) { gfar_write(&priv->regs->imask, IMASK_RTX_DISABLED); __netif_rx_schedule(&priv->napi); } + + spin_unlock(&priv->rxlock); + spin_unlock_irqrestore(&priv->txlock, flags); } /* Interrupt Handler for Transmit complete */ -- cgit From 859975764fa61e927e7a69f46a55a4ba415785dd Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Mon, 12 Jan 2009 22:11:56 -0800 Subject: net: ppp_generic - fix regressions caused by IDR conversion The commits: 7a95d267fb62cd6b80ef73be0592bbbe1dbd5df7 ("net: ppp_generic - use idr technique instead of cardmaps") ab5024ab23b78c86a0a1425defcdde48710fe449 ("net: ppp_generic - use DEFINE_IDR for static initialization") introduced usage of IDR functionality but broke userspace side. Before this commits it was possible to allocate new ppp interface with specified number. Now it fails with EINVAL. Fix it by trying to allocate interface with specified unit number and return EEXIST if fail which allow pppd to ask us to allocate new unit number. And fix messages on memory allocation fails - add details that it's PPP module who is complaining. Signed-off-by: Cyrill Gorcunov Signed-off-by: David S. Miller --- drivers/net/ppp_generic.c | 43 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 06b448285eb..7b2728b8f1b 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -250,6 +250,7 @@ static int ppp_connect_channel(struct channel *pch, int unit); static int ppp_disconnect_channel(struct channel *pch); static void ppp_destroy_channel(struct channel *pch); static int unit_get(struct idr *p, void *ptr); +static int unit_set(struct idr *p, void *ptr, int n); static void unit_put(struct idr *p, int n); static void *unit_find(struct idr *p, int n); @@ -2432,11 +2433,18 @@ ppp_create_interface(int unit, int *retp) } else { if (unit_find(&ppp_units_idr, unit)) goto out2; /* unit already exists */ - else { - /* darn, someone is cheating us? */ - *retp = -EINVAL; + /* + * if caller need a specified unit number + * lets try to satisfy him, otherwise -- + * he should better ask us for new unit number + * + * NOTE: yes I know that returning EEXIST it's not + * fair but at least pppd will ask us to allocate + * new unit in this case so user is happy :) + */ + unit = unit_set(&ppp_units_idr, ppp, unit); + if (unit < 0) goto out2; - } } /* Initialize the new ppp unit */ @@ -2677,14 +2685,37 @@ static void __exit ppp_cleanup(void) * by holding all_ppp_mutex */ +/* associate pointer with specified number */ +static int unit_set(struct idr *p, void *ptr, int n) +{ + int unit, err; + +again: + if (!idr_pre_get(p, GFP_KERNEL)) { + printk(KERN_ERR "PPP: No free memory for idr\n"); + return -ENOMEM; + } + + err = idr_get_new_above(p, ptr, n, &unit); + if (err == -EAGAIN) + goto again; + + if (unit != n) { + idr_remove(p, unit); + return -EINVAL; + } + + return unit; +} + /* get new free unit number and associate pointer with it */ static int unit_get(struct idr *p, void *ptr) { int unit, err; again: - if (idr_pre_get(p, GFP_KERNEL) == 0) { - printk(KERN_ERR "Out of memory expanding drawable idr\n"); + if (!idr_pre_get(p, GFP_KERNEL)) { + printk(KERN_ERR "PPP: No free memory for idr\n"); return -ENOMEM; } -- cgit From f2d8dc75a14479f8803a70cf637b5d79a3bb87f1 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 12 Jan 2009 22:29:23 -0800 Subject: Input: corgikbd - mark probe function as __devinit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A pointer to corgikbd_probe is passed to the core via platform_driver_register and so the function must not disappear when the .init sections are discarded. Otherwise (if also having HOTPLUG=y) unbinding and binding a device to the driver via sysfs will result in an oops as does a device being registered late. An alternative to this patch is using platform_driver_probe instead of platform_driver_register plus removing the pointer to the probe function from the struct platform_driver. [dtor@mail.ru: fixed some more section markups] Signed-off-by: Uwe Kleine-König Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/corgikbd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c index c8ed065ea0c..abb04c82c62 100644 --- a/drivers/input/keyboard/corgikbd.c +++ b/drivers/input/keyboard/corgikbd.c @@ -288,7 +288,7 @@ static int corgikbd_resume(struct platform_device *dev) #define corgikbd_resume NULL #endif -static int __init corgikbd_probe(struct platform_device *pdev) +static int __devinit corgikbd_probe(struct platform_device *pdev) { struct corgikbd *corgikbd; struct input_dev *input_dev; @@ -368,7 +368,7 @@ static int __init corgikbd_probe(struct platform_device *pdev) return err; } -static int corgikbd_remove(struct platform_device *pdev) +static int __devexit corgikbd_remove(struct platform_device *pdev) { int i; struct corgikbd *corgikbd = platform_get_drvdata(pdev); @@ -388,7 +388,7 @@ static int corgikbd_remove(struct platform_device *pdev) static struct platform_driver corgikbd_driver = { .probe = corgikbd_probe, - .remove = corgikbd_remove, + .remove = __devexit_p(corgikbd_remove), .suspend = corgikbd_suspend, .resume = corgikbd_resume, .driver = { @@ -397,7 +397,7 @@ static struct platform_driver corgikbd_driver = { }, }; -static int __devinit corgikbd_init(void) +static int __init corgikbd_init(void) { return platform_driver_register(&corgikbd_driver); } -- cgit From 840207edfa8b5e5b46e0d268bf33efe71fecea20 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 12 Jan 2009 22:32:17 -0800 Subject: Input: corgi_ts - mark probe function as __devinit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A pointer to corgits_probe is passed to the core via platform_driver_register and so the function must not disappear when the .init sections are discarded. Otherwise (if also having HOTPLUG=y) unbinding and binding a device to the driver via sysfs will result in an oops as does a device being registered late. An alternative to this patch is using platform_driver_probe instead of platform_driver_register plus removing the pointer to the probe function from the struct platform_driver. [dtor@mail.ru: fixed some more section markups] Signed-off-by: Uwe Kleine-König Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/corgi_ts.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c index 65202c9f63f..3fb51b54fe6 100644 --- a/drivers/input/touchscreen/corgi_ts.c +++ b/drivers/input/touchscreen/corgi_ts.c @@ -268,7 +268,7 @@ static int corgits_resume(struct platform_device *dev) #define corgits_resume NULL #endif -static int __init corgits_probe(struct platform_device *pdev) +static int __devinit corgits_probe(struct platform_device *pdev) { struct corgi_ts *corgi_ts; struct input_dev *input_dev; @@ -343,7 +343,7 @@ static int __init corgits_probe(struct platform_device *pdev) return err; } -static int corgits_remove(struct platform_device *pdev) +static int __devexit corgits_remove(struct platform_device *pdev) { struct corgi_ts *corgi_ts = platform_get_drvdata(pdev); @@ -352,12 +352,13 @@ static int corgits_remove(struct platform_device *pdev) corgi_ts->machinfo->put_hsync(); input_unregister_device(corgi_ts->input); kfree(corgi_ts); + return 0; } static struct platform_driver corgits_driver = { .probe = corgits_probe, - .remove = corgits_remove, + .remove = __devexit_p(corgits_remove), .suspend = corgits_suspend, .resume = corgits_resume, .driver = { @@ -366,7 +367,7 @@ static struct platform_driver corgits_driver = { }, }; -static int __devinit corgits_init(void) +static int __init corgits_init(void) { return platform_driver_register(&corgits_driver); } -- cgit From f9d088b2080b476c86f8ddbc274851b89668c6d7 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 13 Jan 2009 11:54:49 +0100 Subject: ALSA: hda - Fix a typo Fix a typo in stac92hd83xxx_cfg_tbl[]. The actual number is identical thus there is no behavior change. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 35b83dc6e19..a4e2d8fcc8b 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1682,7 +1682,7 @@ static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, - "DFI LanParty", STAC_92HD71BXX_REF), + "DFI LanParty", STAC_92HD83XXX_REF), {} /* terminator */ }; -- cgit From f84e3e915ea03dfa6e32626fc25a4f284ef222ac Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 13 Jan 2009 12:32:21 +0100 Subject: ALSA: hda - Add support of NVidia MCP78 HDMI Added the new id for NVidia MCP HDMI (10de:0007). Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_nvhdmi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c index 96952a37d88..d57d8132a06 100644 --- a/sound/pci/hda/patch_nvhdmi.c +++ b/sound/pci/hda/patch_nvhdmi.c @@ -160,6 +160,7 @@ static int patch_nvhdmi(struct hda_codec *codec) */ static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { { .id = 0x10de0002, .name = "MCP78 HDMI", .patch = patch_nvhdmi }, + { .id = 0x10de0006, .name = "MCP78 HDMI", .patch = patch_nvhdmi }, { .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi }, { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi }, { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi }, @@ -167,6 +168,7 @@ static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { }; MODULE_ALIAS("snd-hda-codec-id:10de0002"); +MODULE_ALIAS("snd-hda-codec-id:10de0006"); MODULE_ALIAS("snd-hda-codec-id:10de0007"); MODULE_ALIAS("snd-hda-codec-id:10de0067"); MODULE_ALIAS("snd-hda-codec-id:10de8001"); -- cgit From dafb70ce1026d4d6ef1b16ad6996c9589bb11cce Mon Sep 17 00:00:00 2001 From: Giuseppe Bilotta Date: Tue, 13 Jan 2009 08:58:49 -0500 Subject: ALSA: hda - Add quirk for another HP dv5 Add the model=hp-m4 quirk for another HP dv5 (103c:3603) Reference: kernel bug#12440 http://bugzilla.kernel.org/show_bug.cgi?id=12440 Signed-off-by: Takashi Iwai Cc: stable@kernel.org --- sound/pci/hda/patch_sigmatel.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index a4e2d8fcc8b..9acf2f0a2df 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1736,6 +1736,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { "HP dv7", STAC_HP_M4), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fc, "HP dv7", STAC_HP_M4), + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3603, + "HP dv5", STAC_HP_M4), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, "unknown HP", STAC_HP_M4), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, -- cgit From 4a922a969cb0190ce4580d4b064e2ac35f3ac9bf Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 13 Jan 2009 16:11:00 +0100 Subject: x86, cpufreq: remove leftover copymask_copy() Impact: fix potential boot crash on MAXSMP Remove code left over by: 50c668d: Revert "cpumask: use work_on_cpu in acpi-cpufreq.c for drv_read That cmd.cpumask is not allocated anymore. No impact on default !MAXSMP kernels. Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index 6f11e029e8c..8f3c95c7e61 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -235,8 +235,6 @@ static u32 get_cur_val(const struct cpumask *mask) return 0; } - cpumask_copy(cmd.mask, mask); - drv_read(&cmd); dprintk("get_cur_val = %u\n", cmd.val); -- cgit From 85b9e4fe13de9b35af1dbd50acc5f4978b9119ee Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 12 Jan 2009 14:37:44 -0500 Subject: mac80211: fix "‘ret’ may be used uninitialized" warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit net/mac80211/ht.c: In function ‘ieee80211_start_tx_ba_session’: net/mac80211/ht.c:472: warning: ‘ret’ may be used uninitialized in this function Signed-off-by: John W. Linville --- net/mac80211/ht.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 5f510a13b9f..c5c0c527109 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c @@ -469,7 +469,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) struct ieee80211_sub_if_data *sdata; u16 start_seq_num; u8 *state; - int ret; + int ret = 0; if ((tid >= STA_TID_NUM) || !(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) return -EINVAL; -- cgit From 922d8a0b6d82fb40ffb561576e3800c3784ff43d Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 12 Jan 2009 14:40:20 -0500 Subject: b43: fix "‘gmode’ may be used uninitialized" warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/net/wireless/b43/main.c: In function ‘b43_op_config’: drivers/net/wireless/b43/main.c:3264: warning: ‘gmode’ may be used uninitialized Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 7b31a327b24..c788bad1066 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -3261,7 +3261,7 @@ static int b43_switch_band(struct b43_wl *wl, struct ieee80211_channel *chan) struct b43_wldev *down_dev; struct b43_wldev *d; int err; - bool gmode; + bool uninitialized_var(gmode); int prev_status; /* Find a device and PHY which supports the band. */ -- cgit From 08cb7e01678b0a8d95d76aa0a395f2d7390f7ee1 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 12 Jan 2009 14:43:18 -0500 Subject: b43legacy: fix "‘up_dev’ may be used uninitialized" warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/net/wireless/b43legacy/main.c: In function ‘b43legacy_op_dev_config’: drivers/net/wireless/b43legacy/main.c:2468: warning: ‘up_dev’ may be used uninitialized in this function Signed-off-by: John W. Linville --- drivers/net/wireless/b43legacy/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index c1324e31d2f..fb996c27a19 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -2465,7 +2465,7 @@ static void b43legacy_put_phy_into_reset(struct b43legacy_wldev *dev) static int b43legacy_switch_phymode(struct b43legacy_wl *wl, unsigned int new_mode) { - struct b43legacy_wldev *up_dev; + struct b43legacy_wldev *uninitialized_var(up_dev); struct b43legacy_wldev *down_dev; int err; bool gmode = 0; -- cgit From 25a4cceaa44a7f73c8f92e6177812347500a0b15 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 12 Jan 2009 14:44:52 -0500 Subject: iwl3945: fix "‘power_idx’ may be used uninitialized" warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/net/wireless/iwlwifi/iwl-3945.c: In function ‘iwl3945_txpower_set_from_eeprom’: drivers/net/wireless/iwlwifi/iwl-3945.c:2222: warning: ‘power_idx’ may be used uninitialized in this function Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-3945.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 8fdb34222c0..45cfa1cf194 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2219,7 +2219,7 @@ int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv) /* set tx power value for all OFDM rates */ for (rate_index = 0; rate_index < IWL_OFDM_RATES; rate_index++) { - s32 power_idx; + s32 uninitialized_var(power_idx); int rc; /* use channel group's clip-power table, -- cgit From 26d1597c9a4532eec74f9651c4c96483cb8892fe Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 12 Jan 2009 14:46:39 -0500 Subject: p54: fix "‘ret’ may be used uninitialized" warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/net/wireless/p54/p54common.c: In function ‘p54_config’: drivers/net/wireless/p54/p54common.c:1853: warning: ‘ret’ may be used uninitialized in this function Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index cba89ed0f57..c6a370fa9bc 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -1850,7 +1850,7 @@ static void p54_remove_interface(struct ieee80211_hw *dev, static int p54_config(struct ieee80211_hw *dev, u32 changed) { - int ret; + int ret = 0; struct p54_common *priv = dev->priv; struct ieee80211_conf *conf = &dev->conf; -- cgit From d86be86e9aab221089d72399072511f13fe2a771 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 13 Jan 2009 09:22:20 -0700 Subject: dmatest: Use custom map/unmap for destination buffer The dmatest driver should use DMA_BIDIRECTIONAL on the destination buffer to ensure that the poison values are written to RAM and not just written to cache and discarded. Acked-by: Haavard Skinnemoen Acked-by: Maciej Sosnowski Signed-off-by: Atsushi Nemoto Signed-off-by: Dan Williams --- drivers/dma/dmatest.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c index 3603f1ea5b2..732fa1ec36a 100644 --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c @@ -217,6 +217,10 @@ static int dmatest_func(void *data) chan = thread->chan; while (!kthread_should_stop()) { + struct dma_device *dev = chan->device; + struct dma_async_tx_descriptor *tx; + dma_addr_t dma_src, dma_dest; + total_tests++; len = dmatest_random() % test_buf_size + 1; @@ -226,10 +230,30 @@ static int dmatest_func(void *data) dmatest_init_srcbuf(thread->srcbuf, src_off, len); dmatest_init_dstbuf(thread->dstbuf, dst_off, len); - cookie = dma_async_memcpy_buf_to_buf(chan, - thread->dstbuf + dst_off, - thread->srcbuf + src_off, - len); + dma_src = dma_map_single(dev->dev, thread->srcbuf + src_off, + len, DMA_TO_DEVICE); + /* map with DMA_BIDIRECTIONAL to force writeback/invalidate */ + dma_dest = dma_map_single(dev->dev, thread->dstbuf, + test_buf_size, DMA_BIDIRECTIONAL); + + tx = dev->device_prep_dma_memcpy(chan, dma_dest + dst_off, + dma_src, len, + DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP); + if (!tx) { + dma_unmap_single(dev->dev, dma_src, len, DMA_TO_DEVICE); + dma_unmap_single(dev->dev, dma_dest, + test_buf_size, DMA_BIDIRECTIONAL); + pr_warning("%s: #%u: prep error with src_off=0x%x " + "dst_off=0x%x len=0x%x\n", + thread_name, total_tests - 1, + src_off, dst_off, len); + msleep(100); + failed_tests++; + continue; + } + tx->callback = NULL; + cookie = tx->tx_submit(tx); + if (dma_submit_error(cookie)) { pr_warning("%s: #%u: submit error %d with src_off=0x%x " "dst_off=0x%x len=0x%x\n", @@ -253,6 +277,9 @@ static int dmatest_func(void *data) failed_tests++; continue; } + /* Unmap by myself (see DMA_COMPL_SKIP_DEST_UNMAP above) */ + dma_unmap_single(dev->dev, dma_dest, + test_buf_size, DMA_BIDIRECTIONAL); error_count = 0; -- cgit From 29bdccbee69c199910b2b39377e66ee5c33f241c Mon Sep 17 00:00:00 2001 From: Anirban Chakraborty Date: Thu, 8 Jan 2009 15:41:08 -0800 Subject: [SCSI] qla2xxx: Fix ISP restart bug in multiq code After restarting ISP the additional queues are not being setup correctly. The following patch fixes the issue. Please apply. Signed-off-by: Anirban Chakraborty Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_init.c | 58 +++++++++++++++++++++++++---------------- drivers/scsi/qla2xxx/qla_mid.c | 1 + drivers/scsi/qla2xxx/qla_os.c | 7 +++-- 3 files changed, 40 insertions(+), 26 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 2d4f32b4df5..9ad4d0968e5 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1258,35 +1258,48 @@ qla2x00_init_rings(scsi_qla_host_t *vha) { int rval; unsigned long flags = 0; - int cnt; + int cnt, que; struct qla_hw_data *ha = vha->hw; - struct req_que *req = ha->req_q_map[0]; - struct rsp_que *rsp = ha->rsp_q_map[0]; + struct req_que *req; + struct rsp_que *rsp; + struct scsi_qla_host *vp; struct mid_init_cb_24xx *mid_init_cb = (struct mid_init_cb_24xx *) ha->init_cb; spin_lock_irqsave(&ha->hardware_lock, flags); /* Clear outstanding commands array. */ - for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) - req->outstanding_cmds[cnt] = NULL; + for (que = 0; que < ha->max_queues; que++) { + req = ha->req_q_map[que]; + if (!req) + continue; + for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) + req->outstanding_cmds[cnt] = NULL; - req->current_outstanding_cmd = 0; + req->current_outstanding_cmd = 0; - /* Clear RSCN queue. */ - vha->rscn_in_ptr = 0; - vha->rscn_out_ptr = 0; + /* Initialize firmware. */ + req->ring_ptr = req->ring; + req->ring_index = 0; + req->cnt = req->length; + } - /* Initialize firmware. */ - req->ring_ptr = req->ring; - req->ring_index = 0; - req->cnt = req->length; - rsp->ring_ptr = rsp->ring; - rsp->ring_index = 0; + for (que = 0; que < ha->max_queues; que++) { + rsp = ha->rsp_q_map[que]; + if (!rsp) + continue; + rsp->ring_ptr = rsp->ring; + rsp->ring_index = 0; - /* Initialize response queue entries */ - qla2x00_init_response_q_entries(rsp); + /* Initialize response queue entries */ + qla2x00_init_response_q_entries(rsp); + } + /* Clear RSCN queue. */ + list_for_each_entry(vp, &ha->vp_list, list) { + vp->rscn_in_ptr = 0; + vp->rscn_out_ptr = 0; + } ha->isp_ops->config_rings(vha); spin_unlock_irqrestore(&ha->hardware_lock, flags); @@ -3212,8 +3225,8 @@ qla2x00_loop_resync(scsi_qla_host_t *vha) int rval = QLA_SUCCESS; uint32_t wait_time; struct qla_hw_data *ha = vha->hw; - struct req_que *req = ha->req_q_map[0]; - struct rsp_que *rsp = ha->rsp_q_map[0]; + struct req_que *req = ha->req_q_map[vha->req_ques[0]]; + struct rsp_que *rsp = req->rsp; atomic_set(&vha->loop_state, LOOP_UPDATE); clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags); @@ -3492,6 +3505,7 @@ qla25xx_init_queues(struct qla_hw_data *ha) } req = ha->req_q_map[i]; if (req) { + /* Clear outstanding commands array. */ req->options &= ~BIT_0; ret = qla25xx_init_req_que(base_vha, req, req->options); if (ret != QLA_SUCCESS) @@ -3500,7 +3514,7 @@ qla25xx_init_queues(struct qla_hw_data *ha) req->id)); else DEBUG2_17(printk(KERN_WARNING - "%s Rsp que:%d inited\n", __func__, + "%s Req que:%d inited\n", __func__, req->id)); } } @@ -4151,8 +4165,8 @@ qla24xx_configure_vhba(scsi_qla_host_t *vha) uint16_t mb[MAILBOX_REGISTER_COUNT]; struct qla_hw_data *ha = vha->hw; struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); - struct req_que *req = ha->req_q_map[0]; - struct rsp_que *rsp = ha->rsp_q_map[0]; + struct req_que *req = ha->req_q_map[vha->req_ques[0]]; + struct rsp_que *rsp = req->rsp; if (!vha->vp_idx) return -EINVAL; diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 886323130fc..f53179c4642 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -629,6 +629,7 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options, req->ring_index = 0; req->cnt = req->length; req->id = que_id; + req->max_q_depth = ha->req_q_map[0]->max_q_depth; mutex_unlock(&ha->vport_lock); ret = qla25xx_init_req_que(base_vha, req, options); diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 4a71f522f92..cf32653fe01 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1158,8 +1158,8 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) struct req_que *req; spin_lock_irqsave(&ha->hardware_lock, flags); - for (que = 0; que < QLA_MAX_HOST_QUES; que++) { - req = ha->req_q_map[vha->req_ques[que]]; + for (que = 0; que < ha->max_queues; que++) { + req = ha->req_q_map[que]; if (!req) continue; for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { @@ -1193,7 +1193,7 @@ qla2xxx_slave_configure(struct scsi_device *sdev) scsi_qla_host_t *vha = shost_priv(sdev->host); struct qla_hw_data *ha = vha->hw; struct fc_rport *rport = starget_to_rport(sdev->sdev_target); - struct req_que *req = ha->req_q_map[0]; + struct req_que *req = ha->req_q_map[vha->req_ques[0]]; if (sdev->tagged_supported) scsi_activate_tcq(sdev, req->max_q_depth); @@ -1998,7 +1998,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) return 0; probe_failed: - qla2x00_free_que(ha, req, rsp); qla2x00_free_device(base_vha); scsi_host_put(base_vha->host); -- cgit From fd7a253311412b3fc7c85586552c90eca61e7d23 Mon Sep 17 00:00:00 2001 From: "Kashyap, Desai" Date: Tue, 6 Jan 2009 14:56:31 +0530 Subject: [SCSI] mpt fusion: Update MPI Headers to version 01.05.19 This Patch is submitted to increment the MPI headers used by LSI MPT fusion drivers to the latest version 01.05.19. Year is changed in CopyRight. Signed-off-by: Kashyap Desai Signed-off-by: James Bottomley --- drivers/message/fusion/lsi/mpi.h | 7 ++- drivers/message/fusion/lsi/mpi_cnfg.h | 47 +++++++++++++++- drivers/message/fusion/lsi/mpi_fc.h | 2 +- drivers/message/fusion/lsi/mpi_history.txt | 86 +++++++++++++++++++++--------- drivers/message/fusion/lsi/mpi_init.h | 2 +- drivers/message/fusion/lsi/mpi_ioc.h | 22 +++++++- drivers/message/fusion/lsi/mpi_lan.h | 2 +- drivers/message/fusion/lsi/mpi_log_fc.h | 2 +- drivers/message/fusion/lsi/mpi_log_sas.h | 37 ++++++++++--- drivers/message/fusion/lsi/mpi_raid.h | 11 +++- drivers/message/fusion/lsi/mpi_sas.h | 18 +++++-- drivers/message/fusion/lsi/mpi_targ.h | 2 +- drivers/message/fusion/lsi/mpi_tool.h | 2 +- drivers/message/fusion/lsi/mpi_type.h | 4 +- 14 files changed, 191 insertions(+), 53 deletions(-) diff --git a/drivers/message/fusion/lsi/mpi.h b/drivers/message/fusion/lsi/mpi.h index 10b6ef75872..11c0f461320 100644 --- a/drivers/message/fusion/lsi/mpi.h +++ b/drivers/message/fusion/lsi/mpi.h @@ -6,7 +6,7 @@ * Title: MPI Message independent structures and definitions * Creation Date: July 27, 2000 * - * mpi.h Version: 01.05.13 + * mpi.h Version: 01.05.16 * * Version History * --------------- @@ -79,6 +79,9 @@ * 03-27-06 01.05.11 Bumped MPI_HEADER_VERSION_UNIT. * 10-11-06 01.05.12 Bumped MPI_HEADER_VERSION_UNIT. * 05-24-07 01.05.13 Bumped MPI_HEADER_VERSION_UNIT. + * 08-07-07 01.05.14 Bumped MPI_HEADER_VERSION_UNIT. + * 01-15-08 01.05.15 Bumped MPI_HEADER_VERSION_UNIT. + * 03-28-08 01.05.16 Bumped MPI_HEADER_VERSION_UNIT. * -------------------------------------------------------------------------- */ @@ -109,7 +112,7 @@ /* Note: The major versions of 0xe0 through 0xff are reserved */ /* versioning for this MPI header set */ -#define MPI_HEADER_VERSION_UNIT (0x10) +#define MPI_HEADER_VERSION_UNIT (0x13) #define MPI_HEADER_VERSION_DEV (0x00) #define MPI_HEADER_VERSION_UNIT_MASK (0xFF00) #define MPI_HEADER_VERSION_UNIT_SHIFT (8) diff --git a/drivers/message/fusion/lsi/mpi_cnfg.h b/drivers/message/fusion/lsi/mpi_cnfg.h index b2db3330c59..013c7d88194 100644 --- a/drivers/message/fusion/lsi/mpi_cnfg.h +++ b/drivers/message/fusion/lsi/mpi_cnfg.h @@ -6,7 +6,7 @@ * Title: MPI Config message, structures, and Pages * Creation Date: July 27, 2000 * - * mpi_cnfg.h Version: 01.05.15 + * mpi_cnfg.h Version: 01.05.18 * * Version History * --------------- @@ -308,6 +308,20 @@ * Expander Page 0 Flags field. * Fixed define for * MPI_SAS_EXPANDER1_DISCINFO_BAD_PHY_DISABLED. + * 08-07-07 01.05.16 Added MPI_IOCPAGE6_CAP_FLAGS_MULTIPORT_DRIVE_SUPPORT + * define. + * Added BIOS Page 4 structure. + * Added MPI_RAID_PHYS_DISK1_PATH_MAX define for RAID + * Physcial Disk Page 1. + * 01-15-07 01.05.17 Added additional bit defines for ExtFlags field of + * Manufacturing Page 4. + * Added Solid State Drives Supported bit to IOC Page 6 + * Capabilities Flags. + * Added new value for AccessStatus field of SAS Device + * Page 0 (_SATA_NEEDS_INITIALIZATION). + * 03-28-08 01.05.18 Defined new bits in Manufacturing Page 4 ExtFlags field + * to control coercion size and the mixing of SAS and SATA + * SSD drives. * -------------------------------------------------------------------------- */ @@ -686,6 +700,14 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_4 #define MPI_MANPAGE4_IR_NO_MIX_SAS_SATA (0x01) /* defines for the ExtFlags field */ +#define MPI_MANPAGE4_EXTFLAGS_MASK_COERCION_SIZE (0x0180) +#define MPI_MANPAGE4_EXTFLAGS_SHIFT_COERCION_SIZE (7) +#define MPI_MANPAGE4_EXTFLAGS_1GB_COERCION_SIZE (0) +#define MPI_MANPAGE4_EXTFLAGS_128MB_COERCION_SIZE (1) + +#define MPI_MANPAGE4_EXTFLAGS_NO_MIX_SSD_SAS_SATA (0x0040) +#define MPI_MANPAGE4_EXTFLAGS_MIX_SSD_AND_NON_SSD (0x0020) +#define MPI_MANPAGE4_EXTFLAGS_DUAL_PORT_SUPPORT (0x0010) #define MPI_MANPAGE4_EXTFLAGS_HIDE_NON_IR_METADATA (0x0008) #define MPI_MANPAGE4_EXTFLAGS_SAS_CACHE_DISABLE (0x0004) #define MPI_MANPAGE4_EXTFLAGS_SATA_CACHE_DISABLE (0x0002) @@ -1159,6 +1181,8 @@ typedef struct _CONFIG_PAGE_IOC_6 /* IOC Page 6 Capabilities Flags */ +#define MPI_IOCPAGE6_CAP_FLAGS_SSD_SUPPORT (0x00000020) +#define MPI_IOCPAGE6_CAP_FLAGS_MULTIPORT_DRIVE_SUPPORT (0x00000010) #define MPI_IOCPAGE6_CAP_FLAGS_DISABLE_SMART_POLLING (0x00000008) #define MPI_IOCPAGE6_CAP_FLAGS_MASK_METADATA_SIZE (0x00000006) @@ -1428,6 +1452,15 @@ typedef struct _CONFIG_PAGE_BIOS_2 #define MPI_BIOSPAGE2_FORM_SAS_WWN (0x05) #define MPI_BIOSPAGE2_FORM_ENCLOSURE_SLOT (0x06) +typedef struct _CONFIG_PAGE_BIOS_4 +{ + CONFIG_PAGE_HEADER Header; /* 00h */ + U64 ReassignmentBaseWWID; /* 04h */ +} CONFIG_PAGE_BIOS_4, MPI_POINTER PTR_CONFIG_PAGE_BIOS_4, + BIOSPage4_t, MPI_POINTER pBIOSPage4_t; + +#define MPI_BIOSPAGE4_PAGEVERSION (0x00) + /**************************************************************************** * SCSI Port Config Pages @@ -2419,6 +2452,15 @@ typedef struct _RAID_PHYS_DISK1_PATH #define MPI_RAID_PHYSDISK1_FLAG_BROKEN (0x0002) #define MPI_RAID_PHYSDISK1_FLAG_INVALID (0x0001) + +/* + * Host code (drivers, BIOS, utilities, etc.) should leave this define set to + * one and check Header.PageLength or NumPhysDiskPaths at runtime. + */ +#ifndef MPI_RAID_PHYS_DISK1_PATH_MAX +#define MPI_RAID_PHYS_DISK1_PATH_MAX (1) +#endif + typedef struct _CONFIG_PAGE_RAID_PHYS_DISK_1 { CONFIG_PAGE_HEADER Header; /* 00h */ @@ -2426,7 +2468,7 @@ typedef struct _CONFIG_PAGE_RAID_PHYS_DISK_1 U8 PhysDiskNum; /* 05h */ U16 Reserved2; /* 06h */ U32 Reserved1; /* 08h */ - RAID_PHYS_DISK1_PATH Path[1]; /* 0Ch */ + RAID_PHYS_DISK1_PATH Path[MPI_RAID_PHYS_DISK1_PATH_MAX];/* 0Ch */ } CONFIG_PAGE_RAID_PHYS_DISK_1, MPI_POINTER PTR_CONFIG_PAGE_RAID_PHYS_DISK_1, RaidPhysDiskPage1_t, MPI_POINTER pRaidPhysDiskPage1_t; @@ -2844,6 +2886,7 @@ typedef struct _CONFIG_PAGE_SAS_DEVICE_0 #define MPI_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED (0x01) #define MPI_SAS_DEVICE0_ASTATUS_SATA_CAPABILITY_FAILED (0x02) #define MPI_SAS_DEVICE0_ASTATUS_SATA_AFFILIATION_CONFLICT (0x03) +#define MPI_SAS_DEVICE0_ASTATUS_SATA_NEEDS_INITIALIZATION (0x04) /* specific values for SATA Init failures */ #define MPI_SAS_DEVICE0_ASTATUS_SIF_UNKNOWN (0x10) #define MPI_SAS_DEVICE0_ASTATUS_SIF_AFFILIATION_CONFLICT (0x11) diff --git a/drivers/message/fusion/lsi/mpi_fc.h b/drivers/message/fusion/lsi/mpi_fc.h index 627acfbb862..7d663ce76f8 100644 --- a/drivers/message/fusion/lsi/mpi_fc.h +++ b/drivers/message/fusion/lsi/mpi_fc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2004 LSI Corporation. + * Copyright (c) 2000-2008 LSI Corporation. * * * Name: mpi_fc.h diff --git a/drivers/message/fusion/lsi/mpi_history.txt b/drivers/message/fusion/lsi/mpi_history.txt index 3f15fcfe4a2..693e4b51135 100644 --- a/drivers/message/fusion/lsi/mpi_history.txt +++ b/drivers/message/fusion/lsi/mpi_history.txt @@ -3,28 +3,28 @@ MPI Header File Change History ============================== - Copyright (c) 2000-2007 LSI Corporation. + Copyright (c) 2000-2008 LSI Corporation. --------------------------------------- - Header Set Release Version: 01.05.16 - Header Set Release Date: 05-24-07 + Header Set Release Version: 01.05.19 + Header Set Release Date: 03-28-08 --------------------------------------- Filename Current version Prior version ---------- --------------- ------------- - mpi.h 01.05.13 01.05.12 - mpi_ioc.h 01.05.14 01.05.13 - mpi_cnfg.h 01.05.15 01.05.14 + mpi.h 01.05.16 01.05.15 + mpi_ioc.h 01.05.16 01.05.15 + mpi_cnfg.h 01.05.18 01.05.17 mpi_init.h 01.05.09 01.05.09 mpi_targ.h 01.05.06 01.05.06 mpi_fc.h 01.05.01 01.05.01 mpi_lan.h 01.05.01 01.05.01 - mpi_raid.h 01.05.03 01.05.03 + mpi_raid.h 01.05.05 01.05.05 mpi_tool.h 01.05.03 01.05.03 mpi_inb.h 01.05.01 01.05.01 - mpi_sas.h 01.05.04 01.05.04 + mpi_sas.h 01.05.05 01.05.05 mpi_type.h 01.05.02 01.05.02 - mpi_history.txt 01.05.14 01.05.14 + mpi_history.txt 01.05.19 01.05.18 * Date Version Description @@ -96,6 +96,9 @@ mpi.h * 03-27-06 01.05.11 Bumped MPI_HEADER_VERSION_UNIT. * 10-11-06 01.05.12 Bumped MPI_HEADER_VERSION_UNIT. * 05-24-07 01.05.13 Bumped MPI_HEADER_VERSION_UNIT. + * 08-07-07 01.05.14 Bumped MPI_HEADER_VERSION_UNIT. + * 01-15-08 01.05.15 Bumped MPI_HEADER_VERSION_UNIT. + * 03-28-08 01.05.16 Bumped MPI_HEADER_VERSION_UNIT. * -------------------------------------------------------------------------- mpi_ioc.h @@ -127,7 +130,7 @@ mpi_ioc.h * 08-08-01 01.02.01 Original release for v1.2 work. * New format for FWVersion and ProductId in * MSG_IOC_FACTS_REPLY and MPI_FW_HEADER. - * 08-31-01 01.02.02 Added event MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE and + * 08-31-01 01.02.02 Addded event MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE and * related structure and defines. * Added event MPI_EVENT_ON_BUS_TIMER_EXPIRED. * Added MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE. @@ -187,7 +190,7 @@ mpi_ioc.h * 10-11-06 01.05.12 Added MPI_IOCFACTS_EXCEPT_METADATA_UNSUPPORTED. * Added MaxInitiators field to PortFacts reply. * Added SAS Device Status Change ReasonCode for - * asynchronous notification. + * asynchronous notificaiton. * Added MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE and event * data structure. * Added new ImageType values for FWDownload and FWUpload @@ -199,6 +202,16 @@ mpi_ioc.h * added _MULTI_PORT_DOMAIN. * 05-24-07 01.05.14 Added Common Boot Block type to FWDownload Request. * Added Common Boot Block type to FWUpload Request. + * 08-07-07 01.05.15 Added MPI_EVENT_SAS_INIT_RC_REMOVED define. + * Added MPI_EVENT_IR2_RC_DUAL_PORT_ADDED and + * MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED for IR2 event data. + * Added SASAddress field to SAS Initiator Device Table + * Overflow event data structure. + * 03-28-08 01.05.16 Added two new ReasonCode values to SAS Device Status + * Change Event data to indicate completion of internally + * generated task management. + * Added MPI_EVENT_DSCVRY_ERR_DS_SATA_INIT_FAILURE define. + * Added MPI_EVENT_SAS_INIT_RC_INACCESSIBLE define. * -------------------------------------------------------------------------- mpi_cnfg.h @@ -213,7 +226,7 @@ mpi_cnfg.h * Added _RESPONSE_ID_MASK definition to SCSI_PORT_1 * page and updated the page version. * Added Information field and _INFO_PARAMS_NEGOTIATED - * definition to SCSI_DEVICE_0 page. + * definitionto SCSI_DEVICE_0 page. * 06-22-00 01.00.03 Removed batch controls from LAN_0 page and updated the * page version. * Added BucketsRemaining to LAN_1 page, redefined the @@ -496,6 +509,20 @@ mpi_cnfg.h * Expander Page 0 Flags field. * Fixed define for * MPI_SAS_EXPANDER1_DISCINFO_BAD_PHY_DISABLED. + * 08-07-07 01.05.16 Added MPI_IOCPAGE6_CAP_FLAGS_MULTIPORT_DRIVE_SUPPORT + * define. + * Added BIOS Page 4 structure. + * Added MPI_RAID_PHYS_DISK1_PATH_MAX define for RAID + * Physcial Disk Page 1. + * 01-15-07 01.05.17 Added additional bit defines for ExtFlags field of + * Manufacturing Page 4. + * Added Solid State Drives Supported bit to IOC Page 6 + * Capabilities Flags. + * Added new value for AccessStatus field of SAS Device + * Page 0 (_SATA_NEEDS_INITIALIZATION). + * 03-28-08 01.05.18 Defined new bits in Manufacturing Page 4 ExtFlags field + * to control coercion size and the mixing of SAS and SATA + * SSD drives. * -------------------------------------------------------------------------- mpi_init.h @@ -661,6 +688,9 @@ mpi_raid.h * _SET_RESYNC_RATE and _SET_DATA_SCRUB_RATE. * 02-28-07 01.05.03 Added new RAID Action, Device FW Update Mode, and * associated defines. + * 08-07-07 01.05.04 Added Disable Full Rebuild bit to the ActionDataWord + * for the RAID Action MPI_RAID_ACTION_DISABLE_VOLUME. + * 01-15-08 01.05.05 Added define for MPI_RAID_ACTION_SET_VOLUME_NAME. * -------------------------------------------------------------------------- mpi_tool.h @@ -694,6 +724,10 @@ mpi_sas.h * reply. * 10-11-06 01.05.04 Fixed the name of a define for Operation field of SAS IO * Unit Control request. + * 01-15-08 01.05.05 Added support for MPI_SAS_OP_SET_IOC_PARAMETER, + * including adding IOCParameter and IOCParameter value + * fields to SAS IO Unit Control Request. + * Added MPI_SAS_DEVICE_INFO_PRODUCT_SPECIFIC define. * -------------------------------------------------------------------------- mpi_type.h @@ -709,20 +743,20 @@ mpi_type.h mpi_history.txt Parts list history -Filename 01.05.15 01.05.15 ----------- -------- -------- -mpi.h 01.05.12 01.05.13 -mpi_ioc.h 01.05.13 01.05.14 -mpi_cnfg.h 01.05.14 01.05.15 -mpi_init.h 01.05.09 01.05.09 -mpi_targ.h 01.05.06 01.05.06 -mpi_fc.h 01.05.01 01.05.01 -mpi_lan.h 01.05.01 01.05.01 -mpi_raid.h 01.05.03 01.05.03 -mpi_tool.h 01.05.03 01.05.03 -mpi_inb.h 01.05.01 01.05.01 -mpi_sas.h 01.05.04 01.05.04 -mpi_type.h 01.05.02 01.05.02 +Filename 01.05.19 01.05.18 01.05.17 01.05.16 01.05.15 +---------- -------- -------- -------- -------- -------- +mpi.h 01.05.16 01.05.15 01.05.14 01.05.13 01.05.12 +mpi_ioc.h 01.05.16 01.05.15 01.05.15 01.05.14 01.05.13 +mpi_cnfg.h 01.05.18 01.05.17 01.05.16 01.05.15 01.05.14 +mpi_init.h 01.05.09 01.05.09 01.05.09 01.05.09 01.05.09 +mpi_targ.h 01.05.06 01.05.06 01.05.06 01.05.06 01.05.06 +mpi_fc.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 +mpi_lan.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 +mpi_raid.h 01.05.05 01.05.05 01.05.04 01.05.03 01.05.03 +mpi_tool.h 01.05.03 01.05.03 01.05.03 01.05.03 01.05.03 +mpi_inb.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 +mpi_sas.h 01.05.05 01.05.05 01.05.04 01.05.04 01.05.04 +mpi_type.h 01.05.02 01.05.02 01.05.02 01.05.02 01.05.02 Filename 01.05.14 01.05.13 01.05.12 01.05.11 01.05.10 01.05.09 ---------- -------- -------- -------- -------- -------- -------- diff --git a/drivers/message/fusion/lsi/mpi_init.h b/drivers/message/fusion/lsi/mpi_init.h index a9e3693601a..4295d062caa 100644 --- a/drivers/message/fusion/lsi/mpi_init.h +++ b/drivers/message/fusion/lsi/mpi_init.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2007 LSI Corporation. + * Copyright (c) 2000-2008 LSI Corporation. * * * Name: mpi_init.h diff --git a/drivers/message/fusion/lsi/mpi_ioc.h b/drivers/message/fusion/lsi/mpi_ioc.h index 5cbb6bd048e..8faa4fab7b8 100644 --- a/drivers/message/fusion/lsi/mpi_ioc.h +++ b/drivers/message/fusion/lsi/mpi_ioc.h @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2007 LSI Corporation. + * Copyright (c) 2000-2008 LSI Corporation. * * * Name: mpi_ioc.h * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages * Creation Date: August 11, 2000 * - * mpi_ioc.h Version: 01.05.14 + * mpi_ioc.h Version: 01.05.16 * * Version History * --------------- @@ -113,6 +113,16 @@ * added _MULTI_PORT_DOMAIN. * 05-24-07 01.05.14 Added Common Boot Block type to FWDownload Request. * Added Common Boot Block type to FWUpload Request. + * 08-07-07 01.05.15 Added MPI_EVENT_SAS_INIT_RC_REMOVED define. + * Added MPI_EVENT_IR2_RC_DUAL_PORT_ADDED and + * MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED for IR2 event data. + * Added SASAddress field to SAS Initiator Device Table + * Overflow event data structure. + * 03-28-08 01.05.16 Added two new ReasonCode values to SAS Device Status + * Change Event data to indicate completion of internally + * generated task management. + * Added MPI_EVENT_DSCVRY_ERR_DS_SATA_INIT_FAILURE define. + * Added MPI_EVENT_SAS_INIT_RC_INACCESSIBLE define. * -------------------------------------------------------------------------- */ @@ -612,6 +622,8 @@ typedef struct _EVENT_DATA_SAS_DEVICE_STATUS_CHANGE #define MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL (0x0B) #define MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL (0x0C) #define MPI_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION (0x0D) +#define MPI_EVENT_SAS_DEV_STAT_RC_CMPL_INTERNAL_DEV_RESET (0x0E) +#define MPI_EVENT_SAS_DEV_STAT_RC_CMPL_TASK_ABORT_INTERNAL (0x0F) /* SCSI Event data for Queue Full event */ @@ -708,6 +720,8 @@ typedef struct _MPI_EVENT_DATA_IR2 #define MPI_EVENT_IR2_RC_PD_REMOVED (0x05) #define MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED (0x06) #define MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR (0x07) +#define MPI_EVENT_IR2_RC_DUAL_PORT_ADDED (0x08) +#define MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED (0x09) /* defines for logical disk states */ #define MPI_LD_STATE_OPTIMAL (0x00) @@ -867,6 +881,7 @@ typedef struct _EVENT_DATA_DISCOVERY_ERROR #define MPI_EVENT_DSCVRY_ERR_DS_UNSUPPORTED_DEVICE (0x00000800) #define MPI_EVENT_DSCVRY_ERR_DS_MAX_SATA_TARGETS (0x00001000) #define MPI_EVENT_DSCVRY_ERR_DS_MULTI_PORT_DOMAIN (0x00002000) +#define MPI_EVENT_DSCVRY_ERR_DS_SATA_INIT_FAILURE (0x00004000) /* SAS SMP Error Event data */ @@ -902,6 +917,8 @@ typedef struct _EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE /* defines for the ReasonCode field of the SAS Initiator Device Status Change event */ #define MPI_EVENT_SAS_INIT_RC_ADDED (0x01) +#define MPI_EVENT_SAS_INIT_RC_REMOVED (0x02) +#define MPI_EVENT_SAS_INIT_RC_INACCESSIBLE (0x03) /* SAS Initiator Device Table Overflow Event data */ @@ -910,6 +927,7 @@ typedef struct _EVENT_DATA_SAS_INIT_TABLE_OVERFLOW U8 MaxInit; /* 00h */ U8 CurrentInit; /* 01h */ U16 Reserved1; /* 02h */ + U64 SASAddress; /* 04h */ } EVENT_DATA_SAS_INIT_TABLE_OVERFLOW, MPI_POINTER PTR_EVENT_DATA_SAS_INIT_TABLE_OVERFLOW, MpiEventDataSasInitTableOverflow_t, diff --git a/drivers/message/fusion/lsi/mpi_lan.h b/drivers/message/fusion/lsi/mpi_lan.h index 03253b53b78..f41fcb69b35 100644 --- a/drivers/message/fusion/lsi/mpi_lan.h +++ b/drivers/message/fusion/lsi/mpi_lan.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2004 LSI Corporation. + * Copyright (c) 2000-2008 LSI Corporation. * * * Name: mpi_lan.h diff --git a/drivers/message/fusion/lsi/mpi_log_fc.h b/drivers/message/fusion/lsi/mpi_log_fc.h index e4dafcefeec..face6e7acc7 100644 --- a/drivers/message/fusion/lsi/mpi_log_fc.h +++ b/drivers/message/fusion/lsi/mpi_log_fc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2001 LSI Corporation. All rights reserved. + * Copyright (c) 2000-2008 LSI Corporation. All rights reserved. * * NAME: fc_log.h * SUMMARY: MPI IocLogInfo definitions for the SYMFC9xx chips diff --git a/drivers/message/fusion/lsi/mpi_log_sas.h b/drivers/message/fusion/lsi/mpi_log_sas.h index af9da03e95e..691620dbedd 100644 --- a/drivers/message/fusion/lsi/mpi_log_sas.h +++ b/drivers/message/fusion/lsi/mpi_log_sas.h @@ -1,6 +1,6 @@ /*************************************************************************** * * - * Copyright 2003 LSI Corporation. All rights reserved. * + * Copyright (c) 2000-2008 LSI Corporation. All rights reserved. * * * * Description * * ------------ * @@ -73,6 +73,8 @@ #define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_EXACT_IO (0x00070004) #define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_EXACT_IO_REQ (0x00070005) +#define IOP_LOGINFO_CODE_LOG_TIMESTAMP_EVENT (0x00080000) + /****************************************************************************/ /* PL LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = PL */ /****************************************************************************/ @@ -92,7 +94,7 @@ #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_OPEN_TIMEOUT_EXP (0x0000000C) #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_UNUSED_0D (0x0000000D) #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_DVTBLE_ACCSS_FAIL (0x0000000E) -#define PL_LOGINFO_SUB CODE_OPEN_FAIL_BAD_DEST (0x00000011) +#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_BAD_DEST (0x00000011) #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RATE_NOT_SUPP (0x00000012) #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_PROT_NOT_SUPP (0x00000013) #define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RESERVED_ABANDON0 (0x00000014) @@ -159,10 +161,11 @@ #define PL_LOGINFO_SUB_CODE_INVALID_SGL (0x00000200) #define PL_LOGINFO_SUB_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00000300) -#define PL_LOGINFO_SUB_CODE_FRAME_XFER_ERROR (0x00000400) /* Bits 0-3 encode Transport Status Register (offset 0x08) */ - /* Bit 0 is Status Bit 0: FrameXferErr */ - /* Bit 1 & 2 are Status Bits 16 and 17: FrameXmitErrStatus */ - /* Bit 3 is Status Bit 18 WriteDataLengthGTDataLengthErr */ +#define PL_LOGINFO_SUB_CODE_FRAME_XFER_ERROR (0x00000400) +/* Bits 0-3 encode Transport Status Register (offset 0x08) */ +/* Bit 0 is Status Bit 0: FrameXferErr */ +/* Bit 1 & 2 are Status Bits 16 and 17: FrameXmitErrStatus */ +/* Bit 3 is Status Bit 18 WriteDataLenghtGTDataLengthErr */ #define PL_LOGINFO_SUB_CODE_TX_FM_CONNECTED_LOW (0x00000500) #define PL_LOGINFO_SUB_CODE_SATA_NON_NCQ_RW_ERR_BIT_SET (0x00000600) @@ -177,6 +180,11 @@ #define PL_LOGINFO_SUB_CODE_DISCOVERY_REMOTE_SEP_RESET (0x00000E01) #define PL_LOGINFO_SUB_CODE_SECOND_OPEN (0x00000F00) #define PL_LOGINFO_SUB_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00001000) +#define PL_LOGINFO_SUB_CODE_BREAK_ON_SATA_CONNECTION (0x00002000) +/* not currently used in mainline */ +#define PL_LOGINFO_SUB_CODE_BREAK_ON_STUCK_LINK (0x00003000) +#define PL_LOGINFO_SUB_CODE_BREAK_ON_STUCK_LINK_AIP (0x00004000) +#define PL_LOGINFO_SUB_CODE_BREAK_ON_INCOMPLETE_BREAK_RCVD (0x00005000) #define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_FAILURE (0x00200000) /* Can't get SMP Frame */ #define PL_LOGINFO_CODE_ENCL_MGMT_SMP_READ_ERROR (0x00200010) /* Error occured on SMP Read */ @@ -243,6 +251,8 @@ #define IR_LOGINFO_VOLUME_ACTIVATE_VOLUME_FAILED (0x00010014) /* Activation failed trying to import the volume */ #define IR_LOGINFO_VOLUME_ACTIVATING_IMPORT_VOLUME_FAILED (0x00010015) +/* Activation failed trying to import the volume */ +#define IR_LOGINFO_VOLUME_ACTIVATING_TOO_MANY_PHYS_DISKS (0x00010016) /* Phys Disk failed, too many phys disks */ #define IR_LOGINFO_PHYSDISK_CREATE_TOO_MANY_DISKS (0x00010020) @@ -285,6 +295,21 @@ /* Compatibility Error : IME size limited to < 2TB */ #define IR_LOGINFO_COMPAT_ERROR_IME_VOL_NOT_CURRENTLY_SUPPORTED (0x0001003D) +/* Device Firmware Update: DFU can only be started once */ +#define IR_LOGINFO_DEV_FW_UPDATE_ERR_DFU_IN_PROGRESS (0x00010050) +/* Device Firmware Update: Volume must be Optimal/Active/non-Quiesced */ +#define IR_LOGINFO_DEV_FW_UPDATE_ERR_DEVICE_IN_INVALID_STATE (0x00010051) +/* Device Firmware Update: DFU Timeout cannot be zero */ +#define IR_LOGINFO_DEV_FW_UPDATE_ERR_INVALID_TIMEOUT (0x00010052) +/* Device Firmware Update: CREATE TIMER FAILED */ +#define IR_LOGINFO_DEV_FW_UPDATE_ERR_NO_TIMERS (0x00010053) +/* Device Firmware Update: Failed to read SAS_IO_UNIT_PG_1 */ +#define IR_LOGINFO_DEV_FW_UPDATE_ERR_READING_CFG_PAGE (0x00010054) +/* Device Firmware Update: Invalid SAS_IO_UNIT_PG_1 value(s) */ +#define IR_LOGINFO_DEV_FW_UPDATE_ERR_PORT_IO_TIMEOUTS_REQUIRED (0x00010055) +/* Device Firmware Update: Unable to allocate memory for page */ +#define IR_LOGINFO_DEV_FW_UPDATE_ERR_ALLOC_CFG_PAGE (0x00010056) + /****************************************************************************/ /* Defines for convenience */ diff --git a/drivers/message/fusion/lsi/mpi_raid.h b/drivers/message/fusion/lsi/mpi_raid.h index 2856108421d..add60cc85be 100644 --- a/drivers/message/fusion/lsi/mpi_raid.h +++ b/drivers/message/fusion/lsi/mpi_raid.h @@ -1,12 +1,12 @@ /* - * Copyright (c) 2001-2007 LSI Corporation. + * Copyright (c) 2001-2008 LSI Corporation. * * * Name: mpi_raid.h * Title: MPI RAID message and structures * Creation Date: February 27, 2001 * - * mpi_raid.h Version: 01.05.03 + * mpi_raid.h Version: 01.05.05 * * Version History * --------------- @@ -34,6 +34,9 @@ * _SET_RESYNC_RATE and _SET_DATA_SCRUB_RATE. * 02-28-07 01.05.03 Added new RAID Action, Device FW Update Mode, and * associated defines. + * 08-07-07 01.05.04 Added Disable Full Rebuild bit to the ActionDataWord + * for the RAID Action MPI_RAID_ACTION_DISABLE_VOLUME. + * 01-15-08 01.05.05 Added define for MPI_RAID_ACTION_SET_VOLUME_NAME. * -------------------------------------------------------------------------- */ @@ -93,6 +96,7 @@ typedef struct _MSG_RAID_ACTION #define MPI_RAID_ACTION_SET_RESYNC_RATE (0x13) #define MPI_RAID_ACTION_SET_DATA_SCRUB_RATE (0x14) #define MPI_RAID_ACTION_DEVICE_FW_UPDATE_MODE (0x15) +#define MPI_RAID_ACTION_SET_VOLUME_NAME (0x16) /* ActionDataWord defines for use with MPI_RAID_ACTION_CREATE_VOLUME action */ #define MPI_RAID_ACTION_ADATA_DO_NOT_SYNC (0x00000001) @@ -105,6 +109,9 @@ typedef struct _MSG_RAID_ACTION #define MPI_RAID_ACTION_ADATA_KEEP_LBA0 (0x00000000) #define MPI_RAID_ACTION_ADATA_ZERO_LBA0 (0x00000002) +/* ActionDataWord defines for use with MPI_RAID_ACTION_DISABLE_VOLUME action */ +#define MPI_RAID_ACTION_ADATA_DISABLE_FULL_REBUILD (0x00000001) + /* ActionDataWord defines for use with MPI_RAID_ACTION_ACTIVATE_VOLUME action */ #define MPI_RAID_ACTION_ADATA_INACTIVATE_ALL (0x00000001) diff --git a/drivers/message/fusion/lsi/mpi_sas.h b/drivers/message/fusion/lsi/mpi_sas.h index 33fca83cefc..ab410036bbf 100644 --- a/drivers/message/fusion/lsi/mpi_sas.h +++ b/drivers/message/fusion/lsi/mpi_sas.h @@ -1,12 +1,12 @@ /* - * Copyright (c) 2004-2006 LSI Corporation. + * Copyright (c) 2004-2008 LSI Corporation. * * * Name: mpi_sas.h * Title: MPI Serial Attached SCSI structures and definitions * Creation Date: August 19, 2004 * - * mpi_sas.h Version: 01.05.04 + * mpi_sas.h Version: 01.05.05 * * Version History * --------------- @@ -23,6 +23,10 @@ * reply. * 10-11-06 01.05.04 Fixed the name of a define for Operation field of SAS IO * Unit Control request. + * 01-15-08 01.05.05 Added support for MPI_SAS_OP_SET_IOC_PARAMETER, + * including adding IOCParameter and IOCParameter value + * fields to SAS IO Unit Control Request. + * Added MPI_SAS_DEVICE_INFO_PRODUCT_SPECIFIC define. * -------------------------------------------------------------------------- */ @@ -60,6 +64,8 @@ * Values for the SAS DeviceInfo field used in SAS Device Status Change Event * data and SAS IO Unit Configuration pages. */ +#define MPI_SAS_DEVICE_INFO_PRODUCT_SPECIFIC (0xF0000000) + #define MPI_SAS_DEVICE_INFO_SEP (0x00004000) #define MPI_SAS_DEVICE_INFO_ATAPI_DEVICE (0x00002000) #define MPI_SAS_DEVICE_INFO_LSI_DEVICE (0x00001000) @@ -216,7 +222,7 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST U8 ChainOffset; /* 02h */ U8 Function; /* 03h */ U16 DevHandle; /* 04h */ - U8 Reserved3; /* 06h */ + U8 IOCParameter; /* 06h */ U8 MsgFlags; /* 07h */ U32 MsgContext; /* 08h */ U8 TargetID; /* 0Ch */ @@ -225,7 +231,7 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST U8 PrimFlags; /* 0Fh */ U32 Primitive; /* 10h */ U64 SASAddress; /* 14h */ - U32 Reserved4; /* 1Ch */ + U32 IOCParameterValue; /* 1Ch */ } MSG_SAS_IOUNIT_CONTROL_REQUEST, MPI_POINTER PTR_MSG_SAS_IOUNIT_CONTROL_REQUEST, SasIoUnitControlRequest_t, MPI_POINTER pSasIoUnitControlRequest_t; @@ -241,6 +247,8 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST #define MPI_SAS_OP_TRANSMIT_PORT_SELECT_SIGNAL (0x0C) #define MPI_SAS_OP_TRANSMIT_REMOVE_DEVICE (0x0D) /* obsolete name */ #define MPI_SAS_OP_REMOVE_DEVICE (0x0D) +#define MPI_SAS_OP_SET_IOC_PARAMETER (0x0E) +#define MPI_SAS_OP_PRODUCT_SPECIFIC_MIN (0x80) /* values for the PrimFlags field */ #define MPI_SAS_PRIMFLAGS_SINGLE (0x08) @@ -256,7 +264,7 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REPLY U8 MsgLength; /* 02h */ U8 Function; /* 03h */ U16 DevHandle; /* 04h */ - U8 Reserved3; /* 06h */ + U8 IOCParameter; /* 06h */ U8 MsgFlags; /* 07h */ U32 MsgContext; /* 08h */ U16 Reserved4; /* 0Ch */ diff --git a/drivers/message/fusion/lsi/mpi_targ.h b/drivers/message/fusion/lsi/mpi_targ.h index ff8c37d3fdc..c3dea7f6909 100644 --- a/drivers/message/fusion/lsi/mpi_targ.h +++ b/drivers/message/fusion/lsi/mpi_targ.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2004 LSI Corporation. + * Copyright (c) 2000-2008 LSI Corporation. * * * Name: mpi_targ.h diff --git a/drivers/message/fusion/lsi/mpi_tool.h b/drivers/message/fusion/lsi/mpi_tool.h index 8834ae6ce0f..53cd715aa7e 100644 --- a/drivers/message/fusion/lsi/mpi_tool.h +++ b/drivers/message/fusion/lsi/mpi_tool.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2005 LSI Corporation. + * Copyright (c) 2001-2008 LSI Corporation. * * * Name: mpi_tool.h diff --git a/drivers/message/fusion/lsi/mpi_type.h b/drivers/message/fusion/lsi/mpi_type.h index 08dad9c1e44..888b26dbc41 100644 --- a/drivers/message/fusion/lsi/mpi_type.h +++ b/drivers/message/fusion/lsi/mpi_type.h @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2004 LSI Corporation. + * Copyright (c) 2000-2008 LSI Corporation. * * * Name: mpi_type.h * Title: MPI Basic type definitions * Creation Date: June 6, 2000 * - * mpi_type.h Version: 01.05.01 + * mpi_type.h Version: 01.05.02 * * Version History * --------------- -- cgit From e382968ba618e016ff7922dff9a6140c2f9108c8 Mon Sep 17 00:00:00 2001 From: "Kashyap, Desai" Date: Thu, 8 Jan 2009 14:27:16 +0530 Subject: [SCSI] mpt fusion: Add separate msi enable disable for FC,SPI,SAS Added support for MSI enable/disable for different buses FC,SPI,SAS instead of having single MSI enable/disable feature. Signed-off-by: Kashyap Desai Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.c | 50 +++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index c4e8b9aa382..787a12648db 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -79,9 +79,22 @@ MODULE_VERSION(my_VERSION); /* * cmd line parameters */ -static int mpt_msi_enable = -1; -module_param(mpt_msi_enable, int, 0); -MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)"); + +static int mpt_msi_enable_spi; +module_param(mpt_msi_enable_spi, int, 0); +MODULE_PARM_DESC(mpt_msi_enable_spi, " Enable MSI Support for SPI \ + controllers (default=0)"); + +static int mpt_msi_enable_fc; +module_param(mpt_msi_enable_fc, int, 0); +MODULE_PARM_DESC(mpt_msi_enable_fc, " Enable MSI Support for FC \ + controllers (default=0)"); + +static int mpt_msi_enable_sas; +module_param(mpt_msi_enable_sas, int, 1); +MODULE_PARM_DESC(mpt_msi_enable_sas, " Enable MSI Support for SAS \ + controllers (default=1)"); + static int mpt_channel_mapping; module_param(mpt_channel_mapping, int, 0); @@ -91,7 +104,9 @@ static int mpt_debug_level; static int mpt_set_debug_level(const char *val, struct kernel_param *kp); module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int, &mpt_debug_level, 0600); -MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h - (default=0)"); +MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h \ + - (default=0)"); + #ifdef MFCNT static int mfcounter = 0; @@ -1751,16 +1766,25 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) ioc->bus_type = SAS; } - if (mpt_msi_enable == -1) { - /* Enable on SAS, disable on FC and SPI */ - if (ioc->bus_type == SAS) - ioc->msi_enable = 1; - else - ioc->msi_enable = 0; - } else - /* follow flag: 0 - disable; 1 - enable */ - ioc->msi_enable = mpt_msi_enable; + switch (ioc->bus_type) { + + case SAS: + ioc->msi_enable = mpt_msi_enable_sas; + break; + + case SPI: + ioc->msi_enable = mpt_msi_enable_spi; + break; + + case FC: + ioc->msi_enable = mpt_msi_enable_fc; + break; + + default: + ioc->msi_enable = 0; + break; + } if (ioc->errata_flag_1064) pci_disable_io_access(pdev); -- cgit From 2f4c782c2e06fbaef2ac2b6b7abd796b96abd98b Mon Sep 17 00:00:00 2001 From: "Kashyap, Desai" Date: Tue, 6 Jan 2009 15:03:37 +0530 Subject: [SCSI] mpt fusion: Add Firmware debug support Signed-off-by: Kashyap Desai Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.c | 37 +++++++++++++++++++++++++++++++++++++ drivers/message/fusion/mptbase.h | 3 +++ drivers/message/fusion/mptscsih.c | 3 +++ 3 files changed, 43 insertions(+) diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 787a12648db..96ac88317b8 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -107,6 +107,14 @@ module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int, MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h \ - (default=0)"); +int mpt_fwfault_debug; +EXPORT_SYMBOL(mpt_fwfault_debug); +module_param_call(mpt_fwfault_debug, param_set_int, param_get_int, + &mpt_fwfault_debug, 0600); +MODULE_PARM_DESC(mpt_fwfault_debug, "Enable detection of Firmware fault" + " and halt Firmware on fault - (default=0)"); + + #ifdef MFCNT static int mfcounter = 0; @@ -6337,6 +6345,33 @@ mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int sh *size = y; } + +/** + * mpt_halt_firmware - Halts the firmware if it is operational and panic + * the kernel + * @ioc: Pointer to MPT_ADAPTER structure + * + **/ +void +mpt_halt_firmware(MPT_ADAPTER *ioc) +{ + u32 ioc_raw_state; + + ioc_raw_state = mpt_GetIocState(ioc, 0); + + if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) { + printk(MYIOC_s_ERR_FMT "IOC is in FAULT state (%04xh)!!!\n", + ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK); + panic("%s: IOC Fault (%04xh)!!!\n", ioc->name, + ioc_raw_state & MPI_DOORBELL_DATA_MASK); + } else { + CHIPREG_WRITE32(&ioc->chip->Doorbell, 0xC0FFEE00); + panic("%s: Firmware is halted due to command timeout\n", + ioc->name); + } +} +EXPORT_SYMBOL(mpt_halt_firmware); + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * Reset Handling @@ -6369,6 +6404,8 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag) printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name); printk("MF count 0x%x !\n", ioc->mfcnt); #endif + if (mpt_fwfault_debug) + mpt_halt_firmware(ioc); /* Reset the adapter. Prevent more than 1 call to * mpt_do_ioc_recovery at any instant in time. diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index dff048cfa10..b3e981d2a50 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -922,11 +922,14 @@ extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); extern int mpt_findImVolumes(MPT_ADAPTER *ioc); extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); extern int mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk); +extern void mpt_halt_firmware(MPT_ADAPTER *ioc); + /* * Public data decl's... */ extern struct list_head ioc_list; +extern int mpt_fwfault_debug; /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ #endif /* } __KERNEL__ */ diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index ee090413e59..e62c6bc4ad3 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -1846,6 +1846,9 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) if (hd->timeouts < -1) hd->timeouts++; + if (mpt_fwfault_debug) + mpt_halt_firmware(ioc); + /* Most important! Set TaskMsgContext to SCpnt's MsgContext! * (the IO to be ABORT'd) * -- cgit From 2856830bd395fbc2f0c5327effe71fb025dd262d Mon Sep 17 00:00:00 2001 From: Karen Xie Date: Sat, 10 Jan 2009 19:06:07 -0800 Subject: [SCSI] iscsi_tcp: make padbuf non-static virt_to_page() call should not be used on kernel text and data addresses. virt_to_page() is used by sg_init_one(). So change padbuf to be allocated within iscsi_segment. Signed-off-by: Karen Xie Acked-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/libiscsi_tcp.c | 3 +-- include/scsi/libiscsi_tcp.h | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c index a745f91d292..e7705d3532c 100644 --- a/drivers/scsi/libiscsi_tcp.c +++ b/drivers/scsi/libiscsi_tcp.c @@ -177,7 +177,6 @@ int iscsi_tcp_segment_done(struct iscsi_tcp_conn *tcp_conn, struct iscsi_segment *segment, int recv, unsigned copied) { - static unsigned char padbuf[ISCSI_PAD_LEN]; struct scatterlist sg; unsigned int pad; @@ -233,7 +232,7 @@ int iscsi_tcp_segment_done(struct iscsi_tcp_conn *tcp_conn, debug_tcp("consume %d pad bytes\n", pad); segment->total_size += pad; segment->size = pad; - segment->data = padbuf; + segment->data = segment->padbuf; return 0; } } diff --git a/include/scsi/libiscsi_tcp.h b/include/scsi/libiscsi_tcp.h index 83e32f6d785..9e3182e659d 100644 --- a/include/scsi/libiscsi_tcp.h +++ b/include/scsi/libiscsi_tcp.h @@ -39,6 +39,7 @@ struct iscsi_segment { unsigned int total_copied; struct hash_desc *hash; + unsigned char padbuf[ISCSI_PAD_LEN]; unsigned char recv_digest[ISCSI_DIGEST_SIZE]; unsigned char digest[ISCSI_DIGEST_SIZE]; unsigned int digest_len; -- cgit From debf47779efd6eace440c884c8cca2665d966eb4 Mon Sep 17 00:00:00 2001 From: "ILLES, Marton" Date: Mon, 12 Jan 2009 15:45:52 +0100 Subject: [SCSI] Add SUN Universal Xport to no attach blacklist I was using a Sun ST2510 device (iSCSI) and a special "block device" appeared which is used by SUN Common Array Manager in-band management. However it also appeared as a block device and caused some IO error: [ 716.868000] scsi 15:0:0:31: Direct-Access SUN Universal Xport 0735 PQ: 0 ANSI: 5 [ 716.868000] qla4xxx 0000:04:01.1: scsi(15:0:0:31): Enabled tagged queuing, queue depth 32. [ 716.868000] sd 15:0:0:31: [sdf] 40960 512-byte hardware sectors (21 MB) [ 716.868000] sd 15:0:0:31: [sdf] Write Protect is off [ 716.868000] sd 15:0:0:31: [sdf] Mode Sense: 77 00 10 08 [ 716.868000] sd 15:0:0:31: [sdf] Write cache: disabled, read cache: enabled, supports DPO and FUA [ 716.868000] sd 15:0:0:31: [sdf] 40960 512-byte hardware sectors (21 MB) [ 716.868000] sd 15:0:0:31: [sdf] Write Protect is off [ 716.868000] sd 15:0:0:31: [sdf] Mode Sense: 77 00 10 08 [ 716.872000] sd 15:0:0:31: [sdf] Write cache: disabled, read cache: enabled, supports DPO and FUA [ 716.872000] sdf: unknown partition table [ 716.932000] sd 15:0:0:31: [sdf] Attached SCSI disk [ 716.932000] sd 15:0:0:31: Attached scsi generic sg6 type 0 [ 717.412000] end_request: I/O error, dev sdf, sector 40 [ 717.412000] Buffer I/O error on device sdf, logical block 5 [ 717.412000] Buffer I/O error on device sdf, logical block 6 [ 717.412000] Buffer I/O error on device sdf, logical block 7 [ 717.412000] Buffer I/O error on device sdf, logical block 8 [ 717.412000] Buffer I/O error on device sdf, logical block 9 [ 717.412000] Buffer I/O error on device sdf, logical block 10 [ 717.412000] Buffer I/O error on device sdf, logical block 11 [ 717.412000] Buffer I/O error on device sdf, logical block 12 [ 717.412000] Buffer I/O error on device sdf, logical block 13 [ 717.412000] Buffer I/O error on device sdf, logical block 14 After some googling it appeared that similar issue has been solved for SGI/IBM devices in 4869040512082b761de2d7c35975d01044f8bfea, so here is the patch for SUN, please apply. Signed-off-by: James Bottomley --- drivers/scsi/scsi_devinfo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index 4969e4ec75e..099b5455bbc 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -224,6 +224,7 @@ static struct { {"SGI", "TP9100", "*", BLIST_REPORTLUN2}, {"SGI", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, {"IBM", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, + {"SUN", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, {"SMSC", "USB 2 HS-CF", NULL, BLIST_SPARSELUN | BLIST_INQUIRY_36}, {"SONY", "CD-ROM CDU-8001", NULL, BLIST_BORKEN}, {"SONY", "TSL", NULL, BLIST_FORCELUN}, /* DDS3 & DDS4 autoloaders */ -- cgit From c107b41c485c43f15b24743e81eaab742b3c0b67 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 13 Jan 2009 17:46:37 +0100 Subject: ALSA: hda - Use queue_delayed_work() Replaced the old schedule_work() with queue_delayed_work() where overlooked in the previous patches. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 3c596da2b9b..fdad6ae7aad 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2815,7 +2815,7 @@ void snd_hda_power_down(struct hda_codec *codec) return; if (power_save(codec)) { codec->power_transition = 1; /* avoid reentrance */ - schedule_delayed_work(&codec->power_work, + queue_delayed_work(codec->bus->workq, &codec->power_work, msecs_to_jiffies(power_save(codec) * 1000)); } } -- cgit From 32aeef605aa01e1fee45e052eceffb00e72ba2b0 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 13 Jan 2009 16:50:37 +0100 Subject: [SCSI] Skip deleted devices in __scsi_device_lookup_by_target() __scsi_device_lookup_by_target() will always return the first sdev with a matching LUN, regardless of the state. However, when this sdev is in SDEV_DEL scsi_device_lookup_by_target() will ignore this device and so any valid device on the list after the deleted device will never be found. So we have to modify __scsi_device_lookup_by_target() to skip any device in SDEV_DEL. Signed-off-by: Hannes Reinecke Signed-off-by: James Bottomley --- drivers/scsi/scsi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 42e72a2c1f9..cbcd3f681b6 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -1095,7 +1095,8 @@ EXPORT_SYMBOL(__starget_for_each_device); * Description: Looks up the scsi_device with the specified @lun for a given * @starget. The returned scsi_device does not have an additional * reference. You must hold the host's host_lock over this call and - * any access to the returned scsi_device. + * any access to the returned scsi_device. A scsi_device in state + * SDEV_DEL is skipped. * * Note: The only reason why drivers should use this is because * they need to access the device list in irq context. Otherwise you @@ -1107,6 +1108,8 @@ struct scsi_device *__scsi_device_lookup_by_target(struct scsi_target *starget, struct scsi_device *sdev; list_for_each_entry(sdev, &starget->devices, same_target_siblings) { + if (sdev->sdev_state == SDEV_DEL) + continue; if (sdev->lun ==lun) return sdev; } -- cgit From 417bec5b0f25e000866f1be845d44a3ca0690697 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 13 Jan 2009 17:57:12 +0100 Subject: ALSA: hda - Update model descriptions in patch_sigmatel.c Update models in patch_sigmatel.c, mainly for the last Gateway updates. Signed-off-by: Takashi Iwai --- Documentation/sound/alsa/HD-Audio-Models.txt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt index 4b7ac21ea9e..64eb1100eec 100644 --- a/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/Documentation/sound/alsa/HD-Audio-Models.txt @@ -275,7 +275,8 @@ STAC9200 dell-m25 Dell Inspiron E1505n dell-m26 Dell Inspiron 1501 dell-m27 Dell Inspiron E1705/9400 - gateway Gateway laptops with EAPD control + gateway-m4 Gateway laptops with EAPD control + gateway-m4-2 Gateway laptops with EAPD control panasonic Panasonic CF-74 STAC9205/9254 @@ -302,6 +303,7 @@ STAC9220/9221 macbook-pro Intel Mac Book Pro 2nd generation (eq. type 3) imac-intel Intel iMac (eq. type 2) imac-intel-20 Intel iMac (newer version) (eq. type 3) + ecs202 ECS/PC chips dell-d81 Dell (unknown) dell-d82 Dell (unknown) dell-m81 Dell (unknown) @@ -310,9 +312,13 @@ STAC9220/9221 STAC9202/9250/9251 ================== ref Reference board, base config + m1 Some Gateway MX series laptops (NX560XL) + m1-2 Some Gateway MX series laptops (MX6453) + m2 Some Gateway MX series laptops (M255) m2-2 Some Gateway MX series laptops + m3 Some Gateway MX series laptops + m5 Some Gateway MX series laptops (MP6954) m6 Some Gateway NX series laptops - pa6 Gateway NX860 series STAC9227/9228/9229/927x ======================= @@ -329,6 +335,7 @@ STAC92HD71B* dell-m4-1 Dell desktops dell-m4-2 Dell desktops dell-m4-3 Dell desktops + hp-m4 HP dv laptops STAC92HD73* =========== @@ -337,6 +344,7 @@ STAC92HD73* dell-m6-amic Dell desktops/laptops with analog mics dell-m6-dmic Dell desktops/laptops with digital mics dell-m6 Dell desktops/laptops with both type of mics + dell-eq Dell desktops/laptops STAC92HD83* =========== -- cgit From c8399943bdb70fef78798b97f975506ecc99e039 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 12 Jan 2009 23:01:15 +0100 Subject: x86, generic: mark complex bitops.h inlines as __always_inline Impact: reduce kernel image size Hugh Dickins noticed that older gcc versions when the kernel is built for code size didn't inline some of the bitops. Mark all complex x86 bitops that have more than a single asm statement or two as always inline to avoid this problem. Probably should be done for other architectures too. Ingo then found a better fix that only requires a single line change, but it unfortunately only works on gcc 4.3. On older gccs the original patch still makes a ~0.3% defconfig difference with CONFIG_OPTIMIZE_INLINING=y. With gcc 4.1 and a defconfig like build: 6116998 1138540 883788 8139326 7c323e vmlinux-oi-with-patch 6137043 1138540 883788 8159371 7c808b vmlinux-optimize-inlining ~20k / 0.3% difference. Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar --- arch/x86/include/asm/bitops.h | 14 ++++++++++---- include/asm-generic/bitops/__ffs.h | 2 +- include/asm-generic/bitops/__fls.h | 2 +- include/asm-generic/bitops/fls.h | 2 +- include/asm-generic/bitops/fls64.h | 4 ++-- 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h index e02a359d2aa..02b47a603fc 100644 --- a/arch/x86/include/asm/bitops.h +++ b/arch/x86/include/asm/bitops.h @@ -3,6 +3,9 @@ /* * Copyright 1992, Linus Torvalds. + * + * Note: inlines with more than a single statement should be marked + * __always_inline to avoid problems with older gcc's inlining heuristics. */ #ifndef _LINUX_BITOPS_H @@ -53,7 +56,8 @@ * Note that @nr may be almost arbitrarily large; this function is not * restricted to acting on a single-word quantity. */ -static inline void set_bit(unsigned int nr, volatile unsigned long *addr) +static __always_inline void +set_bit(unsigned int nr, volatile unsigned long *addr) { if (IS_IMMEDIATE(nr)) { asm volatile(LOCK_PREFIX "orb %1,%0" @@ -90,7 +94,8 @@ static inline void __set_bit(int nr, volatile unsigned long *addr) * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() * in order to ensure changes are visible on other processors. */ -static inline void clear_bit(int nr, volatile unsigned long *addr) +static __always_inline void +clear_bit(int nr, volatile unsigned long *addr) { if (IS_IMMEDIATE(nr)) { asm volatile(LOCK_PREFIX "andb %1,%0" @@ -204,7 +209,8 @@ static inline int test_and_set_bit(int nr, volatile unsigned long *addr) * * This is the same as test_and_set_bit on x86. */ -static inline int test_and_set_bit_lock(int nr, volatile unsigned long *addr) +static __always_inline int +test_and_set_bit_lock(int nr, volatile unsigned long *addr) { return test_and_set_bit(nr, addr); } @@ -300,7 +306,7 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr) return oldbit; } -static inline int constant_test_bit(unsigned int nr, const volatile unsigned long *addr) +static __always_inline int constant_test_bit(unsigned int nr, const volatile unsigned long *addr) { return ((1UL << (nr % BITS_PER_LONG)) & (((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0; diff --git a/include/asm-generic/bitops/__ffs.h b/include/asm-generic/bitops/__ffs.h index 9a3274aecf8..937d7c43557 100644 --- a/include/asm-generic/bitops/__ffs.h +++ b/include/asm-generic/bitops/__ffs.h @@ -9,7 +9,7 @@ * * Undefined if no bit exists, so code should check against 0 first. */ -static inline unsigned long __ffs(unsigned long word) +static __always_inline unsigned long __ffs(unsigned long word) { int num = 0; diff --git a/include/asm-generic/bitops/__fls.h b/include/asm-generic/bitops/__fls.h index be24465403d..a60a7ccb678 100644 --- a/include/asm-generic/bitops/__fls.h +++ b/include/asm-generic/bitops/__fls.h @@ -9,7 +9,7 @@ * * Undefined if no set bit exists, so code should check against 0 first. */ -static inline unsigned long __fls(unsigned long word) +static __always_inline unsigned long __fls(unsigned long word) { int num = BITS_PER_LONG - 1; diff --git a/include/asm-generic/bitops/fls.h b/include/asm-generic/bitops/fls.h index 850859bc506..0576d1f42f4 100644 --- a/include/asm-generic/bitops/fls.h +++ b/include/asm-generic/bitops/fls.h @@ -9,7 +9,7 @@ * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. */ -static inline int fls(int x) +static __always_inline int fls(int x) { int r = 32; diff --git a/include/asm-generic/bitops/fls64.h b/include/asm-generic/bitops/fls64.h index 86d403f8b25..b097cf8444e 100644 --- a/include/asm-generic/bitops/fls64.h +++ b/include/asm-generic/bitops/fls64.h @@ -15,7 +15,7 @@ * at position 64. */ #if BITS_PER_LONG == 32 -static inline int fls64(__u64 x) +static __always_inline int fls64(__u64 x) { __u32 h = x >> 32; if (h) @@ -23,7 +23,7 @@ static inline int fls64(__u64 x) return fls(x); } #elif BITS_PER_LONG == 64 -static inline int fls64(__u64 x) +static __always_inline int fls64(__u64 x) { if (x == 0) return 0; -- cgit From 5597b25c300eeaf43392f399990d3f3027a9b779 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Thu, 8 Jan 2009 18:11:56 -0600 Subject: powerpc/e500mc: Doorbells need to be taken w/exceptions disabled We use Doorbell interrupts for IPIs and thus we need to make sure we aren't interrupted in the process of processing the IPI. Signed-off-by: Kumar Gala Acked-by: Dave Liu --- arch/powerpc/kernel/head_fsl_booke.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 2f32720a44a..36ffb3504a4 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -707,7 +707,7 @@ interrupt_base: EXCEPTION(0x2060, PerformanceMonitor, performance_monitor_exception, EXC_XFER_STD) #ifdef CONFIG_PPC_E500MC - EXCEPTION(0x2070, Doorbell, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2070, Doorbell, unknown_exception, EXC_XFER_STD) #endif /* Debug Interrupt */ -- cgit From 6c9789de2a02755101f757789ffcb17312f3fa9b Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sun, 11 Jan 2009 18:30:13 +0300 Subject: powerpc/83xx: Make serial ports work on MPC8315E-RDB w/ FSL U-Boots FSL U-Boots use /soc8315@e0000000 node to search and fixup serial nodes' clock-frequency properties. Though in upstream kernels we use new naming convention -- for IMMR address space dts files specify /immr@e0000000 nodes. This makes FSL U-Boots fail to fixup the clock frequencies, and that leads to serial ports misbehaviour. We can workaround the issue by filling the clock frequency values manually. p.s. For the same reason FSL U-Boots fail to fixup MAC addresses for ethernet nodes, so users should either change the .dts file locally or set MAC address via `ifconfig hw ether' command. Signed-off-by: Anton Vorontsov Signed-off-by: Kumar Gala --- arch/powerpc/boot/dts/mpc8315erdb.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/boot/dts/mpc8315erdb.dts b/arch/powerpc/boot/dts/mpc8315erdb.dts index 072c9b0f8c8..71784165b77 100644 --- a/arch/powerpc/boot/dts/mpc8315erdb.dts +++ b/arch/powerpc/boot/dts/mpc8315erdb.dts @@ -255,7 +255,7 @@ device_type = "serial"; compatible = "ns16550"; reg = <0x4500 0x100>; - clock-frequency = <0>; + clock-frequency = <133333333>; interrupts = <9 0x8>; interrupt-parent = <&ipic>; }; @@ -265,7 +265,7 @@ device_type = "serial"; compatible = "ns16550"; reg = <0x4600 0x100>; - clock-frequency = <0>; + clock-frequency = <133333333>; interrupts = <10 0x8>; interrupt-parent = <&ipic>; }; -- cgit From ea0105ea3881b409e362451690184af494bce6e3 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sun, 11 Jan 2009 19:55:39 +0300 Subject: powerpc/83xx: Move mcu_mpc8349emitx driver out of drivers/i2c/chips/ This patch is used to help Jean Delvare to get rid of drivers/i2c/chips/ directory. The new location suggested by Kumar Gala: as the driver is 83xx specific it's placed into arch/powerpc/platforms/83xx/. Signed-off-by: Anton Vorontsov Acked-by: Jean Delvare Signed-off-by: Kumar Gala --- arch/powerpc/platforms/83xx/Makefile | 1 + arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c | 209 +++++++++++++++++++++++++ arch/powerpc/platforms/Kconfig | 11 ++ drivers/i2c/chips/Kconfig | 11 -- drivers/i2c/chips/Makefile | 1 - drivers/i2c/chips/mcu_mpc8349emitx.c | 209 ------------------------- 6 files changed, 221 insertions(+), 221 deletions(-) create mode 100644 arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c delete mode 100644 drivers/i2c/chips/mcu_mpc8349emitx.c diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/platforms/83xx/Makefile index ba5028e2989..051777c542c 100644 --- a/arch/powerpc/platforms/83xx/Makefile +++ b/arch/powerpc/platforms/83xx/Makefile @@ -3,6 +3,7 @@ # obj-y := misc.o usb.o obj-$(CONFIG_SUSPEND) += suspend.o suspend-asm.o +obj-$(CONFIG_MCU_MPC8349EMITX) += mcu_mpc8349emitx.o obj-$(CONFIG_MPC831x_RDB) += mpc831x_rdb.o obj-$(CONFIG_MPC832x_RDB) += mpc832x_rdb.o obj-$(CONFIG_MPC834x_MDS) += mpc834x_mds.o diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c new file mode 100644 index 00000000000..82a9bcb858b --- /dev/null +++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c @@ -0,0 +1,209 @@ +/* + * Power Management and GPIO expander driver for MPC8349E-mITX-compatible MCU + * + * Copyright (c) 2008 MontaVista Software, Inc. + * + * Author: Anton Vorontsov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * I don't have specifications for the MCU firmware, I found this register + * and bits positions by the trial&error method. + */ +#define MCU_REG_CTRL 0x20 +#define MCU_CTRL_POFF 0x40 + +#define MCU_NUM_GPIO 2 + +struct mcu { + struct mutex lock; + struct device_node *np; + struct i2c_client *client; + struct of_gpio_chip of_gc; + u8 reg_ctrl; +}; + +static struct mcu *glob_mcu; + +static void mcu_power_off(void) +{ + struct mcu *mcu = glob_mcu; + + pr_info("Sending power-off request to the MCU...\n"); + mutex_lock(&mcu->lock); + i2c_smbus_write_byte_data(glob_mcu->client, MCU_REG_CTRL, + mcu->reg_ctrl | MCU_CTRL_POFF); + mutex_unlock(&mcu->lock); +} + +static void mcu_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct of_gpio_chip *of_gc = to_of_gpio_chip(gc); + struct mcu *mcu = container_of(of_gc, struct mcu, of_gc); + u8 bit = 1 << (4 + gpio); + + mutex_lock(&mcu->lock); + if (val) + mcu->reg_ctrl &= ~bit; + else + mcu->reg_ctrl |= bit; + + i2c_smbus_write_byte_data(mcu->client, MCU_REG_CTRL, mcu->reg_ctrl); + mutex_unlock(&mcu->lock); +} + +static int mcu_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) +{ + mcu_gpio_set(gc, gpio, val); + return 0; +} + +static int mcu_gpiochip_add(struct mcu *mcu) +{ + struct device_node *np; + struct of_gpio_chip *of_gc = &mcu->of_gc; + struct gpio_chip *gc = &of_gc->gc; + int ret; + + np = of_find_compatible_node(NULL, NULL, "fsl,mcu-mpc8349emitx"); + if (!np) + return -ENODEV; + + gc->owner = THIS_MODULE; + gc->label = np->full_name; + gc->can_sleep = 1; + gc->ngpio = MCU_NUM_GPIO; + gc->base = -1; + gc->set = mcu_gpio_set; + gc->direction_output = mcu_gpio_dir_out; + of_gc->gpio_cells = 2; + of_gc->xlate = of_gpio_simple_xlate; + + np->data = of_gc; + mcu->np = np; + + /* + * We don't want to lose the node, its ->data and ->full_name... + * So, if succeeded, we don't put the node here. + */ + ret = gpiochip_add(gc); + if (ret) + of_node_put(np); + return ret; +} + +static int mcu_gpiochip_remove(struct mcu *mcu) +{ + int ret; + + ret = gpiochip_remove(&mcu->of_gc.gc); + if (ret) + return ret; + of_node_put(mcu->np); + + return 0; +} + +static int __devinit mcu_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct mcu *mcu; + int ret; + + mcu = kzalloc(sizeof(*mcu), GFP_KERNEL); + if (!mcu) + return -ENOMEM; + + mutex_init(&mcu->lock); + mcu->client = client; + i2c_set_clientdata(client, mcu); + + ret = i2c_smbus_read_byte_data(mcu->client, MCU_REG_CTRL); + if (ret < 0) + goto err; + mcu->reg_ctrl = ret; + + ret = mcu_gpiochip_add(mcu); + if (ret) + goto err; + + /* XXX: this is potentially racy, but there is no lock for ppc_md */ + if (!ppc_md.power_off) { + glob_mcu = mcu; + ppc_md.power_off = mcu_power_off; + dev_info(&client->dev, "will provide power-off service\n"); + } + + return 0; +err: + kfree(mcu); + return ret; +} + +static int __devexit mcu_remove(struct i2c_client *client) +{ + struct mcu *mcu = i2c_get_clientdata(client); + int ret; + + if (glob_mcu == mcu) { + ppc_md.power_off = NULL; + glob_mcu = NULL; + } + + ret = mcu_gpiochip_remove(mcu); + if (ret) + return ret; + i2c_set_clientdata(client, NULL); + kfree(mcu); + return 0; +} + +static const struct i2c_device_id mcu_ids[] = { + { "mcu-mpc8349emitx", }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, mcu_ids); + +static struct i2c_driver mcu_driver = { + .driver = { + .name = "mcu-mpc8349emitx", + .owner = THIS_MODULE, + }, + .probe = mcu_probe, + .remove = __devexit_p(mcu_remove), + .id_table = mcu_ids, +}; + +static int __init mcu_init(void) +{ + return i2c_add_driver(&mcu_driver); +} +module_init(mcu_init); + +static void __exit mcu_exit(void) +{ + i2c_del_driver(&mcu_driver); +} +module_exit(mcu_exit); + +MODULE_DESCRIPTION("Power Management and GPIO expander driver for " + "MPC8349E-mITX-compatible MCU"); +MODULE_AUTHOR("Anton Vorontsov "); +MODULE_LICENSE("GPL"); diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index 47fe2bea986..200b9cb900e 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig @@ -323,4 +323,15 @@ config SIMPLE_GPIO chip-selects, Ethernet/USB PHY's power and various other small on-board peripherals. +config MCU_MPC8349EMITX + tristate "MPC8349E-mITX MCU driver" + depends on I2C && PPC_83xx + select GENERIC_GPIO + select ARCH_REQUIRE_GPIOLIB + help + Say Y here to enable soft power-off functionality on the Freescale + boards with the MPC8349E-mITX-compatible MCU chips. This driver will + also register MCU GPIOs with the generic GPIO API, so you'll able + to use MCU pins as GPIOs. + endmenu diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig index 59c3d23f5bd..b9bef04b7be 100644 --- a/drivers/i2c/chips/Kconfig +++ b/drivers/i2c/chips/Kconfig @@ -139,15 +139,4 @@ config SENSORS_TSL2550 This driver can also be built as a module. If so, the module will be called tsl2550. -config MCU_MPC8349EMITX - tristate "MPC8349E-mITX MCU driver" - depends on I2C && PPC_83xx - select GENERIC_GPIO - select ARCH_REQUIRE_GPIOLIB - help - Say Y here to enable soft power-off functionality on the Freescale - boards with the MPC8349E-mITX-compatible MCU chips. This driver will - also register MCU GPIOs with the generic GPIO API, so you'll able - to use MCU pins as GPIOs. - endmenu diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile index 83accaaf816..00fcb5193ac 100644 --- a/drivers/i2c/chips/Makefile +++ b/drivers/i2c/chips/Makefile @@ -19,7 +19,6 @@ obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o obj-$(CONFIG_PCF8575) += pcf8575.o obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o -obj-$(CONFIG_MCU_MPC8349EMITX) += mcu_mpc8349emitx.o ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) EXTRA_CFLAGS += -DDEBUG diff --git a/drivers/i2c/chips/mcu_mpc8349emitx.c b/drivers/i2c/chips/mcu_mpc8349emitx.c deleted file mode 100644 index 82a9bcb858b..00000000000 --- a/drivers/i2c/chips/mcu_mpc8349emitx.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Power Management and GPIO expander driver for MPC8349E-mITX-compatible MCU - * - * Copyright (c) 2008 MontaVista Software, Inc. - * - * Author: Anton Vorontsov - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * I don't have specifications for the MCU firmware, I found this register - * and bits positions by the trial&error method. - */ -#define MCU_REG_CTRL 0x20 -#define MCU_CTRL_POFF 0x40 - -#define MCU_NUM_GPIO 2 - -struct mcu { - struct mutex lock; - struct device_node *np; - struct i2c_client *client; - struct of_gpio_chip of_gc; - u8 reg_ctrl; -}; - -static struct mcu *glob_mcu; - -static void mcu_power_off(void) -{ - struct mcu *mcu = glob_mcu; - - pr_info("Sending power-off request to the MCU...\n"); - mutex_lock(&mcu->lock); - i2c_smbus_write_byte_data(glob_mcu->client, MCU_REG_CTRL, - mcu->reg_ctrl | MCU_CTRL_POFF); - mutex_unlock(&mcu->lock); -} - -static void mcu_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) -{ - struct of_gpio_chip *of_gc = to_of_gpio_chip(gc); - struct mcu *mcu = container_of(of_gc, struct mcu, of_gc); - u8 bit = 1 << (4 + gpio); - - mutex_lock(&mcu->lock); - if (val) - mcu->reg_ctrl &= ~bit; - else - mcu->reg_ctrl |= bit; - - i2c_smbus_write_byte_data(mcu->client, MCU_REG_CTRL, mcu->reg_ctrl); - mutex_unlock(&mcu->lock); -} - -static int mcu_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) -{ - mcu_gpio_set(gc, gpio, val); - return 0; -} - -static int mcu_gpiochip_add(struct mcu *mcu) -{ - struct device_node *np; - struct of_gpio_chip *of_gc = &mcu->of_gc; - struct gpio_chip *gc = &of_gc->gc; - int ret; - - np = of_find_compatible_node(NULL, NULL, "fsl,mcu-mpc8349emitx"); - if (!np) - return -ENODEV; - - gc->owner = THIS_MODULE; - gc->label = np->full_name; - gc->can_sleep = 1; - gc->ngpio = MCU_NUM_GPIO; - gc->base = -1; - gc->set = mcu_gpio_set; - gc->direction_output = mcu_gpio_dir_out; - of_gc->gpio_cells = 2; - of_gc->xlate = of_gpio_simple_xlate; - - np->data = of_gc; - mcu->np = np; - - /* - * We don't want to lose the node, its ->data and ->full_name... - * So, if succeeded, we don't put the node here. - */ - ret = gpiochip_add(gc); - if (ret) - of_node_put(np); - return ret; -} - -static int mcu_gpiochip_remove(struct mcu *mcu) -{ - int ret; - - ret = gpiochip_remove(&mcu->of_gc.gc); - if (ret) - return ret; - of_node_put(mcu->np); - - return 0; -} - -static int __devinit mcu_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct mcu *mcu; - int ret; - - mcu = kzalloc(sizeof(*mcu), GFP_KERNEL); - if (!mcu) - return -ENOMEM; - - mutex_init(&mcu->lock); - mcu->client = client; - i2c_set_clientdata(client, mcu); - - ret = i2c_smbus_read_byte_data(mcu->client, MCU_REG_CTRL); - if (ret < 0) - goto err; - mcu->reg_ctrl = ret; - - ret = mcu_gpiochip_add(mcu); - if (ret) - goto err; - - /* XXX: this is potentially racy, but there is no lock for ppc_md */ - if (!ppc_md.power_off) { - glob_mcu = mcu; - ppc_md.power_off = mcu_power_off; - dev_info(&client->dev, "will provide power-off service\n"); - } - - return 0; -err: - kfree(mcu); - return ret; -} - -static int __devexit mcu_remove(struct i2c_client *client) -{ - struct mcu *mcu = i2c_get_clientdata(client); - int ret; - - if (glob_mcu == mcu) { - ppc_md.power_off = NULL; - glob_mcu = NULL; - } - - ret = mcu_gpiochip_remove(mcu); - if (ret) - return ret; - i2c_set_clientdata(client, NULL); - kfree(mcu); - return 0; -} - -static const struct i2c_device_id mcu_ids[] = { - { "mcu-mpc8349emitx", }, - {}, -}; -MODULE_DEVICE_TABLE(i2c, mcu_ids); - -static struct i2c_driver mcu_driver = { - .driver = { - .name = "mcu-mpc8349emitx", - .owner = THIS_MODULE, - }, - .probe = mcu_probe, - .remove = __devexit_p(mcu_remove), - .id_table = mcu_ids, -}; - -static int __init mcu_init(void) -{ - return i2c_add_driver(&mcu_driver); -} -module_init(mcu_init); - -static void __exit mcu_exit(void) -{ - i2c_del_driver(&mcu_driver); -} -module_exit(mcu_exit); - -MODULE_DESCRIPTION("Power Management and GPIO expander driver for " - "MPC8349E-mITX-compatible MCU"); -MODULE_AUTHOR("Anton Vorontsov "); -MODULE_LICENSE("GPL"); -- cgit From 33966dd0e2f68f26943cd9ee93ec6abbc6547a8e Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 13 Jan 2009 16:04:36 -0800 Subject: tcp: splice as many packets as possible at once As spotted by Willy Tarreau, current splice() from tcp socket to pipe is not optimal. It processes at most one segment per call. This results in low performance and very high overhead due to syscall rate when splicing from interfaces which do not support LRO. Willy provided a patch inside tcp_splice_read(), but a better fix is to let tcp_read_sock() process as many segments as possible, so that tcp_rcv_space_adjust() and tcp_cleanup_rbuf() are called less often. With this change, splice() behaves like tcp_recvmsg(), being able to consume many skbs in one system call. With typical 1460 bytes of payload per frame, that means splice(SPLICE_F_NONBLOCK) can return 16*1460 = 23360 bytes. Signed-off-by: Willy Tarreau Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/tcp.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index ce572f9dff0..48ada1b2d2c 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -522,8 +522,12 @@ static int tcp_splice_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, unsigned int offset, size_t len) { struct tcp_splice_state *tss = rd_desc->arg.data; + int ret; - return skb_splice_bits(skb, offset, tss->pipe, tss->len, tss->flags); + ret = skb_splice_bits(skb, offset, tss->pipe, rd_desc->count, tss->flags); + if (ret > 0) + rd_desc->count -= ret; + return ret; } static int __tcp_splice_read(struct sock *sk, struct tcp_splice_state *tss) @@ -531,6 +535,7 @@ static int __tcp_splice_read(struct sock *sk, struct tcp_splice_state *tss) /* Store TCP splice context information in read_descriptor_t. */ read_descriptor_t rd_desc = { .arg.data = tss, + .count = tss->len, }; return tcp_read_sock(sk, &rd_desc, tcp_splice_data_recv); @@ -611,11 +616,13 @@ ssize_t tcp_splice_read(struct socket *sock, loff_t *ppos, tss.len -= ret; spliced += ret; + if (!timeo) + break; release_sock(sk); lock_sock(sk); if (sk->sk_err || sk->sk_state == TCP_CLOSE || - (sk->sk_shutdown & RCV_SHUTDOWN) || !timeo || + (sk->sk_shutdown & RCV_SHUTDOWN) || signal_pending(current)) break; } -- cgit From 7a6046ebe28d6a5d259097dcb44162e5a6eca88e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 13 Jan 2009 17:38:24 -0800 Subject: sparc64: Fix UP build failure. sparc_ksyms_64.c includes asm/spinlock.h directly, which is a no-no. Even better, none of these exports are even necessary. All of these functions are inlines. Reported by Meelis Roos and Alexander Beregalov. Signed-off-by: David S. Miller --- arch/sparc/kernel/sparc_ksyms_64.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/arch/sparc/kernel/sparc_ksyms_64.c b/arch/sparc/kernel/sparc_ksyms_64.c index da8f804feb4..0f26066a08d 100644 --- a/arch/sparc/kernel/sparc_ksyms_64.c +++ b/arch/sparc/kernel/sparc_ksyms_64.c @@ -9,7 +9,6 @@ #include #include -#include #include #include #include @@ -23,16 +22,6 @@ struct poll { short revents; }; -/* used by various drivers */ -#ifdef CONFIG_SMP -/* Out of line rw-locking implementation. */ -EXPORT_SYMBOL(__read_lock); -EXPORT_SYMBOL(__read_unlock); -EXPORT_SYMBOL(__write_lock); -EXPORT_SYMBOL(__write_unlock); -EXPORT_SYMBOL(__write_trylock); -#endif /* CONFIG_SMP */ - /* from helpers.S */ EXPORT_SYMBOL(__flushw_user); EXPORT_SYMBOL_GPL(real_hard_smp_processor_id); -- cgit From d63dab00e85641515a0a060e6de93e6b7f450665 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 13 Jan 2009 18:20:20 -0800 Subject: Input: omap-keypad - mark probe function as __devinit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A pointer to omap_kp_probe is passed to the core via platform_driver_register and so the function must not disappear when the .init sections are discarded. Otherwise (if also having HOTPLUG=y) unbinding and binding a device to the driver via sysfs will result in an oops as does a device being registered late. An alternative to this patch is using platform_driver_probe instead of platform_driver_register plus removing the pointer to the probe function from the struct platform_driver. [dtor@mail.ru: fixed some more section markups] Signed-off-by: Uwe Kleine-König Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/omap-keypad.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index ec0ebee4606..23b4fd18f85 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c @@ -279,7 +279,7 @@ static int omap_kp_resume(struct platform_device *dev) #define omap_kp_resume NULL #endif -static int __init omap_kp_probe(struct platform_device *pdev) +static int __devinit omap_kp_probe(struct platform_device *pdev) { struct omap_kp *omap_kp; struct input_dev *input_dev; @@ -422,7 +422,7 @@ err1: return -EINVAL; } -static int omap_kp_remove(struct platform_device *pdev) +static int __devexit omap_kp_remove(struct platform_device *pdev) { struct omap_kp *omap_kp = platform_get_drvdata(pdev); @@ -454,7 +454,7 @@ static int omap_kp_remove(struct platform_device *pdev) static struct platform_driver omap_kp_driver = { .probe = omap_kp_probe, - .remove = omap_kp_remove, + .remove = __devexit_p(omap_kp_remove), .suspend = omap_kp_suspend, .resume = omap_kp_resume, .driver = { @@ -463,7 +463,7 @@ static struct platform_driver omap_kp_driver = { }, }; -static int __devinit omap_kp_init(void) +static int __init omap_kp_init(void) { printk(KERN_INFO "OMAP Keypad Driver\n"); return platform_driver_register(&omap_kp_driver); -- cgit From 27f23336bcc1b08512751c878b3e05ed6b815e86 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 13 Jan 2009 18:20:31 -0800 Subject: Input: spitzkbd - mark probe function as __devinit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A pointer to spitzkbd_probe is passed to the core via platform_driver_register and so the function must not disappear when the .init sections are discarded. Otherwise (if also having HOTPLUG=y) unbinding and binding a device to the driver via sysfs will result in an oops as does a device being registered late. An alternative to this patch is using platform_driver_probe instead of platform_driver_register plus removing the pointer to the probe function from the struct platform_driver. [dtor@mail.ru: fixed some more section markups] Signed-off-by: Uwe Kleine-König Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/spitzkbd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c index c48b76a46a5..9d1781a618e 100644 --- a/drivers/input/keyboard/spitzkbd.c +++ b/drivers/input/keyboard/spitzkbd.c @@ -343,7 +343,7 @@ static int spitzkbd_resume(struct platform_device *dev) #define spitzkbd_resume NULL #endif -static int __init spitzkbd_probe(struct platform_device *dev) +static int __devinit spitzkbd_probe(struct platform_device *dev) { struct spitzkbd *spitzkbd; struct input_dev *input_dev; @@ -444,7 +444,7 @@ static int __init spitzkbd_probe(struct platform_device *dev) return err; } -static int spitzkbd_remove(struct platform_device *dev) +static int __devexit spitzkbd_remove(struct platform_device *dev) { int i; struct spitzkbd *spitzkbd = platform_get_drvdata(dev); @@ -470,7 +470,7 @@ static int spitzkbd_remove(struct platform_device *dev) static struct platform_driver spitzkbd_driver = { .probe = spitzkbd_probe, - .remove = spitzkbd_remove, + .remove = __devexit_p(spitzkbd_remove), .suspend = spitzkbd_suspend, .resume = spitzkbd_resume, .driver = { @@ -479,7 +479,7 @@ static struct platform_driver spitzkbd_driver = { }, }; -static int __devinit spitzkbd_init(void) +static int __init spitzkbd_init(void) { return platform_driver_register(&spitzkbd_driver); } -- cgit From 7891cc818967e186be68caac32d84bfd0a3f0bd2 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 13 Jan 2009 22:17:51 -0800 Subject: ipv6: Fix fib6_dump_table walker leak When a fib6 table dump is prematurely ended, we won't unlink its walker from the list. This causes all sorts of grief for other users of the list later. Reported-by: Chris Caputo Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/ipv6/ip6_fib.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 29c7c99e69f..52ee1dced2f 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -298,6 +298,10 @@ static void fib6_dump_end(struct netlink_callback *cb) struct fib6_walker_t *w = (void*)cb->args[2]; if (w) { + if (cb->args[4]) { + cb->args[4] = 0; + fib6_walker_unlink(w); + } cb->args[2] = 0; kfree(w); } @@ -330,15 +334,12 @@ static int fib6_dump_table(struct fib6_table *table, struct sk_buff *skb, read_lock_bh(&table->tb6_lock); res = fib6_walk_continue(w); read_unlock_bh(&table->tb6_lock); - if (res != 0) { - if (res < 0) - fib6_walker_unlink(w); - goto end; + if (res <= 0) { + fib6_walker_unlink(w); + cb->args[4] = 0; } - fib6_walker_unlink(w); - cb->args[4] = 0; } -end: + return res; } -- cgit From 2acc9dcb609427a20463e529ef552dd93b469847 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 9 Jan 2009 16:57:14 +0100 Subject: ALSA: hda - Fix silent headphone output on Panasonic CF-74 CF-74 does the headphone/speaker switching on hardware, thus the driver shouldn't do any software-toggling of pins. Otherwise it results in a silent headphone output. This patch simply resets the hp_detect flag to fix the problem. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 0e6fc56fa37..89ff916a0ed 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -4467,6 +4467,12 @@ static int patch_stac9200(struct hda_codec *codec) return err; } + /* CF-74 has no headphone detection, and the driver should *NOT* + * do detection and HP/speaker toggle because the hardware does it. + */ + if (spec->board_config == STAC_9200_PANASONIC) + spec->hp_detect = 0; + codec->patch_ops = stac92xx_patch_ops; return 0; -- cgit From c15c5060fc32d7de7cde76aa61e98bae1334d82e Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Tue, 13 Jan 2009 13:30:07 -0500 Subject: ALSA: hda: stac92hd8xxx amp mixers Added amp nid for stac92hd8xxx families of codecs so the input amp mixer is created. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 89ff916a0ed..77fcc312a1f 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -336,6 +336,10 @@ static unsigned int stac92hd83xxx_pwr_mapping[4] = { 0x03, 0x0c, 0x10, 0x40, }; +static unsigned int stac92hd83xxx_amp_nids[1] = { + 0xc, +}; + static hda_nid_t stac92hd71bxx_pwr_nids[3] = { 0x0a, 0x0d, 0x0f }; @@ -4747,6 +4751,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) spec->dmux_nids = stac92hd83xxx_dmux_nids; spec->adc_nids = stac92hd83xxx_adc_nids; spec->pwr_nids = stac92hd83xxx_pwr_nids; + spec->amp_nids = stac92hd83xxx_amp_nids; spec->pwr_mapping = stac92hd83xxx_pwr_mapping; spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); spec->multiout.dac_nids = spec->dac_nids; @@ -4764,6 +4769,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids); spec->num_dmuxes = ARRAY_SIZE(stac92hd83xxx_dmux_nids); spec->num_adcs = ARRAY_SIZE(stac92hd83xxx_adc_nids); + spec->num_amps = ARRAY_SIZE(stac92hd83xxx_amp_nids); spec->num_dmics = STAC92HD83XXX_NUM_DMICS; spec->dinput_mux = &stac92hd83xxx_dmux; spec->pin_nids = stac92hd83xxx_pin_nids; -- cgit From 8317e0b0c2234f5f1f5d54804e4093d11bc0dffa Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 14 Jan 2009 07:56:51 +0100 Subject: ALSA: hda - Don't reset HP pinctl in patch_sigmatel.c Resetting HP pinctl at the unplugged state may cause a sort of regression on some devices because of their wrong pin configuration. A simple workaround is to disable the pin reset. This is ugly and may be not good from the power-saving POV (if any), but damn simple. Signed-off-by: Takashi Iwai Cc: stable@kernel.org --- sound/pci/hda/patch_sigmatel.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 77fcc312a1f..103ac6d743e 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -4225,8 +4225,19 @@ static void stac92xx_hp_detect(struct hda_codec *codec) continue; if (presence) stac92xx_set_pinctl(codec, cfg->hp_pins[i], val); +#if 0 /* FIXME */ +/* Resetting the pinctl like below may lead to (a sort of) regressions + * on some devices since they use the HP pin actually for line/speaker + * outs although the default pin config shows a different pin (that is + * wrong and useless). + * + * So, it's basically a problem of default pin configs, likely a BIOS issue. + * But, disabling the code below just works around it, and I'm too tired of + * bug reports with such devices... + */ else stac92xx_reset_pinctl(codec, cfg->hp_pins[i], val); +#endif /* FIXME */ } } -- cgit From 3e420e78ece6f9d2accc1568e80dfd0501e13df1 Mon Sep 17 00:00:00 2001 From: Luke Yelavich Date: Tue, 16 Dec 2008 12:37:47 +1100 Subject: ALSA: hda - Add automatic model setting for Samsung Q45 Have the Samsung Q45 (144d:c510) select ALC262_HIPPO by default Reference: Ubuntu bug 200210 http://launchpad.net/bugs/200210 Signed-off-by: Luke Yelavich Cc: stable@kernel.org Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index ea4c88fe05c..82dd0843197 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10573,6 +10573,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA), SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA), + SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO), SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000), SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), -- cgit From 9248f2693921b143b54f380b60c945b28a7a5358 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 14 Jan 2009 09:40:25 +0100 Subject: ALSA: hda - Fix stac92hd83xxx_amp_nids[] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the bug introduced in commit c15c5060fc32d7de7cde76aa61e98bae1334d82e: sound/pci/hda/patch_sigmatel.c: In function ‘patch_stac92hd83xxx’: sound/pci/hda/patch_sigmatel.c:4765: warning: assignment from incompatible pointer type Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 103ac6d743e..25230f4c888 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -336,7 +336,7 @@ static unsigned int stac92hd83xxx_pwr_mapping[4] = { 0x03, 0x0c, 0x10, 0x40, }; -static unsigned int stac92hd83xxx_amp_nids[1] = { +static hda_nid_t stac92hd83xxx_amp_nids[1] = { 0xc, }; -- cgit From 5c6c9e6feccf771d060708fbbba9e0f67f8e0e67 Mon Sep 17 00:00:00 2001 From: "Signed-off-by: Peter Stokes" Date: Wed, 14 Jan 2009 09:47:57 +0100 Subject: ALSA: USB quirk for Logitech Quickcam Pro 9000 name The Logitech QuickCam Pro 9000 does not appear to any product identification strings in its USB device descriptor. Therefore it receives a device name of "USB Device 0x46d:0x990". Th e attached patch below adds a USB quirk to provide a more friendly name. Signed-off-by: Takashi Iwai --- sound/usb/usbquirks.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h index 92115755d98..5d8ef09b9dc 100644 --- a/sound/usb/usbquirks.h +++ b/sound/usb/usbquirks.h @@ -128,6 +128,14 @@ .bInterfaceClass = USB_CLASS_AUDIO, .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL }, +{ + USB_DEVICE(0x046d, 0x0990), + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + .vendor_name = "Logitech, Inc.", + .product_name = "QuickCam Pro 9000", + .ifnum = QUIRK_NO_INTERFACE + } +}, /* * Yamaha devices -- cgit From e4fa4c97016037620f9dc8bafe03e1086b665b4c Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Wed, 14 Jan 2009 14:58:15 +0800 Subject: rcu: add __cpuinit to rcu_init_percpu_data() Impact: reduce memory footprint add __cpuinit to rcu_init_percpu_data(), and this function's text will be discarded after boot when !CONFIG_HOTPLUG_CPU. Signed-off-by: Lai Jiangshan Signed-off-by: Ingo Molnar --- kernel/rcuclassic.c | 2 +- kernel/rcutree.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/rcuclassic.c b/kernel/rcuclassic.c index 490934fc7ac..bd5a9003497 100644 --- a/kernel/rcuclassic.c +++ b/kernel/rcuclassic.c @@ -716,7 +716,7 @@ void rcu_check_callbacks(int cpu, int user) raise_rcu_softirq(); } -static void rcu_init_percpu_data(int cpu, struct rcu_ctrlblk *rcp, +static void __cpuinit rcu_init_percpu_data(int cpu, struct rcu_ctrlblk *rcp, struct rcu_data *rdp) { unsigned long flags; diff --git a/kernel/rcutree.c b/kernel/rcutree.c index f2d8638e6c6..b2fd602a6f6 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -1314,7 +1314,7 @@ int rcu_needs_cpu(int cpu) * access due to the fact that this CPU cannot possibly have any RCU * callbacks in flight yet. */ -static void +static void __cpuinit rcu_init_percpu_data(int cpu, struct rcu_state *rsp) { unsigned long flags; -- cgit From baf48f6577e581a9adb8fe849dc80e24b21d171d Mon Sep 17 00:00:00 2001 From: Mandeep Singh Baines Date: Mon, 12 Jan 2009 21:15:17 -0800 Subject: softlock: fix false panic which can occur if softlockup_thresh is reduced At run-time, if softlockup_thresh is changed to a much lower value, touch_timestamp is likely to be much older than the new softlock_thresh. This will cause a false softlockup to be detected. If softlockup_panic is enabled, the system will panic. The fix is to touch all watchdogs before changing softlockup_thresh. Signed-off-by: Mandeep Singh Baines Signed-off-by: Ingo Molnar --- include/linux/sched.h | 3 +++ kernel/softlockup.c | 9 +++++++++ kernel/sysctl.c | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 4cae9b81a1f..54cbabf3b87 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -293,6 +293,9 @@ extern void sched_show_task(struct task_struct *p); extern void softlockup_tick(void); extern void touch_softlockup_watchdog(void); extern void touch_all_softlockup_watchdogs(void); +extern int proc_dosoftlockup_thresh(struct ctl_table *table, int write, + struct file *filp, void __user *buffer, + size_t *lenp, loff_t *ppos); extern unsigned int softlockup_panic; extern unsigned long sysctl_hung_task_check_count; extern unsigned long sysctl_hung_task_timeout_secs; diff --git a/kernel/softlockup.c b/kernel/softlockup.c index d9188c66278..85d5a245510 100644 --- a/kernel/softlockup.c +++ b/kernel/softlockup.c @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -88,6 +89,14 @@ void touch_all_softlockup_watchdogs(void) } EXPORT_SYMBOL(touch_all_softlockup_watchdogs); +int proc_dosoftlockup_thresh(struct ctl_table *table, int write, + struct file *filp, void __user *buffer, + size_t *lenp, loff_t *ppos) +{ + touch_all_softlockup_watchdogs(); + return proc_dointvec_minmax(table, write, filp, buffer, lenp, ppos); +} + /* * This callback runs from the timer interrupt, and checks * whether the watchdog thread has hung or not: diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 89d74436318..596dc31a711 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -800,7 +800,7 @@ static struct ctl_table kern_table[] = { .data = &softlockup_thresh, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = &proc_dointvec_minmax, + .proc_handler = &proc_dosoftlockup_thresh, .strategy = &sysctl_intvec, .extra1 = &neg_one, .extra2 = &sixty, -- cgit From b5ba7e6d1e7e2ac808afd21be1e56dc34caf20e6 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Mon, 12 Jan 2009 17:46:17 +0530 Subject: x86: replacing mp_config_ioapic with mpc_ioapic Impact: cleanup, solve 80 columns wrap problems Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/include/asm/io_apic.h | 10 +------ arch/x86/kernel/acpi/boot.c | 28 ++++++++++---------- arch/x86/kernel/io_apic.c | 60 ++++++++++++++++++++---------------------- arch/x86/kernel/mpparse.c | 12 ++++----- 4 files changed, 50 insertions(+), 60 deletions(-) diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h index 7a1f44ac1f1..5a56ae9b505 100644 --- a/arch/x86/include/asm/io_apic.h +++ b/arch/x86/include/asm/io_apic.h @@ -120,14 +120,6 @@ extern int nr_ioapic_registers[MAX_IO_APICS]; #define MP_MAX_IOAPIC_PIN 127 -struct mp_config_ioapic { - unsigned long mp_apicaddr; - unsigned int mp_apicid; - unsigned char mp_type; - unsigned char mp_apicver; - unsigned char mp_flags; -}; - struct mp_config_intsrc { unsigned int mp_dstapic; unsigned char mp_type; @@ -139,7 +131,7 @@ struct mp_config_intsrc { }; /* I/O APIC entries */ -extern struct mp_config_ioapic mp_ioapics[MAX_IO_APICS]; +extern struct mpc_ioapic mp_ioapics[MAX_IO_APICS]; /* # of MP IRQ source entries */ extern int mp_irq_entries; diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index d37593c2f43..2b27019e64f 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -912,8 +912,8 @@ static u8 __init uniq_ioapic_id(u8 id) DECLARE_BITMAP(used, 256); bitmap_zero(used, 256); for (i = 0; i < nr_ioapics; i++) { - struct mp_config_ioapic *ia = &mp_ioapics[i]; - __set_bit(ia->mp_apicid, used); + struct mpc_ioapic *ia = &mp_ioapics[i]; + __set_bit(ia->apicid, used); } if (!test_bit(id, used)) return id; @@ -945,29 +945,29 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base) idx = nr_ioapics; - mp_ioapics[idx].mp_type = MP_IOAPIC; - mp_ioapics[idx].mp_flags = MPC_APIC_USABLE; - mp_ioapics[idx].mp_apicaddr = address; + mp_ioapics[idx].type = MP_IOAPIC; + mp_ioapics[idx].flags = MPC_APIC_USABLE; + mp_ioapics[idx].apicaddr = address; set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); - mp_ioapics[idx].mp_apicid = uniq_ioapic_id(id); + mp_ioapics[idx].apicid = uniq_ioapic_id(id); #ifdef CONFIG_X86_32 - mp_ioapics[idx].mp_apicver = io_apic_get_version(idx); + mp_ioapics[idx].apicver = io_apic_get_version(idx); #else - mp_ioapics[idx].mp_apicver = 0; + mp_ioapics[idx].apicver = 0; #endif /* * Build basic GSI lookup table to facilitate gsi->io_apic lookups * and to prevent reprogramming of IOAPIC pins (PCI GSIs). */ - mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].mp_apicid; + mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].apicid; mp_ioapic_routing[idx].gsi_base = gsi_base; mp_ioapic_routing[idx].gsi_end = gsi_base + io_apic_get_redir_entries(idx); - printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%lx, " - "GSI %d-%d\n", idx, mp_ioapics[idx].mp_apicid, - mp_ioapics[idx].mp_apicver, mp_ioapics[idx].mp_apicaddr, + printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, " + "GSI %d-%d\n", idx, mp_ioapics[idx].apicid, + mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr, mp_ioapic_routing[idx].gsi_base, mp_ioapic_routing[idx].gsi_end); nr_ioapics++; @@ -1026,7 +1026,7 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) mp_irq.mp_irqflag = (trigger << 2) | polarity; mp_irq.mp_srcbus = MP_ISA_BUS; mp_irq.mp_srcbusirq = bus_irq; /* IRQ */ - mp_irq.mp_dstapic = mp_ioapics[ioapic].mp_apicid; /* APIC ID */ + mp_irq.mp_dstapic = mp_ioapics[ioapic].apicid; /* APIC ID */ mp_irq.mp_dstirq = pin; /* INTIN# */ save_mp_irq(&mp_irq); @@ -1062,7 +1062,7 @@ void __init mp_config_acpi_legacy_irqs(void) ioapic = mp_find_ioapic(0); if (ioapic < 0) return; - dstapic = mp_ioapics[ioapic].mp_apicid; + dstapic = mp_ioapics[ioapic].apicid; /* * Use the default configuration for the IRQs 0-15. Unless diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c index 109c91db202..6c51ecdfbf4 100644 --- a/arch/x86/kernel/io_apic.c +++ b/arch/x86/kernel/io_apic.c @@ -83,7 +83,7 @@ static DEFINE_SPINLOCK(vector_lock); int nr_ioapic_registers[MAX_IO_APICS]; /* I/O APIC entries */ -struct mp_config_ioapic mp_ioapics[MAX_IO_APICS]; +struct mpc_ioapic mp_ioapics[MAX_IO_APICS]; int nr_ioapics; /* MP IRQ source entries */ @@ -387,7 +387,7 @@ struct io_apic { static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx) { return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx) - + (mp_ioapics[idx].mp_apicaddr & ~PAGE_MASK); + + (mp_ioapics[idx].apicaddr & ~PAGE_MASK); } static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg) @@ -946,7 +946,7 @@ static int find_irq_entry(int apic, int pin, int type) for (i = 0; i < mp_irq_entries; i++) if (mp_irqs[i].mp_irqtype == type && - (mp_irqs[i].mp_dstapic == mp_ioapics[apic].mp_apicid || + (mp_irqs[i].mp_dstapic == mp_ioapics[apic].apicid || mp_irqs[i].mp_dstapic == MP_APIC_ALL) && mp_irqs[i].mp_dstirq == pin) return i; @@ -988,7 +988,7 @@ static int __init find_isa_irq_apic(int irq, int type) if (i < mp_irq_entries) { int apic; for(apic = 0; apic < nr_ioapics; apic++) { - if (mp_ioapics[apic].mp_apicid == mp_irqs[i].mp_dstapic) + if (mp_ioapics[apic].apicid == mp_irqs[i].mp_dstapic) return apic; } } @@ -1016,7 +1016,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin) int lbus = mp_irqs[i].mp_srcbus; for (apic = 0; apic < nr_ioapics; apic++) - if (mp_ioapics[apic].mp_apicid == mp_irqs[i].mp_dstapic || + if (mp_ioapics[apic].apicid == mp_irqs[i].mp_dstapic || mp_irqs[i].mp_dstapic == MP_APIC_ALL) break; @@ -1567,14 +1567,14 @@ static void setup_IO_APIC_irq(int apic, int pin, unsigned int irq, struct irq_de apic_printk(APIC_VERBOSE,KERN_DEBUG "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> " "IRQ %d Mode:%i Active:%i)\n", - apic, mp_ioapics[apic].mp_apicid, pin, cfg->vector, + apic, mp_ioapics[apic].apicid, pin, cfg->vector, irq, trigger, polarity); - if (setup_ioapic_entry(mp_ioapics[apic].mp_apicid, irq, &entry, + if (setup_ioapic_entry(mp_ioapics[apic].apicid, irq, &entry, dest, trigger, polarity, cfg->vector)) { printk("Failed to setup ioapic entry for ioapic %d, pin %d\n", - mp_ioapics[apic].mp_apicid, pin); + mp_ioapics[apic].apicid, pin); __clear_irq_vector(irq, cfg); return; } @@ -1605,12 +1605,10 @@ static void __init setup_IO_APIC_irqs(void) notcon = 1; apic_printk(APIC_VERBOSE, KERN_DEBUG " %d-%d", - mp_ioapics[apic].mp_apicid, - pin); + mp_ioapics[apic].apicid, pin); } else apic_printk(APIC_VERBOSE, " %d-%d", - mp_ioapics[apic].mp_apicid, - pin); + mp_ioapics[apic].apicid, pin); continue; } if (notcon) { @@ -1700,7 +1698,7 @@ __apicdebuginit(void) print_IO_APIC(void) printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries); for (i = 0; i < nr_ioapics; i++) printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n", - mp_ioapics[i].mp_apicid, nr_ioapic_registers[i]); + mp_ioapics[i].apicid, nr_ioapic_registers[i]); /* * We are a bit conservative about what we expect. We have to @@ -1720,7 +1718,7 @@ __apicdebuginit(void) print_IO_APIC(void) spin_unlock_irqrestore(&ioapic_lock, flags); printk("\n"); - printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mp_apicid); + printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].apicid); printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw); printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID); printk(KERN_DEBUG "....... : Delivery Type: %X\n", reg_00.bits.delivery_type); @@ -2122,14 +2120,14 @@ static void __init setup_ioapic_ids_from_mpc(void) reg_00.raw = io_apic_read(apic, 0); spin_unlock_irqrestore(&ioapic_lock, flags); - old_id = mp_ioapics[apic].mp_apicid; + old_id = mp_ioapics[apic].apicid; - if (mp_ioapics[apic].mp_apicid >= get_physical_broadcast()) { + if (mp_ioapics[apic].apicid >= get_physical_broadcast()) { printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n", - apic, mp_ioapics[apic].mp_apicid); + apic, mp_ioapics[apic].apicid); printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", reg_00.bits.ID); - mp_ioapics[apic].mp_apicid = reg_00.bits.ID; + mp_ioapics[apic].apicid = reg_00.bits.ID; } /* @@ -2138,9 +2136,9 @@ static void __init setup_ioapic_ids_from_mpc(void) * 'stuck on smp_invalidate_needed IPI wait' messages. */ if (check_apicid_used(phys_id_present_map, - mp_ioapics[apic].mp_apicid)) { + mp_ioapics[apic].apicid)) { printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n", - apic, mp_ioapics[apic].mp_apicid); + apic, mp_ioapics[apic].apicid); for (i = 0; i < get_physical_broadcast(); i++) if (!physid_isset(i, phys_id_present_map)) break; @@ -2149,13 +2147,13 @@ static void __init setup_ioapic_ids_from_mpc(void) printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", i); physid_set(i, phys_id_present_map); - mp_ioapics[apic].mp_apicid = i; + mp_ioapics[apic].apicid = i; } else { physid_mask_t tmp; - tmp = apicid_to_cpu_present(mp_ioapics[apic].mp_apicid); + tmp = apicid_to_cpu_present(mp_ioapics[apic].apicid); apic_printk(APIC_VERBOSE, "Setting %d in the " "phys_id_present_map\n", - mp_ioapics[apic].mp_apicid); + mp_ioapics[apic].apicid); physids_or(phys_id_present_map, phys_id_present_map, tmp); } @@ -2164,11 +2162,11 @@ static void __init setup_ioapic_ids_from_mpc(void) * We need to adjust the IRQ routing table * if the ID changed. */ - if (old_id != mp_ioapics[apic].mp_apicid) + if (old_id != mp_ioapics[apic].apicid) for (i = 0; i < mp_irq_entries; i++) if (mp_irqs[i].mp_dstapic == old_id) mp_irqs[i].mp_dstapic - = mp_ioapics[apic].mp_apicid; + = mp_ioapics[apic].apicid; /* * Read the right value from the MPC table and @@ -2176,9 +2174,9 @@ static void __init setup_ioapic_ids_from_mpc(void) */ apic_printk(APIC_VERBOSE, KERN_INFO "...changing IO-APIC physical APIC ID to %d ...", - mp_ioapics[apic].mp_apicid); + mp_ioapics[apic].apicid); - reg_00.bits.ID = mp_ioapics[apic].mp_apicid; + reg_00.bits.ID = mp_ioapics[apic].apicid; spin_lock_irqsave(&ioapic_lock, flags); io_apic_write(apic, 0, reg_00.raw); spin_unlock_irqrestore(&ioapic_lock, flags); @@ -2189,7 +2187,7 @@ static void __init setup_ioapic_ids_from_mpc(void) spin_lock_irqsave(&ioapic_lock, flags); reg_00.raw = io_apic_read(apic, 0); spin_unlock_irqrestore(&ioapic_lock, flags); - if (reg_00.bits.ID != mp_ioapics[apic].mp_apicid) + if (reg_00.bits.ID != mp_ioapics[apic].apicid) printk("could not set ID!\n"); else apic_printk(APIC_VERBOSE, " ok.\n"); @@ -3118,8 +3116,8 @@ static int ioapic_resume(struct sys_device *dev) spin_lock_irqsave(&ioapic_lock, flags); reg_00.raw = io_apic_read(dev->id, 0); - if (reg_00.bits.ID != mp_ioapics[dev->id].mp_apicid) { - reg_00.bits.ID = mp_ioapics[dev->id].mp_apicid; + if (reg_00.bits.ID != mp_ioapics[dev->id].apicid) { + reg_00.bits.ID = mp_ioapics[dev->id].apicid; io_apic_write(dev->id, 0, reg_00.raw); } spin_unlock_irqrestore(&ioapic_lock, flags); @@ -4101,7 +4099,7 @@ void __init ioapic_init_mappings(void) ioapic_res = ioapic_setup_resources(); for (i = 0; i < nr_ioapics; i++) { if (smp_found_config) { - ioapic_phys = mp_ioapics[i].mp_apicaddr; + ioapic_phys = mp_ioapics[i].apicaddr; #ifdef CONFIG_X86_32 if (!ioapic_phys) { printk(KERN_ERR diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 8385d4e7e15..a86a6553743 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c @@ -143,11 +143,11 @@ static void __init MP_ioapic_info(struct mpc_ioapic *m) if (bad_ioapic(m->apicaddr)) return; - mp_ioapics[nr_ioapics].mp_apicaddr = m->apicaddr; - mp_ioapics[nr_ioapics].mp_apicid = m->apicid; - mp_ioapics[nr_ioapics].mp_type = m->type; - mp_ioapics[nr_ioapics].mp_apicver = m->apicver; - mp_ioapics[nr_ioapics].mp_flags = m->flags; + mp_ioapics[nr_ioapics].apicaddr = m->apicaddr; + mp_ioapics[nr_ioapics].apicid = m->apicid; + mp_ioapics[nr_ioapics].type = m->type; + mp_ioapics[nr_ioapics].apicver = m->apicver; + mp_ioapics[nr_ioapics].flags = m->flags; nr_ioapics++; } @@ -416,7 +416,7 @@ static void __init construct_default_ioirq_mptable(int mpc_default_type) intsrc.type = MP_INTSRC; intsrc.irqflag = 0; /* conforming */ intsrc.srcbus = 0; - intsrc.dstapic = mp_ioapics[0].mp_apicid; + intsrc.dstapic = mp_ioapics[0].apicid; intsrc.irqtype = mp_INT; -- cgit From c2c21745ecba23c74690a124bcd371f83bd71e45 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Mon, 12 Jan 2009 17:47:22 +0530 Subject: x86: replacing mp_config_intsrc with mpc_intsrc Impact: cleanup, solve 80 columns wrap problems Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/include/asm/io_apic.h | 16 +--------- arch/x86/kernel/acpi/boot.c | 70 ++++++++++++++++++++---------------------- arch/x86/kernel/io_apic.c | 64 +++++++++++++++++++------------------- arch/x86/kernel/mpparse.c | 68 ++++++++++++++++++++-------------------- 4 files changed, 101 insertions(+), 117 deletions(-) diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h index 5a56ae9b505..08ec793aa04 100644 --- a/arch/x86/include/asm/io_apic.h +++ b/arch/x86/include/asm/io_apic.h @@ -114,22 +114,8 @@ struct IR_IO_APIC_route_entry { extern int nr_ioapics; extern int nr_ioapic_registers[MAX_IO_APICS]; -/* - * MP-BIOS irq configuration table structures: - */ - #define MP_MAX_IOAPIC_PIN 127 -struct mp_config_intsrc { - unsigned int mp_dstapic; - unsigned char mp_type; - unsigned char mp_irqtype; - unsigned short mp_irqflag; - unsigned char mp_srcbus; - unsigned char mp_srcbusirq; - unsigned char mp_dstirq; -}; - /* I/O APIC entries */ extern struct mpc_ioapic mp_ioapics[MAX_IO_APICS]; @@ -137,7 +123,7 @@ extern struct mpc_ioapic mp_ioapics[MAX_IO_APICS]; extern int mp_irq_entries; /* MP IRQ source entries */ -extern struct mp_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; +extern struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES]; /* non-0 if default (table-less) MP configuration */ extern int mpc_default_type; diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 2b27019e64f..4cb5964f149 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -973,19 +973,19 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base) nr_ioapics++; } -static void assign_to_mp_irq(struct mp_config_intsrc *m, - struct mp_config_intsrc *mp_irq) +static void assign_to_mp_irq(struct mpc_intsrc *m, + struct mpc_intsrc *mp_irq) { - memcpy(mp_irq, m, sizeof(struct mp_config_intsrc)); + memcpy(mp_irq, m, sizeof(struct mpc_intsrc)); } -static int mp_irq_cmp(struct mp_config_intsrc *mp_irq, - struct mp_config_intsrc *m) +static int mp_irq_cmp(struct mpc_intsrc *mp_irq, + struct mpc_intsrc *m) { - return memcmp(mp_irq, m, sizeof(struct mp_config_intsrc)); + return memcmp(mp_irq, m, sizeof(struct mpc_intsrc)); } -static void save_mp_irq(struct mp_config_intsrc *m) +static void save_mp_irq(struct mpc_intsrc *m) { int i; @@ -1003,7 +1003,7 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) { int ioapic; int pin; - struct mp_config_intsrc mp_irq; + struct mpc_intsrc mp_irq; /* * Convert 'gsi' to 'ioapic.pin'. @@ -1021,13 +1021,13 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) if ((bus_irq == 0) && (trigger == 3)) trigger = 1; - mp_irq.mp_type = MP_INTSRC; - mp_irq.mp_irqtype = mp_INT; - mp_irq.mp_irqflag = (trigger << 2) | polarity; - mp_irq.mp_srcbus = MP_ISA_BUS; - mp_irq.mp_srcbusirq = bus_irq; /* IRQ */ - mp_irq.mp_dstapic = mp_ioapics[ioapic].apicid; /* APIC ID */ - mp_irq.mp_dstirq = pin; /* INTIN# */ + mp_irq.type = MP_INTSRC; + mp_irq.irqtype = mp_INT; + mp_irq.irqflag = (trigger << 2) | polarity; + mp_irq.srcbus = MP_ISA_BUS; + mp_irq.srcbusirq = bus_irq; /* IRQ */ + mp_irq.dstapic = mp_ioapics[ioapic].apicid; /* APIC ID */ + mp_irq.dstirq = pin; /* INTIN# */ save_mp_irq(&mp_irq); } @@ -1037,7 +1037,7 @@ void __init mp_config_acpi_legacy_irqs(void) int i; int ioapic; unsigned int dstapic; - struct mp_config_intsrc mp_irq; + struct mpc_intsrc mp_irq; #if defined (CONFIG_MCA) || defined (CONFIG_EISA) /* @@ -1072,16 +1072,14 @@ void __init mp_config_acpi_legacy_irqs(void) int idx; for (idx = 0; idx < mp_irq_entries; idx++) { - struct mp_config_intsrc *irq = mp_irqs + idx; + struct mpc_intsrc *irq = mp_irqs + idx; /* Do we already have a mapping for this ISA IRQ? */ - if (irq->mp_srcbus == MP_ISA_BUS - && irq->mp_srcbusirq == i) + if (irq->srcbus == MP_ISA_BUS && irq->srcbusirq == i) break; /* Do we already have a mapping for this IOAPIC pin */ - if (irq->mp_dstapic == dstapic && - irq->mp_dstirq == i) + if (irq->dstapic == dstapic && irq->dstirq == i) break; } @@ -1090,13 +1088,13 @@ void __init mp_config_acpi_legacy_irqs(void) continue; /* IRQ already used */ } - mp_irq.mp_type = MP_INTSRC; - mp_irq.mp_irqflag = 0; /* Conforming */ - mp_irq.mp_srcbus = MP_ISA_BUS; - mp_irq.mp_dstapic = dstapic; - mp_irq.mp_irqtype = mp_INT; - mp_irq.mp_srcbusirq = i; /* Identity mapped */ - mp_irq.mp_dstirq = i; + mp_irq.type = MP_INTSRC; + mp_irq.irqflag = 0; /* Conforming */ + mp_irq.srcbus = MP_ISA_BUS; + mp_irq.dstapic = dstapic; + mp_irq.irqtype = mp_INT; + mp_irq.srcbusirq = i; /* Identity mapped */ + mp_irq.dstirq = i; save_mp_irq(&mp_irq); } @@ -1207,22 +1205,22 @@ int mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin, u32 gsi, int triggering, int polarity) { #ifdef CONFIG_X86_MPPARSE - struct mp_config_intsrc mp_irq; + struct mpc_intsrc mp_irq; int ioapic; if (!acpi_ioapic) return 0; /* print the entry should happen on mptable identically */ - mp_irq.mp_type = MP_INTSRC; - mp_irq.mp_irqtype = mp_INT; - mp_irq.mp_irqflag = (triggering == ACPI_EDGE_SENSITIVE ? 4 : 0x0c) | + mp_irq.type = MP_INTSRC; + mp_irq.irqtype = mp_INT; + mp_irq.irqflag = (triggering == ACPI_EDGE_SENSITIVE ? 4 : 0x0c) | (polarity == ACPI_ACTIVE_HIGH ? 1 : 3); - mp_irq.mp_srcbus = number; - mp_irq.mp_srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3); + mp_irq.srcbus = number; + mp_irq.srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3); ioapic = mp_find_ioapic(gsi); - mp_irq.mp_dstapic = mp_ioapic_routing[ioapic].apic_id; - mp_irq.mp_dstirq = gsi - mp_ioapic_routing[ioapic].gsi_base; + mp_irq.dstapic = mp_ioapic_routing[ioapic].apic_id; + mp_irq.dstirq = gsi - mp_ioapic_routing[ioapic].gsi_base; save_mp_irq(&mp_irq); #endif diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c index 6c51ecdfbf4..79b8c0c72d3 100644 --- a/arch/x86/kernel/io_apic.c +++ b/arch/x86/kernel/io_apic.c @@ -87,7 +87,7 @@ struct mpc_ioapic mp_ioapics[MAX_IO_APICS]; int nr_ioapics; /* MP IRQ source entries */ -struct mp_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; +struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES]; /* # of MP IRQ source entries */ int mp_irq_entries; @@ -945,10 +945,10 @@ static int find_irq_entry(int apic, int pin, int type) int i; for (i = 0; i < mp_irq_entries; i++) - if (mp_irqs[i].mp_irqtype == type && - (mp_irqs[i].mp_dstapic == mp_ioapics[apic].apicid || - mp_irqs[i].mp_dstapic == MP_APIC_ALL) && - mp_irqs[i].mp_dstirq == pin) + if (mp_irqs[i].irqtype == type && + (mp_irqs[i].dstapic == mp_ioapics[apic].apicid || + mp_irqs[i].dstapic == MP_APIC_ALL) && + mp_irqs[i].dstirq == pin) return i; return -1; @@ -962,13 +962,13 @@ static int __init find_isa_irq_pin(int irq, int type) int i; for (i = 0; i < mp_irq_entries; i++) { - int lbus = mp_irqs[i].mp_srcbus; + int lbus = mp_irqs[i].srcbus; if (test_bit(lbus, mp_bus_not_pci) && - (mp_irqs[i].mp_irqtype == type) && - (mp_irqs[i].mp_srcbusirq == irq)) + (mp_irqs[i].irqtype == type) && + (mp_irqs[i].srcbusirq == irq)) - return mp_irqs[i].mp_dstirq; + return mp_irqs[i].dstirq; } return -1; } @@ -978,17 +978,17 @@ static int __init find_isa_irq_apic(int irq, int type) int i; for (i = 0; i < mp_irq_entries; i++) { - int lbus = mp_irqs[i].mp_srcbus; + int lbus = mp_irqs[i].srcbus; if (test_bit(lbus, mp_bus_not_pci) && - (mp_irqs[i].mp_irqtype == type) && - (mp_irqs[i].mp_srcbusirq == irq)) + (mp_irqs[i].irqtype == type) && + (mp_irqs[i].srcbusirq == irq)) break; } if (i < mp_irq_entries) { int apic; for(apic = 0; apic < nr_ioapics; apic++) { - if (mp_ioapics[apic].apicid == mp_irqs[i].mp_dstapic) + if (mp_ioapics[apic].apicid == mp_irqs[i].dstapic) return apic; } } @@ -1013,23 +1013,23 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin) return -1; } for (i = 0; i < mp_irq_entries; i++) { - int lbus = mp_irqs[i].mp_srcbus; + int lbus = mp_irqs[i].srcbus; for (apic = 0; apic < nr_ioapics; apic++) - if (mp_ioapics[apic].apicid == mp_irqs[i].mp_dstapic || - mp_irqs[i].mp_dstapic == MP_APIC_ALL) + if (mp_ioapics[apic].apicid == mp_irqs[i].dstapic || + mp_irqs[i].dstapic == MP_APIC_ALL) break; if (!test_bit(lbus, mp_bus_not_pci) && - !mp_irqs[i].mp_irqtype && + !mp_irqs[i].irqtype && (bus == lbus) && - (slot == ((mp_irqs[i].mp_srcbusirq >> 2) & 0x1f))) { - int irq = pin_2_irq(i,apic,mp_irqs[i].mp_dstirq); + (slot == ((mp_irqs[i].srcbusirq >> 2) & 0x1f))) { + int irq = pin_2_irq(i, apic, mp_irqs[i].dstirq); if (!(apic || IO_APIC_IRQ(irq))) continue; - if (pin == (mp_irqs[i].mp_srcbusirq & 3)) + if (pin == (mp_irqs[i].srcbusirq & 3)) return irq; /* * Use the first all-but-pin matching entry as a @@ -1072,7 +1072,7 @@ static int EISA_ELCR(unsigned int irq) * EISA conforming in the MP table, that means its trigger type must * be read in from the ELCR */ -#define default_EISA_trigger(idx) (EISA_ELCR(mp_irqs[idx].mp_srcbusirq)) +#define default_EISA_trigger(idx) (EISA_ELCR(mp_irqs[idx].srcbusirq)) #define default_EISA_polarity(idx) default_ISA_polarity(idx) /* PCI interrupts are always polarity one level triggered, @@ -1089,13 +1089,13 @@ static int EISA_ELCR(unsigned int irq) static int MPBIOS_polarity(int idx) { - int bus = mp_irqs[idx].mp_srcbus; + int bus = mp_irqs[idx].srcbus; int polarity; /* * Determine IRQ line polarity (high active or low active): */ - switch (mp_irqs[idx].mp_irqflag & 3) + switch (mp_irqs[idx].irqflag & 3) { case 0: /* conforms, ie. bus-type dependent polarity */ if (test_bit(bus, mp_bus_not_pci)) @@ -1131,13 +1131,13 @@ static int MPBIOS_polarity(int idx) static int MPBIOS_trigger(int idx) { - int bus = mp_irqs[idx].mp_srcbus; + int bus = mp_irqs[idx].srcbus; int trigger; /* * Determine IRQ trigger mode (edge or level sensitive): */ - switch ((mp_irqs[idx].mp_irqflag>>2) & 3) + switch ((mp_irqs[idx].irqflag>>2) & 3) { case 0: /* conforms, ie. bus-type dependent */ if (test_bit(bus, mp_bus_not_pci)) @@ -1215,16 +1215,16 @@ int (*ioapic_renumber_irq)(int ioapic, int irq); static int pin_2_irq(int idx, int apic, int pin) { int irq, i; - int bus = mp_irqs[idx].mp_srcbus; + int bus = mp_irqs[idx].srcbus; /* * Debugging check, we are in big trouble if this message pops up! */ - if (mp_irqs[idx].mp_dstirq != pin) + if (mp_irqs[idx].dstirq != pin) printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n"); if (test_bit(bus, mp_bus_not_pci)) { - irq = mp_irqs[idx].mp_srcbusirq; + irq = mp_irqs[idx].srcbusirq; } else { /* * PCI IRQs are mapped in order @@ -2164,8 +2164,8 @@ static void __init setup_ioapic_ids_from_mpc(void) */ if (old_id != mp_ioapics[apic].apicid) for (i = 0; i < mp_irq_entries; i++) - if (mp_irqs[i].mp_dstapic == old_id) - mp_irqs[i].mp_dstapic + if (mp_irqs[i].dstapic == old_id) + mp_irqs[i].dstapic = mp_ioapics[apic].apicid; /* @@ -3983,8 +3983,8 @@ int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity) return -1; for (i = 0; i < mp_irq_entries; i++) - if (mp_irqs[i].mp_irqtype == mp_INT && - mp_irqs[i].mp_srcbusirq == bus_irq) + if (mp_irqs[i].irqtype == mp_INT && + mp_irqs[i].srcbusirq == bus_irq) break; if (i >= mp_irq_entries) return -1; diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index a86a6553743..ad36377dc93 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c @@ -159,55 +159,55 @@ static void print_MP_intsrc_info(struct mpc_intsrc *m) m->srcbusirq, m->dstapic, m->dstirq); } -static void __init print_mp_irq_info(struct mp_config_intsrc *mp_irq) +static void __init print_mp_irq_info(struct mpc_intsrc *mp_irq) { apic_printk(APIC_VERBOSE, "Int: type %d, pol %d, trig %d, bus %02x," " IRQ %02x, APIC ID %x, APIC INT %02x\n", - mp_irq->mp_irqtype, mp_irq->mp_irqflag & 3, - (mp_irq->mp_irqflag >> 2) & 3, mp_irq->mp_srcbus, - mp_irq->mp_srcbusirq, mp_irq->mp_dstapic, mp_irq->mp_dstirq); + mp_irq->irqtype, mp_irq->irqflag & 3, + (mp_irq->irqflag >> 2) & 3, mp_irq->srcbus, + mp_irq->srcbusirq, mp_irq->dstapic, mp_irq->dstirq); } static void __init assign_to_mp_irq(struct mpc_intsrc *m, - struct mp_config_intsrc *mp_irq) + struct mpc_intsrc *mp_irq) { - mp_irq->mp_dstapic = m->dstapic; - mp_irq->mp_type = m->type; - mp_irq->mp_irqtype = m->irqtype; - mp_irq->mp_irqflag = m->irqflag; - mp_irq->mp_srcbus = m->srcbus; - mp_irq->mp_srcbusirq = m->srcbusirq; - mp_irq->mp_dstirq = m->dstirq; + mp_irq->dstapic = m->dstapic; + mp_irq->type = m->type; + mp_irq->irqtype = m->irqtype; + mp_irq->irqflag = m->irqflag; + mp_irq->srcbus = m->srcbus; + mp_irq->srcbusirq = m->srcbusirq; + mp_irq->dstirq = m->dstirq; } -static void __init assign_to_mpc_intsrc(struct mp_config_intsrc *mp_irq, +static void __init assign_to_mpc_intsrc(struct mpc_intsrc *mp_irq, struct mpc_intsrc *m) { - m->dstapic = mp_irq->mp_dstapic; - m->type = mp_irq->mp_type; - m->irqtype = mp_irq->mp_irqtype; - m->irqflag = mp_irq->mp_irqflag; - m->srcbus = mp_irq->mp_srcbus; - m->srcbusirq = mp_irq->mp_srcbusirq; - m->dstirq = mp_irq->mp_dstirq; + m->dstapic = mp_irq->dstapic; + m->type = mp_irq->type; + m->irqtype = mp_irq->irqtype; + m->irqflag = mp_irq->irqflag; + m->srcbus = mp_irq->srcbus; + m->srcbusirq = mp_irq->srcbusirq; + m->dstirq = mp_irq->dstirq; } -static int __init mp_irq_mpc_intsrc_cmp(struct mp_config_intsrc *mp_irq, +static int __init mp_irq_mpc_intsrc_cmp(struct mpc_intsrc *mp_irq, struct mpc_intsrc *m) { - if (mp_irq->mp_dstapic != m->dstapic) + if (mp_irq->dstapic != m->dstapic) return 1; - if (mp_irq->mp_type != m->type) + if (mp_irq->type != m->type) return 2; - if (mp_irq->mp_irqtype != m->irqtype) + if (mp_irq->irqtype != m->irqtype) return 3; - if (mp_irq->mp_irqflag != m->irqflag) + if (mp_irq->irqflag != m->irqflag) return 4; - if (mp_irq->mp_srcbus != m->srcbus) + if (mp_irq->srcbus != m->srcbus) return 5; - if (mp_irq->mp_srcbusirq != m->srcbusirq) + if (mp_irq->srcbusirq != m->srcbusirq) return 6; - if (mp_irq->mp_dstirq != m->dstirq) + if (mp_irq->dstirq != m->dstirq) return 7; return 0; @@ -808,15 +808,15 @@ static int __init get_MP_intsrc_index(struct mpc_intsrc *m) /* not legacy */ for (i = 0; i < mp_irq_entries; i++) { - if (mp_irqs[i].mp_irqtype != mp_INT) + if (mp_irqs[i].irqtype != mp_INT) continue; - if (mp_irqs[i].mp_irqflag != 0x0f) + if (mp_irqs[i].irqflag != 0x0f) continue; - if (mp_irqs[i].mp_srcbus != m->srcbus) + if (mp_irqs[i].srcbus != m->srcbus) continue; - if (mp_irqs[i].mp_srcbusirq != m->srcbusirq) + if (mp_irqs[i].srcbusirq != m->srcbusirq) continue; if (irq_used[i]) { /* already claimed */ @@ -921,10 +921,10 @@ static int __init replace_intsrc_all(struct mpc_table *mpc, if (irq_used[i]) continue; - if (mp_irqs[i].mp_irqtype != mp_INT) + if (mp_irqs[i].irqtype != mp_INT) continue; - if (mp_irqs[i].mp_irqflag != 0x0f) + if (mp_irqs[i].irqflag != 0x0f) continue; if (nr_m_spare > 0) { -- cgit From 09b3ec7315a18d885127544204f1e389d41058d0 Mon Sep 17 00:00:00 2001 From: Frederik Deweerdt Date: Mon, 12 Jan 2009 22:35:42 +0100 Subject: x86, tlb flush_data: replace per_cpu with an array Impact: micro-optimization, memory reduction On x86_64 flush tlb data is stored in per_cpu variables. This is unnecessary because only the first NUM_INVALIDATE_TLB_VECTORS entries are accessed. This patch aims at making the code less confusing (there's nothing really "per_cpu") by using a plain array. It also would save some memory on most distros out there (Ubuntu x86_64 has NR_CPUS=64 by default). [ Ravikiran G Thirumalai also pointed out that the correct alignment is ____cacheline_internodealigned_in_smp, so that there's no bouncing on vsmp. ] Signed-off-by: Frederik Deweerdt Acked-by: Ravikiran Thirumalai Signed-off-by: Ingo Molnar --- arch/x86/kernel/tlb_64.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/x86/kernel/tlb_64.c b/arch/x86/kernel/tlb_64.c index f8be6f1d2e4..8cfea5d1451 100644 --- a/arch/x86/kernel/tlb_64.c +++ b/arch/x86/kernel/tlb_64.c @@ -33,7 +33,7 @@ * To avoid global state use 8 different call vectors. * Each CPU uses a specific vector to trigger flushes on other * CPUs. Depending on the received vector the target CPUs look into - * the right per cpu variable for the flush data. + * the right array slot for the flush data. * * With more than 8 CPUs they are hashed to the 8 available * vectors. The limited global vector space forces us to this right now. @@ -48,13 +48,13 @@ union smp_flush_state { unsigned long flush_va; spinlock_t tlbstate_lock; }; - char pad[SMP_CACHE_BYTES]; -} ____cacheline_aligned; + char pad[CONFIG_X86_INTERNODE_CACHE_BYTES]; +} ____cacheline_internodealigned_in_smp; /* State is put into the per CPU data section, but padded to a full cache line because other CPUs can access it and we don't want false sharing in the per cpu data segment. */ -static DEFINE_PER_CPU(union smp_flush_state, flush_state); +static union smp_flush_state flush_state[NUM_INVALIDATE_TLB_VECTORS]; /* * We cannot call mmdrop() because we are in interrupt context, @@ -129,7 +129,7 @@ asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs) * Use that to determine where the sender put the data. */ sender = ~regs->orig_ax - INVALIDATE_TLB_VECTOR_START; - f = &per_cpu(flush_state, sender); + f = &flush_state[sender]; if (!cpu_isset(cpu, f->flush_cpumask)) goto out; @@ -169,7 +169,7 @@ void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm, /* Caller has disabled preemption */ sender = smp_processor_id() % NUM_INVALIDATE_TLB_VECTORS; - f = &per_cpu(flush_state, sender); + f = &flush_state[sender]; /* * Could avoid this lock when @@ -205,8 +205,8 @@ static int __cpuinit init_smp_flush(void) { int i; - for_each_possible_cpu(i) - spin_lock_init(&per_cpu(flush_state, i).tlbstate_lock); + for (i = 0; i < ARRAY_SIZE(flush_state); i++) + spin_lock_init(&flush_state[i].tlbstate_lock); return 0; } -- cgit From 0a2a18b721abc960fbcada406746877d22340a60 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 12 Jan 2009 23:37:16 +0100 Subject: x86: change the default cache size to 64 bytes Right now the generic cacheline size is 128 bytes - that is wasteful when structures are aligned, as all modern x86 CPUs have an (effective) cacheline sizes of 64 bytes. It was set to 128 bytes due to some cacheline aliasing problems on older P4 systems, but those are many years old and we dont optimize for them anymore. (They'll still get the 128 bytes cacheline size if the kernel is specifically built for Pentium 4) Signed-off-by: Ingo Molnar Acked-by: Arjan van de Ven --- arch/x86/Kconfig.cpu | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu index 8078955845a..cdf4a962323 100644 --- a/arch/x86/Kconfig.cpu +++ b/arch/x86/Kconfig.cpu @@ -307,10 +307,10 @@ config X86_CMPXCHG config X86_L1_CACHE_SHIFT int - default "7" if MPENTIUM4 || X86_GENERIC || GENERIC_CPU || MPSC + default "7" if MPENTIUM4 || MPSC default "4" if X86_ELAN || M486 || M386 || MGEODEGX1 default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX - default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MVIAC7 + default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MVIAC7 || X86_GENERIC || GENERIC_CPU config X86_XADD def_bool y -- cgit From b665967979d0e990f196e7c4ba88e17c9ed9b781 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 12 Jan 2009 11:54:27 -0800 Subject: x86: make 32bit MAX_HARDIRQS_PER_CPU to be NR_VECTORS Impact: clean up to be same as 64bit 32-bit is using per-cpu vector too, so don't use default NR_IRQS. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/include/asm/hardirq_32.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/x86/include/asm/hardirq_32.h b/arch/x86/include/asm/hardirq_32.h index cf7954d1405..d4b5d731073 100644 --- a/arch/x86/include/asm/hardirq_32.h +++ b/arch/x86/include/asm/hardirq_32.h @@ -19,6 +19,9 @@ typedef struct { DECLARE_PER_CPU(irq_cpustat_t, irq_stat); +/* We can have at most NR_VECTORS irqs routed to a cpu at a time */ +#define MAX_HARDIRQS_PER_CPU NR_VECTORS + #define __ARCH_IRQ_STAT #define __IRQ_STAT(cpu, member) (per_cpu(irq_stat, cpu).member) -- cgit From 14819ea1e0bcbdc9b084cd60a6a24d5d786324ef Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 14 Jan 2009 12:34:21 +0100 Subject: irq: export __set_irq_handler() and handle_level_irq() Impact: build fix ARM updates broke x86 allmodconfig builds: ERROR: "__set_irq_handler" [drivers/mfd/pcf50633-core.ko] undefined! ERROR: "handle_level_irq" [drivers/mfd/pcf50633-core.ko] undefined! Signed-off-by: Ingo Molnar --- kernel/irq/chip.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index f63c706d25e..7de11bd64df 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -383,6 +383,7 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc) out_unlock: spin_unlock(&desc->lock); } +EXPORT_SYMBOL_GPL(handle_level_irq); /** * handle_fasteoi_irq - irq handler for transparent controllers @@ -593,6 +594,7 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, } spin_unlock_irqrestore(&desc->lock, flags); } +EXPORT_SYMBOL_GPL(__set_irq_handler); void set_irq_chip_and_handler(unsigned int irq, struct irq_chip *chip, -- cgit From 4c696ba7982501d43dea11dbbaabd2aa8a19cc42 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:13:53 +0100 Subject: [CVE-2009-0029] Move compat system call declarations to compat header file Move declarations to correct header file. Signed-off-by: Heiko Carstens --- include/linux/compat.h | 13 +++++++++++++ include/linux/syscalls.h | 12 ------------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/include/linux/compat.h b/include/linux/compat.h index e88f3ecf38b..3fd2194ff57 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -280,5 +280,18 @@ asmlinkage long compat_sys_timerfd_settime(int ufd, int flags, asmlinkage long compat_sys_timerfd_gettime(int ufd, struct compat_itimerspec __user *otmr); +asmlinkage long compat_sys_move_pages(pid_t pid, unsigned long nr_page, + __u32 __user *pages, + const int __user *nodes, + int __user *status, + int flags); +asmlinkage long compat_sys_futimesat(unsigned int dfd, char __user *filename, + struct compat_timeval __user *t); +asmlinkage long compat_sys_newfstatat(unsigned int dfd, char __user * filename, + struct compat_stat __user *statbuf, + int flag); +asmlinkage long compat_sys_openat(unsigned int dfd, const char __user *filename, + int flags, int mode); + #endif /* CONFIG_COMPAT */ #endif /* _LINUX_COMPAT_H */ diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 18d0a243a7b..a7593f670ca 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -530,11 +530,6 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages, const int __user *nodes, int __user *status, int flags); -asmlinkage long compat_sys_move_pages(pid_t pid, unsigned long nr_page, - __u32 __user *pages, - const int __user *nodes, - int __user *status, - int flags); asmlinkage long sys_mbind(unsigned long start, unsigned long len, unsigned long mode, unsigned long __user *nmask, @@ -583,13 +578,6 @@ asmlinkage long sys_readlinkat(int dfd, const char __user *path, char __user *bu int bufsiz); asmlinkage long sys_utimensat(int dfd, char __user *filename, struct timespec __user *utimes, int flags); -asmlinkage long compat_sys_futimesat(unsigned int dfd, char __user *filename, - struct compat_timeval __user *t); -asmlinkage long compat_sys_newfstatat(unsigned int dfd, char __user * filename, - struct compat_stat __user *statbuf, - int flag); -asmlinkage long compat_sys_openat(unsigned int dfd, const char __user *filename, - int flags, int mode); asmlinkage long sys_unshare(unsigned long unshare_flags); asmlinkage long sys_splice(int fd_in, loff_t __user *off_in, -- cgit From 2ed7c03ec17779afb4fcfa3b8c61df61bd4879ba Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:13:54 +0100 Subject: [CVE-2009-0029] Convert all system calls to return a long Convert all system calls to return a long. This should be a NOP since all converted types should have the same size anyway. With the exception of sys_exit_group which returned void. But that doesn't matter since the system call doesn't return. Signed-off-by: Heiko Carstens --- fs/read_write.c | 18 +++++------ fs/xattr.c | 12 ++++---- include/linux/syscalls.h | 79 ++++++++++++++++++++++++------------------------ ipc/mqueue.c | 2 +- kernel/exit.c | 4 ++- kernel/signal.c | 2 +- kernel/timer.c | 2 +- mm/filemap.c | 2 +- mm/mmap.c | 2 +- mm/mremap.c | 2 +- mm/nommu.c | 2 +- 11 files changed, 64 insertions(+), 63 deletions(-) diff --git a/fs/read_write.c b/fs/read_write.c index 5cc6924eb15..940367f51f2 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -147,7 +147,7 @@ loff_t vfs_llseek(struct file *file, loff_t offset, int origin) } EXPORT_SYMBOL(vfs_llseek); -asmlinkage off_t sys_lseek(unsigned int fd, off_t offset, unsigned int origin) +asmlinkage long sys_lseek(unsigned int fd, off_t offset, unsigned int origin) { off_t retval; struct file * file; @@ -369,7 +369,7 @@ static inline void file_pos_write(struct file *file, loff_t pos) file->f_pos = pos; } -asmlinkage ssize_t sys_read(unsigned int fd, char __user * buf, size_t count) +asmlinkage long sys_read(unsigned int fd, char __user * buf, size_t count) { struct file *file; ssize_t ret = -EBADF; @@ -386,7 +386,7 @@ asmlinkage ssize_t sys_read(unsigned int fd, char __user * buf, size_t count) return ret; } -asmlinkage ssize_t sys_write(unsigned int fd, const char __user * buf, size_t count) +asmlinkage long sys_write(unsigned int fd, const char __user * buf, size_t count) { struct file *file; ssize_t ret = -EBADF; @@ -403,7 +403,7 @@ asmlinkage ssize_t sys_write(unsigned int fd, const char __user * buf, size_t co return ret; } -asmlinkage ssize_t sys_pread64(unsigned int fd, char __user *buf, +asmlinkage long sys_pread64(unsigned int fd, char __user *buf, size_t count, loff_t pos) { struct file *file; @@ -424,7 +424,7 @@ asmlinkage ssize_t sys_pread64(unsigned int fd, char __user *buf, return ret; } -asmlinkage ssize_t sys_pwrite64(unsigned int fd, const char __user *buf, +asmlinkage long sys_pwrite64(unsigned int fd, const char __user *buf, size_t count, loff_t pos) { struct file *file; @@ -672,7 +672,7 @@ ssize_t vfs_writev(struct file *file, const struct iovec __user *vec, EXPORT_SYMBOL(vfs_writev); -asmlinkage ssize_t +asmlinkage long sys_readv(unsigned long fd, const struct iovec __user *vec, unsigned long vlen) { struct file *file; @@ -693,7 +693,7 @@ sys_readv(unsigned long fd, const struct iovec __user *vec, unsigned long vlen) return ret; } -asmlinkage ssize_t +asmlinkage long sys_writev(unsigned long fd, const struct iovec __user *vec, unsigned long vlen) { struct file *file; @@ -812,7 +812,7 @@ out: return retval; } -asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t __user *offset, size_t count) +asmlinkage long sys_sendfile(int out_fd, int in_fd, off_t __user *offset, size_t count) { loff_t pos; off_t off; @@ -831,7 +831,7 @@ asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t __user *offset, siz return do_sendfile(out_fd, in_fd, NULL, count, 0); } -asmlinkage ssize_t sys_sendfile64(int out_fd, int in_fd, loff_t __user *offset, size_t count) +asmlinkage long sys_sendfile64(int out_fd, int in_fd, loff_t __user *offset, size_t count) { loff_t pos; ssize_t ret; diff --git a/fs/xattr.c b/fs/xattr.c index 237804cd6b5..d049ae27aae 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -349,7 +349,7 @@ getxattr(struct dentry *d, const char __user *name, void __user *value, return error; } -asmlinkage ssize_t +asmlinkage long sys_getxattr(const char __user *pathname, const char __user *name, void __user *value, size_t size) { @@ -364,7 +364,7 @@ sys_getxattr(const char __user *pathname, const char __user *name, return error; } -asmlinkage ssize_t +asmlinkage long sys_lgetxattr(const char __user *pathname, const char __user *name, void __user *value, size_t size) { @@ -379,7 +379,7 @@ sys_lgetxattr(const char __user *pathname, const char __user *name, void __user return error; } -asmlinkage ssize_t +asmlinkage long sys_fgetxattr(int fd, const char __user *name, void __user *value, size_t size) { struct file *f; @@ -424,7 +424,7 @@ listxattr(struct dentry *d, char __user *list, size_t size) return error; } -asmlinkage ssize_t +asmlinkage long sys_listxattr(const char __user *pathname, char __user *list, size_t size) { struct path path; @@ -438,7 +438,7 @@ sys_listxattr(const char __user *pathname, char __user *list, size_t size) return error; } -asmlinkage ssize_t +asmlinkage long sys_llistxattr(const char __user *pathname, char __user *list, size_t size) { struct path path; @@ -452,7 +452,7 @@ sys_llistxattr(const char __user *pathname, char __user *list, size_t size) return error; } -asmlinkage ssize_t +asmlinkage long sys_flistxattr(int fd, char __user *list, size_t size) { struct file *f; diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index a7593f670ca..22290eeaf55 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -77,7 +77,7 @@ asmlinkage long sys_times(struct tms __user *tbuf); asmlinkage long sys_gettid(void); asmlinkage long sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp); -asmlinkage unsigned long sys_alarm(unsigned int seconds); +asmlinkage long sys_alarm(unsigned int seconds); asmlinkage long sys_getpid(void); asmlinkage long sys_getppid(void); asmlinkage long sys_getuid(void); @@ -166,7 +166,7 @@ asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments, unsigned long flags); asmlinkage long sys_exit(int error_code); -asmlinkage void sys_exit_group(int error_code); +asmlinkage long sys_exit_group(int error_code); asmlinkage long sys_wait4(pid_t pid, int __user *stat_addr, int options, struct rusage __user *ru); asmlinkage long sys_waitid(int which, pid_t pid, @@ -196,7 +196,7 @@ asmlinkage long sys_tkill(int pid, int sig); asmlinkage long sys_rt_sigqueueinfo(int pid, int sig, siginfo_t __user *uinfo); asmlinkage long sys_sgetmask(void); asmlinkage long sys_ssetmask(int newmask); -asmlinkage unsigned long sys_signal(int sig, __sighandler_t handler); +asmlinkage long sys_signal(int sig, __sighandler_t handler); asmlinkage long sys_pause(void); asmlinkage long sys_sync(void); @@ -246,29 +246,29 @@ asmlinkage long sys_lsetxattr(const char __user *path, const char __user *name, const void __user *value, size_t size, int flags); asmlinkage long sys_fsetxattr(int fd, const char __user *name, const void __user *value, size_t size, int flags); -asmlinkage ssize_t sys_getxattr(const char __user *path, const char __user *name, - void __user *value, size_t size); -asmlinkage ssize_t sys_lgetxattr(const char __user *path, const char __user *name, - void __user *value, size_t size); -asmlinkage ssize_t sys_fgetxattr(int fd, const char __user *name, - void __user *value, size_t size); -asmlinkage ssize_t sys_listxattr(const char __user *path, char __user *list, - size_t size); -asmlinkage ssize_t sys_llistxattr(const char __user *path, char __user *list, - size_t size); -asmlinkage ssize_t sys_flistxattr(int fd, char __user *list, size_t size); +asmlinkage long sys_getxattr(const char __user *path, const char __user *name, + void __user *value, size_t size); +asmlinkage long sys_lgetxattr(const char __user *path, const char __user *name, + void __user *value, size_t size); +asmlinkage long sys_fgetxattr(int fd, const char __user *name, + void __user *value, size_t size); +asmlinkage long sys_listxattr(const char __user *path, char __user *list, + size_t size); +asmlinkage long sys_llistxattr(const char __user *path, char __user *list, + size_t size); +asmlinkage long sys_flistxattr(int fd, char __user *list, size_t size); asmlinkage long sys_removexattr(const char __user *path, const char __user *name); asmlinkage long sys_lremovexattr(const char __user *path, const char __user *name); asmlinkage long sys_fremovexattr(int fd, const char __user *name); -asmlinkage unsigned long sys_brk(unsigned long brk); +asmlinkage long sys_brk(unsigned long brk); asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot); -asmlinkage unsigned long sys_mremap(unsigned long addr, - unsigned long old_len, unsigned long new_len, - unsigned long flags, unsigned long new_addr); +asmlinkage long sys_mremap(unsigned long addr, + unsigned long old_len, unsigned long new_len, + unsigned long flags, unsigned long new_addr); asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size, unsigned long prot, unsigned long pgoff, unsigned long flags); @@ -321,10 +321,10 @@ asmlinkage long sys_io_submit(aio_context_t, long, struct iocb __user * __user *); asmlinkage long sys_io_cancel(aio_context_t ctx_id, struct iocb __user *iocb, struct io_event __user *result); -asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, - off_t __user *offset, size_t count); -asmlinkage ssize_t sys_sendfile64(int out_fd, int in_fd, - loff_t __user *offset, size_t count); +asmlinkage long sys_sendfile(int out_fd, int in_fd, + off_t __user *offset, size_t count); +asmlinkage long sys_sendfile64(int out_fd, int in_fd, + loff_t __user *offset, size_t count); asmlinkage long sys_readlink(const char __user *path, char __user *buf, int bufsiz); asmlinkage long sys_creat(const char __user *pathname, int mode); @@ -368,26 +368,25 @@ asmlinkage long sys_utime(char __user *filename, struct utimbuf __user *times); asmlinkage long sys_utimes(char __user *filename, struct timeval __user *utimes); -asmlinkage off_t sys_lseek(unsigned int fd, off_t offset, - unsigned int origin); +asmlinkage long sys_lseek(unsigned int fd, off_t offset, + unsigned int origin); asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high, unsigned long offset_low, loff_t __user *result, unsigned int origin); -asmlinkage ssize_t sys_read(unsigned int fd, char __user *buf, - size_t count); -asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count); -asmlinkage ssize_t sys_readv(unsigned long fd, - const struct iovec __user *vec, - unsigned long vlen); -asmlinkage ssize_t sys_write(unsigned int fd, const char __user *buf, - size_t count); -asmlinkage ssize_t sys_writev(unsigned long fd, - const struct iovec __user *vec, - unsigned long vlen); -asmlinkage ssize_t sys_pread64(unsigned int fd, char __user *buf, - size_t count, loff_t pos); -asmlinkage ssize_t sys_pwrite64(unsigned int fd, const char __user *buf, - size_t count, loff_t pos); +asmlinkage long sys_read(unsigned int fd, char __user *buf, size_t count); +asmlinkage long sys_readahead(int fd, loff_t offset, size_t count); +asmlinkage long sys_readv(unsigned long fd, + const struct iovec __user *vec, + unsigned long vlen); +asmlinkage long sys_write(unsigned int fd, const char __user *buf, + size_t count); +asmlinkage long sys_writev(unsigned long fd, + const struct iovec __user *vec, + unsigned long vlen); +asmlinkage long sys_pread64(unsigned int fd, char __user *buf, + size_t count, loff_t pos); +asmlinkage long sys_pwrite64(unsigned int fd, const char __user *buf, + size_t count, loff_t pos); asmlinkage long sys_getcwd(char __user *buf, unsigned long size); asmlinkage long sys_mkdir(const char __user *pathname, int mode); asmlinkage long sys_chdir(const char __user *filename); @@ -476,7 +475,7 @@ asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf); asmlinkage long sys_mq_open(const char __user *name, int oflag, mode_t mode, struct mq_attr __user *attr); asmlinkage long sys_mq_unlink(const char __user *name); asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec __user *abs_timeout); -asmlinkage ssize_t sys_mq_timedreceive(mqd_t mqdes, char __user *msg_ptr, size_t msg_len, unsigned int __user *msg_prio, const struct timespec __user *abs_timeout); +asmlinkage long sys_mq_timedreceive(mqd_t mqdes, char __user *msg_ptr, size_t msg_len, unsigned int __user *msg_prio, const struct timespec __user *abs_timeout); asmlinkage long sys_mq_notify(mqd_t mqdes, const struct sigevent __user *notification); asmlinkage long sys_mq_getsetattr(mqd_t mqdes, const struct mq_attr __user *mqstat, struct mq_attr __user *omqstat); diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 23fdb8492b8..6df028b7054 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -907,7 +907,7 @@ out: return ret; } -asmlinkage ssize_t sys_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr, +asmlinkage long sys_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr, size_t msg_len, unsigned int __user *u_msg_prio, const struct timespec __user *u_abs_timeout) { diff --git a/kernel/exit.c b/kernel/exit.c index c7740fa3252..fac9b040af2 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -1182,9 +1182,11 @@ do_group_exit(int exit_code) * wait4()-ing process will get the correct exit code - even if this * thread is not the thread group leader. */ -asmlinkage void sys_exit_group(int error_code) +asmlinkage long sys_exit_group(int error_code) { do_group_exit((error_code & 0xff) << 8); + /* NOTREACHED */ + return 0; } static struct pid *task_pid_type(struct task_struct *task, enum pid_type type) diff --git a/kernel/signal.c b/kernel/signal.c index 3152ac3b62e..856a5479d49 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2559,7 +2559,7 @@ sys_ssetmask(int newmask) /* * For backwards compatibility. Functionality superseded by sigaction. */ -asmlinkage unsigned long +asmlinkage long sys_signal(int sig, __sighandler_t handler) { struct k_sigaction new_sa, old_sa; diff --git a/kernel/timer.c b/kernel/timer.c index dee3f641a7a..7b8697d7f04 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -1129,7 +1129,7 @@ void do_timer(unsigned long ticks) * For backwards compatibility? This can be done in libc so Alpha * and all newer ports shouldn't need it. */ -asmlinkage unsigned long sys_alarm(unsigned int seconds) +asmlinkage long sys_alarm(unsigned int seconds) { return alarm_setitimer(seconds); } diff --git a/mm/filemap.c b/mm/filemap.c index ceba0bd0366..538b75ed623 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1374,7 +1374,7 @@ do_readahead(struct address_space *mapping, struct file *filp, return 0; } -asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count) +asmlinkage long sys_readahead(int fd, loff_t offset, size_t count) { ssize_t ret; struct file *file; diff --git a/mm/mmap.c b/mm/mmap.c index 749623196cb..a970d890cb2 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -245,7 +245,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) return next; } -asmlinkage unsigned long sys_brk(unsigned long brk) +asmlinkage long sys_brk(unsigned long brk) { unsigned long rlim, retval; unsigned long newbrk, oldbrk; diff --git a/mm/mremap.c b/mm/mremap.c index 646de959aa5..5572e0825d8 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -420,7 +420,7 @@ out_nc: return ret; } -asmlinkage unsigned long sys_mremap(unsigned long addr, +asmlinkage long sys_mremap(unsigned long addr, unsigned long old_len, unsigned long new_len, unsigned long flags, unsigned long new_addr) { diff --git a/mm/nommu.c b/mm/nommu.c index 60ed8375c98..ee3e7892773 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -416,7 +416,7 @@ EXPORT_SYMBOL(vm_insert_page); * to a regular file. in this case, the unmapping will need * to invoke file system routines that need the global lock. */ -asmlinkage unsigned long sys_brk(unsigned long brk) +asmlinkage long sys_brk(unsigned long brk) { struct mm_struct *mm = current->mm; -- cgit From e55380edf68796d75bf41391a781c68ee678587d Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:13:55 +0100 Subject: [CVE-2009-0029] Rename old_readdir to sys_old_readdir This way it matches the generic system call name convention. Signed-off-by: Heiko Carstens --- arch/arm/kernel/calls.S | 2 +- arch/cris/arch-v10/kernel/entry.S | 2 +- arch/cris/arch-v32/kernel/entry.S | 2 +- arch/h8300/kernel/syscalls.S | 2 +- arch/m68k/kernel/entry.S | 2 +- arch/m68knommu/kernel/syscalltable.S | 2 +- arch/mips/kernel/scall32-o32.S | 2 +- arch/mn10300/kernel/entry.S | 2 +- arch/powerpc/include/asm/systbl.h | 2 +- arch/sh/kernel/syscalls_32.S | 2 +- arch/sh/kernel/syscalls_64.S | 2 +- arch/sparc/kernel/systbls_32.S | 2 +- arch/x86/kernel/syscall_table_32.S | 2 +- fs/readdir.c | 2 +- include/linux/syscalls.h | 2 ++ 15 files changed, 16 insertions(+), 14 deletions(-) diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index 09a061cb783..9ca8d13f05f 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -98,7 +98,7 @@ CALL(sys_uselib) CALL(sys_swapon) CALL(sys_reboot) - CALL(OBSOLETE(old_readdir)) /* used by libc4 */ + CALL(OBSOLETE(sys_old_readdir)) /* used by libc4 */ /* 90 */ CALL(OBSOLETE(old_mmap)) /* used by libc4 */ CALL(sys_munmap) CALL(sys_truncate) diff --git a/arch/cris/arch-v10/kernel/entry.S b/arch/cris/arch-v10/kernel/entry.S index ed171d389e6..72f5cd319b9 100644 --- a/arch/cris/arch-v10/kernel/entry.S +++ b/arch/cris/arch-v10/kernel/entry.S @@ -691,7 +691,7 @@ sys_call_table: .long sys_uselib .long sys_swapon .long sys_reboot - .long old_readdir + .long sys_old_readdir .long old_mmap /* 90 */ .long sys_munmap .long sys_truncate diff --git a/arch/cris/arch-v32/kernel/entry.S b/arch/cris/arch-v32/kernel/entry.S index 7f6f93e6b70..5e674c8f7c5 100644 --- a/arch/cris/arch-v32/kernel/entry.S +++ b/arch/cris/arch-v32/kernel/entry.S @@ -614,7 +614,7 @@ sys_call_table: .long sys_uselib .long sys_swapon .long sys_reboot - .long old_readdir + .long sys_old_readdir .long old_mmap /* 90 */ .long sys_munmap .long sys_truncate diff --git a/arch/h8300/kernel/syscalls.S b/arch/h8300/kernel/syscalls.S index 54e21c3f205..4eb67faac63 100644 --- a/arch/h8300/kernel/syscalls.S +++ b/arch/h8300/kernel/syscalls.S @@ -103,7 +103,7 @@ SYMBOL_NAME_LABEL(sys_call_table) .long SYMBOL_NAME(sys_uselib) .long SYMBOL_NAME(sys_swapon) .long SYMBOL_NAME(sys_reboot) - .long SYMBOL_NAME(old_readdir) + .long SYMBOL_NAME(sys_old_readdir) .long SYMBOL_NAME(old_mmap) /* 90 */ .long SYMBOL_NAME(sys_munmap) .long SYMBOL_NAME(sys_truncate) diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S index 5b780826647..5c332f2b9b8 100644 --- a/arch/m68k/kernel/entry.S +++ b/arch/m68k/kernel/entry.S @@ -513,7 +513,7 @@ sys_call_table: .long sys_uselib .long sys_swapon .long sys_reboot - .long old_readdir + .long sys_old_readdir .long old_mmap /* 90 */ .long sys_munmap .long sys_truncate diff --git a/arch/m68knommu/kernel/syscalltable.S b/arch/m68knommu/kernel/syscalltable.S index 812f8d8b7a8..5c3e3f62194 100644 --- a/arch/m68knommu/kernel/syscalltable.S +++ b/arch/m68knommu/kernel/syscalltable.S @@ -107,7 +107,7 @@ ENTRY(sys_call_table) .long sys_uselib .long sys_ni_syscall /* sys_swapon */ .long sys_reboot - .long old_readdir + .long sys_old_readdir .long old_mmap /* 90 */ .long sys_munmap .long sys_truncate diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index d0916a55cd7..51d1ba415b9 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -398,7 +398,7 @@ einval: li v0, -ENOSYS sys sys_uselib 1 sys sys_swapon 2 sys sys_reboot 3 - sys old_readdir 3 + sys sys_old_readdir 3 sys old_mmap 6 /* 4090 */ sys sys_munmap 2 sys sys_truncate 2 diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S index 62fba8aa9b6..ceeaaaa359e 100644 --- a/arch/mn10300/kernel/entry.S +++ b/arch/mn10300/kernel/entry.S @@ -478,7 +478,7 @@ ENTRY(sys_call_table) .long sys_uselib .long sys_swapon .long sys_reboot - .long old_readdir + .long sys_old_readdir .long old_mmap /* 90 */ .long sys_munmap .long sys_truncate diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index 803def23665..72353f6070a 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h @@ -92,7 +92,7 @@ COMPAT_SYS_SPU(readlink) SYSCALL(uselib) SYSCALL(swapon) SYSCALL(reboot) -SYSX(sys_ni_syscall,compat_sys_old_readdir,old_readdir) +SYSX(sys_ni_syscall,compat_sys_old_readdir,sys_old_readdir) SYSCALL_SPU(mmap) SYSCALL_SPU(munmap) SYSCALL_SPU(truncate) diff --git a/arch/sh/kernel/syscalls_32.S b/arch/sh/kernel/syscalls_32.S index 0af693e6576..a87ce076cfa 100644 --- a/arch/sh/kernel/syscalls_32.S +++ b/arch/sh/kernel/syscalls_32.S @@ -105,7 +105,7 @@ ENTRY(sys_call_table) .long sys_uselib .long sys_swapon .long sys_reboot - .long old_readdir + .long sys_old_readdir .long old_mmap /* 90 */ .long sys_munmap .long sys_truncate diff --git a/arch/sh/kernel/syscalls_64.S b/arch/sh/kernel/syscalls_64.S index 0b436aa3cad..557cb91f5ca 100644 --- a/arch/sh/kernel/syscalls_64.S +++ b/arch/sh/kernel/syscalls_64.S @@ -109,7 +109,7 @@ sys_call_table: .long sys_uselib .long sys_swapon .long sys_reboot - .long old_readdir + .long sys_old_readdir .long old_mmap /* 90 */ .long sys_munmap .long sys_truncate diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index 7d080758644..8a434f51ba0 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S @@ -56,7 +56,7 @@ sys_call_table: /*185*/ .long sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname /*190*/ .long sys_init_module, sys_personality, sparc_remap_file_pages, sys_epoll_create, sys_epoll_ctl /*195*/ .long sys_epoll_wait, sys_ioprio_set, sys_getppid, sparc_sigaction, sys_sgetmask -/*200*/ .long sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, old_readdir +/*200*/ .long sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, sys_old_readdir /*205*/ .long sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64 /*210*/ .long sys_fadvise64_64, sys_tgkill, sys_waitpid, sys_swapoff, sys_sysinfo /*215*/ .long sys_ipc, sys_sigreturn, sys_clone, sys_ioprio_get, sys_adjtimex diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S index d44395ff34c..e2e86a08f31 100644 --- a/arch/x86/kernel/syscall_table_32.S +++ b/arch/x86/kernel/syscall_table_32.S @@ -88,7 +88,7 @@ ENTRY(sys_call_table) .long sys_uselib .long sys_swapon .long sys_reboot - .long old_readdir + .long sys_old_readdir .long old_mmap /* 90 */ .long sys_munmap .long sys_truncate diff --git a/fs/readdir.c b/fs/readdir.c index b318d9b5af2..8b4c2a0051a 100644 --- a/fs/readdir.c +++ b/fs/readdir.c @@ -102,7 +102,7 @@ efault: return -EFAULT; } -asmlinkage long old_readdir(unsigned int fd, struct old_linux_dirent __user * dirent, unsigned int count) +asmlinkage long sys_old_readdir(unsigned int fd, struct old_linux_dirent __user * dirent, unsigned int count) { int error; struct file * file; diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 22290eeaf55..ca079c3d09e 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -54,6 +54,7 @@ struct compat_stat; struct compat_timeval; struct robust_list_head; struct getcpu_cache; +struct old_linux_dirent; #include #include @@ -608,6 +609,7 @@ asmlinkage long sys_timerfd_gettime(int ufd, struct itimerspec __user *otmr); asmlinkage long sys_eventfd(unsigned int count); asmlinkage long sys_eventfd2(unsigned int count, int flags); asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len); +asmlinkage long sys_old_readdir(unsigned int, struct old_linux_dirent __user *, unsigned int); int kernel_execve(const char *filename, char *const argv[], char *const envp[]); -- cgit From 1134723e96f6e2abcf8bfd7a2d1c96fcc323ef35 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:13:56 +0100 Subject: [CVE-2009-0029] Remove __attribute__((weak)) from sys_pipe/sys_pipe2 Remove __attribute__((weak)) from common code sys_pipe implemantation. IA64, ALPHA, SUPERH (32bit) and SPARC (32bit) have own implemantations with the same name. Just rename them. For sys_pipe2 there is no architecture specific implementation. Cc: Richard Henderson Cc: David S. Miller Cc: Paul Mundt Cc: Tony Luck Signed-off-by: Heiko Carstens --- arch/alpha/kernel/entry.S | 8 ++++---- arch/alpha/kernel/systbls.S | 2 +- arch/ia64/ia32/ia32_entry.S | 2 +- arch/ia64/include/asm/unistd.h | 2 +- arch/ia64/kernel/entry.S | 2 +- arch/ia64/kernel/sys_ia64.c | 2 +- arch/s390/kernel/entry.h | 1 - arch/sh/include/asm/syscalls_32.h | 6 +++--- arch/sh/kernel/sys_sh32.c | 2 +- arch/sh/kernel/syscalls_32.S | 2 +- arch/sparc/kernel/entry.S | 4 ++-- arch/sparc/kernel/syscalls.S | 2 +- arch/sparc/kernel/systbls_32.S | 2 +- arch/sparc/kernel/systbls_64.S | 4 ++-- fs/pipe.c | 4 ++-- 15 files changed, 22 insertions(+), 23 deletions(-) diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index f77345bc66a..aa2e50cf985 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S @@ -896,9 +896,9 @@ sys_getxpid: .end sys_getxpid .align 4 - .globl sys_pipe - .ent sys_pipe -sys_pipe: + .globl sys_alpha_pipe + .ent sys_alpha_pipe +sys_alpha_pipe: lda $sp, -16($sp) stq $26, 0($sp) .prologue 0 @@ -916,7 +916,7 @@ sys_pipe: stq $1, 80+16($sp) 1: lda $sp, 16($sp) ret -.end sys_pipe +.end sys_alpha_pipe .align 4 .globl sys_execve diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S index ba914af18c4..9d9e3a98bb9 100644 --- a/arch/alpha/kernel/systbls.S +++ b/arch/alpha/kernel/systbls.S @@ -52,7 +52,7 @@ sys_call_table: .quad sys_setpgid .quad alpha_ni_syscall /* 40 */ .quad sys_dup - .quad sys_pipe + .quad sys_alpha_pipe .quad osf_set_program_attributes .quad alpha_ni_syscall .quad sys_open /* 45 */ diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S index a8cf1995885..a46f8395e9a 100644 --- a/arch/ia64/ia32/ia32_entry.S +++ b/arch/ia64/ia32/ia32_entry.S @@ -220,7 +220,7 @@ ia32_syscall_table: data8 sys_mkdir data8 sys_rmdir /* 40 */ data8 sys_dup - data8 sys_pipe + data8 sys_ia64_pipe data8 compat_sys_times data8 sys_ni_syscall /* old prof syscall holder */ data8 sys32_brk /* 45 */ diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h index f791576355a..9015979ebe0 100644 --- a/arch/ia64/include/asm/unistd.h +++ b/arch/ia64/include/asm/unistd.h @@ -364,7 +364,7 @@ struct pt_regs; struct sigaction; long sys_execve(char __user *filename, char __user * __user *argv, char __user * __user *envp, struct pt_regs *regs); -asmlinkage long sys_pipe(void); +asmlinkage long sys_ia64_pipe(void); asmlinkage long sys_rt_sigaction(int sig, const struct sigaction __user *act, struct sigaction __user *oact, diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index d435f4a7a96..e5341e2c117 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -1442,7 +1442,7 @@ sys_call_table: data8 sys_mkdir // 1055 data8 sys_rmdir data8 sys_dup - data8 sys_pipe + data8 sys_ia64_pipe data8 sys_times data8 ia64_brk // 1060 data8 sys_setgid diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c index bcbb6d8792d..92ed83f3403 100644 --- a/arch/ia64/kernel/sys_ia64.c +++ b/arch/ia64/kernel/sys_ia64.c @@ -154,7 +154,7 @@ out: * and r9) as this is faster than doing a copy_to_user(). */ asmlinkage long -sys_pipe (void) +sys_ia64_pipe (void) { struct pt_regs *regs = task_pt_regs(current); int fd[2]; diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h index a65afc91e8a..5c9b5b37004 100644 --- a/arch/s390/kernel/entry.h +++ b/arch/s390/kernel/entry.h @@ -30,7 +30,6 @@ struct fadvise64_64_args; struct old_sigaction; struct sel_arg_struct; -long sys_pipe(unsigned long __user *fildes); long sys_mmap2(struct mmap_arg_struct __user *arg); long old_mmap(struct mmap_arg_struct __user *arg); long sys_ipc(uint call, int first, unsigned long second, diff --git a/arch/sh/include/asm/syscalls_32.h b/arch/sh/include/asm/syscalls_32.h index 104c5e68610..8b30200305c 100644 --- a/arch/sh/include/asm/syscalls_32.h +++ b/arch/sh/include/asm/syscalls_32.h @@ -36,9 +36,9 @@ asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5, asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, struct pt_regs __regs); -asmlinkage int sys_pipe(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs); +asmlinkage int sys_sh_pipe(unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7, + struct pt_regs __regs); asmlinkage ssize_t sys_pread_wrapper(unsigned int fd, char __user *buf, size_t count, long dummy, loff_t pos); asmlinkage ssize_t sys_pwrite_wrapper(unsigned int fd, const char __user *buf, diff --git a/arch/sh/kernel/sys_sh32.c b/arch/sh/kernel/sys_sh32.c index dbba1e1833d..63ba12836ea 100644 --- a/arch/sh/kernel/sys_sh32.c +++ b/arch/sh/kernel/sys_sh32.c @@ -22,7 +22,7 @@ * sys_pipe() is the normal C calling standard for creating * a pipe. It's not the way Unix traditionally does this, though. */ -asmlinkage int sys_pipe(unsigned long r4, unsigned long r5, +asmlinkage int sys_sh_pipe(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, struct pt_regs __regs) { diff --git a/arch/sh/kernel/syscalls_32.S b/arch/sh/kernel/syscalls_32.S index a87ce076cfa..e67c1733e1b 100644 --- a/arch/sh/kernel/syscalls_32.S +++ b/arch/sh/kernel/syscalls_32.S @@ -58,7 +58,7 @@ ENTRY(sys_call_table) .long sys_mkdir .long sys_rmdir /* 40 */ .long sys_dup - .long sys_pipe + .long sys_sh_pipe .long sys_times .long sys_ni_syscall /* old prof syscall holder */ .long sys_brk /* 45 */ diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index faf9ccd9ef5..f41ecc5ac0b 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -1088,8 +1088,8 @@ sunos_execv: ld [%sp + STACKFRAME_SZ + PT_I0], %o0 .align 4 - .globl sys_pipe -sys_pipe: + .globl sys_sparc_pipe +sys_sparc_pipe: mov %o7, %l5 add %sp, STACKFRAME_SZ, %o0 ! pt_regs *regs arg call sparc_pipe diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S index 7a6786a7136..87f5a3b8a25 100644 --- a/arch/sparc/kernel/syscalls.S +++ b/arch/sparc/kernel/syscalls.S @@ -20,7 +20,7 @@ execve_merge: add %sp, PTREGS_OFF, %o0 .align 32 -sys_pipe: +sys_sparc_pipe: ba,pt %xcc, sparc_pipe add %sp, PTREGS_OFF, %o0 sys_nis_syscall: diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index 8a434f51ba0..dccc95df0c7 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S @@ -24,7 +24,7 @@ sys_call_table: /*25*/ .long sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_pause /*30*/ .long sys_utime, sys_lchown, sys_fchown, sys_access, sys_nice /*35*/ .long sys_chown, sys_sync, sys_kill, sys_newstat, sys_sendfile -/*40*/ .long sys_newlstat, sys_dup, sys_pipe, sys_times, sys_getuid +/*40*/ .long sys_newlstat, sys_dup, sys_sparc_pipe, sys_times, sys_getuid /*45*/ .long sys_umount, sys_setgid16, sys_getgid16, sys_signal, sys_geteuid16 /*50*/ .long sys_getegid16, sys_acct, sys_nis_syscall, sys_getgid, sys_ioctl /*55*/ .long sys_reboot, sys_mmap2, sys_symlink, sys_readlink, sys_execve diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index 9fc78cf354b..e6007bb3704 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S @@ -26,7 +26,7 @@ sys_call_table32: /*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys_pause /*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice .word sys_chown, sys_sync, sys32_kill, compat_sys_newstat, sys32_sendfile -/*40*/ .word compat_sys_newlstat, sys_dup, sys_pipe, compat_sys_times, sys_getuid +/*40*/ .word compat_sys_newlstat, sys_dup, sys_sparc_pipe, compat_sys_times, sys_getuid .word sys32_umount, sys_setgid16, sys_getgid16, sys32_signal, sys_geteuid16 /*50*/ .word sys_getegid16, sys_acct, sys_nis_syscall, sys_getgid, compat_sys_ioctl .word sys32_reboot, sys32_mmap2, sys_symlink, sys32_readlink, sys32_execve @@ -100,7 +100,7 @@ sys_call_table: /*25*/ .word sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_nis_syscall /*30*/ .word sys_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice .word sys_nis_syscall, sys_sync, sys_kill, sys_newstat, sys_sendfile64 -/*40*/ .word sys_newlstat, sys_dup, sys_pipe, sys_times, sys_nis_syscall +/*40*/ .word sys_newlstat, sys_dup, sys_sparc_pipe, sys_times, sys_nis_syscall .word sys_umount, sys_setgid, sys_getgid, sys_signal, sys_geteuid /*50*/ .word sys_getegid, sys_acct, sys_memory_ordering, sys_nis_syscall, sys_ioctl .word sys_reboot, sys_nis_syscall, sys_symlink, sys_readlink, sys_execve diff --git a/fs/pipe.c b/fs/pipe.c index 891697112f6..0c64db86c91 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -1043,7 +1043,7 @@ int do_pipe(int *fd) * sys_pipe() is the normal C calling standard for creating * a pipe. It's not the way Unix traditionally does this, though. */ -asmlinkage long __weak sys_pipe2(int __user *fildes, int flags) +asmlinkage long sys_pipe2(int __user *fildes, int flags) { int fd[2]; int error; @@ -1059,7 +1059,7 @@ asmlinkage long __weak sys_pipe2(int __user *fildes, int flags) return error; } -asmlinkage long __weak sys_pipe(int __user *fildes) +asmlinkage long sys_pipe(int __user *fildes) { return sys_pipe2(fildes, 0); } -- cgit From c9da9f2129d6a421c32e334a83770a9e67f7feac Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:13:57 +0100 Subject: [CVE-2009-0029] Make sys_pselect7 static Not a single architecture has wired up sys_pselect7 plus it is the only system call with seven parameters. Just make it static and rename it to do_pselect which will do the work for sys_pselect6. Signed-off-by: Heiko Carstens --- fs/compat.c | 6 +++--- fs/select.c | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/fs/compat.c b/fs/compat.c index 30f2faa22f5..65a070e705a 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -1709,7 +1709,7 @@ asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp, } #ifdef HAVE_SET_RESTORE_SIGMASK -asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp, +static long do_compat_pselect(int n, compat_ulong_t __user *inp, compat_ulong_t __user *outp, compat_ulong_t __user *exp, struct compat_timespec __user *tsp, compat_sigset_t __user *sigmask, compat_size_t sigsetsize) @@ -1775,8 +1775,8 @@ asmlinkage long compat_sys_pselect6(int n, compat_ulong_t __user *inp, (compat_size_t __user *)(sig+sizeof(up)))) return -EFAULT; } - return compat_sys_pselect7(n, inp, outp, exp, tsp, compat_ptr(up), - sigsetsize); + return do_compat_pselect(n, inp, outp, exp, tsp, compat_ptr(up), + sigsetsize); } asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds, diff --git a/fs/select.c b/fs/select.c index b0cf1f0896d..d1651648be1 100644 --- a/fs/select.c +++ b/fs/select.c @@ -582,9 +582,9 @@ asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp, } #ifdef HAVE_SET_RESTORE_SIGMASK -asmlinkage long sys_pselect7(int n, fd_set __user *inp, fd_set __user *outp, - fd_set __user *exp, struct timespec __user *tsp, - const sigset_t __user *sigmask, size_t sigsetsize) +static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp, + fd_set __user *exp, struct timespec __user *tsp, + const sigset_t __user *sigmask, size_t sigsetsize) { sigset_t ksigmask, sigsaved; struct timespec ts, end_time, *to = NULL; @@ -650,7 +650,7 @@ asmlinkage long sys_pselect6(int n, fd_set __user *inp, fd_set __user *outp, return -EFAULT; } - return sys_pselect7(n, inp, outp, exp, tsp, up, sigsetsize); + return do_pselect(n, inp, outp, exp, tsp, up, sigsetsize); } #endif /* HAVE_SET_RESTORE_SIGMASK */ -- cgit From f627a741d24f12955fa2d9f8831c3b12860635bd Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:13:58 +0100 Subject: [CVE-2009-0029] Make sys_syslog a conditional system call Remove the -ENOSYS implementation for !CONFIG_PRINTK and use the cond_syscall infrastructure instead. Acked-by: Kyle McMartin Signed-off-by: Heiko Carstens --- kernel/printk.c | 5 ----- kernel/sys_ni.c | 1 + 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/kernel/printk.c b/kernel/printk.c index 7015733793e..e48cf33783f 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -742,11 +742,6 @@ EXPORT_SYMBOL(vprintk); #else -asmlinkage long sys_syslog(int type, char __user *buf, int len) -{ - return -ENOSYS; -} - static void call_console_drivers(unsigned start, unsigned end) { } diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index e14a2328170..27dad296738 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c @@ -131,6 +131,7 @@ cond_syscall(sys_io_destroy); cond_syscall(sys_io_submit); cond_syscall(sys_io_cancel); cond_syscall(sys_io_getevents); +cond_syscall(sys_syslog); /* arch-specific weak syscall entries */ cond_syscall(sys_pciconfig_read); -- cgit From 1a94bc34768e463a93cb3751819709ab0ea80a01 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:13:59 +0100 Subject: [CVE-2009-0029] System call wrapper infrastructure From: Martin Schwidefsky By selecting HAVE_SYSCALL_WRAPPERS architectures can activate system call wrappers in order to sign extend system call arguments. All architectures where the ABI defines that the caller of a function has to perform sign extension probably need this. Reported-by: Christian Borntraeger Acked-by: Ralf Baechle Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- arch/Kconfig | 3 +++ include/linux/syscalls.h | 62 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/arch/Kconfig b/arch/Kconfig index 2e13aa26192..550dab22daa 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -62,6 +62,9 @@ config HAVE_EFFICIENT_UNALIGNED_ACCESS See Documentation/unaligned-memory-access.txt for more information on the topic of unaligned memory accesses. +config HAVE_SYSCALL_WRAPPERS + bool + config KRETPROBES def_bool y depends on KPROBES && HAVE_KRETPROBES diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index ca079c3d09e..0bb537d7ba2 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -66,6 +66,68 @@ struct old_linux_dirent; #include #include +#define __SC_DECL1(t1, a1) t1 a1 +#define __SC_DECL2(t2, a2, ...) t2 a2, __SC_DECL1(__VA_ARGS__) +#define __SC_DECL3(t3, a3, ...) t3 a3, __SC_DECL2(__VA_ARGS__) +#define __SC_DECL4(t4, a4, ...) t4 a4, __SC_DECL3(__VA_ARGS__) +#define __SC_DECL5(t5, a5, ...) t5 a5, __SC_DECL4(__VA_ARGS__) +#define __SC_DECL6(t6, a6, ...) t6 a6, __SC_DECL5(__VA_ARGS__) + +#define __SC_LONG1(t1, a1) long a1 +#define __SC_LONG2(t2, a2, ...) long a2, __SC_LONG1(__VA_ARGS__) +#define __SC_LONG3(t3, a3, ...) long a3, __SC_LONG2(__VA_ARGS__) +#define __SC_LONG4(t4, a4, ...) long a4, __SC_LONG3(__VA_ARGS__) +#define __SC_LONG5(t5, a5, ...) long a5, __SC_LONG4(__VA_ARGS__) +#define __SC_LONG6(t6, a6, ...) long a6, __SC_LONG5(__VA_ARGS__) + +#define __SC_CAST1(t1, a1) (t1) a1 +#define __SC_CAST2(t2, a2, ...) (t2) a2, __SC_CAST1(__VA_ARGS__) +#define __SC_CAST3(t3, a3, ...) (t3) a3, __SC_CAST2(__VA_ARGS__) +#define __SC_CAST4(t4, a4, ...) (t4) a4, __SC_CAST3(__VA_ARGS__) +#define __SC_CAST5(t5, a5, ...) (t5) a5, __SC_CAST4(__VA_ARGS__) +#define __SC_CAST6(t6, a6, ...) (t6) a6, __SC_CAST5(__VA_ARGS__) + +#define __SC_TEST(type) BUILD_BUG_ON(sizeof(type) > sizeof(long)) +#define __SC_TEST1(t1, a1) __SC_TEST(t1) +#define __SC_TEST2(t2, a2, ...) __SC_TEST(t2); __SC_TEST1(__VA_ARGS__) +#define __SC_TEST3(t3, a3, ...) __SC_TEST(t3); __SC_TEST2(__VA_ARGS__) +#define __SC_TEST4(t4, a4, ...) __SC_TEST(t4); __SC_TEST3(__VA_ARGS__) +#define __SC_TEST5(t5, a5, ...) __SC_TEST(t5); __SC_TEST4(__VA_ARGS__) +#define __SC_TEST6(t6, a6, ...) __SC_TEST(t6); __SC_TEST5(__VA_ARGS__) + +#define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void) +#define SYSCALL_DEFINE1(...) SYSCALL_DEFINEx(1, __VA_ARGS__) +#define SYSCALL_DEFINE2(...) SYSCALL_DEFINEx(2, __VA_ARGS__) +#define SYSCALL_DEFINE3(...) SYSCALL_DEFINEx(3, __VA_ARGS__) +#define SYSCALL_DEFINE4(...) SYSCALL_DEFINEx(4, __VA_ARGS__) +#define SYSCALL_DEFINE5(...) SYSCALL_DEFINEx(5, __VA_ARGS__) +#define SYSCALL_DEFINE6(...) SYSCALL_DEFINEx(6, __VA_ARGS__) + +#define SYSCALL_ALIAS(alias, name) \ + asm ("\t.globl " #alias "\n\t.set " #alias ", " #name) + +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS + +#define SYSCALL_DEFINE(name) static inline long SYSC_##name +#define SYSCALL_DEFINEx(x, name, ...) \ + asmlinkage long sys_##name(__SC_DECL##x(__VA_ARGS__)); \ + static inline long SYSC_##name(__SC_DECL##x(__VA_ARGS__)); \ + asmlinkage long SyS_##name(__SC_LONG##x(__VA_ARGS__)) \ + { \ + __SC_TEST##x(__VA_ARGS__); \ + return (long) SYSC_##name(__SC_CAST##x(__VA_ARGS__)); \ + } \ + SYSCALL_ALIAS(sys_##name, SyS_##name); \ + static inline long SYSC_##name(__SC_DECL##x(__VA_ARGS__)) + +#else /* CONFIG_HAVE_SYSCALL_WRAPPERS */ + +#define SYSCALL_DEFINE(name) asmlinkage long sys_##name +#define SYSCALL_DEFINEx(x, name, ...) \ + asmlinkage long sys_##name(__SC_DECL##x(__VA_ARGS__)) + +#endif /* CONFIG_HAVE_SYSCALL_WRAPPERS */ + asmlinkage long sys_time(time_t __user *tloc); asmlinkage long sys_stime(time_t __user *tptr); asmlinkage long sys_gettimeofday(struct timeval __user *tv, -- cgit From ee6a093222549ac0c72cfd296c69fa5e7d6daa34 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 14 Jan 2009 14:14:00 +0100 Subject: [CVE-2009-0029] powerpc: Enable syscall wrappers for 64-bit This enables the use of syscall wrappers to do proper sign extension for 64-bit programs. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Heiko Carstens --- arch/powerpc/Kconfig | 1 + include/linux/syscalls.h | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 84b861316ce..e39b73bc0ff 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -123,6 +123,7 @@ config PPC select HAVE_DMA_ATTRS if PPC64 select USE_GENERIC_SMP_HELPERS if SMP select HAVE_OPROFILE + select HAVE_SYSCALL_WRAPPERS if PPC64 config EARLY_PRINTK bool diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 0bb537d7ba2..90aa5eba87a 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -103,8 +103,14 @@ struct old_linux_dirent; #define SYSCALL_DEFINE5(...) SYSCALL_DEFINEx(5, __VA_ARGS__) #define SYSCALL_DEFINE6(...) SYSCALL_DEFINEx(6, __VA_ARGS__) +#ifdef CONFIG_PPC64 +#define SYSCALL_ALIAS(alias, name) \ + asm ("\t.globl " #alias "\n\t.set " #alias ", " #name "\n" \ + "\t.globl ." #alias "\n\t.set ." #alias ", ." #name) +#else #define SYSCALL_ALIAS(alias, name) \ asm ("\t.globl " #alias "\n\t.set " #alias ", " #name) +#endif #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS -- cgit From ed6bb6194350dc6ae97a65dbf2d621a3dbe6bbe9 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:01 +0100 Subject: [CVE-2009-0029] s390: enable system call wrappers Signed-off-by: Heiko Carstens --- arch/s390/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index a94a3c3ae93..6b0a3538dc6 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -77,6 +77,7 @@ mainmenu "Linux Kernel Configuration" config S390 def_bool y select USE_GENERIC_SMP_HELPERS if SMP + select HAVE_SYSCALL_WRAPPERS select HAVE_FUNCTION_TRACER select HAVE_OPROFILE select HAVE_KPROBES -- cgit From 6673e0c3fbeaed2cd08e2fd4a4aa97382d6fedb0 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:02 +0100 Subject: [CVE-2009-0029] System call wrapper special cases System calls with an unsigned long long argument can't be converted with the standard wrappers since that would include a cast to long, which in turn means that we would lose the upper 32 bit on 32 bit architectures. Also semctl can't use the standard wrapper since it has a 'union' parameter. So we handle them as special case and add some extra wrappers instead. Signed-off-by: Heiko Carstens --- fs/dcookies.c | 10 ++++++++-- fs/open.c | 27 ++++++++++++++++++++++++--- fs/read_write.c | 24 ++++++++++++++++++++---- fs/sync.c | 26 ++++++++++++++++++++++---- ipc/sem.c | 9 ++++++++- mm/fadvise.c | 18 ++++++++++++++++-- mm/filemap.c | 9 ++++++++- 7 files changed, 106 insertions(+), 17 deletions(-) diff --git a/fs/dcookies.c b/fs/dcookies.c index 180e9fec4ad..a21cabdbd87 100644 --- a/fs/dcookies.c +++ b/fs/dcookies.c @@ -145,7 +145,7 @@ out: /* And here is where the userspace process can look up the cookie value * to retrieve the path. */ -asmlinkage long sys_lookup_dcookie(u64 cookie64, char __user * buf, size_t len) +SYSCALL_DEFINE(lookup_dcookie)(u64 cookie64, char __user * buf, size_t len) { unsigned long cookie = (unsigned long)cookie64; int err = -EINVAL; @@ -198,7 +198,13 @@ out: mutex_unlock(&dcookie_mutex); return err; } - +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_lookup_dcookie(u64 cookie64, long buf, long len) +{ + return SYSC_lookup_dcookie(cookie64, (char __user *) buf, (size_t) len); +} +SYSCALL_ALIAS(sys_lookup_dcookie, SyS_lookup_dcookie); +#endif static int dcookie_init(void) { diff --git a/fs/open.c b/fs/open.c index d882fd2351d..e349013fc79 100644 --- a/fs/open.c +++ b/fs/open.c @@ -351,21 +351,35 @@ asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length) /* LFS versions of truncate are only needed on 32 bit machines */ #if BITS_PER_LONG == 32 -asmlinkage long sys_truncate64(const char __user * path, loff_t length) +SYSCALL_DEFINE(truncate64)(const char __user * path, loff_t length) { return do_sys_truncate(path, length); } +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_truncate64(long path, loff_t length) +{ + return SYSC_truncate64((const char __user *) path, length); +} +SYSCALL_ALIAS(sys_truncate64, SyS_truncate64); +#endif -asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length) +SYSCALL_DEFINE(ftruncate64)(unsigned int fd, loff_t length) { long ret = do_sys_ftruncate(fd, length, 0); /* avoid REGPARM breakage on x86: */ asmlinkage_protect(2, ret, fd, length); return ret; } +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_ftruncate64(long fd, loff_t length) +{ + return SYSC_ftruncate64((unsigned int) fd, length); +} +SYSCALL_ALIAS(sys_ftruncate64, SyS_ftruncate64); #endif +#endif /* BITS_PER_LONG == 32 */ -asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len) +SYSCALL_DEFINE(fallocate)(int fd, int mode, loff_t offset, loff_t len) { struct file *file; struct inode *inode; @@ -422,6 +436,13 @@ out_fput: out: return ret; } +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_fallocate(long fd, long mode, loff_t offset, loff_t len) +{ + return SYSC_fallocate((int)fd, (int)mode, offset, len); +} +SYSCALL_ALIAS(sys_fallocate, SyS_fallocate); +#endif /* * access() needs to use the real uid/gid, not the effective uid/gid. diff --git a/fs/read_write.c b/fs/read_write.c index 940367f51f2..7a8326bc590 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -403,8 +403,8 @@ asmlinkage long sys_write(unsigned int fd, const char __user * buf, size_t count return ret; } -asmlinkage long sys_pread64(unsigned int fd, char __user *buf, - size_t count, loff_t pos) +SYSCALL_DEFINE(pread64)(unsigned int fd, char __user *buf, + size_t count, loff_t pos) { struct file *file; ssize_t ret = -EBADF; @@ -423,9 +423,17 @@ asmlinkage long sys_pread64(unsigned int fd, char __user *buf, return ret; } +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_pread64(long fd, long buf, long count, loff_t pos) +{ + return SYSC_pread64((unsigned int) fd, (char __user *) buf, + (size_t) count, pos); +} +SYSCALL_ALIAS(sys_pread64, SyS_pread64); +#endif -asmlinkage long sys_pwrite64(unsigned int fd, const char __user *buf, - size_t count, loff_t pos) +SYSCALL_DEFINE(pwrite64)(unsigned int fd, const char __user *buf, + size_t count, loff_t pos) { struct file *file; ssize_t ret = -EBADF; @@ -444,6 +452,14 @@ asmlinkage long sys_pwrite64(unsigned int fd, const char __user *buf, return ret; } +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_pwrite64(long fd, long buf, long count, loff_t pos) +{ + return SYSC_pwrite64((unsigned int) fd, (const char __user *) buf, + (size_t) count, pos); +} +SYSCALL_ALIAS(sys_pwrite64, SyS_pwrite64); +#endif /* * Reduce an iovec's length in-place. Return the resulting number of segments diff --git a/fs/sync.c b/fs/sync.c index ac02b56548b..23ebbd72ecc 100644 --- a/fs/sync.c +++ b/fs/sync.c @@ -201,8 +201,8 @@ asmlinkage long sys_fdatasync(unsigned int fd) * already-instantiated disk blocks, there are no guarantees here that the data * will be available after a crash. */ -asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, - unsigned int flags) +SYSCALL_DEFINE(sync_file_range)(int fd, loff_t offset, loff_t nbytes, + unsigned int flags) { int ret; struct file *file; @@ -262,14 +262,32 @@ out_put: out: return ret; } +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_sync_file_range(long fd, loff_t offset, loff_t nbytes, + long flags) +{ + return SYSC_sync_file_range((int) fd, offset, nbytes, + (unsigned int) flags); +} +SYSCALL_ALIAS(sys_sync_file_range, SyS_sync_file_range); +#endif /* It would be nice if people remember that not all the world's an i386 when they introduce new system calls */ -asmlinkage long sys_sync_file_range2(int fd, unsigned int flags, - loff_t offset, loff_t nbytes) +SYSCALL_DEFINE(sync_file_range2)(int fd, unsigned int flags, + loff_t offset, loff_t nbytes) { return sys_sync_file_range(fd, offset, nbytes, flags); } +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_sync_file_range2(long fd, long flags, + loff_t offset, loff_t nbytes) +{ + return SYSC_sync_file_range2((int) fd, (unsigned int) flags, + offset, nbytes); +} +SYSCALL_ALIAS(sys_sync_file_range2, SyS_sync_file_range2); +#endif /* * `endbyte' is inclusive diff --git a/ipc/sem.c b/ipc/sem.c index c68cd3f8f0c..c385c40c061 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -887,7 +887,7 @@ out_up: return err; } -asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg) +SYSCALL_DEFINE(semctl)(int semid, int semnum, int cmd, union semun arg) { int err = -EINVAL; int version; @@ -923,6 +923,13 @@ asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg) return -EINVAL; } } +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_semctl(int semid, int semnum, int cmd, union semun arg) +{ + return SYSC_semctl((int) semid, (int) semnum, (int) cmd, arg); +} +SYSCALL_ALIAS(sys_semctl, SyS_semctl); +#endif /* If the task doesn't already have a undo_list, then allocate one * here. We guarantee there is only one thread using this undo list, diff --git a/mm/fadvise.c b/mm/fadvise.c index a1da969bd98..54a0f8040af 100644 --- a/mm/fadvise.c +++ b/mm/fadvise.c @@ -24,7 +24,7 @@ * POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could * deactivate the pages and clear PG_Referenced. */ -asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice) +SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice) { struct file *file = fget(fd); struct address_space *mapping; @@ -126,12 +126,26 @@ out: fput(file); return ret; } +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_fadvise64_64(long fd, loff_t offset, loff_t len, long advice) +{ + return SYSC_fadvise64_64((int) fd, offset, len, (int) advice); +} +SYSCALL_ALIAS(sys_fadvise64_64, SyS_fadvise64_64); +#endif #ifdef __ARCH_WANT_SYS_FADVISE64 -asmlinkage long sys_fadvise64(int fd, loff_t offset, size_t len, int advice) +SYSCALL_DEFINE(fadvise64)(int fd, loff_t offset, size_t len, int advice) { return sys_fadvise64_64(fd, offset, len, advice); } +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_fadvise64(long fd, loff_t offset, long len, long advice) +{ + return SYSC_fadvise64((int) fd, offset, (size_t)len, (int)advice); +} +SYSCALL_ALIAS(sys_fadvise64, SyS_fadvise64); +#endif #endif diff --git a/mm/filemap.c b/mm/filemap.c index 538b75ed623..23acefe5180 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1374,7 +1374,7 @@ do_readahead(struct address_space *mapping, struct file *filp, return 0; } -asmlinkage long sys_readahead(int fd, loff_t offset, size_t count) +SYSCALL_DEFINE(readahead)(int fd, loff_t offset, size_t count) { ssize_t ret; struct file *file; @@ -1393,6 +1393,13 @@ asmlinkage long sys_readahead(int fd, loff_t offset, size_t count) } return ret; } +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_readahead(long fd, loff_t offset, long count) +{ + return SYSC_readahead((int) fd, offset, (size_t) count); +} +SYSCALL_ALIAS(sys_readahead, SyS_readahead); +#endif #ifdef CONFIG_MMU /** -- cgit From 58fd3aa288939d3097fa04505b25c2f5e6e144d1 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:03 +0100 Subject: [CVE-2009-0029] System call wrappers part 01 Signed-off-by: Heiko Carstens --- kernel/hrtimer.c | 4 ++-- kernel/sys.c | 2 +- kernel/time.c | 14 +++++++------- kernel/timer.c | 6 +++--- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 1455b7651b6..2dc30c59c5f 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -1467,8 +1467,8 @@ out: return ret; } -asmlinkage long -sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp) +SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp, + struct timespec __user *, rmtp) { struct timespec tu; diff --git a/kernel/sys.c b/kernel/sys.c index 763c3c17ded..37165e55233 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -919,7 +919,7 @@ void do_sys_times(struct tms *tms) tms->tms_cstime = cputime_to_clock_t(cstime); } -asmlinkage long sys_times(struct tms __user * tbuf) +SYSCALL_DEFINE1(times, struct tms __user *, tbuf) { if (tbuf) { struct tms tmp; diff --git a/kernel/time.c b/kernel/time.c index 4886e3ce83a..29511943871 100644 --- a/kernel/time.c +++ b/kernel/time.c @@ -60,7 +60,7 @@ EXPORT_SYMBOL(sys_tz); * why not move it into the appropriate arch directory (for those * architectures that need it). */ -asmlinkage long sys_time(time_t __user * tloc) +SYSCALL_DEFINE1(time, time_t __user *, tloc) { time_t i = get_seconds(); @@ -79,7 +79,7 @@ asmlinkage long sys_time(time_t __user * tloc) * architectures that need it). */ -asmlinkage long sys_stime(time_t __user *tptr) +SYSCALL_DEFINE1(stime, time_t __user *, tptr) { struct timespec tv; int err; @@ -99,8 +99,8 @@ asmlinkage long sys_stime(time_t __user *tptr) #endif /* __ARCH_WANT_SYS_TIME */ -asmlinkage long sys_gettimeofday(struct timeval __user *tv, - struct timezone __user *tz) +SYSCALL_DEFINE2(gettimeofday, struct timeval __user *, tv, + struct timezone __user *, tz) { if (likely(tv != NULL)) { struct timeval ktv; @@ -184,8 +184,8 @@ int do_sys_settimeofday(struct timespec *tv, struct timezone *tz) return 0; } -asmlinkage long sys_settimeofday(struct timeval __user *tv, - struct timezone __user *tz) +SYSCALL_DEFINE2(settimeofday, struct timeval __user *, tv, + struct timezone __user *, tz) { struct timeval user_tv; struct timespec new_ts; @@ -205,7 +205,7 @@ asmlinkage long sys_settimeofday(struct timeval __user *tv, return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL); } -asmlinkage long sys_adjtimex(struct timex __user *txc_p) +SYSCALL_DEFINE1(adjtimex, struct timex __user *, txc_p) { struct timex txc; /* Local copy of parameter */ int ret; diff --git a/kernel/timer.c b/kernel/timer.c index 7b8697d7f04..76041df06c5 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -1129,7 +1129,7 @@ void do_timer(unsigned long ticks) * For backwards compatibility? This can be done in libc so Alpha * and all newer ports shouldn't need it. */ -asmlinkage long sys_alarm(unsigned int seconds) +SYSCALL_DEFINE1(alarm, unsigned int, seconds) { return alarm_setitimer(seconds); } @@ -1152,7 +1152,7 @@ asmlinkage long sys_alarm(unsigned int seconds) * * This is SMP safe as current->tgid does not change. */ -asmlinkage long sys_getpid(void) +SYSCALL_DEFINE0(getpid) { return task_tgid_vnr(current); } @@ -1308,7 +1308,7 @@ signed long __sched schedule_timeout_uninterruptible(signed long timeout) EXPORT_SYMBOL(schedule_timeout_uninterruptible); /* Thread ID - the internal kernel "pid" */ -asmlinkage long sys_gettid(void) +SYSCALL_DEFINE0(gettid) { return task_pid_vnr(current); } -- cgit From dbf040d9d1cbf1ef6250bdb095c5c118950bcde8 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:04 +0100 Subject: [CVE-2009-0029] System call wrappers part 02 Signed-off-by: Heiko Carstens --- kernel/sys.c | 10 +++++----- kernel/timer.c | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/kernel/sys.c b/kernel/sys.c index 37165e55233..4c33555f8d9 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -756,7 +756,7 @@ error: return retval; } -asmlinkage long sys_getresuid(uid_t __user *ruid, uid_t __user *euid, uid_t __user *suid) +SYSCALL_DEFINE3(getresuid, uid_t __user *, ruid, uid_t __user *, euid, uid_t __user *, suid) { const struct cred *cred = current_cred(); int retval; @@ -814,7 +814,7 @@ error: return retval; } -asmlinkage long sys_getresgid(gid_t __user *rgid, gid_t __user *egid, gid_t __user *sgid) +SYSCALL_DEFINE3(getresgid, gid_t __user *, rgid, gid_t __user *, egid, gid_t __user *, sgid) { const struct cred *cred = current_cred(); int retval; @@ -1015,7 +1015,7 @@ out: return err; } -asmlinkage long sys_getpgid(pid_t pid) +SYSCALL_DEFINE1(getpgid, pid_t, pid) { struct task_struct *p; struct pid *grp; @@ -1045,14 +1045,14 @@ out: #ifdef __ARCH_WANT_SYS_GETPGRP -asmlinkage long sys_getpgrp(void) +SYSCALL_DEFINE0(getpgrp) { return sys_getpgid(0); } #endif -asmlinkage long sys_getsid(pid_t pid) +SYSCALL_DEFINE1(getsid, pid_t, pid) { struct task_struct *p; struct pid *sid; diff --git a/kernel/timer.c b/kernel/timer.c index 76041df06c5..14a51530a4c 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -1163,7 +1163,7 @@ SYSCALL_DEFINE0(getpid) * value of ->real_parent under rcu_read_lock(), see * release_task()->call_rcu(delayed_put_task_struct). */ -asmlinkage long sys_getppid(void) +SYSCALL_DEFINE0(getppid) { int pid; @@ -1174,25 +1174,25 @@ asmlinkage long sys_getppid(void) return pid; } -asmlinkage long sys_getuid(void) +SYSCALL_DEFINE0(getuid) { /* Only we change this so SMP safe */ return current_uid(); } -asmlinkage long sys_geteuid(void) +SYSCALL_DEFINE0(geteuid) { /* Only we change this so SMP safe */ return current_euid(); } -asmlinkage long sys_getgid(void) +SYSCALL_DEFINE0(getgid) { /* Only we change this so SMP safe */ return current_gid(); } -asmlinkage long sys_getegid(void) +SYSCALL_DEFINE0(getegid) { /* Only we change this so SMP safe */ return current_egid(); -- cgit From ae1251ab785f6da87219df8352ffdac68bba23e4 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:05 +0100 Subject: [CVE-2009-0029] System call wrappers part 03 Signed-off-by: Heiko Carstens --- kernel/sys.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/kernel/sys.c b/kernel/sys.c index 4c33555f8d9..ace9ced598b 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -478,7 +478,7 @@ void ctrl_alt_del(void) * SMP: There are not races, the GIDs are checked only by filesystem * operations (as far as semantic preservation is concerned). */ -asmlinkage long sys_setregid(gid_t rgid, gid_t egid) +SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid) { const struct cred *old; struct cred *new; @@ -529,7 +529,7 @@ error: * * SMP: Same implicit races as above. */ -asmlinkage long sys_setgid(gid_t gid) +SYSCALL_DEFINE1(setgid, gid_t, gid) { const struct cred *old; struct cred *new; @@ -597,7 +597,7 @@ static int set_user(struct cred *new) * 100% compatible with BSD. A program which uses just setuid() will be * 100% compatible with POSIX with saved IDs. */ -asmlinkage long sys_setreuid(uid_t ruid, uid_t euid) +SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid) { const struct cred *old; struct cred *new; @@ -661,7 +661,7 @@ error: * will allow a root program to temporarily drop privileges and be able to * regain them by swapping the real and effective uid. */ -asmlinkage long sys_setuid(uid_t uid) +SYSCALL_DEFINE1(setuid, uid_t, uid) { const struct cred *old; struct cred *new; @@ -705,7 +705,7 @@ error: * This function implements a generic ability to update ruid, euid, * and suid. This allows you to implement the 4.4 compatible seteuid(). */ -asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid) +SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid) { const struct cred *old; struct cred *new; @@ -771,7 +771,7 @@ SYSCALL_DEFINE3(getresuid, uid_t __user *, ruid, uid_t __user *, euid, uid_t __u /* * Same as above, but for rgid, egid, sgid. */ -asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid) +SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid) { const struct cred *old; struct cred *new; @@ -833,7 +833,7 @@ SYSCALL_DEFINE3(getresgid, gid_t __user *, rgid, gid_t __user *, egid, gid_t __u * whatever uid it wants to). It normally shadows "euid", except when * explicitly set by setfsuid() or for access.. */ -asmlinkage long sys_setfsuid(uid_t uid) +SYSCALL_DEFINE1(setfsuid, uid_t, uid) { const struct cred *old; struct cred *new; @@ -870,7 +870,7 @@ change_okay: /* * Samma på svenska.. */ -asmlinkage long sys_setfsgid(gid_t gid) +SYSCALL_DEFINE1(setfsgid, gid_t, gid) { const struct cred *old; struct cred *new; @@ -1311,7 +1311,7 @@ int set_current_groups(struct group_info *group_info) EXPORT_SYMBOL(set_current_groups); -asmlinkage long sys_getgroups(int gidsetsize, gid_t __user *grouplist) +SYSCALL_DEFINE2(getgroups, int, gidsetsize, gid_t __user *, grouplist) { const struct cred *cred = current_cred(); int i; -- cgit From b290ebe2c46d01b742b948ce03f09e8a3efb9a92 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:06 +0100 Subject: [CVE-2009-0029] System call wrappers part 04 Signed-off-by: Heiko Carstens --- kernel/acct.c | 2 +- kernel/capability.c | 4 ++-- kernel/exec_domain.c | 3 +-- kernel/itimer.c | 2 +- kernel/signal.c | 7 +++---- kernel/sys.c | 6 +++--- 6 files changed, 11 insertions(+), 13 deletions(-) diff --git a/kernel/acct.c b/kernel/acct.c index d57b7cbb98b..7afa3156416 100644 --- a/kernel/acct.c +++ b/kernel/acct.c @@ -277,7 +277,7 @@ static int acct_on(char *name) * should be written. If the filename is NULL, accounting will be * shutdown. */ -asmlinkage long sys_acct(const char __user *name) +SYSCALL_DEFINE1(acct, const char __user *, name) { int error; diff --git a/kernel/capability.c b/kernel/capability.c index 688926e496b..4e17041963f 100644 --- a/kernel/capability.c +++ b/kernel/capability.c @@ -161,7 +161,7 @@ static inline int cap_get_target_pid(pid_t pid, kernel_cap_t *pEp, * * Returns 0 on success and < 0 on error. */ -asmlinkage long sys_capget(cap_user_header_t header, cap_user_data_t dataptr) +SYSCALL_DEFINE2(capget, cap_user_header_t, header, cap_user_data_t, dataptr) { int ret = 0; pid_t pid; @@ -235,7 +235,7 @@ asmlinkage long sys_capget(cap_user_header_t header, cap_user_data_t dataptr) * * Returns 0 on success and < 0 on error. */ -asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data) +SYSCALL_DEFINE2(capset, cap_user_header_t, header, const cap_user_data_t, data) { struct __user_cap_data_struct kdata[_KERNEL_CAPABILITY_U32S]; unsigned i, tocopy; diff --git a/kernel/exec_domain.c b/kernel/exec_domain.c index 0511716e942..667c841c295 100644 --- a/kernel/exec_domain.c +++ b/kernel/exec_domain.c @@ -209,8 +209,7 @@ static int __init proc_execdomains_init(void) module_init(proc_execdomains_init); #endif -asmlinkage long -sys_personality(u_long personality) +SYSCALL_DEFINE1(personality, u_long, personality) { u_long old = current->personality; diff --git a/kernel/itimer.c b/kernel/itimer.c index db7c358b9a0..7e0663ea94f 100644 --- a/kernel/itimer.c +++ b/kernel/itimer.c @@ -100,7 +100,7 @@ int do_getitimer(int which, struct itimerval *value) return 0; } -asmlinkage long sys_getitimer(int which, struct itimerval __user *value) +SYSCALL_DEFINE2(getitimer, int, which, struct itimerval __user *, value) { int error = -EFAULT; struct itimerval get_buffer; diff --git a/kernel/signal.c b/kernel/signal.c index 856a5479d49..3fe08eaa5de 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2434,8 +2434,7 @@ out: #ifdef __ARCH_WANT_SYS_SIGPENDING -asmlinkage long -sys_sigpending(old_sigset_t __user *set) +SYSCALL_DEFINE1(sigpending, old_sigset_t __user *, set) { return do_sigpending(set, sizeof(*set)); } @@ -2446,8 +2445,8 @@ sys_sigpending(old_sigset_t __user *set) /* Some platforms have their own version with special arguments others support only sys_rt_sigprocmask. */ -asmlinkage long -sys_sigprocmask(int how, old_sigset_t __user *set, old_sigset_t __user *oset) +SYSCALL_DEFINE3(sigprocmask, int, how, old_sigset_t __user *, set, + old_sigset_t __user *, oset) { int error; old_sigset_t old_set, new_set; diff --git a/kernel/sys.c b/kernel/sys.c index ace9ced598b..cbe4502c28a 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -944,7 +944,7 @@ SYSCALL_DEFINE1(times, struct tms __user *, tbuf) * Auch. Had to add the 'did_exec' flag to conform completely to POSIX. * LBT 04.03.94 */ -asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) +SYSCALL_DEFINE2(setpgid, pid_t, pid, pid_t, pgid) { struct task_struct *p; struct task_struct *group_leader = current->group_leader; @@ -1080,7 +1080,7 @@ out: return retval; } -asmlinkage long sys_setsid(void) +SYSCALL_DEFINE0(setsid) { struct task_struct *group_leader = current->group_leader; struct pid *sid = task_pid(group_leader); @@ -1340,7 +1340,7 @@ out: * without another task interfering. */ -asmlinkage long sys_setgroups(int gidsetsize, gid_t __user *grouplist) +SYSCALL_DEFINE2(setgroups, int, gidsetsize, gid_t __user *, grouplist) { struct group_info *group_info; int retval; -- cgit From 362e9c07c7220c0a78c88826fc0d2bf7e4a4bb68 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:07 +0100 Subject: [CVE-2009-0029] System call wrappers part 05 Signed-off-by: Heiko Carstens --- kernel/itimer.c | 5 ++--- kernel/posix-timers.c | 43 +++++++++++++++++++------------------------ 2 files changed, 21 insertions(+), 27 deletions(-) diff --git a/kernel/itimer.c b/kernel/itimer.c index 7e0663ea94f..6a5fe93dd8b 100644 --- a/kernel/itimer.c +++ b/kernel/itimer.c @@ -260,9 +260,8 @@ unsigned int alarm_setitimer(unsigned int seconds) return it_old.it_value.tv_sec; } -asmlinkage long sys_setitimer(int which, - struct itimerval __user *value, - struct itimerval __user *ovalue) +SYSCALL_DEFINE3(setitimer, int, which, struct itimerval __user *, value, + struct itimerval __user *, ovalue) { struct itimerval set_buffer, get_buffer; int error; diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index 887c63787de..052ec4d195c 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c @@ -477,10 +477,9 @@ static void release_posix_timer(struct k_itimer *tmr, int it_id_set) /* Create a POSIX.1b interval timer. */ -asmlinkage long -sys_timer_create(const clockid_t which_clock, - struct sigevent __user *timer_event_spec, - timer_t __user * created_timer_id) +SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock, + struct sigevent __user *, timer_event_spec, + timer_t __user *, created_timer_id) { struct k_itimer *new_timer; int error, new_timer_id; @@ -661,8 +660,8 @@ common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) } /* Get the time remaining on a POSIX.1b interval timer. */ -asmlinkage long -sys_timer_gettime(timer_t timer_id, struct itimerspec __user *setting) +SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id, + struct itimerspec __user *, setting) { struct k_itimer *timr; struct itimerspec cur_setting; @@ -691,8 +690,7 @@ sys_timer_gettime(timer_t timer_id, struct itimerspec __user *setting) * the call back to do_schedule_next_timer(). So all we need to do is * to pick up the frozen overrun. */ -asmlinkage long -sys_timer_getoverrun(timer_t timer_id) +SYSCALL_DEFINE1(timer_getoverrun, timer_t, timer_id) { struct k_itimer *timr; int overrun; @@ -760,10 +758,9 @@ common_timer_set(struct k_itimer *timr, int flags, } /* Set a POSIX.1b interval timer */ -asmlinkage long -sys_timer_settime(timer_t timer_id, int flags, - const struct itimerspec __user *new_setting, - struct itimerspec __user *old_setting) +SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags, + const struct itimerspec __user *, new_setting, + struct itimerspec __user *, old_setting) { struct k_itimer *timr; struct itimerspec new_spec, old_spec; @@ -816,8 +813,7 @@ static inline int timer_delete_hook(struct k_itimer *timer) } /* Delete a POSIX.1b interval timer. */ -asmlinkage long -sys_timer_delete(timer_t timer_id) +SYSCALL_DEFINE1(timer_delete, timer_t, timer_id) { struct k_itimer *timer; unsigned long flags; @@ -903,8 +899,8 @@ int do_posix_clock_nonanosleep(const clockid_t clock, int flags, } EXPORT_SYMBOL_GPL(do_posix_clock_nonanosleep); -asmlinkage long sys_clock_settime(const clockid_t which_clock, - const struct timespec __user *tp) +SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, + const struct timespec __user *, tp) { struct timespec new_tp; @@ -916,8 +912,8 @@ asmlinkage long sys_clock_settime(const clockid_t which_clock, return CLOCK_DISPATCH(which_clock, clock_set, (which_clock, &new_tp)); } -asmlinkage long -sys_clock_gettime(const clockid_t which_clock, struct timespec __user *tp) +SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, + struct timespec __user *,tp) { struct timespec kernel_tp; int error; @@ -933,8 +929,8 @@ sys_clock_gettime(const clockid_t which_clock, struct timespec __user *tp) } -asmlinkage long -sys_clock_getres(const clockid_t which_clock, struct timespec __user *tp) +SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, + struct timespec __user *, tp) { struct timespec rtn_tp; int error; @@ -963,10 +959,9 @@ static int common_nsleep(const clockid_t which_clock, int flags, which_clock); } -asmlinkage long -sys_clock_nanosleep(const clockid_t which_clock, int flags, - const struct timespec __user *rqtp, - struct timespec __user *rmtp) +SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, + const struct timespec __user *, rqtp, + struct timespec __user *, rmtp) { struct timespec t; -- cgit From 5add95d4f7cf08f6f62510f19576992912387501 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:08 +0100 Subject: [CVE-2009-0029] System call wrappers part 06 Signed-off-by: Heiko Carstens --- kernel/sched.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index 8be2c13b50d..1a0fdfa5ddf 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -5126,7 +5126,7 @@ int can_nice(const struct task_struct *p, const int nice) * sys_setpriority is a more generic, but much slower function that * does similar things. */ -asmlinkage long sys_nice(int increment) +SYSCALL_DEFINE1(nice, int, increment) { long nice, retval; @@ -5433,8 +5433,8 @@ do_sched_setscheduler(pid_t pid, int policy, struct sched_param __user *param) * @policy: new policy. * @param: structure containing the new RT priority. */ -asmlinkage long -sys_sched_setscheduler(pid_t pid, int policy, struct sched_param __user *param) +SYSCALL_DEFINE3(sched_setscheduler, pid_t, pid, int, policy, + struct sched_param __user *, param) { /* negative values for policy are not valid */ if (policy < 0) @@ -5448,7 +5448,7 @@ sys_sched_setscheduler(pid_t pid, int policy, struct sched_param __user *param) * @pid: the pid in question. * @param: structure containing the new RT priority. */ -asmlinkage long sys_sched_setparam(pid_t pid, struct sched_param __user *param) +SYSCALL_DEFINE2(sched_setparam, pid_t, pid, struct sched_param __user *, param) { return do_sched_setscheduler(pid, -1, param); } @@ -5457,7 +5457,7 @@ asmlinkage long sys_sched_setparam(pid_t pid, struct sched_param __user *param) * sys_sched_getscheduler - get the policy (scheduling class) of a thread * @pid: the pid in question. */ -asmlinkage long sys_sched_getscheduler(pid_t pid) +SYSCALL_DEFINE1(sched_getscheduler, pid_t, pid) { struct task_struct *p; int retval; @@ -5482,7 +5482,7 @@ asmlinkage long sys_sched_getscheduler(pid_t pid) * @pid: the pid in question. * @param: structure containing the RT priority. */ -asmlinkage long sys_sched_getparam(pid_t pid, struct sched_param __user *param) +SYSCALL_DEFINE2(sched_getparam, pid_t, pid, struct sched_param __user *, param) { struct sched_param lp; struct task_struct *p; @@ -5600,8 +5600,8 @@ static int get_user_cpu_mask(unsigned long __user *user_mask_ptr, unsigned len, * @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) +SYSCALL_DEFINE3(sched_setaffinity, pid_t, pid, unsigned int, len, + unsigned long __user *, user_mask_ptr) { cpumask_var_t new_mask; int retval; @@ -5648,8 +5648,8 @@ out_unlock: * @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) +SYSCALL_DEFINE3(sched_getaffinity, pid_t, pid, unsigned int, len, + unsigned long __user *, user_mask_ptr) { int ret; cpumask_var_t mask; @@ -5678,7 +5678,7 @@ asmlinkage long sys_sched_getaffinity(pid_t pid, unsigned int len, * This function yields the current CPU to other tasks. If there are no * other threads running on this CPU then this function will return. */ -asmlinkage long sys_sched_yield(void) +SYSCALL_DEFINE0(sched_yield) { struct rq *rq = this_rq_lock(); @@ -5819,7 +5819,7 @@ long __sched io_schedule_timeout(long timeout) * this syscall returns the maximum rt_priority that can be used * by a given scheduling class. */ -asmlinkage long sys_sched_get_priority_max(int policy) +SYSCALL_DEFINE1(sched_get_priority_max, int, policy) { int ret = -EINVAL; @@ -5844,7 +5844,7 @@ asmlinkage long sys_sched_get_priority_max(int policy) * this syscall returns the minimum rt_priority that can be used * by a given scheduling class. */ -asmlinkage long sys_sched_get_priority_min(int policy) +SYSCALL_DEFINE1(sched_get_priority_min, int, policy) { int ret = -EINVAL; -- cgit From 754fe8d297bfae7b77f7ce866e2fb0c5fb186506 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:09 +0100 Subject: [CVE-2009-0029] System call wrappers part 07 Signed-off-by: Heiko Carstens --- kernel/exit.c | 8 ++++---- kernel/kexec.c | 5 ++--- kernel/sched.c | 4 ++-- kernel/signal.c | 2 +- kernel/sys.c | 7 ++++--- net/socket.c | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/kernel/exit.c b/kernel/exit.c index fac9b040af2..08895df0eab 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -1141,7 +1141,7 @@ NORET_TYPE void complete_and_exit(struct completion *comp, long code) EXPORT_SYMBOL(complete_and_exit); -asmlinkage long sys_exit(int error_code) +SYSCALL_DEFINE1(exit, int, error_code) { do_exit((error_code&0xff)<<8); } @@ -1182,7 +1182,7 @@ do_group_exit(int exit_code) * wait4()-ing process will get the correct exit code - even if this * thread is not the thread group leader. */ -asmlinkage long sys_exit_group(int error_code) +SYSCALL_DEFINE1(exit_group, int, error_code) { do_group_exit((error_code & 0xff) << 8); /* NOTREACHED */ @@ -1795,8 +1795,8 @@ asmlinkage long sys_waitid(int which, pid_t upid, return ret; } -asmlinkage long sys_wait4(pid_t upid, int __user *stat_addr, - int options, struct rusage __user *ru) +SYSCALL_DEFINE4(wait4, pid_t, upid, int __user *, stat_addr, + int, options, struct rusage __user *, ru) { struct pid *pid = NULL; enum pid_type type; diff --git a/kernel/kexec.c b/kernel/kexec.c index 3fb855ad6aa..8a6d7b08864 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -934,9 +934,8 @@ struct kimage *kexec_crash_image; static DEFINE_MUTEX(kexec_mutex); -asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments, - struct kexec_segment __user *segments, - unsigned long flags) +SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments, + struct kexec_segment __user *, segments, unsigned long, flags) { struct kimage **dest_image, *image; int result; diff --git a/kernel/sched.c b/kernel/sched.c index 1a0fdfa5ddf..65c02037b05 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -5869,8 +5869,8 @@ SYSCALL_DEFINE1(sched_get_priority_min, int, policy) * this syscall writes the default timeslice value of a given process * into the user-space timespec buffer. A value of '0' means infinity. */ -asmlinkage -long sys_sched_rr_get_interval(pid_t pid, struct timespec __user *interval) +SYSCALL_DEFINE4(sched_rr_get_interval, pid_t, pid, + struct timespec __user *, interval) { struct task_struct *p; unsigned int time_slice; diff --git a/kernel/signal.c b/kernel/signal.c index 3fe08eaa5de..41f32e08615 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1961,7 +1961,7 @@ EXPORT_SYMBOL(unblock_all_signals); * System call entry points. */ -asmlinkage long sys_restart_syscall(void) +SYSCALL_DEFINE0(restart_syscall) { struct restart_block *restart = ¤t_thread_info()->restart_block; return restart->fn(restart); diff --git a/kernel/sys.c b/kernel/sys.c index cbe4502c28a..39b192b4003 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -143,7 +143,7 @@ out: return error; } -asmlinkage long sys_setpriority(int which, int who, int niceval) +SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval) { struct task_struct *g, *p; struct user_struct *user; @@ -208,7 +208,7 @@ out: * has been offset by 20 (ie it returns 40..1 instead of -20..19) * to stay compatible. */ -asmlinkage long sys_getpriority(int which, int who) +SYSCALL_DEFINE2(getpriority, int, which, int, who) { struct task_struct *g, *p; struct user_struct *user; @@ -355,7 +355,8 @@ EXPORT_SYMBOL_GPL(kernel_power_off); * * reboot doesn't sync: do that yourself before calling this. */ -asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user * arg) +SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, + void __user *, arg) { char buffer[256]; diff --git a/net/socket.c b/net/socket.c index 06603d73c41..cc9b666e58f 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1789,7 +1789,7 @@ out_put: * Shutdown a socket. */ -asmlinkage long sys_shutdown(int fd, int how) +SYSCALL_DEFINE2(shutdown, int, fd, int, how) { int err, fput_needed; struct socket *sock; -- cgit From 17da2bd90abf428523de0fb98f7075e00e3ed42e Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:10 +0100 Subject: [CVE-2009-0029] System call wrappers part 08 Signed-off-by: Heiko Carstens --- kernel/exit.c | 7 +++---- kernel/fork.c | 2 +- kernel/futex.c | 6 +++--- kernel/module.c | 10 ++++------ kernel/sched.c | 2 +- kernel/signal.c | 18 +++++++----------- 6 files changed, 19 insertions(+), 26 deletions(-) diff --git a/kernel/exit.c b/kernel/exit.c index 08895df0eab..f80dec3f187 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -1754,9 +1754,8 @@ end: return retval; } -asmlinkage long sys_waitid(int which, pid_t upid, - struct siginfo __user *infop, int options, - struct rusage __user *ru) +SYSCALL_DEFINE5(waitid, int, which, pid_t, upid, struct siginfo __user *, + infop, int, options, struct rusage __user *, ru) { struct pid *pid = NULL; enum pid_type type; @@ -1833,7 +1832,7 @@ SYSCALL_DEFINE4(wait4, pid_t, upid, int __user *, stat_addr, * sys_waitpid() remains for compatibility. waitpid() should be * implemented by calling sys_wait4() from libc.a. */ -asmlinkage long sys_waitpid(pid_t pid, int __user *stat_addr, int options) +SYSCALL_DEFINE3(waitpid, pid_t, pid, int __user *, stat_addr, int, options) { return sys_wait4(pid, stat_addr, options, NULL); } diff --git a/kernel/fork.c b/kernel/fork.c index 1d68f1255dd..8eb37d38c6a 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -901,7 +901,7 @@ static void copy_flags(unsigned long clone_flags, struct task_struct *p) clear_freeze_flag(p); } -asmlinkage long sys_set_tid_address(int __user *tidptr) +SYSCALL_DEFINE1(set_tid_address, int __user *, tidptr) { current->clear_child_tid = tidptr; diff --git a/kernel/futex.c b/kernel/futex.c index 002aa189eb0..e86931d8d4e 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -1978,9 +1978,9 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, } -asmlinkage long sys_futex(u32 __user *uaddr, int op, u32 val, - struct timespec __user *utime, u32 __user *uaddr2, - u32 val3) +SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val, + struct timespec __user *, utime, u32 __user *, uaddr2, + u32, val3) { struct timespec ts; ktime_t t, *tp = NULL; diff --git a/kernel/module.c b/kernel/module.c index c9332c90d5a..e8b51d41dd7 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -743,8 +743,8 @@ static void wait_for_zero_refcount(struct module *mod) mutex_lock(&module_mutex); } -asmlinkage long -sys_delete_module(const char __user *name_user, unsigned int flags) +SYSCALL_DEFINE2(delete_module, const char __user *, name_user, + unsigned int, flags) { struct module *mod; char name[MODULE_NAME_LEN]; @@ -2296,10 +2296,8 @@ static noinline struct module *load_module(void __user *umod, } /* This is where the real work happens */ -asmlinkage long -sys_init_module(void __user *umod, - unsigned long len, - const char __user *uargs) +SYSCALL_DEFINE3(init_module, void __user *, umod, + unsigned long, len, const char __user *, uargs) { struct module *mod; int ret = 0; diff --git a/kernel/sched.c b/kernel/sched.c index 65c02037b05..eb1931eef58 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -5869,7 +5869,7 @@ SYSCALL_DEFINE1(sched_get_priority_min, int, policy) * this syscall writes the default timeslice value of a given process * into the user-space timespec buffer. A value of '0' means infinity. */ -SYSCALL_DEFINE4(sched_rr_get_interval, pid_t, pid, +SYSCALL_DEFINE2(sched_rr_get_interval, pid_t, pid, struct timespec __user *, interval) { struct task_struct *p; diff --git a/kernel/signal.c b/kernel/signal.c index 41f32e08615..278cc8737f1 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2014,8 +2014,8 @@ int sigprocmask(int how, sigset_t *set, sigset_t *oldset) return error; } -asmlinkage long -sys_rt_sigprocmask(int how, sigset_t __user *set, sigset_t __user *oset, size_t sigsetsize) +SYSCALL_DEFINE4(rt_sigprocmask, int, how, sigset_t __user *, set, + sigset_t __user *, oset, size_t, sigsetsize) { int error = -EINVAL; sigset_t old_set, new_set; @@ -2074,8 +2074,7 @@ out: return error; } -asmlinkage long -sys_rt_sigpending(sigset_t __user *set, size_t sigsetsize) +SYSCALL_DEFINE2(rt_sigpending, sigset_t __user *, set, size_t, sigsetsize) { return do_sigpending(set, sigsetsize); } @@ -2146,11 +2145,9 @@ int copy_siginfo_to_user(siginfo_t __user *to, siginfo_t *from) #endif -asmlinkage long -sys_rt_sigtimedwait(const sigset_t __user *uthese, - siginfo_t __user *uinfo, - const struct timespec __user *uts, - size_t sigsetsize) +SYSCALL_DEFINE4(rt_sigtimedwait, const sigset_t __user *, uthese, + siginfo_t __user *, uinfo, const struct timespec __user *, uts, + size_t, sigsetsize) { int ret, sig; sigset_t these; @@ -2223,8 +2220,7 @@ sys_rt_sigtimedwait(const sigset_t __user *uthese, return ret; } -asmlinkage long -sys_kill(pid_t pid, int sig) +SYSCALL_DEFINE2(kill, pid_t, pid, int, sig) { struct siginfo info; -- cgit From a5f8fa9e9ba5ef3305e147f41ad6e1e84ac1f0bd Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:11 +0100 Subject: [CVE-2009-0029] System call wrappers part 09 Signed-off-by: Heiko Carstens --- fs/sync.c | 6 +++--- kernel/signal.c | 21 ++++++++------------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/fs/sync.c b/fs/sync.c index 23ebbd72ecc..a16d53e5fe9 100644 --- a/fs/sync.c +++ b/fs/sync.c @@ -36,7 +36,7 @@ static void do_sync(unsigned long wait) laptop_sync_completion(); } -asmlinkage long sys_sync(void) +SYSCALL_DEFINE0(sync) { do_sync(1); return 0; @@ -144,12 +144,12 @@ static int do_fsync(unsigned int fd, int datasync) return ret; } -asmlinkage long sys_fsync(unsigned int fd) +SYSCALL_DEFINE1(fsync, unsigned int, fd) { return do_fsync(fd, 0); } -asmlinkage long sys_fdatasync(unsigned int fd) +SYSCALL_DEFINE1(fdatasync, unsigned int, fd) { return do_fsync(fd, 1); } diff --git a/kernel/signal.c b/kernel/signal.c index 278cc8737f1..e2333929611 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2279,7 +2279,7 @@ static int do_tkill(pid_t tgid, pid_t pid, int sig) * exists but it's not belonging to the target process anymore. This * method solves the problem of threads exiting and PIDs getting reused. */ -asmlinkage long sys_tgkill(pid_t tgid, pid_t pid, int sig) +SYSCALL_DEFINE3(tgkill, pid_t, tgid, pid_t, pid, int, sig) { /* This is only valid for single tasks */ if (pid <= 0 || tgid <= 0) @@ -2291,8 +2291,7 @@ asmlinkage long sys_tgkill(pid_t tgid, pid_t pid, int sig) /* * Send a signal to only one task, even if it's a CLONE_THREAD task. */ -asmlinkage long -sys_tkill(pid_t pid, int sig) +SYSCALL_DEFINE2(tkill, pid_t, pid, int, sig) { /* This is only valid for single tasks */ if (pid <= 0) @@ -2301,8 +2300,8 @@ sys_tkill(pid_t pid, int sig) return do_tkill(0, pid, sig); } -asmlinkage long -sys_rt_sigqueueinfo(pid_t pid, int sig, siginfo_t __user *uinfo) +SYSCALL_DEFINE3(rt_sigqueueinfo, pid_t, pid, int, sig, + siginfo_t __user *, uinfo) { siginfo_t info; @@ -2526,15 +2525,13 @@ out: /* * For backwards compatibility. Functionality superseded by sigprocmask. */ -asmlinkage long -sys_sgetmask(void) +SYSCALL_DEFINE0(sgetmask) { /* SMP safe */ return current->blocked.sig[0]; } -asmlinkage long -sys_ssetmask(int newmask) +SYSCALL_DEFINE1(ssetmask, int, newmask) { int old; @@ -2554,8 +2551,7 @@ sys_ssetmask(int newmask) /* * For backwards compatibility. Functionality superseded by sigaction. */ -asmlinkage long -sys_signal(int sig, __sighandler_t handler) +SYSCALL_DEFINE2(signal, int, sig, __sighandler_t, handler) { struct k_sigaction new_sa, old_sa; int ret; @@ -2572,8 +2568,7 @@ sys_signal(int sig, __sighandler_t handler) #ifdef __ARCH_WANT_SYS_PAUSE -asmlinkage long -sys_pause(void) +SYSCALL_DEFINE0(pause) { current->state = TASK_INTERRUPTIBLE; schedule(); -- cgit From bdc480e3bef6eb0e7071770834cbdda7e30a5436 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:12 +0100 Subject: [CVE-2009-0029] System call wrappers part 10 Signed-off-by: Heiko Carstens --- fs/buffer.c | 2 +- fs/namespace.c | 9 ++++----- fs/open.c | 12 +++++------- fs/stat.c | 2 +- 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/fs/buffer.c b/fs/buffer.c index b6e8b8632e2..b58208f1640 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -3243,7 +3243,7 @@ void block_sync_page(struct page *page) * Use of bdflush() is deprecated and will be removed in a future kernel. * The `pdflush' kernel threads fully replace bdflush daemons and this call. */ -asmlinkage long sys_bdflush(int func, long data) +SYSCALL_DEFINE2(bdflush, int, func, long, data) { static int msg_count; diff --git a/fs/namespace.c b/fs/namespace.c index a40685d800a..3876a0fbaa6 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1128,7 +1128,7 @@ static int do_umount(struct vfsmount *mnt, int flags) * unixes. Our API is identical to OSF/1 to avoid making a mess of AMD */ -asmlinkage long sys_umount(char __user * name, int flags) +SYSCALL_DEFINE2(umount, char __user *, name, int, flags) { struct path path; int retval; @@ -1160,7 +1160,7 @@ out: /* * The 2.0 compatible umount. No flags. */ -asmlinkage long sys_oldumount(char __user * name) +SYSCALL_DEFINE1(oldumount, char __user *, name) { return sys_umount(name, 0); } @@ -2045,9 +2045,8 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns, return new_ns; } -asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name, - char __user * type, unsigned long flags, - void __user * data) +SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, + char __user *, type, unsigned long, flags, void __user *, data) { int retval; unsigned long data_page; diff --git a/fs/open.c b/fs/open.c index e349013fc79..f6c2f5673ed 100644 --- a/fs/open.c +++ b/fs/open.c @@ -122,7 +122,7 @@ static int vfs_statfs64(struct dentry *dentry, struct statfs64 *buf) return 0; } -asmlinkage long sys_statfs(const char __user *pathname, struct statfs __user * buf) +SYSCALL_DEFINE2(statfs, const char __user *, pathname, struct statfs __user *, buf) { struct path path; int error; @@ -138,8 +138,7 @@ asmlinkage long sys_statfs(const char __user *pathname, struct statfs __user * b return error; } - -asmlinkage long sys_statfs64(const char __user *pathname, size_t sz, struct statfs64 __user *buf) +SYSCALL_DEFINE3(statfs64, const char __user *, pathname, size_t, sz, struct statfs64 __user *, buf) { struct path path; long error; @@ -157,8 +156,7 @@ asmlinkage long sys_statfs64(const char __user *pathname, size_t sz, struct stat return error; } - -asmlinkage long sys_fstatfs(unsigned int fd, struct statfs __user * buf) +SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct statfs __user *, buf) { struct file * file; struct statfs tmp; @@ -289,7 +287,7 @@ out: return error; } -asmlinkage long sys_truncate(const char __user * path, unsigned long length) +SYSCALL_DEFINE2(truncate, const char __user *, path, unsigned long, length) { /* on 32-bit boxen it will cut the range 2^31--2^32-1 off */ return do_sys_truncate(path, (long)length); @@ -341,7 +339,7 @@ out: return error; } -asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length) +SYSCALL_DEFINE2(ftruncate, unsigned int, fd, unsigned long, length) { long ret = do_sys_ftruncate(fd, length, 1); /* avoid REGPARM breakage on x86: */ diff --git a/fs/stat.c b/fs/stat.c index 7e12a6f8279..a1411648048 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -152,7 +152,7 @@ static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat __user * sta return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; } -asmlinkage long sys_stat(char __user * filename, struct __old_kernel_stat __user * statbuf) +SYSCALL_DEFINE2(stat, char __user *, filename, struct __old_kernel_stat __user *, statbuf) { struct kstat stat; int error = vfs_stat_fd(AT_FDCWD, filename, &stat); -- cgit From 257ac264d69017270fbc3cf5536953525db4076c Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:13 +0100 Subject: [CVE-2009-0029] System call wrappers part 11 Signed-off-by: Heiko Carstens --- fs/open.c | 2 +- fs/stat.c | 20 ++++++++++++-------- fs/super.c | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/fs/open.c b/fs/open.c index f6c2f5673ed..322bb60d168 100644 --- a/fs/open.c +++ b/fs/open.c @@ -174,7 +174,7 @@ out: return error; } -asmlinkage long sys_fstatfs64(unsigned int fd, size_t sz, struct statfs64 __user *buf) +SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, size_t, sz, struct statfs64 __user *, buf) { struct file * file; struct statfs64 tmp; diff --git a/fs/stat.c b/fs/stat.c index a1411648048..f29c5fe4f8b 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -162,7 +162,8 @@ SYSCALL_DEFINE2(stat, char __user *, filename, struct __old_kernel_stat __user * return error; } -asmlinkage long sys_lstat(char __user * filename, struct __old_kernel_stat __user * statbuf) + +SYSCALL_DEFINE2(lstat, char __user *, filename, struct __old_kernel_stat __user *, statbuf) { struct kstat stat; int error = vfs_lstat_fd(AT_FDCWD, filename, &stat); @@ -172,7 +173,8 @@ asmlinkage long sys_lstat(char __user * filename, struct __old_kernel_stat __use return error; } -asmlinkage long sys_fstat(unsigned int fd, struct __old_kernel_stat __user * statbuf) + +SYSCALL_DEFINE2(fstat, unsigned int, fd, struct __old_kernel_stat __user *, statbuf) { struct kstat stat; int error = vfs_fstat(fd, &stat); @@ -235,7 +237,7 @@ static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf) return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; } -asmlinkage long sys_newstat(char __user *filename, struct stat __user *statbuf) +SYSCALL_DEFINE2(newstat, char __user *, filename, struct stat __user *, statbuf) { struct kstat stat; int error = vfs_stat_fd(AT_FDCWD, filename, &stat); @@ -246,7 +248,7 @@ asmlinkage long sys_newstat(char __user *filename, struct stat __user *statbuf) return error; } -asmlinkage long sys_newlstat(char __user *filename, struct stat __user *statbuf) +SYSCALL_DEFINE2(newlstat, char __user *, filename, struct stat __user *, statbuf) { struct kstat stat; int error = vfs_lstat_fd(AT_FDCWD, filename, &stat); @@ -280,7 +282,7 @@ out: } #endif -asmlinkage long sys_newfstat(unsigned int fd, struct stat __user *statbuf) +SYSCALL_DEFINE2(newfstat, unsigned int, fd, struct stat __user *, statbuf) { struct kstat stat; int error = vfs_fstat(fd, &stat); @@ -365,7 +367,7 @@ static long cp_new_stat64(struct kstat *stat, struct stat64 __user *statbuf) return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; } -asmlinkage long sys_stat64(char __user * filename, struct stat64 __user * statbuf) +SYSCALL_DEFINE2(stat64, char __user *, filename, struct stat64 __user *, statbuf) { struct kstat stat; int error = vfs_stat(filename, &stat); @@ -375,7 +377,8 @@ asmlinkage long sys_stat64(char __user * filename, struct stat64 __user * statbu return error; } -asmlinkage long sys_lstat64(char __user * filename, struct stat64 __user * statbuf) + +SYSCALL_DEFINE2(lstat64, char __user *, filename, struct stat64 __user *, statbuf) { struct kstat stat; int error = vfs_lstat(filename, &stat); @@ -385,7 +388,8 @@ asmlinkage long sys_lstat64(char __user * filename, struct stat64 __user * statb return error; } -asmlinkage long sys_fstat64(unsigned long fd, struct stat64 __user * statbuf) + +SYSCALL_DEFINE2(fstat64, unsigned long, fd, struct stat64 __user *, statbuf) { struct kstat stat; int error = vfs_fstat(fd, &stat); diff --git a/fs/super.c b/fs/super.c index ed080c41716..645e5403f2a 100644 --- a/fs/super.c +++ b/fs/super.c @@ -544,7 +544,7 @@ rescan: return NULL; } -asmlinkage long sys_ustat(unsigned dev, struct ustat __user * ubuf) +SYSCALL_DEFINE2(ustat, unsigned, dev, struct ustat __user *, ubuf) { struct super_block *s; struct ustat tmp; -- cgit From 64fd1de3d821659ac0a3004fd5ee1de59e64af30 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:14 +0100 Subject: [CVE-2009-0029] System call wrappers part 12 Signed-off-by: Heiko Carstens --- fs/xattr.c | 46 +++++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/fs/xattr.c b/fs/xattr.c index d049ae27aae..0367a5dae2b 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -251,9 +251,9 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value, return error; } -asmlinkage long -sys_setxattr(const char __user *pathname, const char __user *name, - const void __user *value, size_t size, int flags) +SYSCALL_DEFINE5(setxattr, const char __user *, pathname, + const char __user *, name, const void __user *, value, + size_t, size, int, flags) { struct path path; int error; @@ -270,9 +270,9 @@ sys_setxattr(const char __user *pathname, const char __user *name, return error; } -asmlinkage long -sys_lsetxattr(const char __user *pathname, const char __user *name, - const void __user *value, size_t size, int flags) +SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname, + const char __user *, name, const void __user *, value, + size_t, size, int, flags) { struct path path; int error; @@ -289,9 +289,8 @@ sys_lsetxattr(const char __user *pathname, const char __user *name, return error; } -asmlinkage long -sys_fsetxattr(int fd, const char __user *name, const void __user *value, - size_t size, int flags) +SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, + const void __user *,value, size_t, size, int, flags) { struct file *f; struct dentry *dentry; @@ -349,9 +348,8 @@ getxattr(struct dentry *d, const char __user *name, void __user *value, return error; } -asmlinkage long -sys_getxattr(const char __user *pathname, const char __user *name, - void __user *value, size_t size) +SYSCALL_DEFINE4(getxattr, const char __user *, pathname, + const char __user *, name, void __user *, value, size_t, size) { struct path path; ssize_t error; @@ -364,9 +362,8 @@ sys_getxattr(const char __user *pathname, const char __user *name, return error; } -asmlinkage long -sys_lgetxattr(const char __user *pathname, const char __user *name, void __user *value, - size_t size) +SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname, + const char __user *, name, void __user *, value, size_t, size) { struct path path; ssize_t error; @@ -379,8 +376,8 @@ sys_lgetxattr(const char __user *pathname, const char __user *name, void __user return error; } -asmlinkage long -sys_fgetxattr(int fd, const char __user *name, void __user *value, size_t size) +SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name, + void __user *, value, size_t, size) { struct file *f; ssize_t error = -EBADF; @@ -424,8 +421,8 @@ listxattr(struct dentry *d, char __user *list, size_t size) return error; } -asmlinkage long -sys_listxattr(const char __user *pathname, char __user *list, size_t size) +SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list, + size_t, size) { struct path path; ssize_t error; @@ -438,8 +435,8 @@ sys_listxattr(const char __user *pathname, char __user *list, size_t size) return error; } -asmlinkage long -sys_llistxattr(const char __user *pathname, char __user *list, size_t size) +SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list, + size_t, size) { struct path path; ssize_t error; @@ -452,8 +449,7 @@ sys_llistxattr(const char __user *pathname, char __user *list, size_t size) return error; } -asmlinkage long -sys_flistxattr(int fd, char __user *list, size_t size) +SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size) { struct file *f; ssize_t error = -EBADF; @@ -485,8 +481,8 @@ removexattr(struct dentry *d, const char __user *name) return vfs_removexattr(d, kname); } -asmlinkage long -sys_removexattr(const char __user *pathname, const char __user *name) +SYSCALL_DEFINE2(removexattr, const char __user *, pathname, + const char __user *, name) { struct path path; int error; -- cgit From 6a6160a7b5c27b3c38651baef92a14fa7072b3c1 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:15 +0100 Subject: [CVE-2009-0029] System call wrappers part 13 Signed-off-by: Heiko Carstens --- fs/xattr.c | 7 +++---- mm/fremap.c | 4 ++-- mm/mlock.c | 4 ++-- mm/mmap.c | 4 ++-- mm/mprotect.c | 4 ++-- mm/mremap.c | 6 +++--- mm/msync.c | 2 +- mm/nommu.c | 11 +++++------ 8 files changed, 20 insertions(+), 22 deletions(-) diff --git a/fs/xattr.c b/fs/xattr.c index 0367a5dae2b..197c4fcac03 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -499,8 +499,8 @@ SYSCALL_DEFINE2(removexattr, const char __user *, pathname, return error; } -asmlinkage long -sys_lremovexattr(const char __user *pathname, const char __user *name) +SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname, + const char __user *, name) { struct path path; int error; @@ -517,8 +517,7 @@ sys_lremovexattr(const char __user *pathname, const char __user *name) return error; } -asmlinkage long -sys_fremovexattr(int fd, const char __user *name) +SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name) { struct file *f; struct dentry *dentry; diff --git a/mm/fremap.c b/mm/fremap.c index 62d5bbda921..736ba7f3306 100644 --- a/mm/fremap.c +++ b/mm/fremap.c @@ -120,8 +120,8 @@ static int populate_range(struct mm_struct *mm, struct vm_area_struct *vma, * and the vma's default protection is used. Arbitrary protections * might be implemented in the future. */ -asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size, - unsigned long prot, unsigned long pgoff, unsigned long flags) +SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, + unsigned long, prot, unsigned long, pgoff, unsigned long, flags) { struct mm_struct *mm = current->mm; struct address_space *mapping; diff --git a/mm/mlock.c b/mm/mlock.c index e125156c664..04d5e7429c5 100644 --- a/mm/mlock.c +++ b/mm/mlock.c @@ -530,7 +530,7 @@ static int do_mlock(unsigned long start, size_t len, int on) return error; } -asmlinkage long sys_mlock(unsigned long start, size_t len) +SYSCALL_DEFINE2(mlock, unsigned long, start, size_t, len) { unsigned long locked; unsigned long lock_limit; @@ -558,7 +558,7 @@ asmlinkage long sys_mlock(unsigned long start, size_t len) return error; } -asmlinkage long sys_munlock(unsigned long start, size_t len) +SYSCALL_DEFINE2(munlock, unsigned long, start, size_t, len) { int ret; diff --git a/mm/mmap.c b/mm/mmap.c index a970d890cb2..8d95902e9a3 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -245,7 +245,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) return next; } -asmlinkage long sys_brk(unsigned long brk) +SYSCALL_DEFINE1(brk, unsigned long, brk) { unsigned long rlim, retval; unsigned long newbrk, oldbrk; @@ -1948,7 +1948,7 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) EXPORT_SYMBOL(do_munmap); -asmlinkage long sys_munmap(unsigned long addr, size_t len) +SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) { int ret; struct mm_struct *mm = current->mm; diff --git a/mm/mprotect.c b/mm/mprotect.c index d0f6e7ce09f..abe2694e13f 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -217,8 +217,8 @@ fail: return error; } -asmlinkage long -sys_mprotect(unsigned long start, size_t len, unsigned long prot) +SYSCALL_DEFINE3(mprotect, unsigned long, start, size_t, len, + unsigned long, prot) { unsigned long vm_flags, nstart, end, tmp, reqprot; struct vm_area_struct *vma, *prev; diff --git a/mm/mremap.c b/mm/mremap.c index 5572e0825d8..a39b7b91be4 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -420,9 +420,9 @@ out_nc: return ret; } -asmlinkage long sys_mremap(unsigned long addr, - unsigned long old_len, unsigned long new_len, - unsigned long flags, unsigned long new_addr) +SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len, + unsigned long, new_len, unsigned long, flags, + unsigned long, new_addr) { unsigned long ret; diff --git a/mm/msync.c b/mm/msync.c index 07dae08cf31..4083209b7f0 100644 --- a/mm/msync.c +++ b/mm/msync.c @@ -28,7 +28,7 @@ * So by _not_ starting I/O in MS_ASYNC we provide complete flexibility to * applications. */ -asmlinkage long sys_msync(unsigned long start, size_t len, int flags) +SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, int, flags) { unsigned long end; struct mm_struct *mm = current->mm; diff --git a/mm/nommu.c b/mm/nommu.c index ee3e7892773..8cee8c8ff0f 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -416,7 +416,7 @@ EXPORT_SYMBOL(vm_insert_page); * to a regular file. in this case, the unmapping will need * to invoke file system routines that need the global lock. */ -asmlinkage long sys_brk(unsigned long brk) +SYSCALL_DEFINE1(brk, unsigned long, brk) { struct mm_struct *mm = current->mm; @@ -1573,7 +1573,7 @@ erase_whole_vma: } EXPORT_SYMBOL(do_munmap); -asmlinkage long sys_munmap(unsigned long addr, size_t len) +SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) { int ret; struct mm_struct *mm = current->mm; @@ -1657,10 +1657,9 @@ unsigned long do_mremap(unsigned long addr, } EXPORT_SYMBOL(do_mremap); -asmlinkage -unsigned long sys_mremap(unsigned long addr, - unsigned long old_len, unsigned long new_len, - unsigned long flags, unsigned long new_addr) +SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len, + unsigned long, new_len, unsigned long, flags, + unsigned long, new_addr) { unsigned long ret; -- cgit From 3480b25743cb7404928d57efeaa3d085708b04c2 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:16 +0100 Subject: [CVE-2009-0029] System call wrappers part 14 Signed-off-by: Heiko Carstens --- fs/namei.c | 8 ++++---- fs/namespace.c | 4 ++-- fs/open.c | 2 +- mm/madvise.c | 2 +- mm/mincore.c | 4 ++-- mm/mlock.c | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index f05bed24242..43fa2525972 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2017,7 +2017,7 @@ out_unlock: return error; } -asmlinkage long sys_mknod(const char __user *filename, int mode, unsigned dev) +SYSCALL_DEFINE3(mknod, const char __user *, filename, int, mode, unsigned, dev) { return sys_mknodat(AT_FDCWD, filename, mode, dev); } @@ -2302,7 +2302,7 @@ asmlinkage long sys_unlinkat(int dfd, const char __user *pathname, int flag) return do_unlinkat(dfd, pathname); } -asmlinkage long sys_unlink(const char __user *pathname) +SYSCALL_DEFINE1(unlink, const char __user *, pathname) { return do_unlinkat(AT_FDCWD, pathname); } @@ -2370,7 +2370,7 @@ out_putname: return error; } -asmlinkage long sys_symlink(const char __user *oldname, const char __user *newname) +SYSCALL_DEFINE2(symlink, const char __user *, oldname, const char __user *, newname) { return sys_symlinkat(oldname, AT_FDCWD, newname); } @@ -2473,7 +2473,7 @@ out: return error; } -asmlinkage long sys_link(const char __user *oldname, const char __user *newname) +SYSCALL_DEFINE2(link, const char __user *, oldname, const char __user *, newname) { return sys_linkat(AT_FDCWD, oldname, AT_FDCWD, newname, 0); } diff --git a/fs/namespace.c b/fs/namespace.c index 3876a0fbaa6..228d8c4bfd1 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2171,8 +2171,8 @@ static void chroot_fs_refs(struct path *old_root, struct path *new_root) * though, so you may need to say mount --bind /nfs/my_root /nfs/my_root * first. */ -asmlinkage long sys_pivot_root(const char __user * new_root, - const char __user * put_old) +SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, + const char __user *, put_old) { struct vfsmount *tmp; struct path new, old, parent_path, root_parent, root; diff --git a/fs/open.c b/fs/open.c index 322bb60d168..9b926de6ed9 100644 --- a/fs/open.c +++ b/fs/open.c @@ -569,7 +569,7 @@ out: return error; } -asmlinkage long sys_chroot(const char __user * filename) +SYSCALL_DEFINE1(chroot, const char __user *, filename) { struct path path; int error; diff --git a/mm/madvise.c b/mm/madvise.c index f9349c18a1b..b9ce574827c 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -281,7 +281,7 @@ madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev, * -EBADF - map exists, but area maps something that isn't a file. * -EAGAIN - a kernel resource was temporarily unavailable. */ -asmlinkage long sys_madvise(unsigned long start, size_t len_in, int behavior) +SYSCALL_DEFINE3(madvise, unsigned long, start, size_t, len_in, int, behavior) { unsigned long end, tmp; struct vm_area_struct * vma, *prev; diff --git a/mm/mincore.c b/mm/mincore.c index 5178800bc12..8cb508f84ea 100644 --- a/mm/mincore.c +++ b/mm/mincore.c @@ -177,8 +177,8 @@ none_mapped: * mapped * -EAGAIN - A kernel resource was temporarily unavailable. */ -asmlinkage long sys_mincore(unsigned long start, size_t len, - unsigned char __user * vec) +SYSCALL_DEFINE3(mincore, unsigned long, start, size_t, len, + unsigned char __user *, vec) { long retval; unsigned long pages; diff --git a/mm/mlock.c b/mm/mlock.c index 04d5e7429c5..2904a347e47 100644 --- a/mm/mlock.c +++ b/mm/mlock.c @@ -595,7 +595,7 @@ out: return 0; } -asmlinkage long sys_mlockall(int flags) +SYSCALL_DEFINE1(mlockall, int, flags) { unsigned long lock_limit; int ret = -EINVAL; @@ -623,7 +623,7 @@ out: return ret; } -asmlinkage long sys_munlockall(void) +SYSCALL_DEFINE0(munlockall) { int ret; -- cgit From a26eab2400f0477bfac0255600552394855016f7 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:17 +0100 Subject: [CVE-2009-0029] System call wrappers part 15 Signed-off-by: Heiko Carstens --- fs/fcntl.c | 11 ++++++----- fs/ioctl.c | 2 +- fs/namei.c | 2 +- fs/open.c | 4 ++-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/fs/fcntl.c b/fs/fcntl.c index cdc14194672..bd215cc791d 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -50,7 +50,7 @@ static int get_close_on_exec(unsigned int fd) return res; } -asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags) +SYSCALL_DEFINE3(dup3, unsigned int, oldfd, unsigned int, newfd, int, flags) { int err = -EBADF; struct file * file, *tofree; @@ -113,7 +113,7 @@ out_unlock: return err; } -asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd) +SYSCALL_DEFINE2(dup2, unsigned int, oldfd, unsigned int, newfd) { if (unlikely(newfd == oldfd)) { /* corner case */ struct files_struct *files = current->files; @@ -126,7 +126,7 @@ asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd) return sys_dup3(oldfd, newfd, 0); } -asmlinkage long sys_dup(unsigned int fildes) +SYSCALL_DEFINE1(dup, unsigned int, fildes) { int ret = -EBADF; struct file *file = fget(fildes); @@ -335,7 +335,7 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, return err; } -asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) +SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) { struct file *filp; long err = -EBADF; @@ -358,7 +358,8 @@ out: } #if BITS_PER_LONG == 32 -asmlinkage long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg) +SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, + unsigned long, arg) { struct file * filp; long err; diff --git a/fs/ioctl.c b/fs/ioctl.c index 20b0a8a24c6..240ec63984c 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -542,7 +542,7 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, return error; } -asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) +SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) { struct file *filp; int error = -EBADF; diff --git a/fs/namei.c b/fs/namei.c index 43fa2525972..00c4f37a039 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2718,7 +2718,7 @@ exit: return error; } -asmlinkage long sys_rename(const char __user *oldname, const char __user *newname) +SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newname) { return sys_renameat(AT_FDCWD, oldname, AT_FDCWD, newname); } diff --git a/fs/open.c b/fs/open.c index 9b926de6ed9..ecc75a2c262 100644 --- a/fs/open.c +++ b/fs/open.c @@ -594,7 +594,7 @@ out: return error; } -asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) +SYSCALL_DEFINE2(fchmod, unsigned int, fd, mode_t, mode) { struct inode * inode; struct dentry * dentry; @@ -658,7 +658,7 @@ out: return error; } -asmlinkage long sys_chmod(const char __user *filename, mode_t mode) +SYSCALL_DEFINE2(chmod, const char __user *, filename, mode_t, mode) { return sys_fchmodat(AT_FDCWD, filename, mode); } -- cgit From 002c8976ee537724b20a5e179d9b349309438836 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:18 +0100 Subject: [CVE-2009-0029] System call wrappers part 16 Signed-off-by: Heiko Carstens --- fs/aio.c | 22 +++++++++++----------- fs/locks.c | 2 +- fs/open.c | 2 +- fs/read_write.c | 4 ++-- fs/stat.c | 4 ++-- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/fs/aio.c b/fs/aio.c index d6f89d3c15e..8fa77e23394 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -1270,7 +1270,7 @@ static void io_destroy(struct kioctx *ioctx) * pointer is passed for ctxp. Will fail with -ENOSYS if not * implemented. */ -asmlinkage long sys_io_setup(unsigned nr_events, aio_context_t __user *ctxp) +SYSCALL_DEFINE2(io_setup, unsigned, nr_events, aio_context_t __user *, ctxp) { struct kioctx *ioctx = NULL; unsigned long ctx; @@ -1308,7 +1308,7 @@ out: * implemented. May fail with -EFAULT if the context pointed to * is invalid. */ -asmlinkage long sys_io_destroy(aio_context_t ctx) +SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx) { struct kioctx *ioctx = lookup_ioctx(ctx); if (likely(NULL != ioctx)) { @@ -1662,8 +1662,8 @@ out_put_req: * are available to queue any iocbs. Will return 0 if nr is 0. Will * fail with -ENOSYS if not implemented. */ -asmlinkage long sys_io_submit(aio_context_t ctx_id, long nr, - struct iocb __user * __user *iocbpp) +SYSCALL_DEFINE3(io_submit, aio_context_t, ctx_id, long, nr, + struct iocb __user * __user *, iocbpp) { struct kioctx *ctx; long ret = 0; @@ -1737,8 +1737,8 @@ static struct kiocb *lookup_kiocb(struct kioctx *ctx, struct iocb __user *iocb, * invalid. May fail with -EAGAIN if the iocb specified was not * cancelled. Will fail with -ENOSYS if not implemented. */ -asmlinkage long sys_io_cancel(aio_context_t ctx_id, struct iocb __user *iocb, - struct io_event __user *result) +SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb, + struct io_event __user *, result) { int (*cancel)(struct kiocb *iocb, struct io_event *res); struct kioctx *ctx; @@ -1799,11 +1799,11 @@ asmlinkage long sys_io_cancel(aio_context_t ctx_id, struct iocb __user *iocb, * will be updated if not NULL and the operation blocks. Will fail * with -ENOSYS if not implemented. */ -asmlinkage long sys_io_getevents(aio_context_t ctx_id, - long min_nr, - long nr, - struct io_event __user *events, - struct timespec __user *timeout) +SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id, + long, min_nr, + long, nr, + struct io_event __user *, events, + struct timespec __user *, timeout) { struct kioctx *ioctx = lookup_ioctx(ctx_id); long ret = -EINVAL; diff --git a/fs/locks.c b/fs/locks.c index 46a2e12f7d4..ec3deea29e3 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1564,7 +1564,7 @@ EXPORT_SYMBOL(flock_lock_file_wait); * %LOCK_MAND can be combined with %LOCK_READ or %LOCK_WRITE to allow other * processes read and write access respectively. */ -asmlinkage long sys_flock(unsigned int fd, unsigned int cmd) +SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd) { struct file *filp; struct file_lock *lock; diff --git a/fs/open.c b/fs/open.c index ecc75a2c262..293408b1c16 100644 --- a/fs/open.c +++ b/fs/open.c @@ -1081,7 +1081,7 @@ asmlinkage long sys_openat(int dfd, const char __user *filename, int flags, * For backward compatibility? Maybe this should be moved * into arch/i386 instead? */ -asmlinkage long sys_creat(const char __user * pathname, int mode) +SYSCALL_DEFINE2(creat, const char __user *, pathname, int, mode) { return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode); } diff --git a/fs/read_write.c b/fs/read_write.c index 7a8326bc590..0671aa016b6 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -828,7 +828,7 @@ out: return retval; } -asmlinkage long sys_sendfile(int out_fd, int in_fd, off_t __user *offset, size_t count) +SYSCALL_DEFINE4(sendfile, int, out_fd, int, in_fd, off_t __user *, offset, size_t, count) { loff_t pos; off_t off; @@ -847,7 +847,7 @@ asmlinkage long sys_sendfile(int out_fd, int in_fd, off_t __user *offset, size_t return do_sendfile(out_fd, in_fd, NULL, count, 0); } -asmlinkage long sys_sendfile64(int out_fd, int in_fd, loff_t __user *offset, size_t count) +SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd, loff_t __user *, offset, size_t, count) { loff_t pos; ssize_t ret; diff --git a/fs/stat.c b/fs/stat.c index f29c5fe4f8b..d712a0dfb50 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -320,8 +320,8 @@ asmlinkage long sys_readlinkat(int dfd, const char __user *pathname, return error; } -asmlinkage long sys_readlink(const char __user *path, char __user *buf, - int bufsiz) +SYSCALL_DEFINE3(readlink, const char __user *, path, char __user *, buf, + int, bufsiz) { return sys_readlinkat(AT_FDCWD, path, buf, bufsiz); } -- cgit From ca013e945b1ba5828b151ee646946f1297b67a4c Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:19 +0100 Subject: [CVE-2009-0029] System call wrappers part 17 Signed-off-by: Heiko Carstens --- fs/open.c | 16 +++++++--------- kernel/uid16.c | 6 +++--- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/fs/open.c b/fs/open.c index 293408b1c16..4a6d8006474 100644 --- a/fs/open.c +++ b/fs/open.c @@ -517,7 +517,7 @@ out: return res; } -asmlinkage long sys_access(const char __user *filename, int mode) +SYSCALL_DEFINE2(access, const char __user *, filename, int, mode) { return sys_faccessat(AT_FDCWD, filename, mode); } @@ -688,7 +688,7 @@ static int chown_common(struct dentry * dentry, uid_t user, gid_t group) return error; } -asmlinkage long sys_chown(const char __user * filename, uid_t user, gid_t group) +SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group) { struct path path; int error; @@ -732,7 +732,7 @@ out: return error; } -asmlinkage long sys_lchown(const char __user * filename, uid_t user, gid_t group) +SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group) { struct path path; int error; @@ -751,8 +751,7 @@ out: return error; } - -asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group) +SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group) { struct file * file; int error = -EBADF; @@ -1048,7 +1047,7 @@ long do_sys_open(int dfd, const char __user *filename, int flags, int mode) return fd; } -asmlinkage long sys_open(const char __user *filename, int flags, int mode) +SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, int, mode) { long ret; @@ -1117,7 +1116,7 @@ EXPORT_SYMBOL(filp_close); * releasing the fd. This ensures that one clone task can't release * an fd while another clone is opening it. */ -asmlinkage long sys_close(unsigned int fd) +SYSCALL_DEFINE1(close, unsigned int, fd) { struct file * filp; struct files_struct *files = current->files; @@ -1150,14 +1149,13 @@ out_unlock: spin_unlock(&files->file_lock); return -EBADF; } - EXPORT_SYMBOL(sys_close); /* * This routine simulates a hangup on the tty, to arrange that users * are given clean terminals at login time. */ -asmlinkage long sys_vhangup(void) +SYSCALL_DEFINE0(vhangup) { if (capable(CAP_SYS_TTY_CONFIG)) { tty_vhangup_self(); diff --git a/kernel/uid16.c b/kernel/uid16.c index 2460c3199b5..37f48c049a2 100644 --- a/kernel/uid16.c +++ b/kernel/uid16.c @@ -17,7 +17,7 @@ #include -asmlinkage long sys_chown16(const char __user * filename, old_uid_t user, old_gid_t group) +SYSCALL_DEFINE3(chown16, const char __user *, filename, old_uid_t, user, old_gid_t, group) { long ret = sys_chown(filename, low2highuid(user), low2highgid(group)); /* avoid REGPARM breakage on x86: */ @@ -25,7 +25,7 @@ asmlinkage long sys_chown16(const char __user * filename, old_uid_t user, old_gi return ret; } -asmlinkage long sys_lchown16(const char __user * filename, old_uid_t user, old_gid_t group) +SYSCALL_DEFINE3(lchown16, const char __user *, filename, old_uid_t, user, old_gid_t, group) { long ret = sys_lchown(filename, low2highuid(user), low2highgid(group)); /* avoid REGPARM breakage on x86: */ @@ -33,7 +33,7 @@ asmlinkage long sys_lchown16(const char __user * filename, old_uid_t user, old_g return ret; } -asmlinkage long sys_fchown16(unsigned int fd, old_uid_t user, old_gid_t group) +SYSCALL_DEFINE3(fchown16, unsigned int, fd, old_uid_t, user, old_gid_t, group) { long ret = sys_fchown(fd, low2highuid(user), low2highgid(group)); /* avoid REGPARM breakage on x86: */ -- cgit From a6b42e83f249aad723589b2bdf6d1dfb2b0997c8 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:20 +0100 Subject: [CVE-2009-0029] System call wrappers part 18 Signed-off-by: Heiko Carstens --- kernel/uid16.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/kernel/uid16.c b/kernel/uid16.c index 37f48c049a2..221894e6e98 100644 --- a/kernel/uid16.c +++ b/kernel/uid16.c @@ -41,7 +41,7 @@ SYSCALL_DEFINE3(fchown16, unsigned int, fd, old_uid_t, user, old_gid_t, group) return ret; } -asmlinkage long sys_setregid16(old_gid_t rgid, old_gid_t egid) +SYSCALL_DEFINE2(setregid16, old_gid_t, rgid, old_gid_t, egid) { long ret = sys_setregid(low2highgid(rgid), low2highgid(egid)); /* avoid REGPARM breakage on x86: */ @@ -49,7 +49,7 @@ asmlinkage long sys_setregid16(old_gid_t rgid, old_gid_t egid) return ret; } -asmlinkage long sys_setgid16(old_gid_t gid) +SYSCALL_DEFINE1(setgid16, old_gid_t, gid) { long ret = sys_setgid(low2highgid(gid)); /* avoid REGPARM breakage on x86: */ @@ -57,7 +57,7 @@ asmlinkage long sys_setgid16(old_gid_t gid) return ret; } -asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid) +SYSCALL_DEFINE2(setreuid16, old_uid_t, ruid, old_uid_t, euid) { long ret = sys_setreuid(low2highuid(ruid), low2highuid(euid)); /* avoid REGPARM breakage on x86: */ @@ -65,7 +65,7 @@ asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid) return ret; } -asmlinkage long sys_setuid16(old_uid_t uid) +SYSCALL_DEFINE1(setuid16, old_uid_t, uid) { long ret = sys_setuid(low2highuid(uid)); /* avoid REGPARM breakage on x86: */ @@ -73,7 +73,7 @@ asmlinkage long sys_setuid16(old_uid_t uid) return ret; } -asmlinkage long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid) +SYSCALL_DEFINE3(setresuid16, old_uid_t, ruid, old_uid_t, euid, old_uid_t, suid) { long ret = sys_setresuid(low2highuid(ruid), low2highuid(euid), low2highuid(suid)); @@ -82,7 +82,7 @@ asmlinkage long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid) return ret; } -asmlinkage long sys_getresuid16(old_uid_t __user *ruid, old_uid_t __user *euid, old_uid_t __user *suid) +SYSCALL_DEFINE3(getresuid16, old_uid_t __user *, ruid, old_uid_t __user *, euid, old_uid_t __user *, suid) { const struct cred *cred = current_cred(); int retval; @@ -94,7 +94,7 @@ asmlinkage long sys_getresuid16(old_uid_t __user *ruid, old_uid_t __user *euid, return retval; } -asmlinkage long sys_setresgid16(old_gid_t rgid, old_gid_t egid, old_gid_t sgid) +SYSCALL_DEFINE3(setresgid16, old_gid_t, rgid, old_gid_t, egid, old_gid_t, sgid) { long ret = sys_setresgid(low2highgid(rgid), low2highgid(egid), low2highgid(sgid)); @@ -103,7 +103,8 @@ asmlinkage long sys_setresgid16(old_gid_t rgid, old_gid_t egid, old_gid_t sgid) return ret; } -asmlinkage long sys_getresgid16(old_gid_t __user *rgid, old_gid_t __user *egid, old_gid_t __user *sgid) + +SYSCALL_DEFINE3(getresgid16, old_gid_t __user *, rgid, old_gid_t __user *, egid, old_gid_t __user *, sgid) { const struct cred *cred = current_cred(); int retval; @@ -115,7 +116,7 @@ asmlinkage long sys_getresgid16(old_gid_t __user *rgid, old_gid_t __user *egid, return retval; } -asmlinkage long sys_setfsuid16(old_uid_t uid) +SYSCALL_DEFINE1(setfsuid16, old_uid_t, uid) { long ret = sys_setfsuid(low2highuid(uid)); /* avoid REGPARM breakage on x86: */ @@ -123,7 +124,7 @@ asmlinkage long sys_setfsuid16(old_uid_t uid) return ret; } -asmlinkage long sys_setfsgid16(old_gid_t gid) +SYSCALL_DEFINE1(setfsgid16, old_gid_t, gid) { long ret = sys_setfsgid(low2highgid(gid)); /* avoid REGPARM breakage on x86: */ -- cgit From 003d7ab479168132a2b2c6700fe682b08f08ab0c Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:21 +0100 Subject: [CVE-2009-0029] System call wrappers part 19 Signed-off-by: Heiko Carstens --- fs/read_write.c | 8 ++++---- fs/utimes.c | 5 +++-- kernel/uid16.c | 12 ++++++------ 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/fs/read_write.c b/fs/read_write.c index 0671aa016b6..fad10af59d9 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -147,7 +147,7 @@ loff_t vfs_llseek(struct file *file, loff_t offset, int origin) } EXPORT_SYMBOL(vfs_llseek); -asmlinkage long sys_lseek(unsigned int fd, off_t offset, unsigned int origin) +SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, origin) { off_t retval; struct file * file; @@ -171,9 +171,9 @@ bad: } #ifdef __ARCH_WANT_SYS_LLSEEK -asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high, - unsigned long offset_low, loff_t __user * result, - unsigned int origin) +SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high, + unsigned long, offset_low, loff_t __user *, result, + unsigned int, origin) { int retval; struct file * file; diff --git a/fs/utimes.c b/fs/utimes.c index 6929e3e91d0..ee853615798 100644 --- a/fs/utimes.c +++ b/fs/utimes.c @@ -24,7 +24,7 @@ * must be owner or have write permission. * Else, update from *times, must be owner or super user. */ -asmlinkage long sys_utime(char __user *filename, struct utimbuf __user *times) +SYSCALL_DEFINE2(utime, char __user *, filename, struct utimbuf __user *, times) { struct timespec tv[2]; @@ -214,7 +214,8 @@ asmlinkage long sys_futimesat(int dfd, char __user *filename, struct timeval __u return do_utimes(dfd, filename, utimes ? tstimes : NULL, 0); } -asmlinkage long sys_utimes(char __user *filename, struct timeval __user *utimes) +SYSCALL_DEFINE2(utimes, char __user *, filename, + struct timeval __user *, utimes) { return sys_futimesat(AT_FDCWD, filename, utimes); } diff --git a/kernel/uid16.c b/kernel/uid16.c index 221894e6e98..0314501688b 100644 --- a/kernel/uid16.c +++ b/kernel/uid16.c @@ -162,7 +162,7 @@ static int groups16_from_user(struct group_info *group_info, return 0; } -asmlinkage long sys_getgroups16(int gidsetsize, old_gid_t __user *grouplist) +SYSCALL_DEFINE2(getgroups16, int, gidsetsize, old_gid_t __user *, grouplist) { const struct cred *cred = current_cred(); int i; @@ -185,7 +185,7 @@ out: return i; } -asmlinkage long sys_setgroups16(int gidsetsize, old_gid_t __user *grouplist) +SYSCALL_DEFINE2(setgroups16, int, gidsetsize, old_gid_t __user *, grouplist) { struct group_info *group_info; int retval; @@ -210,22 +210,22 @@ asmlinkage long sys_setgroups16(int gidsetsize, old_gid_t __user *grouplist) return retval; } -asmlinkage long sys_getuid16(void) +SYSCALL_DEFINE0(getuid16) { return high2lowuid(current_uid()); } -asmlinkage long sys_geteuid16(void) +SYSCALL_DEFINE0(geteuid16) { return high2lowuid(current_euid()); } -asmlinkage long sys_getgid16(void) +SYSCALL_DEFINE0(getgid16) { return high2lowgid(current_gid()); } -asmlinkage long sys_getegid16(void) +SYSCALL_DEFINE0(getegid16) { return high2lowgid(current_egid()); } -- cgit From 3cdad42884bbd95d5aa01297e8236ea1bad70053 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:22 +0100 Subject: [CVE-2009-0029] System call wrappers part 20 Signed-off-by: Heiko Carstens --- fs/dcache.c | 2 +- fs/namei.c | 4 ++-- fs/open.c | 4 ++-- fs/quota.c | 3 ++- fs/read_write.c | 13 +++++++------ 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 4547f66884a..937df0fb0da 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -2092,7 +2092,7 @@ Elong: * return NULL; * } */ -asmlinkage long sys_getcwd(char __user *buf, unsigned long size) +SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size) { int error; struct path pwd, root; diff --git a/fs/namei.c b/fs/namei.c index 00c4f37a039..90520f05f99 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2081,7 +2081,7 @@ out_err: return error; } -asmlinkage long sys_mkdir(const char __user *pathname, int mode) +SYSCALL_DEFINE2(mkdir, const char __user *, pathname, int, mode) { return sys_mkdirat(AT_FDCWD, pathname, mode); } @@ -2195,7 +2195,7 @@ exit1: return error; } -asmlinkage long sys_rmdir(const char __user *pathname) +SYSCALL_DEFINE1(rmdir, const char __user *, pathname) { return do_rmdir(AT_FDCWD, pathname); } diff --git a/fs/open.c b/fs/open.c index 4a6d8006474..bc49e3c388d 100644 --- a/fs/open.c +++ b/fs/open.c @@ -522,7 +522,7 @@ SYSCALL_DEFINE2(access, const char __user *, filename, int, mode) return sys_faccessat(AT_FDCWD, filename, mode); } -asmlinkage long sys_chdir(const char __user * filename) +SYSCALL_DEFINE1(chdir, const char __user *, filename) { struct path path; int error; @@ -543,7 +543,7 @@ out: return error; } -asmlinkage long sys_fchdir(unsigned int fd) +SYSCALL_DEFINE1(fchdir, unsigned int, fd) { struct file *file; struct inode *inode; diff --git a/fs/quota.c b/fs/quota.c index 4a8c94f05f7..d76ada914f9 100644 --- a/fs/quota.c +++ b/fs/quota.c @@ -371,7 +371,8 @@ static inline struct super_block *quotactl_block(const char __user *special) * calls. Maybe we need to add the process quotas etc. in the future, * but we probably should use rlimits for that. */ -asmlinkage long sys_quotactl(unsigned int cmd, const char __user *special, qid_t id, void __user *addr) +SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special, + qid_t, id, void __user *, addr) { uint cmds, type; struct super_block *sb = NULL; diff --git a/fs/read_write.c b/fs/read_write.c index fad10af59d9..400fe81c973 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -369,7 +369,7 @@ static inline void file_pos_write(struct file *file, loff_t pos) file->f_pos = pos; } -asmlinkage long sys_read(unsigned int fd, char __user * buf, size_t count) +SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) { struct file *file; ssize_t ret = -EBADF; @@ -386,7 +386,8 @@ asmlinkage long sys_read(unsigned int fd, char __user * buf, size_t count) return ret; } -asmlinkage long sys_write(unsigned int fd, const char __user * buf, size_t count) +SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf, + size_t, count) { struct file *file; ssize_t ret = -EBADF; @@ -688,8 +689,8 @@ ssize_t vfs_writev(struct file *file, const struct iovec __user *vec, EXPORT_SYMBOL(vfs_writev); -asmlinkage long -sys_readv(unsigned long fd, const struct iovec __user *vec, unsigned long vlen) +SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec, + unsigned long, vlen) { struct file *file; ssize_t ret = -EBADF; @@ -709,8 +710,8 @@ sys_readv(unsigned long fd, const struct iovec __user *vec, unsigned long vlen) return ret; } -asmlinkage long -sys_writev(unsigned long fd, const struct iovec __user *vec, unsigned long vlen) +SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec, + unsigned long, vlen) { struct file *file; ssize_t ret = -EBADF; -- cgit From 20f37034fb966a1c35894f9fe529fda0b6440101 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:23 +0100 Subject: [CVE-2009-0029] System call wrappers part 21 Signed-off-by: Heiko Carstens --- fs/readdir.c | 6 ++++-- net/socket.c | 30 +++++++++++++++--------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/fs/readdir.c b/fs/readdir.c index 8b4c2a0051a..cf6a0e39819 100644 --- a/fs/readdir.c +++ b/fs/readdir.c @@ -187,7 +187,8 @@ efault: return -EFAULT; } -asmlinkage long sys_getdents(unsigned int fd, struct linux_dirent __user * dirent, unsigned int count) +SYSCALL_DEFINE3(getdents, unsigned int, fd, + struct linux_dirent __user *, dirent, unsigned int, count) { struct file * file; struct linux_dirent __user * lastdirent; @@ -268,7 +269,8 @@ efault: return -EFAULT; } -asmlinkage long sys_getdents64(unsigned int fd, struct linux_dirent64 __user * dirent, unsigned int count) +SYSCALL_DEFINE3(getdents64, unsigned int, fd, + struct linux_dirent64 __user *, dirent, unsigned int, count) { struct file * file; struct linux_dirent64 __user * lastdirent; diff --git a/net/socket.c b/net/socket.c index cc9b666e58f..fdd72c586a1 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1356,7 +1356,7 @@ out_fd1: * the protocol layer (having also checked the address is ok). */ -asmlinkage long sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen) +SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen) { struct socket *sock; struct sockaddr_storage address; @@ -1418,8 +1418,8 @@ asmlinkage long sys_listen(int fd, int backlog) * clean when we restucture accept also. */ -asmlinkage long sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr, - int __user *upeer_addrlen, int flags) +SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr, + int __user *, upeer_addrlen, int, flags) { struct socket *sock, *newsock; struct file *newfile; @@ -1502,8 +1502,8 @@ out_fd: goto out_put; } -asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, - int __user *upeer_addrlen) +SYSCALL_DEFINE3(accept, int, fd, struct sockaddr __user *, upeer_sockaddr, + int __user *, upeer_addrlen) { return sys_accept4(fd, upeer_sockaddr, upeer_addrlen, 0); } @@ -1520,8 +1520,8 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, * include the -EINPROGRESS status for such sockets. */ -asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr, - int addrlen) +SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr, + int, addrlen) { struct socket *sock; struct sockaddr_storage address; @@ -1552,8 +1552,8 @@ out: * name to user space. */ -asmlinkage long sys_getsockname(int fd, struct sockaddr __user *usockaddr, - int __user *usockaddr_len) +SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr, + int __user *, usockaddr_len) { struct socket *sock; struct sockaddr_storage address; @@ -1583,8 +1583,8 @@ out: * name to user space. */ -asmlinkage long sys_getpeername(int fd, struct sockaddr __user *usockaddr, - int __user *usockaddr_len) +SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr, + int __user *, usockaddr_len) { struct socket *sock; struct sockaddr_storage address; @@ -1725,8 +1725,8 @@ asmlinkage long sys_recv(int fd, void __user *ubuf, size_t size, * to pass the user mode parameter for the protocols to sort out. */ -asmlinkage long sys_setsockopt(int fd, int level, int optname, - char __user *optval, int optlen) +SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname, + char __user *, optval, int, optlen) { int err, fput_needed; struct socket *sock; @@ -1759,8 +1759,8 @@ out_put: * to pass a user mode parameter for the protocols to sort out. */ -asmlinkage long sys_getsockopt(int fd, int level, int optname, - char __user *optval, int __user *optlen) +SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname, + char __user *, optval, int __user *, optlen) { int err, fput_needed; struct socket *sock; -- cgit From 3e0fa65f8ba4fd24b3dcfaf14d5b15eaab0fdc61 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:24 +0100 Subject: [CVE-2009-0029] System call wrappers part 22 Signed-off-by: Heiko Carstens --- net/socket.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/net/socket.c b/net/socket.c index fdd72c586a1..35dd7371752 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1214,7 +1214,7 @@ int sock_create_kern(int family, int type, int protocol, struct socket **res) return __sock_create(&init_net, family, type, protocol, res, 1); } -asmlinkage long sys_socket(int family, int type, int protocol) +SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol) { int retval; struct socket *sock; @@ -1255,8 +1255,8 @@ out_release: * Create a pair of connected sockets. */ -asmlinkage long sys_socketpair(int family, int type, int protocol, - int __user *usockvec) +SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol, + int __user *, usockvec) { struct socket *sock1, *sock2; int fd1, fd2, err; @@ -1385,7 +1385,7 @@ SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen) * ready for listening. */ -asmlinkage long sys_listen(int fd, int backlog) +SYSCALL_DEFINE2(listen, int, fd, int, backlog) { struct socket *sock; int err, fput_needed; @@ -1615,9 +1615,9 @@ SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr, * the protocol. */ -asmlinkage long sys_sendto(int fd, void __user *buff, size_t len, - unsigned flags, struct sockaddr __user *addr, - int addr_len) +SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len, + unsigned, flags, struct sockaddr __user *, addr, + int, addr_len) { struct socket *sock; struct sockaddr_storage address; @@ -1660,7 +1660,8 @@ out: * Send a datagram down a socket. */ -asmlinkage long sys_send(int fd, void __user *buff, size_t len, unsigned flags) +SYSCALL_DEFINE4(send, int, fd, void __user *, buff, size_t, len, + unsigned, flags) { return sys_sendto(fd, buff, len, flags, NULL, 0); } @@ -1671,9 +1672,9 @@ asmlinkage long sys_send(int fd, void __user *buff, size_t len, unsigned flags) * sender address from kernel to user space. */ -asmlinkage long sys_recvfrom(int fd, void __user *ubuf, size_t size, - unsigned flags, struct sockaddr __user *addr, - int __user *addr_len) +SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size, + unsigned, flags, struct sockaddr __user *, addr, + int __user *, addr_len) { struct socket *sock; struct iovec iov; @@ -1815,7 +1816,7 @@ SYSCALL_DEFINE2(shutdown, int, fd, int, how) * BSD sendmsg interface */ -asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags) +SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags) { struct compat_msghdr __user *msg_compat = (struct compat_msghdr __user *)msg; @@ -1921,8 +1922,8 @@ out: * BSD recvmsg interface */ -asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, - unsigned int flags) +SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg, + unsigned int, flags) { struct compat_msghdr __user *msg_compat = (struct compat_msghdr __user *)msg; @@ -2045,7 +2046,7 @@ static const unsigned char nargs[19]={ * it is set by the callees. */ -asmlinkage long sys_socketcall(int call, unsigned long __user *args) +SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) { unsigned long a[6]; unsigned long a0, a1; -- cgit From 5a8a82b1d306a325d899b67715618413657efda4 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:25 +0100 Subject: [CVE-2009-0029] System call wrappers part 23 Signed-off-by: Heiko Carstens --- fs/eventpoll.c | 18 +++++++++--------- fs/select.c | 8 ++++---- kernel/sys.c | 6 +++--- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 96355d50534..ba2f9ec7119 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -1110,7 +1110,7 @@ retry: /* * Open an eventpoll file descriptor. */ -asmlinkage long sys_epoll_create1(int flags) +SYSCALL_DEFINE1(epoll_create1, int, flags) { int error, fd = -1; struct eventpoll *ep; @@ -1150,7 +1150,7 @@ error_return: return fd; } -asmlinkage long sys_epoll_create(int size) +SYSCALL_DEFINE1(epoll_create, int, size) { if (size < 0) return -EINVAL; @@ -1163,8 +1163,8 @@ asmlinkage long sys_epoll_create(int size) * the eventpoll file that enables the insertion/removal/change of * file descriptors inside the interest set. */ -asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, - struct epoll_event __user *event) +SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd, + struct epoll_event __user *, event) { int error; struct file *file, *tfile; @@ -1261,8 +1261,8 @@ error_return: * Implement the event wait interface for the eventpoll file. It is the kernel * part of the user space epoll_wait(2). */ -asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events, - int maxevents, int timeout) +SYSCALL_DEFINE4(epoll_wait, int, epfd, struct epoll_event __user *, events, + int, maxevents, int, timeout) { int error; struct file *file; @@ -1319,9 +1319,9 @@ error_return: * Implement the event wait interface for the eventpoll file. It is the kernel * part of the user space epoll_pwait(2). */ -asmlinkage long sys_epoll_pwait(int epfd, struct epoll_event __user *events, - int maxevents, int timeout, const sigset_t __user *sigmask, - size_t sigsetsize) +SYSCALL_DEFINE6(epoll_pwait, int, epfd, struct epoll_event __user *, events, + int, maxevents, int, timeout, const sigset_t __user *, sigmask, + size_t, sigsetsize) { int error; sigset_t ksigmask, sigsaved; diff --git a/fs/select.c b/fs/select.c index d1651648be1..338f703403a 100644 --- a/fs/select.c +++ b/fs/select.c @@ -557,8 +557,8 @@ out_nofds: return ret; } -asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp, - fd_set __user *exp, struct timeval __user *tvp) +SYSCALL_DEFINE5(select, int, n, fd_set __user *, inp, fd_set __user *, outp, + fd_set __user *, exp, struct timeval __user *, tvp) { struct timespec end_time, *to = NULL; struct timeval tv; @@ -854,8 +854,8 @@ static long do_restart_poll(struct restart_block *restart_block) return ret; } -asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds, - long timeout_msecs) +SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds, + long, timeout_msecs) { struct timespec end_time, *to = NULL; int ret; diff --git a/kernel/sys.c b/kernel/sys.c index 39b192b4003..5292f2119da 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -1406,7 +1406,7 @@ asmlinkage long sys_newuname(struct new_utsname __user * name) return errno; } -asmlinkage long sys_sethostname(char __user *name, int len) +SYSCALL_DEFINE2(sethostname, char __user *, name, int, len) { int errno; char tmp[__NEW_UTS_LEN]; @@ -1430,7 +1430,7 @@ asmlinkage long sys_sethostname(char __user *name, int len) #ifdef __ARCH_WANT_SYS_GETHOSTNAME -asmlinkage long sys_gethostname(char __user *name, int len) +SYSCALL_DEFINE2(gethostname, char __user *, name, int, len) { int i, errno; struct new_utsname *u; @@ -1455,7 +1455,7 @@ asmlinkage long sys_gethostname(char __user *name, int len) * Only setdomainname; getdomainname can be implemented by calling * uname() */ -asmlinkage long sys_setdomainname(char __user *name, int len) +SYSCALL_DEFINE2(setdomainname, char __user *, name, int, len) { int errno; char tmp[__NEW_UTS_LEN]; -- cgit From e48fbb699f82ef1e80bd7126046394d2dc9ca7e6 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:26 +0100 Subject: [CVE-2009-0029] System call wrappers part 24 Signed-off-by: Heiko Carstens --- ipc/msg.c | 12 ++++++------ kernel/sys.c | 13 +++++++------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/ipc/msg.c b/ipc/msg.c index b4eee1c6101..2ceab7f12fc 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -309,7 +309,7 @@ static inline int msg_security(struct kern_ipc_perm *ipcp, int msgflg) return security_msg_queue_associate(msq, msgflg); } -asmlinkage long sys_msgget(key_t key, int msgflg) +SYSCALL_DEFINE2(msgget, key_t, key, int, msgflg) { struct ipc_namespace *ns; struct ipc_ops msg_ops; @@ -466,7 +466,7 @@ out_up: return err; } -asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf) +SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf) { struct msg_queue *msq; int err, version; @@ -723,8 +723,8 @@ out_free: return err; } -asmlinkage long -sys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz, int msgflg) +SYSCALL_DEFINE4(msgsnd, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz, + int, msgflg) { long mtype; @@ -904,8 +904,8 @@ out_unlock: return msgsz; } -asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, - long msgtyp, int msgflg) +SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz, + long, msgtyp, int, msgflg) { long err, mtype; diff --git a/kernel/sys.c b/kernel/sys.c index 5292f2119da..70ffa8408cd 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -1395,7 +1395,7 @@ EXPORT_SYMBOL(in_egroup_p); DECLARE_RWSEM(uts_sem); -asmlinkage long sys_newuname(struct new_utsname __user * name) +SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name) { int errno = 0; @@ -1478,7 +1478,7 @@ SYSCALL_DEFINE2(setdomainname, char __user *, name, int, len) return errno; } -asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit __user *rlim) +SYSCALL_DEFINE2(getrlimit, unsigned int, resource, struct rlimit __user *, rlim) { if (resource >= RLIM_NLIMITS) return -EINVAL; @@ -1497,7 +1497,8 @@ asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit __user *rlim) * Back compatibility for getrlimit. Needed for some apps. */ -asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit __user *rlim) +SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource, + struct rlimit __user *, rlim) { struct rlimit x; if (resource >= RLIM_NLIMITS) @@ -1515,7 +1516,7 @@ asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit __user *r #endif -asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim) +SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim) { struct rlimit new_rlim, *old_rlim; int retval; @@ -1688,7 +1689,7 @@ int getrusage(struct task_struct *p, int who, struct rusage __user *ru) return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0; } -asmlinkage long sys_getrusage(int who, struct rusage __user *ru) +SYSCALL_DEFINE2(getrusage, int, who, struct rusage __user *, ru) { if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN && who != RUSAGE_THREAD) @@ -1696,7 +1697,7 @@ asmlinkage long sys_getrusage(int who, struct rusage __user *ru) return getrusage(current, who, ru); } -asmlinkage long sys_umask(int mask) +SYSCALL_DEFINE1(umask, int, mask) { mask = xchg(¤t->fs->umask, mask & S_IRWXUGO); return mask; -- cgit From d5460c9974a321a194aded4a8c4daaac68ea8171 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:27 +0100 Subject: [CVE-2009-0029] System call wrappers part 25 Signed-off-by: Heiko Carstens --- ipc/mqueue.c | 6 +++--- ipc/sem.c | 9 +++++---- ipc/shm.c | 8 ++++---- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 6df028b7054..faac04c85e7 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -650,8 +650,8 @@ static struct file *do_open(struct dentry *dentry, int oflag) return dentry_open(dentry, mqueue_mnt, oflag, cred); } -asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode, - struct mq_attr __user *u_attr) +SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode, + struct mq_attr __user *, u_attr) { struct dentry *dentry; struct file *filp; @@ -721,7 +721,7 @@ out_putname: return fd; } -asmlinkage long sys_mq_unlink(const char __user *u_name) +SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name) { int err; char *name; diff --git a/ipc/sem.c b/ipc/sem.c index c385c40c061..16a2189e96f 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -308,7 +308,7 @@ static inline int sem_more_checks(struct kern_ipc_perm *ipcp, return 0; } -asmlinkage long sys_semget(key_t key, int nsems, int semflg) +SYSCALL_DEFINE3(semget, key_t, key, int, nsems, int, semflg) { struct ipc_namespace *ns; struct ipc_ops sem_ops; @@ -1055,8 +1055,8 @@ out: return un; } -asmlinkage long sys_semtimedop(int semid, struct sembuf __user *tsops, - unsigned nsops, const struct timespec __user *timeout) +SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, + unsigned, nsops, const struct timespec __user *, timeout) { int error = -EINVAL; struct sem_array *sma; @@ -1232,7 +1232,8 @@ out_free: return error; } -asmlinkage long sys_semop (int semid, struct sembuf __user *tsops, unsigned nsops) +SYSCALL_DEFINE3(semop, int, semid, struct sembuf __user *, tsops, + unsigned, nsops) { return sys_semtimedop(semid, tsops, nsops, NULL); } diff --git a/ipc/shm.c b/ipc/shm.c index d0ab5527bf4..a9e09ad2263 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -440,7 +440,7 @@ static inline int shm_more_checks(struct kern_ipc_perm *ipcp, return 0; } -asmlinkage long sys_shmget (key_t key, size_t size, int shmflg) +SYSCALL_DEFINE3(shmget, key_t, key, size_t, size, int, shmflg) { struct ipc_namespace *ns; struct ipc_ops shm_ops; @@ -621,7 +621,7 @@ out_up: return err; } -asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf) +SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) { struct shmid_kernel *shp; int err, version; @@ -939,7 +939,7 @@ out_put_dentry: goto out_nattch; } -asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg) +SYSCALL_DEFINE3(shmat, int, shmid, char __user *, shmaddr, int, shmflg) { unsigned long ret; long err; @@ -955,7 +955,7 @@ asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg) * detach and kill segment if marked destroyed. * The work is done in shm_close. */ -asmlinkage long sys_shmdt(char __user *shmaddr) +SYSCALL_DEFINE1(shmdt, char __user *, shmaddr) { struct mm_struct *mm = current->mm; struct vm_area_struct *vma, *next; -- cgit From c4ea37c26a691ad0b7e86aa5884aab27830e95c9 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:28 +0100 Subject: [CVE-2009-0029] System call wrappers part 26 Signed-off-by: Heiko Carstens --- drivers/pci/syscall.c | 12 ++++-------- ipc/mqueue.c | 22 +++++++++++----------- kernel/sys.c | 4 ++-- mm/swapfile.c | 4 ++-- 4 files changed, 19 insertions(+), 23 deletions(-) diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c index 645d7a60e41..ec22284eed3 100644 --- a/drivers/pci/syscall.c +++ b/drivers/pci/syscall.c @@ -14,10 +14,8 @@ #include #include "pci.h" -asmlinkage long -sys_pciconfig_read(unsigned long bus, unsigned long dfn, - unsigned long off, unsigned long len, - void __user *buf) +SYSCALL_DEFINE5(pciconfig_read, unsigned long, bus, unsigned long, dfn, + unsigned long, off, unsigned long, len, void __user *, buf) { struct pci_dev *dev; u8 byte; @@ -86,10 +84,8 @@ error: return err; } -asmlinkage long -sys_pciconfig_write(unsigned long bus, unsigned long dfn, - unsigned long off, unsigned long len, - void __user *buf) +SYSCALL_DEFINE5(pciconfig_write, unsigned long, bus, unsigned long, dfn, + unsigned long, off, unsigned long, len, void __user *, buf) { struct pci_dev *dev; u8 byte; diff --git a/ipc/mqueue.c b/ipc/mqueue.c index faac04c85e7..54b4077fed7 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -814,9 +814,9 @@ static inline void pipelined_receive(struct mqueue_inode_info *info) sender->state = STATE_READY; } -asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr, - size_t msg_len, unsigned int msg_prio, - const struct timespec __user *u_abs_timeout) +SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr, + size_t, msg_len, unsigned int, msg_prio, + const struct timespec __user *, u_abs_timeout) { struct file *filp; struct inode *inode; @@ -907,9 +907,9 @@ out: return ret; } -asmlinkage long sys_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr, - size_t msg_len, unsigned int __user *u_msg_prio, - const struct timespec __user *u_abs_timeout) +SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr, + size_t, msg_len, unsigned int __user *, u_msg_prio, + const struct timespec __user *, u_abs_timeout) { long timeout; ssize_t ret; @@ -997,8 +997,8 @@ out: * and he isn't currently owner of notification, will be silently discarded. * It isn't explicitly defined in the POSIX. */ -asmlinkage long sys_mq_notify(mqd_t mqdes, - const struct sigevent __user *u_notification) +SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes, + const struct sigevent __user *, u_notification) { int ret; struct file *filp; @@ -1123,9 +1123,9 @@ out: return ret; } -asmlinkage long sys_mq_getsetattr(mqd_t mqdes, - const struct mq_attr __user *u_mqstat, - struct mq_attr __user *u_omqstat) +SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mqdes, + const struct mq_attr __user *, u_mqstat, + struct mq_attr __user *, u_omqstat) { int ret; struct mq_attr mqstat, omqstat; diff --git a/kernel/sys.c b/kernel/sys.c index 70ffa8408cd..59aadcdad6c 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -1703,8 +1703,8 @@ SYSCALL_DEFINE1(umask, int, mask) return mask; } -asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, - unsigned long arg4, unsigned long arg5) +SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, + unsigned long, arg4, unsigned long, arg5) { struct task_struct *me = current; unsigned char comm[sizeof(me->comm)]; diff --git a/mm/swapfile.c b/mm/swapfile.c index da422c47e2e..f48b831e5e5 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -1377,7 +1377,7 @@ out: return ret; } -asmlinkage long sys_swapoff(const char __user * specialfile) +SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) { struct swap_info_struct * p = NULL; unsigned short *swap_map; @@ -1633,7 +1633,7 @@ late_initcall(max_swapfiles_check); * * The swapon system call */ -asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags) +SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) { struct swap_info_struct * p; char *name = NULL; -- cgit From 1e7bfb2134dfec37ce04fb3a4ca89299e892d10c Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:29 +0100 Subject: [CVE-2009-0029] System call wrappers part 27 Signed-off-by: Heiko Carstens --- fs/exec.c | 2 +- fs/filesystems.c | 2 +- fs/nfsctl.c | 4 ++-- kernel/printk.c | 2 +- kernel/ptrace.c | 2 +- kernel/sysctl.c | 4 ++-- kernel/timer.c | 2 +- security/keys/keyctl.c | 18 +++++++++--------- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/fs/exec.c b/fs/exec.c index 71a6efe5d8b..0dd60a01f1b 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -99,7 +99,7 @@ static inline void put_binfmt(struct linux_binfmt * fmt) * * Also note that we take the address to load from from the file itself. */ -asmlinkage long sys_uselib(const char __user * library) +SYSCALL_DEFINE1(uselib, const char __user *, library) { struct file *file; struct nameidata nd; diff --git a/fs/filesystems.c b/fs/filesystems.c index d488dcd7f2b..1aa70260e6d 100644 --- a/fs/filesystems.c +++ b/fs/filesystems.c @@ -179,7 +179,7 @@ static int fs_maxindex(void) /* * Whee.. Weird sysv syscall. */ -asmlinkage long sys_sysfs(int option, unsigned long arg1, unsigned long arg2) +SYSCALL_DEFINE3(sysfs, int, option, unsigned long, arg1, unsigned long, arg2) { int retval = -EINVAL; diff --git a/fs/nfsctl.c b/fs/nfsctl.c index b27451909df..8f9a20556f7 100644 --- a/fs/nfsctl.c +++ b/fs/nfsctl.c @@ -86,8 +86,8 @@ static struct { }, }; -long -asmlinkage sys_nfsservctl(int cmd, struct nfsctl_arg __user *arg, void __user *res) +SYSCALL_DEFINE3(nfsservctl, int, cmd, struct nfsctl_arg __user *, arg, + void __user *, res) { struct file *file; void __user *p = &arg->u; diff --git a/kernel/printk.c b/kernel/printk.c index e48cf33783f..69188f226a9 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -382,7 +382,7 @@ out: return error; } -asmlinkage long sys_syslog(int type, char __user *buf, int len) +SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) { return do_syslog(type, buf, len); } diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 29dc700e198..c9cf48b21f0 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -574,7 +574,7 @@ struct task_struct *ptrace_get_task_struct(pid_t pid) #define arch_ptrace_attach(child) do { } while (0) #endif -asmlinkage long sys_ptrace(long request, long pid, long addr, long data) +SYSCALL_DEFINE4(ptrace, long, request, long, pid, long, addr, long, data) { struct task_struct *child; long ret; diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 89d74436318..3e38b74b612 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -1688,7 +1688,7 @@ int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *ol return error; } -asmlinkage long sys_sysctl(struct __sysctl_args __user *args) +SYSCALL_DEFINE1(sysctl, struct __sysctl_args __user *, args) { struct __sysctl_args tmp; int error; @@ -2989,7 +2989,7 @@ int sysctl_ms_jiffies(struct ctl_table *table, #else /* CONFIG_SYSCTL_SYSCALL */ -asmlinkage long sys_sysctl(struct __sysctl_args __user *args) +SYSCALL_DEFINE1(sysctl, struct __sysctl_args __user *, args) { struct __sysctl_args tmp; int error; diff --git a/kernel/timer.c b/kernel/timer.c index 14a51530a4c..13dd64fe143 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -1400,7 +1400,7 @@ out: return 0; } -asmlinkage long sys_sysinfo(struct sysinfo __user *info) +SYSCALL_DEFINE1(sysinfo, struct sysinfo __user *, info) { struct sysinfo val; diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 09796797d12..070a53eab80 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -54,11 +54,11 @@ static int key_get_type_from_user(char *type, * - returns the new key's serial number * - implements add_key() */ -asmlinkage long sys_add_key(const char __user *_type, - const char __user *_description, - const void __user *_payload, - size_t plen, - key_serial_t ringid) +SYSCALL_DEFINE5(add_key, const char __user *, _type, + const char __user *, _description, + const void __user *, _payload, + size_t, plen, + key_serial_t, ringid) { key_ref_t keyring_ref, key_ref; char type[32], *description; @@ -146,10 +146,10 @@ asmlinkage long sys_add_key(const char __user *_type, * - if the _callout_info string is empty, it will be rendered as "-" * - implements request_key() */ -asmlinkage long sys_request_key(const char __user *_type, - const char __user *_description, - const char __user *_callout_info, - key_serial_t destringid) +SYSCALL_DEFINE4(request_key, const char __user *, _type, + const char __user *, _description, + const char __user *, _callout_info, + key_serial_t, destringid) { struct key_type *ktype; struct key *key; -- cgit From 938bb9f5e840eddbf54e4f62f6c5ba9b3ae12c9d Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:30 +0100 Subject: [CVE-2009-0029] System call wrappers part 28 Signed-off-by: Heiko Carstens --- fs/ioprio.c | 5 ++--- fs/notify/inotify/inotify_user.c | 4 ++-- mm/mempolicy.c | 24 +++++++++++------------- mm/migrate.c | 8 ++++---- security/keys/keyctl.c | 4 ++-- 5 files changed, 21 insertions(+), 24 deletions(-) diff --git a/fs/ioprio.c b/fs/ioprio.c index 1a39ac37094..c7c0b28d7d2 100644 --- a/fs/ioprio.c +++ b/fs/ioprio.c @@ -72,7 +72,7 @@ int set_task_ioprio(struct task_struct *task, int ioprio) } EXPORT_SYMBOL_GPL(set_task_ioprio); -asmlinkage long sys_ioprio_set(int which, int who, int ioprio) +SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio) { int class = IOPRIO_PRIO_CLASS(ioprio); int data = IOPRIO_PRIO_DATA(ioprio); @@ -188,7 +188,7 @@ int ioprio_best(unsigned short aprio, unsigned short bprio) return aprio; } -asmlinkage long sys_ioprio_get(int which, int who) +SYSCALL_DEFINE2(ioprio_get, int, which, int, who) { struct task_struct *g, *p; struct user_struct *user; @@ -252,4 +252,3 @@ asmlinkage long sys_ioprio_get(int which, int who) read_unlock(&tasklist_lock); return ret; } - diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index 81b8644b013..efef1ffca77 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c @@ -576,7 +576,7 @@ static const struct inotify_operations inotify_user_ops = { .destroy_watch = free_inotify_user_watch, }; -asmlinkage long sys_inotify_init1(int flags) +SYSCALL_DEFINE1(inotify_init1, int, flags) { struct inotify_device *dev; struct inotify_handle *ih; @@ -655,7 +655,7 @@ out_put_fd: return ret; } -asmlinkage long sys_inotify_init(void) +SYSCALL_DEFINE0(inotify_init) { return sys_inotify_init1(0); } diff --git a/mm/mempolicy.c b/mm/mempolicy.c index e412ffa8e52..3eb4a6fdc04 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -1068,10 +1068,9 @@ static int copy_nodes_to_user(unsigned long __user *mask, unsigned long maxnode, return copy_to_user(mask, nodes_addr(*nodes), copy) ? -EFAULT : 0; } -asmlinkage long sys_mbind(unsigned long start, unsigned long len, - unsigned long mode, - unsigned long __user *nmask, unsigned long maxnode, - unsigned flags) +SYSCALL_DEFINE6(mbind, unsigned long, start, unsigned long, len, + unsigned long, mode, unsigned long __user *, nmask, + unsigned long, maxnode, unsigned, flags) { nodemask_t nodes; int err; @@ -1091,8 +1090,8 @@ asmlinkage long sys_mbind(unsigned long start, unsigned long len, } /* Set the process memory policy */ -asmlinkage long sys_set_mempolicy(int mode, unsigned long __user *nmask, - unsigned long maxnode) +SYSCALL_DEFINE3(set_mempolicy, int, mode, unsigned long __user *, nmask, + unsigned long, maxnode) { int err; nodemask_t nodes; @@ -1110,9 +1109,9 @@ asmlinkage long sys_set_mempolicy(int mode, unsigned long __user *nmask, return do_set_mempolicy(mode, flags, &nodes); } -asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode, - const unsigned long __user *old_nodes, - const unsigned long __user *new_nodes) +SYSCALL_DEFINE4(migrate_pages, pid_t, pid, unsigned long, maxnode, + const unsigned long __user *, old_nodes, + const unsigned long __user *, new_nodes) { const struct cred *cred = current_cred(), *tcred; struct mm_struct *mm; @@ -1185,10 +1184,9 @@ out: /* Retrieve NUMA policy */ -asmlinkage long sys_get_mempolicy(int __user *policy, - unsigned long __user *nmask, - unsigned long maxnode, - unsigned long addr, unsigned long flags) +SYSCALL_DEFINE5(get_mempolicy, int __user *, policy, + unsigned long __user *, nmask, unsigned long, maxnode, + unsigned long, addr, unsigned long, flags) { int err; int uninitialized_var(pval); diff --git a/mm/migrate.c b/mm/migrate.c index a30ea5fcf9f..2bb4e1d6352 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -1055,10 +1055,10 @@ out: * Move a list of pages in the address space of the currently executing * process. */ -asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages, - const void __user * __user *pages, - const int __user *nodes, - int __user *status, int flags) +SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages, + const void __user * __user *, pages, + const int __user *, nodes, + int __user *, status, int, flags) { const struct cred *cred = current_cred(), *tcred; struct task_struct *task; diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 070a53eab80..e9335e1c6cf 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -1216,8 +1216,8 @@ long keyctl_get_security(key_serial_t keyid, /* * the key control system call */ -asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3, - unsigned long arg4, unsigned long arg5) +SYSCALL_DEFINE5(keyctl, int, option, unsigned long, arg2, unsigned long, arg3, + unsigned long, arg4, unsigned long, arg5) { switch (option) { case KEYCTL_GET_KEYRING_ID: -- cgit From 2e4d0924eb0c403ce4014fa139d1d61bf2c44fee Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:31 +0100 Subject: [CVE-2009-0029] System call wrappers part 29 Signed-off-by: Heiko Carstens --- fs/namei.c | 21 ++++++++++----------- fs/notify/inotify/inotify_user.c | 5 +++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 90520f05f99..bbc15c23755 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1962,8 +1962,8 @@ static int may_mknod(mode_t mode) } } -asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode, - unsigned dev) +SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, int, mode, + unsigned, dev) { int error; char *tmp; @@ -2044,7 +2044,7 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) return error; } -asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode) +SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, int, mode) { int error = 0; char * tmp; @@ -2291,7 +2291,7 @@ slashes: goto exit2; } -asmlinkage long sys_unlinkat(int dfd, const char __user *pathname, int flag) +SYSCALL_DEFINE3(unlinkat, int, dfd, const char __user *, pathname, int, flag) { if ((flag & ~AT_REMOVEDIR) != 0) return -EINVAL; @@ -2328,8 +2328,8 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) return error; } -asmlinkage long sys_symlinkat(const char __user *oldname, - int newdfd, const char __user *newname) +SYSCALL_DEFINE3(symlinkat, const char __user *, oldname, + int, newdfd, const char __user *, newname) { int error; char *from; @@ -2422,9 +2422,8 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de * with linux 2.0, and to avoid hard-linking to directories * and other special files. --ADM */ -asmlinkage long sys_linkat(int olddfd, const char __user *oldname, - int newdfd, const char __user *newname, - int flags) +SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname, + int, newdfd, const char __user *, newname, int, flags) { struct dentry *new_dentry; struct nameidata nd; @@ -2624,8 +2623,8 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, return error; } -asmlinkage long sys_renameat(int olddfd, const char __user *oldname, - int newdfd, const char __user *newname) +SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname, + int, newdfd, const char __user *, newname) { struct dentry *old_dir, *new_dir; struct dentry *old_dentry, *new_dentry; diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index efef1ffca77..d53a1838d6e 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c @@ -660,7 +660,8 @@ SYSCALL_DEFINE0(inotify_init) return sys_inotify_init1(0); } -asmlinkage long sys_inotify_add_watch(int fd, const char __user *pathname, u32 mask) +SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname, + u32, mask) { struct inode *inode; struct inotify_device *dev; @@ -704,7 +705,7 @@ fput_and_out: return ret; } -asmlinkage long sys_inotify_rm_watch(int fd, __s32 wd) +SYSCALL_DEFINE2(inotify_rm_watch, int, fd, __s32, wd) { struct file *filp; struct inotify_device *dev; -- cgit From 6559eed8ca7db0531a207cd80be5e28cd6f213c5 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:32 +0100 Subject: [CVE-2009-0029] System call wrappers part 30 Signed-off-by: Heiko Carstens --- fs/open.c | 13 ++++++------- fs/stat.c | 12 ++++++------ fs/utimes.c | 6 ++++-- kernel/fork.c | 2 +- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/fs/open.c b/fs/open.c index bc49e3c388d..a3a78ceb2a2 100644 --- a/fs/open.c +++ b/fs/open.c @@ -447,7 +447,7 @@ SYSCALL_ALIAS(sys_fallocate, SyS_fallocate); * We do this by temporarily clearing all FS-related capabilities and * switching the fsuid/fsgid around to the real ones. */ -asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode) +SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode) { const struct cred *old_cred; struct cred *override_cred; @@ -628,8 +628,7 @@ out: return err; } -asmlinkage long sys_fchmodat(int dfd, const char __user *filename, - mode_t mode) +SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, mode_t, mode) { struct path path; struct inode *inode; @@ -707,8 +706,8 @@ out: return error; } -asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user, - gid_t group, int flag) +SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user, + gid_t, group, int, flag) { struct path path; int error = -EINVAL; @@ -1060,8 +1059,8 @@ SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, int, mode) return ret; } -asmlinkage long sys_openat(int dfd, const char __user *filename, int flags, - int mode) +SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, flags, + int, mode) { long ret; diff --git a/fs/stat.c b/fs/stat.c index d712a0dfb50..2db740a0cfb 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -260,8 +260,8 @@ SYSCALL_DEFINE2(newlstat, char __user *, filename, struct stat __user *, statbuf } #if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT) -asmlinkage long sys_newfstatat(int dfd, char __user *filename, - struct stat __user *statbuf, int flag) +SYSCALL_DEFINE4(newfstatat, int, dfd, char __user *, filename, + struct stat __user *, statbuf, int, flag) { struct kstat stat; int error = -EINVAL; @@ -293,8 +293,8 @@ SYSCALL_DEFINE2(newfstat, unsigned int, fd, struct stat __user *, statbuf) return error; } -asmlinkage long sys_readlinkat(int dfd, const char __user *pathname, - char __user *buf, int bufsiz) +SYSCALL_DEFINE4(readlinkat, int, dfd, const char __user *, pathname, + char __user *, buf, int, bufsiz) { struct path path; int error; @@ -400,8 +400,8 @@ SYSCALL_DEFINE2(fstat64, unsigned long, fd, struct stat64 __user *, statbuf) return error; } -asmlinkage long sys_fstatat64(int dfd, char __user *filename, - struct stat64 __user *statbuf, int flag) +SYSCALL_DEFINE4(fstatat64, int, dfd, char __user *, filename, + struct stat64 __user *, statbuf, int, flag) { struct kstat stat; int error = -EINVAL; diff --git a/fs/utimes.c b/fs/utimes.c index ee853615798..e4c75db5d37 100644 --- a/fs/utimes.c +++ b/fs/utimes.c @@ -170,7 +170,8 @@ out: return error; } -asmlinkage long sys_utimensat(int dfd, char __user *filename, struct timespec __user *utimes, int flags) +SYSCALL_DEFINE4(utimensat, int, dfd, char __user *, filename, + struct timespec __user *, utimes, int, flags) { struct timespec tstimes[2]; @@ -187,7 +188,8 @@ asmlinkage long sys_utimensat(int dfd, char __user *filename, struct timespec __ return do_utimes(dfd, filename, utimes ? tstimes : NULL, flags); } -asmlinkage long sys_futimesat(int dfd, char __user *filename, struct timeval __user *utimes) +SYSCALL_DEFINE3(futimesat, int, dfd, char __user *, filename, + struct timeval __user *, utimes) { struct timeval times[2]; struct timespec tstimes[2]; diff --git a/kernel/fork.c b/kernel/fork.c index 8eb37d38c6a..bf0cef8bbdf 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1603,7 +1603,7 @@ static int unshare_fd(unsigned long unshare_flags, struct files_struct **new_fdp * constructed. Here we are modifying the current, active, * task_struct. */ -asmlinkage long sys_unshare(unsigned long unshare_flags) +SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags) { int err = 0; struct fs_struct *fs, *new_fs = NULL; -- cgit From 836f92adf121f806e9beb5b6b88bd5c9c4ea3f24 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:33 +0100 Subject: [CVE-2009-0029] System call wrappers part 31 Signed-off-by: Heiko Carstens --- fs/signalfd.c | 8 ++++---- fs/splice.c | 12 ++++++------ fs/timerfd.c | 8 ++++---- kernel/futex.c | 11 +++++------ kernel/sys.c | 4 ++-- 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/fs/signalfd.c b/fs/signalfd.c index 9c39bc7f843..b07565c9438 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c @@ -205,8 +205,8 @@ static const struct file_operations signalfd_fops = { .read = signalfd_read, }; -asmlinkage long sys_signalfd4(int ufd, sigset_t __user *user_mask, - size_t sizemask, int flags) +SYSCALL_DEFINE4(signalfd4, int, ufd, sigset_t __user *, user_mask, + size_t, sizemask, int, flags) { sigset_t sigmask; struct signalfd_ctx *ctx; @@ -259,8 +259,8 @@ asmlinkage long sys_signalfd4(int ufd, sigset_t __user *user_mask, return ufd; } -asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, - size_t sizemask) +SYSCALL_DEFINE3(signalfd, int, ufd, sigset_t __user *, user_mask, + size_t, sizemask) { return sys_signalfd4(ufd, user_mask, sizemask, 0); } diff --git a/fs/splice.c b/fs/splice.c index a54b3e3f10a..4ed0ba44a96 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -1435,8 +1435,8 @@ static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov, * Currently we punt and implement it as a normal copy, see pipe_to_user(). * */ -asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov, - unsigned long nr_segs, unsigned int flags) +SYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, iov, + unsigned long, nr_segs, unsigned int, flags) { struct file *file; long error; @@ -1461,9 +1461,9 @@ asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov, return error; } -asmlinkage long sys_splice(int fd_in, loff_t __user *off_in, - int fd_out, loff_t __user *off_out, - size_t len, unsigned int flags) +SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in, + int, fd_out, loff_t __user *, off_out, + size_t, len, unsigned int, flags) { long error; struct file *in, *out; @@ -1685,7 +1685,7 @@ static long do_tee(struct file *in, struct file *out, size_t len, return ret; } -asmlinkage long sys_tee(int fdin, int fdout, size_t len, unsigned int flags) +SYSCALL_DEFINE4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags) { struct file *in; int error, fput_in; diff --git a/fs/timerfd.c b/fs/timerfd.c index 0862f0e49d0..c8c14f58b96 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c @@ -177,7 +177,7 @@ static struct file *timerfd_fget(int fd) return file; } -asmlinkage long sys_timerfd_create(int clockid, int flags) +SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) { int ufd; struct timerfd_ctx *ctx; @@ -208,9 +208,9 @@ asmlinkage long sys_timerfd_create(int clockid, int flags) return ufd; } -asmlinkage long sys_timerfd_settime(int ufd, int flags, - const struct itimerspec __user *utmr, - struct itimerspec __user *otmr) +SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, + const struct itimerspec __user *, utmr, + struct itimerspec __user *, otmr) { struct file *file; struct timerfd_ctx *ctx; diff --git a/kernel/futex.c b/kernel/futex.c index e86931d8d4e..f89d373a9c6 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -1733,9 +1733,8 @@ pi_faulted: * @head: pointer to the list-head * @len: length of the list-head, as userspace expects */ -asmlinkage long -sys_set_robust_list(struct robust_list_head __user *head, - size_t len) +SYSCALL_DEFINE2(set_robust_list, struct robust_list_head __user *, head, + size_t, len) { if (!futex_cmpxchg_enabled) return -ENOSYS; @@ -1756,9 +1755,9 @@ sys_set_robust_list(struct robust_list_head __user *head, * @head_ptr: pointer to a list-head pointer, the kernel fills it in * @len_ptr: pointer to a length field, the kernel fills in the header size */ -asmlinkage long -sys_get_robust_list(int pid, struct robust_list_head __user * __user *head_ptr, - size_t __user *len_ptr) +SYSCALL_DEFINE3(get_robust_list, int, pid, + struct robust_list_head __user * __user *, head_ptr, + size_t __user *, len_ptr) { struct robust_list_head __user *head; unsigned long ret; diff --git a/kernel/sys.c b/kernel/sys.c index 59aadcdad6c..e7dc0e10a48 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -1817,8 +1817,8 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, return error; } -asmlinkage long sys_getcpu(unsigned __user *cpup, unsigned __user *nodep, - struct getcpu_cache __user *unused) +SYSCALL_DEFINE3(getcpu, unsigned __user *, cpup, unsigned __user *, nodep, + struct getcpu_cache __user *, unused) { int err = 0; int cpu = raw_smp_processor_id(); -- cgit From d4e82042c4cfa87a7d51710b71f568fe80132551 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:34 +0100 Subject: [CVE-2009-0029] System call wrappers part 32 Signed-off-by: Heiko Carstens --- fs/eventfd.c | 5 ++--- fs/pipe.c | 2 +- fs/readdir.c | 3 ++- fs/select.c | 11 ++++++----- fs/timerfd.c | 2 +- include/linux/syscalls.h | 7 +++++++ kernel/signal.c | 11 +++++------ 7 files changed, 24 insertions(+), 17 deletions(-) diff --git a/fs/eventfd.c b/fs/eventfd.c index 08bf558d040..5de2c2db3aa 100644 --- a/fs/eventfd.c +++ b/fs/eventfd.c @@ -198,7 +198,7 @@ struct file *eventfd_fget(int fd) return file; } -asmlinkage long sys_eventfd2(unsigned int count, int flags) +SYSCALL_DEFINE2(eventfd2, unsigned int, count, int, flags) { int fd; struct eventfd_ctx *ctx; @@ -228,8 +228,7 @@ asmlinkage long sys_eventfd2(unsigned int count, int flags) return fd; } -asmlinkage long sys_eventfd(unsigned int count) +SYSCALL_DEFINE1(eventfd, unsigned int, count) { return sys_eventfd2(count, 0); } - diff --git a/fs/pipe.c b/fs/pipe.c index 0c64db86c91..b89c878588a 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -1043,7 +1043,7 @@ int do_pipe(int *fd) * sys_pipe() is the normal C calling standard for creating * a pipe. It's not the way Unix traditionally does this, though. */ -asmlinkage long sys_pipe2(int __user *fildes, int flags) +SYSCALL_DEFINE2(pipe2, int __user *, fildes, int, flags) { int fd[2]; int error; diff --git a/fs/readdir.c b/fs/readdir.c index cf6a0e39819..7723401f8d8 100644 --- a/fs/readdir.c +++ b/fs/readdir.c @@ -102,7 +102,8 @@ efault: return -EFAULT; } -asmlinkage long sys_old_readdir(unsigned int fd, struct old_linux_dirent __user * dirent, unsigned int count) +SYSCALL_DEFINE3(old_readdir, unsigned int, fd, + struct old_linux_dirent __user *, dirent, unsigned int, count) { int error; struct file * file; diff --git a/fs/select.c b/fs/select.c index 338f703403a..0fe0e1469df 100644 --- a/fs/select.c +++ b/fs/select.c @@ -636,8 +636,9 @@ static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp, * which has a pointer to the sigset_t itself followed by a size_t containing * the sigset size. */ -asmlinkage long sys_pselect6(int n, fd_set __user *inp, fd_set __user *outp, - fd_set __user *exp, struct timespec __user *tsp, void __user *sig) +SYSCALL_DEFINE6(pselect6, int, n, fd_set __user *, inp, fd_set __user *, outp, + fd_set __user *, exp, struct timespec __user *, tsp, + void __user *, sig) { size_t sigsetsize = 0; sigset_t __user *up = NULL; @@ -889,9 +890,9 @@ SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds, } #ifdef HAVE_SET_RESTORE_SIGMASK -asmlinkage long sys_ppoll(struct pollfd __user *ufds, unsigned int nfds, - struct timespec __user *tsp, const sigset_t __user *sigmask, - size_t sigsetsize) +SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds, + struct timespec __user *, tsp, const sigset_t __user *, sigmask, + size_t, sigsetsize) { sigset_t ksigmask, sigsaved; struct timespec ts, end_time, *to = NULL; diff --git a/fs/timerfd.c b/fs/timerfd.c index c8c14f58b96..6a123b8ff3f 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c @@ -265,7 +265,7 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, return 0; } -asmlinkage long sys_timerfd_gettime(int ufd, struct itimerspec __user *otmr) +SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr) { struct file *file; struct timerfd_ctx *ctx; diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 90aa5eba87a..56c400138b0 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -678,6 +678,13 @@ asmlinkage long sys_eventfd(unsigned int count); asmlinkage long sys_eventfd2(unsigned int count, int flags); asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len); asmlinkage long sys_old_readdir(unsigned int, struct old_linux_dirent __user *, unsigned int); +asmlinkage long sys_pselect6(int, fd_set __user *, fd_set __user *, + fd_set __user *, struct timespec __user *, + void __user *); +asmlinkage long sys_ppoll(struct pollfd __user *, unsigned int, + struct timespec __user *, const sigset_t __user *, + size_t); +asmlinkage long sys_pipe2(int __user *, int); int kernel_execve(const char *filename, char *const argv[], char *const envp[]); diff --git a/kernel/signal.c b/kernel/signal.c index e2333929611..e73759783dc 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2491,11 +2491,10 @@ out: #endif /* __ARCH_WANT_SYS_SIGPROCMASK */ #ifdef __ARCH_WANT_SYS_RT_SIGACTION -asmlinkage long -sys_rt_sigaction(int sig, - const struct sigaction __user *act, - struct sigaction __user *oact, - size_t sigsetsize) +SYSCALL_DEFINE4(rt_sigaction, int, sig, + const struct sigaction __user *, act, + struct sigaction __user *, oact, + size_t, sigsetsize) { struct k_sigaction new_sa, old_sa; int ret = -EINVAL; @@ -2578,7 +2577,7 @@ SYSCALL_DEFINE0(pause) #endif #ifdef __ARCH_WANT_SYS_RT_SIGSUSPEND -asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize) +SYSCALL_DEFINE2(rt_sigsuspend, sigset_t __user *, unewset, size_t, sigsetsize) { sigset_t newset; -- cgit From 2b66421995d2e93c9d1a0111acf2581f8529c6e5 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:35 +0100 Subject: [CVE-2009-0029] System call wrappers part 33 Signed-off-by: Heiko Carstens --- fs/pipe.c | 2 +- include/linux/syscalls.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/pipe.c b/fs/pipe.c index b89c878588a..3a48ba5179d 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -1059,7 +1059,7 @@ SYSCALL_DEFINE2(pipe2, int __user *, fildes, int, flags) return error; } -asmlinkage long sys_pipe(int __user *fildes) +SYSCALL_DEFINE1(pipe, int __user *, fildes) { return sys_pipe2(fildes, 0); } diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 56c400138b0..16875f89e6a 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -685,6 +685,7 @@ asmlinkage long sys_ppoll(struct pollfd __user *, unsigned int, struct timespec __user *, const sigset_t __user *, size_t); asmlinkage long sys_pipe2(int __user *, int); +asmlinkage long sys_pipe(int __user *); int kernel_execve(const char *filename, char *const argv[], char *const envp[]); -- cgit From 26689452f5ca201add63b1b1ff0dbcf82d6885e7 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 14 Jan 2009 14:14:36 +0100 Subject: [CVE-2009-0029] s390 specific system call wrappers Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_wrapper.S | 4 ++-- arch/s390/kernel/entry.h | 15 ++++++++------- arch/s390/kernel/process.c | 9 +++++---- arch/s390/kernel/signal.c | 19 ++++++++----------- arch/s390/kernel/sys_s390.c | 35 +++++++++++++++++++++-------------- arch/s390/kernel/syscalls.S | 12 ++++++------ 6 files changed, 50 insertions(+), 44 deletions(-) diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index fc2c97197a5..6035cd20c7a 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -547,7 +547,7 @@ sys32_setdomainname_wrapper: .globl sys32_newuname_wrapper sys32_newuname_wrapper: llgtr %r2,%r2 # struct new_utsname * - jg s390x_newuname # branch to system call + jg sys_s390_newuname # branch to system call .globl compat_sys_adjtimex_wrapper compat_sys_adjtimex_wrapper: @@ -615,7 +615,7 @@ sys32_sysfs_wrapper: .globl sys32_personality_wrapper sys32_personality_wrapper: llgfr %r2,%r2 # unsigned long - jg s390x_personality # branch to system call + jg sys_s390_personality # branch to system call .globl sys32_setfsuid16_wrapper sys32_setfsuid16_wrapper: diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h index 5c9b5b37004..950c59c6688 100644 --- a/arch/s390/kernel/entry.h +++ b/arch/s390/kernel/entry.h @@ -31,21 +31,22 @@ struct old_sigaction; struct sel_arg_struct; long sys_mmap2(struct mmap_arg_struct __user *arg); -long old_mmap(struct mmap_arg_struct __user *arg); +long sys_s390_old_mmap(struct mmap_arg_struct __user *arg); long sys_ipc(uint call, int first, unsigned long second, unsigned long third, void __user *ptr); -long s390x_newuname(struct new_utsname __user *name); -long s390x_personality(unsigned long personality); -long s390_fadvise64(int fd, u32 offset_high, u32 offset_low, +long sys_s390_newuname(struct new_utsname __user *name); +long sys_s390_personality(unsigned long personality); +long sys_s390_fadvise64(int fd, u32 offset_high, u32 offset_low, size_t len, int advice); -long s390_fadvise64_64(struct fadvise64_64_args __user *args); -long s390_fallocate(int fd, int mode, loff_t offset, u32 len_high, u32 len_low); +long sys_s390_fadvise64_64(struct fadvise64_64_args __user *args); +long sys_s390_fallocate(int fd, int mode, loff_t offset, u32 len_high, + u32 len_low); long sys_fork(void); long sys_clone(void); long sys_vfork(void); void execve_tail(void); long sys_execve(void); -int sys_sigsuspend(int history0, int history1, old_sigset_t mask); +long sys_sigsuspend(int history0, int history1, old_sigset_t mask); long sys_sigaction(int sig, const struct old_sigaction __user *act, struct old_sigaction __user *oact); long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss); diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index b6110bdf8dc..5cd38a90e64 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -225,13 +226,13 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp, return 0; } -asmlinkage long sys_fork(void) +SYSCALL_DEFINE0(fork) { struct pt_regs *regs = task_pt_regs(current); return do_fork(SIGCHLD, regs->gprs[15], regs, 0, NULL, NULL); } -asmlinkage long sys_clone(void) +SYSCALL_DEFINE0(clone) { struct pt_regs *regs = task_pt_regs(current); unsigned long clone_flags; @@ -258,7 +259,7 @@ asmlinkage long sys_clone(void) * do not have enough call-clobbered registers to hold all * the information you need. */ -asmlinkage long sys_vfork(void) +SYSCALL_DEFINE0(vfork) { struct pt_regs *regs = task_pt_regs(current); return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, @@ -278,7 +279,7 @@ asmlinkage void execve_tail(void) /* * sys_execve() executes a new program. */ -asmlinkage long sys_execve(void) +SYSCALL_DEFINE0(execve) { struct pt_regs *regs = task_pt_regs(current); char *filename; diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 8e6812a2267..3cf74c3ccb6 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -53,8 +54,7 @@ typedef struct /* * Atomically swap in the new signal mask, and wait for a signal. */ -asmlinkage int -sys_sigsuspend(int history0, int history1, old_sigset_t mask) +SYSCALL_DEFINE3(sigsuspend, int, history0, int, history1, old_sigset_t, mask) { mask &= _BLOCKABLE; spin_lock_irq(¤t->sighand->siglock); @@ -70,9 +70,8 @@ sys_sigsuspend(int history0, int history1, old_sigset_t mask) return -ERESTARTNOHAND; } -asmlinkage long -sys_sigaction(int sig, const struct old_sigaction __user *act, - struct old_sigaction __user *oact) +SYSCALL_DEFINE3(sigaction, int, sig, const struct old_sigaction __user *, act, + struct old_sigaction __user *, oact) { struct k_sigaction new_ka, old_ka; int ret; @@ -102,15 +101,13 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, return ret; } -asmlinkage long -sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) +SYSCALL_DEFINE2(sigaltstack, const stack_t __user *, uss, + stack_t __user *, uoss) { struct pt_regs *regs = task_pt_regs(current); return do_sigaltstack(uss, uoss, regs->gprs[15]); } - - /* Returns non-zero on fault. */ static int save_sigregs(struct pt_regs *regs, _sigregs __user *sregs) { @@ -164,7 +161,7 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs) return 0; } -asmlinkage long sys_sigreturn(void) +SYSCALL_DEFINE0(sigreturn) { struct pt_regs *regs = task_pt_regs(current); sigframe __user *frame = (sigframe __user *)regs->gprs[15]; @@ -191,7 +188,7 @@ badframe: return 0; } -asmlinkage long sys_rt_sigreturn(void) +SYSCALL_DEFINE0(rt_sigreturn) { struct pt_regs *regs = task_pt_regs(current); rt_sigframe __user *frame = (rt_sigframe __user *)regs->gprs[15]; diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c index c34be4568b8..c7ae4b17e0e 100644 --- a/arch/s390/kernel/sys_s390.c +++ b/arch/s390/kernel/sys_s390.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "entry.h" @@ -74,7 +75,7 @@ struct mmap_arg_struct { unsigned long offset; }; -asmlinkage long sys_mmap2(struct mmap_arg_struct __user *arg) +SYSCALL_DEFINE1(mmap2, struct mmap_arg_struct __user *, arg) { struct mmap_arg_struct a; int error = -EFAULT; @@ -86,7 +87,7 @@ out: return error; } -asmlinkage long old_mmap(struct mmap_arg_struct __user *arg) +SYSCALL_DEFINE1(s390_old_mmap, struct mmap_arg_struct __user *, arg) { struct mmap_arg_struct a; long error = -EFAULT; @@ -108,8 +109,8 @@ out: * * This is really horribly ugly. */ -asmlinkage long sys_ipc(uint call, int first, unsigned long second, - unsigned long third, void __user *ptr) +SYSCALL_DEFINE5(ipc, uint, call, int, first, unsigned long, second, + unsigned long, third, void __user *, ptr) { struct ipc_kludge tmp; int ret; @@ -175,7 +176,7 @@ asmlinkage long sys_ipc(uint call, int first, unsigned long second, } #ifdef CONFIG_64BIT -asmlinkage long s390x_newuname(struct new_utsname __user *name) +SYSCALL_DEFINE1(s390_newuname, struct new_utsname __user *, name) { int ret = sys_newuname(name); @@ -186,7 +187,7 @@ asmlinkage long s390x_newuname(struct new_utsname __user *name) return ret; } -asmlinkage long s390x_personality(unsigned long personality) +SYSCALL_DEFINE1(s390_personality, unsigned long, personality) { int ret; @@ -205,15 +206,13 @@ asmlinkage long s390x_personality(unsigned long personality) */ #ifndef CONFIG_64BIT -asmlinkage long -s390_fadvise64(int fd, u32 offset_high, u32 offset_low, size_t len, int advice) +SYSCALL_DEFINE5(s390_fadvise64, int, fd, u32, offset_high, u32, offset_low, + size_t, len, int, advice) { return sys_fadvise64(fd, (u64) offset_high << 32 | offset_low, len, advice); } -#endif - struct fadvise64_64_args { int fd; long long offset; @@ -221,8 +220,7 @@ struct fadvise64_64_args { int advice; }; -asmlinkage long -s390_fadvise64_64(struct fadvise64_64_args __user *args) +SYSCALL_DEFINE1(s390_fadvise64_64, struct fadvise64_64_args __user *, args) { struct fadvise64_64_args a; @@ -231,7 +229,6 @@ s390_fadvise64_64(struct fadvise64_64_args __user *args) return sys_fadvise64_64(a.fd, a.offset, a.len, a.advice); } -#ifndef CONFIG_64BIT /* * This is a wrapper to call sys_fallocate(). For 31 bit s390 the last * 64 bit argument "len" is split into the upper and lower 32 bits. The @@ -244,9 +241,19 @@ s390_fadvise64_64(struct fadvise64_64_args __user *args) * to * %r2: fd, %r3: mode, %r4/%r5: offset, 96(%r15)-103(%r15): len */ -asmlinkage long s390_fallocate(int fd, int mode, loff_t offset, +SYSCALL_DEFINE(s390_fallocate)(int fd, int mode, loff_t offset, u32 len_high, u32 len_low) { return sys_fallocate(fd, mode, offset, ((u64)len_high << 32) | len_low); } +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_s390_fallocate(long fd, long mode, loff_t offset, + long len_high, long len_low) +{ + return SYSC_s390_fallocate((int) fd, (int) mode, offset, + (u32) len_high, (u32) len_low); +} +SYSCALL_ALIAS(sys_s390_fallocate, SyS_s390_fallocate); +#endif + #endif diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 2d61787949d..76d16e0140b 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -98,7 +98,7 @@ SYSCALL(sys_uselib,sys_uselib,sys32_uselib_wrapper) SYSCALL(sys_swapon,sys_swapon,sys32_swapon_wrapper) SYSCALL(sys_reboot,sys_reboot,sys32_reboot_wrapper) SYSCALL(sys_ni_syscall,sys_ni_syscall,old32_readdir_wrapper) /* old readdir syscall */ -SYSCALL(old_mmap,old_mmap,old32_mmap_wrapper) /* 90 */ +SYSCALL(sys_s390_old_mmap,sys_s390_old_mmap,old32_mmap_wrapper) /* 90 */ SYSCALL(sys_munmap,sys_munmap,sys32_munmap_wrapper) SYSCALL(sys_truncate,sys_truncate,sys32_truncate_wrapper) SYSCALL(sys_ftruncate,sys_ftruncate,sys32_ftruncate_wrapper) @@ -130,7 +130,7 @@ SYSCALL(sys_fsync,sys_fsync,sys32_fsync_wrapper) SYSCALL(sys_sigreturn,sys_sigreturn,sys32_sigreturn) SYSCALL(sys_clone,sys_clone,sys32_clone) /* 120 */ SYSCALL(sys_setdomainname,sys_setdomainname,sys32_setdomainname_wrapper) -SYSCALL(sys_newuname,s390x_newuname,sys32_newuname_wrapper) +SYSCALL(sys_newuname,sys_s390_newuname,sys32_newuname_wrapper) NI_SYSCALL /* modify_ldt for i386 */ SYSCALL(sys_adjtimex,sys_adjtimex,compat_sys_adjtimex_wrapper) SYSCALL(sys_mprotect,sys_mprotect,sys32_mprotect_wrapper) /* 125 */ @@ -144,7 +144,7 @@ SYSCALL(sys_getpgid,sys_getpgid,sys32_getpgid_wrapper) SYSCALL(sys_fchdir,sys_fchdir,sys32_fchdir_wrapper) SYSCALL(sys_bdflush,sys_bdflush,sys32_bdflush_wrapper) SYSCALL(sys_sysfs,sys_sysfs,sys32_sysfs_wrapper) /* 135 */ -SYSCALL(sys_personality,s390x_personality,sys32_personality_wrapper) +SYSCALL(sys_personality,sys_s390_personality,sys32_personality_wrapper) NI_SYSCALL /* for afs_syscall */ SYSCALL(sys_setfsuid16,sys_ni_syscall,sys32_setfsuid16_wrapper) /* old setfsuid16 syscall */ SYSCALL(sys_setfsgid16,sys_ni_syscall,sys32_setfsgid16_wrapper) /* old setfsgid16 syscall */ @@ -261,7 +261,7 @@ SYSCALL(sys_epoll_create,sys_epoll_create,sys_epoll_create_wrapper) SYSCALL(sys_epoll_ctl,sys_epoll_ctl,sys_epoll_ctl_wrapper) /* 250 */ SYSCALL(sys_epoll_wait,sys_epoll_wait,sys_epoll_wait_wrapper) SYSCALL(sys_set_tid_address,sys_set_tid_address,sys32_set_tid_address_wrapper) -SYSCALL(s390_fadvise64,sys_fadvise64_64,sys32_fadvise64_wrapper) +SYSCALL(sys_s390_fadvise64,sys_fadvise64_64,sys32_fadvise64_wrapper) SYSCALL(sys_timer_create,sys_timer_create,sys32_timer_create_wrapper) SYSCALL(sys_timer_settime,sys_timer_settime,sys32_timer_settime_wrapper) /* 255 */ SYSCALL(sys_timer_gettime,sys_timer_gettime,sys32_timer_gettime_wrapper) @@ -272,7 +272,7 @@ SYSCALL(sys_clock_gettime,sys_clock_gettime,sys32_clock_gettime_wrapper) /* 260 SYSCALL(sys_clock_getres,sys_clock_getres,sys32_clock_getres_wrapper) SYSCALL(sys_clock_nanosleep,sys_clock_nanosleep,sys32_clock_nanosleep_wrapper) NI_SYSCALL /* reserved for vserver */ -SYSCALL(s390_fadvise64_64,sys_ni_syscall,sys32_fadvise64_64_wrapper) +SYSCALL(sys_s390_fadvise64_64,sys_ni_syscall,sys32_fadvise64_64_wrapper) SYSCALL(sys_statfs64,sys_statfs64,compat_sys_statfs64_wrapper) SYSCALL(sys_fstatfs64,sys_fstatfs64,compat_sys_fstatfs64_wrapper) SYSCALL(sys_remap_file_pages,sys_remap_file_pages,sys32_remap_file_pages_wrapper) @@ -322,7 +322,7 @@ NI_SYSCALL /* 310 sys_move_pages */ SYSCALL(sys_getcpu,sys_getcpu,sys_getcpu_wrapper) SYSCALL(sys_epoll_pwait,sys_epoll_pwait,compat_sys_epoll_pwait_wrapper) SYSCALL(sys_utimes,sys_utimes,compat_sys_utimes_wrapper) -SYSCALL(s390_fallocate,sys_fallocate,sys_fallocate_wrapper) +SYSCALL(sys_s390_fallocate,sys_fallocate,sys_fallocate_wrapper) SYSCALL(sys_utimensat,sys_utimensat,compat_sys_utimensat_wrapper) /* 315 */ SYSCALL(sys_signalfd,sys_signalfd,compat_sys_signalfd_wrapper) NI_SYSCALL /* 317 old sys_timer_fd */ -- cgit From 2465fb6605b4f8f3964b132017bf4078d1265fe9 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 14 Jan 2009 15:58:55 +0100 Subject: ALSA: hda - Fix missing initialization of NID 0x0e for STAC925x The selector widget 0x0e isn't initialized properly in the whole probe process, thus it can be a wrong value depending on the BIOS setup. This patch adds the init verb to set it to the max & unmuted. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 25230f4c888..6d9a4a2aa4a 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -884,6 +884,8 @@ static struct hda_verb stac92hd71bxx_analog_core_init[] = { static struct hda_verb stac925x_core_init[] = { /* set dac0mux for dac converter */ { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00}, + /* unmute and set max the selector */ + { 0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb07f }, {} }; -- cgit From 18e6959c385f3edf3991fa6662a53dac4eb10d5b Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Wed, 14 Jan 2009 07:28:16 +0100 Subject: mm: fix assertion This assertion is incorrect for lockless pagecache. By definition if we have an unpinned page that we are trying to take a speculative reference to, it may become the tail of a compound page at any time (if it is freed, then reallocated as a compound page). It was still a valid assertion for the vmscan.c LRU isolation case, but it doesn't seem incredibly helpful... if somebody wants it, they can put it back directly where it applies in the vmscan code. Signed-off-by: Nick Piggin Signed-off-by: Linus Torvalds --- include/linux/mm.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index b91a73fd1bc..e8ddc98b840 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -260,7 +260,6 @@ static inline int put_page_testzero(struct page *page) */ static inline int get_page_unless_zero(struct page *page) { - VM_BUG_ON(PageTail(page)); return atomic_inc_not_zero(&page->_count); } -- cgit From 9316fcacb89c59fe556c48587ac02cd7f5d38045 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 14 Jan 2009 09:35:44 -0800 Subject: kernel/up.c: omit it if SMP=y, USE_GENERIC_SMP_HELPERS=n Fix the sparc build - we were including `up.o' on SMP builds, when CONFIG_USE_GENERIC_SMP_HELPERS=n. Tested-by: Robert Reif Fixed-by: Robert Reif Cc: David Miller Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/Makefile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/kernel/Makefile b/kernel/Makefile index 2aebc4cd787..170a9213c1b 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -40,9 +40,8 @@ obj-$(CONFIG_RT_MUTEXES) += rtmutex.o obj-$(CONFIG_DEBUG_RT_MUTEXES) += rtmutex-debug.o obj-$(CONFIG_RT_MUTEX_TESTER) += rtmutex-tester.o obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o -ifeq ($(CONFIG_USE_GENERIC_SMP_HELPERS),y) -obj-y += smp.o -else +obj-$(CONFIG_USE_GENERIC_SMP_HELPERS) += smp.o +ifneq ($(CONFIG_SMP),y) obj-y += up.o endif obj-$(CONFIG_SMP) += spinlock.o -- cgit From 9b896033aa2781d36b2d3f756fe70325fc8487e2 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 14 Jan 2009 19:19:02 +0100 Subject: ide: fix accidental LOCKDEP breakage caused by local_irq_set() removal commit 54cc1428cfa619e16d75baae8cb041a2eff015f0 ("ide: remove local_irq_set() macro") accidentally replaced local_save_flags() by local_irq_set() in ide_probe_port() and __ide_wait_stat() which resulted in LOCKDEP breakage. Reported-by: Larry Finger Tested-by: Larry Finger Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-iops.c | 2 +- drivers/ide/ide-probe.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index e728cfe7273..753b92ebe0a 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -493,7 +493,7 @@ static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long ti stat = tp_ops->read_status(hwif); if (stat & ATA_BUSY) { - local_irq_save(flags); + local_save_flags(flags); local_irq_enable_in_hardirq(); timeout += jiffies; while ((stat = tp_ops->read_status(hwif)) & ATA_BUSY) { diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 0ccbb4459fb..312127ea443 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -796,7 +796,7 @@ static int ide_probe_port(ide_hwif_t *hwif) if (irqd) disable_irq(hwif->irq); - local_irq_save(flags); + local_save_flags(flags); local_irq_enable_in_hardirq(); if (ide_port_wait_ready(hwif) == -EBUSY) -- cgit From b94b898f3107046b5c97c556e23529283ea5eadd Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Wed, 14 Jan 2009 19:19:02 +0100 Subject: it821x: Add ultra_mask quirk for Vortex86SX On Vortex86SX with IDE controller revision 0x11 ultra DMA must be disabled. This patch was tested by DMP and seems to work. It is a cleaned up version of their older Kernel patch: http://www.dmp.com.tw/tech/vortex86sx/patch-2.6.24-DMP.gz Tested-by: Shawn Lin Signed-off-by: Brandon Philips Cc: Alan Cox Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/it821x.c | 12 ++++++++++++ include/linux/pci_ids.h | 1 + 2 files changed, 13 insertions(+) diff --git a/drivers/ide/it821x.c b/drivers/ide/it821x.c index 0be27ac1f07..983440a9a5f 100644 --- a/drivers/ide/it821x.c +++ b/drivers/ide/it821x.c @@ -68,6 +68,8 @@ #define DRV_NAME "it821x" +#define QUIRK_VORTEX86 1 + struct it821x_dev { unsigned int smart:1, /* Are we in smart raid mode */ @@ -79,6 +81,7 @@ struct it821x_dev u16 pio[2]; /* Cached PIO values */ u16 mwdma[2]; /* Cached MWDMA values */ u16 udma[2]; /* Cached UDMA values (per drive) */ + u16 quirks; }; #define ATA_66 0 @@ -577,6 +580,12 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif) hwif->ultra_mask = ATA_UDMA6; hwif->mwdma_mask = ATA_MWDMA2; + + /* Vortex86SX quirk: prevent Ultra-DMA mode to fix BadCRC issue */ + if (idev->quirks & QUIRK_VORTEX86) { + if (dev->revision == 0x11) + hwif->ultra_mask = 0; + } } static void it8212_disable_raid(struct pci_dev *dev) @@ -649,6 +658,8 @@ static int __devinit it821x_init_one(struct pci_dev *dev, const struct pci_devic return -ENOMEM; } + itdevs->quirks = id->driver_data; + rc = ide_pci_init_one(dev, &it821x_chipset, itdevs); if (rc) kfree(itdevs); @@ -668,6 +679,7 @@ static void __devexit it821x_remove(struct pci_dev *dev) static const struct pci_device_id it821x_pci_tbl[] = { { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8211), 0 }, { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8212), 0 }, + { PCI_VDEVICE(RDC, PCI_DEVICE_ID_RDC_D1010), QUIRK_VORTEX86 }, { 0, }, }; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index d543365518a..d56ad9c21c0 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2174,6 +2174,7 @@ #define PCI_DEVICE_ID_RDC_R6040 0x6040 #define PCI_DEVICE_ID_RDC_R6060 0x6060 #define PCI_DEVICE_ID_RDC_R6061 0x6061 +#define PCI_DEVICE_ID_RDC_D1010 0x1010 #define PCI_VENDOR_ID_LENOVO 0x17aa -- cgit From 4a2462693b37da1438f53f3fbfc75e081659e975 Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Wed, 14 Jan 2009 19:19:03 +0100 Subject: it821x.c: use dev->revision instead of pci_read_config_byte Minor cleanup. Signed-off-by: Brandon Philips Cc: Alan Cox Cc: Shawn Lin Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/it821x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/ide/it821x.c b/drivers/ide/it821x.c index 983440a9a5f..e1c4f543739 100644 --- a/drivers/ide/it821x.c +++ b/drivers/ide/it821x.c @@ -560,8 +560,7 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif) * this is necessary. */ - pci_read_config_byte(dev, 0x08, &conf); - if (conf == 0x10) { + if (dev->revision == 0x10) { idev->timing10 = 1; hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA; if (idev->smart == 0) -- cgit From 655772cc79c94ebf282e1df4d3c3375f05a565ae Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 14 Jan 2009 19:19:03 +0100 Subject: ide: can't use SSD/non-rotational queue flag for all CFA devices Some rotating disks also present themselves as CFA devices. Reported-by: Alan Cox Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-disk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 4088a622873..806760d24ce 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -633,7 +633,7 @@ static void ide_disk_setup(ide_drive_t *drive) printk(KERN_INFO "%s: max request size: %dKiB\n", drive->name, q->max_sectors / 2); - if (ata_id_is_ssd(id) || ata_id_is_cfa(id)) + if (ata_id_is_ssd(id)) queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q); /* calculate drive capacity, and select LBA if possible */ -- cgit From 4180e8334cf8301cf37131bc5d69c0cd724682cb Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 14 Jan 2009 19:19:03 +0100 Subject: via82cxxx: fix cable warning message Remove reference to the removed old-style kernel parameter. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/via82cxxx.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c index fecc0e03c3f..703c3eeb20a 100644 --- a/drivers/ide/via82cxxx.c +++ b/drivers/ide/via82cxxx.c @@ -432,8 +432,6 @@ static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_i if (via_clock < 20000 || via_clock > 50000) { printk(KERN_WARNING DRV_NAME ": User given PCI clock speed " "impossible (%d), using 33 MHz instead.\n", via_clock); - printk(KERN_WARNING DRV_NAME ": Use ide0=ata66 if you want " - "to assume 80-wire cable.\n"); via_clock = 33333; } -- cgit From cadb300a4254b1f28bce84e280b7d46c525f73c6 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 14 Jan 2009 19:19:03 +0100 Subject: sl82c105: remove dead code CONFIG_LOPEC and CONFIG_SANDPOINT config options are gone. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/sl82c105.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/ide/sl82c105.c b/drivers/ide/sl82c105.c index 48cc748c504..6297956507c 100644 --- a/drivers/ide/sl82c105.c +++ b/drivers/ide/sl82c105.c @@ -310,10 +310,6 @@ static const struct ide_port_info sl82c105_chipset __devinitdata = { .dma_ops = &sl82c105_dma_ops, .host_flags = IDE_HFLAG_IO_32BIT | IDE_HFLAG_UNMASK_IRQS | -/* FIXME: check for Compatibility mode in generic IDE PCI code */ -#if defined(CONFIG_LOPEC) || defined(CONFIG_SANDPOINT) - IDE_HFLAG_FORCE_LEGACY_IRQS | -#endif IDE_HFLAG_SERIALIZE_DMA | IDE_HFLAG_NO_AUTODMA, .pio_mask = ATA_PIO5, -- cgit From e86c1451d3138b4cd0378282b30397d171fa4252 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 14 Jan 2009 19:19:03 +0100 Subject: ide: remove unused CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- Documentation/mips/AU1xxx_IDE.README | 6 +----- drivers/ide/Kconfig | 5 ----- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/Documentation/mips/AU1xxx_IDE.README b/Documentation/mips/AU1xxx_IDE.README index f54962aea84..8ace35ebdcd 100644 --- a/Documentation/mips/AU1xxx_IDE.README +++ b/Documentation/mips/AU1xxx_IDE.README @@ -52,14 +52,12 @@ Two files are introduced: b) 'drivers/ide/mips/au1xxx-ide.c' contains the functionality of the AU1XXX IDE driver -Four configs variables are introduced: +Following extra configs variables are introduced: CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA - enable the PIO+DBDMA mode CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA - enable the MWDMA mode CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON - set Burstable FIFO in DBDMA controller - CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ - maximum transfer size - per descriptor SUPPORTED IDE MODES @@ -87,7 +85,6 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y CONFIG_IDEDMA_PCI_AUTO=y CONFIG_BLK_DEV_IDE_AU1XXX=y CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA=y -CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ=128 CONFIG_BLK_DEV_IDEDMA=y CONFIG_IDEDMA_AUTO=y @@ -105,7 +102,6 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y CONFIG_IDEDMA_PCI_AUTO=y CONFIG_BLK_DEV_IDE_AU1XXX=y CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA=y -CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ=128 CONFIG_BLK_DEV_IDEDMA=y CONFIG_IDEDMA_AUTO=y diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 3f9503867e6..b1c6f68d98c 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -701,11 +701,6 @@ config BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA depends on SOC_AU1200 && BLK_DEV_IDE_AU1XXX endchoice -config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ - int "Maximum transfer size (KB) per request (up to 128)" - default "128" - depends on BLK_DEV_IDE_AU1XXX - config BLK_DEV_IDE_TX4938 tristate "TX4938 internal IDE support" depends on SOC_TX4938 -- cgit From a294d97742568f429590cf2022d92e4b0c5f6ba0 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Wed, 14 Jan 2009 19:19:04 +0100 Subject: tx4938ide: Fix build error due to read_sff_dma_status moving Signed-off-by: Atsushi Nemoto Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/tx4938ide.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/ide/tx4938ide.c b/drivers/ide/tx4938ide.c index b4ef218072c..d9095345f7c 100644 --- a/drivers/ide/tx4938ide.c +++ b/drivers/ide/tx4938ide.c @@ -202,7 +202,6 @@ static const struct ide_tp_ops tx4938ide_tp_ops = { .exec_command = ide_exec_command, .read_status = ide_read_status, .read_altstatus = ide_read_altstatus, - .read_sff_dma_status = ide_read_sff_dma_status, .set_irq = ide_set_irq, -- cgit From 2ea5521022ac8f4f528dcbae02668e02a3501a5a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 14 Jan 2009 19:19:04 +0100 Subject: ide: fix suspend regression MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Monday 12 January 2009, Simon Holm Thøgersen wrote: > commit 295f000 ("ide: don't execute the next queued command from the > hard-IRQ context (v2)") breaks suspend to disk for me. On > 'echo disk > /sys/power/state' the systems hangs, letting me switch > virtual consoles, but not responding to Alt+SysRq Restart the request queue early for REQ_TYPE_PM_RESUME requests (though there is only one resume request for the whole resume sequence it stays in the queue until is fully completed and now depends on kblockd for processing consequential resume states). Reported-and-bisected-by: Simon Holm Thøgersen Tested-by: Simon Holm Thøgersen Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-pm.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/ide/ide-pm.c b/drivers/ide/ide-pm.c index 4b3bf6a06b7..60538d9c84e 100644 --- a/drivers/ide/ide-pm.c +++ b/drivers/ide/ide-pm.c @@ -186,12 +186,10 @@ void ide_complete_pm_request(ide_drive_t *drive, struct request *rq) blk_pm_suspend_request(rq) ? "suspend" : "resume"); #endif spin_lock_irqsave(q->queue_lock, flags); - if (blk_pm_suspend_request(rq)) { + if (blk_pm_suspend_request(rq)) blk_stop_queue(q); - } else { + else drive->dev_flags &= ~IDE_DFLAG_BLOCKED; - blk_start_queue(q); - } spin_unlock_irqrestore(q->queue_lock, flags); drive->hwif->rq = NULL; @@ -219,6 +217,8 @@ void ide_check_pm_state(ide_drive_t *drive, struct request *rq) * point. */ ide_hwif_t *hwif = drive->hwif; + struct request_queue *q = drive->queue; + unsigned long flags; int rc; #ifdef DEBUG_PM printk("%s: Wakeup request inited, waiting for !BSY...\n", drive->name); @@ -231,5 +231,9 @@ void ide_check_pm_state(ide_drive_t *drive, struct request *rq) rc = ide_wait_not_busy(hwif, 100000); if (rc) printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name); + + spin_lock_irqsave(q->queue_lock, flags); + blk_start_queue(q); + spin_unlock_irqrestore(q->queue_lock, flags); } } -- cgit From e720b9e498b6bbb1b4f3b3d2f8e9a78578aafef7 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 14 Jan 2009 19:19:04 +0100 Subject: IDE: fix sparse signed-ness errors with host->host_busy The host_busy field in struct ide_host defaults to a signed-long, where most arch's test_and_set_bit_* macros use an unsigned long. Change to using an unsigned long, which on ARM removes the following sparse errors: drivers/ide/ide-io.c:681:8: warning: incorrect type in argument 2 (different signedness) drivers/ide/ide-io.c:681:8: expected unsigned long volatile *p drivers/ide/ide-io.c:681:8: got long volatile * drivers/ide/ide-io.c:681:8: warning: incorrect type in argument 2 (different signedness) drivers/ide/ide-io.c:681:8: expected unsigned long volatile *p drivers/ide/ide-io.c:681:8: got long volatile * drivers/ide/ide-io.c:695:3: warning: incorrect type in argument 2 (different signedness) drivers/ide/ide-io.c:695:3: expected unsigned long volatile *p drivers/ide/ide-io.c:695:3: got long volatile * drivers/ide/ide-io.c:695:3: warning: incorrect type in argument 2 (different signedness) drivers/ide/ide-io.c:695:3: expected unsigned long volatile *p drivers/ide/ide-io.c:695:3: got long volatile * drivers/ide/ide-io.c:695:3: warning: incorrect type in argument 2 (different signedness) drivers/ide/ide-io.c:695:3: expected unsigned long volatile *p drivers/ide/ide-io.c:695:3: got long volatile * drivers/ide/ide-io.c:695:3: warning: incorrect type in argument 2 (different signedness) drivers/ide/ide-io.c:695:3: expected unsigned long volatile *p drivers/ide/ide-io.c:695:3: got long volatile * drivers/ide/ide-io.c:695:3: warning: incorrect type in argument 2 (different signedness) drivers/ide/ide-io.c:695:3: expected unsigned long volatile *p drivers/ide/ide-io.c:695:3: got long volatile * drivers/ide/ide-io.c:695:3: warning: incorrect type in argument 2 (different signedness) drivers/ide/ide-io.c:695:3: expected unsigned long volatile *p drivers/ide/ide-io.c:695:3: got long volatile * drivers/ide/ide-io.c:695:3: warning: incorrect type in argument 2 (different signedness) drivers/ide/ide-io.c:695:3: expected unsigned long volatile *p drivers/ide/ide-io.c:695:3: got long volatile * drivers/ide/ide-io.c:695:3: warning: incorrect type in argument 2 (different signedness) drivers/ide/ide-io.c:695:3: expected unsigned long volatile *p drivers/ide/ide-io.c:695:3: got long volatile * Signed-off-by: Ben Dooks Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/ide.h b/include/linux/ide.h index 3644f632338..194da5a4b0d 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -871,7 +871,7 @@ struct ide_host { ide_hwif_t *cur_port; /* for hosts requiring serialization */ /* used for hosts requiring serialization */ - volatile long host_busy; + volatile unsigned long host_busy; }; #define IDE_HOST_BUSY 0 -- cgit From 5cca0cf15a94417f49625ce52e23589eed0a1675 Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Fri, 9 Jan 2009 14:35:20 -0800 Subject: x86, pat: fix reserve_memtype() for legacy 1MB range Thierry Vignaud reported: > http://bugzilla.kernel.org/show_bug.cgi?id=12372 > > On P4 with an SiS motherboard (video card is a SiS 651) > X server fails to start with error: > xf86MapVidMem: Could not mmap framebuffer (0x00000000,0x2000) (Invalid > argument) Here X is trying to map first 8KB of memory using /dev/mem. Existing code treats first 0-4KB of memory as non-RAM and 4KB-8KB as RAM. Recent code changes don't allow to map memory with different attributes at the same time. Fix this by treating the first 1MB legacy region as special and always track the attribute requests with in this region using linear linked list (and don't bother if the range is RAM or non-RAM or mixed) Reported-and-tested-by: Thierry Vignaud Signed-off-by: Suresh Siddha Signed-off-by: Venkatesh Pallipadi Signed-off-by: Ingo Molnar --- arch/x86/mm/pat.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index 85cbd3cd372..070ee4a3b22 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c @@ -333,11 +333,20 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type, req_type & _PAGE_CACHE_MASK); } - is_range_ram = pagerange_is_ram(start, end); - if (is_range_ram == 1) - return reserve_ram_pages_type(start, end, req_type, new_type); - else if (is_range_ram < 0) - return -EINVAL; + /* + * For legacy reasons, some parts of the physical address range in the + * legacy 1MB region is treated as non-RAM (even when listed as RAM in + * the e820 tables). So we will track the memory attributes of this + * legacy 1MB region using the linear memtype_list always. + */ + if (end >= ISA_END_ADDRESS) { + is_range_ram = pagerange_is_ram(start, end); + if (is_range_ram == 1) + return reserve_ram_pages_type(start, end, req_type, + new_type); + else if (is_range_ram < 0) + return -EINVAL; + } new = kmalloc(sizeof(struct memtype), GFP_KERNEL); if (!new) @@ -437,11 +446,19 @@ int free_memtype(u64 start, u64 end) if (is_ISA_range(start, end - 1)) return 0; - is_range_ram = pagerange_is_ram(start, end); - if (is_range_ram == 1) - return free_ram_pages_type(start, end); - else if (is_range_ram < 0) - return -EINVAL; + /* + * For legacy reasons, some parts of the physical address range in the + * legacy 1MB region is treated as non-RAM (even when listed as RAM in + * the e820 tables). So we will track the memory attributes of this + * legacy 1MB region using the linear memtype_list always. + */ + if (end >= ISA_END_ADDRESS) { + is_range_ram = pagerange_is_ram(start, end); + if (is_range_ram == 1) + return free_ram_pages_type(start, end); + else if (is_range_ram < 0) + return -EINVAL; + } spin_lock(&memtype_lock); list_for_each_entry(entry, &memtype_list, nd) { -- cgit From 73310a169aebe257efdd35a763cce1c7658f40c9 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 14 Jan 2009 11:28:35 -0800 Subject: init: make initrd/initramfs decompression failure a KERN_EMERG event Impact: More consistent behaviour, avoid policy in the kernel Upgrade/downgrade initrd/initramfs decompression failure from inconsistently a panic or a KERN_ALERT message to a KERN_EMERG event. It is, however, possible do design a system which can recover from this (using the kernel builtin code and/or the internal initramfs), which means this is policy, not a technical necessity. A good way to handle this would be to have a panic-level=X option, to force a panic on a printk above a certain level. That is a separate patch, however. Signed-off-by: H. Peter Anvin --- init/do_mounts_rd.c | 3 ++- init/initramfs.c | 11 +++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index 91d0cfca507..027a402708d 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -83,7 +83,8 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) printk(KERN_NOTICE "RAMDISK: %s image found at block %d\n", compress_name, start_block); if (!*decompressor) - printk(KERN_CRIT "RAMDISK: %s decompressor not configured!\n", + printk(KERN_EMERG + "RAMDISK: %s decompressor not configured!\n", compress_name); nblocks = 0; goto done; diff --git a/init/initramfs.c b/init/initramfs.c index 9a7290ec818..7dcde7ea660 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -528,7 +528,7 @@ static int __init populate_rootfs(void) char *err = unpack_to_rootfs(__initramfs_start, __initramfs_end - __initramfs_start, 0); if (err) - panic(err); + panic(err); /* Failed to decompress INTERNAL initramfs */ if (initrd_start) { #ifdef CONFIG_BLK_DEV_RAM int fd; @@ -554,9 +554,12 @@ static int __init populate_rootfs(void) printk(KERN_INFO "Unpacking initramfs..."); err = unpack_to_rootfs((char *)initrd_start, initrd_end - initrd_start, 0); - if (err) - panic(err); - printk(" done\n"); + if (err) { + printk(" failed!\n"); + printk(KERN_EMERG "%s\n", err); + } else { + printk(" done\n"); + } free_initrd(); #endif } -- cgit From 2ea038917bbdd51a7ae4a898c6a04641324dd033 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Wed, 14 Jan 2009 21:38:20 +0100 Subject: Revert "kbuild: strip generated symbols from *.ko" This reverts commit ad7a953c522ceb496611d127e51e278bfe0ff483. And commit: ("allow stripping of generated symbols under CONFIG_KALLSYMS_ALL") 9bb482476c6c9d1ae033306440c51ceac93ea80c These stripping patches has caused a set of issues: 1) People have reported compatibility issues with binutils due to lack of support for `--strip-unneeded-symbols' with objcopy 2.15.92.0.2 Reported by: Wenji 2) ccache and distcc no longer works as expeced Reported by: Ted, Roland, + others 3) The installed modules increased a lot in size Reported by: Ted, Davej + others Reported-by: Wenji Huang Reported-by: "Theodore Ts'o" Reported-by: Dave Jones Reported-by: Roland McGrath Signed-off-by: Sam Ravnborg --- Makefile | 59 ++++------- arch/x86/scripts/strip-symbols | 1 - init/Kconfig | 7 -- kernel/kallsyms.c | 16 +-- scripts/Makefile.build | 55 ++++------- scripts/Makefile.modinst | 3 +- scripts/genksyms/genksyms.c | 21 ++-- scripts/genksyms/keywords.c_shipped | 189 ++++++++++++++++++------------------ scripts/genksyms/keywords.gperf | 2 - scripts/kallsyms.c | 21 ++-- scripts/mksysmap | 7 +- scripts/strip-symbols | 22 ----- 12 files changed, 166 insertions(+), 237 deletions(-) delete mode 100644 arch/x86/scripts/strip-symbols delete mode 100644 scripts/strip-symbols diff --git a/Makefile b/Makefile index c06e250eca1..c2c4bbeef59 100644 --- a/Makefile +++ b/Makefile @@ -606,25 +606,20 @@ export INSTALL_PATH ?= /boot MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE) export MODLIB -strip-symbols := $(srctree)/scripts/strip-symbols \ - $(wildcard $(srctree)/arch/$(ARCH)/scripts/strip-symbols) - # -# INSTALL_MOD_STRIP, if defined, will cause modules to be stripped while -# they get installed. If INSTALL_MOD_STRIP is '1', then the default -# options (see below) will be used. Otherwise, INSTALL_MOD_STRIP will -# be used as the option(s) to the objcopy command. +# INSTALL_MOD_STRIP, if defined, will cause modules to be +# stripped after they are installed. If INSTALL_MOD_STRIP is '1', then +# the default option --strip-debug will be used. Otherwise, +# INSTALL_MOD_STRIP will used as the options to the strip command. + ifdef INSTALL_MOD_STRIP ifeq ($(INSTALL_MOD_STRIP),1) -mod_strip_cmd = $(OBJCOPY) --strip-debug -ifeq ($(CONFIG_KALLSYMS_ALL),$(CONFIG_KALLSYMS_STRIP_GENERATED)) -mod_strip_cmd += --wildcard $(addprefix --strip-symbols ,$(strip-symbols)) -endif +mod_strip_cmd = $(STRIP) --strip-debug else -mod_strip_cmd = $(OBJCOPY) $(INSTALL_MOD_STRIP) +mod_strip_cmd = $(STRIP) $(INSTALL_MOD_STRIP) endif # INSTALL_MOD_STRIP=1 else -mod_strip_cmd = false +mod_strip_cmd = true endif # INSTALL_MOD_STRIP export mod_strip_cmd @@ -754,7 +749,6 @@ last_kallsyms := 2 endif kallsyms.o := .tmp_kallsyms$(last_kallsyms).o -kallsyms.h := $(wildcard include/config/kallsyms/*.h) $(wildcard include/config/kallsyms/*/*.h) define verify_kallsyms $(Q)$(if $($(quiet)cmd_sysmap), \ @@ -779,41 +773,24 @@ endef # Generate .S file with all kernel symbols quiet_cmd_kallsyms = KSYM $@ - cmd_kallsyms = { test $* -eq 0 || $(NM) -n $<; } \ - | $(KALLSYMS) $(if $(CONFIG_KALLSYMS_ALL),--all-symbols) >$@ - -quiet_cmd_kstrip = STRIP $@ - cmd_kstrip = $(OBJCOPY) --wildcard $(addprefix --strip$(if $(CONFIG_RELOCATABLE),-unneeded)-symbols ,$(filter %/scripts/strip-symbols,$^)) $< $@ + cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) \ + $(if $(CONFIG_KALLSYMS_ALL),--all-symbols) > $@ -$(foreach n,0 1 2 3,.tmp_kallsyms$(n).o): KBUILD_AFLAGS += -Wa,--strip-local-absolute -$(foreach n,0 1 2 3,.tmp_kallsyms$(n).o): %.o: %.S scripts FORCE +.tmp_kallsyms1.o .tmp_kallsyms2.o .tmp_kallsyms3.o: %.o: %.S scripts FORCE $(call if_changed_dep,as_o_S) -ifeq ($(CONFIG_KALLSYMS_STRIP_GENERATED),y) -strip-ext := .stripped -endif - -.tmp_kallsyms%.S: .tmp_vmlinux%$(strip-ext) $(KALLSYMS) $(kallsyms.h) +.tmp_kallsyms%.S: .tmp_vmlinux% $(KALLSYMS) $(call cmd,kallsyms) -# make -jN seems to have problems with intermediate files, see bug #3330. -.SECONDARY: $(foreach n,1 2 3,.tmp_vmlinux$(n).stripped) -.tmp_vmlinux%.stripped: .tmp_vmlinux% $(strip-symbols) $(kallsyms.h) - $(call cmd,kstrip) - -ifneq ($(CONFIG_DEBUG_INFO),y) -.tmp_vmlinux%: LDFLAGS_vmlinux += -S -endif # .tmp_vmlinux1 must be complete except kallsyms, so update vmlinux version -.tmp_vmlinux%: $(vmlinux-lds) $(vmlinux-all) FORCE - $(if $(filter 1,$*),$(call if_changed_rule,ksym_ld),$(call if_changed,vmlinux__)) +.tmp_vmlinux1: $(vmlinux-lds) $(vmlinux-all) FORCE + $(call if_changed_rule,ksym_ld) -.tmp_vmlinux0$(strip-ext): - $(Q)echo "placeholder" >$@ +.tmp_vmlinux2: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms1.o FORCE + $(call if_changed,vmlinux__) -.tmp_vmlinux1: .tmp_kallsyms0.o -.tmp_vmlinux2: .tmp_kallsyms1.o -.tmp_vmlinux3: .tmp_kallsyms2.o +.tmp_vmlinux3: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms2.o FORCE + $(call if_changed,vmlinux__) # Needs to visit scripts/ before $(KALLSYMS) can be used. $(KALLSYMS): scripts ; diff --git a/arch/x86/scripts/strip-symbols b/arch/x86/scripts/strip-symbols deleted file mode 100644 index a2f1ccb827c..00000000000 --- a/arch/x86/scripts/strip-symbols +++ /dev/null @@ -1 +0,0 @@ -__cpu_vendor_dev_X86_VENDOR_* diff --git a/init/Kconfig b/init/Kconfig index a724a149bf3..0e9924743a1 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -626,13 +626,6 @@ config KALLSYMS_ALL Say N. -config KALLSYMS_STRIP_GENERATED - bool "Strip machine generated symbols from kallsyms" - depends on KALLSYMS_ALL - default y - help - Say N if you want kallsyms to retain even machine generated symbols. - config KALLSYMS_EXTRA_PASS bool "Do an extra kallsyms pass" depends on KALLSYMS diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index e694afa0eb8..7b8b0f21a5b 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c @@ -30,19 +30,20 @@ #define all_var 0 #endif -extern const unsigned long kallsyms_addresses[]; -extern const u8 kallsyms_names[]; +/* These will be re-linked against their real values during the second link stage */ +extern const unsigned long kallsyms_addresses[] __attribute__((weak)); +extern const u8 kallsyms_names[] __attribute__((weak)); /* tell the compiler that the count isn't in the small data section if the arch * has one (eg: FRV) */ extern const unsigned long kallsyms_num_syms - __attribute__((__section__(".rodata"))); +__attribute__((weak, section(".rodata"))); -extern const u8 kallsyms_token_table[]; -extern const u16 kallsyms_token_index[]; +extern const u8 kallsyms_token_table[] __attribute__((weak)); +extern const u16 kallsyms_token_index[] __attribute__((weak)); -extern const unsigned long kallsyms_markers[]; +extern const unsigned long kallsyms_markers[] __attribute__((weak)); static inline int is_kernel_inittext(unsigned long addr) { @@ -167,6 +168,9 @@ static unsigned long get_symbol_pos(unsigned long addr, unsigned long symbol_start = 0, symbol_end = 0; unsigned long i, low, high, mid; + /* This kernel should never had been booted. */ + BUG_ON(!kallsyms_addresses); + /* do a binary search on the sorted kallsyms_addresses array */ low = 0; high = kallsyms_num_syms; diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 5d900307de3..c7de8b39fcf 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -151,16 +151,16 @@ cmd_cc_i_c = $(CPP) $(c_flags) -o $@ $< $(obj)/%.i: $(src)/%.c FORCE $(call if_changed_dep,cc_i_c) -cmd_genksyms = \ +cmd_gensymtypes = \ $(CPP) -D__GENKSYMS__ $(c_flags) $< | \ - $(GENKSYMS) -T $@ -A -a $(ARCH) \ + $(GENKSYMS) -T $@ -a $(ARCH) \ $(if $(KBUILD_PRESERVE),-p) \ $(if $(1),-r $(firstword $(wildcard $(@:.symtypes=.symref) /dev/null))) quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@ cmd_cc_symtypes_c = \ set -e; \ - $(call cmd_genksyms, true) >/dev/null; \ + $(call cmd_gensymtypes, true) >/dev/null; \ test -s $@ || rm -f $@ $(obj)/%.symtypes : $(src)/%.c FORCE @@ -177,38 +177,28 @@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< else # When module versioning is enabled the following steps are executed: -# o compile a .tmp_.s from .c -# o if .tmp_.s doesn't contain a __ksymtab version, i.e. does -# not export symbols, we just assemble .tmp_.s to .o and +# o compile a .tmp_.o from .c +# o if .tmp_.o doesn't contain a __ksymtab version, i.e. does +# not export symbols, we just rename .tmp_.o to .o and # are done. # o otherwise, we calculate symbol versions using the good old # genksyms on the preprocessed source and postprocess them in a way -# that they are usable as assembly source -# o assemble .o from .tmp_.s forcing inclusion of directives -# defining the actual values of __crc_*, followed by objcopy-ing them -# to force these symbols to be local to permit stripping them later. -s_file = $(@D)/.tmp_$(@F:.o=.s) -v_file = $(@D)/.tmp_$(@F:.o=.v) -tmp_o_file = $(@D)/.tmp_$(@F) -no_g_c_flags = $(filter-out -g%,$(c_flags)) - -cmd_cc_o_c = $(CC) $(c_flags) -S -o $(s_file) $< +# that they are usable as a linker script +# o generate .o from .tmp_.o using the linker to +# replace the unresolved symbols __crc_exported_symbol with +# the actual value of the checksum generated by genksyms +cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $< cmd_modversions = \ - if grep -q __ksymtab $(s_file); then \ - if $(call cmd_genksyms, $(KBUILD_SYMTYPES)) > $(v_file) \ - && $(CC) $(no_g_c_flags) -c -Wa,$(v_file) \ - -o $(tmp_o_file) $(s_file) \ - && $(OBJCOPY) -L '__crc_*' -L '___crc_*' -w \ - $(tmp_o_file) $@; \ - then \ - : ; \ - else \ - rm -f $@; exit 1; \ - fi; \ + if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \ + $(call cmd_gensymtypes, $(KBUILD_SYMTYPES)) \ + > $(@D)/.tmp_$(@F:.o=.ver); \ + \ + $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ + -T $(@D)/.tmp_$(@F:.o=.ver); \ + rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \ else \ - rm -f $(v_file); \ - $(CC) $(no_g_c_flags) -c -o $@ $(s_file); \ + mv -f $(@D)/.tmp_$(@F) $@; \ fi; endif @@ -225,12 +215,7 @@ define rule_cc_o_c $(cmd_record_mcount) \ scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > \ $(dot-target).tmp; \ - if [ -r $(@D)/.tmp_$(@F:.o=.v) ]; then \ - echo >> $(dot-target).tmp; \ - echo '$@: $(GENKSYMS)' >> $(dot-target).tmp; \ - echo '$(GENKSYMS):: ;' >> $(dot-target).tmp; \ - fi; \ - rm -f $(depfile) $(@D)/.tmp_$(@F:.o=.?); \ + rm -f $(depfile); \ mv -f $(dot-target).tmp $(dot-target).cmd endef diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index a5122dce126..efa5d940e63 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst @@ -17,8 +17,7 @@ __modinst: $(modules) @: quiet_cmd_modules_install = INSTALL $@ - cmd_modules_install = mkdir -p $(2); \ - $(mod_strip_cmd) $@ $(2)/$(notdir $@) || cp $@ $(2) + cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@) # Modules built outside the kernel source tree go into extra by default INSTALL_MOD_DIR ?= extra diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c index f8bb4cabd62..3a8297b5184 100644 --- a/scripts/genksyms/genksyms.c +++ b/scripts/genksyms/genksyms.c @@ -43,7 +43,7 @@ int cur_line = 1; char *cur_filename; static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types, - flag_preserve, flag_warnings, flag_asm; + flag_preserve, flag_warnings; static const char *arch = ""; static const char *mod_prefix = ""; @@ -610,11 +610,8 @@ void export_symbol(const char *name) if (flag_dump_defs) fputs(">\n", debugfile); - /* Used as assembly source or a linker script. */ - printf(flag_asm - ? ".equiv %s__crc_%s, %#08lx\n" - : "%s__crc_%s = %#08lx ;\n", - mod_prefix, name, crc); + /* Used as a linker script. */ + printf("%s__crc_%s = 0x%08lx ;\n", mod_prefix, name, crc); } } @@ -651,10 +648,9 @@ void error_with_pos(const char *fmt, ...) static void genksyms_usage(void) { - fputs("Usage:\n" "genksyms [-aAdDTwqhV] > /path/to/.tmp_obj.ver\n" "\n" + fputs("Usage:\n" "genksyms [-adDTwqhV] > /path/to/.tmp_obj.ver\n" "\n" #ifdef __GNU_LIBRARY__ " -a, --arch Select architecture\n" - " -A, --asm Generate assembly rather than linker script\n" " -d, --debug Increment the debug level (repeatable)\n" " -D, --dump Dump expanded symbol defs (for debugging only)\n" " -r, --reference file Read reference symbols from a file\n" @@ -666,7 +662,6 @@ static void genksyms_usage(void) " -V, --version Print the release version\n" #else /* __GNU_LIBRARY__ */ " -a Select architecture\n" - " -A Generate assembly rather than linker script\n" " -d Increment the debug level (repeatable)\n" " -D Dump expanded symbol defs (for debugging only)\n" " -r file Read reference symbols from a file\n" @@ -688,7 +683,6 @@ int main(int argc, char **argv) #ifdef __GNU_LIBRARY__ struct option long_opts[] = { {"arch", 1, 0, 'a'}, - {"asm", 0, 0, 'A'}, {"debug", 0, 0, 'd'}, {"warnings", 0, 0, 'w'}, {"quiet", 0, 0, 'q'}, @@ -701,10 +695,10 @@ int main(int argc, char **argv) {0, 0, 0, 0} }; - while ((o = getopt_long(argc, argv, "a:dwqVADr:T:ph", + while ((o = getopt_long(argc, argv, "a:dwqVDr:T:ph", &long_opts[0], NULL)) != EOF) #else /* __GNU_LIBRARY__ */ - while ((o = getopt(argc, argv, "a:dwqVADr:T:ph")) != EOF) + while ((o = getopt(argc, argv, "a:dwqVDr:T:ph")) != EOF) #endif /* __GNU_LIBRARY__ */ switch (o) { case 'a': @@ -722,9 +716,6 @@ int main(int argc, char **argv) case 'V': fputs("genksyms version 2.5.60\n", stderr); break; - case 'A': - flag_asm = 1; - break; case 'D': flag_dump_defs = 1; break; diff --git a/scripts/genksyms/keywords.c_shipped b/scripts/genksyms/keywords.c_shipped index 83484fe93ed..971e0113ae7 100644 --- a/scripts/genksyms/keywords.c_shipped +++ b/scripts/genksyms/keywords.c_shipped @@ -1,4 +1,4 @@ -/* ANSI-C code produced by gperf version 3.0.1 */ +/* ANSI-C code produced by gperf version 3.0.2 */ /* Command-line: gperf -L ANSI-C -a -C -E -g -H is_reserved_hash -k '1,3,$' -N is_reserved_word -p -t scripts/genksyms/keywords.gperf */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -32,7 +32,7 @@ #line 3 "scripts/genksyms/keywords.gperf" struct resword { const char *name; int token; }; -/* maximum key range = 64, duplicates = 0 */ +/* maximum key range = 62, duplicates = 0 */ #ifdef __GNUC__ __inline @@ -46,32 +46,32 @@ is_reserved_hash (register const char *str, register unsigned int len) { static const unsigned char asso_values[] = { - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 0, - 67, 67, 67, 67, 67, 67, 15, 67, 67, 67, - 0, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 0, 67, 0, 67, 5, - 25, 20, 15, 30, 67, 15, 67, 67, 10, 0, - 10, 40, 20, 67, 10, 5, 0, 10, 15, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67 + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 5, + 65, 65, 65, 65, 65, 65, 35, 65, 65, 65, + 0, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 0, 65, 0, 65, 5, + 20, 15, 10, 30, 65, 15, 65, 65, 20, 0, + 10, 35, 20, 65, 10, 5, 0, 10, 5, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65 }; return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]]; } @@ -84,119 +84,116 @@ is_reserved_word (register const char *str, register unsigned int len) { enum { - TOTAL_KEYWORDS = 45, + TOTAL_KEYWORDS = 43, MIN_WORD_LENGTH = 3, MAX_WORD_LENGTH = 24, MIN_HASH_VALUE = 3, - MAX_HASH_VALUE = 66 + MAX_HASH_VALUE = 64 }; static const struct resword wordlist[] = { {""}, {""}, {""}, -#line 28 "scripts/genksyms/keywords.gperf" +#line 26 "scripts/genksyms/keywords.gperf" {"asm", ASM_KEYW}, {""}, -#line 10 "scripts/genksyms/keywords.gperf" +#line 8 "scripts/genksyms/keywords.gperf" {"__asm", ASM_KEYW}, {""}, -#line 11 "scripts/genksyms/keywords.gperf" +#line 9 "scripts/genksyms/keywords.gperf" {"__asm__", ASM_KEYW}, {""}, {""}, -#line 54 "scripts/genksyms/keywords.gperf" +#line 52 "scripts/genksyms/keywords.gperf" {"__typeof__", TYPEOF_KEYW}, {""}, -#line 14 "scripts/genksyms/keywords.gperf" +#line 12 "scripts/genksyms/keywords.gperf" {"__const", CONST_KEYW}, -#line 13 "scripts/genksyms/keywords.gperf" +#line 11 "scripts/genksyms/keywords.gperf" {"__attribute__", ATTRIBUTE_KEYW}, -#line 15 "scripts/genksyms/keywords.gperf" +#line 13 "scripts/genksyms/keywords.gperf" {"__const__", CONST_KEYW}, -#line 20 "scripts/genksyms/keywords.gperf" +#line 18 "scripts/genksyms/keywords.gperf" {"__signed__", SIGNED_KEYW}, -#line 46 "scripts/genksyms/keywords.gperf" +#line 44 "scripts/genksyms/keywords.gperf" {"static", STATIC_KEYW}, - {""}, -#line 41 "scripts/genksyms/keywords.gperf" +#line 20 "scripts/genksyms/keywords.gperf" + {"__volatile__", VOLATILE_KEYW}, +#line 39 "scripts/genksyms/keywords.gperf" {"int", INT_KEYW}, -#line 34 "scripts/genksyms/keywords.gperf" +#line 32 "scripts/genksyms/keywords.gperf" {"char", CHAR_KEYW}, -#line 35 "scripts/genksyms/keywords.gperf" +#line 33 "scripts/genksyms/keywords.gperf" {"const", CONST_KEYW}, -#line 47 "scripts/genksyms/keywords.gperf" +#line 45 "scripts/genksyms/keywords.gperf" {"struct", STRUCT_KEYW}, -#line 26 "scripts/genksyms/keywords.gperf" +#line 24 "scripts/genksyms/keywords.gperf" {"__restrict__", RESTRICT_KEYW}, -#line 27 "scripts/genksyms/keywords.gperf" - {"restrict", RESTRICT_KEYW}, -#line 7 "scripts/genksyms/keywords.gperf" - {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW}, -#line 18 "scripts/genksyms/keywords.gperf" - {"__inline__", INLINE_KEYW}, - {""}, -#line 22 "scripts/genksyms/keywords.gperf" - {"__volatile__", VOLATILE_KEYW}, -#line 5 "scripts/genksyms/keywords.gperf" - {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, #line 25 "scripts/genksyms/keywords.gperf" + {"restrict", RESTRICT_KEYW}, +#line 23 "scripts/genksyms/keywords.gperf" {"_restrict", RESTRICT_KEYW}, - {""}, -#line 12 "scripts/genksyms/keywords.gperf" - {"__attribute", ATTRIBUTE_KEYW}, -#line 6 "scripts/genksyms/keywords.gperf" - {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, #line 16 "scripts/genksyms/keywords.gperf" + {"__inline__", INLINE_KEYW}, +#line 10 "scripts/genksyms/keywords.gperf" + {"__attribute", ATTRIBUTE_KEYW}, + {""}, +#line 14 "scripts/genksyms/keywords.gperf" {"__extension__", EXTENSION_KEYW}, -#line 37 "scripts/genksyms/keywords.gperf" +#line 35 "scripts/genksyms/keywords.gperf" {"enum", ENUM_KEYW}, -#line 8 "scripts/genksyms/keywords.gperf" - {"EXPORT_UNUSED_SYMBOL", EXPORT_SYMBOL_KEYW}, -#line 38 "scripts/genksyms/keywords.gperf" +#line 19 "scripts/genksyms/keywords.gperf" + {"__volatile", VOLATILE_KEYW}, +#line 36 "scripts/genksyms/keywords.gperf" {"extern", EXTERN_KEYW}, {""}, -#line 19 "scripts/genksyms/keywords.gperf" +#line 17 "scripts/genksyms/keywords.gperf" {"__signed", SIGNED_KEYW}, -#line 9 "scripts/genksyms/keywords.gperf" - {"EXPORT_UNUSED_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, -#line 49 "scripts/genksyms/keywords.gperf" - {"union", UNION_KEYW}, -#line 53 "scripts/genksyms/keywords.gperf" +#line 7 "scripts/genksyms/keywords.gperf" + {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW}, + {""}, +#line 51 "scripts/genksyms/keywords.gperf" {"typeof", TYPEOF_KEYW}, -#line 48 "scripts/genksyms/keywords.gperf" +#line 46 "scripts/genksyms/keywords.gperf" {"typedef", TYPEDEF_KEYW}, -#line 17 "scripts/genksyms/keywords.gperf" +#line 15 "scripts/genksyms/keywords.gperf" {"__inline", INLINE_KEYW}, -#line 33 "scripts/genksyms/keywords.gperf" +#line 31 "scripts/genksyms/keywords.gperf" {"auto", AUTO_KEYW}, -#line 21 "scripts/genksyms/keywords.gperf" - {"__volatile", VOLATILE_KEYW}, +#line 47 "scripts/genksyms/keywords.gperf" + {"union", UNION_KEYW}, {""}, {""}, -#line 50 "scripts/genksyms/keywords.gperf" +#line 48 "scripts/genksyms/keywords.gperf" {"unsigned", UNSIGNED_KEYW}, - {""}, -#line 44 "scripts/genksyms/keywords.gperf" +#line 49 "scripts/genksyms/keywords.gperf" + {"void", VOID_KEYW}, +#line 42 "scripts/genksyms/keywords.gperf" {"short", SHORT_KEYW}, -#line 40 "scripts/genksyms/keywords.gperf" + {""}, {""}, +#line 50 "scripts/genksyms/keywords.gperf" + {"volatile", VOLATILE_KEYW}, + {""}, +#line 37 "scripts/genksyms/keywords.gperf" + {"float", FLOAT_KEYW}, +#line 34 "scripts/genksyms/keywords.gperf" + {"double", DOUBLE_KEYW}, + {""}, +#line 5 "scripts/genksyms/keywords.gperf" + {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, + {""}, {""}, +#line 38 "scripts/genksyms/keywords.gperf" {"inline", INLINE_KEYW}, +#line 6 "scripts/genksyms/keywords.gperf" + {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, +#line 41 "scripts/genksyms/keywords.gperf" + {"register", REGISTER_KEYW}, {""}, -#line 52 "scripts/genksyms/keywords.gperf" - {"volatile", VOLATILE_KEYW}, -#line 42 "scripts/genksyms/keywords.gperf" - {"long", LONG_KEYW}, -#line 24 "scripts/genksyms/keywords.gperf" +#line 22 "scripts/genksyms/keywords.gperf" {"_Bool", BOOL_KEYW}, - {""}, {""}, #line 43 "scripts/genksyms/keywords.gperf" - {"register", REGISTER_KEYW}, -#line 51 "scripts/genksyms/keywords.gperf" - {"void", VOID_KEYW}, -#line 39 "scripts/genksyms/keywords.gperf" - {"float", FLOAT_KEYW}, -#line 36 "scripts/genksyms/keywords.gperf" - {"double", DOUBLE_KEYW}, - {""}, {""}, {""}, {""}, -#line 45 "scripts/genksyms/keywords.gperf" - {"signed", SIGNED_KEYW} + {"signed", SIGNED_KEYW}, + {""}, {""}, +#line 40 "scripts/genksyms/keywords.gperf" + {"long", LONG_KEYW} }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) diff --git a/scripts/genksyms/keywords.gperf b/scripts/genksyms/keywords.gperf index 8abe7ab8d88..5ef3733225f 100644 --- a/scripts/genksyms/keywords.gperf +++ b/scripts/genksyms/keywords.gperf @@ -5,8 +5,6 @@ struct resword { const char *name; int token; } EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW EXPORT_SYMBOL_GPL_FUTURE, EXPORT_SYMBOL_KEYW -EXPORT_UNUSED_SYMBOL, EXPORT_SYMBOL_KEYW -EXPORT_UNUSED_SYMBOL_GPL, EXPORT_SYMBOL_KEYW __asm, ASM_KEYW __asm__, ASM_KEYW __attribute, ATTRIBUTE_KEYW diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 92758120a76..ad2434b2697 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -130,9 +130,18 @@ static int read_symbol(FILE *in, struct sym_entry *s) static int symbol_valid(struct sym_entry *s) { /* Symbols which vary between passes. Passes 1 and 2 must have - * identical symbol lists. + * identical symbol lists. The kallsyms_* symbols below are only added + * after pass 1, they would be included in pass 2 when --all-symbols is + * specified so exclude them to get a stable symbol list. */ static char *special_symbols[] = { + "kallsyms_addresses", + "kallsyms_num_syms", + "kallsyms_names", + "kallsyms_markers", + "kallsyms_token_table", + "kallsyms_token_index", + /* Exclude linker generated symbols which vary between passes */ "_SDA_BASE_", /* ppc */ "_SDA2_BASE_", /* ppc */ @@ -164,9 +173,7 @@ static int symbol_valid(struct sym_entry *s) } /* Exclude symbols which vary between passes. */ - if (strstr((char *)s->sym + offset, "_compiled.") || - strncmp((char*)s->sym + offset, "__compound_literal.", 19) == 0 || - strncmp((char*)s->sym + offset, "__compound_literal$", 19) == 0) + if (strstr((char *)s->sym + offset, "_compiled.")) return 0; for (i = 0; special_symbols[i]; i++) @@ -543,10 +550,8 @@ int main(int argc, char **argv) usage(); read_map(stdin); - if (table_cnt) { - sort_symbols(); - optimize_token_table(); - } + sort_symbols(); + optimize_token_table(); write_src(); return 0; diff --git a/scripts/mksysmap b/scripts/mksysmap index 1db316a3712..6e133a0bae7 100644 --- a/scripts/mksysmap +++ b/scripts/mksysmap @@ -37,6 +37,9 @@ # readprofile starts reading symbols when _stext is found, and # continue until it finds a symbol which is not either of 'T', 't', -# 'W' or 'w'. +# 'W' or 'w'. __crc_ are 'A' and placed in the middle +# so we just ignore them to let readprofile continue to work. +# (At least sparc64 has __crc_ in the middle). + +$NM -n $1 | grep -v '\( [aNUw] \)\|\(__crc_\)\|\( \$[adt]\)' > $2 -$NM -n $1 | grep -v '\( [aNUw] \)\|\( \$[adt]\)' > $2 diff --git a/scripts/strip-symbols b/scripts/strip-symbols deleted file mode 100644 index 29ee8c1a014..00000000000 --- a/scripts/strip-symbols +++ /dev/null @@ -1,22 +0,0 @@ -<*> -*.h -__compound_literal[$.][0-9]* -__crc_[a-zA-Z_]* -__exitcall_[a-zA-Z_]* -__func__[$.][0-9]* -__FUNCTION__[$.][0-9]* -gcc[0-9]_compiled[$.] -__initcall_[a-zA-Z_]* -__kcrctab_[a-zA-Z_]* -__kstrtab_[a-zA-Z_]* -__ksymtab_[a-zA-Z_]* -__mod_[a-zA-Z_]*[0-9] -__module_depends -__param_[a-zA-Z_]* -__pci_fixup_*PCI_ANY_IDPCI_ANY_ID* -__pci_fixup_*PCI_ANY_IDPCI_DEVICE_ID_* -__pci_fixup_*PCI_VENDOR_ID_*PCI_ANY_ID* -__pci_fixup_*PCI_VENDOR_ID_*PCI_DEVICE_ID_* -__PRETTY_FUNCTION__[$.][0-9]* -__setup_[a-zA-Z_]* -____versions -- cgit From 2302e8730e5caa774e7c6702fc878404d71f13f9 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 7 Jan 2009 22:33:15 +0100 Subject: kbuild: print usage with no arguments in scripts/config Requested by Sam. Signed-off-by: Andi Kleen Signed-off-by: Sam Ravnborg --- scripts/config | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/config b/scripts/config index 68b9761cdc3..db6084b78a1 100755 --- a/scripts/config +++ b/scripts/config @@ -60,6 +60,10 @@ else FN=.config fi +if [ "$1" = "" ] ; then + usage +fi + while [ "$1" != "" ] ; do CMD="$1" shift -- cgit From df291fa993c506da89a89264ff8166bccd172a14 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 8 Jan 2009 10:59:34 -0800 Subject: kbuild: fix kbuild.txt typos Fix typos in the new kbuild.txt file. Signed-off-by: Randy Dunlap Signed-off-by: Sam Ravnborg --- Documentation/kbuild/kbuild.txt | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/Documentation/kbuild/kbuild.txt b/Documentation/kbuild/kbuild.txt index 923f9ddee8f..f3355b6812d 100644 --- a/Documentation/kbuild/kbuild.txt +++ b/Documentation/kbuild/kbuild.txt @@ -3,7 +3,7 @@ Environment variables KCPPFLAGS -------------------------------------------------- Additional options to pass when preprocessing. The preprocessing options -will be used in all cases where kbuild do preprocessing including +will be used in all cases where kbuild does preprocessing including building C files and assembler files. KAFLAGS @@ -16,7 +16,7 @@ Additional options to the C compiler. KBUILD_VERBOSE -------------------------------------------------- -Set the kbuild verbosity. Can be assinged same values as "V=...". +Set the kbuild verbosity. Can be assigned same values as "V=...". See make help for the full list. Setting "V=..." takes precedence over KBUILD_VERBOSE. @@ -35,14 +35,14 @@ KBUILD_OUTPUT -------------------------------------------------- Specify the output directory when building the kernel. The output directory can also be specificed using "O=...". -Setting "O=..." takes precedence over KBUILD_OUTPUT +Setting "O=..." takes precedence over KBUILD_OUTPUT. ARCH -------------------------------------------------- Set ARCH to the architecture to be built. In most cases the name of the architecture is the same as the directory name found in the arch/ directory. -But some architectures suach as x86 and sparc has aliases. +But some architectures such as x86 and sparc have aliases. x86: i386 for 32 bit, x86_64 for 64 bit sparc: sparc for 32 bit, sparc64 for 64 bit @@ -63,7 +63,7 @@ CF is often used on the command-line like this: INSTALL_PATH -------------------------------------------------- INSTALL_PATH specifies where to place the updated kernel and system map -images. Default is /boot, but you can set it to other values +images. Default is /boot, but you can set it to other values. MODLIB @@ -90,7 +90,7 @@ INSTALL_MOD_STRIP will used as the options to the strip command. INSTALL_FW_PATH -------------------------------------------------- -INSTALL_FW_PATH specify where to install the firmware blobs. +INSTALL_FW_PATH specifies where to install the firmware blobs. The default value is: $(INSTALL_MOD_PATH)/lib/firmware @@ -99,7 +99,7 @@ The value can be overridden in which case the default value is ignored. INSTALL_HDR_PATH -------------------------------------------------- -INSTALL_HDR_PATH specify where to install user space headers when +INSTALL_HDR_PATH specifies where to install user space headers when executing "make headers_*". The default value is: @@ -112,22 +112,23 @@ The value can be overridden in which case the default value is ignored. KBUILD_MODPOST_WARN -------------------------------------------------- -KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined -symbols in the final module linking stage. +KBUILD_MODPOST_WARN can be set to avoid errors in case of undefined +symbols in the final module linking stage. It changes such errors +into warnings. -KBUILD_MODPOST_FINAL +KBUILD_MODPOST_NOFINAL -------------------------------------------------- KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules. -This is solely usefull to speed up test compiles. +This is solely useful to speed up test compiles. KBUILD_EXTRA_SYMBOLS -------------------------------------------------- -For modules use symbols from another modules. +For modules that use symbols from other modules. See more details in modules.txt. ALLSOURCE_ARCHS -------------------------------------------------- -For tags/TAGS/cscope targets, you can specify more than one archs -to be included in the databases, separated by blankspace. e.g. +For tags/TAGS/cscope targets, you can specify more than one arch +to be included in the databases, separated by blank space. E.g.: $ make ALLSOURCE_ARCHS="x86 mips arm" tags -- cgit From 444027031cd069ea7e48b016cb33bbf201c8a9f0 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Wed, 14 Jan 2009 23:37:47 +0300 Subject: x86: headers cleanup - prctl.h Impact: cleanup (internal kernel function exported) 'make headers_check' warn us about leaking of kernel private (mostly compile time vars) data to userspace in headers. Fix it. sys_arch_prctl is completely removed from header since frankly I don't even understand why we describe it here. It is described like __SYSCALL(__NR_arch_prctl, sys_arch_prctl) in unistd_64.h and implemented in process_64.c. User-mode linux involved? So this one in fact is suspicious. Signed-off-by: Cyrill Gorcunov Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/prctl.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/x86/include/asm/prctl.h b/arch/x86/include/asm/prctl.h index a8894647dd9..3ac5032fae0 100644 --- a/arch/x86/include/asm/prctl.h +++ b/arch/x86/include/asm/prctl.h @@ -6,8 +6,4 @@ #define ARCH_GET_FS 0x1003 #define ARCH_GET_GS 0x1004 -#ifdef CONFIG_X86_64 -extern long sys_arch_prctl(int, unsigned long); -#endif /* CONFIG_X86_64 */ - #endif /* _ASM_X86_PRCTL_H */ -- cgit From a7c4e68615e20771f279c51a2bec8980675c78c7 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Wed, 14 Jan 2009 23:37:49 +0300 Subject: x86: headers cleanup - sigcontext32.h Impact: cleanup 'make headers_check' warn us about lack of linux/types.h here. Lets add it. Signed-off-by: Cyrill Gorcunov Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/sigcontext32.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/include/asm/sigcontext32.h b/arch/x86/include/asm/sigcontext32.h index 6126188cf3a..ad1478c4ae1 100644 --- a/arch/x86/include/asm/sigcontext32.h +++ b/arch/x86/include/asm/sigcontext32.h @@ -1,6 +1,8 @@ #ifndef _ASM_X86_SIGCONTEXT32_H #define _ASM_X86_SIGCONTEXT32_H +#include + /* signal context for 32bit programs. */ #define X86_FXSR_MAGIC 0x0000 -- cgit From dbca1df48e89d8aa59254fdc10ef16c16e73d94e Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Wed, 14 Jan 2009 23:37:50 +0300 Subject: x86: headers cleanup - setup.h Impact: cleanup 'make headers_check' warn us about leaking of kernel private (mostly compile time vars) data to userspace in headers. Fix it. Guard this one by __KERNEL__. Signed-off-by: Cyrill Gorcunov Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/setup.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h index ebe858cdc8a..29d31c0d13d 100644 --- a/arch/x86/include/asm/setup.h +++ b/arch/x86/include/asm/setup.h @@ -1,6 +1,8 @@ #ifndef _ASM_X86_SETUP_H #define _ASM_X86_SETUP_H +#ifdef __KERNEL__ + #define COMMAND_LINE_SIZE 2048 #ifndef __ASSEMBLY__ @@ -8,10 +10,8 @@ /* Interrupt control for vSMPowered x86_64 systems */ void vsmp_init(void); - void setup_bios_corruption_check(void); - #ifdef CONFIG_X86_VISWS extern void visws_early_detect(void); extern int is_visws_box(void); @@ -43,7 +43,7 @@ struct x86_quirks { void (*mpc_oem_bus_info)(struct mpc_bus *m, char *name); void (*mpc_oem_pci_bus)(struct mpc_bus *m); void (*smp_read_mpc_oem)(struct mpc_oemtable *oemtable, - unsigned short oemsize); + unsigned short oemsize); int (*setup_ioapic_ids)(void); int (*update_genapic)(void); }; @@ -56,8 +56,6 @@ extern unsigned long saved_video_mode; #endif #endif /* __ASSEMBLY__ */ -#ifdef __KERNEL__ - #ifdef __i386__ #include -- cgit From 1b0652eb588e57c3ab230e0291e7da99c7e665e0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 14 Jan 2009 08:27:35 +0100 Subject: ALSA: hda - Fix HP dv5 mic input Fix HP dv5 (103c:3603) built-in mic input. Reference: kernel bug 12440 http://bugzilla.kernel.org/show_bug.cgi?id=12440 Signed-off-by: Takashi Iwai Cc: stable@kernel.org --- sound/pci/hda/patch_sigmatel.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 6d9a4a2aa4a..e6c13963f21 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -90,6 +90,7 @@ enum { STAC_DELL_M4_2, STAC_DELL_M4_3, STAC_HP_M4, + STAC_HP_DV5, STAC_92HD71BXX_MODELS }; @@ -1778,6 +1779,7 @@ static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { [STAC_DELL_M4_2] = dell_m4_2_pin_configs, [STAC_DELL_M4_3] = dell_m4_3_pin_configs, [STAC_HP_M4] = NULL, + [STAC_HP_DV5] = NULL, }; static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { @@ -1786,6 +1788,7 @@ static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { [STAC_DELL_M4_2] = "dell-m4-2", [STAC_DELL_M4_3] = "dell-m4-3", [STAC_HP_M4] = "hp-m4", + [STAC_HP_DV5] = "hp-dv5", }; static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { @@ -1799,7 +1802,7 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fc, "HP dv7", STAC_HP_M4), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3603, - "HP dv5", STAC_HP_M4), + "HP dv5", STAC_HP_DV5), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, "unknown HP", STAC_HP_M4), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, -- cgit From 483a2b3a3182abcb7fcea986d7ea13e793bb00b1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 14 Jan 2009 14:35:15 -0800 Subject: ARM etherh: Fix build failure. Reported by Russell King: drivers/net/arm/etherh.c:649: error: unknown field 'ndo_set_mac_addr' specified in initializer Signed-off-by: David S. Miller --- drivers/net/arm/etherh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c index 745ac188bab..d15d8b79d8e 100644 --- a/drivers/net/arm/etherh.c +++ b/drivers/net/arm/etherh.c @@ -646,7 +646,7 @@ static const struct net_device_ops etherh_netdev_ops = { .ndo_get_stats = ei_get_stats, .ndo_set_multicast_list = ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_addr = eth_set_mac_addr, + .ndo_set_mac_address = eth_set_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ei_poll, -- cgit From f17f5c91ae3bfeb5cfc37fa132a5fdfceb8927be Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 14 Jan 2009 14:36:12 -0800 Subject: gro: Check for GSO packets and packets with frag_list As GRO cannot be applied to packets with frag_list we need to make sure that we reject such packets if they are fed to us, e.g., through a tunnel device. Also there is no point in applying GRO on GSO packets so they too should be rejected. This allows GRO to be used in virtio-net which may produce GSO packets directly but may still benefit from GRO if the other end of it doesn't support GSO. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/core/dev.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/core/dev.c b/net/core/dev.c index b715a55cccc..7dec715293b 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2392,6 +2392,9 @@ int dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) if (!(skb->dev->features & NETIF_F_GRO)) goto normal; + if (skb_is_gso(skb) || skb_shinfo(skb)->frag_list) + goto normal; + rcu_read_lock(); list_for_each_entry_rcu(ptype, head, list) { struct sk_buff *p; -- cgit From f0d44ae310bc8eb0b6694e257015d8b24e1a357c Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 14 Jan 2009 14:38:02 -0800 Subject: phylib: Fix Freescale TBI PHY detection Freescale on-chip TBI PHYs reports PHY ID as 0x0, but as of commit 3ee82383f0098a2e13acc8cf1be8e47512f41e5a Author: Giulio Benetti Date: Thu Nov 13 21:53:13 2008 +0000 phy: fix phy address bug PHYID returns 0xffff and not 0xffffffff when not found and in some case(at91sam9263) 0x0. Maybe this patch could be useful. phy_device.c treats PHY ID == 0x0 as bogus IDs, and that results in gianfar driver failure to see the TBI PHYs. This code snippet triggers: if (!priv->tbiphy) { printk(KERN_WARNING "SGMII mode requires that the device " "tree specify a tbi-handle\n"); return; } Although tbi-handle is specified in the device tree. Btw, technically PHY ID == 0x0 is a valid ID (if we ever see a PHY manufactured by Xerox :-). Signed-off-by: Anton Vorontsov Acked-by: Andy Fleming Signed-off-by: David S. Miller --- drivers/net/phy/phy_device.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index e35460165bf..0a06e4fd37d 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -231,15 +231,6 @@ struct phy_device * get_phy_device(struct mii_bus *bus, int addr) if ((phy_id & 0x1fffffff) == 0x1fffffff) return NULL; - /* - * Broken hardware is sometimes missing the pull-up resistor on the - * MDIO line, which results in reads to non-existent devices returning - * 0 rather than 0xffff. Catch this here and treat 0 as a non-existent - * device as well. - */ - if (phy_id == 0) - return NULL; - dev = phy_device_create(bus, addr, phy_id); return dev; -- cgit From bae584316045011ce3376816585a305d2b9b76f2 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Wed, 14 Jan 2009 14:41:00 -0800 Subject: i4l: do not print a warning when shutting down an i4l ppp interface When an i4l ppp interface is shut down (e.g. with /sbin/ifdown ippp0) a scary warning is logged: isdn_free_channel: called with invalid drv(-1) or channel(-1) This warning is caused by isdn_net_unbind_channel(), which always calls isdn_free_channel() even if isdn_net_local->isdn_device and isdn_net_local->isdn_channel are (still) in a perfectly acceptable default state, so let's not do that. Signed-off-by: Paul Bolle Signed-off-by: David S. Miller --- drivers/isdn/i4l/isdn_net.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c index 7c5f97033b9..de6be7181f0 100644 --- a/drivers/isdn/i4l/isdn_net.c +++ b/drivers/isdn/i4l/isdn_net.c @@ -292,7 +292,9 @@ isdn_net_unbind_channel(isdn_net_local * lp) lp->dialstate = 0; dev->rx_netdev[isdn_dc2minor(lp->isdn_device, lp->isdn_channel)] = NULL; dev->st_netdev[isdn_dc2minor(lp->isdn_device, lp->isdn_channel)] = NULL; - isdn_free_channel(lp->isdn_device, lp->isdn_channel, ISDN_USAGE_NET); + if (lp->isdn_device != -1 && lp->isdn_channel != -1) + isdn_free_channel(lp->isdn_device, lp->isdn_channel, + ISDN_USAGE_NET); lp->flags &= ~ISDN_NET_CONNECTED; lp->isdn_device = -1; lp->isdn_channel = -1; -- cgit From 5f3e54057c62e5f654c66e4ce1172993f67fc284 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Wed, 14 Jan 2009 14:42:21 -0800 Subject: i4l: minor cleanups Minor cleanups, either made possible or obvious after commit d700555 (I4l: convert to net_device_ops). Signed-off-by: Paul Bolle Signed-off-by: David S. Miller --- drivers/isdn/i4l/isdn_net.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c index de6be7181f0..cb8943da4f1 100644 --- a/drivers/isdn/i4l/isdn_net.c +++ b/drivers/isdn/i4l/isdn_net.c @@ -2515,7 +2515,6 @@ static const struct net_device_ops isdn_netdev_ops = { .ndo_stop = isdn_net_close, .ndo_do_ioctl = isdn_net_ioctl, - .ndo_validate_addr = NULL, .ndo_start_xmit = isdn_net_start_xmit, .ndo_get_stats = isdn_net_get_stats, .ndo_tx_timeout = isdn_net_tx_timeout, @@ -2530,12 +2529,8 @@ static void _isdn_setup(struct net_device *dev) ether_setup(dev); - dev->flags = IFF_NOARP | IFF_POINTOPOINT; /* Setup the generic properties */ - dev->mtu = 1500; dev->flags = IFF_NOARP|IFF_POINTOPOINT; - dev->type = ARPHRD_ETHER; - dev->addr_len = ETH_ALEN; dev->header_ops = NULL; dev->netdev_ops = &isdn_netdev_ops; -- cgit From fc8c7dc1b29560c016a67a34ccff32a712b5aa86 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 14 Jan 2009 14:55:35 -0800 Subject: xfrm: For 32/64 compatability wrt. xfrm_usersa_info Reported by Jiri Klimes. Fix suggested by Patrick McHardy. Signed-off-by: David S. Miller --- net/xfrm/xfrm_user.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index b95a2d64eb5..7877e7975da 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -1914,10 +1914,17 @@ static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, } #endif +/* For the xfrm_usersa_info cases we have to work around some 32-bit vs. + * 64-bit compatability issues. On 32-bit the structure is 220 bytes, but + * for 64-bit it gets padded out to 224 bytes. Those bytes are just + * padding and don't have any content we care about. Therefore as long + * as we have enough bytes for the content we can make both cases work. + */ + #define XMSGSIZE(type) sizeof(struct type) static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = { - [XFRM_MSG_NEWSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info), + [XFRM_MSG_NEWSA - XFRM_MSG_BASE] = 220, /* see above */ [XFRM_MSG_DELSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_id), [XFRM_MSG_GETSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_id), [XFRM_MSG_NEWPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info), @@ -1927,7 +1934,7 @@ static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = { [XFRM_MSG_ACQUIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_acquire), [XFRM_MSG_EXPIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_expire), [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info), - [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info), + [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = 220, /* see above */ [XFRM_MSG_POLEXPIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_polexpire), [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_flush), [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = 0, -- cgit From b8a1b1ce14252b59b2d5c89de25b54f9bfd4cc5e Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Wed, 14 Jan 2009 14:55:41 -0800 Subject: IPoIB: Fix hang in napi_disable() if P_Key is never found After commit fe25c561 ("IPoIB: Don't enable NAPI when it's already enabled"), if an interface is brought up but the corresponding P_Key never appears, then ipoib_stop() will hang in napi_disable(), because ipoib_open() returns before it does napi_enable(). Fix this by changing ipoib_open() to call napi_enable() even if the P_Key isn't present. Reported-by: Yossi Etigin Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/ipoib/ipoib_main.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index dce0443f9d6..0bd2a4ff084 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -106,23 +106,17 @@ int ipoib_open(struct net_device *dev) ipoib_dbg(priv, "bringing up interface\n"); - set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags); + if (!test_and_set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) + napi_enable(&priv->napi); if (ipoib_pkey_dev_delay_open(dev)) return 0; - napi_enable(&priv->napi); + if (ipoib_ib_dev_open(dev)) + goto err_disable; - if (ipoib_ib_dev_open(dev)) { - napi_disable(&priv->napi); - return -EINVAL; - } - - if (ipoib_ib_dev_up(dev)) { - ipoib_ib_dev_stop(dev, 1); - napi_disable(&priv->napi); - return -EINVAL; - } + if (ipoib_ib_dev_up(dev)) + goto err_stop; if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) { struct ipoib_dev_priv *cpriv; @@ -144,6 +138,15 @@ int ipoib_open(struct net_device *dev) netif_start_queue(dev); return 0; + +err_stop: + ipoib_ib_dev_stop(dev, 1); + +err_disable: + napi_disable(&priv->napi); + clear_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags); + + return -EINVAL; } static int ipoib_stop(struct net_device *dev) -- cgit From 95c4bff0308eb0819436b730a836846d3e784657 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Wed, 14 Jan 2009 23:37:46 +0300 Subject: x86: headers cleanup - boot.h Impact: cleanup 'make headers_check' warn us about leaking of kernel private (mostly compile time vars) data to userspace in headers. Fix it. Neither BOOT_HEAP_SIZE, BOOT_STACK_SIZE refs was found by searching thru net (ie in user-space area) so fence this all by __KERNEL__ guard. Signed-off-by: Cyrill Gorcunov Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/boot.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/asm/boot.h b/arch/x86/include/asm/boot.h index c0e8e68a31f..6526cf08b0e 100644 --- a/arch/x86/include/asm/boot.h +++ b/arch/x86/include/asm/boot.h @@ -10,14 +10,16 @@ #define EXTENDED_VGA 0xfffe /* 80x50 mode */ #define ASK_VGA 0xfffd /* ask for it at bootup */ +#ifdef __KERNEL__ + /* Physical address where kernel should be loaded. */ #define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \ + (CONFIG_PHYSICAL_ALIGN - 1)) \ & ~(CONFIG_PHYSICAL_ALIGN - 1)) -#if (defined CONFIG_KERNEL_BZIP2) +#ifdef CONFIG_KERNEL_BZIP2 #define BOOT_HEAP_SIZE 0x400000 -#else +#else /* !CONFIG_KERNEL_BZIP2 */ #ifdef CONFIG_X86_64 #define BOOT_HEAP_SIZE 0x7000 @@ -25,7 +27,7 @@ #define BOOT_HEAP_SIZE 0x4000 #endif -#endif +#endif /* !CONFIG_KERNEL_BZIP2 */ #ifdef CONFIG_X86_64 #define BOOT_STACK_SIZE 0x4000 @@ -33,4 +35,6 @@ #define BOOT_STACK_SIZE 0x1000 #endif +#endif /* __KERNEL__ */ + #endif /* _ASM_X86_BOOT_H */ -- cgit From ee287587dafd77fd211e50637561224605c214b4 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 14 Jan 2009 16:07:38 -0800 Subject: bzip2/lzma: update boot protocol specification Impact: documentation Update the boot protocol specification to include the currently supported file formats and their magic numbers. Signed-off-by: H. Peter Anvin --- Documentation/x86/boot.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/x86/boot.txt b/Documentation/x86/boot.txt index fcdc62b3c3d..9ac70ffe2b7 100644 --- a/Documentation/x86/boot.txt +++ b/Documentation/x86/boot.txt @@ -542,7 +542,10 @@ Protocol: 2.08+ The payload may be compressed. The format of both the compressed and uncompressed data should be determined using the standard magic - numbers. Currently only gzip compressed ELF is used. + numbers. The currently supported compression formats are gzip + (magic numbers 1F 8B or 1F 9E), bzip2 (magic number 42 5A) and LZMA + (magic number 5D 00). The uncompressed payload is currently always ELF + (magic number 7F 45 4C 46). Field name: payload_length Type: read -- cgit From aa0effbd1c0269ce7dd13be8dbf13e6b04f30ebd Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Tue, 13 Jan 2009 19:31:29 -0800 Subject: cris: introduce asm/swab.h Adjust the arch overrides to the new names as well. Signed-off-by: Harvey Harrison Signed-off-by: Linus Torvalds --- arch/cris/include/arch-v10/arch/byteorder.h | 26 ------------------------- arch/cris/include/arch-v10/arch/swab.h | 30 +++++++++++++++++++++++++++++ arch/cris/include/arch-v32/arch/byteorder.h | 20 ------------------- arch/cris/include/arch-v32/arch/swab.h | 24 +++++++++++++++++++++++ arch/cris/include/asm/Kbuild | 1 + arch/cris/include/asm/byteorder.h | 20 +------------------ arch/cris/include/asm/swab.h | 8 ++++++++ 7 files changed, 64 insertions(+), 65 deletions(-) delete mode 100644 arch/cris/include/arch-v10/arch/byteorder.h create mode 100644 arch/cris/include/arch-v10/arch/swab.h delete mode 100644 arch/cris/include/arch-v32/arch/byteorder.h create mode 100644 arch/cris/include/arch-v32/arch/swab.h create mode 100644 arch/cris/include/asm/swab.h diff --git a/arch/cris/include/arch-v10/arch/byteorder.h b/arch/cris/include/arch-v10/arch/byteorder.h deleted file mode 100644 index 255b646b7fa..00000000000 --- a/arch/cris/include/arch-v10/arch/byteorder.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _CRIS_ARCH_BYTEORDER_H -#define _CRIS_ARCH_BYTEORDER_H - -#include -#include - -/* we just define these two (as we can do the swap in a single - * asm instruction in CRIS) and the arch-independent files will put - * them together into ntohl etc. - */ - -static inline __attribute_const__ __u32 ___arch__swab32(__u32 x) -{ - __asm__ ("swapwb %0" : "=r" (x) : "0" (x)); - - return(x); -} - -static inline __attribute_const__ __u16 ___arch__swab16(__u16 x) -{ - __asm__ ("swapb %0" : "=r" (x) : "0" (x)); - - return(x); -} - -#endif diff --git a/arch/cris/include/arch-v10/arch/swab.h b/arch/cris/include/arch-v10/arch/swab.h new file mode 100644 index 00000000000..e4e847d8a05 --- /dev/null +++ b/arch/cris/include/arch-v10/arch/swab.h @@ -0,0 +1,30 @@ +#ifndef _CRIS_ARCH_SWAB_H +#define _CRIS_ARCH_SWAB_H + +#include +#include + +#define __SWAB_64_THRU_32__ + +/* we just define these two (as we can do the swap in a single + * asm instruction in CRIS) and the arch-independent files will put + * them together into ntohl etc. + */ + +static inline __attribute_const__ __u32 __arch_swab32(__u32 x) +{ + __asm__ ("swapwb %0" : "=r" (x) : "0" (x)); + + return(x); +} +#define __arch_swab32 __arch_swab32 + +static inline __attribute_const__ __u16 __arch_swab16(__u16 x) +{ + __asm__ ("swapb %0" : "=r" (x) : "0" (x)); + + return(x); +} +#define __arch_swab16 __arch_swab16 + +#endif diff --git a/arch/cris/include/arch-v32/arch/byteorder.h b/arch/cris/include/arch-v32/arch/byteorder.h deleted file mode 100644 index 6ef8fb4a35f..00000000000 --- a/arch/cris/include/arch-v32/arch/byteorder.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef _ASM_CRIS_ARCH_BYTEORDER_H -#define _ASM_CRIS_ARCH_BYTEORDER_H - -#include - -static inline __const__ __u32 -___arch__swab32(__u32 x) -{ - __asm__ __volatile__ ("swapwb %0" : "=r" (x) : "0" (x)); - return (x); -} - -static inline __const__ __u16 -___arch__swab16(__u16 x) -{ - __asm__ __volatile__ ("swapb %0" : "=r" (x) : "0" (x)); - return (x); -} - -#endif /* _ASM_CRIS_ARCH_BYTEORDER_H */ diff --git a/arch/cris/include/arch-v32/arch/swab.h b/arch/cris/include/arch-v32/arch/swab.h new file mode 100644 index 00000000000..9a4ea5e209c --- /dev/null +++ b/arch/cris/include/arch-v32/arch/swab.h @@ -0,0 +1,24 @@ +#ifndef _ASM_CRIS_ARCH_SWAB_H +#define _ASM_CRIS_ARCH_SWAB_H + +#include + +#define __SWAB_64_THRU_32__ + +static inline __const__ __u32 +__arch_swab32(__u32 x) +{ + __asm__ __volatile__ ("swapwb %0" : "=r" (x) : "0" (x)); + return (x); +} +#define __arch_swab32 __arch_swab32 + +static inline __const__ __u16 +__arch_swab16(__u16 x) +{ + __asm__ __volatile__ ("swapb %0" : "=r" (x) : "0" (x)); + return (x); +} +#define __arch_swab16 __arch_swab16 + +#endif /* _ASM_CRIS_ARCH_SWAB_H */ diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild index d5b631935ec..b79b7c6543a 100644 --- a/arch/cris/include/asm/Kbuild +++ b/arch/cris/include/asm/Kbuild @@ -9,3 +9,4 @@ header-y += sync_serial.h unifdef-y += etraxgpio.h unifdef-y += rs485.h +unifdef-y += swab.h diff --git a/arch/cris/include/asm/byteorder.h b/arch/cris/include/asm/byteorder.h index cc8e418cfd1..7678d86317a 100644 --- a/arch/cris/include/asm/byteorder.h +++ b/arch/cris/include/asm/byteorder.h @@ -1,25 +1,7 @@ #ifndef _CRIS_BYTEORDER_H #define _CRIS_BYTEORDER_H -#ifdef __GNUC__ - -#ifdef __KERNEL__ -#include - -/* defines are necessary because the other files detect the presence - * of a defined __arch_swab32, not an inline - */ -#define __arch__swab32(x) ___arch__swab32(x) -#define __arch__swab16(x) ___arch__swab16(x) -#endif /* __KERNEL__ */ - -#if !defined(__STRICT_ANSI__) || defined(__KERNEL__) -# define __BYTEORDER_HAS_U64__ -# define __SWAB_64_THRU_32__ -#endif - -#endif /* __GNUC__ */ - +#include #include #endif diff --git a/arch/cris/include/asm/swab.h b/arch/cris/include/asm/swab.h new file mode 100644 index 00000000000..80668e88419 --- /dev/null +++ b/arch/cris/include/asm/swab.h @@ -0,0 +1,8 @@ +#ifndef _CRIS_SWAB_H +#define _CRIS_SWAB_H + +#ifdef __KERNEL__ +#include +#endif /* __KERNEL__ */ + +#endif /* _CRIS_SWAB_H */ -- cgit From 74d96f018673759d04d032c137d132f6447bfb1e Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Tue, 13 Jan 2009 19:27:09 -0800 Subject: byteorder: make swab.h include asm/swab.h like a regular header Add swab.h to kbuild.asm and remove the individual entries from each arch, mark as unifdef as some arches have some kernel-only bits inside. Signed-off-by: Harvey Harrison Signed-off-by: Linus Torvalds --- arch/alpha/include/asm/Kbuild | 1 - arch/alpha/include/asm/byteorder.h | 1 - arch/arm/include/asm/Kbuild | 1 - arch/arm/include/asm/byteorder.h | 2 -- arch/avr32/include/asm/Kbuild | 1 - arch/avr32/include/asm/byteorder.h | 1 - arch/blackfin/include/asm/Kbuild | 1 - arch/blackfin/include/asm/byteorder.h | 1 - arch/cris/include/asm/Kbuild | 1 - arch/cris/include/asm/byteorder.h | 1 - arch/h8300/include/asm/Kbuild | 1 - arch/h8300/include/asm/byteorder.h | 1 - arch/ia64/include/asm/Kbuild | 1 - arch/ia64/include/asm/byteorder.h | 1 - arch/m68knommu/include/asm/Kbuild | 2 -- arch/m68knommu/include/asm/byteorder.h | 1 - arch/mips/include/asm/Kbuild | 1 - arch/mips/include/asm/byteorder.h | 2 -- arch/parisc/include/asm/Kbuild | 1 - arch/parisc/include/asm/byteorder.h | 1 - arch/powerpc/include/asm/Kbuild | 1 - arch/powerpc/include/asm/byteorder.h | 2 -- arch/s390/include/asm/Kbuild | 1 - arch/s390/include/asm/byteorder.h | 1 - arch/sh/include/asm/Kbuild | 1 - arch/sh/include/asm/byteorder.h | 2 -- arch/sparc/include/asm/Kbuild | 1 - arch/sparc/include/asm/byteorder.h | 1 - arch/x86/include/asm/Kbuild | 1 - arch/x86/include/asm/byteorder.h | 1 - arch/xtensa/include/asm/Kbuild | 2 -- arch/xtensa/include/asm/byteorder.h | 2 -- include/asm-frv/Kbuild | 1 - include/asm-frv/byteorder.h | 1 - include/asm-generic/Kbuild.asm | 1 + include/asm-m32r/Kbuild | 1 - include/asm-m32r/byteorder.h | 2 -- include/asm-m68k/Kbuild | 1 - include/asm-m68k/byteorder.h | 1 - include/asm-mn10300/Kbuild | 1 - include/asm-mn10300/byteorder.h | 1 - include/linux/swab.h | 2 +- 42 files changed, 2 insertions(+), 49 deletions(-) diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild index 4dad2736057..b7c8f188b31 100644 --- a/arch/alpha/include/asm/Kbuild +++ b/arch/alpha/include/asm/Kbuild @@ -9,4 +9,3 @@ unifdef-y += console.h unifdef-y += fpu.h unifdef-y += sysinfo.h unifdef-y += compiler.h -unifdef-y += swab.h diff --git a/arch/alpha/include/asm/byteorder.h b/arch/alpha/include/asm/byteorder.h index 6772f316870..73683093202 100644 --- a/arch/alpha/include/asm/byteorder.h +++ b/arch/alpha/include/asm/byteorder.h @@ -1,7 +1,6 @@ #ifndef _ALPHA_BYTEORDER_H #define _ALPHA_BYTEORDER_H -#include #include #endif /* _ALPHA_BYTEORDER_H */ diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild index 43b0b2ba392..73237bd130a 100644 --- a/arch/arm/include/asm/Kbuild +++ b/arch/arm/include/asm/Kbuild @@ -1,4 +1,3 @@ include include/asm-generic/Kbuild.asm unifdef-y += hwcap.h -unifdef-y += swab.h diff --git a/arch/arm/include/asm/byteorder.h b/arch/arm/include/asm/byteorder.h index c02b6fc28e1..77379748b17 100644 --- a/arch/arm/include/asm/byteorder.h +++ b/arch/arm/include/asm/byteorder.h @@ -15,8 +15,6 @@ #ifndef __ASM_ARM_BYTEORDER_H #define __ASM_ARM_BYTEORDER_H -#include - #ifdef __ARMEB__ #include #else diff --git a/arch/avr32/include/asm/Kbuild b/arch/avr32/include/asm/Kbuild index 219822c8ad1..3136628ba8d 100644 --- a/arch/avr32/include/asm/Kbuild +++ b/arch/avr32/include/asm/Kbuild @@ -1,4 +1,3 @@ include include/asm-generic/Kbuild.asm -header-y += swab.h header-y += cachectl.h diff --git a/arch/avr32/include/asm/byteorder.h b/arch/avr32/include/asm/byteorder.h index 2aba64b4e12..50abc21619a 100644 --- a/arch/avr32/include/asm/byteorder.h +++ b/arch/avr32/include/asm/byteorder.h @@ -4,7 +4,6 @@ #ifndef __ASM_AVR32_BYTEORDER_H #define __ASM_AVR32_BYTEORDER_H -#include #include #endif /* __ASM_AVR32_BYTEORDER_H */ diff --git a/arch/blackfin/include/asm/Kbuild b/arch/blackfin/include/asm/Kbuild index d0d1ac43554..606ecfdcc96 100644 --- a/arch/blackfin/include/asm/Kbuild +++ b/arch/blackfin/include/asm/Kbuild @@ -1,4 +1,3 @@ include include/asm-generic/Kbuild.asm unifdef-y += fixed_code.h -unifdef-y += swab.h diff --git a/arch/blackfin/include/asm/byteorder.h b/arch/blackfin/include/asm/byteorder.h index b9e797a497b..3e69106a4d3 100644 --- a/arch/blackfin/include/asm/byteorder.h +++ b/arch/blackfin/include/asm/byteorder.h @@ -1,7 +1,6 @@ #ifndef _BLACKFIN_BYTEORDER_H #define _BLACKFIN_BYTEORDER_H -#include #include #endif /* _BLACKFIN_BYTEORDER_H */ diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild index b79b7c6543a..d5b631935ec 100644 --- a/arch/cris/include/asm/Kbuild +++ b/arch/cris/include/asm/Kbuild @@ -9,4 +9,3 @@ header-y += sync_serial.h unifdef-y += etraxgpio.h unifdef-y += rs485.h -unifdef-y += swab.h diff --git a/arch/cris/include/asm/byteorder.h b/arch/cris/include/asm/byteorder.h index 7678d86317a..bcd189798e2 100644 --- a/arch/cris/include/asm/byteorder.h +++ b/arch/cris/include/asm/byteorder.h @@ -1,7 +1,6 @@ #ifndef _CRIS_BYTEORDER_H #define _CRIS_BYTEORDER_H -#include #include #endif diff --git a/arch/h8300/include/asm/Kbuild b/arch/h8300/include/asm/Kbuild index 27b108a86b3..c68e1680da0 100644 --- a/arch/h8300/include/asm/Kbuild +++ b/arch/h8300/include/asm/Kbuild @@ -1,2 +1 @@ include include/asm-generic/Kbuild.asm -unifdef-y += swab.h diff --git a/arch/h8300/include/asm/byteorder.h b/arch/h8300/include/asm/byteorder.h index c36b80a3dd8..13539da99ef 100644 --- a/arch/h8300/include/asm/byteorder.h +++ b/arch/h8300/include/asm/byteorder.h @@ -1,7 +1,6 @@ #ifndef _H8300_BYTEORDER_H #define _H8300_BYTEORDER_H -#include #include #endif /* _H8300_BYTEORDER_H */ diff --git a/arch/ia64/include/asm/Kbuild b/arch/ia64/include/asm/Kbuild index 3b25bd9dca9..ccbe8ae47a6 100644 --- a/arch/ia64/include/asm/Kbuild +++ b/arch/ia64/include/asm/Kbuild @@ -14,4 +14,3 @@ unifdef-y += gcc_intrin.h unifdef-y += intrinsics.h unifdef-y += perfmon.h unifdef-y += ustack.h -unifdef-y += swab.h diff --git a/arch/ia64/include/asm/byteorder.h b/arch/ia64/include/asm/byteorder.h index 0f84c5cb703..a8dd7355815 100644 --- a/arch/ia64/include/asm/byteorder.h +++ b/arch/ia64/include/asm/byteorder.h @@ -1,7 +1,6 @@ #ifndef _ASM_IA64_BYTEORDER_H #define _ASM_IA64_BYTEORDER_H -#include #include #endif /* _ASM_IA64_BYTEORDER_H */ diff --git a/arch/m68knommu/include/asm/Kbuild b/arch/m68knommu/include/asm/Kbuild index 58c02a45413..c68e1680da0 100644 --- a/arch/m68knommu/include/asm/Kbuild +++ b/arch/m68knommu/include/asm/Kbuild @@ -1,3 +1 @@ include include/asm-generic/Kbuild.asm - -unifdef-y += swab.h diff --git a/arch/m68knommu/include/asm/byteorder.h b/arch/m68knommu/include/asm/byteorder.h index a6f0b8f7f62..9c6c76a1504 100644 --- a/arch/m68knommu/include/asm/byteorder.h +++ b/arch/m68knommu/include/asm/byteorder.h @@ -1,7 +1,6 @@ #ifndef _M68KNOMMU_BYTEORDER_H #define _M68KNOMMU_BYTEORDER_H -#include #include #endif /* _M68KNOMMU_BYTEORDER_H */ diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild index 023866c0c10..7897f05e316 100644 --- a/arch/mips/include/asm/Kbuild +++ b/arch/mips/include/asm/Kbuild @@ -1,4 +1,3 @@ include include/asm-generic/Kbuild.asm header-y += cachectl.h sgidefs.h sysmips.h -header-y += swab.h diff --git a/arch/mips/include/asm/byteorder.h b/arch/mips/include/asm/byteorder.h index 607b7183070..9579051ff1c 100644 --- a/arch/mips/include/asm/byteorder.h +++ b/arch/mips/include/asm/byteorder.h @@ -8,8 +8,6 @@ #ifndef _ASM_BYTEORDER_H #define _ASM_BYTEORDER_H -#include - #if defined(__MIPSEB__) #include #elif defined(__MIPSEL__) diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild index 2121d99f836..f88b252e419 100644 --- a/arch/parisc/include/asm/Kbuild +++ b/arch/parisc/include/asm/Kbuild @@ -1,4 +1,3 @@ include include/asm-generic/Kbuild.asm unifdef-y += pdc.h -unifdef-y += swab.h diff --git a/arch/parisc/include/asm/byteorder.h b/arch/parisc/include/asm/byteorder.h index da66029c4cb..58af2c5f5d6 100644 --- a/arch/parisc/include/asm/byteorder.h +++ b/arch/parisc/include/asm/byteorder.h @@ -1,7 +1,6 @@ #ifndef _PARISC_BYTEORDER_H #define _PARISC_BYTEORDER_H -#include #include #endif /* _PARISC_BYTEORDER_H */ diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild index 9268602de5d..5ab7d7fe198 100644 --- a/arch/powerpc/include/asm/Kbuild +++ b/arch/powerpc/include/asm/Kbuild @@ -35,4 +35,3 @@ unifdef-y += spu_info.h unifdef-y += termios.h unifdef-y += types.h unifdef-y += unistd.h -unifdef-y += swab.h diff --git a/arch/powerpc/include/asm/byteorder.h b/arch/powerpc/include/asm/byteorder.h index 5cca27a4153..aa6cc4fac96 100644 --- a/arch/powerpc/include/asm/byteorder.h +++ b/arch/powerpc/include/asm/byteorder.h @@ -7,8 +7,6 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ - -#include #include #endif /* _ASM_POWERPC_BYTEORDER_H */ diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild index f2af4167bd5..63a23415fba 100644 --- a/arch/s390/include/asm/Kbuild +++ b/arch/s390/include/asm/Kbuild @@ -13,4 +13,3 @@ unifdef-y += cmb.h unifdef-y += debug.h unifdef-y += chpid.h unifdef-y += schid.h -unifdef-y += swab.h diff --git a/arch/s390/include/asm/byteorder.h b/arch/s390/include/asm/byteorder.h index b95a2b2933f..a332e59e26f 100644 --- a/arch/s390/include/asm/byteorder.h +++ b/arch/s390/include/asm/byteorder.h @@ -1,7 +1,6 @@ #ifndef _S390_BYTEORDER_H #define _S390_BYTEORDER_H -#include #include #endif /* _S390_BYTEORDER_H */ diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild index f1a2a0d1c79..43910cdf78a 100644 --- a/arch/sh/include/asm/Kbuild +++ b/arch/sh/include/asm/Kbuild @@ -6,4 +6,3 @@ unifdef-y += unistd_32.h unifdef-y += unistd_64.h unifdef-y += posix_types_32.h unifdef-y += posix_types_64.h -unifdef-y += swab.h diff --git a/arch/sh/include/asm/byteorder.h b/arch/sh/include/asm/byteorder.h index e95c41a5c8c..db2f5d7cb17 100644 --- a/arch/sh/include/asm/byteorder.h +++ b/arch/sh/include/asm/byteorder.h @@ -1,8 +1,6 @@ #ifndef __ASM_SH_BYTEORDER_H #define __ASM_SH_BYTEORDER_H -#include - #ifdef __LITTLE_ENDIAN__ #include #else diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild index 95e38a43dff..deeb0fba802 100644 --- a/arch/sparc/include/asm/Kbuild +++ b/arch/sparc/include/asm/Kbuild @@ -17,4 +17,3 @@ header-y += traps.h header-y += uctx.h header-y += utrap.h header-y += watchdog.h -header-y += swab.h diff --git a/arch/sparc/include/asm/byteorder.h b/arch/sparc/include/asm/byteorder.h index 48a047cd6fa..ccc1b6b7de6 100644 --- a/arch/sparc/include/asm/byteorder.h +++ b/arch/sparc/include/asm/byteorder.h @@ -1,7 +1,6 @@ #ifndef _SPARC_BYTEORDER_H #define _SPARC_BYTEORDER_H -#include #include #endif /* _SPARC_BYTEORDER_H */ diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index a9f8a814a1f..4a8e80cdcfa 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -22,4 +22,3 @@ unifdef-y += unistd_32.h unifdef-y += unistd_64.h unifdef-y += vm86.h unifdef-y += vsyscall.h -unifdef-y += swab.h diff --git a/arch/x86/include/asm/byteorder.h b/arch/x86/include/asm/byteorder.h index 7c49917e3d9..b13a7a88f3e 100644 --- a/arch/x86/include/asm/byteorder.h +++ b/arch/x86/include/asm/byteorder.h @@ -1,7 +1,6 @@ #ifndef _ASM_X86_BYTEORDER_H #define _ASM_X86_BYTEORDER_H -#include #include #endif /* _ASM_X86_BYTEORDER_H */ diff --git a/arch/xtensa/include/asm/Kbuild b/arch/xtensa/include/asm/Kbuild index 58c02a45413..c68e1680da0 100644 --- a/arch/xtensa/include/asm/Kbuild +++ b/arch/xtensa/include/asm/Kbuild @@ -1,3 +1 @@ include include/asm-generic/Kbuild.asm - -unifdef-y += swab.h diff --git a/arch/xtensa/include/asm/byteorder.h b/arch/xtensa/include/asm/byteorder.h index 329b94591ca..54eb6315349 100644 --- a/arch/xtensa/include/asm/byteorder.h +++ b/arch/xtensa/include/asm/byteorder.h @@ -1,8 +1,6 @@ #ifndef _XTENSA_BYTEORDER_H #define _XTENSA_BYTEORDER_H -#include - #ifdef __XTENSA_EL__ #include #elif defined(__XTENSA_EB__) diff --git a/include/asm-frv/Kbuild b/include/asm-frv/Kbuild index 1f44e7c7699..0f8956def73 100644 --- a/include/asm-frv/Kbuild +++ b/include/asm-frv/Kbuild @@ -3,4 +3,3 @@ include include/asm-generic/Kbuild.asm header-y += registers.h unifdef-y += termios.h -unifdef-y += swab.h diff --git a/include/asm-frv/byteorder.h b/include/asm-frv/byteorder.h index 1187e51ecd1..f29b7593e08 100644 --- a/include/asm-frv/byteorder.h +++ b/include/asm-frv/byteorder.h @@ -1,7 +1,6 @@ #ifndef _ASM_BYTEORDER_H #define _ASM_BYTEORDER_H -#include #include #endif /* _ASM_BYTEORDER_H */ diff --git a/include/asm-generic/Kbuild.asm b/include/asm-generic/Kbuild.asm index 1870d5e05f1..70d185534b9 100644 --- a/include/asm-generic/Kbuild.asm +++ b/include/asm-generic/Kbuild.asm @@ -31,6 +31,7 @@ unifdef-y += socket.h unifdef-y += sockios.h unifdef-y += stat.h unifdef-y += statfs.h +unifdef-y += swab.h unifdef-y += termbits.h unifdef-y += termios.h unifdef-y += types.h diff --git a/include/asm-m32r/Kbuild b/include/asm-m32r/Kbuild index 27b108a86b3..c68e1680da0 100644 --- a/include/asm-m32r/Kbuild +++ b/include/asm-m32r/Kbuild @@ -1,2 +1 @@ include include/asm-generic/Kbuild.asm -unifdef-y += swab.h diff --git a/include/asm-m32r/byteorder.h b/include/asm-m32r/byteorder.h index 61ff9cfd845..21855d8b028 100644 --- a/include/asm-m32r/byteorder.h +++ b/include/asm-m32r/byteorder.h @@ -1,8 +1,6 @@ #ifndef _ASM_M32R_BYTEORDER_H #define _ASM_M32R_BYTEORDER_H -#include - #if defined(__LITTLE_ENDIAN__) # include #else diff --git a/include/asm-m68k/Kbuild b/include/asm-m68k/Kbuild index 52fd96b4142..1a922fad76f 100644 --- a/include/asm-m68k/Kbuild +++ b/include/asm-m68k/Kbuild @@ -1,3 +1,2 @@ include include/asm-generic/Kbuild.asm header-y += cachectl.h -unifdef-y += swab.h diff --git a/include/asm-m68k/byteorder.h b/include/asm-m68k/byteorder.h index 300866523b8..31b260a8880 100644 --- a/include/asm-m68k/byteorder.h +++ b/include/asm-m68k/byteorder.h @@ -1,7 +1,6 @@ #ifndef _M68K_BYTEORDER_H #define _M68K_BYTEORDER_H -#include #include #endif /* _M68K_BYTEORDER_H */ diff --git a/include/asm-mn10300/Kbuild b/include/asm-mn10300/Kbuild index 27b108a86b3..c68e1680da0 100644 --- a/include/asm-mn10300/Kbuild +++ b/include/asm-mn10300/Kbuild @@ -1,2 +1 @@ include include/asm-generic/Kbuild.asm -unifdef-y += swab.h diff --git a/include/asm-mn10300/byteorder.h b/include/asm-mn10300/byteorder.h index 45b18ded19e..5dd0bdd9fee 100644 --- a/include/asm-mn10300/byteorder.h +++ b/include/asm-mn10300/byteorder.h @@ -1,7 +1,6 @@ #ifndef _ASM_BYTEORDER_H #define _ASM_BYTEORDER_H -#include #include #endif /* _ASM_BYTEORDER_H */ diff --git a/include/linux/swab.h b/include/linux/swab.h index be5284d4a05..ea0c02fd516 100644 --- a/include/linux/swab.h +++ b/include/linux/swab.h @@ -3,7 +3,7 @@ #include #include -#include +#include /* * casts are necessary for constants, because we never know how for sure -- cgit From 29b37f42127f7da511560a40ea74f5047da40c13 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 13 Jan 2009 11:26:18 +1100 Subject: crypto: authenc - Fix zero-length IV crash As it is if an algorithm with a zero-length IV is used (e.g., NULL encryption) with authenc, authenc may generate an SG entry of length zero, which will trigger a BUG check in the hash layer. This patch fixes it by skipping the IV SG generation if the IV size is zero. Signed-off-by: Herbert Xu --- crypto/authenc.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/crypto/authenc.c b/crypto/authenc.c index 40b6e9ec9e3..5793b64c81a 100644 --- a/crypto/authenc.c +++ b/crypto/authenc.c @@ -158,16 +158,19 @@ static int crypto_authenc_genicv(struct aead_request *req, u8 *iv, dstp = sg_page(dst); vdst = PageHighMem(dstp) ? NULL : page_address(dstp) + dst->offset; - sg_init_table(cipher, 2); - sg_set_buf(cipher, iv, ivsize); - authenc_chain(cipher, dst, vdst == iv + ivsize); + if (ivsize) { + sg_init_table(cipher, 2); + sg_set_buf(cipher, iv, ivsize); + authenc_chain(cipher, dst, vdst == iv + ivsize); + dst = cipher; + } cryptlen = req->cryptlen + ivsize; - hash = crypto_authenc_hash(req, flags, cipher, cryptlen); + hash = crypto_authenc_hash(req, flags, dst, cryptlen); if (IS_ERR(hash)) return PTR_ERR(hash); - scatterwalk_map_and_copy(hash, cipher, cryptlen, + scatterwalk_map_and_copy(hash, dst, cryptlen, crypto_aead_authsize(authenc), 1); return 0; } @@ -285,11 +288,14 @@ static int crypto_authenc_iverify(struct aead_request *req, u8 *iv, srcp = sg_page(src); vsrc = PageHighMem(srcp) ? NULL : page_address(srcp) + src->offset; - sg_init_table(cipher, 2); - sg_set_buf(cipher, iv, ivsize); - authenc_chain(cipher, src, vsrc == iv + ivsize); + if (ivsize) { + sg_init_table(cipher, 2); + sg_set_buf(cipher, iv, ivsize); + authenc_chain(cipher, src, vsrc == iv + ivsize); + src = cipher; + } - return crypto_authenc_verify(req, cipher, cryptlen + ivsize); + return crypto_authenc_verify(req, src, cryptlen + ivsize); } static int crypto_authenc_decrypt(struct aead_request *req) -- cgit From f557206800801410c30e53ce7a27219b2c4cf0ba Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 14 Jan 2009 20:40:03 -0800 Subject: gro: Fix page ref count for skbs freed normally When an skb with page frags is merged into an existing one, we cannibalise its reference count. This is OK when the skb is reused because we set nr_frags to zero in that case. However, for the case where the skb is freed through kfree_skb, we didn't clear nr_frags which causes the page to be freed prematurely. This is fixed by moving the skb resetting into skb_gro_receive. Reported-by: Jeff Kirsher Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/core/dev.c | 6 ------ net/core/skbuff.c | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index 7dec715293b..60377b6c0a8 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2491,12 +2491,6 @@ EXPORT_SYMBOL(napi_gro_receive); void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) { - skb_shinfo(skb)->nr_frags = 0; - - skb->len -= skb->data_len; - skb->truesize -= skb->data_len; - skb->data_len = 0; - __skb_pull(skb, skb_headlen(skb)); skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb)); diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 5110b359c75..65eac773903 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -2602,6 +2602,12 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) skb_shinfo(skb)->nr_frags * sizeof(skb_frag_t)); skb_shinfo(p)->nr_frags += skb_shinfo(skb)->nr_frags; + skb_shinfo(skb)->nr_frags = 0; + + skb->truesize -= skb->data_len; + skb->len -= skb->data_len; + skb->data_len = 0; + NAPI_GRO_CB(skb)->free = 1; goto done; } -- cgit From 4e704ee3c2cd38748ca59d835435d6a7e7f6f613 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 14 Jan 2009 20:41:12 -0800 Subject: gso: Ensure that the packet is long enough When we get a GSO packet from an untrusted source, we need to ensure that it is sufficiently long so that we don't end up crashing. Based on discovery and patch by Ian Campbell. Signed-off-by: Herbert Xu Tested-by: Ian Campbell Signed-off-by: David S. Miller --- net/ipv4/tcp.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 48ada1b2d2c..0cd71b84e48 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2389,7 +2389,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features) unsigned int seq; __be32 delta; unsigned int oldlen; - unsigned int len; + unsigned int mss; if (!pskb_may_pull(skb, sizeof(*th))) goto out; @@ -2405,10 +2405,13 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features) oldlen = (u16)~skb->len; __skb_pull(skb, thlen); + mss = skb_shinfo(skb)->gso_size; + if (unlikely(skb->len <= mss)) + goto out; + if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) { /* Packet is from an untrusted source, reset gso_segs. */ int type = skb_shinfo(skb)->gso_type; - int mss; if (unlikely(type & ~(SKB_GSO_TCPV4 | @@ -2419,7 +2422,6 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features) !(type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)))) goto out; - mss = skb_shinfo(skb)->gso_size; skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(skb->len, mss); segs = NULL; @@ -2430,8 +2432,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features) if (IS_ERR(segs)) goto out; - len = skb_shinfo(skb)->gso_size; - delta = htonl(oldlen + (thlen + len)); + delta = htonl(oldlen + (thlen + mss)); skb = segs; th = tcp_hdr(skb); @@ -2447,7 +2448,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features) csum_fold(csum_partial(skb_transport_header(skb), thlen, skb->csum)); - seq += len; + seq += mss; skb = skb->next; th = tcp_hdr(skb); -- cgit From d7e094d4212bc72f5575e54edfef1349e0c4cdb5 Mon Sep 17 00:00:00 2001 From: Mike Ditto Date: Wed, 14 Jan 2009 20:43:43 -0800 Subject: powerpc/fs_enet: Add missing irq free in error path. If something goes wrong attaching to phy driver, we weren't freeing the IRQ. Signed-off-by: Mike Ditto Signed-off-by: David S. Miller --- drivers/net/fs_enet/fs_enet-main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 4e6a9195fe5..ce900e54d8d 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -795,6 +795,7 @@ static int fs_enet_open(struct net_device *dev) err = fs_init_phy(dev); if (err) { + free_irq(fep->interrupt, dev); if (fep->fpi->use_napi) napi_disable(&fep->napi); return err; -- cgit From d1d5e6b1cead3df6f722d1d458874bd7f93da8d6 Mon Sep 17 00:00:00 2001 From: Daniele Venzano Date: Wed, 14 Jan 2009 20:46:24 -0800 Subject: sis900: generate fake MAC address if the hardware doesn't have one The attached patch modifies the sis900 driver when the MAC address read from the hardware is invalid. As suggested, the patch now generates a random address so that the user can go on and use the hardware. In any case a message is also shown to warn on the unexpected condition. This seems to happen with newer HW implementation of the sis900 chipset, since this never came up before. Patch is against vanilla 2.6.28 (but the driver doesn't change so often, so it will probably apply to older/newer versions too). See bugzilla ID 10201 and 11649 and ignore the previous patch. Signed-off-by: Daniele Venzano Signed-off-by: David S. Miller --- drivers/net/sis900.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 6cbefcae9ac..be4465bc0a6 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -509,10 +509,10 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev, else ret = sis900_get_mac_addr(pci_dev, net_dev); - if (ret == 0) { - printk(KERN_WARNING "%s: Cannot read MAC address.\n", dev_name); - ret = -ENODEV; - goto err_unmap_rx; + if (!ret || !is_valid_ether_addr(net_dev->dev_addr)) { + random_ether_addr(net_dev->dev_addr); + printk(KERN_WARNING "%s: Unreadable or invalid MAC address," + "using random generated one\n", dev_name); } /* 630ET : set the mii access mode as software-mode */ -- cgit From 2edbb454428729f450f7a0aabbf95ac62b46b78a Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Wed, 14 Jan 2009 20:47:30 -0800 Subject: netxen: fix endianness in firmware commands o Set restricted (little endian) data types in firmware command requests and responses. o Remove unnecessary conversion to LE when writing registers. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 98 ++++++++++++++++++------------------ drivers/net/netxen/netxen_nic_ctx.c | 50 ++++++++---------- drivers/net/netxen/netxen_nic_hw.c | 42 +++++++++------- drivers/net/netxen/netxen_nic_init.c | 2 +- 4 files changed, 95 insertions(+), 97 deletions(-) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index f8e601c51da..31311cc66d1 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -995,31 +995,31 @@ struct netxen_recv_context { */ typedef struct { - u64 host_phys_addr; /* Ring base addr */ - u32 ring_size; /* Ring entries */ - u16 msi_index; - u16 rsvd; /* Padding */ + __le64 host_phys_addr; /* Ring base addr */ + __le32 ring_size; /* Ring entries */ + __le16 msi_index; + __le16 rsvd; /* Padding */ } nx_hostrq_sds_ring_t; typedef struct { - u64 host_phys_addr; /* Ring base addr */ - u64 buff_size; /* Packet buffer size */ - u32 ring_size; /* Ring entries */ - u32 ring_kind; /* Class of ring */ + __le64 host_phys_addr; /* Ring base addr */ + __le64 buff_size; /* Packet buffer size */ + __le32 ring_size; /* Ring entries */ + __le32 ring_kind; /* Class of ring */ } nx_hostrq_rds_ring_t; typedef struct { - u64 host_rsp_dma_addr; /* Response dma'd here */ - u32 capabilities[4]; /* Flag bit vector */ - u32 host_int_crb_mode; /* Interrupt crb usage */ - u32 host_rds_crb_mode; /* RDS crb usage */ + __le64 host_rsp_dma_addr; /* Response dma'd here */ + __le32 capabilities[4]; /* Flag bit vector */ + __le32 host_int_crb_mode; /* Interrupt crb usage */ + __le32 host_rds_crb_mode; /* RDS crb usage */ /* These ring offsets are relative to data[0] below */ - u32 rds_ring_offset; /* Offset to RDS config */ - u32 sds_ring_offset; /* Offset to SDS config */ - u16 num_rds_rings; /* Count of RDS rings */ - u16 num_sds_rings; /* Count of SDS rings */ - u16 rsvd1; /* Padding */ - u16 rsvd2; /* Padding */ + __le32 rds_ring_offset; /* Offset to RDS config */ + __le32 sds_ring_offset; /* Offset to SDS config */ + __le16 num_rds_rings; /* Count of RDS rings */ + __le16 num_sds_rings; /* Count of SDS rings */ + __le16 rsvd1; /* Padding */ + __le16 rsvd2; /* Padding */ u8 reserved[128]; /* reserve space for future expansion*/ /* MUST BE 64-bit aligned. The following is packed: @@ -1029,24 +1029,24 @@ typedef struct { } nx_hostrq_rx_ctx_t; typedef struct { - u32 host_producer_crb; /* Crb to use */ - u32 rsvd1; /* Padding */ + __le32 host_producer_crb; /* Crb to use */ + __le32 rsvd1; /* Padding */ } nx_cardrsp_rds_ring_t; typedef struct { - u32 host_consumer_crb; /* Crb to use */ - u32 interrupt_crb; /* Crb to use */ + __le32 host_consumer_crb; /* Crb to use */ + __le32 interrupt_crb; /* Crb to use */ } nx_cardrsp_sds_ring_t; typedef struct { /* These ring offsets are relative to data[0] below */ - u32 rds_ring_offset; /* Offset to RDS config */ - u32 sds_ring_offset; /* Offset to SDS config */ - u32 host_ctx_state; /* Starting State */ - u32 num_fn_per_port; /* How many PCI fn share the port */ - u16 num_rds_rings; /* Count of RDS rings */ - u16 num_sds_rings; /* Count of SDS rings */ - u16 context_id; /* Handle for context */ + __le32 rds_ring_offset; /* Offset to RDS config */ + __le32 sds_ring_offset; /* Offset to SDS config */ + __le32 host_ctx_state; /* Starting State */ + __le32 num_fn_per_port; /* How many PCI fn share the port */ + __le16 num_rds_rings; /* Count of RDS rings */ + __le16 num_sds_rings; /* Count of SDS rings */ + __le16 context_id; /* Handle for context */ u8 phys_port; /* Physical id of port */ u8 virt_port; /* Virtual/Logical id of port */ u8 reserved[128]; /* save space for future expansion */ @@ -1072,34 +1072,34 @@ typedef struct { */ typedef struct { - u64 host_phys_addr; /* Ring base addr */ - u32 ring_size; /* Ring entries */ - u32 rsvd; /* Padding */ + __le64 host_phys_addr; /* Ring base addr */ + __le32 ring_size; /* Ring entries */ + __le32 rsvd; /* Padding */ } nx_hostrq_cds_ring_t; typedef struct { - u64 host_rsp_dma_addr; /* Response dma'd here */ - u64 cmd_cons_dma_addr; /* */ - u64 dummy_dma_addr; /* */ - u32 capabilities[4]; /* Flag bit vector */ - u32 host_int_crb_mode; /* Interrupt crb usage */ - u32 rsvd1; /* Padding */ - u16 rsvd2; /* Padding */ - u16 interrupt_ctl; - u16 msi_index; - u16 rsvd3; /* Padding */ + __le64 host_rsp_dma_addr; /* Response dma'd here */ + __le64 cmd_cons_dma_addr; /* */ + __le64 dummy_dma_addr; /* */ + __le32 capabilities[4]; /* Flag bit vector */ + __le32 host_int_crb_mode; /* Interrupt crb usage */ + __le32 rsvd1; /* Padding */ + __le16 rsvd2; /* Padding */ + __le16 interrupt_ctl; + __le16 msi_index; + __le16 rsvd3; /* Padding */ nx_hostrq_cds_ring_t cds_ring; /* Desc of cds ring */ u8 reserved[128]; /* future expansion */ } nx_hostrq_tx_ctx_t; typedef struct { - u32 host_producer_crb; /* Crb to use */ - u32 interrupt_crb; /* Crb to use */ + __le32 host_producer_crb; /* Crb to use */ + __le32 interrupt_crb; /* Crb to use */ } nx_cardrsp_cds_ring_t; typedef struct { - u32 host_ctx_state; /* Starting state */ - u16 context_id; /* Handle for context */ + __le32 host_ctx_state; /* Starting state */ + __le16 context_id; /* Handle for context */ u8 phys_port; /* Physical id of port */ u8 virt_port; /* Virtual/Logical id of port */ nx_cardrsp_cds_ring_t cds_ring; /* Card cds settings */ @@ -1202,9 +1202,9 @@ enum { #define VPORT_MISS_MODE_ACCEPT_MULTI 2 /* accept unmatched multicast */ typedef struct { - u64 qhdr; - u64 req_hdr; - u64 words[6]; + __le64 qhdr; + __le64 req_hdr; + __le64 words[6]; } nx_nic_req_t; typedef struct { diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index 64b51643c62..746bdb47041 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c @@ -76,7 +76,7 @@ netxen_api_unlock(struct netxen_adapter *adapter) static u32 netxen_poll_rsp(struct netxen_adapter *adapter) { - u32 raw_rsp, rsp = NX_CDRP_RSP_OK; + u32 rsp = NX_CDRP_RSP_OK; int timeout = 0; do { @@ -86,10 +86,7 @@ netxen_poll_rsp(struct netxen_adapter *adapter) if (++timeout > NX_OS_CRB_RETRY_COUNT) return NX_CDRP_RSP_TIMEOUT; - netxen_nic_read_w1(adapter, NX_CDRP_CRB_OFFSET, - &raw_rsp); - - rsp = le32_to_cpu(raw_rsp); + netxen_nic_read_w1(adapter, NX_CDRP_CRB_OFFSET, &rsp); } while (!NX_CDRP_IS_RSP(rsp)); return rsp; @@ -109,20 +106,16 @@ netxen_issue_cmd(struct netxen_adapter *adapter, if (netxen_api_lock(adapter)) return NX_RCODE_TIMEOUT; - netxen_nic_write_w1(adapter, NX_SIGN_CRB_OFFSET, - cpu_to_le32(signature)); + netxen_nic_write_w1(adapter, NX_SIGN_CRB_OFFSET, signature); - netxen_nic_write_w1(adapter, NX_ARG1_CRB_OFFSET, - cpu_to_le32(arg1)); + netxen_nic_write_w1(adapter, NX_ARG1_CRB_OFFSET, arg1); - netxen_nic_write_w1(adapter, NX_ARG2_CRB_OFFSET, - cpu_to_le32(arg2)); + netxen_nic_write_w1(adapter, NX_ARG2_CRB_OFFSET, arg2); - netxen_nic_write_w1(adapter, NX_ARG3_CRB_OFFSET, - cpu_to_le32(arg3)); + netxen_nic_write_w1(adapter, NX_ARG3_CRB_OFFSET, arg3); netxen_nic_write_w1(adapter, NX_CDRP_CRB_OFFSET, - cpu_to_le32(NX_CDRP_FORM_CMD(cmd))); + NX_CDRP_FORM_CMD(cmd)); rsp = netxen_poll_rsp(adapter); @@ -133,7 +126,6 @@ netxen_issue_cmd(struct netxen_adapter *adapter, rcode = NX_RCODE_TIMEOUT; } else if (rsp == NX_CDRP_RSP_FAIL) { netxen_nic_read_w1(adapter, NX_ARG1_CRB_OFFSET, &rcode); - rcode = le32_to_cpu(rcode); printk(KERN_ERR "%s: failed card response code:0x%x\n", netxen_nic_driver_name, rcode); @@ -183,7 +175,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) int i, nrds_rings, nsds_rings; size_t rq_size, rsp_size; - u32 cap, reg; + u32 cap, reg, val; int err; @@ -225,11 +217,14 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) prq->num_rds_rings = cpu_to_le16(nrds_rings); prq->num_sds_rings = cpu_to_le16(nsds_rings); - prq->rds_ring_offset = 0; - prq->sds_ring_offset = prq->rds_ring_offset + + prq->rds_ring_offset = cpu_to_le32(0); + + val = le32_to_cpu(prq->rds_ring_offset) + (sizeof(nx_hostrq_rds_ring_t) * nrds_rings); + prq->sds_ring_offset = cpu_to_le32(val); - prq_rds = (nx_hostrq_rds_ring_t *)(prq->data + prq->rds_ring_offset); + prq_rds = (nx_hostrq_rds_ring_t *)(prq->data + + le32_to_cpu(prq->rds_ring_offset)); for (i = 0; i < nrds_rings; i++) { @@ -241,17 +236,14 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) prq_rds[i].buff_size = cpu_to_le64(rds_ring->dma_size); } - prq_sds = (nx_hostrq_sds_ring_t *)(prq->data + prq->sds_ring_offset); + prq_sds = (nx_hostrq_sds_ring_t *)(prq->data + + le32_to_cpu(prq->sds_ring_offset)); prq_sds[0].host_phys_addr = cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr); prq_sds[0].ring_size = cpu_to_le32(adapter->max_rx_desc_count); /* only one msix vector for now */ - prq_sds[0].msi_index = cpu_to_le32(0); - - /* now byteswap offsets */ - prq->rds_ring_offset = cpu_to_le32(prq->rds_ring_offset); - prq->sds_ring_offset = cpu_to_le32(prq->sds_ring_offset); + prq_sds[0].msi_index = cpu_to_le16(0); phys_addr = hostrq_phys_addr; err = netxen_issue_cmd(adapter, @@ -269,9 +261,9 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) prsp_rds = ((nx_cardrsp_rds_ring_t *) - &prsp->data[prsp->rds_ring_offset]); + &prsp->data[le32_to_cpu(prsp->rds_ring_offset)]); - for (i = 0; i < le32_to_cpu(prsp->num_rds_rings); i++) { + for (i = 0; i < le16_to_cpu(prsp->num_rds_rings); i++) { rds_ring = &recv_ctx->rds_rings[i]; reg = le32_to_cpu(prsp_rds[i].host_producer_crb); @@ -279,7 +271,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) } prsp_sds = ((nx_cardrsp_sds_ring_t *) - &prsp->data[prsp->sds_ring_offset]); + &prsp->data[le32_to_cpu(prsp->sds_ring_offset)]); reg = le32_to_cpu(prsp_sds[0].host_consumer_crb); recv_ctx->crb_sts_consumer = NETXEN_NIC_REG(reg - 0x200); @@ -288,7 +280,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) recv_ctx->state = le32_to_cpu(prsp->host_ctx_state); recv_ctx->context_id = le16_to_cpu(prsp->context_id); - recv_ctx->virt_port = le16_to_cpu(prsp->virt_port); + recv_ctx->virt_port = prsp->virt_port; out_free_rsp: pci_free_consistent(adapter->pdev, rsp_size, prsp, cardrsp_phys_addr); diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index aa6e603bfcb..e8a0eed0078 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -539,16 +539,19 @@ static int nx_p3_sre_macaddr_change(struct net_device *dev, { struct netxen_adapter *adapter = netdev_priv(dev); nx_nic_req_t req; - nx_mac_req_t mac_req; + nx_mac_req_t *mac_req; + u64 word; int rv; memset(&req, 0, sizeof(nx_nic_req_t)); - req.qhdr |= (NX_NIC_REQUEST << 23); - req.req_hdr |= NX_MAC_EVENT; - req.req_hdr |= ((u64)adapter->portnum << 16); - mac_req.op = op; - memcpy(&mac_req.mac_addr, addr, 6); - req.words[0] = cpu_to_le64(*(u64 *)&mac_req); + req.qhdr = cpu_to_le64(NX_NIC_REQUEST << 23); + + word = NX_MAC_EVENT | ((u64)adapter->portnum << 16); + req.req_hdr = cpu_to_le64(word); + + mac_req = (nx_mac_req_t *)&req.words[0]; + mac_req->op = op; + memcpy(mac_req->mac_addr, addr, 6); rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); if (rv != 0) { @@ -612,12 +615,16 @@ send_fw_cmd: int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) { nx_nic_req_t req; + u64 word; memset(&req, 0, sizeof(nx_nic_req_t)); - req.qhdr |= (NX_HOST_REQUEST << 23); - req.req_hdr |= NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE; - req.req_hdr |= ((u64)adapter->portnum << 16); + req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23); + + word = NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE | + ((u64)adapter->portnum << 16); + req.req_hdr = cpu_to_le64(word); + req.words[0] = cpu_to_le64(mode); return netxen_send_cmd_descs(adapter, @@ -632,13 +639,15 @@ int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) int netxen_config_intr_coalesce(struct netxen_adapter *adapter) { nx_nic_req_t req; + u64 word; int rv; memset(&req, 0, sizeof(nx_nic_req_t)); - req.qhdr |= (NX_NIC_REQUEST << 23); - req.req_hdr |= NETXEN_CONFIG_INTR_COALESCE; - req.req_hdr |= ((u64)adapter->portnum << 16); + req.qhdr = cpu_to_le64(NX_NIC_REQUEST << 23); + + word = NETXEN_CONFIG_INTR_COALESCE | ((u64)adapter->portnum << 16); + req.req_hdr = cpu_to_le64(word); memcpy(&req.words[0], &adapter->coal, sizeof(adapter->coal)); @@ -772,13 +781,10 @@ int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac) adapter->hw_read_wx(adapter, crbaddr, &mac_lo, 4); adapter->hw_read_wx(adapter, crbaddr+4, &mac_hi, 4); - mac_hi = cpu_to_le32(mac_hi); - mac_lo = cpu_to_le32(mac_lo); - if (pci_func & 1) - *mac = ((mac_lo >> 16) | ((u64)mac_hi << 16)); + *mac = le64_to_cpu((mac_lo >> 16) | ((u64)mac_hi << 16)); else - *mac = ((mac_lo) | ((u64)mac_hi << 32)); + *mac = le64_to_cpu((u64)mac_lo | ((u64)mac_hi << 32)); return 0; } diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index d924468e506..c0e06a65317 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -1277,7 +1277,7 @@ static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, dev_kfree_skb_any(skb); for (i = 0; i < nr_frags; i++) { - index = frag_desc->frag_handles[i]; + index = le16_to_cpu(frag_desc->frag_handles[i]); skb = netxen_process_rxbuf(adapter, rds_ring, index, cksum); if (skb) -- cgit From 391587c3447d99b842a647f8e701895c9eea050b Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Wed, 14 Jan 2009 20:48:11 -0800 Subject: netxen: fix ipv6 offload and tx cleanup o fix the ip/tcp hdr offset in tx descriptors for ipv6. o cleanup xmit function, move the tso checks into separate function, this reduces unnecessary endian conversions back and forth. o optimize macros to initialize tx descriptors. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 43 +++++---------- drivers/net/netxen/netxen_nic_hw.c | 4 -- drivers/net/netxen/netxen_nic_main.c | 101 ++++++++++++++++------------------- 3 files changed, 57 insertions(+), 91 deletions(-) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 31311cc66d1..acb2ac971ca 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -308,27 +308,16 @@ struct netxen_ring_ctx { #define netxen_set_cmd_desc_ctxid(cmd_desc, var) \ ((cmd_desc)->port_ctxid |= ((var) << 4 & 0xF0)) -#define netxen_set_cmd_desc_flags(cmd_desc, val) \ - (cmd_desc)->flags_opcode = ((cmd_desc)->flags_opcode & \ - ~cpu_to_le16(0x7f)) | cpu_to_le16((val) & 0x7f) -#define netxen_set_cmd_desc_opcode(cmd_desc, val) \ - (cmd_desc)->flags_opcode = ((cmd_desc)->flags_opcode & \ - ~cpu_to_le16((u16)0x3f << 7)) | cpu_to_le16(((val) & 0x3f) << 7) - -#define netxen_set_cmd_desc_num_of_buff(cmd_desc, val) \ - (cmd_desc)->num_of_buffers_total_length = \ - ((cmd_desc)->num_of_buffers_total_length & \ - ~cpu_to_le32(0xff)) | cpu_to_le32((val) & 0xff) -#define netxen_set_cmd_desc_totallength(cmd_desc, val) \ - (cmd_desc)->num_of_buffers_total_length = \ - ((cmd_desc)->num_of_buffers_total_length & \ - ~cpu_to_le32((u32)0xffffff << 8)) | \ - cpu_to_le32(((val) & 0xffffff) << 8) - -#define netxen_get_cmd_desc_opcode(cmd_desc) \ - ((le16_to_cpu((cmd_desc)->flags_opcode) >> 7) & 0x003f) -#define netxen_get_cmd_desc_totallength(cmd_desc) \ - ((le32_to_cpu((cmd_desc)->num_of_buffers_total_length) >> 8) & 0xffffff) +#define netxen_set_tx_port(_desc, _port) \ + (_desc)->port_ctxid = ((_port) & 0xf) | (((_port) << 4) & 0xf0) + +#define netxen_set_tx_flags_opcode(_desc, _flags, _opcode) \ + (_desc)->flags_opcode = \ + cpu_to_le16(((_flags) & 0x7f) | (((_opcode) & 0x3f) << 7)) + +#define netxen_set_tx_frags_len(_desc, _frags, _len) \ + (_desc)->num_of_buffers_total_length = \ + cpu_to_le32(((_frags) & 0xff) | (((_len) & 0xffffff) << 8)) struct cmd_desc_type0 { u8 tcp_hdr_offset; /* For LSO only */ @@ -757,7 +746,7 @@ extern char netxen_nic_driver_name[]; */ struct netxen_skb_frag { u64 dma; - u32 length; + ulong length; }; #define _netxen_set_bits(config_word, start, bits, val) {\ @@ -783,13 +772,7 @@ struct netxen_skb_frag { struct netxen_cmd_buffer { struct sk_buff *skb; struct netxen_skb_frag frag_array[MAX_BUFFERS_PER_CMD + 1]; - u32 total_length; - u32 mss; - u16 port; - u8 cmd; - u8 frag_count; - unsigned long time_stamp; - u32 state; + u32 frag_count; }; /* In rx_buffer, we do not need multiple fragments as is a single buffer */ @@ -1486,8 +1469,6 @@ void netxen_release_tx_buffers(struct netxen_adapter *adapter); void netxen_initialize_adapter_ops(struct netxen_adapter *adapter); int netxen_init_firmware(struct netxen_adapter *adapter); -void netxen_tso_check(struct netxen_adapter *adapter, - struct cmd_desc_type0 *desc, struct sk_buff *skb); void netxen_nic_clear_stats(struct netxen_adapter *adapter); void netxen_watchdog_task(struct work_struct *work); void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index e8a0eed0078..98d0bcda5f4 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -508,12 +508,8 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter, cmd_desc = &cmd_desc_arr[i]; pbuf = &adapter->cmd_buf_arr[producer]; - pbuf->mss = 0; - pbuf->total_length = 0; pbuf->skb = NULL; - pbuf->cmd = 0; pbuf->frag_count = 0; - pbuf->port = 0; /* adapter->ahw.cmd_desc_head[producer] = *cmd_desc; */ memcpy(&adapter->ahw.cmd_desc_head[producer], diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index ba01524b553..cb391238180 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -39,6 +39,7 @@ #include "netxen_nic_phan_reg.h" #include +#include #include MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver"); @@ -1137,29 +1138,46 @@ static int netxen_nic_close(struct net_device *netdev) return 0; } -void netxen_tso_check(struct netxen_adapter *adapter, +static bool netxen_tso_check(struct net_device *netdev, struct cmd_desc_type0 *desc, struct sk_buff *skb) { - if (desc->mss) { - desc->total_hdr_length = (sizeof(struct ethhdr) + - ip_hdrlen(skb) + tcp_hdrlen(skb)); + bool tso = false; + u8 opcode = TX_ETHER_PKT; - if ((NX_IS_REVISION_P3(adapter->ahw.revision_id)) && - (skb->protocol == htons(ETH_P_IPV6))) - netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO6); - else - netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO); + if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && + skb_shinfo(skb)->gso_size > 0) { + + desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); + desc->total_hdr_length = + skb_transport_offset(skb) + tcp_hdrlen(skb); + + opcode = (skb->protocol == htons(ETH_P_IPV6)) ? + TX_TCP_LSO6 : TX_TCP_LSO; + tso = true; } else if (skb->ip_summed == CHECKSUM_PARTIAL) { - if (ip_hdr(skb)->protocol == IPPROTO_TCP) - netxen_set_cmd_desc_opcode(desc, TX_TCP_PKT); - else if (ip_hdr(skb)->protocol == IPPROTO_UDP) - netxen_set_cmd_desc_opcode(desc, TX_UDP_PKT); - else - return; + u8 l4proto; + + if (skb->protocol == htons(ETH_P_IP)) { + l4proto = ip_hdr(skb)->protocol; + + if (l4proto == IPPROTO_TCP) + opcode = TX_TCP_PKT; + else if(l4proto == IPPROTO_UDP) + opcode = TX_UDP_PKT; + } else if (skb->protocol == htons(ETH_P_IPV6)) { + l4proto = ipv6_hdr(skb)->nexthdr; + + if (l4proto == IPPROTO_TCP) + opcode = TX_TCPV6_PKT; + else if(l4proto == IPPROTO_UDP) + opcode = TX_UDPV6_PKT; + } } desc->tcp_hdr_offset = skb_transport_offset(skb); desc->ip_hdr_offset = skb_network_offset(skb); + netxen_set_tx_flags_opcode(desc, 0, opcode); + return tso; } static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) @@ -1167,33 +1185,20 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) struct netxen_adapter *adapter = netdev_priv(netdev); struct netxen_hardware_context *hw = &adapter->ahw; unsigned int first_seg_len = skb->len - skb->data_len; + struct netxen_cmd_buffer *pbuf; struct netxen_skb_frag *buffrag; - unsigned int i; + struct cmd_desc_type0 *hwdesc; + int i, k; u32 producer, consumer; - u32 saved_producer = 0; - struct cmd_desc_type0 *hwdesc; - int k; - struct netxen_cmd_buffer *pbuf = NULL; - int frag_count; - int no_of_desc; + int frag_count, no_of_desc; u32 num_txd = adapter->max_tx_desc_count; + bool is_tso = false; frag_count = skb_shinfo(skb)->nr_frags + 1; /* There 4 fragments per descriptor */ no_of_desc = (frag_count + 3) >> 2; - if (netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) { - if (skb_shinfo(skb)->gso_size > 0) { - - no_of_desc++; - if ((ip_hdrlen(skb) + tcp_hdrlen(skb) + - sizeof(struct ethhdr)) > - (sizeof(struct cmd_desc_type0) - 2)) { - no_of_desc++; - } - } - } producer = adapter->cmd_producer; smp_mb(); @@ -1205,34 +1210,22 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) } /* Copy the descriptors into the hardware */ - saved_producer = producer; hwdesc = &hw->cmd_desc_head[producer]; memset(hwdesc, 0, sizeof(struct cmd_desc_type0)); /* Take skb->data itself */ pbuf = &adapter->cmd_buf_arr[producer]; - if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && - skb_shinfo(skb)->gso_size > 0) { - pbuf->mss = skb_shinfo(skb)->gso_size; - hwdesc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); - } else { - pbuf->mss = 0; - hwdesc->mss = 0; - } - pbuf->total_length = skb->len; + + is_tso = netxen_tso_check(netdev, hwdesc, skb); + pbuf->skb = skb; - pbuf->cmd = TX_ETHER_PKT; pbuf->frag_count = frag_count; - pbuf->port = adapter->portnum; buffrag = &pbuf->frag_array[0]; buffrag->dma = pci_map_single(adapter->pdev, skb->data, first_seg_len, PCI_DMA_TODEVICE); buffrag->length = first_seg_len; - netxen_set_cmd_desc_totallength(hwdesc, skb->len); - netxen_set_cmd_desc_num_of_buff(hwdesc, frag_count); - netxen_set_cmd_desc_opcode(hwdesc, TX_ETHER_PKT); + netxen_set_tx_frags_len(hwdesc, frag_count, skb->len); + netxen_set_tx_port(hwdesc, adapter->portnum); - netxen_set_cmd_desc_port(hwdesc, adapter->portnum); - netxen_set_cmd_desc_ctxid(hwdesc, adapter->portnum); hwdesc->buffer1_length = cpu_to_le16(first_seg_len); hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma); @@ -1285,16 +1278,12 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) } producer = get_next_index(producer, num_txd); - /* might change opcode to TX_TCP_LSO */ - netxen_tso_check(adapter, &hw->cmd_desc_head[saved_producer], skb); - /* For LSO, we need to copy the MAC/IP/TCP headers into * the descriptor ring */ - if (netxen_get_cmd_desc_opcode(&hw->cmd_desc_head[saved_producer]) - == TX_TCP_LSO) { + if (is_tso) { int hdr_len, first_hdr_len, more_hdr; - hdr_len = hw->cmd_desc_head[saved_producer].total_hdr_length; + hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); if (hdr_len > (sizeof(struct cmd_desc_type0) - 2)) { first_hdr_len = sizeof(struct cmd_desc_type0) - 2; more_hdr = 1; -- cgit From c7860a2aec571ea95d3ad19b8d9775b27828baac Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Wed, 14 Jan 2009 20:48:32 -0800 Subject: netxen: fix link speed reporting for some boards o Read negotiated link speed when link state changes. o Fix link speed reporting for hybrid nic boards, which have both 1Gbps and 10Gbps ports. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 3 ++- drivers/net/netxen/netxen_nic_ethtool.c | 31 +++++++++++++++++++++++-------- drivers/net/netxen/netxen_nic_hw.c | 28 ++++++++++++++++++++-------- drivers/net/netxen/netxen_nic_main.c | 14 +++++++++++++- 4 files changed, 58 insertions(+), 18 deletions(-) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index acb2ac971ca..a674a23f72b 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -499,7 +499,8 @@ typedef enum { NETXEN_BRDTYPE_P3_10G_SFP_CT = 0x002a, NETXEN_BRDTYPE_P3_10G_SFP_QT = 0x002b, NETXEN_BRDTYPE_P3_10G_CX4 = 0x0031, - NETXEN_BRDTYPE_P3_10G_XFP = 0x0032 + NETXEN_BRDTYPE_P3_10G_XFP = 0x0032, + NETXEN_BRDTYPE_P3_10G_TP = 0x0080 } netxen_brdtype_t; diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index e45ce295172..c0bd40fcf70 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -136,11 +136,9 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ecmd->port = PORT_TP; - if (netif_running(dev)) { - ecmd->speed = adapter->link_speed; - ecmd->duplex = adapter->link_duplex; - ecmd->autoneg = adapter->link_autoneg; - } + ecmd->speed = adapter->link_speed; + ecmd->duplex = adapter->link_duplex; + ecmd->autoneg = adapter->link_autoneg; } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { u32 val; @@ -171,7 +169,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) } else return -EIO; - ecmd->phy_address = adapter->portnum; + ecmd->phy_address = adapter->physical_port; ecmd->transceiver = XCVR_EXTERNAL; switch ((netxen_brdtype_t) boardinfo->board_type) { @@ -180,13 +178,13 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) case NETXEN_BRDTYPE_P3_REF_QG: case NETXEN_BRDTYPE_P3_4_GB: case NETXEN_BRDTYPE_P3_4_GB_MM: - case NETXEN_BRDTYPE_P3_10000_BASE_T: ecmd->supported |= SUPPORTED_Autoneg; ecmd->advertising |= ADVERTISED_Autoneg; case NETXEN_BRDTYPE_P2_SB31_10G_CX4: case NETXEN_BRDTYPE_P3_10G_CX4: case NETXEN_BRDTYPE_P3_10G_CX4_LP: + case NETXEN_BRDTYPE_P3_10000_BASE_T: ecmd->supported |= SUPPORTED_TP; ecmd->advertising |= ADVERTISED_TP; ecmd->port = PORT_TP; @@ -204,16 +202,33 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ecmd->port = PORT_FIBRE; ecmd->autoneg = AUTONEG_DISABLE; break; - case NETXEN_BRDTYPE_P2_SB31_10G: case NETXEN_BRDTYPE_P3_10G_SFP_PLUS: case NETXEN_BRDTYPE_P3_10G_SFP_CT: case NETXEN_BRDTYPE_P3_10G_SFP_QT: + ecmd->advertising |= ADVERTISED_TP; + ecmd->supported |= SUPPORTED_TP; + case NETXEN_BRDTYPE_P2_SB31_10G: case NETXEN_BRDTYPE_P3_10G_XFP: ecmd->supported |= SUPPORTED_FIBRE; ecmd->advertising |= ADVERTISED_FIBRE; ecmd->port = PORT_FIBRE; ecmd->autoneg = AUTONEG_DISABLE; break; + case NETXEN_BRDTYPE_P3_10G_TP: + if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { + ecmd->autoneg = AUTONEG_DISABLE; + ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP); + ecmd->advertising |= + (ADVERTISED_FIBRE | ADVERTISED_TP); + ecmd->port = PORT_FIBRE; + } else { + ecmd->autoneg = AUTONEG_ENABLE; + ecmd->supported |= (SUPPORTED_TP |SUPPORTED_Autoneg); + ecmd->advertising |= + (ADVERTISED_TP | ADVERTISED_Autoneg); + ecmd->port = PORT_TP; + } + break; default: printk(KERN_ERR "netxen-nic: Unsupported board model %d\n", (netxen_brdtype_t) boardinfo->board_type); diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 98d0bcda5f4..4276f7f8223 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -2036,7 +2036,13 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter) rv = -1; } - DPRINTK(INFO, "Discovered board type:0x%x ", boardinfo->board_type); + if (boardinfo->board_type == NETXEN_BRDTYPE_P3_4_GB_MM) { + u32 gpio = netxen_nic_reg_read(adapter, + NETXEN_ROMUSB_GLB_PAD_GPIO_I); + if ((gpio & 0x8000) == 0) + boardinfo->board_type = NETXEN_BRDTYPE_P3_10G_TP; + } + switch ((netxen_brdtype_t) boardinfo->board_type) { case NETXEN_BRDTYPE_P2_SB35_4G: adapter->ahw.board_type = NETXEN_NIC_GBE; @@ -2055,7 +2061,6 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter) case NETXEN_BRDTYPE_P3_10G_SFP_QT: case NETXEN_BRDTYPE_P3_10G_XFP: case NETXEN_BRDTYPE_P3_10000_BASE_T: - adapter->ahw.board_type = NETXEN_NIC_XGBE; break; case NETXEN_BRDTYPE_P1_BD: @@ -2065,9 +2070,12 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter) case NETXEN_BRDTYPE_P3_REF_QG: case NETXEN_BRDTYPE_P3_4_GB: case NETXEN_BRDTYPE_P3_4_GB_MM: - adapter->ahw.board_type = NETXEN_NIC_GBE; break; + case NETXEN_BRDTYPE_P3_10G_TP: + adapter->ahw.board_type = (adapter->portnum < 2) ? + NETXEN_NIC_XGBE : NETXEN_NIC_GBE; + break; default: printk("%s: Unknown(%x)\n", netxen_nic_driver_name, boardinfo->board_type); @@ -2112,12 +2120,16 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter) { __u32 status; __u32 autoneg; - __u32 mode; __u32 port_mode; - netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, &mode); - if (netxen_get_niu_enable_ge(mode)) { /* Gb 10/100/1000 Mbps mode */ + if (!netif_carrier_ok(adapter->netdev)) { + adapter->link_speed = 0; + adapter->link_duplex = -1; + adapter->link_autoneg = AUTONEG_ENABLE; + return; + } + if (adapter->ahw.board_type == NETXEN_NIC_GBE) { adapter->hw_read_wx(adapter, NETXEN_PORT_MODE_ADDR, &port_mode, 4); if (port_mode == NETXEN_PORT_MODE_802_3_AP) { @@ -2143,7 +2155,7 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter) adapter->link_speed = SPEED_1000; break; default: - adapter->link_speed = -1; + adapter->link_speed = 0; break; } switch (netxen_get_phy_duplex(status)) { @@ -2166,7 +2178,7 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter) goto link_down; } else { link_down: - adapter->link_speed = -1; + adapter->link_speed = 0; adapter->link_duplex = -1; } } diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index cb391238180..2c6ce6ffde0 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -243,7 +243,7 @@ static void netxen_check_options(struct netxen_adapter *adapter) case NETXEN_BRDTYPE_P3_4_GB: case NETXEN_BRDTYPE_P3_4_GB_MM: adapter->msix_supported = !!use_msi_x; - adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G; + adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; break; case NETXEN_BRDTYPE_P2_SB35_4G: @@ -252,6 +252,14 @@ static void netxen_check_options(struct netxen_adapter *adapter) adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; break; + case NETXEN_BRDTYPE_P3_10G_TP: + adapter->msix_supported = !!use_msi_x; + if (adapter->ahw.board_type == NETXEN_NIC_XGBE) + adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G; + else + adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; + break; + default: adapter->msix_supported = 0; adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; @@ -1396,6 +1404,8 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter) netif_carrier_off(netdev); netif_stop_queue(netdev); } + + netxen_nic_set_link_parameters(adapter); } else if (!adapter->ahw.linkup && linkup) { printk(KERN_INFO "%s: %s NIC Link is up\n", netxen_nic_driver_name, netdev->name); @@ -1404,6 +1414,8 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter) netif_carrier_on(netdev); netif_wake_queue(netdev); } + + netxen_nic_set_link_parameters(adapter); } } -- cgit From 27c915a4d843b90eb4065298969578d15e5e6ab0 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Wed, 14 Jan 2009 20:49:00 -0800 Subject: netxen: firmware init fix o Fix order or rom register writes. o Reduce udelays when writing rom registers. This cuts the firmware init time by 40%. o Do not reset core/memory clocks when reinitializing driver. Firmware willl handle this when initialized. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic_hw.c | 6 ++--- drivers/net/netxen/netxen_nic_init.c | 35 ++++++++++++++++----------- drivers/net/netxen/netxen_nic_main.c | 47 +++++++++++++++++++++--------------- 3 files changed, 51 insertions(+), 37 deletions(-) diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 4276f7f8223..511db2ac57c 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -939,7 +939,7 @@ int netxen_load_firmware(struct netxen_adapter *adapter) { int i; u32 data, size = 0; - u32 flashaddr = NETXEN_BOOTLD_START, memaddr = NETXEN_BOOTLD_START; + u32 flashaddr = NETXEN_BOOTLD_START; size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START)/4; @@ -951,10 +951,8 @@ int netxen_load_firmware(struct netxen_adapter *adapter) if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0) return -EIO; - adapter->pci_mem_write(adapter, memaddr, &data, 4); + adapter->pci_mem_write(adapter, flashaddr, &data, 4); flashaddr += 4; - memaddr += 4; - cond_resched(); } msleep(1); diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index c0e06a65317..a3203644b48 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -439,6 +439,8 @@ static int netxen_wait_rom_done(struct netxen_adapter *adapter) long timeout = 0; long done = 0; + cond_resched(); + while (done == 0) { done = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_GLB_STATUS); done &= 2; @@ -533,12 +535,9 @@ static int do_rom_fast_write(struct netxen_adapter *adapter, int addr, static int do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) { - cond_resched(); - netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr); - netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3); - udelay(100); /* prevent bursting on CRB */ netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0); + netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3); netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb); if (netxen_wait_rom_done(adapter)) { printk("Error waiting for rom done\n"); @@ -546,7 +545,7 @@ static int do_rom_fast_read(struct netxen_adapter *adapter, } /* reset abyte_cnt and dummy_byte_cnt */ netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0); - udelay(100); /* prevent bursting on CRB */ + udelay(10); netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0); *valp = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_ROM_RDATA); @@ -884,14 +883,16 @@ int netxen_flash_unlock(struct netxen_adapter *adapter) int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) { int addr, val; - int i, init_delay = 0; + int i, n, init_delay = 0; struct crb_addr_pair *buf; - unsigned offset, n; + unsigned offset; u32 off; /* resetall */ + rom_lock(adapter); netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff); + netxen_rom_unlock(adapter); if (verbose) { if (netxen_rom_fast_read(adapter, NETXEN_BOARDTYPE, &val) == 0) @@ -910,7 +911,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { if (netxen_rom_fast_read(adapter, 0, &n) != 0 || - (n != 0xcafecafeUL) || + (n != 0xcafecafe) || netxen_rom_fast_read(adapter, 4, &n) != 0) { printk(KERN_ERR "%s: ERROR Reading crb_init area: " "n: %08x\n", netxen_nic_driver_name, n); @@ -975,6 +976,14 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) /* do not reset PCI */ if (off == (ROMUSB_GLB + 0xbc)) continue; + if (off == (ROMUSB_GLB + 0xa8)) + continue; + if (off == (ROMUSB_GLB + 0xc8)) /* core clock */ + continue; + if (off == (ROMUSB_GLB + 0x24)) /* MN clock */ + continue; + if (off == (ROMUSB_GLB + 0x1c)) /* MS clock */ + continue; if (off == (NETXEN_CRB_PEG_NET_1 + 0x18)) buf[i].data = 0x1020; /* skip the function enable register */ @@ -992,23 +1001,21 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) continue; } + init_delay = 1; /* After writing this register, HW needs time for CRB */ /* to quiet down (else crb_window returns 0xffffffff) */ if (off == NETXEN_ROMUSB_GLB_SW_RESET) { - init_delay = 1; + init_delay = 1000; if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { /* hold xdma in reset also */ buf[i].data = NETXEN_NIC_XDMA_RESET; + buf[i].data = 0x8000ff; } } adapter->hw_write_wx(adapter, off, &buf[i].data, 4); - if (init_delay == 1) { - msleep(1000); - init_delay = 0; - } - msleep(1); + msleep(init_delay); } kfree(buf); diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 2c6ce6ffde0..cbe2b3e814d 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -280,10 +280,15 @@ static void netxen_check_options(struct netxen_adapter *adapter) static int netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot) { - int ret = 0; + u32 val, timeout; if (first_boot == 0x55555555) { /* This is the first boot after power up */ + adapter->pci_write_normalize(adapter, + NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); + + if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) + return 0; /* PCI bus master workaround */ adapter->hw_read_wx(adapter, @@ -303,18 +308,26 @@ netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot) /* clear the register for future unloads/loads */ adapter->pci_write_normalize(adapter, NETXEN_CAM_RAM(0x1fc), 0); - ret = -1; + return -EIO; } - if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { - /* Start P2 boot loader */ - adapter->pci_write_normalize(adapter, - NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); - adapter->pci_write_normalize(adapter, - NETXEN_ROMUSB_GLB_PEGTUNE_DONE, 1); - } + /* Start P2 boot loader */ + val = adapter->pci_read_normalize(adapter, + NETXEN_ROMUSB_GLB_PEGTUNE_DONE); + adapter->pci_write_normalize(adapter, + NETXEN_ROMUSB_GLB_PEGTUNE_DONE, val | 0x1); + timeout = 0; + do { + msleep(1); + val = adapter->pci_read_normalize(adapter, + NETXEN_CAM_RAM(0x1fc)); + + if (++timeout > 5000) + return -EIO; + + } while (val == NETXEN_BDINFO_MAGIC); } - return ret; + return 0; } static void netxen_set_port_mode(struct netxen_adapter *adapter) @@ -793,8 +806,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) CRB_CMDPEG_STATE, 0); netxen_pinit_from_rom(adapter, 0); msleep(1); - netxen_load_firmware(adapter); } + netxen_load_firmware(adapter); if (NX_IS_REVISION_P3(revision_id)) netxen_pcie_strap_init(adapter); @@ -810,13 +823,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } - if ((first_boot == 0x55555555) && - (NX_IS_REVISION_P2(revision_id))) { - /* Unlock the HW, prompting the boot sequence */ - adapter->pci_write_normalize(adapter, - NETXEN_ROMUSB_GLB_PEGTUNE_DONE, 1); - } - err = netxen_initialize_adapter_offload(adapter); if (err) goto err_out_iounmap; @@ -830,7 +836,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->pci_write_normalize(adapter, CRB_DRIVER_VERSION, i); /* Handshake with the card before we register the devices. */ - netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); + err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); + if (err) + goto err_out_free_offload; } /* first_driver */ @@ -934,6 +942,7 @@ err_out_disable_msi: if (adapter->flags & NETXEN_NIC_MSI_ENABLED) pci_disable_msi(pdev); +err_out_free_offload: if (first_driver) netxen_free_adapter_offload(adapter); -- cgit From 06e9d9f9783860fe4c602ef491f47211804ccc96 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Wed, 14 Jan 2009 20:49:22 -0800 Subject: netxen: cleanup mac list on driver unload This fixes a tiny memory leak when driver is unloaded. The mac address list maintained in netxen_adapter needs to deleted when driver is going down. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 1 + drivers/net/netxen/netxen_nic_hw.c | 13 +++++++++++++ drivers/net/netxen/netxen_nic_main.c | 3 +++ 3 files changed, 17 insertions(+) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index a674a23f72b..6598a34b87d 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -1478,6 +1478,7 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter); u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max); void netxen_p2_nic_set_multi(struct net_device *netdev); void netxen_p3_nic_set_multi(struct net_device *netdev); +void netxen_p3_free_mac_list(struct netxen_adapter *adapter); int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32); int netxen_config_intr_coalesce(struct netxen_adapter *adapter); diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 511db2ac57c..e2d2a2fdbe1 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -627,6 +627,19 @@ int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) (struct cmd_desc_type0 *)&req, 1); } +void netxen_p3_free_mac_list(struct netxen_adapter *adapter) +{ + nx_mac_list_t *cur, *next; + + cur = adapter->mac_list; + + while (cur) { + next = cur->next; + kfree(cur); + cur = next; + } +} + #define NETXEN_CONFIG_INTR_COALESCE 3 /* diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index cbe2b3e814d..9268fd2fbac 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -986,6 +986,9 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) netxen_free_hw_resources(adapter); netxen_release_rx_buffers(adapter); netxen_free_sw_resources(adapter); + + if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) + netxen_p3_free_mac_list(adapter); } if (adapter->portnum == 0) -- cgit From 03e678ee968ae54b79c1580c2935895bd863ad95 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Wed, 14 Jan 2009 20:49:43 -0800 Subject: netxen: hold tx lock while sending firmware commands Some firmware commands like mac address addition/deletion are sent on the transmit ring. So need to hold the tx lock before touching tx producer/consumer indices. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic_hw.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index e2d2a2fdbe1..821cff68b3f 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -503,6 +503,8 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter, i = 0; + netif_tx_lock_bh(adapter->netdev); + producer = adapter->cmd_producer; do { cmd_desc = &cmd_desc_arr[i]; @@ -527,6 +529,8 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter, netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer); + netif_tx_unlock_bh(adapter->netdev); + return 0; } -- cgit From 6f70340698333f14b1d9c9e913c5de8f66b72c55 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Wed, 14 Jan 2009 20:50:00 -0800 Subject: netxen: handle dma mapping failures o Bail out if pci_map_single() fails while replenishing rx ring. o Drop packet if pci_map_{single,page}() fail in tx. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 1 - drivers/net/netxen/netxen_nic_init.c | 68 +++++++++++++++++------------------- drivers/net/netxen/netxen_nic_main.c | 38 ++++++++++++++++++-- 3 files changed, 67 insertions(+), 40 deletions(-) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 6598a34b87d..c11c568fd7d 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -860,7 +860,6 @@ struct nx_host_rds_ring { u32 skb_size; struct netxen_rx_buffer *rx_buf_arr; /* rx buffers for receive */ struct list_head free_list; - int begin_alloc; }; /* diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index a3203644b48..ca7c8d8050c 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -308,7 +308,6 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) } memset(rds_ring->rx_buf_arr, 0, RCV_BUFFSIZE); INIT_LIST_HEAD(&rds_ring->free_list); - rds_ring->begin_alloc = 0; /* * Now go through all of them, set reference handles * and put them in the queues. @@ -1435,7 +1434,6 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) struct rcv_desc *pdesc; struct netxen_rx_buffer *buffer; int count = 0; - int index = 0; netxen_ctx_msg msg = 0; dma_addr_t dma; struct list_head *head; @@ -1443,7 +1441,6 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) rds_ring = &recv_ctx->rds_rings[ringid]; producer = rds_ring->producer; - index = rds_ring->begin_alloc; head = &rds_ring->free_list; /* We can start writing rx descriptors into the phantom memory. */ @@ -1451,39 +1448,37 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) skb = dev_alloc_skb(rds_ring->skb_size); if (unlikely(!skb)) { - rds_ring->begin_alloc = index; break; } + if (!adapter->ahw.cut_through) + skb_reserve(skb, 2); + + dma = pci_map_single(pdev, skb->data, + rds_ring->dma_size, PCI_DMA_FROMDEVICE); + if (pci_dma_mapping_error(pdev, dma)) { + dev_kfree_skb_any(skb); + break; + } + + count++; buffer = list_entry(head->next, struct netxen_rx_buffer, list); list_del(&buffer->list); - count++; /* now there should be no failure */ - pdesc = &rds_ring->desc_head[producer]; - - if (!adapter->ahw.cut_through) - skb_reserve(skb, 2); - /* This will be setup when we receive the - * buffer after it has been filled FSL TBD TBD - * skb->dev = netdev; - */ - dma = pci_map_single(pdev, skb->data, rds_ring->dma_size, - PCI_DMA_FROMDEVICE); - pdesc->addr_buffer = cpu_to_le64(dma); buffer->skb = skb; buffer->state = NETXEN_BUFFER_BUSY; buffer->dma = dma; + /* make a rcv descriptor */ + pdesc = &rds_ring->desc_head[producer]; + pdesc->addr_buffer = cpu_to_le64(dma); pdesc->reference_handle = cpu_to_le16(buffer->ref_handle); pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size); - DPRINTK(INFO, "done writing descripter\n"); - producer = - get_next_index(producer, rds_ring->max_rx_desc_count); - index = get_next_index(index, rds_ring->max_rx_desc_count); + + producer = get_next_index(producer, rds_ring->max_rx_desc_count); } /* if we did allocate buffers, then write the count to Phantom */ if (count) { - rds_ring->begin_alloc = index; rds_ring->producer = producer; /* Window = 1 */ adapter->pci_write_normalize(adapter, @@ -1522,49 +1517,50 @@ static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, struct rcv_desc *pdesc; struct netxen_rx_buffer *buffer; int count = 0; - int index = 0; struct list_head *head; + dma_addr_t dma; rds_ring = &recv_ctx->rds_rings[ringid]; producer = rds_ring->producer; - index = rds_ring->begin_alloc; head = &rds_ring->free_list; /* We can start writing rx descriptors into the phantom memory. */ while (!list_empty(head)) { skb = dev_alloc_skb(rds_ring->skb_size); if (unlikely(!skb)) { - rds_ring->begin_alloc = index; break; } + if (!adapter->ahw.cut_through) + skb_reserve(skb, 2); + + dma = pci_map_single(pdev, skb->data, + rds_ring->dma_size, PCI_DMA_FROMDEVICE); + if (pci_dma_mapping_error(pdev, dma)) { + dev_kfree_skb_any(skb); + break; + } + + count++; buffer = list_entry(head->next, struct netxen_rx_buffer, list); list_del(&buffer->list); - count++; /* now there should be no failure */ - pdesc = &rds_ring->desc_head[producer]; - if (!adapter->ahw.cut_through) - skb_reserve(skb, 2); buffer->skb = skb; buffer->state = NETXEN_BUFFER_BUSY; - buffer->dma = pci_map_single(pdev, skb->data, - rds_ring->dma_size, - PCI_DMA_FROMDEVICE); + buffer->dma = dma; /* make a rcv descriptor */ + pdesc = &rds_ring->desc_head[producer]; pdesc->reference_handle = cpu_to_le16(buffer->ref_handle); pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size); pdesc->addr_buffer = cpu_to_le64(buffer->dma); - producer = - get_next_index(producer, rds_ring->max_rx_desc_count); - index = get_next_index(index, rds_ring->max_rx_desc_count); - buffer = &rds_ring->rx_buf_arr[index]; + + producer = get_next_index(producer, rds_ring->max_rx_desc_count); } /* if we did allocate buffers, then write the count to Phantom */ if (count) { - rds_ring->begin_alloc = index; rds_ring->producer = producer; /* Window = 1 */ adapter->pci_write_normalize(adapter, diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 9268fd2fbac..86867405a36 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -1200,6 +1200,24 @@ static bool netxen_tso_check(struct net_device *netdev, return tso; } +static void +netxen_clean_tx_dma_mapping(struct pci_dev *pdev, + struct netxen_cmd_buffer *pbuf, int last) +{ + int k; + struct netxen_skb_frag *buffrag; + + buffrag = &pbuf->frag_array[0]; + pci_unmap_single(pdev, buffrag->dma, + buffrag->length, PCI_DMA_TODEVICE); + + for (k = 1; k < last; k++) { + buffrag = &pbuf->frag_array[k]; + pci_unmap_page(pdev, buffrag->dma, + buffrag->length, PCI_DMA_TODEVICE); + } +} + static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) { struct netxen_adapter *adapter = netdev_priv(netdev); @@ -1208,6 +1226,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) struct netxen_cmd_buffer *pbuf; struct netxen_skb_frag *buffrag; struct cmd_desc_type0 *hwdesc; + struct pci_dev *pdev = adapter->pdev; + dma_addr_t temp_dma; int i, k; u32 producer, consumer; @@ -1240,8 +1260,12 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) pbuf->skb = skb; pbuf->frag_count = frag_count; buffrag = &pbuf->frag_array[0]; - buffrag->dma = pci_map_single(adapter->pdev, skb->data, first_seg_len, + temp_dma = pci_map_single(pdev, skb->data, first_seg_len, PCI_DMA_TODEVICE); + if (pci_dma_mapping_error(pdev, temp_dma)) + goto drop_packet; + + buffrag->dma = temp_dma; buffrag->length = first_seg_len; netxen_set_tx_frags_len(hwdesc, frag_count, skb->len); netxen_set_tx_port(hwdesc, adapter->portnum); @@ -1253,7 +1277,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) struct skb_frag_struct *frag; int len, temp_len; unsigned long offset; - dma_addr_t temp_dma; /* move to next desc. if there is a need */ if ((i & 0x3) == 0) { @@ -1269,8 +1292,12 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) offset = frag->page_offset; temp_len = len; - temp_dma = pci_map_page(adapter->pdev, frag->page, offset, + temp_dma = pci_map_page(pdev, frag->page, offset, len, PCI_DMA_TODEVICE); + if (pci_dma_mapping_error(pdev, temp_dma)) { + netxen_clean_tx_dma_mapping(pdev, pbuf, i); + goto drop_packet; + } buffrag++; buffrag->dma = temp_dma; @@ -1345,6 +1372,11 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) netdev->trans_start = jiffies; return NETDEV_TX_OK; + +drop_packet: + adapter->stats.txdropped++; + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; } static int netxen_nic_check_temp(struct netxen_adapter *adapter) -- cgit From 2950e952920811be465ec95c6b56f03dc66a05c0 Mon Sep 17 00:00:00 2001 From: Jos-Vicente Gilabert Date: Wed, 14 Jan 2009 20:55:00 -0800 Subject: drivers/net/irda/irda-usb.c: fix buffer overflow Taken from http://bugzilla.kernel.org/show_bug.cgi?id=12397 We're doing an sprintf of an 11-char string into an 11-char buffer. Whoops. It breaks firmware uploading. Reported-by: Jos-Vicente Gilabert Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/irda/irda-usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 29118f58a14..3a22dc41b65 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c @@ -1073,7 +1073,7 @@ static int stir421x_patch_device(struct irda_usb_cb *self) { unsigned int i; int ret; - char stir421x_fw_name[11]; + char stir421x_fw_name[12]; const struct firmware *fw; const unsigned char *fw_version_ptr; /* pointer to version string */ unsigned long fw_version = 0; -- cgit From 937f1ba56b4be37d9e2ad77412f95048662058d2 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 14 Jan 2009 21:05:05 -0800 Subject: net: Add init_dummy_netdev() and fix EMAC driver using it This adds an init_dummy_netdev() function that gets a network device structure (allocation and lifetime entirely under caller's control) and initialize the minimum amount of fields so it can be used to schedule NAPI polls without registering a full blown interface. This is to be used by drivers that need to tie several hardware interfaces to a single NAPI poll scheduler due to HW limitations. It also updates the ibm_newemac driver to use that, this fixing the oops on 2.6.29 due to passing NULL as "dev" to netif_napi_add() Symbol is exported GPL only a I don't think we want binary drivers doing that sort of acrobatics (if we want them at all). Signed-off-by: Benjamin Herrenschmidt Tested-by: Geert Uytterhoeven Signed-off-by: David S. Miller --- drivers/net/ibm_newemac/mal.c | 4 +++- drivers/net/ibm_newemac/mal.h | 2 ++ include/linux/netdevice.h | 3 +++ net/core/dev.c | 39 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/drivers/net/ibm_newemac/mal.c b/drivers/net/ibm_newemac/mal.c index ecf9798987f..2a2fc17b287 100644 --- a/drivers/net/ibm_newemac/mal.c +++ b/drivers/net/ibm_newemac/mal.c @@ -613,7 +613,9 @@ static int __devinit mal_probe(struct of_device *ofdev, INIT_LIST_HEAD(&mal->list); spin_lock_init(&mal->lock); - netif_napi_add(NULL, &mal->napi, mal_poll, + init_dummy_netdev(&mal->dummy_dev); + + netif_napi_add(&mal->dummy_dev, &mal->napi, mal_poll, CONFIG_IBM_NEW_EMAC_POLL_WEIGHT); /* Load power-on reset defaults */ diff --git a/drivers/net/ibm_newemac/mal.h b/drivers/net/ibm_newemac/mal.h index 2f0a8736084..9ededfbf072 100644 --- a/drivers/net/ibm_newemac/mal.h +++ b/drivers/net/ibm_newemac/mal.h @@ -214,6 +214,8 @@ struct mal_instance { int index; spinlock_t lock; + struct net_device dummy_dev; + unsigned int features; }; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 4647604c7ca..ec54785d34f 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -795,6 +795,7 @@ struct net_device NETREG_UNREGISTERING, /* called unregister_netdevice */ NETREG_UNREGISTERED, /* completed unregister todo */ NETREG_RELEASED, /* called free_netdev */ + NETREG_DUMMY, /* dummy device for NAPI poll */ } reg_state; /* Called from unregister, can be used to call free_netdev */ @@ -1077,6 +1078,8 @@ extern void free_netdev(struct net_device *dev); extern void synchronize_net(void); extern int register_netdevice_notifier(struct notifier_block *nb); extern int unregister_netdevice_notifier(struct notifier_block *nb); +extern int init_dummy_netdev(struct net_device *dev); + extern int call_netdevice_notifiers(unsigned long val, struct net_device *dev); extern struct net_device *dev_get_by_index(struct net *net, int ifindex); extern struct net_device *__dev_get_by_index(struct net *net, int ifindex); diff --git a/net/core/dev.c b/net/core/dev.c index 60377b6c0a8..8d675975d85 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -4430,6 +4430,45 @@ err_uninit: goto out; } +/** + * init_dummy_netdev - init a dummy network device for NAPI + * @dev: device to init + * + * This takes a network device structure and initialize the minimum + * amount of fields so it can be used to schedule NAPI polls without + * registering a full blown interface. This is to be used by drivers + * that need to tie several hardware interfaces to a single NAPI + * poll scheduler due to HW limitations. + */ +int init_dummy_netdev(struct net_device *dev) +{ + /* Clear everything. Note we don't initialize spinlocks + * are they aren't supposed to be taken by any of the + * NAPI code and this dummy netdev is supposed to be + * only ever used for NAPI polls + */ + memset(dev, 0, sizeof(struct net_device)); + + /* make sure we BUG if trying to hit standard + * register/unregister code path + */ + dev->reg_state = NETREG_DUMMY; + + /* initialize the ref count */ + atomic_set(&dev->refcnt, 1); + + /* NAPI wants this */ + INIT_LIST_HEAD(&dev->napi_list); + + /* a dummy interface is started by default */ + set_bit(__LINK_STATE_PRESENT, &dev->state); + set_bit(__LINK_STATE_START, &dev->state); + + return 0; +} +EXPORT_SYMBOL_GPL(init_dummy_netdev); + + /** * register_netdev - register a network device * @dev: device to register -- cgit From d57bc36e7aba9e3a00d154f5eff80ff596146fc4 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 14 Jan 2009 21:05:55 -0800 Subject: ax88796: start_xmit fix using net_device_ops This patch hooks up the start_xmit/tx_timeout/get_stats callbacks in the ax88796 driver since they no longer are installed by the lib8390 code. Without this patch the function dev_hard_start_xmit() crashes due to a start_xmit callback with the value NULL. While at it, update the ax88796 driver to make use of use of struct net_device_ops. Signed-off-by: Magnus Damm Signed-off-by: David S. Miller --- drivers/net/ax88796.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c index 337488ec707..a4eb6c40678 100644 --- a/drivers/net/ax88796.c +++ b/drivers/net/ax88796.c @@ -37,7 +37,10 @@ static int phy_debug = 0; #define __ei_open ax_ei_open #define __ei_close ax_ei_close #define __ei_poll ax_ei_poll +#define __ei_start_xmit ax_ei_start_xmit #define __ei_tx_timeout ax_ei_tx_timeout +#define __ei_get_stats ax_ei_get_stats +#define __ei_set_multicast_list ax_ei_set_multicast_list #define __ei_interrupt ax_ei_interrupt #define ____alloc_ei_netdev ax__alloc_ei_netdev #define __NS8390_init ax_NS8390_init @@ -623,6 +626,23 @@ static void ax_eeprom_register_write(struct eeprom_93cx6 *eeprom) } #endif +static const struct net_device_ops ax_netdev_ops = { + .ndo_open = ax_open, + .ndo_stop = ax_close, + .ndo_do_ioctl = ax_ioctl, + + .ndo_start_xmit = ax_ei_start_xmit, + .ndo_tx_timeout = ax_ei_tx_timeout, + .ndo_get_stats = ax_ei_get_stats, + .ndo_set_multicast_list = ax_ei_set_multicast_list, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, + .ndo_change_mtu = eth_change_mtu, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = ax_ei_poll, +#endif +}; + /* setup code */ static void ax_initial_setup(struct net_device *dev, struct ei_device *ei_local) @@ -738,9 +758,7 @@ static int ax_init_dev(struct net_device *dev, int first_init) ei_status.get_8390_hdr = &ax_get_8390_hdr; ei_status.priv = 0; - dev->open = ax_open; - dev->stop = ax_close; - dev->do_ioctl = ax_ioctl; + dev->netdev_ops = &ax_netdev_ops; dev->ethtool_ops = &ax_ethtool_ops; ax->msg_enable = NETIF_MSG_LINK; @@ -753,9 +771,6 @@ static int ax_init_dev(struct net_device *dev, int first_init) ax->mii.mdio_write = ax_phy_write; ax->mii.dev = dev; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = ax_ei_poll; -#endif ax_NS8390_init(dev, 0); if (first_init) -- cgit From c53a6ee88b0a91bd012ef1b7988c0b93dae6f24d Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Wed, 14 Jan 2009 21:06:55 -0800 Subject: can: fix slowpath issue in hrtimer callback function Due to the loopback functionality in can_send() we can not invoke it from hardirq context which was done inside the bcm_tx_timeout_handler() hrtimer callback: [ 700.361154] [] warn_slowpath+0x80/0xb6 [ 700.361163] [] valid_state+0x125/0x136 [ 700.361171] [] mark_lock+0x18e/0x332 [ 700.361180] [] __lock_acquire+0x12e/0xb1e [ 700.361189] [] bcm_tx_timeout_handler+0x0/0xbc [can_bcm] [ 700.361198] [] dev_queue_xmit+0x191/0x479 [ 700.361206] [] __local_bh_disable+0x2b/0x64 [ 700.361213] [] dev_queue_xmit+0x191/0x479 [ 700.361225] [] can_send+0xd7/0x11a [can] [ 700.361235] [] bcm_can_tx+0x9d/0xd9 [can_bcm] [ 700.361245] [] bcm_tx_timeout_handler+0x6a/0xbc [can_bcm] [ 700.361255] [] bcm_tx_timeout_handler+0x0/0xbc [can_bcm] [ 700.361263] [] __run_hrtimer+0x5a/0x86 [ 700.361273] [] bcm_tx_timeout_handler+0x0/0xbc [can_bcm] [ 700.361282] [] hrtimer_interrupt+0xb9/0x110 This patch moves the rest of the functionality from the hrtimer callback to the already existing tasklet to fix this slowpath problem. Signed-off-by: Oliver Hartkopp Signed-off-by: David S. Miller --- net/can/bcm.c | 57 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/net/can/bcm.c b/net/can/bcm.c index 1649c8ab2c2..b7c7d465113 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c @@ -347,51 +347,54 @@ static void bcm_tx_timeout_tsklet(unsigned long data) struct bcm_op *op = (struct bcm_op *)data; struct bcm_msg_head msg_head; - /* create notification to user */ - msg_head.opcode = TX_EXPIRED; - msg_head.flags = op->flags; - msg_head.count = op->count; - msg_head.ival1 = op->ival1; - msg_head.ival2 = op->ival2; - msg_head.can_id = op->can_id; - msg_head.nframes = 0; - - bcm_send_to_user(op, &msg_head, NULL, 0); -} - -/* - * bcm_tx_timeout_handler - performes cyclic CAN frame transmissions - */ -static enum hrtimer_restart bcm_tx_timeout_handler(struct hrtimer *hrtimer) -{ - struct bcm_op *op = container_of(hrtimer, struct bcm_op, timer); - enum hrtimer_restart ret = HRTIMER_NORESTART; - if (op->kt_ival1.tv64 && (op->count > 0)) { op->count--; - if (!op->count && (op->flags & TX_COUNTEVT)) - tasklet_schedule(&op->tsklet); + if (!op->count && (op->flags & TX_COUNTEVT)) { + + /* create notification to user */ + msg_head.opcode = TX_EXPIRED; + msg_head.flags = op->flags; + msg_head.count = op->count; + msg_head.ival1 = op->ival1; + msg_head.ival2 = op->ival2; + msg_head.can_id = op->can_id; + msg_head.nframes = 0; + + bcm_send_to_user(op, &msg_head, NULL, 0); + } } if (op->kt_ival1.tv64 && (op->count > 0)) { /* send (next) frame */ bcm_can_tx(op); - hrtimer_forward(hrtimer, ktime_get(), op->kt_ival1); - ret = HRTIMER_RESTART; + hrtimer_start(&op->timer, + ktime_add(ktime_get(), op->kt_ival1), + HRTIMER_MODE_ABS); } else { if (op->kt_ival2.tv64) { /* send (next) frame */ bcm_can_tx(op); - hrtimer_forward(hrtimer, ktime_get(), op->kt_ival2); - ret = HRTIMER_RESTART; + hrtimer_start(&op->timer, + ktime_add(ktime_get(), op->kt_ival2), + HRTIMER_MODE_ABS); } } +} - return ret; +/* + * bcm_tx_timeout_handler - performes cyclic CAN frame transmissions + */ +static enum hrtimer_restart bcm_tx_timeout_handler(struct hrtimer *hrtimer) +{ + struct bcm_op *op = container_of(hrtimer, struct bcm_op, timer); + + tasklet_schedule(&op->tsklet); + + return HRTIMER_NORESTART; } /* -- cgit From 6782dfe44acedf1e583d84e9e0d4f966d8e9befa Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Wed, 14 Jan 2009 22:32:58 -0700 Subject: fsldma: check for NO_IRQ in fsl_dma_chan_remove() There's no per-channel IRQ on mpc83xx, so only call free_irq if we have one. Acked-by: Timur Tabi Acked-by: Li Yang Signed-off-by: Peter Korsgaard Signed-off-by: Dan Williams --- drivers/dma/fsldma.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 748e140c5a1..b1b45eb42cb 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -890,7 +890,8 @@ err_no_reg: static void fsl_dma_chan_remove(struct fsl_dma_chan *fchan) { - free_irq(fchan->irq, fchan); + if (fchan->irq != NO_IRQ) + free_irq(fchan->irq, fchan); list_del(&fchan->common.device_node); iounmap(fchan->reg_base); kfree(fchan); -- cgit From cbbe1efa4972350286b52cb48aefaa11e198c0fb Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Wed, 14 Jan 2009 21:44:39 -0800 Subject: IPoIB: Fix deadlock between ipoib_open() and child interface create Fix a deadlock between child interface creation/deletion and ipoib start/stop. The former takes vlan_mutex, and then might take RTNL via register_netdev()/unregister_netdev(). The latter is executed with RTNL held, and tries to take vlan_mutex, which can lead to an AB-BA deadlock. Fix this by having the child interface creation/deletion code take the RTNL first so vlan_mutex always nests inside RTNL. We can use register_netdevice() for child interfaces because we form the interface name from the parent interface and hence don't need the '%' expansion of register_netdev(). Reported-by: Yossi Etigin Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/ipoib/ipoib_vlan.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c index 2cf1a408871..5a76a551035 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c @@ -61,6 +61,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) ppriv = netdev_priv(pdev); + rtnl_lock(); mutex_lock(&ppriv->vlan_mutex); /* @@ -111,7 +112,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) goto device_init_failed; } - result = register_netdev(priv->dev); + result = register_netdevice(priv->dev); if (result) { ipoib_warn(priv, "failed to initialize; error %i", result); goto register_failed; @@ -134,12 +135,13 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) list_add_tail(&priv->list, &ppriv->child_intfs); mutex_unlock(&ppriv->vlan_mutex); + rtnl_unlock(); return 0; sysfs_failed: ipoib_delete_debug_files(priv->dev); - unregister_netdev(priv->dev); + unregister_netdevice(priv->dev); register_failed: ipoib_dev_cleanup(priv->dev); @@ -149,6 +151,7 @@ device_init_failed: err: mutex_unlock(&ppriv->vlan_mutex); + rtnl_unlock(); return result; } @@ -162,10 +165,11 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey) ppriv = netdev_priv(pdev); + rtnl_lock(); mutex_lock(&ppriv->vlan_mutex); list_for_each_entry_safe(priv, tpriv, &ppriv->child_intfs, list) { if (priv->pkey == pkey) { - unregister_netdev(priv->dev); + unregister_netdevice(priv->dev); ipoib_dev_cleanup(priv->dev); list_del(&priv->list); free_netdev(priv->dev); @@ -175,6 +179,7 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey) } } mutex_unlock(&ppriv->vlan_mutex); + rtnl_unlock(); return ret; } -- cgit From 7e86c0e6850504ec9516b953f316a47277825e33 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 15 Jan 2009 10:21:23 +0100 Subject: sound: virtuoso: do not overwrite EEPROM on Xonar D2/D2X On the Asus Xonar D2 and D2X models, the SPI chip select signal for the fourth DAC shares its pin with the serial clock for the EEPROM that contains the PCI subdevice ID values. It appears that when DAC registers are written and some other unknown conditions occur (probably noise on the EEPROM's chip select line), the EEPROM gets overwritten with garbage, which makes it impossible to properly detect the card later. Therefore, we better avoid DAC register writes and make sure that the driver works with the DAC's registers' default values. Consequently, the sample format is now I2S instead of left-justified (no user-visible change), and the DAC's volume/mute registers cannot be used anymore (volume changes are now done by the software volume plugin). Signed-off-by: Clemens Ladisch Cc: Signed-off-by: Takashi Iwai --- sound/pci/oxygen/virtuoso.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 98c6a8c65d8..e9e829e83d7 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -26,7 +26,7 @@ * SPI 0 -> 1st PCM1796 (front) * SPI 1 -> 2nd PCM1796 (surround) * SPI 2 -> 3rd PCM1796 (center/LFE) - * SPI 4 -> 4th PCM1796 (back) + * SPI 4 -> 4th PCM1796 (back) and EEPROM self-destruct (do not use!) * * GPIO 2 -> M0 of CS5381 * GPIO 3 -> M1 of CS5381 @@ -207,6 +207,12 @@ static void xonar_gpio_changed(struct oxygen *chip); static inline void pcm1796_write_spi(struct oxygen *chip, unsigned int codec, u8 reg, u8 value) { + /* + * We don't want to do writes on SPI 4 because the EEPROM, which shares + * the same pin, might get confused and broken. We'd better take care + * that the driver works with the default register values ... + */ +#if 0 /* maps ALSA channel pair number to SPI output */ static const u8 codec_map[4] = { 0, 1, 2, 4 @@ -217,6 +223,7 @@ static inline void pcm1796_write_spi(struct oxygen *chip, unsigned int codec, (codec_map[codec] << OXYGEN_SPI_CODEC_SHIFT) | OXYGEN_SPI_CEN_LATCH_CLOCK_HI, (reg << 8) | value); +#endif } static inline void pcm1796_write_i2c(struct oxygen *chip, unsigned int codec, @@ -750,6 +757,9 @@ static const DECLARE_TLV_DB_SCALE(cs4362a_db_scale, -12700, 100, 0); static int xonar_d2_control_filter(struct snd_kcontrol_new *template) { + if (!strncmp(template->name, "Master Playback ", 16)) + /* disable volume/mute because they would require SPI writes */ + return 1; if (!strncmp(template->name, "CD Capture ", 11)) /* CD in is actually connected to the video in pin */ template->private_value ^= AC97_CD ^ AC97_VIDEO; @@ -840,9 +850,8 @@ static const struct oxygen_model model_xonar_d2 = { .dac_volume_min = 0x0f, .dac_volume_max = 0xff, .misc_flags = OXYGEN_MISC_MIDI, - .function_flags = OXYGEN_FUNCTION_SPI | - OXYGEN_FUNCTION_ENABLE_SPI_4_5, - .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, + .function_flags = OXYGEN_FUNCTION_SPI, + .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; -- cgit From 9e6f8ed7c3a303d37eb119847dd3029701e37e28 Mon Sep 17 00:00:00 2001 From: Balaji Rao Date: Wed, 14 Jan 2009 13:02:00 +0100 Subject: mfd: Remove non exported references from pcf50633 Remove references to set_irq_type and handle_level_irq which are not exported to modules Signed-off-by: Balaji Rao Signed-off-by: Samuel Ortiz --- drivers/mfd/pcf50633-core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index 24508e28e3f..ea9488e7ad6 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c @@ -626,7 +626,6 @@ static int __devinit pcf50633_probe(struct i2c_client *client, } if (client->irq) { - set_irq_handler(client->irq, handle_level_irq); ret = request_irq(client->irq, pcf50633_irq, IRQF_TRIGGER_LOW, "pcf50633", pcf); -- cgit From f11826385b63566d98c02d35f592232ee77cd791 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 14 Jan 2009 12:27:35 +0000 Subject: x86: fully honor "nolapic" Impact: widen the effect of the 'nolapic' boot parameter "nolapic" should not only suppress SMP and use of the LAPIC, but it also ought to have the effect of disabling all IO-APIC related activity as well as PCI MSI and HT-IRQs. Signed-off-by: Jan Beulich Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic.c | 7 ++++++- arch/x86/kernel/io_apic.c | 6 ++++++ arch/x86/kernel/smpboot.c | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c index 0f830e4f567..c3dd64fabcf 100644 --- a/arch/x86/kernel/apic.c +++ b/arch/x86/kernel/apic.c @@ -1126,6 +1126,11 @@ void __cpuinit setup_local_APIC(void) unsigned int value; int i, j; + if (disable_apic) { + disable_ioapic_setup(); + return; + } + #ifdef CONFIG_X86_32 /* Pound the ESR really hard over the head with a big hammer - mbligh */ if (lapic_is_integrated() && esr_disable) { @@ -1566,11 +1571,11 @@ int apic_version[MAX_APICS]; int __init APIC_init_uniprocessor(void) { -#ifdef CONFIG_X86_64 if (disable_apic) { pr_info("Apic disabled\n"); return -1; } +#ifdef CONFIG_X86_64 if (!cpu_has_apic) { disable_apic = 1; pr_info("Apic disabled by BIOS\n"); diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c index 1c4a1302536..40747e58f30 100644 --- a/arch/x86/kernel/io_apic.c +++ b/arch/x86/kernel/io_apic.c @@ -3258,6 +3258,9 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms int err; unsigned dest; + if (disable_apic) + return -ENXIO; + cfg = irq_cfg(irq); err = assign_irq_vector(irq, cfg, TARGET_CPUS); if (err) @@ -3726,6 +3729,9 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) struct irq_cfg *cfg; int err; + if (disable_apic) + return -ENXIO; + cfg = irq_cfg(irq); err = assign_irq_vector(irq, cfg, TARGET_CPUS); if (!err) { diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index bb1a3b1fc87..31f99ec2e0f 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -1125,6 +1125,7 @@ static int __init smp_sanity_check(unsigned max_cpus) printk(KERN_ERR "... forcing use of dummy APIC emulation." "(tell your hw vendor)\n"); smpboot_clear_io_apic(); + disable_ioapic_setup(); return -1; } -- cgit From a08c4743ed5b861c4fa3d75be00da7106c926296 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 14 Jan 2009 12:28:51 +0000 Subject: x86: avoid early crash in disable_local_APIC() E.g. when called due to an early panic. Signed-off-by: Jan Beulich Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c index c3dd64fabcf..38d6aab2358 100644 --- a/arch/x86/kernel/apic.c +++ b/arch/x86/kernel/apic.c @@ -895,6 +895,10 @@ void disable_local_APIC(void) { unsigned int value; + /* APIC hasn't been mapped yet */ + if (!apic_phys) + return; + clear_local_APIC(); /* -- cgit From 934d96eafadcf3eb3ccd094af9919f020907fc41 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Wed, 14 Jan 2009 20:38:17 +0530 Subject: time-sched.c: tick_nohz_update_jiffies should be static Impact: cleanup, reduce kernel size a bit, avoid sparse warning Fixes sparse warning: kernel/time/tick-sched.c:137:6: warning: symbol 'tick_nohz_update_jiffies' was not declared. Should it be static? Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- kernel/time/tick-sched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 1b6c05bd0d0..d3f1ef4d5cb 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -134,7 +134,7 @@ __setup("nohz=", setup_tick_nohz); * value. We do this unconditionally on any cpu, as we don't know whether the * cpu, which has the update task assigned is in a long sleep. */ -void tick_nohz_update_jiffies(void) +static void tick_nohz_update_jiffies(void) { int cpu = smp_processor_id(); struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); -- cgit From dd7667aa700a45ffb3efac64f6df0867d5837f5b Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 15 Jan 2009 13:09:51 +0200 Subject: ARM: OMAP: Fix compile for various McBSP Include irqs.h or cpu.h directly as needed to fix omap builds. Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/mcbsp.c | 1 + arch/arm/mach-omap2/mcbsp.c | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/mach-omap1/mcbsp.c b/arch/arm/mach-omap1/mcbsp.c index 4474da7bc88..ca7a0cc1707 100644 --- a/arch/arm/mach-omap1/mcbsp.c +++ b/arch/arm/mach-omap1/mcbsp.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index acdc709901c..e20023c9d15 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include -- cgit From dc0e88c7e15acbe3d7e8682312f709938f0dcf01 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 15 Jan 2009 13:09:52 +0200 Subject: ARM: OMAP: Fix compile for palmte Remove old MMC platform init code accidentally left behind. Patches are welcome to the new style MMC init code. Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/board-palmte.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c index 75e32d35afd..00322f42f45 100644 --- a/arch/arm/mach-omap1/board-palmte.c +++ b/arch/arm/mach-omap1/board-palmte.c @@ -195,15 +195,6 @@ static struct omap_usb_config palmte_usb_config __initdata = { .pins[0] = 2, }; -static struct omap_mmc_config palmte_mmc_config __initdata = { - .mmc[0] = { - .enabled = 1, - .wp_pin = PALMTE_MMC_WP_GPIO, - .power_pin = PALMTE_MMC_POWER_GPIO, - .switch_pin = PALMTE_MMC_SWITCH_GPIO, - }, -}; - static struct omap_lcd_config palmte_lcd_config __initdata = { .ctrl_name = "internal", }; -- cgit From 73069e388d0f2509e45e1a58b0facca99ef2446e Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Thu, 15 Jan 2009 13:09:52 +0200 Subject: ARM: OMAP: Fix gpio by switching to generic gpio calls, v2 Fix compile by removing remaining omap specific gpio calls. Based on earlier patches by Jarkko Nikula. Also remove old GPIO key code, there is already a patch to do this with gpio_keys. Signed-off-by: Jarkko Nikula Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/board-sx1.c | 6 ++-- arch/arm/mach-omap2/board-apollon.c | 64 ++++------------------------------ arch/arm/mach-omap2/board-ldp.c | 2 +- arch/arm/plat-omap/include/mach/gpio.h | 10 ------ drivers/mtd/onenand/omap2.c | 6 ++-- 5 files changed, 13 insertions(+), 75 deletions(-) diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c index 8171fe0ca08..09a242261a3 100644 --- a/arch/arm/mach-omap1/board-sx1.c +++ b/arch/arm/mach-omap1/board-sx1.c @@ -423,9 +423,9 @@ static void __init omap_sx1_init(void) /* turn on USB power */ /* sx1_setusbpower(1); cant do it here because i2c is not ready */ - omap_request_gpio(1); /* A_IRDA_OFF */ - omap_request_gpio(11); /* A_SWITCH */ - omap_request_gpio(15); /* A_USB_ON */ + gpio_request(1, "A_IRDA_OFF"); + gpio_request(11, "A_SWITCH"); + gpio_request(15, "A_USB_ON"); gpio_direction_output(1, 1); /*A_IRDA_OFF = 1 */ gpio_direction_output(11, 0); /*A_SWITCH = 0 */ gpio_direction_output(15, 0); /*A_USB_ON = 0 */ diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c index bf1e5d32c2a..0a7b24ba165 100644 --- a/arch/arm/mach-omap2/board-apollon.c +++ b/arch/arm/mach-omap2/board-apollon.c @@ -22,8 +22,6 @@ #include #include #include -#include -#include #include #include #include @@ -282,65 +280,16 @@ static void __init apollon_led_init(void) { /* LED0 - AA10 */ omap_cfg_reg(AA10_242X_GPIO13); - omap_request_gpio(LED0_GPIO13); - omap_set_gpio_direction(LED0_GPIO13, 0); - omap_set_gpio_dataout(LED0_GPIO13, 0); + gpio_request(LED0_GPIO13, "LED0"); + gpio_direction_output(LED0_GPIO13, 0); /* LED1 - AA6 */ omap_cfg_reg(AA6_242X_GPIO14); - omap_request_gpio(LED1_GPIO14); - omap_set_gpio_direction(LED1_GPIO14, 0); - omap_set_gpio_dataout(LED1_GPIO14, 0); + gpio_request(LED1_GPIO14, "LED1"); + gpio_direction_output(LED1_GPIO14, 0); /* LED2 - AA4 */ omap_cfg_reg(AA4_242X_GPIO15); - omap_request_gpio(LED2_GPIO15); - omap_set_gpio_direction(LED2_GPIO15, 0); - omap_set_gpio_dataout(LED2_GPIO15, 0); -} - -static irqreturn_t apollon_sw_interrupt(int irq, void *ignored) -{ - static unsigned int led0, led1, led2; - - if (irq == OMAP_GPIO_IRQ(SW_ENTER_GPIO16)) - omap_set_gpio_dataout(LED0_GPIO13, led0 ^= 1); - else if (irq == OMAP_GPIO_IRQ(SW_UP_GPIO17)) - omap_set_gpio_dataout(LED1_GPIO14, led1 ^= 1); - else if (irq == OMAP_GPIO_IRQ(SW_DOWN_GPIO58)) - omap_set_gpio_dataout(LED2_GPIO15, led2 ^= 1); - - return IRQ_HANDLED; -} - -static void __init apollon_sw_init(void) -{ - /* Enter SW - Y11 */ - omap_cfg_reg(Y11_242X_GPIO16); - omap_request_gpio(SW_ENTER_GPIO16); - gpio_direction_input(SW_ENTER_GPIO16); - /* Up SW - AA12 */ - omap_cfg_reg(AA12_242X_GPIO17); - omap_request_gpio(SW_UP_GPIO17); - gpio_direction_input(SW_UP_GPIO17); - /* Down SW - AA8 */ - omap_cfg_reg(AA8_242X_GPIO58); - omap_request_gpio(SW_DOWN_GPIO58); - gpio_direction_input(SW_DOWN_GPIO58); - - set_irq_type(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), IRQ_TYPE_EDGE_RISING); - if (request_irq(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), &apollon_sw_interrupt, - IRQF_SHARED, "enter sw", - &apollon_sw_interrupt)) - return; - set_irq_type(OMAP_GPIO_IRQ(SW_UP_GPIO17), IRQ_TYPE_EDGE_RISING); - if (request_irq(OMAP_GPIO_IRQ(SW_UP_GPIO17), &apollon_sw_interrupt, - IRQF_SHARED, "up sw", - &apollon_sw_interrupt)) - return; - set_irq_type(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), IRQ_TYPE_EDGE_RISING); - if (request_irq(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), &apollon_sw_interrupt, - IRQF_SHARED, "down sw", - &apollon_sw_interrupt)) - return; + gpio_request(LED2_GPIO15, "LED2"); + gpio_direction_output(LED2_GPIO15, 0); } static void __init apollon_usb_init(void) @@ -357,7 +306,6 @@ static void __init omap_apollon_init(void) u32 v; apollon_led_init(); - apollon_sw_init(); apollon_flash_init(); apollon_usb_init(); diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c index aa6972781e4..f6a13451d1f 100644 --- a/arch/arm/mach-omap2/board-ldp.c +++ b/arch/arm/mach-omap2/board-ldp.c @@ -88,7 +88,7 @@ static inline void __init ldp_init_smc911x(void) ldp_smc911x_resources[1].start = OMAP_GPIO_IRQ(eth_gpio); - if (omap_request_gpio(eth_gpio) < 0) { + if (gpio_request(eth_gpio, "smc911x irq") < 0) { printk(KERN_ERR "Failed to request GPIO%d for smc911x IRQ\n", eth_gpio); return; diff --git a/arch/arm/plat-omap/include/mach/gpio.h b/arch/arm/plat-omap/include/mach/gpio.h index 04e68e88f13..8d9dfe31438 100644 --- a/arch/arm/plat-omap/include/mach/gpio.h +++ b/arch/arm/plat-omap/include/mach/gpio.h @@ -87,16 +87,6 @@ extern void omap_set_gpio_debounce_time(int gpio, int enable); #include #include -static inline int omap_request_gpio(int gpio) -{ - return gpio_request(gpio, "FIXME"); -} - -static inline void omap_free_gpio(int gpio) -{ - gpio_free(gpio); -} - static inline int gpio_get_value(unsigned gpio) { return __gpio_get_value(gpio); diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c index 96ecc1766fa..77a4f144615 100644 --- a/drivers/mtd/onenand/omap2.c +++ b/drivers/mtd/onenand/omap2.c @@ -629,7 +629,7 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev) } if (c->gpio_irq) { - if ((r = omap_request_gpio(c->gpio_irq)) < 0) { + if ((r = gpio_request(c->gpio_irq, "OneNAND irq")) < 0) { dev_err(&pdev->dev, "Failed to request GPIO%d for " "OneNAND\n", c->gpio_irq); goto err_iounmap; @@ -726,7 +726,7 @@ err_release_dma: free_irq(gpio_to_irq(c->gpio_irq), c); err_release_gpio: if (c->gpio_irq) - omap_free_gpio(c->gpio_irq); + gpio_free(c->gpio_irq); err_iounmap: iounmap(c->onenand.base); err_release_mem_region: @@ -761,7 +761,7 @@ static int __devexit omap2_onenand_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); if (c->gpio_irq) { free_irq(gpio_to_irq(c->gpio_irq), c); - omap_free_gpio(c->gpio_irq); + gpio_free(c->gpio_irq); } iounmap(c->onenand.base); release_mem_region(c->phys_base, ONENAND_IO_SIZE); -- cgit From 145d9c94b9039efdab6853255f6b916adc793bfd Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 15 Jan 2009 13:09:53 +0200 Subject: ARM: OMAP: Fix compile for beagle Move twl4030 gpio init code to where it should be. Also include twl4030.h. Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-omap3beagle.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 9e5ada01b5f..38c88fbe658 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -28,6 +28,8 @@ #include #include +#include + #include #include #include @@ -120,6 +122,9 @@ static int beagle_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio) { /* gpio + 0 is "mmc0_cd" (input/IRQ) */ + omap_cfg_reg(AH8_34XX_GPIO29); + mmc[0].gpio_cd = gpio + 0; + twl4030_mmc_init(mmc); /* REVISIT: need ehci-omap hooks for external VBUS * power switch and overcurrent detect @@ -304,10 +309,6 @@ static void __init omap3_beagle_init(void) omap_board_config_size = ARRAY_SIZE(omap3_beagle_config); omap_serial_init(); - omap_cfg_reg(AH8_34XX_GPIO29); - mmc[0].gpio_cd = gpio + 0; - twl4030_mmc_init(mmc); - omap_cfg_reg(J25_34XX_GPIO170); gpio_request(170, "DVI_nPD"); /* REVISIT leave DVI powered down until it's needed ... */ -- cgit From 3a26e3318bc2ceec340f242c6ee7074becdc7219 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 15 Jan 2009 13:09:53 +0200 Subject: ARM: OMAP: Fix gpio.c compile on 15xx with CONFIG_DEBUGFS There are no wakeup registers on 15xx, and suspend_wakeup does not exist in the struct gpio_bank. Without this fix we'll get "arch/arm/plat-omap/gpio.c:1792: error: 'struct gpio_bank' has no member named 'suspend_wakeup'" as noted by Russell King. Note that the ifdefs will be cleaned up once the omap gpio code gets split into omap1 and omap2 specific parts. Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/gpio.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 07b6968a7d1..f856a90b264 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -1789,6 +1789,8 @@ static int dbg_gpio_show(struct seq_file *s, void *unused) /* FIXME for at least omap2, show pullup/pulldown state */ irqstat = irq_desc[irq].status; +#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX) || \ + defined(CONFIG_ARCH_OMAP34XX) if (is_in && ((bank->suspend_wakeup & mask) || irqstat & IRQ_TYPE_SENSE_MASK)) { char *trigger = NULL; @@ -1818,6 +1820,7 @@ static int dbg_gpio_show(struct seq_file *s, void *unused) (bank->suspend_wakeup & mask) ? " wakeup" : ""); } +#endif seq_printf(s, "\n"); } -- cgit From 4b3cf44846b6424d4119676ad68d54a62b81e31c Mon Sep 17 00:00:00 2001 From: Anand Gadiyar Date: Thu, 15 Jan 2009 13:09:53 +0200 Subject: ARM: OMAP: Fix DMA CCR programming for request line > 63, v3 Bug in existing code causes synchro control to be set +32 if request line greater than 63 is used. Also clean up the function a bit by removing extra parens and clearing the bits at before write. Reported by Wenbiao Wang. Signed-off-by: Anand Gadiyar Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/dma.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 692d2b495af..e77373c39f8 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -278,14 +278,11 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, u32 val; val = dma_read(CCR(lch)); - val &= ~(3 << 19); - if (dma_trigger > 63) - val |= 1 << 20; - if (dma_trigger > 31) - val |= 1 << 19; - - val &= ~(0x1f); - val |= (dma_trigger & 0x1f); + + /* DMA_SYNCHRO_CONTROL_UPPER depends on the channel number */ + val &= ~((3 << 19) | 0x1f); + val |= (dma_trigger & ~0x1f) << 14; + val |= dma_trigger & 0x1f; if (sync_mode & OMAP_DMA_SYNC_FRAME) val |= 1 << 5; -- cgit From 52628229db37229d9a6eb3af082b17a61736b86c Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Thu, 15 Jan 2009 13:09:54 +0200 Subject: ARM: OMAP: remove duplicated #include's Removed duplicated #include's in arch/arm/mach-omap1/board-voiceblue.c Signed-off-by: Huang Weiyi Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/board-voiceblue.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c index c224f3c6423..a7653542a2b 100644 --- a/arch/arm/mach-omap1/board-voiceblue.c +++ b/arch/arm/mach-omap1/board-voiceblue.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include -- cgit From 9b4a357787c27289b8c9efe916417690473538f7 Mon Sep 17 00:00:00 2001 From: Arun KS Date: Thu, 15 Jan 2009 13:09:54 +0200 Subject: ARM: OMAP: Fix OSK ASoC by registering I2C board info for tlvaic23 Adding I2C board info is required for tlvaic23 i2c chip driver. Cc: Jarkko Nikula Signed-off-by: Arun KS Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/board-osk.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index ff9e67baa5c..d17952fa2e6 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -259,8 +259,10 @@ static struct i2c_board_info __initdata osk_i2c_board_info[] = { .platform_data = &tps_board, }, + { + I2C_BOARD_INFO("tlv320aic23", 0x1B), + }, /* TODO when driver support is ready: - * - aic23 audio chip at 0x1a * - optionally on Mistral, ov9640 camera sensor at 0x30 */ }; -- cgit From 3127f8f8595a064b3f1a1837fea2177902589ac3 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 15 Jan 2009 13:09:54 +0200 Subject: ARM: OMAP: Fix ASoC by enabling writes to XCCR and RCCR McBSP registers, v3 This patch enables writing to McBSP Transmit Configuration Control Register (XCCR) and Receive Configuration Control Register (RCCR) for 2430/34xx platforms. It also adds XCCR, RCCR entries in McBSP register configuration structure and bit definitions for both registers. If we enable the writing to CCR registers for 2430/34xx and don't set the default values (setting 0 as a consequence) in ASoC driver, the Transmit/Receive DMA mode gets disabled and the the transmission/reception doesn't happen, ending with a "write error: Input/Output error" when playing with 'aplay'. Also define dummy CCR registers for omap1. Cc: Jarkko Nikula Signed-off-by: Misael Lopez Cruz Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/include/mach/mcbsp.h | 11 +++++++++++ arch/arm/plat-omap/mcbsp.c | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/arch/arm/plat-omap/include/mach/mcbsp.h b/arch/arm/plat-omap/include/mach/mcbsp.h index 6a0d1a0a24a..eef873db3d4 100644 --- a/arch/arm/plat-omap/include/mach/mcbsp.h +++ b/arch/arm/plat-omap/include/mach/mcbsp.h @@ -87,6 +87,10 @@ #define OMAP_MCBSP_REG_XCERG 0x3A #define OMAP_MCBSP_REG_XCERH 0x3C +/* Dummy defines, these are not available on omap1 */ +#define OMAP_MCBSP_REG_XCCR 0x00 +#define OMAP_MCBSP_REG_RCCR 0x00 + #define AUDIO_MCBSP_DATAWRITE (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1) #define AUDIO_MCBSP_DATAREAD (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1) @@ -231,11 +235,16 @@ #define XPBBLK(value) ((value)<<7) /* Bits 7:8 */ /*********************** McBSP XCCR bit definitions *************************/ +#define EXTCLKGATE 0x8000 +#define PPCONNECT 0x4000 +#define DXENDLY(value) ((value)<<12) /* Bits 12:13 */ +#define XFULL_CYCLE 0x0800 #define DILB 0x0020 #define XDMAEN 0x0008 #define XDISABLE 0x0001 /********************** McBSP RCCR bit definitions *************************/ +#define RFULL_CYCLE 0x0800 #define RDMAEN 0x0008 #define RDISABLE 0x0001 @@ -267,6 +276,8 @@ struct omap_mcbsp_reg_cfg { u16 rcerh; u16 xcerg; u16 xcerh; + u16 xccr; + u16 rccr; }; typedef enum { diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index af33fc713e1..f2401a831f9 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -173,6 +173,10 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config) OMAP_MCBSP_WRITE(io_base, MCR2, config->mcr2); OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1); OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0); + if (cpu_is_omap2430() || cpu_is_omap34xx()) { + OMAP_MCBSP_WRITE(io_base, XCCR, config->xccr); + OMAP_MCBSP_WRITE(io_base, RCCR, config->rccr); + } } EXPORT_SYMBOL(omap_mcbsp_config); -- cgit From e999bbe7f1318390e997d13e508e4f16b1b130af Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 15 Jan 2009 13:55:59 +0200 Subject: ARM: OMAP: Remove unused platform devices, v3 This patch removes old platform devices. Alsa should now be using the ASoC driver. For boards not yet using ASoC, please see sound/soc/omap/osk5912.c. Add dummy aic23_power_up and aic23_power_down functions for 770 to keep things compiling. Remove references to omap_gpio_switch, and unused h2_nand_dev_ready function. This patch is based on an earlier patch by Arun KS. Cc: Jarkko Nikula Signed-off-by: Arun KS Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/board-h2.c | 45 +------------ arch/arm/mach-omap1/board-h3.c | 50 -------------- arch/arm/mach-omap1/board-innovator.c | 39 ----------- arch/arm/mach-omap1/board-nokia770.c | 8 ++- arch/arm/mach-omap1/board-osk.c | 39 ----------- arch/arm/mach-omap1/board-palmte.c | 20 ------ arch/arm/mach-omap1/board-palmtt.c | 41 ----------- arch/arm/mach-omap1/board-palmz71.c | 37 ---------- arch/arm/mach-omap1/board-sx1.c | 33 +-------- arch/arm/plat-omap/include/mach/aic23.h | 116 -------------------------------- 10 files changed, 9 insertions(+), 419 deletions(-) delete mode 100644 arch/arm/plat-omap/include/mach/aic23.h diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index b240c5f861d..0d784a79509 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c @@ -37,16 +37,14 @@ #include #include -#include #include +#include #include #include #include #include #include #include -#include -#include static int h2_keymap[] = { KEY(0, 0, KEY_LEFT), @@ -292,41 +290,6 @@ static struct platform_device h2_lcd_device = { .id = -1, }; -static struct omap_mcbsp_reg_cfg mcbsp_regs = { - .spcr2 = FREE | FRST | GRST | XRST | XINTM(3), - .spcr1 = RINTM(3) | RRST, - .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) | - RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(1), - .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16), - .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) | - XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(1) | XFIG, - .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16), - .srgr1 = FWID(15), - .srgr2 = GSYNC | CLKSP | FSGM | FPER(31), - - .pcr0 = CLKXM | CLKRM | FSXP | FSRP | CLKXP | CLKRP, - /*.pcr0 = CLKXP | CLKRP,*/ /* mcbsp: slave */ -}; - -static struct omap_alsa_codec_config alsa_config = { - .name = "H2 TSC2101", - .mcbsp_regs_alsa = &mcbsp_regs, - .codec_configure_dev = NULL, /* tsc2101_configure, */ - .codec_set_samplerate = NULL, /* tsc2101_set_samplerate, */ - .codec_clock_setup = NULL, /* tsc2101_clock_setup, */ - .codec_clock_on = NULL, /* tsc2101_clock_on, */ - .codec_clock_off = NULL, /* tsc2101_clock_off, */ - .get_default_samplerate = NULL, /* tsc2101_get_default_samplerate, */ -}; - -static struct platform_device h2_mcbsp1_device = { - .name = "omap_alsa_mcbsp", - .id = 1, - .dev = { - .platform_data = &alsa_config, - }, -}; - static struct platform_device *h2_devices[] __initdata = { &h2_nor_device, &h2_nand_device, @@ -334,7 +297,6 @@ static struct platform_device *h2_devices[] __initdata = { &h2_irda_device, &h2_kp_device, &h2_lcd_device, - &h2_mcbsp1_device, }; static void __init h2_init_smc91x(void) @@ -409,11 +371,6 @@ static struct omap_board_config_kernel h2_config[] __initdata = { #define H2_NAND_RB_GPIO_PIN 62 -static int h2_nand_dev_ready(struct omap_nand_platform_data *data) -{ - return gpio_get_value(H2_NAND_RB_GPIO_PIN); -} - static void __init h2_init(void) { /* Here we assume the NOR boot config: NOR on CS3 (possibly swapped diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index 5157eea9be3..bf08b6ad22e 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c @@ -49,8 +49,6 @@ #include #include #include -#include -#include #define H3_TS_GPIO 48 @@ -387,41 +385,6 @@ static struct spi_board_info h3_spi_board_info[] __initdata = { }, }; -static struct omap_mcbsp_reg_cfg mcbsp_regs = { - .spcr2 = FREE | FRST | GRST | XRST | XINTM(3), - .spcr1 = RINTM(3) | RRST, - .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) | - RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(1), - .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16), - .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) | - XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(1) | XFIG, - .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16), - .srgr1 = FWID(15), - .srgr2 = GSYNC | CLKSP | FSGM | FPER(31), - - .pcr0 = CLKRM | SCLKME | FSXP | FSRP | CLKXP | CLKRP, - /*.pcr0 = CLKXP | CLKRP,*/ /* mcbsp: slave */ -}; - -static struct omap_alsa_codec_config alsa_config = { - .name = "H3 TSC2101", - .mcbsp_regs_alsa = &mcbsp_regs, - .codec_configure_dev = NULL, /* tsc2101_configure, */ - .codec_set_samplerate = NULL, /* tsc2101_set_samplerate, */ - .codec_clock_setup = NULL, /* tsc2101_clock_setup, */ - .codec_clock_on = NULL, /* tsc2101_clock_on, */ - .codec_clock_off = NULL, /* tsc2101_clock_off, */ - .get_default_samplerate = NULL, /* tsc2101_get_default_samplerate, */ -}; - -static struct platform_device h3_mcbsp1_device = { - .name = "omap_alsa_mcbsp", - .id = 1, - .dev = { - .platform_data = &alsa_config, - }, -}; - static struct platform_device *devices[] __initdata = { &nor_device, &nand_device, @@ -430,7 +393,6 @@ static struct platform_device *devices[] __initdata = { &h3_irda_device, &h3_kp_device, &h3_lcd_device, - &h3_mcbsp1_device, }; static struct omap_usb_config h3_usb_config __initdata = { @@ -472,18 +434,6 @@ static struct i2c_board_info __initdata h3_i2c_board_info[] = { }, }; -static struct omap_gpio_switch h3_gpio_switches[] __initdata = { - { - .name = "mmc_slot", - .gpio = OMAP_MPUIO(1), - .type = OMAP_GPIO_SWITCH_TYPE_COVER, - .debounce_rising = 100, - .debounce_falling = 0, - .notify = h3_mmc_slot_cover_handler, - .notify_data = NULL, - }, -}; - #define H3_NAND_RB_GPIO_PIN 10 static int nand_dev_ready(struct omap_nand_platform_data *data) diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c index af2fb907008..071cd02a734 100644 --- a/arch/arm/mach-omap1/board-innovator.c +++ b/arch/arm/mach-omap1/board-innovator.c @@ -37,8 +37,6 @@ #include #include #include -#include -#include #include static int innovator_keymap[] = { @@ -115,42 +113,6 @@ static struct platform_device innovator_flash_device = { .resource = &innovator_flash_resource, }; -#define DEFAULT_BITPERSAMPLE 16 - -static struct omap_mcbsp_reg_cfg mcbsp_regs = { - .spcr2 = FREE | FRST | GRST | XRST | XINTM(3), - .spcr1 = RINTM(3) | RRST, - .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) | - RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(0), - .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16), - .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) | - XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG, - .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16), - .srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1), - .srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1), - /*.pcr0 = FSXM | FSRM | CLKXM | CLKRM | CLKXP | CLKRP,*/ /* mcbsp: master */ - .pcr0 = CLKXP | CLKRP, /* mcbsp: slave */ -}; - -static struct omap_alsa_codec_config alsa_config = { - .name = "OMAP Innovator AIC23", - .mcbsp_regs_alsa = &mcbsp_regs, - .codec_configure_dev = NULL, /* aic23_configure, */ - .codec_set_samplerate = NULL, /* aic23_set_samplerate, */ - .codec_clock_setup = NULL, /* aic23_clock_setup, */ - .codec_clock_on = NULL, /* aic23_clock_on, */ - .codec_clock_off = NULL, /* aic23_clock_off, */ - .get_default_samplerate = NULL, /* aic23_get_default_samplerate, */ -}; - -static struct platform_device innovator_mcbsp1_device = { - .name = "omap_alsa_mcbsp", - .id = 1, - .dev = { - .platform_data = &alsa_config, - }, -}; - static struct resource innovator_kp_resources[] = { [0] = { .start = INT_KEYBOARD, @@ -227,7 +189,6 @@ static struct platform_device innovator1510_spi_device = { static struct platform_device *innovator1510_devices[] __initdata = { &innovator_flash_device, &innovator1510_smc91x_device, - &innovator_mcbsp1_device, &innovator_kp_device, &innovator1510_lcd_device, &innovator1510_spi_device, diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index 4970c402a59..af51e0b180f 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -261,6 +260,13 @@ static DEFINE_MUTEX(audio_pwr_lock); */ static int audio_pwr_state = -1; +static inline void aic23_power_up(void) +{ +} +static inline void aic23_power_down(void) +{ +} + /* * audio_pwr_up / down should be called under audio_pwr_lock */ diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index d17952fa2e6..1a16ecb2ccc 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -51,8 +51,6 @@ #include #include #include -#include -#include static struct mtd_partition osk_partitions[] = { /* bootloader (U-Boot, etc) in first sector */ @@ -141,47 +139,10 @@ static struct platform_device osk5912_cf_device = { .resource = osk5912_cf_resources, }; -#define DEFAULT_BITPERSAMPLE 16 - -static struct omap_mcbsp_reg_cfg mcbsp_regs = { - .spcr2 = FREE | FRST | GRST | XRST | XINTM(3), - .spcr1 = RINTM(3) | RRST, - .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) | - RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(0), - .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16), - .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) | - XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG, - .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16), - .srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1), - .srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1), - /*.pcr0 = FSXM | FSRM | CLKXM | CLKRM | CLKXP | CLKRP,*/ /* mcbsp: master */ - .pcr0 = CLKXP | CLKRP, /* mcbsp: slave */ -}; - -static struct omap_alsa_codec_config alsa_config = { - .name = "OSK AIC23", - .mcbsp_regs_alsa = &mcbsp_regs, - .codec_configure_dev = NULL, /* aic23_configure, */ - .codec_set_samplerate = NULL, /* aic23_set_samplerate, */ - .codec_clock_setup = NULL, /* aic23_clock_setup, */ - .codec_clock_on = NULL, /* aic23_clock_on, */ - .codec_clock_off = NULL, /* aic23_clock_off, */ - .get_default_samplerate = NULL, /* aic23_get_default_samplerate, */ -}; - -static struct platform_device osk5912_mcbsp1_device = { - .name = "omap_alsa_mcbsp", - .id = 1, - .dev = { - .platform_data = &alsa_config, - }, -}; - static struct platform_device *osk5912_devices[] __initdata = { &osk5912_flash_device, &osk5912_smc91x_device, &osk5912_cf_device, - &osk5912_mcbsp1_device, }; static struct gpio_led tps_leds[] = { diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c index 00322f42f45..99f2b43f254 100644 --- a/arch/arm/mach-omap1/board-palmte.c +++ b/arch/arm/mach-omap1/board-palmte.c @@ -42,8 +42,6 @@ #include #include #include -#include -#include static void __init omap_palmte_init_irq(void) { @@ -203,24 +201,6 @@ static struct omap_uart_config palmte_uart_config __initdata = { .enabled_uarts = (1 << 0) | (1 << 1) | (0 << 2), }; -static struct omap_mcbsp_reg_cfg palmte_mcbsp1_regs = { - .spcr2 = FRST | GRST | XRST | XINTM(3), - .xcr2 = XDATDLY(1) | XFIG, - .xcr1 = XWDLEN1(OMAP_MCBSP_WORD_32), - .pcr0 = SCLKME | FSXP | CLKXP, -}; - -static struct omap_alsa_codec_config palmte_alsa_config = { - .name = "TSC2102 audio", - .mcbsp_regs_alsa = &palmte_mcbsp1_regs, - .codec_configure_dev = NULL, /* tsc2102_configure, */ - .codec_set_samplerate = NULL, /* tsc2102_set_samplerate, */ - .codec_clock_setup = NULL, /* tsc2102_clock_setup, */ - .codec_clock_on = NULL, /* tsc2102_clock_on, */ - .codec_clock_off = NULL, /* tsc2102_clock_off, */ - .get_default_samplerate = NULL, /* tsc2102_get_default_samplerate, */ -}; - #ifdef CONFIG_APM /* * Values measured in 10 minute intervals averaged over 10 samples. diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c index 5c001afe806..1cbc1275c95 100644 --- a/arch/arm/mach-omap1/board-palmtt.c +++ b/arch/arm/mach-omap1/board-palmtt.c @@ -30,7 +30,6 @@ #include #include -#include #include #include #include @@ -40,7 +39,6 @@ #include #include #include -#include #include #include @@ -122,44 +120,6 @@ static struct platform_device palmtt_flash_device = { .resource = &palmtt_flash_resource, }; -#define DEFAULT_BITPERSAMPLE 16 - -static struct omap_mcbsp_reg_cfg mcbsp_regs = { - .spcr2 = FREE | FRST | GRST | XRST | XINTM(3), - .spcr1 = RINTM(3) | RRST, - .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) | - RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(0), - .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | - RWDLEN1(OMAP_MCBSP_WORD_16), - .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) | - XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG, - .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | - XWDLEN1(OMAP_MCBSP_WORD_16), - .srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1), - .srgr2 = GSYNC | CLKSP | FSGM | - FPER(DEFAULT_BITPERSAMPLE * 2 - 1), - .pcr0 = CLKXP | CLKRP, /* mcbsp: slave */ -}; - -static struct omap_alsa_codec_config alsa_config = { - .name = "PalmTT AIC23", - .mcbsp_regs_alsa = &mcbsp_regs, - .codec_configure_dev = NULL, /* aic23_configure, */ - .codec_set_samplerate = NULL, /* aic23_set_samplerate, */ - .codec_clock_setup = NULL, /* aic23_clock_setup, */ - .codec_clock_on = NULL, /* aic23_clock_on, */ - .codec_clock_off = NULL, /* aic23_clock_off, */ - .get_default_samplerate = NULL, /* aic23_get_default_samplerate, */ -}; - -static struct platform_device palmtt_mcbsp1_device = { - .name = "omap_alsa_mcbsp", - .id = 1, - .dev = { - .platform_data = &alsa_config, - }, -}; - static struct resource palmtt_kp_resources[] = { [0] = { .start = INT_KEYBOARD, @@ -257,7 +217,6 @@ static struct platform_device palmtt_led_device = { static struct platform_device *palmtt_devices[] __initdata = { &palmtt_flash_device, - &palmtt_mcbsp1_device, &palmtt_kp_device, &palmtt_lcd_device, &palmtt_irda_device, diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c index cc05257eb1c..baf5efbfe3e 100644 --- a/arch/arm/mach-omap1/board-palmz71.c +++ b/arch/arm/mach-omap1/board-palmz71.c @@ -32,7 +32,6 @@ #include #include -#include #include #include #include @@ -179,41 +178,6 @@ static struct platform_device palmz71_spi_device = { .id = -1, }; -#define DEFAULT_BITPERSAMPLE 16 - -static struct omap_mcbsp_reg_cfg mcbsp_regs = { - .spcr2 = FREE | FRST | GRST | XRST | XINTM(3), - .spcr1 = RINTM(3) | RRST, - .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) | - RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(0), - .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16), - .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) | - XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG, - .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16), - .srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1), - .srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1), - .pcr0 = CLKXP | CLKRP, /* mcbsp: slave */ -}; - -static struct omap_alsa_codec_config alsa_config = { - .name = "PalmZ71 AIC23", - .mcbsp_regs_alsa = &mcbsp_regs, - .codec_configure_dev = NULL, /* aic23_configure */ - .codec_set_samplerate = NULL, /* aic23_set_samplerate */ - .codec_clock_setup = NULL, /* aic23_clock_setup */ - .codec_clock_on = NULL, /* aic23_clock_on */ - .codec_clock_off = NULL, /* aic23_clock_off */ - .get_default_samplerate = NULL, /* aic23_get_default_samplerate */ -}; - -static struct platform_device palmz71_mcbsp1_device = { - .name = "omap_alsa_mcbsp", - .id = 1, - .dev = { - .platform_data = &alsa_config, - }, -}; - static struct omap_backlight_config palmz71_backlight_config = { .default_intensity = 0xa0, }; @@ -229,7 +193,6 @@ static struct platform_device palmz71_backlight_device = { static struct platform_device *devices[] __initdata = { &palmz71_rom_device, &palmz71_kp_device, - &palmz71_mcbsp1_device, &palmz71_lcd_device, &palmz71_irda_device, &palmz71_spi_device, diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c index 09a242261a3..28c76a1e71c 100644 --- a/arch/arm/mach-omap1/board-sx1.c +++ b/arch/arm/mach-omap1/board-sx1.c @@ -34,13 +34,12 @@ #include #include +#include #include #include #include #include #include -#include -#include #include /* Write to I2C device */ @@ -254,35 +253,6 @@ static struct platform_device sx1_irda_device = { .resource = sx1_irda_resources, }; -/*----------- McBSP & Sound -------------------------*/ - -/* Playback interface - McBSP1 */ -static struct omap_mcbsp_reg_cfg mcbsp1_regs = { - .spcr2 = XINTM(3), /* SPCR2=30 */ - .spcr1 = RINTM(3), /* SPCR1=30 */ - .rcr2 = 0, /* RCR2 =00 */ - .rcr1 = RFRLEN1(1) | RWDLEN1(OMAP_MCBSP_WORD_16), /* RCR1=140 */ - .xcr2 = 0, /* XCR2 = 0 */ - .xcr1 = XFRLEN1(1) | XWDLEN1(OMAP_MCBSP_WORD_16), /* XCR1 = 140 */ - .srgr1 = FWID(15) | CLKGDV(12), /* SRGR1=0f0c */ - .srgr2 = FSGM | FPER(31), /* SRGR2=101f */ - .pcr0 = FSXM | FSRM | CLKXM | CLKRM | FSXP | FSRP | CLKXP | CLKRP, - /* PCR0 =0f0f */ -}; - -static struct omap_alsa_codec_config sx1_alsa_config = { - .name = "SX1 EGold", - .mcbsp_regs_alsa = &mcbsp1_regs, -}; - -static struct platform_device sx1_mcbsp1_device = { - .name = "omap_alsa_mcbsp", - .id = 1, - .dev = { - .platform_data = &sx1_alsa_config, - }, -}; - /*----------- MTD -------------------------*/ static struct mtd_partition sx1_partitions[] = { @@ -394,7 +364,6 @@ static struct platform_device *sx1_devices[] __initdata = { &sx1_flash_device, &sx1_kp_device, &sx1_lcd_device, - &sx1_mcbsp1_device, &sx1_irda_device, }; /*-----------------------------------------*/ diff --git a/arch/arm/plat-omap/include/mach/aic23.h b/arch/arm/plat-omap/include/mach/aic23.h deleted file mode 100644 index 5ccedac7752..00000000000 --- a/arch/arm/plat-omap/include/mach/aic23.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * arch/arm/plat-omap/include/mach/aic23.h - * - * Hardware definitions for TI TLV320AIC23 audio codec - * - * Copyright (C) 2002 RidgeRun, Inc. - * Author: Steve Johnson - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __ASM_ARCH_AIC23_H -#define __ASM_ARCH_AIC23_H - -// Codec TLV320AIC23 -#define LEFT_LINE_VOLUME_ADDR 0x00 -#define RIGHT_LINE_VOLUME_ADDR 0x01 -#define LEFT_CHANNEL_VOLUME_ADDR 0x02 -#define RIGHT_CHANNEL_VOLUME_ADDR 0x03 -#define ANALOG_AUDIO_CONTROL_ADDR 0x04 -#define DIGITAL_AUDIO_CONTROL_ADDR 0x05 -#define POWER_DOWN_CONTROL_ADDR 0x06 -#define DIGITAL_AUDIO_FORMAT_ADDR 0x07 -#define SAMPLE_RATE_CONTROL_ADDR 0x08 -#define DIGITAL_INTERFACE_ACT_ADDR 0x09 -#define RESET_CONTROL_ADDR 0x0F - -// Left (right) line input volume control register -#define LRS_ENABLED 0x0100 -#define LIM_MUTED 0x0080 -#define LIV_DEFAULT 0x0017 -#define LIV_MAX 0x001f -#define LIV_MIN 0x0000 - -// Left (right) channel headphone volume control register -#define LZC_ON 0x0080 -#define LHV_DEFAULT 0x0079 -#define LHV_MAX 0x007f -#define LHV_MIN 0x0000 - -// Analog audio path control register -#define STA_REG(x) ((x)<<6) -#define STE_ENABLED 0x0020 -#define DAC_SELECTED 0x0010 -#define BYPASS_ON 0x0008 -#define INSEL_MIC 0x0004 -#define MICM_MUTED 0x0002 -#define MICB_20DB 0x0001 - -// Digital audio path control register -#define DACM_MUTE 0x0008 -#define DEEMP_32K 0x0002 -#define DEEMP_44K 0x0004 -#define DEEMP_48K 0x0006 -#define ADCHP_ON 0x0001 - -// Power control down register -#define DEVICE_POWER_OFF 0x0080 -#define CLK_OFF 0x0040 -#define OSC_OFF 0x0020 -#define OUT_OFF 0x0010 -#define DAC_OFF 0x0008 -#define ADC_OFF 0x0004 -#define MIC_OFF 0x0002 -#define LINE_OFF 0x0001 - -// Digital audio interface register -#define MS_MASTER 0x0040 -#define LRSWAP_ON 0x0020 -#define LRP_ON 0x0010 -#define IWL_16 0x0000 -#define IWL_20 0x0004 -#define IWL_24 0x0008 -#define IWL_32 0x000C -#define FOR_I2S 0x0002 -#define FOR_DSP 0x0003 - -// Sample rate control register -#define CLKOUT_HALF 0x0080 -#define CLKIN_HALF 0x0040 -#define BOSR_384fs 0x0002 // BOSR_272fs when in USB mode -#define USB_CLK_ON 0x0001 -#define SR_MASK 0xf -#define CLKOUT_SHIFT 7 -#define CLKIN_SHIFT 6 -#define SR_SHIFT 2 -#define BOSR_SHIFT 1 - -// Digital interface register -#define ACT_ON 0x0001 - -#define TLV320AIC23ID1 (0x1a) // cs low -#define TLV320AIC23ID2 (0x1b) // cs high - -void aic23_power_up(void); -void aic23_power_down(void); - -#endif /* __ASM_ARCH_AIC23_H */ -- cgit From 1639058ed1dd0b856a5c34064a990c7827b0e32b Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 15 Jan 2009 13:57:48 +0200 Subject: ARM: OMAP: Fix compile for h3 MMC Fix compile for h3 MMC Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/include/mach/board-h3.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm/plat-omap/include/mach/board-h3.h b/arch/arm/plat-omap/include/mach/board-h3.h index 14909dc7858..1888326da7e 100644 --- a/arch/arm/plat-omap/include/mach/board-h3.h +++ b/arch/arm/plat-omap/include/mach/board-h3.h @@ -30,7 +30,9 @@ /* In OMAP1710 H3 the Ethernet is directly connected to CS1 */ #define OMAP1710_ETHR_START 0x04000300 +#define H3_TPS_GPIO_BASE (OMAP_MAX_GPIO_LINES + 16 /* MPUIO */) +# define H3_TPS_GPIO_MMC_PWR_EN (H3_TPS_GPIO_BASE + 4) + extern void h3_mmc_init(void); -extern void h3_mmc_slot_cover_handler(void *arg, int state); #endif /* __ASM_ARCH_OMAP_H3_H */ -- cgit From e56d0cfe7790fd3218ae4f6aae1335547fea8763 Mon Sep 17 00:00:00 2001 From: Baodong Chen Date: Thu, 8 Jan 2009 19:24:29 +0800 Subject: Documentation/x86/boot.txt: modify fieldname Modify field names to the right ones: - start_sys was changed to start_sys_seg - iinitrd_addr_max was changed to ramdisk_max - pad2 was changed to pad2 and pad3 - readmode_swtch was changed to realmode_swtch Signed-off-by: Baodong Chen <[email]chenbdchenbd@gmail.com[email]> Acked-by: Jiri Kosina Signed-off-by: Ingo Molnar --- Documentation/x86/boot.txt | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Documentation/x86/boot.txt b/Documentation/x86/boot.txt index 7b4596ac412..12299697b7c 100644 --- a/Documentation/x86/boot.txt +++ b/Documentation/x86/boot.txt @@ -158,7 +158,7 @@ Offset Proto Name Meaning 0202/4 2.00+ header Magic signature "HdrS" 0206/2 2.00+ version Boot protocol version supported 0208/4 2.00+ realmode_swtch Boot loader hook (see below) -020C/2 2.00+ start_sys The load-low segment (0x1000) (obsolete) +020C/2 2.00+ start_sys_seg The load-low segment (0x1000) (obsolete) 020E/2 2.00+ kernel_version Pointer to kernel version string 0210/1 2.00+ type_of_loader Boot loader identifier 0211/1 2.00+ loadflags Boot protocol option flags @@ -170,10 +170,11 @@ Offset Proto Name Meaning 0224/2 2.01+ heap_end_ptr Free memory after setup end 0226/2 N/A pad1 Unused 0228/4 2.02+ cmd_line_ptr 32-bit pointer to the kernel command line -022C/4 2.03+ initrd_addr_max Highest legal initrd address +022C/4 2.03+ ramdisk_max Highest legal initrd address 0230/4 2.05+ kernel_alignment Physical addr alignment required for kernel 0234/1 2.05+ relocatable_kernel Whether kernel is relocatable or not -0235/3 N/A pad2 Unused +0235/1 N/A pad2 Unused +0236/2 N/A pad3 Unused 0238/4 2.06+ cmdline_size Maximum size of the kernel command line 023C/4 2.07+ hardware_subarch Hardware subarchitecture 0240/8 2.07+ hardware_subarch_data Subarchitecture-specific data @@ -299,14 +300,14 @@ Protocol: 2.00+ e.g. 0x0204 for version 2.04, and 0x0a11 for a hypothetical version 10.17. -Field name: readmode_swtch +Field name: realmode_swtch Type: modify (optional) Offset/size: 0x208/4 Protocol: 2.00+ Boot loader hook (see ADVANCED BOOT LOADER HOOKS below.) -Field name: start_sys +Field name: start_sys_seg Type: read Offset/size: 0x20c/2 Protocol: 2.00+ @@ -468,7 +469,7 @@ Protocol: 2.02+ zero, the kernel will assume that your boot loader does not support the 2.02+ protocol. -Field name: initrd_addr_max +Field name: ramdisk_max Type: read Offset/size: 0x22c/4 Protocol: 2.03+ -- cgit From 98a4826b99bc4bcc34c604b2fc4fcf4d771600ec Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 14 Jan 2009 10:56:32 +0100 Subject: sched: fix bandwidth validation for UID grouping Impact: make rt-limit tunables work again Mark Glines reported: > I've got an issue on x86-64 where I can't configure the system to allow > RT tasks for a non-root user. > > In 2.6.26.5, I was able to do the following to set things up nicely: > echo 450000 >/sys/kernel/uids/0/cpu_rt_runtime > echo 450000 >/sys/kernel/uids/1000/cpu_rt_runtime > > Seems like every value I try to echo into the /sys files returns EINVAL. For UID grouping we initialize the root group with infinite bandwidth which by default is actually more than the global limit, therefore the bandwidth check always fails. Because the root group is a phantom group (for UID grouping) we cannot runtime adjust it, therefore we let it reflect the global bandwidth settings. Reported-by: Mark Glines Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- kernel/sched.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/kernel/sched.c b/kernel/sched.c index 3b630d88266..ed62d1cee05 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -9050,6 +9050,13 @@ static int tg_schedulable(struct task_group *tg, void *data) runtime = d->rt_runtime; } +#ifdef CONFIG_USER_SCHED + if (tg == &root_task_group) { + period = global_rt_period(); + runtime = global_rt_runtime(); + } +#endif + /* * Cannot have more runtime than the period. */ -- cgit From cce7ade803699463ecc62a065ca522004f7ccb3d Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 15 Jan 2009 14:53:37 +0100 Subject: sched: SCHED_IDLE weight change Increase the SCHED_IDLE weight from 2 to 3, this gives much more stable vruntime numbers. time advanced in 100ms: weight=2 64765.988352 67012.881408 88501.412352 weight=3 35496.181411 34130.971298 35497.411573 Signed-off-by: Mike Galbraith Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- kernel/sched.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index ed62d1cee05..6acfb3c2398 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1323,8 +1323,8 @@ static inline void update_load_sub(struct load_weight *lw, unsigned long dec) * slice expiry etc. */ -#define WEIGHT_IDLEPRIO 2 -#define WMULT_IDLEPRIO (1 << 31) +#define WEIGHT_IDLEPRIO 3 +#define WMULT_IDLEPRIO 1431655765 /* * Nice levels are multiplicative, with a gentle 10% change for every -- cgit From 6bc912b71b6f33b041cfde93ca3f019cbaa852bc Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 15 Jan 2009 14:53:38 +0100 Subject: sched: SCHED_OTHER vs SCHED_IDLE isolation Stronger SCHED_IDLE isolation: - no SCHED_IDLE buddies - never let SCHED_IDLE preempt on wakeup - always preempt SCHED_IDLE on wakeup - limit SLEEPER fairness for SCHED_IDLE. Signed-off-by: Mike Galbraith Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- kernel/sched_fair.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 8e1352c7555..cdebd8089cb 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -677,9 +677,13 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) unsigned long thresh = sysctl_sched_latency; /* - * convert the sleeper threshold into virtual time + * Convert the sleeper threshold into virtual time. + * SCHED_IDLE is a special sub-class. We care about + * fairness only relative to other SCHED_IDLE tasks, + * all of which have the same weight. */ - if (sched_feat(NORMALIZED_SLEEPER)) + if (sched_feat(NORMALIZED_SLEEPER) && + task_of(se)->policy != SCHED_IDLE) thresh = calc_delta_fair(thresh, se); vruntime -= thresh; @@ -1340,14 +1344,18 @@ wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se) static void set_last_buddy(struct sched_entity *se) { - for_each_sched_entity(se) - cfs_rq_of(se)->last = se; + if (likely(task_of(se)->policy != SCHED_IDLE)) { + for_each_sched_entity(se) + cfs_rq_of(se)->last = se; + } } static void set_next_buddy(struct sched_entity *se) { - for_each_sched_entity(se) - cfs_rq_of(se)->next = se; + if (likely(task_of(se)->policy != SCHED_IDLE)) { + for_each_sched_entity(se) + cfs_rq_of(se)->next = se; + } } /* @@ -1393,12 +1401,18 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int sync) return; /* - * Batch tasks do not preempt (their preemption is driven by + * Batch and idle tasks do not preempt (their preemption is driven by * the tick): */ - if (unlikely(p->policy == SCHED_BATCH)) + if (unlikely(p->policy != SCHED_NORMAL)) return; + /* Idle tasks are by definition preempted by everybody. */ + if (unlikely(curr->policy == SCHED_IDLE)) { + resched_task(curr); + return; + } + if (!sched_feat(WAKEUP_PREEMPT)) return; -- cgit From e17036dac189dd034c092a91df56aa740db7146d Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 15 Jan 2009 14:53:39 +0100 Subject: sched: fix update_min_vruntime Impact: fix SCHED_IDLE latency problems OK, so we have 1 running task A (which is obviously curr and the tree is equally obviously empty). 'A' nicely chugs along, doing its thing, carrying min_vruntime along as it goes. Then some whacko speed freak SCHED_IDLE task gets inserted due to SMP balancing, which is very likely far right, in that case update_curr update_min_vruntime cfs_rq->rb_leftmost := true (the crazy task sitting in a tree) vruntime = se->vruntime and voila, min_vruntime is waaay right of where it ought to be. OK, so why did I write it like that to begin with... Aah, yes. Say we've just dequeued current schedule deactivate_task(prev) dequeue_entity update_min_vruntime Then we'll set vruntime = cfs_rq->min_vruntime; we find !cfs_rq->curr, but do find someone in the tree. Then we _must_ do vruntime = se->vruntime, because vruntime = min_vruntime(vruntime := cfs_rq->min_vruntime, se->vruntime) will not advance vruntime, and cause lags the other way around (which we fixed with that initial patch: 1af5f730fc1bf7c62ec9fb2d307206e18bf40a69 (sched: more accurate min_vruntime accounting). Signed-off-by: Peter Zijlstra Tested-by: Mike Galbraith Acked-by: Mike Galbraith Cc: Signed-off-by: Ingo Molnar --- kernel/sched_fair.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index cdebd8089cb..16b419bb8b0 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -283,7 +283,7 @@ static void update_min_vruntime(struct cfs_rq *cfs_rq) struct sched_entity, run_node); - if (vruntime == cfs_rq->min_vruntime) + if (!cfs_rq->curr) vruntime = se->vruntime; else vruntime = min_vruntime(vruntime, se->vruntime); -- cgit From eff317d0834ad1ff03f747f6bc2d76b9a9c95160 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 15 Jan 2009 14:40:47 +0200 Subject: ASoC: Fix the power update function for snd_soc_dapm_value_mux Modify the check for the mux type to also handle the snd_soc_dapm_value_mux type in a same way as the snd_soc_dapm_mux. Signed-off-by: Peter Ujfalusi Signed-off-by: Takashi Iwai --- sound/soc/soc-dapm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 493a4e8aa27..a2f1da8b464 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -720,7 +720,8 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, struct snd_soc_dapm_path *path; int found = 0; - if (widget->id != snd_soc_dapm_mux) + if (widget->id != snd_soc_dapm_mux && + widget->id != snd_soc_dapm_value_mux) return -ENODEV; if (!snd_soc_test_bits(widget->codec, e->reg, mask, val)) -- cgit From 428549f5746c9d6135d425d076a1bed2614d58ee Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 15 Jan 2009 16:56:59 +0100 Subject: ALSA: hda - Fix invalid amp value for STAC925x The value set in the commit 2465fb6605b4f8f3964b132017bf4078d1265fe9 is actually wrong. The value range is from 0 to 0x1f while the patch sets to 0x7f. Let's fix it. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index e6c13963f21..c39deebb588 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -886,7 +886,7 @@ static struct hda_verb stac925x_core_init[] = { /* set dac0mux for dac converter */ { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00}, /* unmute and set max the selector */ - { 0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb07f }, + { 0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f }, {} }; -- cgit From 1cf167f27ad2720af11ee8aa350009342f909e70 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:22:18 -0800 Subject: bnx2x: Using singlethread work queue Since slow-path events, including link update, are handled in work-queue, a race condition was introduced in the self-test that sometimes caused the link status to fail: the self-test was running under RTNL lock, and if the link-watch was scheduled it stoped the shared work-queue (waiting for the RTNL lock) and so the link update event was not handled until the self-test ended (releasing the RTNL lock) with failure (since the link status was not updated) Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x.h | 2 +- drivers/net/bnx2x_main.c | 20 +++++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index fd705d1295a..96a8889afbe 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h @@ -811,7 +811,7 @@ struct bnx2x { int pm_cap; int pcie_cap; - struct work_struct sp_task; + struct delayed_work sp_task; struct work_struct reset_task; struct timer_list timer; diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 4be05847f86..cc6ffba7459 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -95,6 +95,7 @@ MODULE_PARM_DESC(debug, "default debug msglevel"); module_param(use_multi, int, 0); MODULE_PARM_DESC(use_multi, "use per-CPU queues"); #endif +static struct workqueue_struct *bnx2x_wq; enum bnx2x_board_type { BCM57710 = 0, @@ -671,7 +672,8 @@ static void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw) synchronize_irq(bp->pdev->irq); /* make sure sp_task is not running */ - cancel_work_sync(&bp->sp_task); + cancel_delayed_work(&bp->sp_task); + flush_workqueue(bnx2x_wq); } /* fast path */ @@ -1660,7 +1662,7 @@ static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) if (unlikely(status & 0x1)) { - schedule_work(&bp->sp_task); + queue_delayed_work(bnx2x_wq, &bp->sp_task, 0); status &= ~0x1; if (!status) @@ -2820,7 +2822,7 @@ static void bnx2x_attn_int(struct bnx2x *bp) static void bnx2x_sp_task(struct work_struct *work) { - struct bnx2x *bp = container_of(work, struct bnx2x, sp_task); + struct bnx2x *bp = container_of(work, struct bnx2x, sp_task.work); u16 status; @@ -2875,7 +2877,7 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) return IRQ_HANDLED; #endif - schedule_work(&bp->sp_task); + queue_delayed_work(bnx2x_wq, &bp->sp_task, 0); return IRQ_HANDLED; } @@ -7501,7 +7503,7 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) mutex_init(&bp->port.phy_mutex); - INIT_WORK(&bp->sp_task, bnx2x_sp_task); + INIT_DELAYED_WORK(&bp->sp_task, bnx2x_sp_task); INIT_WORK(&bp->reset_task, bnx2x_reset_task); rc = bnx2x_get_hwinfo(bp); @@ -10519,12 +10521,20 @@ static struct pci_driver bnx2x_pci_driver = { static int __init bnx2x_init(void) { + bnx2x_wq = create_singlethread_workqueue("bnx2x"); + if (bnx2x_wq == NULL) { + printk(KERN_ERR PFX "Cannot create workqueue\n"); + return -ENOMEM; + } + return pci_register_driver(&bnx2x_pci_driver); } static void __exit bnx2x_cleanup(void) { pci_unregister_driver(&bnx2x_pci_driver); + + destroy_workqueue(bnx2x_wq); } module_init(bnx2x_init); -- cgit From 58f4c4cfce5c4715b79621f0a635925c55f855d5 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:23:36 -0800 Subject: bnx2x: Missing memory barriers While working on IA64, it became clear that the following memory barriers are missing Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index cc6ffba7459..f0b2e73b87f 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -1357,11 +1357,23 @@ static inline void bnx2x_update_rx_prod(struct bnx2x *bp, rx_prods.cqe_prod = rx_comp_prod; rx_prods.sge_prod = rx_sge_prod; + /* + * Make sure that the BD and SGE data is updated before updating the + * producers since FW might read the BD/SGE right after the producer + * is updated. + * This is only applicable for weak-ordered memory model archs such + * as IA-64. The following barrier is also mandatory since FW will + * assumes BDs must have buffers. + */ + wmb(); + for (i = 0; i < sizeof(struct tstorm_eth_rx_producers)/4; i++) REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_RX_PRODS_OFFSET(BP_PORT(bp), FP_CL_ID(fp)) + i*4, ((u32 *)&rx_prods)[i]); + mmiowb(); /* keep prod updates ordered */ + DP(NETIF_MSG_RX_STATUS, "Wrote: bd_prod %u cqe_prod %u sge_prod %u\n", bd_prod, rx_comp_prod, rx_sge_prod); @@ -1582,7 +1594,6 @@ next_cqe: /* Update producers */ bnx2x_update_rx_prod(bp, fp, bd_prod_fw, sw_comp_prod, fp->rx_sge_prod); - mmiowb(); /* keep prod updates ordered */ fp->rx_pkt += rx_pkt; fp->rx_calls++; @@ -8729,6 +8740,8 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) tx_bd->general_data = ((UNICAST_ADDRESS << ETH_TX_BD_ETH_ADDR_TYPE_SHIFT) | 1); + wmb(); + fp->hw_tx_prods->bds_prod = cpu_to_le16(le16_to_cpu(fp->hw_tx_prods->bds_prod) + 1); mb(); /* FW restriction: must not reorder writing nbd and packets */ @@ -8780,7 +8793,6 @@ test_loopback_rx_exit: /* Update producers */ bnx2x_update_rx_prod(bp, fp, fp->rx_bd_prod, fp->rx_comp_prod, fp->rx_sge_prod); - mmiowb(); /* keep prod updates ordered */ test_loopback_exit: bp->link_params.loopback_mode = LOOPBACK_NONE; @@ -9707,6 +9719,15 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) DP(NETIF_MSG_TX_QUEUED, "doorbell: nbd %d bd %u\n", nbd, bd_prod); + /* + * Make sure that the BD data is updated before updating the producer + * since FW might read the BD right after the producer is updated. + * This is only applicable for weak-ordered memory model archs such + * as IA-64. The following barrier is also mandatory since FW will + * assumes packets must have BDs. + */ + wmb(); + fp->hw_tx_prods->bds_prod = cpu_to_le16(le16_to_cpu(fp->hw_tx_prods->bds_prod) + nbd); mb(); /* FW restriction: must not reorder writing nbd and packets */ @@ -9720,6 +9741,9 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) dev->trans_start = jiffies; if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) { + /* We want bnx2x_tx_int to "see" the updated tx_bd_prod + if we put Tx into XOFF state. */ + smp_mb(); netif_stop_queue(dev); bp->eth_stats.driver_xoff++; if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3) -- cgit From 4f40f2cba244e04c0f385c5ce60498b513b335dd Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:24:17 -0800 Subject: bnx2x: Using system page size for SGE When the page size is not 4KB, the FW must be programmed to work with the right SGE boundaries and fragment list length. To avoid confusion with the BCM_PAGE_SIZE which is set to 4KB for the FW sake, another alias for the system page size was added to explicitly indicate that it is meant for the SGE Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x.h | 3 +++ drivers/net/bnx2x_main.c | 32 ++++++++++++++++---------------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index 96a8889afbe..2cd1e427828 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h @@ -150,6 +150,9 @@ struct sw_rx_page { #define PAGES_PER_SGE_SHIFT 0 #define PAGES_PER_SGE (1 << PAGES_PER_SGE_SHIFT) +#define SGE_PAGE_SIZE PAGE_SIZE +#define SGE_PAGE_SHIFT PAGE_SHIFT +#define SGE_PAGE_ALIGN(addr) PAGE_ALIGN(addr) #define BCM_RX_ETH_PAYLOAD_ALIGN 64 diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index f0b2e73b87f..75b2624cd60 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -974,7 +974,7 @@ static inline void bnx2x_free_rx_sge(struct bnx2x *bp, return; pci_unmap_page(bp->pdev, pci_unmap_addr(sw_buf, mapping), - BCM_PAGE_SIZE*PAGES_PER_SGE, PCI_DMA_FROMDEVICE); + SGE_PAGE_SIZE*PAGES_PER_SGE, PCI_DMA_FROMDEVICE); __free_pages(page, PAGES_PER_SGE_SHIFT); sw_buf->page = NULL; @@ -1002,7 +1002,7 @@ static inline int bnx2x_alloc_rx_sge(struct bnx2x *bp, if (unlikely(page == NULL)) return -ENOMEM; - mapping = pci_map_page(bp->pdev, page, 0, BCM_PAGE_SIZE*PAGES_PER_SGE, + mapping = pci_map_page(bp->pdev, page, 0, SGE_PAGE_SIZE*PAGES_PER_SGE, PCI_DMA_FROMDEVICE); if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { __free_pages(page, PAGES_PER_SGE_SHIFT); @@ -1098,9 +1098,9 @@ static void bnx2x_update_sge_prod(struct bnx2x_fastpath *fp, struct eth_fast_path_rx_cqe *fp_cqe) { struct bnx2x *bp = fp->bp; - u16 sge_len = BCM_PAGE_ALIGN(le16_to_cpu(fp_cqe->pkt_len) - + u16 sge_len = SGE_PAGE_ALIGN(le16_to_cpu(fp_cqe->pkt_len) - le16_to_cpu(fp_cqe->len_on_bd)) >> - BCM_PAGE_SHIFT; + SGE_PAGE_SHIFT; u16 last_max, last_elem, first_elem; u16 delta = 0; u16 i; @@ -1205,22 +1205,22 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, u16 cqe_idx) { struct sw_rx_page *rx_pg, old_rx_pg; - struct page *sge; u16 len_on_bd = le16_to_cpu(fp_cqe->len_on_bd); u32 i, frag_len, frag_size, pages; int err; int j; frag_size = le16_to_cpu(fp_cqe->pkt_len) - len_on_bd; - pages = BCM_PAGE_ALIGN(frag_size) >> BCM_PAGE_SHIFT; + pages = SGE_PAGE_ALIGN(frag_size) >> SGE_PAGE_SHIFT; /* This is needed in order to enable forwarding support */ if (frag_size) - skb_shinfo(skb)->gso_size = min((u32)BCM_PAGE_SIZE, + skb_shinfo(skb)->gso_size = min((u32)SGE_PAGE_SIZE, max(frag_size, (u32)len_on_bd)); #ifdef BNX2X_STOP_ON_ERROR - if (pages > 8*PAGES_PER_SGE) { + if (pages > + min((u32)8, (u32)MAX_SKB_FRAGS) * SGE_PAGE_SIZE * PAGES_PER_SGE) { BNX2X_ERR("SGL length is too long: %d. CQE index is %d\n", pages, cqe_idx); BNX2X_ERR("fp_cqe->pkt_len = %d fp_cqe->len_on_bd = %d\n", @@ -1236,9 +1236,8 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, /* FW gives the indices of the SGE as if the ring is an array (meaning that "next" element will consume 2 indices) */ - frag_len = min(frag_size, (u32)(BCM_PAGE_SIZE*PAGES_PER_SGE)); + frag_len = min(frag_size, (u32)(SGE_PAGE_SIZE*PAGES_PER_SGE)); rx_pg = &fp->rx_page_ring[sge_idx]; - sge = rx_pg->page; old_rx_pg = *rx_pg; /* If we fail to allocate a substitute page, we simply stop @@ -1251,7 +1250,7 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, /* Unmap the page as we r going to pass it to the stack */ pci_unmap_page(bp->pdev, pci_unmap_addr(&old_rx_pg, mapping), - BCM_PAGE_SIZE*PAGES_PER_SGE, PCI_DMA_FROMDEVICE); + SGE_PAGE_SIZE*PAGES_PER_SGE, PCI_DMA_FROMDEVICE); /* Add one frag and update the appropriate fields in the skb */ skb_fill_page_desc(skb, j, old_rx_pg.page, 0, frag_len); @@ -4544,7 +4543,7 @@ static void bnx2x_set_client_config(struct bnx2x *bp) if (bp->flags & TPA_ENABLE_FLAG) { tstorm_client.max_sges_for_packet = - BCM_PAGE_ALIGN(tstorm_client.mtu) >> BCM_PAGE_SHIFT; + SGE_PAGE_ALIGN(tstorm_client.mtu) >> SGE_PAGE_SHIFT; tstorm_client.max_sges_for_packet = ((tstorm_client.max_sges_for_packet + PAGES_PER_SGE - 1) & (~(PAGES_PER_SGE - 1))) >> @@ -4727,10 +4726,11 @@ static void bnx2x_init_internal_func(struct bnx2x *bp) bp->e1hov); } - /* Init CQ ring mapping and aggregation size */ - max_agg_size = min((u32)(bp->rx_buf_size + - 8*BCM_PAGE_SIZE*PAGES_PER_SGE), - (u32)0xffff); + /* Init CQ ring mapping and aggregation size, the FW limit is 8 frags */ + max_agg_size = + min((u32)(min((u32)8, (u32)MAX_SKB_FRAGS) * + SGE_PAGE_SIZE * PAGES_PER_SGE), + (u32)0xffff); for_each_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; -- cgit From ad33ea3a8d2ec324dc0f46b6ae404d824d2b349b Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:24:57 -0800 Subject: bnx2x: Missing mask when calculating flow control Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 75b2624cd60..9b1555820f5 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -1899,7 +1899,8 @@ static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode) static void bnx2x_calc_fc_adv(struct bnx2x *bp) { - switch (bp->link_vars.ieee_fc) { + switch (bp->link_vars.ieee_fc & + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK) { case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE: bp->port.advertising &= ~(ADVERTISED_Asym_Pause | ADVERTISED_Pause); -- cgit From 3c96c68b0c67d11b8519bc38233aec586f0211f4 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:25:31 -0800 Subject: bnx2x: Flow control updated before reporting the link Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 9b1555820f5..4f1ee1f2968 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -1970,10 +1970,11 @@ static u8 bnx2x_initial_phy_init(struct bnx2x *bp) rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars); bnx2x_release_phy_lock(bp); + bnx2x_calc_fc_adv(bp); + if (bp->link_vars.link_up) bnx2x_link_report(bp); - bnx2x_calc_fc_adv(bp); return rc; } -- cgit From a5e9a7cfad5fd301ce2b7869bbf386b70aa39e7c Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:26:01 -0800 Subject: bnx2x: Protecting the link change indication Without this lock, in some race conditions the driver missed link change indication Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 4f1ee1f2968..701bcc1260c 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -2234,9 +2234,7 @@ static void bnx2x_link_attn(struct bnx2x *bp) /* Make sure that we are synced with the current statistics */ bnx2x_stats_handle(bp, STATS_EVENT_STOP); - bnx2x_acquire_phy_lock(bp); bnx2x_link_update(&bp->link_params, &bp->link_vars); - bnx2x_release_phy_lock(bp); if (bp->link_vars.link_up) { @@ -2485,6 +2483,8 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted) if (asserted & ATTN_HARD_WIRED_MASK) { if (asserted & ATTN_NIG_FOR_FUNC) { + bnx2x_acquire_phy_lock(bp); + /* save nig interrupt mask */ bp->nig_mask = REG_RD(bp, nig_int_mask_addr); REG_WR(bp, nig_int_mask_addr, 0); @@ -2540,8 +2540,10 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted) REG_WR(bp, hc_addr, asserted); /* now set back the mask */ - if (asserted & ATTN_NIG_FOR_FUNC) + if (asserted & ATTN_NIG_FOR_FUNC) { REG_WR(bp, nig_int_mask_addr, bp->nig_mask); + bnx2x_release_phy_lock(bp); + } } static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn) -- cgit From 0c6671b0d94f706dfc20cb22d792218ba9814412 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:26:51 -0800 Subject: bnx2x: VLAN tagged packets without VLAN offload Wrong handling of tagged packet if VLAN offload is disabled caused packets to get corrupted Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x.h | 12 +++++++----- drivers/net/bnx2x_main.c | 42 +++++++++++++++++++++++++++++++++--------- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index 2cd1e427828..e7fbca7722d 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h @@ -20,6 +20,11 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +#define BCM_VLAN 1 +#endif + + /* error/debug prints */ #define DRV_MODULE_NAME "bnx2x" @@ -78,11 +83,6 @@ #endif -#ifdef NETIF_F_HW_VLAN_TX -#define BCM_VLAN 1 -#endif - - #define U64_LO(x) (u32)(((u64)(x)) & 0xffffffff) #define U64_HI(x) (u32)(((u64)(x)) >> 32) #define HILO_U64(hi, lo) ((((u64)(hi)) << 32) + (lo)) @@ -804,6 +804,8 @@ struct bnx2x { #define TPA_ENABLE_FLAG 0x80 #define NO_MCP_FLAG 0x100 #define BP_NOMCP(bp) (bp->flags & NO_MCP_FLAG) +#define HW_VLAN_TX_FLAG 0x400 +#define HW_VLAN_RX_FLAG 0x800 int func; #define BP_PORT(bp) (bp->func % PORT_MAX) diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 701bcc1260c..ca8b25126b2 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -38,9 +38,7 @@ #include #include #include -#ifdef NETIF_F_HW_VLAN_TX - #include -#endif +#include #include #include #include @@ -1283,6 +1281,13 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, if (likely(new_skb)) { /* fix ip xsum and give it to the stack */ /* (no need to map the new skb) */ +#ifdef BCM_VLAN + int is_vlan_cqe = + (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & + PARSING_FLAGS_VLAN); + int is_not_hwaccel_vlan_cqe = + (is_vlan_cqe && (!(bp->flags & HW_VLAN_RX_FLAG))); +#endif prefetch(skb); prefetch(((char *)(skb)) + 128); @@ -1307,6 +1312,12 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, struct iphdr *iph; iph = (struct iphdr *)skb->data; +#ifdef BCM_VLAN + /* If there is no Rx VLAN offloading - + take VLAN tag into an account */ + if (unlikely(is_not_hwaccel_vlan_cqe)) + iph = (struct iphdr *)((u8 *)iph + VLAN_HLEN); +#endif iph->check = 0; iph->check = ip_fast_csum((u8 *)iph, iph->ihl); } @@ -1314,9 +1325,8 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, if (!bnx2x_fill_frag_skb(bp, fp, skb, &cqe->fast_path_cqe, cqe_idx)) { #ifdef BCM_VLAN - if ((bp->vlgrp != NULL) && - (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & - PARSING_FLAGS_VLAN)) + if ((bp->vlgrp != NULL) && is_vlan_cqe && + (!is_not_hwaccel_vlan_cqe)) vlan_hwaccel_receive_skb(skb, bp->vlgrp, le16_to_cpu(cqe->fast_path_cqe. vlan_tag)); @@ -1560,7 +1570,7 @@ reuse_rx: } #ifdef BCM_VLAN - if ((bp->vlgrp != NULL) && + if ((bp->vlgrp != NULL) && (bp->flags & HW_VLAN_RX_FLAG) && (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & PARSING_FLAGS_VLAN)) vlan_hwaccel_receive_skb(skb, bp->vlgrp, @@ -4538,7 +4548,7 @@ static void bnx2x_set_client_config(struct bnx2x *bp) tstorm_client.config_flags = TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE; #ifdef BCM_VLAN - if (bp->rx_mode && bp->vlgrp) { + if (bp->rx_mode && bp->vlgrp && (bp->flags & HW_VLAN_RX_FLAG)) { tstorm_client.config_flags |= TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE; DP(NETIF_MSG_IFUP, "vlan removal enabled\n"); @@ -9567,11 +9577,14 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) "sending pkt %u @%p next_idx %u bd %u @%p\n", pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_bd); - if ((bp->vlgrp != NULL) && vlan_tx_tag_present(skb)) { +#ifdef BCM_VLAN + if ((bp->vlgrp != NULL) && vlan_tx_tag_present(skb) && + (bp->flags & HW_VLAN_TX_FLAG)) { tx_bd->vlan = cpu_to_le16(vlan_tx_tag_get(skb)); tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_VLAN_TAG; vlan_off += 4; } else +#endif tx_bd->vlan = cpu_to_le16(pkt_prod); if (xmit_type) { @@ -10017,6 +10030,16 @@ static void bnx2x_vlan_rx_register(struct net_device *dev, struct bnx2x *bp = netdev_priv(dev); bp->vlgrp = vlgrp; + + /* Set flags according to the required capabilities */ + bp->flags &= ~(HW_VLAN_RX_FLAG | HW_VLAN_TX_FLAG); + + if (dev->features & NETIF_F_HW_VLAN_TX) + bp->flags |= HW_VLAN_TX_FLAG; + + if (dev->features & NETIF_F_HW_VLAN_RX) + bp->flags |= HW_VLAN_RX_FLAG; + if (netif_running(dev)) bnx2x_set_client_config(bp); } @@ -10173,6 +10196,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, dev->features |= NETIF_F_HIGHDMA; #ifdef BCM_VLAN dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX); + bp->flags |= (HW_VLAN_RX_FLAG | HW_VLAN_TX_FLAG); #endif dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN); dev->features |= NETIF_F_TSO6; -- cgit From 68d5948436c2f782ebb5ddf25a6588ee452e8c30 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:27:36 -0800 Subject: bnx2x: Endianness issues Adding missing le_to_cpu and disabling wrong HW endianity flag (the two complete each other) Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index ca8b25126b2..d2350dd300b 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -1438,7 +1438,7 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) DP(NETIF_MSG_RX_STATUS, "CQE type %x err %x status %x" " queue %x vlan %x len %u\n", CQE_TYPE(cqe_fp_flags), cqe_fp_flags, cqe->fast_path_cqe.status_flags, - cqe->fast_path_cqe.rss_hash_result, + le32_to_cpu(cqe->fast_path_cqe.rss_hash_result), le16_to_cpu(cqe->fast_path_cqe.vlan_tag), le16_to_cpu(cqe->fast_path_cqe.pkt_len)); @@ -2821,8 +2821,10 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) static void bnx2x_attn_int(struct bnx2x *bp) { /* read local copy of bits */ - u32 attn_bits = bp->def_status_blk->atten_status_block.attn_bits; - u32 attn_ack = bp->def_status_blk->atten_status_block.attn_bits_ack; + u32 attn_bits = le32_to_cpu(bp->def_status_blk->atten_status_block. + attn_bits); + u32 attn_ack = le32_to_cpu(bp->def_status_blk->atten_status_block. + attn_bits_ack); u32 attn_state = bp->attn_state; /* look for changed bits */ @@ -2870,7 +2872,7 @@ static void bnx2x_sp_task(struct work_struct *work) if (status & 0x2) bp->stats_pending = 0; - bnx2x_ack_sb(bp, DEF_SB_ID, ATTENTION_ID, bp->def_att_idx, + bnx2x_ack_sb(bp, DEF_SB_ID, ATTENTION_ID, le16_to_cpu(bp->def_att_idx), IGU_INT_NOP, 1); bnx2x_ack_sb(bp, DEF_SB_ID, USTORM_ID, le16_to_cpu(bp->def_u_idx), IGU_INT_NOP, 1); @@ -5161,7 +5163,6 @@ static int bnx2x_init_common(struct bnx2x *bp) REG_WR(bp, PXP2_REG_RQ_SRC_ENDIAN_M, 1); REG_WR(bp, PXP2_REG_RQ_CDU_ENDIAN_M, 1); REG_WR(bp, PXP2_REG_RQ_DBG_ENDIAN_M, 1); - REG_WR(bp, PXP2_REG_RQ_HC_ENDIAN_M, 1); /* REG_WR(bp, PXP2_REG_RD_PBF_SWAP_MODE, 1); */ REG_WR(bp, PXP2_REG_RD_QM_SWAP_MODE, 1); -- cgit From a5f67a04d998b0b6e4beb1de8f1247dd93ac1ff4 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:28:13 -0800 Subject: bnx2x: Fixing the doorbell size The size of the doorbell is 4KB, this bug become visible when using more than 8 queues Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index e7fbca7722d..6fcccef4cf3 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h @@ -739,7 +739,7 @@ struct bnx2x { struct bnx2x_fastpath fp[MAX_CONTEXT]; void __iomem *regview; void __iomem *doorbells; -#define BNX2X_DB_SIZE (16*2048) +#define BNX2X_DB_SIZE (16*BCM_PAGE_SIZE) struct net_device *dev; struct pci_dev *pdev; -- cgit From f5ba6772f226be0266f95642c8162493246d3b79 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:29:18 -0800 Subject: bnx2x: Missing brackets Calculation bug due to missing brackets Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index d2350dd300b..a755fea996d 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -2920,7 +2920,7 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) #define ADD_64(s_hi, a_hi, s_lo, a_lo) \ do { \ s_lo += a_lo; \ - s_hi += a_hi + (s_lo < a_lo) ? 1 : 0; \ + s_hi += a_hi + ((s_lo < a_lo) ? 1 : 0); \ } while (0) /* difference = minuend - subtrahend */ -- cgit From 26c8fa4d8a08b6e7a61f23339e2236218957ecc0 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:29:55 -0800 Subject: bnx2x: Indirection table initialization index Wrong initialization of the multi-queue indirection table - it should be using the function and not the port index Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index a755fea996d..9e6aa8a1ee9 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -4524,7 +4524,7 @@ static void bnx2x_init_context(struct bnx2x *bp) static void bnx2x_init_ind_table(struct bnx2x *bp) { - int port = BP_PORT(bp); + int func = BP_FUNC(bp); int i; if (!is_multi(bp)) @@ -4533,10 +4533,8 @@ static void bnx2x_init_ind_table(struct bnx2x *bp) DP(NETIF_MSG_IFUP, "Initializing indirection table\n"); for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++) REG_WR8(bp, BAR_TSTRORM_INTMEM + - TSTORM_INDIRECTION_TABLE_OFFSET(port) + i, - i % bp->num_queues); - - REG_WR(bp, PRS_REG_A_PRSU_20, 0xf); + TSTORM_INDIRECTION_TABLE_OFFSET(func) + i, + BP_CL_ID(bp) + (i % bp->num_queues)); } static void bnx2x_set_client_config(struct bnx2x *bp) @@ -5240,6 +5238,7 @@ static int bnx2x_init_common(struct bnx2x *bp) } bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END); + REG_WR(bp, PRS_REG_A_PRSU_20, 0xf); /* set NIC mode */ REG_WR(bp, PRS_REG_NIC_MODE, 1); if (CHIP_IS_E1H(bp)) -- cgit From e7799c5f79072b5b34cf08170f142bcb8569cfff Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:30:27 -0800 Subject: bnx2x: MTU Filter Too big packets could pass due to wrong filter size Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 9e6aa8a1ee9..b573951600d 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -4543,7 +4543,7 @@ static void bnx2x_set_client_config(struct bnx2x *bp) int port = BP_PORT(bp); int i; - tstorm_client.mtu = bp->dev->mtu + ETH_OVREHEAD; + tstorm_client.mtu = bp->dev->mtu; tstorm_client.statistics_counter_id = BP_CL_ID(bp); tstorm_client.config_flags = TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE; -- cgit From 0ef00459a638ae4f5d1e5326d3e50232fa80119f Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 21:31:08 -0800 Subject: bnx2x: First slow path interrupt race The "read for interrupts" flag must be set before enabling slow-path interrupts as well (and not just before fast-path interrupts) Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index b573951600d..7c533797c06 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -4812,6 +4812,15 @@ static void bnx2x_nic_init(struct bnx2x *bp, u32 load_code) bnx2x_init_context(bp); bnx2x_init_internal(bp, load_code); bnx2x_init_ind_table(bp); + bnx2x_stats_init(bp); + + /* At this point, we are ready for interrupts */ + atomic_set(&bp->intr_sem, 0); + + /* flush all before enabling interrupts */ + mb(); + mmiowb(); + bnx2x_int_enable(bp); } @@ -6420,17 +6429,8 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) } } - bnx2x_stats_init(bp); - bp->state = BNX2X_STATE_OPENING_WAIT4_PORT; - /* Enable Rx interrupt handling before sending the ramrod - as it's completed on Rx FP queue */ - bnx2x_napi_enable(bp); - - /* Enable interrupt handling */ - atomic_set(&bp->intr_sem, 0); - rc = bnx2x_setup_leading(bp); if (rc) { BNX2X_ERR("Setup leading failed!\n"); -- cgit From b96ecfa689126d1e652ebd758da0b5b9b27dbd12 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 14 Jan 2009 21:46:51 -0800 Subject: korina: fix usage of driver_data Using platform_set_drvdata() here makes no sense, since the driver_data field has already been filled with valuable data (i.e. the MAC address). Also having driver_data point to the net_device is rather pointless since struct korina_device contains an apropriate field for it. Signed-off-by: Phil Sutter Signed-off-by: David S. Miller --- drivers/net/korina.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/korina.c b/drivers/net/korina.c index 4a5580c1126..fefb33db79a 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -1089,7 +1089,6 @@ static int korina_probe(struct platform_device *pdev) return -ENOMEM; } SET_NETDEV_DEV(dev, &pdev->dev); - platform_set_drvdata(pdev, dev); lp = netdev_priv(dev); bif->dev = dev; -- cgit From a13b27826a67bfc0ca444fb42885f2069b6898e2 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 14 Jan 2009 21:47:50 -0800 Subject: korina: reset resource buffer size to 1536 The new value is the one used in the external patch before and allows at least a standard MTU of 1500 to be handled correctly. Impact of this change gets visible when bigger packets are to be received, issuing: | ping -s 492 and bigger payload sized led to 100% packet loss. Signed-off-by: Phil Sutter Acked-by: Florian Fainelli --- drivers/net/korina.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/korina.c b/drivers/net/korina.c index fefb33db79a..e30c2f437d1 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -84,7 +84,10 @@ #define KORINA_NUM_RDS 64 /* number of receive descriptors */ #define KORINA_NUM_TDS 64 /* number of transmit descriptors */ -#define KORINA_RBSIZE 536 /* size of one resource buffer = Ether MTU */ +/* KORINA_RBSIZE is the hardware's default maximum receive + * frame size in bytes. Having this hardcoded means that there + * is no support for MTU sizes greater than 1500. */ +#define KORINA_RBSIZE 1536 /* size of one resource buffer = Ether MTU */ #define KORINA_RDS_MASK (KORINA_NUM_RDS - 1) #define KORINA_TDS_MASK (KORINA_NUM_TDS - 1) #define RD_RING_SIZE (KORINA_NUM_RDS * sizeof(struct dma_desc)) -- cgit From beb0babfb77eab0cbcc7f64a7b8f3545fec5c0ba Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 14 Jan 2009 21:48:24 -0800 Subject: korina: disable napi on close and restart Without this the driver will crash when the NIC is being restarted. Signed-off-by: Phil Sutter Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/korina.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/korina.c b/drivers/net/korina.c index e30c2f437d1..65b8487c189 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -904,6 +904,8 @@ static int korina_restart(struct net_device *dev) korina_free_ring(dev); + napi_disable(&lp->napi); + ret = korina_init(dev); if (ret < 0) { printk(KERN_ERR DRV_NAME "%s: cannot restart device\n", @@ -1070,6 +1072,8 @@ static int korina_close(struct net_device *dev) korina_free_ring(dev); + napi_disable(&lp->napi); + free_irq(lp->rx_irq, dev); free_irq(lp->tx_irq, dev); free_irq(lp->ovr_irq, dev); -- cgit From 4cf83b664fc14f8262d3013566ca36645f891df2 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 14 Jan 2009 21:48:59 -0800 Subject: korina: rework korina_rx() for use with napi This function needs an early exit condition to function properly, or else caller assumes napi workload wasn't enough to handle all received packets and korina_rx is called again (and again and again and ...). Signed-off-by: Phil Sutter Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/korina.c | 109 +++++++++++++++++++++++++-------------------------- 1 file changed, 53 insertions(+), 56 deletions(-) diff --git a/drivers/net/korina.c b/drivers/net/korina.c index 65b8487c189..a1d8af7d0bc 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -353,15 +353,20 @@ static int korina_rx(struct net_device *dev, int limit) struct dma_desc *rd = &lp->rd_ring[lp->rx_next_done]; struct sk_buff *skb, *skb_new; u8 *pkt_buf; - u32 devcs, pkt_len, dmas, rx_free_desc; + u32 devcs, pkt_len, dmas; int count; dma_cache_inv((u32)rd, sizeof(*rd)); for (count = 0; count < limit; count++) { + skb = lp->rx_skb[lp->rx_next_done]; + skb_new = NULL; devcs = rd->devcs; + if ((KORINA_RBSIZE - (u32)DMA_COUNT(rd->control)) == 0) + break; + /* Update statistics counters */ if (devcs & ETH_RX_CRC) dev->stats.rx_crc_errors++; @@ -384,63 +389,55 @@ static int korina_rx(struct net_device *dev, int limit) * in Rc32434 (errata ref #077) */ dev->stats.rx_errors++; dev->stats.rx_dropped++; - } - - while ((rx_free_desc = KORINA_RBSIZE - (u32)DMA_COUNT(rd->control)) != 0) { - /* init the var. used for the later - * operations within the while loop */ - skb_new = NULL; + } else if ((devcs & ETH_RX_ROK)) { pkt_len = RCVPKT_LENGTH(devcs); - skb = lp->rx_skb[lp->rx_next_done]; - - if ((devcs & ETH_RX_ROK)) { - /* must be the (first and) last - * descriptor then */ - pkt_buf = (u8 *)lp->rx_skb[lp->rx_next_done]->data; - - /* invalidate the cache */ - dma_cache_inv((unsigned long)pkt_buf, pkt_len - 4); - - /* Malloc up new buffer. */ - skb_new = netdev_alloc_skb(dev, KORINA_RBSIZE + 2); - - if (!skb_new) - break; - /* Do not count the CRC */ - skb_put(skb, pkt_len - 4); - skb->protocol = eth_type_trans(skb, dev); - - /* Pass the packet to upper layers */ - netif_receive_skb(skb); - dev->stats.rx_packets++; - dev->stats.rx_bytes += pkt_len; - - /* Update the mcast stats */ - if (devcs & ETH_RX_MP) - dev->stats.multicast++; - - lp->rx_skb[lp->rx_next_done] = skb_new; - } - - rd->devcs = 0; - - /* Restore descriptor's curr_addr */ - if (skb_new) - rd->ca = CPHYSADDR(skb_new->data); - else - rd->ca = CPHYSADDR(skb->data); - - rd->control = DMA_COUNT(KORINA_RBSIZE) | - DMA_DESC_COD | DMA_DESC_IOD; - lp->rd_ring[(lp->rx_next_done - 1) & - KORINA_RDS_MASK].control &= - ~DMA_DESC_COD; - - lp->rx_next_done = (lp->rx_next_done + 1) & KORINA_RDS_MASK; - dma_cache_wback((u32)rd, sizeof(*rd)); - rd = &lp->rd_ring[lp->rx_next_done]; - writel(~DMA_STAT_DONE, &lp->rx_dma_regs->dmas); + + /* must be the (first and) last + * descriptor then */ + pkt_buf = (u8 *)lp->rx_skb[lp->rx_next_done]->data; + + /* invalidate the cache */ + dma_cache_inv((unsigned long)pkt_buf, pkt_len - 4); + + /* Malloc up new buffer. */ + skb_new = netdev_alloc_skb(dev, KORINA_RBSIZE + 2); + + if (!skb_new) + break; + /* Do not count the CRC */ + skb_put(skb, pkt_len - 4); + skb->protocol = eth_type_trans(skb, dev); + + /* Pass the packet to upper layers */ + netif_receive_skb(skb); + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; + + /* Update the mcast stats */ + if (devcs & ETH_RX_MP) + dev->stats.multicast++; + + lp->rx_skb[lp->rx_next_done] = skb_new; } + + rd->devcs = 0; + + /* Restore descriptor's curr_addr */ + if (skb_new) + rd->ca = CPHYSADDR(skb_new->data); + else + rd->ca = CPHYSADDR(skb->data); + + rd->control = DMA_COUNT(KORINA_RBSIZE) | + DMA_DESC_COD | DMA_DESC_IOD; + lp->rd_ring[(lp->rx_next_done - 1) & + KORINA_RDS_MASK].control &= + ~DMA_DESC_COD; + + lp->rx_next_done = (lp->rx_next_done + 1) & KORINA_RDS_MASK; + dma_cache_wback((u32)rd, sizeof(*rd)); + rd = &lp->rd_ring[lp->rx_next_done]; + writel(~DMA_STAT_DONE, &lp->rx_dma_regs->dmas); } dmas = readl(&lp->rx_dma_regs->dmas); -- cgit From 4676f63d4c1e2e3530e42cb39bf88a1c1d4d78a5 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 14 Jan 2009 21:49:39 -0800 Subject: korina: do schedule napi after testing for it The called netif_rx_schedule() does all the work for us: - it checks the return value of netif_rx_schedule_prep() and - if everything is ok calls __netif_rx_schedule(). Before this change, the driver received absolutely nothing. Signed-off-by: Phil Sutter Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/korina.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/korina.c b/drivers/net/korina.c index a1d8af7d0bc..7aa05f81fe9 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -330,7 +330,7 @@ static irqreturn_t korina_rx_dma_interrupt(int irq, void *dev_id) dmas = readl(&lp->rx_dma_regs->dmas); if (dmas & (DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR)) { - netif_rx_schedule_prep(&lp->napi); + netif_rx_schedule(&lp->napi); dmasm = readl(&lp->rx_dma_regs->dmasm); writel(dmasm | (DMA_STAT_DONE | -- cgit From 60d3f9827ca455e7272681d67a37137c328d7012 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 14 Jan 2009 21:50:12 -0800 Subject: korina: do tx at the right position Triggering TX before the write to the DMA status mask register leads to transferring packets with maximum payload no matter what the actual packet size is. While here, also trigger RX scheduling after writing the DMA status mask register, like it was in the original driver before it was sent upstream. Signed-off-by: Phil Sutter Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/korina.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/korina.c b/drivers/net/korina.c index 7aa05f81fe9..dced5e71463 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -330,13 +330,13 @@ static irqreturn_t korina_rx_dma_interrupt(int irq, void *dev_id) dmas = readl(&lp->rx_dma_regs->dmas); if (dmas & (DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR)) { - netif_rx_schedule(&lp->napi); - dmasm = readl(&lp->rx_dma_regs->dmasm); writel(dmasm | (DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR), &lp->rx_dma_regs->dmasm); + netif_rx_schedule(&lp->napi); + if (dmas & DMA_STAT_ERR) printk(KERN_ERR DRV_NAME "%s: DMA error\n", dev->name); @@ -623,12 +623,12 @@ korina_tx_dma_interrupt(int irq, void *dev_id) dmas = readl(&lp->tx_dma_regs->dmas); if (dmas & (DMA_STAT_FINI | DMA_STAT_ERR)) { - korina_tx(dev); - dmasm = readl(&lp->tx_dma_regs->dmasm); writel(dmasm | (DMA_STAT_FINI | DMA_STAT_ERR), &lp->tx_dma_regs->dmasm); + korina_tx(dev); + if (lp->tx_chain_status == desc_filled && (readl(&(lp->tx_dma_regs->dmandptr)) == 0)) { writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]), -- cgit From 97bc477cbc3d63f2a29c2c81031434b3a082f44c Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 14 Jan 2009 21:50:41 -0800 Subject: korina: fix handling tx_chain_tail Originally this must have been a rewrite error when introducing 'chain_index'. But the original driver did not use the previous chain item everywhere: when altering the address tx_chain_tail points to, it should move forward, not backwards. Also this is not an "index" but rather the penultimate element in the chain, so rename it accordingly. Signed-off-by: Phil Sutter Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/korina.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/net/korina.c b/drivers/net/korina.c index dced5e71463..f2001750251 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -199,7 +199,7 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev) struct korina_private *lp = netdev_priv(dev); unsigned long flags; u32 length; - u32 chain_index; + u32 chain_prev, chain_next; struct dma_desc *td; spin_lock_irqsave(&lp->lock, flags); @@ -231,8 +231,8 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev) /* Setup the transmit descriptor. */ dma_cache_inv((u32) td, sizeof(*td)); td->ca = CPHYSADDR(skb->data); - chain_index = (lp->tx_chain_tail - 1) & - KORINA_TDS_MASK; + chain_prev = (lp->tx_chain_tail - 1) & KORINA_TDS_MASK; + chain_next = (lp->tx_chain_tail + 1) & KORINA_TDS_MASK; if (readl(&(lp->tx_dma_regs->dmandptr)) == 0) { if (lp->tx_chain_status == desc_empty) { @@ -240,7 +240,7 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev) td->control = DMA_COUNT(length) | DMA_DESC_COF | DMA_DESC_IOF; /* Move tail */ - lp->tx_chain_tail = chain_index; + lp->tx_chain_tail = chain_next; /* Write to NDPTR */ writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]), &lp->tx_dma_regs->dmandptr); @@ -251,12 +251,12 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev) td->control = DMA_COUNT(length) | DMA_DESC_COF | DMA_DESC_IOF; /* Link to prev */ - lp->td_ring[chain_index].control &= + lp->td_ring[chain_prev].control &= ~DMA_DESC_COF; /* Link to prev */ - lp->td_ring[chain_index].link = CPHYSADDR(td); + lp->td_ring[chain_prev].link = CPHYSADDR(td); /* Move tail */ - lp->tx_chain_tail = chain_index; + lp->tx_chain_tail = chain_next; /* Write to NDPTR */ writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]), &(lp->tx_dma_regs->dmandptr)); @@ -270,17 +270,17 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev) td->control = DMA_COUNT(length) | DMA_DESC_COF | DMA_DESC_IOF; /* Move tail */ - lp->tx_chain_tail = chain_index; + lp->tx_chain_tail = chain_next; lp->tx_chain_status = desc_filled; netif_stop_queue(dev); } else { /* Update tail */ td->control = DMA_COUNT(length) | DMA_DESC_COF | DMA_DESC_IOF; - lp->td_ring[chain_index].control &= + lp->td_ring[chain_prev].control &= ~DMA_DESC_COF; - lp->td_ring[chain_index].link = CPHYSADDR(td); - lp->tx_chain_tail = chain_index; + lp->td_ring[chain_prev].link = CPHYSADDR(td); + lp->tx_chain_tail = chain_next; } } dma_cache_wback((u32) td, sizeof(*td)); -- cgit From 5edc7668bbece4238a32943ae7a47135af076948 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 14 Jan 2009 21:51:15 -0800 Subject: korina: do not stop queue here Apparently this doesn't make sense. Otherwise the queue gets disabled as soon as it's getting empty and can only be resurrected by a driver restart. Signed-off-by: Phil Sutter Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/korina.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/korina.c b/drivers/net/korina.c index f2001750251..bd33fa91599 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -272,7 +272,6 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev) /* Move tail */ lp->tx_chain_tail = chain_next; lp->tx_chain_status = desc_filled; - netif_stop_queue(dev); } else { /* Update tail */ td->control = DMA_COUNT(length) | -- cgit From 1c5625cf0f121486abad4da0e0251ec67765aa95 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 14 Jan 2009 21:51:48 -0800 Subject: korina: do not use IRQF_SHARED with IRQF_DISABLED As the kernel warning states: "IRQF_DISABLED is not guaranteed on shared IRQs". Since these IRQs' values are hardcoded and my test system doesn't show any shared use of IRQs at all, rather make them non-shared than non-disabled. Signed-off-by: Phil Sutter Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/korina.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/korina.c b/drivers/net/korina.c index bd33fa91599..1d6e48e1336 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -1000,14 +1000,14 @@ static int korina_open(struct net_device *dev) * that handles the Done Finished * Ovr and Und Events */ ret = request_irq(lp->rx_irq, &korina_rx_dma_interrupt, - IRQF_SHARED | IRQF_DISABLED, "Korina ethernet Rx", dev); + IRQF_DISABLED, "Korina ethernet Rx", dev); if (ret < 0) { printk(KERN_ERR DRV_NAME "%s: unable to get Rx DMA IRQ %d\n", dev->name, lp->rx_irq); goto err_release; } ret = request_irq(lp->tx_irq, &korina_tx_dma_interrupt, - IRQF_SHARED | IRQF_DISABLED, "Korina ethernet Tx", dev); + IRQF_DISABLED, "Korina ethernet Tx", dev); if (ret < 0) { printk(KERN_ERR DRV_NAME "%s: unable to get Tx DMA IRQ %d\n", dev->name, lp->tx_irq); @@ -1016,7 +1016,7 @@ static int korina_open(struct net_device *dev) /* Install handler for overrun error. */ ret = request_irq(lp->ovr_irq, &korina_ovr_interrupt, - IRQF_SHARED | IRQF_DISABLED, "Ethernet Overflow", dev); + IRQF_DISABLED, "Ethernet Overflow", dev); if (ret < 0) { printk(KERN_ERR DRV_NAME"%s: unable to get OVR IRQ %d\n", dev->name, lp->ovr_irq); @@ -1025,7 +1025,7 @@ static int korina_open(struct net_device *dev) /* Install handler for underflow error. */ ret = request_irq(lp->und_irq, &korina_und_interrupt, - IRQF_SHARED | IRQF_DISABLED, "Ethernet Underflow", dev); + IRQF_DISABLED, "Ethernet Underflow", dev); if (ret < 0) { printk(KERN_ERR DRV_NAME "%s: unable to get UND IRQ %d\n", dev->name, lp->und_irq); -- cgit From c9280d681c4093405fc896dc25f81d5ff9de8183 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 15 Jan 2009 17:31:00 +0100 Subject: ALSA: hda - Fix (yet more) STAC925x issues The codec-parsing of STAC925x was utterly broken due to its unique design unlike other STAC codecs. It has a volume control only in NID 0x0e (similar as STAC9200), but the parser assumes that the amp is available on each DAC widget. The patch fixes the whole wrong stories: fix the initial volume, assign the fixed "Master" volume, and avoid to create wrong volume controls. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index c39deebb588..faef1ca8660 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -885,8 +885,8 @@ static struct hda_verb stac92hd71bxx_analog_core_init[] = { static struct hda_verb stac925x_core_init[] = { /* set dac0mux for dac converter */ { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* unmute and set max the selector */ - { 0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f }, + /* mute the master volume */ + { 0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, {} }; @@ -1138,6 +1138,8 @@ static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { }; static struct snd_kcontrol_new stac925x_mixer[] = { + HDA_CODEC_VOLUME("Master Playback Volume", 0x0e, 0, HDA_OUTPUT), + HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), STAC_INPUT_SOURCE(1), HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT), @@ -3573,13 +3575,12 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out err = stac92xx_auto_fill_dac_nids(codec); if (err < 0) return err; + err = stac92xx_auto_create_multi_out_ctls(codec, + &spec->autocfg); + if (err < 0) + return err; } - err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg); - - if (err < 0) - return err; - /* setup analog beep controls */ if (spec->anabeep_nid > 0) { err = stac92xx_auto_create_beep_ctls(codec, -- cgit From 7a0b6e01434f77194b86c8051b4c3718da636c64 Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Thu, 15 Jan 2009 15:16:55 +0900 Subject: [IA64] Update to use account_{steal,idle}_ticks This patch fixes the following errors caused by 79741dd35713ff4f6fd0eafd59fa94e8a4ba922d which changed the prototypes of account_steal_time() and account_idle_time(). > CC arch/ia64/xen/time.o > arch/ia64/xen/time.c: In function 'consider_steal_time': > arch/ia64/xen/time.c:132: warning: passing argument 1 of 'account_steal_time' makes integer from pointer without a cast > arch/ia64/xen/time.c:132: error: too many arguments to function 'account_steal_time' > arch/ia64/xen/time.c:133: warning: passing argument 1 of 'account_steal_time' makes integer from pointer without a cast > arch/ia64/xen/time.c:133: error: too many arguments to function 'account_steal_time' Cc: Martin Schwidefsky Signed-off-by: Isaku Yamahata Signed-off-by: Tony Luck --- arch/ia64/xen/time.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/ia64/xen/time.c b/arch/ia64/xen/time.c index d15a94c330f..68d6204c3f1 100644 --- a/arch/ia64/xen/time.c +++ b/arch/ia64/xen/time.c @@ -129,8 +129,8 @@ consider_steal_time(unsigned long new_itm) blocked = stolentick; if (stolen > 0 || blocked > 0) { - account_steal_time(NULL, jiffies_to_cputime(stolen)); - account_steal_time(idle_task(cpu), jiffies_to_cputime(blocked)); + account_steal_ticks(stolen); + account_idle_ticks(blocked); run_local_timers(); if (rcu_pending(cpu)) -- cgit From 9abf0eea877d6107d3a8a5c6913450e961fb7050 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 11 Jan 2009 03:00:58 -0200 Subject: ACPI: thinkpad-acpi: update documents for the new location Update documentation to reflect the new location of the thinkpad-acpi driver. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- Documentation/laptops/thinkpad-acpi.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt index 898b4987bb8..ddc371e0a1a 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt @@ -16,7 +16,8 @@ supported by the generic Linux ACPI drivers. This driver used to be named ibm-acpi until kernel 2.6.21 and release 0.13-20070314. It used to be in the drivers/acpi tree, but it was moved to the drivers/misc tree and renamed to thinkpad-acpi for kernel -2.6.22, and release 0.14. +2.6.22, and release 0.14. It was moved to drivers/platform/x86 for +kernel 2.6.29. The driver is named "thinkpad-acpi". In some places, like module names, "thinkpad_acpi" is used because of userspace issues. -- cgit From e0b36fc5efd610a208b6b80e821a49302ca424ab Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 11 Jan 2009 03:00:59 -0200 Subject: ACPI: thinkpad-acpi: struct device - replace bus_id with dev_name(), dev_set_name() Signed-off-by: Kay Sievers Acked-by: Greg Kroah-Hartman Acked-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- drivers/platform/x86/thinkpad_acpi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 3478453eba7..ee3fa007f31 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -2375,7 +2375,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) /* forward it to userspace, maybe it knows how to handle it */ acpi_bus_generate_netlink_event( ibm->acpi->device->pnp.device_class, - ibm->acpi->device->dev.bus_id, + dev_name(&ibm->acpi->device->dev), event, 0); return; } @@ -2505,7 +2505,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) if (!ignore_acpi_ev && send_acpi_ev) { acpi_bus_generate_netlink_event( ibm->acpi->device->pnp.device_class, - ibm->acpi->device->dev.bus_id, + dev_name(&ibm->acpi->device->dev), event, hkey); } } @@ -3724,7 +3724,7 @@ static void dock_notify(struct ibm_struct *ibm, u32 event) } acpi_bus_generate_proc_event(ibm->acpi->device, event, data); acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, - ibm->acpi->device->dev.bus_id, + dev_name(&ibm->acpi->device->dev), event, data); } @@ -3826,7 +3826,7 @@ static void bay_notify(struct ibm_struct *ibm, u32 event) { acpi_bus_generate_proc_event(ibm->acpi->device, event, 0); acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, - ibm->acpi->device->dev.bus_id, + dev_name(&ibm->acpi->device->dev), event, 0); } -- cgit From 0773a6cf673316440999752e23f8c3d4f85e48b9 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Thu, 15 Jan 2009 10:29:17 -0800 Subject: [IA64] Turn on CONFIG_HAVE_UNSTABLE_CLOCK sched_clock() on ia64 is based on ar.itc, so is never completely synchronized between cpus. On some platforms (e.g. certain models of SGI Altix) it may be running at radically different frequencies. Based on a patch from Dimitri Sivanich which set this just for SN2 && GENERIC kernels ... it is needed for all ia64 machines. Signed-off-by: Tony Luck --- arch/ia64/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 3d31636cbaf..6183aeccecf 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -17,6 +17,7 @@ config IA64 select ACPI if (!IA64_HP_SIM) select PM if (!IA64_HP_SIM) select ARCH_SUPPORTS_MSI + select HAVE_UNSTABLE_SCHED_CLOCK select HAVE_IDE select HAVE_OPROFILE select HAVE_KPROBES -- cgit From a73f30916ee524437253739eacc682f6fb0f3ea8 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 11 Jan 2009 03:01:00 -0200 Subject: ACPI: thinkpad-acpi: debug facility to emulate the rf switches This code is required to keep the thinkpad-acpi maintainer sane, and it is disabled by default. Add a debug facility to simulate an rfkill hardware rocker switch, a bluetooth rfkill soft-switch, a WWAN rfkill soft-switch on thinkpads. The simulated switches obviously do not kill any radios in hardware or firmware (unlike the real one). They also don't issue deprecated proc events. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- drivers/platform/x86/Kconfig | 11 ++ drivers/platform/x86/thinkpad_acpi.c | 190 +++++++++++++++++++++++++++++++++++ 2 files changed, 201 insertions(+) diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index e65448e99b4..431772b8a1d 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -192,6 +192,17 @@ config THINKPAD_ACPI If you have an IBM or Lenovo ThinkPad laptop, say Y or M here. +config THINKPAD_ACPI_DEBUGFACILITIES + bool "Maintainer debug facilities" + depends on THINKPAD_ACPI + default n + ---help--- + Enables extra stuff in the thinkpad-acpi which is completely useless + for normal use. Read the driver source to find out what it does. + + Say N here, unless you were told by a kernel maintainer to do + otherwise. + config THINKPAD_ACPI_DEBUG bool "Verbose debug mode" depends on THINKPAD_ACPI diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index ee3fa007f31..a086ce8ed4e 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -288,6 +288,16 @@ struct tpacpi_led_classdev { unsigned int led; }; +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES +static int dbg_wlswemul; +static int tpacpi_wlsw_emulstate; +static int dbg_bluetoothemul; +static int tpacpi_bluetooth_emulstate; +static int dbg_wwanemul; +static int tpacpi_wwan_emulstate; +#endif + + /**************************************************************************** **************************************************************************** * @@ -1006,6 +1016,94 @@ static DRIVER_ATTR(version, S_IRUGO, /* --------------------------------------------------------------------- */ +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES + +static void tpacpi_send_radiosw_update(void); + +/* wlsw_emulstate ------------------------------------------------------ */ +static ssize_t tpacpi_driver_wlsw_emulstate_show(struct device_driver *drv, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_wlsw_emulstate); +} + +static ssize_t tpacpi_driver_wlsw_emulstate_store(struct device_driver *drv, + const char *buf, size_t count) +{ + unsigned long t; + + if (parse_strtoul(buf, 1, &t)) + return -EINVAL; + + if (tpacpi_wlsw_emulstate != t) { + tpacpi_wlsw_emulstate = !!t; + tpacpi_send_radiosw_update(); + } else + tpacpi_wlsw_emulstate = !!t; + + return count; +} + +static DRIVER_ATTR(wlsw_emulstate, S_IWUSR | S_IRUGO, + tpacpi_driver_wlsw_emulstate_show, + tpacpi_driver_wlsw_emulstate_store); + +/* bluetooth_emulstate ------------------------------------------------- */ +static ssize_t tpacpi_driver_bluetooth_emulstate_show( + struct device_driver *drv, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_bluetooth_emulstate); +} + +static ssize_t tpacpi_driver_bluetooth_emulstate_store( + struct device_driver *drv, + const char *buf, size_t count) +{ + unsigned long t; + + if (parse_strtoul(buf, 1, &t)) + return -EINVAL; + + tpacpi_bluetooth_emulstate = !!t; + + return count; +} + +static DRIVER_ATTR(bluetooth_emulstate, S_IWUSR | S_IRUGO, + tpacpi_driver_bluetooth_emulstate_show, + tpacpi_driver_bluetooth_emulstate_store); + +/* wwan_emulstate ------------------------------------------------- */ +static ssize_t tpacpi_driver_wwan_emulstate_show( + struct device_driver *drv, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_wwan_emulstate); +} + +static ssize_t tpacpi_driver_wwan_emulstate_store( + struct device_driver *drv, + const char *buf, size_t count) +{ + unsigned long t; + + if (parse_strtoul(buf, 1, &t)) + return -EINVAL; + + tpacpi_wwan_emulstate = !!t; + + return count; +} + +static DRIVER_ATTR(wwan_emulstate, S_IWUSR | S_IRUGO, + tpacpi_driver_wwan_emulstate_show, + tpacpi_driver_wwan_emulstate_store); + +#endif + +/* --------------------------------------------------------------------- */ + static struct driver_attribute *tpacpi_driver_attributes[] = { &driver_attr_debug_level, &driver_attr_version, &driver_attr_interface_version, @@ -1022,6 +1120,15 @@ static int __init tpacpi_create_driver_attributes(struct device_driver *drv) i++; } +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES + if (!res && dbg_wlswemul) + res = driver_create_file(drv, &driver_attr_wlsw_emulstate); + if (!res && dbg_bluetoothemul) + res = driver_create_file(drv, &driver_attr_bluetooth_emulstate); + if (!res && dbg_wwanemul) + res = driver_create_file(drv, &driver_attr_wwan_emulstate); +#endif + return res; } @@ -1031,6 +1138,12 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv) for (i = 0; i < ARRAY_SIZE(tpacpi_driver_attributes); i++) driver_remove_file(drv, tpacpi_driver_attributes[i]); + +#ifdef THINKPAD_ACPI_DEBUGFACILITIES + driver_remove_file(drv, &driver_attr_wlsw_emulstate); + driver_remove_file(drv, &driver_attr_bluetooth_emulstate); + driver_remove_file(drv, &driver_attr_wwan_emulstate); +#endif } /**************************************************************************** @@ -1216,6 +1329,12 @@ static struct attribute_set *hotkey_dev_attributes; static int hotkey_get_wlsw(int *status) { +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES + if (dbg_wlswemul) { + *status = !!tpacpi_wlsw_emulstate; + return 0; + } +#endif if (!acpi_evalf(hkey_handle, status, "WLSW", "d")) return -EIO; return 0; @@ -2222,6 +2341,13 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) hotkey_source_mask, hotkey_poll_freq); #endif +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES + if (dbg_wlswemul) { + tp_features.hotkey_wlsw = 1; + printk(TPACPI_INFO + "radio switch emulation enabled\n"); + } else +#endif /* Not all thinkpads have a hardware radio switch */ if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) { tp_features.hotkey_wlsw = 1; @@ -2656,6 +2782,12 @@ static int bluetooth_get_radiosw(void) if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status) return RFKILL_STATE_HARD_BLOCKED; +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES + if (dbg_bluetoothemul) + return (tpacpi_bluetooth_emulstate) ? + RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; +#endif + if (!acpi_evalf(hkey_handle, &status, "GBDC", "d")) return -EIO; @@ -2689,6 +2821,15 @@ static int bluetooth_set_radiosw(int radio_on, int update_rfk) && radio_on) return -EPERM; +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES + if (dbg_bluetoothemul) { + tpacpi_bluetooth_emulstate = !!radio_on; + if (update_rfk) + bluetooth_update_rfk(); + return 0; + } +#endif + if (!acpi_evalf(hkey_handle, &status, "GBDC", "d")) return -EIO; if (radio_on) @@ -2792,6 +2933,13 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm) str_supported(tp_features.bluetooth), status); +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES + if (dbg_bluetoothemul) { + tp_features.bluetooth = 1; + printk(TPACPI_INFO + "bluetooth switch emulation enabled\n"); + } else +#endif if (tp_features.bluetooth && !(status & TP_ACPI_BLUETOOTH_HWPRESENT)) { /* no bluetooth hardware present in system */ @@ -2890,6 +3038,12 @@ static int wan_get_radiosw(void) if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status) return RFKILL_STATE_HARD_BLOCKED; +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES + if (dbg_wwanemul) + return (tpacpi_wwan_emulstate) ? + RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; +#endif + if (!acpi_evalf(hkey_handle, &status, "GWAN", "d")) return -EIO; @@ -2923,6 +3077,15 @@ static int wan_set_radiosw(int radio_on, int update_rfk) && radio_on) return -EPERM; +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES + if (dbg_wwanemul) { + tpacpi_wwan_emulstate = !!radio_on; + if (update_rfk) + wan_update_rfk(); + return 0; + } +#endif + if (!acpi_evalf(hkey_handle, &status, "GWAN", "d")) return -EIO; if (radio_on) @@ -3024,6 +3187,13 @@ static int __init wan_init(struct ibm_init_struct *iibm) str_supported(tp_features.wan), status); +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES + if (dbg_wwanemul) { + tp_features.wan = 1; + printk(TPACPI_INFO + "wwan switch emulation enabled\n"); + } else +#endif if (tp_features.wan && !(status & TP_ACPI_WANCARD_HWPRESENT)) { /* no wan hardware present in system */ @@ -6701,6 +6871,26 @@ TPACPI_PARAM(brightness); TPACPI_PARAM(volume); TPACPI_PARAM(fan); +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES +module_param(dbg_wlswemul, uint, 0); +MODULE_PARM_DESC(dbg_wlswemul, "Enables WLSW emulation"); +module_param_named(wlsw_state, tpacpi_wlsw_emulstate, bool, 0); +MODULE_PARM_DESC(wlsw_state, + "Initial state of the emulated WLSW switch"); + +module_param(dbg_bluetoothemul, uint, 0); +MODULE_PARM_DESC(dbg_bluetoothemul, "Enables bluetooth switch emulation"); +module_param_named(bluetooth_state, tpacpi_bluetooth_emulstate, bool, 0); +MODULE_PARM_DESC(bluetooth_state, + "Initial state of the emulated bluetooth switch"); + +module_param(dbg_wwanemul, uint, 0); +MODULE_PARM_DESC(dbg_wwanemul, "Enables WWAN switch emulation"); +module_param_named(wwan_state, tpacpi_wwan_emulstate, bool, 0); +MODULE_PARM_DESC(wwan_state, + "Initial state of the emulated WWAN switch"); +#endif + static void thinkpad_acpi_module_exit(void) { struct ibm_struct *ibm, *itmp; -- cgit From 153f82207c51193e4d6a7e6f0e3f9442eabeba1c Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 11 Jan 2009 03:01:01 -0200 Subject: ACPI: thinkpad-acpi: resume with radios disabled Instruct the firmware to not enable the radios when resuming. This is safer, and the rfkill core will take care to manually enable any radios that need to be enabled. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- drivers/platform/x86/thinkpad_acpi.c | 66 ++++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index a086ce8ed4e..b2c5913ff72 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -122,6 +122,27 @@ enum { #define TPACPI_HKEY_INPUT_PRODUCT 0x5054 /* "TP" */ #define TPACPI_HKEY_INPUT_VERSION 0x4101 +/* ACPI \WGSV commands */ +enum { + TP_ACPI_WGSV_GET_STATE = 0x01, /* Get state information */ + TP_ACPI_WGSV_PWR_ON_ON_RESUME = 0x02, /* Resume WWAN powered on */ + TP_ACPI_WGSV_PWR_OFF_ON_RESUME = 0x03, /* Resume WWAN powered off */ + TP_ACPI_WGSV_SAVE_STATE = 0x04, /* Save state for S4/S5 */ +}; + +/* TP_ACPI_WGSV_GET_STATE bits */ +enum { + TP_ACPI_WGSV_STATE_WWANEXIST = 0x0001, /* WWAN hw available */ + TP_ACPI_WGSV_STATE_WWANPWR = 0x0002, /* WWAN radio enabled */ + TP_ACPI_WGSV_STATE_WWANPWRRES = 0x0004, /* WWAN state at resume */ + TP_ACPI_WGSV_STATE_WWANBIOSOFF = 0x0008, /* WWAN disabled in BIOS */ + TP_ACPI_WGSV_STATE_BLTHEXIST = 0x0001, /* BLTH hw available */ + TP_ACPI_WGSV_STATE_BLTHPWR = 0x0002, /* BLTH radio enabled */ + TP_ACPI_WGSV_STATE_BLTHPWRRES = 0x0004, /* BLTH state at resume */ + TP_ACPI_WGSV_STATE_BLTHBIOSOFF = 0x0008, /* BLTH disabled in BIOS */ + TP_ACPI_WGSV_STATE_UWBEXIST = 0x0010, /* UWB hw available */ + TP_ACPI_WGSV_STATE_UWBPWR = 0x0020, /* UWB radio enabled */ +}; /**************************************************************************** * Main driver @@ -2766,11 +2787,28 @@ enum { /* ACPI GBDC/SBDC bits */ TP_ACPI_BLUETOOTH_HWPRESENT = 0x01, /* Bluetooth hw available */ TP_ACPI_BLUETOOTH_RADIOSSW = 0x02, /* Bluetooth radio enabled */ - TP_ACPI_BLUETOOTH_UNK = 0x04, /* unknown function */ + TP_ACPI_BLUETOOTH_RESUMECTRL = 0x04, /* Bluetooth state at resume: + off / last state */ +}; + +enum { + /* ACPI \BLTH commands */ + TP_ACPI_BLTH_GET_ULTRAPORT_ID = 0x00, /* Get Ultraport BT ID */ + TP_ACPI_BLTH_GET_PWR_ON_RESUME = 0x01, /* Get power-on-resume state */ + TP_ACPI_BLTH_PWR_ON_ON_RESUME = 0x02, /* Resume powered on */ + TP_ACPI_BLTH_PWR_OFF_ON_RESUME = 0x03, /* Resume powered off */ + TP_ACPI_BLTH_SAVE_STATE = 0x05, /* Save state for S4/S5 */ }; static struct rfkill *tpacpi_bluetooth_rfkill; +static void bluetooth_suspend(pm_message_t state) +{ + /* Try to make sure radio will resume powered off */ + acpi_evalf(NULL, NULL, "\\BLTH", "vd", + TP_ACPI_BLTH_PWR_OFF_ON_RESUME); +} + static int bluetooth_get_radiosw(void) { int status; @@ -2830,12 +2868,11 @@ static int bluetooth_set_radiosw(int radio_on, int update_rfk) } #endif - if (!acpi_evalf(hkey_handle, &status, "GBDC", "d")) - return -EIO; + /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */ if (radio_on) - status |= TP_ACPI_BLUETOOTH_RADIOSSW; + status = TP_ACPI_BLUETOOTH_RADIOSSW; else - status &= ~TP_ACPI_BLUETOOTH_RADIOSSW; + status = 0; if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status)) return -EIO; @@ -3012,6 +3049,7 @@ static struct ibm_struct bluetooth_driver_data = { .read = bluetooth_read, .write = bluetooth_write, .exit = bluetooth_exit, + .suspend = bluetooth_suspend, }; /************************************************************************* @@ -3022,11 +3060,19 @@ enum { /* ACPI GWAN/SWAN bits */ TP_ACPI_WANCARD_HWPRESENT = 0x01, /* Wan hw available */ TP_ACPI_WANCARD_RADIOSSW = 0x02, /* Wan radio enabled */ - TP_ACPI_WANCARD_UNK = 0x04, /* unknown function */ + TP_ACPI_WANCARD_RESUMECTRL = 0x04, /* Wan state at resume: + off / last state */ }; static struct rfkill *tpacpi_wan_rfkill; +static void wan_suspend(pm_message_t state) +{ + /* Try to make sure radio will resume powered off */ + acpi_evalf(NULL, NULL, "\\WGSV", "qvd", + TP_ACPI_WGSV_PWR_OFF_ON_RESUME); +} + static int wan_get_radiosw(void) { int status; @@ -3086,12 +3132,11 @@ static int wan_set_radiosw(int radio_on, int update_rfk) } #endif - if (!acpi_evalf(hkey_handle, &status, "GWAN", "d")) - return -EIO; + /* We make sure to keep TP_ACPI_WANCARD_RESUMECTRL off */ if (radio_on) - status |= TP_ACPI_WANCARD_RADIOSSW; + status = TP_ACPI_WANCARD_RADIOSSW; else - status &= ~TP_ACPI_WANCARD_RADIOSSW; + status = 0; if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status)) return -EIO; @@ -3266,6 +3311,7 @@ static struct ibm_struct wan_driver_data = { .read = wan_read, .write = wan_write, .exit = wan_exit, + .suspend = wan_suspend, }; /************************************************************************* -- cgit From 90d9d3c79c44bcf95bc487e9bbceaff2de370310 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 11 Jan 2009 03:01:02 -0200 Subject: ACPI: thinkpad-acpi: preserve radio state across shutdown Store in firmware NVRAM the radio state on machine shutdown for WWAN and bluetooth. Also, try to set the initial boot state of these radios as the rfkill default state for their respective classes. Signed-off-by: Henrique de Moraes Holschuh Cc: Ivo van Doorn Signed-off-by: Len Brown --- drivers/platform/x86/thinkpad_acpi.c | 59 +++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index b2c5913ff72..27d709bac98 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -222,6 +222,7 @@ struct ibm_struct { void (*exit) (void); void (*resume) (void); void (*suspend) (pm_message_t state); + void (*shutdown) (void); struct list_head all_drivers; @@ -759,6 +760,18 @@ static int tpacpi_resume_handler(struct platform_device *pdev) return 0; } +static void tpacpi_shutdown_handler(struct platform_device *pdev) +{ + struct ibm_struct *ibm, *itmp; + + list_for_each_entry_safe(ibm, itmp, + &tpacpi_all_drivers, + all_drivers) { + if (ibm->shutdown) + (ibm->shutdown)(); + } +} + static struct platform_driver tpacpi_pdriver = { .driver = { .name = TPACPI_DRVR_NAME, @@ -766,6 +779,7 @@ static struct platform_driver tpacpi_pdriver = { }, .suspend = tpacpi_suspend_handler, .resume = tpacpi_resume_handler, + .shutdown = tpacpi_shutdown_handler, }; static struct platform_driver tpacpi_hwmon_pdriver = { @@ -957,7 +971,22 @@ static int __init tpacpi_new_rfkill(const unsigned int id, int (*get_state)(void *, enum rfkill_state *)) { int res; - enum rfkill_state initial_state; + enum rfkill_state initial_state = RFKILL_STATE_SOFT_BLOCKED; + + res = get_state(NULL, &initial_state); + if (res < 0) { + printk(TPACPI_ERR + "failed to read initial state for %s, error %d; " + "will turn radio off\n", name, res); + } else { + /* try to set the initial state as the default for the rfkill + * type, since we ask the firmware to preserve it across S5 in + * NVRAM */ + rfkill_set_default(rfktype, + (initial_state == RFKILL_STATE_UNBLOCKED) ? + RFKILL_STATE_UNBLOCKED : + RFKILL_STATE_SOFT_BLOCKED); + } *rfk = rfkill_allocate(&tpacpi_pdev->dev, rfktype); if (!*rfk) { @@ -969,9 +998,7 @@ static int __init tpacpi_new_rfkill(const unsigned int id, (*rfk)->name = name; (*rfk)->get_state = get_state; (*rfk)->toggle_radio = toggle_radio; - - if (!get_state(NULL, &initial_state)) - (*rfk)->state = initial_state; + (*rfk)->state = initial_state; res = rfkill_register(*rfk); if (res < 0) { @@ -2943,8 +2970,19 @@ static int tpacpi_bluetooth_rfk_set(void *data, enum rfkill_state state) return bluetooth_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0); } +static void bluetooth_shutdown(void) +{ + /* Order firmware to save current state to NVRAM */ + if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd", + TP_ACPI_BLTH_SAVE_STATE)) + printk(TPACPI_NOTICE + "failed to save bluetooth state to NVRAM\n"); +} + static void bluetooth_exit(void) { + bluetooth_shutdown(); + if (tpacpi_bluetooth_rfkill) rfkill_unregister(tpacpi_bluetooth_rfkill); @@ -3050,6 +3088,7 @@ static struct ibm_struct bluetooth_driver_data = { .write = bluetooth_write, .exit = bluetooth_exit, .suspend = bluetooth_suspend, + .shutdown = bluetooth_shutdown, }; /************************************************************************* @@ -3207,8 +3246,19 @@ static int tpacpi_wan_rfk_set(void *data, enum rfkill_state state) return wan_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0); } +static void wan_shutdown(void) +{ + /* Order firmware to save current state to NVRAM */ + if (!acpi_evalf(NULL, NULL, "\\WGSV", "vd", + TP_ACPI_WGSV_SAVE_STATE)) + printk(TPACPI_NOTICE + "failed to save WWAN state to NVRAM\n"); +} + static void wan_exit(void) { + wan_shutdown(); + if (tpacpi_wan_rfkill) rfkill_unregister(tpacpi_wan_rfkill); @@ -3312,6 +3362,7 @@ static struct ibm_struct wan_driver_data = { .write = wan_write, .exit = wan_exit, .suspend = wan_suspend, + .shutdown = wan_shutdown, }; /************************************************************************* -- cgit From 0045c0aa7d5e787f78938e6a10927b8a516f0b83 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 11 Jan 2009 03:01:03 -0200 Subject: ACPI: thinkpad-acpi: add UWB radio support Add rfkill support for USB UWB radio devices on very recent ThinkPad laptop models. The new subdriver is moslty a trimmed down copy of the wwan subdriver. Signed-off-by: Henrique de Moraes Holschuh Cc: Ivo van Doorn Signed-off-by: Len Brown --- Documentation/laptops/thinkpad-acpi.txt | 18 +++ drivers/platform/x86/thinkpad_acpi.c | 206 +++++++++++++++++++++++++++++++- 2 files changed, 223 insertions(+), 1 deletion(-) diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt index ddc371e0a1a..91c00010b15 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt @@ -1413,6 +1413,24 @@ Sysfs notes: rfkill controller switch "tpacpi_wwan_sw": refer to Documentation/rfkill.txt for details. +EXPERIMENTAL: UWB +----------------- + +This feature is marked EXPERIMENTAL because it has not been extensively +tested and validated in various ThinkPad models yet. The feature may not +work as expected. USE WITH CAUTION! To use this feature, you need to supply +the experimental=1 parameter when loading the module. + +sysfs rfkill class: switch "tpacpi_uwb_sw" + +This feature exports an rfkill controller for the UWB device, if one is +present and enabled in the BIOS. + +Sysfs notes: + + rfkill controller switch "tpacpi_uwb_sw": refer to + Documentation/rfkill.txt for details. + Multiple Commands, Module Parameters ------------------------------------ diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 27d709bac98..c1d40410ad7 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -169,6 +169,7 @@ enum { enum { TPACPI_RFK_BLUETOOTH_SW_ID = 0, TPACPI_RFK_WWAN_SW_ID, + TPACPI_RFK_UWB_SW_ID, }; /* Debugging */ @@ -261,6 +262,7 @@ static struct { u32 bright_16levels:1; u32 bright_acpimode:1; u32 wan:1; + u32 uwb:1; u32 fan_ctrl_status_undef:1; u32 input_device_registered:1; u32 platform_drv_registered:1; @@ -317,6 +319,8 @@ static int dbg_bluetoothemul; static int tpacpi_bluetooth_emulstate; static int dbg_wwanemul; static int tpacpi_wwan_emulstate; +static int dbg_uwbemul; +static int tpacpi_uwb_emulstate; #endif @@ -967,6 +971,7 @@ static int __init tpacpi_new_rfkill(const unsigned int id, struct rfkill **rfk, const enum rfkill_type rfktype, const char *name, + const bool set_default, int (*toggle_radio)(void *, enum rfkill_state), int (*get_state)(void *, enum rfkill_state *)) { @@ -978,7 +983,7 @@ static int __init tpacpi_new_rfkill(const unsigned int id, printk(TPACPI_ERR "failed to read initial state for %s, error %d; " "will turn radio off\n", name, res); - } else { + } else if (set_default) { /* try to set the initial state as the default for the rfkill * type, since we ask the firmware to preserve it across S5 in * NVRAM */ @@ -1148,6 +1153,31 @@ static DRIVER_ATTR(wwan_emulstate, S_IWUSR | S_IRUGO, tpacpi_driver_wwan_emulstate_show, tpacpi_driver_wwan_emulstate_store); +/* uwb_emulstate ------------------------------------------------- */ +static ssize_t tpacpi_driver_uwb_emulstate_show( + struct device_driver *drv, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_uwb_emulstate); +} + +static ssize_t tpacpi_driver_uwb_emulstate_store( + struct device_driver *drv, + const char *buf, size_t count) +{ + unsigned long t; + + if (parse_strtoul(buf, 1, &t)) + return -EINVAL; + + tpacpi_uwb_emulstate = !!t; + + return count; +} + +static DRIVER_ATTR(uwb_emulstate, S_IWUSR | S_IRUGO, + tpacpi_driver_uwb_emulstate_show, + tpacpi_driver_uwb_emulstate_store); #endif /* --------------------------------------------------------------------- */ @@ -1175,6 +1205,8 @@ static int __init tpacpi_create_driver_attributes(struct device_driver *drv) res = driver_create_file(drv, &driver_attr_bluetooth_emulstate); if (!res && dbg_wwanemul) res = driver_create_file(drv, &driver_attr_wwan_emulstate); + if (!res && dbg_uwbemul) + res = driver_create_file(drv, &driver_attr_uwb_emulstate); #endif return res; @@ -1191,6 +1223,7 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv) driver_remove_file(drv, &driver_attr_wlsw_emulstate); driver_remove_file(drv, &driver_attr_bluetooth_emulstate); driver_remove_file(drv, &driver_attr_wwan_emulstate); + driver_remove_file(drv, &driver_attr_uwb_emulstate); #endif } @@ -2125,6 +2158,7 @@ static struct attribute *hotkey_mask_attributes[] __initdata = { static void bluetooth_update_rfk(void); static void wan_update_rfk(void); +static void uwb_update_rfk(void); static void tpacpi_send_radiosw_update(void) { int wlsw; @@ -2134,6 +2168,8 @@ static void tpacpi_send_radiosw_update(void) bluetooth_update_rfk(); if (tp_features.wan) wan_update_rfk(); + if (tp_features.uwb) + uwb_update_rfk(); if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) { mutex_lock(&tpacpi_inputdev_send_mutex); @@ -3035,6 +3071,7 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm) &tpacpi_bluetooth_rfkill, RFKILL_TYPE_BLUETOOTH, "tpacpi_bluetooth_sw", + true, tpacpi_bluetooth_rfk_set, tpacpi_bluetooth_rfk_get); if (res) { @@ -3309,6 +3346,7 @@ static int __init wan_init(struct ibm_init_struct *iibm) &tpacpi_wan_rfkill, RFKILL_TYPE_WWAN, "tpacpi_wwan_sw", + true, tpacpi_wan_rfk_set, tpacpi_wan_rfk_get); if (res) { @@ -3365,6 +3403,162 @@ static struct ibm_struct wan_driver_data = { .shutdown = wan_shutdown, }; +/************************************************************************* + * UWB subdriver + */ + +enum { + /* ACPI GUWB/SUWB bits */ + TP_ACPI_UWB_HWPRESENT = 0x01, /* UWB hw available */ + TP_ACPI_UWB_RADIOSSW = 0x02, /* UWB radio enabled */ +}; + +static struct rfkill *tpacpi_uwb_rfkill; + +static int uwb_get_radiosw(void) +{ + int status; + + if (!tp_features.uwb) + return -ENODEV; + + /* WLSW overrides UWB in firmware/hardware, reflect that */ + if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status) + return RFKILL_STATE_HARD_BLOCKED; + +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES + if (dbg_uwbemul) + return (tpacpi_uwb_emulstate) ? + RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; +#endif + + if (!acpi_evalf(hkey_handle, &status, "GUWB", "d")) + return -EIO; + + return ((status & TP_ACPI_UWB_RADIOSSW) != 0) ? + RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; +} + +static void uwb_update_rfk(void) +{ + int status; + + if (!tpacpi_uwb_rfkill) + return; + + status = uwb_get_radiosw(); + if (status < 0) + return; + rfkill_force_state(tpacpi_uwb_rfkill, status); +} + +static int uwb_set_radiosw(int radio_on, int update_rfk) +{ + int status; + + if (!tp_features.uwb) + return -ENODEV; + + /* WLSW overrides UWB in firmware/hardware, but there is no + * reason to risk weird behaviour. */ + if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status + && radio_on) + return -EPERM; + +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES + if (dbg_uwbemul) { + tpacpi_uwb_emulstate = !!radio_on; + if (update_rfk) + uwb_update_rfk(); + return 0; + } +#endif + + status = (radio_on) ? TP_ACPI_UWB_RADIOSSW : 0; + if (!acpi_evalf(hkey_handle, NULL, "SUWB", "vd", status)) + return -EIO; + + if (update_rfk) + uwb_update_rfk(); + + return 0; +} + +/* --------------------------------------------------------------------- */ + +static int tpacpi_uwb_rfk_get(void *data, enum rfkill_state *state) +{ + int uwbs = uwb_get_radiosw(); + + if (uwbs < 0) + return uwbs; + + *state = uwbs; + return 0; +} + +static int tpacpi_uwb_rfk_set(void *data, enum rfkill_state state) +{ + return uwb_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0); +} + +static void uwb_exit(void) +{ + if (tpacpi_uwb_rfkill) + rfkill_unregister(tpacpi_uwb_rfkill); +} + +static int __init uwb_init(struct ibm_init_struct *iibm) +{ + int res; + int status = 0; + + vdbg_printk(TPACPI_DBG_INIT, "initializing uwb subdriver\n"); + + TPACPI_ACPIHANDLE_INIT(hkey); + + tp_features.uwb = hkey_handle && + acpi_evalf(hkey_handle, &status, "GUWB", "qd"); + + vdbg_printk(TPACPI_DBG_INIT, "uwb is %s, status 0x%02x\n", + str_supported(tp_features.uwb), + status); + +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES + if (dbg_uwbemul) { + tp_features.uwb = 1; + printk(TPACPI_INFO + "uwb switch emulation enabled\n"); + } else +#endif + if (tp_features.uwb && + !(status & TP_ACPI_UWB_HWPRESENT)) { + /* no uwb hardware present in system */ + tp_features.uwb = 0; + dbg_printk(TPACPI_DBG_INIT, + "uwb hardware not installed\n"); + } + + if (!tp_features.uwb) + return 1; + + res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID, + &tpacpi_uwb_rfkill, + RFKILL_TYPE_UWB, + "tpacpi_uwb_sw", + false, + tpacpi_uwb_rfk_set, + tpacpi_uwb_rfk_get); + + return res; +} + +static struct ibm_struct uwb_driver_data = { + .name = "uwb", + .exit = uwb_exit, + .flags.experimental = 1, +}; + /************************************************************************* * Video subdriver */ @@ -6830,6 +7024,10 @@ static struct ibm_init_struct ibms_init[] __initdata = { .init = wan_init, .data = &wan_driver_data, }, + { + .init = uwb_init, + .data = &uwb_driver_data, + }, #ifdef CONFIG_THINKPAD_ACPI_VIDEO { .init = video_init, @@ -6986,6 +7184,12 @@ MODULE_PARM_DESC(dbg_wwanemul, "Enables WWAN switch emulation"); module_param_named(wwan_state, tpacpi_wwan_emulstate, bool, 0); MODULE_PARM_DESC(wwan_state, "Initial state of the emulated WWAN switch"); + +module_param(dbg_uwbemul, uint, 0); +MODULE_PARM_DESC(dbg_uwbemul, "Enables UWB switch emulation"); +module_param_named(uwb_state, tpacpi_uwb_emulstate, bool, 0); +MODULE_PARM_DESC(uwb_state, + "Initial state of the emulated UWB switch"); #endif static void thinkpad_acpi_module_exit(void) -- cgit From 88fc241f54459ac3d86c5e13b449730199f66061 Mon Sep 17 00:00:00 2001 From: Doug Chapman Date: Thu, 15 Jan 2009 10:38:56 -0800 Subject: [IA64] dump stack on kernel unaligned warnings Often the cause of kernel unaligned access warnings is not obvious from just the ip displayed in the warning. This adds the option via proc to dump the stack in addition to the warning. The default is off (just display the 1 line warning). To enable the stack to be shown: echo 1 > /proc/sys/kernel/unaligned-dump-stack Signed-off-by: Doug Chapman Signed-off-by: Tony Luck --- arch/ia64/kernel/unaligned.c | 6 +++++- kernel/sysctl.c | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c index ff0e7c10faa..6db08599ebb 100644 --- a/arch/ia64/kernel/unaligned.c +++ b/arch/ia64/kernel/unaligned.c @@ -59,6 +59,7 @@ dump (const char *str, void *vp, size_t len) * (i.e. don't allow attacker to fill up logs with unaligned accesses). */ int no_unaligned_warning; +int unaligned_dump_stack; static int noprint_warning; /* @@ -1371,9 +1372,12 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs) } } } else { - if (within_logging_rate_limit()) + if (within_logging_rate_limit()) { printk(KERN_WARNING "kernel unaligned access to 0x%016lx, ip=0x%016lx\n", ifa, regs->cr_iip + ipsr->ri); + if (unaligned_dump_stack) + dump_stack(); + } set_fs(KERNEL_DS); } diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 3e38b74b612..368d1638ee7 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -144,6 +144,7 @@ extern int acct_parm[]; #ifdef CONFIG_IA64 extern int no_unaligned_warning; +extern int unaligned_dump_stack; #endif #ifdef CONFIG_RT_MUTEXES @@ -781,6 +782,14 @@ static struct ctl_table kern_table[] = { .mode = 0644, .proc_handler = &proc_dointvec, }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "unaligned-dump-stack", + .data = &unaligned_dump_stack, + .maxlen = sizeof (int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, #endif #ifdef CONFIG_DETECT_SOFTLOCKUP { -- cgit From 7646ea88af80a92f2775e17d4283830d7f09ea2d Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 11 Jan 2009 03:01:04 -0200 Subject: ACPI: thinkpad-acpi: use killable instead of interruptible mutexes Unfortunately, POSIX in all of its braindamage, do not state that userspace has to deal with EINTR in read/write and friends... so, lesser code just doesn't. Switch from *_interruptible to *_killable on the sysfs- and procfs-related mutexes. This closes this possible can of worms. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- drivers/platform/x86/thinkpad_acpi.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index c1d40410ad7..7670c8ee63d 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -1878,7 +1878,7 @@ static ssize_t hotkey_mask_show(struct device *dev, { int res; - if (mutex_lock_interruptible(&hotkey_mutex)) + if (mutex_lock_killable(&hotkey_mutex)) return -ERESTARTSYS; res = hotkey_mask_get(); mutex_unlock(&hotkey_mutex); @@ -1897,7 +1897,7 @@ static ssize_t hotkey_mask_store(struct device *dev, if (parse_strtoul(buf, 0xffffffffUL, &t)) return -EINVAL; - if (mutex_lock_interruptible(&hotkey_mutex)) + if (mutex_lock_killable(&hotkey_mutex)) return -ERESTARTSYS; res = hotkey_mask_set(t); @@ -1983,7 +1983,7 @@ static ssize_t hotkey_source_mask_store(struct device *dev, ((t & ~TPACPI_HKEY_NVRAM_KNOWN_MASK) != 0)) return -EINVAL; - if (mutex_lock_interruptible(&hotkey_mutex)) + if (mutex_lock_killable(&hotkey_mutex)) return -ERESTARTSYS; HOTKEY_CONFIG_CRITICAL_START @@ -2018,7 +2018,7 @@ static ssize_t hotkey_poll_freq_store(struct device *dev, if (parse_strtoul(buf, 25, &t)) return -EINVAL; - if (mutex_lock_interruptible(&hotkey_mutex)) + if (mutex_lock_killable(&hotkey_mutex)) return -ERESTARTSYS; hotkey_poll_freq = t; @@ -2754,7 +2754,7 @@ static int hotkey_read(char *p) return len; } - if (mutex_lock_interruptible(&hotkey_mutex)) + if (mutex_lock_killable(&hotkey_mutex)) return -ERESTARTSYS; res = hotkey_status_get(&status); if (!res) @@ -2785,7 +2785,7 @@ static int hotkey_write(char *buf) if (!tp_features.hotkey) return -ENODEV; - if (mutex_lock_interruptible(&hotkey_mutex)) + if (mutex_lock_killable(&hotkey_mutex)) return -ERESTARTSYS; status = -1; @@ -5311,7 +5311,7 @@ static int brightness_set(int value) value < 0) return -EINVAL; - res = mutex_lock_interruptible(&brightness_mutex); + res = mutex_lock_killable(&brightness_mutex); if (res < 0) return res; @@ -5849,7 +5849,7 @@ static int fan_get_status_safe(u8 *status) int rc; u8 s; - if (mutex_lock_interruptible(&fan_mutex)) + if (mutex_lock_killable(&fan_mutex)) return -ERESTARTSYS; rc = fan_get_status(&s); if (!rc) @@ -5932,7 +5932,7 @@ static int fan_set_level_safe(int level) if (!fan_control_allowed) return -EPERM; - if (mutex_lock_interruptible(&fan_mutex)) + if (mutex_lock_killable(&fan_mutex)) return -ERESTARTSYS; if (level == TPACPI_FAN_LAST_LEVEL) @@ -5954,7 +5954,7 @@ static int fan_set_enable(void) if (!fan_control_allowed) return -EPERM; - if (mutex_lock_interruptible(&fan_mutex)) + if (mutex_lock_killable(&fan_mutex)) return -ERESTARTSYS; switch (fan_control_access_mode) { @@ -6009,7 +6009,7 @@ static int fan_set_disable(void) if (!fan_control_allowed) return -EPERM; - if (mutex_lock_interruptible(&fan_mutex)) + if (mutex_lock_killable(&fan_mutex)) return -ERESTARTSYS; rc = 0; @@ -6047,7 +6047,7 @@ static int fan_set_speed(int speed) if (!fan_control_allowed) return -EPERM; - if (mutex_lock_interruptible(&fan_mutex)) + if (mutex_lock_killable(&fan_mutex)) return -ERESTARTSYS; rc = 0; @@ -6249,7 +6249,7 @@ static ssize_t fan_pwm1_store(struct device *dev, /* scale down from 0-255 to 0-7 */ newlevel = (s >> 5) & 0x07; - if (mutex_lock_interruptible(&fan_mutex)) + if (mutex_lock_killable(&fan_mutex)) return -ERESTARTSYS; rc = fan_get_status(&status); -- cgit From 3827e7a3fd03718d4d204c66d9e3ab9b125ae552 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 11 Jan 2009 03:01:05 -0200 Subject: ACPI: thinkpad-acpi: clean up hotkey_notify() Clean up the hotkey_notify() handler, which handles the HKEY notifications from the ACPI firmware. It was getting too long and deep. No functional changes. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- drivers/platform/x86/thinkpad_acpi.c | 174 ++++++++++++++++++++++------------- 1 file changed, 109 insertions(+), 65 deletions(-) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 7670c8ee63d..d833ee689f9 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -2571,13 +2571,100 @@ err_exit: return (res < 0)? res : 1; } +static bool hotkey_notify_hotkey(const u32 hkey, + bool *send_acpi_ev, + bool *ignore_acpi_ev) +{ + /* 0x1000-0x1FFF: key presses */ + unsigned int scancode = hkey & 0xfff; + *send_acpi_ev = true; + *ignore_acpi_ev = false; + + if (scancode > 0 && scancode < 0x21) { + scancode--; + if (!(hotkey_source_mask & (1 << scancode))) { + tpacpi_input_send_key(scancode); + *send_acpi_ev = false; + } else { + *ignore_acpi_ev = true; + } + return true; + } + return false; +} + +static bool hotkey_notify_wakeup(const u32 hkey, + bool *send_acpi_ev, + bool *ignore_acpi_ev) +{ + /* 0x2000-0x2FFF: Wakeup reason */ + *send_acpi_ev = true; + *ignore_acpi_ev = false; + + switch (hkey) { + case 0x2304: /* suspend, undock */ + case 0x2404: /* hibernation, undock */ + hotkey_wakeup_reason = TP_ACPI_WAKEUP_UNDOCK; + *ignore_acpi_ev = true; + break; + + case 0x2305: /* suspend, bay eject */ + case 0x2405: /* hibernation, bay eject */ + hotkey_wakeup_reason = TP_ACPI_WAKEUP_BAYEJ; + *ignore_acpi_ev = true; + break; + + default: + return false; + } + + if (hotkey_wakeup_reason != TP_ACPI_WAKEUP_NONE) { + printk(TPACPI_INFO + "woke up due to a hot-unplug " + "request...\n"); + hotkey_wakeup_reason_notify_change(); + } + return true; +} + +static bool hotkey_notify_usrevent(const u32 hkey, + bool *send_acpi_ev, + bool *ignore_acpi_ev) +{ + /* 0x5000-0x5FFF: human interface helpers */ + *send_acpi_ev = true; + *ignore_acpi_ev = false; + + switch (hkey) { + case 0x5010: /* Lenovo new BIOS: brightness changed */ + case 0x500b: /* X61t: tablet pen inserted into bay */ + case 0x500c: /* X61t: tablet pen removed from bay */ + return true; + + case 0x5009: /* X41t-X61t: swivel up (tablet mode) */ + case 0x500a: /* X41t-X61t: swivel down (normal mode) */ + tpacpi_input_send_tabletsw(); + hotkey_tablet_mode_notify_change(); + *send_acpi_ev = false; + return true; + + case 0x5001: + case 0x5002: + /* LID switch events. Do not propagate */ + *ignore_acpi_ev = true; + return true; + + default: + return false; + } +} + static void hotkey_notify(struct ibm_struct *ibm, u32 event) { u32 hkey; - unsigned int scancode; - int send_acpi_ev; - int ignore_acpi_ev; - int unk_ev; + bool send_acpi_ev; + bool ignore_acpi_ev; + bool known_ev; if (event != 0x80) { printk(TPACPI_ERR @@ -2601,105 +2688,62 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) return; } - send_acpi_ev = 1; - ignore_acpi_ev = 0; - unk_ev = 0; + send_acpi_ev = true; + ignore_acpi_ev = false; switch (hkey >> 12) { case 1: /* 0x1000-0x1FFF: key presses */ - scancode = hkey & 0xfff; - if (scancode > 0 && scancode < 0x21) { - scancode--; - if (!(hotkey_source_mask & (1 << scancode))) { - tpacpi_input_send_key(scancode); - send_acpi_ev = 0; - } else { - ignore_acpi_ev = 1; - } - } else { - unk_ev = 1; - } + known_ev = hotkey_notify_hotkey(hkey, &send_acpi_ev, + &ignore_acpi_ev); break; case 2: - /* Wakeup reason */ - switch (hkey) { - case 0x2304: /* suspend, undock */ - case 0x2404: /* hibernation, undock */ - hotkey_wakeup_reason = TP_ACPI_WAKEUP_UNDOCK; - ignore_acpi_ev = 1; - break; - case 0x2305: /* suspend, bay eject */ - case 0x2405: /* hibernation, bay eject */ - hotkey_wakeup_reason = TP_ACPI_WAKEUP_BAYEJ; - ignore_acpi_ev = 1; - break; - default: - unk_ev = 1; - } - if (hotkey_wakeup_reason != TP_ACPI_WAKEUP_NONE) { - printk(TPACPI_INFO - "woke up due to a hot-unplug " - "request...\n"); - hotkey_wakeup_reason_notify_change(); - } + /* 0x2000-0x2FFF: Wakeup reason */ + known_ev = hotkey_notify_wakeup(hkey, &send_acpi_ev, + &ignore_acpi_ev); break; case 3: - /* bay-related wakeups */ + /* 0x3000-0x3FFF: bay-related wakeups */ if (hkey == 0x3003) { hotkey_autosleep_ack = 1; printk(TPACPI_INFO "bay ejected\n"); hotkey_wakeup_hotunplug_complete_notify_change(); + known_ev = true; } else { - unk_ev = 1; + known_ev = false; } break; case 4: - /* dock-related wakeups */ + /* 0x4000-0x4FFF: dock-related wakeups */ if (hkey == 0x4003) { hotkey_autosleep_ack = 1; printk(TPACPI_INFO "undocked\n"); hotkey_wakeup_hotunplug_complete_notify_change(); + known_ev = true; } else { - unk_ev = 1; + known_ev = false; } break; case 5: /* 0x5000-0x5FFF: human interface helpers */ - switch (hkey) { - case 0x5010: /* Lenovo new BIOS: brightness changed */ - case 0x500b: /* X61t: tablet pen inserted into bay */ - case 0x500c: /* X61t: tablet pen removed from bay */ - break; - case 0x5009: /* X41t-X61t: swivel up (tablet mode) */ - case 0x500a: /* X41t-X61t: swivel down (normal mode) */ - tpacpi_input_send_tabletsw(); - hotkey_tablet_mode_notify_change(); - send_acpi_ev = 0; - break; - case 0x5001: - case 0x5002: - /* LID switch events. Do not propagate */ - ignore_acpi_ev = 1; - break; - default: - unk_ev = 1; - } + known_ev = hotkey_notify_usrevent(hkey, &send_acpi_ev, + &ignore_acpi_ev); break; case 7: /* 0x7000-0x7FFF: misc */ if (tp_features.hotkey_wlsw && hkey == 0x7000) { tpacpi_send_radiosw_update(); send_acpi_ev = 0; + known_ev = true; break; } /* fallthrough to default */ default: - unk_ev = 1; + known_ev = false; } - if (unk_ev) { + if (!known_ev) { printk(TPACPI_NOTICE "unhandled HKEY event 0x%04x\n", hkey); } -- cgit From a6a3bb5c88d706c5efe0c86b3b669ac9ee012b3f Mon Sep 17 00:00:00 2001 From: Brent Casavant Date: Wed, 10 Dec 2008 09:46:16 -0600 Subject: [IA64] generic_defconfig: Enable SATA_VITESSE CONFIG_SATA_VITESSE=y was not added to generic_defconfig when sn2_defconfig was removed. SGI Altix systems that use an IO10 base IO card to drive the root device are unable to boot without the Vitesse controller. Signed-off-by: Brent Casavant Signed-off-by: Robin Holt Signed-off-by: Jes Sorensen Signed-off-by: Tony Luck --- arch/ia64/configs/generic_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ia64/configs/generic_defconfig b/arch/ia64/configs/generic_defconfig index 27eb67604c5..a109db30ce5 100644 --- a/arch/ia64/configs/generic_defconfig +++ b/arch/ia64/configs/generic_defconfig @@ -578,7 +578,7 @@ CONFIG_ATA_PIIX=y # CONFIG_SATA_SIS is not set # CONFIG_SATA_ULI is not set # CONFIG_SATA_VIA is not set -# CONFIG_SATA_VITESSE is not set +CONFIG_SATA_VITESSE=y # CONFIG_SATA_INIC162X is not set # CONFIG_PATA_ACPI is not set # CONFIG_PATA_ALI is not set -- cgit From 175add1981e53d22caba8f42d5f924a4de507b6c Mon Sep 17 00:00:00 2001 From: John Keller Date: Mon, 24 Nov 2008 16:47:17 -0600 Subject: [IA64] SN specific version of dma_get_required_mask() Create a platform specific version of dma_get_required_mask() for ia64 SN Altix. All SN Altix platforms support 64 bit DMA addressing regardless of the size of system memory. Create an ia64 machvec for dma_get_required_mask, with the SN version unconditionally returning DMA_64BIT_MASK. Signed-off-by: John Keller Signed-off-by: Tony Luck --- Documentation/DMA-API.txt | 9 ++++----- arch/ia64/include/asm/dma-mapping.h | 2 ++ arch/ia64/include/asm/machvec.h | 7 +++++++ arch/ia64/include/asm/machvec_init.h | 1 + arch/ia64/include/asm/machvec_sn2.h | 2 ++ arch/ia64/pci/pci.c | 27 +++++++++++++++++++++++++++ arch/ia64/sn/pci/pci_dma.c | 6 ++++++ 7 files changed, 49 insertions(+), 5 deletions(-) diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt index b462bb14954..52441694fe0 100644 --- a/Documentation/DMA-API.txt +++ b/Documentation/DMA-API.txt @@ -170,16 +170,15 @@ Returns: 0 if successful and a negative error if not. u64 dma_get_required_mask(struct device *dev) -After setting the mask with dma_set_mask(), this API returns the -actual mask (within that already set) that the platform actually -requires to operate efficiently. Usually this means the returned mask +This API returns the mask that the platform requires to +operate efficiently. Usually this means the returned mask is the minimum required to cover all of memory. Examining the required mask gives drivers with variable descriptor sizes the opportunity to use smaller descriptors as necessary. Requesting the required mask does not alter the current mask. If you -wish to take advantage of it, you should issue another dma_set_mask() -call to lower the mask again. +wish to take advantage of it, you should issue a dma_set_mask() +call to set the mask to the value returned. Part Id - Streaming DMA mappings diff --git a/arch/ia64/include/asm/dma-mapping.h b/arch/ia64/include/asm/dma-mapping.h index bbab7e2b0fc..1f912d92758 100644 --- a/arch/ia64/include/asm/dma-mapping.h +++ b/arch/ia64/include/asm/dma-mapping.h @@ -9,6 +9,8 @@ #include #include +#define ARCH_HAS_DMA_GET_REQUIRED_MASK + struct dma_mapping_ops { int (*mapping_error)(struct device *dev, dma_addr_t dma_addr); diff --git a/arch/ia64/include/asm/machvec.h b/arch/ia64/include/asm/machvec.h index 59c17e44668..fe87b212170 100644 --- a/arch/ia64/include/asm/machvec.h +++ b/arch/ia64/include/asm/machvec.h @@ -62,6 +62,7 @@ typedef dma_addr_t ia64_mv_dma_map_single_attrs (struct device *, void *, size_t typedef void ia64_mv_dma_unmap_single_attrs (struct device *, dma_addr_t, size_t, int, struct dma_attrs *); typedef int ia64_mv_dma_map_sg_attrs (struct device *, struct scatterlist *, int, int, struct dma_attrs *); typedef void ia64_mv_dma_unmap_sg_attrs (struct device *, struct scatterlist *, int, int, struct dma_attrs *); +typedef u64 ia64_mv_dma_get_required_mask (struct device *); /* * WARNING: The legacy I/O space is _architected_. Platforms are @@ -159,6 +160,7 @@ extern void machvec_tlb_migrate_finish (struct mm_struct *); # define platform_dma_sync_sg_for_device ia64_mv.dma_sync_sg_for_device # define platform_dma_mapping_error ia64_mv.dma_mapping_error # define platform_dma_supported ia64_mv.dma_supported +# define platform_dma_get_required_mask ia64_mv.dma_get_required_mask # define platform_irq_to_vector ia64_mv.irq_to_vector # define platform_local_vector_to_irq ia64_mv.local_vector_to_irq # define platform_pci_get_legacy_mem ia64_mv.pci_get_legacy_mem @@ -213,6 +215,7 @@ struct ia64_machine_vector { ia64_mv_dma_sync_sg_for_device *dma_sync_sg_for_device; ia64_mv_dma_mapping_error *dma_mapping_error; ia64_mv_dma_supported *dma_supported; + ia64_mv_dma_get_required_mask *dma_get_required_mask; ia64_mv_irq_to_vector *irq_to_vector; ia64_mv_local_vector_to_irq *local_vector_to_irq; ia64_mv_pci_get_legacy_mem_t *pci_get_legacy_mem; @@ -263,6 +266,7 @@ struct ia64_machine_vector { platform_dma_sync_sg_for_device, \ platform_dma_mapping_error, \ platform_dma_supported, \ + platform_dma_get_required_mask, \ platform_irq_to_vector, \ platform_local_vector_to_irq, \ platform_pci_get_legacy_mem, \ @@ -366,6 +370,9 @@ extern void machvec_init_from_cmdline(const char *cmdline); #ifndef platform_dma_supported # define platform_dma_supported swiotlb_dma_supported #endif +#ifndef platform_dma_get_required_mask +# define platform_dma_get_required_mask ia64_dma_get_required_mask +#endif #ifndef platform_irq_to_vector # define platform_irq_to_vector __ia64_irq_to_vector #endif diff --git a/arch/ia64/include/asm/machvec_init.h b/arch/ia64/include/asm/machvec_init.h index ef964b28684..37a469849ab 100644 --- a/arch/ia64/include/asm/machvec_init.h +++ b/arch/ia64/include/asm/machvec_init.h @@ -3,6 +3,7 @@ extern ia64_mv_send_ipi_t ia64_send_ipi; extern ia64_mv_global_tlb_purge_t ia64_global_tlb_purge; +extern ia64_mv_dma_get_required_mask ia64_dma_get_required_mask; extern ia64_mv_irq_to_vector __ia64_irq_to_vector; extern ia64_mv_local_vector_to_irq __ia64_local_vector_to_irq; extern ia64_mv_pci_get_legacy_mem_t ia64_pci_get_legacy_mem; diff --git a/arch/ia64/include/asm/machvec_sn2.h b/arch/ia64/include/asm/machvec_sn2.h index 781308ea7b8..f1a6e0d6dfa 100644 --- a/arch/ia64/include/asm/machvec_sn2.h +++ b/arch/ia64/include/asm/machvec_sn2.h @@ -67,6 +67,7 @@ extern ia64_mv_dma_sync_single_for_device sn_dma_sync_single_for_device; extern ia64_mv_dma_sync_sg_for_device sn_dma_sync_sg_for_device; extern ia64_mv_dma_mapping_error sn_dma_mapping_error; extern ia64_mv_dma_supported sn_dma_supported; +extern ia64_mv_dma_get_required_mask sn_dma_get_required_mask; extern ia64_mv_migrate_t sn_migrate; extern ia64_mv_kernel_launch_event_t sn_kernel_launch_event; extern ia64_mv_setup_msi_irq_t sn_setup_msi_irq; @@ -123,6 +124,7 @@ extern ia64_mv_pci_fixup_bus_t sn_pci_fixup_bus; #define platform_dma_sync_sg_for_device sn_dma_sync_sg_for_device #define platform_dma_mapping_error sn_dma_mapping_error #define platform_dma_supported sn_dma_supported +#define platform_dma_get_required_mask sn_dma_get_required_mask #define platform_migrate sn_migrate #define platform_kernel_launch_event sn_kernel_launch_event #ifdef CONFIG_PCI_MSI diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 211fcfd115f..61f1af5c23c 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -748,6 +749,32 @@ static void __init set_pci_cacheline_size(void) pci_cache_line_size = (1 << cci.pcci_line_size) / 4; } +u64 ia64_dma_get_required_mask(struct device *dev) +{ + u32 low_totalram = ((max_pfn - 1) << PAGE_SHIFT); + u32 high_totalram = ((max_pfn - 1) >> (32 - PAGE_SHIFT)); + u64 mask; + + if (!high_totalram) { + /* convert to mask just covering totalram */ + low_totalram = (1 << (fls(low_totalram) - 1)); + low_totalram += low_totalram - 1; + mask = low_totalram; + } else { + high_totalram = (1 << (fls(high_totalram) - 1)); + high_totalram += high_totalram - 1; + mask = (((u64)high_totalram) << 32) + 0xffffffff; + } + return mask; +} +EXPORT_SYMBOL_GPL(ia64_dma_get_required_mask); + +u64 dma_get_required_mask(struct device *dev) +{ + return platform_dma_get_required_mask(dev); +} +EXPORT_SYMBOL_GPL(dma_get_required_mask); + static int __init pcibios_init(void) { set_pci_cacheline_size(); diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c index 53ebb648449..863f5017baa 100644 --- a/arch/ia64/sn/pci/pci_dma.c +++ b/arch/ia64/sn/pci/pci_dma.c @@ -356,6 +356,12 @@ int sn_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) } EXPORT_SYMBOL(sn_dma_mapping_error); +u64 sn_dma_get_required_mask(struct device *dev) +{ + return DMA_64BIT_MASK; +} +EXPORT_SYMBOL_GPL(sn_dma_get_required_mask); + char *sn_pci_get_legacy_mem(struct pci_bus *bus) { if (!SN_PCIBUS_BUSSOFT(bus)) -- cgit From 106b4e6657e10831f35c32afa26d9c11e6312783 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 11 Jan 2009 03:01:06 -0200 Subject: ACPI: thinkpad-acpi: handle HKEY thermal and battery alarms Handle some HKEY events that are actually firmware alarms. For now, we do the simple thing: log specific messages to the log and let the thinkpad-specific event pass to userspace. In the future, these events will be migrated to generic notifications and subsystems. These alarms are NOT available on all ThinkPads. E.g. the T43 only issues 0x6011 and 0x6012. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- drivers/platform/x86/thinkpad_acpi.c | 63 +++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index d833ee689f9..c4e4b641d95 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -174,10 +174,12 @@ enum { /* Debugging */ #define TPACPI_LOG TPACPI_FILE ": " -#define TPACPI_ERR KERN_ERR TPACPI_LOG -#define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG -#define TPACPI_INFO KERN_INFO TPACPI_LOG -#define TPACPI_DEBUG KERN_DEBUG TPACPI_LOG +#define TPACPI_ALERT KERN_ALERT TPACPI_LOG +#define TPACPI_CRIT KERN_CRIT TPACPI_LOG +#define TPACPI_ERR KERN_ERR TPACPI_LOG +#define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG +#define TPACPI_INFO KERN_INFO TPACPI_LOG +#define TPACPI_DEBUG KERN_DEBUG TPACPI_LOG #define TPACPI_DBG_ALL 0xffff #define TPACPI_DBG_INIT 0x0001 @@ -2614,6 +2616,15 @@ static bool hotkey_notify_wakeup(const u32 hkey, *ignore_acpi_ev = true; break; + case 0x2313: /* Battery on critical low level (S3) */ + case 0x2413: /* Battery on critical low level (S4) */ + printk(TPACPI_ALERT + "EMERGENCY WAKEUP: battery almost empty\n"); + /* how to auto-heal: */ + /* 2313: woke up from S3, go to S4/S5 */ + /* 2413: woke up from S4, go to S5 */ + break; + default: return false; } @@ -2659,6 +2670,45 @@ static bool hotkey_notify_usrevent(const u32 hkey, } } +static bool hotkey_notify_thermal(const u32 hkey, + bool *send_acpi_ev, + bool *ignore_acpi_ev) +{ + /* 0x6000-0x6FFF: thermal alarms */ + *send_acpi_ev = true; + *ignore_acpi_ev = false; + + switch (hkey) { + case 0x6011: + printk(TPACPI_CRIT + "THERMAL ALARM: battery is too hot!\n"); + /* recommended action: warn user through gui */ + return true; + case 0x6012: + printk(TPACPI_ALERT + "THERMAL EMERGENCY: battery is extremely hot!\n"); + /* recommended action: immediate sleep/hibernate */ + return true; + case 0x6021: + printk(TPACPI_CRIT + "THERMAL ALARM: " + "a sensor reports something is too hot!\n"); + /* recommended action: warn user through gui, that */ + /* some internal component is too hot */ + return true; + case 0x6022: + printk(TPACPI_ALERT + "THERMAL EMERGENCY: " + "a sensor reports something is extremely hot!\n"); + /* recommended action: immediate sleep/hibernate */ + return true; + default: + printk(TPACPI_ALERT + "THERMAL ALERT: unknown thermal alarm received\n"); + return false; + } +} + static void hotkey_notify(struct ibm_struct *ibm, u32 event) { u32 hkey; @@ -2731,6 +2781,11 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) known_ev = hotkey_notify_usrevent(hkey, &send_acpi_ev, &ignore_acpi_ev); break; + case 6: + /* 0x6000-0x6FFF: thermal alarms */ + known_ev = hotkey_notify_thermal(hkey, &send_acpi_ev, + &ignore_acpi_ev); + break; case 7: /* 0x7000-0x7FFF: misc */ if (tp_features.hotkey_wlsw && hkey == 0x7000) { -- cgit From cb4293589855714b6d5079336019bf2af5fc41f8 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 11 Jan 2009 03:01:07 -0200 Subject: ACPI: thinkpad-acpi: start the event hunt season Ask users to tell us about any unhandled events they find. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- drivers/platform/x86/thinkpad_acpi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index c4e4b641d95..d7d41ae2f29 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -2801,6 +2801,9 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) if (!known_ev) { printk(TPACPI_NOTICE "unhandled HKEY event 0x%04x\n", hkey); + printk(TPACPI_NOTICE + "please report the conditions when this " + "event happened to %s\n", TPACPI_MAIL); } /* Legacy events */ -- cgit From 1c2ece758a36b48133717e4db060fbe8fa52c5cd Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 11 Jan 2009 03:01:08 -0200 Subject: ACPI: thinkpad-acpi: clean-up fan subdriver quirk Better document the Unitialized HFSP quirk, and modularize it a bit. This makes the code flow easier to read and reduces LOC. Apply the Unitialized HFSP closer to the source (i.e. inside the get_fan_status()), this fixes a harmless buglet where at driver init with the quirk active, the user could set the hwmon pwm1 attribute and switch out of pwm1_mode=2 to pwm1_mode=0 without changing pwm1_mode directly. Signed-off-by: Henrique de Moraes Holschuh Cc: Tino Keitel Signed-off-by: Len Brown --- drivers/platform/x86/thinkpad_acpi.c | 109 +++++++++++++++++++---------------- 1 file changed, 58 insertions(+), 51 deletions(-) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index d7d41ae2f29..213219d938e 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -5896,6 +5896,60 @@ TPACPI_HANDLE(sfan, ec, "SFAN", /* 570 */ "JFNS", /* 770x-JL */ ); /* all others */ +/* + * Unitialized HFSP quirk: ACPI DSDT and EC fail to initialize the + * HFSP register at boot, so it contains 0x07 but the Thinkpad could + * be in auto mode (0x80). + * + * This is corrected by any write to HFSP either by the driver, or + * by the firmware. + * + * We assume 0x07 really means auto mode while this quirk is active, + * as this is far more likely than the ThinkPad being in level 7, + * which is only used by the firmware during thermal emergencies. + */ + +static void fan_quirk1_detect(void) +{ + /* In some ThinkPads, neither the EC nor the ACPI + * DSDT initialize the HFSP register, and it ends up + * being initially set to 0x07 when it *could* be + * either 0x07 or 0x80. + * + * Enable for TP-1Y (T43), TP-78 (R51e), + * TP-76 (R52), TP-70 (T43, R52), which are known + * to be buggy. */ + if (fan_control_initial_status == 0x07) { + switch (thinkpad_id.ec_model) { + case 0x5931: /* TP-1Y */ + case 0x3837: /* TP-78 */ + case 0x3637: /* TP-76 */ + case 0x3037: /* TP-70 */ + printk(TPACPI_NOTICE + "fan_init: initial fan status is unknown, " + "assuming it is in auto mode\n"); + tp_features.fan_ctrl_status_undef = 1; + ;; + } + } +} + +static void fan_quirk1_handle(u8 *fan_status) +{ + if (unlikely(tp_features.fan_ctrl_status_undef)) { + if (*fan_status != fan_control_initial_status) { + /* something changed the HFSP regisnter since + * driver init time, so it is not undefined + * anymore */ + tp_features.fan_ctrl_status_undef = 0; + } else { + /* Return most likely status. In fact, it + * might be the only possible status */ + *fan_status = TP_EC_FAN_AUTO; + } + } +} + /* * Call with fan_mutex held */ @@ -5934,8 +5988,10 @@ static int fan_get_status(u8 *status) if (unlikely(!acpi_ec_read(fan_status_offset, &s))) return -EIO; - if (likely(status)) + if (likely(status)) { *status = s; + fan_quirk1_handle(status); + } break; @@ -6245,16 +6301,6 @@ static ssize_t fan_pwm1_enable_show(struct device *dev, if (res) return res; - if (unlikely(tp_features.fan_ctrl_status_undef)) { - if (status != fan_control_initial_status) { - tp_features.fan_ctrl_status_undef = 0; - } else { - /* Return most likely status. In fact, it - * might be the only possible status */ - status = TP_EC_FAN_AUTO; - } - } - if (status & TP_EC_FAN_FULLSPEED) { mode = 0; } else if (status & TP_EC_FAN_AUTO) { @@ -6319,14 +6365,6 @@ static ssize_t fan_pwm1_show(struct device *dev, if (res) return res; - if (unlikely(tp_features.fan_ctrl_status_undef)) { - if (status != fan_control_initial_status) { - tp_features.fan_ctrl_status_undef = 0; - } else { - status = TP_EC_FAN_AUTO; - } - } - if ((status & (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) != 0) status = fan_control_desired_level; @@ -6458,29 +6496,7 @@ static int __init fan_init(struct ibm_init_struct *iibm) if (likely(acpi_ec_read(fan_status_offset, &fan_control_initial_status))) { fan_status_access_mode = TPACPI_FAN_RD_TPEC; - - /* In some ThinkPads, neither the EC nor the ACPI - * DSDT initialize the fan status, and it ends up - * being set to 0x07 when it *could* be either - * 0x07 or 0x80. - * - * Enable for TP-1Y (T43), TP-78 (R51e), - * TP-76 (R52), TP-70 (T43, R52), which are known - * to be buggy. */ - if (fan_control_initial_status == 0x07) { - switch (thinkpad_id.ec_model) { - case 0x5931: /* TP-1Y */ - case 0x3837: /* TP-78 */ - case 0x3637: /* TP-76 */ - case 0x3037: /* TP-70 */ - printk(TPACPI_NOTICE - "fan_init: initial fan status " - "is unknown, assuming it is " - "in auto mode\n"); - tp_features.fan_ctrl_status_undef = 1; - ;; - } - } + fan_quirk1_detect(); } else { printk(TPACPI_ERR "ThinkPad ACPI EC access misbehaving, " @@ -6669,15 +6685,6 @@ static int fan_read(char *p) if (rc < 0) return rc; - if (unlikely(tp_features.fan_ctrl_status_undef)) { - if (status != fan_control_initial_status) - tp_features.fan_ctrl_status_undef = 0; - else - /* Return most likely status. In fact, it - * might be the only possible status */ - status = TP_EC_FAN_AUTO; - } - len += sprintf(p + len, "status:\t\t%s\n", (status != 0) ? "enabled" : "disabled"); -- cgit From 54926ce8d2db7ebcbc4b80aae2cec571cd793e46 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 11 Jan 2009 03:01:09 -0200 Subject: ACPI: thinkpad-acpi: handle HKEY event 6030 HKEY event 0x6030 is a helper for Lenovo's Advanced Thermal Management Windows driver, which is, of course, completely undocumented. Silence any warnings about it being an unknown alarm, and report it unmodified for userspace. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- drivers/platform/x86/thinkpad_acpi.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 213219d938e..886a4306e78 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -2702,6 +2702,12 @@ static bool hotkey_notify_thermal(const u32 hkey, "a sensor reports something is extremely hot!\n"); /* recommended action: immediate sleep/hibernate */ return true; + case 0x6030: + printk(TPACPI_INFO + "EC reports that Thermal Table has changed\n"); + /* recommended action: do nothing, we don't have + * Lenovo ATM information */ + return true; default: printk(TPACPI_ALERT "THERMAL ALERT: unknown thermal alarm received\n"); -- cgit From aa2fbcec07b0d594808bc3058692395d24eba66e Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 11 Jan 2009 03:01:10 -0200 Subject: ACPI: thinkpad-acpi: bump up version to 0.22 It is about time to bump up the version. Features added since 0.21: fan suspend/resume support, preserve radio state across power off (for some radio types), built-in UWB radio rfkill support and thermal alarm events support. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- Documentation/laptops/thinkpad-acpi.txt | 6 +++--- drivers/platform/x86/thinkpad_acpi.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt index 91c00010b15..41bc99fa188 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt @@ -1,7 +1,7 @@ ThinkPad ACPI Extras Driver - Version 0.21 - May 29th, 2008 + Version 0.22 + November 23rd, 2008 Borislav Deianov Henrique de Moraes Holschuh @@ -17,7 +17,7 @@ This driver used to be named ibm-acpi until kernel 2.6.21 and release 0.13-20070314. It used to be in the drivers/acpi tree, but it was moved to the drivers/misc tree and renamed to thinkpad-acpi for kernel 2.6.22, and release 0.14. It was moved to drivers/platform/x86 for -kernel 2.6.29. +kernel 2.6.29 and release 0.22. The driver is named "thinkpad-acpi". In some places, like module names, "thinkpad_acpi" is used because of userspace issues. diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 886a4306e78..bcbc05107ba 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -21,7 +21,7 @@ * 02110-1301, USA. */ -#define TPACPI_VERSION "0.21" +#define TPACPI_VERSION "0.22" #define TPACPI_SYSFS_VERSION 0x020200 /* -- cgit From 6272d68cc6a5f90c6b1a2228cf0f67b895305d17 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Thu, 15 Jan 2009 17:17:15 +0100 Subject: sched: sched_slice() fixlet Mike's change: 0a582440f "sched: fix sched_slice())" broke group scheduling by forgetting to reload cfs_rq on each loop. This patch fixes aim7 regression and specjbb2005 regression becomes less than 1.5% on 8-core stokley. Signed-off-by: Lin Ming Signed-off-by: Peter Zijlstra Tested-by: Jayson King Signed-off-by: Ingo Molnar --- kernel/sched_fair.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 16b419bb8b0..5cc1c162044 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -429,7 +429,10 @@ static u64 sched_slice(struct cfs_rq *cfs_rq, struct sched_entity *se) u64 slice = __sched_period(cfs_rq->nr_running + !se->on_rq); for_each_sched_entity(se) { - struct load_weight *load = &cfs_rq->load; + struct load_weight *load; + + cfs_rq = cfs_rq_of(se); + load = &cfs_rq->load; if (unlikely(!se->on_rq)) { struct load_weight lw = cfs_rq->load; -- cgit From c0253eec2a8e1140dd9672a1efe095cdcf5811d0 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 15 Jan 2009 13:30:25 +0000 Subject: tty: Fix race in the flush for some ldiscs If you issue an ioctl to flush a tty as the line discipline is changing or otherwise unplugged you can get a crash. The bug is very old but the rest of the BKL lock dropping and some very "good" luck on Ingo's part caught an example. Use the correct ldisc_ref form so that we wait for the ldisc change to complete and then flush Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/char/tty_ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index a408c8e487e..6f4c7d0a53b 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c @@ -1057,7 +1057,7 @@ int tty_perform_flush(struct tty_struct *tty, unsigned long arg) if (retval) return retval; - ld = tty_ldisc_ref(tty); + ld = tty_ldisc_ref_wait(tty); switch (arg) { case TCIFLUSH: if (ld && ld->ops->flush_buffer) -- cgit From 25cf9bc1fcb085daaeb82b09bab0fb3c40570887 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 15 Jan 2009 13:30:34 +0000 Subject: 8250_pci: add support for netmos 9835 IBM devices Most of netmos 9835 hardware is handled by parport-serial. IBM introduces a device which doesn't have any parallel ports and have screwed subdevice PCI id (not corresponding to port numbers). Handle this device (9710:9835 1014:0299) properly. Signed-off-by: Jiri Slaby Signed-off-by: Andrew Morton Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/serial/8250_pci.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index c088146b751..2a3671233b1 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c @@ -602,6 +602,10 @@ static int pci_netmos_init(struct pci_dev *dev) /* subdevice 0x00PS means

parallel, serial */ unsigned int num_serial = dev->subsystem_device & 0xf; + if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM && + dev->subsystem_device == 0x0299) + return 0; + if (num_serial == 0) return -ENODEV; return num_serial; @@ -3096,6 +3100,10 @@ static struct pci_device_id serial_pci_tbl[] = { 0, pbn_b0_8_115200 }, + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835, + PCI_VENDOR_ID_IBM, 0x0299, + 0, 0, pbn_b0_bt_2_115200 }, + /* * These entries match devices with class COMMUNICATION_SERIAL, * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL -- cgit From 7fdd4f76e9a289592d020538f1837a7541ea89ff Mon Sep 17 00:00:00 2001 From: Daniel Gagnon Date: Thu, 15 Jan 2009 13:30:45 +0000 Subject: serial: Add SupraExpress 336i PnP Voice Modem Add SupraExpress 336i PnP Voice Modem Tested and working with the following device: (output from lspnp -v) 01:01.00 SUP1381 (unknown) state = active io 0x2f8-0x2ff irq 3 Signed-off-by: Daniel Gagnon Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/serial/8250_pnp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c index fde7f9ccf57..bbcfc26a3b6 100644 --- a/drivers/serial/8250_pnp.c +++ b/drivers/serial/8250_pnp.c @@ -270,6 +270,8 @@ static const struct pnp_device_id pnp_dev_table[] = { { "RSS0250", 0 }, /* SupraExpress 28.8 Data/Fax PnP modem */ { "SUP1310", 0 }, + /* SupraExpress 336i PnP Voice Modem */ + { "SUP1381", 0 }, /* SupraExpress 33.6 Data/Fax PnP modem */ { "SUP1421", 0 }, /* SupraExpress 33.6 Data/Fax PnP modem */ -- cgit From cd1e40f0981e22018373307cd4087dc876b08fb0 Mon Sep 17 00:00:00 2001 From: Mischa Jonker Date: Thu, 15 Jan 2009 13:30:56 +0000 Subject: When a break signal is detected, the next character should be ignored. This was not implemented correctly for the pnx8xxx_uart driver. [From further discussion: Correct, you can look to it as two separate bugs: a) the next character is not ignored while it should; b) the status bits 31-8 are copied to the 'ch' variable while they shouldn't. Both bugs prevent correct break signal handling (and therefore correct behaviour of the magic SysRq key). Bug b didn't cause too much trouble earlier because in most situations the status bits are all zero; for this case they unfortunately aren't. ] Signed-off-by: Mischa Jonker Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/serial/pnx8xxx_uart.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/serial/pnx8xxx_uart.c b/drivers/serial/pnx8xxx_uart.c index 22e30d21225..1bb8f1b4576 100644 --- a/drivers/serial/pnx8xxx_uart.c +++ b/drivers/serial/pnx8xxx_uart.c @@ -187,7 +187,7 @@ static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport) status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) | ISTAT_TO_SM(serial_in(sport, PNX8XXX_ISTAT)); while (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFIFO)) { - ch = serial_in(sport, PNX8XXX_FIFO); + ch = serial_in(sport, PNX8XXX_FIFO) & 0xff; sport->port.icount.rx++; @@ -198,9 +198,16 @@ static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport) * out of the main execution path */ if (status & (FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE | - PNX8XXX_UART_FIFO_RXPAR) | + PNX8XXX_UART_FIFO_RXPAR | + PNX8XXX_UART_FIFO_RXBRK) | ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN))) { - if (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR)) + if (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXBRK)) { + status &= ~(FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE) | + FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR)); + sport->port.icount.brk++; + if (uart_handle_break(&sport->port)) + goto ignore_char; + } else if (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR)) sport->port.icount.parity++; else if (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE)) sport->port.icount.frame++; @@ -284,14 +291,8 @@ static irqreturn_t pnx8xxx_int(int irq, void *dev_id) /* Get the interrupts */ status = serial_in(sport, PNX8XXX_ISTAT) & serial_in(sport, PNX8XXX_IEN); - /* Break signal received */ - if (status & PNX8XXX_UART_INT_BREAK) { - sport->port.icount.brk++; - uart_handle_break(&sport->port); - } - - /* Byte received */ - if (status & PNX8XXX_UART_INT_RX) + /* Byte or break signal received */ + if (status & (PNX8XXX_UART_INT_RX | PNX8XXX_UART_INT_BREAK)) pnx8xxx_rx_chars(sport); /* TX holding register empty - transmit a byte */ -- cgit From a9fec7102f01f6464b19e13ffd9d8c48663379ad Mon Sep 17 00:00:00 2001 From: Jim Paris Date: Thu, 15 Jan 2009 13:31:07 +0000 Subject: ftdi_sio: fix kref leak Commit 4a90f09b20f4622dcbff1f0e1e6bae1704f8ad8c added kref stuff to ftdi_sio, but missed tty_kref_put at one exit point in ftdi_process_read. Signed-off-by: Jim Paris Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/usb/serial/ftdi_sio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index ef6cfa5a447..c70a8f667d8 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -2030,7 +2030,7 @@ static void ftdi_process_read(struct work_struct *work) spin_unlock_irqrestore(&priv->rx_lock, flags); dbg("%s - deferring remainder until unthrottled", __func__); - return; + goto out; } spin_unlock_irqrestore(&priv->rx_lock, flags); /* if the port is closed stop trying to read */ -- cgit From fe41cbb164a0dc55f3914a0e4cabe8240410157c Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 15 Jan 2009 13:31:15 +0000 Subject: tty: Fix a kref leak in the HSO driver on re-open Signed-off-by: Linus Torvalds --- drivers/net/usb/hso.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index c4918b86ed1..9df04dd1332 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1297,6 +1297,7 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp) /* setup */ spin_lock_irq(&serial->serial_lock); tty->driver_data = serial; + tty_kref_put(serial->tty); serial->tty = tty_kref_get(tty); spin_unlock_irq(&serial->serial_lock); -- cgit From d45eb81c3e345fabaf27ef3ab437b85c0bf9fafa Mon Sep 17 00:00:00 2001 From: Denis Joseph Barrow Date: Thu, 15 Jan 2009 13:31:24 +0000 Subject: tty: Fix double grabbing of a spinlock The HSO changes for kref introduced a recursive spinlock take. All functions which call put_rxbuf_data already have serial->serial_lock grabbed. [Comment to code added-AC] Signed-off-by: Denis Joseph Barrow Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/net/usb/hso.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 9df04dd1332..e25a58f6ff6 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -2044,9 +2044,8 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial) return -2; } - spin_lock(&serial->serial_lock); + /* All callers to put_rxbuf_data hold serial_lock */ tty = tty_kref_get(serial->tty); - spin_unlock(&serial->serial_lock); /* Push data to tty */ if (tty) { -- cgit From 5839b414f9f9d2d6a471988763b61dbf85eb2dba Mon Sep 17 00:00:00 2001 From: Denis Joseph Barrow Date: Thu, 15 Jan 2009 13:31:34 +0000 Subject: hso serial throttled tty kref fix. This patch is for Alan Cox as it related to the tty layer. Hopefully the hso driver is again relatively stable with this fix. Signed-off-by: Denis Joseph Barrow Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/net/usb/hso.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index e25a58f6ff6..6478bf63f28 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -2053,8 +2053,10 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial) serial->curr_rx_urb_offset; D1("data to push to tty"); while (write_length_remaining) { - if (test_bit(TTY_THROTTLED, &tty->flags)) + if (test_bit(TTY_THROTTLED, &tty->flags)) { + tty_kref_put(tty); return -1; + } curr_write_len = tty_insert_flip_string (tty, urb->transfer_buffer + serial->curr_rx_urb_offset, -- cgit From cbbc49877d44408c4d0decf77c3c141732bbc679 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 15 Jan 2009 19:12:51 +0000 Subject: CREDITS address update for dwmw2. Update employer's care-of address in CREDITS file, and remove references to some _very_ old stuff I'd forgotten I'd ever done. Signed-off-by: David Woodhouse Signed-off-by: Linus Torvalds --- CREDITS | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/CREDITS b/CREDITS index 939da46a87f..2b39168c06a 100644 --- a/CREDITS +++ b/CREDITS @@ -3786,14 +3786,11 @@ S: The Netherlands N: David Woodhouse E: dwmw2@infradead.org -D: ARCnet stuff, Applicom board driver, SO_BINDTODEVICE, -D: some Alpha platform porting from 2.0, Memory Technology Devices, -D: Acquire watchdog timer, PC speaker driver maintenance, +D: JFFS2 file system, Memory Technology Device subsystem, D: various other stuff that annoyed me by not working. -S: c/o Red Hat Engineering -S: Rustat House -S: 60 Clifton Road -S: Cambridge. CB1 7EG +S: c/o Intel Corporation +S: Pipers Way +S: Swindon. SN3 1RJ S: England N: Chris Wright -- cgit From bb9a35f293a3c8b5d57253cdfe2f29fa2627e1b9 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Thu, 15 Jan 2009 22:27:46 +0100 Subject: hwmon: (k8temp) Warn about fam F rev F errata Add warning about wrong CPU temperature readouts on all fam F rev F. The allowed combinations of processors ensure that all processors in a multisocket system have similar characteristics, e.g. (1) provide temperature sensor interface (>=RevC && =RevF) Thus it is sufficient to check the revision of the boot CPU. For "mixed silicon support" refer to "Revision Guide for AMD Athlon 64 and AMD Opteron Processors" (RevA-E) and "Revision Guide for AMD NPT Family 0Fh Processors" (RefF-G). Cc: Rudolf Marek Signed-off-by: Andreas Herrmann Signed-off-by: Jean Delvare --- drivers/hwmon/k8temp.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c index bd2bde0ef95..ca56f2e26fd 100644 --- a/drivers/hwmon/k8temp.c +++ b/drivers/hwmon/k8temp.c @@ -31,6 +31,7 @@ #include #include #include +#include #define TEMP_FROM_REG(val) (((((val) >> 16) & 0xff) - 49) * 1000) #define REG_TEMP 0xe4 @@ -141,20 +142,34 @@ static int __devinit k8temp_probe(struct pci_dev *pdev, int err; u8 scfg; u32 temp; + u8 model, stepping; struct k8temp_data *data; - u32 cpuid = cpuid_eax(1); - - /* this feature should be available since SH-C0 core */ - if ((cpuid == 0xf40) || (cpuid == 0xf50) || (cpuid == 0xf51)) { - err = -ENODEV; - goto exit; - } if (!(data = kzalloc(sizeof(struct k8temp_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } + model = boot_cpu_data.x86_model; + stepping = boot_cpu_data.x86_mask; + + switch (boot_cpu_data.x86) { + case 0xf: + /* feature available since SH-C0, exclude older revisions */ + if (((model == 4) && (stepping == 0)) || + ((model == 5) && (stepping <= 1))) { + err = -ENODEV; + goto exit_free; + } + + if (model >= 0x40) { + dev_warn(&pdev->dev, "Temperature readouts might be " + "wrong - check erratum #141\n"); + } + + break; + } + pci_read_config_byte(pdev, REG_TEMP, &scfg); scfg &= ~(SEL_PLACE | SEL_CORE); /* Select sensor 0, core0 */ pci_write_config_byte(pdev, REG_TEMP, scfg); -- cgit From a2e066bba2aad6583e3ff648bf28339d6c9f0898 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Thu, 15 Jan 2009 22:27:47 +0100 Subject: hwmon: (k8temp) Fix wrong sensor selection for AMD K8 RevF/RevG CPUs Meaning of ThermSenseCoreSel bit was inverted beginning with K8 RevF. That means with current driver temp1/temp2 belong to core 1 and temp3/temp4 belong to core 0 on a K8 RevF/RevG CPU. This patch ensures that temp1/temp2 always belong to core 0 and temp3/temp4 to core 1 for all K8 revisions. Cc: Rudolf Marek Signed-off-by: Andreas Herrmann Signed-off-by: Jean Delvare --- drivers/hwmon/k8temp.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c index ca56f2e26fd..a6381bc9189 100644 --- a/drivers/hwmon/k8temp.c +++ b/drivers/hwmon/k8temp.c @@ -48,6 +48,7 @@ struct k8temp_data { /* registers values */ u8 sensorsp; /* sensor presence bits - SEL_CORE & SEL_PLACE */ u32 temp[2][2]; /* core, place */ + u8 swap_core_select; /* meaning of SEL_CORE is inverted */ }; static struct k8temp_data *k8temp_update_device(struct device *dev) @@ -117,6 +118,9 @@ static ssize_t show_temp(struct device *dev, int place = attr->index; struct k8temp_data *data = k8temp_update_device(dev); + if (data->swap_core_select) + core = core ? 0 : 1; + return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[core][place])); } @@ -162,7 +166,12 @@ static int __devinit k8temp_probe(struct pci_dev *pdev, goto exit_free; } + /* + * AMD NPT family 0fh, i.e. RevF and RevG: + * meaning of SEL_CORE bit is inverted + */ if (model >= 0x40) { + data->swap_core_select = 1; dev_warn(&pdev->dev, "Temperature readouts might be " "wrong - check erratum #141\n"); } -- cgit From 76ff08da34196cfa308fcd3552bb9ea20888e745 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Thu, 15 Jan 2009 22:27:47 +0100 Subject: hwmon: (k8temp) Fix temperature reporting for (most) K8 RevG CPUs Current Temperature for K8 RevG desktop CPUs is a "normalized value" which can be below ambient temperature. As a consequence lots of RevG systems report temperatures like: $ sensors k8temp-pci-00c3 Adapter: PCI adapter Core0 Temp: +17 C Core0 Temp: +3 C Core1 Temp: +21 C Core1 Temp: +5 C being quite below ambient temperature. There are even reports of negative temperature values. This patch corrects the temperature reporting of k8temp for RevG desktop CPUs. Cc: Rudolf Marek Signed-off-by: Andreas Herrmann Signed-off-by: Jean Delvare --- drivers/hwmon/k8temp.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c index a6381bc9189..1fe99511184 100644 --- a/drivers/hwmon/k8temp.c +++ b/drivers/hwmon/k8temp.c @@ -49,6 +49,7 @@ struct k8temp_data { u8 sensorsp; /* sensor presence bits - SEL_CORE & SEL_PLACE */ u32 temp[2][2]; /* core, place */ u8 swap_core_select; /* meaning of SEL_CORE is inverted */ + u32 temp_offset; }; static struct k8temp_data *k8temp_update_device(struct device *dev) @@ -116,13 +117,15 @@ static ssize_t show_temp(struct device *dev, to_sensor_dev_attr_2(devattr); int core = attr->nr; int place = attr->index; + int temp; struct k8temp_data *data = k8temp_update_device(dev); if (data->swap_core_select) core = core ? 0 : 1; - return sprintf(buf, "%d\n", - TEMP_FROM_REG(data->temp[core][place])); + temp = TEMP_FROM_REG(data->temp[core][place]) + data->temp_offset; + + return sprintf(buf, "%d\n", temp); } /* core, place */ @@ -176,6 +179,16 @@ static int __devinit k8temp_probe(struct pci_dev *pdev, "wrong - check erratum #141\n"); } + if ((model >= 0x69) && + !(model == 0xc1 || model == 0x6c || model == 0x7c)) { + /* + * RevG desktop CPUs (i.e. no socket S1G1 parts) + * need additional offset, otherwise reported + * temperature is below ambient temperature + */ + data->temp_offset = 21000; + } + break; } -- cgit From 1c301fc5394f7e1aa4c201e6e03d55d9c08b3bdf Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Thu, 15 Jan 2009 22:27:47 +0100 Subject: hwmon: Add a driver for the ADT7475 hardware monitoring chip Hwmon driver for the ADT7475 chip. Signed-off-by: Jordan Crouse Signed-off-by: Hans de Goede Signed-off-by: Jean Delvare --- Documentation/hwmon/adt7475 | 87 +++ drivers/hwmon/Kconfig | 10 + drivers/hwmon/Makefile | 2 + drivers/hwmon/adt7475.c | 1221 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1320 insertions(+) create mode 100644 Documentation/hwmon/adt7475 create mode 100644 drivers/hwmon/adt7475.c diff --git a/Documentation/hwmon/adt7475 b/Documentation/hwmon/adt7475 new file mode 100644 index 00000000000..a2b1abec850 --- /dev/null +++ b/Documentation/hwmon/adt7475 @@ -0,0 +1,87 @@ +This describes the interface for the ADT7475 driver: + +(there are 4 fans, numbered fan1 to fan4): + +fanX_input Read the current speed of the fan (in RPMs) +fanX_min Read/write the minimum speed of the fan. Dropping + below this sets an alarm. + +(there are three PWMs, numbered pwm1 to pwm3): + +pwmX Read/write the current duty cycle of the PWM. Writes + only have effect when auto mode is turned off (see + below). Range is 0 - 255. + +pwmX_enable Fan speed control method: + + 0 - No control (fan at full speed) + 1 - Manual fan speed control (using pwm[1-*]) + 2 - Automatic fan speed control + +pwmX_auto_channels_temp Select which channels affect this PWM + + 1 - TEMP1 controls PWM + 2 - TEMP2 controls PWM + 4 - TEMP3 controls PWM + 6 - TEMP2 and TEMP3 control PWM + 7 - All three inputs control PWM + +pwmX_freq Read/write the PWM frequency in Hz. The number + should be one of the following: + + 11 Hz + 14 Hz + 22 Hz + 29 Hz + 35 Hz + 44 Hz + 58 Hz + 88 Hz + +pwmX_auto_point1_pwm Read/write the minimum PWM duty cycle in automatic mode + +pwmX_auto_point2_pwm Read/write the maximum PWM duty cycle in automatic mode + +(there are three temperature settings numbered temp1 to temp3): + +tempX_input Read the current temperature. The value is in milli + degrees of Celsius. + +tempX_max Read/write the upper temperature limit - exceeding this + will cause an alarm. + +tempX_min Read/write the lower temperature limit - exceeding this + will cause an alarm. + +tempX_offset Read/write the temperature adjustment offset + +tempX_crit Read/write the THERM limit for remote1. + +tempX_crit_hyst Set the temperature value below crit where the + fans will stay on - this helps drive the temperature + low enough so it doesn't stay near the edge and + cause THERM to keep tripping. + +tempX_auto_point1_temp Read/write the minimum temperature where the fans will + turn on in automatic mode. + +tempX_auto_point2_temp Read/write the maximum temperature over which the fans + will run in automatic mode. tempX_auto_point1_temp + and tempX_auto_point2_temp together define the + range of automatic control. + +tempX_alarm Read a 1 if the max/min alarm is set +tempX_fault Read a 1 if either temp1 or temp3 diode has a fault + +(There are two voltage settings, in1 and in2): + +inX_input Read the current voltage on VCC. Value is in + millivolts. + +inX_min read/write the minimum voltage limit. + Dropping below this causes an alarm. + +inX_max read/write the maximum voltage limit. + Exceeding this causes an alarm. + +inX_alarm Read a 1 if the max/min alarm is set. diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 4b33bc82cc2..5c349a19a3a 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -189,6 +189,16 @@ config SENSORS_ADT7473 This driver can also be built as a module. If so, the module will be called adt7473. +config SENSORS_ADT7475 + tristate "Analog Devices ADT7475" + depends on I2C && EXPERIMENTAL + help + If you say yes here you get support for the Analog Devices + ADT7475 hardware monitoring chips. + + This driver can also be build as a module. If so, the module + will be called adt7475. + config SENSORS_K8TEMP tristate "AMD Athlon64/FX or Opteron temperature sensor" depends on X86 && PCI && EXPERIMENTAL diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 19cb1ace3eb..2e80f37f39e 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -28,6 +28,8 @@ obj-$(CONFIG_SENSORS_ADS7828) += ads7828.o obj-$(CONFIG_SENSORS_ADT7462) += adt7462.o obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o obj-$(CONFIG_SENSORS_ADT7473) += adt7473.o +obj-$(CONFIG_SENSORS_ADT7475) += adt7475.o + obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o obj-$(CONFIG_SENSORS_AMS) += ams/ obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c new file mode 100644 index 00000000000..d39877a7da6 --- /dev/null +++ b/drivers/hwmon/adt7475.c @@ -0,0 +1,1221 @@ +/* + * adt7475 - Thermal sensor driver for the ADT7475 chip and derivatives + * Copyright (C) 2007-2008, Advanced Micro Devices, Inc. + * Copyright (C) 2008 Jordan Crouse + * Copyright (C) 2008 Hans de Goede + + * Derived from the lm83 driver by Jean Delvare + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Indexes for the sysfs hooks */ + +#define INPUT 0 +#define MIN 1 +#define MAX 2 +#define CONTROL 3 +#define OFFSET 3 +#define AUTOMIN 4 +#define THERM 5 +#define HYSTERSIS 6 + +/* These are unique identifiers for the sysfs functions - unlike the + numbers above, these are not also indexes into an array +*/ + +#define ALARM 9 +#define FAULT 10 + +/* 7475 Common Registers */ + +#define REG_VOLTAGE_BASE 0x21 +#define REG_TEMP_BASE 0x25 +#define REG_TACH_BASE 0x28 +#define REG_PWM_BASE 0x30 +#define REG_PWM_MAX_BASE 0x38 + +#define REG_DEVID 0x3D +#define REG_VENDID 0x3E + +#define REG_STATUS1 0x41 +#define REG_STATUS2 0x42 + +#define REG_VOLTAGE_MIN_BASE 0x46 +#define REG_VOLTAGE_MAX_BASE 0x47 + +#define REG_TEMP_MIN_BASE 0x4E +#define REG_TEMP_MAX_BASE 0x4F + +#define REG_TACH_MIN_BASE 0x54 + +#define REG_PWM_CONFIG_BASE 0x5C + +#define REG_TEMP_TRANGE_BASE 0x5F + +#define REG_PWM_MIN_BASE 0x64 + +#define REG_TEMP_TMIN_BASE 0x67 +#define REG_TEMP_THERM_BASE 0x6A + +#define REG_REMOTE1_HYSTERSIS 0x6D +#define REG_REMOTE2_HYSTERSIS 0x6E + +#define REG_TEMP_OFFSET_BASE 0x70 + +#define REG_EXTEND1 0x76 +#define REG_EXTEND2 0x77 +#define REG_CONFIG5 0x7C + +#define CONFIG5_TWOSCOMP 0x01 +#define CONFIG5_TEMPOFFSET 0x02 + +/* ADT7475 Settings */ + +#define ADT7475_VOLTAGE_COUNT 2 +#define ADT7475_TEMP_COUNT 3 +#define ADT7475_TACH_COUNT 4 +#define ADT7475_PWM_COUNT 3 + +/* Macro to read the registers */ + +#define adt7475_read(reg) i2c_smbus_read_byte_data(client, (reg)) + +/* Macros to easily index the registers */ + +#define TACH_REG(idx) (REG_TACH_BASE + ((idx) * 2)) +#define TACH_MIN_REG(idx) (REG_TACH_MIN_BASE + ((idx) * 2)) + +#define PWM_REG(idx) (REG_PWM_BASE + (idx)) +#define PWM_MAX_REG(idx) (REG_PWM_MAX_BASE + (idx)) +#define PWM_MIN_REG(idx) (REG_PWM_MIN_BASE + (idx)) +#define PWM_CONFIG_REG(idx) (REG_PWM_CONFIG_BASE + (idx)) + +#define VOLTAGE_REG(idx) (REG_VOLTAGE_BASE + (idx)) +#define VOLTAGE_MIN_REG(idx) (REG_VOLTAGE_MIN_BASE + ((idx) * 2)) +#define VOLTAGE_MAX_REG(idx) (REG_VOLTAGE_MAX_BASE + ((idx) * 2)) + +#define TEMP_REG(idx) (REG_TEMP_BASE + (idx)) +#define TEMP_MIN_REG(idx) (REG_TEMP_MIN_BASE + ((idx) * 2)) +#define TEMP_MAX_REG(idx) (REG_TEMP_MAX_BASE + ((idx) * 2)) +#define TEMP_TMIN_REG(idx) (REG_TEMP_TMIN_BASE + (idx)) +#define TEMP_THERM_REG(idx) (REG_TEMP_THERM_BASE + (idx)) +#define TEMP_OFFSET_REG(idx) (REG_TEMP_OFFSET_BASE + (idx)) +#define TEMP_TRANGE_REG(idx) (REG_TEMP_TRANGE_BASE + (idx)) + +static unsigned short normal_i2c[] = { 0x2e, I2C_CLIENT_END }; + +I2C_CLIENT_INSMOD_1(adt7475); + +static const struct i2c_device_id adt7475_id[] = { + { "adt7475", adt7475 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, adt7475_id); + +struct adt7475_data { + struct device *hwmon_dev; + struct mutex lock; + + unsigned long measure_updated; + unsigned long limits_updated; + char valid; + + u8 config5; + u16 alarms; + u16 voltage[3][3]; + u16 temp[7][3]; + u16 tach[2][4]; + u8 pwm[4][3]; + u8 range[3]; + u8 pwmctl[3]; + u8 pwmchan[3]; +}; + +static struct i2c_driver adt7475_driver; +static struct adt7475_data *adt7475_update_device(struct device *dev); +static void adt7475_read_hystersis(struct i2c_client *client); +static void adt7475_read_pwm(struct i2c_client *client, int index); + +/* Given a temp value, convert it to register value */ + +static inline u16 temp2reg(struct adt7475_data *data, long val) +{ + u16 ret; + + if (!(data->config5 & CONFIG5_TWOSCOMP)) { + val = SENSORS_LIMIT(val, -64000, 191000); + ret = (val + 64500) / 1000; + } else { + val = SENSORS_LIMIT(val, -128000, 127000); + if (val < -500) + ret = (256500 + val) / 1000; + else + ret = (val + 500) / 1000; + } + + return ret << 2; +} + +/* Given a register value, convert it to a real temp value */ + +static inline int reg2temp(struct adt7475_data *data, u16 reg) +{ + if (data->config5 & CONFIG5_TWOSCOMP) { + if (reg >= 512) + return (reg - 1024) * 250; + else + return reg * 250; + } else + return (reg - 256) * 250; +} + +static inline int tach2rpm(u16 tach) +{ + if (tach == 0 || tach == 0xFFFF) + return 0; + + return (90000 * 60) / tach; +} + +static inline u16 rpm2tach(unsigned long rpm) +{ + if (rpm == 0) + return 0; + + return SENSORS_LIMIT((90000 * 60) / rpm, 1, 0xFFFF); +} + +static inline int reg2vcc(u16 reg) +{ + return (4296 * reg) / 1000; +} + +static inline int reg2vccp(u16 reg) +{ + return (2929 * reg) / 1000; +} + +static inline u16 vcc2reg(long vcc) +{ + vcc = SENSORS_LIMIT(vcc, 0, 4396); + return (vcc * 1000) / 4296; +} + +static inline u16 vccp2reg(long vcc) +{ + vcc = SENSORS_LIMIT(vcc, 0, 2998); + return (vcc * 1000) / 2929; +} + +static u16 adt7475_read_word(struct i2c_client *client, int reg) +{ + u16 val; + + val = i2c_smbus_read_byte_data(client, reg); + val |= (i2c_smbus_read_byte_data(client, reg + 1) << 8); + + return val; +} + +static void adt7475_write_word(struct i2c_client *client, int reg, u16 val) +{ + i2c_smbus_write_byte_data(client, reg + 1, val >> 8); + i2c_smbus_write_byte_data(client, reg, val & 0xFF); +} + +/* Find the nearest value in a table - used for pwm frequency and + auto temp range */ +static int find_nearest(long val, const int *array, int size) +{ + int i; + + if (val < array[0]) + return 0; + + if (val > array[size - 1]) + return size - 1; + + for (i = 0; i < size - 1; i++) { + int a, b; + + if (val > array[i + 1]) + continue; + + a = val - array[i]; + b = array[i + 1] - val; + + return (a <= b) ? i : i + 1; + } + + return 0; +} + +static ssize_t show_voltage(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct adt7475_data *data = adt7475_update_device(dev); + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + unsigned short val; + + switch (sattr->nr) { + case ALARM: + return sprintf(buf, "%d\n", + (data->alarms >> (sattr->index + 1)) & 1); + default: + val = data->voltage[sattr->nr][sattr->index]; + return sprintf(buf, "%d\n", + sattr->index == + 0 ? reg2vccp(val) : reg2vcc(val)); + } +} + +static ssize_t set_voltage(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7475_data *data = i2c_get_clientdata(client); + unsigned char reg; + long val; + + if (strict_strtol(buf, 10, &val)) + return -EINVAL; + + mutex_lock(&data->lock); + + data->voltage[sattr->nr][sattr->index] = + sattr->index ? vcc2reg(val) : vccp2reg(val); + + if (sattr->nr == MIN) + reg = VOLTAGE_MIN_REG(sattr->index); + else + reg = VOLTAGE_MAX_REG(sattr->index); + + i2c_smbus_write_byte_data(client, reg, + data->voltage[sattr->nr][sattr->index] >> 2); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_temp(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct adt7475_data *data = adt7475_update_device(dev); + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + int out; + + switch (sattr->nr) { + case HYSTERSIS: + mutex_lock(&data->lock); + out = data->temp[sattr->nr][sattr->index]; + if (sattr->index != 1) + out = (out >> 4) & 0xF; + else + out = (out & 0xF); + /* Show the value as an absolute number tied to + * THERM */ + out = reg2temp(data, data->temp[THERM][sattr->index]) - + out * 1000; + mutex_unlock(&data->lock); + break; + + case OFFSET: + /* Offset is always 2's complement, regardless of the + * setting in CONFIG5 */ + mutex_lock(&data->lock); + out = (s8)data->temp[sattr->nr][sattr->index]; + if (data->config5 & CONFIG5_TEMPOFFSET) + out *= 1000; + else + out *= 500; + mutex_unlock(&data->lock); + break; + + case ALARM: + out = (data->alarms >> (sattr->index + 4)) & 1; + break; + + case FAULT: + /* Note - only for remote1 and remote2 */ + out = data->alarms & (sattr->index ? 0x8000 : 0x4000); + out = out ? 0 : 1; + break; + + default: + /* All other temp values are in the configured format */ + out = reg2temp(data, data->temp[sattr->nr][sattr->index]); + } + + return sprintf(buf, "%d\n", out); +} + +static ssize_t set_temp(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7475_data *data = i2c_get_clientdata(client); + unsigned char reg = 0; + u8 out; + int temp; + long val; + + if (strict_strtol(buf, 10, &val)) + return -EINVAL; + + mutex_lock(&data->lock); + + /* We need the config register in all cases for temp <-> reg conv. */ + data->config5 = adt7475_read(REG_CONFIG5); + + switch (sattr->nr) { + case OFFSET: + if (data->config5 & CONFIG5_TEMPOFFSET) { + val = SENSORS_LIMIT(val, -63000, 127000); + out = data->temp[OFFSET][sattr->index] = val / 1000; + } else { + val = SENSORS_LIMIT(val, -63000, 64000); + out = data->temp[OFFSET][sattr->index] = val / 500; + } + break; + + case HYSTERSIS: + /* The value will be given as an absolute value, turn it + into an offset based on THERM */ + + /* Read fresh THERM and HYSTERSIS values from the chip */ + data->temp[THERM][sattr->index] = + adt7475_read(TEMP_THERM_REG(sattr->index)) << 2; + adt7475_read_hystersis(client); + + temp = reg2temp(data, data->temp[THERM][sattr->index]); + val = SENSORS_LIMIT(val, temp - 15000, temp); + val = (temp - val) / 1000; + + if (sattr->index != 1) { + data->temp[HYSTERSIS][sattr->index] &= 0xF0; + data->temp[HYSTERSIS][sattr->index] |= (val & 0xF) << 4; + } else { + data->temp[HYSTERSIS][sattr->index] &= 0x0F; + data->temp[HYSTERSIS][sattr->index] |= (val & 0xF); + } + + out = data->temp[HYSTERSIS][sattr->index]; + break; + + default: + data->temp[sattr->nr][sattr->index] = temp2reg(data, val); + + /* We maintain an extra 2 digits of precision for simplicity + * - shift those back off before writing the value */ + out = (u8) (data->temp[sattr->nr][sattr->index] >> 2); + } + + switch (sattr->nr) { + case MIN: + reg = TEMP_MIN_REG(sattr->index); + break; + case MAX: + reg = TEMP_MAX_REG(sattr->index); + break; + case OFFSET: + reg = TEMP_OFFSET_REG(sattr->index); + break; + case AUTOMIN: + reg = TEMP_TMIN_REG(sattr->index); + break; + case THERM: + reg = TEMP_THERM_REG(sattr->index); + break; + case HYSTERSIS: + if (sattr->index != 2) + reg = REG_REMOTE1_HYSTERSIS; + else + reg = REG_REMOTE2_HYSTERSIS; + + break; + } + + i2c_smbus_write_byte_data(client, reg, out); + + mutex_unlock(&data->lock); + return count; +} + +/* Table of autorange values - the user will write the value in millidegrees, + and we'll convert it */ +static const int autorange_table[] = { + 2000, 2500, 3330, 4000, 5000, 6670, 8000, + 10000, 13330, 16000, 20000, 26670, 32000, 40000, + 53330, 80000 +}; + +static ssize_t show_point2(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct adt7475_data *data = adt7475_update_device(dev); + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + int out, val; + + mutex_lock(&data->lock); + out = (data->range[sattr->index] >> 4) & 0x0F; + val = reg2temp(data, data->temp[AUTOMIN][sattr->index]); + mutex_unlock(&data->lock); + + return sprintf(buf, "%d\n", val + autorange_table[out]); +} + +static ssize_t set_point2(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct adt7475_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + int temp; + long val; + + if (strict_strtol(buf, 10, &val)) + return -EINVAL; + + mutex_lock(&data->lock); + + /* Get a fresh copy of the needed registers */ + data->config5 = adt7475_read(REG_CONFIG5); + data->temp[AUTOMIN][sattr->index] = + adt7475_read(TEMP_TMIN_REG(sattr->index)) << 2; + data->range[sattr->index] = + adt7475_read(TEMP_TRANGE_REG(sattr->index)); + + /* The user will write an absolute value, so subtract the start point + to figure the range */ + temp = reg2temp(data, data->temp[AUTOMIN][sattr->index]); + val = SENSORS_LIMIT(val, temp + autorange_table[0], + temp + autorange_table[ARRAY_SIZE(autorange_table) - 1]); + val -= temp; + + /* Find the nearest table entry to what the user wrote */ + val = find_nearest(val, autorange_table, ARRAY_SIZE(autorange_table)); + + data->range[sattr->index] &= ~0xF0; + data->range[sattr->index] |= val << 4; + + i2c_smbus_write_byte_data(client, TEMP_TRANGE_REG(sattr->index), + data->range[sattr->index]); + + mutex_unlock(&data->lock); + return count; +} + +static ssize_t show_tach(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct adt7475_data *data = adt7475_update_device(dev); + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + int out; + + if (sattr->nr == ALARM) + out = (data->alarms >> (sattr->index + 10)) & 1; + else + out = tach2rpm(data->tach[sattr->nr][sattr->index]); + + return sprintf(buf, "%d\n", out); +} + +static ssize_t set_tach(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7475_data *data = i2c_get_clientdata(client); + unsigned long val; + + if (strict_strtoul(buf, 10, &val)) + return -EINVAL; + + mutex_lock(&data->lock); + + data->tach[MIN][sattr->index] = rpm2tach(val); + + adt7475_write_word(client, TACH_MIN_REG(sattr->index), + data->tach[MIN][sattr->index]); + + mutex_unlock(&data->lock); + return count; +} + +static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct adt7475_data *data = adt7475_update_device(dev); + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + + return sprintf(buf, "%d\n", data->pwm[sattr->nr][sattr->index]); +} + +static ssize_t show_pwmchan(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct adt7475_data *data = adt7475_update_device(dev); + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + + return sprintf(buf, "%d\n", data->pwmchan[sattr->index]); +} + +static ssize_t show_pwmctrl(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct adt7475_data *data = adt7475_update_device(dev); + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + + return sprintf(buf, "%d\n", data->pwmctl[sattr->index]); +} + +static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7475_data *data = i2c_get_clientdata(client); + unsigned char reg = 0; + long val; + + if (strict_strtol(buf, 10, &val)) + return -EINVAL; + + mutex_lock(&data->lock); + + switch (sattr->nr) { + case INPUT: + /* Get a fresh value for CONTROL */ + data->pwm[CONTROL][sattr->index] = + adt7475_read(PWM_CONFIG_REG(sattr->index)); + + /* If we are not in manual mode, then we shouldn't allow + * the user to set the pwm speed */ + if (((data->pwm[CONTROL][sattr->index] >> 5) & 7) != 7) { + mutex_unlock(&data->lock); + return count; + } + + reg = PWM_REG(sattr->index); + break; + + case MIN: + reg = PWM_MIN_REG(sattr->index); + break; + + case MAX: + reg = PWM_MAX_REG(sattr->index); + break; + } + + data->pwm[sattr->nr][sattr->index] = SENSORS_LIMIT(val, 0, 0xFF); + i2c_smbus_write_byte_data(client, reg, + data->pwm[sattr->nr][sattr->index]); + + mutex_unlock(&data->lock); + + return count; +} + +/* Called by set_pwmctrl and set_pwmchan */ + +static int hw_set_pwm(struct i2c_client *client, int index, + unsigned int pwmctl, unsigned int pwmchan) +{ + struct adt7475_data *data = i2c_get_clientdata(client); + long val = 0; + + switch (pwmctl) { + case 0: + val = 0x03; /* Run at full speed */ + break; + case 1: + val = 0x07; /* Manual mode */ + break; + case 2: + switch (pwmchan) { + case 1: + /* Remote1 controls PWM */ + val = 0x00; + break; + case 2: + /* local controls PWM */ + val = 0x01; + break; + case 4: + /* remote2 controls PWM */ + val = 0x02; + break; + case 6: + /* local/remote2 control PWM */ + val = 0x05; + break; + case 7: + /* All three control PWM */ + val = 0x06; + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } + + data->pwmctl[index] = pwmctl; + data->pwmchan[index] = pwmchan; + + data->pwm[CONTROL][index] &= ~0xE0; + data->pwm[CONTROL][index] |= (val & 7) << 5; + + i2c_smbus_write_byte_data(client, PWM_CONFIG_REG(index), + data->pwm[CONTROL][index]); + + return 0; +} + +static ssize_t set_pwmchan(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7475_data *data = i2c_get_clientdata(client); + int r; + long val; + + if (strict_strtol(buf, 10, &val)) + return -EINVAL; + + mutex_lock(&data->lock); + /* Read Modify Write PWM values */ + adt7475_read_pwm(client, sattr->index); + r = hw_set_pwm(client, sattr->index, data->pwmctl[sattr->index], val); + if (r) + count = r; + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t set_pwmctrl(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7475_data *data = i2c_get_clientdata(client); + int r; + long val; + + if (strict_strtol(buf, 10, &val)) + return -EINVAL; + + mutex_lock(&data->lock); + /* Read Modify Write PWM values */ + adt7475_read_pwm(client, sattr->index); + r = hw_set_pwm(client, sattr->index, val, data->pwmchan[sattr->index]); + if (r) + count = r; + mutex_unlock(&data->lock); + + return count; +} + +/* List of frequencies for the PWM */ +static const int pwmfreq_table[] = { + 11, 14, 22, 29, 35, 44, 58, 88 +}; + +static ssize_t show_pwmfreq(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct adt7475_data *data = adt7475_update_device(dev); + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + + return sprintf(buf, "%d\n", + pwmfreq_table[data->range[sattr->index] & 7]); +} + +static ssize_t set_pwmfreq(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7475_data *data = i2c_get_clientdata(client); + int out; + long val; + + if (strict_strtol(buf, 10, &val)) + return -EINVAL; + + out = find_nearest(val, pwmfreq_table, ARRAY_SIZE(pwmfreq_table)); + + mutex_lock(&data->lock); + + data->range[sattr->index] = + adt7475_read(TEMP_TRANGE_REG(sattr->index)); + data->range[sattr->index] &= ~7; + data->range[sattr->index] |= out; + + i2c_smbus_write_byte_data(client, TEMP_TRANGE_REG(sattr->index), + data->range[sattr->index]); + + mutex_unlock(&data->lock); + return count; +} + +static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_voltage, NULL, INPUT, 0); +static SENSOR_DEVICE_ATTR_2(in1_max, S_IRUGO | S_IWUSR, show_voltage, + set_voltage, MAX, 0); +static SENSOR_DEVICE_ATTR_2(in1_min, S_IRUGO | S_IWUSR, show_voltage, + set_voltage, MIN, 0); +static SENSOR_DEVICE_ATTR_2(in1_alarm, S_IRUGO, show_voltage, NULL, ALARM, 0); +static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_voltage, NULL, INPUT, 1); +static SENSOR_DEVICE_ATTR_2(in2_max, S_IRUGO | S_IWUSR, show_voltage, + set_voltage, MAX, 1); +static SENSOR_DEVICE_ATTR_2(in2_min, S_IRUGO | S_IWUSR, show_voltage, + set_voltage, MIN, 1); +static SENSOR_DEVICE_ATTR_2(in2_alarm, S_IRUGO, show_voltage, NULL, ALARM, 1); +static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, INPUT, 0); +static SENSOR_DEVICE_ATTR_2(temp1_alarm, S_IRUGO, show_temp, NULL, ALARM, 0); +static SENSOR_DEVICE_ATTR_2(temp1_fault, S_IRUGO, show_temp, NULL, FAULT, 0); +static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, set_temp, + MAX, 0); +static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR, show_temp, set_temp, + MIN, 0); +static SENSOR_DEVICE_ATTR_2(temp1_offset, S_IRUGO | S_IWUSR, show_temp, + set_temp, OFFSET, 0); +static SENSOR_DEVICE_ATTR_2(temp1_auto_point1_temp, S_IRUGO | S_IWUSR, + show_temp, set_temp, AUTOMIN, 0); +static SENSOR_DEVICE_ATTR_2(temp1_auto_point2_temp, S_IRUGO | S_IWUSR, + show_point2, set_point2, 0, 0); +static SENSOR_DEVICE_ATTR_2(temp1_crit, S_IRUGO | S_IWUSR, show_temp, set_temp, + THERM, 0); +static SENSOR_DEVICE_ATTR_2(temp1_crit_hyst, S_IRUGO | S_IWUSR, show_temp, + set_temp, HYSTERSIS, 0); +static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, INPUT, 1); +static SENSOR_DEVICE_ATTR_2(temp2_alarm, S_IRUGO, show_temp, NULL, ALARM, 1); +static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, set_temp, + MAX, 1); +static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR, show_temp, set_temp, + MIN, 1); +static SENSOR_DEVICE_ATTR_2(temp2_offset, S_IRUGO | S_IWUSR, show_temp, + set_temp, OFFSET, 1); +static SENSOR_DEVICE_ATTR_2(temp2_auto_point1_temp, S_IRUGO | S_IWUSR, + show_temp, set_temp, AUTOMIN, 1); +static SENSOR_DEVICE_ATTR_2(temp2_auto_point2_temp, S_IRUGO | S_IWUSR, + show_point2, set_point2, 0, 1); +static SENSOR_DEVICE_ATTR_2(temp2_crit, S_IRUGO | S_IWUSR, show_temp, set_temp, + THERM, 1); +static SENSOR_DEVICE_ATTR_2(temp2_crit_hyst, S_IRUGO | S_IWUSR, show_temp, + set_temp, HYSTERSIS, 1); +static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, INPUT, 2); +static SENSOR_DEVICE_ATTR_2(temp3_alarm, S_IRUGO, show_temp, NULL, ALARM, 2); +static SENSOR_DEVICE_ATTR_2(temp3_fault, S_IRUGO, show_temp, NULL, FAULT, 2); +static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, set_temp, + MAX, 2); +static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR, show_temp, set_temp, + MIN, 2); +static SENSOR_DEVICE_ATTR_2(temp3_offset, S_IRUGO | S_IWUSR, show_temp, + set_temp, OFFSET, 2); +static SENSOR_DEVICE_ATTR_2(temp3_auto_point1_temp, S_IRUGO | S_IWUSR, + show_temp, set_temp, AUTOMIN, 2); +static SENSOR_DEVICE_ATTR_2(temp3_auto_point2_temp, S_IRUGO | S_IWUSR, + show_point2, set_point2, 0, 2); +static SENSOR_DEVICE_ATTR_2(temp3_crit, S_IRUGO | S_IWUSR, show_temp, set_temp, + THERM, 2); +static SENSOR_DEVICE_ATTR_2(temp3_crit_hyst, S_IRUGO | S_IWUSR, show_temp, + set_temp, HYSTERSIS, 2); +static SENSOR_DEVICE_ATTR_2(fan1_input, S_IRUGO, show_tach, NULL, INPUT, 0); +static SENSOR_DEVICE_ATTR_2(fan1_min, S_IRUGO | S_IWUSR, show_tach, set_tach, + MIN, 0); +static SENSOR_DEVICE_ATTR_2(fan1_alarm, S_IRUGO, show_tach, NULL, ALARM, 0); +static SENSOR_DEVICE_ATTR_2(fan2_input, S_IRUGO, show_tach, NULL, INPUT, 1); +static SENSOR_DEVICE_ATTR_2(fan2_min, S_IRUGO | S_IWUSR, show_tach, set_tach, + MIN, 1); +static SENSOR_DEVICE_ATTR_2(fan2_alarm, S_IRUGO, show_tach, NULL, ALARM, 1); +static SENSOR_DEVICE_ATTR_2(fan3_input, S_IRUGO, show_tach, NULL, INPUT, 2); +static SENSOR_DEVICE_ATTR_2(fan3_min, S_IRUGO | S_IWUSR, show_tach, set_tach, + MIN, 2); +static SENSOR_DEVICE_ATTR_2(fan3_alarm, S_IRUGO, show_tach, NULL, ALARM, 2); +static SENSOR_DEVICE_ATTR_2(fan4_input, S_IRUGO, show_tach, NULL, INPUT, 3); +static SENSOR_DEVICE_ATTR_2(fan4_min, S_IRUGO | S_IWUSR, show_tach, set_tach, + MIN, 3); +static SENSOR_DEVICE_ATTR_2(fan4_alarm, S_IRUGO, show_tach, NULL, ALARM, 3); +static SENSOR_DEVICE_ATTR_2(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm, INPUT, + 0); +static SENSOR_DEVICE_ATTR_2(pwm1_freq, S_IRUGO | S_IWUSR, show_pwmfreq, + set_pwmfreq, INPUT, 0); +static SENSOR_DEVICE_ATTR_2(pwm1_enable, S_IRUGO | S_IWUSR, show_pwmctrl, + set_pwmctrl, INPUT, 0); +static SENSOR_DEVICE_ATTR_2(pwm1_auto_channel_temp, S_IRUGO | S_IWUSR, + show_pwmchan, set_pwmchan, INPUT, 0); +static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO | S_IWUSR, show_pwm, + set_pwm, MIN, 0); +static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO | S_IWUSR, show_pwm, + set_pwm, MAX, 0); +static SENSOR_DEVICE_ATTR_2(pwm2, S_IRUGO | S_IWUSR, show_pwm, set_pwm, INPUT, + 1); +static SENSOR_DEVICE_ATTR_2(pwm2_freq, S_IRUGO | S_IWUSR, show_pwmfreq, + set_pwmfreq, INPUT, 1); +static SENSOR_DEVICE_ATTR_2(pwm2_enable, S_IRUGO | S_IWUSR, show_pwmctrl, + set_pwmctrl, INPUT, 1); +static SENSOR_DEVICE_ATTR_2(pwm2_auto_channel_temp, S_IRUGO | S_IWUSR, + show_pwmchan, set_pwmchan, INPUT, 1); +static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO | S_IWUSR, show_pwm, + set_pwm, MIN, 1); +static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO | S_IWUSR, show_pwm, + set_pwm, MAX, 1); +static SENSOR_DEVICE_ATTR_2(pwm3, S_IRUGO | S_IWUSR, show_pwm, set_pwm, INPUT, + 2); +static SENSOR_DEVICE_ATTR_2(pwm3_freq, S_IRUGO | S_IWUSR, show_pwmfreq, + set_pwmfreq, INPUT, 2); +static SENSOR_DEVICE_ATTR_2(pwm3_enable, S_IRUGO | S_IWUSR, show_pwmctrl, + set_pwmctrl, INPUT, 2); +static SENSOR_DEVICE_ATTR_2(pwm3_auto_channel_temp, S_IRUGO | S_IWUSR, + show_pwmchan, set_pwmchan, INPUT, 2); +static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO | S_IWUSR, show_pwm, + set_pwm, MIN, 2); +static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO | S_IWUSR, show_pwm, + set_pwm, MAX, 2); + +static struct attribute *adt7475_attrs[] = { + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in1_max.dev_attr.attr, + &sensor_dev_attr_in1_min.dev_attr.attr, + &sensor_dev_attr_in1_alarm.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_in2_max.dev_attr.attr, + &sensor_dev_attr_in2_min.dev_attr.attr, + &sensor_dev_attr_in2_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_fault.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp1_offset.dev_attr.attr, + &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr, + &sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr, + &sensor_dev_attr_temp1_crit.dev_attr.attr, + &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp2_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp2_min.dev_attr.attr, + &sensor_dev_attr_temp2_offset.dev_attr.attr, + &sensor_dev_attr_temp2_auto_point1_temp.dev_attr.attr, + &sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr, + &sensor_dev_attr_temp2_crit.dev_attr.attr, + &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp3_fault.dev_attr.attr, + &sensor_dev_attr_temp3_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp3_min.dev_attr.attr, + &sensor_dev_attr_temp3_offset.dev_attr.attr, + &sensor_dev_attr_temp3_auto_point1_temp.dev_attr.attr, + &sensor_dev_attr_temp3_auto_point2_temp.dev_attr.attr, + &sensor_dev_attr_temp3_crit.dev_attr.attr, + &sensor_dev_attr_temp3_crit_hyst.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan1_min.dev_attr.attr, + &sensor_dev_attr_fan1_alarm.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan2_min.dev_attr.attr, + &sensor_dev_attr_fan2_alarm.dev_attr.attr, + &sensor_dev_attr_fan3_input.dev_attr.attr, + &sensor_dev_attr_fan3_min.dev_attr.attr, + &sensor_dev_attr_fan3_alarm.dev_attr.attr, + &sensor_dev_attr_fan4_input.dev_attr.attr, + &sensor_dev_attr_fan4_min.dev_attr.attr, + &sensor_dev_attr_fan4_alarm.dev_attr.attr, + &sensor_dev_attr_pwm1.dev_attr.attr, + &sensor_dev_attr_pwm1_freq.dev_attr.attr, + &sensor_dev_attr_pwm1_enable.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_channel_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, + &sensor_dev_attr_pwm2.dev_attr.attr, + &sensor_dev_attr_pwm2_freq.dev_attr.attr, + &sensor_dev_attr_pwm2_enable.dev_attr.attr, + &sensor_dev_attr_pwm2_auto_channel_temp.dev_attr.attr, + &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr, + &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr, + &sensor_dev_attr_pwm3.dev_attr.attr, + &sensor_dev_attr_pwm3_freq.dev_attr.attr, + &sensor_dev_attr_pwm3_enable.dev_attr.attr, + &sensor_dev_attr_pwm3_auto_channel_temp.dev_attr.attr, + &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr, + &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr, + NULL, +}; + +struct attribute_group adt7475_attr_group = { .attrs = adt7475_attrs }; + +static int adt7475_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = client->adapter; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; + + if (kind <= 0) { + if (adt7475_read(REG_VENDID) != 0x41 || + adt7475_read(REG_DEVID) != 0x75) { + dev_err(&adapter->dev, + "Couldn't detect a adt7475 part at 0x%02x\n", + (unsigned int)client->addr); + return -ENODEV; + } + } + + strlcpy(info->type, adt7475_id[0].name, I2C_NAME_SIZE); + + return 0; +} + +static int adt7475_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct adt7475_data *data; + int i, ret = 0; + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -ENOMEM; + + mutex_init(&data->lock); + i2c_set_clientdata(client, data); + + /* Call adt7475_read_pwm for all pwm's as this will reprogram any + pwm's which are disabled to manual mode with 0% duty cycle */ + for (i = 0; i < ADT7475_PWM_COUNT; i++) + adt7475_read_pwm(client, i); + + ret = sysfs_create_group(&client->dev.kobj, &adt7475_attr_group); + if (ret) + goto efree; + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + ret = PTR_ERR(data->hwmon_dev); + goto eremove; + } + + return 0; + +eremove: + sysfs_remove_group(&client->dev.kobj, &adt7475_attr_group); +efree: + kfree(data); + return ret; +} + +static int adt7475_remove(struct i2c_client *client) +{ + struct adt7475_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &adt7475_attr_group); + kfree(data); + + return 0; +} + +static struct i2c_driver adt7475_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "adt7475", + }, + .probe = adt7475_probe, + .remove = adt7475_remove, + .id_table = adt7475_id, + .detect = adt7475_detect, + .address_data = &addr_data, +}; + +static void adt7475_read_hystersis(struct i2c_client *client) +{ + struct adt7475_data *data = i2c_get_clientdata(client); + + data->temp[HYSTERSIS][0] = (u16) adt7475_read(REG_REMOTE1_HYSTERSIS); + data->temp[HYSTERSIS][1] = data->temp[HYSTERSIS][0]; + data->temp[HYSTERSIS][2] = (u16) adt7475_read(REG_REMOTE2_HYSTERSIS); +} + +static void adt7475_read_pwm(struct i2c_client *client, int index) +{ + struct adt7475_data *data = i2c_get_clientdata(client); + unsigned int v; + + data->pwm[CONTROL][index] = adt7475_read(PWM_CONFIG_REG(index)); + + /* Figure out the internal value for pwmctrl and pwmchan + based on the current settings */ + v = (data->pwm[CONTROL][index] >> 5) & 7; + + if (v == 3) + data->pwmctl[index] = 0; + else if (v == 7) + data->pwmctl[index] = 1; + else if (v == 4) { + /* The fan is disabled - we don't want to + support that, so change to manual mode and + set the duty cycle to 0 instead + */ + data->pwm[INPUT][index] = 0; + data->pwm[CONTROL][index] &= ~0xE0; + data->pwm[CONTROL][index] |= (7 << 5); + + i2c_smbus_write_byte_data(client, PWM_CONFIG_REG(index), + data->pwm[INPUT][index]); + + i2c_smbus_write_byte_data(client, PWM_CONFIG_REG(index), + data->pwm[CONTROL][index]); + + data->pwmctl[index] = 1; + } else { + data->pwmctl[index] = 2; + + switch (v) { + case 0: + data->pwmchan[index] = 1; + break; + case 1: + data->pwmchan[index] = 2; + break; + case 2: + data->pwmchan[index] = 4; + break; + case 5: + data->pwmchan[index] = 6; + break; + case 6: + data->pwmchan[index] = 7; + break; + } + } +} + +static struct adt7475_data *adt7475_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct adt7475_data *data = i2c_get_clientdata(client); + u8 ext; + int i; + + mutex_lock(&data->lock); + + /* Measurement values update every 2 seconds */ + if (time_after(jiffies, data->measure_updated + HZ * 2) || + !data->valid) { + data->alarms = adt7475_read(REG_STATUS2) << 8; + data->alarms |= adt7475_read(REG_STATUS1); + + ext = adt7475_read(REG_EXTEND1); + for (i = 0; i < ADT7475_VOLTAGE_COUNT; i++) + data->voltage[INPUT][i] = + (adt7475_read(VOLTAGE_REG(i)) << 2) | + ((ext >> ((i + 1) * 2)) & 3); + + ext = adt7475_read(REG_EXTEND2); + for (i = 0; i < ADT7475_TEMP_COUNT; i++) + data->temp[INPUT][i] = + (adt7475_read(TEMP_REG(i)) << 2) | + ((ext >> ((i + 1) * 2)) & 3); + + for (i = 0; i < ADT7475_TACH_COUNT; i++) + data->tach[INPUT][i] = + adt7475_read_word(client, TACH_REG(i)); + + /* Updated by hw when in auto mode */ + for (i = 0; i < ADT7475_PWM_COUNT; i++) + data->pwm[INPUT][i] = adt7475_read(PWM_REG(i)); + + data->measure_updated = jiffies; + } + + /* Limits and settings, should never change update every 60 seconds */ + if (time_after(jiffies, data->limits_updated + HZ * 2) || + !data->valid) { + data->config5 = adt7475_read(REG_CONFIG5); + + for (i = 0; i < ADT7475_VOLTAGE_COUNT; i++) { + /* Adjust values so they match the input precision */ + data->voltage[MIN][i] = + adt7475_read(VOLTAGE_MIN_REG(i)) << 2; + data->voltage[MAX][i] = + adt7475_read(VOLTAGE_MAX_REG(i)) << 2; + } + + for (i = 0; i < ADT7475_TEMP_COUNT; i++) { + /* Adjust values so they match the input precision */ + data->temp[MIN][i] = + adt7475_read(TEMP_MIN_REG(i)) << 2; + data->temp[MAX][i] = + adt7475_read(TEMP_MAX_REG(i)) << 2; + data->temp[AUTOMIN][i] = + adt7475_read(TEMP_TMIN_REG(i)) << 2; + data->temp[THERM][i] = + adt7475_read(TEMP_THERM_REG(i)) << 2; + data->temp[OFFSET][i] = + adt7475_read(TEMP_OFFSET_REG(i)); + } + adt7475_read_hystersis(client); + + for (i = 0; i < ADT7475_TACH_COUNT; i++) + data->tach[MIN][i] = + adt7475_read_word(client, TACH_MIN_REG(i)); + + for (i = 0; i < ADT7475_PWM_COUNT; i++) { + data->pwm[MAX][i] = adt7475_read(PWM_MAX_REG(i)); + data->pwm[MIN][i] = adt7475_read(PWM_MIN_REG(i)); + /* Set the channel and control information */ + adt7475_read_pwm(client, i); + } + + data->range[0] = adt7475_read(TEMP_TRANGE_REG(0)); + data->range[1] = adt7475_read(TEMP_TRANGE_REG(1)); + data->range[2] = adt7475_read(TEMP_TRANGE_REG(2)); + + data->limits_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->lock); + + return data; +} + +static int __init sensors_adt7475_init(void) +{ + return i2c_add_driver(&adt7475_driver); +} + +static void __exit sensors_adt7475_exit(void) +{ + i2c_del_driver(&adt7475_driver); +} + +MODULE_AUTHOR("Advanced Micro Devices, Inc"); +MODULE_DESCRIPTION("adt7475 driver"); +MODULE_LICENSE("GPL"); + +module_init(sensors_adt7475_init); +module_exit(sensors_adt7475_exit); -- cgit From 058943ddcb7cb307a0c406088c1e61f203d8b66f Mon Sep 17 00:00:00 2001 From: Alistair John Strachan Date: Thu, 15 Jan 2009 22:27:47 +0100 Subject: hwmon: (abituguru3) Match partial DMI board name strings The switch-over to using DMI board strings to identify abituguru3 compatible mainboards works most of the time, but sometimes the vendor has substantially modified the board string between BIOS revisions. We have found that the vendor chipset identification string (provided in brackets) changes frequently and is of no use to us. The rest of the board string sometimes changes in subtle ways, e.g. whitespace or variations in capitalization. The new comparison code checks only a part of the supplied DMI board string, trimming the bracketed content, whitespace, and ignoring case as necessary. This fixes a bug where an IP35 Pro running an early BIOS would not be detected without the force=1 module parameter, and also speculatively fixes other similiar issues. Signed-off-by: Alistair John Strachan Reported-by: Nick Pasich Cc: Hans de Goede Signed-off-by: Jean Delvare --- drivers/hwmon/abituguru3.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c index 70bb854086d..4914b34e6bc 100644 --- a/drivers/hwmon/abituguru3.c +++ b/drivers/hwmon/abituguru3.c @@ -279,7 +279,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { { "OTES1 Fan", 36, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x0011, "AT8 32X(ATI RD580-ULI M1575)", { + { 0x0011, "AT8 32X", { { "CPU Core", 0, 0, 10, 1, 0 }, { "DDR", 1, 0, 20, 1, 0 }, { "DDR VTT", 2, 0, 10, 1, 0 }, @@ -402,7 +402,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { { "AUX3 Fan", 36, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x0016, "AW9D-MAX (Intel i975-ICH7)", { + { 0x0016, "AW9D-MAX", { { "CPU Core", 0, 0, 10, 1, 0 }, { "DDR2", 1, 0, 20, 1, 0 }, { "DDR2 VTT", 2, 0, 10, 1, 0 }, @@ -509,7 +509,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { { "AUX3 FAN", 36, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x001A, "IP35 Pro(Intel P35-ICH9R)", { + { 0x001A, "IP35 Pro", { { "CPU Core", 0, 0, 10, 1, 0 }, { "DDR2", 1, 0, 20, 1, 0 }, { "DDR2 VTT", 2, 0, 10, 1, 0 }, @@ -1128,6 +1128,7 @@ static int __init abituguru3_dmi_detect(void) { const char *board_vendor, *board_name; int i, err = (force) ? 1 : -ENODEV; + size_t sublen; board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); if (!board_vendor || strcmp(board_vendor, "http://www.abit.com.tw/")) @@ -1137,9 +1138,20 @@ static int __init abituguru3_dmi_detect(void) if (!board_name) return err; + /* At the moment, we don't care about the part of the vendor + * DMI string contained in brackets. Truncate the string at + * the first occurrence of a bracket. Trim any trailing space + * from the substring. + */ + sublen = strcspn(board_name, "("); + while (sublen > 0 && board_name[sublen - 1] == ' ') + sublen--; + for (i = 0; abituguru3_motherboards[i].id; i++) { const char *dmi_name = abituguru3_motherboards[i].dmi_name; - if (dmi_name && !strcmp(dmi_name, board_name)) + if (!dmi_name || strlen(dmi_name) != sublen) + continue; + if (!strncasecmp(board_name, dmi_name, sublen)) break; } -- cgit From 3907a8def78a15cd91985c23a3e76b563f36929a Mon Sep 17 00:00:00 2001 From: Alistair John Strachan Date: Thu, 15 Jan 2009 22:27:48 +0100 Subject: hwmon: (abituguru3) Enable DMI probing feature on IN9 32X MAX Switch the IN9 32X MAX over from port probing to the preferred DMI probe method. Signed-off-by: Alistair John Strachan Tested-by: Paul Hartman Cc: Hans de Goede Signed-off-by: Jean Delvare --- drivers/hwmon/abituguru3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c index 4914b34e6bc..f948ed16e96 100644 --- a/drivers/hwmon/abituguru3.c +++ b/drivers/hwmon/abituguru3.c @@ -482,7 +482,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { { "AUX3 Fan", 36, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x0019, NULL /* Unknown, need DMI string */, { + { 0x0019, "IN9 32X MAX", { { "CPU Core", 7, 0, 10, 1, 0 }, { "DDR2", 13, 0, 20, 1, 0 }, { "DDR2 VTT", 14, 0, 10, 1, 0 }, -- cgit From 46a5f173fc88ffc22651162033696d8a9fbcdc5c Mon Sep 17 00:00:00 2001 From: Alistair John Strachan Date: Thu, 15 Jan 2009 22:27:48 +0100 Subject: hwmon: (abituguru3) Fix CONFIG_DMI=n fallback to probe When CONFIG_DMI is not enabled, dmi detection should flag that no board could be detected (err=1) rather than another error condition (err<0). This fixes the fallback to manual probing for all motherboards, even those without DMI strings, when CONFIG_DMI=n. Signed-off-by: Alistair John Strachan Cc: Hans de Goede Signed-off-by: Jean Delvare --- drivers/hwmon/abituguru3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c index f948ed16e96..e52b38806d0 100644 --- a/drivers/hwmon/abituguru3.c +++ b/drivers/hwmon/abituguru3.c @@ -1165,7 +1165,7 @@ static int __init abituguru3_dmi_detect(void) static inline int abituguru3_dmi_detect(void) { - return -ENODEV; + return 1; } #endif /* CONFIG_DMI */ -- cgit From c903ff837909ccada51243307d4239f86af40179 Mon Sep 17 00:00:00 2001 From: Mike Travis Date: Thu, 15 Jan 2009 12:28:29 -0800 Subject: rcu: move Kconfig menu Move RCU Kconfig options from top-level menu to an "RCU Subsystem" menu under the "General Setup" menu. Signed-off-by: Mike Travis Tested-by: "Paul E. McKenney" Signed-off-by: Ingo Molnar --- init/Kconfig | 179 ++++++++++++++++++++++++++++++----------------------------- 1 file changed, 92 insertions(+), 87 deletions(-) diff --git a/init/Kconfig b/init/Kconfig index a724a149bf3..989f58b0395 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -238,6 +238,98 @@ config AUDIT_TREE def_bool y depends on AUDITSYSCALL && INOTIFY +menu "RCU Subsystem" + +choice + prompt "RCU Implementation" + default CLASSIC_RCU + +config CLASSIC_RCU + bool "Classic RCU" + help + This option selects the classic RCU implementation that is + designed for best read-side performance on non-realtime + systems. + + Select this option if you are unsure. + +config TREE_RCU + bool "Tree-based hierarchical RCU" + help + This option selects the RCU implementation that is + designed for very large SMP system with hundreds or + thousands of CPUs. + +config PREEMPT_RCU + bool "Preemptible RCU" + depends on PREEMPT + help + This option reduces the latency of the kernel by making certain + RCU sections preemptible. Normally RCU code is non-preemptible, if + this option is selected then read-only RCU sections become + preemptible. This helps latency, but may expose bugs due to + now-naive assumptions about each RCU read-side critical section + remaining on a given CPU through its execution. + +endchoice + +config RCU_TRACE + bool "Enable tracing for RCU" + depends on TREE_RCU || PREEMPT_RCU + help + This option provides tracing in RCU which presents stats + in debugfs for debugging RCU implementation. + + Say Y here if you want to enable RCU tracing + Say N if you are unsure. + +config RCU_FANOUT + int "Tree-based hierarchical RCU fanout value" + range 2 64 if 64BIT + range 2 32 if !64BIT + depends on TREE_RCU + default 64 if 64BIT + default 32 if !64BIT + help + This option controls the fanout of hierarchical implementations + of RCU, allowing RCU to work efficiently on machines with + large numbers of CPUs. This value must be at least the cube + root of NR_CPUS, which allows NR_CPUS up to 32,768 for 32-bit + systems and up to 262,144 for 64-bit systems. + + Select a specific number if testing RCU itself. + Take the default if unsure. + +config RCU_FANOUT_EXACT + bool "Disable tree-based hierarchical RCU auto-balancing" + depends on TREE_RCU + default n + help + This option forces use of the exact RCU_FANOUT value specified, + regardless of imbalances in the hierarchy. This is useful for + testing RCU itself, and might one day be useful on systems with + strong NUMA behavior. + + Without RCU_FANOUT_EXACT, the code will balance the hierarchy. + + Say N if unsure. + +config TREE_RCU_TRACE + def_bool RCU_TRACE && TREE_RCU + select DEBUG_FS + help + This option provides tracing for the TREE_RCU implementation, + permitting Makefile to trivially select kernel/rcutree_trace.c. + +config PREEMPT_RCU_TRACE + def_bool RCU_TRACE && PREEMPT_RCU + select DEBUG_FS + help + This option provides tracing for the PREEMPT_RCU implementation, + permitting Makefile to trivially select kernel/rcupreempt_trace.c. + +endmenu # "RCU Subsystem" + config IKCONFIG tristate "Kernel .config support" ---help--- @@ -973,90 +1065,3 @@ source "block/Kconfig" config PREEMPT_NOTIFIERS bool -choice - prompt "RCU Implementation" - default CLASSIC_RCU - -config CLASSIC_RCU - bool "Classic RCU" - help - This option selects the classic RCU implementation that is - designed for best read-side performance on non-realtime - systems. - - Select this option if you are unsure. - -config TREE_RCU - bool "Tree-based hierarchical RCU" - help - This option selects the RCU implementation that is - designed for very large SMP system with hundreds or - thousands of CPUs. - -config PREEMPT_RCU - bool "Preemptible RCU" - depends on PREEMPT - help - This option reduces the latency of the kernel by making certain - RCU sections preemptible. Normally RCU code is non-preemptible, if - this option is selected then read-only RCU sections become - preemptible. This helps latency, but may expose bugs due to - now-naive assumptions about each RCU read-side critical section - remaining on a given CPU through its execution. - -endchoice - -config RCU_TRACE - bool "Enable tracing for RCU" - depends on TREE_RCU || PREEMPT_RCU - help - This option provides tracing in RCU which presents stats - in debugfs for debugging RCU implementation. - - Say Y here if you want to enable RCU tracing - Say N if you are unsure. - -config RCU_FANOUT - int "Tree-based hierarchical RCU fanout value" - range 2 64 if 64BIT - range 2 32 if !64BIT - depends on TREE_RCU - default 64 if 64BIT - default 32 if !64BIT - help - This option controls the fanout of hierarchical implementations - of RCU, allowing RCU to work efficiently on machines with - large numbers of CPUs. This value must be at least the cube - root of NR_CPUS, which allows NR_CPUS up to 32,768 for 32-bit - systems and up to 262,144 for 64-bit systems. - - Select a specific number if testing RCU itself. - Take the default if unsure. - -config RCU_FANOUT_EXACT - bool "Disable tree-based hierarchical RCU auto-balancing" - depends on TREE_RCU - default n - help - This option forces use of the exact RCU_FANOUT value specified, - regardless of imbalances in the hierarchy. This is useful for - testing RCU itself, and might one day be useful on systems with - strong NUMA behavior. - - Without RCU_FANOUT_EXACT, the code will balance the hierarchy. - - Say N if unsure. - -config TREE_RCU_TRACE - def_bool RCU_TRACE && TREE_RCU - select DEBUG_FS - help - This option provides tracing for the TREE_RCU implementation, - permitting Makefile to trivially select kernel/rcutree_trace.c. - -config PREEMPT_RCU_TRACE - def_bool RCU_TRACE && PREEMPT_RCU - select DEBUG_FS - help - This option provides tracing for the PREEMPT_RCU implementation, - permitting Makefile to trivially select kernel/rcupreempt_trace.c. -- cgit From 4a13ad0bd8869bb491c67918662f9b1852595af5 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 14 Jan 2009 12:28:51 +0000 Subject: x86: avoid early crash in disable_local_APIC() E.g. when called due to an early panic. Signed-off-by: Jan Beulich Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c index 0f830e4f567..d19aa3aab62 100644 --- a/arch/x86/kernel/apic.c +++ b/arch/x86/kernel/apic.c @@ -895,6 +895,10 @@ void disable_local_APIC(void) { unsigned int value; + /* APIC hasn't been mapped yet */ + if (!apic_phys) + return; + clear_local_APIC(); /* -- cgit From 18c07cf530cf4aa8b7551801f68ed40db5ee4e45 Mon Sep 17 00:00:00 2001 From: Cliff Wickman Date: Thu, 15 Jan 2009 09:51:20 -0600 Subject: x86, UV: cpu_relax in uv_wait_completion The function uv_wait_completion() spins on reads of a memory-mapped register, waiting for completion of BAU hardware replies. It should call "cpu_relax()" between those reads to improve performance on hyperthreaded configurations. Signed-off-by: Cliff Wickman Acked-by: Jack Steiner Signed-off-by: Ingo Molnar --- arch/x86/kernel/tlb_uv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c index f885023167e..6812b829ed8 100644 --- a/arch/x86/kernel/tlb_uv.c +++ b/arch/x86/kernel/tlb_uv.c @@ -200,6 +200,7 @@ static int uv_wait_completion(struct bau_desc *bau_desc, destination_timeouts = 0; } } + cpu_relax(); } return FLUSH_COMPLETE; } -- cgit From a58c891a53aca81c78f9cbe0572a301042470e96 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 15 Jan 2009 15:29:35 -0800 Subject: b44: GFP_DMA skb should not escape from driver b44 chip has some hardware limitations, that need GFP_DMA bounce buffers in some situations. In order to not deplete DMA zone, we should keep allocated GFP_DMA skb only for driver use. At rx time, we copy such skb to newly allocated skb, reusing existing copybreak infrastructure. On machines with low amount of memory, all skb meet the hardware limitation, so no copy is needed. We detect this situation using a new device flag, set to one if one GFP_DMA skb was ever allocated by b44_alloc_rx_skb(). Previously allocated skb, even outside from DMA zone will then be recycled, to have minimal impact on DMA zone use. Signed-off-by: Eric Dumazet Tested-by: Ionut Leonte Signed-off-by: David S. Miller --- drivers/net/b44.c | 4 +++- drivers/net/b44.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 5ae131c147f..c38512ebcea 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -679,6 +679,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) dev_kfree_skb_any(skb); return -ENOMEM; } + bp->force_copybreak = 1; } rh = (struct rx_header *) skb->data; @@ -800,7 +801,7 @@ static int b44_rx(struct b44 *bp, int budget) /* Omit CRC. */ len -= 4; - if (len > RX_COPY_THRESHOLD) { + if (!bp->force_copybreak && len > RX_COPY_THRESHOLD) { int skb_size; skb_size = b44_alloc_rx_skb(bp, cons, bp->rx_prod); if (skb_size < 0) @@ -2152,6 +2153,7 @@ static int __devinit b44_init_one(struct ssb_device *sdev, bp = netdev_priv(dev); bp->sdev = sdev; bp->dev = dev; + bp->force_copybreak = 0; bp->msg_enable = netif_msg_init(b44_debug, B44_DEF_MSG_ENABLE); diff --git a/drivers/net/b44.h b/drivers/net/b44.h index 7db0c84a795..e678498de6d 100644 --- a/drivers/net/b44.h +++ b/drivers/net/b44.h @@ -395,7 +395,7 @@ struct b44 { u32 rx_pending; u32 tx_pending; u8 phy_addr; - + u8 force_copybreak; struct mii_if_info mii_if; }; -- cgit From b5db0e38653bfada34a92f360b4111566ede3842 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 15 Jan 2009 15:32:12 -0800 Subject: Revert "x86 PAT: remove CPA WARN_ON for zero pte" This reverts commit 58dab916dfb57328d50deb0aa9b3fc92efa248ff, which makes my Nehalem come to a nasty crawling almost-halt. It looks like it turns off caching of regular kernel RAM, with the understandable slowdown of a few orders of magnitude as a result. Acked-by: Ingo Molnar Cc: Yinghai Lu Cc: Peter Anvin Cc: Venkatesh Pallipadi Cc: Suresh Siddha Signed-off-by: Linus Torvalds --- arch/x86/mm/pageattr.c | 10 ++++------ arch/x86/mm/pat.c | 45 +++++++++++++-------------------------------- 2 files changed, 17 insertions(+), 38 deletions(-) diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 4cf30dee816..e89d24815f2 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -555,12 +555,10 @@ repeat: if (!pte_val(old_pte)) { if (!primary) return 0; - - /* - * Special error value returned, indicating that the mapping - * did not exist at this address. - */ - return -EFAULT; + WARN(1, KERN_WARNING "CPA: called for zero pte. " + "vaddr = %lx cpa->vaddr = %lx\n", address, + *cpa->vaddr); + return -EINVAL; } if (level == PG_LEVEL_4K) { diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index 160c42d3eb8..8b08fb95527 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c @@ -505,35 +505,6 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size) } #endif /* CONFIG_STRICT_DEVMEM */ -/* - * Change the memory type for the physial address range in kernel identity - * mapping space if that range is a part of identity map. - */ -static int kernel_map_sync_memtype(u64 base, unsigned long size, - unsigned long flags) -{ - unsigned long id_sz; - int ret; - - if (!pat_enabled || base >= __pa(high_memory)) - return 0; - - id_sz = (__pa(high_memory) < base + size) ? - __pa(high_memory) - base : - size; - - ret = ioremap_change_attr((unsigned long)__va(base), id_sz, flags); - /* - * -EFAULT return means that the addr was not valid and did not have - * any identity mapping. That case is a success for - * kernel_map_sync_memtype. - */ - if (ret == -EFAULT) - ret = 0; - - return ret; -} - int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, unsigned long size, pgprot_t *vma_prot) { @@ -584,7 +555,9 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, if (retval < 0) return 0; - if (kernel_map_sync_memtype(offset, size, flags)) { + if (((pfn < max_low_pfn_mapped) || + (pfn >= (1UL<<(32 - PAGE_SHIFT)) && pfn < max_pfn_mapped)) && + ioremap_change_attr((unsigned long)__va(offset), size, flags) < 0) { free_memtype(offset, offset + size); printk(KERN_INFO "%s:%d /dev/mem ioremap_change_attr failed %s for %Lx-%Lx\n", @@ -632,7 +605,7 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot, int strict_prot) { int is_ram = 0; - int ret; + int id_sz, ret; unsigned long flags; unsigned long want_flags = (pgprot_val(*vma_prot) & _PAGE_CACHE_MASK); @@ -673,7 +646,15 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot, flags); } - if (kernel_map_sync_memtype(paddr, size, flags)) { + /* Need to keep identity mapping in sync */ + if (paddr >= __pa(high_memory)) + return 0; + + id_sz = (__pa(high_memory) < paddr + size) ? + __pa(high_memory) - paddr : + size; + + if (ioremap_change_attr((unsigned long)__va(paddr), id_sz, flags) < 0) { free_memtype(paddr, paddr + size); printk(KERN_ERR "%s:%d reserve_pfn_range ioremap_change_attr failed %s " -- cgit From db0fb1848a645b0b1b033765f3a5244e7afd2e3c Mon Sep 17 00:00:00 2001 From: Peter W Morreale Date: Thu, 15 Jan 2009 13:50:42 -0800 Subject: Update of Documentation: vm.txt and proc.txt Update Documentation/sysctl/vm.txt and Documentation/filesystems/proc.txt. More specifically, the section on /proc/sys/vm in Documentation/filesystems/proc.txt was removed and a link to Documentation/sysctl/vm.txt added. Most of the verbiage from proc.txt was simply moved in vm.txt, with new addtional text for "swappiness" and "stat_interval". Signed-off-by: Peter W Morreale Acked-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/filesystems/proc.txt | 288 +---------------- Documentation/sysctl/vm.txt | 619 ++++++++++++++++++++++++++----------- 2 files changed, 437 insertions(+), 470 deletions(-) diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index d105eb45282..bbebc3a43ac 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -1371,292 +1371,8 @@ auto_msgmni default value is 1. 2.4 /proc/sys/vm - The virtual memory subsystem ----------------------------------------------- -The files in this directory can be used to tune the operation of the virtual -memory (VM) subsystem of the Linux kernel. - -vfs_cache_pressure ------------------- - -Controls the tendency of the kernel to reclaim the memory which is used for -caching of directory and inode objects. - -At the default value of vfs_cache_pressure=100 the kernel will attempt to -reclaim dentries and inodes at a "fair" rate with respect to pagecache and -swapcache reclaim. Decreasing vfs_cache_pressure causes the kernel to prefer -to retain dentry and inode caches. Increasing vfs_cache_pressure beyond 100 -causes the kernel to prefer to reclaim dentries and inodes. - -dirty_background_bytes ----------------------- - -Contains the amount of dirty memory at which the pdflush background writeback -daemon will start writeback. - -If dirty_background_bytes is written, dirty_background_ratio becomes a function -of its value (dirty_background_bytes / the amount of dirtyable system memory). - -dirty_background_ratio ----------------------- - -Contains, as a percentage of the dirtyable system memory (free pages + mapped -pages + file cache, not including locked pages and HugePages), the number of -pages at which the pdflush background writeback daemon will start writing out -dirty data. - -If dirty_background_ratio is written, dirty_background_bytes becomes a function -of its value (dirty_background_ratio * the amount of dirtyable system memory). - -dirty_bytes ------------ - -Contains the amount of dirty memory at which a process generating disk writes -will itself start writeback. - -If dirty_bytes is written, dirty_ratio becomes a function of its value -(dirty_bytes / the amount of dirtyable system memory). - -dirty_ratio ------------ - -Contains, as a percentage of the dirtyable system memory (free pages + mapped -pages + file cache, not including locked pages and HugePages), the number of -pages at which a process which is generating disk writes will itself start -writing out dirty data. - -If dirty_ratio is written, dirty_bytes becomes a function of its value -(dirty_ratio * the amount of dirtyable system memory). - -dirty_writeback_centisecs -------------------------- - -The pdflush writeback daemons will periodically wake up and write `old' data -out to disk. This tunable expresses the interval between those wakeups, in -100'ths of a second. - -Setting this to zero disables periodic writeback altogether. - -dirty_expire_centisecs ----------------------- - -This tunable is used to define when dirty data is old enough to be eligible -for writeout by the pdflush daemons. It is expressed in 100'ths of a second. -Data which has been dirty in-memory for longer than this interval will be -written out next time a pdflush daemon wakes up. - -highmem_is_dirtyable --------------------- - -Only present if CONFIG_HIGHMEM is set. - -This defaults to 0 (false), meaning that the ratios set above are calculated -as a percentage of lowmem only. This protects against excessive scanning -in page reclaim, swapping and general VM distress. - -Setting this to 1 can be useful on 32 bit machines where you want to make -random changes within an MMAPed file that is larger than your available -lowmem without causing large quantities of random IO. Is is safe if the -behavior of all programs running on the machine is known and memory will -not be otherwise stressed. - -legacy_va_layout ----------------- - -If non-zero, this sysctl disables the new 32-bit mmap mmap layout - the kernel -will use the legacy (2.4) layout for all processes. - -lowmem_reserve_ratio ---------------------- - -For some specialised workloads on highmem machines it is dangerous for -the kernel to allow process memory to be allocated from the "lowmem" -zone. This is because that memory could then be pinned via the mlock() -system call, or by unavailability of swapspace. - -And on large highmem machines this lack of reclaimable lowmem memory -can be fatal. - -So the Linux page allocator has a mechanism which prevents allocations -which _could_ use highmem from using too much lowmem. This means that -a certain amount of lowmem is defended from the possibility of being -captured into pinned user memory. - -(The same argument applies to the old 16 megabyte ISA DMA region. This -mechanism will also defend that region from allocations which could use -highmem or lowmem). - -The `lowmem_reserve_ratio' tunable determines how aggressive the kernel is -in defending these lower zones. - -If you have a machine which uses highmem or ISA DMA and your -applications are using mlock(), or if you are running with no swap then -you probably should change the lowmem_reserve_ratio setting. - -The lowmem_reserve_ratio is an array. You can see them by reading this file. -- -% cat /proc/sys/vm/lowmem_reserve_ratio -256 256 32 -- -Note: # of this elements is one fewer than number of zones. Because the highest - zone's value is not necessary for following calculation. - -But, these values are not used directly. The kernel calculates # of protection -pages for each zones from them. These are shown as array of protection pages -in /proc/zoneinfo like followings. (This is an example of x86-64 box). -Each zone has an array of protection pages like this. - -- -Node 0, zone DMA - pages free 1355 - min 3 - low 3 - high 4 - : - : - numa_other 0 - protection: (0, 2004, 2004, 2004) - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - pagesets - cpu: 0 pcp: 0 - : -- -These protections are added to score to judge whether this zone should be used -for page allocation or should be reclaimed. - -In this example, if normal pages (index=2) are required to this DMA zone and -pages_high is used for watermark, the kernel judges this zone should not be -used because pages_free(1355) is smaller than watermark + protection[2] -(4 + 2004 = 2008). If this protection value is 0, this zone would be used for -normal page requirement. If requirement is DMA zone(index=0), protection[0] -(=0) is used. - -zone[i]'s protection[j] is calculated by following expression. - -(i < j): - zone[i]->protection[j] - = (total sums of present_pages from zone[i+1] to zone[j] on the node) - / lowmem_reserve_ratio[i]; -(i = j): - (should not be protected. = 0; -(i > j): - (not necessary, but looks 0) - -The default values of lowmem_reserve_ratio[i] are - 256 (if zone[i] means DMA or DMA32 zone) - 32 (others). -As above expression, they are reciprocal number of ratio. -256 means 1/256. # of protection pages becomes about "0.39%" of total present -pages of higher zones on the node. - -If you would like to protect more pages, smaller values are effective. -The minimum value is 1 (1/1 -> 100%). - -page-cluster ------------- - -page-cluster controls the number of pages which are written to swap in -a single attempt. The swap I/O size. - -It is a logarithmic value - setting it to zero means "1 page", setting -it to 1 means "2 pages", setting it to 2 means "4 pages", etc. - -The default value is three (eight pages at a time). There may be some -small benefits in tuning this to a different value if your workload is -swap-intensive. - -overcommit_memory ------------------ - -Controls overcommit of system memory, possibly allowing processes -to allocate (but not use) more memory than is actually available. - - -0 - Heuristic overcommit handling. Obvious overcommits of - address space are refused. Used for a typical system. It - ensures a seriously wild allocation fails while allowing - overcommit to reduce swap usage. root is allowed to - allocate slightly more memory in this mode. This is the - default. - -1 - Always overcommit. Appropriate for some scientific - applications. - -2 - Don't overcommit. The total address space commit - for the system is not permitted to exceed swap plus a - configurable percentage (default is 50) of physical RAM. - Depending on the percentage you use, in most situations - this means a process will not be killed while attempting - to use already-allocated memory but will receive errors - on memory allocation as appropriate. - -overcommit_ratio ----------------- - -Percentage of physical memory size to include in overcommit calculations -(see above.) - -Memory allocation limit = swapspace + physmem * (overcommit_ratio / 100) - - swapspace = total size of all swap areas - physmem = size of physical memory in system - -nr_hugepages and hugetlb_shm_group ----------------------------------- - -nr_hugepages configures number of hugetlb page reserved for the system. - -hugetlb_shm_group contains group id that is allowed to create SysV shared -memory segment using hugetlb page. - -hugepages_treat_as_movable --------------------------- - -This parameter is only useful when kernelcore= is specified at boot time to -create ZONE_MOVABLE for pages that may be reclaimed or migrated. Huge pages -are not movable so are not normally allocated from ZONE_MOVABLE. A non-zero -value written to hugepages_treat_as_movable allows huge pages to be allocated -from ZONE_MOVABLE. - -Once enabled, the ZONE_MOVABLE is treated as an area of memory the huge -pages pool can easily grow or shrink within. Assuming that applications are -not running that mlock() a lot of memory, it is likely the huge pages pool -can grow to the size of ZONE_MOVABLE by repeatedly entering the desired value -into nr_hugepages and triggering page reclaim. - -laptop_mode ------------ - -laptop_mode is a knob that controls "laptop mode". All the things that are -controlled by this knob are discussed in Documentation/laptops/laptop-mode.txt. - -block_dump ----------- - -block_dump enables block I/O debugging when set to a nonzero value. More -information on block I/O debugging is in Documentation/laptops/laptop-mode.txt. - -swap_token_timeout ------------------- - -This file contains valid hold time of swap out protection token. The Linux -VM has token based thrashing control mechanism and uses the token to prevent -unnecessary page faults in thrashing situation. The unit of the value is -second. The value would be useful to tune thrashing behavior. - -drop_caches ------------ - -Writing to this will cause the kernel to drop clean caches, dentries and -inodes from memory, causing that memory to become free. - -To free pagecache: - echo 1 > /proc/sys/vm/drop_caches -To free dentries and inodes: - echo 2 > /proc/sys/vm/drop_caches -To free pagecache, dentries and inodes: - echo 3 > /proc/sys/vm/drop_caches - -As this is a non-destructive operation and dirty objects are not freeable, the -user should run `sync' first. +Please see: Documentation/sysctls/vm.txt for a description of these +entries. 2.5 /proc/sys/dev - Device specific parameters diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index a3415070bca..3197fc83bc5 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt @@ -1,12 +1,13 @@ -Documentation for /proc/sys/vm/* kernel version 2.2.10 +Documentation for /proc/sys/vm/* kernel version 2.6.29 (c) 1998, 1999, Rik van Riel + (c) 2008 Peter W. Morreale For general info and legal blurb, please look in README. ============================================================== This file contains the documentation for the sysctl files in -/proc/sys/vm and is valid for Linux kernel version 2.2. +/proc/sys/vm and is valid for Linux kernel version 2.6.29. The files in this directory can be used to tune the operation of the virtual memory (VM) subsystem of the Linux kernel and @@ -16,180 +17,274 @@ Default values and initialization routines for most of these files can be found in mm/swap.c. Currently, these files are in /proc/sys/vm: -- overcommit_memory -- page-cluster -- dirty_ratio + +- block_dump +- dirty_background_bytes - dirty_background_ratio +- dirty_bytes - dirty_expire_centisecs +- dirty_ratio - dirty_writeback_centisecs -- highmem_is_dirtyable (only if CONFIG_HIGHMEM set) +- drop_caches +- hugepages_treat_as_movable +- hugetlb_shm_group +- laptop_mode +- legacy_va_layout +- lowmem_reserve_ratio - max_map_count - min_free_kbytes -- laptop_mode -- block_dump -- drop-caches -- zone_reclaim_mode -- min_unmapped_ratio - min_slab_ratio -- panic_on_oom -- oom_dump_tasks -- oom_kill_allocating_task -- mmap_min_address -- numa_zonelist_order +- min_unmapped_ratio +- mmap_min_addr - nr_hugepages - nr_overcommit_hugepages -- nr_trim_pages (only if CONFIG_MMU=n) +- nr_pdflush_threads +- nr_trim_pages (only if CONFIG_MMU=n) +- numa_zonelist_order +- oom_dump_tasks +- oom_kill_allocating_task +- overcommit_memory +- overcommit_ratio +- page-cluster +- panic_on_oom +- percpu_pagelist_fraction +- stat_interval +- swappiness +- vfs_cache_pressure +- zone_reclaim_mode + ============================================================== -dirty_bytes, dirty_ratio, dirty_background_bytes, -dirty_background_ratio, dirty_expire_centisecs, -dirty_writeback_centisecs, highmem_is_dirtyable, -vfs_cache_pressure, laptop_mode, block_dump, swap_token_timeout, -drop-caches, hugepages_treat_as_movable: +block_dump -See Documentation/filesystems/proc.txt +block_dump enables block I/O debugging when set to a nonzero value. More +information on block I/O debugging is in Documentation/laptops/laptop-mode.txt. ============================================================== -overcommit_memory: +dirty_background_bytes -This value contains a flag that enables memory overcommitment. +Contains the amount of dirty memory at which the pdflush background writeback +daemon will start writeback. -When this flag is 0, the kernel attempts to estimate the amount -of free memory left when userspace requests more memory. +If dirty_background_bytes is written, dirty_background_ratio becomes a function +of its value (dirty_background_bytes / the amount of dirtyable system memory). -When this flag is 1, the kernel pretends there is always enough -memory until it actually runs out. +============================================================== -When this flag is 2, the kernel uses a "never overcommit" -policy that attempts to prevent any overcommit of memory. +dirty_background_ratio -This feature can be very useful because there are a lot of -programs that malloc() huge amounts of memory "just-in-case" -and don't use much of it. +Contains, as a percentage of total system memory, the number of pages at which +the pdflush background writeback daemon will start writing out dirty data. -The default value is 0. +============================================================== -See Documentation/vm/overcommit-accounting and -security/commoncap.c::cap_vm_enough_memory() for more information. +dirty_bytes + +Contains the amount of dirty memory at which a process generating disk writes +will itself start writeback. + +If dirty_bytes is written, dirty_ratio becomes a function of its value +(dirty_bytes / the amount of dirtyable system memory). ============================================================== -overcommit_ratio: +dirty_expire_centisecs -When overcommit_memory is set to 2, the committed address -space is not permitted to exceed swap plus this percentage -of physical RAM. See above. +This tunable is used to define when dirty data is old enough to be eligible +for writeout by the pdflush daemons. It is expressed in 100'ths of a second. +Data which has been dirty in-memory for longer than this interval will be +written out next time a pdflush daemon wakes up. + +============================================================== + +dirty_ratio + +Contains, as a percentage of total system memory, the number of pages at which +a process which is generating disk writes will itself start writing out dirty +data. ============================================================== -page-cluster: +dirty_writeback_centisecs -The Linux VM subsystem avoids excessive disk seeks by reading -multiple pages on a page fault. The number of pages it reads -is dependent on the amount of memory in your machine. +The pdflush writeback daemons will periodically wake up and write `old' data +out to disk. This tunable expresses the interval between those wakeups, in +100'ths of a second. -The number of pages the kernel reads in at once is equal to -2 ^ page-cluster. Values above 2 ^ 5 don't make much sense -for swap because we only cluster swap data in 32-page groups. +Setting this to zero disables periodic writeback altogether. ============================================================== -max_map_count: +drop_caches -This file contains the maximum number of memory map areas a process -may have. Memory map areas are used as a side-effect of calling -malloc, directly by mmap and mprotect, and also when loading shared -libraries. +Writing to this will cause the kernel to drop clean caches, dentries and +inodes from memory, causing that memory to become free. -While most applications need less than a thousand maps, certain -programs, particularly malloc debuggers, may consume lots of them, -e.g., up to one or two maps per allocation. +To free pagecache: + echo 1 > /proc/sys/vm/drop_caches +To free dentries and inodes: + echo 2 > /proc/sys/vm/drop_caches +To free pagecache, dentries and inodes: + echo 3 > /proc/sys/vm/drop_caches -The default value is 65536. +As this is a non-destructive operation and dirty objects are not freeable, the +user should run `sync' first. ============================================================== -min_free_kbytes: +hugepages_treat_as_movable -This is used to force the Linux VM to keep a minimum number -of kilobytes free. The VM uses this number to compute a pages_min -value for each lowmem zone in the system. Each lowmem zone gets -a number of reserved free pages based proportionally on its size. +This parameter is only useful when kernelcore= is specified at boot time to +create ZONE_MOVABLE for pages that may be reclaimed or migrated. Huge pages +are not movable so are not normally allocated from ZONE_MOVABLE. A non-zero +value written to hugepages_treat_as_movable allows huge pages to be allocated +from ZONE_MOVABLE. -Some minimal amount of memory is needed to satisfy PF_MEMALLOC -allocations; if you set this to lower than 1024KB, your system will -become subtly broken, and prone to deadlock under high loads. - -Setting this too high will OOM your machine instantly. +Once enabled, the ZONE_MOVABLE is treated as an area of memory the huge +pages pool can easily grow or shrink within. Assuming that applications are +not running that mlock() a lot of memory, it is likely the huge pages pool +can grow to the size of ZONE_MOVABLE by repeatedly entering the desired value +into nr_hugepages and triggering page reclaim. ============================================================== -percpu_pagelist_fraction +hugetlb_shm_group -This is the fraction of pages at most (high mark pcp->high) in each zone that -are allocated for each per cpu page list. The min value for this is 8. It -means that we don't allow more than 1/8th of pages in each zone to be -allocated in any single per_cpu_pagelist. This entry only changes the value -of hot per cpu pagelists. User can specify a number like 100 to allocate -1/100th of each zone to each per cpu page list. +hugetlb_shm_group contains group id that is allowed to create SysV +shared memory segment using hugetlb page. -The batch value of each per cpu pagelist is also updated as a result. It is -set to pcp->high/4. The upper limit of batch is (PAGE_SHIFT * 8) +============================================================== -The initial value is zero. Kernel does not use this value at boot time to set -the high water marks for each per cpu page list. +laptop_mode -=============================================================== +laptop_mode is a knob that controls "laptop mode". All the things that are +controlled by this knob are discussed in Documentation/laptops/laptop-mode.txt. -zone_reclaim_mode: +============================================================== -Zone_reclaim_mode allows someone to set more or less aggressive approaches to -reclaim memory when a zone runs out of memory. If it is set to zero then no -zone reclaim occurs. Allocations will be satisfied from other zones / nodes -in the system. +legacy_va_layout -This is value ORed together of +If non-zero, this sysctl disables the new 32-bit mmap mmap layout - the kernel +will use the legacy (2.4) layout for all processes. -1 = Zone reclaim on -2 = Zone reclaim writes dirty pages out -4 = Zone reclaim swaps pages +============================================================== -zone_reclaim_mode is set during bootup to 1 if it is determined that pages -from remote zones will cause a measurable performance reduction. The -page allocator will then reclaim easily reusable pages (those page -cache pages that are currently not used) before allocating off node pages. +lowmem_reserve_ratio + +For some specialised workloads on highmem machines it is dangerous for +the kernel to allow process memory to be allocated from the "lowmem" +zone. This is because that memory could then be pinned via the mlock() +system call, or by unavailability of swapspace. + +And on large highmem machines this lack of reclaimable lowmem memory +can be fatal. + +So the Linux page allocator has a mechanism which prevents allocations +which _could_ use highmem from using too much lowmem. This means that +a certain amount of lowmem is defended from the possibility of being +captured into pinned user memory. + +(The same argument applies to the old 16 megabyte ISA DMA region. This +mechanism will also defend that region from allocations which could use +highmem or lowmem). + +The `lowmem_reserve_ratio' tunable determines how aggressive the kernel is +in defending these lower zones. + +If you have a machine which uses highmem or ISA DMA and your +applications are using mlock(), or if you are running with no swap then +you probably should change the lowmem_reserve_ratio setting. + +The lowmem_reserve_ratio is an array. You can see them by reading this file. +- +% cat /proc/sys/vm/lowmem_reserve_ratio +256 256 32 +- +Note: # of this elements is one fewer than number of zones. Because the highest + zone's value is not necessary for following calculation. + +But, these values are not used directly. The kernel calculates # of protection +pages for each zones from them. These are shown as array of protection pages +in /proc/zoneinfo like followings. (This is an example of x86-64 box). +Each zone has an array of protection pages like this. + +- +Node 0, zone DMA + pages free 1355 + min 3 + low 3 + high 4 + : + : + numa_other 0 + protection: (0, 2004, 2004, 2004) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + pagesets + cpu: 0 pcp: 0 + : +- +These protections are added to score to judge whether this zone should be used +for page allocation or should be reclaimed. + +In this example, if normal pages (index=2) are required to this DMA zone and +pages_high is used for watermark, the kernel judges this zone should not be +used because pages_free(1355) is smaller than watermark + protection[2] +(4 + 2004 = 2008). If this protection value is 0, this zone would be used for +normal page requirement. If requirement is DMA zone(index=0), protection[0] +(=0) is used. + +zone[i]'s protection[j] is calculated by following expression. + +(i < j): + zone[i]->protection[j] + = (total sums of present_pages from zone[i+1] to zone[j] on the node) + / lowmem_reserve_ratio[i]; +(i = j): + (should not be protected. = 0; +(i > j): + (not necessary, but looks 0) + +The default values of lowmem_reserve_ratio[i] are + 256 (if zone[i] means DMA or DMA32 zone) + 32 (others). +As above expression, they are reciprocal number of ratio. +256 means 1/256. # of protection pages becomes about "0.39%" of total present +pages of higher zones on the node. + +If you would like to protect more pages, smaller values are effective. +The minimum value is 1 (1/1 -> 100%). -It may be beneficial to switch off zone reclaim if the system is -used for a file server and all of memory should be used for caching files -from disk. In that case the caching effect is more important than -data locality. +============================================================== -Allowing zone reclaim to write out pages stops processes that are -writing large amounts of data from dirtying pages on other nodes. Zone -reclaim will write out dirty pages if a zone fills up and so effectively -throttle the process. This may decrease the performance of a single process -since it cannot use all of system memory to buffer the outgoing writes -anymore but it preserve the memory on other nodes so that the performance -of other processes running on other nodes will not be affected. +max_map_count: -Allowing regular swap effectively restricts allocations to the local -node unless explicitly overridden by memory policies or cpuset -configurations. +This file contains the maximum number of memory map areas a process +may have. Memory map areas are used as a side-effect of calling +malloc, directly by mmap and mprotect, and also when loading shared +libraries. -============================================================= +While most applications need less than a thousand maps, certain +programs, particularly malloc debuggers, may consume lots of them, +e.g., up to one or two maps per allocation. -min_unmapped_ratio: +The default value is 65536. -This is available only on NUMA kernels. +============================================================== -A percentage of the total pages in each zone. Zone reclaim will only -occur if more than this percentage of pages are file backed and unmapped. -This is to insure that a minimal amount of local pages is still available for -file I/O even if the node is overallocated. +min_free_kbytes: -The default is 1 percent. +This is used to force the Linux VM to keep a minimum number +of kilobytes free. The VM uses this number to compute a pages_min +value for each lowmem zone in the system. Each lowmem zone gets +a number of reserved free pages based proportionally on its size. + +Some minimal amount of memory is needed to satisfy PF_MEMALLOC +allocations; if you set this to lower than 1024KB, your system will +become subtly broken, and prone to deadlock under high loads. + +Setting this too high will OOM your machine instantly. ============================================================= @@ -211,82 +306,73 @@ and may not be fast. ============================================================= -panic_on_oom +min_unmapped_ratio: -This enables or disables panic on out-of-memory feature. +This is available only on NUMA kernels. -If this is set to 0, the kernel will kill some rogue process, -called oom_killer. Usually, oom_killer can kill rogue processes and -system will survive. +A percentage of the total pages in each zone. Zone reclaim will only +occur if more than this percentage of pages are file backed and unmapped. +This is to insure that a minimal amount of local pages is still available for +file I/O even if the node is overallocated. -If this is set to 1, the kernel panics when out-of-memory happens. -However, if a process limits using nodes by mempolicy/cpusets, -and those nodes become memory exhaustion status, one process -may be killed by oom-killer. No panic occurs in this case. -Because other nodes' memory may be free. This means system total status -may be not fatal yet. +The default is 1 percent. -If this is set to 2, the kernel panics compulsorily even on the -above-mentioned. +============================================================== -The default value is 0. -1 and 2 are for failover of clustering. Please select either -according to your policy of failover. +mmap_min_addr -============================================================= +This file indicates the amount of address space which a user process will +be restricted from mmaping. Since kernel null dereference bugs could +accidentally operate based on the information in the first couple of pages +of memory userspace processes should not be allowed to write to them. By +default this value is set to 0 and no protections will be enforced by the +security module. Setting this value to something like 64k will allow the +vast majority of applications to work correctly and provide defense in depth +against future potential kernel bugs. -oom_dump_tasks +============================================================== -Enables a system-wide task dump (excluding kernel threads) to be -produced when the kernel performs an OOM-killing and includes such -information as pid, uid, tgid, vm size, rss, cpu, oom_adj score, and -name. This is helpful to determine why the OOM killer was invoked -and to identify the rogue task that caused it. +nr_hugepages -If this is set to zero, this information is suppressed. On very -large systems with thousands of tasks it may not be feasible to dump -the memory state information for each one. Such systems should not -be forced to incur a performance penalty in OOM conditions when the -information may not be desired. +Change the minimum size of the hugepage pool. -If this is set to non-zero, this information is shown whenever the -OOM killer actually kills a memory-hogging task. +See Documentation/vm/hugetlbpage.txt -The default value is 0. +============================================================== -============================================================= +nr_overcommit_hugepages -oom_kill_allocating_task +Change the maximum size of the hugepage pool. The maximum is +nr_hugepages + nr_overcommit_hugepages. -This enables or disables killing the OOM-triggering task in -out-of-memory situations. +See Documentation/vm/hugetlbpage.txt -If this is set to zero, the OOM killer will scan through the entire -tasklist and select a task based on heuristics to kill. This normally -selects a rogue memory-hogging task that frees up a large amount of -memory when killed. +============================================================== -If this is set to non-zero, the OOM killer simply kills the task that -triggered the out-of-memory condition. This avoids the expensive -tasklist scan. +nr_pdflush_threads -If panic_on_oom is selected, it takes precedence over whatever value -is used in oom_kill_allocating_task. +The current number of pdflush threads. This value is read-only. +The value changes according to the number of dirty pages in the system. -The default value is 0. +When neccessary, additional pdflush threads are created, one per second, up to +nr_pdflush_threads_max. ============================================================== -mmap_min_addr +nr_trim_pages -This file indicates the amount of address space which a user process will -be restricted from mmaping. Since kernel null dereference bugs could -accidentally operate based on the information in the first couple of pages -of memory userspace processes should not be allowed to write to them. By -default this value is set to 0 and no protections will be enforced by the -security module. Setting this value to something like 64k will allow the -vast majority of applications to work correctly and provide defense in depth -against future potential kernel bugs. +This is available only on NOMMU kernels. + +This value adjusts the excess page trimming behaviour of power-of-2 aligned +NOMMU mmap allocations. + +A value of 0 disables trimming of allocations entirely, while a value of 1 +trims excess pages aggressively. Any value >= 1 acts as the watermark where +trimming of allocations is initiated. + +The default value is 1. + +See Documentation/nommu-mmap.txt for more information. ============================================================== @@ -335,34 +421,199 @@ this is causing problems for your system/application. ============================================================== -nr_hugepages +oom_dump_tasks -Change the minimum size of the hugepage pool. +Enables a system-wide task dump (excluding kernel threads) to be +produced when the kernel performs an OOM-killing and includes such +information as pid, uid, tgid, vm size, rss, cpu, oom_adj score, and +name. This is helpful to determine why the OOM killer was invoked +and to identify the rogue task that caused it. -See Documentation/vm/hugetlbpage.txt +If this is set to zero, this information is suppressed. On very +large systems with thousands of tasks it may not be feasible to dump +the memory state information for each one. Such systems should not +be forced to incur a performance penalty in OOM conditions when the +information may not be desired. + +If this is set to non-zero, this information is shown whenever the +OOM killer actually kills a memory-hogging task. + +The default value is 0. ============================================================== -nr_overcommit_hugepages +oom_kill_allocating_task -Change the maximum size of the hugepage pool. The maximum is -nr_hugepages + nr_overcommit_hugepages. +This enables or disables killing the OOM-triggering task in +out-of-memory situations. -See Documentation/vm/hugetlbpage.txt +If this is set to zero, the OOM killer will scan through the entire +tasklist and select a task based on heuristics to kill. This normally +selects a rogue memory-hogging task that frees up a large amount of +memory when killed. + +If this is set to non-zero, the OOM killer simply kills the task that +triggered the out-of-memory condition. This avoids the expensive +tasklist scan. + +If panic_on_oom is selected, it takes precedence over whatever value +is used in oom_kill_allocating_task. + +The default value is 0. ============================================================== -nr_trim_pages +overcommit_memory: -This is available only on NOMMU kernels. +This value contains a flag that enables memory overcommitment. -This value adjusts the excess page trimming behaviour of power-of-2 aligned -NOMMU mmap allocations. +When this flag is 0, the kernel attempts to estimate the amount +of free memory left when userspace requests more memory. -A value of 0 disables trimming of allocations entirely, while a value of 1 -trims excess pages aggressively. Any value >= 1 acts as the watermark where -trimming of allocations is initiated. +When this flag is 1, the kernel pretends there is always enough +memory until it actually runs out. -The default value is 1. +When this flag is 2, the kernel uses a "never overcommit" +policy that attempts to prevent any overcommit of memory. -See Documentation/nommu-mmap.txt for more information. +This feature can be very useful because there are a lot of +programs that malloc() huge amounts of memory "just-in-case" +and don't use much of it. + +The default value is 0. + +See Documentation/vm/overcommit-accounting and +security/commoncap.c::cap_vm_enough_memory() for more information. + +============================================================== + +overcommit_ratio: + +When overcommit_memory is set to 2, the committed address +space is not permitted to exceed swap plus this percentage +of physical RAM. See above. + +============================================================== + +page-cluster + +page-cluster controls the number of pages which are written to swap in +a single attempt. The swap I/O size. + +It is a logarithmic value - setting it to zero means "1 page", setting +it to 1 means "2 pages", setting it to 2 means "4 pages", etc. + +The default value is three (eight pages at a time). There may be some +small benefits in tuning this to a different value if your workload is +swap-intensive. + +============================================================= + +panic_on_oom + +This enables or disables panic on out-of-memory feature. + +If this is set to 0, the kernel will kill some rogue process, +called oom_killer. Usually, oom_killer can kill rogue processes and +system will survive. + +If this is set to 1, the kernel panics when out-of-memory happens. +However, if a process limits using nodes by mempolicy/cpusets, +and those nodes become memory exhaustion status, one process +may be killed by oom-killer. No panic occurs in this case. +Because other nodes' memory may be free. This means system total status +may be not fatal yet. + +If this is set to 2, the kernel panics compulsorily even on the +above-mentioned. + +The default value is 0. +1 and 2 are for failover of clustering. Please select either +according to your policy of failover. + +============================================================= + +percpu_pagelist_fraction + +This is the fraction of pages at most (high mark pcp->high) in each zone that +are allocated for each per cpu page list. The min value for this is 8. It +means that we don't allow more than 1/8th of pages in each zone to be +allocated in any single per_cpu_pagelist. This entry only changes the value +of hot per cpu pagelists. User can specify a number like 100 to allocate +1/100th of each zone to each per cpu page list. + +The batch value of each per cpu pagelist is also updated as a result. It is +set to pcp->high/4. The upper limit of batch is (PAGE_SHIFT * 8) + +The initial value is zero. Kernel does not use this value at boot time to set +the high water marks for each per cpu page list. + +============================================================== + +stat_interval + +The time interval between which vm statistics are updated. The default +is 1 second. + +============================================================== + +swappiness + +This control is used to define how aggressive the kernel will swap +memory pages. Higher values will increase agressiveness, lower values +descrease the amount of swap. + +The default value is 60. + +============================================================== + +vfs_cache_pressure +------------------ + +Controls the tendency of the kernel to reclaim the memory which is used for +caching of directory and inode objects. + +At the default value of vfs_cache_pressure=100 the kernel will attempt to +reclaim dentries and inodes at a "fair" rate with respect to pagecache and +swapcache reclaim. Decreasing vfs_cache_pressure causes the kernel to prefer +to retain dentry and inode caches. Increasing vfs_cache_pressure beyond 100 +causes the kernel to prefer to reclaim dentries and inodes. + +============================================================== + +zone_reclaim_mode: + +Zone_reclaim_mode allows someone to set more or less aggressive approaches to +reclaim memory when a zone runs out of memory. If it is set to zero then no +zone reclaim occurs. Allocations will be satisfied from other zones / nodes +in the system. + +This is value ORed together of + +1 = Zone reclaim on +2 = Zone reclaim writes dirty pages out +4 = Zone reclaim swaps pages + +zone_reclaim_mode is set during bootup to 1 if it is determined that pages +from remote zones will cause a measurable performance reduction. The +page allocator will then reclaim easily reusable pages (those page +cache pages that are currently not used) before allocating off node pages. + +It may be beneficial to switch off zone reclaim if the system is +used for a file server and all of memory should be used for caching files +from disk. In that case the caching effect is more important than +data locality. + +Allowing zone reclaim to write out pages stops processes that are +writing large amounts of data from dirtying pages on other nodes. Zone +reclaim will write out dirty pages if a zone fills up and so effectively +throttle the process. This may decrease the performance of a single process +since it cannot use all of system memory to buffer the outgoing writes +anymore but it preserve the memory on other nodes so that the performance +of other processes running on other nodes will not be affected. + +Allowing regular swap effectively restricts allocations to the local +node unless explicitly overridden by memory policies or cpuset +configurations. + +============ End of Document ================================= -- cgit From 1f14081d8b31b2780e2e6e2ae2766264e1f7d38b Mon Sep 17 00:00:00 2001 From: Itai Levi Date: Thu, 15 Jan 2009 13:50:43 -0800 Subject: atmel_serial: fix flow control bug Fix the following problem, related to hardware flow control (CTS/RTS): Transmitting while CTS line is asserted in DMA mode, due to not checking for tx-stopped condition. We found these problems while testing the UARTs with hardware flow-control. Signed-off-by: Haavard Skinnemoen Cc: "Andrew Victor" Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/atmel_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c index d5efd6c7790..89362d733d6 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/serial/atmel_serial.c @@ -579,7 +579,7 @@ static void atmel_tx_dma(struct uart_port *port) /* disable PDC transmit */ UART_PUT_PTCR(port, ATMEL_PDC_TXTDIS); - if (!uart_circ_empty(xmit)) { + if (!uart_circ_empty(xmit) && !uart_tx_stopped(port)) { dma_sync_single_for_device(port->dev, pdc->dma_addr, pdc->dma_size, -- cgit From 5b96f1729064453e09805a387378e0644da1c937 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 15 Jan 2009 13:50:44 -0800 Subject: atmel_spi: allow transfer when max_speed_hz = 0 For some reason I have to slowdown clock to touchscreen device. In atmel_spi_setup() there is comment that max_speed_hz == 0 means as slow as possible and divider is set to maximum value. But in atmel_spi_transfer() function is check against not zero max_speed_hz with EINVAL returned. Probably driver should setup divider for each transfer based on transfer->speed_hz value, but I think that would be not necessary overhead as all used devices have constant clock. Below patch works fine for me. Signed-off-by: Stanislaw Gruszka Signed-off-by: Haavard Skinnemoen Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/spi/atmel_spi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index 5e39bac9c51..56ff3e6864e 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c @@ -670,8 +670,7 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg) dev_dbg(controller, "new message %p submitted for %s\n", msg, spi->dev.bus_id); - if (unlikely(list_empty(&msg->transfers) - || !spi->max_speed_hz)) + if (unlikely(list_empty(&msg->transfers))) return -EINVAL; if (as->stopping) -- cgit From a342d215c206d955fea55d778e3803b29ee41b60 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 15 Jan 2009 13:50:45 -0800 Subject: gpio: fix probe() error return in gpio driver probes A number of drivers in drivers/gpio return -ENODEV when confronted with missing setup parameters such as the platform data. However, returning -ENODEV causes the driver layer to silently ignore the driver as it assumes the probe did not find anything and was only speculative. To make life easier to discern why a driver is not being attached, change to returning -EINVAL, which is a better description of the fact that the driver data was not valid. Also add a set of dev_dbg() statements to the error paths to provide an better explanation of the error as there may be more that one point in the driver. Signed-off-by: Ben Dooks Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/gpio/max7301.c | 6 ++++-- drivers/gpio/max732x.c | 6 ++++-- drivers/gpio/mcp23s08.c | 6 ++++-- drivers/gpio/pca953x.c | 6 ++++-- drivers/gpio/pcf857x.c | 12 ++++++++---- 5 files changed, 24 insertions(+), 12 deletions(-) diff --git a/drivers/gpio/max7301.c b/drivers/gpio/max7301.c index 8b24d784db9..3e7f4e06386 100644 --- a/drivers/gpio/max7301.c +++ b/drivers/gpio/max7301.c @@ -217,8 +217,10 @@ static int __devinit max7301_probe(struct spi_device *spi) int i, ret; pdata = spi->dev.platform_data; - if (!pdata || !pdata->base) - return -ENODEV; + if (!pdata || !pdata->base) { + dev_dbg(&spi->dev, "incorrect or missing platform data\n"); + return -EINVAL; + } /* * bits_per_word cannot be configured in platform data diff --git a/drivers/gpio/max732x.c b/drivers/gpio/max732x.c index 55ae9a41897..f7868243af8 100644 --- a/drivers/gpio/max732x.c +++ b/drivers/gpio/max732x.c @@ -267,8 +267,10 @@ static int __devinit max732x_probe(struct i2c_client *client, int ret, nr_port; pdata = client->dev.platform_data; - if (pdata == NULL) - return -ENODEV; + if (pdata == NULL) { + dev_dbg(&client->dev, "no platform data\n"); + return -EINVAL; + } chip = kzalloc(sizeof(struct max732x_chip), GFP_KERNEL); if (chip == NULL) diff --git a/drivers/gpio/mcp23s08.c b/drivers/gpio/mcp23s08.c index 89c1d222e9d..f6fae0e50e6 100644 --- a/drivers/gpio/mcp23s08.c +++ b/drivers/gpio/mcp23s08.c @@ -310,8 +310,10 @@ static int mcp23s08_probe(struct spi_device *spi) unsigned base; pdata = spi->dev.platform_data; - if (!pdata || !gpio_is_valid(pdata->base)) - return -ENODEV; + if (!pdata || !gpio_is_valid(pdata->base)) { + dev_dbg(&spi->dev, "invalid or missing platform data\n"); + return -EINVAL; + } for (addr = 0; addr < 4; addr++) { if (!pdata->chip[addr].is_present) diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index 37f35388a2a..8dc0164bd51 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c @@ -202,8 +202,10 @@ static int __devinit pca953x_probe(struct i2c_client *client, int ret; pdata = client->dev.platform_data; - if (pdata == NULL) - return -ENODEV; + if (pdata == NULL) { + dev_dbg(&client->dev, "no platform data\n"); + return -EINVAL; + } chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); if (chip == NULL) diff --git a/drivers/gpio/pcf857x.c b/drivers/gpio/pcf857x.c index 4bc2070dd4a..9525724be73 100644 --- a/drivers/gpio/pcf857x.c +++ b/drivers/gpio/pcf857x.c @@ -188,8 +188,10 @@ static int pcf857x_probe(struct i2c_client *client, int status; pdata = client->dev.platform_data; - if (!pdata) - return -ENODEV; + if (!pdata) { + dev_dbg(&client->dev, "no platform data\n"); + return -EINVAL; + } /* Allocate, initialize, and register this gpio_chip. */ gpio = kzalloc(sizeof *gpio, GFP_KERNEL); @@ -248,8 +250,10 @@ static int pcf857x_probe(struct i2c_client *client, else status = i2c_read_le16(client); - } else - status = -ENODEV; + } else { + dev_dbg(&client->dev, "unsupported number of gpios\n"); + status = -EINVAL; + } if (status < 0) goto fail; -- cgit From b46578ed094122a6b36002c644711cef68aa9c9e Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 15 Jan 2009 13:50:46 -0800 Subject: video/framebuffer: fix bug: jpegview cannot work on framebuffer device other than 16BPP Force fb_var_screeninfo color format on all Blackfin Framebuffer Drivers. Signed-off-by: Michael Hennerich Signed-off-by: Bryan Wu Cc: Mike Frysinger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/bf54x-lq043fb.c | 15 ++++++++++++++- drivers/video/bfin-t350mcqb-fb.c | 15 ++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c index 7644ed24956..37e60b1d2ed 100644 --- a/drivers/video/bf54x-lq043fb.c +++ b/drivers/video/bf54x-lq043fb.c @@ -335,7 +335,20 @@ static int bfin_bf54x_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { - if (var->bits_per_pixel != LCD_BPP) { + switch (var->bits_per_pixel) { + case 24:/* TRUECOLOUR, 16m */ + var->red.offset = 16; + var->green.offset = 8; + var->blue.offset = 0; + var->red.length = var->green.length = var->blue.length = 8; + var->transp.offset = 0; + var->transp.length = 0; + var->transp.msb_right = 0; + var->red.msb_right = 0; + var->green.msb_right = 0; + var->blue.msb_right = 0; + break; + default: pr_debug("%s: depth not supported: %u BPP\n", __func__, var->bits_per_pixel); return -EINVAL; diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c index a9b3ada05d9..2a423d3a2a8 100644 --- a/drivers/video/bfin-t350mcqb-fb.c +++ b/drivers/video/bfin-t350mcqb-fb.c @@ -254,7 +254,20 @@ static int bfin_t350mcqb_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { - if (var->bits_per_pixel != LCD_BPP) { + switch (var->bits_per_pixel) { + case 24:/* TRUECOLOUR, 16m */ + var->red.offset = 0; + var->green.offset = 8; + var->blue.offset = 16; + var->red.length = var->green.length = var->blue.length = 8; + var->transp.offset = 0; + var->transp.length = 0; + var->transp.msb_right = 0; + var->red.msb_right = 0; + var->green.msb_right = 0; + var->blue.msb_right = 0; + break; + default: pr_debug("%s: depth not supported: %u BPP\n", __func__, var->bits_per_pixel); return -EINVAL; -- cgit From 822c18f2e38cbc775792ab65ace4f9198678dec9 Mon Sep 17 00:00:00 2001 From: Ivan Kokshaysky Date: Thu, 15 Jan 2009 13:50:48 -0800 Subject: alpha: fix vmalloc breakage On alpha, we have to map some stuff in the VMALLOC space very early in the boot process (to make SRM console callbacks work and so on, see arch/alpha/mm/init.c). For old VM allocator, we just manually placed a vm_struct onto the global vmlist and this worked for ages. Unfortunately, the new allocator isn't aware of this, so it constantly tries to allocate the VM space which is already in use, making vmalloc on alpha defunct. This patch forces KVA to import vmlist entries on init. [akpm@linux-foundation.org: remove unneeded check (per Johannes)] Signed-off-by: Ivan Kokshaysky Cc: Nick Piggin Cc: Johannes Weiner Cc: Richard Henderson Cc: Johannes Weiner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmalloc.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index c5db9a7264d..7e00b280648 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -984,6 +985,8 @@ EXPORT_SYMBOL(vm_map_ram); void __init vmalloc_init(void) { + struct vmap_area *va; + struct vm_struct *tmp; int i; for_each_possible_cpu(i) { @@ -996,6 +999,14 @@ void __init vmalloc_init(void) vbq->nr_dirty = 0; } + /* Import existing vmlist entries. */ + for (tmp = vmlist; tmp; tmp = tmp->next) { + va = alloc_bootmem(sizeof(struct vmap_area)); + va->flags = tmp->flags | VM_VM_AREA; + va->va_start = (unsigned long)tmp->addr; + va->va_end = va->va_start + tmp->size; + __insert_vmap_area(va); + } vmap_initialized = true; } -- cgit From 44c12cb2f564b532971c1474073fcbbb8336242e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 15 Jan 2009 13:50:49 -0800 Subject: edac: add MAINTAINERS entry for i5400 EDAC driver i5400 EDAC driver were added upstream by those changesets: - 920c8df6ac678fdb8c49a6ce2e47a98e62757d77 "edac: driver for i5400 MCH (Seaburg)" - 8375d4909aee4c18798f373ecf24a79f040f75fc "edac: driver for i5400 MCH (update)" Update MAINTAINERS entry for this file to correspond to the driver maintainer. Signed-off-by: Mauro Carvalho Chehab Cc: Ben Woodard Cc: Doug Thompson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 3f6ef02ad68..73548f8ad0b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1581,6 +1581,13 @@ L: bluesmoke-devel@lists.sourceforge.net W: bluesmoke.sourceforge.net S: Maintained +EDAC-I5400 +P: Mauro Carvalho Chehab +M: mchehab@redhat.com +L: bluesmoke-devel@lists.sourceforge.net +W: bluesmoke.sourceforge.net +S: Maintained + EDAC-I82975X P: Ranganathan Desikan P: Arvind R. -- cgit From 89365e264104b52da6a61c4e227bb5a934764fa7 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Thu, 15 Jan 2009 13:50:50 -0800 Subject: sysrq documentation: remove the redundant updated date git is maintaining the last update time much more accuratly than the internal update time. Remove it. Signed-off-by: Andy Whitcroft Cc: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/sysrq.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/sysrq.txt b/Documentation/sysrq.txt index 10a0263ebb3..265f637b97d 100644 --- a/Documentation/sysrq.txt +++ b/Documentation/sysrq.txt @@ -1,6 +1,5 @@ Linux Magic System Request Key Hacks Documentation for sysrq.c -Last update: 2007-AUG-04 * What is the magic SysRq key? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- cgit From 47c33d9c1984ae4c5bd1f144024eacc14c5bc0c0 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Thu, 15 Jan 2009 13:50:51 -0800 Subject: sysrq documentation: document why the command header only is shown Document the interactions between loglevel and the sysrq output. Also document how to work round it should output be required on the console. Signed-off-by: Andy Whitcroft Cc: Martin Mares Cc: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/sysrq.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Documentation/sysrq.txt b/Documentation/sysrq.txt index 265f637b97d..9e592c718af 100644 --- a/Documentation/sysrq.txt +++ b/Documentation/sysrq.txt @@ -210,6 +210,24 @@ within a function called by handle_sysrq, you must be aware that you are in a lock (you are also in an interrupt handler, which means don't sleep!), so you must call __handle_sysrq_nolock instead. +* When I hit a SysRq key combination only the header appears on the console? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Sysrq output is subject to the same console loglevel control as all +other console output. This means that if the kernel was booted 'quiet' +as is common on distro kernels the output may not appear on the actual +console, even though it will appear in the dmesg buffer, and be accessible +via the dmesg command and to the consumers of /proc/kmsg. As a specific +exception the header line from the sysrq command is passed to all console +consumers as if the current loglevel was maximum. If only the header +is emitted it is almost certain that the kernel loglevel is too low. +Should you require the output on the console channel then you will need +to temporarily up the console loglevel using alt-sysrq-8 or: + + echo 8 > /proc/sysrq-trigger + +Remember to return the loglevel to normal after triggering the sysrq +command you are interested in. + * I have more questions, who can I ask? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ And I'll answer any questions about the registration system you got, also -- cgit From fb144adc517d9ebe8fd8d98a5696fb68ec91e1f5 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Thu, 15 Jan 2009 13:50:52 -0800 Subject: sysrq: add commentary on why we use the console loglevel over using KERN_EMERG Add an explanitory comment as to why we modify the kernel console loglevel rather than simply moving sysrq messages to KERN_EMERG level. Signed-off-by: Andy Whitcroft Cc: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/sysrq.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index d41b9f6f790..33a9351c896 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c @@ -473,6 +473,12 @@ void __handle_sysrq(int key, struct tty_struct *tty, int check_mask) unsigned long flags; spin_lock_irqsave(&sysrq_key_table_lock, flags); + /* + * Raise the apparent loglevel to maximum so that the sysrq header + * is shown to provide the user with positive feedback. We do not + * simply emit this at KERN_EMERG as that would change message + * routing in the consumers of /proc/kmsg. + */ orig_log_level = console_loglevel; console_loglevel = 7; printk(KERN_INFO "SysRq : "); -- cgit From a748384bba1754409383ba9f0738bffdfa3fd431 Mon Sep 17 00:00:00 2001 From: Alessandro Zummo Date: Thu, 15 Jan 2009 13:50:52 -0800 Subject: rtc: tw4030 add alarm/update interfaces - implement alarm_irq_enable - return correct error code when registering fails [dbrownell@users.sourceforge.net: build fixes, force 1/sec irqs] Signed-off-by: Alessandro Zummo Signed-off-by: David Brownell Cc: Tony Lindgren Cc: Samuel Ortiz Cc: rtc-linux@googlegroups.com Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-twl4030.c | 44 ++++++++++---------------------------------- 1 file changed, 10 insertions(+), 34 deletions(-) diff --git a/drivers/rtc/rtc-twl4030.c b/drivers/rtc/rtc-twl4030.c index 8ce5f74ee45..25dc3e1cedb 100644 --- a/drivers/rtc/rtc-twl4030.c +++ b/drivers/rtc/rtc-twl4030.c @@ -120,7 +120,7 @@ static int twl4030_rtc_write_u8(u8 data, u8 reg) static unsigned char rtc_irq_bits; /* - * Enable timer and/or alarm interrupts. + * Enable 1/second update and/or alarm interrupts. */ static int set_rtc_irq_bit(unsigned char bit) { @@ -128,6 +128,7 @@ static int set_rtc_irq_bit(unsigned char bit) int ret; val = rtc_irq_bits | bit; + val &= ~BIT_RTC_INTERRUPTS_REG_EVERY_M; ret = twl4030_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG); if (ret == 0) rtc_irq_bits = val; @@ -136,7 +137,7 @@ static int set_rtc_irq_bit(unsigned char bit) } /* - * Disable timer and/or alarm interrupts. + * Disable update and/or alarm interrupts. */ static int mask_rtc_irq_bit(unsigned char bit) { @@ -151,7 +152,7 @@ static int mask_rtc_irq_bit(unsigned char bit) return ret; } -static inline int twl4030_rtc_alarm_irq_set_state(int enabled) +static int twl4030_rtc_alarm_irq_enable(struct device *dev, unsigned enabled) { int ret; @@ -163,7 +164,7 @@ static inline int twl4030_rtc_alarm_irq_set_state(int enabled) return ret; } -static inline int twl4030_rtc_irq_set_state(int enabled) +static int twl4030_rtc_update_irq_enable(struct device *dev, unsigned enabled) { int ret; @@ -292,7 +293,7 @@ static int twl4030_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) unsigned char alarm_data[ALL_TIME_REGS + 1]; int ret; - ret = twl4030_rtc_alarm_irq_set_state(0); + ret = twl4030_rtc_alarm_irq_enable(dev, 0); if (ret) goto out; @@ -312,35 +313,11 @@ static int twl4030_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) } if (alm->enabled) - ret = twl4030_rtc_alarm_irq_set_state(1); + ret = twl4030_rtc_alarm_irq_enable(dev, 1); out: return ret; } -#ifdef CONFIG_RTC_INTF_DEV - -static int twl4030_rtc_ioctl(struct device *dev, unsigned int cmd, - unsigned long arg) -{ - switch (cmd) { - case RTC_AIE_OFF: - return twl4030_rtc_alarm_irq_set_state(0); - case RTC_AIE_ON: - return twl4030_rtc_alarm_irq_set_state(1); - case RTC_UIE_OFF: - return twl4030_rtc_irq_set_state(0); - case RTC_UIE_ON: - return twl4030_rtc_irq_set_state(1); - - default: - return -ENOIOCTLCMD; - } -} - -#else -#define twl4030_rtc_ioctl NULL -#endif - static irqreturn_t twl4030_rtc_interrupt(int irq, void *rtc) { unsigned long events = 0; @@ -400,11 +377,12 @@ out: } static struct rtc_class_ops twl4030_rtc_ops = { - .ioctl = twl4030_rtc_ioctl, .read_time = twl4030_rtc_read_time, .set_time = twl4030_rtc_set_time, .read_alarm = twl4030_rtc_read_alarm, .set_alarm = twl4030_rtc_set_alarm, + .alarm_irq_enable = twl4030_rtc_alarm_irq_enable, + .update_irq_enable = twl4030_rtc_update_irq_enable, }; /*----------------------------------------------------------------------*/ @@ -422,7 +400,7 @@ static int __devinit twl4030_rtc_probe(struct platform_device *pdev) rtc = rtc_device_register(pdev->name, &pdev->dev, &twl4030_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { - ret = -EINVAL; + ret = PTR_ERR(rtc); dev_err(&pdev->dev, "can't register RTC device, err %ld\n", PTR_ERR(rtc)); goto out0; @@ -432,7 +410,6 @@ static int __devinit twl4030_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, rtc); ret = twl4030_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG); - if (ret < 0) goto out1; @@ -475,7 +452,6 @@ static int __devinit twl4030_rtc_probe(struct platform_device *pdev) return ret; - out2: free_irq(irq, rtc); out1: -- cgit From 4216d0bd8fef77b7926eb065a766e2ee003acf6a Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Thu, 15 Jan 2009 13:50:54 -0800 Subject: rtc-pxa: fix build failure Fix these build errors: CC drivers/rtc/rtc-pxa.o drivers/rtc/rtc-pxa.c: In function `pxa_rtc_init': drivers/rtc/rtc-pxa.c:472: error: implicit declaration of function `cpu_is_pxa27x' drivers/rtc/rtc-pxa.c:472: error: implicit declaration of function `cpu_is_pxa3xx' Signed-off-by: Antonio Ospite Signed-off-by: Alessandro Zummo Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-pxa.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c index cc7eb8767b8..bd56a033bfd 100644 --- a/drivers/rtc/rtc-pxa.c +++ b/drivers/rtc/rtc-pxa.c @@ -27,6 +27,8 @@ #include #include +#include + #define TIMER_FREQ CLOCK_TICK_RATE #define RTC_DEF_DIVIDER (32768 - 1) #define RTC_DEF_TRIM 0 -- cgit From cafa1d8b0c90252e73f20db1b6f32cf88e73ff17 Mon Sep 17 00:00:00 2001 From: Matti Halme Date: Thu, 15 Jan 2009 13:50:56 -0800 Subject: rtc: rtc-twl4030 don't mask alarm interrupts on shutdown A triggering RTC alarm should be able to power on a device that has been powered off. This patch enables that on twl4030 by not masking the alarm interrupt at shutdown. Signed-off-by: Matti Halme Signed-off-by: Alessandro Zummo Acked-by: David Brownell Cc: Tony Lindgren Cc: Samuel Ortiz Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-twl4030.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc-twl4030.c b/drivers/rtc/rtc-twl4030.c index 25dc3e1cedb..ad35f76c46b 100644 --- a/drivers/rtc/rtc-twl4030.c +++ b/drivers/rtc/rtc-twl4030.c @@ -482,8 +482,9 @@ static int __devexit twl4030_rtc_remove(struct platform_device *pdev) static void twl4030_rtc_shutdown(struct platform_device *pdev) { - mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M | - BIT_RTC_INTERRUPTS_REG_IT_ALARM_M); + /* mask timer interrupts, but leave alarm interrupts on to enable + power-on when alarm is triggered */ + mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M); } #ifdef CONFIG_PM -- cgit From 158bc69effbf96f59c01cdeb20f8d4c184e59f8e Mon Sep 17 00:00:00 2001 From: Dean Nelson Date: Thu, 15 Jan 2009 13:50:57 -0800 Subject: sgi-xp: eliminate false detection of no heartbeat After XPC has been up and running on multiple partitions for any length of time, if XPC on one of the partitions is stopped and restarted (either by a rmmod/insmod or a system restart), it is possible for the XPCs running on the other partitions to falsely detect a lack of heartbeat from the XPC that was just restarted. This false detection will occur if the restarted XPC comes up within the five-seconds preceding one of the other XPC's heartbeat check (which occurs once every twenty seconds). The detection of no heartbeat results in the detecting XPC deactivating from the just restarted XPC. The only remedy is to restart one of the XPCs and hope that one doesn't hit this five-second window on any of the other partitions. Signed-off-by: Dean Nelson Signed-off-by: Robin Holt Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/misc/sgi-xp/xpc_sn2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/sgi-xp/xpc_sn2.c b/drivers/misc/sgi-xp/xpc_sn2.c index 73b7fb8de47..82fb9958f22 100644 --- a/drivers/misc/sgi-xp/xpc_sn2.c +++ b/drivers/misc/sgi-xp/xpc_sn2.c @@ -899,7 +899,7 @@ xpc_update_partition_info_sn2(struct xpc_partition *part, u8 remote_rp_version, dev_dbg(xpc_part, " remote_vars_pa = 0x%016lx\n", part_sn2->remote_vars_pa); - part->last_heartbeat = remote_vars->heartbeat; + part->last_heartbeat = remote_vars->heartbeat - 1; dev_dbg(xpc_part, " last_heartbeat = 0x%016lx\n", part->last_heartbeat); -- cgit From a6b2f87be1aafedc585bad86b77c2e2bbd49b308 Mon Sep 17 00:00:00 2001 From: Paul Fulghum Date: Thu, 15 Jan 2009 13:50:57 -0800 Subject: synclink_gt: enable RI interrupt - Enable ring indicator interrupt. - Remove vendor specific CVS version tags. Signed-off-by: Paul Fulghum Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/synclink_gt.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index 53544e21f19..f329f459817 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c @@ -1,6 +1,4 @@ /* - * $Id: synclink_gt.c,v 4.50 2007/07/25 19:29:25 paulkf Exp $ - * * Device driver for Microgate SyncLink GT serial adapters. * * written by Paul Fulghum for Microgate Corporation @@ -91,7 +89,6 @@ * module identification */ static char *driver_name = "SyncLink GT"; -static char *driver_version = "$Revision: 4.50 $"; static char *tty_driver_name = "synclink_gt"; static char *tty_dev_prefix = "ttySLG"; MODULE_LICENSE("GPL"); @@ -1309,7 +1306,7 @@ static int read_proc(char *page, char **start, off_t off, int count, off_t begin = 0; struct slgt_info *info; - len += sprintf(page, "synclink_gt driver:%s\n", driver_version); + len += sprintf(page, "synclink_gt driver\n"); info = slgt_device_list; while( info ) { @@ -2441,7 +2438,7 @@ static void program_hw(struct slgt_info *info) info->ri_chkcount = 0; info->dsr_chkcount = 0; - slgt_irq_on(info, IRQ_DCD | IRQ_CTS | IRQ_DSR); + slgt_irq_on(info, IRQ_DCD | IRQ_CTS | IRQ_DSR | IRQ_RI); get_signals(info); if (info->netcount || @@ -3576,7 +3573,7 @@ static void slgt_cleanup(void) struct slgt_info *info; struct slgt_info *tmp; - printk("unload %s %s\n", driver_name, driver_version); + printk(KERN_INFO "unload %s\n", driver_name); if (serial_driver) { for (info=slgt_device_list ; info != NULL ; info=info->next_device) @@ -3619,7 +3616,7 @@ static int __init slgt_init(void) { int rc; - printk("%s %s\n", driver_name, driver_version); + printk(KERN_INFO "%s\n", driver_name); serial_driver = alloc_tty_driver(MAX_DEVICES); if (!serial_driver) { @@ -3650,9 +3647,8 @@ static int __init slgt_init(void) goto error; } - printk("%s %s, tty major#%d\n", - driver_name, driver_version, - serial_driver->major); + printk(KERN_INFO "%s, tty major#%d\n", + driver_name, serial_driver->major); slgt_device_count = 0; if ((rc = pci_register_driver(&pci_driver)) < 0) { -- cgit From 23964d2d02984d44aeb2d84d7ffb3359e728df43 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Thu, 15 Jan 2009 13:50:58 -0800 Subject: cgroups: clean up Kconfig - move CONFIG_PROC_PID_CPUSET into cgroup menu - move MM_OWNER to the bottom for better menu indent - fix typos - use tabs not spaces Signed-off-by: Li Zefan Acked-by: Paul Menage Acked-by: Balbir Singh Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- init/Kconfig | 56 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/init/Kconfig b/init/Kconfig index a724a149bf3..56fd93c63c7 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -328,11 +328,10 @@ config CGROUP_SCHED endchoice -menu "Control Group support" -config CGROUPS - bool "Control Group support" +menuconfig CGROUPS + boolean "Control Group support" help - This option add support for grouping sets of processes together, for + This option adds support for grouping sets of processes together, for use with process control subsystems such as Cpusets, CFS, memory controls or device isolation. See @@ -343,6 +342,8 @@ config CGROUPS Say N if unsure. +if CGROUPS + config CGROUP_DEBUG bool "Example debug cgroup subsystem" depends on CGROUPS @@ -350,24 +351,24 @@ config CGROUP_DEBUG help This option enables a simple cgroup subsystem that exports useful debugging information about the cgroups - framework + framework. - Say N if unsure + Say N if unsure. config CGROUP_NS - bool "Namespace cgroup subsystem" - depends on CGROUPS - help - Provides a simple namespace cgroup subsystem to - provide hierarchical naming of sets of namespaces, - for instance virtual servers and checkpoint/restart - jobs. + bool "Namespace cgroup subsystem" + depends on CGROUPS + help + Provides a simple namespace cgroup subsystem to + provide hierarchical naming of sets of namespaces, + for instance virtual servers and checkpoint/restart + jobs. config CGROUP_FREEZER - bool "control group freezer subsystem" - depends on CGROUPS - help - Provides a way to freeze and unfreeze all tasks in a + bool "Freezer cgroup subsystem" + depends on CGROUPS + help + Provides a way to freeze and unfreeze all tasks in a cgroup. config CGROUP_DEVICE @@ -388,18 +389,23 @@ config CPUSETS Say N if unsure. +config PROC_PID_CPUSET + bool "Include legacy /proc//cpuset file" + depends on CPUSETS + default y + config CGROUP_CPUACCT bool "Simple CPU accounting cgroup subsystem" depends on CGROUPS help Provides a simple Resource Controller for monitoring the - total CPU consumed by the tasks in a cgroup + total CPU consumed by the tasks in a cgroup. config RESOURCE_COUNTERS bool "Resource counters" help This option enables controller independent resource accounting - infrastructure that works with cgroups + infrastructure that works with cgroups. depends on CGROUPS config CGROUP_MEM_RES_CTLR @@ -425,9 +431,6 @@ config CGROUP_MEM_RES_CTLR This config option also selects MM_OWNER config option, which could in turn add some fork/exit overhead. -config MM_OWNER - bool - config CGROUP_MEM_RES_CTLR_SWAP bool "Memory Resource Controller Swap Extension(EXPERIMENTAL)" depends on CGROUP_MEM_RES_CTLR && SWAP && EXPERIMENTAL @@ -444,8 +447,10 @@ config CGROUP_MEM_RES_CTLR_SWAP there will be no overhead from this. Even when you set this config=y, if boot option "noswapaccount" is set, swap will not be accounted. +endif # CGROUPS -endmenu +config MM_OWNER + bool config SYSFS_DEPRECATED bool @@ -483,11 +488,6 @@ config SYSFS_DEPRECATED_V2 if the original kernel, that came with your distribution, has this option set to N. -config PROC_PID_CPUSET - bool "Include legacy /proc//cpuset file" - depends on CPUSETS - default y - config RELAY bool "Kernel->user space relay support (formerly relayfs)" help -- cgit From 45ce80fb6b6f9594d1396d44dd7e7c02d596fef8 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Thu, 15 Jan 2009 13:50:59 -0800 Subject: cgroups: consolidate cgroup documents Move Documentation/cpusets.txt and Documentation/controllers/* to Documentation/cgroups/ Signed-off-by: Li Zefan Acked-by: KAMEZAWA Hiroyuki Acked-by: Balbir Singh Acked-by: Paul Menage Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/cgroups/cgroups.txt | 5 +- Documentation/cgroups/cpuacct.txt | 32 + Documentation/cgroups/cpusets.txt | 808 +++++++++++++++++++++++++ Documentation/cgroups/devices.txt | 52 ++ Documentation/cgroups/memcg_test.txt | 342 +++++++++++ Documentation/cgroups/memory.txt | 399 ++++++++++++ Documentation/cgroups/resource_counter.txt | 181 ++++++ Documentation/controllers/cpuacct.txt | 32 - Documentation/controllers/devices.txt | 52 -- Documentation/controllers/memcg_test.txt | 342 ----------- Documentation/controllers/memory.txt | 399 ------------ Documentation/controllers/resource_counter.txt | 181 ------ Documentation/cpusets.txt | 808 ------------------------- Documentation/scheduler/sched-design-CFS.txt | 2 +- include/linux/res_counter.h | 2 +- init/Kconfig | 9 +- kernel/cpuset.c | 2 +- 17 files changed, 1824 insertions(+), 1824 deletions(-) create mode 100644 Documentation/cgroups/cpuacct.txt create mode 100644 Documentation/cgroups/cpusets.txt create mode 100644 Documentation/cgroups/devices.txt create mode 100644 Documentation/cgroups/memcg_test.txt create mode 100644 Documentation/cgroups/memory.txt create mode 100644 Documentation/cgroups/resource_counter.txt delete mode 100644 Documentation/controllers/cpuacct.txt delete mode 100644 Documentation/controllers/devices.txt delete mode 100644 Documentation/controllers/memcg_test.txt delete mode 100644 Documentation/controllers/memory.txt delete mode 100644 Documentation/controllers/resource_counter.txt delete mode 100644 Documentation/cpusets.txt diff --git a/Documentation/cgroups/cgroups.txt b/Documentation/cgroups/cgroups.txt index e33ee74eee7..d9e5d6f41b9 100644 --- a/Documentation/cgroups/cgroups.txt +++ b/Documentation/cgroups/cgroups.txt @@ -1,7 +1,8 @@ CGROUPS ------- -Written by Paul Menage based on Documentation/cpusets.txt +Written by Paul Menage based on +Documentation/cgroups/cpusets.txt Original copyright statements from cpusets.txt: Portions Copyright (C) 2004 BULL SA. @@ -68,7 +69,7 @@ On their own, the only use for cgroups is for simple job tracking. The intention is that other subsystems hook into the generic cgroup support to provide new attributes for cgroups, such as accounting/limiting the resources which processes in a cgroup can -access. For example, cpusets (see Documentation/cpusets.txt) allows +access. For example, cpusets (see Documentation/cgroups/cpusets.txt) allows you to associate a set of CPUs and a set of memory nodes with the tasks in each cgroup. diff --git a/Documentation/cgroups/cpuacct.txt b/Documentation/cgroups/cpuacct.txt new file mode 100644 index 00000000000..bb775fbe43d --- /dev/null +++ b/Documentation/cgroups/cpuacct.txt @@ -0,0 +1,32 @@ +CPU Accounting Controller +------------------------- + +The CPU accounting controller is used to group tasks using cgroups and +account the CPU usage of these groups of tasks. + +The CPU accounting controller supports multi-hierarchy groups. An accounting +group accumulates the CPU usage of all of its child groups and the tasks +directly present in its group. + +Accounting groups can be created by first mounting the cgroup filesystem. + +# mkdir /cgroups +# mount -t cgroup -ocpuacct none /cgroups + +With the above step, the initial or the parent accounting group +becomes visible at /cgroups. At bootup, this group includes all the +tasks in the system. /cgroups/tasks lists the tasks in this cgroup. +/cgroups/cpuacct.usage gives the CPU time (in nanoseconds) obtained by +this group which is essentially the CPU time obtained by all the tasks +in the system. + +New accounting groups can be created under the parent group /cgroups. + +# cd /cgroups +# mkdir g1 +# echo $$ > g1 + +The above steps create a new group g1 and move the current shell +process (bash) into it. CPU time consumed by this bash and its children +can be obtained from g1/cpuacct.usage and the same is accumulated in +/cgroups/cpuacct.usage also. diff --git a/Documentation/cgroups/cpusets.txt b/Documentation/cgroups/cpusets.txt new file mode 100644 index 00000000000..5c86c258c79 --- /dev/null +++ b/Documentation/cgroups/cpusets.txt @@ -0,0 +1,808 @@ + CPUSETS + ------- + +Copyright (C) 2004 BULL SA. +Written by Simon.Derr@bull.net + +Portions Copyright (c) 2004-2006 Silicon Graphics, Inc. +Modified by Paul Jackson +Modified by Christoph Lameter +Modified by Paul Menage +Modified by Hidetoshi Seto + +CONTENTS: +========= + +1. Cpusets + 1.1 What are cpusets ? + 1.2 Why are cpusets needed ? + 1.3 How are cpusets implemented ? + 1.4 What are exclusive cpusets ? + 1.5 What is memory_pressure ? + 1.6 What is memory spread ? + 1.7 What is sched_load_balance ? + 1.8 What is sched_relax_domain_level ? + 1.9 How do I use cpusets ? +2. Usage Examples and Syntax + 2.1 Basic Usage + 2.2 Adding/removing cpus + 2.3 Setting flags + 2.4 Attaching processes +3. Questions +4. Contact + +1. Cpusets +========== + +1.1 What are cpusets ? +---------------------- + +Cpusets provide a mechanism for assigning a set of CPUs and Memory +Nodes to a set of tasks. In this document "Memory Node" refers to +an on-line node that contains memory. + +Cpusets constrain the CPU and Memory placement of tasks to only +the resources within a tasks current cpuset. They form a nested +hierarchy visible in a virtual file system. These are the essential +hooks, beyond what is already present, required to manage dynamic +job placement on large systems. + +Cpusets use the generic cgroup subsystem described in +Documentation/cgroups/cgroups.txt. + +Requests by a task, using the sched_setaffinity(2) system call to +include CPUs in its CPU affinity mask, and using the mbind(2) and +set_mempolicy(2) system calls to include Memory Nodes in its memory +policy, are both filtered through that tasks cpuset, filtering out any +CPUs or Memory Nodes not in that cpuset. The scheduler will not +schedule a task on a CPU that is not allowed in its cpus_allowed +vector, and the kernel page allocator will not allocate a page on a +node that is not allowed in the requesting tasks mems_allowed vector. + +User level code may create and destroy cpusets by name in the cgroup +virtual file system, manage the attributes and permissions of these +cpusets and which CPUs and Memory Nodes are assigned to each cpuset, +specify and query to which cpuset a task is assigned, and list the +task pids assigned to a cpuset. + + +1.2 Why are cpusets needed ? +---------------------------- + +The management of large computer systems, with many processors (CPUs), +complex memory cache hierarchies and multiple Memory Nodes having +non-uniform access times (NUMA) presents additional challenges for +the efficient scheduling and memory placement of processes. + +Frequently more modest sized systems can be operated with adequate +efficiency just by letting the operating system automatically share +the available CPU and Memory resources amongst the requesting tasks. + +But larger systems, which benefit more from careful processor and +memory placement to reduce memory access times and contention, +and which typically represent a larger investment for the customer, +can benefit from explicitly placing jobs on properly sized subsets of +the system. + +This can be especially valuable on: + + * Web Servers running multiple instances of the same web application, + * Servers running different applications (for instance, a web server + and a database), or + * NUMA systems running large HPC applications with demanding + performance characteristics. + +These subsets, or "soft partitions" must be able to be dynamically +adjusted, as the job mix changes, without impacting other concurrently +executing jobs. The location of the running jobs pages may also be moved +when the memory locations are changed. + +The kernel cpuset patch provides the minimum essential kernel +mechanisms required to efficiently implement such subsets. It +leverages existing CPU and Memory Placement facilities in the Linux +kernel to avoid any additional impact on the critical scheduler or +memory allocator code. + + +1.3 How are cpusets implemented ? +--------------------------------- + +Cpusets provide a Linux kernel mechanism to constrain which CPUs and +Memory Nodes are used by a process or set of processes. + +The Linux kernel already has a pair of mechanisms to specify on which +CPUs a task may be scheduled (sched_setaffinity) and on which Memory +Nodes it may obtain memory (mbind, set_mempolicy). + +Cpusets extends these two mechanisms as follows: + + - Cpusets are sets of allowed CPUs and Memory Nodes, known to the + kernel. + - Each task in the system is attached to a cpuset, via a pointer + in the task structure to a reference counted cgroup structure. + - Calls to sched_setaffinity are filtered to just those CPUs + allowed in that tasks cpuset. + - Calls to mbind and set_mempolicy are filtered to just + those Memory Nodes allowed in that tasks cpuset. + - The root cpuset contains all the systems CPUs and Memory + Nodes. + - For any cpuset, one can define child cpusets containing a subset + of the parents CPU and Memory Node resources. + - The hierarchy of cpusets can be mounted at /dev/cpuset, for + browsing and manipulation from user space. + - A cpuset may be marked exclusive, which ensures that no other + cpuset (except direct ancestors and descendents) may contain + any overlapping CPUs or Memory Nodes. + - You can list all the tasks (by pid) attached to any cpuset. + +The implementation of cpusets requires a few, simple hooks +into the rest of the kernel, none in performance critical paths: + + - in init/main.c, to initialize the root cpuset at system boot. + - in fork and exit, to attach and detach a task from its cpuset. + - in sched_setaffinity, to mask the requested CPUs by what's + allowed in that tasks cpuset. + - in sched.c migrate_all_tasks(), to keep migrating tasks within + the CPUs allowed by their cpuset, if possible. + - in the mbind and set_mempolicy system calls, to mask the requested + Memory Nodes by what's allowed in that tasks cpuset. + - in page_alloc.c, to restrict memory to allowed nodes. + - in vmscan.c, to restrict page recovery to the current cpuset. + +You should mount the "cgroup" filesystem type in order to enable +browsing and modifying the cpusets presently known to the kernel. No +new system calls are added for cpusets - all support for querying and +modifying cpusets is via this cpuset file system. + +The /proc//status file for each task has four added lines, +displaying the tasks cpus_allowed (on which CPUs it may be scheduled) +and mems_allowed (on which Memory Nodes it may obtain memory), +in the two formats seen in the following example: + + Cpus_allowed: ffffffff,ffffffff,ffffffff,ffffffff + Cpus_allowed_list: 0-127 + Mems_allowed: ffffffff,ffffffff + Mems_allowed_list: 0-63 + +Each cpuset is represented by a directory in the cgroup file system +containing (on top of the standard cgroup files) the following +files describing that cpuset: + + - cpus: list of CPUs in that cpuset + - mems: list of Memory Nodes in that cpuset + - memory_migrate flag: if set, move pages to cpusets nodes + - cpu_exclusive flag: is cpu placement exclusive? + - mem_exclusive flag: is memory placement exclusive? + - mem_hardwall flag: is memory allocation hardwalled + - memory_pressure: measure of how much paging pressure in cpuset + +In addition, the root cpuset only has the following file: + - memory_pressure_enabled flag: compute memory_pressure? + +New cpusets are created using the mkdir system call or shell +command. The properties of a cpuset, such as its flags, allowed +CPUs and Memory Nodes, and attached tasks, are modified by writing +to the appropriate file in that cpusets directory, as listed above. + +The named hierarchical structure of nested cpusets allows partitioning +a large system into nested, dynamically changeable, "soft-partitions". + +The attachment of each task, automatically inherited at fork by any +children of that task, to a cpuset allows organizing the work load +on a system into related sets of tasks such that each set is constrained +to using the CPUs and Memory Nodes of a particular cpuset. A task +may be re-attached to any other cpuset, if allowed by the permissions +on the necessary cpuset file system directories. + +Such management of a system "in the large" integrates smoothly with +the detailed placement done on individual tasks and memory regions +using the sched_setaffinity, mbind and set_mempolicy system calls. + +The following rules apply to each cpuset: + + - Its CPUs and Memory Nodes must be a subset of its parents. + - It can't be marked exclusive unless its parent is. + - If its cpu or memory is exclusive, they may not overlap any sibling. + +These rules, and the natural hierarchy of cpusets, enable efficient +enforcement of the exclusive guarantee, without having to scan all +cpusets every time any of them change to ensure nothing overlaps a +exclusive cpuset. Also, the use of a Linux virtual file system (vfs) +to represent the cpuset hierarchy provides for a familiar permission +and name space for cpusets, with a minimum of additional kernel code. + +The cpus and mems files in the root (top_cpuset) cpuset are +read-only. The cpus file automatically tracks the value of +cpu_online_map using a CPU hotplug notifier, and the mems file +automatically tracks the value of node_states[N_HIGH_MEMORY]--i.e., +nodes with memory--using the cpuset_track_online_nodes() hook. + + +1.4 What are exclusive cpusets ? +-------------------------------- + +If a cpuset is cpu or mem exclusive, no other cpuset, other than +a direct ancestor or descendent, may share any of the same CPUs or +Memory Nodes. + +A cpuset that is mem_exclusive *or* mem_hardwall is "hardwalled", +i.e. it restricts kernel allocations for page, buffer and other data +commonly shared by the kernel across multiple users. All cpusets, +whether hardwalled or not, restrict allocations of memory for user +space. This enables configuring a system so that several independent +jobs can share common kernel data, such as file system pages, while +isolating each job's user allocation in its own cpuset. To do this, +construct a large mem_exclusive cpuset to hold all the jobs, and +construct child, non-mem_exclusive cpusets for each individual job. +Only a small amount of typical kernel memory, such as requests from +interrupt handlers, is allowed to be taken outside even a +mem_exclusive cpuset. + + +1.5 What is memory_pressure ? +----------------------------- +The memory_pressure of a cpuset provides a simple per-cpuset metric +of the rate that the tasks in a cpuset are attempting to free up in +use memory on the nodes of the cpuset to satisfy additional memory +requests. + +This enables batch managers monitoring jobs running in dedicated +cpusets to efficiently detect what level of memory pressure that job +is causing. + +This is useful both on tightly managed systems running a wide mix of +submitted jobs, which may choose to terminate or re-prioritize jobs that +are trying to use more memory than allowed on the nodes assigned them, +and with tightly coupled, long running, massively parallel scientific +computing jobs that will dramatically fail to meet required performance +goals if they start to use more memory than allowed to them. + +This mechanism provides a very economical way for the batch manager +to monitor a cpuset for signs of memory pressure. It's up to the +batch manager or other user code to decide what to do about it and +take action. + +==> Unless this feature is enabled by writing "1" to the special file + /dev/cpuset/memory_pressure_enabled, the hook in the rebalance + code of __alloc_pages() for this metric reduces to simply noticing + that the cpuset_memory_pressure_enabled flag is zero. So only + systems that enable this feature will compute the metric. + +Why a per-cpuset, running average: + + Because this meter is per-cpuset, rather than per-task or mm, + the system load imposed by a batch scheduler monitoring this + metric is sharply reduced on large systems, because a scan of + the tasklist can be avoided on each set of queries. + + Because this meter is a running average, instead of an accumulating + counter, a batch scheduler can detect memory pressure with a + single read, instead of having to read and accumulate results + for a period of time. + + Because this meter is per-cpuset rather than per-task or mm, + the batch scheduler can obtain the key information, memory + pressure in a cpuset, with a single read, rather than having to + query and accumulate results over all the (dynamically changing) + set of tasks in the cpuset. + +A per-cpuset simple digital filter (requires a spinlock and 3 words +of data per-cpuset) is kept, and updated by any task attached to that +cpuset, if it enters the synchronous (direct) page reclaim code. + +A per-cpuset file provides an integer number representing the recent +(half-life of 10 seconds) rate of direct page reclaims caused by +the tasks in the cpuset, in units of reclaims attempted per second, +times 1000. + + +1.6 What is memory spread ? +--------------------------- +There are two boolean flag files per cpuset that control where the +kernel allocates pages for the file system buffers and related in +kernel data structures. They are called 'memory_spread_page' and +'memory_spread_slab'. + +If the per-cpuset boolean flag file 'memory_spread_page' is set, then +the kernel will spread the file system buffers (page cache) evenly +over all the nodes that the faulting task is allowed to use, instead +of preferring to put those pages on the node where the task is running. + +If the per-cpuset boolean flag file 'memory_spread_slab' is set, +then the kernel will spread some file system related slab caches, +such as for inodes and dentries evenly over all the nodes that the +faulting task is allowed to use, instead of preferring to put those +pages on the node where the task is running. + +The setting of these flags does not affect anonymous data segment or +stack segment pages of a task. + +By default, both kinds of memory spreading are off, and memory +pages are allocated on the node local to where the task is running, +except perhaps as modified by the tasks NUMA mempolicy or cpuset +configuration, so long as sufficient free memory pages are available. + +When new cpusets are created, they inherit the memory spread settings +of their parent. + +Setting memory spreading causes allocations for the affected page +or slab caches to ignore the tasks NUMA mempolicy and be spread +instead. Tasks using mbind() or set_mempolicy() calls to set NUMA +mempolicies will not notice any change in these calls as a result of +their containing tasks memory spread settings. If memory spreading +is turned off, then the currently specified NUMA mempolicy once again +applies to memory page allocations. + +Both 'memory_spread_page' and 'memory_spread_slab' are boolean flag +files. By default they contain "0", meaning that the feature is off +for that cpuset. If a "1" is written to that file, then that turns +the named feature on. + +The implementation is simple. + +Setting the flag 'memory_spread_page' turns on a per-process flag +PF_SPREAD_PAGE for each task that is in that cpuset or subsequently +joins that cpuset. The page allocation calls for the page cache +is modified to perform an inline check for this PF_SPREAD_PAGE task +flag, and if set, a call to a new routine cpuset_mem_spread_node() +returns the node to prefer for the allocation. + +Similarly, setting 'memory_spread_slab' turns on the flag +PF_SPREAD_SLAB, and appropriately marked slab caches will allocate +pages from the node returned by cpuset_mem_spread_node(). + +The cpuset_mem_spread_node() routine is also simple. It uses the +value of a per-task rotor cpuset_mem_spread_rotor to select the next +node in the current tasks mems_allowed to prefer for the allocation. + +This memory placement policy is also known (in other contexts) as +round-robin or interleave. + +This policy can provide substantial improvements for jobs that need +to place thread local data on the corresponding node, but that need +to access large file system data sets that need to be spread across +the several nodes in the jobs cpuset in order to fit. Without this +policy, especially for jobs that might have one thread reading in the +data set, the memory allocation across the nodes in the jobs cpuset +can become very uneven. + +1.7 What is sched_load_balance ? +-------------------------------- + +The kernel scheduler (kernel/sched.c) automatically load balances +tasks. If one CPU is underutilized, kernel code running on that +CPU will look for tasks on other more overloaded CPUs and move those +tasks to itself, within the constraints of such placement mechanisms +as cpusets and sched_setaffinity. + +The algorithmic cost of load balancing and its impact on key shared +kernel data structures such as the task list increases more than +linearly with the number of CPUs being balanced. So the scheduler +has support to partition the systems CPUs into a number of sched +domains such that it only load balances within each sched domain. +Each sched domain covers some subset of the CPUs in the system; +no two sched domains overlap; some CPUs might not be in any sched +domain and hence won't be load balanced. + +Put simply, it costs less to balance between two smaller sched domains +than one big one, but doing so means that overloads in one of the +two domains won't be load balanced to the other one. + +By default, there is one sched domain covering all CPUs, except those +marked isolated using the kernel boot time "isolcpus=" argument. + +This default load balancing across all CPUs is not well suited for +the following two situations: + 1) On large systems, load balancing across many CPUs is expensive. + If the system is managed using cpusets to place independent jobs + on separate sets of CPUs, full load balancing is unnecessary. + 2) Systems supporting realtime on some CPUs need to minimize + system overhead on those CPUs, including avoiding task load + balancing if that is not needed. + +When the per-cpuset flag "sched_load_balance" is enabled (the default +setting), it requests that all the CPUs in that cpusets allowed 'cpus' +be contained in a single sched domain, ensuring that load balancing +can move a task (not otherwised pinned, as by sched_setaffinity) +from any CPU in that cpuset to any other. + +When the per-cpuset flag "sched_load_balance" is disabled, then the +scheduler will avoid load balancing across the CPUs in that cpuset, +--except-- in so far as is necessary because some overlapping cpuset +has "sched_load_balance" enabled. + +So, for example, if the top cpuset has the flag "sched_load_balance" +enabled, then the scheduler will have one sched domain covering all +CPUs, and the setting of the "sched_load_balance" flag in any other +cpusets won't matter, as we're already fully load balancing. + +Therefore in the above two situations, the top cpuset flag +"sched_load_balance" should be disabled, and only some of the smaller, +child cpusets have this flag enabled. + +When doing this, you don't usually want to leave any unpinned tasks in +the top cpuset that might use non-trivial amounts of CPU, as such tasks +may be artificially constrained to some subset of CPUs, depending on +the particulars of this flag setting in descendent cpusets. Even if +such a task could use spare CPU cycles in some other CPUs, the kernel +scheduler might not consider the possibility of load balancing that +task to that underused CPU. + +Of course, tasks pinned to a particular CPU can be left in a cpuset +that disables "sched_load_balance" as those tasks aren't going anywhere +else anyway. + +There is an impedance mismatch here, between cpusets and sched domains. +Cpusets are hierarchical and nest. Sched domains are flat; they don't +overlap and each CPU is in at most one sched domain. + +It is necessary for sched domains to be flat because load balancing +across partially overlapping sets of CPUs would risk unstable dynamics +that would be beyond our understanding. So if each of two partially +overlapping cpusets enables the flag 'sched_load_balance', then we +form a single sched domain that is a superset of both. We won't move +a task to a CPU outside it cpuset, but the scheduler load balancing +code might waste some compute cycles considering that possibility. + +This mismatch is why there is not a simple one-to-one relation +between which cpusets have the flag "sched_load_balance" enabled, +and the sched domain configuration. If a cpuset enables the flag, it +will get balancing across all its CPUs, but if it disables the flag, +it will only be assured of no load balancing if no other overlapping +cpuset enables the flag. + +If two cpusets have partially overlapping 'cpus' allowed, and only +one of them has this flag enabled, then the other may find its +tasks only partially load balanced, just on the overlapping CPUs. +This is just the general case of the top_cpuset example given a few +paragraphs above. In the general case, as in the top cpuset case, +don't leave tasks that might use non-trivial amounts of CPU in +such partially load balanced cpusets, as they may be artificially +constrained to some subset of the CPUs allowed to them, for lack of +load balancing to the other CPUs. + +1.7.1 sched_load_balance implementation details. +------------------------------------------------ + +The per-cpuset flag 'sched_load_balance' defaults to enabled (contrary +to most cpuset flags.) When enabled for a cpuset, the kernel will +ensure that it can load balance across all the CPUs in that cpuset +(makes sure that all the CPUs in the cpus_allowed of that cpuset are +in the same sched domain.) + +If two overlapping cpusets both have 'sched_load_balance' enabled, +then they will be (must be) both in the same sched domain. + +If, as is the default, the top cpuset has 'sched_load_balance' enabled, +then by the above that means there is a single sched domain covering +the whole system, regardless of any other cpuset settings. + +The kernel commits to user space that it will avoid load balancing +where it can. It will pick as fine a granularity partition of sched +domains as it can while still providing load balancing for any set +of CPUs allowed to a cpuset having 'sched_load_balance' enabled. + +The internal kernel cpuset to scheduler interface passes from the +cpuset code to the scheduler code a partition of the load balanced +CPUs in the system. This partition is a set of subsets (represented +as an array of cpumask_t) of CPUs, pairwise disjoint, that cover all +the CPUs that must be load balanced. + +Whenever the 'sched_load_balance' flag changes, or CPUs come or go +from a cpuset with this flag enabled, or a cpuset with this flag +enabled is removed, the cpuset code builds a new such partition and +passes it to the scheduler sched domain setup code, to have the sched +domains rebuilt as necessary. + +This partition exactly defines what sched domains the scheduler should +setup - one sched domain for each element (cpumask_t) in the partition. + +The scheduler remembers the currently active sched domain partitions. +When the scheduler routine partition_sched_domains() is invoked from +the cpuset code to update these sched domains, it compares the new +partition requested with the current, and updates its sched domains, +removing the old and adding the new, for each change. + + +1.8 What is sched_relax_domain_level ? +-------------------------------------- + +In sched domain, the scheduler migrates tasks in 2 ways; periodic load +balance on tick, and at time of some schedule events. + +When a task is woken up, scheduler try to move the task on idle CPU. +For example, if a task A running on CPU X activates another task B +on the same CPU X, and if CPU Y is X's sibling and performing idle, +then scheduler migrate task B to CPU Y so that task B can start on +CPU Y without waiting task A on CPU X. + +And if a CPU run out of tasks in its runqueue, the CPU try to pull +extra tasks from other busy CPUs to help them before it is going to +be idle. + +Of course it takes some searching cost to find movable tasks and/or +idle CPUs, the scheduler might not search all CPUs in the domain +everytime. In fact, in some architectures, the searching ranges on +events are limited in the same socket or node where the CPU locates, +while the load balance on tick searchs all. + +For example, assume CPU Z is relatively far from CPU X. Even if CPU Z +is idle while CPU X and the siblings are busy, scheduler can't migrate +woken task B from X to Z since it is out of its searching range. +As the result, task B on CPU X need to wait task A or wait load balance +on the next tick. For some applications in special situation, waiting +1 tick may be too long. + +The 'sched_relax_domain_level' file allows you to request changing +this searching range as you like. This file takes int value which +indicates size of searching range in levels ideally as follows, +otherwise initial value -1 that indicates the cpuset has no request. + + -1 : no request. use system default or follow request of others. + 0 : no search. + 1 : search siblings (hyperthreads in a core). + 2 : search cores in a package. + 3 : search cpus in a node [= system wide on non-NUMA system] + ( 4 : search nodes in a chunk of node [on NUMA system] ) + ( 5 : search system wide [on NUMA system] ) + +The system default is architecture dependent. The system default +can be changed using the relax_domain_level= boot parameter. + +This file is per-cpuset and affect the sched domain where the cpuset +belongs to. Therefore if the flag 'sched_load_balance' of a cpuset +is disabled, then 'sched_relax_domain_level' have no effect since +there is no sched domain belonging the cpuset. + +If multiple cpusets are overlapping and hence they form a single sched +domain, the largest value among those is used. Be careful, if one +requests 0 and others are -1 then 0 is used. + +Note that modifying this file will have both good and bad effects, +and whether it is acceptable or not will be depend on your situation. +Don't modify this file if you are not sure. + +If your situation is: + - The migration costs between each cpu can be assumed considerably + small(for you) due to your special application's behavior or + special hardware support for CPU cache etc. + - The searching cost doesn't have impact(for you) or you can make + the searching cost enough small by managing cpuset to compact etc. + - The latency is required even it sacrifices cache hit rate etc. +then increasing 'sched_relax_domain_level' would benefit you. + + +1.9 How do I use cpusets ? +-------------------------- + +In order to minimize the impact of cpusets on critical kernel +code, such as the scheduler, and due to the fact that the kernel +does not support one task updating the memory placement of another +task directly, the impact on a task of changing its cpuset CPU +or Memory Node placement, or of changing to which cpuset a task +is attached, is subtle. + +If a cpuset has its Memory Nodes modified, then for each task attached +to that cpuset, the next time that the kernel attempts to allocate +a page of memory for that task, the kernel will notice the change +in the tasks cpuset, and update its per-task memory placement to +remain within the new cpusets memory placement. If the task was using +mempolicy MPOL_BIND, and the nodes to which it was bound overlap with +its new cpuset, then the task will continue to use whatever subset +of MPOL_BIND nodes are still allowed in the new cpuset. If the task +was using MPOL_BIND and now none of its MPOL_BIND nodes are allowed +in the new cpuset, then the task will be essentially treated as if it +was MPOL_BIND bound to the new cpuset (even though its numa placement, +as queried by get_mempolicy(), doesn't change). If a task is moved +from one cpuset to another, then the kernel will adjust the tasks +memory placement, as above, the next time that the kernel attempts +to allocate a page of memory for that task. + +If a cpuset has its 'cpus' modified, then each task in that cpuset +will have its allowed CPU placement changed immediately. Similarly, +if a tasks pid is written to a cpusets 'tasks' file, in either its +current cpuset or another cpuset, then its allowed CPU placement is +changed immediately. If such a task had been bound to some subset +of its cpuset using the sched_setaffinity() call, the task will be +allowed to run on any CPU allowed in its new cpuset, negating the +affect of the prior sched_setaffinity() call. + +In summary, the memory placement of a task whose cpuset is changed is +updated by the kernel, on the next allocation of a page for that task, +but the processor placement is not updated, until that tasks pid is +rewritten to the 'tasks' file of its cpuset. This is done to avoid +impacting the scheduler code in the kernel with a check for changes +in a tasks processor placement. + +Normally, once a page is allocated (given a physical page +of main memory) then that page stays on whatever node it +was allocated, so long as it remains allocated, even if the +cpusets memory placement policy 'mems' subsequently changes. +If the cpuset flag file 'memory_migrate' is set true, then when +tasks are attached to that cpuset, any pages that task had +allocated to it on nodes in its previous cpuset are migrated +to the tasks new cpuset. The relative placement of the page within +the cpuset is preserved during these migration operations if possible. +For example if the page was on the second valid node of the prior cpuset +then the page will be placed on the second valid node of the new cpuset. + +Also if 'memory_migrate' is set true, then if that cpusets +'mems' file is modified, pages allocated to tasks in that +cpuset, that were on nodes in the previous setting of 'mems', +will be moved to nodes in the new setting of 'mems.' +Pages that were not in the tasks prior cpuset, or in the cpusets +prior 'mems' setting, will not be moved. + +There is an exception to the above. If hotplug functionality is used +to remove all the CPUs that are currently assigned to a cpuset, +then all the tasks in that cpuset will be moved to the nearest ancestor +with non-empty cpus. But the moving of some (or all) tasks might fail if +cpuset is bound with another cgroup subsystem which has some restrictions +on task attaching. In this failing case, those tasks will stay +in the original cpuset, and the kernel will automatically update +their cpus_allowed to allow all online CPUs. When memory hotplug +functionality for removing Memory Nodes is available, a similar exception +is expected to apply there as well. In general, the kernel prefers to +violate cpuset placement, over starving a task that has had all +its allowed CPUs or Memory Nodes taken offline. + +There is a second exception to the above. GFP_ATOMIC requests are +kernel internal allocations that must be satisfied, immediately. +The kernel may drop some request, in rare cases even panic, if a +GFP_ATOMIC alloc fails. If the request cannot be satisfied within +the current tasks cpuset, then we relax the cpuset, and look for +memory anywhere we can find it. It's better to violate the cpuset +than stress the kernel. + +To start a new job that is to be contained within a cpuset, the steps are: + + 1) mkdir /dev/cpuset + 2) mount -t cgroup -ocpuset cpuset /dev/cpuset + 3) Create the new cpuset by doing mkdir's and write's (or echo's) in + the /dev/cpuset virtual file system. + 4) Start a task that will be the "founding father" of the new job. + 5) Attach that task to the new cpuset by writing its pid to the + /dev/cpuset tasks file for that cpuset. + 6) fork, exec or clone the job tasks from this founding father task. + +For example, the following sequence of commands will setup a cpuset +named "Charlie", containing just CPUs 2 and 3, and Memory Node 1, +and then start a subshell 'sh' in that cpuset: + + mount -t cgroup -ocpuset cpuset /dev/cpuset + cd /dev/cpuset + mkdir Charlie + cd Charlie + /bin/echo 2-3 > cpus + /bin/echo 1 > mems + /bin/echo $$ > tasks + sh + # The subshell 'sh' is now running in cpuset Charlie + # The next line should display '/Charlie' + cat /proc/self/cpuset + +In the future, a C library interface to cpusets will likely be +available. For now, the only way to query or modify cpusets is +via the cpuset file system, using the various cd, mkdir, echo, cat, +rmdir commands from the shell, or their equivalent from C. + +The sched_setaffinity calls can also be done at the shell prompt using +SGI's runon or Robert Love's taskset. The mbind and set_mempolicy +calls can be done at the shell prompt using the numactl command +(part of Andi Kleen's numa package). + +2. Usage Examples and Syntax +============================ + +2.1 Basic Usage +--------------- + +Creating, modifying, using the cpusets can be done through the cpuset +virtual filesystem. + +To mount it, type: +# mount -t cgroup -o cpuset cpuset /dev/cpuset + +Then under /dev/cpuset you can find a tree that corresponds to the +tree of the cpusets in the system. For instance, /dev/cpuset +is the cpuset that holds the whole system. + +If you want to create a new cpuset under /dev/cpuset: +# cd /dev/cpuset +# mkdir my_cpuset + +Now you want to do something with this cpuset. +# cd my_cpuset + +In this directory you can find several files: +# ls +cpu_exclusive memory_migrate mems tasks +cpus memory_pressure notify_on_release +mem_exclusive memory_spread_page sched_load_balance +mem_hardwall memory_spread_slab sched_relax_domain_level + +Reading them will give you information about the state of this cpuset: +the CPUs and Memory Nodes it can use, the processes that are using +it, its properties. By writing to these files you can manipulate +the cpuset. + +Set some flags: +# /bin/echo 1 > cpu_exclusive + +Add some cpus: +# /bin/echo 0-7 > cpus + +Add some mems: +# /bin/echo 0-7 > mems + +Now attach your shell to this cpuset: +# /bin/echo $$ > tasks + +You can also create cpusets inside your cpuset by using mkdir in this +directory. +# mkdir my_sub_cs + +To remove a cpuset, just use rmdir: +# rmdir my_sub_cs +This will fail if the cpuset is in use (has cpusets inside, or has +processes attached). + +Note that for legacy reasons, the "cpuset" filesystem exists as a +wrapper around the cgroup filesystem. + +The command + +mount -t cpuset X /dev/cpuset + +is equivalent to + +mount -t cgroup -ocpuset X /dev/cpuset +echo "/sbin/cpuset_release_agent" > /dev/cpuset/release_agent + +2.2 Adding/removing cpus +------------------------ + +This is the syntax to use when writing in the cpus or mems files +in cpuset directories: + +# /bin/echo 1-4 > cpus -> set cpus list to cpus 1,2,3,4 +# /bin/echo 1,2,3,4 > cpus -> set cpus list to cpus 1,2,3,4 + +2.3 Setting flags +----------------- + +The syntax is very simple: + +# /bin/echo 1 > cpu_exclusive -> set flag 'cpu_exclusive' +# /bin/echo 0 > cpu_exclusive -> unset flag 'cpu_exclusive' + +2.4 Attaching processes +----------------------- + +# /bin/echo PID > tasks + +Note that it is PID, not PIDs. You can only attach ONE task at a time. +If you have several tasks to attach, you have to do it one after another: + +# /bin/echo PID1 > tasks +# /bin/echo PID2 > tasks + ... +# /bin/echo PIDn > tasks + + +3. Questions +============ + +Q: what's up with this '/bin/echo' ? +A: bash's builtin 'echo' command does not check calls to write() against + errors. If you use it in the cpuset file system, you won't be + able to tell whether a command succeeded or failed. + +Q: When I attach processes, only the first of the line gets really attached ! +A: We can only return one error code per call to write(). So you should also + put only ONE pid. + +4. Contact +========== + +Web: http://www.bullopensource.org/cpuset diff --git a/Documentation/cgroups/devices.txt b/Documentation/cgroups/devices.txt new file mode 100644 index 00000000000..7cc6e6a6067 --- /dev/null +++ b/Documentation/cgroups/devices.txt @@ -0,0 +1,52 @@ +Device Whitelist Controller + +1. Description: + +Implement a cgroup to track and enforce open and mknod restrictions +on device files. A device cgroup associates a device access +whitelist with each cgroup. A whitelist entry has 4 fields. +'type' is a (all), c (char), or b (block). 'all' means it applies +to all types and all major and minor numbers. Major and minor are +either an integer or * for all. Access is a composition of r +(read), w (write), and m (mknod). + +The root device cgroup starts with rwm to 'all'. A child device +cgroup gets a copy of the parent. Administrators can then remove +devices from the whitelist or add new entries. A child cgroup can +never receive a device access which is denied by its parent. However +when a device access is removed from a parent it will not also be +removed from the child(ren). + +2. User Interface + +An entry is added using devices.allow, and removed using +devices.deny. For instance + + echo 'c 1:3 mr' > /cgroups/1/devices.allow + +allows cgroup 1 to read and mknod the device usually known as +/dev/null. Doing + + echo a > /cgroups/1/devices.deny + +will remove the default 'a *:* rwm' entry. Doing + + echo a > /cgroups/1/devices.allow + +will add the 'a *:* rwm' entry to the whitelist. + +3. Security + +Any task can move itself between cgroups. This clearly won't +suffice, but we can decide the best way to adequately restrict +movement as people get some experience with this. We may just want +to require CAP_SYS_ADMIN, which at least is a separate bit from +CAP_MKNOD. We may want to just refuse moving to a cgroup which +isn't a descendent of the current one. Or we may want to use +CAP_MAC_ADMIN, since we really are trying to lock down root. + +CAP_SYS_ADMIN is needed to modify the whitelist or move another +task to a new cgroup. (Again we'll probably want to change that). + +A cgroup may not be granted more permissions than the cgroup's +parent has. diff --git a/Documentation/cgroups/memcg_test.txt b/Documentation/cgroups/memcg_test.txt new file mode 100644 index 00000000000..19533f93b7a --- /dev/null +++ b/Documentation/cgroups/memcg_test.txt @@ -0,0 +1,342 @@ +Memory Resource Controller(Memcg) Implementation Memo. +Last Updated: 2008/12/15 +Base Kernel Version: based on 2.6.28-rc8-mm. + +Because VM is getting complex (one of reasons is memcg...), memcg's behavior +is complex. This is a document for memcg's internal behavior. +Please note that implementation details can be changed. + +(*) Topics on API should be in Documentation/cgroups/memory.txt) + +0. How to record usage ? + 2 objects are used. + + page_cgroup ....an object per page. + Allocated at boot or memory hotplug. Freed at memory hot removal. + + swap_cgroup ... an entry per swp_entry. + Allocated at swapon(). Freed at swapoff(). + + The page_cgroup has USED bit and double count against a page_cgroup never + occurs. swap_cgroup is used only when a charged page is swapped-out. + +1. Charge + + a page/swp_entry may be charged (usage += PAGE_SIZE) at + + mem_cgroup_newpage_charge() + Called at new page fault and Copy-On-Write. + + mem_cgroup_try_charge_swapin() + Called at do_swap_page() (page fault on swap entry) and swapoff. + Followed by charge-commit-cancel protocol. (With swap accounting) + At commit, a charge recorded in swap_cgroup is removed. + + mem_cgroup_cache_charge() + Called at add_to_page_cache() + + mem_cgroup_cache_charge_swapin() + Called at shmem's swapin. + + mem_cgroup_prepare_migration() + Called before migration. "extra" charge is done and followed by + charge-commit-cancel protocol. + At commit, charge against oldpage or newpage will be committed. + +2. Uncharge + a page/swp_entry may be uncharged (usage -= PAGE_SIZE) by + + mem_cgroup_uncharge_page() + Called when an anonymous page is fully unmapped. I.e., mapcount goes + to 0. If the page is SwapCache, uncharge is delayed until + mem_cgroup_uncharge_swapcache(). + + mem_cgroup_uncharge_cache_page() + Called when a page-cache is deleted from radix-tree. If the page is + SwapCache, uncharge is delayed until mem_cgroup_uncharge_swapcache(). + + mem_cgroup_uncharge_swapcache() + Called when SwapCache is removed from radix-tree. The charge itself + is moved to swap_cgroup. (If mem+swap controller is disabled, no + charge to swap occurs.) + + mem_cgroup_uncharge_swap() + Called when swp_entry's refcnt goes down to 0. A charge against swap + disappears. + + mem_cgroup_end_migration(old, new) + At success of migration old is uncharged (if necessary), a charge + to new page is committed. At failure, charge to old page is committed. + +3. charge-commit-cancel + In some case, we can't know this "charge" is valid or not at charging + (because of races). + To handle such case, there are charge-commit-cancel functions. + mem_cgroup_try_charge_XXX + mem_cgroup_commit_charge_XXX + mem_cgroup_cancel_charge_XXX + these are used in swap-in and migration. + + At try_charge(), there are no flags to say "this page is charged". + at this point, usage += PAGE_SIZE. + + At commit(), the function checks the page should be charged or not + and set flags or avoid charging.(usage -= PAGE_SIZE) + + At cancel(), simply usage -= PAGE_SIZE. + +Under below explanation, we assume CONFIG_MEM_RES_CTRL_SWAP=y. + +4. Anonymous + Anonymous page is newly allocated at + - page fault into MAP_ANONYMOUS mapping. + - Copy-On-Write. + It is charged right after it's allocated before doing any page table + related operations. Of course, it's uncharged when another page is used + for the fault address. + + At freeing anonymous page (by exit() or munmap()), zap_pte() is called + and pages for ptes are freed one by one.(see mm/memory.c). Uncharges + are done at page_remove_rmap() when page_mapcount() goes down to 0. + + Another page freeing is by page-reclaim (vmscan.c) and anonymous + pages are swapped out. In this case, the page is marked as + PageSwapCache(). uncharge() routine doesn't uncharge the page marked + as SwapCache(). It's delayed until __delete_from_swap_cache(). + + 4.1 Swap-in. + At swap-in, the page is taken from swap-cache. There are 2 cases. + + (a) If the SwapCache is newly allocated and read, it has no charges. + (b) If the SwapCache has been mapped by processes, it has been + charged already. + + This swap-in is one of the most complicated work. In do_swap_page(), + following events occur when pte is unchanged. + + (1) the page (SwapCache) is looked up. + (2) lock_page() + (3) try_charge_swapin() + (4) reuse_swap_page() (may call delete_swap_cache()) + (5) commit_charge_swapin() + (6) swap_free(). + + Considering following situation for example. + + (A) The page has not been charged before (2) and reuse_swap_page() + doesn't call delete_from_swap_cache(). + (B) The page has not been charged before (2) and reuse_swap_page() + calls delete_from_swap_cache(). + (C) The page has been charged before (2) and reuse_swap_page() doesn't + call delete_from_swap_cache(). + (D) The page has been charged before (2) and reuse_swap_page() calls + delete_from_swap_cache(). + + memory.usage/memsw.usage changes to this page/swp_entry will be + Case (A) (B) (C) (D) + Event + Before (2) 0/ 1 0/ 1 1/ 1 1/ 1 + =========================================== + (3) +1/+1 +1/+1 +1/+1 +1/+1 + (4) - 0/ 0 - -1/ 0 + (5) 0/-1 0/ 0 -1/-1 0/ 0 + (6) - 0/-1 - 0/-1 + =========================================== + Result 1/ 1 1/ 1 1/ 1 1/ 1 + + In any cases, charges to this page should be 1/ 1. + + 4.2 Swap-out. + At swap-out, typical state transition is below. + + (a) add to swap cache. (marked as SwapCache) + swp_entry's refcnt += 1. + (b) fully unmapped. + swp_entry's refcnt += # of ptes. + (c) write back to swap. + (d) delete from swap cache. (remove from SwapCache) + swp_entry's refcnt -= 1. + + + At (b), the page is marked as SwapCache and not uncharged. + At (d), the page is removed from SwapCache and a charge in page_cgroup + is moved to swap_cgroup. + + Finally, at task exit, + (e) zap_pte() is called and swp_entry's refcnt -=1 -> 0. + Here, a charge in swap_cgroup disappears. + +5. Page Cache + Page Cache is charged at + - add_to_page_cache_locked(). + + uncharged at + - __remove_from_page_cache(). + + The logic is very clear. (About migration, see below) + Note: __remove_from_page_cache() is called by remove_from_page_cache() + and __remove_mapping(). + +6. Shmem(tmpfs) Page Cache + Memcg's charge/uncharge have special handlers of shmem. The best way + to understand shmem's page state transition is to read mm/shmem.c. + But brief explanation of the behavior of memcg around shmem will be + helpful to understand the logic. + + Shmem's page (just leaf page, not direct/indirect block) can be on + - radix-tree of shmem's inode. + - SwapCache. + - Both on radix-tree and SwapCache. This happens at swap-in + and swap-out, + + It's charged when... + - A new page is added to shmem's radix-tree. + - A swp page is read. (move a charge from swap_cgroup to page_cgroup) + It's uncharged when + - A page is removed from radix-tree and not SwapCache. + - When SwapCache is removed, a charge is moved to swap_cgroup. + - When swp_entry's refcnt goes down to 0, a charge in swap_cgroup + disappears. + +7. Page Migration + One of the most complicated functions is page-migration-handler. + Memcg has 2 routines. Assume that we are migrating a page's contents + from OLDPAGE to NEWPAGE. + + Usual migration logic is.. + (a) remove the page from LRU. + (b) allocate NEWPAGE (migration target) + (c) lock by lock_page(). + (d) unmap all mappings. + (e-1) If necessary, replace entry in radix-tree. + (e-2) move contents of a page. + (f) map all mappings again. + (g) pushback the page to LRU. + (-) OLDPAGE will be freed. + + Before (g), memcg should complete all necessary charge/uncharge to + NEWPAGE/OLDPAGE. + + The point is.... + - If OLDPAGE is anonymous, all charges will be dropped at (d) because + try_to_unmap() drops all mapcount and the page will not be + SwapCache. + + - If OLDPAGE is SwapCache, charges will be kept at (g) because + __delete_from_swap_cache() isn't called at (e-1) + + - If OLDPAGE is page-cache, charges will be kept at (g) because + remove_from_swap_cache() isn't called at (e-1) + + memcg provides following hooks. + + - mem_cgroup_prepare_migration(OLDPAGE) + Called after (b) to account a charge (usage += PAGE_SIZE) against + memcg which OLDPAGE belongs to. + + - mem_cgroup_end_migration(OLDPAGE, NEWPAGE) + Called after (f) before (g). + If OLDPAGE is used, commit OLDPAGE again. If OLDPAGE is already + charged, a charge by prepare_migration() is automatically canceled. + If NEWPAGE is used, commit NEWPAGE and uncharge OLDPAGE. + + But zap_pte() (by exit or munmap) can be called while migration, + we have to check if OLDPAGE/NEWPAGE is a valid page after commit(). + +8. LRU + Each memcg has its own private LRU. Now, it's handling is under global + VM's control (means that it's handled under global zone->lru_lock). + Almost all routines around memcg's LRU is called by global LRU's + list management functions under zone->lru_lock(). + + A special function is mem_cgroup_isolate_pages(). This scans + memcg's private LRU and call __isolate_lru_page() to extract a page + from LRU. + (By __isolate_lru_page(), the page is removed from both of global and + private LRU.) + + +9. Typical Tests. + + Tests for racy cases. + + 9.1 Small limit to memcg. + When you do test to do racy case, it's good test to set memcg's limit + to be very small rather than GB. Many races found in the test under + xKB or xxMB limits. + (Memory behavior under GB and Memory behavior under MB shows very + different situation.) + + 9.2 Shmem + Historically, memcg's shmem handling was poor and we saw some amount + of troubles here. This is because shmem is page-cache but can be + SwapCache. Test with shmem/tmpfs is always good test. + + 9.3 Migration + For NUMA, migration is an another special case. To do easy test, cpuset + is useful. Following is a sample script to do migration. + + mount -t cgroup -o cpuset none /opt/cpuset + + mkdir /opt/cpuset/01 + echo 1 > /opt/cpuset/01/cpuset.cpus + echo 0 > /opt/cpuset/01/cpuset.mems + echo 1 > /opt/cpuset/01/cpuset.memory_migrate + mkdir /opt/cpuset/02 + echo 1 > /opt/cpuset/02/cpuset.cpus + echo 1 > /opt/cpuset/02/cpuset.mems + echo 1 > /opt/cpuset/02/cpuset.memory_migrate + + In above set, when you moves a task from 01 to 02, page migration to + node 0 to node 1 will occur. Following is a script to migrate all + under cpuset. + -- + move_task() + { + for pid in $1 + do + /bin/echo $pid >$2/tasks 2>/dev/null + echo -n $pid + echo -n " " + done + echo END + } + + G1_TASK=`cat ${G1}/tasks` + G2_TASK=`cat ${G2}/tasks` + move_task "${G1_TASK}" ${G2} & + -- + 9.4 Memory hotplug. + memory hotplug test is one of good test. + to offline memory, do following. + # echo offline > /sys/devices/system/memory/memoryXXX/state + (XXX is the place of memory) + This is an easy way to test page migration, too. + + 9.5 mkdir/rmdir + When using hierarchy, mkdir/rmdir test should be done. + Use tests like the following. + + echo 1 >/opt/cgroup/01/memory/use_hierarchy + mkdir /opt/cgroup/01/child_a + mkdir /opt/cgroup/01/child_b + + set limit to 01. + add limit to 01/child_b + run jobs under child_a and child_b + + create/delete following groups at random while jobs are running. + /opt/cgroup/01/child_a/child_aa + /opt/cgroup/01/child_b/child_bb + /opt/cgroup/01/child_c + + running new jobs in new group is also good. + + 9.6 Mount with other subsystems. + Mounting with other subsystems is a good test because there is a + race and lock dependency with other cgroup subsystems. + + example) + # mount -t cgroup none /cgroup -t cpuset,memory,cpu,devices + + and do task move, mkdir, rmdir etc...under this. diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt new file mode 100644 index 00000000000..e1501964df1 --- /dev/null +++ b/Documentation/cgroups/memory.txt @@ -0,0 +1,399 @@ +Memory Resource Controller + +NOTE: The Memory Resource Controller has been generically been referred +to as the memory controller in this document. Do not confuse memory controller +used here with the memory controller that is used in hardware. + +Salient features + +a. Enable control of both RSS (mapped) and Page Cache (unmapped) pages +b. The infrastructure allows easy addition of other types of memory to control +c. Provides *zero overhead* for non memory controller users +d. Provides a double LRU: global memory pressure causes reclaim from the + global LRU; a cgroup on hitting a limit, reclaims from the per + cgroup LRU + +NOTE: Swap Cache (unmapped) is not accounted now. + +Benefits and Purpose of the memory controller + +The memory controller isolates the memory behaviour of a group of tasks +from the rest of the system. The article on LWN [12] mentions some probable +uses of the memory controller. The memory controller can be used to + +a. Isolate an application or a group of applications + Memory hungry applications can be isolated and limited to a smaller + amount of memory. +b. Create a cgroup with limited amount of memory, this can be used + as a good alternative to booting with mem=XXXX. +c. Virtualization solutions can control the amount of memory they want + to assign to a virtual machine instance. +d. A CD/DVD burner could control the amount of memory used by the + rest of the system to ensure that burning does not fail due to lack + of available memory. +e. There are several other use cases, find one or use the controller just + for fun (to learn and hack on the VM subsystem). + +1. History + +The memory controller has a long history. A request for comments for the memory +controller was posted by Balbir Singh [1]. At the time the RFC was posted +there were several implementations for memory control. The goal of the +RFC was to build consensus and agreement for the minimal features required +for memory control. The first RSS controller was posted by Balbir Singh[2] +in Feb 2007. Pavel Emelianov [3][4][5] has since posted three versions of the +RSS controller. At OLS, at the resource management BoF, everyone suggested +that we handle both page cache and RSS together. Another request was raised +to allow user space handling of OOM. The current memory controller is +at version 6; it combines both mapped (RSS) and unmapped Page +Cache Control [11]. + +2. Memory Control + +Memory is a unique resource in the sense that it is present in a limited +amount. If a task requires a lot of CPU processing, the task can spread +its processing over a period of hours, days, months or years, but with +memory, the same physical memory needs to be reused to accomplish the task. + +The memory controller implementation has been divided into phases. These +are: + +1. Memory controller +2. mlock(2) controller +3. Kernel user memory accounting and slab control +4. user mappings length controller + +The memory controller is the first controller developed. + +2.1. Design + +The core of the design is a counter called the res_counter. The res_counter +tracks the current memory usage and limit of the group of processes associated +with the controller. Each cgroup has a memory controller specific data +structure (mem_cgroup) associated with it. + +2.2. Accounting + + +--------------------+ + | mem_cgroup | + | (res_counter) | + +--------------------+ + / ^ \ + / | \ + +---------------+ | +---------------+ + | mm_struct | |.... | mm_struct | + | | | | | + +---------------+ | +---------------+ + | + + --------------+ + | + +---------------+ +------+--------+ + | page +----------> page_cgroup| + | | | | + +---------------+ +---------------+ + + (Figure 1: Hierarchy of Accounting) + + +Figure 1 shows the important aspects of the controller + +1. Accounting happens per cgroup +2. Each mm_struct knows about which cgroup it belongs to +3. Each page has a pointer to the page_cgroup, which in turn knows the + cgroup it belongs to + +The accounting is done as follows: mem_cgroup_charge() is invoked to setup +the necessary data structures and check if the cgroup that is being charged +is over its limit. If it is then reclaim is invoked on the cgroup. +More details can be found in the reclaim section of this document. +If everything goes well, a page meta-data-structure called page_cgroup is +allocated and associated with the page. This routine also adds the page to +the per cgroup LRU. + +2.2.1 Accounting details + +All mapped anon pages (RSS) and cache pages (Page Cache) are accounted. +(some pages which never be reclaimable and will not be on global LRU + are not accounted. we just accounts pages under usual vm management.) + +RSS pages are accounted at page_fault unless they've already been accounted +for earlier. A file page will be accounted for as Page Cache when it's +inserted into inode (radix-tree). While it's mapped into the page tables of +processes, duplicate accounting is carefully avoided. + +A RSS page is unaccounted when it's fully unmapped. A PageCache page is +unaccounted when it's removed from radix-tree. + +At page migration, accounting information is kept. + +Note: we just account pages-on-lru because our purpose is to control amount +of used pages. not-on-lru pages are tend to be out-of-control from vm view. + +2.3 Shared Page Accounting + +Shared pages are accounted on the basis of the first touch approach. The +cgroup that first touches a page is accounted for the page. The principle +behind this approach is that a cgroup that aggressively uses a shared +page will eventually get charged for it (once it is uncharged from +the cgroup that brought it in -- this will happen on memory pressure). + +Exception: If CONFIG_CGROUP_CGROUP_MEM_RES_CTLR_SWAP is not used.. +When you do swapoff and make swapped-out pages of shmem(tmpfs) to +be backed into memory in force, charges for pages are accounted against the +caller of swapoff rather than the users of shmem. + + +2.4 Swap Extension (CONFIG_CGROUP_MEM_RES_CTLR_SWAP) +Swap Extension allows you to record charge for swap. A swapped-in page is +charged back to original page allocator if possible. + +When swap is accounted, following files are added. + - memory.memsw.usage_in_bytes. + - memory.memsw.limit_in_bytes. + +usage of mem+swap is limited by memsw.limit_in_bytes. + +Note: why 'mem+swap' rather than swap. +The global LRU(kswapd) can swap out arbitrary pages. Swap-out means +to move account from memory to swap...there is no change in usage of +mem+swap. + +In other words, when we want to limit the usage of swap without affecting +global LRU, mem+swap limit is better than just limiting swap from OS point +of view. + +2.5 Reclaim + +Each cgroup maintains a per cgroup LRU that consists of an active +and inactive list. When a cgroup goes over its limit, we first try +to reclaim memory from the cgroup so as to make space for the new +pages that the cgroup has touched. If the reclaim is unsuccessful, +an OOM routine is invoked to select and kill the bulkiest task in the +cgroup. + +The reclaim algorithm has not been modified for cgroups, except that +pages that are selected for reclaiming come from the per cgroup LRU +list. + +2. Locking + +The memory controller uses the following hierarchy + +1. zone->lru_lock is used for selecting pages to be isolated +2. mem->per_zone->lru_lock protects the per cgroup LRU (per zone) +3. lock_page_cgroup() is used to protect page->page_cgroup + +3. User Interface + +0. Configuration + +a. Enable CONFIG_CGROUPS +b. Enable CONFIG_RESOURCE_COUNTERS +c. Enable CONFIG_CGROUP_MEM_RES_CTLR + +1. Prepare the cgroups +# mkdir -p /cgroups +# mount -t cgroup none /cgroups -o memory + +2. Make the new group and move bash into it +# mkdir /cgroups/0 +# echo $$ > /cgroups/0/tasks + +Since now we're in the 0 cgroup, +We can alter the memory limit: +# echo 4M > /cgroups/0/memory.limit_in_bytes + +NOTE: We can use a suffix (k, K, m, M, g or G) to indicate values in kilo, +mega or gigabytes. + +# cat /cgroups/0/memory.limit_in_bytes +4194304 + +NOTE: The interface has now changed to display the usage in bytes +instead of pages + +We can check the usage: +# cat /cgroups/0/memory.usage_in_bytes +1216512 + +A successful write to this file does not guarantee a successful set of +this limit to the value written into the file. This can be due to a +number of factors, such as rounding up to page boundaries or the total +availability of memory on the system. The user is required to re-read +this file after a write to guarantee the value committed by the kernel. + +# echo 1 > memory.limit_in_bytes +# cat memory.limit_in_bytes +4096 + +The memory.failcnt field gives the number of times that the cgroup limit was +exceeded. + +The memory.stat file gives accounting information. Now, the number of +caches, RSS and Active pages/Inactive pages are shown. + +4. Testing + +Balbir posted lmbench, AIM9, LTP and vmmstress results [10] and [11]. +Apart from that v6 has been tested with several applications and regular +daily use. The controller has also been tested on the PPC64, x86_64 and +UML platforms. + +4.1 Troubleshooting + +Sometimes a user might find that the application under a cgroup is +terminated. There are several causes for this: + +1. The cgroup limit is too low (just too low to do anything useful) +2. The user is using anonymous memory and swap is turned off or too low + +A sync followed by echo 1 > /proc/sys/vm/drop_caches will help get rid of +some of the pages cached in the cgroup (page cache pages). + +4.2 Task migration + +When a task migrates from one cgroup to another, it's charge is not +carried forward. The pages allocated from the original cgroup still +remain charged to it, the charge is dropped when the page is freed or +reclaimed. + +4.3 Removing a cgroup + +A cgroup can be removed by rmdir, but as discussed in sections 4.1 and 4.2, a +cgroup might have some charge associated with it, even though all +tasks have migrated away from it. +Such charges are freed(at default) or moved to its parent. When moved, +both of RSS and CACHES are moved to parent. +If both of them are busy, rmdir() returns -EBUSY. See 5.1 Also. + +Charges recorded in swap information is not updated at removal of cgroup. +Recorded information is discarded and a cgroup which uses swap (swapcache) +will be charged as a new owner of it. + + +5. Misc. interfaces. + +5.1 force_empty + memory.force_empty interface is provided to make cgroup's memory usage empty. + You can use this interface only when the cgroup has no tasks. + When writing anything to this + + # echo 0 > memory.force_empty + + Almost all pages tracked by this memcg will be unmapped and freed. Some of + pages cannot be freed because it's locked or in-use. Such pages are moved + to parent and this cgroup will be empty. But this may return -EBUSY in + some too busy case. + + Typical use case of this interface is that calling this before rmdir(). + Because rmdir() moves all pages to parent, some out-of-use page caches can be + moved to the parent. If you want to avoid that, force_empty will be useful. + +5.2 stat file + memory.stat file includes following statistics (now) + cache - # of pages from page-cache and shmem. + rss - # of pages from anonymous memory. + pgpgin - # of event of charging + pgpgout - # of event of uncharging + active_anon - # of pages on active lru of anon, shmem. + inactive_anon - # of pages on active lru of anon, shmem + active_file - # of pages on active lru of file-cache + inactive_file - # of pages on inactive lru of file cache + unevictable - # of pages cannot be reclaimed.(mlocked etc) + + Below is depend on CONFIG_DEBUG_VM. + inactive_ratio - VM inernal parameter. (see mm/page_alloc.c) + recent_rotated_anon - VM internal parameter. (see mm/vmscan.c) + recent_rotated_file - VM internal parameter. (see mm/vmscan.c) + recent_scanned_anon - VM internal parameter. (see mm/vmscan.c) + recent_scanned_file - VM internal parameter. (see mm/vmscan.c) + + Memo: + recent_rotated means recent frequency of lru rotation. + recent_scanned means recent # of scans to lru. + showing for better debug please see the code for meanings. + + +5.3 swappiness + Similar to /proc/sys/vm/swappiness, but affecting a hierarchy of groups only. + + Following cgroup's swapiness can't be changed. + - root cgroup (uses /proc/sys/vm/swappiness). + - a cgroup which uses hierarchy and it has child cgroup. + - a cgroup which uses hierarchy and not the root of hierarchy. + + +6. Hierarchy support + +The memory controller supports a deep hierarchy and hierarchical accounting. +The hierarchy is created by creating the appropriate cgroups in the +cgroup filesystem. Consider for example, the following cgroup filesystem +hierarchy + + root + / | \ + / | \ + a b c + | \ + | \ + d e + +In the diagram above, with hierarchical accounting enabled, all memory +usage of e, is accounted to its ancestors up until the root (i.e, c and root), +that has memory.use_hierarchy enabled. If one of the ancestors goes over its +limit, the reclaim algorithm reclaims from the tasks in the ancestor and the +children of the ancestor. + +6.1 Enabling hierarchical accounting and reclaim + +The memory controller by default disables the hierarchy feature. Support +can be enabled by writing 1 to memory.use_hierarchy file of the root cgroup + +# echo 1 > memory.use_hierarchy + +The feature can be disabled by + +# echo 0 > memory.use_hierarchy + +NOTE1: Enabling/disabling will fail if the cgroup already has other +cgroups created below it. + +NOTE2: This feature can be enabled/disabled per subtree. + +7. TODO + +1. Add support for accounting huge pages (as a separate controller) +2. Make per-cgroup scanner reclaim not-shared pages first +3. Teach controller to account for shared-pages +4. Start reclamation in the background when the limit is + not yet hit but the usage is getting closer + +Summary + +Overall, the memory controller has been a stable controller and has been +commented and discussed quite extensively in the community. + +References + +1. Singh, Balbir. RFC: Memory Controller, http://lwn.net/Articles/206697/ +2. Singh, Balbir. Memory Controller (RSS Control), + http://lwn.net/Articles/222762/ +3. Emelianov, Pavel. Resource controllers based on process cgroups + http://lkml.org/lkml/2007/3/6/198 +4. Emelianov, Pavel. RSS controller based on process cgroups (v2) + http://lkml.org/lkml/2007/4/9/78 +5. Emelianov, Pavel. RSS controller based on process cgroups (v3) + http://lkml.org/lkml/2007/5/30/244 +6. Menage, Paul. Control Groups v10, http://lwn.net/Articles/236032/ +7. Vaidyanathan, Srinivasan, Control Groups: Pagecache accounting and control + subsystem (v3), http://lwn.net/Articles/235534/ +8. Singh, Balbir. RSS controller v2 test results (lmbench), + http://lkml.org/lkml/2007/5/17/232 +9. Singh, Balbir. RSS controller v2 AIM9 results + http://lkml.org/lkml/2007/5/18/1 +10. Singh, Balbir. Memory controller v6 test results, + http://lkml.org/lkml/2007/8/19/36 +11. Singh, Balbir. Memory controller introduction (v6), + http://lkml.org/lkml/2007/8/17/69 +12. Corbet, Jonathan, Controlling memory use in cgroups, + http://lwn.net/Articles/243795/ diff --git a/Documentation/cgroups/resource_counter.txt b/Documentation/cgroups/resource_counter.txt new file mode 100644 index 00000000000..f196ac1d7d2 --- /dev/null +++ b/Documentation/cgroups/resource_counter.txt @@ -0,0 +1,181 @@ + + The Resource Counter + +The resource counter, declared at include/linux/res_counter.h, +is supposed to facilitate the resource management by controllers +by providing common stuff for accounting. + +This "stuff" includes the res_counter structure and routines +to work with it. + + + +1. Crucial parts of the res_counter structure + + a. unsigned long long usage + + The usage value shows the amount of a resource that is consumed + by a group at a given time. The units of measurement should be + determined by the controller that uses this counter. E.g. it can + be bytes, items or any other unit the controller operates on. + + b. unsigned long long max_usage + + The maximal value of the usage over time. + + This value is useful when gathering statistical information about + the particular group, as it shows the actual resource requirements + for a particular group, not just some usage snapshot. + + c. unsigned long long limit + + The maximal allowed amount of resource to consume by the group. In + case the group requests for more resources, so that the usage value + would exceed the limit, the resource allocation is rejected (see + the next section). + + d. unsigned long long failcnt + + The failcnt stands for "failures counter". This is the number of + resource allocation attempts that failed. + + c. spinlock_t lock + + Protects changes of the above values. + + + +2. Basic accounting routines + + a. void res_counter_init(struct res_counter *rc) + + Initializes the resource counter. As usual, should be the first + routine called for a new counter. + + b. int res_counter_charge[_locked] + (struct res_counter *rc, unsigned long val) + + When a resource is about to be allocated it has to be accounted + with the appropriate resource counter (controller should determine + which one to use on its own). This operation is called "charging". + + This is not very important which operation - resource allocation + or charging - is performed first, but + * if the allocation is performed first, this may create a + temporary resource over-usage by the time resource counter is + charged; + * if the charging is performed first, then it should be uncharged + on error path (if the one is called). + + c. void res_counter_uncharge[_locked] + (struct res_counter *rc, unsigned long val) + + When a resource is released (freed) it should be de-accounted + from the resource counter it was accounted to. This is called + "uncharging". + + The _locked routines imply that the res_counter->lock is taken. + + + 2.1 Other accounting routines + + There are more routines that may help you with common needs, like + checking whether the limit is reached or resetting the max_usage + value. They are all declared in include/linux/res_counter.h. + + + +3. Analyzing the resource counter registrations + + a. If the failcnt value constantly grows, this means that the counter's + limit is too tight. Either the group is misbehaving and consumes too + many resources, or the configuration is not suitable for the group + and the limit should be increased. + + b. The max_usage value can be used to quickly tune the group. One may + set the limits to maximal values and either load the container with + a common pattern or leave one for a while. After this the max_usage + value shows the amount of memory the container would require during + its common activity. + + Setting the limit a bit above this value gives a pretty good + configuration that works in most of the cases. + + c. If the max_usage is much less than the limit, but the failcnt value + is growing, then the group tries to allocate a big chunk of resource + at once. + + d. If the max_usage is much less than the limit, but the failcnt value + is 0, then this group is given too high limit, that it does not + require. It is better to lower the limit a bit leaving more resource + for other groups. + + + +4. Communication with the control groups subsystem (cgroups) + +All the resource controllers that are using cgroups and resource counters +should provide files (in the cgroup filesystem) to work with the resource +counter fields. They are recommended to adhere to the following rules: + + a. File names + + Field name File name + --------------------------------------------------- + usage usage_in_ + max_usage max_usage_in_ + limit limit_in_ + failcnt failcnt + lock no file :) + + b. Reading from file should show the corresponding field value in the + appropriate format. + + c. Writing to file + + Field Expected behavior + ---------------------------------- + usage prohibited + max_usage reset to usage + limit set the limit + failcnt reset to zero + + + +5. Usage example + + a. Declare a task group (take a look at cgroups subsystem for this) and + fold a res_counter into it + + struct my_group { + struct res_counter res; + + + } + + b. Put hooks in resource allocation/release paths + + int alloc_something(...) + { + if (res_counter_charge(res_counter_ptr, amount) < 0) + return -ENOMEM; + + + } + + void release_something(...) + { + res_counter_uncharge(res_counter_ptr, amount); + + + } + + In order to keep the usage value self-consistent, both the + "res_counter_ptr" and the "amount" in release_something() should be + the same as they were in the alloc_something() when the releasing + resource was allocated. + + c. Provide the way to read res_counter values and set them (the cgroups + still can help with it). + + c. Compile and run :) diff --git a/Documentation/controllers/cpuacct.txt b/Documentation/controllers/cpuacct.txt deleted file mode 100644 index bb775fbe43d..00000000000 --- a/Documentation/controllers/cpuacct.txt +++ /dev/null @@ -1,32 +0,0 @@ -CPU Accounting Controller -------------------------- - -The CPU accounting controller is used to group tasks using cgroups and -account the CPU usage of these groups of tasks. - -The CPU accounting controller supports multi-hierarchy groups. An accounting -group accumulates the CPU usage of all of its child groups and the tasks -directly present in its group. - -Accounting groups can be created by first mounting the cgroup filesystem. - -# mkdir /cgroups -# mount -t cgroup -ocpuacct none /cgroups - -With the above step, the initial or the parent accounting group -becomes visible at /cgroups. At bootup, this group includes all the -tasks in the system. /cgroups/tasks lists the tasks in this cgroup. -/cgroups/cpuacct.usage gives the CPU time (in nanoseconds) obtained by -this group which is essentially the CPU time obtained by all the tasks -in the system. - -New accounting groups can be created under the parent group /cgroups. - -# cd /cgroups -# mkdir g1 -# echo $$ > g1 - -The above steps create a new group g1 and move the current shell -process (bash) into it. CPU time consumed by this bash and its children -can be obtained from g1/cpuacct.usage and the same is accumulated in -/cgroups/cpuacct.usage also. diff --git a/Documentation/controllers/devices.txt b/Documentation/controllers/devices.txt deleted file mode 100644 index 7cc6e6a6067..00000000000 --- a/Documentation/controllers/devices.txt +++ /dev/null @@ -1,52 +0,0 @@ -Device Whitelist Controller - -1. Description: - -Implement a cgroup to track and enforce open and mknod restrictions -on device files. A device cgroup associates a device access -whitelist with each cgroup. A whitelist entry has 4 fields. -'type' is a (all), c (char), or b (block). 'all' means it applies -to all types and all major and minor numbers. Major and minor are -either an integer or * for all. Access is a composition of r -(read), w (write), and m (mknod). - -The root device cgroup starts with rwm to 'all'. A child device -cgroup gets a copy of the parent. Administrators can then remove -devices from the whitelist or add new entries. A child cgroup can -never receive a device access which is denied by its parent. However -when a device access is removed from a parent it will not also be -removed from the child(ren). - -2. User Interface - -An entry is added using devices.allow, and removed using -devices.deny. For instance - - echo 'c 1:3 mr' > /cgroups/1/devices.allow - -allows cgroup 1 to read and mknod the device usually known as -/dev/null. Doing - - echo a > /cgroups/1/devices.deny - -will remove the default 'a *:* rwm' entry. Doing - - echo a > /cgroups/1/devices.allow - -will add the 'a *:* rwm' entry to the whitelist. - -3. Security - -Any task can move itself between cgroups. This clearly won't -suffice, but we can decide the best way to adequately restrict -movement as people get some experience with this. We may just want -to require CAP_SYS_ADMIN, which at least is a separate bit from -CAP_MKNOD. We may want to just refuse moving to a cgroup which -isn't a descendent of the current one. Or we may want to use -CAP_MAC_ADMIN, since we really are trying to lock down root. - -CAP_SYS_ADMIN is needed to modify the whitelist or move another -task to a new cgroup. (Again we'll probably want to change that). - -A cgroup may not be granted more permissions than the cgroup's -parent has. diff --git a/Documentation/controllers/memcg_test.txt b/Documentation/controllers/memcg_test.txt deleted file mode 100644 index 08d4d3ea0d7..00000000000 --- a/Documentation/controllers/memcg_test.txt +++ /dev/null @@ -1,342 +0,0 @@ -Memory Resource Controller(Memcg) Implementation Memo. -Last Updated: 2008/12/15 -Base Kernel Version: based on 2.6.28-rc8-mm. - -Because VM is getting complex (one of reasons is memcg...), memcg's behavior -is complex. This is a document for memcg's internal behavior. -Please note that implementation details can be changed. - -(*) Topics on API should be in Documentation/controllers/memory.txt) - -0. How to record usage ? - 2 objects are used. - - page_cgroup ....an object per page. - Allocated at boot or memory hotplug. Freed at memory hot removal. - - swap_cgroup ... an entry per swp_entry. - Allocated at swapon(). Freed at swapoff(). - - The page_cgroup has USED bit and double count against a page_cgroup never - occurs. swap_cgroup is used only when a charged page is swapped-out. - -1. Charge - - a page/swp_entry may be charged (usage += PAGE_SIZE) at - - mem_cgroup_newpage_charge() - Called at new page fault and Copy-On-Write. - - mem_cgroup_try_charge_swapin() - Called at do_swap_page() (page fault on swap entry) and swapoff. - Followed by charge-commit-cancel protocol. (With swap accounting) - At commit, a charge recorded in swap_cgroup is removed. - - mem_cgroup_cache_charge() - Called at add_to_page_cache() - - mem_cgroup_cache_charge_swapin() - Called at shmem's swapin. - - mem_cgroup_prepare_migration() - Called before migration. "extra" charge is done and followed by - charge-commit-cancel protocol. - At commit, charge against oldpage or newpage will be committed. - -2. Uncharge - a page/swp_entry may be uncharged (usage -= PAGE_SIZE) by - - mem_cgroup_uncharge_page() - Called when an anonymous page is fully unmapped. I.e., mapcount goes - to 0. If the page is SwapCache, uncharge is delayed until - mem_cgroup_uncharge_swapcache(). - - mem_cgroup_uncharge_cache_page() - Called when a page-cache is deleted from radix-tree. If the page is - SwapCache, uncharge is delayed until mem_cgroup_uncharge_swapcache(). - - mem_cgroup_uncharge_swapcache() - Called when SwapCache is removed from radix-tree. The charge itself - is moved to swap_cgroup. (If mem+swap controller is disabled, no - charge to swap occurs.) - - mem_cgroup_uncharge_swap() - Called when swp_entry's refcnt goes down to 0. A charge against swap - disappears. - - mem_cgroup_end_migration(old, new) - At success of migration old is uncharged (if necessary), a charge - to new page is committed. At failure, charge to old page is committed. - -3. charge-commit-cancel - In some case, we can't know this "charge" is valid or not at charging - (because of races). - To handle such case, there are charge-commit-cancel functions. - mem_cgroup_try_charge_XXX - mem_cgroup_commit_charge_XXX - mem_cgroup_cancel_charge_XXX - these are used in swap-in and migration. - - At try_charge(), there are no flags to say "this page is charged". - at this point, usage += PAGE_SIZE. - - At commit(), the function checks the page should be charged or not - and set flags or avoid charging.(usage -= PAGE_SIZE) - - At cancel(), simply usage -= PAGE_SIZE. - -Under below explanation, we assume CONFIG_MEM_RES_CTRL_SWAP=y. - -4. Anonymous - Anonymous page is newly allocated at - - page fault into MAP_ANONYMOUS mapping. - - Copy-On-Write. - It is charged right after it's allocated before doing any page table - related operations. Of course, it's uncharged when another page is used - for the fault address. - - At freeing anonymous page (by exit() or munmap()), zap_pte() is called - and pages for ptes are freed one by one.(see mm/memory.c). Uncharges - are done at page_remove_rmap() when page_mapcount() goes down to 0. - - Another page freeing is by page-reclaim (vmscan.c) and anonymous - pages are swapped out. In this case, the page is marked as - PageSwapCache(). uncharge() routine doesn't uncharge the page marked - as SwapCache(). It's delayed until __delete_from_swap_cache(). - - 4.1 Swap-in. - At swap-in, the page is taken from swap-cache. There are 2 cases. - - (a) If the SwapCache is newly allocated and read, it has no charges. - (b) If the SwapCache has been mapped by processes, it has been - charged already. - - This swap-in is one of the most complicated work. In do_swap_page(), - following events occur when pte is unchanged. - - (1) the page (SwapCache) is looked up. - (2) lock_page() - (3) try_charge_swapin() - (4) reuse_swap_page() (may call delete_swap_cache()) - (5) commit_charge_swapin() - (6) swap_free(). - - Considering following situation for example. - - (A) The page has not been charged before (2) and reuse_swap_page() - doesn't call delete_from_swap_cache(). - (B) The page has not been charged before (2) and reuse_swap_page() - calls delete_from_swap_cache(). - (C) The page has been charged before (2) and reuse_swap_page() doesn't - call delete_from_swap_cache(). - (D) The page has been charged before (2) and reuse_swap_page() calls - delete_from_swap_cache(). - - memory.usage/memsw.usage changes to this page/swp_entry will be - Case (A) (B) (C) (D) - Event - Before (2) 0/ 1 0/ 1 1/ 1 1/ 1 - =========================================== - (3) +1/+1 +1/+1 +1/+1 +1/+1 - (4) - 0/ 0 - -1/ 0 - (5) 0/-1 0/ 0 -1/-1 0/ 0 - (6) - 0/-1 - 0/-1 - =========================================== - Result 1/ 1 1/ 1 1/ 1 1/ 1 - - In any cases, charges to this page should be 1/ 1. - - 4.2 Swap-out. - At swap-out, typical state transition is below. - - (a) add to swap cache. (marked as SwapCache) - swp_entry's refcnt += 1. - (b) fully unmapped. - swp_entry's refcnt += # of ptes. - (c) write back to swap. - (d) delete from swap cache. (remove from SwapCache) - swp_entry's refcnt -= 1. - - - At (b), the page is marked as SwapCache and not uncharged. - At (d), the page is removed from SwapCache and a charge in page_cgroup - is moved to swap_cgroup. - - Finally, at task exit, - (e) zap_pte() is called and swp_entry's refcnt -=1 -> 0. - Here, a charge in swap_cgroup disappears. - -5. Page Cache - Page Cache is charged at - - add_to_page_cache_locked(). - - uncharged at - - __remove_from_page_cache(). - - The logic is very clear. (About migration, see below) - Note: __remove_from_page_cache() is called by remove_from_page_cache() - and __remove_mapping(). - -6. Shmem(tmpfs) Page Cache - Memcg's charge/uncharge have special handlers of shmem. The best way - to understand shmem's page state transition is to read mm/shmem.c. - But brief explanation of the behavior of memcg around shmem will be - helpful to understand the logic. - - Shmem's page (just leaf page, not direct/indirect block) can be on - - radix-tree of shmem's inode. - - SwapCache. - - Both on radix-tree and SwapCache. This happens at swap-in - and swap-out, - - It's charged when... - - A new page is added to shmem's radix-tree. - - A swp page is read. (move a charge from swap_cgroup to page_cgroup) - It's uncharged when - - A page is removed from radix-tree and not SwapCache. - - When SwapCache is removed, a charge is moved to swap_cgroup. - - When swp_entry's refcnt goes down to 0, a charge in swap_cgroup - disappears. - -7. Page Migration - One of the most complicated functions is page-migration-handler. - Memcg has 2 routines. Assume that we are migrating a page's contents - from OLDPAGE to NEWPAGE. - - Usual migration logic is.. - (a) remove the page from LRU. - (b) allocate NEWPAGE (migration target) - (c) lock by lock_page(). - (d) unmap all mappings. - (e-1) If necessary, replace entry in radix-tree. - (e-2) move contents of a page. - (f) map all mappings again. - (g) pushback the page to LRU. - (-) OLDPAGE will be freed. - - Before (g), memcg should complete all necessary charge/uncharge to - NEWPAGE/OLDPAGE. - - The point is.... - - If OLDPAGE is anonymous, all charges will be dropped at (d) because - try_to_unmap() drops all mapcount and the page will not be - SwapCache. - - - If OLDPAGE is SwapCache, charges will be kept at (g) because - __delete_from_swap_cache() isn't called at (e-1) - - - If OLDPAGE is page-cache, charges will be kept at (g) because - remove_from_swap_cache() isn't called at (e-1) - - memcg provides following hooks. - - - mem_cgroup_prepare_migration(OLDPAGE) - Called after (b) to account a charge (usage += PAGE_SIZE) against - memcg which OLDPAGE belongs to. - - - mem_cgroup_end_migration(OLDPAGE, NEWPAGE) - Called after (f) before (g). - If OLDPAGE is used, commit OLDPAGE again. If OLDPAGE is already - charged, a charge by prepare_migration() is automatically canceled. - If NEWPAGE is used, commit NEWPAGE and uncharge OLDPAGE. - - But zap_pte() (by exit or munmap) can be called while migration, - we have to check if OLDPAGE/NEWPAGE is a valid page after commit(). - -8. LRU - Each memcg has its own private LRU. Now, it's handling is under global - VM's control (means that it's handled under global zone->lru_lock). - Almost all routines around memcg's LRU is called by global LRU's - list management functions under zone->lru_lock(). - - A special function is mem_cgroup_isolate_pages(). This scans - memcg's private LRU and call __isolate_lru_page() to extract a page - from LRU. - (By __isolate_lru_page(), the page is removed from both of global and - private LRU.) - - -9. Typical Tests. - - Tests for racy cases. - - 9.1 Small limit to memcg. - When you do test to do racy case, it's good test to set memcg's limit - to be very small rather than GB. Many races found in the test under - xKB or xxMB limits. - (Memory behavior under GB and Memory behavior under MB shows very - different situation.) - - 9.2 Shmem - Historically, memcg's shmem handling was poor and we saw some amount - of troubles here. This is because shmem is page-cache but can be - SwapCache. Test with shmem/tmpfs is always good test. - - 9.3 Migration - For NUMA, migration is an another special case. To do easy test, cpuset - is useful. Following is a sample script to do migration. - - mount -t cgroup -o cpuset none /opt/cpuset - - mkdir /opt/cpuset/01 - echo 1 > /opt/cpuset/01/cpuset.cpus - echo 0 > /opt/cpuset/01/cpuset.mems - echo 1 > /opt/cpuset/01/cpuset.memory_migrate - mkdir /opt/cpuset/02 - echo 1 > /opt/cpuset/02/cpuset.cpus - echo 1 > /opt/cpuset/02/cpuset.mems - echo 1 > /opt/cpuset/02/cpuset.memory_migrate - - In above set, when you moves a task from 01 to 02, page migration to - node 0 to node 1 will occur. Following is a script to migrate all - under cpuset. - -- - move_task() - { - for pid in $1 - do - /bin/echo $pid >$2/tasks 2>/dev/null - echo -n $pid - echo -n " " - done - echo END - } - - G1_TASK=`cat ${G1}/tasks` - G2_TASK=`cat ${G2}/tasks` - move_task "${G1_TASK}" ${G2} & - -- - 9.4 Memory hotplug. - memory hotplug test is one of good test. - to offline memory, do following. - # echo offline > /sys/devices/system/memory/memoryXXX/state - (XXX is the place of memory) - This is an easy way to test page migration, too. - - 9.5 mkdir/rmdir - When using hierarchy, mkdir/rmdir test should be done. - Use tests like the following. - - echo 1 >/opt/cgroup/01/memory/use_hierarchy - mkdir /opt/cgroup/01/child_a - mkdir /opt/cgroup/01/child_b - - set limit to 01. - add limit to 01/child_b - run jobs under child_a and child_b - - create/delete following groups at random while jobs are running. - /opt/cgroup/01/child_a/child_aa - /opt/cgroup/01/child_b/child_bb - /opt/cgroup/01/child_c - - running new jobs in new group is also good. - - 9.6 Mount with other subsystems. - Mounting with other subsystems is a good test because there is a - race and lock dependency with other cgroup subsystems. - - example) - # mount -t cgroup none /cgroup -t cpuset,memory,cpu,devices - - and do task move, mkdir, rmdir etc...under this. diff --git a/Documentation/controllers/memory.txt b/Documentation/controllers/memory.txt deleted file mode 100644 index e1501964df1..00000000000 --- a/Documentation/controllers/memory.txt +++ /dev/null @@ -1,399 +0,0 @@ -Memory Resource Controller - -NOTE: The Memory Resource Controller has been generically been referred -to as the memory controller in this document. Do not confuse memory controller -used here with the memory controller that is used in hardware. - -Salient features - -a. Enable control of both RSS (mapped) and Page Cache (unmapped) pages -b. The infrastructure allows easy addition of other types of memory to control -c. Provides *zero overhead* for non memory controller users -d. Provides a double LRU: global memory pressure causes reclaim from the - global LRU; a cgroup on hitting a limit, reclaims from the per - cgroup LRU - -NOTE: Swap Cache (unmapped) is not accounted now. - -Benefits and Purpose of the memory controller - -The memory controller isolates the memory behaviour of a group of tasks -from the rest of the system. The article on LWN [12] mentions some probable -uses of the memory controller. The memory controller can be used to - -a. Isolate an application or a group of applications - Memory hungry applications can be isolated and limited to a smaller - amount of memory. -b. Create a cgroup with limited amount of memory, this can be used - as a good alternative to booting with mem=XXXX. -c. Virtualization solutions can control the amount of memory they want - to assign to a virtual machine instance. -d. A CD/DVD burner could control the amount of memory used by the - rest of the system to ensure that burning does not fail due to lack - of available memory. -e. There are several other use cases, find one or use the controller just - for fun (to learn and hack on the VM subsystem). - -1. History - -The memory controller has a long history. A request for comments for the memory -controller was posted by Balbir Singh [1]. At the time the RFC was posted -there were several implementations for memory control. The goal of the -RFC was to build consensus and agreement for the minimal features required -for memory control. The first RSS controller was posted by Balbir Singh[2] -in Feb 2007. Pavel Emelianov [3][4][5] has since posted three versions of the -RSS controller. At OLS, at the resource management BoF, everyone suggested -that we handle both page cache and RSS together. Another request was raised -to allow user space handling of OOM. The current memory controller is -at version 6; it combines both mapped (RSS) and unmapped Page -Cache Control [11]. - -2. Memory Control - -Memory is a unique resource in the sense that it is present in a limited -amount. If a task requires a lot of CPU processing, the task can spread -its processing over a period of hours, days, months or years, but with -memory, the same physical memory needs to be reused to accomplish the task. - -The memory controller implementation has been divided into phases. These -are: - -1. Memory controller -2. mlock(2) controller -3. Kernel user memory accounting and slab control -4. user mappings length controller - -The memory controller is the first controller developed. - -2.1. Design - -The core of the design is a counter called the res_counter. The res_counter -tracks the current memory usage and limit of the group of processes associated -with the controller. Each cgroup has a memory controller specific data -structure (mem_cgroup) associated with it. - -2.2. Accounting - - +--------------------+ - | mem_cgroup | - | (res_counter) | - +--------------------+ - / ^ \ - / | \ - +---------------+ | +---------------+ - | mm_struct | |.... | mm_struct | - | | | | | - +---------------+ | +---------------+ - | - + --------------+ - | - +---------------+ +------+--------+ - | page +----------> page_cgroup| - | | | | - +---------------+ +---------------+ - - (Figure 1: Hierarchy of Accounting) - - -Figure 1 shows the important aspects of the controller - -1. Accounting happens per cgroup -2. Each mm_struct knows about which cgroup it belongs to -3. Each page has a pointer to the page_cgroup, which in turn knows the - cgroup it belongs to - -The accounting is done as follows: mem_cgroup_charge() is invoked to setup -the necessary data structures and check if the cgroup that is being charged -is over its limit. If it is then reclaim is invoked on the cgroup. -More details can be found in the reclaim section of this document. -If everything goes well, a page meta-data-structure called page_cgroup is -allocated and associated with the page. This routine also adds the page to -the per cgroup LRU. - -2.2.1 Accounting details - -All mapped anon pages (RSS) and cache pages (Page Cache) are accounted. -(some pages which never be reclaimable and will not be on global LRU - are not accounted. we just accounts pages under usual vm management.) - -RSS pages are accounted at page_fault unless they've already been accounted -for earlier. A file page will be accounted for as Page Cache when it's -inserted into inode (radix-tree). While it's mapped into the page tables of -processes, duplicate accounting is carefully avoided. - -A RSS page is unaccounted when it's fully unmapped. A PageCache page is -unaccounted when it's removed from radix-tree. - -At page migration, accounting information is kept. - -Note: we just account pages-on-lru because our purpose is to control amount -of used pages. not-on-lru pages are tend to be out-of-control from vm view. - -2.3 Shared Page Accounting - -Shared pages are accounted on the basis of the first touch approach. The -cgroup that first touches a page is accounted for the page. The principle -behind this approach is that a cgroup that aggressively uses a shared -page will eventually get charged for it (once it is uncharged from -the cgroup that brought it in -- this will happen on memory pressure). - -Exception: If CONFIG_CGROUP_CGROUP_MEM_RES_CTLR_SWAP is not used.. -When you do swapoff and make swapped-out pages of shmem(tmpfs) to -be backed into memory in force, charges for pages are accounted against the -caller of swapoff rather than the users of shmem. - - -2.4 Swap Extension (CONFIG_CGROUP_MEM_RES_CTLR_SWAP) -Swap Extension allows you to record charge for swap. A swapped-in page is -charged back to original page allocator if possible. - -When swap is accounted, following files are added. - - memory.memsw.usage_in_bytes. - - memory.memsw.limit_in_bytes. - -usage of mem+swap is limited by memsw.limit_in_bytes. - -Note: why 'mem+swap' rather than swap. -The global LRU(kswapd) can swap out arbitrary pages. Swap-out means -to move account from memory to swap...there is no change in usage of -mem+swap. - -In other words, when we want to limit the usage of swap without affecting -global LRU, mem+swap limit is better than just limiting swap from OS point -of view. - -2.5 Reclaim - -Each cgroup maintains a per cgroup LRU that consists of an active -and inactive list. When a cgroup goes over its limit, we first try -to reclaim memory from the cgroup so as to make space for the new -pages that the cgroup has touched. If the reclaim is unsuccessful, -an OOM routine is invoked to select and kill the bulkiest task in the -cgroup. - -The reclaim algorithm has not been modified for cgroups, except that -pages that are selected for reclaiming come from the per cgroup LRU -list. - -2. Locking - -The memory controller uses the following hierarchy - -1. zone->lru_lock is used for selecting pages to be isolated -2. mem->per_zone->lru_lock protects the per cgroup LRU (per zone) -3. lock_page_cgroup() is used to protect page->page_cgroup - -3. User Interface - -0. Configuration - -a. Enable CONFIG_CGROUPS -b. Enable CONFIG_RESOURCE_COUNTERS -c. Enable CONFIG_CGROUP_MEM_RES_CTLR - -1. Prepare the cgroups -# mkdir -p /cgroups -# mount -t cgroup none /cgroups -o memory - -2. Make the new group and move bash into it -# mkdir /cgroups/0 -# echo $$ > /cgroups/0/tasks - -Since now we're in the 0 cgroup, -We can alter the memory limit: -# echo 4M > /cgroups/0/memory.limit_in_bytes - -NOTE: We can use a suffix (k, K, m, M, g or G) to indicate values in kilo, -mega or gigabytes. - -# cat /cgroups/0/memory.limit_in_bytes -4194304 - -NOTE: The interface has now changed to display the usage in bytes -instead of pages - -We can check the usage: -# cat /cgroups/0/memory.usage_in_bytes -1216512 - -A successful write to this file does not guarantee a successful set of -this limit to the value written into the file. This can be due to a -number of factors, such as rounding up to page boundaries or the total -availability of memory on the system. The user is required to re-read -this file after a write to guarantee the value committed by the kernel. - -# echo 1 > memory.limit_in_bytes -# cat memory.limit_in_bytes -4096 - -The memory.failcnt field gives the number of times that the cgroup limit was -exceeded. - -The memory.stat file gives accounting information. Now, the number of -caches, RSS and Active pages/Inactive pages are shown. - -4. Testing - -Balbir posted lmbench, AIM9, LTP and vmmstress results [10] and [11]. -Apart from that v6 has been tested with several applications and regular -daily use. The controller has also been tested on the PPC64, x86_64 and -UML platforms. - -4.1 Troubleshooting - -Sometimes a user might find that the application under a cgroup is -terminated. There are several causes for this: - -1. The cgroup limit is too low (just too low to do anything useful) -2. The user is using anonymous memory and swap is turned off or too low - -A sync followed by echo 1 > /proc/sys/vm/drop_caches will help get rid of -some of the pages cached in the cgroup (page cache pages). - -4.2 Task migration - -When a task migrates from one cgroup to another, it's charge is not -carried forward. The pages allocated from the original cgroup still -remain charged to it, the charge is dropped when the page is freed or -reclaimed. - -4.3 Removing a cgroup - -A cgroup can be removed by rmdir, but as discussed in sections 4.1 and 4.2, a -cgroup might have some charge associated with it, even though all -tasks have migrated away from it. -Such charges are freed(at default) or moved to its parent. When moved, -both of RSS and CACHES are moved to parent. -If both of them are busy, rmdir() returns -EBUSY. See 5.1 Also. - -Charges recorded in swap information is not updated at removal of cgroup. -Recorded information is discarded and a cgroup which uses swap (swapcache) -will be charged as a new owner of it. - - -5. Misc. interfaces. - -5.1 force_empty - memory.force_empty interface is provided to make cgroup's memory usage empty. - You can use this interface only when the cgroup has no tasks. - When writing anything to this - - # echo 0 > memory.force_empty - - Almost all pages tracked by this memcg will be unmapped and freed. Some of - pages cannot be freed because it's locked or in-use. Such pages are moved - to parent and this cgroup will be empty. But this may return -EBUSY in - some too busy case. - - Typical use case of this interface is that calling this before rmdir(). - Because rmdir() moves all pages to parent, some out-of-use page caches can be - moved to the parent. If you want to avoid that, force_empty will be useful. - -5.2 stat file - memory.stat file includes following statistics (now) - cache - # of pages from page-cache and shmem. - rss - # of pages from anonymous memory. - pgpgin - # of event of charging - pgpgout - # of event of uncharging - active_anon - # of pages on active lru of anon, shmem. - inactive_anon - # of pages on active lru of anon, shmem - active_file - # of pages on active lru of file-cache - inactive_file - # of pages on inactive lru of file cache - unevictable - # of pages cannot be reclaimed.(mlocked etc) - - Below is depend on CONFIG_DEBUG_VM. - inactive_ratio - VM inernal parameter. (see mm/page_alloc.c) - recent_rotated_anon - VM internal parameter. (see mm/vmscan.c) - recent_rotated_file - VM internal parameter. (see mm/vmscan.c) - recent_scanned_anon - VM internal parameter. (see mm/vmscan.c) - recent_scanned_file - VM internal parameter. (see mm/vmscan.c) - - Memo: - recent_rotated means recent frequency of lru rotation. - recent_scanned means recent # of scans to lru. - showing for better debug please see the code for meanings. - - -5.3 swappiness - Similar to /proc/sys/vm/swappiness, but affecting a hierarchy of groups only. - - Following cgroup's swapiness can't be changed. - - root cgroup (uses /proc/sys/vm/swappiness). - - a cgroup which uses hierarchy and it has child cgroup. - - a cgroup which uses hierarchy and not the root of hierarchy. - - -6. Hierarchy support - -The memory controller supports a deep hierarchy and hierarchical accounting. -The hierarchy is created by creating the appropriate cgroups in the -cgroup filesystem. Consider for example, the following cgroup filesystem -hierarchy - - root - / | \ - / | \ - a b c - | \ - | \ - d e - -In the diagram above, with hierarchical accounting enabled, all memory -usage of e, is accounted to its ancestors up until the root (i.e, c and root), -that has memory.use_hierarchy enabled. If one of the ancestors goes over its -limit, the reclaim algorithm reclaims from the tasks in the ancestor and the -children of the ancestor. - -6.1 Enabling hierarchical accounting and reclaim - -The memory controller by default disables the hierarchy feature. Support -can be enabled by writing 1 to memory.use_hierarchy file of the root cgroup - -# echo 1 > memory.use_hierarchy - -The feature can be disabled by - -# echo 0 > memory.use_hierarchy - -NOTE1: Enabling/disabling will fail if the cgroup already has other -cgroups created below it. - -NOTE2: This feature can be enabled/disabled per subtree. - -7. TODO - -1. Add support for accounting huge pages (as a separate controller) -2. Make per-cgroup scanner reclaim not-shared pages first -3. Teach controller to account for shared-pages -4. Start reclamation in the background when the limit is - not yet hit but the usage is getting closer - -Summary - -Overall, the memory controller has been a stable controller and has been -commented and discussed quite extensively in the community. - -References - -1. Singh, Balbir. RFC: Memory Controller, http://lwn.net/Articles/206697/ -2. Singh, Balbir. Memory Controller (RSS Control), - http://lwn.net/Articles/222762/ -3. Emelianov, Pavel. Resource controllers based on process cgroups - http://lkml.org/lkml/2007/3/6/198 -4. Emelianov, Pavel. RSS controller based on process cgroups (v2) - http://lkml.org/lkml/2007/4/9/78 -5. Emelianov, Pavel. RSS controller based on process cgroups (v3) - http://lkml.org/lkml/2007/5/30/244 -6. Menage, Paul. Control Groups v10, http://lwn.net/Articles/236032/ -7. Vaidyanathan, Srinivasan, Control Groups: Pagecache accounting and control - subsystem (v3), http://lwn.net/Articles/235534/ -8. Singh, Balbir. RSS controller v2 test results (lmbench), - http://lkml.org/lkml/2007/5/17/232 -9. Singh, Balbir. RSS controller v2 AIM9 results - http://lkml.org/lkml/2007/5/18/1 -10. Singh, Balbir. Memory controller v6 test results, - http://lkml.org/lkml/2007/8/19/36 -11. Singh, Balbir. Memory controller introduction (v6), - http://lkml.org/lkml/2007/8/17/69 -12. Corbet, Jonathan, Controlling memory use in cgroups, - http://lwn.net/Articles/243795/ diff --git a/Documentation/controllers/resource_counter.txt b/Documentation/controllers/resource_counter.txt deleted file mode 100644 index f196ac1d7d2..00000000000 --- a/Documentation/controllers/resource_counter.txt +++ /dev/null @@ -1,181 +0,0 @@ - - The Resource Counter - -The resource counter, declared at include/linux/res_counter.h, -is supposed to facilitate the resource management by controllers -by providing common stuff for accounting. - -This "stuff" includes the res_counter structure and routines -to work with it. - - - -1. Crucial parts of the res_counter structure - - a. unsigned long long usage - - The usage value shows the amount of a resource that is consumed - by a group at a given time. The units of measurement should be - determined by the controller that uses this counter. E.g. it can - be bytes, items or any other unit the controller operates on. - - b. unsigned long long max_usage - - The maximal value of the usage over time. - - This value is useful when gathering statistical information about - the particular group, as it shows the actual resource requirements - for a particular group, not just some usage snapshot. - - c. unsigned long long limit - - The maximal allowed amount of resource to consume by the group. In - case the group requests for more resources, so that the usage value - would exceed the limit, the resource allocation is rejected (see - the next section). - - d. unsigned long long failcnt - - The failcnt stands for "failures counter". This is the number of - resource allocation attempts that failed. - - c. spinlock_t lock - - Protects changes of the above values. - - - -2. Basic accounting routines - - a. void res_counter_init(struct res_counter *rc) - - Initializes the resource counter. As usual, should be the first - routine called for a new counter. - - b. int res_counter_charge[_locked] - (struct res_counter *rc, unsigned long val) - - When a resource is about to be allocated it has to be accounted - with the appropriate resource counter (controller should determine - which one to use on its own). This operation is called "charging". - - This is not very important which operation - resource allocation - or charging - is performed first, but - * if the allocation is performed first, this may create a - temporary resource over-usage by the time resource counter is - charged; - * if the charging is performed first, then it should be uncharged - on error path (if the one is called). - - c. void res_counter_uncharge[_locked] - (struct res_counter *rc, unsigned long val) - - When a resource is released (freed) it should be de-accounted - from the resource counter it was accounted to. This is called - "uncharging". - - The _locked routines imply that the res_counter->lock is taken. - - - 2.1 Other accounting routines - - There are more routines that may help you with common needs, like - checking whether the limit is reached or resetting the max_usage - value. They are all declared in include/linux/res_counter.h. - - - -3. Analyzing the resource counter registrations - - a. If the failcnt value constantly grows, this means that the counter's - limit is too tight. Either the group is misbehaving and consumes too - many resources, or the configuration is not suitable for the group - and the limit should be increased. - - b. The max_usage value can be used to quickly tune the group. One may - set the limits to maximal values and either load the container with - a common pattern or leave one for a while. After this the max_usage - value shows the amount of memory the container would require during - its common activity. - - Setting the limit a bit above this value gives a pretty good - configuration that works in most of the cases. - - c. If the max_usage is much less than the limit, but the failcnt value - is growing, then the group tries to allocate a big chunk of resource - at once. - - d. If the max_usage is much less than the limit, but the failcnt value - is 0, then this group is given too high limit, that it does not - require. It is better to lower the limit a bit leaving more resource - for other groups. - - - -4. Communication with the control groups subsystem (cgroups) - -All the resource controllers that are using cgroups and resource counters -should provide files (in the cgroup filesystem) to work with the resource -counter fields. They are recommended to adhere to the following rules: - - a. File names - - Field name File name - --------------------------------------------------- - usage usage_in_ - max_usage max_usage_in_ - limit limit_in_ - failcnt failcnt - lock no file :) - - b. Reading from file should show the corresponding field value in the - appropriate format. - - c. Writing to file - - Field Expected behavior - ---------------------------------- - usage prohibited - max_usage reset to usage - limit set the limit - failcnt reset to zero - - - -5. Usage example - - a. Declare a task group (take a look at cgroups subsystem for this) and - fold a res_counter into it - - struct my_group { - struct res_counter res; - - - } - - b. Put hooks in resource allocation/release paths - - int alloc_something(...) - { - if (res_counter_charge(res_counter_ptr, amount) < 0) - return -ENOMEM; - - - } - - void release_something(...) - { - res_counter_uncharge(res_counter_ptr, amount); - - - } - - In order to keep the usage value self-consistent, both the - "res_counter_ptr" and the "amount" in release_something() should be - the same as they were in the alloc_something() when the releasing - resource was allocated. - - c. Provide the way to read res_counter values and set them (the cgroups - still can help with it). - - c. Compile and run :) diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt deleted file mode 100644 index 5c86c258c79..00000000000 --- a/Documentation/cpusets.txt +++ /dev/null @@ -1,808 +0,0 @@ - CPUSETS - ------- - -Copyright (C) 2004 BULL SA. -Written by Simon.Derr@bull.net - -Portions Copyright (c) 2004-2006 Silicon Graphics, Inc. -Modified by Paul Jackson -Modified by Christoph Lameter -Modified by Paul Menage -Modified by Hidetoshi Seto - -CONTENTS: -========= - -1. Cpusets - 1.1 What are cpusets ? - 1.2 Why are cpusets needed ? - 1.3 How are cpusets implemented ? - 1.4 What are exclusive cpusets ? - 1.5 What is memory_pressure ? - 1.6 What is memory spread ? - 1.7 What is sched_load_balance ? - 1.8 What is sched_relax_domain_level ? - 1.9 How do I use cpusets ? -2. Usage Examples and Syntax - 2.1 Basic Usage - 2.2 Adding/removing cpus - 2.3 Setting flags - 2.4 Attaching processes -3. Questions -4. Contact - -1. Cpusets -========== - -1.1 What are cpusets ? ----------------------- - -Cpusets provide a mechanism for assigning a set of CPUs and Memory -Nodes to a set of tasks. In this document "Memory Node" refers to -an on-line node that contains memory. - -Cpusets constrain the CPU and Memory placement of tasks to only -the resources within a tasks current cpuset. They form a nested -hierarchy visible in a virtual file system. These are the essential -hooks, beyond what is already present, required to manage dynamic -job placement on large systems. - -Cpusets use the generic cgroup subsystem described in -Documentation/cgroups/cgroups.txt. - -Requests by a task, using the sched_setaffinity(2) system call to -include CPUs in its CPU affinity mask, and using the mbind(2) and -set_mempolicy(2) system calls to include Memory Nodes in its memory -policy, are both filtered through that tasks cpuset, filtering out any -CPUs or Memory Nodes not in that cpuset. The scheduler will not -schedule a task on a CPU that is not allowed in its cpus_allowed -vector, and the kernel page allocator will not allocate a page on a -node that is not allowed in the requesting tasks mems_allowed vector. - -User level code may create and destroy cpusets by name in the cgroup -virtual file system, manage the attributes and permissions of these -cpusets and which CPUs and Memory Nodes are assigned to each cpuset, -specify and query to which cpuset a task is assigned, and list the -task pids assigned to a cpuset. - - -1.2 Why are cpusets needed ? ----------------------------- - -The management of large computer systems, with many processors (CPUs), -complex memory cache hierarchies and multiple Memory Nodes having -non-uniform access times (NUMA) presents additional challenges for -the efficient scheduling and memory placement of processes. - -Frequently more modest sized systems can be operated with adequate -efficiency just by letting the operating system automatically share -the available CPU and Memory resources amongst the requesting tasks. - -But larger systems, which benefit more from careful processor and -memory placement to reduce memory access times and contention, -and which typically represent a larger investment for the customer, -can benefit from explicitly placing jobs on properly sized subsets of -the system. - -This can be especially valuable on: - - * Web Servers running multiple instances of the same web application, - * Servers running different applications (for instance, a web server - and a database), or - * NUMA systems running large HPC applications with demanding - performance characteristics. - -These subsets, or "soft partitions" must be able to be dynamically -adjusted, as the job mix changes, without impacting other concurrently -executing jobs. The location of the running jobs pages may also be moved -when the memory locations are changed. - -The kernel cpuset patch provides the minimum essential kernel -mechanisms required to efficiently implement such subsets. It -leverages existing CPU and Memory Placement facilities in the Linux -kernel to avoid any additional impact on the critical scheduler or -memory allocator code. - - -1.3 How are cpusets implemented ? ---------------------------------- - -Cpusets provide a Linux kernel mechanism to constrain which CPUs and -Memory Nodes are used by a process or set of processes. - -The Linux kernel already has a pair of mechanisms to specify on which -CPUs a task may be scheduled (sched_setaffinity) and on which Memory -Nodes it may obtain memory (mbind, set_mempolicy). - -Cpusets extends these two mechanisms as follows: - - - Cpusets are sets of allowed CPUs and Memory Nodes, known to the - kernel. - - Each task in the system is attached to a cpuset, via a pointer - in the task structure to a reference counted cgroup structure. - - Calls to sched_setaffinity are filtered to just those CPUs - allowed in that tasks cpuset. - - Calls to mbind and set_mempolicy are filtered to just - those Memory Nodes allowed in that tasks cpuset. - - The root cpuset contains all the systems CPUs and Memory - Nodes. - - For any cpuset, one can define child cpusets containing a subset - of the parents CPU and Memory Node resources. - - The hierarchy of cpusets can be mounted at /dev/cpuset, for - browsing and manipulation from user space. - - A cpuset may be marked exclusive, which ensures that no other - cpuset (except direct ancestors and descendents) may contain - any overlapping CPUs or Memory Nodes. - - You can list all the tasks (by pid) attached to any cpuset. - -The implementation of cpusets requires a few, simple hooks -into the rest of the kernel, none in performance critical paths: - - - in init/main.c, to initialize the root cpuset at system boot. - - in fork and exit, to attach and detach a task from its cpuset. - - in sched_setaffinity, to mask the requested CPUs by what's - allowed in that tasks cpuset. - - in sched.c migrate_all_tasks(), to keep migrating tasks within - the CPUs allowed by their cpuset, if possible. - - in the mbind and set_mempolicy system calls, to mask the requested - Memory Nodes by what's allowed in that tasks cpuset. - - in page_alloc.c, to restrict memory to allowed nodes. - - in vmscan.c, to restrict page recovery to the current cpuset. - -You should mount the "cgroup" filesystem type in order to enable -browsing and modifying the cpusets presently known to the kernel. No -new system calls are added for cpusets - all support for querying and -modifying cpusets is via this cpuset file system. - -The /proc//status file for each task has four added lines, -displaying the tasks cpus_allowed (on which CPUs it may be scheduled) -and mems_allowed (on which Memory Nodes it may obtain memory), -in the two formats seen in the following example: - - Cpus_allowed: ffffffff,ffffffff,ffffffff,ffffffff - Cpus_allowed_list: 0-127 - Mems_allowed: ffffffff,ffffffff - Mems_allowed_list: 0-63 - -Each cpuset is represented by a directory in the cgroup file system -containing (on top of the standard cgroup files) the following -files describing that cpuset: - - - cpus: list of CPUs in that cpuset - - mems: list of Memory Nodes in that cpuset - - memory_migrate flag: if set, move pages to cpusets nodes - - cpu_exclusive flag: is cpu placement exclusive? - - mem_exclusive flag: is memory placement exclusive? - - mem_hardwall flag: is memory allocation hardwalled - - memory_pressure: measure of how much paging pressure in cpuset - -In addition, the root cpuset only has the following file: - - memory_pressure_enabled flag: compute memory_pressure? - -New cpusets are created using the mkdir system call or shell -command. The properties of a cpuset, such as its flags, allowed -CPUs and Memory Nodes, and attached tasks, are modified by writing -to the appropriate file in that cpusets directory, as listed above. - -The named hierarchical structure of nested cpusets allows partitioning -a large system into nested, dynamically changeable, "soft-partitions". - -The attachment of each task, automatically inherited at fork by any -children of that task, to a cpuset allows organizing the work load -on a system into related sets of tasks such that each set is constrained -to using the CPUs and Memory Nodes of a particular cpuset. A task -may be re-attached to any other cpuset, if allowed by the permissions -on the necessary cpuset file system directories. - -Such management of a system "in the large" integrates smoothly with -the detailed placement done on individual tasks and memory regions -using the sched_setaffinity, mbind and set_mempolicy system calls. - -The following rules apply to each cpuset: - - - Its CPUs and Memory Nodes must be a subset of its parents. - - It can't be marked exclusive unless its parent is. - - If its cpu or memory is exclusive, they may not overlap any sibling. - -These rules, and the natural hierarchy of cpusets, enable efficient -enforcement of the exclusive guarantee, without having to scan all -cpusets every time any of them change to ensure nothing overlaps a -exclusive cpuset. Also, the use of a Linux virtual file system (vfs) -to represent the cpuset hierarchy provides for a familiar permission -and name space for cpusets, with a minimum of additional kernel code. - -The cpus and mems files in the root (top_cpuset) cpuset are -read-only. The cpus file automatically tracks the value of -cpu_online_map using a CPU hotplug notifier, and the mems file -automatically tracks the value of node_states[N_HIGH_MEMORY]--i.e., -nodes with memory--using the cpuset_track_online_nodes() hook. - - -1.4 What are exclusive cpusets ? --------------------------------- - -If a cpuset is cpu or mem exclusive, no other cpuset, other than -a direct ancestor or descendent, may share any of the same CPUs or -Memory Nodes. - -A cpuset that is mem_exclusive *or* mem_hardwall is "hardwalled", -i.e. it restricts kernel allocations for page, buffer and other data -commonly shared by the kernel across multiple users. All cpusets, -whether hardwalled or not, restrict allocations of memory for user -space. This enables configuring a system so that several independent -jobs can share common kernel data, such as file system pages, while -isolating each job's user allocation in its own cpuset. To do this, -construct a large mem_exclusive cpuset to hold all the jobs, and -construct child, non-mem_exclusive cpusets for each individual job. -Only a small amount of typical kernel memory, such as requests from -interrupt handlers, is allowed to be taken outside even a -mem_exclusive cpuset. - - -1.5 What is memory_pressure ? ------------------------------ -The memory_pressure of a cpuset provides a simple per-cpuset metric -of the rate that the tasks in a cpuset are attempting to free up in -use memory on the nodes of the cpuset to satisfy additional memory -requests. - -This enables batch managers monitoring jobs running in dedicated -cpusets to efficiently detect what level of memory pressure that job -is causing. - -This is useful both on tightly managed systems running a wide mix of -submitted jobs, which may choose to terminate or re-prioritize jobs that -are trying to use more memory than allowed on the nodes assigned them, -and with tightly coupled, long running, massively parallel scientific -computing jobs that will dramatically fail to meet required performance -goals if they start to use more memory than allowed to them. - -This mechanism provides a very economical way for the batch manager -to monitor a cpuset for signs of memory pressure. It's up to the -batch manager or other user code to decide what to do about it and -take action. - -==> Unless this feature is enabled by writing "1" to the special file - /dev/cpuset/memory_pressure_enabled, the hook in the rebalance - code of __alloc_pages() for this metric reduces to simply noticing - that the cpuset_memory_pressure_enabled flag is zero. So only - systems that enable this feature will compute the metric. - -Why a per-cpuset, running average: - - Because this meter is per-cpuset, rather than per-task or mm, - the system load imposed by a batch scheduler monitoring this - metric is sharply reduced on large systems, because a scan of - the tasklist can be avoided on each set of queries. - - Because this meter is a running average, instead of an accumulating - counter, a batch scheduler can detect memory pressure with a - single read, instead of having to read and accumulate results - for a period of time. - - Because this meter is per-cpuset rather than per-task or mm, - the batch scheduler can obtain the key information, memory - pressure in a cpuset, with a single read, rather than having to - query and accumulate results over all the (dynamically changing) - set of tasks in the cpuset. - -A per-cpuset simple digital filter (requires a spinlock and 3 words -of data per-cpuset) is kept, and updated by any task attached to that -cpuset, if it enters the synchronous (direct) page reclaim code. - -A per-cpuset file provides an integer number representing the recent -(half-life of 10 seconds) rate of direct page reclaims caused by -the tasks in the cpuset, in units of reclaims attempted per second, -times 1000. - - -1.6 What is memory spread ? ---------------------------- -There are two boolean flag files per cpuset that control where the -kernel allocates pages for the file system buffers and related in -kernel data structures. They are called 'memory_spread_page' and -'memory_spread_slab'. - -If the per-cpuset boolean flag file 'memory_spread_page' is set, then -the kernel will spread the file system buffers (page cache) evenly -over all the nodes that the faulting task is allowed to use, instead -of preferring to put those pages on the node where the task is running. - -If the per-cpuset boolean flag file 'memory_spread_slab' is set, -then the kernel will spread some file system related slab caches, -such as for inodes and dentries evenly over all the nodes that the -faulting task is allowed to use, instead of preferring to put those -pages on the node where the task is running. - -The setting of these flags does not affect anonymous data segment or -stack segment pages of a task. - -By default, both kinds of memory spreading are off, and memory -pages are allocated on the node local to where the task is running, -except perhaps as modified by the tasks NUMA mempolicy or cpuset -configuration, so long as sufficient free memory pages are available. - -When new cpusets are created, they inherit the memory spread settings -of their parent. - -Setting memory spreading causes allocations for the affected page -or slab caches to ignore the tasks NUMA mempolicy and be spread -instead. Tasks using mbind() or set_mempolicy() calls to set NUMA -mempolicies will not notice any change in these calls as a result of -their containing tasks memory spread settings. If memory spreading -is turned off, then the currently specified NUMA mempolicy once again -applies to memory page allocations. - -Both 'memory_spread_page' and 'memory_spread_slab' are boolean flag -files. By default they contain "0", meaning that the feature is off -for that cpuset. If a "1" is written to that file, then that turns -the named feature on. - -The implementation is simple. - -Setting the flag 'memory_spread_page' turns on a per-process flag -PF_SPREAD_PAGE for each task that is in that cpuset or subsequently -joins that cpuset. The page allocation calls for the page cache -is modified to perform an inline check for this PF_SPREAD_PAGE task -flag, and if set, a call to a new routine cpuset_mem_spread_node() -returns the node to prefer for the allocation. - -Similarly, setting 'memory_spread_slab' turns on the flag -PF_SPREAD_SLAB, and appropriately marked slab caches will allocate -pages from the node returned by cpuset_mem_spread_node(). - -The cpuset_mem_spread_node() routine is also simple. It uses the -value of a per-task rotor cpuset_mem_spread_rotor to select the next -node in the current tasks mems_allowed to prefer for the allocation. - -This memory placement policy is also known (in other contexts) as -round-robin or interleave. - -This policy can provide substantial improvements for jobs that need -to place thread local data on the corresponding node, but that need -to access large file system data sets that need to be spread across -the several nodes in the jobs cpuset in order to fit. Without this -policy, especially for jobs that might have one thread reading in the -data set, the memory allocation across the nodes in the jobs cpuset -can become very uneven. - -1.7 What is sched_load_balance ? --------------------------------- - -The kernel scheduler (kernel/sched.c) automatically load balances -tasks. If one CPU is underutilized, kernel code running on that -CPU will look for tasks on other more overloaded CPUs and move those -tasks to itself, within the constraints of such placement mechanisms -as cpusets and sched_setaffinity. - -The algorithmic cost of load balancing and its impact on key shared -kernel data structures such as the task list increases more than -linearly with the number of CPUs being balanced. So the scheduler -has support to partition the systems CPUs into a number of sched -domains such that it only load balances within each sched domain. -Each sched domain covers some subset of the CPUs in the system; -no two sched domains overlap; some CPUs might not be in any sched -domain and hence won't be load balanced. - -Put simply, it costs less to balance between two smaller sched domains -than one big one, but doing so means that overloads in one of the -two domains won't be load balanced to the other one. - -By default, there is one sched domain covering all CPUs, except those -marked isolated using the kernel boot time "isolcpus=" argument. - -This default load balancing across all CPUs is not well suited for -the following two situations: - 1) On large systems, load balancing across many CPUs is expensive. - If the system is managed using cpusets to place independent jobs - on separate sets of CPUs, full load balancing is unnecessary. - 2) Systems supporting realtime on some CPUs need to minimize - system overhead on those CPUs, including avoiding task load - balancing if that is not needed. - -When the per-cpuset flag "sched_load_balance" is enabled (the default -setting), it requests that all the CPUs in that cpusets allowed 'cpus' -be contained in a single sched domain, ensuring that load balancing -can move a task (not otherwised pinned, as by sched_setaffinity) -from any CPU in that cpuset to any other. - -When the per-cpuset flag "sched_load_balance" is disabled, then the -scheduler will avoid load balancing across the CPUs in that cpuset, ---except-- in so far as is necessary because some overlapping cpuset -has "sched_load_balance" enabled. - -So, for example, if the top cpuset has the flag "sched_load_balance" -enabled, then the scheduler will have one sched domain covering all -CPUs, and the setting of the "sched_load_balance" flag in any other -cpusets won't matter, as we're already fully load balancing. - -Therefore in the above two situations, the top cpuset flag -"sched_load_balance" should be disabled, and only some of the smaller, -child cpusets have this flag enabled. - -When doing this, you don't usually want to leave any unpinned tasks in -the top cpuset that might use non-trivial amounts of CPU, as such tasks -may be artificially constrained to some subset of CPUs, depending on -the particulars of this flag setting in descendent cpusets. Even if -such a task could use spare CPU cycles in some other CPUs, the kernel -scheduler might not consider the possibility of load balancing that -task to that underused CPU. - -Of course, tasks pinned to a particular CPU can be left in a cpuset -that disables "sched_load_balance" as those tasks aren't going anywhere -else anyway. - -There is an impedance mismatch here, between cpusets and sched domains. -Cpusets are hierarchical and nest. Sched domains are flat; they don't -overlap and each CPU is in at most one sched domain. - -It is necessary for sched domains to be flat because load balancing -across partially overlapping sets of CPUs would risk unstable dynamics -that would be beyond our understanding. So if each of two partially -overlapping cpusets enables the flag 'sched_load_balance', then we -form a single sched domain that is a superset of both. We won't move -a task to a CPU outside it cpuset, but the scheduler load balancing -code might waste some compute cycles considering that possibility. - -This mismatch is why there is not a simple one-to-one relation -between which cpusets have the flag "sched_load_balance" enabled, -and the sched domain configuration. If a cpuset enables the flag, it -will get balancing across all its CPUs, but if it disables the flag, -it will only be assured of no load balancing if no other overlapping -cpuset enables the flag. - -If two cpusets have partially overlapping 'cpus' allowed, and only -one of them has this flag enabled, then the other may find its -tasks only partially load balanced, just on the overlapping CPUs. -This is just the general case of the top_cpuset example given a few -paragraphs above. In the general case, as in the top cpuset case, -don't leave tasks that might use non-trivial amounts of CPU in -such partially load balanced cpusets, as they may be artificially -constrained to some subset of the CPUs allowed to them, for lack of -load balancing to the other CPUs. - -1.7.1 sched_load_balance implementation details. ------------------------------------------------- - -The per-cpuset flag 'sched_load_balance' defaults to enabled (contrary -to most cpuset flags.) When enabled for a cpuset, the kernel will -ensure that it can load balance across all the CPUs in that cpuset -(makes sure that all the CPUs in the cpus_allowed of that cpuset are -in the same sched domain.) - -If two overlapping cpusets both have 'sched_load_balance' enabled, -then they will be (must be) both in the same sched domain. - -If, as is the default, the top cpuset has 'sched_load_balance' enabled, -then by the above that means there is a single sched domain covering -the whole system, regardless of any other cpuset settings. - -The kernel commits to user space that it will avoid load balancing -where it can. It will pick as fine a granularity partition of sched -domains as it can while still providing load balancing for any set -of CPUs allowed to a cpuset having 'sched_load_balance' enabled. - -The internal kernel cpuset to scheduler interface passes from the -cpuset code to the scheduler code a partition of the load balanced -CPUs in the system. This partition is a set of subsets (represented -as an array of cpumask_t) of CPUs, pairwise disjoint, that cover all -the CPUs that must be load balanced. - -Whenever the 'sched_load_balance' flag changes, or CPUs come or go -from a cpuset with this flag enabled, or a cpuset with this flag -enabled is removed, the cpuset code builds a new such partition and -passes it to the scheduler sched domain setup code, to have the sched -domains rebuilt as necessary. - -This partition exactly defines what sched domains the scheduler should -setup - one sched domain for each element (cpumask_t) in the partition. - -The scheduler remembers the currently active sched domain partitions. -When the scheduler routine partition_sched_domains() is invoked from -the cpuset code to update these sched domains, it compares the new -partition requested with the current, and updates its sched domains, -removing the old and adding the new, for each change. - - -1.8 What is sched_relax_domain_level ? --------------------------------------- - -In sched domain, the scheduler migrates tasks in 2 ways; periodic load -balance on tick, and at time of some schedule events. - -When a task is woken up, scheduler try to move the task on idle CPU. -For example, if a task A running on CPU X activates another task B -on the same CPU X, and if CPU Y is X's sibling and performing idle, -then scheduler migrate task B to CPU Y so that task B can start on -CPU Y without waiting task A on CPU X. - -And if a CPU run out of tasks in its runqueue, the CPU try to pull -extra tasks from other busy CPUs to help them before it is going to -be idle. - -Of course it takes some searching cost to find movable tasks and/or -idle CPUs, the scheduler might not search all CPUs in the domain -everytime. In fact, in some architectures, the searching ranges on -events are limited in the same socket or node where the CPU locates, -while the load balance on tick searchs all. - -For example, assume CPU Z is relatively far from CPU X. Even if CPU Z -is idle while CPU X and the siblings are busy, scheduler can't migrate -woken task B from X to Z since it is out of its searching range. -As the result, task B on CPU X need to wait task A or wait load balance -on the next tick. For some applications in special situation, waiting -1 tick may be too long. - -The 'sched_relax_domain_level' file allows you to request changing -this searching range as you like. This file takes int value which -indicates size of searching range in levels ideally as follows, -otherwise initial value -1 that indicates the cpuset has no request. - - -1 : no request. use system default or follow request of others. - 0 : no search. - 1 : search siblings (hyperthreads in a core). - 2 : search cores in a package. - 3 : search cpus in a node [= system wide on non-NUMA system] - ( 4 : search nodes in a chunk of node [on NUMA system] ) - ( 5 : search system wide [on NUMA system] ) - -The system default is architecture dependent. The system default -can be changed using the relax_domain_level= boot parameter. - -This file is per-cpuset and affect the sched domain where the cpuset -belongs to. Therefore if the flag 'sched_load_balance' of a cpuset -is disabled, then 'sched_relax_domain_level' have no effect since -there is no sched domain belonging the cpuset. - -If multiple cpusets are overlapping and hence they form a single sched -domain, the largest value among those is used. Be careful, if one -requests 0 and others are -1 then 0 is used. - -Note that modifying this file will have both good and bad effects, -and whether it is acceptable or not will be depend on your situation. -Don't modify this file if you are not sure. - -If your situation is: - - The migration costs between each cpu can be assumed considerably - small(for you) due to your special application's behavior or - special hardware support for CPU cache etc. - - The searching cost doesn't have impact(for you) or you can make - the searching cost enough small by managing cpuset to compact etc. - - The latency is required even it sacrifices cache hit rate etc. -then increasing 'sched_relax_domain_level' would benefit you. - - -1.9 How do I use cpusets ? --------------------------- - -In order to minimize the impact of cpusets on critical kernel -code, such as the scheduler, and due to the fact that the kernel -does not support one task updating the memory placement of another -task directly, the impact on a task of changing its cpuset CPU -or Memory Node placement, or of changing to which cpuset a task -is attached, is subtle. - -If a cpuset has its Memory Nodes modified, then for each task attached -to that cpuset, the next time that the kernel attempts to allocate -a page of memory for that task, the kernel will notice the change -in the tasks cpuset, and update its per-task memory placement to -remain within the new cpusets memory placement. If the task was using -mempolicy MPOL_BIND, and the nodes to which it was bound overlap with -its new cpuset, then the task will continue to use whatever subset -of MPOL_BIND nodes are still allowed in the new cpuset. If the task -was using MPOL_BIND and now none of its MPOL_BIND nodes are allowed -in the new cpuset, then the task will be essentially treated as if it -was MPOL_BIND bound to the new cpuset (even though its numa placement, -as queried by get_mempolicy(), doesn't change). If a task is moved -from one cpuset to another, then the kernel will adjust the tasks -memory placement, as above, the next time that the kernel attempts -to allocate a page of memory for that task. - -If a cpuset has its 'cpus' modified, then each task in that cpuset -will have its allowed CPU placement changed immediately. Similarly, -if a tasks pid is written to a cpusets 'tasks' file, in either its -current cpuset or another cpuset, then its allowed CPU placement is -changed immediately. If such a task had been bound to some subset -of its cpuset using the sched_setaffinity() call, the task will be -allowed to run on any CPU allowed in its new cpuset, negating the -affect of the prior sched_setaffinity() call. - -In summary, the memory placement of a task whose cpuset is changed is -updated by the kernel, on the next allocation of a page for that task, -but the processor placement is not updated, until that tasks pid is -rewritten to the 'tasks' file of its cpuset. This is done to avoid -impacting the scheduler code in the kernel with a check for changes -in a tasks processor placement. - -Normally, once a page is allocated (given a physical page -of main memory) then that page stays on whatever node it -was allocated, so long as it remains allocated, even if the -cpusets memory placement policy 'mems' subsequently changes. -If the cpuset flag file 'memory_migrate' is set true, then when -tasks are attached to that cpuset, any pages that task had -allocated to it on nodes in its previous cpuset are migrated -to the tasks new cpuset. The relative placement of the page within -the cpuset is preserved during these migration operations if possible. -For example if the page was on the second valid node of the prior cpuset -then the page will be placed on the second valid node of the new cpuset. - -Also if 'memory_migrate' is set true, then if that cpusets -'mems' file is modified, pages allocated to tasks in that -cpuset, that were on nodes in the previous setting of 'mems', -will be moved to nodes in the new setting of 'mems.' -Pages that were not in the tasks prior cpuset, or in the cpusets -prior 'mems' setting, will not be moved. - -There is an exception to the above. If hotplug functionality is used -to remove all the CPUs that are currently assigned to a cpuset, -then all the tasks in that cpuset will be moved to the nearest ancestor -with non-empty cpus. But the moving of some (or all) tasks might fail if -cpuset is bound with another cgroup subsystem which has some restrictions -on task attaching. In this failing case, those tasks will stay -in the original cpuset, and the kernel will automatically update -their cpus_allowed to allow all online CPUs. When memory hotplug -functionality for removing Memory Nodes is available, a similar exception -is expected to apply there as well. In general, the kernel prefers to -violate cpuset placement, over starving a task that has had all -its allowed CPUs or Memory Nodes taken offline. - -There is a second exception to the above. GFP_ATOMIC requests are -kernel internal allocations that must be satisfied, immediately. -The kernel may drop some request, in rare cases even panic, if a -GFP_ATOMIC alloc fails. If the request cannot be satisfied within -the current tasks cpuset, then we relax the cpuset, and look for -memory anywhere we can find it. It's better to violate the cpuset -than stress the kernel. - -To start a new job that is to be contained within a cpuset, the steps are: - - 1) mkdir /dev/cpuset - 2) mount -t cgroup -ocpuset cpuset /dev/cpuset - 3) Create the new cpuset by doing mkdir's and write's (or echo's) in - the /dev/cpuset virtual file system. - 4) Start a task that will be the "founding father" of the new job. - 5) Attach that task to the new cpuset by writing its pid to the - /dev/cpuset tasks file for that cpuset. - 6) fork, exec or clone the job tasks from this founding father task. - -For example, the following sequence of commands will setup a cpuset -named "Charlie", containing just CPUs 2 and 3, and Memory Node 1, -and then start a subshell 'sh' in that cpuset: - - mount -t cgroup -ocpuset cpuset /dev/cpuset - cd /dev/cpuset - mkdir Charlie - cd Charlie - /bin/echo 2-3 > cpus - /bin/echo 1 > mems - /bin/echo $$ > tasks - sh - # The subshell 'sh' is now running in cpuset Charlie - # The next line should display '/Charlie' - cat /proc/self/cpuset - -In the future, a C library interface to cpusets will likely be -available. For now, the only way to query or modify cpusets is -via the cpuset file system, using the various cd, mkdir, echo, cat, -rmdir commands from the shell, or their equivalent from C. - -The sched_setaffinity calls can also be done at the shell prompt using -SGI's runon or Robert Love's taskset. The mbind and set_mempolicy -calls can be done at the shell prompt using the numactl command -(part of Andi Kleen's numa package). - -2. Usage Examples and Syntax -============================ - -2.1 Basic Usage ---------------- - -Creating, modifying, using the cpusets can be done through the cpuset -virtual filesystem. - -To mount it, type: -# mount -t cgroup -o cpuset cpuset /dev/cpuset - -Then under /dev/cpuset you can find a tree that corresponds to the -tree of the cpusets in the system. For instance, /dev/cpuset -is the cpuset that holds the whole system. - -If you want to create a new cpuset under /dev/cpuset: -# cd /dev/cpuset -# mkdir my_cpuset - -Now you want to do something with this cpuset. -# cd my_cpuset - -In this directory you can find several files: -# ls -cpu_exclusive memory_migrate mems tasks -cpus memory_pressure notify_on_release -mem_exclusive memory_spread_page sched_load_balance -mem_hardwall memory_spread_slab sched_relax_domain_level - -Reading them will give you information about the state of this cpuset: -the CPUs and Memory Nodes it can use, the processes that are using -it, its properties. By writing to these files you can manipulate -the cpuset. - -Set some flags: -# /bin/echo 1 > cpu_exclusive - -Add some cpus: -# /bin/echo 0-7 > cpus - -Add some mems: -# /bin/echo 0-7 > mems - -Now attach your shell to this cpuset: -# /bin/echo $$ > tasks - -You can also create cpusets inside your cpuset by using mkdir in this -directory. -# mkdir my_sub_cs - -To remove a cpuset, just use rmdir: -# rmdir my_sub_cs -This will fail if the cpuset is in use (has cpusets inside, or has -processes attached). - -Note that for legacy reasons, the "cpuset" filesystem exists as a -wrapper around the cgroup filesystem. - -The command - -mount -t cpuset X /dev/cpuset - -is equivalent to - -mount -t cgroup -ocpuset X /dev/cpuset -echo "/sbin/cpuset_release_agent" > /dev/cpuset/release_agent - -2.2 Adding/removing cpus ------------------------- - -This is the syntax to use when writing in the cpus or mems files -in cpuset directories: - -# /bin/echo 1-4 > cpus -> set cpus list to cpus 1,2,3,4 -# /bin/echo 1,2,3,4 > cpus -> set cpus list to cpus 1,2,3,4 - -2.3 Setting flags ------------------ - -The syntax is very simple: - -# /bin/echo 1 > cpu_exclusive -> set flag 'cpu_exclusive' -# /bin/echo 0 > cpu_exclusive -> unset flag 'cpu_exclusive' - -2.4 Attaching processes ------------------------ - -# /bin/echo PID > tasks - -Note that it is PID, not PIDs. You can only attach ONE task at a time. -If you have several tasks to attach, you have to do it one after another: - -# /bin/echo PID1 > tasks -# /bin/echo PID2 > tasks - ... -# /bin/echo PIDn > tasks - - -3. Questions -============ - -Q: what's up with this '/bin/echo' ? -A: bash's builtin 'echo' command does not check calls to write() against - errors. If you use it in the cpuset file system, you won't be - able to tell whether a command succeeded or failed. - -Q: When I attach processes, only the first of the line gets really attached ! -A: We can only return one error code per call to write(). So you should also - put only ONE pid. - -4. Contact -========== - -Web: http://www.bullopensource.org/cpuset diff --git a/Documentation/scheduler/sched-design-CFS.txt b/Documentation/scheduler/sched-design-CFS.txt index 8398ca4ff4e..6f33593e59e 100644 --- a/Documentation/scheduler/sched-design-CFS.txt +++ b/Documentation/scheduler/sched-design-CFS.txt @@ -231,7 +231,7 @@ CPU bandwidth control purposes: This options needs CONFIG_CGROUPS to be defined, and lets the administrator create arbitrary groups of tasks, using the "cgroup" pseudo filesystem. See - Documentation/cgroups.txt for more information about this filesystem. + Documentation/cgroups/cgroups.txt for more information about this filesystem. Only one of these options to group tasks can be chosen and not both. diff --git a/include/linux/res_counter.h b/include/linux/res_counter.h index dede0a2cfc4..4c5bcf6ca7e 100644 --- a/include/linux/res_counter.h +++ b/include/linux/res_counter.h @@ -9,7 +9,7 @@ * * Author: Pavel Emelianov * - * See Documentation/controllers/resource_counter.txt for more + * See Documentation/cgroups/resource_counter.txt for more * info about what this counter is. */ diff --git a/init/Kconfig b/init/Kconfig index 56fd93c63c7..2af83825634 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -323,8 +323,8 @@ config CGROUP_SCHED This option allows you to create arbitrary task groups using the "cgroup" pseudo filesystem and control the cpu bandwidth allocated to each such task group. - Refer to Documentation/cgroups.txt for more information - on "cgroup" pseudo filesystem. + Refer to Documentation/cgroups/cgroups.txt for more + information on "cgroup" pseudo filesystem. endchoice @@ -335,10 +335,9 @@ menuconfig CGROUPS use with process control subsystems such as Cpusets, CFS, memory controls or device isolation. See - - Documentation/cpusets.txt (Cpusets) - Documentation/scheduler/sched-design-CFS.txt (CFS) - - Documentation/cgroups/ (features for grouping, isolation) - - Documentation/controllers/ (features for resource control) + - Documentation/cgroups/ (features for grouping, isolation + and resource control) Say N if unsure. diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 647c77a88fc..a85678865c5 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -568,7 +568,7 @@ update_domain_attr_tree(struct sched_domain_attr *dattr, struct cpuset *c) * load balancing domains (sched domains) as specified by that partial * partition. * - * See "What is sched_load_balance" in Documentation/cpusets.txt + * See "What is sched_load_balance" in Documentation/cgroups/cpusets.txt * for a background explanation of this. * * Does not return errors, on the theory that the callers of this -- cgit From b098161b4d0231f7dc5306111d576c0bfe0c8eba Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Thu, 15 Jan 2009 13:51:00 -0800 Subject: idr: fix wrong kernel-doc idr_get_new_above() and ida_get_new_above() return an id in the range of @staring_id ... 0x7fffffff, not 0 ... 0x7fffffff. Signed-off-by: Li Zefan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/idr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/idr.c b/lib/idr.c index 1c4f9281f41..6b7cfa6508f 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -292,7 +292,7 @@ static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id) * and go back to the idr_pre_get() call. If the idr is full, it will * return -ENOSPC. * - * @id returns a value in the range 0 ... 0x7fffffff + * @id returns a value in the range @starting_id ... 0x7fffffff */ int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id) { @@ -723,7 +723,7 @@ EXPORT_SYMBOL(ida_pre_get); * and go back to the ida_pre_get() call. If the ida is full, it will * return -ENOSPC. * - * @p_id returns a value in the range 0 ... 0x7fffffff. + * @p_id returns a value in the range @starting_id ... 0x7fffffff. */ int ida_get_new_above(struct ida *ida, int starting_id, int *p_id) { -- cgit From 65a67bd2644bef225ee318dde76016a4697218fa Mon Sep 17 00:00:00 2001 From: Marcus Meissner Date: Thu, 15 Jan 2009 13:51:00 -0800 Subject: Documentation/accounting/getdelays.c: fix endless loop When no option is passed to getdelays it just hangs, waiting for a reply which will never come. This patch prints usage() when no output marker is specified. Signed-off-by: Marcus Meissner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/accounting/getdelays.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c index cc49400b4af..7ea231172c8 100644 --- a/Documentation/accounting/getdelays.c +++ b/Documentation/accounting/getdelays.c @@ -392,6 +392,10 @@ int main(int argc, char *argv[]) goto err; } } + if (!maskset && !tid && !containerset) { + usage(); + goto err; + } do { int i; -- cgit From 3eabdb76a03bbe8f556162738c264dbfb24cff6a Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 15 Jan 2009 13:51:01 -0800 Subject: jbd: fix missing kernel-doc Fix jbd header file kernel-doc notation: Warning(linux-2.6.28-git13//include/linux/jbd.h:823): No description found for parameter 'j_average_commit_time' Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/jbd.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/jbd.h b/include/linux/jbd.h index 6384b19efe6..64246dce566 100644 --- a/include/linux/jbd.h +++ b/include/linux/jbd.h @@ -614,6 +614,8 @@ struct transaction_s * @j_wbufsize: maximum number of buffer_heads allowed in j_wbuf, the * number that will fit in j_blocksize * @j_last_sync_writer: most recent pid which did a synchronous write + * @j_average_commit_time: the average amount of time in nanoseconds it + * takes to commit a transaction to the disk. * @j_private: An opaque pointer to fs-private information. */ -- cgit From 6ae301e85c9c58d2f430a8a7057ce488b7ff76df Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 15 Jan 2009 13:51:01 -0800 Subject: resources: fix parameter name and kernel-doc Fix __request_region() parameter kernel-doc notation and parameter name: Warning(linux-2.6.28-git10//kernel/resource.c:627): No description found for parameter 'flags' Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/ioport.h | 3 ++- kernel/resource.c | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/linux/ioport.h b/include/linux/ioport.h index f6bb2ca8e3b..32e4b2f7229 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -143,7 +143,8 @@ static inline unsigned long resource_type(struct resource *res) extern struct resource * __request_region(struct resource *, resource_size_t start, - resource_size_t n, const char *name, int relaxed); + resource_size_t n, + const char *name, int flags); /* Compatibility cruft */ #define release_region(start,n) __release_region(&ioport_resource, (start), (n)) diff --git a/kernel/resource.c b/kernel/resource.c index ca6a1536b20..fd5d7d574bb 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -620,6 +620,7 @@ resource_size_t resource_alignment(struct resource *res) * @start: resource start address * @n: resource region size * @name: reserving caller's ID string + * @flags: IO resource flags */ struct resource * __request_region(struct resource *parent, resource_size_t start, resource_size_t n, -- cgit From 71038f527f3665f562cf9afe083df729958a099b Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Thu, 15 Jan 2009 13:51:02 -0800 Subject: MAINTAINERS: add entry for freezer Now that people are using freezer for non-suspend/hibernation stuff, it should have separate maintainers entry so that it is easier to find. Signed-off-by: Pavel Machek Acked-by: Rafael J. Wysocki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 73548f8ad0b..3fe4dc2c256 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1821,6 +1821,14 @@ M: hch@infradead.org W: ftp://ftp.openlinux.org/pub/people/hch/vxfs S: Maintained +FREEZER +P: Pavel Machek +M: pavel@suse.cz +P: Rafael J. Wysocki +M: rjw@sisk.pl +L: linux-pm@lists.linux-foundation.org +S: Supported + FTRACE P: Steven Rostedt M: rostedt@goodmis.org -- cgit From 1bcbf31337391a2f54ef6c1e8871c2de5944a7dc Mon Sep 17 00:00:00 2001 From: Qinghuang Feng Date: Thu, 15 Jan 2009 13:51:03 -0800 Subject: btrfs & squashfs: Move btrfs and squashfsto's magic number to Use the standard magic.h for btrfs and squashfs. Signed-off-by: Qinghuang Feng Cc: Phillip Lougher Cc: Chris Mason Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/btrfs/super.c | 2 +- fs/squashfs/squashfs_fs.h | 1 - fs/squashfs/super.c | 1 + include/linux/magic.h | 2 ++ 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 0a14b495532..7256cf242eb 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "compat.h" #include "ctree.h" #include "disk-io.h" @@ -51,7 +52,6 @@ #include "export.h" #include "compression.h" -#define BTRFS_SUPER_MAGIC 0x9123683E static struct super_operations btrfs_super_ops; diff --git a/fs/squashfs/squashfs_fs.h b/fs/squashfs/squashfs_fs.h index 6840da1bf21..283daafc568 100644 --- a/fs/squashfs/squashfs_fs.h +++ b/fs/squashfs/squashfs_fs.h @@ -26,7 +26,6 @@ #define SQUASHFS_CACHED_FRAGMENTS CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE #define SQUASHFS_MAJOR 4 #define SQUASHFS_MINOR 0 -#define SQUASHFS_MAGIC 0x73717368 #define SQUASHFS_START 0 /* size of metadata (inode and directory) blocks */ diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c index a0466d7467b..071df5b5b49 100644 --- a/fs/squashfs/super.c +++ b/fs/squashfs/super.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "squashfs_fs.h" #include "squashfs_fs_sb.h" diff --git a/include/linux/magic.h b/include/linux/magic.h index 439f6f3cb0c..0b4df7eba85 100644 --- a/include/linux/magic.h +++ b/include/linux/magic.h @@ -10,11 +10,13 @@ #define SYSFS_MAGIC 0x62656572 #define SECURITYFS_MAGIC 0x73636673 #define TMPFS_MAGIC 0x01021994 +#define SQUASHFS_MAGIC 0x73717368 #define EFS_SUPER_MAGIC 0x414A53 #define EXT2_SUPER_MAGIC 0xEF53 #define EXT3_SUPER_MAGIC 0xEF53 #define XENFS_SUPER_MAGIC 0xabba1974 #define EXT4_SUPER_MAGIC 0xEF53 +#define BTRFS_SUPER_MAGIC 0x9123683E #define HPFS_SUPER_MAGIC 0xf995e849 #define ISOFS_SUPER_MAGIC 0x9660 #define JFFS2_SUPER_MAGIC 0x72b6 -- cgit From c91192d66d6cea7878b8542c9d9f1873971aba92 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Thu, 15 Jan 2009 13:51:03 -0800 Subject: nbd: do not allow two clients at the same time Two nbd-clients at same time are bad idea, and cause WARN_ON from nbd in 2.6.28-rc7 from sysfs_add_one. This simply prevents that from happening. To reproduce: cat /dev/zero | head -c 10000000 > /tmp/delme.fstest.fs nbd-server 9100 -l /anyone.can.connect > /tmp/delme.fstest.fs & sleep 1 nbd-client localhost 9100 /dev/nd0 & nbd-client localhost 9100 /dev/nd0 & Signed-off-by: Pavel Machek Acked-by: Paul Clements Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/nbd.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 7bcc1d8bc96..34f80fa6fed 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -406,6 +406,7 @@ static int nbd_do_it(struct nbd_device *lo) ret = sysfs_create_file(&disk_to_dev(lo->disk)->kobj, &pid_attr.attr); if (ret) { printk(KERN_ERR "nbd: sysfs_create_file failed!"); + lo->pid = 0; return ret; } @@ -413,6 +414,7 @@ static int nbd_do_it(struct nbd_device *lo) nbd_end_request(req); sysfs_remove_file(&disk_to_dev(lo->disk)->kobj, &pid_attr.attr); + lo->pid = 0; return 0; } @@ -648,6 +650,8 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode, set_capacity(lo->disk, lo->bytesize >> 9); return 0; case NBD_DO_IT: + if (lo->pid) + return -EBUSY; if (!lo->file) return -EINVAL; thread = kthread_create(nbd_thread, lo, lo->disk->disk_name); -- cgit From a27506459c5e6ccc8437fca0adb6d3759c883c28 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Thu, 15 Jan 2009 13:51:04 -0800 Subject: checkpatch: handle missing #if open in context If the #if opening statement is not in the context then the context stack can be empty. Handle this by ensuring there is always a blank entry in the stack. Signed-off-by: Andy Whitcroft Tested-by: Dhaval Giani Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 7bed4ed2c51..eefef65fa58 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -411,13 +411,15 @@ sub ctx_statement_block { my $type = ''; my $level = 0; - my @stack = ([$type, $level]); + my @stack = (); my $p; my $c; my $len = 0; my $remainder; while (1) { + @stack = (['', 0]) if ($#stack == -1); + #warn "CSB: blk<$blk> remain<$remain>\n"; # If we are about to drop off the end, pull in more # context. -- cgit From f9a0b3d17a01fe1ba24ce1e9c18666a52052e011 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Thu, 15 Jan 2009 13:51:05 -0800 Subject: checkpatch: type/cast spacing should not check prefix spacing We should not be complaining about the prefix spacing for types and casts. We are triggering here because the check for spacing between '*'s is overly loose. Tighten this up. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index eefef65fa58..1d7924ad3a3 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1665,7 +1665,7 @@ sub process { # Should not end with a space. $to =~ s/\s+$//; # '*'s should not have spaces between. - while ($to =~ s/(.)\s\*/$1\*/) { + while ($to =~ s/\*\s+\*/\*\*/) { } #print "from<$from> to<$to>\n"; @@ -1680,7 +1680,7 @@ sub process { # Should not end with a space. $to =~ s/\s+$//; # '*'s should not have spaces between. - while ($to =~ s/(.)\s\*/$1\*/) { + while ($to =~ s/\*\s+\*/\*\*/) { } # Modifiers should have spaces. $to =~ s/(\b$Modifier$)/$1 /; -- cgit From 63f17f8973ccdb8260e59ce5b1b4e2b2ee0401f0 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Thu, 15 Jan 2009 13:51:06 -0800 Subject: checkpatch: allow parentheses on return handle array values When we allow return to have surrounding parentheses when containing comparison operators we are not correctly handling the case where the values contain array sufffixes. Squash them. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 1d7924ad3a3..696196e194f 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2016,7 +2016,11 @@ sub process { # Flatten any parentheses $value =~ s/\)\(/\) \(/g; - while ($value !~ /(?:$Ident|-?$Constant)\s*$Compare\s*(?:$Ident|-?$Constant)/ && $value =~ s/\([^\(\)]*\)/1/) { + while ($value =~ s/\[[^\{\}]*\]/1/ || + $value !~ /(?:$Ident|-?$Constant)\s* + $Compare\s* + (?:$Ident|-?$Constant)/x && + $value =~ s/\([^\(\)]*\)/1/) { } if ($value =~ /^(?:$Ident|-?$Constant)$/) { -- cgit From 39667782362becd5527e48d6c976a9f9985b95e6 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Thu, 15 Jan 2009 13:51:06 -0800 Subject: checkpatch: if should not continue a preceeding brace We should not be continuing a braced section with an if, for example: if (...) { } if (...) { } Detect this and suggest adding a newline. Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 696196e194f..5ea55e330c2 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2108,6 +2108,11 @@ sub process { ERROR("trailing statements should be on next line\n" . $herecurr); } } +# if should not continue a brace + if ($line =~ /}\s*if\b/) { + ERROR("trailing statements should be on next line\n" . + $herecurr); + } # case and default should not have general statements after them if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && $line !~ /\G(?: -- cgit From 6903ffb2257266472ef2edd0092d526ae2dc00f7 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Thu, 15 Jan 2009 13:51:07 -0800 Subject: checkpatch: struct seq_operations should normally be const In the general use case struct seq_operations should be a const object. Check for and warn where it is not. Cc: Ingo Molnar Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 5ea55e330c2..447435c33dd 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2527,9 +2527,10 @@ sub process { WARN("please use device_initcall() instead of __initcall()\n" . $herecurr); } # check for struct file_operations, ensure they are const. - if ($line =~ /\bstruct\s+file_operations\b/ && - $line !~ /\bconst\b/) { - WARN("struct file_operations should normally be const\n" . $herecurr); + if ($line !~ /\bconst\b/ && + $line =~ /\bstruct\s+(file_operations|seq_operations)\b/) { + WARN("struct $1 should normally be const\n" . + $herecurr); } # use of NR_CPUS is usually wrong -- cgit From db92a6502d4e8cb885e85e862b24ba5c07036fbf Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Thu, 15 Jan 2009 13:51:07 -0800 Subject: checkpatch: version: 0.27 Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 447435c33dd..45eb0ae98eb 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -10,7 +10,7 @@ use strict; my $P = $0; $P =~ s@.*/@@g; -my $V = '0.26'; +my $V = '0.27'; use Getopt::Long qw(:config no_auto_abbrev); -- cgit From c3d6362b8717759de7f2086f9665a4d96cacbc51 Mon Sep 17 00:00:00 2001 From: Alex Murray Date: Thu, 15 Jan 2009 13:51:08 -0800 Subject: hwmon: applesmc: fix light sensor readings on newer MacBooks The light sensors ALV0 and ALV1 on newer MacBooks (early 2008 and later) changed to report 10 bytes instead the earlier 6, and the sensor encoding subsequently changed. As a result, the reported light sensors readings are much too low. Via experiments leading up to this patch, it seems only the ALV0 is reporting data, and the most useful value therein is a 10-bit big-endian value at offset 6. This suggests that a new protocol was added as a backward-compatible replacement on top of the old one. This patch makes applesmc report the improved light sensor reading for the new machines, on a scale in conformance with earlier ones. Signed-off-by: Alex Murray Signed-off-by: Henrik Rydberg Cc: Nicolas Boichat Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/hwmon/applesmc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index dca47a591ba..e3018623658 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -590,6 +590,11 @@ static ssize_t applesmc_light_show(struct device *dev, } ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length); + /* newer macbooks report a single 10-bit bigendian value */ + if (data_length == 10) { + left = be16_to_cpu(*(__be16 *)(buffer + 6)) >> 2; + goto out; + } left = buffer[2]; if (ret) goto out; -- cgit From bd112db872c2f69993c86f458467acb4a14da010 Mon Sep 17 00:00:00 2001 From: Daisuke Nishimura Date: Thu, 15 Jan 2009 13:51:11 -0800 Subject: memcg: fix mem_cgroup_get_reclaim_stat_from_page In case of swapin, a new page is added to lru before it is charged, so page->pc->mem_cgroup points to NULL or last mem_cgroup the page was charged before. In the latter case, if the mem_cgroup has already freed by rmdir, the area pointed to by page->pc->mem_cgroup may have invalid data. Actually, I saw general protection fault. general protection fault: 0000 [#1] SMP last sysfs file: /sys/devices/system/cpu/cpu15/cache/index1/shared_cpu_map CPU 4 Modules linked in: ipt_REJECT xt_tcpudp iptable_filter ip_tables x_tables bridge stp ipv6 autofs4 hidp rfcomm l2cap bluetooth sunrpc dm_mirror dm_region_hash dm_log dm_multipath dm_mod rfkill input_polldev sbs sbshc battery ac lp sg ide_cd_mod cdrom button serio_raw acpi_memhotplug parport_pc e1000 rtc_cmos parport rtc_core rtc_lib i2c_i801 i2c_core shpchp pcspkr ata_piix libata megaraid_mbox megaraid_mm sd_mod scsi_mod ext3 jbd ehci_hcd ohci_hcd uhci_hcd [last unloaded: microcode] Pid: 26038, comm: page01 Tainted: G W 2.6.28-rc9-mm1-mmotm-2008-12-22-16-14-f2ab3dea #1 RIP: 0010:[] [] update_page_reclaim_stat+0x2f/0x42 RSP: 0000:ffff8801ee457da8 EFLAGS: 00010002 RAX: 32353438312021c8 RBX: 0000000000000000 RCX: 32353438312021c8 RDX: 0000000000000000 RSI: ffff8800cb0b1000 RDI: ffff8801164d1d28 RBP: ffff880110002cb8 R08: ffff88010f2eae23 R09: 0000000000000001 R10: ffff8800bc514b00 R11: ffff880110002c00 R12: 0000000000000000 R13: ffff88000f484100 R14: 0000000000000003 R15: 00000000001200d2 FS: 00007f8a261726f0(0000) GS:ffff88010f2eaa80(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 00007f8a25d22000 CR3: 00000001ef18c000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process page01 (pid: 26038, threadinfo ffff8801ee456000, task ffff8800b585b960) Stack: ffffe200071ee568 ffff880110001f00 0000000000000000 ffffffff8028ea17 ffff88000f484100 0000000000000000 0000000000000020 00007f8a25d22000 ffff8800bc514b00 ffffffff8028ec34 0000000000000000 0000000000016fd8 Call Trace: [] ? ____pagevec_lru_add+0xc1/0x13c [] ? drain_cpu_pagevecs+0x36/0x89 [] ? swapin_readahead+0x78/0x98 [] ? handle_mm_fault+0x3d9/0x741 [] ? do_page_fault+0x3ce/0x78c [] ? trace_hardirqs_off_thunk+0x3a/0x3c [] ? page_fault+0x1f/0x30 Code: cc 55 48 8d af b8 0d 00 00 48 89 f7 53 89 d3 e8 39 85 02 00 48 63 d3 48 ff 44 d5 10 45 85 e4 74 05 48 ff 44 d5 00 48 85 c0 74 0e <48> ff 44 d0 10 45 85 e4 74 04 48 ff 04 d0 5b 5d 41 5c c3 41 54 RIP [] update_page_reclaim_stat+0x2f/0x42 RSP Signed-off-by: Daisuke Nishimura Acked-by: KAMEZAWA Hiroyuki Cc: Balbir Singh Cc: Pavel Emelyanov Cc: Li Zefan Cc: Paul Menage Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memcontrol.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index e2996b80601..b6651277116 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -358,6 +358,10 @@ void mem_cgroup_rotate_lru_list(struct page *page, enum lru_list lru) return; pc = lookup_page_cgroup(page); + /* + * Used bit is set without atomic ops but after smp_wmb(). + * For making pc->mem_cgroup visible, insert smp_rmb() here. + */ smp_rmb(); /* unused page is not rotated. */ if (!PageCgroupUsed(pc)) @@ -374,7 +378,10 @@ void mem_cgroup_add_lru_list(struct page *page, enum lru_list lru) if (mem_cgroup_disabled()) return; pc = lookup_page_cgroup(page); - /* barrier to sync with "charge" */ + /* + * Used bit is set without atomic ops but after smp_wmb(). + * For making pc->mem_cgroup visible, insert smp_rmb() here. + */ smp_rmb(); if (!PageCgroupUsed(pc)) return; @@ -559,6 +566,14 @@ mem_cgroup_get_reclaim_stat_from_page(struct page *page) return NULL; pc = lookup_page_cgroup(page); + /* + * Used bit is set without atomic ops but after smp_wmb(). + * For making pc->mem_cgroup visible, insert smp_rmb() here. + */ + smp_rmb(); + if (!PageCgroupUsed(pc)) + return NULL; + mz = page_cgroup_zoneinfo(pc); if (!mz) return NULL; -- cgit From 40d58138f832a48208cdce57d6572a033b1f7a23 Mon Sep 17 00:00:00 2001 From: Daisuke Nishimura Date: Thu, 15 Jan 2009 13:51:12 -0800 Subject: memcg: fix error path of mem_cgroup_move_parent There is a bug in error path of mem_cgroup_move_parent. Extra refcnt got from try_charge should be dropped, and usages incremented by try_charge should be decremented in both error paths: A: failure at get_page_unless_zero B: failure at isolate_lru_page This bug makes this parent directory unremovable. In case of A, rmdir doesn't return, because res.usage doesn't go down to 0 at mem_cgroup_force_empty even after all the pc in lru are removed. In case of B, rmdir fails and returns -EBUSY, because it has extra ref counts even after res.usage goes down to 0. Signed-off-by: Daisuke Nishimura Acked-by: KAMEZAWA Hiroyuki Acked-by: Balbir Singh Cc: Pavel Emelyanov Cc: Li Zefan Cc: Paul Menage Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memcontrol.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index b6651277116..7be9b35d7ff 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -994,14 +994,15 @@ static int mem_cgroup_move_account(struct page_cgroup *pc, if (pc->mem_cgroup != from) goto out; - css_put(&from->css); res_counter_uncharge(&from->res, PAGE_SIZE); mem_cgroup_charge_statistics(from, pc, false); if (do_swap_account) res_counter_uncharge(&from->memsw, PAGE_SIZE); + css_put(&from->css); + + css_get(&to->css); pc->mem_cgroup = to; mem_cgroup_charge_statistics(to, pc, true); - css_get(&to->css); ret = 0; out: unlock_page_cgroup(pc); @@ -1034,8 +1035,10 @@ static int mem_cgroup_move_parent(struct page_cgroup *pc, if (ret || !parent) return ret; - if (!get_page_unless_zero(page)) - return -EBUSY; + if (!get_page_unless_zero(page)) { + ret = -EBUSY; + goto uncharge; + } ret = isolate_lru_page(page); @@ -1044,19 +1047,23 @@ static int mem_cgroup_move_parent(struct page_cgroup *pc, ret = mem_cgroup_move_account(pc, child, parent); - /* drop extra refcnt by try_charge() (move_account increment one) */ - css_put(&parent->css); putback_lru_page(page); if (!ret) { put_page(page); + /* drop extra refcnt by try_charge() */ + css_put(&parent->css); return 0; } - /* uncharge if move fails */ + cancel: + put_page(page); +uncharge: + /* drop extra refcnt by try_charge() */ + css_put(&parent->css); + /* uncharge if move fails */ res_counter_uncharge(&parent->res, PAGE_SIZE); if (do_swap_account) res_counter_uncharge(&parent->memsw, PAGE_SIZE); - put_page(page); return ret; } -- cgit From c268e9946d7dc30ac4e55cdc3f43c8af1ae8153c Mon Sep 17 00:00:00 2001 From: Daisuke Nishimura Date: Thu, 15 Jan 2009 13:51:13 -0800 Subject: memcg: fix hierarchical reclaim If root_mem has no children, last_scaned_child is set to root_mem itself. But after some children added to root_mem, mem_cgroup_get_next_node can mem_cgroup_put the root_mem although root_mem has not been mem_cgroup_get. This patch fixes this behavior by: - Set last_scanned_child to NULL if root_mem has no children or DFS search has returned to root_mem itself(root_mem is not a "child" of root_mem). Make mem_cgroup_get_first_node return root_mem in this case. There are no mem_cgroup_get/put for root_mem. - Rename mem_cgroup_get_next_node to __mem_cgroup_get_next_node, and mem_cgroup_get_first_node to mem_cgroup_get_next_node. Make mem_cgroup_hierarchical_reclaim call only new mem_cgroup_get_next_node. Signed-off-by: Daisuke Nishimura Cc: Balbir Singh Cc: KAMEZAWA Hiroyuki Cc: Pavel Emelyanov Cc: Li Zefan Cc: Paul Menage Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memcontrol.c | 68 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 7be9b35d7ff..322625f551c 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -633,7 +633,7 @@ unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan, * called with hierarchy_mutex held */ static struct mem_cgroup * -mem_cgroup_get_next_node(struct mem_cgroup *curr, struct mem_cgroup *root_mem) +__mem_cgroup_get_next_node(struct mem_cgroup *curr, struct mem_cgroup *root_mem) { struct cgroup *cgroup, *curr_cgroup, *root_cgroup; @@ -644,19 +644,16 @@ mem_cgroup_get_next_node(struct mem_cgroup *curr, struct mem_cgroup *root_mem) /* * Walk down to children */ - mem_cgroup_put(curr); cgroup = list_entry(curr_cgroup->children.next, struct cgroup, sibling); curr = mem_cgroup_from_cont(cgroup); - mem_cgroup_get(curr); goto done; } visit_parent: if (curr_cgroup == root_cgroup) { - mem_cgroup_put(curr); - curr = root_mem; - mem_cgroup_get(curr); + /* caller handles NULL case */ + curr = NULL; goto done; } @@ -664,11 +661,9 @@ visit_parent: * Goto next sibling */ if (curr_cgroup->sibling.next != &curr_cgroup->parent->children) { - mem_cgroup_put(curr); cgroup = list_entry(curr_cgroup->sibling.next, struct cgroup, sibling); curr = mem_cgroup_from_cont(cgroup); - mem_cgroup_get(curr); goto done; } @@ -679,7 +674,6 @@ visit_parent: goto visit_parent; done: - root_mem->last_scanned_child = curr; return curr; } @@ -689,40 +683,46 @@ done: * that to reclaim free pages from. */ static struct mem_cgroup * -mem_cgroup_get_first_node(struct mem_cgroup *root_mem) +mem_cgroup_get_next_node(struct mem_cgroup *root_mem) { struct cgroup *cgroup; - struct mem_cgroup *ret; + struct mem_cgroup *orig, *next; bool obsolete; - obsolete = mem_cgroup_is_obsolete(root_mem->last_scanned_child); - /* * Scan all children under the mem_cgroup mem */ mutex_lock(&mem_cgroup_subsys.hierarchy_mutex); + + orig = root_mem->last_scanned_child; + obsolete = mem_cgroup_is_obsolete(orig); + if (list_empty(&root_mem->css.cgroup->children)) { - ret = root_mem; + /* + * root_mem might have children before and last_scanned_child + * may point to one of them. We put it later. + */ + if (orig) + VM_BUG_ON(!obsolete); + next = NULL; goto done; } - if (!root_mem->last_scanned_child || obsolete) { - - if (obsolete && root_mem->last_scanned_child) - mem_cgroup_put(root_mem->last_scanned_child); - + if (!orig || obsolete) { cgroup = list_first_entry(&root_mem->css.cgroup->children, struct cgroup, sibling); - ret = mem_cgroup_from_cont(cgroup); - mem_cgroup_get(ret); + next = mem_cgroup_from_cont(cgroup); } else - ret = mem_cgroup_get_next_node(root_mem->last_scanned_child, - root_mem); + next = __mem_cgroup_get_next_node(orig, root_mem); done: - root_mem->last_scanned_child = ret; + if (next) + mem_cgroup_get(next); + root_mem->last_scanned_child = next; + if (orig) + mem_cgroup_put(orig); mutex_unlock(&mem_cgroup_subsys.hierarchy_mutex); - return ret; + return (next) ? next : root_mem; } static bool mem_cgroup_check_under_limit(struct mem_cgroup *mem) @@ -780,21 +780,18 @@ static int mem_cgroup_hierarchical_reclaim(struct mem_cgroup *root_mem, if (!root_mem->use_hierarchy) return ret; - next_mem = mem_cgroup_get_first_node(root_mem); + next_mem = mem_cgroup_get_next_node(root_mem); while (next_mem != root_mem) { if (mem_cgroup_is_obsolete(next_mem)) { - mem_cgroup_put(next_mem); - next_mem = mem_cgroup_get_first_node(root_mem); + next_mem = mem_cgroup_get_next_node(root_mem); continue; } ret = try_to_free_mem_cgroup_pages(next_mem, gfp_mask, noswap, get_swappiness(next_mem)); if (mem_cgroup_check_under_limit(root_mem)) return 0; - mutex_lock(&mem_cgroup_subsys.hierarchy_mutex); - next_mem = mem_cgroup_get_next_node(next_mem, root_mem); - mutex_unlock(&mem_cgroup_subsys.hierarchy_mutex); + next_mem = mem_cgroup_get_next_node(root_mem); } return ret; } @@ -2254,7 +2251,14 @@ static void mem_cgroup_pre_destroy(struct cgroup_subsys *ss, static void mem_cgroup_destroy(struct cgroup_subsys *ss, struct cgroup *cont) { - mem_cgroup_put(mem_cgroup_from_cont(cont)); + struct mem_cgroup *mem = mem_cgroup_from_cont(cont); + struct mem_cgroup *last_scanned_child = mem->last_scanned_child; + + if (last_scanned_child) { + VM_BUG_ON(!mem_cgroup_is_obsolete(last_scanned_child)); + mem_cgroup_put(last_scanned_child); + } + mem_cgroup_put(mem); } static int mem_cgroup_populate(struct cgroup_subsys *ss, -- cgit From 4d1c627389c8ba6d9e703208567ffcdbd356f682 Mon Sep 17 00:00:00 2001 From: Daisuke Nishimura Date: Thu, 15 Jan 2009 13:51:14 -0800 Subject: memcg: make oom less frequently In previous implementation, mem_cgroup_try_charge checked the return value of mem_cgroup_try_to_free_pages, and just retried if some pages had been reclaimed. But now, try_charge(and mem_cgroup_hierarchical_reclaim called from it) only checks whether the usage is less than the limit. This patch tries to change the behavior as before to cause oom less frequently. Signed-off-by: Daisuke Nishimura Acked-by: Balbir Singh Acked-by: KAMEZAWA Hiroyuki Cc: Pavel Emelyanov Cc: Li Zefan Cc: Paul Menage Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memcontrol.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 322625f551c..fb62b4335fa 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -773,10 +773,10 @@ static int mem_cgroup_hierarchical_reclaim(struct mem_cgroup *root_mem, * but there might be left over accounting, even after children * have left. */ - ret = try_to_free_mem_cgroup_pages(root_mem, gfp_mask, noswap, + ret += try_to_free_mem_cgroup_pages(root_mem, gfp_mask, noswap, get_swappiness(root_mem)); if (mem_cgroup_check_under_limit(root_mem)) - return 0; + return 1; /* indicate reclaim has succeeded */ if (!root_mem->use_hierarchy) return ret; @@ -787,10 +787,10 @@ static int mem_cgroup_hierarchical_reclaim(struct mem_cgroup *root_mem, next_mem = mem_cgroup_get_next_node(root_mem); continue; } - ret = try_to_free_mem_cgroup_pages(next_mem, gfp_mask, noswap, + ret += try_to_free_mem_cgroup_pages(next_mem, gfp_mask, noswap, get_swappiness(next_mem)); if (mem_cgroup_check_under_limit(root_mem)) - return 0; + return 1; /* indicate reclaim has succeeded */ next_mem = mem_cgroup_get_next_node(root_mem); } return ret; @@ -875,6 +875,8 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm, ret = mem_cgroup_hierarchical_reclaim(mem_over_limit, gfp_mask, noswap); + if (ret) + continue; /* * try_to_free_mem_cgroup_pages() might not give us a full -- cgit From 46666d8ac42893f90edde7e57a11bc8749d7e89c Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 15 Jan 2009 13:51:15 -0800 Subject: revert "mm: vmalloc use mutex for purge" Revert commit e97a630eb0f5b8b380fd67504de6cedebb489003 ("mm: vmalloc use mutex for purge") Bryan Donlan reports: : After testing 2.6.29-rc1 on xen-x86 with a btrfs root filesystem, I : got the OOPS quoted below and a hard freeze shortly after boot. : Boot messages and config are attached. : : ------------[ cut here ]------------ : Kernel BUG at c05ef80d [verbose debug info unavailable] : invalid opcode: 0000 [#1] SMP : last sysfs file: /sys/block/xvdc/size : Modules linked in: : : Pid: 0, comm: swapper Not tainted (2.6.29-rc1 #6) : EIP: 0061:[] EFLAGS: 00010087 CPU: 2 : EIP is at schedule+0x7cd/0x950 : EAX: d5aeca80 EBX: 00000002 ECX: 00000000 EDX: d4cb9a40 : ESI: c12f5600 EDI: d4cb9a40 EBP: d6033fa4 ESP: d6033ef4 : DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0069 : Process swapper (pid: 0, ti=d6032000 task=d6020b70 task.ti=d6032000) : Stack: : 000d85bc 00000000 000186a0 00000000 0dd11410 c0105417 c12efe00 0dc367c3 : 00000011 c0105d46 d5a5d310 deadbeef d4cb9a40 c07cc600 c05f1340 c12e0060 : deadbeef d6020b70 d6020d08 00000002 c014377d 00000000 c12f5600 00002c22 : Call Trace: : [] xen_force_evtchn_callback+0x17/0x30 : [] check_events+0x8/0x12 : [] _spin_unlock_irqrestore+0x20/0x40 : [] hrtimer_start_range_ns+0x12d/0x2e0 : [] tick_nohz_restart_sched_tick+0x146/0x160 : [] cpu_idle+0xa5/0xc0 and bisected it to this commit. Let's remove it now while we have a think about the problem. Reported-by: Bryan Donlan Tested-by: Christophe Saout Cc: Nick Piggin Cc: Ingo Molnar Cc: Jeremy Fitzhardinge Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmalloc.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 7e00b280648..75f49d312e8 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -496,7 +495,7 @@ static atomic_t vmap_lazy_nr = ATOMIC_INIT(0); static void __purge_vmap_area_lazy(unsigned long *start, unsigned long *end, int sync, int force_flush) { - static DEFINE_MUTEX(purge_lock); + static DEFINE_SPINLOCK(purge_lock); LIST_HEAD(valist); struct vmap_area *va; int nr = 0; @@ -507,10 +506,10 @@ static void __purge_vmap_area_lazy(unsigned long *start, unsigned long *end, * the case that isn't actually used at the moment anyway. */ if (!sync && !force_flush) { - if (!mutex_trylock(&purge_lock)) + if (!spin_trylock(&purge_lock)) return; } else - mutex_lock(&purge_lock); + spin_lock(&purge_lock); rcu_read_lock(); list_for_each_entry_rcu(va, &vmap_area_list, list) { @@ -542,7 +541,7 @@ static void __purge_vmap_area_lazy(unsigned long *start, unsigned long *end, __free_vmap_area(va); spin_unlock(&vmap_area_lock); } - mutex_unlock(&purge_lock); + spin_unlock(&purge_lock); } /* -- cgit From 70b66cbfd3316b792a855cb9a2574e85f1a63d0f Mon Sep 17 00:00:00 2001 From: Ivan Kokshaysky Date: Thu, 15 Jan 2009 13:51:17 -0800 Subject: alpha: nautilus - fix compile failure with gcc-4.3 init_srm_irq() deals with irq's #16 and above, but size of irq_desc array on nautilus and some other system types is 16. So gcc-4.3 complains that "array subscript is above array bounds", even though this function is never called on those systems. This adds a check for NR_IRQS <= 16, which effectively optimizes init_srm_irq() code away on problematic platforms. Thanks to Daniel Drake for detailed analysis of the problem. Signed-off-by: Ivan Kokshaysky Cc: Richard Henderson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/kernel/irq_srm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/alpha/kernel/irq_srm.c b/arch/alpha/kernel/irq_srm.c index 32212014fbe..a03fbca4940 100644 --- a/arch/alpha/kernel/irq_srm.c +++ b/arch/alpha/kernel/irq_srm.c @@ -63,6 +63,8 @@ init_srm_irqs(long max, unsigned long ignore_mask) { long i; + if (NR_IRQS <= 16) + return; for (i = 16; i < max; ++i) { if (i < 64 && ((ignore_mask >> i) & 1)) continue; -- cgit From 2f88d151cb8e73587983d7feccd70672ff6730fe Mon Sep 17 00:00:00 2001 From: Ivan Kokshaysky Date: Thu, 15 Jan 2009 13:51:18 -0800 Subject: alpha: nautilus - fix hang on boot Recently introduced generic pci_common_swizzle() relies on bus->self being NULL for the root PCI bus. But on nautilus bus->self points to the host bridge device, which is necessary as we do a root bus sizing on this system. As a result, pci_common_swizzle() loops infinitely. This worked until 2.6.29-rc1 because the alpha-specific swizzle routine checked for bus->parent == NULL (instead of bus->self). Fixed by clearing bus->self after bus sizing is done. Signed-off-by: Ivan Kokshaysky Cc: Richard Henderson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/kernel/sys_nautilus.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c index a7f23b5ab81..99c0f46f6b9 100644 --- a/arch/alpha/kernel/sys_nautilus.c +++ b/arch/alpha/kernel/sys_nautilus.c @@ -245,6 +245,10 @@ nautilus_init_pci(void) IRONGATE0->pci_mem = pci_mem; pci_bus_assign_resources(bus); + + /* pci_common_swizzle() relies on bus->self being NULL + for the root bus, so just clear it. */ + bus->self = NULL; pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq); } -- cgit From 5f7dc5d75076fd1c1fc6bc09f2467509d20db24a Mon Sep 17 00:00:00 2001 From: Ivan Kokshaysky Date: Thu, 15 Jan 2009 13:51:19 -0800 Subject: alpha: fix RTC on marvel Unlike other alphas, marvel doesn't have real PC-style CMOS clock hardware - RTC accesses are emulated via PAL calls. Unfortunately, for unknown reason these calls work only on CPU #0. So current implementation for arbitrary CPU makes CMOS_READ/WRITE to be executed on CPU #0 via IPI. However, for obvious reason this doesn't work with standard get/set_rtc_time() functions, where a bunch of CMOS accesses is done with disabled interrupts. Solved by making the IPI calls for entire get/set_rtc_time() functions, not for individual CMOS accesses. Which is also a lot more effective performance-wise. The patch is largely based on the code from Jay Estabrook. My changes: - tweak asm-generic/rtc.h by adding a couple of #defines to avoid a massive code duplication in arch/alpha/include/asm/rtc.h; - sys_marvel.c: fix get/set_rtc_time() return values (Jay's FIXMEs). NOTE: this fixes *only* LIB_RTC drivers. Legacy (CONFIG_RTC) driver wont't work on marvel. Actually I think that we should just disable CONFIG_RTC on alpha (maybe in 2.6.30?), like most other arches - AFAIK, all modern distributions use LIB_RTC anyway. Signed-off-by: Ivan Kokshaysky Cc: Richard Henderson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/include/asm/machvec.h | 4 +++ arch/alpha/include/asm/rtc.h | 12 ++++++--- arch/alpha/kernel/core_marvel.c | 10 +------ arch/alpha/kernel/machvec_impl.h | 5 +++- arch/alpha/kernel/proto.h | 2 ++ arch/alpha/kernel/sys_jensen.c | 2 ++ arch/alpha/kernel/sys_marvel.c | 56 +++++++++++++++++++++++++++++++++++++++- arch/alpha/kernel/time.c | 10 +++++++ include/asm-generic/rtc.h | 14 +++++++--- 9 files changed, 98 insertions(+), 17 deletions(-) diff --git a/arch/alpha/include/asm/machvec.h b/arch/alpha/include/asm/machvec.h index a86c083cdf7..fea4ea75b79 100644 --- a/arch/alpha/include/asm/machvec.h +++ b/arch/alpha/include/asm/machvec.h @@ -21,6 +21,7 @@ struct pci_dev; struct pci_ops; struct pci_controller; struct _alpha_agp_info; +struct rtc_time; struct alpha_machine_vector { @@ -94,6 +95,9 @@ struct alpha_machine_vector struct _alpha_agp_info *(*agp_info)(void); + unsigned int (*rtc_get_time)(struct rtc_time *); + int (*rtc_set_time)(struct rtc_time *); + const char *vector_name; /* NUMA information */ diff --git a/arch/alpha/include/asm/rtc.h b/arch/alpha/include/asm/rtc.h index 4e854b1333e..1f7fba671ae 100644 --- a/arch/alpha/include/asm/rtc.h +++ b/arch/alpha/include/asm/rtc.h @@ -1,9 +1,15 @@ #ifndef _ALPHA_RTC_H #define _ALPHA_RTC_H -/* - * Alpha uses the default access methods for the RTC. - */ +#if defined(CONFIG_ALPHA_GENERIC) +# define get_rtc_time alpha_mv.rtc_get_time +# define set_rtc_time alpha_mv.rtc_set_time +#else +# if defined(CONFIG_ALPHA_MARVEL) && defined(CONFIG_SMP) +# define get_rtc_time marvel_get_rtc_time +# define set_rtc_time marvel_set_rtc_time +# endif +#endif #include diff --git a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c index 9cd8dca742a..e302daecbe5 100644 --- a/arch/alpha/kernel/core_marvel.c +++ b/arch/alpha/kernel/core_marvel.c @@ -658,16 +658,8 @@ __marvel_rtc_io(u8 b, unsigned long addr, int write) rtc_access.data = bcd2bin(b); rtc_access.function = 0x48 + !write; /* GET/PUT_TOY */ -#ifdef CONFIG_SMP - if (smp_processor_id() != boot_cpuid) - smp_call_function_single(boot_cpuid, - __marvel_access_rtc, - &rtc_access, 1); - else - __marvel_access_rtc(&rtc_access); -#else __marvel_access_rtc(&rtc_access); -#endif + ret = bin2bcd(rtc_access.data); break; diff --git a/arch/alpha/kernel/machvec_impl.h b/arch/alpha/kernel/machvec_impl.h index 466c9dff818..512685f7809 100644 --- a/arch/alpha/kernel/machvec_impl.h +++ b/arch/alpha/kernel/machvec_impl.h @@ -40,7 +40,10 @@ #define CAT1(x,y) x##y #define CAT(x,y) CAT1(x,y) -#define DO_DEFAULT_RTC .rtc_port = 0x70 +#define DO_DEFAULT_RTC \ + .rtc_port = 0x70, \ + .rtc_get_time = common_get_rtc_time, \ + .rtc_set_time = common_set_rtc_time #define DO_EV4_MMU \ .max_asn = EV4_MAX_ASN, \ diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h index 708d5ca8778..fe14c6747cd 100644 --- a/arch/alpha/kernel/proto.h +++ b/arch/alpha/kernel/proto.h @@ -145,6 +145,8 @@ extern void smp_percpu_timer_interrupt(struct pt_regs *); extern irqreturn_t timer_interrupt(int irq, void *dev); extern void common_init_rtc(void); extern unsigned long est_cycle_freq; +extern unsigned int common_get_rtc_time(struct rtc_time *time); +extern int common_set_rtc_time(struct rtc_time *time); /* smc37c93x.c */ extern void SMC93x_Init(void); diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c index 2c3de97de46..e2516f9a896 100644 --- a/arch/alpha/kernel/sys_jensen.c +++ b/arch/alpha/kernel/sys_jensen.c @@ -261,6 +261,8 @@ struct alpha_machine_vector jensen_mv __initmv = { .machine_check = jensen_machine_check, .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, .rtc_port = 0x170, + .rtc_get_time = common_get_rtc_time, + .rtc_set_time = common_set_rtc_time, .nr_irqs = 16, .device_interrupt = jensen_device_interrupt, diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c index 828449cd263..c5a1a2438c6 100644 --- a/arch/alpha/kernel/sys_marvel.c +++ b/arch/alpha/kernel/sys_marvel.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "proto.h" #include "err_impl.h" @@ -426,6 +427,57 @@ marvel_init_rtc(void) init_rtc_irq(); } +struct marvel_rtc_time { + struct rtc_time *time; + int retval; +}; + +#ifdef CONFIG_SMP +static void +smp_get_rtc_time(void *data) +{ + struct marvel_rtc_time *mrt = data; + mrt->retval = __get_rtc_time(mrt->time); +} + +static void +smp_set_rtc_time(void *data) +{ + struct marvel_rtc_time *mrt = data; + mrt->retval = __set_rtc_time(mrt->time); +} +#endif + +static unsigned int +marvel_get_rtc_time(struct rtc_time *time) +{ +#ifdef CONFIG_SMP + struct marvel_rtc_time mrt; + + if (smp_processor_id() != boot_cpuid) { + mrt.time = time; + smp_call_function_single(boot_cpuid, smp_get_rtc_time, &mrt, 1); + return mrt.retval; + } +#endif + return __get_rtc_time(time); +} + +static int +marvel_set_rtc_time(struct rtc_time *time) +{ +#ifdef CONFIG_SMP + struct marvel_rtc_time mrt; + + if (smp_processor_id() != boot_cpuid) { + mrt.time = time; + smp_call_function_single(boot_cpuid, smp_set_rtc_time, &mrt, 1); + return mrt.retval; + } +#endif + return __set_rtc_time(time); +} + static void marvel_smp_callin(void) { @@ -466,7 +518,9 @@ marvel_smp_callin(void) struct alpha_machine_vector marvel_ev7_mv __initmv = { .vector_name = "MARVEL/EV7", DO_EV7_MMU, - DO_DEFAULT_RTC, + .rtc_port = 0x70, + .rtc_get_time = marvel_get_rtc_time, + .rtc_set_time = marvel_set_rtc_time, DO_MARVEL_IO, .machine_check = marvel_machine_check, .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index e6a231435cb..b04e2cbf23a 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -180,6 +181,15 @@ common_init_rtc(void) init_rtc_irq(); } +unsigned int common_get_rtc_time(struct rtc_time *time) +{ + return __get_rtc_time(time); +} + +int common_set_rtc_time(struct rtc_time *time) +{ + return __set_rtc_time(time); +} /* Validate a computed cycle counter result against the known bounds for the given processor core. There's too much brokenness in the way of diff --git a/include/asm-generic/rtc.h b/include/asm-generic/rtc.h index 89061c1a67d..763e3b060f4 100644 --- a/include/asm-generic/rtc.h +++ b/include/asm-generic/rtc.h @@ -42,7 +42,7 @@ static inline unsigned char rtc_is_updating(void) return uip; } -static inline unsigned int get_rtc_time(struct rtc_time *time) +static inline unsigned int __get_rtc_time(struct rtc_time *time) { unsigned char ctrl; unsigned long flags; @@ -108,8 +108,12 @@ static inline unsigned int get_rtc_time(struct rtc_time *time) return RTC_24H; } +#ifndef get_rtc_time +#define get_rtc_time __get_rtc_time +#endif + /* Set the current date and time in the real time clock. */ -static inline int set_rtc_time(struct rtc_time *time) +static inline int __set_rtc_time(struct rtc_time *time) { unsigned long flags; unsigned char mon, day, hrs, min, sec; @@ -190,11 +194,15 @@ static inline int set_rtc_time(struct rtc_time *time) return 0; } +#ifndef set_rtc_time +#define set_rtc_time __set_rtc_time +#endif + static inline unsigned int get_rtc_ss(void) { struct rtc_time h; - get_rtc_time(&h); + __get_rtc_time(&h); return h.tm_sec; } -- cgit From 6946ce00c944131464d408c1e9b7b290d8bc3d15 Mon Sep 17 00:00:00 2001 From: Ivan Kokshaysky Date: Thu, 15 Jan 2009 13:51:20 -0800 Subject: alpha: .gitignore vmlinux.lds Signed-off-by: Ivan Kokshaysky Cc: Richard Henderson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/kernel/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 arch/alpha/kernel/.gitignore diff --git a/arch/alpha/kernel/.gitignore b/arch/alpha/kernel/.gitignore new file mode 100644 index 00000000000..c5f676c3c22 --- /dev/null +++ b/arch/alpha/kernel/.gitignore @@ -0,0 +1 @@ +vmlinux.lds -- cgit From 5da7f3d71e243ef5c464967581414d29c72bab75 Mon Sep 17 00:00:00 2001 From: Ivan Kokshaysky Date: Thu, 15 Jan 2009 13:51:20 -0800 Subject: alpha: make pte_alloc_one_kernel() inline As it's just a single call to __get_free_page(). Signed-off-by: Ivan Kokshaysky Cc: Richard Henderson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/include/asm/pgalloc.h | 7 ++++++- arch/alpha/mm/init.c | 7 ------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/arch/alpha/include/asm/pgalloc.h b/arch/alpha/include/asm/pgalloc.h index fd090155dcc..bc2a0daf2d9 100644 --- a/arch/alpha/include/asm/pgalloc.h +++ b/arch/alpha/include/asm/pgalloc.h @@ -50,7 +50,12 @@ pmd_free(struct mm_struct *mm, pmd_t *pmd) free_page((unsigned long)pmd); } -extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr); +static inline pte_t * +pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) +{ + pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); + return pte; +} static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c index 234e42b8ee7..5d7a16eab31 100644 --- a/arch/alpha/mm/init.c +++ b/arch/alpha/mm/init.c @@ -59,13 +59,6 @@ pgd_alloc(struct mm_struct *mm) return ret; } -pte_t * -pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) -{ - pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); - return pte; -} - /* * BAD_PAGE is the page that is used for page faults when linux -- cgit From 5b019e99016f3a692ba45bf68fba73a402d7c01a Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 15 Jan 2009 13:51:21 -0800 Subject: lib/idr.c: use kmem_cache_zalloc() for the idr_layer cache David points out that the idr_remove_all() function returns unused slabs to the kmem cache, but needs to zero them first or else they will be uninitialized upon next use. This causes crashes which have been observed in the firewire subsystem. He fixed this by zeroing the object before freeing it in idr_remove_all(). But we agree that simply removing the constructor and zeroing the object at allocation time is simpler than relying upon slab constructor machinery and might even be faster. This problem was introduced by "idr: make idr_remove rcu-safe" (commit cf481c20c476ad2c0febdace9ce23f5a4db19582), which was first released in 2.6.27. There are no known codesites which trigger this bug in 2.6.27 or 2.6.28. The post-2.6.28 firewire changes are the only known triggerer. There might of course be not-yet-discovered triggerers in 2.6.27 and 2.6.28, and there might be out-of-tree triggerers which are added to those kernel versions. I'll let the -stable guys decide whether they want to backport this fix. Reported-by: David Moore Cc: Stefan Richter Cc: Nadia Derbey Cc: Paul E. McKenney Cc: Manfred Spraul Cc: Kristian Hgsberg Acked-by: Pekka Enberg Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/idr.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/lib/idr.c b/lib/idr.c index 6b7cfa6508f..c11c5765cde 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -121,7 +121,7 @@ int idr_pre_get(struct idr *idp, gfp_t gfp_mask) { while (idp->id_free_cnt < IDR_FREE_MAX) { struct idr_layer *new; - new = kmem_cache_alloc(idr_layer_cache, gfp_mask); + new = kmem_cache_zalloc(idr_layer_cache, gfp_mask); if (new == NULL) return (0); move_to_free_list(idp, new); @@ -623,16 +623,10 @@ void *idr_replace(struct idr *idp, void *ptr, int id) } EXPORT_SYMBOL(idr_replace); -static void idr_cache_ctor(void *idr_layer) -{ - memset(idr_layer, 0, sizeof(struct idr_layer)); -} - void __init idr_init_cache(void) { idr_layer_cache = kmem_cache_create("idr_layer_cache", - sizeof(struct idr_layer), 0, SLAB_PANIC, - idr_cache_ctor); + sizeof(struct idr_layer), 0, SLAB_PANIC, NULL); } /** -- cgit From 9e0c79782143a816ba7d7f0f6e195091a97053f6 Mon Sep 17 00:00:00 2001 From: Eric Piel Date: Thu, 15 Jan 2009 13:51:23 -0800 Subject: lis3lv02d: merge with leds hp disk Move the second part of the HP laptop disk protection functionality (a red led) to the same driver. From a purely Linux developer's point of view, the led and the accelerometer have nothing related. However, they correspond to the same ACPI functionality, and so will always be used together, moreover as they share the same ACPI PNP alias, there is no other simple to allow to have same loaded at the same time if they are not in the same module. Also make it requires the led class to compile and update the Kconfig text. Signed-off-by: Pavel Machek Signed-off-by: Eric Piel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/hwmon/Kconfig | 14 ++++- drivers/hwmon/hp_accel.c | 43 +++++++++++++- drivers/leds/Kconfig | 7 --- drivers/leds/Makefile | 1 - drivers/leds/leds-hp-disk.c | 137 -------------------------------------------- 5 files changed, 52 insertions(+), 150 deletions(-) delete mode 100644 drivers/leds/leds-hp-disk.c diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 4b33bc82cc2..54b43bea5e4 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -861,6 +861,8 @@ config SENSORS_HDAPS config SENSORS_LIS3LV02D tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer" depends on ACPI && INPUT + select NEW_LEDS + select LEDS_CLASS default n help This driver provides support for the LIS3LV02Dx accelerometer. In @@ -872,10 +874,16 @@ config SENSORS_LIS3LV02D /sys/devices/platform/lis3lv02d. This driver also provides an absolute input class device, allowing - the laptop to act as a pinball machine-esque joystick. + the laptop to act as a pinball machine-esque joystick. On HP laptops, + if the led infrastructure is activated, support for a led indicating + disk protection will be provided as hp:red:hddprotection. - This driver can also be built as a module. If so, the module - will be called lis3lv02d. + This driver can also be built as modules. If so, the core module + will be called lis3lv02d and a specific module for HP laptops will be + called hp_accel. + + Say Y here if you have an applicable laptop and want to experience + the awesome power of lis3lv02d. config SENSORS_APPLESMC tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)" diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c index bf8d4058057..86a0f51d99d 100644 --- a/drivers/hwmon/hp_accel.c +++ b/drivers/hwmon/hp_accel.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include "lis3lv02d.h" @@ -154,10 +155,34 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = { */ }; +static acpi_status hpled_acpi_write(acpi_handle handle, int reg) +{ + unsigned long long ret; /* Not used when writing */ + union acpi_object in_obj[1]; + struct acpi_object_list args = { 1, in_obj }; + + in_obj[0].type = ACPI_TYPE_INTEGER; + in_obj[0].integer.value = reg; + + return acpi_evaluate_integer(handle, "ALED", &args, &ret); +} + +static void hpled_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + hpled_acpi_write(adev.device->handle, !!value); +} + +static struct led_classdev hpled_led = { + .name = "hp:red:hddprotection", + .default_trigger = "none", + .brightness_set = hpled_set, +}; static int lis3lv02d_add(struct acpi_device *device) { u8 val; + int ret; if (!device) return -EINVAL; @@ -183,7 +208,17 @@ static int lis3lv02d_add(struct acpi_device *device) adev.ac = lis3lv02d_axis_normal; } - return lis3lv02d_init_device(&adev); + ret = led_classdev_register(NULL, &hpled_led); + if (ret) + return ret; + + ret = lis3lv02d_init_device(&adev); + if (ret) { + led_classdev_unregister(&hpled_led); + return ret; + } + + return ret; } static int lis3lv02d_remove(struct acpi_device *device, int type) @@ -194,6 +229,8 @@ static int lis3lv02d_remove(struct acpi_device *device, int type) lis3lv02d_joystick_disable(); lis3lv02d_poweroff(device->handle); + led_classdev_unregister(&hpled_led); + return lis3lv02d_remove_fs(); } @@ -203,6 +240,7 @@ static int lis3lv02d_suspend(struct acpi_device *device, pm_message_t state) { /* make sure the device is off when we suspend */ lis3lv02d_poweroff(device->handle); + led_classdev_suspend(&hpled_led); return 0; } @@ -215,6 +253,7 @@ static int lis3lv02d_resume(struct acpi_device *device) else lis3lv02d_poweroff(device->handle); mutex_unlock(&adev.lock); + led_classdev_resume(&hpled_led); return 0; } #else @@ -256,7 +295,7 @@ static void __exit lis3lv02d_exit_module(void) acpi_bus_unregister_driver(&lis3lv02d_driver); } -MODULE_DESCRIPTION("Glue between LIS3LV02Dx and HP ACPI BIOS"); +MODULE_DESCRIPTION("Glue between LIS3LV02Dx and HP ACPI BIOS and support for disk protection LED."); MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek"); MODULE_LICENSE("GPL"); diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index a4a1ae21463..742713611bc 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -119,13 +119,6 @@ config LEDS_GPIO outputs. To be useful the particular board must have LEDs and they must be connected to the GPIO lines. -config LEDS_HP_DISK - tristate "LED Support for disk protection LED on HP notebooks" - depends on LEDS_CLASS && ACPI - help - This option enable support for disk protection LED, found on - newer HP notebooks. - config LEDS_CLEVO_MAIL tristate "Mail LED on Clevo notebook (EXPERIMENTAL)" depends on LEDS_CLASS && X86 && SERIO_I8042 && DMI && EXPERIMENTAL diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index bc247cb02e8..9d76f0f160a 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -23,7 +23,6 @@ obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o obj-$(CONFIG_LEDS_FSG) += leds-fsg.o obj-$(CONFIG_LEDS_PCA955X) += leds-pca955x.o obj-$(CONFIG_LEDS_DA903X) += leds-da903x.o -obj-$(CONFIG_LEDS_HP_DISK) += leds-hp-disk.o obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o # LED Triggers diff --git a/drivers/leds/leds-hp-disk.c b/drivers/leds/leds-hp-disk.c deleted file mode 100644 index d786adc8c5e..00000000000 --- a/drivers/leds/leds-hp-disk.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * leds-hp-disk.c - driver for HP "hard disk protection" LED - * - * Copyright (C) 2008 Pavel Machek - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRIVER_NAME "leds-hp-disk" -#define ACPI_MDPS_CLASS "led" - -/* For automatic insertion of the module */ -static struct acpi_device_id hpled_device_ids[] = { - {"HPQ0004", 0}, /* HP Mobile Data Protection System PNP */ - {"", 0}, -}; -MODULE_DEVICE_TABLE(acpi, hpled_device_ids); - -struct acpi_hpled { - struct acpi_device *device; /* The ACPI device */ -}; - -static struct acpi_hpled adev; - -static acpi_status hpled_acpi_write(acpi_handle handle, int reg) -{ - unsigned long long ret; /* Not used when writing */ - union acpi_object in_obj[1]; - struct acpi_object_list args = { 1, in_obj }; - - in_obj[0].type = ACPI_TYPE_INTEGER; - in_obj[0].integer.value = reg; - - return acpi_evaluate_integer(handle, "ALED", &args, &ret); -} - -static void hpled_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - hpled_acpi_write(adev.device->handle, !!value); -} - -static struct led_classdev hpled_led = { - .name = "hp:red:hddprotection", - .default_trigger = "heartbeat", - .brightness_set = hpled_set, - .flags = LED_CORE_SUSPENDRESUME, -}; - -static int hpled_add(struct acpi_device *device) -{ - int ret; - - if (!device) - return -EINVAL; - - adev.device = device; - strcpy(acpi_device_name(device), DRIVER_NAME); - strcpy(acpi_device_class(device), ACPI_MDPS_CLASS); - device->driver_data = &adev; - - ret = led_classdev_register(NULL, &hpled_led); - return ret; -} - -static int hpled_remove(struct acpi_device *device, int type) -{ - if (!device) - return -EINVAL; - - led_classdev_unregister(&hpled_led); - return 0; -} - - - -static struct acpi_driver leds_hp_driver = { - .name = DRIVER_NAME, - .class = ACPI_MDPS_CLASS, - .ids = hpled_device_ids, - .ops = { - .add = hpled_add, - .remove = hpled_remove, - } -}; - -static int __init hpled_init_module(void) -{ - int ret; - - if (acpi_disabled) - return -ENODEV; - - ret = acpi_bus_register_driver(&leds_hp_driver); - if (ret < 0) - return ret; - - printk(KERN_INFO DRIVER_NAME " driver loaded.\n"); - - return 0; -} - -static void __exit hpled_exit_module(void) -{ - acpi_bus_unregister_driver(&leds_hp_driver); -} - -MODULE_DESCRIPTION("Driver for HP disk protection LED"); -MODULE_AUTHOR("Pavel Machek "); -MODULE_LICENSE("GPL"); - -module_init(hpled_init_module); -module_exit(hpled_exit_module); -- cgit From 219beb291ba9275dd676578724103abed4cfbfe3 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Thu, 15 Jan 2009 13:51:24 -0800 Subject: lis3: fix documentation to fit into 80 columns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix lis3 documentation to fit into 80 columns. Signed-off-by: Pavel Machek Cc: Éric Piel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/hwmon/lis3lv02d | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/Documentation/hwmon/lis3lv02d b/Documentation/hwmon/lis3lv02d index 65dfb0c0fd6..0fcfc4a7ccd 100644 --- a/Documentation/hwmon/lis3lv02d +++ b/Documentation/hwmon/lis3lv02d @@ -13,18 +13,21 @@ Author: Description ----------- -This driver provides support for the accelerometer found in various HP laptops -sporting the feature officially called "HP Mobile Data Protection System 3D" or -"HP 3D DriveGuard". It detect automatically laptops with this sensor. Known models -(for now the HP 2133, nc6420, nc2510, nc8510, nc84x0, nw9440 and nx9420) will -have their axis automatically oriented on standard way (eg: you can directly -play neverball). The accelerometer data is readable via +This driver provides support for the accelerometer found in various HP +laptops sporting the feature officially called "HP Mobile Data +Protection System 3D" or "HP 3D DriveGuard". It detect automatically +laptops with this sensor. Known models (for now the HP 2133, nc6420, +nc2510, nc8510, nc84x0, nw9440 and nx9420) will have their axis +automatically oriented on standard way (eg: you can directly play +neverball). The accelerometer data is readable via /sys/devices/platform/lis3lv02d. Sysfs attributes under /sys/devices/platform/lis3lv02d/: position - 3D position that the accelerometer reports. Format: "(x,y,z)" -calibrate - read: values (x, y, z) that are used as the base for input class device operation. - write: forces the base to be recalibrated with the current position. +calibrate - read: values (x, y, z) that are used as the base for input + class device operation. + write: forces the base to be recalibrated with the current + position. rate - reports the sampling rate of the accelerometer device in HZ This driver also provides an absolute input class device, allowing @@ -39,11 +42,12 @@ the accelerometer are converted into a "standard" organisation of the axes * When the laptop is horizontal the position reported is about 0 for X and Y and a positive value for Z * If the left side is elevated, X increases (becomes positive) - * If the front side (where the touchpad is) is elevated, Y decreases (becomes negative) + * If the front side (where the touchpad is) is elevated, Y decreases + (becomes negative) * If the laptop is put upside-down, Z becomes negative -If your laptop model is not recognized (cf "dmesg"), you can send an email to the -authors to add it to the database. When reporting a new laptop, please include -the output of "dmidecode" plus the value of /sys/devices/platform/lis3lv02d/position -in these four cases. +If your laptop model is not recognized (cf "dmesg"), you can send an +email to the authors to add it to the database. When reporting a new +laptop, please include the output of "dmidecode" plus the value of +/sys/devices/platform/lis3lv02d/position in these four cases. -- cgit From 9e1c9d865543593ee92ec3a5075f064dec981a96 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Thu, 15 Jan 2009 13:51:24 -0800 Subject: hp_accel: do not call ACPI from invalid context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The LED on HP notebooks is connected through ACPI. That unfortunately means that it needs to be delayed by using schedule_work() to avoid calling the ACPI interpreter from an invalid context. [akpm@linux-foundation.org: use flush_work() rather than sort-of reimplementing it] Signed-off-by: Pavel Machek Cc: Éric Piel Cc: Len Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/hwmon/hp_accel.c | 68 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 19 deletions(-) diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c index 86a0f51d99d..03705240000 100644 --- a/drivers/hwmon/hp_accel.c +++ b/drivers/hwmon/hp_accel.c @@ -3,7 +3,7 @@ * * Copyright (C) 2007-2008 Yan Burman * Copyright (C) 2008 Eric Piel - * Copyright (C) 2008 Pavel Machek + * Copyright (C) 2008-2009 Pavel Machek * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -44,6 +44,36 @@ #define DRIVER_NAME "lis3lv02d" #define ACPI_MDPS_CLASS "accelerometer" +/* Delayed LEDs infrastructure ------------------------------------ */ + +/* Special LED class that can defer work */ +struct delayed_led_classdev { + struct led_classdev led_classdev; + struct work_struct work; + enum led_brightness new_brightness; + + unsigned int led; /* For driver */ + void (*set_brightness)(struct delayed_led_classdev *data, enum led_brightness value); +}; + +static inline void delayed_set_status_worker(struct work_struct *work) +{ + struct delayed_led_classdev *data = + container_of(work, struct delayed_led_classdev, work); + + data->set_brightness(data, data->new_brightness); +} + +static inline void delayed_sysfs_set(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct delayed_led_classdev *data = container_of(led_cdev, + struct delayed_led_classdev, led_classdev); + data->new_brightness = brightness; + schedule_work(&data->work); +} + +/* HP-specific accelerometer driver ------------------------------------ */ /* For automatic insertion of the module */ static struct acpi_device_id lis3lv02d_device_ids[] = { @@ -155,28 +185,27 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = { */ }; -static acpi_status hpled_acpi_write(acpi_handle handle, int reg) +static void hpled_set(struct delayed_led_classdev *led_cdev, enum led_brightness value) { + acpi_handle handle = adev.device->handle; unsigned long long ret; /* Not used when writing */ union acpi_object in_obj[1]; struct acpi_object_list args = { 1, in_obj }; in_obj[0].type = ACPI_TYPE_INTEGER; - in_obj[0].integer.value = reg; + in_obj[0].integer.value = !!value; - return acpi_evaluate_integer(handle, "ALED", &args, &ret); -} - -static void hpled_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - hpled_acpi_write(adev.device->handle, !!value); + acpi_evaluate_integer(handle, "ALED", &args, &ret); } -static struct led_classdev hpled_led = { - .name = "hp:red:hddprotection", - .default_trigger = "none", - .brightness_set = hpled_set, +static struct delayed_led_classdev hpled_led = { + .led_classdev = { + .name = "hp::hddprotect", + .default_trigger = "none", + .brightness_set = delayed_sysfs_set, + .flags = LED_CORE_SUSPENDRESUME, + }, + .set_brightness = hpled_set, }; static int lis3lv02d_add(struct acpi_device *device) @@ -208,13 +237,15 @@ static int lis3lv02d_add(struct acpi_device *device) adev.ac = lis3lv02d_axis_normal; } - ret = led_classdev_register(NULL, &hpled_led); + INIT_WORK(&hpled_led.work, delayed_set_status_worker); + ret = led_classdev_register(NULL, &hpled_led.led_classdev); if (ret) return ret; ret = lis3lv02d_init_device(&adev); if (ret) { - led_classdev_unregister(&hpled_led); + flush_work(&hpled_led.work); + led_classdev_unregister(&hpled_led.led_classdev); return ret; } @@ -229,7 +260,8 @@ static int lis3lv02d_remove(struct acpi_device *device, int type) lis3lv02d_joystick_disable(); lis3lv02d_poweroff(device->handle); - led_classdev_unregister(&hpled_led); + flush_work(&hpled_led.work); + led_classdev_unregister(&hpled_led.led_classdev); return lis3lv02d_remove_fs(); } @@ -240,7 +272,6 @@ static int lis3lv02d_suspend(struct acpi_device *device, pm_message_t state) { /* make sure the device is off when we suspend */ lis3lv02d_poweroff(device->handle); - led_classdev_suspend(&hpled_led); return 0; } @@ -253,7 +284,6 @@ static int lis3lv02d_resume(struct acpi_device *device) else lis3lv02d_poweroff(device->handle); mutex_unlock(&adev.lock); - led_classdev_resume(&hpled_led); return 0; } #else -- cgit From 0eb253e223c88b982461e59154fcad1b82597592 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Thu, 15 Jan 2009 13:51:25 -0800 Subject: memcg: fix section mismatch At system boot when creating the top cgroup, mem_cgroup_create() calls enable_swap_cgroup() which is marked as __init, so mark mem_cgroup_create() as __ref to avoid false section mismatch warning. Reported-by: Rakib Mullick Signed-off-by: Li Zefan Acked-by; KAMEZAWA Hiroyuki Cc: Balbir Singh Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memcontrol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index fb62b4335fa..f0dc076adf0 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -2202,7 +2202,7 @@ static void __init enable_swap_cgroup(void) } #endif -static struct cgroup_subsys_state * +static struct cgroup_subsys_state * __ref mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont) { struct mem_cgroup *mem, *parent; -- cgit From 068b38c1fa7a9210608f27ac521897ccc5f9b726 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Thu, 15 Jan 2009 13:51:26 -0800 Subject: memcg: fix a race when setting memory.swappiness (suppose: memcg->use_hierarchy == 0 and memcg->swappiness == 60) echo 10 > /memcg/0/swappiness | mem_cgroup_swappiness_write() | ... | echo 1 > /memcg/0/use_hierarchy | mkdir /mnt/0/1 | sub_memcg->swappiness = 60; memcg->swappiness = 10; | In the above scenario, we end up having 2 different swappiness values in a single hierarchy. We should hold cgroup_lock() when cheking cgrp->children list. Signed-off-by: Li Zefan Acked-by: KAMEZAWA Hiroyuki Cc: Balbir Singh Cc: Paul Menage Cc: Daisuke Nishimura Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memcontrol.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index f0dc076adf0..4d0ea3ceba6 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1992,6 +1992,7 @@ static int mem_cgroup_swappiness_write(struct cgroup *cgrp, struct cftype *cft, { struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp); struct mem_cgroup *parent; + if (val > 100) return -EINVAL; @@ -1999,15 +2000,22 @@ static int mem_cgroup_swappiness_write(struct cgroup *cgrp, struct cftype *cft, return -EINVAL; parent = mem_cgroup_from_cont(cgrp->parent); + + cgroup_lock(); + /* If under hierarchy, only empty-root can set this value */ if ((parent->use_hierarchy) || - (memcg->use_hierarchy && !list_empty(&cgrp->children))) + (memcg->use_hierarchy && !list_empty(&cgrp->children))) { + cgroup_unlock(); return -EINVAL; + } spin_lock(&memcg->reclaim_param_lock); memcg->swappiness = val; spin_unlock(&memcg->reclaim_param_lock); + cgroup_unlock(); + return 0; } -- cgit From 00bfddaf7f68a6551319b536f052040c370756b0 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Thu, 15 Jan 2009 13:51:26 -0800 Subject: include of is preferred over Impact: fix 15 make headers_check warnings: include of is preferred over Signed-off-by: Jaswinder Singh Rajput Cc: Ingo Molnar Cc: Sam Ravnborg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/agpgart.h | 1 - include/linux/atm_idt77105.h | 2 +- include/linux/capi.h | 2 +- include/linux/connector.h | 2 +- include/linux/cyclades.h | 2 -- include/linux/fb.h | 2 +- include/linux/if_pppol2tp.h | 2 +- include/linux/if_pppox.h | 2 +- include/linux/input.h | 2 +- include/linux/joystick.h | 2 +- include/linux/kvm.h | 2 +- include/linux/loop.h | 2 +- include/linux/matroxfb.h | 2 +- include/linux/phantom.h | 2 +- include/linux/radeonfb.h | 2 +- 15 files changed, 13 insertions(+), 16 deletions(-) diff --git a/include/linux/agpgart.h b/include/linux/agpgart.h index c8fdb6e658e..110c600c885 100644 --- a/include/linux/agpgart.h +++ b/include/linux/agpgart.h @@ -52,7 +52,6 @@ #ifndef __KERNEL__ #include -#include struct agp_version { __u16 major; diff --git a/include/linux/atm_idt77105.h b/include/linux/atm_idt77105.h index 05621cf2070..8b724000aa5 100644 --- a/include/linux/atm_idt77105.h +++ b/include/linux/atm_idt77105.h @@ -7,7 +7,7 @@ #ifndef LINUX_ATM_IDT77105_H #define LINUX_ATM_IDT77105_H -#include +#include #include #include diff --git a/include/linux/capi.h b/include/linux/capi.h index fdebaaa9f66..65100d6cb89 100644 --- a/include/linux/capi.h +++ b/include/linux/capi.h @@ -12,7 +12,7 @@ #ifndef __LINUX_CAPI_H__ #define __LINUX_CAPI_H__ -#include +#include #include #ifndef __KERNEL__ #include diff --git a/include/linux/connector.h b/include/linux/connector.h index 5c7f9468f75..34f2789d9b9 100644 --- a/include/linux/connector.h +++ b/include/linux/connector.h @@ -22,7 +22,7 @@ #ifndef __CONNECTOR_H #define __CONNECTOR_H -#include +#include #define CN_IDX_CONNECTOR 0xffffffff #define CN_VAL_CONNECTOR 0xffffffff diff --git a/include/linux/cyclades.h b/include/linux/cyclades.h index 2d3d1e04ba9..d06fbf28634 100644 --- a/include/linux/cyclades.h +++ b/include/linux/cyclades.h @@ -150,8 +150,6 @@ struct CYZ_BOOT_CTRL { * architectures and compilers. */ -#include - typedef __u64 ucdouble; /* 64 bits, unsigned */ typedef __u32 uclong; /* 32 bits, unsigned */ typedef __u16 ucshort; /* 16 bits, unsigned */ diff --git a/include/linux/fb.h b/include/linux/fb.h index 1ee63df5be9..818fe21257e 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -1,7 +1,7 @@ #ifndef _LINUX_FB_H #define _LINUX_FB_H -#include +#include #include struct dentry; diff --git a/include/linux/if_pppol2tp.h b/include/linux/if_pppol2tp.h index a7d6a2234b3..c7a66882b6d 100644 --- a/include/linux/if_pppol2tp.h +++ b/include/linux/if_pppol2tp.h @@ -15,7 +15,7 @@ #ifndef __LINUX_IF_PPPOL2TP_H #define __LINUX_IF_PPPOL2TP_H -#include +#include #ifdef __KERNEL__ #include diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h index 6fb7f178857..30c88b2245f 100644 --- a/include/linux/if_pppox.h +++ b/include/linux/if_pppox.h @@ -17,7 +17,7 @@ #define __LINUX_IF_PPPOX_H -#include +#include #include #ifdef __KERNEL__ diff --git a/include/linux/input.h b/include/linux/input.h index 9a6355f74db..1249a0c20a3 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -16,7 +16,7 @@ #include #include #include -#include +#include #endif /* diff --git a/include/linux/joystick.h b/include/linux/joystick.h index b5e051295a6..9e20c29c1e1 100644 --- a/include/linux/joystick.h +++ b/include/linux/joystick.h @@ -27,7 +27,7 @@ * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic */ -#include +#include #include /* diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 35525ac6333..5715f190760 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -7,7 +7,7 @@ * Note: you must update KVM_API_VERSION if you change this interface. */ -#include +#include #include #include #include diff --git a/include/linux/loop.h b/include/linux/loop.h index 46169a7b559..6ffd6db5bb0 100644 --- a/include/linux/loop.h +++ b/include/linux/loop.h @@ -80,7 +80,7 @@ enum { }; #include /* for __kernel_old_dev_t */ -#include /* for __u64 */ +#include /* for __u64 */ /* Backwards compatibility version */ struct loop_info { diff --git a/include/linux/matroxfb.h b/include/linux/matroxfb.h index ae5b0949306..404f678e734 100644 --- a/include/linux/matroxfb.h +++ b/include/linux/matroxfb.h @@ -2,7 +2,7 @@ #define __LINUX_MATROXFB_H__ #include -#include +#include #include struct matroxioc_output_mode { diff --git a/include/linux/phantom.h b/include/linux/phantom.h index 02268c54c25..94dd6645c60 100644 --- a/include/linux/phantom.h +++ b/include/linux/phantom.h @@ -10,7 +10,7 @@ #ifndef __PHANTOM_H #define __PHANTOM_H -#include +#include /* PHN_(G/S)ET_REG param */ struct phm_reg { diff --git a/include/linux/radeonfb.h b/include/linux/radeonfb.h index 5bd8975ed78..8c4bbdecc44 100644 --- a/include/linux/radeonfb.h +++ b/include/linux/radeonfb.h @@ -2,7 +2,7 @@ #define __LINUX_RADEONFB_H__ #include -#include +#include #define ATY_RADEON_LCD_ON 0x00000001 #define ATY_RADEON_CRT_ON 0x00000002 -- cgit From 634a84f8d5b74da497688d3346f6809c28239eda Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 15 Jan 2009 13:51:28 -0800 Subject: drivers/usb/core/hub.c: fix CONFIG_USB_OTG=y build Carry out the PM-routine interface change in the USB OTG pathway. This was omitted from the earlier interface-change patch by mistake. Signed-off-by: Alan Stern Cc: Greg KH Cc: Russell King Cc: Felipe Balbi Cc: Tony Lindgren Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/usb/core/hub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index d5d0e40b1e2..94d5ee263c2 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1554,7 +1554,7 @@ static int usb_configure_device_otg(struct usb_device *udev) * (Includes HNP test device.) */ if (udev->bus->b_hnp_enable || udev->bus->is_b_host) { - err = usb_port_suspend(udev); + err = usb_port_suspend(udev, PMSG_SUSPEND); if (err < 0) dev_dbg(&udev->dev, "HNP fail, %d\n", err); } -- cgit From 6b7021ef7e1a703c7092daeceda063951b22b4f6 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 15 Jan 2009 13:51:29 -0800 Subject: ext2: also update the inode on disk when dir is IS_DIRSYNC We used to just write changed page for IS_DIRSYNC inodes. But we also have to update the directory inode itself just for the case that we've allocated a new block and changed i_size. [akpm@linux-foundation.org: still sync the data page] Signed-off-by: Jan Kara Tested-by: Pavel Machek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ext2/dir.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index 9a0fc400f91..2999d72153b 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c @@ -95,10 +95,13 @@ static int ext2_commit_chunk(struct page *page, loff_t pos, unsigned len) mark_inode_dirty(dir); } - if (IS_DIRSYNC(dir)) + if (IS_DIRSYNC(dir)) { err = write_one_page(page, 1); - else + if (!err) + err = ext2_sync_inode(dir); + } else { unlock_page(page); + } return err; } -- cgit From 6364853dabe78dda7ffdfb8803c1e56c0fff2e43 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Thu, 15 Jan 2009 13:51:29 -0800 Subject: 9p: disallow RDMA if RDMA CM isn't available If INET=y and INFINIBAND=y, but IPV6=m then INFINIBAND_ADDR_TRANS is set to n and the RDMA CM functions rdma_connect() et al are not built. However, the current config dependencies allow NET_9P_RDMA to be selected in this, which leads to a build failure. Fix this by adding a dependency on INFINIBAND_ADDR_TRANS to disallow NET_9P_RDMA in this case. Reported-by: Randy Dunlap Signed-off-by: Roland Dreier Acked-by: Randy Dunlap Tested-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- net/9p/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/9p/Kconfig b/net/9p/Kconfig index 0663f99e977..7ed75c7bd5d 100644 --- a/net/9p/Kconfig +++ b/net/9p/Kconfig @@ -23,7 +23,7 @@ config NET_9P_VIRTIO guest partitions and a host partition. config NET_9P_RDMA - depends on INET && INFINIBAND && EXPERIMENTAL + depends on INET && INFINIBAND && INFINIBAND_ADDR_TRANS && EXPERIMENTAL tristate "9P RDMA Transport (Experimental)" help This builds support for an RDMA transport. -- cgit From d3b924d960a808105180d229b4667061123cc4ef Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 15 Jan 2009 20:43:56 -0800 Subject: mlx4_core: Fix min() warning Fix drivers/net/mlx4/profile.c: In function `mlx4_make_profile': drivers/net/mlx4/profile.c:110: warning: comparison of distinct pointer types lacks a cast This happened because num_possible_cpus() was secretly changed by commit ae7a47e7 ("cpumask: make cpumask.h eat its own dogfood.") from returning "int" to (now) returning "unsigned int". I think that was a good change, so we should just swallow the fallout. Cc: "David S. Miller" Cc: Roland Dreier Cc: Yevgeny Petrilin Cc: Jack Morgenstein Cc: Vladimir Sokolovsky Cc: Michael S. Tsirkin Signed-off-by: Andrew Morton Signed-off-by: Roland Dreier --- drivers/net/mlx4/profile.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/mlx4/profile.c b/drivers/net/mlx4/profile.c index 919fb9eb1b6..cebdf3243ca 100644 --- a/drivers/net/mlx4/profile.c +++ b/drivers/net/mlx4/profile.c @@ -107,9 +107,9 @@ u64 mlx4_make_profile(struct mlx4_dev *dev, profile[MLX4_RES_AUXC].num = request->num_qp; profile[MLX4_RES_SRQ].num = request->num_srq; profile[MLX4_RES_CQ].num = request->num_cq; - profile[MLX4_RES_EQ].num = min(dev_cap->max_eqs, - dev_cap->reserved_eqs + - num_possible_cpus() + 1); + profile[MLX4_RES_EQ].num = min_t(unsigned, dev_cap->max_eqs, + dev_cap->reserved_eqs + + num_possible_cpus() + 1); profile[MLX4_RES_DMPT].num = request->num_mpt; profile[MLX4_RES_CMPT].num = MLX4_NUM_CMPTS; profile[MLX4_RES_MTT].num = request->num_mtt; -- cgit From 775a42ecf8b8a86b55173da27e6cc874af5b944d Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 6 Jan 2009 14:59:00 +0000 Subject: powerpc: Cleanup from l64 to ll64 change drivers/scsi This is a powerpc specific driver. Signed-off-by: Stephen Rothwell Signed-off-by: Benjamin Herrenschmidt --- drivers/scsi/ibmvscsi/ibmvfc.c | 14 +++++++------- drivers/scsi/ibmvscsi/ibmvfc.h | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index ee0739b217b..91ef669d98f 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -933,7 +933,7 @@ static void ibmvfc_get_host_speed(struct Scsi_Host *shost) fc_host_speed(shost) = FC_PORTSPEED_16GBIT; break; default: - ibmvfc_log(vhost, 3, "Unknown port speed: %ld Gbit\n", + ibmvfc_log(vhost, 3, "Unknown port speed: %lld Gbit\n", vhost->login_buf->resp.link_speed / 100); fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; break; @@ -2149,8 +2149,8 @@ static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq, { const char *desc = ibmvfc_get_ae_desc(crq->event); - ibmvfc_log(vhost, 3, "%s event received. scsi_id: %lx, wwpn: %lx," - " node_name: %lx\n", desc, crq->scsi_id, crq->wwpn, crq->node_name); + ibmvfc_log(vhost, 3, "%s event received. scsi_id: %llx, wwpn: %llx," + " node_name: %llx\n", desc, crq->scsi_id, crq->wwpn, crq->node_name); switch (crq->event) { case IBMVFC_AE_LINK_UP: @@ -2184,7 +2184,7 @@ static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq, ibmvfc_link_down(vhost, IBMVFC_HALTED); break; default: - dev_err(vhost->dev, "Unknown async event received: %ld\n", crq->event); + dev_err(vhost->dev, "Unknown async event received: %lld\n", crq->event); break; }; } @@ -2261,13 +2261,13 @@ static void ibmvfc_handle_crq(struct ibmvfc_crq *crq, struct ibmvfc_host *vhost) * actually sent */ if (unlikely(!ibmvfc_valid_event(&vhost->pool, evt))) { - dev_err(vhost->dev, "Returned correlation_token 0x%08lx is invalid!\n", + dev_err(vhost->dev, "Returned correlation_token 0x%08llx is invalid!\n", crq->ioba); return; } if (unlikely(atomic_read(&evt->free))) { - dev_err(vhost->dev, "Received duplicate correlation_token 0x%08lx!\n", + dev_err(vhost->dev, "Received duplicate correlation_token 0x%08llx!\n", crq->ioba); return; } @@ -3259,7 +3259,7 @@ static int ibmvfc_alloc_target(struct ibmvfc_host *vhost, u64 scsi_id) tgt = mempool_alloc(vhost->tgt_pool, GFP_KERNEL); if (!tgt) { - dev_err(vhost->dev, "Target allocation failure for scsi id %08lx\n", + dev_err(vhost->dev, "Target allocation failure for scsi id %08llx\n", scsi_id); return -ENOMEM; } diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h index babdf3db59d..87dafd0f8d4 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.h +++ b/drivers/scsi/ibmvscsi/ibmvfc.h @@ -691,13 +691,13 @@ struct ibmvfc_host { #define DBG_CMD(CMD) do { if (ibmvfc_debug) CMD; } while (0) #define tgt_dbg(t, fmt, ...) \ - DBG_CMD(dev_info((t)->vhost->dev, "%lX: " fmt, (t)->scsi_id, ##__VA_ARGS__)) + DBG_CMD(dev_info((t)->vhost->dev, "%llX: " fmt, (t)->scsi_id, ##__VA_ARGS__)) #define tgt_info(t, fmt, ...) \ - dev_info((t)->vhost->dev, "%lX: " fmt, (t)->scsi_id, ##__VA_ARGS__) + dev_info((t)->vhost->dev, "%llX: " fmt, (t)->scsi_id, ##__VA_ARGS__) #define tgt_err(t, fmt, ...) \ - dev_err((t)->vhost->dev, "%lX: " fmt, (t)->scsi_id, ##__VA_ARGS__) + dev_err((t)->vhost->dev, "%llX: " fmt, (t)->scsi_id, ##__VA_ARGS__) #define ibmvfc_dbg(vhost, ...) \ DBG_CMD(dev_info((vhost)->dev, ##__VA_ARGS__)) -- cgit From c52fe6b620e9c7a52b296ec478bd24b91b4e7634 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 13 Jan 2009 19:54:50 +0000 Subject: powerpc/ps3: set_dabr() takes an unsigned long Also silences this warning: arch/powerpc/platforms/ps3/setup.c:275: warning: initialization from incompatible pointer type Signed-off-by: Stephen Rothwell Acked-by: Geoff Levand Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/ps3/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c index 35f3e85cf60..3331ccbb8d3 100644 --- a/arch/powerpc/platforms/ps3/setup.c +++ b/arch/powerpc/platforms/ps3/setup.c @@ -186,7 +186,7 @@ early_param("ps3flash", early_parse_ps3flash); #define prealloc_ps3flash_bounce_buffer() do { } while (0) #endif -static int ps3_set_dabr(u64 dabr) +static int ps3_set_dabr(unsigned long dabr) { enum {DABR_USER = 1, DABR_KERNEL = 2,}; -- cgit From 494fd07a88ea561e1bea73516d7e92c4c2d1f223 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 13 Jan 2009 19:58:10 +0000 Subject: powerpc/ps3: Use dma_addr_t down through the stack Push the dma_addr_t type usage all the way down to where the actual values are manipulated. Now that u64 is "unsigned long long", this removes warnings like: arch/powerpc/platforms/ps3/system-bus.c:532: warning: passing argument 4 of 'ps3_dma_map' from incompatible pointer type arch/powerpc/platforms/ps3/system-bus.c:649: warning: passing argument 4 of 'ps3_dma_map' from incompatible pointer type Signed-off-by: Stephen Rothwell Acked-by: Geoff Levand Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/ps3.h | 8 ++++---- arch/powerpc/platforms/ps3/mm.c | 32 +++++++++++++++++--------------- arch/powerpc/platforms/ps3/system-bus.c | 4 ++-- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h index eead5c67197..67f1812698d 100644 --- a/arch/powerpc/include/asm/ps3.h +++ b/arch/powerpc/include/asm/ps3.h @@ -103,10 +103,10 @@ struct ps3_dma_region_ops { int (*map)(struct ps3_dma_region *, unsigned long virt_addr, unsigned long len, - unsigned long *bus_addr, + dma_addr_t *bus_addr, u64 iopte_pp); int (*unmap)(struct ps3_dma_region *, - unsigned long bus_addr, + dma_addr_t bus_addr, unsigned long len); }; /** @@ -124,9 +124,9 @@ int ps3_dma_region_init(struct ps3_system_bus_device *dev, int ps3_dma_region_create(struct ps3_dma_region *r); int ps3_dma_region_free(struct ps3_dma_region *r); int ps3_dma_map(struct ps3_dma_region *r, unsigned long virt_addr, - unsigned long len, unsigned long *bus_addr, + unsigned long len, dma_addr_t *bus_addr, u64 iopte_pp); -int ps3_dma_unmap(struct ps3_dma_region *r, unsigned long bus_addr, +int ps3_dma_unmap(struct ps3_dma_region *r, dma_addr_t bus_addr, unsigned long len); /* mmio routines */ diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c index a4d49dd9e8a..4761e2dcf3e 100644 --- a/arch/powerpc/platforms/ps3/mm.c +++ b/arch/powerpc/platforms/ps3/mm.c @@ -777,7 +777,7 @@ static int dma_ioc0_region_free(struct ps3_dma_region *r) */ static int dma_sb_map_area(struct ps3_dma_region *r, unsigned long virt_addr, - unsigned long len, unsigned long *bus_addr, + unsigned long len, dma_addr_t *bus_addr, u64 iopte_flag) { int result; @@ -800,7 +800,7 @@ static int dma_sb_map_area(struct ps3_dma_region *r, unsigned long virt_addr, DBG("%s:%d lpar_addr %lxh\n", __func__, __LINE__, lpar_addr); DBG("%s:%d len %lxh\n", __func__, __LINE__, len); - DBG("%s:%d bus_addr %lxh (%lxh)\n", __func__, __LINE__, + DBG("%s:%d bus_addr %llxh (%lxh)\n", __func__, __LINE__, *bus_addr, len); } @@ -832,7 +832,7 @@ static int dma_sb_map_area(struct ps3_dma_region *r, unsigned long virt_addr, } static int dma_ioc0_map_area(struct ps3_dma_region *r, unsigned long virt_addr, - unsigned long len, unsigned long *bus_addr, + unsigned long len, dma_addr_t *bus_addr, u64 iopte_flag) { int result; @@ -872,7 +872,7 @@ static int dma_ioc0_map_area(struct ps3_dma_region *r, unsigned long virt_addr, return result; } *bus_addr = c->bus_addr + phys_addr - aligned_phys; - DBG("%s: va=%#lx pa=%#lx a_pa=%#lx bus=%#lx\n", __func__, + DBG("%s: va=%#lx pa=%#lx a_pa=%#lx bus=%#llx\n", __func__, virt_addr, phys_addr, aligned_phys, *bus_addr); c->usage_count = 1; @@ -889,7 +889,7 @@ static int dma_ioc0_map_area(struct ps3_dma_region *r, unsigned long virt_addr, * This is the common dma unmap routine. */ -static int dma_sb_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr, +static int dma_sb_unmap_area(struct ps3_dma_region *r, dma_addr_t bus_addr, unsigned long len) { unsigned long flags; @@ -903,7 +903,7 @@ static int dma_sb_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr, 1 << r->page_size); unsigned long aligned_len = _ALIGN_UP(len + bus_addr - aligned_bus, 1 << r->page_size); - DBG("%s:%d: not found: bus_addr %lxh\n", + DBG("%s:%d: not found: bus_addr %llxh\n", __func__, __LINE__, bus_addr); DBG("%s:%d: not found: len %lxh\n", __func__, __LINE__, len); @@ -926,12 +926,12 @@ static int dma_sb_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr, } static int dma_ioc0_unmap_area(struct ps3_dma_region *r, - unsigned long bus_addr, unsigned long len) + dma_addr_t bus_addr, unsigned long len) { unsigned long flags; struct dma_chunk *c; - DBG("%s: start a=%#lx l=%#lx\n", __func__, bus_addr, len); + DBG("%s: start a=%#llx l=%#lx\n", __func__, bus_addr, len); spin_lock_irqsave(&r->chunk_list.lock, flags); c = dma_find_chunk(r, bus_addr, len); @@ -941,7 +941,7 @@ static int dma_ioc0_unmap_area(struct ps3_dma_region *r, unsigned long aligned_len = _ALIGN_UP(len + bus_addr - aligned_bus, 1 << r->page_size); - DBG("%s:%d: not found: bus_addr %lxh\n", + DBG("%s:%d: not found: bus_addr %llxh\n", __func__, __LINE__, bus_addr); DBG("%s:%d: not found: len %lxh\n", __func__, __LINE__, len); @@ -975,7 +975,8 @@ static int dma_ioc0_unmap_area(struct ps3_dma_region *r, static int dma_sb_region_create_linear(struct ps3_dma_region *r) { int result; - unsigned long virt_addr, len, tmp; + unsigned long virt_addr, len; + dma_addr_t tmp; if (r->len > 16*1024*1024) { /* FIXME: need proper fix */ /* force 16M dma pages for linear mapping */ @@ -1027,7 +1028,8 @@ static int dma_sb_region_create_linear(struct ps3_dma_region *r) static int dma_sb_region_free_linear(struct ps3_dma_region *r) { int result; - unsigned long bus_addr, len, lpar_addr; + dma_addr_t bus_addr; + unsigned long len, lpar_addr; if (r->offset < map.rm.size) { /* Unmap (part of) 1st RAM chunk */ @@ -1072,7 +1074,7 @@ static int dma_sb_region_free_linear(struct ps3_dma_region *r) */ static int dma_sb_map_area_linear(struct ps3_dma_region *r, - unsigned long virt_addr, unsigned long len, unsigned long *bus_addr, + unsigned long virt_addr, unsigned long len, dma_addr_t *bus_addr, u64 iopte_flag) { unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr) @@ -1091,7 +1093,7 @@ static int dma_sb_map_area_linear(struct ps3_dma_region *r, */ static int dma_sb_unmap_area_linear(struct ps3_dma_region *r, - unsigned long bus_addr, unsigned long len) + dma_addr_t bus_addr, unsigned long len) { return 0; }; @@ -1169,13 +1171,13 @@ int ps3_dma_region_free(struct ps3_dma_region *r) EXPORT_SYMBOL(ps3_dma_region_free); int ps3_dma_map(struct ps3_dma_region *r, unsigned long virt_addr, - unsigned long len, unsigned long *bus_addr, + unsigned long len, dma_addr_t *bus_addr, u64 iopte_flag) { return r->region_ops->map(r, virt_addr, len, bus_addr, iopte_flag); } -int ps3_dma_unmap(struct ps3_dma_region *r, unsigned long bus_addr, +int ps3_dma_unmap(struct ps3_dma_region *r, dma_addr_t bus_addr, unsigned long len) { return r->region_ops->unmap(r, bus_addr, len); diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index ee0d2291162..70ef793e556 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c @@ -568,7 +568,7 @@ static dma_addr_t ps3_sb_map_page(struct device *_dev, struct page *page, { struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); int result; - unsigned long bus_addr; + dma_addr_t bus_addr; void *ptr = page_address(page) + offset; result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size, @@ -590,7 +590,7 @@ static dma_addr_t ps3_ioc0_map_page(struct device *_dev, struct page *page, { struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); int result; - unsigned long bus_addr; + dma_addr_t bus_addr; u64 iopte_flag; void *ptr = page_address(page) + offset; -- cgit From b17b3df161814c43c03dbc8dbf8d32741bb30ba4 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 13 Jan 2009 19:59:41 +0000 Subject: powerpc/ps3: The lv1_ routines have u64 parameters We just fix up the reference parameters as the others are dealt with by arithmetic promotion rules and don't cause warnings. This removes warnings like this: arch/powerpc/platforms/ps3/interrupt.c:327: warning: passing argument 1 of 'lv1_construct_event_receive_port' from incompatible pointer type Also, these: drivers/ps3/ps3-vuart.c:462: warning: passing argument 4 of 'ps3_vuart_raw_read' from incompatible pointer type drivers/ps3/ps3-vuart.c:592: warning: passing argument 4 of 'ps3_vuart_raw_read' from incompatible pointer type Signed-off-by: Stephen Rothwell Acked-by: Geoff Levand Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/ps3/interrupt.c | 8 +++---- arch/powerpc/platforms/ps3/mm.c | 38 ++++++++++++++++++--------------- arch/powerpc/platforms/ps3/spu.c | 12 +++++++---- arch/powerpc/platforms/ps3/system-bus.c | 4 +++- drivers/ps3/ps3-vuart.c | 24 +++++++++++---------- 5 files changed, 49 insertions(+), 37 deletions(-) diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c index e59634f7af9..b746792d84c 100644 --- a/arch/powerpc/platforms/ps3/interrupt.c +++ b/arch/powerpc/platforms/ps3/interrupt.c @@ -322,7 +322,7 @@ EXPORT_SYMBOL_GPL(ps3_irq_plug_destroy); int ps3_event_receive_port_setup(enum ps3_cpu_binding cpu, unsigned int *virq) { int result; - unsigned long outlet; + u64 outlet; result = lv1_construct_event_receive_port(&outlet); @@ -468,7 +468,7 @@ int ps3_io_irq_setup(enum ps3_cpu_binding cpu, unsigned int interrupt_id, unsigned int *virq) { int result; - unsigned long outlet; + u64 outlet; result = lv1_construct_io_irq_outlet(interrupt_id, &outlet); @@ -525,7 +525,7 @@ int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp, unsigned int *virq) { int result; - unsigned long outlet; + u64 outlet; u64 lpar_addr; BUG_ON(!is_kernel_addr((u64)virt_addr_bmp)); @@ -581,7 +581,7 @@ int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id, unsigned int class, unsigned int *virq) { int result; - unsigned long outlet; + u64 outlet; BUG_ON(class > 2); diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c index 4761e2dcf3e..5c8d066283e 100644 --- a/arch/powerpc/platforms/ps3/mm.c +++ b/arch/powerpc/platforms/ps3/mm.c @@ -79,7 +79,7 @@ enum { */ struct mem_region { - unsigned long base; + u64 base; unsigned long size; unsigned long offset; }; @@ -104,8 +104,8 @@ struct mem_region { struct map { unsigned long total; - unsigned long vas_id; - unsigned long htab_size; + u64 vas_id; + u64 htab_size; struct mem_region rm; struct mem_region r1; }; @@ -116,9 +116,9 @@ static void __maybe_unused _debug_dump_map(const struct map *m, { DBG("%s:%d: map.total = %lxh\n", func, line, m->total); DBG("%s:%d: map.rm.size = %lxh\n", func, line, m->rm.size); - DBG("%s:%d: map.vas_id = %lu\n", func, line, m->vas_id); - DBG("%s:%d: map.htab_size = %lxh\n", func, line, m->htab_size); - DBG("%s:%d: map.r1.base = %lxh\n", func, line, m->r1.base); + DBG("%s:%d: map.vas_id = %llu\n", func, line, m->vas_id); + DBG("%s:%d: map.htab_size = %llxh\n", func, line, m->htab_size); + DBG("%s:%d: map.r1.base = %llxh\n", func, line, m->r1.base); DBG("%s:%d: map.r1.offset = %lxh\n", func, line, m->r1.offset); DBG("%s:%d: map.r1.size = %lxh\n", func, line, m->r1.size); } @@ -146,11 +146,11 @@ EXPORT_SYMBOL(ps3_mm_phys_to_lpar); void __init ps3_mm_vas_create(unsigned long* htab_size) { int result; - unsigned long start_address; - unsigned long size; - unsigned long access_right; - unsigned long max_page_size; - unsigned long flags; + u64 start_address; + u64 size; + u64 access_right; + u64 max_page_size; + u64 flags; result = lv1_query_logical_partition_address_region_info(0, &start_address, &size, &access_right, &max_page_size, @@ -164,7 +164,7 @@ void __init ps3_mm_vas_create(unsigned long* htab_size) } if (max_page_size < PAGE_SHIFT_16M) { - DBG("%s:%d: bad max_page_size %lxh\n", __func__, __LINE__, + DBG("%s:%d: bad max_page_size %llxh\n", __func__, __LINE__, max_page_size); goto fail; } @@ -208,7 +208,7 @@ void ps3_mm_vas_destroy(void) { int result; - DBG("%s:%d: map.vas_id = %lu\n", __func__, __LINE__, map.vas_id); + DBG("%s:%d: map.vas_id = %llu\n", __func__, __LINE__, map.vas_id); if (map.vas_id) { result = lv1_select_virtual_address_space(0); @@ -235,7 +235,7 @@ void ps3_mm_vas_destroy(void) static int ps3_mm_region_create(struct mem_region *r, unsigned long size) { int result; - unsigned long muid; + u64 muid; r->size = _ALIGN_DOWN(size, 1 << PAGE_SHIFT_16M); @@ -277,7 +277,7 @@ static void ps3_mm_region_destroy(struct mem_region *r) { int result; - DBG("%s:%d: r->base = %lxh\n", __func__, __LINE__, r->base); + DBG("%s:%d: r->base = %llxh\n", __func__, __LINE__, r->base); if (r->base) { result = lv1_release_memory(r->base); BUG_ON(result); @@ -648,6 +648,7 @@ fail_alloc: static int dma_sb_region_create(struct ps3_dma_region *r) { int result; + u64 bus_addr; DBG(" -> %s:%d:\n", __func__, __LINE__); @@ -671,7 +672,8 @@ static int dma_sb_region_create(struct ps3_dma_region *r) result = lv1_allocate_device_dma_region(r->dev->bus_id, r->dev->dev_id, roundup_pow_of_two(r->len), r->page_size, r->region_type, - &r->bus_addr); + &bus_addr); + r->bus_addr = bus_addr; if (result) { DBG("%s:%d: lv1_allocate_device_dma_region failed: %s\n", @@ -685,6 +687,7 @@ static int dma_sb_region_create(struct ps3_dma_region *r) static int dma_ioc0_region_create(struct ps3_dma_region *r) { int result; + u64 bus_addr; INIT_LIST_HEAD(&r->chunk_list.head); spin_lock_init(&r->chunk_list.lock); @@ -692,7 +695,8 @@ static int dma_ioc0_region_create(struct ps3_dma_region *r) result = lv1_allocate_io_segment(0, r->len, r->page_size, - &r->bus_addr); + &bus_addr); + r->bus_addr = bus_addr; if (result) { DBG("%s:%d: lv1_allocate_io_segment failed: %s\n", __func__, __LINE__, ps3_result(result)); diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c index ccae3d446b9..b3c6a993f9f 100644 --- a/arch/powerpc/platforms/ps3/spu.c +++ b/arch/powerpc/platforms/ps3/spu.c @@ -149,7 +149,7 @@ EXPORT_SYMBOL_GPL(ps3_get_spe_id); static unsigned long get_vas_id(void) { - unsigned long id; + u64 id; lv1_get_logical_ppe_id(&id); lv1_get_virtual_address_space_id_of_ppe(id, &id); @@ -160,14 +160,18 @@ static unsigned long get_vas_id(void) static int __init construct_spu(struct spu *spu) { int result; - unsigned long unused; + u64 unused; + u64 problem_phys; + u64 local_store_phys; result = lv1_construct_logical_spe(PAGE_SHIFT, PAGE_SHIFT, PAGE_SHIFT, PAGE_SHIFT, PAGE_SHIFT, get_vas_id(), SPE_TYPE_LOGICAL, - &spu_pdata(spu)->priv2_addr, &spu->problem_phys, - &spu->local_store_phys, &unused, + &spu_pdata(spu)->priv2_addr, &problem_phys, + &local_store_phys, &unused, &spu_pdata(spu)->shadow_addr, &spu_pdata(spu)->spe_id); + spu->problem_phys = problem_phys; + spu->local_store_phys = local_store_phys; if (result) { pr_debug("%s:%d: lv1_construct_logical_spe failed: %s\n", diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index 70ef793e556..9bd4d677d3f 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c @@ -250,9 +250,11 @@ static void _dump_mmio_region(const struct ps3_mmio_region* r, static int ps3_sb_mmio_region_create(struct ps3_mmio_region *r) { int result; + u64 lpar_addr; result = lv1_map_device_mmio_region(r->dev->bus_id, r->dev->dev_id, - r->bus_addr, r->len, r->page_size, &r->lpar_addr); + r->bus_addr, r->len, r->page_size, &lpar_addr); + r->lpar_addr = lpar_addr; if (result) { pr_debug("%s:%d: lv1_map_device_mmio_region failed: %s\n", diff --git a/drivers/ps3/ps3-vuart.c b/drivers/ps3/ps3-vuart.c index 90c097a7a47..264c4475014 100644 --- a/drivers/ps3/ps3-vuart.c +++ b/drivers/ps3/ps3-vuart.c @@ -159,11 +159,13 @@ int ps3_vuart_get_triggers(struct ps3_system_bus_device *dev, struct vuart_triggers *trig) { int result; - unsigned long size; - unsigned long val; + u64 size; + u64 val; + u64 tx; result = lv1_get_virtual_uart_param(dev->port_number, - PARAM_TX_TRIGGER, &trig->tx); + PARAM_TX_TRIGGER, &tx); + trig->tx = tx; if (result) { dev_dbg(&dev->core, "%s:%d: tx_trigger failed: %s\n", @@ -201,7 +203,7 @@ int ps3_vuart_set_triggers(struct ps3_system_bus_device *dev, unsigned int tx, unsigned int rx) { int result; - unsigned long size; + u64 size; result = lv1_set_virtual_uart_param(dev->port_number, PARAM_TX_TRIGGER, tx); @@ -363,7 +365,7 @@ int ps3_vuart_disable_interrupt_disconnect(struct ps3_system_bus_device *dev) */ static int ps3_vuart_raw_write(struct ps3_system_bus_device *dev, - const void *buf, unsigned int bytes, unsigned long *bytes_written) + const void *buf, unsigned int bytes, u64 *bytes_written) { int result; struct ps3_vuart_port_priv *priv = to_port_priv(dev); @@ -379,7 +381,7 @@ static int ps3_vuart_raw_write(struct ps3_system_bus_device *dev, priv->stats.bytes_written += *bytes_written; - dev_dbg(&dev->core, "%s:%d: wrote %lxh/%xh=>%lxh\n", __func__, __LINE__, + dev_dbg(&dev->core, "%s:%d: wrote %llxh/%xh=>%lxh\n", __func__, __LINE__, *bytes_written, bytes, priv->stats.bytes_written); return result; @@ -393,7 +395,7 @@ static int ps3_vuart_raw_write(struct ps3_system_bus_device *dev, */ static int ps3_vuart_raw_read(struct ps3_system_bus_device *dev, void *buf, - unsigned int bytes, unsigned long *bytes_read) + unsigned int bytes, u64 *bytes_read) { int result; struct ps3_vuart_port_priv *priv = to_port_priv(dev); @@ -411,7 +413,7 @@ static int ps3_vuart_raw_read(struct ps3_system_bus_device *dev, void *buf, priv->stats.bytes_read += *bytes_read; - dev_dbg(&dev->core, "%s:%d: read %lxh/%xh=>%lxh\n", __func__, __LINE__, + dev_dbg(&dev->core, "%s:%d: read %llxh/%xh=>%lxh\n", __func__, __LINE__, *bytes_read, bytes, priv->stats.bytes_read); return result; @@ -500,7 +502,7 @@ int ps3_vuart_write(struct ps3_system_bus_device *dev, const void *buf, spin_lock_irqsave(&priv->tx_list.lock, flags); if (list_empty(&priv->tx_list.head)) { - unsigned long bytes_written; + u64 bytes_written; result = ps3_vuart_raw_write(dev, buf, bytes, &bytes_written); @@ -745,7 +747,7 @@ static int ps3_vuart_handle_interrupt_tx(struct ps3_system_bus_device *dev) list_for_each_entry_safe(lb, n, &priv->tx_list.head, link) { - unsigned long bytes_written; + u64 bytes_written; result = ps3_vuart_raw_write(dev, lb->head, lb->tail - lb->head, &bytes_written); @@ -762,7 +764,7 @@ static int ps3_vuart_handle_interrupt_tx(struct ps3_system_bus_device *dev) if (bytes_written < lb->tail - lb->head) { lb->head += bytes_written; dev_dbg(&dev->core, - "%s:%d cleared buf_%lu, %lxh bytes\n", + "%s:%d cleared buf_%lu, %llxh bytes\n", __func__, __LINE__, lb->dbg_number, bytes_written); goto port_full; -- cgit From 46ca0d15394baf804fbb38694c651dd067c69458 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 13 Jan 2009 20:00:29 +0000 Subject: powerpc/ps3: clear_bit()/set_bit() operate on unsigned longs This fixes these compiler warning: arch/powerpc/platforms/ps3/interrupt.c:109: warning: passing argument 2 of 'clear_bit' from incompatible pointer type arch/powerpc/platforms/ps3/interrupt.c:130: warning: passing argument 2 of 'set_bit' from incompatible pointer type Signed-off-by: Stephen Rothwell Acked-by: Geoff Levand Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/ps3/interrupt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c index b746792d84c..3ea6e51a7ff 100644 --- a/arch/powerpc/platforms/ps3/interrupt.c +++ b/arch/powerpc/platforms/ps3/interrupt.c @@ -60,6 +60,8 @@ * gives a usable range of plug values of {NUM_ISA_INTERRUPTS..63}. Note * that there is no constraint on how many in this set an individual thread * can acquire. + * + * The mask is declared as unsigned long so we can use set/clear_bit on it. */ #define PS3_BMP_MINALIGN 64 @@ -68,7 +70,7 @@ struct ps3_bmp { struct { u64 status; u64 unused_1[3]; - u64 mask; + unsigned long mask; u64 unused_2[3]; }; u64 ipi_debug_brk_mask; -- cgit From 5418b9c671a99727667cd499a2acbebe66e172cc Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 13 Jan 2009 20:01:28 +0000 Subject: powerpc/ps3: ps3_repository_read_mm_info() takes u64 * arguments Fixes compiler warnings: arch/powerpc/platforms/ps3/mm.c:1205: warning: passing argument 2 of 'ps3_repository_read_mm_info' from incompatible pointer type arch/powerpc/platforms/ps3/mm.c:1205: warning: passing argument 3 of 'ps3_repository_read_mm_info' from incompatible pointer type Signed-off-by: Stephen Rothwell Acked-by: Geoff Levand Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/ps3/mm.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c index 5c8d066283e..715508cc7e0 100644 --- a/arch/powerpc/platforms/ps3/mm.c +++ b/arch/powerpc/platforms/ps3/mm.c @@ -80,7 +80,7 @@ enum { struct mem_region { u64 base; - unsigned long size; + u64 size; unsigned long offset; }; @@ -103,7 +103,7 @@ struct mem_region { */ struct map { - unsigned long total; + u64 total; u64 vas_id; u64 htab_size; struct mem_region rm; @@ -114,13 +114,13 @@ struct map { static void __maybe_unused _debug_dump_map(const struct map *m, const char *func, int line) { - DBG("%s:%d: map.total = %lxh\n", func, line, m->total); - DBG("%s:%d: map.rm.size = %lxh\n", func, line, m->rm.size); + DBG("%s:%d: map.total = %llxh\n", func, line, m->total); + DBG("%s:%d: map.rm.size = %llxh\n", func, line, m->rm.size); DBG("%s:%d: map.vas_id = %llu\n", func, line, m->vas_id); DBG("%s:%d: map.htab_size = %llxh\n", func, line, m->htab_size); DBG("%s:%d: map.r1.base = %llxh\n", func, line, m->r1.base); DBG("%s:%d: map.r1.offset = %lxh\n", func, line, m->r1.offset); - DBG("%s:%d: map.r1.size = %lxh\n", func, line, m->r1.size); + DBG("%s:%d: map.r1.size = %llxh\n", func, line, m->r1.size); } static struct map map; @@ -240,10 +240,9 @@ static int ps3_mm_region_create(struct mem_region *r, unsigned long size) r->size = _ALIGN_DOWN(size, 1 << PAGE_SHIFT_16M); DBG("%s:%d requested %lxh\n", __func__, __LINE__, size); - DBG("%s:%d actual %lxh\n", __func__, __LINE__, r->size); - DBG("%s:%d difference %lxh (%luMB)\n", __func__, __LINE__, - (unsigned long)(size - r->size), - (size - r->size) / 1024 / 1024); + DBG("%s:%d actual %llxh\n", __func__, __LINE__, r->size); + DBG("%s:%d difference %llxh (%lluMB)\n", __func__, __LINE__, + size - r->size, (size - r->size) / 1024 / 1024); if (r->size == 0) { DBG("%s:%d: size == 0\n", __func__, __LINE__); -- cgit From 5c949070c7a591d1001a5d8444731dfa4223b094 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 13 Jan 2009 20:02:39 +0000 Subject: powerpc/ps3: Printing fixups for l64 to ll64 conversion arch/powerpc Signed-off-by: Stephen Rothwell Acked-by: Geoff Levand Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/ps3/device-init.c | 26 +++++++++++++------------- arch/powerpc/platforms/ps3/htab.c | 2 +- arch/powerpc/platforms/ps3/interrupt.c | 16 ++++++++-------- arch/powerpc/platforms/ps3/mm.c | 10 +++++----- arch/powerpc/platforms/ps3/os-area.c | 2 +- arch/powerpc/platforms/ps3/repository.c | 22 +++++++++++----------- arch/powerpc/platforms/ps3/system-bus.c | 6 +++--- 7 files changed, 42 insertions(+), 42 deletions(-) diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c index ca71a12b764..bb028f165fb 100644 --- a/arch/powerpc/platforms/ps3/device-init.c +++ b/arch/powerpc/platforms/ps3/device-init.c @@ -82,7 +82,7 @@ static int __init ps3_register_lpm_devices(void) goto fail_rights; } - pr_debug("%s:%d: pu_id %lu, rights %lu(%lxh)\n", + pr_debug("%s:%d: pu_id %llu, rights %llu(%llxh)\n", __func__, __LINE__, dev->lpm.pu_id, dev->lpm.rights, dev->lpm.rights); @@ -348,7 +348,7 @@ static int ps3_setup_storage_dev(const struct ps3_repository_device *repo, return -ENODEV; } - pr_debug("%s:%u: (%u:%u:%u): port %lu blk_size %lu num_blocks %lu " + pr_debug("%s:%u: (%u:%u:%u): port %llu blk_size %llu num_blocks %llu " "num_regions %u\n", __func__, __LINE__, repo->bus_index, repo->dev_index, repo->dev_type, port, blk_size, num_blocks, num_regions); @@ -394,7 +394,7 @@ static int ps3_setup_storage_dev(const struct ps3_repository_device *repo, result = -ENODEV; goto fail_read_region; } - pr_debug("%s:%u: region %u: id %u start %lu size %lu\n", + pr_debug("%s:%u: region %u: id %u start %llu size %llu\n", __func__, __LINE__, i, id, start, size); p->regions[i].id = id; @@ -662,13 +662,13 @@ static void ps3_find_and_add_device(u64 bus_id, u64 dev_id) if (rem) break; } - pr_warning("%s:%u: device %lu:%lu not found\n", __func__, __LINE__, + pr_warning("%s:%u: device %llu:%llu not found\n", __func__, __LINE__, bus_id, dev_id); return; found: if (retries) - pr_debug("%s:%u: device %lu:%lu found after %u retries\n", + pr_debug("%s:%u: device %llu:%llu found after %u retries\n", __func__, __LINE__, bus_id, dev_id, retries); ps3_setup_dynamic_device(&repo); @@ -715,14 +715,14 @@ static irqreturn_t ps3_notification_interrupt(int irq, void *data) res = lv1_storage_get_async_status(PS3_NOTIFICATION_DEV_ID, &tag, &status); if (tag != dev->tag) - pr_err("%s:%u: tag mismatch, got %lx, expected %lx\n", + pr_err("%s:%u: tag mismatch, got %llx, expected %llx\n", __func__, __LINE__, tag, dev->tag); if (res) { - pr_err("%s:%u: res %d status 0x%lx\n", __func__, __LINE__, res, + pr_err("%s:%u: res %d status 0x%llx\n", __func__, __LINE__, res, status); } else { - pr_debug("%s:%u: completed, status 0x%lx\n", __func__, + pr_debug("%s:%u: completed, status 0x%llx\n", __func__, __LINE__, status); dev->lv1_status = status; complete(&dev->done); @@ -761,7 +761,7 @@ static int ps3_notification_read_write(struct ps3_notification_device *dev, } if (dev->lv1_status) { - pr_err("%s:%u: %s not completed, status 0x%lx\n", __func__, + pr_err("%s:%u: %s not completed, status 0x%llx\n", __func__, __LINE__, op, dev->lv1_status); return -EIO; } @@ -850,16 +850,16 @@ static int ps3_probe_thread(void *data) if (res) break; - pr_debug("%s:%u: notify event type 0x%lx bus id %lu dev id %lu" - " type %lu port %lu\n", __func__, __LINE__, + pr_debug("%s:%u: notify event type 0x%llx bus id %llu dev id %llu" + " type %llu port %llu\n", __func__, __LINE__, notify_event->event_type, notify_event->bus_id, notify_event->dev_id, notify_event->dev_type, notify_event->dev_port); if (notify_event->event_type != notify_region_probe || notify_event->bus_id != dev.sbd.bus_id) { - pr_warning("%s:%u: bad notify_event: event %lu, " - "dev_id %lu, dev_type %lu\n", + pr_warning("%s:%u: bad notify_event: event %llu, " + "dev_id %llu, dev_type %llu\n", __func__, __LINE__, notify_event->event_type, notify_event->dev_id, notify_event->dev_type); diff --git a/arch/powerpc/platforms/ps3/htab.c b/arch/powerpc/platforms/ps3/htab.c index 6eb1d4d182c..1e8a1e39dfe 100644 --- a/arch/powerpc/platforms/ps3/htab.c +++ b/arch/powerpc/platforms/ps3/htab.c @@ -75,7 +75,7 @@ static long ps3_hpte_insert(unsigned long hpte_group, unsigned long va, if (result) { /* all entries bolted !*/ - pr_info("%s:result=%d va=%lx pa=%lx ix=%lx v=%lx r=%lx\n", + pr_info("%s:result=%d va=%lx pa=%lx ix=%lx v=%llx r=%llx\n", __func__, result, va, pa, hpte_group, hpte_v, hpte_r); BUG(); } diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c index 3ea6e51a7ff..8ec5ccf76b1 100644 --- a/arch/powerpc/platforms/ps3/interrupt.c +++ b/arch/powerpc/platforms/ps3/interrupt.c @@ -104,7 +104,7 @@ static void ps3_chip_mask(unsigned int virq) struct ps3_private *pd = get_irq_chip_data(virq); unsigned long flags; - pr_debug("%s:%d: thread_id %lu, virq %d\n", __func__, __LINE__, + pr_debug("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__, pd->thread_id, virq); local_irq_save(flags); @@ -125,7 +125,7 @@ static void ps3_chip_unmask(unsigned int virq) struct ps3_private *pd = get_irq_chip_data(virq); unsigned long flags; - pr_debug("%s:%d: thread_id %lu, virq %d\n", __func__, __LINE__, + pr_debug("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__, pd->thread_id, virq); local_irq_save(flags); @@ -223,7 +223,7 @@ static int ps3_virq_destroy(unsigned int virq) { const struct ps3_private *pd = get_irq_chip_data(virq); - pr_debug("%s:%d: ppe_id %lu, thread_id %lu, virq %u\n", __func__, + pr_debug("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__, __LINE__, pd->ppe_id, pd->thread_id, virq); set_irq_chip_data(virq, NULL); @@ -293,7 +293,7 @@ int ps3_irq_plug_destroy(unsigned int virq) int result; const struct ps3_private *pd = get_irq_chip_data(virq); - pr_debug("%s:%d: ppe_id %lu, thread_id %lu, virq %u\n", __func__, + pr_debug("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__, __LINE__, pd->ppe_id, pd->thread_id, virq); ps3_chip_mask(virq); @@ -693,7 +693,7 @@ void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq) pd->bmp.ipi_debug_brk_mask = 0x8000000000000000UL >> virq; - pr_debug("%s:%d: cpu %u, virq %u, mask %lxh\n", __func__, __LINE__, + pr_debug("%s:%d: cpu %u, virq %u, mask %llxh\n", __func__, __LINE__, cpu, virq, pd->bmp.ipi_debug_brk_mask); } @@ -712,7 +712,7 @@ static unsigned int ps3_get_irq(void) plug &= 0x3f; if (unlikely(plug == NO_IRQ)) { - pr_debug("%s:%d: no plug found: thread_id %lu\n", __func__, + pr_debug("%s:%d: no plug found: thread_id %llu\n", __func__, __LINE__, pd->thread_id); dump_bmp(&per_cpu(ps3_private, 0)); dump_bmp(&per_cpu(ps3_private, 1)); @@ -747,7 +747,7 @@ void __init ps3_init_IRQ(void) pd->thread_id = get_hard_smp_processor_id(cpu); spin_lock_init(&pd->bmp.lock); - pr_debug("%s:%d: ppe_id %lu, thread_id %lu, bmp %lxh\n", + pr_debug("%s:%d: ppe_id %llu, thread_id %llu, bmp %lxh\n", __func__, __LINE__, pd->ppe_id, pd->thread_id, ps3_mm_phys_to_lpar(__pa(&pd->bmp))); @@ -772,6 +772,6 @@ void ps3_shutdown_IRQ(int cpu) lv1_get_logical_ppe_id(&ppe_id); result = lv1_configure_irq_state_bitmap(ppe_id, thread_id, 0); - DBG("%s:%d: lv1_configure_irq_state_bitmap (%lu:%lu/%d) %s\n", __func__, + DBG("%s:%d: lv1_configure_irq_state_bitmap (%llu:%llu/%d) %s\n", __func__, __LINE__, ppe_id, thread_id, cpu, ps3_result(result)); } diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c index 715508cc7e0..67de6bf3db3 100644 --- a/arch/powerpc/platforms/ps3/mm.c +++ b/arch/powerpc/platforms/ps3/mm.c @@ -354,7 +354,7 @@ static unsigned long dma_sb_lpar_to_bus(struct ps3_dma_region *r, static void __maybe_unused _dma_dump_region(const struct ps3_dma_region *r, const char *func, int line) { - DBG("%s:%d: dev %lu:%lu\n", func, line, r->dev->bus_id, + DBG("%s:%d: dev %llu:%llu\n", func, line, r->dev->bus_id, r->dev->dev_id); DBG("%s:%d: page_size %u\n", func, line, r->page_size); DBG("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr); @@ -389,7 +389,7 @@ struct dma_chunk { static void _dma_dump_chunk (const struct dma_chunk* c, const char* func, int line) { - DBG("%s:%d: r.dev %lu:%lu\n", func, line, + DBG("%s:%d: r.dev %llu:%llu\n", func, line, c->region->dev->bus_id, c->region->dev->dev_id); DBG("%s:%d: r.bus_addr %lxh\n", func, line, c->region->bus_addr); DBG("%s:%d: r.page_size %u\n", func, line, c->region->page_size); @@ -595,7 +595,7 @@ static int dma_ioc0_map_pages(struct ps3_dma_region *r, unsigned long phys_addr, /* build ioptes for the area */ pages = len >> r->page_size; - DBG("%s: pgsize=%#x len=%#lx pages=%#x iopteflag=%#lx\n", __func__, + DBG("%s: pgsize=%#x len=%#lx pages=%#x iopteflag=%#llx\n", __func__, r->page_size, r->len, pages, iopte_flag); for (iopage = 0; iopage < pages; iopage++) { offset = (1 << r->page_size) * iopage; @@ -654,7 +654,7 @@ static int dma_sb_region_create(struct ps3_dma_region *r) BUG_ON(!r); if (!r->dev->bus_id) { - pr_info("%s:%d: %lu:%lu no dma\n", __func__, __LINE__, + pr_info("%s:%d: %llu:%llu no dma\n", __func__, __LINE__, r->dev->bus_id, r->dev->dev_id); return 0; } @@ -723,7 +723,7 @@ static int dma_sb_region_free(struct ps3_dma_region *r) BUG_ON(!r); if (!r->dev->bus_id) { - pr_info("%s:%d: %lu:%lu no dma\n", __func__, __LINE__, + pr_info("%s:%d: %llu:%llu no dma\n", __func__, __LINE__, r->dev->bus_id, r->dev->dev_id); return 0; } diff --git a/arch/powerpc/platforms/ps3/os-area.c b/arch/powerpc/platforms/ps3/os-area.c index 1d201782d4e..e1c83c23b43 100644 --- a/arch/powerpc/platforms/ps3/os-area.c +++ b/arch/powerpc/platforms/ps3/os-area.c @@ -306,7 +306,7 @@ static void _dump_params(const struct os_area_params *p, const char *func, { pr_debug("%s:%d: p.boot_flag: %u\n", func, line, p->boot_flag); pr_debug("%s:%d: p.num_params: %u\n", func, line, p->num_params); - pr_debug("%s:%d: p.rtc_diff %ld\n", func, line, p->rtc_diff); + pr_debug("%s:%d: p.rtc_diff %lld\n", func, line, p->rtc_diff); pr_debug("%s:%d: p.av_multi_out %u\n", func, line, p->av_multi_out); pr_debug("%s:%d: p.ctrl_button: %u\n", func, line, p->ctrl_button); pr_debug("%s:%d: p.static_ip_addr: %u.%u.%u.%u\n", func, line, diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c index 22063adeb38..5e304c292f6 100644 --- a/arch/powerpc/platforms/ps3/repository.c +++ b/arch/powerpc/platforms/ps3/repository.c @@ -44,7 +44,7 @@ static void _dump_field(const char *hdr, u64 n, const char *func, int line) s[i] = (in[i] <= 126 && in[i] >= 32) ? in[i] : '.'; s[i] = 0; - pr_debug("%s:%d: %s%016lx : %s\n", func, line, hdr, n, s); + pr_debug("%s:%d: %s%016llx : %s\n", func, line, hdr, n, s); #endif } @@ -70,8 +70,8 @@ static void _dump_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4, _dump_field("n2: ", n2, func, line); _dump_field("n3: ", n3, func, line); _dump_field("n4: ", n4, func, line); - pr_debug("%s:%d: v1: %016lx\n", func, line, v1); - pr_debug("%s:%d: v2: %016lx\n", func, line, v2); + pr_debug("%s:%d: v1: %016llx\n", func, line, v1); + pr_debug("%s:%d: v2: %016llx\n", func, line, v2); } /** @@ -149,10 +149,10 @@ static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4, *_v2 = v2; if (v1 && !_v1) - pr_debug("%s:%d: warning: discarding non-zero v1: %016lx\n", + pr_debug("%s:%d: warning: discarding non-zero v1: %016llx\n", __func__, __LINE__, v1); if (v2 && !_v2) - pr_debug("%s:%d: warning: discarding non-zero v2: %016lx\n", + pr_debug("%s:%d: warning: discarding non-zero v2: %016llx\n", __func__, __LINE__, v2); return 0; @@ -327,7 +327,7 @@ int ps3_repository_find_device(struct ps3_repository_device *repo) return result; } - pr_debug("%s:%d: bus_type %u, bus_index %u, bus_id %lu, num_dev %u\n", + pr_debug("%s:%d: bus_type %u, bus_index %u, bus_id %llu, num_dev %u\n", __func__, __LINE__, tmp.bus_type, tmp.bus_index, tmp.bus_id, num_dev); @@ -353,7 +353,7 @@ int ps3_repository_find_device(struct ps3_repository_device *repo) return result; } - pr_debug("%s:%d: found: dev_type %u, dev_index %u, dev_id %lu\n", + pr_debug("%s:%d: found: dev_type %u, dev_index %u, dev_id %llu\n", __func__, __LINE__, tmp.dev_type, tmp.dev_index, tmp.dev_id); *repo = tmp; @@ -367,7 +367,7 @@ int ps3_repository_find_device_by_id(struct ps3_repository_device *repo, struct ps3_repository_device tmp; unsigned int num_dev; - pr_debug(" -> %s:%u: find device by id %lu:%lu\n", __func__, __LINE__, + pr_debug(" -> %s:%u: find device by id %llu:%llu\n", __func__, __LINE__, bus_id, dev_id); for (tmp.bus_index = 0; tmp.bus_index < 10; tmp.bus_index++) { @@ -382,7 +382,7 @@ int ps3_repository_find_device_by_id(struct ps3_repository_device *repo, if (tmp.bus_id == bus_id) goto found_bus; - pr_debug("%s:%u: skip, bus_id %lu\n", __func__, __LINE__, + pr_debug("%s:%u: skip, bus_id %llu\n", __func__, __LINE__, tmp.bus_id); } pr_debug(" <- %s:%u: bus not found\n", __func__, __LINE__); @@ -416,7 +416,7 @@ found_bus: if (tmp.dev_id == dev_id) goto found_dev; - pr_debug("%s:%u: skip, dev_id %lu\n", __func__, __LINE__, + pr_debug("%s:%u: skip, dev_id %llu\n", __func__, __LINE__, tmp.dev_id); } pr_debug(" <- %s:%u: dev not found\n", __func__, __LINE__); @@ -430,7 +430,7 @@ found_dev: return result; } - pr_debug(" <- %s:%u: found: type (%u:%u) index (%u:%u) id (%lu:%lu)\n", + pr_debug(" <- %s:%u: found: type (%u:%u) index (%u:%u) id (%llu:%llu)\n", __func__, __LINE__, tmp.bus_type, tmp.dev_type, tmp.bus_index, tmp.dev_index, tmp.bus_id, tmp.dev_id); *repo = tmp; diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index 9bd4d677d3f..58311a86785 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c @@ -182,7 +182,7 @@ int ps3_open_hv_device(struct ps3_system_bus_device *dev) case PS3_MATCH_ID_SYSTEM_MANAGER: pr_debug("%s:%d: unsupported match_id: %u\n", __func__, __LINE__, dev->match_id); - pr_debug("%s:%d: bus_id: %lu\n", __func__, __LINE__, + pr_debug("%s:%d: bus_id: %llu\n", __func__, __LINE__, dev->bus_id); BUG(); return -EINVAL; @@ -220,7 +220,7 @@ int ps3_close_hv_device(struct ps3_system_bus_device *dev) case PS3_MATCH_ID_SYSTEM_MANAGER: pr_debug("%s:%d: unsupported match_id: %u\n", __func__, __LINE__, dev->match_id); - pr_debug("%s:%d: bus_id: %lu\n", __func__, __LINE__, + pr_debug("%s:%d: bus_id: %llu\n", __func__, __LINE__, dev->bus_id); BUG(); return -EINVAL; @@ -240,7 +240,7 @@ EXPORT_SYMBOL_GPL(ps3_close_hv_device); static void _dump_mmio_region(const struct ps3_mmio_region* r, const char* func, int line) { - pr_debug("%s:%d: dev %lu:%lu\n", func, line, r->dev->bus_id, + pr_debug("%s:%d: dev %llu:%llu\n", func, line, r->dev->bus_id, r->dev->dev_id); pr_debug("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr); pr_debug("%s:%d: len %lxh\n", func, line, r->len); -- cgit From e377c6e24d1b465ebd18fe49d0dc06932ced9bb0 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 13 Jan 2009 20:04:48 +0000 Subject: powerpc/ps3: Printing fixups for l64 to ll64 conversion drivers/block Signed-off-by: Stephen Rothwell Acked-by: Geoff Levand Signed-off-by: Benjamin Herrenschmidt --- drivers/block/ps3disk.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c index 936466f62af..bccc42bb921 100644 --- a/drivers/block/ps3disk.c +++ b/drivers/block/ps3disk.c @@ -141,7 +141,7 @@ static int ps3disk_submit_request_sg(struct ps3_storage_device *dev, start_sector = req->sector * priv->blocking_factor; sectors = req->nr_sectors * priv->blocking_factor; - dev_dbg(&dev->sbd.core, "%s:%u: %s %lu sectors starting at %lu\n", + dev_dbg(&dev->sbd.core, "%s:%u: %s %llu sectors starting at %llu\n", __func__, __LINE__, op, sectors, start_sector); if (write) { @@ -178,7 +178,7 @@ static int ps3disk_submit_flush_request(struct ps3_storage_device *dev, LV1_STORAGE_ATA_HDDOUT, 0, 0, 0, 0, &dev->tag); if (res) { - dev_err(&dev->sbd.core, "%s:%u: sync cache failed 0x%lx\n", + dev_err(&dev->sbd.core, "%s:%u: sync cache failed 0x%llx\n", __func__, __LINE__, res); end_request(req, 0); return 0; @@ -238,11 +238,11 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data) if (tag != dev->tag) dev_err(&dev->sbd.core, - "%s:%u: tag mismatch, got %lx, expected %lx\n", + "%s:%u: tag mismatch, got %llx, expected %llx\n", __func__, __LINE__, tag, dev->tag); if (res) { - dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%lx\n", + dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%llx\n", __func__, __LINE__, res, status); return IRQ_HANDLED; } @@ -269,7 +269,7 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data) op = read ? "read" : "write"; } if (status) { - dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%lx\n", __func__, + dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__, __LINE__, op, status); error = -EIO; } else { @@ -297,7 +297,7 @@ static int ps3disk_sync_cache(struct ps3_storage_device *dev) res = ps3stor_send_command(dev, LV1_STORAGE_ATA_HDDOUT, 0, 0, 0, 0); if (res) { - dev_err(&dev->sbd.core, "%s:%u: sync cache failed 0x%lx\n", + dev_err(&dev->sbd.core, "%s:%u: sync cache failed 0x%llx\n", __func__, __LINE__, res); return -EIO; } @@ -388,7 +388,7 @@ static int ps3disk_identify(struct ps3_storage_device *dev) sizeof(ata_cmnd), ata_cmnd.buffer, ata_cmnd.arglen); if (res) { - dev_err(&dev->sbd.core, "%s:%u: identify disk failed 0x%lx\n", + dev_err(&dev->sbd.core, "%s:%u: identify disk failed 0x%llx\n", __func__, __LINE__, res); return -EIO; } @@ -426,7 +426,7 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev) if (dev->blk_size < 512) { dev_err(&dev->sbd.core, - "%s:%u: cannot handle block size %lu\n", __func__, + "%s:%u: cannot handle block size %llu\n", __func__, __LINE__, dev->blk_size); return -EINVAL; } @@ -512,7 +512,7 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev) dev->regions[dev->region_idx].size*priv->blocking_factor); dev_info(&dev->sbd.core, - "%s is a %s (%lu MiB total, %lu MiB for OtherOS)\n", + "%s is a %s (%llu MiB total, %lu MiB for OtherOS)\n", gendisk->disk_name, priv->model, priv->raw_capacity >> 11, get_capacity(gendisk) >> 11); -- cgit From 4c33d2dc34f50e5d5436e62cd99395859f157a19 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 13 Jan 2009 20:06:02 +0000 Subject: powerpc/ps3: Printing fixups for l64 to ll64 conversion drivers/char Also a couple of min -> min_t changes. Signed-off-by: Stephen Rothwell Acked-by: Geoff Levand Signed-off-by: Benjamin Herrenschmidt --- drivers/char/ps3flash.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c index 79b6f461be7..afbe45676d7 100644 --- a/drivers/char/ps3flash.c +++ b/drivers/char/ps3flash.c @@ -44,7 +44,7 @@ static ssize_t ps3flash_read_write_sectors(struct ps3_storage_device *dev, u64 res = ps3stor_read_write_sectors(dev, lpar, start_sector, sectors, write); if (res) { - dev_err(&dev->sbd.core, "%s:%u: %s failed 0x%lx\n", __func__, + dev_err(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__, __LINE__, write ? "write" : "read", res); return -EIO; } @@ -59,7 +59,7 @@ static ssize_t ps3flash_read_sectors(struct ps3_storage_device *dev, max_sectors = dev->bounce_size / dev->blk_size; if (sectors > max_sectors) { - dev_dbg(&dev->sbd.core, "%s:%u Limiting sectors to %lu\n", + dev_dbg(&dev->sbd.core, "%s:%u Limiting sectors to %llu\n", __func__, __LINE__, max_sectors); sectors = max_sectors; } @@ -144,7 +144,7 @@ static ssize_t ps3flash_read(struct file *file, char __user *buf, size_t count, goto fail; } - n = min(remaining, sectors_read*dev->blk_size-offset); + n = min_t(u64, remaining, sectors_read*dev->blk_size-offset); dev_dbg(&dev->sbd.core, "%s:%u: copy %lu bytes from 0x%p to user 0x%p\n", __func__, __LINE__, n, dev->bounce_buf+offset, buf); @@ -225,7 +225,7 @@ static ssize_t ps3flash_write(struct file *file, const char __user *buf, if (end_read_sector >= start_read_sector) { /* Merge head and tail */ dev_dbg(&dev->sbd.core, - "Merged head and tail: %lu sectors at %lu\n", + "Merged head and tail: %llu sectors at %llu\n", chunk_sectors, start_write_sector); res = ps3flash_read_sectors(dev, start_write_sector, chunk_sectors, 0); @@ -235,7 +235,7 @@ static ssize_t ps3flash_write(struct file *file, const char __user *buf, if (head) { /* Read head */ dev_dbg(&dev->sbd.core, - "head: %lu sectors at %lu\n", head, + "head: %llu sectors at %llu\n", head, start_write_sector); res = ps3flash_read_sectors(dev, start_write_sector, @@ -247,7 +247,7 @@ static ssize_t ps3flash_write(struct file *file, const char __user *buf, start_write_sector+chunk_sectors) { /* Read tail */ dev_dbg(&dev->sbd.core, - "tail: %lu sectors at %lu\n", tail, + "tail: %llu sectors at %llu\n", tail, start_read_sector); sec_off = start_read_sector-start_write_sector; res = ps3flash_read_sectors(dev, @@ -258,7 +258,7 @@ static ssize_t ps3flash_write(struct file *file, const char __user *buf, } } - n = min(remaining, dev->bounce_size-offset); + n = min_t(u64, remaining, dev->bounce_size-offset); dev_dbg(&dev->sbd.core, "%s:%u: copy %lu bytes from user 0x%p to 0x%p\n", __func__, __LINE__, n, buf, dev->bounce_buf+offset); @@ -299,11 +299,11 @@ static irqreturn_t ps3flash_interrupt(int irq, void *data) if (tag != dev->tag) dev_err(&dev->sbd.core, - "%s:%u: tag mismatch, got %lx, expected %lx\n", + "%s:%u: tag mismatch, got %llx, expected %llx\n", __func__, __LINE__, tag, dev->tag); if (res) { - dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%lx\n", + dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%llx\n", __func__, __LINE__, res, status); } else { dev->lv1_status = status; -- cgit From 26db11af12fb58dde1d6327035a248a99f60f112 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 13 Jan 2009 20:07:55 +0000 Subject: powerpc/ps3: Printing fixups for l64 to ll64 conversion sound/ppc Signed-off-by: Stephen Rothwell Acked-by: Takashi Iwai Acked-by: Geoff Levand Signed-off-by: Benjamin Herrenschmidt --- sound/ppc/snd_ps3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c index 8f9e3859c37..ff321110ec0 100644 --- a/sound/ppc/snd_ps3.c +++ b/sound/ppc/snd_ps3.c @@ -477,7 +477,7 @@ static int snd_ps3_pcm_prepare(struct snd_pcm_substream *substream) card->dma_start_bus_addr[SND_PS3_CH_R] = runtime->dma_addr + (runtime->dma_bytes / 2); - pr_debug("%s: vaddr=%p bus=%#lx\n", __func__, + pr_debug("%s: vaddr=%p bus=%#llx\n", __func__, card->dma_start_vaddr[SND_PS3_CH_L], card->dma_start_bus_addr[SND_PS3_CH_L]); @@ -1030,7 +1030,7 @@ static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev) pr_info("%s: nullbuffer alloc failed\n", __func__); goto clean_preallocate; } - pr_debug("%s: null vaddr=%p dma=%#lx\n", __func__, + pr_debug("%s: null vaddr=%p dma=%#llx\n", __func__, the_card.null_buffer_start_vaddr, the_card.null_buffer_start_dma_addr); /* set default sample rate/word width */ -- cgit From a9dad6e598155e2a548142336cd833e5360335d1 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 13 Jan 2009 20:10:06 +0000 Subject: powerpc/ps3: Printing fixups for l64 to ll64 conversion drivers/ps3 Also some min -> mint_t conversion. Signed-off-by: Stephen Rothwell Acked-by: Geoff Levand Signed-off-by: Benjamin Herrenschmidt --- drivers/ps3/ps3-lpm.c | 16 ++++++++-------- drivers/ps3/ps3-vuart.c | 8 ++++---- drivers/ps3/ps3stor_lib.c | 14 +++++++------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/ps3/ps3-lpm.c b/drivers/ps3/ps3-lpm.c index 204158cf7a5..fe96793e3f0 100644 --- a/drivers/ps3/ps3-lpm.c +++ b/drivers/ps3/ps3-lpm.c @@ -732,7 +732,7 @@ static u64 pm_signal_group_to_ps3_lv1_signal_group(u64 group) case 8: return pm_translate_signal_group_number_on_island8(subgroup); default: - dev_dbg(sbd_core(), "%s:%u: island not found: %lu\n", __func__, + dev_dbg(sbd_core(), "%s:%u: island not found: %llu\n", __func__, __LINE__, group); BUG(); break; @@ -765,7 +765,7 @@ static int __ps3_set_signal(u64 lv1_signal_group, u64 bus_select, signal_select, attr1, attr2, attr3); if (ret) dev_err(sbd_core(), - "%s:%u: error:%d 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n", + "%s:%u: error:%d 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx\n", __func__, __LINE__, ret, lv1_signal_group, bus_select, signal_select, attr1, attr2, attr3); @@ -908,7 +908,7 @@ void ps3_disable_pm(u32 cpu) lpm_priv->tb_count = tmp; - dev_dbg(sbd_core(), "%s:%u: tb_count %lu (%lxh)\n", __func__, __LINE__, + dev_dbg(sbd_core(), "%s:%u: tb_count %llu (%llxh)\n", __func__, __LINE__, lpm_priv->tb_count, lpm_priv->tb_count); } EXPORT_SYMBOL_GPL(ps3_disable_pm); @@ -938,7 +938,7 @@ int ps3_lpm_copy_tb(unsigned long offset, void *buf, unsigned long count, if (offset >= lpm_priv->tb_count) return 0; - count = min(count, lpm_priv->tb_count - offset); + count = min_t(u64, count, lpm_priv->tb_count - offset); while (*bytes_copied < count) { const unsigned long request = count - *bytes_copied; @@ -993,7 +993,7 @@ int ps3_lpm_copy_tb_to_user(unsigned long offset, void __user *buf, if (offset >= lpm_priv->tb_count) return 0; - count = min(count, lpm_priv->tb_count - offset); + count = min_t(u64, count, lpm_priv->tb_count - offset); while (*bytes_copied < count) { const unsigned long request = count - *bytes_copied; @@ -1013,7 +1013,7 @@ int ps3_lpm_copy_tb_to_user(unsigned long offset, void __user *buf, result = copy_to_user(buf, lpm_priv->tb_cache, tmp); if (result) { - dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%p\n", + dev_dbg(sbd_core(), "%s:%u: 0x%llx bytes at 0x%p\n", __func__, __LINE__, tmp, buf); dev_err(sbd_core(), "%s:%u: copy_to_user failed: %d\n", __func__, __LINE__, result); @@ -1148,8 +1148,8 @@ int ps3_lpm_open(enum ps3_lpm_tb_type tb_type, void *tb_cache, lpm_priv->shadow.group_control = PS3_LPM_SHADOW_REG_INIT; lpm_priv->shadow.debug_bus_control = PS3_LPM_SHADOW_REG_INIT; - dev_dbg(sbd_core(), "%s:%u: lpm_id 0x%lx, outlet_id 0x%lx, " - "tb_size 0x%lx\n", __func__, __LINE__, lpm_priv->lpm_id, + dev_dbg(sbd_core(), "%s:%u: lpm_id 0x%llx, outlet_id 0x%llx, " + "tb_size 0x%llx\n", __func__, __LINE__, lpm_priv->lpm_id, lpm_priv->outlet_id, tb_size); return 0; diff --git a/drivers/ps3/ps3-vuart.c b/drivers/ps3/ps3-vuart.c index 264c4475014..e4ad5ba5d0a 100644 --- a/drivers/ps3/ps3-vuart.c +++ b/drivers/ps3/ps3-vuart.c @@ -114,7 +114,7 @@ struct ports_bmp { static void __maybe_unused _dump_ports_bmp( const struct ports_bmp *bmp, const char *func, int line) { - pr_debug("%s:%d: ports_bmp: %016lxh\n", func, line, bmp->status); + pr_debug("%s:%d: ports_bmp: %016llxh\n", func, line, bmp->status); } #define dump_port_params(_b) _dump_port_params(_b, __func__, __LINE__) @@ -250,7 +250,7 @@ static int ps3_vuart_get_rx_bytes_waiting(struct ps3_system_bus_device *dev, dev_dbg(&dev->core, "%s:%d: rx_bytes failed: %s\n", __func__, __LINE__, ps3_result(result)); - dev_dbg(&dev->core, "%s:%d: %lxh\n", __func__, __LINE__, + dev_dbg(&dev->core, "%s:%d: %llxh\n", __func__, __LINE__, *bytes_waiting); return result; } @@ -297,7 +297,7 @@ static int ps3_vuart_get_interrupt_status(struct ps3_system_bus_device *dev, *status = tmp & priv->interrupt_mask; - dev_dbg(&dev->core, "%s:%d: m %lxh, s %lxh, m&s %lxh\n", + dev_dbg(&dev->core, "%s:%d: m %llxh, s %llxh, m&s %lxh\n", __func__, __LINE__, priv->interrupt_mask, tmp, *status); return result; @@ -594,7 +594,7 @@ static int ps3_vuart_queue_rx_bytes(struct ps3_system_bus_device *dev, list_add_tail(&lb->link, &priv->rx_list.head); priv->rx_list.bytes_held += bytes; - dev_dbg(&dev->core, "%s:%d: buf_%lu: queued %lxh bytes\n", + dev_dbg(&dev->core, "%s:%d: buf_%lu: queued %llxh bytes\n", __func__, __LINE__, lb->dbg_number, bytes); *bytes_queued = bytes; diff --git a/drivers/ps3/ps3stor_lib.c b/drivers/ps3/ps3stor_lib.c index 55955f16ad9..18066d55539 100644 --- a/drivers/ps3/ps3stor_lib.c +++ b/drivers/ps3/ps3stor_lib.c @@ -70,7 +70,7 @@ static int ps3stor_probe_access(struct ps3_storage_device *dev) __func__, __LINE__, n); dev->region_idx = __ffs(dev->accessible_regions); dev_info(&dev->sbd.core, - "First accessible region has index %u start %lu size %lu\n", + "First accessible region has index %u start %llu size %llu\n", dev->region_idx, dev->regions[dev->region_idx].start, dev->regions[dev->region_idx].size); @@ -220,7 +220,7 @@ u64 ps3stor_read_write_sectors(struct ps3_storage_device *dev, u64 lpar, const char *op = write ? "write" : "read"; int res; - dev_dbg(&dev->sbd.core, "%s:%u: %s %lu sectors starting at %lu\n", + dev_dbg(&dev->sbd.core, "%s:%u: %s %llu sectors starting at %llu\n", __func__, __LINE__, op, sectors, start_sector); init_completion(&dev->done); @@ -238,7 +238,7 @@ u64 ps3stor_read_write_sectors(struct ps3_storage_device *dev, u64 lpar, wait_for_completion(&dev->done); if (dev->lv1_status) { - dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%lx\n", __func__, + dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__, __LINE__, op, dev->lv1_status); return dev->lv1_status; } @@ -268,7 +268,7 @@ u64 ps3stor_send_command(struct ps3_storage_device *dev, u64 cmd, u64 arg1, { int res; - dev_dbg(&dev->sbd.core, "%s:%u: send device command 0x%lx\n", __func__, + dev_dbg(&dev->sbd.core, "%s:%u: send device command 0x%llx\n", __func__, __LINE__, cmd); init_completion(&dev->done); @@ -277,19 +277,19 @@ u64 ps3stor_send_command(struct ps3_storage_device *dev, u64 cmd, u64 arg1, arg2, arg3, arg4, &dev->tag); if (res) { dev_err(&dev->sbd.core, - "%s:%u: send_device_command 0x%lx failed %d\n", + "%s:%u: send_device_command 0x%llx failed %d\n", __func__, __LINE__, cmd, res); return -1; } wait_for_completion(&dev->done); if (dev->lv1_status) { - dev_dbg(&dev->sbd.core, "%s:%u: command 0x%lx failed 0x%lx\n", + dev_dbg(&dev->sbd.core, "%s:%u: command 0x%llx failed 0x%llx\n", __func__, __LINE__, cmd, dev->lv1_status); return dev->lv1_status; } - dev_dbg(&dev->sbd.core, "%s:%u: command 0x%lx completed\n", __func__, + dev_dbg(&dev->sbd.core, "%s:%u: command 0x%llx completed\n", __func__, __LINE__, cmd); return 0; -- cgit From 7ad489e3d2459f7520d9062cb855ff29a8dd683d Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 13 Jan 2009 20:11:44 +0000 Subject: powerpc/ps3: Printing fixups for l64 to ll64 conversion drivers/scsi Signed-off-by: Stephen Rothwell Acked-by: Geoff Levand Signed-off-by: Benjamin Herrenschmidt --- drivers/scsi/ps3rom.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c index ce48e2d0193..ca0dd33497e 100644 --- a/drivers/scsi/ps3rom.c +++ b/drivers/scsi/ps3rom.c @@ -290,11 +290,11 @@ static irqreturn_t ps3rom_interrupt(int irq, void *data) if (tag != dev->tag) dev_err(&dev->sbd.core, - "%s:%u: tag mismatch, got %lx, expected %lx\n", + "%s:%u: tag mismatch, got %llx, expected %llx\n", __func__, __LINE__, tag, dev->tag); if (res) { - dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%lx\n", + dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%llx\n", __func__, __LINE__, res, status); return IRQ_HANDLED; } @@ -364,7 +364,7 @@ static int __devinit ps3rom_probe(struct ps3_system_bus_device *_dev) if (dev->blk_size != CD_FRAMESIZE) { dev_err(&dev->sbd.core, - "%s:%u: cannot handle block size %lu\n", __func__, + "%s:%u: cannot handle block size %llu\n", __func__, __LINE__, dev->blk_size); return -EINVAL; } -- cgit From 5d9ee3ff3dbf815cd9ee18c166bb9b538e8057d2 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 13 Jan 2009 20:13:39 +0000 Subject: powerpc/ps3: printing fixups for l64 to ll64 conversion drivers/video Signed-off-by: Stephen Rothwell Acked-by: Geoff Levand Signed-off-by: Benjamin Herrenschmidt --- drivers/video/ps3fb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c index 38ac805db97..87f826e4c95 100644 --- a/drivers/video/ps3fb.c +++ b/drivers/video/ps3fb.c @@ -1006,7 +1006,7 @@ static int ps3fb_xdr_settings(u64 xdr_lpar, struct device *dev) __func__, status); return -ENXIO; } - dev_dbg(dev, "video:%p ioif:%lx lpar:%lx size:%lx\n", + dev_dbg(dev, "video:%p ioif:%lx lpar:%llx size:%lx\n", ps3fb_videomemory.address, GPU_IOIF, xdr_lpar, ps3fb_videomemory.size); @@ -1133,7 +1133,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) __func__, status); goto err; } - dev_dbg(&dev->core, "ddr:lpar:0x%lx\n", ddr_lpar); + dev_dbg(&dev->core, "ddr:lpar:0x%llx\n", ddr_lpar); status = lv1_gpu_context_allocate(ps3fb.memory_handle, 0, &ps3fb.context_handle, -- cgit From 9ba0fdbfaed2e74005d87fab948c5522b86ff733 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Wed, 14 Jan 2009 09:09:34 +0000 Subject: powerpc: is_hugepage_only_range() must account for both 4kB and 64kB slices powerpc: is_hugepage_only_range() must account for both 4kB and 64kB slices The subpage_prot syscall fails on second and subsequent calls for a given region, because is_hugepage_only_range() is mis-identifying the 4 kB slices when the process has a 64 kB page size. Signed-off-by: Dave Kleikamp Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/slice.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c index db44e02e045..ba5194817f8 100644 --- a/arch/powerpc/mm/slice.c +++ b/arch/powerpc/mm/slice.c @@ -710,9 +710,18 @@ int is_hugepage_only_range(struct mm_struct *mm, unsigned long addr, unsigned long len) { struct slice_mask mask, available; + unsigned int psize = mm->context.user_psize; mask = slice_range_to_mask(addr, len); - available = slice_mask_for_size(mm, mm->context.user_psize); + available = slice_mask_for_size(mm, psize); +#ifdef CONFIG_PPC_64K_PAGES + /* We need to account for 4k slices too */ + if (psize == MMU_PAGE_64K) { + struct slice_mask compat_mask; + compat_mask = slice_mask_for_size(mm, MMU_PAGE_4K); + or_mask(available, compat_mask); + } +#endif #if 0 /* too verbose */ slice_dbg("is_hugepage_only_range(mm=%p, addr=%lx, len=%lx)\n", -- cgit From b60c31d85a2a2f1a9c8623f1fb56e2688aa1e2b1 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Wed, 14 Jan 2009 13:42:41 +0000 Subject: powerpc: Get the number of SLBs from "slb-size" property The PAPR says that the property for specifying the number of SLBs should be called "slb-size". We currently only look for "ibm,slb-size" because this is what firmware actually presents. This patch makes us look for the "slb-size" property as well and in preference to the "ibm,slb-size". This should future proof us if firmware changes to match PAPR. Signed-off-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/prom.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index c09cffafb6e..f00f83109ab 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -590,6 +590,11 @@ static void __init check_cpu_slb_size(unsigned long node) { u32 *slb_size_ptr; + slb_size_ptr = of_get_flat_dt_prop(node, "slb-size", NULL); + if (slb_size_ptr != NULL) { + mmu_slb_size = *slb_size_ptr; + return; + } slb_size_ptr = of_get_flat_dt_prop(node, "ibm,slb-size", NULL); if (slb_size_ptr != NULL) { mmu_slb_size = *slb_size_ptr; -- cgit From 7f8030d166f84b7413a0393819cb8b800484d5a9 Mon Sep 17 00:00:00 2001 From: Hendrik Brueckner Date: Wed, 14 Jan 2009 23:15:44 +0000 Subject: hvc_console: Remove tty->low_latency This patch removes the tty->low_latency setting. For irq based hvc_console backends the tty->low_latency must be set to 0, because the tty_flip_buffer_push() function must not be called from IRQ context (see drivers/char/tty_buffer.c). For polled backends, the low_latency setting causes the bug trace below, because tty_flip_buffer_push() is called within an atomic context and subsequent calls might sleep due to mutex_lock. BUG: sleeping function called from invalid context at /root/cvs/linux-2.6.git/kernel/mutex.c:207 in_atomic(): 1, irqs_disabled(): 0, pid: 748, name: khvcd 1 lock held by khvcd/748: #0: (hvc_structs_lock){--..}, at: [<00000000002ceb50>] khvcd+0x58/0x12c CPU: 0 Not tainted 2.6.29-rc1git #29 Process khvcd (pid: 748, task: 000000002fb9a480, ksp: 000000002f66bd78) 070000000000000a 000000002f66ba00 0000000000000002 (null) 000000002f66baa0 000000002f66ba18 000000002f66ba18 0000000000104f08 ffffffffffffc000 000000002f66bd78 (null) (null) 000000002f66ba00 000000000000000c 000000002f66ba00 000000002f66ba70 0000000000466af8 0000000000104f08 000000002f66ba00 000000002f66ba50 Call Trace: ([<0000000000104e7c>] show_trace+0x138/0x158) [<0000000000104f62>] show_stack+0xc6/0xf8 [<0000000000105740>] dump_stack+0xb0/0xc0 [<000000000013144a>] __might_sleep+0x14e/0x17c [<000000000045e226>] mutex_lock_nested+0x42/0x3b4 [<00000000002c443e>] echo_char_raw+0x3a/0x9c [<00000000002c688c>] n_tty_receive_buf+0x1154/0x1208 [<00000000002ca0a2>] flush_to_ldisc+0x152/0x220 [<00000000002ca1da>] tty_flip_buffer_push+0x6a/0x90 [<00000000002cea74>] hvc_poll+0x244/0x2c8 [<00000000002ceb68>] khvcd+0x70/0x12c [<000000000015bbd0>] kthread+0x68/0xa0 [<0000000000109d5a>] kernel_thread_starter+0x6/0xc [<0000000000109d54>] kernel_thread_starter+0x0/0xc 1 lock held by khvcd/748: #0: (hvc_structs_lock){--..}, at: [<00000000002ceb50>] khvcd+0x58/0x12c Signed-off-by: Hendrik Brueckner Acked-by: Christian Borntraeger Signed-off-by: Benjamin Herrenschmidt --- drivers/char/hvc_console.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 09676b4e5d8..94e7e3c8c05 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c @@ -318,8 +318,6 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) } /* else count == 0 */ tty->driver_data = hp; - if (!hp->irq_requested) - tty->low_latency = 1; /* Makes flushes to ldisc synchronous. */ hp->tty = tty; -- cgit From 0025e75357e7e8daf03a74294c98425a80a433c7 Mon Sep 17 00:00:00 2001 From: Matthias Fuchs Date: Thu, 15 Jan 2009 09:43:35 +0000 Subject: serial: Add 16850 uart type support to OF uart driver This patch adds support for "ns16850" as supported value of the compatible node in flat device tree uart descriptions. This is needed for example when you have a XR16C2850 uart connected to a PPC405's external bus controller. Signed-off-by: Matthias Fuchs Signed-off-by: Benjamin Herrenschmidt --- drivers/serial/of_serial.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c index a821e3a3d66..14f8fa9135b 100644 --- a/drivers/serial/of_serial.c +++ b/drivers/serial/of_serial.c @@ -163,6 +163,7 @@ static struct of_device_id __devinitdata of_platform_serial_table[] = { { .type = "serial", .compatible = "ns16450", .data = (void *)PORT_16450, }, { .type = "serial", .compatible = "ns16550", .data = (void *)PORT_16550, }, { .type = "serial", .compatible = "ns16750", .data = (void *)PORT_16750, }, + { .type = "serial", .compatible = "ns16850", .data = (void *)PORT_16850, }, #ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL { .type = "serial", .compatible = "ibm,qpace-nwp-serial", .data = (void *)PORT_NWPSERIAL, }, -- cgit From 169d5f663759ec494aa74a552ce99486235e6e50 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Wed, 14 Jan 2009 22:33:31 -0700 Subject: fsldma: print correct IRQ on mpc83xx The mpc83xx variant uses a shared IRQ for all channels, so the individual channel nodes don't have an interrupt property. Fix the code to print the controller IRQ instead if there isn't any for the channel. Acked-by: Timur Tabi Acked-by: Li Yang Signed-off-by: Peter Korsgaard Signed-off-by: Dan Williams --- drivers/dma/fsldma.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index b1b45eb42cb..70126a60623 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -875,7 +875,8 @@ static int __devinit fsl_dma_chan_probe(struct fsl_dma_device *fdev, } dev_info(fdev->dev, "#%d (%s), irq %d\n", new_fsl_chan->id, - compatible, new_fsl_chan->irq); + compatible, + new_fsl_chan->irq != NO_IRQ ? new_fsl_chan->irq : fdev->irq); return 0; -- cgit From 40a518d9f1fd8ed1061b8b4e2ce8a44794f4eb03 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 12 Jan 2009 12:05:32 -0800 Subject: drm: initial KMS config fixes When mode setting is first initialized, the driver will call into drm_helper_initial_config() to set up an initial output and framebuffer configuration. This routine is responsible for probing the available connectors, encoders, and crtcs, looking for modes and putting together something reasonable (where reasonable is defined as "allows kernel messages to be visible on as many displays as possible"). However, the code was a bit too aggressive in setting default modes when none were found on a given connector. Even if some connectors had modes, any connectors found lacking modes would have the default 800x600 mode added to their mode list, which in some cases could cause problems later down the line. In my case, the LVDS was perfectly available, but the initial config code added 800x600 modes to both of the detected but unavailable HDMI connectors (which are on my non-existent docking station). This ended up preventing later code from setting a mode on my LVDS, which is bad. This patch fixes that behavior by making the initial config code walk through the connectors first, counting the available modes, before it decides to add any default modes to a possibly connected output. It also fixes the logic in drm_target_preferred() that was causing zeroed out modes to be set as the preferred mode for a given connector, even if no modes were available. Signed-off-by: Jesse Barnes Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc_helper.c | 127 ++++++++++++++++++++++++++++---------- include/drm/drm_crtc.h | 2 +- include/drm/drm_crtc_helper.h | 2 +- 3 files changed, 95 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index d8a982b7129..e490e69db21 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -36,7 +36,7 @@ /* * Detailed mode info for 800x600@60Hz */ -static struct drm_display_mode std_mode[] = { +static struct drm_display_mode std_modes[] = { { DRM_MODE("800x600", DRM_MODE_TYPE_DEFAULT, 40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, @@ -60,15 +60,18 @@ static struct drm_display_mode std_mode[] = { * changes have occurred. * * FIXME: take into account monitor limits + * + * RETURNS: + * Number of modes found on @connector. */ -void drm_helper_probe_single_connector_modes(struct drm_connector *connector, - uint32_t maxX, uint32_t maxY) +int drm_helper_probe_single_connector_modes(struct drm_connector *connector, + uint32_t maxX, uint32_t maxY) { struct drm_device *dev = connector->dev; struct drm_display_mode *mode, *t; struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; - int ret; + int count = 0; DRM_DEBUG("%s\n", drm_get_connector_name(connector)); /* set all modes to the unverified state */ @@ -81,14 +84,14 @@ void drm_helper_probe_single_connector_modes(struct drm_connector *connector, DRM_DEBUG("%s is disconnected\n", drm_get_connector_name(connector)); /* TODO set EDID to NULL */ - return; + return 0; } - ret = (*connector_funcs->get_modes)(connector); + count = (*connector_funcs->get_modes)(connector); + if (!count) + return 0; - if (ret) { - drm_mode_connector_list_update(connector); - } + drm_mode_connector_list_update(connector); if (maxX && maxY) drm_mode_validate_size(dev, &connector->modes, maxX, @@ -102,25 +105,8 @@ void drm_helper_probe_single_connector_modes(struct drm_connector *connector, drm_mode_prune_invalid(dev, &connector->modes, true); - if (list_empty(&connector->modes)) { - struct drm_display_mode *stdmode; - - DRM_DEBUG("No valid modes on %s\n", - drm_get_connector_name(connector)); - - /* Should we do this here ??? - * When no valid EDID modes are available we end up - * here and bailed in the past, now we add a standard - * 640x480@60Hz mode and carry on. - */ - stdmode = drm_mode_duplicate(dev, &std_mode[0]); - drm_mode_probed_add(connector, stdmode); - drm_mode_list_concat(&connector->probed_modes, - &connector->modes); - - DRM_DEBUG("Adding standard 640x480 @ 60Hz to %s\n", - drm_get_connector_name(connector)); - } + if (list_empty(&connector->modes)) + return 0; drm_mode_sort(&connector->modes); @@ -131,20 +117,58 @@ void drm_helper_probe_single_connector_modes(struct drm_connector *connector, drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); drm_mode_debug_printmodeline(mode); } + + return count; } EXPORT_SYMBOL(drm_helper_probe_single_connector_modes); -void drm_helper_probe_connector_modes(struct drm_device *dev, uint32_t maxX, +int drm_helper_probe_connector_modes(struct drm_device *dev, uint32_t maxX, uint32_t maxY) { struct drm_connector *connector; + int count = 0; list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - drm_helper_probe_single_connector_modes(connector, maxX, maxY); + count += drm_helper_probe_single_connector_modes(connector, + maxX, maxY); } + + return count; } EXPORT_SYMBOL(drm_helper_probe_connector_modes); +static void drm_helper_add_std_modes(struct drm_device *dev, + struct drm_connector *connector) +{ + struct drm_display_mode *mode, *t; + int i; + + for (i = 0; i < ARRAY_SIZE(std_modes); i++) { + struct drm_display_mode *stdmode; + + /* + * When no valid EDID modes are available we end up + * here and bailed in the past, now we add some standard + * modes and move on. + */ + stdmode = drm_mode_duplicate(dev, &std_modes[i]); + drm_mode_probed_add(connector, stdmode); + drm_mode_list_concat(&connector->probed_modes, + &connector->modes); + + DRM_DEBUG("Adding mode %s to %s\n", stdmode->name, + drm_get_connector_name(connector)); + } + drm_mode_sort(&connector->modes); + + DRM_DEBUG("Added std modes on %s\n", drm_get_connector_name(connector)); + list_for_each_entry_safe(mode, t, &connector->modes, head) { + mode->vrefresh = drm_mode_vrefresh(mode); + + drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); + drm_mode_debug_printmodeline(mode); + } +} /** * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config @@ -237,6 +261,8 @@ static void drm_enable_connectors(struct drm_device *dev, bool *enabled) list_for_each_entry(connector, &dev->mode_config.connector_list, head) { enabled[i] = drm_connector_enabled(connector, true); + DRM_DEBUG("connector %d enabled? %s\n", connector->base.id, + enabled[i] ? "yes" : "no"); any_enabled |= enabled[i]; i++; } @@ -265,11 +291,17 @@ static bool drm_target_preferred(struct drm_device *dev, continue; } + DRM_DEBUG("looking for preferred mode on connector %d\n", + connector->base.id); + modes[i] = drm_has_preferred_mode(connector, width, height); - if (!modes[i]) { + /* No preferred modes, pick one off the list */ + if (!modes[i] && !list_empty(&connector->modes)) { list_for_each_entry(modes[i], &connector->modes, head) break; } + DRM_DEBUG("found mode %s\n", modes[i] ? modes[i]->name : + "none"); i++; } return true; @@ -369,6 +401,8 @@ static void drm_setup_crtcs(struct drm_device *dev) int width, height; int i, ret; + DRM_DEBUG("\n"); + width = dev->mode_config.max_width; height = dev->mode_config.max_height; @@ -390,6 +424,8 @@ static void drm_setup_crtcs(struct drm_device *dev) if (!ret) DRM_ERROR("Unable to find initial modes\n"); + DRM_DEBUG("picking CRTCs for %dx%d config\n", width, height); + drm_pick_crtcs(dev, crtcs, modes, 0, width, height); i = 0; @@ -403,6 +439,8 @@ static void drm_setup_crtcs(struct drm_device *dev) } if (mode && crtc) { + DRM_DEBUG("desired mode %s set on crtc %d\n", + mode->name, crtc->base.id); crtc->desired_mode = mode; connector->encoder->crtc = crtc; } else @@ -764,10 +802,31 @@ bool drm_helper_plugged_event(struct drm_device *dev) */ bool drm_helper_initial_config(struct drm_device *dev, bool can_grow) { - int ret = false; + struct drm_connector *connector; + int count = 0; - drm_helper_plugged_event(dev); - return ret; + count = drm_helper_probe_connector_modes(dev, + dev->mode_config.max_width, + dev->mode_config.max_height); + + /* + * None of the available connectors had any modes, so add some + * and try to light them up anyway + */ + if (!count) { + DRM_ERROR("connectors have no modes, using standard modes\n"); + list_for_each_entry(connector, + &dev->mode_config.connector_list, + head) + drm_helper_add_std_modes(dev, connector); + } + + drm_setup_crtcs(dev); + + /* alert the driver fb layer */ + dev->mode_config.funcs->fb_changed(dev); + + return 0; } EXPORT_SYMBOL(drm_helper_initial_config); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 0acb07f31fa..47809ac94bc 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -395,7 +395,7 @@ struct drm_connector_funcs { void (*save)(struct drm_connector *connector); void (*restore)(struct drm_connector *connector); enum drm_connector_status (*detect)(struct drm_connector *connector); - void (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height); + int (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height); int (*set_property)(struct drm_connector *connector, struct drm_property *property, uint64_t val); void (*destroy)(struct drm_connector *connector); diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index 4bc04cf460a..0c6f0e11b41 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h @@ -88,7 +88,7 @@ struct drm_connector_helper_funcs { struct drm_encoder *(*best_encoder)(struct drm_connector *connector); }; -extern void drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY); +extern int drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY); extern void drm_helper_disable_unused_functions(struct drm_device *dev); extern int drm_helper_hotplug_stage_two(struct drm_device *dev); extern bool drm_helper_initial_config(struct drm_device *dev, bool can_grow); -- cgit From 712531bfe95be42a672ebab51b55580e7d92c464 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 9 Jan 2009 13:56:14 -0800 Subject: drm: handle depth & bpp changes correctly Signed-off-by: Jesse Barnes Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc_helper.c | 48 +++++++++++++++++++++++++----------- drivers/gpu/drm/i915/intel_display.c | 2 ++ 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index e490e69db21..964c5eb1fad 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -480,6 +480,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, int saved_x, saved_y; struct drm_encoder *encoder; bool ret = true; + bool depth_changed, bpp_changed; adjusted_mode = drm_mode_duplicate(dev, mode); @@ -488,6 +489,15 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, if (!crtc->enabled) return true; + if (old_fb && crtc->fb) { + depth_changed = (old_fb->depth != crtc->fb->depth); + bpp_changed = (old_fb->bits_per_pixel != + crtc->fb->bits_per_pixel); + } else { + depth_changed = true; + bpp_changed = true; + } + saved_mode = crtc->mode; saved_x = crtc->x; saved_y = crtc->y; @@ -500,7 +510,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, crtc->y = y; if (drm_mode_equal(&saved_mode, &crtc->mode)) { - if (saved_x != crtc->x || saved_y != crtc->y) { + if (saved_x != crtc->x || saved_y != crtc->y || + depth_changed || bpp_changed) { crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y, old_fb); goto done; @@ -606,8 +617,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) struct drm_encoder **save_encoders, *new_encoder; struct drm_framebuffer *old_fb; bool save_enabled; - bool changed = false; - bool flip_or_move = false; + bool mode_changed = false; + bool fb_changed = false; struct drm_connector *connector; int count = 0, ro, fail = 0; struct drm_crtc_helper_funcs *crtc_funcs; @@ -635,7 +646,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) /* save previous config */ save_enabled = set->crtc->enabled; - /* this is meant to be num_connector not num_crtc */ + /* + * We do mode_config.num_connectors here since we'll look at the + * CRTC and encoder associated with each connector later. + */ save_crtcs = kzalloc(dev->mode_config.num_connector * sizeof(struct drm_crtc *), GFP_KERNEL); if (!save_crtcs) @@ -651,21 +665,25 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) /* We should be able to check here if the fb has the same properties * and then just flip_or_move it */ if (set->crtc->fb != set->fb) { - /* if we have no fb then its a change not a flip */ + /* If we have no fb then treat it as a full mode set */ if (set->crtc->fb == NULL) - changed = true; + mode_changed = true; + else if ((set->fb->bits_per_pixel != + set->crtc->fb->bits_per_pixel) || + set->fb->depth != set->crtc->fb->depth) + fb_changed = true; else - flip_or_move = true; + fb_changed = true; } if (set->x != set->crtc->x || set->y != set->crtc->y) - flip_or_move = true; + fb_changed = true; if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) { DRM_DEBUG("modes are different\n"); drm_mode_debug_printmodeline(&set->crtc->mode); drm_mode_debug_printmodeline(set->mode); - changed = true; + mode_changed = true; } /* a) traverse passed in connector list and get encoders for them */ @@ -688,7 +706,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) } if (new_encoder != connector->encoder) { - changed = true; + mode_changed = true; connector->encoder = new_encoder; } } @@ -715,16 +733,16 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) new_crtc = set->crtc; } if (new_crtc != connector->encoder->crtc) { - changed = true; + mode_changed = true; connector->encoder->crtc = new_crtc; } } /* mode_set_base is not a required function */ - if (flip_or_move && !crtc_funcs->mode_set_base) - changed = true; + if (fb_changed && !crtc_funcs->mode_set_base) + mode_changed = true; - if (changed) { + if (mode_changed) { old_fb = set->crtc->fb; set->crtc->fb = set->fb; set->crtc->enabled = (set->mode != NULL); @@ -743,7 +761,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) set->crtc->desired_mode = set->mode; } drm_helper_disable_unused_functions(dev); - } else if (flip_or_move) { + } else if (fb_changed) { old_fb = set->crtc->fb; if (set->crtc->fb != set->fb) set->crtc->fb = set->fb; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8ccb9c3ab86..4372acff5a0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -401,6 +401,8 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, I915_WRITE(dspstride, crtc->fb->pitch); dspcntr = I915_READ(dspcntr_reg); + /* Mask out pixel format bits in case we change it */ + dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; switch (crtc->fb->bits_per_pixel) { case 8: dspcntr |= DISPPLANE_8BPP; -- cgit From e285f3cd2c376d2336f9a383241a98266363c7d4 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 14 Jan 2009 10:53:36 -0800 Subject: drm/i915: make LVDS fixed mode a preferred mode The detected fixed panel mode really is preferred, so mark it as such and add it to the LVDS connector mode list. Signed-off-by: Jesse Barnes Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/intel_lvds.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index ccecfaf6307..2fafdcc108f 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -456,6 +456,13 @@ void intel_lvds_init(struct drm_device *dev) dev_priv->panel_fixed_mode = drm_mode_duplicate(dev, dev_priv->vbt_mode); mutex_unlock(&dev->mode_config.mutex); + if (dev_priv->panel_fixed_mode) { + dev_priv->panel_fixed_mode->type |= + DRM_MODE_TYPE_PREFERRED; + drm_mode_probed_add(connector, + dev_priv->panel_fixed_mode); + goto out; + } } /* -- cgit From 71acb5eb8d95b371f4cdd88a47f3c83c870d1c8f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 30 Dec 2008 20:31:46 +1000 Subject: drm/i915: add support for physical memory objects This is an initial patch to do support for objects which needs physical contiguous main ram, cursors and overlay registers on older chipsets. These objects are bound on cursor bin, like pinning, and we copy the data to/from the backing store object into the real one on attach/detach. notes: possible over the top in attach/detach operations. no overlay support yet. Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/i915_dma.c | 2 + drivers/gpu/drm/i915/i915_drv.h | 23 +++++ drivers/gpu/drm/i915/i915_gem.c | 189 ++++++++++++++++++++++++++++++++++- drivers/gpu/drm/i915/intel_display.c | 32 ++++-- 4 files changed, 233 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 868f574363a..bbadf1c0414 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1160,6 +1160,8 @@ int i915_driver_unload(struct drm_device *dev) if (drm_core_check_feature(dev, DRIVER_MODESET)) { intel_modeset_cleanup(dev); + i915_gem_free_all_phys_object(dev); + mutex_lock(&dev->struct_mutex); i915_gem_cleanup_ringbuffer(dev); mutex_unlock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 563de18063f..e1351825200 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -72,6 +72,18 @@ enum pipe { #define WATCH_INACTIVE 0 #define WATCH_PWRITE 0 +#define I915_GEM_PHYS_CURSOR_0 1 +#define I915_GEM_PHYS_CURSOR_1 2 +#define I915_GEM_PHYS_OVERLAY_REGS 3 +#define I915_MAX_PHYS_OBJECT (I915_GEM_PHYS_OVERLAY_REGS) + +struct drm_i915_gem_phys_object { + int id; + struct page **page_list; + drm_dma_handle_t *handle; + struct drm_gem_object *cur_obj; +}; + typedef struct _drm_i915_ring_buffer { int tail_mask; unsigned long Size; @@ -358,6 +370,9 @@ typedef struct drm_i915_private { uint32_t bit_6_swizzle_x; /** Bit 6 swizzling required for Y tiling */ uint32_t bit_6_swizzle_y; + + /* storage for physical objects */ + struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT]; } mm; } drm_i915_private_t; @@ -436,6 +451,9 @@ struct drm_i915_gem_object { /** User space pin count and filp owning the pin */ uint32_t user_pin_count; struct drm_file *pin_filp; + + /** for phy allocated objects */ + struct drm_i915_gem_phys_object *phys_obj; }; /** @@ -598,6 +616,11 @@ int i915_gem_do_init(struct drm_device *dev, unsigned long start, int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write); +int i915_gem_attach_phys_object(struct drm_device *dev, + struct drm_gem_object *obj, int id); +void i915_gem_detach_phys_object(struct drm_device *dev, + struct drm_gem_object *obj); +void i915_gem_free_all_phys_object(struct drm_device *dev); /* i915_gem_tiling.c */ void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 1384d668655..96316fd4723 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -55,6 +55,9 @@ static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, static void i915_gem_object_get_fence_reg(struct drm_gem_object *obj); static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); static int i915_gem_evict_something(struct drm_device *dev); +static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, + struct drm_i915_gem_pwrite *args, + struct drm_file *file_priv); int i915_gem_do_init(struct drm_device *dev, unsigned long start, unsigned long end) @@ -386,8 +389,10 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, * pread/pwrite currently are reading and writing from the CPU * perspective, requiring manual detiling by the client. */ - if (obj_priv->tiling_mode == I915_TILING_NONE && - dev->gtt_total != 0) + if (obj_priv->phys_obj) + ret = i915_gem_phys_pwrite(dev, obj, args, file_priv); + else if (obj_priv->tiling_mode == I915_TILING_NONE && + dev->gtt_total != 0) ret = i915_gem_gtt_pwrite(dev, obj, args, file_priv); else ret = i915_gem_shmem_pwrite(dev, obj, args, file_priv); @@ -2858,6 +2863,9 @@ void i915_gem_free_object(struct drm_gem_object *obj) while (obj_priv->pin_count > 0) i915_gem_object_unpin(obj); + if (obj_priv->phys_obj) + i915_gem_detach_phys_object(dev, obj); + i915_gem_object_unbind(obj); list = &obj->map_list; @@ -3293,3 +3301,180 @@ i915_gem_load(struct drm_device *dev) i915_gem_detect_bit_6_swizzle(dev); } + +/* + * Create a physically contiguous memory object for this object + * e.g. for cursor + overlay regs + */ +int i915_gem_init_phys_object(struct drm_device *dev, + int id, int size) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_i915_gem_phys_object *phys_obj; + int ret; + + if (dev_priv->mm.phys_objs[id - 1] || !size) + return 0; + + phys_obj = drm_calloc(1, sizeof(struct drm_i915_gem_phys_object), DRM_MEM_DRIVER); + if (!phys_obj) + return -ENOMEM; + + phys_obj->id = id; + + phys_obj->handle = drm_pci_alloc(dev, size, 0, 0xffffffff); + if (!phys_obj->handle) { + ret = -ENOMEM; + goto kfree_obj; + } +#ifdef CONFIG_X86 + set_memory_wc((unsigned long)phys_obj->handle->vaddr, phys_obj->handle->size / PAGE_SIZE); +#endif + + dev_priv->mm.phys_objs[id - 1] = phys_obj; + + return 0; +kfree_obj: + drm_free(phys_obj, sizeof(struct drm_i915_gem_phys_object), DRM_MEM_DRIVER); + return ret; +} + +void i915_gem_free_phys_object(struct drm_device *dev, int id) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_i915_gem_phys_object *phys_obj; + + if (!dev_priv->mm.phys_objs[id - 1]) + return; + + phys_obj = dev_priv->mm.phys_objs[id - 1]; + if (phys_obj->cur_obj) { + i915_gem_detach_phys_object(dev, phys_obj->cur_obj); + } + +#ifdef CONFIG_X86 + set_memory_wb((unsigned long)phys_obj->handle->vaddr, phys_obj->handle->size / PAGE_SIZE); +#endif + drm_pci_free(dev, phys_obj->handle); + kfree(phys_obj); + dev_priv->mm.phys_objs[id - 1] = NULL; +} + +void i915_gem_free_all_phys_object(struct drm_device *dev) +{ + int i; + + for (i = 0; i < I915_MAX_PHYS_OBJECT; i++) + i915_gem_free_phys_object(dev, i); +} + +void i915_gem_detach_phys_object(struct drm_device *dev, + struct drm_gem_object *obj) +{ + struct drm_i915_gem_object *obj_priv; + int i; + int ret; + int page_count; + + obj_priv = obj->driver_private; + if (!obj_priv->phys_obj) + return; + + ret = i915_gem_object_get_page_list(obj); + if (ret) + goto out; + + page_count = obj->size / PAGE_SIZE; + + for (i = 0; i < page_count; i++) { + char *dst = kmap_atomic(obj_priv->page_list[i], KM_USER0); + char *src = obj_priv->phys_obj->handle->vaddr + (i * PAGE_SIZE); + + memcpy(dst, src, PAGE_SIZE); + kunmap_atomic(dst, KM_USER0); + } + drm_clflush_pages(obj_priv->page_list, page_count); + drm_agp_chipset_flush(dev); +out: + obj_priv->phys_obj->cur_obj = NULL; + obj_priv->phys_obj = NULL; +} + +int +i915_gem_attach_phys_object(struct drm_device *dev, + struct drm_gem_object *obj, int id) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_i915_gem_object *obj_priv; + int ret = 0; + int page_count; + int i; + + if (id > I915_MAX_PHYS_OBJECT) + return -EINVAL; + + obj_priv = obj->driver_private; + + if (obj_priv->phys_obj) { + if (obj_priv->phys_obj->id == id) + return 0; + i915_gem_detach_phys_object(dev, obj); + } + + + /* create a new object */ + if (!dev_priv->mm.phys_objs[id - 1]) { + ret = i915_gem_init_phys_object(dev, id, + obj->size); + if (ret) { + DRM_ERROR("failed to init phys object %d size: %d\n", id, obj->size); + goto out; + } + } + + /* bind to the object */ + obj_priv->phys_obj = dev_priv->mm.phys_objs[id - 1]; + obj_priv->phys_obj->cur_obj = obj; + + ret = i915_gem_object_get_page_list(obj); + if (ret) { + DRM_ERROR("failed to get page list\n"); + goto out; + } + + page_count = obj->size / PAGE_SIZE; + + for (i = 0; i < page_count; i++) { + char *src = kmap_atomic(obj_priv->page_list[i], KM_USER0); + char *dst = obj_priv->phys_obj->handle->vaddr + (i * PAGE_SIZE); + + memcpy(dst, src, PAGE_SIZE); + kunmap_atomic(src, KM_USER0); + } + + return 0; +out: + return ret; +} + +static int +i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, + struct drm_i915_gem_pwrite *args, + struct drm_file *file_priv) +{ + struct drm_i915_gem_object *obj_priv = obj->driver_private; + void *obj_addr; + int ret; + char __user *user_data; + + user_data = (char __user *) (uintptr_t) args->data_ptr; + obj_addr = obj_priv->phys_obj->handle->vaddr + args->offset; + + DRM_ERROR("obj_addr %p, %lld\n", obj_addr, args->size); + ret = copy_from_user(obj_addr, user_data, args->size); + if (ret) + return -EFAULT; + + drm_agp_chipset_flush(dev); + return 0; +} diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4372acff5a0..114a7a1a874 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1020,17 +1020,23 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, return -ENOMEM; } - if (dev_priv->cursor_needs_physical) { - addr = dev->agp->base + obj_priv->gtt_offset; - } else { + /* we only need to pin inside GTT if cursor is non-phy */ + if (!dev_priv->cursor_needs_physical) { + ret = i915_gem_object_pin(bo, PAGE_SIZE); + if (ret) { + DRM_ERROR("failed to pin cursor bo\n"); + drm_gem_object_unreference(bo); + return ret; + } addr = obj_priv->gtt_offset; - } - - ret = i915_gem_object_pin(bo, PAGE_SIZE); - if (ret) { - DRM_ERROR("failed to pin cursor bo\n"); - drm_gem_object_unreference(bo); - return ret; + } else { + ret = i915_gem_attach_phys_object(dev, bo, (pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1); + if (ret) { + DRM_ERROR("failed to attach phys object\n"); + drm_gem_object_unreference(bo); + return ret; + } + addr = obj_priv->phys_obj->handle->busaddr; } temp = 0; @@ -1043,7 +1049,11 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, I915_WRITE(base, addr); if (intel_crtc->cursor_bo) { - i915_gem_object_unpin(intel_crtc->cursor_bo); + if (dev_priv->cursor_needs_physical) { + if (intel_crtc->cursor_bo != bo) + i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo); + } else + i915_gem_object_unpin(intel_crtc->cursor_bo); drm_gem_object_unreference(intel_crtc->cursor_bo); } -- cgit From 34b8686e12eaf9878aaab89e92222060c3e7cc48 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 15 Jan 2009 14:03:07 +1000 Subject: drm/i915: lock correct mutex around object unreference. This makes sure the mutex is held around the unreference. Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/intel_display.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 114a7a1a874..31c3732b7a6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1016,8 +1016,8 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, if (bo->size < width * height * 4) { DRM_ERROR("buffer is to small\n"); - drm_gem_object_unreference(bo); - return -ENOMEM; + ret = -ENOMEM; + goto fail; } /* we only need to pin inside GTT if cursor is non-phy */ @@ -1025,16 +1025,14 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, ret = i915_gem_object_pin(bo, PAGE_SIZE); if (ret) { DRM_ERROR("failed to pin cursor bo\n"); - drm_gem_object_unreference(bo); - return ret; + goto fail; } addr = obj_priv->gtt_offset; } else { ret = i915_gem_attach_phys_object(dev, bo, (pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1); if (ret) { DRM_ERROR("failed to attach phys object\n"); - drm_gem_object_unreference(bo); - return ret; + goto fail; } addr = obj_priv->phys_obj->handle->busaddr; } @@ -1054,13 +1052,20 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo); } else i915_gem_object_unpin(intel_crtc->cursor_bo); + mutex_lock(&dev->struct_mutex); drm_gem_object_unreference(intel_crtc->cursor_bo); + mutex_unlock(&dev->struct_mutex); } intel_crtc->cursor_addr = addr; intel_crtc->cursor_bo = bo; return 0; +fail: + mutex_lock(&dev->struct_mutex); + drm_gem_object_unreference(bo); + mutex_unlock(&dev->struct_mutex); + return ret; } static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) -- cgit From 2de686d227e8869547683de659d5419061c2c518 Mon Sep 17 00:00:00 2001 From: Luke Yelavich Date: Fri, 16 Jan 2009 15:08:02 +1100 Subject: ALSA: hda - add quirks for some 82801H variants to use ALC883_MITAC Add the 82801H variants 1071:8227 and 8086:2503 to use ALC883_MITAC Reference: Ubuntu bug 210865 https://bugs.launchpad.net/bugs/210865 Signed-off-by: Luke Yelavich Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 82dd0843197..5d249a547fb 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -8478,6 +8478,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), + SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC), SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), @@ -8526,6 +8527,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), + SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC), SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL), SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), {} -- cgit From 49148020bcb6910ce71417bd990a5ce7017f9bd3 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Fri, 16 Jan 2009 21:58:10 +1000 Subject: m68k,m68knommu: merge header files Merge header files for m68k and m68knommu to the single location: arch/m68k/include/asm The majority of this patch was the result of the script that is included in the changelog below. The script was originally written by Arnd Bergman and exten by me to cover a few more files. When the header files differed the script uses the following: The original m68k file is named _mm.h [mm for memory manager] The m68knommu file is named _no.h [no for no memory manager] The files uses the following include guard: This include gaurd works as the m68knommu toolchain set the __uClinux__ symbol - so this should work in userspace too. Merging the header files for m68k and m68knommu exposes the (unexpected?) ABI differences thus it is easier to actually identify these and thus to fix them. The commit has been build tested with both a m68k and a m68knommu toolchain - with success. The commit has also been tested with "make headers_check" and this patch fixes make headers_check for m68knommu. The script used: TARGET=arch/m68k/include/asm SOURCE=arch/m68knommu/include/asm INCLUDE="cachectl.h errno.h fcntl.h hwtest.h ioctls.h ipcbuf.h \ linkage.h math-emu.h md.h mman.h movs.h msgbuf.h openprom.h \ oplib.h poll.h posix_types.h resource.h rtc.h sembuf.h shmbuf.h \ shm.h shmparam.h socket.h sockios.h spinlock.h statfs.h stat.h \ termbits.h termios.h tlb.h types.h user.h" EQUAL="auxvec.h cputime.h device.h emergency-restart.h futex.h \ ioctl.h irq_regs.h kdebug.h local.h mutex.h percpu.h \ sections.h topology.h" NOMUUFILES="anchor.h bootstd.h coldfire.h commproc.h dbg.h \ elia.h flat.h m5206sim.h m520xsim.h m523xsim.h m5249sim.h \ m5272sim.h m527xsim.h m528xsim.h m5307sim.h m532xsim.h \ m5407sim.h m68360_enet.h m68360.h m68360_pram.h m68360_quicc.h \ m68360_regs.h MC68328.h MC68332.h MC68EZ328.h MC68VZ328.h \ mcfcache.h mcfdma.h mcfmbus.h mcfne.h mcfpci.h mcfpit.h \ mcfsim.h mcfsmc.h mcftimer.h mcfuart.h mcfwdebug.h \ nettel.h quicc_simple.h smp.h" FILES="atomic.h bitops.h bootinfo.h bug.h bugs.h byteorder.h cache.h \ cacheflush.h checksum.h current.h delay.h div64.h \ dma-mapping.h dma.h elf.h entry.h fb.h fpu.h hardirq.h hw_irq.h io.h \ irq.h kmap_types.h machdep.h mc146818rtc.h mmu.h mmu_context.h \ module.h page.h page_offset.h param.h pci.h pgalloc.h \ pgtable.h processor.h ptrace.h scatterlist.h segment.h \ setup.h sigcontext.h siginfo.h signal.h string.h system.h swab.h \ thread_info.h timex.h tlbflush.h traps.h uaccess.h ucontext.h \ unaligned.h unistd.h" mergefile() { BASE=${1%.h} git mv ${SOURCE}/$1 ${TARGET}/${BASE}_no.h git mv ${TARGET}/$1 ${TARGET}/${BASE}_mm.h cat << EOF > ${TARGET}/$1 EOF git add ${TARGET}/$1 } set -e mkdir -p ${TARGET} git mv include/asm-m68k/* ${TARGET} rmdir include/asm-m68k git rm ${SOURCE}/Kbuild for F in $INCLUDE $EQUAL; do git rm ${SOURCE}/$F done for F in $NOMUUFILES; do git mv ${SOURCE}/$F ${TARGET}/$F done for F in $FILES ; do mergefile $F done rmdir arch/m68knommu/include/asm rmdir arch/m68knommu/include Cc: Arnd Bergmann Cc: Geert Uytterhoeven Signed-off-by: Sam Ravnborg Signed-off-by: Greg Ungerer --- Makefile | 4 + arch/m68k/include/asm/Kbuild | 3 + arch/m68k/include/asm/MC68328.h | 1266 ++++++++++++++ arch/m68k/include/asm/MC68332.h | 152 ++ arch/m68k/include/asm/MC68EZ328.h | 1253 +++++++++++++ arch/m68k/include/asm/MC68VZ328.h | 1349 ++++++++++++++ arch/m68k/include/asm/a.out-core.h | 67 + arch/m68k/include/asm/a.out.h | 20 + arch/m68k/include/asm/adb_iop.h | 44 + arch/m68k/include/asm/amigahw.h | 350 ++++ arch/m68k/include/asm/amigaints.h | 113 ++ arch/m68k/include/asm/amigayle.h | 107 ++ arch/m68k/include/asm/amipcmcia.h | 110 ++ arch/m68k/include/asm/anchor.h | 112 ++ arch/m68k/include/asm/apollodma.h | 248 +++ arch/m68k/include/asm/apollohw.h | 108 ++ arch/m68k/include/asm/atafd.h | 12 + arch/m68k/include/asm/atafdreg.h | 79 + arch/m68k/include/asm/atari_joystick.h | 22 + arch/m68k/include/asm/atari_stdma.h | 22 + arch/m68k/include/asm/atari_stram.h | 17 + arch/m68k/include/asm/atarihw.h | 807 +++++++++ arch/m68k/include/asm/atariints.h | 204 +++ arch/m68k/include/asm/atarikb.h | 46 + arch/m68k/include/asm/atomic.h | 5 + arch/m68k/include/asm/atomic_mm.h | 196 +++ arch/m68k/include/asm/atomic_no.h | 155 ++ arch/m68k/include/asm/auxvec.h | 4 + arch/m68k/include/asm/bitops.h | 5 + arch/m68k/include/asm/bitops_mm.h | 464 +++++ arch/m68k/include/asm/bitops_no.h | 337 ++++ arch/m68k/include/asm/blinken.h | 32 + arch/m68k/include/asm/bootinfo.h | 5 + arch/m68k/include/asm/bootinfo_mm.h | 378 ++++ arch/m68k/include/asm/bootinfo_no.h | 2 + arch/m68k/include/asm/bootstd.h | 132 ++ arch/m68k/include/asm/bug.h | 5 + arch/m68k/include/asm/bug_mm.h | 29 + arch/m68k/include/asm/bug_no.h | 4 + arch/m68k/include/asm/bugs.h | 5 + arch/m68k/include/asm/bugs_mm.h | 14 + arch/m68k/include/asm/bugs_no.h | 16 + arch/m68k/include/asm/bvme6000hw.h | 150 ++ arch/m68k/include/asm/byteorder.h | 5 + arch/m68k/include/asm/byteorder_mm.h | 7 + arch/m68k/include/asm/byteorder_no.h | 7 + arch/m68k/include/asm/cache.h | 5 + arch/m68k/include/asm/cache_mm.h | 11 + arch/m68k/include/asm/cache_no.h | 12 + arch/m68k/include/asm/cachectl.h | 14 + arch/m68k/include/asm/cacheflush.h | 5 + arch/m68k/include/asm/cacheflush_mm.h | 156 ++ arch/m68k/include/asm/cacheflush_no.h | 84 + arch/m68k/include/asm/checksum.h | 5 + arch/m68k/include/asm/checksum_mm.h | 148 ++ arch/m68k/include/asm/checksum_no.h | 132 ++ arch/m68k/include/asm/coldfire.h | 51 + arch/m68k/include/asm/commproc.h | 703 ++++++++ arch/m68k/include/asm/contregs.h | 53 + arch/m68k/include/asm/cputime.h | 6 + arch/m68k/include/asm/current.h | 5 + arch/m68k/include/asm/current_mm.h | 6 + arch/m68k/include/asm/current_no.h | 24 + arch/m68k/include/asm/dbg.h | 6 + arch/m68k/include/asm/delay.h | 5 + arch/m68k/include/asm/delay_mm.h | 57 + arch/m68k/include/asm/delay_no.h | 76 + arch/m68k/include/asm/device.h | 7 + arch/m68k/include/asm/div64.h | 5 + arch/m68k/include/asm/div64_mm.h | 28 + arch/m68k/include/asm/div64_no.h | 1 + arch/m68k/include/asm/dma-mapping.h | 5 + arch/m68k/include/asm/dma-mapping_mm.h | 112 ++ arch/m68k/include/asm/dma-mapping_no.h | 10 + arch/m68k/include/asm/dma.h | 5 + arch/m68k/include/asm/dma_mm.h | 16 + arch/m68k/include/asm/dma_no.h | 494 ++++++ arch/m68k/include/asm/dsp56k.h | 35 + arch/m68k/include/asm/dvma.h | 240 +++ arch/m68k/include/asm/elf.h | 5 + arch/m68k/include/asm/elf_mm.h | 119 ++ arch/m68k/include/asm/elf_no.h | 110 ++ arch/m68k/include/asm/elia.h | 41 + arch/m68k/include/asm/emergency-restart.h | 6 + arch/m68k/include/asm/entry.h | 5 + arch/m68k/include/asm/entry_mm.h | 137 ++ arch/m68k/include/asm/entry_no.h | 182 ++ arch/m68k/include/asm/errno.h | 6 + arch/m68k/include/asm/fb.h | 5 + arch/m68k/include/asm/fb_mm.h | 34 + arch/m68k/include/asm/fb_no.h | 12 + arch/m68k/include/asm/fbio.h | 330 ++++ arch/m68k/include/asm/fcntl.h | 11 + arch/m68k/include/asm/flat.h | 17 + arch/m68k/include/asm/floppy.h | 254 +++ arch/m68k/include/asm/fpu.h | 5 + arch/m68k/include/asm/fpu_mm.h | 21 + arch/m68k/include/asm/fpu_no.h | 21 + arch/m68k/include/asm/futex.h | 6 + arch/m68k/include/asm/hardirq.h | 5 + arch/m68k/include/asm/hardirq_mm.h | 16 + arch/m68k/include/asm/hardirq_no.h | 27 + arch/m68k/include/asm/hp300hw.h | 25 + arch/m68k/include/asm/hw_irq.h | 5 + arch/m68k/include/asm/hw_irq_mm.h | 6 + arch/m68k/include/asm/hw_irq_no.h | 4 + arch/m68k/include/asm/hwtest.h | 15 + arch/m68k/include/asm/ide.h | 130 ++ arch/m68k/include/asm/idprom.h | 27 + arch/m68k/include/asm/intersil.h | 48 + arch/m68k/include/asm/io.h | 5 + arch/m68k/include/asm/io_mm.h | 369 ++++ arch/m68k/include/asm/io_no.h | 194 ++ arch/m68k/include/asm/ioctl.h | 1 + arch/m68k/include/asm/ioctls.h | 84 + arch/m68k/include/asm/ipcbuf.h | 29 + arch/m68k/include/asm/irq.h | 5 + arch/m68k/include/asm/irq_mm.h | 125 ++ arch/m68k/include/asm/irq_no.h | 26 + arch/m68k/include/asm/irq_regs.h | 1 + arch/m68k/include/asm/kdebug.h | 1 + arch/m68k/include/asm/kmap_types.h | 5 + arch/m68k/include/asm/kmap_types_mm.h | 21 + arch/m68k/include/asm/kmap_types_no.h | 21 + arch/m68k/include/asm/linkage.h | 7 + arch/m68k/include/asm/local.h | 6 + arch/m68k/include/asm/m5206sim.h | 131 ++ arch/m68k/include/asm/m520xsim.h | 63 + arch/m68k/include/asm/m523xsim.h | 45 + arch/m68k/include/asm/m5249sim.h | 209 +++ arch/m68k/include/asm/m5272sim.h | 78 + arch/m68k/include/asm/m527xsim.h | 74 + arch/m68k/include/asm/m528xsim.h | 159 ++ arch/m68k/include/asm/m5307sim.h | 181 ++ arch/m68k/include/asm/m532xsim.h | 2238 ++++++++++++++++++++++++ arch/m68k/include/asm/m5407sim.h | 157 ++ arch/m68k/include/asm/m68360.h | 13 + arch/m68k/include/asm/m68360_enet.h | 177 ++ arch/m68k/include/asm/m68360_pram.h | 431 +++++ arch/m68k/include/asm/m68360_quicc.h | 362 ++++ arch/m68k/include/asm/m68360_regs.h | 408 +++++ arch/m68k/include/asm/mac_asc.h | 27 + arch/m68k/include/asm/mac_baboon.h | 32 + arch/m68k/include/asm/mac_iop.h | 162 ++ arch/m68k/include/asm/mac_mouse.h | 23 + arch/m68k/include/asm/mac_oss.h | 94 + arch/m68k/include/asm/mac_psc.h | 248 +++ arch/m68k/include/asm/mac_via.h | 267 +++ arch/m68k/include/asm/machdep.h | 5 + arch/m68k/include/asm/machdep_mm.h | 35 + arch/m68k/include/asm/machdep_no.h | 26 + arch/m68k/include/asm/machines.h | 85 + arch/m68k/include/asm/machw.h | 49 + arch/m68k/include/asm/macintosh.h | 135 ++ arch/m68k/include/asm/macints.h | 155 ++ arch/m68k/include/asm/math-emu.h | 315 ++++ arch/m68k/include/asm/mc146818rtc.h | 5 + arch/m68k/include/asm/mc146818rtc_mm.h | 26 + arch/m68k/include/asm/mc146818rtc_no.h | 9 + arch/m68k/include/asm/mcfcache.h | 150 ++ arch/m68k/include/asm/mcfdma.h | 144 ++ arch/m68k/include/asm/mcfmbus.h | 77 + arch/m68k/include/asm/mcfne.h | 325 ++++ arch/m68k/include/asm/mcfpci.h | 119 ++ arch/m68k/include/asm/mcfpit.h | 64 + arch/m68k/include/asm/mcfsim.h | 126 ++ arch/m68k/include/asm/mcfsmc.h | 187 ++ arch/m68k/include/asm/mcftimer.h | 80 + arch/m68k/include/asm/mcfuart.h | 216 +++ arch/m68k/include/asm/mcfwdebug.h | 118 ++ arch/m68k/include/asm/md.h | 13 + arch/m68k/include/asm/mman.h | 17 + arch/m68k/include/asm/mmu.h | 5 + arch/m68k/include/asm/mmu_context.h | 5 + arch/m68k/include/asm/mmu_context_mm.h | 154 ++ arch/m68k/include/asm/mmu_context_no.h | 33 + arch/m68k/include/asm/mmu_mm.h | 7 + arch/m68k/include/asm/mmu_no.h | 10 + arch/m68k/include/asm/mmzone.h | 9 + arch/m68k/include/asm/module.h | 5 + arch/m68k/include/asm/module_mm.h | 39 + arch/m68k/include/asm/module_no.h | 11 + arch/m68k/include/asm/motorola_pgalloc.h | 109 ++ arch/m68k/include/asm/motorola_pgtable.h | 291 +++ arch/m68k/include/asm/movs.h | 55 + arch/m68k/include/asm/msgbuf.h | 31 + arch/m68k/include/asm/mutex.h | 9 + arch/m68k/include/asm/mvme147hw.h | 113 ++ arch/m68k/include/asm/mvme16xhw.h | 111 ++ arch/m68k/include/asm/nettel.h | 108 ++ arch/m68k/include/asm/nubus.h | 46 + arch/m68k/include/asm/openprom.h | 312 ++++ arch/m68k/include/asm/oplib.h | 291 +++ arch/m68k/include/asm/page.h | 5 + arch/m68k/include/asm/page_mm.h | 228 +++ arch/m68k/include/asm/page_no.h | 77 + arch/m68k/include/asm/page_offset.h | 5 + arch/m68k/include/asm/page_offset_mm.h | 8 + arch/m68k/include/asm/page_offset_no.h | 5 + arch/m68k/include/asm/param.h | 5 + arch/m68k/include/asm/param_mm.h | 22 + arch/m68k/include/asm/param_no.h | 22 + arch/m68k/include/asm/parport.h | 26 + arch/m68k/include/asm/pci.h | 5 + arch/m68k/include/asm/pci_mm.h | 12 + arch/m68k/include/asm/pci_no.h | 29 + arch/m68k/include/asm/percpu.h | 6 + arch/m68k/include/asm/pgalloc.h | 5 + arch/m68k/include/asm/pgalloc_mm.h | 19 + arch/m68k/include/asm/pgalloc_no.h | 8 + arch/m68k/include/asm/pgtable.h | 5 + arch/m68k/include/asm/pgtable_mm.h | 166 ++ arch/m68k/include/asm/pgtable_no.h | 70 + arch/m68k/include/asm/poll.h | 9 + arch/m68k/include/asm/posix_types.h | 61 + arch/m68k/include/asm/processor.h | 5 + arch/m68k/include/asm/processor_mm.h | 130 ++ arch/m68k/include/asm/processor_no.h | 143 ++ arch/m68k/include/asm/ptrace.h | 5 + arch/m68k/include/asm/ptrace_mm.h | 80 + arch/m68k/include/asm/ptrace_no.h | 87 + arch/m68k/include/asm/q40_master.h | 69 + arch/m68k/include/asm/q40ints.h | 29 + arch/m68k/include/asm/quicc_simple.h | 52 + arch/m68k/include/asm/raw_io.h | 347 ++++ arch/m68k/include/asm/resource.h | 6 + arch/m68k/include/asm/rtc.h | 76 + arch/m68k/include/asm/sbus.h | 45 + arch/m68k/include/asm/scatterlist.h | 5 + arch/m68k/include/asm/scatterlist_mm.h | 23 + arch/m68k/include/asm/scatterlist_no.h | 22 + arch/m68k/include/asm/sections.h | 6 + arch/m68k/include/asm/segment.h | 5 + arch/m68k/include/asm/segment_mm.h | 57 + arch/m68k/include/asm/segment_no.h | 51 + arch/m68k/include/asm/sembuf.h | 25 + arch/m68k/include/asm/serial.h | 33 + arch/m68k/include/asm/setup.h | 5 + arch/m68k/include/asm/setup_mm.h | 376 ++++ arch/m68k/include/asm/setup_no.h | 10 + arch/m68k/include/asm/shm.h | 31 + arch/m68k/include/asm/shmbuf.h | 42 + arch/m68k/include/asm/shmparam.h | 6 + arch/m68k/include/asm/sigcontext.h | 5 + arch/m68k/include/asm/sigcontext_mm.h | 19 + arch/m68k/include/asm/sigcontext_no.h | 17 + arch/m68k/include/asm/siginfo.h | 5 + arch/m68k/include/asm/siginfo_mm.h | 92 + arch/m68k/include/asm/siginfo_no.h | 6 + arch/m68k/include/asm/signal.h | 5 + arch/m68k/include/asm/signal_mm.h | 206 +++ arch/m68k/include/asm/signal_no.h | 159 ++ arch/m68k/include/asm/smp.h | 1 + arch/m68k/include/asm/socket.h | 57 + arch/m68k/include/asm/sockios.h | 13 + arch/m68k/include/asm/spinlock.h | 6 + arch/m68k/include/asm/stat.h | 77 + arch/m68k/include/asm/statfs.h | 6 + arch/m68k/include/asm/string.h | 5 + arch/m68k/include/asm/string_mm.h | 131 ++ arch/m68k/include/asm/string_no.h | 126 ++ arch/m68k/include/asm/sun3-head.h | 10 + arch/m68k/include/asm/sun3_pgalloc.h | 102 ++ arch/m68k/include/asm/sun3_pgtable.h | 234 +++ arch/m68k/include/asm/sun3ints.h | 37 + arch/m68k/include/asm/sun3mmu.h | 171 ++ arch/m68k/include/asm/sun3x.h | 27 + arch/m68k/include/asm/sun3xflop.h | 263 +++ arch/m68k/include/asm/sun3xprom.h | 43 + arch/m68k/include/asm/suspend.h | 6 + arch/m68k/include/asm/swab.h | 0 arch/m68k/include/asm/swab_mm.h | 16 + arch/m68k/include/asm/swab_no.h | 24 + arch/m68k/include/asm/system.h | 5 + arch/m68k/include/asm/system_mm.h | 218 +++ arch/m68k/include/asm/system_no.h | 324 ++++ arch/m68k/include/asm/termbits.h | 200 +++ arch/m68k/include/asm/termios.h | 92 + arch/m68k/include/asm/thread_info.h | 5 + arch/m68k/include/asm/thread_info_mm.h | 57 + arch/m68k/include/asm/thread_info_no.h | 100 ++ arch/m68k/include/asm/timex.h | 5 + arch/m68k/include/asm/timex_mm.h | 18 + arch/m68k/include/asm/timex_no.h | 23 + arch/m68k/include/asm/tlb.h | 20 + arch/m68k/include/asm/tlbflush.h | 5 + arch/m68k/include/asm/tlbflush_mm.h | 219 +++ arch/m68k/include/asm/tlbflush_no.h | 55 + arch/m68k/include/asm/topology.h | 6 + arch/m68k/include/asm/traps.h | 5 + arch/m68k/include/asm/traps_mm.h | 272 +++ arch/m68k/include/asm/traps_no.h | 154 ++ arch/m68k/include/asm/types.h | 37 + arch/m68k/include/asm/uaccess.h | 5 + arch/m68k/include/asm/uaccess_mm.h | 374 ++++ arch/m68k/include/asm/uaccess_no.h | 181 ++ arch/m68k/include/asm/ucontext.h | 5 + arch/m68k/include/asm/ucontext_mm.h | 30 + arch/m68k/include/asm/ucontext_no.h | 32 + arch/m68k/include/asm/unaligned.h | 5 + arch/m68k/include/asm/unaligned_mm.h | 13 + arch/m68k/include/asm/unaligned_no.h | 25 + arch/m68k/include/asm/unistd.h | 5 + arch/m68k/include/asm/unistd_mm.h | 374 ++++ arch/m68k/include/asm/unistd_no.h | 372 ++++ arch/m68k/include/asm/user.h | 86 + arch/m68k/include/asm/virtconvert.h | 48 + arch/m68k/include/asm/xor.h | 1 + arch/m68k/include/asm/zorro.h | 45 + arch/m68knommu/include/asm/Kbuild | 3 - arch/m68knommu/include/asm/MC68328.h | 1266 -------------- arch/m68knommu/include/asm/MC68332.h | 152 -- arch/m68knommu/include/asm/MC68EZ328.h | 1253 ------------- arch/m68knommu/include/asm/MC68VZ328.h | 1349 -------------- arch/m68knommu/include/asm/anchor.h | 112 -- arch/m68knommu/include/asm/atomic.h | 155 -- arch/m68knommu/include/asm/auxvec.h | 4 - arch/m68knommu/include/asm/bitops.h | 337 ---- arch/m68knommu/include/asm/bootinfo.h | 2 - arch/m68knommu/include/asm/bootstd.h | 132 -- arch/m68knommu/include/asm/bug.h | 4 - arch/m68knommu/include/asm/bugs.h | 16 - arch/m68knommu/include/asm/byteorder.h | 7 - arch/m68knommu/include/asm/cache.h | 12 - arch/m68knommu/include/asm/cachectl.h | 1 - arch/m68knommu/include/asm/cacheflush.h | 84 - arch/m68knommu/include/asm/checksum.h | 132 -- arch/m68knommu/include/asm/coldfire.h | 51 - arch/m68knommu/include/asm/commproc.h | 703 -------- arch/m68knommu/include/asm/cputime.h | 6 - arch/m68knommu/include/asm/current.h | 24 - arch/m68knommu/include/asm/dbg.h | 6 - arch/m68knommu/include/asm/delay.h | 76 - arch/m68knommu/include/asm/device.h | 7 - arch/m68knommu/include/asm/div64.h | 1 - arch/m68knommu/include/asm/dma-mapping.h | 10 - arch/m68knommu/include/asm/dma.h | 494 ------ arch/m68knommu/include/asm/elf.h | 110 -- arch/m68knommu/include/asm/elia.h | 41 - arch/m68knommu/include/asm/emergency-restart.h | 6 - arch/m68knommu/include/asm/entry.h | 182 -- arch/m68knommu/include/asm/errno.h | 1 - arch/m68knommu/include/asm/fb.h | 12 - arch/m68knommu/include/asm/fcntl.h | 1 - arch/m68knommu/include/asm/flat.h | 17 - arch/m68knommu/include/asm/fpu.h | 21 - arch/m68knommu/include/asm/futex.h | 6 - arch/m68knommu/include/asm/hardirq.h | 27 - arch/m68knommu/include/asm/hw_irq.h | 4 - arch/m68knommu/include/asm/hwtest.h | 1 - arch/m68knommu/include/asm/io.h | 194 -- arch/m68knommu/include/asm/ioctl.h | 1 - arch/m68knommu/include/asm/ioctls.h | 1 - arch/m68knommu/include/asm/ipcbuf.h | 1 - arch/m68knommu/include/asm/irq.h | 26 - arch/m68knommu/include/asm/irq_regs.h | 1 - arch/m68knommu/include/asm/kdebug.h | 1 - arch/m68knommu/include/asm/kmap_types.h | 21 - arch/m68knommu/include/asm/linkage.h | 1 - arch/m68knommu/include/asm/local.h | 6 - arch/m68knommu/include/asm/m5206sim.h | 131 -- arch/m68knommu/include/asm/m520xsim.h | 63 - arch/m68knommu/include/asm/m523xsim.h | 45 - arch/m68knommu/include/asm/m5249sim.h | 209 --- arch/m68knommu/include/asm/m5272sim.h | 78 - arch/m68knommu/include/asm/m527xsim.h | 74 - arch/m68knommu/include/asm/m528xsim.h | 159 -- arch/m68knommu/include/asm/m5307sim.h | 181 -- arch/m68knommu/include/asm/m532xsim.h | 2238 ------------------------ arch/m68knommu/include/asm/m5407sim.h | 157 -- arch/m68knommu/include/asm/m68360.h | 13 - arch/m68knommu/include/asm/m68360_enet.h | 177 -- arch/m68knommu/include/asm/m68360_pram.h | 431 ----- arch/m68knommu/include/asm/m68360_quicc.h | 362 ---- arch/m68knommu/include/asm/m68360_regs.h | 408 ----- arch/m68knommu/include/asm/machdep.h | 26 - arch/m68knommu/include/asm/math-emu.h | 1 - arch/m68knommu/include/asm/mc146818rtc.h | 9 - arch/m68knommu/include/asm/mcfcache.h | 150 -- arch/m68knommu/include/asm/mcfdma.h | 144 -- arch/m68knommu/include/asm/mcfmbus.h | 77 - arch/m68knommu/include/asm/mcfne.h | 325 ---- arch/m68knommu/include/asm/mcfpci.h | 119 -- arch/m68knommu/include/asm/mcfpit.h | 64 - arch/m68knommu/include/asm/mcfsim.h | 126 -- arch/m68knommu/include/asm/mcfsmc.h | 187 -- arch/m68knommu/include/asm/mcftimer.h | 80 - arch/m68knommu/include/asm/mcfuart.h | 216 --- arch/m68knommu/include/asm/mcfwdebug.h | 118 -- arch/m68knommu/include/asm/md.h | 1 - arch/m68knommu/include/asm/mman.h | 1 - arch/m68knommu/include/asm/mmu.h | 10 - arch/m68knommu/include/asm/mmu_context.h | 33 - arch/m68knommu/include/asm/module.h | 11 - arch/m68knommu/include/asm/movs.h | 1 - arch/m68knommu/include/asm/msgbuf.h | 1 - arch/m68knommu/include/asm/mutex.h | 9 - arch/m68knommu/include/asm/nettel.h | 108 -- arch/m68knommu/include/asm/openprom.h | 1 - arch/m68knommu/include/asm/oplib.h | 1 - arch/m68knommu/include/asm/page.h | 77 - arch/m68knommu/include/asm/page_offset.h | 5 - arch/m68knommu/include/asm/param.h | 22 - arch/m68knommu/include/asm/pci.h | 29 - arch/m68knommu/include/asm/percpu.h | 6 - arch/m68knommu/include/asm/pgalloc.h | 8 - arch/m68knommu/include/asm/pgtable.h | 70 - arch/m68knommu/include/asm/poll.h | 1 - arch/m68knommu/include/asm/posix_types.h | 1 - arch/m68knommu/include/asm/processor.h | 143 -- arch/m68knommu/include/asm/ptrace.h | 87 - arch/m68knommu/include/asm/quicc_simple.h | 52 - arch/m68knommu/include/asm/resource.h | 1 - arch/m68knommu/include/asm/rtc.h | 1 - arch/m68knommu/include/asm/scatterlist.h | 22 - arch/m68knommu/include/asm/sections.h | 7 - arch/m68knommu/include/asm/segment.h | 51 - arch/m68knommu/include/asm/sembuf.h | 1 - arch/m68knommu/include/asm/setup.h | 10 - arch/m68knommu/include/asm/shm.h | 1 - arch/m68knommu/include/asm/shmbuf.h | 1 - arch/m68knommu/include/asm/shmparam.h | 1 - arch/m68knommu/include/asm/sigcontext.h | 17 - arch/m68knommu/include/asm/siginfo.h | 6 - arch/m68knommu/include/asm/signal.h | 159 -- arch/m68knommu/include/asm/smp.h | 1 - arch/m68knommu/include/asm/socket.h | 1 - arch/m68knommu/include/asm/sockios.h | 1 - arch/m68knommu/include/asm/spinlock.h | 1 - arch/m68knommu/include/asm/stat.h | 1 - arch/m68knommu/include/asm/statfs.h | 1 - arch/m68knommu/include/asm/string.h | 126 -- arch/m68knommu/include/asm/swab.h | 24 - arch/m68knommu/include/asm/system.h | 324 ---- arch/m68knommu/include/asm/termbits.h | 1 - arch/m68knommu/include/asm/termios.h | 1 - arch/m68knommu/include/asm/thread_info.h | 100 -- arch/m68knommu/include/asm/timex.h | 23 - arch/m68knommu/include/asm/tlb.h | 1 - arch/m68knommu/include/asm/tlbflush.h | 55 - arch/m68knommu/include/asm/topology.h | 6 - arch/m68knommu/include/asm/traps.h | 154 -- arch/m68knommu/include/asm/types.h | 1 - arch/m68knommu/include/asm/uaccess.h | 181 -- arch/m68knommu/include/asm/ucontext.h | 32 - arch/m68knommu/include/asm/unaligned.h | 25 - arch/m68knommu/include/asm/unistd.h | 372 ---- arch/m68knommu/include/asm/user.h | 1 - include/asm-m68k/Kbuild | 3 - include/asm-m68k/a.out-core.h | 67 - include/asm-m68k/a.out.h | 20 - include/asm-m68k/adb_iop.h | 44 - include/asm-m68k/amigahw.h | 350 ---- include/asm-m68k/amigaints.h | 113 -- include/asm-m68k/amigayle.h | 107 -- include/asm-m68k/amipcmcia.h | 110 -- include/asm-m68k/apollodma.h | 248 --- include/asm-m68k/apollohw.h | 108 -- include/asm-m68k/atafd.h | 12 - include/asm-m68k/atafdreg.h | 79 - include/asm-m68k/atari_joystick.h | 22 - include/asm-m68k/atari_stdma.h | 22 - include/asm-m68k/atari_stram.h | 17 - include/asm-m68k/atarihw.h | 807 --------- include/asm-m68k/atariints.h | 204 --- include/asm-m68k/atarikb.h | 46 - include/asm-m68k/atomic.h | 196 --- include/asm-m68k/auxvec.h | 4 - include/asm-m68k/bitops.h | 464 ----- include/asm-m68k/blinken.h | 32 - include/asm-m68k/bootinfo.h | 378 ---- include/asm-m68k/bug.h | 29 - include/asm-m68k/bugs.h | 14 - include/asm-m68k/bvme6000hw.h | 150 -- include/asm-m68k/byteorder.h | 7 - include/asm-m68k/cache.h | 11 - include/asm-m68k/cachectl.h | 14 - include/asm-m68k/cacheflush.h | 156 -- include/asm-m68k/checksum.h | 148 -- include/asm-m68k/contregs.h | 53 - include/asm-m68k/cputime.h | 6 - include/asm-m68k/current.h | 6 - include/asm-m68k/delay.h | 57 - include/asm-m68k/device.h | 7 - include/asm-m68k/div64.h | 28 - include/asm-m68k/dma-mapping.h | 112 -- include/asm-m68k/dma.h | 16 - include/asm-m68k/dsp56k.h | 35 - include/asm-m68k/dvma.h | 240 --- include/asm-m68k/elf.h | 119 -- include/asm-m68k/emergency-restart.h | 6 - include/asm-m68k/entry.h | 137 -- include/asm-m68k/errno.h | 6 - include/asm-m68k/fb.h | 34 - include/asm-m68k/fbio.h | 330 ---- include/asm-m68k/fcntl.h | 11 - include/asm-m68k/floppy.h | 254 --- include/asm-m68k/fpu.h | 21 - include/asm-m68k/futex.h | 6 - include/asm-m68k/hardirq.h | 16 - include/asm-m68k/hp300hw.h | 25 - include/asm-m68k/hw_irq.h | 6 - include/asm-m68k/hwtest.h | 15 - include/asm-m68k/ide.h | 130 -- include/asm-m68k/idprom.h | 27 - include/asm-m68k/intersil.h | 48 - include/asm-m68k/io.h | 369 ---- include/asm-m68k/ioctl.h | 1 - include/asm-m68k/ioctls.h | 84 - include/asm-m68k/ipcbuf.h | 29 - include/asm-m68k/irq.h | 125 -- include/asm-m68k/irq_regs.h | 1 - include/asm-m68k/kdebug.h | 1 - include/asm-m68k/kmap_types.h | 21 - include/asm-m68k/linkage.h | 7 - include/asm-m68k/local.h | 6 - include/asm-m68k/mac_asc.h | 27 - include/asm-m68k/mac_baboon.h | 32 - include/asm-m68k/mac_iop.h | 162 -- include/asm-m68k/mac_mouse.h | 23 - include/asm-m68k/mac_oss.h | 94 - include/asm-m68k/mac_psc.h | 248 --- include/asm-m68k/mac_via.h | 267 --- include/asm-m68k/machdep.h | 35 - include/asm-m68k/machines.h | 85 - include/asm-m68k/machw.h | 49 - include/asm-m68k/macintosh.h | 135 -- include/asm-m68k/macints.h | 155 -- include/asm-m68k/math-emu.h | 315 ---- include/asm-m68k/mc146818rtc.h | 26 - include/asm-m68k/md.h | 13 - include/asm-m68k/mman.h | 17 - include/asm-m68k/mmu.h | 7 - include/asm-m68k/mmu_context.h | 154 -- include/asm-m68k/mmzone.h | 9 - include/asm-m68k/module.h | 39 - include/asm-m68k/motorola_pgalloc.h | 109 -- include/asm-m68k/motorola_pgtable.h | 291 --- include/asm-m68k/movs.h | 55 - include/asm-m68k/msgbuf.h | 31 - include/asm-m68k/mutex.h | 9 - include/asm-m68k/mvme147hw.h | 113 -- include/asm-m68k/mvme16xhw.h | 111 -- include/asm-m68k/nubus.h | 46 - include/asm-m68k/openprom.h | 312 ---- include/asm-m68k/oplib.h | 291 --- include/asm-m68k/page.h | 228 --- include/asm-m68k/page_offset.h | 8 - include/asm-m68k/param.h | 22 - include/asm-m68k/parport.h | 26 - include/asm-m68k/pci.h | 12 - include/asm-m68k/percpu.h | 6 - include/asm-m68k/pgalloc.h | 19 - include/asm-m68k/pgtable.h | 166 -- include/asm-m68k/poll.h | 9 - include/asm-m68k/posix_types.h | 61 - include/asm-m68k/processor.h | 130 -- include/asm-m68k/ptrace.h | 80 - include/asm-m68k/q40_master.h | 69 - include/asm-m68k/q40ints.h | 29 - include/asm-m68k/raw_io.h | 347 ---- include/asm-m68k/resource.h | 6 - include/asm-m68k/rtc.h | 76 - include/asm-m68k/sbus.h | 45 - include/asm-m68k/scatterlist.h | 23 - include/asm-m68k/sections.h | 6 - include/asm-m68k/segment.h | 57 - include/asm-m68k/sembuf.h | 25 - include/asm-m68k/serial.h | 33 - include/asm-m68k/setup.h | 376 ---- include/asm-m68k/shm.h | 31 - include/asm-m68k/shmbuf.h | 42 - include/asm-m68k/shmparam.h | 6 - include/asm-m68k/sigcontext.h | 19 - include/asm-m68k/siginfo.h | 92 - include/asm-m68k/signal.h | 206 --- include/asm-m68k/socket.h | 57 - include/asm-m68k/sockios.h | 13 - include/asm-m68k/spinlock.h | 6 - include/asm-m68k/stat.h | 77 - include/asm-m68k/statfs.h | 6 - include/asm-m68k/string.h | 131 -- include/asm-m68k/sun3-head.h | 10 - include/asm-m68k/sun3_pgalloc.h | 102 -- include/asm-m68k/sun3_pgtable.h | 234 --- include/asm-m68k/sun3ints.h | 37 - include/asm-m68k/sun3mmu.h | 171 -- include/asm-m68k/sun3x.h | 27 - include/asm-m68k/sun3xflop.h | 263 --- include/asm-m68k/sun3xprom.h | 43 - include/asm-m68k/suspend.h | 6 - include/asm-m68k/swab.h | 16 - include/asm-m68k/system.h | 218 --- include/asm-m68k/termbits.h | 200 --- include/asm-m68k/termios.h | 92 - include/asm-m68k/thread_info.h | 57 - include/asm-m68k/timex.h | 18 - include/asm-m68k/tlb.h | 20 - include/asm-m68k/tlbflush.h | 219 --- include/asm-m68k/topology.h | 6 - include/asm-m68k/traps.h | 272 --- include/asm-m68k/types.h | 37 - include/asm-m68k/uaccess.h | 374 ---- include/asm-m68k/ucontext.h | 30 - include/asm-m68k/unaligned.h | 13 - include/asm-m68k/unistd.h | 374 ---- include/asm-m68k/user.h | 86 - include/asm-m68k/virtconvert.h | 48 - include/asm-m68k/xor.h | 1 - include/asm-m68k/zorro.h | 45 - 610 files changed, 31202 insertions(+), 31039 deletions(-) create mode 100644 arch/m68k/include/asm/Kbuild create mode 100644 arch/m68k/include/asm/MC68328.h create mode 100644 arch/m68k/include/asm/MC68332.h create mode 100644 arch/m68k/include/asm/MC68EZ328.h create mode 100644 arch/m68k/include/asm/MC68VZ328.h create mode 100644 arch/m68k/include/asm/a.out-core.h create mode 100644 arch/m68k/include/asm/a.out.h create mode 100644 arch/m68k/include/asm/adb_iop.h create mode 100644 arch/m68k/include/asm/amigahw.h create mode 100644 arch/m68k/include/asm/amigaints.h create mode 100644 arch/m68k/include/asm/amigayle.h create mode 100644 arch/m68k/include/asm/amipcmcia.h create mode 100644 arch/m68k/include/asm/anchor.h create mode 100644 arch/m68k/include/asm/apollodma.h create mode 100644 arch/m68k/include/asm/apollohw.h create mode 100644 arch/m68k/include/asm/atafd.h create mode 100644 arch/m68k/include/asm/atafdreg.h create mode 100644 arch/m68k/include/asm/atari_joystick.h create mode 100644 arch/m68k/include/asm/atari_stdma.h create mode 100644 arch/m68k/include/asm/atari_stram.h create mode 100644 arch/m68k/include/asm/atarihw.h create mode 100644 arch/m68k/include/asm/atariints.h create mode 100644 arch/m68k/include/asm/atarikb.h create mode 100644 arch/m68k/include/asm/atomic.h create mode 100644 arch/m68k/include/asm/atomic_mm.h create mode 100644 arch/m68k/include/asm/atomic_no.h create mode 100644 arch/m68k/include/asm/auxvec.h create mode 100644 arch/m68k/include/asm/bitops.h create mode 100644 arch/m68k/include/asm/bitops_mm.h create mode 100644 arch/m68k/include/asm/bitops_no.h create mode 100644 arch/m68k/include/asm/blinken.h create mode 100644 arch/m68k/include/asm/bootinfo.h create mode 100644 arch/m68k/include/asm/bootinfo_mm.h create mode 100644 arch/m68k/include/asm/bootinfo_no.h create mode 100644 arch/m68k/include/asm/bootstd.h create mode 100644 arch/m68k/include/asm/bug.h create mode 100644 arch/m68k/include/asm/bug_mm.h create mode 100644 arch/m68k/include/asm/bug_no.h create mode 100644 arch/m68k/include/asm/bugs.h create mode 100644 arch/m68k/include/asm/bugs_mm.h create mode 100644 arch/m68k/include/asm/bugs_no.h create mode 100644 arch/m68k/include/asm/bvme6000hw.h create mode 100644 arch/m68k/include/asm/byteorder.h create mode 100644 arch/m68k/include/asm/byteorder_mm.h create mode 100644 arch/m68k/include/asm/byteorder_no.h create mode 100644 arch/m68k/include/asm/cache.h create mode 100644 arch/m68k/include/asm/cache_mm.h create mode 100644 arch/m68k/include/asm/cache_no.h create mode 100644 arch/m68k/include/asm/cachectl.h create mode 100644 arch/m68k/include/asm/cacheflush.h create mode 100644 arch/m68k/include/asm/cacheflush_mm.h create mode 100644 arch/m68k/include/asm/cacheflush_no.h create mode 100644 arch/m68k/include/asm/checksum.h create mode 100644 arch/m68k/include/asm/checksum_mm.h create mode 100644 arch/m68k/include/asm/checksum_no.h create mode 100644 arch/m68k/include/asm/coldfire.h create mode 100644 arch/m68k/include/asm/commproc.h create mode 100644 arch/m68k/include/asm/contregs.h create mode 100644 arch/m68k/include/asm/cputime.h create mode 100644 arch/m68k/include/asm/current.h create mode 100644 arch/m68k/include/asm/current_mm.h create mode 100644 arch/m68k/include/asm/current_no.h create mode 100644 arch/m68k/include/asm/dbg.h create mode 100644 arch/m68k/include/asm/delay.h create mode 100644 arch/m68k/include/asm/delay_mm.h create mode 100644 arch/m68k/include/asm/delay_no.h create mode 100644 arch/m68k/include/asm/device.h create mode 100644 arch/m68k/include/asm/div64.h create mode 100644 arch/m68k/include/asm/div64_mm.h create mode 100644 arch/m68k/include/asm/div64_no.h create mode 100644 arch/m68k/include/asm/dma-mapping.h create mode 100644 arch/m68k/include/asm/dma-mapping_mm.h create mode 100644 arch/m68k/include/asm/dma-mapping_no.h create mode 100644 arch/m68k/include/asm/dma.h create mode 100644 arch/m68k/include/asm/dma_mm.h create mode 100644 arch/m68k/include/asm/dma_no.h create mode 100644 arch/m68k/include/asm/dsp56k.h create mode 100644 arch/m68k/include/asm/dvma.h create mode 100644 arch/m68k/include/asm/elf.h create mode 100644 arch/m68k/include/asm/elf_mm.h create mode 100644 arch/m68k/include/asm/elf_no.h create mode 100644 arch/m68k/include/asm/elia.h create mode 100644 arch/m68k/include/asm/emergency-restart.h create mode 100644 arch/m68k/include/asm/entry.h create mode 100644 arch/m68k/include/asm/entry_mm.h create mode 100644 arch/m68k/include/asm/entry_no.h create mode 100644 arch/m68k/include/asm/errno.h create mode 100644 arch/m68k/include/asm/fb.h create mode 100644 arch/m68k/include/asm/fb_mm.h create mode 100644 arch/m68k/include/asm/fb_no.h create mode 100644 arch/m68k/include/asm/fbio.h create mode 100644 arch/m68k/include/asm/fcntl.h create mode 100644 arch/m68k/include/asm/flat.h create mode 100644 arch/m68k/include/asm/floppy.h create mode 100644 arch/m68k/include/asm/fpu.h create mode 100644 arch/m68k/include/asm/fpu_mm.h create mode 100644 arch/m68k/include/asm/fpu_no.h create mode 100644 arch/m68k/include/asm/futex.h create mode 100644 arch/m68k/include/asm/hardirq.h create mode 100644 arch/m68k/include/asm/hardirq_mm.h create mode 100644 arch/m68k/include/asm/hardirq_no.h create mode 100644 arch/m68k/include/asm/hp300hw.h create mode 100644 arch/m68k/include/asm/hw_irq.h create mode 100644 arch/m68k/include/asm/hw_irq_mm.h create mode 100644 arch/m68k/include/asm/hw_irq_no.h create mode 100644 arch/m68k/include/asm/hwtest.h create mode 100644 arch/m68k/include/asm/ide.h create mode 100644 arch/m68k/include/asm/idprom.h create mode 100644 arch/m68k/include/asm/intersil.h create mode 100644 arch/m68k/include/asm/io.h create mode 100644 arch/m68k/include/asm/io_mm.h create mode 100644 arch/m68k/include/asm/io_no.h create mode 100644 arch/m68k/include/asm/ioctl.h create mode 100644 arch/m68k/include/asm/ioctls.h create mode 100644 arch/m68k/include/asm/ipcbuf.h create mode 100644 arch/m68k/include/asm/irq.h create mode 100644 arch/m68k/include/asm/irq_mm.h create mode 100644 arch/m68k/include/asm/irq_no.h create mode 100644 arch/m68k/include/asm/irq_regs.h create mode 100644 arch/m68k/include/asm/kdebug.h create mode 100644 arch/m68k/include/asm/kmap_types.h create mode 100644 arch/m68k/include/asm/kmap_types_mm.h create mode 100644 arch/m68k/include/asm/kmap_types_no.h create mode 100644 arch/m68k/include/asm/linkage.h create mode 100644 arch/m68k/include/asm/local.h create mode 100644 arch/m68k/include/asm/m5206sim.h create mode 100644 arch/m68k/include/asm/m520xsim.h create mode 100644 arch/m68k/include/asm/m523xsim.h create mode 100644 arch/m68k/include/asm/m5249sim.h create mode 100644 arch/m68k/include/asm/m5272sim.h create mode 100644 arch/m68k/include/asm/m527xsim.h create mode 100644 arch/m68k/include/asm/m528xsim.h create mode 100644 arch/m68k/include/asm/m5307sim.h create mode 100644 arch/m68k/include/asm/m532xsim.h create mode 100644 arch/m68k/include/asm/m5407sim.h create mode 100644 arch/m68k/include/asm/m68360.h create mode 100644 arch/m68k/include/asm/m68360_enet.h create mode 100644 arch/m68k/include/asm/m68360_pram.h create mode 100644 arch/m68k/include/asm/m68360_quicc.h create mode 100644 arch/m68k/include/asm/m68360_regs.h create mode 100644 arch/m68k/include/asm/mac_asc.h create mode 100644 arch/m68k/include/asm/mac_baboon.h create mode 100644 arch/m68k/include/asm/mac_iop.h create mode 100644 arch/m68k/include/asm/mac_mouse.h create mode 100644 arch/m68k/include/asm/mac_oss.h create mode 100644 arch/m68k/include/asm/mac_psc.h create mode 100644 arch/m68k/include/asm/mac_via.h create mode 100644 arch/m68k/include/asm/machdep.h create mode 100644 arch/m68k/include/asm/machdep_mm.h create mode 100644 arch/m68k/include/asm/machdep_no.h create mode 100644 arch/m68k/include/asm/machines.h create mode 100644 arch/m68k/include/asm/machw.h create mode 100644 arch/m68k/include/asm/macintosh.h create mode 100644 arch/m68k/include/asm/macints.h create mode 100644 arch/m68k/include/asm/math-emu.h create mode 100644 arch/m68k/include/asm/mc146818rtc.h create mode 100644 arch/m68k/include/asm/mc146818rtc_mm.h create mode 100644 arch/m68k/include/asm/mc146818rtc_no.h create mode 100644 arch/m68k/include/asm/mcfcache.h create mode 100644 arch/m68k/include/asm/mcfdma.h create mode 100644 arch/m68k/include/asm/mcfmbus.h create mode 100644 arch/m68k/include/asm/mcfne.h create mode 100644 arch/m68k/include/asm/mcfpci.h create mode 100644 arch/m68k/include/asm/mcfpit.h create mode 100644 arch/m68k/include/asm/mcfsim.h create mode 100644 arch/m68k/include/asm/mcfsmc.h create mode 100644 arch/m68k/include/asm/mcftimer.h create mode 100644 arch/m68k/include/asm/mcfuart.h create mode 100644 arch/m68k/include/asm/mcfwdebug.h create mode 100644 arch/m68k/include/asm/md.h create mode 100644 arch/m68k/include/asm/mman.h create mode 100644 arch/m68k/include/asm/mmu.h create mode 100644 arch/m68k/include/asm/mmu_context.h create mode 100644 arch/m68k/include/asm/mmu_context_mm.h create mode 100644 arch/m68k/include/asm/mmu_context_no.h create mode 100644 arch/m68k/include/asm/mmu_mm.h create mode 100644 arch/m68k/include/asm/mmu_no.h create mode 100644 arch/m68k/include/asm/mmzone.h create mode 100644 arch/m68k/include/asm/module.h create mode 100644 arch/m68k/include/asm/module_mm.h create mode 100644 arch/m68k/include/asm/module_no.h create mode 100644 arch/m68k/include/asm/motorola_pgalloc.h create mode 100644 arch/m68k/include/asm/motorola_pgtable.h create mode 100644 arch/m68k/include/asm/movs.h create mode 100644 arch/m68k/include/asm/msgbuf.h create mode 100644 arch/m68k/include/asm/mutex.h create mode 100644 arch/m68k/include/asm/mvme147hw.h create mode 100644 arch/m68k/include/asm/mvme16xhw.h create mode 100644 arch/m68k/include/asm/nettel.h create mode 100644 arch/m68k/include/asm/nubus.h create mode 100644 arch/m68k/include/asm/openprom.h create mode 100644 arch/m68k/include/asm/oplib.h create mode 100644 arch/m68k/include/asm/page.h create mode 100644 arch/m68k/include/asm/page_mm.h create mode 100644 arch/m68k/include/asm/page_no.h create mode 100644 arch/m68k/include/asm/page_offset.h create mode 100644 arch/m68k/include/asm/page_offset_mm.h create mode 100644 arch/m68k/include/asm/page_offset_no.h create mode 100644 arch/m68k/include/asm/param.h create mode 100644 arch/m68k/include/asm/param_mm.h create mode 100644 arch/m68k/include/asm/param_no.h create mode 100644 arch/m68k/include/asm/parport.h create mode 100644 arch/m68k/include/asm/pci.h create mode 100644 arch/m68k/include/asm/pci_mm.h create mode 100644 arch/m68k/include/asm/pci_no.h create mode 100644 arch/m68k/include/asm/percpu.h create mode 100644 arch/m68k/include/asm/pgalloc.h create mode 100644 arch/m68k/include/asm/pgalloc_mm.h create mode 100644 arch/m68k/include/asm/pgalloc_no.h create mode 100644 arch/m68k/include/asm/pgtable.h create mode 100644 arch/m68k/include/asm/pgtable_mm.h create mode 100644 arch/m68k/include/asm/pgtable_no.h create mode 100644 arch/m68k/include/asm/poll.h create mode 100644 arch/m68k/include/asm/posix_types.h create mode 100644 arch/m68k/include/asm/processor.h create mode 100644 arch/m68k/include/asm/processor_mm.h create mode 100644 arch/m68k/include/asm/processor_no.h create mode 100644 arch/m68k/include/asm/ptrace.h create mode 100644 arch/m68k/include/asm/ptrace_mm.h create mode 100644 arch/m68k/include/asm/ptrace_no.h create mode 100644 arch/m68k/include/asm/q40_master.h create mode 100644 arch/m68k/include/asm/q40ints.h create mode 100644 arch/m68k/include/asm/quicc_simple.h create mode 100644 arch/m68k/include/asm/raw_io.h create mode 100644 arch/m68k/include/asm/resource.h create mode 100644 arch/m68k/include/asm/rtc.h create mode 100644 arch/m68k/include/asm/sbus.h create mode 100644 arch/m68k/include/asm/scatterlist.h create mode 100644 arch/m68k/include/asm/scatterlist_mm.h create mode 100644 arch/m68k/include/asm/scatterlist_no.h create mode 100644 arch/m68k/include/asm/sections.h create mode 100644 arch/m68k/include/asm/segment.h create mode 100644 arch/m68k/include/asm/segment_mm.h create mode 100644 arch/m68k/include/asm/segment_no.h create mode 100644 arch/m68k/include/asm/sembuf.h create mode 100644 arch/m68k/include/asm/serial.h create mode 100644 arch/m68k/include/asm/setup.h create mode 100644 arch/m68k/include/asm/setup_mm.h create mode 100644 arch/m68k/include/asm/setup_no.h create mode 100644 arch/m68k/include/asm/shm.h create mode 100644 arch/m68k/include/asm/shmbuf.h create mode 100644 arch/m68k/include/asm/shmparam.h create mode 100644 arch/m68k/include/asm/sigcontext.h create mode 100644 arch/m68k/include/asm/sigcontext_mm.h create mode 100644 arch/m68k/include/asm/sigcontext_no.h create mode 100644 arch/m68k/include/asm/siginfo.h create mode 100644 arch/m68k/include/asm/siginfo_mm.h create mode 100644 arch/m68k/include/asm/siginfo_no.h create mode 100644 arch/m68k/include/asm/signal.h create mode 100644 arch/m68k/include/asm/signal_mm.h create mode 100644 arch/m68k/include/asm/signal_no.h create mode 100644 arch/m68k/include/asm/smp.h create mode 100644 arch/m68k/include/asm/socket.h create mode 100644 arch/m68k/include/asm/sockios.h create mode 100644 arch/m68k/include/asm/spinlock.h create mode 100644 arch/m68k/include/asm/stat.h create mode 100644 arch/m68k/include/asm/statfs.h create mode 100644 arch/m68k/include/asm/string.h create mode 100644 arch/m68k/include/asm/string_mm.h create mode 100644 arch/m68k/include/asm/string_no.h create mode 100644 arch/m68k/include/asm/sun3-head.h create mode 100644 arch/m68k/include/asm/sun3_pgalloc.h create mode 100644 arch/m68k/include/asm/sun3_pgtable.h create mode 100644 arch/m68k/include/asm/sun3ints.h create mode 100644 arch/m68k/include/asm/sun3mmu.h create mode 100644 arch/m68k/include/asm/sun3x.h create mode 100644 arch/m68k/include/asm/sun3xflop.h create mode 100644 arch/m68k/include/asm/sun3xprom.h create mode 100644 arch/m68k/include/asm/suspend.h create mode 100644 arch/m68k/include/asm/swab.h create mode 100644 arch/m68k/include/asm/swab_mm.h create mode 100644 arch/m68k/include/asm/swab_no.h create mode 100644 arch/m68k/include/asm/system.h create mode 100644 arch/m68k/include/asm/system_mm.h create mode 100644 arch/m68k/include/asm/system_no.h create mode 100644 arch/m68k/include/asm/termbits.h create mode 100644 arch/m68k/include/asm/termios.h create mode 100644 arch/m68k/include/asm/thread_info.h create mode 100644 arch/m68k/include/asm/thread_info_mm.h create mode 100644 arch/m68k/include/asm/thread_info_no.h create mode 100644 arch/m68k/include/asm/timex.h create mode 100644 arch/m68k/include/asm/timex_mm.h create mode 100644 arch/m68k/include/asm/timex_no.h create mode 100644 arch/m68k/include/asm/tlb.h create mode 100644 arch/m68k/include/asm/tlbflush.h create mode 100644 arch/m68k/include/asm/tlbflush_mm.h create mode 100644 arch/m68k/include/asm/tlbflush_no.h create mode 100644 arch/m68k/include/asm/topology.h create mode 100644 arch/m68k/include/asm/traps.h create mode 100644 arch/m68k/include/asm/traps_mm.h create mode 100644 arch/m68k/include/asm/traps_no.h create mode 100644 arch/m68k/include/asm/types.h create mode 100644 arch/m68k/include/asm/uaccess.h create mode 100644 arch/m68k/include/asm/uaccess_mm.h create mode 100644 arch/m68k/include/asm/uaccess_no.h create mode 100644 arch/m68k/include/asm/ucontext.h create mode 100644 arch/m68k/include/asm/ucontext_mm.h create mode 100644 arch/m68k/include/asm/ucontext_no.h create mode 100644 arch/m68k/include/asm/unaligned.h create mode 100644 arch/m68k/include/asm/unaligned_mm.h create mode 100644 arch/m68k/include/asm/unaligned_no.h create mode 100644 arch/m68k/include/asm/unistd.h create mode 100644 arch/m68k/include/asm/unistd_mm.h create mode 100644 arch/m68k/include/asm/unistd_no.h create mode 100644 arch/m68k/include/asm/user.h create mode 100644 arch/m68k/include/asm/virtconvert.h create mode 100644 arch/m68k/include/asm/xor.h create mode 100644 arch/m68k/include/asm/zorro.h delete mode 100644 arch/m68knommu/include/asm/Kbuild delete mode 100644 arch/m68knommu/include/asm/MC68328.h delete mode 100644 arch/m68knommu/include/asm/MC68332.h delete mode 100644 arch/m68knommu/include/asm/MC68EZ328.h delete mode 100644 arch/m68knommu/include/asm/MC68VZ328.h delete mode 100644 arch/m68knommu/include/asm/anchor.h delete mode 100644 arch/m68knommu/include/asm/atomic.h delete mode 100644 arch/m68knommu/include/asm/auxvec.h delete mode 100644 arch/m68knommu/include/asm/bitops.h delete mode 100644 arch/m68knommu/include/asm/bootinfo.h delete mode 100644 arch/m68knommu/include/asm/bootstd.h delete mode 100644 arch/m68knommu/include/asm/bug.h delete mode 100644 arch/m68knommu/include/asm/bugs.h delete mode 100644 arch/m68knommu/include/asm/byteorder.h delete mode 100644 arch/m68knommu/include/asm/cache.h delete mode 100644 arch/m68knommu/include/asm/cachectl.h delete mode 100644 arch/m68knommu/include/asm/cacheflush.h delete mode 100644 arch/m68knommu/include/asm/checksum.h delete mode 100644 arch/m68knommu/include/asm/coldfire.h delete mode 100644 arch/m68knommu/include/asm/commproc.h delete mode 100644 arch/m68knommu/include/asm/cputime.h delete mode 100644 arch/m68knommu/include/asm/current.h delete mode 100644 arch/m68knommu/include/asm/dbg.h delete mode 100644 arch/m68knommu/include/asm/delay.h delete mode 100644 arch/m68knommu/include/asm/device.h delete mode 100644 arch/m68knommu/include/asm/div64.h delete mode 100644 arch/m68knommu/include/asm/dma-mapping.h delete mode 100644 arch/m68knommu/include/asm/dma.h delete mode 100644 arch/m68knommu/include/asm/elf.h delete mode 100644 arch/m68knommu/include/asm/elia.h delete mode 100644 arch/m68knommu/include/asm/emergency-restart.h delete mode 100644 arch/m68knommu/include/asm/entry.h delete mode 100644 arch/m68knommu/include/asm/errno.h delete mode 100644 arch/m68knommu/include/asm/fb.h delete mode 100644 arch/m68knommu/include/asm/fcntl.h delete mode 100644 arch/m68knommu/include/asm/flat.h delete mode 100644 arch/m68knommu/include/asm/fpu.h delete mode 100644 arch/m68knommu/include/asm/futex.h delete mode 100644 arch/m68knommu/include/asm/hardirq.h delete mode 100644 arch/m68knommu/include/asm/hw_irq.h delete mode 100644 arch/m68knommu/include/asm/hwtest.h delete mode 100644 arch/m68knommu/include/asm/io.h delete mode 100644 arch/m68knommu/include/asm/ioctl.h delete mode 100644 arch/m68knommu/include/asm/ioctls.h delete mode 100644 arch/m68knommu/include/asm/ipcbuf.h delete mode 100644 arch/m68knommu/include/asm/irq.h delete mode 100644 arch/m68knommu/include/asm/irq_regs.h delete mode 100644 arch/m68knommu/include/asm/kdebug.h delete mode 100644 arch/m68knommu/include/asm/kmap_types.h delete mode 100644 arch/m68knommu/include/asm/linkage.h delete mode 100644 arch/m68knommu/include/asm/local.h delete mode 100644 arch/m68knommu/include/asm/m5206sim.h delete mode 100644 arch/m68knommu/include/asm/m520xsim.h delete mode 100644 arch/m68knommu/include/asm/m523xsim.h delete mode 100644 arch/m68knommu/include/asm/m5249sim.h delete mode 100644 arch/m68knommu/include/asm/m5272sim.h delete mode 100644 arch/m68knommu/include/asm/m527xsim.h delete mode 100644 arch/m68knommu/include/asm/m528xsim.h delete mode 100644 arch/m68knommu/include/asm/m5307sim.h delete mode 100644 arch/m68knommu/include/asm/m532xsim.h delete mode 100644 arch/m68knommu/include/asm/m5407sim.h delete mode 100644 arch/m68knommu/include/asm/m68360.h delete mode 100644 arch/m68knommu/include/asm/m68360_enet.h delete mode 100644 arch/m68knommu/include/asm/m68360_pram.h delete mode 100644 arch/m68knommu/include/asm/m68360_quicc.h delete mode 100644 arch/m68knommu/include/asm/m68360_regs.h delete mode 100644 arch/m68knommu/include/asm/machdep.h delete mode 100644 arch/m68knommu/include/asm/math-emu.h delete mode 100644 arch/m68knommu/include/asm/mc146818rtc.h delete mode 100644 arch/m68knommu/include/asm/mcfcache.h delete mode 100644 arch/m68knommu/include/asm/mcfdma.h delete mode 100644 arch/m68knommu/include/asm/mcfmbus.h delete mode 100644 arch/m68knommu/include/asm/mcfne.h delete mode 100644 arch/m68knommu/include/asm/mcfpci.h delete mode 100644 arch/m68knommu/include/asm/mcfpit.h delete mode 100644 arch/m68knommu/include/asm/mcfsim.h delete mode 100644 arch/m68knommu/include/asm/mcfsmc.h delete mode 100644 arch/m68knommu/include/asm/mcftimer.h delete mode 100644 arch/m68knommu/include/asm/mcfuart.h delete mode 100644 arch/m68knommu/include/asm/mcfwdebug.h delete mode 100644 arch/m68knommu/include/asm/md.h delete mode 100644 arch/m68knommu/include/asm/mman.h delete mode 100644 arch/m68knommu/include/asm/mmu.h delete mode 100644 arch/m68knommu/include/asm/mmu_context.h delete mode 100644 arch/m68knommu/include/asm/module.h delete mode 100644 arch/m68knommu/include/asm/movs.h delete mode 100644 arch/m68knommu/include/asm/msgbuf.h delete mode 100644 arch/m68knommu/include/asm/mutex.h delete mode 100644 arch/m68knommu/include/asm/nettel.h delete mode 100644 arch/m68knommu/include/asm/openprom.h delete mode 100644 arch/m68knommu/include/asm/oplib.h delete mode 100644 arch/m68knommu/include/asm/page.h delete mode 100644 arch/m68knommu/include/asm/page_offset.h delete mode 100644 arch/m68knommu/include/asm/param.h delete mode 100644 arch/m68knommu/include/asm/pci.h delete mode 100644 arch/m68knommu/include/asm/percpu.h delete mode 100644 arch/m68knommu/include/asm/pgalloc.h delete mode 100644 arch/m68knommu/include/asm/pgtable.h delete mode 100644 arch/m68knommu/include/asm/poll.h delete mode 100644 arch/m68knommu/include/asm/posix_types.h delete mode 100644 arch/m68knommu/include/asm/processor.h delete mode 100644 arch/m68knommu/include/asm/ptrace.h delete mode 100644 arch/m68knommu/include/asm/quicc_simple.h delete mode 100644 arch/m68knommu/include/asm/resource.h delete mode 100644 arch/m68knommu/include/asm/rtc.h delete mode 100644 arch/m68knommu/include/asm/scatterlist.h delete mode 100644 arch/m68knommu/include/asm/sections.h delete mode 100644 arch/m68knommu/include/asm/segment.h delete mode 100644 arch/m68knommu/include/asm/sembuf.h delete mode 100644 arch/m68knommu/include/asm/setup.h delete mode 100644 arch/m68knommu/include/asm/shm.h delete mode 100644 arch/m68knommu/include/asm/shmbuf.h delete mode 100644 arch/m68knommu/include/asm/shmparam.h delete mode 100644 arch/m68knommu/include/asm/sigcontext.h delete mode 100644 arch/m68knommu/include/asm/siginfo.h delete mode 100644 arch/m68knommu/include/asm/signal.h delete mode 100644 arch/m68knommu/include/asm/smp.h delete mode 100644 arch/m68knommu/include/asm/socket.h delete mode 100644 arch/m68knommu/include/asm/sockios.h delete mode 100644 arch/m68knommu/include/asm/spinlock.h delete mode 100644 arch/m68knommu/include/asm/stat.h delete mode 100644 arch/m68knommu/include/asm/statfs.h delete mode 100644 arch/m68knommu/include/asm/string.h delete mode 100644 arch/m68knommu/include/asm/swab.h delete mode 100644 arch/m68knommu/include/asm/system.h delete mode 100644 arch/m68knommu/include/asm/termbits.h delete mode 100644 arch/m68knommu/include/asm/termios.h delete mode 100644 arch/m68knommu/include/asm/thread_info.h delete mode 100644 arch/m68knommu/include/asm/timex.h delete mode 100644 arch/m68knommu/include/asm/tlb.h delete mode 100644 arch/m68knommu/include/asm/tlbflush.h delete mode 100644 arch/m68knommu/include/asm/topology.h delete mode 100644 arch/m68knommu/include/asm/traps.h delete mode 100644 arch/m68knommu/include/asm/types.h delete mode 100644 arch/m68knommu/include/asm/uaccess.h delete mode 100644 arch/m68knommu/include/asm/ucontext.h delete mode 100644 arch/m68knommu/include/asm/unaligned.h delete mode 100644 arch/m68knommu/include/asm/unistd.h delete mode 100644 arch/m68knommu/include/asm/user.h delete mode 100644 include/asm-m68k/Kbuild delete mode 100644 include/asm-m68k/a.out-core.h delete mode 100644 include/asm-m68k/a.out.h delete mode 100644 include/asm-m68k/adb_iop.h delete mode 100644 include/asm-m68k/amigahw.h delete mode 100644 include/asm-m68k/amigaints.h delete mode 100644 include/asm-m68k/amigayle.h delete mode 100644 include/asm-m68k/amipcmcia.h delete mode 100644 include/asm-m68k/apollodma.h delete mode 100644 include/asm-m68k/apollohw.h delete mode 100644 include/asm-m68k/atafd.h delete mode 100644 include/asm-m68k/atafdreg.h delete mode 100644 include/asm-m68k/atari_joystick.h delete mode 100644 include/asm-m68k/atari_stdma.h delete mode 100644 include/asm-m68k/atari_stram.h delete mode 100644 include/asm-m68k/atarihw.h delete mode 100644 include/asm-m68k/atariints.h delete mode 100644 include/asm-m68k/atarikb.h delete mode 100644 include/asm-m68k/atomic.h delete mode 100644 include/asm-m68k/auxvec.h delete mode 100644 include/asm-m68k/bitops.h delete mode 100644 include/asm-m68k/blinken.h delete mode 100644 include/asm-m68k/bootinfo.h delete mode 100644 include/asm-m68k/bug.h delete mode 100644 include/asm-m68k/bugs.h delete mode 100644 include/asm-m68k/bvme6000hw.h delete mode 100644 include/asm-m68k/byteorder.h delete mode 100644 include/asm-m68k/cache.h delete mode 100644 include/asm-m68k/cachectl.h delete mode 100644 include/asm-m68k/cacheflush.h delete mode 100644 include/asm-m68k/checksum.h delete mode 100644 include/asm-m68k/contregs.h delete mode 100644 include/asm-m68k/cputime.h delete mode 100644 include/asm-m68k/current.h delete mode 100644 include/asm-m68k/delay.h delete mode 100644 include/asm-m68k/device.h delete mode 100644 include/asm-m68k/div64.h delete mode 100644 include/asm-m68k/dma-mapping.h delete mode 100644 include/asm-m68k/dma.h delete mode 100644 include/asm-m68k/dsp56k.h delete mode 100644 include/asm-m68k/dvma.h delete mode 100644 include/asm-m68k/elf.h delete mode 100644 include/asm-m68k/emergency-restart.h delete mode 100644 include/asm-m68k/entry.h delete mode 100644 include/asm-m68k/errno.h delete mode 100644 include/asm-m68k/fb.h delete mode 100644 include/asm-m68k/fbio.h delete mode 100644 include/asm-m68k/fcntl.h delete mode 100644 include/asm-m68k/floppy.h delete mode 100644 include/asm-m68k/fpu.h delete mode 100644 include/asm-m68k/futex.h delete mode 100644 include/asm-m68k/hardirq.h delete mode 100644 include/asm-m68k/hp300hw.h delete mode 100644 include/asm-m68k/hw_irq.h delete mode 100644 include/asm-m68k/hwtest.h delete mode 100644 include/asm-m68k/ide.h delete mode 100644 include/asm-m68k/idprom.h delete mode 100644 include/asm-m68k/intersil.h delete mode 100644 include/asm-m68k/io.h delete mode 100644 include/asm-m68k/ioctl.h delete mode 100644 include/asm-m68k/ioctls.h delete mode 100644 include/asm-m68k/ipcbuf.h delete mode 100644 include/asm-m68k/irq.h delete mode 100644 include/asm-m68k/irq_regs.h delete mode 100644 include/asm-m68k/kdebug.h delete mode 100644 include/asm-m68k/kmap_types.h delete mode 100644 include/asm-m68k/linkage.h delete mode 100644 include/asm-m68k/local.h delete mode 100644 include/asm-m68k/mac_asc.h delete mode 100644 include/asm-m68k/mac_baboon.h delete mode 100644 include/asm-m68k/mac_iop.h delete mode 100644 include/asm-m68k/mac_mouse.h delete mode 100644 include/asm-m68k/mac_oss.h delete mode 100644 include/asm-m68k/mac_psc.h delete mode 100644 include/asm-m68k/mac_via.h delete mode 100644 include/asm-m68k/machdep.h delete mode 100644 include/asm-m68k/machines.h delete mode 100644 include/asm-m68k/machw.h delete mode 100644 include/asm-m68k/macintosh.h delete mode 100644 include/asm-m68k/macints.h delete mode 100644 include/asm-m68k/math-emu.h delete mode 100644 include/asm-m68k/mc146818rtc.h delete mode 100644 include/asm-m68k/md.h delete mode 100644 include/asm-m68k/mman.h delete mode 100644 include/asm-m68k/mmu.h delete mode 100644 include/asm-m68k/mmu_context.h delete mode 100644 include/asm-m68k/mmzone.h delete mode 100644 include/asm-m68k/module.h delete mode 100644 include/asm-m68k/motorola_pgalloc.h delete mode 100644 include/asm-m68k/motorola_pgtable.h delete mode 100644 include/asm-m68k/movs.h delete mode 100644 include/asm-m68k/msgbuf.h delete mode 100644 include/asm-m68k/mutex.h delete mode 100644 include/asm-m68k/mvme147hw.h delete mode 100644 include/asm-m68k/mvme16xhw.h delete mode 100644 include/asm-m68k/nubus.h delete mode 100644 include/asm-m68k/openprom.h delete mode 100644 include/asm-m68k/oplib.h delete mode 100644 include/asm-m68k/page.h delete mode 100644 include/asm-m68k/page_offset.h delete mode 100644 include/asm-m68k/param.h delete mode 100644 include/asm-m68k/parport.h delete mode 100644 include/asm-m68k/pci.h delete mode 100644 include/asm-m68k/percpu.h delete mode 100644 include/asm-m68k/pgalloc.h delete mode 100644 include/asm-m68k/pgtable.h delete mode 100644 include/asm-m68k/poll.h delete mode 100644 include/asm-m68k/posix_types.h delete mode 100644 include/asm-m68k/processor.h delete mode 100644 include/asm-m68k/ptrace.h delete mode 100644 include/asm-m68k/q40_master.h delete mode 100644 include/asm-m68k/q40ints.h delete mode 100644 include/asm-m68k/raw_io.h delete mode 100644 include/asm-m68k/resource.h delete mode 100644 include/asm-m68k/rtc.h delete mode 100644 include/asm-m68k/sbus.h delete mode 100644 include/asm-m68k/scatterlist.h delete mode 100644 include/asm-m68k/sections.h delete mode 100644 include/asm-m68k/segment.h delete mode 100644 include/asm-m68k/sembuf.h delete mode 100644 include/asm-m68k/serial.h delete mode 100644 include/asm-m68k/setup.h delete mode 100644 include/asm-m68k/shm.h delete mode 100644 include/asm-m68k/shmbuf.h delete mode 100644 include/asm-m68k/shmparam.h delete mode 100644 include/asm-m68k/sigcontext.h delete mode 100644 include/asm-m68k/siginfo.h delete mode 100644 include/asm-m68k/signal.h delete mode 100644 include/asm-m68k/socket.h delete mode 100644 include/asm-m68k/sockios.h delete mode 100644 include/asm-m68k/spinlock.h delete mode 100644 include/asm-m68k/stat.h delete mode 100644 include/asm-m68k/statfs.h delete mode 100644 include/asm-m68k/string.h delete mode 100644 include/asm-m68k/sun3-head.h delete mode 100644 include/asm-m68k/sun3_pgalloc.h delete mode 100644 include/asm-m68k/sun3_pgtable.h delete mode 100644 include/asm-m68k/sun3ints.h delete mode 100644 include/asm-m68k/sun3mmu.h delete mode 100644 include/asm-m68k/sun3x.h delete mode 100644 include/asm-m68k/sun3xflop.h delete mode 100644 include/asm-m68k/sun3xprom.h delete mode 100644 include/asm-m68k/suspend.h delete mode 100644 include/asm-m68k/swab.h delete mode 100644 include/asm-m68k/system.h delete mode 100644 include/asm-m68k/termbits.h delete mode 100644 include/asm-m68k/termios.h delete mode 100644 include/asm-m68k/thread_info.h delete mode 100644 include/asm-m68k/timex.h delete mode 100644 include/asm-m68k/tlb.h delete mode 100644 include/asm-m68k/tlbflush.h delete mode 100644 include/asm-m68k/topology.h delete mode 100644 include/asm-m68k/traps.h delete mode 100644 include/asm-m68k/types.h delete mode 100644 include/asm-m68k/uaccess.h delete mode 100644 include/asm-m68k/ucontext.h delete mode 100644 include/asm-m68k/unaligned.h delete mode 100644 include/asm-m68k/unistd.h delete mode 100644 include/asm-m68k/user.h delete mode 100644 include/asm-m68k/virtconvert.h delete mode 100644 include/asm-m68k/xor.h delete mode 100644 include/asm-m68k/zorro.h diff --git a/Makefile b/Makefile index c06e250eca1..bab7b8485f1 100644 --- a/Makefile +++ b/Makefile @@ -213,6 +213,10 @@ endif # Where to locate arch specific headers hdr-arch := $(SRCARCH) +ifeq ($(ARCH),m68knommu) + hdr-arch := m68k +endif + KCONFIG_CONFIG ?= .config # SHELL used by kbuild diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild new file mode 100644 index 00000000000..52fd96b4142 --- /dev/null +++ b/arch/m68k/include/asm/Kbuild @@ -0,0 +1,3 @@ +include include/asm-generic/Kbuild.asm +header-y += cachectl.h +unifdef-y += swab.h diff --git a/arch/m68k/include/asm/MC68328.h b/arch/m68k/include/asm/MC68328.h new file mode 100644 index 00000000000..a337e56d09b --- /dev/null +++ b/arch/m68k/include/asm/MC68328.h @@ -0,0 +1,1266 @@ + +/* include/asm-m68knommu/MC68328.h: '328 control registers + * + * Copyright (C) 1999 Vladimir Gurevich + * Bear & Hare Software, Inc. + * + * Based on include/asm-m68knommu/MC68332.h + * Copyright (C) 1998 Kenneth Albanowski , + * + */ + +#ifndef _MC68328_H_ +#define _MC68328_H_ + +#define BYTE_REF(addr) (*((volatile unsigned char*)addr)) +#define WORD_REF(addr) (*((volatile unsigned short*)addr)) +#define LONG_REF(addr) (*((volatile unsigned long*)addr)) + +#define PUT_FIELD(field, val) (((val) << field##_SHIFT) & field##_MASK) +#define GET_FIELD(reg, field) (((reg) & field##_MASK) >> field##_SHIFT) + +/********** + * + * 0xFFFFF0xx -- System Control + * + **********/ + +/* + * System Control Register (SCR) + */ +#define SCR_ADDR 0xfffff000 +#define SCR BYTE_REF(SCR_ADDR) + +#define SCR_WDTH8 0x01 /* 8-Bit Width Select */ +#define SCR_DMAP 0x04 /* Double Map */ +#define SCR_SO 0x08 /* Supervisor Only */ +#define SCR_BETEN 0x10 /* Bus-Error Time-Out Enable */ +#define SCR_PRV 0x20 /* Privilege Violation */ +#define SCR_WPV 0x40 /* Write Protect Violation */ +#define SCR_BETO 0x80 /* Bus-Error TimeOut */ + +/* + * Mask Revision Register + */ +#define MRR_ADDR 0xfffff004 +#define MRR LONG_REF(MRR_ADDR) + +/********** + * + * 0xFFFFF1xx -- Chip-Select logic + * + **********/ + +/********** + * + * 0xFFFFF2xx -- Phase Locked Loop (PLL) & Power Control + * + **********/ + +/* + * Group Base Address Registers + */ +#define GRPBASEA_ADDR 0xfffff100 +#define GRPBASEB_ADDR 0xfffff102 +#define GRPBASEC_ADDR 0xfffff104 +#define GRPBASED_ADDR 0xfffff106 + +#define GRPBASEA WORD_REF(GRPBASEA_ADDR) +#define GRPBASEB WORD_REF(GRPBASEB_ADDR) +#define GRPBASEC WORD_REF(GRPBASEC_ADDR) +#define GRPBASED WORD_REF(GRPBASED_ADDR) + +#define GRPBASE_V 0x0001 /* Valid */ +#define GRPBASE_GBA_MASK 0xfff0 /* Group Base Address (bits 31-20) */ + +/* + * Group Base Address Mask Registers + */ +#define GRPMASKA_ADDR 0xfffff108 +#define GRPMASKB_ADDR 0xfffff10a +#define GRPMASKC_ADDR 0xfffff10c +#define GRPMASKD_ADDR 0xfffff10e + +#define GRPMASKA WORD_REF(GRPMASKA_ADDR) +#define GRPMASKB WORD_REF(GRPMASKB_ADDR) +#define GRPMASKC WORD_REF(GRPMASKC_ADDR) +#define GRPMASKD WORD_REF(GRPMASKD_ADDR) + +#define GRMMASK_GMA_MASK 0xfffff0 /* Group Base Mask (bits 31-20) */ + +/* + * Chip-Select Option Registers (group A) + */ +#define CSA0_ADDR 0xfffff110 +#define CSA1_ADDR 0xfffff114 +#define CSA2_ADDR 0xfffff118 +#define CSA3_ADDR 0xfffff11c + +#define CSA0 LONG_REF(CSA0_ADDR) +#define CSA1 LONG_REF(CSA1_ADDR) +#define CSA2 LONG_REF(CSA2_ADDR) +#define CSA3 LONG_REF(CSA3_ADDR) + +#define CSA_WAIT_MASK 0x00000007 /* Wait State Selection */ +#define CSA_WAIT_SHIFT 0 +#define CSA_RO 0x00000008 /* Read-Only */ +#define CSA_AM_MASK 0x0000ff00 /* Address Mask (bits 23-16) */ +#define CSA_AM_SHIFT 8 +#define CSA_BUSW 0x00010000 /* Bus Width Select */ +#define CSA_AC_MASK 0xff000000 /* Address Compare (bits 23-16) */ +#define CSA_AC_SHIFT 24 + +/* + * Chip-Select Option Registers (group B) + */ +#define CSB0_ADDR 0xfffff120 +#define CSB1_ADDR 0xfffff124 +#define CSB2_ADDR 0xfffff128 +#define CSB3_ADDR 0xfffff12c + +#define CSB0 LONG_REF(CSB0_ADDR) +#define CSB1 LONG_REF(CSB1_ADDR) +#define CSB2 LONG_REF(CSB2_ADDR) +#define CSB3 LONG_REF(CSB3_ADDR) + +#define CSB_WAIT_MASK 0x00000007 /* Wait State Selection */ +#define CSB_WAIT_SHIFT 0 +#define CSB_RO 0x00000008 /* Read-Only */ +#define CSB_AM_MASK 0x0000ff00 /* Address Mask (bits 23-16) */ +#define CSB_AM_SHIFT 8 +#define CSB_BUSW 0x00010000 /* Bus Width Select */ +#define CSB_AC_MASK 0xff000000 /* Address Compare (bits 23-16) */ +#define CSB_AC_SHIFT 24 + +/* + * Chip-Select Option Registers (group C) + */ +#define CSC0_ADDR 0xfffff130 +#define CSC1_ADDR 0xfffff134 +#define CSC2_ADDR 0xfffff138 +#define CSC3_ADDR 0xfffff13c + +#define CSC0 LONG_REF(CSC0_ADDR) +#define CSC1 LONG_REF(CSC1_ADDR) +#define CSC2 LONG_REF(CSC2_ADDR) +#define CSC3 LONG_REF(CSC3_ADDR) + +#define CSC_WAIT_MASK 0x00000007 /* Wait State Selection */ +#define CSC_WAIT_SHIFT 0 +#define CSC_RO 0x00000008 /* Read-Only */ +#define CSC_AM_MASK 0x0000fff0 /* Address Mask (bits 23-12) */ +#define CSC_AM_SHIFT 4 +#define CSC_BUSW 0x00010000 /* Bus Width Select */ +#define CSC_AC_MASK 0xfff00000 /* Address Compare (bits 23-12) */ +#define CSC_AC_SHIFT 20 + +/* + * Chip-Select Option Registers (group D) + */ +#define CSD0_ADDR 0xfffff140 +#define CSD1_ADDR 0xfffff144 +#define CSD2_ADDR 0xfffff148 +#define CSD3_ADDR 0xfffff14c + +#define CSD0 LONG_REF(CSD0_ADDR) +#define CSD1 LONG_REF(CSD1_ADDR) +#define CSD2 LONG_REF(CSD2_ADDR) +#define CSD3 LONG_REF(CSD3_ADDR) + +#define CSD_WAIT_MASK 0x00000007 /* Wait State Selection */ +#define CSD_WAIT_SHIFT 0 +#define CSD_RO 0x00000008 /* Read-Only */ +#define CSD_AM_MASK 0x0000fff0 /* Address Mask (bits 23-12) */ +#define CSD_AM_SHIFT 4 +#define CSD_BUSW 0x00010000 /* Bus Width Select */ +#define CSD_AC_MASK 0xfff00000 /* Address Compare (bits 23-12) */ +#define CSD_AC_SHIFT 20 + +/********** + * + * 0xFFFFF2xx -- Phase Locked Loop (PLL) & Power Control + * + **********/ + +/* + * PLL Control Register + */ +#define PLLCR_ADDR 0xfffff200 +#define PLLCR WORD_REF(PLLCR_ADDR) + +#define PLLCR_DISPLL 0x0008 /* Disable PLL */ +#define PLLCR_CLKEN 0x0010 /* Clock (CLKO pin) enable */ +#define PLLCR_SYSCLK_SEL_MASK 0x0700 /* System Clock Selection */ +#define PLLCR_SYSCLK_SEL_SHIFT 8 +#define PLLCR_PIXCLK_SEL_MASK 0x3800 /* LCD Clock Selection */ +#define PLLCR_PIXCLK_SEL_SHIFT 11 + +/* 'EZ328-compatible definitions */ +#define PLLCR_LCDCLK_SEL_MASK PLLCR_PIXCLK_SEL_MASK +#define PLLCR_LCDCLK_SEL_SHIFT PLLCR_PIXCLK_SEL_SHIFT + +/* + * PLL Frequency Select Register + */ +#define PLLFSR_ADDR 0xfffff202 +#define PLLFSR WORD_REF(PLLFSR_ADDR) + +#define PLLFSR_PC_MASK 0x00ff /* P Count */ +#define PLLFSR_PC_SHIFT 0 +#define PLLFSR_QC_MASK 0x0f00 /* Q Count */ +#define PLLFSR_QC_SHIFT 8 +#define PLLFSR_PROT 0x4000 /* Protect P & Q */ +#define PLLFSR_CLK32 0x8000 /* Clock 32 (kHz) */ + +/* + * Power Control Register + */ +#define PCTRL_ADDR 0xfffff207 +#define PCTRL BYTE_REF(PCTRL_ADDR) + +#define PCTRL_WIDTH_MASK 0x1f /* CPU Clock bursts width */ +#define PCTRL_WIDTH_SHIFT 0 +#define PCTRL_STOP 0x40 /* Enter power-save mode immediately */ +#define PCTRL_PCEN 0x80 /* Power Control Enable */ + +/********** + * + * 0xFFFFF3xx -- Interrupt Controller + * + **********/ + +/* + * Interrupt Vector Register + */ +#define IVR_ADDR 0xfffff300 +#define IVR BYTE_REF(IVR_ADDR) + +#define IVR_VECTOR_MASK 0xF8 + +/* + * Interrupt control Register + */ +#define ICR_ADRR 0xfffff302 +#define ICR WORD_REF(ICR_ADDR) + +#define ICR_ET6 0x0100 /* Edge Trigger Select for IRQ6 */ +#define ICR_ET3 0x0200 /* Edge Trigger Select for IRQ3 */ +#define ICR_ET2 0x0400 /* Edge Trigger Select for IRQ2 */ +#define ICR_ET1 0x0800 /* Edge Trigger Select for IRQ1 */ +#define ICR_POL6 0x1000 /* Polarity Control for IRQ6 */ +#define ICR_POL3 0x2000 /* Polarity Control for IRQ3 */ +#define ICR_POL2 0x4000 /* Polarity Control for IRQ2 */ +#define ICR_POL1 0x8000 /* Polarity Control for IRQ1 */ + +/* + * Interrupt Mask Register + */ +#define IMR_ADDR 0xfffff304 +#define IMR LONG_REF(IMR_ADDR) + +/* + * Define the names for bit positions first. This is useful for + * request_irq + */ +#define SPIM_IRQ_NUM 0 /* SPI Master interrupt */ +#define TMR2_IRQ_NUM 1 /* Timer 2 interrupt */ +#define UART_IRQ_NUM 2 /* UART interrupt */ +#define WDT_IRQ_NUM 3 /* Watchdog Timer interrupt */ +#define RTC_IRQ_NUM 4 /* RTC interrupt */ +#define KB_IRQ_NUM 6 /* Keyboard Interrupt */ +#define PWM_IRQ_NUM 7 /* Pulse-Width Modulator int. */ +#define INT0_IRQ_NUM 8 /* External INT0 */ +#define INT1_IRQ_NUM 9 /* External INT1 */ +#define INT2_IRQ_NUM 10 /* External INT2 */ +#define INT3_IRQ_NUM 11 /* External INT3 */ +#define INT4_IRQ_NUM 12 /* External INT4 */ +#define INT5_IRQ_NUM 13 /* External INT5 */ +#define INT6_IRQ_NUM 14 /* External INT6 */ +#define INT7_IRQ_NUM 15 /* External INT7 */ +#define IRQ1_IRQ_NUM 16 /* IRQ1 */ +#define IRQ2_IRQ_NUM 17 /* IRQ2 */ +#define IRQ3_IRQ_NUM 18 /* IRQ3 */ +#define IRQ6_IRQ_NUM 19 /* IRQ6 */ +#define PEN_IRQ_NUM 20 /* Pen Interrupt */ +#define SPIS_IRQ_NUM 21 /* SPI Slave Interrupt */ +#define TMR1_IRQ_NUM 22 /* Timer 1 interrupt */ +#define IRQ7_IRQ_NUM 23 /* IRQ7 */ + +/* '328-compatible definitions */ +#define SPI_IRQ_NUM SPIM_IRQ_NUM +#define TMR_IRQ_NUM TMR1_IRQ_NUM + +/* + * Here go the bitmasks themselves + */ +#define IMR_MSPIM (1 << SPIM _IRQ_NUM) /* Mask SPI Master interrupt */ +#define IMR_MTMR2 (1 << TMR2_IRQ_NUM) /* Mask Timer 2 interrupt */ +#define IMR_MUART (1 << UART_IRQ_NUM) /* Mask UART interrupt */ +#define IMR_MWDT (1 << WDT_IRQ_NUM) /* Mask Watchdog Timer interrupt */ +#define IMR_MRTC (1 << RTC_IRQ_NUM) /* Mask RTC interrupt */ +#define IMR_MKB (1 << KB_IRQ_NUM) /* Mask Keyboard Interrupt */ +#define IMR_MPWM (1 << PWM_IRQ_NUM) /* Mask Pulse-Width Modulator int. */ +#define IMR_MINT0 (1 << INT0_IRQ_NUM) /* Mask External INT0 */ +#define IMR_MINT1 (1 << INT1_IRQ_NUM) /* Mask External INT1 */ +#define IMR_MINT2 (1 << INT2_IRQ_NUM) /* Mask External INT2 */ +#define IMR_MINT3 (1 << INT3_IRQ_NUM) /* Mask External INT3 */ +#define IMR_MINT4 (1 << INT4_IRQ_NUM) /* Mask External INT4 */ +#define IMR_MINT5 (1 << INT5_IRQ_NUM) /* Mask External INT5 */ +#define IMR_MINT6 (1 << INT6_IRQ_NUM) /* Mask External INT6 */ +#define IMR_MINT7 (1 << INT7_IRQ_NUM) /* Mask External INT7 */ +#define IMR_MIRQ1 (1 << IRQ1_IRQ_NUM) /* Mask IRQ1 */ +#define IMR_MIRQ2 (1 << IRQ2_IRQ_NUM) /* Mask IRQ2 */ +#define IMR_MIRQ3 (1 << IRQ3_IRQ_NUM) /* Mask IRQ3 */ +#define IMR_MIRQ6 (1 << IRQ6_IRQ_NUM) /* Mask IRQ6 */ +#define IMR_MPEN (1 << PEN_IRQ_NUM) /* Mask Pen Interrupt */ +#define IMR_MSPIS (1 << SPIS_IRQ_NUM) /* Mask SPI Slave Interrupt */ +#define IMR_MTMR1 (1 << TMR1_IRQ_NUM) /* Mask Timer 1 interrupt */ +#define IMR_MIRQ7 (1 << IRQ7_IRQ_NUM) /* Mask IRQ7 */ + +/* 'EZ328-compatible definitions */ +#define IMR_MSPI IMR_MSPIM +#define IMR_MTMR IMR_MTMR1 + +/* + * Interrupt Wake-Up Enable Register + */ +#define IWR_ADDR 0xfffff308 +#define IWR LONG_REF(IWR_ADDR) + +#define IWR_SPIM (1 << SPIM _IRQ_NUM) /* SPI Master interrupt */ +#define IWR_TMR2 (1 << TMR2_IRQ_NUM) /* Timer 2 interrupt */ +#define IWR_UART (1 << UART_IRQ_NUM) /* UART interrupt */ +#define IWR_WDT (1 << WDT_IRQ_NUM) /* Watchdog Timer interrupt */ +#define IWR_RTC (1 << RTC_IRQ_NUM) /* RTC interrupt */ +#define IWR_KB (1 << KB_IRQ_NUM) /* Keyboard Interrupt */ +#define IWR_PWM (1 << PWM_IRQ_NUM) /* Pulse-Width Modulator int. */ +#define IWR_INT0 (1 << INT0_IRQ_NUM) /* External INT0 */ +#define IWR_INT1 (1 << INT1_IRQ_NUM) /* External INT1 */ +#define IWR_INT2 (1 << INT2_IRQ_NUM) /* External INT2 */ +#define IWR_INT3 (1 << INT3_IRQ_NUM) /* External INT3 */ +#define IWR_INT4 (1 << INT4_IRQ_NUM) /* External INT4 */ +#define IWR_INT5 (1 << INT5_IRQ_NUM) /* External INT5 */ +#define IWR_INT6 (1 << INT6_IRQ_NUM) /* External INT6 */ +#define IWR_INT7 (1 << INT7_IRQ_NUM) /* External INT7 */ +#define IWR_IRQ1 (1 << IRQ1_IRQ_NUM) /* IRQ1 */ +#define IWR_IRQ2 (1 << IRQ2_IRQ_NUM) /* IRQ2 */ +#define IWR_IRQ3 (1 << IRQ3_IRQ_NUM) /* IRQ3 */ +#define IWR_IRQ6 (1 << IRQ6_IRQ_NUM) /* IRQ6 */ +#define IWR_PEN (1 << PEN_IRQ_NUM) /* Pen Interrupt */ +#define IWR_SPIS (1 << SPIS_IRQ_NUM) /* SPI Slave Interrupt */ +#define IWR_TMR1 (1 << TMR1_IRQ_NUM) /* Timer 1 interrupt */ +#define IWR_IRQ7 (1 << IRQ7_IRQ_NUM) /* IRQ7 */ + +/* + * Interrupt Status Register + */ +#define ISR_ADDR 0xfffff30c +#define ISR LONG_REF(ISR_ADDR) + +#define ISR_SPIM (1 << SPIM _IRQ_NUM) /* SPI Master interrupt */ +#define ISR_TMR2 (1 << TMR2_IRQ_NUM) /* Timer 2 interrupt */ +#define ISR_UART (1 << UART_IRQ_NUM) /* UART interrupt */ +#define ISR_WDT (1 << WDT_IRQ_NUM) /* Watchdog Timer interrupt */ +#define ISR_RTC (1 << RTC_IRQ_NUM) /* RTC interrupt */ +#define ISR_KB (1 << KB_IRQ_NUM) /* Keyboard Interrupt */ +#define ISR_PWM (1 << PWM_IRQ_NUM) /* Pulse-Width Modulator int. */ +#define ISR_INT0 (1 << INT0_IRQ_NUM) /* External INT0 */ +#define ISR_INT1 (1 << INT1_IRQ_NUM) /* External INT1 */ +#define ISR_INT2 (1 << INT2_IRQ_NUM) /* External INT2 */ +#define ISR_INT3 (1 << INT3_IRQ_NUM) /* External INT3 */ +#define ISR_INT4 (1 << INT4_IRQ_NUM) /* External INT4 */ +#define ISR_INT5 (1 << INT5_IRQ_NUM) /* External INT5 */ +#define ISR_INT6 (1 << INT6_IRQ_NUM) /* External INT6 */ +#define ISR_INT7 (1 << INT7_IRQ_NUM) /* External INT7 */ +#define ISR_IRQ1 (1 << IRQ1_IRQ_NUM) /* IRQ1 */ +#define ISR_IRQ2 (1 << IRQ2_IRQ_NUM) /* IRQ2 */ +#define ISR_IRQ3 (1 << IRQ3_IRQ_NUM) /* IRQ3 */ +#define ISR_IRQ6 (1 << IRQ6_IRQ_NUM) /* IRQ6 */ +#define ISR_PEN (1 << PEN_IRQ_NUM) /* Pen Interrupt */ +#define ISR_SPIS (1 << SPIS_IRQ_NUM) /* SPI Slave Interrupt */ +#define ISR_TMR1 (1 << TMR1_IRQ_NUM) /* Timer 1 interrupt */ +#define ISR_IRQ7 (1 << IRQ7_IRQ_NUM) /* IRQ7 */ + +/* 'EZ328-compatible definitions */ +#define ISR_SPI ISR_SPIM +#define ISR_TMR ISR_TMR1 + +/* + * Interrupt Pending Register + */ +#define IPR_ADDR 0xfffff310 +#define IPR LONG_REF(IPR_ADDR) + +#define IPR_SPIM (1 << SPIM _IRQ_NUM) /* SPI Master interrupt */ +#define IPR_TMR2 (1 << TMR2_IRQ_NUM) /* Timer 2 interrupt */ +#define IPR_UART (1 << UART_IRQ_NUM) /* UART interrupt */ +#define IPR_WDT (1 << WDT_IRQ_NUM) /* Watchdog Timer interrupt */ +#define IPR_RTC (1 << RTC_IRQ_NUM) /* RTC interrupt */ +#define IPR_KB (1 << KB_IRQ_NUM) /* Keyboard Interrupt */ +#define IPR_PWM (1 << PWM_IRQ_NUM) /* Pulse-Width Modulator int. */ +#define IPR_INT0 (1 << INT0_IRQ_NUM) /* External INT0 */ +#define IPR_INT1 (1 << INT1_IRQ_NUM) /* External INT1 */ +#define IPR_INT2 (1 << INT2_IRQ_NUM) /* External INT2 */ +#define IPR_INT3 (1 << INT3_IRQ_NUM) /* External INT3 */ +#define IPR_INT4 (1 << INT4_IRQ_NUM) /* External INT4 */ +#define IPR_INT5 (1 << INT5_IRQ_NUM) /* External INT5 */ +#define IPR_INT6 (1 << INT6_IRQ_NUM) /* External INT6 */ +#define IPR_INT7 (1 << INT7_IRQ_NUM) /* External INT7 */ +#define IPR_IRQ1 (1 << IRQ1_IRQ_NUM) /* IRQ1 */ +#define IPR_IRQ2 (1 << IRQ2_IRQ_NUM) /* IRQ2 */ +#define IPR_IRQ3 (1 << IRQ3_IRQ_NUM) /* IRQ3 */ +#define IPR_IRQ6 (1 << IRQ6_IRQ_NUM) /* IRQ6 */ +#define IPR_PEN (1 << PEN_IRQ_NUM) /* Pen Interrupt */ +#define IPR_SPIS (1 << SPIS_IRQ_NUM) /* SPI Slave Interrupt */ +#define IPR_TMR1 (1 << TMR1_IRQ_NUM) /* Timer 1 interrupt */ +#define IPR_IRQ7 (1 << IRQ7_IRQ_NUM) /* IRQ7 */ + +/* 'EZ328-compatible definitions */ +#define IPR_SPI IPR_SPIM +#define IPR_TMR IPR_TMR1 + +/********** + * + * 0xFFFFF4xx -- Parallel Ports + * + **********/ + +/* + * Port A + */ +#define PADIR_ADDR 0xfffff400 /* Port A direction reg */ +#define PADATA_ADDR 0xfffff401 /* Port A data register */ +#define PASEL_ADDR 0xfffff403 /* Port A Select register */ + +#define PADIR BYTE_REF(PADIR_ADDR) +#define PADATA BYTE_REF(PADATA_ADDR) +#define PASEL BYTE_REF(PASEL_ADDR) + +#define PA(x) (1 << (x)) +#define PA_A(x) PA((x) - 16) /* This is specific to PA only! */ + +#define PA_A16 PA(0) /* Use A16 as PA(0) */ +#define PA_A17 PA(1) /* Use A17 as PA(1) */ +#define PA_A18 PA(2) /* Use A18 as PA(2) */ +#define PA_A19 PA(3) /* Use A19 as PA(3) */ +#define PA_A20 PA(4) /* Use A20 as PA(4) */ +#define PA_A21 PA(5) /* Use A21 as PA(5) */ +#define PA_A22 PA(6) /* Use A22 as PA(6) */ +#define PA_A23 PA(7) /* Use A23 as PA(7) */ + +/* + * Port B + */ +#define PBDIR_ADDR 0xfffff408 /* Port B direction reg */ +#define PBDATA_ADDR 0xfffff409 /* Port B data register */ +#define PBSEL_ADDR 0xfffff40b /* Port B Select Register */ + +#define PBDIR BYTE_REF(PBDIR_ADDR) +#define PBDATA BYTE_REF(PBDATA_ADDR) +#define PBSEL BYTE_REF(PBSEL_ADDR) + +#define PB(x) (1 << (x)) +#define PB_D(x) PB(x) /* This is specific to port B only */ + +#define PB_D0 PB(0) /* Use D0 as PB(0) */ +#define PB_D1 PB(1) /* Use D1 as PB(1) */ +#define PB_D2 PB(2) /* Use D2 as PB(2) */ +#define PB_D3 PB(3) /* Use D3 as PB(3) */ +#define PB_D4 PB(4) /* Use D4 as PB(4) */ +#define PB_D5 PB(5) /* Use D5 as PB(5) */ +#define PB_D6 PB(6) /* Use D6 as PB(6) */ +#define PB_D7 PB(7) /* Use D7 as PB(7) */ + +/* + * Port C + */ +#define PCDIR_ADDR 0xfffff410 /* Port C direction reg */ +#define PCDATA_ADDR 0xfffff411 /* Port C data register */ +#define PCSEL_ADDR 0xfffff413 /* Port C Select Register */ + +#define PCDIR BYTE_REF(PCDIR_ADDR) +#define PCDATA BYTE_REF(PCDATA_ADDR) +#define PCSEL BYTE_REF(PCSEL_ADDR) + +#define PC(x) (1 << (x)) + +#define PC_WE PC(6) /* Use WE as PC(6) */ +#define PC_DTACK PC(5) /* Use DTACK as PC(5) */ +#define PC_IRQ7 PC(4) /* Use IRQ7 as PC(4) */ +#define PC_LDS PC(2) /* Use LDS as PC(2) */ +#define PC_UDS PC(1) /* Use UDS as PC(1) */ +#define PC_MOCLK PC(0) /* Use MOCLK as PC(0) */ + +/* + * Port D + */ +#define PDDIR_ADDR 0xfffff418 /* Port D direction reg */ +#define PDDATA_ADDR 0xfffff419 /* Port D data register */ +#define PDPUEN_ADDR 0xfffff41a /* Port D Pull-Up enable reg */ +#define PDPOL_ADDR 0xfffff41c /* Port D Polarity Register */ +#define PDIRQEN_ADDR 0xfffff41d /* Port D IRQ enable register */ +#define PDIQEG_ADDR 0xfffff41f /* Port D IRQ Edge Register */ + +#define PDDIR BYTE_REF(PDDIR_ADDR) +#define PDDATA BYTE_REF(PDDATA_ADDR) +#define PDPUEN BYTE_REF(PDPUEN_ADDR) +#define PDPOL BYTE_REF(PDPOL_ADDR) +#define PDIRQEN BYTE_REF(PDIRQEN_ADDR) +#define PDIQEG BYTE_REF(PDIQEG_ADDR) + +#define PD(x) (1 << (x)) +#define PD_KB(x) PD(x) /* This is specific for Port D only */ + +#define PD_KB0 PD(0) /* Use KB0 as PD(0) */ +#define PD_KB1 PD(1) /* Use KB1 as PD(1) */ +#define PD_KB2 PD(2) /* Use KB2 as PD(2) */ +#define PD_KB3 PD(3) /* Use KB3 as PD(3) */ +#define PD_KB4 PD(4) /* Use KB4 as PD(4) */ +#define PD_KB5 PD(5) /* Use KB5 as PD(5) */ +#define PD_KB6 PD(6) /* Use KB6 as PD(6) */ +#define PD_KB7 PD(7) /* Use KB7 as PD(7) */ + +/* + * Port E + */ +#define PEDIR_ADDR 0xfffff420 /* Port E direction reg */ +#define PEDATA_ADDR 0xfffff421 /* Port E data register */ +#define PEPUEN_ADDR 0xfffff422 /* Port E Pull-Up enable reg */ +#define PESEL_ADDR 0xfffff423 /* Port E Select Register */ + +#define PEDIR BYTE_REF(PEDIR_ADDR) +#define PEDATA BYTE_REF(PEDATA_ADDR) +#define PEPUEN BYTE_REF(PEPUEN_ADDR) +#define PESEL BYTE_REF(PESEL_ADDR) + +#define PE(x) (1 << (x)) + +#define PE_CSA1 PE(1) /* Use CSA1 as PE(1) */ +#define PE_CSA2 PE(2) /* Use CSA2 as PE(2) */ +#define PE_CSA3 PE(3) /* Use CSA3 as PE(3) */ +#define PE_CSB0 PE(4) /* Use CSB0 as PE(4) */ +#define PE_CSB1 PE(5) /* Use CSB1 as PE(5) */ +#define PE_CSB2 PE(6) /* Use CSB2 as PE(6) */ +#define PE_CSB3 PE(7) /* Use CSB3 as PE(7) */ + +/* + * Port F + */ +#define PFDIR_ADDR 0xfffff428 /* Port F direction reg */ +#define PFDATA_ADDR 0xfffff429 /* Port F data register */ +#define PFPUEN_ADDR 0xfffff42a /* Port F Pull-Up enable reg */ +#define PFSEL_ADDR 0xfffff42b /* Port F Select Register */ + +#define PFDIR BYTE_REF(PFDIR_ADDR) +#define PFDATA BYTE_REF(PFDATA_ADDR) +#define PFPUEN BYTE_REF(PFPUEN_ADDR) +#define PFSEL BYTE_REF(PFSEL_ADDR) + +#define PF(x) (1 << (x)) +#define PF_A(x) PF((x) - 24) /* This is Port F specific only */ + +#define PF_A24 PF(0) /* Use A24 as PF(0) */ +#define PF_A25 PF(1) /* Use A25 as PF(1) */ +#define PF_A26 PF(2) /* Use A26 as PF(2) */ +#define PF_A27 PF(3) /* Use A27 as PF(3) */ +#define PF_A28 PF(4) /* Use A28 as PF(4) */ +#define PF_A29 PF(5) /* Use A29 as PF(5) */ +#define PF_A30 PF(6) /* Use A30 as PF(6) */ +#define PF_A31 PF(7) /* Use A31 as PF(7) */ + +/* + * Port G + */ +#define PGDIR_ADDR 0xfffff430 /* Port G direction reg */ +#define PGDATA_ADDR 0xfffff431 /* Port G data register */ +#define PGPUEN_ADDR 0xfffff432 /* Port G Pull-Up enable reg */ +#define PGSEL_ADDR 0xfffff433 /* Port G Select Register */ + +#define PGDIR BYTE_REF(PGDIR_ADDR) +#define PGDATA BYTE_REF(PGDATA_ADDR) +#define PGPUEN BYTE_REF(PGPUEN_ADDR) +#define PGSEL BYTE_REF(PGSEL_ADDR) + +#define PG(x) (1 << (x)) + +#define PG_UART_TXD PG(0) /* Use UART_TXD as PG(0) */ +#define PG_UART_RXD PG(1) /* Use UART_RXD as PG(1) */ +#define PG_PWMOUT PG(2) /* Use PWMOUT as PG(2) */ +#define PG_TOUT2 PG(3) /* Use TOUT2 as PG(3) */ +#define PG_TIN2 PG(4) /* Use TIN2 as PG(4) */ +#define PG_TOUT1 PG(5) /* Use TOUT1 as PG(5) */ +#define PG_TIN1 PG(6) /* Use TIN1 as PG(6) */ +#define PG_RTCOUT PG(7) /* Use RTCOUT as PG(7) */ + +/* + * Port J + */ +#define PJDIR_ADDR 0xfffff438 /* Port J direction reg */ +#define PJDATA_ADDR 0xfffff439 /* Port J data register */ +#define PJSEL_ADDR 0xfffff43b /* Port J Select Register */ + +#define PJDIR BYTE_REF(PJDIR_ADDR) +#define PJDATA BYTE_REF(PJDATA_ADDR) +#define PJSEL BYTE_REF(PJSEL_ADDR) + +#define PJ(x) (1 << (x)) + +#define PJ_CSD3 PJ(7) /* Use CSD3 as PJ(7) */ + +/* + * Port K + */ +#define PKDIR_ADDR 0xfffff440 /* Port K direction reg */ +#define PKDATA_ADDR 0xfffff441 /* Port K data register */ +#define PKPUEN_ADDR 0xfffff442 /* Port K Pull-Up enable reg */ +#define PKSEL_ADDR 0xfffff443 /* Port K Select Register */ + +#define PKDIR BYTE_REF(PKDIR_ADDR) +#define PKDATA BYTE_REF(PKDATA_ADDR) +#define PKPUEN BYTE_REF(PKPUEN_ADDR) +#define PKSEL BYTE_REF(PKSEL_ADDR) + +#define PK(x) (1 << (x)) + +/* + * Port M + */ +#define PMDIR_ADDR 0xfffff438 /* Port M direction reg */ +#define PMDATA_ADDR 0xfffff439 /* Port M data register */ +#define PMPUEN_ADDR 0xfffff43a /* Port M Pull-Up enable reg */ +#define PMSEL_ADDR 0xfffff43b /* Port M Select Register */ + +#define PMDIR BYTE_REF(PMDIR_ADDR) +#define PMDATA BYTE_REF(PMDATA_ADDR) +#define PMPUEN BYTE_REF(PMPUEN_ADDR) +#define PMSEL BYTE_REF(PMSEL_ADDR) + +#define PM(x) (1 << (x)) + +/********** + * + * 0xFFFFF5xx -- Pulse-Width Modulator (PWM) + * + **********/ + +/* + * PWM Control Register + */ +#define PWMC_ADDR 0xfffff500 +#define PWMC WORD_REF(PWMC_ADDR) + +#define PWMC_CLKSEL_MASK 0x0007 /* Clock Selection */ +#define PWMC_CLKSEL_SHIFT 0 +#define PWMC_PWMEN 0x0010 /* Enable PWM */ +#define PMNC_POL 0x0020 /* PWM Output Bit Polarity */ +#define PWMC_PIN 0x0080 /* Current PWM output pin status */ +#define PWMC_LOAD 0x0100 /* Force a new period */ +#define PWMC_IRQEN 0x4000 /* Interrupt Request Enable */ +#define PWMC_CLKSRC 0x8000 /* Clock Source Select */ + +/* 'EZ328-compatible definitions */ +#define PWMC_EN PWMC_PWMEN + +/* + * PWM Period Register + */ +#define PWMP_ADDR 0xfffff502 +#define PWMP WORD_REF(PWMP_ADDR) + +/* + * PWM Width Register + */ +#define PWMW_ADDR 0xfffff504 +#define PWMW WORD_REF(PWMW_ADDR) + +/* + * PWM Counter Register + */ +#define PWMCNT_ADDR 0xfffff506 +#define PWMCNT WORD_REF(PWMCNT_ADDR) + +/********** + * + * 0xFFFFF6xx -- General-Purpose Timers + * + **********/ + +/* + * Timer Unit 1 and 2 Control Registers + */ +#define TCTL1_ADDR 0xfffff600 +#define TCTL1 WORD_REF(TCTL1_ADDR) +#define TCTL2_ADDR 0xfffff60c +#define TCTL2 WORD_REF(TCTL2_ADDR) + +#define TCTL_TEN 0x0001 /* Timer Enable */ +#define TCTL_CLKSOURCE_MASK 0x000e /* Clock Source: */ +#define TCTL_CLKSOURCE_STOP 0x0000 /* Stop count (disabled) */ +#define TCTL_CLKSOURCE_SYSCLK 0x0002 /* SYSCLK to prescaler */ +#define TCTL_CLKSOURCE_SYSCLK_16 0x0004 /* SYSCLK/16 to prescaler */ +#define TCTL_CLKSOURCE_TIN 0x0006 /* TIN to prescaler */ +#define TCTL_CLKSOURCE_32KHZ 0x0008 /* 32kHz clock to prescaler */ +#define TCTL_IRQEN 0x0010 /* IRQ Enable */ +#define TCTL_OM 0x0020 /* Output Mode */ +#define TCTL_CAP_MASK 0x00c0 /* Capture Edge: */ +#define TCTL_CAP_RE 0x0040 /* Capture on rizing edge */ +#define TCTL_CAP_FE 0x0080 /* Capture on falling edge */ +#define TCTL_FRR 0x0010 /* Free-Run Mode */ + +/* 'EZ328-compatible definitions */ +#define TCTL_ADDR TCTL1_ADDR +#define TCTL TCTL1 + +/* + * Timer Unit 1 and 2 Prescaler Registers + */ +#define TPRER1_ADDR 0xfffff602 +#define TPRER1 WORD_REF(TPRER1_ADDR) +#define TPRER2_ADDR 0xfffff60e +#define TPRER2 WORD_REF(TPRER2_ADDR) + +/* 'EZ328-compatible definitions */ +#define TPRER_ADDR TPRER1_ADDR +#define TPRER TPRER1 + +/* + * Timer Unit 1 and 2 Compare Registers + */ +#define TCMP1_ADDR 0xfffff604 +#define TCMP1 WORD_REF(TCMP1_ADDR) +#define TCMP2_ADDR 0xfffff610 +#define TCMP2 WORD_REF(TCMP2_ADDR) + +/* 'EZ328-compatible definitions */ +#define TCMP_ADDR TCMP1_ADDR +#define TCMP TCMP1 + +/* + * Timer Unit 1 and 2 Capture Registers + */ +#define TCR1_ADDR 0xfffff606 +#define TCR1 WORD_REF(TCR1_ADDR) +#define TCR2_ADDR 0xfffff612 +#define TCR2 WORD_REF(TCR2_ADDR) + +/* 'EZ328-compatible definitions */ +#define TCR_ADDR TCR1_ADDR +#define TCR TCR1 + +/* + * Timer Unit 1 and 2 Counter Registers + */ +#define TCN1_ADDR 0xfffff608 +#define TCN1 WORD_REF(TCN1_ADDR) +#define TCN2_ADDR 0xfffff614 +#define TCN2 WORD_REF(TCN2_ADDR) + +/* 'EZ328-compatible definitions */ +#define TCN_ADDR TCN1_ADDR +#define TCN TCN + +/* + * Timer Unit 1 and 2 Status Registers + */ +#define TSTAT1_ADDR 0xfffff60a +#define TSTAT1 WORD_REF(TSTAT1_ADDR) +#define TSTAT2_ADDR 0xfffff616 +#define TSTAT2 WORD_REF(TSTAT2_ADDR) + +#define TSTAT_COMP 0x0001 /* Compare Event occurred */ +#define TSTAT_CAPT 0x0001 /* Capture Event occurred */ + +/* 'EZ328-compatible definitions */ +#define TSTAT_ADDR TSTAT1_ADDR +#define TSTAT TSTAT1 + +/* + * Watchdog Compare Register + */ +#define WRR_ADDR 0xfffff61a +#define WRR WORD_REF(WRR_ADDR) + +/* + * Watchdog Counter Register + */ +#define WCN_ADDR 0xfffff61c +#define WCN WORD_REF(WCN_ADDR) + +/* + * Watchdog Control and Status Register + */ +#define WCSR_ADDR 0xfffff618 +#define WCSR WORD_REF(WCSR_ADDR) + +#define WCSR_WDEN 0x0001 /* Watchdog Enable */ +#define WCSR_FI 0x0002 /* Forced Interrupt (instead of SW reset)*/ +#define WCSR_WRST 0x0004 /* Watchdog Reset */ + +/********** + * + * 0xFFFFF7xx -- Serial Periferial Interface Slave (SPIS) + * + **********/ + +/* + * SPI Slave Register + */ +#define SPISR_ADDR 0xfffff700 +#define SPISR WORD_REF(SPISR_ADDR) + +#define SPISR_DATA_ADDR 0xfffff701 +#define SPISR_DATA BYTE_REF(SPISR_DATA_ADDR) + +#define SPISR_DATA_MASK 0x00ff /* Shifted data from the external device */ +#define SPISR_DATA_SHIFT 0 +#define SPISR_SPISEN 0x0100 /* SPIS module enable */ +#define SPISR_POL 0x0200 /* SPSCLK polarity control */ +#define SPISR_PHA 0x0400 /* Phase relationship between SPSCLK & SPSRxD */ +#define SPISR_OVWR 0x0800 /* Data buffer has been overwritten */ +#define SPISR_DATARDY 0x1000 /* Data ready */ +#define SPISR_ENPOL 0x2000 /* Enable Polarity */ +#define SPISR_IRQEN 0x4000 /* SPIS IRQ Enable */ +#define SPISR_SPISIRQ 0x8000 /* SPIS IRQ posted */ + +/********** + * + * 0xFFFFF8xx -- Serial Periferial Interface Master (SPIM) + * + **********/ + +/* + * SPIM Data Register + */ +#define SPIMDATA_ADDR 0xfffff800 +#define SPIMDATA WORD_REF(SPIMDATA_ADDR) + +/* + * SPIM Control/Status Register + */ +#define SPIMCONT_ADDR 0xfffff802 +#define SPIMCONT WORD_REF(SPIMCONT_ADDR) + +#define SPIMCONT_BIT_COUNT_MASK 0x000f /* Transfer Length in Bytes */ +#define SPIMCONT_BIT_COUNT_SHIFT 0 +#define SPIMCONT_POL 0x0010 /* SPMCLK Signel Polarity */ +#define SPIMCONT_PHA 0x0020 /* Clock/Data phase relationship */ +#define SPIMCONT_IRQEN 0x0040 /* IRQ Enable */ +#define SPIMCONT_SPIMIRQ 0x0080 /* Interrupt Request */ +#define SPIMCONT_XCH 0x0100 /* Exchange */ +#define SPIMCONT_RSPIMEN 0x0200 /* Enable SPIM */ +#define SPIMCONT_DATA_RATE_MASK 0xe000 /* SPIM Data Rate */ +#define SPIMCONT_DATA_RATE_SHIFT 13 + +/* 'EZ328-compatible definitions */ +#define SPIMCONT_IRQ SPIMCONT_SPIMIRQ +#define SPIMCONT_ENABLE SPIMCONT_SPIMEN +/********** + * + * 0xFFFFF9xx -- UART + * + **********/ + +/* + * UART Status/Control Register + */ +#define USTCNT_ADDR 0xfffff900 +#define USTCNT WORD_REF(USTCNT_ADDR) + +#define USTCNT_TXAVAILEN 0x0001 /* Transmitter Available Int Enable */ +#define USTCNT_TXHALFEN 0x0002 /* Transmitter Half Empty Int Enable */ +#define USTCNT_TXEMPTYEN 0x0004 /* Transmitter Empty Int Enable */ +#define USTCNT_RXREADYEN 0x0008 /* Receiver Ready Interrupt Enable */ +#define USTCNT_RXHALFEN 0x0010 /* Receiver Half-Full Int Enable */ +#define USTCNT_RXFULLEN 0x0020 /* Receiver Full Interrupt Enable */ +#define USTCNT_CTSDELTAEN 0x0040 /* CTS Delta Interrupt Enable */ +#define USTCNT_GPIODELTAEN 0x0080 /* Old Data Interrupt Enable */ +#define USTCNT_8_7 0x0100 /* Eight or seven-bit transmission */ +#define USTCNT_STOP 0x0200 /* Stop bit transmission */ +#define USTCNT_ODD_EVEN 0x0400 /* Odd Parity */ +#define USTCNT_PARITYEN 0x0800 /* Parity Enable */ +#define USTCNT_CLKMODE 0x1000 /* Clock Mode Select */ +#define USTCNT_TXEN 0x2000 /* Transmitter Enable */ +#define USTCNT_RXEN 0x4000 /* Receiver Enable */ +#define USTCNT_UARTEN 0x8000 /* UART Enable */ + +/* 'EZ328-compatible definitions */ +#define USTCNT_TXAE USTCNT_TXAVAILEN +#define USTCNT_TXHE USTCNT_TXHALFEN +#define USTCNT_TXEE USTCNT_TXEMPTYEN +#define USTCNT_RXRE USTCNT_RXREADYEN +#define USTCNT_RXHE USTCNT_RXHALFEN +#define USTCNT_RXFE USTCNT_RXFULLEN +#define USTCNT_CTSD USTCNT_CTSDELTAEN +#define USTCNT_ODD USTCNT_ODD_EVEN +#define USTCNT_PEN USTCNT_PARITYEN +#define USTCNT_CLKM USTCNT_CLKMODE +#define USTCNT_UEN USTCNT_UARTEN + +/* + * UART Baud Control Register + */ +#define UBAUD_ADDR 0xfffff902 +#define UBAUD WORD_REF(UBAUD_ADDR) + +#define UBAUD_PRESCALER_MASK 0x003f /* Actual divisor is 65 - PRESCALER */ +#define UBAUD_PRESCALER_SHIFT 0 +#define UBAUD_DIVIDE_MASK 0x0700 /* Baud Rate freq. divizor */ +#define UBAUD_DIVIDE_SHIFT 8 +#define UBAUD_BAUD_SRC 0x0800 /* Baud Rate Source */ +#define UBAUD_GPIOSRC 0x1000 /* GPIO source */ +#define UBAUD_GPIODIR 0x2000 /* GPIO Direction */ +#define UBAUD_GPIO 0x4000 /* Current GPIO pin status */ +#define UBAUD_GPIODELTA 0x8000 /* GPIO pin value changed */ + +/* + * UART Receiver Register + */ +#define URX_ADDR 0xfffff904 +#define URX WORD_REF(URX_ADDR) + +#define URX_RXDATA_ADDR 0xfffff905 +#define URX_RXDATA BYTE_REF(URX_RXDATA_ADDR) + +#define URX_RXDATA_MASK 0x00ff /* Received data */ +#define URX_RXDATA_SHIFT 0 +#define URX_PARITY_ERROR 0x0100 /* Parity Error */ +#define URX_BREAK 0x0200 /* Break Detected */ +#define URX_FRAME_ERROR 0x0400 /* Framing Error */ +#define URX_OVRUN 0x0800 /* Serial Overrun */ +#define URX_DATA_READY 0x2000 /* Data Ready (FIFO not empty) */ +#define URX_FIFO_HALF 0x4000 /* FIFO is Half-Full */ +#define URX_FIFO_FULL 0x8000 /* FIFO is Full */ + +/* + * UART Transmitter Register + */ +#define UTX_ADDR 0xfffff906 +#define UTX WORD_REF(UTX_ADDR) + +#define UTX_TXDATA_ADDR 0xfffff907 +#define UTX_TXDATA BYTE_REF(UTX_TXDATA_ADDR) + +#define UTX_TXDATA_MASK 0x00ff /* Data to be transmitted */ +#define UTX_TXDATA_SHIFT 0 +#define UTX_CTS_DELTA 0x0100 /* CTS changed */ +#define UTX_CTS_STATUS 0x0200 /* CTS State */ +#define UTX_IGNORE_CTS 0x0800 /* Ignore CTS */ +#define UTX_SEND_BREAK 0x1000 /* Send a BREAK */ +#define UTX_TX_AVAIL 0x2000 /* Transmit FIFO has a slot available */ +#define UTX_FIFO_HALF 0x4000 /* Transmit FIFO is half empty */ +#define UTX_FIFO_EMPTY 0x8000 /* Transmit FIFO is empty */ + +/* 'EZ328-compatible definitions */ +#define UTX_CTS_STAT UTX_CTS_STATUS +#define UTX_NOCTS UTX_IGNORE_CTS + +/* + * UART Miscellaneous Register + */ +#define UMISC_ADDR 0xfffff908 +#define UMISC WORD_REF(UMISC_ADDR) + +#define UMISC_TX_POL 0x0004 /* Transmit Polarity */ +#define UMISC_RX_POL 0x0008 /* Receive Polarity */ +#define UMISC_IRDA_LOOP 0x0010 /* IrDA Loopback Enable */ +#define UMISC_IRDA_EN 0x0020 /* Infra-Red Enable */ +#define UMISC_RTS 0x0040 /* Set RTS status */ +#define UMISC_RTSCONT 0x0080 /* Choose RTS control */ +#define UMISC_LOOP 0x1000 /* Serial Loopback Enable */ +#define UMISC_FORCE_PERR 0x2000 /* Force Parity Error */ +#define UMISC_CLKSRC 0x4000 /* Clock Source */ + + +/* generalization of uart control registers to support multiple ports: */ +typedef volatile struct { + volatile unsigned short int ustcnt; + volatile unsigned short int ubaud; + union { + volatile unsigned short int w; + struct { + volatile unsigned char status; + volatile unsigned char rxdata; + } b; + } urx; + union { + volatile unsigned short int w; + struct { + volatile unsigned char status; + volatile unsigned char txdata; + } b; + } utx; + volatile unsigned short int umisc; + volatile unsigned short int pad1; + volatile unsigned short int pad2; + volatile unsigned short int pad3; +} __attribute__((packed)) m68328_uart; + + +/********** + * + * 0xFFFFFAxx -- LCD Controller + * + **********/ + +/* + * LCD Screen Starting Address Register + */ +#define LSSA_ADDR 0xfffffa00 +#define LSSA LONG_REF(LSSA_ADDR) + +#define LSSA_SSA_MASK 0xfffffffe /* Bit 0 is reserved */ + +/* + * LCD Virtual Page Width Register + */ +#define LVPW_ADDR 0xfffffa05 +#define LVPW BYTE_REF(LVPW_ADDR) + +/* + * LCD Screen Width Register (not compatible with 'EZ328 !!!) + */ +#define LXMAX_ADDR 0xfffffa08 +#define LXMAX WORD_REF(LXMAX_ADDR) + +#define LXMAX_XM_MASK 0x02ff /* Bits 0-3 are reserved */ + +/* + * LCD Screen Height Register + */ +#define LYMAX_ADDR 0xfffffa0a +#define LYMAX WORD_REF(LYMAX_ADDR) + +#define LYMAX_YM_MASK 0x02ff /* Bits 10-15 are reserved */ + +/* + * LCD Cursor X Position Register + */ +#define LCXP_ADDR 0xfffffa18 +#define LCXP WORD_REF(LCXP_ADDR) + +#define LCXP_CC_MASK 0xc000 /* Cursor Control */ +#define LCXP_CC_TRAMSPARENT 0x0000 +#define LCXP_CC_BLACK 0x4000 +#define LCXP_CC_REVERSED 0x8000 +#define LCXP_CC_WHITE 0xc000 +#define LCXP_CXP_MASK 0x02ff /* Cursor X position */ + +/* + * LCD Cursor Y Position Register + */ +#define LCYP_ADDR 0xfffffa1a +#define LCYP WORD_REF(LCYP_ADDR) + +#define LCYP_CYP_MASK 0x01ff /* Cursor Y Position */ + +/* + * LCD Cursor Width and Heigth Register + */ +#define LCWCH_ADDR 0xfffffa1c +#define LCWCH WORD_REF(LCWCH_ADDR) + +#define LCWCH_CH_MASK 0x001f /* Cursor Height */ +#define LCWCH_CH_SHIFT 0 +#define LCWCH_CW_MASK 0x1f00 /* Cursor Width */ +#define LCWCH_CW_SHIFT 8 + +/* + * LCD Blink Control Register + */ +#define LBLKC_ADDR 0xfffffa1f +#define LBLKC BYTE_REF(LBLKC_ADDR) + +#define LBLKC_BD_MASK 0x7f /* Blink Divisor */ +#define LBLKC_BD_SHIFT 0 +#define LBLKC_BKEN 0x80 /* Blink Enabled */ + +/* + * LCD Panel Interface Configuration Register + */ +#define LPICF_ADDR 0xfffffa20 +#define LPICF BYTE_REF(LPICF_ADDR) + +#define LPICF_GS_MASK 0x01 /* Gray-Scale Mode */ +#define LPICF_GS_BW 0x00 +#define LPICF_GS_GRAY_4 0x01 +#define LPICF_PBSIZ_MASK 0x06 /* Panel Bus Width */ +#define LPICF_PBSIZ_1 0x00 +#define LPICF_PBSIZ_2 0x02 +#define LPICF_PBSIZ_4 0x04 + +/* + * LCD Polarity Configuration Register + */ +#define LPOLCF_ADDR 0xfffffa21 +#define LPOLCF BYTE_REF(LPOLCF_ADDR) + +#define LPOLCF_PIXPOL 0x01 /* Pixel Polarity */ +#define LPOLCF_LPPOL 0x02 /* Line Pulse Polarity */ +#define LPOLCF_FLMPOL 0x04 /* Frame Marker Polarity */ +#define LPOLCF_LCKPOL 0x08 /* LCD Shift Lock Polarity */ + +/* + * LACD (LCD Alternate Crystal Direction) Rate Control Register + */ +#define LACDRC_ADDR 0xfffffa23 +#define LACDRC BYTE_REF(LACDRC_ADDR) + +#define LACDRC_ACD_MASK 0x0f /* Alternate Crystal Direction Control */ +#define LACDRC_ACD_SHIFT 0 + +/* + * LCD Pixel Clock Divider Register + */ +#define LPXCD_ADDR 0xfffffa25 +#define LPXCD BYTE_REF(LPXCD_ADDR) + +#define LPXCD_PCD_MASK 0x3f /* Pixel Clock Divider */ +#define LPXCD_PCD_SHIFT 0 + +/* + * LCD Clocking Control Register + */ +#define LCKCON_ADDR 0xfffffa27 +#define LCKCON BYTE_REF(LCKCON_ADDR) + +#define LCKCON_PCDS 0x01 /* Pixel Clock Divider Source Select */ +#define LCKCON_DWIDTH 0x02 /* Display Memory Width */ +#define LCKCON_DWS_MASK 0x3c /* Display Wait-State */ +#define LCKCON_DWS_SHIFT 2 +#define LCKCON_DMA16 0x40 /* DMA burst length */ +#define LCKCON_LCDON 0x80 /* Enable LCD Controller */ + +/* 'EZ328-compatible definitions */ +#define LCKCON_DW_MASK LCKCON_DWS_MASK +#define LCKCON_DW_SHIFT LCKCON_DWS_SHIFT + +/* + * LCD Last Buffer Address Register + */ +#define LLBAR_ADDR 0xfffffa29 +#define LLBAR BYTE_REF(LLBAR_ADDR) + +#define LLBAR_LBAR_MASK 0x7f /* Number of memory words to fill 1 line */ +#define LLBAR_LBAR_SHIFT 0 + +/* + * LCD Octet Terminal Count Register + */ +#define LOTCR_ADDR 0xfffffa2b +#define LOTCR BYTE_REF(LOTCR_ADDR) + +/* + * LCD Panning Offset Register + */ +#define LPOSR_ADDR 0xfffffa2d +#define LPOSR BYTE_REF(LPOSR_ADDR) + +#define LPOSR_BOS 0x08 /* Byte offset (for B/W mode only */ +#define LPOSR_POS_MASK 0x07 /* Pixel Offset Code */ +#define LPOSR_POS_SHIFT 0 + +/* + * LCD Frame Rate Control Modulation Register + */ +#define LFRCM_ADDR 0xfffffa31 +#define LFRCM BYTE_REF(LFRCM_ADDR) + +#define LFRCM_YMOD_MASK 0x0f /* Vertical Modulation */ +#define LFRCM_YMOD_SHIFT 0 +#define LFRCM_XMOD_MASK 0xf0 /* Horizontal Modulation */ +#define LFRCM_XMOD_SHIFT 4 + +/* + * LCD Gray Palette Mapping Register + */ +#define LGPMR_ADDR 0xfffffa32 +#define LGPMR WORD_REF(LGPMR_ADDR) + +#define LGPMR_GLEVEL3_MASK 0x000f +#define LGPMR_GLEVEL3_SHIFT 0 +#define LGPMR_GLEVEL2_MASK 0x00f0 +#define LGPMR_GLEVEL2_SHIFT 4 +#define LGPMR_GLEVEL0_MASK 0x0f00 +#define LGPMR_GLEVEL0_SHIFT 8 +#define LGPMR_GLEVEL1_MASK 0xf000 +#define LGPMR_GLEVEL1_SHIFT 12 + +/********** + * + * 0xFFFFFBxx -- Real-Time Clock (RTC) + * + **********/ + +/* + * RTC Hours Minutes and Seconds Register + */ +#define RTCTIME_ADDR 0xfffffb00 +#define RTCTIME LONG_REF(RTCTIME_ADDR) + +#define RTCTIME_SECONDS_MASK 0x0000003f /* Seconds */ +#define RTCTIME_SECONDS_SHIFT 0 +#define RTCTIME_MINUTES_MASK 0x003f0000 /* Minutes */ +#define RTCTIME_MINUTES_SHIFT 16 +#define RTCTIME_HOURS_MASK 0x1f000000 /* Hours */ +#define RTCTIME_HOURS_SHIFT 24 + +/* + * RTC Alarm Register + */ +#define RTCALRM_ADDR 0xfffffb04 +#define RTCALRM LONG_REF(RTCALRM_ADDR) + +#define RTCALRM_SECONDS_MASK 0x0000003f /* Seconds */ +#define RTCALRM_SECONDS_SHIFT 0 +#define RTCALRM_MINUTES_MASK 0x003f0000 /* Minutes */ +#define RTCALRM_MINUTES_SHIFT 16 +#define RTCALRM_HOURS_MASK 0x1f000000 /* Hours */ +#define RTCALRM_HOURS_SHIFT 24 + +/* + * RTC Control Register + */ +#define RTCCTL_ADDR 0xfffffb0c +#define RTCCTL WORD_REF(RTCCTL_ADDR) + +#define RTCCTL_384 0x0020 /* Crystal Selection */ +#define RTCCTL_ENABLE 0x0080 /* RTC Enable */ + +/* 'EZ328-compatible definitions */ +#define RTCCTL_XTL RTCCTL_384 +#define RTCCTL_EN RTCCTL_ENABLE + +/* + * RTC Interrupt Status Register + */ +#define RTCISR_ADDR 0xfffffb0e +#define RTCISR WORD_REF(RTCISR_ADDR) + +#define RTCISR_SW 0x0001 /* Stopwatch timed out */ +#define RTCISR_MIN 0x0002 /* 1-minute interrupt has occurred */ +#define RTCISR_ALM 0x0004 /* Alarm interrupt has occurred */ +#define RTCISR_DAY 0x0008 /* 24-hour rollover interrupt has occurred */ +#define RTCISR_1HZ 0x0010 /* 1Hz interrupt has occurred */ + +/* + * RTC Interrupt Enable Register + */ +#define RTCIENR_ADDR 0xfffffb10 +#define RTCIENR WORD_REF(RTCIENR_ADDR) + +#define RTCIENR_SW 0x0001 /* Stopwatch interrupt enable */ +#define RTCIENR_MIN 0x0002 /* 1-minute interrupt enable */ +#define RTCIENR_ALM 0x0004 /* Alarm interrupt enable */ +#define RTCIENR_DAY 0x0008 /* 24-hour rollover interrupt enable */ +#define RTCIENR_1HZ 0x0010 /* 1Hz interrupt enable */ + +/* + * Stopwatch Minutes Register + */ +#define STPWCH_ADDR 0xfffffb12 +#define STPWCH WORD_REF(STPWCH) + +#define STPWCH_CNT_MASK 0x00ff /* Stopwatch countdown value */ +#define SPTWCH_CNT_SHIFT 0 + +#endif /* _MC68328_H_ */ diff --git a/arch/m68k/include/asm/MC68332.h b/arch/m68k/include/asm/MC68332.h new file mode 100644 index 00000000000..6bb8f02685a --- /dev/null +++ b/arch/m68k/include/asm/MC68332.h @@ -0,0 +1,152 @@ + +/* include/asm-m68knommu/MC68332.h: '332 control registers + * + * Copyright (C) 1998 Kenneth Albanowski , + * + */ + +#ifndef _MC68332_H_ +#define _MC68332_H_ + +#define BYTE_REF(addr) (*((volatile unsigned char*)addr)) +#define WORD_REF(addr) (*((volatile unsigned short*)addr)) + +#define PORTE_ADDR 0xfffa11 +#define PORTE BYTE_REF(PORTE_ADDR) +#define DDRE_ADDR 0xfffa15 +#define DDRE BYTE_REF(DDRE_ADDR) +#define PEPAR_ADDR 0xfffa17 +#define PEPAR BYTE_REF(PEPAR_ADDR) + +#define PORTF_ADDR 0xfffa19 +#define PORTF BYTE_REF(PORTF_ADDR) +#define DDRF_ADDR 0xfffa1d +#define DDRF BYTE_REF(DDRF_ADDR) +#define PFPAR_ADDR 0xfffa1f +#define PFPAR BYTE_REF(PFPAR_ADDR) + +#define PORTQS_ADDR 0xfffc15 +#define PORTQS BYTE_REF(PORTQS_ADDR) +#define DDRQS_ADDR 0xfffc17 +#define DDRQS BYTE_REF(DDRQS_ADDR) +#define PQSPAR_ADDR 0xfffc16 +#define PQSPAR BYTE_REF(PQSPAR_ADDR) + +#define CSPAR0_ADDR 0xFFFA44 +#define CSPAR0 WORD_REF(CSPAR0_ADDR) +#define CSPAR1_ADDR 0xFFFA46 +#define CSPAR1 WORD_REF(CSPAR1_ADDR) +#define CSARBT_ADDR 0xFFFA48 +#define CSARBT WORD_REF(CSARBT_ADDR) +#define CSOPBT_ADDR 0xFFFA4A +#define CSOPBT WORD_REF(CSOPBT_ADDR) +#define CSBAR0_ADDR 0xFFFA4C +#define CSBAR0 WORD_REF(CSBAR0_ADDR) +#define CSOR0_ADDR 0xFFFA4E +#define CSOR0 WORD_REF(CSOR0_ADDR) +#define CSBAR1_ADDR 0xFFFA50 +#define CSBAR1 WORD_REF(CSBAR1_ADDR) +#define CSOR1_ADDR 0xFFFA52 +#define CSOR1 WORD_REF(CSOR1_ADDR) +#define CSBAR2_ADDR 0xFFFA54 +#define CSBAR2 WORD_REF(CSBAR2_ADDR) +#define CSOR2_ADDR 0xFFFA56 +#define CSOR2 WORD_REF(CSOR2_ADDR) +#define CSBAR3_ADDR 0xFFFA58 +#define CSBAR3 WORD_REF(CSBAR3_ADDR) +#define CSOR3_ADDR 0xFFFA5A +#define CSOR3 WORD_REF(CSOR3_ADDR) +#define CSBAR4_ADDR 0xFFFA5C +#define CSBAR4 WORD_REF(CSBAR4_ADDR) +#define CSOR4_ADDR 0xFFFA5E +#define CSOR4 WORD_REF(CSOR4_ADDR) +#define CSBAR5_ADDR 0xFFFA60 +#define CSBAR5 WORD_REF(CSBAR5_ADDR) +#define CSOR5_ADDR 0xFFFA62 +#define CSOR5 WORD_REF(CSOR5_ADDR) +#define CSBAR6_ADDR 0xFFFA64 +#define CSBAR6 WORD_REF(CSBAR6_ADDR) +#define CSOR6_ADDR 0xFFFA66 +#define CSOR6 WORD_REF(CSOR6_ADDR) +#define CSBAR7_ADDR 0xFFFA68 +#define CSBAR7 WORD_REF(CSBAR7_ADDR) +#define CSOR7_ADDR 0xFFFA6A +#define CSOR7 WORD_REF(CSOR7_ADDR) +#define CSBAR8_ADDR 0xFFFA6C +#define CSBAR8 WORD_REF(CSBAR8_ADDR) +#define CSOR8_ADDR 0xFFFA6E +#define CSOR8 WORD_REF(CSOR8_ADDR) +#define CSBAR9_ADDR 0xFFFA70 +#define CSBAR9 WORD_REF(CSBAR9_ADDR) +#define CSOR9_ADDR 0xFFFA72 +#define CSOR9 WORD_REF(CSOR9_ADDR) +#define CSBAR10_ADDR 0xFFFA74 +#define CSBAR10 WORD_REF(CSBAR10_ADDR) +#define CSOR10_ADDR 0xFFFA76 +#define CSOR10 WORD_REF(CSOR10_ADDR) + +#define CSOR_MODE_ASYNC 0x0000 +#define CSOR_MODE_SYNC 0x8000 +#define CSOR_MODE_MASK 0x8000 +#define CSOR_BYTE_DISABLE 0x0000 +#define CSOR_BYTE_UPPER 0x4000 +#define CSOR_BYTE_LOWER 0x2000 +#define CSOR_BYTE_BOTH 0x6000 +#define CSOR_BYTE_MASK 0x6000 +#define CSOR_RW_RSVD 0x0000 +#define CSOR_RW_READ 0x0800 +#define CSOR_RW_WRITE 0x1000 +#define CSOR_RW_BOTH 0x1800 +#define CSOR_RW_MASK 0x1800 +#define CSOR_STROBE_DS 0x0400 +#define CSOR_STROBE_AS 0x0000 +#define CSOR_STROBE_MASK 0x0400 +#define CSOR_DSACK_WAIT(x) (wait << 6) +#define CSOR_DSACK_FTERM (14 << 6) +#define CSOR_DSACK_EXTERNAL (15 << 6) +#define CSOR_DSACK_MASK 0x03c0 +#define CSOR_SPACE_CPU 0x0000 +#define CSOR_SPACE_USER 0x0010 +#define CSOR_SPACE_SU 0x0020 +#define CSOR_SPACE_BOTH 0x0030 +#define CSOR_SPACE_MASK 0x0030 +#define CSOR_IPL_ALL 0x0000 +#define CSOR_IPL_PRIORITY(x) (x << 1) +#define CSOR_IPL_MASK 0x000e +#define CSOR_AVEC_ON 0x0001 +#define CSOR_AVEC_OFF 0x0000 +#define CSOR_AVEC_MASK 0x0001 + +#define CSBAR_ADDR(x) ((addr >> 11) << 3) +#define CSBAR_ADDR_MASK 0xfff8 +#define CSBAR_BLKSIZE_2K 0x0000 +#define CSBAR_BLKSIZE_8K 0x0001 +#define CSBAR_BLKSIZE_16K 0x0002 +#define CSBAR_BLKSIZE_64K 0x0003 +#define CSBAR_BLKSIZE_128K 0x0004 +#define CSBAR_BLKSIZE_256K 0x0005 +#define CSBAR_BLKSIZE_512K 0x0006 +#define CSBAR_BLKSIZE_1M 0x0007 +#define CSBAR_BLKSIZE_MASK 0x0007 + +#define CSPAR_DISC 0 +#define CSPAR_ALT 1 +#define CSPAR_CS8 2 +#define CSPAR_CS16 3 +#define CSPAR_MASK 3 + +#define CSPAR0_CSBOOT(x) (x << 0) +#define CSPAR0_CS0(x) (x << 2) +#define CSPAR0_CS1(x) (x << 4) +#define CSPAR0_CS2(x) (x << 6) +#define CSPAR0_CS3(x) (x << 8) +#define CSPAR0_CS4(x) (x << 10) +#define CSPAR0_CS5(x) (x << 12) + +#define CSPAR1_CS6(x) (x << 0) +#define CSPAR1_CS7(x) (x << 2) +#define CSPAR1_CS8(x) (x << 4) +#define CSPAR1_CS9(x) (x << 6) +#define CSPAR1_CS10(x) (x << 8) + +#endif diff --git a/arch/m68k/include/asm/MC68EZ328.h b/arch/m68k/include/asm/MC68EZ328.h new file mode 100644 index 00000000000..69b7f9139e5 --- /dev/null +++ b/arch/m68k/include/asm/MC68EZ328.h @@ -0,0 +1,1253 @@ + +/* include/asm-m68knommu/MC68EZ328.h: 'EZ328 control registers + * + * Copyright (C) 1999 Vladimir Gurevich + * Bear & Hare Software, Inc. + * + * Based on include/asm-m68knommu/MC68332.h + * Copyright (C) 1998 Kenneth Albanowski , + * The Silver Hammer Group, Ltd. + * + */ + +#ifndef _MC68EZ328_H_ +#define _MC68EZ328_H_ + +#define BYTE_REF(addr) (*((volatile unsigned char*)addr)) +#define WORD_REF(addr) (*((volatile unsigned short*)addr)) +#define LONG_REF(addr) (*((volatile unsigned long*)addr)) + +#define PUT_FIELD(field, val) (((val) << field##_SHIFT) & field##_MASK) +#define GET_FIELD(reg, field) (((reg) & field##_MASK) >> field##_SHIFT) + +/********** + * + * 0xFFFFF0xx -- System Control + * + **********/ + +/* + * System Control Register (SCR) + */ +#define SCR_ADDR 0xfffff000 +#define SCR BYTE_REF(SCR_ADDR) + +#define SCR_WDTH8 0x01 /* 8-Bit Width Select */ +#define SCR_DMAP 0x04 /* Double Map */ +#define SCR_SO 0x08 /* Supervisor Only */ +#define SCR_BETEN 0x10 /* Bus-Error Time-Out Enable */ +#define SCR_PRV 0x20 /* Privilege Violation */ +#define SCR_WPV 0x40 /* Write Protect Violation */ +#define SCR_BETO 0x80 /* Bus-Error TimeOut */ + +/* + * Silicon ID Register (Mask Revision Register (MRR) for '328 Compatibility) + */ +#define MRR_ADDR 0xfffff004 +#define MRR LONG_REF(MRR_ADDR) + +/********** + * + * 0xFFFFF1xx -- Chip-Select logic + * + **********/ + +/* + * Chip Select Group Base Registers + */ +#define CSGBA_ADDR 0xfffff100 +#define CSGBB_ADDR 0xfffff102 + +#define CSGBC_ADDR 0xfffff104 +#define CSGBD_ADDR 0xfffff106 + +#define CSGBA WORD_REF(CSGBA_ADDR) +#define CSGBB WORD_REF(CSGBB_ADDR) +#define CSGBC WORD_REF(CSGBC_ADDR) +#define CSGBD WORD_REF(CSGBD_ADDR) + +/* + * Chip Select Registers + */ +#define CSA_ADDR 0xfffff110 +#define CSB_ADDR 0xfffff112 +#define CSC_ADDR 0xfffff114 +#define CSD_ADDR 0xfffff116 + +#define CSA WORD_REF(CSA_ADDR) +#define CSB WORD_REF(CSB_ADDR) +#define CSC WORD_REF(CSC_ADDR) +#define CSD WORD_REF(CSD_ADDR) + +#define CSA_EN 0x0001 /* Chip-Select Enable */ +#define CSA_SIZ_MASK 0x000e /* Chip-Select Size */ +#define CSA_SIZ_SHIFT 1 +#define CSA_WS_MASK 0x0070 /* Wait State */ +#define CSA_WS_SHIFT 4 +#define CSA_BSW 0x0080 /* Data Bus Width */ +#define CSA_FLASH 0x0100 /* FLASH Memory Support */ +#define CSA_RO 0x8000 /* Read-Only */ + +#define CSB_EN 0x0001 /* Chip-Select Enable */ +#define CSB_SIZ_MASK 0x000e /* Chip-Select Size */ +#define CSB_SIZ_SHIFT 1 +#define CSB_WS_MASK 0x0070 /* Wait State */ +#define CSB_WS_SHIFT 4 +#define CSB_BSW 0x0080 /* Data Bus Width */ +#define CSB_FLASH 0x0100 /* FLASH Memory Support */ +#define CSB_UPSIZ_MASK 0x1800 /* Unprotected memory block size */ +#define CSB_UPSIZ_SHIFT 11 +#define CSB_ROP 0x2000 /* Readonly if protected */ +#define CSB_SOP 0x4000 /* Supervisor only if protected */ +#define CSB_RO 0x8000 /* Read-Only */ + +#define CSC_EN 0x0001 /* Chip-Select Enable */ +#define CSC_SIZ_MASK 0x000e /* Chip-Select Size */ +#define CSC_SIZ_SHIFT 1 +#define CSC_WS_MASK 0x0070 /* Wait State */ +#define CSC_WS_SHIFT 4 +#define CSC_BSW 0x0080 /* Data Bus Width */ +#define CSC_FLASH 0x0100 /* FLASH Memory Support */ +#define CSC_UPSIZ_MASK 0x1800 /* Unprotected memory block size */ +#define CSC_UPSIZ_SHIFT 11 +#define CSC_ROP 0x2000 /* Readonly if protected */ +#define CSC_SOP 0x4000 /* Supervisor only if protected */ +#define CSC_RO 0x8000 /* Read-Only */ + +#define CSD_EN 0x0001 /* Chip-Select Enable */ +#define CSD_SIZ_MASK 0x000e /* Chip-Select Size */ +#define CSD_SIZ_SHIFT 1 +#define CSD_WS_MASK 0x0070 /* Wait State */ +#define CSD_WS_SHIFT 4 +#define CSD_BSW 0x0080 /* Data Bus Width */ +#define CSD_FLASH 0x0100 /* FLASH Memory Support */ +#define CSD_DRAM 0x0200 /* Dram Selection */ +#define CSD_COMB 0x0400 /* Combining */ +#define CSD_UPSIZ_MASK 0x1800 /* Unprotected memory block size */ +#define CSD_UPSIZ_SHIFT 11 +#define CSD_ROP 0x2000 /* Readonly if protected */ +#define CSD_SOP 0x4000 /* Supervisor only if protected */ +#define CSD_RO 0x8000 /* Read-Only */ + +/* + * Emulation Chip-Select Register + */ +#define EMUCS_ADDR 0xfffff118 +#define EMUCS WORD_REF(EMUCS_ADDR) + +#define EMUCS_WS_MASK 0x0070 +#define EMUCS_WS_SHIFT 4 + +/********** + * + * 0xFFFFF2xx -- Phase Locked Loop (PLL) & Power Control + * + **********/ + +/* + * PLL Control Register + */ +#define PLLCR_ADDR 0xfffff200 +#define PLLCR WORD_REF(PLLCR_ADDR) + +#define PLLCR_DISPLL 0x0008 /* Disable PLL */ +#define PLLCR_CLKEN 0x0010 /* Clock (CLKO pin) enable */ +#define PLLCR_PRESC 0x0020 /* VCO prescaler */ +#define PLLCR_SYSCLK_SEL_MASK 0x0700 /* System Clock Selection */ +#define PLLCR_SYSCLK_SEL_SHIFT 8 +#define PLLCR_LCDCLK_SEL_MASK 0x3800 /* LCD Clock Selection */ +#define PLLCR_LCDCLK_SEL_SHIFT 11 + +/* '328-compatible definitions */ +#define PLLCR_PIXCLK_SEL_MASK PLLCR_LCDCLK_SEL_MASK +#define PLLCR_PIXCLK_SEL_SHIFT PLLCR_LCDCLK_SEL_SHIFT + +/* + * PLL Frequency Select Register + */ +#define PLLFSR_ADDR 0xfffff202 +#define PLLFSR WORD_REF(PLLFSR_ADDR) + +#define PLLFSR_PC_MASK 0x00ff /* P Count */ +#define PLLFSR_PC_SHIFT 0 +#define PLLFSR_QC_MASK 0x0f00 /* Q Count */ +#define PLLFSR_QC_SHIFT 8 +#define PLLFSR_PROT 0x4000 /* Protect P & Q */ +#define PLLFSR_CLK32 0x8000 /* Clock 32 (kHz) */ + +/* + * Power Control Register + */ +#define PCTRL_ADDR 0xfffff207 +#define PCTRL BYTE_REF(PCTRL_ADDR) + +#define PCTRL_WIDTH_MASK 0x1f /* CPU Clock bursts width */ +#define PCTRL_WIDTH_SHIFT 0 +#define PCTRL_PCEN 0x80 /* Power Control Enable */ + +/********** + * + * 0xFFFFF3xx -- Interrupt Controller + * + **********/ + +/* + * Interrupt Vector Register + */ +#define IVR_ADDR 0xfffff300 +#define IVR BYTE_REF(IVR_ADDR) + +#define IVR_VECTOR_MASK 0xF8 + +/* + * Interrupt control Register + */ +#define ICR_ADDR 0xfffff302 +#define ICR WORD_REF(ICR_ADDR) + +#define ICR_POL5 0x0080 /* Polarity Control for IRQ5 */ +#define ICR_ET6 0x0100 /* Edge Trigger Select for IRQ6 */ +#define ICR_ET3 0x0200 /* Edge Trigger Select for IRQ3 */ +#define ICR_ET2 0x0400 /* Edge Trigger Select for IRQ2 */ +#define ICR_ET1 0x0800 /* Edge Trigger Select for IRQ1 */ +#define ICR_POL6 0x1000 /* Polarity Control for IRQ6 */ +#define ICR_POL3 0x2000 /* Polarity Control for IRQ3 */ +#define ICR_POL2 0x4000 /* Polarity Control for IRQ2 */ +#define ICR_POL1 0x8000 /* Polarity Control for IRQ1 */ + +/* + * Interrupt Mask Register + */ +#define IMR_ADDR 0xfffff304 +#define IMR LONG_REF(IMR_ADDR) + +/* + * Define the names for bit positions first. This is useful for + * request_irq + */ +#define SPI_IRQ_NUM 0 /* SPI interrupt */ +#define TMR_IRQ_NUM 1 /* Timer interrupt */ +#define UART_IRQ_NUM 2 /* UART interrupt */ +#define WDT_IRQ_NUM 3 /* Watchdog Timer interrupt */ +#define RTC_IRQ_NUM 4 /* RTC interrupt */ +#define KB_IRQ_NUM 6 /* Keyboard Interrupt */ +#define PWM_IRQ_NUM 7 /* Pulse-Width Modulator int. */ +#define INT0_IRQ_NUM 8 /* External INT0 */ +#define INT1_IRQ_NUM 9 /* External INT1 */ +#define INT2_IRQ_NUM 10 /* External INT2 */ +#define INT3_IRQ_NUM 11 /* External INT3 */ +#define IRQ1_IRQ_NUM 16 /* IRQ1 */ +#define IRQ2_IRQ_NUM 17 /* IRQ2 */ +#define IRQ3_IRQ_NUM 18 /* IRQ3 */ +#define IRQ6_IRQ_NUM 19 /* IRQ6 */ +#define IRQ5_IRQ_NUM 20 /* IRQ5 */ +#define SAM_IRQ_NUM 22 /* Sampling Timer for RTC */ +#define EMIQ_IRQ_NUM 23 /* Emulator Interrupt */ + +/* '328-compatible definitions */ +#define SPIM_IRQ_NUM SPI_IRQ_NUM +#define TMR1_IRQ_NUM TMR_IRQ_NUM + +/* + * Here go the bitmasks themselves + */ +#define IMR_MSPI (1 << SPI_IRQ_NUM) /* Mask SPI interrupt */ +#define IMR_MTMR (1 << TMR_IRQ_NUM) /* Mask Timer interrupt */ +#define IMR_MUART (1 << UART_IRQ_NUM) /* Mask UART interrupt */ +#define IMR_MWDT (1 << WDT_IRQ_NUM) /* Mask Watchdog Timer interrupt */ +#define IMR_MRTC (1 << RTC_IRQ_NUM) /* Mask RTC interrupt */ +#define IMR_MKB (1 << KB_IRQ_NUM) /* Mask Keyboard Interrupt */ +#define IMR_MPWM (1 << PWM_IRQ_NUM) /* Mask Pulse-Width Modulator int. */ +#define IMR_MINT0 (1 << INT0_IRQ_NUM) /* Mask External INT0 */ +#define IMR_MINT1 (1 << INT1_IRQ_NUM) /* Mask External INT1 */ +#define IMR_MINT2 (1 << INT2_IRQ_NUM) /* Mask External INT2 */ +#define IMR_MINT3 (1 << INT3_IRQ_NUM) /* Mask External INT3 */ +#define IMR_MIRQ1 (1 << IRQ1_IRQ_NUM) /* Mask IRQ1 */ +#define IMR_MIRQ2 (1 << IRQ2_IRQ_NUM) /* Mask IRQ2 */ +#define IMR_MIRQ3 (1 << IRQ3_IRQ_NUM) /* Mask IRQ3 */ +#define IMR_MIRQ6 (1 << IRQ6_IRQ_NUM) /* Mask IRQ6 */ +#define IMR_MIRQ5 (1 << IRQ5_IRQ_NUM) /* Mask IRQ5 */ +#define IMR_MSAM (1 << SAM_IRQ_NUM) /* Mask Sampling Timer for RTC */ +#define IMR_MEMIQ (1 << EMIQ_IRQ_NUM) /* Mask Emulator Interrupt */ + +/* '328-compatible definitions */ +#define IMR_MSPIM IMR_MSPI +#define IMR_MTMR1 IMR_MTMR + +/* + * Interrupt Status Register + */ +#define ISR_ADDR 0xfffff30c +#define ISR LONG_REF(ISR_ADDR) + +#define ISR_SPI (1 << SPI_IRQ_NUM) /* SPI interrupt */ +#define ISR_TMR (1 << TMR_IRQ_NUM) /* Timer interrupt */ +#define ISR_UART (1 << UART_IRQ_NUM) /* UART interrupt */ +#define ISR_WDT (1 << WDT_IRQ_NUM) /* Watchdog Timer interrupt */ +#define ISR_RTC (1 << RTC_IRQ_NUM) /* RTC interrupt */ +#define ISR_KB (1 << KB_IRQ_NUM) /* Keyboard Interrupt */ +#define ISR_PWM (1 << PWM_IRQ_NUM) /* Pulse-Width Modulator interrupt */ +#define ISR_INT0 (1 << INT0_IRQ_NUM) /* External INT0 */ +#define ISR_INT1 (1 << INT1_IRQ_NUM) /* External INT1 */ +#define ISR_INT2 (1 << INT2_IRQ_NUM) /* External INT2 */ +#define ISR_INT3 (1 << INT3_IRQ_NUM) /* External INT3 */ +#define ISR_IRQ1 (1 << IRQ1_IRQ_NUM) /* IRQ1 */ +#define ISR_IRQ2 (1 << IRQ2_IRQ_NUM) /* IRQ2 */ +#define ISR_IRQ3 (1 << IRQ3_IRQ_NUM) /* IRQ3 */ +#define ISR_IRQ6 (1 << IRQ6_IRQ_NUM) /* IRQ6 */ +#define ISR_IRQ5 (1 << IRQ5_IRQ_NUM) /* IRQ5 */ +#define ISR_SAM (1 << SAM_IRQ_NUM) /* Sampling Timer for RTC */ +#define ISR_EMIQ (1 << EMIQ_IRQ_NUM) /* Emulator Interrupt */ + +/* '328-compatible definitions */ +#define ISR_SPIM ISR_SPI +#define ISR_TMR1 ISR_TMR + +/* + * Interrupt Pending Register + */ +#define IPR_ADDR 0xfffff30c +#define IPR LONG_REF(IPR_ADDR) + +#define IPR_SPI (1 << SPI_IRQ_NUM) /* SPI interrupt */ +#define IPR_TMR (1 << TMR_IRQ_NUM) /* Timer interrupt */ +#define IPR_UART (1 << UART_IRQ_NUM) /* UART interrupt */ +#define IPR_WDT (1 << WDT_IRQ_NUM) /* Watchdog Timer interrupt */ +#define IPR_RTC (1 << RTC_IRQ_NUM) /* RTC interrupt */ +#define IPR_KB (1 << KB_IRQ_NUM) /* Keyboard Interrupt */ +#define IPR_PWM (1 << PWM_IRQ_NUM) /* Pulse-Width Modulator interrupt */ +#define IPR_INT0 (1 << INT0_IRQ_NUM) /* External INT0 */ +#define IPR_INT1 (1 << INT1_IRQ_NUM) /* External INT1 */ +#define IPR_INT2 (1 << INT2_IRQ_NUM) /* External INT2 */ +#define IPR_INT3 (1 << INT3_IRQ_NUM) /* External INT3 */ +#define IPR_IRQ1 (1 << IRQ1_IRQ_NUM) /* IRQ1 */ +#define IPR_IRQ2 (1 << IRQ2_IRQ_NUM) /* IRQ2 */ +#define IPR_IRQ3 (1 << IRQ3_IRQ_NUM) /* IRQ3 */ +#define IPR_IRQ6 (1 << IRQ6_IRQ_NUM) /* IRQ6 */ +#define IPR_IRQ5 (1 << IRQ5_IRQ_NUM) /* IRQ5 */ +#define IPR_SAM (1 << SAM_IRQ_NUM) /* Sampling Timer for RTC */ +#define IPR_EMIQ (1 << EMIQ_IRQ_NUM) /* Emulator Interrupt */ + +/* '328-compatible definitions */ +#define IPR_SPIM IPR_SPI +#define IPR_TMR1 IPR_TMR + +/********** + * + * 0xFFFFF4xx -- Parallel Ports + * + **********/ + +/* + * Port A + */ +#define PADIR_ADDR 0xfffff400 /* Port A direction reg */ +#define PADATA_ADDR 0xfffff401 /* Port A data register */ +#define PAPUEN_ADDR 0xfffff402 /* Port A Pull-Up enable reg */ + +#define PADIR BYTE_REF(PADIR_ADDR) +#define PADATA BYTE_REF(PADATA_ADDR) +#define PAPUEN BYTE_REF(PAPUEN_ADDR) + +#define PA(x) (1 << (x)) + +/* + * Port B + */ +#define PBDIR_ADDR 0xfffff408 /* Port B direction reg */ +#define PBDATA_ADDR 0xfffff409 /* Port B data register */ +#define PBPUEN_ADDR 0xfffff40a /* Port B Pull-Up enable reg */ +#define PBSEL_ADDR 0xfffff40b /* Port B Select Register */ + +#define PBDIR BYTE_REF(PBDIR_ADDR) +#define PBDATA BYTE_REF(PBDATA_ADDR) +#define PBPUEN BYTE_REF(PBPUEN_ADDR) +#define PBSEL BYTE_REF(PBSEL_ADDR) + +#define PB(x) (1 << (x)) + +#define PB_CSB0 0x01 /* Use CSB0 as PB[0] */ +#define PB_CSB1 0x02 /* Use CSB1 as PB[1] */ +#define PB_CSC0_RAS0 0x04 /* Use CSC0/RAS0 as PB[2] */ +#define PB_CSC1_RAS1 0x08 /* Use CSC1/RAS1 as PB[3] */ +#define PB_CSD0_CAS0 0x10 /* Use CSD0/CAS0 as PB[4] */ +#define PB_CSD1_CAS1 0x20 /* Use CSD1/CAS1 as PB[5] */ +#define PB_TIN_TOUT 0x40 /* Use TIN/TOUT as PB[6] */ +#define PB_PWMO 0x80 /* Use PWMO as PB[7] */ + +/* + * Port C + */ +#define PCDIR_ADDR 0xfffff410 /* Port C direction reg */ +#define PCDATA_ADDR 0xfffff411 /* Port C data register */ +#define PCPDEN_ADDR 0xfffff412 /* Port C Pull-Down enb. reg */ +#define PCSEL_ADDR 0xfffff413 /* Port C Select Register */ + +#define PCDIR BYTE_REF(PCDIR_ADDR) +#define PCDATA BYTE_REF(PCDATA_ADDR) +#define PCPDEN BYTE_REF(PCPDEN_ADDR) +#define PCSEL BYTE_REF(PCSEL_ADDR) + +#define PC(x) (1 << (x)) + +#define PC_LD0 0x01 /* Use LD0 as PC[0] */ +#define PC_LD1 0x02 /* Use LD1 as PC[1] */ +#define PC_LD2 0x04 /* Use LD2 as PC[2] */ +#define PC_LD3 0x08 /* Use LD3 as PC[3] */ +#define PC_LFLM 0x10 /* Use LFLM as PC[4] */ +#define PC_LLP 0x20 /* Use LLP as PC[5] */ +#define PC_LCLK 0x40 /* Use LCLK as PC[6] */ +#define PC_LACD 0x80 /* Use LACD as PC[7] */ + +/* + * Port D + */ +#define PDDIR_ADDR 0xfffff418 /* Port D direction reg */ +#define PDDATA_ADDR 0xfffff419 /* Port D data register */ +#define PDPUEN_ADDR 0xfffff41a /* Port D Pull-Up enable reg */ +#define PDSEL_ADDR 0xfffff41b /* Port D Select Register */ +#define PDPOL_ADDR 0xfffff41c /* Port D Polarity Register */ +#define PDIRQEN_ADDR 0xfffff41d /* Port D IRQ enable register */ +#define PDKBEN_ADDR 0xfffff41e /* Port D Keyboard Enable reg */ +#define PDIQEG_ADDR 0xfffff41f /* Port D IRQ Edge Register */ + +#define PDDIR BYTE_REF(PDDIR_ADDR) +#define PDDATA BYTE_REF(PDDATA_ADDR) +#define PDPUEN BYTE_REF(PDPUEN_ADDR) +#define PDSEL BYTE_REF(PDSEL_ADDR) +#define PDPOL BYTE_REF(PDPOL_ADDR) +#define PDIRQEN BYTE_REF(PDIRQEN_ADDR) +#define PDKBEN BYTE_REF(PDKBEN_ADDR) +#define PDIQEG BYTE_REF(PDIQEG_ADDR) + +#define PD(x) (1 << (x)) + +#define PD_INT0 0x01 /* Use INT0 as PD[0] */ +#define PD_INT1 0x02 /* Use INT1 as PD[1] */ +#define PD_INT2 0x04 /* Use INT2 as PD[2] */ +#define PD_INT3 0x08 /* Use INT3 as PD[3] */ +#define PD_IRQ1 0x10 /* Use IRQ1 as PD[4] */ +#define PD_IRQ2 0x20 /* Use IRQ2 as PD[5] */ +#define PD_IRQ3 0x40 /* Use IRQ3 as PD[6] */ +#define PD_IRQ6 0x80 /* Use IRQ6 as PD[7] */ + +/* + * Port E + */ +#define PEDIR_ADDR 0xfffff420 /* Port E direction reg */ +#define PEDATA_ADDR 0xfffff421 /* Port E data register */ +#define PEPUEN_ADDR 0xfffff422 /* Port E Pull-Up enable reg */ +#define PESEL_ADDR 0xfffff423 /* Port E Select Register */ + +#define PEDIR BYTE_REF(PEDIR_ADDR) +#define PEDATA BYTE_REF(PEDATA_ADDR) +#define PEPUEN BYTE_REF(PEPUEN_ADDR) +#define PESEL BYTE_REF(PESEL_ADDR) + +#define PE(x) (1 << (x)) + +#define PE_SPMTXD 0x01 /* Use SPMTXD as PE[0] */ +#define PE_SPMRXD 0x02 /* Use SPMRXD as PE[1] */ +#define PE_SPMCLK 0x04 /* Use SPMCLK as PE[2] */ +#define PE_DWE 0x08 /* Use DWE as PE[3] */ +#define PE_RXD 0x10 /* Use RXD as PE[4] */ +#define PE_TXD 0x20 /* Use TXD as PE[5] */ +#define PE_RTS 0x40 /* Use RTS as PE[6] */ +#define PE_CTS 0x80 /* Use CTS as PE[7] */ + +/* + * Port F + */ +#define PFDIR_ADDR 0xfffff428 /* Port F direction reg */ +#define PFDATA_ADDR 0xfffff429 /* Port F data register */ +#define PFPUEN_ADDR 0xfffff42a /* Port F Pull-Up enable reg */ +#define PFSEL_ADDR 0xfffff42b /* Port F Select Register */ + +#define PFDIR BYTE_REF(PFDIR_ADDR) +#define PFDATA BYTE_REF(PFDATA_ADDR) +#define PFPUEN BYTE_REF(PFPUEN_ADDR) +#define PFSEL BYTE_REF(PFSEL_ADDR) + +#define PF(x) (1 << (x)) + +#define PF_LCONTRAST 0x01 /* Use LCONTRAST as PF[0] */ +#define PF_IRQ5 0x02 /* Use IRQ5 as PF[1] */ +#define PF_CLKO 0x04 /* Use CLKO as PF[2] */ +#define PF_A20 0x08 /* Use A20 as PF[3] */ +#define PF_A21 0x10 /* Use A21 as PF[4] */ +#define PF_A22 0x20 /* Use A22 as PF[5] */ +#define PF_A23 0x40 /* Use A23 as PF[6] */ +#define PF_CSA1 0x80 /* Use CSA1 as PF[7] */ + +/* + * Port G + */ +#define PGDIR_ADDR 0xfffff430 /* Port G direction reg */ +#define PGDATA_ADDR 0xfffff431 /* Port G data register */ +#define PGPUEN_ADDR 0xfffff432 /* Port G Pull-Up enable reg */ +#define PGSEL_ADDR 0xfffff433 /* Port G Select Register */ + +#define PGDIR BYTE_REF(PGDIR_ADDR) +#define PGDATA BYTE_REF(PGDATA_ADDR) +#define PGPUEN BYTE_REF(PGPUEN_ADDR) +#define PGSEL BYTE_REF(PGSEL_ADDR) + +#define PG(x) (1 << (x)) + +#define PG_BUSW_DTACK 0x01 /* Use BUSW/DTACK as PG[0] */ +#define PG_A0 0x02 /* Use A0 as PG[1] */ +#define PG_EMUIRQ 0x04 /* Use EMUIRQ as PG[2] */ +#define PG_HIZ_P_D 0x08 /* Use HIZ/P/D as PG[3] */ +#define PG_EMUCS 0x10 /* Use EMUCS as PG[4] */ +#define PG_EMUBRK 0x20 /* Use EMUBRK as PG[5] */ + +/********** + * + * 0xFFFFF5xx -- Pulse-Width Modulator (PWM) + * + **********/ + +/* + * PWM Control Register + */ +#define PWMC_ADDR 0xfffff500 +#define PWMC WORD_REF(PWMC_ADDR) + +#define PWMC_CLKSEL_MASK 0x0003 /* Clock Selection */ +#define PWMC_CLKSEL_SHIFT 0 +#define PWMC_REPEAT_MASK 0x000c /* Sample Repeats */ +#define PWMC_REPEAT_SHIFT 2 +#define PWMC_EN 0x0010 /* Enable PWM */ +#define PMNC_FIFOAV 0x0020 /* FIFO Available */ +#define PWMC_IRQEN 0x0040 /* Interrupt Request Enable */ +#define PWMC_IRQ 0x0080 /* Interrupt Request (FIFO empty) */ +#define PWMC_PRESCALER_MASK 0x7f00 /* Incoming Clock prescaler */ +#define PWMC_PRESCALER_SHIFT 8 +#define PWMC_CLKSRC 0x8000 /* Clock Source Select */ + +/* '328-compatible definitions */ +#define PWMC_PWMEN PWMC_EN + +/* + * PWM Sample Register + */ +#define PWMS_ADDR 0xfffff502 +#define PWMS WORD_REF(PWMS_ADDR) + +/* + * PWM Period Register + */ +#define PWMP_ADDR 0xfffff504 +#define PWMP BYTE_REF(PWMP_ADDR) + +/* + * PWM Counter Register + */ +#define PWMCNT_ADDR 0xfffff505 +#define PWMCNT BYTE_REF(PWMCNT_ADDR) + +/********** + * + * 0xFFFFF6xx -- General-Purpose Timer + * + **********/ + +/* + * Timer Control register + */ +#define TCTL_ADDR 0xfffff600 +#define TCTL WORD_REF(TCTL_ADDR) + +#define TCTL_TEN 0x0001 /* Timer Enable */ +#define TCTL_CLKSOURCE_MASK 0x000e /* Clock Source: */ +#define TCTL_CLKSOURCE_STOP 0x0000 /* Stop count (disabled) */ +#define TCTL_CLKSOURCE_SYSCLK 0x0002 /* SYSCLK to prescaler */ +#define TCTL_CLKSOURCE_SYSCLK_16 0x0004 /* SYSCLK/16 to prescaler */ +#define TCTL_CLKSOURCE_TIN 0x0006 /* TIN to prescaler */ +#define TCTL_CLKSOURCE_32KHZ 0x0008 /* 32kHz clock to prescaler */ +#define TCTL_IRQEN 0x0010 /* IRQ Enable */ +#define TCTL_OM 0x0020 /* Output Mode */ +#define TCTL_CAP_MASK 0x00c0 /* Capture Edge: */ +#define TCTL_CAP_RE 0x0040 /* Capture on rizing edge */ +#define TCTL_CAP_FE 0x0080 /* Capture on falling edge */ +#define TCTL_FRR 0x0010 /* Free-Run Mode */ + +/* '328-compatible definitions */ +#define TCTL1_ADDR TCTL_ADDR +#define TCTL1 TCTL + +/* + * Timer Prescaler Register + */ +#define TPRER_ADDR 0xfffff602 +#define TPRER WORD_REF(TPRER_ADDR) + +/* '328-compatible definitions */ +#define TPRER1_ADDR TPRER_ADDR +#define TPRER1 TPRER + +/* + * Timer Compare Register + */ +#define TCMP_ADDR 0xfffff604 +#define TCMP WORD_REF(TCMP_ADDR) + +/* '328-compatible definitions */ +#define TCMP1_ADDR TCMP_ADDR +#define TCMP1 TCMP + +/* + * Timer Capture register + */ +#define TCR_ADDR 0xfffff606 +#define TCR WORD_REF(TCR_ADDR) + +/* '328-compatible definitions */ +#define TCR1_ADDR TCR_ADDR +#define TCR1 TCR + +/* + * Timer Counter Register + */ +#define TCN_ADDR 0xfffff608 +#define TCN WORD_REF(TCN_ADDR) + +/* '328-compatible definitions */ +#define TCN1_ADDR TCN_ADDR +#define TCN1 TCN + +/* + * Timer Status Register + */ +#define TSTAT_ADDR 0xfffff60a +#define TSTAT WORD_REF(TSTAT_ADDR) + +#define TSTAT_COMP 0x0001 /* Compare Event occurred */ +#define TSTAT_CAPT 0x0001 /* Capture Event occurred */ + +/* '328-compatible definitions */ +#define TSTAT1_ADDR TSTAT_ADDR +#define TSTAT1 TSTAT + +/********** + * + * 0xFFFFF8xx -- Serial Periferial Interface Master (SPIM) + * + **********/ + +/* + * SPIM Data Register + */ +#define SPIMDATA_ADDR 0xfffff800 +#define SPIMDATA WORD_REF(SPIMDATA_ADDR) + +/* + * SPIM Control/Status Register + */ +#define SPIMCONT_ADDR 0xfffff802 +#define SPIMCONT WORD_REF(SPIMCONT_ADDR) + +#define SPIMCONT_BIT_COUNT_MASK 0x000f /* Transfer Length in Bytes */ +#define SPIMCONT_BIT_COUNT_SHIFT 0 +#define SPIMCONT_POL 0x0010 /* SPMCLK Signel Polarity */ +#define SPIMCONT_PHA 0x0020 /* Clock/Data phase relationship */ +#define SPIMCONT_IRQEN 0x0040 /* IRQ Enable */ +#define SPIMCONT_IRQ 0x0080 /* Interrupt Request */ +#define SPIMCONT_XCH 0x0100 /* Exchange */ +#define SPIMCONT_ENABLE 0x0200 /* Enable SPIM */ +#define SPIMCONT_DATA_RATE_MASK 0xe000 /* SPIM Data Rate */ +#define SPIMCONT_DATA_RATE_SHIFT 13 + +/* '328-compatible definitions */ +#define SPIMCONT_SPIMIRQ SPIMCONT_IRQ +#define SPIMCONT_SPIMEN SPIMCONT_ENABLE + +/********** + * + * 0xFFFFF9xx -- UART + * + **********/ + +/* + * UART Status/Control Register + */ +#define USTCNT_ADDR 0xfffff900 +#define USTCNT WORD_REF(USTCNT_ADDR) + +#define USTCNT_TXAE 0x0001 /* Transmitter Available Interrupt Enable */ +#define USTCNT_TXHE 0x0002 /* Transmitter Half Empty Enable */ +#define USTCNT_TXEE 0x0004 /* Transmitter Empty Interrupt Enable */ +#define USTCNT_RXRE 0x0008 /* Receiver Ready Interrupt Enable */ +#define USTCNT_RXHE 0x0010 /* Receiver Half-Full Interrupt Enable */ +#define USTCNT_RXFE 0x0020 /* Receiver Full Interrupt Enable */ +#define USTCNT_CTSD 0x0040 /* CTS Delta Interrupt Enable */ +#define USTCNT_ODEN 0x0080 /* Old Data Interrupt Enable */ +#define USTCNT_8_7 0x0100 /* Eight or seven-bit transmission */ +#define USTCNT_STOP 0x0200 /* Stop bit transmission */ +#define USTCNT_ODD 0x0400 /* Odd Parity */ +#define USTCNT_PEN 0x0800 /* Parity Enable */ +#define USTCNT_CLKM 0x1000 /* Clock Mode Select */ +#define USTCNT_TXEN 0x2000 /* Transmitter Enable */ +#define USTCNT_RXEN 0x4000 /* Receiver Enable */ +#define USTCNT_UEN 0x8000 /* UART Enable */ + +/* '328-compatible definitions */ +#define USTCNT_TXAVAILEN USTCNT_TXAE +#define USTCNT_TXHALFEN USTCNT_TXHE +#define USTCNT_TXEMPTYEN USTCNT_TXEE +#define USTCNT_RXREADYEN USTCNT_RXRE +#define USTCNT_RXHALFEN USTCNT_RXHE +#define USTCNT_RXFULLEN USTCNT_RXFE +#define USTCNT_CTSDELTAEN USTCNT_CTSD +#define USTCNT_ODD_EVEN USTCNT_ODD +#define USTCNT_PARITYEN USTCNT_PEN +#define USTCNT_CLKMODE USTCNT_CLKM +#define USTCNT_UARTEN USTCNT_UEN + +/* + * UART Baud Control Register + */ +#define UBAUD_ADDR 0xfffff902 +#define UBAUD WORD_REF(UBAUD_ADDR) + +#define UBAUD_PRESCALER_MASK 0x003f /* Actual divisor is 65 - PRESCALER */ +#define UBAUD_PRESCALER_SHIFT 0 +#define UBAUD_DIVIDE_MASK 0x0700 /* Baud Rate freq. divizor */ +#define UBAUD_DIVIDE_SHIFT 8 +#define UBAUD_BAUD_SRC 0x0800 /* Baud Rate Source */ +#define UBAUD_UCLKDIR 0x2000 /* UCLK Direction */ + +/* + * UART Receiver Register + */ +#define URX_ADDR 0xfffff904 +#define URX WORD_REF(URX_ADDR) + +#define URX_RXDATA_ADDR 0xfffff905 +#define URX_RXDATA BYTE_REF(URX_RXDATA_ADDR) + +#define URX_RXDATA_MASK 0x00ff /* Received data */ +#define URX_RXDATA_SHIFT 0 +#define URX_PARITY_ERROR 0x0100 /* Parity Error */ +#define URX_BREAK 0x0200 /* Break Detected */ +#define URX_FRAME_ERROR 0x0400 /* Framing Error */ +#define URX_OVRUN 0x0800 /* Serial Overrun */ +#define URX_OLD_DATA 0x1000 /* Old data in FIFO */ +#define URX_DATA_READY 0x2000 /* Data Ready (FIFO not empty) */ +#define URX_FIFO_HALF 0x4000 /* FIFO is Half-Full */ +#define URX_FIFO_FULL 0x8000 /* FIFO is Full */ + +/* + * UART Transmitter Register + */ +#define UTX_ADDR 0xfffff906 +#define UTX WORD_REF(UTX_ADDR) + +#define UTX_TXDATA_ADDR 0xfffff907 +#define UTX_TXDATA BYTE_REF(UTX_TXDATA_ADDR) + +#define UTX_TXDATA_MASK 0x00ff /* Data to be transmitted */ +#define UTX_TXDATA_SHIFT 0 +#define UTX_CTS_DELTA 0x0100 /* CTS changed */ +#define UTX_CTS_STAT 0x0200 /* CTS State */ +#define UTX_BUSY 0x0400 /* FIFO is busy, sending a character */ +#define UTX_NOCTS 0x0800 /* Ignore CTS */ +#define UTX_SEND_BREAK 0x1000 /* Send a BREAK */ +#define UTX_TX_AVAIL 0x2000 /* Transmit FIFO has a slot available */ +#define UTX_FIFO_HALF 0x4000 /* Transmit FIFO is half empty */ +#define UTX_FIFO_EMPTY 0x8000 /* Transmit FIFO is empty */ + +/* '328-compatible definitions */ +#define UTX_CTS_STATUS UTX_CTS_STAT +#define UTX_IGNORE_CTS UTX_NOCTS + +/* + * UART Miscellaneous Register + */ +#define UMISC_ADDR 0xfffff908 +#define UMISC WORD_REF(UMISC_ADDR) + +#define UMISC_TX_POL 0x0004 /* Transmit Polarity */ +#define UMISC_RX_POL 0x0008 /* Receive Polarity */ +#define UMISC_IRDA_LOOP 0x0010 /* IrDA Loopback Enable */ +#define UMISC_IRDA_EN 0x0020 /* Infra-Red Enable */ +#define UMISC_RTS 0x0040 /* Set RTS status */ +#define UMISC_RTSCONT 0x0080 /* Choose RTS control */ +#define UMISC_IR_TEST 0x0400 /* IRDA Test Enable */ +#define UMISC_BAUD_RESET 0x0800 /* Reset Baud Rate Generation Counters */ +#define UMISC_LOOP 0x1000 /* Serial Loopback Enable */ +#define UMISC_FORCE_PERR 0x2000 /* Force Parity Error */ +#define UMISC_CLKSRC 0x4000 /* Clock Source */ +#define UMISC_BAUD_TEST 0x8000 /* Enable Baud Test Mode */ + +/* + * UART Non-integer Prescaler Register + */ +#define NIPR_ADDR 0xfffff90a +#define NIPR WORD_REF(NIPR_ADDR) + +#define NIPR_STEP_VALUE_MASK 0x00ff /* NI prescaler step value */ +#define NIPR_STEP_VALUE_SHIFT 0 +#define NIPR_SELECT_MASK 0x0700 /* Tap Selection */ +#define NIPR_SELECT_SHIFT 8 +#define NIPR_PRE_SEL 0x8000 /* Non-integer prescaler select */ + + +/* generalization of uart control registers to support multiple ports: */ +typedef volatile struct { + volatile unsigned short int ustcnt; + volatile unsigned short int ubaud; + union { + volatile unsigned short int w; + struct { + volatile unsigned char status; + volatile unsigned char rxdata; + } b; + } urx; + union { + volatile unsigned short int w; + struct { + volatile unsigned char status; + volatile unsigned char txdata; + } b; + } utx; + volatile unsigned short int umisc; + volatile unsigned short int nipr; + volatile unsigned short int pad1; + volatile unsigned short int pad2; +} __attribute__((packed)) m68328_uart; + + +/********** + * + * 0xFFFFFAxx -- LCD Controller + * + **********/ + +/* + * LCD Screen Starting Address Register + */ +#define LSSA_ADDR 0xfffffa00 +#define LSSA LONG_REF(LSSA_ADDR) + +#define LSSA_SSA_MASK 0x1ffffffe /* Bits 0 and 29-31 are reserved */ + +/* + * LCD Virtual Page Width Register + */ +#define LVPW_ADDR 0xfffffa05 +#define LVPW BYTE_REF(LVPW_ADDR) + +/* + * LCD Screen Width Register (not compatible with '328 !!!) + */ +#define LXMAX_ADDR 0xfffffa08 +#define LXMAX WORD_REF(LXMAX_ADDR) + +#define LXMAX_XM_MASK 0x02f0 /* Bits 0-3 and 10-15 are reserved */ + +/* + * LCD Screen Height Register + */ +#define LYMAX_ADDR 0xfffffa0a +#define LYMAX WORD_REF(LYMAX_ADDR) + +#define LYMAX_YM_MASK 0x01ff /* Bits 9-15 are reserved */ + +/* + * LCD Cursor X Position Register + */ +#define LCXP_ADDR 0xfffffa18 +#define LCXP WORD_REF(LCXP_ADDR) + +#define LCXP_CC_MASK 0xc000 /* Cursor Control */ +#define LCXP_CC_TRAMSPARENT 0x0000 +#define LCXP_CC_BLACK 0x4000 +#define LCXP_CC_REVERSED 0x8000 +#define LCXP_CC_WHITE 0xc000 +#define LCXP_CXP_MASK 0x02ff /* Cursor X position */ + +/* + * LCD Cursor Y Position Register + */ +#define LCYP_ADDR 0xfffffa1a +#define LCYP WORD_REF(LCYP_ADDR) + +#define LCYP_CYP_MASK 0x01ff /* Cursor Y Position */ + +/* + * LCD Cursor Width and Heigth Register + */ +#define LCWCH_ADDR 0xfffffa1c +#define LCWCH WORD_REF(LCWCH_ADDR) + +#define LCWCH_CH_MASK 0x001f /* Cursor Height */ +#define LCWCH_CH_SHIFT 0 +#define LCWCH_CW_MASK 0x1f00 /* Cursor Width */ +#define LCWCH_CW_SHIFT 8 + +/* + * LCD Blink Control Register + */ +#define LBLKC_ADDR 0xfffffa1f +#define LBLKC BYTE_REF(LBLKC_ADDR) + +#define LBLKC_BD_MASK 0x7f /* Blink Divisor */ +#define LBLKC_BD_SHIFT 0 +#define LBLKC_BKEN 0x80 /* Blink Enabled */ + +/* + * LCD Panel Interface Configuration Register + */ +#define LPICF_ADDR 0xfffffa20 +#define LPICF BYTE_REF(LPICF_ADDR) + +#define LPICF_GS_MASK 0x03 /* Gray-Scale Mode */ +#define LPICF_GS_BW 0x00 +#define LPICF_GS_GRAY_4 0x01 +#define LPICF_GS_GRAY_16 0x02 +#define LPICF_PBSIZ_MASK 0x0c /* Panel Bus Width */ +#define LPICF_PBSIZ_1 0x00 +#define LPICF_PBSIZ_2 0x04 +#define LPICF_PBSIZ_4 0x08 + +/* + * LCD Polarity Configuration Register + */ +#define LPOLCF_ADDR 0xfffffa21 +#define LPOLCF BYTE_REF(LPOLCF_ADDR) + +#define LPOLCF_PIXPOL 0x01 /* Pixel Polarity */ +#define LPOLCF_LPPOL 0x02 /* Line Pulse Polarity */ +#define LPOLCF_FLMPOL 0x04 /* Frame Marker Polarity */ +#define LPOLCF_LCKPOL 0x08 /* LCD Shift Lock Polarity */ + +/* + * LACD (LCD Alternate Crystal Direction) Rate Control Register + */ +#define LACDRC_ADDR 0xfffffa23 +#define LACDRC BYTE_REF(LACDRC_ADDR) + +#define LACDRC_ACDSLT 0x80 /* Signal Source Select */ +#define LACDRC_ACD_MASK 0x0f /* Alternate Crystal Direction Control */ +#define LACDRC_ACD_SHIFT 0 + +/* + * LCD Pixel Clock Divider Register + */ +#define LPXCD_ADDR 0xfffffa25 +#define LPXCD BYTE_REF(LPXCD_ADDR) + +#define LPXCD_PCD_MASK 0x3f /* Pixel Clock Divider */ +#define LPXCD_PCD_SHIFT 0 + +/* + * LCD Clocking Control Register + */ +#define LCKCON_ADDR 0xfffffa27 +#define LCKCON BYTE_REF(LCKCON_ADDR) + +#define LCKCON_DWS_MASK 0x0f /* Display Wait-State */ +#define LCKCON_DWS_SHIFT 0 +#define LCKCON_DWIDTH 0x40 /* Display Memory Width */ +#define LCKCON_LCDON 0x80 /* Enable LCD Controller */ + +/* '328-compatible definitions */ +#define LCKCON_DW_MASK LCKCON_DWS_MASK +#define LCKCON_DW_SHIFT LCKCON_DWS_SHIFT + +/* + * LCD Refresh Rate Adjustment Register + */ +#define LRRA_ADDR 0xfffffa29 +#define LRRA BYTE_REF(LRRA_ADDR) + +/* + * LCD Panning Offset Register + */ +#define LPOSR_ADDR 0xfffffa2d +#define LPOSR BYTE_REF(LPOSR_ADDR) + +#define LPOSR_POS_MASK 0x0f /* Pixel Offset Code */ +#define LPOSR_POS_SHIFT 0 + +/* + * LCD Frame Rate Control Modulation Register + */ +#define LFRCM_ADDR 0xfffffa31 +#define LFRCM BYTE_REF(LFRCM_ADDR) + +#define LFRCM_YMOD_MASK 0x0f /* Vertical Modulation */ +#define LFRCM_YMOD_SHIFT 0 +#define LFRCM_XMOD_MASK 0xf0 /* Horizontal Modulation */ +#define LFRCM_XMOD_SHIFT 4 + +/* + * LCD Gray Palette Mapping Register + */ +#define LGPMR_ADDR 0xfffffa33 +#define LGPMR BYTE_REF(LGPMR_ADDR) + +#define LGPMR_G1_MASK 0x0f +#define LGPMR_G1_SHIFT 0 +#define LGPMR_G2_MASK 0xf0 +#define LGPMR_G2_SHIFT 4 + +/* + * PWM Contrast Control Register + */ +#define PWMR_ADDR 0xfffffa36 +#define PWMR WORD_REF(PWMR_ADDR) + +#define PWMR_PW_MASK 0x00ff /* Pulse Width */ +#define PWMR_PW_SHIFT 0 +#define PWMR_CCPEN 0x0100 /* Contrast Control Enable */ +#define PWMR_SRC_MASK 0x0600 /* Input Clock Source */ +#define PWMR_SRC_LINE 0x0000 /* Line Pulse */ +#define PWMR_SRC_PIXEL 0x0200 /* Pixel Clock */ +#define PWMR_SRC_LCD 0x4000 /* LCD clock */ + +/********** + * + * 0xFFFFFBxx -- Real-Time Clock (RTC) + * + **********/ + +/* + * RTC Hours Minutes and Seconds Register + */ +#define RTCTIME_ADDR 0xfffffb00 +#define RTCTIME LONG_REF(RTCTIME_ADDR) + +#define RTCTIME_SECONDS_MASK 0x0000003f /* Seconds */ +#define RTCTIME_SECONDS_SHIFT 0 +#define RTCTIME_MINUTES_MASK 0x003f0000 /* Minutes */ +#define RTCTIME_MINUTES_SHIFT 16 +#define RTCTIME_HOURS_MASK 0x1f000000 /* Hours */ +#define RTCTIME_HOURS_SHIFT 24 + +/* + * RTC Alarm Register + */ +#define RTCALRM_ADDR 0xfffffb04 +#define RTCALRM LONG_REF(RTCALRM_ADDR) + +#define RTCALRM_SECONDS_MASK 0x0000003f /* Seconds */ +#define RTCALRM_SECONDS_SHIFT 0 +#define RTCALRM_MINUTES_MASK 0x003f0000 /* Minutes */ +#define RTCALRM_MINUTES_SHIFT 16 +#define RTCALRM_HOURS_MASK 0x1f000000 /* Hours */ +#define RTCALRM_HOURS_SHIFT 24 + +/* + * Watchdog Timer Register + */ +#define WATCHDOG_ADDR 0xfffffb0a +#define WATCHDOG WORD_REF(WATCHDOG_ADDR) + +#define WATCHDOG_EN 0x0001 /* Watchdog Enabled */ +#define WATCHDOG_ISEL 0x0002 /* Select the watchdog interrupt */ +#define WATCHDOG_INTF 0x0080 /* Watchdog interrupt occcured */ +#define WATCHDOG_CNT_MASK 0x0300 /* Watchdog Counter */ +#define WATCHDOG_CNT_SHIFT 8 + +/* + * RTC Control Register + */ +#define RTCCTL_ADDR 0xfffffb0c +#define RTCCTL WORD_REF(RTCCTL_ADDR) + +#define RTCCTL_XTL 0x0020 /* Crystal Selection */ +#define RTCCTL_EN 0x0080 /* RTC Enable */ + +/* '328-compatible definitions */ +#define RTCCTL_384 RTCCTL_XTL +#define RTCCTL_ENABLE RTCCTL_EN + +/* + * RTC Interrupt Status Register + */ +#define RTCISR_ADDR 0xfffffb0e +#define RTCISR WORD_REF(RTCISR_ADDR) + +#define RTCISR_SW 0x0001 /* Stopwatch timed out */ +#define RTCISR_MIN 0x0002 /* 1-minute interrupt has occurred */ +#define RTCISR_ALM 0x0004 /* Alarm interrupt has occurred */ +#define RTCISR_DAY 0x0008 /* 24-hour rollover interrupt has occurred */ +#define RTCISR_1HZ 0x0010 /* 1Hz interrupt has occurred */ +#define RTCISR_HR 0x0020 /* 1-hour interrupt has occurred */ +#define RTCISR_SAM0 0x0100 /* 4Hz / 4.6875Hz interrupt has occurred */ +#define RTCISR_SAM1 0x0200 /* 8Hz / 9.3750Hz interrupt has occurred */ +#define RTCISR_SAM2 0x0400 /* 16Hz / 18.7500Hz interrupt has occurred */ +#define RTCISR_SAM3 0x0800 /* 32Hz / 37.5000Hz interrupt has occurred */ +#define RTCISR_SAM4 0x1000 /* 64Hz / 75.0000Hz interrupt has occurred */ +#define RTCISR_SAM5 0x2000 /* 128Hz / 150.0000Hz interrupt has occurred */ +#define RTCISR_SAM6 0x4000 /* 256Hz / 300.0000Hz interrupt has occurred */ +#define RTCISR_SAM7 0x8000 /* 512Hz / 600.0000Hz interrupt has occurred */ + +/* + * RTC Interrupt Enable Register + */ +#define RTCIENR_ADDR 0xfffffb10 +#define RTCIENR WORD_REF(RTCIENR_ADDR) + +#define RTCIENR_SW 0x0001 /* Stopwatch interrupt enable */ +#define RTCIENR_MIN 0x0002 /* 1-minute interrupt enable */ +#define RTCIENR_ALM 0x0004 /* Alarm interrupt enable */ +#define RTCIENR_DAY 0x0008 /* 24-hour rollover interrupt enable */ +#define RTCIENR_1HZ 0x0010 /* 1Hz interrupt enable */ +#define RTCIENR_HR 0x0020 /* 1-hour interrupt enable */ +#define RTCIENR_SAM0 0x0100 /* 4Hz / 4.6875Hz interrupt enable */ +#define RTCIENR_SAM1 0x0200 /* 8Hz / 9.3750Hz interrupt enable */ +#define RTCIENR_SAM2 0x0400 /* 16Hz / 18.7500Hz interrupt enable */ +#define RTCIENR_SAM3 0x0800 /* 32Hz / 37.5000Hz interrupt enable */ +#define RTCIENR_SAM4 0x1000 /* 64Hz / 75.0000Hz interrupt enable */ +#define RTCIENR_SAM5 0x2000 /* 128Hz / 150.0000Hz interrupt enable */ +#define RTCIENR_SAM6 0x4000 /* 256Hz / 300.0000Hz interrupt enable */ +#define RTCIENR_SAM7 0x8000 /* 512Hz / 600.0000Hz interrupt enable */ + +/* + * Stopwatch Minutes Register + */ +#define STPWCH_ADDR 0xfffffb12 +#define STPWCH WORD_REF(STPWCH) + +#define STPWCH_CNT_MASK 0x003f /* Stopwatch countdown value */ +#define SPTWCH_CNT_SHIFT 0 + +/* + * RTC Day Count Register + */ +#define DAYR_ADDR 0xfffffb1a +#define DAYR WORD_REF(DAYR_ADDR) + +#define DAYR_DAYS_MASK 0x1ff /* Day Setting */ +#define DAYR_DAYS_SHIFT 0 + +/* + * RTC Day Alarm Register + */ +#define DAYALARM_ADDR 0xfffffb1c +#define DAYALARM WORD_REF(DAYALARM_ADDR) + +#define DAYALARM_DAYSAL_MASK 0x01ff /* Day Setting of the Alarm */ +#define DAYALARM_DAYSAL_SHIFT 0 + +/********** + * + * 0xFFFFFCxx -- DRAM Controller + * + **********/ + +/* + * DRAM Memory Configuration Register + */ +#define DRAMMC_ADDR 0xfffffc00 +#define DRAMMC WORD_REF(DRAMMC_ADDR) + +#define DRAMMC_ROW12_MASK 0xc000 /* Row address bit for MD12 */ +#define DRAMMC_ROW12_PA10 0x0000 +#define DRAMMC_ROW12_PA21 0x4000 +#define DRAMMC_ROW12_PA23 0x8000 +#define DRAMMC_ROW0_MASK 0x3000 /* Row address bit for MD0 */ +#define DRAMMC_ROW0_PA11 0x0000 +#define DRAMMC_ROW0_PA22 0x1000 +#define DRAMMC_ROW0_PA23 0x2000 +#define DRAMMC_ROW11 0x0800 /* Row address bit for MD11 PA20/PA22 */ +#define DRAMMC_ROW10 0x0400 /* Row address bit for MD10 PA19/PA21 */ +#define DRAMMC_ROW9 0x0200 /* Row address bit for MD9 PA9/PA19 */ +#define DRAMMC_ROW8 0x0100 /* Row address bit for MD8 PA10/PA20 */ +#define DRAMMC_COL10 0x0080 /* Col address bit for MD10 PA11/PA0 */ +#define DRAMMC_COL9 0x0040 /* Col address bit for MD9 PA10/PA0 */ +#define DRAMMC_COL8 0x0020 /* Col address bit for MD8 PA9/PA0 */ +#define DRAMMC_REF_MASK 0x001f /* Reresh Cycle */ +#define DRAMMC_REF_SHIFT 0 + +/* + * DRAM Control Register + */ +#define DRAMC_ADDR 0xfffffc02 +#define DRAMC WORD_REF(DRAMC_ADDR) + +#define DRAMC_DWE 0x0001 /* DRAM Write Enable */ +#define DRAMC_RST 0x0002 /* Reset Burst Refresh Enable */ +#define DRAMC_LPR 0x0004 /* Low-Power Refresh Enable */ +#define DRAMC_SLW 0x0008 /* Slow RAM */ +#define DRAMC_LSP 0x0010 /* Light Sleep */ +#define DRAMC_MSW 0x0020 /* Slow Multiplexing */ +#define DRAMC_WS_MASK 0x00c0 /* Wait-states */ +#define DRAMC_WS_SHIFT 6 +#define DRAMC_PGSZ_MASK 0x0300 /* Page Size for fast page mode */ +#define DRAMC_PGSZ_SHIFT 8 +#define DRAMC_PGSZ_256K 0x0000 +#define DRAMC_PGSZ_512K 0x0100 +#define DRAMC_PGSZ_1024K 0x0200 +#define DRAMC_PGSZ_2048K 0x0300 +#define DRAMC_EDO 0x0400 /* EDO DRAM */ +#define DRAMC_CLK 0x0800 /* Refresh Timer Clock source select */ +#define DRAMC_BC_MASK 0x3000 /* Page Access Clock Cycle (FP mode) */ +#define DRAMC_BC_SHIFT 12 +#define DRAMC_RM 0x4000 /* Refresh Mode */ +#define DRAMC_EN 0x8000 /* DRAM Controller enable */ + + +/********** + * + * 0xFFFFFDxx -- In-Circuit Emulation (ICE) + * + **********/ + +/* + * ICE Module Address Compare Register + */ +#define ICEMACR_ADDR 0xfffffd00 +#define ICEMACR LONG_REF(ICEMACR_ADDR) + +/* + * ICE Module Address Mask Register + */ +#define ICEMAMR_ADDR 0xfffffd04 +#define ICEMAMR LONG_REF(ICEMAMR_ADDR) + +/* + * ICE Module Control Compare Register + */ +#define ICEMCCR_ADDR 0xfffffd08 +#define ICEMCCR WORD_REF(ICEMCCR_ADDR) + +#define ICEMCCR_PD 0x0001 /* Program/Data Cycle Selection */ +#define ICEMCCR_RW 0x0002 /* Read/Write Cycle Selection */ + +/* + * ICE Module Control Mask Register + */ +#define ICEMCMR_ADDR 0xfffffd0a +#define ICEMCMR WORD_REF(ICEMCMR_ADDR) + +#define ICEMCMR_PDM 0x0001 /* Program/Data Cycle Mask */ +#define ICEMCMR_RWM 0x0002 /* Read/Write Cycle Mask */ + +/* + * ICE Module Control Register + */ +#define ICEMCR_ADDR 0xfffffd0c +#define ICEMCR WORD_REF(ICEMCR_ADDR) + +#define ICEMCR_CEN 0x0001 /* Compare Enable */ +#define ICEMCR_PBEN 0x0002 /* Program Break Enable */ +#define ICEMCR_SB 0x0004 /* Single Breakpoint */ +#define ICEMCR_HMDIS 0x0008 /* HardMap disable */ +#define ICEMCR_BBIEN 0x0010 /* Bus Break Interrupt Enable */ + +/* + * ICE Module Status Register + */ +#define ICEMSR_ADDR 0xfffffd0e +#define ICEMSR WORD_REF(ICEMSR_ADDR) + +#define ICEMSR_EMUEN 0x0001 /* Emulation Enable */ +#define ICEMSR_BRKIRQ 0x0002 /* A-Line Vector Fetch Detected */ +#define ICEMSR_BBIRQ 0x0004 /* Bus Break Interrupt Detected */ +#define ICEMSR_EMIRQ 0x0008 /* EMUIRQ Falling Edge Detected */ + +#endif /* _MC68EZ328_H_ */ diff --git a/arch/m68k/include/asm/MC68VZ328.h b/arch/m68k/include/asm/MC68VZ328.h new file mode 100644 index 00000000000..2b9bf626a0a --- /dev/null +++ b/arch/m68k/include/asm/MC68VZ328.h @@ -0,0 +1,1349 @@ + +/* include/asm-m68knommu/MC68VZ328.h: 'VZ328 control registers + * + * Copyright (c) 2000-2001 Lineo Inc. + * Copyright (c) 2000-2001 Lineo Canada Corp. + * Copyright (C) 1999 Vladimir Gurevich + * Bare & Hare Software, Inc. + * Based on include/asm-m68knommu/MC68332.h + * Copyright (C) 1998 Kenneth Albanowski , + * The Silver Hammer Group, Ltd. + * + * M68VZ328 fixes by Evan Stawnyczy + * vz multiport fixes by Michael Leslie + */ + +#ifndef _MC68VZ328_H_ +#define _MC68VZ328_H_ + +#define BYTE_REF(addr) (*((volatile unsigned char*)addr)) +#define WORD_REF(addr) (*((volatile unsigned short*)addr)) +#define LONG_REF(addr) (*((volatile unsigned long*)addr)) + +#define PUT_FIELD(field, val) (((val) << field##_SHIFT) & field##_MASK) +#define GET_FIELD(reg, field) (((reg) & field##_MASK) >> field##_SHIFT) + +/********** + * + * 0xFFFFF0xx -- System Control + * + **********/ + +/* + * System Control Register (SCR) + */ +#define SCR_ADDR 0xfffff000 +#define SCR BYTE_REF(SCR_ADDR) + +#define SCR_WDTH8 0x01 /* 8-Bit Width Select */ +#define SCR_DMAP 0x04 /* Double Map */ +#define SCR_SO 0x08 /* Supervisor Only */ +#define SCR_BETEN 0x10 /* Bus-Error Time-Out Enable */ +#define SCR_PRV 0x20 /* Privilege Violation */ +#define SCR_WPV 0x40 /* Write Protect Violation */ +#define SCR_BETO 0x80 /* Bus-Error TimeOut */ + +/* + * Silicon ID Register (Mask Revision Register (MRR) for '328 Compatibility) + */ +#define MRR_ADDR 0xfffff004 +#define MRR LONG_REF(MRR_ADDR) + +/********** + * + * 0xFFFFF1xx -- Chip-Select logic + * + **********/ + +/* + * Chip Select Group Base Registers + */ +#define CSGBA_ADDR 0xfffff100 +#define CSGBB_ADDR 0xfffff102 + +#define CSGBC_ADDR 0xfffff104 +#define CSGBD_ADDR 0xfffff106 + +#define CSGBA WORD_REF(CSGBA_ADDR) +#define CSGBB WORD_REF(CSGBB_ADDR) +#define CSGBC WORD_REF(CSGBC_ADDR) +#define CSGBD WORD_REF(CSGBD_ADDR) + +/* + * Chip Select Registers + */ +#define CSA_ADDR 0xfffff110 +#define CSB_ADDR 0xfffff112 +#define CSC_ADDR 0xfffff114 +#define CSD_ADDR 0xfffff116 + +#define CSA WORD_REF(CSA_ADDR) +#define CSB WORD_REF(CSB_ADDR) +#define CSC WORD_REF(CSC_ADDR) +#define CSD WORD_REF(CSD_ADDR) + +#define CSA_EN 0x0001 /* Chip-Select Enable */ +#define CSA_SIZ_MASK 0x000e /* Chip-Select Size */ +#define CSA_SIZ_SHIFT 1 +#define CSA_WS_MASK 0x0070 /* Wait State */ +#define CSA_WS_SHIFT 4 +#define CSA_BSW 0x0080 /* Data Bus Width */ +#define CSA_FLASH 0x0100 /* FLASH Memory Support */ +#define CSA_RO 0x8000 /* Read-Only */ + +#define CSB_EN 0x0001 /* Chip-Select Enable */ +#define CSB_SIZ_MASK 0x000e /* Chip-Select Size */ +#define CSB_SIZ_SHIFT 1 +#define CSB_WS_MASK 0x0070 /* Wait State */ +#define CSB_WS_SHIFT 4 +#define CSB_BSW 0x0080 /* Data Bus Width */ +#define CSB_FLASH 0x0100 /* FLASH Memory Support */ +#define CSB_UPSIZ_MASK 0x1800 /* Unprotected memory block size */ +#define CSB_UPSIZ_SHIFT 11 +#define CSB_ROP 0x2000 /* Readonly if protected */ +#define CSB_SOP 0x4000 /* Supervisor only if protected */ +#define CSB_RO 0x8000 /* Read-Only */ + +#define CSC_EN 0x0001 /* Chip-Select Enable */ +#define CSC_SIZ_MASK 0x000e /* Chip-Select Size */ +#define CSC_SIZ_SHIFT 1 +#define CSC_WS_MASK 0x0070 /* Wait State */ +#define CSC_WS_SHIFT 4 +#define CSC_BSW 0x0080 /* Data Bus Width */ +#define CSC_FLASH 0x0100 /* FLASH Memory Support */ +#define CSC_UPSIZ_MASK 0x1800 /* Unprotected memory block size */ +#define CSC_UPSIZ_SHIFT 11 +#define CSC_ROP 0x2000 /* Readonly if protected */ +#define CSC_SOP 0x4000 /* Supervisor only if protected */ +#define CSC_RO 0x8000 /* Read-Only */ + +#define CSD_EN 0x0001 /* Chip-Select Enable */ +#define CSD_SIZ_MASK 0x000e /* Chip-Select Size */ +#define CSD_SIZ_SHIFT 1 +#define CSD_WS_MASK 0x0070 /* Wait State */ +#define CSD_WS_SHIFT 4 +#define CSD_BSW 0x0080 /* Data Bus Width */ +#define CSD_FLASH 0x0100 /* FLASH Memory Support */ +#define CSD_DRAM 0x0200 /* Dram Selection */ +#define CSD_COMB 0x0400 /* Combining */ +#define CSD_UPSIZ_MASK 0x1800 /* Unprotected memory block size */ +#define CSD_UPSIZ_SHIFT 11 +#define CSD_ROP 0x2000 /* Readonly if protected */ +#define CSD_SOP 0x4000 /* Supervisor only if protected */ +#define CSD_RO 0x8000 /* Read-Only */ + +/* + * Emulation Chip-Select Register + */ +#define EMUCS_ADDR 0xfffff118 +#define EMUCS WORD_REF(EMUCS_ADDR) + +#define EMUCS_WS_MASK 0x0070 +#define EMUCS_WS_SHIFT 4 + +/********** + * + * 0xFFFFF2xx -- Phase Locked Loop (PLL) & Power Control + * + **********/ + +/* + * PLL Control Register + */ +#define PLLCR_ADDR 0xfffff200 +#define PLLCR WORD_REF(PLLCR_ADDR) + +#define PLLCR_DISPLL 0x0008 /* Disable PLL */ +#define PLLCR_CLKEN 0x0010 /* Clock (CLKO pin) enable */ +#define PLLCR_PRESC 0x0020 /* VCO prescaler */ +#define PLLCR_SYSCLK_SEL_MASK 0x0700 /* System Clock Selection */ +#define PLLCR_SYSCLK_SEL_SHIFT 8 +#define PLLCR_LCDCLK_SEL_MASK 0x3800 /* LCD Clock Selection */ +#define PLLCR_LCDCLK_SEL_SHIFT 11 + +/* '328-compatible definitions */ +#define PLLCR_PIXCLK_SEL_MASK PLLCR_LCDCLK_SEL_MASK +#define PLLCR_PIXCLK_SEL_SHIFT PLLCR_LCDCLK_SEL_SHIFT + +/* + * PLL Frequency Select Register + */ +#define PLLFSR_ADDR 0xfffff202 +#define PLLFSR WORD_REF(PLLFSR_ADDR) + +#define PLLFSR_PC_MASK 0x00ff /* P Count */ +#define PLLFSR_PC_SHIFT 0 +#define PLLFSR_QC_MASK 0x0f00 /* Q Count */ +#define PLLFSR_QC_SHIFT 8 +#define PLLFSR_PROT 0x4000 /* Protect P & Q */ +#define PLLFSR_CLK32 0x8000 /* Clock 32 (kHz) */ + +/* + * Power Control Register + */ +#define PCTRL_ADDR 0xfffff207 +#define PCTRL BYTE_REF(PCTRL_ADDR) + +#define PCTRL_WIDTH_MASK 0x1f /* CPU Clock bursts width */ +#define PCTRL_WIDTH_SHIFT 0 +#define PCTRL_PCEN 0x80 /* Power Control Enable */ + +/********** + * + * 0xFFFFF3xx -- Interrupt Controller + * + **********/ + +/* + * Interrupt Vector Register + */ +#define IVR_ADDR 0xfffff300 +#define IVR BYTE_REF(IVR_ADDR) + +#define IVR_VECTOR_MASK 0xF8 + +/* + * Interrupt control Register + */ +#define ICR_ADDR 0xfffff302 +#define ICR WORD_REF(ICR_ADDR) + +#define ICR_POL5 0x0080 /* Polarity Control for IRQ5 */ +#define ICR_ET6 0x0100 /* Edge Trigger Select for IRQ6 */ +#define ICR_ET3 0x0200 /* Edge Trigger Select for IRQ3 */ +#define ICR_ET2 0x0400 /* Edge Trigger Select for IRQ2 */ +#define ICR_ET1 0x0800 /* Edge Trigger Select for IRQ1 */ +#define ICR_POL6 0x1000 /* Polarity Control for IRQ6 */ +#define ICR_POL3 0x2000 /* Polarity Control for IRQ3 */ +#define ICR_POL2 0x4000 /* Polarity Control for IRQ2 */ +#define ICR_POL1 0x8000 /* Polarity Control for IRQ1 */ + +/* + * Interrupt Mask Register + */ +#define IMR_ADDR 0xfffff304 +#define IMR LONG_REF(IMR_ADDR) + +/* + * Define the names for bit positions first. This is useful for + * request_irq + */ +#define SPI2_IRQ_NUM 0 /* SPI 2 interrupt */ +#define TMR_IRQ_NUM 1 /* Timer 1 interrupt */ +#define UART1_IRQ_NUM 2 /* UART 1 interrupt */ +#define WDT_IRQ_NUM 3 /* Watchdog Timer interrupt */ +#define RTC_IRQ_NUM 4 /* RTC interrupt */ +#define TMR2_IRQ_NUM 5 /* Timer 2 interrupt */ +#define KB_IRQ_NUM 6 /* Keyboard Interrupt */ +#define PWM1_IRQ_NUM 7 /* Pulse-Width Modulator 1 int. */ +#define INT0_IRQ_NUM 8 /* External INT0 */ +#define INT1_IRQ_NUM 9 /* External INT1 */ +#define INT2_IRQ_NUM 10 /* External INT2 */ +#define INT3_IRQ_NUM 11 /* External INT3 */ +#define UART2_IRQ_NUM 12 /* UART 2 interrupt */ +#define PWM2_IRQ_NUM 13 /* Pulse-Width Modulator 1 int. */ +#define IRQ1_IRQ_NUM 16 /* IRQ1 */ +#define IRQ2_IRQ_NUM 17 /* IRQ2 */ +#define IRQ3_IRQ_NUM 18 /* IRQ3 */ +#define IRQ6_IRQ_NUM 19 /* IRQ6 */ +#define IRQ5_IRQ_NUM 20 /* IRQ5 */ +#define SPI1_IRQ_NUM 21 /* SPI 1 interrupt */ +#define SAM_IRQ_NUM 22 /* Sampling Timer for RTC */ +#define EMIQ_IRQ_NUM 23 /* Emulator Interrupt */ + +#define SPI_IRQ_NUM SPI2_IRQ_NUM + +/* '328-compatible definitions */ +#define SPIM_IRQ_NUM SPI_IRQ_NUM +#define TMR1_IRQ_NUM TMR_IRQ_NUM +#define UART_IRQ_NUM UART1_IRQ_NUM + +/* + * Here go the bitmasks themselves + */ +#define IMR_MSPI (1 << SPI_IRQ_NUM) /* Mask SPI interrupt */ +#define IMR_MTMR (1 << TMR_IRQ_NUM) /* Mask Timer interrupt */ +#define IMR_MUART (1 << UART_IRQ_NUM) /* Mask UART interrupt */ +#define IMR_MWDT (1 << WDT_IRQ_NUM) /* Mask Watchdog Timer interrupt */ +#define IMR_MRTC (1 << RTC_IRQ_NUM) /* Mask RTC interrupt */ +#define IMR_MKB (1 << KB_IRQ_NUM) /* Mask Keyboard Interrupt */ +#define IMR_MPWM (1 << PWM_IRQ_NUM) /* Mask Pulse-Width Modulator int. */ +#define IMR_MINT0 (1 << INT0_IRQ_NUM) /* Mask External INT0 */ +#define IMR_MINT1 (1 << INT1_IRQ_NUM) /* Mask External INT1 */ +#define IMR_MINT2 (1 << INT2_IRQ_NUM) /* Mask External INT2 */ +#define IMR_MINT3 (1 << INT3_IRQ_NUM) /* Mask External INT3 */ +#define IMR_MIRQ1 (1 << IRQ1_IRQ_NUM) /* Mask IRQ1 */ +#define IMR_MIRQ2 (1 << IRQ2_IRQ_NUM) /* Mask IRQ2 */ +#define IMR_MIRQ3 (1 << IRQ3_IRQ_NUM) /* Mask IRQ3 */ +#define IMR_MIRQ6 (1 << IRQ6_IRQ_NUM) /* Mask IRQ6 */ +#define IMR_MIRQ5 (1 << IRQ5_IRQ_NUM) /* Mask IRQ5 */ +#define IMR_MSAM (1 << SAM_IRQ_NUM) /* Mask Sampling Timer for RTC */ +#define IMR_MEMIQ (1 << EMIQ_IRQ_NUM) /* Mask Emulator Interrupt */ + +/* '328-compatible definitions */ +#define IMR_MSPIM IMR_MSPI +#define IMR_MTMR1 IMR_MTMR + +/* + * Interrupt Status Register + */ +#define ISR_ADDR 0xfffff30c +#define ISR LONG_REF(ISR_ADDR) + +#define ISR_SPI (1 << SPI_IRQ_NUM) /* SPI interrupt */ +#define ISR_TMR (1 << TMR_IRQ_NUM) /* Timer interrupt */ +#define ISR_UART (1 << UART_IRQ_NUM) /* UART interrupt */ +#define ISR_WDT (1 << WDT_IRQ_NUM) /* Watchdog Timer interrupt */ +#define ISR_RTC (1 << RTC_IRQ_NUM) /* RTC interrupt */ +#define ISR_KB (1 << KB_IRQ_NUM) /* Keyboard Interrupt */ +#define ISR_PWM (1 << PWM_IRQ_NUM) /* Pulse-Width Modulator interrupt */ +#define ISR_INT0 (1 << INT0_IRQ_NUM) /* External INT0 */ +#define ISR_INT1 (1 << INT1_IRQ_NUM) /* External INT1 */ +#define ISR_INT2 (1 << INT2_IRQ_NUM) /* External INT2 */ +#define ISR_INT3 (1 << INT3_IRQ_NUM) /* External INT3 */ +#define ISR_IRQ1 (1 << IRQ1_IRQ_NUM) /* IRQ1 */ +#define ISR_IRQ2 (1 << IRQ2_IRQ_NUM) /* IRQ2 */ +#define ISR_IRQ3 (1 << IRQ3_IRQ_NUM) /* IRQ3 */ +#define ISR_IRQ6 (1 << IRQ6_IRQ_NUM) /* IRQ6 */ +#define ISR_IRQ5 (1 << IRQ5_IRQ_NUM) /* IRQ5 */ +#define ISR_SAM (1 << SAM_IRQ_NUM) /* Sampling Timer for RTC */ +#define ISR_EMIQ (1 << EMIQ_IRQ_NUM) /* Emulator Interrupt */ + +/* '328-compatible definitions */ +#define ISR_SPIM ISR_SPI +#define ISR_TMR1 ISR_TMR + +/* + * Interrupt Pending Register + */ +#define IPR_ADDR 0xfffff30c +#define IPR LONG_REF(IPR_ADDR) + +#define IPR_SPI (1 << SPI_IRQ_NUM) /* SPI interrupt */ +#define IPR_TMR (1 << TMR_IRQ_NUM) /* Timer interrupt */ +#define IPR_UART (1 << UART_IRQ_NUM) /* UART interrupt */ +#define IPR_WDT (1 << WDT_IRQ_NUM) /* Watchdog Timer interrupt */ +#define IPR_RTC (1 << RTC_IRQ_NUM) /* RTC interrupt */ +#define IPR_KB (1 << KB_IRQ_NUM) /* Keyboard Interrupt */ +#define IPR_PWM (1 << PWM_IRQ_NUM) /* Pulse-Width Modulator interrupt */ +#define IPR_INT0 (1 << INT0_IRQ_NUM) /* External INT0 */ +#define IPR_INT1 (1 << INT1_IRQ_NUM) /* External INT1 */ +#define IPR_INT2 (1 << INT2_IRQ_NUM) /* External INT2 */ +#define IPR_INT3 (1 << INT3_IRQ_NUM) /* External INT3 */ +#define IPR_IRQ1 (1 << IRQ1_IRQ_NUM) /* IRQ1 */ +#define IPR_IRQ2 (1 << IRQ2_IRQ_NUM) /* IRQ2 */ +#define IPR_IRQ3 (1 << IRQ3_IRQ_NUM) /* IRQ3 */ +#define IPR_IRQ6 (1 << IRQ6_IRQ_NUM) /* IRQ6 */ +#define IPR_IRQ5 (1 << IRQ5_IRQ_NUM) /* IRQ5 */ +#define IPR_SAM (1 << SAM_IRQ_NUM) /* Sampling Timer for RTC */ +#define IPR_EMIQ (1 << EMIQ_IRQ_NUM) /* Emulator Interrupt */ + +/* '328-compatible definitions */ +#define IPR_SPIM IPR_SPI +#define IPR_TMR1 IPR_TMR + +/********** + * + * 0xFFFFF4xx -- Parallel Ports + * + **********/ + +/* + * Port A + */ +#define PADIR_ADDR 0xfffff400 /* Port A direction reg */ +#define PADATA_ADDR 0xfffff401 /* Port A data register */ +#define PAPUEN_ADDR 0xfffff402 /* Port A Pull-Up enable reg */ + +#define PADIR BYTE_REF(PADIR_ADDR) +#define PADATA BYTE_REF(PADATA_ADDR) +#define PAPUEN BYTE_REF(PAPUEN_ADDR) + +#define PA(x) (1 << (x)) + +/* + * Port B + */ +#define PBDIR_ADDR 0xfffff408 /* Port B direction reg */ +#define PBDATA_ADDR 0xfffff409 /* Port B data register */ +#define PBPUEN_ADDR 0xfffff40a /* Port B Pull-Up enable reg */ +#define PBSEL_ADDR 0xfffff40b /* Port B Select Register */ + +#define PBDIR BYTE_REF(PBDIR_ADDR) +#define PBDATA BYTE_REF(PBDATA_ADDR) +#define PBPUEN BYTE_REF(PBPUEN_ADDR) +#define PBSEL BYTE_REF(PBSEL_ADDR) + +#define PB(x) (1 << (x)) + +#define PB_CSB0 0x01 /* Use CSB0 as PB[0] */ +#define PB_CSB1 0x02 /* Use CSB1 as PB[1] */ +#define PB_CSC0_RAS0 0x04 /* Use CSC0/RAS0 as PB[2] */ +#define PB_CSC1_RAS1 0x08 /* Use CSC1/RAS1 as PB[3] */ +#define PB_CSD0_CAS0 0x10 /* Use CSD0/CAS0 as PB[4] */ +#define PB_CSD1_CAS1 0x20 /* Use CSD1/CAS1 as PB[5] */ +#define PB_TIN_TOUT 0x40 /* Use TIN/TOUT as PB[6] */ +#define PB_PWMO 0x80 /* Use PWMO as PB[7] */ + +/* + * Port C + */ +#define PCDIR_ADDR 0xfffff410 /* Port C direction reg */ +#define PCDATA_ADDR 0xfffff411 /* Port C data register */ +#define PCPDEN_ADDR 0xfffff412 /* Port C Pull-Down enb. reg */ +#define PCSEL_ADDR 0xfffff413 /* Port C Select Register */ + +#define PCDIR BYTE_REF(PCDIR_ADDR) +#define PCDATA BYTE_REF(PCDATA_ADDR) +#define PCPDEN BYTE_REF(PCPDEN_ADDR) +#define PCSEL BYTE_REF(PCSEL_ADDR) + +#define PC(x) (1 << (x)) + +#define PC_LD0 0x01 /* Use LD0 as PC[0] */ +#define PC_LD1 0x02 /* Use LD1 as PC[1] */ +#define PC_LD2 0x04 /* Use LD2 as PC[2] */ +#define PC_LD3 0x08 /* Use LD3 as PC[3] */ +#define PC_LFLM 0x10 /* Use LFLM as PC[4] */ +#define PC_LLP 0x20 /* Use LLP as PC[5] */ +#define PC_LCLK 0x40 /* Use LCLK as PC[6] */ +#define PC_LACD 0x80 /* Use LACD as PC[7] */ + +/* + * Port D + */ +#define PDDIR_ADDR 0xfffff418 /* Port D direction reg */ +#define PDDATA_ADDR 0xfffff419 /* Port D data register */ +#define PDPUEN_ADDR 0xfffff41a /* Port D Pull-Up enable reg */ +#define PDSEL_ADDR 0xfffff41b /* Port D Select Register */ +#define PDPOL_ADDR 0xfffff41c /* Port D Polarity Register */ +#define PDIRQEN_ADDR 0xfffff41d /* Port D IRQ enable register */ +#define PDKBEN_ADDR 0xfffff41e /* Port D Keyboard Enable reg */ +#define PDIQEG_ADDR 0xfffff41f /* Port D IRQ Edge Register */ + +#define PDDIR BYTE_REF(PDDIR_ADDR) +#define PDDATA BYTE_REF(PDDATA_ADDR) +#define PDPUEN BYTE_REF(PDPUEN_ADDR) +#define PDSEL BYTE_REF(PDSEL_ADDR) +#define PDPOL BYTE_REF(PDPOL_ADDR) +#define PDIRQEN BYTE_REF(PDIRQEN_ADDR) +#define PDKBEN BYTE_REF(PDKBEN_ADDR) +#define PDIQEG BYTE_REF(PDIQEG_ADDR) + +#define PD(x) (1 << (x)) + +#define PD_INT0 0x01 /* Use INT0 as PD[0] */ +#define PD_INT1 0x02 /* Use INT1 as PD[1] */ +#define PD_INT2 0x04 /* Use INT2 as PD[2] */ +#define PD_INT3 0x08 /* Use INT3 as PD[3] */ +#define PD_IRQ1 0x10 /* Use IRQ1 as PD[4] */ +#define PD_IRQ2 0x20 /* Use IRQ2 as PD[5] */ +#define PD_IRQ3 0x40 /* Use IRQ3 as PD[6] */ +#define PD_IRQ6 0x80 /* Use IRQ6 as PD[7] */ + +/* + * Port E + */ +#define PEDIR_ADDR 0xfffff420 /* Port E direction reg */ +#define PEDATA_ADDR 0xfffff421 /* Port E data register */ +#define PEPUEN_ADDR 0xfffff422 /* Port E Pull-Up enable reg */ +#define PESEL_ADDR 0xfffff423 /* Port E Select Register */ + +#define PEDIR BYTE_REF(PEDIR_ADDR) +#define PEDATA BYTE_REF(PEDATA_ADDR) +#define PEPUEN BYTE_REF(PEPUEN_ADDR) +#define PESEL BYTE_REF(PESEL_ADDR) + +#define PE(x) (1 << (x)) + +#define PE_SPMTXD 0x01 /* Use SPMTXD as PE[0] */ +#define PE_SPMRXD 0x02 /* Use SPMRXD as PE[1] */ +#define PE_SPMCLK 0x04 /* Use SPMCLK as PE[2] */ +#define PE_DWE 0x08 /* Use DWE as PE[3] */ +#define PE_RXD 0x10 /* Use RXD as PE[4] */ +#define PE_TXD 0x20 /* Use TXD as PE[5] */ +#define PE_RTS 0x40 /* Use RTS as PE[6] */ +#define PE_CTS 0x80 /* Use CTS as PE[7] */ + +/* + * Port F + */ +#define PFDIR_ADDR 0xfffff428 /* Port F direction reg */ +#define PFDATA_ADDR 0xfffff429 /* Port F data register */ +#define PFPUEN_ADDR 0xfffff42a /* Port F Pull-Up enable reg */ +#define PFSEL_ADDR 0xfffff42b /* Port F Select Register */ + +#define PFDIR BYTE_REF(PFDIR_ADDR) +#define PFDATA BYTE_REF(PFDATA_ADDR) +#define PFPUEN BYTE_REF(PFPUEN_ADDR) +#define PFSEL BYTE_REF(PFSEL_ADDR) + +#define PF(x) (1 << (x)) + +#define PF_LCONTRAST 0x01 /* Use LCONTRAST as PF[0] */ +#define PF_IRQ5 0x02 /* Use IRQ5 as PF[1] */ +#define PF_CLKO 0x04 /* Use CLKO as PF[2] */ +#define PF_A20 0x08 /* Use A20 as PF[3] */ +#define PF_A21 0x10 /* Use A21 as PF[4] */ +#define PF_A22 0x20 /* Use A22 as PF[5] */ +#define PF_A23 0x40 /* Use A23 as PF[6] */ +#define PF_CSA1 0x80 /* Use CSA1 as PF[7] */ + +/* + * Port G + */ +#define PGDIR_ADDR 0xfffff430 /* Port G direction reg */ +#define PGDATA_ADDR 0xfffff431 /* Port G data register */ +#define PGPUEN_ADDR 0xfffff432 /* Port G Pull-Up enable reg */ +#define PGSEL_ADDR 0xfffff433 /* Port G Select Register */ + +#define PGDIR BYTE_REF(PGDIR_ADDR) +#define PGDATA BYTE_REF(PGDATA_ADDR) +#define PGPUEN BYTE_REF(PGPUEN_ADDR) +#define PGSEL BYTE_REF(PGSEL_ADDR) + +#define PG(x) (1 << (x)) + +#define PG_BUSW_DTACK 0x01 /* Use BUSW/DTACK as PG[0] */ +#define PG_A0 0x02 /* Use A0 as PG[1] */ +#define PG_EMUIRQ 0x04 /* Use EMUIRQ as PG[2] */ +#define PG_HIZ_P_D 0x08 /* Use HIZ/P/D as PG[3] */ +#define PG_EMUCS 0x10 /* Use EMUCS as PG[4] */ +#define PG_EMUBRK 0x20 /* Use EMUBRK as PG[5] */ + +/* + * Port J + */ +#define PJDIR_ADDR 0xfffff438 /* Port J direction reg */ +#define PJDATA_ADDR 0xfffff439 /* Port J data register */ +#define PJPUEN_ADDR 0xfffff43A /* Port J Pull-Up enb. reg */ +#define PJSEL_ADDR 0xfffff43B /* Port J Select Register */ + +#define PJDIR BYTE_REF(PJDIR_ADDR) +#define PJDATA BYTE_REF(PJDATA_ADDR) +#define PJPUEN BYTE_REF(PJPUEN_ADDR) +#define PJSEL BYTE_REF(PJSEL_ADDR) + +#define PJ(x) (1 << (x)) + +/* + * Port K + */ +#define PKDIR_ADDR 0xfffff440 /* Port K direction reg */ +#define PKDATA_ADDR 0xfffff441 /* Port K data register */ +#define PKPUEN_ADDR 0xfffff442 /* Port K Pull-Up enb. reg */ +#define PKSEL_ADDR 0xfffff443 /* Port K Select Register */ + +#define PKDIR BYTE_REF(PKDIR_ADDR) +#define PKDATA BYTE_REF(PKDATA_ADDR) +#define PKPUEN BYTE_REF(PKPUEN_ADDR) +#define PKSEL BYTE_REF(PKSEL_ADDR) + +#define PK(x) (1 << (x)) + +#define PK_DATAREADY 0x01 /* Use ~DATA_READY as PK[0] */ +#define PK_PWM2 0x01 /* Use PWM2 as PK[0] */ +#define PK_R_W 0x02 /* Use R/W as PK[1] */ +#define PK_LDS 0x04 /* Use /LDS as PK[2] */ +#define PK_UDS 0x08 /* Use /UDS as PK[3] */ +#define PK_LD4 0x10 /* Use LD4 as PK[4] */ +#define PK_LD5 0x20 /* Use LD5 as PK[5] */ +#define PK_LD6 0x40 /* Use LD6 as PK[6] */ +#define PK_LD7 0x80 /* Use LD7 as PK[7] */ + +#define PJDIR_ADDR 0xfffff438 /* Port J direction reg */ +#define PJDATA_ADDR 0xfffff439 /* Port J data register */ +#define PJPUEN_ADDR 0xfffff43A /* Port J Pull-Up enable reg */ +#define PJSEL_ADDR 0xfffff43B /* Port J Select Register */ + +#define PJDIR BYTE_REF(PJDIR_ADDR) +#define PJDATA BYTE_REF(PJDATA_ADDR) +#define PJPUEN BYTE_REF(PJPUEN_ADDR) +#define PJSEL BYTE_REF(PJSEL_ADDR) + +#define PJ(x) (1 << (x)) + +#define PJ_MOSI 0x01 /* Use MOSI as PJ[0] */ +#define PJ_MISO 0x02 /* Use MISO as PJ[1] */ +#define PJ_SPICLK1 0x04 /* Use SPICLK1 as PJ[2] */ +#define PJ_SS 0x08 /* Use SS as PJ[3] */ +#define PJ_RXD2 0x10 /* Use RXD2 as PJ[4] */ +#define PJ_TXD2 0x20 /* Use TXD2 as PJ[5] */ +#define PJ_RTS2 0x40 /* Use RTS2 as PJ[5] */ +#define PJ_CTS2 0x80 /* Use CTS2 as PJ[5] */ + +/* + * Port M + */ +#define PMDIR_ADDR 0xfffff448 /* Port M direction reg */ +#define PMDATA_ADDR 0xfffff449 /* Port M data register */ +#define PMPUEN_ADDR 0xfffff44a /* Port M Pull-Up enable reg */ +#define PMSEL_ADDR 0xfffff44b /* Port M Select Register */ + +#define PMDIR BYTE_REF(PMDIR_ADDR) +#define PMDATA BYTE_REF(PMDATA_ADDR) +#define PMPUEN BYTE_REF(PMPUEN_ADDR) +#define PMSEL BYTE_REF(PMSEL_ADDR) + +#define PM(x) (1 << (x)) + +#define PM_SDCLK 0x01 /* Use SDCLK as PM[0] */ +#define PM_SDCE 0x02 /* Use SDCE as PM[1] */ +#define PM_DQMH 0x04 /* Use DQMH as PM[2] */ +#define PM_DQML 0x08 /* Use DQML as PM[3] */ +#define PM_SDA10 0x10 /* Use SDA10 as PM[4] */ +#define PM_DMOE 0x20 /* Use DMOE as PM[5] */ + +/********** + * + * 0xFFFFF5xx -- Pulse-Width Modulator (PWM) + * + **********/ + +/* + * PWM Control Register + */ +#define PWMC_ADDR 0xfffff500 +#define PWMC WORD_REF(PWMC_ADDR) + +#define PWMC_CLKSEL_MASK 0x0003 /* Clock Selection */ +#define PWMC_CLKSEL_SHIFT 0 +#define PWMC_REPEAT_MASK 0x000c /* Sample Repeats */ +#define PWMC_REPEAT_SHIFT 2 +#define PWMC_EN 0x0010 /* Enable PWM */ +#define PMNC_FIFOAV 0x0020 /* FIFO Available */ +#define PWMC_IRQEN 0x0040 /* Interrupt Request Enable */ +#define PWMC_IRQ 0x0080 /* Interrupt Request (FIFO empty) */ +#define PWMC_PRESCALER_MASK 0x7f00 /* Incoming Clock prescaler */ +#define PWMC_PRESCALER_SHIFT 8 +#define PWMC_CLKSRC 0x8000 /* Clock Source Select */ + +/* '328-compatible definitions */ +#define PWMC_PWMEN PWMC_EN + +/* + * PWM Sample Register + */ +#define PWMS_ADDR 0xfffff502 +#define PWMS WORD_REF(PWMS_ADDR) + +/* + * PWM Period Register + */ +#define PWMP_ADDR 0xfffff504 +#define PWMP BYTE_REF(PWMP_ADDR) + +/* + * PWM Counter Register + */ +#define PWMCNT_ADDR 0xfffff505 +#define PWMCNT BYTE_REF(PWMCNT_ADDR) + +/********** + * + * 0xFFFFF6xx -- General-Purpose Timer + * + **********/ + +/* + * Timer Control register + */ +#define TCTL_ADDR 0xfffff600 +#define TCTL WORD_REF(TCTL_ADDR) + +#define TCTL_TEN 0x0001 /* Timer Enable */ +#define TCTL_CLKSOURCE_MASK 0x000e /* Clock Source: */ +#define TCTL_CLKSOURCE_STOP 0x0000 /* Stop count (disabled) */ +#define TCTL_CLKSOURCE_SYSCLK 0x0002 /* SYSCLK to prescaler */ +#define TCTL_CLKSOURCE_SYSCLK_16 0x0004 /* SYSCLK/16 to prescaler */ +#define TCTL_CLKSOURCE_TIN 0x0006 /* TIN to prescaler */ +#define TCTL_CLKSOURCE_32KHZ 0x0008 /* 32kHz clock to prescaler */ +#define TCTL_IRQEN 0x0010 /* IRQ Enable */ +#define TCTL_OM 0x0020 /* Output Mode */ +#define TCTL_CAP_MASK 0x00c0 /* Capture Edge: */ +#define TCTL_CAP_RE 0x0040 /* Capture on rizing edge */ +#define TCTL_CAP_FE 0x0080 /* Capture on falling edge */ +#define TCTL_FRR 0x0010 /* Free-Run Mode */ + +/* '328-compatible definitions */ +#define TCTL1_ADDR TCTL_ADDR +#define TCTL1 TCTL + +/* + * Timer Prescaler Register + */ +#define TPRER_ADDR 0xfffff602 +#define TPRER WORD_REF(TPRER_ADDR) + +/* '328-compatible definitions */ +#define TPRER1_ADDR TPRER_ADDR +#define TPRER1 TPRER + +/* + * Timer Compare Register + */ +#define TCMP_ADDR 0xfffff604 +#define TCMP WORD_REF(TCMP_ADDR) + +/* '328-compatible definitions */ +#define TCMP1_ADDR TCMP_ADDR +#define TCMP1 TCMP + +/* + * Timer Capture register + */ +#define TCR_ADDR 0xfffff606 +#define TCR WORD_REF(TCR_ADDR) + +/* '328-compatible definitions */ +#define TCR1_ADDR TCR_ADDR +#define TCR1 TCR + +/* + * Timer Counter Register + */ +#define TCN_ADDR 0xfffff608 +#define TCN WORD_REF(TCN_ADDR) + +/* '328-compatible definitions */ +#define TCN1_ADDR TCN_ADDR +#define TCN1 TCN + +/* + * Timer Status Register + */ +#define TSTAT_ADDR 0xfffff60a +#define TSTAT WORD_REF(TSTAT_ADDR) + +#define TSTAT_COMP 0x0001 /* Compare Event occurred */ +#define TSTAT_CAPT 0x0001 /* Capture Event occurred */ + +/* '328-compatible definitions */ +#define TSTAT1_ADDR TSTAT_ADDR +#define TSTAT1 TSTAT + +/********** + * + * 0xFFFFF8xx -- Serial Periferial Interface Master (SPIM) + * + **********/ + +/* + * SPIM Data Register + */ +#define SPIMDATA_ADDR 0xfffff800 +#define SPIMDATA WORD_REF(SPIMDATA_ADDR) + +/* + * SPIM Control/Status Register + */ +#define SPIMCONT_ADDR 0xfffff802 +#define SPIMCONT WORD_REF(SPIMCONT_ADDR) + +#define SPIMCONT_BIT_COUNT_MASK 0x000f /* Transfer Length in Bytes */ +#define SPIMCONT_BIT_COUNT_SHIFT 0 +#define SPIMCONT_POL 0x0010 /* SPMCLK Signel Polarity */ +#define SPIMCONT_PHA 0x0020 /* Clock/Data phase relationship */ +#define SPIMCONT_IRQEN 0x0040 /* IRQ Enable */ +#define SPIMCONT_IRQ 0x0080 /* Interrupt Request */ +#define SPIMCONT_XCH 0x0100 /* Exchange */ +#define SPIMCONT_ENABLE 0x0200 /* Enable SPIM */ +#define SPIMCONT_DATA_RATE_MASK 0xe000 /* SPIM Data Rate */ +#define SPIMCONT_DATA_RATE_SHIFT 13 + +/* '328-compatible definitions */ +#define SPIMCONT_SPIMIRQ SPIMCONT_IRQ +#define SPIMCONT_SPIMEN SPIMCONT_ENABLE + +/********** + * + * 0xFFFFF9xx -- UART + * + **********/ + +/* + * UART Status/Control Register + */ + +#define USTCNT_ADDR 0xfffff900 +#define USTCNT WORD_REF(USTCNT_ADDR) + +#define USTCNT_TXAE 0x0001 /* Transmitter Available Interrupt Enable */ +#define USTCNT_TXHE 0x0002 /* Transmitter Half Empty Enable */ +#define USTCNT_TXEE 0x0004 /* Transmitter Empty Interrupt Enable */ +#define USTCNT_RXRE 0x0008 /* Receiver Ready Interrupt Enable */ +#define USTCNT_RXHE 0x0010 /* Receiver Half-Full Interrupt Enable */ +#define USTCNT_RXFE 0x0020 /* Receiver Full Interrupt Enable */ +#define USTCNT_CTSD 0x0040 /* CTS Delta Interrupt Enable */ +#define USTCNT_ODEN 0x0080 /* Old Data Interrupt Enable */ +#define USTCNT_8_7 0x0100 /* Eight or seven-bit transmission */ +#define USTCNT_STOP 0x0200 /* Stop bit transmission */ +#define USTCNT_ODD 0x0400 /* Odd Parity */ +#define USTCNT_PEN 0x0800 /* Parity Enable */ +#define USTCNT_CLKM 0x1000 /* Clock Mode Select */ +#define USTCNT_TXEN 0x2000 /* Transmitter Enable */ +#define USTCNT_RXEN 0x4000 /* Receiver Enable */ +#define USTCNT_UEN 0x8000 /* UART Enable */ + +/* '328-compatible definitions */ +#define USTCNT_TXAVAILEN USTCNT_TXAE +#define USTCNT_TXHALFEN USTCNT_TXHE +#define USTCNT_TXEMPTYEN USTCNT_TXEE +#define USTCNT_RXREADYEN USTCNT_RXRE +#define USTCNT_RXHALFEN USTCNT_RXHE +#define USTCNT_RXFULLEN USTCNT_RXFE +#define USTCNT_CTSDELTAEN USTCNT_CTSD +#define USTCNT_ODD_EVEN USTCNT_ODD +#define USTCNT_PARITYEN USTCNT_PEN +#define USTCNT_CLKMODE USTCNT_CLKM +#define USTCNT_UARTEN USTCNT_UEN + +/* + * UART Baud Control Register + */ +#define UBAUD_ADDR 0xfffff902 +#define UBAUD WORD_REF(UBAUD_ADDR) + +#define UBAUD_PRESCALER_MASK 0x003f /* Actual divisor is 65 - PRESCALER */ +#define UBAUD_PRESCALER_SHIFT 0 +#define UBAUD_DIVIDE_MASK 0x0700 /* Baud Rate freq. divizor */ +#define UBAUD_DIVIDE_SHIFT 8 +#define UBAUD_BAUD_SRC 0x0800 /* Baud Rate Source */ +#define UBAUD_UCLKDIR 0x2000 /* UCLK Direction */ + +/* + * UART Receiver Register + */ +#define URX_ADDR 0xfffff904 +#define URX WORD_REF(URX_ADDR) + +#define URX_RXDATA_ADDR 0xfffff905 +#define URX_RXDATA BYTE_REF(URX_RXDATA_ADDR) + +#define URX_RXDATA_MASK 0x00ff /* Received data */ +#define URX_RXDATA_SHIFT 0 +#define URX_PARITY_ERROR 0x0100 /* Parity Error */ +#define URX_BREAK 0x0200 /* Break Detected */ +#define URX_FRAME_ERROR 0x0400 /* Framing Error */ +#define URX_OVRUN 0x0800 /* Serial Overrun */ +#define URX_OLD_DATA 0x1000 /* Old data in FIFO */ +#define URX_DATA_READY 0x2000 /* Data Ready (FIFO not empty) */ +#define URX_FIFO_HALF 0x4000 /* FIFO is Half-Full */ +#define URX_FIFO_FULL 0x8000 /* FIFO is Full */ + +/* + * UART Transmitter Register + */ +#define UTX_ADDR 0xfffff906 +#define UTX WORD_REF(UTX_ADDR) + +#define UTX_TXDATA_ADDR 0xfffff907 +#define UTX_TXDATA BYTE_REF(UTX_TXDATA_ADDR) + +#define UTX_TXDATA_MASK 0x00ff /* Data to be transmitted */ +#define UTX_TXDATA_SHIFT 0 +#define UTX_CTS_DELTA 0x0100 /* CTS changed */ +#define UTX_CTS_STAT 0x0200 /* CTS State */ +#define UTX_BUSY 0x0400 /* FIFO is busy, sending a character */ +#define UTX_NOCTS 0x0800 /* Ignore CTS */ +#define UTX_SEND_BREAK 0x1000 /* Send a BREAK */ +#define UTX_TX_AVAIL 0x2000 /* Transmit FIFO has a slot available */ +#define UTX_FIFO_HALF 0x4000 /* Transmit FIFO is half empty */ +#define UTX_FIFO_EMPTY 0x8000 /* Transmit FIFO is empty */ + +/* '328-compatible definitions */ +#define UTX_CTS_STATUS UTX_CTS_STAT +#define UTX_IGNORE_CTS UTX_NOCTS + +/* + * UART Miscellaneous Register + */ +#define UMISC_ADDR 0xfffff908 +#define UMISC WORD_REF(UMISC_ADDR) + +#define UMISC_TX_POL 0x0004 /* Transmit Polarity */ +#define UMISC_RX_POL 0x0008 /* Receive Polarity */ +#define UMISC_IRDA_LOOP 0x0010 /* IrDA Loopback Enable */ +#define UMISC_IRDA_EN 0x0020 /* Infra-Red Enable */ +#define UMISC_RTS 0x0040 /* Set RTS status */ +#define UMISC_RTSCONT 0x0080 /* Choose RTS control */ +#define UMISC_IR_TEST 0x0400 /* IRDA Test Enable */ +#define UMISC_BAUD_RESET 0x0800 /* Reset Baud Rate Generation Counters */ +#define UMISC_LOOP 0x1000 /* Serial Loopback Enable */ +#define UMISC_FORCE_PERR 0x2000 /* Force Parity Error */ +#define UMISC_CLKSRC 0x4000 /* Clock Source */ +#define UMISC_BAUD_TEST 0x8000 /* Enable Baud Test Mode */ + +/* + * UART Non-integer Prescaler Register + */ +#define NIPR_ADDR 0xfffff90a +#define NIPR WORD_REF(NIPR_ADDR) + +#define NIPR_STEP_VALUE_MASK 0x00ff /* NI prescaler step value */ +#define NIPR_STEP_VALUE_SHIFT 0 +#define NIPR_SELECT_MASK 0x0700 /* Tap Selection */ +#define NIPR_SELECT_SHIFT 8 +#define NIPR_PRE_SEL 0x8000 /* Non-integer prescaler select */ + + +/* generalization of uart control registers to support multiple ports: */ +typedef struct { + volatile unsigned short int ustcnt; + volatile unsigned short int ubaud; + union { + volatile unsigned short int w; + struct { + volatile unsigned char status; + volatile unsigned char rxdata; + } b; + } urx; + union { + volatile unsigned short int w; + struct { + volatile unsigned char status; + volatile unsigned char txdata; + } b; + } utx; + volatile unsigned short int umisc; + volatile unsigned short int nipr; + volatile unsigned short int hmark; + volatile unsigned short int unused; +} __attribute__((packed)) m68328_uart; + + + + +/********** + * + * 0xFFFFFAxx -- LCD Controller + * + **********/ + +/* + * LCD Screen Starting Address Register + */ +#define LSSA_ADDR 0xfffffa00 +#define LSSA LONG_REF(LSSA_ADDR) + +#define LSSA_SSA_MASK 0x1ffffffe /* Bits 0 and 29-31 are reserved */ + +/* + * LCD Virtual Page Width Register + */ +#define LVPW_ADDR 0xfffffa05 +#define LVPW BYTE_REF(LVPW_ADDR) + +/* + * LCD Screen Width Register (not compatible with '328 !!!) + */ +#define LXMAX_ADDR 0xfffffa08 +#define LXMAX WORD_REF(LXMAX_ADDR) + +#define LXMAX_XM_MASK 0x02f0 /* Bits 0-3 and 10-15 are reserved */ + +/* + * LCD Screen Height Register + */ +#define LYMAX_ADDR 0xfffffa0a +#define LYMAX WORD_REF(LYMAX_ADDR) + +#define LYMAX_YM_MASK 0x01ff /* Bits 9-15 are reserved */ + +/* + * LCD Cursor X Position Register + */ +#define LCXP_ADDR 0xfffffa18 +#define LCXP WORD_REF(LCXP_ADDR) + +#define LCXP_CC_MASK 0xc000 /* Cursor Control */ +#define LCXP_CC_TRAMSPARENT 0x0000 +#define LCXP_CC_BLACK 0x4000 +#define LCXP_CC_REVERSED 0x8000 +#define LCXP_CC_WHITE 0xc000 +#define LCXP_CXP_MASK 0x02ff /* Cursor X position */ + +/* + * LCD Cursor Y Position Register + */ +#define LCYP_ADDR 0xfffffa1a +#define LCYP WORD_REF(LCYP_ADDR) + +#define LCYP_CYP_MASK 0x01ff /* Cursor Y Position */ + +/* + * LCD Cursor Width and Heigth Register + */ +#define LCWCH_ADDR 0xfffffa1c +#define LCWCH WORD_REF(LCWCH_ADDR) + +#define LCWCH_CH_MASK 0x001f /* Cursor Height */ +#define LCWCH_CH_SHIFT 0 +#define LCWCH_CW_MASK 0x1f00 /* Cursor Width */ +#define LCWCH_CW_SHIFT 8 + +/* + * LCD Blink Control Register + */ +#define LBLKC_ADDR 0xfffffa1f +#define LBLKC BYTE_REF(LBLKC_ADDR) + +#define LBLKC_BD_MASK 0x7f /* Blink Divisor */ +#define LBLKC_BD_SHIFT 0 +#define LBLKC_BKEN 0x80 /* Blink Enabled */ + +/* + * LCD Panel Interface Configuration Register + */ +#define LPICF_ADDR 0xfffffa20 +#define LPICF BYTE_REF(LPICF_ADDR) + +#define LPICF_GS_MASK 0x03 /* Gray-Scale Mode */ +#define LPICF_GS_BW 0x00 +#define LPICF_GS_GRAY_4 0x01 +#define LPICF_GS_GRAY_16 0x02 +#define LPICF_PBSIZ_MASK 0x0c /* Panel Bus Width */ +#define LPICF_PBSIZ_1 0x00 +#define LPICF_PBSIZ_2 0x04 +#define LPICF_PBSIZ_4 0x08 + +/* + * LCD Polarity Configuration Register + */ +#define LPOLCF_ADDR 0xfffffa21 +#define LPOLCF BYTE_REF(LPOLCF_ADDR) + +#define LPOLCF_PIXPOL 0x01 /* Pixel Polarity */ +#define LPOLCF_LPPOL 0x02 /* Line Pulse Polarity */ +#define LPOLCF_FLMPOL 0x04 /* Frame Marker Polarity */ +#define LPOLCF_LCKPOL 0x08 /* LCD Shift Lock Polarity */ + +/* + * LACD (LCD Alternate Crystal Direction) Rate Control Register + */ +#define LACDRC_ADDR 0xfffffa23 +#define LACDRC BYTE_REF(LACDRC_ADDR) + +#define LACDRC_ACDSLT 0x80 /* Signal Source Select */ +#define LACDRC_ACD_MASK 0x0f /* Alternate Crystal Direction Control */ +#define LACDRC_ACD_SHIFT 0 + +/* + * LCD Pixel Clock Divider Register + */ +#define LPXCD_ADDR 0xfffffa25 +#define LPXCD BYTE_REF(LPXCD_ADDR) + +#define LPXCD_PCD_MASK 0x3f /* Pixel Clock Divider */ +#define LPXCD_PCD_SHIFT 0 + +/* + * LCD Clocking Control Register + */ +#define LCKCON_ADDR 0xfffffa27 +#define LCKCON BYTE_REF(LCKCON_ADDR) + +#define LCKCON_DWS_MASK 0x0f /* Display Wait-State */ +#define LCKCON_DWS_SHIFT 0 +#define LCKCON_DWIDTH 0x40 /* Display Memory Width */ +#define LCKCON_LCDON 0x80 /* Enable LCD Controller */ + +/* '328-compatible definitions */ +#define LCKCON_DW_MASK LCKCON_DWS_MASK +#define LCKCON_DW_SHIFT LCKCON_DWS_SHIFT + +/* + * LCD Refresh Rate Adjustment Register + */ +#define LRRA_ADDR 0xfffffa29 +#define LRRA BYTE_REF(LRRA_ADDR) + +/* + * LCD Panning Offset Register + */ +#define LPOSR_ADDR 0xfffffa2d +#define LPOSR BYTE_REF(LPOSR_ADDR) + +#define LPOSR_POS_MASK 0x0f /* Pixel Offset Code */ +#define LPOSR_POS_SHIFT 0 + +/* + * LCD Frame Rate Control Modulation Register + */ +#define LFRCM_ADDR 0xfffffa31 +#define LFRCM BYTE_REF(LFRCM_ADDR) + +#define LFRCM_YMOD_MASK 0x0f /* Vertical Modulation */ +#define LFRCM_YMOD_SHIFT 0 +#define LFRCM_XMOD_MASK 0xf0 /* Horizontal Modulation */ +#define LFRCM_XMOD_SHIFT 4 + +/* + * LCD Gray Palette Mapping Register + */ +#define LGPMR_ADDR 0xfffffa33 +#define LGPMR BYTE_REF(LGPMR_ADDR) + +#define LGPMR_G1_MASK 0x0f +#define LGPMR_G1_SHIFT 0 +#define LGPMR_G2_MASK 0xf0 +#define LGPMR_G2_SHIFT 4 + +/* + * PWM Contrast Control Register + */ +#define PWMR_ADDR 0xfffffa36 +#define PWMR WORD_REF(PWMR_ADDR) + +#define PWMR_PW_MASK 0x00ff /* Pulse Width */ +#define PWMR_PW_SHIFT 0 +#define PWMR_CCPEN 0x0100 /* Contrast Control Enable */ +#define PWMR_SRC_MASK 0x0600 /* Input Clock Source */ +#define PWMR_SRC_LINE 0x0000 /* Line Pulse */ +#define PWMR_SRC_PIXEL 0x0200 /* Pixel Clock */ +#define PWMR_SRC_LCD 0x4000 /* LCD clock */ + +/********** + * + * 0xFFFFFBxx -- Real-Time Clock (RTC) + * + **********/ + +/* + * RTC Hours Minutes and Seconds Register + */ +#define RTCTIME_ADDR 0xfffffb00 +#define RTCTIME LONG_REF(RTCTIME_ADDR) + +#define RTCTIME_SECONDS_MASK 0x0000003f /* Seconds */ +#define RTCTIME_SECONDS_SHIFT 0 +#define RTCTIME_MINUTES_MASK 0x003f0000 /* Minutes */ +#define RTCTIME_MINUTES_SHIFT 16 +#define RTCTIME_HOURS_MASK 0x1f000000 /* Hours */ +#define RTCTIME_HOURS_SHIFT 24 + +/* + * RTC Alarm Register + */ +#define RTCALRM_ADDR 0xfffffb04 +#define RTCALRM LONG_REF(RTCALRM_ADDR) + +#define RTCALRM_SECONDS_MASK 0x0000003f /* Seconds */ +#define RTCALRM_SECONDS_SHIFT 0 +#define RTCALRM_MINUTES_MASK 0x003f0000 /* Minutes */ +#define RTCALRM_MINUTES_SHIFT 16 +#define RTCALRM_HOURS_MASK 0x1f000000 /* Hours */ +#define RTCALRM_HOURS_SHIFT 24 + +/* + * Watchdog Timer Register + */ +#define WATCHDOG_ADDR 0xfffffb0a +#define WATCHDOG WORD_REF(WATCHDOG_ADDR) + +#define WATCHDOG_EN 0x0001 /* Watchdog Enabled */ +#define WATCHDOG_ISEL 0x0002 /* Select the watchdog interrupt */ +#define WATCHDOG_INTF 0x0080 /* Watchdog interrupt occcured */ +#define WATCHDOG_CNT_MASK 0x0300 /* Watchdog Counter */ +#define WATCHDOG_CNT_SHIFT 8 + +/* + * RTC Control Register + */ +#define RTCCTL_ADDR 0xfffffb0c +#define RTCCTL WORD_REF(RTCCTL_ADDR) + +#define RTCCTL_XTL 0x0020 /* Crystal Selection */ +#define RTCCTL_EN 0x0080 /* RTC Enable */ + +/* '328-compatible definitions */ +#define RTCCTL_384 RTCCTL_XTL +#define RTCCTL_ENABLE RTCCTL_EN + +/* + * RTC Interrupt Status Register + */ +#define RTCISR_ADDR 0xfffffb0e +#define RTCISR WORD_REF(RTCISR_ADDR) + +#define RTCISR_SW 0x0001 /* Stopwatch timed out */ +#define RTCISR_MIN 0x0002 /* 1-minute interrupt has occurred */ +#define RTCISR_ALM 0x0004 /* Alarm interrupt has occurred */ +#define RTCISR_DAY 0x0008 /* 24-hour rollover interrupt has occurred */ +#define RTCISR_1HZ 0x0010 /* 1Hz interrupt has occurred */ +#define RTCISR_HR 0x0020 /* 1-hour interrupt has occurred */ +#define RTCISR_SAM0 0x0100 /* 4Hz / 4.6875Hz interrupt has occurred */ +#define RTCISR_SAM1 0x0200 /* 8Hz / 9.3750Hz interrupt has occurred */ +#define RTCISR_SAM2 0x0400 /* 16Hz / 18.7500Hz interrupt has occurred */ +#define RTCISR_SAM3 0x0800 /* 32Hz / 37.5000Hz interrupt has occurred */ +#define RTCISR_SAM4 0x1000 /* 64Hz / 75.0000Hz interrupt has occurred */ +#define RTCISR_SAM5 0x2000 /* 128Hz / 150.0000Hz interrupt has occurred */ +#define RTCISR_SAM6 0x4000 /* 256Hz / 300.0000Hz interrupt has occurred */ +#define RTCISR_SAM7 0x8000 /* 512Hz / 600.0000Hz interrupt has occurred */ + +/* + * RTC Interrupt Enable Register + */ +#define RTCIENR_ADDR 0xfffffb10 +#define RTCIENR WORD_REF(RTCIENR_ADDR) + +#define RTCIENR_SW 0x0001 /* Stopwatch interrupt enable */ +#define RTCIENR_MIN 0x0002 /* 1-minute interrupt enable */ +#define RTCIENR_ALM 0x0004 /* Alarm interrupt enable */ +#define RTCIENR_DAY 0x0008 /* 24-hour rollover interrupt enable */ +#define RTCIENR_1HZ 0x0010 /* 1Hz interrupt enable */ +#define RTCIENR_HR 0x0020 /* 1-hour interrupt enable */ +#define RTCIENR_SAM0 0x0100 /* 4Hz / 4.6875Hz interrupt enable */ +#define RTCIENR_SAM1 0x0200 /* 8Hz / 9.3750Hz interrupt enable */ +#define RTCIENR_SAM2 0x0400 /* 16Hz / 18.7500Hz interrupt enable */ +#define RTCIENR_SAM3 0x0800 /* 32Hz / 37.5000Hz interrupt enable */ +#define RTCIENR_SAM4 0x1000 /* 64Hz / 75.0000Hz interrupt enable */ +#define RTCIENR_SAM5 0x2000 /* 128Hz / 150.0000Hz interrupt enable */ +#define RTCIENR_SAM6 0x4000 /* 256Hz / 300.0000Hz interrupt enable */ +#define RTCIENR_SAM7 0x8000 /* 512Hz / 600.0000Hz interrupt enable */ + +/* + * Stopwatch Minutes Register + */ +#define STPWCH_ADDR 0xfffffb12 +#define STPWCH WORD_REF(STPWCH_ADDR) + +#define STPWCH_CNT_MASK 0x003f /* Stopwatch countdown value */ +#define SPTWCH_CNT_SHIFT 0 + +/* + * RTC Day Count Register + */ +#define DAYR_ADDR 0xfffffb1a +#define DAYR WORD_REF(DAYR_ADDR) + +#define DAYR_DAYS_MASK 0x1ff /* Day Setting */ +#define DAYR_DAYS_SHIFT 0 + +/* + * RTC Day Alarm Register + */ +#define DAYALARM_ADDR 0xfffffb1c +#define DAYALARM WORD_REF(DAYALARM_ADDR) + +#define DAYALARM_DAYSAL_MASK 0x01ff /* Day Setting of the Alarm */ +#define DAYALARM_DAYSAL_SHIFT 0 + +/********** + * + * 0xFFFFFCxx -- DRAM Controller + * + **********/ + +/* + * DRAM Memory Configuration Register + */ +#define DRAMMC_ADDR 0xfffffc00 +#define DRAMMC WORD_REF(DRAMMC_ADDR) + +#define DRAMMC_ROW12_MASK 0xc000 /* Row address bit for MD12 */ +#define DRAMMC_ROW12_PA10 0x0000 +#define DRAMMC_ROW12_PA21 0x4000 +#define DRAMMC_ROW12_PA23 0x8000 +#define DRAMMC_ROW0_MASK 0x3000 /* Row address bit for MD0 */ +#define DRAMMC_ROW0_PA11 0x0000 +#define DRAMMC_ROW0_PA22 0x1000 +#define DRAMMC_ROW0_PA23 0x2000 +#define DRAMMC_ROW11 0x0800 /* Row address bit for MD11 PA20/PA22 */ +#define DRAMMC_ROW10 0x0400 /* Row address bit for MD10 PA19/PA21 */ +#define DRAMMC_ROW9 0x0200 /* Row address bit for MD9 PA9/PA19 */ +#define DRAMMC_ROW8 0x0100 /* Row address bit for MD8 PA10/PA20 */ +#define DRAMMC_COL10 0x0080 /* Col address bit for MD10 PA11/PA0 */ +#define DRAMMC_COL9 0x0040 /* Col address bit for MD9 PA10/PA0 */ +#define DRAMMC_COL8 0x0020 /* Col address bit for MD8 PA9/PA0 */ +#define DRAMMC_REF_MASK 0x001f /* Reresh Cycle */ +#define DRAMMC_REF_SHIFT 0 + +/* + * DRAM Control Register + */ +#define DRAMC_ADDR 0xfffffc02 +#define DRAMC WORD_REF(DRAMC_ADDR) + +#define DRAMC_DWE 0x0001 /* DRAM Write Enable */ +#define DRAMC_RST 0x0002 /* Reset Burst Refresh Enable */ +#define DRAMC_LPR 0x0004 /* Low-Power Refresh Enable */ +#define DRAMC_SLW 0x0008 /* Slow RAM */ +#define DRAMC_LSP 0x0010 /* Light Sleep */ +#define DRAMC_MSW 0x0020 /* Slow Multiplexing */ +#define DRAMC_WS_MASK 0x00c0 /* Wait-states */ +#define DRAMC_WS_SHIFT 6 +#define DRAMC_PGSZ_MASK 0x0300 /* Page Size for fast page mode */ +#define DRAMC_PGSZ_SHIFT 8 +#define DRAMC_PGSZ_256K 0x0000 +#define DRAMC_PGSZ_512K 0x0100 +#define DRAMC_PGSZ_1024K 0x0200 +#define DRAMC_PGSZ_2048K 0x0300 +#define DRAMC_EDO 0x0400 /* EDO DRAM */ +#define DRAMC_CLK 0x0800 /* Refresh Timer Clock source select */ +#define DRAMC_BC_MASK 0x3000 /* Page Access Clock Cycle (FP mode) */ +#define DRAMC_BC_SHIFT 12 +#define DRAMC_RM 0x4000 /* Refresh Mode */ +#define DRAMC_EN 0x8000 /* DRAM Controller enable */ + + +/********** + * + * 0xFFFFFDxx -- In-Circuit Emulation (ICE) + * + **********/ + +/* + * ICE Module Address Compare Register + */ +#define ICEMACR_ADDR 0xfffffd00 +#define ICEMACR LONG_REF(ICEMACR_ADDR) + +/* + * ICE Module Address Mask Register + */ +#define ICEMAMR_ADDR 0xfffffd04 +#define ICEMAMR LONG_REF(ICEMAMR_ADDR) + +/* + * ICE Module Control Compare Register + */ +#define ICEMCCR_ADDR 0xfffffd08 +#define ICEMCCR WORD_REF(ICEMCCR_ADDR) + +#define ICEMCCR_PD 0x0001 /* Program/Data Cycle Selection */ +#define ICEMCCR_RW 0x0002 /* Read/Write Cycle Selection */ + +/* + * ICE Module Control Mask Register + */ +#define ICEMCMR_ADDR 0xfffffd0a +#define ICEMCMR WORD_REF(ICEMCMR_ADDR) + +#define ICEMCMR_PDM 0x0001 /* Program/Data Cycle Mask */ +#define ICEMCMR_RWM 0x0002 /* Read/Write Cycle Mask */ + +/* + * ICE Module Control Register + */ +#define ICEMCR_ADDR 0xfffffd0c +#define ICEMCR WORD_REF(ICEMCR_ADDR) + +#define ICEMCR_CEN 0x0001 /* Compare Enable */ +#define ICEMCR_PBEN 0x0002 /* Program Break Enable */ +#define ICEMCR_SB 0x0004 /* Single Breakpoint */ +#define ICEMCR_HMDIS 0x0008 /* HardMap disable */ +#define ICEMCR_BBIEN 0x0010 /* Bus Break Interrupt Enable */ + +/* + * ICE Module Status Register + */ +#define ICEMSR_ADDR 0xfffffd0e +#define ICEMSR WORD_REF(ICEMSR_ADDR) + +#define ICEMSR_EMUEN 0x0001 /* Emulation Enable */ +#define ICEMSR_BRKIRQ 0x0002 /* A-Line Vector Fetch Detected */ +#define ICEMSR_BBIRQ 0x0004 /* Bus Break Interrupt Detected */ +#define ICEMSR_EMIRQ 0x0008 /* EMUIRQ Falling Edge Detected */ + +#endif /* _MC68VZ328_H_ */ diff --git a/arch/m68k/include/asm/a.out-core.h b/arch/m68k/include/asm/a.out-core.h new file mode 100644 index 00000000000..f6bfc1d63ff --- /dev/null +++ b/arch/m68k/include/asm/a.out-core.h @@ -0,0 +1,67 @@ +/* a.out coredump register dumper + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_A_OUT_CORE_H +#define _ASM_A_OUT_CORE_H + +#ifdef __KERNEL__ + +#include +#include + +/* + * fill in the user structure for an a.out core dump + */ +static inline void aout_dump_thread(struct pt_regs *regs, struct user *dump) +{ + struct switch_stack *sw; + +/* changed the size calculations - should hopefully work better. lbt */ + dump->magic = CMAGIC; + dump->start_code = 0; + dump->start_stack = rdusp() & ~(PAGE_SIZE - 1); + dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT; + dump->u_dsize = ((unsigned long) (current->mm->brk + + (PAGE_SIZE-1))) >> PAGE_SHIFT; + dump->u_dsize -= dump->u_tsize; + dump->u_ssize = 0; + + if (dump->start_stack < TASK_SIZE) + dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT; + + dump->u_ar0 = offsetof(struct user, regs); + sw = ((struct switch_stack *)regs) - 1; + dump->regs.d1 = regs->d1; + dump->regs.d2 = regs->d2; + dump->regs.d3 = regs->d3; + dump->regs.d4 = regs->d4; + dump->regs.d5 = regs->d5; + dump->regs.d6 = sw->d6; + dump->regs.d7 = sw->d7; + dump->regs.a0 = regs->a0; + dump->regs.a1 = regs->a1; + dump->regs.a2 = regs->a2; + dump->regs.a3 = sw->a3; + dump->regs.a4 = sw->a4; + dump->regs.a5 = sw->a5; + dump->regs.a6 = sw->a6; + dump->regs.d0 = regs->d0; + dump->regs.orig_d0 = regs->orig_d0; + dump->regs.stkadj = regs->stkadj; + dump->regs.sr = regs->sr; + dump->regs.pc = regs->pc; + dump->regs.fmtvec = (regs->format << 12) | regs->vector; + /* dump floating point stuff */ + dump->u_fpvalid = dump_fpu (regs, &dump->m68kfp); +} + +#endif /* __KERNEL__ */ +#endif /* _ASM_A_OUT_CORE_H */ diff --git a/arch/m68k/include/asm/a.out.h b/arch/m68k/include/asm/a.out.h new file mode 100644 index 00000000000..3885fe43432 --- /dev/null +++ b/arch/m68k/include/asm/a.out.h @@ -0,0 +1,20 @@ +#ifndef __M68K_A_OUT_H__ +#define __M68K_A_OUT_H__ + +struct exec +{ + unsigned long a_info; /* Use macros N_MAGIC, etc for access */ + unsigned a_text; /* length of text, in bytes */ + unsigned a_data; /* length of data, in bytes */ + unsigned a_bss; /* length of uninitialized data area for file, in bytes */ + unsigned a_syms; /* length of symbol table data in file, in bytes */ + unsigned a_entry; /* start address */ + unsigned a_trsize; /* length of relocation info for text, in bytes */ + unsigned a_drsize; /* length of relocation info for data, in bytes */ +}; + +#define N_TRSIZE(a) ((a).a_trsize) +#define N_DRSIZE(a) ((a).a_drsize) +#define N_SYMSIZE(a) ((a).a_syms) + +#endif /* __M68K_A_OUT_H__ */ diff --git a/arch/m68k/include/asm/adb_iop.h b/arch/m68k/include/asm/adb_iop.h new file mode 100644 index 00000000000..8a48e56f2d6 --- /dev/null +++ b/arch/m68k/include/asm/adb_iop.h @@ -0,0 +1,44 @@ +/* + * ADB through the IOP + * Written by Joshua M. Thompson + */ + +/* IOP number and channel number for ADB */ + +#define ADB_IOP IOP_NUM_ISM +#define ADB_CHAN 2 + +/* From the A/UX headers...maybe important, maybe not */ + +#define ADB_IOP_LISTEN 0x01 +#define ADB_IOP_TALK 0x02 +#define ADB_IOP_EXISTS 0x04 +#define ADB_IOP_FLUSH 0x08 +#define ADB_IOP_RESET 0x10 +#define ADB_IOP_INT 0x20 +#define ADB_IOP_POLL 0x40 +#define ADB_IOP_UNINT 0x80 + +#define AIF_RESET 0x00 +#define AIF_FLUSH 0x01 +#define AIF_LISTEN 0x08 +#define AIF_TALK 0x0C + +/* Flag bits in struct adb_iopmsg */ + +#define ADB_IOP_EXPLICIT 0x80 /* nonzero if explicit command */ +#define ADB_IOP_AUTOPOLL 0x40 /* auto/SRQ polling enabled */ +#define ADB_IOP_SRQ 0x04 /* SRQ detected */ +#define ADB_IOP_TIMEOUT 0x02 /* nonzero if timeout */ + +#ifndef __ASSEMBLY__ + +struct adb_iopmsg { + __u8 flags; /* ADB flags */ + __u8 count; /* no. of data bytes */ + __u8 cmd; /* ADB command */ + __u8 data[8]; /* ADB data */ + __u8 spare[21]; /* spare */ +}; + +#endif /* __ASSEMBLY__ */ diff --git a/arch/m68k/include/asm/amigahw.h b/arch/m68k/include/asm/amigahw.h new file mode 100644 index 00000000000..5ca5dd951a4 --- /dev/null +++ b/arch/m68k/include/asm/amigahw.h @@ -0,0 +1,350 @@ +/* +** asm-m68k/amigahw.h -- This header defines some macros and pointers for +** the various Amiga custom hardware registers. +** The naming conventions used here conform to those +** used in the Amiga Hardware Reference Manual, 3rd Edition +** +** Copyright 1992 by Greg Harp +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +** Created: 9/24/92 by Greg Harp +*/ + +#ifndef _M68K_AMIGAHW_H +#define _M68K_AMIGAHW_H + +#include + + /* + * Different Amiga models + */ + +#define AMI_UNKNOWN (0) +#define AMI_500 (1) +#define AMI_500PLUS (2) +#define AMI_600 (3) +#define AMI_1000 (4) +#define AMI_1200 (5) +#define AMI_2000 (6) +#define AMI_2500 (7) +#define AMI_3000 (8) +#define AMI_3000T (9) +#define AMI_3000PLUS (10) +#define AMI_4000 (11) +#define AMI_4000T (12) +#define AMI_CDTV (13) +#define AMI_CD32 (14) +#define AMI_DRACO (15) + + + /* + * Chipsets + */ + +extern unsigned long amiga_chipset; + +#define CS_STONEAGE (0) +#define CS_OCS (1) +#define CS_ECS (2) +#define CS_AGA (3) + + + /* + * Miscellaneous + */ + +extern unsigned long amiga_eclock; /* 700 kHz E Peripheral Clock */ +extern unsigned long amiga_colorclock; /* 3.5 MHz Color Clock */ +extern unsigned long amiga_chip_size; /* Chip RAM Size (bytes) */ +extern unsigned char amiga_vblank; /* VBLANK Frequency */ + + +#define AMIGAHW_DECLARE(name) unsigned name : 1 +#define AMIGAHW_SET(name) (amiga_hw_present.name = 1) +#define AMIGAHW_PRESENT(name) (amiga_hw_present.name) + +struct amiga_hw_present { + /* video hardware */ + AMIGAHW_DECLARE(AMI_VIDEO); /* Amiga Video */ + AMIGAHW_DECLARE(AMI_BLITTER); /* Amiga Blitter */ + AMIGAHW_DECLARE(AMBER_FF); /* Amber Flicker Fixer */ + /* sound hardware */ + AMIGAHW_DECLARE(AMI_AUDIO); /* Amiga Audio */ + /* disk storage interfaces */ + AMIGAHW_DECLARE(AMI_FLOPPY); /* Amiga Floppy */ + AMIGAHW_DECLARE(A3000_SCSI); /* SCSI (wd33c93, A3000 alike) */ + AMIGAHW_DECLARE(A4000_SCSI); /* SCSI (ncr53c710, A4000T alike) */ + AMIGAHW_DECLARE(A1200_IDE); /* IDE (A1200 alike) */ + AMIGAHW_DECLARE(A4000_IDE); /* IDE (A4000 alike) */ + AMIGAHW_DECLARE(CD_ROM); /* CD ROM drive */ + /* other I/O hardware */ + AMIGAHW_DECLARE(AMI_KEYBOARD); /* Amiga Keyboard */ + AMIGAHW_DECLARE(AMI_MOUSE); /* Amiga Mouse */ + AMIGAHW_DECLARE(AMI_SERIAL); /* Amiga Serial */ + AMIGAHW_DECLARE(AMI_PARALLEL); /* Amiga Parallel */ + /* real time clocks */ + AMIGAHW_DECLARE(A2000_CLK); /* Hardware Clock (A2000 alike) */ + AMIGAHW_DECLARE(A3000_CLK); /* Hardware Clock (A3000 alike) */ + /* supporting hardware */ + AMIGAHW_DECLARE(CHIP_RAM); /* Chip RAM */ + AMIGAHW_DECLARE(PAULA); /* Paula (8364) */ + AMIGAHW_DECLARE(DENISE); /* Denise (8362) */ + AMIGAHW_DECLARE(DENISE_HR); /* Denise (8373) */ + AMIGAHW_DECLARE(LISA); /* Lisa (8375) */ + AMIGAHW_DECLARE(AGNUS_PAL); /* Normal/Fat PAL Agnus (8367/8371) */ + AMIGAHW_DECLARE(AGNUS_NTSC); /* Normal/Fat NTSC Agnus (8361/8370) */ + AMIGAHW_DECLARE(AGNUS_HR_PAL); /* Fat Hires PAL Agnus (8372) */ + AMIGAHW_DECLARE(AGNUS_HR_NTSC); /* Fat Hires NTSC Agnus (8372) */ + AMIGAHW_DECLARE(ALICE_PAL); /* PAL Alice (8374) */ + AMIGAHW_DECLARE(ALICE_NTSC); /* NTSC Alice (8374) */ + AMIGAHW_DECLARE(MAGIC_REKICK); /* A3000 Magic Hard Rekick */ + AMIGAHW_DECLARE(PCMCIA); /* PCMCIA Slot */ + AMIGAHW_DECLARE(GG2_ISA); /* GG2 Zorro2ISA Bridge */ + AMIGAHW_DECLARE(ZORRO); /* Zorro AutoConfig */ + AMIGAHW_DECLARE(ZORRO3); /* Zorro III */ +}; + +extern struct amiga_hw_present amiga_hw_present; + +struct CUSTOM { + unsigned short bltddat; + unsigned short dmaconr; + unsigned short vposr; + unsigned short vhposr; + unsigned short dskdatr; + unsigned short joy0dat; + unsigned short joy1dat; + unsigned short clxdat; + unsigned short adkconr; + unsigned short pot0dat; + unsigned short pot1dat; + unsigned short potgor; + unsigned short serdatr; + unsigned short dskbytr; + unsigned short intenar; + unsigned short intreqr; + unsigned char *dskptr; + unsigned short dsklen; + unsigned short dskdat; + unsigned short refptr; + unsigned short vposw; + unsigned short vhposw; + unsigned short copcon; + unsigned short serdat; + unsigned short serper; + unsigned short potgo; + unsigned short joytest; + unsigned short strequ; + unsigned short strvbl; + unsigned short strhor; + unsigned short strlong; + unsigned short bltcon0; + unsigned short bltcon1; + unsigned short bltafwm; + unsigned short bltalwm; + unsigned char *bltcpt; + unsigned char *bltbpt; + unsigned char *bltapt; + unsigned char *bltdpt; + unsigned short bltsize; + unsigned char pad2d; + unsigned char bltcon0l; + unsigned short bltsizv; + unsigned short bltsizh; + unsigned short bltcmod; + unsigned short bltbmod; + unsigned short bltamod; + unsigned short bltdmod; + unsigned short spare2[4]; + unsigned short bltcdat; + unsigned short bltbdat; + unsigned short bltadat; + unsigned short spare3[3]; + unsigned short deniseid; + unsigned short dsksync; + unsigned short *cop1lc; + unsigned short *cop2lc; + unsigned short copjmp1; + unsigned short copjmp2; + unsigned short copins; + unsigned short diwstrt; + unsigned short diwstop; + unsigned short ddfstrt; + unsigned short ddfstop; + unsigned short dmacon; + unsigned short clxcon; + unsigned short intena; + unsigned short intreq; + unsigned short adkcon; + struct { + unsigned short *audlc; + unsigned short audlen; + unsigned short audper; + unsigned short audvol; + unsigned short auddat; + unsigned short audspare[2]; + } aud[4]; + unsigned char *bplpt[8]; + unsigned short bplcon0; + unsigned short bplcon1; + unsigned short bplcon2; + unsigned short bplcon3; + unsigned short bpl1mod; + unsigned short bpl2mod; + unsigned short bplcon4; + unsigned short clxcon2; + unsigned short bpldat[8]; + unsigned char *sprpt[8]; + struct { + unsigned short pos; + unsigned short ctl; + unsigned short dataa; + unsigned short datab; + } spr[8]; + unsigned short color[32]; + unsigned short htotal; + unsigned short hsstop; + unsigned short hbstrt; + unsigned short hbstop; + unsigned short vtotal; + unsigned short vsstop; + unsigned short vbstrt; + unsigned short vbstop; + unsigned short sprhstrt; + unsigned short sprhstop; + unsigned short bplhstrt; + unsigned short bplhstop; + unsigned short hhposw; + unsigned short hhposr; + unsigned short beamcon0; + unsigned short hsstrt; + unsigned short vsstrt; + unsigned short hcenter; + unsigned short diwhigh; + unsigned short spare4[11]; + unsigned short fmode; +}; + +/* + * DMA register bits + */ +#define DMAF_SETCLR (0x8000) +#define DMAF_AUD0 (0x0001) +#define DMAF_AUD1 (0x0002) +#define DMAF_AUD2 (0x0004) +#define DMAF_AUD3 (0x0008) +#define DMAF_DISK (0x0010) +#define DMAF_SPRITE (0x0020) +#define DMAF_BLITTER (0x0040) +#define DMAF_COPPER (0x0080) +#define DMAF_RASTER (0x0100) +#define DMAF_MASTER (0x0200) +#define DMAF_BLITHOG (0x0400) +#define DMAF_BLTNZERO (0x2000) +#define DMAF_BLTDONE (0x4000) +#define DMAF_ALL (0x01FF) + +struct CIA { + unsigned char pra; char pad0[0xff]; + unsigned char prb; char pad1[0xff]; + unsigned char ddra; char pad2[0xff]; + unsigned char ddrb; char pad3[0xff]; + unsigned char talo; char pad4[0xff]; + unsigned char tahi; char pad5[0xff]; + unsigned char tblo; char pad6[0xff]; + unsigned char tbhi; char pad7[0xff]; + unsigned char todlo; char pad8[0xff]; + unsigned char todmid; char pad9[0xff]; + unsigned char todhi; char pada[0x1ff]; + unsigned char sdr; char padb[0xff]; + unsigned char icr; char padc[0xff]; + unsigned char cra; char padd[0xff]; + unsigned char crb; char pade[0xff]; +}; + +#define zTwoBase (0x80000000) +#define ZTWO_PADDR(x) (((unsigned long)(x))-zTwoBase) +#define ZTWO_VADDR(x) (((unsigned long)(x))+zTwoBase) + +#define CUSTOM_PHYSADDR (0xdff000) +#define amiga_custom ((*(volatile struct CUSTOM *)(zTwoBase+CUSTOM_PHYSADDR))) + +#define CIAA_PHYSADDR (0xbfe001) +#define CIAB_PHYSADDR (0xbfd000) +#define ciaa ((*(volatile struct CIA *)(zTwoBase + CIAA_PHYSADDR))) +#define ciab ((*(volatile struct CIA *)(zTwoBase + CIAB_PHYSADDR))) + +#define CHIP_PHYSADDR (0x000000) + +void amiga_chip_init (void); +void *amiga_chip_alloc(unsigned long size, const char *name); +void *amiga_chip_alloc_res(unsigned long size, struct resource *res); +void amiga_chip_free(void *ptr); +unsigned long amiga_chip_avail( void ); /*MILAN*/ +extern volatile unsigned short amiga_audio_min_period; + +static inline void amifb_video_off(void) +{ + if (amiga_chipset == CS_ECS || amiga_chipset == CS_AGA) { + /* program Denise/Lisa for a higher maximum play rate */ + amiga_custom.htotal = 113; /* 31 kHz */ + amiga_custom.vtotal = 223; /* 70 Hz */ + amiga_custom.beamcon0 = 0x4390; /* HARDDIS, VAR{BEAM,VSY,HSY,CSY}EN */ + /* suspend the monitor */ + amiga_custom.hsstrt = amiga_custom.hsstop = 116; + amiga_custom.vsstrt = amiga_custom.vsstop = 226; + amiga_audio_min_period = 57; + } +} + +struct tod3000 { + unsigned int :28, second2:4; /* lower digit */ + unsigned int :28, second1:4; /* upper digit */ + unsigned int :28, minute2:4; /* lower digit */ + unsigned int :28, minute1:4; /* upper digit */ + unsigned int :28, hour2:4; /* lower digit */ + unsigned int :28, hour1:4; /* upper digit */ + unsigned int :28, weekday:4; + unsigned int :28, day2:4; /* lower digit */ + unsigned int :28, day1:4; /* upper digit */ + unsigned int :28, month2:4; /* lower digit */ + unsigned int :28, month1:4; /* upper digit */ + unsigned int :28, year2:4; /* lower digit */ + unsigned int :28, year1:4; /* upper digit */ + unsigned int :28, cntrl1:4; /* control-byte 1 */ + unsigned int :28, cntrl2:4; /* control-byte 2 */ + unsigned int :28, cntrl3:4; /* control-byte 3 */ +}; +#define TOD3000_CNTRL1_HOLD 0 +#define TOD3000_CNTRL1_FREE 9 +#define tod_3000 ((*(volatile struct tod3000 *)(zTwoBase+0xDC0000))) + +struct tod2000 { + unsigned int :28, second2:4; /* lower digit */ + unsigned int :28, second1:4; /* upper digit */ + unsigned int :28, minute2:4; /* lower digit */ + unsigned int :28, minute1:4; /* upper digit */ + unsigned int :28, hour2:4; /* lower digit */ + unsigned int :28, hour1:4; /* upper digit */ + unsigned int :28, day2:4; /* lower digit */ + unsigned int :28, day1:4; /* upper digit */ + unsigned int :28, month2:4; /* lower digit */ + unsigned int :28, month1:4; /* upper digit */ + unsigned int :28, year2:4; /* lower digit */ + unsigned int :28, year1:4; /* upper digit */ + unsigned int :28, weekday:4; + unsigned int :28, cntrl1:4; /* control-byte 1 */ + unsigned int :28, cntrl2:4; /* control-byte 2 */ + unsigned int :28, cntrl3:4; /* control-byte 3 */ +}; + +#define TOD2000_CNTRL1_HOLD (1<<0) +#define TOD2000_CNTRL1_BUSY (1<<1) +#define TOD2000_CNTRL3_24HMODE (1<<2) +#define TOD2000_HOUR1_PM (1<<2) +#define tod_2000 ((*(volatile struct tod2000 *)(zTwoBase+0xDC0000))) + +#endif /* _M68K_AMIGAHW_H */ diff --git a/arch/m68k/include/asm/amigaints.h b/arch/m68k/include/asm/amigaints.h new file mode 100644 index 00000000000..b1bcdb835ab --- /dev/null +++ b/arch/m68k/include/asm/amigaints.h @@ -0,0 +1,113 @@ +/* +** amigaints.h -- Amiga Linux interrupt handling structs and prototypes +** +** Copyright 1992 by Greg Harp +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +** Created 10/2/92 by Greg Harp +*/ + +#ifndef _ASMm68k_AMIGAINTS_H_ +#define _ASMm68k_AMIGAINTS_H_ + +#include + +/* +** Amiga Interrupt sources. +** +*/ + +#define AUTO_IRQS (8) +#define AMI_STD_IRQS (14) +#define CIA_IRQS (5) +#define AMI_IRQS (32) /* AUTO_IRQS+AMI_STD_IRQS+2*CIA_IRQS */ + +/* builtin serial port interrupts */ +#define IRQ_AMIGA_TBE (IRQ_USER+0) +#define IRQ_AMIGA_RBF (IRQ_USER+11) + +/* floppy disk interrupts */ +#define IRQ_AMIGA_DSKBLK (IRQ_USER+1) +#define IRQ_AMIGA_DSKSYN (IRQ_USER+12) + +/* software interrupts */ +#define IRQ_AMIGA_SOFT (IRQ_USER+2) + +/* interrupts from external hardware */ +#define IRQ_AMIGA_PORTS IRQ_AUTO_2 +#define IRQ_AMIGA_EXTER IRQ_AUTO_6 + +/* copper interrupt */ +#define IRQ_AMIGA_COPPER (IRQ_USER+4) + +/* vertical blanking interrupt */ +#define IRQ_AMIGA_VERTB (IRQ_USER+5) + +/* Blitter done interrupt */ +#define IRQ_AMIGA_BLIT (IRQ_USER+6) + +/* Audio interrupts */ +#define IRQ_AMIGA_AUD0 (IRQ_USER+7) +#define IRQ_AMIGA_AUD1 (IRQ_USER+8) +#define IRQ_AMIGA_AUD2 (IRQ_USER+9) +#define IRQ_AMIGA_AUD3 (IRQ_USER+10) + +/* CIA interrupt sources */ +#define IRQ_AMIGA_CIAA (IRQ_USER+14) +#define IRQ_AMIGA_CIAA_TA (IRQ_USER+14) +#define IRQ_AMIGA_CIAA_TB (IRQ_USER+15) +#define IRQ_AMIGA_CIAA_ALRM (IRQ_USER+16) +#define IRQ_AMIGA_CIAA_SP (IRQ_USER+17) +#define IRQ_AMIGA_CIAA_FLG (IRQ_USER+18) +#define IRQ_AMIGA_CIAB (IRQ_USER+19) +#define IRQ_AMIGA_CIAB_TA (IRQ_USER+19) +#define IRQ_AMIGA_CIAB_TB (IRQ_USER+20) +#define IRQ_AMIGA_CIAB_ALRM (IRQ_USER+21) +#define IRQ_AMIGA_CIAB_SP (IRQ_USER+22) +#define IRQ_AMIGA_CIAB_FLG (IRQ_USER+23) + + +/* INTREQR masks */ +#define IF_SETCLR 0x8000 /* set/clr bit */ +#define IF_INTEN 0x4000 /* master interrupt bit in INT* registers */ +#define IF_EXTER 0x2000 /* external level 6 and CIA B interrupt */ +#define IF_DSKSYN 0x1000 /* disk sync interrupt */ +#define IF_RBF 0x0800 /* serial receive buffer full interrupt */ +#define IF_AUD3 0x0400 /* audio channel 3 done interrupt */ +#define IF_AUD2 0x0200 /* audio channel 2 done interrupt */ +#define IF_AUD1 0x0100 /* audio channel 1 done interrupt */ +#define IF_AUD0 0x0080 /* audio channel 0 done interrupt */ +#define IF_BLIT 0x0040 /* blitter done interrupt */ +#define IF_VERTB 0x0020 /* vertical blanking interrupt */ +#define IF_COPER 0x0010 /* copper interrupt */ +#define IF_PORTS 0x0008 /* external level 2 and CIA A interrupt */ +#define IF_SOFT 0x0004 /* software initiated interrupt */ +#define IF_DSKBLK 0x0002 /* diskblock DMA finished */ +#define IF_TBE 0x0001 /* serial transmit buffer empty interrupt */ + +/* CIA interrupt control register bits */ + +#define CIA_ICR_TA 0x01 +#define CIA_ICR_TB 0x02 +#define CIA_ICR_ALRM 0x04 +#define CIA_ICR_SP 0x08 +#define CIA_ICR_FLG 0x10 +#define CIA_ICR_ALL 0x1f +#define CIA_ICR_SETCLR 0x80 + +extern void amiga_init_IRQ(void); + +/* to access the interrupt control registers of CIA's use only +** these functions, they behave exactly like the amiga os routines +*/ + +extern struct ciabase ciaa_base, ciab_base; + +extern void cia_init_IRQ(struct ciabase *base); +extern unsigned char cia_set_irq(struct ciabase *base, unsigned char mask); +extern unsigned char cia_able_irq(struct ciabase *base, unsigned char mask); + +#endif /* asm-m68k/amigaints.h */ diff --git a/arch/m68k/include/asm/amigayle.h b/arch/m68k/include/asm/amigayle.h new file mode 100644 index 00000000000..bb5a6aa329f --- /dev/null +++ b/arch/m68k/include/asm/amigayle.h @@ -0,0 +1,107 @@ +/* +** asm-m68k/amigayle.h -- This header defines the registers of the gayle chip +** found on the Amiga 1200 +** This information was found by disassembling card.resource, +** so the definitions may not be 100% correct +** anyone has an official doc ? +** +** Copyright 1997 by Alain Malek +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +** Created: 11/28/97 by Alain Malek +*/ + +#ifndef _M68K_AMIGAYLE_H_ +#define _M68K_AMIGAYLE_H_ + +#include +#include + +/* memory layout */ + +#define GAYLE_RAM (0x600000+zTwoBase) +#define GAYLE_RAMSIZE (0x400000) +#define GAYLE_ATTRIBUTE (0xa00000+zTwoBase) +#define GAYLE_ATTRIBUTESIZE (0x020000) +#define GAYLE_IO (0xa20000+zTwoBase) /* 16bit and even 8bit registers */ +#define GAYLE_IOSIZE (0x010000) +#define GAYLE_IO_8BITODD (0xa30000+zTwoBase) /* odd 8bit registers */ + +/* offset for accessing odd IO registers */ +#define GAYLE_ODD (GAYLE_IO_8BITODD-GAYLE_IO-1) + +/* GAYLE registers */ + +struct GAYLE { + u_char cardstatus; + u_char pad0[0x1000-1]; + + u_char intreq; + u_char pad1[0x1000-1]; + + u_char inten; + u_char pad2[0x1000-1]; + + u_char config; + u_char pad3[0x1000-1]; +}; + +#define GAYLE_ADDRESS (0xda8000) /* gayle main registers base address */ + +#define GAYLE_RESET (0xa40000) /* write 0x00 to start reset, + read 1 byte to stop reset */ + +#define gayle (*(volatile struct GAYLE *)(zTwoBase+GAYLE_ADDRESS)) +#define gayle_reset (*(volatile u_char *)(zTwoBase+GAYLE_RESET)) + +#define gayle_attribute ((volatile u_char *)(GAYLE_ATTRIBUTE)) + +#if 0 +#define gayle_inb(a) readb( GAYLE_IO+(a)+(((a)&1)*GAYLE_ODD) ) +#define gayle_outb(v,a) writeb( v, GAYLE_IO+(a)+(((a)&1)*GAYLE_ODD) ) + +#define gayle_inw(a) readw( GAYLE_IO+(a) ) +#define gayle_outw(v,a) writew( v, GAYLE_IO+(a) ) +#endif + +/* GAYLE_CARDSTATUS bit def */ + +#define GAYLE_CS_CCDET 0x40 /* credit card detect */ +#define GAYLE_CS_BVD1 0x20 /* battery voltage detect 1 */ +#define GAYLE_CS_SC 0x20 /* credit card status change */ +#define GAYLE_CS_BVD2 0x10 /* battery voltage detect 2 */ +#define GAYLE_CS_DA 0x10 /* digital audio */ +#define GAYLE_CS_WR 0x08 /* write enable (1 == enabled) */ +#define GAYLE_CS_BSY 0x04 /* credit card busy */ +#define GAYLE_CS_IRQ 0x04 /* interrupt request */ + +/* GAYLE_IRQ bit def */ + +#define GAYLE_IRQ_IDE 0x80 +#define GAYLE_IRQ_CCDET 0x40 +#define GAYLE_IRQ_BVD1 0x20 +#define GAYLE_IRQ_SC 0x20 +#define GAYLE_IRQ_BVD2 0x10 +#define GAYLE_IRQ_DA 0x10 +#define GAYLE_IRQ_WR 0x08 +#define GAYLE_IRQ_BSY 0x04 +#define GAYLE_IRQ_IRQ 0x04 +#define GAYLE_IRQ_IDEACK1 0x02 +#define GAYLE_IRQ_IDEACK0 0x01 + +/* GAYLE_CONFIG bit def + (bit 0-1 for program voltage, bit 2-3 for access speed */ + +#define GAYLE_CFG_0V 0x00 +#define GAYLE_CFG_5V 0x01 +#define GAYLE_CFG_12V 0x02 + +#define GAYLE_CFG_100NS 0x08 +#define GAYLE_CFG_150NS 0x04 +#define GAYLE_CFG_250NS 0x00 +#define GAYLE_CFG_720NS 0x0c + +#endif /* asm-m68k/amigayle.h */ diff --git a/arch/m68k/include/asm/amipcmcia.h b/arch/m68k/include/asm/amipcmcia.h new file mode 100644 index 00000000000..6f1ec1887d8 --- /dev/null +++ b/arch/m68k/include/asm/amipcmcia.h @@ -0,0 +1,110 @@ +/* +** asm-m68k/pcmcia.h -- Amiga Linux PCMCIA Definitions +** +** Copyright 1997 by Alain Malek +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +** Created: 12/10/97 by Alain Malek +*/ + +#ifndef __AMIGA_PCMCIA_H__ +#define __AMIGA_PCMCIA_H__ + +#include + +/* prototypes */ + +void pcmcia_reset(void); +int pcmcia_copy_tuple(unsigned char tuple_id, void *tuple, int max_len); +void pcmcia_program_voltage(int voltage); +void pcmcia_access_speed(int speed); +void pcmcia_write_enable(void); +void pcmcia_write_disable(void); + +static inline u_char pcmcia_read_status(void) +{ + return (gayle.cardstatus & 0x7c); +} + +static inline u_char pcmcia_get_intreq(void) +{ + return (gayle.intreq); +} + +static inline void pcmcia_ack_int(u_char intreq) +{ + gayle.intreq = 0xf8; +} + +static inline void pcmcia_enable_irq(void) +{ + gayle.inten |= GAYLE_IRQ_IRQ; +} + +static inline void pcmcia_disable_irq(void) +{ + gayle.inten &= ~GAYLE_IRQ_IRQ; +} + +#define PCMCIA_INSERTED (gayle.cardstatus & GAYLE_CS_CCDET) + +/* valid voltages for pcmcia_ProgramVoltage */ + +#define PCMCIA_0V 0 +#define PCMCIA_5V 5 +#define PCMCIA_12V 12 + +/* valid speeds for pcmcia_AccessSpeed */ + +#define PCMCIA_SPEED_100NS 100 +#define PCMCIA_SPEED_150NS 150 +#define PCMCIA_SPEED_250NS 250 +#define PCMCIA_SPEED_720NS 720 + +/* PCMCIA Tuple codes */ + +#define CISTPL_NULL 0x00 +#define CISTPL_DEVICE 0x01 +#define CISTPL_LONGLINK_CB 0x02 +#define CISTPL_CONFIG_CB 0x04 +#define CISTPL_CFTABLE_ENTRY_CB 0x05 +#define CISTPL_LONGLINK_MFC 0x06 +#define CISTPL_BAR 0x07 +#define CISTPL_CHECKSUM 0x10 +#define CISTPL_LONGLINK_A 0x11 +#define CISTPL_LONGLINK_C 0x12 +#define CISTPL_LINKTARGET 0x13 +#define CISTPL_NO_LINK 0x14 +#define CISTPL_VERS_1 0x15 +#define CISTPL_ALTSTR 0x16 +#define CISTPL_DEVICE_A 0x17 +#define CISTPL_JEDEC_C 0x18 +#define CISTPL_JEDEC_A 0x19 +#define CISTPL_CONFIG 0x1a +#define CISTPL_CFTABLE_ENTRY 0x1b +#define CISTPL_DEVICE_OC 0x1c +#define CISTPL_DEVICE_OA 0x1d +#define CISTPL_DEVICE_GEO 0x1e +#define CISTPL_DEVICE_GEO_A 0x1f +#define CISTPL_MANFID 0x20 +#define CISTPL_FUNCID 0x21 +#define CISTPL_FUNCE 0x22 +#define CISTPL_SWIL 0x23 +#define CISTPL_END 0xff + +/* FUNCID */ + +#define CISTPL_FUNCID_MULTI 0x00 +#define CISTPL_FUNCID_MEMORY 0x01 +#define CISTPL_FUNCID_SERIAL 0x02 +#define CISTPL_FUNCID_PARALLEL 0x03 +#define CISTPL_FUNCID_FIXED 0x04 +#define CISTPL_FUNCID_VIDEO 0x05 +#define CISTPL_FUNCID_NETWORK 0x06 +#define CISTPL_FUNCID_AIMS 0x07 +#define CISTPL_FUNCID_SCSI 0x08 + +#endif diff --git a/arch/m68k/include/asm/anchor.h b/arch/m68k/include/asm/anchor.h new file mode 100644 index 00000000000..871c0d5cfc3 --- /dev/null +++ b/arch/m68k/include/asm/anchor.h @@ -0,0 +1,112 @@ +/****************************************************************************/ + +/* + * anchor.h -- Anchor CO-MEM Lite PCI host bridge part. + * + * (C) Copyright 2000, Moreton Bay (www.moreton.com.au) + */ + +/****************************************************************************/ +#ifndef anchor_h +#define anchor_h +/****************************************************************************/ + +/* + * Define basic addressing info. + */ +#if defined(CONFIG_M5407C3) +#define COMEM_BASE 0xFFFF0000 /* Base of CO-MEM address space */ +#define COMEM_IRQ 25 /* IRQ of anchor part */ +#else +#define COMEM_BASE 0x80000000 /* Base of CO-MEM address space */ +#define COMEM_IRQ 25 /* IRQ of anchor part */ +#endif + +/****************************************************************************/ + +/* + * 4-byte registers of CO-MEM, so adjust register addresses for + * easy access. Handy macro for word access too. + */ +#define LREG(a) ((a) >> 2) +#define WREG(a) ((a) >> 1) + + +/* + * Define base addresses within CO-MEM Lite register address space. + */ +#define COMEM_I2O 0x0000 /* I2O registers */ +#define COMEM_OPREGS 0x0400 /* Operation registers */ +#define COMEM_PCIBUS 0x2000 /* Direct access to PCI bus */ +#define COMEM_SHMEM 0x4000 /* Shared memory region */ + +#define COMEM_SHMEMSIZE 0x4000 /* Size of shared memory */ + + +/* + * Define CO-MEM Registers. + */ +#define COMEM_I2OHISR 0x0030 /* I2O host interrupt status */ +#define COMEM_I2OHIMR 0x0034 /* I2O host interrupt mask */ +#define COMEM_I2OLISR 0x0038 /* I2O local interrupt status */ +#define COMEM_I2OLIMR 0x003c /* I2O local interrupt mask */ +#define COMEM_IBFPFIFO 0x0040 /* I2O inbound free/post FIFO */ +#define COMEM_OBPFFIFO 0x0044 /* I2O outbound post/free FIFO */ +#define COMEM_IBPFFIFO 0x0048 /* I2O inbound post/free FIFO */ +#define COMEM_OBFPFIFO 0x004c /* I2O outbound free/post FIFO */ + +#define COMEM_DAHBASE 0x0460 /* Direct access base address */ + +#define COMEM_NVCMD 0x04a0 /* I2C serial command */ +#define COMEM_NVREAD 0x04a4 /* I2C serial read */ +#define COMEM_NVSTAT 0x04a8 /* I2C status */ + +#define COMEM_DMALBASE 0x04b0 /* DMA local base address */ +#define COMEM_DMAHBASE 0x04b4 /* DMA host base address */ +#define COMEM_DMASIZE 0x04b8 /* DMA size */ +#define COMEM_DMACTL 0x04bc /* DMA control */ + +#define COMEM_HCTL 0x04e0 /* Host control */ +#define COMEM_HINT 0x04e4 /* Host interrupt control/status */ +#define COMEM_HLDATA 0x04e8 /* Host to local data mailbox */ +#define COMEM_LINT 0x04f4 /* Local interrupt contole status */ +#define COMEM_LHDATA 0x04f8 /* Local to host data mailbox */ + +#define COMEM_LBUSCFG 0x04fc /* Local bus configuration */ + + +/* + * Commands and flags for use with Direct Access Register. + */ +#define COMEM_DA_IACK 0x00000000 /* Interrupt acknowledge (read) */ +#define COMEM_DA_SPCL 0x00000010 /* Special cycle (write) */ +#define COMEM_DA_MEMRD 0x00000004 /* Memory read cycle */ +#define COMEM_DA_MEMWR 0x00000004 /* Memory write cycle */ +#define COMEM_DA_IORD 0x00000002 /* I/O read cycle */ +#define COMEM_DA_IOWR 0x00000002 /* I/O write cycle */ +#define COMEM_DA_CFGRD 0x00000006 /* Configuration read cycle */ +#define COMEM_DA_CFGWR 0x00000006 /* Configuration write cycle */ + +#define COMEM_DA_ADDR(a) ((a) & 0xffffe000) + +#define COMEM_DA_OFFSET(a) ((a) & 0x00001fff) + + +/* + * The PCI bus will be limited in what slots will actually be used. + * Define valid device numbers for different boards. + */ +#if defined(CONFIG_M5407C3) +#define COMEM_MINDEV 14 /* Minimum valid DEVICE */ +#define COMEM_MAXDEV 14 /* Maximum valid DEVICE */ +#define COMEM_BRIDGEDEV 15 /* Slot bridge is in */ +#else +#define COMEM_MINDEV 0 /* Minimum valid DEVICE */ +#define COMEM_MAXDEV 3 /* Maximum valid DEVICE */ +#endif + +#define COMEM_MAXPCI (COMEM_MAXDEV+1) /* Maximum PCI devices */ + + +/****************************************************************************/ +#endif /* anchor_h */ diff --git a/arch/m68k/include/asm/apollodma.h b/arch/m68k/include/asm/apollodma.h new file mode 100644 index 00000000000..954adc851ad --- /dev/null +++ b/arch/m68k/include/asm/apollodma.h @@ -0,0 +1,248 @@ +/* + * linux/include/asm/dma.h: Defines for using and allocating dma channels. + * Written by Hennus Bergman, 1992. + * High DMA channel support & info by Hannu Savolainen + * and John Boyd, Nov. 1992. + */ + +#ifndef _ASM_APOLLO_DMA_H +#define _ASM_APOLLO_DMA_H + +#include /* need byte IO */ +#include /* And spinlocks */ +#include + + +#define dma_outb(val,addr) (*((volatile unsigned char *)(addr+IO_BASE)) = (val)) +#define dma_inb(addr) (*((volatile unsigned char *)(addr+IO_BASE))) + +/* + * NOTES about DMA transfers: + * + * controller 1: channels 0-3, byte operations, ports 00-1F + * controller 2: channels 4-7, word operations, ports C0-DF + * + * - ALL registers are 8 bits only, regardless of transfer size + * - channel 4 is not used - cascades 1 into 2. + * - channels 0-3 are byte - addresses/counts are for physical bytes + * - channels 5-7 are word - addresses/counts are for physical words + * - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries + * - transfer count loaded to registers is 1 less than actual count + * - controller 2 offsets are all even (2x offsets for controller 1) + * - page registers for 5-7 don't use data bit 0, represent 128K pages + * - page registers for 0-3 use bit 0, represent 64K pages + * + * DMA transfers are limited to the lower 16MB of _physical_ memory. + * Note that addresses loaded into registers must be _physical_ addresses, + * not logical addresses (which may differ if paging is active). + * + * Address mapping for channels 0-3: + * + * A23 ... A16 A15 ... A8 A7 ... A0 (Physical addresses) + * | ... | | ... | | ... | + * | ... | | ... | | ... | + * | ... | | ... | | ... | + * P7 ... P0 A7 ... A0 A7 ... A0 + * | Page | Addr MSB | Addr LSB | (DMA registers) + * + * Address mapping for channels 5-7: + * + * A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0 (Physical addresses) + * | ... | \ \ ... \ \ \ ... \ \ + * | ... | \ \ ... \ \ \ ... \ (not used) + * | ... | \ \ ... \ \ \ ... \ + * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0 + * | Page | Addr MSB | Addr LSB | (DMA registers) + * + * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses + * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at + * the hardware level, so odd-byte transfers aren't possible). + * + * Transfer count (_not # bytes_) is limited to 64K, represented as actual + * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more, + * and up to 128K bytes may be transferred on channels 5-7 in one operation. + * + */ + +#define MAX_DMA_CHANNELS 8 + +/* The maximum address that we can perform a DMA transfer to on this platform */#define MAX_DMA_ADDRESS (PAGE_OFFSET+0x1000000) + +/* 8237 DMA controllers */ +#define IO_DMA1_BASE 0x10C00 /* 8 bit slave DMA, channels 0..3 */ +#define IO_DMA2_BASE 0x10D00 /* 16 bit master DMA, ch 4(=slave input)..7 */ + +/* DMA controller registers */ +#define DMA1_CMD_REG (IO_DMA1_BASE+0x08) /* command register (w) */ +#define DMA1_STAT_REG (IO_DMA1_BASE+0x08) /* status register (r) */ +#define DMA1_REQ_REG (IO_DMA1_BASE+0x09) /* request register (w) */ +#define DMA1_MASK_REG (IO_DMA1_BASE+0x0A) /* single-channel mask (w) */ +#define DMA1_MODE_REG (IO_DMA1_BASE+0x0B) /* mode register (w) */ +#define DMA1_CLEAR_FF_REG (IO_DMA1_BASE+0x0C) /* clear pointer flip-flop (w) */ +#define DMA1_TEMP_REG (IO_DMA1_BASE+0x0D) /* Temporary Register (r) */ +#define DMA1_RESET_REG (IO_DMA1_BASE+0x0D) /* Master Clear (w) */ +#define DMA1_CLR_MASK_REG (IO_DMA1_BASE+0x0E) /* Clear Mask */ +#define DMA1_MASK_ALL_REG (IO_DMA1_BASE+0x0F) /* all-channels mask (w) */ + +#define DMA2_CMD_REG (IO_DMA2_BASE+0x10) /* command register (w) */ +#define DMA2_STAT_REG (IO_DMA2_BASE+0x10) /* status register (r) */ +#define DMA2_REQ_REG (IO_DMA2_BASE+0x12) /* request register (w) */ +#define DMA2_MASK_REG (IO_DMA2_BASE+0x14) /* single-channel mask (w) */ +#define DMA2_MODE_REG (IO_DMA2_BASE+0x16) /* mode register (w) */ +#define DMA2_CLEAR_FF_REG (IO_DMA2_BASE+0x18) /* clear pointer flip-flop (w) */ +#define DMA2_TEMP_REG (IO_DMA2_BASE+0x1A) /* Temporary Register (r) */ +#define DMA2_RESET_REG (IO_DMA2_BASE+0x1A) /* Master Clear (w) */ +#define DMA2_CLR_MASK_REG (IO_DMA2_BASE+0x1C) /* Clear Mask */ +#define DMA2_MASK_ALL_REG (IO_DMA2_BASE+0x1E) /* all-channels mask (w) */ + +#define DMA_ADDR_0 (IO_DMA1_BASE+0x00) /* DMA address registers */ +#define DMA_ADDR_1 (IO_DMA1_BASE+0x02) +#define DMA_ADDR_2 (IO_DMA1_BASE+0x04) +#define DMA_ADDR_3 (IO_DMA1_BASE+0x06) +#define DMA_ADDR_4 (IO_DMA2_BASE+0x00) +#define DMA_ADDR_5 (IO_DMA2_BASE+0x04) +#define DMA_ADDR_6 (IO_DMA2_BASE+0x08) +#define DMA_ADDR_7 (IO_DMA2_BASE+0x0C) + +#define DMA_CNT_0 (IO_DMA1_BASE+0x01) /* DMA count registers */ +#define DMA_CNT_1 (IO_DMA1_BASE+0x03) +#define DMA_CNT_2 (IO_DMA1_BASE+0x05) +#define DMA_CNT_3 (IO_DMA1_BASE+0x07) +#define DMA_CNT_4 (IO_DMA2_BASE+0x02) +#define DMA_CNT_5 (IO_DMA2_BASE+0x06) +#define DMA_CNT_6 (IO_DMA2_BASE+0x0A) +#define DMA_CNT_7 (IO_DMA2_BASE+0x0E) + +#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */ +#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */ +#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ + +#define DMA_AUTOINIT 0x10 + +#define DMA_8BIT 0 +#define DMA_16BIT 1 +#define DMA_BUSMASTER 2 + +extern spinlock_t dma_spin_lock; + +static __inline__ unsigned long claim_dma_lock(void) +{ + unsigned long flags; + spin_lock_irqsave(&dma_spin_lock, flags); + return flags; +} + +static __inline__ void release_dma_lock(unsigned long flags) +{ + spin_unlock_irqrestore(&dma_spin_lock, flags); +} + +/* enable/disable a specific DMA channel */ +static __inline__ void enable_dma(unsigned int dmanr) +{ + if (dmanr<=3) + dma_outb(dmanr, DMA1_MASK_REG); + else + dma_outb(dmanr & 3, DMA2_MASK_REG); +} + +static __inline__ void disable_dma(unsigned int dmanr) +{ + if (dmanr<=3) + dma_outb(dmanr | 4, DMA1_MASK_REG); + else + dma_outb((dmanr & 3) | 4, DMA2_MASK_REG); +} + +/* Clear the 'DMA Pointer Flip Flop'. + * Write 0 for LSB/MSB, 1 for MSB/LSB access. + * Use this once to initialize the FF to a known state. + * After that, keep track of it. :-) + * --- In order to do that, the DMA routines below should --- + * --- only be used while holding the DMA lock ! --- + */ +static __inline__ void clear_dma_ff(unsigned int dmanr) +{ + if (dmanr<=3) + dma_outb(0, DMA1_CLEAR_FF_REG); + else + dma_outb(0, DMA2_CLEAR_FF_REG); +} + +/* set mode (above) for a specific DMA channel */ +static __inline__ void set_dma_mode(unsigned int dmanr, char mode) +{ + if (dmanr<=3) + dma_outb(mode | dmanr, DMA1_MODE_REG); + else + dma_outb(mode | (dmanr&3), DMA2_MODE_REG); +} + +/* Set transfer address & page bits for specific DMA channel. + * Assumes dma flipflop is clear. + */ +static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) +{ + if (dmanr <= 3) { + dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); + dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); + } else { + dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); + dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); + } +} + + +/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for + * a specific DMA channel. + * You must ensure the parameters are valid. + * NOTE: from a manual: "the number of transfers is one more + * than the initial word count"! This is taken into account. + * Assumes dma flip-flop is clear. + * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7. + */ +static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) +{ + count--; + if (dmanr <= 3) { + dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); + dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); + } else { + dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); + dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); + } +} + + +/* Get DMA residue count. After a DMA transfer, this + * should return zero. Reading this while a DMA transfer is + * still in progress will return unpredictable results. + * If called before the channel has been used, it may return 1. + * Otherwise, it returns the number of _bytes_ left to transfer. + * + * Assumes DMA flip-flop is clear. + */ +static __inline__ int get_dma_residue(unsigned int dmanr) +{ + unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE + : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE; + + /* using short to get 16-bit wrap around */ + unsigned short count; + + count = 1 + dma_inb(io_port); + count += dma_inb(io_port) << 8; + + return (dmanr<=3)? count : (count<<1); +} + + +/* These are in kernel/dma.c: */ +extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ +extern void free_dma(unsigned int dmanr); /* release it again */ + +/* These are in arch/m68k/apollo/dma.c: */ +extern unsigned short dma_map_page(unsigned long phys_addr,int count,int type); +extern void dma_unmap_page(unsigned short dma_addr); + +#endif /* _ASM_APOLLO_DMA_H */ diff --git a/arch/m68k/include/asm/apollohw.h b/arch/m68k/include/asm/apollohw.h new file mode 100644 index 00000000000..a1373b9aa28 --- /dev/null +++ b/arch/m68k/include/asm/apollohw.h @@ -0,0 +1,108 @@ +/* apollohw.h : some structures to access apollo HW */ + +#ifndef _ASMm68k_APOLLOHW_H_ +#define _ASMm68k_APOLLOHW_H_ + +#include + +/* + apollo models +*/ + +extern u_long apollo_model; + +#define APOLLO_UNKNOWN (0) +#define APOLLO_DN3000 (1) +#define APOLLO_DN3010 (2) +#define APOLLO_DN3500 (3) +#define APOLLO_DN4000 (4) +#define APOLLO_DN4500 (5) + +/* + see scn2681 data sheet for more info. + member names are read_write. +*/ + +#define DECLARE_2681_FIELD(x) unsigned char x; unsigned char dummy##x + +struct SCN2681 { + + DECLARE_2681_FIELD(mra); + DECLARE_2681_FIELD(sra_csra); + DECLARE_2681_FIELD(BRGtest_cra); + DECLARE_2681_FIELD(rhra_thra); + DECLARE_2681_FIELD(ipcr_acr); + DECLARE_2681_FIELD(isr_imr); + DECLARE_2681_FIELD(ctu_ctur); + DECLARE_2681_FIELD(ctl_ctlr); + DECLARE_2681_FIELD(mrb); + DECLARE_2681_FIELD(srb_csrb); + DECLARE_2681_FIELD(tst_crb); + DECLARE_2681_FIELD(rhrb_thrb); + DECLARE_2681_FIELD(reserved); + DECLARE_2681_FIELD(ip_opcr); + DECLARE_2681_FIELD(startCnt_setOutBit); + DECLARE_2681_FIELD(stopCnt_resetOutBit); + +}; + +#if 0 +struct mc146818 { + + unsigned int second1:4, second2:4, alarm_second1:4, alarm_second2:4, + minute1:4, minute2:4, alarm_minute1:4, alarm_minute2:4; + unsigned int hours1:4, hours2:4, alarm_hours1:4, alarm_hours2:4, + day_of_week1:4, day_of_week2:4, day_of_month1:4, day_of_month2:4; + unsigned int month1:4, month2:4, year1:4, year2:4, :16; + +}; +#endif + +struct mc146818 { + unsigned char second, alarm_second; + unsigned char minute, alarm_minute; + unsigned char hours, alarm_hours; + unsigned char day_of_week, day_of_month; + unsigned char month, year; +}; + + +#define IO_BASE 0x80000000 + +extern u_long sio01_physaddr; +extern u_long sio23_physaddr; +extern u_long rtc_physaddr; +extern u_long pica_physaddr; +extern u_long picb_physaddr; +extern u_long cpuctrl_physaddr; +extern u_long timer_physaddr; + +#define SAU7_SIO01_PHYSADDR 0x10400 +#define SAU7_SIO23_PHYSADDR 0x10500 +#define SAU7_RTC_PHYSADDR 0x10900 +#define SAU7_PICA 0x11000 +#define SAU7_PICB 0x11100 +#define SAU7_CPUCTRL 0x10100 +#define SAU7_TIMER 0x010800 + +#define SAU8_SIO01_PHYSADDR 0x8400 +#define SAU8_RTC_PHYSADDR 0x8900 +#define SAU8_PICA 0x9400 +#define SAU8_PICB 0x9500 +#define SAU8_CPUCTRL 0x8100 +#define SAU8_TIMER 0x8800 + +#define sio01 ((*(volatile struct SCN2681 *)(IO_BASE + sio01_physaddr))) +#define sio23 ((*(volatile struct SCN2681 *)(IO_BASE + sio23_physaddr))) +#define rtc (((volatile struct mc146818 *)(IO_BASE + rtc_physaddr))) +#define cpuctrl (*(volatile unsigned int *)(IO_BASE + cpuctrl_physaddr)) +#define pica (IO_BASE + pica_physaddr) +#define picb (IO_BASE + picb_physaddr) +#define timer (IO_BASE + timer_physaddr) +#define addr_xlat_map ((unsigned short *)(IO_BASE + 0x17000)) + +#define isaIO2mem(x) (((((x) & 0x3f8) << 7) | (((x) & 0xfc00) >> 6) | ((x) & 0x7)) + 0x40000 + IO_BASE) + +#define IRQ_APOLLO IRQ_USER + +#endif diff --git a/arch/m68k/include/asm/atafd.h b/arch/m68k/include/asm/atafd.h new file mode 100644 index 00000000000..8456889ee7d --- /dev/null +++ b/arch/m68k/include/asm/atafd.h @@ -0,0 +1,12 @@ +#ifndef _ASM_M68K_FD_H +#define _ASM_M68K_FD_H + +/* Definitions for the Atari Floppy driver */ + +struct atari_format_descr { + int track; /* to be formatted */ + int head; /* "" "" */ + int sect_offset; /* offset of first sector */ +}; + +#endif diff --git a/arch/m68k/include/asm/atafdreg.h b/arch/m68k/include/asm/atafdreg.h new file mode 100644 index 00000000000..bbf80949fd9 --- /dev/null +++ b/arch/m68k/include/asm/atafdreg.h @@ -0,0 +1,79 @@ +#ifndef _LINUX_FDREG_H +#define _LINUX_FDREG_H + +/* +** WD1772 stuff + */ + +/* register codes */ + +#define FDCSELREG_STP (0x80) /* command/status register */ +#define FDCSELREG_TRA (0x82) /* track register */ +#define FDCSELREG_SEC (0x84) /* sector register */ +#define FDCSELREG_DTA (0x86) /* data register */ + +/* register names for FDC_READ/WRITE macros */ + +#define FDCREG_CMD 0 +#define FDCREG_STATUS 0 +#define FDCREG_TRACK 2 +#define FDCREG_SECTOR 4 +#define FDCREG_DATA 6 + +/* command opcodes */ + +#define FDCCMD_RESTORE (0x00) /* - */ +#define FDCCMD_SEEK (0x10) /* | */ +#define FDCCMD_STEP (0x20) /* | TYP 1 Commands */ +#define FDCCMD_STIN (0x40) /* | */ +#define FDCCMD_STOT (0x60) /* - */ +#define FDCCMD_RDSEC (0x80) /* - TYP 2 Commands */ +#define FDCCMD_WRSEC (0xa0) /* - " */ +#define FDCCMD_RDADR (0xc0) /* - */ +#define FDCCMD_RDTRA (0xe0) /* | TYP 3 Commands */ +#define FDCCMD_WRTRA (0xf0) /* - */ +#define FDCCMD_FORCI (0xd0) /* - TYP 4 Command */ + +/* command modifier bits */ + +#define FDCCMDADD_SR6 (0x00) /* step rate settings */ +#define FDCCMDADD_SR12 (0x01) +#define FDCCMDADD_SR2 (0x02) +#define FDCCMDADD_SR3 (0x03) +#define FDCCMDADD_V (0x04) /* verify */ +#define FDCCMDADD_H (0x08) /* wait for spin-up */ +#define FDCCMDADD_U (0x10) /* update track register */ +#define FDCCMDADD_M (0x10) /* multiple sector access */ +#define FDCCMDADD_E (0x04) /* head settling flag */ +#define FDCCMDADD_P (0x02) /* precompensation off */ +#define FDCCMDADD_A0 (0x01) /* DAM flag */ + +/* status register bits */ + +#define FDCSTAT_MOTORON (0x80) /* motor on */ +#define FDCSTAT_WPROT (0x40) /* write protected (FDCCMD_WR*) */ +#define FDCSTAT_SPINUP (0x20) /* motor speed stable (Type I) */ +#define FDCSTAT_DELDAM (0x20) /* sector has deleted DAM (Type II+III) */ +#define FDCSTAT_RECNF (0x10) /* record not found */ +#define FDCSTAT_CRC (0x08) /* CRC error */ +#define FDCSTAT_TR00 (0x04) /* Track 00 flag (Type I) */ +#define FDCSTAT_LOST (0x04) /* Lost Data (Type II+III) */ +#define FDCSTAT_IDX (0x02) /* Index status (Type I) */ +#define FDCSTAT_DRQ (0x02) /* DRQ status (Type II+III) */ +#define FDCSTAT_BUSY (0x01) /* FDC is busy */ + + +/* PSG Port A Bit Nr 0 .. Side Sel .. 0 -> Side 1 1 -> Side 2 */ +#define DSKSIDE (0x01) + +#define DSKDRVNONE (0x06) +#define DSKDRV0 (0x02) +#define DSKDRV1 (0x04) + +/* step rates */ +#define FDCSTEP_6 0x00 +#define FDCSTEP_12 0x01 +#define FDCSTEP_2 0x02 +#define FDCSTEP_3 0x03 + +#endif diff --git a/arch/m68k/include/asm/atari_joystick.h b/arch/m68k/include/asm/atari_joystick.h new file mode 100644 index 00000000000..93be7da9f2c --- /dev/null +++ b/arch/m68k/include/asm/atari_joystick.h @@ -0,0 +1,22 @@ +#ifndef _LINUX_ATARI_JOYSTICK_H +#define _LINUX_ATARI_JOYSTICK_H + +/* + * linux/include/linux/atari_joystick.h + * header file for Atari Joystick driver + * by Robert de Vries (robert@and.nl) on 19Jul93 + */ + +void atari_joystick_interrupt(char*); +int atari_joystick_init(void); +extern int atari_mouse_buttons; + +struct joystick_status { + char fire; + char dir; + int ready; + int active; + wait_queue_head_t wait; +}; + +#endif diff --git a/arch/m68k/include/asm/atari_stdma.h b/arch/m68k/include/asm/atari_stdma.h new file mode 100644 index 00000000000..8e389b7fa70 --- /dev/null +++ b/arch/m68k/include/asm/atari_stdma.h @@ -0,0 +1,22 @@ + +#ifndef _atari_stdma_h +#define _atari_stdma_h + + +#include + + +/***************************** Prototypes *****************************/ + +void stdma_lock(irq_handler_t handler, void *data); +void stdma_release( void ); +int stdma_others_waiting( void ); +int stdma_islocked( void ); +void *stdma_locked_by( void ); +void stdma_init( void ); + +/************************* End of Prototypes **************************/ + + + +#endif /* _atari_stdma_h */ diff --git a/arch/m68k/include/asm/atari_stram.h b/arch/m68k/include/asm/atari_stram.h new file mode 100644 index 00000000000..7546d13963b --- /dev/null +++ b/arch/m68k/include/asm/atari_stram.h @@ -0,0 +1,17 @@ +#ifndef _M68K_ATARI_STRAM_H +#define _M68K_ATARI_STRAM_H + +/* + * Functions for Atari ST-RAM management + */ + +/* public interface */ +void *atari_stram_alloc(long size, const char *owner); +void atari_stram_free(void *); + +/* functions called internally by other parts of the kernel */ +void atari_stram_init(void); +void atari_stram_reserve_pages(void *start_mem); +void atari_stram_mem_init_hook (void); + +#endif /*_M68K_ATARI_STRAM_H */ diff --git a/arch/m68k/include/asm/atarihw.h b/arch/m68k/include/asm/atarihw.h new file mode 100644 index 00000000000..1412b4ab202 --- /dev/null +++ b/arch/m68k/include/asm/atarihw.h @@ -0,0 +1,807 @@ +/* +** linux/atarihw.h -- This header defines some macros and pointers for +** the various Atari custom hardware registers. +** +** Copyright 1994 by Björn Brauel +** +** 5/1/94 Roman Hodek: +** Added definitions for TT specific chips. +** +** 1996-09-13 lars brinkhoff : +** Finally added definitions for the matrix/codec and the DSP56001 host +** interface. +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +*/ + +#ifndef _LINUX_ATARIHW_H_ +#define _LINUX_ATARIHW_H_ + +#include +#include +#include + +extern u_long atari_mch_cookie; +extern u_long atari_mch_type; +extern u_long atari_switches; +extern int atari_rtc_year_offset; +extern int atari_dont_touch_floppy_select; + +/* convenience macros for testing machine type */ +#define MACH_IS_ST ((atari_mch_cookie >> 16) == ATARI_MCH_ST) +#define MACH_IS_STE ((atari_mch_cookie >> 16) == ATARI_MCH_STE && \ + (atari_mch_cookie & 0xffff) == 0) +#define MACH_IS_MSTE ((atari_mch_cookie >> 16) == ATARI_MCH_STE && \ + (atari_mch_cookie & 0xffff) == 0x10) +#define MACH_IS_TT ((atari_mch_cookie >> 16) == ATARI_MCH_TT) +#define MACH_IS_FALCON ((atari_mch_cookie >> 16) == ATARI_MCH_FALCON) +#define MACH_IS_MEDUSA (atari_mch_type == ATARI_MACH_MEDUSA) +#define MACH_IS_AB40 (atari_mch_type == ATARI_MACH_AB40) + +/* values for atari_switches */ +#define ATARI_SWITCH_IKBD 0x01 +#define ATARI_SWITCH_MIDI 0x02 +#define ATARI_SWITCH_SND6 0x04 +#define ATARI_SWITCH_SND7 0x08 +#define ATARI_SWITCH_OVSC_SHIFT 16 +#define ATARI_SWITCH_OVSC_IKBD (ATARI_SWITCH_IKBD << ATARI_SWITCH_OVSC_SHIFT) +#define ATARI_SWITCH_OVSC_MIDI (ATARI_SWITCH_MIDI << ATARI_SWITCH_OVSC_SHIFT) +#define ATARI_SWITCH_OVSC_SND6 (ATARI_SWITCH_SND6 << ATARI_SWITCH_OVSC_SHIFT) +#define ATARI_SWITCH_OVSC_SND7 (ATARI_SWITCH_SND7 << ATARI_SWITCH_OVSC_SHIFT) +#define ATARI_SWITCH_OVSC_MASK 0xffff0000 + +/* + * Define several Hardware-Chips for indication so that for the ATARI we do + * no longer decide whether it is a Falcon or other machine . It's just + * important what hardware the machine uses + */ + +/* ++roman 08/08/95: rewritten from ORing constants to a C bitfield */ + +#define ATARIHW_DECLARE(name) unsigned name : 1 +#define ATARIHW_SET(name) (atari_hw_present.name = 1) +#define ATARIHW_PRESENT(name) (atari_hw_present.name) + +struct atari_hw_present { + /* video hardware */ + ATARIHW_DECLARE(STND_SHIFTER); /* ST-Shifter - no base low ! */ + ATARIHW_DECLARE(EXTD_SHIFTER); /* STe-Shifter - 24 bit address */ + ATARIHW_DECLARE(TT_SHIFTER); /* TT-Shifter */ + ATARIHW_DECLARE(VIDEL_SHIFTER); /* Falcon-Shifter */ + /* sound hardware */ + ATARIHW_DECLARE(YM_2149); /* Yamaha YM 2149 */ + ATARIHW_DECLARE(PCM_8BIT); /* PCM-Sound in STe-ATARI */ + ATARIHW_DECLARE(CODEC); /* CODEC Sound (Falcon) */ + /* disk storage interfaces */ + ATARIHW_DECLARE(TT_SCSI); /* Directly mapped NCR5380 */ + ATARIHW_DECLARE(ST_SCSI); /* NCR5380 via ST-DMA (Falcon) */ + ATARIHW_DECLARE(ACSI); /* Standard ACSI like in STs */ + ATARIHW_DECLARE(IDE); /* IDE Interface */ + ATARIHW_DECLARE(FDCSPEED); /* 8/16 MHz switch for FDC */ + /* other I/O hardware */ + ATARIHW_DECLARE(ST_MFP); /* The ST-MFP (there should be no Atari + without it... but who knows?) */ + ATARIHW_DECLARE(TT_MFP); /* 2nd MFP */ + ATARIHW_DECLARE(SCC); /* Serial Communications Contr. */ + ATARIHW_DECLARE(ST_ESCC); /* SCC Z83230 in an ST */ + ATARIHW_DECLARE(ANALOG_JOY); /* Paddle Interface for STe + and Falcon */ + ATARIHW_DECLARE(MICROWIRE); /* Microwire Interface */ + /* DMA */ + ATARIHW_DECLARE(STND_DMA); /* 24 Bit limited ST-DMA */ + ATARIHW_DECLARE(EXTD_DMA); /* 32 Bit ST-DMA */ + ATARIHW_DECLARE(SCSI_DMA); /* DMA for the NCR5380 */ + ATARIHW_DECLARE(SCC_DMA); /* DMA for the SCC */ + /* real time clocks */ + ATARIHW_DECLARE(TT_CLK); /* TT compatible clock chip */ + ATARIHW_DECLARE(MSTE_CLK); /* Mega ST(E) clock chip */ + /* supporting hardware */ + ATARIHW_DECLARE(SCU); /* System Control Unit */ + ATARIHW_DECLARE(BLITTER); /* Blitter */ + ATARIHW_DECLARE(VME); /* VME Bus */ + ATARIHW_DECLARE(DSP56K); /* DSP56k processor in Falcon */ +}; + +extern struct atari_hw_present atari_hw_present; + + +/* Reading the MFP port register gives a machine independent delay, since the + * MFP always has a 8 MHz clock. This avoids problems with the varying length + * of nops on various machines. Somebody claimed that the tstb takes 600 ns. + */ +#define MFPDELAY() \ + __asm__ __volatile__ ( "tstb %0" : : "m" (mfp.par_dt_reg) : "cc" ); + +/* Do cache push/invalidate for DMA read/write. This function obeys the + * snooping on some machines (Medusa) and processors: The Medusa itself can + * snoop, but only the '040 can source data from its cache to DMA writes i.e., + * reads from memory). Both '040 and '060 invalidate cache entries on snooped + * DMA reads (i.e., writes to memory). + */ + + +#define atari_readb raw_inb +#define atari_writeb raw_outb + +#define atari_inb_p raw_inb +#define atari_outb_p raw_outb + + + +#include +#include + +static inline void dma_cache_maintenance( unsigned long paddr, + unsigned long len, + int writeflag ) + +{ + if (writeflag) { + if (!MACH_IS_MEDUSA || CPU_IS_060) + cache_push( paddr, len ); + } + else { + if (!MACH_IS_MEDUSA) + cache_clear( paddr, len ); + } +} + + +/* +** Shifter + */ +#define ST_LOW 0 +#define ST_MID 1 +#define ST_HIGH 2 +#define TT_LOW 7 +#define TT_MID 4 +#define TT_HIGH 6 + +#define SHF_BAS (0xffff8200) +struct SHIFTER + { + u_char pad1; + u_char bas_hi; + u_char pad2; + u_char bas_md; + u_char pad3; + u_char volatile vcounthi; + u_char pad4; + u_char volatile vcountmid; + u_char pad5; + u_char volatile vcountlow; + u_char volatile syncmode; + u_char pad6; + u_char pad7; + u_char bas_lo; + }; +# define shifter ((*(volatile struct SHIFTER *)SHF_BAS)) + +#define SHF_FBAS (0xffff820e) +struct SHIFTER_F030 + { + u_short off_next; + u_short scn_width; + }; +# define shifter_f030 ((*(volatile struct SHIFTER_F030 *)SHF_FBAS)) + + +#define SHF_TBAS (0xffff8200) +struct SHIFTER_TT { + u_char char_dummy0; + u_char bas_hi; /* video mem base addr, high and mid byte */ + u_char char_dummy1; + u_char bas_md; + u_char char_dummy2; + u_char vcount_hi; /* pointer to currently displayed byte */ + u_char char_dummy3; + u_char vcount_md; + u_char char_dummy4; + u_char vcount_lo; + u_short st_sync; /* ST compatible sync mode register, unused */ + u_char char_dummy5; + u_char bas_lo; /* video mem addr, low byte */ + u_char char_dummy6[2+3*16]; + /* $ffff8240: */ + u_short color_reg[16]; /* 16 color registers */ + u_char st_shiftmode; /* ST compatible shift mode register, unused */ + u_char char_dummy7; + u_short tt_shiftmode; /* TT shift mode register */ + + +}; +#define shifter_tt ((*(volatile struct SHIFTER_TT *)SHF_TBAS)) + +/* values for shifter_tt->tt_shiftmode */ +#define TT_SHIFTER_STLOW 0x0000 +#define TT_SHIFTER_STMID 0x0100 +#define TT_SHIFTER_STHIGH 0x0200 +#define TT_SHIFTER_TTLOW 0x0700 +#define TT_SHIFTER_TTMID 0x0400 +#define TT_SHIFTER_TTHIGH 0x0600 +#define TT_SHIFTER_MODEMASK 0x0700 +#define TT_SHIFTER_NUMMODE 0x0008 +#define TT_SHIFTER_PALETTE_MASK 0x000f +#define TT_SHIFTER_GRAYMODE 0x1000 + +/* 256 TT palette registers */ +#define TT_PALETTE_BASE (0xffff8400) +#define tt_palette ((volatile u_short *)TT_PALETTE_BASE) + +#define TT_PALETTE_RED_MASK 0x0f00 +#define TT_PALETTE_GREEN_MASK 0x00f0 +#define TT_PALETTE_BLUE_MASK 0x000f + +/* +** Falcon030 VIDEL Video Controller +** for description see File 'linux\tools\atari\hardware.txt + */ +#define f030_col ((u_long *) 0xffff9800) +#define f030_xreg ((u_short*) 0xffff8282) +#define f030_yreg ((u_short*) 0xffff82a2) +#define f030_creg ((u_short*) 0xffff82c0) +#define f030_sreg ((u_short*) 0xffff8260) +#define f030_mreg ((u_short*) 0xffff820a) +#define f030_linewidth ((u_short*) 0xffff820e) +#define f030_hscroll ((u_char*) 0xffff8265) + +#define VIDEL_BAS (0xffff8260) +struct VIDEL { + u_short st_shift; + u_short pad1; + u_char xoffset_s; + u_char xoffset; + u_short f_shift; + u_char pad2[0x1a]; + u_short hht; + u_short hbb; + u_short hbe; + u_short hdb; + u_short hde; + u_short hss; + u_char pad3[0x14]; + u_short vft; + u_short vbb; + u_short vbe; + u_short vdb; + u_short vde; + u_short vss; + u_char pad4[0x12]; + u_short control; + u_short mode; +}; +#define videl ((*(volatile struct VIDEL *)VIDEL_BAS)) + +/* +** DMA/WD1772 Disk Controller + */ + +#define FWD_BAS (0xffff8604) +struct DMA_WD + { + u_short fdc_acces_seccount; + u_short dma_mode_status; + u_char dma_vhi; /* Some extended ST-DMAs can handle 32 bit addresses */ + u_char dma_hi; + u_char char_dummy2; + u_char dma_md; + u_char char_dummy3; + u_char dma_lo; + u_short fdc_speed; + }; +# define dma_wd ((*(volatile struct DMA_WD *)FWD_BAS)) +/* alias */ +#define st_dma dma_wd +/* The two highest bytes of an extended DMA as a short; this is a must + * for the Medusa. + */ +#define st_dma_ext_dmahi (*((volatile unsigned short *)0xffff8608)) + +/* +** YM2149 Sound Chip +** access in bytes + */ + +#define YM_BAS (0xffff8800) +struct SOUND_YM + { + u_char rd_data_reg_sel; + u_char char_dummy1; + u_char wd_data; + }; +#define sound_ym ((*(volatile struct SOUND_YM *)YM_BAS)) + +/* TT SCSI DMA */ + +#define TT_SCSI_DMA_BAS (0xffff8700) +struct TT_DMA { + u_char char_dummy0; + u_char dma_addr_hi; + u_char char_dummy1; + u_char dma_addr_hmd; + u_char char_dummy2; + u_char dma_addr_lmd; + u_char char_dummy3; + u_char dma_addr_lo; + u_char char_dummy4; + u_char dma_cnt_hi; + u_char char_dummy5; + u_char dma_cnt_hmd; + u_char char_dummy6; + u_char dma_cnt_lmd; + u_char char_dummy7; + u_char dma_cnt_lo; + u_long dma_restdata; + u_short dma_ctrl; +}; +#define tt_scsi_dma ((*(volatile struct TT_DMA *)TT_SCSI_DMA_BAS)) + +/* TT SCSI Controller 5380 */ + +#define TT_5380_BAS (0xffff8781) +struct TT_5380 { + u_char scsi_data; + u_char char_dummy1; + u_char scsi_icr; + u_char char_dummy2; + u_char scsi_mode; + u_char char_dummy3; + u_char scsi_tcr; + u_char char_dummy4; + u_char scsi_idstat; + u_char char_dummy5; + u_char scsi_dmastat; + u_char char_dummy6; + u_char scsi_targrcv; + u_char char_dummy7; + u_char scsi_inircv; +}; +#define tt_scsi ((*(volatile struct TT_5380 *)TT_5380_BAS)) +#define tt_scsi_regp ((volatile char *)TT_5380_BAS) + + +/* +** Falcon DMA Sound Subsystem + */ + +#define MATRIX_BASE (0xffff8930) +struct MATRIX +{ + u_short source; + u_short destination; + u_char external_frequency_divider; + u_char internal_frequency_divider; +}; +#define falcon_matrix (*(volatile struct MATRIX *)MATRIX_BASE) + +#define CODEC_BASE (0xffff8936) +struct CODEC +{ + u_char tracks; + u_char input_source; +#define CODEC_SOURCE_ADC 1 +#define CODEC_SOURCE_MATRIX 2 + u_char adc_source; +#define ADC_SOURCE_RIGHT_PSG 1 +#define ADC_SOURCE_LEFT_PSG 2 + u_char gain; +#define CODEC_GAIN_RIGHT 0x0f +#define CODEC_GAIN_LEFT 0xf0 + u_char attenuation; +#define CODEC_ATTENUATION_RIGHT 0x0f +#define CODEC_ATTENUATION_LEFT 0xf0 + u_char unused1; + u_char status; +#define CODEC_OVERFLOW_RIGHT 1 +#define CODEC_OVERFLOW_LEFT 2 + u_char unused2, unused3, unused4, unused5; + u_char gpio_directions; +#define GPIO_IN 0 +#define GPIO_OUT 1 + u_char unused6; + u_char gpio_data; +}; +#define falcon_codec (*(volatile struct CODEC *)CODEC_BASE) + +/* +** Falcon Blitter +*/ + +#define BLT_BAS (0xffff8a00) + +struct BLITTER + { + u_short halftone[16]; + u_short src_x_inc; + u_short src_y_inc; + u_long src_address; + u_short endmask1; + u_short endmask2; + u_short endmask3; + u_short dst_x_inc; + u_short dst_y_inc; + u_long dst_address; + u_short wd_per_line; + u_short ln_per_bb; + u_short hlf_op_reg; + u_short log_op_reg; + u_short lin_nm_reg; + u_short skew_reg; + }; +# define blitter ((*(volatile struct BLITTER *)BLT_BAS)) + + +/* +** SCC Z8530 + */ + +#define SCC_BAS (0xffff8c81) +struct SCC + { + u_char cha_a_ctrl; + u_char char_dummy1; + u_char cha_a_data; + u_char char_dummy2; + u_char cha_b_ctrl; + u_char char_dummy3; + u_char cha_b_data; + }; +# define scc ((*(volatile struct SCC*)SCC_BAS)) + +/* The ESCC (Z85230) in an Atari ST. The channels are reversed! */ +# define st_escc ((*(volatile struct SCC*)0xfffffa31)) +# define st_escc_dsr ((*(volatile char *)0xfffffa39)) + +/* TT SCC DMA Controller (same chip as SCSI DMA) */ + +#define TT_SCC_DMA_BAS (0xffff8c00) +#define tt_scc_dma ((*(volatile struct TT_DMA *)TT_SCC_DMA_BAS)) + +/* +** VIDEL Palette Register + */ + +#define FPL_BAS (0xffff9800) +struct VIDEL_PALETTE + { + u_long reg[256]; + }; +# define videl_palette ((*(volatile struct VIDEL_PALETTE*)FPL_BAS)) + + +/* +** Falcon DSP Host Interface + */ + +#define DSP56K_HOST_INTERFACE_BASE (0xffffa200) +struct DSP56K_HOST_INTERFACE { + u_char icr; +#define DSP56K_ICR_RREQ 0x01 +#define DSP56K_ICR_TREQ 0x02 +#define DSP56K_ICR_HF0 0x08 +#define DSP56K_ICR_HF1 0x10 +#define DSP56K_ICR_HM0 0x20 +#define DSP56K_ICR_HM1 0x40 +#define DSP56K_ICR_INIT 0x80 + + u_char cvr; +#define DSP56K_CVR_HV_MASK 0x1f +#define DSP56K_CVR_HC 0x80 + + u_char isr; +#define DSP56K_ISR_RXDF 0x01 +#define DSP56K_ISR_TXDE 0x02 +#define DSP56K_ISR_TRDY 0x04 +#define DSP56K_ISR_HF2 0x08 +#define DSP56K_ISR_HF3 0x10 +#define DSP56K_ISR_DMA 0x40 +#define DSP56K_ISR_HREQ 0x80 + + u_char ivr; + + union { + u_char b[4]; + u_short w[2]; + u_long l; + } data; +}; +#define dsp56k_host_interface ((*(volatile struct DSP56K_HOST_INTERFACE *)DSP56K_HOST_INTERFACE_BASE)) + +/* +** MFP 68901 + */ + +#define MFP_BAS (0xfffffa01) +struct MFP + { + u_char par_dt_reg; + u_char char_dummy1; + u_char active_edge; + u_char char_dummy2; + u_char data_dir; + u_char char_dummy3; + u_char int_en_a; + u_char char_dummy4; + u_char int_en_b; + u_char char_dummy5; + u_char int_pn_a; + u_char char_dummy6; + u_char int_pn_b; + u_char char_dummy7; + u_char int_sv_a; + u_char char_dummy8; + u_char int_sv_b; + u_char char_dummy9; + u_char int_mk_a; + u_char char_dummy10; + u_char int_mk_b; + u_char char_dummy11; + u_char vec_adr; + u_char char_dummy12; + u_char tim_ct_a; + u_char char_dummy13; + u_char tim_ct_b; + u_char char_dummy14; + u_char tim_ct_cd; + u_char char_dummy15; + u_char tim_dt_a; + u_char char_dummy16; + u_char tim_dt_b; + u_char char_dummy17; + u_char tim_dt_c; + u_char char_dummy18; + u_char tim_dt_d; + u_char char_dummy19; + u_char sync_char; + u_char char_dummy20; + u_char usart_ctr; + u_char char_dummy21; + u_char rcv_stat; + u_char char_dummy22; + u_char trn_stat; + u_char char_dummy23; + u_char usart_dta; + }; +# define mfp ((*(volatile struct MFP*)MFP_BAS)) + +/* TT's second MFP */ + +#define TT_MFP_BAS (0xfffffa81) +# define tt_mfp ((*(volatile struct MFP*)TT_MFP_BAS)) + + +/* TT System Control Unit */ + +#define TT_SCU_BAS (0xffff8e01) +struct TT_SCU { + u_char sys_mask; + u_char char_dummy1; + u_char sys_stat; + u_char char_dummy2; + u_char softint; + u_char char_dummy3; + u_char vmeint; + u_char char_dummy4; + u_char gp_reg1; + u_char char_dummy5; + u_char gp_reg2; + u_char char_dummy6; + u_char vme_mask; + u_char char_dummy7; + u_char vme_stat; +}; +#define tt_scu ((*(volatile struct TT_SCU *)TT_SCU_BAS)) + +/* TT real time clock */ + +#define TT_RTC_BAS (0xffff8961) +struct TT_RTC { + u_char regsel; + u_char dummy; + u_char data; +}; +#define tt_rtc ((*(volatile struct TT_RTC *)TT_RTC_BAS)) + + +/* +** ACIA 6850 + */ +/* constants for the ACIA registers */ + +/* baudrate selection and reset (Baudrate = clock/factor) */ +#define ACIA_DIV1 0 +#define ACIA_DIV16 1 +#define ACIA_DIV64 2 +#define ACIA_RESET 3 + +/* character format */ +#define ACIA_D7E2S (0<<2) /* 7 data, even parity, 2 stop */ +#define ACIA_D7O2S (1<<2) /* 7 data, odd parity, 2 stop */ +#define ACIA_D7E1S (2<<2) /* 7 data, even parity, 1 stop */ +#define ACIA_D7O1S (3<<2) /* 7 data, odd parity, 1 stop */ +#define ACIA_D8N2S (4<<2) /* 8 data, no parity, 2 stop */ +#define ACIA_D8N1S (5<<2) /* 8 data, no parity, 1 stop */ +#define ACIA_D8E1S (6<<2) /* 8 data, even parity, 1 stop */ +#define ACIA_D8O1S (7<<2) /* 8 data, odd parity, 1 stop */ + +/* transmit control */ +#define ACIA_RLTID (0<<5) /* RTS low, TxINT disabled */ +#define ACIA_RLTIE (1<<5) /* RTS low, TxINT enabled */ +#define ACIA_RHTID (2<<5) /* RTS high, TxINT disabled */ +#define ACIA_RLTIDSB (3<<5) /* RTS low, TxINT disabled, send break */ + +/* receive control */ +#define ACIA_RID (0<<7) /* RxINT disabled */ +#define ACIA_RIE (1<<7) /* RxINT enabled */ + +/* status fields of the ACIA */ +#define ACIA_RDRF 1 /* Receive Data Register Full */ +#define ACIA_TDRE (1<<1) /* Transmit Data Register Empty */ +#define ACIA_DCD (1<<2) /* Data Carrier Detect */ +#define ACIA_CTS (1<<3) /* Clear To Send */ +#define ACIA_FE (1<<4) /* Framing Error */ +#define ACIA_OVRN (1<<5) /* Receiver Overrun */ +#define ACIA_PE (1<<6) /* Parity Error */ +#define ACIA_IRQ (1<<7) /* Interrupt Request */ + +#define ACIA_BAS (0xfffffc00) +struct ACIA + { + u_char key_ctrl; + u_char char_dummy1; + u_char key_data; + u_char char_dummy2; + u_char mid_ctrl; + u_char char_dummy3; + u_char mid_data; + }; +# define acia ((*(volatile struct ACIA*)ACIA_BAS)) + +#define TT_DMASND_BAS (0xffff8900) +struct TT_DMASND { + u_char int_ctrl; /* Falcon: Interrupt control */ + u_char ctrl; + u_char pad2; + u_char bas_hi; + u_char pad3; + u_char bas_mid; + u_char pad4; + u_char bas_low; + u_char pad5; + u_char addr_hi; + u_char pad6; + u_char addr_mid; + u_char pad7; + u_char addr_low; + u_char pad8; + u_char end_hi; + u_char pad9; + u_char end_mid; + u_char pad10; + u_char end_low; + u_char pad11[12]; + u_char track_select; /* Falcon */ + u_char mode; + u_char pad12[14]; + /* Falcon only: */ + u_short cbar_src; + u_short cbar_dst; + u_char ext_div; + u_char int_div; + u_char rec_track_select; + u_char dac_src; + u_char adc_src; + u_char input_gain; + u_short output_atten; +}; +# define tt_dmasnd ((*(volatile struct TT_DMASND *)TT_DMASND_BAS)) + +#define DMASND_MFP_INT_REPLAY 0x01 +#define DMASND_MFP_INT_RECORD 0x02 +#define DMASND_TIMERA_INT_REPLAY 0x04 +#define DMASND_TIMERA_INT_RECORD 0x08 + +#define DMASND_CTRL_OFF 0x00 +#define DMASND_CTRL_ON 0x01 +#define DMASND_CTRL_REPEAT 0x02 +#define DMASND_CTRL_RECORD_ON 0x10 +#define DMASND_CTRL_RECORD_OFF 0x00 +#define DMASND_CTRL_RECORD_REPEAT 0x20 +#define DMASND_CTRL_SELECT_REPLAY 0x00 +#define DMASND_CTRL_SELECT_RECORD 0x80 +#define DMASND_MODE_MONO 0x80 +#define DMASND_MODE_STEREO 0x00 +#define DMASND_MODE_8BIT 0x00 +#define DMASND_MODE_16BIT 0x40 /* Falcon only */ +#define DMASND_MODE_6KHZ 0x00 /* Falcon: mute */ +#define DMASND_MODE_12KHZ 0x01 +#define DMASND_MODE_25KHZ 0x02 +#define DMASND_MODE_50KHZ 0x03 + + +#define DMASNDSetBase(bufstart) \ + do { \ + tt_dmasnd.bas_hi = (unsigned char)(((bufstart) & 0xff0000) >> 16); \ + tt_dmasnd.bas_mid = (unsigned char)(((bufstart) & 0x00ff00) >> 8); \ + tt_dmasnd.bas_low = (unsigned char) ((bufstart) & 0x0000ff); \ + } while( 0 ) + +#define DMASNDGetAdr() ((tt_dmasnd.addr_hi << 16) + \ + (tt_dmasnd.addr_mid << 8) + \ + (tt_dmasnd.addr_low)) + +#define DMASNDSetEnd(bufend) \ + do { \ + tt_dmasnd.end_hi = (unsigned char)(((bufend) & 0xff0000) >> 16); \ + tt_dmasnd.end_mid = (unsigned char)(((bufend) & 0x00ff00) >> 8); \ + tt_dmasnd.end_low = (unsigned char) ((bufend) & 0x0000ff); \ + } while( 0 ) + + +#define TT_MICROWIRE_BAS (0xffff8922) +struct TT_MICROWIRE { + u_short data; + u_short mask; +}; +# define tt_microwire ((*(volatile struct TT_MICROWIRE *)TT_MICROWIRE_BAS)) + +#define MW_LM1992_ADDR 0x0400 + +#define MW_LM1992_VOLUME(dB) \ + (0x0c0 | ((dB) < -80 ? 0 : (dB) > 0 ? 40 : (((dB) + 80) / 2))) +#define MW_LM1992_BALLEFT(dB) \ + (0x140 | ((dB) < -40 ? 0 : (dB) > 0 ? 20 : (((dB) + 40) / 2))) +#define MW_LM1992_BALRIGHT(dB) \ + (0x100 | ((dB) < -40 ? 0 : (dB) > 0 ? 20 : (((dB) + 40) / 2))) +#define MW_LM1992_TREBLE(dB) \ + (0x080 | ((dB) < -12 ? 0 : (dB) > 12 ? 12 : (((dB) / 2) + 6))) +#define MW_LM1992_BASS(dB) \ + (0x040 | ((dB) < -12 ? 0 : (dB) > 12 ? 12 : (((dB) / 2) + 6))) + +#define MW_LM1992_PSG_LOW 0x000 +#define MW_LM1992_PSG_HIGH 0x001 +#define MW_LM1992_PSG_OFF 0x002 + +#define MSTE_RTC_BAS (0xfffffc21) + +struct MSTE_RTC { + u_char sec_ones; + u_char dummy1; + u_char sec_tens; + u_char dummy2; + u_char min_ones; + u_char dummy3; + u_char min_tens; + u_char dummy4; + u_char hr_ones; + u_char dummy5; + u_char hr_tens; + u_char dummy6; + u_char weekday; + u_char dummy7; + u_char day_ones; + u_char dummy8; + u_char day_tens; + u_char dummy9; + u_char mon_ones; + u_char dummy10; + u_char mon_tens; + u_char dummy11; + u_char year_ones; + u_char dummy12; + u_char year_tens; + u_char dummy13; + u_char mode; + u_char dummy14; + u_char test; + u_char dummy15; + u_char reset; +}; + +#define mste_rtc ((*(volatile struct MSTE_RTC *)MSTE_RTC_BAS)) + +#endif /* linux/atarihw.h */ + diff --git a/arch/m68k/include/asm/atariints.h b/arch/m68k/include/asm/atariints.h new file mode 100644 index 00000000000..5748e99f4e2 --- /dev/null +++ b/arch/m68k/include/asm/atariints.h @@ -0,0 +1,204 @@ +/* +** atariints.h -- Atari Linux interrupt handling structs and prototypes +** +** Copyright 1994 by Björn Brauel +** +** 5/2/94 Roman Hodek: +** TT interrupt definitions added. +** +** 12/02/96: (Roman) +** Adapted to new int handling scheme (see ataints.c); revised numbering +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +*/ + +#ifndef _LINUX_ATARIINTS_H_ +#define _LINUX_ATARIINTS_H_ + +#include +#include + +/* +** Atari Interrupt sources. +** +*/ + +#define STMFP_SOURCE_BASE 8 +#define TTMFP_SOURCE_BASE 24 +#define SCC_SOURCE_BASE 40 +#define VME_SOURCE_BASE 56 +#define VME_MAX_SOURCES 16 + +#define NUM_ATARI_SOURCES (VME_SOURCE_BASE+VME_MAX_SOURCES-STMFP_SOURCE_BASE) + +/* convert vector number to int source number */ +#define IRQ_VECTOR_TO_SOURCE(v) ((v) - ((v) < 0x20 ? 0x18 : (0x40-8))) + +/* convert irq_handler index to vector number */ +#define IRQ_SOURCE_TO_VECTOR(i) ((i) + ((i) < 8 ? 0x18 : (0x40-8))) + +/* interrupt service types */ +#define IRQ_TYPE_SLOW 0 +#define IRQ_TYPE_FAST 1 +#define IRQ_TYPE_PRIO 2 + +/* ST-MFP interrupts */ +#define IRQ_MFP_BUSY (8) +#define IRQ_MFP_DCD (9) +#define IRQ_MFP_CTS (10) +#define IRQ_MFP_GPU (11) +#define IRQ_MFP_TIMD (12) +#define IRQ_MFP_TIMC (13) +#define IRQ_MFP_ACIA (14) +#define IRQ_MFP_FDC (15) +#define IRQ_MFP_ACSI IRQ_MFP_FDC +#define IRQ_MFP_FSCSI IRQ_MFP_FDC +#define IRQ_MFP_IDE IRQ_MFP_FDC +#define IRQ_MFP_TIMB (16) +#define IRQ_MFP_SERERR (17) +#define IRQ_MFP_SEREMPT (18) +#define IRQ_MFP_RECERR (19) +#define IRQ_MFP_RECFULL (20) +#define IRQ_MFP_TIMA (21) +#define IRQ_MFP_RI (22) +#define IRQ_MFP_MMD (23) + +/* TT-MFP interrupts */ +#define IRQ_TT_MFP_IO0 (24) +#define IRQ_TT_MFP_IO1 (25) +#define IRQ_TT_MFP_SCC (26) +#define IRQ_TT_MFP_RI (27) +#define IRQ_TT_MFP_TIMD (28) +#define IRQ_TT_MFP_TIMC (29) +#define IRQ_TT_MFP_DRVRDY (30) +#define IRQ_TT_MFP_SCSIDMA (31) +#define IRQ_TT_MFP_TIMB (32) +#define IRQ_TT_MFP_SERERR (33) +#define IRQ_TT_MFP_SEREMPT (34) +#define IRQ_TT_MFP_RECERR (35) +#define IRQ_TT_MFP_RECFULL (36) +#define IRQ_TT_MFP_TIMA (37) +#define IRQ_TT_MFP_RTC (38) +#define IRQ_TT_MFP_SCSI (39) + +/* SCC interrupts */ +#define IRQ_SCCB_TX (40) +#define IRQ_SCCB_STAT (42) +#define IRQ_SCCB_RX (44) +#define IRQ_SCCB_SPCOND (46) +#define IRQ_SCCA_TX (48) +#define IRQ_SCCA_STAT (50) +#define IRQ_SCCA_RX (52) +#define IRQ_SCCA_SPCOND (54) + + +#define INT_CLK 24576 /* CLK while int_clk =2.456MHz and divide = 100 */ +#define INT_TICKS 246 /* to make sched_time = 99.902... HZ */ + + +#define MFP_ENABLE 0 +#define MFP_PENDING 1 +#define MFP_SERVICE 2 +#define MFP_MASK 3 + +/* Utility functions for setting/clearing bits in the interrupt registers of + * the MFP. 'type' should be constant, if 'irq' is constant, too, code size is + * reduced. set_mfp_bit() is nonsense for PENDING and SERVICE registers. */ + +static inline int get_mfp_bit( unsigned irq, int type ) + +{ unsigned char mask, *reg; + + mask = 1 << (irq & 7); + reg = (unsigned char *)&mfp.int_en_a + type*4 + + ((irq & 8) >> 2) + (((irq-8) & 16) << 3); + return( *reg & mask ); +} + +static inline void set_mfp_bit( unsigned irq, int type ) + +{ unsigned char mask, *reg; + + mask = 1 << (irq & 7); + reg = (unsigned char *)&mfp.int_en_a + type*4 + + ((irq & 8) >> 2) + (((irq-8) & 16) << 3); + __asm__ __volatile__ ( "orb %0,%1" + : : "di" (mask), "m" (*reg) : "memory" ); +} + +static inline void clear_mfp_bit( unsigned irq, int type ) + +{ unsigned char mask, *reg; + + mask = ~(1 << (irq & 7)); + reg = (unsigned char *)&mfp.int_en_a + type*4 + + ((irq & 8) >> 2) + (((irq-8) & 16) << 3); + if (type == MFP_PENDING || type == MFP_SERVICE) + __asm__ __volatile__ ( "moveb %0,%1" + : : "di" (mask), "m" (*reg) : "memory" ); + else + __asm__ __volatile__ ( "andb %0,%1" + : : "di" (mask), "m" (*reg) : "memory" ); +} + +/* + * {en,dis}able_irq have the usual semantics of temporary blocking the + * interrupt, but not loosing requests that happen between disabling and + * enabling. This is done with the MFP mask registers. + */ + +static inline void atari_enable_irq( unsigned irq ) + +{ + if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; + set_mfp_bit( irq, MFP_MASK ); +} + +static inline void atari_disable_irq( unsigned irq ) + +{ + if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; + clear_mfp_bit( irq, MFP_MASK ); +} + +/* + * In opposite to {en,dis}able_irq, requests between turn{off,on}_irq are not + * "stored" + */ + +static inline void atari_turnon_irq( unsigned irq ) + +{ + if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; + set_mfp_bit( irq, MFP_ENABLE ); +} + +static inline void atari_turnoff_irq( unsigned irq ) + +{ + if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; + clear_mfp_bit( irq, MFP_ENABLE ); + clear_mfp_bit( irq, MFP_PENDING ); +} + +static inline void atari_clear_pending_irq( unsigned irq ) + +{ + if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; + clear_mfp_bit( irq, MFP_PENDING ); +} + +static inline int atari_irq_pending( unsigned irq ) + +{ + if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return( 0 ); + return( get_mfp_bit( irq, MFP_PENDING ) ); +} + +unsigned long atari_register_vme_int( void ); +void atari_unregister_vme_int( unsigned long ); + +#endif /* linux/atariints.h */ diff --git a/arch/m68k/include/asm/atarikb.h b/arch/m68k/include/asm/atarikb.h new file mode 100644 index 00000000000..546e7da5804 --- /dev/null +++ b/arch/m68k/include/asm/atarikb.h @@ -0,0 +1,46 @@ +/* +** atarikb.h -- This header contains the prototypes of functions of +** the intelligent keyboard of the Atari needed by the +** mouse and joystick drivers. +** +** Copyright 1994 by Robert de Vries +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +** Created: 20 Feb 1994 by Robert de Vries +*/ + +#ifndef _LINUX_ATARIKB_H +#define _LINUX_ATARIKB_H + +void ikbd_write(const char *, int); +void ikbd_mouse_button_action(int mode); +void ikbd_mouse_rel_pos(void); +void ikbd_mouse_abs_pos(int xmax, int ymax); +void ikbd_mouse_kbd_mode(int dx, int dy); +void ikbd_mouse_thresh(int x, int y); +void ikbd_mouse_scale(int x, int y); +void ikbd_mouse_pos_get(int *x, int *y); +void ikbd_mouse_pos_set(int x, int y); +void ikbd_mouse_y0_bot(void); +void ikbd_mouse_y0_top(void); +void ikbd_mouse_disable(void); +void ikbd_joystick_event_on(void); +void ikbd_joystick_event_off(void); +void ikbd_joystick_get_state(void); +void ikbd_joystick_disable(void); + +/* Hook for MIDI serial driver */ +extern void (*atari_MIDI_interrupt_hook) (void); +/* Hook for mouse driver */ +extern void (*atari_mouse_interrupt_hook) (char *); +/* Hook for keyboard inputdev driver */ +extern void (*atari_input_keyboard_interrupt_hook) (unsigned char, char); +/* Hook for mouse inputdev driver */ +extern void (*atari_input_mouse_interrupt_hook) (char *); + +int atari_keyb_init(void); + +#endif /* _LINUX_ATARIKB_H */ diff --git a/arch/m68k/include/asm/atomic.h b/arch/m68k/include/asm/atomic.h new file mode 100644 index 00000000000..8d29145ebb2 --- /dev/null +++ b/arch/m68k/include/asm/atomic.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "atomic_no.h" +#else +#include "atomic_mm.h" +#endif diff --git a/arch/m68k/include/asm/atomic_mm.h b/arch/m68k/include/asm/atomic_mm.h new file mode 100644 index 00000000000..eb0ab9d4ee7 --- /dev/null +++ b/arch/m68k/include/asm/atomic_mm.h @@ -0,0 +1,196 @@ +#ifndef __ARCH_M68K_ATOMIC__ +#define __ARCH_M68K_ATOMIC__ + +#include +#include + +/* + * Atomic operations that C can't guarantee us. Useful for + * resource counting etc.. + */ + +/* + * We do not have SMP m68k systems, so we don't have to deal with that. + */ + +#define ATOMIC_INIT(i) { (i) } + +#define atomic_read(v) ((v)->counter) +#define atomic_set(v, i) (((v)->counter) = i) + +static inline void atomic_add(int i, atomic_t *v) +{ + __asm__ __volatile__("addl %1,%0" : "+m" (*v) : "id" (i)); +} + +static inline void atomic_sub(int i, atomic_t *v) +{ + __asm__ __volatile__("subl %1,%0" : "+m" (*v) : "id" (i)); +} + +static inline void atomic_inc(atomic_t *v) +{ + __asm__ __volatile__("addql #1,%0" : "+m" (*v)); +} + +static inline void atomic_dec(atomic_t *v) +{ + __asm__ __volatile__("subql #1,%0" : "+m" (*v)); +} + +static inline int atomic_dec_and_test(atomic_t *v) +{ + char c; + __asm__ __volatile__("subql #1,%1; seq %0" : "=d" (c), "+m" (*v)); + return c != 0; +} + +static inline int atomic_inc_and_test(atomic_t *v) +{ + char c; + __asm__ __volatile__("addql #1,%1; seq %0" : "=d" (c), "+m" (*v)); + return c != 0; +} + +#ifdef CONFIG_RMW_INSNS + +static inline int atomic_add_return(int i, atomic_t *v) +{ + int t, tmp; + + __asm__ __volatile__( + "1: movel %2,%1\n" + " addl %3,%1\n" + " casl %2,%1,%0\n" + " jne 1b" + : "+m" (*v), "=&d" (t), "=&d" (tmp) + : "g" (i), "2" (atomic_read(v))); + return t; +} + +static inline int atomic_sub_return(int i, atomic_t *v) +{ + int t, tmp; + + __asm__ __volatile__( + "1: movel %2,%1\n" + " subl %3,%1\n" + " casl %2,%1,%0\n" + " jne 1b" + : "+m" (*v), "=&d" (t), "=&d" (tmp) + : "g" (i), "2" (atomic_read(v))); + return t; +} + +#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) +#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) + +#else /* !CONFIG_RMW_INSNS */ + +static inline int atomic_add_return(int i, atomic_t * v) +{ + unsigned long flags; + int t; + + local_irq_save(flags); + t = atomic_read(v); + t += i; + atomic_set(v, t); + local_irq_restore(flags); + + return t; +} + +static inline int atomic_sub_return(int i, atomic_t * v) +{ + unsigned long flags; + int t; + + local_irq_save(flags); + t = atomic_read(v); + t -= i; + atomic_set(v, t); + local_irq_restore(flags); + + return t; +} + +static inline int atomic_cmpxchg(atomic_t *v, int old, int new) +{ + unsigned long flags; + int prev; + + local_irq_save(flags); + prev = atomic_read(v); + if (prev == old) + atomic_set(v, new); + local_irq_restore(flags); + return prev; +} + +static inline int atomic_xchg(atomic_t *v, int new) +{ + unsigned long flags; + int prev; + + local_irq_save(flags); + prev = atomic_read(v); + atomic_set(v, new); + local_irq_restore(flags); + return prev; +} + +#endif /* !CONFIG_RMW_INSNS */ + +#define atomic_dec_return(v) atomic_sub_return(1, (v)) +#define atomic_inc_return(v) atomic_add_return(1, (v)) + +static inline int atomic_sub_and_test(int i, atomic_t *v) +{ + char c; + __asm__ __volatile__("subl %2,%1; seq %0" : "=d" (c), "+m" (*v): "g" (i)); + return c != 0; +} + +static inline int atomic_add_negative(int i, atomic_t *v) +{ + char c; + __asm__ __volatile__("addl %2,%1; smi %0" : "=d" (c), "+m" (*v): "g" (i)); + return c != 0; +} + +static inline void atomic_clear_mask(unsigned long mask, unsigned long *v) +{ + __asm__ __volatile__("andl %1,%0" : "+m" (*v) : "id" (~(mask))); +} + +static inline void atomic_set_mask(unsigned long mask, unsigned long *v) +{ + __asm__ __volatile__("orl %1,%0" : "+m" (*v) : "id" (mask)); +} + +static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) +{ + int c, old; + c = atomic_read(v); + for (;;) { + if (unlikely(c == (u))) + break; + old = atomic_cmpxchg((v), c, c + (a)); + if (likely(old == c)) + break; + c = old; + } + return c != (u); +} + +#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) + +/* Atomic operations are already serializing */ +#define smp_mb__before_atomic_dec() barrier() +#define smp_mb__after_atomic_dec() barrier() +#define smp_mb__before_atomic_inc() barrier() +#define smp_mb__after_atomic_inc() barrier() + +#include +#endif /* __ARCH_M68K_ATOMIC __ */ diff --git a/arch/m68k/include/asm/atomic_no.h b/arch/m68k/include/asm/atomic_no.h new file mode 100644 index 00000000000..6bb674855a3 --- /dev/null +++ b/arch/m68k/include/asm/atomic_no.h @@ -0,0 +1,155 @@ +#ifndef __ARCH_M68KNOMMU_ATOMIC__ +#define __ARCH_M68KNOMMU_ATOMIC__ + +#include +#include + +/* + * Atomic operations that C can't guarantee us. Useful for + * resource counting etc.. + */ + +/* + * We do not have SMP m68k systems, so we don't have to deal with that. + */ + +#define ATOMIC_INIT(i) { (i) } + +#define atomic_read(v) ((v)->counter) +#define atomic_set(v, i) (((v)->counter) = i) + +static __inline__ void atomic_add(int i, atomic_t *v) +{ +#ifdef CONFIG_COLDFIRE + __asm__ __volatile__("addl %1,%0" : "+m" (*v) : "d" (i)); +#else + __asm__ __volatile__("addl %1,%0" : "+m" (*v) : "di" (i)); +#endif +} + +static __inline__ void atomic_sub(int i, atomic_t *v) +{ +#ifdef CONFIG_COLDFIRE + __asm__ __volatile__("subl %1,%0" : "+m" (*v) : "d" (i)); +#else + __asm__ __volatile__("subl %1,%0" : "+m" (*v) : "di" (i)); +#endif +} + +static __inline__ int atomic_sub_and_test(int i, atomic_t * v) +{ + char c; +#ifdef CONFIG_COLDFIRE + __asm__ __volatile__("subl %2,%1; seq %0" + : "=d" (c), "+m" (*v) + : "d" (i)); +#else + __asm__ __volatile__("subl %2,%1; seq %0" + : "=d" (c), "+m" (*v) + : "di" (i)); +#endif + return c != 0; +} + +static __inline__ void atomic_inc(volatile atomic_t *v) +{ + __asm__ __volatile__("addql #1,%0" : "+m" (*v)); +} + +/* + * atomic_inc_and_test - increment and test + * @v: pointer of type atomic_t + * + * Atomically increments @v by 1 + * and returns true if the result is zero, or false for all + * other cases. + */ + +static __inline__ int atomic_inc_and_test(volatile atomic_t *v) +{ + char c; + __asm__ __volatile__("addql #1,%1; seq %0" : "=d" (c), "+m" (*v)); + return c != 0; +} + +static __inline__ void atomic_dec(volatile atomic_t *v) +{ + __asm__ __volatile__("subql #1,%0" : "+m" (*v)); +} + +static __inline__ int atomic_dec_and_test(volatile atomic_t *v) +{ + char c; + __asm__ __volatile__("subql #1,%1; seq %0" : "=d" (c), "+m" (*v)); + return c != 0; +} + +static __inline__ void atomic_clear_mask(unsigned long mask, unsigned long *v) +{ + __asm__ __volatile__("andl %1,%0" : "+m" (*v) : "id" (~(mask))); +} + +static __inline__ void atomic_set_mask(unsigned long mask, unsigned long *v) +{ + __asm__ __volatile__("orl %1,%0" : "+m" (*v) : "id" (mask)); +} + +/* Atomic operations are already serializing */ +#define smp_mb__before_atomic_dec() barrier() +#define smp_mb__after_atomic_dec() barrier() +#define smp_mb__before_atomic_inc() barrier() +#define smp_mb__after_atomic_inc() barrier() + +static inline int atomic_add_return(int i, atomic_t * v) +{ + unsigned long temp, flags; + + local_irq_save(flags); + temp = *(long *)v; + temp += i; + *(long *)v = temp; + local_irq_restore(flags); + + return temp; +} + +#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) + +static inline int atomic_sub_return(int i, atomic_t * v) +{ + unsigned long temp, flags; + + local_irq_save(flags); + temp = *(long *)v; + temp -= i; + *(long *)v = temp; + local_irq_restore(flags); + + return temp; +} + +#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) +#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) + +static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) +{ + int c, old; + c = atomic_read(v); + for (;;) { + if (unlikely(c == (u))) + break; + old = atomic_cmpxchg((v), c, c + (a)); + if (likely(old == c)) + break; + c = old; + } + return c != (u); +} + +#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) + +#define atomic_dec_return(v) atomic_sub_return(1,(v)) +#define atomic_inc_return(v) atomic_add_return(1,(v)) + +#include +#endif /* __ARCH_M68KNOMMU_ATOMIC __ */ diff --git a/arch/m68k/include/asm/auxvec.h b/arch/m68k/include/asm/auxvec.h new file mode 100644 index 00000000000..844d6d52204 --- /dev/null +++ b/arch/m68k/include/asm/auxvec.h @@ -0,0 +1,4 @@ +#ifndef __ASMm68k_AUXVEC_H +#define __ASMm68k_AUXVEC_H + +#endif diff --git a/arch/m68k/include/asm/bitops.h b/arch/m68k/include/asm/bitops.h new file mode 100644 index 00000000000..ce163abddab --- /dev/null +++ b/arch/m68k/include/asm/bitops.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "bitops_no.h" +#else +#include "bitops_mm.h" +#endif diff --git a/arch/m68k/include/asm/bitops_mm.h b/arch/m68k/include/asm/bitops_mm.h new file mode 100644 index 00000000000..9bde784e7ba --- /dev/null +++ b/arch/m68k/include/asm/bitops_mm.h @@ -0,0 +1,464 @@ +#ifndef _M68K_BITOPS_H +#define _M68K_BITOPS_H +/* + * Copyright 1992, Linus Torvalds. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#ifndef _LINUX_BITOPS_H +#error only can be included directly +#endif + +#include + +/* + * Require 68020 or better. + * + * They use the standard big-endian m680x0 bit ordering. + */ + +#define test_and_set_bit(nr,vaddr) \ + (__builtin_constant_p(nr) ? \ + __constant_test_and_set_bit(nr, vaddr) : \ + __generic_test_and_set_bit(nr, vaddr)) + +#define __test_and_set_bit(nr,vaddr) test_and_set_bit(nr,vaddr) + +static inline int __constant_test_and_set_bit(int nr, unsigned long *vaddr) +{ + char *p = (char *)vaddr + (nr ^ 31) / 8; + char retval; + + __asm__ __volatile__ ("bset %2,%1; sne %0" + : "=d" (retval), "+m" (*p) + : "di" (nr & 7)); + + return retval; +} + +static inline int __generic_test_and_set_bit(int nr, unsigned long *vaddr) +{ + char retval; + + __asm__ __volatile__ ("bfset %2{%1:#1}; sne %0" + : "=d" (retval) : "d" (nr^31), "o" (*vaddr) : "memory"); + + return retval; +} + +#define set_bit(nr,vaddr) \ + (__builtin_constant_p(nr) ? \ + __constant_set_bit(nr, vaddr) : \ + __generic_set_bit(nr, vaddr)) + +#define __set_bit(nr,vaddr) set_bit(nr,vaddr) + +static inline void __constant_set_bit(int nr, volatile unsigned long *vaddr) +{ + char *p = (char *)vaddr + (nr ^ 31) / 8; + __asm__ __volatile__ ("bset %1,%0" + : "+m" (*p) : "di" (nr & 7)); +} + +static inline void __generic_set_bit(int nr, volatile unsigned long *vaddr) +{ + __asm__ __volatile__ ("bfset %1{%0:#1}" + : : "d" (nr^31), "o" (*vaddr) : "memory"); +} + +#define test_and_clear_bit(nr,vaddr) \ + (__builtin_constant_p(nr) ? \ + __constant_test_and_clear_bit(nr, vaddr) : \ + __generic_test_and_clear_bit(nr, vaddr)) + +#define __test_and_clear_bit(nr,vaddr) test_and_clear_bit(nr,vaddr) + +static inline int __constant_test_and_clear_bit(int nr, unsigned long *vaddr) +{ + char *p = (char *)vaddr + (nr ^ 31) / 8; + char retval; + + __asm__ __volatile__ ("bclr %2,%1; sne %0" + : "=d" (retval), "+m" (*p) + : "di" (nr & 7)); + + return retval; +} + +static inline int __generic_test_and_clear_bit(int nr, unsigned long *vaddr) +{ + char retval; + + __asm__ __volatile__ ("bfclr %2{%1:#1}; sne %0" + : "=d" (retval) : "d" (nr^31), "o" (*vaddr) : "memory"); + + return retval; +} + +/* + * clear_bit() doesn't provide any barrier for the compiler. + */ +#define smp_mb__before_clear_bit() barrier() +#define smp_mb__after_clear_bit() barrier() + +#define clear_bit(nr,vaddr) \ + (__builtin_constant_p(nr) ? \ + __constant_clear_bit(nr, vaddr) : \ + __generic_clear_bit(nr, vaddr)) +#define __clear_bit(nr,vaddr) clear_bit(nr,vaddr) + +static inline void __constant_clear_bit(int nr, volatile unsigned long *vaddr) +{ + char *p = (char *)vaddr + (nr ^ 31) / 8; + __asm__ __volatile__ ("bclr %1,%0" + : "+m" (*p) : "di" (nr & 7)); +} + +static inline void __generic_clear_bit(int nr, volatile unsigned long *vaddr) +{ + __asm__ __volatile__ ("bfclr %1{%0:#1}" + : : "d" (nr^31), "o" (*vaddr) : "memory"); +} + +#define test_and_change_bit(nr,vaddr) \ + (__builtin_constant_p(nr) ? \ + __constant_test_and_change_bit(nr, vaddr) : \ + __generic_test_and_change_bit(nr, vaddr)) + +#define __test_and_change_bit(nr,vaddr) test_and_change_bit(nr,vaddr) +#define __change_bit(nr,vaddr) change_bit(nr,vaddr) + +static inline int __constant_test_and_change_bit(int nr, unsigned long *vaddr) +{ + char *p = (char *)vaddr + (nr ^ 31) / 8; + char retval; + + __asm__ __volatile__ ("bchg %2,%1; sne %0" + : "=d" (retval), "+m" (*p) + : "di" (nr & 7)); + + return retval; +} + +static inline int __generic_test_and_change_bit(int nr, unsigned long *vaddr) +{ + char retval; + + __asm__ __volatile__ ("bfchg %2{%1:#1}; sne %0" + : "=d" (retval) : "d" (nr^31), "o" (*vaddr) : "memory"); + + return retval; +} + +#define change_bit(nr,vaddr) \ + (__builtin_constant_p(nr) ? \ + __constant_change_bit(nr, vaddr) : \ + __generic_change_bit(nr, vaddr)) + +static inline void __constant_change_bit(int nr, unsigned long *vaddr) +{ + char *p = (char *)vaddr + (nr ^ 31) / 8; + __asm__ __volatile__ ("bchg %1,%0" + : "+m" (*p) : "di" (nr & 7)); +} + +static inline void __generic_change_bit(int nr, unsigned long *vaddr) +{ + __asm__ __volatile__ ("bfchg %1{%0:#1}" + : : "d" (nr^31), "o" (*vaddr) : "memory"); +} + +static inline int test_bit(int nr, const unsigned long *vaddr) +{ + return (vaddr[nr >> 5] & (1UL << (nr & 31))) != 0; +} + +static inline int find_first_zero_bit(const unsigned long *vaddr, + unsigned size) +{ + const unsigned long *p = vaddr; + int res = 32; + unsigned long num; + + if (!size) + return 0; + + size = (size + 31) >> 5; + while (!(num = ~*p++)) { + if (!--size) + goto out; + } + + __asm__ __volatile__ ("bfffo %1{#0,#0},%0" + : "=d" (res) : "d" (num & -num)); + res ^= 31; +out: + return ((long)p - (long)vaddr - 4) * 8 + res; +} + +static inline int find_next_zero_bit(const unsigned long *vaddr, int size, + int offset) +{ + const unsigned long *p = vaddr + (offset >> 5); + int bit = offset & 31UL, res; + + if (offset >= size) + return size; + + if (bit) { + unsigned long num = ~*p++ & (~0UL << bit); + offset -= bit; + + /* Look for zero in first longword */ + __asm__ __volatile__ ("bfffo %1{#0,#0},%0" + : "=d" (res) : "d" (num & -num)); + if (res < 32) + return offset + (res ^ 31); + offset += 32; + } + /* No zero yet, search remaining full bytes for a zero */ + res = find_first_zero_bit(p, size - ((long)p - (long)vaddr) * 8); + return offset + res; +} + +static inline int find_first_bit(const unsigned long *vaddr, unsigned size) +{ + const unsigned long *p = vaddr; + int res = 32; + unsigned long num; + + if (!size) + return 0; + + size = (size + 31) >> 5; + while (!(num = *p++)) { + if (!--size) + goto out; + } + + __asm__ __volatile__ ("bfffo %1{#0,#0},%0" + : "=d" (res) : "d" (num & -num)); + res ^= 31; +out: + return ((long)p - (long)vaddr - 4) * 8 + res; +} + +static inline int find_next_bit(const unsigned long *vaddr, int size, + int offset) +{ + const unsigned long *p = vaddr + (offset >> 5); + int bit = offset & 31UL, res; + + if (offset >= size) + return size; + + if (bit) { + unsigned long num = *p++ & (~0UL << bit); + offset -= bit; + + /* Look for one in first longword */ + __asm__ __volatile__ ("bfffo %1{#0,#0},%0" + : "=d" (res) : "d" (num & -num)); + if (res < 32) + return offset + (res ^ 31); + offset += 32; + } + /* No one yet, search remaining full bytes for a one */ + res = find_first_bit(p, size - ((long)p - (long)vaddr) * 8); + return offset + res; +} + +/* + * ffz = Find First Zero in word. Undefined if no zero exists, + * so code should check against ~0UL first.. + */ +static inline unsigned long ffz(unsigned long word) +{ + int res; + + __asm__ __volatile__ ("bfffo %1{#0,#0},%0" + : "=d" (res) : "d" (~word & -~word)); + return res ^ 31; +} + +#ifdef __KERNEL__ + +/* + * ffs: find first bit set. This is defined the same way as + * the libc and compiler builtin ffs routines, therefore + * differs in spirit from the above ffz (man ffs). + */ + +static inline int ffs(int x) +{ + int cnt; + + asm ("bfffo %1{#0:#0},%0" : "=d" (cnt) : "dm" (x & -x)); + + return 32 - cnt; +} +#define __ffs(x) (ffs(x) - 1) + +/* + * fls: find last bit set. + */ + +static inline int fls(int x) +{ + int cnt; + + asm ("bfffo %1{#0,#0},%0" : "=d" (cnt) : "dm" (x)); + + return 32 - cnt; +} + +static inline int __fls(int x) +{ + return fls(x) - 1; +} + +#include +#include +#include +#include + +/* Bitmap functions for the minix filesystem */ + +static inline int minix_find_first_zero_bit(const void *vaddr, unsigned size) +{ + const unsigned short *p = vaddr, *addr = vaddr; + int res; + unsigned short num; + + if (!size) + return 0; + + size = (size >> 4) + ((size & 15) > 0); + while (*p++ == 0xffff) + { + if (--size == 0) + return (p - addr) << 4; + } + + num = ~*--p; + __asm__ __volatile__ ("bfffo %1{#16,#16},%0" + : "=d" (res) : "d" (num & -num)); + return ((p - addr) << 4) + (res ^ 31); +} + +#define minix_test_and_set_bit(nr, addr) __test_and_set_bit((nr) ^ 16, (unsigned long *)(addr)) +#define minix_set_bit(nr,addr) __set_bit((nr) ^ 16, (unsigned long *)(addr)) +#define minix_test_and_clear_bit(nr, addr) __test_and_clear_bit((nr) ^ 16, (unsigned long *)(addr)) + +static inline int minix_test_bit(int nr, const void *vaddr) +{ + const unsigned short *p = vaddr; + return (p[nr >> 4] & (1U << (nr & 15))) != 0; +} + +/* Bitmap functions for the ext2 filesystem. */ + +#define ext2_set_bit(nr, addr) __test_and_set_bit((nr) ^ 24, (unsigned long *)(addr)) +#define ext2_set_bit_atomic(lock, nr, addr) test_and_set_bit((nr) ^ 24, (unsigned long *)(addr)) +#define ext2_clear_bit(nr, addr) __test_and_clear_bit((nr) ^ 24, (unsigned long *)(addr)) +#define ext2_clear_bit_atomic(lock, nr, addr) test_and_clear_bit((nr) ^ 24, (unsigned long *)(addr)) + +static inline int ext2_test_bit(int nr, const void *vaddr) +{ + const unsigned char *p = vaddr; + return (p[nr >> 3] & (1U << (nr & 7))) != 0; +} + +static inline int ext2_find_first_zero_bit(const void *vaddr, unsigned size) +{ + const unsigned long *p = vaddr, *addr = vaddr; + int res; + + if (!size) + return 0; + + size = (size >> 5) + ((size & 31) > 0); + while (*p++ == ~0UL) + { + if (--size == 0) + return (p - addr) << 5; + } + + --p; + for (res = 0; res < 32; res++) + if (!ext2_test_bit (res, p)) + break; + return (p - addr) * 32 + res; +} + +static inline int ext2_find_next_zero_bit(const void *vaddr, unsigned size, + unsigned offset) +{ + const unsigned long *addr = vaddr; + const unsigned long *p = addr + (offset >> 5); + int bit = offset & 31UL, res; + + if (offset >= size) + return size; + + if (bit) { + /* Look for zero in first longword */ + for (res = bit; res < 32; res++) + if (!ext2_test_bit (res, p)) + return (p - addr) * 32 + res; + p++; + } + /* No zero yet, search remaining full bytes for a zero */ + res = ext2_find_first_zero_bit (p, size - 32 * (p - addr)); + return (p - addr) * 32 + res; +} + +static inline int ext2_find_first_bit(const void *vaddr, unsigned size) +{ + const unsigned long *p = vaddr, *addr = vaddr; + int res; + + if (!size) + return 0; + + size = (size >> 5) + ((size & 31) > 0); + while (*p++ == 0UL) { + if (--size == 0) + return (p - addr) << 5; + } + + --p; + for (res = 0; res < 32; res++) + if (ext2_test_bit(res, p)) + break; + return (p - addr) * 32 + res; +} + +static inline int ext2_find_next_bit(const void *vaddr, unsigned size, + unsigned offset) +{ + const unsigned long *addr = vaddr; + const unsigned long *p = addr + (offset >> 5); + int bit = offset & 31UL, res; + + if (offset >= size) + return size; + + if (bit) { + /* Look for one in first longword */ + for (res = bit; res < 32; res++) + if (ext2_test_bit(res, p)) + return (p - addr) * 32 + res; + p++; + } + /* No set bit yet, search remaining full bytes for a set bit */ + res = ext2_find_first_bit(p, size - 32 * (p - addr)); + return (p - addr) * 32 + res; +} + +#endif /* __KERNEL__ */ + +#endif /* _M68K_BITOPS_H */ diff --git a/arch/m68k/include/asm/bitops_no.h b/arch/m68k/include/asm/bitops_no.h new file mode 100644 index 00000000000..9d3cbe5fad1 --- /dev/null +++ b/arch/m68k/include/asm/bitops_no.h @@ -0,0 +1,337 @@ +#ifndef _M68KNOMMU_BITOPS_H +#define _M68KNOMMU_BITOPS_H + +/* + * Copyright 1992, Linus Torvalds. + */ + +#include +#include /* swab32 */ + +#ifdef __KERNEL__ + +#ifndef _LINUX_BITOPS_H +#error only can be included directly +#endif + +#if defined (__mcfisaaplus__) || defined (__mcfisac__) +static inline int ffs(unsigned int val) +{ + if (!val) + return 0; + + asm volatile( + "bitrev %0\n\t" + "ff1 %0\n\t" + : "=d" (val) + : "0" (val) + ); + val++; + return val; +} + +static inline int __ffs(unsigned int val) +{ + asm volatile( + "bitrev %0\n\t" + "ff1 %0\n\t" + : "=d" (val) + : "0" (val) + ); + return val; +} + +#else +#include +#include +#endif + +#include +#include + +static __inline__ void set_bit(int nr, volatile unsigned long * addr) +{ +#ifdef CONFIG_COLDFIRE + __asm__ __volatile__ ("lea %0,%%a0; bset %1,(%%a0)" + : "+m" (((volatile char *)addr)[(nr^31) >> 3]) + : "d" (nr) + : "%a0", "cc"); +#else + __asm__ __volatile__ ("bset %1,%0" + : "+m" (((volatile char *)addr)[(nr^31) >> 3]) + : "di" (nr) + : "cc"); +#endif +} + +#define __set_bit(nr, addr) set_bit(nr, addr) + +/* + * clear_bit() doesn't provide any barrier for the compiler. + */ +#define smp_mb__before_clear_bit() barrier() +#define smp_mb__after_clear_bit() barrier() + +static __inline__ void clear_bit(int nr, volatile unsigned long * addr) +{ +#ifdef CONFIG_COLDFIRE + __asm__ __volatile__ ("lea %0,%%a0; bclr %1,(%%a0)" + : "+m" (((volatile char *)addr)[(nr^31) >> 3]) + : "d" (nr) + : "%a0", "cc"); +#else + __asm__ __volatile__ ("bclr %1,%0" + : "+m" (((volatile char *)addr)[(nr^31) >> 3]) + : "di" (nr) + : "cc"); +#endif +} + +#define __clear_bit(nr, addr) clear_bit(nr, addr) + +static __inline__ void change_bit(int nr, volatile unsigned long * addr) +{ +#ifdef CONFIG_COLDFIRE + __asm__ __volatile__ ("lea %0,%%a0; bchg %1,(%%a0)" + : "+m" (((volatile char *)addr)[(nr^31) >> 3]) + : "d" (nr) + : "%a0", "cc"); +#else + __asm__ __volatile__ ("bchg %1,%0" + : "+m" (((volatile char *)addr)[(nr^31) >> 3]) + : "di" (nr) + : "cc"); +#endif +} + +#define __change_bit(nr, addr) change_bit(nr, addr) + +static __inline__ int test_and_set_bit(int nr, volatile unsigned long * addr) +{ + char retval; + +#ifdef CONFIG_COLDFIRE + __asm__ __volatile__ ("lea %1,%%a0; bset %2,(%%a0); sne %0" + : "=d" (retval), "+m" (((volatile char *)addr)[(nr^31) >> 3]) + : "d" (nr) + : "%a0"); +#else + __asm__ __volatile__ ("bset %2,%1; sne %0" + : "=d" (retval), "+m" (((volatile char *)addr)[(nr^31) >> 3]) + : "di" (nr) + /* No clobber */); +#endif + + return retval; +} + +#define __test_and_set_bit(nr, addr) test_and_set_bit(nr, addr) + +static __inline__ int test_and_clear_bit(int nr, volatile unsigned long * addr) +{ + char retval; + +#ifdef CONFIG_COLDFIRE + __asm__ __volatile__ ("lea %1,%%a0; bclr %2,(%%a0); sne %0" + : "=d" (retval), "+m" (((volatile char *)addr)[(nr^31) >> 3]) + : "d" (nr) + : "%a0"); +#else + __asm__ __volatile__ ("bclr %2,%1; sne %0" + : "=d" (retval), "+m" (((volatile char *)addr)[(nr^31) >> 3]) + : "di" (nr) + /* No clobber */); +#endif + + return retval; +} + +#define __test_and_clear_bit(nr, addr) test_and_clear_bit(nr, addr) + +static __inline__ int test_and_change_bit(int nr, volatile unsigned long * addr) +{ + char retval; + +#ifdef CONFIG_COLDFIRE + __asm__ __volatile__ ("lea %1,%%a0\n\tbchg %2,(%%a0)\n\tsne %0" + : "=d" (retval), "+m" (((volatile char *)addr)[(nr^31) >> 3]) + : "d" (nr) + : "%a0"); +#else + __asm__ __volatile__ ("bchg %2,%1; sne %0" + : "=d" (retval), "+m" (((volatile char *)addr)[(nr^31) >> 3]) + : "di" (nr) + /* No clobber */); +#endif + + return retval; +} + +#define __test_and_change_bit(nr, addr) test_and_change_bit(nr, addr) + +/* + * This routine doesn't need to be atomic. + */ +static __inline__ int __constant_test_bit(int nr, const volatile unsigned long * addr) +{ + return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; +} + +static __inline__ int __test_bit(int nr, const volatile unsigned long * addr) +{ + int * a = (int *) addr; + int mask; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + return ((mask & *a) != 0); +} + +#define test_bit(nr,addr) \ +(__builtin_constant_p(nr) ? \ + __constant_test_bit((nr),(addr)) : \ + __test_bit((nr),(addr))) + +#include +#include +#include + +static __inline__ int ext2_set_bit(int nr, volatile void * addr) +{ + char retval; + +#ifdef CONFIG_COLDFIRE + __asm__ __volatile__ ("lea %1,%%a0; bset %2,(%%a0); sne %0" + : "=d" (retval), "+m" (((volatile char *)addr)[nr >> 3]) + : "d" (nr) + : "%a0"); +#else + __asm__ __volatile__ ("bset %2,%1; sne %0" + : "=d" (retval), "+m" (((volatile char *)addr)[nr >> 3]) + : "di" (nr) + /* No clobber */); +#endif + + return retval; +} + +static __inline__ int ext2_clear_bit(int nr, volatile void * addr) +{ + char retval; + +#ifdef CONFIG_COLDFIRE + __asm__ __volatile__ ("lea %1,%%a0; bclr %2,(%%a0); sne %0" + : "=d" (retval), "+m" (((volatile char *)addr)[nr >> 3]) + : "d" (nr) + : "%a0"); +#else + __asm__ __volatile__ ("bclr %2,%1; sne %0" + : "=d" (retval), "+m" (((volatile char *)addr)[nr >> 3]) + : "di" (nr) + /* No clobber */); +#endif + + return retval; +} + +#define ext2_set_bit_atomic(lock, nr, addr) \ + ({ \ + int ret; \ + spin_lock(lock); \ + ret = ext2_set_bit((nr), (addr)); \ + spin_unlock(lock); \ + ret; \ + }) + +#define ext2_clear_bit_atomic(lock, nr, addr) \ + ({ \ + int ret; \ + spin_lock(lock); \ + ret = ext2_clear_bit((nr), (addr)); \ + spin_unlock(lock); \ + ret; \ + }) + +static __inline__ int ext2_test_bit(int nr, const volatile void * addr) +{ + char retval; + +#ifdef CONFIG_COLDFIRE + __asm__ __volatile__ ("lea %1,%%a0; btst %2,(%%a0); sne %0" + : "=d" (retval) + : "m" (((const volatile char *)addr)[nr >> 3]), "d" (nr) + : "%a0"); +#else + __asm__ __volatile__ ("btst %2,%1; sne %0" + : "=d" (retval) + : "m" (((const volatile char *)addr)[nr >> 3]), "di" (nr) + /* No clobber */); +#endif + + return retval; +} + +#define ext2_find_first_zero_bit(addr, size) \ + ext2_find_next_zero_bit((addr), (size), 0) + +static __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset) +{ + unsigned long *p = ((unsigned long *) addr) + (offset >> 5); + unsigned long result = offset & ~31UL; + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; + offset &= 31UL; + if(offset) { + /* We hold the little endian value in tmp, but then the + * shift is illegal. So we could keep a big endian value + * in tmp, like this: + * + * tmp = __swab32(*(p++)); + * tmp |= ~0UL >> (32-offset); + * + * but this would decrease performance, so we change the + * shift: + */ + tmp = *(p++); + tmp |= __swab32(~0UL >> (32-offset)); + if(size < 32) + goto found_first; + if(~tmp) + goto found_middle; + size -= 32; + result += 32; + } + while(size & ~31UL) { + if(~(tmp = *(p++))) + goto found_middle; + result += 32; + size -= 32; + } + if(!size) + return result; + tmp = *p; + +found_first: + /* tmp is little endian, so we would have to swab the shift, + * see above. But then we have to swab tmp below for ffz, so + * we might as well do this here. + */ + return result + ffz(__swab32(tmp) | (~0UL << size)); +found_middle: + return result + ffz(__swab32(tmp)); +} + +#define ext2_find_next_bit(addr, size, off) \ + generic_find_next_le_bit((unsigned long *)(addr), (size), (off)) +#include + +#endif /* __KERNEL__ */ + +#include +#include +#include + +#endif /* _M68KNOMMU_BITOPS_H */ diff --git a/arch/m68k/include/asm/blinken.h b/arch/m68k/include/asm/blinken.h new file mode 100644 index 00000000000..1a749cf7b06 --- /dev/null +++ b/arch/m68k/include/asm/blinken.h @@ -0,0 +1,32 @@ +/* +** asm/blinken.h -- m68k blinkenlights support (currently hp300 only) +** +** (c) 1998 Phil Blundell +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +*/ + +#ifndef _M68K_BLINKEN_H +#define _M68K_BLINKEN_H + +#include +#include + +#define HP300_LEDS 0xf001ffff + +extern unsigned char ledstate; + +static __inline__ void blinken_leds(int on, int off) +{ + if (MACH_IS_HP300) + { + ledstate |= on; + ledstate &= ~off; + out_8(HP300_LEDS, ~ledstate); + } +} + +#endif diff --git a/arch/m68k/include/asm/bootinfo.h b/arch/m68k/include/asm/bootinfo.h new file mode 100644 index 00000000000..fedf3e32612 --- /dev/null +++ b/arch/m68k/include/asm/bootinfo.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "bootinfo_no.h" +#else +#include "bootinfo_mm.h" +#endif diff --git a/arch/m68k/include/asm/bootinfo_mm.h b/arch/m68k/include/asm/bootinfo_mm.h new file mode 100644 index 00000000000..fb8a06b9ab6 --- /dev/null +++ b/arch/m68k/include/asm/bootinfo_mm.h @@ -0,0 +1,378 @@ +/* +** asm/bootinfo.h -- Definition of the Linux/m68k boot information structure +** +** Copyright 1992 by Greg Harp +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +** Created 09/29/92 by Greg Harp +** +** 5/2/94 Roman Hodek: +** Added bi_atari part of the machine dependent union bi_un; for now it +** contains just a model field to distinguish between TT and Falcon. +** 26/7/96 Roman Zippel: +** Renamed to setup.h; added some useful macros to allow gcc some +** optimizations if possible. +** 5/10/96 Geert Uytterhoeven: +** Redesign of the boot information structure; renamed to bootinfo.h again +** 27/11/96 Geert Uytterhoeven: +** Backwards compatibility with bootinfo interface version 1.0 +*/ + +#ifndef _M68K_BOOTINFO_H +#define _M68K_BOOTINFO_H + + + /* + * Bootinfo definitions + * + * This is an easily parsable and extendable structure containing all + * information to be passed from the bootstrap to the kernel. + * + * This way I hope to keep all future changes back/forewards compatible. + * Thus, keep your fingers crossed... + * + * This structure is copied right after the kernel bss by the bootstrap + * routine. + */ + +#ifndef __ASSEMBLY__ + +struct bi_record { + unsigned short tag; /* tag ID */ + unsigned short size; /* size of record (in bytes) */ + unsigned long data[0]; /* data */ +}; + +#endif /* __ASSEMBLY__ */ + + + /* + * Tag Definitions + * + * Machine independent tags start counting from 0x0000 + * Machine dependent tags start counting from 0x8000 + */ + +#define BI_LAST 0x0000 /* last record (sentinel) */ +#define BI_MACHTYPE 0x0001 /* machine type (u_long) */ +#define BI_CPUTYPE 0x0002 /* cpu type (u_long) */ +#define BI_FPUTYPE 0x0003 /* fpu type (u_long) */ +#define BI_MMUTYPE 0x0004 /* mmu type (u_long) */ +#define BI_MEMCHUNK 0x0005 /* memory chunk address and size */ + /* (struct mem_info) */ +#define BI_RAMDISK 0x0006 /* ramdisk address and size */ + /* (struct mem_info) */ +#define BI_COMMAND_LINE 0x0007 /* kernel command line parameters */ + /* (string) */ + + /* + * Amiga-specific tags + */ + +#define BI_AMIGA_MODEL 0x8000 /* model (u_long) */ +#define BI_AMIGA_AUTOCON 0x8001 /* AutoConfig device */ + /* (struct ConfigDev) */ +#define BI_AMIGA_CHIP_SIZE 0x8002 /* size of Chip RAM (u_long) */ +#define BI_AMIGA_VBLANK 0x8003 /* VBLANK frequency (u_char) */ +#define BI_AMIGA_PSFREQ 0x8004 /* power supply frequency (u_char) */ +#define BI_AMIGA_ECLOCK 0x8005 /* EClock frequency (u_long) */ +#define BI_AMIGA_CHIPSET 0x8006 /* native chipset present (u_long) */ +#define BI_AMIGA_SERPER 0x8007 /* serial port period (u_short) */ + + /* + * Atari-specific tags + */ + +#define BI_ATARI_MCH_COOKIE 0x8000 /* _MCH cookie from TOS (u_long) */ +#define BI_ATARI_MCH_TYPE 0x8001 /* special machine type (u_long) */ + /* (values are ATARI_MACH_* defines */ + +/* mch_cookie values (upper word) */ +#define ATARI_MCH_ST 0 +#define ATARI_MCH_STE 1 +#define ATARI_MCH_TT 2 +#define ATARI_MCH_FALCON 3 + +/* mch_type values */ +#define ATARI_MACH_NORMAL 0 /* no special machine type */ +#define ATARI_MACH_MEDUSA 1 /* Medusa 040 */ +#define ATARI_MACH_HADES 2 /* Hades 040 or 060 */ +#define ATARI_MACH_AB40 3 /* Afterburner040 on Falcon */ + + /* + * VME-specific tags + */ + +#define BI_VME_TYPE 0x8000 /* VME sub-architecture (u_long) */ +#define BI_VME_BRDINFO 0x8001 /* VME board information (struct) */ + +/* BI_VME_TYPE codes */ +#define VME_TYPE_TP34V 0x0034 /* Tadpole TP34V */ +#define VME_TYPE_MVME147 0x0147 /* Motorola MVME147 */ +#define VME_TYPE_MVME162 0x0162 /* Motorola MVME162 */ +#define VME_TYPE_MVME166 0x0166 /* Motorola MVME166 */ +#define VME_TYPE_MVME167 0x0167 /* Motorola MVME167 */ +#define VME_TYPE_MVME172 0x0172 /* Motorola MVME172 */ +#define VME_TYPE_MVME177 0x0177 /* Motorola MVME177 */ +#define VME_TYPE_BVME4000 0x4000 /* BVM Ltd. BVME4000 */ +#define VME_TYPE_BVME6000 0x6000 /* BVM Ltd. BVME6000 */ + +/* BI_VME_BRDINFO is a 32 byte struct as returned by the Bug code on + * Motorola VME boards. Contains board number, Bug version, board + * configuration options, etc. See include/asm/mvme16xhw.h for details. + */ + + + /* + * Macintosh-specific tags (all u_long) + */ + +#define BI_MAC_MODEL 0x8000 /* Mac Gestalt ID (model type) */ +#define BI_MAC_VADDR 0x8001 /* Mac video base address */ +#define BI_MAC_VDEPTH 0x8002 /* Mac video depth */ +#define BI_MAC_VROW 0x8003 /* Mac video rowbytes */ +#define BI_MAC_VDIM 0x8004 /* Mac video dimensions */ +#define BI_MAC_VLOGICAL 0x8005 /* Mac video logical base */ +#define BI_MAC_SCCBASE 0x8006 /* Mac SCC base address */ +#define BI_MAC_BTIME 0x8007 /* Mac boot time */ +#define BI_MAC_GMTBIAS 0x8008 /* Mac GMT timezone offset */ +#define BI_MAC_MEMSIZE 0x8009 /* Mac RAM size (sanity check) */ +#define BI_MAC_CPUID 0x800a /* Mac CPU type (sanity check) */ +#define BI_MAC_ROMBASE 0x800b /* Mac system ROM base address */ + + /* + * Macintosh hardware profile data - unused, see macintosh.h for + * resonable type values + */ + +#define BI_MAC_VIA1BASE 0x8010 /* Mac VIA1 base address (always present) */ +#define BI_MAC_VIA2BASE 0x8011 /* Mac VIA2 base address (type varies) */ +#define BI_MAC_VIA2TYPE 0x8012 /* Mac VIA2 type (VIA, RBV, OSS) */ +#define BI_MAC_ADBTYPE 0x8013 /* Mac ADB interface type */ +#define BI_MAC_ASCBASE 0x8014 /* Mac Apple Sound Chip base address */ +#define BI_MAC_SCSI5380 0x8015 /* Mac NCR 5380 SCSI (base address, multi) */ +#define BI_MAC_SCSIDMA 0x8016 /* Mac SCSI DMA (base address) */ +#define BI_MAC_SCSI5396 0x8017 /* Mac NCR 53C96 SCSI (base address, multi) */ +#define BI_MAC_IDETYPE 0x8018 /* Mac IDE interface type */ +#define BI_MAC_IDEBASE 0x8019 /* Mac IDE interface base address */ +#define BI_MAC_NUBUS 0x801a /* Mac Nubus type (none, regular, pseudo) */ +#define BI_MAC_SLOTMASK 0x801b /* Mac Nubus slots present */ +#define BI_MAC_SCCTYPE 0x801c /* Mac SCC serial type (normal, IOP) */ +#define BI_MAC_ETHTYPE 0x801d /* Mac builtin ethernet type (Sonic, MACE */ +#define BI_MAC_ETHBASE 0x801e /* Mac builtin ethernet base address */ +#define BI_MAC_PMU 0x801f /* Mac power management / poweroff hardware */ +#define BI_MAC_IOP_SWIM 0x8020 /* Mac SWIM floppy IOP */ +#define BI_MAC_IOP_ADB 0x8021 /* Mac ADB IOP */ + + /* + * Mac: compatibility with old booter data format (temporarily) + * Fields unused with the new bootinfo can be deleted now; instead of + * adding new fields the struct might be splitted into a hardware address + * part and a hardware type part + */ + +#ifndef __ASSEMBLY__ + +struct mac_booter_data +{ + unsigned long videoaddr; + unsigned long videorow; + unsigned long videodepth; + unsigned long dimensions; + unsigned long args; + unsigned long boottime; + unsigned long gmtbias; + unsigned long bootver; + unsigned long videological; + unsigned long sccbase; + unsigned long id; + unsigned long memsize; + unsigned long serialmf; + unsigned long serialhsk; + unsigned long serialgpi; + unsigned long printmf; + unsigned long printhsk; + unsigned long printgpi; + unsigned long cpuid; + unsigned long rombase; + unsigned long adbdelay; + unsigned long timedbra; +}; + +extern struct mac_booter_data + mac_bi_data; + +#endif + + /* + * Apollo-specific tags + */ + +#define BI_APOLLO_MODEL 0x8000 /* model (u_long) */ + + /* + * HP300-specific tags + */ + +#define BI_HP300_MODEL 0x8000 /* model (u_long) */ +#define BI_HP300_UART_SCODE 0x8001 /* UART select code (u_long) */ +#define BI_HP300_UART_ADDR 0x8002 /* phys. addr of UART (u_long) */ + + /* + * Stuff for bootinfo interface versioning + * + * At the start of kernel code, a 'struct bootversion' is located. + * bootstrap checks for a matching version of the interface before booting + * a kernel, to avoid user confusion if kernel and bootstrap don't work + * together :-) + * + * If incompatible changes are made to the bootinfo interface, the major + * number below should be stepped (and the minor reset to 0) for the + * appropriate machine. If a change is backward-compatible, the minor + * should be stepped. "Backwards-compatible" means that booting will work, + * but certain features may not. + */ + +#define BOOTINFOV_MAGIC 0x4249561A /* 'BIV^Z' */ +#define MK_BI_VERSION(major,minor) (((major)<<16)+(minor)) +#define BI_VERSION_MAJOR(v) (((v) >> 16) & 0xffff) +#define BI_VERSION_MINOR(v) ((v) & 0xffff) + +#ifndef __ASSEMBLY__ + +struct bootversion { + unsigned short branch; + unsigned long magic; + struct { + unsigned long machtype; + unsigned long version; + } machversions[0]; +}; + +#endif /* __ASSEMBLY__ */ + +#define AMIGA_BOOTI_VERSION MK_BI_VERSION( 2, 0 ) +#define ATARI_BOOTI_VERSION MK_BI_VERSION( 2, 1 ) +#define MAC_BOOTI_VERSION MK_BI_VERSION( 2, 0 ) +#define MVME147_BOOTI_VERSION MK_BI_VERSION( 2, 0 ) +#define MVME16x_BOOTI_VERSION MK_BI_VERSION( 2, 0 ) +#define BVME6000_BOOTI_VERSION MK_BI_VERSION( 2, 0 ) +#define Q40_BOOTI_VERSION MK_BI_VERSION( 2, 0 ) +#define HP300_BOOTI_VERSION MK_BI_VERSION( 2, 0 ) + +#ifdef BOOTINFO_COMPAT_1_0 + + /* + * Backwards compatibility with bootinfo interface version 1.0 + */ + +#define COMPAT_AMIGA_BOOTI_VERSION MK_BI_VERSION( 1, 0 ) +#define COMPAT_ATARI_BOOTI_VERSION MK_BI_VERSION( 1, 0 ) +#define COMPAT_MAC_BOOTI_VERSION MK_BI_VERSION( 1, 0 ) + +#include + +#define COMPAT_NUM_AUTO 16 + +struct compat_bi_Amiga { + int model; + int num_autocon; + struct ConfigDev autocon[COMPAT_NUM_AUTO]; + unsigned long chip_size; + unsigned char vblank; + unsigned char psfreq; + unsigned long eclock; + unsigned long chipset; + unsigned long hw_present; +}; + +struct compat_bi_Atari { + unsigned long hw_present; + unsigned long mch_cookie; +}; + +#ifndef __ASSEMBLY__ + +struct compat_bi_Macintosh +{ + unsigned long videoaddr; + unsigned long videorow; + unsigned long videodepth; + unsigned long dimensions; + unsigned long args; + unsigned long boottime; + unsigned long gmtbias; + unsigned long bootver; + unsigned long videological; + unsigned long sccbase; + unsigned long id; + unsigned long memsize; + unsigned long serialmf; + unsigned long serialhsk; + unsigned long serialgpi; + unsigned long printmf; + unsigned long printhsk; + unsigned long printgpi; + unsigned long cpuid; + unsigned long rombase; + unsigned long adbdelay; + unsigned long timedbra; +}; + +#endif + +struct compat_mem_info { + unsigned long addr; + unsigned long size; +}; + +#define COMPAT_NUM_MEMINFO 4 + +#define COMPAT_CPUB_68020 0 +#define COMPAT_CPUB_68030 1 +#define COMPAT_CPUB_68040 2 +#define COMPAT_CPUB_68060 3 +#define COMPAT_FPUB_68881 5 +#define COMPAT_FPUB_68882 6 +#define COMPAT_FPUB_68040 7 +#define COMPAT_FPUB_68060 8 + +#define COMPAT_CPU_68020 (1<= (unsigned long)(-64)) { \ + /* let errno be a function, preserve res in %d0 */ \ + int __err = -(res); \ + errno = __err; \ + res = -1; \ + } \ + return (type)(res); \ +} while (0) + +#define _bsc0(type,name) \ +type name(void) \ +{ \ + register long __res __asm__ ("%d0") = __BN_##name; \ + __asm__ __volatile__ ("trap #2" \ + : "=g" (__res) \ + : "0" (__res) \ + ); \ + __bsc_return(type,__res); \ +} + +#define _bsc1(type,name,atype,a) \ +type name(atype a) \ +{ \ + register long __res __asm__ ("%d0") = __BN_##name; \ + register long __a __asm__ ("%d1") = (long)a; \ + __asm__ __volatile__ ("trap #2" \ + : "=g" (__res) \ + : "0" (__res), "d" (__a) \ + ); \ + __bsc_return(type,__res); \ +} + +#define _bsc2(type,name,atype,a,btype,b) \ +type name(atype a, btype b) \ +{ \ + register long __res __asm__ ("%d0") = __BN_##name; \ + register long __a __asm__ ("%d1") = (long)a; \ + register long __b __asm__ ("%d2") = (long)b; \ + __asm__ __volatile__ ("trap #2" \ + : "=g" (__res) \ + : "0" (__res), "d" (__a), "d" (__b) \ + ); \ + __bsc_return(type,__res); \ +} + +#define _bsc3(type,name,atype,a,btype,b,ctype,c) \ +type name(atype a, btype b, ctype c) \ +{ \ + register long __res __asm__ ("%d0") = __BN_##name; \ + register long __a __asm__ ("%d1") = (long)a; \ + register long __b __asm__ ("%d2") = (long)b; \ + register long __c __asm__ ("%d3") = (long)c; \ + __asm__ __volatile__ ("trap #2" \ + : "=g" (__res) \ + : "0" (__res), "d" (__a), "d" (__b), \ + "d" (__c) \ + ); \ + __bsc_return(type,__res); \ +} + +#define _bsc4(type,name,atype,a,btype,b,ctype,c,dtype,d) \ +type name(atype a, btype b, ctype c, dtype d) \ +{ \ + register long __res __asm__ ("%d0") = __BN_##name; \ + register long __a __asm__ ("%d1") = (long)a; \ + register long __b __asm__ ("%d2") = (long)b; \ + register long __c __asm__ ("%d3") = (long)c; \ + register long __d __asm__ ("%d4") = (long)d; \ + __asm__ __volatile__ ("trap #2" \ + : "=g" (__res) \ + : "0" (__res), "d" (__a), "d" (__b), \ + "d" (__c), "d" (__d) \ + ); \ + __bsc_return(type,__res); \ +} + +#define _bsc5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \ +type name(atype a, btype b, ctype c, dtype d, etype e) \ +{ \ + register long __res __asm__ ("%d0") = __BN_##name; \ + register long __a __asm__ ("%d1") = (long)a; \ + register long __b __asm__ ("%d2") = (long)b; \ + register long __c __asm__ ("%d3") = (long)c; \ + register long __d __asm__ ("%d4") = (long)d; \ + register long __e __asm__ ("%d5") = (long)e; \ + __asm__ __volatile__ ("trap #2" \ + : "=g" (__res) \ + : "0" (__res), "d" (__a), "d" (__b), \ + "d" (__c), "d" (__d), "d" (__e) \ + ); \ + __bsc_return(type,__res); \ +} + +#endif /* __BOOTSTD_H__ */ diff --git a/arch/m68k/include/asm/bug.h b/arch/m68k/include/asm/bug.h new file mode 100644 index 00000000000..997e0944ebc --- /dev/null +++ b/arch/m68k/include/asm/bug.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "bug_no.h" +#else +#include "bug_mm.h" +#endif diff --git a/arch/m68k/include/asm/bug_mm.h b/arch/m68k/include/asm/bug_mm.h new file mode 100644 index 00000000000..e5b528deb8a --- /dev/null +++ b/arch/m68k/include/asm/bug_mm.h @@ -0,0 +1,29 @@ +#ifndef _M68K_BUG_H +#define _M68K_BUG_H + + +#ifdef CONFIG_BUG +#ifdef CONFIG_DEBUG_BUGVERBOSE +#ifndef CONFIG_SUN3 +#define BUG() do { \ + printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ + __builtin_trap(); \ +} while (0) +#else +#define BUG() do { \ + printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ + panic("BUG!"); \ +} while (0) +#endif +#else +#define BUG() do { \ + __builtin_trap(); \ +} while (0) +#endif + +#define HAVE_ARCH_BUG +#endif + +#include + +#endif diff --git a/arch/m68k/include/asm/bug_no.h b/arch/m68k/include/asm/bug_no.h new file mode 100644 index 00000000000..70e7dc0af21 --- /dev/null +++ b/arch/m68k/include/asm/bug_no.h @@ -0,0 +1,4 @@ +#ifndef _M68KNOMMU_BUG_H +#define _M68KNOMMU_BUG_H +#include +#endif diff --git a/arch/m68k/include/asm/bugs.h b/arch/m68k/include/asm/bugs.h new file mode 100644 index 00000000000..01f047d784e --- /dev/null +++ b/arch/m68k/include/asm/bugs.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "bugs_no.h" +#else +#include "bugs_mm.h" +#endif diff --git a/arch/m68k/include/asm/bugs_mm.h b/arch/m68k/include/asm/bugs_mm.h new file mode 100644 index 00000000000..d0193559241 --- /dev/null +++ b/arch/m68k/include/asm/bugs_mm.h @@ -0,0 +1,14 @@ +/* + * include/asm-m68k/bugs.h + * + * Copyright (C) 1994 Linus Torvalds + */ + +/* + * This is included by init/main.c to check for architecture-dependent bugs. + * + * Needs: + * void check_bugs(void); + */ + +extern void check_bugs(void); /* in arch/m68k/kernel/setup.c */ diff --git a/arch/m68k/include/asm/bugs_no.h b/arch/m68k/include/asm/bugs_no.h new file mode 100644 index 00000000000..5f382dac3a6 --- /dev/null +++ b/arch/m68k/include/asm/bugs_no.h @@ -0,0 +1,16 @@ +/* + * include/asm-m68k/bugs.h + * + * Copyright (C) 1994 Linus Torvalds + */ + +/* + * This is included by init/main.c to check for architecture-dependent bugs. + * + * Needs: + * void check_bugs(void); + */ + +static void check_bugs(void) +{ +} diff --git a/arch/m68k/include/asm/bvme6000hw.h b/arch/m68k/include/asm/bvme6000hw.h new file mode 100644 index 00000000000..f40d2f8510e --- /dev/null +++ b/arch/m68k/include/asm/bvme6000hw.h @@ -0,0 +1,150 @@ +#ifndef _M68K_BVME6000HW_H_ +#define _M68K_BVME6000HW_H_ + +#include + +/* + * PIT structure + */ + +#define BVME_PIT_BASE 0xffa00000 + +typedef struct { + unsigned char + pad_a[3], pgcr, + pad_b[3], psrr, + pad_c[3], paddr, + pad_d[3], pbddr, + pad_e[3], pcddr, + pad_f[3], pivr, + pad_g[3], pacr, + pad_h[3], pbcr, + pad_i[3], padr, + pad_j[3], pbdr, + pad_k[3], paar, + pad_l[3], pbar, + pad_m[3], pcdr, + pad_n[3], psr, + pad_o[3], res1, + pad_p[3], res2, + pad_q[3], tcr, + pad_r[3], tivr, + pad_s[3], res3, + pad_t[3], cprh, + pad_u[3], cprm, + pad_v[3], cprl, + pad_w[3], res4, + pad_x[3], crh, + pad_y[3], crm, + pad_z[3], crl, + pad_A[3], tsr, + pad_B[3], res5; +} PitRegs_t, *PitRegsPtr; + +#define bvmepit ((*(volatile PitRegsPtr)(BVME_PIT_BASE))) + +#define BVME_RTC_BASE 0xff900000 + +typedef struct { + unsigned char + pad_a[3], msr, + pad_b[3], t0cr_rtmr, + pad_c[3], t1cr_omr, + pad_d[3], pfr_icr0, + pad_e[3], irr_icr1, + pad_f[3], bcd_tenms, + pad_g[3], bcd_sec, + pad_h[3], bcd_min, + pad_i[3], bcd_hr, + pad_j[3], bcd_dom, + pad_k[3], bcd_mth, + pad_l[3], bcd_year, + pad_m[3], bcd_ujcc, + pad_n[3], bcd_hjcc, + pad_o[3], bcd_dow, + pad_p[3], t0lsb, + pad_q[3], t0msb, + pad_r[3], t1lsb, + pad_s[3], t1msb, + pad_t[3], cmp_sec, + pad_u[3], cmp_min, + pad_v[3], cmp_hr, + pad_w[3], cmp_dom, + pad_x[3], cmp_mth, + pad_y[3], cmp_dow, + pad_z[3], sav_sec, + pad_A[3], sav_min, + pad_B[3], sav_hr, + pad_C[3], sav_dom, + pad_D[3], sav_mth, + pad_E[3], ram, + pad_F[3], test; +} RtcRegs_t, *RtcPtr_t; + + +#define BVME_I596_BASE 0xff100000 + +#define BVME_ETHIRQ_REG 0xff20000b + +#define BVME_LOCAL_IRQ_STAT 0xff20000f + +#define BVME_ETHERR 0x02 +#define BVME_ABORT_STATUS 0x08 + +#define BVME_NCR53C710_BASE 0xff000000 + +#define BVME_SCC_A_ADDR 0xffb0000b +#define BVME_SCC_B_ADDR 0xffb00003 +#define BVME_SCC_RTxC 7372800 + +#define BVME_CONFIG_REG 0xff500003 + +#define config_reg_ptr (volatile unsigned char *)BVME_CONFIG_REG + +#define BVME_CONFIG_SW1 0x08 +#define BVME_CONFIG_SW2 0x04 +#define BVME_CONFIG_SW3 0x02 +#define BVME_CONFIG_SW4 0x01 + + +#define BVME_IRQ_TYPE_PRIO 0 + +#define BVME_IRQ_PRN (IRQ_USER+20) +#define BVME_IRQ_TIMER (IRQ_USER+25) +#define BVME_IRQ_I596 IRQ_AUTO_2 +#define BVME_IRQ_SCSI IRQ_AUTO_3 +#define BVME_IRQ_RTC IRQ_AUTO_6 +#define BVME_IRQ_ABORT IRQ_AUTO_7 + +/* SCC interrupts */ +#define BVME_IRQ_SCC_BASE IRQ_USER +#define BVME_IRQ_SCCB_TX IRQ_USER +#define BVME_IRQ_SCCB_STAT (IRQ_USER+2) +#define BVME_IRQ_SCCB_RX (IRQ_USER+4) +#define BVME_IRQ_SCCB_SPCOND (IRQ_USER+6) +#define BVME_IRQ_SCCA_TX (IRQ_USER+8) +#define BVME_IRQ_SCCA_STAT (IRQ_USER+10) +#define BVME_IRQ_SCCA_RX (IRQ_USER+12) +#define BVME_IRQ_SCCA_SPCOND (IRQ_USER+14) + +/* Address control registers */ + +#define BVME_ACR_A32VBA 0xff400003 +#define BVME_ACR_A32MSK 0xff410003 +#define BVME_ACR_A24VBA 0xff420003 +#define BVME_ACR_A24MSK 0xff430003 +#define BVME_ACR_A16VBA 0xff440003 +#define BVME_ACR_A32LBA 0xff450003 +#define BVME_ACR_A24LBA 0xff460003 +#define BVME_ACR_ADDRCTL 0xff470003 + +#define bvme_acr_a32vba *(volatile unsigned char *)BVME_ACR_A32VBA +#define bvme_acr_a32msk *(volatile unsigned char *)BVME_ACR_A32MSK +#define bvme_acr_a24vba *(volatile unsigned char *)BVME_ACR_A24VBA +#define bvme_acr_a24msk *(volatile unsigned char *)BVME_ACR_A24MSK +#define bvme_acr_a16vba *(volatile unsigned char *)BVME_ACR_A16VBA +#define bvme_acr_a32lba *(volatile unsigned char *)BVME_ACR_A32LBA +#define bvme_acr_a24lba *(volatile unsigned char *)BVME_ACR_A24LBA +#define bvme_acr_addrctl *(volatile unsigned char *)BVME_ACR_ADDRCTL + +#endif diff --git a/arch/m68k/include/asm/byteorder.h b/arch/m68k/include/asm/byteorder.h new file mode 100644 index 00000000000..f20502a001f --- /dev/null +++ b/arch/m68k/include/asm/byteorder.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "byteorder_no.h" +#else +#include "byteorder_mm.h" +#endif diff --git a/arch/m68k/include/asm/byteorder_mm.h b/arch/m68k/include/asm/byteorder_mm.h new file mode 100644 index 00000000000..300866523b8 --- /dev/null +++ b/arch/m68k/include/asm/byteorder_mm.h @@ -0,0 +1,7 @@ +#ifndef _M68K_BYTEORDER_H +#define _M68K_BYTEORDER_H + +#include +#include + +#endif /* _M68K_BYTEORDER_H */ diff --git a/arch/m68k/include/asm/byteorder_no.h b/arch/m68k/include/asm/byteorder_no.h new file mode 100644 index 00000000000..a6f0b8f7f62 --- /dev/null +++ b/arch/m68k/include/asm/byteorder_no.h @@ -0,0 +1,7 @@ +#ifndef _M68KNOMMU_BYTEORDER_H +#define _M68KNOMMU_BYTEORDER_H + +#include +#include + +#endif /* _M68KNOMMU_BYTEORDER_H */ diff --git a/arch/m68k/include/asm/cache.h b/arch/m68k/include/asm/cache.h new file mode 100644 index 00000000000..599c29bc8f4 --- /dev/null +++ b/arch/m68k/include/asm/cache.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "cache_no.h" +#else +#include "cache_mm.h" +#endif diff --git a/arch/m68k/include/asm/cache_mm.h b/arch/m68k/include/asm/cache_mm.h new file mode 100644 index 00000000000..fed3fd30de7 --- /dev/null +++ b/arch/m68k/include/asm/cache_mm.h @@ -0,0 +1,11 @@ +/* + * include/asm-m68k/cache.h + */ +#ifndef __ARCH_M68K_CACHE_H +#define __ARCH_M68K_CACHE_H + +/* bytes per L1 cache line */ +#define L1_CACHE_SHIFT 4 +#define L1_CACHE_BYTES (1<< L1_CACHE_SHIFT) + +#endif diff --git a/arch/m68k/include/asm/cache_no.h b/arch/m68k/include/asm/cache_no.h new file mode 100644 index 00000000000..24e9eace5f8 --- /dev/null +++ b/arch/m68k/include/asm/cache_no.h @@ -0,0 +1,12 @@ +#ifndef __ARCH_M68KNOMMU_CACHE_H +#define __ARCH_M68KNOMMU_CACHE_H + +/* bytes per L1 cache line */ +#define L1_CACHE_BYTES 16 /* this need to be at least 1 */ + +/* m68k-elf-gcc 2.95.2 doesn't like these */ + +#define __cacheline_aligned +#define ____cacheline_aligned + +#endif diff --git a/arch/m68k/include/asm/cachectl.h b/arch/m68k/include/asm/cachectl.h new file mode 100644 index 00000000000..525978e959e --- /dev/null +++ b/arch/m68k/include/asm/cachectl.h @@ -0,0 +1,14 @@ +#ifndef _M68K_CACHECTL_H +#define _M68K_CACHECTL_H + +/* Definitions for the cacheflush system call. */ + +#define FLUSH_SCOPE_LINE 1 /* Flush a cache line */ +#define FLUSH_SCOPE_PAGE 2 /* Flush a page */ +#define FLUSH_SCOPE_ALL 3 /* Flush the whole cache -- superuser only */ + +#define FLUSH_CACHE_DATA 1 /* Writeback and flush data cache */ +#define FLUSH_CACHE_INSN 2 /* Flush instruction cache */ +#define FLUSH_CACHE_BOTH 3 /* Flush both caches */ + +#endif /* _M68K_CACHECTL_H */ diff --git a/arch/m68k/include/asm/cacheflush.h b/arch/m68k/include/asm/cacheflush.h new file mode 100644 index 00000000000..a70d7319630 --- /dev/null +++ b/arch/m68k/include/asm/cacheflush.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "cacheflush_no.h" +#else +#include "cacheflush_mm.h" +#endif diff --git a/arch/m68k/include/asm/cacheflush_mm.h b/arch/m68k/include/asm/cacheflush_mm.h new file mode 100644 index 00000000000..16bf375fdbe --- /dev/null +++ b/arch/m68k/include/asm/cacheflush_mm.h @@ -0,0 +1,156 @@ +#ifndef _M68K_CACHEFLUSH_H +#define _M68K_CACHEFLUSH_H + +#include + +/* cache code */ +#define FLUSH_I_AND_D (0x00000808) +#define FLUSH_I (0x00000008) + +/* + * Cache handling functions + */ + +static inline void flush_icache(void) +{ + if (CPU_IS_040_OR_060) + asm volatile ( "nop\n" + " .chip 68040\n" + " cpusha %bc\n" + " .chip 68k"); + else { + unsigned long tmp; + asm volatile ( "movec %%cacr,%0\n" + " or.w %1,%0\n" + " movec %0,%%cacr" + : "=&d" (tmp) + : "id" (FLUSH_I)); + } +} + +/* + * invalidate the cache for the specified memory range. + * It starts at the physical address specified for + * the given number of bytes. + */ +extern void cache_clear(unsigned long paddr, int len); +/* + * push any dirty cache in the specified memory range. + * It starts at the physical address specified for + * the given number of bytes. + */ +extern void cache_push(unsigned long paddr, int len); + +/* + * push and invalidate pages in the specified user virtual + * memory range. + */ +extern void cache_push_v(unsigned long vaddr, int len); + +/* This is needed whenever the virtual mapping of the current + process changes. */ +#define __flush_cache_all() \ +({ \ + if (CPU_IS_040_OR_060) \ + __asm__ __volatile__("nop\n\t" \ + ".chip 68040\n\t" \ + "cpusha %dc\n\t" \ + ".chip 68k"); \ + else { \ + unsigned long _tmp; \ + __asm__ __volatile__("movec %%cacr,%0\n\t" \ + "orw %1,%0\n\t" \ + "movec %0,%%cacr" \ + : "=&d" (_tmp) \ + : "di" (FLUSH_I_AND_D)); \ + } \ +}) + +#define __flush_cache_030() \ +({ \ + if (CPU_IS_020_OR_030) { \ + unsigned long _tmp; \ + __asm__ __volatile__("movec %%cacr,%0\n\t" \ + "orw %1,%0\n\t" \ + "movec %0,%%cacr" \ + : "=&d" (_tmp) \ + : "di" (FLUSH_I_AND_D)); \ + } \ +}) + +#define flush_cache_all() __flush_cache_all() + +#define flush_cache_vmap(start, end) flush_cache_all() +#define flush_cache_vunmap(start, end) flush_cache_all() + +static inline void flush_cache_mm(struct mm_struct *mm) +{ + if (mm == current->mm) + __flush_cache_030(); +} + +#define flush_cache_dup_mm(mm) flush_cache_mm(mm) + +/* flush_cache_range/flush_cache_page must be macros to avoid + a dependency on linux/mm.h, which includes this file... */ +static inline void flush_cache_range(struct vm_area_struct *vma, + unsigned long start, + unsigned long end) +{ + if (vma->vm_mm == current->mm) + __flush_cache_030(); +} + +static inline void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn) +{ + if (vma->vm_mm == current->mm) + __flush_cache_030(); +} + + +/* Push the page at kernel virtual address and clear the icache */ +/* RZ: use cpush %bc instead of cpush %dc, cinv %ic */ +static inline void __flush_page_to_ram(void *vaddr) +{ + if (CPU_IS_040_OR_060) { + __asm__ __volatile__("nop\n\t" + ".chip 68040\n\t" + "cpushp %%bc,(%0)\n\t" + ".chip 68k" + : : "a" (__pa(vaddr))); + } else { + unsigned long _tmp; + __asm__ __volatile__("movec %%cacr,%0\n\t" + "orw %1,%0\n\t" + "movec %0,%%cacr" + : "=&d" (_tmp) + : "di" (FLUSH_I)); + } +} + +#define flush_dcache_page(page) __flush_page_to_ram(page_address(page)) +#define flush_dcache_mmap_lock(mapping) do { } while (0) +#define flush_dcache_mmap_unlock(mapping) do { } while (0) +#define flush_icache_page(vma, page) __flush_page_to_ram(page_address(page)) + +extern void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, + unsigned long addr, int len); +extern void flush_icache_range(unsigned long address, unsigned long endaddr); + +static inline void copy_to_user_page(struct vm_area_struct *vma, + struct page *page, unsigned long vaddr, + void *dst, void *src, int len) +{ + flush_cache_page(vma, vaddr, page_to_pfn(page)); + memcpy(dst, src, len); + flush_icache_user_range(vma, page, vaddr, len); +} +static inline void copy_from_user_page(struct vm_area_struct *vma, + struct page *page, unsigned long vaddr, + void *dst, void *src, int len) +{ + flush_cache_page(vma, vaddr, page_to_pfn(page)); + memcpy(dst, src, len); +} + +#endif /* _M68K_CACHEFLUSH_H */ diff --git a/arch/m68k/include/asm/cacheflush_no.h b/arch/m68k/include/asm/cacheflush_no.h new file mode 100644 index 00000000000..87e5dc0413b --- /dev/null +++ b/arch/m68k/include/asm/cacheflush_no.h @@ -0,0 +1,84 @@ +#ifndef _M68KNOMMU_CACHEFLUSH_H +#define _M68KNOMMU_CACHEFLUSH_H + +/* + * (C) Copyright 2000-2004, Greg Ungerer + */ +#include + +#define flush_cache_all() __flush_cache_all() +#define flush_cache_mm(mm) do { } while (0) +#define flush_cache_dup_mm(mm) do { } while (0) +#define flush_cache_range(vma, start, end) __flush_cache_all() +#define flush_cache_page(vma, vmaddr) do { } while (0) +#define flush_dcache_range(start,len) __flush_cache_all() +#define flush_dcache_page(page) do { } while (0) +#define flush_dcache_mmap_lock(mapping) do { } while (0) +#define flush_dcache_mmap_unlock(mapping) do { } while (0) +#define flush_icache_range(start,len) __flush_cache_all() +#define flush_icache_page(vma,pg) do { } while (0) +#define flush_icache_user_range(vma,pg,adr,len) do { } while (0) +#define flush_cache_vmap(start, end) do { } while (0) +#define flush_cache_vunmap(start, end) do { } while (0) + +#define copy_to_user_page(vma, page, vaddr, dst, src, len) \ + memcpy(dst, src, len) +#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ + memcpy(dst, src, len) + +static inline void __flush_cache_all(void) +{ +#ifdef CONFIG_M5407 + /* + * Use cpushl to push and invalidate all cache lines. + * Gas doesn't seem to know how to generate the ColdFire + * cpushl instruction... Oh well, bit stuff it for now. + */ + __asm__ __volatile__ ( + "nop\n\t" + "clrl %%d0\n\t" + "1:\n\t" + "movel %%d0,%%a0\n\t" + "2:\n\t" + ".word 0xf468\n\t" + "addl #0x10,%%a0\n\t" + "cmpl #0x00000800,%%a0\n\t" + "blt 2b\n\t" + "addql #1,%%d0\n\t" + "cmpil #4,%%d0\n\t" + "bne 1b\n\t" + "movel #0xb6088500,%%d0\n\t" + "movec %%d0,%%CACR\n\t" + : : : "d0", "a0" ); +#endif /* CONFIG_M5407 */ +#if defined(CONFIG_M527x) || defined(CONFIG_M528x) + __asm__ __volatile__ ( + "movel #0x81000200, %%d0\n\t" + "movec %%d0, %%CACR\n\t" + "nop\n\t" + : : : "d0" ); +#endif /* CONFIG_M527x || CONFIG_M528x */ +#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || defined(CONFIG_M5272) + __asm__ __volatile__ ( + "movel #0x81000100, %%d0\n\t" + "movec %%d0, %%CACR\n\t" + "nop\n\t" + : : : "d0" ); +#endif /* CONFIG_M5206 || CONFIG_M5206e || CONFIG_M5272 */ +#ifdef CONFIG_M5249 + __asm__ __volatile__ ( + "movel #0xa1000200, %%d0\n\t" + "movec %%d0, %%CACR\n\t" + "nop\n\t" + : : : "d0" ); +#endif /* CONFIG_M5249 */ +#ifdef CONFIG_M532x + __asm__ __volatile__ ( + "movel #0x81000200, %%d0\n\t" + "movec %%d0, %%CACR\n\t" + "nop\n\t" + : : : "d0" ); +#endif /* CONFIG_M532x */ +} + +#endif /* _M68KNOMMU_CACHEFLUSH_H */ diff --git a/arch/m68k/include/asm/checksum.h b/arch/m68k/include/asm/checksum.h new file mode 100644 index 00000000000..1cf54476745 --- /dev/null +++ b/arch/m68k/include/asm/checksum.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "checksum_no.h" +#else +#include "checksum_mm.h" +#endif diff --git a/arch/m68k/include/asm/checksum_mm.h b/arch/m68k/include/asm/checksum_mm.h new file mode 100644 index 00000000000..494f9aec37e --- /dev/null +++ b/arch/m68k/include/asm/checksum_mm.h @@ -0,0 +1,148 @@ +#ifndef _M68K_CHECKSUM_H +#define _M68K_CHECKSUM_H + +#include + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +__wsum csum_partial(const void *buff, int len, __wsum sum); + +/* + * the same as csum_partial, but copies from src while it + * checksums + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ + +extern __wsum csum_partial_copy_from_user(const void __user *src, + void *dst, + int len, __wsum sum, + int *csum_err); + +extern __wsum csum_partial_copy_nocheck(const void *src, + void *dst, int len, + __wsum sum); + +/* + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. + * + */ +static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) +{ + unsigned int sum = 0; + unsigned long tmp; + + __asm__ ("subqw #1,%2\n" + "1:\t" + "movel %1@+,%3\n\t" + "addxl %3,%0\n\t" + "dbra %2,1b\n\t" + "movel %0,%3\n\t" + "swap %3\n\t" + "addxw %3,%0\n\t" + "clrw %3\n\t" + "addxw %3,%0\n\t" + : "=d" (sum), "=&a" (iph), "=&d" (ihl), "=&d" (tmp) + : "0" (sum), "1" (iph), "2" (ihl) + : "memory"); + return (__force __sum16)~sum; +} + +/* + * Fold a partial checksum + */ + +static inline __sum16 csum_fold(__wsum sum) +{ + unsigned int tmp = (__force u32)sum; + __asm__("swap %1\n\t" + "addw %1, %0\n\t" + "clrw %1\n\t" + "addxw %1, %0" + : "=&d" (sum), "=&d" (tmp) + : "0" (sum), "1" (tmp)); + return (__force __sum16)~sum; +} + + +static inline __wsum +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) +{ + __asm__ ("addl %2,%0\n\t" + "addxl %3,%0\n\t" + "addxl %4,%0\n\t" + "clrl %1\n\t" + "addxl %1,%0" + : "=&d" (sum), "=d" (saddr) + : "g" (daddr), "1" (saddr), "d" (len + proto), + "0" (sum)); + return sum; +} + + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +static inline __sum16 +csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) +{ + return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); +} + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ + +static inline __sum16 ip_compute_csum(const void *buff, int len) +{ + return csum_fold (csum_partial(buff, len, 0)); +} + +#define _HAVE_ARCH_IPV6_CSUM +static __inline__ __sum16 +csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, + __u32 len, unsigned short proto, __wsum sum) +{ + register unsigned long tmp; + __asm__("addl %2@,%0\n\t" + "movel %2@(4),%1\n\t" + "addxl %1,%0\n\t" + "movel %2@(8),%1\n\t" + "addxl %1,%0\n\t" + "movel %2@(12),%1\n\t" + "addxl %1,%0\n\t" + "movel %3@,%1\n\t" + "addxl %1,%0\n\t" + "movel %3@(4),%1\n\t" + "addxl %1,%0\n\t" + "movel %3@(8),%1\n\t" + "addxl %1,%0\n\t" + "movel %3@(12),%1\n\t" + "addxl %1,%0\n\t" + "addxl %4,%0\n\t" + "clrl %1\n\t" + "addxl %1,%0" + : "=&d" (sum), "=&d" (tmp) + : "a" (saddr), "a" (daddr), "d" (len + proto), + "0" (sum)); + + return csum_fold(sum); +} + +#endif /* _M68K_CHECKSUM_H */ diff --git a/arch/m68k/include/asm/checksum_no.h b/arch/m68k/include/asm/checksum_no.h new file mode 100644 index 00000000000..81883482ffb --- /dev/null +++ b/arch/m68k/include/asm/checksum_no.h @@ -0,0 +1,132 @@ +#ifndef _M68K_CHECKSUM_H +#define _M68K_CHECKSUM_H + +#include + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +__wsum csum_partial(const void *buff, int len, __wsum sum); + +/* + * the same as csum_partial, but copies from src while it + * checksums + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ + +__wsum csum_partial_copy_nocheck(const void *src, void *dst, + int len, __wsum sum); + + +/* + * the same as csum_partial_copy, but copies from user space. + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ + +extern __wsum csum_partial_copy_from_user(const void __user *src, + void *dst, int len, __wsum sum, int *csum_err); + +__sum16 ip_fast_csum(const void *iph, unsigned int ihl); + +/* + * Fold a partial checksum + */ + +static inline __sum16 csum_fold(__wsum sum) +{ + unsigned int tmp = (__force u32)sum; +#ifdef CONFIG_COLDFIRE + tmp = (tmp & 0xffff) + (tmp >> 16); + tmp = (tmp & 0xffff) + (tmp >> 16); + return (__force __sum16)~tmp; +#else + __asm__("swap %1\n\t" + "addw %1, %0\n\t" + "clrw %1\n\t" + "addxw %1, %0" + : "=&d" (sum), "=&d" (tmp) + : "0" (sum), "1" (sum)); + return (__force __sum16)~sum; +#endif +} + + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ + +static inline __wsum +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) +{ + __asm__ ("addl %1,%0\n\t" + "addxl %4,%0\n\t" + "addxl %5,%0\n\t" + "clrl %1\n\t" + "addxl %1,%0" + : "=&d" (sum), "=&d" (saddr) + : "0" (daddr), "1" (saddr), "d" (len + proto), + "d"(sum)); + return sum; +} + +static inline __sum16 +csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) +{ + return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); +} + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ + +extern __sum16 ip_compute_csum(const void *buff, int len); + +#define _HAVE_ARCH_IPV6_CSUM +static __inline__ __sum16 +csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, + __u32 len, unsigned short proto, __wsum sum) +{ + register unsigned long tmp; + __asm__("addl %2@,%0\n\t" + "movel %2@(4),%1\n\t" + "addxl %1,%0\n\t" + "movel %2@(8),%1\n\t" + "addxl %1,%0\n\t" + "movel %2@(12),%1\n\t" + "addxl %1,%0\n\t" + "movel %3@,%1\n\t" + "addxl %1,%0\n\t" + "movel %3@(4),%1\n\t" + "addxl %1,%0\n\t" + "movel %3@(8),%1\n\t" + "addxl %1,%0\n\t" + "movel %3@(12),%1\n\t" + "addxl %1,%0\n\t" + "addxl %4,%0\n\t" + "clrl %1\n\t" + "addxl %1,%0" + : "=&d" (sum), "=&d" (tmp) + : "a" (saddr), "a" (daddr), "d" (len + proto), + "0" (sum)); + + return csum_fold(sum); +} + +#endif /* _M68K_CHECKSUM_H */ diff --git a/arch/m68k/include/asm/coldfire.h b/arch/m68k/include/asm/coldfire.h new file mode 100644 index 00000000000..83a9fa4e618 --- /dev/null +++ b/arch/m68k/include/asm/coldfire.h @@ -0,0 +1,51 @@ +/****************************************************************************/ + +/* + * coldfire.h -- Motorola ColdFire CPU sepecific defines + * + * (C) Copyright 1999-2006, Greg Ungerer (gerg@snapgear.com) + * (C) Copyright 2000, Lineo (www.lineo.com) + */ + +/****************************************************************************/ +#ifndef coldfire_h +#define coldfire_h +/****************************************************************************/ + + +/* + * Define master clock frequency. This is essentially done at config + * time now. No point enumerating dozens of possible clock options + * here. Also the peripheral clock (bus clock) divide ratio is set + * at config time too. + */ +#ifdef CONFIG_CLOCK_SET +#define MCF_CLK CONFIG_CLOCK_FREQ +#define MCF_BUSCLK (CONFIG_CLOCK_FREQ / CONFIG_CLOCK_DIV) +#else +#error "Don't know what your ColdFire CPU clock frequency is??" +#endif + +/* + * Define the processor support peripherals base address. + * This is generally setup by the boards start up code. + */ +#define MCF_MBAR 0x10000000 +#define MCF_MBAR2 0x80000000 +#if defined(CONFIG_M520x) +#define MCF_IPSBAR 0xFC000000 +#else +#define MCF_IPSBAR 0x40000000 +#endif + +#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ + defined(CONFIG_M520x) +#undef MCF_MBAR +#define MCF_MBAR MCF_IPSBAR +#elif defined(CONFIG_M532x) +#undef MCF_MBAR +#define MCF_MBAR 0x00000000 +#endif + +/****************************************************************************/ +#endif /* coldfire_h */ diff --git a/arch/m68k/include/asm/commproc.h b/arch/m68k/include/asm/commproc.h new file mode 100644 index 00000000000..edf5eb6c08d --- /dev/null +++ b/arch/m68k/include/asm/commproc.h @@ -0,0 +1,703 @@ + +/* + * 68360 Communication Processor Module. + * Copyright (c) 2000 Michael Leslie (mc68360) after: + * Copyright (c) 1997 Dan Malek (mpc8xx) + * + * This file contains structures and information for the communication + * processor channels. Some CPM control and status is available + * through the 68360 internal memory map. See include/asm/360_immap.h for details. + * This file is not a complete map of all of the 360 QUICC's capabilities + * + * On the MBX board, EPPC-Bug loads CPM microcode into the first 512 + * bytes of the DP RAM and relocates the I2C parameter area to the + * IDMA1 space. The remaining DP RAM is available for buffer descriptors + * or other use. + */ +#ifndef __CPM_360__ +#define __CPM_360__ + + +/* CPM Command register masks: */ +#define CPM_CR_RST ((ushort)0x8000) +#define CPM_CR_OPCODE ((ushort)0x0f00) +#define CPM_CR_CHAN ((ushort)0x00f0) +#define CPM_CR_FLG ((ushort)0x0001) + +/* CPM Command set (opcodes): */ +#define CPM_CR_INIT_TRX ((ushort)0x0000) +#define CPM_CR_INIT_RX ((ushort)0x0001) +#define CPM_CR_INIT_TX ((ushort)0x0002) +#define CPM_CR_HUNT_MODE ((ushort)0x0003) +#define CPM_CR_STOP_TX ((ushort)0x0004) +#define CPM_CR_GRSTOP_TX ((ushort)0x0005) +#define CPM_CR_RESTART_TX ((ushort)0x0006) +#define CPM_CR_CLOSE_RXBD ((ushort)0x0007) +#define CPM_CR_SET_GADDR ((ushort)0x0008) +#define CPM_CR_GCI_TIMEOUT ((ushort)0x0009) +#define CPM_CR_GCI_ABORT ((ushort)0x000a) +#define CPM_CR_RESET_BCS ((ushort)0x000a) + +/* CPM Channel numbers. */ +#define CPM_CR_CH_SCC1 ((ushort)0x0000) +#define CPM_CR_CH_SCC2 ((ushort)0x0004) +#define CPM_CR_CH_SPI ((ushort)0x0005) /* SPI / Timers */ +#define CPM_CR_CH_TMR ((ushort)0x0005) +#define CPM_CR_CH_SCC3 ((ushort)0x0008) +#define CPM_CR_CH_SMC1 ((ushort)0x0009) /* SMC1 / IDMA1 */ +#define CPM_CR_CH_IDMA1 ((ushort)0x0009) +#define CPM_CR_CH_SCC4 ((ushort)0x000c) +#define CPM_CR_CH_SMC2 ((ushort)0x000d) /* SMC2 / IDMA2 */ +#define CPM_CR_CH_IDMA2 ((ushort)0x000d) + + +#define mk_cr_cmd(CH, CMD) ((CMD << 8) | (CH << 4)) + +#if 1 /* mleslie: I dinna think we have any such restrictions on + * DP RAM aboard the 360 board - see the MC68360UM p.3-3 */ + +/* The dual ported RAM is multi-functional. Some areas can be (and are + * being) used for microcode. There is an area that can only be used + * as data ram for buffer descriptors, which is all we use right now. + * Currently the first 512 and last 256 bytes are used for microcode. + */ +/* mleslie: The uCquicc board is using no extra microcode in DPRAM */ +#define CPM_DATAONLY_BASE ((uint)0x0000) +#define CPM_DATAONLY_SIZE ((uint)0x0800) +#define CPM_DP_NOSPACE ((uint)0x7fffffff) + +#endif + + +/* Export the base address of the communication processor registers + * and dual port ram. */ +/* extern cpm360_t *cpmp; */ /* Pointer to comm processor */ +extern QUICC *pquicc; +uint m360_cpm_dpalloc(uint size); +/* void *m360_cpm_hostalloc(uint size); */ +void m360_cpm_setbrg(uint brg, uint rate); + +#if 0 /* use QUICC_BD declared in include/asm/m68360_quicc.h */ +/* Buffer descriptors used by many of the CPM protocols. */ +typedef struct cpm_buf_desc { + ushort cbd_sc; /* Status and Control */ + ushort cbd_datlen; /* Data length in buffer */ + uint cbd_bufaddr; /* Buffer address in host memory */ +} cbd_t; +#endif + + +/* rx bd status/control bits */ +#define BD_SC_EMPTY ((ushort)0x8000) /* Recieve is empty */ +#define BD_SC_WRAP ((ushort)0x2000) /* Last buffer descriptor in table */ +#define BD_SC_INTRPT ((ushort)0x1000) /* Interrupt on change */ +#define BD_SC_LAST ((ushort)0x0800) /* Last buffer in frame OR control char */ + +#define BD_SC_FIRST ((ushort)0x0400) /* 1st buffer in an HDLC frame */ +#define BD_SC_ADDR ((ushort)0x0400) /* 1st byte is a multidrop address */ + +#define BD_SC_CM ((ushort)0x0200) /* Continous mode */ +#define BD_SC_ID ((ushort)0x0100) /* Received too many idles */ + +#define BD_SC_AM ((ushort)0x0080) /* Multidrop address match */ +#define BD_SC_DE ((ushort)0x0080) /* DPLL Error (HDLC) */ + +#define BD_SC_BR ((ushort)0x0020) /* Break received */ +#define BD_SC_LG ((ushort)0x0020) /* Frame length violation (HDLC) */ + +#define BD_SC_FR ((ushort)0x0010) /* Framing error */ +#define BD_SC_NO ((ushort)0x0010) /* Nonoctet aligned frame (HDLC) */ + +#define BD_SC_PR ((ushort)0x0008) /* Parity error */ +#define BD_SC_AB ((ushort)0x0008) /* Received abort Sequence (HDLC) */ + +#define BD_SC_OV ((ushort)0x0002) /* Overrun */ +#define BD_SC_CD ((ushort)0x0001) /* Carrier Detect lost */ + +/* tx bd status/control bits (as differ from rx bd) */ +#define BD_SC_READY ((ushort)0x8000) /* Transmit is ready */ +#define BD_SC_TC ((ushort)0x0400) /* Transmit CRC */ +#define BD_SC_P ((ushort)0x0100) /* xmt preamble */ +#define BD_SC_UN ((ushort)0x0002) /* Underrun */ + + + + +/* Parameter RAM offsets. */ + + + +/* In 2.4 ppc, the PROFF_S?C? are used as byte offsets into DPRAM. + * In 2.0, we use a more structured C struct map of DPRAM, and so + * instead, we need only a parameter ram `slot' */ + +#define PRSLOT_SCC1 0 +#define PRSLOT_SCC2 1 +#define PRSLOT_SCC3 2 +#define PRSLOT_SMC1 2 +#define PRSLOT_SCC4 3 +#define PRSLOT_SMC2 3 + + +/* #define PROFF_SCC1 ((uint)0x0000) */ +/* #define PROFF_SCC2 ((uint)0x0100) */ +/* #define PROFF_SCC3 ((uint)0x0200) */ +/* #define PROFF_SMC1 ((uint)0x0280) */ +/* #define PROFF_SCC4 ((uint)0x0300) */ +/* #define PROFF_SMC2 ((uint)0x0380) */ + + +/* Define enough so I can at least use the serial port as a UART. + * The MBX uses SMC1 as the host serial port. + */ +typedef struct smc_uart { + ushort smc_rbase; /* Rx Buffer descriptor base address */ + ushort smc_tbase; /* Tx Buffer descriptor base address */ + u_char smc_rfcr; /* Rx function code */ + u_char smc_tfcr; /* Tx function code */ + ushort smc_mrblr; /* Max receive buffer length */ + uint smc_rstate; /* Internal */ + uint smc_idp; /* Internal */ + ushort smc_rbptr; /* Internal */ + ushort smc_ibc; /* Internal */ + uint smc_rxtmp; /* Internal */ + uint smc_tstate; /* Internal */ + uint smc_tdp; /* Internal */ + ushort smc_tbptr; /* Internal */ + ushort smc_tbc; /* Internal */ + uint smc_txtmp; /* Internal */ + ushort smc_maxidl; /* Maximum idle characters */ + ushort smc_tmpidl; /* Temporary idle counter */ + ushort smc_brklen; /* Last received break length */ + ushort smc_brkec; /* rcv'd break condition counter */ + ushort smc_brkcr; /* xmt break count register */ + ushort smc_rmask; /* Temporary bit mask */ +} smc_uart_t; + +/* Function code bits. +*/ +#define SMC_EB ((u_char)0x10) /* Set big endian byte order */ + +/* SMC uart mode register. +*/ +#define SMCMR_REN ((ushort)0x0001) +#define SMCMR_TEN ((ushort)0x0002) +#define SMCMR_DM ((ushort)0x000c) +#define SMCMR_SM_GCI ((ushort)0x0000) +#define SMCMR_SM_UART ((ushort)0x0020) +#define SMCMR_SM_TRANS ((ushort)0x0030) +#define SMCMR_SM_MASK ((ushort)0x0030) +#define SMCMR_PM_EVEN ((ushort)0x0100) /* Even parity, else odd */ +#define SMCMR_REVD SMCMR_PM_EVEN +#define SMCMR_PEN ((ushort)0x0200) /* Parity enable */ +#define SMCMR_BS SMCMR_PEN +#define SMCMR_SL ((ushort)0x0400) /* Two stops, else one */ +#define SMCR_CLEN_MASK ((ushort)0x7800) /* Character length */ +#define smcr_mk_clen(C) (((C) << 11) & SMCR_CLEN_MASK) + +/* SMC2 as Centronics parallel printer. It is half duplex, in that + * it can only receive or transmit. The parameter ram values for + * each direction are either unique or properly overlap, so we can + * include them in one structure. + */ +typedef struct smc_centronics { + ushort scent_rbase; + ushort scent_tbase; + u_char scent_cfcr; + u_char scent_smask; + ushort scent_mrblr; + uint scent_rstate; + uint scent_r_ptr; + ushort scent_rbptr; + ushort scent_r_cnt; + uint scent_rtemp; + uint scent_tstate; + uint scent_t_ptr; + ushort scent_tbptr; + ushort scent_t_cnt; + uint scent_ttemp; + ushort scent_max_sl; + ushort scent_sl_cnt; + ushort scent_character1; + ushort scent_character2; + ushort scent_character3; + ushort scent_character4; + ushort scent_character5; + ushort scent_character6; + ushort scent_character7; + ushort scent_character8; + ushort scent_rccm; + ushort scent_rccr; +} smc_cent_t; + +/* Centronics Status Mask Register. +*/ +#define SMC_CENT_F ((u_char)0x08) +#define SMC_CENT_PE ((u_char)0x04) +#define SMC_CENT_S ((u_char)0x02) + +/* SMC Event and Mask register. +*/ +#define SMCM_BRKE ((unsigned char)0x40) /* When in UART Mode */ +#define SMCM_BRK ((unsigned char)0x10) /* When in UART Mode */ +#define SMCM_TXE ((unsigned char)0x10) /* When in Transparent Mode */ +#define SMCM_BSY ((unsigned char)0x04) +#define SMCM_TX ((unsigned char)0x02) +#define SMCM_RX ((unsigned char)0x01) + +/* Baud rate generators. +*/ +#define CPM_BRG_RST ((uint)0x00020000) +#define CPM_BRG_EN ((uint)0x00010000) +#define CPM_BRG_EXTC_INT ((uint)0x00000000) +#define CPM_BRG_EXTC_CLK2 ((uint)0x00004000) +#define CPM_BRG_EXTC_CLK6 ((uint)0x00008000) +#define CPM_BRG_ATB ((uint)0x00002000) +#define CPM_BRG_CD_MASK ((uint)0x00001ffe) +#define CPM_BRG_DIV16 ((uint)0x00000001) + +/* SCCs. +*/ +#define SCC_GSMRH_IRP ((uint)0x00040000) +#define SCC_GSMRH_GDE ((uint)0x00010000) +#define SCC_GSMRH_TCRC_CCITT ((uint)0x00008000) +#define SCC_GSMRH_TCRC_BISYNC ((uint)0x00004000) +#define SCC_GSMRH_TCRC_HDLC ((uint)0x00000000) +#define SCC_GSMRH_REVD ((uint)0x00002000) +#define SCC_GSMRH_TRX ((uint)0x00001000) +#define SCC_GSMRH_TTX ((uint)0x00000800) +#define SCC_GSMRH_CDP ((uint)0x00000400) +#define SCC_GSMRH_CTSP ((uint)0x00000200) +#define SCC_GSMRH_CDS ((uint)0x00000100) +#define SCC_GSMRH_CTSS ((uint)0x00000080) +#define SCC_GSMRH_TFL ((uint)0x00000040) +#define SCC_GSMRH_RFW ((uint)0x00000020) +#define SCC_GSMRH_TXSY ((uint)0x00000010) +#define SCC_GSMRH_SYNL16 ((uint)0x0000000c) +#define SCC_GSMRH_SYNL8 ((uint)0x00000008) +#define SCC_GSMRH_SYNL4 ((uint)0x00000004) +#define SCC_GSMRH_RTSM ((uint)0x00000002) +#define SCC_GSMRH_RSYN ((uint)0x00000001) + +#define SCC_GSMRL_SIR ((uint)0x80000000) /* SCC2 only */ +#define SCC_GSMRL_EDGE_NONE ((uint)0x60000000) +#define SCC_GSMRL_EDGE_NEG ((uint)0x40000000) +#define SCC_GSMRL_EDGE_POS ((uint)0x20000000) +#define SCC_GSMRL_EDGE_BOTH ((uint)0x00000000) +#define SCC_GSMRL_TCI ((uint)0x10000000) +#define SCC_GSMRL_TSNC_3 ((uint)0x0c000000) +#define SCC_GSMRL_TSNC_4 ((uint)0x08000000) +#define SCC_GSMRL_TSNC_14 ((uint)0x04000000) +#define SCC_GSMRL_TSNC_INF ((uint)0x00000000) +#define SCC_GSMRL_RINV ((uint)0x02000000) +#define SCC_GSMRL_TINV ((uint)0x01000000) +#define SCC_GSMRL_TPL_128 ((uint)0x00c00000) +#define SCC_GSMRL_TPL_64 ((uint)0x00a00000) +#define SCC_GSMRL_TPL_48 ((uint)0x00800000) +#define SCC_GSMRL_TPL_32 ((uint)0x00600000) +#define SCC_GSMRL_TPL_16 ((uint)0x00400000) +#define SCC_GSMRL_TPL_8 ((uint)0x00200000) +#define SCC_GSMRL_TPL_NONE ((uint)0x00000000) +#define SCC_GSMRL_TPP_ALL1 ((uint)0x00180000) +#define SCC_GSMRL_TPP_01 ((uint)0x00100000) +#define SCC_GSMRL_TPP_10 ((uint)0x00080000) +#define SCC_GSMRL_TPP_ZEROS ((uint)0x00000000) +#define SCC_GSMRL_TEND ((uint)0x00040000) +#define SCC_GSMRL_TDCR_32 ((uint)0x00030000) +#define SCC_GSMRL_TDCR_16 ((uint)0x00020000) +#define SCC_GSMRL_TDCR_8 ((uint)0x00010000) +#define SCC_GSMRL_TDCR_1 ((uint)0x00000000) +#define SCC_GSMRL_RDCR_32 ((uint)0x0000c000) +#define SCC_GSMRL_RDCR_16 ((uint)0x00008000) +#define SCC_GSMRL_RDCR_8 ((uint)0x00004000) +#define SCC_GSMRL_RDCR_1 ((uint)0x00000000) +#define SCC_GSMRL_RENC_DFMAN ((uint)0x00003000) +#define SCC_GSMRL_RENC_MANCH ((uint)0x00002000) +#define SCC_GSMRL_RENC_FM0 ((uint)0x00001000) +#define SCC_GSMRL_RENC_NRZI ((uint)0x00000800) +#define SCC_GSMRL_RENC_NRZ ((uint)0x00000000) +#define SCC_GSMRL_TENC_DFMAN ((uint)0x00000600) +#define SCC_GSMRL_TENC_MANCH ((uint)0x00000400) +#define SCC_GSMRL_TENC_FM0 ((uint)0x00000200) +#define SCC_GSMRL_TENC_NRZI ((uint)0x00000100) +#define SCC_GSMRL_TENC_NRZ ((uint)0x00000000) +#define SCC_GSMRL_DIAG_LE ((uint)0x000000c0) /* Loop and echo */ +#define SCC_GSMRL_DIAG_ECHO ((uint)0x00000080) +#define SCC_GSMRL_DIAG_LOOP ((uint)0x00000040) +#define SCC_GSMRL_DIAG_NORM ((uint)0x00000000) +#define SCC_GSMRL_ENR ((uint)0x00000020) +#define SCC_GSMRL_ENT ((uint)0x00000010) +#define SCC_GSMRL_MODE_ENET ((uint)0x0000000c) +#define SCC_GSMRL_MODE_DDCMP ((uint)0x00000009) +#define SCC_GSMRL_MODE_BISYNC ((uint)0x00000008) +#define SCC_GSMRL_MODE_V14 ((uint)0x00000007) +#define SCC_GSMRL_MODE_AHDLC ((uint)0x00000006) +#define SCC_GSMRL_MODE_PROFIBUS ((uint)0x00000005) +#define SCC_GSMRL_MODE_UART ((uint)0x00000004) +#define SCC_GSMRL_MODE_SS7 ((uint)0x00000003) +#define SCC_GSMRL_MODE_ATALK ((uint)0x00000002) +#define SCC_GSMRL_MODE_HDLC ((uint)0x00000000) + +#define SCC_TODR_TOD ((ushort)0x8000) + +/* SCC Event and Mask register. +*/ +#define SCCM_TXE ((unsigned char)0x10) +#define SCCM_BSY ((unsigned char)0x04) +#define SCCM_TX ((unsigned char)0x02) +#define SCCM_RX ((unsigned char)0x01) + +typedef struct scc_param { + ushort scc_rbase; /* Rx Buffer descriptor base address */ + ushort scc_tbase; /* Tx Buffer descriptor base address */ + u_char scc_rfcr; /* Rx function code */ + u_char scc_tfcr; /* Tx function code */ + ushort scc_mrblr; /* Max receive buffer length */ + uint scc_rstate; /* Internal */ + uint scc_idp; /* Internal */ + ushort scc_rbptr; /* Internal */ + ushort scc_ibc; /* Internal */ + uint scc_rxtmp; /* Internal */ + uint scc_tstate; /* Internal */ + uint scc_tdp; /* Internal */ + ushort scc_tbptr; /* Internal */ + ushort scc_tbc; /* Internal */ + uint scc_txtmp; /* Internal */ + uint scc_rcrc; /* Internal */ + uint scc_tcrc; /* Internal */ +} sccp_t; + + +/* Function code bits. + */ +#define SCC_EB ((u_char)0x10) /* Set big endian byte order */ +#define SCC_FC_DMA ((u_char)0x08) /* Set SDMA */ + +/* CPM Ethernet through SCC1. + */ +typedef struct scc_enet { + sccp_t sen_genscc; + uint sen_cpres; /* Preset CRC */ + uint sen_cmask; /* Constant mask for CRC */ + uint sen_crcec; /* CRC Error counter */ + uint sen_alec; /* alignment error counter */ + uint sen_disfc; /* discard frame counter */ + ushort sen_pads; /* Tx short frame pad character */ + ushort sen_retlim; /* Retry limit threshold */ + ushort sen_retcnt; /* Retry limit counter */ + ushort sen_maxflr; /* maximum frame length register */ + ushort sen_minflr; /* minimum frame length register */ + ushort sen_maxd1; /* maximum DMA1 length */ + ushort sen_maxd2; /* maximum DMA2 length */ + ushort sen_maxd; /* Rx max DMA */ + ushort sen_dmacnt; /* Rx DMA counter */ + ushort sen_maxb; /* Max BD byte count */ + ushort sen_gaddr1; /* Group address filter */ + ushort sen_gaddr2; + ushort sen_gaddr3; + ushort sen_gaddr4; + uint sen_tbuf0data0; /* Save area 0 - current frame */ + uint sen_tbuf0data1; /* Save area 1 - current frame */ + uint sen_tbuf0rba; /* Internal */ + uint sen_tbuf0crc; /* Internal */ + ushort sen_tbuf0bcnt; /* Internal */ + ushort sen_paddrh; /* physical address (MSB) */ + ushort sen_paddrm; + ushort sen_paddrl; /* physical address (LSB) */ + ushort sen_pper; /* persistence */ + ushort sen_rfbdptr; /* Rx first BD pointer */ + ushort sen_tfbdptr; /* Tx first BD pointer */ + ushort sen_tlbdptr; /* Tx last BD pointer */ + uint sen_tbuf1data0; /* Save area 0 - current frame */ + uint sen_tbuf1data1; /* Save area 1 - current frame */ + uint sen_tbuf1rba; /* Internal */ + uint sen_tbuf1crc; /* Internal */ + ushort sen_tbuf1bcnt; /* Internal */ + ushort sen_txlen; /* Tx Frame length counter */ + ushort sen_iaddr1; /* Individual address filter */ + ushort sen_iaddr2; + ushort sen_iaddr3; + ushort sen_iaddr4; + ushort sen_boffcnt; /* Backoff counter */ + + /* NOTE: Some versions of the manual have the following items + * incorrectly documented. Below is the proper order. + */ + ushort sen_taddrh; /* temp address (MSB) */ + ushort sen_taddrm; + ushort sen_taddrl; /* temp address (LSB) */ +} scc_enet_t; + + + +#if defined (CONFIG_UCQUICC) +/* uCquicc has the following signals connected to Ethernet: + * 68360 - lxt905 + * PA0/RXD1 - rxd + * PA1/TXD1 - txd + * PA8/CLK1 - tclk + * PA9/CLK2 - rclk + * PC0/!RTS1 - t_en + * PC1/!CTS1 - col + * PC5/!CD1 - cd + */ +#define PA_ENET_RXD PA_RXD1 +#define PA_ENET_TXD PA_TXD1 +#define PA_ENET_TCLK PA_CLK1 +#define PA_ENET_RCLK PA_CLK2 +#define PC_ENET_TENA PC_RTS1 +#define PC_ENET_CLSN PC_CTS1 +#define PC_ENET_RENA PC_CD1 + +/* Control bits in the SICR to route TCLK (CLK1) and RCLK (CLK2) to + * SCC1. + */ +#define SICR_ENET_MASK ((uint)0x000000ff) +#define SICR_ENET_CLKRT ((uint)0x0000002c) + +#endif /* config_ucquicc */ + + +#ifdef MBX +/* Bits in parallel I/O port registers that have to be set/cleared + * to configure the pins for SCC1 use. The TCLK and RCLK seem unique + * to the MBX860 board. Any two of the four available clocks could be + * used, and the MPC860 cookbook manual has an example using different + * clock pins. + */ +#define PA_ENET_RXD ((ushort)0x0001) +#define PA_ENET_TXD ((ushort)0x0002) +#define PA_ENET_TCLK ((ushort)0x0200) +#define PA_ENET_RCLK ((ushort)0x0800) +#define PC_ENET_TENA ((ushort)0x0001) +#define PC_ENET_CLSN ((ushort)0x0010) +#define PC_ENET_RENA ((ushort)0x0020) + +/* Control bits in the SICR to route TCLK (CLK2) and RCLK (CLK4) to + * SCC1. Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero. + */ +#define SICR_ENET_MASK ((uint)0x000000ff) +#define SICR_ENET_CLKRT ((uint)0x0000003d) +#endif + +#ifdef CONFIG_RPXLITE +/* This ENET stuff is for the MPC850 with ethernet on SCC2. Some of + * this may be unique to the RPX-Lite configuration. + * Note TENA is on Port B. + */ +#define PA_ENET_RXD ((ushort)0x0004) +#define PA_ENET_TXD ((ushort)0x0008) +#define PA_ENET_TCLK ((ushort)0x0200) +#define PA_ENET_RCLK ((ushort)0x0800) +#define PB_ENET_TENA ((uint)0x00002000) +#define PC_ENET_CLSN ((ushort)0x0040) +#define PC_ENET_RENA ((ushort)0x0080) + +#define SICR_ENET_MASK ((uint)0x0000ff00) +#define SICR_ENET_CLKRT ((uint)0x00003d00) +#endif + +#ifdef CONFIG_BSEIP +/* This ENET stuff is for the MPC823 with ethernet on SCC2. + * This is unique to the BSE ip-Engine board. + */ +#define PA_ENET_RXD ((ushort)0x0004) +#define PA_ENET_TXD ((ushort)0x0008) +#define PA_ENET_TCLK ((ushort)0x0100) +#define PA_ENET_RCLK ((ushort)0x0200) +#define PB_ENET_TENA ((uint)0x00002000) +#define PC_ENET_CLSN ((ushort)0x0040) +#define PC_ENET_RENA ((ushort)0x0080) + +/* BSE uses port B and C bits for PHY control also. +*/ +#define PB_BSE_POWERUP ((uint)0x00000004) +#define PB_BSE_FDXDIS ((uint)0x00008000) +#define PC_BSE_LOOPBACK ((ushort)0x0800) + +#define SICR_ENET_MASK ((uint)0x0000ff00) +#define SICR_ENET_CLKRT ((uint)0x00002c00) +#endif + +/* SCC Event register as used by Ethernet. +*/ +#define SCCE_ENET_GRA ((ushort)0x0080) /* Graceful stop complete */ +#define SCCE_ENET_TXE ((ushort)0x0010) /* Transmit Error */ +#define SCCE_ENET_RXF ((ushort)0x0008) /* Full frame received */ +#define SCCE_ENET_BSY ((ushort)0x0004) /* All incoming buffers full */ +#define SCCE_ENET_TXB ((ushort)0x0002) /* A buffer was transmitted */ +#define SCCE_ENET_RXB ((ushort)0x0001) /* A buffer was received */ + +/* SCC Mode Register (PMSR) as used by Ethernet. +*/ +#define SCC_PMSR_HBC ((ushort)0x8000) /* Enable heartbeat */ +#define SCC_PMSR_FC ((ushort)0x4000) /* Force collision */ +#define SCC_PMSR_RSH ((ushort)0x2000) /* Receive short frames */ +#define SCC_PMSR_IAM ((ushort)0x1000) /* Check individual hash */ +#define SCC_PMSR_ENCRC ((ushort)0x0800) /* Ethernet CRC mode */ +#define SCC_PMSR_PRO ((ushort)0x0200) /* Promiscuous mode */ +#define SCC_PMSR_BRO ((ushort)0x0100) /* Catch broadcast pkts */ +#define SCC_PMSR_SBT ((ushort)0x0080) /* Special backoff timer */ +#define SCC_PMSR_LPB ((ushort)0x0040) /* Set Loopback mode */ +#define SCC_PMSR_SIP ((ushort)0x0020) /* Sample Input Pins */ +#define SCC_PMSR_LCW ((ushort)0x0010) /* Late collision window */ +#define SCC_PMSR_NIB22 ((ushort)0x000a) /* Start frame search */ +#define SCC_PMSR_FDE ((ushort)0x0001) /* Full duplex enable */ + +/* Buffer descriptor control/status used by Ethernet receive. +*/ +#define BD_ENET_RX_EMPTY ((ushort)0x8000) +#define BD_ENET_RX_WRAP ((ushort)0x2000) +#define BD_ENET_RX_INTR ((ushort)0x1000) +#define BD_ENET_RX_LAST ((ushort)0x0800) +#define BD_ENET_RX_FIRST ((ushort)0x0400) +#define BD_ENET_RX_MISS ((ushort)0x0100) +#define BD_ENET_RX_LG ((ushort)0x0020) +#define BD_ENET_RX_NO ((ushort)0x0010) +#define BD_ENET_RX_SH ((ushort)0x0008) +#define BD_ENET_RX_CR ((ushort)0x0004) +#define BD_ENET_RX_OV ((ushort)0x0002) +#define BD_ENET_RX_CL ((ushort)0x0001) +#define BD_ENET_RX_STATS ((ushort)0x013f) /* All status bits */ + +/* Buffer descriptor control/status used by Ethernet transmit. +*/ +#define BD_ENET_TX_READY ((ushort)0x8000) +#define BD_ENET_TX_PAD ((ushort)0x4000) +#define BD_ENET_TX_WRAP ((ushort)0x2000) +#define BD_ENET_TX_INTR ((ushort)0x1000) +#define BD_ENET_TX_LAST ((ushort)0x0800) +#define BD_ENET_TX_TC ((ushort)0x0400) +#define BD_ENET_TX_DEF ((ushort)0x0200) +#define BD_ENET_TX_HB ((ushort)0x0100) +#define BD_ENET_TX_LC ((ushort)0x0080) +#define BD_ENET_TX_RL ((ushort)0x0040) +#define BD_ENET_TX_RCMASK ((ushort)0x003c) +#define BD_ENET_TX_UN ((ushort)0x0002) +#define BD_ENET_TX_CSL ((ushort)0x0001) +#define BD_ENET_TX_STATS ((ushort)0x03ff) /* All status bits */ + +/* SCC as UART +*/ +typedef struct scc_uart { + sccp_t scc_genscc; + uint scc_res1; /* Reserved */ + uint scc_res2; /* Reserved */ + ushort scc_maxidl; /* Maximum idle chars */ + ushort scc_idlc; /* temp idle counter */ + ushort scc_brkcr; /* Break count register */ + ushort scc_parec; /* receive parity error counter */ + ushort scc_frmec; /* receive framing error counter */ + ushort scc_nosec; /* receive noise counter */ + ushort scc_brkec; /* receive break condition counter */ + ushort scc_brkln; /* last received break length */ + ushort scc_uaddr1; /* UART address character 1 */ + ushort scc_uaddr2; /* UART address character 2 */ + ushort scc_rtemp; /* Temp storage */ + ushort scc_toseq; /* Transmit out of sequence char */ + ushort scc_char1; /* control character 1 */ + ushort scc_char2; /* control character 2 */ + ushort scc_char3; /* control character 3 */ + ushort scc_char4; /* control character 4 */ + ushort scc_char5; /* control character 5 */ + ushort scc_char6; /* control character 6 */ + ushort scc_char7; /* control character 7 */ + ushort scc_char8; /* control character 8 */ + ushort scc_rccm; /* receive control character mask */ + ushort scc_rccr; /* receive control character register */ + ushort scc_rlbc; /* receive last break character */ +} scc_uart_t; + +/* SCC Event and Mask registers when it is used as a UART. +*/ +#define UART_SCCM_GLR ((ushort)0x1000) +#define UART_SCCM_GLT ((ushort)0x0800) +#define UART_SCCM_AB ((ushort)0x0200) +#define UART_SCCM_IDL ((ushort)0x0100) +#define UART_SCCM_GRA ((ushort)0x0080) +#define UART_SCCM_BRKE ((ushort)0x0040) +#define UART_SCCM_BRKS ((ushort)0x0020) +#define UART_SCCM_CCR ((ushort)0x0008) +#define UART_SCCM_BSY ((ushort)0x0004) +#define UART_SCCM_TX ((ushort)0x0002) +#define UART_SCCM_RX ((ushort)0x0001) + +/* The SCC PMSR when used as a UART. +*/ +#define SCU_PMSR_FLC ((ushort)0x8000) +#define SCU_PMSR_SL ((ushort)0x4000) +#define SCU_PMSR_CL ((ushort)0x3000) +#define SCU_PMSR_UM ((ushort)0x0c00) +#define SCU_PMSR_FRZ ((ushort)0x0200) +#define SCU_PMSR_RZS ((ushort)0x0100) +#define SCU_PMSR_SYN ((ushort)0x0080) +#define SCU_PMSR_DRT ((ushort)0x0040) +#define SCU_PMSR_PEN ((ushort)0x0010) +#define SCU_PMSR_RPM ((ushort)0x000c) +#define SCU_PMSR_REVP ((ushort)0x0008) +#define SCU_PMSR_TPM ((ushort)0x0003) +#define SCU_PMSR_TEVP ((ushort)0x0003) + +/* CPM Transparent mode SCC. + */ +typedef struct scc_trans { + sccp_t st_genscc; + uint st_cpres; /* Preset CRC */ + uint st_cmask; /* Constant mask for CRC */ +} scc_trans_t; + +#define BD_SCC_TX_LAST ((ushort)0x0800) + + + +/* CPM interrupts. There are nearly 32 interrupts generated by CPM + * channels or devices. All of these are presented to the PPC core + * as a single interrupt. The CPM interrupt handler dispatches its + * own handlers, in a similar fashion to the PPC core handler. We + * use the table as defined in the manuals (i.e. no special high + * priority and SCC1 == SCCa, etc...). + */ +/* #define CPMVEC_NR 32 */ +/* #define CPMVEC_PIO_PC15 ((ushort)0x1f) */ +/* #define CPMVEC_SCC1 ((ushort)0x1e) */ +/* #define CPMVEC_SCC2 ((ushort)0x1d) */ +/* #define CPMVEC_SCC3 ((ushort)0x1c) */ +/* #define CPMVEC_SCC4 ((ushort)0x1b) */ +/* #define CPMVEC_PIO_PC14 ((ushort)0x1a) */ +/* #define CPMVEC_TIMER1 ((ushort)0x19) */ +/* #define CPMVEC_PIO_PC13 ((ushort)0x18) */ +/* #define CPMVEC_PIO_PC12 ((ushort)0x17) */ +/* #define CPMVEC_SDMA_CB_ERR ((ushort)0x16) */ +/* #define CPMVEC_IDMA1 ((ushort)0x15) */ +/* #define CPMVEC_IDMA2 ((ushort)0x14) */ +/* #define CPMVEC_TIMER2 ((ushort)0x12) */ +/* #define CPMVEC_RISCTIMER ((ushort)0x11) */ +/* #define CPMVEC_I2C ((ushort)0x10) */ +/* #define CPMVEC_PIO_PC11 ((ushort)0x0f) */ +/* #define CPMVEC_PIO_PC10 ((ushort)0x0e) */ +/* #define CPMVEC_TIMER3 ((ushort)0x0c) */ +/* #define CPMVEC_PIO_PC9 ((ushort)0x0b) */ +/* #define CPMVEC_PIO_PC8 ((ushort)0x0a) */ +/* #define CPMVEC_PIO_PC7 ((ushort)0x09) */ +/* #define CPMVEC_TIMER4 ((ushort)0x07) */ +/* #define CPMVEC_PIO_PC6 ((ushort)0x06) */ +/* #define CPMVEC_SPI ((ushort)0x05) */ +/* #define CPMVEC_SMC1 ((ushort)0x04) */ +/* #define CPMVEC_SMC2 ((ushort)0x03) */ +/* #define CPMVEC_PIO_PC5 ((ushort)0x02) */ +/* #define CPMVEC_PIO_PC4 ((ushort)0x01) */ +/* #define CPMVEC_ERROR ((ushort)0x00) */ + +extern void cpm_install_handler(int vec, void (*handler)(void *), void *dev_id); + +/* CPM interrupt configuration vector. +*/ +#define CICR_SCD_SCC4 ((uint)0x00c00000) /* SCC4 @ SCCd */ +#define CICR_SCC_SCC3 ((uint)0x00200000) /* SCC3 @ SCCc */ +#define CICR_SCB_SCC2 ((uint)0x00040000) /* SCC2 @ SCCb */ +#define CICR_SCA_SCC1 ((uint)0x00000000) /* SCC1 @ SCCa */ +#define CICR_IRL_MASK ((uint)0x0000e000) /* Core interrupt */ +#define CICR_HP_MASK ((uint)0x00001f00) /* Hi-pri int. */ +#define CICR_IEN ((uint)0x00000080) /* Int. enable */ +#define CICR_SPS ((uint)0x00000001) /* SCC Spread */ +#endif /* __CPM_360__ */ diff --git a/arch/m68k/include/asm/contregs.h b/arch/m68k/include/asm/contregs.h new file mode 100644 index 00000000000..d1ea750bddf --- /dev/null +++ b/arch/m68k/include/asm/contregs.h @@ -0,0 +1,53 @@ +#ifndef _M68K_CONTREGS_H +#define _M68K_CONTREGS_H + +/* contregs.h: Addresses of registers in the ASI_CONTROL alternate address + * space. These are for the mmu's context register, etc. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +/* 3=sun3 + 4=sun4 (as in sun4 sysmaint student book) + c=sun4c (according to davem) */ + +#define AC_IDPROM 0x00000000 /* 34 ID PROM, R/O, byte, 32 bytes */ +#define AC_PAGEMAP 0x10000000 /* 3 Pagemap R/W, long */ +#define AC_SEGMAP 0x20000000 /* 3 Segment map, byte */ +#define AC_CONTEXT 0x30000000 /* 34c current mmu-context */ +#define AC_SENABLE 0x40000000 /* 34c system dvma/cache/reset enable reg*/ +#define AC_UDVMA_ENB 0x50000000 /* 34 Not used on Sun boards, byte */ +#define AC_BUS_ERROR 0x60000000 /* 34 Not cleared on read, byte. */ +#define AC_SYNC_ERR 0x60000000 /* c fault type */ +#define AC_SYNC_VA 0x60000004 /* c fault virtual address */ +#define AC_ASYNC_ERR 0x60000008 /* c asynchronous fault type */ +#define AC_ASYNC_VA 0x6000000c /* c async fault virtual address */ +#define AC_LEDS 0x70000000 /* 34 Zero turns on LEDs, byte */ +#define AC_CACHETAGS 0x80000000 /* 34c direct access to the VAC tags */ +#define AC_CACHEDDATA 0x90000000 /* 3 c direct access to the VAC data */ +#define AC_UDVMA_MAP 0xD0000000 /* 4 Not used on Sun boards, byte */ +#define AC_VME_VECTOR 0xE0000000 /* 4 For non-Autovector VME, byte */ +#define AC_BOOT_SCC 0xF0000000 /* 34 bypass to access Zilog 8530. byte.*/ + +/* s=Swift, h=Ross_HyperSPARC, v=TI_Viking, t=Tsunami, r=Ross_Cypress */ +#define AC_M_PCR 0x0000 /* shv Processor Control Reg */ +#define AC_M_CTPR 0x0100 /* shv Context Table Pointer Reg */ +#define AC_M_CXR 0x0200 /* shv Context Register */ +#define AC_M_SFSR 0x0300 /* shv Synchronous Fault Status Reg */ +#define AC_M_SFAR 0x0400 /* shv Synchronous Fault Address Reg */ +#define AC_M_AFSR 0x0500 /* hv Asynchronous Fault Status Reg */ +#define AC_M_AFAR 0x0600 /* hv Asynchronous Fault Address Reg */ +#define AC_M_RESET 0x0700 /* hv Reset Reg */ +#define AC_M_RPR 0x1000 /* hv Root Pointer Reg */ +#define AC_M_TSUTRCR 0x1000 /* s TLB Replacement Ctrl Reg */ +#define AC_M_IAPTP 0x1100 /* hv Instruction Access PTP */ +#define AC_M_DAPTP 0x1200 /* hv Data Access PTP */ +#define AC_M_ITR 0x1300 /* hv Index Tag Register */ +#define AC_M_TRCR 0x1400 /* hv TLB Replacement Control Reg */ +#define AC_M_SFSRX 0x1300 /* s Synch Fault Status Reg prim */ +#define AC_M_SFARX 0x1400 /* s Synch Fault Address Reg prim */ +#define AC_M_RPR1 0x1500 /* h Root Pointer Reg (entry 2) */ +#define AC_M_IAPTP1 0x1600 /* h Instruction Access PTP (entry 2) */ +#define AC_M_DAPTP1 0x1700 /* h Data Access PTP (entry 2) */ + +#endif /* _M68K_CONTREGS_H */ diff --git a/arch/m68k/include/asm/cputime.h b/arch/m68k/include/asm/cputime.h new file mode 100644 index 00000000000..c79c5e89230 --- /dev/null +++ b/arch/m68k/include/asm/cputime.h @@ -0,0 +1,6 @@ +#ifndef __M68K_CPUTIME_H +#define __M68K_CPUTIME_H + +#include + +#endif /* __M68K_CPUTIME_H */ diff --git a/arch/m68k/include/asm/current.h b/arch/m68k/include/asm/current.h new file mode 100644 index 00000000000..51b056dfaed --- /dev/null +++ b/arch/m68k/include/asm/current.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "current_no.h" +#else +#include "current_mm.h" +#endif diff --git a/arch/m68k/include/asm/current_mm.h b/arch/m68k/include/asm/current_mm.h new file mode 100644 index 00000000000..8de8f8ceda6 --- /dev/null +++ b/arch/m68k/include/asm/current_mm.h @@ -0,0 +1,6 @@ +#ifndef _M68K_CURRENT_H +#define _M68K_CURRENT_H + +register struct task_struct *current __asm__("%a2"); + +#endif /* !(_M68K_CURRENT_H) */ diff --git a/arch/m68k/include/asm/current_no.h b/arch/m68k/include/asm/current_no.h new file mode 100644 index 00000000000..53ee0f9f7ce --- /dev/null +++ b/arch/m68k/include/asm/current_no.h @@ -0,0 +1,24 @@ +#ifndef _M68KNOMMU_CURRENT_H +#define _M68KNOMMU_CURRENT_H +/* + * current.h + * (C) Copyright 2000, Lineo, David McCullough + * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) + * + * rather than dedicate a register (as the m68k source does), we + * just keep a global, we should probably just change it all to be + * current and lose _current_task. + */ + +#include + +struct task_struct; + +static inline struct task_struct *get_current(void) +{ + return(current_thread_info()->task); +} + +#define current get_current() + +#endif /* _M68KNOMMU_CURRENT_H */ diff --git a/arch/m68k/include/asm/dbg.h b/arch/m68k/include/asm/dbg.h new file mode 100644 index 00000000000..27af3270f67 --- /dev/null +++ b/arch/m68k/include/asm/dbg.h @@ -0,0 +1,6 @@ +#define DEBUG 1 +#ifdef CONFIG_COLDFIRE +#define BREAK asm volatile ("halt") +#else +#define BREAK *(volatile unsigned char *)0xdeadbee0 = 0 +#endif diff --git a/arch/m68k/include/asm/delay.h b/arch/m68k/include/asm/delay.h new file mode 100644 index 00000000000..d2598e3dd7b --- /dev/null +++ b/arch/m68k/include/asm/delay.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "delay_no.h" +#else +#include "delay_mm.h" +#endif diff --git a/arch/m68k/include/asm/delay_mm.h b/arch/m68k/include/asm/delay_mm.h new file mode 100644 index 00000000000..5ed92851bc6 --- /dev/null +++ b/arch/m68k/include/asm/delay_mm.h @@ -0,0 +1,57 @@ +#ifndef _M68K_DELAY_H +#define _M68K_DELAY_H + +#include + +/* + * Copyright (C) 1994 Hamish Macdonald + * + * Delay routines, using a pre-computed "loops_per_jiffy" value. + */ + +static inline void __delay(unsigned long loops) +{ + __asm__ __volatile__ ("1: subql #1,%0; jcc 1b" + : "=d" (loops) : "0" (loops)); +} + +extern void __bad_udelay(void); + +/* + * Use only for very small delays ( < 1 msec). Should probably use a + * lookup table, really, as the multiplications take much too long with + * short delays. This is a "reasonable" implementation, though (and the + * first constant multiplications gets optimized away if the delay is + * a constant) + */ +static inline void __const_udelay(unsigned long xloops) +{ + unsigned long tmp; + + __asm__ ("mulul %2,%0:%1" + : "=d" (xloops), "=d" (tmp) + : "d" (xloops), "1" (loops_per_jiffy)); + __delay(xloops * HZ); +} + +static inline void __udelay(unsigned long usecs) +{ + __const_udelay(usecs * 4295); /* 2**32 / 1000000 */ +} + +#define udelay(n) (__builtin_constant_p(n) ? \ + ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 4295)) : \ + __udelay(n)) + +static inline unsigned long muldiv(unsigned long a, unsigned long b, + unsigned long c) +{ + unsigned long tmp; + + __asm__ ("mulul %2,%0:%1; divul %3,%0:%1" + : "=d" (tmp), "=d" (a) + : "d" (b), "d" (c), "1" (a)); + return a; +} + +#endif /* defined(_M68K_DELAY_H) */ diff --git a/arch/m68k/include/asm/delay_no.h b/arch/m68k/include/asm/delay_no.h new file mode 100644 index 00000000000..55cbd6294ab --- /dev/null +++ b/arch/m68k/include/asm/delay_no.h @@ -0,0 +1,76 @@ +#ifndef _M68KNOMMU_DELAY_H +#define _M68KNOMMU_DELAY_H + +/* + * Copyright (C) 1994 Hamish Macdonald + * Copyright (C) 2004 Greg Ungerer + */ + +#include + +static inline void __delay(unsigned long loops) +{ +#if defined(CONFIG_COLDFIRE) + /* The coldfire runs this loop at significantly different speeds + * depending upon long word alignment or not. We'll pad it to + * long word alignment which is the faster version. + * The 0x4a8e is of course a 'tstl %fp' instruction. This is better + * than using a NOP (0x4e71) instruction because it executes in one + * cycle not three and doesn't allow for an arbitary delay waiting + * for bus cycles to finish. Also fp/a6 isn't likely to cause a + * stall waiting for the register to become valid if such is added + * to the coldfire at some stage. + */ + __asm__ __volatile__ ( ".balignw 4, 0x4a8e\n\t" + "1: subql #1, %0\n\t" + "jcc 1b" + : "=d" (loops) : "0" (loops)); +#else + __asm__ __volatile__ ( "1: subql #1, %0\n\t" + "jcc 1b" + : "=d" (loops) : "0" (loops)); +#endif +} + +/* + * Ideally we use a 32*32->64 multiply to calculate the number of + * loop iterations, but the older standard 68k and ColdFire do not + * have this instruction. So for them we have a clsoe approximation + * loop using 32*32->32 multiplies only. This calculation based on + * the ARM version of delay. + * + * We want to implement: + * + * loops = (usecs * 0x10c6 * HZ * loops_per_jiffy) / 2^32 + */ + +#define HZSCALE (268435456 / (1000000/HZ)) + +extern unsigned long loops_per_jiffy; + +static inline void _udelay(unsigned long usecs) +{ +#if defined(CONFIG_M68328) || defined(CONFIG_M68EZ328) || \ + defined(CONFIG_M68VZ328) || defined(CONFIG_M68360) || \ + defined(CONFIG_COLDFIRE) + __delay((((usecs * HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6); +#else + unsigned long tmp; + + usecs *= 4295; /* 2**32 / 1000000 */ + __asm__ ("mulul %2,%0:%1" + : "=d" (usecs), "=d" (tmp) + : "d" (usecs), "1" (loops_per_jiffy*HZ)); + __delay(usecs); +#endif +} + +/* + * Moved the udelay() function into library code, no longer inlined. + * I had to change the algorithm because we are overflowing now on + * the faster ColdFire parts. The code is a little bigger, so it makes + * sense to library it. + */ +extern void udelay(unsigned long usecs); + +#endif /* defined(_M68KNOMMU_DELAY_H) */ diff --git a/arch/m68k/include/asm/device.h b/arch/m68k/include/asm/device.h new file mode 100644 index 00000000000..d8f9872b0e2 --- /dev/null +++ b/arch/m68k/include/asm/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/arch/m68k/include/asm/div64.h b/arch/m68k/include/asm/div64.h new file mode 100644 index 00000000000..d211d9f5427 --- /dev/null +++ b/arch/m68k/include/asm/div64.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "div64_no.h" +#else +#include "div64_mm.h" +#endif diff --git a/arch/m68k/include/asm/div64_mm.h b/arch/m68k/include/asm/div64_mm.h new file mode 100644 index 00000000000..8243c931b5c --- /dev/null +++ b/arch/m68k/include/asm/div64_mm.h @@ -0,0 +1,28 @@ +#ifndef _M68K_DIV64_H +#define _M68K_DIV64_H + +#include + +/* n = n / base; return rem; */ + +#define do_div(n, base) ({ \ + union { \ + unsigned long n32[2]; \ + unsigned long long n64; \ + } __n; \ + unsigned long __rem, __upper; \ + \ + __n.n64 = (n); \ + if ((__upper = __n.n32[0])) { \ + asm ("divul.l %2,%1:%0" \ + : "=d" (__n.n32[0]), "=d" (__upper) \ + : "d" (base), "0" (__n.n32[0])); \ + } \ + asm ("divu.l %2,%1:%0" \ + : "=d" (__n.n32[1]), "=d" (__rem) \ + : "d" (base), "1" (__upper), "0" (__n.n32[1])); \ + (n) = __n.n64; \ + __rem; \ +}) + +#endif /* _M68K_DIV64_H */ diff --git a/arch/m68k/include/asm/div64_no.h b/arch/m68k/include/asm/div64_no.h new file mode 100644 index 00000000000..6cd978cefb2 --- /dev/null +++ b/arch/m68k/include/asm/div64_no.h @@ -0,0 +1 @@ +#include diff --git a/arch/m68k/include/asm/dma-mapping.h b/arch/m68k/include/asm/dma-mapping.h new file mode 100644 index 00000000000..f4a4c7638f8 --- /dev/null +++ b/arch/m68k/include/asm/dma-mapping.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "dma-mapping_no.h" +#else +#include "dma-mapping_mm.h" +#endif diff --git a/arch/m68k/include/asm/dma-mapping_mm.h b/arch/m68k/include/asm/dma-mapping_mm.h new file mode 100644 index 00000000000..26f505488c1 --- /dev/null +++ b/arch/m68k/include/asm/dma-mapping_mm.h @@ -0,0 +1,112 @@ +#ifndef _M68K_DMA_MAPPING_H +#define _M68K_DMA_MAPPING_H + +#include + +struct scatterlist; + +#ifndef CONFIG_MMU_SUN3 +static inline int dma_supported(struct device *dev, u64 mask) +{ + return 1; +} + +static inline int dma_set_mask(struct device *dev, u64 mask) +{ + return 0; +} + +static inline int dma_get_cache_alignment(void) +{ + return 1 << L1_CACHE_SHIFT; +} + +static inline int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) +{ + return 0; +} + +extern void *dma_alloc_coherent(struct device *, size_t, + dma_addr_t *, gfp_t); +extern void dma_free_coherent(struct device *, size_t, + void *, dma_addr_t); + +static inline void *dma_alloc_noncoherent(struct device *dev, size_t size, + dma_addr_t *handle, gfp_t flag) +{ + return dma_alloc_coherent(dev, size, handle, flag); +} +static inline void dma_free_noncoherent(struct device *dev, size_t size, + void *addr, dma_addr_t handle) +{ + dma_free_coherent(dev, size, addr, handle); +} +static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, + enum dma_data_direction dir) +{ + /* we use coherent allocation, so not much to do here. */ +} + +extern dma_addr_t dma_map_single(struct device *, void *, size_t, + enum dma_data_direction); +static inline void dma_unmap_single(struct device *dev, dma_addr_t addr, + size_t size, enum dma_data_direction dir) +{ +} + +extern dma_addr_t dma_map_page(struct device *, struct page *, + unsigned long, size_t size, + enum dma_data_direction); +static inline void dma_unmap_page(struct device *dev, dma_addr_t address, + size_t size, enum dma_data_direction dir) +{ +} + +extern int dma_map_sg(struct device *, struct scatterlist *, int, + enum dma_data_direction); +static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg, + int nhwentries, enum dma_data_direction dir) +{ +} + +extern void dma_sync_single_for_device(struct device *, dma_addr_t, size_t, + enum dma_data_direction); +extern void dma_sync_sg_for_device(struct device *, struct scatterlist *, int, + enum dma_data_direction); + +static inline void dma_sync_single_range_for_device(struct device *dev, + dma_addr_t dma_handle, unsigned long offset, size_t size, + enum dma_data_direction direction) +{ + /* just sync everything for now */ + dma_sync_single_for_device(dev, dma_handle, offset + size, direction); +} + +static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, + size_t size, enum dma_data_direction dir) +{ +} + +static inline void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir) +{ +} + +static inline void dma_sync_single_range_for_cpu(struct device *dev, + dma_addr_t dma_handle, unsigned long offset, size_t size, + enum dma_data_direction direction) +{ + /* just sync everything for now */ + dma_sync_single_for_cpu(dev, dma_handle, offset + size, direction); +} + +static inline int dma_mapping_error(struct device *dev, dma_addr_t handle) +{ + return 0; +} + +#else +#include +#endif + +#endif /* _M68K_DMA_MAPPING_H */ diff --git a/arch/m68k/include/asm/dma-mapping_no.h b/arch/m68k/include/asm/dma-mapping_no.h new file mode 100644 index 00000000000..6aeab18e58b --- /dev/null +++ b/arch/m68k/include/asm/dma-mapping_no.h @@ -0,0 +1,10 @@ +#ifndef _M68KNOMMU_DMA_MAPPING_H +#define _M68KNOMMU_DMA_MAPPING_H + +#ifdef CONFIG_PCI +#include +#else +#include +#endif + +#endif /* _M68KNOMMU_DMA_MAPPING_H */ diff --git a/arch/m68k/include/asm/dma.h b/arch/m68k/include/asm/dma.h new file mode 100644 index 00000000000..b82e660cf1c --- /dev/null +++ b/arch/m68k/include/asm/dma.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "dma_no.h" +#else +#include "dma_mm.h" +#endif diff --git a/arch/m68k/include/asm/dma_mm.h b/arch/m68k/include/asm/dma_mm.h new file mode 100644 index 00000000000..4240fbc946f --- /dev/null +++ b/arch/m68k/include/asm/dma_mm.h @@ -0,0 +1,16 @@ +#ifndef _M68K_DMA_H +#define _M68K_DMA_H 1 + + +/* it's useless on the m68k, but unfortunately needed by the new + bootmem allocator (but this should do it for this) */ +#define MAX_DMA_ADDRESS PAGE_OFFSET + +#define MAX_DMA_CHANNELS 8 + +extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ +extern void free_dma(unsigned int dmanr); /* release it again */ + +#define isa_dma_bridge_buggy (0) + +#endif /* _M68K_DMA_H */ diff --git a/arch/m68k/include/asm/dma_no.h b/arch/m68k/include/asm/dma_no.h new file mode 100644 index 00000000000..939a0205621 --- /dev/null +++ b/arch/m68k/include/asm/dma_no.h @@ -0,0 +1,494 @@ +#ifndef _M68K_DMA_H +#define _M68K_DMA_H 1 + +//#define DMA_DEBUG 1 + + +#ifdef CONFIG_COLDFIRE +/* + * ColdFire DMA Model: + * ColdFire DMA supports two forms of DMA: Single and Dual address. Single + * address mode emits a source address, and expects that the device will either + * pick up the data (DMA READ) or source data (DMA WRITE). This implies that + * the device will place data on the correct byte(s) of the data bus, as the + * memory transactions are always 32 bits. This implies that only 32 bit + * devices will find single mode transfers useful. Dual address DMA mode + * performs two cycles: source read and destination write. ColdFire will + * align the data so that the device will always get the correct bytes, thus + * is useful for 8 and 16 bit devices. This is the mode that is supported + * below. + * + * AUG/22/2000 : added support for 32-bit Dual-Address-Mode (K) 2000 + * Oliver Kamphenkel (O.Kamphenkel@tu-bs.de) + * + * AUG/25/2000 : addad support for 8, 16 and 32-bit Single-Address-Mode (K)2000 + * Oliver Kamphenkel (O.Kamphenkel@tu-bs.de) + * + * APR/18/2002 : added proper support for MCF5272 DMA controller. + * Arthur Shipkowski (art@videon-central.com) + */ + +#include +#include +#include + +/* + * Set number of channels of DMA on ColdFire for different implementations. + */ +#if defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) || \ + defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) +#define MAX_M68K_DMA_CHANNELS 4 +#elif defined(CONFIG_M5272) +#define MAX_M68K_DMA_CHANNELS 1 +#elif defined(CONFIG_M532x) +#define MAX_M68K_DMA_CHANNELS 0 +#else +#define MAX_M68K_DMA_CHANNELS 2 +#endif + +extern unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS]; +extern unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS]; + +#if !defined(CONFIG_M5272) +#define DMA_MODE_WRITE_BIT 0x01 /* Memory/IO to IO/Memory select */ +#define DMA_MODE_WORD_BIT 0x02 /* 8 or 16 bit transfers */ +#define DMA_MODE_LONG_BIT 0x04 /* or 32 bit transfers */ +#define DMA_MODE_SINGLE_BIT 0x08 /* single-address-mode */ + +/* I/O to memory, 8 bits, mode */ +#define DMA_MODE_READ 0 +/* memory to I/O, 8 bits, mode */ +#define DMA_MODE_WRITE 1 +/* I/O to memory, 16 bits, mode */ +#define DMA_MODE_READ_WORD 2 +/* memory to I/O, 16 bits, mode */ +#define DMA_MODE_WRITE_WORD 3 +/* I/O to memory, 32 bits, mode */ +#define DMA_MODE_READ_LONG 4 +/* memory to I/O, 32 bits, mode */ +#define DMA_MODE_WRITE_LONG 5 +/* I/O to memory, 8 bits, single-address-mode */ +#define DMA_MODE_READ_SINGLE 8 +/* memory to I/O, 8 bits, single-address-mode */ +#define DMA_MODE_WRITE_SINGLE 9 +/* I/O to memory, 16 bits, single-address-mode */ +#define DMA_MODE_READ_WORD_SINGLE 10 +/* memory to I/O, 16 bits, single-address-mode */ +#define DMA_MODE_WRITE_WORD_SINGLE 11 +/* I/O to memory, 32 bits, single-address-mode */ +#define DMA_MODE_READ_LONG_SINGLE 12 +/* memory to I/O, 32 bits, single-address-mode */ +#define DMA_MODE_WRITE_LONG_SINGLE 13 + +#else /* CONFIG_M5272 is defined */ + +/* Source static-address mode */ +#define DMA_MODE_SRC_SA_BIT 0x01 +/* Two bits to select between all four modes */ +#define DMA_MODE_SSIZE_MASK 0x06 +/* Offset to shift bits in */ +#define DMA_MODE_SSIZE_OFF 0x01 +/* Destination static-address mode */ +#define DMA_MODE_DES_SA_BIT 0x10 +/* Two bits to select between all four modes */ +#define DMA_MODE_DSIZE_MASK 0x60 +/* Offset to shift bits in */ +#define DMA_MODE_DSIZE_OFF 0x05 +/* Size modifiers */ +#define DMA_MODE_SIZE_LONG 0x00 +#define DMA_MODE_SIZE_BYTE 0x01 +#define DMA_MODE_SIZE_WORD 0x02 +#define DMA_MODE_SIZE_LINE 0x03 + +/* + * Aliases to help speed quick ports; these may be suboptimal, however. They + * do not include the SINGLE mode modifiers since the MCF5272 does not have a + * mode where the device is in control of its addressing. + */ + +/* I/O to memory, 8 bits, mode */ +#define DMA_MODE_READ ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT) +/* memory to I/O, 8 bits, mode */ +#define DMA_MODE_WRITE ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT) +/* I/O to memory, 16 bits, mode */ +#define DMA_MODE_READ_WORD ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT) +/* memory to I/O, 16 bits, mode */ +#define DMA_MODE_WRITE_WORD ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT) +/* I/O to memory, 32 bits, mode */ +#define DMA_MODE_READ_LONG ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT) +/* memory to I/O, 32 bits, mode */ +#define DMA_MODE_WRITE_LONG ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT) + +#endif /* !defined(CONFIG_M5272) */ + +#if !defined(CONFIG_M5272) +/* enable/disable a specific DMA channel */ +static __inline__ void enable_dma(unsigned int dmanr) +{ + volatile unsigned short *dmawp; + +#ifdef DMA_DEBUG + printk("enable_dma(dmanr=%d)\n", dmanr); +#endif + + dmawp = (unsigned short *) dma_base_addr[dmanr]; + dmawp[MCFDMA_DCR] |= MCFDMA_DCR_EEXT; +} + +static __inline__ void disable_dma(unsigned int dmanr) +{ + volatile unsigned short *dmawp; + volatile unsigned char *dmapb; + +#ifdef DMA_DEBUG + printk("disable_dma(dmanr=%d)\n", dmanr); +#endif + + dmawp = (unsigned short *) dma_base_addr[dmanr]; + dmapb = (unsigned char *) dma_base_addr[dmanr]; + + /* Turn off external requests, and stop any DMA in progress */ + dmawp[MCFDMA_DCR] &= ~MCFDMA_DCR_EEXT; + dmapb[MCFDMA_DSR] = MCFDMA_DSR_DONE; +} + +/* + * Clear the 'DMA Pointer Flip Flop'. + * Write 0 for LSB/MSB, 1 for MSB/LSB access. + * Use this once to initialize the FF to a known state. + * After that, keep track of it. :-) + * --- In order to do that, the DMA routines below should --- + * --- only be used while interrupts are disabled! --- + * + * This is a NOP for ColdFire. Provide a stub for compatibility. + */ +static __inline__ void clear_dma_ff(unsigned int dmanr) +{ +} + +/* set mode (above) for a specific DMA channel */ +static __inline__ void set_dma_mode(unsigned int dmanr, char mode) +{ + + volatile unsigned char *dmabp; + volatile unsigned short *dmawp; + +#ifdef DMA_DEBUG + printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode); +#endif + + dmabp = (unsigned char *) dma_base_addr[dmanr]; + dmawp = (unsigned short *) dma_base_addr[dmanr]; + + // Clear config errors + dmabp[MCFDMA_DSR] = MCFDMA_DSR_DONE; + + // Set command register + dmawp[MCFDMA_DCR] = + MCFDMA_DCR_INT | // Enable completion irq + MCFDMA_DCR_CS | // Force one xfer per request + MCFDMA_DCR_AA | // Enable auto alignment + // single-address-mode + ((mode & DMA_MODE_SINGLE_BIT) ? MCFDMA_DCR_SAA : 0) | + // sets s_rw (-> r/w) high if Memory to I/0 + ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_S_RW : 0) | + // Memory to I/O or I/O to Memory + ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_SINC : MCFDMA_DCR_DINC) | + // 32 bit, 16 bit or 8 bit transfers + ((mode & DMA_MODE_WORD_BIT) ? MCFDMA_DCR_SSIZE_WORD : + ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_SSIZE_LONG : + MCFDMA_DCR_SSIZE_BYTE)) | + ((mode & DMA_MODE_WORD_BIT) ? MCFDMA_DCR_DSIZE_WORD : + ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_DSIZE_LONG : + MCFDMA_DCR_DSIZE_BYTE)); + +#ifdef DEBUG_DMA + printk("%s(%d): dmanr=%d DSR[%x]=%x DCR[%x]=%x\n", __FILE__, __LINE__, + dmanr, (int) &dmabp[MCFDMA_DSR], dmabp[MCFDMA_DSR], + (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR]); +#endif +} + +/* Set transfer address for specific DMA channel */ +static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) +{ + volatile unsigned short *dmawp; + volatile unsigned int *dmalp; + +#ifdef DMA_DEBUG + printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a); +#endif + + dmawp = (unsigned short *) dma_base_addr[dmanr]; + dmalp = (unsigned int *) dma_base_addr[dmanr]; + + // Determine which address registers are used for memory/device accesses + if (dmawp[MCFDMA_DCR] & MCFDMA_DCR_SINC) { + // Source incrementing, must be memory + dmalp[MCFDMA_SAR] = a; + // Set dest address, must be device + dmalp[MCFDMA_DAR] = dma_device_address[dmanr]; + } else { + // Destination incrementing, must be memory + dmalp[MCFDMA_DAR] = a; + // Set source address, must be device + dmalp[MCFDMA_SAR] = dma_device_address[dmanr]; + } + +#ifdef DEBUG_DMA + printk("%s(%d): dmanr=%d DCR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n", + __FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR], + (int) &dmalp[MCFDMA_SAR], dmalp[MCFDMA_SAR], + (int) &dmalp[MCFDMA_DAR], dmalp[MCFDMA_DAR]); +#endif +} + +/* + * Specific for Coldfire - sets device address. + * Should be called after the mode set call, and before set DMA address. + */ +static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a) +{ +#ifdef DMA_DEBUG + printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a); +#endif + + dma_device_address[dmanr] = a; +} + +/* + * NOTE 2: "count" represents _bytes_. + */ +static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) +{ + volatile unsigned short *dmawp; + +#ifdef DMA_DEBUG + printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count); +#endif + + dmawp = (unsigned short *) dma_base_addr[dmanr]; + dmawp[MCFDMA_BCR] = (unsigned short)count; +} + +/* + * Get DMA residue count. After a DMA transfer, this + * should return zero. Reading this while a DMA transfer is + * still in progress will return unpredictable results. + * Otherwise, it returns the number of _bytes_ left to transfer. + */ +static __inline__ int get_dma_residue(unsigned int dmanr) +{ + volatile unsigned short *dmawp; + unsigned short count; + +#ifdef DMA_DEBUG + printk("get_dma_residue(dmanr=%d)\n", dmanr); +#endif + + dmawp = (unsigned short *) dma_base_addr[dmanr]; + count = dmawp[MCFDMA_BCR]; + return((int) count); +} +#else /* CONFIG_M5272 is defined */ + +/* + * The MCF5272 DMA controller is very different than the controller defined above + * in terms of register mapping. For instance, with the exception of the 16-bit + * interrupt register (IRQ#85, for reference), all of the registers are 32-bit. + * + * The big difference, however, is the lack of device-requested DMA. All modes + * are dual address transfer, and there is no 'device' setup or direction bit. + * You can DMA between a device and memory, between memory and memory, or even between + * two devices directly, with any combination of incrementing and non-incrementing + * addresses you choose. This puts a crimp in distinguishing between the 'device + * address' set up by set_dma_device_addr. + * + * Therefore, there are two options. One is to use set_dma_addr and set_dma_device_addr, + * which will act exactly as above in -- it will look to see if the source is set to + * autoincrement, and if so it will make the source use the set_dma_addr value and the + * destination the set_dma_device_addr value. Otherwise the source will be set to the + * set_dma_device_addr value and the destination will get the set_dma_addr value. + * + * The other is to use the provided set_dma_src_addr and set_dma_dest_addr functions + * and make it explicit. Depending on what you're doing, one of these two should work + * for you, but don't mix them in the same transfer setup. + */ + +/* enable/disable a specific DMA channel */ +static __inline__ void enable_dma(unsigned int dmanr) +{ + volatile unsigned int *dmalp; + +#ifdef DMA_DEBUG + printk("enable_dma(dmanr=%d)\n", dmanr); +#endif + + dmalp = (unsigned int *) dma_base_addr[dmanr]; + dmalp[MCFDMA_DMR] |= MCFDMA_DMR_EN; +} + +static __inline__ void disable_dma(unsigned int dmanr) +{ + volatile unsigned int *dmalp; + +#ifdef DMA_DEBUG + printk("disable_dma(dmanr=%d)\n", dmanr); +#endif + + dmalp = (unsigned int *) dma_base_addr[dmanr]; + + /* Turn off external requests, and stop any DMA in progress */ + dmalp[MCFDMA_DMR] &= ~MCFDMA_DMR_EN; + dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET; +} + +/* + * Clear the 'DMA Pointer Flip Flop'. + * Write 0 for LSB/MSB, 1 for MSB/LSB access. + * Use this once to initialize the FF to a known state. + * After that, keep track of it. :-) + * --- In order to do that, the DMA routines below should --- + * --- only be used while interrupts are disabled! --- + * + * This is a NOP for ColdFire. Provide a stub for compatibility. + */ +static __inline__ void clear_dma_ff(unsigned int dmanr) +{ +} + +/* set mode (above) for a specific DMA channel */ +static __inline__ void set_dma_mode(unsigned int dmanr, char mode) +{ + + volatile unsigned int *dmalp; + volatile unsigned short *dmawp; + +#ifdef DMA_DEBUG + printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode); +#endif + dmalp = (unsigned int *) dma_base_addr[dmanr]; + dmawp = (unsigned short *) dma_base_addr[dmanr]; + + // Clear config errors + dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET; + + // Set command register + dmalp[MCFDMA_DMR] = + MCFDMA_DMR_RQM_DUAL | // Mandatory Request Mode setting + MCFDMA_DMR_DSTT_SD | // Set up addressing types; set to supervisor-data. + MCFDMA_DMR_SRCT_SD | // Set up addressing types; set to supervisor-data. + // source static-address-mode + ((mode & DMA_MODE_SRC_SA_BIT) ? MCFDMA_DMR_SRCM_SA : MCFDMA_DMR_SRCM_IA) | + // dest static-address-mode + ((mode & DMA_MODE_DES_SA_BIT) ? MCFDMA_DMR_DSTM_SA : MCFDMA_DMR_DSTM_IA) | + // burst, 32 bit, 16 bit or 8 bit transfers are separately configurable on the MCF5272 + (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_DSTS_OFF) | + (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_SRCS_OFF); + + dmawp[MCFDMA_DIR] |= MCFDMA_DIR_ASCEN; /* Enable completion interrupts */ + +#ifdef DEBUG_DMA + printk("%s(%d): dmanr=%d DMR[%x]=%x DIR[%x]=%x\n", __FILE__, __LINE__, + dmanr, (int) &dmalp[MCFDMA_DMR], dmabp[MCFDMA_DMR], + (int) &dmawp[MCFDMA_DIR], dmawp[MCFDMA_DIR]); +#endif +} + +/* Set transfer address for specific DMA channel */ +static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) +{ + volatile unsigned int *dmalp; + +#ifdef DMA_DEBUG + printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a); +#endif + + dmalp = (unsigned int *) dma_base_addr[dmanr]; + + // Determine which address registers are used for memory/device accesses + if (dmalp[MCFDMA_DMR] & MCFDMA_DMR_SRCM) { + // Source incrementing, must be memory + dmalp[MCFDMA_DSAR] = a; + // Set dest address, must be device + dmalp[MCFDMA_DDAR] = dma_device_address[dmanr]; + } else { + // Destination incrementing, must be memory + dmalp[MCFDMA_DDAR] = a; + // Set source address, must be device + dmalp[MCFDMA_DSAR] = dma_device_address[dmanr]; + } + +#ifdef DEBUG_DMA + printk("%s(%d): dmanr=%d DMR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n", + __FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DMR], dmawp[MCFDMA_DMR], + (int) &dmalp[MCFDMA_DSAR], dmalp[MCFDMA_DSAR], + (int) &dmalp[MCFDMA_DDAR], dmalp[MCFDMA_DDAR]); +#endif +} + +/* + * Specific for Coldfire - sets device address. + * Should be called after the mode set call, and before set DMA address. + */ +static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a) +{ +#ifdef DMA_DEBUG + printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a); +#endif + + dma_device_address[dmanr] = a; +} + +/* + * NOTE 2: "count" represents _bytes_. + * + * NOTE 3: While a 32-bit register, "count" is only a maximum 24-bit value. + */ +static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) +{ + volatile unsigned int *dmalp; + +#ifdef DMA_DEBUG + printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count); +#endif + + dmalp = (unsigned int *) dma_base_addr[dmanr]; + dmalp[MCFDMA_DBCR] = count; +} + +/* + * Get DMA residue count. After a DMA transfer, this + * should return zero. Reading this while a DMA transfer is + * still in progress will return unpredictable results. + * Otherwise, it returns the number of _bytes_ left to transfer. + */ +static __inline__ int get_dma_residue(unsigned int dmanr) +{ + volatile unsigned int *dmalp; + unsigned int count; + +#ifdef DMA_DEBUG + printk("get_dma_residue(dmanr=%d)\n", dmanr); +#endif + + dmalp = (unsigned int *) dma_base_addr[dmanr]; + count = dmalp[MCFDMA_DBCR]; + return(count); +} + +#endif /* !defined(CONFIG_M5272) */ +#endif /* CONFIG_COLDFIRE */ + +#define MAX_DMA_CHANNELS 8 + +/* Don't define MAX_DMA_ADDRESS; it's useless on the m68k/coldfire and any + occurrence should be flagged as an error. */ +/* under 2.4 it is actually needed by the new bootmem allocator */ +#define MAX_DMA_ADDRESS PAGE_OFFSET + +/* These are in kernel/dma.c: */ +extern int request_dma(unsigned int dmanr, const char *device_id); /* reserve a DMA channel */ +extern void free_dma(unsigned int dmanr); /* release it again */ + +#endif /* _M68K_DMA_H */ diff --git a/arch/m68k/include/asm/dsp56k.h b/arch/m68k/include/asm/dsp56k.h new file mode 100644 index 00000000000..2d8c0c9f794 --- /dev/null +++ b/arch/m68k/include/asm/dsp56k.h @@ -0,0 +1,35 @@ +/* + * linux/include/asm-m68k/dsp56k.h - defines and declarations for + * DSP56k device driver + * + * Copyright (C) 1996,1997 Fredrik Noring, lars brinkhoff & Tomas Berndtsson + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + + +/* Used for uploading DSP binary code */ +struct dsp56k_upload { + int len; + char __user *bin; +}; + +/* For the DSP host flags */ +struct dsp56k_host_flags { + int dir; /* Bit field. 1 = write output bit, 0 = do nothing. + * 0x0000 means reading only, 0x0011 means + * writing the bits stored in `out' on HF0 and HF1. + * Note that HF2 and HF3 can only be read. + */ + int out; /* Bit field like above. */ + int status; /* Host register's current state is returned */ +}; + +/* ioctl command codes */ +#define DSP56K_UPLOAD 1 /* Upload DSP binary program */ +#define DSP56K_SET_TX_WSIZE 2 /* Host transmit word size (1-4) */ +#define DSP56K_SET_RX_WSIZE 3 /* Host receive word size (1-4) */ +#define DSP56K_HOST_FLAGS 4 /* Host flag registers */ +#define DSP56K_HOST_CMD 5 /* Trig Host Command (0-31) */ diff --git a/arch/m68k/include/asm/dvma.h b/arch/m68k/include/asm/dvma.h new file mode 100644 index 00000000000..890bbf7e775 --- /dev/null +++ b/arch/m68k/include/asm/dvma.h @@ -0,0 +1,240 @@ +/* + * include/asm-m68k/dma.h + * + * Copyright 1995 (C) David S. Miller (davem@caip.rutgers.edu) + * + * Hacked to fit Sun3x needs by Thomas Bogendoerfer + */ + +#ifndef __M68K_DVMA_H +#define __M68K_DVMA_H + + +#define DVMA_PAGE_SHIFT 13 +#define DVMA_PAGE_SIZE (1UL << DVMA_PAGE_SHIFT) +#define DVMA_PAGE_MASK (~(DVMA_PAGE_SIZE-1)) +#define DVMA_PAGE_ALIGN(addr) ALIGN(addr, DVMA_PAGE_SIZE) + +extern void dvma_init(void); +extern int dvma_map_iommu(unsigned long kaddr, unsigned long baddr, + int len); + +#define dvma_malloc(x) dvma_malloc_align(x, 0) +#define dvma_map(x, y) dvma_map_align(x, y, 0) +#define dvma_map_vme(x, y) (dvma_map(x, y) & 0xfffff) +#define dvma_map_align_vme(x, y, z) (dvma_map_align (x, y, z) & 0xfffff) +extern unsigned long dvma_map_align(unsigned long kaddr, int len, + int align); +extern void *dvma_malloc_align(unsigned long len, unsigned long align); + +extern void dvma_unmap(void *baddr); +extern void dvma_free(void *vaddr); + + +#ifdef CONFIG_SUN3 +/* sun3 dvma page support */ + +/* memory and pmegs potentially reserved for dvma */ +#define DVMA_PMEG_START 10 +#define DVMA_PMEG_END 16 +#define DVMA_START 0xf00000 +#define DVMA_END 0xfe0000 +#define DVMA_SIZE (DVMA_END-DVMA_START) +#define IOMMU_TOTAL_ENTRIES 128 +#define IOMMU_ENTRIES 120 + +/* empirical kludge -- dvma regions only seem to work right on 0x10000 + byte boundaries */ +#define DVMA_REGION_SIZE 0x10000 +#define DVMA_ALIGN(addr) (((addr)+DVMA_REGION_SIZE-1) & \ + ~(DVMA_REGION_SIZE-1)) + +/* virt <-> phys conversions */ +#define dvma_vtop(x) ((unsigned long)(x) & 0xffffff) +#define dvma_ptov(x) ((unsigned long)(x) | 0xf000000) +#define dvma_vtovme(x) ((unsigned long)(x) & 0x00fffff) +#define dvma_vmetov(x) ((unsigned long)(x) | 0xff00000) +#define dvma_vtob(x) dvma_vtop(x) +#define dvma_btov(x) dvma_ptov(x) + +static inline int dvma_map_cpu(unsigned long kaddr, unsigned long vaddr, + int len) +{ + return 0; +} + +#else /* Sun3x */ + +/* sun3x dvma page support */ + +#define DVMA_START 0x0 +#define DVMA_END 0xf00000 +#define DVMA_SIZE (DVMA_END-DVMA_START) +#define IOMMU_TOTAL_ENTRIES 2048 +/* the prom takes the top meg */ +#define IOMMU_ENTRIES (IOMMU_TOTAL_ENTRIES - 0x80) + +#define dvma_vtob(x) ((unsigned long)(x) & 0x00ffffff) +#define dvma_btov(x) ((unsigned long)(x) | 0xff000000) + +extern int dvma_map_cpu(unsigned long kaddr, unsigned long vaddr, int len); + + + +/* everything below this line is specific to dma used for the onboard + ESP scsi on sun3x */ + +/* Structure to describe the current status of DMA registers on the Sparc */ +struct sparc_dma_registers { + __volatile__ unsigned long cond_reg; /* DMA condition register */ + __volatile__ unsigned long st_addr; /* Start address of this transfer */ + __volatile__ unsigned long cnt; /* How many bytes to transfer */ + __volatile__ unsigned long dma_test; /* DMA test register */ +}; + +/* DVMA chip revisions */ +enum dvma_rev { + dvmarev0, + dvmaesc1, + dvmarev1, + dvmarev2, + dvmarev3, + dvmarevplus, + dvmahme +}; + +#define DMA_HASCOUNT(rev) ((rev)==dvmaesc1) + +/* Linux DMA information structure, filled during probe. */ +struct Linux_SBus_DMA { + struct Linux_SBus_DMA *next; + struct linux_sbus_device *SBus_dev; + struct sparc_dma_registers *regs; + + /* Status, misc info */ + int node; /* Prom node for this DMA device */ + int running; /* Are we doing DMA now? */ + int allocated; /* Are we "owned" by anyone yet? */ + + /* Transfer information. */ + unsigned long addr; /* Start address of current transfer */ + int nbytes; /* Size of current transfer */ + int realbytes; /* For splitting up large transfers, etc. */ + + /* DMA revision */ + enum dvma_rev revision; +}; + +extern struct Linux_SBus_DMA *dma_chain; + +/* Broken hardware... */ +#define DMA_ISBROKEN(dma) ((dma)->revision == dvmarev1) +#define DMA_ISESC1(dma) ((dma)->revision == dvmaesc1) + +/* Fields in the cond_reg register */ +/* First, the version identification bits */ +#define DMA_DEVICE_ID 0xf0000000 /* Device identification bits */ +#define DMA_VERS0 0x00000000 /* Sunray DMA version */ +#define DMA_ESCV1 0x40000000 /* DMA ESC Version 1 */ +#define DMA_VERS1 0x80000000 /* DMA rev 1 */ +#define DMA_VERS2 0xa0000000 /* DMA rev 2 */ +#define DMA_VERHME 0xb0000000 /* DMA hme gate array */ +#define DMA_VERSPLUS 0x90000000 /* DMA rev 1 PLUS */ + +#define DMA_HNDL_INTR 0x00000001 /* An IRQ needs to be handled */ +#define DMA_HNDL_ERROR 0x00000002 /* We need to take an error */ +#define DMA_FIFO_ISDRAIN 0x0000000c /* The DMA FIFO is draining */ +#define DMA_INT_ENAB 0x00000010 /* Turn on interrupts */ +#define DMA_FIFO_INV 0x00000020 /* Invalidate the FIFO */ +#define DMA_ACC_SZ_ERR 0x00000040 /* The access size was bad */ +#define DMA_FIFO_STDRAIN 0x00000040 /* DMA_VERS1 Drain the FIFO */ +#define DMA_RST_SCSI 0x00000080 /* Reset the SCSI controller */ +#define DMA_RST_ENET DMA_RST_SCSI /* Reset the ENET controller */ +#define DMA_ST_WRITE 0x00000100 /* write from device to memory */ +#define DMA_ENABLE 0x00000200 /* Fire up DMA, handle requests */ +#define DMA_PEND_READ 0x00000400 /* DMA_VERS1/0/PLUS Pending Read */ +#define DMA_ESC_BURST 0x00000800 /* 1=16byte 0=32byte */ +#define DMA_READ_AHEAD 0x00001800 /* DMA read ahead partial longword */ +#define DMA_DSBL_RD_DRN 0x00001000 /* No EC drain on slave reads */ +#define DMA_BCNT_ENAB 0x00002000 /* If on, use the byte counter */ +#define DMA_TERM_CNTR 0x00004000 /* Terminal counter */ +#define DMA_CSR_DISAB 0x00010000 /* No FIFO drains during csr */ +#define DMA_SCSI_DISAB 0x00020000 /* No FIFO drains during reg */ +#define DMA_DSBL_WR_INV 0x00020000 /* No EC inval. on slave writes */ +#define DMA_ADD_ENABLE 0x00040000 /* Special ESC DVMA optimization */ +#define DMA_E_BURST8 0x00040000 /* ENET: SBUS r/w burst size */ +#define DMA_BRST_SZ 0x000c0000 /* SCSI: SBUS r/w burst size */ +#define DMA_BRST64 0x00080000 /* SCSI: 64byte bursts (HME on UltraSparc only) */ +#define DMA_BRST32 0x00040000 /* SCSI: 32byte bursts */ +#define DMA_BRST16 0x00000000 /* SCSI: 16byte bursts */ +#define DMA_BRST0 0x00080000 /* SCSI: no bursts (non-HME gate arrays) */ +#define DMA_ADDR_DISAB 0x00100000 /* No FIFO drains during addr */ +#define DMA_2CLKS 0x00200000 /* Each transfer = 2 clock ticks */ +#define DMA_3CLKS 0x00400000 /* Each transfer = 3 clock ticks */ +#define DMA_EN_ENETAUI DMA_3CLKS /* Put lance into AUI-cable mode */ +#define DMA_CNTR_DISAB 0x00800000 /* No IRQ when DMA_TERM_CNTR set */ +#define DMA_AUTO_NADDR 0x01000000 /* Use "auto nxt addr" feature */ +#define DMA_SCSI_ON 0x02000000 /* Enable SCSI dma */ +#define DMA_PARITY_OFF 0x02000000 /* HME: disable parity checking */ +#define DMA_LOADED_ADDR 0x04000000 /* Address has been loaded */ +#define DMA_LOADED_NADDR 0x08000000 /* Next address has been loaded */ + +/* Values describing the burst-size property from the PROM */ +#define DMA_BURST1 0x01 +#define DMA_BURST2 0x02 +#define DMA_BURST4 0x04 +#define DMA_BURST8 0x08 +#define DMA_BURST16 0x10 +#define DMA_BURST32 0x20 +#define DMA_BURST64 0x40 +#define DMA_BURSTBITS 0x7f + +/* Determine highest possible final transfer address given a base */ +#define DMA_MAXEND(addr) (0x01000000UL-(((unsigned long)(addr))&0x00ffffffUL)) + +/* Yes, I hack a lot of elisp in my spare time... */ +#define DMA_ERROR_P(regs) ((((regs)->cond_reg) & DMA_HNDL_ERROR)) +#define DMA_IRQ_P(regs) ((((regs)->cond_reg) & (DMA_HNDL_INTR | DMA_HNDL_ERROR))) +#define DMA_WRITE_P(regs) ((((regs)->cond_reg) & DMA_ST_WRITE)) +#define DMA_OFF(regs) ((((regs)->cond_reg) &= (~DMA_ENABLE))) +#define DMA_INTSOFF(regs) ((((regs)->cond_reg) &= (~DMA_INT_ENAB))) +#define DMA_INTSON(regs) ((((regs)->cond_reg) |= (DMA_INT_ENAB))) +#define DMA_PUNTFIFO(regs) ((((regs)->cond_reg) |= DMA_FIFO_INV)) +#define DMA_SETSTART(regs, addr) ((((regs)->st_addr) = (char *) addr)) +#define DMA_BEGINDMA_W(regs) \ + ((((regs)->cond_reg |= (DMA_ST_WRITE|DMA_ENABLE|DMA_INT_ENAB)))) +#define DMA_BEGINDMA_R(regs) \ + ((((regs)->cond_reg |= ((DMA_ENABLE|DMA_INT_ENAB)&(~DMA_ST_WRITE))))) + +/* For certain DMA chips, we need to disable ints upon irq entry + * and turn them back on when we are done. So in any ESP interrupt + * handler you *must* call DMA_IRQ_ENTRY upon entry and DMA_IRQ_EXIT + * when leaving the handler. You have been warned... + */ +#define DMA_IRQ_ENTRY(dma, dregs) do { \ + if(DMA_ISBROKEN(dma)) DMA_INTSOFF(dregs); \ + } while (0) + +#define DMA_IRQ_EXIT(dma, dregs) do { \ + if(DMA_ISBROKEN(dma)) DMA_INTSON(dregs); \ + } while(0) + +/* Reset the friggin' thing... */ +#define DMA_RESET(dma) do { \ + struct sparc_dma_registers *regs = dma->regs; \ + /* Let the current FIFO drain itself */ \ + sparc_dma_pause(regs, (DMA_FIFO_ISDRAIN)); \ + /* Reset the logic */ \ + regs->cond_reg |= (DMA_RST_SCSI); /* assert */ \ + __delay(400); /* let the bits set ;) */ \ + regs->cond_reg &= ~(DMA_RST_SCSI); /* de-assert */ \ + sparc_dma_enable_interrupts(regs); /* Re-enable interrupts */ \ + /* Enable FAST transfers if available */ \ + if(dma->revision>dvmarev1) regs->cond_reg |= DMA_3CLKS; \ + dma->running = 0; \ +} while(0) + + +#endif /* !CONFIG_SUN3 */ + +#endif /* !(__M68K_DVMA_H) */ diff --git a/arch/m68k/include/asm/elf.h b/arch/m68k/include/asm/elf.h new file mode 100644 index 00000000000..04ce488bc63 --- /dev/null +++ b/arch/m68k/include/asm/elf.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "elf_no.h" +#else +#include "elf_mm.h" +#endif diff --git a/arch/m68k/include/asm/elf_mm.h b/arch/m68k/include/asm/elf_mm.h new file mode 100644 index 00000000000..0b0f49eb876 --- /dev/null +++ b/arch/m68k/include/asm/elf_mm.h @@ -0,0 +1,119 @@ +#ifndef __ASMm68k_ELF_H +#define __ASMm68k_ELF_H + +/* + * ELF register definitions.. + */ + +#include +#include + +/* + * 68k ELF relocation types + */ +#define R_68K_NONE 0 +#define R_68K_32 1 +#define R_68K_16 2 +#define R_68K_8 3 +#define R_68K_PC32 4 +#define R_68K_PC16 5 +#define R_68K_PC8 6 +#define R_68K_GOT32 7 +#define R_68K_GOT16 8 +#define R_68K_GOT8 9 +#define R_68K_GOT32O 10 +#define R_68K_GOT16O 11 +#define R_68K_GOT8O 12 +#define R_68K_PLT32 13 +#define R_68K_PLT16 14 +#define R_68K_PLT8 15 +#define R_68K_PLT32O 16 +#define R_68K_PLT16O 17 +#define R_68K_PLT8O 18 +#define R_68K_COPY 19 +#define R_68K_GLOB_DAT 20 +#define R_68K_JMP_SLOT 21 +#define R_68K_RELATIVE 22 + +typedef unsigned long elf_greg_t; + +#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t)) +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +typedef struct user_m68kfp_struct elf_fpregset_t; + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(x) ((x)->e_machine == EM_68K) + +/* + * These are used to set parameters in the core dumps. + */ +#define ELF_CLASS ELFCLASS32 +#define ELF_DATA ELFDATA2MSB +#define ELF_ARCH EM_68K + +/* For SVR4/m68k the function pointer to be registered with `atexit' is + passed in %a1. Although my copy of the ABI has no such statement, it + is actually used on ASV. */ +#define ELF_PLAT_INIT(_r, load_addr) _r->a1 = 0 + +#define USE_ELF_CORE_DUMP +#ifndef CONFIG_SUN3 +#define ELF_EXEC_PAGESIZE 4096 +#else +#define ELF_EXEC_PAGESIZE 8192 +#endif + +/* This is the location that an ET_DYN program is loaded if exec'ed. Typical + use of this is to invoke "./ld.so someprog" to test out a new version of + the loader. We need to make sure that it is out of the way of the program + that it will "exec", and that there is sufficient room for the brk. */ + +#ifndef CONFIG_SUN3 +#define ELF_ET_DYN_BASE 0xD0000000UL +#else +#define ELF_ET_DYN_BASE 0x0D800000UL +#endif + +#define ELF_CORE_COPY_REGS(pr_reg, regs) \ + /* Bleech. */ \ + pr_reg[0] = regs->d1; \ + pr_reg[1] = regs->d2; \ + pr_reg[2] = regs->d3; \ + pr_reg[3] = regs->d4; \ + pr_reg[4] = regs->d5; \ + pr_reg[7] = regs->a0; \ + pr_reg[8] = regs->a1; \ + pr_reg[9] = regs->a2; \ + pr_reg[14] = regs->d0; \ + pr_reg[15] = rdusp(); \ + pr_reg[16] = regs->orig_d0; \ + pr_reg[17] = regs->sr; \ + pr_reg[18] = regs->pc; \ + pr_reg[19] = (regs->format << 12) | regs->vector; \ + { \ + struct switch_stack *sw = ((struct switch_stack *)regs) - 1; \ + pr_reg[5] = sw->d6; \ + pr_reg[6] = sw->d7; \ + pr_reg[10] = sw->a3; \ + pr_reg[11] = sw->a4; \ + pr_reg[12] = sw->a5; \ + pr_reg[13] = sw->a6; \ + } + +/* This yields a mask that user programs can use to figure out what + instruction set this cpu supports. */ + +#define ELF_HWCAP (0) + +/* This yields a string that ld.so will use to load implementation + specific libraries for optimization. This is more specific in + intent than poking at uname or /proc/cpuinfo. */ + +#define ELF_PLATFORM (NULL) + +#define SET_PERSONALITY(ex) set_personality(PER_LINUX) + +#endif diff --git a/arch/m68k/include/asm/elf_no.h b/arch/m68k/include/asm/elf_no.h new file mode 100644 index 00000000000..b8046837f38 --- /dev/null +++ b/arch/m68k/include/asm/elf_no.h @@ -0,0 +1,110 @@ +#ifndef __ASMm68k_ELF_H +#define __ASMm68k_ELF_H + +/* + * ELF register definitions.. + */ + +#include +#include + +/* + * 68k ELF relocation types + */ +#define R_68K_NONE 0 +#define R_68K_32 1 +#define R_68K_16 2 +#define R_68K_8 3 +#define R_68K_PC32 4 +#define R_68K_PC16 5 +#define R_68K_PC8 6 +#define R_68K_GOT32 7 +#define R_68K_GOT16 8 +#define R_68K_GOT8 9 +#define R_68K_GOT32O 10 +#define R_68K_GOT16O 11 +#define R_68K_GOT8O 12 +#define R_68K_PLT32 13 +#define R_68K_PLT16 14 +#define R_68K_PLT8 15 +#define R_68K_PLT32O 16 +#define R_68K_PLT16O 17 +#define R_68K_PLT8O 18 +#define R_68K_COPY 19 +#define R_68K_GLOB_DAT 20 +#define R_68K_JMP_SLOT 21 +#define R_68K_RELATIVE 22 + +typedef unsigned long elf_greg_t; + +#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t)) +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +typedef struct user_m68kfp_struct elf_fpregset_t; + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(x) ((x)->e_machine == EM_68K) + +/* + * These are used to set parameters in the core dumps. + */ +#define ELF_CLASS ELFCLASS32 +#define ELF_DATA ELFDATA2MSB +#define ELF_ARCH EM_68K + +/* For SVR4/m68k the function pointer to be registered with `atexit' is + passed in %a1. Although my copy of the ABI has no such statement, it + is actually used on ASV. */ +#define ELF_PLAT_INIT(_r, load_addr) _r->a1 = 0 + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE 4096 + +/* This is the location that an ET_DYN program is loaded if exec'ed. Typical + use of this is to invoke "./ld.so someprog" to test out a new version of + the loader. We need to make sure that it is out of the way of the program + that it will "exec", and that there is sufficient room for the brk. */ + +#define ELF_ET_DYN_BASE 0xD0000000UL + +#define ELF_CORE_COPY_REGS(pr_reg, regs) \ + /* Bleech. */ \ + pr_reg[0] = regs->d1; \ + pr_reg[1] = regs->d2; \ + pr_reg[2] = regs->d3; \ + pr_reg[3] = regs->d4; \ + pr_reg[4] = regs->d5; \ + pr_reg[7] = regs->a0; \ + pr_reg[8] = regs->a1; \ + pr_reg[14] = regs->d0; \ + pr_reg[15] = rdusp(); \ + pr_reg[16] = 0 /* regs->orig_d0 */; \ + pr_reg[17] = regs->sr; \ + pr_reg[18] = regs->pc; \ + /* pr_reg[19] = (regs->format << 12) | regs->vector; */ \ + { \ + struct switch_stack *sw = ((struct switch_stack *)regs) - 1; \ + pr_reg[5] = sw->d6; \ + pr_reg[6] = sw->d7; \ + pr_reg[10] = sw->a3; \ + pr_reg[11] = sw->a4; \ + pr_reg[12] = sw->a5; \ + pr_reg[13] = sw->a6; \ + } + +/* This yields a mask that user programs can use to figure out what + instruction set this cpu supports. */ + +#define ELF_HWCAP (0) + +/* This yields a string that ld.so will use to load implementation + specific libraries for optimization. This is more specific in + intent than poking at uname or /proc/cpuinfo. */ + +#define ELF_PLATFORM (NULL) + +#define SET_PERSONALITY(ex) set_personality(PER_LINUX) + +#endif diff --git a/arch/m68k/include/asm/elia.h b/arch/m68k/include/asm/elia.h new file mode 100644 index 00000000000..e037d4e2de3 --- /dev/null +++ b/arch/m68k/include/asm/elia.h @@ -0,0 +1,41 @@ +/****************************************************************************/ + +/* + * elia.h -- Lineo (formerly Moreton Bay) eLIA platform support. + * + * (C) Copyright 1999-2000, Moreton Bay (www.moreton.com.au) + * (C) Copyright 1999-2000, Lineo (www.lineo.com) + */ + +/****************************************************************************/ +#ifndef elia_h +#define elia_h +/****************************************************************************/ + +#include + +#ifdef CONFIG_eLIA + +/* + * The serial port DTR and DCD lines are also on the Parallel I/O + * as well, so define those too. + */ + +#define eLIA_DCD1 0x0001 +#define eLIA_DCD0 0x0002 +#define eLIA_DTR1 0x0004 +#define eLIA_DTR0 0x0008 + +#define eLIA_PCIRESET 0x0020 + +/* + * Kernel macros to set and unset the LEDs. + */ +#ifndef __ASSEMBLY__ +extern unsigned short ppdata; +#endif /* __ASSEMBLY__ */ + +#endif /* CONFIG_eLIA */ + +/****************************************************************************/ +#endif /* elia_h */ diff --git a/arch/m68k/include/asm/emergency-restart.h b/arch/m68k/include/asm/emergency-restart.h new file mode 100644 index 00000000000..108d8c48e42 --- /dev/null +++ b/arch/m68k/include/asm/emergency-restart.h @@ -0,0 +1,6 @@ +#ifndef _ASM_EMERGENCY_RESTART_H +#define _ASM_EMERGENCY_RESTART_H + +#include + +#endif /* _ASM_EMERGENCY_RESTART_H */ diff --git a/arch/m68k/include/asm/entry.h b/arch/m68k/include/asm/entry.h new file mode 100644 index 00000000000..876eec6f2b5 --- /dev/null +++ b/arch/m68k/include/asm/entry.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "entry_no.h" +#else +#include "entry_mm.h" +#endif diff --git a/arch/m68k/include/asm/entry_mm.h b/arch/m68k/include/asm/entry_mm.h new file mode 100644 index 00000000000..5202f5a5b42 --- /dev/null +++ b/arch/m68k/include/asm/entry_mm.h @@ -0,0 +1,137 @@ +#ifndef __M68K_ENTRY_H +#define __M68K_ENTRY_H + +#include +#include + +/* + * Stack layout in 'ret_from_exception': + * + * This allows access to the syscall arguments in registers d1-d5 + * + * 0(sp) - d1 + * 4(sp) - d2 + * 8(sp) - d3 + * C(sp) - d4 + * 10(sp) - d5 + * 14(sp) - a0 + * 18(sp) - a1 + * 1C(sp) - a2 + * 20(sp) - d0 + * 24(sp) - orig_d0 + * 28(sp) - stack adjustment + * 2C(sp) - sr + * 2E(sp) - pc + * 32(sp) - format & vector + */ + +/* + * 97/05/14 Andreas: Register %a2 is now set to the current task throughout + * the whole kernel. + */ + +/* the following macro is used when enabling interrupts */ +#if defined(MACH_ATARI_ONLY) + /* block out HSYNC on the atari */ +#define ALLOWINT (~0x400) +#define MAX_NOINT_IPL 3 +#else + /* portable version */ +#define ALLOWINT (~0x700) +#define MAX_NOINT_IPL 0 +#endif /* machine compilation types */ + +#ifdef __ASSEMBLY__ + +#define curptr a2 + +LFLUSH_I_AND_D = 0x00000808 +LSIGTRAP = 5 + +/* process bits for task_struct.ptrace */ +PT_TRACESYS_OFF = 3 +PT_TRACESYS_BIT = 1 +PT_PTRACED_OFF = 3 +PT_PTRACED_BIT = 0 +PT_DTRACE_OFF = 3 +PT_DTRACE_BIT = 2 + +#define SAVE_ALL_INT save_all_int +#define SAVE_ALL_SYS save_all_sys +#define RESTORE_ALL restore_all +/* + * This defines the normal kernel pt-regs layout. + * + * regs a3-a6 and d6-d7 are preserved by C code + * the kernel doesn't mess with usp unless it needs to + */ + +/* + * a -1 in the orig_d0 field signifies + * that the stack frame is NOT for syscall + */ +.macro save_all_int + clrl %sp@- | stk_adj + pea -1:w | orig d0 + movel %d0,%sp@- | d0 + moveml %d1-%d5/%a0-%a1/%curptr,%sp@- +.endm + +.macro save_all_sys + clrl %sp@- | stk_adj + movel %d0,%sp@- | orig d0 + movel %d0,%sp@- | d0 + moveml %d1-%d5/%a0-%a1/%curptr,%sp@- +.endm + +.macro restore_all + moveml %sp@+,%a0-%a1/%curptr/%d1-%d5 + movel %sp@+,%d0 + addql #4,%sp | orig d0 + addl %sp@+,%sp | stk adj + rte +.endm + +#define SWITCH_STACK_SIZE (6*4+4) /* includes return address */ + +#define SAVE_SWITCH_STACK save_switch_stack +#define RESTORE_SWITCH_STACK restore_switch_stack +#define GET_CURRENT(tmp) get_current tmp + +.macro save_switch_stack + moveml %a3-%a6/%d6-%d7,%sp@- +.endm + +.macro restore_switch_stack + moveml %sp@+,%a3-%a6/%d6-%d7 +.endm + +.macro get_current reg=%d0 + movel %sp,\reg + andw #-THREAD_SIZE,\reg + movel \reg,%curptr + movel %curptr@,%curptr +.endm + +#else /* C source */ + +#define STR(X) STR1(X) +#define STR1(X) #X + +#define PT_OFF_ORIG_D0 0x24 +#define PT_OFF_FORMATVEC 0x32 +#define PT_OFF_SR 0x2C +#define SAVE_ALL_INT \ + "clrl %%sp@-;" /* stk_adj */ \ + "pea -1:w;" /* orig d0 = -1 */ \ + "movel %%d0,%%sp@-;" /* d0 */ \ + "moveml %%d1-%%d5/%%a0-%%a2,%%sp@-" +#define GET_CURRENT(tmp) \ + "movel %%sp,"#tmp"\n\t" \ + "andw #-"STR(THREAD_SIZE)","#tmp"\n\t" \ + "movel "#tmp",%%a2\n\t" \ + "movel %%a2@,%%a2" + +#endif + +#endif /* __M68K_ENTRY_H */ diff --git a/arch/m68k/include/asm/entry_no.h b/arch/m68k/include/asm/entry_no.h new file mode 100644 index 00000000000..c2553d26273 --- /dev/null +++ b/arch/m68k/include/asm/entry_no.h @@ -0,0 +1,182 @@ +#ifndef __M68KNOMMU_ENTRY_H +#define __M68KNOMMU_ENTRY_H + +#include +#include + +/* + * Stack layout in 'ret_from_exception': + * + * This allows access to the syscall arguments in registers d1-d5 + * + * 0(sp) - d1 + * 4(sp) - d2 + * 8(sp) - d3 + * C(sp) - d4 + * 10(sp) - d5 + * 14(sp) - a0 + * 18(sp) - a1 + * 1C(sp) - a2 + * 20(sp) - d0 + * 24(sp) - orig_d0 + * 28(sp) - stack adjustment + * 2C(sp) - [ sr ] [ format & vector ] + * 2E(sp) - [ pc-hiword ] [ sr ] + * 30(sp) - [ pc-loword ] [ pc-hiword ] + * 32(sp) - [ format & vector ] [ pc-loword ] + * ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ + * M68K COLDFIRE + */ + +#define ALLOWINT 0xf8ff + +#ifdef __ASSEMBLY__ + +/* process bits for task_struct.flags */ +PF_TRACESYS_OFF = 3 +PF_TRACESYS_BIT = 5 +PF_PTRACED_OFF = 3 +PF_PTRACED_BIT = 4 +PF_DTRACE_OFF = 1 +PF_DTRACE_BIT = 5 + +LENOSYS = 38 + +#define SWITCH_STACK_SIZE (6*4+4) /* Includes return address */ + +/* + * This defines the normal kernel pt-regs layout. + * + * regs are a2-a6 and d6-d7 preserved by C code + * the kernel doesn't mess with usp unless it needs to + */ + +#ifdef CONFIG_COLDFIRE +/* + * This is made a little more tricky on the ColdFire. There is no + * separate kernel and user stack pointers. Need to artificially + * construct a usp in software... When doing this we need to disable + * interrupts, otherwise bad things could happen. + */ +.macro SAVE_ALL + move #0x2700,%sr /* disable intrs */ + btst #5,%sp@(2) /* from user? */ + bnes 6f /* no, skip */ + movel %sp,sw_usp /* save user sp */ + addql #8,sw_usp /* remove exception */ + movel sw_ksp,%sp /* kernel sp */ + subql #8,%sp /* room for exception */ + clrl %sp@- /* stkadj */ + movel %d0,%sp@- /* orig d0 */ + movel %d0,%sp@- /* d0 */ + lea %sp@(-32),%sp /* space for 8 regs */ + moveml %d1-%d5/%a0-%a2,%sp@ + movel sw_usp,%a0 /* get usp */ + movel %a0@-,%sp@(PT_PC) /* copy exception program counter */ + movel %a0@-,%sp@(PT_FORMATVEC)/* copy exception format/vector/sr */ + bra 7f + 6: + clrl %sp@- /* stkadj */ + movel %d0,%sp@- /* orig d0 */ + movel %d0,%sp@- /* d0 */ + lea %sp@(-32),%sp /* space for 8 regs */ + moveml %d1-%d5/%a0-%a2,%sp@ + 7: +.endm + +.macro RESTORE_ALL + btst #5,%sp@(PT_SR) /* going user? */ + bnes 8f /* no, skip */ + move #0x2700,%sr /* disable intrs */ + movel sw_usp,%a0 /* get usp */ + movel %sp@(PT_PC),%a0@- /* copy exception program counter */ + movel %sp@(PT_FORMATVEC),%a0@-/* copy exception format/vector/sr */ + moveml %sp@,%d1-%d5/%a0-%a2 + lea %sp@(32),%sp /* space for 8 regs */ + movel %sp@+,%d0 + addql #4,%sp /* orig d0 */ + addl %sp@+,%sp /* stkadj */ + addql #8,%sp /* remove exception */ + movel %sp,sw_ksp /* save ksp */ + subql #8,sw_usp /* set exception */ + movel sw_usp,%sp /* restore usp */ + rte + 8: + moveml %sp@,%d1-%d5/%a0-%a2 + lea %sp@(32),%sp /* space for 8 regs */ + movel %sp@+,%d0 + addql #4,%sp /* orig d0 */ + addl %sp@+,%sp /* stkadj */ + rte +.endm + +/* + * Quick exception save, use current stack only. + */ +.macro SAVE_LOCAL + move #0x2700,%sr /* disable intrs */ + clrl %sp@- /* stkadj */ + movel %d0,%sp@- /* orig d0 */ + movel %d0,%sp@- /* d0 */ + lea %sp@(-32),%sp /* space for 8 regs */ + moveml %d1-%d5/%a0-%a2,%sp@ +.endm + +.macro RESTORE_LOCAL + moveml %sp@,%d1-%d5/%a0-%a2 + lea %sp@(32),%sp /* space for 8 regs */ + movel %sp@+,%d0 + addql #4,%sp /* orig d0 */ + addl %sp@+,%sp /* stkadj */ + rte +.endm + +.macro SAVE_SWITCH_STACK + lea %sp@(-24),%sp /* 6 regs */ + moveml %a3-%a6/%d6-%d7,%sp@ +.endm + +.macro RESTORE_SWITCH_STACK + moveml %sp@,%a3-%a6/%d6-%d7 + lea %sp@(24),%sp /* 6 regs */ +.endm + +/* + * Software copy of the user and kernel stack pointers... Ugh... + * Need these to get around ColdFire not having separate kernel + * and user stack pointers. + */ +.globl sw_usp +.globl sw_ksp + +#else /* !CONFIG_COLDFIRE */ + +/* + * Standard 68k interrupt entry and exit macros. + */ +.macro SAVE_ALL + clrl %sp@- /* stkadj */ + movel %d0,%sp@- /* orig d0 */ + movel %d0,%sp@- /* d0 */ + moveml %d1-%d5/%a0-%a2,%sp@- +.endm + +.macro RESTORE_ALL + moveml %sp@+,%a0-%a2/%d1-%d5 + movel %sp@+,%d0 + addql #4,%sp /* orig d0 */ + addl %sp@+,%sp /* stkadj */ + rte +.endm + +.macro SAVE_SWITCH_STACK + moveml %a3-%a6/%d6-%d7,%sp@- +.endm + +.macro RESTORE_SWITCH_STACK + moveml %sp@+,%a3-%a6/%d6-%d7 +.endm + +#endif /* !CONFIG_COLDFIRE */ +#endif /* __ASSEMBLY__ */ +#endif /* __M68KNOMMU_ENTRY_H */ diff --git a/arch/m68k/include/asm/errno.h b/arch/m68k/include/asm/errno.h new file mode 100644 index 00000000000..0d4e188d6ef --- /dev/null +++ b/arch/m68k/include/asm/errno.h @@ -0,0 +1,6 @@ +#ifndef _M68K_ERRNO_H +#define _M68K_ERRNO_H + +#include + +#endif /* _M68K_ERRNO_H */ diff --git a/arch/m68k/include/asm/fb.h b/arch/m68k/include/asm/fb.h new file mode 100644 index 00000000000..97bcaefd206 --- /dev/null +++ b/arch/m68k/include/asm/fb.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "fb_no.h" +#else +#include "fb_mm.h" +#endif diff --git a/arch/m68k/include/asm/fb_mm.h b/arch/m68k/include/asm/fb_mm.h new file mode 100644 index 00000000000..380b97ae815 --- /dev/null +++ b/arch/m68k/include/asm/fb_mm.h @@ -0,0 +1,34 @@ +#ifndef _ASM_FB_H_ +#define _ASM_FB_H_ + +#include +#include +#include +#include + +#ifdef CONFIG_SUN3 +static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma, + unsigned long off) +{ + pgprot_val(vma->vm_page_prot) |= SUN3_PAGE_NOCACHE; +} +#else +static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma, + unsigned long off) +{ + if (CPU_IS_020_OR_030) + pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE030; + if (CPU_IS_040_OR_060) { + pgprot_val(vma->vm_page_prot) &= _CACHEMASK040; + /* Use no-cache mode, serialized */ + pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE_S; + } +} +#endif /* CONFIG_SUN3 */ + +static inline int fb_is_primary_device(struct fb_info *info) +{ + return 0; +} + +#endif /* _ASM_FB_H_ */ diff --git a/arch/m68k/include/asm/fb_no.h b/arch/m68k/include/asm/fb_no.h new file mode 100644 index 00000000000..c7df3803099 --- /dev/null +++ b/arch/m68k/include/asm/fb_no.h @@ -0,0 +1,12 @@ +#ifndef _ASM_FB_H_ +#define _ASM_FB_H_ +#include + +#define fb_pgprotect(...) do {} while (0) + +static inline int fb_is_primary_device(struct fb_info *info) +{ + return 0; +} + +#endif /* _ASM_FB_H_ */ diff --git a/arch/m68k/include/asm/fbio.h b/arch/m68k/include/asm/fbio.h new file mode 100644 index 00000000000..b9215a0907d --- /dev/null +++ b/arch/m68k/include/asm/fbio.h @@ -0,0 +1,330 @@ +#ifndef __LINUX_FBIO_H +#define __LINUX_FBIO_H + +#include +#include + +/* Constants used for fbio SunOS compatibility */ +/* (C) 1996 Miguel de Icaza */ + +/* Frame buffer types */ +#define FBTYPE_NOTYPE -1 +#define FBTYPE_SUN1BW 0 /* mono */ +#define FBTYPE_SUN1COLOR 1 +#define FBTYPE_SUN2BW 2 +#define FBTYPE_SUN2COLOR 3 +#define FBTYPE_SUN2GP 4 +#define FBTYPE_SUN5COLOR 5 +#define FBTYPE_SUN3COLOR 6 +#define FBTYPE_MEMCOLOR 7 +#define FBTYPE_SUN4COLOR 8 + +#define FBTYPE_NOTSUN1 9 +#define FBTYPE_NOTSUN2 10 +#define FBTYPE_NOTSUN3 11 + +#define FBTYPE_SUNFAST_COLOR 12 /* cg6 */ +#define FBTYPE_SUNROP_COLOR 13 +#define FBTYPE_SUNFB_VIDEO 14 +#define FBTYPE_SUNGIFB 15 +#define FBTYPE_SUNGPLAS 16 +#define FBTYPE_SUNGP3 17 +#define FBTYPE_SUNGT 18 +#define FBTYPE_SUNLEO 19 /* zx Leo card */ +#define FBTYPE_MDICOLOR 20 /* cg14 */ +#define FBTYPE_TCXCOLOR 21 /* SUNW,tcx card */ + +#define FBTYPE_LASTPLUSONE 21 /* This is not last + 1 in fact... */ + +/* Does not seem to be listed in the Sun file either */ +#define FBTYPE_CREATOR 22 +#define FBTYPE_PCI_IGA1682 23 +#define FBTYPE_P9100COLOR 24 + +#define FBTYPE_PCI_GENERIC 1000 +#define FBTYPE_PCI_MACH64 1001 + +/* fbio ioctls */ +/* Returned by FBIOGTYPE */ +struct fbtype { + int fb_type; /* fb type, see above */ + int fb_height; /* pixels */ + int fb_width; /* pixels */ + int fb_depth; + int fb_cmsize; /* color map entries */ + int fb_size; /* fb size in bytes */ +}; +#define FBIOGTYPE _IOR('F', 0, struct fbtype) + +struct fbcmap { + int index; /* first element (0 origin) */ + int count; + unsigned char __user *red; + unsigned char __user *green; + unsigned char __user *blue; +}; + +#ifdef __KERNEL__ +#define FBIOPUTCMAP_SPARC _IOW('F', 3, struct fbcmap) +#define FBIOGETCMAP_SPARC _IOW('F', 4, struct fbcmap) +#else +#define FBIOPUTCMAP _IOW('F', 3, struct fbcmap) +#define FBIOGETCMAP _IOW('F', 4, struct fbcmap) +#endif + +/* # of device specific values */ +#define FB_ATTR_NDEVSPECIFIC 8 +/* # of possible emulations */ +#define FB_ATTR_NEMUTYPES 4 + +struct fbsattr { + int flags; + int emu_type; /* -1 if none */ + int dev_specific[FB_ATTR_NDEVSPECIFIC]; +}; + +struct fbgattr { + int real_type; /* real frame buffer type */ + int owner; /* unknown */ + struct fbtype fbtype; /* real frame buffer fbtype */ + struct fbsattr sattr; + int emu_types[FB_ATTR_NEMUTYPES]; /* supported emulations */ +}; +#define FBIOSATTR _IOW('F', 5, struct fbgattr) /* Unsupported: */ +#define FBIOGATTR _IOR('F', 6, struct fbgattr) /* supported */ + +#define FBIOSVIDEO _IOW('F', 7, int) +#define FBIOGVIDEO _IOR('F', 8, int) + +struct fbcursor { + short set; /* what to set, choose from the list above */ + short enable; /* cursor on/off */ + struct fbcurpos pos; /* cursor position */ + struct fbcurpos hot; /* cursor hot spot */ + struct fbcmap cmap; /* color map info */ + struct fbcurpos size; /* cursor bit map size */ + char __user *image; /* cursor image bits */ + char __user *mask; /* cursor mask bits */ +}; + +/* set/get cursor attributes/shape */ +#define FBIOSCURSOR _IOW('F', 24, struct fbcursor) +#define FBIOGCURSOR _IOWR('F', 25, struct fbcursor) + +/* set/get cursor position */ +#define FBIOSCURPOS _IOW('F', 26, struct fbcurpos) +#define FBIOGCURPOS _IOW('F', 27, struct fbcurpos) + +/* get max cursor size */ +#define FBIOGCURMAX _IOR('F', 28, struct fbcurpos) + +/* wid manipulation */ +struct fb_wid_alloc { +#define FB_WID_SHARED_8 0 +#define FB_WID_SHARED_24 1 +#define FB_WID_DBL_8 2 +#define FB_WID_DBL_24 3 + __u32 wa_type; + __s32 wa_index; /* Set on return */ + __u32 wa_count; +}; +struct fb_wid_item { + __u32 wi_type; + __s32 wi_index; + __u32 wi_attrs; + __u32 wi_values[32]; +}; +struct fb_wid_list { + __u32 wl_flags; + __u32 wl_count; + struct fb_wid_item *wl_list; +}; + +#define FBIO_WID_ALLOC _IOWR('F', 30, struct fb_wid_alloc) +#define FBIO_WID_FREE _IOW('F', 31, struct fb_wid_alloc) +#define FBIO_WID_PUT _IOW('F', 32, struct fb_wid_list) +#define FBIO_WID_GET _IOWR('F', 33, struct fb_wid_list) + +/* Creator ioctls */ +#define FFB_IOCTL ('F'<<8) +#define FFB_SYS_INFO (FFB_IOCTL|80) +#define FFB_CLUTREAD (FFB_IOCTL|81) +#define FFB_CLUTPOST (FFB_IOCTL|82) +#define FFB_SETDIAGMODE (FFB_IOCTL|83) +#define FFB_GETMONITORID (FFB_IOCTL|84) +#define FFB_GETVIDEOMODE (FFB_IOCTL|85) +#define FFB_SETVIDEOMODE (FFB_IOCTL|86) +#define FFB_SETSERVER (FFB_IOCTL|87) +#define FFB_SETOVCTL (FFB_IOCTL|88) +#define FFB_GETOVCTL (FFB_IOCTL|89) +#define FFB_GETSAXNUM (FFB_IOCTL|90) +#define FFB_FBDEBUG (FFB_IOCTL|91) + +/* Cg14 ioctls */ +#define MDI_IOCTL ('M'<<8) +#define MDI_RESET (MDI_IOCTL|1) +#define MDI_GET_CFGINFO (MDI_IOCTL|2) +#define MDI_SET_PIXELMODE (MDI_IOCTL|3) +# define MDI_32_PIX 32 +# define MDI_16_PIX 16 +# define MDI_8_PIX 8 + +struct mdi_cfginfo { + int mdi_ncluts; /* Number of implemented CLUTs in this MDI */ + int mdi_type; /* FBTYPE name */ + int mdi_height; /* height */ + int mdi_width; /* widht */ + int mdi_size; /* available ram */ + int mdi_mode; /* 8bpp, 16bpp or 32bpp */ + int mdi_pixfreq; /* pixel clock (from PROM) */ +}; + +/* SparcLinux specific ioctl for the MDI, should be replaced for + * the SET_XLUT/SET_CLUTn ioctls instead + */ +#define MDI_CLEAR_XLUT (MDI_IOCTL|9) + +/* leo & ffb ioctls */ +struct fb_clut_alloc { + __u32 clutid; /* Set on return */ + __u32 flag; + __u32 index; +}; + +struct fb_clut { +#define FB_CLUT_WAIT 0x00000001 /* Not yet implemented */ + __u32 flag; + __u32 clutid; + __u32 offset; + __u32 count; + char * red; + char * green; + char * blue; +}; + +struct fb_clut32 { + __u32 flag; + __u32 clutid; + __u32 offset; + __u32 count; + __u32 red; + __u32 green; + __u32 blue; +}; + +#define LEO_CLUTALLOC _IOWR('L', 53, struct fb_clut_alloc) +#define LEO_CLUTFREE _IOW('L', 54, struct fb_clut_alloc) +#define LEO_CLUTREAD _IOW('L', 55, struct fb_clut) +#define LEO_CLUTPOST _IOW('L', 56, struct fb_clut) +#define LEO_SETGAMMA _IOW('L', 68, int) /* Not yet implemented */ +#define LEO_GETGAMMA _IOR('L', 69, int) /* Not yet implemented */ + +#ifdef __KERNEL__ +/* Addresses on the fd of a cgsix that are mappable */ +#define CG6_FBC 0x70000000 +#define CG6_TEC 0x70001000 +#define CG6_BTREGS 0x70002000 +#define CG6_FHC 0x70004000 +#define CG6_THC 0x70005000 +#define CG6_ROM 0x70006000 +#define CG6_RAM 0x70016000 +#define CG6_DHC 0x80000000 + +#define CG3_MMAP_OFFSET 0x4000000 + +/* Addresses on the fd of a tcx that are mappable */ +#define TCX_RAM8BIT 0x00000000 +#define TCX_RAM24BIT 0x01000000 +#define TCX_UNK3 0x10000000 +#define TCX_UNK4 0x20000000 +#define TCX_CONTROLPLANE 0x28000000 +#define TCX_UNK6 0x30000000 +#define TCX_UNK7 0x38000000 +#define TCX_TEC 0x70000000 +#define TCX_BTREGS 0x70002000 +#define TCX_THC 0x70004000 +#define TCX_DHC 0x70008000 +#define TCX_ALT 0x7000a000 +#define TCX_SYNC 0x7000e000 +#define TCX_UNK2 0x70010000 + +/* CG14 definitions */ + +/* Offsets into the OBIO space: */ +#define CG14_REGS 0 /* registers */ +#define CG14_CURSORREGS 0x1000 /* cursor registers */ +#define CG14_DACREGS 0x2000 /* DAC registers */ +#define CG14_XLUT 0x3000 /* X Look Up Table -- ??? */ +#define CG14_CLUT1 0x4000 /* Color Look Up Table */ +#define CG14_CLUT2 0x5000 /* Color Look Up Table */ +#define CG14_CLUT3 0x6000 /* Color Look Up Table */ +#define CG14_AUTO 0xf000 + +#endif /* KERNEL */ + +/* These are exported to userland for applications to use */ +/* Mappable offsets for the cg14: control registers */ +#define MDI_DIRECT_MAP 0x10000000 +#define MDI_CTLREG_MAP 0x20000000 +#define MDI_CURSOR_MAP 0x30000000 +#define MDI_SHDW_VRT_MAP 0x40000000 + +/* Mappable offsets for the cg14: frame buffer resolutions */ +/* 32 bits */ +#define MDI_CHUNKY_XBGR_MAP 0x50000000 +#define MDI_CHUNKY_BGR_MAP 0x60000000 + +/* 16 bits */ +#define MDI_PLANAR_X16_MAP 0x70000000 +#define MDI_PLANAR_C16_MAP 0x80000000 + +/* 8 bit is done as CG3 MMAP offset */ +/* 32 bits, planar */ +#define MDI_PLANAR_X32_MAP 0x90000000 +#define MDI_PLANAR_B32_MAP 0xa0000000 +#define MDI_PLANAR_G32_MAP 0xb0000000 +#define MDI_PLANAR_R32_MAP 0xc0000000 + +/* Mappable offsets on leo */ +#define LEO_SS0_MAP 0x00000000 +#define LEO_LC_SS0_USR_MAP 0x00800000 +#define LEO_LD_SS0_MAP 0x00801000 +#define LEO_LX_CURSOR_MAP 0x00802000 +#define LEO_SS1_MAP 0x00803000 +#define LEO_LC_SS1_USR_MAP 0x01003000 +#define LEO_LD_SS1_MAP 0x01004000 +#define LEO_UNK_MAP 0x01005000 +#define LEO_LX_KRN_MAP 0x01006000 +#define LEO_LC_SS0_KRN_MAP 0x01007000 +#define LEO_LC_SS1_KRN_MAP 0x01008000 +#define LEO_LD_GBL_MAP 0x01009000 +#define LEO_UNK2_MAP 0x0100a000 + +#ifdef __KERNEL__ +struct fbcmap32 { + int index; /* first element (0 origin) */ + int count; + u32 red; + u32 green; + u32 blue; +}; + +#define FBIOPUTCMAP32 _IOW('F', 3, struct fbcmap32) +#define FBIOGETCMAP32 _IOW('F', 4, struct fbcmap32) + +struct fbcursor32 { + short set; /* what to set, choose from the list above */ + short enable; /* cursor on/off */ + struct fbcurpos pos; /* cursor position */ + struct fbcurpos hot; /* cursor hot spot */ + struct fbcmap32 cmap; /* color map info */ + struct fbcurpos size; /* cursor bit map size */ + u32 image; /* cursor image bits */ + u32 mask; /* cursor mask bits */ +}; + +#define FBIOSCURSOR32 _IOW('F', 24, struct fbcursor32) +#define FBIOGCURSOR32 _IOW('F', 25, struct fbcursor32) +#endif + +#endif /* __LINUX_FBIO_H */ diff --git a/arch/m68k/include/asm/fcntl.h b/arch/m68k/include/asm/fcntl.h new file mode 100644 index 00000000000..1c369b20dc4 --- /dev/null +++ b/arch/m68k/include/asm/fcntl.h @@ -0,0 +1,11 @@ +#ifndef _M68K_FCNTL_H +#define _M68K_FCNTL_H + +#define O_DIRECTORY 040000 /* must be a directory */ +#define O_NOFOLLOW 0100000 /* don't follow links */ +#define O_DIRECT 0200000 /* direct disk access hint - currently ignored */ +#define O_LARGEFILE 0400000 + +#include + +#endif /* _M68K_FCNTL_H */ diff --git a/arch/m68k/include/asm/flat.h b/arch/m68k/include/asm/flat.h new file mode 100644 index 00000000000..814b5174a8e --- /dev/null +++ b/arch/m68k/include/asm/flat.h @@ -0,0 +1,17 @@ +/* + * include/asm-m68knommu/flat.h -- uClinux flat-format executables + */ + +#ifndef __M68KNOMMU_FLAT_H__ +#define __M68KNOMMU_FLAT_H__ + +#define flat_stack_align(sp) /* nothing needed */ +#define flat_argvp_envp_on_stack() 1 +#define flat_old_ram_flag(flags) (flags) +#define flat_reloc_valid(reloc, size) ((reloc) <= (size)) +#define flat_get_addr_from_rp(rp, relval, flags, p) get_unaligned(rp) +#define flat_put_addr_at_rp(rp, val, relval) put_unaligned(val,rp) +#define flat_get_relocate_addr(rel) (rel) +#define flat_set_persistent(relval, p) 0 + +#endif /* __M68KNOMMU_FLAT_H__ */ diff --git a/arch/m68k/include/asm/floppy.h b/arch/m68k/include/asm/floppy.h new file mode 100644 index 00000000000..697d50393dd --- /dev/null +++ b/arch/m68k/include/asm/floppy.h @@ -0,0 +1,254 @@ +/* + * Implementation independent bits of the Floppy driver. + * + * much of this file is derived from what was originally the Q40 floppy driver. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1999, 2000, 2001 + * + * Sun3x support added 2/4/2000 Sam Creasey (sammy@sammy.net) + * + */ + +#include + +#include + +asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id); + +/* constants... */ + +#undef MAX_DMA_ADDRESS +#define MAX_DMA_ADDRESS 0x00 /* nothing like that */ + + +/* + * Again, the CMOS information doesn't work on m68k.. + */ +#define FLOPPY0_TYPE (MACH_IS_Q40 ? 6 : 4) +#define FLOPPY1_TYPE 0 + +/* basically PC init + set use_virtual_dma */ +#define FDC1 m68k_floppy_init() + +#define N_FDC 1 +#define N_DRIVE 8 + + +/* vdma globals adapted from asm-i386/floppy.h */ + +static int virtual_dma_count=0; +static int virtual_dma_residue=0; +static char *virtual_dma_addr=NULL; +static int virtual_dma_mode=0; +static int doing_pdma=0; + +#include + +extern spinlock_t dma_spin_lock; + +static __inline__ unsigned long claim_dma_lock(void) +{ + unsigned long flags; + spin_lock_irqsave(&dma_spin_lock, flags); + return flags; +} + +static __inline__ void release_dma_lock(unsigned long flags) +{ + spin_unlock_irqrestore(&dma_spin_lock, flags); +} + + +static __inline__ unsigned char fd_inb(int port) +{ + if(MACH_IS_Q40) + return inb_p(port); + else if(MACH_IS_SUN3X) + return sun3x_82072_fd_inb(port); + return 0; +} + +static __inline__ void fd_outb(unsigned char value, int port) +{ + if(MACH_IS_Q40) + outb_p(value, port); + else if(MACH_IS_SUN3X) + sun3x_82072_fd_outb(value, port); +} + + +static int fd_request_irq(void) +{ + if(MACH_IS_Q40) + return request_irq(FLOPPY_IRQ, floppy_hardint, + IRQF_DISABLED, "floppy", floppy_hardint); + else if(MACH_IS_SUN3X) + return sun3xflop_request_irq(); + return -ENXIO; +} + +static void fd_free_irq(void) +{ + if(MACH_IS_Q40) + free_irq(FLOPPY_IRQ, floppy_hardint); +} + +#define fd_request_dma() vdma_request_dma(FLOPPY_DMA,"floppy") +#define fd_get_dma_residue() vdma_get_dma_residue(FLOPPY_DMA) +#define fd_dma_mem_alloc(size) vdma_mem_alloc(size) +#define fd_dma_setup(addr, size, mode, io) vdma_dma_setup(addr, size, mode, io) + +#define fd_enable_irq() /* nothing... */ +#define fd_disable_irq() /* nothing... */ + +#define fd_free_dma() /* nothing */ + +/* No 64k boundary crossing problems on Q40 - no DMA at all */ +#define CROSS_64KB(a,s) (0) + +#define DMA_MODE_READ 0x44 /* i386 look-alike */ +#define DMA_MODE_WRITE 0x48 + + +static int m68k_floppy_init(void) +{ + use_virtual_dma =1; + can_use_virtual_dma = 1; + + + if (MACH_IS_Q40) + return 0x3f0; + else if(MACH_IS_SUN3X) + return sun3xflop_init(); + else + return -1; +} + + +static int vdma_request_dma(unsigned int dmanr, const char * device_id) +{ + return 0; +} + + +static int vdma_get_dma_residue(unsigned int dummy) +{ + return virtual_dma_count + virtual_dma_residue; +} + + +static unsigned long vdma_mem_alloc(unsigned long size) +{ + return (unsigned long) vmalloc(size); + +} + +static void _fd_dma_mem_free(unsigned long addr, unsigned long size) +{ + vfree((void *)addr); +} +#define fd_dma_mem_free(addr,size) _fd_dma_mem_free(addr, size) + + +/* choose_dma_mode ???*/ + +static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io) +{ + doing_pdma = 1; + virtual_dma_port = (MACH_IS_Q40 ? io : 0); + virtual_dma_mode = (mode == DMA_MODE_WRITE); + virtual_dma_addr = addr; + virtual_dma_count = size; + virtual_dma_residue = 0; + return 0; +} + + + +static void fd_disable_dma(void) +{ + doing_pdma = 0; + virtual_dma_residue += virtual_dma_count; + virtual_dma_count=0; +} + + + +/* this is the only truly Q40 specific function */ + +asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id) +{ + register unsigned char st; + +#undef TRACE_FLPY_INT +#define NO_FLOPPY_ASSEMBLER + +#ifdef TRACE_FLPY_INT + static int calls=0; + static int bytes=0; + static int dma_wait=0; +#endif + if(!doing_pdma) { + floppy_interrupt(irq, dev_id); + return IRQ_HANDLED; + } + +#ifdef TRACE_FLPY_INT + if(!calls) + bytes = virtual_dma_count; +#endif + + { + register int lcount; + register char *lptr; + + /* serve 1st byte fast: */ + + st=1; + for(lcount=virtual_dma_count, lptr=virtual_dma_addr; + lcount; lcount--, lptr++) { + st=inb(virtual_dma_port+4) & 0xa0 ; + if(st != 0xa0) + break; + if(virtual_dma_mode) + outb_p(*lptr, virtual_dma_port+5); + else + *lptr = inb_p(virtual_dma_port+5); + } + + virtual_dma_count = lcount; + virtual_dma_addr = lptr; + st = inb(virtual_dma_port+4); + } + +#ifdef TRACE_FLPY_INT + calls++; +#endif + if(st == 0x20) + return IRQ_HANDLED; + if(!(st & 0x20)) { + virtual_dma_residue += virtual_dma_count; + virtual_dma_count=0; +#ifdef TRACE_FLPY_INT + printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n", + virtual_dma_count, virtual_dma_residue, calls, bytes, + dma_wait); + calls = 0; + dma_wait=0; +#endif + doing_pdma = 0; + floppy_interrupt(irq, dev_id); + return IRQ_HANDLED; + } +#ifdef TRACE_FLPY_INT + if(!virtual_dma_count) + dma_wait++; +#endif + return IRQ_HANDLED; +} + +#define EXTRA_FLOPPY_PARAMS diff --git a/arch/m68k/include/asm/fpu.h b/arch/m68k/include/asm/fpu.h new file mode 100644 index 00000000000..e19bc5ed9c3 --- /dev/null +++ b/arch/m68k/include/asm/fpu.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "fpu_no.h" +#else +#include "fpu_mm.h" +#endif diff --git a/arch/m68k/include/asm/fpu_mm.h b/arch/m68k/include/asm/fpu_mm.h new file mode 100644 index 00000000000..ffb6b8cfc6d --- /dev/null +++ b/arch/m68k/include/asm/fpu_mm.h @@ -0,0 +1,21 @@ +#ifndef __M68K_FPU_H +#define __M68K_FPU_H + + +/* + * MAX floating point unit state size (FSAVE/FRESTORE) + */ + +#if defined(CONFIG_M68020) || defined(CONFIG_M68030) +#define FPSTATESIZE (216) +#elif defined(CONFIG_M68040) +#define FPSTATESIZE (96) +#elif defined(CONFIG_M68KFPU_EMU) +#define FPSTATESIZE (28) +#elif defined(CONFIG_M68060) +#define FPSTATESIZE (12) +#else +#define FPSTATESIZE (0) +#endif + +#endif /* __M68K_FPU_H */ diff --git a/arch/m68k/include/asm/fpu_no.h b/arch/m68k/include/asm/fpu_no.h new file mode 100644 index 00000000000..b16b2e4fca2 --- /dev/null +++ b/arch/m68k/include/asm/fpu_no.h @@ -0,0 +1,21 @@ +#ifndef __M68KNOMMU_FPU_H +#define __M68KNOMMU_FPU_H + + +/* + * MAX floating point unit state size (FSAVE/FRESTORE) + */ +#if defined(CONFIG_M68020) || defined(CONFIG_M68030) +#define FPSTATESIZE (216/sizeof(unsigned char)) +#elif defined(CONFIG_M68040) +#define FPSTATESIZE (96/sizeof(unsigned char)) +#elif defined(CONFIG_M68KFPU_EMU) +#define FPSTATESIZE (28/sizeof(unsigned char)) +#elif defined(CONFIG_M68060) +#define FPSTATESIZE (12/sizeof(unsigned char)) +#else +/* Assume no FP unit present then... */ +#define FPSTATESIZE (2) /* dummy size */ +#endif + +#endif /* __M68K_FPU_H */ diff --git a/arch/m68k/include/asm/futex.h b/arch/m68k/include/asm/futex.h new file mode 100644 index 00000000000..6a332a9f099 --- /dev/null +++ b/arch/m68k/include/asm/futex.h @@ -0,0 +1,6 @@ +#ifndef _ASM_FUTEX_H +#define _ASM_FUTEX_H + +#include + +#endif diff --git a/arch/m68k/include/asm/hardirq.h b/arch/m68k/include/asm/hardirq.h new file mode 100644 index 00000000000..56d0d5db231 --- /dev/null +++ b/arch/m68k/include/asm/hardirq.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "hardirq_no.h" +#else +#include "hardirq_mm.h" +#endif diff --git a/arch/m68k/include/asm/hardirq_mm.h b/arch/m68k/include/asm/hardirq_mm.h new file mode 100644 index 00000000000..394ee946015 --- /dev/null +++ b/arch/m68k/include/asm/hardirq_mm.h @@ -0,0 +1,16 @@ +#ifndef __M68K_HARDIRQ_H +#define __M68K_HARDIRQ_H + +#include +#include + +/* entry.S is sensitive to the offsets of these fields */ +typedef struct { + unsigned int __softirq_pending; +} ____cacheline_aligned irq_cpustat_t; + +#include /* Standard mappings for irq_cpustat_t above */ + +#define HARDIRQ_BITS 8 + +#endif diff --git a/arch/m68k/include/asm/hardirq_no.h b/arch/m68k/include/asm/hardirq_no.h new file mode 100644 index 00000000000..bfad28149a4 --- /dev/null +++ b/arch/m68k/include/asm/hardirq_no.h @@ -0,0 +1,27 @@ +#ifndef __M68K_HARDIRQ_H +#define __M68K_HARDIRQ_H + +#include +#include +#include + +typedef struct { + unsigned int __softirq_pending; +} ____cacheline_aligned irq_cpustat_t; + +#include /* Standard mappings for irq_cpustat_t above */ + +#define HARDIRQ_BITS 8 + +/* + * The hardirq mask has to be large enough to have + * space for potentially all IRQ sources in the system + * nesting on a single CPU: + */ +#if (1 << HARDIRQ_BITS) < NR_IRQS +# error HARDIRQ_BITS is too low! +#endif + +void ack_bad_irq(unsigned int irq); + +#endif /* __M68K_HARDIRQ_H */ diff --git a/arch/m68k/include/asm/hp300hw.h b/arch/m68k/include/asm/hp300hw.h new file mode 100644 index 00000000000..d998ea67c19 --- /dev/null +++ b/arch/m68k/include/asm/hp300hw.h @@ -0,0 +1,25 @@ +#ifndef _M68K_HP300HW_H +#define _M68K_HP300HW_H + +extern unsigned long hp300_model; + +/* This information was taken from NetBSD */ +#define HP_320 (0) /* 16MHz 68020+HP MMU+16K external cache */ +#define HP_330 (1) /* 16MHz 68020+68851 MMU */ +#define HP_340 (2) /* 16MHz 68030 */ +#define HP_345 (3) /* 50MHz 68030+32K external cache */ +#define HP_350 (4) /* 25MHz 68020+HP MMU+32K external cache */ +#define HP_360 (5) /* 25MHz 68030 */ +#define HP_370 (6) /* 33MHz 68030+64K external cache */ +#define HP_375 (7) /* 50MHz 68030+32K external cache */ +#define HP_380 (8) /* 25MHz 68040 */ +#define HP_385 (9) /* 33MHz 68040 */ + +#define HP_400 (10) /* 50MHz 68030+32K external cache */ +#define HP_425T (11) /* 25MHz 68040 - model 425t */ +#define HP_425S (12) /* 25MHz 68040 - model 425s */ +#define HP_425E (13) /* 25MHz 68040 - model 425e */ +#define HP_433T (14) /* 33MHz 68040 - model 433t */ +#define HP_433S (15) /* 33MHz 68040 - model 433s */ + +#endif /* _M68K_HP300HW_H */ diff --git a/arch/m68k/include/asm/hw_irq.h b/arch/m68k/include/asm/hw_irq.h new file mode 100644 index 00000000000..e1952601589 --- /dev/null +++ b/arch/m68k/include/asm/hw_irq.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "hw_irq_no.h" +#else +#include "hw_irq_mm.h" +#endif diff --git a/arch/m68k/include/asm/hw_irq_mm.h b/arch/m68k/include/asm/hw_irq_mm.h new file mode 100644 index 00000000000..eacef0951fb --- /dev/null +++ b/arch/m68k/include/asm/hw_irq_mm.h @@ -0,0 +1,6 @@ +#ifndef __ASM_M68K_HW_IRQ_H +#define __ASM_M68K_HW_IRQ_H + +/* Dummy include. */ + +#endif diff --git a/arch/m68k/include/asm/hw_irq_no.h b/arch/m68k/include/asm/hw_irq_no.h new file mode 100644 index 00000000000..f3ec9e5ae04 --- /dev/null +++ b/arch/m68k/include/asm/hw_irq_no.h @@ -0,0 +1,4 @@ +#ifndef __M68KNOMMU_HW_IRQ_H__ +#define __M68KNOMMU_HW_IRQ_H__ + +#endif /* __M68KNOMMU_HW_IRQ_H__ */ diff --git a/arch/m68k/include/asm/hwtest.h b/arch/m68k/include/asm/hwtest.h new file mode 100644 index 00000000000..402c8a4401f --- /dev/null +++ b/arch/m68k/include/asm/hwtest.h @@ -0,0 +1,15 @@ +/* Routines to test for presence/absence of hardware registers: + * see arch/m68k/mm/hwtest.c. + * -- PMM 05/1998 + * + * Removed __init from decls. We might want them in modules, and + * the code is tiny anyway. 16/5/98 pb + */ + +#ifndef __ASM_HWTEST_H +#define __ASM_HWTEST_H + +extern int hwreg_present(volatile void *regp); +extern int hwreg_write(volatile void *regp, unsigned short val); + +#endif diff --git a/arch/m68k/include/asm/ide.h b/arch/m68k/include/asm/ide.h new file mode 100644 index 00000000000..b996a3c8cff --- /dev/null +++ b/arch/m68k/include/asm/ide.h @@ -0,0 +1,130 @@ +/* + * linux/include/asm-m68k/ide.h + * + * Copyright (C) 1994-1996 Linus Torvalds & authors + */ + +/* Copyright(c) 1996 Kars de Jong */ +/* Based on the ide driver from 1.2.13pl8 */ + +/* + * Credits (alphabetical): + * + * - Bjoern Brauel + * - Kars de Jong + * - Torsten Ebeling + * - Dwight Engen + * - Thorsten Floeck + * - Roman Hodek + * - Guenther Kelleter + * - Chris Lawrence + * - Michael Rausch + * - Christian Sauer + * - Michael Schmitz + * - Jes Soerensen + * - Michael Thurm + * - Geert Uytterhoeven + */ + +#ifndef _M68K_IDE_H +#define _M68K_IDE_H + +#ifdef __KERNEL__ + + +#include +#include +#include + +#ifdef CONFIG_ATARI +#include +#include +#endif + +#ifdef CONFIG_MAC +#include +#endif + +/* + * Get rid of defs from io.h - ide has its private and conflicting versions + * Since so far no single m68k platform uses ISA/PCI I/O space for IDE, we + * always use the `raw' MMIO versions + */ +#undef inb +#undef inw +#undef insw +#undef inl +#undef insl +#undef outb +#undef outw +#undef outsw +#undef outl +#undef outsl +#undef readb +#undef readw +#undef readl +#undef writeb +#undef writew +#undef writel + +#define inb in_8 +#define inw in_be16 +#define insw(port, addr, n) raw_insw((u16 *)port, addr, n) +#define inl in_be32 +#define insl(port, addr, n) raw_insl((u32 *)port, addr, n) +#define outb(val, port) out_8(port, val) +#define outw(val, port) out_be16(port, val) +#define outsw(port, addr, n) raw_outsw((u16 *)port, addr, n) +#define outl(val, port) out_be32(port, val) +#define outsl(port, addr, n) raw_outsl((u32 *)port, addr, n) +#define readb in_8 +#define readw in_be16 +#define __ide_mm_insw(port, addr, n) raw_insw((u16 *)port, addr, n) +#define readl in_be32 +#define __ide_mm_insl(port, addr, n) raw_insl((u32 *)port, addr, n) +#define writeb(val, port) out_8(port, val) +#define writew(val, port) out_be16(port, val) +#define __ide_mm_outsw(port, addr, n) raw_outsw((u16 *)port, addr, n) +#define writel(val, port) out_be32(port, val) +#define __ide_mm_outsl(port, addr, n) raw_outsl((u32 *)port, addr, n) +#if defined(CONFIG_ATARI) || defined(CONFIG_Q40) +#define insw_swapw(port, addr, n) raw_insw_swapw((u16 *)port, addr, n) +#define outsw_swapw(port, addr, n) raw_outsw_swapw((u16 *)port, addr, n) +#endif + +#ifdef CONFIG_BLK_DEV_FALCON_IDE +#define IDE_ARCH_LOCK + +extern int falconide_intr_lock; + +static __inline__ void ide_release_lock (void) +{ + if (MACH_IS_ATARI) { + if (falconide_intr_lock == 0) { + printk("ide_release_lock: bug\n"); + return; + } + falconide_intr_lock = 0; + stdma_release(); + } +} + +static __inline__ void +ide_get_lock(irq_handler_t handler, void *data) +{ + if (MACH_IS_ATARI) { + if (falconide_intr_lock == 0) { + if (in_interrupt() > 0) + panic( "Falcon IDE hasn't ST-DMA lock in interrupt" ); + stdma_lock(handler, data); + falconide_intr_lock = 1; + } + } +} +#endif /* CONFIG_BLK_DEV_FALCON_IDE */ + +#define IDE_ARCH_ACK_INTR +#define ide_ack_intr(hwif) ((hwif)->ack_intr ? (hwif)->ack_intr(hwif) : 1) + +#endif /* __KERNEL__ */ +#endif /* _M68K_IDE_H */ diff --git a/arch/m68k/include/asm/idprom.h b/arch/m68k/include/asm/idprom.h new file mode 100644 index 00000000000..160616a89e0 --- /dev/null +++ b/arch/m68k/include/asm/idprom.h @@ -0,0 +1,27 @@ +#ifndef _M68K_IDPROM_H +#define _M68K_IDPROM_H +/* + * idprom.h: Macros and defines for idprom routines + * + * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu) + */ + +#include + +struct idprom { + u8 id_format; /* Format identifier (always 0x01) */ + u8 id_machtype; /* Machine type */ + u8 id_ethaddr[6]; /* Hardware ethernet address */ + s32 id_date; /* Date of manufacture */ + u32 id_sernum:24; /* Unique serial number */ + u8 id_cksum; /* Checksum - xor of the data bytes */ + u8 reserved[16]; +}; + +extern struct idprom *idprom; +extern void idprom_init(void); + +/* Sun3: in control space */ +#define SUN3_IDPROM_BASE 0x00000000 + +#endif /* !(_M68K_IDPROM_H) */ diff --git a/arch/m68k/include/asm/intersil.h b/arch/m68k/include/asm/intersil.h new file mode 100644 index 00000000000..f482902cac8 --- /dev/null +++ b/arch/m68k/include/asm/intersil.h @@ -0,0 +1,48 @@ +#ifndef _SUN3_INTERSIL_H +#define _SUN3_INTERSIL_H +/* bits 0 and 1 */ +#define INTERSIL_FREQ_32K 0x00 +#define INTERSIL_FREQ_1M 0x01 +#define INTERSIL_FREQ_2M 0x02 +#define INTERSIL_FREQ_4M 0x03 + +/* bit 2 */ +#define INTERSIL_12H_MODE 0x00 +#define INTERSIL_24H_MODE 0x04 + +/* bit 3 */ +#define INTERSIL_STOP 0x00 +#define INTERSIL_RUN 0x08 + +/* bit 4 */ +#define INTERSIL_INT_ENABLE 0x10 +#define INTERSIL_INT_DISABLE 0x00 + +/* bit 5 */ +#define INTERSIL_MODE_NORMAL 0x00 +#define INTERSIL_MODE_TEST 0x20 + +#define INTERSIL_HZ_100_MASK 0x02 + +struct intersil_dt { + unsigned char csec; + unsigned char hour; + unsigned char minute; + unsigned char second; + unsigned char month; + unsigned char day; + unsigned char year; + unsigned char weekday; +}; + +struct intersil_7170 { + struct intersil_dt counter; + struct intersil_dt alarm; + unsigned char int_reg; + unsigned char cmd_reg; +}; + +extern volatile char* clock_va; +#define intersil_clock ((volatile struct intersil_7170 *) clock_va) +#define intersil_clear() (void)intersil_clock->int_reg +#endif diff --git a/arch/m68k/include/asm/io.h b/arch/m68k/include/asm/io.h new file mode 100644 index 00000000000..c7210ba184e --- /dev/null +++ b/arch/m68k/include/asm/io.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "io_no.h" +#else +#include "io_mm.h" +#endif diff --git a/arch/m68k/include/asm/io_mm.h b/arch/m68k/include/asm/io_mm.h new file mode 100644 index 00000000000..9e673e3bd43 --- /dev/null +++ b/arch/m68k/include/asm/io_mm.h @@ -0,0 +1,369 @@ +/* + * linux/include/asm-m68k/io.h + * + * 4/1/00 RZ: - rewritten to avoid clashes between ISA/PCI and other + * IO access + * - added Q40 support + * - added skeleton for GG-II and Amiga PCMCIA + * 2/3/01 RZ: - moved a few more defs into raw_io.h + * + * inX/outX should not be used by any driver unless it does + * ISA access. Other drivers should use function defined in raw_io.h + * or define its own macros on top of these. + * + * inX(),outX() are for ISA I/O + * isa_readX(),isa_writeX() are for ISA memory + */ + +#ifndef _IO_H +#define _IO_H + +#ifdef __KERNEL__ + +#include +#include +#include + +#include + +#ifdef CONFIG_ATARI +#include +#endif + + +/* + * IO/MEM definitions for various ISA bridges + */ + + +#ifdef CONFIG_Q40 + +#define q40_isa_io_base 0xff400000 +#define q40_isa_mem_base 0xff800000 + +#define Q40_ISA_IO_B(ioaddr) (q40_isa_io_base+1+4*((unsigned long)(ioaddr))) +#define Q40_ISA_IO_W(ioaddr) (q40_isa_io_base+ 4*((unsigned long)(ioaddr))) +#define Q40_ISA_MEM_B(madr) (q40_isa_mem_base+1+4*((unsigned long)(madr))) +#define Q40_ISA_MEM_W(madr) (q40_isa_mem_base+ 4*((unsigned long)(madr))) + +#define MULTI_ISA 0 +#endif /* Q40 */ + +/* GG-II Zorro to ISA bridge */ +#ifdef CONFIG_GG2 + +extern unsigned long gg2_isa_base; +#define GG2_ISA_IO_B(ioaddr) (gg2_isa_base+1+((unsigned long)(ioaddr)*4)) +#define GG2_ISA_IO_W(ioaddr) (gg2_isa_base+ ((unsigned long)(ioaddr)*4)) +#define GG2_ISA_MEM_B(madr) (gg2_isa_base+1+(((unsigned long)(madr)*4) & 0xfffff)) +#define GG2_ISA_MEM_W(madr) (gg2_isa_base+ (((unsigned long)(madr)*4) & 0xfffff)) + +#ifndef MULTI_ISA +#define MULTI_ISA 0 +#else +#undef MULTI_ISA +#define MULTI_ISA 1 +#endif +#endif /* GG2 */ + +#ifdef CONFIG_AMIGA_PCMCIA +#include + +#define AG_ISA_IO_B(ioaddr) ( GAYLE_IO+(ioaddr)+(((ioaddr)&1)*GAYLE_ODD) ) +#define AG_ISA_IO_W(ioaddr) ( GAYLE_IO+(ioaddr) ) + +#ifndef MULTI_ISA +#define MULTI_ISA 0 +#else +#undef MULTI_ISA +#define MULTI_ISA 1 +#endif +#endif /* AMIGA_PCMCIA */ + + + +#ifdef CONFIG_ISA + +#if MULTI_ISA == 0 +#undef MULTI_ISA +#endif + +#define ISA_TYPE_Q40 (1) +#define ISA_TYPE_GG2 (2) +#define ISA_TYPE_AG (3) + +#if defined(CONFIG_Q40) && !defined(MULTI_ISA) +#define ISA_TYPE ISA_TYPE_Q40 +#define ISA_SEX 0 +#endif +#if defined(CONFIG_AMIGA_PCMCIA) && !defined(MULTI_ISA) +#define ISA_TYPE ISA_TYPE_AG +#define ISA_SEX 1 +#endif +#if defined(CONFIG_GG2) && !defined(MULTI_ISA) +#define ISA_TYPE ISA_TYPE_GG2 +#define ISA_SEX 0 +#endif + +#ifdef MULTI_ISA +extern int isa_type; +extern int isa_sex; + +#define ISA_TYPE isa_type +#define ISA_SEX isa_sex +#endif + +/* + * define inline addr translation functions. Normally only one variant will + * be compiled in so the case statement will be optimised away + */ + +static inline u8 __iomem *isa_itb(unsigned long addr) +{ + switch(ISA_TYPE) + { +#ifdef CONFIG_Q40 + case ISA_TYPE_Q40: return (u8 __iomem *)Q40_ISA_IO_B(addr); +#endif +#ifdef CONFIG_GG2 + case ISA_TYPE_GG2: return (u8 __iomem *)GG2_ISA_IO_B(addr); +#endif +#ifdef CONFIG_AMIGA_PCMCIA + case ISA_TYPE_AG: return (u8 __iomem *)AG_ISA_IO_B(addr); +#endif + default: return NULL; /* avoid warnings, just in case */ + } +} +static inline u16 __iomem *isa_itw(unsigned long addr) +{ + switch(ISA_TYPE) + { +#ifdef CONFIG_Q40 + case ISA_TYPE_Q40: return (u16 __iomem *)Q40_ISA_IO_W(addr); +#endif +#ifdef CONFIG_GG2 + case ISA_TYPE_GG2: return (u16 __iomem *)GG2_ISA_IO_W(addr); +#endif +#ifdef CONFIG_AMIGA_PCMCIA + case ISA_TYPE_AG: return (u16 __iomem *)AG_ISA_IO_W(addr); +#endif + default: return NULL; /* avoid warnings, just in case */ + } +} +static inline u32 __iomem *isa_itl(unsigned long addr) +{ + switch(ISA_TYPE) + { +#ifdef CONFIG_AMIGA_PCMCIA + case ISA_TYPE_AG: return (u32 __iomem *)AG_ISA_IO_W(addr); +#endif + default: return 0; /* avoid warnings, just in case */ + } +} +static inline u8 __iomem *isa_mtb(unsigned long addr) +{ + switch(ISA_TYPE) + { +#ifdef CONFIG_Q40 + case ISA_TYPE_Q40: return (u8 __iomem *)Q40_ISA_MEM_B(addr); +#endif +#ifdef CONFIG_GG2 + case ISA_TYPE_GG2: return (u8 __iomem *)GG2_ISA_MEM_B(addr); +#endif +#ifdef CONFIG_AMIGA_PCMCIA + case ISA_TYPE_AG: return (u8 __iomem *)addr; +#endif + default: return NULL; /* avoid warnings, just in case */ + } +} +static inline u16 __iomem *isa_mtw(unsigned long addr) +{ + switch(ISA_TYPE) + { +#ifdef CONFIG_Q40 + case ISA_TYPE_Q40: return (u16 __iomem *)Q40_ISA_MEM_W(addr); +#endif +#ifdef CONFIG_GG2 + case ISA_TYPE_GG2: return (u16 __iomem *)GG2_ISA_MEM_W(addr); +#endif +#ifdef CONFIG_AMIGA_PCMCIA + case ISA_TYPE_AG: return (u16 __iomem *)addr; +#endif + default: return NULL; /* avoid warnings, just in case */ + } +} + + +#define isa_inb(port) in_8(isa_itb(port)) +#define isa_inw(port) (ISA_SEX ? in_be16(isa_itw(port)) : in_le16(isa_itw(port))) +#define isa_inl(port) (ISA_SEX ? in_be32(isa_itl(port)) : in_le32(isa_itl(port))) +#define isa_outb(val,port) out_8(isa_itb(port),(val)) +#define isa_outw(val,port) (ISA_SEX ? out_be16(isa_itw(port),(val)) : out_le16(isa_itw(port),(val))) +#define isa_outl(val,port) (ISA_SEX ? out_be32(isa_itl(port),(val)) : out_le32(isa_itl(port),(val))) + +#define isa_readb(p) in_8(isa_mtb((unsigned long)(p))) +#define isa_readw(p) \ + (ISA_SEX ? in_be16(isa_mtw((unsigned long)(p))) \ + : in_le16(isa_mtw((unsigned long)(p)))) +#define isa_writeb(val,p) out_8(isa_mtb((unsigned long)(p)),(val)) +#define isa_writew(val,p) \ + (ISA_SEX ? out_be16(isa_mtw((unsigned long)(p)),(val)) \ + : out_le16(isa_mtw((unsigned long)(p)),(val))) + +static inline void isa_delay(void) +{ + switch(ISA_TYPE) + { +#ifdef CONFIG_Q40 + case ISA_TYPE_Q40: isa_outb(0,0x80); break; +#endif +#ifdef CONFIG_GG2 + case ISA_TYPE_GG2: break; +#endif +#ifdef CONFIG_AMIGA_PCMCIA + case ISA_TYPE_AG: break; +#endif + default: break; /* avoid warnings */ + } +} + +#define isa_inb_p(p) ({u8 v=isa_inb(p);isa_delay();v;}) +#define isa_outb_p(v,p) ({isa_outb((v),(p));isa_delay();}) +#define isa_inw_p(p) ({u16 v=isa_inw(p);isa_delay();v;}) +#define isa_outw_p(v,p) ({isa_outw((v),(p));isa_delay();}) +#define isa_inl_p(p) ({u32 v=isa_inl(p);isa_delay();v;}) +#define isa_outl_p(v,p) ({isa_outl((v),(p));isa_delay();}) + +#define isa_insb(port, buf, nr) raw_insb(isa_itb(port), (u8 *)(buf), (nr)) +#define isa_outsb(port, buf, nr) raw_outsb(isa_itb(port), (u8 *)(buf), (nr)) + +#define isa_insw(port, buf, nr) \ + (ISA_SEX ? raw_insw(isa_itw(port), (u16 *)(buf), (nr)) : \ + raw_insw_swapw(isa_itw(port), (u16 *)(buf), (nr))) + +#define isa_outsw(port, buf, nr) \ + (ISA_SEX ? raw_outsw(isa_itw(port), (u16 *)(buf), (nr)) : \ + raw_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr))) + +#define isa_insl(port, buf, nr) \ + (ISA_SEX ? raw_insl(isa_itl(port), (u32 *)(buf), (nr)) : \ + raw_insw_swapw(isa_itw(port), (u16 *)(buf), (nr)<<1)) + +#define isa_outsl(port, buf, nr) \ + (ISA_SEX ? raw_outsl(isa_itl(port), (u32 *)(buf), (nr)) : \ + raw_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr)<<1)) + + +#define inb isa_inb +#define inb_p isa_inb_p +#define outb isa_outb +#define outb_p isa_outb_p +#define inw isa_inw +#define inw_p isa_inw_p +#define outw isa_outw +#define outw_p isa_outw_p +#define inl isa_inl +#define inl_p isa_inl_p +#define outl isa_outl +#define outl_p isa_outl_p +#define insb isa_insb +#define insw isa_insw +#define insl isa_insl +#define outsb isa_outsb +#define outsw isa_outsw +#define outsl isa_outsl +#define readb isa_readb +#define readw isa_readw +#define writeb isa_writeb +#define writew isa_writew + +#else /* CONFIG_ISA */ + +/* + * We need to define dummy functions for GENERIC_IOMAP support. + */ +#define inb(port) 0xff +#define inb_p(port) 0xff +#define outb(val,port) ((void)0) +#define outb_p(val,port) ((void)0) +#define inw(port) 0xffff +#define outw(val,port) ((void)0) +#define inl(port) 0xffffffffUL +#define outl(val,port) ((void)0) + +#define insb(port,buf,nr) ((void)0) +#define outsb(port,buf,nr) ((void)0) +#define insw(port,buf,nr) ((void)0) +#define outsw(port,buf,nr) ((void)0) +#define insl(port,buf,nr) ((void)0) +#define outsl(port,buf,nr) ((void)0) + +/* + * These should be valid on any ioremap()ed region + */ +#define readb(addr) in_8(addr) +#define writeb(val,addr) out_8((addr),(val)) +#define readw(addr) in_le16(addr) +#define writew(val,addr) out_le16((addr),(val)) + +#endif /* CONFIG_ISA */ + +#define readl(addr) in_le32(addr) +#define writel(val,addr) out_le32((addr),(val)) + +#define mmiowb() + +static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); +} +static inline void __iomem *ioremap_nocache(unsigned long physaddr, unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); +} +static inline void __iomem *ioremap_writethrough(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_WRITETHROUGH); +} +static inline void __iomem *ioremap_fullcache(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_FULL_CACHING); +} + +static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count) +{ + __builtin_memset((void __force *) addr, val, count); +} +static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, int count) +{ + __builtin_memcpy(dst, (void __force *) src, count); +} +static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int count) +{ + __builtin_memcpy((void __force *) dst, src, count); +} + +#ifndef CONFIG_SUN3 +#define IO_SPACE_LIMIT 0xffff +#else +#define IO_SPACE_LIMIT 0x0fffffff +#endif + +#endif /* __KERNEL__ */ + +#define __ARCH_HAS_NO_PAGE_ZERO_MAPPED 1 + +/* + * Convert a physical pointer to a virtual kernel pointer for /dev/mem + * access + */ +#define xlate_dev_mem_ptr(p) __va(p) + +/* + * Convert a virtual cached pointer to an uncached pointer + */ +#define xlate_dev_kmem_ptr(p) p + +#endif /* _IO_H */ diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h new file mode 100644 index 00000000000..6adef1ee208 --- /dev/null +++ b/arch/m68k/include/asm/io_no.h @@ -0,0 +1,194 @@ +#ifndef _M68KNOMMU_IO_H +#define _M68KNOMMU_IO_H + +#ifdef __KERNEL__ + + +/* + * These are for ISA/PCI shared memory _only_ and should never be used + * on any other type of memory, including Zorro memory. They are meant to + * access the bus in the bus byte order which is little-endian!. + * + * readX/writeX() are used to access memory mapped devices. On some + * architectures the memory mapped IO stuff needs to be accessed + * differently. On the m68k architecture, we just read/write the + * memory location directly. + */ +/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates + * two accesses to memory, which may be undesireable for some devices. + */ + +/* + * swap functions are sometimes needed to interface little-endian hardware + */ +static inline unsigned short _swapw(volatile unsigned short v) +{ + return ((v << 8) | (v >> 8)); +} + +static inline unsigned int _swapl(volatile unsigned long v) +{ + return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24)); +} + +#define readb(addr) \ + ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; }) +#define readw(addr) \ + ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; }) +#define readl(addr) \ + ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; }) + +#define readb_relaxed(addr) readb(addr) +#define readw_relaxed(addr) readw(addr) +#define readl_relaxed(addr) readl(addr) + +#define writeb(b,addr) (void)((*(volatile unsigned char *) (addr)) = (b)) +#define writew(b,addr) (void)((*(volatile unsigned short *) (addr)) = (b)) +#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b)) + +#define __raw_readb readb +#define __raw_readw readw +#define __raw_readl readl +#define __raw_writeb writeb +#define __raw_writew writew +#define __raw_writel writel + +static inline void io_outsb(unsigned int addr, void *buf, int len) +{ + volatile unsigned char *ap = (volatile unsigned char *) addr; + unsigned char *bp = (unsigned char *) buf; + while (len--) + *ap = *bp++; +} + +static inline void io_outsw(unsigned int addr, void *buf, int len) +{ + volatile unsigned short *ap = (volatile unsigned short *) addr; + unsigned short *bp = (unsigned short *) buf; + while (len--) + *ap = _swapw(*bp++); +} + +static inline void io_outsl(unsigned int addr, void *buf, int len) +{ + volatile unsigned int *ap = (volatile unsigned int *) addr; + unsigned int *bp = (unsigned int *) buf; + while (len--) + *ap = _swapl(*bp++); +} + +static inline void io_insb(unsigned int addr, void *buf, int len) +{ + volatile unsigned char *ap = (volatile unsigned char *) addr; + unsigned char *bp = (unsigned char *) buf; + while (len--) + *bp++ = *ap; +} + +static inline void io_insw(unsigned int addr, void *buf, int len) +{ + volatile unsigned short *ap = (volatile unsigned short *) addr; + unsigned short *bp = (unsigned short *) buf; + while (len--) + *bp++ = _swapw(*ap); +} + +static inline void io_insl(unsigned int addr, void *buf, int len) +{ + volatile unsigned int *ap = (volatile unsigned int *) addr; + unsigned int *bp = (unsigned int *) buf; + while (len--) + *bp++ = _swapl(*ap); +} + +#define mmiowb() + +/* + * make the short names macros so specific devices + * can override them as required + */ + +#define memset_io(a,b,c) memset((void *)(a),(b),(c)) +#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) +#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) + +#define inb(addr) readb(addr) +#define inw(addr) readw(addr) +#define inl(addr) readl(addr) +#define outb(x,addr) ((void) writeb(x,addr)) +#define outw(x,addr) ((void) writew(x,addr)) +#define outl(x,addr) ((void) writel(x,addr)) + +#define inb_p(addr) inb(addr) +#define inw_p(addr) inw(addr) +#define inl_p(addr) inl(addr) +#define outb_p(x,addr) outb(x,addr) +#define outw_p(x,addr) outw(x,addr) +#define outl_p(x,addr) outl(x,addr) + +#define outsb(a,b,l) io_outsb(a,b,l) +#define outsw(a,b,l) io_outsw(a,b,l) +#define outsl(a,b,l) io_outsl(a,b,l) + +#define insb(a,b,l) io_insb(a,b,l) +#define insw(a,b,l) io_insw(a,b,l) +#define insl(a,b,l) io_insl(a,b,l) + +#define IO_SPACE_LIMIT 0xffff + + +/* Values for nocacheflag and cmode */ +#define IOMAP_FULL_CACHING 0 +#define IOMAP_NOCACHE_SER 1 +#define IOMAP_NOCACHE_NONSER 2 +#define IOMAP_WRITETHROUGH 3 + +extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag); +extern void __iounmap(void *addr, unsigned long size); + +static inline void *ioremap(unsigned long physaddr, unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); +} +static inline void *ioremap_nocache(unsigned long physaddr, unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); +} +static inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_WRITETHROUGH); +} +static inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_FULL_CACHING); +} + +extern void iounmap(void *addr); + +/* Pages to physical address... */ +#define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT) +#define page_to_bus(page) ((page - mem_map) << PAGE_SHIFT) + +/* + * Macros used for converting between virtual and physical mappings. + */ +#define phys_to_virt(vaddr) ((void *) (vaddr)) +#define virt_to_phys(vaddr) ((unsigned long) (vaddr)) + +#define virt_to_bus virt_to_phys +#define bus_to_virt phys_to_virt + +/* + * Convert a physical pointer to a virtual kernel pointer for /dev/mem + * access + */ +#define xlate_dev_mem_ptr(p) __va(p) + +/* + * Convert a virtual cached pointer to an uncached pointer + */ +#define xlate_dev_kmem_ptr(p) p + +#endif /* __KERNEL__ */ + +#endif /* _M68KNOMMU_IO_H */ diff --git a/arch/m68k/include/asm/ioctl.h b/arch/m68k/include/asm/ioctl.h new file mode 100644 index 00000000000..b279fe06dfe --- /dev/null +++ b/arch/m68k/include/asm/ioctl.h @@ -0,0 +1 @@ +#include diff --git a/arch/m68k/include/asm/ioctls.h b/arch/m68k/include/asm/ioctls.h new file mode 100644 index 00000000000..b8d2f4be7fd --- /dev/null +++ b/arch/m68k/include/asm/ioctls.h @@ -0,0 +1,84 @@ +#ifndef __ARCH_M68K_IOCTLS_H__ +#define __ARCH_M68K_IOCTLS_H__ + +#include + +/* 0x54 is just a magic number to make these relatively unique ('T') */ + +#define TCGETS 0x5401 +#define TCSETS 0x5402 +#define TCSETSW 0x5403 +#define TCSETSF 0x5404 +#define TCGETA 0x5405 +#define TCSETA 0x5406 +#define TCSETAW 0x5407 +#define TCSETAF 0x5408 +#define TCSBRK 0x5409 +#define TCXONC 0x540A +#define TCFLSH 0x540B +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E +#define TIOCGPGRP 0x540F +#define TIOCSPGRP 0x5410 +#define TIOCOUTQ 0x5411 +#define TIOCSTI 0x5412 +#define TIOCGWINSZ 0x5413 +#define TIOCSWINSZ 0x5414 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define FIONREAD 0x541B +#define TIOCINQ FIONREAD +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420 +#define FIONBIO 0x5421 +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TIOCSBRK 0x5427 /* BSD compatibility */ +#define TIOCCBRK 0x5428 /* BSD compatibility */ +#define TIOCGSID 0x5429 /* Return the session ID of FD */ +#define TCGETS2 _IOR('T',0x2A, struct termios2) +#define TCSETS2 _IOW('T',0x2B, struct termios2) +#define TCSETSW2 _IOW('T',0x2C, struct termios2) +#define TCSETSF2 _IOW('T',0x2D, struct termios2) +#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ +#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ + +#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ +#define FIOCLEX 0x5451 +#define FIOASYNC 0x5452 +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 +#define TIOCGLCKTRMIOS 0x5456 +#define TIOCSLCKTRMIOS 0x5457 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ + +#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ +#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ +#define FIOQSIZE 0x545E + +/* Used for packet mode */ +#define TIOCPKT_DATA 0 +#define TIOCPKT_FLUSHREAD 1 +#define TIOCPKT_FLUSHWRITE 2 +#define TIOCPKT_STOP 4 +#define TIOCPKT_START 8 +#define TIOCPKT_NOSTOP 16 +#define TIOCPKT_DOSTOP 32 + +#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ + +#endif /* __ARCH_M68K_IOCTLS_H__ */ diff --git a/arch/m68k/include/asm/ipcbuf.h b/arch/m68k/include/asm/ipcbuf.h new file mode 100644 index 00000000000..a623ea3f095 --- /dev/null +++ b/arch/m68k/include/asm/ipcbuf.h @@ -0,0 +1,29 @@ +#ifndef __m68k_IPCBUF_H__ +#define __m68k_IPCBUF_H__ + +/* + * The user_ipc_perm structure for m68k architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 32-bit mode_t and seq + * - 2 miscellaneous 32-bit values + */ + +struct ipc64_perm +{ + __kernel_key_t key; + __kernel_uid32_t uid; + __kernel_gid32_t gid; + __kernel_uid32_t cuid; + __kernel_gid32_t cgid; + __kernel_mode_t mode; + unsigned short __pad1; + unsigned short seq; + unsigned short __pad2; + unsigned long __unused1; + unsigned long __unused2; +}; + +#endif /* __m68k_IPCBUF_H__ */ diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h new file mode 100644 index 00000000000..d031416595b --- /dev/null +++ b/arch/m68k/include/asm/irq.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "irq_no.h" +#else +#include "irq_mm.h" +#endif diff --git a/arch/m68k/include/asm/irq_mm.h b/arch/m68k/include/asm/irq_mm.h new file mode 100644 index 00000000000..226bfc0f21b --- /dev/null +++ b/arch/m68k/include/asm/irq_mm.h @@ -0,0 +1,125 @@ +#ifndef _M68K_IRQ_H_ +#define _M68K_IRQ_H_ + +#include +#include +#include + +/* + * This should be the same as the max(NUM_X_SOURCES) for all the + * different m68k hosts compiled into the kernel. + * Currently the Atari has 72 and the Amiga 24, but if both are + * supported in the kernel it is better to make room for 72. + */ +#if defined(CONFIG_VME) || defined(CONFIG_SUN3) || defined(CONFIG_SUN3X) +#define NR_IRQS 200 +#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) +#define NR_IRQS 72 +#elif defined(CONFIG_Q40) +#define NR_IRQS 43 +#elif defined(CONFIG_AMIGA) +#define NR_IRQS 32 +#elif defined(CONFIG_APOLLO) +#define NR_IRQS 24 +#elif defined(CONFIG_HP300) +#define NR_IRQS 8 +#else +#define NR_IRQS 0 +#endif + +/* + * The hardirq mask has to be large enough to have + * space for potentially all IRQ sources in the system + * nesting on a single CPU: + */ +#if (1 << HARDIRQ_BITS) < NR_IRQS +# error HARDIRQ_BITS is too low! +#endif + +/* + * Interrupt source definitions + * General interrupt sources are the level 1-7. + * Adding an interrupt service routine for one of these sources + * results in the addition of that routine to a chain of routines. + * Each one is called in succession. Each individual interrupt + * service routine should determine if the device associated with + * that routine requires service. + */ + +#define IRQ_SPURIOUS 0 + +#define IRQ_AUTO_1 1 /* level 1 interrupt */ +#define IRQ_AUTO_2 2 /* level 2 interrupt */ +#define IRQ_AUTO_3 3 /* level 3 interrupt */ +#define IRQ_AUTO_4 4 /* level 4 interrupt */ +#define IRQ_AUTO_5 5 /* level 5 interrupt */ +#define IRQ_AUTO_6 6 /* level 6 interrupt */ +#define IRQ_AUTO_7 7 /* level 7 interrupt (non-maskable) */ + +#define IRQ_USER 8 + +extern unsigned int irq_canonicalize(unsigned int irq); + +struct pt_regs; + +/* + * various flags for request_irq() - the Amiga now uses the standard + * mechanism like all other architectures - IRQF_DISABLED and + * IRQF_SHARED are your friends. + */ +#ifndef MACH_AMIGA_ONLY +#define IRQ_FLG_LOCK (0x0001) /* handler is not replaceable */ +#define IRQ_FLG_REPLACE (0x0002) /* replace existing handler */ +#define IRQ_FLG_FAST (0x0004) +#define IRQ_FLG_SLOW (0x0008) +#define IRQ_FLG_STD (0x8000) /* internally used */ +#endif + +/* + * This structure is used to chain together the ISRs for a particular + * interrupt source (if it supports chaining). + */ +typedef struct irq_node { + int (*handler)(int, void *); + void *dev_id; + struct irq_node *next; + unsigned long flags; + const char *devname; +} irq_node_t; + +/* + * This structure has only 4 elements for speed reasons + */ +struct irq_handler { + int (*handler)(int, void *); + unsigned long flags; + void *dev_id; + const char *devname; +}; + +struct irq_controller { + const char *name; + spinlock_t lock; + int (*startup)(unsigned int irq); + void (*shutdown)(unsigned int irq); + void (*enable)(unsigned int irq); + void (*disable)(unsigned int irq); +}; + +extern int m68k_irq_startup(unsigned int); +extern void m68k_irq_shutdown(unsigned int); + +/* + * This function returns a new irq_node_t + */ +extern irq_node_t *new_irq_node(void); + +extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)); +extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, + void (*handler)(unsigned int, struct pt_regs *)); +extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int); + +asmlinkage void m68k_handle_int(unsigned int); +asmlinkage void __m68k_handle_int(unsigned int, struct pt_regs *); + +#endif /* _M68K_IRQ_H_ */ diff --git a/arch/m68k/include/asm/irq_no.h b/arch/m68k/include/asm/irq_no.h new file mode 100644 index 00000000000..9373c31ac87 --- /dev/null +++ b/arch/m68k/include/asm/irq_no.h @@ -0,0 +1,26 @@ +#ifndef _M68KNOMMU_IRQ_H_ +#define _M68KNOMMU_IRQ_H_ + +#ifdef CONFIG_COLDFIRE +/* + * On the ColdFire we keep track of all vectors. That way drivers + * can register whatever vector number they wish, and we can deal + * with it. + */ +#define SYS_IRQS 256 +#define NR_IRQS SYS_IRQS + +#else + +/* + * # of m68k interrupts + */ +#define SYS_IRQS 8 +#define NR_IRQS (24 + SYS_IRQS) + +#endif /* CONFIG_COLDFIRE */ + + +#define irq_canonicalize(irq) (irq) + +#endif /* _M68KNOMMU_IRQ_H_ */ diff --git a/arch/m68k/include/asm/irq_regs.h b/arch/m68k/include/asm/irq_regs.h new file mode 100644 index 00000000000..3dd9c0b7027 --- /dev/null +++ b/arch/m68k/include/asm/irq_regs.h @@ -0,0 +1 @@ +#include diff --git a/arch/m68k/include/asm/kdebug.h b/arch/m68k/include/asm/kdebug.h new file mode 100644 index 00000000000..6ece1b03766 --- /dev/null +++ b/arch/m68k/include/asm/kdebug.h @@ -0,0 +1 @@ +#include diff --git a/arch/m68k/include/asm/kmap_types.h b/arch/m68k/include/asm/kmap_types.h new file mode 100644 index 00000000000..045d9fd122a --- /dev/null +++ b/arch/m68k/include/asm/kmap_types.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "kmap_types_no.h" +#else +#include "kmap_types_mm.h" +#endif diff --git a/arch/m68k/include/asm/kmap_types_mm.h b/arch/m68k/include/asm/kmap_types_mm.h new file mode 100644 index 00000000000..c843c63d380 --- /dev/null +++ b/arch/m68k/include/asm/kmap_types_mm.h @@ -0,0 +1,21 @@ +#ifndef __ASM_M68K_KMAP_TYPES_H +#define __ASM_M68K_KMAP_TYPES_H + +enum km_type { + KM_BOUNCE_READ, + KM_SKB_SUNRPC_DATA, + KM_SKB_DATA_SOFTIRQ, + KM_USER0, + KM_USER1, + KM_BIO_SRC_IRQ, + KM_BIO_DST_IRQ, + KM_PTE0, + KM_PTE1, + KM_IRQ0, + KM_IRQ1, + KM_SOFTIRQ0, + KM_SOFTIRQ1, + KM_TYPE_NR +}; + +#endif /* __ASM_M68K_KMAP_TYPES_H */ diff --git a/arch/m68k/include/asm/kmap_types_no.h b/arch/m68k/include/asm/kmap_types_no.h new file mode 100644 index 00000000000..bfb6707575d --- /dev/null +++ b/arch/m68k/include/asm/kmap_types_no.h @@ -0,0 +1,21 @@ +#ifndef __ASM_M68K_KMAP_TYPES_H +#define __ASM_M68K_KMAP_TYPES_H + +enum km_type { + KM_BOUNCE_READ, + KM_SKB_SUNRPC_DATA, + KM_SKB_DATA_SOFTIRQ, + KM_USER0, + KM_USER1, + KM_BIO_SRC_IRQ, + KM_BIO_DST_IRQ, + KM_PTE0, + KM_PTE1, + KM_IRQ0, + KM_IRQ1, + KM_SOFTIRQ0, + KM_SOFTIRQ1, + KM_TYPE_NR +}; + +#endif diff --git a/arch/m68k/include/asm/linkage.h b/arch/m68k/include/asm/linkage.h new file mode 100644 index 00000000000..5a822bb790f --- /dev/null +++ b/arch/m68k/include/asm/linkage.h @@ -0,0 +1,7 @@ +#ifndef __ASM_LINKAGE_H +#define __ASM_LINKAGE_H + +#define __ALIGN .align 4 +#define __ALIGN_STR ".align 4" + +#endif diff --git a/arch/m68k/include/asm/local.h b/arch/m68k/include/asm/local.h new file mode 100644 index 00000000000..6c259263e1f --- /dev/null +++ b/arch/m68k/include/asm/local.h @@ -0,0 +1,6 @@ +#ifndef _ASM_M68K_LOCAL_H +#define _ASM_M68K_LOCAL_H + +#include + +#endif /* _ASM_M68K_LOCAL_H */ diff --git a/arch/m68k/include/asm/m5206sim.h b/arch/m68k/include/asm/m5206sim.h new file mode 100644 index 00000000000..7e3594dea88 --- /dev/null +++ b/arch/m68k/include/asm/m5206sim.h @@ -0,0 +1,131 @@ +/****************************************************************************/ + +/* + * m5206sim.h -- ColdFire 5206 System Integration Module support. + * + * (C) Copyright 1999, Greg Ungerer (gerg@snapgear.com) + * (C) Copyright 2000, Lineo Inc. (www.lineo.com) + */ + +/****************************************************************************/ +#ifndef m5206sim_h +#define m5206sim_h +/****************************************************************************/ + + +/* + * Define the 5206 SIM register set addresses. + */ +#define MCFSIM_SIMR 0x03 /* SIM Config reg (r/w) */ +#define MCFSIM_ICR1 0x14 /* Intr Ctrl reg 1 (r/w) */ +#define MCFSIM_ICR2 0x15 /* Intr Ctrl reg 2 (r/w) */ +#define MCFSIM_ICR3 0x16 /* Intr Ctrl reg 3 (r/w) */ +#define MCFSIM_ICR4 0x17 /* Intr Ctrl reg 4 (r/w) */ +#define MCFSIM_ICR5 0x18 /* Intr Ctrl reg 5 (r/w) */ +#define MCFSIM_ICR6 0x19 /* Intr Ctrl reg 6 (r/w) */ +#define MCFSIM_ICR7 0x1a /* Intr Ctrl reg 7 (r/w) */ +#define MCFSIM_ICR8 0x1b /* Intr Ctrl reg 8 (r/w) */ +#define MCFSIM_ICR9 0x1c /* Intr Ctrl reg 9 (r/w) */ +#define MCFSIM_ICR10 0x1d /* Intr Ctrl reg 10 (r/w) */ +#define MCFSIM_ICR11 0x1e /* Intr Ctrl reg 11 (r/w) */ +#define MCFSIM_ICR12 0x1f /* Intr Ctrl reg 12 (r/w) */ +#define MCFSIM_ICR13 0x20 /* Intr Ctrl reg 13 (r/w) */ +#ifdef CONFIG_M5206e +#define MCFSIM_ICR14 0x21 /* Intr Ctrl reg 14 (r/w) */ +#define MCFSIM_ICR15 0x22 /* Intr Ctrl reg 15 (r/w) */ +#endif + +#define MCFSIM_IMR 0x36 /* Interrupt Mask reg (r/w) */ +#define MCFSIM_IPR 0x3a /* Interrupt Pend reg (r/w) */ + +#define MCFSIM_RSR 0x40 /* Reset Status reg (r/w) */ +#define MCFSIM_SYPCR 0x41 /* System Protection reg (r/w)*/ + +#define MCFSIM_SWIVR 0x42 /* SW Watchdog intr reg (r/w) */ +#define MCFSIM_SWSR 0x43 /* SW Watchdog service (r/w) */ + +#define MCFSIM_DCRR 0x46 /* DRAM Refresh reg (r/w) */ +#define MCFSIM_DCTR 0x4a /* DRAM Timing reg (r/w) */ +#define MCFSIM_DAR0 0x4c /* DRAM 0 Address reg(r/w) */ +#define MCFSIM_DMR0 0x50 /* DRAM 0 Mask reg (r/w) */ +#define MCFSIM_DCR0 0x57 /* DRAM 0 Control reg (r/w) */ +#define MCFSIM_DAR1 0x58 /* DRAM 1 Address reg (r/w) */ +#define MCFSIM_DMR1 0x5c /* DRAM 1 Mask reg (r/w) */ +#define MCFSIM_DCR1 0x63 /* DRAM 1 Control reg (r/w) */ + +#define MCFSIM_CSAR0 0x64 /* CS 0 Address 0 reg (r/w) */ +#define MCFSIM_CSMR0 0x68 /* CS 0 Mask 0 reg (r/w) */ +#define MCFSIM_CSCR0 0x6e /* CS 0 Control reg (r/w) */ +#define MCFSIM_CSAR1 0x70 /* CS 1 Address reg (r/w) */ +#define MCFSIM_CSMR1 0x74 /* CS 1 Mask reg (r/w) */ +#define MCFSIM_CSCR1 0x7a /* CS 1 Control reg (r/w) */ +#define MCFSIM_CSAR2 0x7c /* CS 2 Address reg (r/w) */ +#define MCFSIM_CSMR2 0x80 /* CS 2 Mask reg (r/w) */ +#define MCFSIM_CSCR2 0x86 /* CS 2 Control reg (r/w) */ +#define MCFSIM_CSAR3 0x88 /* CS 3 Address reg (r/w) */ +#define MCFSIM_CSMR3 0x8c /* CS 3 Mask reg (r/w) */ +#define MCFSIM_CSCR3 0x92 /* CS 3 Control reg (r/w) */ +#define MCFSIM_CSAR4 0x94 /* CS 4 Address reg (r/w) */ +#define MCFSIM_CSMR4 0x98 /* CS 4 Mask reg (r/w) */ +#define MCFSIM_CSCR4 0x9e /* CS 4 Control reg (r/w) */ +#define MCFSIM_CSAR5 0xa0 /* CS 5 Address reg (r/w) */ +#define MCFSIM_CSMR5 0xa4 /* CS 5 Mask reg (r/w) */ +#define MCFSIM_CSCR5 0xaa /* CS 5 Control reg (r/w) */ +#define MCFSIM_CSAR6 0xac /* CS 6 Address reg (r/w) */ +#define MCFSIM_CSMR6 0xb0 /* CS 6 Mask reg (r/w) */ +#define MCFSIM_CSCR6 0xb6 /* CS 6 Control reg (r/w) */ +#define MCFSIM_CSAR7 0xb8 /* CS 7 Address reg (r/w) */ +#define MCFSIM_CSMR7 0xbc /* CS 7 Mask reg (r/w) */ +#define MCFSIM_CSCR7 0xc2 /* CS 7 Control reg (r/w) */ +#define MCFSIM_DMCR 0xc6 /* Default control */ + +#ifdef CONFIG_M5206e +#define MCFSIM_PAR 0xca /* Pin Assignment reg (r/w) */ +#else +#define MCFSIM_PAR 0xcb /* Pin Assignment reg (r/w) */ +#endif + +#define MCFSIM_PADDR 0x1c5 /* Parallel Direction (r/w) */ +#define MCFSIM_PADAT 0x1c9 /* Parallel Port Value (r/w) */ + +/* + * Some symbol defines for the Parallel Port Pin Assignment Register + */ +#ifdef CONFIG_M5206e +#define MCFSIM_PAR_DREQ0 0x100 /* Set to select DREQ0 input */ + /* Clear to select T0 input */ +#define MCFSIM_PAR_DREQ1 0x200 /* Select DREQ1 input */ + /* Clear to select T0 output */ +#endif + +/* + * Some symbol defines for the Interrupt Control Register + */ +#define MCFSIM_SWDICR MCFSIM_ICR8 /* Watchdog timer ICR */ +#define MCFSIM_TIMER1ICR MCFSIM_ICR9 /* Timer 1 ICR */ +#define MCFSIM_TIMER2ICR MCFSIM_ICR10 /* Timer 2 ICR */ +#define MCFSIM_UART1ICR MCFSIM_ICR12 /* UART 1 ICR */ +#define MCFSIM_UART2ICR MCFSIM_ICR13 /* UART 2 ICR */ +#ifdef CONFIG_M5206e +#define MCFSIM_DMA1ICR MCFSIM_ICR14 /* DMA 1 ICR */ +#define MCFSIM_DMA2ICR MCFSIM_ICR15 /* DMA 2 ICR */ +#endif + +#if defined(CONFIG_M5206e) +#define MCFSIM_IMR_MASKALL 0xfffe /* All SIM intr sources */ +#endif + +/* + * Macro to get and set IMR register. It is 16 bits on the 5206. + */ +#define mcf_getimr() \ + *((volatile unsigned short *) (MCF_MBAR + MCFSIM_IMR)) + +#define mcf_setimr(imr) \ + *((volatile unsigned short *) (MCF_MBAR + MCFSIM_IMR)) = (imr) + +#define mcf_getipr() \ + *((volatile unsigned short *) (MCF_MBAR + MCFSIM_IPR)) + +/****************************************************************************/ +#endif /* m5206sim_h */ diff --git a/arch/m68k/include/asm/m520xsim.h b/arch/m68k/include/asm/m520xsim.h new file mode 100644 index 00000000000..49d016e6391 --- /dev/null +++ b/arch/m68k/include/asm/m520xsim.h @@ -0,0 +1,63 @@ +/****************************************************************************/ + +/* + * m520xsim.h -- ColdFire 5207/5208 System Integration Module support. + * + * (C) Copyright 2005, Intec Automation (mike@steroidmicros.com) + */ + +/****************************************************************************/ +#ifndef m520xsim_h +#define m520xsim_h +/****************************************************************************/ + + +/* + * Define the 5282 SIM register set addresses. + */ +#define MCFICM_INTC0 0x48000 /* Base for Interrupt Ctrl 0 */ +#define MCFINTC_IPRH 0x00 /* Interrupt pending 32-63 */ +#define MCFINTC_IPRL 0x04 /* Interrupt pending 1-31 */ +#define MCFINTC_IMRH 0x08 /* Interrupt mask 32-63 */ +#define MCFINTC_IMRL 0x0c /* Interrupt mask 1-31 */ +#define MCFINTC_INTFRCH 0x10 /* Interrupt force 32-63 */ +#define MCFINTC_INTFRCL 0x14 /* Interrupt force 1-31 */ +#define MCFINTC_ICR0 0x40 /* Base ICR register */ + +#define MCFINT_VECBASE 64 +#define MCFINT_UART0 26 /* Interrupt number for UART0 */ +#define MCFINT_UART1 27 /* Interrupt number for UART1 */ +#define MCFINT_UART2 28 /* Interrupt number for UART2 */ +#define MCFINT_QSPI 31 /* Interrupt number for QSPI */ +#define MCFINT_PIT1 4 /* Interrupt number for PIT1 (PIT0 in processor) */ + +/* + * SDRAM configuration registers. + */ +#define MCFSIM_SDMR 0x000a8000 /* SDRAM Mode/Extended Mode Register */ +#define MCFSIM_SDCR 0x000a8004 /* SDRAM Control Register */ +#define MCFSIM_SDCFG1 0x000a8008 /* SDRAM Configuration Register 1 */ +#define MCFSIM_SDCFG2 0x000a800c /* SDRAM Configuration Register 2 */ +#define MCFSIM_SDCS0 0x000a8110 /* SDRAM Chip Select 0 Configuration */ +#define MCFSIM_SDCS1 0x000a8114 /* SDRAM Chip Select 1 Configuration */ + + +#define MCF_GPIO_PAR_UART (0xA4036) +#define MCF_GPIO_PAR_FECI2C (0xA4033) +#define MCF_GPIO_PAR_FEC (0xA4038) + +#define MCF_GPIO_PAR_UART_PAR_URXD0 (0x0001) +#define MCF_GPIO_PAR_UART_PAR_UTXD0 (0x0002) + +#define MCF_GPIO_PAR_UART_PAR_URXD1 (0x0040) +#define MCF_GPIO_PAR_UART_PAR_UTXD1 (0x0080) + +#define MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2 (0x02) +#define MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2 (0x04) + +#define ICR_INTRCONF 0x05 +#define MCFPIT_IMR MCFINTC_IMRL +#define MCFPIT_IMR_IBIT (1 << MCFINT_PIT1) + +/****************************************************************************/ +#endif /* m520xsim_h */ diff --git a/arch/m68k/include/asm/m523xsim.h b/arch/m68k/include/asm/m523xsim.h new file mode 100644 index 00000000000..bf397313e93 --- /dev/null +++ b/arch/m68k/include/asm/m523xsim.h @@ -0,0 +1,45 @@ +/****************************************************************************/ + +/* + * m523xsim.h -- ColdFire 523x System Integration Module support. + * + * (C) Copyright 2003-2005, Greg Ungerer + */ + +/****************************************************************************/ +#ifndef m523xsim_h +#define m523xsim_h +/****************************************************************************/ + + +/* + * Define the 523x SIM register set addresses. + */ +#define MCFICM_INTC0 0x0c00 /* Base for Interrupt Ctrl 0 */ +#define MCFICM_INTC1 0x0d00 /* Base for Interrupt Ctrl 0 */ +#define MCFINTC_IPRH 0x00 /* Interrupt pending 32-63 */ +#define MCFINTC_IPRL 0x04 /* Interrupt pending 1-31 */ +#define MCFINTC_IMRH 0x08 /* Interrupt mask 32-63 */ +#define MCFINTC_IMRL 0x0c /* Interrupt mask 1-31 */ +#define MCFINTC_INTFRCH 0x10 /* Interrupt force 32-63 */ +#define MCFINTC_INTFRCL 0x14 /* Interrupt force 1-31 */ +#define MCFINTC_IRLR 0x18 /* */ +#define MCFINTC_IACKL 0x19 /* */ +#define MCFINTC_ICR0 0x40 /* Base ICR register */ + +#define MCFINT_VECBASE 64 /* Vector base number */ +#define MCFINT_UART0 13 /* Interrupt number for UART0 */ +#define MCFINT_PIT1 36 /* Interrupt number for PIT1 */ +#define MCFINT_QSPI 18 /* Interrupt number for QSPI */ + +/* + * SDRAM configuration registers. + */ +#define MCFSIM_DCR 0x44 /* SDRAM control */ +#define MCFSIM_DACR0 0x48 /* SDRAM base address 0 */ +#define MCFSIM_DMR0 0x4c /* SDRAM address mask 0 */ +#define MCFSIM_DACR1 0x50 /* SDRAM base address 1 */ +#define MCFSIM_DMR1 0x54 /* SDRAM address mask 1 */ + +/****************************************************************************/ +#endif /* m523xsim_h */ diff --git a/arch/m68k/include/asm/m5249sim.h b/arch/m68k/include/asm/m5249sim.h new file mode 100644 index 00000000000..366eb8602d2 --- /dev/null +++ b/arch/m68k/include/asm/m5249sim.h @@ -0,0 +1,209 @@ +/****************************************************************************/ + +/* + * m5249sim.h -- ColdFire 5249 System Integration Module support. + * + * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) + */ + +/****************************************************************************/ +#ifndef m5249sim_h +#define m5249sim_h +/****************************************************************************/ + +/* + * Define the 5249 SIM register set addresses. + */ +#define MCFSIM_RSR 0x00 /* Reset Status reg (r/w) */ +#define MCFSIM_SYPCR 0x01 /* System Protection reg (r/w)*/ +#define MCFSIM_SWIVR 0x02 /* SW Watchdog intr reg (r/w) */ +#define MCFSIM_SWSR 0x03 /* SW Watchdog service (r/w) */ +#define MCFSIM_PAR 0x04 /* Pin Assignment reg (r/w) */ +#define MCFSIM_IRQPAR 0x06 /* Interrupt Assignment reg (r/w) */ +#define MCFSIM_MPARK 0x0C /* BUS Master Control Reg*/ +#define MCFSIM_IPR 0x40 /* Interrupt Pend reg (r/w) */ +#define MCFSIM_IMR 0x44 /* Interrupt Mask reg (r/w) */ +#define MCFSIM_AVR 0x4b /* Autovector Ctrl reg (r/w) */ +#define MCFSIM_ICR0 0x4c /* Intr Ctrl reg 0 (r/w) */ +#define MCFSIM_ICR1 0x4d /* Intr Ctrl reg 1 (r/w) */ +#define MCFSIM_ICR2 0x4e /* Intr Ctrl reg 2 (r/w) */ +#define MCFSIM_ICR3 0x4f /* Intr Ctrl reg 3 (r/w) */ +#define MCFSIM_ICR4 0x50 /* Intr Ctrl reg 4 (r/w) */ +#define MCFSIM_ICR5 0x51 /* Intr Ctrl reg 5 (r/w) */ +#define MCFSIM_ICR6 0x52 /* Intr Ctrl reg 6 (r/w) */ +#define MCFSIM_ICR7 0x53 /* Intr Ctrl reg 7 (r/w) */ +#define MCFSIM_ICR8 0x54 /* Intr Ctrl reg 8 (r/w) */ +#define MCFSIM_ICR9 0x55 /* Intr Ctrl reg 9 (r/w) */ +#define MCFSIM_ICR10 0x56 /* Intr Ctrl reg 10 (r/w) */ +#define MCFSIM_ICR11 0x57 /* Intr Ctrl reg 11 (r/w) */ + +#define MCFSIM_CSAR0 0x80 /* CS 0 Address 0 reg (r/w) */ +#define MCFSIM_CSMR0 0x84 /* CS 0 Mask 0 reg (r/w) */ +#define MCFSIM_CSCR0 0x8a /* CS 0 Control reg (r/w) */ +#define MCFSIM_CSAR1 0x8c /* CS 1 Address reg (r/w) */ +#define MCFSIM_CSMR1 0x90 /* CS 1 Mask reg (r/w) */ +#define MCFSIM_CSCR1 0x96 /* CS 1 Control reg (r/w) */ +#define MCFSIM_CSAR2 0x98 /* CS 2 Address reg (r/w) */ +#define MCFSIM_CSMR2 0x9c /* CS 2 Mask reg (r/w) */ +#define MCFSIM_CSCR2 0xa2 /* CS 2 Control reg (r/w) */ +#define MCFSIM_CSAR3 0xa4 /* CS 3 Address reg (r/w) */ +#define MCFSIM_CSMR3 0xa8 /* CS 3 Mask reg (r/w) */ +#define MCFSIM_CSCR3 0xae /* CS 3 Control reg (r/w) */ + +#define MCFSIM_DCR 0x100 /* DRAM Control reg (r/w) */ +#define MCFSIM_DACR0 0x108 /* DRAM 0 Addr and Ctrl (r/w) */ +#define MCFSIM_DMR0 0x10c /* DRAM 0 Mask reg (r/w) */ +#define MCFSIM_DACR1 0x110 /* DRAM 1 Addr and Ctrl (r/w) */ +#define MCFSIM_DMR1 0x114 /* DRAM 1 Mask reg (r/w) */ + + +/* + * Some symbol defines for the above... + */ +#define MCFSIM_SWDICR MCFSIM_ICR0 /* Watchdog timer ICR */ +#define MCFSIM_TIMER1ICR MCFSIM_ICR1 /* Timer 1 ICR */ +#define MCFSIM_TIMER2ICR MCFSIM_ICR2 /* Timer 2 ICR */ +#define MCFSIM_UART1ICR MCFSIM_ICR4 /* UART 1 ICR */ +#define MCFSIM_UART2ICR MCFSIM_ICR5 /* UART 2 ICR */ +#define MCFSIM_DMA0ICR MCFSIM_ICR6 /* DMA 0 ICR */ +#define MCFSIM_DMA1ICR MCFSIM_ICR7 /* DMA 1 ICR */ +#define MCFSIM_DMA2ICR MCFSIM_ICR8 /* DMA 2 ICR */ +#define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */ + +/* + * General purpose IO registers (in MBAR2). + */ +#define MCFSIM2_GPIOREAD 0x0 /* GPIO read values */ +#define MCFSIM2_GPIOWRITE 0x4 /* GPIO write values */ +#define MCFSIM2_GPIOENABLE 0x8 /* GPIO enabled */ +#define MCFSIM2_GPIOFUNC 0xc /* GPIO function */ +#define MCFSIM2_GPIO1READ 0xb0 /* GPIO1 read values */ +#define MCFSIM2_GPIO1WRITE 0xb4 /* GPIO1 write values */ +#define MCFSIM2_GPIO1ENABLE 0xb8 /* GPIO1 enabled */ +#define MCFSIM2_GPIO1FUNC 0xbc /* GPIO1 function */ + +#define MCFSIM2_GPIOINTSTAT 0xc0 /* GPIO interrupt status */ +#define MCFSIM2_GPIOINTCLEAR 0xc0 /* GPIO interrupt clear */ +#define MCFSIM2_GPIOINTENABLE 0xc4 /* GPIO interrupt enable */ + +#define MCFSIM2_INTLEVEL1 0x140 /* Interrupt level reg 1 */ +#define MCFSIM2_INTLEVEL2 0x144 /* Interrupt level reg 2 */ +#define MCFSIM2_INTLEVEL3 0x148 /* Interrupt level reg 3 */ +#define MCFSIM2_INTLEVEL4 0x14c /* Interrupt level reg 4 */ +#define MCFSIM2_INTLEVEL5 0x150 /* Interrupt level reg 5 */ +#define MCFSIM2_INTLEVEL6 0x154 /* Interrupt level reg 6 */ +#define MCFSIM2_INTLEVEL7 0x158 /* Interrupt level reg 7 */ +#define MCFSIM2_INTLEVEL8 0x15c /* Interrupt level reg 8 */ + +#define MCFSIM2_DMAROUTE 0x188 /* DMA routing */ + +#define MCFSIM2_IDECONFIG1 0x18c /* IDEconfig1 */ +#define MCFSIM2_IDECONFIG2 0x190 /* IDEconfig2 */ + + +/* + * Macro to set IMR register. It is 32 bits on the 5249. + */ +#define MCFSIM_IMR_MASKALL 0x7fffe /* All SIM intr sources */ + +#define mcf_getimr() \ + *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) + +#define mcf_setimr(imr) \ + *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr); + +#define mcf_getipr() \ + *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR)) + +/****************************************************************************/ + +#ifdef __ASSEMBLER__ + +/* + * The M5249C3 board needs a little help getting all its SIM devices + * initialized at kernel start time. dBUG doesn't set much up, so + * we need to do it manually. + */ +.macro m5249c3_setup + /* + * Set MBAR1 and MBAR2, just incase they are not set. + */ + movel #0x10000001,%a0 + movec %a0,%MBAR /* map MBAR region */ + subql #1,%a0 /* get MBAR address in a0 */ + + movel #0x80000001,%a1 + movec %a1,#3086 /* map MBAR2 region */ + subql #1,%a1 /* get MBAR2 address in a1 */ + + /* + * Move secondary interrupts to base at 128. + */ + moveb #0x80,%d0 + moveb %d0,0x16b(%a1) /* interrupt base register */ + + /* + * Work around broken CSMR0/DRAM vector problem. + */ + movel #0x001F0021,%d0 /* disable C/I bit */ + movel %d0,0x84(%a0) /* set CSMR0 */ + + /* + * Disable the PLL firstly. (Who knows what state it is + * in here!). + */ + movel 0x180(%a1),%d0 /* get current PLL value */ + andl #0xfffffffe,%d0 /* PLL bypass first */ + movel %d0,0x180(%a1) /* set PLL register */ + nop + +#if CONFIG_CLOCK_FREQ == 140000000 + /* + * Set initial clock frequency. This assumes M5249C3 board + * is fitted with 11.2896MHz crystal. It will program the + * PLL for 140MHz. Lets go fast :-) + */ + movel #0x125a40f0,%d0 /* set for 140MHz */ + movel %d0,0x180(%a1) /* set PLL register */ + orl #0x1,%d0 + movel %d0,0x180(%a1) /* set PLL register */ +#endif + + /* + * Setup CS1 for ethernet controller. + * (Setup as per M5249C3 doco). + */ + movel #0xe0000000,%d0 /* CS1 mapped at 0xe0000000 */ + movel %d0,0x8c(%a0) + movel #0x001f0021,%d0 /* CS1 size of 1Mb */ + movel %d0,0x90(%a0) + movew #0x0080,%d0 /* CS1 = 16bit port, AA */ + movew %d0,0x96(%a0) + + /* + * Setup CS2 for IDE interface. + */ + movel #0x50000000,%d0 /* CS2 mapped at 0x50000000 */ + movel %d0,0x98(%a0) + movel #0x001f0001,%d0 /* CS2 size of 1MB */ + movel %d0,0x9c(%a0) + movew #0x0080,%d0 /* CS2 = 16bit, TA */ + movew %d0,0xa2(%a0) + + movel #0x00107000,%d0 /* IDEconfig1 */ + movel %d0,0x18c(%a1) + movel #0x000c0400,%d0 /* IDEconfig2 */ + movel %d0,0x190(%a1) + + movel #0x00080000,%d0 /* GPIO19, IDE reset bit */ + orl %d0,0xc(%a1) /* function GPIO19 */ + orl %d0,0x8(%a1) /* enable GPIO19 as output */ + orl %d0,0x4(%a1) /* de-assert IDE reset */ +.endm + +#define PLATFORM_SETUP m5249c3_setup + +#endif /* __ASSEMBLER__ */ + +/****************************************************************************/ +#endif /* m5249sim_h */ diff --git a/arch/m68k/include/asm/m5272sim.h b/arch/m68k/include/asm/m5272sim.h new file mode 100644 index 00000000000..6217edc2113 --- /dev/null +++ b/arch/m68k/include/asm/m5272sim.h @@ -0,0 +1,78 @@ +/****************************************************************************/ + +/* + * m5272sim.h -- ColdFire 5272 System Integration Module support. + * + * (C) Copyright 1999, Greg Ungerer (gerg@snapgear.com) + * (C) Copyright 2000, Lineo Inc. (www.lineo.com) + */ + +/****************************************************************************/ +#ifndef m5272sim_h +#define m5272sim_h +/****************************************************************************/ + + +/* + * Define the 5272 SIM register set addresses. + */ +#define MCFSIM_SCR 0x04 /* SIM Config reg (r/w) */ +#define MCFSIM_SPR 0x06 /* System Protection reg (r/w)*/ +#define MCFSIM_PMR 0x08 /* Power Management reg (r/w) */ +#define MCFSIM_APMR 0x0e /* Active Low Power reg (r/w) */ +#define MCFSIM_DIR 0x10 /* Device Identity reg (r/w) */ + +#define MCFSIM_ICR1 0x20 /* Intr Ctrl reg 1 (r/w) */ +#define MCFSIM_ICR2 0x24 /* Intr Ctrl reg 2 (r/w) */ +#define MCFSIM_ICR3 0x28 /* Intr Ctrl reg 3 (r/w) */ +#define MCFSIM_ICR4 0x2c /* Intr Ctrl reg 4 (r/w) */ + +#define MCFSIM_ISR 0x30 /* Interrupt Source reg (r/w) */ +#define MCFSIM_PITR 0x34 /* Interrupt Transition (r/w) */ +#define MCFSIM_PIWR 0x38 /* Interrupt Wakeup reg (r/w) */ +#define MCFSIM_PIVR 0x3f /* Interrupt Vector reg (r/w( */ + +#define MCFSIM_WRRR 0x280 /* Watchdog reference (r/w) */ +#define MCFSIM_WIRR 0x284 /* Watchdog interrupt (r/w) */ +#define MCFSIM_WCR 0x288 /* Watchdog counter (r/w) */ +#define MCFSIM_WER 0x28c /* Watchdog event (r/w) */ + +#define MCFSIM_CSBR0 0x40 /* CS0 Base Address (r/w) */ +#define MCFSIM_CSOR0 0x44 /* CS0 Option (r/w) */ +#define MCFSIM_CSBR1 0x48 /* CS1 Base Address (r/w) */ +#define MCFSIM_CSOR1 0x4c /* CS1 Option (r/w) */ +#define MCFSIM_CSBR2 0x50 /* CS2 Base Address (r/w) */ +#define MCFSIM_CSOR2 0x54 /* CS2 Option (r/w) */ +#define MCFSIM_CSBR3 0x58 /* CS3 Base Address (r/w) */ +#define MCFSIM_CSOR3 0x5c /* CS3 Option (r/w) */ +#define MCFSIM_CSBR4 0x60 /* CS4 Base Address (r/w) */ +#define MCFSIM_CSOR4 0x64 /* CS4 Option (r/w) */ +#define MCFSIM_CSBR5 0x68 /* CS5 Base Address (r/w) */ +#define MCFSIM_CSOR5 0x6c /* CS5 Option (r/w) */ +#define MCFSIM_CSBR6 0x70 /* CS6 Base Address (r/w) */ +#define MCFSIM_CSOR6 0x74 /* CS6 Option (r/w) */ +#define MCFSIM_CSBR7 0x78 /* CS7 Base Address (r/w) */ +#define MCFSIM_CSOR7 0x7c /* CS7 Option (r/w) */ + +#define MCFSIM_SDCR 0x180 /* SDRAM Configuration (r/w) */ +#define MCFSIM_SDTR 0x184 /* SDRAM Timing (r/w) */ +#define MCFSIM_DCAR0 0x4c /* DRAM 0 Address reg(r/w) */ +#define MCFSIM_DCMR0 0x50 /* DRAM 0 Mask reg (r/w) */ +#define MCFSIM_DCCR0 0x57 /* DRAM 0 Control reg (r/w) */ +#define MCFSIM_DCAR1 0x58 /* DRAM 1 Address reg (r/w) */ +#define MCFSIM_DCMR1 0x5c /* DRAM 1 Mask reg (r/w) */ +#define MCFSIM_DCCR1 0x63 /* DRAM 1 Control reg (r/w) */ + +#define MCFSIM_PACNT 0x80 /* Port A Control (r/w) */ +#define MCFSIM_PADDR 0x84 /* Port A Direction (r/w) */ +#define MCFSIM_PADAT 0x86 /* Port A Data (r/w) */ +#define MCFSIM_PBCNT 0x88 /* Port B Control (r/w) */ +#define MCFSIM_PBDDR 0x8c /* Port B Direction (r/w) */ +#define MCFSIM_PBDAT 0x8e /* Port B Data (r/w) */ +#define MCFSIM_PCDDR 0x94 /* Port C Direction (r/w) */ +#define MCFSIM_PCDAT 0x96 /* Port C Data (r/w) */ +#define MCFSIM_PDCNT 0x98 /* Port D Control (r/w) */ + + +/****************************************************************************/ +#endif /* m5272sim_h */ diff --git a/arch/m68k/include/asm/m527xsim.h b/arch/m68k/include/asm/m527xsim.h new file mode 100644 index 00000000000..1f63ab3fb3e --- /dev/null +++ b/arch/m68k/include/asm/m527xsim.h @@ -0,0 +1,74 @@ +/****************************************************************************/ + +/* + * m527xsim.h -- ColdFire 5270/5271 System Integration Module support. + * + * (C) Copyright 2004, Greg Ungerer (gerg@snapgear.com) + */ + +/****************************************************************************/ +#ifndef m527xsim_h +#define m527xsim_h +/****************************************************************************/ + + +/* + * Define the 5270/5271 SIM register set addresses. + */ +#define MCFICM_INTC0 0x0c00 /* Base for Interrupt Ctrl 0 */ +#define MCFICM_INTC1 0x0d00 /* Base for Interrupt Ctrl 1 */ +#define MCFINTC_IPRH 0x00 /* Interrupt pending 32-63 */ +#define MCFINTC_IPRL 0x04 /* Interrupt pending 1-31 */ +#define MCFINTC_IMRH 0x08 /* Interrupt mask 32-63 */ +#define MCFINTC_IMRL 0x0c /* Interrupt mask 1-31 */ +#define MCFINTC_INTFRCH 0x10 /* Interrupt force 32-63 */ +#define MCFINTC_INTFRCL 0x14 /* Interrupt force 1-31 */ +#define MCFINTC_IRLR 0x18 /* */ +#define MCFINTC_IACKL 0x19 /* */ +#define MCFINTC_ICR0 0x40 /* Base ICR register */ + +#define MCFINT_VECBASE 64 /* Vector base number */ +#define MCFINT_UART0 13 /* Interrupt number for UART0 */ +#define MCFINT_UART1 14 /* Interrupt number for UART1 */ +#define MCFINT_UART2 15 /* Interrupt number for UART2 */ +#define MCFINT_PIT1 36 /* Interrupt number for PIT1 */ + +/* + * SDRAM configuration registers. + */ +#ifdef CONFIG_M5271 +#define MCFSIM_DCR 0x40 /* SDRAM control */ +#define MCFSIM_DACR0 0x48 /* SDRAM base address 0 */ +#define MCFSIM_DMR0 0x4c /* SDRAM address mask 0 */ +#define MCFSIM_DACR1 0x50 /* SDRAM base address 1 */ +#define MCFSIM_DMR1 0x54 /* SDRAM address mask 1 */ +#endif +#ifdef CONFIG_M5275 +#define MCFSIM_DMR 0x40 /* SDRAM mode */ +#define MCFSIM_DCR 0x44 /* SDRAM control */ +#define MCFSIM_DCFG1 0x48 /* SDRAM configuration 1 */ +#define MCFSIM_DCFG2 0x4c /* SDRAM configuration 2 */ +#define MCFSIM_DBAR0 0x50 /* SDRAM base address 0 */ +#define MCFSIM_DMR0 0x54 /* SDRAM address mask 0 */ +#define MCFSIM_DBAR1 0x58 /* SDRAM base address 1 */ +#define MCFSIM_DMR1 0x5c /* SDRAM address mask 1 */ +#endif + +/* + * GPIO pins setups to enable the UARTs. + */ +#ifdef CONFIG_M5271 +#define MCF_GPIO_PAR_UART 0x100048 /* PAR UART address */ +#define UART0_ENABLE_MASK 0x000f +#define UART1_ENABLE_MASK 0x0ff0 +#define UART2_ENABLE_MASK 0x3000 +#endif +#ifdef CONFIG_M5275 +#define MCF_GPIO_PAR_UART 0x10007c /* PAR UART address */ +#define UART0_ENABLE_MASK 0x000f +#define UART1_ENABLE_MASK 0x00f0 +#define UART2_ENABLE_MASK 0x3f00 +#endif + +/****************************************************************************/ +#endif /* m527xsim_h */ diff --git a/arch/m68k/include/asm/m528xsim.h b/arch/m68k/include/asm/m528xsim.h new file mode 100644 index 00000000000..28bf783a5d6 --- /dev/null +++ b/arch/m68k/include/asm/m528xsim.h @@ -0,0 +1,159 @@ +/****************************************************************************/ + +/* + * m528xsim.h -- ColdFire 5280/5282 System Integration Module support. + * + * (C) Copyright 2003, Greg Ungerer (gerg@snapgear.com) + */ + +/****************************************************************************/ +#ifndef m528xsim_h +#define m528xsim_h +/****************************************************************************/ + + +/* + * Define the 5280/5282 SIM register set addresses. + */ +#define MCFICM_INTC0 0x0c00 /* Base for Interrupt Ctrl 0 */ +#define MCFICM_INTC1 0x0d00 /* Base for Interrupt Ctrl 0 */ +#define MCFINTC_IPRH 0x00 /* Interrupt pending 32-63 */ +#define MCFINTC_IPRL 0x04 /* Interrupt pending 1-31 */ +#define MCFINTC_IMRH 0x08 /* Interrupt mask 32-63 */ +#define MCFINTC_IMRL 0x0c /* Interrupt mask 1-31 */ +#define MCFINTC_INTFRCH 0x10 /* Interrupt force 32-63 */ +#define MCFINTC_INTFRCL 0x14 /* Interrupt force 1-31 */ +#define MCFINTC_IRLR 0x18 /* */ +#define MCFINTC_IACKL 0x19 /* */ +#define MCFINTC_ICR0 0x40 /* Base ICR register */ + +#define MCFINT_VECBASE 64 /* Vector base number */ +#define MCFINT_UART0 13 /* Interrupt number for UART0 */ +#define MCFINT_PIT1 55 /* Interrupt number for PIT1 */ + +/* + * SDRAM configuration registers. + */ +#define MCFSIM_DCR 0x44 /* SDRAM control */ +#define MCFSIM_DACR0 0x48 /* SDRAM base address 0 */ +#define MCFSIM_DMR0 0x4c /* SDRAM address mask 0 */ +#define MCFSIM_DACR1 0x50 /* SDRAM base address 1 */ +#define MCFSIM_DMR1 0x54 /* SDRAM address mask 1 */ + +/* + * Derek Cheung - 6 Feb 2005 + * add I2C and QSPI register definition using Freescale's MCF5282 + */ +/* set Port AS pin for I2C or UART */ +#define MCF5282_GPIO_PASPAR (volatile u16 *) (MCF_IPSBAR + 0x00100056) + +/* Port UA Pin Assignment Register (8 Bit) */ +#define MCF5282_GPIO_PUAPAR 0x10005C + +/* Interrupt Mask Register Register Low */ +#define MCF5282_INTC0_IMRL (volatile u32 *) (MCF_IPSBAR + 0x0C0C) +/* Interrupt Control Register 7 */ +#define MCF5282_INTC0_ICR17 (volatile u8 *) (MCF_IPSBAR + 0x0C51) + + + +/********************************************************************* +* +* Inter-IC (I2C) Module +* +*********************************************************************/ +/* Read/Write access macros for general use */ +#define MCF5282_I2C_I2ADR (volatile u8 *) (MCF_IPSBAR + 0x0300) // Address +#define MCF5282_I2C_I2FDR (volatile u8 *) (MCF_IPSBAR + 0x0304) // Freq Divider +#define MCF5282_I2C_I2CR (volatile u8 *) (MCF_IPSBAR + 0x0308) // Control +#define MCF5282_I2C_I2SR (volatile u8 *) (MCF_IPSBAR + 0x030C) // Status +#define MCF5282_I2C_I2DR (volatile u8 *) (MCF_IPSBAR + 0x0310) // Data I/O + +/* Bit level definitions and macros */ +#define MCF5282_I2C_I2ADR_ADDR(x) (((x)&0x7F)<<0x01) + +#define MCF5282_I2C_I2FDR_IC(x) (((x)&0x3F)) + +#define MCF5282_I2C_I2CR_IEN (0x80) // I2C enable +#define MCF5282_I2C_I2CR_IIEN (0x40) // interrupt enable +#define MCF5282_I2C_I2CR_MSTA (0x20) // master/slave mode +#define MCF5282_I2C_I2CR_MTX (0x10) // transmit/receive mode +#define MCF5282_I2C_I2CR_TXAK (0x08) // transmit acknowledge enable +#define MCF5282_I2C_I2CR_RSTA (0x04) // repeat start + +#define MCF5282_I2C_I2SR_ICF (0x80) // data transfer bit +#define MCF5282_I2C_I2SR_IAAS (0x40) // I2C addressed as a slave +#define MCF5282_I2C_I2SR_IBB (0x20) // I2C bus busy +#define MCF5282_I2C_I2SR_IAL (0x10) // aribitration lost +#define MCF5282_I2C_I2SR_SRW (0x04) // slave read/write +#define MCF5282_I2C_I2SR_IIF (0x02) // I2C interrupt +#define MCF5282_I2C_I2SR_RXAK (0x01) // received acknowledge + + + +/********************************************************************* +* +* Queued Serial Peripheral Interface (QSPI) Module +* +*********************************************************************/ +/* Derek - 21 Feb 2005 */ +/* change to the format used in I2C */ +/* Read/Write access macros for general use */ +#define MCF5282_QSPI_QMR MCF_IPSBAR + 0x0340 +#define MCF5282_QSPI_QDLYR MCF_IPSBAR + 0x0344 +#define MCF5282_QSPI_QWR MCF_IPSBAR + 0x0348 +#define MCF5282_QSPI_QIR MCF_IPSBAR + 0x034C +#define MCF5282_QSPI_QAR MCF_IPSBAR + 0x0350 +#define MCF5282_QSPI_QDR MCF_IPSBAR + 0x0354 +#define MCF5282_QSPI_QCR MCF_IPSBAR + 0x0354 + +/* Bit level definitions and macros */ +#define MCF5282_QSPI_QMR_MSTR (0x8000) +#define MCF5282_QSPI_QMR_DOHIE (0x4000) +#define MCF5282_QSPI_QMR_BITS_16 (0x0000) +#define MCF5282_QSPI_QMR_BITS_8 (0x2000) +#define MCF5282_QSPI_QMR_BITS_9 (0x2400) +#define MCF5282_QSPI_QMR_BITS_10 (0x2800) +#define MCF5282_QSPI_QMR_BITS_11 (0x2C00) +#define MCF5282_QSPI_QMR_BITS_12 (0x3000) +#define MCF5282_QSPI_QMR_BITS_13 (0x3400) +#define MCF5282_QSPI_QMR_BITS_14 (0x3800) +#define MCF5282_QSPI_QMR_BITS_15 (0x3C00) +#define MCF5282_QSPI_QMR_CPOL (0x0200) +#define MCF5282_QSPI_QMR_CPHA (0x0100) +#define MCF5282_QSPI_QMR_BAUD(x) (((x)&0x00FF)) + +#define MCF5282_QSPI_QDLYR_SPE (0x80) +#define MCF5282_QSPI_QDLYR_QCD(x) (((x)&0x007F)<<8) +#define MCF5282_QSPI_QDLYR_DTL(x) (((x)&0x00FF)) + +#define MCF5282_QSPI_QWR_HALT (0x8000) +#define MCF5282_QSPI_QWR_WREN (0x4000) +#define MCF5282_QSPI_QWR_WRTO (0x2000) +#define MCF5282_QSPI_QWR_CSIV (0x1000) +#define MCF5282_QSPI_QWR_ENDQP(x) (((x)&0x000F)<<8) +#define MCF5282_QSPI_QWR_CPTQP(x) (((x)&0x000F)<<4) +#define MCF5282_QSPI_QWR_NEWQP(x) (((x)&0x000F)) + +#define MCF5282_QSPI_QIR_WCEFB (0x8000) +#define MCF5282_QSPI_QIR_ABRTB (0x4000) +#define MCF5282_QSPI_QIR_ABRTL (0x1000) +#define MCF5282_QSPI_QIR_WCEFE (0x0800) +#define MCF5282_QSPI_QIR_ABRTE (0x0400) +#define MCF5282_QSPI_QIR_SPIFE (0x0100) +#define MCF5282_QSPI_QIR_WCEF (0x0008) +#define MCF5282_QSPI_QIR_ABRT (0x0004) +#define MCF5282_QSPI_QIR_SPIF (0x0001) + +#define MCF5282_QSPI_QAR_ADDR(x) (((x)&0x003F)) + +#define MCF5282_QSPI_QDR_COMMAND(x) (((x)&0xFF00)) +#define MCF5282_QSPI_QCR_DATA(x) (((x)&0x00FF)<<8) +#define MCF5282_QSPI_QCR_CONT (0x8000) +#define MCF5282_QSPI_QCR_BITSE (0x4000) +#define MCF5282_QSPI_QCR_DT (0x2000) +#define MCF5282_QSPI_QCR_DSCK (0x1000) +#define MCF5282_QSPI_QCR_CS (((x)&0x000F)<<8) + +/****************************************************************************/ +#endif /* m528xsim_h */ diff --git a/arch/m68k/include/asm/m5307sim.h b/arch/m68k/include/asm/m5307sim.h new file mode 100644 index 00000000000..5886728409c --- /dev/null +++ b/arch/m68k/include/asm/m5307sim.h @@ -0,0 +1,181 @@ +/****************************************************************************/ + +/* + * m5307sim.h -- ColdFire 5307 System Integration Module support. + * + * (C) Copyright 1999, Moreton Bay Ventures Pty Ltd. + * (C) Copyright 1999, Lineo (www.lineo.com) + * + * Modified by David W. Miller for the MCF5307 Eval Board. + */ + +/****************************************************************************/ +#ifndef m5307sim_h +#define m5307sim_h +/****************************************************************************/ + +/* + * Define the 5307 SIM register set addresses. + */ +#define MCFSIM_RSR 0x00 /* Reset Status reg (r/w) */ +#define MCFSIM_SYPCR 0x01 /* System Protection reg (r/w)*/ +#define MCFSIM_SWIVR 0x02 /* SW Watchdog intr reg (r/w) */ +#define MCFSIM_SWSR 0x03 /* SW Watchdog service (r/w) */ +#define MCFSIM_PAR 0x04 /* Pin Assignment reg (r/w) */ +#define MCFSIM_IRQPAR 0x06 /* Interrupt Assignment reg (r/w) */ +#define MCFSIM_PLLCR 0x08 /* PLL Controll Reg*/ +#define MCFSIM_MPARK 0x0C /* BUS Master Control Reg*/ +#define MCFSIM_IPR 0x40 /* Interrupt Pend reg (r/w) */ +#define MCFSIM_IMR 0x44 /* Interrupt Mask reg (r/w) */ +#define MCFSIM_AVR 0x4b /* Autovector Ctrl reg (r/w) */ +#define MCFSIM_ICR0 0x4c /* Intr Ctrl reg 0 (r/w) */ +#define MCFSIM_ICR1 0x4d /* Intr Ctrl reg 1 (r/w) */ +#define MCFSIM_ICR2 0x4e /* Intr Ctrl reg 2 (r/w) */ +#define MCFSIM_ICR3 0x4f /* Intr Ctrl reg 3 (r/w) */ +#define MCFSIM_ICR4 0x50 /* Intr Ctrl reg 4 (r/w) */ +#define MCFSIM_ICR5 0x51 /* Intr Ctrl reg 5 (r/w) */ +#define MCFSIM_ICR6 0x52 /* Intr Ctrl reg 6 (r/w) */ +#define MCFSIM_ICR7 0x53 /* Intr Ctrl reg 7 (r/w) */ +#define MCFSIM_ICR8 0x54 /* Intr Ctrl reg 8 (r/w) */ +#define MCFSIM_ICR9 0x55 /* Intr Ctrl reg 9 (r/w) */ +#define MCFSIM_ICR10 0x56 /* Intr Ctrl reg 10 (r/w) */ +#define MCFSIM_ICR11 0x57 /* Intr Ctrl reg 11 (r/w) */ + +#define MCFSIM_CSAR0 0x80 /* CS 0 Address 0 reg (r/w) */ +#define MCFSIM_CSMR0 0x84 /* CS 0 Mask 0 reg (r/w) */ +#define MCFSIM_CSCR0 0x8a /* CS 0 Control reg (r/w) */ +#define MCFSIM_CSAR1 0x8c /* CS 1 Address reg (r/w) */ +#define MCFSIM_CSMR1 0x90 /* CS 1 Mask reg (r/w) */ +#define MCFSIM_CSCR1 0x96 /* CS 1 Control reg (r/w) */ + +#ifdef CONFIG_OLDMASK +#define MCFSIM_CSBAR 0x98 /* CS Base Address reg (r/w) */ +#define MCFSIM_CSBAMR 0x9c /* CS Base Mask reg (r/w) */ +#define MCFSIM_CSMR2 0x9e /* CS 2 Mask reg (r/w) */ +#define MCFSIM_CSCR2 0xa2 /* CS 2 Control reg (r/w) */ +#define MCFSIM_CSMR3 0xaa /* CS 3 Mask reg (r/w) */ +#define MCFSIM_CSCR3 0xae /* CS 3 Control reg (r/w) */ +#define MCFSIM_CSMR4 0xb6 /* CS 4 Mask reg (r/w) */ +#define MCFSIM_CSCR4 0xba /* CS 4 Control reg (r/w) */ +#define MCFSIM_CSMR5 0xc2 /* CS 5 Mask reg (r/w) */ +#define MCFSIM_CSCR5 0xc6 /* CS 5 Control reg (r/w) */ +#define MCFSIM_CSMR6 0xce /* CS 6 Mask reg (r/w) */ +#define MCFSIM_CSCR6 0xd2 /* CS 6 Control reg (r/w) */ +#define MCFSIM_CSMR7 0xda /* CS 7 Mask reg (r/w) */ +#define MCFSIM_CSCR7 0xde /* CS 7 Control reg (r/w) */ +#else +#define MCFSIM_CSAR2 0x98 /* CS 2 Address reg (r/w) */ +#define MCFSIM_CSMR2 0x9c /* CS 2 Mask reg (r/w) */ +#define MCFSIM_CSCR2 0xa2 /* CS 2 Control reg (r/w) */ +#define MCFSIM_CSAR3 0xa4 /* CS 3 Address reg (r/w) */ +#define MCFSIM_CSMR3 0xa8 /* CS 3 Mask reg (r/w) */ +#define MCFSIM_CSCR3 0xae /* CS 3 Control reg (r/w) */ +#define MCFSIM_CSAR4 0xb0 /* CS 4 Address reg (r/w) */ +#define MCFSIM_CSMR4 0xb4 /* CS 4 Mask reg (r/w) */ +#define MCFSIM_CSCR4 0xba /* CS 4 Control reg (r/w) */ +#define MCFSIM_CSAR5 0xbc /* CS 5 Address reg (r/w) */ +#define MCFSIM_CSMR5 0xc0 /* CS 5 Mask reg (r/w) */ +#define MCFSIM_CSCR5 0xc6 /* CS 5 Control reg (r/w) */ +#define MCFSIM_CSAR6 0xc8 /* CS 6 Address reg (r/w) */ +#define MCFSIM_CSMR6 0xcc /* CS 6 Mask reg (r/w) */ +#define MCFSIM_CSCR6 0xd2 /* CS 6 Control reg (r/w) */ +#define MCFSIM_CSAR7 0xd4 /* CS 7 Address reg (r/w) */ +#define MCFSIM_CSMR7 0xd8 /* CS 7 Mask reg (r/w) */ +#define MCFSIM_CSCR7 0xde /* CS 7 Control reg (r/w) */ +#endif /* CONFIG_OLDMASK */ + +#define MCFSIM_DCR 0x100 /* DRAM Control reg (r/w) */ +#define MCFSIM_DACR0 0x108 /* DRAM 0 Addr and Ctrl (r/w) */ +#define MCFSIM_DMR0 0x10c /* DRAM 0 Mask reg (r/w) */ +#define MCFSIM_DACR1 0x110 /* DRAM 1 Addr and Ctrl (r/w) */ +#define MCFSIM_DMR1 0x114 /* DRAM 1 Mask reg (r/w) */ + +#define MCFSIM_PADDR 0x244 /* Parallel Direction (r/w) */ +#define MCFSIM_PADAT 0x248 /* Parallel Data (r/w) */ + + +/* Definition offset address for CS2-7 -- old mask 5307 */ + +#define MCF5307_CS2 (0x400000) +#define MCF5307_CS3 (0x600000) +#define MCF5307_CS4 (0x800000) +#define MCF5307_CS5 (0xA00000) +#define MCF5307_CS6 (0xC00000) +#define MCF5307_CS7 (0xE00000) + + +/* + * Some symbol defines for the above... + */ +#define MCFSIM_SWDICR MCFSIM_ICR0 /* Watchdog timer ICR */ +#define MCFSIM_TIMER1ICR MCFSIM_ICR1 /* Timer 1 ICR */ +#define MCFSIM_TIMER2ICR MCFSIM_ICR2 /* Timer 2 ICR */ +#define MCFSIM_UART1ICR MCFSIM_ICR4 /* UART 1 ICR */ +#define MCFSIM_UART2ICR MCFSIM_ICR5 /* UART 2 ICR */ +#define MCFSIM_DMA0ICR MCFSIM_ICR6 /* DMA 0 ICR */ +#define MCFSIM_DMA1ICR MCFSIM_ICR7 /* DMA 1 ICR */ +#define MCFSIM_DMA2ICR MCFSIM_ICR8 /* DMA 2 ICR */ +#define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */ + +#if defined(CONFIG_M5307) +#define MCFSIM_IMR_MASKALL 0x3fffe /* All SIM intr sources */ +#endif + +/* + * Macro to set IMR register. It is 32 bits on the 5307. + */ +#define mcf_getimr() \ + *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) + +#define mcf_setimr(imr) \ + *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr); + +#define mcf_getipr() \ + *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR)) + + +/* + * Some symbol defines for the Parallel Port Pin Assignment Register + */ +#define MCFSIM_PAR_DREQ0 0x40 /* Set to select DREQ0 input */ + /* Clear to select par I/O */ +#define MCFSIM_PAR_DREQ1 0x20 /* Select DREQ1 input */ + /* Clear to select par I/O */ + +/* + * Defines for the IRQPAR Register + */ +#define IRQ5_LEVEL4 0x80 +#define IRQ3_LEVEL6 0x40 +#define IRQ1_LEVEL2 0x20 + + +/* + * Define the Cache register flags. + */ +#define CACR_EC (1<<31) +#define CACR_ESB (1<<29) +#define CACR_DPI (1<<28) +#define CACR_HLCK (1<<27) +#define CACR_CINVA (1<<24) +#define CACR_DNFB (1<<10) +#define CACR_DCM_WTHRU (0<<8) +#define CACR_DCM_WBACK (1<<8) +#define CACR_DCM_OFF_PRE (2<<8) +#define CACR_DCM_OFF_IMP (3<<8) +#define CACR_DW (1<<5) + +#define ACR_BASE_POS 24 +#define ACR_MASK_POS 16 +#define ACR_ENABLE (1<<15) +#define ACR_USER (0<<13) +#define ACR_SUPER (1<<13) +#define ACR_ANY (2<<13) +#define ACR_CM_WTHRU (0<<5) +#define ACR_CM_WBACK (1<<5) +#define ACR_CM_OFF_PRE (2<<5) +#define ACR_CM_OFF_IMP (3<<5) +#define ACR_WPROTECT (1<<2) + +/****************************************************************************/ +#endif /* m5307sim_h */ diff --git a/arch/m68k/include/asm/m532xsim.h b/arch/m68k/include/asm/m532xsim.h new file mode 100644 index 00000000000..1835fd20a82 --- /dev/null +++ b/arch/m68k/include/asm/m532xsim.h @@ -0,0 +1,2238 @@ +/****************************************************************************/ + +/* + * m532xsim.h -- ColdFire 5329 registers + */ + +/****************************************************************************/ +#ifndef m532xsim_h +#define m532xsim_h +/****************************************************************************/ + +#define MCF_REG32(x) (*(volatile unsigned long *)(x)) +#define MCF_REG16(x) (*(volatile unsigned short *)(x)) +#define MCF_REG08(x) (*(volatile unsigned char *)(x)) + +#define MCFINT_VECBASE 64 +#define MCFINT_UART0 26 /* Interrupt number for UART0 */ +#define MCFINT_UART1 27 /* Interrupt number for UART1 */ + +#define MCF_WTM_WCR MCF_REG16(0xFC098000) + +/* + * Define the 532x SIM register set addresses. + */ +#define MCFSIM_IPRL 0xFC048004 +#define MCFSIM_IPRH 0xFC048000 +#define MCFSIM_IPR MCFSIM_IPRL +#define MCFSIM_IMRL 0xFC04800C +#define MCFSIM_IMRH 0xFC048008 +#define MCFSIM_IMR MCFSIM_IMRL +#define MCFSIM_ICR0 0xFC048040 +#define MCFSIM_ICR1 0xFC048041 +#define MCFSIM_ICR2 0xFC048042 +#define MCFSIM_ICR3 0xFC048043 +#define MCFSIM_ICR4 0xFC048044 +#define MCFSIM_ICR5 0xFC048045 +#define MCFSIM_ICR6 0xFC048046 +#define MCFSIM_ICR7 0xFC048047 +#define MCFSIM_ICR8 0xFC048048 +#define MCFSIM_ICR9 0xFC048049 +#define MCFSIM_ICR10 0xFC04804A +#define MCFSIM_ICR11 0xFC04804B + +/* + * Some symbol defines for the above... + */ +#define MCFSIM_SWDICR MCFSIM_ICR0 /* Watchdog timer ICR */ +#define MCFSIM_TIMER1ICR MCFSIM_ICR1 /* Timer 1 ICR */ +#define MCFSIM_TIMER2ICR MCFSIM_ICR2 /* Timer 2 ICR */ +#define MCFSIM_UART1ICR MCFSIM_ICR4 /* UART 1 ICR */ +#define MCFSIM_UART2ICR MCFSIM_ICR5 /* UART 2 ICR */ +#define MCFSIM_DMA0ICR MCFSIM_ICR6 /* DMA 0 ICR */ +#define MCFSIM_DMA1ICR MCFSIM_ICR7 /* DMA 1 ICR */ +#define MCFSIM_DMA2ICR MCFSIM_ICR8 /* DMA 2 ICR */ +#define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */ + + +#define MCFSIM_IMR_MASKALL 0xFFFFFFFF /* All SIM intr sources */ + +#define MCFSIM_IMR_SIMR0 0xFC04801C +#define MCFSIM_IMR_SIMR1 0xFC04C01C +#define MCFSIM_IMR_CIMR0 0xFC04801D +#define MCFSIM_IMR_CIMR1 0xFC04C01D + +#define MCFSIM_ICR_TIMER1 (0xFC048040+32) +#define MCFSIM_ICR_TIMER2 (0xFC048040+33) + + +/* + * Macro to set IMR register. It is 32 bits on the 5307. + */ +#define mcf_getimr() \ + *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) + +#define mcf_setimr(imr) \ + *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr); + +#define mcf_getipr() \ + *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR)) + +#define mcf_getiprl() \ + *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPRL)) + +#define mcf_getiprh() \ + *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPRH)) + + +#define mcf_enable_irq0(irq) \ + *((volatile unsigned char*) (MCFSIM_IMR_CIMR0)) = (irq); + +#define mcf_enable_irq1(irq) \ + *((volatile unsigned char*) (MCFSIM_IMR_CIMR1)) = (irq); + +#define mcf_disable_irq0(irq) \ + *((volatile unsigned char*) (MCFSIM_IMR_SIMR0)) = (irq); + +#define mcf_disable_irq1(irq) \ + *((volatile unsigned char*) (MCFSIM_IMR_SIMR1)) = (irq); + +/* + * Define the Cache register flags. + */ +#define CACR_EC (1<<31) +#define CACR_ESB (1<<29) +#define CACR_DPI (1<<28) +#define CACR_HLCK (1<<27) +#define CACR_CINVA (1<<24) +#define CACR_DNFB (1<<10) +#define CACR_DCM_WTHRU (0<<8) +#define CACR_DCM_WBACK (1<<8) +#define CACR_DCM_OFF_PRE (2<<8) +#define CACR_DCM_OFF_IMP (3<<8) +#define CACR_DW (1<<5) + +#define ACR_BASE_POS 24 +#define ACR_MASK_POS 16 +#define ACR_ENABLE (1<<15) +#define ACR_USER (0<<13) +#define ACR_SUPER (1<<13) +#define ACR_ANY (2<<13) +#define ACR_CM_WTHRU (0<<5) +#define ACR_CM_WBACK (1<<5) +#define ACR_CM_OFF_PRE (2<<5) +#define ACR_CM_OFF_IMP (3<<5) +#define ACR_WPROTECT (1<<2) + +/********************************************************************* + * + * Inter-IC (I2C) Module + * + *********************************************************************/ + +/* Read/Write access macros for general use */ +#define MCF532x_I2C_I2ADR (volatile u8 *) (0xFC058000) // Address +#define MCF532x_I2C_I2FDR (volatile u8 *) (0xFC058004) // Freq Divider +#define MCF532x_I2C_I2CR (volatile u8 *) (0xFC058008) // Control +#define MCF532x_I2C_I2SR (volatile u8 *) (0xFC05800C) // Status +#define MCF532x_I2C_I2DR (volatile u8 *) (0xFC058010) // Data I/O + +/* Bit level definitions and macros */ +#define MCF532x_I2C_I2ADR_ADDR(x) (((x)&0x7F)<<0x01) + +#define MCF532x_I2C_I2FDR_IC(x) (((x)&0x3F)) + +#define MCF532x_I2C_I2CR_IEN (0x80) // I2C enable +#define MCF532x_I2C_I2CR_IIEN (0x40) // interrupt enable +#define MCF532x_I2C_I2CR_MSTA (0x20) // master/slave mode +#define MCF532x_I2C_I2CR_MTX (0x10) // transmit/receive mode +#define MCF532x_I2C_I2CR_TXAK (0x08) // transmit acknowledge enable +#define MCF532x_I2C_I2CR_RSTA (0x04) // repeat start + +#define MCF532x_I2C_I2SR_ICF (0x80) // data transfer bit +#define MCF532x_I2C_I2SR_IAAS (0x40) // I2C addressed as a slave +#define MCF532x_I2C_I2SR_IBB (0x20) // I2C bus busy +#define MCF532x_I2C_I2SR_IAL (0x10) // aribitration lost +#define MCF532x_I2C_I2SR_SRW (0x04) // slave read/write +#define MCF532x_I2C_I2SR_IIF (0x02) // I2C interrupt +#define MCF532x_I2C_I2SR_RXAK (0x01) // received acknowledge + +#define MCF532x_PAR_FECI2C (volatile u8 *) (0xFC0A4053) + + +/* + * The M5329EVB board needs a help getting its devices initialized + * at kernel start time if dBUG doesn't set it up (for example + * it is not used), so we need to do it manually. + */ +#ifdef __ASSEMBLER__ +.macro m5329EVB_setup + movel #0xFC098000, %a7 + movel #0x0, (%a7) +#define CORE_SRAM 0x80000000 +#define CORE_SRAM_SIZE 0x8000 + movel #CORE_SRAM, %d0 + addl #0x221, %d0 + movec %d0,%RAMBAR1 + movel #CORE_SRAM, %sp + addl #CORE_SRAM_SIZE, %sp + jsr sysinit +.endm +#define PLATFORM_SETUP m5329EVB_setup + +#endif /* __ASSEMBLER__ */ + +/********************************************************************* + * + * Chip Configuration Module (CCM) + * + *********************************************************************/ + +/* Register read/write macros */ +#define MCF_CCM_CCR MCF_REG16(0xFC0A0004) +#define MCF_CCM_RCON MCF_REG16(0xFC0A0008) +#define MCF_CCM_CIR MCF_REG16(0xFC0A000A) +#define MCF_CCM_MISCCR MCF_REG16(0xFC0A0010) +#define MCF_CCM_CDR MCF_REG16(0xFC0A0012) +#define MCF_CCM_UHCSR MCF_REG16(0xFC0A0014) +#define MCF_CCM_UOCSR MCF_REG16(0xFC0A0016) + +/* Bit definitions and macros for MCF_CCM_CCR */ +#define MCF_CCM_CCR_RESERVED (0x0001) +#define MCF_CCM_CCR_PLL_MODE (0x0003) +#define MCF_CCM_CCR_OSC_MODE (0x0005) +#define MCF_CCM_CCR_BOOTPS(x) (((x)&0x0003)<<3|0x0001) +#define MCF_CCM_CCR_LOAD (0x0021) +#define MCF_CCM_CCR_LIMP (0x0041) +#define MCF_CCM_CCR_CSC(x) (((x)&0x0003)<<8|0x0001) + +/* Bit definitions and macros for MCF_CCM_RCON */ +#define MCF_CCM_RCON_RESERVED (0x0001) +#define MCF_CCM_RCON_PLL_MODE (0x0003) +#define MCF_CCM_RCON_OSC_MODE (0x0005) +#define MCF_CCM_RCON_BOOTPS(x) (((x)&0x0003)<<3|0x0001) +#define MCF_CCM_RCON_LOAD (0x0021) +#define MCF_CCM_RCON_LIMP (0x0041) +#define MCF_CCM_RCON_CSC(x) (((x)&0x0003)<<8|0x0001) + +/* Bit definitions and macros for MCF_CCM_CIR */ +#define MCF_CCM_CIR_PRN(x) (((x)&0x003F)<<0) +#define MCF_CCM_CIR_PIN(x) (((x)&0x03FF)<<6) + +/* Bit definitions and macros for MCF_CCM_MISCCR */ +#define MCF_CCM_MISCCR_USBSRC (0x0001) +#define MCF_CCM_MISCCR_USBDIV (0x0002) +#define MCF_CCM_MISCCR_SSI_SRC (0x0010) +#define MCF_CCM_MISCCR_TIM_DMA (0x0020) +#define MCF_CCM_MISCCR_SSI_PUS (0x0040) +#define MCF_CCM_MISCCR_SSI_PUE (0x0080) +#define MCF_CCM_MISCCR_LCD_CHEN (0x0100) +#define MCF_CCM_MISCCR_LIMP (0x1000) +#define MCF_CCM_MISCCR_PLL_LOCK (0x2000) + +/* Bit definitions and macros for MCF_CCM_CDR */ +#define MCF_CCM_CDR_SSIDIV(x) (((x)&0x000F)<<0) +#define MCF_CCM_CDR_LPDIV(x) (((x)&0x000F)<<8) + +/* Bit definitions and macros for MCF_CCM_UHCSR */ +#define MCF_CCM_UHCSR_XPDE (0x0001) +#define MCF_CCM_UHCSR_UHMIE (0x0002) +#define MCF_CCM_UHCSR_WKUP (0x0004) +#define MCF_CCM_UHCSR_PORTIND(x) (((x)&0x0003)<<14) + +/* Bit definitions and macros for MCF_CCM_UOCSR */ +#define MCF_CCM_UOCSR_XPDE (0x0001) +#define MCF_CCM_UOCSR_UOMIE (0x0002) +#define MCF_CCM_UOCSR_WKUP (0x0004) +#define MCF_CCM_UOCSR_PWRFLT (0x0008) +#define MCF_CCM_UOCSR_SEND (0x0010) +#define MCF_CCM_UOCSR_VVLD (0x0020) +#define MCF_CCM_UOCSR_BVLD (0x0040) +#define MCF_CCM_UOCSR_AVLD (0x0080) +#define MCF_CCM_UOCSR_DPPU (0x0100) +#define MCF_CCM_UOCSR_DCR_VBUS (0x0200) +#define MCF_CCM_UOCSR_CRG_VBUS (0x0400) +#define MCF_CCM_UOCSR_DRV_VBUS (0x0800) +#define MCF_CCM_UOCSR_DMPD (0x1000) +#define MCF_CCM_UOCSR_DPPD (0x2000) +#define MCF_CCM_UOCSR_PORTIND(x) (((x)&0x0003)<<14) + +/********************************************************************* + * + * DMA Timers (DTIM) + * + *********************************************************************/ + +/* Register read/write macros */ +#define MCF_DTIM0_DTMR MCF_REG16(0xFC070000) +#define MCF_DTIM0_DTXMR MCF_REG08(0xFC070002) +#define MCF_DTIM0_DTER MCF_REG08(0xFC070003) +#define MCF_DTIM0_DTRR MCF_REG32(0xFC070004) +#define MCF_DTIM0_DTCR MCF_REG32(0xFC070008) +#define MCF_DTIM0_DTCN MCF_REG32(0xFC07000C) +#define MCF_DTIM1_DTMR MCF_REG16(0xFC074000) +#define MCF_DTIM1_DTXMR MCF_REG08(0xFC074002) +#define MCF_DTIM1_DTER MCF_REG08(0xFC074003) +#define MCF_DTIM1_DTRR MCF_REG32(0xFC074004) +#define MCF_DTIM1_DTCR MCF_REG32(0xFC074008) +#define MCF_DTIM1_DTCN MCF_REG32(0xFC07400C) +#define MCF_DTIM2_DTMR MCF_REG16(0xFC078000) +#define MCF_DTIM2_DTXMR MCF_REG08(0xFC078002) +#define MCF_DTIM2_DTER MCF_REG08(0xFC078003) +#define MCF_DTIM2_DTRR MCF_REG32(0xFC078004) +#define MCF_DTIM2_DTCR MCF_REG32(0xFC078008) +#define MCF_DTIM2_DTCN MCF_REG32(0xFC07800C) +#define MCF_DTIM3_DTMR MCF_REG16(0xFC07C000) +#define MCF_DTIM3_DTXMR MCF_REG08(0xFC07C002) +#define MCF_DTIM3_DTER MCF_REG08(0xFC07C003) +#define MCF_DTIM3_DTRR MCF_REG32(0xFC07C004) +#define MCF_DTIM3_DTCR MCF_REG32(0xFC07C008) +#define MCF_DTIM3_DTCN MCF_REG32(0xFC07C00C) +#define MCF_DTIM_DTMR(x) MCF_REG16(0xFC070000+((x)*0x4000)) +#define MCF_DTIM_DTXMR(x) MCF_REG08(0xFC070002+((x)*0x4000)) +#define MCF_DTIM_DTER(x) MCF_REG08(0xFC070003+((x)*0x4000)) +#define MCF_DTIM_DTRR(x) MCF_REG32(0xFC070004+((x)*0x4000)) +#define MCF_DTIM_DTCR(x) MCF_REG32(0xFC070008+((x)*0x4000)) +#define MCF_DTIM_DTCN(x) MCF_REG32(0xFC07000C+((x)*0x4000)) + +/* Bit definitions and macros for MCF_DTIM_DTMR */ +#define MCF_DTIM_DTMR_RST (0x0001) +#define MCF_DTIM_DTMR_CLK(x) (((x)&0x0003)<<1) +#define MCF_DTIM_DTMR_FRR (0x0008) +#define MCF_DTIM_DTMR_ORRI (0x0010) +#define MCF_DTIM_DTMR_OM (0x0020) +#define MCF_DTIM_DTMR_CE(x) (((x)&0x0003)<<6) +#define MCF_DTIM_DTMR_PS(x) (((x)&0x00FF)<<8) +#define MCF_DTIM_DTMR_CE_ANY (0x00C0) +#define MCF_DTIM_DTMR_CE_FALL (0x0080) +#define MCF_DTIM_DTMR_CE_RISE (0x0040) +#define MCF_DTIM_DTMR_CE_NONE (0x0000) +#define MCF_DTIM_DTMR_CLK_DTIN (0x0006) +#define MCF_DTIM_DTMR_CLK_DIV16 (0x0004) +#define MCF_DTIM_DTMR_CLK_DIV1 (0x0002) +#define MCF_DTIM_DTMR_CLK_STOP (0x0000) + +/* Bit definitions and macros for MCF_DTIM_DTXMR */ +#define MCF_DTIM_DTXMR_MODE16 (0x01) +#define MCF_DTIM_DTXMR_DMAEN (0x80) + +/* Bit definitions and macros for MCF_DTIM_DTER */ +#define MCF_DTIM_DTER_CAP (0x01) +#define MCF_DTIM_DTER_REF (0x02) + +/* Bit definitions and macros for MCF_DTIM_DTRR */ +#define MCF_DTIM_DTRR_REF(x) (((x)&0xFFFFFFFF)<<0) + +/* Bit definitions and macros for MCF_DTIM_DTCR */ +#define MCF_DTIM_DTCR_CAP(x) (((x)&0xFFFFFFFF)<<0) + +/* Bit definitions and macros for MCF_DTIM_DTCN */ +#define MCF_DTIM_DTCN_CNT(x) (((x)&0xFFFFFFFF)<<0) + +/********************************************************************* + * + * FlexBus Chip Selects (FBCS) + * + *********************************************************************/ + +/* Register read/write macros */ +#define MCF_FBCS0_CSAR MCF_REG32(0xFC008000) +#define MCF_FBCS0_CSMR MCF_REG32(0xFC008004) +#define MCF_FBCS0_CSCR MCF_REG32(0xFC008008) +#define MCF_FBCS1_CSAR MCF_REG32(0xFC00800C) +#define MCF_FBCS1_CSMR MCF_REG32(0xFC008010) +#define MCF_FBCS1_CSCR MCF_REG32(0xFC008014) +#define MCF_FBCS2_CSAR MCF_REG32(0xFC008018) +#define MCF_FBCS2_CSMR MCF_REG32(0xFC00801C) +#define MCF_FBCS2_CSCR MCF_REG32(0xFC008020) +#define MCF_FBCS3_CSAR MCF_REG32(0xFC008024) +#define MCF_FBCS3_CSMR MCF_REG32(0xFC008028) +#define MCF_FBCS3_CSCR MCF_REG32(0xFC00802C) +#define MCF_FBCS4_CSAR MCF_REG32(0xFC008030) +#define MCF_FBCS4_CSMR MCF_REG32(0xFC008034) +#define MCF_FBCS4_CSCR MCF_REG32(0xFC008038) +#define MCF_FBCS5_CSAR MCF_REG32(0xFC00803C) +#define MCF_FBCS5_CSMR MCF_REG32(0xFC008040) +#define MCF_FBCS5_CSCR MCF_REG32(0xFC008044) +#define MCF_FBCS_CSAR(x) MCF_REG32(0xFC008000+((x)*0x00C)) +#define MCF_FBCS_CSMR(x) MCF_REG32(0xFC008004+((x)*0x00C)) +#define MCF_FBCS_CSCR(x) MCF_REG32(0xFC008008+((x)*0x00C)) + +/* Bit definitions and macros for MCF_FBCS_CSAR */ +#define MCF_FBCS_CSAR_BA(x) ((x)&0xFFFF0000) + +/* Bit definitions and macros for MCF_FBCS_CSMR */ +#define MCF_FBCS_CSMR_V (0x00000001) +#define MCF_FBCS_CSMR_WP (0x00000100) +#define MCF_FBCS_CSMR_BAM(x) (((x)&0x0000FFFF)<<16) +#define MCF_FBCS_CSMR_BAM_4G (0xFFFF0000) +#define MCF_FBCS_CSMR_BAM_2G (0x7FFF0000) +#define MCF_FBCS_CSMR_BAM_1G (0x3FFF0000) +#define MCF_FBCS_CSMR_BAM_1024M (0x3FFF0000) +#define MCF_FBCS_CSMR_BAM_512M (0x1FFF0000) +#define MCF_FBCS_CSMR_BAM_256M (0x0FFF0000) +#define MCF_FBCS_CSMR_BAM_128M (0x07FF0000) +#define MCF_FBCS_CSMR_BAM_64M (0x03FF0000) +#define MCF_FBCS_CSMR_BAM_32M (0x01FF0000) +#define MCF_FBCS_CSMR_BAM_16M (0x00FF0000) +#define MCF_FBCS_CSMR_BAM_8M (0x007F0000) +#define MCF_FBCS_CSMR_BAM_4M (0x003F0000) +#define MCF_FBCS_CSMR_BAM_2M (0x001F0000) +#define MCF_FBCS_CSMR_BAM_1M (0x000F0000) +#define MCF_FBCS_CSMR_BAM_1024K (0x000F0000) +#define MCF_FBCS_CSMR_BAM_512K (0x00070000) +#define MCF_FBCS_CSMR_BAM_256K (0x00030000) +#define MCF_FBCS_CSMR_BAM_128K (0x00010000) +#define MCF_FBCS_CSMR_BAM_64K (0x00000000) + +/* Bit definitions and macros for MCF_FBCS_CSCR */ +#define MCF_FBCS_CSCR_BSTW (0x00000008) +#define MCF_FBCS_CSCR_BSTR (0x00000010) +#define MCF_FBCS_CSCR_BEM (0x00000020) +#define MCF_FBCS_CSCR_PS(x) (((x)&0x00000003)<<6) +#define MCF_FBCS_CSCR_AA (0x00000100) +#define MCF_FBCS_CSCR_SBM (0x00000200) +#define MCF_FBCS_CSCR_WS(x) (((x)&0x0000003F)<<10) +#define MCF_FBCS_CSCR_WRAH(x) (((x)&0x00000003)<<16) +#define MCF_FBCS_CSCR_RDAH(x) (((x)&0x00000003)<<18) +#define MCF_FBCS_CSCR_ASET(x) (((x)&0x00000003)<<20) +#define MCF_FBCS_CSCR_SWSEN (0x00800000) +#define MCF_FBCS_CSCR_SWS(x) (((x)&0x0000003F)<<26) +#define MCF_FBCS_CSCR_PS_8 (0x0040) +#define MCF_FBCS_CSCR_PS_16 (0x0080) +#define MCF_FBCS_CSCR_PS_32 (0x0000) + +/********************************************************************* + * + * General Purpose I/O (GPIO) + * + *********************************************************************/ + +/* Register read/write macros */ +#define MCF_GPIO_PODR_FECH MCF_REG08(0xFC0A4000) +#define MCF_GPIO_PODR_FECL MCF_REG08(0xFC0A4001) +#define MCF_GPIO_PODR_SSI MCF_REG08(0xFC0A4002) +#define MCF_GPIO_PODR_BUSCTL MCF_REG08(0xFC0A4003) +#define MCF_GPIO_PODR_BE MCF_REG08(0xFC0A4004) +#define MCF_GPIO_PODR_CS MCF_REG08(0xFC0A4005) +#define MCF_GPIO_PODR_PWM MCF_REG08(0xFC0A4006) +#define MCF_GPIO_PODR_FECI2C MCF_REG08(0xFC0A4007) +#define MCF_GPIO_PODR_UART MCF_REG08(0xFC0A4009) +#define MCF_GPIO_PODR_QSPI MCF_REG08(0xFC0A400A) +#define MCF_GPIO_PODR_TIMER MCF_REG08(0xFC0A400B) +#define MCF_GPIO_PODR_LCDDATAH MCF_REG08(0xFC0A400D) +#define MCF_GPIO_PODR_LCDDATAM MCF_REG08(0xFC0A400E) +#define MCF_GPIO_PODR_LCDDATAL MCF_REG08(0xFC0A400F) +#define MCF_GPIO_PODR_LCDCTLH MCF_REG08(0xFC0A4010) +#define MCF_GPIO_PODR_LCDCTLL MCF_REG08(0xFC0A4011) +#define MCF_GPIO_PDDR_FECH MCF_REG08(0xFC0A4014) +#define MCF_GPIO_PDDR_FECL MCF_REG08(0xFC0A4015) +#define MCF_GPIO_PDDR_SSI MCF_REG08(0xFC0A4016) +#define MCF_GPIO_PDDR_BUSCTL MCF_REG08(0xFC0A4017) +#define MCF_GPIO_PDDR_BE MCF_REG08(0xFC0A4018) +#define MCF_GPIO_PDDR_CS MCF_REG08(0xFC0A4019) +#define MCF_GPIO_PDDR_PWM MCF_REG08(0xFC0A401A) +#define MCF_GPIO_PDDR_FECI2C MCF_REG08(0xFC0A401B) +#define MCF_GPIO_PDDR_UART MCF_REG08(0xFC0A401C) +#define MCF_GPIO_PDDR_QSPI MCF_REG08(0xFC0A401E) +#define MCF_GPIO_PDDR_TIMER MCF_REG08(0xFC0A401F) +#define MCF_GPIO_PDDR_LCDDATAH MCF_REG08(0xFC0A4021) +#define MCF_GPIO_PDDR_LCDDATAM MCF_REG08(0xFC0A4022) +#define MCF_GPIO_PDDR_LCDDATAL MCF_REG08(0xFC0A4023) +#define MCF_GPIO_PDDR_LCDCTLH MCF_REG08(0xFC0A4024) +#define MCF_GPIO_PDDR_LCDCTLL MCF_REG08(0xFC0A4025) +#define MCF_GPIO_PPDSDR_FECH MCF_REG08(0xFC0A4028) +#define MCF_GPIO_PPDSDR_FECL MCF_REG08(0xFC0A4029) +#define MCF_GPIO_PPDSDR_SSI MCF_REG08(0xFC0A402A) +#define MCF_GPIO_PPDSDR_BUSCTL MCF_REG08(0xFC0A402B) +#define MCF_GPIO_PPDSDR_BE MCF_REG08(0xFC0A402C) +#define MCF_GPIO_PPDSDR_CS MCF_REG08(0xFC0A402D) +#define MCF_GPIO_PPDSDR_PWM MCF_REG08(0xFC0A402E) +#define MCF_GPIO_PPDSDR_FECI2C MCF_REG08(0xFC0A402F) +#define MCF_GPIO_PPDSDR_UART MCF_REG08(0xFC0A4031) +#define MCF_GPIO_PPDSDR_QSPI MCF_REG08(0xFC0A4032) +#define MCF_GPIO_PPDSDR_TIMER MCF_REG08(0xFC0A4033) +#define MCF_GPIO_PPDSDR_LCDDATAH MCF_REG08(0xFC0A4035) +#define MCF_GPIO_PPDSDR_LCDDATAM MCF_REG08(0xFC0A4036) +#define MCF_GPIO_PPDSDR_LCDDATAL MCF_REG08(0xFC0A4037) +#define MCF_GPIO_PPDSDR_LCDCTLH MCF_REG08(0xFC0A4038) +#define MCF_GPIO_PPDSDR_LCDCTLL MCF_REG08(0xFC0A4039) +#define MCF_GPIO_PCLRR_FECH MCF_REG08(0xFC0A403C) +#define MCF_GPIO_PCLRR_FECL MCF_REG08(0xFC0A403D) +#define MCF_GPIO_PCLRR_SSI MCF_REG08(0xFC0A403E) +#define MCF_GPIO_PCLRR_BUSCTL MCF_REG08(0xFC0A403F) +#define MCF_GPIO_PCLRR_BE MCF_REG08(0xFC0A4040) +#define MCF_GPIO_PCLRR_CS MCF_REG08(0xFC0A4041) +#define MCF_GPIO_PCLRR_PWM MCF_REG08(0xFC0A4042) +#define MCF_GPIO_PCLRR_FECI2C MCF_REG08(0xFC0A4043) +#define MCF_GPIO_PCLRR_UART MCF_REG08(0xFC0A4045) +#define MCF_GPIO_PCLRR_QSPI MCF_REG08(0xFC0A4046) +#define MCF_GPIO_PCLRR_TIMER MCF_REG08(0xFC0A4047) +#define MCF_GPIO_PCLRR_LCDDATAH MCF_REG08(0xFC0A4049) +#define MCF_GPIO_PCLRR_LCDDATAM MCF_REG08(0xFC0A404A) +#define MCF_GPIO_PCLRR_LCDDATAL MCF_REG08(0xFC0A404B) +#define MCF_GPIO_PCLRR_LCDCTLH MCF_REG08(0xFC0A404C) +#define MCF_GPIO_PCLRR_LCDCTLL MCF_REG08(0xFC0A404D) +#define MCF_GPIO_PAR_FEC MCF_REG08(0xFC0A4050) +#define MCF_GPIO_PAR_PWM MCF_REG08(0xFC0A4051) +#define MCF_GPIO_PAR_BUSCTL MCF_REG08(0xFC0A4052) +#define MCF_GPIO_PAR_FECI2C MCF_REG08(0xFC0A4053) +#define MCF_GPIO_PAR_BE MCF_REG08(0xFC0A4054) +#define MCF_GPIO_PAR_CS MCF_REG08(0xFC0A4055) +#define MCF_GPIO_PAR_SSI MCF_REG16(0xFC0A4056) +#define MCF_GPIO_PAR_UART MCF_REG16(0xFC0A4058) +#define MCF_GPIO_PAR_QSPI MCF_REG16(0xFC0A405A) +#define MCF_GPIO_PAR_TIMER MCF_REG08(0xFC0A405C) +#define MCF_GPIO_PAR_LCDDATA MCF_REG08(0xFC0A405D) +#define MCF_GPIO_PAR_LCDCTL MCF_REG16(0xFC0A405E) +#define MCF_GPIO_PAR_IRQ MCF_REG16(0xFC0A4060) +#define MCF_GPIO_MSCR_FLEXBUS MCF_REG08(0xFC0A4064) +#define MCF_GPIO_MSCR_SDRAM MCF_REG08(0xFC0A4065) +#define MCF_GPIO_DSCR_I2C MCF_REG08(0xFC0A4068) +#define MCF_GPIO_DSCR_PWM MCF_REG08(0xFC0A4069) +#define MCF_GPIO_DSCR_FEC MCF_REG08(0xFC0A406A) +#define MCF_GPIO_DSCR_UART MCF_REG08(0xFC0A406B) +#define MCF_GPIO_DSCR_QSPI MCF_REG08(0xFC0A406C) +#define MCF_GPIO_DSCR_TIMER MCF_REG08(0xFC0A406D) +#define MCF_GPIO_DSCR_SSI MCF_REG08(0xFC0A406E) +#define MCF_GPIO_DSCR_LCD MCF_REG08(0xFC0A406F) +#define MCF_GPIO_DSCR_DEBUG MCF_REG08(0xFC0A4070) +#define MCF_GPIO_DSCR_CLKRST MCF_REG08(0xFC0A4071) +#define MCF_GPIO_DSCR_IRQ MCF_REG08(0xFC0A4072) + +/* Bit definitions and macros for MCF_GPIO_PODR_FECH */ +#define MCF_GPIO_PODR_FECH_PODR_FECH0 (0x01) +#define MCF_GPIO_PODR_FECH_PODR_FECH1 (0x02) +#define MCF_GPIO_PODR_FECH_PODR_FECH2 (0x04) +#define MCF_GPIO_PODR_FECH_PODR_FECH3 (0x08) +#define MCF_GPIO_PODR_FECH_PODR_FECH4 (0x10) +#define MCF_GPIO_PODR_FECH_PODR_FECH5 (0x20) +#define MCF_GPIO_PODR_FECH_PODR_FECH6 (0x40) +#define MCF_GPIO_PODR_FECH_PODR_FECH7 (0x80) + +/* Bit definitions and macros for MCF_GPIO_PODR_FECL */ +#define MCF_GPIO_PODR_FECL_PODR_FECL0 (0x01) +#define MCF_GPIO_PODR_FECL_PODR_FECL1 (0x02) +#define MCF_GPIO_PODR_FECL_PODR_FECL2 (0x04) +#define MCF_GPIO_PODR_FECL_PODR_FECL3 (0x08) +#define MCF_GPIO_PODR_FECL_PODR_FECL4 (0x10) +#define MCF_GPIO_PODR_FECL_PODR_FECL5 (0x20) +#define MCF_GPIO_PODR_FECL_PODR_FECL6 (0x40) +#define MCF_GPIO_PODR_FECL_PODR_FECL7 (0x80) + +/* Bit definitions and macros for MCF_GPIO_PODR_SSI */ +#define MCF_GPIO_PODR_SSI_PODR_SSI0 (0x01) +#define MCF_GPIO_PODR_SSI_PODR_SSI1 (0x02) +#define MCF_GPIO_PODR_SSI_PODR_SSI2 (0x04) +#define MCF_GPIO_PODR_SSI_PODR_SSI3 (0x08) +#define MCF_GPIO_PODR_SSI_PODR_SSI4 (0x10) + +/* Bit definitions and macros for MCF_GPIO_PODR_BUSCTL */ +#define MCF_GPIO_PODR_BUSCTL_POSDR_BUSCTL0 (0x01) +#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL1 (0x02) +#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL2 (0x04) +#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL3 (0x08) + +/* Bit definitions and macros for MCF_GPIO_PODR_BE */ +#define MCF_GPIO_PODR_BE_PODR_BE0 (0x01) +#define MCF_GPIO_PODR_BE_PODR_BE1 (0x02) +#define MCF_GPIO_PODR_BE_PODR_BE2 (0x04) +#define MCF_GPIO_PODR_BE_PODR_BE3 (0x08) + +/* Bit definitions and macros for MCF_GPIO_PODR_CS */ +#define MCF_GPIO_PODR_CS_PODR_CS1 (0x02) +#define MCF_GPIO_PODR_CS_PODR_CS2 (0x04) +#define MCF_GPIO_PODR_CS_PODR_CS3 (0x08) +#define MCF_GPIO_PODR_CS_PODR_CS4 (0x10) +#define MCF_GPIO_PODR_CS_PODR_CS5 (0x20) + +/* Bit definitions and macros for MCF_GPIO_PODR_PWM */ +#define MCF_GPIO_PODR_PWM_PODR_PWM2 (0x04) +#define MCF_GPIO_PODR_PWM_PODR_PWM3 (0x08) +#define MCF_GPIO_PODR_PWM_PODR_PWM4 (0x10) +#define MCF_GPIO_PODR_PWM_PODR_PWM5 (0x20) + +/* Bit definitions and macros for MCF_GPIO_PODR_FECI2C */ +#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C0 (0x01) +#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C1 (0x02) +#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C2 (0x04) +#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C3 (0x08) + +/* Bit definitions and macros for MCF_GPIO_PODR_UART */ +#define MCF_GPIO_PODR_UART_PODR_UART0 (0x01) +#define MCF_GPIO_PODR_UART_PODR_UART1 (0x02) +#define MCF_GPIO_PODR_UART_PODR_UART2 (0x04) +#define MCF_GPIO_PODR_UART_PODR_UART3 (0x08) +#define MCF_GPIO_PODR_UART_PODR_UART4 (0x10) +#define MCF_GPIO_PODR_UART_PODR_UART5 (0x20) +#define MCF_GPIO_PODR_UART_PODR_UART6 (0x40) +#define MCF_GPIO_PODR_UART_PODR_UART7 (0x80) + +/* Bit definitions and macros for MCF_GPIO_PODR_QSPI */ +#define MCF_GPIO_PODR_QSPI_PODR_QSPI0 (0x01) +#define MCF_GPIO_PODR_QSPI_PODR_QSPI1 (0x02) +#define MCF_GPIO_PODR_QSPI_PODR_QSPI2 (0x04) +#define MCF_GPIO_PODR_QSPI_PODR_QSPI3 (0x08) +#define MCF_GPIO_PODR_QSPI_PODR_QSPI4 (0x10) +#define MCF_GPIO_PODR_QSPI_PODR_QSPI5 (0x20) + +/* Bit definitions and macros for MCF_GPIO_PODR_TIMER */ +#define MCF_GPIO_PODR_TIMER_PODR_TIMER0 (0x01) +#define MCF_GPIO_PODR_TIMER_PODR_TIMER1 (0x02) +#define MCF_GPIO_PODR_TIMER_PODR_TIMER2 (0x04) +#define MCF_GPIO_PODR_TIMER_PODR_TIMER3 (0x08) + +/* Bit definitions and macros for MCF_GPIO_PODR_LCDDATAH */ +#define MCF_GPIO_PODR_LCDDATAH_PODR_LCDDATAH0 (0x01) +#define MCF_GPIO_PODR_LCDDATAH_PODR_LCDDATAH1 (0x02) + +/* Bit definitions and macros for MCF_GPIO_PODR_LCDDATAM */ +#define MCF_GPIO_PODR_LCDDATAM_PODR_LCDDATAM0 (0x01) +#define MCF_GPIO_PODR_LCDDATAM_PODR_LCDDATAM1 (0x02) +#define MCF_GPIO_PODR_LCDDATAM_PODR_LCDDATAM2 (0x04) +#define MCF_GPIO_PODR_LCDDATAM_PODR_LCDDATAM3 (0x08) +#define MCF_GPIO_PODR_LCDDATAM_PODR_LCDDATAM4 (0x10) +#define MCF_GPIO_PODR_LCDDATAM_PODR_LCDDATAM5 (0x20) +#define MCF_GPIO_PODR_LCDDATAM_PODR_LCDDATAM6 (0x40) +#define MCF_GPIO_PODR_LCDDATAM_PODR_LCDDATAM7 (0x80) + +/* Bit definitions and macros for MCF_GPIO_PODR_LCDDATAL */ +#define MCF_GPIO_PODR_LCDDATAL_PODR_LCDDATAL0 (0x01) +#define MCF_GPIO_PODR_LCDDATAL_PODR_LCDDATAL1 (0x02) +#define MCF_GPIO_PODR_LCDDATAL_PODR_LCDDATAL2 (0x04) +#define MCF_GPIO_PODR_LCDDATAL_PODR_LCDDATAL3 (0x08) +#define MCF_GPIO_PODR_LCDDATAL_PODR_LCDDATAL4 (0x10) +#define MCF_GPIO_PODR_LCDDATAL_PODR_LCDDATAL5 (0x20) +#define MCF_GPIO_PODR_LCDDATAL_PODR_LCDDATAL6 (0x40) +#define MCF_GPIO_PODR_LCDDATAL_PODR_LCDDATAL7 (0x80) + +/* Bit definitions and macros for MCF_GPIO_PODR_LCDCTLH */ +#define MCF_GPIO_PODR_LCDCTLH_PODR_LCDCTLH0 (0x01) + +/* Bit definitions and macros for MCF_GPIO_PODR_LCDCTLL */ +#define MCF_GPIO_PODR_LCDCTLL_PODR_LCDCTLL0 (0x01) +#define MCF_GPIO_PODR_LCDCTLL_PODR_LCDCTLL1 (0x02) +#define MCF_GPIO_PODR_LCDCTLL_PODR_LCDCTLL2 (0x04) +#define MCF_GPIO_PODR_LCDCTLL_PODR_LCDCTLL3 (0x08) +#define MCF_GPIO_PODR_LCDCTLL_PODR_LCDCTLL4 (0x10) +#define MCF_GPIO_PODR_LCDCTLL_PODR_LCDCTLL5 (0x20) +#define MCF_GPIO_PODR_LCDCTLL_PODR_LCDCTLL6 (0x40) +#define MCF_GPIO_PODR_LCDCTLL_PODR_LCDCTLL7 (0x80) + +/* Bit definitions and macros for MCF_GPIO_PDDR_FECH */ +#define MCF_GPIO_PDDR_FECH_PDDR_FECH0 (0x01) +#define MCF_GPIO_PDDR_FECH_PDDR_FECH1 (0x02) +#define MCF_GPIO_PDDR_FECH_PDDR_FECH2 (0x04) +#define MCF_GPIO_PDDR_FECH_PDDR_FECH3 (0x08) +#define MCF_GPIO_PDDR_FECH_PDDR_FECH4 (0x10) +#define MCF_GPIO_PDDR_FECH_PDDR_FECH5 (0x20) +#define MCF_GPIO_PDDR_FECH_PDDR_FECH6 (0x40) +#define MCF_GPIO_PDDR_FECH_PDDR_FECH7 (0x80) + +/* Bit definitions and macros for MCF_GPIO_PDDR_FECL */ +#define MCF_GPIO_PDDR_FECL_PDDR_FECL0 (0x01) +#define MCF_GPIO_PDDR_FECL_PDDR_FECL1 (0x02) +#define MCF_GPIO_PDDR_FECL_PDDR_FECL2 (0x04) +#define MCF_GPIO_PDDR_FECL_PDDR_FECL3 (0x08) +#define MCF_GPIO_PDDR_FECL_PDDR_FECL4 (0x10) +#define MCF_GPIO_PDDR_FECL_PDDR_FECL5 (0x20) +#define MCF_GPIO_PDDR_FECL_PDDR_FECL6 (0x40) +#define MCF_GPIO_PDDR_FECL_PDDR_FECL7 (0x80) + +/* Bit definitions and macros for MCF_GPIO_PDDR_SSI */ +#define MCF_GPIO_PDDR_SSI_PDDR_SSI0 (0x01) +#define MCF_GPIO_PDDR_SSI_PDDR_SSI1 (0x02) +#define MCF_GPIO_PDDR_SSI_PDDR_SSI2 (0x04) +#define MCF_GPIO_PDDR_SSI_PDDR_SSI3 (0x08) +#define MCF_GPIO_PDDR_SSI_PDDR_SSI4 (0x10) + +/* Bit definitions and macros for MCF_GPIO_PDDR_BUSCTL */ +#define MCF_GPIO_PDDR_BUSCTL_POSDR_BUSCTL0 (0x01) +#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL1 (0x02) +#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL2 (0x04) +#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL3 (0x08) + +/* Bit definitions and macros for MCF_GPIO_PDDR_BE */ +#define MCF_GPIO_PDDR_BE_PDDR_BE0 (0x01) +#define MCF_GPIO_PDDR_BE_PDDR_BE1 (0x02) +#define MCF_GPIO_PDDR_BE_PDDR_BE2 (0x04) +#define MCF_GPIO_PDDR_BE_PDDR_BE3 (0x08) + +/* Bit definitions and macros for MCF_GPIO_PDDR_CS */ +#define MCF_GPIO_PDDR_CS_PDDR_CS1 (0x02) +#define MCF_GPIO_PDDR_CS_PDDR_CS2 (0x04) +#define MCF_GPIO_PDDR_CS_PDDR_CS3 (0x08) +#define MCF_GPIO_PDDR_CS_PDDR_CS4 (0x10) +#define MCF_GPIO_PDDR_CS_PDDR_CS5 (0x20) + +/* Bit definitions and macros for MCF_GPIO_PDDR_PWM */ +#define MCF_GPIO_PDDR_PWM_PDDR_PWM2 (0x04) +#define MCF_GPIO_PDDR_PWM_PDDR_PWM3 (0x08) +#define MCF_GPIO_PDDR_PWM_PDDR_PWM4 (0x10) +#define MCF_GPIO_PDDR_PWM_PDDR_PWM5 (0x20) + +/* Bit definitions and macros for MCF_GPIO_PDDR_FECI2C */ +#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C0 (0x01) +#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C1 (0x02) +#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C2 (0x04) +#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C3 (0x08) + +/* Bit definitions and macros for MCF_GPIO_PDDR_UART */ +#define MCF_GPIO_PDDR_UART_PDDR_UART0 (0x01) +#define MCF_GPIO_PDDR_UART_PDDR_UART1 (0x02) +#define MCF_GPIO_PDDR_UART_PDDR_UART2 (0x04) +#define MCF_GPIO_PDDR_UART_PDDR_UART3 (0x08) +#define MCF_GPIO_PDDR_UART_PDDR_UART4 (0x10) +#define MCF_GPIO_PDDR_UART_PDDR_UART5 (0x20) +#define MCF_GPIO_PDDR_UART_PDDR_UART6 (0x40) +#define MCF_GPIO_PDDR_UART_PDDR_UART7 (0x80) + +/* Bit definitions and macros for MCF_GPIO_PDDR_QSPI */ +#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI0 (0x01) +#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI1 (0x02) +#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI2 (0x04) +#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI3 (0x08) +#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI4 (0x10) +#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI5 (0x20) + +/* Bit definitions and macros for MCF_GPIO_PDDR_TIMER */ +#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER0 (0x01) +#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER1 (0x02) +#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER2 (0x04) +#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER3 (0x08) + +/* Bit definitions and macros for MCF_GPIO_PDDR_LCDDATAH */ +#define MCF_GPIO_PDDR_LCDDATAH_PDDR_LCDDATAH0 (0x01) +#define MCF_GPIO_PDDR_LCDDATAH_PDDR_LCDDATAH1 (0x02) + +/* Bit definitions and macros for MCF_GPIO_PDDR_LCDDATAM */ +#define MCF_GPIO_PDDR_LCDDATAM_PDDR_LCDDATAM0 (0x01) +#define MCF_GPIO_PDDR_LCDDATAM_PDDR_LCDDATAM1 (0x02) +#define MCF_GPIO_PDDR_LCDDATAM_PDDR_LCDDATAM2 (0x04) +#define MCF_GPIO_PDDR_LCDDATAM_PDDR_LCDDATAM3 (0x08) +#define MCF_GPIO_PDDR_LCDDATAM_PDDR_LCDDATAM4 (0x10) +#define MCF_GPIO_PDDR_LCDDATAM_PDDR_LCDDATAM5 (0x20) +#define MCF_GPIO_PDDR_LCDDATAM_PDDR_LCDDATAM6 (0x40) +#define MCF_GPIO_PDDR_LCDDATAM_PDDR_LCDDATAM7 (0x80) + +/* Bit definitions and macros for MCF_GPIO_PDDR_LCDDATAL */ +#define MCF_GPIO_PDDR_LCDDATAL_PDDR_LCDDATAL0 (0x01) +#define MCF_GPIO_PDDR_LCDDATAL_PDDR_LCDDATAL1 (0x02) +#define MCF_GPIO_PDDR_LCDDATAL_PDDR_LCDDATAL2 (0x04) +#define MCF_GPIO_PDDR_LCDDATAL_PDDR_LCDDATAL3 (0x08) +#define MCF_GPIO_PDDR_LCDDATAL_PDDR_LCDDATAL4 (0x10) +#define MCF_GPIO_PDDR_LCDDATAL_PDDR_LCDDATAL5 (0x20) +#define MCF_GPIO_PDDR_LCDDATAL_PDDR_LCDDATAL6 (0x40) +#define MCF_GPIO_PDDR_LCDDATAL_PDDR_LCDDATAL7 (0x80) + +/* Bit definitions and macros for MCF_GPIO_PDDR_LCDCTLH */ +#define MCF_GPIO_PDDR_LCDCTLH_PDDR_LCDCTLH0 (0x01) + +/* Bit definitions and macros for MCF_GPIO_PDDR_LCDCTLL */ +#define MCF_GPIO_PDDR_LCDCTLL_PDDR_LCDCTLL0 (0x01) +#define MCF_GPIO_PDDR_LCDCTLL_PDDR_LCDCTLL1 (0x02) +#define MCF_GPIO_PDDR_LCDCTLL_PDDR_LCDCTLL2 (0x04) +#define MCF_GPIO_PDDR_LCDCTLL_PDDR_LCDCTLL3 (0x08) +#define MCF_GPIO_PDDR_LCDCTLL_PDDR_LCDCTLL4 (0x10) +#define MCF_GPIO_PDDR_LCDCTLL_PDDR_LCDCTLL5 (0x20) +#define MCF_GPIO_PDDR_LCDCTLL_PDDR_LCDCTLL6 (0x40) +#define MCF_GPIO_PDDR_LCDCTLL_PDDR_LCDCTLL7 (0x80) + +/* Bit definitions and macros for MCF_GPIO_PPDSDR_FECH */ +#define MCF_GPIO_PPDSDR_FECH_PPDSDR_FECH0 (0x01) +#define MCF_GPIO_PPDSDR_FECH_PPDSDR_FECH1 (0x02) +#define MCF_GPIO_PPDSDR_FECH_PPDSDR_FECH2 (0x04) +#define MCF_GPIO_PPDSDR_FECH_PPDSDR_FECH3 (0x08) +#define MCF_GPIO_PPDSDR_FECH_PPDSDR_FECH4 (0x10) +#define MCF_GPIO_PPDSDR_FECH_PPDSDR_FECH5 (0x20) +#define MCF_GPIO_PPDSDR_FECH_PPDSDR_FECH6 (0x40) +#define MCF_GPIO_PPDSDR_FECH_PPDSDR_FECH7 (0x80) + +/* Bit definitions and macros for MCF_GPIO_PPDSDR_FECL */ +#define MCF_GPIO_PPDSDR_FECL_PPDSDR_FECL0 (0x01) +#define MCF_GPIO_PPDSDR_FECL_PPDSDR_FECL1 (0x02) +#define MCF_GPIO_PPDSDR_FECL_PPDSDR_FECL2 (0x04) +#define MCF_GPIO_PPDSDR_FECL_PPDSDR_FECL3 (0x08) +#define MCF_GPIO_PPDSDR_FECL_PPDSDR_FECL4 (0x10) +#define MCF_GPIO_PPDSDR_FECL_PPDSDR_FECL5 (0x20) +#define MCF_GPIO_PPDSDR_FECL_PPDSDR_FECL6 (0x40) +#define MCF_GPIO_PPDSDR_FECL_PPDSDR_FECL7 (0x80) + +/* Bit definitions and macros for MCF_GPIO_PPDSDR_SSI */ +#define MCF_GPIO_PPDSDR_SSI_PPDSDR_SSI0 (0x01) +#define MCF_GPIO_PPDSDR_SSI_PPDSDR_SSI1 (0x02) +#define MCF_GPIO_PPDSDR_SSI_PPDSDR_SSI2 (0x04) +#define MCF_GPIO_PPDSDR_SSI_PPDSDR_SSI3 (0x08) +#define MCF_GPIO_PPDSDR_SSI_PPDSDR_SSI4 (0x10) + +/* Bit definitions and macros for MCF_GPIO_PPDSDR_BUSCTL */ +#define MCF_GPIO_PPDSDR_BUSCTL_POSDR_BUSCTL0 (0x01) +#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL1 (0x02) +#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL2 (0x04) +#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL3 (0x08) + +/* Bit definitions and macros for MCF_GPIO_PPDSDR_BE */ +#define MCF_GPIO_PPDSDR_BE_PPDSDR_BE0 (0x01) +#define MCF_GPIO_PPDSDR_BE_PPDSDR_BE1 (0x02) +#define MCF_GPIO_PPDSDR_BE_PPDSDR_BE2 (0x04) +#define MCF_GPIO_PPDSDR_BE_PPDSDR_BE3 (0x08) + +/* Bit definitions and macros for MCF_GPIO_PPDSDR_CS */ +#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS1 (0x02) +#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS2 (0x04) +#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS3 (0x08) +#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS4 (0x10) +#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS5 (0x20) + +/* Bit definitions and macros for MCF_GPIO_PPDSDR_PWM */ +#define MCF_GPIO_PPDSDR_PWM_PPDSDR_PWM2 (0x04) +#define MCF_GPIO_PPDSDR_PWM_PPDSDR_PWM3 (0x08) +#define MCF_GPIO_PPDSDR_PWM_PPDSDR_PWM4 (0x10) +#define MCF_GPIO_PPDSDR_PWM_PPDSDR_PWM5 (0x20) + +/* Bit definitions and macros for MCF_GPIO_PPDSDR_FECI2C */ +#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C0 (0x01) +#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C1 (0x02) +#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C2 (0x04) +#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C3 (0x08) + +/* Bit definitions and macros for MCF_GPIO_PPDSDR_UART */ +#define MCF_GPIO_PPDSDR_UART_PPDSDR_UART0 (0x01) +#define MCF_GPIO_PPDSDR_UART_PPDSDR_UART1 (0x02) +#define MCF_GPIO_PPDSDR_UART_PPDSDR_UART2 (0x04) +#define MCF_GPIO_PPDSDR_UART_PPDSDR_UART3 (0x08) +#define MCF_GPIO_PPDSDR_UART_PPDSDR_UART4 (0x10) +#define MCF_GPIO_PPDSDR_UART_PPDSDR_UART5 (0x20) +#define MCF_GPIO_PPDSDR_UART_PPDSDR_UART6 (0x40) +#define MCF_GPIO_PPDSDR_UART_PPDSDR_UART7 (0x80) + +/* Bit definitions and macros for MCF_GPIO_PPDSDR_QSPI */ +#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI0 (0x01) +#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI1 (0x02) +#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI2 (0x04) +#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI3 (0x08) +#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI4 (0x10) +#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI5 (0x20) + +/* Bit definitions and macros for MCF_GPIO_PPDSDR_TIMER */ +#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER0 (0x01) +#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER1 (0x02) +#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER2 (0x04) +#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER3 (0x08) + +/* Bit definitions and macros for MCF_GPIO_PPDSDR_LCDDATAH */ +#define MCF_GPIO_PPDSDR_LCDDATAH_PPDSDR_LCDDATAH0 (0x01) +#define MCF_GPIO_PPDSDR_LCDDATAH_PPDSDR_LCDDATAH1 (0x02) + +/* Bit definitions and macros for MCF_GPIO_PPDSDR_LCDDATAM */ +#define MCF_GPIO_PPDSDR_LCDDATAM_PPDSDR_LCDDATAM0 (0x01) +#define MCF_GPIO_PPDSDR_LCDDATAM_PPDSDR_LCDDATAM1 (0x02) +#define MCF_GPIO_PPDSDR_LCDDATAM_PPDSDR_LCDDATAM2 (0x04) +#define MCF_GPIO_PPDSDR_LCDDATAM_PPDSDR_LCDDATAM3 (0x08) +#define MCF_GPIO_PPDSDR_LCDDATAM_PPDSDR_LCDDATAM4 (0x10) +#define MCF_GPIO_PPDSDR_LCDDATAM_PPDSDR_LCDDATAM5 (0x20) +#define MCF_GPIO_PPDSDR_LCDDATAM_PPDSDR_LCDDATAM6 (0x40) +#define MCF_GPIO_PPDSDR_LCDDATAM_PPDSDR_LCDDATAM7 (0x80) + +/* Bit definitions and macros for MCF_GPIO_PPDSDR_LCDDATAL */ +#define MCF_GPIO_PPDSDR_LCDDATAL_PPDSDR_LCDDATAL0 (0x01) +#define MCF_GPIO_PPDSDR_LCDDATAL_PPDSDR_LCDDATAL1 (0x02) +#define MCF_GPIO_PPDSDR_LCDDATAL_PPDSDR_LCDDATAL2 (0x04) +#define MCF_GPIO_PPDSDR_LCDDATAL_PPDSDR_LCDDATAL3 (0x08) +#define MCF_GPIO_PPDSDR_LCDDATAL_PPDSDR_LCDDATAL4 (0x10) +#define MCF_GPIO_PPDSDR_LCDDATAL_PPDSDR_LCDDATAL5 (0x20) +#define MCF_GPIO_PPDSDR_LCDDATAL_PPDSDR_LCDDATAL6 (0x40) +#define MCF_GPIO_PPDSDR_LCDDATAL_PPDSDR_LCDDATAL7 (0x80) + +/* Bit definitions and macros for MCF_GPIO_PPDSDR_LCDCTLH */ +#define MCF_GPIO_PPDSDR_LCDCTLH_PPDSDR_LCDCTLH0 (0x01) + +/* Bit definitions and macros for MCF_GPIO_PPDSDR_LCDCTLL */ +#define MCF_GPIO_PPDSDR_LCDCTLL_PPDSDR_LCDCTLL0 (0x01) +#define MCF_GPIO_PPDSDR_LCDCTLL_PPDSDR_LCDCTLL1 (0x02) +#define MCF_GPIO_PPDSDR_LCDCTLL_PPDSDR_LCDCTLL2 (0x04) +#define MCF_GPIO_PPDSDR_LCDCTLL_PPDSDR_LCDCTLL3 (0x08) +#define MCF_GPIO_PPDSDR_LCDCTLL_PPDSDR_LCDCTLL4 (0x10) +#define MCF_GPIO_PPDSDR_LCDCTLL_PPDSDR_LCDCTLL5 (0x20) +#define MCF_GPIO_PPDSDR_LCDCTLL_PPDSDR_LCDCTLL6 (0x40) +#define MCF_GPIO_PPDSDR_LCDCTLL_PPDSDR_LCDCTLL7 (0x80) + +/* Bit definitions and macros for MCF_GPIO_PCLRR_FECH */ +#define MCF_GPIO_PCLRR_FECH_PCLRR_FECH0 (0x01) +#define MCF_GPIO_PCLRR_FECH_PCLRR_FECH1 (0x02) +#define MCF_GPIO_PCLRR_FECH_PCLRR_FECH2 (0x04) +#define MCF_GPIO_PCLRR_FECH_PCLRR_FECH3 (0x08) +#define MCF_GPIO_PCLRR_FECH_PCLRR_FECH4 (0x10) +#define MCF_GPIO_PCLRR_FECH_PCLRR_FECH5 (0x20) +#define MCF_GPIO_PCLRR_FECH_PCLRR_FECH6 (0x40) +#define MCF_GPIO_PCLRR_FECH_PCLRR_FECH7 (0x80) + +/* Bit definitions and macros for MCF_GPIO_PCLRR_FECL */ +#define MCF_GPIO_PCLRR_FECL_PCLRR_FECL0 (0x01) +#define MCF_GPIO_PCLRR_FECL_PCLRR_FECL1 (0x02) +#define MCF_GPIO_PCLRR_FECL_PCLRR_FECL2 (0x04) +#define MCF_GPIO_PCLRR_FECL_PCLRR_FECL3 (0x08) +#define MCF_GPIO_PCLRR_FECL_PCLRR_FECL4 (0x10) +#define MCF_GPIO_PCLRR_FECL_PCLRR_FECL5 (0x20) +#define MCF_GPIO_PCLRR_FECL_PCLRR_FECL6 (0x40) +#define MCF_GPIO_PCLRR_FECL_PCLRR_FECL7 (0x80) + +/* Bit definitions and macros for MCF_GPIO_PCLRR_SSI */ +#define MCF_GPIO_PCLRR_SSI_PCLRR_SSI0 (0x01) +#define MCF_GPIO_PCLRR_SSI_PCLRR_SSI1 (0x02) +#define MCF_GPIO_PCLRR_SSI_PCLRR_SSI2 (0x04) +#define MCF_GPIO_PCLRR_SSI_PCLRR_SSI3 (0x08) +#define MCF_GPIO_PCLRR_SSI_PCLRR_SSI4 (0x10) + +/* Bit definitions and macros for MCF_GPIO_PCLRR_BUSCTL */ +#define MCF_GPIO_PCLRR_BUSCTL_POSDR_BUSCTL0 (0x01) +#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL1 (0x02) +#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL2 (0x04) +#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL3 (0x08) + +/* Bit definitions and macros for MCF_GPIO_PCLRR_BE */ +#define MCF_GPIO_PCLRR_BE_PCLRR_BE0 (0x01) +#define MCF_GPIO_PCLRR_BE_PCLRR_BE1 (0x02) +#define MCF_GPIO_PCLRR_BE_PCLRR_BE2 (0x04) +#define MCF_GPIO_PCLRR_BE_PCLRR_BE3 (0x08) + +/* Bit definitions and macros for MCF_GPIO_PCLRR_CS */ +#define MCF_GPIO_PCLRR_CS_PCLRR_CS1 (0x02) +#define MCF_GPIO_PCLRR_CS_PCLRR_CS2 (0x04) +#define MCF_GPIO_PCLRR_CS_PCLRR_CS3 (0x08) +#define MCF_GPIO_PCLRR_CS_PCLRR_CS4 (0x10) +#define MCF_GPIO_PCLRR_CS_PCLRR_CS5 (0x20) + +/* Bit definitions and macros for MCF_GPIO_PCLRR_PWM */ +#define MCF_GPIO_PCLRR_PWM_PCLRR_PWM2 (0x04) +#define MCF_GPIO_PCLRR_PWM_PCLRR_PWM3 (0x08) +#define MCF_GPIO_PCLRR_PWM_PCLRR_PWM4 (0x10) +#define MCF_GPIO_PCLRR_PWM_PCLRR_PWM5 (0x20) + +/* Bit definitions and macros for MCF_GPIO_PCLRR_FECI2C */ +#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C0 (0x01) +#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C1 (0x02) +#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C2 (0x04) +#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C3 (0x08) + +/* Bit definitions and macros for MCF_GPIO_PCLRR_UART */ +#define MCF_GPIO_PCLRR_UART_PCLRR_UART0 (0x01) +#define MCF_GPIO_PCLRR_UART_PCLRR_UART1 (0x02) +#define MCF_GPIO_PCLRR_UART_PCLRR_UART2 (0x04) +#define MCF_GPIO_PCLRR_UART_PCLRR_UART3 (0x08) +#define MCF_GPIO_PCLRR_UART_PCLRR_UART4 (0x10) +#define MCF_GPIO_PCLRR_UART_PCLRR_UART5 (0x20) +#define MCF_GPIO_PCLRR_UART_PCLRR_UART6 (0x40) +#define MCF_GPIO_PCLRR_UART_PCLRR_UART7 (0x80) + +/* Bit definitions and macros for MCF_GPIO_PCLRR_QSPI */ +#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI0 (0x01) +#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI1 (0x02) +#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI2 (0x04) +#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI3 (0x08) +#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI4 (0x10) +#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI5 (0x20) + +/* Bit definitions and macros for MCF_GPIO_PCLRR_TIMER */ +#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER0 (0x01) +#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER1 (0x02) +#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER2 (0x04) +#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER3 (0x08) + +/* Bit definitions and macros for MCF_GPIO_PCLRR_LCDDATAH */ +#define MCF_GPIO_PCLRR_LCDDATAH_PCLRR_LCDDATAH0 (0x01) +#define MCF_GPIO_PCLRR_LCDDATAH_PCLRR_LCDDATAH1 (0x02) + +/* Bit definitions and macros for MCF_GPIO_PCLRR_LCDDATAM */ +#define MCF_GPIO_PCLRR_LCDDATAM_PCLRR_LCDDATAM0 (0x01) +#define MCF_GPIO_PCLRR_LCDDATAM_PCLRR_LCDDATAM1 (0x02) +#define MCF_GPIO_PCLRR_LCDDATAM_PCLRR_LCDDATAM2 (0x04) +#define MCF_GPIO_PCLRR_LCDDATAM_PCLRR_LCDDATAM3 (0x08) +#define MCF_GPIO_PCLRR_LCDDATAM_PCLRR_LCDDATAM4 (0x10) +#define MCF_GPIO_PCLRR_LCDDATAM_PCLRR_LCDDATAM5 (0x20) +#define MCF_GPIO_PCLRR_LCDDATAM_PCLRR_LCDDATAM6 (0x40) +#define MCF_GPIO_PCLRR_LCDDATAM_PCLRR_LCDDATAM7 (0x80) + +/* Bit definitions and macros for MCF_GPIO_PCLRR_LCDDATAL */ +#define MCF_GPIO_PCLRR_LCDDATAL_PCLRR_LCDDATAL0 (0x01) +#define MCF_GPIO_PCLRR_LCDDATAL_PCLRR_LCDDATAL1 (0x02) +#define MCF_GPIO_PCLRR_LCDDATAL_PCLRR_LCDDATAL2 (0x04) +#define MCF_GPIO_PCLRR_LCDDATAL_PCLRR_LCDDATAL3 (0x08) +#define MCF_GPIO_PCLRR_LCDDATAL_PCLRR_LCDDATAL4 (0x10) +#define MCF_GPIO_PCLRR_LCDDATAL_PCLRR_LCDDATAL5 (0x20) +#define MCF_GPIO_PCLRR_LCDDATAL_PCLRR_LCDDATAL6 (0x40) +#define MCF_GPIO_PCLRR_LCDDATAL_PCLRR_LCDDATAL7 (0x80) + +/* Bit definitions and macros for MCF_GPIO_PCLRR_LCDCTLH */ +#define MCF_GPIO_PCLRR_LCDCTLH_PCLRR_LCDCTLH0 (0x01) + +/* Bit definitions and macros for MCF_GPIO_PCLRR_LCDCTLL */ +#define MCF_GPIO_PCLRR_LCDCTLL_PCLRR_LCDCTLL0 (0x01) +#define MCF_GPIO_PCLRR_LCDCTLL_PCLRR_LCDCTLL1 (0x02) +#define MCF_GPIO_PCLRR_LCDCTLL_PCLRR_LCDCTLL2 (0x04) +#define MCF_GPIO_PCLRR_LCDCTLL_PCLRR_LCDCTLL3 (0x08) +#define MCF_GPIO_PCLRR_LCDCTLL_PCLRR_LCDCTLL4 (0x10) +#define MCF_GPIO_PCLRR_LCDCTLL_PCLRR_LCDCTLL5 (0x20) +#define MCF_GPIO_PCLRR_LCDCTLL_PCLRR_LCDCTLL6 (0x40) +#define MCF_GPIO_PCLRR_LCDCTLL_PCLRR_LCDCTLL7 (0x80) + +/* Bit definitions and macros for MCF_GPIO_PAR_FEC */ +#define MCF_GPIO_PAR_FEC_PAR_FEC_MII(x) (((x)&0x03)<<0) +#define MCF_GPIO_PAR_FEC_PAR_FEC_7W(x) (((x)&0x03)<<2) +#define MCF_GPIO_PAR_FEC_PAR_FEC_7W_GPIO (0x00) +#define MCF_GPIO_PAR_FEC_PAR_FEC_7W_URTS1 (0x04) +#define MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC (0x0C) +#define MCF_GPIO_PAR_FEC_PAR_FEC_MII_GPIO (0x00) +#define MCF_GPIO_PAR_FEC_PAR_FEC_MII_UART (0x01) +#define MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC (0x03) + +/* Bit definitions and macros for MCF_GPIO_PAR_PWM */ +#define MCF_GPIO_PAR_PWM_PAR_PWM1(x) (((x)&0x03)<<0) +#define MCF_GPIO_PAR_PWM_PAR_PWM3(x) (((x)&0x03)<<2) +#define MCF_GPIO_PAR_PWM_PAR_PWM5 (0x10) +#define MCF_GPIO_PAR_PWM_PAR_PWM7 (0x20) + +/* Bit definitions and macros for MCF_GPIO_PAR_BUSCTL */ +#define MCF_GPIO_PAR_BUSCTL_PAR_TS(x) (((x)&0x03)<<3) +#define MCF_GPIO_PAR_BUSCTL_PAR_RWB (0x20) +#define MCF_GPIO_PAR_BUSCTL_PAR_TA (0x40) +#define MCF_GPIO_PAR_BUSCTL_PAR_OE (0x80) +#define MCF_GPIO_PAR_BUSCTL_PAR_OE_GPIO (0x00) +#define MCF_GPIO_PAR_BUSCTL_PAR_OE_OE (0x80) +#define MCF_GPIO_PAR_BUSCTL_PAR_TA_GPIO (0x00) +#define MCF_GPIO_PAR_BUSCTL_PAR_TA_TA (0x40) +#define MCF_GPIO_PAR_BUSCTL_PAR_RWB_GPIO (0x00) +#define MCF_GPIO_PAR_BUSCTL_PAR_RWB_RWB (0x20) +#define MCF_GPIO_PAR_BUSCTL_PAR_TS_GPIO (0x00) +#define MCF_GPIO_PAR_BUSCTL_PAR_TS_DACK0 (0x10) +#define MCF_GPIO_PAR_BUSCTL_PAR_TS_TS (0x18) + +/* Bit definitions and macros for MCF_GPIO_PAR_FECI2C */ +#define MCF_GPIO_PAR_FECI2C_PAR_SDA(x) (((x)&0x03)<<0) +#define MCF_GPIO_PAR_FECI2C_PAR_SCL(x) (((x)&0x03)<<2) +#define MCF_GPIO_PAR_FECI2C_PAR_MDIO(x) (((x)&0x03)<<4) +#define MCF_GPIO_PAR_FECI2C_PAR_MDC(x) (((x)&0x03)<<6) +#define MCF_GPIO_PAR_FECI2C_PAR_MDC_GPIO (0x00) +#define MCF_GPIO_PAR_FECI2C_PAR_MDC_UTXD2 (0x40) +#define MCF_GPIO_PAR_FECI2C_PAR_MDC_SCL (0x80) +#define MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC (0xC0) +#define MCF_GPIO_PAR_FECI2C_PAR_MDIO_GPIO (0x00) +#define MCF_GPIO_PAR_FECI2C_PAR_MDIO_URXD2 (0x10) +#define MCF_GPIO_PAR_FECI2C_PAR_MDIO_SDA (0x20) +#define MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO (0x30) +#define MCF_GPIO_PAR_FECI2C_PAR_SCL_GPIO (0x00) +#define MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2 (0x04) +#define MCF_GPIO_PAR_FECI2C_PAR_SCL_SCL (0x0C) +#define MCF_GPIO_PAR_FECI2C_PAR_SDA_GPIO (0x00) +#define MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2 (0x02) +#define MCF_GPIO_PAR_FECI2C_PAR_SDA_SDA (0x03) + +/* Bit definitions and macros for MCF_GPIO_PAR_BE */ +#define MCF_GPIO_PAR_BE_PAR_BE0 (0x01) +#define MCF_GPIO_PAR_BE_PAR_BE1 (0x02) +#define MCF_GPIO_PAR_BE_PAR_BE2 (0x04) +#define MCF_GPIO_PAR_BE_PAR_BE3 (0x08) + +/* Bit definitions and macros for MCF_GPIO_PAR_CS */ +#define MCF_GPIO_PAR_CS_PAR_CS1 (0x02) +#define MCF_GPIO_PAR_CS_PAR_CS2 (0x04) +#define MCF_GPIO_PAR_CS_PAR_CS3 (0x08) +#define MCF_GPIO_PAR_CS_PAR_CS4 (0x10) +#define MCF_GPIO_PAR_CS_PAR_CS5 (0x20) +#define MCF_GPIO_PAR_CS_PAR_CS_CS1_GPIO (0x00) +#define MCF_GPIO_PAR_CS_PAR_CS_CS1_SDCS1 (0x01) +#define MCF_GPIO_PAR_CS_PAR_CS_CS1_CS1 (0x03) + +/* Bit definitions and macros for MCF_GPIO_PAR_SSI */ +#define MCF_GPIO_PAR_SSI_PAR_MCLK (0x0080) +#define MCF_GPIO_PAR_SSI_PAR_TXD(x) (((x)&0x0003)<<8) +#define MCF_GPIO_PAR_SSI_PAR_RXD(x) (((x)&0x0003)<<10) +#define MCF_GPIO_PAR_SSI_PAR_FS(x) (((x)&0x0003)<<12) +#define MCF_GPIO_PAR_SSI_PAR_BCLK(x) (((x)&0x0003)<<14) + +/* Bit definitions and macros for MCF_GPIO_PAR_UART */ +#define MCF_GPIO_PAR_UART_PAR_UTXD0 (0x0001) +#define MCF_GPIO_PAR_UART_PAR_URXD0 (0x0002) +#define MCF_GPIO_PAR_UART_PAR_URTS0 (0x0004) +#define MCF_GPIO_PAR_UART_PAR_UCTS0 (0x0008) +#define MCF_GPIO_PAR_UART_PAR_UTXD1(x) (((x)&0x0003)<<4) +#define MCF_GPIO_PAR_UART_PAR_URXD1(x) (((x)&0x0003)<<6) +#define MCF_GPIO_PAR_UART_PAR_URTS1(x) (((x)&0x0003)<<8) +#define MCF_GPIO_PAR_UART_PAR_UCTS1(x) (((x)&0x0003)<<10) +#define MCF_GPIO_PAR_UART_PAR_UCTS1_GPIO (0x0000) +#define MCF_GPIO_PAR_UART_PAR_UCTS1_SSI_BCLK (0x0800) +#define MCF_GPIO_PAR_UART_PAR_UCTS1_ULPI_D7 (0x0400) +#define MCF_GPIO_PAR_UART_PAR_UCTS1_UCTS1 (0x0C00) +#define MCF_GPIO_PAR_UART_PAR_URTS1_GPIO (0x0000) +#define MCF_GPIO_PAR_UART_PAR_URTS1_SSI_FS (0x0200) +#define MCF_GPIO_PAR_UART_PAR_URTS1_ULPI_D6 (0x0100) +#define MCF_GPIO_PAR_UART_PAR_URTS1_URTS1 (0x0300) +#define MCF_GPIO_PAR_UART_PAR_URXD1_GPIO (0x0000) +#define MCF_GPIO_PAR_UART_PAR_URXD1_SSI_RXD (0x0080) +#define MCF_GPIO_PAR_UART_PAR_URXD1_ULPI_D5 (0x0040) +#define MCF_GPIO_PAR_UART_PAR_URXD1_URXD1 (0x00C0) +#define MCF_GPIO_PAR_UART_PAR_UTXD1_GPIO (0x0000) +#define MCF_GPIO_PAR_UART_PAR_UTXD1_SSI_TXD (0x0020) +#define MCF_GPIO_PAR_UART_PAR_UTXD1_ULPI_D4 (0x0010) +#define MCF_GPIO_PAR_UART_PAR_UTXD1_UTXD1 (0x0030) + +/* Bit definitions and macros for MCF_GPIO_PAR_QSPI */ +#define MCF_GPIO_PAR_QSPI_PAR_SCK(x) (((x)&0x0003)<<4) +#define MCF_GPIO_PAR_QSPI_PAR_DOUT(x) (((x)&0x0003)<<6) +#define MCF_GPIO_PAR_QSPI_PAR_DIN(x) (((x)&0x0003)<<8) +#define MCF_GPIO_PAR_QSPI_PAR_PCS0(x) (((x)&0x0003)<<10) +#define MCF_GPIO_PAR_QSPI_PAR_PCS1(x) (((x)&0x0003)<<12) +#define MCF_GPIO_PAR_QSPI_PAR_PCS2(x) (((x)&0x0003)<<14) + +/* Bit definitions and macros for MCF_GPIO_PAR_TIMER */ +#define MCF_GPIO_PAR_TIMER_PAR_TIN0(x) (((x)&0x03)<<0) +#define MCF_GPIO_PAR_TIMER_PAR_TIN1(x) (((x)&0x03)<<2) +#define MCF_GPIO_PAR_TIMER_PAR_TIN2(x) (((x)&0x03)<<4) +#define MCF_GPIO_PAR_TIMER_PAR_TIN3(x) (((x)&0x03)<<6) +#define MCF_GPIO_PAR_TIMER_PAR_TIN3_GPIO (0x00) +#define MCF_GPIO_PAR_TIMER_PAR_TIN3_TOUT3 (0x80) +#define MCF_GPIO_PAR_TIMER_PAR_TIN3_URXD2 (0x40) +#define MCF_GPIO_PAR_TIMER_PAR_TIN3_TIN3 (0xC0) +#define MCF_GPIO_PAR_TIMER_PAR_TIN2_GPIO (0x00) +#define MCF_GPIO_PAR_TIMER_PAR_TIN2_TOUT2 (0x20) +#define MCF_GPIO_PAR_TIMER_PAR_TIN2_UTXD2 (0x10) +#define MCF_GPIO_PAR_TIMER_PAR_TIN2_TIN2 (0x30) +#define MCF_GPIO_PAR_TIMER_PAR_TIN1_GPIO (0x00) +#define MCF_GPIO_PAR_TIMER_PAR_TIN1_TOUT1 (0x08) +#define MCF_GPIO_PAR_TIMER_PAR_TIN1_DACK1 (0x04) +#define MCF_GPIO_PAR_TIMER_PAR_TIN1_TIN1 (0x0C) +#define MCF_GPIO_PAR_TIMER_PAR_TIN0_GPIO (0x00) +#define MCF_GPIO_PAR_TIMER_PAR_TIN0_TOUT0 (0x02) +#define MCF_GPIO_PAR_TIMER_PAR_TIN0_DREQ0 (0x01) +#define MCF_GPIO_PAR_TIMER_PAR_TIN0_TIN0 (0x03) + +/* Bit definitions and macros for MCF_GPIO_PAR_LCDDATA */ +#define MCF_GPIO_PAR_LCDDATA_PAR_LD7_0(x) (((x)&0x03)<<0) +#define MCF_GPIO_PAR_LCDDATA_PAR_LD15_8(x) (((x)&0x03)<<2) +#define MCF_GPIO_PAR_LCDDATA_PAR_LD16(x) (((x)&0x03)<<4) +#define MCF_GPIO_PAR_LCDDATA_PAR_LD17(x) (((x)&0x03)<<6) + +/* Bit definitions and macros for MCF_GPIO_PAR_LCDCTL */ +#define MCF_GPIO_PAR_LCDCTL_PAR_CLS (0x0001) +#define MCF_GPIO_PAR_LCDCTL_PAR_PS (0x0002) +#define MCF_GPIO_PAR_LCDCTL_PAR_REV (0x0004) +#define MCF_GPIO_PAR_LCDCTL_PAR_SPL_SPR (0x0008) +#define MCF_GPIO_PAR_LCDCTL_PAR_CONTRAST (0x0010) +#define MCF_GPIO_PAR_LCDCTL_PAR_LSCLK (0x0020) +#define MCF_GPIO_PAR_LCDCTL_PAR_LP_HSYNC (0x0040) +#define MCF_GPIO_PAR_LCDCTL_PAR_FLM_VSYNC (0x0080) +#define MCF_GPIO_PAR_LCDCTL_PAR_ACD_OE (0x0100) + +/* Bit definitions and macros for MCF_GPIO_PAR_IRQ */ +#define MCF_GPIO_PAR_IRQ_PAR_IRQ1(x) (((x)&0x0003)<<4) +#define MCF_GPIO_PAR_IRQ_PAR_IRQ2(x) (((x)&0x0003)<<6) +#define MCF_GPIO_PAR_IRQ_PAR_IRQ4(x) (((x)&0x0003)<<8) +#define MCF_GPIO_PAR_IRQ_PAR_IRQ5(x) (((x)&0x0003)<<10) +#define MCF_GPIO_PAR_IRQ_PAR_IRQ6(x) (((x)&0x0003)<<12) + +/* Bit definitions and macros for MCF_GPIO_MSCR_FLEXBUS */ +#define MCF_GPIO_MSCR_FLEXBUS_MSCR_ADDRCTL(x) (((x)&0x03)<<0) +#define MCF_GPIO_MSCR_FLEXBUS_MSCR_DLOWER(x) (((x)&0x03)<<2) +#define MCF_GPIO_MSCR_FLEXBUS_MSCR_DUPPER(x) (((x)&0x03)<<4) + +/* Bit definitions and macros for MCF_GPIO_MSCR_SDRAM */ +#define MCF_GPIO_MSCR_SDRAM_MSCR_SDRAM(x) (((x)&0x03)<<0) +#define MCF_GPIO_MSCR_SDRAM_MSCR_SDCLK(x) (((x)&0x03)<<2) +#define MCF_GPIO_MSCR_SDRAM_MSCR_SDCLKB(x) (((x)&0x03)<<4) + +/* Bit definitions and macros for MCF_GPIO_DSCR_I2C */ +#define MCF_GPIO_DSCR_I2C_I2C_DSE(x) (((x)&0x03)<<0) + +/* Bit definitions and macros for MCF_GPIO_DSCR_PWM */ +#define MCF_GPIO_DSCR_PWM_PWM_DSE(x) (((x)&0x03)<<0) + +/* Bit definitions and macros for MCF_GPIO_DSCR_FEC */ +#define MCF_GPIO_DSCR_FEC_FEC_DSE(x) (((x)&0x03)<<0) + +/* Bit definitions and macros for MCF_GPIO_DSCR_UART */ +#define MCF_GPIO_DSCR_UART_UART0_DSE(x) (((x)&0x03)<<0) +#define MCF_GPIO_DSCR_UART_UART1_DSE(x) (((x)&0x03)<<2) + +/* Bit definitions and macros for MCF_GPIO_DSCR_QSPI */ +#define MCF_GPIO_DSCR_QSPI_QSPI_DSE(x) (((x)&0x03)<<0) + +/* Bit definitions and macros for MCF_GPIO_DSCR_TIMER */ +#define MCF_GPIO_DSCR_TIMER_TIMER_DSE(x) (((x)&0x03)<<0) + +/* Bit definitions and macros for MCF_GPIO_DSCR_SSI */ +#define MCF_GPIO_DSCR_SSI_SSI_DSE(x) (((x)&0x03)<<0) + +/* Bit definitions and macros for MCF_GPIO_DSCR_LCD */ +#define MCF_GPIO_DSCR_LCD_LCD_DSE(x) (((x)&0x03)<<0) + +/* Bit definitions and macros for MCF_GPIO_DSCR_DEBUG */ +#define MCF_GPIO_DSCR_DEBUG_DEBUG_DSE(x) (((x)&0x03)<<0) + +/* Bit definitions and macros for MCF_GPIO_DSCR_CLKRST */ +#define MCF_GPIO_DSCR_CLKRST_CLKRST_DSE(x) (((x)&0x03)<<0) + +/* Bit definitions and macros for MCF_GPIO_DSCR_IRQ */ +#define MCF_GPIO_DSCR_IRQ_IRQ_DSE(x) (((x)&0x03)<<0) + +/********************************************************************* + * + * Interrupt Controller (INTC) + * + *********************************************************************/ + +/* Register read/write macros */ +#define MCF_INTC0_IPRH MCF_REG32(0xFC048000) +#define MCF_INTC0_IPRL MCF_REG32(0xFC048004) +#define MCF_INTC0_IMRH MCF_REG32(0xFC048008) +#define MCF_INTC0_IMRL MCF_REG32(0xFC04800C) +#define MCF_INTC0_INTFRCH MCF_REG32(0xFC048010) +#define MCF_INTC0_INTFRCL MCF_REG32(0xFC048014) +#define MCF_INTC0_ICONFIG MCF_REG16(0xFC04801A) +#define MCF_INTC0_SIMR MCF_REG08(0xFC04801C) +#define MCF_INTC0_CIMR MCF_REG08(0xFC04801D) +#define MCF_INTC0_CLMASK MCF_REG08(0xFC04801E) +#define MCF_INTC0_SLMASK MCF_REG08(0xFC04801F) +#define MCF_INTC0_ICR0 MCF_REG08(0xFC048040) +#define MCF_INTC0_ICR1 MCF_REG08(0xFC048041) +#define MCF_INTC0_ICR2 MCF_REG08(0xFC048042) +#define MCF_INTC0_ICR3 MCF_REG08(0xFC048043) +#define MCF_INTC0_ICR4 MCF_REG08(0xFC048044) +#define MCF_INTC0_ICR5 MCF_REG08(0xFC048045) +#define MCF_INTC0_ICR6 MCF_REG08(0xFC048046) +#define MCF_INTC0_ICR7 MCF_REG08(0xFC048047) +#define MCF_INTC0_ICR8 MCF_REG08(0xFC048048) +#define MCF_INTC0_ICR9 MCF_REG08(0xFC048049) +#define MCF_INTC0_ICR10 MCF_REG08(0xFC04804A) +#define MCF_INTC0_ICR11 MCF_REG08(0xFC04804B) +#define MCF_INTC0_ICR12 MCF_REG08(0xFC04804C) +#define MCF_INTC0_ICR13 MCF_REG08(0xFC04804D) +#define MCF_INTC0_ICR14 MCF_REG08(0xFC04804E) +#define MCF_INTC0_ICR15 MCF_REG08(0xFC04804F) +#define MCF_INTC0_ICR16 MCF_REG08(0xFC048050) +#define MCF_INTC0_ICR17 MCF_REG08(0xFC048051) +#define MCF_INTC0_ICR18 MCF_REG08(0xFC048052) +#define MCF_INTC0_ICR19 MCF_REG08(0xFC048053) +#define MCF_INTC0_ICR20 MCF_REG08(0xFC048054) +#define MCF_INTC0_ICR21 MCF_REG08(0xFC048055) +#define MCF_INTC0_ICR22 MCF_REG08(0xFC048056) +#define MCF_INTC0_ICR23 MCF_REG08(0xFC048057) +#define MCF_INTC0_ICR24 MCF_REG08(0xFC048058) +#define MCF_INTC0_ICR25 MCF_REG08(0xFC048059) +#define MCF_INTC0_ICR26 MCF_REG08(0xFC04805A) +#define MCF_INTC0_ICR27 MCF_REG08(0xFC04805B) +#define MCF_INTC0_ICR28 MCF_REG08(0xFC04805C) +#define MCF_INTC0_ICR29 MCF_REG08(0xFC04805D) +#define MCF_INTC0_ICR30 MCF_REG08(0xFC04805E) +#define MCF_INTC0_ICR31 MCF_REG08(0xFC04805F) +#define MCF_INTC0_ICR32 MCF_REG08(0xFC048060) +#define MCF_INTC0_ICR33 MCF_REG08(0xFC048061) +#define MCF_INTC0_ICR34 MCF_REG08(0xFC048062) +#define MCF_INTC0_ICR35 MCF_REG08(0xFC048063) +#define MCF_INTC0_ICR36 MCF_REG08(0xFC048064) +#define MCF_INTC0_ICR37 MCF_REG08(0xFC048065) +#define MCF_INTC0_ICR38 MCF_REG08(0xFC048066) +#define MCF_INTC0_ICR39 MCF_REG08(0xFC048067) +#define MCF_INTC0_ICR40 MCF_REG08(0xFC048068) +#define MCF_INTC0_ICR41 MCF_REG08(0xFC048069) +#define MCF_INTC0_ICR42 MCF_REG08(0xFC04806A) +#define MCF_INTC0_ICR43 MCF_REG08(0xFC04806B) +#define MCF_INTC0_ICR44 MCF_REG08(0xFC04806C) +#define MCF_INTC0_ICR45 MCF_REG08(0xFC04806D) +#define MCF_INTC0_ICR46 MCF_REG08(0xFC04806E) +#define MCF_INTC0_ICR47 MCF_REG08(0xFC04806F) +#define MCF_INTC0_ICR48 MCF_REG08(0xFC048070) +#define MCF_INTC0_ICR49 MCF_REG08(0xFC048071) +#define MCF_INTC0_ICR50 MCF_REG08(0xFC048072) +#define MCF_INTC0_ICR51 MCF_REG08(0xFC048073) +#define MCF_INTC0_ICR52 MCF_REG08(0xFC048074) +#define MCF_INTC0_ICR53 MCF_REG08(0xFC048075) +#define MCF_INTC0_ICR54 MCF_REG08(0xFC048076) +#define MCF_INTC0_ICR55 MCF_REG08(0xFC048077) +#define MCF_INTC0_ICR56 MCF_REG08(0xFC048078) +#define MCF_INTC0_ICR57 MCF_REG08(0xFC048079) +#define MCF_INTC0_ICR58 MCF_REG08(0xFC04807A) +#define MCF_INTC0_ICR59 MCF_REG08(0xFC04807B) +#define MCF_INTC0_ICR60 MCF_REG08(0xFC04807C) +#define MCF_INTC0_ICR61 MCF_REG08(0xFC04807D) +#define MCF_INTC0_ICR62 MCF_REG08(0xFC04807E) +#define MCF_INTC0_ICR63 MCF_REG08(0xFC04807F) +#define MCF_INTC0_ICR(x) MCF_REG08(0xFC048040+((x)*0x001)) +#define MCF_INTC0_SWIACK MCF_REG08(0xFC0480E0) +#define MCF_INTC0_L1IACK MCF_REG08(0xFC0480E4) +#define MCF_INTC0_L2IACK MCF_REG08(0xFC0480E8) +#define MCF_INTC0_L3IACK MCF_REG08(0xFC0480EC) +#define MCF_INTC0_L4IACK MCF_REG08(0xFC0480F0) +#define MCF_INTC0_L5IACK MCF_REG08(0xFC0480F4) +#define MCF_INTC0_L6IACK MCF_REG08(0xFC0480F8) +#define MCF_INTC0_L7IACK MCF_REG08(0xFC0480FC) +#define MCF_INTC0_LIACK(x) MCF_REG08(0xFC0480E4+((x)*0x004)) +#define MCF_INTC1_IPRH MCF_REG32(0xFC04C000) +#define MCF_INTC1_IPRL MCF_REG32(0xFC04C004) +#define MCF_INTC1_IMRH MCF_REG32(0xFC04C008) +#define MCF_INTC1_IMRL MCF_REG32(0xFC04C00C) +#define MCF_INTC1_INTFRCH MCF_REG32(0xFC04C010) +#define MCF_INTC1_INTFRCL MCF_REG32(0xFC04C014) +#define MCF_INTC1_ICONFIG MCF_REG16(0xFC04C01A) +#define MCF_INTC1_SIMR MCF_REG08(0xFC04C01C) +#define MCF_INTC1_CIMR MCF_REG08(0xFC04C01D) +#define MCF_INTC1_CLMASK MCF_REG08(0xFC04C01E) +#define MCF_INTC1_SLMASK MCF_REG08(0xFC04C01F) +#define MCF_INTC1_ICR0 MCF_REG08(0xFC04C040) +#define MCF_INTC1_ICR1 MCF_REG08(0xFC04C041) +#define MCF_INTC1_ICR2 MCF_REG08(0xFC04C042) +#define MCF_INTC1_ICR3 MCF_REG08(0xFC04C043) +#define MCF_INTC1_ICR4 MCF_REG08(0xFC04C044) +#define MCF_INTC1_ICR5 MCF_REG08(0xFC04C045) +#define MCF_INTC1_ICR6 MCF_REG08(0xFC04C046) +#define MCF_INTC1_ICR7 MCF_REG08(0xFC04C047) +#define MCF_INTC1_ICR8 MCF_REG08(0xFC04C048) +#define MCF_INTC1_ICR9 MCF_REG08(0xFC04C049) +#define MCF_INTC1_ICR10 MCF_REG08(0xFC04C04A) +#define MCF_INTC1_ICR11 MCF_REG08(0xFC04C04B) +#define MCF_INTC1_ICR12 MCF_REG08(0xFC04C04C) +#define MCF_INTC1_ICR13 MCF_REG08(0xFC04C04D) +#define MCF_INTC1_ICR14 MCF_REG08(0xFC04C04E) +#define MCF_INTC1_ICR15 MCF_REG08(0xFC04C04F) +#define MCF_INTC1_ICR16 MCF_REG08(0xFC04C050) +#define MCF_INTC1_ICR17 MCF_REG08(0xFC04C051) +#define MCF_INTC1_ICR18 MCF_REG08(0xFC04C052) +#define MCF_INTC1_ICR19 MCF_REG08(0xFC04C053) +#define MCF_INTC1_ICR20 MCF_REG08(0xFC04C054) +#define MCF_INTC1_ICR21 MCF_REG08(0xFC04C055) +#define MCF_INTC1_ICR22 MCF_REG08(0xFC04C056) +#define MCF_INTC1_ICR23 MCF_REG08(0xFC04C057) +#define MCF_INTC1_ICR24 MCF_REG08(0xFC04C058) +#define MCF_INTC1_ICR25 MCF_REG08(0xFC04C059) +#define MCF_INTC1_ICR26 MCF_REG08(0xFC04C05A) +#define MCF_INTC1_ICR27 MCF_REG08(0xFC04C05B) +#define MCF_INTC1_ICR28 MCF_REG08(0xFC04C05C) +#define MCF_INTC1_ICR29 MCF_REG08(0xFC04C05D) +#define MCF_INTC1_ICR30 MCF_REG08(0xFC04C05E) +#define MCF_INTC1_ICR31 MCF_REG08(0xFC04C05F) +#define MCF_INTC1_ICR32 MCF_REG08(0xFC04C060) +#define MCF_INTC1_ICR33 MCF_REG08(0xFC04C061) +#define MCF_INTC1_ICR34 MCF_REG08(0xFC04C062) +#define MCF_INTC1_ICR35 MCF_REG08(0xFC04C063) +#define MCF_INTC1_ICR36 MCF_REG08(0xFC04C064) +#define MCF_INTC1_ICR37 MCF_REG08(0xFC04C065) +#define MCF_INTC1_ICR38 MCF_REG08(0xFC04C066) +#define MCF_INTC1_ICR39 MCF_REG08(0xFC04C067) +#define MCF_INTC1_ICR40 MCF_REG08(0xFC04C068) +#define MCF_INTC1_ICR41 MCF_REG08(0xFC04C069) +#define MCF_INTC1_ICR42 MCF_REG08(0xFC04C06A) +#define MCF_INTC1_ICR43 MCF_REG08(0xFC04C06B) +#define MCF_INTC1_ICR44 MCF_REG08(0xFC04C06C) +#define MCF_INTC1_ICR45 MCF_REG08(0xFC04C06D) +#define MCF_INTC1_ICR46 MCF_REG08(0xFC04C06E) +#define MCF_INTC1_ICR47 MCF_REG08(0xFC04C06F) +#define MCF_INTC1_ICR48 MCF_REG08(0xFC04C070) +#define MCF_INTC1_ICR49 MCF_REG08(0xFC04C071) +#define MCF_INTC1_ICR50 MCF_REG08(0xFC04C072) +#define MCF_INTC1_ICR51 MCF_REG08(0xFC04C073) +#define MCF_INTC1_ICR52 MCF_REG08(0xFC04C074) +#define MCF_INTC1_ICR53 MCF_REG08(0xFC04C075) +#define MCF_INTC1_ICR54 MCF_REG08(0xFC04C076) +#define MCF_INTC1_ICR55 MCF_REG08(0xFC04C077) +#define MCF_INTC1_ICR56 MCF_REG08(0xFC04C078) +#define MCF_INTC1_ICR57 MCF_REG08(0xFC04C079) +#define MCF_INTC1_ICR58 MCF_REG08(0xFC04C07A) +#define MCF_INTC1_ICR59 MCF_REG08(0xFC04C07B) +#define MCF_INTC1_ICR60 MCF_REG08(0xFC04C07C) +#define MCF_INTC1_ICR61 MCF_REG08(0xFC04C07D) +#define MCF_INTC1_ICR62 MCF_REG08(0xFC04C07E) +#define MCF_INTC1_ICR63 MCF_REG08(0xFC04C07F) +#define MCF_INTC1_ICR(x) MCF_REG08(0xFC04C040+((x)*0x001)) +#define MCF_INTC1_SWIACK MCF_REG08(0xFC04C0E0) +#define MCF_INTC1_L1IACK MCF_REG08(0xFC04C0E4) +#define MCF_INTC1_L2IACK MCF_REG08(0xFC04C0E8) +#define MCF_INTC1_L3IACK MCF_REG08(0xFC04C0EC) +#define MCF_INTC1_L4IACK MCF_REG08(0xFC04C0F0) +#define MCF_INTC1_L5IACK MCF_REG08(0xFC04C0F4) +#define MCF_INTC1_L6IACK MCF_REG08(0xFC04C0F8) +#define MCF_INTC1_L7IACK MCF_REG08(0xFC04C0FC) +#define MCF_INTC1_LIACK(x) MCF_REG08(0xFC04C0E4+((x)*0x004)) +#define MCF_INTC_IPRH(x) MCF_REG32(0xFC048000+((x)*0x4000)) +#define MCF_INTC_IPRL(x) MCF_REG32(0xFC048004+((x)*0x4000)) +#define MCF_INTC_IMRH(x) MCF_REG32(0xFC048008+((x)*0x4000)) +#define MCF_INTC_IMRL(x) MCF_REG32(0xFC04800C+((x)*0x4000)) +#define MCF_INTC_INTFRCH(x) MCF_REG32(0xFC048010+((x)*0x4000)) +#define MCF_INTC_INTFRCL(x) MCF_REG32(0xFC048014+((x)*0x4000)) +#define MCF_INTC_ICONFIG(x) MCF_REG16(0xFC04801A+((x)*0x4000)) +#define MCF_INTC_SIMR(x) MCF_REG08(0xFC04801C+((x)*0x4000)) +#define MCF_INTC_CIMR(x) MCF_REG08(0xFC04801D+((x)*0x4000)) +#define MCF_INTC_CLMASK(x) MCF_REG08(0xFC04801E+((x)*0x4000)) +#define MCF_INTC_SLMASK(x) MCF_REG08(0xFC04801F+((x)*0x4000)) +#define MCF_INTC_ICR0(x) MCF_REG08(0xFC048040+((x)*0x4000)) +#define MCF_INTC_ICR1(x) MCF_REG08(0xFC048041+((x)*0x4000)) +#define MCF_INTC_ICR2(x) MCF_REG08(0xFC048042+((x)*0x4000)) +#define MCF_INTC_ICR3(x) MCF_REG08(0xFC048043+((x)*0x4000)) +#define MCF_INTC_ICR4(x) MCF_REG08(0xFC048044+((x)*0x4000)) +#define MCF_INTC_ICR5(x) MCF_REG08(0xFC048045+((x)*0x4000)) +#define MCF_INTC_ICR6(x) MCF_REG08(0xFC048046+((x)*0x4000)) +#define MCF_INTC_ICR7(x) MCF_REG08(0xFC048047+((x)*0x4000)) +#define MCF_INTC_ICR8(x) MCF_REG08(0xFC048048+((x)*0x4000)) +#define MCF_INTC_ICR9(x) MCF_REG08(0xFC048049+((x)*0x4000)) +#define MCF_INTC_ICR10(x) MCF_REG08(0xFC04804A+((x)*0x4000)) +#define MCF_INTC_ICR11(x) MCF_REG08(0xFC04804B+((x)*0x4000)) +#define MCF_INTC_ICR12(x) MCF_REG08(0xFC04804C+((x)*0x4000)) +#define MCF_INTC_ICR13(x) MCF_REG08(0xFC04804D+((x)*0x4000)) +#define MCF_INTC_ICR14(x) MCF_REG08(0xFC04804E+((x)*0x4000)) +#define MCF_INTC_ICR15(x) MCF_REG08(0xFC04804F+((x)*0x4000)) +#define MCF_INTC_ICR16(x) MCF_REG08(0xFC048050+((x)*0x4000)) +#define MCF_INTC_ICR17(x) MCF_REG08(0xFC048051+((x)*0x4000)) +#define MCF_INTC_ICR18(x) MCF_REG08(0xFC048052+((x)*0x4000)) +#define MCF_INTC_ICR19(x) MCF_REG08(0xFC048053+((x)*0x4000)) +#define MCF_INTC_ICR20(x) MCF_REG08(0xFC048054+((x)*0x4000)) +#define MCF_INTC_ICR21(x) MCF_REG08(0xFC048055+((x)*0x4000)) +#define MCF_INTC_ICR22(x) MCF_REG08(0xFC048056+((x)*0x4000)) +#define MCF_INTC_ICR23(x) MCF_REG08(0xFC048057+((x)*0x4000)) +#define MCF_INTC_ICR24(x) MCF_REG08(0xFC048058+((x)*0x4000)) +#define MCF_INTC_ICR25(x) MCF_REG08(0xFC048059+((x)*0x4000)) +#define MCF_INTC_ICR26(x) MCF_REG08(0xFC04805A+((x)*0x4000)) +#define MCF_INTC_ICR27(x) MCF_REG08(0xFC04805B+((x)*0x4000)) +#define MCF_INTC_ICR28(x) MCF_REG08(0xFC04805C+((x)*0x4000)) +#define MCF_INTC_ICR29(x) MCF_REG08(0xFC04805D+((x)*0x4000)) +#define MCF_INTC_ICR30(x) MCF_REG08(0xFC04805E+((x)*0x4000)) +#define MCF_INTC_ICR31(x) MCF_REG08(0xFC04805F+((x)*0x4000)) +#define MCF_INTC_ICR32(x) MCF_REG08(0xFC048060+((x)*0x4000)) +#define MCF_INTC_ICR33(x) MCF_REG08(0xFC048061+((x)*0x4000)) +#define MCF_INTC_ICR34(x) MCF_REG08(0xFC048062+((x)*0x4000)) +#define MCF_INTC_ICR35(x) MCF_REG08(0xFC048063+((x)*0x4000)) +#define MCF_INTC_ICR36(x) MCF_REG08(0xFC048064+((x)*0x4000)) +#define MCF_INTC_ICR37(x) MCF_REG08(0xFC048065+((x)*0x4000)) +#define MCF_INTC_ICR38(x) MCF_REG08(0xFC048066+((x)*0x4000)) +#define MCF_INTC_ICR39(x) MCF_REG08(0xFC048067+((x)*0x4000)) +#define MCF_INTC_ICR40(x) MCF_REG08(0xFC048068+((x)*0x4000)) +#define MCF_INTC_ICR41(x) MCF_REG08(0xFC048069+((x)*0x4000)) +#define MCF_INTC_ICR42(x) MCF_REG08(0xFC04806A+((x)*0x4000)) +#define MCF_INTC_ICR43(x) MCF_REG08(0xFC04806B+((x)*0x4000)) +#define MCF_INTC_ICR44(x) MCF_REG08(0xFC04806C+((x)*0x4000)) +#define MCF_INTC_ICR45(x) MCF_REG08(0xFC04806D+((x)*0x4000)) +#define MCF_INTC_ICR46(x) MCF_REG08(0xFC04806E+((x)*0x4000)) +#define MCF_INTC_ICR47(x) MCF_REG08(0xFC04806F+((x)*0x4000)) +#define MCF_INTC_ICR48(x) MCF_REG08(0xFC048070+((x)*0x4000)) +#define MCF_INTC_ICR49(x) MCF_REG08(0xFC048071+((x)*0x4000)) +#define MCF_INTC_ICR50(x) MCF_REG08(0xFC048072+((x)*0x4000)) +#define MCF_INTC_ICR51(x) MCF_REG08(0xFC048073+((x)*0x4000)) +#define MCF_INTC_ICR52(x) MCF_REG08(0xFC048074+((x)*0x4000)) +#define MCF_INTC_ICR53(x) MCF_REG08(0xFC048075+((x)*0x4000)) +#define MCF_INTC_ICR54(x) MCF_REG08(0xFC048076+((x)*0x4000)) +#define MCF_INTC_ICR55(x) MCF_REG08(0xFC048077+((x)*0x4000)) +#define MCF_INTC_ICR56(x) MCF_REG08(0xFC048078+((x)*0x4000)) +#define MCF_INTC_ICR57(x) MCF_REG08(0xFC048079+((x)*0x4000)) +#define MCF_INTC_ICR58(x) MCF_REG08(0xFC04807A+((x)*0x4000)) +#define MCF_INTC_ICR59(x) MCF_REG08(0xFC04807B+((x)*0x4000)) +#define MCF_INTC_ICR60(x) MCF_REG08(0xFC04807C+((x)*0x4000)) +#define MCF_INTC_ICR61(x) MCF_REG08(0xFC04807D+((x)*0x4000)) +#define MCF_INTC_ICR62(x) MCF_REG08(0xFC04807E+((x)*0x4000)) +#define MCF_INTC_ICR63(x) MCF_REG08(0xFC04807F+((x)*0x4000)) +#define MCF_INTC_SWIACK(x) MCF_REG08(0xFC0480E0+((x)*0x4000)) +#define MCF_INTC_L1IACK(x) MCF_REG08(0xFC0480E4+((x)*0x4000)) +#define MCF_INTC_L2IACK(x) MCF_REG08(0xFC0480E8+((x)*0x4000)) +#define MCF_INTC_L3IACK(x) MCF_REG08(0xFC0480EC+((x)*0x4000)) +#define MCF_INTC_L4IACK(x) MCF_REG08(0xFC0480F0+((x)*0x4000)) +#define MCF_INTC_L5IACK(x) MCF_REG08(0xFC0480F4+((x)*0x4000)) +#define MCF_INTC_L6IACK(x) MCF_REG08(0xFC0480F8+((x)*0x4000)) +#define MCF_INTC_L7IACK(x) MCF_REG08(0xFC0480FC+((x)*0x4000)) + +/* Bit definitions and macros for MCF_INTC_IPRH */ +#define MCF_INTC_IPRH_INT32 (0x00000001) +#define MCF_INTC_IPRH_INT33 (0x00000002) +#define MCF_INTC_IPRH_INT34 (0x00000004) +#define MCF_INTC_IPRH_INT35 (0x00000008) +#define MCF_INTC_IPRH_INT36 (0x00000010) +#define MCF_INTC_IPRH_INT37 (0x00000020) +#define MCF_INTC_IPRH_INT38 (0x00000040) +#define MCF_INTC_IPRH_INT39 (0x00000080) +#define MCF_INTC_IPRH_INT40 (0x00000100) +#define MCF_INTC_IPRH_INT41 (0x00000200) +#define MCF_INTC_IPRH_INT42 (0x00000400) +#define MCF_INTC_IPRH_INT43 (0x00000800) +#define MCF_INTC_IPRH_INT44 (0x00001000) +#define MCF_INTC_IPRH_INT45 (0x00002000) +#define MCF_INTC_IPRH_INT46 (0x00004000) +#define MCF_INTC_IPRH_INT47 (0x00008000) +#define MCF_INTC_IPRH_INT48 (0x00010000) +#define MCF_INTC_IPRH_INT49 (0x00020000) +#define MCF_INTC_IPRH_INT50 (0x00040000) +#define MCF_INTC_IPRH_INT51 (0x00080000) +#define MCF_INTC_IPRH_INT52 (0x00100000) +#define MCF_INTC_IPRH_INT53 (0x00200000) +#define MCF_INTC_IPRH_INT54 (0x00400000) +#define MCF_INTC_IPRH_INT55 (0x00800000) +#define MCF_INTC_IPRH_INT56 (0x01000000) +#define MCF_INTC_IPRH_INT57 (0x02000000) +#define MCF_INTC_IPRH_INT58 (0x04000000) +#define MCF_INTC_IPRH_INT59 (0x08000000) +#define MCF_INTC_IPRH_INT60 (0x10000000) +#define MCF_INTC_IPRH_INT61 (0x20000000) +#define MCF_INTC_IPRH_INT62 (0x40000000) +#define MCF_INTC_IPRH_INT63 (0x80000000) + +/* Bit definitions and macros for MCF_INTC_IPRL */ +#define MCF_INTC_IPRL_INT0 (0x00000001) +#define MCF_INTC_IPRL_INT1 (0x00000002) +#define MCF_INTC_IPRL_INT2 (0x00000004) +#define MCF_INTC_IPRL_INT3 (0x00000008) +#define MCF_INTC_IPRL_INT4 (0x00000010) +#define MCF_INTC_IPRL_INT5 (0x00000020) +#define MCF_INTC_IPRL_INT6 (0x00000040) +#define MCF_INTC_IPRL_INT7 (0x00000080) +#define MCF_INTC_IPRL_INT8 (0x00000100) +#define MCF_INTC_IPRL_INT9 (0x00000200) +#define MCF_INTC_IPRL_INT10 (0x00000400) +#define MCF_INTC_IPRL_INT11 (0x00000800) +#define MCF_INTC_IPRL_INT12 (0x00001000) +#define MCF_INTC_IPRL_INT13 (0x00002000) +#define MCF_INTC_IPRL_INT14 (0x00004000) +#define MCF_INTC_IPRL_INT15 (0x00008000) +#define MCF_INTC_IPRL_INT16 (0x00010000) +#define MCF_INTC_IPRL_INT17 (0x00020000) +#define MCF_INTC_IPRL_INT18 (0x00040000) +#define MCF_INTC_IPRL_INT19 (0x00080000) +#define MCF_INTC_IPRL_INT20 (0x00100000) +#define MCF_INTC_IPRL_INT21 (0x00200000) +#define MCF_INTC_IPRL_INT22 (0x00400000) +#define MCF_INTC_IPRL_INT23 (0x00800000) +#define MCF_INTC_IPRL_INT24 (0x01000000) +#define MCF_INTC_IPRL_INT25 (0x02000000) +#define MCF_INTC_IPRL_INT26 (0x04000000) +#define MCF_INTC_IPRL_INT27 (0x08000000) +#define MCF_INTC_IPRL_INT28 (0x10000000) +#define MCF_INTC_IPRL_INT29 (0x20000000) +#define MCF_INTC_IPRL_INT30 (0x40000000) +#define MCF_INTC_IPRL_INT31 (0x80000000) + +/* Bit definitions and macros for MCF_INTC_IMRH */ +#define MCF_INTC_IMRH_INT_MASK32 (0x00000001) +#define MCF_INTC_IMRH_INT_MASK33 (0x00000002) +#define MCF_INTC_IMRH_INT_MASK34 (0x00000004) +#define MCF_INTC_IMRH_INT_MASK35 (0x00000008) +#define MCF_INTC_IMRH_INT_MASK36 (0x00000010) +#define MCF_INTC_IMRH_INT_MASK37 (0x00000020) +#define MCF_INTC_IMRH_INT_MASK38 (0x00000040) +#define MCF_INTC_IMRH_INT_MASK39 (0x00000080) +#define MCF_INTC_IMRH_INT_MASK40 (0x00000100) +#define MCF_INTC_IMRH_INT_MASK41 (0x00000200) +#define MCF_INTC_IMRH_INT_MASK42 (0x00000400) +#define MCF_INTC_IMRH_INT_MASK43 (0x00000800) +#define MCF_INTC_IMRH_INT_MASK44 (0x00001000) +#define MCF_INTC_IMRH_INT_MASK45 (0x00002000) +#define MCF_INTC_IMRH_INT_MASK46 (0x00004000) +#define MCF_INTC_IMRH_INT_MASK47 (0x00008000) +#define MCF_INTC_IMRH_INT_MASK48 (0x00010000) +#define MCF_INTC_IMRH_INT_MASK49 (0x00020000) +#define MCF_INTC_IMRH_INT_MASK50 (0x00040000) +#define MCF_INTC_IMRH_INT_MASK51 (0x00080000) +#define MCF_INTC_IMRH_INT_MASK52 (0x00100000) +#define MCF_INTC_IMRH_INT_MASK53 (0x00200000) +#define MCF_INTC_IMRH_INT_MASK54 (0x00400000) +#define MCF_INTC_IMRH_INT_MASK55 (0x00800000) +#define MCF_INTC_IMRH_INT_MASK56 (0x01000000) +#define MCF_INTC_IMRH_INT_MASK57 (0x02000000) +#define MCF_INTC_IMRH_INT_MASK58 (0x04000000) +#define MCF_INTC_IMRH_INT_MASK59 (0x08000000) +#define MCF_INTC_IMRH_INT_MASK60 (0x10000000) +#define MCF_INTC_IMRH_INT_MASK61 (0x20000000) +#define MCF_INTC_IMRH_INT_MASK62 (0x40000000) +#define MCF_INTC_IMRH_INT_MASK63 (0x80000000) + +/* Bit definitions and macros for MCF_INTC_IMRL */ +#define MCF_INTC_IMRL_INT_MASK0 (0x00000001) +#define MCF_INTC_IMRL_INT_MASK1 (0x00000002) +#define MCF_INTC_IMRL_INT_MASK2 (0x00000004) +#define MCF_INTC_IMRL_INT_MASK3 (0x00000008) +#define MCF_INTC_IMRL_INT_MASK4 (0x00000010) +#define MCF_INTC_IMRL_INT_MASK5 (0x00000020) +#define MCF_INTC_IMRL_INT_MASK6 (0x00000040) +#define MCF_INTC_IMRL_INT_MASK7 (0x00000080) +#define MCF_INTC_IMRL_INT_MASK8 (0x00000100) +#define MCF_INTC_IMRL_INT_MASK9 (0x00000200) +#define MCF_INTC_IMRL_INT_MASK10 (0x00000400) +#define MCF_INTC_IMRL_INT_MASK11 (0x00000800) +#define MCF_INTC_IMRL_INT_MASK12 (0x00001000) +#define MCF_INTC_IMRL_INT_MASK13 (0x00002000) +#define MCF_INTC_IMRL_INT_MASK14 (0x00004000) +#define MCF_INTC_IMRL_INT_MASK15 (0x00008000) +#define MCF_INTC_IMRL_INT_MASK16 (0x00010000) +#define MCF_INTC_IMRL_INT_MASK17 (0x00020000) +#define MCF_INTC_IMRL_INT_MASK18 (0x00040000) +#define MCF_INTC_IMRL_INT_MASK19 (0x00080000) +#define MCF_INTC_IMRL_INT_MASK20 (0x00100000) +#define MCF_INTC_IMRL_INT_MASK21 (0x00200000) +#define MCF_INTC_IMRL_INT_MASK22 (0x00400000) +#define MCF_INTC_IMRL_INT_MASK23 (0x00800000) +#define MCF_INTC_IMRL_INT_MASK24 (0x01000000) +#define MCF_INTC_IMRL_INT_MASK25 (0x02000000) +#define MCF_INTC_IMRL_INT_MASK26 (0x04000000) +#define MCF_INTC_IMRL_INT_MASK27 (0x08000000) +#define MCF_INTC_IMRL_INT_MASK28 (0x10000000) +#define MCF_INTC_IMRL_INT_MASK29 (0x20000000) +#define MCF_INTC_IMRL_INT_MASK30 (0x40000000) +#define MCF_INTC_IMRL_INT_MASK31 (0x80000000) + +/* Bit definitions and macros for MCF_INTC_INTFRCH */ +#define MCF_INTC_INTFRCH_INTFRC32 (0x00000001) +#define MCF_INTC_INTFRCH_INTFRC33 (0x00000002) +#define MCF_INTC_INTFRCH_INTFRC34 (0x00000004) +#define MCF_INTC_INTFRCH_INTFRC35 (0x00000008) +#define MCF_INTC_INTFRCH_INTFRC36 (0x00000010) +#define MCF_INTC_INTFRCH_INTFRC37 (0x00000020) +#define MCF_INTC_INTFRCH_INTFRC38 (0x00000040) +#define MCF_INTC_INTFRCH_INTFRC39 (0x00000080) +#define MCF_INTC_INTFRCH_INTFRC40 (0x00000100) +#define MCF_INTC_INTFRCH_INTFRC41 (0x00000200) +#define MCF_INTC_INTFRCH_INTFRC42 (0x00000400) +#define MCF_INTC_INTFRCH_INTFRC43 (0x00000800) +#define MCF_INTC_INTFRCH_INTFRC44 (0x00001000) +#define MCF_INTC_INTFRCH_INTFRC45 (0x00002000) +#define MCF_INTC_INTFRCH_INTFRC46 (0x00004000) +#define MCF_INTC_INTFRCH_INTFRC47 (0x00008000) +#define MCF_INTC_INTFRCH_INTFRC48 (0x00010000) +#define MCF_INTC_INTFRCH_INTFRC49 (0x00020000) +#define MCF_INTC_INTFRCH_INTFRC50 (0x00040000) +#define MCF_INTC_INTFRCH_INTFRC51 (0x00080000) +#define MCF_INTC_INTFRCH_INTFRC52 (0x00100000) +#define MCF_INTC_INTFRCH_INTFRC53 (0x00200000) +#define MCF_INTC_INTFRCH_INTFRC54 (0x00400000) +#define MCF_INTC_INTFRCH_INTFRC55 (0x00800000) +#define MCF_INTC_INTFRCH_INTFRC56 (0x01000000) +#define MCF_INTC_INTFRCH_INTFRC57 (0x02000000) +#define MCF_INTC_INTFRCH_INTFRC58 (0x04000000) +#define MCF_INTC_INTFRCH_INTFRC59 (0x08000000) +#define MCF_INTC_INTFRCH_INTFRC60 (0x10000000) +#define MCF_INTC_INTFRCH_INTFRC61 (0x20000000) +#define MCF_INTC_INTFRCH_INTFRC62 (0x40000000) +#define MCF_INTC_INTFRCH_INTFRC63 (0x80000000) + +/* Bit definitions and macros for MCF_INTC_INTFRCL */ +#define MCF_INTC_INTFRCL_INTFRC0 (0x00000001) +#define MCF_INTC_INTFRCL_INTFRC1 (0x00000002) +#define MCF_INTC_INTFRCL_INTFRC2 (0x00000004) +#define MCF_INTC_INTFRCL_INTFRC3 (0x00000008) +#define MCF_INTC_INTFRCL_INTFRC4 (0x00000010) +#define MCF_INTC_INTFRCL_INTFRC5 (0x00000020) +#define MCF_INTC_INTFRCL_INTFRC6 (0x00000040) +#define MCF_INTC_INTFRCL_INTFRC7 (0x00000080) +#define MCF_INTC_INTFRCL_INTFRC8 (0x00000100) +#define MCF_INTC_INTFRCL_INTFRC9 (0x00000200) +#define MCF_INTC_INTFRCL_INTFRC10 (0x00000400) +#define MCF_INTC_INTFRCL_INTFRC11 (0x00000800) +#define MCF_INTC_INTFRCL_INTFRC12 (0x00001000) +#define MCF_INTC_INTFRCL_INTFRC13 (0x00002000) +#define MCF_INTC_INTFRCL_INTFRC14 (0x00004000) +#define MCF_INTC_INTFRCL_INTFRC15 (0x00008000) +#define MCF_INTC_INTFRCL_INTFRC16 (0x00010000) +#define MCF_INTC_INTFRCL_INTFRC17 (0x00020000) +#define MCF_INTC_INTFRCL_INTFRC18 (0x00040000) +#define MCF_INTC_INTFRCL_INTFRC19 (0x00080000) +#define MCF_INTC_INTFRCL_INTFRC20 (0x00100000) +#define MCF_INTC_INTFRCL_INTFRC21 (0x00200000) +#define MCF_INTC_INTFRCL_INTFRC22 (0x00400000) +#define MCF_INTC_INTFRCL_INTFRC23 (0x00800000) +#define MCF_INTC_INTFRCL_INTFRC24 (0x01000000) +#define MCF_INTC_INTFRCL_INTFRC25 (0x02000000) +#define MCF_INTC_INTFRCL_INTFRC26 (0x04000000) +#define MCF_INTC_INTFRCL_INTFRC27 (0x08000000) +#define MCF_INTC_INTFRCL_INTFRC28 (0x10000000) +#define MCF_INTC_INTFRCL_INTFRC29 (0x20000000) +#define MCF_INTC_INTFRCL_INTFRC30 (0x40000000) +#define MCF_INTC_INTFRCL_INTFRC31 (0x80000000) + +/* Bit definitions and macros for MCF_INTC_ICONFIG */ +#define MCF_INTC_ICONFIG_EMASK (0x0020) +#define MCF_INTC_ICONFIG_ELVLPRI1 (0x0200) +#define MCF_INTC_ICONFIG_ELVLPRI2 (0x0400) +#define MCF_INTC_ICONFIG_ELVLPRI3 (0x0800) +#define MCF_INTC_ICONFIG_ELVLPRI4 (0x1000) +#define MCF_INTC_ICONFIG_ELVLPRI5 (0x2000) +#define MCF_INTC_ICONFIG_ELVLPRI6 (0x4000) +#define MCF_INTC_ICONFIG_ELVLPRI7 (0x8000) + +/* Bit definitions and macros for MCF_INTC_SIMR */ +#define MCF_INTC_SIMR_SIMR(x) (((x)&0x7F)<<0) + +/* Bit definitions and macros for MCF_INTC_CIMR */ +#define MCF_INTC_CIMR_CIMR(x) (((x)&0x7F)<<0) + +/* Bit definitions and macros for MCF_INTC_CLMASK */ +#define MCF_INTC_CLMASK_CLMASK(x) (((x)&0x0F)<<0) + +/* Bit definitions and macros for MCF_INTC_SLMASK */ +#define MCF_INTC_SLMASK_SLMASK(x) (((x)&0x0F)<<0) + +/* Bit definitions and macros for MCF_INTC_ICR */ +#define MCF_INTC_ICR_IL(x) (((x)&0x07)<<0) + +/* Bit definitions and macros for MCF_INTC_SWIACK */ +#define MCF_INTC_SWIACK_VECTOR(x) (((x)&0xFF)<<0) + +/* Bit definitions and macros for MCF_INTC_LIACK */ +#define MCF_INTC_LIACK_VECTOR(x) (((x)&0xFF)<<0) + +/********************************************************************/ +/********************************************************************* +* +* LCD Controller (LCDC) +* +*********************************************************************/ + +/* Register read/write macros */ +#define MCF_LCDC_LSSAR MCF_REG32(0xFC0AC000) +#define MCF_LCDC_LSR MCF_REG32(0xFC0AC004) +#define MCF_LCDC_LVPWR MCF_REG32(0xFC0AC008) +#define MCF_LCDC_LCPR MCF_REG32(0xFC0AC00C) +#define MCF_LCDC_LCWHBR MCF_REG32(0xFC0AC010) +#define MCF_LCDC_LCCMR MCF_REG32(0xFC0AC014) +#define MCF_LCDC_LPCR MCF_REG32(0xFC0AC018) +#define MCF_LCDC_LHCR MCF_REG32(0xFC0AC01C) +#define MCF_LCDC_LVCR MCF_REG32(0xFC0AC020) +#define MCF_LCDC_LPOR MCF_REG32(0xFC0AC024) +#define MCF_LCDC_LSCR MCF_REG32(0xFC0AC028) +#define MCF_LCDC_LPCCR MCF_REG32(0xFC0AC02C) +#define MCF_LCDC_LDCR MCF_REG32(0xFC0AC030) +#define MCF_LCDC_LRMCR MCF_REG32(0xFC0AC034) +#define MCF_LCDC_LICR MCF_REG32(0xFC0AC038) +#define MCF_LCDC_LIER MCF_REG32(0xFC0AC03C) +#define MCF_LCDC_LISR MCF_REG32(0xFC0AC040) +#define MCF_LCDC_LGWSAR MCF_REG32(0xFC0AC050) +#define MCF_LCDC_LGWSR MCF_REG32(0xFC0AC054) +#define MCF_LCDC_LGWVPWR MCF_REG32(0xFC0AC058) +#define MCF_LCDC_LGWPOR MCF_REG32(0xFC0AC05C) +#define MCF_LCDC_LGWPR MCF_REG32(0xFC0AC060) +#define MCF_LCDC_LGWCR MCF_REG32(0xFC0AC064) +#define MCF_LCDC_LGWDCR MCF_REG32(0xFC0AC068) +#define MCF_LCDC_BPLUT_BASE MCF_REG32(0xFC0AC800) +#define MCF_LCDC_GWLUT_BASE MCF_REG32(0xFC0ACC00) + +/* Bit definitions and macros for MCF_LCDC_LSSAR */ +#define MCF_LCDC_LSSAR_SSA(x) (((x)&0x3FFFFFFF)<<2) + +/* Bit definitions and macros for MCF_LCDC_LSR */ +#define MCF_LCDC_LSR_YMAX(x) (((x)&0x000003FF)<<0) +#define MCF_LCDC_LSR_XMAX(x) (((x)&0x0000003F)<<20) + +/* Bit definitions and macros for MCF_LCDC_LVPWR */ +#define MCF_LCDC_LVPWR_VPW(x) (((x)&0x000003FF)<<0) + +/* Bit definitions and macros for MCF_LCDC_LCPR */ +#define MCF_LCDC_LCPR_CYP(x) (((x)&0x000003FF)<<0) +#define MCF_LCDC_LCPR_CXP(x) (((x)&0x000003FF)<<16) +#define MCF_LCDC_LCPR_OP (0x10000000) +#define MCF_LCDC_LCPR_CC(x) (((x)&0x00000003)<<30) +#define MCF_LCDC_LCPR_CC_TRANSPARENT (0x00000000) +#define MCF_LCDC_LCPR_CC_OR (0x40000000) +#define MCF_LCDC_LCPR_CC_XOR (0x80000000) +#define MCF_LCDC_LCPR_CC_AND (0xC0000000) +#define MCF_LCDC_LCPR_OP_ON (0x10000000) +#define MCF_LCDC_LCPR_OP_OFF (0x00000000) + +/* Bit definitions and macros for MCF_LCDC_LCWHBR */ +#define MCF_LCDC_LCWHBR_BD(x) (((x)&0x000000FF)<<0) +#define MCF_LCDC_LCWHBR_CH(x) (((x)&0x0000001F)<<16) +#define MCF_LCDC_LCWHBR_CW(x) (((x)&0x0000001F)<<24) +#define MCF_LCDC_LCWHBR_BK_EN (0x80000000) +#define MCF_LCDC_LCWHBR_BK_EN_ON (0x80000000) +#define MCF_LCDC_LCWHBR_BK_EN_OFF (0x00000000) + +/* Bit definitions and macros for MCF_LCDC_LCCMR */ +#define MCF_LCDC_LCCMR_CUR_COL_B(x) (((x)&0x0000003F)<<0) +#define MCF_LCDC_LCCMR_CUR_COL_G(x) (((x)&0x0000003F)<<6) +#define MCF_LCDC_LCCMR_CUR_COL_R(x) (((x)&0x0000003F)<<12) + +/* Bit definitions and macros for MCF_LCDC_LPCR */ +#define MCF_LCDC_LPCR_PCD(x) (((x)&0x0000003F)<<0) +#define MCF_LCDC_LPCR_SHARP (0x00000040) +#define MCF_LCDC_LPCR_SCLKSEL (0x00000080) +#define MCF_LCDC_LPCR_ACD(x) (((x)&0x0000007F)<<8) +#define MCF_LCDC_LPCR_ACDSEL (0x00008000) +#define MCF_LCDC_LPCR_REV_VS (0x00010000) +#define MCF_LCDC_LPCR_SWAP_SEL (0x00020000) +#define MCF_LCDC_LPCR_ENDSEL (0x00040000) +#define MCF_LCDC_LPCR_SCLKIDLE (0x00080000) +#define MCF_LCDC_LPCR_OEPOL (0x00100000) +#define MCF_LCDC_LPCR_CLKPOL (0x00200000) +#define MCF_LCDC_LPCR_LPPOL (0x00400000) +#define MCF_LCDC_LPCR_FLM (0x00800000) +#define MCF_LCDC_LPCR_PIXPOL (0x01000000) +#define MCF_LCDC_LPCR_BPIX(x) (((x)&0x00000007)<<25) +#define MCF_LCDC_LPCR_PBSIZ(x) (((x)&0x00000003)<<28) +#define MCF_LCDC_LPCR_COLOR (0x40000000) +#define MCF_LCDC_LPCR_TFT (0x80000000) +#define MCF_LCDC_LPCR_MODE_MONOCGROME (0x00000000) +#define MCF_LCDC_LPCR_MODE_CSTN (0x40000000) +#define MCF_LCDC_LPCR_MODE_TFT (0xC0000000) +#define MCF_LCDC_LPCR_PBSIZ_1 (0x00000000) +#define MCF_LCDC_LPCR_PBSIZ_2 (0x10000000) +#define MCF_LCDC_LPCR_PBSIZ_4 (0x20000000) +#define MCF_LCDC_LPCR_PBSIZ_8 (0x30000000) +#define MCF_LCDC_LPCR_BPIX_1bpp (0x00000000) +#define MCF_LCDC_LPCR_BPIX_2bpp (0x02000000) +#define MCF_LCDC_LPCR_BPIX_4bpp (0x04000000) +#define MCF_LCDC_LPCR_BPIX_8bpp (0x06000000) +#define MCF_LCDC_LPCR_BPIX_12bpp (0x08000000) +#define MCF_LCDC_LPCR_BPIX_16bpp (0x0A000000) +#define MCF_LCDC_LPCR_BPIX_18bpp (0x0C000000) + +#define MCF_LCDC_LPCR_PANEL_TYPE(x) (((x)&0x00000003)<<30) + +/* Bit definitions and macros for MCF_LCDC_LHCR */ +#define MCF_LCDC_LHCR_H_WAIT_2(x) (((x)&0x000000FF)<<0) +#define MCF_LCDC_LHCR_H_WAIT_1(x) (((x)&0x000000FF)<<8) +#define MCF_LCDC_LHCR_H_WIDTH(x) (((x)&0x0000003F)<<26) + +/* Bit definitions and macros for MCF_LCDC_LVCR */ +#define MCF_LCDC_LVCR_V_WAIT_2(x) (((x)&0x000000FF)<<0) +#define MCF_LCDC_LVCR_V_WAIT_1(x) (((x)&0x000000FF)<<8) +#define MCF_LCDC_LVCR_V_WIDTH(x) (((x)&0x0000003F)<<26) + +/* Bit definitions and macros for MCF_LCDC_LPOR */ +#define MCF_LCDC_LPOR_POS(x) (((x)&0x0000001F)<<0) + +/* Bit definitions and macros for MCF_LCDC_LPCCR */ +#define MCF_LCDC_LPCCR_PW(x) (((x)&0x000000FF)<<0) +#define MCF_LCDC_LPCCR_CC_EN (0x00000100) +#define MCF_LCDC_LPCCR_SCR(x) (((x)&0x00000003)<<9) +#define MCF_LCDC_LPCCR_LDMSK (0x00008000) +#define MCF_LCDC_LPCCR_CLS_HI_WIDTH(x) (((x)&0x000001FF)<<16) +#define MCF_LCDC_LPCCR_SCR_LINEPULSE (0x00000000) +#define MCF_LCDC_LPCCR_SCR_PIXELCLK (0x00002000) +#define MCF_LCDC_LPCCR_SCR_LCDCLOCK (0x00004000) + +/* Bit definitions and macros for MCF_LCDC_LDCR */ +#define MCF_LCDC_LDCR_TM(x) (((x)&0x0000001F)<<0) +#define MCF_LCDC_LDCR_HM(x) (((x)&0x0000001F)<<16) +#define MCF_LCDC_LDCR_BURST (0x80000000) + +/* Bit definitions and macros for MCF_LCDC_LRMCR */ +#define MCF_LCDC_LRMCR_SEL_REF (0x00000001) + +/* Bit definitions and macros for MCF_LCDC_LICR */ +#define MCF_LCDC_LICR_INTCON (0x00000001) +#define MCF_LCDC_LICR_INTSYN (0x00000004) +#define MCF_LCDC_LICR_GW_INT_CON (0x00000010) + +/* Bit definitions and macros for MCF_LCDC_LIER */ +#define MCF_LCDC_LIER_BOF_EN (0x00000001) +#define MCF_LCDC_LIER_EOF_EN (0x00000002) +#define MCF_LCDC_LIER_ERR_RES_EN (0x00000004) +#define MCF_LCDC_LIER_UDR_ERR_EN (0x00000008) +#define MCF_LCDC_LIER_GW_BOF_EN (0x00000010) +#define MCF_LCDC_LIER_GW_EOF_EN (0x00000020) +#define MCF_LCDC_LIER_GW_ERR_RES_EN (0x00000040) +#define MCF_LCDC_LIER_GW_UDR_ERR_EN (0x00000080) + +/* Bit definitions and macros for MCF_LCDC_LISR */ +#define MCF_LCDC_LISR_BOF (0x00000001) +#define MCF_LCDC_LISR_EOF (0x00000002) +#define MCF_LCDC_LISR_ERR_RES (0x00000004) +#define MCF_LCDC_LISR_UDR_ERR (0x00000008) +#define MCF_LCDC_LISR_GW_BOF (0x00000010) +#define MCF_LCDC_LISR_GW_EOF (0x00000020) +#define MCF_LCDC_LISR_GW_ERR_RES (0x00000040) +#define MCF_LCDC_LISR_GW_UDR_ERR (0x00000080) + +/* Bit definitions and macros for MCF_LCDC_LGWSAR */ +#define MCF_LCDC_LGWSAR_GWSA(x) (((x)&0x3FFFFFFF)<<2) + +/* Bit definitions and macros for MCF_LCDC_LGWSR */ +#define MCF_LCDC_LGWSR_GWH(x) (((x)&0x000003FF)<<0) +#define MCF_LCDC_LGWSR_GWW(x) (((x)&0x0000003F)<<20) + +/* Bit definitions and macros for MCF_LCDC_LGWVPWR */ +#define MCF_LCDC_LGWVPWR_GWVPW(x) (((x)&0x000003FF)<<0) + +/* Bit definitions and macros for MCF_LCDC_LGWPOR */ +#define MCF_LCDC_LGWPOR_GWPO(x) (((x)&0x0000001F)<<0) + +/* Bit definitions and macros for MCF_LCDC_LGWPR */ +#define MCF_LCDC_LGWPR_GWYP(x) (((x)&0x000003FF)<<0) +#define MCF_LCDC_LGWPR_GWXP(x) (((x)&0x000003FF)<<16) + +/* Bit definitions and macros for MCF_LCDC_LGWCR */ +#define MCF_LCDC_LGWCR_GWCKB(x) (((x)&0x0000003F)<<0) +#define MCF_LCDC_LGWCR_GWCKG(x) (((x)&0x0000003F)<<6) +#define MCF_LCDC_LGWCR_GWCKR(x) (((x)&0x0000003F)<<12) +#define MCF_LCDC_LGWCR_GW_RVS (0x00200000) +#define MCF_LCDC_LGWCR_GWE (0x00400000) +#define MCF_LCDC_LGWCR_GWCKE (0x00800000) +#define MCF_LCDC_LGWCR_GWAV(x) (((x)&0x000000FF)<<24) + +/* Bit definitions and macros for MCF_LCDC_LGWDCR */ +#define MCF_LCDC_LGWDCR_GWTM(x) (((x)&0x0000001F)<<0) +#define MCF_LCDC_LGWDCR_GWHM(x) (((x)&0x0000001F)<<16) +#define MCF_LCDC_LGWDCR_GWBT (0x80000000) + +/* Bit definitions and macros for MCF_LCDC_LSCR */ +#define MCF_LCDC_LSCR_PS_RISE_DELAY(x) (((x)&0x0000003F)<<26) +#define MCF_LCDC_LSCR_CLS_RISE_DELAY(x) (((x)&0x000000FF)<<16) +#define MCF_LCDC_LSCR_REV_TOGGLE_DELAY(x) (((x)&0x0000000F)<<8) +#define MCF_LCDC_LSCR_GRAY_2(x) (((x)&0x0000000F)<<4) +#define MCF_LCDC_LSCR_GRAY_1(x) (((x)&0x0000000F)<<0) + +/* Bit definitions and macros for MCF_LCDC_BPLUT_BASE */ +#define MCF_LCDC_BPLUT_BASE_BASE(x) (((x)&0xFFFFFFFF)<<0) + +/* Bit definitions and macros for MCF_LCDC_GWLUT_BASE */ +#define MCF_LCDC_GWLUT_BASE_BASE(x) (((x)&0xFFFFFFFF)<<0) + +/********************************************************************* + * + * Phase Locked Loop (PLL) + * + *********************************************************************/ + +/* Register read/write macros */ +#define MCF_PLL_PODR MCF_REG08(0xFC0C0000) +#define MCF_PLL_PLLCR MCF_REG08(0xFC0C0004) +#define MCF_PLL_PMDR MCF_REG08(0xFC0C0008) +#define MCF_PLL_PFDR MCF_REG08(0xFC0C000C) + +/* Bit definitions and macros for MCF_PLL_PODR */ +#define MCF_PLL_PODR_BUSDIV(x) (((x)&0x0F)<<0) +#define MCF_PLL_PODR_CPUDIV(x) (((x)&0x0F)<<4) + +/* Bit definitions and macros for MCF_PLL_PLLCR */ +#define MCF_PLL_PLLCR_DITHDEV(x) (((x)&0x07)<<0) +#define MCF_PLL_PLLCR_DITHEN (0x80) + +/* Bit definitions and macros for MCF_PLL_PMDR */ +#define MCF_PLL_PMDR_MODDIV(x) (((x)&0xFF)<<0) + +/* Bit definitions and macros for MCF_PLL_PFDR */ +#define MCF_PLL_PFDR_MFD(x) (((x)&0xFF)<<0) + +/********************************************************************* + * + * System Control Module Registers (SCM) + * + *********************************************************************/ + +/* Register read/write macros */ +#define MCF_SCM_MPR MCF_REG32(0xFC000000) +#define MCF_SCM_PACRA MCF_REG32(0xFC000020) +#define MCF_SCM_PACRB MCF_REG32(0xFC000024) +#define MCF_SCM_PACRC MCF_REG32(0xFC000028) +#define MCF_SCM_PACRD MCF_REG32(0xFC00002C) +#define MCF_SCM_PACRE MCF_REG32(0xFC000040) +#define MCF_SCM_PACRF MCF_REG32(0xFC000044) + +#define MCF_SCM_BCR MCF_REG32(0xFC040024) + +/********************************************************************* + * + * SDRAM Controller (SDRAMC) + * + *********************************************************************/ + +/* Register read/write macros */ +#define MCF_SDRAMC_SDMR MCF_REG32(0xFC0B8000) +#define MCF_SDRAMC_SDCR MCF_REG32(0xFC0B8004) +#define MCF_SDRAMC_SDCFG1 MCF_REG32(0xFC0B8008) +#define MCF_SDRAMC_SDCFG2 MCF_REG32(0xFC0B800C) +#define MCF_SDRAMC_LIMP_FIX MCF_REG32(0xFC0B8080) +#define MCF_SDRAMC_SDDS MCF_REG32(0xFC0B8100) +#define MCF_SDRAMC_SDCS0 MCF_REG32(0xFC0B8110) +#define MCF_SDRAMC_SDCS1 MCF_REG32(0xFC0B8114) +#define MCF_SDRAMC_SDCS2 MCF_REG32(0xFC0B8118) +#define MCF_SDRAMC_SDCS3 MCF_REG32(0xFC0B811C) +#define MCF_SDRAMC_SDCS(x) MCF_REG32(0xFC0B8110+((x)*0x004)) + +/* Bit definitions and macros for MCF_SDRAMC_SDMR */ +#define MCF_SDRAMC_SDMR_CMD (0x00010000) +#define MCF_SDRAMC_SDMR_AD(x) (((x)&0x00000FFF)<<18) +#define MCF_SDRAMC_SDMR_BNKAD(x) (((x)&0x00000003)<<30) +#define MCF_SDRAMC_SDMR_BNKAD_LMR (0x00000000) +#define MCF_SDRAMC_SDMR_BNKAD_LEMR (0x40000000) + +/* Bit definitions and macros for MCF_SDRAMC_SDCR */ +#define MCF_SDRAMC_SDCR_IPALL (0x00000002) +#define MCF_SDRAMC_SDCR_IREF (0x00000004) +#define MCF_SDRAMC_SDCR_DQS_OE(x) (((x)&0x0000000F)<<8) +#define MCF_SDRAMC_SDCR_PS(x) (((x)&0x00000003)<<12) +#define MCF_SDRAMC_SDCR_RCNT(x) (((x)&0x0000003F)<<16) +#define MCF_SDRAMC_SDCR_OE_RULE (0x00400000) +#define MCF_SDRAMC_SDCR_MUX(x) (((x)&0x00000003)<<24) +#define MCF_SDRAMC_SDCR_REF (0x10000000) +#define MCF_SDRAMC_SDCR_DDR (0x20000000) +#define MCF_SDRAMC_SDCR_CKE (0x40000000) +#define MCF_SDRAMC_SDCR_MODE_EN (0x80000000) +#define MCF_SDRAMC_SDCR_PS_16 (0x00002000) +#define MCF_SDRAMC_SDCR_PS_32 (0x00000000) + +/* Bit definitions and macros for MCF_SDRAMC_SDCFG1 */ +#define MCF_SDRAMC_SDCFG1_WTLAT(x) (((x)&0x00000007)<<4) +#define MCF_SDRAMC_SDCFG1_REF2ACT(x) (((x)&0x0000000F)<<8) +#define MCF_SDRAMC_SDCFG1_PRE2ACT(x) (((x)&0x00000007)<<12) +#define MCF_SDRAMC_SDCFG1_ACT2RW(x) (((x)&0x00000007)<<16) +#define MCF_SDRAMC_SDCFG1_RDLAT(x) (((x)&0x0000000F)<<20) +#define MCF_SDRAMC_SDCFG1_SWT2RD(x) (((x)&0x00000007)<<24) +#define MCF_SDRAMC_SDCFG1_SRD2RW(x) (((x)&0x0000000F)<<28) + +/* Bit definitions and macros for MCF_SDRAMC_SDCFG2 */ +#define MCF_SDRAMC_SDCFG2_BL(x) (((x)&0x0000000F)<<16) +#define MCF_SDRAMC_SDCFG2_BRD2WT(x) (((x)&0x0000000F)<<20) +#define MCF_SDRAMC_SDCFG2_BWT2RW(x) (((x)&0x0000000F)<<24) +#define MCF_SDRAMC_SDCFG2_BRD2PRE(x) (((x)&0x0000000F)<<28) + +/* Device Errata - LIMP mode work around */ +#define MCF_SDRAMC_REFRESH (0x40000000) + +/* Bit definitions and macros for MCF_SDRAMC_SDDS */ +#define MCF_SDRAMC_SDDS_SB_D(x) (((x)&0x00000003)<<0) +#define MCF_SDRAMC_SDDS_SB_S(x) (((x)&0x00000003)<<2) +#define MCF_SDRAMC_SDDS_SB_A(x) (((x)&0x00000003)<<4) +#define MCF_SDRAMC_SDDS_SB_C(x) (((x)&0x00000003)<<6) +#define MCF_SDRAMC_SDDS_SB_E(x) (((x)&0x00000003)<<8) + +/* Bit definitions and macros for MCF_SDRAMC_SDCS */ +#define MCF_SDRAMC_SDCS_CSSZ(x) (((x)&0x0000001F)<<0) +#define MCF_SDRAMC_SDCS_BASE(x) (((x)&0x00000FFF)<<20) +#define MCF_SDRAMC_SDCS_BA(x) ((x)&0xFFF00000) +#define MCF_SDRAMC_SDCS_CSSZ_DIABLE (0x00000000) +#define MCF_SDRAMC_SDCS_CSSZ_1MBYTE (0x00000013) +#define MCF_SDRAMC_SDCS_CSSZ_2MBYTE (0x00000014) +#define MCF_SDRAMC_SDCS_CSSZ_4MBYTE (0x00000015) +#define MCF_SDRAMC_SDCS_CSSZ_8MBYTE (0x00000016) +#define MCF_SDRAMC_SDCS_CSSZ_16MBYTE (0x00000017) +#define MCF_SDRAMC_SDCS_CSSZ_32MBYTE (0x00000018) +#define MCF_SDRAMC_SDCS_CSSZ_64MBYTE (0x00000019) +#define MCF_SDRAMC_SDCS_CSSZ_128MBYTE (0x0000001A) +#define MCF_SDRAMC_SDCS_CSSZ_256MBYTE (0x0000001B) +#define MCF_SDRAMC_SDCS_CSSZ_512MBYTE (0x0000001C) +#define MCF_SDRAMC_SDCS_CSSZ_1GBYTE (0x0000001D) +#define MCF_SDRAMC_SDCS_CSSZ_2GBYTE (0x0000001E) +#define MCF_SDRAMC_SDCS_CSSZ_4GBYTE (0x0000001F) + +/********************************************************************* + * + * FlexCAN module registers + * + *********************************************************************/ +#define MCF_FLEXCAN_BASEADDR(x) (0xFC020000+(x)*0x0800) +#define MCF_FLEXCAN_CANMCR(x) MCF_REG32(0xFC020000+(x)*0x0800+0x00) +#define MCF_FLEXCAN_CANCTRL(x) MCF_REG32(0xFC020000+(x)*0x0800+0x04) +#define MCF_FLEXCAN_TIMER(x) MCF_REG32(0xFC020000+(x)*0x0800+0x08) +#define MCF_FLEXCAN_RXGMASK(x) MCF_REG32(0xFC020000+(x)*0x0800+0x10) +#define MCF_FLEXCAN_RX14MASK(x) MCF_REG32(0xFC020000+(x)*0x0800+0x14) +#define MCF_FLEXCAN_RX15MASK(x) MCF_REG32(0xFC020000+(x)*0x0800+0x18) +#define MCF_FLEXCAN_ERRCNT(x) MCF_REG32(0xFC020000+(x)*0x0800+0x1C) +#define MCF_FLEXCAN_ERRSTAT(x) MCF_REG32(0xFC020000+(x)*0x0800+0x20) +#define MCF_FLEXCAN_IMASK(x) MCF_REG32(0xFC020000+(x)*0x0800+0x28) +#define MCF_FLEXCAN_IFLAG(x) MCF_REG32(0xFC020000+(x)*0x0800+0x30) + +#define MCF_FLEXCAN_MB_CNT(x,y) MCF_REG32(0xFC020080+(x)*0x0800+(y)*0x10+0x0) +#define MCF_FLEXCAN_MB_ID(x,y) MCF_REG32(0xFC020080+(x)*0x0800+(y)*0x10+0x4) +#define MCF_FLEXCAN_MB_DB(x,y,z) MCF_REG08(0xFC020080+(x)*0x0800+(y)*0x10+0x8+(z)*0x1) + +/* + * FlexCAN Module Configuration Register + */ +#define CANMCR_MDIS (0x80000000) +#define CANMCR_FRZ (0x40000000) +#define CANMCR_HALT (0x10000000) +#define CANMCR_SOFTRST (0x02000000) +#define CANMCR_FRZACK (0x01000000) +#define CANMCR_SUPV (0x00800000) +#define CANMCR_MAXMB(x) ((x)&0x0F) + +/* + * FlexCAN Control Register + */ +#define CANCTRL_PRESDIV(x) (((x)&0xFF)<<24) +#define CANCTRL_RJW(x) (((x)&0x03)<<22) +#define CANCTRL_PSEG1(x) (((x)&0x07)<<19) +#define CANCTRL_PSEG2(x) (((x)&0x07)<<16) +#define CANCTRL_BOFFMSK (0x00008000) +#define CANCTRL_ERRMSK (0x00004000) +#define CANCTRL_CLKSRC (0x00002000) +#define CANCTRL_LPB (0x00001000) +#define CANCTRL_SAMP (0x00000080) +#define CANCTRL_BOFFREC (0x00000040) +#define CANCTRL_TSYNC (0x00000020) +#define CANCTRL_LBUF (0x00000010) +#define CANCTRL_LOM (0x00000008) +#define CANCTRL_PROPSEG(x) ((x)&0x07) + +/* + * FlexCAN Error Counter Register + */ +#define ERRCNT_RXECTR(x) (((x)&0xFF)<<8) +#define ERRCNT_TXECTR(x) ((x)&0xFF) + +/* + * FlexCAN Error and Status Register + */ +#define ERRSTAT_BITERR(x) (((x)&0x03)<<14) +#define ERRSTAT_ACKERR (0x00002000) +#define ERRSTAT_CRCERR (0x00001000) +#define ERRSTAT_FRMERR (0x00000800) +#define ERRSTAT_STFERR (0x00000400) +#define ERRSTAT_TXWRN (0x00000200) +#define ERRSTAT_RXWRN (0x00000100) +#define ERRSTAT_IDLE (0x00000080) +#define ERRSTAT_TXRX (0x00000040) +#define ERRSTAT_FLTCONF(x) (((x)&0x03)<<4) +#define ERRSTAT_BOFFINT (0x00000004) +#define ERRSTAT_ERRINT (0x00000002) + +/* + * Interrupt Mask Register + */ +#define IMASK_BUF15M (0x8000) +#define IMASK_BUF14M (0x4000) +#define IMASK_BUF13M (0x2000) +#define IMASK_BUF12M (0x1000) +#define IMASK_BUF11M (0x0800) +#define IMASK_BUF10M (0x0400) +#define IMASK_BUF9M (0x0200) +#define IMASK_BUF8M (0x0100) +#define IMASK_BUF7M (0x0080) +#define IMASK_BUF6M (0x0040) +#define IMASK_BUF5M (0x0020) +#define IMASK_BUF4M (0x0010) +#define IMASK_BUF3M (0x0008) +#define IMASK_BUF2M (0x0004) +#define IMASK_BUF1M (0x0002) +#define IMASK_BUF0M (0x0001) +#define IMASK_BUFnM(x) (0x1<<(x)) +#define IMASK_BUFF_ENABLE_ALL (0x1111) +#define IMASK_BUFF_DISABLE_ALL (0x0000) + +/* + * Interrupt Flag Register + */ +#define IFLAG_BUF15M (0x8000) +#define IFLAG_BUF14M (0x4000) +#define IFLAG_BUF13M (0x2000) +#define IFLAG_BUF12M (0x1000) +#define IFLAG_BUF11M (0x0800) +#define IFLAG_BUF10M (0x0400) +#define IFLAG_BUF9M (0x0200) +#define IFLAG_BUF8M (0x0100) +#define IFLAG_BUF7M (0x0080) +#define IFLAG_BUF6M (0x0040) +#define IFLAG_BUF5M (0x0020) +#define IFLAG_BUF4M (0x0010) +#define IFLAG_BUF3M (0x0008) +#define IFLAG_BUF2M (0x0004) +#define IFLAG_BUF1M (0x0002) +#define IFLAG_BUF0M (0x0001) +#define IFLAG_BUFF_SET_ALL (0xFFFF) +#define IFLAG_BUFF_CLEAR_ALL (0x0000) +#define IFLAG_BUFnM(x) (0x1<<(x)) + +/* + * Message Buffers + */ +#define MB_CNT_CODE(x) (((x)&0x0F)<<24) +#define MB_CNT_SRR (0x00400000) +#define MB_CNT_IDE (0x00200000) +#define MB_CNT_RTR (0x00100000) +#define MB_CNT_LENGTH(x) (((x)&0x0F)<<16) +#define MB_CNT_TIMESTAMP(x) ((x)&0xFFFF) +#define MB_ID_STD(x) (((x)&0x07FF)<<18) +#define MB_ID_EXT(x) ((x)&0x3FFFF) + +/********************************************************************* + * + * Edge Port Module (EPORT) + * + *********************************************************************/ + +/* Register read/write macros */ +#define MCF_EPORT_EPPAR MCF_REG16(0xFC094000) +#define MCF_EPORT_EPDDR MCF_REG08(0xFC094002) +#define MCF_EPORT_EPIER MCF_REG08(0xFC094003) +#define MCF_EPORT_EPDR MCF_REG08(0xFC094004) +#define MCF_EPORT_EPPDR MCF_REG08(0xFC094005) +#define MCF_EPORT_EPFR MCF_REG08(0xFC094006) + +/* Bit definitions and macros for MCF_EPORT_EPPAR */ +#define MCF_EPORT_EPPAR_EPPA1(x) (((x)&0x0003)<<2) +#define MCF_EPORT_EPPAR_EPPA2(x) (((x)&0x0003)<<4) +#define MCF_EPORT_EPPAR_EPPA3(x) (((x)&0x0003)<<6) +#define MCF_EPORT_EPPAR_EPPA4(x) (((x)&0x0003)<<8) +#define MCF_EPORT_EPPAR_EPPA5(x) (((x)&0x0003)<<10) +#define MCF_EPORT_EPPAR_EPPA6(x) (((x)&0x0003)<<12) +#define MCF_EPORT_EPPAR_EPPA7(x) (((x)&0x0003)<<14) +#define MCF_EPORT_EPPAR_LEVEL (0) +#define MCF_EPORT_EPPAR_RISING (1) +#define MCF_EPORT_EPPAR_FALLING (2) +#define MCF_EPORT_EPPAR_BOTH (3) +#define MCF_EPORT_EPPAR_EPPA7_LEVEL (0x0000) +#define MCF_EPORT_EPPAR_EPPA7_RISING (0x4000) +#define MCF_EPORT_EPPAR_EPPA7_FALLING (0x8000) +#define MCF_EPORT_EPPAR_EPPA7_BOTH (0xC000) +#define MCF_EPORT_EPPAR_EPPA6_LEVEL (0x0000) +#define MCF_EPORT_EPPAR_EPPA6_RISING (0x1000) +#define MCF_EPORT_EPPAR_EPPA6_FALLING (0x2000) +#define MCF_EPORT_EPPAR_EPPA6_BOTH (0x3000) +#define MCF_EPORT_EPPAR_EPPA5_LEVEL (0x0000) +#define MCF_EPORT_EPPAR_EPPA5_RISING (0x0400) +#define MCF_EPORT_EPPAR_EPPA5_FALLING (0x0800) +#define MCF_EPORT_EPPAR_EPPA5_BOTH (0x0C00) +#define MCF_EPORT_EPPAR_EPPA4_LEVEL (0x0000) +#define MCF_EPORT_EPPAR_EPPA4_RISING (0x0100) +#define MCF_EPORT_EPPAR_EPPA4_FALLING (0x0200) +#define MCF_EPORT_EPPAR_EPPA4_BOTH (0x0300) +#define MCF_EPORT_EPPAR_EPPA3_LEVEL (0x0000) +#define MCF_EPORT_EPPAR_EPPA3_RISING (0x0040) +#define MCF_EPORT_EPPAR_EPPA3_FALLING (0x0080) +#define MCF_EPORT_EPPAR_EPPA3_BOTH (0x00C0) +#define MCF_EPORT_EPPAR_EPPA2_LEVEL (0x0000) +#define MCF_EPORT_EPPAR_EPPA2_RISING (0x0010) +#define MCF_EPORT_EPPAR_EPPA2_FALLING (0x0020) +#define MCF_EPORT_EPPAR_EPPA2_BOTH (0x0030) +#define MCF_EPORT_EPPAR_EPPA1_LEVEL (0x0000) +#define MCF_EPORT_EPPAR_EPPA1_RISING (0x0004) +#define MCF_EPORT_EPPAR_EPPA1_FALLING (0x0008) +#define MCF_EPORT_EPPAR_EPPA1_BOTH (0x000C) + +/* Bit definitions and macros for MCF_EPORT_EPDDR */ +#define MCF_EPORT_EPDDR_EPDD1 (0x02) +#define MCF_EPORT_EPDDR_EPDD2 (0x04) +#define MCF_EPORT_EPDDR_EPDD3 (0x08) +#define MCF_EPORT_EPDDR_EPDD4 (0x10) +#define MCF_EPORT_EPDDR_EPDD5 (0x20) +#define MCF_EPORT_EPDDR_EPDD6 (0x40) +#define MCF_EPORT_EPDDR_EPDD7 (0x80) + +/* Bit definitions and macros for MCF_EPORT_EPIER */ +#define MCF_EPORT_EPIER_EPIE1 (0x02) +#define MCF_EPORT_EPIER_EPIE2 (0x04) +#define MCF_EPORT_EPIER_EPIE3 (0x08) +#define MCF_EPORT_EPIER_EPIE4 (0x10) +#define MCF_EPORT_EPIER_EPIE5 (0x20) +#define MCF_EPORT_EPIER_EPIE6 (0x40) +#define MCF_EPORT_EPIER_EPIE7 (0x80) + +/* Bit definitions and macros for MCF_EPORT_EPDR */ +#define MCF_EPORT_EPDR_EPD1 (0x02) +#define MCF_EPORT_EPDR_EPD2 (0x04) +#define MCF_EPORT_EPDR_EPD3 (0x08) +#define MCF_EPORT_EPDR_EPD4 (0x10) +#define MCF_EPORT_EPDR_EPD5 (0x20) +#define MCF_EPORT_EPDR_EPD6 (0x40) +#define MCF_EPORT_EPDR_EPD7 (0x80) + +/* Bit definitions and macros for MCF_EPORT_EPPDR */ +#define MCF_EPORT_EPPDR_EPPD1 (0x02) +#define MCF_EPORT_EPPDR_EPPD2 (0x04) +#define MCF_EPORT_EPPDR_EPPD3 (0x08) +#define MCF_EPORT_EPPDR_EPPD4 (0x10) +#define MCF_EPORT_EPPDR_EPPD5 (0x20) +#define MCF_EPORT_EPPDR_EPPD6 (0x40) +#define MCF_EPORT_EPPDR_EPPD7 (0x80) + +/* Bit definitions and macros for MCF_EPORT_EPFR */ +#define MCF_EPORT_EPFR_EPF1 (0x02) +#define MCF_EPORT_EPFR_EPF2 (0x04) +#define MCF_EPORT_EPFR_EPF3 (0x08) +#define MCF_EPORT_EPFR_EPF4 (0x10) +#define MCF_EPORT_EPFR_EPF5 (0x20) +#define MCF_EPORT_EPFR_EPF6 (0x40) +#define MCF_EPORT_EPFR_EPF7 (0x80) + +/********************************************************************/ +#endif /* m532xsim_h */ diff --git a/arch/m68k/include/asm/m5407sim.h b/arch/m68k/include/asm/m5407sim.h new file mode 100644 index 00000000000..cc22c4a5300 --- /dev/null +++ b/arch/m68k/include/asm/m5407sim.h @@ -0,0 +1,157 @@ +/****************************************************************************/ + +/* + * m5407sim.h -- ColdFire 5407 System Integration Module support. + * + * (C) Copyright 2000, Lineo (www.lineo.com) + * (C) Copyright 1999, Moreton Bay Ventures Pty Ltd. + * + * Modified by David W. Miller for the MCF5307 Eval Board. + */ + +/****************************************************************************/ +#ifndef m5407sim_h +#define m5407sim_h +/****************************************************************************/ + +/* + * Define the 5407 SIM register set addresses. + */ +#define MCFSIM_RSR 0x00 /* Reset Status reg (r/w) */ +#define MCFSIM_SYPCR 0x01 /* System Protection reg (r/w)*/ +#define MCFSIM_SWIVR 0x02 /* SW Watchdog intr reg (r/w) */ +#define MCFSIM_SWSR 0x03 /* SW Watchdog service (r/w) */ +#define MCFSIM_PAR 0x04 /* Pin Assignment reg (r/w) */ +#define MCFSIM_IRQPAR 0x06 /* Interrupt Assignment reg (r/w) */ +#define MCFSIM_PLLCR 0x08 /* PLL Controll Reg*/ +#define MCFSIM_MPARK 0x0C /* BUS Master Control Reg*/ +#define MCFSIM_IPR 0x40 /* Interrupt Pend reg (r/w) */ +#define MCFSIM_IMR 0x44 /* Interrupt Mask reg (r/w) */ +#define MCFSIM_AVR 0x4b /* Autovector Ctrl reg (r/w) */ +#define MCFSIM_ICR0 0x4c /* Intr Ctrl reg 0 (r/w) */ +#define MCFSIM_ICR1 0x4d /* Intr Ctrl reg 1 (r/w) */ +#define MCFSIM_ICR2 0x4e /* Intr Ctrl reg 2 (r/w) */ +#define MCFSIM_ICR3 0x4f /* Intr Ctrl reg 3 (r/w) */ +#define MCFSIM_ICR4 0x50 /* Intr Ctrl reg 4 (r/w) */ +#define MCFSIM_ICR5 0x51 /* Intr Ctrl reg 5 (r/w) */ +#define MCFSIM_ICR6 0x52 /* Intr Ctrl reg 6 (r/w) */ +#define MCFSIM_ICR7 0x53 /* Intr Ctrl reg 7 (r/w) */ +#define MCFSIM_ICR8 0x54 /* Intr Ctrl reg 8 (r/w) */ +#define MCFSIM_ICR9 0x55 /* Intr Ctrl reg 9 (r/w) */ +#define MCFSIM_ICR10 0x56 /* Intr Ctrl reg 10 (r/w) */ +#define MCFSIM_ICR11 0x57 /* Intr Ctrl reg 11 (r/w) */ + +#define MCFSIM_CSAR0 0x80 /* CS 0 Address 0 reg (r/w) */ +#define MCFSIM_CSMR0 0x84 /* CS 0 Mask 0 reg (r/w) */ +#define MCFSIM_CSCR0 0x8a /* CS 0 Control reg (r/w) */ +#define MCFSIM_CSAR1 0x8c /* CS 1 Address reg (r/w) */ +#define MCFSIM_CSMR1 0x90 /* CS 1 Mask reg (r/w) */ +#define MCFSIM_CSCR1 0x96 /* CS 1 Control reg (r/w) */ + +#define MCFSIM_CSAR2 0x98 /* CS 2 Address reg (r/w) */ +#define MCFSIM_CSMR2 0x9c /* CS 2 Mask reg (r/w) */ +#define MCFSIM_CSCR2 0xa2 /* CS 2 Control reg (r/w) */ +#define MCFSIM_CSAR3 0xa4 /* CS 3 Address reg (r/w) */ +#define MCFSIM_CSMR3 0xa8 /* CS 3 Mask reg (r/w) */ +#define MCFSIM_CSCR3 0xae /* CS 3 Control reg (r/w) */ +#define MCFSIM_CSAR4 0xb0 /* CS 4 Address reg (r/w) */ +#define MCFSIM_CSMR4 0xb4 /* CS 4 Mask reg (r/w) */ +#define MCFSIM_CSCR4 0xba /* CS 4 Control reg (r/w) */ +#define MCFSIM_CSAR5 0xbc /* CS 5 Address reg (r/w) */ +#define MCFSIM_CSMR5 0xc0 /* CS 5 Mask reg (r/w) */ +#define MCFSIM_CSCR5 0xc6 /* CS 5 Control reg (r/w) */ +#define MCFSIM_CSAR6 0xc8 /* CS 6 Address reg (r/w) */ +#define MCFSIM_CSMR6 0xcc /* CS 6 Mask reg (r/w) */ +#define MCFSIM_CSCR6 0xd2 /* CS 6 Control reg (r/w) */ +#define MCFSIM_CSAR7 0xd4 /* CS 7 Address reg (r/w) */ +#define MCFSIM_CSMR7 0xd8 /* CS 7 Mask reg (r/w) */ +#define MCFSIM_CSCR7 0xde /* CS 7 Control reg (r/w) */ + +#define MCFSIM_DCR 0x100 /* DRAM Control reg (r/w) */ +#define MCFSIM_DACR0 0x108 /* DRAM 0 Addr and Ctrl (r/w) */ +#define MCFSIM_DMR0 0x10c /* DRAM 0 Mask reg (r/w) */ +#define MCFSIM_DACR1 0x110 /* DRAM 1 Addr and Ctrl (r/w) */ +#define MCFSIM_DMR1 0x114 /* DRAM 1 Mask reg (r/w) */ + +#define MCFSIM_PADDR 0x244 /* Parallel Direction (r/w) */ +#define MCFSIM_PADAT 0x248 /* Parallel Data (r/w) */ + + +/* + * Some symbol defines for the above... + */ +#define MCFSIM_SWDICR MCFSIM_ICR0 /* Watchdog timer ICR */ +#define MCFSIM_TIMER1ICR MCFSIM_ICR1 /* Timer 1 ICR */ +#define MCFSIM_TIMER2ICR MCFSIM_ICR2 /* Timer 2 ICR */ +#define MCFSIM_UART1ICR MCFSIM_ICR4 /* UART 1 ICR */ +#define MCFSIM_UART2ICR MCFSIM_ICR5 /* UART 2 ICR */ +#define MCFSIM_DMA0ICR MCFSIM_ICR6 /* DMA 0 ICR */ +#define MCFSIM_DMA1ICR MCFSIM_ICR7 /* DMA 1 ICR */ +#define MCFSIM_DMA2ICR MCFSIM_ICR8 /* DMA 2 ICR */ +#define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */ + +/* + * Macro to set IMR register. It is 32 bits on the 5407. + */ +#define mcf_getimr() \ + *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) + +#define mcf_setimr(imr) \ + *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr); + +#define mcf_getipr() \ + *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR)) + + +/* + * Some symbol defines for the Parallel Port Pin Assignment Register + */ +#define MCFSIM_PAR_DREQ0 0x40 /* Set to select DREQ0 input */ + /* Clear to select par I/O */ +#define MCFSIM_PAR_DREQ1 0x20 /* Select DREQ1 input */ + /* Clear to select par I/O */ + +/* + * Defines for the IRQPAR Register + */ +#define IRQ5_LEVEL4 0x80 +#define IRQ3_LEVEL6 0x40 +#define IRQ1_LEVEL2 0x20 + + +/* + * Define the Cache register flags. + */ +#define CACR_DEC 0x80000000 /* Enable data cache */ +#define CACR_DWP 0x40000000 /* Data write protection */ +#define CACR_DESB 0x20000000 /* Enable data store buffer */ +#define CACR_DDPI 0x10000000 /* Disable CPUSHL */ +#define CACR_DHCLK 0x08000000 /* Half data cache lock mode */ +#define CACR_DDCM_WT 0x00000000 /* Write through cache*/ +#define CACR_DDCM_CP 0x02000000 /* Copyback cache */ +#define CACR_DDCM_P 0x04000000 /* No cache, precise */ +#define CACR_DDCM_IMP 0x06000000 /* No cache, imprecise */ +#define CACR_DCINVA 0x01000000 /* Invalidate data cache */ +#define CACR_BEC 0x00080000 /* Enable branch cache */ +#define CACR_BCINVA 0x00040000 /* Invalidate branch cache */ +#define CACR_IEC 0x00008000 /* Enable instruction cache */ +#define CACR_DNFB 0x00002000 /* Inhibited fill buffer */ +#define CACR_IDPI 0x00001000 /* Disable CPUSHL */ +#define CACR_IHLCK 0x00000800 /* Intruction cache half lock */ +#define CACR_IDCM 0x00000400 /* Intruction cache inhibit */ +#define CACR_ICINVA 0x00000100 /* Invalidate instr cache */ + +#define ACR_BASE_POS 24 /* Address Base */ +#define ACR_MASK_POS 16 /* Address Mask */ +#define ACR_ENABLE 0x00008000 /* Enable address */ +#define ACR_USER 0x00000000 /* User mode access only */ +#define ACR_SUPER 0x00002000 /* Supervisor mode only */ +#define ACR_ANY 0x00004000 /* Match any access mode */ +#define ACR_CM_WT 0x00000000 /* Write through mode */ +#define ACR_CM_CP 0x00000020 /* Copyback mode */ +#define ACR_CM_OFF_PRE 0x00000040 /* No cache, precise */ +#define ACR_CM_OFF_IMP 0x00000060 /* No cache, imprecise */ +#define ACR_WPROTECT 0x00000004 /* Write protect */ + +/****************************************************************************/ +#endif /* m5407sim_h */ diff --git a/arch/m68k/include/asm/m68360.h b/arch/m68k/include/asm/m68360.h new file mode 100644 index 00000000000..eb7d39ef285 --- /dev/null +++ b/arch/m68k/include/asm/m68360.h @@ -0,0 +1,13 @@ +#include "m68360_regs.h" +#include "m68360_pram.h" +#include "m68360_quicc.h" +#include "m68360_enet.h" + +#ifdef CONFIG_M68360 + +#define CPM_INTERRUPT 4 + +/* see MC68360 User's Manual, p. 7-377 */ +#define CPM_VECTOR_BASE 0x04 /* 3 MSbits of CPM vector */ + +#endif /* CONFIG_M68360 */ diff --git a/arch/m68k/include/asm/m68360_enet.h b/arch/m68k/include/asm/m68360_enet.h new file mode 100644 index 00000000000..c36f4d05920 --- /dev/null +++ b/arch/m68k/include/asm/m68360_enet.h @@ -0,0 +1,177 @@ +/*********************************** + * $Id: m68360_enet.h,v 1.1 2002/03/02 15:01:07 gerg Exp $ + *********************************** + * + *************************************** + * Definitions for the ETHERNET controllers + *************************************** + */ + +#ifndef __ETHER_H +#define __ETHER_H + +#include "quicc_simple.h" + +/* + * transmit BD's + */ +#define T_R 0x8000 /* ready bit */ +#define E_T_PAD 0x4000 /* short frame padding */ +#define T_W 0x2000 /* wrap bit */ +#define T_I 0x1000 /* interrupt on completion */ +#define T_L 0x0800 /* last in frame */ +#define T_TC 0x0400 /* transmit CRC (when last) */ + +#define T_DEF 0x0200 /* defer indication */ +#define T_HB 0x0100 /* heartbeat */ +#define T_LC 0x0080 /* error: late collision */ +#define T_RL 0x0040 /* error: retransmission limit */ +#define T_RC 0x003c /* retry count */ +#define T_UN 0x0002 /* error: underrun */ +#define T_CSL 0x0001 /* carier sense lost */ +#define T_ERROR (T_HB | T_LC | T_RL | T_UN | T_CSL) + +/* + * receive BD's + */ +#define R_E 0x8000 /* buffer empty */ +#define R_W 0x2000 /* wrap bit */ +#define R_I 0x1000 /* interrupt on reception */ +#define R_L 0x0800 /* last BD in frame */ +#define R_F 0x0400 /* first BD in frame */ +#define R_M 0x0100 /* received because of promisc. mode */ + +#define R_LG 0x0020 /* frame too long */ +#define R_NO 0x0010 /* non-octet aligned */ +#define R_SH 0x0008 /* short frame */ +#define R_CR 0x0004 /* receive CRC error */ +#define R_OV 0x0002 /* receive overrun */ +#define R_CL 0x0001 /* collision */ +#define ETHER_R_ERROR (R_LG | R_NO | R_SH | R_CR | R_OV | R_CL) + + +/* + * ethernet interrupts + */ +#define ETHERNET_GRA 0x0080 /* graceful stop complete */ +#define ETHERNET_TXE 0x0010 /* transmit error */ +#define ETHERNET_RXF 0x0008 /* receive frame */ +#define ETHERNET_BSY 0x0004 /* busy condition */ +#define ETHERNET_TXB 0x0002 /* transmit buffer */ +#define ETHERNET_RXB 0x0001 /* receive buffer */ + +/* + * ethernet protocol specific mode register (PSMR) + */ +#define ETHER_HBC 0x8000 /* heartbeat checking */ +#define ETHER_FC 0x4000 /* force collision */ +#define ETHER_RSH 0x2000 /* receive short frames */ +#define ETHER_IAM 0x1000 /* individual address mode */ +#define ETHER_CRC_32 (0x2<<10) /* Enable CRC */ +#define ETHER_PRO 0x0200 /* promiscuous */ +#define ETHER_BRO 0x0100 /* broadcast address */ +#define ETHER_SBT 0x0080 /* stop backoff timer */ +#define ETHER_LPB 0x0040 /* Loop Back Mode */ +#define ETHER_SIP 0x0020 /* sample input pins */ +#define ETHER_LCW 0x0010 /* late collision window */ +#define ETHER_NIB_13 (0x0<<1) /* # of ignored bits 13 */ +#define ETHER_NIB_14 (0x1<<1) /* # of ignored bits 14 */ +#define ETHER_NIB_15 (0x2<<1) /* # of ignored bits 15 */ +#define ETHER_NIB_16 (0x3<<1) /* # of ignored bits 16 */ +#define ETHER_NIB_21 (0x4<<1) /* # of ignored bits 21 */ +#define ETHER_NIB_22 (0x5<<1) /* # of ignored bits 22 */ +#define ETHER_NIB_23 (0x6<<1) /* # of ignored bits 23 */ +#define ETHER_NIB_24 (0x7<<1) /* # of ignored bits 24 */ + +/* + * ethernet specific parameters + */ +#define CRC_WORD 4 /* Length in bytes of CRC */ +#define C_PRES 0xffffffff /* preform 32 bit CRC */ +#define C_MASK 0xdebb20e3 /* comply with 32 bit CRC */ +#define CRCEC 0x00000000 +#define ALEC 0x00000000 +#define DISFC 0x00000000 +#define PADS 0x00000000 +#define RET_LIM 0x000f /* retry 15 times to send a frame before interrupt */ +#define ETH_MFLR 0x05ee /* 1518 max frame size */ +#define MINFLR 0x0040 /* Minimum frame size 64 */ +#define MAXD1 0x05ee /* Max dma count 1518 */ +#define MAXD2 0x05ee +#define GADDR1 0x00000000 /* Clear group address */ +#define GADDR2 0x00000000 +#define GADDR3 0x00000000 +#define GADDR4 0x00000000 +#define P_PER 0x00000000 /*not used */ +#define IADDR1 0x00000000 /* Individual hash table not used */ +#define IADDR2 0x00000000 +#define IADDR3 0x00000000 +#define IADDR4 0x00000000 +#define TADDR_H 0x00000000 /* clear this regs */ +#define TADDR_M 0x00000000 +#define TADDR_L 0x00000000 + +/* SCC Parameter Ram */ +#define RFCR 0x18 /* normal operation */ +#define TFCR 0x18 /* normal operation */ +#define E_MRBLR 1518 /* Max ethernet frame length */ + +/* + * ethernet specific structure + */ +typedef union { + unsigned char b[6]; + struct { + unsigned short high; + unsigned short middl; + unsigned short low; + } w; +} ETHER_ADDR; + +typedef struct { + int max_frame_length; + int promisc_mode; + int reject_broadcast; + ETHER_ADDR phys_adr; +} ETHER_SPECIFIC; + +typedef struct { + ETHER_ADDR dst_addr; + ETHER_ADDR src_addr; + unsigned short type_or_len; + unsigned char data[1]; +} ETHER_FRAME; + +#define MAX_DATALEN 1500 +typedef struct { + ETHER_ADDR dst_addr; + ETHER_ADDR src_addr; + unsigned short type_or_len; + unsigned char data[MAX_DATALEN]; + unsigned char fcs[CRC_WORD]; +} ETHER_MAX_FRAME; + + +/* + * Internal ethernet function prototypes + */ +void ether_interrupt(int scc_num); +/* mleslie: debug */ +/* static void ethernet_rx_internal(int scc_num); */ +/* static void ethernet_tx_internal(int scc_num); */ + +/* + * User callable routines prototypes (ethernet specific) + */ +void ethernet_init(int scc_number, + alloc_routine *alloc_buffer, + free_routine *free_buffer, + store_rx_buffer_routine *store_rx_buffer, + handle_tx_error_routine *handle_tx_error, + handle_rx_error_routine *handle_rx_error, + handle_lost_error_routine *handle_lost_error, + ETHER_SPECIFIC *ether_spec); +int ethernet_tx(int scc_number, void *buf, int length); + +#endif + diff --git a/arch/m68k/include/asm/m68360_pram.h b/arch/m68k/include/asm/m68360_pram.h new file mode 100644 index 00000000000..e6088bbce93 --- /dev/null +++ b/arch/m68k/include/asm/m68360_pram.h @@ -0,0 +1,431 @@ +/*********************************** + * $Id: m68360_pram.h,v 1.1 2002/03/02 15:01:07 gerg Exp $ + *********************************** + * + *************************************** + * Definitions of the parameter area RAM. + * Note that different structures are overlaid + * at the same offsets for the different modes + * of operation. + *************************************** + */ + +#ifndef __PRAM_H +#define __PRAM_H + +/* Time slot assignment table */ +#define VALID_SLOT 0x8000 +#define WRAP_SLOT 0x4000 + +/***************************************************************** + Global Multichannel parameter RAM +*****************************************************************/ +struct global_multi_pram { + /* + * Global Multichannel parameter RAM + */ + unsigned long mcbase; /* Multichannel Base pointer */ + unsigned short qmcstate; /* Multichannel Controller state */ + unsigned short mrblr; /* Maximum Receive Buffer Length */ + unsigned short tx_s_ptr; /* TSTATx Pointer */ + unsigned short rxptr; /* Current Time slot entry in TSATRx */ + unsigned short grfthr; /* Global Receive frame threshold */ + unsigned short grfcnt; /* Global Receive Frame Count */ + unsigned long intbase; /* Multichannel Base address */ + unsigned long iintptr; /* Pointer to interrupt queue */ + unsigned short rx_s_ptr; /* TSTARx Pointer */ + + unsigned short txptr; /* Current Time slot entry in TSATTx */ + unsigned long c_mask32; /* CRC Constant (debb20e3) */ + unsigned short tsatrx[32]; /* Time Slot Assignment Table Rx */ + unsigned short tsattx[32]; /* Time Slot Assignment Table Tx */ + unsigned short c_mask16; /* CRC Constant (f0b8) */ +}; + +/***************************************************************** + Quicc32 HDLC parameter RAM +*****************************************************************/ +struct quicc32_pram { + + unsigned short tbase; /* Tx Buffer Descriptors Base Address */ + unsigned short chamr; /* Channel Mode Register */ + unsigned long tstate; /* Tx Internal State */ + unsigned long txintr; /* Tx Internal Data Pointer */ + unsigned short tbptr; /* Tx Buffer Descriptor Pointer */ + unsigned short txcntr; /* Tx Internal Byte Count */ + unsigned long tupack; /* (Tx Temp) */ + unsigned long zistate; /* Zero Insertion machine state */ + unsigned long tcrc; /* Temp Transmit CRC */ + unsigned short intmask; /* Channel's interrupt mask flags */ + unsigned short bdflags; + unsigned short rbase; /* Rx Buffer Descriptors Base Address */ + unsigned short mflr; /* Max Frame Length Register */ + unsigned long rstate; /* Rx Internal State */ + unsigned long rxintr; /* Rx Internal Data Pointer */ + unsigned short rbptr; /* Rx Buffer Descriptor Pointer */ + unsigned short rxbyc; /* Rx Internal Byte Count */ + unsigned long rpack; /* (Rx Temp) */ + unsigned long zdstate; /* Zero Deletion machine state */ + unsigned long rcrc; /* Temp Transmit CRC */ + unsigned short maxc; /* Max_length counter */ + unsigned short tmp_mb; /* Temp */ +}; + + +/***************************************************************** + HDLC parameter RAM +*****************************************************************/ + +struct hdlc_pram { + /* + * SCC parameter RAM + */ + unsigned short rbase; /* RX BD base address */ + unsigned short tbase; /* TX BD base address */ + unsigned char rfcr; /* Rx function code */ + unsigned char tfcr; /* Tx function code */ + unsigned short mrblr; /* Rx buffer length */ + unsigned long rstate; /* Rx internal state */ + unsigned long rptr; /* Rx internal data pointer */ + unsigned short rbptr; /* rb BD Pointer */ + unsigned short rcount; /* Rx internal byte count */ + unsigned long rtemp; /* Rx temp */ + unsigned long tstate; /* Tx internal state */ + unsigned long tptr; /* Tx internal data pointer */ + unsigned short tbptr; /* Tx BD pointer */ + unsigned short tcount; /* Tx byte count */ + unsigned long ttemp; /* Tx temp */ + unsigned long rcrc; /* temp receive CRC */ + unsigned long tcrc; /* temp transmit CRC */ + + /* + * HDLC specific parameter RAM + */ + unsigned char RESERVED1[4]; /* Reserved area */ + unsigned long c_mask; /* CRC constant */ + unsigned long c_pres; /* CRC preset */ + unsigned short disfc; /* discarded frame counter */ + unsigned short crcec; /* CRC error counter */ + unsigned short abtsc; /* abort sequence counter */ + unsigned short nmarc; /* nonmatching address rx cnt */ + unsigned short retrc; /* frame retransmission cnt */ + unsigned short mflr; /* maximum frame length reg */ + unsigned short max_cnt; /* maximum length counter */ + unsigned short rfthr; /* received frames threshold */ + unsigned short rfcnt; /* received frames count */ + unsigned short hmask; /* user defined frm addr mask */ + unsigned short haddr1; /* user defined frm address 1 */ + unsigned short haddr2; /* user defined frm address 2 */ + unsigned short haddr3; /* user defined frm address 3 */ + unsigned short haddr4; /* user defined frm address 4 */ + unsigned short tmp; /* temp */ + unsigned short tmp_mb; /* temp */ +}; + + + +/***************************************************************** + UART parameter RAM +*****************************************************************/ + +/* + * bits in uart control characters table + */ +#define CC_INVALID 0x8000 /* control character is valid */ +#define CC_REJ 0x4000 /* don't store char in buffer */ +#define CC_CHAR 0x00ff /* control character */ + +/* UART */ +struct uart_pram { + /* + * SCC parameter RAM + */ + unsigned short rbase; /* RX BD base address */ + unsigned short tbase; /* TX BD base address */ + unsigned char rfcr; /* Rx function code */ + unsigned char tfcr; /* Tx function code */ + unsigned short mrblr; /* Rx buffer length */ + unsigned long rstate; /* Rx internal state */ + unsigned long rptr; /* Rx internal data pointer */ + unsigned short rbptr; /* rb BD Pointer */ + unsigned short rcount; /* Rx internal byte count */ + unsigned long rx_temp; /* Rx temp */ + unsigned long tstate; /* Tx internal state */ + unsigned long tptr; /* Tx internal data pointer */ + unsigned short tbptr; /* Tx BD pointer */ + unsigned short tcount; /* Tx byte count */ + unsigned long ttemp; /* Tx temp */ + unsigned long rcrc; /* temp receive CRC */ + unsigned long tcrc; /* temp transmit CRC */ + + /* + * UART specific parameter RAM + */ + unsigned char RESERVED1[8]; /* Reserved area */ + unsigned short max_idl; /* maximum idle characters */ + unsigned short idlc; /* rx idle counter (internal) */ + unsigned short brkcr; /* break count register */ + + unsigned short parec; /* Rx parity error counter */ + unsigned short frmer; /* Rx framing error counter */ + unsigned short nosec; /* Rx noise counter */ + unsigned short brkec; /* Rx break character counter */ + unsigned short brkln; /* Reaceive break length */ + + unsigned short uaddr1; /* address character 1 */ + unsigned short uaddr2; /* address character 2 */ + unsigned short rtemp; /* temp storage */ + unsigned short toseq; /* Tx out of sequence char */ + unsigned short cc[8]; /* Rx control characters */ + unsigned short rccm; /* Rx control char mask */ + unsigned short rccr; /* Rx control char register */ + unsigned short rlbc; /* Receive last break char */ +}; + + + +/***************************************************************** + BISYNC parameter RAM +*****************************************************************/ + +struct bisync_pram { + /* + * SCC parameter RAM + */ + unsigned short rbase; /* RX BD base address */ + unsigned short tbase; /* TX BD base address */ + unsigned char rfcr; /* Rx function code */ + unsigned char tfcr; /* Tx function code */ + unsigned short mrblr; /* Rx buffer length */ + unsigned long rstate; /* Rx internal state */ + unsigned long rptr; /* Rx internal data pointer */ + unsigned short rbptr; /* rb BD Pointer */ + unsigned short rcount; /* Rx internal byte count */ + unsigned long rtemp; /* Rx temp */ + unsigned long tstate; /* Tx internal state */ + unsigned long tptr; /* Tx internal data pointer */ + unsigned short tbptr; /* Tx BD pointer */ + unsigned short tcount; /* Tx byte count */ + unsigned long ttemp; /* Tx temp */ + unsigned long rcrc; /* temp receive CRC */ + unsigned long tcrc; /* temp transmit CRC */ + + /* + * BISYNC specific parameter RAM + */ + unsigned char RESERVED1[4]; /* Reserved area */ + unsigned long crcc; /* CRC Constant Temp Value */ + unsigned short prcrc; /* Preset Receiver CRC-16/LRC */ + unsigned short ptcrc; /* Preset Transmitter CRC-16/LRC */ + unsigned short parec; /* Receive Parity Error Counter */ + unsigned short bsync; /* BISYNC SYNC Character */ + unsigned short bdle; /* BISYNC DLE Character */ + unsigned short cc[8]; /* Rx control characters */ + unsigned short rccm; /* Receive Control Character Mask */ +}; + +/***************************************************************** + IOM2 parameter RAM + (overlaid on tx bd[5] of SCC channel[2]) +*****************************************************************/ +struct iom2_pram { + unsigned short ci_data; /* ci data */ + unsigned short monitor_data; /* monitor data */ + unsigned short tstate; /* transmitter state */ + unsigned short rstate; /* receiver state */ +}; + +/***************************************************************** + SPI/SMC parameter RAM + (overlaid on tx bd[6,7] of SCC channel[2]) +*****************************************************************/ + +#define SPI_R 0x8000 /* Ready bit in BD */ + +struct spi_pram { + unsigned short rbase; /* Rx BD Base Address */ + unsigned short tbase; /* Tx BD Base Address */ + unsigned char rfcr; /* Rx function code */ + unsigned char tfcr; /* Tx function code */ + unsigned short mrblr; /* Rx buffer length */ + unsigned long rstate; /* Rx internal state */ + unsigned long rptr; /* Rx internal data pointer */ + unsigned short rbptr; /* rb BD Pointer */ + unsigned short rcount; /* Rx internal byte count */ + unsigned long rtemp; /* Rx temp */ + unsigned long tstate; /* Tx internal state */ + unsigned long tptr; /* Tx internal data pointer */ + unsigned short tbptr; /* Tx BD pointer */ + unsigned short tcount; /* Tx byte count */ + unsigned long ttemp; /* Tx temp */ +}; + +struct smc_uart_pram { + unsigned short rbase; /* Rx BD Base Address */ + unsigned short tbase; /* Tx BD Base Address */ + unsigned char rfcr; /* Rx function code */ + unsigned char tfcr; /* Tx function code */ + unsigned short mrblr; /* Rx buffer length */ + unsigned long rstate; /* Rx internal state */ + unsigned long rptr; /* Rx internal data pointer */ + unsigned short rbptr; /* rb BD Pointer */ + unsigned short rcount; /* Rx internal byte count */ + unsigned long rtemp; /* Rx temp */ + unsigned long tstate; /* Tx internal state */ + unsigned long tptr; /* Tx internal data pointer */ + unsigned short tbptr; /* Tx BD pointer */ + unsigned short tcount; /* Tx byte count */ + unsigned long ttemp; /* Tx temp */ + unsigned short max_idl; /* Maximum IDLE Characters */ + unsigned short idlc; /* Temporary IDLE Counter */ + unsigned short brkln; /* Last Rx Break Length */ + unsigned short brkec; /* Rx Break Condition Counter */ + unsigned short brkcr; /* Break Count Register (Tx) */ + unsigned short r_mask; /* Temporary bit mask */ +}; + +struct smc_trnsp_pram { + unsigned short rbase; /* rx BD Base Address */ + unsigned short tbase; /* Tx BD Base Address */ + unsigned char rfcr; /* Rx function code */ + unsigned char tfcr; /* Tx function code */ + unsigned short mrblr; /* Rx buffer length */ + unsigned long rstate; /* Rx internal state */ + unsigned long rptr; /* Rx internal data pointer */ + unsigned short rbptr; /* rb BD Pointer */ + unsigned short rcount; /* Rx internal byte count */ + unsigned long rtemp; /* Rx temp */ + unsigned long tstate; /* Tx internal state */ + unsigned long tptr; /* Tx internal data pointer */ + unsigned short tbptr; /* Tx BD pointer */ + unsigned short tcount; /* Tx byte count */ + unsigned long ttemp; /* Tx temp */ + unsigned short reserved[5]; /* Reserved */ +}; + +struct idma_pram { + unsigned short ibase; /* IDMA BD Base Address */ + unsigned short ibptr; /* IDMA buffer descriptor pointer */ + unsigned long istate; /* IDMA internal state */ + unsigned long itemp; /* IDMA temp */ +}; + +struct ethernet_pram { + /* + * SCC parameter RAM + */ + unsigned short rbase; /* RX BD base address */ + unsigned short tbase; /* TX BD base address */ + unsigned char rfcr; /* Rx function code */ + unsigned char tfcr; /* Tx function code */ + unsigned short mrblr; /* Rx buffer length */ + unsigned long rstate; /* Rx internal state */ + unsigned long rptr; /* Rx internal data pointer */ + unsigned short rbptr; /* rb BD Pointer */ + unsigned short rcount; /* Rx internal byte count */ + unsigned long rtemp; /* Rx temp */ + unsigned long tstate; /* Tx internal state */ + unsigned long tptr; /* Tx internal data pointer */ + unsigned short tbptr; /* Tx BD pointer */ + unsigned short tcount; /* Tx byte count */ + unsigned long ttemp; /* Tx temp */ + unsigned long rcrc; /* temp receive CRC */ + unsigned long tcrc; /* temp transmit CRC */ + + /* + * ETHERNET specific parameter RAM + */ + unsigned long c_pres; /* preset CRC */ + unsigned long c_mask; /* constant mask for CRC */ + unsigned long crcec; /* CRC error counter */ + unsigned long alec; /* alighnment error counter */ + unsigned long disfc; /* discard frame counter */ + unsigned short pads; /* short frame PAD characters */ + unsigned short ret_lim; /* retry limit threshold */ + unsigned short ret_cnt; /* retry limit counter */ + unsigned short mflr; /* maximum frame length reg */ + unsigned short minflr; /* minimum frame length reg */ + unsigned short maxd1; /* maximum DMA1 length reg */ + unsigned short maxd2; /* maximum DMA2 length reg */ + unsigned short maxd; /* rx max DMA */ + unsigned short dma_cnt; /* rx dma counter */ + unsigned short max_b; /* max bd byte count */ + unsigned short gaddr1; /* group address filter 1 */ + unsigned short gaddr2; /* group address filter 2 */ + unsigned short gaddr3; /* group address filter 3 */ + unsigned short gaddr4; /* group address filter 4 */ + unsigned long tbuf0_data0; /* save area 0 - current frm */ + unsigned long tbuf0_data1; /* save area 1 - current frm */ + unsigned long tbuf0_rba0; + unsigned long tbuf0_crc; + unsigned short tbuf0_bcnt; + union { + unsigned char b[6]; + struct { + unsigned short high; + unsigned short middl; + unsigned short low; + } w; + } paddr; + unsigned short p_per; /* persistence */ + unsigned short rfbd_ptr; /* rx first bd pointer */ + unsigned short tfbd_ptr; /* tx first bd pointer */ + unsigned short tlbd_ptr; /* tx last bd pointer */ + unsigned long tbuf1_data0; /* save area 0 - next frame */ + unsigned long tbuf1_data1; /* save area 1 - next frame */ + unsigned long tbuf1_rba0; + unsigned long tbuf1_crc; + unsigned short tbuf1_bcnt; + unsigned short tx_len; /* tx frame length counter */ + unsigned short iaddr1; /* individual address filter 1*/ + unsigned short iaddr2; /* individual address filter 2*/ + unsigned short iaddr3; /* individual address filter 3*/ + unsigned short iaddr4; /* individual address filter 4*/ + unsigned short boff_cnt; /* back-off counter */ + unsigned short taddr_h; /* temp address (MSB) */ + unsigned short taddr_m; /* temp address */ + unsigned short taddr_l; /* temp address (LSB) */ +}; + +struct transparent_pram { + /* + * SCC parameter RAM + */ + unsigned short rbase; /* RX BD base address */ + unsigned short tbase; /* TX BD base address */ + unsigned char rfcr; /* Rx function code */ + unsigned char tfcr; /* Tx function code */ + unsigned short mrblr; /* Rx buffer length */ + unsigned long rstate; /* Rx internal state */ + unsigned long rptr; /* Rx internal data pointer */ + unsigned short rbptr; /* rb BD Pointer */ + unsigned short rcount; /* Rx internal byte count */ + unsigned long rtemp; /* Rx temp */ + unsigned long tstate; /* Tx internal state */ + unsigned long tptr; /* Tx internal data pointer */ + unsigned short tbptr; /* Tx BD pointer */ + unsigned short tcount; /* Tx byte count */ + unsigned long ttemp; /* Tx temp */ + unsigned long rcrc; /* temp receive CRC */ + unsigned long tcrc; /* temp transmit CRC */ + + /* + * TRANSPARENT specific parameter RAM + */ + unsigned long crc_p; /* CRC Preset */ + unsigned long crc_c; /* CRC constant */ +}; + +struct timer_pram { + /* + * RISC timers parameter RAM + */ + unsigned short tm_base; /* RISC timer table base adr */ + unsigned short tm_ptr; /* RISC timer table pointer */ + unsigned short r_tmr; /* RISC timer mode register */ + unsigned short r_tmv; /* RISC timer valid register */ + unsigned long tm_cmd; /* RISC timer cmd register */ + unsigned long tm_cnt; /* RISC timer internal cnt */ +}; + +#endif diff --git a/arch/m68k/include/asm/m68360_quicc.h b/arch/m68k/include/asm/m68360_quicc.h new file mode 100644 index 00000000000..6d40f4d18e1 --- /dev/null +++ b/arch/m68k/include/asm/m68360_quicc.h @@ -0,0 +1,362 @@ +/*********************************** + * $Id: m68360_quicc.h,v 1.1 2002/03/02 15:01:07 gerg Exp $ + *********************************** + * + *************************************** + * Definitions of QUICC memory structures + *************************************** + */ + +#ifndef __M68360_QUICC_H +#define __M68360_QUICC_H + +/* + * include registers and + * parameter ram definitions files + */ +#include +#include + + + +/* Buffer Descriptors */ +typedef struct quicc_bd { + volatile unsigned short status; + volatile unsigned short length; + volatile unsigned char *buf; /* WARNING: This is only true if *char is 32 bits */ +} QUICC_BD; + + +#ifdef MOTOROLA_ORIGINAL +struct user_data { + /* BASE + 0x000: user data memory */ + volatile unsigned char udata_bd_ucode[0x400]; /*user data bd's Ucode*/ + volatile unsigned char udata_bd[0x200]; /*user data Ucode */ + volatile unsigned char ucode_ext[0x100]; /*Ucode Extention ram */ + volatile unsigned char RESERVED1[0x500]; /* Reserved area */ +}; +#else +struct user_data { + /* BASE + 0x000: user data memory */ + volatile unsigned char udata_bd_ucode[0x400]; /* user data, bds, Ucode*/ + volatile unsigned char udata_bd1[0x200]; /* user, bds */ + volatile unsigned char ucode_bd_scratch[0x100]; /* user, bds, ucode scratch */ + volatile unsigned char udata_bd2[0x100]; /* user, bds */ + volatile unsigned char RESERVED1[0x400]; /* Reserved area */ +}; +#endif + + +/* + * internal ram + */ +typedef struct quicc { + union { + struct quicc32_pram ch_pram_tbl[32]; /* 32*64(bytes) per channel */ + struct user_data u; + }ch_or_u; /* multipul or user space */ + + /* BASE + 0xc00: PARAMETER RAM */ + union { + struct scc_pram { + union { + struct hdlc_pram h; + struct uart_pram u; + struct bisync_pram b; + struct transparent_pram t; + unsigned char RESERVED66[0x70]; + } pscc; /* scc parameter area (protocol dependent) */ + union { + struct { + unsigned char RESERVED70[0x10]; + struct spi_pram spi; + unsigned char RESERVED72[0x8]; + struct timer_pram timer; + } timer_spi; + struct { + struct idma_pram idma; + unsigned char RESERVED67[0x4]; + union { + struct smc_uart_pram u; + struct smc_trnsp_pram t; + } psmc; + } idma_smc; + } pothers; + } scc; + struct ethernet_pram enet_scc; + struct global_multi_pram m; + unsigned char pr[0x100]; + } pram[4]; + + /* reserved */ + + /* BASE + 0x1000: INTERNAL REGISTERS */ + /* SIM */ + volatile unsigned long sim_mcr; /* module configuration reg */ + volatile unsigned short sim_simtr; /* module test register */ + volatile unsigned char RESERVED2[0x2]; /* Reserved area */ + volatile unsigned char sim_avr; /* auto vector reg */ + volatile unsigned char sim_rsr; /* reset status reg */ + volatile unsigned char RESERVED3[0x2]; /* Reserved area */ + volatile unsigned char sim_clkocr; /* CLCO control register */ + volatile unsigned char RESERVED62[0x3]; /* Reserved area */ + volatile unsigned short sim_pllcr; /* PLL control register */ + volatile unsigned char RESERVED63[0x2]; /* Reserved area */ + volatile unsigned short sim_cdvcr; /* Clock devider control register */ + volatile unsigned short sim_pepar; /* Port E pin assignment register */ + volatile unsigned char RESERVED64[0xa]; /* Reserved area */ + volatile unsigned char sim_sypcr; /* system protection control*/ + volatile unsigned char sim_swiv; /* software interrupt vector*/ + volatile unsigned char RESERVED6[0x2]; /* Reserved area */ + volatile unsigned short sim_picr; /* periodic interrupt control reg */ + volatile unsigned char RESERVED7[0x2]; /* Reserved area */ + volatile unsigned short sim_pitr; /* periodic interrupt timing reg */ + volatile unsigned char RESERVED8[0x3]; /* Reserved area */ + volatile unsigned char sim_swsr; /* software service */ + volatile unsigned long sim_bkar; /* breakpoint address register*/ + volatile unsigned long sim_bkcr; /* breakpoint control register*/ + volatile unsigned char RESERVED10[0x8]; /* Reserved area */ + /* MEMC */ + volatile unsigned long memc_gmr; /* Global memory register */ + volatile unsigned short memc_mstat; /* MEMC status register */ + volatile unsigned char RESERVED11[0xa]; /* Reserved area */ + volatile unsigned long memc_br0; /* base register 0 */ + volatile unsigned long memc_or0; /* option register 0 */ + volatile unsigned char RESERVED12[0x8]; /* Reserved area */ + volatile unsigned long memc_br1; /* base register 1 */ + volatile unsigned long memc_or1; /* option register 1 */ + volatile unsigned char RESERVED13[0x8]; /* Reserved area */ + volatile unsigned long memc_br2; /* base register 2 */ + volatile unsigned long memc_or2; /* option register 2 */ + volatile unsigned char RESERVED14[0x8]; /* Reserved area */ + volatile unsigned long memc_br3; /* base register 3 */ + volatile unsigned long memc_or3; /* option register 3 */ + volatile unsigned char RESERVED15[0x8]; /* Reserved area */ + volatile unsigned long memc_br4; /* base register 3 */ + volatile unsigned long memc_or4; /* option register 3 */ + volatile unsigned char RESERVED16[0x8]; /* Reserved area */ + volatile unsigned long memc_br5; /* base register 3 */ + volatile unsigned long memc_or5; /* option register 3 */ + volatile unsigned char RESERVED17[0x8]; /* Reserved area */ + volatile unsigned long memc_br6; /* base register 3 */ + volatile unsigned long memc_or6; /* option register 3 */ + volatile unsigned char RESERVED18[0x8]; /* Reserved area */ + volatile unsigned long memc_br7; /* base register 3 */ + volatile unsigned long memc_or7; /* option register 3 */ + volatile unsigned char RESERVED9[0x28]; /* Reserved area */ + /* TEST */ + volatile unsigned short test_tstmra; /* master shift a */ + volatile unsigned short test_tstmrb; /* master shift b */ + volatile unsigned short test_tstsc; /* shift count */ + volatile unsigned short test_tstrc; /* repetition counter */ + volatile unsigned short test_creg; /* control */ + volatile unsigned short test_dreg; /* destributed register */ + volatile unsigned char RESERVED58[0x404]; /* Reserved area */ + /* IDMA1 */ + volatile unsigned short idma_iccr; /* channel configuration reg*/ + volatile unsigned char RESERVED19[0x2]; /* Reserved area */ + volatile unsigned short idma1_cmr; /* dma mode reg */ + volatile unsigned char RESERVED68[0x2]; /* Reserved area */ + volatile unsigned long idma1_sapr; /* dma source addr ptr */ + volatile unsigned long idma1_dapr; /* dma destination addr ptr */ + volatile unsigned long idma1_bcr; /* dma byte count reg */ + volatile unsigned char idma1_fcr; /* function code reg */ + volatile unsigned char RESERVED20; /* Reserved area */ + volatile unsigned char idma1_cmar; /* channel mask reg */ + volatile unsigned char RESERVED21; /* Reserved area */ + volatile unsigned char idma1_csr; /* channel status reg */ + volatile unsigned char RESERVED22[0x3]; /* Reserved area */ + /* SDMA */ + volatile unsigned char sdma_sdsr; /* status reg */ + volatile unsigned char RESERVED23; /* Reserved area */ + volatile unsigned short sdma_sdcr; /* configuration reg */ + volatile unsigned long sdma_sdar; /* address reg */ + /* IDMA2 */ + volatile unsigned char RESERVED69[0x2]; /* Reserved area */ + volatile unsigned short idma2_cmr; /* dma mode reg */ + volatile unsigned long idma2_sapr; /* dma source addr ptr */ + volatile unsigned long idma2_dapr; /* dma destination addr ptr */ + volatile unsigned long idma2_bcr; /* dma byte count reg */ + volatile unsigned char idma2_fcr; /* function code reg */ + volatile unsigned char RESERVED24; /* Reserved area */ + volatile unsigned char idma2_cmar; /* channel mask reg */ + volatile unsigned char RESERVED25; /* Reserved area */ + volatile unsigned char idma2_csr; /* channel status reg */ + volatile unsigned char RESERVED26[0x7]; /* Reserved area */ + /* Interrupt Controller */ + volatile unsigned long intr_cicr; /* CP interrupt configuration reg*/ + volatile unsigned long intr_cipr; /* CP interrupt pending reg */ + volatile unsigned long intr_cimr; /* CP interrupt mask reg */ + volatile unsigned long intr_cisr; /* CP interrupt in service reg*/ + /* Parallel I/O */ + volatile unsigned short pio_padir; /* port A data direction reg */ + volatile unsigned short pio_papar; /* port A pin assignment reg */ + volatile unsigned short pio_paodr; /* port A open drain reg */ + volatile unsigned short pio_padat; /* port A data register */ + volatile unsigned char RESERVED28[0x8]; /* Reserved area */ + volatile unsigned short pio_pcdir; /* port C data direction reg*/ + volatile unsigned short pio_pcpar; /* port C pin assignment reg*/ + volatile unsigned short pio_pcso; /* port C special options */ + volatile unsigned short pio_pcdat; /* port C data register */ + volatile unsigned short pio_pcint; /* port C interrupt cntrl reg */ + volatile unsigned char RESERVED29[0x16]; /* Reserved area */ + /* Timer */ + volatile unsigned short timer_tgcr; /* timer global configuration reg */ + volatile unsigned char RESERVED30[0xe]; /* Reserved area */ + volatile unsigned short timer_tmr1; /* timer 1 mode reg */ + volatile unsigned short timer_tmr2; /* timer 2 mode reg */ + volatile unsigned short timer_trr1; /* timer 1 referance reg */ + volatile unsigned short timer_trr2; /* timer 2 referance reg */ + volatile unsigned short timer_tcr1; /* timer 1 capture reg */ + volatile unsigned short timer_tcr2; /* timer 2 capture reg */ + volatile unsigned short timer_tcn1; /* timer 1 counter reg */ + volatile unsigned short timer_tcn2; /* timer 2 counter reg */ + volatile unsigned short timer_tmr3; /* timer 3 mode reg */ + volatile unsigned short timer_tmr4; /* timer 4 mode reg */ + volatile unsigned short timer_trr3; /* timer 3 referance reg */ + volatile unsigned short timer_trr4; /* timer 4 referance reg */ + volatile unsigned short timer_tcr3; /* timer 3 capture reg */ + volatile unsigned short timer_tcr4; /* timer 4 capture reg */ + volatile unsigned short timer_tcn3; /* timer 3 counter reg */ + volatile unsigned short timer_tcn4; /* timer 4 counter reg */ + volatile unsigned short timer_ter1; /* timer 1 event reg */ + volatile unsigned short timer_ter2; /* timer 2 event reg */ + volatile unsigned short timer_ter3; /* timer 3 event reg */ + volatile unsigned short timer_ter4; /* timer 4 event reg */ + volatile unsigned char RESERVED34[0x8]; /* Reserved area */ + /* CP */ + volatile unsigned short cp_cr; /* command register */ + volatile unsigned char RESERVED35[0x2]; /* Reserved area */ + volatile unsigned short cp_rccr; /* main configuration reg */ + volatile unsigned char RESERVED37; /* Reserved area */ + volatile unsigned char cp_rmds; /* development support status reg */ + volatile unsigned long cp_rmdr; /* development support control reg */ + volatile unsigned short cp_rctr1; /* ram break register 1 */ + volatile unsigned short cp_rctr2; /* ram break register 2 */ + volatile unsigned short cp_rctr3; /* ram break register 3 */ + volatile unsigned short cp_rctr4; /* ram break register 4 */ + volatile unsigned char RESERVED59[0x2]; /* Reserved area */ + volatile unsigned short cp_rter; /* RISC timers event reg */ + volatile unsigned char RESERVED38[0x2]; /* Reserved area */ + volatile unsigned short cp_rtmr; /* RISC timers mask reg */ + volatile unsigned char RESERVED39[0x14]; /* Reserved area */ + /* BRG */ + union { + volatile unsigned long l; + struct { + volatile unsigned short BRGC_RESERV:14; + volatile unsigned short rst:1; + volatile unsigned short en:1; + volatile unsigned short extc:2; + volatile unsigned short atb:1; + volatile unsigned short cd:12; + volatile unsigned short div16:1; + } b; + } brgc[4]; /* BRG1-BRG4 configuration regs*/ + /* SCC registers */ + struct scc_regs { + union { + struct { + /* Low word. */ + volatile unsigned short GSMR_RESERV2:1; + volatile unsigned short edge:2; + volatile unsigned short tci:1; + volatile unsigned short tsnc:2; + volatile unsigned short rinv:1; + volatile unsigned short tinv:1; + volatile unsigned short tpl:3; + volatile unsigned short tpp:2; + volatile unsigned short tend:1; + volatile unsigned short tdcr:2; + volatile unsigned short rdcr:2; + volatile unsigned short renc:3; + volatile unsigned short tenc:3; + volatile unsigned short diag:2; + volatile unsigned short enr:1; + volatile unsigned short ent:1; + volatile unsigned short mode:4; + /* High word. */ + volatile unsigned short GSMR_RESERV1:14; + volatile unsigned short pri:1; + volatile unsigned short gde:1; + volatile unsigned short tcrc:2; + volatile unsigned short revd:1; + volatile unsigned short trx:1; + volatile unsigned short ttx:1; + volatile unsigned short cdp:1; + volatile unsigned short ctsp:1; + volatile unsigned short cds:1; + volatile unsigned short ctss:1; + volatile unsigned short tfl:1; + volatile unsigned short rfw:1; + volatile unsigned short txsy:1; + volatile unsigned short synl:2; + volatile unsigned short rtsm:1; + volatile unsigned short rsyn:1; + } b; + struct { + volatile unsigned long low; + volatile unsigned long high; + } w; + } scc_gsmr; /* SCC general mode reg */ + volatile unsigned short scc_psmr; /* protocol specific mode reg */ + volatile unsigned char RESERVED42[0x2]; /* Reserved area */ + volatile unsigned short scc_todr; /* SCC transmit on demand */ + volatile unsigned short scc_dsr; /* SCC data sync reg */ + volatile unsigned short scc_scce; /* SCC event reg */ + volatile unsigned char RESERVED43[0x2];/* Reserved area */ + volatile unsigned short scc_sccm; /* SCC mask reg */ + volatile unsigned char RESERVED44[0x1];/* Reserved area */ + volatile unsigned char scc_sccs; /* SCC status reg */ + volatile unsigned char RESERVED45[0x8]; /* Reserved area */ + } scc_regs[4]; + /* SMC */ + struct smc_regs { + volatile unsigned char RESERVED46[0x2]; /* Reserved area */ + volatile unsigned short smc_smcmr; /* SMC mode reg */ + volatile unsigned char RESERVED60[0x2]; /* Reserved area */ + volatile unsigned char smc_smce; /* SMC event reg */ + volatile unsigned char RESERVED47[0x3]; /* Reserved area */ + volatile unsigned char smc_smcm; /* SMC mask reg */ + volatile unsigned char RESERVED48[0x5]; /* Reserved area */ + } smc_regs[2]; + /* SPI */ + volatile unsigned short spi_spmode; /* SPI mode reg */ + volatile unsigned char RESERVED51[0x4]; /* Reserved area */ + volatile unsigned char spi_spie; /* SPI event reg */ + volatile unsigned char RESERVED52[0x3]; /* Reserved area */ + volatile unsigned char spi_spim; /* SPI mask reg */ + volatile unsigned char RESERVED53[0x2]; /* Reserved area */ + volatile unsigned char spi_spcom; /* SPI command reg */ + volatile unsigned char RESERVED54[0x4]; /* Reserved area */ + /* PIP */ + volatile unsigned short pip_pipc; /* pip configuration reg */ + volatile unsigned char RESERVED65[0x2]; /* Reserved area */ + volatile unsigned short pip_ptpr; /* pip timing parameters reg */ + volatile unsigned long pip_pbdir; /* port b data direction reg */ + volatile unsigned long pip_pbpar; /* port b pin assignment reg */ + volatile unsigned long pip_pbodr; /* port b open drain reg */ + volatile unsigned long pip_pbdat; /* port b data reg */ + volatile unsigned char RESERVED71[0x18]; /* Reserved area */ + /* Serial Interface */ + volatile unsigned long si_simode; /* SI mode register */ + volatile unsigned char si_sigmr; /* SI global mode register */ + volatile unsigned char RESERVED55; /* Reserved area */ + volatile unsigned char si_sistr; /* SI status register */ + volatile unsigned char si_sicmr; /* SI command register */ + volatile unsigned char RESERVED56[0x4]; /* Reserved area */ + volatile unsigned long si_sicr; /* SI clock routing */ + volatile unsigned long si_sirp; /* SI ram pointers */ + volatile unsigned char RESERVED57[0xc]; /* Reserved area */ + volatile unsigned short si_siram[0x80]; /* SI routing ram */ +} QUICC; + +#endif + +/* + * Local variables: + * c-indent-level: 4 + * c-basic-offset: 4 + * tab-width: 4 + * End: + */ diff --git a/arch/m68k/include/asm/m68360_regs.h b/arch/m68k/include/asm/m68360_regs.h new file mode 100644 index 00000000000..d57217ca4f2 --- /dev/null +++ b/arch/m68k/include/asm/m68360_regs.h @@ -0,0 +1,408 @@ +/*********************************** + * $Id: m68360_regs.h,v 1.2 2002/10/26 15:03:55 gerg Exp $ + *********************************** + * + *************************************** + * Definitions of the QUICC registers + *************************************** + */ + +#ifndef __REGISTERS_H +#define __REGISTERS_H + +#define CLEAR_BIT(x, bit) x =bit + +/***************************************************************** + Command Register +*****************************************************************/ + +/* bit fields within command register */ +#define SOFTWARE_RESET 0x8000 +#define CMD_OPCODE 0x0f00 +#define CMD_CHANNEL 0x00f0 +#define CMD_FLAG 0x0001 + +/* general command opcodes */ +#define INIT_RXTX_PARAMS 0x0000 +#define INIT_RX_PARAMS 0x0100 +#define INIT_TX_PARAMS 0x0200 +#define ENTER_HUNT_MODE 0x0300 +#define STOP_TX 0x0400 +#define GR_STOP_TX 0x0500 +#define RESTART_TX 0x0600 +#define CLOSE_RX_BD 0x0700 +#define SET_ENET_GROUP 0x0800 +#define RESET_ENET_GROUP 0x0900 + +/* quicc32 CP commands */ +#define STOP_TX_32 0x0e00 /*add chan# bits 2-6 */ +#define ENTER_HUNT_MODE_32 0x1e00 + +/* quicc32 mask/event SCC register */ +#define GOV 0x01 +#define GUN 0x02 +#define GINT 0x04 +#define IQOV 0x08 + + +/* Timer commands */ +#define SET_TIMER 0x0800 + +/* Multi channel Interrupt structure */ +#define INTR_VALID 0x8000 /* Valid interrupt entry */ +#define INTR_WRAP 0x4000 /* Wrap bit in the interrupt entry table */ +#define INTR_CH_NU 0x07c0 /* Channel Num in interrupt table */ +#define INTR_MASK_BITS 0x383f + +/* + * General SCC mode register (GSMR) + */ + +#define MODE_HDLC 0x0 +#define MODE_APPLE_TALK 0x2 +#define MODE_SS7 0x3 +#define MODE_UART 0x4 +#define MODE_PROFIBUS 0x5 +#define MODE_ASYNC_HDLC 0x6 +#define MODE_V14 0x7 +#define MODE_BISYNC 0x8 +#define MODE_DDCMP 0x9 +#define MODE_MULTI_CHANNEL 0xa +#define MODE_ETHERNET 0xc + +#define DIAG_NORMAL 0x0 +#define DIAG_LOCAL_LPB 0x1 +#define DIAG_AUTO_ECHO 0x2 +#define DIAG_LBP_ECHO 0x3 + +/* For RENC and TENC fields in GSMR */ +#define ENC_NRZ 0x0 +#define ENC_NRZI 0x1 +#define ENC_FM0 0x2 +#define ENC_MANCH 0x4 +#define ENC_DIFF_MANC 0x6 + +/* For TDCR and RDCR fields in GSMR */ +#define CLOCK_RATE_1 0x0 +#define CLOCK_RATE_8 0x1 +#define CLOCK_RATE_16 0x2 +#define CLOCK_RATE_32 0x3 + +#define TPP_00 0x0 +#define TPP_10 0x1 +#define TPP_01 0x2 +#define TPP_11 0x3 + +#define TPL_NO 0x0 +#define TPL_8 0x1 +#define TPL_16 0x2 +#define TPL_32 0x3 +#define TPL_48 0x4 +#define TPL_64 0x5 +#define TPL_128 0x6 + +#define TSNC_INFINITE 0x0 +#define TSNC_14_65 0x1 +#define TSNC_4_15 0x2 +#define TSNC_3_1 0x3 + +#define EDGE_BOTH 0x0 +#define EDGE_POS 0x1 +#define EDGE_NEG 0x2 +#define EDGE_NO 0x3 + +#define SYNL_NO 0x0 +#define SYNL_4 0x1 +#define SYNL_8 0x2 +#define SYNL_16 0x3 + +#define TCRC_CCITT16 0x0 +#define TCRC_CRC16 0x1 +#define TCRC_CCITT32 0x2 + + +/***************************************************************** + TODR (Transmit on demand) Register +*****************************************************************/ +#define TODR_TOD 0x8000 /* Transmit on demand */ + + +/***************************************************************** + CICR register settings +*****************************************************************/ + +/* note that relative irq priorities of the SCCs can be reordered + * if desired - see p. 7-377 of the MC68360UM */ +#define CICR_SCA_SCC1 ((uint)0x00000000) /* SCC1 @ SCCa */ +#define CICR_SCB_SCC2 ((uint)0x00040000) /* SCC2 @ SCCb */ +#define CICR_SCC_SCC3 ((uint)0x00200000) /* SCC3 @ SCCc */ +#define CICR_SCD_SCC4 ((uint)0x00c00000) /* SCC4 @ SCCd */ + +#define CICR_IRL_MASK ((uint)0x0000e000) /* Core interrupt */ +#define CICR_HP_MASK ((uint)0x00001f00) /* Hi-pri int. */ +#define CICR_VBA_MASK ((uint)0x000000e0) /* Vector Base Address */ +#define CICR_SPS ((uint)0x00000001) /* SCC Spread */ + + +/***************************************************************** + Interrupt bits for CIPR and CIMR (MC68360UM p. 7-379) +*****************************************************************/ + +#define INTR_PIO_PC0 0x80000000 /* parallel I/O C bit 0 */ +#define INTR_SCC1 0x40000000 /* SCC port 1 */ +#define INTR_SCC2 0x20000000 /* SCC port 2 */ +#define INTR_SCC3 0x10000000 /* SCC port 3 */ +#define INTR_SCC4 0x08000000 /* SCC port 4 */ +#define INTR_PIO_PC1 0x04000000 /* parallel i/o C bit 1 */ +#define INTR_TIMER1 0x02000000 /* timer 1 */ +#define INTR_PIO_PC2 0x01000000 /* parallel i/o C bit 2 */ +#define INTR_PIO_PC3 0x00800000 /* parallel i/o C bit 3 */ +#define INTR_SDMA_BERR 0x00400000 /* SDMA channel bus error */ +#define INTR_DMA1 0x00200000 /* idma 1 */ +#define INTR_DMA2 0x00100000 /* idma 2 */ +#define INTR_TIMER2 0x00040000 /* timer 2 */ +#define INTR_CP_TIMER 0x00020000 /* CP timer */ +#define INTR_PIP_STATUS 0x00010000 /* PIP status */ +#define INTR_PIO_PC4 0x00008000 /* parallel i/o C bit 4 */ +#define INTR_PIO_PC5 0x00004000 /* parallel i/o C bit 5 */ +#define INTR_TIMER3 0x00001000 /* timer 3 */ +#define INTR_PIO_PC6 0x00000800 /* parallel i/o C bit 6 */ +#define INTR_PIO_PC7 0x00000400 /* parallel i/o C bit 7 */ +#define INTR_PIO_PC8 0x00000200 /* parallel i/o C bit 8 */ +#define INTR_TIMER4 0x00000080 /* timer 4 */ +#define INTR_PIO_PC9 0x00000040 /* parallel i/o C bit 9 */ +#define INTR_SCP 0x00000020 /* SCP */ +#define INTR_SMC1 0x00000010 /* SMC 1 */ +#define INTR_SMC2 0x00000008 /* SMC 2 */ +#define INTR_PIO_PC10 0x00000004 /* parallel i/o C bit 10 */ +#define INTR_PIO_PC11 0x00000002 /* parallel i/o C bit 11 */ +#define INTR_ERR 0x00000001 /* error */ + + +/***************************************************************** + CPM Interrupt vector encodings (MC68360UM p. 7-376) +*****************************************************************/ + +#define CPMVEC_NR 32 +#define CPMVEC_PIO_PC0 0x1f +#define CPMVEC_SCC1 0x1e +#define CPMVEC_SCC2 0x1d +#define CPMVEC_SCC3 0x1c +#define CPMVEC_SCC4 0x1b +#define CPMVEC_PIO_PC1 0x1a +#define CPMVEC_TIMER1 0x19 +#define CPMVEC_PIO_PC2 0x18 +#define CPMVEC_PIO_PC3 0x17 +#define CPMVEC_SDMA_CB_ERR 0x16 +#define CPMVEC_IDMA1 0x15 +#define CPMVEC_IDMA2 0x14 +#define CPMVEC_RESERVED3 0x13 +#define CPMVEC_TIMER2 0x12 +#define CPMVEC_RISCTIMER 0x11 +#define CPMVEC_RESERVED2 0x10 +#define CPMVEC_PIO_PC4 0x0f +#define CPMVEC_PIO_PC5 0x0e +#define CPMVEC_TIMER3 0x0c +#define CPMVEC_PIO_PC6 0x0b +#define CPMVEC_PIO_PC7 0x0a +#define CPMVEC_PIO_PC8 0x09 +#define CPMVEC_RESERVED1 0x08 +#define CPMVEC_TIMER4 0x07 +#define CPMVEC_PIO_PC9 0x06 +#define CPMVEC_SPI 0x05 +#define CPMVEC_SMC1 0x04 +#define CPMVEC_SMC2 0x03 +#define CPMVEC_PIO_PC10 0x02 +#define CPMVEC_PIO_PC11 0x01 +#define CPMVEC_ERROR 0x00 + +/* #define CPMVEC_PIO_PC0 ((ushort)0x1f) */ +/* #define CPMVEC_SCC1 ((ushort)0x1e) */ +/* #define CPMVEC_SCC2 ((ushort)0x1d) */ +/* #define CPMVEC_SCC3 ((ushort)0x1c) */ +/* #define CPMVEC_SCC4 ((ushort)0x1b) */ +/* #define CPMVEC_PIO_PC1 ((ushort)0x1a) */ +/* #define CPMVEC_TIMER1 ((ushort)0x19) */ +/* #define CPMVEC_PIO_PC2 ((ushort)0x18) */ +/* #define CPMVEC_PIO_PC3 ((ushort)0x17) */ +/* #define CPMVEC_SDMA_CB_ERR ((ushort)0x16) */ +/* #define CPMVEC_IDMA1 ((ushort)0x15) */ +/* #define CPMVEC_IDMA2 ((ushort)0x14) */ +/* #define CPMVEC_RESERVED3 ((ushort)0x13) */ +/* #define CPMVEC_TIMER2 ((ushort)0x12) */ +/* #define CPMVEC_RISCTIMER ((ushort)0x11) */ +/* #define CPMVEC_RESERVED2 ((ushort)0x10) */ +/* #define CPMVEC_PIO_PC4 ((ushort)0x0f) */ +/* #define CPMVEC_PIO_PC5 ((ushort)0x0e) */ +/* #define CPMVEC_TIMER3 ((ushort)0x0c) */ +/* #define CPMVEC_PIO_PC6 ((ushort)0x0b) */ +/* #define CPMVEC_PIO_PC7 ((ushort)0x0a) */ +/* #define CPMVEC_PIO_PC8 ((ushort)0x09) */ +/* #define CPMVEC_RESERVED1 ((ushort)0x08) */ +/* #define CPMVEC_TIMER4 ((ushort)0x07) */ +/* #define CPMVEC_PIO_PC9 ((ushort)0x06) */ +/* #define CPMVEC_SPI ((ushort)0x05) */ +/* #define CPMVEC_SMC1 ((ushort)0x04) */ +/* #define CPMVEC_SMC2 ((ushort)0x03) */ +/* #define CPMVEC_PIO_PC10 ((ushort)0x02) */ +/* #define CPMVEC_PIO_PC11 ((ushort)0x01) */ +/* #define CPMVEC_ERROR ((ushort)0x00) */ + + +/***************************************************************** + * PIO control registers + *****************************************************************/ + +/* Port A - See 360UM p. 7-358 + * + * Note that most of these pins have alternate functions + */ + + +/* The macros are nice, but there are all sorts of references to 1-indexed + * facilities on the 68360... */ +/* #define PA_RXD(n) ((ushort)(0x01<<(2*n))) */ +/* #define PA_TXD(n) ((ushort)(0x02<<(2*n))) */ + +#define PA_RXD1 ((ushort)0x0001) +#define PA_TXD1 ((ushort)0x0002) +#define PA_RXD2 ((ushort)0x0004) +#define PA_TXD2 ((ushort)0x0008) +#define PA_RXD3 ((ushort)0x0010) +#define PA_TXD3 ((ushort)0x0020) +#define PA_RXD4 ((ushort)0x0040) +#define PA_TXD4 ((ushort)0x0080) + +#define PA_CLK1 ((ushort)0x0100) +#define PA_CLK2 ((ushort)0x0200) +#define PA_CLK3 ((ushort)0x0400) +#define PA_CLK4 ((ushort)0x0800) +#define PA_CLK5 ((ushort)0x1000) +#define PA_CLK6 ((ushort)0x2000) +#define PA_CLK7 ((ushort)0x4000) +#define PA_CLK8 ((ushort)0x8000) + + +/* Port B - See 360UM p. 7-362 + */ + + +/* Port C - See 360UM p. 7-365 + */ + +#define PC_RTS1 ((ushort)0x0001) +#define PC_RTS2 ((ushort)0x0002) +#define PC__RTS3 ((ushort)0x0004) /* !RTS3 */ +#define PC__RTS4 ((ushort)0x0008) /* !RTS4 */ + +#define PC_CTS1 ((ushort)0x0010) +#define PC_CD1 ((ushort)0x0020) +#define PC_CTS2 ((ushort)0x0040) +#define PC_CD2 ((ushort)0x0080) +#define PC_CTS3 ((ushort)0x0100) +#define PC_CD3 ((ushort)0x0200) +#define PC_CTS4 ((ushort)0x0400) +#define PC_CD4 ((ushort)0x0800) + + + +/***************************************************************** + chip select option register +*****************************************************************/ +#define DTACK 0xe000 +#define ADR_MASK 0x1ffc +#define RDWR_MASK 0x0002 +#define FC_MASK 0x0001 + +/***************************************************************** + tbase and rbase registers +*****************************************************************/ +#define TBD_ADDR(quicc,pram) ((struct quicc_bd *) \ + (quicc->ch_or_u.u.udata_bd_ucode + pram->tbase)) +#define RBD_ADDR(quicc,pram) ((struct quicc_bd *) \ + (quicc->ch_or_u.u.udata_bd_ucode + pram->rbase)) +#define TBD_CUR_ADDR(quicc,pram) ((struct quicc_bd *) \ + (quicc->ch_or_u.u.udata_bd_ucode + pram->tbptr)) +#define RBD_CUR_ADDR(quicc,pram) ((struct quicc_bd *) \ + (quicc->ch_or_u.u.udata_bd_ucode + pram->rbptr)) +#define TBD_SET_CUR_ADDR(bd,quicc,pram) pram->tbptr = \ + ((unsigned short)((char *)(bd) - (char *)(quicc->ch_or_u.u.udata_bd_ucode))) +#define RBD_SET_CUR_ADDR(bd,quicc,pram) pram->rbptr = \ + ((unsigned short)((char *)(bd) - (char *)(quicc->ch_or_u.u.udata_bd_ucode))) +#define INCREASE_TBD(bd,quicc,pram) { \ + if((bd)->status & T_W) \ + (bd) = TBD_ADDR(quicc,pram); \ + else \ + (bd)++; \ +} +#define DECREASE_TBD(bd,quicc,pram) { \ + if ((bd) == TBD_ADDR(quicc, pram)) \ + while (!((bd)->status & T_W)) \ + (bd)++; \ + else \ + (bd)--; \ +} +#define INCREASE_RBD(bd,quicc,pram) { \ + if((bd)->status & R_W) \ + (bd) = RBD_ADDR(quicc,pram); \ + else \ + (bd)++; \ +} +#define DECREASE_RBD(bd,quicc,pram) { \ + if ((bd) == RBD_ADDR(quicc, pram)) \ + while (!((bd)->status & T_W)) \ + (bd)++; \ + else \ + (bd)--; \ +} + +/***************************************************************** + Macros for Multi channel +*****************************************************************/ +#define QMC_BASE(quicc,page) (struct global_multi_pram *)(&quicc->pram[page]) +#define MCBASE(quicc,page) (unsigned long)(quicc->pram[page].m.mcbase) +#define CHANNEL_PRAM_BASE(quicc,channel) ((struct quicc32_pram *) \ + (&(quicc->ch_or_u.ch_pram_tbl[channel]))) +#define TBD_32_ADDR(quicc,page,channel) ((struct quicc_bd *) \ + (MCBASE(quicc,page) + (CHANNEL_PRAM_BASE(quicc,channel)->tbase))) +#define RBD_32_ADDR(quicc,page,channel) ((struct quicc_bd *) \ + (MCBASE(quicc,page) + (CHANNEL_PRAM_BASE(quicc,channel)->rbase))) +#define TBD_32_CUR_ADDR(quicc,page,channel) ((struct quicc_bd *) \ + (MCBASE(quicc,page) + (CHANNEL_PRAM_BASE(quicc,channel)->tbptr))) +#define RBD_32_CUR_ADDR(quicc,page,channel) ((struct quicc_bd *) \ + (MCBASE(quicc,page) + (CHANNEL_PRAM_BASE(quicc,channel)->rbptr))) +#define TBD_32_SET_CUR_ADDR(bd,quicc,page,channel) \ + CHANNEL_PRAM_BASE(quicc,channel)->tbptr = \ + ((unsigned short)((char *)(bd) - (char *)(MCBASE(quicc,page)))) +#define RBD_32_SET_CUR_ADDR(bd,quicc,page,channel) \ + CHANNEL_PRAM_BASE(quicc,channel)->rbptr = \ + ((unsigned short)((char *)(bd) - (char *)(MCBASE(quicc,page)))) + +#define INCREASE_TBD_32(bd,quicc,page,channel) { \ + if((bd)->status & T_W) \ + (bd) = TBD_32_ADDR(quicc,page,channel); \ + else \ + (bd)++; \ +} +#define DECREASE_TBD_32(bd,quicc,page,channel) { \ + if ((bd) == TBD_32_ADDR(quicc, page,channel)) \ + while (!((bd)->status & T_W)) \ + (bd)++; \ + else \ + (bd)--; \ +} +#define INCREASE_RBD_32(bd,quicc,page,channel) { \ + if((bd)->status & R_W) \ + (bd) = RBD_32_ADDR(quicc,page,channel); \ + else \ + (bd)++; \ +} +#define DECREASE_RBD_32(bd,quicc,page,channel) { \ + if ((bd) == RBD_32_ADDR(quicc, page,channel)) \ + while (!((bd)->status & T_W)) \ + (bd)++; \ + else \ + (bd)--; \ +} + +#endif diff --git a/arch/m68k/include/asm/mac_asc.h b/arch/m68k/include/asm/mac_asc.h new file mode 100644 index 00000000000..fc2e5467b41 --- /dev/null +++ b/arch/m68k/include/asm/mac_asc.h @@ -0,0 +1,27 @@ +/* + * Apple Sound Chip + */ + +#ifndef __ASM_MAC_ASC_H +#define __ASM_MAC_ASC_H + +/* + * ASC offsets and controls + */ + +#define ASC_BUF_BASE 0x00 /* RAM buffer offset */ +#define ASC_BUF_SIZE 0x800 + +#define ASC_CONTROL 0x800 +#define ASC_CONTROL_OFF 0x00 +#define ASC_FREQ(chan,byte) ((0x810)+((chan)<<3)+(byte)) +#define ASC_ENABLE 0x801 +#define ASC_ENABLE_SAMPLE 0x02 +#define ASC_MODE 0x802 +#define ASC_MODE_SAMPLE 0x02 + +#define ASC_VOLUME 0x806 +#define ASC_CHAN 0x807 /* ??? */ + + +#endif diff --git a/arch/m68k/include/asm/mac_baboon.h b/arch/m68k/include/asm/mac_baboon.h new file mode 100644 index 00000000000..c2a042b8c34 --- /dev/null +++ b/arch/m68k/include/asm/mac_baboon.h @@ -0,0 +1,32 @@ +/* + * Definitions for the "Baboon" custom IC on the PowerBook 190. + */ + +#define BABOON_BASE (0x50F1A000) /* same as IDE controller base */ + +#ifndef __ASSEMBLY__ + +struct baboon { + char pad1[208]; /* generic IDE registers, not used here */ + short mb_control; /* Control register: + * bit 5 : slot 2 power control + * bit 6 : slot 1 power control + */ + char pad2[2]; + short mb_status; /* (0xD4) media bay status register: + * + * bit 0: ???? + * bit 1: IDE interrupt active? + * bit 2: bay status, 0 = full, 1 = empty + * bit 3: ???? + */ + char pad3[2]; /* (0xD6) not used */ + short mb_ifr; /* (0xD8) media bay interrupt flags register: + * + * bit 0: ???? + * bit 1: IDE controller interrupt + * bit 2: media bay status change interrupt + */ +}; + +#endif /* __ASSEMBLY **/ diff --git a/arch/m68k/include/asm/mac_iop.h b/arch/m68k/include/asm/mac_iop.h new file mode 100644 index 00000000000..a2c7e6fcca3 --- /dev/null +++ b/arch/m68k/include/asm/mac_iop.h @@ -0,0 +1,162 @@ +/* + * I/O Processor (IOP) defines and structures, mostly snagged from A/UX + * header files. + * + * The original header from which this was taken is copyrighted. I've done some + * rewriting (in fact my changes make this a bit more readable, IMHO) but some + * more should be done. + */ + +/* + * This is the base address of the IOPs. Use this as the address of + * a "struct iop" (see below) to see where the actual registers fall. + */ + +#define SCC_IOP_BASE_IIFX (0x50F04000) +#define ISM_IOP_BASE_IIFX (0x50F12000) + +#define SCC_IOP_BASE_QUADRA (0x50F0C000) +#define ISM_IOP_BASE_QUADRA (0x50F1E000) + +/* IOP status/control register bits: */ + +#define IOP_BYPASS 0x01 /* bypass-mode hardware access */ +#define IOP_AUTOINC 0x02 /* allow autoincrement of ramhi/lo */ +#define IOP_RUN 0x04 /* set to 0 to reset IOP chip */ +#define IOP_IRQ 0x08 /* generate IRQ to IOP if 1 */ +#define IOP_INT0 0x10 /* intr priority from IOP to host */ +#define IOP_INT1 0x20 /* intr priority from IOP to host */ +#define IOP_HWINT 0x40 /* IRQ from hardware; bypass mode only */ +#define IOP_DMAINACTIVE 0x80 /* no DMA request active; bypass mode only */ + +#define NUM_IOPS 2 +#define NUM_IOP_CHAN 7 +#define NUM_IOP_MSGS NUM_IOP_CHAN*8 +#define IOP_MSG_LEN 32 + +/* IOP reference numbers, used by the globally-visible iop_xxx functions */ + +#define IOP_NUM_SCC 0 +#define IOP_NUM_ISM 1 + +/* IOP channel states */ + +#define IOP_MSG_IDLE 0 /* idle */ +#define IOP_MSG_NEW 1 /* new message sent */ +#define IOP_MSG_RCVD 2 /* message received; processing */ +#define IOP_MSG_COMPLETE 3 /* message processing complete */ + +/* IOP message status codes */ + +#define IOP_MSGSTATUS_UNUSED 0 /* Unusued message structure */ +#define IOP_MSGSTATUS_WAITING 1 /* waiting for channel */ +#define IOP_MSGSTATUS_SENT 2 /* message sent, awaiting reply */ +#define IOP_MSGSTATUS_COMPLETE 3 /* message complete and reply rcvd */ +#define IOP_MSGSTATUS_UNSOL 6 /* message is unsolicited */ + +/* IOP memory addresses of the members of the mac_iop_kernel structure. */ + +#define IOP_ADDR_MAX_SEND_CHAN 0x0200 +#define IOP_ADDR_SEND_STATE 0x0201 +#define IOP_ADDR_PATCH_CTRL 0x021F +#define IOP_ADDR_SEND_MSG 0x0220 +#define IOP_ADDR_MAX_RECV_CHAN 0x0300 +#define IOP_ADDR_RECV_STATE 0x0301 +#define IOP_ADDR_ALIVE 0x031F +#define IOP_ADDR_RECV_MSG 0x0320 + +#ifndef __ASSEMBLY__ + +/* + * IOP Control registers, staggered because in usual Apple style they were + * too lazy to decode the A0 bit. This structure is assumed to begin at + * one of the xxx_IOP_BASE addresses given above. + */ + +struct mac_iop { + __u8 ram_addr_hi; /* shared RAM address hi byte */ + __u8 pad0; + __u8 ram_addr_lo; /* shared RAM address lo byte */ + __u8 pad1; + __u8 status_ctrl; /* status/control register */ + __u8 pad2[3]; + __u8 ram_data; /* RAM data byte at ramhi/lo */ + + __u8 pad3[23]; + + /* Bypass-mode hardware access registers */ + + union { + struct { /* SCC registers */ + __u8 sccb_cmd; /* SCC B command reg */ + __u8 pad4; + __u8 scca_cmd; /* SCC A command reg */ + __u8 pad5; + __u8 sccb_data; /* SCC B data */ + __u8 pad6; + __u8 scca_data; /* SCC A data */ + } scc_regs; + + struct { /* ISM registers */ + __u8 wdata; /* write a data byte */ + __u8 pad7; + __u8 wmark; /* write a mark byte */ + __u8 pad8; + __u8 wcrc; /* write 2-byte crc to disk */ + __u8 pad9; + __u8 wparams; /* write the param regs */ + __u8 pad10; + __u8 wphase; /* write the phase states & dirs */ + __u8 pad11; + __u8 wsetup; /* write the setup register */ + __u8 pad12; + __u8 wzeroes; /* mode reg: 1's clr bits, 0's are x */ + __u8 pad13; + __u8 wones; /* mode reg: 1's set bits, 0's are x */ + __u8 pad14; + __u8 rdata; /* read a data byte */ + __u8 pad15; + __u8 rmark; /* read a mark byte */ + __u8 pad16; + __u8 rerror; /* read the error register */ + __u8 pad17; + __u8 rparams; /* read the param regs */ + __u8 pad18; + __u8 rphase; /* read the phase states & dirs */ + __u8 pad19; + __u8 rsetup; /* read the setup register */ + __u8 pad20; + __u8 rmode; /* read the mode register */ + __u8 pad21; + __u8 rhandshake; /* read the handshake register */ + } ism_regs; + } b; +}; + +/* This structure is used to track IOP messages in the Linux kernel */ + +struct iop_msg { + struct iop_msg *next; /* next message in queue or NULL */ + uint iop_num; /* IOP number */ + uint channel; /* channel number */ + void *caller_priv; /* caller private data */ + int status; /* status of this message */ + __u8 message[IOP_MSG_LEN]; /* the message being sent/received */ + __u8 reply[IOP_MSG_LEN]; /* the reply to the message */ + void (*handler)(struct iop_msg *); + /* function to call when reply recvd */ +}; + +extern int iop_scc_present,iop_ism_present; + +extern int iop_listen(uint, uint, + void (*handler)(struct iop_msg *), + const char *); +extern int iop_send_message(uint, uint, void *, uint, __u8 *, + void (*)(struct iop_msg *)); +extern void iop_complete_message(struct iop_msg *); +extern void iop_upload_code(uint, __u8 *, uint, __u16); +extern void iop_download_code(uint, __u8 *, uint, __u16); +extern __u8 *iop_compare_code(uint, __u8 *, uint, __u16); + +#endif /* __ASSEMBLY__ */ diff --git a/arch/m68k/include/asm/mac_mouse.h b/arch/m68k/include/asm/mac_mouse.h new file mode 100644 index 00000000000..39a5c292eae --- /dev/null +++ b/arch/m68k/include/asm/mac_mouse.h @@ -0,0 +1,23 @@ +#ifndef _ASM_MAC_MOUSE_H +#define _ASM_MAC_MOUSE_H + +/* + * linux/include/asm-m68k/mac_mouse.h + * header file for Macintosh ADB mouse driver + * 27-10-97 Michael Schmitz + * copied from: + * header file for Atari Mouse driver + * by Robert de Vries (robert@and.nl) on 19Jul93 + */ + +struct mouse_status { + char buttons; + short dx; + short dy; + int ready; + int active; + wait_queue_head_t wait; + struct fasync_struct *fasyncptr; +}; + +#endif diff --git a/arch/m68k/include/asm/mac_oss.h b/arch/m68k/include/asm/mac_oss.h new file mode 100644 index 00000000000..7221f725193 --- /dev/null +++ b/arch/m68k/include/asm/mac_oss.h @@ -0,0 +1,94 @@ +/* + * OSS + * + * This is used in place of VIA2 on the IIfx. + */ + +#define OSS_BASE (0x50f1a000) + +/* + * Interrupt level offsets for mac_oss->irq_level + */ + +#define OSS_NUBUS0 0 +#define OSS_NUBUS1 1 +#define OSS_NUBUS2 2 +#define OSS_NUBUS3 3 +#define OSS_NUBUS4 4 +#define OSS_NUBUS5 5 +#define OSS_IOPISM 6 +#define OSS_IOPSCC 7 +#define OSS_SOUND 8 +#define OSS_SCSI 9 +#define OSS_60HZ 10 +#define OSS_VIA1 11 +#define OSS_UNUSED1 12 +#define OSS_UNUSED2 13 +#define OSS_PARITY 14 +#define OSS_UNUSED3 15 + +#define OSS_NUM_SOURCES 16 + +/* + * Pending interrupt bits in mac_oss->irq_pending + */ + +#define OSS_IP_NUBUS0 0x0001 +#define OSS_IP_NUBUS1 0x0002 +#define OSS_IP_NUBUS2 0x0004 +#define OSS_IP_NUBUS3 0x0008 +#define OSS_IP_NUBUS4 0x0010 +#define OSS_IP_NUBUS5 0x0020 +#define OSS_IP_IOPISM 0x0040 +#define OSS_IP_IOPSCC 0x0080 +#define OSS_IP_SOUND 0x0100 +#define OSS_IP_SCSI 0x0200 +#define OSS_IP_60HZ 0x0400 +#define OSS_IP_VIA1 0x0800 +#define OSS_IP_UNUSED1 0x1000 +#define OSS_IP_UNUSED2 0x2000 +#define OSS_IP_PARITY 0x4000 +#define OSS_IP_UNUSED3 0x8000 + +#define OSS_IP_NUBUS (OSS_IP_NUBUS0|OSS_IP_NUBUS1|OSS_IP_NUBUS2|OSS_IP_NUBUS3|OSS_IP_NUBUS4|OSS_IP_NUBUS5) + +/* + * Rom Control Register + */ + +#define OSS_POWEROFF 0x80 + +/* + * OSS Interrupt levels for various sub-systems + * + * This mapping is layed out with two things in mind: first, we try to keep + * things on their own levels to avoid having to do double-dispatches. Second, + * the levels match as closely as possible the alternate IRQ mapping mode (aka + * "A/UX mode") available on some VIA machines. + */ + +#define OSS_IRQLEV_DISABLED 0 +#define OSS_IRQLEV_IOPISM 1 /* ADB? */ +#define OSS_IRQLEV_SCSI IRQ_AUTO_2 +#define OSS_IRQLEV_NUBUS IRQ_AUTO_3 /* keep this on its own level */ +#define OSS_IRQLEV_IOPSCC IRQ_AUTO_4 /* matches VIA alternate mapping */ +#define OSS_IRQLEV_SOUND IRQ_AUTO_5 /* matches VIA alternate mapping */ +#define OSS_IRQLEV_60HZ 6 /* matches VIA alternate mapping */ +#define OSS_IRQLEV_VIA1 IRQ_AUTO_6 /* matches VIA alternate mapping */ +#define OSS_IRQLEV_PARITY 7 /* matches VIA alternate mapping */ + +#ifndef __ASSEMBLY__ + +struct mac_oss { + __u8 irq_level[0x10]; /* [0x000-0x00f] Interrupt levels */ + __u8 padding0[0x1F2]; /* [0x010-0x201] IO space filler */ + __u16 irq_pending; /* [0x202-0x203] pending interrupts bits */ + __u8 rom_ctrl; /* [0x204-0x204] ROM cntl reg (for poweroff) */ + __u8 padding1[0x2]; /* [0x205-0x206] currently unused by A/UX */ + __u8 ack_60hz; /* [0x207-0x207] 60 Hz ack. */ +}; + +extern volatile struct mac_oss *oss; +extern int oss_present; + +#endif /* __ASSEMBLY__ */ diff --git a/arch/m68k/include/asm/mac_psc.h b/arch/m68k/include/asm/mac_psc.h new file mode 100644 index 00000000000..7808bb0b232 --- /dev/null +++ b/arch/m68k/include/asm/mac_psc.h @@ -0,0 +1,248 @@ +/* + * Apple Peripheral System Controller (PSC) + * + * The PSC is used on the AV Macs to control IO functions not handled + * by the VIAs (Ethernet, DSP, SCC, Sound). This includes nine DMA + * channels. + * + * The first seven DMA channels appear to be "one-shot" and are actually + * sets of two channels; one member is active while the other is being + * configured, and then you flip the active member and start all over again. + * The one-shot channels are grouped together and are: + * + * 1. SCSI + * 2. Ethernet Read + * 3. Ethernet Write + * 4. Floppy Disk Controller + * 5. SCC Channel A Receive + * 6. SCC Channel B Receive + * 7. SCC Channel A Transmit + * + * The remaining two channels are handled somewhat differently. They appear + * to be closely tied and share one set of registers. They also seem to run + * continuously, although how you keep the buffer filled in this scenario is + * not understood as there seems to be only one input and one output buffer + * pointer. + * + * Much of this was extrapolated from what was known about the Ethernet + * registers and subsequently confirmed using MacsBug (ie by pinging the + * machine with easy-to-find patterns and looking for them in the DMA + * buffers, or by sending a file over the serial ports and finding the + * file in the buffers.) + * + * 1999-05-25 (jmt) + */ + +#define PSC_BASE (0x50F31000) + +/* + * The IER/IFR registers work like the VIA, except that it has 4 + * of them each on different interrupt levels, and each register + * set only seems to handle four interrupts instead of seven. + * + * To access a particular set of registers, add 0xn0 to the base + * where n = 3,4,5 or 6. + */ + +#define pIFRbase 0x100 +#define pIERbase 0x104 + +/* + * One-shot DMA control registers + */ + +#define PSC_MYSTERY 0x804 + +#define PSC_CTL_BASE 0xC00 + +#define PSC_SCSI_CTL 0xC00 +#define PSC_ENETRD_CTL 0xC10 +#define PSC_ENETWR_CTL 0xC20 +#define PSC_FDC_CTL 0xC30 +#define PSC_SCCA_CTL 0xC40 +#define PSC_SCCB_CTL 0xC50 +#define PSC_SCCATX_CTL 0xC60 + +/* + * DMA channels. Add +0x10 for the second channel in the set. + * You're supposed to use one channel while the other runs and + * then flip channels and do the whole thing again. + */ + +#define PSC_ADDR_BASE 0x1000 +#define PSC_LEN_BASE 0x1004 +#define PSC_CMD_BASE 0x1008 + +#define PSC_SET0 0x00 +#define PSC_SET1 0x10 + +#define PSC_SCSI_ADDR 0x1000 /* confirmed */ +#define PSC_SCSI_LEN 0x1004 /* confirmed */ +#define PSC_SCSI_CMD 0x1008 /* confirmed */ +#define PSC_ENETRD_ADDR 0x1020 /* confirmed */ +#define PSC_ENETRD_LEN 0x1024 /* confirmed */ +#define PSC_ENETRD_CMD 0x1028 /* confirmed */ +#define PSC_ENETWR_ADDR 0x1040 /* confirmed */ +#define PSC_ENETWR_LEN 0x1044 /* confirmed */ +#define PSC_ENETWR_CMD 0x1048 /* confirmed */ +#define PSC_FDC_ADDR 0x1060 /* strongly suspected */ +#define PSC_FDC_LEN 0x1064 /* strongly suspected */ +#define PSC_FDC_CMD 0x1068 /* strongly suspected */ +#define PSC_SCCA_ADDR 0x1080 /* confirmed */ +#define PSC_SCCA_LEN 0x1084 /* confirmed */ +#define PSC_SCCA_CMD 0x1088 /* confirmed */ +#define PSC_SCCB_ADDR 0x10A0 /* confirmed */ +#define PSC_SCCB_LEN 0x10A4 /* confirmed */ +#define PSC_SCCB_CMD 0x10A8 /* confirmed */ +#define PSC_SCCATX_ADDR 0x10C0 /* confirmed */ +#define PSC_SCCATX_LEN 0x10C4 /* confirmed */ +#define PSC_SCCATX_CMD 0x10C8 /* confirmed */ + +/* + * Free-running DMA registers. The only part known for sure are the bits in + * the control register, the buffer addresses and the buffer length. Everything + * else is anybody's guess. + * + * These registers seem to be mirrored every thirty-two bytes up until offset + * 0x300. It's safe to assume then that a new set of registers starts there. + */ + +#define PSC_SND_CTL 0x200 /* + * [ 16-bit ] + * Sound (Singer?) control register. + * + * bit 0 : ???? + * bit 1 : ???? + * bit 2 : Set to one to enable sound + * output. Possibly a mute flag. + * bit 3 : ???? + * bit 4 : ???? + * bit 5 : ???? + * bit 6 : Set to one to enable pass-thru + * audio. In this mode the audio data + * seems to appear in both the input + * buffer and the output buffer. + * bit 7 : Set to one to activate the + * sound input DMA or zero to + * disable it. + * bit 8 : Set to one to activate the + * sound output DMA or zero to + * disable it. + * bit 9 : \ + * bit 11 : | + * These two bits control the sample + * rate. Usually set to binary 10 and + * MacOS 8.0 says I'm at 48 KHz. Using + * a binary value of 01 makes things + * sound about 1/2 speed (24 KHz?) and + * binary 00 is slower still (22 KHz?) + * + * Setting this to 0x0000 is a good way to + * kill all DMA at boot time so that the + * PSC won't overwrite the kernel image + * with sound data. + */ + +/* + * 0x0202 - 0x0203 is unused. Writing there + * seems to clobber the control register. + */ + +#define PSC_SND_SOURCE 0x204 /* + * [ 32-bit ] + * Controls input source and volume: + * + * bits 12-15 : input source volume, 0 - F + * bits 16-19 : unknown, always 0x5 + * bits 20-23 : input source selection: + * 0x3 = CD Audio + * 0x4 = External Audio + * + * The volume is definitely not the general + * output volume as it doesn't affect the + * alert sound volume. + */ +#define PSC_SND_STATUS1 0x208 /* + * [ 32-bit ] + * Appears to be a read-only status register. + * The usual value is 0x00400002. + */ +#define PSC_SND_HUH3 0x20C /* + * [ 16-bit ] + * Unknown 16-bit value, always 0x0000. + */ +#define PSC_SND_BITS2GO 0x20E /* + * [ 16-bit ] + * Counts down to zero from some constant + * value. The value appears to be the + * number of _bits_ remaining before the + * buffer is full, which would make sense + * since Apple's docs say the sound DMA + * channels are 1 bit wide. + */ +#define PSC_SND_INADDR 0x210 /* + * [ 32-bit ] + * Address of the sound input DMA buffer + */ +#define PSC_SND_OUTADDR 0x214 /* + * [ 32-bit ] + * Address of the sound output DMA buffer + */ +#define PSC_SND_LEN 0x218 /* + * [ 16-bit ] + * Length of both buffers in eight-byte units. + */ +#define PSC_SND_HUH4 0x21A /* + * [ 16-bit ] + * Unknown, always 0x0000. + */ +#define PSC_SND_STATUS2 0x21C /* + * [ 16-bit ] + * Appears to e a read-only status register. + * The usual value is 0x0200. + */ +#define PSC_SND_HUH5 0x21E /* + * [ 16-bit ] + * Unknown, always 0x0000. + */ + +#ifndef __ASSEMBLY__ + +extern volatile __u8 *psc; +extern int psc_present; + +/* + * Access functions + */ + +static inline void psc_write_byte(int offset, __u8 data) +{ + *((volatile __u8 *)(psc + offset)) = data; +} + +static inline void psc_write_word(int offset, __u16 data) +{ + *((volatile __u16 *)(psc + offset)) = data; +} + +static inline void psc_write_long(int offset, __u32 data) +{ + *((volatile __u32 *)(psc + offset)) = data; +} + +static inline u8 psc_read_byte(int offset) +{ + return *((volatile __u8 *)(psc + offset)); +} + +static inline u16 psc_read_word(int offset) +{ + return *((volatile __u16 *)(psc + offset)); +} + +static inline u32 psc_read_long(int offset) +{ + return *((volatile __u32 *)(psc + offset)); +} + +#endif /* __ASSEMBLY__ */ diff --git a/arch/m68k/include/asm/mac_via.h b/arch/m68k/include/asm/mac_via.h new file mode 100644 index 00000000000..39afb438b65 --- /dev/null +++ b/arch/m68k/include/asm/mac_via.h @@ -0,0 +1,267 @@ +/* + * 6522 Versatile Interface Adapter (VIA) + * + * There are two of these on the Mac II. Some IRQ's are vectored + * via them as are assorted bits and bobs - eg rtc, adb. The picture + * is a bit incomplete as the Mac documentation doesn't cover this well + */ + +#ifndef _ASM_MAC_VIA_H_ +#define _ASM_MAC_VIA_H_ + +/* + * Base addresses for the VIAs. There are two in every machine, + * although on some machines the second is an RBV or an OSS. + * The OSS is different enough that it's handled separately. + * + * Do not use these values directly; use the via1 and via2 variables + * instead (and don't forget to check rbv_present when using via2!) + */ + +#define VIA1_BASE (0x50F00000) +#define VIA2_BASE (0x50F02000) +#define RBV_BASE (0x50F26000) + +/* + * Not all of these are true post MacII I think. + * CSA: probably the ones CHRP marks as 'unused' change purposes + * when the IWM becomes the SWIM. + * http://www.rs6000.ibm.com/resource/technology/chrpio/via5.mak.html + * ftp://ftp.austin.ibm.com/pub/technology/spec/chrp/inwork/CHRP_IORef_1.0.pdf + * + * also, http://developer.apple.com/technotes/hw/hw_09.html claims the + * following changes for IIfx: + * VIA1A_vSccWrReq not available and that VIA1A_vSync has moved to an IOP. + * Also, "All of the functionality of VIA2 has been moved to other chips". + */ + +#define VIA1A_vSccWrReq 0x80 /* SCC write. (input) + * [CHRP] SCC WREQ: Reflects the state of the + * Wait/Request pins from the SCC. + * [Macintosh Family Hardware] + * as CHRP on SE/30,II,IIx,IIcx,IIci. + * on IIfx, "0 means an active request" + */ +#define VIA1A_vRev8 0x40 /* Revision 8 board ??? + * [CHRP] En WaitReqB: Lets the WaitReq_L + * signal from port B of the SCC appear on + * the PA7 input pin. Output. + * [Macintosh Family] On the SE/30, this + * is the bit to flip screen buffers. + * 0=alternate, 1=main. + * on II,IIx,IIcx,IIci,IIfx this is a bit + * for Rev ID. 0=II,IIx, 1=IIcx,IIci,IIfx + */ +#define VIA1A_vHeadSel 0x20 /* Head select for IWM. + * [CHRP] unused. + * [Macintosh Family] "Floppy disk + * state-control line SEL" on all but IIfx + */ +#define VIA1A_vOverlay 0x10 /* [Macintosh Family] On SE/30,II,IIx,IIcx + * this bit enables the "Overlay" address + * map in the address decoders as it is on + * reset for mapping the ROM over the reset + * vector. 1=use overlay map. + * On the IIci,IIfx it is another bit of the + * CPU ID: 0=normal IIci, 1=IIci with parity + * feature or IIfx. + * [CHRP] En WaitReqA: Lets the WaitReq_L + * signal from port A of the SCC appear + * on the PA7 input pin (CHRP). Output. + * [MkLinux] "Drive Select" + * (with 0x20 being 'disk head select') + */ +#define VIA1A_vSync 0x08 /* [CHRP] Sync Modem: modem clock select: + * 1: select the external serial clock to + * drive the SCC's /RTxCA pin. + * 0: Select the 3.6864MHz clock to drive + * the SCC cell. + * [Macintosh Family] Correct on all but IIfx + */ + +/* Macintosh Family Hardware sez: bits 0-2 of VIA1A are volume control + * on Macs which had the PWM sound hardware. Reserved on newer models. + * On IIci,IIfx, bits 1-2 are the rest of the CPU ID: + * bit 2: 1=IIci, 0=IIfx + * bit 1: 1 on both IIci and IIfx. + * MkLinux sez bit 0 is 'burnin flag' in this case. + * CHRP sez: VIA1A bits 0-2 and 5 are 'unused': if programmed as + * inputs, these bits will read 0. + */ +#define VIA1A_vVolume 0x07 /* Audio volume mask for PWM */ +#define VIA1A_CPUID0 0x02 /* CPU id bit 0 on RBV, others */ +#define VIA1A_CPUID1 0x04 /* CPU id bit 0 on RBV, others */ +#define VIA1A_CPUID2 0x10 /* CPU id bit 0 on RBV, others */ +#define VIA1A_CPUID3 0x40 /* CPU id bit 0 on RBV, others */ + +/* Info on VIA1B is from Macintosh Family Hardware & MkLinux. + * CHRP offers no info. */ +#define VIA1B_vSound 0x80 /* Sound enable (for compatibility with + * PWM hardware) 0=enabled. + * Also, on IIci w/parity, shows parity error + * 0=error, 1=OK. */ +#define VIA1B_vMystery 0x40 /* On IIci, parity enable. 0=enabled,1=disabled + * On SE/30, vertical sync interrupt enable. + * 0=enabled. This vSync interrupt shows up + * as a slot $E interrupt. */ +#define VIA1B_vADBS2 0x20 /* ADB state input bit 1 (unused on IIfx) */ +#define VIA1B_vADBS1 0x10 /* ADB state input bit 0 (unused on IIfx) */ +#define VIA1B_vADBInt 0x08 /* ADB interrupt 0=interrupt (unused on IIfx)*/ +#define VIA1B_vRTCEnb 0x04 /* Enable Real time clock. 0=enabled. */ +#define VIA1B_vRTCClk 0x02 /* Real time clock serial-clock line. */ +#define VIA1B_vRTCData 0x01 /* Real time clock serial-data line. */ + +/* MkLinux defines the following "VIA1 Register B contents where they + * differ from standard VIA1". From the naming scheme, we assume they + * correspond to a VIA work-alike named 'EVR'. */ +#define EVRB_XCVR 0x08 /* XCVR_SESSION* */ +#define EVRB_FULL 0x10 /* VIA_FULL */ +#define EVRB_SYSES 0x20 /* SYS_SESSION */ +#define EVRB_AUXIE 0x00 /* Enable A/UX Interrupt Scheme */ +#define EVRB_AUXID 0x40 /* Disable A/UX Interrupt Scheme */ +#define EVRB_SFTWRIE 0x00 /* Software Interrupt ReQuest */ +#define EVRB_SFTWRID 0x80 /* Software Interrupt ReQuest */ + +/* + * VIA2 A register is the interrupt lines raised off the nubus + * slots. + * The below info is from 'Macintosh Family Hardware.' + * MkLinux calls the 'IIci internal video IRQ' below the 'RBV slot 0 irq.' + * It also notes that the slot $9 IRQ is the 'Ethernet IRQ' and + * defines the 'Video IRQ' as 0x40 for the 'EVR' VIA work-alike. + * Perhaps OSS uses vRAM1 and vRAM2 for ADB. + */ + +#define VIA2A_vRAM1 0x80 /* RAM size bit 1 (IIci: reserved) */ +#define VIA2A_vRAM0 0x40 /* RAM size bit 0 (IIci: internal video IRQ) */ +#define VIA2A_vIRQE 0x20 /* IRQ from slot $E */ +#define VIA2A_vIRQD 0x10 /* IRQ from slot $D */ +#define VIA2A_vIRQC 0x08 /* IRQ from slot $C */ +#define VIA2A_vIRQB 0x04 /* IRQ from slot $B */ +#define VIA2A_vIRQA 0x02 /* IRQ from slot $A */ +#define VIA2A_vIRQ9 0x01 /* IRQ from slot $9 */ + +/* RAM size bits decoded as follows: + * bit1 bit0 size of ICs in bank A + * 0 0 256 kbit + * 0 1 1 Mbit + * 1 0 4 Mbit + * 1 1 16 Mbit + */ + +/* + * Register B has the fun stuff in it + */ + +#define VIA2B_vVBL 0x80 /* VBL output to VIA1 (60.15Hz) driven by + * timer T1. + * on IIci, parity test: 0=test mode. + * [MkLinux] RBV_PARODD: 1=odd,0=even. */ +#define VIA2B_vSndJck 0x40 /* External sound jack status. + * 0=plug is inserted. On SE/30, always 0 */ +#define VIA2B_vTfr0 0x20 /* Transfer mode bit 0 ack from NuBus */ +#define VIA2B_vTfr1 0x10 /* Transfer mode bit 1 ack from NuBus */ +#define VIA2B_vMode32 0x08 /* 24/32bit switch - doubles as cache flush + * on II, AMU/PMMU control. + * if AMU, 0=24bit to 32bit translation + * if PMMU, 1=PMMU is accessing page table. + * on SE/30 tied low. + * on IIx,IIcx,IIfx, unused. + * on IIci/RBV, cache control. 0=flush cache. + */ +#define VIA2B_vPower 0x04 /* Power off, 0=shut off power. + * on SE/30 this signal sent to PDS card. */ +#define VIA2B_vBusLk 0x02 /* Lock NuBus transactions, 0=locked. + * on SE/30 sent to PDS card. */ +#define VIA2B_vCDis 0x01 /* Cache control. On IIci, 1=disable cache card + * on others, 0=disable processor's instruction + * and data caches. */ + +/* Apple sez: http://developer.apple.com/technotes/ov/ov_04.html + * Another example of a valid function that has no ROM support is the use + * of the alternate video page for page-flipping animation. Since there + * is no ROM call to flip pages, it is necessary to go play with the + * right bit in the VIA chip (6522 Versatile Interface Adapter). + * [CSA: don't know which one this is, but it's one of 'em!] + */ + +/* + * 6522 registers - see databook. + * CSA: Assignments for VIA1 confirmed from CHRP spec. + */ + +/* partial address decode. 0xYYXX : XX part for RBV, YY part for VIA */ +/* Note: 15 VIA regs, 8 RBV regs */ + +#define vBufB 0x0000 /* [VIA/RBV] Register B */ +#define vBufAH 0x0200 /* [VIA only] Buffer A, with handshake. DON'T USE! */ +#define vDirB 0x0400 /* [VIA only] Data Direction Register B. */ +#define vDirA 0x0600 /* [VIA only] Data Direction Register A. */ +#define vT1CL 0x0800 /* [VIA only] Timer one counter low. */ +#define vT1CH 0x0a00 /* [VIA only] Timer one counter high. */ +#define vT1LL 0x0c00 /* [VIA only] Timer one latches low. */ +#define vT1LH 0x0e00 /* [VIA only] Timer one latches high. */ +#define vT2CL 0x1000 /* [VIA only] Timer two counter low. */ +#define vT2CH 0x1200 /* [VIA only] Timer two counter high. */ +#define vSR 0x1400 /* [VIA only] Shift register. */ +#define vACR 0x1600 /* [VIA only] Auxilary control register. */ +#define vPCR 0x1800 /* [VIA only] Peripheral control register. */ + /* CHRP sez never ever to *write* this. + * Mac family says never to *change* this. + * In fact we need to initialize it once at start. */ +#define vIFR 0x1a00 /* [VIA/RBV] Interrupt flag register. */ +#define vIER 0x1c00 /* [VIA/RBV] Interrupt enable register. */ +#define vBufA 0x1e00 /* [VIA/RBV] register A (no handshake) */ + +/* The RBV only decodes the bottom eight address lines; the VIA doesn't + * decode the bottom eight -- so vBufB | rBufB will always get you BufB */ +/* CSA: in fact, only bits 0,1, and 4 seem to be decoded. + * BUT note the values for rIER and rIFR, where the top 8 bits *do* seem + * to matter. In fact *all* of the top 8 bits seem to matter; + * setting rIER=0x1813 and rIFR=0x1803 doesn't work, either. + * Perhaps some sort of 'compatibility mode' is built-in? [21-May-1999] + */ + +#define rBufB 0x0000 /* [VIA/RBV] Register B */ +#define rExp 0x0001 /* [RBV only] RBV future expansion (always 0) */ +#define rSIFR 0x0002 /* [RBV only] RBV slot interrupts register. */ +#define rIFR 0x1a03 /* [VIA/RBV] RBV interrupt flag register. */ +#define rMonP 0x0010 /* [RBV only] RBV video monitor type. */ +#define rChpT 0x0011 /* [RBV only] RBV test mode register (reads as 0). */ +#define rSIER 0x0012 /* [RBV only] RBV slot interrupt enables. */ +#define rIER 0x1c13 /* [VIA/RBV] RBV interrupt flag enable register. */ +#define rBufA rSIFR /* the 'slot interrupts register' is BufA on a VIA */ + +/* + * Video monitor parameters, for rMonP: + */ +#define RBV_DEPTH 0x07 /* bits per pixel: 000=1,001=2,010=4,011=8 */ +#define RBV_MONID 0x38 /* monitor type, as below. */ +#define RBV_VIDOFF 0x40 /* 1 turns off onboard video */ +/* Supported monitor types: */ +#define MON_15BW (1<<3) /* 15" BW portrait. */ +#define MON_IIGS (2<<3) /* 12" color (modified IIGS monitor). */ +#define MON_15RGB (5<<3) /* 15" RGB portrait. */ +#define MON_12OR13 (6<<3) /* 12" BW or 13" RGB. */ +#define MON_NONE (7<<3) /* No monitor attached. */ + +/* To clarify IER manipulations */ +#define IER_SET_BIT(b) (0x80 | (1<<(b)) ) +#define IER_CLR_BIT(b) (0x7F & (1<<(b)) ) + +#ifndef __ASSEMBLY__ + +extern volatile __u8 *via1,*via2; +extern int rbv_present,via_alt_mapping; + +static inline int rbv_set_video_bpp(int bpp) +{ + char val = (bpp==1)?0:(bpp==2)?1:(bpp==4)?2:(bpp==8)?3:-1; + if (!rbv_present || val<0) return -1; + via2[rMonP] = (via2[rMonP] & ~RBV_DEPTH) | val; + return 0; +} + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_MAC_VIA_H_ */ diff --git a/arch/m68k/include/asm/machdep.h b/arch/m68k/include/asm/machdep.h new file mode 100644 index 00000000000..fc24b6fc550 --- /dev/null +++ b/arch/m68k/include/asm/machdep.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "machdep_no.h" +#else +#include "machdep_mm.h" +#endif diff --git a/arch/m68k/include/asm/machdep_mm.h b/arch/m68k/include/asm/machdep_mm.h new file mode 100644 index 00000000000..5637dcef314 --- /dev/null +++ b/arch/m68k/include/asm/machdep_mm.h @@ -0,0 +1,35 @@ +#ifndef _M68K_MACHDEP_H +#define _M68K_MACHDEP_H + +#include +#include + +struct pt_regs; +struct mktime; +struct rtc_time; +struct rtc_pll_info; +struct buffer_head; + +extern void (*mach_sched_init) (irq_handler_t handler); +/* machine dependent irq functions */ +extern void (*mach_init_IRQ) (void); +extern void (*mach_get_model) (char *model); +extern void (*mach_get_hardware_list) (struct seq_file *m); +/* machine dependent timer functions */ +extern unsigned long (*mach_gettimeoffset)(void); +extern int (*mach_hwclk)(int, struct rtc_time*); +extern unsigned int (*mach_get_ss)(void); +extern int (*mach_get_rtc_pll)(struct rtc_pll_info *); +extern int (*mach_set_rtc_pll)(struct rtc_pll_info *); +extern int (*mach_set_clock_mmss)(unsigned long); +extern void (*mach_reset)( void ); +extern void (*mach_halt)( void ); +extern void (*mach_power_off)( void ); +extern unsigned long (*mach_hd_init) (unsigned long, unsigned long); +extern void (*mach_hd_setup)(char *, int *); +extern long mach_max_dma_address; +extern void (*mach_heartbeat) (int); +extern void (*mach_l2_flush) (int); +extern void (*mach_beep) (unsigned int, unsigned int); + +#endif /* _M68K_MACHDEP_H */ diff --git a/arch/m68k/include/asm/machdep_no.h b/arch/m68k/include/asm/machdep_no.h new file mode 100644 index 00000000000..de9f47a51cc --- /dev/null +++ b/arch/m68k/include/asm/machdep_no.h @@ -0,0 +1,26 @@ +#ifndef _M68KNOMMU_MACHDEP_H +#define _M68KNOMMU_MACHDEP_H + +#include + +/* Hardware clock functions */ +extern void hw_timer_init(void); +extern unsigned long hw_timer_offset(void); + +extern irqreturn_t arch_timer_interrupt(int irq, void *dummy); + +/* Machine dependent time handling */ +extern void (*mach_gettod)(int *year, int *mon, int *day, int *hour, + int *min, int *sec); +extern int (*mach_set_clock_mmss)(unsigned long); + +/* machine dependent power off functions */ +extern void (*mach_reset)( void ); +extern void (*mach_halt)( void ); +extern void (*mach_power_off)( void ); + +extern void config_BSP(char *command, int len); + +extern void do_IRQ(int irq, struct pt_regs *fp); + +#endif /* _M68KNOMMU_MACHDEP_H */ diff --git a/arch/m68k/include/asm/machines.h b/arch/m68k/include/asm/machines.h new file mode 100644 index 00000000000..be667e84f01 --- /dev/null +++ b/arch/m68k/include/asm/machines.h @@ -0,0 +1,85 @@ +/* + * machines.h: Defines for taking apart the machine type value in the + * idprom and determining the kind of machine we are on. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * Sun3/3x models added by David Monro (davidm@psrg.cs.usyd.edu.au) + */ +#ifndef _SPARC_MACHINES_H +#define _SPARC_MACHINES_H + +struct Sun_Machine_Models { + char *name; + unsigned char id_machtype; +}; + +/* Current number of machines we know about that has an IDPROM + * machtype entry including one entry for the 0x80 OBP machines. + */ +// reduced along with table in arch/m68k/sun3/idprom.c +// sun3 port doesn't need to know about sparc machines. +//#define NUM_SUN_MACHINES 23 +#define NUM_SUN_MACHINES 8 + +/* The machine type in the idprom area looks like this: + * + * --------------- + * | ARCH | MACH | + * --------------- + * 7 4 3 0 + * + * The ARCH field determines the architecture line (sun4, sun4c, etc). + * The MACH field determines the machine make within that architecture. + */ + +#define SM_ARCH_MASK 0xf0 +#define SM_SUN3 0x10 +#define SM_SUN4 0x20 +#define SM_SUN3X 0x40 +#define SM_SUN4C 0x50 +#define SM_SUN4M 0x70 +#define SM_SUN4M_OBP 0x80 + +#define SM_TYP_MASK 0x0f +/* Sun3 machines */ +#define SM_3_160 0x01 /* Sun 3/160 series */ +#define SM_3_50 0x02 /* Sun 3/50 series */ +#define SM_3_260 0x03 /* Sun 3/260 series */ +#define SM_3_110 0x04 /* Sun 3/110 series */ +#define SM_3_60 0x07 /* Sun 3/60 series */ +#define SM_3_E 0x08 /* Sun 3/E series */ + +/* Sun3x machines */ +#define SM_3_460 0x01 /* Sun 3/460 (460,470,480) series */ +#define SM_3_80 0x02 /* Sun 3/80 series */ + +/* Sun4 machines */ +#define SM_4_260 0x01 /* Sun 4/200 series */ +#define SM_4_110 0x02 /* Sun 4/100 series */ +#define SM_4_330 0x03 /* Sun 4/300 series */ +#define SM_4_470 0x04 /* Sun 4/400 series */ + +/* Sun4c machines Full Name - PROM NAME */ +#define SM_4C_SS1 0x01 /* Sun4c SparcStation 1 - Sun 4/60 */ +#define SM_4C_IPC 0x02 /* Sun4c SparcStation IPC - Sun 4/40 */ +#define SM_4C_SS1PLUS 0x03 /* Sun4c SparcStation 1+ - Sun 4/65 */ +#define SM_4C_SLC 0x04 /* Sun4c SparcStation SLC - Sun 4/20 */ +#define SM_4C_SS2 0x05 /* Sun4c SparcStation 2 - Sun 4/75 */ +#define SM_4C_ELC 0x06 /* Sun4c SparcStation ELC - Sun 4/25 */ +#define SM_4C_IPX 0x07 /* Sun4c SparcStation IPX - Sun 4/50 */ + +/* Sun4m machines, these predate the OpenBoot. These values only mean + * something if the value in the ARCH field is SM_SUN4M, if it is + * SM_SUN4M_OBP then you have the following situation: + * 1) You either have a sun4d, a sun4e, or a recently made sun4m. + * 2) You have to consult OpenBoot to determine which machine this is. + */ +#define SM_4M_SS60 0x01 /* Sun4m SparcSystem 600 */ +#define SM_4M_SS50 0x02 /* Sun4m SparcStation 10 */ +#define SM_4M_SS40 0x03 /* Sun4m SparcStation 5 */ + +/* Sun4d machines -- N/A */ +/* Sun4e machines -- N/A */ +/* Sun4u machines -- N/A */ + +#endif /* !(_SPARC_MACHINES_H) */ diff --git a/arch/m68k/include/asm/machw.h b/arch/m68k/include/asm/machw.h new file mode 100644 index 00000000000..2b4de0c2ce4 --- /dev/null +++ b/arch/m68k/include/asm/machw.h @@ -0,0 +1,49 @@ +/* +** linux/machw.h -- This header defines some macros and pointers for +** the various Macintosh custom hardware registers. +** +** Copyright 1997 by Michael Schmitz +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +*/ + +#ifndef _ASM_MACHW_H_ +#define _ASM_MACHW_H_ + +/* + * head.S maps the videomem to VIDEOMEMBASE + */ + +#define VIDEOMEMBASE 0xf0000000 +#define VIDEOMEMSIZE (4096*1024) +#define VIDEOMEMMASK (-4096*1024) + +#ifndef __ASSEMBLY__ + +#include + +#if 0 +/* +** SCC Z8530 +*/ + +#define MAC_SCC_BAS (0x50F04000) +struct MAC_SCC + { + u_char cha_a_ctrl; + u_char char_dummy1; + u_char cha_a_data; + u_char char_dummy2; + u_char cha_b_ctrl; + u_char char_dummy3; + u_char cha_b_data; + }; +# define mac_scc ((*(volatile struct SCC*)MAC_SCC_BAS)) +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* linux/machw.h */ diff --git a/arch/m68k/include/asm/macintosh.h b/arch/m68k/include/asm/macintosh.h new file mode 100644 index 00000000000..05309f7e3d0 --- /dev/null +++ b/arch/m68k/include/asm/macintosh.h @@ -0,0 +1,135 @@ +#ifndef __ASM_MACINTOSH_H +#define __ASM_MACINTOSH_H + +#include +#include + +/* + * Apple Macintoshisms + */ + +extern void mac_reset(void); +extern void mac_poweroff(void); +extern void mac_init_IRQ(void); +extern int mac_irq_pending(unsigned int); + +/* + * Floppy driver magic hook - probably shouldnt be here + */ + +extern void via1_set_head(int); + +/* + * Macintosh Table + */ + +struct mac_model +{ + short ident; + char *name; + char adb_type; + char via_type; + char scsi_type; + char ide_type; + char scc_type; + char ether_type; + char nubus_type; +}; + +#define MAC_ADB_NONE 0 +#define MAC_ADB_II 1 +#define MAC_ADB_IISI 2 +#define MAC_ADB_CUDA 3 +#define MAC_ADB_PB1 4 +#define MAC_ADB_PB2 5 +#define MAC_ADB_IOP 6 + +#define MAC_VIA_II 1 +#define MAC_VIA_IIci 2 +#define MAC_VIA_QUADRA 3 + +#define MAC_SCSI_NONE 0 +#define MAC_SCSI_OLD 1 +#define MAC_SCSI_QUADRA 2 +#define MAC_SCSI_QUADRA2 3 +#define MAC_SCSI_QUADRA3 4 + +#define MAC_IDE_NONE 0 +#define MAC_IDE_QUADRA 1 +#define MAC_IDE_PB 2 +#define MAC_IDE_BABOON 3 + +#define MAC_SCC_II 1 +#define MAC_SCC_IOP 2 +#define MAC_SCC_QUADRA 3 +#define MAC_SCC_PSC 4 + +#define MAC_ETHER_NONE 0 +#define MAC_ETHER_SONIC 1 +#define MAC_ETHER_MACE 2 + +#define MAC_NO_NUBUS 0 +#define MAC_NUBUS 1 + +/* + * Gestalt numbers + */ + +#define MAC_MODEL_II 6 +#define MAC_MODEL_IIX 7 +#define MAC_MODEL_IICX 8 +#define MAC_MODEL_SE30 9 +#define MAC_MODEL_IICI 11 +#define MAC_MODEL_IIFX 13 /* And well numbered it is too */ +#define MAC_MODEL_IISI 18 +#define MAC_MODEL_LC 19 +#define MAC_MODEL_Q900 20 +#define MAC_MODEL_PB170 21 +#define MAC_MODEL_Q700 22 +#define MAC_MODEL_CLII 23 /* aka: P200 */ +#define MAC_MODEL_PB140 25 +#define MAC_MODEL_Q950 26 /* aka: WGS95 */ +#define MAC_MODEL_LCIII 27 /* aka: P450 */ +#define MAC_MODEL_PB210 29 +#define MAC_MODEL_C650 30 +#define MAC_MODEL_PB230 32 +#define MAC_MODEL_PB180 33 +#define MAC_MODEL_PB160 34 +#define MAC_MODEL_Q800 35 /* aka: WGS80 */ +#define MAC_MODEL_Q650 36 +#define MAC_MODEL_LCII 37 /* aka: P400/405/410/430 */ +#define MAC_MODEL_PB250 38 +#define MAC_MODEL_IIVI 44 +#define MAC_MODEL_P600 45 /* aka: P600CD */ +#define MAC_MODEL_IIVX 48 +#define MAC_MODEL_CCL 49 /* aka: P250 */ +#define MAC_MODEL_PB165C 50 +#define MAC_MODEL_C610 52 /* aka: WGS60 */ +#define MAC_MODEL_Q610 53 +#define MAC_MODEL_PB145 54 /* aka: PB145B */ +#define MAC_MODEL_P520 56 /* aka: LC520 */ +#define MAC_MODEL_C660 60 +#define MAC_MODEL_P460 62 /* aka: LCIII+, P466/P467 */ +#define MAC_MODEL_PB180C 71 +#define MAC_MODEL_PB520 72 /* aka: PB520C, PB540, PB540C, PB550C */ +#define MAC_MODEL_PB270C 77 +#define MAC_MODEL_Q840 78 +#define MAC_MODEL_P550 80 /* aka: LC550, P560 */ +#define MAC_MODEL_CCLII 83 /* aka: P275 */ +#define MAC_MODEL_PB165 84 +#define MAC_MODEL_PB190 85 /* aka: PB190CS */ +#define MAC_MODEL_TV 88 +#define MAC_MODEL_P475 89 /* aka: LC475, P476 */ +#define MAC_MODEL_P475F 90 /* aka: P475 w/ FPU (no LC040) */ +#define MAC_MODEL_P575 92 /* aka: LC575, P577/P578 */ +#define MAC_MODEL_Q605 94 +#define MAC_MODEL_Q605_ACC 95 /* Q605 accelerated to 33 MHz */ +#define MAC_MODEL_Q630 98 /* aka: LC630, P630/631/635/636/637/638/640 */ +#define MAC_MODEL_P588 99 /* aka: LC580, P580 */ +#define MAC_MODEL_PB280 102 +#define MAC_MODEL_PB280C 103 +#define MAC_MODEL_PB150 115 + +extern struct mac_model *macintosh_config; + +#endif diff --git a/arch/m68k/include/asm/macints.h b/arch/m68k/include/asm/macints.h new file mode 100644 index 00000000000..679c48ab440 --- /dev/null +++ b/arch/m68k/include/asm/macints.h @@ -0,0 +1,155 @@ +/* +** macints.h -- Macintosh Linux interrupt handling structs and prototypes +** +** Copyright 1997 by Michael Schmitz +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +*/ + +#ifndef _ASM_MACINTS_H_ +#define _ASM_MACINTS_H_ + +#include + +/* Setting this prints debugging info for unclaimed interrupts */ + +#define DEBUG_SPURIOUS + +/* Setting this prints debugging info on each autovector interrupt */ + +/* #define DEBUG_IRQS */ + +/* Setting this prints debugging info on each Nubus interrupt */ + +/* #define DEBUG_NUBUS_INT */ + +/* Setting this prints debugging info on irqs as they enabled and disabled. */ + +/* #define DEBUG_IRQUSE */ + +/* + * Base IRQ number for all Mac68K interrupt sources. Each source + * has eight indexes (base -> base+7). + */ + +#define VIA1_SOURCE_BASE 8 +#define VIA2_SOURCE_BASE 16 +#define MAC_SCC_SOURCE_BASE 24 +#define PSC3_SOURCE_BASE 24 +#define PSC4_SOURCE_BASE 32 +#define PSC5_SOURCE_BASE 40 +#define PSC6_SOURCE_BASE 48 +#define NUBUS_SOURCE_BASE 56 +#define BABOON_SOURCE_BASE 64 + +/* + * Maximum IRQ number is BABOON_SOURCE_BASE + 7, + * giving us IRQs up through 71 + */ + +#define NUM_MAC_SOURCES 72 + +/* + * clean way to separate IRQ into its source and index + */ + +#define IRQ_SRC(irq) (irq >> 3) +#define IRQ_IDX(irq) (irq & 7) + +/* VIA1 interrupts */ +#define IRQ_VIA1_0 (8) /* one second int. */ +#define IRQ_VIA1_1 (9) /* VBlank int. */ +#define IRQ_MAC_VBL IRQ_VIA1_1 +#define IRQ_VIA1_2 (10) /* ADB SR shifts complete */ +#define IRQ_MAC_ADB IRQ_VIA1_2 +#define IRQ_MAC_ADB_SR IRQ_VIA1_2 +#define IRQ_VIA1_3 (11) /* ADB SR CB2 ?? */ +#define IRQ_MAC_ADB_SD IRQ_VIA1_3 +#define IRQ_VIA1_4 (12) /* ADB SR ext. clock pulse */ +#define IRQ_MAC_ADB_CL IRQ_VIA1_4 +#define IRQ_VIA1_5 (13) +#define IRQ_MAC_TIMER_2 IRQ_VIA1_5 +#define IRQ_VIA1_6 (14) +#define IRQ_MAC_TIMER_1 IRQ_VIA1_6 +#define IRQ_VIA1_7 (15) + +/* VIA2/RBV interrupts */ +#define IRQ_VIA2_0 (16) +#define IRQ_MAC_SCSIDRQ IRQ_VIA2_0 +#define IRQ_VIA2_1 (17) +#define IRQ_MAC_NUBUS IRQ_VIA2_1 +#define IRQ_VIA2_2 (18) +#define IRQ_VIA2_3 (19) +#define IRQ_MAC_SCSI IRQ_VIA2_3 +#define IRQ_VIA2_4 (20) +#define IRQ_VIA2_5 (21) +#define IRQ_VIA2_6 (22) +#define IRQ_VIA2_7 (23) + +/* Level 3 (PSC, AV Macs only) interrupts */ +#define IRQ_PSC3_0 (24) +#define IRQ_MAC_MACE IRQ_PSC3_0 +#define IRQ_PSC3_1 (25) +#define IRQ_PSC3_2 (26) +#define IRQ_PSC3_3 (27) + +/* Level 4 (SCC) interrupts */ +#define IRQ_SCC (32) +#define IRQ_SCCA (33) +#define IRQ_SCCB (34) +#if 0 /* FIXME: are there multiple interrupt conditions on the SCC ?? */ +/* SCC interrupts */ +#define IRQ_SCCB_TX (32) +#define IRQ_SCCB_STAT (33) +#define IRQ_SCCB_RX (34) +#define IRQ_SCCB_SPCOND (35) +#define IRQ_SCCA_TX (36) +#define IRQ_SCCA_STAT (37) +#define IRQ_SCCA_RX (38) +#define IRQ_SCCA_SPCOND (39) +#endif + +/* Level 4 (PSC, AV Macs only) interrupts */ +#define IRQ_PSC4_0 (32) +#define IRQ_PSC4_1 (33) +#define IRQ_PSC4_2 (34) +#define IRQ_PSC4_3 (35) +#define IRQ_MAC_MACE_DMA IRQ_PSC4_3 + +/* Level 5 (PSC, AV Macs only) interrupts */ +#define IRQ_PSC5_0 (40) +#define IRQ_PSC5_1 (41) +#define IRQ_PSC5_2 (42) +#define IRQ_PSC5_3 (43) + +/* Level 6 (PSC, AV Macs only) interrupts */ +#define IRQ_PSC6_0 (48) +#define IRQ_PSC6_1 (49) +#define IRQ_PSC6_2 (50) +#define IRQ_PSC6_3 (51) + +/* Nubus interrupts (cascaded to VIA2) */ +#define IRQ_NUBUS_9 (56) +#define IRQ_NUBUS_A (57) +#define IRQ_NUBUS_B (58) +#define IRQ_NUBUS_C (59) +#define IRQ_NUBUS_D (60) +#define IRQ_NUBUS_E (61) +#define IRQ_NUBUS_F (62) + +/* Baboon interrupts (cascaded to nubus slot $C) */ +#define IRQ_BABOON_0 (64) +#define IRQ_BABOON_1 (65) +#define IRQ_BABOON_2 (66) +#define IRQ_BABOON_3 (67) + +#define SLOT2IRQ(x) (x + 47) +#define IRQ2SLOT(x) (x - 47) + +#define INT_CLK 24576 /* CLK while int_clk =2.456MHz and divide = 100 */ +#define INT_TICKS 246 /* to make sched_time = 99.902... HZ */ + +#endif /* asm/macints.h */ diff --git a/arch/m68k/include/asm/math-emu.h b/arch/m68k/include/asm/math-emu.h new file mode 100644 index 00000000000..ddfab96403c --- /dev/null +++ b/arch/m68k/include/asm/math-emu.h @@ -0,0 +1,315 @@ +#ifndef _ASM_M68K_SETUP_H +#define _ASM_M68K_SETUP_H + +#include +#include + +/* Status Register bits */ + +/* accrued exception bits */ +#define FPSR_AEXC_INEX 3 +#define FPSR_AEXC_DZ 4 +#define FPSR_AEXC_UNFL 5 +#define FPSR_AEXC_OVFL 6 +#define FPSR_AEXC_IOP 7 + +/* exception status bits */ +#define FPSR_EXC_INEX1 8 +#define FPSR_EXC_INEX2 9 +#define FPSR_EXC_DZ 10 +#define FPSR_EXC_UNFL 11 +#define FPSR_EXC_OVFL 12 +#define FPSR_EXC_OPERR 13 +#define FPSR_EXC_SNAN 14 +#define FPSR_EXC_BSUN 15 + +/* quotient byte, assumes big-endian, of course */ +#define FPSR_QUOTIENT(fpsr) (*((signed char *) &(fpsr) + 1)) + +/* condition code bits */ +#define FPSR_CC_NAN 24 +#define FPSR_CC_INF 25 +#define FPSR_CC_Z 26 +#define FPSR_CC_NEG 27 + + +/* Control register bits */ + +/* rounding mode */ +#define FPCR_ROUND_RN 0 /* round to nearest/even */ +#define FPCR_ROUND_RZ 1 /* round to zero */ +#define FPCR_ROUND_RM 2 /* minus infinity */ +#define FPCR_ROUND_RP 3 /* plus infinity */ + +/* rounding precision */ +#define FPCR_PRECISION_X 0 /* long double */ +#define FPCR_PRECISION_S 1 /* double */ +#define FPCR_PRECISION_D 2 /* float */ + + +/* Flags to select the debugging output */ +#define PDECODE 0 +#define PEXECUTE 1 +#define PCONV 2 +#define PNORM 3 +#define PREGISTER 4 +#define PINSTR 5 +#define PUNIMPL 6 +#define PMOVEM 7 + +#define PMDECODE (1< +#include + +union fp_mant64 { + unsigned long long m64; + unsigned long m32[2]; +}; + +union fp_mant128 { + unsigned long long m64[2]; + unsigned long m32[4]; +}; + +/* internal representation of extended fp numbers */ +struct fp_ext { + unsigned char lowmant; + unsigned char sign; + unsigned short exp; + union fp_mant64 mant; +}; + +/* C representation of FPU registers */ +/* NOTE: if you change this, you have to change the assembler offsets + below and the size in , too */ +struct fp_data { + struct fp_ext fpreg[8]; + unsigned int fpcr; + unsigned int fpsr; + unsigned int fpiar; + unsigned short prec; + unsigned short rnd; + struct fp_ext temp[2]; +}; + +#ifdef FPU_EMU_DEBUG +extern unsigned int fp_debugprint; + +#define dprint(bit, fmt, args...) ({ \ + if (fp_debugprint & (1 << (bit))) \ + printk(fmt, ## args); \ +}) +#else +#define dprint(bit, fmt, args...) +#endif + +#define uprint(str) ({ \ + static int __count = 3; \ + \ + if (__count > 0) { \ + printk("You just hit an unimplemented " \ + "fpu instruction (%s)\n", str); \ + printk("Please report this to ....\n"); \ + __count--; \ + } \ +}) + +#define FPDATA ((struct fp_data *)current->thread.fp) + +#else /* __ASSEMBLY__ */ + +#define FPDATA %a2 + +/* offsets from the base register to the floating point data in the task struct */ +#define FPD_FPREG (TASK_THREAD+THREAD_FPREG+0) +#define FPD_FPCR (TASK_THREAD+THREAD_FPREG+96) +#define FPD_FPSR (TASK_THREAD+THREAD_FPREG+100) +#define FPD_FPIAR (TASK_THREAD+THREAD_FPREG+104) +#define FPD_PREC (TASK_THREAD+THREAD_FPREG+108) +#define FPD_RND (TASK_THREAD+THREAD_FPREG+110) +#define FPD_TEMPFP1 (TASK_THREAD+THREAD_FPREG+112) +#define FPD_TEMPFP2 (TASK_THREAD+THREAD_FPREG+124) +#define FPD_SIZEOF (TASK_THREAD+THREAD_FPREG+136) + +/* offsets on the stack to access saved registers, + * these are only used during instruction decoding + * where we always know how deep we're on the stack. + */ +#define FPS_DO (PT_D0) +#define FPS_D1 (PT_D1) +#define FPS_D2 (PT_D2) +#define FPS_A0 (PT_A0) +#define FPS_A1 (PT_A1) +#define FPS_A2 (PT_A2) +#define FPS_SR (PT_SR) +#define FPS_PC (PT_PC) +#define FPS_EA (PT_PC+6) +#define FPS_PC2 (PT_PC+10) + +.macro fp_get_fp_reg + lea (FPD_FPREG,FPDATA,%d0.w*4),%a0 + lea (%a0,%d0.w*8),%a0 +.endm + +/* Macros used to get/put the current program counter. + * 020/030 use a different stack frame then 040/060, for the + * 040/060 the return pc points already to the next location, + * so this only needs to be modified for jump instructions. + */ +.macro fp_get_pc dest + move.l (FPS_PC+4,%sp),\dest +.endm + +.macro fp_put_pc src,jump=0 + move.l \src,(FPS_PC+4,%sp) +.endm + +.macro fp_get_instr_data f,s,dest,label + getuser \f,%sp@(FPS_PC+4)@(0),\dest,\label,%sp@(FPS_PC+4) + addq.l #\s,%sp@(FPS_PC+4) +.endm + +.macro fp_get_instr_word dest,label,addr + fp_get_instr_data w,2,\dest,\label,\addr +.endm + +.macro fp_get_instr_long dest,label,addr + fp_get_instr_data l,4,\dest,\label,\addr +.endm + +/* These macros are used to read from/write to user space + * on error we jump to the fixup section, load the fault + * address into %a0 and jump to the exit. + * (derived from ) + */ +.macro getuser size,src,dest,label,addr +| printf ,"[\size<%08x]",1,\addr +.Lu1\@: moves\size \src,\dest + + .section .fixup,"ax" + .even +.Lu2\@: move.l \addr,%a0 + jra \label + .previous + + .section __ex_table,"a" + .align 4 + .long .Lu1\@,.Lu2\@ + .previous +.endm + +.macro putuser size,src,dest,label,addr +| printf ,"[\size>%08x]",1,\addr +.Lu1\@: moves\size \src,\dest +.Lu2\@: + + .section .fixup,"ax" + .even +.Lu3\@: move.l \addr,%a0 + jra \label + .previous + + .section __ex_table,"a" + .align 4 + .long .Lu1\@,.Lu3\@ + .long .Lu2\@,.Lu3\@ + .previous +.endm + +/* work around binutils idiocy */ +old_gas=-1 +.irp gas_ident.x .x +old_gas=old_gas+1 +.endr +.if !old_gas +.irp m b,w,l +.macro getuser.\m src,dest,label,addr + getuser .\m,\src,\dest,\label,\addr +.endm +.macro putuser.\m src,dest,label,addr + putuser .\m,\src,\dest,\label,\addr +.endm +.endr +.endif + +.macro movestack nr,arg1,arg2,arg3,arg4,arg5 + .if \nr + movestack (\nr-1),\arg2,\arg3,\arg4,\arg5 + move.l \arg1,-(%sp) + .endif +.endm + +.macro printf bit=-1,string,nr=0,arg1,arg2,arg3,arg4,arg5 +#ifdef FPU_EMU_DEBUG + .data +.Lpdata\@: + .string "\string" + .previous + + movem.l %d0/%d1/%a0/%a1,-(%sp) + .if \bit+1 +#if 0 + moveq #\bit,%d0 + andw #7,%d0 + btst %d0,fp_debugprint+((31-\bit)/8) +#else + btst #\bit,fp_debugprint+((31-\bit)/8) +#endif + jeq .Lpskip\@ + .endif + movestack \nr,\arg1,\arg2,\arg3,\arg4,\arg5 + pea .Lpdata\@ + jsr printk + lea ((\nr+1)*4,%sp),%sp +.Lpskip\@: + movem.l (%sp)+,%d0/%d1/%a0/%a1 +#endif +.endm + +.macro printx bit,fp +#ifdef FPU_EMU_DEBUG + movem.l %d0/%a0,-(%sp) + lea \fp,%a0 +#if 0 + moveq #'+',%d0 + tst.w (%a0) + jeq .Lx1\@ + moveq #'-',%d0 +.Lx1\@: printf \bit," %c",1,%d0 + move.l (4,%a0),%d0 + bclr #31,%d0 + jne .Lx2\@ + printf \bit,"0." + jra .Lx3\@ +.Lx2\@: printf \bit,"1." +.Lx3\@: printf \bit,"%08x%08x",2,%d0,%a0@(8) + move.w (2,%a0),%d0 + ext.l %d0 + printf \bit,"E%04x",1,%d0 +#else + printf \bit," %08x%08x%08x",3,%a0@,%a0@(4),%a0@(8) +#endif + movem.l (%sp)+,%d0/%a0 +#endif +.endm + +.macro debug instr,args +#ifdef FPU_EMU_DEBUG + \instr \args +#endif +.endm + + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_M68K_SETUP_H */ diff --git a/arch/m68k/include/asm/mc146818rtc.h b/arch/m68k/include/asm/mc146818rtc.h new file mode 100644 index 00000000000..fb90dcf7842 --- /dev/null +++ b/arch/m68k/include/asm/mc146818rtc.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "mc146818rtc_no.h" +#else +#include "mc146818rtc_mm.h" +#endif diff --git a/arch/m68k/include/asm/mc146818rtc_mm.h b/arch/m68k/include/asm/mc146818rtc_mm.h new file mode 100644 index 00000000000..9f70a01f73d --- /dev/null +++ b/arch/m68k/include/asm/mc146818rtc_mm.h @@ -0,0 +1,26 @@ +/* + * Machine dependent access functions for RTC registers. + */ +#ifndef _ASM_MC146818RTC_H +#define _ASM_MC146818RTC_H + + +#ifdef CONFIG_ATARI +/* RTC in Atari machines */ + +#include + +#define RTC_PORT(x) (TT_RTC_BAS + 2*(x)) +#define RTC_ALWAYS_BCD 0 + +#define CMOS_READ(addr) ({ \ +atari_outb_p((addr),RTC_PORT(0)); \ +atari_inb_p(RTC_PORT(1)); \ +}) +#define CMOS_WRITE(val, addr) ({ \ +atari_outb_p((addr),RTC_PORT(0)); \ +atari_outb_p((val),RTC_PORT(1)); \ +}) +#endif /* CONFIG_ATARI */ + +#endif /* _ASM_MC146818RTC_H */ diff --git a/arch/m68k/include/asm/mc146818rtc_no.h b/arch/m68k/include/asm/mc146818rtc_no.h new file mode 100644 index 00000000000..907a0481a14 --- /dev/null +++ b/arch/m68k/include/asm/mc146818rtc_no.h @@ -0,0 +1,9 @@ +/* + * Machine dependent access functions for RTC registers. + */ +#ifndef _M68KNOMMU_MC146818RTC_H +#define _M68KNOMMU_MC146818RTC_H + +/* empty include file to satisfy the include in genrtc.c/ide-geometry.c */ + +#endif /* _M68KNOMMU_MC146818RTC_H */ diff --git a/arch/m68k/include/asm/mcfcache.h b/arch/m68k/include/asm/mcfcache.h new file mode 100644 index 00000000000..c042634fada --- /dev/null +++ b/arch/m68k/include/asm/mcfcache.h @@ -0,0 +1,150 @@ +/****************************************************************************/ + +/* + * mcfcache.h -- ColdFire CPU cache support code + * + * (C) Copyright 2004, Greg Ungerer + */ + +/****************************************************************************/ +#ifndef __M68KNOMMU_MCFCACHE_H +#define __M68KNOMMU_MCFCACHE_H +/****************************************************************************/ + + +/* + * The different ColdFire families have different cache arrangments. + * Everything from a small instruction only cache, to configurable + * data and/or instruction cache, to unified instruction/data, to + * harvard style separate instruction and data caches. + */ + +#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || defined(CONFIG_M5272) +/* + * Simple version 2 core cache. These have instruction cache only, + * we just need to invalidate it and enable it. + */ +.macro CACHE_ENABLE + movel #0x01000000,%d0 /* invalidate cache cmd */ + movec %d0,%CACR /* do invalidate cache */ + movel #0x80000100,%d0 /* setup cache mask */ + movec %d0,%CACR /* enable cache */ +.endm +#endif /* CONFIG_M5206 || CONFIG_M5206e || CONFIG_M5272 */ + +#if defined(CONFIG_M523x) || defined(CONFIG_M527x) +/* + * New version 2 cores have a configurable split cache arrangement. + * For now I am just enabling instruction cache - but ultimately I + * think a split instruction/data cache would be better. + */ +.macro CACHE_ENABLE + movel #0x01400000,%d0 + movec %d0,%CACR /* invalidate cache */ + nop + movel #0x0000c000,%d0 /* set SDRAM cached only */ + movec %d0,%ACR0 + movel #0x00000000,%d0 /* no other regions cached */ + movec %d0,%ACR1 + movel #0x80400100,%d0 /* configure cache */ + movec %d0,%CACR /* enable cache */ + nop +.endm +#endif /* CONFIG_M523x || CONFIG_M527x */ + +#if defined(CONFIG_M528x) +.macro CACHE_ENABLE + nop + movel #0x01000000, %d0 + movec %d0, %CACR /* Invalidate cache */ + nop + movel #0x0000c020, %d0 /* Set SDRAM cached only */ + movec %d0, %ACR0 + movel #0x00000000, %d0 /* No other regions cached */ + movec %d0, %ACR1 + movel #0x80000200, %d0 /* Setup cache mask */ + movec %d0, %CACR /* Enable cache */ + nop +.endm +#endif /* CONFIG_M528x */ + +#if defined(CONFIG_M5249) || defined(CONFIG_M5307) +/* + * The version 3 core cache. Oddly enough the version 2 core 5249 + * has the same SDRAM and cache setup as the version 3 cores. + * This is a single unified instruction/data cache. + */ +.macro CACHE_ENABLE + movel #0x01000000,%d0 /* invalidate whole cache */ + movec %d0,%CACR + nop +#if defined(DEBUGGER_COMPATIBLE_CACHE) || defined(CONFIG_SECUREEDGEMP3) + movel #0x0000c000,%d0 /* set SDRAM cached (write-thru) */ +#else + movel #0x0000c020,%d0 /* set SDRAM cached (copyback) */ +#endif + movec %d0,%ACR0 + movel #0x00000000,%d0 /* no other regions cached */ + movec %d0,%ACR1 + movel #0xa0000200,%d0 /* enable cache */ + movec %d0,%CACR + nop +.endm +#endif /* CONFIG_M5249 || CONFIG_M5307 */ + +#if defined(CONFIG_M532x) +.macro CACHE_ENABLE + movel #0x01000000,%d0 /* invalidate cache cmd */ + movec %d0,%CACR /* do invalidate cache */ + nop + movel #0x4001C000,%d0 /* set SDRAM cached (write-thru) */ + movec %d0,%ACR0 + movel #0x00000000,%d0 /* no other regions cached */ + movec %d0,%ACR1 + movel #0x80000200,%d0 /* setup cache mask */ + movec %d0,%CACR /* enable cache */ + nop +.endm +#endif /* CONFIG_M532x */ + +#if defined(CONFIG_M5407) +/* + * Version 4 cores have a true harvard style separate instruction + * and data cache. Invalidate and enable cache, also enable write + * buffers and branch accelerator. + */ +.macro CACHE_ENABLE + movel #0x01040100,%d0 /* invalidate whole cache */ + movec %d0,%CACR + nop + movel #0x000fc000,%d0 /* set SDRAM cached only */ + movec %d0, %ACR0 + movel #0x00000000,%d0 /* no other regions cached */ + movec %d0, %ACR1 + movel #0x000fc000,%d0 /* set SDRAM cached only */ + movec %d0, %ACR2 + movel #0x00000000,%d0 /* no other regions cached */ + movec %d0, %ACR3 + movel #0xb6088400,%d0 /* enable caches */ + movec %d0,%CACR + nop +.endm +#endif /* CONFIG_M5407 */ + +#if defined(CONFIG_M520x) +.macro CACHE_ENABLE + move.l #0x01000000,%d0 /* invalidate whole cache */ + movec %d0,%CACR + nop + move.l #0x0000c000,%d0 /* set SDRAM cached (write-thru) */ + movec %d0,%ACR0 + move.l #0x00000000,%d0 /* no other regions cached */ + movec %d0,%ACR1 + move.l #0x80400000,%d0 /* enable 8K instruction cache */ + movec %d0,%CACR + nop +.endm +#endif /* CONFIG_M520x */ + +/****************************************************************************/ +#endif /* __M68KNOMMU_MCFCACHE_H */ diff --git a/arch/m68k/include/asm/mcfdma.h b/arch/m68k/include/asm/mcfdma.h new file mode 100644 index 00000000000..705c52c79cd --- /dev/null +++ b/arch/m68k/include/asm/mcfdma.h @@ -0,0 +1,144 @@ +/****************************************************************************/ + +/* + * mcfdma.h -- Coldfire internal DMA support defines. + * + * (C) Copyright 1999, Rob Scott (rscott@mtrob.ml.org) + */ + +/****************************************************************************/ +#ifndef mcfdma_h +#define mcfdma_h +/****************************************************************************/ + + +/* + * Get address specific defines for this Coldfire member. + */ +#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) +#define MCFDMA_BASE0 0x200 /* Base address of DMA 0 */ +#define MCFDMA_BASE1 0x240 /* Base address of DMA 1 */ +#elif defined(CONFIG_M5272) +#define MCFDMA_BASE0 0x0e0 /* Base address of DMA 0 */ +#elif defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) +/* These are relative to the IPSBAR, not MBAR */ +#define MCFDMA_BASE0 0x100 /* Base address of DMA 0 */ +#define MCFDMA_BASE1 0x140 /* Base address of DMA 1 */ +#define MCFDMA_BASE2 0x180 /* Base address of DMA 2 */ +#define MCFDMA_BASE3 0x1C0 /* Base address of DMA 3 */ +#elif defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) +#define MCFDMA_BASE0 0x300 /* Base address of DMA 0 */ +#define MCFDMA_BASE1 0x340 /* Base address of DMA 1 */ +#define MCFDMA_BASE2 0x380 /* Base address of DMA 2 */ +#define MCFDMA_BASE3 0x3C0 /* Base address of DMA 3 */ +#endif + + +#if !defined(CONFIG_M5272) + +/* + * Define the DMA register set addresses. + * Note: these are longword registers, use unsigned long as data type + */ +#define MCFDMA_SAR 0x00 /* DMA source address (r/w) */ +#define MCFDMA_DAR 0x01 /* DMA destination adr (r/w) */ +/* these are word registers, use unsigned short data type */ +#define MCFDMA_DCR 0x04 /* DMA control reg (r/w) */ +#define MCFDMA_BCR 0x06 /* DMA byte count reg (r/w) */ +/* these are byte registers, use unsiged char data type */ +#define MCFDMA_DSR 0x10 /* DMA status reg (r/w) */ +#define MCFDMA_DIVR 0x14 /* DMA interrupt vec (r/w) */ + +/* + * Bit definitions for the DMA Control Register (DCR). + */ +#define MCFDMA_DCR_INT 0x8000 /* Enable completion irq */ +#define MCFDMA_DCR_EEXT 0x4000 /* Enable external DMA req */ +#define MCFDMA_DCR_CS 0x2000 /* Enable cycle steal */ +#define MCFDMA_DCR_AA 0x1000 /* Enable auto alignment */ +#define MCFDMA_DCR_BWC_MASK 0x0E00 /* Bandwidth ctl mask */ +#define MCFDMA_DCR_BWC_512 0x0200 /* Bandwidth: 512 Bytes */ +#define MCFDMA_DCR_BWC_1024 0x0400 /* Bandwidth: 1024 Bytes */ +#define MCFDMA_DCR_BWC_2048 0x0600 /* Bandwidth: 2048 Bytes */ +#define MCFDMA_DCR_BWC_4096 0x0800 /* Bandwidth: 4096 Bytes */ +#define MCFDMA_DCR_BWC_8192 0x0a00 /* Bandwidth: 8192 Bytes */ +#define MCFDMA_DCR_BWC_16384 0x0c00 /* Bandwidth: 16384 Bytes */ +#define MCFDMA_DCR_BWC_32768 0x0e00 /* Bandwidth: 32768 Bytes */ +#define MCFDMA_DCR_SAA 0x0100 /* Single Address Access */ +#define MCFDMA_DCR_S_RW 0x0080 /* SAA read/write value */ +#define MCFDMA_DCR_SINC 0x0040 /* Source addr inc enable */ +#define MCFDMA_DCR_SSIZE_MASK 0x0030 /* Src xfer size */ +#define MCFDMA_DCR_SSIZE_LONG 0x0000 /* Src xfer size, 00 = longw */ +#define MCFDMA_DCR_SSIZE_BYTE 0x0010 /* Src xfer size, 01 = byte */ +#define MCFDMA_DCR_SSIZE_WORD 0x0020 /* Src xfer size, 10 = word */ +#define MCFDMA_DCR_SSIZE_LINE 0x0030 /* Src xfer size, 11 = line */ +#define MCFDMA_DCR_DINC 0x0008 /* Dest addr inc enable */ +#define MCFDMA_DCR_DSIZE_MASK 0x0006 /* Dest xfer size */ +#define MCFDMA_DCR_DSIZE_LONG 0x0000 /* Dest xfer size, 00 = long */ +#define MCFDMA_DCR_DSIZE_BYTE 0x0002 /* Dest xfer size, 01 = byte */ +#define MCFDMA_DCR_DSIZE_WORD 0x0004 /* Dest xfer size, 10 = word */ +#define MCFDMA_DCR_DSIZE_LINE 0x0006 /* Dest xfer size, 11 = line */ +#define MCFDMA_DCR_START 0x0001 /* Start transfer */ + +/* + * Bit definitions for the DMA Status Register (DSR). + */ +#define MCFDMA_DSR_CE 0x40 /* Config error */ +#define MCFDMA_DSR_BES 0x20 /* Bus Error on source */ +#define MCFDMA_DSR_BED 0x10 /* Bus Error on dest */ +#define MCFDMA_DSR_REQ 0x04 /* Requests remaining */ +#define MCFDMA_DSR_BSY 0x02 /* Busy */ +#define MCFDMA_DSR_DONE 0x01 /* DMA transfer complete */ + +#else /* This is an MCF5272 */ + +#define MCFDMA_DMR 0x00 /* Mode Register (r/w) */ +#define MCFDMA_DIR 0x03 /* Interrupt trigger register (r/w) */ +#define MCFDMA_DSAR 0x03 /* Source Address register (r/w) */ +#define MCFDMA_DDAR 0x04 /* Destination Address register (r/w) */ +#define MCFDMA_DBCR 0x02 /* Byte Count Register (r/w) */ + +/* Bit definitions for the DMA Mode Register (DMR) */ +#define MCFDMA_DMR_RESET 0x80000000L /* Reset bit */ +#define MCFDMA_DMR_EN 0x40000000L /* DMA enable */ +#define MCFDMA_DMR_RQM 0x000C0000L /* Request Mode Mask */ +#define MCFDMA_DMR_RQM_DUAL 0x000C0000L /* Dual address mode, the only valid mode */ +#define MCFDMA_DMR_DSTM 0x00002000L /* Destination addressing mask */ +#define MCFDMA_DMR_DSTM_SA 0x00000000L /* Destination uses static addressing */ +#define MCFDMA_DMR_DSTM_IA 0x00002000L /* Destination uses incremental addressing */ +#define MCFDMA_DMR_DSTT_UD 0x00000400L /* Destination is user data */ +#define MCFDMA_DMR_DSTT_UC 0x00000800L /* Destination is user code */ +#define MCFDMA_DMR_DSTT_SD 0x00001400L /* Destination is supervisor data */ +#define MCFDMA_DMR_DSTT_SC 0x00001800L /* Destination is supervisor code */ +#define MCFDMA_DMR_DSTS_OFF 0x8 /* offset to the destination size bits */ +#define MCFDMA_DMR_DSTS_LONG 0x00000000L /* Long destination size */ +#define MCFDMA_DMR_DSTS_BYTE 0x00000100L /* Byte destination size */ +#define MCFDMA_DMR_DSTS_WORD 0x00000200L /* Word destination size */ +#define MCFDMA_DMR_DSTS_LINE 0x00000300L /* Line destination size */ +#define MCFDMA_DMR_SRCM 0x00000020L /* Source addressing mask */ +#define MCFDMA_DMR_SRCM_SA 0x00000000L /* Source uses static addressing */ +#define MCFDMA_DMR_SRCM_IA 0x00000020L /* Source uses incremental addressing */ +#define MCFDMA_DMR_SRCT_UD 0x00000004L /* Source is user data */ +#define MCFDMA_DMR_SRCT_UC 0x00000008L /* Source is user code */ +#define MCFDMA_DMR_SRCT_SD 0x00000014L /* Source is supervisor data */ +#define MCFDMA_DMR_SRCT_SC 0x00000018L /* Source is supervisor code */ +#define MCFDMA_DMR_SRCS_OFF 0x0 /* Offset to the source size bits */ +#define MCFDMA_DMR_SRCS_LONG 0x00000000L /* Long source size */ +#define MCFDMA_DMR_SRCS_BYTE 0x00000001L /* Byte source size */ +#define MCFDMA_DMR_SRCS_WORD 0x00000002L /* Word source size */ +#define MCFDMA_DMR_SRCS_LINE 0x00000003L /* Line source size */ + +/* Bit definitions for the DMA interrupt register (DIR) */ +#define MCFDMA_DIR_INVEN 0x1000 /* Invalid Combination interrupt enable */ +#define MCFDMA_DIR_ASCEN 0x0800 /* Address Sequence Complete (Completion) interrupt enable */ +#define MCFDMA_DIR_TEEN 0x0200 /* Transfer Error interrupt enable */ +#define MCFDMA_DIR_TCEN 0x0100 /* Transfer Complete (a bus transfer, that is) interrupt enable */ +#define MCFDMA_DIR_INV 0x0010 /* Invalid Combination */ +#define MCFDMA_DIR_ASC 0x0008 /* Address Sequence Complete (DMA Completion) */ +#define MCFDMA_DIR_TE 0x0002 /* Transfer Error */ +#define MCFDMA_DIR_TC 0x0001 /* Transfer Complete */ + +#endif /* !defined(CONFIG_M5272) */ + +/****************************************************************************/ +#endif /* mcfdma_h */ diff --git a/arch/m68k/include/asm/mcfmbus.h b/arch/m68k/include/asm/mcfmbus.h new file mode 100644 index 00000000000..319899c47a2 --- /dev/null +++ b/arch/m68k/include/asm/mcfmbus.h @@ -0,0 +1,77 @@ +/****************************************************************************/ + +/* + * mcfmbus.h -- Coldfire MBUS support defines. + * + * (C) Copyright 1999, Martin Floeer (mfloeer@axcent.de) + */ + +/****************************************************************************/ + + +#ifndef mcfmbus_h +#define mcfmbus_h + + +#define MCFMBUS_BASE 0x280 +#define MCFMBUS_IRQ_VECTOR 0x19 +#define MCFMBUS_IRQ 0x1 +#define MCFMBUS_CLK 0x3f +#define MCFMBUS_IRQ_LEVEL 0x07 /*IRQ Level 1*/ +#define MCFMBUS_ADDRESS 0x01 + + +/* +* Define the 5307 MBUS register set addresses +*/ + +#define MCFMBUS_MADR 0x00 +#define MCFMBUS_MFDR 0x04 +#define MCFMBUS_MBCR 0x08 +#define MCFMBUS_MBSR 0x0C +#define MCFMBUS_MBDR 0x10 + + +#define MCFMBUS_MADR_ADDR(a) (((a)&0x7F)<<0x01) /*Slave Address*/ + +#define MCFMBUS_MFDR_MBC(a) ((a)&0x3F) /*M-Bus Clock*/ + +/* +* Define bit flags in Control Register +*/ + +#define MCFMBUS_MBCR_MEN (0x80) /* M-Bus Enable */ +#define MCFMBUS_MBCR_MIEN (0x40) /* M-Bus Interrupt Enable */ +#define MCFMBUS_MBCR_MSTA (0x20) /* Master/Slave Mode Select Bit */ +#define MCFMBUS_MBCR_MTX (0x10) /* Transmit/Rcv Mode Select Bit */ +#define MCFMBUS_MBCR_TXAK (0x08) /* Transmit Acknowledge Enable */ +#define MCFMBUS_MBCR_RSTA (0x04) /* Repeat Start */ + +/* +* Define bit flags in Status Register +*/ + +#define MCFMBUS_MBSR_MCF (0x80) /* Data Transfer Complete */ +#define MCFMBUS_MBSR_MAAS (0x40) /* Addressed as a Slave */ +#define MCFMBUS_MBSR_MBB (0x20) /* Bus Busy */ +#define MCFMBUS_MBSR_MAL (0x10) /* Arbitration Lost */ +#define MCFMBUS_MBSR_SRW (0x04) /* Slave Transmit */ +#define MCFMBUS_MBSR_MIF (0x02) /* M-Bus Interrupt */ +#define MCFMBUS_MBSR_RXAK (0x01) /* No Acknowledge Received */ + +/* +* Define bit flags in DATA I/O Register +*/ + +#define MCFMBUS_MBDR_READ (0x01) /* 1=read 0=write MBUS */ + +#define MBUSIOCSCLOCK 1 +#define MBUSIOCGCLOCK 2 +#define MBUSIOCSADDR 3 +#define MBUSIOCGADDR 4 +#define MBUSIOCSSLADDR 5 +#define MBUSIOCGSLADDR 6 +#define MBUSIOCSSUBADDR 7 +#define MBUSIOCGSUBADDR 8 + +#endif diff --git a/arch/m68k/include/asm/mcfne.h b/arch/m68k/include/asm/mcfne.h new file mode 100644 index 00000000000..431f63aadd0 --- /dev/null +++ b/arch/m68k/include/asm/mcfne.h @@ -0,0 +1,325 @@ +/****************************************************************************/ + +/* + * mcfne.h -- NE2000 in ColdFire eval boards. + * + * (C) Copyright 1999-2000, Greg Ungerer (gerg@snapgear.com) + * (C) Copyright 2000, Lineo (www.lineo.com) + * (C) Copyright 2001, SnapGear (www.snapgear.com) + * + * 19990409 David W. Miller Converted from m5206ne.h for 5307 eval board + * + * Hacked support for m5206e Cadre III evaluation board + * Fred Stevens (fred.stevens@pemstar.com) 13 April 1999 + */ + +/****************************************************************************/ +#ifndef mcfne_h +#define mcfne_h +/****************************************************************************/ + + +/* + * Support for NE2000 clones devices in ColdFire based boards. + * Not all boards address these parts the same way, some use a + * direct addressing method, others use a side-band address space + * to access odd address registers, some require byte swapping + * others do not. + */ +#define BSWAP(w) (((w) << 8) | ((w) >> 8)) +#define RSWAP(w) (w) + + +/* + * Define the basic hardware resources of NE2000 boards. + */ + +#if defined(CONFIG_ARN5206) +#define NE2000_ADDR 0x40000300 +#define NE2000_ODDOFFSET 0x00010000 +#define NE2000_IRQ_VECTOR 0xf0 +#define NE2000_IRQ_PRIORITY 2 +#define NE2000_IRQ_LEVEL 4 +#define NE2000_BYTE volatile unsigned short +#endif + +#if defined(CONFIG_M5206eC3) +#define NE2000_ADDR 0x40000300 +#define NE2000_ODDOFFSET 0x00010000 +#define NE2000_IRQ_VECTOR 0x1c +#define NE2000_IRQ_PRIORITY 2 +#define NE2000_IRQ_LEVEL 4 +#define NE2000_BYTE volatile unsigned short +#endif + +#if defined(CONFIG_M5206e) && defined(CONFIG_NETtel) +#define NE2000_ADDR 0x30000300 +#define NE2000_IRQ_VECTOR 25 +#define NE2000_IRQ_PRIORITY 1 +#define NE2000_IRQ_LEVEL 3 +#define NE2000_BYTE volatile unsigned char +#endif + +#if defined(CONFIG_M5307C3) +#define NE2000_ADDR 0x40000300 +#define NE2000_ODDOFFSET 0x00010000 +#define NE2000_IRQ_VECTOR 0x1b +#define NE2000_BYTE volatile unsigned short +#endif + +#if defined(CONFIG_M5272) && defined(CONFIG_NETtel) +#define NE2000_ADDR 0x30600300 +#define NE2000_ODDOFFSET 0x00008000 +#define NE2000_IRQ_VECTOR 67 +#undef BSWAP +#define BSWAP(w) (w) +#define NE2000_BYTE volatile unsigned short +#undef RSWAP +#define RSWAP(w) (((w) << 8) | ((w) >> 8)) +#endif + +#if defined(CONFIG_M5307) && defined(CONFIG_NETtel) +#define NE2000_ADDR0 0x30600300 +#define NE2000_ADDR1 0x30800300 +#define NE2000_ODDOFFSET 0x00008000 +#define NE2000_IRQ_VECTOR0 27 +#define NE2000_IRQ_VECTOR1 29 +#undef BSWAP +#define BSWAP(w) (w) +#define NE2000_BYTE volatile unsigned short +#undef RSWAP +#define RSWAP(w) (((w) << 8) | ((w) >> 8)) +#endif + +#if defined(CONFIG_M5307) && defined(CONFIG_SECUREEDGEMP3) +#define NE2000_ADDR 0x30600300 +#define NE2000_ODDOFFSET 0x00008000 +#define NE2000_IRQ_VECTOR 27 +#undef BSWAP +#define BSWAP(w) (w) +#define NE2000_BYTE volatile unsigned short +#undef RSWAP +#define RSWAP(w) (((w) << 8) | ((w) >> 8)) +#endif + +#if defined(CONFIG_ARN5307) +#define NE2000_ADDR 0xfe600300 +#define NE2000_ODDOFFSET 0x00010000 +#define NE2000_IRQ_VECTOR 0x1b +#define NE2000_IRQ_PRIORITY 2 +#define NE2000_IRQ_LEVEL 3 +#define NE2000_BYTE volatile unsigned short +#endif + +#if defined(CONFIG_M5407C3) +#define NE2000_ADDR 0x40000300 +#define NE2000_ODDOFFSET 0x00010000 +#define NE2000_IRQ_VECTOR 0x1b +#define NE2000_BYTE volatile unsigned short +#endif + +/****************************************************************************/ + +/* + * Side-band address space for odd address requires re-mapping + * many of the standard ISA access functions. + */ +#ifdef NE2000_ODDOFFSET + +#undef outb +#undef outb_p +#undef inb +#undef inb_p +#undef outsb +#undef outsw +#undef insb +#undef insw + +#define outb ne2000_outb +#define inb ne2000_inb +#define outb_p ne2000_outb +#define inb_p ne2000_inb +#define outsb ne2000_outsb +#define outsw ne2000_outsw +#define insb ne2000_insb +#define insw ne2000_insw + + +#ifndef COLDFIRE_NE2000_FUNCS + +void ne2000_outb(unsigned int val, unsigned int addr); +int ne2000_inb(unsigned int addr); +void ne2000_insb(unsigned int addr, void *vbuf, int unsigned long len); +void ne2000_insw(unsigned int addr, void *vbuf, unsigned long len); +void ne2000_outsb(unsigned int addr, void *vbuf, unsigned long len); +void ne2000_outsw(unsigned int addr, void *vbuf, unsigned long len); + +#else + +/* + * This macro converts a conventional register address into the + * real memory pointer of the mapped NE2000 device. + * On most NE2000 implementations on ColdFire boards the chip is + * mapped in kinda funny, due to its ISA heritage. + */ +#define NE2000_PTR(addr) ((addr&0x1)?(NE2000_ODDOFFSET+addr-1):(addr)) +#define NE2000_DATA_PTR(addr) (addr) + + +void ne2000_outb(unsigned int val, unsigned int addr) +{ + NE2000_BYTE *rp; + + rp = (NE2000_BYTE *) NE2000_PTR(addr); + *rp = RSWAP(val); +} + +int ne2000_inb(unsigned int addr) +{ + NE2000_BYTE *rp, val; + + rp = (NE2000_BYTE *) NE2000_PTR(addr); + val = *rp; + return((int) ((NE2000_BYTE) RSWAP(val))); +} + +void ne2000_insb(unsigned int addr, void *vbuf, int unsigned long len) +{ + NE2000_BYTE *rp, val; + unsigned char *buf; + + buf = (unsigned char *) vbuf; + rp = (NE2000_BYTE *) NE2000_DATA_PTR(addr); + for (; (len > 0); len--) { + val = *rp; + *buf++ = RSWAP(val); + } +} + +void ne2000_insw(unsigned int addr, void *vbuf, unsigned long len) +{ + volatile unsigned short *rp; + unsigned short w, *buf; + + buf = (unsigned short *) vbuf; + rp = (volatile unsigned short *) NE2000_DATA_PTR(addr); + for (; (len > 0); len--) { + w = *rp; + *buf++ = BSWAP(w); + } +} + +void ne2000_outsb(unsigned int addr, const void *vbuf, unsigned long len) +{ + NE2000_BYTE *rp, val; + unsigned char *buf; + + buf = (unsigned char *) vbuf; + rp = (NE2000_BYTE *) NE2000_DATA_PTR(addr); + for (; (len > 0); len--) { + val = *buf++; + *rp = RSWAP(val); + } +} + +void ne2000_outsw(unsigned int addr, const void *vbuf, unsigned long len) +{ + volatile unsigned short *rp; + unsigned short w, *buf; + + buf = (unsigned short *) vbuf; + rp = (volatile unsigned short *) NE2000_DATA_PTR(addr); + for (; (len > 0); len--) { + w = *buf++; + *rp = BSWAP(w); + } +} + +#endif /* COLDFIRE_NE2000_FUNCS */ +#endif /* NE2000_OFFOFFSET */ + +/****************************************************************************/ + +#ifdef COLDFIRE_NE2000_FUNCS + +/* + * Lastly the interrupt set up code... + * Minor differences between the different board types. + */ + +#if defined(CONFIG_ARN5206) +void ne2000_irqsetup(int irq) +{ + volatile unsigned char *icrp; + + icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_ICR4); + *icrp = MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI2; + mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT4); +} +#endif + +#if defined(CONFIG_M5206eC3) +void ne2000_irqsetup(int irq) +{ + volatile unsigned char *icrp; + + icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_ICR4); + *icrp = MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI2 | MCFSIM_ICR_AUTOVEC; + mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT4); +} +#endif + +#if defined(CONFIG_M5206e) && defined(CONFIG_NETtel) +void ne2000_irqsetup(int irq) +{ + mcf_autovector(irq); +} +#endif + +#if defined(CONFIG_M5272) && defined(CONFIG_NETtel) +void ne2000_irqsetup(int irq) +{ + volatile unsigned long *icrp; + volatile unsigned long *pitr; + + /* The NE2000 device uses external IRQ3 */ + icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1); + *icrp = (*icrp & 0x77077777) | 0x00d00000; + + pitr = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PITR); + *pitr = *pitr | 0x20000000; +} + +void ne2000_irqack(int irq) +{ + volatile unsigned long *icrp; + + /* The NE2000 device uses external IRQ3 */ + icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1); + *icrp = (*icrp & 0x77777777) | 0x00800000; +} +#endif + +#if defined(CONFIG_M5307) || defined(CONFIG_M5407) +#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3) + +void ne2000_irqsetup(int irq) +{ + mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT3); + mcf_autovector(irq); +} + +#else + +void ne2000_irqsetup(int irq) +{ + mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT3); +} + +#endif /* ! CONFIG_NETtel || CONFIG_SECUREEDGEMP3 */ +#endif /* CONFIG_M5307 || CONFIG_M5407 */ + +#endif /* COLDFIRE_NE2000_FUNCS */ + +/****************************************************************************/ +#endif /* mcfne_h */ diff --git a/arch/m68k/include/asm/mcfpci.h b/arch/m68k/include/asm/mcfpci.h new file mode 100644 index 00000000000..f1507dd06ec --- /dev/null +++ b/arch/m68k/include/asm/mcfpci.h @@ -0,0 +1,119 @@ +/****************************************************************************/ + +/* + * mcfpci.h -- PCI bridge on ColdFire eval boards. + * + * (C) Copyright 2000, Greg Ungerer (gerg@snapgear.com) + * (C) Copyright 2000, Lineo Inc. (www.lineo.com) + */ + +/****************************************************************************/ +#ifndef mcfpci_h +#define mcfpci_h +/****************************************************************************/ + + +#ifdef CONFIG_PCI + +/* + * Address regions in the PCI address space are not mapped into the + * normal memory space of the ColdFire. They must be accessed via + * handler routines. This is easy for I/O space (inb/outb/etc) but + * needs some code changes to support ordinary memory. Interrupts + * also need to be vectored through the PCI handler first, then it + * will call the actual driver sub-handlers. + */ + +/* + * Un-define all the standard I/O access routines. + */ +#undef inb +#undef inw +#undef inl +#undef inb_p +#undef inw_p +#undef insb +#undef insw +#undef insl +#undef outb +#undef outw +#undef outl +#undef outb_p +#undef outw_p +#undef outsb +#undef outsw +#undef outsl + +#undef request_irq +#undef free_irq + +#undef bus_to_virt +#undef virt_to_bus + + +/* + * Re-direct all I/O memory accesses functions to PCI specific ones. + */ +#define inb pci_inb +#define inw pci_inw +#define inl pci_inl +#define inb_p pci_inb +#define inw_p pci_inw +#define insb pci_insb +#define insw pci_insw +#define insl pci_insl + +#define outb pci_outb +#define outw pci_outw +#define outl pci_outl +#define outb_p pci_outb +#define outw_p pci_outw +#define outsb pci_outsb +#define outsw pci_outsw +#define outsl pci_outsl + +#define request_irq pci_request_irq +#define free_irq pci_free_irq + +#define virt_to_bus pci_virt_to_bus +#define bus_to_virt pci_bus_to_virt + +#define CONFIG_COMEMPCI 1 + + +/* + * Prototypes of the real PCI functions (defined in bios32.c). + */ +unsigned char pci_inb(unsigned int addr); +unsigned short pci_inw(unsigned int addr); +unsigned int pci_inl(unsigned int addr); +void pci_insb(void *addr, void *buf, int len); +void pci_insw(void *addr, void *buf, int len); +void pci_insl(void *addr, void *buf, int len); + +void pci_outb(unsigned char val, unsigned int addr); +void pci_outw(unsigned short val, unsigned int addr); +void pci_outl(unsigned int val, unsigned int addr); +void pci_outsb(void *addr, void *buf, int len); +void pci_outsw(void *addr, void *buf, int len); +void pci_outsl(void *addr, void *buf, int len); + +int pci_request_irq(unsigned int irq, + void (*handler)(int, void *, struct pt_regs *), + unsigned long flags, + const char *device, + void *dev_id); +void pci_free_irq(unsigned int irq, void *dev_id); + +void *pci_bmalloc(int size); +void pci_bmfree(void *bmp, int len); +void pci_copytoshmem(unsigned long bmp, void *src, int size); +void pci_copyfromshmem(void *dst, unsigned long bmp, int size); +unsigned long pci_virt_to_bus(volatile void *address); +void *pci_bus_to_virt(unsigned long address); +void pci_bmcpyto(void *dst, void *src, int len); +void pci_bmcpyfrom(void *dst, void *src, int len); + +#endif /* CONFIG_PCI */ +/****************************************************************************/ +#endif /* mcfpci_h */ diff --git a/arch/m68k/include/asm/mcfpit.h b/arch/m68k/include/asm/mcfpit.h new file mode 100644 index 00000000000..f570cf64fd2 --- /dev/null +++ b/arch/m68k/include/asm/mcfpit.h @@ -0,0 +1,64 @@ +/****************************************************************************/ + +/* + * mcfpit.h -- ColdFire internal PIT timer support defines. + * + * (C) Copyright 2003, Greg Ungerer (gerg@snapgear.com) + */ + +/****************************************************************************/ +#ifndef mcfpit_h +#define mcfpit_h +/****************************************************************************/ + + +/* + * Get address specific defines for the 5270/5271, 5280/5282, and 5208. + */ +#if defined(CONFIG_M520x) +#define MCFPIT_BASE1 0x00080000 /* Base address of TIMER1 */ +#define MCFPIT_BASE2 0x00084000 /* Base address of TIMER2 */ +#else +#define MCFPIT_BASE1 0x00150000 /* Base address of TIMER1 */ +#define MCFPIT_BASE2 0x00160000 /* Base address of TIMER2 */ +#define MCFPIT_BASE3 0x00170000 /* Base address of TIMER3 */ +#define MCFPIT_BASE4 0x00180000 /* Base address of TIMER4 */ +#endif + +/* + * Define the PIT timer register set addresses. + */ +#define MCFPIT_PCSR 0x0 /* PIT control register */ +#define MCFPIT_PMR 0x2 /* PIT modulus register */ +#define MCFPIT_PCNTR 0x4 /* PIT count register */ + +/* + * Bit definitions for the PIT Control and Status register. + */ +#define MCFPIT_PCSR_CLK1 0x0000 /* System clock divisor */ +#define MCFPIT_PCSR_CLK2 0x0100 /* System clock divisor */ +#define MCFPIT_PCSR_CLK4 0x0200 /* System clock divisor */ +#define MCFPIT_PCSR_CLK8 0x0300 /* System clock divisor */ +#define MCFPIT_PCSR_CLK16 0x0400 /* System clock divisor */ +#define MCFPIT_PCSR_CLK32 0x0500 /* System clock divisor */ +#define MCFPIT_PCSR_CLK64 0x0600 /* System clock divisor */ +#define MCFPIT_PCSR_CLK128 0x0700 /* System clock divisor */ +#define MCFPIT_PCSR_CLK256 0x0800 /* System clock divisor */ +#define MCFPIT_PCSR_CLK512 0x0900 /* System clock divisor */ +#define MCFPIT_PCSR_CLK1024 0x0a00 /* System clock divisor */ +#define MCFPIT_PCSR_CLK2048 0x0b00 /* System clock divisor */ +#define MCFPIT_PCSR_CLK4096 0x0c00 /* System clock divisor */ +#define MCFPIT_PCSR_CLK8192 0x0d00 /* System clock divisor */ +#define MCFPIT_PCSR_CLK16384 0x0e00 /* System clock divisor */ +#define MCFPIT_PCSR_CLK32768 0x0f00 /* System clock divisor */ +#define MCFPIT_PCSR_DOZE 0x0040 /* Clock run in doze mode */ +#define MCFPIT_PCSR_HALTED 0x0020 /* Clock run in halt mode */ +#define MCFPIT_PCSR_OVW 0x0010 /* Overwrite PIT counter now */ +#define MCFPIT_PCSR_PIE 0x0008 /* Enable PIT interrupt */ +#define MCFPIT_PCSR_PIF 0x0004 /* PIT interrupt flag */ +#define MCFPIT_PCSR_RLD 0x0002 /* Reload counter */ +#define MCFPIT_PCSR_EN 0x0001 /* Enable PIT */ +#define MCFPIT_PCSR_DISABLE 0x0000 /* Disable PIT */ + +/****************************************************************************/ +#endif /* mcfpit_h */ diff --git a/arch/m68k/include/asm/mcfsim.h b/arch/m68k/include/asm/mcfsim.h new file mode 100644 index 00000000000..da3f2ceff3a --- /dev/null +++ b/arch/m68k/include/asm/mcfsim.h @@ -0,0 +1,126 @@ +/****************************************************************************/ + +/* + * mcfsim.h -- ColdFire System Integration Module support. + * + * (C) Copyright 1999-2003, Greg Ungerer (gerg@snapgear.com) + * (C) Copyright 2000, Lineo Inc. (www.lineo.com) + */ + +/****************************************************************************/ +#ifndef mcfsim_h +#define mcfsim_h +/****************************************************************************/ + + +/* + * Include 5204, 5206/e, 5235, 5249, 5270/5271, 5272, 5280/5282, + * 5307 or 5407 specific addresses. + */ +#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) +#include +#elif defined(CONFIG_M520x) +#include +#elif defined(CONFIG_M523x) +#include +#elif defined(CONFIG_M5249) +#include +#elif defined(CONFIG_M527x) +#include +#elif defined(CONFIG_M5272) +#include +#elif defined(CONFIG_M528x) +#include +#elif defined(CONFIG_M5307) +#include +#elif defined(CONFIG_M532x) +#include +#elif defined(CONFIG_M5407) +#include +#endif + + +/* + * Define the base address of the SIM within the MBAR address space. + */ +#define MCFSIM_BASE 0x0 /* Base address of SIM */ + + +/* + * Bit definitions for the ICR family of registers. + */ +#define MCFSIM_ICR_AUTOVEC 0x80 /* Auto-vectored intr */ +#define MCFSIM_ICR_LEVEL0 0x00 /* Level 0 intr */ +#define MCFSIM_ICR_LEVEL1 0x04 /* Level 1 intr */ +#define MCFSIM_ICR_LEVEL2 0x08 /* Level 2 intr */ +#define MCFSIM_ICR_LEVEL3 0x0c /* Level 3 intr */ +#define MCFSIM_ICR_LEVEL4 0x10 /* Level 4 intr */ +#define MCFSIM_ICR_LEVEL5 0x14 /* Level 5 intr */ +#define MCFSIM_ICR_LEVEL6 0x18 /* Level 6 intr */ +#define MCFSIM_ICR_LEVEL7 0x1c /* Level 7 intr */ + +#define MCFSIM_ICR_PRI0 0x00 /* Priority 0 intr */ +#define MCFSIM_ICR_PRI1 0x01 /* Priority 1 intr */ +#define MCFSIM_ICR_PRI2 0x02 /* Priority 2 intr */ +#define MCFSIM_ICR_PRI3 0x03 /* Priority 3 intr */ + +/* + * Bit definitions for the Interrupt Mask register (IMR). + */ +#define MCFSIM_IMR_EINT1 0x0002 /* External intr # 1 */ +#define MCFSIM_IMR_EINT2 0x0004 /* External intr # 2 */ +#define MCFSIM_IMR_EINT3 0x0008 /* External intr # 3 */ +#define MCFSIM_IMR_EINT4 0x0010 /* External intr # 4 */ +#define MCFSIM_IMR_EINT5 0x0020 /* External intr # 5 */ +#define MCFSIM_IMR_EINT6 0x0040 /* External intr # 6 */ +#define MCFSIM_IMR_EINT7 0x0080 /* External intr # 7 */ + +#define MCFSIM_IMR_SWD 0x0100 /* Software Watchdog intr */ +#define MCFSIM_IMR_TIMER1 0x0200 /* TIMER 1 intr */ +#define MCFSIM_IMR_TIMER2 0x0400 /* TIMER 2 intr */ +#define MCFSIM_IMR_MBUS 0x0800 /* MBUS intr */ +#define MCFSIM_IMR_UART1 0x1000 /* UART 1 intr */ +#define MCFSIM_IMR_UART2 0x2000 /* UART 2 intr */ + +#if defined(CONFIG_M5206e) +#define MCFSIM_IMR_DMA1 0x4000 /* DMA 1 intr */ +#define MCFSIM_IMR_DMA2 0x8000 /* DMA 2 intr */ +#elif defined(CONFIG_M5249) || defined(CONFIG_M5307) +#define MCFSIM_IMR_DMA0 0x4000 /* DMA 0 intr */ +#define MCFSIM_IMR_DMA1 0x8000 /* DMA 1 intr */ +#define MCFSIM_IMR_DMA2 0x10000 /* DMA 2 intr */ +#define MCFSIM_IMR_DMA3 0x20000 /* DMA 3 intr */ +#endif + +/* + * Mask for all of the SIM devices. Some parts have more or less + * SIM devices. This is a catchall for the sandard set. + */ +#ifndef MCFSIM_IMR_MASKALL +#define MCFSIM_IMR_MASKALL 0x3ffe /* All intr sources */ +#endif + + +/* + * PIT interrupt settings, if not found in mXXXXsim.h file. + */ +#ifndef ICR_INTRCONF +#define ICR_INTRCONF 0x2b /* PIT1 level 5, priority 3 */ +#endif +#ifndef MCFPIT_IMR +#define MCFPIT_IMR MCFINTC_IMRH +#endif +#ifndef MCFPIT_IMR_IBIT +#define MCFPIT_IMR_IBIT (1 << (MCFINT_PIT1 - 32)) +#endif + + +#ifndef __ASSEMBLY__ +/* + * Definition for the interrupt auto-vectoring support. + */ +extern void mcf_autovector(unsigned int vec); +#endif /* __ASSEMBLY__ */ + +/****************************************************************************/ +#endif /* mcfsim_h */ diff --git a/arch/m68k/include/asm/mcfsmc.h b/arch/m68k/include/asm/mcfsmc.h new file mode 100644 index 00000000000..2d7a4dbd968 --- /dev/null +++ b/arch/m68k/include/asm/mcfsmc.h @@ -0,0 +1,187 @@ +/****************************************************************************/ + +/* + * mcfsmc.h -- SMC ethernet support for ColdFire environments. + * + * (C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com) + * (C) Copyright 2000, Lineo Inc. (www.lineo.com) + */ + +/****************************************************************************/ +#ifndef mcfsmc_h +#define mcfsmc_h +/****************************************************************************/ + +/* + * None of the current ColdFire targets that use the SMC91x111 + * allow 8 bit accesses. So this code is 16bit access only. + */ + + +#undef outb +#undef inb +#undef outw +#undef outwd +#undef inw +#undef outl +#undef inl + +#undef outsb +#undef outsw +#undef outsl +#undef insb +#undef insw +#undef insl + +/* + * Re-defines for ColdFire environment... The SMC part is + * mapped into memory space, so remap the PC-style in/out + * routines to handle that. + */ +#define outb smc_outb +#define inb smc_inb +#define outw smc_outw +#define outwd smc_outwd +#define inw smc_inw +#define outl smc_outl +#define inl smc_inl + +#define outsb smc_outsb +#define outsw smc_outsw +#define outsl smc_outsl +#define insb smc_insb +#define insw smc_insw +#define insl smc_insl + + +static inline int smc_inb(unsigned int addr) +{ + register unsigned short w; + w = *((volatile unsigned short *) (addr & ~0x1)); + return(((addr & 0x1) ? w : (w >> 8)) & 0xff); +} + +static inline void smc_outw(unsigned int val, unsigned int addr) +{ + *((volatile unsigned short *) addr) = (val << 8) | (val >> 8); +} + +static inline int smc_inw(unsigned int addr) +{ + register unsigned short w; + w = *((volatile unsigned short *) addr); + return(((w << 8) | (w >> 8)) & 0xffff); +} + +static inline void smc_outl(unsigned long val, unsigned int addr) +{ + *((volatile unsigned long *) addr) = + ((val << 8) & 0xff000000) | ((val >> 8) & 0x00ff0000) | + ((val << 8) & 0x0000ff00) | ((val >> 8) & 0x000000ff); +} + +static inline void smc_outwd(unsigned int val, unsigned int addr) +{ + *((volatile unsigned short *) addr) = val; +} + + +/* + * The rep* functions are used to feed the data port with + * raw data. So we do not byte swap them when copying. + */ + +static inline void smc_insb(unsigned int addr, void *vbuf, int unsigned long len) +{ + volatile unsigned short *rp; + unsigned short *buf, *ebuf; + + buf = (unsigned short *) vbuf; + rp = (volatile unsigned short *) addr; + + /* Copy as words for as long as possible */ + for (ebuf = buf + (len >> 1); (buf < ebuf); ) + *buf++ = *rp; + + /* Lastly, handle left over byte */ + if (len & 0x1) + *((unsigned char *) buf) = (*rp >> 8) & 0xff; +} + +static inline void smc_insw(unsigned int addr, void *vbuf, unsigned long len) +{ + volatile unsigned short *rp; + unsigned short *buf, *ebuf; + + buf = (unsigned short *) vbuf; + rp = (volatile unsigned short *) addr; + for (ebuf = buf + len; (buf < ebuf); ) + *buf++ = *rp; +} + +static inline void smc_insl(unsigned int addr, void *vbuf, unsigned long len) +{ + volatile unsigned long *rp; + unsigned long *buf, *ebuf; + + buf = (unsigned long *) vbuf; + rp = (volatile unsigned long *) addr; + for (ebuf = buf + len; (buf < ebuf); ) + *buf++ = *rp; +} + +static inline void smc_outsw(unsigned int addr, const void *vbuf, unsigned long len) +{ + volatile unsigned short *rp; + unsigned short *buf, *ebuf; + + buf = (unsigned short *) vbuf; + rp = (volatile unsigned short *) addr; + for (ebuf = buf + len; (buf < ebuf); ) + *rp = *buf++; +} + +static inline void smc_outsl(unsigned int addr, void *vbuf, unsigned long len) +{ + volatile unsigned long *rp; + unsigned long *buf, *ebuf; + + buf = (unsigned long *) vbuf; + rp = (volatile unsigned long *) addr; + for (ebuf = buf + len; (buf < ebuf); ) + *rp = *buf++; +} + + +#ifdef CONFIG_NETtel +/* + * Re-map the address space of at least one of the SMC ethernet + * parts. Both parts power up decoding the same address, so we + * need to move one of them first, before doing enything else. + * + * We also increase the number of wait states for this part by one. + */ + +void smc_remap(unsigned int ioaddr) +{ + static int once = 0; + extern unsigned short ppdata; + if (once++ == 0) { + *((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADDR)) = 0x00ec; + ppdata |= 0x0080; + *((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADAT)) = ppdata; + outw(0x0001, ioaddr + BANK_SELECT); + outw(0x0001, ioaddr + BANK_SELECT); + outw(0x0067, ioaddr + BASE); + + ppdata &= ~0x0080; + *((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADAT)) = ppdata; + } + + *((volatile unsigned short *)(MCF_MBAR+MCFSIM_CSCR3)) = 0x1180; +} + +#endif + +/****************************************************************************/ +#endif /* mcfsmc_h */ diff --git a/arch/m68k/include/asm/mcftimer.h b/arch/m68k/include/asm/mcftimer.h new file mode 100644 index 00000000000..0f90f6d2227 --- /dev/null +++ b/arch/m68k/include/asm/mcftimer.h @@ -0,0 +1,80 @@ +/****************************************************************************/ + +/* + * mcftimer.h -- ColdFire internal TIMER support defines. + * + * (C) Copyright 1999-2006, Greg Ungerer + * (C) Copyright 2000, Lineo Inc. (www.lineo.com) + */ + +/****************************************************************************/ +#ifndef mcftimer_h +#define mcftimer_h +/****************************************************************************/ + + +/* + * Get address specific defines for this ColdFire member. + */ +#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) +#define MCFTIMER_BASE1 0x100 /* Base address of TIMER1 */ +#define MCFTIMER_BASE2 0x120 /* Base address of TIMER2 */ +#elif defined(CONFIG_M5272) +#define MCFTIMER_BASE1 0x200 /* Base address of TIMER1 */ +#define MCFTIMER_BASE2 0x220 /* Base address of TIMER2 */ +#define MCFTIMER_BASE3 0x240 /* Base address of TIMER4 */ +#define MCFTIMER_BASE4 0x260 /* Base address of TIMER3 */ +#elif defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) +#define MCFTIMER_BASE1 0x140 /* Base address of TIMER1 */ +#define MCFTIMER_BASE2 0x180 /* Base address of TIMER2 */ +#elif defined(CONFIG_M532x) +#define MCFTIMER_BASE1 0xfc070000 /* Base address of TIMER1 */ +#define MCFTIMER_BASE2 0xfc074000 /* Base address of TIMER2 */ +#define MCFTIMER_BASE3 0xfc078000 /* Base address of TIMER3 */ +#define MCFTIMER_BASE4 0xfc07c000 /* Base address of TIMER4 */ +#endif + + +/* + * Define the TIMER register set addresses. + */ +#define MCFTIMER_TMR 0x00 /* Timer Mode reg (r/w) */ +#define MCFTIMER_TRR 0x04 /* Timer Reference (r/w) */ +#define MCFTIMER_TCR 0x08 /* Timer Capture reg (r/w) */ +#define MCFTIMER_TCN 0x0C /* Timer Counter reg (r/w) */ +#if defined(CONFIG_M532x) +#define MCFTIMER_TER 0x03 /* Timer Event reg (r/w) */ +#else +#define MCFTIMER_TER 0x11 /* Timer Event reg (r/w) */ +#endif + +/* + * Bit definitions for the Timer Mode Register (TMR). + * Register bit flags are common accross ColdFires. + */ +#define MCFTIMER_TMR_PREMASK 0xff00 /* Prescalar mask */ +#define MCFTIMER_TMR_DISCE 0x0000 /* Disable capture */ +#define MCFTIMER_TMR_ANYCE 0x00c0 /* Capture any edge */ +#define MCFTIMER_TMR_FALLCE 0x0080 /* Capture fallingedge */ +#define MCFTIMER_TMR_RISECE 0x0040 /* Capture rising edge */ +#define MCFTIMER_TMR_ENOM 0x0020 /* Enable output toggle */ +#define MCFTIMER_TMR_DISOM 0x0000 /* Do single output pulse */ +#define MCFTIMER_TMR_ENORI 0x0010 /* Enable ref interrupt */ +#define MCFTIMER_TMR_DISORI 0x0000 /* Disable ref interrupt */ +#define MCFTIMER_TMR_RESTART 0x0008 /* Restart counter */ +#define MCFTIMER_TMR_FREERUN 0x0000 /* Free running counter */ +#define MCFTIMER_TMR_CLKTIN 0x0006 /* Input clock is TIN */ +#define MCFTIMER_TMR_CLK16 0x0004 /* Input clock is /16 */ +#define MCFTIMER_TMR_CLK1 0x0002 /* Input clock is /1 */ +#define MCFTIMER_TMR_CLKSTOP 0x0000 /* Stop counter */ +#define MCFTIMER_TMR_ENABLE 0x0001 /* Enable timer */ +#define MCFTIMER_TMR_DISABLE 0x0000 /* Disable timer */ + +/* + * Bit definitions for the Timer Event Registers (TER). + */ +#define MCFTIMER_TER_CAP 0x01 /* Capture event */ +#define MCFTIMER_TER_REF 0x02 /* Refernece event */ + +/****************************************************************************/ +#endif /* mcftimer_h */ diff --git a/arch/m68k/include/asm/mcfuart.h b/arch/m68k/include/asm/mcfuart.h new file mode 100644 index 00000000000..ef229387361 --- /dev/null +++ b/arch/m68k/include/asm/mcfuart.h @@ -0,0 +1,216 @@ +/****************************************************************************/ + +/* + * mcfuart.h -- ColdFire internal UART support defines. + * + * (C) Copyright 1999-2003, Greg Ungerer (gerg@snapgear.com) + * (C) Copyright 2000, Lineo Inc. (www.lineo.com) + */ + +/****************************************************************************/ +#ifndef mcfuart_h +#define mcfuart_h +/****************************************************************************/ + +/* + * Define the base address of the UARTS within the MBAR address + * space. + */ +#if defined(CONFIG_M5272) +#define MCFUART_BASE1 0x100 /* Base address of UART1 */ +#define MCFUART_BASE2 0x140 /* Base address of UART2 */ +#elif defined(CONFIG_M5206) || defined(CONFIG_M5206e) +#if defined(CONFIG_NETtel) +#define MCFUART_BASE1 0x180 /* Base address of UART1 */ +#define MCFUART_BASE2 0x140 /* Base address of UART2 */ +#else +#define MCFUART_BASE1 0x140 /* Base address of UART1 */ +#define MCFUART_BASE2 0x180 /* Base address of UART2 */ +#endif +#elif defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) +#define MCFUART_BASE1 0x200 /* Base address of UART1 */ +#define MCFUART_BASE2 0x240 /* Base address of UART2 */ +#define MCFUART_BASE3 0x280 /* Base address of UART3 */ +#elif defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) +#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3) +#define MCFUART_BASE1 0x200 /* Base address of UART1 */ +#define MCFUART_BASE2 0x1c0 /* Base address of UART2 */ +#else +#define MCFUART_BASE1 0x1c0 /* Base address of UART1 */ +#define MCFUART_BASE2 0x200 /* Base address of UART2 */ +#endif +#elif defined(CONFIG_M520x) +#define MCFUART_BASE1 0x60000 /* Base address of UART1 */ +#define MCFUART_BASE2 0x64000 /* Base address of UART2 */ +#define MCFUART_BASE3 0x68000 /* Base address of UART2 */ +#elif defined(CONFIG_M532x) +#define MCFUART_BASE1 0xfc060000 /* Base address of UART1 */ +#define MCFUART_BASE2 0xfc064000 /* Base address of UART2 */ +#define MCFUART_BASE3 0xfc068000 /* Base address of UART3 */ +#endif + + +#include +#include + +struct mcf_platform_uart { + unsigned long mapbase; /* Physical address base */ + void __iomem *membase; /* Virtual address if mapped */ + unsigned int irq; /* Interrupt vector */ + unsigned int uartclk; /* UART clock rate */ +}; + +/* + * Define the ColdFire UART register set addresses. + */ +#define MCFUART_UMR 0x00 /* Mode register (r/w) */ +#define MCFUART_USR 0x04 /* Status register (r) */ +#define MCFUART_UCSR 0x04 /* Clock Select (w) */ +#define MCFUART_UCR 0x08 /* Command register (w) */ +#define MCFUART_URB 0x0c /* Receiver Buffer (r) */ +#define MCFUART_UTB 0x0c /* Transmit Buffer (w) */ +#define MCFUART_UIPCR 0x10 /* Input Port Change (r) */ +#define MCFUART_UACR 0x10 /* Auxiliary Control (w) */ +#define MCFUART_UISR 0x14 /* Interrupt Status (r) */ +#define MCFUART_UIMR 0x14 /* Interrupt Mask (w) */ +#define MCFUART_UBG1 0x18 /* Baud Rate MSB (r/w) */ +#define MCFUART_UBG2 0x1c /* Baud Rate LSB (r/w) */ +#ifdef CONFIG_M5272 +#define MCFUART_UTF 0x28 /* Transmitter FIFO (r/w) */ +#define MCFUART_URF 0x2c /* Receiver FIFO (r/w) */ +#define MCFUART_UFPD 0x30 /* Frac Prec. Divider (r/w) */ +#else +#define MCFUART_UIVR 0x30 /* Interrupt Vector (r/w) */ +#endif +#define MCFUART_UIPR 0x34 /* Input Port (r) */ +#define MCFUART_UOP1 0x38 /* Output Port Bit Set (w) */ +#define MCFUART_UOP0 0x3c /* Output Port Bit Reset (w) */ + + +/* + * Define bit flags in Mode Register 1 (MR1). + */ +#define MCFUART_MR1_RXRTS 0x80 /* Auto RTS flow control */ +#define MCFUART_MR1_RXIRQFULL 0x40 /* RX IRQ type FULL */ +#define MCFUART_MR1_RXIRQRDY 0x00 /* RX IRQ type RDY */ +#define MCFUART_MR1_RXERRBLOCK 0x20 /* RX block error mode */ +#define MCFUART_MR1_RXERRCHAR 0x00 /* RX char error mode */ + +#define MCFUART_MR1_PARITYNONE 0x10 /* No parity */ +#define MCFUART_MR1_PARITYEVEN 0x00 /* Even parity */ +#define MCFUART_MR1_PARITYODD 0x04 /* Odd parity */ +#define MCFUART_MR1_PARITYSPACE 0x08 /* Space parity */ +#define MCFUART_MR1_PARITYMARK 0x0c /* Mark parity */ + +#define MCFUART_MR1_CS5 0x00 /* 5 bits per char */ +#define MCFUART_MR1_CS6 0x01 /* 6 bits per char */ +#define MCFUART_MR1_CS7 0x02 /* 7 bits per char */ +#define MCFUART_MR1_CS8 0x03 /* 8 bits per char */ + +/* + * Define bit flags in Mode Register 2 (MR2). + */ +#define MCFUART_MR2_LOOPBACK 0x80 /* Loopback mode */ +#define MCFUART_MR2_REMOTELOOP 0xc0 /* Remote loopback mode */ +#define MCFUART_MR2_AUTOECHO 0x40 /* Automatic echo */ +#define MCFUART_MR2_TXRTS 0x20 /* Assert RTS on TX */ +#define MCFUART_MR2_TXCTS 0x10 /* Auto CTS flow control */ + +#define MCFUART_MR2_STOP1 0x07 /* 1 stop bit */ +#define MCFUART_MR2_STOP15 0x08 /* 1.5 stop bits */ +#define MCFUART_MR2_STOP2 0x0f /* 2 stop bits */ + +/* + * Define bit flags in Status Register (USR). + */ +#define MCFUART_USR_RXBREAK 0x80 /* Received BREAK */ +#define MCFUART_USR_RXFRAMING 0x40 /* Received framing error */ +#define MCFUART_USR_RXPARITY 0x20 /* Received parity error */ +#define MCFUART_USR_RXOVERRUN 0x10 /* Received overrun error */ +#define MCFUART_USR_TXEMPTY 0x08 /* Transmitter empty */ +#define MCFUART_USR_TXREADY 0x04 /* Transmitter ready */ +#define MCFUART_USR_RXFULL 0x02 /* Receiver full */ +#define MCFUART_USR_RXREADY 0x01 /* Receiver ready */ + +#define MCFUART_USR_RXERR (MCFUART_USR_RXBREAK | MCFUART_USR_RXFRAMING | \ + MCFUART_USR_RXPARITY | MCFUART_USR_RXOVERRUN) + +/* + * Define bit flags in Clock Select Register (UCSR). + */ +#define MCFUART_UCSR_RXCLKTIMER 0xd0 /* RX clock is timer */ +#define MCFUART_UCSR_RXCLKEXT16 0xe0 /* RX clock is external x16 */ +#define MCFUART_UCSR_RXCLKEXT1 0xf0 /* RX clock is external x1 */ + +#define MCFUART_UCSR_TXCLKTIMER 0x0d /* TX clock is timer */ +#define MCFUART_UCSR_TXCLKEXT16 0x0e /* TX clock is external x16 */ +#define MCFUART_UCSR_TXCLKEXT1 0x0f /* TX clock is external x1 */ + +/* + * Define bit flags in Command Register (UCR). + */ +#define MCFUART_UCR_CMDNULL 0x00 /* No command */ +#define MCFUART_UCR_CMDRESETMRPTR 0x10 /* Reset MR pointer */ +#define MCFUART_UCR_CMDRESETRX 0x20 /* Reset receiver */ +#define MCFUART_UCR_CMDRESETTX 0x30 /* Reset transmitter */ +#define MCFUART_UCR_CMDRESETERR 0x40 /* Reset error status */ +#define MCFUART_UCR_CMDRESETBREAK 0x50 /* Reset BREAK change */ +#define MCFUART_UCR_CMDBREAKSTART 0x60 /* Start BREAK */ +#define MCFUART_UCR_CMDBREAKSTOP 0x70 /* Stop BREAK */ + +#define MCFUART_UCR_TXNULL 0x00 /* No TX command */ +#define MCFUART_UCR_TXENABLE 0x04 /* Enable TX */ +#define MCFUART_UCR_TXDISABLE 0x08 /* Disable TX */ +#define MCFUART_UCR_RXNULL 0x00 /* No RX command */ +#define MCFUART_UCR_RXENABLE 0x01 /* Enable RX */ +#define MCFUART_UCR_RXDISABLE 0x02 /* Disable RX */ + +/* + * Define bit flags in Input Port Change Register (UIPCR). + */ +#define MCFUART_UIPCR_CTSCOS 0x10 /* CTS change of state */ +#define MCFUART_UIPCR_CTS 0x01 /* CTS value */ + +/* + * Define bit flags in Input Port Register (UIP). + */ +#define MCFUART_UIPR_CTS 0x01 /* CTS value */ + +/* + * Define bit flags in Output Port Registers (UOP). + * Clear bit by writing to UOP0, set by writing to UOP1. + */ +#define MCFUART_UOP_RTS 0x01 /* RTS set or clear */ + +/* + * Define bit flags in the Auxiliary Control Register (UACR). + */ +#define MCFUART_UACR_IEC 0x01 /* Input enable control */ + +/* + * Define bit flags in Interrupt Status Register (UISR). + * These same bits are used for the Interrupt Mask Register (UIMR). + */ +#define MCFUART_UIR_COS 0x80 /* Change of state (CTS) */ +#define MCFUART_UIR_DELTABREAK 0x04 /* Break start or stop */ +#define MCFUART_UIR_RXREADY 0x02 /* Receiver ready */ +#define MCFUART_UIR_TXREADY 0x01 /* Transmitter ready */ + +#ifdef CONFIG_M5272 +/* + * Define bit flags in the Transmitter FIFO Register (UTF). + */ +#define MCFUART_UTF_TXB 0x1f /* Transmitter data level */ +#define MCFUART_UTF_FULL 0x20 /* Transmitter fifo full */ +#define MCFUART_UTF_TXS 0xc0 /* Transmitter status */ + +/* + * Define bit flags in the Receiver FIFO Register (URF). + */ +#define MCFUART_URF_RXB 0x1f /* Receiver data level */ +#define MCFUART_URF_FULL 0x20 /* Receiver fifo full */ +#define MCFUART_URF_RXS 0xc0 /* Receiver status */ +#endif + +/****************************************************************************/ +#endif /* mcfuart_h */ diff --git a/arch/m68k/include/asm/mcfwdebug.h b/arch/m68k/include/asm/mcfwdebug.h new file mode 100644 index 00000000000..27f70e45d70 --- /dev/null +++ b/arch/m68k/include/asm/mcfwdebug.h @@ -0,0 +1,118 @@ +/****************************************************************************/ + +/* + * mcfdebug.h -- ColdFire Debug Module support. + * + * (C) Copyright 2001, Lineo Inc. (www.lineo.com) + */ + +/****************************************************************************/ +#ifndef mcfdebug_h +#define mcfdebug_h +/****************************************************************************/ + +/* Define the debug module registers */ +#define MCFDEBUG_CSR 0x0 /* Configuration status */ +#define MCFDEBUG_BAAR 0x5 /* BDM address attribute */ +#define MCFDEBUG_AATR 0x6 /* Address attribute trigger */ +#define MCFDEBUG_TDR 0x7 /* Trigger definition */ +#define MCFDEBUG_PBR 0x8 /* PC breakpoint */ +#define MCFDEBUG_PBMR 0x9 /* PC breakpoint mask */ +#define MCFDEBUG_ABHR 0xc /* High address breakpoint */ +#define MCFDEBUG_ABLR 0xd /* Low address breakpoint */ +#define MCFDEBUG_DBR 0xe /* Data breakpoint */ +#define MCFDEBUG_DBMR 0xf /* Data breakpoint mask */ + +/* Define some handy constants for the trigger definition register */ +#define MCFDEBUG_TDR_TRC_DISP 0x00000000 /* display on DDATA only */ +#define MCFDEBUG_TDR_TRC_HALT 0x40000000 /* Processor halt on BP */ +#define MCFDEBUG_TDR_TRC_INTR 0x80000000 /* Debug intr on BP */ +#define MCFDEBUG_TDR_LXT1 0x00004000 /* TDR level 1 */ +#define MCFDEBUG_TDR_LXT2 0x00008000 /* TDR level 2 */ +#define MCFDEBUG_TDR_EBL1 0x00002000 /* Enable breakpoint level 1 */ +#define MCFDEBUG_TDR_EBL2 0x20000000 /* Enable breakpoint level 2 */ +#define MCFDEBUG_TDR_EDLW1 0x00001000 /* Enable data BP longword */ +#define MCFDEBUG_TDR_EDLW2 0x10000000 +#define MCFDEBUG_TDR_EDWL1 0x00000800 /* Enable data BP lower word */ +#define MCFDEBUG_TDR_EDWL2 0x08000000 +#define MCFDEBUG_TDR_EDWU1 0x00000400 /* Enable data BP upper word */ +#define MCFDEBUG_TDR_EDWU2 0x04000000 +#define MCFDEBUG_TDR_EDLL1 0x00000200 /* Enable data BP low low byte */ +#define MCFDEBUG_TDR_EDLL2 0x02000000 +#define MCFDEBUG_TDR_EDLM1 0x00000100 /* Enable data BP low mid byte */ +#define MCFDEBUG_TDR_EDLM2 0x01000000 +#define MCFDEBUG_TDR_EDUM1 0x00000080 /* Enable data BP up mid byte */ +#define MCFDEBUG_TDR_EDUM2 0x00800000 +#define MCFDEBUG_TDR_EDUU1 0x00000040 /* Enable data BP up up byte */ +#define MCFDEBUG_TDR_EDUU2 0x00400000 +#define MCFDEBUG_TDR_DI1 0x00000020 /* Data BP invert */ +#define MCFDEBUG_TDR_DI2 0x00200000 +#define MCFDEBUG_TDR_EAI1 0x00000010 /* Enable address BP inverted */ +#define MCFDEBUG_TDR_EAI2 0x00100000 +#define MCFDEBUG_TDR_EAR1 0x00000008 /* Enable address BP range */ +#define MCFDEBUG_TDR_EAR2 0x00080000 +#define MCFDEBUG_TDR_EAL1 0x00000004 /* Enable address BP low */ +#define MCFDEBUG_TDR_EAL2 0x00040000 +#define MCFDEBUG_TDR_EPC1 0x00000002 /* Enable PC BP */ +#define MCFDEBUG_TDR_EPC2 0x00020000 +#define MCFDEBUG_TDR_PCI1 0x00000001 /* PC BP invert */ +#define MCFDEBUG_TDR_PCI2 0x00010000 + +/* Constants for the address attribute trigger register */ +#define MCFDEBUG_AAR_RESET 0x00000005 +/* Fields not yet implemented */ + +/* And some definitions for the writable sections of the CSR */ +#define MCFDEBUG_CSR_RESET 0x00100000 +#define MCFDEBUG_CSR_PSTCLK 0x00020000 /* PSTCLK disable */ +#define MCFDEBUG_CSR_IPW 0x00010000 /* Inhibit processor writes */ +#define MCFDEBUG_CSR_MAP 0x00008000 /* Processor refs in emul mode */ +#define MCFDEBUG_CSR_TRC 0x00004000 /* Emul mode on trace exception */ +#define MCFDEBUG_CSR_EMU 0x00002000 /* Force emulation mode */ +#define MCFDEBUG_CSR_DDC_READ 0x00000800 /* Debug data control */ +#define MCFDEBUG_CSR_DDC_WRITE 0x00001000 +#define MCFDEBUG_CSR_UHE 0x00000400 /* User mode halt enable */ +#define MCFDEBUG_CSR_BTB0 0x00000000 /* Branch target 0 bytes */ +#define MCFDEBUG_CSR_BTB2 0x00000100 /* Branch target 2 bytes */ +#define MCFDEBUG_CSR_BTB3 0x00000200 /* Branch target 3 bytes */ +#define MCFDEBUG_CSR_BTB4 0x00000300 /* Branch target 4 bytes */ +#define MCFDEBUG_CSR_NPL 0x00000040 /* Non-pipelined mode */ +#define MCFDEBUG_CSR_SSM 0x00000010 /* Single step mode */ + +/* Constants for the BDM address attribute register */ +#define MCFDEBUG_BAAR_RESET 0x00000005 +/* Fields not yet implemented */ + + +/* This routine wrappers up the wdebug asm instruction so that the register + * and value can be relatively easily specified. The biggest hassle here is + * that the debug module instructions (2 longs) must be long word aligned and + * some pointer fiddling is performed to ensure this. + */ +static inline void wdebug(int reg, unsigned long data) { + unsigned short dbg_spc[6]; + unsigned short *dbg; + + // Force alignment to long word boundary + dbg = (unsigned short *)((((unsigned long)dbg_spc) + 3) & 0xfffffffc); + + // Build up the debug instruction + dbg[0] = 0x2c80 | (reg & 0xf); + dbg[1] = (data >> 16) & 0xffff; + dbg[2] = data & 0xffff; + dbg[3] = 0; + + // Perform the wdebug instruction +#if 0 + // This strain is for gas which doesn't have the wdebug instructions defined + asm( "move.l %0, %%a0\n\t" + ".word 0xfbd0\n\t" + ".word 0x0003\n\t" + :: "g" (dbg) : "a0"); +#else + // And this is for when it does + asm( "wdebug (%0)" :: "a" (dbg)); +#endif +} + +#endif diff --git a/arch/m68k/include/asm/md.h b/arch/m68k/include/asm/md.h new file mode 100644 index 00000000000..d2f78f226f3 --- /dev/null +++ b/arch/m68k/include/asm/md.h @@ -0,0 +1,13 @@ +/* + * md.h: High speed xor_block operation for RAID4/5 + * + */ + +#ifndef __ASM_MD_H +#define __ASM_MD_H + +/* #define HAVE_ARCH_XORBLOCK */ + +#define MD_XORBLOCK_ALIGNMENT sizeof(long) + +#endif /* __ASM_MD_H */ diff --git a/arch/m68k/include/asm/mman.h b/arch/m68k/include/asm/mman.h new file mode 100644 index 00000000000..1626d37f489 --- /dev/null +++ b/arch/m68k/include/asm/mman.h @@ -0,0 +1,17 @@ +#ifndef __M68K_MMAN_H__ +#define __M68K_MMAN_H__ + +#include + +#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ +#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ +#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ +#define MAP_LOCKED 0x2000 /* pages are locked */ +#define MAP_NORESERVE 0x4000 /* don't check for reservations */ +#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ +#define MAP_NONBLOCK 0x10000 /* do not block on IO */ + +#define MCL_CURRENT 1 /* lock all current mappings */ +#define MCL_FUTURE 2 /* lock all future mappings */ + +#endif /* __M68K_MMAN_H__ */ diff --git a/arch/m68k/include/asm/mmu.h b/arch/m68k/include/asm/mmu.h new file mode 100644 index 00000000000..a81d3946675 --- /dev/null +++ b/arch/m68k/include/asm/mmu.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "mmu_no.h" +#else +#include "mmu_mm.h" +#endif diff --git a/arch/m68k/include/asm/mmu_context.h b/arch/m68k/include/asm/mmu_context.h new file mode 100644 index 00000000000..b440928fc6c --- /dev/null +++ b/arch/m68k/include/asm/mmu_context.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "mmu_context_no.h" +#else +#include "mmu_context_mm.h" +#endif diff --git a/arch/m68k/include/asm/mmu_context_mm.h b/arch/m68k/include/asm/mmu_context_mm.h new file mode 100644 index 00000000000..894dacbcee1 --- /dev/null +++ b/arch/m68k/include/asm/mmu_context_mm.h @@ -0,0 +1,154 @@ +#ifndef __M68K_MMU_CONTEXT_H +#define __M68K_MMU_CONTEXT_H + +#include + +static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) +{ +} + +#ifndef CONFIG_SUN3 + +#include +#include +#include + +static inline int init_new_context(struct task_struct *tsk, + struct mm_struct *mm) +{ + mm->context = virt_to_phys(mm->pgd); + return 0; +} + +#define destroy_context(mm) do { } while(0) + +static inline void switch_mm_0230(struct mm_struct *mm) +{ + unsigned long crp[2] = { + 0x80000000 | _PAGE_TABLE, mm->context + }; + unsigned long tmp; + + asm volatile (".chip 68030"); + + /* flush MC68030/MC68020 caches (they are virtually addressed) */ + asm volatile ( + "movec %%cacr,%0;" + "orw %1,%0; " + "movec %0,%%cacr" + : "=d" (tmp) : "di" (FLUSH_I_AND_D)); + + /* Switch the root pointer. For a 030-only kernel, + * avoid flushing the whole ATC, we only need to + * flush the user entries. The 68851 does this by + * itself. Avoid a runtime check here. + */ + asm volatile ( +#ifdef CPU_M68030_ONLY + "pmovefd %0,%%crp; " + "pflush #0,#4" +#else + "pmove %0,%%crp" +#endif + : : "m" (crp[0])); + + asm volatile (".chip 68k"); +} + +static inline void switch_mm_0460(struct mm_struct *mm) +{ + asm volatile (".chip 68040"); + + /* flush address translation cache (user entries) */ + asm volatile ("pflushan"); + + /* switch the root pointer */ + asm volatile ("movec %0,%%urp" : : "r" (mm->context)); + + if (CPU_IS_060) { + unsigned long tmp; + + /* clear user entries in the branch cache */ + asm volatile ( + "movec %%cacr,%0; " + "orl %1,%0; " + "movec %0,%%cacr" + : "=d" (tmp): "di" (0x00200000)); + } + + asm volatile (".chip 68k"); +} + +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) +{ + if (prev != next) { + if (CPU_IS_020_OR_030) + switch_mm_0230(next); + else + switch_mm_0460(next); + } +} + +#define deactivate_mm(tsk,mm) do { } while (0) + +static inline void activate_mm(struct mm_struct *prev_mm, + struct mm_struct *next_mm) +{ + next_mm->context = virt_to_phys(next_mm->pgd); + + if (CPU_IS_020_OR_030) + switch_mm_0230(next_mm); + else + switch_mm_0460(next_mm); +} + +#else /* CONFIG_SUN3 */ +#include +#include + +extern unsigned long get_free_context(struct mm_struct *mm); +extern void clear_context(unsigned long context); + +/* set the context for a new task to unmapped */ +static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm) +{ + mm->context = SUN3_INVALID_CONTEXT; + return 0; +} + +/* find the context given to this process, and if it hasn't already + got one, go get one for it. */ +static inline void get_mmu_context(struct mm_struct *mm) +{ + if(mm->context == SUN3_INVALID_CONTEXT) + mm->context = get_free_context(mm); +} + +/* flush context if allocated... */ +static inline void destroy_context(struct mm_struct *mm) +{ + if(mm->context != SUN3_INVALID_CONTEXT) + clear_context(mm->context); +} + +static inline void activate_context(struct mm_struct *mm) +{ + get_mmu_context(mm); + sun3_put_context(mm->context); +} + +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) +{ + activate_context(tsk->mm); +} + +#define deactivate_mm(tsk,mm) do { } while (0) + +static inline void activate_mm(struct mm_struct *prev_mm, + struct mm_struct *next_mm) +{ + activate_context(next_mm); +} + +#endif +#endif diff --git a/arch/m68k/include/asm/mmu_context_no.h b/arch/m68k/include/asm/mmu_context_no.h new file mode 100644 index 00000000000..9ccee4278c9 --- /dev/null +++ b/arch/m68k/include/asm/mmu_context_no.h @@ -0,0 +1,33 @@ +#ifndef __M68KNOMMU_MMU_CONTEXT_H +#define __M68KNOMMU_MMU_CONTEXT_H + +#include +#include +#include +#include + +static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) +{ +} + +static inline int +init_new_context(struct task_struct *tsk, struct mm_struct *mm) +{ + // mm->context = virt_to_phys(mm->pgd); + return(0); +} + +#define destroy_context(mm) do { } while(0) + +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) +{ +} + +#define deactivate_mm(tsk,mm) do { } while (0) + +static inline void activate_mm(struct mm_struct *prev_mm, + struct mm_struct *next_mm) +{ +} + +#endif diff --git a/arch/m68k/include/asm/mmu_mm.h b/arch/m68k/include/asm/mmu_mm.h new file mode 100644 index 00000000000..ccd36d26615 --- /dev/null +++ b/arch/m68k/include/asm/mmu_mm.h @@ -0,0 +1,7 @@ +#ifndef __MMU_H +#define __MMU_H + +/* Default "unsigned long" context */ +typedef unsigned long mm_context_t; + +#endif diff --git a/arch/m68k/include/asm/mmu_no.h b/arch/m68k/include/asm/mmu_no.h new file mode 100644 index 00000000000..e2da1e6f09f --- /dev/null +++ b/arch/m68k/include/asm/mmu_no.h @@ -0,0 +1,10 @@ +#ifndef __M68KNOMMU_MMU_H +#define __M68KNOMMU_MMU_H + +/* Copyright (C) 2002, David McCullough */ + +typedef struct { + unsigned long end_brk; +} mm_context_t; + +#endif /* __M68KNOMMU_MMU_H */ diff --git a/arch/m68k/include/asm/mmzone.h b/arch/m68k/include/asm/mmzone.h new file mode 100644 index 00000000000..e1f1ec7b700 --- /dev/null +++ b/arch/m68k/include/asm/mmzone.h @@ -0,0 +1,9 @@ +#ifndef _ASM_M68K_MMZONE_H_ +#define _ASM_M68K_MMZONE_H_ + +extern pg_data_t pg_data_map[]; + +#define NODE_DATA(nid) (&pg_data_map[nid]) +#define NODE_MEM_MAP(nid) (NODE_DATA(nid)->node_mem_map) + +#endif /* _ASM_M68K_MMZONE_H_ */ diff --git a/arch/m68k/include/asm/module.h b/arch/m68k/include/asm/module.h new file mode 100644 index 00000000000..79b59d137dd --- /dev/null +++ b/arch/m68k/include/asm/module.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "module_no.h" +#else +#include "module_mm.h" +#endif diff --git a/arch/m68k/include/asm/module_mm.h b/arch/m68k/include/asm/module_mm.h new file mode 100644 index 00000000000..382d20a6fc1 --- /dev/null +++ b/arch/m68k/include/asm/module_mm.h @@ -0,0 +1,39 @@ +#ifndef _ASM_M68K_MODULE_H +#define _ASM_M68K_MODULE_H + +struct mod_arch_specific { + struct m68k_fixup_info *fixup_start, *fixup_end; +}; + +#define MODULE_ARCH_INIT { \ + .fixup_start = __start_fixup, \ + .fixup_end = __stop_fixup, \ +} + +#define Elf_Shdr Elf32_Shdr +#define Elf_Sym Elf32_Sym +#define Elf_Ehdr Elf32_Ehdr + + +enum m68k_fixup_type { + m68k_fixup_memoffset, + m68k_fixup_vnode_shift, +}; + +struct m68k_fixup_info { + enum m68k_fixup_type type; + void *addr; +}; + +#define m68k_fixup(type, addr) \ + " .section \".m68k_fixup\",\"aw\"\n" \ + " .long " #type "," #addr "\n" \ + " .previous\n" + +extern struct m68k_fixup_info __start_fixup[], __stop_fixup[]; + +struct module; +extern void module_fixup(struct module *mod, struct m68k_fixup_info *start, + struct m68k_fixup_info *end); + +#endif /* _ASM_M68K_MODULE_H */ diff --git a/arch/m68k/include/asm/module_no.h b/arch/m68k/include/asm/module_no.h new file mode 100644 index 00000000000..2e45ab50b23 --- /dev/null +++ b/arch/m68k/include/asm/module_no.h @@ -0,0 +1,11 @@ +#ifndef ASM_M68KNOMMU_MODULE_H +#define ASM_M68KNOMMU_MODULE_H + +struct mod_arch_specific { +}; + +#define Elf_Shdr Elf32_Shdr +#define Elf_Sym Elf32_Sym +#define Elf_Ehdr Elf32_Ehdr + +#endif /* ASM_M68KNOMMU_MODULE_H */ diff --git a/arch/m68k/include/asm/motorola_pgalloc.h b/arch/m68k/include/asm/motorola_pgalloc.h new file mode 100644 index 00000000000..d08bf6261df --- /dev/null +++ b/arch/m68k/include/asm/motorola_pgalloc.h @@ -0,0 +1,109 @@ +#ifndef _MOTOROLA_PGALLOC_H +#define _MOTOROLA_PGALLOC_H + +#include +#include + +extern pmd_t *get_pointer_table(void); +extern int free_pointer_table(pmd_t *); + +static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) +{ + pte_t *pte; + + pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); + if (pte) { + __flush_page_to_ram(pte); + flush_tlb_kernel_page(pte); + nocache_page(pte); + } + + return pte; +} + +static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) +{ + cache_page(pte); + free_page((unsigned long) pte); +} + +static inline pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) +{ + struct page *page = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0); + pte_t *pte; + + if(!page) + return NULL; + + pte = kmap(page); + if (pte) { + __flush_page_to_ram(pte); + flush_tlb_kernel_page(pte); + nocache_page(pte); + } + kunmap(pte); + pgtable_page_ctor(page); + return page; +} + +static inline void pte_free(struct mm_struct *mm, pgtable_t page) +{ + pgtable_page_dtor(page); + cache_page(kmap(page)); + kunmap(page); + __free_page(page); +} + +static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t page) +{ + pgtable_page_dtor(page); + cache_page(kmap(page)); + kunmap(page); + __free_page(page); +} + + +static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) +{ + return get_pointer_table(); +} + +static inline int pmd_free(struct mm_struct *mm, pmd_t *pmd) +{ + return free_pointer_table(pmd); +} + +static inline int __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) +{ + return free_pointer_table(pmd); +} + + +static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) +{ + pmd_free(mm, (pmd_t *)pgd); +} + +static inline pgd_t *pgd_alloc(struct mm_struct *mm) +{ + return (pgd_t *)get_pointer_table(); +} + + +static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte) +{ + pmd_set(pmd, pte); +} + +static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t page) +{ + pmd_set(pmd, page_address(page)); +} +#define pmd_pgtable(pmd) pmd_page(pmd) + +static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd) +{ + pgd_set(pgd, pmd); +} + +#endif /* _MOTOROLA_PGALLOC_H */ diff --git a/arch/m68k/include/asm/motorola_pgtable.h b/arch/m68k/include/asm/motorola_pgtable.h new file mode 100644 index 00000000000..8e9a8a754dd --- /dev/null +++ b/arch/m68k/include/asm/motorola_pgtable.h @@ -0,0 +1,291 @@ +#ifndef _MOTOROLA_PGTABLE_H +#define _MOTOROLA_PGTABLE_H + + +/* + * Definitions for MMU descriptors + */ +#define _PAGE_PRESENT 0x001 +#define _PAGE_SHORT 0x002 +#define _PAGE_RONLY 0x004 +#define _PAGE_ACCESSED 0x008 +#define _PAGE_DIRTY 0x010 +#define _PAGE_SUPER 0x080 /* 68040 supervisor only */ +#define _PAGE_GLOBAL040 0x400 /* 68040 global bit, used for kva descs */ +#define _PAGE_NOCACHE030 0x040 /* 68030 no-cache mode */ +#define _PAGE_NOCACHE 0x060 /* 68040 cache mode, non-serialized */ +#define _PAGE_NOCACHE_S 0x040 /* 68040 no-cache mode, serialized */ +#define _PAGE_CACHE040 0x020 /* 68040 cache mode, cachable, copyback */ +#define _PAGE_CACHE040W 0x000 /* 68040 cache mode, cachable, write-through */ + +#define _DESCTYPE_MASK 0x003 + +#define _CACHEMASK040 (~0x060) +#define _TABLE_MASK (0xfffffe00) + +#define _PAGE_TABLE (_PAGE_SHORT) +#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_NOCACHE) + +#define _PAGE_PROTNONE 0x004 +#define _PAGE_FILE 0x008 /* pagecache or swap? */ + +#ifndef __ASSEMBLY__ + +/* This is the cache mode to be used for pages containing page descriptors for + * processors >= '040. It is in pte_mknocache(), and the variable is defined + * and initialized in head.S */ +extern int m68k_pgtable_cachemode; + +/* This is the cache mode for normal pages, for supervisor access on + * processors >= '040. It is used in pte_mkcache(), and the variable is + * defined and initialized in head.S */ + +#if defined(CPU_M68060_ONLY) && defined(CONFIG_060_WRITETHROUGH) +#define m68k_supervisor_cachemode _PAGE_CACHE040W +#elif defined(CPU_M68040_OR_M68060_ONLY) +#define m68k_supervisor_cachemode _PAGE_CACHE040 +#elif defined(CPU_M68020_OR_M68030_ONLY) +#define m68k_supervisor_cachemode 0 +#else +extern int m68k_supervisor_cachemode; +#endif + +#if defined(CPU_M68040_OR_M68060_ONLY) +#define mm_cachebits _PAGE_CACHE040 +#elif defined(CPU_M68020_OR_M68030_ONLY) +#define mm_cachebits 0 +#else +extern unsigned long mm_cachebits; +#endif + +#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED | mm_cachebits) +#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | mm_cachebits) +#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits) +#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits) +#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | mm_cachebits) + +/* Alternate definitions that are compile time constants, for + initializing protection_map. The cachebits are fixed later. */ +#define PAGE_NONE_C __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) +#define PAGE_SHARED_C __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED) +#define PAGE_COPY_C __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED) +#define PAGE_READONLY_C __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED) + +/* + * The m68k can't do page protection for execute, and considers that the same are read. + * Also, write permissions imply read permissions. This is the closest we can get.. + */ +#define __P000 PAGE_NONE_C +#define __P001 PAGE_READONLY_C +#define __P010 PAGE_COPY_C +#define __P011 PAGE_COPY_C +#define __P100 PAGE_READONLY_C +#define __P101 PAGE_READONLY_C +#define __P110 PAGE_COPY_C +#define __P111 PAGE_COPY_C + +#define __S000 PAGE_NONE_C +#define __S001 PAGE_READONLY_C +#define __S010 PAGE_SHARED_C +#define __S011 PAGE_SHARED_C +#define __S100 PAGE_READONLY_C +#define __S101 PAGE_READONLY_C +#define __S110 PAGE_SHARED_C +#define __S111 PAGE_SHARED_C + +/* + * Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + */ +#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) + +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ + pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); + return pte; +} + +static inline void pmd_set(pmd_t *pmdp, pte_t *ptep) +{ + unsigned long ptbl = virt_to_phys(ptep) | _PAGE_TABLE | _PAGE_ACCESSED; + unsigned long *ptr = pmdp->pmd; + short i = 16; + while (--i >= 0) { + *ptr++ = ptbl; + ptbl += (sizeof(pte_t)*PTRS_PER_PTE/16); + } +} + +static inline void pgd_set(pgd_t *pgdp, pmd_t *pmdp) +{ + pgd_val(*pgdp) = _PAGE_TABLE | _PAGE_ACCESSED | __pa(pmdp); +} + +#define __pte_page(pte) ((unsigned long)__va(pte_val(pte) & PAGE_MASK)) +#define __pmd_page(pmd) ((unsigned long)__va(pmd_val(pmd) & _TABLE_MASK)) +#define __pgd_page(pgd) ((unsigned long)__va(pgd_val(pgd) & _TABLE_MASK)) + + +#define pte_none(pte) (!pte_val(pte)) +#define pte_present(pte) (pte_val(pte) & (_PAGE_PRESENT | _PAGE_PROTNONE)) +#define pte_clear(mm,addr,ptep) ({ pte_val(*(ptep)) = 0; }) + +#define pte_page(pte) virt_to_page(__va(pte_val(pte))) +#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT) +#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) + +#define pmd_none(pmd) (!pmd_val(pmd)) +#define pmd_bad(pmd) ((pmd_val(pmd) & _DESCTYPE_MASK) != _PAGE_TABLE) +#define pmd_present(pmd) (pmd_val(pmd) & _PAGE_TABLE) +#define pmd_clear(pmdp) ({ \ + unsigned long *__ptr = pmdp->pmd; \ + short __i = 16; \ + while (--__i >= 0) \ + *__ptr++ = 0; \ +}) +#define pmd_page(pmd) virt_to_page(__va(pmd_val(pmd))) + + +#define pgd_none(pgd) (!pgd_val(pgd)) +#define pgd_bad(pgd) ((pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE) +#define pgd_present(pgd) (pgd_val(pgd) & _PAGE_TABLE) +#define pgd_clear(pgdp) ({ pgd_val(*pgdp) = 0; }) +#define pgd_page(pgd) (mem_map + ((unsigned long)(__va(pgd_val(pgd)) - PAGE_OFFSET) >> PAGE_SHIFT)) + +#define pte_ERROR(e) \ + printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) +#define pmd_ERROR(e) \ + printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) +#define pgd_ERROR(e) \ + printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) + + +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ +static inline int pte_write(pte_t pte) { return !(pte_val(pte) & _PAGE_RONLY); } +static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } +static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } +static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } +static inline int pte_special(pte_t pte) { return 0; } + +static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) |= _PAGE_RONLY; return pte; } +static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; } +static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } +static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) &= ~_PAGE_RONLY; return pte; } +static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; } +static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; } +static inline pte_t pte_mknocache(pte_t pte) +{ + pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | m68k_pgtable_cachemode; + return pte; +} +static inline pte_t pte_mkcache(pte_t pte) +{ + pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | m68k_supervisor_cachemode; + return pte; +} +static inline pte_t pte_mkspecial(pte_t pte) { return pte; } + +#define PAGE_DIR_OFFSET(tsk,address) pgd_offset((tsk),(address)) + +#define pgd_index(address) ((address) >> PGDIR_SHIFT) + +/* to find an entry in a page-table-directory */ +static inline pgd_t *pgd_offset(const struct mm_struct *mm, + unsigned long address) +{ + return mm->pgd + pgd_index(address); +} + +#define swapper_pg_dir kernel_pg_dir +extern pgd_t kernel_pg_dir[128]; + +static inline pgd_t *pgd_offset_k(unsigned long address) +{ + return kernel_pg_dir + (address >> PGDIR_SHIFT); +} + + +/* Find an entry in the second-level page table.. */ +static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address) +{ + return (pmd_t *)__pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PMD-1)); +} + +/* Find an entry in the third-level page table.. */ +static inline pte_t *pte_offset_kernel(pmd_t *pmdp, unsigned long address) +{ + return (pte_t *)__pmd_page(*pmdp) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); +} + +#define pte_offset_map(pmdp,address) ((pte_t *)__pmd_page(*pmdp) + (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))) +#define pte_offset_map_nested(pmdp, address) pte_offset_map(pmdp, address) +#define pte_unmap(pte) ((void)0) +#define pte_unmap_nested(pte) ((void)0) + +/* + * Allocate and free page tables. The xxx_kernel() versions are + * used to allocate a kernel page table - this turns on ASN bits + * if any. + */ + +/* Prior to calling these routines, the page should have been flushed + * from both the cache and ATC, or the CPU might not notice that the + * cache setting for the page has been changed. -jskov + */ +static inline void nocache_page(void *vaddr) +{ + unsigned long addr = (unsigned long)vaddr; + + if (CPU_IS_040_OR_060) { + pgd_t *dir; + pmd_t *pmdp; + pte_t *ptep; + + dir = pgd_offset_k(addr); + pmdp = pmd_offset(dir, addr); + ptep = pte_offset_kernel(pmdp, addr); + *ptep = pte_mknocache(*ptep); + } +} + +static inline void cache_page(void *vaddr) +{ + unsigned long addr = (unsigned long)vaddr; + + if (CPU_IS_040_OR_060) { + pgd_t *dir; + pmd_t *pmdp; + pte_t *ptep; + + dir = pgd_offset_k(addr); + pmdp = pmd_offset(dir, addr); + ptep = pte_offset_kernel(pmdp, addr); + *ptep = pte_mkcache(*ptep); + } +} + +#define PTE_FILE_MAX_BITS 28 + +static inline unsigned long pte_to_pgoff(pte_t pte) +{ + return pte.pte >> 4; +} + +static inline pte_t pgoff_to_pte(unsigned off) +{ + pte_t pte = { (off << 4) + _PAGE_FILE }; + return pte; +} + +/* Encode and de-code a swap entry (must be !pte_none(e) && !pte_present(e)) */ +#define __swp_type(x) (((x).val >> 4) & 0xff) +#define __swp_offset(x) ((x).val >> 12) +#define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 4) | ((offset) << 12) }) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) + +#endif /* !__ASSEMBLY__ */ +#endif /* _MOTOROLA_PGTABLE_H */ diff --git a/arch/m68k/include/asm/movs.h b/arch/m68k/include/asm/movs.h new file mode 100644 index 00000000000..67dbea36960 --- /dev/null +++ b/arch/m68k/include/asm/movs.h @@ -0,0 +1,55 @@ +#ifndef __MOVS_H__ +#define __MOVS_H__ + +/* +** movs.h +** +** Inline assembly macros to generate movs & related instructions +*/ + +/* Set DFC register value */ + +#define SET_DFC(x) \ + __asm__ __volatile__ (" movec %0,%/dfc" : : "d" (x)); + +/* Get DFC register value */ + +#define GET_DFC(x) \ + __asm__ __volatile__ (" movec %/dfc, %0" : "=d" (x) : ); + +/* Set SFC register value */ + +#define SET_SFC(x) \ + __asm__ __volatile__ (" movec %0,%/sfc" : : "d" (x)); + +/* Get SFC register value */ + +#define GET_SFC(x) \ + __asm__ __volatile__ (" movec %/sfc, %0" : "=d" (x) : ); + +#define SET_VBR(x) \ + __asm__ __volatile__ (" movec %0,%/vbr" : : "r" (x)); + +#define GET_VBR(x) \ + __asm__ __volatile__ (" movec %/vbr, %0" : "=g" (x) : ); + +/* Set a byte using the "movs" instruction */ + +#define SET_CONTROL_BYTE(addr,value) \ + __asm__ __volatile__ (" movsb %0, %1@" : : "d" (value), "a" (addr)); + +/* Get a byte using the "movs" instruction */ + +#define GET_CONTROL_BYTE(addr,value) \ + __asm__ __volatile__ (" movsb %1@, %0" : "=d" (value) : "a" (addr)); + +/* Set a (long)word using the "movs" instruction */ + +#define SET_CONTROL_WORD(addr,value) \ + __asm__ __volatile__ (" movsl %0, %1@" : : "d" (value), "a" (addr)); + +/* Get a (long)word using the "movs" instruction */ + +#define GET_CONTROL_WORD(addr,value) \ + __asm__ __volatile__ (" movsl %1@, %0" : "=d" (value) : "a" (addr)); +#endif diff --git a/arch/m68k/include/asm/msgbuf.h b/arch/m68k/include/asm/msgbuf.h new file mode 100644 index 00000000000..243cb798de8 --- /dev/null +++ b/arch/m68k/include/asm/msgbuf.h @@ -0,0 +1,31 @@ +#ifndef _M68K_MSGBUF_H +#define _M68K_MSGBUF_H + +/* + * The msqid64_ds structure for m68k architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct msqid64_ds { + struct ipc64_perm msg_perm; + __kernel_time_t msg_stime; /* last msgsnd time */ + unsigned long __unused1; + __kernel_time_t msg_rtime; /* last msgrcv time */ + unsigned long __unused2; + __kernel_time_t msg_ctime; /* last change time */ + unsigned long __unused3; + unsigned long msg_cbytes; /* current number of bytes on queue */ + unsigned long msg_qnum; /* number of messages in queue */ + unsigned long msg_qbytes; /* max number of bytes on queue */ + __kernel_pid_t msg_lspid; /* pid of last msgsnd */ + __kernel_pid_t msg_lrpid; /* last receive pid */ + unsigned long __unused4; + unsigned long __unused5; +}; + +#endif /* _M68K_MSGBUF_H */ diff --git a/arch/m68k/include/asm/mutex.h b/arch/m68k/include/asm/mutex.h new file mode 100644 index 00000000000..458c1f7fbc1 --- /dev/null +++ b/arch/m68k/include/asm/mutex.h @@ -0,0 +1,9 @@ +/* + * Pull in the generic implementation for the mutex fastpath. + * + * TODO: implement optimized primitives instead, or leave the generic + * implementation in place, or pick the atomic_xchg() based generic + * implementation. (see asm-generic/mutex-xchg.h for details) + */ + +#include diff --git a/arch/m68k/include/asm/mvme147hw.h b/arch/m68k/include/asm/mvme147hw.h new file mode 100644 index 00000000000..b8104310847 --- /dev/null +++ b/arch/m68k/include/asm/mvme147hw.h @@ -0,0 +1,113 @@ +#ifndef _MVME147HW_H_ +#define _MVME147HW_H_ + +#include + +typedef struct { + unsigned char + ctrl, + bcd_sec, + bcd_min, + bcd_hr, + bcd_dow, + bcd_dom, + bcd_mth, + bcd_year; +} MK48T02; + +#define RTC_WRITE 0x80 +#define RTC_READ 0x40 +#define RTC_STOP 0x20 + +#define m147_rtc ((MK48T02 * volatile)0xfffe07f8) + + +struct pcc_regs { + volatile u_long dma_tadr; + volatile u_long dma_dadr; + volatile u_long dma_bcr; + volatile u_long dma_hr; + volatile u_short t1_preload; + volatile u_short t1_count; + volatile u_short t2_preload; + volatile u_short t2_count; + volatile u_char t1_int_cntrl; + volatile u_char t1_cntrl; + volatile u_char t2_int_cntrl; + volatile u_char t2_cntrl; + volatile u_char ac_fail; + volatile u_char watchdog; + volatile u_char lpt_intr; + volatile u_char lpt_cntrl; + volatile u_char dma_intr; + volatile u_char dma_cntrl; + volatile u_char bus_error; + volatile u_char dma_status; + volatile u_char abort; + volatile u_char ta_fnctl; + volatile u_char serial_cntrl; + volatile u_char general_cntrl; + volatile u_char lan_cntrl; + volatile u_char general_status; + volatile u_char scsi_interrupt; + volatile u_char slave; + volatile u_char soft1_cntrl; + volatile u_char int_base; + volatile u_char soft2_cntrl; + volatile u_char revision_level; + volatile u_char lpt_data; + volatile u_char lpt_status; + }; + +#define m147_pcc ((struct pcc_regs * volatile)0xfffe1000) + + +#define PCC_INT_ENAB 0x08 + +#define PCC_TIMER_INT_CLR 0x80 +#define PCC_TIMER_PRELOAD 63936l + +#define PCC_LEVEL_ABORT 0x07 +#define PCC_LEVEL_SERIAL 0x04 +#define PCC_LEVEL_ETH 0x04 +#define PCC_LEVEL_TIMER1 0x04 +#define PCC_LEVEL_SCSI_PORT 0x04 +#define PCC_LEVEL_SCSI_DMA 0x04 + +#define PCC_IRQ_AC_FAIL (IRQ_USER+0) +#define PCC_IRQ_BERR (IRQ_USER+1) +#define PCC_IRQ_ABORT (IRQ_USER+2) +/* #define PCC_IRQ_SERIAL (IRQ_USER+3) */ +#define PCC_IRQ_PRINTER (IRQ_USER+7) +#define PCC_IRQ_TIMER1 (IRQ_USER+8) +#define PCC_IRQ_TIMER2 (IRQ_USER+9) +#define PCC_IRQ_SOFTWARE1 (IRQ_USER+10) +#define PCC_IRQ_SOFTWARE2 (IRQ_USER+11) + + +#define M147_SCC_A_ADDR 0xfffe3002 +#define M147_SCC_B_ADDR 0xfffe3000 +#define M147_SCC_PCLK 5000000 + +#define MVME147_IRQ_SCSI_PORT (IRQ_USER+0x45) +#define MVME147_IRQ_SCSI_DMA (IRQ_USER+0x46) + +/* SCC interrupts, for MVME147 */ + +#define MVME147_IRQ_TYPE_PRIO 0 +#define MVME147_IRQ_SCC_BASE (IRQ_USER+32) +#define MVME147_IRQ_SCCB_TX (IRQ_USER+32) +#define MVME147_IRQ_SCCB_STAT (IRQ_USER+34) +#define MVME147_IRQ_SCCB_RX (IRQ_USER+36) +#define MVME147_IRQ_SCCB_SPCOND (IRQ_USER+38) +#define MVME147_IRQ_SCCA_TX (IRQ_USER+40) +#define MVME147_IRQ_SCCA_STAT (IRQ_USER+42) +#define MVME147_IRQ_SCCA_RX (IRQ_USER+44) +#define MVME147_IRQ_SCCA_SPCOND (IRQ_USER+46) + +#define MVME147_LANCE_BASE 0xfffe1800 +#define MVME147_LANCE_IRQ (IRQ_USER+4) + +#define ETHERNET_ADDRESS 0xfffe0778 + +#endif diff --git a/arch/m68k/include/asm/mvme16xhw.h b/arch/m68k/include/asm/mvme16xhw.h new file mode 100644 index 00000000000..6117f56653d --- /dev/null +++ b/arch/m68k/include/asm/mvme16xhw.h @@ -0,0 +1,111 @@ +#ifndef _M68K_MVME16xHW_H_ +#define _M68K_MVME16xHW_H_ + +#include + +/* Board ID data structure - pointer to this retrieved from Bug by head.S */ + +/* Note, bytes 12 and 13 are board no in BCD (0162,0166,0167,0177,etc) */ + +extern long mvme_bdid_ptr; + +typedef struct { + char bdid[4]; + u_char rev, mth, day, yr; + u_short size, reserved; + u_short brdno; + char brdsuffix[2]; + u_long options; + u_short clun, dlun, ctype, dnum; + u_long option2; +} t_bdid, *p_bdid; + + +typedef struct { + u_char ack_icr, + flt_icr, + sel_icr, + pe_icr, + bsy_icr, + spare1, + isr, + cr, + spare2, + spare3, + spare4, + data; +} MVMElp, *MVMElpPtr; + +#define MVME_LPR_BASE 0xfff42030 + +#define mvmelp ((*(volatile MVMElpPtr)(MVME_LPR_BASE))) + +typedef struct { + unsigned char + ctrl, + bcd_sec, + bcd_min, + bcd_hr, + bcd_dow, + bcd_dom, + bcd_mth, + bcd_year; +} MK48T08_t, *MK48T08ptr_t; + +#define RTC_WRITE 0x80 +#define RTC_READ 0x40 +#define RTC_STOP 0x20 + +#define MVME_RTC_BASE 0xfffc1ff8 + +#define MVME_I596_BASE 0xfff46000 + +#define MVME_SCC_A_ADDR 0xfff45005 +#define MVME_SCC_B_ADDR 0xfff45001 +#define MVME_SCC_PCLK 10000000 + +#define MVME162_IRQ_TYPE_PRIO 0 + +#define MVME167_IRQ_PRN (IRQ_USER+20) +#define MVME16x_IRQ_I596 (IRQ_USER+23) +#define MVME16x_IRQ_SCSI (IRQ_USER+21) +#define MVME16x_IRQ_FLY (IRQ_USER+63) +#define MVME167_IRQ_SER_ERR (IRQ_USER+28) +#define MVME167_IRQ_SER_MODEM (IRQ_USER+29) +#define MVME167_IRQ_SER_TX (IRQ_USER+30) +#define MVME167_IRQ_SER_RX (IRQ_USER+31) +#define MVME16x_IRQ_TIMER (IRQ_USER+25) +#define MVME167_IRQ_ABORT (IRQ_USER+46) +#define MVME162_IRQ_ABORT (IRQ_USER+30) + +/* SCC interrupts, for MVME162 */ +#define MVME162_IRQ_SCC_BASE (IRQ_USER+0) +#define MVME162_IRQ_SCCB_TX (IRQ_USER+0) +#define MVME162_IRQ_SCCB_STAT (IRQ_USER+2) +#define MVME162_IRQ_SCCB_RX (IRQ_USER+4) +#define MVME162_IRQ_SCCB_SPCOND (IRQ_USER+6) +#define MVME162_IRQ_SCCA_TX (IRQ_USER+8) +#define MVME162_IRQ_SCCA_STAT (IRQ_USER+10) +#define MVME162_IRQ_SCCA_RX (IRQ_USER+12) +#define MVME162_IRQ_SCCA_SPCOND (IRQ_USER+14) + +/* MVME162 version register */ + +#define MVME162_VERSION_REG 0xfff4202e + +extern unsigned short mvme16x_config; + +/* Lower 8 bits must match the revision register in the MC2 chip */ + +#define MVME16x_CONFIG_SPEED_32 0x0001 +#define MVME16x_CONFIG_NO_VMECHIP2 0x0002 +#define MVME16x_CONFIG_NO_SCSICHIP 0x0004 +#define MVME16x_CONFIG_NO_ETHERNET 0x0008 +#define MVME16x_CONFIG_GOT_FPU 0x0010 + +#define MVME16x_CONFIG_GOT_LP 0x0100 +#define MVME16x_CONFIG_GOT_CD2401 0x0200 +#define MVME16x_CONFIG_GOT_SCCA 0x0400 +#define MVME16x_CONFIG_GOT_SCCB 0x0800 + +#endif diff --git a/arch/m68k/include/asm/nettel.h b/arch/m68k/include/asm/nettel.h new file mode 100644 index 00000000000..0299f6a2dee --- /dev/null +++ b/arch/m68k/include/asm/nettel.h @@ -0,0 +1,108 @@ +/****************************************************************************/ + +/* + * nettel.h -- Lineo (formerly Moreton Bay) NETtel support. + * + * (C) Copyright 1999-2000, Moreton Bay (www.moretonbay.com) + * (C) Copyright 2000-2001, Lineo Inc. (www.lineo.com) + * (C) Copyright 2001-2002, SnapGear Inc., (www.snapgear.com) + */ + +/****************************************************************************/ +#ifndef nettel_h +#define nettel_h +/****************************************************************************/ + + +/****************************************************************************/ +#ifdef CONFIG_NETtel +/****************************************************************************/ + +#ifdef CONFIG_COLDFIRE +#include +#include +#endif + +/*---------------------------------------------------------------------------*/ +#if defined(CONFIG_M5307) +/* + * NETtel/5307 based hardware first. DTR/DCD lines are wired to + * GPIO lines. Most of the LED's are driver through a latch + * connected to CS2. + */ +#define MCFPP_DCD1 0x0001 +#define MCFPP_DCD0 0x0002 +#define MCFPP_DTR1 0x0004 +#define MCFPP_DTR0 0x0008 + +#define NETtel_LEDADDR 0x30400000 + +#ifndef __ASSEMBLY__ + +extern volatile unsigned short ppdata; + +/* + * These functions defined to give quasi generic access to the + * PPIO bits used for DTR/DCD. + */ +static __inline__ unsigned int mcf_getppdata(void) +{ + volatile unsigned short *pp; + pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT); + return((unsigned int) *pp); +} + +static __inline__ void mcf_setppdata(unsigned int mask, unsigned int bits) +{ + volatile unsigned short *pp; + pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT); + ppdata = (ppdata & ~mask) | bits; + *pp = ppdata; +} +#endif + +/*---------------------------------------------------------------------------*/ +#elif defined(CONFIG_M5206e) +/* + * NETtel/5206e based hardware has leds on latch on CS3. + * No support modem for lines?? + */ +#define NETtel_LEDADDR 0x50000000 + +/*---------------------------------------------------------------------------*/ +#elif defined(CONFIG_M5272) +/* + * NETtel/5272 based hardware. DTR/DCD lines are wired to GPB lines. + */ +#define MCFPP_DCD0 0x0080 +#define MCFPP_DCD1 0x0000 /* Port 1 no DCD support */ +#define MCFPP_DTR0 0x0040 +#define MCFPP_DTR1 0x0000 /* Port 1 no DTR support */ + +#ifndef __ASSEMBLY__ +/* + * These functions defined to give quasi generic access to the + * PPIO bits used for DTR/DCD. + */ +static __inline__ unsigned int mcf_getppdata(void) +{ + volatile unsigned short *pp; + pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PBDAT); + return((unsigned int) *pp); +} + +static __inline__ void mcf_setppdata(unsigned int mask, unsigned int bits) +{ + volatile unsigned short *pp; + pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PBDAT); + *pp = (*pp & ~mask) | bits; +} +#endif + +#endif +/*---------------------------------------------------------------------------*/ + +/****************************************************************************/ +#endif /* CONFIG_NETtel */ +/****************************************************************************/ +#endif /* nettel_h */ diff --git a/arch/m68k/include/asm/nubus.h b/arch/m68k/include/asm/nubus.h new file mode 100644 index 00000000000..d6be9976f1a --- /dev/null +++ b/arch/m68k/include/asm/nubus.h @@ -0,0 +1,46 @@ +#ifndef _ASM_M68K_NUBUS_H +#define _ASM_M68K_NUBUS_H + +#include + +#define nubus_readb raw_inb +#define nubus_readw raw_inw +#define nubus_readl raw_inl + +#define nubus_writeb raw_outb +#define nubus_writew raw_outw +#define nubus_writel raw_outl + +#define nubus_memset_io(a,b,c) memset((void *)(a),(b),(c)) +#define nubus_memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) +#define nubus_memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) + +static inline void *nubus_remap_nocache_ser(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); +} + +static inline void *nubus_remap_nocache_nonser(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_NONSER); +} + +static inline void *nbus_remap_writethrough(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_WRITETHROUGH); +} + +static inline void *nubus_remap_fullcache(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_FULL_CACHING); +} + +#define nubus_unmap iounmap +#define nubus_iounmap iounmap +#define nubus_ioremap nubus_remap_nocache_ser + +#endif /* _ASM_NUBUS_H */ diff --git a/arch/m68k/include/asm/openprom.h b/arch/m68k/include/asm/openprom.h new file mode 100644 index 00000000000..d33cdadf78e --- /dev/null +++ b/arch/m68k/include/asm/openprom.h @@ -0,0 +1,312 @@ +#ifndef __SPARC_OPENPROM_H +#define __SPARC_OPENPROM_H + +/* openprom.h: Prom structures and defines for access to the OPENBOOT + * prom routines and data areas. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + + +/* Empirical constants... */ +#ifdef CONFIG_SUN3 +#define KADB_DEBUGGER_BEGVM 0x0fee0000 /* There is no kadb yet but...*/ +#define LINUX_OPPROM_BEGVM 0x0fef0000 +#define LINUX_OPPROM_ENDVM 0x0ff10000 /* I think this is right - tm */ +#else +#define KADB_DEBUGGER_BEGVM 0xffc00000 /* Where kern debugger is in virt-mem */ +#define LINUX_OPPROM_BEGVM 0xffd00000 +#define LINUX_OPPROM_ENDVM 0xfff00000 +#define LINUX_OPPROM_MAGIC 0x10010407 +#endif + +#ifndef __ASSEMBLY__ +/* V0 prom device operations. */ +struct linux_dev_v0_funcs { + int (*v0_devopen)(char *device_str); + int (*v0_devclose)(int dev_desc); + int (*v0_rdblkdev)(int dev_desc, int num_blks, int blk_st, char *buf); + int (*v0_wrblkdev)(int dev_desc, int num_blks, int blk_st, char *buf); + int (*v0_wrnetdev)(int dev_desc, int num_bytes, char *buf); + int (*v0_rdnetdev)(int dev_desc, int num_bytes, char *buf); + int (*v0_rdchardev)(int dev_desc, int num_bytes, int dummy, char *buf); + int (*v0_wrchardev)(int dev_desc, int num_bytes, int dummy, char *buf); + int (*v0_seekdev)(int dev_desc, long logical_offst, int from); +}; + +/* V2 and later prom device operations. */ +struct linux_dev_v2_funcs { + int (*v2_inst2pkg)(int d); /* Convert ihandle to phandle */ + char * (*v2_dumb_mem_alloc)(char *va, unsigned sz); + void (*v2_dumb_mem_free)(char *va, unsigned sz); + + /* To map devices into virtual I/O space. */ + char * (*v2_dumb_mmap)(char *virta, int which_io, unsigned paddr, unsigned sz); + void (*v2_dumb_munmap)(char *virta, unsigned size); + + int (*v2_dev_open)(char *devpath); + void (*v2_dev_close)(int d); + int (*v2_dev_read)(int d, char *buf, int nbytes); + int (*v2_dev_write)(int d, char *buf, int nbytes); + int (*v2_dev_seek)(int d, int hi, int lo); + + /* Never issued (multistage load support) */ + void (*v2_wheee2)(void); + void (*v2_wheee3)(void); +}; + +struct linux_mlist_v0 { + struct linux_mlist_v0 *theres_more; + char *start_adr; + unsigned num_bytes; +}; + +struct linux_mem_v0 { + struct linux_mlist_v0 **v0_totphys; + struct linux_mlist_v0 **v0_prommap; + struct linux_mlist_v0 **v0_available; /* What we can use */ +}; + +/* Arguments sent to the kernel from the boot prompt. */ +struct linux_arguments_v0 { + char *argv[8]; + char args[100]; + char boot_dev[2]; + int boot_dev_ctrl; + int boot_dev_unit; + int dev_partition; + char *kernel_file_name; + void *aieee1; /* XXX */ +}; + +/* V2 and up boot things. */ +struct linux_bootargs_v2 { + char **bootpath; + char **bootargs; + int *fd_stdin; + int *fd_stdout; +}; + +#if defined(CONFIG_SUN3) || defined(CONFIG_SUN3X) +struct linux_romvec { + char *pv_initsp; + int (*pv_startmon)(void); + + int *diagberr; + + struct linux_arguments_v0 **pv_v0bootargs; + unsigned *pv_sun3mem; + + unsigned char (*pv_getchar)(void); + int (*pv_putchar)(int ch); + int (*pv_nbgetchar)(void); + int (*pv_nbputchar)(int ch); + unsigned char *pv_echo; + unsigned char *pv_insource; + unsigned char *pv_outsink; + + int (*pv_getkey)(void); + int (*pv_initgetkey)(void); + unsigned int *pv_translation; + unsigned char *pv_keybid; + int *pv_screen_x; + int *pv_screen_y; + struct keybuf *pv_keybuf; + + char *pv_monid; + + /* + * Frame buffer output and terminal emulation + */ + + int (*pv_fbwritechar)(char); + int *pv_fbaddr; + char **pv_font; + int (*pv_fbwritestr)(char); + + void (*pv_reboot)(char *bootstr); + + /* + * Line input and parsing + */ + + unsigned char *pv_linebuf; + unsigned char **pv_lineptr; + int *pv_linesize; + int (*pv_getline)(void); + unsigned char (*pv_getnextchar)(void); + unsigned char (*pv_peeknextchar)(void); + int *pv_fbthere; + int (*pv_getnum)(void); + + void (*pv_printf)(const char *fmt, ...); + int (*pv_printhex)(void); + + unsigned char *pv_leds; + int (*pv_setleds)(void); + + /* + * Non-maskable interrupt (nmi) information + */ + + int (*pv_nmiaddr)(void); + int (*pv_abortentry)(void); + int *pv_nmiclock; + + int *pv_fbtype; + + /* + * Assorted other things + */ + + unsigned pv_romvers; + struct globram *pv_globram; + char *pv_kbdzscc; + + int *pv_keyrinit; + unsigned char *pv_keyrtick; + unsigned *pv_memoryavail; + long *pv_resetaddr; + long *pv_resetmap; + + void (*pv_halt)(void); + unsigned char *pv_memorybitmap; + +#ifdef CONFIG_SUN3 + void (*pv_setctxt)(int ctxt, char *va, int pmeg); + void (*pv_vector_cmd)(void); + int dummy1z; + int dummy2z; + int dummy3z; + int dummy4z; +#endif +}; +#else +/* The top level PROM vector. */ +struct linux_romvec { + /* Version numbers. */ + unsigned int pv_magic_cookie; + unsigned int pv_romvers; + unsigned int pv_plugin_revision; + unsigned int pv_printrev; + + /* Version 0 memory descriptors. */ + struct linux_mem_v0 pv_v0mem; + + /* Node operations. */ + struct linux_nodeops *pv_nodeops; + + char **pv_bootstr; + struct linux_dev_v0_funcs pv_v0devops; + + char *pv_stdin; + char *pv_stdout; +#define PROMDEV_KBD 0 /* input from keyboard */ +#define PROMDEV_SCREEN 0 /* output to screen */ +#define PROMDEV_TTYA 1 /* in/out to ttya */ +#define PROMDEV_TTYB 2 /* in/out to ttyb */ + + /* Blocking getchar/putchar. NOT REENTRANT! (grr) */ + int (*pv_getchar)(void); + void (*pv_putchar)(int ch); + + /* Non-blocking variants. */ + int (*pv_nbgetchar)(void); + int (*pv_nbputchar)(int ch); + + void (*pv_putstr)(char *str, int len); + + /* Miscellany. */ + void (*pv_reboot)(char *bootstr); + void (*pv_printf)(__const__ char *fmt, ...); + void (*pv_abort)(void); + __volatile__ int *pv_ticks; + void (*pv_halt)(void); + void (**pv_synchook)(void); + + /* Evaluate a forth string, not different proto for V0 and V2->up. */ + union { + void (*v0_eval)(int len, char *str); + void (*v2_eval)(char *str); + } pv_fortheval; + + struct linux_arguments_v0 **pv_v0bootargs; + + /* Get ether address. */ + unsigned int (*pv_enaddr)(int d, char *enaddr); + + struct linux_bootargs_v2 pv_v2bootargs; + struct linux_dev_v2_funcs pv_v2devops; + + int filler[15]; + + /* This one is sun4c/sun4 only. */ + void (*pv_setctxt)(int ctxt, char *va, int pmeg); + + /* Prom version 3 Multiprocessor routines. This stuff is crazy. + * No joke. Calling these when there is only one cpu probably + * crashes the machine, have to test this. :-) + */ + + /* v3_cpustart() will start the cpu 'whichcpu' in mmu-context + * 'thiscontext' executing at address 'prog_counter' + */ + int (*v3_cpustart)(unsigned int whichcpu, int ctxtbl_ptr, + int thiscontext, char *prog_counter); + + /* v3_cpustop() will cause cpu 'whichcpu' to stop executing + * until a resume cpu call is made. + */ + int (*v3_cpustop)(unsigned int whichcpu); + + /* v3_cpuidle() will idle cpu 'whichcpu' until a stop or + * resume cpu call is made. + */ + int (*v3_cpuidle)(unsigned int whichcpu); + + /* v3_cpuresume() will resume processor 'whichcpu' executing + * starting with whatever 'pc' and 'npc' were left at the + * last 'idle' or 'stop' call. + */ + int (*v3_cpuresume)(unsigned int whichcpu); +}; +#endif + +/* Routines for traversing the prom device tree. */ +struct linux_nodeops { + int (*no_nextnode)(int node); + int (*no_child)(int node); + int (*no_proplen)(int node, char *name); + int (*no_getprop)(int node, char *name, char *val); + int (*no_setprop)(int node, char *name, char *val, int len); + char * (*no_nextprop)(int node, char *name); +}; + +/* More fun PROM structures for device probing. */ +#define PROMREG_MAX 16 +#define PROMVADDR_MAX 16 +#define PROMINTR_MAX 15 + +struct linux_prom_registers { + int which_io; /* is this in OBIO space? */ + char *phys_addr; /* The physical address of this register */ + int reg_size; /* How many bytes does this register take up? */ +}; + +struct linux_prom_irqs { + int pri; /* IRQ priority */ + int vector; /* This is foobar, what does it do? */ +}; + +/* Element of the "ranges" vector */ +struct linux_prom_ranges { + unsigned int ot_child_space; + unsigned int ot_child_base; /* Bus feels this */ + unsigned int ot_parent_space; + unsigned int ot_parent_base; /* CPU looks from here */ + unsigned int or_size; +}; + +#endif /* !(__ASSEMBLY__) */ + +#endif /* !(__SPARC_OPENPROM_H) */ diff --git a/arch/m68k/include/asm/oplib.h b/arch/m68k/include/asm/oplib.h new file mode 100644 index 00000000000..f082d03336b --- /dev/null +++ b/arch/m68k/include/asm/oplib.h @@ -0,0 +1,291 @@ +/* + * oplib.h: Describes the interface and available routines in the + * Linux Prom library. + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + */ + +#ifndef __SPARC_OPLIB_H +#define __SPARC_OPLIB_H + +#include + +/* The master romvec pointer... */ +extern struct linux_romvec *romvec; + +/* Enumeration to describe the prom major version we have detected. */ +enum prom_major_version { + PROM_V0, /* Original sun4c V0 prom */ + PROM_V2, /* sun4c and early sun4m V2 prom */ + PROM_V3, /* sun4m and later, up to sun4d/sun4e machines V3 */ + PROM_P1275, /* IEEE compliant ISA based Sun PROM, only sun4u */ +}; + +extern enum prom_major_version prom_vers; +/* Revision, and firmware revision. */ +extern unsigned int prom_rev, prom_prev; + +/* Root node of the prom device tree, this stays constant after + * initialization is complete. + */ +extern int prom_root_node; + +/* Pointer to prom structure containing the device tree traversal + * and usage utility functions. Only prom-lib should use these, + * users use the interface defined by the library only! + */ +extern struct linux_nodeops *prom_nodeops; + +/* The functions... */ + +/* You must call prom_init() before using any of the library services, + * preferably as early as possible. Pass it the romvec pointer. + */ +extern void prom_init(struct linux_romvec *rom_ptr); + +/* Boot argument acquisition, returns the boot command line string. */ +extern char *prom_getbootargs(void); + +/* Device utilities. */ + +/* Map and unmap devices in IO space at virtual addresses. Note that the + * virtual address you pass is a request and the prom may put your mappings + * somewhere else, so check your return value as that is where your new + * mappings really are! + * + * Another note, these are only available on V2 or higher proms! + */ +extern char *prom_mapio(char *virt_hint, int io_space, unsigned int phys_addr, unsigned int num_bytes); +extern void prom_unmapio(char *virt_addr, unsigned int num_bytes); + +/* Device operations. */ + +/* Open the device described by the passed string. Note, that the format + * of the string is different on V0 vs. V2->higher proms. The caller must + * know what he/she is doing! Returns the device descriptor, an int. + */ +extern int prom_devopen(char *device_string); + +/* Close a previously opened device described by the passed integer + * descriptor. + */ +extern int prom_devclose(int device_handle); + +/* Do a seek operation on the device described by the passed integer + * descriptor. + */ +extern void prom_seek(int device_handle, unsigned int seek_hival, + unsigned int seek_lowval); + +/* Machine memory configuration routine. */ + +/* This function returns a V0 format memory descriptor table, it has three + * entries. One for the total amount of physical ram on the machine, one + * for the amount of physical ram available, and one describing the virtual + * areas which are allocated by the prom. So, in a sense the physical + * available is a calculation of the total physical minus the physical mapped + * by the prom with virtual mappings. + * + * These lists are returned pre-sorted, this should make your life easier + * since the prom itself is way too lazy to do such nice things. + */ +extern struct linux_mem_v0 *prom_meminfo(void); + +/* Miscellaneous routines, don't really fit in any category per se. */ + +/* Reboot the machine with the command line passed. */ +extern void prom_reboot(char *boot_command); + +/* Evaluate the forth string passed. */ +extern void prom_feval(char *forth_string); + +/* Enter the prom, with possibility of continuation with the 'go' + * command in newer proms. + */ +extern void prom_cmdline(void); + +/* Enter the prom, with no chance of continuation for the stand-alone + * which calls this. + */ +extern void prom_halt(void); + +/* Set the PROM 'sync' callback function to the passed function pointer. + * When the user gives the 'sync' command at the prom prompt while the + * kernel is still active, the prom will call this routine. + * + * XXX The arguments are different on V0 vs. V2->higher proms, grrr! XXX + */ +typedef void (*sync_func_t)(void); +extern void prom_setsync(sync_func_t func_ptr); + +/* Acquire the IDPROM of the root node in the prom device tree. This + * gets passed a buffer where you would like it stuffed. The return value + * is the format type of this idprom or 0xff on error. + */ +extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size); + +/* Get the prom major version. */ +extern int prom_version(void); + +/* Get the prom plugin revision. */ +extern int prom_getrev(void); + +/* Get the prom firmware revision. */ +extern int prom_getprev(void); + +/* Character operations to/from the console.... */ + +/* Non-blocking get character from console. */ +extern int prom_nbgetchar(void); + +/* Non-blocking put character to console. */ +extern int prom_nbputchar(char character); + +/* Blocking get character from console. */ +extern char prom_getchar(void); + +/* Blocking put character to console. */ +extern void prom_putchar(char character); + +/* Prom's internal printf routine, don't use in kernel/boot code. */ +void prom_printf(char *fmt, ...); + +/* Query for input device type */ + +enum prom_input_device { + PROMDEV_IKBD, /* input from keyboard */ + PROMDEV_ITTYA, /* input from ttya */ + PROMDEV_ITTYB, /* input from ttyb */ + PROMDEV_I_UNK, +}; + +extern enum prom_input_device prom_query_input_device(void); + +/* Query for output device type */ + +enum prom_output_device { + PROMDEV_OSCREEN, /* to screen */ + PROMDEV_OTTYA, /* to ttya */ + PROMDEV_OTTYB, /* to ttyb */ + PROMDEV_O_UNK, +}; + +extern enum prom_output_device prom_query_output_device(void); + +/* Multiprocessor operations... */ + +/* Start the CPU with the given device tree node, context table, and context + * at the passed program counter. + */ +extern int prom_startcpu(int cpunode, struct linux_prom_registers *context_table, + int context, char *program_counter); + +/* Stop the CPU with the passed device tree node. */ +extern int prom_stopcpu(int cpunode); + +/* Idle the CPU with the passed device tree node. */ +extern int prom_idlecpu(int cpunode); + +/* Re-Start the CPU with the passed device tree node. */ +extern int prom_restartcpu(int cpunode); + +/* PROM memory allocation facilities... */ + +/* Allocated at possibly the given virtual address a chunk of the + * indicated size. + */ +extern char *prom_alloc(char *virt_hint, unsigned int size); + +/* Free a previously allocated chunk. */ +extern void prom_free(char *virt_addr, unsigned int size); + +/* Sun4/sun4c specific memory-management startup hook. */ + +/* Map the passed segment in the given context at the passed + * virtual address. + */ +extern void prom_putsegment(int context, unsigned long virt_addr, + int physical_segment); + +/* PROM device tree traversal functions... */ + +/* Get the child node of the given node, or zero if no child exists. */ +extern int prom_getchild(int parent_node); + +/* Get the next sibling node of the given node, or zero if no further + * siblings exist. + */ +extern int prom_getsibling(int node); + +/* Get the length, at the passed node, of the given property type. + * Returns -1 on error (ie. no such property at this node). + */ +extern int prom_getproplen(int thisnode, char *property); + +/* Fetch the requested property using the given buffer. Returns + * the number of bytes the prom put into your buffer or -1 on error. + */ +extern int prom_getproperty(int thisnode, char *property, + char *prop_buffer, int propbuf_size); + +/* Acquire an integer property. */ +extern int prom_getint(int node, char *property); + +/* Acquire an integer property, with a default value. */ +extern int prom_getintdefault(int node, char *property, int defval); + +/* Acquire a boolean property, 0=FALSE 1=TRUE. */ +extern int prom_getbool(int node, char *prop); + +/* Acquire a string property, null string on error. */ +extern void prom_getstring(int node, char *prop, char *buf, int bufsize); + +/* Does the passed node have the given "name"? YES=1 NO=0 */ +extern int prom_nodematch(int thisnode, char *name); + +/* Search all siblings starting at the passed node for "name" matching + * the given string. Returns the node on success, zero on failure. + */ +extern int prom_searchsiblings(int node_start, char *name); + +/* Return the first property type, as a string, for the given node. + * Returns a null string on error. + */ +extern char *prom_firstprop(int node); + +/* Returns the next property after the passed property for the given + * node. Returns null string on failure. + */ +extern char *prom_nextprop(int node, char *prev_property); + +/* Returns 1 if the specified node has given property. */ +extern int prom_node_has_property(int node, char *property); + +/* Set the indicated property at the given node with the passed value. + * Returns the number of bytes of your value that the prom took. + */ +extern int prom_setprop(int node, char *prop_name, char *prop_value, + int value_size); + +extern int prom_pathtoinode(char *path); +extern int prom_inst2pkg(int); + +/* Dorking with Bus ranges... */ + +/* Adjust reg values with the passed ranges. */ +extern void prom_adjust_regs(struct linux_prom_registers *regp, int nregs, + struct linux_prom_ranges *rangep, int nranges); + +/* Adjust child ranges with the passed parent ranges. */ +extern void prom_adjust_ranges(struct linux_prom_ranges *cranges, int ncranges, + struct linux_prom_ranges *pranges, int npranges); + +/* Apply promlib probed OBIO ranges to registers. */ +extern void prom_apply_obio_ranges(struct linux_prom_registers *obioregs, int nregs); + +/* Apply ranges of any prom node (and optionally parent node as well) to registers. */ +extern void prom_apply_generic_ranges(int node, int parent, + struct linux_prom_registers *sbusregs, int nregs); + + +#endif /* !(__SPARC_OPLIB_H) */ diff --git a/arch/m68k/include/asm/page.h b/arch/m68k/include/asm/page.h new file mode 100644 index 00000000000..f2b4480cc98 --- /dev/null +++ b/arch/m68k/include/asm/page.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "page_no.h" +#else +#include "page_mm.h" +#endif diff --git a/arch/m68k/include/asm/page_mm.h b/arch/m68k/include/asm/page_mm.h new file mode 100644 index 00000000000..a34b8bad784 --- /dev/null +++ b/arch/m68k/include/asm/page_mm.h @@ -0,0 +1,228 @@ +#ifndef _M68K_PAGE_H +#define _M68K_PAGE_H + +#include + +/* PAGE_SHIFT determines the page size */ +#ifndef CONFIG_SUN3 +#define PAGE_SHIFT (12) +#else +#define PAGE_SHIFT (13) +#endif +#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +#include + +#if PAGE_SHIFT < 13 +#define THREAD_SIZE (8192) +#else +#define THREAD_SIZE PAGE_SIZE +#endif + +#ifndef __ASSEMBLY__ + +#include + +#include + +#define get_user_page(vaddr) __get_free_page(GFP_KERNEL) +#define free_user_page(page, addr) free_page(addr) + +/* + * We don't need to check for alignment etc. + */ +#ifdef CPU_M68040_OR_M68060_ONLY +static inline void copy_page(void *to, void *from) +{ + unsigned long tmp; + + __asm__ __volatile__("1:\t" + ".chip 68040\n\t" + "move16 %1@+,%0@+\n\t" + "move16 %1@+,%0@+\n\t" + ".chip 68k\n\t" + "dbra %2,1b\n\t" + : "=a" (to), "=a" (from), "=d" (tmp) + : "0" (to), "1" (from) , "2" (PAGE_SIZE / 32 - 1) + ); +} + +static inline void clear_page(void *page) +{ + unsigned long tmp; + unsigned long *sp = page; + + *sp++ = 0; + *sp++ = 0; + *sp++ = 0; + *sp++ = 0; + + __asm__ __volatile__("1:\t" + ".chip 68040\n\t" + "move16 %2@+,%0@+\n\t" + ".chip 68k\n\t" + "subqw #8,%2\n\t" + "subqw #8,%2\n\t" + "dbra %1,1b\n\t" + : "=a" (sp), "=d" (tmp) + : "a" (page), "0" (sp), + "1" ((PAGE_SIZE - 16) / 16 - 1)); +} + +#else +#define clear_page(page) memset((page), 0, PAGE_SIZE) +#define copy_page(to,from) memcpy((to), (from), PAGE_SIZE) +#endif + +#define clear_user_page(addr, vaddr, page) \ + do { clear_page(addr); \ + flush_dcache_page(page); \ + } while (0) +#define copy_user_page(to, from, vaddr, page) \ + do { copy_page(to, from); \ + flush_dcache_page(page); \ + } while (0) + +/* + * These are used to make use of C type-checking.. + */ +typedef struct { unsigned long pte; } pte_t; +typedef struct { unsigned long pmd[16]; } pmd_t; +typedef struct { unsigned long pgd; } pgd_t; +typedef struct { unsigned long pgprot; } pgprot_t; +typedef struct page *pgtable_t; + +#define pte_val(x) ((x).pte) +#define pmd_val(x) ((&x)->pmd[0]) +#define pgd_val(x) ((x).pgd) +#define pgprot_val(x) ((x).pgprot) + +#define __pte(x) ((pte_t) { (x) } ) +#define __pmd(x) ((pmd_t) { (x) } ) +#define __pgd(x) ((pgd_t) { (x) } ) +#define __pgprot(x) ((pgprot_t) { (x) } ) + +#endif /* !__ASSEMBLY__ */ + +#include + +#define PAGE_OFFSET (PAGE_OFFSET_RAW) + +#ifndef __ASSEMBLY__ + +extern unsigned long m68k_memoffset; + +#ifndef CONFIG_SUN3 + +#define WANT_PAGE_VIRTUAL + +static inline unsigned long ___pa(void *vaddr) +{ + unsigned long paddr; + asm ( + "1: addl #0,%0\n" + m68k_fixup(%c2, 1b+2) + : "=r" (paddr) + : "0" (vaddr), "i" (m68k_fixup_memoffset)); + return paddr; +} +#define __pa(vaddr) ___pa((void *)(vaddr)) +static inline void *__va(unsigned long paddr) +{ + void *vaddr; + asm ( + "1: subl #0,%0\n" + m68k_fixup(%c2, 1b+2) + : "=r" (vaddr) + : "0" (paddr), "i" (m68k_fixup_memoffset)); + return vaddr; +} + +#else /* !CONFIG_SUN3 */ +/* This #define is a horrible hack to suppress lots of warnings. --m */ +#define __pa(x) ___pa((unsigned long)(x)) +static inline unsigned long ___pa(unsigned long x) +{ + if(x == 0) + return 0; + if(x >= PAGE_OFFSET) + return (x-PAGE_OFFSET); + else + return (x+0x2000000); +} + +static inline void *__va(unsigned long x) +{ + if(x == 0) + return (void *)0; + + if(x < 0x2000000) + return (void *)(x+PAGE_OFFSET); + else + return (void *)(x-0x2000000); +} +#endif /* CONFIG_SUN3 */ + +/* + * NOTE: virtual isn't really correct, actually it should be the offset into the + * memory node, but we have no highmem, so that works for now. + * TODO: implement (fast) pfn<->pgdat_idx conversion functions, this makes lots + * of the shifts unnecessary. + */ +#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) +#define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT) + +extern int m68k_virt_to_node_shift; + +#ifdef CONFIG_SINGLE_MEMORY_CHUNK +#define __virt_to_node(addr) (&pg_data_map[0]) +#else +extern struct pglist_data *pg_data_table[]; + +static inline __attribute_const__ int __virt_to_node_shift(void) +{ + int shift; + + asm ( + "1: moveq #0,%0\n" + m68k_fixup(%c1, 1b) + : "=d" (shift) + : "i" (m68k_fixup_vnode_shift)); + return shift; +} + +#define __virt_to_node(addr) (pg_data_table[(unsigned long)(addr) >> __virt_to_node_shift()]) +#endif + +#define virt_to_page(addr) ({ \ + pfn_to_page(virt_to_pfn(addr)); \ +}) +#define page_to_virt(page) ({ \ + pfn_to_virt(page_to_pfn(page)); \ +}) + +#define pfn_to_page(pfn) ({ \ + unsigned long __pfn = (pfn); \ + struct pglist_data *pgdat; \ + pgdat = __virt_to_node((unsigned long)pfn_to_virt(__pfn)); \ + pgdat->node_mem_map + (__pfn - pgdat->node_start_pfn); \ +}) +#define page_to_pfn(_page) ({ \ + struct page *__p = (_page); \ + struct pglist_data *pgdat; \ + pgdat = &pg_data_map[page_to_nid(__p)]; \ + ((__p) - pgdat->node_mem_map) + pgdat->node_start_pfn; \ +}) + +#define virt_addr_valid(kaddr) ((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory) +#define pfn_valid(pfn) virt_addr_valid(pfn_to_virt(pfn)) + +#endif /* __ASSEMBLY__ */ + +#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + +#include + +#endif /* _M68K_PAGE_H */ diff --git a/arch/m68k/include/asm/page_no.h b/arch/m68k/include/asm/page_no.h new file mode 100644 index 00000000000..3a1ede4544c --- /dev/null +++ b/arch/m68k/include/asm/page_no.h @@ -0,0 +1,77 @@ +#ifndef _M68KNOMMU_PAGE_H +#define _M68KNOMMU_PAGE_H + +/* PAGE_SHIFT determines the page size */ + +#define PAGE_SHIFT (12) +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +#include + +#ifndef __ASSEMBLY__ + +#define get_user_page(vaddr) __get_free_page(GFP_KERNEL) +#define free_user_page(page, addr) free_page(addr) + +#define clear_page(page) memset((page), 0, PAGE_SIZE) +#define copy_page(to,from) memcpy((to), (from), PAGE_SIZE) + +#define clear_user_page(page, vaddr, pg) clear_page(page) +#define copy_user_page(to, from, vaddr, pg) copy_page(to, from) + +#define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \ + alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr) +#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE + +/* + * These are used to make use of C type-checking.. + */ +typedef struct { unsigned long pte; } pte_t; +typedef struct { unsigned long pmd[16]; } pmd_t; +typedef struct { unsigned long pgd; } pgd_t; +typedef struct { unsigned long pgprot; } pgprot_t; +typedef struct page *pgtable_t; + +#define pte_val(x) ((x).pte) +#define pmd_val(x) ((&x)->pmd[0]) +#define pgd_val(x) ((x).pgd) +#define pgprot_val(x) ((x).pgprot) + +#define __pte(x) ((pte_t) { (x) } ) +#define __pmd(x) ((pmd_t) { (x) } ) +#define __pgd(x) ((pgd_t) { (x) } ) +#define __pgprot(x) ((pgprot_t) { (x) } ) + +extern unsigned long memory_start; +extern unsigned long memory_end; + +#endif /* !__ASSEMBLY__ */ + +#include + +#define PAGE_OFFSET (PAGE_OFFSET_RAW) + +#ifndef __ASSEMBLY__ + +#define __pa(vaddr) virt_to_phys((void *)(vaddr)) +#define __va(paddr) phys_to_virt((unsigned long)(paddr)) + +#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) +#define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT) + +#define virt_to_page(addr) (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)) +#define page_to_virt(page) ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET) + +#define pfn_to_page(pfn) virt_to_page(pfn_to_virt(pfn)) +#define page_to_pfn(page) virt_to_pfn(page_to_virt(page)) +#define pfn_valid(pfn) ((pfn) < max_mapnr) + +#define virt_addr_valid(kaddr) (((void *)(kaddr) >= (void *)PAGE_OFFSET) && \ + ((void *)(kaddr) < (void *)memory_end)) + +#endif /* __ASSEMBLY__ */ + +#include + +#endif /* _M68KNOMMU_PAGE_H */ diff --git a/arch/m68k/include/asm/page_offset.h b/arch/m68k/include/asm/page_offset.h new file mode 100644 index 00000000000..66455c849fb --- /dev/null +++ b/arch/m68k/include/asm/page_offset.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "page_offset_no.h" +#else +#include "page_offset_mm.h" +#endif diff --git a/arch/m68k/include/asm/page_offset_mm.h b/arch/m68k/include/asm/page_offset_mm.h new file mode 100644 index 00000000000..1cbdb7f30ac --- /dev/null +++ b/arch/m68k/include/asm/page_offset_mm.h @@ -0,0 +1,8 @@ + +/* This handles the memory map.. */ +#ifndef CONFIG_SUN3 +#define PAGE_OFFSET_RAW 0x00000000 +#else +#define PAGE_OFFSET_RAW 0x0E000000 +#endif + diff --git a/arch/m68k/include/asm/page_offset_no.h b/arch/m68k/include/asm/page_offset_no.h new file mode 100644 index 00000000000..d4e73e0ba64 --- /dev/null +++ b/arch/m68k/include/asm/page_offset_no.h @@ -0,0 +1,5 @@ + + +/* This handles the memory map.. */ +#define PAGE_OFFSET_RAW CONFIG_RAMBASE + diff --git a/arch/m68k/include/asm/param.h b/arch/m68k/include/asm/param.h new file mode 100644 index 00000000000..40d1112a458 --- /dev/null +++ b/arch/m68k/include/asm/param.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "param_no.h" +#else +#include "param_mm.h" +#endif diff --git a/arch/m68k/include/asm/param_mm.h b/arch/m68k/include/asm/param_mm.h new file mode 100644 index 00000000000..536a2788835 --- /dev/null +++ b/arch/m68k/include/asm/param_mm.h @@ -0,0 +1,22 @@ +#ifndef _M68K_PARAM_H +#define _M68K_PARAM_H + +#ifdef __KERNEL__ +# define HZ CONFIG_HZ /* Internal kernel timer frequency */ +# define USER_HZ 100 /* .. some user interfaces are in "ticks" */ +# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ +#endif + +#ifndef HZ +#define HZ 100 +#endif + +#define EXEC_PAGESIZE 8192 + +#ifndef NOGROUP +#define NOGROUP (-1) +#endif + +#define MAXHOSTNAMELEN 64 /* max length of hostname */ + +#endif /* _M68K_PARAM_H */ diff --git a/arch/m68k/include/asm/param_no.h b/arch/m68k/include/asm/param_no.h new file mode 100644 index 00000000000..6044397adb6 --- /dev/null +++ b/arch/m68k/include/asm/param_no.h @@ -0,0 +1,22 @@ +#ifndef _M68KNOMMU_PARAM_H +#define _M68KNOMMU_PARAM_H + +#ifdef __KERNEL__ +#define HZ CONFIG_HZ +#define USER_HZ HZ +#define CLOCKS_PER_SEC (USER_HZ) +#endif + +#ifndef HZ +#define HZ 100 +#endif + +#define EXEC_PAGESIZE 4096 + +#ifndef NOGROUP +#define NOGROUP (-1) +#endif + +#define MAXHOSTNAMELEN 64 /* max length of hostname */ + +#endif /* _M68KNOMMU_PARAM_H */ diff --git a/arch/m68k/include/asm/parport.h b/arch/m68k/include/asm/parport.h new file mode 100644 index 00000000000..646b1872f73 --- /dev/null +++ b/arch/m68k/include/asm/parport.h @@ -0,0 +1,26 @@ +/* + * parport.h: platform-specific PC-style parport initialisation + * + * Copyright (C) 1999, 2000 Tim Waugh + * + * This file should only be included by drivers/parport/parport_pc.c. + * + * RZ: for use with Q40 and other ISA machines + */ + +#ifndef _ASM_M68K_PARPORT_H +#define _ASM_M68K_PARPORT_H 1 + +#define insl(port,buf,len) isa_insb(port,buf,(len)<<2) +#define outsl(port,buf,len) isa_outsb(port,buf,(len)<<2) + +/* no dma, or IRQ autoprobing */ +static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma); +static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) +{ + if (! (MACH_IS_Q40)) + return 0; /* count=0 */ + return parport_pc_find_isa_ports (PARPORT_IRQ_NONE, PARPORT_DMA_NONE); +} + +#endif /* !(_ASM_M68K_PARPORT_H) */ diff --git a/arch/m68k/include/asm/pci.h b/arch/m68k/include/asm/pci.h new file mode 100644 index 00000000000..dbea9537308 --- /dev/null +++ b/arch/m68k/include/asm/pci.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "pci_no.h" +#else +#include "pci_mm.h" +#endif diff --git a/arch/m68k/include/asm/pci_mm.h b/arch/m68k/include/asm/pci_mm.h new file mode 100644 index 00000000000..4ad0aea48ab --- /dev/null +++ b/arch/m68k/include/asm/pci_mm.h @@ -0,0 +1,12 @@ +#ifndef _ASM_M68K_PCI_H +#define _ASM_M68K_PCI_H + +#include + +/* The PCI address space does equal the physical memory + * address space. The networking and block device layers use + * this boolean for bounce buffer decisions. + */ +#define PCI_DMA_BUS_IS_PHYS (1) + +#endif /* _ASM_M68K_PCI_H */ diff --git a/arch/m68k/include/asm/pci_no.h b/arch/m68k/include/asm/pci_no.h new file mode 100644 index 00000000000..9abbc03c73e --- /dev/null +++ b/arch/m68k/include/asm/pci_no.h @@ -0,0 +1,29 @@ +#ifndef M68KNOMMU_PCI_H +#define M68KNOMMU_PCI_H + +#include + +#ifdef CONFIG_COMEMPCI +/* + * These are pretty much arbitary with the CoMEM implementation. + * We have the whole address space to ourselves. + */ +#define PCIBIOS_MIN_IO 0x100 +#define PCIBIOS_MIN_MEM 0x00010000 + +#define pcibios_scan_all_fns(a, b) 0 + +/* + * Return whether the given PCI device DMA address mask can + * be supported properly. For example, if your device can + * only drive the low 24-bits during PCI bus mastering, then + * you would pass 0x00ffffff as the mask to this function. + */ +static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask) +{ + return 1; +} + +#endif /* CONFIG_COMEMPCI */ + +#endif /* M68KNOMMU_PCI_H */ diff --git a/arch/m68k/include/asm/percpu.h b/arch/m68k/include/asm/percpu.h new file mode 100644 index 00000000000..0859d048faf --- /dev/null +++ b/arch/m68k/include/asm/percpu.h @@ -0,0 +1,6 @@ +#ifndef __ASM_M68K_PERCPU_H +#define __ASM_M68K_PERCPU_H + +#include + +#endif /* __ASM_M68K_PERCPU_H */ diff --git a/arch/m68k/include/asm/pgalloc.h b/arch/m68k/include/asm/pgalloc.h new file mode 100644 index 00000000000..059cb73e78f --- /dev/null +++ b/arch/m68k/include/asm/pgalloc.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "pgalloc_no.h" +#else +#include "pgalloc_mm.h" +#endif diff --git a/arch/m68k/include/asm/pgalloc_mm.h b/arch/m68k/include/asm/pgalloc_mm.h new file mode 100644 index 00000000000..4cb1a57ab76 --- /dev/null +++ b/arch/m68k/include/asm/pgalloc_mm.h @@ -0,0 +1,19 @@ + +#ifndef M68K_PGALLOC_H +#define M68K_PGALLOC_H + +#include +#include +#include +#include + + +#ifdef CONFIG_SUN3 +#include +#else +#include +#endif + +extern void m68k_setup_node(int node); + +#endif /* M68K_PGALLOC_H */ diff --git a/arch/m68k/include/asm/pgalloc_no.h b/arch/m68k/include/asm/pgalloc_no.h new file mode 100644 index 00000000000..d6352f671ec --- /dev/null +++ b/arch/m68k/include/asm/pgalloc_no.h @@ -0,0 +1,8 @@ +#ifndef _M68KNOMMU_PGALLOC_H +#define _M68KNOMMU_PGALLOC_H + +#include + +#define check_pgt_cache() do { } while (0) + +#endif /* _M68KNOMMU_PGALLOC_H */ diff --git a/arch/m68k/include/asm/pgtable.h b/arch/m68k/include/asm/pgtable.h new file mode 100644 index 00000000000..ee6759eb445 --- /dev/null +++ b/arch/m68k/include/asm/pgtable.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "pgtable_no.h" +#else +#include "pgtable_mm.h" +#endif diff --git a/arch/m68k/include/asm/pgtable_mm.h b/arch/m68k/include/asm/pgtable_mm.h new file mode 100644 index 00000000000..0b604f0f192 --- /dev/null +++ b/arch/m68k/include/asm/pgtable_mm.h @@ -0,0 +1,166 @@ +#ifndef _M68K_PGTABLE_H +#define _M68K_PGTABLE_H + +#include + +#include + +#ifndef __ASSEMBLY__ +#include +#include +#include + +/* + * This file contains the functions and defines necessary to modify and use + * the m68k page table tree. + */ + +#include + +/* Certain architectures need to do special things when pte's + * within a page table are directly modified. Thus, the following + * hook is made available. + */ +#define set_pte(pteptr, pteval) \ + do{ \ + *(pteptr) = (pteval); \ + } while(0) +#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) + + +/* PMD_SHIFT determines the size of the area a second-level page table can map */ +#ifdef CONFIG_SUN3 +#define PMD_SHIFT 17 +#else +#define PMD_SHIFT 22 +#endif +#define PMD_SIZE (1UL << PMD_SHIFT) +#define PMD_MASK (~(PMD_SIZE-1)) + +/* PGDIR_SHIFT determines what a third-level page table entry can map */ +#ifdef CONFIG_SUN3 +#define PGDIR_SHIFT 17 +#else +#define PGDIR_SHIFT 25 +#endif +#define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define PGDIR_MASK (~(PGDIR_SIZE-1)) + +/* + * entries per page directory level: the m68k is configured as three-level, + * so we do have PMD level physically. + */ +#ifdef CONFIG_SUN3 +#define PTRS_PER_PTE 16 +#define PTRS_PER_PMD 1 +#define PTRS_PER_PGD 2048 +#else +#define PTRS_PER_PTE 1024 +#define PTRS_PER_PMD 8 +#define PTRS_PER_PGD 128 +#endif +#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) +#define FIRST_USER_ADDRESS 0 + +/* Virtual address region for use by kernel_map() */ +#ifdef CONFIG_SUN3 +#define KMAP_START 0x0DC00000 +#define KMAP_END 0x0E000000 +#else +#define KMAP_START 0xd0000000 +#define KMAP_END 0xf0000000 +#endif + +#ifndef CONFIG_SUN3 +/* Just any arbitrary offset to the start of the vmalloc VM area: the + * current 8MB value just means that there will be a 8MB "hole" after the + * physical memory until the kernel virtual memory starts. That means that + * any out-of-bounds memory accesses will hopefully be caught. + * The vmalloc() routines leaves a hole of 4kB between each vmalloced + * area for the same reason. ;) + */ +#define VMALLOC_OFFSET (8*1024*1024) +#define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) +#define VMALLOC_END KMAP_START +#else +extern unsigned long vmalloc_end; +#define VMALLOC_START 0x0f800000 +#define VMALLOC_END vmalloc_end +#endif /* CONFIG_SUN3 */ + +/* zero page used for uninitialized stuff */ +extern void *empty_zero_page; + +/* + * ZERO_PAGE is a global shared page that is always zero: used + * for zero-mapped memory areas etc.. + */ +#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) + +/* number of bits that fit into a memory pointer */ +#define BITS_PER_PTR (8*sizeof(unsigned long)) + +/* to align the pointer to a pointer address */ +#define PTR_MASK (~(sizeof(void*)-1)) + +/* sizeof(void*)==1< +#else +#include +#endif + +#ifndef __ASSEMBLY__ +#include + +/* + * Macro to mark a page protection value as "uncacheable". + */ +#ifdef SUN3_PAGE_NOCACHE +# define __SUN3_PAGE_NOCACHE SUN3_PAGE_NOCACHE +#else +# define __SUN3_PAGE_NOCACHE 0 +#endif +#define pgprot_noncached(prot) \ + (MMU_IS_SUN3 \ + ? (__pgprot(pgprot_val(prot) | __SUN3_PAGE_NOCACHE)) \ + : ((MMU_IS_851 || MMU_IS_030) \ + ? (__pgprot(pgprot_val(prot) | _PAGE_NOCACHE030)) \ + : (MMU_IS_040 || MMU_IS_060) \ + ? (__pgprot((pgprot_val(prot) & _CACHEMASK040) | _PAGE_NOCACHE_S)) \ + : (prot))) + +#endif /* !__ASSEMBLY__ */ + +/* + * No page table caches to initialise + */ +#define pgtable_cache_init() do { } while (0) + +#define check_pgt_cache() do { } while (0) + +#endif /* _M68K_PGTABLE_H */ diff --git a/arch/m68k/include/asm/pgtable_no.h b/arch/m68k/include/asm/pgtable_no.h new file mode 100644 index 00000000000..46251016e82 --- /dev/null +++ b/arch/m68k/include/asm/pgtable_no.h @@ -0,0 +1,70 @@ +#ifndef _M68KNOMMU_PGTABLE_H +#define _M68KNOMMU_PGTABLE_H + +#include + +/* + * (C) Copyright 2000-2002, Greg Ungerer + */ + +#include +#include +#include +#include + +/* + * Trivial page table functions. + */ +#define pgd_present(pgd) (1) +#define pgd_none(pgd) (0) +#define pgd_bad(pgd) (0) +#define pgd_clear(pgdp) +#define kern_addr_valid(addr) (1) +#define pmd_offset(a, b) ((void *)0) + +#define PAGE_NONE __pgprot(0) +#define PAGE_SHARED __pgprot(0) +#define PAGE_COPY __pgprot(0) +#define PAGE_READONLY __pgprot(0) +#define PAGE_KERNEL __pgprot(0) + +extern void paging_init(void); +#define swapper_pg_dir ((pgd_t *) 0) + +#define __swp_type(x) (0) +#define __swp_offset(x) (0) +#define __swp_entry(typ,off) ((swp_entry_t) { ((typ) | ((off) << 7)) }) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) + +static inline int pte_file(pte_t pte) { return 0; } + +/* + * ZERO_PAGE is a global shared page that is always zero: used + * for zero-mapped memory areas etc.. + */ +#define ZERO_PAGE(vaddr) (virt_to_page(0)) + +/* + * These would be in other places but having them here reduces the diffs. + */ +extern unsigned int kobjsize(const void *objp); + +/* + * No page table caches to initialise. + */ +#define pgtable_cache_init() do { } while (0) + +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ + remap_pfn_range(vma, vaddr, pfn, size, prot) + +/* + * All 32bit addresses are effectively valid for vmalloc... + * Sort of meaningless for non-VM targets. + */ +#define VMALLOC_START 0 +#define VMALLOC_END 0xffffffff + +#include + +#endif /* _M68KNOMMU_PGTABLE_H */ diff --git a/arch/m68k/include/asm/poll.h b/arch/m68k/include/asm/poll.h new file mode 100644 index 00000000000..f080fcdb61b --- /dev/null +++ b/arch/m68k/include/asm/poll.h @@ -0,0 +1,9 @@ +#ifndef __m68k_POLL_H +#define __m68k_POLL_H + +#define POLLWRNORM POLLOUT +#define POLLWRBAND 256 + +#include + +#endif diff --git a/arch/m68k/include/asm/posix_types.h b/arch/m68k/include/asm/posix_types.h new file mode 100644 index 00000000000..63cdcc142d9 --- /dev/null +++ b/arch/m68k/include/asm/posix_types.h @@ -0,0 +1,61 @@ +#ifndef __ARCH_M68K_POSIX_TYPES_H +#define __ARCH_M68K_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_timer_t; +typedef int __kernel_clockid_t; +typedef int __kernel_daddr_t; +typedef char * __kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; + +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; +typedef unsigned short __kernel_old_dev_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { + int val[2]; +} __kernel_fsid_t; + +#if defined(__KERNEL__) + +#undef __FD_SET +#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) + +#undef __FD_CLR +#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) + +#undef __FD_ISSET +#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) + +#undef __FD_ZERO +#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp))) + +#endif /* defined(__KERNEL__) */ + +#endif diff --git a/arch/m68k/include/asm/processor.h b/arch/m68k/include/asm/processor.h new file mode 100644 index 00000000000..fc3f2c22f2b --- /dev/null +++ b/arch/m68k/include/asm/processor.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "processor_no.h" +#else +#include "processor_mm.h" +#endif diff --git a/arch/m68k/include/asm/processor_mm.h b/arch/m68k/include/asm/processor_mm.h new file mode 100644 index 00000000000..1f61ef53f0e --- /dev/null +++ b/arch/m68k/include/asm/processor_mm.h @@ -0,0 +1,130 @@ +/* + * include/asm-m68k/processor.h + * + * Copyright (C) 1995 Hamish Macdonald + */ + +#ifndef __ASM_M68K_PROCESSOR_H +#define __ASM_M68K_PROCESSOR_H + +/* + * Default implementation of macro that returns current + * instruction pointer ("program counter"). + */ +#define current_text_addr() ({ __label__ _l; _l: &&_l;}) + +#include +#include +#include +#include + +static inline unsigned long rdusp(void) +{ + unsigned long usp; + + __asm__ __volatile__("move %/usp,%0" : "=a" (usp)); + return usp; +} + +static inline void wrusp(unsigned long usp) +{ + __asm__ __volatile__("move %0,%/usp" : : "a" (usp)); +} + +/* + * User space process size: 3.75GB. This is hardcoded into a few places, + * so don't change it unless you know what you are doing. + */ +#ifndef CONFIG_SUN3 +#define TASK_SIZE (0xF0000000UL) +#else +#define TASK_SIZE (0x0E000000UL) +#endif + +#ifdef __KERNEL__ +#define STACK_TOP TASK_SIZE +#define STACK_TOP_MAX STACK_TOP +#endif + +/* This decides where the kernel will search for a free chunk of vm + * space during mmap's. + */ +#ifndef CONFIG_SUN3 +#define TASK_UNMAPPED_BASE 0xC0000000UL +#else +#define TASK_UNMAPPED_BASE 0x0A000000UL +#endif +#define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr) + +struct thread_struct { + unsigned long ksp; /* kernel stack pointer */ + unsigned long usp; /* user stack pointer */ + unsigned short sr; /* saved status register */ + unsigned short fs; /* saved fs (sfc, dfc) */ + unsigned long crp[2]; /* cpu root pointer */ + unsigned long esp0; /* points to SR of stack frame */ + unsigned long faddr; /* info about last fault */ + int signo, code; + unsigned long fp[8*3]; + unsigned long fpcntl[3]; /* fp control regs */ + unsigned char fpstate[FPSTATESIZE]; /* floating point state */ + struct thread_info info; +}; + +#define INIT_THREAD { \ + .ksp = sizeof(init_stack) + (unsigned long) init_stack, \ + .sr = PS_S, \ + .fs = __KERNEL_DS, \ + .info = INIT_THREAD_INFO(init_task), \ +} + +/* + * Do necessary setup to start up a newly executed thread. + */ +static inline void start_thread(struct pt_regs * regs, unsigned long pc, + unsigned long usp) +{ + /* reads from user space */ + set_fs(USER_DS); + + regs->pc = pc; + regs->sr &= ~0x2000; + wrusp(usp); +} + +/* Forward declaration, a strange C thing */ +struct task_struct; + +/* Free all resources held by a thread. */ +static inline void release_thread(struct task_struct *dead_task) +{ +} + +/* Prepare to copy thread state - unlazy all lazy status */ +#define prepare_to_copy(tsk) do { } while (0) + +extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); + +/* + * Free current thread data structures etc.. + */ +static inline void exit_thread(void) +{ +} + +extern unsigned long thread_saved_pc(struct task_struct *tsk); + +unsigned long get_wchan(struct task_struct *p); + +#define KSTK_EIP(tsk) \ + ({ \ + unsigned long eip = 0; \ + if ((tsk)->thread.esp0 > PAGE_SIZE && \ + (virt_addr_valid((tsk)->thread.esp0))) \ + eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \ + eip; }) +#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) + +#define cpu_relax() barrier() + +#endif diff --git a/arch/m68k/include/asm/processor_no.h b/arch/m68k/include/asm/processor_no.h new file mode 100644 index 00000000000..91cba18acdd --- /dev/null +++ b/arch/m68k/include/asm/processor_no.h @@ -0,0 +1,143 @@ +/* + * include/asm-m68knommu/processor.h + * + * Copyright (C) 1995 Hamish Macdonald + */ + +#ifndef __ASM_M68K_PROCESSOR_H +#define __ASM_M68K_PROCESSOR_H + +/* + * Default implementation of macro that returns current + * instruction pointer ("program counter"). + */ +#define current_text_addr() ({ __label__ _l; _l: &&_l;}) + +#include +#include +#include +#include +#include +#include +#include + +static inline unsigned long rdusp(void) +{ +#ifdef CONFIG_COLDFIRE + extern unsigned int sw_usp; + return(sw_usp); +#else + unsigned long usp; + __asm__ __volatile__("move %/usp,%0" : "=a" (usp)); + return usp; +#endif +} + +static inline void wrusp(unsigned long usp) +{ +#ifdef CONFIG_COLDFIRE + extern unsigned int sw_usp; + sw_usp = usp; +#else + __asm__ __volatile__("move %0,%/usp" : : "a" (usp)); +#endif +} + +/* + * User space process size: 3.75GB. This is hardcoded into a few places, + * so don't change it unless you know what you are doing. + */ +#define TASK_SIZE (0xF0000000UL) + +/* + * This decides where the kernel will search for a free chunk of vm + * space during mmap's. We won't be using it + */ +#define TASK_UNMAPPED_BASE 0 + +/* + * if you change this structure, you must change the code and offsets + * in m68k/machasm.S + */ + +struct thread_struct { + unsigned long ksp; /* kernel stack pointer */ + unsigned long usp; /* user stack pointer */ + unsigned short sr; /* saved status register */ + unsigned short fs; /* saved fs (sfc, dfc) */ + unsigned long crp[2]; /* cpu root pointer */ + unsigned long esp0; /* points to SR of stack frame */ + unsigned long fp[8*3]; + unsigned long fpcntl[3]; /* fp control regs */ + unsigned char fpstate[FPSTATESIZE]; /* floating point state */ +}; + +#define INIT_THREAD { \ + sizeof(init_stack) + (unsigned long) init_stack, 0, \ + PS_S, __KERNEL_DS, \ + {0, 0}, 0, {0,}, {0, 0, 0}, {0,}, \ +} + +/* + * Coldfire stacks need to be re-aligned on trap exit, conventional + * 68k can handle this case cleanly. + */ +#if defined(CONFIG_COLDFIRE) +#define reformat(_regs) do { (_regs)->format = 0x4; } while(0) +#else +#define reformat(_regs) do { } while (0) +#endif + +/* + * Do necessary setup to start up a newly executed thread. + * + * pass the data segment into user programs if it exists, + * it can't hurt anything as far as I can tell + */ +#define start_thread(_regs, _pc, _usp) \ +do { \ + set_fs(USER_DS); /* reads from user space */ \ + (_regs)->pc = (_pc); \ + ((struct switch_stack *)(_regs))[-1].a6 = 0; \ + reformat(_regs); \ + if (current->mm) \ + (_regs)->d5 = current->mm->start_data; \ + (_regs)->sr &= ~0x2000; \ + wrusp(_usp); \ +} while(0) + +/* Forward declaration, a strange C thing */ +struct task_struct; + +/* Free all resources held by a thread. */ +static inline void release_thread(struct task_struct *dead_task) +{ +} + +/* Prepare to copy thread state - unlazy all lazy status */ +#define prepare_to_copy(tsk) do { } while (0) + +extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); + +/* + * Free current thread data structures etc.. + */ +static inline void exit_thread(void) +{ +} + +unsigned long thread_saved_pc(struct task_struct *tsk); +unsigned long get_wchan(struct task_struct *p); + +#define KSTK_EIP(tsk) \ + ({ \ + unsigned long eip = 0; \ + if ((tsk)->thread.esp0 > PAGE_SIZE && \ + (virt_addr_valid((tsk)->thread.esp0))) \ + eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \ + eip; }) +#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) + +#define cpu_relax() barrier() + +#endif diff --git a/arch/m68k/include/asm/ptrace.h b/arch/m68k/include/asm/ptrace.h new file mode 100644 index 00000000000..e83cd2f6610 --- /dev/null +++ b/arch/m68k/include/asm/ptrace.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "ptrace_no.h" +#else +#include "ptrace_mm.h" +#endif diff --git a/arch/m68k/include/asm/ptrace_mm.h b/arch/m68k/include/asm/ptrace_mm.h new file mode 100644 index 00000000000..57e763d79bf --- /dev/null +++ b/arch/m68k/include/asm/ptrace_mm.h @@ -0,0 +1,80 @@ +#ifndef _M68K_PTRACE_H +#define _M68K_PTRACE_H + +#define PT_D1 0 +#define PT_D2 1 +#define PT_D3 2 +#define PT_D4 3 +#define PT_D5 4 +#define PT_D6 5 +#define PT_D7 6 +#define PT_A0 7 +#define PT_A1 8 +#define PT_A2 9 +#define PT_A3 10 +#define PT_A4 11 +#define PT_A5 12 +#define PT_A6 13 +#define PT_D0 14 +#define PT_USP 15 +#define PT_ORIG_D0 16 +#define PT_SR 17 +#define PT_PC 18 + +#ifndef __ASSEMBLY__ + +/* this struct defines the way the registers are stored on the + stack during a system call. */ + +struct pt_regs { + long d1; + long d2; + long d3; + long d4; + long d5; + long a0; + long a1; + long a2; + long d0; + long orig_d0; + long stkadj; + unsigned short sr; + unsigned long pc; + unsigned format : 4; /* frame format specifier */ + unsigned vector : 12; /* vector offset */ +}; + +/* + * This is the extended stack used by signal handlers and the context + * switcher: it's pushed after the normal "struct pt_regs". + */ +struct switch_stack { + unsigned long d6; + unsigned long d7; + unsigned long a3; + unsigned long a4; + unsigned long a5; + unsigned long a6; + unsigned long retpc; +}; + +/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ +#define PTRACE_GETREGS 12 +#define PTRACE_SETREGS 13 +#define PTRACE_GETFPREGS 14 +#define PTRACE_SETFPREGS 15 + +#ifdef __KERNEL__ + +#ifndef PS_S +#define PS_S (0x2000) +#define PS_M (0x1000) +#endif + +#define user_mode(regs) (!((regs)->sr & PS_S)) +#define instruction_pointer(regs) ((regs)->pc) +#define profile_pc(regs) instruction_pointer(regs) +extern void show_regs(struct pt_regs *); +#endif /* __KERNEL__ */ +#endif /* __ASSEMBLY__ */ +#endif /* _M68K_PTRACE_H */ diff --git a/arch/m68k/include/asm/ptrace_no.h b/arch/m68k/include/asm/ptrace_no.h new file mode 100644 index 00000000000..8c9194b9854 --- /dev/null +++ b/arch/m68k/include/asm/ptrace_no.h @@ -0,0 +1,87 @@ +#ifndef _M68K_PTRACE_H +#define _M68K_PTRACE_H + +#define PT_D1 0 +#define PT_D2 1 +#define PT_D3 2 +#define PT_D4 3 +#define PT_D5 4 +#define PT_D6 5 +#define PT_D7 6 +#define PT_A0 7 +#define PT_A1 8 +#define PT_A2 9 +#define PT_A3 10 +#define PT_A4 11 +#define PT_A5 12 +#define PT_A6 13 +#define PT_D0 14 +#define PT_USP 15 +#define PT_ORIG_D0 16 +#define PT_SR 17 +#define PT_PC 18 + +#ifndef __ASSEMBLY__ + +/* this struct defines the way the registers are stored on the + stack during a system call. */ + +struct pt_regs { + long d1; + long d2; + long d3; + long d4; + long d5; + long a0; + long a1; + long a2; + long d0; + long orig_d0; + long stkadj; +#ifdef CONFIG_COLDFIRE + unsigned format : 4; /* frame format specifier */ + unsigned vector : 12; /* vector offset */ + unsigned short sr; + unsigned long pc; +#else + unsigned short sr; + unsigned long pc; + unsigned format : 4; /* frame format specifier */ + unsigned vector : 12; /* vector offset */ +#endif +}; + +/* + * This is the extended stack used by signal handlers and the context + * switcher: it's pushed after the normal "struct pt_regs". + */ +struct switch_stack { + unsigned long d6; + unsigned long d7; + unsigned long a3; + unsigned long a4; + unsigned long a5; + unsigned long a6; + unsigned long retpc; +}; + +/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ +#define PTRACE_GETREGS 12 +#define PTRACE_SETREGS 13 +#define PTRACE_GETFPREGS 14 +#define PTRACE_SETFPREGS 15 + +#ifdef __KERNEL__ + +#ifndef PS_S +#define PS_S (0x2000) +#define PS_M (0x1000) +#endif + +#define user_mode(regs) (!((regs)->sr & PS_S)) +#define instruction_pointer(regs) ((regs)->pc) +#define profile_pc(regs) instruction_pointer(regs) +extern void show_regs(struct pt_regs *); +#endif /* __KERNEL__ */ +#endif /* __ASSEMBLY__ */ +#endif /* _M68K_PTRACE_H */ diff --git a/arch/m68k/include/asm/q40_master.h b/arch/m68k/include/asm/q40_master.h new file mode 100644 index 00000000000..3907a09d4fc --- /dev/null +++ b/arch/m68k/include/asm/q40_master.h @@ -0,0 +1,69 @@ +/* + * Q40 master Chip Control + * RTC stuff merged for compactnes.. +*/ + +#ifndef _Q40_MASTER_H +#define _Q40_MASTER_H + +#include + + +#define q40_master_addr 0xff000000 + +#define IIRQ_REG 0x0 /* internal IRQ reg */ +#define EIRQ_REG 0x4 /* external ... */ +#define KEYCODE_REG 0x1c /* value of received scancode */ +#define DISPLAY_CONTROL_REG 0x18 +#define FRAME_CLEAR_REG 0x24 +#define LED_REG 0x30 + +#define Q40_LED_ON() master_outb(1,LED_REG) +#define Q40_LED_OFF() master_outb(0,LED_REG) + +#define INTERRUPT_REG IIRQ_REG /* "native" ints */ +#define KEY_IRQ_ENABLE_REG 0x08 /**/ +#define KEYBOARD_UNLOCK_REG 0x20 /* clear kb int */ + +#define SAMPLE_ENABLE_REG 0x14 /* generate SAMPLE ints */ +#define SAMPLE_RATE_REG 0x2c +#define SAMPLE_CLEAR_REG 0x28 +#define SAMPLE_LOW 0x00 +#define SAMPLE_HIGH 0x01 + +#define FRAME_RATE_REG 0x38 /* generate FRAME ints at 200 HZ rate */ + +#if 0 +#define SER_ENABLE_REG 0x0c /* allow serial ints to be generated */ +#endif +#define EXT_ENABLE_REG 0x10 /* ... rest of the ISA ints ... */ + + +#define master_inb(_reg_) in_8((unsigned char *)q40_master_addr+_reg_) +#define master_outb(_b_,_reg_) out_8((unsigned char *)q40_master_addr+_reg_,_b_) + +/* RTC defines */ + +#define Q40_RTC_BASE (0xff021ffc) + +#define Q40_RTC_YEAR (*(volatile unsigned char *)(Q40_RTC_BASE+0)) +#define Q40_RTC_MNTH (*(volatile unsigned char *)(Q40_RTC_BASE-4)) +#define Q40_RTC_DATE (*(volatile unsigned char *)(Q40_RTC_BASE-8)) +#define Q40_RTC_DOW (*(volatile unsigned char *)(Q40_RTC_BASE-12)) +#define Q40_RTC_HOUR (*(volatile unsigned char *)(Q40_RTC_BASE-16)) +#define Q40_RTC_MINS (*(volatile unsigned char *)(Q40_RTC_BASE-20)) +#define Q40_RTC_SECS (*(volatile unsigned char *)(Q40_RTC_BASE-24)) +#define Q40_RTC_CTRL (*(volatile unsigned char *)(Q40_RTC_BASE-28)) + +/* some control bits */ +#define Q40_RTC_READ 64 /* prepare for reading */ +#define Q40_RTC_WRITE 128 + +/* define some Q40 specific ints */ +#include "q40ints.h" + +/* misc defs */ +#define DAC_LEFT ((unsigned char *)0xff008000) +#define DAC_RIGHT ((unsigned char *)0xff008004) + +#endif /* _Q40_MASTER_H */ diff --git a/arch/m68k/include/asm/q40ints.h b/arch/m68k/include/asm/q40ints.h new file mode 100644 index 00000000000..3d970afb708 --- /dev/null +++ b/arch/m68k/include/asm/q40ints.h @@ -0,0 +1,29 @@ +/* + * contains some Q40 related interrupt definitions + */ + +#define Q40_IRQ_MAX (34) + +#define Q40_IRQ_SAMPLE (34) +#define Q40_IRQ_KEYBOARD (32) +#define Q40_IRQ_FRAME (33) + + +/* masks for interrupt regiosters*/ +/* internal, IIRQ_REG */ +#define Q40_IRQ_KEYB_MASK (2) +#define Q40_IRQ_SER_MASK (1<<2) +#define Q40_IRQ_FRAME_MASK (1<<3) +#define Q40_IRQ_EXT_MASK (1<<4) /* is a EIRQ */ +/* eirq, EIRQ_REG */ +#define Q40_IRQ3_MASK (1) +#define Q40_IRQ4_MASK (1<<1) +#define Q40_IRQ5_MASK (1<<2) +#define Q40_IRQ6_MASK (1<<3) +#define Q40_IRQ7_MASK (1<<4) +#define Q40_IRQ10_MASK (1<<5) +#define Q40_IRQ14_MASK (1<<6) +#define Q40_IRQ15_MASK (1<<7) + +extern unsigned long q40_probe_irq_on (void); +extern int q40_probe_irq_off (unsigned long irqs); diff --git a/arch/m68k/include/asm/quicc_simple.h b/arch/m68k/include/asm/quicc_simple.h new file mode 100644 index 00000000000..c3636932d4b --- /dev/null +++ b/arch/m68k/include/asm/quicc_simple.h @@ -0,0 +1,52 @@ +/*********************************** + * $Id: quicc_simple.h,v 1.1 2002/03/02 15:01:10 gerg Exp $ + *********************************** + * + *************************************** + * Simple drivers common header + *************************************** + */ + +#ifndef __SIMPLE_H +#define __SIMPLE_H + +/* #include "quicc.h" */ + +#define GLB_SCC_0 0 +#define GLB_SCC_1 1 +#define GLB_SCC_2 2 +#define GLB_SCC_3 3 + +typedef void (int_routine)(unsigned short interrupt_event); +typedef int_routine *int_routine_ptr; +typedef void *(alloc_routine)(int length); +typedef void (free_routine)(int scc_num, int channel_num, void *buf); +typedef void (store_rx_buffer_routine)(int scc_num, int channel_num, void *buff, int length); +typedef int (handle_tx_error_routine)(int scc_num, int channel_num, QUICC_BD *tbd); +typedef void (handle_rx_error_routine)(int scc_num, int channel_num, QUICC_BD *rbd); +typedef void (handle_lost_error_routine)(int scc_num, int channel_num); + +/* user defined functions for global errors */ +typedef void (handle_glob_overrun_routine)(int scc_number); +typedef void (handle_glob_underrun_routine)(int scc_number); +typedef void (glob_intr_q_overflow_routine)(int scc_number); + +/* + * General initialization and command routines + */ +void quicc_issue_cmd (unsigned short cmd, int scc_num); +void quicc_init(void); +void quicc_scc_init(int scc_number, int number_of_rx_buf, int number_of_tx_buf); +void quicc_smc_init(int smc_number, int number_of_rx_buf, int number_of_tx_buf); +void quicc_scc_start(int scc_num); +void quicc_scc_loopback(int scc_num); + +/* Interrupt enable/disable routines for critical pieces of code*/ +unsigned short IntrDis(void); +void IntrEna(unsigned short old_sr); + +/* For debugging */ +void print_rbd(int scc_num); +void print_tbd(int scc_num); + +#endif diff --git a/arch/m68k/include/asm/raw_io.h b/arch/m68k/include/asm/raw_io.h new file mode 100644 index 00000000000..d9eb9834ccc --- /dev/null +++ b/arch/m68k/include/asm/raw_io.h @@ -0,0 +1,347 @@ +/* + * linux/include/asm-m68k/raw_io.h + * + * 10/20/00 RZ: - created from bits of io.h and ide.h to cleanup namespace + * + */ + +#ifndef _RAW_IO_H +#define _RAW_IO_H + +#ifdef __KERNEL__ + +#include + + +/* Values for nocacheflag and cmode */ +#define IOMAP_FULL_CACHING 0 +#define IOMAP_NOCACHE_SER 1 +#define IOMAP_NOCACHE_NONSER 2 +#define IOMAP_WRITETHROUGH 3 + +extern void iounmap(void __iomem *addr); + +extern void __iomem *__ioremap(unsigned long physaddr, unsigned long size, + int cacheflag); +extern void __iounmap(void *addr, unsigned long size); + + +/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates + * two accesses to memory, which may be undesirable for some devices. + */ +#define in_8(addr) \ + ({ u8 __v = (*(__force volatile u8 *) (addr)); __v; }) +#define in_be16(addr) \ + ({ u16 __v = (*(__force volatile u16 *) (addr)); __v; }) +#define in_be32(addr) \ + ({ u32 __v = (*(__force volatile u32 *) (addr)); __v; }) +#define in_le16(addr) \ + ({ u16 __v = le16_to_cpu(*(__force volatile __le16 *) (addr)); __v; }) +#define in_le32(addr) \ + ({ u32 __v = le32_to_cpu(*(__force volatile __le32 *) (addr)); __v; }) + +#define out_8(addr,b) (void)((*(__force volatile u8 *) (addr)) = (b)) +#define out_be16(addr,w) (void)((*(__force volatile u16 *) (addr)) = (w)) +#define out_be32(addr,l) (void)((*(__force volatile u32 *) (addr)) = (l)) +#define out_le16(addr,w) (void)((*(__force volatile __le16 *) (addr)) = cpu_to_le16(w)) +#define out_le32(addr,l) (void)((*(__force volatile __le32 *) (addr)) = cpu_to_le32(l)) + +#define raw_inb in_8 +#define raw_inw in_be16 +#define raw_inl in_be32 +#define __raw_readb in_8 +#define __raw_readw in_be16 +#define __raw_readl in_be32 + +#define raw_outb(val,port) out_8((port),(val)) +#define raw_outw(val,port) out_be16((port),(val)) +#define raw_outl(val,port) out_be32((port),(val)) +#define __raw_writeb(val,addr) out_8((addr),(val)) +#define __raw_writew(val,addr) out_be16((addr),(val)) +#define __raw_writel(val,addr) out_be32((addr),(val)) + +static inline void raw_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len) +{ + unsigned int i; + + for (i = 0; i < len; i++) + *buf++ = in_8(port); +} + +static inline void raw_outsb(volatile u8 __iomem *port, const u8 *buf, + unsigned int len) +{ + unsigned int i; + + for (i = 0; i < len; i++) + out_8(port, *buf++); +} + +static inline void raw_insw(volatile u16 __iomem *port, u16 *buf, unsigned int nr) +{ + unsigned int tmp; + + if (nr & 15) { + tmp = (nr & 15) - 1; + asm volatile ( + "1: movew %2@,%0@+; dbra %1,1b" + : "=a" (buf), "=d" (tmp) + : "a" (port), "0" (buf), + "1" (tmp)); + } + if (nr >> 4) { + tmp = (nr >> 4) - 1; + asm volatile ( + "1: " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "movew %2@,%0@+; " + "dbra %1,1b" + : "=a" (buf), "=d" (tmp) + : "a" (port), "0" (buf), + "1" (tmp)); + } +} + +static inline void raw_outsw(volatile u16 __iomem *port, const u16 *buf, + unsigned int nr) +{ + unsigned int tmp; + + if (nr & 15) { + tmp = (nr & 15) - 1; + asm volatile ( + "1: movew %0@+,%2@; dbra %1,1b" + : "=a" (buf), "=d" (tmp) + : "a" (port), "0" (buf), + "1" (tmp)); + } + if (nr >> 4) { + tmp = (nr >> 4) - 1; + asm volatile ( + "1: " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "movew %0@+,%2@; " + "dbra %1,1b" + : "=a" (buf), "=d" (tmp) + : "a" (port), "0" (buf), + "1" (tmp)); + } +} + +static inline void raw_insl(volatile u32 __iomem *port, u32 *buf, unsigned int nr) +{ + unsigned int tmp; + + if (nr & 15) { + tmp = (nr & 15) - 1; + asm volatile ( + "1: movel %2@,%0@+; dbra %1,1b" + : "=a" (buf), "=d" (tmp) + : "a" (port), "0" (buf), + "1" (tmp)); + } + if (nr >> 4) { + tmp = (nr >> 4) - 1; + asm volatile ( + "1: " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "movel %2@,%0@+; " + "dbra %1,1b" + : "=a" (buf), "=d" (tmp) + : "a" (port), "0" (buf), + "1" (tmp)); + } +} + +static inline void raw_outsl(volatile u32 __iomem *port, const u32 *buf, + unsigned int nr) +{ + unsigned int tmp; + + if (nr & 15) { + tmp = (nr & 15) - 1; + asm volatile ( + "1: movel %0@+,%2@; dbra %1,1b" + : "=a" (buf), "=d" (tmp) + : "a" (port), "0" (buf), + "1" (tmp)); + } + if (nr >> 4) { + tmp = (nr >> 4) - 1; + asm volatile ( + "1: " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "movel %0@+,%2@; " + "dbra %1,1b" + : "=a" (buf), "=d" (tmp) + : "a" (port), "0" (buf), + "1" (tmp)); + } +} + + +static inline void raw_insw_swapw(volatile u16 __iomem *port, u16 *buf, + unsigned int nr) +{ + if ((nr) % 8) + __asm__ __volatile__ + ("\tmovel %0,%/a0\n\t" + "movel %1,%/a1\n\t" + "movel %2,%/d6\n\t" + "subql #1,%/d6\n" + "1:\tmovew %/a0@,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a1@+\n\t" + "dbra %/d6,1b" + : + : "g" (port), "g" (buf), "g" (nr) + : "d0", "a0", "a1", "d6"); + else + __asm__ __volatile__ + ("movel %0,%/a0\n\t" + "movel %1,%/a1\n\t" + "movel %2,%/d6\n\t" + "lsrl #3,%/d6\n\t" + "subql #1,%/d6\n" + "1:\tmovew %/a0@,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a1@+\n\t" + "movew %/a0@,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a1@+\n\t" + "movew %/a0@,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a1@+\n\t" + "movew %/a0@,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a1@+\n\t" + "movew %/a0@,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a1@+\n\t" + "movew %/a0@,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a1@+\n\t" + "movew %/a0@,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a1@+\n\t" + "movew %/a0@,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a1@+\n\t" + "dbra %/d6,1b" + : + : "g" (port), "g" (buf), "g" (nr) + : "d0", "a0", "a1", "d6"); +} + +static inline void raw_outsw_swapw(volatile u16 __iomem *port, const u16 *buf, + unsigned int nr) +{ + if ((nr) % 8) + __asm__ __volatile__ + ("movel %0,%/a0\n\t" + "movel %1,%/a1\n\t" + "movel %2,%/d6\n\t" + "subql #1,%/d6\n" + "1:\tmovew %/a1@+,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a0@\n\t" + "dbra %/d6,1b" + : + : "g" (port), "g" (buf), "g" (nr) + : "d0", "a0", "a1", "d6"); + else + __asm__ __volatile__ + ("movel %0,%/a0\n\t" + "movel %1,%/a1\n\t" + "movel %2,%/d6\n\t" + "lsrl #3,%/d6\n\t" + "subql #1,%/d6\n" + "1:\tmovew %/a1@+,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a0@\n\t" + "movew %/a1@+,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a0@\n\t" + "movew %/a1@+,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a0@\n\t" + "movew %/a1@+,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a0@\n\t" + "movew %/a1@+,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a0@\n\t" + "movew %/a1@+,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a0@\n\t" + "movew %/a1@+,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a0@\n\t" + "movew %/a1@+,%/d0\n\t" + "rolw #8,%/d0\n\t" + "movew %/d0,%/a0@\n\t" + "dbra %/d6,1b" + : + : "g" (port), "g" (buf), "g" (nr) + : "d0", "a0", "a1", "d6"); +} + +#endif /* __KERNEL__ */ + +#endif /* _RAW_IO_H */ diff --git a/arch/m68k/include/asm/resource.h b/arch/m68k/include/asm/resource.h new file mode 100644 index 00000000000..e7d35019f33 --- /dev/null +++ b/arch/m68k/include/asm/resource.h @@ -0,0 +1,6 @@ +#ifndef _M68K_RESOURCE_H +#define _M68K_RESOURCE_H + +#include + +#endif /* _M68K_RESOURCE_H */ diff --git a/arch/m68k/include/asm/rtc.h b/arch/m68k/include/asm/rtc.h new file mode 100644 index 00000000000..5d3e0385984 --- /dev/null +++ b/arch/m68k/include/asm/rtc.h @@ -0,0 +1,76 @@ +/* include/asm-m68k/rtc.h + * + * Copyright Richard Zidlicky + * implementation details for genrtc/q40rtc driver + */ +/* permission is hereby granted to copy, modify and redistribute this code + * in terms of the GNU Library General Public License, Version 2 or later, + * at your option. + */ + +#ifndef _ASM_RTC_H +#define _ASM_RTC_H + +#ifdef __KERNEL__ + +#include +#include +#include + +#define RTC_PIE 0x40 /* periodic interrupt enable */ +#define RTC_AIE 0x20 /* alarm interrupt enable */ +#define RTC_UIE 0x10 /* update-finished interrupt enable */ + +/* some dummy definitions */ +#define RTC_BATT_BAD 0x100 /* battery bad */ +#define RTC_SQWE 0x08 /* enable square-wave output */ +#define RTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */ +#define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */ +#define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */ + +static inline unsigned int get_rtc_time(struct rtc_time *time) +{ + /* + * Only the values that we read from the RTC are set. We leave + * tm_wday, tm_yday and tm_isdst untouched. Even though the + * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated + * by the RTC when initially set to a non-zero value. + */ + mach_hwclk(0, time); + return RTC_24H; +} + +static inline int set_rtc_time(struct rtc_time *time) +{ + return mach_hwclk(1, time); +} + +static inline unsigned int get_rtc_ss(void) +{ + if (mach_get_ss) + return mach_get_ss(); + else{ + struct rtc_time h; + + get_rtc_time(&h); + return h.tm_sec; + } +} + +static inline int get_rtc_pll(struct rtc_pll_info *pll) +{ + if (mach_get_rtc_pll) + return mach_get_rtc_pll(pll); + else + return -EINVAL; +} +static inline int set_rtc_pll(struct rtc_pll_info *pll) +{ + if (mach_set_rtc_pll) + return mach_set_rtc_pll(pll); + else + return -EINVAL; +} +#endif /* __KERNEL__ */ + +#endif /* _ASM__RTC_H */ diff --git a/arch/m68k/include/asm/sbus.h b/arch/m68k/include/asm/sbus.h new file mode 100644 index 00000000000..bfe3ba147f2 --- /dev/null +++ b/arch/m68k/include/asm/sbus.h @@ -0,0 +1,45 @@ +/* + * some sbus structures and macros to make usage of sbus drivers possible + */ + +#ifndef __M68K_SBUS_H +#define __M68K_SBUS_H + +struct sbus_dev { + struct { + unsigned int which_io; + unsigned int phys_addr; + } reg_addrs[1]; +}; + +/* sbus IO functions stolen from include/asm-sparc/io.h for the serial driver */ +/* No SBUS on the Sun3, kludge -- sam */ + +static inline void _sbus_writeb(unsigned char val, unsigned long addr) +{ + *(volatile unsigned char *)addr = val; +} + +static inline unsigned char _sbus_readb(unsigned long addr) +{ + return *(volatile unsigned char *)addr; +} + +static inline void _sbus_writel(unsigned long val, unsigned long addr) +{ + *(volatile unsigned long *)addr = val; + +} + +extern inline unsigned long _sbus_readl(unsigned long addr) +{ + return *(volatile unsigned long *)addr; +} + + +#define sbus_readb(a) _sbus_readb((unsigned long)a) +#define sbus_writeb(v, a) _sbus_writeb(v, (unsigned long)a) +#define sbus_readl(a) _sbus_readl((unsigned long)a) +#define sbus_writel(v, a) _sbus_writel(v, (unsigned long)a) + +#endif diff --git a/arch/m68k/include/asm/scatterlist.h b/arch/m68k/include/asm/scatterlist.h new file mode 100644 index 00000000000..b7e52863625 --- /dev/null +++ b/arch/m68k/include/asm/scatterlist.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "scatterlist_no.h" +#else +#include "scatterlist_mm.h" +#endif diff --git a/arch/m68k/include/asm/scatterlist_mm.h b/arch/m68k/include/asm/scatterlist_mm.h new file mode 100644 index 00000000000..d3a7a0edfec --- /dev/null +++ b/arch/m68k/include/asm/scatterlist_mm.h @@ -0,0 +1,23 @@ +#ifndef _M68K_SCATTERLIST_H +#define _M68K_SCATTERLIST_H + +#include + +struct scatterlist { +#ifdef CONFIG_DEBUG_SG + unsigned long sg_magic; +#endif + unsigned long page_link; + unsigned int offset; + unsigned int length; + + __u32 dma_address; /* A place to hang host-specific addresses at. */ +}; + +/* This is bogus and should go away. */ +#define ISA_DMA_THRESHOLD (0x00ffffff) + +#define sg_dma_address(sg) ((sg)->dma_address) +#define sg_dma_len(sg) ((sg)->length) + +#endif /* !(_M68K_SCATTERLIST_H) */ diff --git a/arch/m68k/include/asm/scatterlist_no.h b/arch/m68k/include/asm/scatterlist_no.h new file mode 100644 index 00000000000..afc4788b0d2 --- /dev/null +++ b/arch/m68k/include/asm/scatterlist_no.h @@ -0,0 +1,22 @@ +#ifndef _M68KNOMMU_SCATTERLIST_H +#define _M68KNOMMU_SCATTERLIST_H + +#include +#include + +struct scatterlist { +#ifdef CONFIG_DEBUG_SG + unsigned long sg_magic; +#endif + unsigned long page_link; + unsigned int offset; + dma_addr_t dma_address; + unsigned int length; +}; + +#define sg_dma_address(sg) ((sg)->dma_address) +#define sg_dma_len(sg) ((sg)->length) + +#define ISA_DMA_THRESHOLD (0xffffffff) + +#endif /* !(_M68KNOMMU_SCATTERLIST_H) */ diff --git a/arch/m68k/include/asm/sections.h b/arch/m68k/include/asm/sections.h new file mode 100644 index 00000000000..d64967ecfec --- /dev/null +++ b/arch/m68k/include/asm/sections.h @@ -0,0 +1,6 @@ +#ifndef _ASM_M68K_SECTIONS_H +#define _ASM_M68K_SECTIONS_H + +#include + +#endif /* _ASM_M68K_SECTIONS_H */ diff --git a/arch/m68k/include/asm/segment.h b/arch/m68k/include/asm/segment.h new file mode 100644 index 00000000000..82583bc004b --- /dev/null +++ b/arch/m68k/include/asm/segment.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "segment_no.h" +#else +#include "segment_mm.h" +#endif diff --git a/arch/m68k/include/asm/segment_mm.h b/arch/m68k/include/asm/segment_mm.h new file mode 100644 index 00000000000..7b0b2d3127f --- /dev/null +++ b/arch/m68k/include/asm/segment_mm.h @@ -0,0 +1,57 @@ +#ifndef _M68K_SEGMENT_H +#define _M68K_SEGMENT_H + +/* define constants */ +/* Address spaces (FC0-FC2) */ +#define USER_DATA (1) +#ifndef __USER_DS +#define __USER_DS (USER_DATA) +#endif +#define USER_PROGRAM (2) +#define SUPER_DATA (5) +#ifndef __KERNEL_DS +#define __KERNEL_DS (SUPER_DATA) +#endif +#define SUPER_PROGRAM (6) +#define CPU_SPACE (7) + +#ifndef __ASSEMBLY__ + +typedef struct { + unsigned long seg; +} mm_segment_t; + +#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) +#define USER_DS MAKE_MM_SEG(__USER_DS) +#define KERNEL_DS MAKE_MM_SEG(__KERNEL_DS) + +/* + * Get/set the SFC/DFC registers for MOVES instructions + */ + +static inline mm_segment_t get_fs(void) +{ + mm_segment_t _v; + __asm__ ("movec %/dfc,%0":"=r" (_v.seg):); + + return _v; +} + +static inline mm_segment_t get_ds(void) +{ + /* return the supervisor data space code */ + return KERNEL_DS; +} + +static inline void set_fs(mm_segment_t val) +{ + __asm__ __volatile__ ("movec %0,%/sfc\n\t" + "movec %0,%/dfc\n\t" + : /* no outputs */ : "r" (val.seg) : "memory"); +} + +#define segment_eq(a,b) ((a).seg == (b).seg) + +#endif /* __ASSEMBLY__ */ + +#endif /* _M68K_SEGMENT_H */ diff --git a/arch/m68k/include/asm/segment_no.h b/arch/m68k/include/asm/segment_no.h new file mode 100644 index 00000000000..42318ebec7e --- /dev/null +++ b/arch/m68k/include/asm/segment_no.h @@ -0,0 +1,51 @@ +#ifndef _M68K_SEGMENT_H +#define _M68K_SEGMENT_H + +/* define constants */ +/* Address spaces (FC0-FC2) */ +#define USER_DATA (1) +#ifndef __USER_DS +#define __USER_DS (USER_DATA) +#endif +#define USER_PROGRAM (2) +#define SUPER_DATA (5) +#ifndef __KERNEL_DS +#define __KERNEL_DS (SUPER_DATA) +#endif +#define SUPER_PROGRAM (6) +#define CPU_SPACE (7) + +#ifndef __ASSEMBLY__ + +typedef struct { + unsigned long seg; +} mm_segment_t; + +#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) +#define USER_DS MAKE_MM_SEG(__USER_DS) +#define KERNEL_DS MAKE_MM_SEG(__KERNEL_DS) + +/* + * Get/set the SFC/DFC registers for MOVES instructions + */ + +static inline mm_segment_t get_fs(void) +{ + return USER_DS; +} + +static inline mm_segment_t get_ds(void) +{ + /* return the supervisor data space code */ + return KERNEL_DS; +} + +static inline void set_fs(mm_segment_t val) +{ +} + +#define segment_eq(a,b) ((a).seg == (b).seg) + +#endif /* __ASSEMBLY__ */ + +#endif /* _M68K_SEGMENT_H */ diff --git a/arch/m68k/include/asm/sembuf.h b/arch/m68k/include/asm/sembuf.h new file mode 100644 index 00000000000..2308052a8c2 --- /dev/null +++ b/arch/m68k/include/asm/sembuf.h @@ -0,0 +1,25 @@ +#ifndef _M68K_SEMBUF_H +#define _M68K_SEMBUF_H + +/* + * The semid64_ds structure for m68k architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct semid64_ds { + struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ + __kernel_time_t sem_otime; /* last semop time */ + unsigned long __unused1; + __kernel_time_t sem_ctime; /* last change time */ + unsigned long __unused2; + unsigned long sem_nsems; /* no. of semaphores in array */ + unsigned long __unused3; + unsigned long __unused4; +}; + +#endif /* _M68K_SEMBUF_H */ diff --git a/arch/m68k/include/asm/serial.h b/arch/m68k/include/asm/serial.h new file mode 100644 index 00000000000..2b90d6e6907 --- /dev/null +++ b/arch/m68k/include/asm/serial.h @@ -0,0 +1,33 @@ +/* + * include/asm-m68k/serial.h + * + * currently this seems useful only for a Q40, + * it's an almost exact copy of ../asm-alpha/serial.h + * + */ + + +/* + * This assumes you have a 1.8432 MHz clock for your UART. + * + * It'd be nice if someone built a serial card with a 24.576 MHz + * clock, since the 16550A is capable of handling a top speed of 1.5 + * megabits/second; but this requires the faster clock. + */ +#define BASE_BAUD ( 1843200 / 16 ) + +/* Standard COM flags (except for COM4, because of the 8514 problem) */ +#ifdef CONFIG_SERIAL_DETECT_IRQ +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ) +#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ) +#else +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) +#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF +#endif + +#define SERIAL_PORT_DFNS \ + /* UART CLK PORT IRQ FLAGS */ \ + { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ + { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \ + { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ + { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ diff --git a/arch/m68k/include/asm/setup.h b/arch/m68k/include/asm/setup.h new file mode 100644 index 00000000000..842f86f75cc --- /dev/null +++ b/arch/m68k/include/asm/setup.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "setup_no.h" +#else +#include "setup_mm.h" +#endif diff --git a/arch/m68k/include/asm/setup_mm.h b/arch/m68k/include/asm/setup_mm.h new file mode 100644 index 00000000000..4dfb3952b37 --- /dev/null +++ b/arch/m68k/include/asm/setup_mm.h @@ -0,0 +1,376 @@ +/* +** asm/setup.h -- Definition of the Linux/m68k setup information +** +** Copyright 1992 by Greg Harp +** +** This file is subject to the terms and conditions of the GNU General Public +** License. See the file COPYING in the main directory of this archive +** for more details. +** +** Created 09/29/92 by Greg Harp +** +** 5/2/94 Roman Hodek: +** Added bi_atari part of the machine dependent union bi_un; for now it +** contains just a model field to distinguish between TT and Falcon. +** 26/7/96 Roman Zippel: +** Renamed to setup.h; added some useful macros to allow gcc some +** optimizations if possible. +** 5/10/96 Geert Uytterhoeven: +** Redesign of the boot information structure; moved boot information +** structure to bootinfo.h +*/ + +#ifndef _M68K_SETUP_H +#define _M68K_SETUP_H + + + + /* + * Linux/m68k Architectures + */ + +#define MACH_AMIGA 1 +#define MACH_ATARI 2 +#define MACH_MAC 3 +#define MACH_APOLLO 4 +#define MACH_SUN3 5 +#define MACH_MVME147 6 +#define MACH_MVME16x 7 +#define MACH_BVME6000 8 +#define MACH_HP300 9 +#define MACH_Q40 10 +#define MACH_SUN3X 11 + +#define COMMAND_LINE_SIZE 256 + +#ifdef __KERNEL__ + +#define CL_SIZE COMMAND_LINE_SIZE + +#ifndef __ASSEMBLY__ +extern unsigned long m68k_machtype; +#endif /* !__ASSEMBLY__ */ + +#if !defined(CONFIG_AMIGA) +# define MACH_IS_AMIGA (0) +#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) || defined(CONFIG_APOLLO) \ + || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \ + || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ + || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) +# define MACH_IS_AMIGA (m68k_machtype == MACH_AMIGA) +#else +# define MACH_AMIGA_ONLY +# define MACH_IS_AMIGA (1) +# define MACH_TYPE (MACH_AMIGA) +#endif + +#if !defined(CONFIG_ATARI) +# define MACH_IS_ATARI (0) +#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_APOLLO) \ + || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \ + || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ + || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) +# define MACH_IS_ATARI (m68k_machtype == MACH_ATARI) +#else +# define MACH_ATARI_ONLY +# define MACH_IS_ATARI (1) +# define MACH_TYPE (MACH_ATARI) +#endif + +#if !defined(CONFIG_MAC) +# define MACH_IS_MAC (0) +#elif defined(CONFIG_AMIGA) || defined(CONFIG_ATARI) || defined(CONFIG_APOLLO) \ + || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \ + || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ + || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) +# define MACH_IS_MAC (m68k_machtype == MACH_MAC) +#else +# define MACH_MAC_ONLY +# define MACH_IS_MAC (1) +# define MACH_TYPE (MACH_MAC) +#endif + +#if defined(CONFIG_SUN3) +#define MACH_IS_SUN3 (1) +#define MACH_SUN3_ONLY (1) +#define MACH_TYPE (MACH_SUN3) +#else +#define MACH_IS_SUN3 (0) +#endif + +#if !defined (CONFIG_APOLLO) +# define MACH_IS_APOLLO (0) +#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ + || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \ + || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ + || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) +# define MACH_IS_APOLLO (m68k_machtype == MACH_APOLLO) +#else +# define MACH_APOLLO_ONLY +# define MACH_IS_APOLLO (1) +# define MACH_TYPE (MACH_APOLLO) +#endif + +#if !defined (CONFIG_MVME147) +# define MACH_IS_MVME147 (0) +#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ + || defined(CONFIG_APOLLO) || defined(CONFIG_BVME6000) \ + || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ + || defined(CONFIG_SUN3X) || defined(CONFIG_MVME16x) +# define MACH_IS_MVME147 (m68k_machtype == MACH_MVME147) +#else +# define MACH_MVME147_ONLY +# define MACH_IS_MVME147 (1) +# define MACH_TYPE (MACH_MVME147) +#endif + +#if !defined (CONFIG_MVME16x) +# define MACH_IS_MVME16x (0) +#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ + || defined(CONFIG_APOLLO) || defined(CONFIG_BVME6000) \ + || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ + || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) +# define MACH_IS_MVME16x (m68k_machtype == MACH_MVME16x) +#else +# define MACH_MVME16x_ONLY +# define MACH_IS_MVME16x (1) +# define MACH_TYPE (MACH_MVME16x) +#endif + +#if !defined (CONFIG_BVME6000) +# define MACH_IS_BVME6000 (0) +#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ + || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \ + || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ + || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) +# define MACH_IS_BVME6000 (m68k_machtype == MACH_BVME6000) +#else +# define MACH_BVME6000_ONLY +# define MACH_IS_BVME6000 (1) +# define MACH_TYPE (MACH_BVME6000) +#endif + +#if !defined (CONFIG_HP300) +# define MACH_IS_HP300 (0) +#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ + || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \ + || defined(CONFIG_BVME6000) || defined(CONFIG_Q40) \ + || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) +# define MACH_IS_HP300 (m68k_machtype == MACH_HP300) +#else +# define MACH_HP300_ONLY +# define MACH_IS_HP300 (1) +# define MACH_TYPE (MACH_HP300) +#endif + +#if !defined (CONFIG_Q40) +# define MACH_IS_Q40 (0) +#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ + || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \ + || defined(CONFIG_BVME6000) || defined(CONFIG_HP300) \ + || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) +# define MACH_IS_Q40 (m68k_machtype == MACH_Q40) +#else +# define MACH_Q40_ONLY +# define MACH_IS_Q40 (1) +# define MACH_TYPE (MACH_Q40) +#endif + +#if !defined (CONFIG_SUN3X) +# define MACH_IS_SUN3X (0) +#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ + || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \ + || defined(CONFIG_BVME6000) || defined(CONFIG_HP300) \ + || defined(CONFIG_Q40) || defined(CONFIG_MVME147) +# define MACH_IS_SUN3X (m68k_machtype == MACH_SUN3X) +#else +# define CONFIG_SUN3X_ONLY +# define MACH_IS_SUN3X (1) +# define MACH_TYPE (MACH_SUN3X) +#endif + +#ifndef MACH_TYPE +# define MACH_TYPE (m68k_machtype) +#endif + +#endif /* __KERNEL__ */ + + + /* + * CPU, FPU and MMU types + * + * Note: we may rely on the following equalities: + * + * CPU_68020 == MMU_68851 + * CPU_68030 == MMU_68030 + * CPU_68040 == FPU_68040 == MMU_68040 + * CPU_68060 == FPU_68060 == MMU_68060 + */ + +#define CPUB_68020 0 +#define CPUB_68030 1 +#define CPUB_68040 2 +#define CPUB_68060 3 + +#define CPU_68020 (1< + +/* We have a bigger command line buffer. */ +#undef COMMAND_LINE_SIZE + +#endif /* __KERNEL__ */ + +#define COMMAND_LINE_SIZE 512 diff --git a/arch/m68k/include/asm/shm.h b/arch/m68k/include/asm/shm.h new file mode 100644 index 00000000000..fa56ec84a12 --- /dev/null +++ b/arch/m68k/include/asm/shm.h @@ -0,0 +1,31 @@ +#ifndef _M68K_SHM_H +#define _M68K_SHM_H + + +/* format of page table entries that correspond to shared memory pages + currently out in swap space (see also mm/swap.c): + bits 0-1 (PAGE_PRESENT) is = 0 + bits 8..2 (SWP_TYPE) are = SHM_SWP_TYPE + bits 31..9 are used like this: + bits 15..9 (SHM_ID) the id of the shared memory segment + bits 30..16 (SHM_IDX) the index of the page within the shared memory segment + (actually only bits 25..16 get used since SHMMAX is so low) + bit 31 (SHM_READ_ONLY) flag whether the page belongs to a read-only attach +*/ +/* on the m68k both bits 0 and 1 must be zero */ +/* format on the sun3 is similar, but bits 30, 31 are set to zero and all + others are reduced by 2. --m */ + +#ifndef CONFIG_SUN3 +#define SHM_ID_SHIFT 9 +#else +#define SHM_ID_SHIFT 7 +#endif +#define _SHM_ID_BITS 7 +#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1) + +#define SHM_IDX_SHIFT (SHM_ID_SHIFT+_SHM_ID_BITS) +#define _SHM_IDX_BITS 15 +#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1) + +#endif /* _M68K_SHM_H */ diff --git a/arch/m68k/include/asm/shmbuf.h b/arch/m68k/include/asm/shmbuf.h new file mode 100644 index 00000000000..f8928d62f1b --- /dev/null +++ b/arch/m68k/include/asm/shmbuf.h @@ -0,0 +1,42 @@ +#ifndef _M68K_SHMBUF_H +#define _M68K_SHMBUF_H + +/* + * The shmid64_ds structure for m68k architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct shmid64_ds { + struct ipc64_perm shm_perm; /* operation perms */ + size_t shm_segsz; /* size of segment (bytes) */ + __kernel_time_t shm_atime; /* last attach time */ + unsigned long __unused1; + __kernel_time_t shm_dtime; /* last detach time */ + unsigned long __unused2; + __kernel_time_t shm_ctime; /* last change time */ + unsigned long __unused3; + __kernel_pid_t shm_cpid; /* pid of creator */ + __kernel_pid_t shm_lpid; /* pid of last operator */ + unsigned long shm_nattch; /* no. of current attaches */ + unsigned long __unused4; + unsigned long __unused5; +}; + +struct shminfo64 { + unsigned long shmmax; + unsigned long shmmin; + unsigned long shmmni; + unsigned long shmseg; + unsigned long shmall; + unsigned long __unused1; + unsigned long __unused2; + unsigned long __unused3; + unsigned long __unused4; +}; + +#endif /* _M68K_SHMBUF_H */ diff --git a/arch/m68k/include/asm/shmparam.h b/arch/m68k/include/asm/shmparam.h new file mode 100644 index 00000000000..558892a2efb --- /dev/null +++ b/arch/m68k/include/asm/shmparam.h @@ -0,0 +1,6 @@ +#ifndef _M68K_SHMPARAM_H +#define _M68K_SHMPARAM_H + +#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ + +#endif /* _M68K_SHMPARAM_H */ diff --git a/arch/m68k/include/asm/sigcontext.h b/arch/m68k/include/asm/sigcontext.h new file mode 100644 index 00000000000..bff6d40345a --- /dev/null +++ b/arch/m68k/include/asm/sigcontext.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "sigcontext_no.h" +#else +#include "sigcontext_mm.h" +#endif diff --git a/arch/m68k/include/asm/sigcontext_mm.h b/arch/m68k/include/asm/sigcontext_mm.h new file mode 100644 index 00000000000..64fbe34cf26 --- /dev/null +++ b/arch/m68k/include/asm/sigcontext_mm.h @@ -0,0 +1,19 @@ +#ifndef _ASM_M68k_SIGCONTEXT_H +#define _ASM_M68k_SIGCONTEXT_H + +struct sigcontext { + unsigned long sc_mask; /* old sigmask */ + unsigned long sc_usp; /* old user stack pointer */ + unsigned long sc_d0; + unsigned long sc_d1; + unsigned long sc_a0; + unsigned long sc_a1; + unsigned short sc_sr; + unsigned long sc_pc; + unsigned short sc_formatvec; + unsigned long sc_fpregs[2*3]; /* room for two fp registers */ + unsigned long sc_fpcntl[3]; + unsigned char sc_fpstate[216]; +}; + +#endif diff --git a/arch/m68k/include/asm/sigcontext_no.h b/arch/m68k/include/asm/sigcontext_no.h new file mode 100644 index 00000000000..36c293fc133 --- /dev/null +++ b/arch/m68k/include/asm/sigcontext_no.h @@ -0,0 +1,17 @@ +#ifndef _ASM_M68KNOMMU_SIGCONTEXT_H +#define _ASM_M68KNOMMU_SIGCONTEXT_H + +struct sigcontext { + unsigned long sc_mask; /* old sigmask */ + unsigned long sc_usp; /* old user stack pointer */ + unsigned long sc_d0; + unsigned long sc_d1; + unsigned long sc_a0; + unsigned long sc_a1; + unsigned long sc_a5; + unsigned short sc_sr; + unsigned long sc_pc; + unsigned short sc_formatvec; +}; + +#endif diff --git a/arch/m68k/include/asm/siginfo.h b/arch/m68k/include/asm/siginfo.h new file mode 100644 index 00000000000..61219d7affc --- /dev/null +++ b/arch/m68k/include/asm/siginfo.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "siginfo_no.h" +#else +#include "siginfo_mm.h" +#endif diff --git a/arch/m68k/include/asm/siginfo_mm.h b/arch/m68k/include/asm/siginfo_mm.h new file mode 100644 index 00000000000..05a8d6d90b5 --- /dev/null +++ b/arch/m68k/include/asm/siginfo_mm.h @@ -0,0 +1,92 @@ +#ifndef _M68K_SIGINFO_H +#define _M68K_SIGINFO_H + +#define HAVE_ARCH_SIGINFO_T +#define HAVE_ARCH_COPY_SIGINFO + +#include + +typedef struct siginfo { + int si_signo; + int si_errno; + int si_code; + + union { + int _pad[SI_PAD_SIZE]; + + /* kill() */ + struct { + __kernel_pid_t _pid; /* sender's pid */ + __kernel_uid_t _uid; /* backwards compatibility */ + __kernel_uid32_t _uid32; /* sender's uid */ + } _kill; + + /* POSIX.1b timers */ + struct { + timer_t _tid; /* timer id */ + int _overrun; /* overrun count */ + char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)]; + sigval_t _sigval; /* same as below */ + int _sys_private; /* not to be passed to user */ + } _timer; + + /* POSIX.1b signals */ + struct { + __kernel_pid_t _pid; /* sender's pid */ + __kernel_uid_t _uid; /* backwards compatibility */ + sigval_t _sigval; + __kernel_uid32_t _uid32; /* sender's uid */ + } _rt; + + /* SIGCHLD */ + struct { + __kernel_pid_t _pid; /* which child */ + __kernel_uid_t _uid; /* backwards compatibility */ + int _status; /* exit code */ + clock_t _utime; + clock_t _stime; + __kernel_uid32_t _uid32; /* sender's uid */ + } _sigchld; + + /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ + struct { + void *_addr; /* faulting insn/memory ref. */ + } _sigfault; + + /* SIGPOLL */ + struct { + int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ + int _fd; + } _sigpoll; + } _sifields; +} siginfo_t; + +#define UID16_SIGINFO_COMPAT_NEEDED + +/* + * How these fields are to be accessed. + */ +#undef si_uid +#ifdef __KERNEL__ +#define si_uid _sifields._kill._uid32 +#define si_uid16 _sifields._kill._uid +#else +#define si_uid _sifields._kill._uid +#endif + +#ifdef __KERNEL__ + +#include + +static inline void copy_siginfo(struct siginfo *to, struct siginfo *from) +{ + if (from->si_code < 0) + memcpy(to, from, sizeof(*to)); + else + /* _sigchld is currently the largest know union member */ + memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld)); +} + +#endif /* __KERNEL__ */ + +#endif diff --git a/arch/m68k/include/asm/siginfo_no.h b/arch/m68k/include/asm/siginfo_no.h new file mode 100644 index 00000000000..b18e5f4064a --- /dev/null +++ b/arch/m68k/include/asm/siginfo_no.h @@ -0,0 +1,6 @@ +#ifndef _M68KNOMMU_SIGINFO_H +#define _M68KNOMMU_SIGINFO_H + +#include + +#endif diff --git a/arch/m68k/include/asm/signal.h b/arch/m68k/include/asm/signal.h new file mode 100644 index 00000000000..3c19988bd93 --- /dev/null +++ b/arch/m68k/include/asm/signal.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "signal_no.h" +#else +#include "signal_mm.h" +#endif diff --git a/arch/m68k/include/asm/signal_mm.h b/arch/m68k/include/asm/signal_mm.h new file mode 100644 index 00000000000..3db8a81942f --- /dev/null +++ b/arch/m68k/include/asm/signal_mm.h @@ -0,0 +1,206 @@ +#ifndef _M68K_SIGNAL_H +#define _M68K_SIGNAL_H + +#include + +/* Avoid too many header ordering problems. */ +struct siginfo; + +#ifdef __KERNEL__ +/* Most things should be clean enough to redefine this at will, if care + is taken to make libc match. */ + +#define _NSIG 64 +#define _NSIG_BPW 32 +#define _NSIG_WORDS (_NSIG / _NSIG_BPW) + +typedef unsigned long old_sigset_t; /* at least 32 bits */ + +typedef struct { + unsigned long sig[_NSIG_WORDS]; +} sigset_t; + +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +#define NSIG 32 +typedef unsigned long sigset_t; + +#endif /* __KERNEL__ */ + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 +#define SIGBUS 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTKFLT 16 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGTSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 +#define SIGURG 23 +#define SIGXCPU 24 +#define SIGXFSZ 25 +#define SIGVTALRM 26 +#define SIGPROF 27 +#define SIGWINCH 28 +#define SIGIO 29 +#define SIGPOLL SIGIO +/* +#define SIGLOST 29 +*/ +#define SIGPWR 30 +#define SIGSYS 31 +#define SIGUNUSED 31 + +/* These should not be considered constants from userland. */ +#define SIGRTMIN 32 +#define SIGRTMAX _NSIG + +/* + * SA_FLAGS values: + * + * SA_ONSTACK indicates that a registered stack_t will be used. + * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. + * SA_RESETHAND clears the handler when the signal is delivered. + * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. + * SA_NODEFER prevents the current signal from being masked in the handler. + * + * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single + * Unix names RESETHAND and NODEFER respectively. + */ +#define SA_NOCLDSTOP 0x00000001 +#define SA_NOCLDWAIT 0x00000002 +#define SA_SIGINFO 0x00000004 +#define SA_ONSTACK 0x08000000 +#define SA_RESTART 0x10000000 +#define SA_NODEFER 0x40000000 +#define SA_RESETHAND 0x80000000 + +#define SA_NOMASK SA_NODEFER +#define SA_ONESHOT SA_RESETHAND + +/* + * sigaltstack controls + */ +#define SS_ONSTACK 1 +#define SS_DISABLE 2 + +#define MINSIGSTKSZ 2048 +#define SIGSTKSZ 8192 + +#include + +#ifdef __KERNEL__ +struct old_sigaction { + __sighandler_t sa_handler; + old_sigset_t sa_mask; + unsigned long sa_flags; + __sigrestore_t sa_restorer; +}; + +struct sigaction { + __sighandler_t sa_handler; + unsigned long sa_flags; + __sigrestore_t sa_restorer; + sigset_t sa_mask; /* mask last for extensibility */ +}; + +struct k_sigaction { + struct sigaction sa; +}; +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +struct sigaction { + union { + __sighandler_t _sa_handler; + void (*_sa_sigaction)(int, struct siginfo *, void *); + } _u; + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; + +#define sa_handler _u._sa_handler +#define sa_sigaction _u._sa_sigaction + +#endif /* __KERNEL__ */ + +typedef struct sigaltstack { + void __user *ss_sp; + int ss_flags; + size_t ss_size; +} stack_t; + +#ifdef __KERNEL__ +#include + +#define __HAVE_ARCH_SIG_BITOPS + +static inline void sigaddset(sigset_t *set, int _sig) +{ + asm ("bfset %0{%1,#1}" + : "+od" (*set) + : "id" ((_sig - 1) ^ 31) + : "cc"); +} + +static inline void sigdelset(sigset_t *set, int _sig) +{ + asm ("bfclr %0{%1,#1}" + : "+od" (*set) + : "id" ((_sig - 1) ^ 31) + : "cc"); +} + +static inline int __const_sigismember(sigset_t *set, int _sig) +{ + unsigned long sig = _sig - 1; + return 1 & (set->sig[sig / _NSIG_BPW] >> (sig % _NSIG_BPW)); +} + +static inline int __gen_sigismember(sigset_t *set, int _sig) +{ + int ret; + asm ("bfextu %1{%2,#1},%0" + : "=d" (ret) + : "od" (*set), "id" ((_sig-1) ^ 31) + : "cc"); + return ret; +} + +#define sigismember(set,sig) \ + (__builtin_constant_p(sig) ? \ + __const_sigismember(set,sig) : \ + __gen_sigismember(set,sig)) + +static inline int sigfindinword(unsigned long word) +{ + asm ("bfffo %1{#0,#0},%0" + : "=d" (word) + : "d" (word & -word) + : "cc"); + return word ^ 31; +} + +struct pt_regs; +extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie); + +#endif /* __KERNEL__ */ + +#endif /* _M68K_SIGNAL_H */ diff --git a/arch/m68k/include/asm/signal_no.h b/arch/m68k/include/asm/signal_no.h new file mode 100644 index 00000000000..216c08be54a --- /dev/null +++ b/arch/m68k/include/asm/signal_no.h @@ -0,0 +1,159 @@ +#ifndef _M68KNOMMU_SIGNAL_H +#define _M68KNOMMU_SIGNAL_H + +#include + +/* Avoid too many header ordering problems. */ +struct siginfo; + +#ifdef __KERNEL__ +/* Most things should be clean enough to redefine this at will, if care + is taken to make libc match. */ + +#define _NSIG 64 +#define _NSIG_BPW 32 +#define _NSIG_WORDS (_NSIG / _NSIG_BPW) + +typedef unsigned long old_sigset_t; /* at least 32 bits */ + +typedef struct { + unsigned long sig[_NSIG_WORDS]; +} sigset_t; + +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +#define NSIG 32 +typedef unsigned long sigset_t; + +#endif /* __KERNEL__ */ + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 +#define SIGBUS 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTKFLT 16 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGTSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 +#define SIGURG 23 +#define SIGXCPU 24 +#define SIGXFSZ 25 +#define SIGVTALRM 26 +#define SIGPROF 27 +#define SIGWINCH 28 +#define SIGIO 29 +#define SIGPOLL SIGIO +/* +#define SIGLOST 29 +*/ +#define SIGPWR 30 +#define SIGSYS 31 +#define SIGUNUSED 31 + +/* These should not be considered constants from userland. */ +#define SIGRTMIN 32 +#define SIGRTMAX _NSIG + +/* + * SA_FLAGS values: + * + * SA_ONSTACK indicates that a registered stack_t will be used. + * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. + * SA_RESETHAND clears the handler when the signal is delivered. + * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. + * SA_NODEFER prevents the current signal from being masked in the handler. + * + * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single + * Unix names RESETHAND and NODEFER respectively. + */ +#define SA_NOCLDSTOP 0x00000001 +#define SA_NOCLDWAIT 0x00000002 +#define SA_SIGINFO 0x00000004 +#define SA_ONSTACK 0x08000000 +#define SA_RESTART 0x10000000 +#define SA_NODEFER 0x40000000 +#define SA_RESETHAND 0x80000000 + +#define SA_NOMASK SA_NODEFER +#define SA_ONESHOT SA_RESETHAND + +/* + * sigaltstack controls + */ +#define SS_ONSTACK 1 +#define SS_DISABLE 2 + +#define MINSIGSTKSZ 2048 +#define SIGSTKSZ 8192 + +#include + +#ifdef __KERNEL__ +struct old_sigaction { + __sighandler_t sa_handler; + old_sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; + +struct sigaction { + __sighandler_t sa_handler; + unsigned long sa_flags; + void (*sa_restorer)(void); + sigset_t sa_mask; /* mask last for extensibility */ +}; + +struct k_sigaction { + struct sigaction sa; +}; +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +struct sigaction { + union { + __sighandler_t _sa_handler; + void (*_sa_sigaction)(int, struct siginfo *, void *); + } _u; + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; + +#define sa_handler _u._sa_handler +#define sa_sigaction _u._sa_sigaction + +#endif /* __KERNEL__ */ + +typedef struct sigaltstack { + void *ss_sp; + int ss_flags; + size_t ss_size; +} stack_t; + +#ifdef __KERNEL__ + +#include +#undef __HAVE_ARCH_SIG_BITOPS + +#define ptrace_signal_deliver(regs, cookie) do { } while (0) + +#endif /* __KERNEL__ */ + +#endif /* _M68KNOMMU_SIGNAL_H */ diff --git a/arch/m68k/include/asm/smp.h b/arch/m68k/include/asm/smp.h new file mode 100644 index 00000000000..9e9bd7e5892 --- /dev/null +++ b/arch/m68k/include/asm/smp.h @@ -0,0 +1 @@ +/* nothing required here yet */ diff --git a/arch/m68k/include/asm/socket.h b/arch/m68k/include/asm/socket.h new file mode 100644 index 00000000000..dbc64e92c41 --- /dev/null +++ b/arch/m68k/include/asm/socket.h @@ -0,0 +1,57 @@ +#ifndef _ASM_SOCKET_H +#define _ASM_SOCKET_H + +#include + +/* For setsockopt(2) */ +#define SOL_SOCKET 1 + +#define SO_DEBUG 1 +#define SO_REUSEADDR 2 +#define SO_TYPE 3 +#define SO_ERROR 4 +#define SO_DONTROUTE 5 +#define SO_BROADCAST 6 +#define SO_SNDBUF 7 +#define SO_RCVBUF 8 +#define SO_SNDBUFFORCE 32 +#define SO_RCVBUFFORCE 33 +#define SO_KEEPALIVE 9 +#define SO_OOBINLINE 10 +#define SO_NO_CHECK 11 +#define SO_PRIORITY 12 +#define SO_LINGER 13 +#define SO_BSDCOMPAT 14 +/* To add :#define SO_REUSEPORT 15 */ +#define SO_PASSCRED 16 +#define SO_PEERCRED 17 +#define SO_RCVLOWAT 18 +#define SO_SNDLOWAT 19 +#define SO_RCVTIMEO 20 +#define SO_SNDTIMEO 21 + +/* Security levels - as per NRL IPv6 - don't actually do anything */ +#define SO_SECURITY_AUTHENTICATION 22 +#define SO_SECURITY_ENCRYPTION_TRANSPORT 23 +#define SO_SECURITY_ENCRYPTION_NETWORK 24 + +#define SO_BINDTODEVICE 25 + +/* Socket filtering */ +#define SO_ATTACH_FILTER 26 +#define SO_DETACH_FILTER 27 + +#define SO_PEERNAME 28 +#define SO_TIMESTAMP 29 +#define SCM_TIMESTAMP SO_TIMESTAMP + +#define SO_ACCEPTCONN 30 + +#define SO_PEERSEC 31 +#define SO_PASSSEC 34 +#define SO_TIMESTAMPNS 35 +#define SCM_TIMESTAMPNS SO_TIMESTAMPNS + +#define SO_MARK 36 + +#endif /* _ASM_SOCKET_H */ diff --git a/arch/m68k/include/asm/sockios.h b/arch/m68k/include/asm/sockios.h new file mode 100644 index 00000000000..c04a23943cb --- /dev/null +++ b/arch/m68k/include/asm/sockios.h @@ -0,0 +1,13 @@ +#ifndef __ARCH_M68K_SOCKIOS__ +#define __ARCH_M68K_SOCKIOS__ + +/* Socket-level I/O control calls. */ +#define FIOSETOWN 0x8901 +#define SIOCSPGRP 0x8902 +#define FIOGETOWN 0x8903 +#define SIOCGPGRP 0x8904 +#define SIOCATMARK 0x8905 +#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */ +#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ + +#endif /* __ARCH_M68K_SOCKIOS__ */ diff --git a/arch/m68k/include/asm/spinlock.h b/arch/m68k/include/asm/spinlock.h new file mode 100644 index 00000000000..20f46e27b53 --- /dev/null +++ b/arch/m68k/include/asm/spinlock.h @@ -0,0 +1,6 @@ +#ifndef __M68K_SPINLOCK_H +#define __M68K_SPINLOCK_H + +#error "m68k doesn't do SMP yet" + +#endif diff --git a/arch/m68k/include/asm/stat.h b/arch/m68k/include/asm/stat.h new file mode 100644 index 00000000000..dd38bc2e9f9 --- /dev/null +++ b/arch/m68k/include/asm/stat.h @@ -0,0 +1,77 @@ +#ifndef _M68K_STAT_H +#define _M68K_STAT_H + +struct __old_kernel_stat { + unsigned short st_dev; + unsigned short st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + unsigned long st_size; + unsigned long st_atime; + unsigned long st_mtime; + unsigned long st_ctime; +}; + +struct stat { + unsigned short st_dev; + unsigned short __pad1; + unsigned long st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + unsigned short __pad2; + unsigned long st_size; + unsigned long st_blksize; + unsigned long st_blocks; + unsigned long st_atime; + unsigned long __unused1; + unsigned long st_mtime; + unsigned long __unused2; + unsigned long st_ctime; + unsigned long __unused3; + unsigned long __unused4; + unsigned long __unused5; +}; + +/* This matches struct stat64 in glibc2.1, hence the absolutely + * insane amounts of padding around dev_t's. + */ +struct stat64 { + unsigned long long st_dev; + unsigned char __pad1[2]; + +#define STAT64_HAS_BROKEN_ST_INO 1 + unsigned long __st_ino; + + unsigned int st_mode; + unsigned int st_nlink; + + unsigned long st_uid; + unsigned long st_gid; + + unsigned long long st_rdev; + unsigned char __pad3[2]; + + long long st_size; + unsigned long st_blksize; + + unsigned long long st_blocks; /* Number 512-byte blocks allocated. */ + + unsigned long st_atime; + unsigned long st_atime_nsec; + + unsigned long st_mtime; + unsigned long st_mtime_nsec; + + unsigned long st_ctime; + unsigned long st_ctime_nsec; + + unsigned long long st_ino; +}; + +#endif /* _M68K_STAT_H */ diff --git a/arch/m68k/include/asm/statfs.h b/arch/m68k/include/asm/statfs.h new file mode 100644 index 00000000000..08d93f14e06 --- /dev/null +++ b/arch/m68k/include/asm/statfs.h @@ -0,0 +1,6 @@ +#ifndef _M68K_STATFS_H +#define _M68K_STATFS_H + +#include + +#endif /* _M68K_STATFS_H */ diff --git a/arch/m68k/include/asm/string.h b/arch/m68k/include/asm/string.h new file mode 100644 index 00000000000..2c356f90f17 --- /dev/null +++ b/arch/m68k/include/asm/string.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "string_no.h" +#else +#include "string_mm.h" +#endif diff --git a/arch/m68k/include/asm/string_mm.h b/arch/m68k/include/asm/string_mm.h new file mode 100644 index 00000000000..2eb7df1e0f5 --- /dev/null +++ b/arch/m68k/include/asm/string_mm.h @@ -0,0 +1,131 @@ +#ifndef _M68K_STRING_H_ +#define _M68K_STRING_H_ + +#include +#include + +static inline size_t __kernel_strlen(const char *s) +{ + const char *sc; + + for (sc = s; *sc++; ) + ; + return sc - s - 1; +} + +static inline char *__kernel_strcpy(char *dest, const char *src) +{ + char *xdest = dest; + + asm volatile ("\n" + "1: move.b (%1)+,(%0)+\n" + " jne 1b" + : "+a" (dest), "+a" (src) + : : "memory"); + return xdest; +} + +#ifndef __IN_STRING_C + +#define __HAVE_ARCH_STRLEN +#define strlen(s) (__builtin_constant_p(s) ? \ + __builtin_strlen(s) : \ + __kernel_strlen(s)) + +#define __HAVE_ARCH_STRNLEN +static inline size_t strnlen(const char *s, size_t count) +{ + const char *sc = s; + + asm volatile ("\n" + "1: subq.l #1,%1\n" + " jcs 2f\n" + " tst.b (%0)+\n" + " jne 1b\n" + " subq.l #1,%0\n" + "2:" + : "+a" (sc), "+d" (count)); + return sc - s; +} + +#define __HAVE_ARCH_STRCPY +#if __GNUC__ >= 4 +#define strcpy(d, s) (__builtin_constant_p(s) && \ + __builtin_strlen(s) <= 32 ? \ + __builtin_strcpy(d, s) : \ + __kernel_strcpy(d, s)) +#else +#define strcpy(d, s) __kernel_strcpy(d, s) +#endif + +#define __HAVE_ARCH_STRNCPY +static inline char *strncpy(char *dest, const char *src, size_t n) +{ + char *xdest = dest; + + asm volatile ("\n" + " jra 2f\n" + "1: move.b (%1),(%0)+\n" + " jeq 2f\n" + " addq.l #1,%1\n" + "2: subq.l #1,%2\n" + " jcc 1b\n" + : "+a" (dest), "+a" (src), "+d" (n) + : : "memory"); + return xdest; +} + +#define __HAVE_ARCH_STRCAT +#define strcat(d, s) ({ \ + char *__d = (d); \ + strcpy(__d + strlen(__d), (s)); \ +}) + +#define __HAVE_ARCH_STRCHR +static inline char *strchr(const char *s, int c) +{ + char sc, ch = c; + + for (; (sc = *s++) != ch; ) { + if (!sc) + return NULL; + } + return (char *)s - 1; +} + +#define __HAVE_ARCH_STRCMP +static inline int strcmp(const char *cs, const char *ct) +{ + char res; + + asm ("\n" + "1: move.b (%0)+,%2\n" /* get *cs */ + " cmp.b (%1)+,%2\n" /* compare a byte */ + " jne 2f\n" /* not equal, break out */ + " tst.b %2\n" /* at end of cs? */ + " jne 1b\n" /* no, keep going */ + " jra 3f\n" /* strings are equal */ + "2: sub.b -(%1),%2\n" /* *cs - *ct */ + "3:" + : "+a" (cs), "+a" (ct), "=d" (res)); + return res; +} + +#define __HAVE_ARCH_MEMSET +extern void *memset(void *, int, __kernel_size_t); +#define memset(d, c, n) __builtin_memset(d, c, n) + +#define __HAVE_ARCH_MEMCPY +extern void *memcpy(void *, const void *, __kernel_size_t); +#define memcpy(d, s, n) __builtin_memcpy(d, s, n) + +#define __HAVE_ARCH_MEMMOVE +extern void *memmove(void *, const void *, __kernel_size_t); + +#define __HAVE_ARCH_MEMCMP +extern int memcmp(const void *, const void *, __kernel_size_t); +#define memcmp(d, s, n) __builtin_memcmp(d, s, n) + +#endif + +#endif /* _M68K_STRING_H_ */ diff --git a/arch/m68k/include/asm/string_no.h b/arch/m68k/include/asm/string_no.h new file mode 100644 index 00000000000..af09e17000f --- /dev/null +++ b/arch/m68k/include/asm/string_no.h @@ -0,0 +1,126 @@ +#ifndef _M68KNOMMU_STRING_H_ +#define _M68KNOMMU_STRING_H_ + +#ifdef __KERNEL__ /* only set these up for kernel code */ + +#include +#include + +#define __HAVE_ARCH_STRCPY +static inline char * strcpy(char * dest,const char *src) +{ + char *xdest = dest; + + __asm__ __volatile__ + ("1:\tmoveb %1@+,%0@+\n\t" + "jne 1b" + : "=a" (dest), "=a" (src) + : "0" (dest), "1" (src) : "memory"); + return xdest; +} + +#define __HAVE_ARCH_STRNCPY +static inline char * strncpy(char *dest, const char *src, size_t n) +{ + char *xdest = dest; + + if (n == 0) + return xdest; + + __asm__ __volatile__ + ("1:\tmoveb %1@+,%0@+\n\t" + "jeq 2f\n\t" + "subql #1,%2\n\t" + "jne 1b\n\t" + "2:" + : "=a" (dest), "=a" (src), "=d" (n) + : "0" (dest), "1" (src), "2" (n) + : "memory"); + return xdest; +} + + +#ifndef CONFIG_COLDFIRE + +#define __HAVE_ARCH_STRCMP +static inline int strcmp(const char * cs,const char * ct) +{ + char __res; + + __asm__ + ("1:\tmoveb %0@+,%2\n\t" /* get *cs */ + "cmpb %1@+,%2\n\t" /* compare a byte */ + "jne 2f\n\t" /* not equal, break out */ + "tstb %2\n\t" /* at end of cs? */ + "jne 1b\n\t" /* no, keep going */ + "jra 3f\n\t" /* strings are equal */ + "2:\tsubb %1@-,%2\n\t" /* *cs - *ct */ + "3:" + : "=a" (cs), "=a" (ct), "=d" (__res) + : "0" (cs), "1" (ct)); + + return __res; +} + +#define __HAVE_ARCH_STRNCMP +static inline int strncmp(const char * cs,const char * ct,size_t count) +{ + char __res; + + if (!count) + return 0; + __asm__ + ("1:\tmovb %0@+,%3\n\t" /* get *cs */ + "cmpb %1@+,%3\n\t" /* compare a byte */ + "jne 3f\n\t" /* not equal, break out */ + "tstb %3\n\t" /* at end of cs? */ + "jeq 4f\n\t" /* yes, all done */ + "subql #1,%2\n\t" /* no, adjust count */ + "jne 1b\n\t" /* more to do, keep going */ + "2:\tmoveq #0,%3\n\t" /* strings are equal */ + "jra 4f\n\t" + "3:\tsubb %1@-,%3\n\t" /* *cs - *ct */ + "4:" + : "=a" (cs), "=a" (ct), "=d" (count), "=d" (__res) + : "0" (cs), "1" (ct), "2" (count)); + return __res; +} + +#endif /* CONFIG_COLDFIRE */ + +#define __HAVE_ARCH_MEMSET +extern void * memset(void * s, int c, size_t count); + +#define __HAVE_ARCH_MEMCPY +extern void * memcpy(void *d, const void *s, size_t count); + +#else /* KERNEL */ + +/* + * let user libraries deal with these, + * IMHO the kernel has no place defining these functions for user apps + */ + +#define __HAVE_ARCH_STRCPY 1 +#define __HAVE_ARCH_STRNCPY 1 +#define __HAVE_ARCH_STRCAT 1 +#define __HAVE_ARCH_STRNCAT 1 +#define __HAVE_ARCH_STRCMP 1 +#define __HAVE_ARCH_STRNCMP 1 +#define __HAVE_ARCH_STRNICMP 1 +#define __HAVE_ARCH_STRCHR 1 +#define __HAVE_ARCH_STRRCHR 1 +#define __HAVE_ARCH_STRSTR 1 +#define __HAVE_ARCH_STRLEN 1 +#define __HAVE_ARCH_STRNLEN 1 +#define __HAVE_ARCH_MEMSET 1 +#define __HAVE_ARCH_MEMCPY 1 +#define __HAVE_ARCH_MEMMOVE 1 +#define __HAVE_ARCH_MEMSCAN 1 +#define __HAVE_ARCH_MEMCMP 1 +#define __HAVE_ARCH_MEMCHR 1 +#define __HAVE_ARCH_STRTOK 1 + +#endif /* KERNEL */ + +#endif /* _M68K_STRING_H_ */ diff --git a/arch/m68k/include/asm/sun3-head.h b/arch/m68k/include/asm/sun3-head.h new file mode 100644 index 00000000000..05af2f18b3b --- /dev/null +++ b/arch/m68k/include/asm/sun3-head.h @@ -0,0 +1,10 @@ +#ifndef __SUN3_HEAD_H +#define __SUN3_HEAD_H + +#define KERNBASE 0xE000000 /* First address the kernel will eventually be */ +#define LOAD_ADDR 0x4000 /* prom jumps to us here unless this is elf /boot */ +#define FC_CONTROL 3 +#define FC_SUPERD 5 +#define FC_CPU 7 + +#endif /* __SUN3_HEAD_H */ diff --git a/arch/m68k/include/asm/sun3_pgalloc.h b/arch/m68k/include/asm/sun3_pgalloc.h new file mode 100644 index 00000000000..d4c83f14381 --- /dev/null +++ b/arch/m68k/include/asm/sun3_pgalloc.h @@ -0,0 +1,102 @@ +/* sun3_pgalloc.h -- + * reorganization around 2.3.39, routines moved from sun3_pgtable.h + * + * + * 02/27/2002 -- Modified to support "highpte" implementation in 2.5.5 (Sam) + * + * moved 1/26/2000 Sam Creasey + */ + +#ifndef _SUN3_PGALLOC_H +#define _SUN3_PGALLOC_H + +#include + +/* FIXME - when we get this compiling */ +/* erm, now that it's compiling, what do we do with it? */ +#define _KERNPG_TABLE 0 + +extern const char bad_pmd_string[]; + +#define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); }) + + +static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) +{ + free_page((unsigned long) pte); +} + +static inline void pte_free(struct mm_struct *mm, pgtable_t page) +{ + pgtable_page_dtor(page); + __free_page(page); +} + +#define __pte_free_tlb(tlb,pte) \ +do { \ + pgtable_page_dtor(pte); \ + tlb_remove_page((tlb), pte); \ +} while (0) + +static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, + unsigned long address) +{ + unsigned long page = __get_free_page(GFP_KERNEL|__GFP_REPEAT); + + if (!page) + return NULL; + + memset((void *)page, 0, PAGE_SIZE); + return (pte_t *) (page); +} + +static inline pgtable_t pte_alloc_one(struct mm_struct *mm, + unsigned long address) +{ + struct page *page = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0); + + if (page == NULL) + return NULL; + + clear_highpage(page); + pgtable_page_ctor(page); + return page; + +} + +static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte) +{ + pmd_val(*pmd) = __pa((unsigned long)pte); +} + +static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t page) +{ + pmd_val(*pmd) = __pa((unsigned long)page_address(page)); +} +#define pmd_pgtable(pmd) pmd_page(pmd) + +/* + * allocating and freeing a pmd is trivial: the 1-entry pmd is + * inside the pgd, so has no extra memory associated with it. + */ +#define pmd_free(mm, x) do { } while (0) +#define __pmd_free_tlb(tlb, x) do { } while (0) + +static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) +{ + free_page((unsigned long) pgd); +} + +static inline pgd_t * pgd_alloc(struct mm_struct *mm) +{ + pgd_t *new_pgd; + + new_pgd = (pgd_t *)get_zeroed_page(GFP_KERNEL); + memcpy(new_pgd, swapper_pg_dir, PAGE_SIZE); + memset(new_pgd, 0, (PAGE_OFFSET >> PGDIR_SHIFT)); + return new_pgd; +} + +#define pgd_populate(mm, pmd, pte) BUG() + +#endif /* SUN3_PGALLOC_H */ diff --git a/arch/m68k/include/asm/sun3_pgtable.h b/arch/m68k/include/asm/sun3_pgtable.h new file mode 100644 index 00000000000..f847ec732d6 --- /dev/null +++ b/arch/m68k/include/asm/sun3_pgtable.h @@ -0,0 +1,234 @@ +#ifndef _SUN3_PGTABLE_H +#define _SUN3_PGTABLE_H + +#include + +#ifndef __ASSEMBLY__ +#include +#include + +/* + * This file contains all the things which change drastically for the sun3 + * pagetable stuff, to avoid making too much of a mess of the generic m68k + * `pgtable.h'; this should only be included from the generic file. --m + */ + +/* For virtual address to physical address conversion */ +#define VTOP(addr) __pa(addr) +#define PTOV(addr) __va(addr) + + +#endif /* !__ASSEMBLY__ */ + +/* These need to be defined for compatibility although the sun3 doesn't use them */ +#define _PAGE_NOCACHE030 0x040 +#define _CACHEMASK040 (~0x060) +#define _PAGE_NOCACHE_S 0x040 + +/* Page protection values within PTE. */ +#define SUN3_PAGE_VALID (0x80000000) +#define SUN3_PAGE_WRITEABLE (0x40000000) +#define SUN3_PAGE_SYSTEM (0x20000000) +#define SUN3_PAGE_NOCACHE (0x10000000) +#define SUN3_PAGE_ACCESSED (0x02000000) +#define SUN3_PAGE_MODIFIED (0x01000000) + + +/* Externally used page protection values. */ +#define _PAGE_PRESENT (SUN3_PAGE_VALID) +#define _PAGE_ACCESSED (SUN3_PAGE_ACCESSED) + +#define PTE_FILE_MAX_BITS 28 + +/* Compound page protection values. */ +//todo: work out which ones *should* have SUN3_PAGE_NOCACHE and fix... +// is it just PAGE_KERNEL and PAGE_SHARED? +#define PAGE_NONE __pgprot(SUN3_PAGE_VALID \ + | SUN3_PAGE_ACCESSED \ + | SUN3_PAGE_NOCACHE) +#define PAGE_SHARED __pgprot(SUN3_PAGE_VALID \ + | SUN3_PAGE_WRITEABLE \ + | SUN3_PAGE_ACCESSED \ + | SUN3_PAGE_NOCACHE) +#define PAGE_COPY __pgprot(SUN3_PAGE_VALID \ + | SUN3_PAGE_ACCESSED \ + | SUN3_PAGE_NOCACHE) +#define PAGE_READONLY __pgprot(SUN3_PAGE_VALID \ + | SUN3_PAGE_ACCESSED \ + | SUN3_PAGE_NOCACHE) +#define PAGE_KERNEL __pgprot(SUN3_PAGE_VALID \ + | SUN3_PAGE_WRITEABLE \ + | SUN3_PAGE_SYSTEM \ + | SUN3_PAGE_NOCACHE \ + | SUN3_PAGE_ACCESSED \ + | SUN3_PAGE_MODIFIED) +#define PAGE_INIT __pgprot(SUN3_PAGE_VALID \ + | SUN3_PAGE_WRITEABLE \ + | SUN3_PAGE_SYSTEM \ + | SUN3_PAGE_NOCACHE) + +/* + * Page protections for initialising protection_map. The sun3 has only two + * protection settings, valid (implying read and execute) and writeable. These + * are as close as we can get... + */ +#define __P000 PAGE_NONE +#define __P001 PAGE_READONLY +#define __P010 PAGE_COPY +#define __P011 PAGE_COPY +#define __P100 PAGE_READONLY +#define __P101 PAGE_READONLY +#define __P110 PAGE_COPY +#define __P111 PAGE_COPY + +#define __S000 PAGE_NONE +#define __S001 PAGE_READONLY +#define __S010 PAGE_SHARED +#define __S011 PAGE_SHARED +#define __S100 PAGE_READONLY +#define __S101 PAGE_READONLY +#define __S110 PAGE_SHARED +#define __S111 PAGE_SHARED + +/* Use these fake page-protections on PMDs. */ +#define SUN3_PMD_VALID (0x00000001) +#define SUN3_PMD_MASK (0x0000003F) +#define SUN3_PMD_MAGIC (0x0000002B) + +#ifndef __ASSEMBLY__ + +/* + * Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + */ +#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) + +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ + pte_val(pte) = (pte_val(pte) & SUN3_PAGE_CHG_MASK) | pgprot_val(newprot); + return pte; +} + +#define pmd_set(pmdp,ptep) do {} while (0) + +static inline void pgd_set(pgd_t *pgdp, pmd_t *pmdp) +{ + pgd_val(*pgdp) = virt_to_phys(pmdp); +} + +#define __pte_page(pte) \ +((unsigned long) __va ((pte_val (pte) & SUN3_PAGE_PGNUM_MASK) << PAGE_SHIFT)) +#define __pmd_page(pmd) \ +((unsigned long) __va (pmd_val (pmd) & PAGE_MASK)) + +static inline int pte_none (pte_t pte) { return !pte_val (pte); } +static inline int pte_present (pte_t pte) { return pte_val (pte) & SUN3_PAGE_VALID; } +static inline void pte_clear (struct mm_struct *mm, unsigned long addr, pte_t *ptep) +{ + pte_val (*ptep) = 0; +} + +#define pte_pfn(pte) (pte_val(pte) & SUN3_PAGE_PGNUM_MASK) +#define pfn_pte(pfn, pgprot) \ +({ pte_t __pte; pte_val(__pte) = pfn | pgprot_val(pgprot); __pte; }) + +#define pte_page(pte) virt_to_page(__pte_page(pte)) +#define pmd_page(pmd) virt_to_page(__pmd_page(pmd)) + + +static inline int pmd_none2 (pmd_t *pmd) { return !pmd_val (*pmd); } +#define pmd_none(pmd) pmd_none2(&(pmd)) +//static inline int pmd_bad (pmd_t pmd) { return (pmd_val (pmd) & SUN3_PMD_MASK) != SUN3_PMD_MAGIC; } +static inline int pmd_bad2 (pmd_t *pmd) { return 0; } +#define pmd_bad(pmd) pmd_bad2(&(pmd)) +static inline int pmd_present2 (pmd_t *pmd) { return pmd_val (*pmd) & SUN3_PMD_VALID; } +/* #define pmd_present(pmd) pmd_present2(&(pmd)) */ +#define pmd_present(pmd) (!pmd_none2(&(pmd))) +static inline void pmd_clear (pmd_t *pmdp) { pmd_val (*pmdp) = 0; } + +static inline int pgd_none (pgd_t pgd) { return 0; } +static inline int pgd_bad (pgd_t pgd) { return 0; } +static inline int pgd_present (pgd_t pgd) { return 1; } +static inline void pgd_clear (pgd_t *pgdp) {} + + +#define pte_ERROR(e) \ + printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) +#define pmd_ERROR(e) \ + printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) +#define pgd_ERROR(e) \ + printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) + + +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not... + * [we have the full set here even if they don't change from m68k] + */ +static inline int pte_write(pte_t pte) { return pte_val(pte) & SUN3_PAGE_WRITEABLE; } +static inline int pte_dirty(pte_t pte) { return pte_val(pte) & SUN3_PAGE_MODIFIED; } +static inline int pte_young(pte_t pte) { return pte_val(pte) & SUN3_PAGE_ACCESSED; } +static inline int pte_file(pte_t pte) { return pte_val(pte) & SUN3_PAGE_ACCESSED; } +static inline int pte_special(pte_t pte) { return 0; } + +static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~SUN3_PAGE_WRITEABLE; return pte; } +static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~SUN3_PAGE_MODIFIED; return pte; } +static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~SUN3_PAGE_ACCESSED; return pte; } +static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= SUN3_PAGE_WRITEABLE; return pte; } +static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= SUN3_PAGE_MODIFIED; return pte; } +static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= SUN3_PAGE_ACCESSED; return pte; } +static inline pte_t pte_mknocache(pte_t pte) { pte_val(pte) |= SUN3_PAGE_NOCACHE; return pte; } +// use this version when caches work... +//static inline pte_t pte_mkcache(pte_t pte) { pte_val(pte) &= SUN3_PAGE_NOCACHE; return pte; } +// until then, use: +static inline pte_t pte_mkcache(pte_t pte) { return pte; } +static inline pte_t pte_mkspecial(pte_t pte) { return pte; } + +extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; +extern pgd_t kernel_pg_dir[PTRS_PER_PGD]; + +/* Find an entry in a pagetable directory. */ +#define pgd_index(address) ((address) >> PGDIR_SHIFT) + +#define pgd_offset(mm, address) \ +((mm)->pgd + pgd_index(address)) + +/* Find an entry in a kernel pagetable directory. */ +#define pgd_offset_k(address) pgd_offset(&init_mm, address) + +/* Find an entry in the second-level pagetable. */ +static inline pmd_t *pmd_offset (pgd_t *pgd, unsigned long address) +{ + return (pmd_t *) pgd; +} + +static inline unsigned long pte_to_pgoff(pte_t pte) +{ + return pte.pte & SUN3_PAGE_PGNUM_MASK; +} + +static inline pte_t pgoff_to_pte(unsigned off) +{ + pte_t pte = { off + SUN3_PAGE_ACCESSED }; + return pte; +} + + +/* Find an entry in the third-level pagetable. */ +#define pte_index(address) ((address >> PAGE_SHIFT) & (PTRS_PER_PTE-1)) +#define pte_offset_kernel(pmd, address) ((pte_t *) __pmd_page(*pmd) + pte_index(address)) +/* FIXME: should we bother with kmap() here? */ +#define pte_offset_map(pmd, address) ((pte_t *)kmap(pmd_page(*pmd)) + pte_index(address)) +#define pte_offset_map_nested(pmd, address) pte_offset_map(pmd, address) +#define pte_unmap(pte) kunmap(pte) +#define pte_unmap_nested(pte) kunmap(pte) + +/* Macros to (de)construct the fake PTEs representing swap pages. */ +#define __swp_type(x) ((x).val & 0x7F) +#define __swp_offset(x) (((x).val) >> 7) +#define __swp_entry(type,offset) ((swp_entry_t) { ((type) | ((offset) << 7)) }) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) + +#endif /* !__ASSEMBLY__ */ +#endif /* !_SUN3_PGTABLE_H */ diff --git a/arch/m68k/include/asm/sun3ints.h b/arch/m68k/include/asm/sun3ints.h new file mode 100644 index 00000000000..309d6e6a137 --- /dev/null +++ b/arch/m68k/include/asm/sun3ints.h @@ -0,0 +1,37 @@ +/* + * sun3ints.h -- Linux/Sun3 interrupt handling code definitions + * + * Erik Verbruggen (erik@bigmama.xtdnet.nl) + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +#ifndef SUN3INTS_H +#define SUN3INTS_H + +#include +#include +#include +#include +#include +#include + +#define SUN3_INT_VECS 192 + +void sun3_enable_irq(unsigned int irq); +void sun3_disable_irq(unsigned int irq); +extern void sun3_init_IRQ (void); +extern void sun3_enable_interrupts (void); +extern void sun3_disable_interrupts (void); +extern volatile unsigned char* sun3_intreg; + +/* master list of VME vectors -- don't fuck with this */ +#define SUN3_VEC_FLOPPY (IRQ_USER+0) +#define SUN3_VEC_VMESCSI0 (IRQ_USER+0) +#define SUN3_VEC_VMESCSI1 (IRQ_USER+1) +#define SUN3_VEC_CG (IRQ_USER+104) + + +#endif /* SUN3INTS_H */ diff --git a/arch/m68k/include/asm/sun3mmu.h b/arch/m68k/include/asm/sun3mmu.h new file mode 100644 index 00000000000..d8f17a0d8c9 --- /dev/null +++ b/arch/m68k/include/asm/sun3mmu.h @@ -0,0 +1,171 @@ +/* + * Definitions for Sun3 custom MMU. + */ +#ifndef __SUN3_MMU_H__ +#define __SUN3_MMU_H__ + +#include +#include +#include + +/* MMU characteristics. */ +#define SUN3_SEGMAPS_PER_CONTEXT 2048 +#define SUN3_PMEGS_NUM 256 +#define SUN3_CONTEXTS_NUM 8 + +#define SUN3_PMEG_SIZE_BITS 17 +#define SUN3_PMEG_SIZE (1 << SUN3_PMEG_SIZE_BITS) +#define SUN3_PMEG_MASK (SUN3_PMEG_SIZE - 1) + +#define SUN3_PTE_SIZE_BITS 13 +#define SUN3_PTE_SIZE (1 << SUN3_PTE_SIZE_BITS) +#define SUN3_PTE_MASK (SUN3_PTE_SIZE - 1) + +#define SUN3_CONTROL_MASK (0x0FFFFFFC) +#define SUN3_INVALID_PMEG 255 +#define SUN3_INVALID_CONTEXT 255 + +#define AC_IDPROM 0x00000000 /* 34 ID PROM, R/O, byte, 32 bytes */ +#define AC_PAGEMAP 0x10000000 /* 3 Pagemap R/W, long */ +#define AC_SEGMAP 0x20000000 /* 3 Segment map, byte */ +#define AC_CONTEXT 0x30000000 /* 34c current mmu-context */ +#define AC_SENABLE 0x40000000 /* 34c system dvma/cache/reset enable reg*/ +#define AC_UDVMA_ENB 0x50000000 /* 34 Not used on Sun boards, byte */ +#define AC_BUS_ERROR 0x60000000 /* 34 Cleared on read, byte. */ +#define AC_SYNC_ERR 0x60000000 /* c fault type */ +#define AC_SYNC_VA 0x60000004 /* c fault virtual address */ +#define AC_ASYNC_ERR 0x60000008 /* c asynchronous fault type */ +#define AC_ASYNC_VA 0x6000000c /* c async fault virtual address */ +#define AC_LEDS 0x70000000 /* 34 Zero turns on LEDs, byte */ +#define AC_CACHETAGS 0x80000000 /* 34c direct access to the VAC tags */ +#define AC_CACHEDDATA 0x90000000 /* 3 c direct access to the VAC data */ +#define AC_UDVMA_MAP 0xD0000000 /* 4 Not used on Sun boards, byte */ +#define AC_VME_VECTOR 0xE0000000 /* 4 For non-Autovector VME, byte */ +#define AC_BOOT_SCC 0xF0000000 /* 34 bypass to access Zilog 8530. byte.*/ + +#define SUN3_PAGE_CHG_MASK (SUN3_PAGE_PGNUM_MASK \ + | SUN3_PAGE_ACCESSED | SUN3_PAGE_MODIFIED) + +/* Bus access type within PTE. */ +#define SUN3_PAGE_TYPE_MASK (0x0c000000) +#define SUN3_PAGE_TYPE_MEMORY (0x00000000) +#define SUN3_PAGE_TYPE_IO (0x04000000) +#define SUN3_PAGE_TYPE_VME16 (0x08000000) +#define SUN3_PAGE_TYPE_VME32 (0x0c000000) + +/* Mask for page number within PTE. */ +#define SUN3_PAGE_PGNUM_MASK (0x0007FFFF) + +/* Bits within bus-error register. */ +#define SUN3_BUSERR_WATCHDOG (0x01) +#define SUN3_BUSERR_unused (0x02) +#define SUN3_BUSERR_FPAENERR (0x04) +#define SUN3_BUSERR_FPABERR (0x08) +#define SUN3_BUSERR_VMEBERR (0x10) +#define SUN3_BUSERR_TIMEOUT (0x20) +#define SUN3_BUSERR_PROTERR (0x40) +#define SUN3_BUSERR_INVALID (0x80) + +#ifndef __ASSEMBLY__ + +/* Read bus error status register (implicitly clearing it). */ +static inline unsigned char sun3_get_buserr(void) +{ + unsigned char sfc, c; + + GET_SFC (sfc); + SET_SFC (FC_CONTROL); + GET_CONTROL_BYTE (AC_BUS_ERROR, c); + SET_SFC (sfc); + + return c; +} + +/* Read segmap from hardware MMU. */ +static inline unsigned long sun3_get_segmap(unsigned long addr) +{ + register unsigned long entry; + unsigned char c, sfc; + + GET_SFC (sfc); + SET_SFC (FC_CONTROL); + GET_CONTROL_BYTE (AC_SEGMAP | (addr & SUN3_CONTROL_MASK), c); + SET_SFC (sfc); + entry = c; + + return entry; +} + +/* Write segmap to hardware MMU. */ +static inline void sun3_put_segmap(unsigned long addr, unsigned long entry) +{ + unsigned char sfc; + + GET_DFC (sfc); + SET_DFC (FC_CONTROL); + SET_CONTROL_BYTE (AC_SEGMAP | (addr & SUN3_CONTROL_MASK), entry); + SET_DFC (sfc); + + return; +} + +/* Read PTE from hardware MMU. */ +static inline unsigned long sun3_get_pte(unsigned long addr) +{ + register unsigned long entry; + unsigned char sfc; + + GET_SFC (sfc); + SET_SFC (FC_CONTROL); + GET_CONTROL_WORD (AC_PAGEMAP | (addr & SUN3_CONTROL_MASK), entry); + SET_SFC (sfc); + + return entry; +} + +/* Write PTE to hardware MMU. */ +static inline void sun3_put_pte(unsigned long addr, unsigned long entry) +{ + unsigned char sfc; + + GET_DFC (sfc); + SET_DFC (FC_CONTROL); + SET_CONTROL_WORD (AC_PAGEMAP | (addr & SUN3_CONTROL_MASK), entry); + SET_DFC (sfc); + + return; +} + +/* get current context */ +static inline unsigned char sun3_get_context(void) +{ + unsigned char sfc, c; + + GET_SFC(sfc); + SET_SFC(FC_CONTROL); + GET_CONTROL_BYTE(AC_CONTEXT, c); + SET_SFC(sfc); + + return c; +} + +/* set alternate context */ +static inline void sun3_put_context(unsigned char c) +{ + unsigned char dfc; + GET_DFC(dfc); + SET_DFC(FC_CONTROL); + SET_CONTROL_BYTE(AC_CONTEXT, c); + SET_DFC(dfc); + + return; +} + +extern void __iomem *sun3_ioremap(unsigned long phys, unsigned long size, + unsigned long type); + +extern int sun3_map_test(unsigned long addr, char *val); + +#endif /* !__ASSEMBLY__ */ + +#endif /* !__SUN3_MMU_H__ */ diff --git a/arch/m68k/include/asm/sun3x.h b/arch/m68k/include/asm/sun3x.h new file mode 100644 index 00000000000..f5691a1ed7c --- /dev/null +++ b/arch/m68k/include/asm/sun3x.h @@ -0,0 +1,27 @@ +#ifndef SUN3X_H +#define SUN3X_H + +/* hardware addresses */ +#define SUN3X_IOMMU 0x60000000 +#define SUN3X_ENAREG 0x61000000 +#define SUN3X_INTREG 0x61001400 +#define SUN3X_DIAGREG 0x61001800 +#define SUN3X_ZS1 0x62000000 +#define SUN3X_ZS2 0x62002000 +#define SUN3X_LANCE 0x65002000 +#define SUN3X_EEPROM 0x64000000 +#define SUN3X_IDPROM 0x640007d8 +#define SUN3X_VIDEO_BASE 0x50000000 +#define SUN3X_VIDEO_P4ID 0x50300000 +#define SUN3X_ESP_BASE 0x66000000 +#define SUN3X_ESP_DMA 0x66001000 +#define SUN3X_FDC 0x6e000000 +#define SUN3X_FDC_FCR 0x6e000400 +#define SUN3X_FDC_FVR 0x6e000800 + +/* some NVRAM addresses */ +#define SUN3X_EEPROM_CONS (SUN3X_EEPROM + 0x1f) +#define SUN3X_EEPROM_PORTA (SUN3X_EEPROM + 0x58) +#define SUN3X_EEPROM_PORTB (SUN3X_EEPROM + 0x60) + +#endif diff --git a/arch/m68k/include/asm/sun3xflop.h b/arch/m68k/include/asm/sun3xflop.h new file mode 100644 index 00000000000..32c45f84ac6 --- /dev/null +++ b/arch/m68k/include/asm/sun3xflop.h @@ -0,0 +1,263 @@ +/* sun3xflop.h: Sun3/80 specific parts of the floppy driver. + * + * Derived partially from asm-sparc/floppy.h, which is: + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * + * Sun3x version 2/4/2000 Sam Creasey (sammy@sammy.net) + */ + +#ifndef __ASM_SUN3X_FLOPPY_H +#define __ASM_SUN3X_FLOPPY_H + +#include +#include +#include +#include +#include + +/* default interrupt vector */ +#define SUN3X_FDC_IRQ 0x40 + +/* some constants */ +#define FCR_TC 0x1 +#define FCR_EJECT 0x2 +#define FCR_MTRON 0x4 +#define FCR_DSEL1 0x8 +#define FCR_DSEL0 0x10 + +/* We don't need no stinkin' I/O port allocation crap. */ +#undef release_region +#undef request_region +#define release_region(X, Y) do { } while(0) +#define request_region(X, Y, Z) (1) + +struct sun3xflop_private { + volatile unsigned char *status_r; + volatile unsigned char *data_r; + volatile unsigned char *fcr_r; + volatile unsigned char *fvr_r; + unsigned char fcr; +} sun3x_fdc; + +/* Super paranoid... */ +#undef HAVE_DISABLE_HLT + +/* Routines unique to each controller type on a Sun. */ +static unsigned char sun3x_82072_fd_inb(int port) +{ + static int once = 0; +// udelay(5); + switch(port & 7) { + default: + printk("floppy: Asked to read unknown port %d\n", port); + panic("floppy: Port bolixed."); + case 4: /* FD_STATUS */ + return (*sun3x_fdc.status_r) & ~STATUS_DMA; + case 5: /* FD_DATA */ + return (*sun3x_fdc.data_r); + case 7: /* FD_DIR */ + /* ugly hack, I can't find a way to actually detect the disk */ + if(!once) { + once = 1; + return 0x80; + } + return 0; + }; + panic("sun_82072_fd_inb: How did I get here?"); +} + +static void sun3x_82072_fd_outb(unsigned char value, int port) +{ +// udelay(5); + switch(port & 7) { + default: + printk("floppy: Asked to write to unknown port %d\n", port); + panic("floppy: Port bolixed."); + case 2: /* FD_DOR */ + /* Oh geese, 82072 on the Sun has no DOR register, + * so we make do with taunting the FCR. + * + * ASSUMPTIONS: There will only ever be one floppy + * drive attached to a Sun controller + * and it will be at drive zero. + */ + + { + unsigned char fcr = sun3x_fdc.fcr; + + if(value & 0x10) { + fcr |= (FCR_DSEL0 | FCR_MTRON); + } else + fcr &= ~(FCR_DSEL0 | FCR_MTRON); + + + if(fcr != sun3x_fdc.fcr) { + *(sun3x_fdc.fcr_r) = fcr; + sun3x_fdc.fcr = fcr; + } + } + break; + case 5: /* FD_DATA */ + *(sun3x_fdc.data_r) = value; + break; + case 7: /* FD_DCR */ + *(sun3x_fdc.status_r) = value; + break; + case 4: /* FD_STATUS */ + *(sun3x_fdc.status_r) = value; + break; + }; + return; +} + + +asmlinkage irqreturn_t sun3xflop_hardint(int irq, void *dev_id) +{ + register unsigned char st; + +#undef TRACE_FLPY_INT +#define NO_FLOPPY_ASSEMBLER + +#ifdef TRACE_FLPY_INT + static int calls=0; + static int bytes=0; + static int dma_wait=0; +#endif + if(!doing_pdma) { + floppy_interrupt(irq, dev_id); + return IRQ_HANDLED; + } + +// printk("doing pdma\n");// st %x\n", sun_fdc->status_82072); + +#ifdef TRACE_FLPY_INT + if(!calls) + bytes = virtual_dma_count; +#endif + + { + register int lcount; + register char *lptr; + + for(lcount=virtual_dma_count, lptr=virtual_dma_addr; + lcount; lcount--, lptr++) { +/* st=fd_inb(virtual_dma_port+4) & 0x80 ; */ + st = *(sun3x_fdc.status_r); +/* if(st != 0xa0) */ +/* break; */ + + if((st & 0x80) == 0) { + virtual_dma_count = lcount; + virtual_dma_addr = lptr; + return IRQ_HANDLED; + } + + if((st & 0x20) == 0) + break; + + if(virtual_dma_mode) +/* fd_outb(*lptr, virtual_dma_port+5); */ + *(sun3x_fdc.data_r) = *lptr; + else +/* *lptr = fd_inb(virtual_dma_port+5); */ + *lptr = *(sun3x_fdc.data_r); + } + + virtual_dma_count = lcount; + virtual_dma_addr = lptr; +/* st = fd_inb(virtual_dma_port+4); */ + st = *(sun3x_fdc.status_r); + } + +#ifdef TRACE_FLPY_INT + calls++; +#endif +// printk("st=%02x\n", st); + if(st == 0x20) + return IRQ_HANDLED; + if(!(st & 0x20)) { + virtual_dma_residue += virtual_dma_count; + virtual_dma_count=0; + doing_pdma = 0; + +#ifdef TRACE_FLPY_INT + printk("count=%x, residue=%x calls=%d bytes=%x dma_wait=%d\n", + virtual_dma_count, virtual_dma_residue, calls, bytes, + dma_wait); + calls = 0; + dma_wait=0; +#endif + + floppy_interrupt(irq, dev_id); + return IRQ_HANDLED; + } + + +#ifdef TRACE_FLPY_INT + if(!virtual_dma_count) + dma_wait++; +#endif + return IRQ_HANDLED; +} + +static int sun3xflop_request_irq(void) +{ + static int once = 0; + int error; + + if(!once) { + once = 1; + error = request_irq(FLOPPY_IRQ, sun3xflop_hardint, + IRQF_DISABLED, "floppy", NULL); + return ((error == 0) ? 0 : -1); + } else return 0; +} + +static void __init floppy_set_flags(int *ints,int param, int param2); + +static int sun3xflop_init(void) +{ + if(FLOPPY_IRQ < 0x40) + FLOPPY_IRQ = SUN3X_FDC_IRQ; + + sun3x_fdc.status_r = (volatile unsigned char *)SUN3X_FDC; + sun3x_fdc.data_r = (volatile unsigned char *)(SUN3X_FDC+1); + sun3x_fdc.fcr_r = (volatile unsigned char *)SUN3X_FDC_FCR; + sun3x_fdc.fvr_r = (volatile unsigned char *)SUN3X_FDC_FVR; + sun3x_fdc.fcr = 0; + + /* Last minute sanity check... */ + if(*sun3x_fdc.status_r == 0xff) { + return -1; + } + + *sun3x_fdc.fvr_r = FLOPPY_IRQ; + + *sun3x_fdc.fcr_r = FCR_TC; + udelay(10); + *sun3x_fdc.fcr_r = 0; + + /* Success... */ + floppy_set_flags(NULL, 1, FD_BROKEN_DCL); // I don't know how to detect this. + allowed_drive_mask = 0x01; + return (int) SUN3X_FDC; +} + +/* I'm not precisely sure this eject routine works */ +static int sun3x_eject(void) +{ + if(MACH_IS_SUN3X) { + + sun3x_fdc.fcr |= (FCR_DSEL0 | FCR_EJECT); + *(sun3x_fdc.fcr_r) = sun3x_fdc.fcr; + udelay(10); + sun3x_fdc.fcr &= ~(FCR_DSEL0 | FCR_EJECT); + *(sun3x_fdc.fcr_r) = sun3x_fdc.fcr; + } + + return 0; +} + +#define fd_eject(drive) sun3x_eject() + +#endif /* !(__ASM_SUN3X_FLOPPY_H) */ diff --git a/arch/m68k/include/asm/sun3xprom.h b/arch/m68k/include/asm/sun3xprom.h new file mode 100644 index 00000000000..6735efcf5f6 --- /dev/null +++ b/arch/m68k/include/asm/sun3xprom.h @@ -0,0 +1,43 @@ +/* Useful PROM locations */ + +#ifndef SUN3X_PROM_H +#define SUN3X_PROM_H + +extern void (*sun3x_putchar)(int); +extern int (*sun3x_getchar)(void); +extern int (*sun3x_mayget)(void); +extern int (*sun3x_mayput)(int); + +void sun3x_reboot(void); +void sun3x_abort(void); +void sun3x_prom_init(void); +unsigned long sun3x_prom_ptov(unsigned long pa, unsigned long size); + +/* interesting hardware locations */ +#define SUN3X_IOMMU 0x60000000 +#define SUN3X_ENAREG 0x61000000 +#define SUN3X_INTREG 0x61001400 +#define SUN3X_DIAGREG 0x61001800 +#define SUN3X_ZS1 0x62000000 +#define SUN3X_ZS2 0x62002000 +#define SUN3X_LANCE 0x65002000 +#define SUN3X_EEPROM 0x64000000 +#define SUN3X_IDPROM 0x640007d8 +#define SUN3X_VIDEO_BASE 0x50400000 +#define SUN3X_VIDEO_REGS 0x50300000 + +/* vector table */ +#define SUN3X_PROM_BASE 0xfefe0000 +#define SUN3X_P_GETCHAR (SUN3X_PROM_BASE + 20) +#define SUN3X_P_PUTCHAR (SUN3X_PROM_BASE + 24) +#define SUN3X_P_MAYGET (SUN3X_PROM_BASE + 28) +#define SUN3X_P_MAYPUT (SUN3X_PROM_BASE + 32) +#define SUN3X_P_REBOOT (SUN3X_PROM_BASE + 96) +#define SUN3X_P_SETLEDS (SUN3X_PROM_BASE + 144) +#define SUN3X_P_ABORT (SUN3X_PROM_BASE + 152) + +/* mapped area */ +#define SUN3X_MAP_START 0xfee00000 +#define SUN3X_MAP_END 0xff000000 + +#endif diff --git a/arch/m68k/include/asm/suspend.h b/arch/m68k/include/asm/suspend.h new file mode 100644 index 00000000000..57b3ddb4d26 --- /dev/null +++ b/arch/m68k/include/asm/suspend.h @@ -0,0 +1,6 @@ +#ifndef _M68K_SUSPEND_H +#define _M68K_SUSPEND_H + +/* Dummy include. */ + +#endif /* _M68K_SUSPEND_H */ diff --git a/arch/m68k/include/asm/swab.h b/arch/m68k/include/asm/swab.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arch/m68k/include/asm/swab_mm.h b/arch/m68k/include/asm/swab_mm.h new file mode 100644 index 00000000000..7221e306682 --- /dev/null +++ b/arch/m68k/include/asm/swab_mm.h @@ -0,0 +1,16 @@ +#ifndef _M68K_SWAB_H +#define _M68K_SWAB_H + +#include +#include + +#define __SWAB_64_THRU_32__ + +static inline __attribute_const__ __u32 __arch_swab32(__u32 val) +{ + __asm__("rolw #8,%0; swap %0; rolw #8,%0" : "=d" (val) : "0" (val)); + return val; +} +#define __arch_swab32 __arch_swab32 + +#endif /* _M68K_SWAB_H */ diff --git a/arch/m68k/include/asm/swab_no.h b/arch/m68k/include/asm/swab_no.h new file mode 100644 index 00000000000..e582257db30 --- /dev/null +++ b/arch/m68k/include/asm/swab_no.h @@ -0,0 +1,24 @@ +#ifndef _M68KNOMMU_SWAB_H +#define _M68KNOMMU_SWAB_H + +#include + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__) +# define __SWAB_64_THRU_32__ +#endif + +#if defined (__mcfisaaplus__) || defined (__mcfisac__) +static inline __attribute_const__ __u32 __arch_swab32(__u32 val) +{ + asm( + "byterev %0" + : "=d" (val) + : "0" (val) + ); + return val; +} + +#define __arch_swab32 __arch_swab32 +#endif + +#endif /* _M68KNOMMU_SWAB_H */ diff --git a/arch/m68k/include/asm/system.h b/arch/m68k/include/asm/system.h new file mode 100644 index 00000000000..ccea925ff4f --- /dev/null +++ b/arch/m68k/include/asm/system.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "system_no.h" +#else +#include "system_mm.h" +#endif diff --git a/arch/m68k/include/asm/system_mm.h b/arch/m68k/include/asm/system_mm.h new file mode 100644 index 00000000000..dbb6515ffd5 --- /dev/null +++ b/arch/m68k/include/asm/system_mm.h @@ -0,0 +1,218 @@ +#ifndef _M68K_SYSTEM_H +#define _M68K_SYSTEM_H + +#include +#include +#include +#include + +#ifdef __KERNEL__ + +/* + * switch_to(n) should switch tasks to task ptr, first checking that + * ptr isn't the current task, in which case it does nothing. This + * also clears the TS-flag if the task we switched to has used the + * math co-processor latest. + */ +/* + * switch_to() saves the extra registers, that are not saved + * automatically by SAVE_SWITCH_STACK in resume(), ie. d0-d5 and + * a0-a1. Some of these are used by schedule() and its predecessors + * and so we might get see unexpected behaviors when a task returns + * with unexpected register values. + * + * syscall stores these registers itself and none of them are used + * by syscall after the function in the syscall has been called. + * + * Beware that resume now expects *next to be in d1 and the offset of + * tss to be in a1. This saves a few instructions as we no longer have + * to push them onto the stack and read them back right after. + * + * 02/17/96 - Jes Sorensen (jds@kom.auc.dk) + * + * Changed 96/09/19 by Andreas Schwab + * pass prev in a0, next in a1 + */ +asmlinkage void resume(void); +#define switch_to(prev,next,last) do { \ + register void *_prev __asm__ ("a0") = (prev); \ + register void *_next __asm__ ("a1") = (next); \ + register void *_last __asm__ ("d1"); \ + __asm__ __volatile__("jbsr resume" \ + : "=a" (_prev), "=a" (_next), "=d" (_last) \ + : "0" (_prev), "1" (_next) \ + : "d0", "d2", "d3", "d4", "d5"); \ + (last) = _last; \ +} while (0) + + +/* + * Force strict CPU ordering. + * Not really required on m68k... + */ +#define nop() do { asm volatile ("nop"); barrier(); } while (0) +#define mb() barrier() +#define rmb() barrier() +#define wmb() barrier() +#define read_barrier_depends() ((void)0) +#define set_mb(var, value) ({ (var) = (value); wmb(); }) + +#define smp_mb() barrier() +#define smp_rmb() barrier() +#define smp_wmb() barrier() +#define smp_read_barrier_depends() ((void)0) + +/* interrupt control.. */ +#if 0 +#define local_irq_enable() asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory") +#else +#include +#define local_irq_enable() ({ \ + if (MACH_IS_Q40 || !hardirq_count()) \ + asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory"); \ +}) +#endif +#define local_irq_disable() asm volatile ("oriw #0x0700,%%sr": : : "memory") +#define local_save_flags(x) asm volatile ("movew %%sr,%0":"=d" (x) : : "memory") +#define local_irq_restore(x) asm volatile ("movew %0,%%sr": :"d" (x) : "memory") + +static inline int irqs_disabled(void) +{ + unsigned long flags; + local_save_flags(flags); + return flags & ~ALLOWINT; +} + +/* For spinlocks etc */ +#define local_irq_save(x) ({ local_save_flags(x); local_irq_disable(); }) + +#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) + +struct __xchg_dummy { unsigned long a[100]; }; +#define __xg(x) ((volatile struct __xchg_dummy *)(x)) + +#ifndef CONFIG_RMW_INSNS +static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) +{ + unsigned long flags, tmp; + + local_irq_save(flags); + + switch (size) { + case 1: + tmp = *(u8 *)ptr; + *(u8 *)ptr = x; + x = tmp; + break; + case 2: + tmp = *(u16 *)ptr; + *(u16 *)ptr = x; + x = tmp; + break; + case 4: + tmp = *(u32 *)ptr; + *(u32 *)ptr = x; + x = tmp; + break; + default: + BUG(); + } + + local_irq_restore(flags); + return x; +} +#else +static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) +{ + switch (size) { + case 1: + __asm__ __volatile__ + ("moveb %2,%0\n\t" + "1:\n\t" + "casb %0,%1,%2\n\t" + "jne 1b" + : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); + break; + case 2: + __asm__ __volatile__ + ("movew %2,%0\n\t" + "1:\n\t" + "casw %0,%1,%2\n\t" + "jne 1b" + : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); + break; + case 4: + __asm__ __volatile__ + ("movel %2,%0\n\t" + "1:\n\t" + "casl %0,%1,%2\n\t" + "jne 1b" + : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); + break; + } + return x; +} +#endif + +#include + +#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) + +/* + * Atomic compare and exchange. Compare OLD with MEM, if identical, + * store NEW in MEM. Return the initial value in MEM. Success is + * indicated by comparing RETURN with OLD. + */ +#ifdef CONFIG_RMW_INSNS +#define __HAVE_ARCH_CMPXCHG 1 + +static inline unsigned long __cmpxchg(volatile void *p, unsigned long old, + unsigned long new, int size) +{ + switch (size) { + case 1: + __asm__ __volatile__ ("casb %0,%2,%1" + : "=d" (old), "=m" (*(char *)p) + : "d" (new), "0" (old), "m" (*(char *)p)); + break; + case 2: + __asm__ __volatile__ ("casw %0,%2,%1" + : "=d" (old), "=m" (*(short *)p) + : "d" (new), "0" (old), "m" (*(short *)p)); + break; + case 4: + __asm__ __volatile__ ("casl %0,%2,%1" + : "=d" (old), "=m" (*(int *)p) + : "d" (new), "0" (old), "m" (*(int *)p)); + break; + } + return old; +} + +#define cmpxchg(ptr, o, n) \ + ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \ + (unsigned long)(n), sizeof(*(ptr)))) +#define cmpxchg_local(ptr, o, n) \ + ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \ + (unsigned long)(n), sizeof(*(ptr)))) +#else + +/* + * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make + * them available. + */ +#define cmpxchg_local(ptr, o, n) \ + ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\ + (unsigned long)(n), sizeof(*(ptr)))) + +#ifndef CONFIG_SMP +#include +#endif + +#endif + +#define arch_align_stack(x) (x) + +#endif /* __KERNEL__ */ + +#endif /* _M68K_SYSTEM_H */ diff --git a/arch/m68k/include/asm/system_no.h b/arch/m68k/include/asm/system_no.h new file mode 100644 index 00000000000..40f49de6982 --- /dev/null +++ b/arch/m68k/include/asm/system_no.h @@ -0,0 +1,324 @@ +#ifndef _M68KNOMMU_SYSTEM_H +#define _M68KNOMMU_SYSTEM_H + +#include +#include +#include + +/* + * switch_to(n) should switch tasks to task ptr, first checking that + * ptr isn't the current task, in which case it does nothing. This + * also clears the TS-flag if the task we switched to has used the + * math co-processor latest. + */ +/* + * switch_to() saves the extra registers, that are not saved + * automatically by SAVE_SWITCH_STACK in resume(), ie. d0-d5 and + * a0-a1. Some of these are used by schedule() and its predecessors + * and so we might get see unexpected behaviors when a task returns + * with unexpected register values. + * + * syscall stores these registers itself and none of them are used + * by syscall after the function in the syscall has been called. + * + * Beware that resume now expects *next to be in d1 and the offset of + * tss to be in a1. This saves a few instructions as we no longer have + * to push them onto the stack and read them back right after. + * + * 02/17/96 - Jes Sorensen (jds@kom.auc.dk) + * + * Changed 96/09/19 by Andreas Schwab + * pass prev in a0, next in a1, offset of tss in d1, and whether + * the mm structures are shared in d2 (to avoid atc flushing). + */ +asmlinkage void resume(void); +#define switch_to(prev,next,last) \ +{ \ + void *_last; \ + __asm__ __volatile__( \ + "movel %1, %%a0\n\t" \ + "movel %2, %%a1\n\t" \ + "jbsr resume\n\t" \ + "movel %%d1, %0\n\t" \ + : "=d" (_last) \ + : "d" (prev), "d" (next) \ + : "cc", "d0", "d1", "d2", "d3", "d4", "d5", "a0", "a1"); \ + (last) = _last; \ +} + +#ifdef CONFIG_COLDFIRE +#define local_irq_enable() __asm__ __volatile__ ( \ + "move %/sr,%%d0\n\t" \ + "andi.l #0xf8ff,%%d0\n\t" \ + "move %%d0,%/sr\n" \ + : /* no outputs */ \ + : \ + : "cc", "%d0", "memory") +#define local_irq_disable() __asm__ __volatile__ ( \ + "move %/sr,%%d0\n\t" \ + "ori.l #0x0700,%%d0\n\t" \ + "move %%d0,%/sr\n" \ + : /* no outputs */ \ + : \ + : "cc", "%d0", "memory") +/* For spinlocks etc */ +#define local_irq_save(x) __asm__ __volatile__ ( \ + "movew %%sr,%0\n\t" \ + "movew #0x0700,%%d0\n\t" \ + "or.l %0,%%d0\n\t" \ + "movew %%d0,%/sr" \ + : "=d" (x) \ + : \ + : "cc", "%d0", "memory") +#else + +/* portable version */ /* FIXME - see entry.h*/ +#define ALLOWINT 0xf8ff + +#define local_irq_enable() asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory") +#define local_irq_disable() asm volatile ("oriw #0x0700,%%sr": : : "memory") +#endif + +#define local_save_flags(x) asm volatile ("movew %%sr,%0":"=d" (x) : : "memory") +#define local_irq_restore(x) asm volatile ("movew %0,%%sr": :"d" (x) : "memory") + +/* For spinlocks etc */ +#ifndef local_irq_save +#define local_irq_save(x) do { local_save_flags(x); local_irq_disable(); } while (0) +#endif + +#define irqs_disabled() \ +({ \ + unsigned long flags; \ + local_save_flags(flags); \ + ((flags & 0x0700) == 0x0700); \ +}) + +#define iret() __asm__ __volatile__ ("rte": : :"memory", "sp", "cc") + +/* + * Force strict CPU ordering. + * Not really required on m68k... + */ +#define nop() asm volatile ("nop"::) +#define mb() asm volatile ("" : : :"memory") +#define rmb() asm volatile ("" : : :"memory") +#define wmb() asm volatile ("" : : :"memory") +#define set_mb(var, value) ({ (var) = (value); wmb(); }) + +#ifdef CONFIG_SMP +#define smp_mb() mb() +#define smp_rmb() rmb() +#define smp_wmb() wmb() +#define smp_read_barrier_depends() read_barrier_depends() +#else +#define smp_mb() barrier() +#define smp_rmb() barrier() +#define smp_wmb() barrier() +#define smp_read_barrier_depends() do { } while(0) +#endif + +#define read_barrier_depends() ((void)0) + +#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) + +struct __xchg_dummy { unsigned long a[100]; }; +#define __xg(x) ((volatile struct __xchg_dummy *)(x)) + +#ifndef CONFIG_RMW_INSNS +static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) +{ + unsigned long tmp, flags; + + local_irq_save(flags); + + switch (size) { + case 1: + __asm__ __volatile__ + ("moveb %2,%0\n\t" + "moveb %1,%2" + : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory"); + break; + case 2: + __asm__ __volatile__ + ("movew %2,%0\n\t" + "movew %1,%2" + : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory"); + break; + case 4: + __asm__ __volatile__ + ("movel %2,%0\n\t" + "movel %1,%2" + : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory"); + break; + } + local_irq_restore(flags); + return tmp; +} +#else +static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) +{ + switch (size) { + case 1: + __asm__ __volatile__ + ("moveb %2,%0\n\t" + "1:\n\t" + "casb %0,%1,%2\n\t" + "jne 1b" + : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); + break; + case 2: + __asm__ __volatile__ + ("movew %2,%0\n\t" + "1:\n\t" + "casw %0,%1,%2\n\t" + "jne 1b" + : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); + break; + case 4: + __asm__ __volatile__ + ("movel %2,%0\n\t" + "1:\n\t" + "casl %0,%1,%2\n\t" + "jne 1b" + : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); + break; + } + return x; +} +#endif + +#include + +/* + * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make + * them available. + */ +#define cmpxchg_local(ptr, o, n) \ + ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\ + (unsigned long)(n), sizeof(*(ptr)))) +#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) + +#ifndef CONFIG_SMP +#include +#endif + +#if defined( CONFIG_M68328 ) || defined( CONFIG_M68EZ328 ) || \ + defined (CONFIG_M68360) || defined( CONFIG_M68VZ328 ) +#define HARD_RESET_NOW() ({ \ + local_irq_disable(); \ + asm(" \ + moveal #0x10c00000, %a0; \ + moveb #0, 0xFFFFF300; \ + moveal 0(%a0), %sp; \ + moveal 4(%a0), %a0; \ + jmp (%a0); \ + "); \ +}) +#endif + +#ifdef CONFIG_COLDFIRE +#if defined(CONFIG_M5272) && defined(CONFIG_NETtel) +/* + * Need to account for broken early mask of 5272 silicon. So don't + * jump through the original start address. Jump strait into the + * known start of the FLASH code. + */ +#define HARD_RESET_NOW() ({ \ + asm(" \ + movew #0x2700, %sr; \ + jmp 0xf0000400; \ + "); \ +}) +#elif defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \ + defined(CONFIG_SECUREEDGEMP3) || defined(CONFIG_CLEOPATRA) +#define HARD_RESET_NOW() ({ \ + asm(" \ + movew #0x2700, %sr; \ + moveal #0x10000044, %a0; \ + movel #0xffffffff, (%a0); \ + moveal #0x10000001, %a0; \ + moveb #0x00, (%a0); \ + moveal #0xf0000004, %a0; \ + moveal (%a0), %a0; \ + jmp (%a0); \ + "); \ +}) +#elif defined(CONFIG_M5272) +/* + * Retrieve the boot address in flash using CSBR0 and CSOR0 + * find the reset vector at flash_address + 4 (e.g. 0x400) + * remap it in the flash's current location (e.g. 0xf0000400) + * and jump there. + */ +#define HARD_RESET_NOW() ({ \ + asm(" \ + movew #0x2700, %%sr; \ + move.l %0+0x40,%%d0; \ + and.l %0+0x44,%%d0; \ + andi.l #0xfffff000,%%d0; \ + mov.l %%d0,%%a0; \ + or.l 4(%%a0),%%d0; \ + mov.l %%d0,%%a0; \ + jmp (%%a0);" \ + : /* No output */ \ + : "o" (*(char *)MCF_MBAR) ); \ +}) +#elif defined(CONFIG_M528x) +/* + * The MCF528x has a bit (SOFTRST) in memory (Reset Control Register RCR), + * that when set, resets the MCF528x. + */ +#define HARD_RESET_NOW() \ +({ \ + unsigned char volatile *reset; \ + asm("move.w #0x2700, %sr"); \ + reset = ((volatile unsigned char *)(MCF_IPSBAR + 0x110000)); \ + while(1) \ + *reset |= (0x01 << 7);\ +}) +#elif defined(CONFIG_M523x) +#define HARD_RESET_NOW() ({ \ + asm(" \ + movew #0x2700, %sr; \ + movel #0x01000000, %sp; \ + moveal #0x40110000, %a0; \ + moveb #0x80, (%a0); \ + "); \ +}) +#elif defined(CONFIG_M520x) + /* + * The MCF5208 has a bit (SOFTRST) in memory (Reset Control Register + * RCR), that when set, resets the MCF5208. + */ +#define HARD_RESET_NOW() \ +({ \ + unsigned char volatile *reset; \ + asm("move.w #0x2700, %sr"); \ + reset = ((volatile unsigned char *)(MCF_IPSBAR + 0xA0000)); \ + while(1) \ + *reset |= 0x80; \ +}) +#else +#define HARD_RESET_NOW() ({ \ + asm(" \ + movew #0x2700, %sr; \ + moveal #0x4, %a0; \ + moveal (%a0), %a0; \ + jmp (%a0); \ + "); \ +}) +#endif +#endif +#define arch_align_stack(x) (x) + + +static inline int irqs_disabled_flags(unsigned long flags) +{ + if (flags & 0x0700) + return 0; + else + return 1; +} + +#endif /* _M68KNOMMU_SYSTEM_H */ diff --git a/arch/m68k/include/asm/termbits.h b/arch/m68k/include/asm/termbits.h new file mode 100644 index 00000000000..8c14170996b --- /dev/null +++ b/arch/m68k/include/asm/termbits.h @@ -0,0 +1,200 @@ +#ifndef __ARCH_M68K_TERMBITS_H__ +#define __ARCH_M68K_TERMBITS_H__ + +#include + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned int tcflag_t; + +#define NCCS 19 +struct termios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ +}; + +struct termios2 { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + +/* c_cc characters */ +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VTIME 5 +#define VMIN 6 +#define VSWTC 7 +#define VSTART 8 +#define VSTOP 9 +#define VSUSP 10 +#define VEOL 11 +#define VREPRINT 12 +#define VDISCARD 13 +#define VWERASE 14 +#define VLNEXT 15 +#define VEOL2 16 + + +/* c_iflag bits */ +#define IGNBRK 0000001 +#define BRKINT 0000002 +#define IGNPAR 0000004 +#define PARMRK 0000010 +#define INPCK 0000020 +#define ISTRIP 0000040 +#define INLCR 0000100 +#define IGNCR 0000200 +#define ICRNL 0000400 +#define IUCLC 0001000 +#define IXON 0002000 +#define IXANY 0004000 +#define IXOFF 0010000 +#define IMAXBEL 0020000 +#define IUTF8 0040000 + +/* c_oflag bits */ +#define OPOST 0000001 +#define OLCUC 0000002 +#define ONLCR 0000004 +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 +#define OFILL 0000100 +#define OFDEL 0000200 +#define NLDLY 0000400 +#define NL0 0000000 +#define NL1 0000400 +#define CRDLY 0003000 +#define CR0 0000000 +#define CR1 0001000 +#define CR2 0002000 +#define CR3 0003000 +#define TABDLY 0014000 +#define TAB0 0000000 +#define TAB1 0004000 +#define TAB2 0010000 +#define TAB3 0014000 +#define XTABS 0014000 +#define BSDLY 0020000 +#define BS0 0000000 +#define BS1 0020000 +#define VTDLY 0040000 +#define VT0 0000000 +#define VT1 0040000 +#define FFDLY 0100000 +#define FF0 0000000 +#define FF1 0100000 + +/* c_cflag bit meaning */ +#define CBAUD 0010017 +#define B0 0000000 /* hang up */ +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +#define EXTA B19200 +#define EXTB B38400 +#define CSIZE 0000060 +#define CS5 0000000 +#define CS6 0000020 +#define CS7 0000040 +#define CS8 0000060 +#define CSTOPB 0000100 +#define CREAD 0000200 +#define PARENB 0000400 +#define PARODD 0001000 +#define HUPCL 0002000 +#define CLOCAL 0004000 +#define CBAUDEX 0010000 +#define BOTHER 0010000 +#define B57600 0010001 +#define B115200 0010002 +#define B230400 0010003 +#define B460800 0010004 +#define B500000 0010005 +#define B576000 0010006 +#define B921600 0010007 +#define B1000000 0010010 +#define B1152000 0010011 +#define B1500000 0010012 +#define B2000000 0010013 +#define B2500000 0010014 +#define B3000000 0010015 +#define B3500000 0010016 +#define B4000000 0010017 +#define CIBAUD 002003600000 /* input baud rate */ +#define CMSPAR 010000000000 /* mark or space (stick) parity */ +#define CRTSCTS 020000000000 /* flow control */ + +#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ + +/* c_lflag bits */ +#define ISIG 0000001 +#define ICANON 0000002 +#define XCASE 0000004 +#define ECHO 0000010 +#define ECHOE 0000020 +#define ECHOK 0000040 +#define ECHONL 0000100 +#define NOFLSH 0000200 +#define TOSTOP 0000400 +#define ECHOCTL 0001000 +#define ECHOPRT 0002000 +#define ECHOKE 0004000 +#define FLUSHO 0010000 +#define PENDIN 0040000 +#define IEXTEN 0100000 + + +/* tcflow() and TCXONC use these */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* tcflush() and TCFLSH use these */ +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* tcsetattr uses these */ +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + +#endif /* __ARCH_M68K_TERMBITS_H__ */ diff --git a/arch/m68k/include/asm/termios.h b/arch/m68k/include/asm/termios.h new file mode 100644 index 00000000000..0823032e404 --- /dev/null +++ b/arch/m68k/include/asm/termios.h @@ -0,0 +1,92 @@ +#ifndef _M68K_TERMIOS_H +#define _M68K_TERMIOS_H + +#include +#include + +struct winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; + +#define NCC 8 +struct termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[NCC]; /* control characters */ +}; + +#ifdef __KERNEL__ +/* intr=^C quit=^| erase=del kill=^U + eof=^D vtime=\0 vmin=\1 sxtc=\0 + start=^Q stop=^S susp=^Z eol=\0 + reprint=^R discard=^U werase=^W lnext=^V + eol2=\0 +*/ +#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" +#endif + +/* modem lines */ +#define TIOCM_LE 0x001 +#define TIOCM_DTR 0x002 +#define TIOCM_RTS 0x004 +#define TIOCM_ST 0x008 +#define TIOCM_SR 0x010 +#define TIOCM_CTS 0x020 +#define TIOCM_CAR 0x040 +#define TIOCM_RNG 0x080 +#define TIOCM_DSR 0x100 +#define TIOCM_CD TIOCM_CAR +#define TIOCM_RI TIOCM_RNG +#define TIOCM_OUT1 0x2000 +#define TIOCM_OUT2 0x4000 +#define TIOCM_LOOP 0x8000 + +/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ + +#ifdef __KERNEL__ + +/* + * Translate a "termio" structure into a "termios". Ugh. + */ +#define user_termio_to_kernel_termios(termios, termio) \ +({ \ + unsigned short tmp; \ + get_user(tmp, &(termio)->c_iflag); \ + (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \ + get_user(tmp, &(termio)->c_oflag); \ + (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \ + get_user(tmp, &(termio)->c_cflag); \ + (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \ + get_user(tmp, &(termio)->c_lflag); \ + (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \ + get_user((termios)->c_line, &(termio)->c_line); \ + copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ +}) + +/* + * Translate a "termios" structure into a "termio". Ugh. + */ +#define kernel_termios_to_user_termio(termio, termios) \ +({ \ + put_user((termios)->c_iflag, &(termio)->c_iflag); \ + put_user((termios)->c_oflag, &(termio)->c_oflag); \ + put_user((termios)->c_cflag, &(termio)->c_cflag); \ + put_user((termios)->c_lflag, &(termio)->c_lflag); \ + put_user((termios)->c_line, &(termio)->c_line); \ + copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ +}) + +#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2)) +#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2)) +#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios)) +#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios)) + +#endif /* __KERNEL__ */ + +#endif /* _M68K_TERMIOS_H */ diff --git a/arch/m68k/include/asm/thread_info.h b/arch/m68k/include/asm/thread_info.h new file mode 100644 index 00000000000..f31a3f42b7b --- /dev/null +++ b/arch/m68k/include/asm/thread_info.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "thread_info_no.h" +#else +#include "thread_info_mm.h" +#endif diff --git a/arch/m68k/include/asm/thread_info_mm.h b/arch/m68k/include/asm/thread_info_mm.h new file mode 100644 index 00000000000..af0fda46e94 --- /dev/null +++ b/arch/m68k/include/asm/thread_info_mm.h @@ -0,0 +1,57 @@ +#ifndef _ASM_M68K_THREAD_INFO_H +#define _ASM_M68K_THREAD_INFO_H + +#include +#include + +struct thread_info { + struct task_struct *task; /* main task structure */ + unsigned long flags; + struct exec_domain *exec_domain; /* execution domain */ + int preempt_count; /* 0 => preemptable, <0 => BUG */ + __u32 cpu; /* should always be 0 on m68k */ + struct restart_block restart_block; +}; + +#define PREEMPT_ACTIVE 0x4000000 + +#define INIT_THREAD_INFO(tsk) \ +{ \ + .task = &tsk, \ + .exec_domain = &default_exec_domain, \ + .restart_block = { \ + .fn = do_no_restart_syscall, \ + }, \ +} + +/* THREAD_SIZE should be 8k, so handle differently for 4k and 8k machines */ +#define THREAD_SIZE_ORDER (13 - PAGE_SHIFT) + +#define init_thread_info (init_task.thread.info) +#define init_stack (init_thread_union.stack) + +#define task_thread_info(tsk) (&(tsk)->thread.info) +#define task_stack_page(tsk) ((tsk)->stack) +#define current_thread_info() task_thread_info(current) + +#define __HAVE_THREAD_FUNCTIONS + +#define setup_thread_stack(p, org) ({ \ + *(struct task_struct **)(p)->stack = (p); \ + task_thread_info(p)->task = (p); \ +}) + +#define end_of_stack(p) ((unsigned long *)(p)->stack + 1) + +/* entry.S relies on these definitions! + * bits 0-7 are tested at every exception exit + * bits 8-15 are also tested at syscall exit + */ +#define TIF_SIGPENDING 6 /* signal pending */ +#define TIF_NEED_RESCHED 7 /* rescheduling necessary */ +#define TIF_DELAYED_TRACE 14 /* single step a syscall */ +#define TIF_SYSCALL_TRACE 15 /* syscall trace active */ +#define TIF_MEMDIE 16 +#define TIF_FREEZE 17 /* thread is freezing for suspend */ + +#endif /* _ASM_M68K_THREAD_INFO_H */ diff --git a/arch/m68k/include/asm/thread_info_no.h b/arch/m68k/include/asm/thread_info_no.h new file mode 100644 index 00000000000..82529f424ea --- /dev/null +++ b/arch/m68k/include/asm/thread_info_no.h @@ -0,0 +1,100 @@ +/* thread_info.h: m68knommu low-level thread information + * adapted from the i386 and PPC versions by Greg Ungerer (gerg@snapgear.com) + * + * Copyright (C) 2002 David Howells (dhowells@redhat.com) + * - Incorporating suggestions made by Linus Torvalds and Dave Miller + */ + +#ifndef _ASM_THREAD_INFO_H +#define _ASM_THREAD_INFO_H + +#include + +#ifdef __KERNEL__ + +#ifndef __ASSEMBLY__ + +/* + * Size of kernel stack for each process. This must be a power of 2... + */ +#ifdef CONFIG_4KSTACKS +#define THREAD_SIZE_ORDER (0) +#else +#define THREAD_SIZE_ORDER (1) +#endif + +/* + * for asm files, THREAD_SIZE is now generated by asm-offsets.c + */ +#define THREAD_SIZE (PAGE_SIZE< preemptable, <0 => BUG */ + struct restart_block restart_block; +}; + +/* + * macros/functions for gaining access to the thread information structure + */ +#define INIT_THREAD_INFO(tsk) \ +{ \ + .task = &tsk, \ + .exec_domain = &default_exec_domain, \ + .flags = 0, \ + .cpu = 0, \ + .restart_block = { \ + .fn = do_no_restart_syscall, \ + }, \ +} + +#define init_thread_info (init_thread_union.thread_info) +#define init_stack (init_thread_union.stack) + + +/* how to get the thread information struct from C */ +static inline struct thread_info *current_thread_info(void) +{ + struct thread_info *ti; + __asm__( + "move.l %%sp, %0 \n\t" + "and.l %1, %0" + : "=&d"(ti) + : "di" (~(THREAD_SIZE-1)) + ); + return ti; +} + +#endif /* __ASSEMBLY__ */ + +#define PREEMPT_ACTIVE 0x4000000 + +/* + * thread information flag bit numbers + */ +#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ +#define TIF_SIGPENDING 1 /* signal pending */ +#define TIF_NEED_RESCHED 2 /* rescheduling necessary */ +#define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling + TIF_NEED_RESCHED */ +#define TIF_MEMDIE 4 +#define TIF_FREEZE 16 /* is freezing for suspend */ + +/* as above, but as bit values */ +#define _TIF_SYSCALL_TRACE (1< +#define CLOCK_TICK_RATE MCF_CLK +#else +#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ +#endif + +typedef unsigned long cycles_t; + +static inline cycles_t get_cycles(void) +{ + return 0; +} + +#endif diff --git a/arch/m68k/include/asm/tlb.h b/arch/m68k/include/asm/tlb.h new file mode 100644 index 00000000000..1785cff7344 --- /dev/null +++ b/arch/m68k/include/asm/tlb.h @@ -0,0 +1,20 @@ +#ifndef _M68K_TLB_H +#define _M68K_TLB_H + +/* + * m68k doesn't need any special per-pte or + * per-vma handling.. + */ +#define tlb_start_vma(tlb, vma) do { } while (0) +#define tlb_end_vma(tlb, vma) do { } while (0) +#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0) + +/* + * .. because we flush the whole mm when it + * fills up. + */ +#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm) + +#include + +#endif /* _M68K_TLB_H */ diff --git a/arch/m68k/include/asm/tlbflush.h b/arch/m68k/include/asm/tlbflush.h new file mode 100644 index 00000000000..b6f93b30951 --- /dev/null +++ b/arch/m68k/include/asm/tlbflush.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "tlbflush_no.h" +#else +#include "tlbflush_mm.h" +#endif diff --git a/arch/m68k/include/asm/tlbflush_mm.h b/arch/m68k/include/asm/tlbflush_mm.h new file mode 100644 index 00000000000..acb6bf21a32 --- /dev/null +++ b/arch/m68k/include/asm/tlbflush_mm.h @@ -0,0 +1,219 @@ +#ifndef _M68K_TLBFLUSH_H +#define _M68K_TLBFLUSH_H + + +#ifndef CONFIG_SUN3 + +#include + +static inline void flush_tlb_kernel_page(void *addr) +{ + if (CPU_IS_040_OR_060) { + mm_segment_t old_fs = get_fs(); + set_fs(KERNEL_DS); + __asm__ __volatile__(".chip 68040\n\t" + "pflush (%0)\n\t" + ".chip 68k" + : : "a" (addr)); + set_fs(old_fs); + } else if (CPU_IS_020_OR_030) + __asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr)); +} + +/* + * flush all user-space atc entries. + */ +static inline void __flush_tlb(void) +{ + if (CPU_IS_040_OR_060) + __asm__ __volatile__(".chip 68040\n\t" + "pflushan\n\t" + ".chip 68k"); + else if (CPU_IS_020_OR_030) + __asm__ __volatile__("pflush #0,#4"); +} + +static inline void __flush_tlb040_one(unsigned long addr) +{ + __asm__ __volatile__(".chip 68040\n\t" + "pflush (%0)\n\t" + ".chip 68k" + : : "a" (addr)); +} + +static inline void __flush_tlb_one(unsigned long addr) +{ + if (CPU_IS_040_OR_060) + __flush_tlb040_one(addr); + else if (CPU_IS_020_OR_030) + __asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr)); +} + +#define flush_tlb() __flush_tlb() + +/* + * flush all atc entries (both kernel and user-space entries). + */ +static inline void flush_tlb_all(void) +{ + if (CPU_IS_040_OR_060) + __asm__ __volatile__(".chip 68040\n\t" + "pflusha\n\t" + ".chip 68k"); + else if (CPU_IS_020_OR_030) + __asm__ __volatile__("pflusha"); +} + +static inline void flush_tlb_mm(struct mm_struct *mm) +{ + if (mm == current->active_mm) + __flush_tlb(); +} + +static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) +{ + if (vma->vm_mm == current->active_mm) { + mm_segment_t old_fs = get_fs(); + set_fs(USER_DS); + __flush_tlb_one(addr); + set_fs(old_fs); + } +} + +static inline void flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ + if (vma->vm_mm == current->active_mm) + __flush_tlb(); +} + +static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + flush_tlb_all(); +} + +#else + + +/* Reserved PMEGs. */ +extern char sun3_reserved_pmeg[SUN3_PMEGS_NUM]; +extern unsigned long pmeg_vaddr[SUN3_PMEGS_NUM]; +extern unsigned char pmeg_alloc[SUN3_PMEGS_NUM]; +extern unsigned char pmeg_ctx[SUN3_PMEGS_NUM]; + +/* Flush all userspace mappings one by one... (why no flush command, + sun?) */ +static inline void flush_tlb_all(void) +{ + unsigned long addr; + unsigned char ctx, oldctx; + + oldctx = sun3_get_context(); + for(addr = 0x00000000; addr < TASK_SIZE; addr += SUN3_PMEG_SIZE) { + for(ctx = 0; ctx < 8; ctx++) { + sun3_put_context(ctx); + sun3_put_segmap(addr, SUN3_INVALID_PMEG); + } + } + + sun3_put_context(oldctx); + /* erase all of the userspace pmeg maps, we've clobbered them + all anyway */ + for(addr = 0; addr < SUN3_INVALID_PMEG; addr++) { + if(pmeg_alloc[addr] == 1) { + pmeg_alloc[addr] = 0; + pmeg_ctx[addr] = 0; + pmeg_vaddr[addr] = 0; + } + } + +} + +/* Clear user TLB entries within the context named in mm */ +static inline void flush_tlb_mm (struct mm_struct *mm) +{ + unsigned char oldctx; + unsigned char seg; + unsigned long i; + + oldctx = sun3_get_context(); + sun3_put_context(mm->context); + + for(i = 0; i < TASK_SIZE; i += SUN3_PMEG_SIZE) { + seg = sun3_get_segmap(i); + if(seg == SUN3_INVALID_PMEG) + continue; + + sun3_put_segmap(i, SUN3_INVALID_PMEG); + pmeg_alloc[seg] = 0; + pmeg_ctx[seg] = 0; + pmeg_vaddr[seg] = 0; + } + + sun3_put_context(oldctx); + +} + +/* Flush a single TLB page. In this case, we're limited to flushing a + single PMEG */ +static inline void flush_tlb_page (struct vm_area_struct *vma, + unsigned long addr) +{ + unsigned char oldctx; + unsigned char i; + + oldctx = sun3_get_context(); + sun3_put_context(vma->vm_mm->context); + addr &= ~SUN3_PMEG_MASK; + if((i = sun3_get_segmap(addr)) != SUN3_INVALID_PMEG) + { + pmeg_alloc[i] = 0; + pmeg_ctx[i] = 0; + pmeg_vaddr[i] = 0; + sun3_put_segmap (addr, SUN3_INVALID_PMEG); + } + sun3_put_context(oldctx); + +} +/* Flush a range of pages from TLB. */ + +static inline void flush_tlb_range (struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + unsigned char seg, oldctx; + + start &= ~SUN3_PMEG_MASK; + + oldctx = sun3_get_context(); + sun3_put_context(mm->context); + + while(start < end) + { + if((seg = sun3_get_segmap(start)) == SUN3_INVALID_PMEG) + goto next; + if(pmeg_ctx[seg] == mm->context) { + pmeg_alloc[seg] = 0; + pmeg_ctx[seg] = 0; + pmeg_vaddr[seg] = 0; + } + sun3_put_segmap(start, SUN3_INVALID_PMEG); + next: + start += SUN3_PMEG_SIZE; + } +} + +static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + flush_tlb_all(); +} + +/* Flush kernel page from TLB. */ +static inline void flush_tlb_kernel_page (unsigned long addr) +{ + sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG); +} + +#endif + +#endif /* _M68K_TLBFLUSH_H */ diff --git a/arch/m68k/include/asm/tlbflush_no.h b/arch/m68k/include/asm/tlbflush_no.h new file mode 100644 index 00000000000..a470cfb803e --- /dev/null +++ b/arch/m68k/include/asm/tlbflush_no.h @@ -0,0 +1,55 @@ +#ifndef _M68KNOMMU_TLBFLUSH_H +#define _M68KNOMMU_TLBFLUSH_H + +/* + * Copyright (C) 2000 Lineo, David McCullough + * Copyright (C) 2000-2002, Greg Ungerer + */ + +#include + +/* + * flush all user-space atc entries. + */ +static inline void __flush_tlb(void) +{ + BUG(); +} + +static inline void __flush_tlb_one(unsigned long addr) +{ + BUG(); +} + +#define flush_tlb() __flush_tlb() + +/* + * flush all atc entries (both kernel and user-space entries). + */ +static inline void flush_tlb_all(void) +{ + BUG(); +} + +static inline void flush_tlb_mm(struct mm_struct *mm) +{ + BUG(); +} + +static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) +{ + BUG(); +} + +static inline void flush_tlb_range(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + BUG(); +} + +static inline void flush_tlb_kernel_page(unsigned long addr) +{ + BUG(); +} + +#endif /* _M68KNOMMU_TLBFLUSH_H */ diff --git a/arch/m68k/include/asm/topology.h b/arch/m68k/include/asm/topology.h new file mode 100644 index 00000000000..ca173e9f26f --- /dev/null +++ b/arch/m68k/include/asm/topology.h @@ -0,0 +1,6 @@ +#ifndef _ASM_M68K_TOPOLOGY_H +#define _ASM_M68K_TOPOLOGY_H + +#include + +#endif /* _ASM_M68K_TOPOLOGY_H */ diff --git a/arch/m68k/include/asm/traps.h b/arch/m68k/include/asm/traps.h new file mode 100644 index 00000000000..3011ec0f536 --- /dev/null +++ b/arch/m68k/include/asm/traps.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "traps_no.h" +#else +#include "traps_mm.h" +#endif diff --git a/arch/m68k/include/asm/traps_mm.h b/arch/m68k/include/asm/traps_mm.h new file mode 100644 index 00000000000..8caef25624c --- /dev/null +++ b/arch/m68k/include/asm/traps_mm.h @@ -0,0 +1,272 @@ +/* + * linux/include/asm/traps.h + * + * Copyright (C) 1993 Hamish Macdonald + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#ifndef _M68K_TRAPS_H +#define _M68K_TRAPS_H + +#ifndef __ASSEMBLY__ + +#include +#include + +typedef void (*e_vector)(void); + +asmlinkage void auto_inthandler(void); +asmlinkage void user_inthandler(void); +asmlinkage void bad_inthandler(void); + +extern e_vector vectors[]; + +#endif + +#define VEC_RESETSP (0) +#define VEC_RESETPC (1) +#define VEC_BUSERR (2) +#define VEC_ADDRERR (3) +#define VEC_ILLEGAL (4) +#define VEC_ZERODIV (5) +#define VEC_CHK (6) +#define VEC_TRAP (7) +#define VEC_PRIV (8) +#define VEC_TRACE (9) +#define VEC_LINE10 (10) +#define VEC_LINE11 (11) +#define VEC_RESV12 (12) +#define VEC_COPROC (13) +#define VEC_FORMAT (14) +#define VEC_UNINT (15) +#define VEC_RESV16 (16) +#define VEC_RESV17 (17) +#define VEC_RESV18 (18) +#define VEC_RESV19 (19) +#define VEC_RESV20 (20) +#define VEC_RESV21 (21) +#define VEC_RESV22 (22) +#define VEC_RESV23 (23) +#define VEC_SPUR (24) +#define VEC_INT1 (25) +#define VEC_INT2 (26) +#define VEC_INT3 (27) +#define VEC_INT4 (28) +#define VEC_INT5 (29) +#define VEC_INT6 (30) +#define VEC_INT7 (31) +#define VEC_SYS (32) +#define VEC_TRAP1 (33) +#define VEC_TRAP2 (34) +#define VEC_TRAP3 (35) +#define VEC_TRAP4 (36) +#define VEC_TRAP5 (37) +#define VEC_TRAP6 (38) +#define VEC_TRAP7 (39) +#define VEC_TRAP8 (40) +#define VEC_TRAP9 (41) +#define VEC_TRAP10 (42) +#define VEC_TRAP11 (43) +#define VEC_TRAP12 (44) +#define VEC_TRAP13 (45) +#define VEC_TRAP14 (46) +#define VEC_TRAP15 (47) +#define VEC_FPBRUC (48) +#define VEC_FPIR (49) +#define VEC_FPDIVZ (50) +#define VEC_FPUNDER (51) +#define VEC_FPOE (52) +#define VEC_FPOVER (53) +#define VEC_FPNAN (54) +#define VEC_FPUNSUP (55) +#define VEC_MMUCFG (56) +#define VEC_MMUILL (57) +#define VEC_MMUACC (58) +#define VEC_RESV59 (59) +#define VEC_UNIMPEA (60) +#define VEC_UNIMPII (61) +#define VEC_RESV62 (62) +#define VEC_RESV63 (63) +#define VEC_USER (64) + +#define VECOFF(vec) ((vec)<<2) + +#ifndef __ASSEMBLY__ + +/* Status register bits */ +#define PS_T (0x8000) +#define PS_S (0x2000) +#define PS_M (0x1000) +#define PS_C (0x0001) + +/* bits for 68020/68030 special status word */ + +#define FC (0x8000) +#define FB (0x4000) +#define RC (0x2000) +#define RB (0x1000) +#define DF (0x0100) +#define RM (0x0080) +#define RW (0x0040) +#define SZ (0x0030) +#define DFC (0x0007) + +/* bits for 68030 MMU status register (mmusr,psr) */ + +#define MMU_B (0x8000) /* bus error */ +#define MMU_L (0x4000) /* limit violation */ +#define MMU_S (0x2000) /* supervisor violation */ +#define MMU_WP (0x0800) /* write-protected */ +#define MMU_I (0x0400) /* invalid descriptor */ +#define MMU_M (0x0200) /* ATC entry modified */ +#define MMU_T (0x0040) /* transparent translation */ +#define MMU_NUM (0x0007) /* number of levels traversed */ + + +/* bits for 68040 special status word */ +#define CP_040 (0x8000) +#define CU_040 (0x4000) +#define CT_040 (0x2000) +#define CM_040 (0x1000) +#define MA_040 (0x0800) +#define ATC_040 (0x0400) +#define LK_040 (0x0200) +#define RW_040 (0x0100) +#define SIZ_040 (0x0060) +#define TT_040 (0x0018) +#define TM_040 (0x0007) + +/* bits for 68040 write back status word */ +#define WBV_040 (0x80) +#define WBSIZ_040 (0x60) +#define WBBYT_040 (0x20) +#define WBWRD_040 (0x40) +#define WBLNG_040 (0x00) +#define WBTT_040 (0x18) +#define WBTM_040 (0x07) + +/* bus access size codes */ +#define BA_SIZE_BYTE (0x20) +#define BA_SIZE_WORD (0x40) +#define BA_SIZE_LONG (0x00) +#define BA_SIZE_LINE (0x60) + +/* bus access transfer type codes */ +#define BA_TT_MOVE16 (0x08) + +/* bits for 68040 MMU status register (mmusr) */ +#define MMU_B_040 (0x0800) +#define MMU_G_040 (0x0400) +#define MMU_S_040 (0x0080) +#define MMU_CM_040 (0x0060) +#define MMU_M_040 (0x0010) +#define MMU_WP_040 (0x0004) +#define MMU_T_040 (0x0002) +#define MMU_R_040 (0x0001) + +/* bits in the 68060 fault status long word (FSLW) */ +#define MMU060_MA (0x08000000) /* misaligned */ +#define MMU060_LK (0x02000000) /* locked transfer */ +#define MMU060_RW (0x01800000) /* read/write */ +# define MMU060_RW_W (0x00800000) /* write */ +# define MMU060_RW_R (0x01000000) /* read */ +# define MMU060_RW_RMW (0x01800000) /* read/modify/write */ +# define MMU060_W (0x00800000) /* general write, includes rmw */ +#define MMU060_SIZ (0x00600000) /* transfer size */ +#define MMU060_TT (0x00180000) /* transfer type (TT) bits */ +#define MMU060_TM (0x00070000) /* transfer modifier (TM) bits */ +#define MMU060_IO (0x00008000) /* instruction or operand */ +#define MMU060_PBE (0x00004000) /* push buffer bus error */ +#define MMU060_SBE (0x00002000) /* store buffer bus error */ +#define MMU060_PTA (0x00001000) /* pointer A fault */ +#define MMU060_PTB (0x00000800) /* pointer B fault */ +#define MMU060_IL (0x00000400) /* double indirect descr fault */ +#define MMU060_PF (0x00000200) /* page fault (invalid descr) */ +#define MMU060_SP (0x00000100) /* supervisor protection */ +#define MMU060_WP (0x00000080) /* write protection */ +#define MMU060_TWE (0x00000040) /* bus error on table search */ +#define MMU060_RE (0x00000020) /* bus error on read */ +#define MMU060_WE (0x00000010) /* bus error on write */ +#define MMU060_TTR (0x00000008) /* error caused by TTR translation */ +#define MMU060_BPE (0x00000004) /* branch prediction error */ +#define MMU060_SEE (0x00000001) /* software emulated error */ + +/* cases of missing or invalid descriptors */ +#define MMU060_DESC_ERR (MMU060_PTA | MMU060_PTB | \ + MMU060_IL | MMU060_PF) +/* bits that indicate real errors */ +#define MMU060_ERR_BITS (MMU060_PBE | MMU060_SBE | MMU060_DESC_ERR | MMU060_SP | \ + MMU060_WP | MMU060_TWE | MMU060_RE | MMU060_WE) + +/* structure for stack frames */ + +struct frame { + struct pt_regs ptregs; + union { + struct { + unsigned long iaddr; /* instruction address */ + } fmt2; + struct { + unsigned long effaddr; /* effective address */ + } fmt3; + struct { + unsigned long effaddr; /* effective address */ + unsigned long pc; /* pc of faulted instr */ + } fmt4; + struct { + unsigned long effaddr; /* effective address */ + unsigned short ssw; /* special status word */ + unsigned short wb3s; /* write back 3 status */ + unsigned short wb2s; /* write back 2 status */ + unsigned short wb1s; /* write back 1 status */ + unsigned long faddr; /* fault address */ + unsigned long wb3a; /* write back 3 address */ + unsigned long wb3d; /* write back 3 data */ + unsigned long wb2a; /* write back 2 address */ + unsigned long wb2d; /* write back 2 data */ + unsigned long wb1a; /* write back 1 address */ + unsigned long wb1dpd0; /* write back 1 data/push data 0*/ + unsigned long pd1; /* push data 1*/ + unsigned long pd2; /* push data 2*/ + unsigned long pd3; /* push data 3*/ + } fmt7; + struct { + unsigned long iaddr; /* instruction address */ + unsigned short int1[4]; /* internal registers */ + } fmt9; + struct { + unsigned short int1; + unsigned short ssw; /* special status word */ + unsigned short isc; /* instruction stage c */ + unsigned short isb; /* instruction stage b */ + unsigned long daddr; /* data cycle fault address */ + unsigned short int2[2]; + unsigned long dobuf; /* data cycle output buffer */ + unsigned short int3[2]; + } fmta; + struct { + unsigned short int1; + unsigned short ssw; /* special status word */ + unsigned short isc; /* instruction stage c */ + unsigned short isb; /* instruction stage b */ + unsigned long daddr; /* data cycle fault address */ + unsigned short int2[2]; + unsigned long dobuf; /* data cycle output buffer */ + unsigned short int3[4]; + unsigned long baddr; /* stage B address */ + unsigned short int4[2]; + unsigned long dibuf; /* data cycle input buffer */ + unsigned short int5[3]; + unsigned ver : 4; /* stack frame version # */ + unsigned int6:12; + unsigned short int7[18]; + } fmtb; + } un; +}; + +#endif /* __ASSEMBLY__ */ + +#endif /* _M68K_TRAPS_H */ diff --git a/arch/m68k/include/asm/traps_no.h b/arch/m68k/include/asm/traps_no.h new file mode 100644 index 00000000000..d0671e5f8e2 --- /dev/null +++ b/arch/m68k/include/asm/traps_no.h @@ -0,0 +1,154 @@ +/* + * linux/include/asm/traps.h + * + * Copyright (C) 1993 Hamish Macdonald + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#ifndef _M68KNOMMU_TRAPS_H +#define _M68KNOMMU_TRAPS_H + +#ifndef __ASSEMBLY__ + +typedef void (*e_vector)(void); + +extern e_vector vectors[]; +extern void init_vectors(void); +extern void enable_vector(unsigned int irq); +extern void disable_vector(unsigned int irq); +extern void ack_vector(unsigned int irq); + +#endif + +#define VEC_BUSERR (2) +#define VEC_ADDRERR (3) +#define VEC_ILLEGAL (4) +#define VEC_ZERODIV (5) +#define VEC_CHK (6) +#define VEC_TRAP (7) +#define VEC_PRIV (8) +#define VEC_TRACE (9) +#define VEC_LINE10 (10) +#define VEC_LINE11 (11) +#define VEC_RESV1 (12) +#define VEC_COPROC (13) +#define VEC_FORMAT (14) +#define VEC_UNINT (15) +#define VEC_SPUR (24) +#define VEC_INT1 (25) +#define VEC_INT2 (26) +#define VEC_INT3 (27) +#define VEC_INT4 (28) +#define VEC_INT5 (29) +#define VEC_INT6 (30) +#define VEC_INT7 (31) +#define VEC_SYS (32) +#define VEC_TRAP1 (33) +#define VEC_TRAP2 (34) +#define VEC_TRAP3 (35) +#define VEC_TRAP4 (36) +#define VEC_TRAP5 (37) +#define VEC_TRAP6 (38) +#define VEC_TRAP7 (39) +#define VEC_TRAP8 (40) +#define VEC_TRAP9 (41) +#define VEC_TRAP10 (42) +#define VEC_TRAP11 (43) +#define VEC_TRAP12 (44) +#define VEC_TRAP13 (45) +#define VEC_TRAP14 (46) +#define VEC_TRAP15 (47) +#define VEC_FPBRUC (48) +#define VEC_FPIR (49) +#define VEC_FPDIVZ (50) +#define VEC_FPUNDER (51) +#define VEC_FPOE (52) +#define VEC_FPOVER (53) +#define VEC_FPNAN (54) +#define VEC_FPUNSUP (55) +#define VEC_UNIMPEA (60) +#define VEC_UNIMPII (61) +#define VEC_USER (64) + +#define VECOFF(vec) ((vec)<<2) + +#ifndef __ASSEMBLY__ + +/* Status register bits */ +#define PS_T (0x8000) +#define PS_S (0x2000) +#define PS_M (0x1000) +#define PS_C (0x0001) + +/* structure for stack frames */ + +struct frame { + struct pt_regs ptregs; + union { + struct { + unsigned long iaddr; /* instruction address */ + } fmt2; + struct { + unsigned long effaddr; /* effective address */ + } fmt3; + struct { + unsigned long effaddr; /* effective address */ + unsigned long pc; /* pc of faulted instr */ + } fmt4; + struct { + unsigned long effaddr; /* effective address */ + unsigned short ssw; /* special status word */ + unsigned short wb3s; /* write back 3 status */ + unsigned short wb2s; /* write back 2 status */ + unsigned short wb1s; /* write back 1 status */ + unsigned long faddr; /* fault address */ + unsigned long wb3a; /* write back 3 address */ + unsigned long wb3d; /* write back 3 data */ + unsigned long wb2a; /* write back 2 address */ + unsigned long wb2d; /* write back 2 data */ + unsigned long wb1a; /* write back 1 address */ + unsigned long wb1dpd0; /* write back 1 data/push data 0*/ + unsigned long pd1; /* push data 1*/ + unsigned long pd2; /* push data 2*/ + unsigned long pd3; /* push data 3*/ + } fmt7; + struct { + unsigned long iaddr; /* instruction address */ + unsigned short int1[4]; /* internal registers */ + } fmt9; + struct { + unsigned short int1; + unsigned short ssw; /* special status word */ + unsigned short isc; /* instruction stage c */ + unsigned short isb; /* instruction stage b */ + unsigned long daddr; /* data cycle fault address */ + unsigned short int2[2]; + unsigned long dobuf; /* data cycle output buffer */ + unsigned short int3[2]; + } fmta; + struct { + unsigned short int1; + unsigned short ssw; /* special status word */ + unsigned short isc; /* instruction stage c */ + unsigned short isb; /* instruction stage b */ + unsigned long daddr; /* data cycle fault address */ + unsigned short int2[2]; + unsigned long dobuf; /* data cycle output buffer */ + unsigned short int3[4]; + unsigned long baddr; /* stage B address */ + unsigned short int4[2]; + unsigned long dibuf; /* data cycle input buffer */ + unsigned short int5[3]; + unsigned ver : 4; /* stack frame version # */ + unsigned int6:12; + unsigned short int7[18]; + } fmtb; + } un; +}; + +#endif /* __ASSEMBLY__ */ + +#endif /* _M68KNOMMU_TRAPS_H */ diff --git a/arch/m68k/include/asm/types.h b/arch/m68k/include/asm/types.h new file mode 100644 index 00000000000..6441cb5f8e7 --- /dev/null +++ b/arch/m68k/include/asm/types.h @@ -0,0 +1,37 @@ +#ifndef _M68K_TYPES_H +#define _M68K_TYPES_H + +/* + * This file is never included by application software unless + * explicitly requested (e.g., via linux/types.h) in which case the + * application is Linux specific so (user-) name space pollution is + * not a major issue. However, for interoperability, libraries still + * need to be careful to avoid a name clashes. + */ +#include + +#ifndef __ASSEMBLY__ + +typedef unsigned short umode_t; + +#endif /* __ASSEMBLY__ */ + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +#ifdef __KERNEL__ + +#define BITS_PER_LONG 32 + +#ifndef __ASSEMBLY__ + +/* DMA addresses are always 32-bits wide */ + +typedef u32 dma_addr_t; +typedef u32 dma64_addr_t; + +#endif /* __ASSEMBLY__ */ + +#endif /* __KERNEL__ */ + +#endif /* _M68K_TYPES_H */ diff --git a/arch/m68k/include/asm/uaccess.h b/arch/m68k/include/asm/uaccess.h new file mode 100644 index 00000000000..38f92dbb9a4 --- /dev/null +++ b/arch/m68k/include/asm/uaccess.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "uaccess_no.h" +#else +#include "uaccess_mm.h" +#endif diff --git a/arch/m68k/include/asm/uaccess_mm.h b/arch/m68k/include/asm/uaccess_mm.h new file mode 100644 index 00000000000..7107f3fbdbb --- /dev/null +++ b/arch/m68k/include/asm/uaccess_mm.h @@ -0,0 +1,374 @@ +#ifndef __M68K_UACCESS_H +#define __M68K_UACCESS_H + +/* + * User space memory access functions + */ +#include +#include +#include +#include +#include + +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 + +/* We let the MMU do all checking */ +static inline int access_ok(int type, const void __user *addr, + unsigned long size) +{ + return 1; +} + +/* + * The exception table consists of pairs of addresses: the first is the + * address of an instruction that is allowed to fault, and the second is + * the address at which the program should continue. No registers are + * modified, so it is entirely up to the continuation code to figure out + * what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path. This means when everything is well, + * we don't even have to jump over them. Further, they do not intrude + * on our cache or tlb entries. + */ + +struct exception_table_entry +{ + unsigned long insn, fixup; +}; + +extern int __put_user_bad(void); +extern int __get_user_bad(void); + +#define __put_user_asm(res, x, ptr, bwl, reg, err) \ +asm volatile ("\n" \ + "1: moves."#bwl" %2,%1\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + " .even\n" \ + "10: moveq.l %3,%0\n" \ + " jra 2b\n" \ + " .previous\n" \ + "\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,10b\n" \ + " .long 2b,10b\n" \ + " .previous" \ + : "+d" (res), "=m" (*(ptr)) \ + : #reg (x), "i" (err)) + +/* + * These are the main single-value transfer routines. They automatically + * use the right size if we just have the right pointer type. + */ + +#define __put_user(x, ptr) \ +({ \ + typeof(*(ptr)) __pu_val = (x); \ + int __pu_err = 0; \ + __chk_user_ptr(ptr); \ + switch (sizeof (*(ptr))) { \ + case 1: \ + __put_user_asm(__pu_err, __pu_val, ptr, b, d, -EFAULT); \ + break; \ + case 2: \ + __put_user_asm(__pu_err, __pu_val, ptr, w, d, -EFAULT); \ + break; \ + case 4: \ + __put_user_asm(__pu_err, __pu_val, ptr, l, r, -EFAULT); \ + break; \ + case 8: \ + { \ + const void __user *__pu_ptr = (ptr); \ + asm volatile ("\n" \ + "1: moves.l %2,(%1)+\n" \ + "2: moves.l %R2,(%1)\n" \ + "3:\n" \ + " .section .fixup,\"ax\"\n" \ + " .even\n" \ + "10: movel %3,%0\n" \ + " jra 3b\n" \ + " .previous\n" \ + "\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,10b\n" \ + " .long 2b,10b\n" \ + " .long 3b,10b\n" \ + " .previous" \ + : "+d" (__pu_err), "+a" (__pu_ptr) \ + : "r" (__pu_val), "i" (-EFAULT) \ + : "memory"); \ + break; \ + } \ + default: \ + __pu_err = __put_user_bad(); \ + break; \ + } \ + __pu_err; \ +}) +#define put_user(x, ptr) __put_user(x, ptr) + + +#define __get_user_asm(res, x, ptr, type, bwl, reg, err) ({ \ + type __gu_val; \ + asm volatile ("\n" \ + "1: moves."#bwl" %2,%1\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + " .even\n" \ + "10: move.l %3,%0\n" \ + " sub."#bwl" %1,%1\n" \ + " jra 2b\n" \ + " .previous\n" \ + "\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,10b\n" \ + " .previous" \ + : "+d" (res), "=&" #reg (__gu_val) \ + : "m" (*(ptr)), "i" (err)); \ + (x) = (typeof(*(ptr)))(unsigned long)__gu_val; \ +}) + +#define __get_user(x, ptr) \ +({ \ + int __gu_err = 0; \ + __chk_user_ptr(ptr); \ + switch (sizeof(*(ptr))) { \ + case 1: \ + __get_user_asm(__gu_err, x, ptr, u8, b, d, -EFAULT); \ + break; \ + case 2: \ + __get_user_asm(__gu_err, x, ptr, u16, w, d, -EFAULT); \ + break; \ + case 4: \ + __get_user_asm(__gu_err, x, ptr, u32, l, r, -EFAULT); \ + break; \ +/* case 8: disabled because gcc-4.1 has a broken typeof \ + { \ + const void *__gu_ptr = (ptr); \ + u64 __gu_val; \ + asm volatile ("\n" \ + "1: moves.l (%2)+,%1\n" \ + "2: moves.l (%2),%R1\n" \ + "3:\n" \ + " .section .fixup,\"ax\"\n" \ + " .even\n" \ + "10: move.l %3,%0\n" \ + " sub.l %1,%1\n" \ + " sub.l %R1,%R1\n" \ + " jra 3b\n" \ + " .previous\n" \ + "\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,10b\n" \ + " .long 2b,10b\n" \ + " .previous" \ + : "+d" (__gu_err), "=&r" (__gu_val), \ + "+a" (__gu_ptr) \ + : "i" (-EFAULT) \ + : "memory"); \ + (x) = (typeof(*(ptr)))__gu_val; \ + break; \ + } */ \ + default: \ + __gu_err = __get_user_bad(); \ + break; \ + } \ + __gu_err; \ +}) +#define get_user(x, ptr) __get_user(x, ptr) + +unsigned long __generic_copy_from_user(void *to, const void __user *from, unsigned long n); +unsigned long __generic_copy_to_user(void __user *to, const void *from, unsigned long n); + +#define __constant_copy_from_user_asm(res, to, from, tmp, n, s1, s2, s3)\ + asm volatile ("\n" \ + "1: moves."#s1" (%2)+,%3\n" \ + " move."#s1" %3,(%1)+\n" \ + "2: moves."#s2" (%2)+,%3\n" \ + " move."#s2" %3,(%1)+\n" \ + " .ifnc \""#s3"\",\"\"\n" \ + "3: moves."#s3" (%2)+,%3\n" \ + " move."#s3" %3,(%1)+\n" \ + " .endif\n" \ + "4:\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,10f\n" \ + " .long 2b,20f\n" \ + " .ifnc \""#s3"\",\"\"\n" \ + " .long 3b,30f\n" \ + " .endif\n" \ + " .previous\n" \ + "\n" \ + " .section .fixup,\"ax\"\n" \ + " .even\n" \ + "10: clr."#s1" (%1)+\n" \ + "20: clr."#s2" (%1)+\n" \ + " .ifnc \""#s3"\",\"\"\n" \ + "30: clr."#s3" (%1)+\n" \ + " .endif\n" \ + " moveq.l #"#n",%0\n" \ + " jra 4b\n" \ + " .previous\n" \ + : "+d" (res), "+&a" (to), "+a" (from), "=&d" (tmp) \ + : : "memory") + +static __always_inline unsigned long +__constant_copy_from_user(void *to, const void __user *from, unsigned long n) +{ + unsigned long res = 0, tmp; + + switch (n) { + case 1: + __get_user_asm(res, *(u8 *)to, (u8 __user *)from, u8, b, d, 1); + break; + case 2: + __get_user_asm(res, *(u16 *)to, (u16 __user *)from, u16, w, d, 2); + break; + case 3: + __constant_copy_from_user_asm(res, to, from, tmp, 3, w, b,); + break; + case 4: + __get_user_asm(res, *(u32 *)to, (u32 __user *)from, u32, l, r, 4); + break; + case 5: + __constant_copy_from_user_asm(res, to, from, tmp, 5, l, b,); + break; + case 6: + __constant_copy_from_user_asm(res, to, from, tmp, 6, l, w,); + break; + case 7: + __constant_copy_from_user_asm(res, to, from, tmp, 7, l, w, b); + break; + case 8: + __constant_copy_from_user_asm(res, to, from, tmp, 8, l, l,); + break; + case 9: + __constant_copy_from_user_asm(res, to, from, tmp, 9, l, l, b); + break; + case 10: + __constant_copy_from_user_asm(res, to, from, tmp, 10, l, l, w); + break; + case 12: + __constant_copy_from_user_asm(res, to, from, tmp, 12, l, l, l); + break; + default: + /* we limit the inlined version to 3 moves */ + return __generic_copy_from_user(to, from, n); + } + + return res; +} + +#define __constant_copy_to_user_asm(res, to, from, tmp, n, s1, s2, s3) \ + asm volatile ("\n" \ + " move."#s1" (%2)+,%3\n" \ + "11: moves."#s1" %3,(%1)+\n" \ + "12: move."#s2" (%2)+,%3\n" \ + "21: moves."#s2" %3,(%1)+\n" \ + "22:\n" \ + " .ifnc \""#s3"\",\"\"\n" \ + " move."#s3" (%2)+,%3\n" \ + "31: moves."#s3" %3,(%1)+\n" \ + "32:\n" \ + " .endif\n" \ + "4:\n" \ + "\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 11b,5f\n" \ + " .long 12b,5f\n" \ + " .long 21b,5f\n" \ + " .long 22b,5f\n" \ + " .ifnc \""#s3"\",\"\"\n" \ + " .long 31b,5f\n" \ + " .long 32b,5f\n" \ + " .endif\n" \ + " .previous\n" \ + "\n" \ + " .section .fixup,\"ax\"\n" \ + " .even\n" \ + "5: moveq.l #"#n",%0\n" \ + " jra 4b\n" \ + " .previous\n" \ + : "+d" (res), "+a" (to), "+a" (from), "=&d" (tmp) \ + : : "memory") + +static __always_inline unsigned long +__constant_copy_to_user(void __user *to, const void *from, unsigned long n) +{ + unsigned long res = 0, tmp; + + switch (n) { + case 1: + __put_user_asm(res, *(u8 *)from, (u8 __user *)to, b, d, 1); + break; + case 2: + __put_user_asm(res, *(u16 *)from, (u16 __user *)to, w, d, 2); + break; + case 3: + __constant_copy_to_user_asm(res, to, from, tmp, 3, w, b,); + break; + case 4: + __put_user_asm(res, *(u32 *)from, (u32 __user *)to, l, r, 4); + break; + case 5: + __constant_copy_to_user_asm(res, to, from, tmp, 5, l, b,); + break; + case 6: + __constant_copy_to_user_asm(res, to, from, tmp, 6, l, w,); + break; + case 7: + __constant_copy_to_user_asm(res, to, from, tmp, 7, l, w, b); + break; + case 8: + __constant_copy_to_user_asm(res, to, from, tmp, 8, l, l,); + break; + case 9: + __constant_copy_to_user_asm(res, to, from, tmp, 9, l, l, b); + break; + case 10: + __constant_copy_to_user_asm(res, to, from, tmp, 10, l, l, w); + break; + case 12: + __constant_copy_to_user_asm(res, to, from, tmp, 12, l, l, l); + break; + default: + /* limit the inlined version to 3 moves */ + return __generic_copy_to_user(to, from, n); + } + + return res; +} + +#define __copy_from_user(to, from, n) \ +(__builtin_constant_p(n) ? \ + __constant_copy_from_user(to, from, n) : \ + __generic_copy_from_user(to, from, n)) + +#define __copy_to_user(to, from, n) \ +(__builtin_constant_p(n) ? \ + __constant_copy_to_user(to, from, n) : \ + __generic_copy_to_user(to, from, n)) + +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user + +#define copy_from_user(to, from, n) __copy_from_user(to, from, n) +#define copy_to_user(to, from, n) __copy_to_user(to, from, n) + +long strncpy_from_user(char *dst, const char __user *src, long count); +long strnlen_user(const char __user *src, long n); +unsigned long __clear_user(void __user *to, unsigned long n); + +#define clear_user __clear_user + +#define strlen_user(str) strnlen_user(str, 32767) + +#endif /* _M68K_UACCESS_H */ diff --git a/arch/m68k/include/asm/uaccess_no.h b/arch/m68k/include/asm/uaccess_no.h new file mode 100644 index 00000000000..68bbe9b312f --- /dev/null +++ b/arch/m68k/include/asm/uaccess_no.h @@ -0,0 +1,181 @@ +#ifndef __M68KNOMMU_UACCESS_H +#define __M68KNOMMU_UACCESS_H + +/* + * User space memory access functions + */ +#include +#include +#include + +#include + +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 + +#define access_ok(type,addr,size) _access_ok((unsigned long)(addr),(size)) + +/* + * It is not enough to just have access_ok check for a real RAM address. + * This would disallow the case of code/ro-data running XIP in flash/rom. + * Ideally we would check the possible flash ranges too, but that is + * currently not so easy. + */ +static inline int _access_ok(unsigned long addr, unsigned long size) +{ + return 1; +} + +/* + * The exception table consists of pairs of addresses: the first is the + * address of an instruction that is allowed to fault, and the second is + * the address at which the program should continue. No registers are + * modified, so it is entirely up to the continuation code to figure out + * what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path. This means when everything is well, + * we don't even have to jump over them. Further, they do not intrude + * on our cache or tlb entries. + */ + +struct exception_table_entry +{ + unsigned long insn, fixup; +}; + +/* Returns 0 if exception not found and fixup otherwise. */ +extern unsigned long search_exception_table(unsigned long); + + +/* + * These are the main single-value transfer routines. They automatically + * use the right size if we just have the right pointer type. + */ + +#define put_user(x, ptr) \ +({ \ + int __pu_err = 0; \ + typeof(*(ptr)) __pu_val = (x); \ + switch (sizeof (*(ptr))) { \ + case 1: \ + __put_user_asm(__pu_err, __pu_val, ptr, b); \ + break; \ + case 2: \ + __put_user_asm(__pu_err, __pu_val, ptr, w); \ + break; \ + case 4: \ + __put_user_asm(__pu_err, __pu_val, ptr, l); \ + break; \ + case 8: \ + memcpy(ptr, &__pu_val, sizeof (*(ptr))); \ + break; \ + default: \ + __pu_err = __put_user_bad(); \ + break; \ + } \ + __pu_err; \ +}) +#define __put_user(x, ptr) put_user(x, ptr) + +extern int __put_user_bad(void); + +/* + * Tell gcc we read from memory instead of writing: this is because + * we do not write to any memory gcc knows about, so there are no + * aliasing issues. + */ + +#define __ptr(x) ((unsigned long *)(x)) + +#define __put_user_asm(err,x,ptr,bwl) \ + __asm__ ("move" #bwl " %0,%1" \ + : /* no outputs */ \ + :"d" (x),"m" (*__ptr(ptr)) : "memory") + +#define get_user(x, ptr) \ +({ \ + int __gu_err = 0; \ + typeof(x) __gu_val = 0; \ + switch (sizeof(*(ptr))) { \ + case 1: \ + __get_user_asm(__gu_err, __gu_val, ptr, b, "=d"); \ + break; \ + case 2: \ + __get_user_asm(__gu_err, __gu_val, ptr, w, "=r"); \ + break; \ + case 4: \ + __get_user_asm(__gu_err, __gu_val, ptr, l, "=r"); \ + break; \ + case 8: \ + memcpy((void *) &__gu_val, ptr, sizeof (*(ptr))); \ + break; \ + default: \ + __gu_val = 0; \ + __gu_err = __get_user_bad(); \ + break; \ + } \ + (x) = (typeof(*(ptr))) __gu_val; \ + __gu_err; \ +}) +#define __get_user(x, ptr) get_user(x, ptr) + +extern int __get_user_bad(void); + +#define __get_user_asm(err,x,ptr,bwl,reg) \ + __asm__ ("move" #bwl " %1,%0" \ + : "=d" (x) \ + : "m" (*__ptr(ptr))) + +#define copy_from_user(to, from, n) (memcpy(to, from, n), 0) +#define copy_to_user(to, from, n) (memcpy(to, from, n), 0) + +#define __copy_from_user(to, from, n) copy_from_user(to, from, n) +#define __copy_to_user(to, from, n) copy_to_user(to, from, n) +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user + +#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; }) + +#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n)) return retval; }) + +/* + * Copy a null terminated string from userspace. + */ + +static inline long +strncpy_from_user(char *dst, const char *src, long count) +{ + char *tmp; + strncpy(dst, src, count); + for (tmp = dst; *tmp && count > 0; tmp++, count--) + ; + return(tmp - dst); /* DAVIDM should we count a NUL ? check getname */ +} + +/* + * Return the size of a string (including the ending 0) + * + * Return 0 on exception, a value greater than N if too long + */ +static inline long strnlen_user(const char *src, long n) +{ + return(strlen(src) + 1); /* DAVIDM make safer */ +} + +#define strlen_user(str) strnlen_user(str, 32767) + +/* + * Zero Userspace + */ + +static inline unsigned long +__clear_user(void *to, unsigned long n) +{ + memset(to, 0, n); + return 0; +} + +#define clear_user(to,n) __clear_user(to,n) + +#endif /* _M68KNOMMU_UACCESS_H */ diff --git a/arch/m68k/include/asm/ucontext.h b/arch/m68k/include/asm/ucontext.h new file mode 100644 index 00000000000..b53cd160c0b --- /dev/null +++ b/arch/m68k/include/asm/ucontext.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "ucontext_no.h" +#else +#include "ucontext_mm.h" +#endif diff --git a/arch/m68k/include/asm/ucontext_mm.h b/arch/m68k/include/asm/ucontext_mm.h new file mode 100644 index 00000000000..e4e22669edc --- /dev/null +++ b/arch/m68k/include/asm/ucontext_mm.h @@ -0,0 +1,30 @@ +#ifndef _M68K_UCONTEXT_H +#define _M68K_UCONTEXT_H + +typedef int greg_t; +#define NGREG 18 +typedef greg_t gregset_t[NGREG]; + +typedef struct fpregset { + int f_fpcntl[3]; + int f_fpregs[8*3]; +} fpregset_t; + +struct mcontext { + int version; + gregset_t gregs; + fpregset_t fpregs; +}; + +#define MCONTEXT_VERSION 2 + +struct ucontext { + unsigned long uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + struct mcontext uc_mcontext; + unsigned long uc_filler[80]; + sigset_t uc_sigmask; /* mask last for extensibility */ +}; + +#endif diff --git a/arch/m68k/include/asm/ucontext_no.h b/arch/m68k/include/asm/ucontext_no.h new file mode 100644 index 00000000000..713a27f901c --- /dev/null +++ b/arch/m68k/include/asm/ucontext_no.h @@ -0,0 +1,32 @@ +#ifndef _M68KNOMMU_UCONTEXT_H +#define _M68KNOMMU_UCONTEXT_H + +typedef int greg_t; +#define NGREG 18 +typedef greg_t gregset_t[NGREG]; + +typedef struct fpregset { + int f_pcr; + int f_psr; + int f_fpiaddr; + int f_fpregs[8][3]; +} fpregset_t; + +struct mcontext { + int version; + gregset_t gregs; + fpregset_t fpregs; +}; + +#define MCONTEXT_VERSION 2 + +struct ucontext { + unsigned long uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + struct mcontext uc_mcontext; + unsigned long uc_filler[80]; + sigset_t uc_sigmask; /* mask last for extensibility */ +}; + +#endif diff --git a/arch/m68k/include/asm/unaligned.h b/arch/m68k/include/asm/unaligned.h new file mode 100644 index 00000000000..c640bba3bdf --- /dev/null +++ b/arch/m68k/include/asm/unaligned.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "unaligned_no.h" +#else +#include "unaligned_mm.h" +#endif diff --git a/arch/m68k/include/asm/unaligned_mm.h b/arch/m68k/include/asm/unaligned_mm.h new file mode 100644 index 00000000000..77698f2dc33 --- /dev/null +++ b/arch/m68k/include/asm/unaligned_mm.h @@ -0,0 +1,13 @@ +#ifndef _ASM_M68K_UNALIGNED_H +#define _ASM_M68K_UNALIGNED_H + +/* + * The m68k can do unaligned accesses itself. + */ +#include +#include + +#define get_unaligned __get_unaligned_be +#define put_unaligned __put_unaligned_be + +#endif /* _ASM_M68K_UNALIGNED_H */ diff --git a/arch/m68k/include/asm/unaligned_no.h b/arch/m68k/include/asm/unaligned_no.h new file mode 100644 index 00000000000..eb1ea4cb9a5 --- /dev/null +++ b/arch/m68k/include/asm/unaligned_no.h @@ -0,0 +1,25 @@ +#ifndef _ASM_M68KNOMMU_UNALIGNED_H +#define _ASM_M68KNOMMU_UNALIGNED_H + + +#ifdef CONFIG_COLDFIRE +#include +#include +#include + +#define get_unaligned __get_unaligned_be +#define put_unaligned __put_unaligned_be + +#else +/* + * The m68k can do unaligned accesses itself. + */ +#include +#include + +#define get_unaligned __get_unaligned_be +#define put_unaligned __put_unaligned_be + +#endif + +#endif /* _ASM_M68KNOMMU_UNALIGNED_H */ diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h new file mode 100644 index 00000000000..df1d9d4cb1f --- /dev/null +++ b/arch/m68k/include/asm/unistd.h @@ -0,0 +1,5 @@ +#ifdef __uClinux__ +#include "unistd_no.h" +#else +#include "unistd_mm.h" +#endif diff --git a/arch/m68k/include/asm/unistd_mm.h b/arch/m68k/include/asm/unistd_mm.h new file mode 100644 index 00000000000..965abb8bc7f --- /dev/null +++ b/arch/m68k/include/asm/unistd_mm.h @@ -0,0 +1,374 @@ +#ifndef _ASM_M68K_UNISTD_H_ +#define _ASM_M68K_UNISTD_H_ + +/* + * This file contains the system call numbers. + */ + +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_open 5 +#define __NR_close 6 +#define __NR_waitpid 7 +#define __NR_creat 8 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_execve 11 +#define __NR_chdir 12 +#define __NR_time 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_chown 16 +#define __NR_break 17 +#define __NR_oldstat 18 +#define __NR_lseek 19 +#define __NR_getpid 20 +#define __NR_mount 21 +#define __NR_umount 22 +#define __NR_setuid 23 +#define __NR_getuid 24 +#define __NR_stime 25 +#define __NR_ptrace 26 +#define __NR_alarm 27 +#define __NR_oldfstat 28 +#define __NR_pause 29 +#define __NR_utime 30 +#define __NR_stty 31 +#define __NR_gtty 32 +#define __NR_access 33 +#define __NR_nice 34 +#define __NR_ftime 35 +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_rename 38 +#define __NR_mkdir 39 +#define __NR_rmdir 40 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_times 43 +#define __NR_prof 44 +#define __NR_brk 45 +#define __NR_setgid 46 +#define __NR_getgid 47 +#define __NR_signal 48 +#define __NR_geteuid 49 +#define __NR_getegid 50 +#define __NR_acct 51 +#define __NR_umount2 52 +#define __NR_lock 53 +#define __NR_ioctl 54 +#define __NR_fcntl 55 +#define __NR_mpx 56 +#define __NR_setpgid 57 +#define __NR_ulimit 58 +#define __NR_oldolduname 59 +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_ustat 62 +#define __NR_dup2 63 +#define __NR_getppid 64 +#define __NR_getpgrp 65 +#define __NR_setsid 66 +#define __NR_sigaction 67 +#define __NR_sgetmask 68 +#define __NR_ssetmask 69 +#define __NR_setreuid 70 +#define __NR_setregid 71 +#define __NR_sigsuspend 72 +#define __NR_sigpending 73 +#define __NR_sethostname 74 +#define __NR_setrlimit 75 +#define __NR_getrlimit 76 +#define __NR_getrusage 77 +#define __NR_gettimeofday 78 +#define __NR_settimeofday 79 +#define __NR_getgroups 80 +#define __NR_setgroups 81 +#define __NR_select 82 +#define __NR_symlink 83 +#define __NR_oldlstat 84 +#define __NR_readlink 85 +#define __NR_uselib 86 +#define __NR_swapon 87 +#define __NR_reboot 88 +#define __NR_readdir 89 +#define __NR_mmap 90 +#define __NR_munmap 91 +#define __NR_truncate 92 +#define __NR_ftruncate 93 +#define __NR_fchmod 94 +#define __NR_fchown 95 +#define __NR_getpriority 96 +#define __NR_setpriority 97 +#define __NR_profil 98 +#define __NR_statfs 99 +#define __NR_fstatfs 100 +#define __NR_ioperm 101 +#define __NR_socketcall 102 +#define __NR_syslog 103 +#define __NR_setitimer 104 +#define __NR_getitimer 105 +#define __NR_stat 106 +#define __NR_lstat 107 +#define __NR_fstat 108 +#define __NR_olduname 109 +#define __NR_iopl /* 110 */ not supported +#define __NR_vhangup 111 +#define __NR_idle /* 112 */ Obsolete +#define __NR_vm86 /* 113 */ not supported +#define __NR_wait4 114 +#define __NR_swapoff 115 +#define __NR_sysinfo 116 +#define __NR_ipc 117 +#define __NR_fsync 118 +#define __NR_sigreturn 119 +#define __NR_clone 120 +#define __NR_setdomainname 121 +#define __NR_uname 122 +#define __NR_cacheflush 123 +#define __NR_adjtimex 124 +#define __NR_mprotect 125 +#define __NR_sigprocmask 126 +#define __NR_create_module 127 +#define __NR_init_module 128 +#define __NR_delete_module 129 +#define __NR_get_kernel_syms 130 +#define __NR_quotactl 131 +#define __NR_getpgid 132 +#define __NR_fchdir 133 +#define __NR_bdflush 134 +#define __NR_sysfs 135 +#define __NR_personality 136 +#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ +#define __NR_setfsuid 138 +#define __NR_setfsgid 139 +#define __NR__llseek 140 +#define __NR_getdents 141 +#define __NR__newselect 142 +#define __NR_flock 143 +#define __NR_msync 144 +#define __NR_readv 145 +#define __NR_writev 146 +#define __NR_getsid 147 +#define __NR_fdatasync 148 +#define __NR__sysctl 149 +#define __NR_mlock 150 +#define __NR_munlock 151 +#define __NR_mlockall 152 +#define __NR_munlockall 153 +#define __NR_sched_setparam 154 +#define __NR_sched_getparam 155 +#define __NR_sched_setscheduler 156 +#define __NR_sched_getscheduler 157 +#define __NR_sched_yield 158 +#define __NR_sched_get_priority_max 159 +#define __NR_sched_get_priority_min 160 +#define __NR_sched_rr_get_interval 161 +#define __NR_nanosleep 162 +#define __NR_mremap 163 +#define __NR_setresuid 164 +#define __NR_getresuid 165 +#define __NR_getpagesize 166 +#define __NR_query_module 167 +#define __NR_poll 168 +#define __NR_nfsservctl 169 +#define __NR_setresgid 170 +#define __NR_getresgid 171 +#define __NR_prctl 172 +#define __NR_rt_sigreturn 173 +#define __NR_rt_sigaction 174 +#define __NR_rt_sigprocmask 175 +#define __NR_rt_sigpending 176 +#define __NR_rt_sigtimedwait 177 +#define __NR_rt_sigqueueinfo 178 +#define __NR_rt_sigsuspend 179 +#define __NR_pread64 180 +#define __NR_pwrite64 181 +#define __NR_lchown 182 +#define __NR_getcwd 183 +#define __NR_capget 184 +#define __NR_capset 185 +#define __NR_sigaltstack 186 +#define __NR_sendfile 187 +#define __NR_getpmsg 188 /* some people actually want streams */ +#define __NR_putpmsg 189 /* some people actually want streams */ +#define __NR_vfork 190 +#define __NR_ugetrlimit 191 +#define __NR_mmap2 192 +#define __NR_truncate64 193 +#define __NR_ftruncate64 194 +#define __NR_stat64 195 +#define __NR_lstat64 196 +#define __NR_fstat64 197 +#define __NR_chown32 198 +#define __NR_getuid32 199 +#define __NR_getgid32 200 +#define __NR_geteuid32 201 +#define __NR_getegid32 202 +#define __NR_setreuid32 203 +#define __NR_setregid32 204 +#define __NR_getgroups32 205 +#define __NR_setgroups32 206 +#define __NR_fchown32 207 +#define __NR_setresuid32 208 +#define __NR_getresuid32 209 +#define __NR_setresgid32 210 +#define __NR_getresgid32 211 +#define __NR_lchown32 212 +#define __NR_setuid32 213 +#define __NR_setgid32 214 +#define __NR_setfsuid32 215 +#define __NR_setfsgid32 216 +#define __NR_pivot_root 217 +#define __NR_getdents64 220 +#define __NR_gettid 221 +#define __NR_tkill 222 +#define __NR_setxattr 223 +#define __NR_lsetxattr 224 +#define __NR_fsetxattr 225 +#define __NR_getxattr 226 +#define __NR_lgetxattr 227 +#define __NR_fgetxattr 228 +#define __NR_listxattr 229 +#define __NR_llistxattr 230 +#define __NR_flistxattr 231 +#define __NR_removexattr 232 +#define __NR_lremovexattr 233 +#define __NR_fremovexattr 234 +#define __NR_futex 235 +#define __NR_sendfile64 236 +#define __NR_mincore 237 +#define __NR_madvise 238 +#define __NR_fcntl64 239 +#define __NR_readahead 240 +#define __NR_io_setup 241 +#define __NR_io_destroy 242 +#define __NR_io_getevents 243 +#define __NR_io_submit 244 +#define __NR_io_cancel 245 +#define __NR_fadvise64 246 +#define __NR_exit_group 247 +#define __NR_lookup_dcookie 248 +#define __NR_epoll_create 249 +#define __NR_epoll_ctl 250 +#define __NR_epoll_wait 251 +#define __NR_remap_file_pages 252 +#define __NR_set_tid_address 253 +#define __NR_timer_create 254 +#define __NR_timer_settime 255 +#define __NR_timer_gettime 256 +#define __NR_timer_getoverrun 257 +#define __NR_timer_delete 258 +#define __NR_clock_settime 259 +#define __NR_clock_gettime 260 +#define __NR_clock_getres 261 +#define __NR_clock_nanosleep 262 +#define __NR_statfs64 263 +#define __NR_fstatfs64 264 +#define __NR_tgkill 265 +#define __NR_utimes 266 +#define __NR_fadvise64_64 267 +#define __NR_mbind 268 +#define __NR_get_mempolicy 269 +#define __NR_set_mempolicy 270 +#define __NR_mq_open 271 +#define __NR_mq_unlink 272 +#define __NR_mq_timedsend 273 +#define __NR_mq_timedreceive 274 +#define __NR_mq_notify 275 +#define __NR_mq_getsetattr 276 +#define __NR_waitid 277 +#define __NR_vserver 278 +#define __NR_add_key 279 +#define __NR_request_key 280 +#define __NR_keyctl 281 +#define __NR_ioprio_set 282 +#define __NR_ioprio_get 283 +#define __NR_inotify_init 284 +#define __NR_inotify_add_watch 285 +#define __NR_inotify_rm_watch 286 +#define __NR_migrate_pages 287 +#define __NR_openat 288 +#define __NR_mkdirat 289 +#define __NR_mknodat 290 +#define __NR_fchownat 291 +#define __NR_futimesat 292 +#define __NR_fstatat64 293 +#define __NR_unlinkat 294 +#define __NR_renameat 295 +#define __NR_linkat 296 +#define __NR_symlinkat 297 +#define __NR_readlinkat 298 +#define __NR_fchmodat 299 +#define __NR_faccessat 300 +#define __NR_pselect6 301 +#define __NR_ppoll 302 +#define __NR_unshare 303 +#define __NR_set_robust_list 304 +#define __NR_get_robust_list 305 +#define __NR_splice 306 +#define __NR_sync_file_range 307 +#define __NR_tee 308 +#define __NR_vmsplice 309 +#define __NR_move_pages 310 +#define __NR_sched_setaffinity 311 +#define __NR_sched_getaffinity 312 +#define __NR_kexec_load 313 +#define __NR_getcpu 314 +#define __NR_epoll_pwait 315 +#define __NR_utimensat 316 +#define __NR_signalfd 317 +#define __NR_timerfd_create 318 +#define __NR_eventfd 319 +#define __NR_fallocate 320 +#define __NR_timerfd_settime 321 +#define __NR_timerfd_gettime 322 +#define __NR_signalfd4 323 +#define __NR_eventfd2 324 +#define __NR_epoll_create1 325 +#define __NR_dup3 326 +#define __NR_pipe2 327 +#define __NR_inotify_init1 328 + +#ifdef __KERNEL__ + +#define NR_syscalls 329 + +#define __ARCH_WANT_IPC_PARSE_VERSION +#define __ARCH_WANT_OLD_READDIR +#define __ARCH_WANT_OLD_STAT +#define __ARCH_WANT_STAT64 +#define __ARCH_WANT_SYS_ALARM +#define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_PAUSE +#define __ARCH_WANT_SYS_SGETMASK +#define __ARCH_WANT_SYS_SIGNAL +#define __ARCH_WANT_SYS_TIME +#define __ARCH_WANT_SYS_UTIME +#define __ARCH_WANT_SYS_WAITPID +#define __ARCH_WANT_SYS_SOCKETCALL +#define __ARCH_WANT_SYS_FADVISE64 +#define __ARCH_WANT_SYS_GETPGRP +#define __ARCH_WANT_SYS_LLSEEK +#define __ARCH_WANT_SYS_NICE +#define __ARCH_WANT_SYS_OLD_GETRLIMIT +#define __ARCH_WANT_SYS_OLDUMOUNT +#define __ARCH_WANT_SYS_SIGPENDING +#define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION + +/* whitelist for checksyscalls */ +#define __IGNORE_restart_syscall + +/* + * "Conditional" syscalls + * + * What we want is __attribute__((weak,alias("sys_ni_syscall"))), + * but it doesn't work on all toolchains, so we just do it by hand + */ +#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") + +#endif /* __KERNEL__ */ +#endif /* _ASM_M68K_UNISTD_H_ */ diff --git a/arch/m68k/include/asm/unistd_no.h b/arch/m68k/include/asm/unistd_no.h new file mode 100644 index 00000000000..b034a2f7b44 --- /dev/null +++ b/arch/m68k/include/asm/unistd_no.h @@ -0,0 +1,372 @@ +#ifndef _ASM_M68K_UNISTD_H_ +#define _ASM_M68K_UNISTD_H_ + +/* + * This file contains the system call numbers. + */ + +#define __NR_restart_syscall 0 +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_open 5 +#define __NR_close 6 +#define __NR_waitpid 7 +#define __NR_creat 8 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_execve 11 +#define __NR_chdir 12 +#define __NR_time 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_chown 16 +#define __NR_break 17 +#define __NR_oldstat 18 +#define __NR_lseek 19 +#define __NR_getpid 20 +#define __NR_mount 21 +#define __NR_umount 22 +#define __NR_setuid 23 +#define __NR_getuid 24 +#define __NR_stime 25 +#define __NR_ptrace 26 +#define __NR_alarm 27 +#define __NR_oldfstat 28 +#define __NR_pause 29 +#define __NR_utime 30 +#define __NR_stty 31 +#define __NR_gtty 32 +#define __NR_access 33 +#define __NR_nice 34 +#define __NR_ftime 35 +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_rename 38 +#define __NR_mkdir 39 +#define __NR_rmdir 40 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_times 43 +#define __NR_prof 44 +#define __NR_brk 45 +#define __NR_setgid 46 +#define __NR_getgid 47 +#define __NR_signal 48 +#define __NR_geteuid 49 +#define __NR_getegid 50 +#define __NR_acct 51 +#define __NR_umount2 52 +#define __NR_lock 53 +#define __NR_ioctl 54 +#define __NR_fcntl 55 +#define __NR_mpx 56 +#define __NR_setpgid 57 +#define __NR_ulimit 58 +#define __NR_oldolduname 59 +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_ustat 62 +#define __NR_dup2 63 +#define __NR_getppid 64 +#define __NR_getpgrp 65 +#define __NR_setsid 66 +#define __NR_sigaction 67 +#define __NR_sgetmask 68 +#define __NR_ssetmask 69 +#define __NR_setreuid 70 +#define __NR_setregid 71 +#define __NR_sigsuspend 72 +#define __NR_sigpending 73 +#define __NR_sethostname 74 +#define __NR_setrlimit 75 +#define __NR_getrlimit 76 +#define __NR_getrusage 77 +#define __NR_gettimeofday 78 +#define __NR_settimeofday 79 +#define __NR_getgroups 80 +#define __NR_setgroups 81 +#define __NR_select 82 +#define __NR_symlink 83 +#define __NR_oldlstat 84 +#define __NR_readlink 85 +#define __NR_uselib 86 +#define __NR_swapon 87 +#define __NR_reboot 88 +#define __NR_readdir 89 +#define __NR_mmap 90 +#define __NR_munmap 91 +#define __NR_truncate 92 +#define __NR_ftruncate 93 +#define __NR_fchmod 94 +#define __NR_fchown 95 +#define __NR_getpriority 96 +#define __NR_setpriority 97 +#define __NR_profil 98 +#define __NR_statfs 99 +#define __NR_fstatfs 100 +#define __NR_ioperm 101 +#define __NR_socketcall 102 +#define __NR_syslog 103 +#define __NR_setitimer 104 +#define __NR_getitimer 105 +#define __NR_stat 106 +#define __NR_lstat 107 +#define __NR_fstat 108 +#define __NR_olduname 109 +#define __NR_iopl /* 110 */ not supported +#define __NR_vhangup 111 +#define __NR_idle /* 112 */ Obsolete +#define __NR_vm86 /* 113 */ not supported +#define __NR_wait4 114 +#define __NR_swapoff 115 +#define __NR_sysinfo 116 +#define __NR_ipc 117 +#define __NR_fsync 118 +#define __NR_sigreturn 119 +#define __NR_clone 120 +#define __NR_setdomainname 121 +#define __NR_uname 122 +#define __NR_cacheflush 123 +#define __NR_adjtimex 124 +#define __NR_mprotect 125 +#define __NR_sigprocmask 126 +#define __NR_create_module 127 +#define __NR_init_module 128 +#define __NR_delete_module 129 +#define __NR_get_kernel_syms 130 +#define __NR_quotactl 131 +#define __NR_getpgid 132 +#define __NR_fchdir 133 +#define __NR_bdflush 134 +#define __NR_sysfs 135 +#define __NR_personality 136 +#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ +#define __NR_setfsuid 138 +#define __NR_setfsgid 139 +#define __NR__llseek 140 +#define __NR_getdents 141 +#define __NR__newselect 142 +#define __NR_flock 143 +#define __NR_msync 144 +#define __NR_readv 145 +#define __NR_writev 146 +#define __NR_getsid 147 +#define __NR_fdatasync 148 +#define __NR__sysctl 149 +#define __NR_mlock 150 +#define __NR_munlock 151 +#define __NR_mlockall 152 +#define __NR_munlockall 153 +#define __NR_sched_setparam 154 +#define __NR_sched_getparam 155 +#define __NR_sched_setscheduler 156 +#define __NR_sched_getscheduler 157 +#define __NR_sched_yield 158 +#define __NR_sched_get_priority_max 159 +#define __NR_sched_get_priority_min 160 +#define __NR_sched_rr_get_interval 161 +#define __NR_nanosleep 162 +#define __NR_mremap 163 +#define __NR_setresuid 164 +#define __NR_getresuid 165 +#define __NR_getpagesize 166 +#define __NR_query_module 167 +#define __NR_poll 168 +#define __NR_nfsservctl 169 +#define __NR_setresgid 170 +#define __NR_getresgid 171 +#define __NR_prctl 172 +#define __NR_rt_sigreturn 173 +#define __NR_rt_sigaction 174 +#define __NR_rt_sigprocmask 175 +#define __NR_rt_sigpending 176 +#define __NR_rt_sigtimedwait 177 +#define __NR_rt_sigqueueinfo 178 +#define __NR_rt_sigsuspend 179 +#define __NR_pread64 180 +#define __NR_pwrite64 181 +#define __NR_lchown 182 +#define __NR_getcwd 183 +#define __NR_capget 184 +#define __NR_capset 185 +#define __NR_sigaltstack 186 +#define __NR_sendfile 187 +#define __NR_getpmsg 188 /* some people actually want streams */ +#define __NR_putpmsg 189 /* some people actually want streams */ +#define __NR_vfork 190 +#define __NR_ugetrlimit 191 +#define __NR_mmap2 192 +#define __NR_truncate64 193 +#define __NR_ftruncate64 194 +#define __NR_stat64 195 +#define __NR_lstat64 196 +#define __NR_fstat64 197 +#define __NR_chown32 198 +#define __NR_getuid32 199 +#define __NR_getgid32 200 +#define __NR_geteuid32 201 +#define __NR_getegid32 202 +#define __NR_setreuid32 203 +#define __NR_setregid32 204 +#define __NR_getgroups32 205 +#define __NR_setgroups32 206 +#define __NR_fchown32 207 +#define __NR_setresuid32 208 +#define __NR_getresuid32 209 +#define __NR_setresgid32 210 +#define __NR_getresgid32 211 +#define __NR_lchown32 212 +#define __NR_setuid32 213 +#define __NR_setgid32 214 +#define __NR_setfsuid32 215 +#define __NR_setfsgid32 216 +#define __NR_pivot_root 217 +#define __NR_getdents64 220 +#define __NR_gettid 221 +#define __NR_tkill 222 +#define __NR_setxattr 223 +#define __NR_lsetxattr 224 +#define __NR_fsetxattr 225 +#define __NR_getxattr 226 +#define __NR_lgetxattr 227 +#define __NR_fgetxattr 228 +#define __NR_listxattr 229 +#define __NR_llistxattr 230 +#define __NR_flistxattr 231 +#define __NR_removexattr 232 +#define __NR_lremovexattr 233 +#define __NR_fremovexattr 234 +#define __NR_futex 235 +#define __NR_sendfile64 236 +#define __NR_mincore 237 +#define __NR_madvise 238 +#define __NR_fcntl64 239 +#define __NR_readahead 240 +#define __NR_io_setup 241 +#define __NR_io_destroy 242 +#define __NR_io_getevents 243 +#define __NR_io_submit 244 +#define __NR_io_cancel 245 +#define __NR_fadvise64 246 +#define __NR_exit_group 247 +#define __NR_lookup_dcookie 248 +#define __NR_epoll_create 249 +#define __NR_epoll_ctl 250 +#define __NR_epoll_wait 251 +#define __NR_remap_file_pages 252 +#define __NR_set_tid_address 253 +#define __NR_timer_create 254 +#define __NR_timer_settime 255 +#define __NR_timer_gettime 256 +#define __NR_timer_getoverrun 257 +#define __NR_timer_delete 258 +#define __NR_clock_settime 259 +#define __NR_clock_gettime 260 +#define __NR_clock_getres 261 +#define __NR_clock_nanosleep 262 +#define __NR_statfs64 263 +#define __NR_fstatfs64 264 +#define __NR_tgkill 265 +#define __NR_utimes 266 +#define __NR_fadvise64_64 267 +#define __NR_mbind 268 +#define __NR_get_mempolicy 269 +#define __NR_set_mempolicy 270 +#define __NR_mq_open 271 +#define __NR_mq_unlink 272 +#define __NR_mq_timedsend 273 +#define __NR_mq_timedreceive 274 +#define __NR_mq_notify 275 +#define __NR_mq_getsetattr 276 +#define __NR_waitid 277 +#define __NR_vserver 278 +#define __NR_add_key 279 +#define __NR_request_key 280 +#define __NR_keyctl 281 +#define __NR_ioprio_set 282 +#define __NR_ioprio_get 283 +#define __NR_inotify_init 284 +#define __NR_inotify_add_watch 285 +#define __NR_inotify_rm_watch 286 +#define __NR_migrate_pages 287 +#define __NR_openat 288 +#define __NR_mkdirat 289 +#define __NR_mknodat 290 +#define __NR_fchownat 291 +#define __NR_futimesat 292 +#define __NR_fstatat64 293 +#define __NR_unlinkat 294 +#define __NR_renameat 295 +#define __NR_linkat 296 +#define __NR_symlinkat 297 +#define __NR_readlinkat 298 +#define __NR_fchmodat 299 +#define __NR_faccessat 300 +#define __NR_pselect6 301 +#define __NR_ppoll 302 +#define __NR_unshare 303 +#define __NR_set_robust_list 304 +#define __NR_get_robust_list 305 +#define __NR_splice 306 +#define __NR_sync_file_range 307 +#define __NR_tee 308 +#define __NR_vmsplice 309 +#define __NR_move_pages 310 +#define __NR_sched_setaffinity 311 +#define __NR_sched_getaffinity 312 +#define __NR_kexec_load 313 +#define __NR_getcpu 314 +#define __NR_epoll_pwait 315 +#define __NR_utimensat 316 +#define __NR_signalfd 317 +#define __NR_timerfd_create 318 +#define __NR_eventfd 319 +#define __NR_fallocate 320 +#define __NR_timerfd_settime 321 +#define __NR_timerfd_gettime 322 +#define __NR_signalfd4 323 +#define __NR_eventfd2 324 +#define __NR_epoll_create1 325 +#define __NR_dup3 326 +#define __NR_pipe2 327 +#define __NR_inotify_init1 328 + +#ifdef __KERNEL__ + +#define NR_syscalls 329 + +#define __ARCH_WANT_IPC_PARSE_VERSION +#define __ARCH_WANT_OLD_READDIR +#define __ARCH_WANT_OLD_STAT +#define __ARCH_WANT_STAT64 +#define __ARCH_WANT_SYS_ALARM +#define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_PAUSE +#define __ARCH_WANT_SYS_SGETMASK +#define __ARCH_WANT_SYS_SIGNAL +#define __ARCH_WANT_SYS_TIME +#define __ARCH_WANT_SYS_UTIME +#define __ARCH_WANT_SYS_WAITPID +#define __ARCH_WANT_SYS_SOCKETCALL +#define __ARCH_WANT_SYS_FADVISE64 +#define __ARCH_WANT_SYS_GETPGRP +#define __ARCH_WANT_SYS_LLSEEK +#define __ARCH_WANT_SYS_NICE +#define __ARCH_WANT_SYS_OLD_GETRLIMIT +#define __ARCH_WANT_SYS_OLDUMOUNT +#define __ARCH_WANT_SYS_SIGPENDING +#define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION + +/* + * "Conditional" syscalls + * + * What we want is __attribute__((weak,alias("sys_ni_syscall"))), + * but it doesn't work on all toolchains, so we just do it by hand + */ +#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") + +#endif /* __KERNEL__ */ +#endif /* _ASM_M68K_UNISTD_H_ */ diff --git a/arch/m68k/include/asm/user.h b/arch/m68k/include/asm/user.h new file mode 100644 index 00000000000..f1f478d6e05 --- /dev/null +++ b/arch/m68k/include/asm/user.h @@ -0,0 +1,86 @@ +#ifndef _M68K_USER_H +#define _M68K_USER_H + +/* Core file format: The core file is written in such a way that gdb + can understand it and provide useful information to the user (under + linux we use the 'trad-core' bfd). There are quite a number of + obstacles to being able to view the contents of the floating point + registers, and until these are solved you will not be able to view the + contents of them. Actually, you can read in the core file and look at + the contents of the user struct to find out what the floating point + registers contain. + The actual file contents are as follows: + UPAGE: 1 page consisting of a user struct that tells gdb what is present + in the file. Directly after this is a copy of the task_struct, which + is currently not used by gdb, but it may come in useful at some point. + All of the registers are stored as part of the upage. The upage should + always be only one page. + DATA: The data area is stored. We use current->end_text to + current->brk to pick up all of the user variables, plus any memory + that may have been malloced. No attempt is made to determine if a page + is demand-zero or if a page is totally unused, we just cover the entire + range. All of the addresses are rounded in such a way that an integral + number of pages is written. + STACK: We need the stack information in order to get a meaningful + backtrace. We need to write the data from (esp) to + current->start_stack, so we round each of these off in order to be able + to write an integer number of pages. + The minimum core file size is 3 pages, or 12288 bytes. +*/ + +struct user_m68kfp_struct { + unsigned long fpregs[8*3]; /* fp0-fp7 registers */ + unsigned long fpcntl[3]; /* fp control regs */ +}; + +/* This is the old layout of "struct pt_regs" as of Linux 1.x, and + is still the layout used by user (the new pt_regs doesn't have + all registers). */ +struct user_regs_struct { + long d1,d2,d3,d4,d5,d6,d7; + long a0,a1,a2,a3,a4,a5,a6; + long d0; + long usp; + long orig_d0; + short stkadj; + short sr; + long pc; + short fmtvec; + short __fill; +}; + + +/* When the kernel dumps core, it starts by dumping the user struct - + this will be used by gdb to figure out where the data and stack segments + are within the file, and what virtual addresses to use. */ +struct user{ +/* We start with the registers, to mimic the way that "memory" is returned + from the ptrace(3,...) function. */ + struct user_regs_struct regs; /* Where the registers are actually stored */ +/* ptrace does not yet supply these. Someday.... */ + int u_fpvalid; /* True if math co-processor being used. */ + /* for this mess. Not yet used. */ + struct user_m68kfp_struct m68kfp; /* Math Co-processor registers. */ +/* The rest of this junk is to help gdb figure out what goes where */ + unsigned long int u_tsize; /* Text segment size (pages). */ + unsigned long int u_dsize; /* Data segment size (pages). */ + unsigned long int u_ssize; /* Stack segment size (pages). */ + unsigned long start_code; /* Starting virtual address of text. */ + unsigned long start_stack; /* Starting virtual address of stack area. + This is actually the bottom of the stack, + the top of the stack is always found in the + esp register. */ + long int signal; /* Signal that caused the core dump. */ + int reserved; /* No longer used */ + unsigned long u_ar0; /* Used by gdb to help find the values for */ + /* the registers. */ + struct user_m68kfp_struct* u_fpstate; /* Math Co-processor pointer. */ + unsigned long magic; /* To uniquely identify a core file */ + char u_comm[32]; /* User command that was responsible */ +}; +#define NBPG 4096 +#define UPAGES 1 +#define HOST_TEXT_START_ADDR (u.start_code) +#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) + +#endif diff --git a/arch/m68k/include/asm/virtconvert.h b/arch/m68k/include/asm/virtconvert.h new file mode 100644 index 00000000000..22ab05c9c52 --- /dev/null +++ b/arch/m68k/include/asm/virtconvert.h @@ -0,0 +1,48 @@ +#ifndef __VIRT_CONVERT__ +#define __VIRT_CONVERT__ + +/* + * Macros used for converting between virtual and physical mappings. + */ + +#ifdef __KERNEL__ + +#include +#include +#include +#include + +/* + * Change virtual addresses to physical addresses and vv. + */ +static inline unsigned long virt_to_phys(void *address) +{ + return __pa(address); +} + +static inline void *phys_to_virt(unsigned long address) +{ + return __va(address); +} + +/* Permanent address of a page. */ +#ifdef CONFIG_SINGLE_MEMORY_CHUNK +#define page_to_phys(page) \ + __pa(PAGE_OFFSET + (((page) - pg_data_map[0].node_mem_map) << PAGE_SHIFT)) +#else +#define page_to_phys(_page) ({ \ + struct page *__page = _page; \ + struct pglist_data *pgdat; \ + pgdat = pg_data_table[page_to_nid(__page)]; \ + page_to_pfn(__page) << PAGE_SHIFT; \ +}) +#endif + +/* + * IO bus memory addresses are 1:1 with the physical address, + */ +#define virt_to_bus virt_to_phys +#define bus_to_virt phys_to_virt + +#endif +#endif diff --git a/arch/m68k/include/asm/xor.h b/arch/m68k/include/asm/xor.h new file mode 100644 index 00000000000..c82eb12a5b1 --- /dev/null +++ b/arch/m68k/include/asm/xor.h @@ -0,0 +1 @@ +#include diff --git a/arch/m68k/include/asm/zorro.h b/arch/m68k/include/asm/zorro.h new file mode 100644 index 00000000000..5ce97c22b58 --- /dev/null +++ b/arch/m68k/include/asm/zorro.h @@ -0,0 +1,45 @@ +#ifndef _ASM_M68K_ZORRO_H +#define _ASM_M68K_ZORRO_H + +#include + +#define z_readb raw_inb +#define z_readw raw_inw +#define z_readl raw_inl + +#define z_writeb raw_outb +#define z_writew raw_outw +#define z_writel raw_outl + +#define z_memset_io(a,b,c) memset((void *)(a),(b),(c)) +#define z_memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) +#define z_memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) + +static inline void __iomem *z_remap_nocache_ser(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); +} + +static inline void __iomem *z_remap_nocache_nonser(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_NONSER); +} + +static inline void __iomem *z_remap_writethrough(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_WRITETHROUGH); +} +static inline void __iomem *z_remap_fullcache(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_FULL_CACHING); +} + +#define z_unmap iounmap +#define z_iounmap iounmap +#define z_ioremap z_remap_nocache_ser + +#endif /* _ASM_M68K_ZORRO_H */ diff --git a/arch/m68knommu/include/asm/Kbuild b/arch/m68knommu/include/asm/Kbuild deleted file mode 100644 index 58c02a45413..00000000000 --- a/arch/m68knommu/include/asm/Kbuild +++ /dev/null @@ -1,3 +0,0 @@ -include include/asm-generic/Kbuild.asm - -unifdef-y += swab.h diff --git a/arch/m68knommu/include/asm/MC68328.h b/arch/m68knommu/include/asm/MC68328.h deleted file mode 100644 index a337e56d09b..00000000000 --- a/arch/m68knommu/include/asm/MC68328.h +++ /dev/null @@ -1,1266 +0,0 @@ - -/* include/asm-m68knommu/MC68328.h: '328 control registers - * - * Copyright (C) 1999 Vladimir Gurevich - * Bear & Hare Software, Inc. - * - * Based on include/asm-m68knommu/MC68332.h - * Copyright (C) 1998 Kenneth Albanowski , - * - */ - -#ifndef _MC68328_H_ -#define _MC68328_H_ - -#define BYTE_REF(addr) (*((volatile unsigned char*)addr)) -#define WORD_REF(addr) (*((volatile unsigned short*)addr)) -#define LONG_REF(addr) (*((volatile unsigned long*)addr)) - -#define PUT_FIELD(field, val) (((val) << field##_SHIFT) & field##_MASK) -#define GET_FIELD(reg, field) (((reg) & field##_MASK) >> field##_SHIFT) - -/********** - * - * 0xFFFFF0xx -- System Control - * - **********/ - -/* - * System Control Register (SCR) - */ -#define SCR_ADDR 0xfffff000 -#define SCR BYTE_REF(SCR_ADDR) - -#define SCR_WDTH8 0x01 /* 8-Bit Width Select */ -#define SCR_DMAP 0x04 /* Double Map */ -#define SCR_SO 0x08 /* Supervisor Only */ -#define SCR_BETEN 0x10 /* Bus-Error Time-Out Enable */ -#define SCR_PRV 0x20 /* Privilege Violation */ -#define SCR_WPV 0x40 /* Write Protect Violation */ -#define SCR_BETO 0x80 /* Bus-Error TimeOut */ - -/* - * Mask Revision Register - */ -#define MRR_ADDR 0xfffff004 -#define MRR LONG_REF(MRR_ADDR) - -/********** - * - * 0xFFFFF1xx -- Chip-Select logic - * - **********/ - -/********** - * - * 0xFFFFF2xx -- Phase Locked Loop (PLL) & Power Control - * - **********/ - -/* - * Group Base Address Registers - */ -#define GRPBASEA_ADDR 0xfffff100 -#define GRPBASEB_ADDR 0xfffff102 -#define GRPBASEC_ADDR 0xfffff104 -#define GRPBASED_ADDR 0xfffff106 - -#define GRPBASEA WORD_REF(GRPBASEA_ADDR) -#define GRPBASEB WORD_REF(GRPBASEB_ADDR) -#define GRPBASEC WORD_REF(GRPBASEC_ADDR) -#define GRPBASED WORD_REF(GRPBASED_ADDR) - -#define GRPBASE_V 0x0001 /* Valid */ -#define GRPBASE_GBA_MASK 0xfff0 /* Group Base Address (bits 31-20) */ - -/* - * Group Base Address Mask Registers - */ -#define GRPMASKA_ADDR 0xfffff108 -#define GRPMASKB_ADDR 0xfffff10a -#define GRPMASKC_ADDR 0xfffff10c -#define GRPMASKD_ADDR 0xfffff10e - -#define GRPMASKA WORD_REF(GRPMASKA_ADDR) -#define GRPMASKB WORD_REF(GRPMASKB_ADDR) -#define GRPMASKC WORD_REF(GRPMASKC_ADDR) -#define GRPMASKD WORD_REF(GRPMASKD_ADDR) - -#define GRMMASK_GMA_MASK 0xfffff0 /* Group Base Mask (bits 31-20) */ - -/* - * Chip-Select Option Registers (group A) - */ -#define CSA0_ADDR 0xfffff110 -#define CSA1_ADDR 0xfffff114 -#define CSA2_ADDR 0xfffff118 -#define CSA3_ADDR 0xfffff11c - -#define CSA0 LONG_REF(CSA0_ADDR) -#define CSA1 LONG_REF(CSA1_ADDR) -#define CSA2 LONG_REF(CSA2_ADDR) -#define CSA3 LONG_REF(CSA3_ADDR) - -#define CSA_WAIT_MASK 0x00000007 /* Wait State Selection */ -#define CSA_WAIT_SHIFT 0 -#define CSA_RO 0x00000008 /* Read-Only */ -#define CSA_AM_MASK 0x0000ff00 /* Address Mask (bits 23-16) */ -#define CSA_AM_SHIFT 8 -#define CSA_BUSW 0x00010000 /* Bus Width Select */ -#define CSA_AC_MASK 0xff000000 /* Address Compare (bits 23-16) */ -#define CSA_AC_SHIFT 24 - -/* - * Chip-Select Option Registers (group B) - */ -#define CSB0_ADDR 0xfffff120 -#define CSB1_ADDR 0xfffff124 -#define CSB2_ADDR 0xfffff128 -#define CSB3_ADDR 0xfffff12c - -#define CSB0 LONG_REF(CSB0_ADDR) -#define CSB1 LONG_REF(CSB1_ADDR) -#define CSB2 LONG_REF(CSB2_ADDR) -#define CSB3 LONG_REF(CSB3_ADDR) - -#define CSB_WAIT_MASK 0x00000007 /* Wait State Selection */ -#define CSB_WAIT_SHIFT 0 -#define CSB_RO 0x00000008 /* Read-Only */ -#define CSB_AM_MASK 0x0000ff00 /* Address Mask (bits 23-16) */ -#define CSB_AM_SHIFT 8 -#define CSB_BUSW 0x00010000 /* Bus Width Select */ -#define CSB_AC_MASK 0xff000000 /* Address Compare (bits 23-16) */ -#define CSB_AC_SHIFT 24 - -/* - * Chip-Select Option Registers (group C) - */ -#define CSC0_ADDR 0xfffff130 -#define CSC1_ADDR 0xfffff134 -#define CSC2_ADDR 0xfffff138 -#define CSC3_ADDR 0xfffff13c - -#define CSC0 LONG_REF(CSC0_ADDR) -#define CSC1 LONG_REF(CSC1_ADDR) -#define CSC2 LONG_REF(CSC2_ADDR) -#define CSC3 LONG_REF(CSC3_ADDR) - -#define CSC_WAIT_MASK 0x00000007 /* Wait State Selection */ -#define CSC_WAIT_SHIFT 0 -#define CSC_RO 0x00000008 /* Read-Only */ -#define CSC_AM_MASK 0x0000fff0 /* Address Mask (bits 23-12) */ -#define CSC_AM_SHIFT 4 -#define CSC_BUSW 0x00010000 /* Bus Width Select */ -#define CSC_AC_MASK 0xfff00000 /* Address Compare (bits 23-12) */ -#define CSC_AC_SHIFT 20 - -/* - * Chip-Select Option Registers (group D) - */ -#define CSD0_ADDR 0xfffff140 -#define CSD1_ADDR 0xfffff144 -#define CSD2_ADDR 0xfffff148 -#define CSD3_ADDR 0xfffff14c - -#define CSD0 LONG_REF(CSD0_ADDR) -#define CSD1 LONG_REF(CSD1_ADDR) -#define CSD2 LONG_REF(CSD2_ADDR) -#define CSD3 LONG_REF(CSD3_ADDR) - -#define CSD_WAIT_MASK 0x00000007 /* Wait State Selection */ -#define CSD_WAIT_SHIFT 0 -#define CSD_RO 0x00000008 /* Read-Only */ -#define CSD_AM_MASK 0x0000fff0 /* Address Mask (bits 23-12) */ -#define CSD_AM_SHIFT 4 -#define CSD_BUSW 0x00010000 /* Bus Width Select */ -#define CSD_AC_MASK 0xfff00000 /* Address Compare (bits 23-12) */ -#define CSD_AC_SHIFT 20 - -/********** - * - * 0xFFFFF2xx -- Phase Locked Loop (PLL) & Power Control - * - **********/ - -/* - * PLL Control Register - */ -#define PLLCR_ADDR 0xfffff200 -#define PLLCR WORD_REF(PLLCR_ADDR) - -#define PLLCR_DISPLL 0x0008 /* Disable PLL */ -#define PLLCR_CLKEN 0x0010 /* Clock (CLKO pin) enable */ -#define PLLCR_SYSCLK_SEL_MASK 0x0700 /* System Clock Selection */ -#define PLLCR_SYSCLK_SEL_SHIFT 8 -#define PLLCR_PIXCLK_SEL_MASK 0x3800 /* LCD Clock Selection */ -#define PLLCR_PIXCLK_SEL_SHIFT 11 - -/* 'EZ328-compatible definitions */ -#define PLLCR_LCDCLK_SEL_MASK PLLCR_PIXCLK_SEL_MASK -#define PLLCR_LCDCLK_SEL_SHIFT PLLCR_PIXCLK_SEL_SHIFT - -/* - * PLL Frequency Select Register - */ -#define PLLFSR_ADDR 0xfffff202 -#define PLLFSR WORD_REF(PLLFSR_ADDR) - -#define PLLFSR_PC_MASK 0x00ff /* P Count */ -#define PLLFSR_PC_SHIFT 0 -#define PLLFSR_QC_MASK 0x0f00 /* Q Count */ -#define PLLFSR_QC_SHIFT 8 -#define PLLFSR_PROT 0x4000 /* Protect P & Q */ -#define PLLFSR_CLK32 0x8000 /* Clock 32 (kHz) */ - -/* - * Power Control Register - */ -#define PCTRL_ADDR 0xfffff207 -#define PCTRL BYTE_REF(PCTRL_ADDR) - -#define PCTRL_WIDTH_MASK 0x1f /* CPU Clock bursts width */ -#define PCTRL_WIDTH_SHIFT 0 -#define PCTRL_STOP 0x40 /* Enter power-save mode immediately */ -#define PCTRL_PCEN 0x80 /* Power Control Enable */ - -/********** - * - * 0xFFFFF3xx -- Interrupt Controller - * - **********/ - -/* - * Interrupt Vector Register - */ -#define IVR_ADDR 0xfffff300 -#define IVR BYTE_REF(IVR_ADDR) - -#define IVR_VECTOR_MASK 0xF8 - -/* - * Interrupt control Register - */ -#define ICR_ADRR 0xfffff302 -#define ICR WORD_REF(ICR_ADDR) - -#define ICR_ET6 0x0100 /* Edge Trigger Select for IRQ6 */ -#define ICR_ET3 0x0200 /* Edge Trigger Select for IRQ3 */ -#define ICR_ET2 0x0400 /* Edge Trigger Select for IRQ2 */ -#define ICR_ET1 0x0800 /* Edge Trigger Select for IRQ1 */ -#define ICR_POL6 0x1000 /* Polarity Control for IRQ6 */ -#define ICR_POL3 0x2000 /* Polarity Control for IRQ3 */ -#define ICR_POL2 0x4000 /* Polarity Control for IRQ2 */ -#define ICR_POL1 0x8000 /* Polarity Control for IRQ1 */ - -/* - * Interrupt Mask Register - */ -#define IMR_ADDR 0xfffff304 -#define IMR LONG_REF(IMR_ADDR) - -/* - * Define the names for bit positions first. This is useful for - * request_irq - */ -#define SPIM_IRQ_NUM 0 /* SPI Master interrupt */ -#define TMR2_IRQ_NUM 1 /* Timer 2 interrupt */ -#define UART_IRQ_NUM 2 /* UART interrupt */ -#define WDT_IRQ_NUM 3 /* Watchdog Timer interrupt */ -#define RTC_IRQ_NUM 4 /* RTC interrupt */ -#define KB_IRQ_NUM 6 /* Keyboard Interrupt */ -#define PWM_IRQ_NUM 7 /* Pulse-Width Modulator int. */ -#define INT0_IRQ_NUM 8 /* External INT0 */ -#define INT1_IRQ_NUM 9 /* External INT1 */ -#define INT2_IRQ_NUM 10 /* External INT2 */ -#define INT3_IRQ_NUM 11 /* External INT3 */ -#define INT4_IRQ_NUM 12 /* External INT4 */ -#define INT5_IRQ_NUM 13 /* External INT5 */ -#define INT6_IRQ_NUM 14 /* External INT6 */ -#define INT7_IRQ_NUM 15 /* External INT7 */ -#define IRQ1_IRQ_NUM 16 /* IRQ1 */ -#define IRQ2_IRQ_NUM 17 /* IRQ2 */ -#define IRQ3_IRQ_NUM 18 /* IRQ3 */ -#define IRQ6_IRQ_NUM 19 /* IRQ6 */ -#define PEN_IRQ_NUM 20 /* Pen Interrupt */ -#define SPIS_IRQ_NUM 21 /* SPI Slave Interrupt */ -#define TMR1_IRQ_NUM 22 /* Timer 1 interrupt */ -#define IRQ7_IRQ_NUM 23 /* IRQ7 */ - -/* '328-compatible definitions */ -#define SPI_IRQ_NUM SPIM_IRQ_NUM -#define TMR_IRQ_NUM TMR1_IRQ_NUM - -/* - * Here go the bitmasks themselves - */ -#define IMR_MSPIM (1 << SPIM _IRQ_NUM) /* Mask SPI Master interrupt */ -#define IMR_MTMR2 (1 << TMR2_IRQ_NUM) /* Mask Timer 2 interrupt */ -#define IMR_MUART (1 << UART_IRQ_NUM) /* Mask UART interrupt */ -#define IMR_MWDT (1 << WDT_IRQ_NUM) /* Mask Watchdog Timer interrupt */ -#define IMR_MRTC (1 << RTC_IRQ_NUM) /* Mask RTC interrupt */ -#define IMR_MKB (1 << KB_IRQ_NUM) /* Mask Keyboard Interrupt */ -#define IMR_MPWM (1 << PWM_IRQ_NUM) /* Mask Pulse-Width Modulator int. */ -#define IMR_MINT0 (1 << INT0_IRQ_NUM) /* Mask External INT0 */ -#define IMR_MINT1 (1 << INT1_IRQ_NUM) /* Mask External INT1 */ -#define IMR_MINT2 (1 << INT2_IRQ_NUM) /* Mask External INT2 */ -#define IMR_MINT3 (1 << INT3_IRQ_NUM) /* Mask External INT3 */ -#define IMR_MINT4 (1 << INT4_IRQ_NUM) /* Mask External INT4 */ -#define IMR_MINT5 (1 << INT5_IRQ_NUM) /* Mask External INT5 */ -#define IMR_MINT6 (1 << INT6_IRQ_NUM) /* Mask External INT6 */ -#define IMR_MINT7 (1 << INT7_IRQ_NUM) /* Mask External INT7 */ -#define IMR_MIRQ1 (1 << IRQ1_IRQ_NUM) /* Mask IRQ1 */ -#define IMR_MIRQ2 (1 << IRQ2_IRQ_NUM) /* Mask IRQ2 */ -#define IMR_MIRQ3 (1 << IRQ3_IRQ_NUM) /* Mask IRQ3 */ -#define IMR_MIRQ6 (1 << IRQ6_IRQ_NUM) /* Mask IRQ6 */ -#define IMR_MPEN (1 << PEN_IRQ_NUM) /* Mask Pen Interrupt */ -#define IMR_MSPIS (1 << SPIS_IRQ_NUM) /* Mask SPI Slave Interrupt */ -#define IMR_MTMR1 (1 << TMR1_IRQ_NUM) /* Mask Timer 1 interrupt */ -#define IMR_MIRQ7 (1 << IRQ7_IRQ_NUM) /* Mask IRQ7 */ - -/* 'EZ328-compatible definitions */ -#define IMR_MSPI IMR_MSPIM -#define IMR_MTMR IMR_MTMR1 - -/* - * Interrupt Wake-Up Enable Register - */ -#define IWR_ADDR 0xfffff308 -#define IWR LONG_REF(IWR_ADDR) - -#define IWR_SPIM (1 << SPIM _IRQ_NUM) /* SPI Master interrupt */ -#define IWR_TMR2 (1 << TMR2_IRQ_NUM) /* Timer 2 interrupt */ -#define IWR_UART (1 << UART_IRQ_NUM) /* UART interrupt */ -#define IWR_WDT (1 << WDT_IRQ_NUM) /* Watchdog Timer interrupt */ -#define IWR_RTC (1 << RTC_IRQ_NUM) /* RTC interrupt */ -#define IWR_KB (1 << KB_IRQ_NUM) /* Keyboard Interrupt */ -#define IWR_PWM (1 << PWM_IRQ_NUM) /* Pulse-Width Modulator int. */ -#define IWR_INT0 (1 << INT0_IRQ_NUM) /* External INT0 */ -#define IWR_INT1 (1 << INT1_IRQ_NUM) /* External INT1 */ -#define IWR_INT2 (1 << INT2_IRQ_NUM) /* External INT2 */ -#define IWR_INT3 (1 << INT3_IRQ_NUM) /* External INT3 */ -#define IWR_INT4 (1 << INT4_IRQ_NUM) /* External INT4 */ -#define IWR_INT5 (1 << INT5_IRQ_NUM) /* External INT5 */ -#define IWR_INT6 (1 << INT6_IRQ_NUM) /* External INT6 */ -#define IWR_INT7 (1 << INT7_IRQ_NUM) /* External INT7 */ -#define IWR_IRQ1 (1 << IRQ1_IRQ_NUM) /* IRQ1 */ -#define IWR_IRQ2 (1 << IRQ2_IRQ_NUM) /* IRQ2 */ -#define IWR_IRQ3 (1 << IRQ3_IRQ_NUM) /* IRQ3 */ -#define IWR_IRQ6 (1 << IRQ6_IRQ_NUM) /* IRQ6 */ -#define IWR_PEN (1 << PEN_IRQ_NUM) /* Pen Interrupt */ -#define IWR_SPIS (1 << SPIS_IRQ_NUM) /* SPI Slave Interrupt */ -#define IWR_TMR1 (1 << TMR1_IRQ_NUM) /* Timer 1 interrupt */ -#define IWR_IRQ7 (1 << IRQ7_IRQ_NUM) /* IRQ7 */ - -/* - * Interrupt Status Register - */ -#define ISR_ADDR 0xfffff30c -#define ISR LONG_REF(ISR_ADDR) - -#define ISR_SPIM (1 << SPIM _IRQ_NUM) /* SPI Master interrupt */ -#define ISR_TMR2 (1 << TMR2_IRQ_NUM) /* Timer 2 interrupt */ -#define ISR_UART (1 << UART_IRQ_NUM) /* UART interrupt */ -#define ISR_WDT (1 << WDT_IRQ_NUM) /* Watchdog Timer interrupt */ -#define ISR_RTC (1 << RTC_IRQ_NUM) /* RTC interrupt */ -#define ISR_KB (1 << KB_IRQ_NUM) /* Keyboard Interrupt */ -#define ISR_PWM (1 << PWM_IRQ_NUM) /* Pulse-Width Modulator int. */ -#define ISR_INT0 (1 << INT0_IRQ_NUM) /* External INT0 */ -#define ISR_INT1 (1 << INT1_IRQ_NUM) /* External INT1 */ -#define ISR_INT2 (1 << INT2_IRQ_NUM) /* External INT2 */ -#define ISR_INT3 (1 << INT3_IRQ_NUM) /* External INT3 */ -#define ISR_INT4 (1 << INT4_IRQ_NUM) /* External INT4 */ -#define ISR_INT5 (1 << INT5_IRQ_NUM) /* External INT5 */ -#define ISR_INT6 (1 << INT6_IRQ_NUM) /* External INT6 */ -#define ISR_INT7 (1 << INT7_IRQ_NUM) /* External INT7 */ -#define ISR_IRQ1 (1 << IRQ1_IRQ_NUM) /* IRQ1 */ -#define ISR_IRQ2 (1 << IRQ2_IRQ_NUM) /* IRQ2 */ -#define ISR_IRQ3 (1 << IRQ3_IRQ_NUM) /* IRQ3 */ -#define ISR_IRQ6 (1 << IRQ6_IRQ_NUM) /* IRQ6 */ -#define ISR_PEN (1 << PEN_IRQ_NUM) /* Pen Interrupt */ -#define ISR_SPIS (1 << SPIS_IRQ_NUM) /* SPI Slave Interrupt */ -#define ISR_TMR1 (1 << TMR1_IRQ_NUM) /* Timer 1 interrupt */ -#define ISR_IRQ7 (1 << IRQ7_IRQ_NUM) /* IRQ7 */ - -/* 'EZ328-compatible definitions */ -#define ISR_SPI ISR_SPIM -#define ISR_TMR ISR_TMR1 - -/* - * Interrupt Pending Register - */ -#define IPR_ADDR 0xfffff310 -#define IPR LONG_REF(IPR_ADDR) - -#define IPR_SPIM (1 << SPIM _IRQ_NUM) /* SPI Master interrupt */ -#define IPR_TMR2 (1 << TMR2_IRQ_NUM) /* Timer 2 interrupt */ -#define IPR_UART (1 << UART_IRQ_NUM) /* UART interrupt */ -#define IPR_WDT (1 << WDT_IRQ_NUM) /* Watchdog Timer interrupt */ -#define IPR_RTC (1 << RTC_IRQ_NUM) /* RTC interrupt */ -#define IPR_KB (1 << KB_IRQ_NUM) /* Keyboard Interrupt */ -#define IPR_PWM (1 << PWM_IRQ_NUM) /* Pulse-Width Modulator int. */ -#define IPR_INT0 (1 << INT0_IRQ_NUM) /* External INT0 */ -#define IPR_INT1 (1 << INT1_IRQ_NUM) /* External INT1 */ -#define IPR_INT2 (1 << INT2_IRQ_NUM) /* External INT2 */ -#define IPR_INT3 (1 << INT3_IRQ_NUM) /* External INT3 */ -#define IPR_INT4 (1 << INT4_IRQ_NUM) /* External INT4 */ -#define IPR_INT5 (1 << INT5_IRQ_NUM) /* External INT5 */ -#define IPR_INT6 (1 << INT6_IRQ_NUM) /* External INT6 */ -#define IPR_INT7 (1 << INT7_IRQ_NUM) /* External INT7 */ -#define IPR_IRQ1 (1 << IRQ1_IRQ_NUM) /* IRQ1 */ -#define IPR_IRQ2 (1 << IRQ2_IRQ_NUM) /* IRQ2 */ -#define IPR_IRQ3 (1 << IRQ3_IRQ_NUM) /* IRQ3 */ -#define IPR_IRQ6 (1 << IRQ6_IRQ_NUM) /* IRQ6 */ -#define IPR_PEN (1 << PEN_IRQ_NUM) /* Pen Interrupt */ -#define IPR_SPIS (1 << SPIS_IRQ_NUM) /* SPI Slave Interrupt */ -#define IPR_TMR1 (1 << TMR1_IRQ_NUM) /* Timer 1 interrupt */ -#define IPR_IRQ7 (1 << IRQ7_IRQ_NUM) /* IRQ7 */ - -/* 'EZ328-compatible definitions */ -#define IPR_SPI IPR_SPIM -#define IPR_TMR IPR_TMR1 - -/********** - * - * 0xFFFFF4xx -- Parallel Ports - * - **********/ - -/* - * Port A - */ -#define PADIR_ADDR 0xfffff400 /* Port A direction reg */ -#define PADATA_ADDR 0xfffff401 /* Port A data register */ -#define PASEL_ADDR 0xfffff403 /* Port A Select register */ - -#define PADIR BYTE_REF(PADIR_ADDR) -#define PADATA BYTE_REF(PADATA_ADDR) -#define PASEL BYTE_REF(PASEL_ADDR) - -#define PA(x) (1 << (x)) -#define PA_A(x) PA((x) - 16) /* This is specific to PA only! */ - -#define PA_A16 PA(0) /* Use A16 as PA(0) */ -#define PA_A17 PA(1) /* Use A17 as PA(1) */ -#define PA_A18 PA(2) /* Use A18 as PA(2) */ -#define PA_A19 PA(3) /* Use A19 as PA(3) */ -#define PA_A20 PA(4) /* Use A20 as PA(4) */ -#define PA_A21 PA(5) /* Use A21 as PA(5) */ -#define PA_A22 PA(6) /* Use A22 as PA(6) */ -#define PA_A23 PA(7) /* Use A23 as PA(7) */ - -/* - * Port B - */ -#define PBDIR_ADDR 0xfffff408 /* Port B direction reg */ -#define PBDATA_ADDR 0xfffff409 /* Port B data register */ -#define PBSEL_ADDR 0xfffff40b /* Port B Select Register */ - -#define PBDIR BYTE_REF(PBDIR_ADDR) -#define PBDATA BYTE_REF(PBDATA_ADDR) -#define PBSEL BYTE_REF(PBSEL_ADDR) - -#define PB(x) (1 << (x)) -#define PB_D(x) PB(x) /* This is specific to port B only */ - -#define PB_D0 PB(0) /* Use D0 as PB(0) */ -#define PB_D1 PB(1) /* Use D1 as PB(1) */ -#define PB_D2 PB(2) /* Use D2 as PB(2) */ -#define PB_D3 PB(3) /* Use D3 as PB(3) */ -#define PB_D4 PB(4) /* Use D4 as PB(4) */ -#define PB_D5 PB(5) /* Use D5 as PB(5) */ -#define PB_D6 PB(6) /* Use D6 as PB(6) */ -#define PB_D7 PB(7) /* Use D7 as PB(7) */ - -/* - * Port C - */ -#define PCDIR_ADDR 0xfffff410 /* Port C direction reg */ -#define PCDATA_ADDR 0xfffff411 /* Port C data register */ -#define PCSEL_ADDR 0xfffff413 /* Port C Select Register */ - -#define PCDIR BYTE_REF(PCDIR_ADDR) -#define PCDATA BYTE_REF(PCDATA_ADDR) -#define PCSEL BYTE_REF(PCSEL_ADDR) - -#define PC(x) (1 << (x)) - -#define PC_WE PC(6) /* Use WE as PC(6) */ -#define PC_DTACK PC(5) /* Use DTACK as PC(5) */ -#define PC_IRQ7 PC(4) /* Use IRQ7 as PC(4) */ -#define PC_LDS PC(2) /* Use LDS as PC(2) */ -#define PC_UDS PC(1) /* Use UDS as PC(1) */ -#define PC_MOCLK PC(0) /* Use MOCLK as PC(0) */ - -/* - * Port D - */ -#define PDDIR_ADDR 0xfffff418 /* Port D direction reg */ -#define PDDATA_ADDR 0xfffff419 /* Port D data register */ -#define PDPUEN_ADDR 0xfffff41a /* Port D Pull-Up enable reg */ -#define PDPOL_ADDR 0xfffff41c /* Port D Polarity Register */ -#define PDIRQEN_ADDR 0xfffff41d /* Port D IRQ enable register */ -#define PDIQEG_ADDR 0xfffff41f /* Port D IRQ Edge Register */ - -#define PDDIR BYTE_REF(PDDIR_ADDR) -#define PDDATA BYTE_REF(PDDATA_ADDR) -#define PDPUEN BYTE_REF(PDPUEN_ADDR) -#define PDPOL BYTE_REF(PDPOL_ADDR) -#define PDIRQEN BYTE_REF(PDIRQEN_ADDR) -#define PDIQEG BYTE_REF(PDIQEG_ADDR) - -#define PD(x) (1 << (x)) -#define PD_KB(x) PD(x) /* This is specific for Port D only */ - -#define PD_KB0 PD(0) /* Use KB0 as PD(0) */ -#define PD_KB1 PD(1) /* Use KB1 as PD(1) */ -#define PD_KB2 PD(2) /* Use KB2 as PD(2) */ -#define PD_KB3 PD(3) /* Use KB3 as PD(3) */ -#define PD_KB4 PD(4) /* Use KB4 as PD(4) */ -#define PD_KB5 PD(5) /* Use KB5 as PD(5) */ -#define PD_KB6 PD(6) /* Use KB6 as PD(6) */ -#define PD_KB7 PD(7) /* Use KB7 as PD(7) */ - -/* - * Port E - */ -#define PEDIR_ADDR 0xfffff420 /* Port E direction reg */ -#define PEDATA_ADDR 0xfffff421 /* Port E data register */ -#define PEPUEN_ADDR 0xfffff422 /* Port E Pull-Up enable reg */ -#define PESEL_ADDR 0xfffff423 /* Port E Select Register */ - -#define PEDIR BYTE_REF(PEDIR_ADDR) -#define PEDATA BYTE_REF(PEDATA_ADDR) -#define PEPUEN BYTE_REF(PEPUEN_ADDR) -#define PESEL BYTE_REF(PESEL_ADDR) - -#define PE(x) (1 << (x)) - -#define PE_CSA1 PE(1) /* Use CSA1 as PE(1) */ -#define PE_CSA2 PE(2) /* Use CSA2 as PE(2) */ -#define PE_CSA3 PE(3) /* Use CSA3 as PE(3) */ -#define PE_CSB0 PE(4) /* Use CSB0 as PE(4) */ -#define PE_CSB1 PE(5) /* Use CSB1 as PE(5) */ -#define PE_CSB2 PE(6) /* Use CSB2 as PE(6) */ -#define PE_CSB3 PE(7) /* Use CSB3 as PE(7) */ - -/* - * Port F - */ -#define PFDIR_ADDR 0xfffff428 /* Port F direction reg */ -#define PFDATA_ADDR 0xfffff429 /* Port F data register */ -#define PFPUEN_ADDR 0xfffff42a /* Port F Pull-Up enable reg */ -#define PFSEL_ADDR 0xfffff42b /* Port F Select Register */ - -#define PFDIR BYTE_REF(PFDIR_ADDR) -#define PFDATA BYTE_REF(PFDATA_ADDR) -#define PFPUEN BYTE_REF(PFPUEN_ADDR) -#define PFSEL BYTE_REF(PFSEL_ADDR) - -#define PF(x) (1 << (x)) -#define PF_A(x) PF((x) - 24) /* This is Port F specific only */ - -#define PF_A24 PF(0) /* Use A24 as PF(0) */ -#define PF_A25 PF(1) /* Use A25 as PF(1) */ -#define PF_A26 PF(2) /* Use A26 as PF(2) */ -#define PF_A27 PF(3) /* Use A27 as PF(3) */ -#define PF_A28 PF(4) /* Use A28 as PF(4) */ -#define PF_A29 PF(5) /* Use A29 as PF(5) */ -#define PF_A30 PF(6) /* Use A30 as PF(6) */ -#define PF_A31 PF(7) /* Use A31 as PF(7) */ - -/* - * Port G - */ -#define PGDIR_ADDR 0xfffff430 /* Port G direction reg */ -#define PGDATA_ADDR 0xfffff431 /* Port G data register */ -#define PGPUEN_ADDR 0xfffff432 /* Port G Pull-Up enable reg */ -#define PGSEL_ADDR 0xfffff433 /* Port G Select Register */ - -#define PGDIR BYTE_REF(PGDIR_ADDR) -#define PGDATA BYTE_REF(PGDATA_ADDR) -#define PGPUEN BYTE_REF(PGPUEN_ADDR) -#define PGSEL BYTE_REF(PGSEL_ADDR) - -#define PG(x) (1 << (x)) - -#define PG_UART_TXD PG(0) /* Use UART_TXD as PG(0) */ -#define PG_UART_RXD PG(1) /* Use UART_RXD as PG(1) */ -#define PG_PWMOUT PG(2) /* Use PWMOUT as PG(2) */ -#define PG_TOUT2 PG(3) /* Use TOUT2 as PG(3) */ -#define PG_TIN2 PG(4) /* Use TIN2 as PG(4) */ -#define PG_TOUT1 PG(5) /* Use TOUT1 as PG(5) */ -#define PG_TIN1 PG(6) /* Use TIN1 as PG(6) */ -#define PG_RTCOUT PG(7) /* Use RTCOUT as PG(7) */ - -/* - * Port J - */ -#define PJDIR_ADDR 0xfffff438 /* Port J direction reg */ -#define PJDATA_ADDR 0xfffff439 /* Port J data register */ -#define PJSEL_ADDR 0xfffff43b /* Port J Select Register */ - -#define PJDIR BYTE_REF(PJDIR_ADDR) -#define PJDATA BYTE_REF(PJDATA_ADDR) -#define PJSEL BYTE_REF(PJSEL_ADDR) - -#define PJ(x) (1 << (x)) - -#define PJ_CSD3 PJ(7) /* Use CSD3 as PJ(7) */ - -/* - * Port K - */ -#define PKDIR_ADDR 0xfffff440 /* Port K direction reg */ -#define PKDATA_ADDR 0xfffff441 /* Port K data register */ -#define PKPUEN_ADDR 0xfffff442 /* Port K Pull-Up enable reg */ -#define PKSEL_ADDR 0xfffff443 /* Port K Select Register */ - -#define PKDIR BYTE_REF(PKDIR_ADDR) -#define PKDATA BYTE_REF(PKDATA_ADDR) -#define PKPUEN BYTE_REF(PKPUEN_ADDR) -#define PKSEL BYTE_REF(PKSEL_ADDR) - -#define PK(x) (1 << (x)) - -/* - * Port M - */ -#define PMDIR_ADDR 0xfffff438 /* Port M direction reg */ -#define PMDATA_ADDR 0xfffff439 /* Port M data register */ -#define PMPUEN_ADDR 0xfffff43a /* Port M Pull-Up enable reg */ -#define PMSEL_ADDR 0xfffff43b /* Port M Select Register */ - -#define PMDIR BYTE_REF(PMDIR_ADDR) -#define PMDATA BYTE_REF(PMDATA_ADDR) -#define PMPUEN BYTE_REF(PMPUEN_ADDR) -#define PMSEL BYTE_REF(PMSEL_ADDR) - -#define PM(x) (1 << (x)) - -/********** - * - * 0xFFFFF5xx -- Pulse-Width Modulator (PWM) - * - **********/ - -/* - * PWM Control Register - */ -#define PWMC_ADDR 0xfffff500 -#define PWMC WORD_REF(PWMC_ADDR) - -#define PWMC_CLKSEL_MASK 0x0007 /* Clock Selection */ -#define PWMC_CLKSEL_SHIFT 0 -#define PWMC_PWMEN 0x0010 /* Enable PWM */ -#define PMNC_POL 0x0020 /* PWM Output Bit Polarity */ -#define PWMC_PIN 0x0080 /* Current PWM output pin status */ -#define PWMC_LOAD 0x0100 /* Force a new period */ -#define PWMC_IRQEN 0x4000 /* Interrupt Request Enable */ -#define PWMC_CLKSRC 0x8000 /* Clock Source Select */ - -/* 'EZ328-compatible definitions */ -#define PWMC_EN PWMC_PWMEN - -/* - * PWM Period Register - */ -#define PWMP_ADDR 0xfffff502 -#define PWMP WORD_REF(PWMP_ADDR) - -/* - * PWM Width Register - */ -#define PWMW_ADDR 0xfffff504 -#define PWMW WORD_REF(PWMW_ADDR) - -/* - * PWM Counter Register - */ -#define PWMCNT_ADDR 0xfffff506 -#define PWMCNT WORD_REF(PWMCNT_ADDR) - -/********** - * - * 0xFFFFF6xx -- General-Purpose Timers - * - **********/ - -/* - * Timer Unit 1 and 2 Control Registers - */ -#define TCTL1_ADDR 0xfffff600 -#define TCTL1 WORD_REF(TCTL1_ADDR) -#define TCTL2_ADDR 0xfffff60c -#define TCTL2 WORD_REF(TCTL2_ADDR) - -#define TCTL_TEN 0x0001 /* Timer Enable */ -#define TCTL_CLKSOURCE_MASK 0x000e /* Clock Source: */ -#define TCTL_CLKSOURCE_STOP 0x0000 /* Stop count (disabled) */ -#define TCTL_CLKSOURCE_SYSCLK 0x0002 /* SYSCLK to prescaler */ -#define TCTL_CLKSOURCE_SYSCLK_16 0x0004 /* SYSCLK/16 to prescaler */ -#define TCTL_CLKSOURCE_TIN 0x0006 /* TIN to prescaler */ -#define TCTL_CLKSOURCE_32KHZ 0x0008 /* 32kHz clock to prescaler */ -#define TCTL_IRQEN 0x0010 /* IRQ Enable */ -#define TCTL_OM 0x0020 /* Output Mode */ -#define TCTL_CAP_MASK 0x00c0 /* Capture Edge: */ -#define TCTL_CAP_RE 0x0040 /* Capture on rizing edge */ -#define TCTL_CAP_FE 0x0080 /* Capture on falling edge */ -#define TCTL_FRR 0x0010 /* Free-Run Mode */ - -/* 'EZ328-compatible definitions */ -#define TCTL_ADDR TCTL1_ADDR -#define TCTL TCTL1 - -/* - * Timer Unit 1 and 2 Prescaler Registers - */ -#define TPRER1_ADDR 0xfffff602 -#define TPRER1 WORD_REF(TPRER1_ADDR) -#define TPRER2_ADDR 0xfffff60e -#define TPRER2 WORD_REF(TPRER2_ADDR) - -/* 'EZ328-compatible definitions */ -#define TPRER_ADDR TPRER1_ADDR -#define TPRER TPRER1 - -/* - * Timer Unit 1 and 2 Compare Registers - */ -#define TCMP1_ADDR 0xfffff604 -#define TCMP1 WORD_REF(TCMP1_ADDR) -#define TCMP2_ADDR 0xfffff610 -#define TCMP2 WORD_REF(TCMP2_ADDR) - -/* 'EZ328-compatible definitions */ -#define TCMP_ADDR TCMP1_ADDR -#define TCMP TCMP1 - -/* - * Timer Unit 1 and 2 Capture Registers - */ -#define TCR1_ADDR 0xfffff606 -#define TCR1 WORD_REF(TCR1_ADDR) -#define TCR2_ADDR 0xfffff612 -#define TCR2 WORD_REF(TCR2_ADDR) - -/* 'EZ328-compatible definitions */ -#define TCR_ADDR TCR1_ADDR -#define TCR TCR1 - -/* - * Timer Unit 1 and 2 Counter Registers - */ -#define TCN1_ADDR 0xfffff608 -#define TCN1 WORD_REF(TCN1_ADDR) -#define TCN2_ADDR 0xfffff614 -#define TCN2 WORD_REF(TCN2_ADDR) - -/* 'EZ328-compatible definitions */ -#define TCN_ADDR TCN1_ADDR -#define TCN TCN - -/* - * Timer Unit 1 and 2 Status Registers - */ -#define TSTAT1_ADDR 0xfffff60a -#define TSTAT1 WORD_REF(TSTAT1_ADDR) -#define TSTAT2_ADDR 0xfffff616 -#define TSTAT2 WORD_REF(TSTAT2_ADDR) - -#define TSTAT_COMP 0x0001 /* Compare Event occurred */ -#define TSTAT_CAPT 0x0001 /* Capture Event occurred */ - -/* 'EZ328-compatible definitions */ -#define TSTAT_ADDR TSTAT1_ADDR -#define TSTAT TSTAT1 - -/* - * Watchdog Compare Register - */ -#define WRR_ADDR 0xfffff61a -#define WRR WORD_REF(WRR_ADDR) - -/* - * Watchdog Counter Register - */ -#define WCN_ADDR 0xfffff61c -#define WCN WORD_REF(WCN_ADDR) - -/* - * Watchdog Control and Status Register - */ -#define WCSR_ADDR 0xfffff618 -#define WCSR WORD_REF(WCSR_ADDR) - -#define WCSR_WDEN 0x0001 /* Watchdog Enable */ -#define WCSR_FI 0x0002 /* Forced Interrupt (instead of SW reset)*/ -#define WCSR_WRST 0x0004 /* Watchdog Reset */ - -/********** - * - * 0xFFFFF7xx -- Serial Periferial Interface Slave (SPIS) - * - **********/ - -/* - * SPI Slave Register - */ -#define SPISR_ADDR 0xfffff700 -#define SPISR WORD_REF(SPISR_ADDR) - -#define SPISR_DATA_ADDR 0xfffff701 -#define SPISR_DATA BYTE_REF(SPISR_DATA_ADDR) - -#define SPISR_DATA_MASK 0x00ff /* Shifted data from the external device */ -#define SPISR_DATA_SHIFT 0 -#define SPISR_SPISEN 0x0100 /* SPIS module enable */ -#define SPISR_POL 0x0200 /* SPSCLK polarity control */ -#define SPISR_PHA 0x0400 /* Phase relationship between SPSCLK & SPSRxD */ -#define SPISR_OVWR 0x0800 /* Data buffer has been overwritten */ -#define SPISR_DATARDY 0x1000 /* Data ready */ -#define SPISR_ENPOL 0x2000 /* Enable Polarity */ -#define SPISR_IRQEN 0x4000 /* SPIS IRQ Enable */ -#define SPISR_SPISIRQ 0x8000 /* SPIS IRQ posted */ - -/********** - * - * 0xFFFFF8xx -- Serial Periferial Interface Master (SPIM) - * - **********/ - -/* - * SPIM Data Register - */ -#define SPIMDATA_ADDR 0xfffff800 -#define SPIMDATA WORD_REF(SPIMDATA_ADDR) - -/* - * SPIM Control/Status Register - */ -#define SPIMCONT_ADDR 0xfffff802 -#define SPIMCONT WORD_REF(SPIMCONT_ADDR) - -#define SPIMCONT_BIT_COUNT_MASK 0x000f /* Transfer Length in Bytes */ -#define SPIMCONT_BIT_COUNT_SHIFT 0 -#define SPIMCONT_POL 0x0010 /* SPMCLK Signel Polarity */ -#define SPIMCONT_PHA 0x0020 /* Clock/Data phase relationship */ -#define SPIMCONT_IRQEN 0x0040 /* IRQ Enable */ -#define SPIMCONT_SPIMIRQ 0x0080 /* Interrupt Request */ -#define SPIMCONT_XCH 0x0100 /* Exchange */ -#define SPIMCONT_RSPIMEN 0x0200 /* Enable SPIM */ -#define SPIMCONT_DATA_RATE_MASK 0xe000 /* SPIM Data Rate */ -#define SPIMCONT_DATA_RATE_SHIFT 13 - -/* 'EZ328-compatible definitions */ -#define SPIMCONT_IRQ SPIMCONT_SPIMIRQ -#define SPIMCONT_ENABLE SPIMCONT_SPIMEN -/********** - * - * 0xFFFFF9xx -- UART - * - **********/ - -/* - * UART Status/Control Register - */ -#define USTCNT_ADDR 0xfffff900 -#define USTCNT WORD_REF(USTCNT_ADDR) - -#define USTCNT_TXAVAILEN 0x0001 /* Transmitter Available Int Enable */ -#define USTCNT_TXHALFEN 0x0002 /* Transmitter Half Empty Int Enable */ -#define USTCNT_TXEMPTYEN 0x0004 /* Transmitter Empty Int Enable */ -#define USTCNT_RXREADYEN 0x0008 /* Receiver Ready Interrupt Enable */ -#define USTCNT_RXHALFEN 0x0010 /* Receiver Half-Full Int Enable */ -#define USTCNT_RXFULLEN 0x0020 /* Receiver Full Interrupt Enable */ -#define USTCNT_CTSDELTAEN 0x0040 /* CTS Delta Interrupt Enable */ -#define USTCNT_GPIODELTAEN 0x0080 /* Old Data Interrupt Enable */ -#define USTCNT_8_7 0x0100 /* Eight or seven-bit transmission */ -#define USTCNT_STOP 0x0200 /* Stop bit transmission */ -#define USTCNT_ODD_EVEN 0x0400 /* Odd Parity */ -#define USTCNT_PARITYEN 0x0800 /* Parity Enable */ -#define USTCNT_CLKMODE 0x1000 /* Clock Mode Select */ -#define USTCNT_TXEN 0x2000 /* Transmitter Enable */ -#define USTCNT_RXEN 0x4000 /* Receiver Enable */ -#define USTCNT_UARTEN 0x8000 /* UART Enable */ - -/* 'EZ328-compatible definitions */ -#define USTCNT_TXAE USTCNT_TXAVAILEN -#define USTCNT_TXHE USTCNT_TXHALFEN -#define USTCNT_TXEE USTCNT_TXEMPTYEN -#define USTCNT_RXRE USTCNT_RXREADYEN -#define USTCNT_RXHE USTCNT_RXHALFEN -#define USTCNT_RXFE USTCNT_RXFULLEN -#define USTCNT_CTSD USTCNT_CTSDELTAEN -#define USTCNT_ODD USTCNT_ODD_EVEN -#define USTCNT_PEN USTCNT_PARITYEN -#define USTCNT_CLKM USTCNT_CLKMODE -#define USTCNT_UEN USTCNT_UARTEN - -/* - * UART Baud Control Register - */ -#define UBAUD_ADDR 0xfffff902 -#define UBAUD WORD_REF(UBAUD_ADDR) - -#define UBAUD_PRESCALER_MASK 0x003f /* Actual divisor is 65 - PRESCALER */ -#define UBAUD_PRESCALER_SHIFT 0 -#define UBAUD_DIVIDE_MASK 0x0700 /* Baud Rate freq. divizor */ -#define UBAUD_DIVIDE_SHIFT 8 -#define UBAUD_BAUD_SRC 0x0800 /* Baud Rate Source */ -#define UBAUD_GPIOSRC 0x1000 /* GPIO source */ -#define UBAUD_GPIODIR 0x2000 /* GPIO Direction */ -#define UBAUD_GPIO 0x4000 /* Current GPIO pin status */ -#define UBAUD_GPIODELTA 0x8000 /* GPIO pin value changed */ - -/* - * UART Receiver Register - */ -#define URX_ADDR 0xfffff904 -#define URX WORD_REF(URX_ADDR) - -#define URX_RXDATA_ADDR 0xfffff905 -#define URX_RXDATA BYTE_REF(URX_RXDATA_ADDR) - -#define URX_RXDATA_MASK 0x00ff /* Received data */ -#define URX_RXDATA_SHIFT 0 -#define URX_PARITY_ERROR 0x0100 /* Parity Error */ -#define URX_BREAK 0x0200 /* Break Detected */ -#define URX_FRAME_ERROR 0x0400 /* Framing Error */ -#define URX_OVRUN 0x0800 /* Serial Overrun */ -#define URX_DATA_READY 0x2000 /* Data Ready (FIFO not empty) */ -#define URX_FIFO_HALF 0x4000 /* FIFO is Half-Full */ -#define URX_FIFO_FULL 0x8000 /* FIFO is Full */ - -/* - * UART Transmitter Register - */ -#define UTX_ADDR 0xfffff906 -#define UTX WORD_REF(UTX_ADDR) - -#define UTX_TXDATA_ADDR 0xfffff907 -#define UTX_TXDATA BYTE_REF(UTX_TXDATA_ADDR) - -#define UTX_TXDATA_MASK 0x00ff /* Data to be transmitted */ -#define UTX_TXDATA_SHIFT 0 -#define UTX_CTS_DELTA 0x0100 /* CTS changed */ -#define UTX_CTS_STATUS 0x0200 /* CTS State */ -#define UTX_IGNORE_CTS 0x0800 /* Ignore CTS */ -#define UTX_SEND_BREAK 0x1000 /* Send a BREAK */ -#define UTX_TX_AVAIL 0x2000 /* Transmit FIFO has a slot available */ -#define UTX_FIFO_HALF 0x4000 /* Transmit FIFO is half empty */ -#define UTX_FIFO_EMPTY 0x8000 /* Transmit FIFO is empty */ - -/* 'EZ328-compatible definitions */ -#define UTX_CTS_STAT UTX_CTS_STATUS -#define UTX_NOCTS UTX_IGNORE_CTS - -/* - * UART Miscellaneous Register - */ -#define UMISC_ADDR 0xfffff908 -#define UMISC WORD_REF(UMISC_ADDR) - -#define UMISC_TX_POL 0x0004 /* Transmit Polarity */ -#define UMISC_RX_POL 0x0008 /* Receive Polarity */ -#define UMISC_IRDA_LOOP 0x0010 /* IrDA Loopback Enable */ -#define UMISC_IRDA_EN 0x0020 /* Infra-Red Enable */ -#define UMISC_RTS 0x0040 /* Set RTS status */ -#define UMISC_RTSCONT 0x0080 /* Choose RTS control */ -#define UMISC_LOOP 0x1000 /* Serial Loopback Enable */ -#define UMISC_FORCE_PERR 0x2000 /* Force Parity Error */ -#define UMISC_CLKSRC 0x4000 /* Clock Source */ - - -/* generalization of uart control registers to support multiple ports: */ -typedef volatile struct { - volatile unsigned short int ustcnt; - volatile unsigned short int ubaud; - union { - volatile unsigned short int w; - struct { - volatile unsigned char status; - volatile unsigned char rxdata; - } b; - } urx; - union { - volatile unsigned short int w; - struct { - volatile unsigned char status; - volatile unsigned char txdata; - } b; - } utx; - volatile unsigned short int umisc; - volatile unsigned short int pad1; - volatile unsigned short int pad2; - volatile unsigned short int pad3; -} __attribute__((packed)) m68328_uart; - - -/********** - * - * 0xFFFFFAxx -- LCD Controller - * - **********/ - -/* - * LCD Screen Starting Address Register - */ -#define LSSA_ADDR 0xfffffa00 -#define LSSA LONG_REF(LSSA_ADDR) - -#define LSSA_SSA_MASK 0xfffffffe /* Bit 0 is reserved */ - -/* - * LCD Virtual Page Width Register - */ -#define LVPW_ADDR 0xfffffa05 -#define LVPW BYTE_REF(LVPW_ADDR) - -/* - * LCD Screen Width Register (not compatible with 'EZ328 !!!) - */ -#define LXMAX_ADDR 0xfffffa08 -#define LXMAX WORD_REF(LXMAX_ADDR) - -#define LXMAX_XM_MASK 0x02ff /* Bits 0-3 are reserved */ - -/* - * LCD Screen Height Register - */ -#define LYMAX_ADDR 0xfffffa0a -#define LYMAX WORD_REF(LYMAX_ADDR) - -#define LYMAX_YM_MASK 0x02ff /* Bits 10-15 are reserved */ - -/* - * LCD Cursor X Position Register - */ -#define LCXP_ADDR 0xfffffa18 -#define LCXP WORD_REF(LCXP_ADDR) - -#define LCXP_CC_MASK 0xc000 /* Cursor Control */ -#define LCXP_CC_TRAMSPARENT 0x0000 -#define LCXP_CC_BLACK 0x4000 -#define LCXP_CC_REVERSED 0x8000 -#define LCXP_CC_WHITE 0xc000 -#define LCXP_CXP_MASK 0x02ff /* Cursor X position */ - -/* - * LCD Cursor Y Position Register - */ -#define LCYP_ADDR 0xfffffa1a -#define LCYP WORD_REF(LCYP_ADDR) - -#define LCYP_CYP_MASK 0x01ff /* Cursor Y Position */ - -/* - * LCD Cursor Width and Heigth Register - */ -#define LCWCH_ADDR 0xfffffa1c -#define LCWCH WORD_REF(LCWCH_ADDR) - -#define LCWCH_CH_MASK 0x001f /* Cursor Height */ -#define LCWCH_CH_SHIFT 0 -#define LCWCH_CW_MASK 0x1f00 /* Cursor Width */ -#define LCWCH_CW_SHIFT 8 - -/* - * LCD Blink Control Register - */ -#define LBLKC_ADDR 0xfffffa1f -#define LBLKC BYTE_REF(LBLKC_ADDR) - -#define LBLKC_BD_MASK 0x7f /* Blink Divisor */ -#define LBLKC_BD_SHIFT 0 -#define LBLKC_BKEN 0x80 /* Blink Enabled */ - -/* - * LCD Panel Interface Configuration Register - */ -#define LPICF_ADDR 0xfffffa20 -#define LPICF BYTE_REF(LPICF_ADDR) - -#define LPICF_GS_MASK 0x01 /* Gray-Scale Mode */ -#define LPICF_GS_BW 0x00 -#define LPICF_GS_GRAY_4 0x01 -#define LPICF_PBSIZ_MASK 0x06 /* Panel Bus Width */ -#define LPICF_PBSIZ_1 0x00 -#define LPICF_PBSIZ_2 0x02 -#define LPICF_PBSIZ_4 0x04 - -/* - * LCD Polarity Configuration Register - */ -#define LPOLCF_ADDR 0xfffffa21 -#define LPOLCF BYTE_REF(LPOLCF_ADDR) - -#define LPOLCF_PIXPOL 0x01 /* Pixel Polarity */ -#define LPOLCF_LPPOL 0x02 /* Line Pulse Polarity */ -#define LPOLCF_FLMPOL 0x04 /* Frame Marker Polarity */ -#define LPOLCF_LCKPOL 0x08 /* LCD Shift Lock Polarity */ - -/* - * LACD (LCD Alternate Crystal Direction) Rate Control Register - */ -#define LACDRC_ADDR 0xfffffa23 -#define LACDRC BYTE_REF(LACDRC_ADDR) - -#define LACDRC_ACD_MASK 0x0f /* Alternate Crystal Direction Control */ -#define LACDRC_ACD_SHIFT 0 - -/* - * LCD Pixel Clock Divider Register - */ -#define LPXCD_ADDR 0xfffffa25 -#define LPXCD BYTE_REF(LPXCD_ADDR) - -#define LPXCD_PCD_MASK 0x3f /* Pixel Clock Divider */ -#define LPXCD_PCD_SHIFT 0 - -/* - * LCD Clocking Control Register - */ -#define LCKCON_ADDR 0xfffffa27 -#define LCKCON BYTE_REF(LCKCON_ADDR) - -#define LCKCON_PCDS 0x01 /* Pixel Clock Divider Source Select */ -#define LCKCON_DWIDTH 0x02 /* Display Memory Width */ -#define LCKCON_DWS_MASK 0x3c /* Display Wait-State */ -#define LCKCON_DWS_SHIFT 2 -#define LCKCON_DMA16 0x40 /* DMA burst length */ -#define LCKCON_LCDON 0x80 /* Enable LCD Controller */ - -/* 'EZ328-compatible definitions */ -#define LCKCON_DW_MASK LCKCON_DWS_MASK -#define LCKCON_DW_SHIFT LCKCON_DWS_SHIFT - -/* - * LCD Last Buffer Address Register - */ -#define LLBAR_ADDR 0xfffffa29 -#define LLBAR BYTE_REF(LLBAR_ADDR) - -#define LLBAR_LBAR_MASK 0x7f /* Number of memory words to fill 1 line */ -#define LLBAR_LBAR_SHIFT 0 - -/* - * LCD Octet Terminal Count Register - */ -#define LOTCR_ADDR 0xfffffa2b -#define LOTCR BYTE_REF(LOTCR_ADDR) - -/* - * LCD Panning Offset Register - */ -#define LPOSR_ADDR 0xfffffa2d -#define LPOSR BYTE_REF(LPOSR_ADDR) - -#define LPOSR_BOS 0x08 /* Byte offset (for B/W mode only */ -#define LPOSR_POS_MASK 0x07 /* Pixel Offset Code */ -#define LPOSR_POS_SHIFT 0 - -/* - * LCD Frame Rate Control Modulation Register - */ -#define LFRCM_ADDR 0xfffffa31 -#define LFRCM BYTE_REF(LFRCM_ADDR) - -#define LFRCM_YMOD_MASK 0x0f /* Vertical Modulation */ -#define LFRCM_YMOD_SHIFT 0 -#define LFRCM_XMOD_MASK 0xf0 /* Horizontal Modulation */ -#define LFRCM_XMOD_SHIFT 4 - -/* - * LCD Gray Palette Mapping Register - */ -#define LGPMR_ADDR 0xfffffa32 -#define LGPMR WORD_REF(LGPMR_ADDR) - -#define LGPMR_GLEVEL3_MASK 0x000f -#define LGPMR_GLEVEL3_SHIFT 0 -#define LGPMR_GLEVEL2_MASK 0x00f0 -#define LGPMR_GLEVEL2_SHIFT 4 -#define LGPMR_GLEVEL0_MASK 0x0f00 -#define LGPMR_GLEVEL0_SHIFT 8 -#define LGPMR_GLEVEL1_MASK 0xf000 -#define LGPMR_GLEVEL1_SHIFT 12 - -/********** - * - * 0xFFFFFBxx -- Real-Time Clock (RTC) - * - **********/ - -/* - * RTC Hours Minutes and Seconds Register - */ -#define RTCTIME_ADDR 0xfffffb00 -#define RTCTIME LONG_REF(RTCTIME_ADDR) - -#define RTCTIME_SECONDS_MASK 0x0000003f /* Seconds */ -#define RTCTIME_SECONDS_SHIFT 0 -#define RTCTIME_MINUTES_MASK 0x003f0000 /* Minutes */ -#define RTCTIME_MINUTES_SHIFT 16 -#define RTCTIME_HOURS_MASK 0x1f000000 /* Hours */ -#define RTCTIME_HOURS_SHIFT 24 - -/* - * RTC Alarm Register - */ -#define RTCALRM_ADDR 0xfffffb04 -#define RTCALRM LONG_REF(RTCALRM_ADDR) - -#define RTCALRM_SECONDS_MASK 0x0000003f /* Seconds */ -#define RTCALRM_SECONDS_SHIFT 0 -#define RTCALRM_MINUTES_MASK 0x003f0000 /* Minutes */ -#define RTCALRM_MINUTES_SHIFT 16 -#define RTCALRM_HOURS_MASK 0x1f000000 /* Hours */ -#define RTCALRM_HOURS_SHIFT 24 - -/* - * RTC Control Register - */ -#define RTCCTL_ADDR 0xfffffb0c -#define RTCCTL WORD_REF(RTCCTL_ADDR) - -#define RTCCTL_384 0x0020 /* Crystal Selection */ -#define RTCCTL_ENABLE 0x0080 /* RTC Enable */ - -/* 'EZ328-compatible definitions */ -#define RTCCTL_XTL RTCCTL_384 -#define RTCCTL_EN RTCCTL_ENABLE - -/* - * RTC Interrupt Status Register - */ -#define RTCISR_ADDR 0xfffffb0e -#define RTCISR WORD_REF(RTCISR_ADDR) - -#define RTCISR_SW 0x0001 /* Stopwatch timed out */ -#define RTCISR_MIN 0x0002 /* 1-minute interrupt has occurred */ -#define RTCISR_ALM 0x0004 /* Alarm interrupt has occurred */ -#define RTCISR_DAY 0x0008 /* 24-hour rollover interrupt has occurred */ -#define RTCISR_1HZ 0x0010 /* 1Hz interrupt has occurred */ - -/* - * RTC Interrupt Enable Register - */ -#define RTCIENR_ADDR 0xfffffb10 -#define RTCIENR WORD_REF(RTCIENR_ADDR) - -#define RTCIENR_SW 0x0001 /* Stopwatch interrupt enable */ -#define RTCIENR_MIN 0x0002 /* 1-minute interrupt enable */ -#define RTCIENR_ALM 0x0004 /* Alarm interrupt enable */ -#define RTCIENR_DAY 0x0008 /* 24-hour rollover interrupt enable */ -#define RTCIENR_1HZ 0x0010 /* 1Hz interrupt enable */ - -/* - * Stopwatch Minutes Register - */ -#define STPWCH_ADDR 0xfffffb12 -#define STPWCH WORD_REF(STPWCH) - -#define STPWCH_CNT_MASK 0x00ff /* Stopwatch countdown value */ -#define SPTWCH_CNT_SHIFT 0 - -#endif /* _MC68328_H_ */ diff --git a/arch/m68knommu/include/asm/MC68332.h b/arch/m68knommu/include/asm/MC68332.h deleted file mode 100644 index 6bb8f02685a..00000000000 --- a/arch/m68knommu/include/asm/MC68332.h +++ /dev/null @@ -1,152 +0,0 @@ - -/* include/asm-m68knommu/MC68332.h: '332 control registers - * - * Copyright (C) 1998 Kenneth Albanowski , - * - */ - -#ifndef _MC68332_H_ -#define _MC68332_H_ - -#define BYTE_REF(addr) (*((volatile unsigned char*)addr)) -#define WORD_REF(addr) (*((volatile unsigned short*)addr)) - -#define PORTE_ADDR 0xfffa11 -#define PORTE BYTE_REF(PORTE_ADDR) -#define DDRE_ADDR 0xfffa15 -#define DDRE BYTE_REF(DDRE_ADDR) -#define PEPAR_ADDR 0xfffa17 -#define PEPAR BYTE_REF(PEPAR_ADDR) - -#define PORTF_ADDR 0xfffa19 -#define PORTF BYTE_REF(PORTF_ADDR) -#define DDRF_ADDR 0xfffa1d -#define DDRF BYTE_REF(DDRF_ADDR) -#define PFPAR_ADDR 0xfffa1f -#define PFPAR BYTE_REF(PFPAR_ADDR) - -#define PORTQS_ADDR 0xfffc15 -#define PORTQS BYTE_REF(PORTQS_ADDR) -#define DDRQS_ADDR 0xfffc17 -#define DDRQS BYTE_REF(DDRQS_ADDR) -#define PQSPAR_ADDR 0xfffc16 -#define PQSPAR BYTE_REF(PQSPAR_ADDR) - -#define CSPAR0_ADDR 0xFFFA44 -#define CSPAR0 WORD_REF(CSPAR0_ADDR) -#define CSPAR1_ADDR 0xFFFA46 -#define CSPAR1 WORD_REF(CSPAR1_ADDR) -#define CSARBT_ADDR 0xFFFA48 -#define CSARBT WORD_REF(CSARBT_ADDR) -#define CSOPBT_ADDR 0xFFFA4A -#define CSOPBT WORD_REF(CSOPBT_ADDR) -#define CSBAR0_ADDR 0xFFFA4C -#define CSBAR0 WORD_REF(CSBAR0_ADDR) -#define CSOR0_ADDR 0xFFFA4E -#define CSOR0 WORD_REF(CSOR0_ADDR) -#define CSBAR1_ADDR 0xFFFA50 -#define CSBAR1 WORD_REF(CSBAR1_ADDR) -#define CSOR1_ADDR 0xFFFA52 -#define CSOR1 WORD_REF(CSOR1_ADDR) -#define CSBAR2_ADDR 0xFFFA54 -#define CSBAR2 WORD_REF(CSBAR2_ADDR) -#define CSOR2_ADDR 0xFFFA56 -#define CSOR2 WORD_REF(CSOR2_ADDR) -#define CSBAR3_ADDR 0xFFFA58 -#define CSBAR3 WORD_REF(CSBAR3_ADDR) -#define CSOR3_ADDR 0xFFFA5A -#define CSOR3 WORD_REF(CSOR3_ADDR) -#define CSBAR4_ADDR 0xFFFA5C -#define CSBAR4 WORD_REF(CSBAR4_ADDR) -#define CSOR4_ADDR 0xFFFA5E -#define CSOR4 WORD_REF(CSOR4_ADDR) -#define CSBAR5_ADDR 0xFFFA60 -#define CSBAR5 WORD_REF(CSBAR5_ADDR) -#define CSOR5_ADDR 0xFFFA62 -#define CSOR5 WORD_REF(CSOR5_ADDR) -#define CSBAR6_ADDR 0xFFFA64 -#define CSBAR6 WORD_REF(CSBAR6_ADDR) -#define CSOR6_ADDR 0xFFFA66 -#define CSOR6 WORD_REF(CSOR6_ADDR) -#define CSBAR7_ADDR 0xFFFA68 -#define CSBAR7 WORD_REF(CSBAR7_ADDR) -#define CSOR7_ADDR 0xFFFA6A -#define CSOR7 WORD_REF(CSOR7_ADDR) -#define CSBAR8_ADDR 0xFFFA6C -#define CSBAR8 WORD_REF(CSBAR8_ADDR) -#define CSOR8_ADDR 0xFFFA6E -#define CSOR8 WORD_REF(CSOR8_ADDR) -#define CSBAR9_ADDR 0xFFFA70 -#define CSBAR9 WORD_REF(CSBAR9_ADDR) -#define CSOR9_ADDR 0xFFFA72 -#define CSOR9 WORD_REF(CSOR9_ADDR) -#define CSBAR10_ADDR 0xFFFA74 -#define CSBAR10 WORD_REF(CSBAR10_ADDR) -#define CSOR10_ADDR 0xFFFA76 -#define CSOR10 WORD_REF(CSOR10_ADDR) - -#define CSOR_MODE_ASYNC 0x0000 -#define CSOR_MODE_SYNC 0x8000 -#define CSOR_MODE_MASK 0x8000 -#define CSOR_BYTE_DISABLE 0x0000 -#define CSOR_BYTE_UPPER 0x4000 -#define CSOR_BYTE_LOWER 0x2000 -#define CSOR_BYTE_BOTH 0x6000 -#define CSOR_BYTE_MASK 0x6000 -#define CSOR_RW_RSVD 0x0000 -#define CSOR_RW_READ 0x0800 -#define CSOR_RW_WRITE 0x1000 -#define CSOR_RW_BOTH 0x1800 -#define CSOR_RW_MASK 0x1800 -#define CSOR_STROBE_DS 0x0400 -#define CSOR_STROBE_AS 0x0000 -#define CSOR_STROBE_MASK 0x0400 -#define CSOR_DSACK_WAIT(x) (wait << 6) -#define CSOR_DSACK_FTERM (14 << 6) -#define CSOR_DSACK_EXTERNAL (15 << 6) -#define CSOR_DSACK_MASK 0x03c0 -#define CSOR_SPACE_CPU 0x0000 -#define CSOR_SPACE_USER 0x0010 -#define CSOR_SPACE_SU 0x0020 -#define CSOR_SPACE_BOTH 0x0030 -#define CSOR_SPACE_MASK 0x0030 -#define CSOR_IPL_ALL 0x0000 -#define CSOR_IPL_PRIORITY(x) (x << 1) -#define CSOR_IPL_MASK 0x000e -#define CSOR_AVEC_ON 0x0001 -#define CSOR_AVEC_OFF 0x0000 -#define CSOR_AVEC_MASK 0x0001 - -#define CSBAR_ADDR(x) ((addr >> 11) << 3) -#define CSBAR_ADDR_MASK 0xfff8 -#define CSBAR_BLKSIZE_2K 0x0000 -#define CSBAR_BLKSIZE_8K 0x0001 -#define CSBAR_BLKSIZE_16K 0x0002 -#define CSBAR_BLKSIZE_64K 0x0003 -#define CSBAR_BLKSIZE_128K 0x0004 -#define CSBAR_BLKSIZE_256K 0x0005 -#define CSBAR_BLKSIZE_512K 0x0006 -#define CSBAR_BLKSIZE_1M 0x0007 -#define CSBAR_BLKSIZE_MASK 0x0007 - -#define CSPAR_DISC 0 -#define CSPAR_ALT 1 -#define CSPAR_CS8 2 -#define CSPAR_CS16 3 -#define CSPAR_MASK 3 - -#define CSPAR0_CSBOOT(x) (x << 0) -#define CSPAR0_CS0(x) (x << 2) -#define CSPAR0_CS1(x) (x << 4) -#define CSPAR0_CS2(x) (x << 6) -#define CSPAR0_CS3(x) (x << 8) -#define CSPAR0_CS4(x) (x << 10) -#define CSPAR0_CS5(x) (x << 12) - -#define CSPAR1_CS6(x) (x << 0) -#define CSPAR1_CS7(x) (x << 2) -#define CSPAR1_CS8(x) (x << 4) -#define CSPAR1_CS9(x) (x << 6) -#define CSPAR1_CS10(x) (x << 8) - -#endif diff --git a/arch/m68knommu/include/asm/MC68EZ328.h b/arch/m68knommu/include/asm/MC68EZ328.h deleted file mode 100644 index 69b7f9139e5..00000000000 --- a/arch/m68knommu/include/asm/MC68EZ328.h +++ /dev/null @@ -1,1253 +0,0 @@ - -/* include/asm-m68knommu/MC68EZ328.h: 'EZ328 control registers - * - * Copyright (C) 1999 Vladimir Gurevich - * Bear & Hare Software, Inc. - * - * Based on include/asm-m68knommu/MC68332.h - * Copyright (C) 1998 Kenneth Albanowski , - * The Silver Hammer Group, Ltd. - * - */ - -#ifndef _MC68EZ328_H_ -#define _MC68EZ328_H_ - -#define BYTE_REF(addr) (*((volatile unsigned char*)addr)) -#define WORD_REF(addr) (*((volatile unsigned short*)addr)) -#define LONG_REF(addr) (*((volatile unsigned long*)addr)) - -#define PUT_FIELD(field, val) (((val) << field##_SHIFT) & field##_MASK) -#define GET_FIELD(reg, field) (((reg) & field##_MASK) >> field##_SHIFT) - -/********** - * - * 0xFFFFF0xx -- System Control - * - **********/ - -/* - * System Control Register (SCR) - */ -#define SCR_ADDR 0xfffff000 -#define SCR BYTE_REF(SCR_ADDR) - -#define SCR_WDTH8 0x01 /* 8-Bit Width Select */ -#define SCR_DMAP 0x04 /* Double Map */ -#define SCR_SO 0x08 /* Supervisor Only */ -#define SCR_BETEN 0x10 /* Bus-Error Time-Out Enable */ -#define SCR_PRV 0x20 /* Privilege Violation */ -#define SCR_WPV 0x40 /* Write Protect Violation */ -#define SCR_BETO 0x80 /* Bus-Error TimeOut */ - -/* - * Silicon ID Register (Mask Revision Register (MRR) for '328 Compatibility) - */ -#define MRR_ADDR 0xfffff004 -#define MRR LONG_REF(MRR_ADDR) - -/********** - * - * 0xFFFFF1xx -- Chip-Select logic - * - **********/ - -/* - * Chip Select Group Base Registers - */ -#define CSGBA_ADDR 0xfffff100 -#define CSGBB_ADDR 0xfffff102 - -#define CSGBC_ADDR 0xfffff104 -#define CSGBD_ADDR 0xfffff106 - -#define CSGBA WORD_REF(CSGBA_ADDR) -#define CSGBB WORD_REF(CSGBB_ADDR) -#define CSGBC WORD_REF(CSGBC_ADDR) -#define CSGBD WORD_REF(CSGBD_ADDR) - -/* - * Chip Select Registers - */ -#define CSA_ADDR 0xfffff110 -#define CSB_ADDR 0xfffff112 -#define CSC_ADDR 0xfffff114 -#define CSD_ADDR 0xfffff116 - -#define CSA WORD_REF(CSA_ADDR) -#define CSB WORD_REF(CSB_ADDR) -#define CSC WORD_REF(CSC_ADDR) -#define CSD WORD_REF(CSD_ADDR) - -#define CSA_EN 0x0001 /* Chip-Select Enable */ -#define CSA_SIZ_MASK 0x000e /* Chip-Select Size */ -#define CSA_SIZ_SHIFT 1 -#define CSA_WS_MASK 0x0070 /* Wait State */ -#define CSA_WS_SHIFT 4 -#define CSA_BSW 0x0080 /* Data Bus Width */ -#define CSA_FLASH 0x0100 /* FLASH Memory Support */ -#define CSA_RO 0x8000 /* Read-Only */ - -#define CSB_EN 0x0001 /* Chip-Select Enable */ -#define CSB_SIZ_MASK 0x000e /* Chip-Select Size */ -#define CSB_SIZ_SHIFT 1 -#define CSB_WS_MASK 0x0070 /* Wait State */ -#define CSB_WS_SHIFT 4 -#define CSB_BSW 0x0080 /* Data Bus Width */ -#define CSB_FLASH 0x0100 /* FLASH Memory Support */ -#define CSB_UPSIZ_MASK 0x1800 /* Unprotected memory block size */ -#define CSB_UPSIZ_SHIFT 11 -#define CSB_ROP 0x2000 /* Readonly if protected */ -#define CSB_SOP 0x4000 /* Supervisor only if protected */ -#define CSB_RO 0x8000 /* Read-Only */ - -#define CSC_EN 0x0001 /* Chip-Select Enable */ -#define CSC_SIZ_MASK 0x000e /* Chip-Select Size */ -#define CSC_SIZ_SHIFT 1 -#define CSC_WS_MASK 0x0070 /* Wait State */ -#define CSC_WS_SHIFT 4 -#define CSC_BSW 0x0080 /* Data Bus Width */ -#define CSC_FLASH 0x0100 /* FLASH Memory Support */ -#define CSC_UPSIZ_MASK 0x1800 /* Unprotected memory block size */ -#define CSC_UPSIZ_SHIFT 11 -#define CSC_ROP 0x2000 /* Readonly if protected */ -#define CSC_SOP 0x4000 /* Supervisor only if protected */ -#define CSC_RO 0x8000 /* Read-Only */ - -#define CSD_EN 0x0001 /* Chip-Select Enable */ -#define CSD_SIZ_MASK 0x000e /* Chip-Select Size */ -#define CSD_SIZ_SHIFT 1 -#define CSD_WS_MASK 0x0070 /* Wait State */ -#define CSD_WS_SHIFT 4 -#define CSD_BSW 0x0080 /* Data Bus Width */ -#define CSD_FLASH 0x0100 /* FLASH Memory Support */ -#define CSD_DRAM 0x0200 /* Dram Selection */ -#define CSD_COMB 0x0400 /* Combining */ -#define CSD_UPSIZ_MASK 0x1800 /* Unprotected memory block size */ -#define CSD_UPSIZ_SHIFT 11 -#define CSD_ROP 0x2000 /* Readonly if protected */ -#define CSD_SOP 0x4000 /* Supervisor only if protected */ -#define CSD_RO 0x8000 /* Read-Only */ - -/* - * Emulation Chip-Select Register - */ -#define EMUCS_ADDR 0xfffff118 -#define EMUCS WORD_REF(EMUCS_ADDR) - -#define EMUCS_WS_MASK 0x0070 -#define EMUCS_WS_SHIFT 4 - -/********** - * - * 0xFFFFF2xx -- Phase Locked Loop (PLL) & Power Control - * - **********/ - -/* - * PLL Control Register - */ -#define PLLCR_ADDR 0xfffff200 -#define PLLCR WORD_REF(PLLCR_ADDR) - -#define PLLCR_DISPLL 0x0008 /* Disable PLL */ -#define PLLCR_CLKEN 0x0010 /* Clock (CLKO pin) enable */ -#define PLLCR_PRESC 0x0020 /* VCO prescaler */ -#define PLLCR_SYSCLK_SEL_MASK 0x0700 /* System Clock Selection */ -#define PLLCR_SYSCLK_SEL_SHIFT 8 -#define PLLCR_LCDCLK_SEL_MASK 0x3800 /* LCD Clock Selection */ -#define PLLCR_LCDCLK_SEL_SHIFT 11 - -/* '328-compatible definitions */ -#define PLLCR_PIXCLK_SEL_MASK PLLCR_LCDCLK_SEL_MASK -#define PLLCR_PIXCLK_SEL_SHIFT PLLCR_LCDCLK_SEL_SHIFT - -/* - * PLL Frequency Select Register - */ -#define PLLFSR_ADDR 0xfffff202 -#define PLLFSR WORD_REF(PLLFSR_ADDR) - -#define PLLFSR_PC_MASK 0x00ff /* P Count */ -#define PLLFSR_PC_SHIFT 0 -#define PLLFSR_QC_MASK 0x0f00 /* Q Count */ -#define PLLFSR_QC_SHIFT 8 -#define PLLFSR_PROT 0x4000 /* Protect P & Q */ -#define PLLFSR_CLK32 0x8000 /* Clock 32 (kHz) */ - -/* - * Power Control Register - */ -#define PCTRL_ADDR 0xfffff207 -#define PCTRL BYTE_REF(PCTRL_ADDR) - -#define PCTRL_WIDTH_MASK 0x1f /* CPU Clock bursts width */ -#define PCTRL_WIDTH_SHIFT 0 -#define PCTRL_PCEN 0x80 /* Power Control Enable */ - -/********** - * - * 0xFFFFF3xx -- Interrupt Controller - * - **********/ - -/* - * Interrupt Vector Register - */ -#define IVR_ADDR 0xfffff300 -#define IVR BYTE_REF(IVR_ADDR) - -#define IVR_VECTOR_MASK 0xF8 - -/* - * Interrupt control Register - */ -#define ICR_ADDR 0xfffff302 -#define ICR WORD_REF(ICR_ADDR) - -#define ICR_POL5 0x0080 /* Polarity Control for IRQ5 */ -#define ICR_ET6 0x0100 /* Edge Trigger Select for IRQ6 */ -#define ICR_ET3 0x0200 /* Edge Trigger Select for IRQ3 */ -#define ICR_ET2 0x0400 /* Edge Trigger Select for IRQ2 */ -#define ICR_ET1 0x0800 /* Edge Trigger Select for IRQ1 */ -#define ICR_POL6 0x1000 /* Polarity Control for IRQ6 */ -#define ICR_POL3 0x2000 /* Polarity Control for IRQ3 */ -#define ICR_POL2 0x4000 /* Polarity Control for IRQ2 */ -#define ICR_POL1 0x8000 /* Polarity Control for IRQ1 */ - -/* - * Interrupt Mask Register - */ -#define IMR_ADDR 0xfffff304 -#define IMR LONG_REF(IMR_ADDR) - -/* - * Define the names for bit positions first. This is useful for - * request_irq - */ -#define SPI_IRQ_NUM 0 /* SPI interrupt */ -#define TMR_IRQ_NUM 1 /* Timer interrupt */ -#define UART_IRQ_NUM 2 /* UART interrupt */ -#define WDT_IRQ_NUM 3 /* Watchdog Timer interrupt */ -#define RTC_IRQ_NUM 4 /* RTC interrupt */ -#define KB_IRQ_NUM 6 /* Keyboard Interrupt */ -#define PWM_IRQ_NUM 7 /* Pulse-Width Modulator int. */ -#define INT0_IRQ_NUM 8 /* External INT0 */ -#define INT1_IRQ_NUM 9 /* External INT1 */ -#define INT2_IRQ_NUM 10 /* External INT2 */ -#define INT3_IRQ_NUM 11 /* External INT3 */ -#define IRQ1_IRQ_NUM 16 /* IRQ1 */ -#define IRQ2_IRQ_NUM 17 /* IRQ2 */ -#define IRQ3_IRQ_NUM 18 /* IRQ3 */ -#define IRQ6_IRQ_NUM 19 /* IRQ6 */ -#define IRQ5_IRQ_NUM 20 /* IRQ5 */ -#define SAM_IRQ_NUM 22 /* Sampling Timer for RTC */ -#define EMIQ_IRQ_NUM 23 /* Emulator Interrupt */ - -/* '328-compatible definitions */ -#define SPIM_IRQ_NUM SPI_IRQ_NUM -#define TMR1_IRQ_NUM TMR_IRQ_NUM - -/* - * Here go the bitmasks themselves - */ -#define IMR_MSPI (1 << SPI_IRQ_NUM) /* Mask SPI interrupt */ -#define IMR_MTMR (1 << TMR_IRQ_NUM) /* Mask Timer interrupt */ -#define IMR_MUART (1 << UART_IRQ_NUM) /* Mask UART interrupt */ -#define IMR_MWDT (1 << WDT_IRQ_NUM) /* Mask Watchdog Timer interrupt */ -#define IMR_MRTC (1 << RTC_IRQ_NUM) /* Mask RTC interrupt */ -#define IMR_MKB (1 << KB_IRQ_NUM) /* Mask Keyboard Interrupt */ -#define IMR_MPWM (1 << PWM_IRQ_NUM) /* Mask Pulse-Width Modulator int. */ -#define IMR_MINT0 (1 << INT0_IRQ_NUM) /* Mask External INT0 */ -#define IMR_MINT1 (1 << INT1_IRQ_NUM) /* Mask External INT1 */ -#define IMR_MINT2 (1 << INT2_IRQ_NUM) /* Mask External INT2 */ -#define IMR_MINT3 (1 << INT3_IRQ_NUM) /* Mask External INT3 */ -#define IMR_MIRQ1 (1 << IRQ1_IRQ_NUM) /* Mask IRQ1 */ -#define IMR_MIRQ2 (1 << IRQ2_IRQ_NUM) /* Mask IRQ2 */ -#define IMR_MIRQ3 (1 << IRQ3_IRQ_NUM) /* Mask IRQ3 */ -#define IMR_MIRQ6 (1 << IRQ6_IRQ_NUM) /* Mask IRQ6 */ -#define IMR_MIRQ5 (1 << IRQ5_IRQ_NUM) /* Mask IRQ5 */ -#define IMR_MSAM (1 << SAM_IRQ_NUM) /* Mask Sampling Timer for RTC */ -#define IMR_MEMIQ (1 << EMIQ_IRQ_NUM) /* Mask Emulator Interrupt */ - -/* '328-compatible definitions */ -#define IMR_MSPIM IMR_MSPI -#define IMR_MTMR1 IMR_MTMR - -/* - * Interrupt Status Register - */ -#define ISR_ADDR 0xfffff30c -#define ISR LONG_REF(ISR_ADDR) - -#define ISR_SPI (1 << SPI_IRQ_NUM) /* SPI interrupt */ -#define ISR_TMR (1 << TMR_IRQ_NUM) /* Timer interrupt */ -#define ISR_UART (1 << UART_IRQ_NUM) /* UART interrupt */ -#define ISR_WDT (1 << WDT_IRQ_NUM) /* Watchdog Timer interrupt */ -#define ISR_RTC (1 << RTC_IRQ_NUM) /* RTC interrupt */ -#define ISR_KB (1 << KB_IRQ_NUM) /* Keyboard Interrupt */ -#define ISR_PWM (1 << PWM_IRQ_NUM) /* Pulse-Width Modulator interrupt */ -#define ISR_INT0 (1 << INT0_IRQ_NUM) /* External INT0 */ -#define ISR_INT1 (1 << INT1_IRQ_NUM) /* External INT1 */ -#define ISR_INT2 (1 << INT2_IRQ_NUM) /* External INT2 */ -#define ISR_INT3 (1 << INT3_IRQ_NUM) /* External INT3 */ -#define ISR_IRQ1 (1 << IRQ1_IRQ_NUM) /* IRQ1 */ -#define ISR_IRQ2 (1 << IRQ2_IRQ_NUM) /* IRQ2 */ -#define ISR_IRQ3 (1 << IRQ3_IRQ_NUM) /* IRQ3 */ -#define ISR_IRQ6 (1 << IRQ6_IRQ_NUM) /* IRQ6 */ -#define ISR_IRQ5 (1 << IRQ5_IRQ_NUM) /* IRQ5 */ -#define ISR_SAM (1 << SAM_IRQ_NUM) /* Sampling Timer for RTC */ -#define ISR_EMIQ (1 << EMIQ_IRQ_NUM) /* Emulator Interrupt */ - -/* '328-compatible definitions */ -#define ISR_SPIM ISR_SPI -#define ISR_TMR1 ISR_TMR - -/* - * Interrupt Pending Register - */ -#define IPR_ADDR 0xfffff30c -#define IPR LONG_REF(IPR_ADDR) - -#define IPR_SPI (1 << SPI_IRQ_NUM) /* SPI interrupt */ -#define IPR_TMR (1 << TMR_IRQ_NUM) /* Timer interrupt */ -#define IPR_UART (1 << UART_IRQ_NUM) /* UART interrupt */ -#define IPR_WDT (1 << WDT_IRQ_NUM) /* Watchdog Timer interrupt */ -#define IPR_RTC (1 << RTC_IRQ_NUM) /* RTC interrupt */ -#define IPR_KB (1 << KB_IRQ_NUM) /* Keyboard Interrupt */ -#define IPR_PWM (1 << PWM_IRQ_NUM) /* Pulse-Width Modulator interrupt */ -#define IPR_INT0 (1 << INT0_IRQ_NUM) /* External INT0 */ -#define IPR_INT1 (1 << INT1_IRQ_NUM) /* External INT1 */ -#define IPR_INT2 (1 << INT2_IRQ_NUM) /* External INT2 */ -#define IPR_INT3 (1 << INT3_IRQ_NUM) /* External INT3 */ -#define IPR_IRQ1 (1 << IRQ1_IRQ_NUM) /* IRQ1 */ -#define IPR_IRQ2 (1 << IRQ2_IRQ_NUM) /* IRQ2 */ -#define IPR_IRQ3 (1 << IRQ3_IRQ_NUM) /* IRQ3 */ -#define IPR_IRQ6 (1 << IRQ6_IRQ_NUM) /* IRQ6 */ -#define IPR_IRQ5 (1 << IRQ5_IRQ_NUM) /* IRQ5 */ -#define IPR_SAM (1 << SAM_IRQ_NUM) /* Sampling Timer for RTC */ -#define IPR_EMIQ (1 << EMIQ_IRQ_NUM) /* Emulator Interrupt */ - -/* '328-compatible definitions */ -#define IPR_SPIM IPR_SPI -#define IPR_TMR1 IPR_TMR - -/********** - * - * 0xFFFFF4xx -- Parallel Ports - * - **********/ - -/* - * Port A - */ -#define PADIR_ADDR 0xfffff400 /* Port A direction reg */ -#define PADATA_ADDR 0xfffff401 /* Port A data register */ -#define PAPUEN_ADDR 0xfffff402 /* Port A Pull-Up enable reg */ - -#define PADIR BYTE_REF(PADIR_ADDR) -#define PADATA BYTE_REF(PADATA_ADDR) -#define PAPUEN BYTE_REF(PAPUEN_ADDR) - -#define PA(x) (1 << (x)) - -/* - * Port B - */ -#define PBDIR_ADDR 0xfffff408 /* Port B direction reg */ -#define PBDATA_ADDR 0xfffff409 /* Port B data register */ -#define PBPUEN_ADDR 0xfffff40a /* Port B Pull-Up enable reg */ -#define PBSEL_ADDR 0xfffff40b /* Port B Select Register */ - -#define PBDIR BYTE_REF(PBDIR_ADDR) -#define PBDATA BYTE_REF(PBDATA_ADDR) -#define PBPUEN BYTE_REF(PBPUEN_ADDR) -#define PBSEL BYTE_REF(PBSEL_ADDR) - -#define PB(x) (1 << (x)) - -#define PB_CSB0 0x01 /* Use CSB0 as PB[0] */ -#define PB_CSB1 0x02 /* Use CSB1 as PB[1] */ -#define PB_CSC0_RAS0 0x04 /* Use CSC0/RAS0 as PB[2] */ -#define PB_CSC1_RAS1 0x08 /* Use CSC1/RAS1 as PB[3] */ -#define PB_CSD0_CAS0 0x10 /* Use CSD0/CAS0 as PB[4] */ -#define PB_CSD1_CAS1 0x20 /* Use CSD1/CAS1 as PB[5] */ -#define PB_TIN_TOUT 0x40 /* Use TIN/TOUT as PB[6] */ -#define PB_PWMO 0x80 /* Use PWMO as PB[7] */ - -/* - * Port C - */ -#define PCDIR_ADDR 0xfffff410 /* Port C direction reg */ -#define PCDATA_ADDR 0xfffff411 /* Port C data register */ -#define PCPDEN_ADDR 0xfffff412 /* Port C Pull-Down enb. reg */ -#define PCSEL_ADDR 0xfffff413 /* Port C Select Register */ - -#define PCDIR BYTE_REF(PCDIR_ADDR) -#define PCDATA BYTE_REF(PCDATA_ADDR) -#define PCPDEN BYTE_REF(PCPDEN_ADDR) -#define PCSEL BYTE_REF(PCSEL_ADDR) - -#define PC(x) (1 << (x)) - -#define PC_LD0 0x01 /* Use LD0 as PC[0] */ -#define PC_LD1 0x02 /* Use LD1 as PC[1] */ -#define PC_LD2 0x04 /* Use LD2 as PC[2] */ -#define PC_LD3 0x08 /* Use LD3 as PC[3] */ -#define PC_LFLM 0x10 /* Use LFLM as PC[4] */ -#define PC_LLP 0x20 /* Use LLP as PC[5] */ -#define PC_LCLK 0x40 /* Use LCLK as PC[6] */ -#define PC_LACD 0x80 /* Use LACD as PC[7] */ - -/* - * Port D - */ -#define PDDIR_ADDR 0xfffff418 /* Port D direction reg */ -#define PDDATA_ADDR 0xfffff419 /* Port D data register */ -#define PDPUEN_ADDR 0xfffff41a /* Port D Pull-Up enable reg */ -#define PDSEL_ADDR 0xfffff41b /* Port D Select Register */ -#define PDPOL_ADDR 0xfffff41c /* Port D Polarity Register */ -#define PDIRQEN_ADDR 0xfffff41d /* Port D IRQ enable register */ -#define PDKBEN_ADDR 0xfffff41e /* Port D Keyboard Enable reg */ -#define PDIQEG_ADDR 0xfffff41f /* Port D IRQ Edge Register */ - -#define PDDIR BYTE_REF(PDDIR_ADDR) -#define PDDATA BYTE_REF(PDDATA_ADDR) -#define PDPUEN BYTE_REF(PDPUEN_ADDR) -#define PDSEL BYTE_REF(PDSEL_ADDR) -#define PDPOL BYTE_REF(PDPOL_ADDR) -#define PDIRQEN BYTE_REF(PDIRQEN_ADDR) -#define PDKBEN BYTE_REF(PDKBEN_ADDR) -#define PDIQEG BYTE_REF(PDIQEG_ADDR) - -#define PD(x) (1 << (x)) - -#define PD_INT0 0x01 /* Use INT0 as PD[0] */ -#define PD_INT1 0x02 /* Use INT1 as PD[1] */ -#define PD_INT2 0x04 /* Use INT2 as PD[2] */ -#define PD_INT3 0x08 /* Use INT3 as PD[3] */ -#define PD_IRQ1 0x10 /* Use IRQ1 as PD[4] */ -#define PD_IRQ2 0x20 /* Use IRQ2 as PD[5] */ -#define PD_IRQ3 0x40 /* Use IRQ3 as PD[6] */ -#define PD_IRQ6 0x80 /* Use IRQ6 as PD[7] */ - -/* - * Port E - */ -#define PEDIR_ADDR 0xfffff420 /* Port E direction reg */ -#define PEDATA_ADDR 0xfffff421 /* Port E data register */ -#define PEPUEN_ADDR 0xfffff422 /* Port E Pull-Up enable reg */ -#define PESEL_ADDR 0xfffff423 /* Port E Select Register */ - -#define PEDIR BYTE_REF(PEDIR_ADDR) -#define PEDATA BYTE_REF(PEDATA_ADDR) -#define PEPUEN BYTE_REF(PEPUEN_ADDR) -#define PESEL BYTE_REF(PESEL_ADDR) - -#define PE(x) (1 << (x)) - -#define PE_SPMTXD 0x01 /* Use SPMTXD as PE[0] */ -#define PE_SPMRXD 0x02 /* Use SPMRXD as PE[1] */ -#define PE_SPMCLK 0x04 /* Use SPMCLK as PE[2] */ -#define PE_DWE 0x08 /* Use DWE as PE[3] */ -#define PE_RXD 0x10 /* Use RXD as PE[4] */ -#define PE_TXD 0x20 /* Use TXD as PE[5] */ -#define PE_RTS 0x40 /* Use RTS as PE[6] */ -#define PE_CTS 0x80 /* Use CTS as PE[7] */ - -/* - * Port F - */ -#define PFDIR_ADDR 0xfffff428 /* Port F direction reg */ -#define PFDATA_ADDR 0xfffff429 /* Port F data register */ -#define PFPUEN_ADDR 0xfffff42a /* Port F Pull-Up enable reg */ -#define PFSEL_ADDR 0xfffff42b /* Port F Select Register */ - -#define PFDIR BYTE_REF(PFDIR_ADDR) -#define PFDATA BYTE_REF(PFDATA_ADDR) -#define PFPUEN BYTE_REF(PFPUEN_ADDR) -#define PFSEL BYTE_REF(PFSEL_ADDR) - -#define PF(x) (1 << (x)) - -#define PF_LCONTRAST 0x01 /* Use LCONTRAST as PF[0] */ -#define PF_IRQ5 0x02 /* Use IRQ5 as PF[1] */ -#define PF_CLKO 0x04 /* Use CLKO as PF[2] */ -#define PF_A20 0x08 /* Use A20 as PF[3] */ -#define PF_A21 0x10 /* Use A21 as PF[4] */ -#define PF_A22 0x20 /* Use A22 as PF[5] */ -#define PF_A23 0x40 /* Use A23 as PF[6] */ -#define PF_CSA1 0x80 /* Use CSA1 as PF[7] */ - -/* - * Port G - */ -#define PGDIR_ADDR 0xfffff430 /* Port G direction reg */ -#define PGDATA_ADDR 0xfffff431 /* Port G data register */ -#define PGPUEN_ADDR 0xfffff432 /* Port G Pull-Up enable reg */ -#define PGSEL_ADDR 0xfffff433 /* Port G Select Register */ - -#define PGDIR BYTE_REF(PGDIR_ADDR) -#define PGDATA BYTE_REF(PGDATA_ADDR) -#define PGPUEN BYTE_REF(PGPUEN_ADDR) -#define PGSEL BYTE_REF(PGSEL_ADDR) - -#define PG(x) (1 << (x)) - -#define PG_BUSW_DTACK 0x01 /* Use BUSW/DTACK as PG[0] */ -#define PG_A0 0x02 /* Use A0 as PG[1] */ -#define PG_EMUIRQ 0x04 /* Use EMUIRQ as PG[2] */ -#define PG_HIZ_P_D 0x08 /* Use HIZ/P/D as PG[3] */ -#define PG_EMUCS 0x10 /* Use EMUCS as PG[4] */ -#define PG_EMUBRK 0x20 /* Use EMUBRK as PG[5] */ - -/********** - * - * 0xFFFFF5xx -- Pulse-Width Modulator (PWM) - * - **********/ - -/* - * PWM Control Register - */ -#define PWMC_ADDR 0xfffff500 -#define PWMC WORD_REF(PWMC_ADDR) - -#define PWMC_CLKSEL_MASK 0x0003 /* Clock Selection */ -#define PWMC_CLKSEL_SHIFT 0 -#define PWMC_REPEAT_MASK 0x000c /* Sample Repeats */ -#define PWMC_REPEAT_SHIFT 2 -#define PWMC_EN 0x0010 /* Enable PWM */ -#define PMNC_FIFOAV 0x0020 /* FIFO Available */ -#define PWMC_IRQEN 0x0040 /* Interrupt Request Enable */ -#define PWMC_IRQ 0x0080 /* Interrupt Request (FIFO empty) */ -#define PWMC_PRESCALER_MASK 0x7f00 /* Incoming Clock prescaler */ -#define PWMC_PRESCALER_SHIFT 8 -#define PWMC_CLKSRC 0x8000 /* Clock Source Select */ - -/* '328-compatible definitions */ -#define PWMC_PWMEN PWMC_EN - -/* - * PWM Sample Register - */ -#define PWMS_ADDR 0xfffff502 -#define PWMS WORD_REF(PWMS_ADDR) - -/* - * PWM Period Register - */ -#define PWMP_ADDR 0xfffff504 -#define PWMP BYTE_REF(PWMP_ADDR) - -/* - * PWM Counter Register - */ -#define PWMCNT_ADDR 0xfffff505 -#define PWMCNT BYTE_REF(PWMCNT_ADDR) - -/********** - * - * 0xFFFFF6xx -- General-Purpose Timer - * - **********/ - -/* - * Timer Control register - */ -#define TCTL_ADDR 0xfffff600 -#define TCTL WORD_REF(TCTL_ADDR) - -#define TCTL_TEN 0x0001 /* Timer Enable */ -#define TCTL_CLKSOURCE_MASK 0x000e /* Clock Source: */ -#define TCTL_CLKSOURCE_STOP 0x0000 /* Stop count (disabled) */ -#define TCTL_CLKSOURCE_SYSCLK 0x0002 /* SYSCLK to prescaler */ -#define TCTL_CLKSOURCE_SYSCLK_16 0x0004 /* SYSCLK/16 to prescaler */ -#define TCTL_CLKSOURCE_TIN 0x0006 /* TIN to prescaler */ -#define TCTL_CLKSOURCE_32KHZ 0x0008 /* 32kHz clock to prescaler */ -#define TCTL_IRQEN 0x0010 /* IRQ Enable */ -#define TCTL_OM 0x0020 /* Output Mode */ -#define TCTL_CAP_MASK 0x00c0 /* Capture Edge: */ -#define TCTL_CAP_RE 0x0040 /* Capture on rizing edge */ -#define TCTL_CAP_FE 0x0080 /* Capture on falling edge */ -#define TCTL_FRR 0x0010 /* Free-Run Mode */ - -/* '328-compatible definitions */ -#define TCTL1_ADDR TCTL_ADDR -#define TCTL1 TCTL - -/* - * Timer Prescaler Register - */ -#define TPRER_ADDR 0xfffff602 -#define TPRER WORD_REF(TPRER_ADDR) - -/* '328-compatible definitions */ -#define TPRER1_ADDR TPRER_ADDR -#define TPRER1 TPRER - -/* - * Timer Compare Register - */ -#define TCMP_ADDR 0xfffff604 -#define TCMP WORD_REF(TCMP_ADDR) - -/* '328-compatible definitions */ -#define TCMP1_ADDR TCMP_ADDR -#define TCMP1 TCMP - -/* - * Timer Capture register - */ -#define TCR_ADDR 0xfffff606 -#define TCR WORD_REF(TCR_ADDR) - -/* '328-compatible definitions */ -#define TCR1_ADDR TCR_ADDR -#define TCR1 TCR - -/* - * Timer Counter Register - */ -#define TCN_ADDR 0xfffff608 -#define TCN WORD_REF(TCN_ADDR) - -/* '328-compatible definitions */ -#define TCN1_ADDR TCN_ADDR -#define TCN1 TCN - -/* - * Timer Status Register - */ -#define TSTAT_ADDR 0xfffff60a -#define TSTAT WORD_REF(TSTAT_ADDR) - -#define TSTAT_COMP 0x0001 /* Compare Event occurred */ -#define TSTAT_CAPT 0x0001 /* Capture Event occurred */ - -/* '328-compatible definitions */ -#define TSTAT1_ADDR TSTAT_ADDR -#define TSTAT1 TSTAT - -/********** - * - * 0xFFFFF8xx -- Serial Periferial Interface Master (SPIM) - * - **********/ - -/* - * SPIM Data Register - */ -#define SPIMDATA_ADDR 0xfffff800 -#define SPIMDATA WORD_REF(SPIMDATA_ADDR) - -/* - * SPIM Control/Status Register - */ -#define SPIMCONT_ADDR 0xfffff802 -#define SPIMCONT WORD_REF(SPIMCONT_ADDR) - -#define SPIMCONT_BIT_COUNT_MASK 0x000f /* Transfer Length in Bytes */ -#define SPIMCONT_BIT_COUNT_SHIFT 0 -#define SPIMCONT_POL 0x0010 /* SPMCLK Signel Polarity */ -#define SPIMCONT_PHA 0x0020 /* Clock/Data phase relationship */ -#define SPIMCONT_IRQEN 0x0040 /* IRQ Enable */ -#define SPIMCONT_IRQ 0x0080 /* Interrupt Request */ -#define SPIMCONT_XCH 0x0100 /* Exchange */ -#define SPIMCONT_ENABLE 0x0200 /* Enable SPIM */ -#define SPIMCONT_DATA_RATE_MASK 0xe000 /* SPIM Data Rate */ -#define SPIMCONT_DATA_RATE_SHIFT 13 - -/* '328-compatible definitions */ -#define SPIMCONT_SPIMIRQ SPIMCONT_IRQ -#define SPIMCONT_SPIMEN SPIMCONT_ENABLE - -/********** - * - * 0xFFFFF9xx -- UART - * - **********/ - -/* - * UART Status/Control Register - */ -#define USTCNT_ADDR 0xfffff900 -#define USTCNT WORD_REF(USTCNT_ADDR) - -#define USTCNT_TXAE 0x0001 /* Transmitter Available Interrupt Enable */ -#define USTCNT_TXHE 0x0002 /* Transmitter Half Empty Enable */ -#define USTCNT_TXEE 0x0004 /* Transmitter Empty Interrupt Enable */ -#define USTCNT_RXRE 0x0008 /* Receiver Ready Interrupt Enable */ -#define USTCNT_RXHE 0x0010 /* Receiver Half-Full Interrupt Enable */ -#define USTCNT_RXFE 0x0020 /* Receiver Full Interrupt Enable */ -#define USTCNT_CTSD 0x0040 /* CTS Delta Interrupt Enable */ -#define USTCNT_ODEN 0x0080 /* Old Data Interrupt Enable */ -#define USTCNT_8_7 0x0100 /* Eight or seven-bit transmission */ -#define USTCNT_STOP 0x0200 /* Stop bit transmission */ -#define USTCNT_ODD 0x0400 /* Odd Parity */ -#define USTCNT_PEN 0x0800 /* Parity Enable */ -#define USTCNT_CLKM 0x1000 /* Clock Mode Select */ -#define USTCNT_TXEN 0x2000 /* Transmitter Enable */ -#define USTCNT_RXEN 0x4000 /* Receiver Enable */ -#define USTCNT_UEN 0x8000 /* UART Enable */ - -/* '328-compatible definitions */ -#define USTCNT_TXAVAILEN USTCNT_TXAE -#define USTCNT_TXHALFEN USTCNT_TXHE -#define USTCNT_TXEMPTYEN USTCNT_TXEE -#define USTCNT_RXREADYEN USTCNT_RXRE -#define USTCNT_RXHALFEN USTCNT_RXHE -#define USTCNT_RXFULLEN USTCNT_RXFE -#define USTCNT_CTSDELTAEN USTCNT_CTSD -#define USTCNT_ODD_EVEN USTCNT_ODD -#define USTCNT_PARITYEN USTCNT_PEN -#define USTCNT_CLKMODE USTCNT_CLKM -#define USTCNT_UARTEN USTCNT_UEN - -/* - * UART Baud Control Register - */ -#define UBAUD_ADDR 0xfffff902 -#define UBAUD WORD_REF(UBAUD_ADDR) - -#define UBAUD_PRESCALER_MASK 0x003f /* Actual divisor is 65 - PRESCALER */ -#define UBAUD_PRESCALER_SHIFT 0 -#define UBAUD_DIVIDE_MASK 0x0700 /* Baud Rate freq. divizor */ -#define UBAUD_DIVIDE_SHIFT 8 -#define UBAUD_BAUD_SRC 0x0800 /* Baud Rate Source */ -#define UBAUD_UCLKDIR 0x2000 /* UCLK Direction */ - -/* - * UART Receiver Register - */ -#define URX_ADDR 0xfffff904 -#define URX WORD_REF(URX_ADDR) - -#define URX_RXDATA_ADDR 0xfffff905 -#define URX_RXDATA BYTE_REF(URX_RXDATA_ADDR) - -#define URX_RXDATA_MASK 0x00ff /* Received data */ -#define URX_RXDATA_SHIFT 0 -#define URX_PARITY_ERROR 0x0100 /* Parity Error */ -#define URX_BREAK 0x0200 /* Break Detected */ -#define URX_FRAME_ERROR 0x0400 /* Framing Error */ -#define URX_OVRUN 0x0800 /* Serial Overrun */ -#define URX_OLD_DATA 0x1000 /* Old data in FIFO */ -#define URX_DATA_READY 0x2000 /* Data Ready (FIFO not empty) */ -#define URX_FIFO_HALF 0x4000 /* FIFO is Half-Full */ -#define URX_FIFO_FULL 0x8000 /* FIFO is Full */ - -/* - * UART Transmitter Register - */ -#define UTX_ADDR 0xfffff906 -#define UTX WORD_REF(UTX_ADDR) - -#define UTX_TXDATA_ADDR 0xfffff907 -#define UTX_TXDATA BYTE_REF(UTX_TXDATA_ADDR) - -#define UTX_TXDATA_MASK 0x00ff /* Data to be transmitted */ -#define UTX_TXDATA_SHIFT 0 -#define UTX_CTS_DELTA 0x0100 /* CTS changed */ -#define UTX_CTS_STAT 0x0200 /* CTS State */ -#define UTX_BUSY 0x0400 /* FIFO is busy, sending a character */ -#define UTX_NOCTS 0x0800 /* Ignore CTS */ -#define UTX_SEND_BREAK 0x1000 /* Send a BREAK */ -#define UTX_TX_AVAIL 0x2000 /* Transmit FIFO has a slot available */ -#define UTX_FIFO_HALF 0x4000 /* Transmit FIFO is half empty */ -#define UTX_FIFO_EMPTY 0x8000 /* Transmit FIFO is empty */ - -/* '328-compatible definitions */ -#define UTX_CTS_STATUS UTX_CTS_STAT -#define UTX_IGNORE_CTS UTX_NOCTS - -/* - * UART Miscellaneous Register - */ -#define UMISC_ADDR 0xfffff908 -#define UMISC WORD_REF(UMISC_ADDR) - -#define UMISC_TX_POL 0x0004 /* Transmit Polarity */ -#define UMISC_RX_POL 0x0008 /* Receive Polarity */ -#define UMISC_IRDA_LOOP 0x0010 /* IrDA Loopback Enable */ -#define UMISC_IRDA_EN 0x0020 /* Infra-Red Enable */ -#define UMISC_RTS 0x0040 /* Set RTS status */ -#define UMISC_RTSCONT 0x0080 /* Choose RTS control */ -#define UMISC_IR_TEST 0x0400 /* IRDA Test Enable */ -#define UMISC_BAUD_RESET 0x0800 /* Reset Baud Rate Generation Counters */ -#define UMISC_LOOP 0x1000 /* Serial Loopback Enable */ -#define UMISC_FORCE_PERR 0x2000 /* Force Parity Error */ -#define UMISC_CLKSRC 0x4000 /* Clock Source */ -#define UMISC_BAUD_TEST 0x8000 /* Enable Baud Test Mode */ - -/* - * UART Non-integer Prescaler Register - */ -#define NIPR_ADDR 0xfffff90a -#define NIPR WORD_REF(NIPR_ADDR) - -#define NIPR_STEP_VALUE_MASK 0x00ff /* NI prescaler step value */ -#define NIPR_STEP_VALUE_SHIFT 0 -#define NIPR_SELECT_MASK 0x0700 /* Tap Selection */ -#define NIPR_SELECT_SHIFT 8 -#define NIPR_PRE_SEL 0x8000 /* Non-integer prescaler select */ - - -/* generalization of uart control registers to support multiple ports: */ -typedef volatile struct { - volatile unsigned short int ustcnt; - volatile unsigned short int ubaud; - union { - volatile unsigned short int w; - struct { - volatile unsigned char status; - volatile unsigned char rxdata; - } b; - } urx; - union { - volatile unsigned short int w; - struct { - volatile unsigned char status; - volatile unsigned char txdata; - } b; - } utx; - volatile unsigned short int umisc; - volatile unsigned short int nipr; - volatile unsigned short int pad1; - volatile unsigned short int pad2; -} __attribute__((packed)) m68328_uart; - - -/********** - * - * 0xFFFFFAxx -- LCD Controller - * - **********/ - -/* - * LCD Screen Starting Address Register - */ -#define LSSA_ADDR 0xfffffa00 -#define LSSA LONG_REF(LSSA_ADDR) - -#define LSSA_SSA_MASK 0x1ffffffe /* Bits 0 and 29-31 are reserved */ - -/* - * LCD Virtual Page Width Register - */ -#define LVPW_ADDR 0xfffffa05 -#define LVPW BYTE_REF(LVPW_ADDR) - -/* - * LCD Screen Width Register (not compatible with '328 !!!) - */ -#define LXMAX_ADDR 0xfffffa08 -#define LXMAX WORD_REF(LXMAX_ADDR) - -#define LXMAX_XM_MASK 0x02f0 /* Bits 0-3 and 10-15 are reserved */ - -/* - * LCD Screen Height Register - */ -#define LYMAX_ADDR 0xfffffa0a -#define LYMAX WORD_REF(LYMAX_ADDR) - -#define LYMAX_YM_MASK 0x01ff /* Bits 9-15 are reserved */ - -/* - * LCD Cursor X Position Register - */ -#define LCXP_ADDR 0xfffffa18 -#define LCXP WORD_REF(LCXP_ADDR) - -#define LCXP_CC_MASK 0xc000 /* Cursor Control */ -#define LCXP_CC_TRAMSPARENT 0x0000 -#define LCXP_CC_BLACK 0x4000 -#define LCXP_CC_REVERSED 0x8000 -#define LCXP_CC_WHITE 0xc000 -#define LCXP_CXP_MASK 0x02ff /* Cursor X position */ - -/* - * LCD Cursor Y Position Register - */ -#define LCYP_ADDR 0xfffffa1a -#define LCYP WORD_REF(LCYP_ADDR) - -#define LCYP_CYP_MASK 0x01ff /* Cursor Y Position */ - -/* - * LCD Cursor Width and Heigth Register - */ -#define LCWCH_ADDR 0xfffffa1c -#define LCWCH WORD_REF(LCWCH_ADDR) - -#define LCWCH_CH_MASK 0x001f /* Cursor Height */ -#define LCWCH_CH_SHIFT 0 -#define LCWCH_CW_MASK 0x1f00 /* Cursor Width */ -#define LCWCH_CW_SHIFT 8 - -/* - * LCD Blink Control Register - */ -#define LBLKC_ADDR 0xfffffa1f -#define LBLKC BYTE_REF(LBLKC_ADDR) - -#define LBLKC_BD_MASK 0x7f /* Blink Divisor */ -#define LBLKC_BD_SHIFT 0 -#define LBLKC_BKEN 0x80 /* Blink Enabled */ - -/* - * LCD Panel Interface Configuration Register - */ -#define LPICF_ADDR 0xfffffa20 -#define LPICF BYTE_REF(LPICF_ADDR) - -#define LPICF_GS_MASK 0x03 /* Gray-Scale Mode */ -#define LPICF_GS_BW 0x00 -#define LPICF_GS_GRAY_4 0x01 -#define LPICF_GS_GRAY_16 0x02 -#define LPICF_PBSIZ_MASK 0x0c /* Panel Bus Width */ -#define LPICF_PBSIZ_1 0x00 -#define LPICF_PBSIZ_2 0x04 -#define LPICF_PBSIZ_4 0x08 - -/* - * LCD Polarity Configuration Register - */ -#define LPOLCF_ADDR 0xfffffa21 -#define LPOLCF BYTE_REF(LPOLCF_ADDR) - -#define LPOLCF_PIXPOL 0x01 /* Pixel Polarity */ -#define LPOLCF_LPPOL 0x02 /* Line Pulse Polarity */ -#define LPOLCF_FLMPOL 0x04 /* Frame Marker Polarity */ -#define LPOLCF_LCKPOL 0x08 /* LCD Shift Lock Polarity */ - -/* - * LACD (LCD Alternate Crystal Direction) Rate Control Register - */ -#define LACDRC_ADDR 0xfffffa23 -#define LACDRC BYTE_REF(LACDRC_ADDR) - -#define LACDRC_ACDSLT 0x80 /* Signal Source Select */ -#define LACDRC_ACD_MASK 0x0f /* Alternate Crystal Direction Control */ -#define LACDRC_ACD_SHIFT 0 - -/* - * LCD Pixel Clock Divider Register - */ -#define LPXCD_ADDR 0xfffffa25 -#define LPXCD BYTE_REF(LPXCD_ADDR) - -#define LPXCD_PCD_MASK 0x3f /* Pixel Clock Divider */ -#define LPXCD_PCD_SHIFT 0 - -/* - * LCD Clocking Control Register - */ -#define LCKCON_ADDR 0xfffffa27 -#define LCKCON BYTE_REF(LCKCON_ADDR) - -#define LCKCON_DWS_MASK 0x0f /* Display Wait-State */ -#define LCKCON_DWS_SHIFT 0 -#define LCKCON_DWIDTH 0x40 /* Display Memory Width */ -#define LCKCON_LCDON 0x80 /* Enable LCD Controller */ - -/* '328-compatible definitions */ -#define LCKCON_DW_MASK LCKCON_DWS_MASK -#define LCKCON_DW_SHIFT LCKCON_DWS_SHIFT - -/* - * LCD Refresh Rate Adjustment Register - */ -#define LRRA_ADDR 0xfffffa29 -#define LRRA BYTE_REF(LRRA_ADDR) - -/* - * LCD Panning Offset Register - */ -#define LPOSR_ADDR 0xfffffa2d -#define LPOSR BYTE_REF(LPOSR_ADDR) - -#define LPOSR_POS_MASK 0x0f /* Pixel Offset Code */ -#define LPOSR_POS_SHIFT 0 - -/* - * LCD Frame Rate Control Modulation Register - */ -#define LFRCM_ADDR 0xfffffa31 -#define LFRCM BYTE_REF(LFRCM_ADDR) - -#define LFRCM_YMOD_MASK 0x0f /* Vertical Modulation */ -#define LFRCM_YMOD_SHIFT 0 -#define LFRCM_XMOD_MASK 0xf0 /* Horizontal Modulation */ -#define LFRCM_XMOD_SHIFT 4 - -/* - * LCD Gray Palette Mapping Register - */ -#define LGPMR_ADDR 0xfffffa33 -#define LGPMR BYTE_REF(LGPMR_ADDR) - -#define LGPMR_G1_MASK 0x0f -#define LGPMR_G1_SHIFT 0 -#define LGPMR_G2_MASK 0xf0 -#define LGPMR_G2_SHIFT 4 - -/* - * PWM Contrast Control Register - */ -#define PWMR_ADDR 0xfffffa36 -#define PWMR WORD_REF(PWMR_ADDR) - -#define PWMR_PW_MASK 0x00ff /* Pulse Width */ -#define PWMR_PW_SHIFT 0 -#define PWMR_CCPEN 0x0100 /* Contrast Control Enable */ -#define PWMR_SRC_MASK 0x0600 /* Input Clock Source */ -#define PWMR_SRC_LINE 0x0000 /* Line Pulse */ -#define PWMR_SRC_PIXEL 0x0200 /* Pixel Clock */ -#define PWMR_SRC_LCD 0x4000 /* LCD clock */ - -/********** - * - * 0xFFFFFBxx -- Real-Time Clock (RTC) - * - **********/ - -/* - * RTC Hours Minutes and Seconds Register - */ -#define RTCTIME_ADDR 0xfffffb00 -#define RTCTIME LONG_REF(RTCTIME_ADDR) - -#define RTCTIME_SECONDS_MASK 0x0000003f /* Seconds */ -#define RTCTIME_SECONDS_SHIFT 0 -#define RTCTIME_MINUTES_MASK 0x003f0000 /* Minutes */ -#define RTCTIME_MINUTES_SHIFT 16 -#define RTCTIME_HOURS_MASK 0x1f000000 /* Hours */ -#define RTCTIME_HOURS_SHIFT 24 - -/* - * RTC Alarm Register - */ -#define RTCALRM_ADDR 0xfffffb04 -#define RTCALRM LONG_REF(RTCALRM_ADDR) - -#define RTCALRM_SECONDS_MASK 0x0000003f /* Seconds */ -#define RTCALRM_SECONDS_SHIFT 0 -#define RTCALRM_MINUTES_MASK 0x003f0000 /* Minutes */ -#define RTCALRM_MINUTES_SHIFT 16 -#define RTCALRM_HOURS_MASK 0x1f000000 /* Hours */ -#define RTCALRM_HOURS_SHIFT 24 - -/* - * Watchdog Timer Register - */ -#define WATCHDOG_ADDR 0xfffffb0a -#define WATCHDOG WORD_REF(WATCHDOG_ADDR) - -#define WATCHDOG_EN 0x0001 /* Watchdog Enabled */ -#define WATCHDOG_ISEL 0x0002 /* Select the watchdog interrupt */ -#define WATCHDOG_INTF 0x0080 /* Watchdog interrupt occcured */ -#define WATCHDOG_CNT_MASK 0x0300 /* Watchdog Counter */ -#define WATCHDOG_CNT_SHIFT 8 - -/* - * RTC Control Register - */ -#define RTCCTL_ADDR 0xfffffb0c -#define RTCCTL WORD_REF(RTCCTL_ADDR) - -#define RTCCTL_XTL 0x0020 /* Crystal Selection */ -#define RTCCTL_EN 0x0080 /* RTC Enable */ - -/* '328-compatible definitions */ -#define RTCCTL_384 RTCCTL_XTL -#define RTCCTL_ENABLE RTCCTL_EN - -/* - * RTC Interrupt Status Register - */ -#define RTCISR_ADDR 0xfffffb0e -#define RTCISR WORD_REF(RTCISR_ADDR) - -#define RTCISR_SW 0x0001 /* Stopwatch timed out */ -#define RTCISR_MIN 0x0002 /* 1-minute interrupt has occurred */ -#define RTCISR_ALM 0x0004 /* Alarm interrupt has occurred */ -#define RTCISR_DAY 0x0008 /* 24-hour rollover interrupt has occurred */ -#define RTCISR_1HZ 0x0010 /* 1Hz interrupt has occurred */ -#define RTCISR_HR 0x0020 /* 1-hour interrupt has occurred */ -#define RTCISR_SAM0 0x0100 /* 4Hz / 4.6875Hz interrupt has occurred */ -#define RTCISR_SAM1 0x0200 /* 8Hz / 9.3750Hz interrupt has occurred */ -#define RTCISR_SAM2 0x0400 /* 16Hz / 18.7500Hz interrupt has occurred */ -#define RTCISR_SAM3 0x0800 /* 32Hz / 37.5000Hz interrupt has occurred */ -#define RTCISR_SAM4 0x1000 /* 64Hz / 75.0000Hz interrupt has occurred */ -#define RTCISR_SAM5 0x2000 /* 128Hz / 150.0000Hz interrupt has occurred */ -#define RTCISR_SAM6 0x4000 /* 256Hz / 300.0000Hz interrupt has occurred */ -#define RTCISR_SAM7 0x8000 /* 512Hz / 600.0000Hz interrupt has occurred */ - -/* - * RTC Interrupt Enable Register - */ -#define RTCIENR_ADDR 0xfffffb10 -#define RTCIENR WORD_REF(RTCIENR_ADDR) - -#define RTCIENR_SW 0x0001 /* Stopwatch interrupt enable */ -#define RTCIENR_MIN 0x0002 /* 1-minute interrupt enable */ -#define RTCIENR_ALM 0x0004 /* Alarm interrupt enable */ -#define RTCIENR_DAY 0x0008 /* 24-hour rollover interrupt enable */ -#define RTCIENR_1HZ 0x0010 /* 1Hz interrupt enable */ -#define RTCIENR_HR 0x0020 /* 1-hour interrupt enable */ -#define RTCIENR_SAM0 0x0100 /* 4Hz / 4.6875Hz interrupt enable */ -#define RTCIENR_SAM1 0x0200 /* 8Hz / 9.3750Hz interrupt enable */ -#define RTCIENR_SAM2 0x0400 /* 16Hz / 18.7500Hz interrupt enable */ -#define RTCIENR_SAM3 0x0800 /* 32Hz / 37.5000Hz interrupt enable */ -#define RTCIENR_SAM4 0x1000 /* 64Hz / 75.0000Hz interrupt enable */ -#define RTCIENR_SAM5 0x2000 /* 128Hz / 150.0000Hz interrupt enable */ -#define RTCIENR_SAM6 0x4000 /* 256Hz / 300.0000Hz interrupt enable */ -#define RTCIENR_SAM7 0x8000 /* 512Hz / 600.0000Hz interrupt enable */ - -/* - * Stopwatch Minutes Register - */ -#define STPWCH_ADDR 0xfffffb12 -#define STPWCH WORD_REF(STPWCH) - -#define STPWCH_CNT_MASK 0x003f /* Stopwatch countdown value */ -#define SPTWCH_CNT_SHIFT 0 - -/* - * RTC Day Count Register - */ -#define DAYR_ADDR 0xfffffb1a -#define DAYR WORD_REF(DAYR_ADDR) - -#define DAYR_DAYS_MASK 0x1ff /* Day Setting */ -#define DAYR_DAYS_SHIFT 0 - -/* - * RTC Day Alarm Register - */ -#define DAYALARM_ADDR 0xfffffb1c -#define DAYALARM WORD_REF(DAYALARM_ADDR) - -#define DAYALARM_DAYSAL_MASK 0x01ff /* Day Setting of the Alarm */ -#define DAYALARM_DAYSAL_SHIFT 0 - -/********** - * - * 0xFFFFFCxx -- DRAM Controller - * - **********/ - -/* - * DRAM Memory Configuration Register - */ -#define DRAMMC_ADDR 0xfffffc00 -#define DRAMMC WORD_REF(DRAMMC_ADDR) - -#define DRAMMC_ROW12_MASK 0xc000 /* Row address bit for MD12 */ -#define DRAMMC_ROW12_PA10 0x0000 -#define DRAMMC_ROW12_PA21 0x4000 -#define DRAMMC_ROW12_PA23 0x8000 -#define DRAMMC_ROW0_MASK 0x3000 /* Row address bit for MD0 */ -#define DRAMMC_ROW0_PA11 0x0000 -#define DRAMMC_ROW0_PA22 0x1000 -#define DRAMMC_ROW0_PA23 0x2000 -#define DRAMMC_ROW11 0x0800 /* Row address bit for MD11 PA20/PA22 */ -#define DRAMMC_ROW10 0x0400 /* Row address bit for MD10 PA19/PA21 */ -#define DRAMMC_ROW9 0x0200 /* Row address bit for MD9 PA9/PA19 */ -#define DRAMMC_ROW8 0x0100 /* Row address bit for MD8 PA10/PA20 */ -#define DRAMMC_COL10 0x0080 /* Col address bit for MD10 PA11/PA0 */ -#define DRAMMC_COL9 0x0040 /* Col address bit for MD9 PA10/PA0 */ -#define DRAMMC_COL8 0x0020 /* Col address bit for MD8 PA9/PA0 */ -#define DRAMMC_REF_MASK 0x001f /* Reresh Cycle */ -#define DRAMMC_REF_SHIFT 0 - -/* - * DRAM Control Register - */ -#define DRAMC_ADDR 0xfffffc02 -#define DRAMC WORD_REF(DRAMC_ADDR) - -#define DRAMC_DWE 0x0001 /* DRAM Write Enable */ -#define DRAMC_RST 0x0002 /* Reset Burst Refresh Enable */ -#define DRAMC_LPR 0x0004 /* Low-Power Refresh Enable */ -#define DRAMC_SLW 0x0008 /* Slow RAM */ -#define DRAMC_LSP 0x0010 /* Light Sleep */ -#define DRAMC_MSW 0x0020 /* Slow Multiplexing */ -#define DRAMC_WS_MASK 0x00c0 /* Wait-states */ -#define DRAMC_WS_SHIFT 6 -#define DRAMC_PGSZ_MASK 0x0300 /* Page Size for fast page mode */ -#define DRAMC_PGSZ_SHIFT 8 -#define DRAMC_PGSZ_256K 0x0000 -#define DRAMC_PGSZ_512K 0x0100 -#define DRAMC_PGSZ_1024K 0x0200 -#define DRAMC_PGSZ_2048K 0x0300 -#define DRAMC_EDO 0x0400 /* EDO DRAM */ -#define DRAMC_CLK 0x0800 /* Refresh Timer Clock source select */ -#define DRAMC_BC_MASK 0x3000 /* Page Access Clock Cycle (FP mode) */ -#define DRAMC_BC_SHIFT 12 -#define DRAMC_RM 0x4000 /* Refresh Mode */ -#define DRAMC_EN 0x8000 /* DRAM Controller enable */ - - -/********** - * - * 0xFFFFFDxx -- In-Circuit Emulation (ICE) - * - **********/ - -/* - * ICE Module Address Compare Register - */ -#define ICEMACR_ADDR 0xfffffd00 -#define ICEMACR LONG_REF(ICEMACR_ADDR) - -/* - * ICE Module Address Mask Register - */ -#define ICEMAMR_ADDR 0xfffffd04 -#define ICEMAMR LONG_REF(ICEMAMR_ADDR) - -/* - * ICE Module Control Compare Register - */ -#define ICEMCCR_ADDR 0xfffffd08 -#define ICEMCCR WORD_REF(ICEMCCR_ADDR) - -#define ICEMCCR_PD 0x0001 /* Program/Data Cycle Selection */ -#define ICEMCCR_RW 0x0002 /* Read/Write Cycle Selection */ - -/* - * ICE Module Control Mask Register - */ -#define ICEMCMR_ADDR 0xfffffd0a -#define ICEMCMR WORD_REF(ICEMCMR_ADDR) - -#define ICEMCMR_PDM 0x0001 /* Program/Data Cycle Mask */ -#define ICEMCMR_RWM 0x0002 /* Read/Write Cycle Mask */ - -/* - * ICE Module Control Register - */ -#define ICEMCR_ADDR 0xfffffd0c -#define ICEMCR WORD_REF(ICEMCR_ADDR) - -#define ICEMCR_CEN 0x0001 /* Compare Enable */ -#define ICEMCR_PBEN 0x0002 /* Program Break Enable */ -#define ICEMCR_SB 0x0004 /* Single Breakpoint */ -#define ICEMCR_HMDIS 0x0008 /* HardMap disable */ -#define ICEMCR_BBIEN 0x0010 /* Bus Break Interrupt Enable */ - -/* - * ICE Module Status Register - */ -#define ICEMSR_ADDR 0xfffffd0e -#define ICEMSR WORD_REF(ICEMSR_ADDR) - -#define ICEMSR_EMUEN 0x0001 /* Emulation Enable */ -#define ICEMSR_BRKIRQ 0x0002 /* A-Line Vector Fetch Detected */ -#define ICEMSR_BBIRQ 0x0004 /* Bus Break Interrupt Detected */ -#define ICEMSR_EMIRQ 0x0008 /* EMUIRQ Falling Edge Detected */ - -#endif /* _MC68EZ328_H_ */ diff --git a/arch/m68knommu/include/asm/MC68VZ328.h b/arch/m68knommu/include/asm/MC68VZ328.h deleted file mode 100644 index 2b9bf626a0a..00000000000 --- a/arch/m68knommu/include/asm/MC68VZ328.h +++ /dev/null @@ -1,1349 +0,0 @@ - -/* include/asm-m68knommu/MC68VZ328.h: 'VZ328 control registers - * - * Copyright (c) 2000-2001 Lineo Inc. - * Copyright (c) 2000-2001 Lineo Canada Corp. - * Copyright (C) 1999 Vladimir Gurevich - * Bare & Hare Software, Inc. - * Based on include/asm-m68knommu/MC68332.h - * Copyright (C) 1998 Kenneth Albanowski , - * The Silver Hammer Group, Ltd. - * - * M68VZ328 fixes by Evan Stawnyczy - * vz multiport fixes by Michael Leslie - */ - -#ifndef _MC68VZ328_H_ -#define _MC68VZ328_H_ - -#define BYTE_REF(addr) (*((volatile unsigned char*)addr)) -#define WORD_REF(addr) (*((volatile unsigned short*)addr)) -#define LONG_REF(addr) (*((volatile unsigned long*)addr)) - -#define PUT_FIELD(field, val) (((val) << field##_SHIFT) & field##_MASK) -#define GET_FIELD(reg, field) (((reg) & field##_MASK) >> field##_SHIFT) - -/********** - * - * 0xFFFFF0xx -- System Control - * - **********/ - -/* - * System Control Register (SCR) - */ -#define SCR_ADDR 0xfffff000 -#define SCR BYTE_REF(SCR_ADDR) - -#define SCR_WDTH8 0x01 /* 8-Bit Width Select */ -#define SCR_DMAP 0x04 /* Double Map */ -#define SCR_SO 0x08 /* Supervisor Only */ -#define SCR_BETEN 0x10 /* Bus-Error Time-Out Enable */ -#define SCR_PRV 0x20 /* Privilege Violation */ -#define SCR_WPV 0x40 /* Write Protect Violation */ -#define SCR_BETO 0x80 /* Bus-Error TimeOut */ - -/* - * Silicon ID Register (Mask Revision Register (MRR) for '328 Compatibility) - */ -#define MRR_ADDR 0xfffff004 -#define MRR LONG_REF(MRR_ADDR) - -/********** - * - * 0xFFFFF1xx -- Chip-Select logic - * - **********/ - -/* - * Chip Select Group Base Registers - */ -#define CSGBA_ADDR 0xfffff100 -#define CSGBB_ADDR 0xfffff102 - -#define CSGBC_ADDR 0xfffff104 -#define CSGBD_ADDR 0xfffff106 - -#define CSGBA WORD_REF(CSGBA_ADDR) -#define CSGBB WORD_REF(CSGBB_ADDR) -#define CSGBC WORD_REF(CSGBC_ADDR) -#define CSGBD WORD_REF(CSGBD_ADDR) - -/* - * Chip Select Registers - */ -#define CSA_ADDR 0xfffff110 -#define CSB_ADDR 0xfffff112 -#define CSC_ADDR 0xfffff114 -#define CSD_ADDR 0xfffff116 - -#define CSA WORD_REF(CSA_ADDR) -#define CSB WORD_REF(CSB_ADDR) -#define CSC WORD_REF(CSC_ADDR) -#define CSD WORD_REF(CSD_ADDR) - -#define CSA_EN 0x0001 /* Chip-Select Enable */ -#define CSA_SIZ_MASK 0x000e /* Chip-Select Size */ -#define CSA_SIZ_SHIFT 1 -#define CSA_WS_MASK 0x0070 /* Wait State */ -#define CSA_WS_SHIFT 4 -#define CSA_BSW 0x0080 /* Data Bus Width */ -#define CSA_FLASH 0x0100 /* FLASH Memory Support */ -#define CSA_RO 0x8000 /* Read-Only */ - -#define CSB_EN 0x0001 /* Chip-Select Enable */ -#define CSB_SIZ_MASK 0x000e /* Chip-Select Size */ -#define CSB_SIZ_SHIFT 1 -#define CSB_WS_MASK 0x0070 /* Wait State */ -#define CSB_WS_SHIFT 4 -#define CSB_BSW 0x0080 /* Data Bus Width */ -#define CSB_FLASH 0x0100 /* FLASH Memory Support */ -#define CSB_UPSIZ_MASK 0x1800 /* Unprotected memory block size */ -#define CSB_UPSIZ_SHIFT 11 -#define CSB_ROP 0x2000 /* Readonly if protected */ -#define CSB_SOP 0x4000 /* Supervisor only if protected */ -#define CSB_RO 0x8000 /* Read-Only */ - -#define CSC_EN 0x0001 /* Chip-Select Enable */ -#define CSC_SIZ_MASK 0x000e /* Chip-Select Size */ -#define CSC_SIZ_SHIFT 1 -#define CSC_WS_MASK 0x0070 /* Wait State */ -#define CSC_WS_SHIFT 4 -#define CSC_BSW 0x0080 /* Data Bus Width */ -#define CSC_FLASH 0x0100 /* FLASH Memory Support */ -#define CSC_UPSIZ_MASK 0x1800 /* Unprotected memory block size */ -#define CSC_UPSIZ_SHIFT 11 -#define CSC_ROP 0x2000 /* Readonly if protected */ -#define CSC_SOP 0x4000 /* Supervisor only if protected */ -#define CSC_RO 0x8000 /* Read-Only */ - -#define CSD_EN 0x0001 /* Chip-Select Enable */ -#define CSD_SIZ_MASK 0x000e /* Chip-Select Size */ -#define CSD_SIZ_SHIFT 1 -#define CSD_WS_MASK 0x0070 /* Wait State */ -#define CSD_WS_SHIFT 4 -#define CSD_BSW 0x0080 /* Data Bus Width */ -#define CSD_FLASH 0x0100 /* FLASH Memory Support */ -#define CSD_DRAM 0x0200 /* Dram Selection */ -#define CSD_COMB 0x0400 /* Combining */ -#define CSD_UPSIZ_MASK 0x1800 /* Unprotected memory block size */ -#define CSD_UPSIZ_SHIFT 11 -#define CSD_ROP 0x2000 /* Readonly if protected */ -#define CSD_SOP 0x4000 /* Supervisor only if protected */ -#define CSD_RO 0x8000 /* Read-Only */ - -/* - * Emulation Chip-Select Register - */ -#define EMUCS_ADDR 0xfffff118 -#define EMUCS WORD_REF(EMUCS_ADDR) - -#define EMUCS_WS_MASK 0x0070 -#define EMUCS_WS_SHIFT 4 - -/********** - * - * 0xFFFFF2xx -- Phase Locked Loop (PLL) & Power Control - * - **********/ - -/* - * PLL Control Register - */ -#define PLLCR_ADDR 0xfffff200 -#define PLLCR WORD_REF(PLLCR_ADDR) - -#define PLLCR_DISPLL 0x0008 /* Disable PLL */ -#define PLLCR_CLKEN 0x0010 /* Clock (CLKO pin) enable */ -#define PLLCR_PRESC 0x0020 /* VCO prescaler */ -#define PLLCR_SYSCLK_SEL_MASK 0x0700 /* System Clock Selection */ -#define PLLCR_SYSCLK_SEL_SHIFT 8 -#define PLLCR_LCDCLK_SEL_MASK 0x3800 /* LCD Clock Selection */ -#define PLLCR_LCDCLK_SEL_SHIFT 11 - -/* '328-compatible definitions */ -#define PLLCR_PIXCLK_SEL_MASK PLLCR_LCDCLK_SEL_MASK -#define PLLCR_PIXCLK_SEL_SHIFT PLLCR_LCDCLK_SEL_SHIFT - -/* - * PLL Frequency Select Register - */ -#define PLLFSR_ADDR 0xfffff202 -#define PLLFSR WORD_REF(PLLFSR_ADDR) - -#define PLLFSR_PC_MASK 0x00ff /* P Count */ -#define PLLFSR_PC_SHIFT 0 -#define PLLFSR_QC_MASK 0x0f00 /* Q Count */ -#define PLLFSR_QC_SHIFT 8 -#define PLLFSR_PROT 0x4000 /* Protect P & Q */ -#define PLLFSR_CLK32 0x8000 /* Clock 32 (kHz) */ - -/* - * Power Control Register - */ -#define PCTRL_ADDR 0xfffff207 -#define PCTRL BYTE_REF(PCTRL_ADDR) - -#define PCTRL_WIDTH_MASK 0x1f /* CPU Clock bursts width */ -#define PCTRL_WIDTH_SHIFT 0 -#define PCTRL_PCEN 0x80 /* Power Control Enable */ - -/********** - * - * 0xFFFFF3xx -- Interrupt Controller - * - **********/ - -/* - * Interrupt Vector Register - */ -#define IVR_ADDR 0xfffff300 -#define IVR BYTE_REF(IVR_ADDR) - -#define IVR_VECTOR_MASK 0xF8 - -/* - * Interrupt control Register - */ -#define ICR_ADDR 0xfffff302 -#define ICR WORD_REF(ICR_ADDR) - -#define ICR_POL5 0x0080 /* Polarity Control for IRQ5 */ -#define ICR_ET6 0x0100 /* Edge Trigger Select for IRQ6 */ -#define ICR_ET3 0x0200 /* Edge Trigger Select for IRQ3 */ -#define ICR_ET2 0x0400 /* Edge Trigger Select for IRQ2 */ -#define ICR_ET1 0x0800 /* Edge Trigger Select for IRQ1 */ -#define ICR_POL6 0x1000 /* Polarity Control for IRQ6 */ -#define ICR_POL3 0x2000 /* Polarity Control for IRQ3 */ -#define ICR_POL2 0x4000 /* Polarity Control for IRQ2 */ -#define ICR_POL1 0x8000 /* Polarity Control for IRQ1 */ - -/* - * Interrupt Mask Register - */ -#define IMR_ADDR 0xfffff304 -#define IMR LONG_REF(IMR_ADDR) - -/* - * Define the names for bit positions first. This is useful for - * request_irq - */ -#define SPI2_IRQ_NUM 0 /* SPI 2 interrupt */ -#define TMR_IRQ_NUM 1 /* Timer 1 interrupt */ -#define UART1_IRQ_NUM 2 /* UART 1 interrupt */ -#define WDT_IRQ_NUM 3 /* Watchdog Timer interrupt */ -#define RTC_IRQ_NUM 4 /* RTC interrupt */ -#define TMR2_IRQ_NUM 5 /* Timer 2 interrupt */ -#define KB_IRQ_NUM 6 /* Keyboard Interrupt */ -#define PWM1_IRQ_NUM 7 /* Pulse-Width Modulator 1 int. */ -#define INT0_IRQ_NUM 8 /* External INT0 */ -#define INT1_IRQ_NUM 9 /* External INT1 */ -#define INT2_IRQ_NUM 10 /* External INT2 */ -#define INT3_IRQ_NUM 11 /* External INT3 */ -#define UART2_IRQ_NUM 12 /* UART 2 interrupt */ -#define PWM2_IRQ_NUM 13 /* Pulse-Width Modulator 1 int. */ -#define IRQ1_IRQ_NUM 16 /* IRQ1 */ -#define IRQ2_IRQ_NUM 17 /* IRQ2 */ -#define IRQ3_IRQ_NUM 18 /* IRQ3 */ -#define IRQ6_IRQ_NUM 19 /* IRQ6 */ -#define IRQ5_IRQ_NUM 20 /* IRQ5 */ -#define SPI1_IRQ_NUM 21 /* SPI 1 interrupt */ -#define SAM_IRQ_NUM 22 /* Sampling Timer for RTC */ -#define EMIQ_IRQ_NUM 23 /* Emulator Interrupt */ - -#define SPI_IRQ_NUM SPI2_IRQ_NUM - -/* '328-compatible definitions */ -#define SPIM_IRQ_NUM SPI_IRQ_NUM -#define TMR1_IRQ_NUM TMR_IRQ_NUM -#define UART_IRQ_NUM UART1_IRQ_NUM - -/* - * Here go the bitmasks themselves - */ -#define IMR_MSPI (1 << SPI_IRQ_NUM) /* Mask SPI interrupt */ -#define IMR_MTMR (1 << TMR_IRQ_NUM) /* Mask Timer interrupt */ -#define IMR_MUART (1 << UART_IRQ_NUM) /* Mask UART interrupt */ -#define IMR_MWDT (1 << WDT_IRQ_NUM) /* Mask Watchdog Timer interrupt */ -#define IMR_MRTC (1 << RTC_IRQ_NUM) /* Mask RTC interrupt */ -#define IMR_MKB (1 << KB_IRQ_NUM) /* Mask Keyboard Interrupt */ -#define IMR_MPWM (1 << PWM_IRQ_NUM) /* Mask Pulse-Width Modulator int. */ -#define IMR_MINT0 (1 << INT0_IRQ_NUM) /* Mask External INT0 */ -#define IMR_MINT1 (1 << INT1_IRQ_NUM) /* Mask External INT1 */ -#define IMR_MINT2 (1 << INT2_IRQ_NUM) /* Mask External INT2 */ -#define IMR_MINT3 (1 << INT3_IRQ_NUM) /* Mask External INT3 */ -#define IMR_MIRQ1 (1 << IRQ1_IRQ_NUM) /* Mask IRQ1 */ -#define IMR_MIRQ2 (1 << IRQ2_IRQ_NUM) /* Mask IRQ2 */ -#define IMR_MIRQ3 (1 << IRQ3_IRQ_NUM) /* Mask IRQ3 */ -#define IMR_MIRQ6 (1 << IRQ6_IRQ_NUM) /* Mask IRQ6 */ -#define IMR_MIRQ5 (1 << IRQ5_IRQ_NUM) /* Mask IRQ5 */ -#define IMR_MSAM (1 << SAM_IRQ_NUM) /* Mask Sampling Timer for RTC */ -#define IMR_MEMIQ (1 << EMIQ_IRQ_NUM) /* Mask Emulator Interrupt */ - -/* '328-compatible definitions */ -#define IMR_MSPIM IMR_MSPI -#define IMR_MTMR1 IMR_MTMR - -/* - * Interrupt Status Register - */ -#define ISR_ADDR 0xfffff30c -#define ISR LONG_REF(ISR_ADDR) - -#define ISR_SPI (1 << SPI_IRQ_NUM) /* SPI interrupt */ -#define ISR_TMR (1 << TMR_IRQ_NUM) /* Timer interrupt */ -#define ISR_UART (1 << UART_IRQ_NUM) /* UART interrupt */ -#define ISR_WDT (1 << WDT_IRQ_NUM) /* Watchdog Timer interrupt */ -#define ISR_RTC (1 << RTC_IRQ_NUM) /* RTC interrupt */ -#define ISR_KB (1 << KB_IRQ_NUM) /* Keyboard Interrupt */ -#define ISR_PWM (1 << PWM_IRQ_NUM) /* Pulse-Width Modulator interrupt */ -#define ISR_INT0 (1 << INT0_IRQ_NUM) /* External INT0 */ -#define ISR_INT1 (1 << INT1_IRQ_NUM) /* External INT1 */ -#define ISR_INT2 (1 << INT2_IRQ_NUM) /* External INT2 */ -#define ISR_INT3 (1 << INT3_IRQ_NUM) /* External INT3 */ -#define ISR_IRQ1 (1 << IRQ1_IRQ_NUM) /* IRQ1 */ -#define ISR_IRQ2 (1 << IRQ2_IRQ_NUM) /* IRQ2 */ -#define ISR_IRQ3 (1 << IRQ3_IRQ_NUM) /* IRQ3 */ -#define ISR_IRQ6 (1 << IRQ6_IRQ_NUM) /* IRQ6 */ -#define ISR_IRQ5 (1 << IRQ5_IRQ_NUM) /* IRQ5 */ -#define ISR_SAM (1 << SAM_IRQ_NUM) /* Sampling Timer for RTC */ -#define ISR_EMIQ (1 << EMIQ_IRQ_NUM) /* Emulator Interrupt */ - -/* '328-compatible definitions */ -#define ISR_SPIM ISR_SPI -#define ISR_TMR1 ISR_TMR - -/* - * Interrupt Pending Register - */ -#define IPR_ADDR 0xfffff30c -#define IPR LONG_REF(IPR_ADDR) - -#define IPR_SPI (1 << SPI_IRQ_NUM) /* SPI interrupt */ -#define IPR_TMR (1 << TMR_IRQ_NUM) /* Timer interrupt */ -#define IPR_UART (1 << UART_IRQ_NUM) /* UART interrupt */ -#define IPR_WDT (1 << WDT_IRQ_NUM) /* Watchdog Timer interrupt */ -#define IPR_RTC (1 << RTC_IRQ_NUM) /* RTC interrupt */ -#define IPR_KB (1 << KB_IRQ_NUM) /* Keyboard Interrupt */ -#define IPR_PWM (1 << PWM_IRQ_NUM) /* Pulse-Width Modulator interrupt */ -#define IPR_INT0 (1 << INT0_IRQ_NUM) /* External INT0 */ -#define IPR_INT1 (1 << INT1_IRQ_NUM) /* External INT1 */ -#define IPR_INT2 (1 << INT2_IRQ_NUM) /* External INT2 */ -#define IPR_INT3 (1 << INT3_IRQ_NUM) /* External INT3 */ -#define IPR_IRQ1 (1 << IRQ1_IRQ_NUM) /* IRQ1 */ -#define IPR_IRQ2 (1 << IRQ2_IRQ_NUM) /* IRQ2 */ -#define IPR_IRQ3 (1 << IRQ3_IRQ_NUM) /* IRQ3 */ -#define IPR_IRQ6 (1 << IRQ6_IRQ_NUM) /* IRQ6 */ -#define IPR_IRQ5 (1 << IRQ5_IRQ_NUM) /* IRQ5 */ -#define IPR_SAM (1 << SAM_IRQ_NUM) /* Sampling Timer for RTC */ -#define IPR_EMIQ (1 << EMIQ_IRQ_NUM) /* Emulator Interrupt */ - -/* '328-compatible definitions */ -#define IPR_SPIM IPR_SPI -#define IPR_TMR1 IPR_TMR - -/********** - * - * 0xFFFFF4xx -- Parallel Ports - * - **********/ - -/* - * Port A - */ -#define PADIR_ADDR 0xfffff400 /* Port A direction reg */ -#define PADATA_ADDR 0xfffff401 /* Port A data register */ -#define PAPUEN_ADDR 0xfffff402 /* Port A Pull-Up enable reg */ - -#define PADIR BYTE_REF(PADIR_ADDR) -#define PADATA BYTE_REF(PADATA_ADDR) -#define PAPUEN BYTE_REF(PAPUEN_ADDR) - -#define PA(x) (1 << (x)) - -/* - * Port B - */ -#define PBDIR_ADDR 0xfffff408 /* Port B direction reg */ -#define PBDATA_ADDR 0xfffff409 /* Port B data register */ -#define PBPUEN_ADDR 0xfffff40a /* Port B Pull-Up enable reg */ -#define PBSEL_ADDR 0xfffff40b /* Port B Select Register */ - -#define PBDIR BYTE_REF(PBDIR_ADDR) -#define PBDATA BYTE_REF(PBDATA_ADDR) -#define PBPUEN BYTE_REF(PBPUEN_ADDR) -#define PBSEL BYTE_REF(PBSEL_ADDR) - -#define PB(x) (1 << (x)) - -#define PB_CSB0 0x01 /* Use CSB0 as PB[0] */ -#define PB_CSB1 0x02 /* Use CSB1 as PB[1] */ -#define PB_CSC0_RAS0 0x04 /* Use CSC0/RAS0 as PB[2] */ -#define PB_CSC1_RAS1 0x08 /* Use CSC1/RAS1 as PB[3] */ -#define PB_CSD0_CAS0 0x10 /* Use CSD0/CAS0 as PB[4] */ -#define PB_CSD1_CAS1 0x20 /* Use CSD1/CAS1 as PB[5] */ -#define PB_TIN_TOUT 0x40 /* Use TIN/TOUT as PB[6] */ -#define PB_PWMO 0x80 /* Use PWMO as PB[7] */ - -/* - * Port C - */ -#define PCDIR_ADDR 0xfffff410 /* Port C direction reg */ -#define PCDATA_ADDR 0xfffff411 /* Port C data register */ -#define PCPDEN_ADDR 0xfffff412 /* Port C Pull-Down enb. reg */ -#define PCSEL_ADDR 0xfffff413 /* Port C Select Register */ - -#define PCDIR BYTE_REF(PCDIR_ADDR) -#define PCDATA BYTE_REF(PCDATA_ADDR) -#define PCPDEN BYTE_REF(PCPDEN_ADDR) -#define PCSEL BYTE_REF(PCSEL_ADDR) - -#define PC(x) (1 << (x)) - -#define PC_LD0 0x01 /* Use LD0 as PC[0] */ -#define PC_LD1 0x02 /* Use LD1 as PC[1] */ -#define PC_LD2 0x04 /* Use LD2 as PC[2] */ -#define PC_LD3 0x08 /* Use LD3 as PC[3] */ -#define PC_LFLM 0x10 /* Use LFLM as PC[4] */ -#define PC_LLP 0x20 /* Use LLP as PC[5] */ -#define PC_LCLK 0x40 /* Use LCLK as PC[6] */ -#define PC_LACD 0x80 /* Use LACD as PC[7] */ - -/* - * Port D - */ -#define PDDIR_ADDR 0xfffff418 /* Port D direction reg */ -#define PDDATA_ADDR 0xfffff419 /* Port D data register */ -#define PDPUEN_ADDR 0xfffff41a /* Port D Pull-Up enable reg */ -#define PDSEL_ADDR 0xfffff41b /* Port D Select Register */ -#define PDPOL_ADDR 0xfffff41c /* Port D Polarity Register */ -#define PDIRQEN_ADDR 0xfffff41d /* Port D IRQ enable register */ -#define PDKBEN_ADDR 0xfffff41e /* Port D Keyboard Enable reg */ -#define PDIQEG_ADDR 0xfffff41f /* Port D IRQ Edge Register */ - -#define PDDIR BYTE_REF(PDDIR_ADDR) -#define PDDATA BYTE_REF(PDDATA_ADDR) -#define PDPUEN BYTE_REF(PDPUEN_ADDR) -#define PDSEL BYTE_REF(PDSEL_ADDR) -#define PDPOL BYTE_REF(PDPOL_ADDR) -#define PDIRQEN BYTE_REF(PDIRQEN_ADDR) -#define PDKBEN BYTE_REF(PDKBEN_ADDR) -#define PDIQEG BYTE_REF(PDIQEG_ADDR) - -#define PD(x) (1 << (x)) - -#define PD_INT0 0x01 /* Use INT0 as PD[0] */ -#define PD_INT1 0x02 /* Use INT1 as PD[1] */ -#define PD_INT2 0x04 /* Use INT2 as PD[2] */ -#define PD_INT3 0x08 /* Use INT3 as PD[3] */ -#define PD_IRQ1 0x10 /* Use IRQ1 as PD[4] */ -#define PD_IRQ2 0x20 /* Use IRQ2 as PD[5] */ -#define PD_IRQ3 0x40 /* Use IRQ3 as PD[6] */ -#define PD_IRQ6 0x80 /* Use IRQ6 as PD[7] */ - -/* - * Port E - */ -#define PEDIR_ADDR 0xfffff420 /* Port E direction reg */ -#define PEDATA_ADDR 0xfffff421 /* Port E data register */ -#define PEPUEN_ADDR 0xfffff422 /* Port E Pull-Up enable reg */ -#define PESEL_ADDR 0xfffff423 /* Port E Select Register */ - -#define PEDIR BYTE_REF(PEDIR_ADDR) -#define PEDATA BYTE_REF(PEDATA_ADDR) -#define PEPUEN BYTE_REF(PEPUEN_ADDR) -#define PESEL BYTE_REF(PESEL_ADDR) - -#define PE(x) (1 << (x)) - -#define PE_SPMTXD 0x01 /* Use SPMTXD as PE[0] */ -#define PE_SPMRXD 0x02 /* Use SPMRXD as PE[1] */ -#define PE_SPMCLK 0x04 /* Use SPMCLK as PE[2] */ -#define PE_DWE 0x08 /* Use DWE as PE[3] */ -#define PE_RXD 0x10 /* Use RXD as PE[4] */ -#define PE_TXD 0x20 /* Use TXD as PE[5] */ -#define PE_RTS 0x40 /* Use RTS as PE[6] */ -#define PE_CTS 0x80 /* Use CTS as PE[7] */ - -/* - * Port F - */ -#define PFDIR_ADDR 0xfffff428 /* Port F direction reg */ -#define PFDATA_ADDR 0xfffff429 /* Port F data register */ -#define PFPUEN_ADDR 0xfffff42a /* Port F Pull-Up enable reg */ -#define PFSEL_ADDR 0xfffff42b /* Port F Select Register */ - -#define PFDIR BYTE_REF(PFDIR_ADDR) -#define PFDATA BYTE_REF(PFDATA_ADDR) -#define PFPUEN BYTE_REF(PFPUEN_ADDR) -#define PFSEL BYTE_REF(PFSEL_ADDR) - -#define PF(x) (1 << (x)) - -#define PF_LCONTRAST 0x01 /* Use LCONTRAST as PF[0] */ -#define PF_IRQ5 0x02 /* Use IRQ5 as PF[1] */ -#define PF_CLKO 0x04 /* Use CLKO as PF[2] */ -#define PF_A20 0x08 /* Use A20 as PF[3] */ -#define PF_A21 0x10 /* Use A21 as PF[4] */ -#define PF_A22 0x20 /* Use A22 as PF[5] */ -#define PF_A23 0x40 /* Use A23 as PF[6] */ -#define PF_CSA1 0x80 /* Use CSA1 as PF[7] */ - -/* - * Port G - */ -#define PGDIR_ADDR 0xfffff430 /* Port G direction reg */ -#define PGDATA_ADDR 0xfffff431 /* Port G data register */ -#define PGPUEN_ADDR 0xfffff432 /* Port G Pull-Up enable reg */ -#define PGSEL_ADDR 0xfffff433 /* Port G Select Register */ - -#define PGDIR BYTE_REF(PGDIR_ADDR) -#define PGDATA BYTE_REF(PGDATA_ADDR) -#define PGPUEN BYTE_REF(PGPUEN_ADDR) -#define PGSEL BYTE_REF(PGSEL_ADDR) - -#define PG(x) (1 << (x)) - -#define PG_BUSW_DTACK 0x01 /* Use BUSW/DTACK as PG[0] */ -#define PG_A0 0x02 /* Use A0 as PG[1] */ -#define PG_EMUIRQ 0x04 /* Use EMUIRQ as PG[2] */ -#define PG_HIZ_P_D 0x08 /* Use HIZ/P/D as PG[3] */ -#define PG_EMUCS 0x10 /* Use EMUCS as PG[4] */ -#define PG_EMUBRK 0x20 /* Use EMUBRK as PG[5] */ - -/* - * Port J - */ -#define PJDIR_ADDR 0xfffff438 /* Port J direction reg */ -#define PJDATA_ADDR 0xfffff439 /* Port J data register */ -#define PJPUEN_ADDR 0xfffff43A /* Port J Pull-Up enb. reg */ -#define PJSEL_ADDR 0xfffff43B /* Port J Select Register */ - -#define PJDIR BYTE_REF(PJDIR_ADDR) -#define PJDATA BYTE_REF(PJDATA_ADDR) -#define PJPUEN BYTE_REF(PJPUEN_ADDR) -#define PJSEL BYTE_REF(PJSEL_ADDR) - -#define PJ(x) (1 << (x)) - -/* - * Port K - */ -#define PKDIR_ADDR 0xfffff440 /* Port K direction reg */ -#define PKDATA_ADDR 0xfffff441 /* Port K data register */ -#define PKPUEN_ADDR 0xfffff442 /* Port K Pull-Up enb. reg */ -#define PKSEL_ADDR 0xfffff443 /* Port K Select Register */ - -#define PKDIR BYTE_REF(PKDIR_ADDR) -#define PKDATA BYTE_REF(PKDATA_ADDR) -#define PKPUEN BYTE_REF(PKPUEN_ADDR) -#define PKSEL BYTE_REF(PKSEL_ADDR) - -#define PK(x) (1 << (x)) - -#define PK_DATAREADY 0x01 /* Use ~DATA_READY as PK[0] */ -#define PK_PWM2 0x01 /* Use PWM2 as PK[0] */ -#define PK_R_W 0x02 /* Use R/W as PK[1] */ -#define PK_LDS 0x04 /* Use /LDS as PK[2] */ -#define PK_UDS 0x08 /* Use /UDS as PK[3] */ -#define PK_LD4 0x10 /* Use LD4 as PK[4] */ -#define PK_LD5 0x20 /* Use LD5 as PK[5] */ -#define PK_LD6 0x40 /* Use LD6 as PK[6] */ -#define PK_LD7 0x80 /* Use LD7 as PK[7] */ - -#define PJDIR_ADDR 0xfffff438 /* Port J direction reg */ -#define PJDATA_ADDR 0xfffff439 /* Port J data register */ -#define PJPUEN_ADDR 0xfffff43A /* Port J Pull-Up enable reg */ -#define PJSEL_ADDR 0xfffff43B /* Port J Select Register */ - -#define PJDIR BYTE_REF(PJDIR_ADDR) -#define PJDATA BYTE_REF(PJDATA_ADDR) -#define PJPUEN BYTE_REF(PJPUEN_ADDR) -#define PJSEL BYTE_REF(PJSEL_ADDR) - -#define PJ(x) (1 << (x)) - -#define PJ_MOSI 0x01 /* Use MOSI as PJ[0] */ -#define PJ_MISO 0x02 /* Use MISO as PJ[1] */ -#define PJ_SPICLK1 0x04 /* Use SPICLK1 as PJ[2] */ -#define PJ_SS 0x08 /* Use SS as PJ[3] */ -#define PJ_RXD2 0x10 /* Use RXD2 as PJ[4] */ -#define PJ_TXD2 0x20 /* Use TXD2 as PJ[5] */ -#define PJ_RTS2 0x40 /* Use RTS2 as PJ[5] */ -#define PJ_CTS2 0x80 /* Use CTS2 as PJ[5] */ - -/* - * Port M - */ -#define PMDIR_ADDR 0xfffff448 /* Port M direction reg */ -#define PMDATA_ADDR 0xfffff449 /* Port M data register */ -#define PMPUEN_ADDR 0xfffff44a /* Port M Pull-Up enable reg */ -#define PMSEL_ADDR 0xfffff44b /* Port M Select Register */ - -#define PMDIR BYTE_REF(PMDIR_ADDR) -#define PMDATA BYTE_REF(PMDATA_ADDR) -#define PMPUEN BYTE_REF(PMPUEN_ADDR) -#define PMSEL BYTE_REF(PMSEL_ADDR) - -#define PM(x) (1 << (x)) - -#define PM_SDCLK 0x01 /* Use SDCLK as PM[0] */ -#define PM_SDCE 0x02 /* Use SDCE as PM[1] */ -#define PM_DQMH 0x04 /* Use DQMH as PM[2] */ -#define PM_DQML 0x08 /* Use DQML as PM[3] */ -#define PM_SDA10 0x10 /* Use SDA10 as PM[4] */ -#define PM_DMOE 0x20 /* Use DMOE as PM[5] */ - -/********** - * - * 0xFFFFF5xx -- Pulse-Width Modulator (PWM) - * - **********/ - -/* - * PWM Control Register - */ -#define PWMC_ADDR 0xfffff500 -#define PWMC WORD_REF(PWMC_ADDR) - -#define PWMC_CLKSEL_MASK 0x0003 /* Clock Selection */ -#define PWMC_CLKSEL_SHIFT 0 -#define PWMC_REPEAT_MASK 0x000c /* Sample Repeats */ -#define PWMC_REPEAT_SHIFT 2 -#define PWMC_EN 0x0010 /* Enable PWM */ -#define PMNC_FIFOAV 0x0020 /* FIFO Available */ -#define PWMC_IRQEN 0x0040 /* Interrupt Request Enable */ -#define PWMC_IRQ 0x0080 /* Interrupt Request (FIFO empty) */ -#define PWMC_PRESCALER_MASK 0x7f00 /* Incoming Clock prescaler */ -#define PWMC_PRESCALER_SHIFT 8 -#define PWMC_CLKSRC 0x8000 /* Clock Source Select */ - -/* '328-compatible definitions */ -#define PWMC_PWMEN PWMC_EN - -/* - * PWM Sample Register - */ -#define PWMS_ADDR 0xfffff502 -#define PWMS WORD_REF(PWMS_ADDR) - -/* - * PWM Period Register - */ -#define PWMP_ADDR 0xfffff504 -#define PWMP BYTE_REF(PWMP_ADDR) - -/* - * PWM Counter Register - */ -#define PWMCNT_ADDR 0xfffff505 -#define PWMCNT BYTE_REF(PWMCNT_ADDR) - -/********** - * - * 0xFFFFF6xx -- General-Purpose Timer - * - **********/ - -/* - * Timer Control register - */ -#define TCTL_ADDR 0xfffff600 -#define TCTL WORD_REF(TCTL_ADDR) - -#define TCTL_TEN 0x0001 /* Timer Enable */ -#define TCTL_CLKSOURCE_MASK 0x000e /* Clock Source: */ -#define TCTL_CLKSOURCE_STOP 0x0000 /* Stop count (disabled) */ -#define TCTL_CLKSOURCE_SYSCLK 0x0002 /* SYSCLK to prescaler */ -#define TCTL_CLKSOURCE_SYSCLK_16 0x0004 /* SYSCLK/16 to prescaler */ -#define TCTL_CLKSOURCE_TIN 0x0006 /* TIN to prescaler */ -#define TCTL_CLKSOURCE_32KHZ 0x0008 /* 32kHz clock to prescaler */ -#define TCTL_IRQEN 0x0010 /* IRQ Enable */ -#define TCTL_OM 0x0020 /* Output Mode */ -#define TCTL_CAP_MASK 0x00c0 /* Capture Edge: */ -#define TCTL_CAP_RE 0x0040 /* Capture on rizing edge */ -#define TCTL_CAP_FE 0x0080 /* Capture on falling edge */ -#define TCTL_FRR 0x0010 /* Free-Run Mode */ - -/* '328-compatible definitions */ -#define TCTL1_ADDR TCTL_ADDR -#define TCTL1 TCTL - -/* - * Timer Prescaler Register - */ -#define TPRER_ADDR 0xfffff602 -#define TPRER WORD_REF(TPRER_ADDR) - -/* '328-compatible definitions */ -#define TPRER1_ADDR TPRER_ADDR -#define TPRER1 TPRER - -/* - * Timer Compare Register - */ -#define TCMP_ADDR 0xfffff604 -#define TCMP WORD_REF(TCMP_ADDR) - -/* '328-compatible definitions */ -#define TCMP1_ADDR TCMP_ADDR -#define TCMP1 TCMP - -/* - * Timer Capture register - */ -#define TCR_ADDR 0xfffff606 -#define TCR WORD_REF(TCR_ADDR) - -/* '328-compatible definitions */ -#define TCR1_ADDR TCR_ADDR -#define TCR1 TCR - -/* - * Timer Counter Register - */ -#define TCN_ADDR 0xfffff608 -#define TCN WORD_REF(TCN_ADDR) - -/* '328-compatible definitions */ -#define TCN1_ADDR TCN_ADDR -#define TCN1 TCN - -/* - * Timer Status Register - */ -#define TSTAT_ADDR 0xfffff60a -#define TSTAT WORD_REF(TSTAT_ADDR) - -#define TSTAT_COMP 0x0001 /* Compare Event occurred */ -#define TSTAT_CAPT 0x0001 /* Capture Event occurred */ - -/* '328-compatible definitions */ -#define TSTAT1_ADDR TSTAT_ADDR -#define TSTAT1 TSTAT - -/********** - * - * 0xFFFFF8xx -- Serial Periferial Interface Master (SPIM) - * - **********/ - -/* - * SPIM Data Register - */ -#define SPIMDATA_ADDR 0xfffff800 -#define SPIMDATA WORD_REF(SPIMDATA_ADDR) - -/* - * SPIM Control/Status Register - */ -#define SPIMCONT_ADDR 0xfffff802 -#define SPIMCONT WORD_REF(SPIMCONT_ADDR) - -#define SPIMCONT_BIT_COUNT_MASK 0x000f /* Transfer Length in Bytes */ -#define SPIMCONT_BIT_COUNT_SHIFT 0 -#define SPIMCONT_POL 0x0010 /* SPMCLK Signel Polarity */ -#define SPIMCONT_PHA 0x0020 /* Clock/Data phase relationship */ -#define SPIMCONT_IRQEN 0x0040 /* IRQ Enable */ -#define SPIMCONT_IRQ 0x0080 /* Interrupt Request */ -#define SPIMCONT_XCH 0x0100 /* Exchange */ -#define SPIMCONT_ENABLE 0x0200 /* Enable SPIM */ -#define SPIMCONT_DATA_RATE_MASK 0xe000 /* SPIM Data Rate */ -#define SPIMCONT_DATA_RATE_SHIFT 13 - -/* '328-compatible definitions */ -#define SPIMCONT_SPIMIRQ SPIMCONT_IRQ -#define SPIMCONT_SPIMEN SPIMCONT_ENABLE - -/********** - * - * 0xFFFFF9xx -- UART - * - **********/ - -/* - * UART Status/Control Register - */ - -#define USTCNT_ADDR 0xfffff900 -#define USTCNT WORD_REF(USTCNT_ADDR) - -#define USTCNT_TXAE 0x0001 /* Transmitter Available Interrupt Enable */ -#define USTCNT_TXHE 0x0002 /* Transmitter Half Empty Enable */ -#define USTCNT_TXEE 0x0004 /* Transmitter Empty Interrupt Enable */ -#define USTCNT_RXRE 0x0008 /* Receiver Ready Interrupt Enable */ -#define USTCNT_RXHE 0x0010 /* Receiver Half-Full Interrupt Enable */ -#define USTCNT_RXFE 0x0020 /* Receiver Full Interrupt Enable */ -#define USTCNT_CTSD 0x0040 /* CTS Delta Interrupt Enable */ -#define USTCNT_ODEN 0x0080 /* Old Data Interrupt Enable */ -#define USTCNT_8_7 0x0100 /* Eight or seven-bit transmission */ -#define USTCNT_STOP 0x0200 /* Stop bit transmission */ -#define USTCNT_ODD 0x0400 /* Odd Parity */ -#define USTCNT_PEN 0x0800 /* Parity Enable */ -#define USTCNT_CLKM 0x1000 /* Clock Mode Select */ -#define USTCNT_TXEN 0x2000 /* Transmitter Enable */ -#define USTCNT_RXEN 0x4000 /* Receiver Enable */ -#define USTCNT_UEN 0x8000 /* UART Enable */ - -/* '328-compatible definitions */ -#define USTCNT_TXAVAILEN USTCNT_TXAE -#define USTCNT_TXHALFEN USTCNT_TXHE -#define USTCNT_TXEMPTYEN USTCNT_TXEE -#define USTCNT_RXREADYEN USTCNT_RXRE -#define USTCNT_RXHALFEN USTCNT_RXHE -#define USTCNT_RXFULLEN USTCNT_RXFE -#define USTCNT_CTSDELTAEN USTCNT_CTSD -#define USTCNT_ODD_EVEN USTCNT_ODD -#define USTCNT_PARITYEN USTCNT_PEN -#define USTCNT_CLKMODE USTCNT_CLKM -#define USTCNT_UARTEN USTCNT_UEN - -/* - * UART Baud Control Register - */ -#define UBAUD_ADDR 0xfffff902 -#define UBAUD WORD_REF(UBAUD_ADDR) - -#define UBAUD_PRESCALER_MASK 0x003f /* Actual divisor is 65 - PRESCALER */ -#define UBAUD_PRESCALER_SHIFT 0 -#define UBAUD_DIVIDE_MASK 0x0700 /* Baud Rate freq. divizor */ -#define UBAUD_DIVIDE_SHIFT 8 -#define UBAUD_BAUD_SRC 0x0800 /* Baud Rate Source */ -#define UBAUD_UCLKDIR 0x2000 /* UCLK Direction */ - -/* - * UART Receiver Register - */ -#define URX_ADDR 0xfffff904 -#define URX WORD_REF(URX_ADDR) - -#define URX_RXDATA_ADDR 0xfffff905 -#define URX_RXDATA BYTE_REF(URX_RXDATA_ADDR) - -#define URX_RXDATA_MASK 0x00ff /* Received data */ -#define URX_RXDATA_SHIFT 0 -#define URX_PARITY_ERROR 0x0100 /* Parity Error */ -#define URX_BREAK 0x0200 /* Break Detected */ -#define URX_FRAME_ERROR 0x0400 /* Framing Error */ -#define URX_OVRUN 0x0800 /* Serial Overrun */ -#define URX_OLD_DATA 0x1000 /* Old data in FIFO */ -#define URX_DATA_READY 0x2000 /* Data Ready (FIFO not empty) */ -#define URX_FIFO_HALF 0x4000 /* FIFO is Half-Full */ -#define URX_FIFO_FULL 0x8000 /* FIFO is Full */ - -/* - * UART Transmitter Register - */ -#define UTX_ADDR 0xfffff906 -#define UTX WORD_REF(UTX_ADDR) - -#define UTX_TXDATA_ADDR 0xfffff907 -#define UTX_TXDATA BYTE_REF(UTX_TXDATA_ADDR) - -#define UTX_TXDATA_MASK 0x00ff /* Data to be transmitted */ -#define UTX_TXDATA_SHIFT 0 -#define UTX_CTS_DELTA 0x0100 /* CTS changed */ -#define UTX_CTS_STAT 0x0200 /* CTS State */ -#define UTX_BUSY 0x0400 /* FIFO is busy, sending a character */ -#define UTX_NOCTS 0x0800 /* Ignore CTS */ -#define UTX_SEND_BREAK 0x1000 /* Send a BREAK */ -#define UTX_TX_AVAIL 0x2000 /* Transmit FIFO has a slot available */ -#define UTX_FIFO_HALF 0x4000 /* Transmit FIFO is half empty */ -#define UTX_FIFO_EMPTY 0x8000 /* Transmit FIFO is empty */ - -/* '328-compatible definitions */ -#define UTX_CTS_STATUS UTX_CTS_STAT -#define UTX_IGNORE_CTS UTX_NOCTS - -/* - * UART Miscellaneous Register - */ -#define UMISC_ADDR 0xfffff908 -#define UMISC WORD_REF(UMISC_ADDR) - -#define UMISC_TX_POL 0x0004 /* Transmit Polarity */ -#define UMISC_RX_POL 0x0008 /* Receive Polarity */ -#define UMISC_IRDA_LOOP 0x0010 /* IrDA Loopback Enable */ -#define UMISC_IRDA_EN 0x0020 /* Infra-Red Enable */ -#define UMISC_RTS 0x0040 /* Set RTS status */ -#define UMISC_RTSCONT 0x0080 /* Choose RTS control */ -#define UMISC_IR_TEST 0x0400 /* IRDA Test Enable */ -#define UMISC_BAUD_RESET 0x0800 /* Reset Baud Rate Generation Counters */ -#define UMISC_LOOP 0x1000 /* Serial Loopback Enable */ -#define UMISC_FORCE_PERR 0x2000 /* Force Parity Error */ -#define UMISC_CLKSRC 0x4000 /* Clock Source */ -#define UMISC_BAUD_TEST 0x8000 /* Enable Baud Test Mode */ - -/* - * UART Non-integer Prescaler Register - */ -#define NIPR_ADDR 0xfffff90a -#define NIPR WORD_REF(NIPR_ADDR) - -#define NIPR_STEP_VALUE_MASK 0x00ff /* NI prescaler step value */ -#define NIPR_STEP_VALUE_SHIFT 0 -#define NIPR_SELECT_MASK 0x0700 /* Tap Selection */ -#define NIPR_SELECT_SHIFT 8 -#define NIPR_PRE_SEL 0x8000 /* Non-integer prescaler select */ - - -/* generalization of uart control registers to support multiple ports: */ -typedef struct { - volatile unsigned short int ustcnt; - volatile unsigned short int ubaud; - union { - volatile unsigned short int w; - struct { - volatile unsigned char status; - volatile unsigned char rxdata; - } b; - } urx; - union { - volatile unsigned short int w; - struct { - volatile unsigned char status; - volatile unsigned char txdata; - } b; - } utx; - volatile unsigned short int umisc; - volatile unsigned short int nipr; - volatile unsigned short int hmark; - volatile unsigned short int unused; -} __attribute__((packed)) m68328_uart; - - - - -/********** - * - * 0xFFFFFAxx -- LCD Controller - * - **********/ - -/* - * LCD Screen Starting Address Register - */ -#define LSSA_ADDR 0xfffffa00 -#define LSSA LONG_REF(LSSA_ADDR) - -#define LSSA_SSA_MASK 0x1ffffffe /* Bits 0 and 29-31 are reserved */ - -/* - * LCD Virtual Page Width Register - */ -#define LVPW_ADDR 0xfffffa05 -#define LVPW BYTE_REF(LVPW_ADDR) - -/* - * LCD Screen Width Register (not compatible with '328 !!!) - */ -#define LXMAX_ADDR 0xfffffa08 -#define LXMAX WORD_REF(LXMAX_ADDR) - -#define LXMAX_XM_MASK 0x02f0 /* Bits 0-3 and 10-15 are reserved */ - -/* - * LCD Screen Height Register - */ -#define LYMAX_ADDR 0xfffffa0a -#define LYMAX WORD_REF(LYMAX_ADDR) - -#define LYMAX_YM_MASK 0x01ff /* Bits 9-15 are reserved */ - -/* - * LCD Cursor X Position Register - */ -#define LCXP_ADDR 0xfffffa18 -#define LCXP WORD_REF(LCXP_ADDR) - -#define LCXP_CC_MASK 0xc000 /* Cursor Control */ -#define LCXP_CC_TRAMSPARENT 0x0000 -#define LCXP_CC_BLACK 0x4000 -#define LCXP_CC_REVERSED 0x8000 -#define LCXP_CC_WHITE 0xc000 -#define LCXP_CXP_MASK 0x02ff /* Cursor X position */ - -/* - * LCD Cursor Y Position Register - */ -#define LCYP_ADDR 0xfffffa1a -#define LCYP WORD_REF(LCYP_ADDR) - -#define LCYP_CYP_MASK 0x01ff /* Cursor Y Position */ - -/* - * LCD Cursor Width and Heigth Register - */ -#define LCWCH_ADDR 0xfffffa1c -#define LCWCH WORD_REF(LCWCH_ADDR) - -#define LCWCH_CH_MASK 0x001f /* Cursor Height */ -#define LCWCH_CH_SHIFT 0 -#define LCWCH_CW_MASK 0x1f00 /* Cursor Width */ -#define LCWCH_CW_SHIFT 8 - -/* - * LCD Blink Control Register - */ -#define LBLKC_ADDR 0xfffffa1f -#define LBLKC BYTE_REF(LBLKC_ADDR) - -#define LBLKC_BD_MASK 0x7f /* Blink Divisor */ -#define LBLKC_BD_SHIFT 0 -#define LBLKC_BKEN 0x80 /* Blink Enabled */ - -/* - * LCD Panel Interface Configuration Register - */ -#define LPICF_ADDR 0xfffffa20 -#define LPICF BYTE_REF(LPICF_ADDR) - -#define LPICF_GS_MASK 0x03 /* Gray-Scale Mode */ -#define LPICF_GS_BW 0x00 -#define LPICF_GS_GRAY_4 0x01 -#define LPICF_GS_GRAY_16 0x02 -#define LPICF_PBSIZ_MASK 0x0c /* Panel Bus Width */ -#define LPICF_PBSIZ_1 0x00 -#define LPICF_PBSIZ_2 0x04 -#define LPICF_PBSIZ_4 0x08 - -/* - * LCD Polarity Configuration Register - */ -#define LPOLCF_ADDR 0xfffffa21 -#define LPOLCF BYTE_REF(LPOLCF_ADDR) - -#define LPOLCF_PIXPOL 0x01 /* Pixel Polarity */ -#define LPOLCF_LPPOL 0x02 /* Line Pulse Polarity */ -#define LPOLCF_FLMPOL 0x04 /* Frame Marker Polarity */ -#define LPOLCF_LCKPOL 0x08 /* LCD Shift Lock Polarity */ - -/* - * LACD (LCD Alternate Crystal Direction) Rate Control Register - */ -#define LACDRC_ADDR 0xfffffa23 -#define LACDRC BYTE_REF(LACDRC_ADDR) - -#define LACDRC_ACDSLT 0x80 /* Signal Source Select */ -#define LACDRC_ACD_MASK 0x0f /* Alternate Crystal Direction Control */ -#define LACDRC_ACD_SHIFT 0 - -/* - * LCD Pixel Clock Divider Register - */ -#define LPXCD_ADDR 0xfffffa25 -#define LPXCD BYTE_REF(LPXCD_ADDR) - -#define LPXCD_PCD_MASK 0x3f /* Pixel Clock Divider */ -#define LPXCD_PCD_SHIFT 0 - -/* - * LCD Clocking Control Register - */ -#define LCKCON_ADDR 0xfffffa27 -#define LCKCON BYTE_REF(LCKCON_ADDR) - -#define LCKCON_DWS_MASK 0x0f /* Display Wait-State */ -#define LCKCON_DWS_SHIFT 0 -#define LCKCON_DWIDTH 0x40 /* Display Memory Width */ -#define LCKCON_LCDON 0x80 /* Enable LCD Controller */ - -/* '328-compatible definitions */ -#define LCKCON_DW_MASK LCKCON_DWS_MASK -#define LCKCON_DW_SHIFT LCKCON_DWS_SHIFT - -/* - * LCD Refresh Rate Adjustment Register - */ -#define LRRA_ADDR 0xfffffa29 -#define LRRA BYTE_REF(LRRA_ADDR) - -/* - * LCD Panning Offset Register - */ -#define LPOSR_ADDR 0xfffffa2d -#define LPOSR BYTE_REF(LPOSR_ADDR) - -#define LPOSR_POS_MASK 0x0f /* Pixel Offset Code */ -#define LPOSR_POS_SHIFT 0 - -/* - * LCD Frame Rate Control Modulation Register - */ -#define LFRCM_ADDR 0xfffffa31 -#define LFRCM BYTE_REF(LFRCM_ADDR) - -#define LFRCM_YMOD_MASK 0x0f /* Vertical Modulation */ -#define LFRCM_YMOD_SHIFT 0 -#define LFRCM_XMOD_MASK 0xf0 /* Horizontal Modulation */ -#define LFRCM_XMOD_SHIFT 4 - -/* - * LCD Gray Palette Mapping Register - */ -#define LGPMR_ADDR 0xfffffa33 -#define LGPMR BYTE_REF(LGPMR_ADDR) - -#define LGPMR_G1_MASK 0x0f -#define LGPMR_G1_SHIFT 0 -#define LGPMR_G2_MASK 0xf0 -#define LGPMR_G2_SHIFT 4 - -/* - * PWM Contrast Control Register - */ -#define PWMR_ADDR 0xfffffa36 -#define PWMR WORD_REF(PWMR_ADDR) - -#define PWMR_PW_MASK 0x00ff /* Pulse Width */ -#define PWMR_PW_SHIFT 0 -#define PWMR_CCPEN 0x0100 /* Contrast Control Enable */ -#define PWMR_SRC_MASK 0x0600 /* Input Clock Source */ -#define PWMR_SRC_LINE 0x0000 /* Line Pulse */ -#define PWMR_SRC_PIXEL 0x0200 /* Pixel Clock */ -#define PWMR_SRC_LCD 0x4000 /* LCD clock */ - -/********** - * - * 0xFFFFFBxx -- Real-Time Clock (RTC) - * - **********/ - -/* - * RTC Hours Minutes and Seconds Register - */ -#define RTCTIME_ADDR 0xfffffb00 -#define RTCTIME LONG_REF(RTCTIME_ADDR) - -#define RTCTIME_SECONDS_MASK 0x0000003f /* Seconds */ -#define RTCTIME_SECONDS_SHIFT 0 -#define RTCTIME_MINUTES_MASK 0x003f0000 /* Minutes */ -#define RTCTIME_MINUTES_SHIFT 16 -#define RTCTIME_HOURS_MASK 0x1f000000 /* Hours */ -#define RTCTIME_HOURS_SHIFT 24 - -/* - * RTC Alarm Register - */ -#define RTCALRM_ADDR 0xfffffb04 -#define RTCALRM LONG_REF(RTCALRM_ADDR) - -#define RTCALRM_SECONDS_MASK 0x0000003f /* Seconds */ -#define RTCALRM_SECONDS_SHIFT 0 -#define RTCALRM_MINUTES_MASK 0x003f0000 /* Minutes */ -#define RTCALRM_MINUTES_SHIFT 16 -#define RTCALRM_HOURS_MASK 0x1f000000 /* Hours */ -#define RTCALRM_HOURS_SHIFT 24 - -/* - * Watchdog Timer Register - */ -#define WATCHDOG_ADDR 0xfffffb0a -#define WATCHDOG WORD_REF(WATCHDOG_ADDR) - -#define WATCHDOG_EN 0x0001 /* Watchdog Enabled */ -#define WATCHDOG_ISEL 0x0002 /* Select the watchdog interrupt */ -#define WATCHDOG_INTF 0x0080 /* Watchdog interrupt occcured */ -#define WATCHDOG_CNT_MASK 0x0300 /* Watchdog Counter */ -#define WATCHDOG_CNT_SHIFT 8 - -/* - * RTC Control Register - */ -#define RTCCTL_ADDR 0xfffffb0c -#define RTCCTL WORD_REF(RTCCTL_ADDR) - -#define RTCCTL_XTL 0x0020 /* Crystal Selection */ -#define RTCCTL_EN 0x0080 /* RTC Enable */ - -/* '328-compatible definitions */ -#define RTCCTL_384 RTCCTL_XTL -#define RTCCTL_ENABLE RTCCTL_EN - -/* - * RTC Interrupt Status Register - */ -#define RTCISR_ADDR 0xfffffb0e -#define RTCISR WORD_REF(RTCISR_ADDR) - -#define RTCISR_SW 0x0001 /* Stopwatch timed out */ -#define RTCISR_MIN 0x0002 /* 1-minute interrupt has occurred */ -#define RTCISR_ALM 0x0004 /* Alarm interrupt has occurred */ -#define RTCISR_DAY 0x0008 /* 24-hour rollover interrupt has occurred */ -#define RTCISR_1HZ 0x0010 /* 1Hz interrupt has occurred */ -#define RTCISR_HR 0x0020 /* 1-hour interrupt has occurred */ -#define RTCISR_SAM0 0x0100 /* 4Hz / 4.6875Hz interrupt has occurred */ -#define RTCISR_SAM1 0x0200 /* 8Hz / 9.3750Hz interrupt has occurred */ -#define RTCISR_SAM2 0x0400 /* 16Hz / 18.7500Hz interrupt has occurred */ -#define RTCISR_SAM3 0x0800 /* 32Hz / 37.5000Hz interrupt has occurred */ -#define RTCISR_SAM4 0x1000 /* 64Hz / 75.0000Hz interrupt has occurred */ -#define RTCISR_SAM5 0x2000 /* 128Hz / 150.0000Hz interrupt has occurred */ -#define RTCISR_SAM6 0x4000 /* 256Hz / 300.0000Hz interrupt has occurred */ -#define RTCISR_SAM7 0x8000 /* 512Hz / 600.0000Hz interrupt has occurred */ - -/* - * RTC Interrupt Enable Register - */ -#define RTCIENR_ADDR 0xfffffb10 -#define RTCIENR WORD_REF(RTCIENR_ADDR) - -#define RTCIENR_SW 0x0001 /* Stopwatch interrupt enable */ -#define RTCIENR_MIN 0x0002 /* 1-minute interrupt enable */ -#define RTCIENR_ALM 0x0004 /* Alarm interrupt enable */ -#define RTCIENR_DAY 0x0008 /* 24-hour rollover interrupt enable */ -#define RTCIENR_1HZ 0x0010 /* 1Hz interrupt enable */ -#define RTCIENR_HR 0x0020 /* 1-hour interrupt enable */ -#define RTCIENR_SAM0 0x0100 /* 4Hz / 4.6875Hz interrupt enable */ -#define RTCIENR_SAM1 0x0200 /* 8Hz / 9.3750Hz interrupt enable */ -#define RTCIENR_SAM2 0x0400 /* 16Hz / 18.7500Hz interrupt enable */ -#define RTCIENR_SAM3 0x0800 /* 32Hz / 37.5000Hz interrupt enable */ -#define RTCIENR_SAM4 0x1000 /* 64Hz / 75.0000Hz interrupt enable */ -#define RTCIENR_SAM5 0x2000 /* 128Hz / 150.0000Hz interrupt enable */ -#define RTCIENR_SAM6 0x4000 /* 256Hz / 300.0000Hz interrupt enable */ -#define RTCIENR_SAM7 0x8000 /* 512Hz / 600.0000Hz interrupt enable */ - -/* - * Stopwatch Minutes Register - */ -#define STPWCH_ADDR 0xfffffb12 -#define STPWCH WORD_REF(STPWCH_ADDR) - -#define STPWCH_CNT_MASK 0x003f /* Stopwatch countdown value */ -#define SPTWCH_CNT_SHIFT 0 - -/* - * RTC Day Count Register - */ -#define DAYR_ADDR 0xfffffb1a -#define DAYR WORD_REF(DAYR_ADDR) - -#define DAYR_DAYS_MASK 0x1ff /* Day Setting */ -#define DAYR_DAYS_SHIFT 0 - -/* - * RTC Day Alarm Register - */ -#define DAYALARM_ADDR 0xfffffb1c -#define DAYALARM WORD_REF(DAYALARM_ADDR) - -#define DAYALARM_DAYSAL_MASK 0x01ff /* Day Setting of the Alarm */ -#define DAYALARM_DAYSAL_SHIFT 0 - -/********** - * - * 0xFFFFFCxx -- DRAM Controller - * - **********/ - -/* - * DRAM Memory Configuration Register - */ -#define DRAMMC_ADDR 0xfffffc00 -#define DRAMMC WORD_REF(DRAMMC_ADDR) - -#define DRAMMC_ROW12_MASK 0xc000 /* Row address bit for MD12 */ -#define DRAMMC_ROW12_PA10 0x0000 -#define DRAMMC_ROW12_PA21 0x4000 -#define DRAMMC_ROW12_PA23 0x8000 -#define DRAMMC_ROW0_MASK 0x3000 /* Row address bit for MD0 */ -#define DRAMMC_ROW0_PA11 0x0000 -#define DRAMMC_ROW0_PA22 0x1000 -#define DRAMMC_ROW0_PA23 0x2000 -#define DRAMMC_ROW11 0x0800 /* Row address bit for MD11 PA20/PA22 */ -#define DRAMMC_ROW10 0x0400 /* Row address bit for MD10 PA19/PA21 */ -#define DRAMMC_ROW9 0x0200 /* Row address bit for MD9 PA9/PA19 */ -#define DRAMMC_ROW8 0x0100 /* Row address bit for MD8 PA10/PA20 */ -#define DRAMMC_COL10 0x0080 /* Col address bit for MD10 PA11/PA0 */ -#define DRAMMC_COL9 0x0040 /* Col address bit for MD9 PA10/PA0 */ -#define DRAMMC_COL8 0x0020 /* Col address bit for MD8 PA9/PA0 */ -#define DRAMMC_REF_MASK 0x001f /* Reresh Cycle */ -#define DRAMMC_REF_SHIFT 0 - -/* - * DRAM Control Register - */ -#define DRAMC_ADDR 0xfffffc02 -#define DRAMC WORD_REF(DRAMC_ADDR) - -#define DRAMC_DWE 0x0001 /* DRAM Write Enable */ -#define DRAMC_RST 0x0002 /* Reset Burst Refresh Enable */ -#define DRAMC_LPR 0x0004 /* Low-Power Refresh Enable */ -#define DRAMC_SLW 0x0008 /* Slow RAM */ -#define DRAMC_LSP 0x0010 /* Light Sleep */ -#define DRAMC_MSW 0x0020 /* Slow Multiplexing */ -#define DRAMC_WS_MASK 0x00c0 /* Wait-states */ -#define DRAMC_WS_SHIFT 6 -#define DRAMC_PGSZ_MASK 0x0300 /* Page Size for fast page mode */ -#define DRAMC_PGSZ_SHIFT 8 -#define DRAMC_PGSZ_256K 0x0000 -#define DRAMC_PGSZ_512K 0x0100 -#define DRAMC_PGSZ_1024K 0x0200 -#define DRAMC_PGSZ_2048K 0x0300 -#define DRAMC_EDO 0x0400 /* EDO DRAM */ -#define DRAMC_CLK 0x0800 /* Refresh Timer Clock source select */ -#define DRAMC_BC_MASK 0x3000 /* Page Access Clock Cycle (FP mode) */ -#define DRAMC_BC_SHIFT 12 -#define DRAMC_RM 0x4000 /* Refresh Mode */ -#define DRAMC_EN 0x8000 /* DRAM Controller enable */ - - -/********** - * - * 0xFFFFFDxx -- In-Circuit Emulation (ICE) - * - **********/ - -/* - * ICE Module Address Compare Register - */ -#define ICEMACR_ADDR 0xfffffd00 -#define ICEMACR LONG_REF(ICEMACR_ADDR) - -/* - * ICE Module Address Mask Register - */ -#define ICEMAMR_ADDR 0xfffffd04 -#define ICEMAMR LONG_REF(ICEMAMR_ADDR) - -/* - * ICE Module Control Compare Register - */ -#define ICEMCCR_ADDR 0xfffffd08 -#define ICEMCCR WORD_REF(ICEMCCR_ADDR) - -#define ICEMCCR_PD 0x0001 /* Program/Data Cycle Selection */ -#define ICEMCCR_RW 0x0002 /* Read/Write Cycle Selection */ - -/* - * ICE Module Control Mask Register - */ -#define ICEMCMR_ADDR 0xfffffd0a -#define ICEMCMR WORD_REF(ICEMCMR_ADDR) - -#define ICEMCMR_PDM 0x0001 /* Program/Data Cycle Mask */ -#define ICEMCMR_RWM 0x0002 /* Read/Write Cycle Mask */ - -/* - * ICE Module Control Register - */ -#define ICEMCR_ADDR 0xfffffd0c -#define ICEMCR WORD_REF(ICEMCR_ADDR) - -#define ICEMCR_CEN 0x0001 /* Compare Enable */ -#define ICEMCR_PBEN 0x0002 /* Program Break Enable */ -#define ICEMCR_SB 0x0004 /* Single Breakpoint */ -#define ICEMCR_HMDIS 0x0008 /* HardMap disable */ -#define ICEMCR_BBIEN 0x0010 /* Bus Break Interrupt Enable */ - -/* - * ICE Module Status Register - */ -#define ICEMSR_ADDR 0xfffffd0e -#define ICEMSR WORD_REF(ICEMSR_ADDR) - -#define ICEMSR_EMUEN 0x0001 /* Emulation Enable */ -#define ICEMSR_BRKIRQ 0x0002 /* A-Line Vector Fetch Detected */ -#define ICEMSR_BBIRQ 0x0004 /* Bus Break Interrupt Detected */ -#define ICEMSR_EMIRQ 0x0008 /* EMUIRQ Falling Edge Detected */ - -#endif /* _MC68VZ328_H_ */ diff --git a/arch/m68knommu/include/asm/anchor.h b/arch/m68knommu/include/asm/anchor.h deleted file mode 100644 index 871c0d5cfc3..00000000000 --- a/arch/m68knommu/include/asm/anchor.h +++ /dev/null @@ -1,112 +0,0 @@ -/****************************************************************************/ - -/* - * anchor.h -- Anchor CO-MEM Lite PCI host bridge part. - * - * (C) Copyright 2000, Moreton Bay (www.moreton.com.au) - */ - -/****************************************************************************/ -#ifndef anchor_h -#define anchor_h -/****************************************************************************/ - -/* - * Define basic addressing info. - */ -#if defined(CONFIG_M5407C3) -#define COMEM_BASE 0xFFFF0000 /* Base of CO-MEM address space */ -#define COMEM_IRQ 25 /* IRQ of anchor part */ -#else -#define COMEM_BASE 0x80000000 /* Base of CO-MEM address space */ -#define COMEM_IRQ 25 /* IRQ of anchor part */ -#endif - -/****************************************************************************/ - -/* - * 4-byte registers of CO-MEM, so adjust register addresses for - * easy access. Handy macro for word access too. - */ -#define LREG(a) ((a) >> 2) -#define WREG(a) ((a) >> 1) - - -/* - * Define base addresses within CO-MEM Lite register address space. - */ -#define COMEM_I2O 0x0000 /* I2O registers */ -#define COMEM_OPREGS 0x0400 /* Operation registers */ -#define COMEM_PCIBUS 0x2000 /* Direct access to PCI bus */ -#define COMEM_SHMEM 0x4000 /* Shared memory region */ - -#define COMEM_SHMEMSIZE 0x4000 /* Size of shared memory */ - - -/* - * Define CO-MEM Registers. - */ -#define COMEM_I2OHISR 0x0030 /* I2O host interrupt status */ -#define COMEM_I2OHIMR 0x0034 /* I2O host interrupt mask */ -#define COMEM_I2OLISR 0x0038 /* I2O local interrupt status */ -#define COMEM_I2OLIMR 0x003c /* I2O local interrupt mask */ -#define COMEM_IBFPFIFO 0x0040 /* I2O inbound free/post FIFO */ -#define COMEM_OBPFFIFO 0x0044 /* I2O outbound post/free FIFO */ -#define COMEM_IBPFFIFO 0x0048 /* I2O inbound post/free FIFO */ -#define COMEM_OBFPFIFO 0x004c /* I2O outbound free/post FIFO */ - -#define COMEM_DAHBASE 0x0460 /* Direct access base address */ - -#define COMEM_NVCMD 0x04a0 /* I2C serial command */ -#define COMEM_NVREAD 0x04a4 /* I2C serial read */ -#define COMEM_NVSTAT 0x04a8 /* I2C status */ - -#define COMEM_DMALBASE 0x04b0 /* DMA local base address */ -#define COMEM_DMAHBASE 0x04b4 /* DMA host base address */ -#define COMEM_DMASIZE 0x04b8 /* DMA size */ -#define COMEM_DMACTL 0x04bc /* DMA control */ - -#define COMEM_HCTL 0x04e0 /* Host control */ -#define COMEM_HINT 0x04e4 /* Host interrupt control/status */ -#define COMEM_HLDATA 0x04e8 /* Host to local data mailbox */ -#define COMEM_LINT 0x04f4 /* Local interrupt contole status */ -#define COMEM_LHDATA 0x04f8 /* Local to host data mailbox */ - -#define COMEM_LBUSCFG 0x04fc /* Local bus configuration */ - - -/* - * Commands and flags for use with Direct Access Register. - */ -#define COMEM_DA_IACK 0x00000000 /* Interrupt acknowledge (read) */ -#define COMEM_DA_SPCL 0x00000010 /* Special cycle (write) */ -#define COMEM_DA_MEMRD 0x00000004 /* Memory read cycle */ -#define COMEM_DA_MEMWR 0x00000004 /* Memory write cycle */ -#define COMEM_DA_IORD 0x00000002 /* I/O read cycle */ -#define COMEM_DA_IOWR 0x00000002 /* I/O write cycle */ -#define COMEM_DA_CFGRD 0x00000006 /* Configuration read cycle */ -#define COMEM_DA_CFGWR 0x00000006 /* Configuration write cycle */ - -#define COMEM_DA_ADDR(a) ((a) & 0xffffe000) - -#define COMEM_DA_OFFSET(a) ((a) & 0x00001fff) - - -/* - * The PCI bus will be limited in what slots will actually be used. - * Define valid device numbers for different boards. - */ -#if defined(CONFIG_M5407C3) -#define COMEM_MINDEV 14 /* Minimum valid DEVICE */ -#define COMEM_MAXDEV 14 /* Maximum valid DEVICE */ -#define COMEM_BRIDGEDEV 15 /* Slot bridge is in */ -#else -#define COMEM_MINDEV 0 /* Minimum valid DEVICE */ -#define COMEM_MAXDEV 3 /* Maximum valid DEVICE */ -#endif - -#define COMEM_MAXPCI (COMEM_MAXDEV+1) /* Maximum PCI devices */ - - -/****************************************************************************/ -#endif /* anchor_h */ diff --git a/arch/m68knommu/include/asm/atomic.h b/arch/m68knommu/include/asm/atomic.h deleted file mode 100644 index 6bb674855a3..00000000000 --- a/arch/m68knommu/include/asm/atomic.h +++ /dev/null @@ -1,155 +0,0 @@ -#ifndef __ARCH_M68KNOMMU_ATOMIC__ -#define __ARCH_M68KNOMMU_ATOMIC__ - -#include -#include - -/* - * Atomic operations that C can't guarantee us. Useful for - * resource counting etc.. - */ - -/* - * We do not have SMP m68k systems, so we don't have to deal with that. - */ - -#define ATOMIC_INIT(i) { (i) } - -#define atomic_read(v) ((v)->counter) -#define atomic_set(v, i) (((v)->counter) = i) - -static __inline__ void atomic_add(int i, atomic_t *v) -{ -#ifdef CONFIG_COLDFIRE - __asm__ __volatile__("addl %1,%0" : "+m" (*v) : "d" (i)); -#else - __asm__ __volatile__("addl %1,%0" : "+m" (*v) : "di" (i)); -#endif -} - -static __inline__ void atomic_sub(int i, atomic_t *v) -{ -#ifdef CONFIG_COLDFIRE - __asm__ __volatile__("subl %1,%0" : "+m" (*v) : "d" (i)); -#else - __asm__ __volatile__("subl %1,%0" : "+m" (*v) : "di" (i)); -#endif -} - -static __inline__ int atomic_sub_and_test(int i, atomic_t * v) -{ - char c; -#ifdef CONFIG_COLDFIRE - __asm__ __volatile__("subl %2,%1; seq %0" - : "=d" (c), "+m" (*v) - : "d" (i)); -#else - __asm__ __volatile__("subl %2,%1; seq %0" - : "=d" (c), "+m" (*v) - : "di" (i)); -#endif - return c != 0; -} - -static __inline__ void atomic_inc(volatile atomic_t *v) -{ - __asm__ __volatile__("addql #1,%0" : "+m" (*v)); -} - -/* - * atomic_inc_and_test - increment and test - * @v: pointer of type atomic_t - * - * Atomically increments @v by 1 - * and returns true if the result is zero, or false for all - * other cases. - */ - -static __inline__ int atomic_inc_and_test(volatile atomic_t *v) -{ - char c; - __asm__ __volatile__("addql #1,%1; seq %0" : "=d" (c), "+m" (*v)); - return c != 0; -} - -static __inline__ void atomic_dec(volatile atomic_t *v) -{ - __asm__ __volatile__("subql #1,%0" : "+m" (*v)); -} - -static __inline__ int atomic_dec_and_test(volatile atomic_t *v) -{ - char c; - __asm__ __volatile__("subql #1,%1; seq %0" : "=d" (c), "+m" (*v)); - return c != 0; -} - -static __inline__ void atomic_clear_mask(unsigned long mask, unsigned long *v) -{ - __asm__ __volatile__("andl %1,%0" : "+m" (*v) : "id" (~(mask))); -} - -static __inline__ void atomic_set_mask(unsigned long mask, unsigned long *v) -{ - __asm__ __volatile__("orl %1,%0" : "+m" (*v) : "id" (mask)); -} - -/* Atomic operations are already serializing */ -#define smp_mb__before_atomic_dec() barrier() -#define smp_mb__after_atomic_dec() barrier() -#define smp_mb__before_atomic_inc() barrier() -#define smp_mb__after_atomic_inc() barrier() - -static inline int atomic_add_return(int i, atomic_t * v) -{ - unsigned long temp, flags; - - local_irq_save(flags); - temp = *(long *)v; - temp += i; - *(long *)v = temp; - local_irq_restore(flags); - - return temp; -} - -#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) - -static inline int atomic_sub_return(int i, atomic_t * v) -{ - unsigned long temp, flags; - - local_irq_save(flags); - temp = *(long *)v; - temp -= i; - *(long *)v = temp; - local_irq_restore(flags); - - return temp; -} - -#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) -#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) - -static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) -{ - int c, old; - c = atomic_read(v); - for (;;) { - if (unlikely(c == (u))) - break; - old = atomic_cmpxchg((v), c, c + (a)); - if (likely(old == c)) - break; - c = old; - } - return c != (u); -} - -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) - -#define atomic_dec_return(v) atomic_sub_return(1,(v)) -#define atomic_inc_return(v) atomic_add_return(1,(v)) - -#include -#endif /* __ARCH_M68KNOMMU_ATOMIC __ */ diff --git a/arch/m68knommu/include/asm/auxvec.h b/arch/m68knommu/include/asm/auxvec.h deleted file mode 100644 index 844d6d52204..00000000000 --- a/arch/m68knommu/include/asm/auxvec.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef __ASMm68k_AUXVEC_H -#define __ASMm68k_AUXVEC_H - -#endif diff --git a/arch/m68knommu/include/asm/bitops.h b/arch/m68knommu/include/asm/bitops.h deleted file mode 100644 index 9d3cbe5fad1..00000000000 --- a/arch/m68knommu/include/asm/bitops.h +++ /dev/null @@ -1,337 +0,0 @@ -#ifndef _M68KNOMMU_BITOPS_H -#define _M68KNOMMU_BITOPS_H - -/* - * Copyright 1992, Linus Torvalds. - */ - -#include -#include /* swab32 */ - -#ifdef __KERNEL__ - -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - -#if defined (__mcfisaaplus__) || defined (__mcfisac__) -static inline int ffs(unsigned int val) -{ - if (!val) - return 0; - - asm volatile( - "bitrev %0\n\t" - "ff1 %0\n\t" - : "=d" (val) - : "0" (val) - ); - val++; - return val; -} - -static inline int __ffs(unsigned int val) -{ - asm volatile( - "bitrev %0\n\t" - "ff1 %0\n\t" - : "=d" (val) - : "0" (val) - ); - return val; -} - -#else -#include -#include -#endif - -#include -#include - -static __inline__ void set_bit(int nr, volatile unsigned long * addr) -{ -#ifdef CONFIG_COLDFIRE - __asm__ __volatile__ ("lea %0,%%a0; bset %1,(%%a0)" - : "+m" (((volatile char *)addr)[(nr^31) >> 3]) - : "d" (nr) - : "%a0", "cc"); -#else - __asm__ __volatile__ ("bset %1,%0" - : "+m" (((volatile char *)addr)[(nr^31) >> 3]) - : "di" (nr) - : "cc"); -#endif -} - -#define __set_bit(nr, addr) set_bit(nr, addr) - -/* - * clear_bit() doesn't provide any barrier for the compiler. - */ -#define smp_mb__before_clear_bit() barrier() -#define smp_mb__after_clear_bit() barrier() - -static __inline__ void clear_bit(int nr, volatile unsigned long * addr) -{ -#ifdef CONFIG_COLDFIRE - __asm__ __volatile__ ("lea %0,%%a0; bclr %1,(%%a0)" - : "+m" (((volatile char *)addr)[(nr^31) >> 3]) - : "d" (nr) - : "%a0", "cc"); -#else - __asm__ __volatile__ ("bclr %1,%0" - : "+m" (((volatile char *)addr)[(nr^31) >> 3]) - : "di" (nr) - : "cc"); -#endif -} - -#define __clear_bit(nr, addr) clear_bit(nr, addr) - -static __inline__ void change_bit(int nr, volatile unsigned long * addr) -{ -#ifdef CONFIG_COLDFIRE - __asm__ __volatile__ ("lea %0,%%a0; bchg %1,(%%a0)" - : "+m" (((volatile char *)addr)[(nr^31) >> 3]) - : "d" (nr) - : "%a0", "cc"); -#else - __asm__ __volatile__ ("bchg %1,%0" - : "+m" (((volatile char *)addr)[(nr^31) >> 3]) - : "di" (nr) - : "cc"); -#endif -} - -#define __change_bit(nr, addr) change_bit(nr, addr) - -static __inline__ int test_and_set_bit(int nr, volatile unsigned long * addr) -{ - char retval; - -#ifdef CONFIG_COLDFIRE - __asm__ __volatile__ ("lea %1,%%a0; bset %2,(%%a0); sne %0" - : "=d" (retval), "+m" (((volatile char *)addr)[(nr^31) >> 3]) - : "d" (nr) - : "%a0"); -#else - __asm__ __volatile__ ("bset %2,%1; sne %0" - : "=d" (retval), "+m" (((volatile char *)addr)[(nr^31) >> 3]) - : "di" (nr) - /* No clobber */); -#endif - - return retval; -} - -#define __test_and_set_bit(nr, addr) test_and_set_bit(nr, addr) - -static __inline__ int test_and_clear_bit(int nr, volatile unsigned long * addr) -{ - char retval; - -#ifdef CONFIG_COLDFIRE - __asm__ __volatile__ ("lea %1,%%a0; bclr %2,(%%a0); sne %0" - : "=d" (retval), "+m" (((volatile char *)addr)[(nr^31) >> 3]) - : "d" (nr) - : "%a0"); -#else - __asm__ __volatile__ ("bclr %2,%1; sne %0" - : "=d" (retval), "+m" (((volatile char *)addr)[(nr^31) >> 3]) - : "di" (nr) - /* No clobber */); -#endif - - return retval; -} - -#define __test_and_clear_bit(nr, addr) test_and_clear_bit(nr, addr) - -static __inline__ int test_and_change_bit(int nr, volatile unsigned long * addr) -{ - char retval; - -#ifdef CONFIG_COLDFIRE - __asm__ __volatile__ ("lea %1,%%a0\n\tbchg %2,(%%a0)\n\tsne %0" - : "=d" (retval), "+m" (((volatile char *)addr)[(nr^31) >> 3]) - : "d" (nr) - : "%a0"); -#else - __asm__ __volatile__ ("bchg %2,%1; sne %0" - : "=d" (retval), "+m" (((volatile char *)addr)[(nr^31) >> 3]) - : "di" (nr) - /* No clobber */); -#endif - - return retval; -} - -#define __test_and_change_bit(nr, addr) test_and_change_bit(nr, addr) - -/* - * This routine doesn't need to be atomic. - */ -static __inline__ int __constant_test_bit(int nr, const volatile unsigned long * addr) -{ - return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; -} - -static __inline__ int __test_bit(int nr, const volatile unsigned long * addr) -{ - int * a = (int *) addr; - int mask; - - a += nr >> 5; - mask = 1 << (nr & 0x1f); - return ((mask & *a) != 0); -} - -#define test_bit(nr,addr) \ -(__builtin_constant_p(nr) ? \ - __constant_test_bit((nr),(addr)) : \ - __test_bit((nr),(addr))) - -#include -#include -#include - -static __inline__ int ext2_set_bit(int nr, volatile void * addr) -{ - char retval; - -#ifdef CONFIG_COLDFIRE - __asm__ __volatile__ ("lea %1,%%a0; bset %2,(%%a0); sne %0" - : "=d" (retval), "+m" (((volatile char *)addr)[nr >> 3]) - : "d" (nr) - : "%a0"); -#else - __asm__ __volatile__ ("bset %2,%1; sne %0" - : "=d" (retval), "+m" (((volatile char *)addr)[nr >> 3]) - : "di" (nr) - /* No clobber */); -#endif - - return retval; -} - -static __inline__ int ext2_clear_bit(int nr, volatile void * addr) -{ - char retval; - -#ifdef CONFIG_COLDFIRE - __asm__ __volatile__ ("lea %1,%%a0; bclr %2,(%%a0); sne %0" - : "=d" (retval), "+m" (((volatile char *)addr)[nr >> 3]) - : "d" (nr) - : "%a0"); -#else - __asm__ __volatile__ ("bclr %2,%1; sne %0" - : "=d" (retval), "+m" (((volatile char *)addr)[nr >> 3]) - : "di" (nr) - /* No clobber */); -#endif - - return retval; -} - -#define ext2_set_bit_atomic(lock, nr, addr) \ - ({ \ - int ret; \ - spin_lock(lock); \ - ret = ext2_set_bit((nr), (addr)); \ - spin_unlock(lock); \ - ret; \ - }) - -#define ext2_clear_bit_atomic(lock, nr, addr) \ - ({ \ - int ret; \ - spin_lock(lock); \ - ret = ext2_clear_bit((nr), (addr)); \ - spin_unlock(lock); \ - ret; \ - }) - -static __inline__ int ext2_test_bit(int nr, const volatile void * addr) -{ - char retval; - -#ifdef CONFIG_COLDFIRE - __asm__ __volatile__ ("lea %1,%%a0; btst %2,(%%a0); sne %0" - : "=d" (retval) - : "m" (((const volatile char *)addr)[nr >> 3]), "d" (nr) - : "%a0"); -#else - __asm__ __volatile__ ("btst %2,%1; sne %0" - : "=d" (retval) - : "m" (((const volatile char *)addr)[nr >> 3]), "di" (nr) - /* No clobber */); -#endif - - return retval; -} - -#define ext2_find_first_zero_bit(addr, size) \ - ext2_find_next_zero_bit((addr), (size), 0) - -static __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset) -{ - unsigned long *p = ((unsigned long *) addr) + (offset >> 5); - unsigned long result = offset & ~31UL; - unsigned long tmp; - - if (offset >= size) - return size; - size -= result; - offset &= 31UL; - if(offset) { - /* We hold the little endian value in tmp, but then the - * shift is illegal. So we could keep a big endian value - * in tmp, like this: - * - * tmp = __swab32(*(p++)); - * tmp |= ~0UL >> (32-offset); - * - * but this would decrease performance, so we change the - * shift: - */ - tmp = *(p++); - tmp |= __swab32(~0UL >> (32-offset)); - if(size < 32) - goto found_first; - if(~tmp) - goto found_middle; - size -= 32; - result += 32; - } - while(size & ~31UL) { - if(~(tmp = *(p++))) - goto found_middle; - result += 32; - size -= 32; - } - if(!size) - return result; - tmp = *p; - -found_first: - /* tmp is little endian, so we would have to swab the shift, - * see above. But then we have to swab tmp below for ffz, so - * we might as well do this here. - */ - return result + ffz(__swab32(tmp) | (~0UL << size)); -found_middle: - return result + ffz(__swab32(tmp)); -} - -#define ext2_find_next_bit(addr, size, off) \ - generic_find_next_le_bit((unsigned long *)(addr), (size), (off)) -#include - -#endif /* __KERNEL__ */ - -#include -#include -#include - -#endif /* _M68KNOMMU_BITOPS_H */ diff --git a/arch/m68knommu/include/asm/bootinfo.h b/arch/m68knommu/include/asm/bootinfo.h deleted file mode 100644 index c12e526f518..00000000000 --- a/arch/m68knommu/include/asm/bootinfo.h +++ /dev/null @@ -1,2 +0,0 @@ - -/* Nothing for m68knommu */ diff --git a/arch/m68knommu/include/asm/bootstd.h b/arch/m68knommu/include/asm/bootstd.h deleted file mode 100644 index bdc1a4ac4fe..00000000000 --- a/arch/m68knommu/include/asm/bootstd.h +++ /dev/null @@ -1,132 +0,0 @@ -/* bootstd.h: Bootloader system call interface - * - * (c) 1999, Rt-Control, Inc. - */ - -#ifndef __BOOTSTD_H__ -#define __BOOTSTD_H__ - -#define NR_BSC 21 /* last used bootloader system call */ - -#define __BN_reset 0 /* reset and start the bootloader */ -#define __BN_test 1 /* tests the system call interface */ -#define __BN_exec 2 /* executes a bootloader image */ -#define __BN_exit 3 /* terminates a bootloader image */ -#define __BN_program 4 /* program FLASH from a chain */ -#define __BN_erase 5 /* erase sector(s) of FLASH */ -#define __BN_open 6 -#define __BN_write 7 -#define __BN_read 8 -#define __BN_close 9 -#define __BN_mmap 10 /* map a file descriptor into memory */ -#define __BN_munmap 11 /* remove a file to memory mapping */ -#define __BN_gethwaddr 12 /* get the hardware address of my interfaces */ -#define __BN_getserialnum 13 /* get the serial number of this board */ -#define __BN_getbenv 14 /* get a bootloader envvar */ -#define __BN_setbenv 15 /* get a bootloader envvar */ -#define __BN_setpmask 16 /* set the protection mask */ -#define __BN_readenv 17 /* read environment variables */ -#define __BN_flash_chattr_range 18 -#define __BN_flash_erase_range 19 -#define __BN_flash_write_range 20 - -/* Calling conventions compatible to (uC)linux/68k - * We use simmilar macros to call into the bootloader as for uClinux - */ - -#define __bsc_return(type, res) \ -do { \ - if ((unsigned long)(res) >= (unsigned long)(-64)) { \ - /* let errno be a function, preserve res in %d0 */ \ - int __err = -(res); \ - errno = __err; \ - res = -1; \ - } \ - return (type)(res); \ -} while (0) - -#define _bsc0(type,name) \ -type name(void) \ -{ \ - register long __res __asm__ ("%d0") = __BN_##name; \ - __asm__ __volatile__ ("trap #2" \ - : "=g" (__res) \ - : "0" (__res) \ - ); \ - __bsc_return(type,__res); \ -} - -#define _bsc1(type,name,atype,a) \ -type name(atype a) \ -{ \ - register long __res __asm__ ("%d0") = __BN_##name; \ - register long __a __asm__ ("%d1") = (long)a; \ - __asm__ __volatile__ ("trap #2" \ - : "=g" (__res) \ - : "0" (__res), "d" (__a) \ - ); \ - __bsc_return(type,__res); \ -} - -#define _bsc2(type,name,atype,a,btype,b) \ -type name(atype a, btype b) \ -{ \ - register long __res __asm__ ("%d0") = __BN_##name; \ - register long __a __asm__ ("%d1") = (long)a; \ - register long __b __asm__ ("%d2") = (long)b; \ - __asm__ __volatile__ ("trap #2" \ - : "=g" (__res) \ - : "0" (__res), "d" (__a), "d" (__b) \ - ); \ - __bsc_return(type,__res); \ -} - -#define _bsc3(type,name,atype,a,btype,b,ctype,c) \ -type name(atype a, btype b, ctype c) \ -{ \ - register long __res __asm__ ("%d0") = __BN_##name; \ - register long __a __asm__ ("%d1") = (long)a; \ - register long __b __asm__ ("%d2") = (long)b; \ - register long __c __asm__ ("%d3") = (long)c; \ - __asm__ __volatile__ ("trap #2" \ - : "=g" (__res) \ - : "0" (__res), "d" (__a), "d" (__b), \ - "d" (__c) \ - ); \ - __bsc_return(type,__res); \ -} - -#define _bsc4(type,name,atype,a,btype,b,ctype,c,dtype,d) \ -type name(atype a, btype b, ctype c, dtype d) \ -{ \ - register long __res __asm__ ("%d0") = __BN_##name; \ - register long __a __asm__ ("%d1") = (long)a; \ - register long __b __asm__ ("%d2") = (long)b; \ - register long __c __asm__ ("%d3") = (long)c; \ - register long __d __asm__ ("%d4") = (long)d; \ - __asm__ __volatile__ ("trap #2" \ - : "=g" (__res) \ - : "0" (__res), "d" (__a), "d" (__b), \ - "d" (__c), "d" (__d) \ - ); \ - __bsc_return(type,__res); \ -} - -#define _bsc5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \ -type name(atype a, btype b, ctype c, dtype d, etype e) \ -{ \ - register long __res __asm__ ("%d0") = __BN_##name; \ - register long __a __asm__ ("%d1") = (long)a; \ - register long __b __asm__ ("%d2") = (long)b; \ - register long __c __asm__ ("%d3") = (long)c; \ - register long __d __asm__ ("%d4") = (long)d; \ - register long __e __asm__ ("%d5") = (long)e; \ - __asm__ __volatile__ ("trap #2" \ - : "=g" (__res) \ - : "0" (__res), "d" (__a), "d" (__b), \ - "d" (__c), "d" (__d), "d" (__e) \ - ); \ - __bsc_return(type,__res); \ -} - -#endif /* __BOOTSTD_H__ */ diff --git a/arch/m68knommu/include/asm/bug.h b/arch/m68knommu/include/asm/bug.h deleted file mode 100644 index 70e7dc0af21..00000000000 --- a/arch/m68knommu/include/asm/bug.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef _M68KNOMMU_BUG_H -#define _M68KNOMMU_BUG_H -#include -#endif diff --git a/arch/m68knommu/include/asm/bugs.h b/arch/m68knommu/include/asm/bugs.h deleted file mode 100644 index 5f382dac3a6..00000000000 --- a/arch/m68knommu/include/asm/bugs.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * include/asm-m68k/bugs.h - * - * Copyright (C) 1994 Linus Torvalds - */ - -/* - * This is included by init/main.c to check for architecture-dependent bugs. - * - * Needs: - * void check_bugs(void); - */ - -static void check_bugs(void) -{ -} diff --git a/arch/m68knommu/include/asm/byteorder.h b/arch/m68knommu/include/asm/byteorder.h deleted file mode 100644 index a6f0b8f7f62..00000000000 --- a/arch/m68knommu/include/asm/byteorder.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _M68KNOMMU_BYTEORDER_H -#define _M68KNOMMU_BYTEORDER_H - -#include -#include - -#endif /* _M68KNOMMU_BYTEORDER_H */ diff --git a/arch/m68knommu/include/asm/cache.h b/arch/m68knommu/include/asm/cache.h deleted file mode 100644 index 24e9eace5f8..00000000000 --- a/arch/m68knommu/include/asm/cache.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __ARCH_M68KNOMMU_CACHE_H -#define __ARCH_M68KNOMMU_CACHE_H - -/* bytes per L1 cache line */ -#define L1_CACHE_BYTES 16 /* this need to be at least 1 */ - -/* m68k-elf-gcc 2.95.2 doesn't like these */ - -#define __cacheline_aligned -#define ____cacheline_aligned - -#endif diff --git a/arch/m68knommu/include/asm/cachectl.h b/arch/m68knommu/include/asm/cachectl.h deleted file mode 100644 index bcf5a6a9dd5..00000000000 --- a/arch/m68knommu/include/asm/cachectl.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/cacheflush.h b/arch/m68knommu/include/asm/cacheflush.h deleted file mode 100644 index 87e5dc0413b..00000000000 --- a/arch/m68knommu/include/asm/cacheflush.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef _M68KNOMMU_CACHEFLUSH_H -#define _M68KNOMMU_CACHEFLUSH_H - -/* - * (C) Copyright 2000-2004, Greg Ungerer - */ -#include - -#define flush_cache_all() __flush_cache_all() -#define flush_cache_mm(mm) do { } while (0) -#define flush_cache_dup_mm(mm) do { } while (0) -#define flush_cache_range(vma, start, end) __flush_cache_all() -#define flush_cache_page(vma, vmaddr) do { } while (0) -#define flush_dcache_range(start,len) __flush_cache_all() -#define flush_dcache_page(page) do { } while (0) -#define flush_dcache_mmap_lock(mapping) do { } while (0) -#define flush_dcache_mmap_unlock(mapping) do { } while (0) -#define flush_icache_range(start,len) __flush_cache_all() -#define flush_icache_page(vma,pg) do { } while (0) -#define flush_icache_user_range(vma,pg,adr,len) do { } while (0) -#define flush_cache_vmap(start, end) do { } while (0) -#define flush_cache_vunmap(start, end) do { } while (0) - -#define copy_to_user_page(vma, page, vaddr, dst, src, len) \ - memcpy(dst, src, len) -#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ - memcpy(dst, src, len) - -static inline void __flush_cache_all(void) -{ -#ifdef CONFIG_M5407 - /* - * Use cpushl to push and invalidate all cache lines. - * Gas doesn't seem to know how to generate the ColdFire - * cpushl instruction... Oh well, bit stuff it for now. - */ - __asm__ __volatile__ ( - "nop\n\t" - "clrl %%d0\n\t" - "1:\n\t" - "movel %%d0,%%a0\n\t" - "2:\n\t" - ".word 0xf468\n\t" - "addl #0x10,%%a0\n\t" - "cmpl #0x00000800,%%a0\n\t" - "blt 2b\n\t" - "addql #1,%%d0\n\t" - "cmpil #4,%%d0\n\t" - "bne 1b\n\t" - "movel #0xb6088500,%%d0\n\t" - "movec %%d0,%%CACR\n\t" - : : : "d0", "a0" ); -#endif /* CONFIG_M5407 */ -#if defined(CONFIG_M527x) || defined(CONFIG_M528x) - __asm__ __volatile__ ( - "movel #0x81000200, %%d0\n\t" - "movec %%d0, %%CACR\n\t" - "nop\n\t" - : : : "d0" ); -#endif /* CONFIG_M527x || CONFIG_M528x */ -#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || defined(CONFIG_M5272) - __asm__ __volatile__ ( - "movel #0x81000100, %%d0\n\t" - "movec %%d0, %%CACR\n\t" - "nop\n\t" - : : : "d0" ); -#endif /* CONFIG_M5206 || CONFIG_M5206e || CONFIG_M5272 */ -#ifdef CONFIG_M5249 - __asm__ __volatile__ ( - "movel #0xa1000200, %%d0\n\t" - "movec %%d0, %%CACR\n\t" - "nop\n\t" - : : : "d0" ); -#endif /* CONFIG_M5249 */ -#ifdef CONFIG_M532x - __asm__ __volatile__ ( - "movel #0x81000200, %%d0\n\t" - "movec %%d0, %%CACR\n\t" - "nop\n\t" - : : : "d0" ); -#endif /* CONFIG_M532x */ -} - -#endif /* _M68KNOMMU_CACHEFLUSH_H */ diff --git a/arch/m68knommu/include/asm/checksum.h b/arch/m68knommu/include/asm/checksum.h deleted file mode 100644 index 81883482ffb..00000000000 --- a/arch/m68knommu/include/asm/checksum.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef _M68K_CHECKSUM_H -#define _M68K_CHECKSUM_H - -#include - -/* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -__wsum csum_partial(const void *buff, int len, __wsum sum); - -/* - * the same as csum_partial, but copies from src while it - * checksums - * - * here even more important to align src and dst on a 32-bit (or even - * better 64-bit) boundary - */ - -__wsum csum_partial_copy_nocheck(const void *src, void *dst, - int len, __wsum sum); - - -/* - * the same as csum_partial_copy, but copies from user space. - * - * here even more important to align src and dst on a 32-bit (or even - * better 64-bit) boundary - */ - -extern __wsum csum_partial_copy_from_user(const void __user *src, - void *dst, int len, __wsum sum, int *csum_err); - -__sum16 ip_fast_csum(const void *iph, unsigned int ihl); - -/* - * Fold a partial checksum - */ - -static inline __sum16 csum_fold(__wsum sum) -{ - unsigned int tmp = (__force u32)sum; -#ifdef CONFIG_COLDFIRE - tmp = (tmp & 0xffff) + (tmp >> 16); - tmp = (tmp & 0xffff) + (tmp >> 16); - return (__force __sum16)~tmp; -#else - __asm__("swap %1\n\t" - "addw %1, %0\n\t" - "clrw %1\n\t" - "addxw %1, %0" - : "=&d" (sum), "=&d" (tmp) - : "0" (sum), "1" (sum)); - return (__force __sum16)~sum; -#endif -} - - -/* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented - */ - -static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) -{ - __asm__ ("addl %1,%0\n\t" - "addxl %4,%0\n\t" - "addxl %5,%0\n\t" - "clrl %1\n\t" - "addxl %1,%0" - : "=&d" (sum), "=&d" (saddr) - : "0" (daddr), "1" (saddr), "d" (len + proto), - "d"(sum)); - return sum; -} - -static inline __sum16 -csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) -{ - return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); -} - -/* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ - -extern __sum16 ip_compute_csum(const void *buff, int len); - -#define _HAVE_ARCH_IPV6_CSUM -static __inline__ __sum16 -csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, - __u32 len, unsigned short proto, __wsum sum) -{ - register unsigned long tmp; - __asm__("addl %2@,%0\n\t" - "movel %2@(4),%1\n\t" - "addxl %1,%0\n\t" - "movel %2@(8),%1\n\t" - "addxl %1,%0\n\t" - "movel %2@(12),%1\n\t" - "addxl %1,%0\n\t" - "movel %3@,%1\n\t" - "addxl %1,%0\n\t" - "movel %3@(4),%1\n\t" - "addxl %1,%0\n\t" - "movel %3@(8),%1\n\t" - "addxl %1,%0\n\t" - "movel %3@(12),%1\n\t" - "addxl %1,%0\n\t" - "addxl %4,%0\n\t" - "clrl %1\n\t" - "addxl %1,%0" - : "=&d" (sum), "=&d" (tmp) - : "a" (saddr), "a" (daddr), "d" (len + proto), - "0" (sum)); - - return csum_fold(sum); -} - -#endif /* _M68K_CHECKSUM_H */ diff --git a/arch/m68knommu/include/asm/coldfire.h b/arch/m68knommu/include/asm/coldfire.h deleted file mode 100644 index 83a9fa4e618..00000000000 --- a/arch/m68knommu/include/asm/coldfire.h +++ /dev/null @@ -1,51 +0,0 @@ -/****************************************************************************/ - -/* - * coldfire.h -- Motorola ColdFire CPU sepecific defines - * - * (C) Copyright 1999-2006, Greg Ungerer (gerg@snapgear.com) - * (C) Copyright 2000, Lineo (www.lineo.com) - */ - -/****************************************************************************/ -#ifndef coldfire_h -#define coldfire_h -/****************************************************************************/ - - -/* - * Define master clock frequency. This is essentially done at config - * time now. No point enumerating dozens of possible clock options - * here. Also the peripheral clock (bus clock) divide ratio is set - * at config time too. - */ -#ifdef CONFIG_CLOCK_SET -#define MCF_CLK CONFIG_CLOCK_FREQ -#define MCF_BUSCLK (CONFIG_CLOCK_FREQ / CONFIG_CLOCK_DIV) -#else -#error "Don't know what your ColdFire CPU clock frequency is??" -#endif - -/* - * Define the processor support peripherals base address. - * This is generally setup by the boards start up code. - */ -#define MCF_MBAR 0x10000000 -#define MCF_MBAR2 0x80000000 -#if defined(CONFIG_M520x) -#define MCF_IPSBAR 0xFC000000 -#else -#define MCF_IPSBAR 0x40000000 -#endif - -#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ - defined(CONFIG_M520x) -#undef MCF_MBAR -#define MCF_MBAR MCF_IPSBAR -#elif defined(CONFIG_M532x) -#undef MCF_MBAR -#define MCF_MBAR 0x00000000 -#endif - -/****************************************************************************/ -#endif /* coldfire_h */ diff --git a/arch/m68knommu/include/asm/commproc.h b/arch/m68knommu/include/asm/commproc.h deleted file mode 100644 index edf5eb6c08d..00000000000 --- a/arch/m68knommu/include/asm/commproc.h +++ /dev/null @@ -1,703 +0,0 @@ - -/* - * 68360 Communication Processor Module. - * Copyright (c) 2000 Michael Leslie (mc68360) after: - * Copyright (c) 1997 Dan Malek (mpc8xx) - * - * This file contains structures and information for the communication - * processor channels. Some CPM control and status is available - * through the 68360 internal memory map. See include/asm/360_immap.h for details. - * This file is not a complete map of all of the 360 QUICC's capabilities - * - * On the MBX board, EPPC-Bug loads CPM microcode into the first 512 - * bytes of the DP RAM and relocates the I2C parameter area to the - * IDMA1 space. The remaining DP RAM is available for buffer descriptors - * or other use. - */ -#ifndef __CPM_360__ -#define __CPM_360__ - - -/* CPM Command register masks: */ -#define CPM_CR_RST ((ushort)0x8000) -#define CPM_CR_OPCODE ((ushort)0x0f00) -#define CPM_CR_CHAN ((ushort)0x00f0) -#define CPM_CR_FLG ((ushort)0x0001) - -/* CPM Command set (opcodes): */ -#define CPM_CR_INIT_TRX ((ushort)0x0000) -#define CPM_CR_INIT_RX ((ushort)0x0001) -#define CPM_CR_INIT_TX ((ushort)0x0002) -#define CPM_CR_HUNT_MODE ((ushort)0x0003) -#define CPM_CR_STOP_TX ((ushort)0x0004) -#define CPM_CR_GRSTOP_TX ((ushort)0x0005) -#define CPM_CR_RESTART_TX ((ushort)0x0006) -#define CPM_CR_CLOSE_RXBD ((ushort)0x0007) -#define CPM_CR_SET_GADDR ((ushort)0x0008) -#define CPM_CR_GCI_TIMEOUT ((ushort)0x0009) -#define CPM_CR_GCI_ABORT ((ushort)0x000a) -#define CPM_CR_RESET_BCS ((ushort)0x000a) - -/* CPM Channel numbers. */ -#define CPM_CR_CH_SCC1 ((ushort)0x0000) -#define CPM_CR_CH_SCC2 ((ushort)0x0004) -#define CPM_CR_CH_SPI ((ushort)0x0005) /* SPI / Timers */ -#define CPM_CR_CH_TMR ((ushort)0x0005) -#define CPM_CR_CH_SCC3 ((ushort)0x0008) -#define CPM_CR_CH_SMC1 ((ushort)0x0009) /* SMC1 / IDMA1 */ -#define CPM_CR_CH_IDMA1 ((ushort)0x0009) -#define CPM_CR_CH_SCC4 ((ushort)0x000c) -#define CPM_CR_CH_SMC2 ((ushort)0x000d) /* SMC2 / IDMA2 */ -#define CPM_CR_CH_IDMA2 ((ushort)0x000d) - - -#define mk_cr_cmd(CH, CMD) ((CMD << 8) | (CH << 4)) - -#if 1 /* mleslie: I dinna think we have any such restrictions on - * DP RAM aboard the 360 board - see the MC68360UM p.3-3 */ - -/* The dual ported RAM is multi-functional. Some areas can be (and are - * being) used for microcode. There is an area that can only be used - * as data ram for buffer descriptors, which is all we use right now. - * Currently the first 512 and last 256 bytes are used for microcode. - */ -/* mleslie: The uCquicc board is using no extra microcode in DPRAM */ -#define CPM_DATAONLY_BASE ((uint)0x0000) -#define CPM_DATAONLY_SIZE ((uint)0x0800) -#define CPM_DP_NOSPACE ((uint)0x7fffffff) - -#endif - - -/* Export the base address of the communication processor registers - * and dual port ram. */ -/* extern cpm360_t *cpmp; */ /* Pointer to comm processor */ -extern QUICC *pquicc; -uint m360_cpm_dpalloc(uint size); -/* void *m360_cpm_hostalloc(uint size); */ -void m360_cpm_setbrg(uint brg, uint rate); - -#if 0 /* use QUICC_BD declared in include/asm/m68360_quicc.h */ -/* Buffer descriptors used by many of the CPM protocols. */ -typedef struct cpm_buf_desc { - ushort cbd_sc; /* Status and Control */ - ushort cbd_datlen; /* Data length in buffer */ - uint cbd_bufaddr; /* Buffer address in host memory */ -} cbd_t; -#endif - - -/* rx bd status/control bits */ -#define BD_SC_EMPTY ((ushort)0x8000) /* Recieve is empty */ -#define BD_SC_WRAP ((ushort)0x2000) /* Last buffer descriptor in table */ -#define BD_SC_INTRPT ((ushort)0x1000) /* Interrupt on change */ -#define BD_SC_LAST ((ushort)0x0800) /* Last buffer in frame OR control char */ - -#define BD_SC_FIRST ((ushort)0x0400) /* 1st buffer in an HDLC frame */ -#define BD_SC_ADDR ((ushort)0x0400) /* 1st byte is a multidrop address */ - -#define BD_SC_CM ((ushort)0x0200) /* Continous mode */ -#define BD_SC_ID ((ushort)0x0100) /* Received too many idles */ - -#define BD_SC_AM ((ushort)0x0080) /* Multidrop address match */ -#define BD_SC_DE ((ushort)0x0080) /* DPLL Error (HDLC) */ - -#define BD_SC_BR ((ushort)0x0020) /* Break received */ -#define BD_SC_LG ((ushort)0x0020) /* Frame length violation (HDLC) */ - -#define BD_SC_FR ((ushort)0x0010) /* Framing error */ -#define BD_SC_NO ((ushort)0x0010) /* Nonoctet aligned frame (HDLC) */ - -#define BD_SC_PR ((ushort)0x0008) /* Parity error */ -#define BD_SC_AB ((ushort)0x0008) /* Received abort Sequence (HDLC) */ - -#define BD_SC_OV ((ushort)0x0002) /* Overrun */ -#define BD_SC_CD ((ushort)0x0001) /* Carrier Detect lost */ - -/* tx bd status/control bits (as differ from rx bd) */ -#define BD_SC_READY ((ushort)0x8000) /* Transmit is ready */ -#define BD_SC_TC ((ushort)0x0400) /* Transmit CRC */ -#define BD_SC_P ((ushort)0x0100) /* xmt preamble */ -#define BD_SC_UN ((ushort)0x0002) /* Underrun */ - - - - -/* Parameter RAM offsets. */ - - - -/* In 2.4 ppc, the PROFF_S?C? are used as byte offsets into DPRAM. - * In 2.0, we use a more structured C struct map of DPRAM, and so - * instead, we need only a parameter ram `slot' */ - -#define PRSLOT_SCC1 0 -#define PRSLOT_SCC2 1 -#define PRSLOT_SCC3 2 -#define PRSLOT_SMC1 2 -#define PRSLOT_SCC4 3 -#define PRSLOT_SMC2 3 - - -/* #define PROFF_SCC1 ((uint)0x0000) */ -/* #define PROFF_SCC2 ((uint)0x0100) */ -/* #define PROFF_SCC3 ((uint)0x0200) */ -/* #define PROFF_SMC1 ((uint)0x0280) */ -/* #define PROFF_SCC4 ((uint)0x0300) */ -/* #define PROFF_SMC2 ((uint)0x0380) */ - - -/* Define enough so I can at least use the serial port as a UART. - * The MBX uses SMC1 as the host serial port. - */ -typedef struct smc_uart { - ushort smc_rbase; /* Rx Buffer descriptor base address */ - ushort smc_tbase; /* Tx Buffer descriptor base address */ - u_char smc_rfcr; /* Rx function code */ - u_char smc_tfcr; /* Tx function code */ - ushort smc_mrblr; /* Max receive buffer length */ - uint smc_rstate; /* Internal */ - uint smc_idp; /* Internal */ - ushort smc_rbptr; /* Internal */ - ushort smc_ibc; /* Internal */ - uint smc_rxtmp; /* Internal */ - uint smc_tstate; /* Internal */ - uint smc_tdp; /* Internal */ - ushort smc_tbptr; /* Internal */ - ushort smc_tbc; /* Internal */ - uint smc_txtmp; /* Internal */ - ushort smc_maxidl; /* Maximum idle characters */ - ushort smc_tmpidl; /* Temporary idle counter */ - ushort smc_brklen; /* Last received break length */ - ushort smc_brkec; /* rcv'd break condition counter */ - ushort smc_brkcr; /* xmt break count register */ - ushort smc_rmask; /* Temporary bit mask */ -} smc_uart_t; - -/* Function code bits. -*/ -#define SMC_EB ((u_char)0x10) /* Set big endian byte order */ - -/* SMC uart mode register. -*/ -#define SMCMR_REN ((ushort)0x0001) -#define SMCMR_TEN ((ushort)0x0002) -#define SMCMR_DM ((ushort)0x000c) -#define SMCMR_SM_GCI ((ushort)0x0000) -#define SMCMR_SM_UART ((ushort)0x0020) -#define SMCMR_SM_TRANS ((ushort)0x0030) -#define SMCMR_SM_MASK ((ushort)0x0030) -#define SMCMR_PM_EVEN ((ushort)0x0100) /* Even parity, else odd */ -#define SMCMR_REVD SMCMR_PM_EVEN -#define SMCMR_PEN ((ushort)0x0200) /* Parity enable */ -#define SMCMR_BS SMCMR_PEN -#define SMCMR_SL ((ushort)0x0400) /* Two stops, else one */ -#define SMCR_CLEN_MASK ((ushort)0x7800) /* Character length */ -#define smcr_mk_clen(C) (((C) << 11) & SMCR_CLEN_MASK) - -/* SMC2 as Centronics parallel printer. It is half duplex, in that - * it can only receive or transmit. The parameter ram values for - * each direction are either unique or properly overlap, so we can - * include them in one structure. - */ -typedef struct smc_centronics { - ushort scent_rbase; - ushort scent_tbase; - u_char scent_cfcr; - u_char scent_smask; - ushort scent_mrblr; - uint scent_rstate; - uint scent_r_ptr; - ushort scent_rbptr; - ushort scent_r_cnt; - uint scent_rtemp; - uint scent_tstate; - uint scent_t_ptr; - ushort scent_tbptr; - ushort scent_t_cnt; - uint scent_ttemp; - ushort scent_max_sl; - ushort scent_sl_cnt; - ushort scent_character1; - ushort scent_character2; - ushort scent_character3; - ushort scent_character4; - ushort scent_character5; - ushort scent_character6; - ushort scent_character7; - ushort scent_character8; - ushort scent_rccm; - ushort scent_rccr; -} smc_cent_t; - -/* Centronics Status Mask Register. -*/ -#define SMC_CENT_F ((u_char)0x08) -#define SMC_CENT_PE ((u_char)0x04) -#define SMC_CENT_S ((u_char)0x02) - -/* SMC Event and Mask register. -*/ -#define SMCM_BRKE ((unsigned char)0x40) /* When in UART Mode */ -#define SMCM_BRK ((unsigned char)0x10) /* When in UART Mode */ -#define SMCM_TXE ((unsigned char)0x10) /* When in Transparent Mode */ -#define SMCM_BSY ((unsigned char)0x04) -#define SMCM_TX ((unsigned char)0x02) -#define SMCM_RX ((unsigned char)0x01) - -/* Baud rate generators. -*/ -#define CPM_BRG_RST ((uint)0x00020000) -#define CPM_BRG_EN ((uint)0x00010000) -#define CPM_BRG_EXTC_INT ((uint)0x00000000) -#define CPM_BRG_EXTC_CLK2 ((uint)0x00004000) -#define CPM_BRG_EXTC_CLK6 ((uint)0x00008000) -#define CPM_BRG_ATB ((uint)0x00002000) -#define CPM_BRG_CD_MASK ((uint)0x00001ffe) -#define CPM_BRG_DIV16 ((uint)0x00000001) - -/* SCCs. -*/ -#define SCC_GSMRH_IRP ((uint)0x00040000) -#define SCC_GSMRH_GDE ((uint)0x00010000) -#define SCC_GSMRH_TCRC_CCITT ((uint)0x00008000) -#define SCC_GSMRH_TCRC_BISYNC ((uint)0x00004000) -#define SCC_GSMRH_TCRC_HDLC ((uint)0x00000000) -#define SCC_GSMRH_REVD ((uint)0x00002000) -#define SCC_GSMRH_TRX ((uint)0x00001000) -#define SCC_GSMRH_TTX ((uint)0x00000800) -#define SCC_GSMRH_CDP ((uint)0x00000400) -#define SCC_GSMRH_CTSP ((uint)0x00000200) -#define SCC_GSMRH_CDS ((uint)0x00000100) -#define SCC_GSMRH_CTSS ((uint)0x00000080) -#define SCC_GSMRH_TFL ((uint)0x00000040) -#define SCC_GSMRH_RFW ((uint)0x00000020) -#define SCC_GSMRH_TXSY ((uint)0x00000010) -#define SCC_GSMRH_SYNL16 ((uint)0x0000000c) -#define SCC_GSMRH_SYNL8 ((uint)0x00000008) -#define SCC_GSMRH_SYNL4 ((uint)0x00000004) -#define SCC_GSMRH_RTSM ((uint)0x00000002) -#define SCC_GSMRH_RSYN ((uint)0x00000001) - -#define SCC_GSMRL_SIR ((uint)0x80000000) /* SCC2 only */ -#define SCC_GSMRL_EDGE_NONE ((uint)0x60000000) -#define SCC_GSMRL_EDGE_NEG ((uint)0x40000000) -#define SCC_GSMRL_EDGE_POS ((uint)0x20000000) -#define SCC_GSMRL_EDGE_BOTH ((uint)0x00000000) -#define SCC_GSMRL_TCI ((uint)0x10000000) -#define SCC_GSMRL_TSNC_3 ((uint)0x0c000000) -#define SCC_GSMRL_TSNC_4 ((uint)0x08000000) -#define SCC_GSMRL_TSNC_14 ((uint)0x04000000) -#define SCC_GSMRL_TSNC_INF ((uint)0x00000000) -#define SCC_GSMRL_RINV ((uint)0x02000000) -#define SCC_GSMRL_TINV ((uint)0x01000000) -#define SCC_GSMRL_TPL_128 ((uint)0x00c00000) -#define SCC_GSMRL_TPL_64 ((uint)0x00a00000) -#define SCC_GSMRL_TPL_48 ((uint)0x00800000) -#define SCC_GSMRL_TPL_32 ((uint)0x00600000) -#define SCC_GSMRL_TPL_16 ((uint)0x00400000) -#define SCC_GSMRL_TPL_8 ((uint)0x00200000) -#define SCC_GSMRL_TPL_NONE ((uint)0x00000000) -#define SCC_GSMRL_TPP_ALL1 ((uint)0x00180000) -#define SCC_GSMRL_TPP_01 ((uint)0x00100000) -#define SCC_GSMRL_TPP_10 ((uint)0x00080000) -#define SCC_GSMRL_TPP_ZEROS ((uint)0x00000000) -#define SCC_GSMRL_TEND ((uint)0x00040000) -#define SCC_GSMRL_TDCR_32 ((uint)0x00030000) -#define SCC_GSMRL_TDCR_16 ((uint)0x00020000) -#define SCC_GSMRL_TDCR_8 ((uint)0x00010000) -#define SCC_GSMRL_TDCR_1 ((uint)0x00000000) -#define SCC_GSMRL_RDCR_32 ((uint)0x0000c000) -#define SCC_GSMRL_RDCR_16 ((uint)0x00008000) -#define SCC_GSMRL_RDCR_8 ((uint)0x00004000) -#define SCC_GSMRL_RDCR_1 ((uint)0x00000000) -#define SCC_GSMRL_RENC_DFMAN ((uint)0x00003000) -#define SCC_GSMRL_RENC_MANCH ((uint)0x00002000) -#define SCC_GSMRL_RENC_FM0 ((uint)0x00001000) -#define SCC_GSMRL_RENC_NRZI ((uint)0x00000800) -#define SCC_GSMRL_RENC_NRZ ((uint)0x00000000) -#define SCC_GSMRL_TENC_DFMAN ((uint)0x00000600) -#define SCC_GSMRL_TENC_MANCH ((uint)0x00000400) -#define SCC_GSMRL_TENC_FM0 ((uint)0x00000200) -#define SCC_GSMRL_TENC_NRZI ((uint)0x00000100) -#define SCC_GSMRL_TENC_NRZ ((uint)0x00000000) -#define SCC_GSMRL_DIAG_LE ((uint)0x000000c0) /* Loop and echo */ -#define SCC_GSMRL_DIAG_ECHO ((uint)0x00000080) -#define SCC_GSMRL_DIAG_LOOP ((uint)0x00000040) -#define SCC_GSMRL_DIAG_NORM ((uint)0x00000000) -#define SCC_GSMRL_ENR ((uint)0x00000020) -#define SCC_GSMRL_ENT ((uint)0x00000010) -#define SCC_GSMRL_MODE_ENET ((uint)0x0000000c) -#define SCC_GSMRL_MODE_DDCMP ((uint)0x00000009) -#define SCC_GSMRL_MODE_BISYNC ((uint)0x00000008) -#define SCC_GSMRL_MODE_V14 ((uint)0x00000007) -#define SCC_GSMRL_MODE_AHDLC ((uint)0x00000006) -#define SCC_GSMRL_MODE_PROFIBUS ((uint)0x00000005) -#define SCC_GSMRL_MODE_UART ((uint)0x00000004) -#define SCC_GSMRL_MODE_SS7 ((uint)0x00000003) -#define SCC_GSMRL_MODE_ATALK ((uint)0x00000002) -#define SCC_GSMRL_MODE_HDLC ((uint)0x00000000) - -#define SCC_TODR_TOD ((ushort)0x8000) - -/* SCC Event and Mask register. -*/ -#define SCCM_TXE ((unsigned char)0x10) -#define SCCM_BSY ((unsigned char)0x04) -#define SCCM_TX ((unsigned char)0x02) -#define SCCM_RX ((unsigned char)0x01) - -typedef struct scc_param { - ushort scc_rbase; /* Rx Buffer descriptor base address */ - ushort scc_tbase; /* Tx Buffer descriptor base address */ - u_char scc_rfcr; /* Rx function code */ - u_char scc_tfcr; /* Tx function code */ - ushort scc_mrblr; /* Max receive buffer length */ - uint scc_rstate; /* Internal */ - uint scc_idp; /* Internal */ - ushort scc_rbptr; /* Internal */ - ushort scc_ibc; /* Internal */ - uint scc_rxtmp; /* Internal */ - uint scc_tstate; /* Internal */ - uint scc_tdp; /* Internal */ - ushort scc_tbptr; /* Internal */ - ushort scc_tbc; /* Internal */ - uint scc_txtmp; /* Internal */ - uint scc_rcrc; /* Internal */ - uint scc_tcrc; /* Internal */ -} sccp_t; - - -/* Function code bits. - */ -#define SCC_EB ((u_char)0x10) /* Set big endian byte order */ -#define SCC_FC_DMA ((u_char)0x08) /* Set SDMA */ - -/* CPM Ethernet through SCC1. - */ -typedef struct scc_enet { - sccp_t sen_genscc; - uint sen_cpres; /* Preset CRC */ - uint sen_cmask; /* Constant mask for CRC */ - uint sen_crcec; /* CRC Error counter */ - uint sen_alec; /* alignment error counter */ - uint sen_disfc; /* discard frame counter */ - ushort sen_pads; /* Tx short frame pad character */ - ushort sen_retlim; /* Retry limit threshold */ - ushort sen_retcnt; /* Retry limit counter */ - ushort sen_maxflr; /* maximum frame length register */ - ushort sen_minflr; /* minimum frame length register */ - ushort sen_maxd1; /* maximum DMA1 length */ - ushort sen_maxd2; /* maximum DMA2 length */ - ushort sen_maxd; /* Rx max DMA */ - ushort sen_dmacnt; /* Rx DMA counter */ - ushort sen_maxb; /* Max BD byte count */ - ushort sen_gaddr1; /* Group address filter */ - ushort sen_gaddr2; - ushort sen_gaddr3; - ushort sen_gaddr4; - uint sen_tbuf0data0; /* Save area 0 - current frame */ - uint sen_tbuf0data1; /* Save area 1 - current frame */ - uint sen_tbuf0rba; /* Internal */ - uint sen_tbuf0crc; /* Internal */ - ushort sen_tbuf0bcnt; /* Internal */ - ushort sen_paddrh; /* physical address (MSB) */ - ushort sen_paddrm; - ushort sen_paddrl; /* physical address (LSB) */ - ushort sen_pper; /* persistence */ - ushort sen_rfbdptr; /* Rx first BD pointer */ - ushort sen_tfbdptr; /* Tx first BD pointer */ - ushort sen_tlbdptr; /* Tx last BD pointer */ - uint sen_tbuf1data0; /* Save area 0 - current frame */ - uint sen_tbuf1data1; /* Save area 1 - current frame */ - uint sen_tbuf1rba; /* Internal */ - uint sen_tbuf1crc; /* Internal */ - ushort sen_tbuf1bcnt; /* Internal */ - ushort sen_txlen; /* Tx Frame length counter */ - ushort sen_iaddr1; /* Individual address filter */ - ushort sen_iaddr2; - ushort sen_iaddr3; - ushort sen_iaddr4; - ushort sen_boffcnt; /* Backoff counter */ - - /* NOTE: Some versions of the manual have the following items - * incorrectly documented. Below is the proper order. - */ - ushort sen_taddrh; /* temp address (MSB) */ - ushort sen_taddrm; - ushort sen_taddrl; /* temp address (LSB) */ -} scc_enet_t; - - - -#if defined (CONFIG_UCQUICC) -/* uCquicc has the following signals connected to Ethernet: - * 68360 - lxt905 - * PA0/RXD1 - rxd - * PA1/TXD1 - txd - * PA8/CLK1 - tclk - * PA9/CLK2 - rclk - * PC0/!RTS1 - t_en - * PC1/!CTS1 - col - * PC5/!CD1 - cd - */ -#define PA_ENET_RXD PA_RXD1 -#define PA_ENET_TXD PA_TXD1 -#define PA_ENET_TCLK PA_CLK1 -#define PA_ENET_RCLK PA_CLK2 -#define PC_ENET_TENA PC_RTS1 -#define PC_ENET_CLSN PC_CTS1 -#define PC_ENET_RENA PC_CD1 - -/* Control bits in the SICR to route TCLK (CLK1) and RCLK (CLK2) to - * SCC1. - */ -#define SICR_ENET_MASK ((uint)0x000000ff) -#define SICR_ENET_CLKRT ((uint)0x0000002c) - -#endif /* config_ucquicc */ - - -#ifdef MBX -/* Bits in parallel I/O port registers that have to be set/cleared - * to configure the pins for SCC1 use. The TCLK and RCLK seem unique - * to the MBX860 board. Any two of the four available clocks could be - * used, and the MPC860 cookbook manual has an example using different - * clock pins. - */ -#define PA_ENET_RXD ((ushort)0x0001) -#define PA_ENET_TXD ((ushort)0x0002) -#define PA_ENET_TCLK ((ushort)0x0200) -#define PA_ENET_RCLK ((ushort)0x0800) -#define PC_ENET_TENA ((ushort)0x0001) -#define PC_ENET_CLSN ((ushort)0x0010) -#define PC_ENET_RENA ((ushort)0x0020) - -/* Control bits in the SICR to route TCLK (CLK2) and RCLK (CLK4) to - * SCC1. Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero. - */ -#define SICR_ENET_MASK ((uint)0x000000ff) -#define SICR_ENET_CLKRT ((uint)0x0000003d) -#endif - -#ifdef CONFIG_RPXLITE -/* This ENET stuff is for the MPC850 with ethernet on SCC2. Some of - * this may be unique to the RPX-Lite configuration. - * Note TENA is on Port B. - */ -#define PA_ENET_RXD ((ushort)0x0004) -#define PA_ENET_TXD ((ushort)0x0008) -#define PA_ENET_TCLK ((ushort)0x0200) -#define PA_ENET_RCLK ((ushort)0x0800) -#define PB_ENET_TENA ((uint)0x00002000) -#define PC_ENET_CLSN ((ushort)0x0040) -#define PC_ENET_RENA ((ushort)0x0080) - -#define SICR_ENET_MASK ((uint)0x0000ff00) -#define SICR_ENET_CLKRT ((uint)0x00003d00) -#endif - -#ifdef CONFIG_BSEIP -/* This ENET stuff is for the MPC823 with ethernet on SCC2. - * This is unique to the BSE ip-Engine board. - */ -#define PA_ENET_RXD ((ushort)0x0004) -#define PA_ENET_TXD ((ushort)0x0008) -#define PA_ENET_TCLK ((ushort)0x0100) -#define PA_ENET_RCLK ((ushort)0x0200) -#define PB_ENET_TENA ((uint)0x00002000) -#define PC_ENET_CLSN ((ushort)0x0040) -#define PC_ENET_RENA ((ushort)0x0080) - -/* BSE uses port B and C bits for PHY control also. -*/ -#define PB_BSE_POWERUP ((uint)0x00000004) -#define PB_BSE_FDXDIS ((uint)0x00008000) -#define PC_BSE_LOOPBACK ((ushort)0x0800) - -#define SICR_ENET_MASK ((uint)0x0000ff00) -#define SICR_ENET_CLKRT ((uint)0x00002c00) -#endif - -/* SCC Event register as used by Ethernet. -*/ -#define SCCE_ENET_GRA ((ushort)0x0080) /* Graceful stop complete */ -#define SCCE_ENET_TXE ((ushort)0x0010) /* Transmit Error */ -#define SCCE_ENET_RXF ((ushort)0x0008) /* Full frame received */ -#define SCCE_ENET_BSY ((ushort)0x0004) /* All incoming buffers full */ -#define SCCE_ENET_TXB ((ushort)0x0002) /* A buffer was transmitted */ -#define SCCE_ENET_RXB ((ushort)0x0001) /* A buffer was received */ - -/* SCC Mode Register (PMSR) as used by Ethernet. -*/ -#define SCC_PMSR_HBC ((ushort)0x8000) /* Enable heartbeat */ -#define SCC_PMSR_FC ((ushort)0x4000) /* Force collision */ -#define SCC_PMSR_RSH ((ushort)0x2000) /* Receive short frames */ -#define SCC_PMSR_IAM ((ushort)0x1000) /* Check individual hash */ -#define SCC_PMSR_ENCRC ((ushort)0x0800) /* Ethernet CRC mode */ -#define SCC_PMSR_PRO ((ushort)0x0200) /* Promiscuous mode */ -#define SCC_PMSR_BRO ((ushort)0x0100) /* Catch broadcast pkts */ -#define SCC_PMSR_SBT ((ushort)0x0080) /* Special backoff timer */ -#define SCC_PMSR_LPB ((ushort)0x0040) /* Set Loopback mode */ -#define SCC_PMSR_SIP ((ushort)0x0020) /* Sample Input Pins */ -#define SCC_PMSR_LCW ((ushort)0x0010) /* Late collision window */ -#define SCC_PMSR_NIB22 ((ushort)0x000a) /* Start frame search */ -#define SCC_PMSR_FDE ((ushort)0x0001) /* Full duplex enable */ - -/* Buffer descriptor control/status used by Ethernet receive. -*/ -#define BD_ENET_RX_EMPTY ((ushort)0x8000) -#define BD_ENET_RX_WRAP ((ushort)0x2000) -#define BD_ENET_RX_INTR ((ushort)0x1000) -#define BD_ENET_RX_LAST ((ushort)0x0800) -#define BD_ENET_RX_FIRST ((ushort)0x0400) -#define BD_ENET_RX_MISS ((ushort)0x0100) -#define BD_ENET_RX_LG ((ushort)0x0020) -#define BD_ENET_RX_NO ((ushort)0x0010) -#define BD_ENET_RX_SH ((ushort)0x0008) -#define BD_ENET_RX_CR ((ushort)0x0004) -#define BD_ENET_RX_OV ((ushort)0x0002) -#define BD_ENET_RX_CL ((ushort)0x0001) -#define BD_ENET_RX_STATS ((ushort)0x013f) /* All status bits */ - -/* Buffer descriptor control/status used by Ethernet transmit. -*/ -#define BD_ENET_TX_READY ((ushort)0x8000) -#define BD_ENET_TX_PAD ((ushort)0x4000) -#define BD_ENET_TX_WRAP ((ushort)0x2000) -#define BD_ENET_TX_INTR ((ushort)0x1000) -#define BD_ENET_TX_LAST ((ushort)0x0800) -#define BD_ENET_TX_TC ((ushort)0x0400) -#define BD_ENET_TX_DEF ((ushort)0x0200) -#define BD_ENET_TX_HB ((ushort)0x0100) -#define BD_ENET_TX_LC ((ushort)0x0080) -#define BD_ENET_TX_RL ((ushort)0x0040) -#define BD_ENET_TX_RCMASK ((ushort)0x003c) -#define BD_ENET_TX_UN ((ushort)0x0002) -#define BD_ENET_TX_CSL ((ushort)0x0001) -#define BD_ENET_TX_STATS ((ushort)0x03ff) /* All status bits */ - -/* SCC as UART -*/ -typedef struct scc_uart { - sccp_t scc_genscc; - uint scc_res1; /* Reserved */ - uint scc_res2; /* Reserved */ - ushort scc_maxidl; /* Maximum idle chars */ - ushort scc_idlc; /* temp idle counter */ - ushort scc_brkcr; /* Break count register */ - ushort scc_parec; /* receive parity error counter */ - ushort scc_frmec; /* receive framing error counter */ - ushort scc_nosec; /* receive noise counter */ - ushort scc_brkec; /* receive break condition counter */ - ushort scc_brkln; /* last received break length */ - ushort scc_uaddr1; /* UART address character 1 */ - ushort scc_uaddr2; /* UART address character 2 */ - ushort scc_rtemp; /* Temp storage */ - ushort scc_toseq; /* Transmit out of sequence char */ - ushort scc_char1; /* control character 1 */ - ushort scc_char2; /* control character 2 */ - ushort scc_char3; /* control character 3 */ - ushort scc_char4; /* control character 4 */ - ushort scc_char5; /* control character 5 */ - ushort scc_char6; /* control character 6 */ - ushort scc_char7; /* control character 7 */ - ushort scc_char8; /* control character 8 */ - ushort scc_rccm; /* receive control character mask */ - ushort scc_rccr; /* receive control character register */ - ushort scc_rlbc; /* receive last break character */ -} scc_uart_t; - -/* SCC Event and Mask registers when it is used as a UART. -*/ -#define UART_SCCM_GLR ((ushort)0x1000) -#define UART_SCCM_GLT ((ushort)0x0800) -#define UART_SCCM_AB ((ushort)0x0200) -#define UART_SCCM_IDL ((ushort)0x0100) -#define UART_SCCM_GRA ((ushort)0x0080) -#define UART_SCCM_BRKE ((ushort)0x0040) -#define UART_SCCM_BRKS ((ushort)0x0020) -#define UART_SCCM_CCR ((ushort)0x0008) -#define UART_SCCM_BSY ((ushort)0x0004) -#define UART_SCCM_TX ((ushort)0x0002) -#define UART_SCCM_RX ((ushort)0x0001) - -/* The SCC PMSR when used as a UART. -*/ -#define SCU_PMSR_FLC ((ushort)0x8000) -#define SCU_PMSR_SL ((ushort)0x4000) -#define SCU_PMSR_CL ((ushort)0x3000) -#define SCU_PMSR_UM ((ushort)0x0c00) -#define SCU_PMSR_FRZ ((ushort)0x0200) -#define SCU_PMSR_RZS ((ushort)0x0100) -#define SCU_PMSR_SYN ((ushort)0x0080) -#define SCU_PMSR_DRT ((ushort)0x0040) -#define SCU_PMSR_PEN ((ushort)0x0010) -#define SCU_PMSR_RPM ((ushort)0x000c) -#define SCU_PMSR_REVP ((ushort)0x0008) -#define SCU_PMSR_TPM ((ushort)0x0003) -#define SCU_PMSR_TEVP ((ushort)0x0003) - -/* CPM Transparent mode SCC. - */ -typedef struct scc_trans { - sccp_t st_genscc; - uint st_cpres; /* Preset CRC */ - uint st_cmask; /* Constant mask for CRC */ -} scc_trans_t; - -#define BD_SCC_TX_LAST ((ushort)0x0800) - - - -/* CPM interrupts. There are nearly 32 interrupts generated by CPM - * channels or devices. All of these are presented to the PPC core - * as a single interrupt. The CPM interrupt handler dispatches its - * own handlers, in a similar fashion to the PPC core handler. We - * use the table as defined in the manuals (i.e. no special high - * priority and SCC1 == SCCa, etc...). - */ -/* #define CPMVEC_NR 32 */ -/* #define CPMVEC_PIO_PC15 ((ushort)0x1f) */ -/* #define CPMVEC_SCC1 ((ushort)0x1e) */ -/* #define CPMVEC_SCC2 ((ushort)0x1d) */ -/* #define CPMVEC_SCC3 ((ushort)0x1c) */ -/* #define CPMVEC_SCC4 ((ushort)0x1b) */ -/* #define CPMVEC_PIO_PC14 ((ushort)0x1a) */ -/* #define CPMVEC_TIMER1 ((ushort)0x19) */ -/* #define CPMVEC_PIO_PC13 ((ushort)0x18) */ -/* #define CPMVEC_PIO_PC12 ((ushort)0x17) */ -/* #define CPMVEC_SDMA_CB_ERR ((ushort)0x16) */ -/* #define CPMVEC_IDMA1 ((ushort)0x15) */ -/* #define CPMVEC_IDMA2 ((ushort)0x14) */ -/* #define CPMVEC_TIMER2 ((ushort)0x12) */ -/* #define CPMVEC_RISCTIMER ((ushort)0x11) */ -/* #define CPMVEC_I2C ((ushort)0x10) */ -/* #define CPMVEC_PIO_PC11 ((ushort)0x0f) */ -/* #define CPMVEC_PIO_PC10 ((ushort)0x0e) */ -/* #define CPMVEC_TIMER3 ((ushort)0x0c) */ -/* #define CPMVEC_PIO_PC9 ((ushort)0x0b) */ -/* #define CPMVEC_PIO_PC8 ((ushort)0x0a) */ -/* #define CPMVEC_PIO_PC7 ((ushort)0x09) */ -/* #define CPMVEC_TIMER4 ((ushort)0x07) */ -/* #define CPMVEC_PIO_PC6 ((ushort)0x06) */ -/* #define CPMVEC_SPI ((ushort)0x05) */ -/* #define CPMVEC_SMC1 ((ushort)0x04) */ -/* #define CPMVEC_SMC2 ((ushort)0x03) */ -/* #define CPMVEC_PIO_PC5 ((ushort)0x02) */ -/* #define CPMVEC_PIO_PC4 ((ushort)0x01) */ -/* #define CPMVEC_ERROR ((ushort)0x00) */ - -extern void cpm_install_handler(int vec, void (*handler)(void *), void *dev_id); - -/* CPM interrupt configuration vector. -*/ -#define CICR_SCD_SCC4 ((uint)0x00c00000) /* SCC4 @ SCCd */ -#define CICR_SCC_SCC3 ((uint)0x00200000) /* SCC3 @ SCCc */ -#define CICR_SCB_SCC2 ((uint)0x00040000) /* SCC2 @ SCCb */ -#define CICR_SCA_SCC1 ((uint)0x00000000) /* SCC1 @ SCCa */ -#define CICR_IRL_MASK ((uint)0x0000e000) /* Core interrupt */ -#define CICR_HP_MASK ((uint)0x00001f00) /* Hi-pri int. */ -#define CICR_IEN ((uint)0x00000080) /* Int. enable */ -#define CICR_SPS ((uint)0x00000001) /* SCC Spread */ -#endif /* __CPM_360__ */ diff --git a/arch/m68knommu/include/asm/cputime.h b/arch/m68knommu/include/asm/cputime.h deleted file mode 100644 index a0c4a660878..00000000000 --- a/arch/m68knommu/include/asm/cputime.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __M68KNOMMU_CPUTIME_H -#define __M68KNOMMU_CPUTIME_H - -#include - -#endif /* __M68KNOMMU_CPUTIME_H */ diff --git a/arch/m68knommu/include/asm/current.h b/arch/m68knommu/include/asm/current.h deleted file mode 100644 index 53ee0f9f7ce..00000000000 --- a/arch/m68knommu/include/asm/current.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef _M68KNOMMU_CURRENT_H -#define _M68KNOMMU_CURRENT_H -/* - * current.h - * (C) Copyright 2000, Lineo, David McCullough - * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) - * - * rather than dedicate a register (as the m68k source does), we - * just keep a global, we should probably just change it all to be - * current and lose _current_task. - */ - -#include - -struct task_struct; - -static inline struct task_struct *get_current(void) -{ - return(current_thread_info()->task); -} - -#define current get_current() - -#endif /* _M68KNOMMU_CURRENT_H */ diff --git a/arch/m68knommu/include/asm/dbg.h b/arch/m68knommu/include/asm/dbg.h deleted file mode 100644 index 27af3270f67..00000000000 --- a/arch/m68knommu/include/asm/dbg.h +++ /dev/null @@ -1,6 +0,0 @@ -#define DEBUG 1 -#ifdef CONFIG_COLDFIRE -#define BREAK asm volatile ("halt") -#else -#define BREAK *(volatile unsigned char *)0xdeadbee0 = 0 -#endif diff --git a/arch/m68knommu/include/asm/delay.h b/arch/m68knommu/include/asm/delay.h deleted file mode 100644 index 55cbd6294ab..00000000000 --- a/arch/m68knommu/include/asm/delay.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef _M68KNOMMU_DELAY_H -#define _M68KNOMMU_DELAY_H - -/* - * Copyright (C) 1994 Hamish Macdonald - * Copyright (C) 2004 Greg Ungerer - */ - -#include - -static inline void __delay(unsigned long loops) -{ -#if defined(CONFIG_COLDFIRE) - /* The coldfire runs this loop at significantly different speeds - * depending upon long word alignment or not. We'll pad it to - * long word alignment which is the faster version. - * The 0x4a8e is of course a 'tstl %fp' instruction. This is better - * than using a NOP (0x4e71) instruction because it executes in one - * cycle not three and doesn't allow for an arbitary delay waiting - * for bus cycles to finish. Also fp/a6 isn't likely to cause a - * stall waiting for the register to become valid if such is added - * to the coldfire at some stage. - */ - __asm__ __volatile__ ( ".balignw 4, 0x4a8e\n\t" - "1: subql #1, %0\n\t" - "jcc 1b" - : "=d" (loops) : "0" (loops)); -#else - __asm__ __volatile__ ( "1: subql #1, %0\n\t" - "jcc 1b" - : "=d" (loops) : "0" (loops)); -#endif -} - -/* - * Ideally we use a 32*32->64 multiply to calculate the number of - * loop iterations, but the older standard 68k and ColdFire do not - * have this instruction. So for them we have a clsoe approximation - * loop using 32*32->32 multiplies only. This calculation based on - * the ARM version of delay. - * - * We want to implement: - * - * loops = (usecs * 0x10c6 * HZ * loops_per_jiffy) / 2^32 - */ - -#define HZSCALE (268435456 / (1000000/HZ)) - -extern unsigned long loops_per_jiffy; - -static inline void _udelay(unsigned long usecs) -{ -#if defined(CONFIG_M68328) || defined(CONFIG_M68EZ328) || \ - defined(CONFIG_M68VZ328) || defined(CONFIG_M68360) || \ - defined(CONFIG_COLDFIRE) - __delay((((usecs * HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6); -#else - unsigned long tmp; - - usecs *= 4295; /* 2**32 / 1000000 */ - __asm__ ("mulul %2,%0:%1" - : "=d" (usecs), "=d" (tmp) - : "d" (usecs), "1" (loops_per_jiffy*HZ)); - __delay(usecs); -#endif -} - -/* - * Moved the udelay() function into library code, no longer inlined. - * I had to change the algorithm because we are overflowing now on - * the faster ColdFire parts. The code is a little bigger, so it makes - * sense to library it. - */ -extern void udelay(unsigned long usecs); - -#endif /* defined(_M68KNOMMU_DELAY_H) */ diff --git a/arch/m68knommu/include/asm/device.h b/arch/m68knommu/include/asm/device.h deleted file mode 100644 index d8f9872b0e2..00000000000 --- a/arch/m68knommu/include/asm/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/arch/m68knommu/include/asm/div64.h b/arch/m68knommu/include/asm/div64.h deleted file mode 100644 index 6cd978cefb2..00000000000 --- a/arch/m68knommu/include/asm/div64.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/dma-mapping.h b/arch/m68knommu/include/asm/dma-mapping.h deleted file mode 100644 index 6aeab18e58b..00000000000 --- a/arch/m68knommu/include/asm/dma-mapping.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _M68KNOMMU_DMA_MAPPING_H -#define _M68KNOMMU_DMA_MAPPING_H - -#ifdef CONFIG_PCI -#include -#else -#include -#endif - -#endif /* _M68KNOMMU_DMA_MAPPING_H */ diff --git a/arch/m68knommu/include/asm/dma.h b/arch/m68knommu/include/asm/dma.h deleted file mode 100644 index 939a0205621..00000000000 --- a/arch/m68knommu/include/asm/dma.h +++ /dev/null @@ -1,494 +0,0 @@ -#ifndef _M68K_DMA_H -#define _M68K_DMA_H 1 - -//#define DMA_DEBUG 1 - - -#ifdef CONFIG_COLDFIRE -/* - * ColdFire DMA Model: - * ColdFire DMA supports two forms of DMA: Single and Dual address. Single - * address mode emits a source address, and expects that the device will either - * pick up the data (DMA READ) or source data (DMA WRITE). This implies that - * the device will place data on the correct byte(s) of the data bus, as the - * memory transactions are always 32 bits. This implies that only 32 bit - * devices will find single mode transfers useful. Dual address DMA mode - * performs two cycles: source read and destination write. ColdFire will - * align the data so that the device will always get the correct bytes, thus - * is useful for 8 and 16 bit devices. This is the mode that is supported - * below. - * - * AUG/22/2000 : added support for 32-bit Dual-Address-Mode (K) 2000 - * Oliver Kamphenkel (O.Kamphenkel@tu-bs.de) - * - * AUG/25/2000 : addad support for 8, 16 and 32-bit Single-Address-Mode (K)2000 - * Oliver Kamphenkel (O.Kamphenkel@tu-bs.de) - * - * APR/18/2002 : added proper support for MCF5272 DMA controller. - * Arthur Shipkowski (art@videon-central.com) - */ - -#include -#include -#include - -/* - * Set number of channels of DMA on ColdFire for different implementations. - */ -#if defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) || \ - defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) -#define MAX_M68K_DMA_CHANNELS 4 -#elif defined(CONFIG_M5272) -#define MAX_M68K_DMA_CHANNELS 1 -#elif defined(CONFIG_M532x) -#define MAX_M68K_DMA_CHANNELS 0 -#else -#define MAX_M68K_DMA_CHANNELS 2 -#endif - -extern unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS]; -extern unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS]; - -#if !defined(CONFIG_M5272) -#define DMA_MODE_WRITE_BIT 0x01 /* Memory/IO to IO/Memory select */ -#define DMA_MODE_WORD_BIT 0x02 /* 8 or 16 bit transfers */ -#define DMA_MODE_LONG_BIT 0x04 /* or 32 bit transfers */ -#define DMA_MODE_SINGLE_BIT 0x08 /* single-address-mode */ - -/* I/O to memory, 8 bits, mode */ -#define DMA_MODE_READ 0 -/* memory to I/O, 8 bits, mode */ -#define DMA_MODE_WRITE 1 -/* I/O to memory, 16 bits, mode */ -#define DMA_MODE_READ_WORD 2 -/* memory to I/O, 16 bits, mode */ -#define DMA_MODE_WRITE_WORD 3 -/* I/O to memory, 32 bits, mode */ -#define DMA_MODE_READ_LONG 4 -/* memory to I/O, 32 bits, mode */ -#define DMA_MODE_WRITE_LONG 5 -/* I/O to memory, 8 bits, single-address-mode */ -#define DMA_MODE_READ_SINGLE 8 -/* memory to I/O, 8 bits, single-address-mode */ -#define DMA_MODE_WRITE_SINGLE 9 -/* I/O to memory, 16 bits, single-address-mode */ -#define DMA_MODE_READ_WORD_SINGLE 10 -/* memory to I/O, 16 bits, single-address-mode */ -#define DMA_MODE_WRITE_WORD_SINGLE 11 -/* I/O to memory, 32 bits, single-address-mode */ -#define DMA_MODE_READ_LONG_SINGLE 12 -/* memory to I/O, 32 bits, single-address-mode */ -#define DMA_MODE_WRITE_LONG_SINGLE 13 - -#else /* CONFIG_M5272 is defined */ - -/* Source static-address mode */ -#define DMA_MODE_SRC_SA_BIT 0x01 -/* Two bits to select between all four modes */ -#define DMA_MODE_SSIZE_MASK 0x06 -/* Offset to shift bits in */ -#define DMA_MODE_SSIZE_OFF 0x01 -/* Destination static-address mode */ -#define DMA_MODE_DES_SA_BIT 0x10 -/* Two bits to select between all four modes */ -#define DMA_MODE_DSIZE_MASK 0x60 -/* Offset to shift bits in */ -#define DMA_MODE_DSIZE_OFF 0x05 -/* Size modifiers */ -#define DMA_MODE_SIZE_LONG 0x00 -#define DMA_MODE_SIZE_BYTE 0x01 -#define DMA_MODE_SIZE_WORD 0x02 -#define DMA_MODE_SIZE_LINE 0x03 - -/* - * Aliases to help speed quick ports; these may be suboptimal, however. They - * do not include the SINGLE mode modifiers since the MCF5272 does not have a - * mode where the device is in control of its addressing. - */ - -/* I/O to memory, 8 bits, mode */ -#define DMA_MODE_READ ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT) -/* memory to I/O, 8 bits, mode */ -#define DMA_MODE_WRITE ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT) -/* I/O to memory, 16 bits, mode */ -#define DMA_MODE_READ_WORD ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT) -/* memory to I/O, 16 bits, mode */ -#define DMA_MODE_WRITE_WORD ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT) -/* I/O to memory, 32 bits, mode */ -#define DMA_MODE_READ_LONG ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT) -/* memory to I/O, 32 bits, mode */ -#define DMA_MODE_WRITE_LONG ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT) - -#endif /* !defined(CONFIG_M5272) */ - -#if !defined(CONFIG_M5272) -/* enable/disable a specific DMA channel */ -static __inline__ void enable_dma(unsigned int dmanr) -{ - volatile unsigned short *dmawp; - -#ifdef DMA_DEBUG - printk("enable_dma(dmanr=%d)\n", dmanr); -#endif - - dmawp = (unsigned short *) dma_base_addr[dmanr]; - dmawp[MCFDMA_DCR] |= MCFDMA_DCR_EEXT; -} - -static __inline__ void disable_dma(unsigned int dmanr) -{ - volatile unsigned short *dmawp; - volatile unsigned char *dmapb; - -#ifdef DMA_DEBUG - printk("disable_dma(dmanr=%d)\n", dmanr); -#endif - - dmawp = (unsigned short *) dma_base_addr[dmanr]; - dmapb = (unsigned char *) dma_base_addr[dmanr]; - - /* Turn off external requests, and stop any DMA in progress */ - dmawp[MCFDMA_DCR] &= ~MCFDMA_DCR_EEXT; - dmapb[MCFDMA_DSR] = MCFDMA_DSR_DONE; -} - -/* - * Clear the 'DMA Pointer Flip Flop'. - * Write 0 for LSB/MSB, 1 for MSB/LSB access. - * Use this once to initialize the FF to a known state. - * After that, keep track of it. :-) - * --- In order to do that, the DMA routines below should --- - * --- only be used while interrupts are disabled! --- - * - * This is a NOP for ColdFire. Provide a stub for compatibility. - */ -static __inline__ void clear_dma_ff(unsigned int dmanr) -{ -} - -/* set mode (above) for a specific DMA channel */ -static __inline__ void set_dma_mode(unsigned int dmanr, char mode) -{ - - volatile unsigned char *dmabp; - volatile unsigned short *dmawp; - -#ifdef DMA_DEBUG - printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode); -#endif - - dmabp = (unsigned char *) dma_base_addr[dmanr]; - dmawp = (unsigned short *) dma_base_addr[dmanr]; - - // Clear config errors - dmabp[MCFDMA_DSR] = MCFDMA_DSR_DONE; - - // Set command register - dmawp[MCFDMA_DCR] = - MCFDMA_DCR_INT | // Enable completion irq - MCFDMA_DCR_CS | // Force one xfer per request - MCFDMA_DCR_AA | // Enable auto alignment - // single-address-mode - ((mode & DMA_MODE_SINGLE_BIT) ? MCFDMA_DCR_SAA : 0) | - // sets s_rw (-> r/w) high if Memory to I/0 - ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_S_RW : 0) | - // Memory to I/O or I/O to Memory - ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_SINC : MCFDMA_DCR_DINC) | - // 32 bit, 16 bit or 8 bit transfers - ((mode & DMA_MODE_WORD_BIT) ? MCFDMA_DCR_SSIZE_WORD : - ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_SSIZE_LONG : - MCFDMA_DCR_SSIZE_BYTE)) | - ((mode & DMA_MODE_WORD_BIT) ? MCFDMA_DCR_DSIZE_WORD : - ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_DSIZE_LONG : - MCFDMA_DCR_DSIZE_BYTE)); - -#ifdef DEBUG_DMA - printk("%s(%d): dmanr=%d DSR[%x]=%x DCR[%x]=%x\n", __FILE__, __LINE__, - dmanr, (int) &dmabp[MCFDMA_DSR], dmabp[MCFDMA_DSR], - (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR]); -#endif -} - -/* Set transfer address for specific DMA channel */ -static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) -{ - volatile unsigned short *dmawp; - volatile unsigned int *dmalp; - -#ifdef DMA_DEBUG - printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a); -#endif - - dmawp = (unsigned short *) dma_base_addr[dmanr]; - dmalp = (unsigned int *) dma_base_addr[dmanr]; - - // Determine which address registers are used for memory/device accesses - if (dmawp[MCFDMA_DCR] & MCFDMA_DCR_SINC) { - // Source incrementing, must be memory - dmalp[MCFDMA_SAR] = a; - // Set dest address, must be device - dmalp[MCFDMA_DAR] = dma_device_address[dmanr]; - } else { - // Destination incrementing, must be memory - dmalp[MCFDMA_DAR] = a; - // Set source address, must be device - dmalp[MCFDMA_SAR] = dma_device_address[dmanr]; - } - -#ifdef DEBUG_DMA - printk("%s(%d): dmanr=%d DCR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n", - __FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR], - (int) &dmalp[MCFDMA_SAR], dmalp[MCFDMA_SAR], - (int) &dmalp[MCFDMA_DAR], dmalp[MCFDMA_DAR]); -#endif -} - -/* - * Specific for Coldfire - sets device address. - * Should be called after the mode set call, and before set DMA address. - */ -static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a) -{ -#ifdef DMA_DEBUG - printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a); -#endif - - dma_device_address[dmanr] = a; -} - -/* - * NOTE 2: "count" represents _bytes_. - */ -static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) -{ - volatile unsigned short *dmawp; - -#ifdef DMA_DEBUG - printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count); -#endif - - dmawp = (unsigned short *) dma_base_addr[dmanr]; - dmawp[MCFDMA_BCR] = (unsigned short)count; -} - -/* - * Get DMA residue count. After a DMA transfer, this - * should return zero. Reading this while a DMA transfer is - * still in progress will return unpredictable results. - * Otherwise, it returns the number of _bytes_ left to transfer. - */ -static __inline__ int get_dma_residue(unsigned int dmanr) -{ - volatile unsigned short *dmawp; - unsigned short count; - -#ifdef DMA_DEBUG - printk("get_dma_residue(dmanr=%d)\n", dmanr); -#endif - - dmawp = (unsigned short *) dma_base_addr[dmanr]; - count = dmawp[MCFDMA_BCR]; - return((int) count); -} -#else /* CONFIG_M5272 is defined */ - -/* - * The MCF5272 DMA controller is very different than the controller defined above - * in terms of register mapping. For instance, with the exception of the 16-bit - * interrupt register (IRQ#85, for reference), all of the registers are 32-bit. - * - * The big difference, however, is the lack of device-requested DMA. All modes - * are dual address transfer, and there is no 'device' setup or direction bit. - * You can DMA between a device and memory, between memory and memory, or even between - * two devices directly, with any combination of incrementing and non-incrementing - * addresses you choose. This puts a crimp in distinguishing between the 'device - * address' set up by set_dma_device_addr. - * - * Therefore, there are two options. One is to use set_dma_addr and set_dma_device_addr, - * which will act exactly as above in -- it will look to see if the source is set to - * autoincrement, and if so it will make the source use the set_dma_addr value and the - * destination the set_dma_device_addr value. Otherwise the source will be set to the - * set_dma_device_addr value and the destination will get the set_dma_addr value. - * - * The other is to use the provided set_dma_src_addr and set_dma_dest_addr functions - * and make it explicit. Depending on what you're doing, one of these two should work - * for you, but don't mix them in the same transfer setup. - */ - -/* enable/disable a specific DMA channel */ -static __inline__ void enable_dma(unsigned int dmanr) -{ - volatile unsigned int *dmalp; - -#ifdef DMA_DEBUG - printk("enable_dma(dmanr=%d)\n", dmanr); -#endif - - dmalp = (unsigned int *) dma_base_addr[dmanr]; - dmalp[MCFDMA_DMR] |= MCFDMA_DMR_EN; -} - -static __inline__ void disable_dma(unsigned int dmanr) -{ - volatile unsigned int *dmalp; - -#ifdef DMA_DEBUG - printk("disable_dma(dmanr=%d)\n", dmanr); -#endif - - dmalp = (unsigned int *) dma_base_addr[dmanr]; - - /* Turn off external requests, and stop any DMA in progress */ - dmalp[MCFDMA_DMR] &= ~MCFDMA_DMR_EN; - dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET; -} - -/* - * Clear the 'DMA Pointer Flip Flop'. - * Write 0 for LSB/MSB, 1 for MSB/LSB access. - * Use this once to initialize the FF to a known state. - * After that, keep track of it. :-) - * --- In order to do that, the DMA routines below should --- - * --- only be used while interrupts are disabled! --- - * - * This is a NOP for ColdFire. Provide a stub for compatibility. - */ -static __inline__ void clear_dma_ff(unsigned int dmanr) -{ -} - -/* set mode (above) for a specific DMA channel */ -static __inline__ void set_dma_mode(unsigned int dmanr, char mode) -{ - - volatile unsigned int *dmalp; - volatile unsigned short *dmawp; - -#ifdef DMA_DEBUG - printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode); -#endif - dmalp = (unsigned int *) dma_base_addr[dmanr]; - dmawp = (unsigned short *) dma_base_addr[dmanr]; - - // Clear config errors - dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET; - - // Set command register - dmalp[MCFDMA_DMR] = - MCFDMA_DMR_RQM_DUAL | // Mandatory Request Mode setting - MCFDMA_DMR_DSTT_SD | // Set up addressing types; set to supervisor-data. - MCFDMA_DMR_SRCT_SD | // Set up addressing types; set to supervisor-data. - // source static-address-mode - ((mode & DMA_MODE_SRC_SA_BIT) ? MCFDMA_DMR_SRCM_SA : MCFDMA_DMR_SRCM_IA) | - // dest static-address-mode - ((mode & DMA_MODE_DES_SA_BIT) ? MCFDMA_DMR_DSTM_SA : MCFDMA_DMR_DSTM_IA) | - // burst, 32 bit, 16 bit or 8 bit transfers are separately configurable on the MCF5272 - (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_DSTS_OFF) | - (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_SRCS_OFF); - - dmawp[MCFDMA_DIR] |= MCFDMA_DIR_ASCEN; /* Enable completion interrupts */ - -#ifdef DEBUG_DMA - printk("%s(%d): dmanr=%d DMR[%x]=%x DIR[%x]=%x\n", __FILE__, __LINE__, - dmanr, (int) &dmalp[MCFDMA_DMR], dmabp[MCFDMA_DMR], - (int) &dmawp[MCFDMA_DIR], dmawp[MCFDMA_DIR]); -#endif -} - -/* Set transfer address for specific DMA channel */ -static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) -{ - volatile unsigned int *dmalp; - -#ifdef DMA_DEBUG - printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a); -#endif - - dmalp = (unsigned int *) dma_base_addr[dmanr]; - - // Determine which address registers are used for memory/device accesses - if (dmalp[MCFDMA_DMR] & MCFDMA_DMR_SRCM) { - // Source incrementing, must be memory - dmalp[MCFDMA_DSAR] = a; - // Set dest address, must be device - dmalp[MCFDMA_DDAR] = dma_device_address[dmanr]; - } else { - // Destination incrementing, must be memory - dmalp[MCFDMA_DDAR] = a; - // Set source address, must be device - dmalp[MCFDMA_DSAR] = dma_device_address[dmanr]; - } - -#ifdef DEBUG_DMA - printk("%s(%d): dmanr=%d DMR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n", - __FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DMR], dmawp[MCFDMA_DMR], - (int) &dmalp[MCFDMA_DSAR], dmalp[MCFDMA_DSAR], - (int) &dmalp[MCFDMA_DDAR], dmalp[MCFDMA_DDAR]); -#endif -} - -/* - * Specific for Coldfire - sets device address. - * Should be called after the mode set call, and before set DMA address. - */ -static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a) -{ -#ifdef DMA_DEBUG - printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a); -#endif - - dma_device_address[dmanr] = a; -} - -/* - * NOTE 2: "count" represents _bytes_. - * - * NOTE 3: While a 32-bit register, "count" is only a maximum 24-bit value. - */ -static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) -{ - volatile unsigned int *dmalp; - -#ifdef DMA_DEBUG - printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count); -#endif - - dmalp = (unsigned int *) dma_base_addr[dmanr]; - dmalp[MCFDMA_DBCR] = count; -} - -/* - * Get DMA residue count. After a DMA transfer, this - * should return zero. Reading this while a DMA transfer is - * still in progress will return unpredictable results. - * Otherwise, it returns the number of _bytes_ left to transfer. - */ -static __inline__ int get_dma_residue(unsigned int dmanr) -{ - volatile unsigned int *dmalp; - unsigned int count; - -#ifdef DMA_DEBUG - printk("get_dma_residue(dmanr=%d)\n", dmanr); -#endif - - dmalp = (unsigned int *) dma_base_addr[dmanr]; - count = dmalp[MCFDMA_DBCR]; - return(count); -} - -#endif /* !defined(CONFIG_M5272) */ -#endif /* CONFIG_COLDFIRE */ - -#define MAX_DMA_CHANNELS 8 - -/* Don't define MAX_DMA_ADDRESS; it's useless on the m68k/coldfire and any - occurrence should be flagged as an error. */ -/* under 2.4 it is actually needed by the new bootmem allocator */ -#define MAX_DMA_ADDRESS PAGE_OFFSET - -/* These are in kernel/dma.c: */ -extern int request_dma(unsigned int dmanr, const char *device_id); /* reserve a DMA channel */ -extern void free_dma(unsigned int dmanr); /* release it again */ - -#endif /* _M68K_DMA_H */ diff --git a/arch/m68knommu/include/asm/elf.h b/arch/m68knommu/include/asm/elf.h deleted file mode 100644 index b8046837f38..00000000000 --- a/arch/m68knommu/include/asm/elf.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef __ASMm68k_ELF_H -#define __ASMm68k_ELF_H - -/* - * ELF register definitions.. - */ - -#include -#include - -/* - * 68k ELF relocation types - */ -#define R_68K_NONE 0 -#define R_68K_32 1 -#define R_68K_16 2 -#define R_68K_8 3 -#define R_68K_PC32 4 -#define R_68K_PC16 5 -#define R_68K_PC8 6 -#define R_68K_GOT32 7 -#define R_68K_GOT16 8 -#define R_68K_GOT8 9 -#define R_68K_GOT32O 10 -#define R_68K_GOT16O 11 -#define R_68K_GOT8O 12 -#define R_68K_PLT32 13 -#define R_68K_PLT16 14 -#define R_68K_PLT8 15 -#define R_68K_PLT32O 16 -#define R_68K_PLT16O 17 -#define R_68K_PLT8O 18 -#define R_68K_COPY 19 -#define R_68K_GLOB_DAT 20 -#define R_68K_JMP_SLOT 21 -#define R_68K_RELATIVE 22 - -typedef unsigned long elf_greg_t; - -#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t)) -typedef elf_greg_t elf_gregset_t[ELF_NGREG]; - -typedef struct user_m68kfp_struct elf_fpregset_t; - -/* - * This is used to ensure we don't load something for the wrong architecture. - */ -#define elf_check_arch(x) ((x)->e_machine == EM_68K) - -/* - * These are used to set parameters in the core dumps. - */ -#define ELF_CLASS ELFCLASS32 -#define ELF_DATA ELFDATA2MSB -#define ELF_ARCH EM_68K - -/* For SVR4/m68k the function pointer to be registered with `atexit' is - passed in %a1. Although my copy of the ABI has no such statement, it - is actually used on ASV. */ -#define ELF_PLAT_INIT(_r, load_addr) _r->a1 = 0 - -#define USE_ELF_CORE_DUMP -#define ELF_EXEC_PAGESIZE 4096 - -/* This is the location that an ET_DYN program is loaded if exec'ed. Typical - use of this is to invoke "./ld.so someprog" to test out a new version of - the loader. We need to make sure that it is out of the way of the program - that it will "exec", and that there is sufficient room for the brk. */ - -#define ELF_ET_DYN_BASE 0xD0000000UL - -#define ELF_CORE_COPY_REGS(pr_reg, regs) \ - /* Bleech. */ \ - pr_reg[0] = regs->d1; \ - pr_reg[1] = regs->d2; \ - pr_reg[2] = regs->d3; \ - pr_reg[3] = regs->d4; \ - pr_reg[4] = regs->d5; \ - pr_reg[7] = regs->a0; \ - pr_reg[8] = regs->a1; \ - pr_reg[14] = regs->d0; \ - pr_reg[15] = rdusp(); \ - pr_reg[16] = 0 /* regs->orig_d0 */; \ - pr_reg[17] = regs->sr; \ - pr_reg[18] = regs->pc; \ - /* pr_reg[19] = (regs->format << 12) | regs->vector; */ \ - { \ - struct switch_stack *sw = ((struct switch_stack *)regs) - 1; \ - pr_reg[5] = sw->d6; \ - pr_reg[6] = sw->d7; \ - pr_reg[10] = sw->a3; \ - pr_reg[11] = sw->a4; \ - pr_reg[12] = sw->a5; \ - pr_reg[13] = sw->a6; \ - } - -/* This yields a mask that user programs can use to figure out what - instruction set this cpu supports. */ - -#define ELF_HWCAP (0) - -/* This yields a string that ld.so will use to load implementation - specific libraries for optimization. This is more specific in - intent than poking at uname or /proc/cpuinfo. */ - -#define ELF_PLATFORM (NULL) - -#define SET_PERSONALITY(ex) set_personality(PER_LINUX) - -#endif diff --git a/arch/m68knommu/include/asm/elia.h b/arch/m68knommu/include/asm/elia.h deleted file mode 100644 index e037d4e2de3..00000000000 --- a/arch/m68knommu/include/asm/elia.h +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************/ - -/* - * elia.h -- Lineo (formerly Moreton Bay) eLIA platform support. - * - * (C) Copyright 1999-2000, Moreton Bay (www.moreton.com.au) - * (C) Copyright 1999-2000, Lineo (www.lineo.com) - */ - -/****************************************************************************/ -#ifndef elia_h -#define elia_h -/****************************************************************************/ - -#include - -#ifdef CONFIG_eLIA - -/* - * The serial port DTR and DCD lines are also on the Parallel I/O - * as well, so define those too. - */ - -#define eLIA_DCD1 0x0001 -#define eLIA_DCD0 0x0002 -#define eLIA_DTR1 0x0004 -#define eLIA_DTR0 0x0008 - -#define eLIA_PCIRESET 0x0020 - -/* - * Kernel macros to set and unset the LEDs. - */ -#ifndef __ASSEMBLY__ -extern unsigned short ppdata; -#endif /* __ASSEMBLY__ */ - -#endif /* CONFIG_eLIA */ - -/****************************************************************************/ -#endif /* elia_h */ diff --git a/arch/m68knommu/include/asm/emergency-restart.h b/arch/m68knommu/include/asm/emergency-restart.h deleted file mode 100644 index 108d8c48e42..00000000000 --- a/arch/m68knommu/include/asm/emergency-restart.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_EMERGENCY_RESTART_H -#define _ASM_EMERGENCY_RESTART_H - -#include - -#endif /* _ASM_EMERGENCY_RESTART_H */ diff --git a/arch/m68knommu/include/asm/entry.h b/arch/m68knommu/include/asm/entry.h deleted file mode 100644 index c2553d26273..00000000000 --- a/arch/m68knommu/include/asm/entry.h +++ /dev/null @@ -1,182 +0,0 @@ -#ifndef __M68KNOMMU_ENTRY_H -#define __M68KNOMMU_ENTRY_H - -#include -#include - -/* - * Stack layout in 'ret_from_exception': - * - * This allows access to the syscall arguments in registers d1-d5 - * - * 0(sp) - d1 - * 4(sp) - d2 - * 8(sp) - d3 - * C(sp) - d4 - * 10(sp) - d5 - * 14(sp) - a0 - * 18(sp) - a1 - * 1C(sp) - a2 - * 20(sp) - d0 - * 24(sp) - orig_d0 - * 28(sp) - stack adjustment - * 2C(sp) - [ sr ] [ format & vector ] - * 2E(sp) - [ pc-hiword ] [ sr ] - * 30(sp) - [ pc-loword ] [ pc-hiword ] - * 32(sp) - [ format & vector ] [ pc-loword ] - * ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ - * M68K COLDFIRE - */ - -#define ALLOWINT 0xf8ff - -#ifdef __ASSEMBLY__ - -/* process bits for task_struct.flags */ -PF_TRACESYS_OFF = 3 -PF_TRACESYS_BIT = 5 -PF_PTRACED_OFF = 3 -PF_PTRACED_BIT = 4 -PF_DTRACE_OFF = 1 -PF_DTRACE_BIT = 5 - -LENOSYS = 38 - -#define SWITCH_STACK_SIZE (6*4+4) /* Includes return address */ - -/* - * This defines the normal kernel pt-regs layout. - * - * regs are a2-a6 and d6-d7 preserved by C code - * the kernel doesn't mess with usp unless it needs to - */ - -#ifdef CONFIG_COLDFIRE -/* - * This is made a little more tricky on the ColdFire. There is no - * separate kernel and user stack pointers. Need to artificially - * construct a usp in software... When doing this we need to disable - * interrupts, otherwise bad things could happen. - */ -.macro SAVE_ALL - move #0x2700,%sr /* disable intrs */ - btst #5,%sp@(2) /* from user? */ - bnes 6f /* no, skip */ - movel %sp,sw_usp /* save user sp */ - addql #8,sw_usp /* remove exception */ - movel sw_ksp,%sp /* kernel sp */ - subql #8,%sp /* room for exception */ - clrl %sp@- /* stkadj */ - movel %d0,%sp@- /* orig d0 */ - movel %d0,%sp@- /* d0 */ - lea %sp@(-32),%sp /* space for 8 regs */ - moveml %d1-%d5/%a0-%a2,%sp@ - movel sw_usp,%a0 /* get usp */ - movel %a0@-,%sp@(PT_PC) /* copy exception program counter */ - movel %a0@-,%sp@(PT_FORMATVEC)/* copy exception format/vector/sr */ - bra 7f - 6: - clrl %sp@- /* stkadj */ - movel %d0,%sp@- /* orig d0 */ - movel %d0,%sp@- /* d0 */ - lea %sp@(-32),%sp /* space for 8 regs */ - moveml %d1-%d5/%a0-%a2,%sp@ - 7: -.endm - -.macro RESTORE_ALL - btst #5,%sp@(PT_SR) /* going user? */ - bnes 8f /* no, skip */ - move #0x2700,%sr /* disable intrs */ - movel sw_usp,%a0 /* get usp */ - movel %sp@(PT_PC),%a0@- /* copy exception program counter */ - movel %sp@(PT_FORMATVEC),%a0@-/* copy exception format/vector/sr */ - moveml %sp@,%d1-%d5/%a0-%a2 - lea %sp@(32),%sp /* space for 8 regs */ - movel %sp@+,%d0 - addql #4,%sp /* orig d0 */ - addl %sp@+,%sp /* stkadj */ - addql #8,%sp /* remove exception */ - movel %sp,sw_ksp /* save ksp */ - subql #8,sw_usp /* set exception */ - movel sw_usp,%sp /* restore usp */ - rte - 8: - moveml %sp@,%d1-%d5/%a0-%a2 - lea %sp@(32),%sp /* space for 8 regs */ - movel %sp@+,%d0 - addql #4,%sp /* orig d0 */ - addl %sp@+,%sp /* stkadj */ - rte -.endm - -/* - * Quick exception save, use current stack only. - */ -.macro SAVE_LOCAL - move #0x2700,%sr /* disable intrs */ - clrl %sp@- /* stkadj */ - movel %d0,%sp@- /* orig d0 */ - movel %d0,%sp@- /* d0 */ - lea %sp@(-32),%sp /* space for 8 regs */ - moveml %d1-%d5/%a0-%a2,%sp@ -.endm - -.macro RESTORE_LOCAL - moveml %sp@,%d1-%d5/%a0-%a2 - lea %sp@(32),%sp /* space for 8 regs */ - movel %sp@+,%d0 - addql #4,%sp /* orig d0 */ - addl %sp@+,%sp /* stkadj */ - rte -.endm - -.macro SAVE_SWITCH_STACK - lea %sp@(-24),%sp /* 6 regs */ - moveml %a3-%a6/%d6-%d7,%sp@ -.endm - -.macro RESTORE_SWITCH_STACK - moveml %sp@,%a3-%a6/%d6-%d7 - lea %sp@(24),%sp /* 6 regs */ -.endm - -/* - * Software copy of the user and kernel stack pointers... Ugh... - * Need these to get around ColdFire not having separate kernel - * and user stack pointers. - */ -.globl sw_usp -.globl sw_ksp - -#else /* !CONFIG_COLDFIRE */ - -/* - * Standard 68k interrupt entry and exit macros. - */ -.macro SAVE_ALL - clrl %sp@- /* stkadj */ - movel %d0,%sp@- /* orig d0 */ - movel %d0,%sp@- /* d0 */ - moveml %d1-%d5/%a0-%a2,%sp@- -.endm - -.macro RESTORE_ALL - moveml %sp@+,%a0-%a2/%d1-%d5 - movel %sp@+,%d0 - addql #4,%sp /* orig d0 */ - addl %sp@+,%sp /* stkadj */ - rte -.endm - -.macro SAVE_SWITCH_STACK - moveml %a3-%a6/%d6-%d7,%sp@- -.endm - -.macro RESTORE_SWITCH_STACK - moveml %sp@+,%a3-%a6/%d6-%d7 -.endm - -#endif /* !CONFIG_COLDFIRE */ -#endif /* __ASSEMBLY__ */ -#endif /* __M68KNOMMU_ENTRY_H */ diff --git a/arch/m68knommu/include/asm/errno.h b/arch/m68knommu/include/asm/errno.h deleted file mode 100644 index 7e8c22b9a5e..00000000000 --- a/arch/m68knommu/include/asm/errno.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/fb.h b/arch/m68knommu/include/asm/fb.h deleted file mode 100644 index c7df3803099..00000000000 --- a/arch/m68knommu/include/asm/fb.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _ASM_FB_H_ -#define _ASM_FB_H_ -#include - -#define fb_pgprotect(...) do {} while (0) - -static inline int fb_is_primary_device(struct fb_info *info) -{ - return 0; -} - -#endif /* _ASM_FB_H_ */ diff --git a/arch/m68knommu/include/asm/fcntl.h b/arch/m68knommu/include/asm/fcntl.h deleted file mode 100644 index f6a552cda4c..00000000000 --- a/arch/m68knommu/include/asm/fcntl.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/flat.h b/arch/m68knommu/include/asm/flat.h deleted file mode 100644 index 814b5174a8e..00000000000 --- a/arch/m68knommu/include/asm/flat.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * include/asm-m68knommu/flat.h -- uClinux flat-format executables - */ - -#ifndef __M68KNOMMU_FLAT_H__ -#define __M68KNOMMU_FLAT_H__ - -#define flat_stack_align(sp) /* nothing needed */ -#define flat_argvp_envp_on_stack() 1 -#define flat_old_ram_flag(flags) (flags) -#define flat_reloc_valid(reloc, size) ((reloc) <= (size)) -#define flat_get_addr_from_rp(rp, relval, flags, p) get_unaligned(rp) -#define flat_put_addr_at_rp(rp, val, relval) put_unaligned(val,rp) -#define flat_get_relocate_addr(rel) (rel) -#define flat_set_persistent(relval, p) 0 - -#endif /* __M68KNOMMU_FLAT_H__ */ diff --git a/arch/m68knommu/include/asm/fpu.h b/arch/m68knommu/include/asm/fpu.h deleted file mode 100644 index b16b2e4fca2..00000000000 --- a/arch/m68knommu/include/asm/fpu.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __M68KNOMMU_FPU_H -#define __M68KNOMMU_FPU_H - - -/* - * MAX floating point unit state size (FSAVE/FRESTORE) - */ -#if defined(CONFIG_M68020) || defined(CONFIG_M68030) -#define FPSTATESIZE (216/sizeof(unsigned char)) -#elif defined(CONFIG_M68040) -#define FPSTATESIZE (96/sizeof(unsigned char)) -#elif defined(CONFIG_M68KFPU_EMU) -#define FPSTATESIZE (28/sizeof(unsigned char)) -#elif defined(CONFIG_M68060) -#define FPSTATESIZE (12/sizeof(unsigned char)) -#else -/* Assume no FP unit present then... */ -#define FPSTATESIZE (2) /* dummy size */ -#endif - -#endif /* __M68K_FPU_H */ diff --git a/arch/m68knommu/include/asm/futex.h b/arch/m68knommu/include/asm/futex.h deleted file mode 100644 index 6a332a9f099..00000000000 --- a/arch/m68knommu/include/asm/futex.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_FUTEX_H -#define _ASM_FUTEX_H - -#include - -#endif diff --git a/arch/m68knommu/include/asm/hardirq.h b/arch/m68knommu/include/asm/hardirq.h deleted file mode 100644 index bfad28149a4..00000000000 --- a/arch/m68knommu/include/asm/hardirq.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __M68K_HARDIRQ_H -#define __M68K_HARDIRQ_H - -#include -#include -#include - -typedef struct { - unsigned int __softirq_pending; -} ____cacheline_aligned irq_cpustat_t; - -#include /* Standard mappings for irq_cpustat_t above */ - -#define HARDIRQ_BITS 8 - -/* - * The hardirq mask has to be large enough to have - * space for potentially all IRQ sources in the system - * nesting on a single CPU: - */ -#if (1 << HARDIRQ_BITS) < NR_IRQS -# error HARDIRQ_BITS is too low! -#endif - -void ack_bad_irq(unsigned int irq); - -#endif /* __M68K_HARDIRQ_H */ diff --git a/arch/m68knommu/include/asm/hw_irq.h b/arch/m68knommu/include/asm/hw_irq.h deleted file mode 100644 index f3ec9e5ae04..00000000000 --- a/arch/m68knommu/include/asm/hw_irq.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef __M68KNOMMU_HW_IRQ_H__ -#define __M68KNOMMU_HW_IRQ_H__ - -#endif /* __M68KNOMMU_HW_IRQ_H__ */ diff --git a/arch/m68knommu/include/asm/hwtest.h b/arch/m68knommu/include/asm/hwtest.h deleted file mode 100644 index 700626a1b1b..00000000000 --- a/arch/m68knommu/include/asm/hwtest.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/io.h b/arch/m68knommu/include/asm/io.h deleted file mode 100644 index 6adef1ee208..00000000000 --- a/arch/m68knommu/include/asm/io.h +++ /dev/null @@ -1,194 +0,0 @@ -#ifndef _M68KNOMMU_IO_H -#define _M68KNOMMU_IO_H - -#ifdef __KERNEL__ - - -/* - * These are for ISA/PCI shared memory _only_ and should never be used - * on any other type of memory, including Zorro memory. They are meant to - * access the bus in the bus byte order which is little-endian!. - * - * readX/writeX() are used to access memory mapped devices. On some - * architectures the memory mapped IO stuff needs to be accessed - * differently. On the m68k architecture, we just read/write the - * memory location directly. - */ -/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates - * two accesses to memory, which may be undesireable for some devices. - */ - -/* - * swap functions are sometimes needed to interface little-endian hardware - */ -static inline unsigned short _swapw(volatile unsigned short v) -{ - return ((v << 8) | (v >> 8)); -} - -static inline unsigned int _swapl(volatile unsigned long v) -{ - return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24)); -} - -#define readb(addr) \ - ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; }) -#define readw(addr) \ - ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; }) -#define readl(addr) \ - ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; }) - -#define readb_relaxed(addr) readb(addr) -#define readw_relaxed(addr) readw(addr) -#define readl_relaxed(addr) readl(addr) - -#define writeb(b,addr) (void)((*(volatile unsigned char *) (addr)) = (b)) -#define writew(b,addr) (void)((*(volatile unsigned short *) (addr)) = (b)) -#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b)) - -#define __raw_readb readb -#define __raw_readw readw -#define __raw_readl readl -#define __raw_writeb writeb -#define __raw_writew writew -#define __raw_writel writel - -static inline void io_outsb(unsigned int addr, void *buf, int len) -{ - volatile unsigned char *ap = (volatile unsigned char *) addr; - unsigned char *bp = (unsigned char *) buf; - while (len--) - *ap = *bp++; -} - -static inline void io_outsw(unsigned int addr, void *buf, int len) -{ - volatile unsigned short *ap = (volatile unsigned short *) addr; - unsigned short *bp = (unsigned short *) buf; - while (len--) - *ap = _swapw(*bp++); -} - -static inline void io_outsl(unsigned int addr, void *buf, int len) -{ - volatile unsigned int *ap = (volatile unsigned int *) addr; - unsigned int *bp = (unsigned int *) buf; - while (len--) - *ap = _swapl(*bp++); -} - -static inline void io_insb(unsigned int addr, void *buf, int len) -{ - volatile unsigned char *ap = (volatile unsigned char *) addr; - unsigned char *bp = (unsigned char *) buf; - while (len--) - *bp++ = *ap; -} - -static inline void io_insw(unsigned int addr, void *buf, int len) -{ - volatile unsigned short *ap = (volatile unsigned short *) addr; - unsigned short *bp = (unsigned short *) buf; - while (len--) - *bp++ = _swapw(*ap); -} - -static inline void io_insl(unsigned int addr, void *buf, int len) -{ - volatile unsigned int *ap = (volatile unsigned int *) addr; - unsigned int *bp = (unsigned int *) buf; - while (len--) - *bp++ = _swapl(*ap); -} - -#define mmiowb() - -/* - * make the short names macros so specific devices - * can override them as required - */ - -#define memset_io(a,b,c) memset((void *)(a),(b),(c)) -#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) -#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) - -#define inb(addr) readb(addr) -#define inw(addr) readw(addr) -#define inl(addr) readl(addr) -#define outb(x,addr) ((void) writeb(x,addr)) -#define outw(x,addr) ((void) writew(x,addr)) -#define outl(x,addr) ((void) writel(x,addr)) - -#define inb_p(addr) inb(addr) -#define inw_p(addr) inw(addr) -#define inl_p(addr) inl(addr) -#define outb_p(x,addr) outb(x,addr) -#define outw_p(x,addr) outw(x,addr) -#define outl_p(x,addr) outl(x,addr) - -#define outsb(a,b,l) io_outsb(a,b,l) -#define outsw(a,b,l) io_outsw(a,b,l) -#define outsl(a,b,l) io_outsl(a,b,l) - -#define insb(a,b,l) io_insb(a,b,l) -#define insw(a,b,l) io_insw(a,b,l) -#define insl(a,b,l) io_insl(a,b,l) - -#define IO_SPACE_LIMIT 0xffff - - -/* Values for nocacheflag and cmode */ -#define IOMAP_FULL_CACHING 0 -#define IOMAP_NOCACHE_SER 1 -#define IOMAP_NOCACHE_NONSER 2 -#define IOMAP_WRITETHROUGH 3 - -extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag); -extern void __iounmap(void *addr, unsigned long size); - -static inline void *ioremap(unsigned long physaddr, unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); -} -static inline void *ioremap_nocache(unsigned long physaddr, unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); -} -static inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_WRITETHROUGH); -} -static inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_FULL_CACHING); -} - -extern void iounmap(void *addr); - -/* Pages to physical address... */ -#define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT) -#define page_to_bus(page) ((page - mem_map) << PAGE_SHIFT) - -/* - * Macros used for converting between virtual and physical mappings. - */ -#define phys_to_virt(vaddr) ((void *) (vaddr)) -#define virt_to_phys(vaddr) ((unsigned long) (vaddr)) - -#define virt_to_bus virt_to_phys -#define bus_to_virt phys_to_virt - -/* - * Convert a physical pointer to a virtual kernel pointer for /dev/mem - * access - */ -#define xlate_dev_mem_ptr(p) __va(p) - -/* - * Convert a virtual cached pointer to an uncached pointer - */ -#define xlate_dev_kmem_ptr(p) p - -#endif /* __KERNEL__ */ - -#endif /* _M68KNOMMU_IO_H */ diff --git a/arch/m68knommu/include/asm/ioctl.h b/arch/m68knommu/include/asm/ioctl.h deleted file mode 100644 index b279fe06dfe..00000000000 --- a/arch/m68knommu/include/asm/ioctl.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/ioctls.h b/arch/m68knommu/include/asm/ioctls.h deleted file mode 100644 index 0b1eb4d8505..00000000000 --- a/arch/m68knommu/include/asm/ioctls.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/ipcbuf.h b/arch/m68knommu/include/asm/ipcbuf.h deleted file mode 100644 index e4a7be6dd70..00000000000 --- a/arch/m68knommu/include/asm/ipcbuf.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/irq.h b/arch/m68knommu/include/asm/irq.h deleted file mode 100644 index 9373c31ac87..00000000000 --- a/arch/m68knommu/include/asm/irq.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _M68KNOMMU_IRQ_H_ -#define _M68KNOMMU_IRQ_H_ - -#ifdef CONFIG_COLDFIRE -/* - * On the ColdFire we keep track of all vectors. That way drivers - * can register whatever vector number they wish, and we can deal - * with it. - */ -#define SYS_IRQS 256 -#define NR_IRQS SYS_IRQS - -#else - -/* - * # of m68k interrupts - */ -#define SYS_IRQS 8 -#define NR_IRQS (24 + SYS_IRQS) - -#endif /* CONFIG_COLDFIRE */ - - -#define irq_canonicalize(irq) (irq) - -#endif /* _M68KNOMMU_IRQ_H_ */ diff --git a/arch/m68knommu/include/asm/irq_regs.h b/arch/m68knommu/include/asm/irq_regs.h deleted file mode 100644 index 3dd9c0b7027..00000000000 --- a/arch/m68knommu/include/asm/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/kdebug.h b/arch/m68knommu/include/asm/kdebug.h deleted file mode 100644 index 6ece1b03766..00000000000 --- a/arch/m68knommu/include/asm/kdebug.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/kmap_types.h b/arch/m68knommu/include/asm/kmap_types.h deleted file mode 100644 index bfb6707575d..00000000000 --- a/arch/m68knommu/include/asm/kmap_types.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __ASM_M68K_KMAP_TYPES_H -#define __ASM_M68K_KMAP_TYPES_H - -enum km_type { - KM_BOUNCE_READ, - KM_SKB_SUNRPC_DATA, - KM_SKB_DATA_SOFTIRQ, - KM_USER0, - KM_USER1, - KM_BIO_SRC_IRQ, - KM_BIO_DST_IRQ, - KM_PTE0, - KM_PTE1, - KM_IRQ0, - KM_IRQ1, - KM_SOFTIRQ0, - KM_SOFTIRQ1, - KM_TYPE_NR -}; - -#endif diff --git a/arch/m68knommu/include/asm/linkage.h b/arch/m68knommu/include/asm/linkage.h deleted file mode 100644 index c288a19ff48..00000000000 --- a/arch/m68knommu/include/asm/linkage.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/local.h b/arch/m68knommu/include/asm/local.h deleted file mode 100644 index 84a39c1b86f..00000000000 --- a/arch/m68knommu/include/asm/local.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __M68KNOMMU_LOCAL_H -#define __M68KNOMMU_LOCAL_H - -#include - -#endif /* __M68KNOMMU_LOCAL_H */ diff --git a/arch/m68knommu/include/asm/m5206sim.h b/arch/m68knommu/include/asm/m5206sim.h deleted file mode 100644 index 7e3594dea88..00000000000 --- a/arch/m68knommu/include/asm/m5206sim.h +++ /dev/null @@ -1,131 +0,0 @@ -/****************************************************************************/ - -/* - * m5206sim.h -- ColdFire 5206 System Integration Module support. - * - * (C) Copyright 1999, Greg Ungerer (gerg@snapgear.com) - * (C) Copyright 2000, Lineo Inc. (www.lineo.com) - */ - -/****************************************************************************/ -#ifndef m5206sim_h -#define m5206sim_h -/****************************************************************************/ - - -/* - * Define the 5206 SIM register set addresses. - */ -#define MCFSIM_SIMR 0x03 /* SIM Config reg (r/w) */ -#define MCFSIM_ICR1 0x14 /* Intr Ctrl reg 1 (r/w) */ -#define MCFSIM_ICR2 0x15 /* Intr Ctrl reg 2 (r/w) */ -#define MCFSIM_ICR3 0x16 /* Intr Ctrl reg 3 (r/w) */ -#define MCFSIM_ICR4 0x17 /* Intr Ctrl reg 4 (r/w) */ -#define MCFSIM_ICR5 0x18 /* Intr Ctrl reg 5 (r/w) */ -#define MCFSIM_ICR6 0x19 /* Intr Ctrl reg 6 (r/w) */ -#define MCFSIM_ICR7 0x1a /* Intr Ctrl reg 7 (r/w) */ -#define MCFSIM_ICR8 0x1b /* Intr Ctrl reg 8 (r/w) */ -#define MCFSIM_ICR9 0x1c /* Intr Ctrl reg 9 (r/w) */ -#define MCFSIM_ICR10 0x1d /* Intr Ctrl reg 10 (r/w) */ -#define MCFSIM_ICR11 0x1e /* Intr Ctrl reg 11 (r/w) */ -#define MCFSIM_ICR12 0x1f /* Intr Ctrl reg 12 (r/w) */ -#define MCFSIM_ICR13 0x20 /* Intr Ctrl reg 13 (r/w) */ -#ifdef CONFIG_M5206e -#define MCFSIM_ICR14 0x21 /* Intr Ctrl reg 14 (r/w) */ -#define MCFSIM_ICR15 0x22 /* Intr Ctrl reg 15 (r/w) */ -#endif - -#define MCFSIM_IMR 0x36 /* Interrupt Mask reg (r/w) */ -#define MCFSIM_IPR 0x3a /* Interrupt Pend reg (r/w) */ - -#define MCFSIM_RSR 0x40 /* Reset Status reg (r/w) */ -#define MCFSIM_SYPCR 0x41 /* System Protection reg (r/w)*/ - -#define MCFSIM_SWIVR 0x42 /* SW Watchdog intr reg (r/w) */ -#define MCFSIM_SWSR 0x43 /* SW Watchdog service (r/w) */ - -#define MCFSIM_DCRR 0x46 /* DRAM Refresh reg (r/w) */ -#define MCFSIM_DCTR 0x4a /* DRAM Timing reg (r/w) */ -#define MCFSIM_DAR0 0x4c /* DRAM 0 Address reg(r/w) */ -#define MCFSIM_DMR0 0x50 /* DRAM 0 Mask reg (r/w) */ -#define MCFSIM_DCR0 0x57 /* DRAM 0 Control reg (r/w) */ -#define MCFSIM_DAR1 0x58 /* DRAM 1 Address reg (r/w) */ -#define MCFSIM_DMR1 0x5c /* DRAM 1 Mask reg (r/w) */ -#define MCFSIM_DCR1 0x63 /* DRAM 1 Control reg (r/w) */ - -#define MCFSIM_CSAR0 0x64 /* CS 0 Address 0 reg (r/w) */ -#define MCFSIM_CSMR0 0x68 /* CS 0 Mask 0 reg (r/w) */ -#define MCFSIM_CSCR0 0x6e /* CS 0 Control reg (r/w) */ -#define MCFSIM_CSAR1 0x70 /* CS 1 Address reg (r/w) */ -#define MCFSIM_CSMR1 0x74 /* CS 1 Mask reg (r/w) */ -#define MCFSIM_CSCR1 0x7a /* CS 1 Control reg (r/w) */ -#define MCFSIM_CSAR2 0x7c /* CS 2 Address reg (r/w) */ -#define MCFSIM_CSMR2 0x80 /* CS 2 Mask reg (r/w) */ -#define MCFSIM_CSCR2 0x86 /* CS 2 Control reg (r/w) */ -#define MCFSIM_CSAR3 0x88 /* CS 3 Address reg (r/w) */ -#define MCFSIM_CSMR3 0x8c /* CS 3 Mask reg (r/w) */ -#define MCFSIM_CSCR3 0x92 /* CS 3 Control reg (r/w) */ -#define MCFSIM_CSAR4 0x94 /* CS 4 Address reg (r/w) */ -#define MCFSIM_CSMR4 0x98 /* CS 4 Mask reg (r/w) */ -#define MCFSIM_CSCR4 0x9e /* CS 4 Control reg (r/w) */ -#define MCFSIM_CSAR5 0xa0 /* CS 5 Address reg (r/w) */ -#define MCFSIM_CSMR5 0xa4 /* CS 5 Mask reg (r/w) */ -#define MCFSIM_CSCR5 0xaa /* CS 5 Control reg (r/w) */ -#define MCFSIM_CSAR6 0xac /* CS 6 Address reg (r/w) */ -#define MCFSIM_CSMR6 0xb0 /* CS 6 Mask reg (r/w) */ -#define MCFSIM_CSCR6 0xb6 /* CS 6 Control reg (r/w) */ -#define MCFSIM_CSAR7 0xb8 /* CS 7 Address reg (r/w) */ -#define MCFSIM_CSMR7 0xbc /* CS 7 Mask reg (r/w) */ -#define MCFSIM_CSCR7 0xc2 /* CS 7 Control reg (r/w) */ -#define MCFSIM_DMCR 0xc6 /* Default control */ - -#ifdef CONFIG_M5206e -#define MCFSIM_PAR 0xca /* Pin Assignment reg (r/w) */ -#else -#define MCFSIM_PAR 0xcb /* Pin Assignment reg (r/w) */ -#endif - -#define MCFSIM_PADDR 0x1c5 /* Parallel Direction (r/w) */ -#define MCFSIM_PADAT 0x1c9 /* Parallel Port Value (r/w) */ - -/* - * Some symbol defines for the Parallel Port Pin Assignment Register - */ -#ifdef CONFIG_M5206e -#define MCFSIM_PAR_DREQ0 0x100 /* Set to select DREQ0 input */ - /* Clear to select T0 input */ -#define MCFSIM_PAR_DREQ1 0x200 /* Select DREQ1 input */ - /* Clear to select T0 output */ -#endif - -/* - * Some symbol defines for the Interrupt Control Register - */ -#define MCFSIM_SWDICR MCFSIM_ICR8 /* Watchdog timer ICR */ -#define MCFSIM_TIMER1ICR MCFSIM_ICR9 /* Timer 1 ICR */ -#define MCFSIM_TIMER2ICR MCFSIM_ICR10 /* Timer 2 ICR */ -#define MCFSIM_UART1ICR MCFSIM_ICR12 /* UART 1 ICR */ -#define MCFSIM_UART2ICR MCFSIM_ICR13 /* UART 2 ICR */ -#ifdef CONFIG_M5206e -#define MCFSIM_DMA1ICR MCFSIM_ICR14 /* DMA 1 ICR */ -#define MCFSIM_DMA2ICR MCFSIM_ICR15 /* DMA 2 ICR */ -#endif - -#if defined(CONFIG_M5206e) -#define MCFSIM_IMR_MASKALL 0xfffe /* All SIM intr sources */ -#endif - -/* - * Macro to get and set IMR register. It is 16 bits on the 5206. - */ -#define mcf_getimr() \ - *((volatile unsigned short *) (MCF_MBAR + MCFSIM_IMR)) - -#define mcf_setimr(imr) \ - *((volatile unsigned short *) (MCF_MBAR + MCFSIM_IMR)) = (imr) - -#define mcf_getipr() \ - *((volatile unsigned short *) (MCF_MBAR + MCFSIM_IPR)) - -/****************************************************************************/ -#endif /* m5206sim_h */ diff --git a/arch/m68knommu/include/asm/m520xsim.h b/arch/m68knommu/include/asm/m520xsim.h deleted file mode 100644 index 49d016e6391..00000000000 --- a/arch/m68knommu/include/asm/m520xsim.h +++ /dev/null @@ -1,63 +0,0 @@ -/****************************************************************************/ - -/* - * m520xsim.h -- ColdFire 5207/5208 System Integration Module support. - * - * (C) Copyright 2005, Intec Automation (mike@steroidmicros.com) - */ - -/****************************************************************************/ -#ifndef m520xsim_h -#define m520xsim_h -/****************************************************************************/ - - -/* - * Define the 5282 SIM register set addresses. - */ -#define MCFICM_INTC0 0x48000 /* Base for Interrupt Ctrl 0 */ -#define MCFINTC_IPRH 0x00 /* Interrupt pending 32-63 */ -#define MCFINTC_IPRL 0x04 /* Interrupt pending 1-31 */ -#define MCFINTC_IMRH 0x08 /* Interrupt mask 32-63 */ -#define MCFINTC_IMRL 0x0c /* Interrupt mask 1-31 */ -#define MCFINTC_INTFRCH 0x10 /* Interrupt force 32-63 */ -#define MCFINTC_INTFRCL 0x14 /* Interrupt force 1-31 */ -#define MCFINTC_ICR0 0x40 /* Base ICR register */ - -#define MCFINT_VECBASE 64 -#define MCFINT_UART0 26 /* Interrupt number for UART0 */ -#define MCFINT_UART1 27 /* Interrupt number for UART1 */ -#define MCFINT_UART2 28 /* Interrupt number for UART2 */ -#define MCFINT_QSPI 31 /* Interrupt number for QSPI */ -#define MCFINT_PIT1 4 /* Interrupt number for PIT1 (PIT0 in processor) */ - -/* - * SDRAM configuration registers. - */ -#define MCFSIM_SDMR 0x000a8000 /* SDRAM Mode/Extended Mode Register */ -#define MCFSIM_SDCR 0x000a8004 /* SDRAM Control Register */ -#define MCFSIM_SDCFG1 0x000a8008 /* SDRAM Configuration Register 1 */ -#define MCFSIM_SDCFG2 0x000a800c /* SDRAM Configuration Register 2 */ -#define MCFSIM_SDCS0 0x000a8110 /* SDRAM Chip Select 0 Configuration */ -#define MCFSIM_SDCS1 0x000a8114 /* SDRAM Chip Select 1 Configuration */ - - -#define MCF_GPIO_PAR_UART (0xA4036) -#define MCF_GPIO_PAR_FECI2C (0xA4033) -#define MCF_GPIO_PAR_FEC (0xA4038) - -#define MCF_GPIO_PAR_UART_PAR_URXD0 (0x0001) -#define MCF_GPIO_PAR_UART_PAR_UTXD0 (0x0002) - -#define MCF_GPIO_PAR_UART_PAR_URXD1 (0x0040) -#define MCF_GPIO_PAR_UART_PAR_UTXD1 (0x0080) - -#define MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2 (0x02) -#define MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2 (0x04) - -#define ICR_INTRCONF 0x05 -#define MCFPIT_IMR MCFINTC_IMRL -#define MCFPIT_IMR_IBIT (1 << MCFINT_PIT1) - -/****************************************************************************/ -#endif /* m520xsim_h */ diff --git a/arch/m68knommu/include/asm/m523xsim.h b/arch/m68knommu/include/asm/m523xsim.h deleted file mode 100644 index bf397313e93..00000000000 --- a/arch/m68knommu/include/asm/m523xsim.h +++ /dev/null @@ -1,45 +0,0 @@ -/****************************************************************************/ - -/* - * m523xsim.h -- ColdFire 523x System Integration Module support. - * - * (C) Copyright 2003-2005, Greg Ungerer - */ - -/****************************************************************************/ -#ifndef m523xsim_h -#define m523xsim_h -/****************************************************************************/ - - -/* - * Define the 523x SIM register set addresses. - */ -#define MCFICM_INTC0 0x0c00 /* Base for Interrupt Ctrl 0 */ -#define MCFICM_INTC1 0x0d00 /* Base for Interrupt Ctrl 0 */ -#define MCFINTC_IPRH 0x00 /* Interrupt pending 32-63 */ -#define MCFINTC_IPRL 0x04 /* Interrupt pending 1-31 */ -#define MCFINTC_IMRH 0x08 /* Interrupt mask 32-63 */ -#define MCFINTC_IMRL 0x0c /* Interrupt mask 1-31 */ -#define MCFINTC_INTFRCH 0x10 /* Interrupt force 32-63 */ -#define MCFINTC_INTFRCL 0x14 /* Interrupt force 1-31 */ -#define MCFINTC_IRLR 0x18 /* */ -#define MCFINTC_IACKL 0x19 /* */ -#define MCFINTC_ICR0 0x40 /* Base ICR register */ - -#define MCFINT_VECBASE 64 /* Vector base number */ -#define MCFINT_UART0 13 /* Interrupt number for UART0 */ -#define MCFINT_PIT1 36 /* Interrupt number for PIT1 */ -#define MCFINT_QSPI 18 /* Interrupt number for QSPI */ - -/* - * SDRAM configuration registers. - */ -#define MCFSIM_DCR 0x44 /* SDRAM control */ -#define MCFSIM_DACR0 0x48 /* SDRAM base address 0 */ -#define MCFSIM_DMR0 0x4c /* SDRAM address mask 0 */ -#define MCFSIM_DACR1 0x50 /* SDRAM base address 1 */ -#define MCFSIM_DMR1 0x54 /* SDRAM address mask 1 */ - -/****************************************************************************/ -#endif /* m523xsim_h */ diff --git a/arch/m68knommu/include/asm/m5249sim.h b/arch/m68knommu/include/asm/m5249sim.h deleted file mode 100644 index 366eb8602d2..00000000000 --- a/arch/m68knommu/include/asm/m5249sim.h +++ /dev/null @@ -1,209 +0,0 @@ -/****************************************************************************/ - -/* - * m5249sim.h -- ColdFire 5249 System Integration Module support. - * - * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) - */ - -/****************************************************************************/ -#ifndef m5249sim_h -#define m5249sim_h -/****************************************************************************/ - -/* - * Define the 5249 SIM register set addresses. - */ -#define MCFSIM_RSR 0x00 /* Reset Status reg (r/w) */ -#define MCFSIM_SYPCR 0x01 /* System Protection reg (r/w)*/ -#define MCFSIM_SWIVR 0x02 /* SW Watchdog intr reg (r/w) */ -#define MCFSIM_SWSR 0x03 /* SW Watchdog service (r/w) */ -#define MCFSIM_PAR 0x04 /* Pin Assignment reg (r/w) */ -#define MCFSIM_IRQPAR 0x06 /* Interrupt Assignment reg (r/w) */ -#define MCFSIM_MPARK 0x0C /* BUS Master Control Reg*/ -#define MCFSIM_IPR 0x40 /* Interrupt Pend reg (r/w) */ -#define MCFSIM_IMR 0x44 /* Interrupt Mask reg (r/w) */ -#define MCFSIM_AVR 0x4b /* Autovector Ctrl reg (r/w) */ -#define MCFSIM_ICR0 0x4c /* Intr Ctrl reg 0 (r/w) */ -#define MCFSIM_ICR1 0x4d /* Intr Ctrl reg 1 (r/w) */ -#define MCFSIM_ICR2 0x4e /* Intr Ctrl reg 2 (r/w) */ -#define MCFSIM_ICR3 0x4f /* Intr Ctrl reg 3 (r/w) */ -#define MCFSIM_ICR4 0x50 /* Intr Ctrl reg 4 (r/w) */ -#define MCFSIM_ICR5 0x51 /* Intr Ctrl reg 5 (r/w) */ -#define MCFSIM_ICR6 0x52 /* Intr Ctrl reg 6 (r/w) */ -#define MCFSIM_ICR7 0x53 /* Intr Ctrl reg 7 (r/w) */ -#define MCFSIM_ICR8 0x54 /* Intr Ctrl reg 8 (r/w) */ -#define MCFSIM_ICR9 0x55 /* Intr Ctrl reg 9 (r/w) */ -#define MCFSIM_ICR10 0x56 /* Intr Ctrl reg 10 (r/w) */ -#define MCFSIM_ICR11 0x57 /* Intr Ctrl reg 11 (r/w) */ - -#define MCFSIM_CSAR0 0x80 /* CS 0 Address 0 reg (r/w) */ -#define MCFSIM_CSMR0 0x84 /* CS 0 Mask 0 reg (r/w) */ -#define MCFSIM_CSCR0 0x8a /* CS 0 Control reg (r/w) */ -#define MCFSIM_CSAR1 0x8c /* CS 1 Address reg (r/w) */ -#define MCFSIM_CSMR1 0x90 /* CS 1 Mask reg (r/w) */ -#define MCFSIM_CSCR1 0x96 /* CS 1 Control reg (r/w) */ -#define MCFSIM_CSAR2 0x98 /* CS 2 Address reg (r/w) */ -#define MCFSIM_CSMR2 0x9c /* CS 2 Mask reg (r/w) */ -#define MCFSIM_CSCR2 0xa2 /* CS 2 Control reg (r/w) */ -#define MCFSIM_CSAR3 0xa4 /* CS 3 Address reg (r/w) */ -#define MCFSIM_CSMR3 0xa8 /* CS 3 Mask reg (r/w) */ -#define MCFSIM_CSCR3 0xae /* CS 3 Control reg (r/w) */ - -#define MCFSIM_DCR 0x100 /* DRAM Control reg (r/w) */ -#define MCFSIM_DACR0 0x108 /* DRAM 0 Addr and Ctrl (r/w) */ -#define MCFSIM_DMR0 0x10c /* DRAM 0 Mask reg (r/w) */ -#define MCFSIM_DACR1 0x110 /* DRAM 1 Addr and Ctrl (r/w) */ -#define MCFSIM_DMR1 0x114 /* DRAM 1 Mask reg (r/w) */ - - -/* - * Some symbol defines for the above... - */ -#define MCFSIM_SWDICR MCFSIM_ICR0 /* Watchdog timer ICR */ -#define MCFSIM_TIMER1ICR MCFSIM_ICR1 /* Timer 1 ICR */ -#define MCFSIM_TIMER2ICR MCFSIM_ICR2 /* Timer 2 ICR */ -#define MCFSIM_UART1ICR MCFSIM_ICR4 /* UART 1 ICR */ -#define MCFSIM_UART2ICR MCFSIM_ICR5 /* UART 2 ICR */ -#define MCFSIM_DMA0ICR MCFSIM_ICR6 /* DMA 0 ICR */ -#define MCFSIM_DMA1ICR MCFSIM_ICR7 /* DMA 1 ICR */ -#define MCFSIM_DMA2ICR MCFSIM_ICR8 /* DMA 2 ICR */ -#define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */ - -/* - * General purpose IO registers (in MBAR2). - */ -#define MCFSIM2_GPIOREAD 0x0 /* GPIO read values */ -#define MCFSIM2_GPIOWRITE 0x4 /* GPIO write values */ -#define MCFSIM2_GPIOENABLE 0x8 /* GPIO enabled */ -#define MCFSIM2_GPIOFUNC 0xc /* GPIO function */ -#define MCFSIM2_GPIO1READ 0xb0 /* GPIO1 read values */ -#define MCFSIM2_GPIO1WRITE 0xb4 /* GPIO1 write values */ -#define MCFSIM2_GPIO1ENABLE 0xb8 /* GPIO1 enabled */ -#define MCFSIM2_GPIO1FUNC 0xbc /* GPIO1 function */ - -#define MCFSIM2_GPIOINTSTAT 0xc0 /* GPIO interrupt status */ -#define MCFSIM2_GPIOINTCLEAR 0xc0 /* GPIO interrupt clear */ -#define MCFSIM2_GPIOINTENABLE 0xc4 /* GPIO interrupt enable */ - -#define MCFSIM2_INTLEVEL1 0x140 /* Interrupt level reg 1 */ -#define MCFSIM2_INTLEVEL2 0x144 /* Interrupt level reg 2 */ -#define MCFSIM2_INTLEVEL3 0x148 /* Interrupt level reg 3 */ -#define MCFSIM2_INTLEVEL4 0x14c /* Interrupt level reg 4 */ -#define MCFSIM2_INTLEVEL5 0x150 /* Interrupt level reg 5 */ -#define MCFSIM2_INTLEVEL6 0x154 /* Interrupt level reg 6 */ -#define MCFSIM2_INTLEVEL7 0x158 /* Interrupt level reg 7 */ -#define MCFSIM2_INTLEVEL8 0x15c /* Interrupt level reg 8 */ - -#define MCFSIM2_DMAROUTE 0x188 /* DMA routing */ - -#define MCFSIM2_IDECONFIG1 0x18c /* IDEconfig1 */ -#define MCFSIM2_IDECONFIG2 0x190 /* IDEconfig2 */ - - -/* - * Macro to set IMR register. It is 32 bits on the 5249. - */ -#define MCFSIM_IMR_MASKALL 0x7fffe /* All SIM intr sources */ - -#define mcf_getimr() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) - -#define mcf_setimr(imr) \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr); - -#define mcf_getipr() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR)) - -/****************************************************************************/ - -#ifdef __ASSEMBLER__ - -/* - * The M5249C3 board needs a little help getting all its SIM devices - * initialized at kernel start time. dBUG doesn't set much up, so - * we need to do it manually. - */ -.macro m5249c3_setup - /* - * Set MBAR1 and MBAR2, just incase they are not set. - */ - movel #0x10000001,%a0 - movec %a0,%MBAR /* map MBAR region */ - subql #1,%a0 /* get MBAR address in a0 */ - - movel #0x80000001,%a1 - movec %a1,#3086 /* map MBAR2 region */ - subql #1,%a1 /* get MBAR2 address in a1 */ - - /* - * Move secondary interrupts to base at 128. - */ - moveb #0x80,%d0 - moveb %d0,0x16b(%a1) /* interrupt base register */ - - /* - * Work around broken CSMR0/DRAM vector problem. - */ - movel #0x001F0021,%d0 /* disable C/I bit */ - movel %d0,0x84(%a0) /* set CSMR0 */ - - /* - * Disable the PLL firstly. (Who knows what state it is - * in here!). - */ - movel 0x180(%a1),%d0 /* get current PLL value */ - andl #0xfffffffe,%d0 /* PLL bypass first */ - movel %d0,0x180(%a1) /* set PLL register */ - nop - -#if CONFIG_CLOCK_FREQ == 140000000 - /* - * Set initial clock frequency. This assumes M5249C3 board - * is fitted with 11.2896MHz crystal. It will program the - * PLL for 140MHz. Lets go fast :-) - */ - movel #0x125a40f0,%d0 /* set for 140MHz */ - movel %d0,0x180(%a1) /* set PLL register */ - orl #0x1,%d0 - movel %d0,0x180(%a1) /* set PLL register */ -#endif - - /* - * Setup CS1 for ethernet controller. - * (Setup as per M5249C3 doco). - */ - movel #0xe0000000,%d0 /* CS1 mapped at 0xe0000000 */ - movel %d0,0x8c(%a0) - movel #0x001f0021,%d0 /* CS1 size of 1Mb */ - movel %d0,0x90(%a0) - movew #0x0080,%d0 /* CS1 = 16bit port, AA */ - movew %d0,0x96(%a0) - - /* - * Setup CS2 for IDE interface. - */ - movel #0x50000000,%d0 /* CS2 mapped at 0x50000000 */ - movel %d0,0x98(%a0) - movel #0x001f0001,%d0 /* CS2 size of 1MB */ - movel %d0,0x9c(%a0) - movew #0x0080,%d0 /* CS2 = 16bit, TA */ - movew %d0,0xa2(%a0) - - movel #0x00107000,%d0 /* IDEconfig1 */ - movel %d0,0x18c(%a1) - movel #0x000c0400,%d0 /* IDEconfig2 */ - movel %d0,0x190(%a1) - - movel #0x00080000,%d0 /* GPIO19, IDE reset bit */ - orl %d0,0xc(%a1) /* function GPIO19 */ - orl %d0,0x8(%a1) /* enable GPIO19 as output */ - orl %d0,0x4(%a1) /* de-assert IDE reset */ -.endm - -#define PLATFORM_SETUP m5249c3_setup - -#endif /* __ASSEMBLER__ */ - -/****************************************************************************/ -#endif /* m5249sim_h */ diff --git a/arch/m68knommu/include/asm/m5272sim.h b/arch/m68knommu/include/asm/m5272sim.h deleted file mode 100644 index 6217edc2113..00000000000 --- a/arch/m68knommu/include/asm/m5272sim.h +++ /dev/null @@ -1,78 +0,0 @@ -/****************************************************************************/ - -/* - * m5272sim.h -- ColdFire 5272 System Integration Module support. - * - * (C) Copyright 1999, Greg Ungerer (gerg@snapgear.com) - * (C) Copyright 2000, Lineo Inc. (www.lineo.com) - */ - -/****************************************************************************/ -#ifndef m5272sim_h -#define m5272sim_h -/****************************************************************************/ - - -/* - * Define the 5272 SIM register set addresses. - */ -#define MCFSIM_SCR 0x04 /* SIM Config reg (r/w) */ -#define MCFSIM_SPR 0x06 /* System Protection reg (r/w)*/ -#define MCFSIM_PMR 0x08 /* Power Management reg (r/w) */ -#define MCFSIM_APMR 0x0e /* Active Low Power reg (r/w) */ -#define MCFSIM_DIR 0x10 /* Device Identity reg (r/w) */ - -#define MCFSIM_ICR1 0x20 /* Intr Ctrl reg 1 (r/w) */ -#define MCFSIM_ICR2 0x24 /* Intr Ctrl reg 2 (r/w) */ -#define MCFSIM_ICR3 0x28 /* Intr Ctrl reg 3 (r/w) */ -#define MCFSIM_ICR4 0x2c /* Intr Ctrl reg 4 (r/w) */ - -#define MCFSIM_ISR 0x30 /* Interrupt Source reg (r/w) */ -#define MCFSIM_PITR 0x34 /* Interrupt Transition (r/w) */ -#define MCFSIM_PIWR 0x38 /* Interrupt Wakeup reg (r/w) */ -#define MCFSIM_PIVR 0x3f /* Interrupt Vector reg (r/w( */ - -#define MCFSIM_WRRR 0x280 /* Watchdog reference (r/w) */ -#define MCFSIM_WIRR 0x284 /* Watchdog interrupt (r/w) */ -#define MCFSIM_WCR 0x288 /* Watchdog counter (r/w) */ -#define MCFSIM_WER 0x28c /* Watchdog event (r/w) */ - -#define MCFSIM_CSBR0 0x40 /* CS0 Base Address (r/w) */ -#define MCFSIM_CSOR0 0x44 /* CS0 Option (r/w) */ -#define MCFSIM_CSBR1 0x48 /* CS1 Base Address (r/w) */ -#define MCFSIM_CSOR1 0x4c /* CS1 Option (r/w) */ -#define MCFSIM_CSBR2 0x50 /* CS2 Base Address (r/w) */ -#define MCFSIM_CSOR2 0x54 /* CS2 Option (r/w) */ -#define MCFSIM_CSBR3 0x58 /* CS3 Base Address (r/w) */ -#define MCFSIM_CSOR3 0x5c /* CS3 Option (r/w) */ -#define MCFSIM_CSBR4 0x60 /* CS4 Base Address (r/w) */ -#define MCFSIM_CSOR4 0x64 /* CS4 Option (r/w) */ -#define MCFSIM_CSBR5 0x68 /* CS5 Base Address (r/w) */ -#define MCFSIM_CSOR5 0x6c /* CS5 Option (r/w) */ -#define MCFSIM_CSBR6 0x70 /* CS6 Base Address (r/w) */ -#define MCFSIM_CSOR6 0x74 /* CS6 Option (r/w) */ -#define MCFSIM_CSBR7 0x78 /* CS7 Base Address (r/w) */ -#define MCFSIM_CSOR7 0x7c /* CS7 Option (r/w) */ - -#define MCFSIM_SDCR 0x180 /* SDRAM Configuration (r/w) */ -#define MCFSIM_SDTR 0x184 /* SDRAM Timing (r/w) */ -#define MCFSIM_DCAR0 0x4c /* DRAM 0 Address reg(r/w) */ -#define MCFSIM_DCMR0 0x50 /* DRAM 0 Mask reg (r/w) */ -#define MCFSIM_DCCR0 0x57 /* DRAM 0 Control reg (r/w) */ -#define MCFSIM_DCAR1 0x58 /* DRAM 1 Address reg (r/w) */ -#define MCFSIM_DCMR1 0x5c /* DRAM 1 Mask reg (r/w) */ -#define MCFSIM_DCCR1 0x63 /* DRAM 1 Control reg (r/w) */ - -#define MCFSIM_PACNT 0x80 /* Port A Control (r/w) */ -#define MCFSIM_PADDR 0x84 /* Port A Direction (r/w) */ -#define MCFSIM_PADAT 0x86 /* Port A Data (r/w) */ -#define MCFSIM_PBCNT 0x88 /* Port B Control (r/w) */ -#define MCFSIM_PBDDR 0x8c /* Port B Direction (r/w) */ -#define MCFSIM_PBDAT 0x8e /* Port B Data (r/w) */ -#define MCFSIM_PCDDR 0x94 /* Port C Direction (r/w) */ -#define MCFSIM_PCDAT 0x96 /* Port C Data (r/w) */ -#define MCFSIM_PDCNT 0x98 /* Port D Control (r/w) */ - - -/****************************************************************************/ -#endif /* m5272sim_h */ diff --git a/arch/m68knommu/include/asm/m527xsim.h b/arch/m68knommu/include/asm/m527xsim.h deleted file mode 100644 index 1f63ab3fb3e..00000000000 --- a/arch/m68knommu/include/asm/m527xsim.h +++ /dev/null @@ -1,74 +0,0 @@ -/****************************************************************************/ - -/* - * m527xsim.h -- ColdFire 5270/5271 System Integration Module support. - * - * (C) Copyright 2004, Greg Ungerer (gerg@snapgear.com) - */ - -/****************************************************************************/ -#ifndef m527xsim_h -#define m527xsim_h -/****************************************************************************/ - - -/* - * Define the 5270/5271 SIM register set addresses. - */ -#define MCFICM_INTC0 0x0c00 /* Base for Interrupt Ctrl 0 */ -#define MCFICM_INTC1 0x0d00 /* Base for Interrupt Ctrl 1 */ -#define MCFINTC_IPRH 0x00 /* Interrupt pending 32-63 */ -#define MCFINTC_IPRL 0x04 /* Interrupt pending 1-31 */ -#define MCFINTC_IMRH 0x08 /* Interrupt mask 32-63 */ -#define MCFINTC_IMRL 0x0c /* Interrupt mask 1-31 */ -#define MCFINTC_INTFRCH 0x10 /* Interrupt force 32-63 */ -#define MCFINTC_INTFRCL 0x14 /* Interrupt force 1-31 */ -#define MCFINTC_IRLR 0x18 /* */ -#define MCFINTC_IACKL 0x19 /* */ -#define MCFINTC_ICR0 0x40 /* Base ICR register */ - -#define MCFINT_VECBASE 64 /* Vector base number */ -#define MCFINT_UART0 13 /* Interrupt number for UART0 */ -#define MCFINT_UART1 14 /* Interrupt number for UART1 */ -#define MCFINT_UART2 15 /* Interrupt number for UART2 */ -#define MCFINT_PIT1 36 /* Interrupt number for PIT1 */ - -/* - * SDRAM configuration registers. - */ -#ifdef CONFIG_M5271 -#define MCFSIM_DCR 0x40 /* SDRAM control */ -#define MCFSIM_DACR0 0x48 /* SDRAM base address 0 */ -#define MCFSIM_DMR0 0x4c /* SDRAM address mask 0 */ -#define MCFSIM_DACR1 0x50 /* SDRAM base address 1 */ -#define MCFSIM_DMR1 0x54 /* SDRAM address mask 1 */ -#endif -#ifdef CONFIG_M5275 -#define MCFSIM_DMR 0x40 /* SDRAM mode */ -#define MCFSIM_DCR 0x44 /* SDRAM control */ -#define MCFSIM_DCFG1 0x48 /* SDRAM configuration 1 */ -#define MCFSIM_DCFG2 0x4c /* SDRAM configuration 2 */ -#define MCFSIM_DBAR0 0x50 /* SDRAM base address 0 */ -#define MCFSIM_DMR0 0x54 /* SDRAM address mask 0 */ -#define MCFSIM_DBAR1 0x58 /* SDRAM base address 1 */ -#define MCFSIM_DMR1 0x5c /* SDRAM address mask 1 */ -#endif - -/* - * GPIO pins setups to enable the UARTs. - */ -#ifdef CONFIG_M5271 -#define MCF_GPIO_PAR_UART 0x100048 /* PAR UART address */ -#define UART0_ENABLE_MASK 0x000f -#define UART1_ENABLE_MASK 0x0ff0 -#define UART2_ENABLE_MASK 0x3000 -#endif -#ifdef CONFIG_M5275 -#define MCF_GPIO_PAR_UART 0x10007c /* PAR UART address */ -#define UART0_ENABLE_MASK 0x000f -#define UART1_ENABLE_MASK 0x00f0 -#define UART2_ENABLE_MASK 0x3f00 -#endif - -/****************************************************************************/ -#endif /* m527xsim_h */ diff --git a/arch/m68knommu/include/asm/m528xsim.h b/arch/m68knommu/include/asm/m528xsim.h deleted file mode 100644 index 28bf783a5d6..00000000000 --- a/arch/m68knommu/include/asm/m528xsim.h +++ /dev/null @@ -1,159 +0,0 @@ -/****************************************************************************/ - -/* - * m528xsim.h -- ColdFire 5280/5282 System Integration Module support. - * - * (C) Copyright 2003, Greg Ungerer (gerg@snapgear.com) - */ - -/****************************************************************************/ -#ifndef m528xsim_h -#define m528xsim_h -/****************************************************************************/ - - -/* - * Define the 5280/5282 SIM register set addresses. - */ -#define MCFICM_INTC0 0x0c00 /* Base for Interrupt Ctrl 0 */ -#define MCFICM_INTC1 0x0d00 /* Base for Interrupt Ctrl 0 */ -#define MCFINTC_IPRH 0x00 /* Interrupt pending 32-63 */ -#define MCFINTC_IPRL 0x04 /* Interrupt pending 1-31 */ -#define MCFINTC_IMRH 0x08 /* Interrupt mask 32-63 */ -#define MCFINTC_IMRL 0x0c /* Interrupt mask 1-31 */ -#define MCFINTC_INTFRCH 0x10 /* Interrupt force 32-63 */ -#define MCFINTC_INTFRCL 0x14 /* Interrupt force 1-31 */ -#define MCFINTC_IRLR 0x18 /* */ -#define MCFINTC_IACKL 0x19 /* */ -#define MCFINTC_ICR0 0x40 /* Base ICR register */ - -#define MCFINT_VECBASE 64 /* Vector base number */ -#define MCFINT_UART0 13 /* Interrupt number for UART0 */ -#define MCFINT_PIT1 55 /* Interrupt number for PIT1 */ - -/* - * SDRAM configuration registers. - */ -#define MCFSIM_DCR 0x44 /* SDRAM control */ -#define MCFSIM_DACR0 0x48 /* SDRAM base address 0 */ -#define MCFSIM_DMR0 0x4c /* SDRAM address mask 0 */ -#define MCFSIM_DACR1 0x50 /* SDRAM base address 1 */ -#define MCFSIM_DMR1 0x54 /* SDRAM address mask 1 */ - -/* - * Derek Cheung - 6 Feb 2005 - * add I2C and QSPI register definition using Freescale's MCF5282 - */ -/* set Port AS pin for I2C or UART */ -#define MCF5282_GPIO_PASPAR (volatile u16 *) (MCF_IPSBAR + 0x00100056) - -/* Port UA Pin Assignment Register (8 Bit) */ -#define MCF5282_GPIO_PUAPAR 0x10005C - -/* Interrupt Mask Register Register Low */ -#define MCF5282_INTC0_IMRL (volatile u32 *) (MCF_IPSBAR + 0x0C0C) -/* Interrupt Control Register 7 */ -#define MCF5282_INTC0_ICR17 (volatile u8 *) (MCF_IPSBAR + 0x0C51) - - - -/********************************************************************* -* -* Inter-IC (I2C) Module -* -*********************************************************************/ -/* Read/Write access macros for general use */ -#define MCF5282_I2C_I2ADR (volatile u8 *) (MCF_IPSBAR + 0x0300) // Address -#define MCF5282_I2C_I2FDR (volatile u8 *) (MCF_IPSBAR + 0x0304) // Freq Divider -#define MCF5282_I2C_I2CR (volatile u8 *) (MCF_IPSBAR + 0x0308) // Control -#define MCF5282_I2C_I2SR (volatile u8 *) (MCF_IPSBAR + 0x030C) // Status -#define MCF5282_I2C_I2DR (volatile u8 *) (MCF_IPSBAR + 0x0310) // Data I/O - -/* Bit level definitions and macros */ -#define MCF5282_I2C_I2ADR_ADDR(x) (((x)&0x7F)<<0x01) - -#define MCF5282_I2C_I2FDR_IC(x) (((x)&0x3F)) - -#define MCF5282_I2C_I2CR_IEN (0x80) // I2C enable -#define MCF5282_I2C_I2CR_IIEN (0x40) // interrupt enable -#define MCF5282_I2C_I2CR_MSTA (0x20) // master/slave mode -#define MCF5282_I2C_I2CR_MTX (0x10) // transmit/receive mode -#define MCF5282_I2C_I2CR_TXAK (0x08) // transmit acknowledge enable -#define MCF5282_I2C_I2CR_RSTA (0x04) // repeat start - -#define MCF5282_I2C_I2SR_ICF (0x80) // data transfer bit -#define MCF5282_I2C_I2SR_IAAS (0x40) // I2C addressed as a slave -#define MCF5282_I2C_I2SR_IBB (0x20) // I2C bus busy -#define MCF5282_I2C_I2SR_IAL (0x10) // aribitration lost -#define MCF5282_I2C_I2SR_SRW (0x04) // slave read/write -#define MCF5282_I2C_I2SR_IIF (0x02) // I2C interrupt -#define MCF5282_I2C_I2SR_RXAK (0x01) // received acknowledge - - - -/********************************************************************* -* -* Queued Serial Peripheral Interface (QSPI) Module -* -*********************************************************************/ -/* Derek - 21 Feb 2005 */ -/* change to the format used in I2C */ -/* Read/Write access macros for general use */ -#define MCF5282_QSPI_QMR MCF_IPSBAR + 0x0340 -#define MCF5282_QSPI_QDLYR MCF_IPSBAR + 0x0344 -#define MCF5282_QSPI_QWR MCF_IPSBAR + 0x0348 -#define MCF5282_QSPI_QIR MCF_IPSBAR + 0x034C -#define MCF5282_QSPI_QAR MCF_IPSBAR + 0x0350 -#define MCF5282_QSPI_QDR MCF_IPSBAR + 0x0354 -#define MCF5282_QSPI_QCR MCF_IPSBAR + 0x0354 - -/* Bit level definitions and macros */ -#define MCF5282_QSPI_QMR_MSTR (0x8000) -#define MCF5282_QSPI_QMR_DOHIE (0x4000) -#define MCF5282_QSPI_QMR_BITS_16 (0x0000) -#define MCF5282_QSPI_QMR_BITS_8 (0x2000) -#define MCF5282_QSPI_QMR_BITS_9 (0x2400) -#define MCF5282_QSPI_QMR_BITS_10 (0x2800) -#define MCF5282_QSPI_QMR_BITS_11 (0x2C00) -#define MCF5282_QSPI_QMR_BITS_12 (0x3000) -#define MCF5282_QSPI_QMR_BITS_13 (0x3400) -#define MCF5282_QSPI_QMR_BITS_14 (0x3800) -#define MCF5282_QSPI_QMR_BITS_15 (0x3C00) -#define MCF5282_QSPI_QMR_CPOL (0x0200) -#define MCF5282_QSPI_QMR_CPHA (0x0100) -#define MCF5282_QSPI_QMR_BAUD(x) (((x)&0x00FF)) - -#define MCF5282_QSPI_QDLYR_SPE (0x80) -#define MCF5282_QSPI_QDLYR_QCD(x) (((x)&0x007F)<<8) -#define MCF5282_QSPI_QDLYR_DTL(x) (((x)&0x00FF)) - -#define MCF5282_QSPI_QWR_HALT (0x8000) -#define MCF5282_QSPI_QWR_WREN (0x4000) -#define MCF5282_QSPI_QWR_WRTO (0x2000) -#define MCF5282_QSPI_QWR_CSIV (0x1000) -#define MCF5282_QSPI_QWR_ENDQP(x) (((x)&0x000F)<<8) -#define MCF5282_QSPI_QWR_CPTQP(x) (((x)&0x000F)<<4) -#define MCF5282_QSPI_QWR_NEWQP(x) (((x)&0x000F)) - -#define MCF5282_QSPI_QIR_WCEFB (0x8000) -#define MCF5282_QSPI_QIR_ABRTB (0x4000) -#define MCF5282_QSPI_QIR_ABRTL (0x1000) -#define MCF5282_QSPI_QIR_WCEFE (0x0800) -#define MCF5282_QSPI_QIR_ABRTE (0x0400) -#define MCF5282_QSPI_QIR_SPIFE (0x0100) -#define MCF5282_QSPI_QIR_WCEF (0x0008) -#define MCF5282_QSPI_QIR_ABRT (0x0004) -#define MCF5282_QSPI_QIR_SPIF (0x0001) - -#define MCF5282_QSPI_QAR_ADDR(x) (((x)&0x003F)) - -#define MCF5282_QSPI_QDR_COMMAND(x) (((x)&0xFF00)) -#define MCF5282_QSPI_QCR_DATA(x) (((x)&0x00FF)<<8) -#define MCF5282_QSPI_QCR_CONT (0x8000) -#define MCF5282_QSPI_QCR_BITSE (0x4000) -#define MCF5282_QSPI_QCR_DT (0x2000) -#define MCF5282_QSPI_QCR_DSCK (0x1000) -#define MCF5282_QSPI_QCR_CS (((x)&0x000F)<<8) - -/****************************************************************************/ -#endif /* m528xsim_h */ diff --git a/arch/m68knommu/include/asm/m5307sim.h b/arch/m68knommu/include/asm/m5307sim.h deleted file mode 100644 index 5886728409c..00000000000 --- a/arch/m68knommu/include/asm/m5307sim.h +++ /dev/null @@ -1,181 +0,0 @@ -/****************************************************************************/ - -/* - * m5307sim.h -- ColdFire 5307 System Integration Module support. - * - * (C) Copyright 1999, Moreton Bay Ventures Pty Ltd. - * (C) Copyright 1999, Lineo (www.lineo.com) - * - * Modified by David W. Miller for the MCF5307 Eval Board. - */ - -/****************************************************************************/ -#ifndef m5307sim_h -#define m5307sim_h -/****************************************************************************/ - -/* - * Define the 5307 SIM register set addresses. - */ -#define MCFSIM_RSR 0x00 /* Reset Status reg (r/w) */ -#define MCFSIM_SYPCR 0x01 /* System Protection reg (r/w)*/ -#define MCFSIM_SWIVR 0x02 /* SW Watchdog intr reg (r/w) */ -#define MCFSIM_SWSR 0x03 /* SW Watchdog service (r/w) */ -#define MCFSIM_PAR 0x04 /* Pin Assignment reg (r/w) */ -#define MCFSIM_IRQPAR 0x06 /* Interrupt Assignment reg (r/w) */ -#define MCFSIM_PLLCR 0x08 /* PLL Controll Reg*/ -#define MCFSIM_MPARK 0x0C /* BUS Master Control Reg*/ -#define MCFSIM_IPR 0x40 /* Interrupt Pend reg (r/w) */ -#define MCFSIM_IMR 0x44 /* Interrupt Mask reg (r/w) */ -#define MCFSIM_AVR 0x4b /* Autovector Ctrl reg (r/w) */ -#define MCFSIM_ICR0 0x4c /* Intr Ctrl reg 0 (r/w) */ -#define MCFSIM_ICR1 0x4d /* Intr Ctrl reg 1 (r/w) */ -#define MCFSIM_ICR2 0x4e /* Intr Ctrl reg 2 (r/w) */ -#define MCFSIM_ICR3 0x4f /* Intr Ctrl reg 3 (r/w) */ -#define MCFSIM_ICR4 0x50 /* Intr Ctrl reg 4 (r/w) */ -#define MCFSIM_ICR5 0x51 /* Intr Ctrl reg 5 (r/w) */ -#define MCFSIM_ICR6 0x52 /* Intr Ctrl reg 6 (r/w) */ -#define MCFSIM_ICR7 0x53 /* Intr Ctrl reg 7 (r/w) */ -#define MCFSIM_ICR8 0x54 /* Intr Ctrl reg 8 (r/w) */ -#define MCFSIM_ICR9 0x55 /* Intr Ctrl reg 9 (r/w) */ -#define MCFSIM_ICR10 0x56 /* Intr Ctrl reg 10 (r/w) */ -#define MCFSIM_ICR11 0x57 /* Intr Ctrl reg 11 (r/w) */ - -#define MCFSIM_CSAR0 0x80 /* CS 0 Address 0 reg (r/w) */ -#define MCFSIM_CSMR0 0x84 /* CS 0 Mask 0 reg (r/w) */ -#define MCFSIM_CSCR0 0x8a /* CS 0 Control reg (r/w) */ -#define MCFSIM_CSAR1 0x8c /* CS 1 Address reg (r/w) */ -#define MCFSIM_CSMR1 0x90 /* CS 1 Mask reg (r/w) */ -#define MCFSIM_CSCR1 0x96 /* CS 1 Control reg (r/w) */ - -#ifdef CONFIG_OLDMASK -#define MCFSIM_CSBAR 0x98 /* CS Base Address reg (r/w) */ -#define MCFSIM_CSBAMR 0x9c /* CS Base Mask reg (r/w) */ -#define MCFSIM_CSMR2 0x9e /* CS 2 Mask reg (r/w) */ -#define MCFSIM_CSCR2 0xa2 /* CS 2 Control reg (r/w) */ -#define MCFSIM_CSMR3 0xaa /* CS 3 Mask reg (r/w) */ -#define MCFSIM_CSCR3 0xae /* CS 3 Control reg (r/w) */ -#define MCFSIM_CSMR4 0xb6 /* CS 4 Mask reg (r/w) */ -#define MCFSIM_CSCR4 0xba /* CS 4 Control reg (r/w) */ -#define MCFSIM_CSMR5 0xc2 /* CS 5 Mask reg (r/w) */ -#define MCFSIM_CSCR5 0xc6 /* CS 5 Control reg (r/w) */ -#define MCFSIM_CSMR6 0xce /* CS 6 Mask reg (r/w) */ -#define MCFSIM_CSCR6 0xd2 /* CS 6 Control reg (r/w) */ -#define MCFSIM_CSMR7 0xda /* CS 7 Mask reg (r/w) */ -#define MCFSIM_CSCR7 0xde /* CS 7 Control reg (r/w) */ -#else -#define MCFSIM_CSAR2 0x98 /* CS 2 Address reg (r/w) */ -#define MCFSIM_CSMR2 0x9c /* CS 2 Mask reg (r/w) */ -#define MCFSIM_CSCR2 0xa2 /* CS 2 Control reg (r/w) */ -#define MCFSIM_CSAR3 0xa4 /* CS 3 Address reg (r/w) */ -#define MCFSIM_CSMR3 0xa8 /* CS 3 Mask reg (r/w) */ -#define MCFSIM_CSCR3 0xae /* CS 3 Control reg (r/w) */ -#define MCFSIM_CSAR4 0xb0 /* CS 4 Address reg (r/w) */ -#define MCFSIM_CSMR4 0xb4 /* CS 4 Mask reg (r/w) */ -#define MCFSIM_CSCR4 0xba /* CS 4 Control reg (r/w) */ -#define MCFSIM_CSAR5 0xbc /* CS 5 Address reg (r/w) */ -#define MCFSIM_CSMR5 0xc0 /* CS 5 Mask reg (r/w) */ -#define MCFSIM_CSCR5 0xc6 /* CS 5 Control reg (r/w) */ -#define MCFSIM_CSAR6 0xc8 /* CS 6 Address reg (r/w) */ -#define MCFSIM_CSMR6 0xcc /* CS 6 Mask reg (r/w) */ -#define MCFSIM_CSCR6 0xd2 /* CS 6 Control reg (r/w) */ -#define MCFSIM_CSAR7 0xd4 /* CS 7 Address reg (r/w) */ -#define MCFSIM_CSMR7 0xd8 /* CS 7 Mask reg (r/w) */ -#define MCFSIM_CSCR7 0xde /* CS 7 Control reg (r/w) */ -#endif /* CONFIG_OLDMASK */ - -#define MCFSIM_DCR 0x100 /* DRAM Control reg (r/w) */ -#define MCFSIM_DACR0 0x108 /* DRAM 0 Addr and Ctrl (r/w) */ -#define MCFSIM_DMR0 0x10c /* DRAM 0 Mask reg (r/w) */ -#define MCFSIM_DACR1 0x110 /* DRAM 1 Addr and Ctrl (r/w) */ -#define MCFSIM_DMR1 0x114 /* DRAM 1 Mask reg (r/w) */ - -#define MCFSIM_PADDR 0x244 /* Parallel Direction (r/w) */ -#define MCFSIM_PADAT 0x248 /* Parallel Data (r/w) */ - - -/* Definition offset address for CS2-7 -- old mask 5307 */ - -#define MCF5307_CS2 (0x400000) -#define MCF5307_CS3 (0x600000) -#define MCF5307_CS4 (0x800000) -#define MCF5307_CS5 (0xA00000) -#define MCF5307_CS6 (0xC00000) -#define MCF5307_CS7 (0xE00000) - - -/* - * Some symbol defines for the above... - */ -#define MCFSIM_SWDICR MCFSIM_ICR0 /* Watchdog timer ICR */ -#define MCFSIM_TIMER1ICR MCFSIM_ICR1 /* Timer 1 ICR */ -#define MCFSIM_TIMER2ICR MCFSIM_ICR2 /* Timer 2 ICR */ -#define MCFSIM_UART1ICR MCFSIM_ICR4 /* UART 1 ICR */ -#define MCFSIM_UART2ICR MCFSIM_ICR5 /* UART 2 ICR */ -#define MCFSIM_DMA0ICR MCFSIM_ICR6 /* DMA 0 ICR */ -#define MCFSIM_DMA1ICR MCFSIM_ICR7 /* DMA 1 ICR */ -#define MCFSIM_DMA2ICR MCFSIM_ICR8 /* DMA 2 ICR */ -#define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */ - -#if defined(CONFIG_M5307) -#define MCFSIM_IMR_MASKALL 0x3fffe /* All SIM intr sources */ -#endif - -/* - * Macro to set IMR register. It is 32 bits on the 5307. - */ -#define mcf_getimr() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) - -#define mcf_setimr(imr) \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr); - -#define mcf_getipr() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR)) - - -/* - * Some symbol defines for the Parallel Port Pin Assignment Register - */ -#define MCFSIM_PAR_DREQ0 0x40 /* Set to select DREQ0 input */ - /* Clear to select par I/O */ -#define MCFSIM_PAR_DREQ1 0x20 /* Select DREQ1 input */ - /* Clear to select par I/O */ - -/* - * Defines for the IRQPAR Register - */ -#define IRQ5_LEVEL4 0x80 -#define IRQ3_LEVEL6 0x40 -#define IRQ1_LEVEL2 0x20 - - -/* - * Define the Cache register flags. - */ -#define CACR_EC (1<<31) -#define CACR_ESB (1<<29) -#define CACR_DPI (1<<28) -#define CACR_HLCK (1<<27) -#define CACR_CINVA (1<<24) -#define CACR_DNFB (1<<10) -#define CACR_DCM_WTHRU (0<<8) -#define CACR_DCM_WBACK (1<<8) -#define CACR_DCM_OFF_PRE (2<<8) -#define CACR_DCM_OFF_IMP (3<<8) -#define CACR_DW (1<<5) - -#define ACR_BASE_POS 24 -#define ACR_MASK_POS 16 -#define ACR_ENABLE (1<<15) -#define ACR_USER (0<<13) -#define ACR_SUPER (1<<13) -#define ACR_ANY (2<<13) -#define ACR_CM_WTHRU (0<<5) -#define ACR_CM_WBACK (1<<5) -#define ACR_CM_OFF_PRE (2<<5) -#define ACR_CM_OFF_IMP (3<<5) -#define ACR_WPROTECT (1<<2) - -/****************************************************************************/ -#endif /* m5307sim_h */ diff --git a/arch/m68knommu/include/asm/m532xsim.h b/arch/m68knommu/include/asm/m532xsim.h deleted file mode 100644 index 1835fd20a82..00000000000 --- a/arch/m68knommu/include/asm/m532xsim.h +++ /dev/null @@ -1,2238 +0,0 @@ -/****************************************************************************/ - -/* - * m532xsim.h -- ColdFire 5329 registers - */ - -/****************************************************************************/ -#ifndef m532xsim_h -#define m532xsim_h -/****************************************************************************/ - -#define MCF_REG32(x) (*(volatile unsigned long *)(x)) -#define MCF_REG16(x) (*(volatile unsigned short *)(x)) -#define MCF_REG08(x) (*(volatile unsigned char *)(x)) - -#define MCFINT_VECBASE 64 -#define MCFINT_UART0 26 /* Interrupt number for UART0 */ -#define MCFINT_UART1 27 /* Interrupt number for UART1 */ - -#define MCF_WTM_WCR MCF_REG16(0xFC098000) - -/* - * Define the 532x SIM register set addresses. - */ -#define MCFSIM_IPRL 0xFC048004 -#define MCFSIM_IPRH 0xFC048000 -#define MCFSIM_IPR MCFSIM_IPRL -#define MCFSIM_IMRL 0xFC04800C -#define MCFSIM_IMRH 0xFC048008 -#define MCFSIM_IMR MCFSIM_IMRL -#define MCFSIM_ICR0 0xFC048040 -#define MCFSIM_ICR1 0xFC048041 -#define MCFSIM_ICR2 0xFC048042 -#define MCFSIM_ICR3 0xFC048043 -#define MCFSIM_ICR4 0xFC048044 -#define MCFSIM_ICR5 0xFC048045 -#define MCFSIM_ICR6 0xFC048046 -#define MCFSIM_ICR7 0xFC048047 -#define MCFSIM_ICR8 0xFC048048 -#define MCFSIM_ICR9 0xFC048049 -#define MCFSIM_ICR10 0xFC04804A -#define MCFSIM_ICR11 0xFC04804B - -/* - * Some symbol defines for the above... - */ -#define MCFSIM_SWDICR MCFSIM_ICR0 /* Watchdog timer ICR */ -#define MCFSIM_TIMER1ICR MCFSIM_ICR1 /* Timer 1 ICR */ -#define MCFSIM_TIMER2ICR MCFSIM_ICR2 /* Timer 2 ICR */ -#define MCFSIM_UART1ICR MCFSIM_ICR4 /* UART 1 ICR */ -#define MCFSIM_UART2ICR MCFSIM_ICR5 /* UART 2 ICR */ -#define MCFSIM_DMA0ICR MCFSIM_ICR6 /* DMA 0 ICR */ -#define MCFSIM_DMA1ICR MCFSIM_ICR7 /* DMA 1 ICR */ -#define MCFSIM_DMA2ICR MCFSIM_ICR8 /* DMA 2 ICR */ -#define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */ - - -#define MCFSIM_IMR_MASKALL 0xFFFFFFFF /* All SIM intr sources */ - -#define MCFSIM_IMR_SIMR0 0xFC04801C -#define MCFSIM_IMR_SIMR1 0xFC04C01C -#define MCFSIM_IMR_CIMR0 0xFC04801D -#define MCFSIM_IMR_CIMR1 0xFC04C01D - -#define MCFSIM_ICR_TIMER1 (0xFC048040+32) -#define MCFSIM_ICR_TIMER2 (0xFC048040+33) - - -/* - * Macro to set IMR register. It is 32 bits on the 5307. - */ -#define mcf_getimr() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) - -#define mcf_setimr(imr) \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr); - -#define mcf_getipr() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR)) - -#define mcf_getiprl() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPRL)) - -#define mcf_getiprh() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPRH)) - - -#define mcf_enable_irq0(irq) \ - *((volatile unsigned char*) (MCFSIM_IMR_CIMR0)) = (irq); - -#define mcf_enable_irq1(irq) \ - *((volatile unsigned char*) (MCFSIM_IMR_CIMR1)) = (irq); - -#define mcf_disable_irq0(irq) \ - *((volatile unsigned char*) (MCFSIM_IMR_SIMR0)) = (irq); - -#define mcf_disable_irq1(irq) \ - *((volatile unsigned char*) (MCFSIM_IMR_SIMR1)) = (irq); - -/* - * Define the Cache register flags. - */ -#define CACR_EC (1<<31) -#define CACR_ESB (1<<29) -#define CACR_DPI (1<<28) -#define CACR_HLCK (1<<27) -#define CACR_CINVA (1<<24) -#define CACR_DNFB (1<<10) -#define CACR_DCM_WTHRU (0<<8) -#define CACR_DCM_WBACK (1<<8) -#define CACR_DCM_OFF_PRE (2<<8) -#define CACR_DCM_OFF_IMP (3<<8) -#define CACR_DW (1<<5) - -#define ACR_BASE_POS 24 -#define ACR_MASK_POS 16 -#define ACR_ENABLE (1<<15) -#define ACR_USER (0<<13) -#define ACR_SUPER (1<<13) -#define ACR_ANY (2<<13) -#define ACR_CM_WTHRU (0<<5) -#define ACR_CM_WBACK (1<<5) -#define ACR_CM_OFF_PRE (2<<5) -#define ACR_CM_OFF_IMP (3<<5) -#define ACR_WPROTECT (1<<2) - -/********************************************************************* - * - * Inter-IC (I2C) Module - * - *********************************************************************/ - -/* Read/Write access macros for general use */ -#define MCF532x_I2C_I2ADR (volatile u8 *) (0xFC058000) // Address -#define MCF532x_I2C_I2FDR (volatile u8 *) (0xFC058004) // Freq Divider -#define MCF532x_I2C_I2CR (volatile u8 *) (0xFC058008) // Control -#define MCF532x_I2C_I2SR (volatile u8 *) (0xFC05800C) // Status -#define MCF532x_I2C_I2DR (volatile u8 *) (0xFC058010) // Data I/O - -/* Bit level definitions and macros */ -#define MCF532x_I2C_I2ADR_ADDR(x) (((x)&0x7F)<<0x01) - -#define MCF532x_I2C_I2FDR_IC(x) (((x)&0x3F)) - -#define MCF532x_I2C_I2CR_IEN (0x80) // I2C enable -#define MCF532x_I2C_I2CR_IIEN (0x40) // interrupt enable -#define MCF532x_I2C_I2CR_MSTA (0x20) // master/slave mode -#define MCF532x_I2C_I2CR_MTX (0x10) // transmit/receive mode -#define MCF532x_I2C_I2CR_TXAK (0x08) // transmit acknowledge enable -#define MCF532x_I2C_I2CR_RSTA (0x04) // repeat start - -#define MCF532x_I2C_I2SR_ICF (0x80) // data transfer bit -#define MCF532x_I2C_I2SR_IAAS (0x40) // I2C addressed as a slave -#define MCF532x_I2C_I2SR_IBB (0x20) // I2C bus busy -#define MCF532x_I2C_I2SR_IAL (0x10) // aribitration lost -#define MCF532x_I2C_I2SR_SRW (0x04) // slave read/write -#define MCF532x_I2C_I2SR_IIF (0x02) // I2C interrupt -#define MCF532x_I2C_I2SR_RXAK (0x01) // received acknowledge - -#define MCF532x_PAR_FECI2C (volatile u8 *) (0xFC0A4053) - - -/* - * The M5329EVB board needs a help getting its devices initialized - * at kernel start time if dBUG doesn't set it up (for example - * it is not used), so we need to do it manually. - */ -#ifdef __ASSEMBLER__ -.macro m5329EVB_setup - movel #0xFC098000, %a7 - movel #0x0, (%a7) -#define CORE_SRAM 0x80000000 -#define CORE_SRAM_SIZE 0x8000 - movel #CORE_SRAM, %d0 - addl #0x221, %d0 - movec %d0,%RAMBAR1 - movel #CORE_SRAM, %sp - addl #CORE_SRAM_SIZE, %sp - jsr sysinit -.endm -#define PLATFORM_SETUP m5329EVB_setup - -#endif /* __ASSEMBLER__ */ - -/********************************************************************* - * - * Chip Configuration Module (CCM) - * - *********************************************************************/ - -/* Register read/write macros */ -#define MCF_CCM_CCR MCF_REG16(0xFC0A0004) -#define MCF_CCM_RCON MCF_REG16(0xFC0A0008) -#define MCF_CCM_CIR MCF_REG16(0xFC0A000A) -#define MCF_CCM_MISCCR MCF_REG16(0xFC0A0010) -#define MCF_CCM_CDR MCF_REG16(0xFC0A0012) -#define MCF_CCM_UHCSR MCF_REG16(0xFC0A0014) -#define MCF_CCM_UOCSR MCF_REG16(0xFC0A0016) - -/* Bit definitions and macros for MCF_CCM_CCR */ -#define MCF_CCM_CCR_RESERVED (0x0001) -#define MCF_CCM_CCR_PLL_MODE (0x0003) -#define MCF_CCM_CCR_OSC_MODE (0x0005) -#define MCF_CCM_CCR_BOOTPS(x) (((x)&0x0003)<<3|0x0001) -#define MCF_CCM_CCR_LOAD (0x0021) -#define MCF_CCM_CCR_LIMP (0x0041) -#define MCF_CCM_CCR_CSC(x) (((x)&0x0003)<<8|0x0001) - -/* Bit definitions and macros for MCF_CCM_RCON */ -#define MCF_CCM_RCON_RESERVED (0x0001) -#define MCF_CCM_RCON_PLL_MODE (0x0003) -#define MCF_CCM_RCON_OSC_MODE (0x0005) -#define MCF_CCM_RCON_BOOTPS(x) (((x)&0x0003)<<3|0x0001) -#define MCF_CCM_RCON_LOAD (0x0021) -#define MCF_CCM_RCON_LIMP (0x0041) -#define MCF_CCM_RCON_CSC(x) (((x)&0x0003)<<8|0x0001) - -/* Bit definitions and macros for MCF_CCM_CIR */ -#define MCF_CCM_CIR_PRN(x) (((x)&0x003F)<<0) -#define MCF_CCM_CIR_PIN(x) (((x)&0x03FF)<<6) - -/* Bit definitions and macros for MCF_CCM_MISCCR */ -#define MCF_CCM_MISCCR_USBSRC (0x0001) -#define MCF_CCM_MISCCR_USBDIV (0x0002) -#define MCF_CCM_MISCCR_SSI_SRC (0x0010) -#define MCF_CCM_MISCCR_TIM_DMA (0x0020) -#define MCF_CCM_MISCCR_SSI_PUS (0x0040) -#define MCF_CCM_MISCCR_SSI_PUE (0x0080) -#define MCF_CCM_MISCCR_LCD_CHEN (0x0100) -#define MCF_CCM_MISCCR_LIMP (0x1000) -#define MCF_CCM_MISCCR_PLL_LOCK (0x2000) - -/* Bit definitions and macros for MCF_CCM_CDR */ -#define MCF_CCM_CDR_SSIDIV(x) (((x)&0x000F)<<0) -#define MCF_CCM_CDR_LPDIV(x) (((x)&0x000F)<<8) - -/* Bit definitions and macros for MCF_CCM_UHCSR */ -#define MCF_CCM_UHCSR_XPDE (0x0001) -#define MCF_CCM_UHCSR_UHMIE (0x0002) -#define MCF_CCM_UHCSR_WKUP (0x0004) -#define MCF_CCM_UHCSR_PORTIND(x) (((x)&0x0003)<<14) - -/* Bit definitions and macros for MCF_CCM_UOCSR */ -#define MCF_CCM_UOCSR_XPDE (0x0001) -#define MCF_CCM_UOCSR_UOMIE (0x0002) -#define MCF_CCM_UOCSR_WKUP (0x0004) -#define MCF_CCM_UOCSR_PWRFLT (0x0008) -#define MCF_CCM_UOCSR_SEND (0x0010) -#define MCF_CCM_UOCSR_VVLD (0x0020) -#define MCF_CCM_UOCSR_BVLD (0x0040) -#define MCF_CCM_UOCSR_AVLD (0x0080) -#define MCF_CCM_UOCSR_DPPU (0x0100) -#define MCF_CCM_UOCSR_DCR_VBUS (0x0200) -#define MCF_CCM_UOCSR_CRG_VBUS (0x0400) -#define MCF_CCM_UOCSR_DRV_VBUS (0x0800) -#define MCF_CCM_UOCSR_DMPD (0x1000) -#define MCF_CCM_UOCSR_DPPD (0x2000) -#define MCF_CCM_UOCSR_PORTIND(x) (((x)&0x0003)<<14) - -/********************************************************************* - * - * DMA Timers (DTIM) - * - *********************************************************************/ - -/* Register read/write macros */ -#define MCF_DTIM0_DTMR MCF_REG16(0xFC070000) -#define MCF_DTIM0_DTXMR MCF_REG08(0xFC070002) -#define MCF_DTIM0_DTER MCF_REG08(0xFC070003) -#define MCF_DTIM0_DTRR MCF_REG32(0xFC070004) -#define MCF_DTIM0_DTCR MCF_REG32(0xFC070008) -#define MCF_DTIM0_DTCN MCF_REG32(0xFC07000C) -#define MCF_DTIM1_DTMR MCF_REG16(0xFC074000) -#define MCF_DTIM1_DTXMR MCF_REG08(0xFC074002) -#define MCF_DTIM1_DTER MCF_REG08(0xFC074003) -#define MCF_DTIM1_DTRR MCF_REG32(0xFC074004) -#define MCF_DTIM1_DTCR MCF_REG32(0xFC074008) -#define MCF_DTIM1_DTCN MCF_REG32(0xFC07400C) -#define MCF_DTIM2_DTMR MCF_REG16(0xFC078000) -#define MCF_DTIM2_DTXMR MCF_REG08(0xFC078002) -#define MCF_DTIM2_DTER MCF_REG08(0xFC078003) -#define MCF_DTIM2_DTRR MCF_REG32(0xFC078004) -#define MCF_DTIM2_DTCR MCF_REG32(0xFC078008) -#define MCF_DTIM2_DTCN MCF_REG32(0xFC07800C) -#define MCF_DTIM3_DTMR MCF_REG16(0xFC07C000) -#define MCF_DTIM3_DTXMR MCF_REG08(0xFC07C002) -#define MCF_DTIM3_DTER MCF_REG08(0xFC07C003) -#define MCF_DTIM3_DTRR MCF_REG32(0xFC07C004) -#define MCF_DTIM3_DTCR MCF_REG32(0xFC07C008) -#define MCF_DTIM3_DTCN MCF_REG32(0xFC07C00C) -#define MCF_DTIM_DTMR(x) MCF_REG16(0xFC070000+((x)*0x4000)) -#define MCF_DTIM_DTXMR(x) MCF_REG08(0xFC070002+((x)*0x4000)) -#define MCF_DTIM_DTER(x) MCF_REG08(0xFC070003+((x)*0x4000)) -#define MCF_DTIM_DTRR(x) MCF_REG32(0xFC070004+((x)*0x4000)) -#define MCF_DTIM_DTCR(x) MCF_REG32(0xFC070008+((x)*0x4000)) -#define MCF_DTIM_DTCN(x) MCF_REG32(0xFC07000C+((x)*0x4000)) - -/* Bit definitions and macros for MCF_DTIM_DTMR */ -#define MCF_DTIM_DTMR_RST (0x0001) -#define MCF_DTIM_DTMR_CLK(x) (((x)&0x0003)<<1) -#define MCF_DTIM_DTMR_FRR (0x0008) -#define MCF_DTIM_DTMR_ORRI (0x0010) -#define MCF_DTIM_DTMR_OM (0x0020) -#define MCF_DTIM_DTMR_CE(x) (((x)&0x0003)<<6) -#define MCF_DTIM_DTMR_PS(x) (((x)&0x00FF)<<8) -#define MCF_DTIM_DTMR_CE_ANY (0x00C0) -#define MCF_DTIM_DTMR_CE_FALL (0x0080) -#define MCF_DTIM_DTMR_CE_RISE (0x0040) -#define MCF_DTIM_DTMR_CE_NONE (0x0000) -#define MCF_DTIM_DTMR_CLK_DTIN (0x0006) -#define MCF_DTIM_DTMR_CLK_DIV16 (0x0004) -#define MCF_DTIM_DTMR_CLK_DIV1 (0x0002) -#define MCF_DTIM_DTMR_CLK_STOP (0x0000) - -/* Bit definitions and macros for MCF_DTIM_DTXMR */ -#define MCF_DTIM_DTXMR_MODE16 (0x01) -#define MCF_DTIM_DTXMR_DMAEN (0x80) - -/* Bit definitions and macros for MCF_DTIM_DTER */ -#define MCF_DTIM_DTER_CAP (0x01) -#define MCF_DTIM_DTER_REF (0x02) - -/* Bit definitions and macros for MCF_DTIM_DTRR */ -#define MCF_DTIM_DTRR_REF(x) (((x)&0xFFFFFFFF)<<0) - -/* Bit definitions and macros for MCF_DTIM_DTCR */ -#define MCF_DTIM_DTCR_CAP(x) (((x)&0xFFFFFFFF)<<0) - -/* Bit definitions and macros for MCF_DTIM_DTCN */ -#define MCF_DTIM_DTCN_CNT(x) (((x)&0xFFFFFFFF)<<0) - -/********************************************************************* - * - * FlexBus Chip Selects (FBCS) - * - *********************************************************************/ - -/* Register read/write macros */ -#define MCF_FBCS0_CSAR MCF_REG32(0xFC008000) -#define MCF_FBCS0_CSMR MCF_REG32(0xFC008004) -#define MCF_FBCS0_CSCR MCF_REG32(0xFC008008) -#define MCF_FBCS1_CSAR MCF_REG32(0xFC00800C) -#define MCF_FBCS1_CSMR MCF_REG32(0xFC008010) -#define MCF_FBCS1_CSCR MCF_REG32(0xFC008014) -#define MCF_FBCS2_CSAR MCF_REG32(0xFC008018) -#define MCF_FBCS2_CSMR MCF_REG32(0xFC00801C) -#define MCF_FBCS2_CSCR MCF_REG32(0xFC008020) -#define MCF_FBCS3_CSAR MCF_REG32(0xFC008024) -#define MCF_FBCS3_CSMR MCF_REG32(0xFC008028) -#define MCF_FBCS3_CSCR MCF_REG32(0xFC00802C) -#define MCF_FBCS4_CSAR MCF_REG32(0xFC008030) -#define MCF_FBCS4_CSMR MCF_REG32(0xFC008034) -#define MCF_FBCS4_CSCR MCF_REG32(0xFC008038) -#define MCF_FBCS5_CSAR MCF_REG32(0xFC00803C) -#define MCF_FBCS5_CSMR MCF_REG32(0xFC008040) -#define MCF_FBCS5_CSCR MCF_REG32(0xFC008044) -#define MCF_FBCS_CSAR(x) MCF_REG32(0xFC008000+((x)*0x00C)) -#define MCF_FBCS_CSMR(x) MCF_REG32(0xFC008004+((x)*0x00C)) -#define MCF_FBCS_CSCR(x) MCF_REG32(0xFC008008+((x)*0x00C)) - -/* Bit definitions and macros for MCF_FBCS_CSAR */ -#define MCF_FBCS_CSAR_BA(x) ((x)&0xFFFF0000) - -/* Bit definitions and macros for MCF_FBCS_CSMR */ -#define MCF_FBCS_CSMR_V (0x00000001) -#define MCF_FBCS_CSMR_WP (0x00000100) -#define MCF_FBCS_CSMR_BAM(x) (((x)&0x0000FFFF)<<16) -#define MCF_FBCS_CSMR_BAM_4G (0xFFFF0000) -#define MCF_FBCS_CSMR_BAM_2G (0x7FFF0000) -#define MCF_FBCS_CSMR_BAM_1G (0x3FFF0000) -#define MCF_FBCS_CSMR_BAM_1024M (0x3FFF0000) -#define MCF_FBCS_CSMR_BAM_512M (0x1FFF0000) -#define MCF_FBCS_CSMR_BAM_256M (0x0FFF0000) -#define MCF_FBCS_CSMR_BAM_128M (0x07FF0000) -#define MCF_FBCS_CSMR_BAM_64M (0x03FF0000) -#define MCF_FBCS_CSMR_BAM_32M (0x01FF0000) -#define MCF_FBCS_CSMR_BAM_16M (0x00FF0000) -#define MCF_FBCS_CSMR_BAM_8M (0x007F0000) -#define MCF_FBCS_CSMR_BAM_4M (0x003F0000) -#define MCF_FBCS_CSMR_BAM_2M (0x001F0000) -#define MCF_FBCS_CSMR_BAM_1M (0x000F0000) -#define MCF_FBCS_CSMR_BAM_1024K (0x000F0000) -#define MCF_FBCS_CSMR_BAM_512K (0x00070000) -#define MCF_FBCS_CSMR_BAM_256K (0x00030000) -#define MCF_FBCS_CSMR_BAM_128K (0x00010000) -#define MCF_FBCS_CSMR_BAM_64K (0x00000000) - -/* Bit definitions and macros for MCF_FBCS_CSCR */ -#define MCF_FBCS_CSCR_BSTW (0x00000008) -#define MCF_FBCS_CSCR_BSTR (0x00000010) -#define MCF_FBCS_CSCR_BEM (0x00000020) -#define MCF_FBCS_CSCR_PS(x) (((x)&0x00000003)<<6) -#define MCF_FBCS_CSCR_AA (0x00000100) -#define MCF_FBCS_CSCR_SBM (0x00000200) -#define MCF_FBCS_CSCR_WS(x) (((x)&0x0000003F)<<10) -#define MCF_FBCS_CSCR_WRAH(x) (((x)&0x00000003)<<16) -#define MCF_FBCS_CSCR_RDAH(x) (((x)&0x00000003)<<18) -#define MCF_FBCS_CSCR_ASET(x) (((x)&0x00000003)<<20) -#define MCF_FBCS_CSCR_SWSEN (0x00800000) -#define MCF_FBCS_CSCR_SWS(x) (((x)&0x0000003F)<<26) -#define MCF_FBCS_CSCR_PS_8 (0x0040) -#define MCF_FBCS_CSCR_PS_16 (0x0080) -#define MCF_FBCS_CSCR_PS_32 (0x0000) - -/********************************************************************* - * - * General Purpose I/O (GPIO) - * - *********************************************************************/ - -/* Register read/write macros */ -#define MCF_GPIO_PODR_FECH MCF_REG08(0xFC0A4000) -#define MCF_GPIO_PODR_FECL MCF_REG08(0xFC0A4001) -#define MCF_GPIO_PODR_SSI MCF_REG08(0xFC0A4002) -#define MCF_GPIO_PODR_BUSCTL MCF_REG08(0xFC0A4003) -#define MCF_GPIO_PODR_BE MCF_REG08(0xFC0A4004) -#define MCF_GPIO_PODR_CS MCF_REG08(0xFC0A4005) -#define MCF_GPIO_PODR_PWM MCF_REG08(0xFC0A4006) -#define MCF_GPIO_PODR_FECI2C MCF_REG08(0xFC0A4007) -#define MCF_GPIO_PODR_UART MCF_REG08(0xFC0A4009) -#define MCF_GPIO_PODR_QSPI MCF_REG08(0xFC0A400A) -#define MCF_GPIO_PODR_TIMER MCF_REG08(0xFC0A400B) -#define MCF_GPIO_PODR_LCDDATAH MCF_REG08(0xFC0A400D) -#define MCF_GPIO_PODR_LCDDATAM MCF_REG08(0xFC0A400E) -#define MCF_GPIO_PODR_LCDDATAL MCF_REG08(0xFC0A400F) -#define MCF_GPIO_PODR_LCDCTLH MCF_REG08(0xFC0A4010) -#define MCF_GPIO_PODR_LCDCTLL MCF_REG08(0xFC0A4011) -#define MCF_GPIO_PDDR_FECH MCF_REG08(0xFC0A4014) -#define MCF_GPIO_PDDR_FECL MCF_REG08(0xFC0A4015) -#define MCF_GPIO_PDDR_SSI MCF_REG08(0xFC0A4016) -#define MCF_GPIO_PDDR_BUSCTL MCF_REG08(0xFC0A4017) -#define MCF_GPIO_PDDR_BE MCF_REG08(0xFC0A4018) -#define MCF_GPIO_PDDR_CS MCF_REG08(0xFC0A4019) -#define MCF_GPIO_PDDR_PWM MCF_REG08(0xFC0A401A) -#define MCF_GPIO_PDDR_FECI2C MCF_REG08(0xFC0A401B) -#define MCF_GPIO_PDDR_UART MCF_REG08(0xFC0A401C) -#define MCF_GPIO_PDDR_QSPI MCF_REG08(0xFC0A401E) -#define MCF_GPIO_PDDR_TIMER MCF_REG08(0xFC0A401F) -#define MCF_GPIO_PDDR_LCDDATAH MCF_REG08(0xFC0A4021) -#define MCF_GPIO_PDDR_LCDDATAM MCF_REG08(0xFC0A4022) -#define MCF_GPIO_PDDR_LCDDATAL MCF_REG08(0xFC0A4023) -#define MCF_GPIO_PDDR_LCDCTLH MCF_REG08(0xFC0A4024) -#define MCF_GPIO_PDDR_LCDCTLL MCF_REG08(0xFC0A4025) -#define MCF_GPIO_PPDSDR_FECH MCF_REG08(0xFC0A4028) -#define MCF_GPIO_PPDSDR_FECL MCF_REG08(0xFC0A4029) -#define MCF_GPIO_PPDSDR_SSI MCF_REG08(0xFC0A402A) -#define MCF_GPIO_PPDSDR_BUSCTL MCF_REG08(0xFC0A402B) -#define MCF_GPIO_PPDSDR_BE MCF_REG08(0xFC0A402C) -#define MCF_GPIO_PPDSDR_CS MCF_REG08(0xFC0A402D) -#define MCF_GPIO_PPDSDR_PWM MCF_REG08(0xFC0A402E) -#define MCF_GPIO_PPDSDR_FECI2C MCF_REG08(0xFC0A402F) -#define MCF_GPIO_PPDSDR_UART MCF_REG08(0xFC0A4031) -#define MCF_GPIO_PPDSDR_QSPI MCF_REG08(0xFC0A4032) -#define MCF_GPIO_PPDSDR_TIMER MCF_REG08(0xFC0A4033) -#define MCF_GPIO_PPDSDR_LCDDATAH MCF_REG08(0xFC0A4035) -#define MCF_GPIO_PPDSDR_LCDDATAM MCF_REG08(0xFC0A4036) -#define MCF_GPIO_PPDSDR_LCDDATAL MCF_REG08(0xFC0A4037) -#define MCF_GPIO_PPDSDR_LCDCTLH MCF_REG08(0xFC0A4038) -#define MCF_GPIO_PPDSDR_LCDCTLL MCF_REG08(0xFC0A4039) -#define MCF_GPIO_PCLRR_FECH MCF_REG08(0xFC0A403C) -#define MCF_GPIO_PCLRR_FECL MCF_REG08(0xFC0A403D) -#define MCF_GPIO_PCLRR_SSI MCF_REG08(0xFC0A403E) -#define MCF_GPIO_PCLRR_BUSCTL MCF_REG08(0xFC0A403F) -#define MCF_GPIO_PCLRR_BE MCF_REG08(0xFC0A4040) -#define MCF_GPIO_PCLRR_CS MCF_REG08(0xFC0A4041) -#define MCF_GPIO_PCLRR_PWM MCF_REG08(0xFC0A4042) -#define MCF_GPIO_PCLRR_FECI2C MCF_REG08(0xFC0A4043) -#define MCF_GPIO_PCLRR_UART MCF_REG08(0xFC0A4045) -#define MCF_GPIO_PCLRR_QSPI MCF_REG08(0xFC0A4046) -#define MCF_GPIO_PCLRR_TIMER MCF_REG08(0xFC0A4047) -#define MCF_GPIO_PCLRR_LCDDATAH MCF_REG08(0xFC0A4049) -#define MCF_GPIO_PCLRR_LCDDATAM MCF_REG08(0xFC0A404A) -#define MCF_GPIO_PCLRR_LCDDATAL MCF_REG08(0xFC0A404B) -#define MCF_GPIO_PCLRR_LCDCTLH MCF_REG08(0xFC0A404C) -#define MCF_GPIO_PCLRR_LCDCTLL MCF_REG08(0xFC0A404D) -#define MCF_GPIO_PAR_FEC MCF_REG08(0xFC0A4050) -#define MCF_GPIO_PAR_PWM MCF_REG08(0xFC0A4051) -#define MCF_GPIO_PAR_BUSCTL MCF_REG08(0xFC0A4052) -#define MCF_GPIO_PAR_FECI2C MCF_REG08(0xFC0A4053) -#define MCF_GPIO_PAR_BE MCF_REG08(0xFC0A4054) -#define MCF_GPIO_PAR_CS MCF_REG08(0xFC0A4055) -#define MCF_GPIO_PAR_SSI MCF_REG16(0xFC0A4056) -#define MCF_GPIO_PAR_UART MCF_REG16(0xFC0A4058) -#define MCF_GPIO_PAR_QSPI MCF_REG16(0xFC0A405A) -#define MCF_GPIO_PAR_TIMER MCF_REG08(0xFC0A405C) -#define MCF_GPIO_PAR_LCDDATA MCF_REG08(0xFC0A405D) -#define MCF_GPIO_PAR_LCDCTL MCF_REG16(0xFC0A405E) -#define MCF_GPIO_PAR_IRQ MCF_REG16(0xFC0A4060) -#define MCF_GPIO_MSCR_FLEXBUS MCF_REG08(0xFC0A4064) -#define MCF_GPIO_MSCR_SDRAM MCF_REG08(0xFC0A4065) -#define MCF_GPIO_DSCR_I2C MCF_REG08(0xFC0A4068) -#define MCF_GPIO_DSCR_PWM MCF_REG08(0xFC0A4069) -#define MCF_GPIO_DSCR_FEC MCF_REG08(0xFC0A406A) -#define MCF_GPIO_DSCR_UART MCF_REG08(0xFC0A406B) -#define MCF_GPIO_DSCR_QSPI MCF_REG08(0xFC0A406C) -#define MCF_GPIO_DSCR_TIMER MCF_REG08(0xFC0A406D) -#define MCF_GPIO_DSCR_SSI MCF_REG08(0xFC0A406E) -#define MCF_GPIO_DSCR_LCD MCF_REG08(0xFC0A406F) -#define MCF_GPIO_DSCR_DEBUG MCF_REG08(0xFC0A4070) -#define MCF_GPIO_DSCR_CLKRST MCF_REG08(0xFC0A4071) -#define MCF_GPIO_DSCR_IRQ MCF_REG08(0xFC0A4072) - -/* Bit definitions and macros for MCF_GPIO_PODR_FECH */ -#define MCF_GPIO_PODR_FECH_PODR_FECH0 (0x01) -#define MCF_GPIO_PODR_FECH_PODR_FECH1 (0x02) -#define MCF_GPIO_PODR_FECH_PODR_FECH2 (0x04) -#define MCF_GPIO_PODR_FECH_PODR_FECH3 (0x08) -#define MCF_GPIO_PODR_FECH_PODR_FECH4 (0x10) -#define MCF_GPIO_PODR_FECH_PODR_FECH5 (0x20) -#define MCF_GPIO_PODR_FECH_PODR_FECH6 (0x40) -#define MCF_GPIO_PODR_FECH_PODR_FECH7 (0x80) - -/* Bit definitions and macros for MCF_GPIO_PODR_FECL */ -#define MCF_GPIO_PODR_FECL_PODR_FECL0 (0x01) -#define MCF_GPIO_PODR_FECL_PODR_FECL1 (0x02) -#define MCF_GPIO_PODR_FECL_PODR_FECL2 (0x04) -#define MCF_GPIO_PODR_FECL_PODR_FECL3 (0x08) -#define MCF_GPIO_PODR_FECL_PODR_FECL4 (0x10) -#define MCF_GPIO_PODR_FECL_PODR_FECL5 (0x20) -#define MCF_GPIO_PODR_FECL_PODR_FECL6 (0x40) -#define MCF_GPIO_PODR_FECL_PODR_FECL7 (0x80) - -/* Bit definitions and macros for MCF_GPIO_PODR_SSI */ -#define MCF_GPIO_PODR_SSI_PODR_SSI0 (0x01) -#define MCF_GPIO_PODR_SSI_PODR_SSI1 (0x02) -#define MCF_GPIO_PODR_SSI_PODR_SSI2 (0x04) -#define MCF_GPIO_PODR_SSI_PODR_SSI3 (0x08) -#define MCF_GPIO_PODR_SSI_PODR_SSI4 (0x10) - -/* Bit definitions and macros for MCF_GPIO_PODR_BUSCTL */ -#define MCF_GPIO_PODR_BUSCTL_POSDR_BUSCTL0 (0x01) -#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL1 (0x02) -#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL2 (0x04) -#define MCF_GPIO_PODR_BUSCTL_PODR_BUSCTL3 (0x08) - -/* Bit definitions and macros for MCF_GPIO_PODR_BE */ -#define MCF_GPIO_PODR_BE_PODR_BE0 (0x01) -#define MCF_GPIO_PODR_BE_PODR_BE1 (0x02) -#define MCF_GPIO_PODR_BE_PODR_BE2 (0x04) -#define MCF_GPIO_PODR_BE_PODR_BE3 (0x08) - -/* Bit definitions and macros for MCF_GPIO_PODR_CS */ -#define MCF_GPIO_PODR_CS_PODR_CS1 (0x02) -#define MCF_GPIO_PODR_CS_PODR_CS2 (0x04) -#define MCF_GPIO_PODR_CS_PODR_CS3 (0x08) -#define MCF_GPIO_PODR_CS_PODR_CS4 (0x10) -#define MCF_GPIO_PODR_CS_PODR_CS5 (0x20) - -/* Bit definitions and macros for MCF_GPIO_PODR_PWM */ -#define MCF_GPIO_PODR_PWM_PODR_PWM2 (0x04) -#define MCF_GPIO_PODR_PWM_PODR_PWM3 (0x08) -#define MCF_GPIO_PODR_PWM_PODR_PWM4 (0x10) -#define MCF_GPIO_PODR_PWM_PODR_PWM5 (0x20) - -/* Bit definitions and macros for MCF_GPIO_PODR_FECI2C */ -#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C0 (0x01) -#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C1 (0x02) -#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C2 (0x04) -#define MCF_GPIO_PODR_FECI2C_PODR_FECI2C3 (0x08) - -/* Bit definitions and macros for MCF_GPIO_PODR_UART */ -#define MCF_GPIO_PODR_UART_PODR_UART0 (0x01) -#define MCF_GPIO_PODR_UART_PODR_UART1 (0x02) -#define MCF_GPIO_PODR_UART_PODR_UART2 (0x04) -#define MCF_GPIO_PODR_UART_PODR_UART3 (0x08) -#define MCF_GPIO_PODR_UART_PODR_UART4 (0x10) -#define MCF_GPIO_PODR_UART_PODR_UART5 (0x20) -#define MCF_GPIO_PODR_UART_PODR_UART6 (0x40) -#define MCF_GPIO_PODR_UART_PODR_UART7 (0x80) - -/* Bit definitions and macros for MCF_GPIO_PODR_QSPI */ -#define MCF_GPIO_PODR_QSPI_PODR_QSPI0 (0x01) -#define MCF_GPIO_PODR_QSPI_PODR_QSPI1 (0x02) -#define MCF_GPIO_PODR_QSPI_PODR_QSPI2 (0x04) -#define MCF_GPIO_PODR_QSPI_PODR_QSPI3 (0x08) -#define MCF_GPIO_PODR_QSPI_PODR_QSPI4 (0x10) -#define MCF_GPIO_PODR_QSPI_PODR_QSPI5 (0x20) - -/* Bit definitions and macros for MCF_GPIO_PODR_TIMER */ -#define MCF_GPIO_PODR_TIMER_PODR_TIMER0 (0x01) -#define MCF_GPIO_PODR_TIMER_PODR_TIMER1 (0x02) -#define MCF_GPIO_PODR_TIMER_PODR_TIMER2 (0x04) -#define MCF_GPIO_PODR_TIMER_PODR_TIMER3 (0x08) - -/* Bit definitions and macros for MCF_GPIO_PODR_LCDDATAH */ -#define MCF_GPIO_PODR_LCDDATAH_PODR_LCDDATAH0 (0x01) -#define MCF_GPIO_PODR_LCDDATAH_PODR_LCDDATAH1 (0x02) - -/* Bit definitions and macros for MCF_GPIO_PODR_LCDDATAM */ -#define MCF_GPIO_PODR_LCDDATAM_PODR_LCDDATAM0 (0x01) -#define MCF_GPIO_PODR_LCDDATAM_PODR_LCDDATAM1 (0x02) -#define MCF_GPIO_PODR_LCDDATAM_PODR_LCDDATAM2 (0x04) -#define MCF_GPIO_PODR_LCDDATAM_PODR_LCDDATAM3 (0x08) -#define MCF_GPIO_PODR_LCDDATAM_PODR_LCDDATAM4 (0x10) -#define MCF_GPIO_PODR_LCDDATAM_PODR_LCDDATAM5 (0x20) -#define MCF_GPIO_PODR_LCDDATAM_PODR_LCDDATAM6 (0x40) -#define MCF_GPIO_PODR_LCDDATAM_PODR_LCDDATAM7 (0x80) - -/* Bit definitions and macros for MCF_GPIO_PODR_LCDDATAL */ -#define MCF_GPIO_PODR_LCDDATAL_PODR_LCDDATAL0 (0x01) -#define MCF_GPIO_PODR_LCDDATAL_PODR_LCDDATAL1 (0x02) -#define MCF_GPIO_PODR_LCDDATAL_PODR_LCDDATAL2 (0x04) -#define MCF_GPIO_PODR_LCDDATAL_PODR_LCDDATAL3 (0x08) -#define MCF_GPIO_PODR_LCDDATAL_PODR_LCDDATAL4 (0x10) -#define MCF_GPIO_PODR_LCDDATAL_PODR_LCDDATAL5 (0x20) -#define MCF_GPIO_PODR_LCDDATAL_PODR_LCDDATAL6 (0x40) -#define MCF_GPIO_PODR_LCDDATAL_PODR_LCDDATAL7 (0x80) - -/* Bit definitions and macros for MCF_GPIO_PODR_LCDCTLH */ -#define MCF_GPIO_PODR_LCDCTLH_PODR_LCDCTLH0 (0x01) - -/* Bit definitions and macros for MCF_GPIO_PODR_LCDCTLL */ -#define MCF_GPIO_PODR_LCDCTLL_PODR_LCDCTLL0 (0x01) -#define MCF_GPIO_PODR_LCDCTLL_PODR_LCDCTLL1 (0x02) -#define MCF_GPIO_PODR_LCDCTLL_PODR_LCDCTLL2 (0x04) -#define MCF_GPIO_PODR_LCDCTLL_PODR_LCDCTLL3 (0x08) -#define MCF_GPIO_PODR_LCDCTLL_PODR_LCDCTLL4 (0x10) -#define MCF_GPIO_PODR_LCDCTLL_PODR_LCDCTLL5 (0x20) -#define MCF_GPIO_PODR_LCDCTLL_PODR_LCDCTLL6 (0x40) -#define MCF_GPIO_PODR_LCDCTLL_PODR_LCDCTLL7 (0x80) - -/* Bit definitions and macros for MCF_GPIO_PDDR_FECH */ -#define MCF_GPIO_PDDR_FECH_PDDR_FECH0 (0x01) -#define MCF_GPIO_PDDR_FECH_PDDR_FECH1 (0x02) -#define MCF_GPIO_PDDR_FECH_PDDR_FECH2 (0x04) -#define MCF_GPIO_PDDR_FECH_PDDR_FECH3 (0x08) -#define MCF_GPIO_PDDR_FECH_PDDR_FECH4 (0x10) -#define MCF_GPIO_PDDR_FECH_PDDR_FECH5 (0x20) -#define MCF_GPIO_PDDR_FECH_PDDR_FECH6 (0x40) -#define MCF_GPIO_PDDR_FECH_PDDR_FECH7 (0x80) - -/* Bit definitions and macros for MCF_GPIO_PDDR_FECL */ -#define MCF_GPIO_PDDR_FECL_PDDR_FECL0 (0x01) -#define MCF_GPIO_PDDR_FECL_PDDR_FECL1 (0x02) -#define MCF_GPIO_PDDR_FECL_PDDR_FECL2 (0x04) -#define MCF_GPIO_PDDR_FECL_PDDR_FECL3 (0x08) -#define MCF_GPIO_PDDR_FECL_PDDR_FECL4 (0x10) -#define MCF_GPIO_PDDR_FECL_PDDR_FECL5 (0x20) -#define MCF_GPIO_PDDR_FECL_PDDR_FECL6 (0x40) -#define MCF_GPIO_PDDR_FECL_PDDR_FECL7 (0x80) - -/* Bit definitions and macros for MCF_GPIO_PDDR_SSI */ -#define MCF_GPIO_PDDR_SSI_PDDR_SSI0 (0x01) -#define MCF_GPIO_PDDR_SSI_PDDR_SSI1 (0x02) -#define MCF_GPIO_PDDR_SSI_PDDR_SSI2 (0x04) -#define MCF_GPIO_PDDR_SSI_PDDR_SSI3 (0x08) -#define MCF_GPIO_PDDR_SSI_PDDR_SSI4 (0x10) - -/* Bit definitions and macros for MCF_GPIO_PDDR_BUSCTL */ -#define MCF_GPIO_PDDR_BUSCTL_POSDR_BUSCTL0 (0x01) -#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL1 (0x02) -#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL2 (0x04) -#define MCF_GPIO_PDDR_BUSCTL_PDDR_BUSCTL3 (0x08) - -/* Bit definitions and macros for MCF_GPIO_PDDR_BE */ -#define MCF_GPIO_PDDR_BE_PDDR_BE0 (0x01) -#define MCF_GPIO_PDDR_BE_PDDR_BE1 (0x02) -#define MCF_GPIO_PDDR_BE_PDDR_BE2 (0x04) -#define MCF_GPIO_PDDR_BE_PDDR_BE3 (0x08) - -/* Bit definitions and macros for MCF_GPIO_PDDR_CS */ -#define MCF_GPIO_PDDR_CS_PDDR_CS1 (0x02) -#define MCF_GPIO_PDDR_CS_PDDR_CS2 (0x04) -#define MCF_GPIO_PDDR_CS_PDDR_CS3 (0x08) -#define MCF_GPIO_PDDR_CS_PDDR_CS4 (0x10) -#define MCF_GPIO_PDDR_CS_PDDR_CS5 (0x20) - -/* Bit definitions and macros for MCF_GPIO_PDDR_PWM */ -#define MCF_GPIO_PDDR_PWM_PDDR_PWM2 (0x04) -#define MCF_GPIO_PDDR_PWM_PDDR_PWM3 (0x08) -#define MCF_GPIO_PDDR_PWM_PDDR_PWM4 (0x10) -#define MCF_GPIO_PDDR_PWM_PDDR_PWM5 (0x20) - -/* Bit definitions and macros for MCF_GPIO_PDDR_FECI2C */ -#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C0 (0x01) -#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C1 (0x02) -#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C2 (0x04) -#define MCF_GPIO_PDDR_FECI2C_PDDR_FECI2C3 (0x08) - -/* Bit definitions and macros for MCF_GPIO_PDDR_UART */ -#define MCF_GPIO_PDDR_UART_PDDR_UART0 (0x01) -#define MCF_GPIO_PDDR_UART_PDDR_UART1 (0x02) -#define MCF_GPIO_PDDR_UART_PDDR_UART2 (0x04) -#define MCF_GPIO_PDDR_UART_PDDR_UART3 (0x08) -#define MCF_GPIO_PDDR_UART_PDDR_UART4 (0x10) -#define MCF_GPIO_PDDR_UART_PDDR_UART5 (0x20) -#define MCF_GPIO_PDDR_UART_PDDR_UART6 (0x40) -#define MCF_GPIO_PDDR_UART_PDDR_UART7 (0x80) - -/* Bit definitions and macros for MCF_GPIO_PDDR_QSPI */ -#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI0 (0x01) -#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI1 (0x02) -#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI2 (0x04) -#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI3 (0x08) -#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI4 (0x10) -#define MCF_GPIO_PDDR_QSPI_PDDR_QSPI5 (0x20) - -/* Bit definitions and macros for MCF_GPIO_PDDR_TIMER */ -#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER0 (0x01) -#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER1 (0x02) -#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER2 (0x04) -#define MCF_GPIO_PDDR_TIMER_PDDR_TIMER3 (0x08) - -/* Bit definitions and macros for MCF_GPIO_PDDR_LCDDATAH */ -#define MCF_GPIO_PDDR_LCDDATAH_PDDR_LCDDATAH0 (0x01) -#define MCF_GPIO_PDDR_LCDDATAH_PDDR_LCDDATAH1 (0x02) - -/* Bit definitions and macros for MCF_GPIO_PDDR_LCDDATAM */ -#define MCF_GPIO_PDDR_LCDDATAM_PDDR_LCDDATAM0 (0x01) -#define MCF_GPIO_PDDR_LCDDATAM_PDDR_LCDDATAM1 (0x02) -#define MCF_GPIO_PDDR_LCDDATAM_PDDR_LCDDATAM2 (0x04) -#define MCF_GPIO_PDDR_LCDDATAM_PDDR_LCDDATAM3 (0x08) -#define MCF_GPIO_PDDR_LCDDATAM_PDDR_LCDDATAM4 (0x10) -#define MCF_GPIO_PDDR_LCDDATAM_PDDR_LCDDATAM5 (0x20) -#define MCF_GPIO_PDDR_LCDDATAM_PDDR_LCDDATAM6 (0x40) -#define MCF_GPIO_PDDR_LCDDATAM_PDDR_LCDDATAM7 (0x80) - -/* Bit definitions and macros for MCF_GPIO_PDDR_LCDDATAL */ -#define MCF_GPIO_PDDR_LCDDATAL_PDDR_LCDDATAL0 (0x01) -#define MCF_GPIO_PDDR_LCDDATAL_PDDR_LCDDATAL1 (0x02) -#define MCF_GPIO_PDDR_LCDDATAL_PDDR_LCDDATAL2 (0x04) -#define MCF_GPIO_PDDR_LCDDATAL_PDDR_LCDDATAL3 (0x08) -#define MCF_GPIO_PDDR_LCDDATAL_PDDR_LCDDATAL4 (0x10) -#define MCF_GPIO_PDDR_LCDDATAL_PDDR_LCDDATAL5 (0x20) -#define MCF_GPIO_PDDR_LCDDATAL_PDDR_LCDDATAL6 (0x40) -#define MCF_GPIO_PDDR_LCDDATAL_PDDR_LCDDATAL7 (0x80) - -/* Bit definitions and macros for MCF_GPIO_PDDR_LCDCTLH */ -#define MCF_GPIO_PDDR_LCDCTLH_PDDR_LCDCTLH0 (0x01) - -/* Bit definitions and macros for MCF_GPIO_PDDR_LCDCTLL */ -#define MCF_GPIO_PDDR_LCDCTLL_PDDR_LCDCTLL0 (0x01) -#define MCF_GPIO_PDDR_LCDCTLL_PDDR_LCDCTLL1 (0x02) -#define MCF_GPIO_PDDR_LCDCTLL_PDDR_LCDCTLL2 (0x04) -#define MCF_GPIO_PDDR_LCDCTLL_PDDR_LCDCTLL3 (0x08) -#define MCF_GPIO_PDDR_LCDCTLL_PDDR_LCDCTLL4 (0x10) -#define MCF_GPIO_PDDR_LCDCTLL_PDDR_LCDCTLL5 (0x20) -#define MCF_GPIO_PDDR_LCDCTLL_PDDR_LCDCTLL6 (0x40) -#define MCF_GPIO_PDDR_LCDCTLL_PDDR_LCDCTLL7 (0x80) - -/* Bit definitions and macros for MCF_GPIO_PPDSDR_FECH */ -#define MCF_GPIO_PPDSDR_FECH_PPDSDR_FECH0 (0x01) -#define MCF_GPIO_PPDSDR_FECH_PPDSDR_FECH1 (0x02) -#define MCF_GPIO_PPDSDR_FECH_PPDSDR_FECH2 (0x04) -#define MCF_GPIO_PPDSDR_FECH_PPDSDR_FECH3 (0x08) -#define MCF_GPIO_PPDSDR_FECH_PPDSDR_FECH4 (0x10) -#define MCF_GPIO_PPDSDR_FECH_PPDSDR_FECH5 (0x20) -#define MCF_GPIO_PPDSDR_FECH_PPDSDR_FECH6 (0x40) -#define MCF_GPIO_PPDSDR_FECH_PPDSDR_FECH7 (0x80) - -/* Bit definitions and macros for MCF_GPIO_PPDSDR_FECL */ -#define MCF_GPIO_PPDSDR_FECL_PPDSDR_FECL0 (0x01) -#define MCF_GPIO_PPDSDR_FECL_PPDSDR_FECL1 (0x02) -#define MCF_GPIO_PPDSDR_FECL_PPDSDR_FECL2 (0x04) -#define MCF_GPIO_PPDSDR_FECL_PPDSDR_FECL3 (0x08) -#define MCF_GPIO_PPDSDR_FECL_PPDSDR_FECL4 (0x10) -#define MCF_GPIO_PPDSDR_FECL_PPDSDR_FECL5 (0x20) -#define MCF_GPIO_PPDSDR_FECL_PPDSDR_FECL6 (0x40) -#define MCF_GPIO_PPDSDR_FECL_PPDSDR_FECL7 (0x80) - -/* Bit definitions and macros for MCF_GPIO_PPDSDR_SSI */ -#define MCF_GPIO_PPDSDR_SSI_PPDSDR_SSI0 (0x01) -#define MCF_GPIO_PPDSDR_SSI_PPDSDR_SSI1 (0x02) -#define MCF_GPIO_PPDSDR_SSI_PPDSDR_SSI2 (0x04) -#define MCF_GPIO_PPDSDR_SSI_PPDSDR_SSI3 (0x08) -#define MCF_GPIO_PPDSDR_SSI_PPDSDR_SSI4 (0x10) - -/* Bit definitions and macros for MCF_GPIO_PPDSDR_BUSCTL */ -#define MCF_GPIO_PPDSDR_BUSCTL_POSDR_BUSCTL0 (0x01) -#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL1 (0x02) -#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL2 (0x04) -#define MCF_GPIO_PPDSDR_BUSCTL_PPDSDR_BUSCTL3 (0x08) - -/* Bit definitions and macros for MCF_GPIO_PPDSDR_BE */ -#define MCF_GPIO_PPDSDR_BE_PPDSDR_BE0 (0x01) -#define MCF_GPIO_PPDSDR_BE_PPDSDR_BE1 (0x02) -#define MCF_GPIO_PPDSDR_BE_PPDSDR_BE2 (0x04) -#define MCF_GPIO_PPDSDR_BE_PPDSDR_BE3 (0x08) - -/* Bit definitions and macros for MCF_GPIO_PPDSDR_CS */ -#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS1 (0x02) -#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS2 (0x04) -#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS3 (0x08) -#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS4 (0x10) -#define MCF_GPIO_PPDSDR_CS_PPDSDR_CS5 (0x20) - -/* Bit definitions and macros for MCF_GPIO_PPDSDR_PWM */ -#define MCF_GPIO_PPDSDR_PWM_PPDSDR_PWM2 (0x04) -#define MCF_GPIO_PPDSDR_PWM_PPDSDR_PWM3 (0x08) -#define MCF_GPIO_PPDSDR_PWM_PPDSDR_PWM4 (0x10) -#define MCF_GPIO_PPDSDR_PWM_PPDSDR_PWM5 (0x20) - -/* Bit definitions and macros for MCF_GPIO_PPDSDR_FECI2C */ -#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C0 (0x01) -#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C1 (0x02) -#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C2 (0x04) -#define MCF_GPIO_PPDSDR_FECI2C_PPDSDR_FECI2C3 (0x08) - -/* Bit definitions and macros for MCF_GPIO_PPDSDR_UART */ -#define MCF_GPIO_PPDSDR_UART_PPDSDR_UART0 (0x01) -#define MCF_GPIO_PPDSDR_UART_PPDSDR_UART1 (0x02) -#define MCF_GPIO_PPDSDR_UART_PPDSDR_UART2 (0x04) -#define MCF_GPIO_PPDSDR_UART_PPDSDR_UART3 (0x08) -#define MCF_GPIO_PPDSDR_UART_PPDSDR_UART4 (0x10) -#define MCF_GPIO_PPDSDR_UART_PPDSDR_UART5 (0x20) -#define MCF_GPIO_PPDSDR_UART_PPDSDR_UART6 (0x40) -#define MCF_GPIO_PPDSDR_UART_PPDSDR_UART7 (0x80) - -/* Bit definitions and macros for MCF_GPIO_PPDSDR_QSPI */ -#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI0 (0x01) -#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI1 (0x02) -#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI2 (0x04) -#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI3 (0x08) -#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI4 (0x10) -#define MCF_GPIO_PPDSDR_QSPI_PPDSDR_QSPI5 (0x20) - -/* Bit definitions and macros for MCF_GPIO_PPDSDR_TIMER */ -#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER0 (0x01) -#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER1 (0x02) -#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER2 (0x04) -#define MCF_GPIO_PPDSDR_TIMER_PPDSDR_TIMER3 (0x08) - -/* Bit definitions and macros for MCF_GPIO_PPDSDR_LCDDATAH */ -#define MCF_GPIO_PPDSDR_LCDDATAH_PPDSDR_LCDDATAH0 (0x01) -#define MCF_GPIO_PPDSDR_LCDDATAH_PPDSDR_LCDDATAH1 (0x02) - -/* Bit definitions and macros for MCF_GPIO_PPDSDR_LCDDATAM */ -#define MCF_GPIO_PPDSDR_LCDDATAM_PPDSDR_LCDDATAM0 (0x01) -#define MCF_GPIO_PPDSDR_LCDDATAM_PPDSDR_LCDDATAM1 (0x02) -#define MCF_GPIO_PPDSDR_LCDDATAM_PPDSDR_LCDDATAM2 (0x04) -#define MCF_GPIO_PPDSDR_LCDDATAM_PPDSDR_LCDDATAM3 (0x08) -#define MCF_GPIO_PPDSDR_LCDDATAM_PPDSDR_LCDDATAM4 (0x10) -#define MCF_GPIO_PPDSDR_LCDDATAM_PPDSDR_LCDDATAM5 (0x20) -#define MCF_GPIO_PPDSDR_LCDDATAM_PPDSDR_LCDDATAM6 (0x40) -#define MCF_GPIO_PPDSDR_LCDDATAM_PPDSDR_LCDDATAM7 (0x80) - -/* Bit definitions and macros for MCF_GPIO_PPDSDR_LCDDATAL */ -#define MCF_GPIO_PPDSDR_LCDDATAL_PPDSDR_LCDDATAL0 (0x01) -#define MCF_GPIO_PPDSDR_LCDDATAL_PPDSDR_LCDDATAL1 (0x02) -#define MCF_GPIO_PPDSDR_LCDDATAL_PPDSDR_LCDDATAL2 (0x04) -#define MCF_GPIO_PPDSDR_LCDDATAL_PPDSDR_LCDDATAL3 (0x08) -#define MCF_GPIO_PPDSDR_LCDDATAL_PPDSDR_LCDDATAL4 (0x10) -#define MCF_GPIO_PPDSDR_LCDDATAL_PPDSDR_LCDDATAL5 (0x20) -#define MCF_GPIO_PPDSDR_LCDDATAL_PPDSDR_LCDDATAL6 (0x40) -#define MCF_GPIO_PPDSDR_LCDDATAL_PPDSDR_LCDDATAL7 (0x80) - -/* Bit definitions and macros for MCF_GPIO_PPDSDR_LCDCTLH */ -#define MCF_GPIO_PPDSDR_LCDCTLH_PPDSDR_LCDCTLH0 (0x01) - -/* Bit definitions and macros for MCF_GPIO_PPDSDR_LCDCTLL */ -#define MCF_GPIO_PPDSDR_LCDCTLL_PPDSDR_LCDCTLL0 (0x01) -#define MCF_GPIO_PPDSDR_LCDCTLL_PPDSDR_LCDCTLL1 (0x02) -#define MCF_GPIO_PPDSDR_LCDCTLL_PPDSDR_LCDCTLL2 (0x04) -#define MCF_GPIO_PPDSDR_LCDCTLL_PPDSDR_LCDCTLL3 (0x08) -#define MCF_GPIO_PPDSDR_LCDCTLL_PPDSDR_LCDCTLL4 (0x10) -#define MCF_GPIO_PPDSDR_LCDCTLL_PPDSDR_LCDCTLL5 (0x20) -#define MCF_GPIO_PPDSDR_LCDCTLL_PPDSDR_LCDCTLL6 (0x40) -#define MCF_GPIO_PPDSDR_LCDCTLL_PPDSDR_LCDCTLL7 (0x80) - -/* Bit definitions and macros for MCF_GPIO_PCLRR_FECH */ -#define MCF_GPIO_PCLRR_FECH_PCLRR_FECH0 (0x01) -#define MCF_GPIO_PCLRR_FECH_PCLRR_FECH1 (0x02) -#define MCF_GPIO_PCLRR_FECH_PCLRR_FECH2 (0x04) -#define MCF_GPIO_PCLRR_FECH_PCLRR_FECH3 (0x08) -#define MCF_GPIO_PCLRR_FECH_PCLRR_FECH4 (0x10) -#define MCF_GPIO_PCLRR_FECH_PCLRR_FECH5 (0x20) -#define MCF_GPIO_PCLRR_FECH_PCLRR_FECH6 (0x40) -#define MCF_GPIO_PCLRR_FECH_PCLRR_FECH7 (0x80) - -/* Bit definitions and macros for MCF_GPIO_PCLRR_FECL */ -#define MCF_GPIO_PCLRR_FECL_PCLRR_FECL0 (0x01) -#define MCF_GPIO_PCLRR_FECL_PCLRR_FECL1 (0x02) -#define MCF_GPIO_PCLRR_FECL_PCLRR_FECL2 (0x04) -#define MCF_GPIO_PCLRR_FECL_PCLRR_FECL3 (0x08) -#define MCF_GPIO_PCLRR_FECL_PCLRR_FECL4 (0x10) -#define MCF_GPIO_PCLRR_FECL_PCLRR_FECL5 (0x20) -#define MCF_GPIO_PCLRR_FECL_PCLRR_FECL6 (0x40) -#define MCF_GPIO_PCLRR_FECL_PCLRR_FECL7 (0x80) - -/* Bit definitions and macros for MCF_GPIO_PCLRR_SSI */ -#define MCF_GPIO_PCLRR_SSI_PCLRR_SSI0 (0x01) -#define MCF_GPIO_PCLRR_SSI_PCLRR_SSI1 (0x02) -#define MCF_GPIO_PCLRR_SSI_PCLRR_SSI2 (0x04) -#define MCF_GPIO_PCLRR_SSI_PCLRR_SSI3 (0x08) -#define MCF_GPIO_PCLRR_SSI_PCLRR_SSI4 (0x10) - -/* Bit definitions and macros for MCF_GPIO_PCLRR_BUSCTL */ -#define MCF_GPIO_PCLRR_BUSCTL_POSDR_BUSCTL0 (0x01) -#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL1 (0x02) -#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL2 (0x04) -#define MCF_GPIO_PCLRR_BUSCTL_PCLRR_BUSCTL3 (0x08) - -/* Bit definitions and macros for MCF_GPIO_PCLRR_BE */ -#define MCF_GPIO_PCLRR_BE_PCLRR_BE0 (0x01) -#define MCF_GPIO_PCLRR_BE_PCLRR_BE1 (0x02) -#define MCF_GPIO_PCLRR_BE_PCLRR_BE2 (0x04) -#define MCF_GPIO_PCLRR_BE_PCLRR_BE3 (0x08) - -/* Bit definitions and macros for MCF_GPIO_PCLRR_CS */ -#define MCF_GPIO_PCLRR_CS_PCLRR_CS1 (0x02) -#define MCF_GPIO_PCLRR_CS_PCLRR_CS2 (0x04) -#define MCF_GPIO_PCLRR_CS_PCLRR_CS3 (0x08) -#define MCF_GPIO_PCLRR_CS_PCLRR_CS4 (0x10) -#define MCF_GPIO_PCLRR_CS_PCLRR_CS5 (0x20) - -/* Bit definitions and macros for MCF_GPIO_PCLRR_PWM */ -#define MCF_GPIO_PCLRR_PWM_PCLRR_PWM2 (0x04) -#define MCF_GPIO_PCLRR_PWM_PCLRR_PWM3 (0x08) -#define MCF_GPIO_PCLRR_PWM_PCLRR_PWM4 (0x10) -#define MCF_GPIO_PCLRR_PWM_PCLRR_PWM5 (0x20) - -/* Bit definitions and macros for MCF_GPIO_PCLRR_FECI2C */ -#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C0 (0x01) -#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C1 (0x02) -#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C2 (0x04) -#define MCF_GPIO_PCLRR_FECI2C_PCLRR_FECI2C3 (0x08) - -/* Bit definitions and macros for MCF_GPIO_PCLRR_UART */ -#define MCF_GPIO_PCLRR_UART_PCLRR_UART0 (0x01) -#define MCF_GPIO_PCLRR_UART_PCLRR_UART1 (0x02) -#define MCF_GPIO_PCLRR_UART_PCLRR_UART2 (0x04) -#define MCF_GPIO_PCLRR_UART_PCLRR_UART3 (0x08) -#define MCF_GPIO_PCLRR_UART_PCLRR_UART4 (0x10) -#define MCF_GPIO_PCLRR_UART_PCLRR_UART5 (0x20) -#define MCF_GPIO_PCLRR_UART_PCLRR_UART6 (0x40) -#define MCF_GPIO_PCLRR_UART_PCLRR_UART7 (0x80) - -/* Bit definitions and macros for MCF_GPIO_PCLRR_QSPI */ -#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI0 (0x01) -#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI1 (0x02) -#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI2 (0x04) -#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI3 (0x08) -#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI4 (0x10) -#define MCF_GPIO_PCLRR_QSPI_PCLRR_QSPI5 (0x20) - -/* Bit definitions and macros for MCF_GPIO_PCLRR_TIMER */ -#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER0 (0x01) -#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER1 (0x02) -#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER2 (0x04) -#define MCF_GPIO_PCLRR_TIMER_PCLRR_TIMER3 (0x08) - -/* Bit definitions and macros for MCF_GPIO_PCLRR_LCDDATAH */ -#define MCF_GPIO_PCLRR_LCDDATAH_PCLRR_LCDDATAH0 (0x01) -#define MCF_GPIO_PCLRR_LCDDATAH_PCLRR_LCDDATAH1 (0x02) - -/* Bit definitions and macros for MCF_GPIO_PCLRR_LCDDATAM */ -#define MCF_GPIO_PCLRR_LCDDATAM_PCLRR_LCDDATAM0 (0x01) -#define MCF_GPIO_PCLRR_LCDDATAM_PCLRR_LCDDATAM1 (0x02) -#define MCF_GPIO_PCLRR_LCDDATAM_PCLRR_LCDDATAM2 (0x04) -#define MCF_GPIO_PCLRR_LCDDATAM_PCLRR_LCDDATAM3 (0x08) -#define MCF_GPIO_PCLRR_LCDDATAM_PCLRR_LCDDATAM4 (0x10) -#define MCF_GPIO_PCLRR_LCDDATAM_PCLRR_LCDDATAM5 (0x20) -#define MCF_GPIO_PCLRR_LCDDATAM_PCLRR_LCDDATAM6 (0x40) -#define MCF_GPIO_PCLRR_LCDDATAM_PCLRR_LCDDATAM7 (0x80) - -/* Bit definitions and macros for MCF_GPIO_PCLRR_LCDDATAL */ -#define MCF_GPIO_PCLRR_LCDDATAL_PCLRR_LCDDATAL0 (0x01) -#define MCF_GPIO_PCLRR_LCDDATAL_PCLRR_LCDDATAL1 (0x02) -#define MCF_GPIO_PCLRR_LCDDATAL_PCLRR_LCDDATAL2 (0x04) -#define MCF_GPIO_PCLRR_LCDDATAL_PCLRR_LCDDATAL3 (0x08) -#define MCF_GPIO_PCLRR_LCDDATAL_PCLRR_LCDDATAL4 (0x10) -#define MCF_GPIO_PCLRR_LCDDATAL_PCLRR_LCDDATAL5 (0x20) -#define MCF_GPIO_PCLRR_LCDDATAL_PCLRR_LCDDATAL6 (0x40) -#define MCF_GPIO_PCLRR_LCDDATAL_PCLRR_LCDDATAL7 (0x80) - -/* Bit definitions and macros for MCF_GPIO_PCLRR_LCDCTLH */ -#define MCF_GPIO_PCLRR_LCDCTLH_PCLRR_LCDCTLH0 (0x01) - -/* Bit definitions and macros for MCF_GPIO_PCLRR_LCDCTLL */ -#define MCF_GPIO_PCLRR_LCDCTLL_PCLRR_LCDCTLL0 (0x01) -#define MCF_GPIO_PCLRR_LCDCTLL_PCLRR_LCDCTLL1 (0x02) -#define MCF_GPIO_PCLRR_LCDCTLL_PCLRR_LCDCTLL2 (0x04) -#define MCF_GPIO_PCLRR_LCDCTLL_PCLRR_LCDCTLL3 (0x08) -#define MCF_GPIO_PCLRR_LCDCTLL_PCLRR_LCDCTLL4 (0x10) -#define MCF_GPIO_PCLRR_LCDCTLL_PCLRR_LCDCTLL5 (0x20) -#define MCF_GPIO_PCLRR_LCDCTLL_PCLRR_LCDCTLL6 (0x40) -#define MCF_GPIO_PCLRR_LCDCTLL_PCLRR_LCDCTLL7 (0x80) - -/* Bit definitions and macros for MCF_GPIO_PAR_FEC */ -#define MCF_GPIO_PAR_FEC_PAR_FEC_MII(x) (((x)&0x03)<<0) -#define MCF_GPIO_PAR_FEC_PAR_FEC_7W(x) (((x)&0x03)<<2) -#define MCF_GPIO_PAR_FEC_PAR_FEC_7W_GPIO (0x00) -#define MCF_GPIO_PAR_FEC_PAR_FEC_7W_URTS1 (0x04) -#define MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC (0x0C) -#define MCF_GPIO_PAR_FEC_PAR_FEC_MII_GPIO (0x00) -#define MCF_GPIO_PAR_FEC_PAR_FEC_MII_UART (0x01) -#define MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC (0x03) - -/* Bit definitions and macros for MCF_GPIO_PAR_PWM */ -#define MCF_GPIO_PAR_PWM_PAR_PWM1(x) (((x)&0x03)<<0) -#define MCF_GPIO_PAR_PWM_PAR_PWM3(x) (((x)&0x03)<<2) -#define MCF_GPIO_PAR_PWM_PAR_PWM5 (0x10) -#define MCF_GPIO_PAR_PWM_PAR_PWM7 (0x20) - -/* Bit definitions and macros for MCF_GPIO_PAR_BUSCTL */ -#define MCF_GPIO_PAR_BUSCTL_PAR_TS(x) (((x)&0x03)<<3) -#define MCF_GPIO_PAR_BUSCTL_PAR_RWB (0x20) -#define MCF_GPIO_PAR_BUSCTL_PAR_TA (0x40) -#define MCF_GPIO_PAR_BUSCTL_PAR_OE (0x80) -#define MCF_GPIO_PAR_BUSCTL_PAR_OE_GPIO (0x00) -#define MCF_GPIO_PAR_BUSCTL_PAR_OE_OE (0x80) -#define MCF_GPIO_PAR_BUSCTL_PAR_TA_GPIO (0x00) -#define MCF_GPIO_PAR_BUSCTL_PAR_TA_TA (0x40) -#define MCF_GPIO_PAR_BUSCTL_PAR_RWB_GPIO (0x00) -#define MCF_GPIO_PAR_BUSCTL_PAR_RWB_RWB (0x20) -#define MCF_GPIO_PAR_BUSCTL_PAR_TS_GPIO (0x00) -#define MCF_GPIO_PAR_BUSCTL_PAR_TS_DACK0 (0x10) -#define MCF_GPIO_PAR_BUSCTL_PAR_TS_TS (0x18) - -/* Bit definitions and macros for MCF_GPIO_PAR_FECI2C */ -#define MCF_GPIO_PAR_FECI2C_PAR_SDA(x) (((x)&0x03)<<0) -#define MCF_GPIO_PAR_FECI2C_PAR_SCL(x) (((x)&0x03)<<2) -#define MCF_GPIO_PAR_FECI2C_PAR_MDIO(x) (((x)&0x03)<<4) -#define MCF_GPIO_PAR_FECI2C_PAR_MDC(x) (((x)&0x03)<<6) -#define MCF_GPIO_PAR_FECI2C_PAR_MDC_GPIO (0x00) -#define MCF_GPIO_PAR_FECI2C_PAR_MDC_UTXD2 (0x40) -#define MCF_GPIO_PAR_FECI2C_PAR_MDC_SCL (0x80) -#define MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC (0xC0) -#define MCF_GPIO_PAR_FECI2C_PAR_MDIO_GPIO (0x00) -#define MCF_GPIO_PAR_FECI2C_PAR_MDIO_URXD2 (0x10) -#define MCF_GPIO_PAR_FECI2C_PAR_MDIO_SDA (0x20) -#define MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO (0x30) -#define MCF_GPIO_PAR_FECI2C_PAR_SCL_GPIO (0x00) -#define MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2 (0x04) -#define MCF_GPIO_PAR_FECI2C_PAR_SCL_SCL (0x0C) -#define MCF_GPIO_PAR_FECI2C_PAR_SDA_GPIO (0x00) -#define MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2 (0x02) -#define MCF_GPIO_PAR_FECI2C_PAR_SDA_SDA (0x03) - -/* Bit definitions and macros for MCF_GPIO_PAR_BE */ -#define MCF_GPIO_PAR_BE_PAR_BE0 (0x01) -#define MCF_GPIO_PAR_BE_PAR_BE1 (0x02) -#define MCF_GPIO_PAR_BE_PAR_BE2 (0x04) -#define MCF_GPIO_PAR_BE_PAR_BE3 (0x08) - -/* Bit definitions and macros for MCF_GPIO_PAR_CS */ -#define MCF_GPIO_PAR_CS_PAR_CS1 (0x02) -#define MCF_GPIO_PAR_CS_PAR_CS2 (0x04) -#define MCF_GPIO_PAR_CS_PAR_CS3 (0x08) -#define MCF_GPIO_PAR_CS_PAR_CS4 (0x10) -#define MCF_GPIO_PAR_CS_PAR_CS5 (0x20) -#define MCF_GPIO_PAR_CS_PAR_CS_CS1_GPIO (0x00) -#define MCF_GPIO_PAR_CS_PAR_CS_CS1_SDCS1 (0x01) -#define MCF_GPIO_PAR_CS_PAR_CS_CS1_CS1 (0x03) - -/* Bit definitions and macros for MCF_GPIO_PAR_SSI */ -#define MCF_GPIO_PAR_SSI_PAR_MCLK (0x0080) -#define MCF_GPIO_PAR_SSI_PAR_TXD(x) (((x)&0x0003)<<8) -#define MCF_GPIO_PAR_SSI_PAR_RXD(x) (((x)&0x0003)<<10) -#define MCF_GPIO_PAR_SSI_PAR_FS(x) (((x)&0x0003)<<12) -#define MCF_GPIO_PAR_SSI_PAR_BCLK(x) (((x)&0x0003)<<14) - -/* Bit definitions and macros for MCF_GPIO_PAR_UART */ -#define MCF_GPIO_PAR_UART_PAR_UTXD0 (0x0001) -#define MCF_GPIO_PAR_UART_PAR_URXD0 (0x0002) -#define MCF_GPIO_PAR_UART_PAR_URTS0 (0x0004) -#define MCF_GPIO_PAR_UART_PAR_UCTS0 (0x0008) -#define MCF_GPIO_PAR_UART_PAR_UTXD1(x) (((x)&0x0003)<<4) -#define MCF_GPIO_PAR_UART_PAR_URXD1(x) (((x)&0x0003)<<6) -#define MCF_GPIO_PAR_UART_PAR_URTS1(x) (((x)&0x0003)<<8) -#define MCF_GPIO_PAR_UART_PAR_UCTS1(x) (((x)&0x0003)<<10) -#define MCF_GPIO_PAR_UART_PAR_UCTS1_GPIO (0x0000) -#define MCF_GPIO_PAR_UART_PAR_UCTS1_SSI_BCLK (0x0800) -#define MCF_GPIO_PAR_UART_PAR_UCTS1_ULPI_D7 (0x0400) -#define MCF_GPIO_PAR_UART_PAR_UCTS1_UCTS1 (0x0C00) -#define MCF_GPIO_PAR_UART_PAR_URTS1_GPIO (0x0000) -#define MCF_GPIO_PAR_UART_PAR_URTS1_SSI_FS (0x0200) -#define MCF_GPIO_PAR_UART_PAR_URTS1_ULPI_D6 (0x0100) -#define MCF_GPIO_PAR_UART_PAR_URTS1_URTS1 (0x0300) -#define MCF_GPIO_PAR_UART_PAR_URXD1_GPIO (0x0000) -#define MCF_GPIO_PAR_UART_PAR_URXD1_SSI_RXD (0x0080) -#define MCF_GPIO_PAR_UART_PAR_URXD1_ULPI_D5 (0x0040) -#define MCF_GPIO_PAR_UART_PAR_URXD1_URXD1 (0x00C0) -#define MCF_GPIO_PAR_UART_PAR_UTXD1_GPIO (0x0000) -#define MCF_GPIO_PAR_UART_PAR_UTXD1_SSI_TXD (0x0020) -#define MCF_GPIO_PAR_UART_PAR_UTXD1_ULPI_D4 (0x0010) -#define MCF_GPIO_PAR_UART_PAR_UTXD1_UTXD1 (0x0030) - -/* Bit definitions and macros for MCF_GPIO_PAR_QSPI */ -#define MCF_GPIO_PAR_QSPI_PAR_SCK(x) (((x)&0x0003)<<4) -#define MCF_GPIO_PAR_QSPI_PAR_DOUT(x) (((x)&0x0003)<<6) -#define MCF_GPIO_PAR_QSPI_PAR_DIN(x) (((x)&0x0003)<<8) -#define MCF_GPIO_PAR_QSPI_PAR_PCS0(x) (((x)&0x0003)<<10) -#define MCF_GPIO_PAR_QSPI_PAR_PCS1(x) (((x)&0x0003)<<12) -#define MCF_GPIO_PAR_QSPI_PAR_PCS2(x) (((x)&0x0003)<<14) - -/* Bit definitions and macros for MCF_GPIO_PAR_TIMER */ -#define MCF_GPIO_PAR_TIMER_PAR_TIN0(x) (((x)&0x03)<<0) -#define MCF_GPIO_PAR_TIMER_PAR_TIN1(x) (((x)&0x03)<<2) -#define MCF_GPIO_PAR_TIMER_PAR_TIN2(x) (((x)&0x03)<<4) -#define MCF_GPIO_PAR_TIMER_PAR_TIN3(x) (((x)&0x03)<<6) -#define MCF_GPIO_PAR_TIMER_PAR_TIN3_GPIO (0x00) -#define MCF_GPIO_PAR_TIMER_PAR_TIN3_TOUT3 (0x80) -#define MCF_GPIO_PAR_TIMER_PAR_TIN3_URXD2 (0x40) -#define MCF_GPIO_PAR_TIMER_PAR_TIN3_TIN3 (0xC0) -#define MCF_GPIO_PAR_TIMER_PAR_TIN2_GPIO (0x00) -#define MCF_GPIO_PAR_TIMER_PAR_TIN2_TOUT2 (0x20) -#define MCF_GPIO_PAR_TIMER_PAR_TIN2_UTXD2 (0x10) -#define MCF_GPIO_PAR_TIMER_PAR_TIN2_TIN2 (0x30) -#define MCF_GPIO_PAR_TIMER_PAR_TIN1_GPIO (0x00) -#define MCF_GPIO_PAR_TIMER_PAR_TIN1_TOUT1 (0x08) -#define MCF_GPIO_PAR_TIMER_PAR_TIN1_DACK1 (0x04) -#define MCF_GPIO_PAR_TIMER_PAR_TIN1_TIN1 (0x0C) -#define MCF_GPIO_PAR_TIMER_PAR_TIN0_GPIO (0x00) -#define MCF_GPIO_PAR_TIMER_PAR_TIN0_TOUT0 (0x02) -#define MCF_GPIO_PAR_TIMER_PAR_TIN0_DREQ0 (0x01) -#define MCF_GPIO_PAR_TIMER_PAR_TIN0_TIN0 (0x03) - -/* Bit definitions and macros for MCF_GPIO_PAR_LCDDATA */ -#define MCF_GPIO_PAR_LCDDATA_PAR_LD7_0(x) (((x)&0x03)<<0) -#define MCF_GPIO_PAR_LCDDATA_PAR_LD15_8(x) (((x)&0x03)<<2) -#define MCF_GPIO_PAR_LCDDATA_PAR_LD16(x) (((x)&0x03)<<4) -#define MCF_GPIO_PAR_LCDDATA_PAR_LD17(x) (((x)&0x03)<<6) - -/* Bit definitions and macros for MCF_GPIO_PAR_LCDCTL */ -#define MCF_GPIO_PAR_LCDCTL_PAR_CLS (0x0001) -#define MCF_GPIO_PAR_LCDCTL_PAR_PS (0x0002) -#define MCF_GPIO_PAR_LCDCTL_PAR_REV (0x0004) -#define MCF_GPIO_PAR_LCDCTL_PAR_SPL_SPR (0x0008) -#define MCF_GPIO_PAR_LCDCTL_PAR_CONTRAST (0x0010) -#define MCF_GPIO_PAR_LCDCTL_PAR_LSCLK (0x0020) -#define MCF_GPIO_PAR_LCDCTL_PAR_LP_HSYNC (0x0040) -#define MCF_GPIO_PAR_LCDCTL_PAR_FLM_VSYNC (0x0080) -#define MCF_GPIO_PAR_LCDCTL_PAR_ACD_OE (0x0100) - -/* Bit definitions and macros for MCF_GPIO_PAR_IRQ */ -#define MCF_GPIO_PAR_IRQ_PAR_IRQ1(x) (((x)&0x0003)<<4) -#define MCF_GPIO_PAR_IRQ_PAR_IRQ2(x) (((x)&0x0003)<<6) -#define MCF_GPIO_PAR_IRQ_PAR_IRQ4(x) (((x)&0x0003)<<8) -#define MCF_GPIO_PAR_IRQ_PAR_IRQ5(x) (((x)&0x0003)<<10) -#define MCF_GPIO_PAR_IRQ_PAR_IRQ6(x) (((x)&0x0003)<<12) - -/* Bit definitions and macros for MCF_GPIO_MSCR_FLEXBUS */ -#define MCF_GPIO_MSCR_FLEXBUS_MSCR_ADDRCTL(x) (((x)&0x03)<<0) -#define MCF_GPIO_MSCR_FLEXBUS_MSCR_DLOWER(x) (((x)&0x03)<<2) -#define MCF_GPIO_MSCR_FLEXBUS_MSCR_DUPPER(x) (((x)&0x03)<<4) - -/* Bit definitions and macros for MCF_GPIO_MSCR_SDRAM */ -#define MCF_GPIO_MSCR_SDRAM_MSCR_SDRAM(x) (((x)&0x03)<<0) -#define MCF_GPIO_MSCR_SDRAM_MSCR_SDCLK(x) (((x)&0x03)<<2) -#define MCF_GPIO_MSCR_SDRAM_MSCR_SDCLKB(x) (((x)&0x03)<<4) - -/* Bit definitions and macros for MCF_GPIO_DSCR_I2C */ -#define MCF_GPIO_DSCR_I2C_I2C_DSE(x) (((x)&0x03)<<0) - -/* Bit definitions and macros for MCF_GPIO_DSCR_PWM */ -#define MCF_GPIO_DSCR_PWM_PWM_DSE(x) (((x)&0x03)<<0) - -/* Bit definitions and macros for MCF_GPIO_DSCR_FEC */ -#define MCF_GPIO_DSCR_FEC_FEC_DSE(x) (((x)&0x03)<<0) - -/* Bit definitions and macros for MCF_GPIO_DSCR_UART */ -#define MCF_GPIO_DSCR_UART_UART0_DSE(x) (((x)&0x03)<<0) -#define MCF_GPIO_DSCR_UART_UART1_DSE(x) (((x)&0x03)<<2) - -/* Bit definitions and macros for MCF_GPIO_DSCR_QSPI */ -#define MCF_GPIO_DSCR_QSPI_QSPI_DSE(x) (((x)&0x03)<<0) - -/* Bit definitions and macros for MCF_GPIO_DSCR_TIMER */ -#define MCF_GPIO_DSCR_TIMER_TIMER_DSE(x) (((x)&0x03)<<0) - -/* Bit definitions and macros for MCF_GPIO_DSCR_SSI */ -#define MCF_GPIO_DSCR_SSI_SSI_DSE(x) (((x)&0x03)<<0) - -/* Bit definitions and macros for MCF_GPIO_DSCR_LCD */ -#define MCF_GPIO_DSCR_LCD_LCD_DSE(x) (((x)&0x03)<<0) - -/* Bit definitions and macros for MCF_GPIO_DSCR_DEBUG */ -#define MCF_GPIO_DSCR_DEBUG_DEBUG_DSE(x) (((x)&0x03)<<0) - -/* Bit definitions and macros for MCF_GPIO_DSCR_CLKRST */ -#define MCF_GPIO_DSCR_CLKRST_CLKRST_DSE(x) (((x)&0x03)<<0) - -/* Bit definitions and macros for MCF_GPIO_DSCR_IRQ */ -#define MCF_GPIO_DSCR_IRQ_IRQ_DSE(x) (((x)&0x03)<<0) - -/********************************************************************* - * - * Interrupt Controller (INTC) - * - *********************************************************************/ - -/* Register read/write macros */ -#define MCF_INTC0_IPRH MCF_REG32(0xFC048000) -#define MCF_INTC0_IPRL MCF_REG32(0xFC048004) -#define MCF_INTC0_IMRH MCF_REG32(0xFC048008) -#define MCF_INTC0_IMRL MCF_REG32(0xFC04800C) -#define MCF_INTC0_INTFRCH MCF_REG32(0xFC048010) -#define MCF_INTC0_INTFRCL MCF_REG32(0xFC048014) -#define MCF_INTC0_ICONFIG MCF_REG16(0xFC04801A) -#define MCF_INTC0_SIMR MCF_REG08(0xFC04801C) -#define MCF_INTC0_CIMR MCF_REG08(0xFC04801D) -#define MCF_INTC0_CLMASK MCF_REG08(0xFC04801E) -#define MCF_INTC0_SLMASK MCF_REG08(0xFC04801F) -#define MCF_INTC0_ICR0 MCF_REG08(0xFC048040) -#define MCF_INTC0_ICR1 MCF_REG08(0xFC048041) -#define MCF_INTC0_ICR2 MCF_REG08(0xFC048042) -#define MCF_INTC0_ICR3 MCF_REG08(0xFC048043) -#define MCF_INTC0_ICR4 MCF_REG08(0xFC048044) -#define MCF_INTC0_ICR5 MCF_REG08(0xFC048045) -#define MCF_INTC0_ICR6 MCF_REG08(0xFC048046) -#define MCF_INTC0_ICR7 MCF_REG08(0xFC048047) -#define MCF_INTC0_ICR8 MCF_REG08(0xFC048048) -#define MCF_INTC0_ICR9 MCF_REG08(0xFC048049) -#define MCF_INTC0_ICR10 MCF_REG08(0xFC04804A) -#define MCF_INTC0_ICR11 MCF_REG08(0xFC04804B) -#define MCF_INTC0_ICR12 MCF_REG08(0xFC04804C) -#define MCF_INTC0_ICR13 MCF_REG08(0xFC04804D) -#define MCF_INTC0_ICR14 MCF_REG08(0xFC04804E) -#define MCF_INTC0_ICR15 MCF_REG08(0xFC04804F) -#define MCF_INTC0_ICR16 MCF_REG08(0xFC048050) -#define MCF_INTC0_ICR17 MCF_REG08(0xFC048051) -#define MCF_INTC0_ICR18 MCF_REG08(0xFC048052) -#define MCF_INTC0_ICR19 MCF_REG08(0xFC048053) -#define MCF_INTC0_ICR20 MCF_REG08(0xFC048054) -#define MCF_INTC0_ICR21 MCF_REG08(0xFC048055) -#define MCF_INTC0_ICR22 MCF_REG08(0xFC048056) -#define MCF_INTC0_ICR23 MCF_REG08(0xFC048057) -#define MCF_INTC0_ICR24 MCF_REG08(0xFC048058) -#define MCF_INTC0_ICR25 MCF_REG08(0xFC048059) -#define MCF_INTC0_ICR26 MCF_REG08(0xFC04805A) -#define MCF_INTC0_ICR27 MCF_REG08(0xFC04805B) -#define MCF_INTC0_ICR28 MCF_REG08(0xFC04805C) -#define MCF_INTC0_ICR29 MCF_REG08(0xFC04805D) -#define MCF_INTC0_ICR30 MCF_REG08(0xFC04805E) -#define MCF_INTC0_ICR31 MCF_REG08(0xFC04805F) -#define MCF_INTC0_ICR32 MCF_REG08(0xFC048060) -#define MCF_INTC0_ICR33 MCF_REG08(0xFC048061) -#define MCF_INTC0_ICR34 MCF_REG08(0xFC048062) -#define MCF_INTC0_ICR35 MCF_REG08(0xFC048063) -#define MCF_INTC0_ICR36 MCF_REG08(0xFC048064) -#define MCF_INTC0_ICR37 MCF_REG08(0xFC048065) -#define MCF_INTC0_ICR38 MCF_REG08(0xFC048066) -#define MCF_INTC0_ICR39 MCF_REG08(0xFC048067) -#define MCF_INTC0_ICR40 MCF_REG08(0xFC048068) -#define MCF_INTC0_ICR41 MCF_REG08(0xFC048069) -#define MCF_INTC0_ICR42 MCF_REG08(0xFC04806A) -#define MCF_INTC0_ICR43 MCF_REG08(0xFC04806B) -#define MCF_INTC0_ICR44 MCF_REG08(0xFC04806C) -#define MCF_INTC0_ICR45 MCF_REG08(0xFC04806D) -#define MCF_INTC0_ICR46 MCF_REG08(0xFC04806E) -#define MCF_INTC0_ICR47 MCF_REG08(0xFC04806F) -#define MCF_INTC0_ICR48 MCF_REG08(0xFC048070) -#define MCF_INTC0_ICR49 MCF_REG08(0xFC048071) -#define MCF_INTC0_ICR50 MCF_REG08(0xFC048072) -#define MCF_INTC0_ICR51 MCF_REG08(0xFC048073) -#define MCF_INTC0_ICR52 MCF_REG08(0xFC048074) -#define MCF_INTC0_ICR53 MCF_REG08(0xFC048075) -#define MCF_INTC0_ICR54 MCF_REG08(0xFC048076) -#define MCF_INTC0_ICR55 MCF_REG08(0xFC048077) -#define MCF_INTC0_ICR56 MCF_REG08(0xFC048078) -#define MCF_INTC0_ICR57 MCF_REG08(0xFC048079) -#define MCF_INTC0_ICR58 MCF_REG08(0xFC04807A) -#define MCF_INTC0_ICR59 MCF_REG08(0xFC04807B) -#define MCF_INTC0_ICR60 MCF_REG08(0xFC04807C) -#define MCF_INTC0_ICR61 MCF_REG08(0xFC04807D) -#define MCF_INTC0_ICR62 MCF_REG08(0xFC04807E) -#define MCF_INTC0_ICR63 MCF_REG08(0xFC04807F) -#define MCF_INTC0_ICR(x) MCF_REG08(0xFC048040+((x)*0x001)) -#define MCF_INTC0_SWIACK MCF_REG08(0xFC0480E0) -#define MCF_INTC0_L1IACK MCF_REG08(0xFC0480E4) -#define MCF_INTC0_L2IACK MCF_REG08(0xFC0480E8) -#define MCF_INTC0_L3IACK MCF_REG08(0xFC0480EC) -#define MCF_INTC0_L4IACK MCF_REG08(0xFC0480F0) -#define MCF_INTC0_L5IACK MCF_REG08(0xFC0480F4) -#define MCF_INTC0_L6IACK MCF_REG08(0xFC0480F8) -#define MCF_INTC0_L7IACK MCF_REG08(0xFC0480FC) -#define MCF_INTC0_LIACK(x) MCF_REG08(0xFC0480E4+((x)*0x004)) -#define MCF_INTC1_IPRH MCF_REG32(0xFC04C000) -#define MCF_INTC1_IPRL MCF_REG32(0xFC04C004) -#define MCF_INTC1_IMRH MCF_REG32(0xFC04C008) -#define MCF_INTC1_IMRL MCF_REG32(0xFC04C00C) -#define MCF_INTC1_INTFRCH MCF_REG32(0xFC04C010) -#define MCF_INTC1_INTFRCL MCF_REG32(0xFC04C014) -#define MCF_INTC1_ICONFIG MCF_REG16(0xFC04C01A) -#define MCF_INTC1_SIMR MCF_REG08(0xFC04C01C) -#define MCF_INTC1_CIMR MCF_REG08(0xFC04C01D) -#define MCF_INTC1_CLMASK MCF_REG08(0xFC04C01E) -#define MCF_INTC1_SLMASK MCF_REG08(0xFC04C01F) -#define MCF_INTC1_ICR0 MCF_REG08(0xFC04C040) -#define MCF_INTC1_ICR1 MCF_REG08(0xFC04C041) -#define MCF_INTC1_ICR2 MCF_REG08(0xFC04C042) -#define MCF_INTC1_ICR3 MCF_REG08(0xFC04C043) -#define MCF_INTC1_ICR4 MCF_REG08(0xFC04C044) -#define MCF_INTC1_ICR5 MCF_REG08(0xFC04C045) -#define MCF_INTC1_ICR6 MCF_REG08(0xFC04C046) -#define MCF_INTC1_ICR7 MCF_REG08(0xFC04C047) -#define MCF_INTC1_ICR8 MCF_REG08(0xFC04C048) -#define MCF_INTC1_ICR9 MCF_REG08(0xFC04C049) -#define MCF_INTC1_ICR10 MCF_REG08(0xFC04C04A) -#define MCF_INTC1_ICR11 MCF_REG08(0xFC04C04B) -#define MCF_INTC1_ICR12 MCF_REG08(0xFC04C04C) -#define MCF_INTC1_ICR13 MCF_REG08(0xFC04C04D) -#define MCF_INTC1_ICR14 MCF_REG08(0xFC04C04E) -#define MCF_INTC1_ICR15 MCF_REG08(0xFC04C04F) -#define MCF_INTC1_ICR16 MCF_REG08(0xFC04C050) -#define MCF_INTC1_ICR17 MCF_REG08(0xFC04C051) -#define MCF_INTC1_ICR18 MCF_REG08(0xFC04C052) -#define MCF_INTC1_ICR19 MCF_REG08(0xFC04C053) -#define MCF_INTC1_ICR20 MCF_REG08(0xFC04C054) -#define MCF_INTC1_ICR21 MCF_REG08(0xFC04C055) -#define MCF_INTC1_ICR22 MCF_REG08(0xFC04C056) -#define MCF_INTC1_ICR23 MCF_REG08(0xFC04C057) -#define MCF_INTC1_ICR24 MCF_REG08(0xFC04C058) -#define MCF_INTC1_ICR25 MCF_REG08(0xFC04C059) -#define MCF_INTC1_ICR26 MCF_REG08(0xFC04C05A) -#define MCF_INTC1_ICR27 MCF_REG08(0xFC04C05B) -#define MCF_INTC1_ICR28 MCF_REG08(0xFC04C05C) -#define MCF_INTC1_ICR29 MCF_REG08(0xFC04C05D) -#define MCF_INTC1_ICR30 MCF_REG08(0xFC04C05E) -#define MCF_INTC1_ICR31 MCF_REG08(0xFC04C05F) -#define MCF_INTC1_ICR32 MCF_REG08(0xFC04C060) -#define MCF_INTC1_ICR33 MCF_REG08(0xFC04C061) -#define MCF_INTC1_ICR34 MCF_REG08(0xFC04C062) -#define MCF_INTC1_ICR35 MCF_REG08(0xFC04C063) -#define MCF_INTC1_ICR36 MCF_REG08(0xFC04C064) -#define MCF_INTC1_ICR37 MCF_REG08(0xFC04C065) -#define MCF_INTC1_ICR38 MCF_REG08(0xFC04C066) -#define MCF_INTC1_ICR39 MCF_REG08(0xFC04C067) -#define MCF_INTC1_ICR40 MCF_REG08(0xFC04C068) -#define MCF_INTC1_ICR41 MCF_REG08(0xFC04C069) -#define MCF_INTC1_ICR42 MCF_REG08(0xFC04C06A) -#define MCF_INTC1_ICR43 MCF_REG08(0xFC04C06B) -#define MCF_INTC1_ICR44 MCF_REG08(0xFC04C06C) -#define MCF_INTC1_ICR45 MCF_REG08(0xFC04C06D) -#define MCF_INTC1_ICR46 MCF_REG08(0xFC04C06E) -#define MCF_INTC1_ICR47 MCF_REG08(0xFC04C06F) -#define MCF_INTC1_ICR48 MCF_REG08(0xFC04C070) -#define MCF_INTC1_ICR49 MCF_REG08(0xFC04C071) -#define MCF_INTC1_ICR50 MCF_REG08(0xFC04C072) -#define MCF_INTC1_ICR51 MCF_REG08(0xFC04C073) -#define MCF_INTC1_ICR52 MCF_REG08(0xFC04C074) -#define MCF_INTC1_ICR53 MCF_REG08(0xFC04C075) -#define MCF_INTC1_ICR54 MCF_REG08(0xFC04C076) -#define MCF_INTC1_ICR55 MCF_REG08(0xFC04C077) -#define MCF_INTC1_ICR56 MCF_REG08(0xFC04C078) -#define MCF_INTC1_ICR57 MCF_REG08(0xFC04C079) -#define MCF_INTC1_ICR58 MCF_REG08(0xFC04C07A) -#define MCF_INTC1_ICR59 MCF_REG08(0xFC04C07B) -#define MCF_INTC1_ICR60 MCF_REG08(0xFC04C07C) -#define MCF_INTC1_ICR61 MCF_REG08(0xFC04C07D) -#define MCF_INTC1_ICR62 MCF_REG08(0xFC04C07E) -#define MCF_INTC1_ICR63 MCF_REG08(0xFC04C07F) -#define MCF_INTC1_ICR(x) MCF_REG08(0xFC04C040+((x)*0x001)) -#define MCF_INTC1_SWIACK MCF_REG08(0xFC04C0E0) -#define MCF_INTC1_L1IACK MCF_REG08(0xFC04C0E4) -#define MCF_INTC1_L2IACK MCF_REG08(0xFC04C0E8) -#define MCF_INTC1_L3IACK MCF_REG08(0xFC04C0EC) -#define MCF_INTC1_L4IACK MCF_REG08(0xFC04C0F0) -#define MCF_INTC1_L5IACK MCF_REG08(0xFC04C0F4) -#define MCF_INTC1_L6IACK MCF_REG08(0xFC04C0F8) -#define MCF_INTC1_L7IACK MCF_REG08(0xFC04C0FC) -#define MCF_INTC1_LIACK(x) MCF_REG08(0xFC04C0E4+((x)*0x004)) -#define MCF_INTC_IPRH(x) MCF_REG32(0xFC048000+((x)*0x4000)) -#define MCF_INTC_IPRL(x) MCF_REG32(0xFC048004+((x)*0x4000)) -#define MCF_INTC_IMRH(x) MCF_REG32(0xFC048008+((x)*0x4000)) -#define MCF_INTC_IMRL(x) MCF_REG32(0xFC04800C+((x)*0x4000)) -#define MCF_INTC_INTFRCH(x) MCF_REG32(0xFC048010+((x)*0x4000)) -#define MCF_INTC_INTFRCL(x) MCF_REG32(0xFC048014+((x)*0x4000)) -#define MCF_INTC_ICONFIG(x) MCF_REG16(0xFC04801A+((x)*0x4000)) -#define MCF_INTC_SIMR(x) MCF_REG08(0xFC04801C+((x)*0x4000)) -#define MCF_INTC_CIMR(x) MCF_REG08(0xFC04801D+((x)*0x4000)) -#define MCF_INTC_CLMASK(x) MCF_REG08(0xFC04801E+((x)*0x4000)) -#define MCF_INTC_SLMASK(x) MCF_REG08(0xFC04801F+((x)*0x4000)) -#define MCF_INTC_ICR0(x) MCF_REG08(0xFC048040+((x)*0x4000)) -#define MCF_INTC_ICR1(x) MCF_REG08(0xFC048041+((x)*0x4000)) -#define MCF_INTC_ICR2(x) MCF_REG08(0xFC048042+((x)*0x4000)) -#define MCF_INTC_ICR3(x) MCF_REG08(0xFC048043+((x)*0x4000)) -#define MCF_INTC_ICR4(x) MCF_REG08(0xFC048044+((x)*0x4000)) -#define MCF_INTC_ICR5(x) MCF_REG08(0xFC048045+((x)*0x4000)) -#define MCF_INTC_ICR6(x) MCF_REG08(0xFC048046+((x)*0x4000)) -#define MCF_INTC_ICR7(x) MCF_REG08(0xFC048047+((x)*0x4000)) -#define MCF_INTC_ICR8(x) MCF_REG08(0xFC048048+((x)*0x4000)) -#define MCF_INTC_ICR9(x) MCF_REG08(0xFC048049+((x)*0x4000)) -#define MCF_INTC_ICR10(x) MCF_REG08(0xFC04804A+((x)*0x4000)) -#define MCF_INTC_ICR11(x) MCF_REG08(0xFC04804B+((x)*0x4000)) -#define MCF_INTC_ICR12(x) MCF_REG08(0xFC04804C+((x)*0x4000)) -#define MCF_INTC_ICR13(x) MCF_REG08(0xFC04804D+((x)*0x4000)) -#define MCF_INTC_ICR14(x) MCF_REG08(0xFC04804E+((x)*0x4000)) -#define MCF_INTC_ICR15(x) MCF_REG08(0xFC04804F+((x)*0x4000)) -#define MCF_INTC_ICR16(x) MCF_REG08(0xFC048050+((x)*0x4000)) -#define MCF_INTC_ICR17(x) MCF_REG08(0xFC048051+((x)*0x4000)) -#define MCF_INTC_ICR18(x) MCF_REG08(0xFC048052+((x)*0x4000)) -#define MCF_INTC_ICR19(x) MCF_REG08(0xFC048053+((x)*0x4000)) -#define MCF_INTC_ICR20(x) MCF_REG08(0xFC048054+((x)*0x4000)) -#define MCF_INTC_ICR21(x) MCF_REG08(0xFC048055+((x)*0x4000)) -#define MCF_INTC_ICR22(x) MCF_REG08(0xFC048056+((x)*0x4000)) -#define MCF_INTC_ICR23(x) MCF_REG08(0xFC048057+((x)*0x4000)) -#define MCF_INTC_ICR24(x) MCF_REG08(0xFC048058+((x)*0x4000)) -#define MCF_INTC_ICR25(x) MCF_REG08(0xFC048059+((x)*0x4000)) -#define MCF_INTC_ICR26(x) MCF_REG08(0xFC04805A+((x)*0x4000)) -#define MCF_INTC_ICR27(x) MCF_REG08(0xFC04805B+((x)*0x4000)) -#define MCF_INTC_ICR28(x) MCF_REG08(0xFC04805C+((x)*0x4000)) -#define MCF_INTC_ICR29(x) MCF_REG08(0xFC04805D+((x)*0x4000)) -#define MCF_INTC_ICR30(x) MCF_REG08(0xFC04805E+((x)*0x4000)) -#define MCF_INTC_ICR31(x) MCF_REG08(0xFC04805F+((x)*0x4000)) -#define MCF_INTC_ICR32(x) MCF_REG08(0xFC048060+((x)*0x4000)) -#define MCF_INTC_ICR33(x) MCF_REG08(0xFC048061+((x)*0x4000)) -#define MCF_INTC_ICR34(x) MCF_REG08(0xFC048062+((x)*0x4000)) -#define MCF_INTC_ICR35(x) MCF_REG08(0xFC048063+((x)*0x4000)) -#define MCF_INTC_ICR36(x) MCF_REG08(0xFC048064+((x)*0x4000)) -#define MCF_INTC_ICR37(x) MCF_REG08(0xFC048065+((x)*0x4000)) -#define MCF_INTC_ICR38(x) MCF_REG08(0xFC048066+((x)*0x4000)) -#define MCF_INTC_ICR39(x) MCF_REG08(0xFC048067+((x)*0x4000)) -#define MCF_INTC_ICR40(x) MCF_REG08(0xFC048068+((x)*0x4000)) -#define MCF_INTC_ICR41(x) MCF_REG08(0xFC048069+((x)*0x4000)) -#define MCF_INTC_ICR42(x) MCF_REG08(0xFC04806A+((x)*0x4000)) -#define MCF_INTC_ICR43(x) MCF_REG08(0xFC04806B+((x)*0x4000)) -#define MCF_INTC_ICR44(x) MCF_REG08(0xFC04806C+((x)*0x4000)) -#define MCF_INTC_ICR45(x) MCF_REG08(0xFC04806D+((x)*0x4000)) -#define MCF_INTC_ICR46(x) MCF_REG08(0xFC04806E+((x)*0x4000)) -#define MCF_INTC_ICR47(x) MCF_REG08(0xFC04806F+((x)*0x4000)) -#define MCF_INTC_ICR48(x) MCF_REG08(0xFC048070+((x)*0x4000)) -#define MCF_INTC_ICR49(x) MCF_REG08(0xFC048071+((x)*0x4000)) -#define MCF_INTC_ICR50(x) MCF_REG08(0xFC048072+((x)*0x4000)) -#define MCF_INTC_ICR51(x) MCF_REG08(0xFC048073+((x)*0x4000)) -#define MCF_INTC_ICR52(x) MCF_REG08(0xFC048074+((x)*0x4000)) -#define MCF_INTC_ICR53(x) MCF_REG08(0xFC048075+((x)*0x4000)) -#define MCF_INTC_ICR54(x) MCF_REG08(0xFC048076+((x)*0x4000)) -#define MCF_INTC_ICR55(x) MCF_REG08(0xFC048077+((x)*0x4000)) -#define MCF_INTC_ICR56(x) MCF_REG08(0xFC048078+((x)*0x4000)) -#define MCF_INTC_ICR57(x) MCF_REG08(0xFC048079+((x)*0x4000)) -#define MCF_INTC_ICR58(x) MCF_REG08(0xFC04807A+((x)*0x4000)) -#define MCF_INTC_ICR59(x) MCF_REG08(0xFC04807B+((x)*0x4000)) -#define MCF_INTC_ICR60(x) MCF_REG08(0xFC04807C+((x)*0x4000)) -#define MCF_INTC_ICR61(x) MCF_REG08(0xFC04807D+((x)*0x4000)) -#define MCF_INTC_ICR62(x) MCF_REG08(0xFC04807E+((x)*0x4000)) -#define MCF_INTC_ICR63(x) MCF_REG08(0xFC04807F+((x)*0x4000)) -#define MCF_INTC_SWIACK(x) MCF_REG08(0xFC0480E0+((x)*0x4000)) -#define MCF_INTC_L1IACK(x) MCF_REG08(0xFC0480E4+((x)*0x4000)) -#define MCF_INTC_L2IACK(x) MCF_REG08(0xFC0480E8+((x)*0x4000)) -#define MCF_INTC_L3IACK(x) MCF_REG08(0xFC0480EC+((x)*0x4000)) -#define MCF_INTC_L4IACK(x) MCF_REG08(0xFC0480F0+((x)*0x4000)) -#define MCF_INTC_L5IACK(x) MCF_REG08(0xFC0480F4+((x)*0x4000)) -#define MCF_INTC_L6IACK(x) MCF_REG08(0xFC0480F8+((x)*0x4000)) -#define MCF_INTC_L7IACK(x) MCF_REG08(0xFC0480FC+((x)*0x4000)) - -/* Bit definitions and macros for MCF_INTC_IPRH */ -#define MCF_INTC_IPRH_INT32 (0x00000001) -#define MCF_INTC_IPRH_INT33 (0x00000002) -#define MCF_INTC_IPRH_INT34 (0x00000004) -#define MCF_INTC_IPRH_INT35 (0x00000008) -#define MCF_INTC_IPRH_INT36 (0x00000010) -#define MCF_INTC_IPRH_INT37 (0x00000020) -#define MCF_INTC_IPRH_INT38 (0x00000040) -#define MCF_INTC_IPRH_INT39 (0x00000080) -#define MCF_INTC_IPRH_INT40 (0x00000100) -#define MCF_INTC_IPRH_INT41 (0x00000200) -#define MCF_INTC_IPRH_INT42 (0x00000400) -#define MCF_INTC_IPRH_INT43 (0x00000800) -#define MCF_INTC_IPRH_INT44 (0x00001000) -#define MCF_INTC_IPRH_INT45 (0x00002000) -#define MCF_INTC_IPRH_INT46 (0x00004000) -#define MCF_INTC_IPRH_INT47 (0x00008000) -#define MCF_INTC_IPRH_INT48 (0x00010000) -#define MCF_INTC_IPRH_INT49 (0x00020000) -#define MCF_INTC_IPRH_INT50 (0x00040000) -#define MCF_INTC_IPRH_INT51 (0x00080000) -#define MCF_INTC_IPRH_INT52 (0x00100000) -#define MCF_INTC_IPRH_INT53 (0x00200000) -#define MCF_INTC_IPRH_INT54 (0x00400000) -#define MCF_INTC_IPRH_INT55 (0x00800000) -#define MCF_INTC_IPRH_INT56 (0x01000000) -#define MCF_INTC_IPRH_INT57 (0x02000000) -#define MCF_INTC_IPRH_INT58 (0x04000000) -#define MCF_INTC_IPRH_INT59 (0x08000000) -#define MCF_INTC_IPRH_INT60 (0x10000000) -#define MCF_INTC_IPRH_INT61 (0x20000000) -#define MCF_INTC_IPRH_INT62 (0x40000000) -#define MCF_INTC_IPRH_INT63 (0x80000000) - -/* Bit definitions and macros for MCF_INTC_IPRL */ -#define MCF_INTC_IPRL_INT0 (0x00000001) -#define MCF_INTC_IPRL_INT1 (0x00000002) -#define MCF_INTC_IPRL_INT2 (0x00000004) -#define MCF_INTC_IPRL_INT3 (0x00000008) -#define MCF_INTC_IPRL_INT4 (0x00000010) -#define MCF_INTC_IPRL_INT5 (0x00000020) -#define MCF_INTC_IPRL_INT6 (0x00000040) -#define MCF_INTC_IPRL_INT7 (0x00000080) -#define MCF_INTC_IPRL_INT8 (0x00000100) -#define MCF_INTC_IPRL_INT9 (0x00000200) -#define MCF_INTC_IPRL_INT10 (0x00000400) -#define MCF_INTC_IPRL_INT11 (0x00000800) -#define MCF_INTC_IPRL_INT12 (0x00001000) -#define MCF_INTC_IPRL_INT13 (0x00002000) -#define MCF_INTC_IPRL_INT14 (0x00004000) -#define MCF_INTC_IPRL_INT15 (0x00008000) -#define MCF_INTC_IPRL_INT16 (0x00010000) -#define MCF_INTC_IPRL_INT17 (0x00020000) -#define MCF_INTC_IPRL_INT18 (0x00040000) -#define MCF_INTC_IPRL_INT19 (0x00080000) -#define MCF_INTC_IPRL_INT20 (0x00100000) -#define MCF_INTC_IPRL_INT21 (0x00200000) -#define MCF_INTC_IPRL_INT22 (0x00400000) -#define MCF_INTC_IPRL_INT23 (0x00800000) -#define MCF_INTC_IPRL_INT24 (0x01000000) -#define MCF_INTC_IPRL_INT25 (0x02000000) -#define MCF_INTC_IPRL_INT26 (0x04000000) -#define MCF_INTC_IPRL_INT27 (0x08000000) -#define MCF_INTC_IPRL_INT28 (0x10000000) -#define MCF_INTC_IPRL_INT29 (0x20000000) -#define MCF_INTC_IPRL_INT30 (0x40000000) -#define MCF_INTC_IPRL_INT31 (0x80000000) - -/* Bit definitions and macros for MCF_INTC_IMRH */ -#define MCF_INTC_IMRH_INT_MASK32 (0x00000001) -#define MCF_INTC_IMRH_INT_MASK33 (0x00000002) -#define MCF_INTC_IMRH_INT_MASK34 (0x00000004) -#define MCF_INTC_IMRH_INT_MASK35 (0x00000008) -#define MCF_INTC_IMRH_INT_MASK36 (0x00000010) -#define MCF_INTC_IMRH_INT_MASK37 (0x00000020) -#define MCF_INTC_IMRH_INT_MASK38 (0x00000040) -#define MCF_INTC_IMRH_INT_MASK39 (0x00000080) -#define MCF_INTC_IMRH_INT_MASK40 (0x00000100) -#define MCF_INTC_IMRH_INT_MASK41 (0x00000200) -#define MCF_INTC_IMRH_INT_MASK42 (0x00000400) -#define MCF_INTC_IMRH_INT_MASK43 (0x00000800) -#define MCF_INTC_IMRH_INT_MASK44 (0x00001000) -#define MCF_INTC_IMRH_INT_MASK45 (0x00002000) -#define MCF_INTC_IMRH_INT_MASK46 (0x00004000) -#define MCF_INTC_IMRH_INT_MASK47 (0x00008000) -#define MCF_INTC_IMRH_INT_MASK48 (0x00010000) -#define MCF_INTC_IMRH_INT_MASK49 (0x00020000) -#define MCF_INTC_IMRH_INT_MASK50 (0x00040000) -#define MCF_INTC_IMRH_INT_MASK51 (0x00080000) -#define MCF_INTC_IMRH_INT_MASK52 (0x00100000) -#define MCF_INTC_IMRH_INT_MASK53 (0x00200000) -#define MCF_INTC_IMRH_INT_MASK54 (0x00400000) -#define MCF_INTC_IMRH_INT_MASK55 (0x00800000) -#define MCF_INTC_IMRH_INT_MASK56 (0x01000000) -#define MCF_INTC_IMRH_INT_MASK57 (0x02000000) -#define MCF_INTC_IMRH_INT_MASK58 (0x04000000) -#define MCF_INTC_IMRH_INT_MASK59 (0x08000000) -#define MCF_INTC_IMRH_INT_MASK60 (0x10000000) -#define MCF_INTC_IMRH_INT_MASK61 (0x20000000) -#define MCF_INTC_IMRH_INT_MASK62 (0x40000000) -#define MCF_INTC_IMRH_INT_MASK63 (0x80000000) - -/* Bit definitions and macros for MCF_INTC_IMRL */ -#define MCF_INTC_IMRL_INT_MASK0 (0x00000001) -#define MCF_INTC_IMRL_INT_MASK1 (0x00000002) -#define MCF_INTC_IMRL_INT_MASK2 (0x00000004) -#define MCF_INTC_IMRL_INT_MASK3 (0x00000008) -#define MCF_INTC_IMRL_INT_MASK4 (0x00000010) -#define MCF_INTC_IMRL_INT_MASK5 (0x00000020) -#define MCF_INTC_IMRL_INT_MASK6 (0x00000040) -#define MCF_INTC_IMRL_INT_MASK7 (0x00000080) -#define MCF_INTC_IMRL_INT_MASK8 (0x00000100) -#define MCF_INTC_IMRL_INT_MASK9 (0x00000200) -#define MCF_INTC_IMRL_INT_MASK10 (0x00000400) -#define MCF_INTC_IMRL_INT_MASK11 (0x00000800) -#define MCF_INTC_IMRL_INT_MASK12 (0x00001000) -#define MCF_INTC_IMRL_INT_MASK13 (0x00002000) -#define MCF_INTC_IMRL_INT_MASK14 (0x00004000) -#define MCF_INTC_IMRL_INT_MASK15 (0x00008000) -#define MCF_INTC_IMRL_INT_MASK16 (0x00010000) -#define MCF_INTC_IMRL_INT_MASK17 (0x00020000) -#define MCF_INTC_IMRL_INT_MASK18 (0x00040000) -#define MCF_INTC_IMRL_INT_MASK19 (0x00080000) -#define MCF_INTC_IMRL_INT_MASK20 (0x00100000) -#define MCF_INTC_IMRL_INT_MASK21 (0x00200000) -#define MCF_INTC_IMRL_INT_MASK22 (0x00400000) -#define MCF_INTC_IMRL_INT_MASK23 (0x00800000) -#define MCF_INTC_IMRL_INT_MASK24 (0x01000000) -#define MCF_INTC_IMRL_INT_MASK25 (0x02000000) -#define MCF_INTC_IMRL_INT_MASK26 (0x04000000) -#define MCF_INTC_IMRL_INT_MASK27 (0x08000000) -#define MCF_INTC_IMRL_INT_MASK28 (0x10000000) -#define MCF_INTC_IMRL_INT_MASK29 (0x20000000) -#define MCF_INTC_IMRL_INT_MASK30 (0x40000000) -#define MCF_INTC_IMRL_INT_MASK31 (0x80000000) - -/* Bit definitions and macros for MCF_INTC_INTFRCH */ -#define MCF_INTC_INTFRCH_INTFRC32 (0x00000001) -#define MCF_INTC_INTFRCH_INTFRC33 (0x00000002) -#define MCF_INTC_INTFRCH_INTFRC34 (0x00000004) -#define MCF_INTC_INTFRCH_INTFRC35 (0x00000008) -#define MCF_INTC_INTFRCH_INTFRC36 (0x00000010) -#define MCF_INTC_INTFRCH_INTFRC37 (0x00000020) -#define MCF_INTC_INTFRCH_INTFRC38 (0x00000040) -#define MCF_INTC_INTFRCH_INTFRC39 (0x00000080) -#define MCF_INTC_INTFRCH_INTFRC40 (0x00000100) -#define MCF_INTC_INTFRCH_INTFRC41 (0x00000200) -#define MCF_INTC_INTFRCH_INTFRC42 (0x00000400) -#define MCF_INTC_INTFRCH_INTFRC43 (0x00000800) -#define MCF_INTC_INTFRCH_INTFRC44 (0x00001000) -#define MCF_INTC_INTFRCH_INTFRC45 (0x00002000) -#define MCF_INTC_INTFRCH_INTFRC46 (0x00004000) -#define MCF_INTC_INTFRCH_INTFRC47 (0x00008000) -#define MCF_INTC_INTFRCH_INTFRC48 (0x00010000) -#define MCF_INTC_INTFRCH_INTFRC49 (0x00020000) -#define MCF_INTC_INTFRCH_INTFRC50 (0x00040000) -#define MCF_INTC_INTFRCH_INTFRC51 (0x00080000) -#define MCF_INTC_INTFRCH_INTFRC52 (0x00100000) -#define MCF_INTC_INTFRCH_INTFRC53 (0x00200000) -#define MCF_INTC_INTFRCH_INTFRC54 (0x00400000) -#define MCF_INTC_INTFRCH_INTFRC55 (0x00800000) -#define MCF_INTC_INTFRCH_INTFRC56 (0x01000000) -#define MCF_INTC_INTFRCH_INTFRC57 (0x02000000) -#define MCF_INTC_INTFRCH_INTFRC58 (0x04000000) -#define MCF_INTC_INTFRCH_INTFRC59 (0x08000000) -#define MCF_INTC_INTFRCH_INTFRC60 (0x10000000) -#define MCF_INTC_INTFRCH_INTFRC61 (0x20000000) -#define MCF_INTC_INTFRCH_INTFRC62 (0x40000000) -#define MCF_INTC_INTFRCH_INTFRC63 (0x80000000) - -/* Bit definitions and macros for MCF_INTC_INTFRCL */ -#define MCF_INTC_INTFRCL_INTFRC0 (0x00000001) -#define MCF_INTC_INTFRCL_INTFRC1 (0x00000002) -#define MCF_INTC_INTFRCL_INTFRC2 (0x00000004) -#define MCF_INTC_INTFRCL_INTFRC3 (0x00000008) -#define MCF_INTC_INTFRCL_INTFRC4 (0x00000010) -#define MCF_INTC_INTFRCL_INTFRC5 (0x00000020) -#define MCF_INTC_INTFRCL_INTFRC6 (0x00000040) -#define MCF_INTC_INTFRCL_INTFRC7 (0x00000080) -#define MCF_INTC_INTFRCL_INTFRC8 (0x00000100) -#define MCF_INTC_INTFRCL_INTFRC9 (0x00000200) -#define MCF_INTC_INTFRCL_INTFRC10 (0x00000400) -#define MCF_INTC_INTFRCL_INTFRC11 (0x00000800) -#define MCF_INTC_INTFRCL_INTFRC12 (0x00001000) -#define MCF_INTC_INTFRCL_INTFRC13 (0x00002000) -#define MCF_INTC_INTFRCL_INTFRC14 (0x00004000) -#define MCF_INTC_INTFRCL_INTFRC15 (0x00008000) -#define MCF_INTC_INTFRCL_INTFRC16 (0x00010000) -#define MCF_INTC_INTFRCL_INTFRC17 (0x00020000) -#define MCF_INTC_INTFRCL_INTFRC18 (0x00040000) -#define MCF_INTC_INTFRCL_INTFRC19 (0x00080000) -#define MCF_INTC_INTFRCL_INTFRC20 (0x00100000) -#define MCF_INTC_INTFRCL_INTFRC21 (0x00200000) -#define MCF_INTC_INTFRCL_INTFRC22 (0x00400000) -#define MCF_INTC_INTFRCL_INTFRC23 (0x00800000) -#define MCF_INTC_INTFRCL_INTFRC24 (0x01000000) -#define MCF_INTC_INTFRCL_INTFRC25 (0x02000000) -#define MCF_INTC_INTFRCL_INTFRC26 (0x04000000) -#define MCF_INTC_INTFRCL_INTFRC27 (0x08000000) -#define MCF_INTC_INTFRCL_INTFRC28 (0x10000000) -#define MCF_INTC_INTFRCL_INTFRC29 (0x20000000) -#define MCF_INTC_INTFRCL_INTFRC30 (0x40000000) -#define MCF_INTC_INTFRCL_INTFRC31 (0x80000000) - -/* Bit definitions and macros for MCF_INTC_ICONFIG */ -#define MCF_INTC_ICONFIG_EMASK (0x0020) -#define MCF_INTC_ICONFIG_ELVLPRI1 (0x0200) -#define MCF_INTC_ICONFIG_ELVLPRI2 (0x0400) -#define MCF_INTC_ICONFIG_ELVLPRI3 (0x0800) -#define MCF_INTC_ICONFIG_ELVLPRI4 (0x1000) -#define MCF_INTC_ICONFIG_ELVLPRI5 (0x2000) -#define MCF_INTC_ICONFIG_ELVLPRI6 (0x4000) -#define MCF_INTC_ICONFIG_ELVLPRI7 (0x8000) - -/* Bit definitions and macros for MCF_INTC_SIMR */ -#define MCF_INTC_SIMR_SIMR(x) (((x)&0x7F)<<0) - -/* Bit definitions and macros for MCF_INTC_CIMR */ -#define MCF_INTC_CIMR_CIMR(x) (((x)&0x7F)<<0) - -/* Bit definitions and macros for MCF_INTC_CLMASK */ -#define MCF_INTC_CLMASK_CLMASK(x) (((x)&0x0F)<<0) - -/* Bit definitions and macros for MCF_INTC_SLMASK */ -#define MCF_INTC_SLMASK_SLMASK(x) (((x)&0x0F)<<0) - -/* Bit definitions and macros for MCF_INTC_ICR */ -#define MCF_INTC_ICR_IL(x) (((x)&0x07)<<0) - -/* Bit definitions and macros for MCF_INTC_SWIACK */ -#define MCF_INTC_SWIACK_VECTOR(x) (((x)&0xFF)<<0) - -/* Bit definitions and macros for MCF_INTC_LIACK */ -#define MCF_INTC_LIACK_VECTOR(x) (((x)&0xFF)<<0) - -/********************************************************************/ -/********************************************************************* -* -* LCD Controller (LCDC) -* -*********************************************************************/ - -/* Register read/write macros */ -#define MCF_LCDC_LSSAR MCF_REG32(0xFC0AC000) -#define MCF_LCDC_LSR MCF_REG32(0xFC0AC004) -#define MCF_LCDC_LVPWR MCF_REG32(0xFC0AC008) -#define MCF_LCDC_LCPR MCF_REG32(0xFC0AC00C) -#define MCF_LCDC_LCWHBR MCF_REG32(0xFC0AC010) -#define MCF_LCDC_LCCMR MCF_REG32(0xFC0AC014) -#define MCF_LCDC_LPCR MCF_REG32(0xFC0AC018) -#define MCF_LCDC_LHCR MCF_REG32(0xFC0AC01C) -#define MCF_LCDC_LVCR MCF_REG32(0xFC0AC020) -#define MCF_LCDC_LPOR MCF_REG32(0xFC0AC024) -#define MCF_LCDC_LSCR MCF_REG32(0xFC0AC028) -#define MCF_LCDC_LPCCR MCF_REG32(0xFC0AC02C) -#define MCF_LCDC_LDCR MCF_REG32(0xFC0AC030) -#define MCF_LCDC_LRMCR MCF_REG32(0xFC0AC034) -#define MCF_LCDC_LICR MCF_REG32(0xFC0AC038) -#define MCF_LCDC_LIER MCF_REG32(0xFC0AC03C) -#define MCF_LCDC_LISR MCF_REG32(0xFC0AC040) -#define MCF_LCDC_LGWSAR MCF_REG32(0xFC0AC050) -#define MCF_LCDC_LGWSR MCF_REG32(0xFC0AC054) -#define MCF_LCDC_LGWVPWR MCF_REG32(0xFC0AC058) -#define MCF_LCDC_LGWPOR MCF_REG32(0xFC0AC05C) -#define MCF_LCDC_LGWPR MCF_REG32(0xFC0AC060) -#define MCF_LCDC_LGWCR MCF_REG32(0xFC0AC064) -#define MCF_LCDC_LGWDCR MCF_REG32(0xFC0AC068) -#define MCF_LCDC_BPLUT_BASE MCF_REG32(0xFC0AC800) -#define MCF_LCDC_GWLUT_BASE MCF_REG32(0xFC0ACC00) - -/* Bit definitions and macros for MCF_LCDC_LSSAR */ -#define MCF_LCDC_LSSAR_SSA(x) (((x)&0x3FFFFFFF)<<2) - -/* Bit definitions and macros for MCF_LCDC_LSR */ -#define MCF_LCDC_LSR_YMAX(x) (((x)&0x000003FF)<<0) -#define MCF_LCDC_LSR_XMAX(x) (((x)&0x0000003F)<<20) - -/* Bit definitions and macros for MCF_LCDC_LVPWR */ -#define MCF_LCDC_LVPWR_VPW(x) (((x)&0x000003FF)<<0) - -/* Bit definitions and macros for MCF_LCDC_LCPR */ -#define MCF_LCDC_LCPR_CYP(x) (((x)&0x000003FF)<<0) -#define MCF_LCDC_LCPR_CXP(x) (((x)&0x000003FF)<<16) -#define MCF_LCDC_LCPR_OP (0x10000000) -#define MCF_LCDC_LCPR_CC(x) (((x)&0x00000003)<<30) -#define MCF_LCDC_LCPR_CC_TRANSPARENT (0x00000000) -#define MCF_LCDC_LCPR_CC_OR (0x40000000) -#define MCF_LCDC_LCPR_CC_XOR (0x80000000) -#define MCF_LCDC_LCPR_CC_AND (0xC0000000) -#define MCF_LCDC_LCPR_OP_ON (0x10000000) -#define MCF_LCDC_LCPR_OP_OFF (0x00000000) - -/* Bit definitions and macros for MCF_LCDC_LCWHBR */ -#define MCF_LCDC_LCWHBR_BD(x) (((x)&0x000000FF)<<0) -#define MCF_LCDC_LCWHBR_CH(x) (((x)&0x0000001F)<<16) -#define MCF_LCDC_LCWHBR_CW(x) (((x)&0x0000001F)<<24) -#define MCF_LCDC_LCWHBR_BK_EN (0x80000000) -#define MCF_LCDC_LCWHBR_BK_EN_ON (0x80000000) -#define MCF_LCDC_LCWHBR_BK_EN_OFF (0x00000000) - -/* Bit definitions and macros for MCF_LCDC_LCCMR */ -#define MCF_LCDC_LCCMR_CUR_COL_B(x) (((x)&0x0000003F)<<0) -#define MCF_LCDC_LCCMR_CUR_COL_G(x) (((x)&0x0000003F)<<6) -#define MCF_LCDC_LCCMR_CUR_COL_R(x) (((x)&0x0000003F)<<12) - -/* Bit definitions and macros for MCF_LCDC_LPCR */ -#define MCF_LCDC_LPCR_PCD(x) (((x)&0x0000003F)<<0) -#define MCF_LCDC_LPCR_SHARP (0x00000040) -#define MCF_LCDC_LPCR_SCLKSEL (0x00000080) -#define MCF_LCDC_LPCR_ACD(x) (((x)&0x0000007F)<<8) -#define MCF_LCDC_LPCR_ACDSEL (0x00008000) -#define MCF_LCDC_LPCR_REV_VS (0x00010000) -#define MCF_LCDC_LPCR_SWAP_SEL (0x00020000) -#define MCF_LCDC_LPCR_ENDSEL (0x00040000) -#define MCF_LCDC_LPCR_SCLKIDLE (0x00080000) -#define MCF_LCDC_LPCR_OEPOL (0x00100000) -#define MCF_LCDC_LPCR_CLKPOL (0x00200000) -#define MCF_LCDC_LPCR_LPPOL (0x00400000) -#define MCF_LCDC_LPCR_FLM (0x00800000) -#define MCF_LCDC_LPCR_PIXPOL (0x01000000) -#define MCF_LCDC_LPCR_BPIX(x) (((x)&0x00000007)<<25) -#define MCF_LCDC_LPCR_PBSIZ(x) (((x)&0x00000003)<<28) -#define MCF_LCDC_LPCR_COLOR (0x40000000) -#define MCF_LCDC_LPCR_TFT (0x80000000) -#define MCF_LCDC_LPCR_MODE_MONOCGROME (0x00000000) -#define MCF_LCDC_LPCR_MODE_CSTN (0x40000000) -#define MCF_LCDC_LPCR_MODE_TFT (0xC0000000) -#define MCF_LCDC_LPCR_PBSIZ_1 (0x00000000) -#define MCF_LCDC_LPCR_PBSIZ_2 (0x10000000) -#define MCF_LCDC_LPCR_PBSIZ_4 (0x20000000) -#define MCF_LCDC_LPCR_PBSIZ_8 (0x30000000) -#define MCF_LCDC_LPCR_BPIX_1bpp (0x00000000) -#define MCF_LCDC_LPCR_BPIX_2bpp (0x02000000) -#define MCF_LCDC_LPCR_BPIX_4bpp (0x04000000) -#define MCF_LCDC_LPCR_BPIX_8bpp (0x06000000) -#define MCF_LCDC_LPCR_BPIX_12bpp (0x08000000) -#define MCF_LCDC_LPCR_BPIX_16bpp (0x0A000000) -#define MCF_LCDC_LPCR_BPIX_18bpp (0x0C000000) - -#define MCF_LCDC_LPCR_PANEL_TYPE(x) (((x)&0x00000003)<<30) - -/* Bit definitions and macros for MCF_LCDC_LHCR */ -#define MCF_LCDC_LHCR_H_WAIT_2(x) (((x)&0x000000FF)<<0) -#define MCF_LCDC_LHCR_H_WAIT_1(x) (((x)&0x000000FF)<<8) -#define MCF_LCDC_LHCR_H_WIDTH(x) (((x)&0x0000003F)<<26) - -/* Bit definitions and macros for MCF_LCDC_LVCR */ -#define MCF_LCDC_LVCR_V_WAIT_2(x) (((x)&0x000000FF)<<0) -#define MCF_LCDC_LVCR_V_WAIT_1(x) (((x)&0x000000FF)<<8) -#define MCF_LCDC_LVCR_V_WIDTH(x) (((x)&0x0000003F)<<26) - -/* Bit definitions and macros for MCF_LCDC_LPOR */ -#define MCF_LCDC_LPOR_POS(x) (((x)&0x0000001F)<<0) - -/* Bit definitions and macros for MCF_LCDC_LPCCR */ -#define MCF_LCDC_LPCCR_PW(x) (((x)&0x000000FF)<<0) -#define MCF_LCDC_LPCCR_CC_EN (0x00000100) -#define MCF_LCDC_LPCCR_SCR(x) (((x)&0x00000003)<<9) -#define MCF_LCDC_LPCCR_LDMSK (0x00008000) -#define MCF_LCDC_LPCCR_CLS_HI_WIDTH(x) (((x)&0x000001FF)<<16) -#define MCF_LCDC_LPCCR_SCR_LINEPULSE (0x00000000) -#define MCF_LCDC_LPCCR_SCR_PIXELCLK (0x00002000) -#define MCF_LCDC_LPCCR_SCR_LCDCLOCK (0x00004000) - -/* Bit definitions and macros for MCF_LCDC_LDCR */ -#define MCF_LCDC_LDCR_TM(x) (((x)&0x0000001F)<<0) -#define MCF_LCDC_LDCR_HM(x) (((x)&0x0000001F)<<16) -#define MCF_LCDC_LDCR_BURST (0x80000000) - -/* Bit definitions and macros for MCF_LCDC_LRMCR */ -#define MCF_LCDC_LRMCR_SEL_REF (0x00000001) - -/* Bit definitions and macros for MCF_LCDC_LICR */ -#define MCF_LCDC_LICR_INTCON (0x00000001) -#define MCF_LCDC_LICR_INTSYN (0x00000004) -#define MCF_LCDC_LICR_GW_INT_CON (0x00000010) - -/* Bit definitions and macros for MCF_LCDC_LIER */ -#define MCF_LCDC_LIER_BOF_EN (0x00000001) -#define MCF_LCDC_LIER_EOF_EN (0x00000002) -#define MCF_LCDC_LIER_ERR_RES_EN (0x00000004) -#define MCF_LCDC_LIER_UDR_ERR_EN (0x00000008) -#define MCF_LCDC_LIER_GW_BOF_EN (0x00000010) -#define MCF_LCDC_LIER_GW_EOF_EN (0x00000020) -#define MCF_LCDC_LIER_GW_ERR_RES_EN (0x00000040) -#define MCF_LCDC_LIER_GW_UDR_ERR_EN (0x00000080) - -/* Bit definitions and macros for MCF_LCDC_LISR */ -#define MCF_LCDC_LISR_BOF (0x00000001) -#define MCF_LCDC_LISR_EOF (0x00000002) -#define MCF_LCDC_LISR_ERR_RES (0x00000004) -#define MCF_LCDC_LISR_UDR_ERR (0x00000008) -#define MCF_LCDC_LISR_GW_BOF (0x00000010) -#define MCF_LCDC_LISR_GW_EOF (0x00000020) -#define MCF_LCDC_LISR_GW_ERR_RES (0x00000040) -#define MCF_LCDC_LISR_GW_UDR_ERR (0x00000080) - -/* Bit definitions and macros for MCF_LCDC_LGWSAR */ -#define MCF_LCDC_LGWSAR_GWSA(x) (((x)&0x3FFFFFFF)<<2) - -/* Bit definitions and macros for MCF_LCDC_LGWSR */ -#define MCF_LCDC_LGWSR_GWH(x) (((x)&0x000003FF)<<0) -#define MCF_LCDC_LGWSR_GWW(x) (((x)&0x0000003F)<<20) - -/* Bit definitions and macros for MCF_LCDC_LGWVPWR */ -#define MCF_LCDC_LGWVPWR_GWVPW(x) (((x)&0x000003FF)<<0) - -/* Bit definitions and macros for MCF_LCDC_LGWPOR */ -#define MCF_LCDC_LGWPOR_GWPO(x) (((x)&0x0000001F)<<0) - -/* Bit definitions and macros for MCF_LCDC_LGWPR */ -#define MCF_LCDC_LGWPR_GWYP(x) (((x)&0x000003FF)<<0) -#define MCF_LCDC_LGWPR_GWXP(x) (((x)&0x000003FF)<<16) - -/* Bit definitions and macros for MCF_LCDC_LGWCR */ -#define MCF_LCDC_LGWCR_GWCKB(x) (((x)&0x0000003F)<<0) -#define MCF_LCDC_LGWCR_GWCKG(x) (((x)&0x0000003F)<<6) -#define MCF_LCDC_LGWCR_GWCKR(x) (((x)&0x0000003F)<<12) -#define MCF_LCDC_LGWCR_GW_RVS (0x00200000) -#define MCF_LCDC_LGWCR_GWE (0x00400000) -#define MCF_LCDC_LGWCR_GWCKE (0x00800000) -#define MCF_LCDC_LGWCR_GWAV(x) (((x)&0x000000FF)<<24) - -/* Bit definitions and macros for MCF_LCDC_LGWDCR */ -#define MCF_LCDC_LGWDCR_GWTM(x) (((x)&0x0000001F)<<0) -#define MCF_LCDC_LGWDCR_GWHM(x) (((x)&0x0000001F)<<16) -#define MCF_LCDC_LGWDCR_GWBT (0x80000000) - -/* Bit definitions and macros for MCF_LCDC_LSCR */ -#define MCF_LCDC_LSCR_PS_RISE_DELAY(x) (((x)&0x0000003F)<<26) -#define MCF_LCDC_LSCR_CLS_RISE_DELAY(x) (((x)&0x000000FF)<<16) -#define MCF_LCDC_LSCR_REV_TOGGLE_DELAY(x) (((x)&0x0000000F)<<8) -#define MCF_LCDC_LSCR_GRAY_2(x) (((x)&0x0000000F)<<4) -#define MCF_LCDC_LSCR_GRAY_1(x) (((x)&0x0000000F)<<0) - -/* Bit definitions and macros for MCF_LCDC_BPLUT_BASE */ -#define MCF_LCDC_BPLUT_BASE_BASE(x) (((x)&0xFFFFFFFF)<<0) - -/* Bit definitions and macros for MCF_LCDC_GWLUT_BASE */ -#define MCF_LCDC_GWLUT_BASE_BASE(x) (((x)&0xFFFFFFFF)<<0) - -/********************************************************************* - * - * Phase Locked Loop (PLL) - * - *********************************************************************/ - -/* Register read/write macros */ -#define MCF_PLL_PODR MCF_REG08(0xFC0C0000) -#define MCF_PLL_PLLCR MCF_REG08(0xFC0C0004) -#define MCF_PLL_PMDR MCF_REG08(0xFC0C0008) -#define MCF_PLL_PFDR MCF_REG08(0xFC0C000C) - -/* Bit definitions and macros for MCF_PLL_PODR */ -#define MCF_PLL_PODR_BUSDIV(x) (((x)&0x0F)<<0) -#define MCF_PLL_PODR_CPUDIV(x) (((x)&0x0F)<<4) - -/* Bit definitions and macros for MCF_PLL_PLLCR */ -#define MCF_PLL_PLLCR_DITHDEV(x) (((x)&0x07)<<0) -#define MCF_PLL_PLLCR_DITHEN (0x80) - -/* Bit definitions and macros for MCF_PLL_PMDR */ -#define MCF_PLL_PMDR_MODDIV(x) (((x)&0xFF)<<0) - -/* Bit definitions and macros for MCF_PLL_PFDR */ -#define MCF_PLL_PFDR_MFD(x) (((x)&0xFF)<<0) - -/********************************************************************* - * - * System Control Module Registers (SCM) - * - *********************************************************************/ - -/* Register read/write macros */ -#define MCF_SCM_MPR MCF_REG32(0xFC000000) -#define MCF_SCM_PACRA MCF_REG32(0xFC000020) -#define MCF_SCM_PACRB MCF_REG32(0xFC000024) -#define MCF_SCM_PACRC MCF_REG32(0xFC000028) -#define MCF_SCM_PACRD MCF_REG32(0xFC00002C) -#define MCF_SCM_PACRE MCF_REG32(0xFC000040) -#define MCF_SCM_PACRF MCF_REG32(0xFC000044) - -#define MCF_SCM_BCR MCF_REG32(0xFC040024) - -/********************************************************************* - * - * SDRAM Controller (SDRAMC) - * - *********************************************************************/ - -/* Register read/write macros */ -#define MCF_SDRAMC_SDMR MCF_REG32(0xFC0B8000) -#define MCF_SDRAMC_SDCR MCF_REG32(0xFC0B8004) -#define MCF_SDRAMC_SDCFG1 MCF_REG32(0xFC0B8008) -#define MCF_SDRAMC_SDCFG2 MCF_REG32(0xFC0B800C) -#define MCF_SDRAMC_LIMP_FIX MCF_REG32(0xFC0B8080) -#define MCF_SDRAMC_SDDS MCF_REG32(0xFC0B8100) -#define MCF_SDRAMC_SDCS0 MCF_REG32(0xFC0B8110) -#define MCF_SDRAMC_SDCS1 MCF_REG32(0xFC0B8114) -#define MCF_SDRAMC_SDCS2 MCF_REG32(0xFC0B8118) -#define MCF_SDRAMC_SDCS3 MCF_REG32(0xFC0B811C) -#define MCF_SDRAMC_SDCS(x) MCF_REG32(0xFC0B8110+((x)*0x004)) - -/* Bit definitions and macros for MCF_SDRAMC_SDMR */ -#define MCF_SDRAMC_SDMR_CMD (0x00010000) -#define MCF_SDRAMC_SDMR_AD(x) (((x)&0x00000FFF)<<18) -#define MCF_SDRAMC_SDMR_BNKAD(x) (((x)&0x00000003)<<30) -#define MCF_SDRAMC_SDMR_BNKAD_LMR (0x00000000) -#define MCF_SDRAMC_SDMR_BNKAD_LEMR (0x40000000) - -/* Bit definitions and macros for MCF_SDRAMC_SDCR */ -#define MCF_SDRAMC_SDCR_IPALL (0x00000002) -#define MCF_SDRAMC_SDCR_IREF (0x00000004) -#define MCF_SDRAMC_SDCR_DQS_OE(x) (((x)&0x0000000F)<<8) -#define MCF_SDRAMC_SDCR_PS(x) (((x)&0x00000003)<<12) -#define MCF_SDRAMC_SDCR_RCNT(x) (((x)&0x0000003F)<<16) -#define MCF_SDRAMC_SDCR_OE_RULE (0x00400000) -#define MCF_SDRAMC_SDCR_MUX(x) (((x)&0x00000003)<<24) -#define MCF_SDRAMC_SDCR_REF (0x10000000) -#define MCF_SDRAMC_SDCR_DDR (0x20000000) -#define MCF_SDRAMC_SDCR_CKE (0x40000000) -#define MCF_SDRAMC_SDCR_MODE_EN (0x80000000) -#define MCF_SDRAMC_SDCR_PS_16 (0x00002000) -#define MCF_SDRAMC_SDCR_PS_32 (0x00000000) - -/* Bit definitions and macros for MCF_SDRAMC_SDCFG1 */ -#define MCF_SDRAMC_SDCFG1_WTLAT(x) (((x)&0x00000007)<<4) -#define MCF_SDRAMC_SDCFG1_REF2ACT(x) (((x)&0x0000000F)<<8) -#define MCF_SDRAMC_SDCFG1_PRE2ACT(x) (((x)&0x00000007)<<12) -#define MCF_SDRAMC_SDCFG1_ACT2RW(x) (((x)&0x00000007)<<16) -#define MCF_SDRAMC_SDCFG1_RDLAT(x) (((x)&0x0000000F)<<20) -#define MCF_SDRAMC_SDCFG1_SWT2RD(x) (((x)&0x00000007)<<24) -#define MCF_SDRAMC_SDCFG1_SRD2RW(x) (((x)&0x0000000F)<<28) - -/* Bit definitions and macros for MCF_SDRAMC_SDCFG2 */ -#define MCF_SDRAMC_SDCFG2_BL(x) (((x)&0x0000000F)<<16) -#define MCF_SDRAMC_SDCFG2_BRD2WT(x) (((x)&0x0000000F)<<20) -#define MCF_SDRAMC_SDCFG2_BWT2RW(x) (((x)&0x0000000F)<<24) -#define MCF_SDRAMC_SDCFG2_BRD2PRE(x) (((x)&0x0000000F)<<28) - -/* Device Errata - LIMP mode work around */ -#define MCF_SDRAMC_REFRESH (0x40000000) - -/* Bit definitions and macros for MCF_SDRAMC_SDDS */ -#define MCF_SDRAMC_SDDS_SB_D(x) (((x)&0x00000003)<<0) -#define MCF_SDRAMC_SDDS_SB_S(x) (((x)&0x00000003)<<2) -#define MCF_SDRAMC_SDDS_SB_A(x) (((x)&0x00000003)<<4) -#define MCF_SDRAMC_SDDS_SB_C(x) (((x)&0x00000003)<<6) -#define MCF_SDRAMC_SDDS_SB_E(x) (((x)&0x00000003)<<8) - -/* Bit definitions and macros for MCF_SDRAMC_SDCS */ -#define MCF_SDRAMC_SDCS_CSSZ(x) (((x)&0x0000001F)<<0) -#define MCF_SDRAMC_SDCS_BASE(x) (((x)&0x00000FFF)<<20) -#define MCF_SDRAMC_SDCS_BA(x) ((x)&0xFFF00000) -#define MCF_SDRAMC_SDCS_CSSZ_DIABLE (0x00000000) -#define MCF_SDRAMC_SDCS_CSSZ_1MBYTE (0x00000013) -#define MCF_SDRAMC_SDCS_CSSZ_2MBYTE (0x00000014) -#define MCF_SDRAMC_SDCS_CSSZ_4MBYTE (0x00000015) -#define MCF_SDRAMC_SDCS_CSSZ_8MBYTE (0x00000016) -#define MCF_SDRAMC_SDCS_CSSZ_16MBYTE (0x00000017) -#define MCF_SDRAMC_SDCS_CSSZ_32MBYTE (0x00000018) -#define MCF_SDRAMC_SDCS_CSSZ_64MBYTE (0x00000019) -#define MCF_SDRAMC_SDCS_CSSZ_128MBYTE (0x0000001A) -#define MCF_SDRAMC_SDCS_CSSZ_256MBYTE (0x0000001B) -#define MCF_SDRAMC_SDCS_CSSZ_512MBYTE (0x0000001C) -#define MCF_SDRAMC_SDCS_CSSZ_1GBYTE (0x0000001D) -#define MCF_SDRAMC_SDCS_CSSZ_2GBYTE (0x0000001E) -#define MCF_SDRAMC_SDCS_CSSZ_4GBYTE (0x0000001F) - -/********************************************************************* - * - * FlexCAN module registers - * - *********************************************************************/ -#define MCF_FLEXCAN_BASEADDR(x) (0xFC020000+(x)*0x0800) -#define MCF_FLEXCAN_CANMCR(x) MCF_REG32(0xFC020000+(x)*0x0800+0x00) -#define MCF_FLEXCAN_CANCTRL(x) MCF_REG32(0xFC020000+(x)*0x0800+0x04) -#define MCF_FLEXCAN_TIMER(x) MCF_REG32(0xFC020000+(x)*0x0800+0x08) -#define MCF_FLEXCAN_RXGMASK(x) MCF_REG32(0xFC020000+(x)*0x0800+0x10) -#define MCF_FLEXCAN_RX14MASK(x) MCF_REG32(0xFC020000+(x)*0x0800+0x14) -#define MCF_FLEXCAN_RX15MASK(x) MCF_REG32(0xFC020000+(x)*0x0800+0x18) -#define MCF_FLEXCAN_ERRCNT(x) MCF_REG32(0xFC020000+(x)*0x0800+0x1C) -#define MCF_FLEXCAN_ERRSTAT(x) MCF_REG32(0xFC020000+(x)*0x0800+0x20) -#define MCF_FLEXCAN_IMASK(x) MCF_REG32(0xFC020000+(x)*0x0800+0x28) -#define MCF_FLEXCAN_IFLAG(x) MCF_REG32(0xFC020000+(x)*0x0800+0x30) - -#define MCF_FLEXCAN_MB_CNT(x,y) MCF_REG32(0xFC020080+(x)*0x0800+(y)*0x10+0x0) -#define MCF_FLEXCAN_MB_ID(x,y) MCF_REG32(0xFC020080+(x)*0x0800+(y)*0x10+0x4) -#define MCF_FLEXCAN_MB_DB(x,y,z) MCF_REG08(0xFC020080+(x)*0x0800+(y)*0x10+0x8+(z)*0x1) - -/* - * FlexCAN Module Configuration Register - */ -#define CANMCR_MDIS (0x80000000) -#define CANMCR_FRZ (0x40000000) -#define CANMCR_HALT (0x10000000) -#define CANMCR_SOFTRST (0x02000000) -#define CANMCR_FRZACK (0x01000000) -#define CANMCR_SUPV (0x00800000) -#define CANMCR_MAXMB(x) ((x)&0x0F) - -/* - * FlexCAN Control Register - */ -#define CANCTRL_PRESDIV(x) (((x)&0xFF)<<24) -#define CANCTRL_RJW(x) (((x)&0x03)<<22) -#define CANCTRL_PSEG1(x) (((x)&0x07)<<19) -#define CANCTRL_PSEG2(x) (((x)&0x07)<<16) -#define CANCTRL_BOFFMSK (0x00008000) -#define CANCTRL_ERRMSK (0x00004000) -#define CANCTRL_CLKSRC (0x00002000) -#define CANCTRL_LPB (0x00001000) -#define CANCTRL_SAMP (0x00000080) -#define CANCTRL_BOFFREC (0x00000040) -#define CANCTRL_TSYNC (0x00000020) -#define CANCTRL_LBUF (0x00000010) -#define CANCTRL_LOM (0x00000008) -#define CANCTRL_PROPSEG(x) ((x)&0x07) - -/* - * FlexCAN Error Counter Register - */ -#define ERRCNT_RXECTR(x) (((x)&0xFF)<<8) -#define ERRCNT_TXECTR(x) ((x)&0xFF) - -/* - * FlexCAN Error and Status Register - */ -#define ERRSTAT_BITERR(x) (((x)&0x03)<<14) -#define ERRSTAT_ACKERR (0x00002000) -#define ERRSTAT_CRCERR (0x00001000) -#define ERRSTAT_FRMERR (0x00000800) -#define ERRSTAT_STFERR (0x00000400) -#define ERRSTAT_TXWRN (0x00000200) -#define ERRSTAT_RXWRN (0x00000100) -#define ERRSTAT_IDLE (0x00000080) -#define ERRSTAT_TXRX (0x00000040) -#define ERRSTAT_FLTCONF(x) (((x)&0x03)<<4) -#define ERRSTAT_BOFFINT (0x00000004) -#define ERRSTAT_ERRINT (0x00000002) - -/* - * Interrupt Mask Register - */ -#define IMASK_BUF15M (0x8000) -#define IMASK_BUF14M (0x4000) -#define IMASK_BUF13M (0x2000) -#define IMASK_BUF12M (0x1000) -#define IMASK_BUF11M (0x0800) -#define IMASK_BUF10M (0x0400) -#define IMASK_BUF9M (0x0200) -#define IMASK_BUF8M (0x0100) -#define IMASK_BUF7M (0x0080) -#define IMASK_BUF6M (0x0040) -#define IMASK_BUF5M (0x0020) -#define IMASK_BUF4M (0x0010) -#define IMASK_BUF3M (0x0008) -#define IMASK_BUF2M (0x0004) -#define IMASK_BUF1M (0x0002) -#define IMASK_BUF0M (0x0001) -#define IMASK_BUFnM(x) (0x1<<(x)) -#define IMASK_BUFF_ENABLE_ALL (0x1111) -#define IMASK_BUFF_DISABLE_ALL (0x0000) - -/* - * Interrupt Flag Register - */ -#define IFLAG_BUF15M (0x8000) -#define IFLAG_BUF14M (0x4000) -#define IFLAG_BUF13M (0x2000) -#define IFLAG_BUF12M (0x1000) -#define IFLAG_BUF11M (0x0800) -#define IFLAG_BUF10M (0x0400) -#define IFLAG_BUF9M (0x0200) -#define IFLAG_BUF8M (0x0100) -#define IFLAG_BUF7M (0x0080) -#define IFLAG_BUF6M (0x0040) -#define IFLAG_BUF5M (0x0020) -#define IFLAG_BUF4M (0x0010) -#define IFLAG_BUF3M (0x0008) -#define IFLAG_BUF2M (0x0004) -#define IFLAG_BUF1M (0x0002) -#define IFLAG_BUF0M (0x0001) -#define IFLAG_BUFF_SET_ALL (0xFFFF) -#define IFLAG_BUFF_CLEAR_ALL (0x0000) -#define IFLAG_BUFnM(x) (0x1<<(x)) - -/* - * Message Buffers - */ -#define MB_CNT_CODE(x) (((x)&0x0F)<<24) -#define MB_CNT_SRR (0x00400000) -#define MB_CNT_IDE (0x00200000) -#define MB_CNT_RTR (0x00100000) -#define MB_CNT_LENGTH(x) (((x)&0x0F)<<16) -#define MB_CNT_TIMESTAMP(x) ((x)&0xFFFF) -#define MB_ID_STD(x) (((x)&0x07FF)<<18) -#define MB_ID_EXT(x) ((x)&0x3FFFF) - -/********************************************************************* - * - * Edge Port Module (EPORT) - * - *********************************************************************/ - -/* Register read/write macros */ -#define MCF_EPORT_EPPAR MCF_REG16(0xFC094000) -#define MCF_EPORT_EPDDR MCF_REG08(0xFC094002) -#define MCF_EPORT_EPIER MCF_REG08(0xFC094003) -#define MCF_EPORT_EPDR MCF_REG08(0xFC094004) -#define MCF_EPORT_EPPDR MCF_REG08(0xFC094005) -#define MCF_EPORT_EPFR MCF_REG08(0xFC094006) - -/* Bit definitions and macros for MCF_EPORT_EPPAR */ -#define MCF_EPORT_EPPAR_EPPA1(x) (((x)&0x0003)<<2) -#define MCF_EPORT_EPPAR_EPPA2(x) (((x)&0x0003)<<4) -#define MCF_EPORT_EPPAR_EPPA3(x) (((x)&0x0003)<<6) -#define MCF_EPORT_EPPAR_EPPA4(x) (((x)&0x0003)<<8) -#define MCF_EPORT_EPPAR_EPPA5(x) (((x)&0x0003)<<10) -#define MCF_EPORT_EPPAR_EPPA6(x) (((x)&0x0003)<<12) -#define MCF_EPORT_EPPAR_EPPA7(x) (((x)&0x0003)<<14) -#define MCF_EPORT_EPPAR_LEVEL (0) -#define MCF_EPORT_EPPAR_RISING (1) -#define MCF_EPORT_EPPAR_FALLING (2) -#define MCF_EPORT_EPPAR_BOTH (3) -#define MCF_EPORT_EPPAR_EPPA7_LEVEL (0x0000) -#define MCF_EPORT_EPPAR_EPPA7_RISING (0x4000) -#define MCF_EPORT_EPPAR_EPPA7_FALLING (0x8000) -#define MCF_EPORT_EPPAR_EPPA7_BOTH (0xC000) -#define MCF_EPORT_EPPAR_EPPA6_LEVEL (0x0000) -#define MCF_EPORT_EPPAR_EPPA6_RISING (0x1000) -#define MCF_EPORT_EPPAR_EPPA6_FALLING (0x2000) -#define MCF_EPORT_EPPAR_EPPA6_BOTH (0x3000) -#define MCF_EPORT_EPPAR_EPPA5_LEVEL (0x0000) -#define MCF_EPORT_EPPAR_EPPA5_RISING (0x0400) -#define MCF_EPORT_EPPAR_EPPA5_FALLING (0x0800) -#define MCF_EPORT_EPPAR_EPPA5_BOTH (0x0C00) -#define MCF_EPORT_EPPAR_EPPA4_LEVEL (0x0000) -#define MCF_EPORT_EPPAR_EPPA4_RISING (0x0100) -#define MCF_EPORT_EPPAR_EPPA4_FALLING (0x0200) -#define MCF_EPORT_EPPAR_EPPA4_BOTH (0x0300) -#define MCF_EPORT_EPPAR_EPPA3_LEVEL (0x0000) -#define MCF_EPORT_EPPAR_EPPA3_RISING (0x0040) -#define MCF_EPORT_EPPAR_EPPA3_FALLING (0x0080) -#define MCF_EPORT_EPPAR_EPPA3_BOTH (0x00C0) -#define MCF_EPORT_EPPAR_EPPA2_LEVEL (0x0000) -#define MCF_EPORT_EPPAR_EPPA2_RISING (0x0010) -#define MCF_EPORT_EPPAR_EPPA2_FALLING (0x0020) -#define MCF_EPORT_EPPAR_EPPA2_BOTH (0x0030) -#define MCF_EPORT_EPPAR_EPPA1_LEVEL (0x0000) -#define MCF_EPORT_EPPAR_EPPA1_RISING (0x0004) -#define MCF_EPORT_EPPAR_EPPA1_FALLING (0x0008) -#define MCF_EPORT_EPPAR_EPPA1_BOTH (0x000C) - -/* Bit definitions and macros for MCF_EPORT_EPDDR */ -#define MCF_EPORT_EPDDR_EPDD1 (0x02) -#define MCF_EPORT_EPDDR_EPDD2 (0x04) -#define MCF_EPORT_EPDDR_EPDD3 (0x08) -#define MCF_EPORT_EPDDR_EPDD4 (0x10) -#define MCF_EPORT_EPDDR_EPDD5 (0x20) -#define MCF_EPORT_EPDDR_EPDD6 (0x40) -#define MCF_EPORT_EPDDR_EPDD7 (0x80) - -/* Bit definitions and macros for MCF_EPORT_EPIER */ -#define MCF_EPORT_EPIER_EPIE1 (0x02) -#define MCF_EPORT_EPIER_EPIE2 (0x04) -#define MCF_EPORT_EPIER_EPIE3 (0x08) -#define MCF_EPORT_EPIER_EPIE4 (0x10) -#define MCF_EPORT_EPIER_EPIE5 (0x20) -#define MCF_EPORT_EPIER_EPIE6 (0x40) -#define MCF_EPORT_EPIER_EPIE7 (0x80) - -/* Bit definitions and macros for MCF_EPORT_EPDR */ -#define MCF_EPORT_EPDR_EPD1 (0x02) -#define MCF_EPORT_EPDR_EPD2 (0x04) -#define MCF_EPORT_EPDR_EPD3 (0x08) -#define MCF_EPORT_EPDR_EPD4 (0x10) -#define MCF_EPORT_EPDR_EPD5 (0x20) -#define MCF_EPORT_EPDR_EPD6 (0x40) -#define MCF_EPORT_EPDR_EPD7 (0x80) - -/* Bit definitions and macros for MCF_EPORT_EPPDR */ -#define MCF_EPORT_EPPDR_EPPD1 (0x02) -#define MCF_EPORT_EPPDR_EPPD2 (0x04) -#define MCF_EPORT_EPPDR_EPPD3 (0x08) -#define MCF_EPORT_EPPDR_EPPD4 (0x10) -#define MCF_EPORT_EPPDR_EPPD5 (0x20) -#define MCF_EPORT_EPPDR_EPPD6 (0x40) -#define MCF_EPORT_EPPDR_EPPD7 (0x80) - -/* Bit definitions and macros for MCF_EPORT_EPFR */ -#define MCF_EPORT_EPFR_EPF1 (0x02) -#define MCF_EPORT_EPFR_EPF2 (0x04) -#define MCF_EPORT_EPFR_EPF3 (0x08) -#define MCF_EPORT_EPFR_EPF4 (0x10) -#define MCF_EPORT_EPFR_EPF5 (0x20) -#define MCF_EPORT_EPFR_EPF6 (0x40) -#define MCF_EPORT_EPFR_EPF7 (0x80) - -/********************************************************************/ -#endif /* m532xsim_h */ diff --git a/arch/m68knommu/include/asm/m5407sim.h b/arch/m68knommu/include/asm/m5407sim.h deleted file mode 100644 index cc22c4a5300..00000000000 --- a/arch/m68knommu/include/asm/m5407sim.h +++ /dev/null @@ -1,157 +0,0 @@ -/****************************************************************************/ - -/* - * m5407sim.h -- ColdFire 5407 System Integration Module support. - * - * (C) Copyright 2000, Lineo (www.lineo.com) - * (C) Copyright 1999, Moreton Bay Ventures Pty Ltd. - * - * Modified by David W. Miller for the MCF5307 Eval Board. - */ - -/****************************************************************************/ -#ifndef m5407sim_h -#define m5407sim_h -/****************************************************************************/ - -/* - * Define the 5407 SIM register set addresses. - */ -#define MCFSIM_RSR 0x00 /* Reset Status reg (r/w) */ -#define MCFSIM_SYPCR 0x01 /* System Protection reg (r/w)*/ -#define MCFSIM_SWIVR 0x02 /* SW Watchdog intr reg (r/w) */ -#define MCFSIM_SWSR 0x03 /* SW Watchdog service (r/w) */ -#define MCFSIM_PAR 0x04 /* Pin Assignment reg (r/w) */ -#define MCFSIM_IRQPAR 0x06 /* Interrupt Assignment reg (r/w) */ -#define MCFSIM_PLLCR 0x08 /* PLL Controll Reg*/ -#define MCFSIM_MPARK 0x0C /* BUS Master Control Reg*/ -#define MCFSIM_IPR 0x40 /* Interrupt Pend reg (r/w) */ -#define MCFSIM_IMR 0x44 /* Interrupt Mask reg (r/w) */ -#define MCFSIM_AVR 0x4b /* Autovector Ctrl reg (r/w) */ -#define MCFSIM_ICR0 0x4c /* Intr Ctrl reg 0 (r/w) */ -#define MCFSIM_ICR1 0x4d /* Intr Ctrl reg 1 (r/w) */ -#define MCFSIM_ICR2 0x4e /* Intr Ctrl reg 2 (r/w) */ -#define MCFSIM_ICR3 0x4f /* Intr Ctrl reg 3 (r/w) */ -#define MCFSIM_ICR4 0x50 /* Intr Ctrl reg 4 (r/w) */ -#define MCFSIM_ICR5 0x51 /* Intr Ctrl reg 5 (r/w) */ -#define MCFSIM_ICR6 0x52 /* Intr Ctrl reg 6 (r/w) */ -#define MCFSIM_ICR7 0x53 /* Intr Ctrl reg 7 (r/w) */ -#define MCFSIM_ICR8 0x54 /* Intr Ctrl reg 8 (r/w) */ -#define MCFSIM_ICR9 0x55 /* Intr Ctrl reg 9 (r/w) */ -#define MCFSIM_ICR10 0x56 /* Intr Ctrl reg 10 (r/w) */ -#define MCFSIM_ICR11 0x57 /* Intr Ctrl reg 11 (r/w) */ - -#define MCFSIM_CSAR0 0x80 /* CS 0 Address 0 reg (r/w) */ -#define MCFSIM_CSMR0 0x84 /* CS 0 Mask 0 reg (r/w) */ -#define MCFSIM_CSCR0 0x8a /* CS 0 Control reg (r/w) */ -#define MCFSIM_CSAR1 0x8c /* CS 1 Address reg (r/w) */ -#define MCFSIM_CSMR1 0x90 /* CS 1 Mask reg (r/w) */ -#define MCFSIM_CSCR1 0x96 /* CS 1 Control reg (r/w) */ - -#define MCFSIM_CSAR2 0x98 /* CS 2 Address reg (r/w) */ -#define MCFSIM_CSMR2 0x9c /* CS 2 Mask reg (r/w) */ -#define MCFSIM_CSCR2 0xa2 /* CS 2 Control reg (r/w) */ -#define MCFSIM_CSAR3 0xa4 /* CS 3 Address reg (r/w) */ -#define MCFSIM_CSMR3 0xa8 /* CS 3 Mask reg (r/w) */ -#define MCFSIM_CSCR3 0xae /* CS 3 Control reg (r/w) */ -#define MCFSIM_CSAR4 0xb0 /* CS 4 Address reg (r/w) */ -#define MCFSIM_CSMR4 0xb4 /* CS 4 Mask reg (r/w) */ -#define MCFSIM_CSCR4 0xba /* CS 4 Control reg (r/w) */ -#define MCFSIM_CSAR5 0xbc /* CS 5 Address reg (r/w) */ -#define MCFSIM_CSMR5 0xc0 /* CS 5 Mask reg (r/w) */ -#define MCFSIM_CSCR5 0xc6 /* CS 5 Control reg (r/w) */ -#define MCFSIM_CSAR6 0xc8 /* CS 6 Address reg (r/w) */ -#define MCFSIM_CSMR6 0xcc /* CS 6 Mask reg (r/w) */ -#define MCFSIM_CSCR6 0xd2 /* CS 6 Control reg (r/w) */ -#define MCFSIM_CSAR7 0xd4 /* CS 7 Address reg (r/w) */ -#define MCFSIM_CSMR7 0xd8 /* CS 7 Mask reg (r/w) */ -#define MCFSIM_CSCR7 0xde /* CS 7 Control reg (r/w) */ - -#define MCFSIM_DCR 0x100 /* DRAM Control reg (r/w) */ -#define MCFSIM_DACR0 0x108 /* DRAM 0 Addr and Ctrl (r/w) */ -#define MCFSIM_DMR0 0x10c /* DRAM 0 Mask reg (r/w) */ -#define MCFSIM_DACR1 0x110 /* DRAM 1 Addr and Ctrl (r/w) */ -#define MCFSIM_DMR1 0x114 /* DRAM 1 Mask reg (r/w) */ - -#define MCFSIM_PADDR 0x244 /* Parallel Direction (r/w) */ -#define MCFSIM_PADAT 0x248 /* Parallel Data (r/w) */ - - -/* - * Some symbol defines for the above... - */ -#define MCFSIM_SWDICR MCFSIM_ICR0 /* Watchdog timer ICR */ -#define MCFSIM_TIMER1ICR MCFSIM_ICR1 /* Timer 1 ICR */ -#define MCFSIM_TIMER2ICR MCFSIM_ICR2 /* Timer 2 ICR */ -#define MCFSIM_UART1ICR MCFSIM_ICR4 /* UART 1 ICR */ -#define MCFSIM_UART2ICR MCFSIM_ICR5 /* UART 2 ICR */ -#define MCFSIM_DMA0ICR MCFSIM_ICR6 /* DMA 0 ICR */ -#define MCFSIM_DMA1ICR MCFSIM_ICR7 /* DMA 1 ICR */ -#define MCFSIM_DMA2ICR MCFSIM_ICR8 /* DMA 2 ICR */ -#define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */ - -/* - * Macro to set IMR register. It is 32 bits on the 5407. - */ -#define mcf_getimr() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) - -#define mcf_setimr(imr) \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr); - -#define mcf_getipr() \ - *((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR)) - - -/* - * Some symbol defines for the Parallel Port Pin Assignment Register - */ -#define MCFSIM_PAR_DREQ0 0x40 /* Set to select DREQ0 input */ - /* Clear to select par I/O */ -#define MCFSIM_PAR_DREQ1 0x20 /* Select DREQ1 input */ - /* Clear to select par I/O */ - -/* - * Defines for the IRQPAR Register - */ -#define IRQ5_LEVEL4 0x80 -#define IRQ3_LEVEL6 0x40 -#define IRQ1_LEVEL2 0x20 - - -/* - * Define the Cache register flags. - */ -#define CACR_DEC 0x80000000 /* Enable data cache */ -#define CACR_DWP 0x40000000 /* Data write protection */ -#define CACR_DESB 0x20000000 /* Enable data store buffer */ -#define CACR_DDPI 0x10000000 /* Disable CPUSHL */ -#define CACR_DHCLK 0x08000000 /* Half data cache lock mode */ -#define CACR_DDCM_WT 0x00000000 /* Write through cache*/ -#define CACR_DDCM_CP 0x02000000 /* Copyback cache */ -#define CACR_DDCM_P 0x04000000 /* No cache, precise */ -#define CACR_DDCM_IMP 0x06000000 /* No cache, imprecise */ -#define CACR_DCINVA 0x01000000 /* Invalidate data cache */ -#define CACR_BEC 0x00080000 /* Enable branch cache */ -#define CACR_BCINVA 0x00040000 /* Invalidate branch cache */ -#define CACR_IEC 0x00008000 /* Enable instruction cache */ -#define CACR_DNFB 0x00002000 /* Inhibited fill buffer */ -#define CACR_IDPI 0x00001000 /* Disable CPUSHL */ -#define CACR_IHLCK 0x00000800 /* Intruction cache half lock */ -#define CACR_IDCM 0x00000400 /* Intruction cache inhibit */ -#define CACR_ICINVA 0x00000100 /* Invalidate instr cache */ - -#define ACR_BASE_POS 24 /* Address Base */ -#define ACR_MASK_POS 16 /* Address Mask */ -#define ACR_ENABLE 0x00008000 /* Enable address */ -#define ACR_USER 0x00000000 /* User mode access only */ -#define ACR_SUPER 0x00002000 /* Supervisor mode only */ -#define ACR_ANY 0x00004000 /* Match any access mode */ -#define ACR_CM_WT 0x00000000 /* Write through mode */ -#define ACR_CM_CP 0x00000020 /* Copyback mode */ -#define ACR_CM_OFF_PRE 0x00000040 /* No cache, precise */ -#define ACR_CM_OFF_IMP 0x00000060 /* No cache, imprecise */ -#define ACR_WPROTECT 0x00000004 /* Write protect */ - -/****************************************************************************/ -#endif /* m5407sim_h */ diff --git a/arch/m68knommu/include/asm/m68360.h b/arch/m68knommu/include/asm/m68360.h deleted file mode 100644 index eb7d39ef285..00000000000 --- a/arch/m68knommu/include/asm/m68360.h +++ /dev/null @@ -1,13 +0,0 @@ -#include "m68360_regs.h" -#include "m68360_pram.h" -#include "m68360_quicc.h" -#include "m68360_enet.h" - -#ifdef CONFIG_M68360 - -#define CPM_INTERRUPT 4 - -/* see MC68360 User's Manual, p. 7-377 */ -#define CPM_VECTOR_BASE 0x04 /* 3 MSbits of CPM vector */ - -#endif /* CONFIG_M68360 */ diff --git a/arch/m68knommu/include/asm/m68360_enet.h b/arch/m68knommu/include/asm/m68360_enet.h deleted file mode 100644 index c36f4d05920..00000000000 --- a/arch/m68knommu/include/asm/m68360_enet.h +++ /dev/null @@ -1,177 +0,0 @@ -/*********************************** - * $Id: m68360_enet.h,v 1.1 2002/03/02 15:01:07 gerg Exp $ - *********************************** - * - *************************************** - * Definitions for the ETHERNET controllers - *************************************** - */ - -#ifndef __ETHER_H -#define __ETHER_H - -#include "quicc_simple.h" - -/* - * transmit BD's - */ -#define T_R 0x8000 /* ready bit */ -#define E_T_PAD 0x4000 /* short frame padding */ -#define T_W 0x2000 /* wrap bit */ -#define T_I 0x1000 /* interrupt on completion */ -#define T_L 0x0800 /* last in frame */ -#define T_TC 0x0400 /* transmit CRC (when last) */ - -#define T_DEF 0x0200 /* defer indication */ -#define T_HB 0x0100 /* heartbeat */ -#define T_LC 0x0080 /* error: late collision */ -#define T_RL 0x0040 /* error: retransmission limit */ -#define T_RC 0x003c /* retry count */ -#define T_UN 0x0002 /* error: underrun */ -#define T_CSL 0x0001 /* carier sense lost */ -#define T_ERROR (T_HB | T_LC | T_RL | T_UN | T_CSL) - -/* - * receive BD's - */ -#define R_E 0x8000 /* buffer empty */ -#define R_W 0x2000 /* wrap bit */ -#define R_I 0x1000 /* interrupt on reception */ -#define R_L 0x0800 /* last BD in frame */ -#define R_F 0x0400 /* first BD in frame */ -#define R_M 0x0100 /* received because of promisc. mode */ - -#define R_LG 0x0020 /* frame too long */ -#define R_NO 0x0010 /* non-octet aligned */ -#define R_SH 0x0008 /* short frame */ -#define R_CR 0x0004 /* receive CRC error */ -#define R_OV 0x0002 /* receive overrun */ -#define R_CL 0x0001 /* collision */ -#define ETHER_R_ERROR (R_LG | R_NO | R_SH | R_CR | R_OV | R_CL) - - -/* - * ethernet interrupts - */ -#define ETHERNET_GRA 0x0080 /* graceful stop complete */ -#define ETHERNET_TXE 0x0010 /* transmit error */ -#define ETHERNET_RXF 0x0008 /* receive frame */ -#define ETHERNET_BSY 0x0004 /* busy condition */ -#define ETHERNET_TXB 0x0002 /* transmit buffer */ -#define ETHERNET_RXB 0x0001 /* receive buffer */ - -/* - * ethernet protocol specific mode register (PSMR) - */ -#define ETHER_HBC 0x8000 /* heartbeat checking */ -#define ETHER_FC 0x4000 /* force collision */ -#define ETHER_RSH 0x2000 /* receive short frames */ -#define ETHER_IAM 0x1000 /* individual address mode */ -#define ETHER_CRC_32 (0x2<<10) /* Enable CRC */ -#define ETHER_PRO 0x0200 /* promiscuous */ -#define ETHER_BRO 0x0100 /* broadcast address */ -#define ETHER_SBT 0x0080 /* stop backoff timer */ -#define ETHER_LPB 0x0040 /* Loop Back Mode */ -#define ETHER_SIP 0x0020 /* sample input pins */ -#define ETHER_LCW 0x0010 /* late collision window */ -#define ETHER_NIB_13 (0x0<<1) /* # of ignored bits 13 */ -#define ETHER_NIB_14 (0x1<<1) /* # of ignored bits 14 */ -#define ETHER_NIB_15 (0x2<<1) /* # of ignored bits 15 */ -#define ETHER_NIB_16 (0x3<<1) /* # of ignored bits 16 */ -#define ETHER_NIB_21 (0x4<<1) /* # of ignored bits 21 */ -#define ETHER_NIB_22 (0x5<<1) /* # of ignored bits 22 */ -#define ETHER_NIB_23 (0x6<<1) /* # of ignored bits 23 */ -#define ETHER_NIB_24 (0x7<<1) /* # of ignored bits 24 */ - -/* - * ethernet specific parameters - */ -#define CRC_WORD 4 /* Length in bytes of CRC */ -#define C_PRES 0xffffffff /* preform 32 bit CRC */ -#define C_MASK 0xdebb20e3 /* comply with 32 bit CRC */ -#define CRCEC 0x00000000 -#define ALEC 0x00000000 -#define DISFC 0x00000000 -#define PADS 0x00000000 -#define RET_LIM 0x000f /* retry 15 times to send a frame before interrupt */ -#define ETH_MFLR 0x05ee /* 1518 max frame size */ -#define MINFLR 0x0040 /* Minimum frame size 64 */ -#define MAXD1 0x05ee /* Max dma count 1518 */ -#define MAXD2 0x05ee -#define GADDR1 0x00000000 /* Clear group address */ -#define GADDR2 0x00000000 -#define GADDR3 0x00000000 -#define GADDR4 0x00000000 -#define P_PER 0x00000000 /*not used */ -#define IADDR1 0x00000000 /* Individual hash table not used */ -#define IADDR2 0x00000000 -#define IADDR3 0x00000000 -#define IADDR4 0x00000000 -#define TADDR_H 0x00000000 /* clear this regs */ -#define TADDR_M 0x00000000 -#define TADDR_L 0x00000000 - -/* SCC Parameter Ram */ -#define RFCR 0x18 /* normal operation */ -#define TFCR 0x18 /* normal operation */ -#define E_MRBLR 1518 /* Max ethernet frame length */ - -/* - * ethernet specific structure - */ -typedef union { - unsigned char b[6]; - struct { - unsigned short high; - unsigned short middl; - unsigned short low; - } w; -} ETHER_ADDR; - -typedef struct { - int max_frame_length; - int promisc_mode; - int reject_broadcast; - ETHER_ADDR phys_adr; -} ETHER_SPECIFIC; - -typedef struct { - ETHER_ADDR dst_addr; - ETHER_ADDR src_addr; - unsigned short type_or_len; - unsigned char data[1]; -} ETHER_FRAME; - -#define MAX_DATALEN 1500 -typedef struct { - ETHER_ADDR dst_addr; - ETHER_ADDR src_addr; - unsigned short type_or_len; - unsigned char data[MAX_DATALEN]; - unsigned char fcs[CRC_WORD]; -} ETHER_MAX_FRAME; - - -/* - * Internal ethernet function prototypes - */ -void ether_interrupt(int scc_num); -/* mleslie: debug */ -/* static void ethernet_rx_internal(int scc_num); */ -/* static void ethernet_tx_internal(int scc_num); */ - -/* - * User callable routines prototypes (ethernet specific) - */ -void ethernet_init(int scc_number, - alloc_routine *alloc_buffer, - free_routine *free_buffer, - store_rx_buffer_routine *store_rx_buffer, - handle_tx_error_routine *handle_tx_error, - handle_rx_error_routine *handle_rx_error, - handle_lost_error_routine *handle_lost_error, - ETHER_SPECIFIC *ether_spec); -int ethernet_tx(int scc_number, void *buf, int length); - -#endif - diff --git a/arch/m68knommu/include/asm/m68360_pram.h b/arch/m68knommu/include/asm/m68360_pram.h deleted file mode 100644 index e6088bbce93..00000000000 --- a/arch/m68knommu/include/asm/m68360_pram.h +++ /dev/null @@ -1,431 +0,0 @@ -/*********************************** - * $Id: m68360_pram.h,v 1.1 2002/03/02 15:01:07 gerg Exp $ - *********************************** - * - *************************************** - * Definitions of the parameter area RAM. - * Note that different structures are overlaid - * at the same offsets for the different modes - * of operation. - *************************************** - */ - -#ifndef __PRAM_H -#define __PRAM_H - -/* Time slot assignment table */ -#define VALID_SLOT 0x8000 -#define WRAP_SLOT 0x4000 - -/***************************************************************** - Global Multichannel parameter RAM -*****************************************************************/ -struct global_multi_pram { - /* - * Global Multichannel parameter RAM - */ - unsigned long mcbase; /* Multichannel Base pointer */ - unsigned short qmcstate; /* Multichannel Controller state */ - unsigned short mrblr; /* Maximum Receive Buffer Length */ - unsigned short tx_s_ptr; /* TSTATx Pointer */ - unsigned short rxptr; /* Current Time slot entry in TSATRx */ - unsigned short grfthr; /* Global Receive frame threshold */ - unsigned short grfcnt; /* Global Receive Frame Count */ - unsigned long intbase; /* Multichannel Base address */ - unsigned long iintptr; /* Pointer to interrupt queue */ - unsigned short rx_s_ptr; /* TSTARx Pointer */ - - unsigned short txptr; /* Current Time slot entry in TSATTx */ - unsigned long c_mask32; /* CRC Constant (debb20e3) */ - unsigned short tsatrx[32]; /* Time Slot Assignment Table Rx */ - unsigned short tsattx[32]; /* Time Slot Assignment Table Tx */ - unsigned short c_mask16; /* CRC Constant (f0b8) */ -}; - -/***************************************************************** - Quicc32 HDLC parameter RAM -*****************************************************************/ -struct quicc32_pram { - - unsigned short tbase; /* Tx Buffer Descriptors Base Address */ - unsigned short chamr; /* Channel Mode Register */ - unsigned long tstate; /* Tx Internal State */ - unsigned long txintr; /* Tx Internal Data Pointer */ - unsigned short tbptr; /* Tx Buffer Descriptor Pointer */ - unsigned short txcntr; /* Tx Internal Byte Count */ - unsigned long tupack; /* (Tx Temp) */ - unsigned long zistate; /* Zero Insertion machine state */ - unsigned long tcrc; /* Temp Transmit CRC */ - unsigned short intmask; /* Channel's interrupt mask flags */ - unsigned short bdflags; - unsigned short rbase; /* Rx Buffer Descriptors Base Address */ - unsigned short mflr; /* Max Frame Length Register */ - unsigned long rstate; /* Rx Internal State */ - unsigned long rxintr; /* Rx Internal Data Pointer */ - unsigned short rbptr; /* Rx Buffer Descriptor Pointer */ - unsigned short rxbyc; /* Rx Internal Byte Count */ - unsigned long rpack; /* (Rx Temp) */ - unsigned long zdstate; /* Zero Deletion machine state */ - unsigned long rcrc; /* Temp Transmit CRC */ - unsigned short maxc; /* Max_length counter */ - unsigned short tmp_mb; /* Temp */ -}; - - -/***************************************************************** - HDLC parameter RAM -*****************************************************************/ - -struct hdlc_pram { - /* - * SCC parameter RAM - */ - unsigned short rbase; /* RX BD base address */ - unsigned short tbase; /* TX BD base address */ - unsigned char rfcr; /* Rx function code */ - unsigned char tfcr; /* Tx function code */ - unsigned short mrblr; /* Rx buffer length */ - unsigned long rstate; /* Rx internal state */ - unsigned long rptr; /* Rx internal data pointer */ - unsigned short rbptr; /* rb BD Pointer */ - unsigned short rcount; /* Rx internal byte count */ - unsigned long rtemp; /* Rx temp */ - unsigned long tstate; /* Tx internal state */ - unsigned long tptr; /* Tx internal data pointer */ - unsigned short tbptr; /* Tx BD pointer */ - unsigned short tcount; /* Tx byte count */ - unsigned long ttemp; /* Tx temp */ - unsigned long rcrc; /* temp receive CRC */ - unsigned long tcrc; /* temp transmit CRC */ - - /* - * HDLC specific parameter RAM - */ - unsigned char RESERVED1[4]; /* Reserved area */ - unsigned long c_mask; /* CRC constant */ - unsigned long c_pres; /* CRC preset */ - unsigned short disfc; /* discarded frame counter */ - unsigned short crcec; /* CRC error counter */ - unsigned short abtsc; /* abort sequence counter */ - unsigned short nmarc; /* nonmatching address rx cnt */ - unsigned short retrc; /* frame retransmission cnt */ - unsigned short mflr; /* maximum frame length reg */ - unsigned short max_cnt; /* maximum length counter */ - unsigned short rfthr; /* received frames threshold */ - unsigned short rfcnt; /* received frames count */ - unsigned short hmask; /* user defined frm addr mask */ - unsigned short haddr1; /* user defined frm address 1 */ - unsigned short haddr2; /* user defined frm address 2 */ - unsigned short haddr3; /* user defined frm address 3 */ - unsigned short haddr4; /* user defined frm address 4 */ - unsigned short tmp; /* temp */ - unsigned short tmp_mb; /* temp */ -}; - - - -/***************************************************************** - UART parameter RAM -*****************************************************************/ - -/* - * bits in uart control characters table - */ -#define CC_INVALID 0x8000 /* control character is valid */ -#define CC_REJ 0x4000 /* don't store char in buffer */ -#define CC_CHAR 0x00ff /* control character */ - -/* UART */ -struct uart_pram { - /* - * SCC parameter RAM - */ - unsigned short rbase; /* RX BD base address */ - unsigned short tbase; /* TX BD base address */ - unsigned char rfcr; /* Rx function code */ - unsigned char tfcr; /* Tx function code */ - unsigned short mrblr; /* Rx buffer length */ - unsigned long rstate; /* Rx internal state */ - unsigned long rptr; /* Rx internal data pointer */ - unsigned short rbptr; /* rb BD Pointer */ - unsigned short rcount; /* Rx internal byte count */ - unsigned long rx_temp; /* Rx temp */ - unsigned long tstate; /* Tx internal state */ - unsigned long tptr; /* Tx internal data pointer */ - unsigned short tbptr; /* Tx BD pointer */ - unsigned short tcount; /* Tx byte count */ - unsigned long ttemp; /* Tx temp */ - unsigned long rcrc; /* temp receive CRC */ - unsigned long tcrc; /* temp transmit CRC */ - - /* - * UART specific parameter RAM - */ - unsigned char RESERVED1[8]; /* Reserved area */ - unsigned short max_idl; /* maximum idle characters */ - unsigned short idlc; /* rx idle counter (internal) */ - unsigned short brkcr; /* break count register */ - - unsigned short parec; /* Rx parity error counter */ - unsigned short frmer; /* Rx framing error counter */ - unsigned short nosec; /* Rx noise counter */ - unsigned short brkec; /* Rx break character counter */ - unsigned short brkln; /* Reaceive break length */ - - unsigned short uaddr1; /* address character 1 */ - unsigned short uaddr2; /* address character 2 */ - unsigned short rtemp; /* temp storage */ - unsigned short toseq; /* Tx out of sequence char */ - unsigned short cc[8]; /* Rx control characters */ - unsigned short rccm; /* Rx control char mask */ - unsigned short rccr; /* Rx control char register */ - unsigned short rlbc; /* Receive last break char */ -}; - - - -/***************************************************************** - BISYNC parameter RAM -*****************************************************************/ - -struct bisync_pram { - /* - * SCC parameter RAM - */ - unsigned short rbase; /* RX BD base address */ - unsigned short tbase; /* TX BD base address */ - unsigned char rfcr; /* Rx function code */ - unsigned char tfcr; /* Tx function code */ - unsigned short mrblr; /* Rx buffer length */ - unsigned long rstate; /* Rx internal state */ - unsigned long rptr; /* Rx internal data pointer */ - unsigned short rbptr; /* rb BD Pointer */ - unsigned short rcount; /* Rx internal byte count */ - unsigned long rtemp; /* Rx temp */ - unsigned long tstate; /* Tx internal state */ - unsigned long tptr; /* Tx internal data pointer */ - unsigned short tbptr; /* Tx BD pointer */ - unsigned short tcount; /* Tx byte count */ - unsigned long ttemp; /* Tx temp */ - unsigned long rcrc; /* temp receive CRC */ - unsigned long tcrc; /* temp transmit CRC */ - - /* - * BISYNC specific parameter RAM - */ - unsigned char RESERVED1[4]; /* Reserved area */ - unsigned long crcc; /* CRC Constant Temp Value */ - unsigned short prcrc; /* Preset Receiver CRC-16/LRC */ - unsigned short ptcrc; /* Preset Transmitter CRC-16/LRC */ - unsigned short parec; /* Receive Parity Error Counter */ - unsigned short bsync; /* BISYNC SYNC Character */ - unsigned short bdle; /* BISYNC DLE Character */ - unsigned short cc[8]; /* Rx control characters */ - unsigned short rccm; /* Receive Control Character Mask */ -}; - -/***************************************************************** - IOM2 parameter RAM - (overlaid on tx bd[5] of SCC channel[2]) -*****************************************************************/ -struct iom2_pram { - unsigned short ci_data; /* ci data */ - unsigned short monitor_data; /* monitor data */ - unsigned short tstate; /* transmitter state */ - unsigned short rstate; /* receiver state */ -}; - -/***************************************************************** - SPI/SMC parameter RAM - (overlaid on tx bd[6,7] of SCC channel[2]) -*****************************************************************/ - -#define SPI_R 0x8000 /* Ready bit in BD */ - -struct spi_pram { - unsigned short rbase; /* Rx BD Base Address */ - unsigned short tbase; /* Tx BD Base Address */ - unsigned char rfcr; /* Rx function code */ - unsigned char tfcr; /* Tx function code */ - unsigned short mrblr; /* Rx buffer length */ - unsigned long rstate; /* Rx internal state */ - unsigned long rptr; /* Rx internal data pointer */ - unsigned short rbptr; /* rb BD Pointer */ - unsigned short rcount; /* Rx internal byte count */ - unsigned long rtemp; /* Rx temp */ - unsigned long tstate; /* Tx internal state */ - unsigned long tptr; /* Tx internal data pointer */ - unsigned short tbptr; /* Tx BD pointer */ - unsigned short tcount; /* Tx byte count */ - unsigned long ttemp; /* Tx temp */ -}; - -struct smc_uart_pram { - unsigned short rbase; /* Rx BD Base Address */ - unsigned short tbase; /* Tx BD Base Address */ - unsigned char rfcr; /* Rx function code */ - unsigned char tfcr; /* Tx function code */ - unsigned short mrblr; /* Rx buffer length */ - unsigned long rstate; /* Rx internal state */ - unsigned long rptr; /* Rx internal data pointer */ - unsigned short rbptr; /* rb BD Pointer */ - unsigned short rcount; /* Rx internal byte count */ - unsigned long rtemp; /* Rx temp */ - unsigned long tstate; /* Tx internal state */ - unsigned long tptr; /* Tx internal data pointer */ - unsigned short tbptr; /* Tx BD pointer */ - unsigned short tcount; /* Tx byte count */ - unsigned long ttemp; /* Tx temp */ - unsigned short max_idl; /* Maximum IDLE Characters */ - unsigned short idlc; /* Temporary IDLE Counter */ - unsigned short brkln; /* Last Rx Break Length */ - unsigned short brkec; /* Rx Break Condition Counter */ - unsigned short brkcr; /* Break Count Register (Tx) */ - unsigned short r_mask; /* Temporary bit mask */ -}; - -struct smc_trnsp_pram { - unsigned short rbase; /* rx BD Base Address */ - unsigned short tbase; /* Tx BD Base Address */ - unsigned char rfcr; /* Rx function code */ - unsigned char tfcr; /* Tx function code */ - unsigned short mrblr; /* Rx buffer length */ - unsigned long rstate; /* Rx internal state */ - unsigned long rptr; /* Rx internal data pointer */ - unsigned short rbptr; /* rb BD Pointer */ - unsigned short rcount; /* Rx internal byte count */ - unsigned long rtemp; /* Rx temp */ - unsigned long tstate; /* Tx internal state */ - unsigned long tptr; /* Tx internal data pointer */ - unsigned short tbptr; /* Tx BD pointer */ - unsigned short tcount; /* Tx byte count */ - unsigned long ttemp; /* Tx temp */ - unsigned short reserved[5]; /* Reserved */ -}; - -struct idma_pram { - unsigned short ibase; /* IDMA BD Base Address */ - unsigned short ibptr; /* IDMA buffer descriptor pointer */ - unsigned long istate; /* IDMA internal state */ - unsigned long itemp; /* IDMA temp */ -}; - -struct ethernet_pram { - /* - * SCC parameter RAM - */ - unsigned short rbase; /* RX BD base address */ - unsigned short tbase; /* TX BD base address */ - unsigned char rfcr; /* Rx function code */ - unsigned char tfcr; /* Tx function code */ - unsigned short mrblr; /* Rx buffer length */ - unsigned long rstate; /* Rx internal state */ - unsigned long rptr; /* Rx internal data pointer */ - unsigned short rbptr; /* rb BD Pointer */ - unsigned short rcount; /* Rx internal byte count */ - unsigned long rtemp; /* Rx temp */ - unsigned long tstate; /* Tx internal state */ - unsigned long tptr; /* Tx internal data pointer */ - unsigned short tbptr; /* Tx BD pointer */ - unsigned short tcount; /* Tx byte count */ - unsigned long ttemp; /* Tx temp */ - unsigned long rcrc; /* temp receive CRC */ - unsigned long tcrc; /* temp transmit CRC */ - - /* - * ETHERNET specific parameter RAM - */ - unsigned long c_pres; /* preset CRC */ - unsigned long c_mask; /* constant mask for CRC */ - unsigned long crcec; /* CRC error counter */ - unsigned long alec; /* alighnment error counter */ - unsigned long disfc; /* discard frame counter */ - unsigned short pads; /* short frame PAD characters */ - unsigned short ret_lim; /* retry limit threshold */ - unsigned short ret_cnt; /* retry limit counter */ - unsigned short mflr; /* maximum frame length reg */ - unsigned short minflr; /* minimum frame length reg */ - unsigned short maxd1; /* maximum DMA1 length reg */ - unsigned short maxd2; /* maximum DMA2 length reg */ - unsigned short maxd; /* rx max DMA */ - unsigned short dma_cnt; /* rx dma counter */ - unsigned short max_b; /* max bd byte count */ - unsigned short gaddr1; /* group address filter 1 */ - unsigned short gaddr2; /* group address filter 2 */ - unsigned short gaddr3; /* group address filter 3 */ - unsigned short gaddr4; /* group address filter 4 */ - unsigned long tbuf0_data0; /* save area 0 - current frm */ - unsigned long tbuf0_data1; /* save area 1 - current frm */ - unsigned long tbuf0_rba0; - unsigned long tbuf0_crc; - unsigned short tbuf0_bcnt; - union { - unsigned char b[6]; - struct { - unsigned short high; - unsigned short middl; - unsigned short low; - } w; - } paddr; - unsigned short p_per; /* persistence */ - unsigned short rfbd_ptr; /* rx first bd pointer */ - unsigned short tfbd_ptr; /* tx first bd pointer */ - unsigned short tlbd_ptr; /* tx last bd pointer */ - unsigned long tbuf1_data0; /* save area 0 - next frame */ - unsigned long tbuf1_data1; /* save area 1 - next frame */ - unsigned long tbuf1_rba0; - unsigned long tbuf1_crc; - unsigned short tbuf1_bcnt; - unsigned short tx_len; /* tx frame length counter */ - unsigned short iaddr1; /* individual address filter 1*/ - unsigned short iaddr2; /* individual address filter 2*/ - unsigned short iaddr3; /* individual address filter 3*/ - unsigned short iaddr4; /* individual address filter 4*/ - unsigned short boff_cnt; /* back-off counter */ - unsigned short taddr_h; /* temp address (MSB) */ - unsigned short taddr_m; /* temp address */ - unsigned short taddr_l; /* temp address (LSB) */ -}; - -struct transparent_pram { - /* - * SCC parameter RAM - */ - unsigned short rbase; /* RX BD base address */ - unsigned short tbase; /* TX BD base address */ - unsigned char rfcr; /* Rx function code */ - unsigned char tfcr; /* Tx function code */ - unsigned short mrblr; /* Rx buffer length */ - unsigned long rstate; /* Rx internal state */ - unsigned long rptr; /* Rx internal data pointer */ - unsigned short rbptr; /* rb BD Pointer */ - unsigned short rcount; /* Rx internal byte count */ - unsigned long rtemp; /* Rx temp */ - unsigned long tstate; /* Tx internal state */ - unsigned long tptr; /* Tx internal data pointer */ - unsigned short tbptr; /* Tx BD pointer */ - unsigned short tcount; /* Tx byte count */ - unsigned long ttemp; /* Tx temp */ - unsigned long rcrc; /* temp receive CRC */ - unsigned long tcrc; /* temp transmit CRC */ - - /* - * TRANSPARENT specific parameter RAM - */ - unsigned long crc_p; /* CRC Preset */ - unsigned long crc_c; /* CRC constant */ -}; - -struct timer_pram { - /* - * RISC timers parameter RAM - */ - unsigned short tm_base; /* RISC timer table base adr */ - unsigned short tm_ptr; /* RISC timer table pointer */ - unsigned short r_tmr; /* RISC timer mode register */ - unsigned short r_tmv; /* RISC timer valid register */ - unsigned long tm_cmd; /* RISC timer cmd register */ - unsigned long tm_cnt; /* RISC timer internal cnt */ -}; - -#endif diff --git a/arch/m68knommu/include/asm/m68360_quicc.h b/arch/m68knommu/include/asm/m68360_quicc.h deleted file mode 100644 index 6d40f4d18e1..00000000000 --- a/arch/m68knommu/include/asm/m68360_quicc.h +++ /dev/null @@ -1,362 +0,0 @@ -/*********************************** - * $Id: m68360_quicc.h,v 1.1 2002/03/02 15:01:07 gerg Exp $ - *********************************** - * - *************************************** - * Definitions of QUICC memory structures - *************************************** - */ - -#ifndef __M68360_QUICC_H -#define __M68360_QUICC_H - -/* - * include registers and - * parameter ram definitions files - */ -#include -#include - - - -/* Buffer Descriptors */ -typedef struct quicc_bd { - volatile unsigned short status; - volatile unsigned short length; - volatile unsigned char *buf; /* WARNING: This is only true if *char is 32 bits */ -} QUICC_BD; - - -#ifdef MOTOROLA_ORIGINAL -struct user_data { - /* BASE + 0x000: user data memory */ - volatile unsigned char udata_bd_ucode[0x400]; /*user data bd's Ucode*/ - volatile unsigned char udata_bd[0x200]; /*user data Ucode */ - volatile unsigned char ucode_ext[0x100]; /*Ucode Extention ram */ - volatile unsigned char RESERVED1[0x500]; /* Reserved area */ -}; -#else -struct user_data { - /* BASE + 0x000: user data memory */ - volatile unsigned char udata_bd_ucode[0x400]; /* user data, bds, Ucode*/ - volatile unsigned char udata_bd1[0x200]; /* user, bds */ - volatile unsigned char ucode_bd_scratch[0x100]; /* user, bds, ucode scratch */ - volatile unsigned char udata_bd2[0x100]; /* user, bds */ - volatile unsigned char RESERVED1[0x400]; /* Reserved area */ -}; -#endif - - -/* - * internal ram - */ -typedef struct quicc { - union { - struct quicc32_pram ch_pram_tbl[32]; /* 32*64(bytes) per channel */ - struct user_data u; - }ch_or_u; /* multipul or user space */ - - /* BASE + 0xc00: PARAMETER RAM */ - union { - struct scc_pram { - union { - struct hdlc_pram h; - struct uart_pram u; - struct bisync_pram b; - struct transparent_pram t; - unsigned char RESERVED66[0x70]; - } pscc; /* scc parameter area (protocol dependent) */ - union { - struct { - unsigned char RESERVED70[0x10]; - struct spi_pram spi; - unsigned char RESERVED72[0x8]; - struct timer_pram timer; - } timer_spi; - struct { - struct idma_pram idma; - unsigned char RESERVED67[0x4]; - union { - struct smc_uart_pram u; - struct smc_trnsp_pram t; - } psmc; - } idma_smc; - } pothers; - } scc; - struct ethernet_pram enet_scc; - struct global_multi_pram m; - unsigned char pr[0x100]; - } pram[4]; - - /* reserved */ - - /* BASE + 0x1000: INTERNAL REGISTERS */ - /* SIM */ - volatile unsigned long sim_mcr; /* module configuration reg */ - volatile unsigned short sim_simtr; /* module test register */ - volatile unsigned char RESERVED2[0x2]; /* Reserved area */ - volatile unsigned char sim_avr; /* auto vector reg */ - volatile unsigned char sim_rsr; /* reset status reg */ - volatile unsigned char RESERVED3[0x2]; /* Reserved area */ - volatile unsigned char sim_clkocr; /* CLCO control register */ - volatile unsigned char RESERVED62[0x3]; /* Reserved area */ - volatile unsigned short sim_pllcr; /* PLL control register */ - volatile unsigned char RESERVED63[0x2]; /* Reserved area */ - volatile unsigned short sim_cdvcr; /* Clock devider control register */ - volatile unsigned short sim_pepar; /* Port E pin assignment register */ - volatile unsigned char RESERVED64[0xa]; /* Reserved area */ - volatile unsigned char sim_sypcr; /* system protection control*/ - volatile unsigned char sim_swiv; /* software interrupt vector*/ - volatile unsigned char RESERVED6[0x2]; /* Reserved area */ - volatile unsigned short sim_picr; /* periodic interrupt control reg */ - volatile unsigned char RESERVED7[0x2]; /* Reserved area */ - volatile unsigned short sim_pitr; /* periodic interrupt timing reg */ - volatile unsigned char RESERVED8[0x3]; /* Reserved area */ - volatile unsigned char sim_swsr; /* software service */ - volatile unsigned long sim_bkar; /* breakpoint address register*/ - volatile unsigned long sim_bkcr; /* breakpoint control register*/ - volatile unsigned char RESERVED10[0x8]; /* Reserved area */ - /* MEMC */ - volatile unsigned long memc_gmr; /* Global memory register */ - volatile unsigned short memc_mstat; /* MEMC status register */ - volatile unsigned char RESERVED11[0xa]; /* Reserved area */ - volatile unsigned long memc_br0; /* base register 0 */ - volatile unsigned long memc_or0; /* option register 0 */ - volatile unsigned char RESERVED12[0x8]; /* Reserved area */ - volatile unsigned long memc_br1; /* base register 1 */ - volatile unsigned long memc_or1; /* option register 1 */ - volatile unsigned char RESERVED13[0x8]; /* Reserved area */ - volatile unsigned long memc_br2; /* base register 2 */ - volatile unsigned long memc_or2; /* option register 2 */ - volatile unsigned char RESERVED14[0x8]; /* Reserved area */ - volatile unsigned long memc_br3; /* base register 3 */ - volatile unsigned long memc_or3; /* option register 3 */ - volatile unsigned char RESERVED15[0x8]; /* Reserved area */ - volatile unsigned long memc_br4; /* base register 3 */ - volatile unsigned long memc_or4; /* option register 3 */ - volatile unsigned char RESERVED16[0x8]; /* Reserved area */ - volatile unsigned long memc_br5; /* base register 3 */ - volatile unsigned long memc_or5; /* option register 3 */ - volatile unsigned char RESERVED17[0x8]; /* Reserved area */ - volatile unsigned long memc_br6; /* base register 3 */ - volatile unsigned long memc_or6; /* option register 3 */ - volatile unsigned char RESERVED18[0x8]; /* Reserved area */ - volatile unsigned long memc_br7; /* base register 3 */ - volatile unsigned long memc_or7; /* option register 3 */ - volatile unsigned char RESERVED9[0x28]; /* Reserved area */ - /* TEST */ - volatile unsigned short test_tstmra; /* master shift a */ - volatile unsigned short test_tstmrb; /* master shift b */ - volatile unsigned short test_tstsc; /* shift count */ - volatile unsigned short test_tstrc; /* repetition counter */ - volatile unsigned short test_creg; /* control */ - volatile unsigned short test_dreg; /* destributed register */ - volatile unsigned char RESERVED58[0x404]; /* Reserved area */ - /* IDMA1 */ - volatile unsigned short idma_iccr; /* channel configuration reg*/ - volatile unsigned char RESERVED19[0x2]; /* Reserved area */ - volatile unsigned short idma1_cmr; /* dma mode reg */ - volatile unsigned char RESERVED68[0x2]; /* Reserved area */ - volatile unsigned long idma1_sapr; /* dma source addr ptr */ - volatile unsigned long idma1_dapr; /* dma destination addr ptr */ - volatile unsigned long idma1_bcr; /* dma byte count reg */ - volatile unsigned char idma1_fcr; /* function code reg */ - volatile unsigned char RESERVED20; /* Reserved area */ - volatile unsigned char idma1_cmar; /* channel mask reg */ - volatile unsigned char RESERVED21; /* Reserved area */ - volatile unsigned char idma1_csr; /* channel status reg */ - volatile unsigned char RESERVED22[0x3]; /* Reserved area */ - /* SDMA */ - volatile unsigned char sdma_sdsr; /* status reg */ - volatile unsigned char RESERVED23; /* Reserved area */ - volatile unsigned short sdma_sdcr; /* configuration reg */ - volatile unsigned long sdma_sdar; /* address reg */ - /* IDMA2 */ - volatile unsigned char RESERVED69[0x2]; /* Reserved area */ - volatile unsigned short idma2_cmr; /* dma mode reg */ - volatile unsigned long idma2_sapr; /* dma source addr ptr */ - volatile unsigned long idma2_dapr; /* dma destination addr ptr */ - volatile unsigned long idma2_bcr; /* dma byte count reg */ - volatile unsigned char idma2_fcr; /* function code reg */ - volatile unsigned char RESERVED24; /* Reserved area */ - volatile unsigned char idma2_cmar; /* channel mask reg */ - volatile unsigned char RESERVED25; /* Reserved area */ - volatile unsigned char idma2_csr; /* channel status reg */ - volatile unsigned char RESERVED26[0x7]; /* Reserved area */ - /* Interrupt Controller */ - volatile unsigned long intr_cicr; /* CP interrupt configuration reg*/ - volatile unsigned long intr_cipr; /* CP interrupt pending reg */ - volatile unsigned long intr_cimr; /* CP interrupt mask reg */ - volatile unsigned long intr_cisr; /* CP interrupt in service reg*/ - /* Parallel I/O */ - volatile unsigned short pio_padir; /* port A data direction reg */ - volatile unsigned short pio_papar; /* port A pin assignment reg */ - volatile unsigned short pio_paodr; /* port A open drain reg */ - volatile unsigned short pio_padat; /* port A data register */ - volatile unsigned char RESERVED28[0x8]; /* Reserved area */ - volatile unsigned short pio_pcdir; /* port C data direction reg*/ - volatile unsigned short pio_pcpar; /* port C pin assignment reg*/ - volatile unsigned short pio_pcso; /* port C special options */ - volatile unsigned short pio_pcdat; /* port C data register */ - volatile unsigned short pio_pcint; /* port C interrupt cntrl reg */ - volatile unsigned char RESERVED29[0x16]; /* Reserved area */ - /* Timer */ - volatile unsigned short timer_tgcr; /* timer global configuration reg */ - volatile unsigned char RESERVED30[0xe]; /* Reserved area */ - volatile unsigned short timer_tmr1; /* timer 1 mode reg */ - volatile unsigned short timer_tmr2; /* timer 2 mode reg */ - volatile unsigned short timer_trr1; /* timer 1 referance reg */ - volatile unsigned short timer_trr2; /* timer 2 referance reg */ - volatile unsigned short timer_tcr1; /* timer 1 capture reg */ - volatile unsigned short timer_tcr2; /* timer 2 capture reg */ - volatile unsigned short timer_tcn1; /* timer 1 counter reg */ - volatile unsigned short timer_tcn2; /* timer 2 counter reg */ - volatile unsigned short timer_tmr3; /* timer 3 mode reg */ - volatile unsigned short timer_tmr4; /* timer 4 mode reg */ - volatile unsigned short timer_trr3; /* timer 3 referance reg */ - volatile unsigned short timer_trr4; /* timer 4 referance reg */ - volatile unsigned short timer_tcr3; /* timer 3 capture reg */ - volatile unsigned short timer_tcr4; /* timer 4 capture reg */ - volatile unsigned short timer_tcn3; /* timer 3 counter reg */ - volatile unsigned short timer_tcn4; /* timer 4 counter reg */ - volatile unsigned short timer_ter1; /* timer 1 event reg */ - volatile unsigned short timer_ter2; /* timer 2 event reg */ - volatile unsigned short timer_ter3; /* timer 3 event reg */ - volatile unsigned short timer_ter4; /* timer 4 event reg */ - volatile unsigned char RESERVED34[0x8]; /* Reserved area */ - /* CP */ - volatile unsigned short cp_cr; /* command register */ - volatile unsigned char RESERVED35[0x2]; /* Reserved area */ - volatile unsigned short cp_rccr; /* main configuration reg */ - volatile unsigned char RESERVED37; /* Reserved area */ - volatile unsigned char cp_rmds; /* development support status reg */ - volatile unsigned long cp_rmdr; /* development support control reg */ - volatile unsigned short cp_rctr1; /* ram break register 1 */ - volatile unsigned short cp_rctr2; /* ram break register 2 */ - volatile unsigned short cp_rctr3; /* ram break register 3 */ - volatile unsigned short cp_rctr4; /* ram break register 4 */ - volatile unsigned char RESERVED59[0x2]; /* Reserved area */ - volatile unsigned short cp_rter; /* RISC timers event reg */ - volatile unsigned char RESERVED38[0x2]; /* Reserved area */ - volatile unsigned short cp_rtmr; /* RISC timers mask reg */ - volatile unsigned char RESERVED39[0x14]; /* Reserved area */ - /* BRG */ - union { - volatile unsigned long l; - struct { - volatile unsigned short BRGC_RESERV:14; - volatile unsigned short rst:1; - volatile unsigned short en:1; - volatile unsigned short extc:2; - volatile unsigned short atb:1; - volatile unsigned short cd:12; - volatile unsigned short div16:1; - } b; - } brgc[4]; /* BRG1-BRG4 configuration regs*/ - /* SCC registers */ - struct scc_regs { - union { - struct { - /* Low word. */ - volatile unsigned short GSMR_RESERV2:1; - volatile unsigned short edge:2; - volatile unsigned short tci:1; - volatile unsigned short tsnc:2; - volatile unsigned short rinv:1; - volatile unsigned short tinv:1; - volatile unsigned short tpl:3; - volatile unsigned short tpp:2; - volatile unsigned short tend:1; - volatile unsigned short tdcr:2; - volatile unsigned short rdcr:2; - volatile unsigned short renc:3; - volatile unsigned short tenc:3; - volatile unsigned short diag:2; - volatile unsigned short enr:1; - volatile unsigned short ent:1; - volatile unsigned short mode:4; - /* High word. */ - volatile unsigned short GSMR_RESERV1:14; - volatile unsigned short pri:1; - volatile unsigned short gde:1; - volatile unsigned short tcrc:2; - volatile unsigned short revd:1; - volatile unsigned short trx:1; - volatile unsigned short ttx:1; - volatile unsigned short cdp:1; - volatile unsigned short ctsp:1; - volatile unsigned short cds:1; - volatile unsigned short ctss:1; - volatile unsigned short tfl:1; - volatile unsigned short rfw:1; - volatile unsigned short txsy:1; - volatile unsigned short synl:2; - volatile unsigned short rtsm:1; - volatile unsigned short rsyn:1; - } b; - struct { - volatile unsigned long low; - volatile unsigned long high; - } w; - } scc_gsmr; /* SCC general mode reg */ - volatile unsigned short scc_psmr; /* protocol specific mode reg */ - volatile unsigned char RESERVED42[0x2]; /* Reserved area */ - volatile unsigned short scc_todr; /* SCC transmit on demand */ - volatile unsigned short scc_dsr; /* SCC data sync reg */ - volatile unsigned short scc_scce; /* SCC event reg */ - volatile unsigned char RESERVED43[0x2];/* Reserved area */ - volatile unsigned short scc_sccm; /* SCC mask reg */ - volatile unsigned char RESERVED44[0x1];/* Reserved area */ - volatile unsigned char scc_sccs; /* SCC status reg */ - volatile unsigned char RESERVED45[0x8]; /* Reserved area */ - } scc_regs[4]; - /* SMC */ - struct smc_regs { - volatile unsigned char RESERVED46[0x2]; /* Reserved area */ - volatile unsigned short smc_smcmr; /* SMC mode reg */ - volatile unsigned char RESERVED60[0x2]; /* Reserved area */ - volatile unsigned char smc_smce; /* SMC event reg */ - volatile unsigned char RESERVED47[0x3]; /* Reserved area */ - volatile unsigned char smc_smcm; /* SMC mask reg */ - volatile unsigned char RESERVED48[0x5]; /* Reserved area */ - } smc_regs[2]; - /* SPI */ - volatile unsigned short spi_spmode; /* SPI mode reg */ - volatile unsigned char RESERVED51[0x4]; /* Reserved area */ - volatile unsigned char spi_spie; /* SPI event reg */ - volatile unsigned char RESERVED52[0x3]; /* Reserved area */ - volatile unsigned char spi_spim; /* SPI mask reg */ - volatile unsigned char RESERVED53[0x2]; /* Reserved area */ - volatile unsigned char spi_spcom; /* SPI command reg */ - volatile unsigned char RESERVED54[0x4]; /* Reserved area */ - /* PIP */ - volatile unsigned short pip_pipc; /* pip configuration reg */ - volatile unsigned char RESERVED65[0x2]; /* Reserved area */ - volatile unsigned short pip_ptpr; /* pip timing parameters reg */ - volatile unsigned long pip_pbdir; /* port b data direction reg */ - volatile unsigned long pip_pbpar; /* port b pin assignment reg */ - volatile unsigned long pip_pbodr; /* port b open drain reg */ - volatile unsigned long pip_pbdat; /* port b data reg */ - volatile unsigned char RESERVED71[0x18]; /* Reserved area */ - /* Serial Interface */ - volatile unsigned long si_simode; /* SI mode register */ - volatile unsigned char si_sigmr; /* SI global mode register */ - volatile unsigned char RESERVED55; /* Reserved area */ - volatile unsigned char si_sistr; /* SI status register */ - volatile unsigned char si_sicmr; /* SI command register */ - volatile unsigned char RESERVED56[0x4]; /* Reserved area */ - volatile unsigned long si_sicr; /* SI clock routing */ - volatile unsigned long si_sirp; /* SI ram pointers */ - volatile unsigned char RESERVED57[0xc]; /* Reserved area */ - volatile unsigned short si_siram[0x80]; /* SI routing ram */ -} QUICC; - -#endif - -/* - * Local variables: - * c-indent-level: 4 - * c-basic-offset: 4 - * tab-width: 4 - * End: - */ diff --git a/arch/m68knommu/include/asm/m68360_regs.h b/arch/m68knommu/include/asm/m68360_regs.h deleted file mode 100644 index d57217ca4f2..00000000000 --- a/arch/m68knommu/include/asm/m68360_regs.h +++ /dev/null @@ -1,408 +0,0 @@ -/*********************************** - * $Id: m68360_regs.h,v 1.2 2002/10/26 15:03:55 gerg Exp $ - *********************************** - * - *************************************** - * Definitions of the QUICC registers - *************************************** - */ - -#ifndef __REGISTERS_H -#define __REGISTERS_H - -#define CLEAR_BIT(x, bit) x =bit - -/***************************************************************** - Command Register -*****************************************************************/ - -/* bit fields within command register */ -#define SOFTWARE_RESET 0x8000 -#define CMD_OPCODE 0x0f00 -#define CMD_CHANNEL 0x00f0 -#define CMD_FLAG 0x0001 - -/* general command opcodes */ -#define INIT_RXTX_PARAMS 0x0000 -#define INIT_RX_PARAMS 0x0100 -#define INIT_TX_PARAMS 0x0200 -#define ENTER_HUNT_MODE 0x0300 -#define STOP_TX 0x0400 -#define GR_STOP_TX 0x0500 -#define RESTART_TX 0x0600 -#define CLOSE_RX_BD 0x0700 -#define SET_ENET_GROUP 0x0800 -#define RESET_ENET_GROUP 0x0900 - -/* quicc32 CP commands */ -#define STOP_TX_32 0x0e00 /*add chan# bits 2-6 */ -#define ENTER_HUNT_MODE_32 0x1e00 - -/* quicc32 mask/event SCC register */ -#define GOV 0x01 -#define GUN 0x02 -#define GINT 0x04 -#define IQOV 0x08 - - -/* Timer commands */ -#define SET_TIMER 0x0800 - -/* Multi channel Interrupt structure */ -#define INTR_VALID 0x8000 /* Valid interrupt entry */ -#define INTR_WRAP 0x4000 /* Wrap bit in the interrupt entry table */ -#define INTR_CH_NU 0x07c0 /* Channel Num in interrupt table */ -#define INTR_MASK_BITS 0x383f - -/* - * General SCC mode register (GSMR) - */ - -#define MODE_HDLC 0x0 -#define MODE_APPLE_TALK 0x2 -#define MODE_SS7 0x3 -#define MODE_UART 0x4 -#define MODE_PROFIBUS 0x5 -#define MODE_ASYNC_HDLC 0x6 -#define MODE_V14 0x7 -#define MODE_BISYNC 0x8 -#define MODE_DDCMP 0x9 -#define MODE_MULTI_CHANNEL 0xa -#define MODE_ETHERNET 0xc - -#define DIAG_NORMAL 0x0 -#define DIAG_LOCAL_LPB 0x1 -#define DIAG_AUTO_ECHO 0x2 -#define DIAG_LBP_ECHO 0x3 - -/* For RENC and TENC fields in GSMR */ -#define ENC_NRZ 0x0 -#define ENC_NRZI 0x1 -#define ENC_FM0 0x2 -#define ENC_MANCH 0x4 -#define ENC_DIFF_MANC 0x6 - -/* For TDCR and RDCR fields in GSMR */ -#define CLOCK_RATE_1 0x0 -#define CLOCK_RATE_8 0x1 -#define CLOCK_RATE_16 0x2 -#define CLOCK_RATE_32 0x3 - -#define TPP_00 0x0 -#define TPP_10 0x1 -#define TPP_01 0x2 -#define TPP_11 0x3 - -#define TPL_NO 0x0 -#define TPL_8 0x1 -#define TPL_16 0x2 -#define TPL_32 0x3 -#define TPL_48 0x4 -#define TPL_64 0x5 -#define TPL_128 0x6 - -#define TSNC_INFINITE 0x0 -#define TSNC_14_65 0x1 -#define TSNC_4_15 0x2 -#define TSNC_3_1 0x3 - -#define EDGE_BOTH 0x0 -#define EDGE_POS 0x1 -#define EDGE_NEG 0x2 -#define EDGE_NO 0x3 - -#define SYNL_NO 0x0 -#define SYNL_4 0x1 -#define SYNL_8 0x2 -#define SYNL_16 0x3 - -#define TCRC_CCITT16 0x0 -#define TCRC_CRC16 0x1 -#define TCRC_CCITT32 0x2 - - -/***************************************************************** - TODR (Transmit on demand) Register -*****************************************************************/ -#define TODR_TOD 0x8000 /* Transmit on demand */ - - -/***************************************************************** - CICR register settings -*****************************************************************/ - -/* note that relative irq priorities of the SCCs can be reordered - * if desired - see p. 7-377 of the MC68360UM */ -#define CICR_SCA_SCC1 ((uint)0x00000000) /* SCC1 @ SCCa */ -#define CICR_SCB_SCC2 ((uint)0x00040000) /* SCC2 @ SCCb */ -#define CICR_SCC_SCC3 ((uint)0x00200000) /* SCC3 @ SCCc */ -#define CICR_SCD_SCC4 ((uint)0x00c00000) /* SCC4 @ SCCd */ - -#define CICR_IRL_MASK ((uint)0x0000e000) /* Core interrupt */ -#define CICR_HP_MASK ((uint)0x00001f00) /* Hi-pri int. */ -#define CICR_VBA_MASK ((uint)0x000000e0) /* Vector Base Address */ -#define CICR_SPS ((uint)0x00000001) /* SCC Spread */ - - -/***************************************************************** - Interrupt bits for CIPR and CIMR (MC68360UM p. 7-379) -*****************************************************************/ - -#define INTR_PIO_PC0 0x80000000 /* parallel I/O C bit 0 */ -#define INTR_SCC1 0x40000000 /* SCC port 1 */ -#define INTR_SCC2 0x20000000 /* SCC port 2 */ -#define INTR_SCC3 0x10000000 /* SCC port 3 */ -#define INTR_SCC4 0x08000000 /* SCC port 4 */ -#define INTR_PIO_PC1 0x04000000 /* parallel i/o C bit 1 */ -#define INTR_TIMER1 0x02000000 /* timer 1 */ -#define INTR_PIO_PC2 0x01000000 /* parallel i/o C bit 2 */ -#define INTR_PIO_PC3 0x00800000 /* parallel i/o C bit 3 */ -#define INTR_SDMA_BERR 0x00400000 /* SDMA channel bus error */ -#define INTR_DMA1 0x00200000 /* idma 1 */ -#define INTR_DMA2 0x00100000 /* idma 2 */ -#define INTR_TIMER2 0x00040000 /* timer 2 */ -#define INTR_CP_TIMER 0x00020000 /* CP timer */ -#define INTR_PIP_STATUS 0x00010000 /* PIP status */ -#define INTR_PIO_PC4 0x00008000 /* parallel i/o C bit 4 */ -#define INTR_PIO_PC5 0x00004000 /* parallel i/o C bit 5 */ -#define INTR_TIMER3 0x00001000 /* timer 3 */ -#define INTR_PIO_PC6 0x00000800 /* parallel i/o C bit 6 */ -#define INTR_PIO_PC7 0x00000400 /* parallel i/o C bit 7 */ -#define INTR_PIO_PC8 0x00000200 /* parallel i/o C bit 8 */ -#define INTR_TIMER4 0x00000080 /* timer 4 */ -#define INTR_PIO_PC9 0x00000040 /* parallel i/o C bit 9 */ -#define INTR_SCP 0x00000020 /* SCP */ -#define INTR_SMC1 0x00000010 /* SMC 1 */ -#define INTR_SMC2 0x00000008 /* SMC 2 */ -#define INTR_PIO_PC10 0x00000004 /* parallel i/o C bit 10 */ -#define INTR_PIO_PC11 0x00000002 /* parallel i/o C bit 11 */ -#define INTR_ERR 0x00000001 /* error */ - - -/***************************************************************** - CPM Interrupt vector encodings (MC68360UM p. 7-376) -*****************************************************************/ - -#define CPMVEC_NR 32 -#define CPMVEC_PIO_PC0 0x1f -#define CPMVEC_SCC1 0x1e -#define CPMVEC_SCC2 0x1d -#define CPMVEC_SCC3 0x1c -#define CPMVEC_SCC4 0x1b -#define CPMVEC_PIO_PC1 0x1a -#define CPMVEC_TIMER1 0x19 -#define CPMVEC_PIO_PC2 0x18 -#define CPMVEC_PIO_PC3 0x17 -#define CPMVEC_SDMA_CB_ERR 0x16 -#define CPMVEC_IDMA1 0x15 -#define CPMVEC_IDMA2 0x14 -#define CPMVEC_RESERVED3 0x13 -#define CPMVEC_TIMER2 0x12 -#define CPMVEC_RISCTIMER 0x11 -#define CPMVEC_RESERVED2 0x10 -#define CPMVEC_PIO_PC4 0x0f -#define CPMVEC_PIO_PC5 0x0e -#define CPMVEC_TIMER3 0x0c -#define CPMVEC_PIO_PC6 0x0b -#define CPMVEC_PIO_PC7 0x0a -#define CPMVEC_PIO_PC8 0x09 -#define CPMVEC_RESERVED1 0x08 -#define CPMVEC_TIMER4 0x07 -#define CPMVEC_PIO_PC9 0x06 -#define CPMVEC_SPI 0x05 -#define CPMVEC_SMC1 0x04 -#define CPMVEC_SMC2 0x03 -#define CPMVEC_PIO_PC10 0x02 -#define CPMVEC_PIO_PC11 0x01 -#define CPMVEC_ERROR 0x00 - -/* #define CPMVEC_PIO_PC0 ((ushort)0x1f) */ -/* #define CPMVEC_SCC1 ((ushort)0x1e) */ -/* #define CPMVEC_SCC2 ((ushort)0x1d) */ -/* #define CPMVEC_SCC3 ((ushort)0x1c) */ -/* #define CPMVEC_SCC4 ((ushort)0x1b) */ -/* #define CPMVEC_PIO_PC1 ((ushort)0x1a) */ -/* #define CPMVEC_TIMER1 ((ushort)0x19) */ -/* #define CPMVEC_PIO_PC2 ((ushort)0x18) */ -/* #define CPMVEC_PIO_PC3 ((ushort)0x17) */ -/* #define CPMVEC_SDMA_CB_ERR ((ushort)0x16) */ -/* #define CPMVEC_IDMA1 ((ushort)0x15) */ -/* #define CPMVEC_IDMA2 ((ushort)0x14) */ -/* #define CPMVEC_RESERVED3 ((ushort)0x13) */ -/* #define CPMVEC_TIMER2 ((ushort)0x12) */ -/* #define CPMVEC_RISCTIMER ((ushort)0x11) */ -/* #define CPMVEC_RESERVED2 ((ushort)0x10) */ -/* #define CPMVEC_PIO_PC4 ((ushort)0x0f) */ -/* #define CPMVEC_PIO_PC5 ((ushort)0x0e) */ -/* #define CPMVEC_TIMER3 ((ushort)0x0c) */ -/* #define CPMVEC_PIO_PC6 ((ushort)0x0b) */ -/* #define CPMVEC_PIO_PC7 ((ushort)0x0a) */ -/* #define CPMVEC_PIO_PC8 ((ushort)0x09) */ -/* #define CPMVEC_RESERVED1 ((ushort)0x08) */ -/* #define CPMVEC_TIMER4 ((ushort)0x07) */ -/* #define CPMVEC_PIO_PC9 ((ushort)0x06) */ -/* #define CPMVEC_SPI ((ushort)0x05) */ -/* #define CPMVEC_SMC1 ((ushort)0x04) */ -/* #define CPMVEC_SMC2 ((ushort)0x03) */ -/* #define CPMVEC_PIO_PC10 ((ushort)0x02) */ -/* #define CPMVEC_PIO_PC11 ((ushort)0x01) */ -/* #define CPMVEC_ERROR ((ushort)0x00) */ - - -/***************************************************************** - * PIO control registers - *****************************************************************/ - -/* Port A - See 360UM p. 7-358 - * - * Note that most of these pins have alternate functions - */ - - -/* The macros are nice, but there are all sorts of references to 1-indexed - * facilities on the 68360... */ -/* #define PA_RXD(n) ((ushort)(0x01<<(2*n))) */ -/* #define PA_TXD(n) ((ushort)(0x02<<(2*n))) */ - -#define PA_RXD1 ((ushort)0x0001) -#define PA_TXD1 ((ushort)0x0002) -#define PA_RXD2 ((ushort)0x0004) -#define PA_TXD2 ((ushort)0x0008) -#define PA_RXD3 ((ushort)0x0010) -#define PA_TXD3 ((ushort)0x0020) -#define PA_RXD4 ((ushort)0x0040) -#define PA_TXD4 ((ushort)0x0080) - -#define PA_CLK1 ((ushort)0x0100) -#define PA_CLK2 ((ushort)0x0200) -#define PA_CLK3 ((ushort)0x0400) -#define PA_CLK4 ((ushort)0x0800) -#define PA_CLK5 ((ushort)0x1000) -#define PA_CLK6 ((ushort)0x2000) -#define PA_CLK7 ((ushort)0x4000) -#define PA_CLK8 ((ushort)0x8000) - - -/* Port B - See 360UM p. 7-362 - */ - - -/* Port C - See 360UM p. 7-365 - */ - -#define PC_RTS1 ((ushort)0x0001) -#define PC_RTS2 ((ushort)0x0002) -#define PC__RTS3 ((ushort)0x0004) /* !RTS3 */ -#define PC__RTS4 ((ushort)0x0008) /* !RTS4 */ - -#define PC_CTS1 ((ushort)0x0010) -#define PC_CD1 ((ushort)0x0020) -#define PC_CTS2 ((ushort)0x0040) -#define PC_CD2 ((ushort)0x0080) -#define PC_CTS3 ((ushort)0x0100) -#define PC_CD3 ((ushort)0x0200) -#define PC_CTS4 ((ushort)0x0400) -#define PC_CD4 ((ushort)0x0800) - - - -/***************************************************************** - chip select option register -*****************************************************************/ -#define DTACK 0xe000 -#define ADR_MASK 0x1ffc -#define RDWR_MASK 0x0002 -#define FC_MASK 0x0001 - -/***************************************************************** - tbase and rbase registers -*****************************************************************/ -#define TBD_ADDR(quicc,pram) ((struct quicc_bd *) \ - (quicc->ch_or_u.u.udata_bd_ucode + pram->tbase)) -#define RBD_ADDR(quicc,pram) ((struct quicc_bd *) \ - (quicc->ch_or_u.u.udata_bd_ucode + pram->rbase)) -#define TBD_CUR_ADDR(quicc,pram) ((struct quicc_bd *) \ - (quicc->ch_or_u.u.udata_bd_ucode + pram->tbptr)) -#define RBD_CUR_ADDR(quicc,pram) ((struct quicc_bd *) \ - (quicc->ch_or_u.u.udata_bd_ucode + pram->rbptr)) -#define TBD_SET_CUR_ADDR(bd,quicc,pram) pram->tbptr = \ - ((unsigned short)((char *)(bd) - (char *)(quicc->ch_or_u.u.udata_bd_ucode))) -#define RBD_SET_CUR_ADDR(bd,quicc,pram) pram->rbptr = \ - ((unsigned short)((char *)(bd) - (char *)(quicc->ch_or_u.u.udata_bd_ucode))) -#define INCREASE_TBD(bd,quicc,pram) { \ - if((bd)->status & T_W) \ - (bd) = TBD_ADDR(quicc,pram); \ - else \ - (bd)++; \ -} -#define DECREASE_TBD(bd,quicc,pram) { \ - if ((bd) == TBD_ADDR(quicc, pram)) \ - while (!((bd)->status & T_W)) \ - (bd)++; \ - else \ - (bd)--; \ -} -#define INCREASE_RBD(bd,quicc,pram) { \ - if((bd)->status & R_W) \ - (bd) = RBD_ADDR(quicc,pram); \ - else \ - (bd)++; \ -} -#define DECREASE_RBD(bd,quicc,pram) { \ - if ((bd) == RBD_ADDR(quicc, pram)) \ - while (!((bd)->status & T_W)) \ - (bd)++; \ - else \ - (bd)--; \ -} - -/***************************************************************** - Macros for Multi channel -*****************************************************************/ -#define QMC_BASE(quicc,page) (struct global_multi_pram *)(&quicc->pram[page]) -#define MCBASE(quicc,page) (unsigned long)(quicc->pram[page].m.mcbase) -#define CHANNEL_PRAM_BASE(quicc,channel) ((struct quicc32_pram *) \ - (&(quicc->ch_or_u.ch_pram_tbl[channel]))) -#define TBD_32_ADDR(quicc,page,channel) ((struct quicc_bd *) \ - (MCBASE(quicc,page) + (CHANNEL_PRAM_BASE(quicc,channel)->tbase))) -#define RBD_32_ADDR(quicc,page,channel) ((struct quicc_bd *) \ - (MCBASE(quicc,page) + (CHANNEL_PRAM_BASE(quicc,channel)->rbase))) -#define TBD_32_CUR_ADDR(quicc,page,channel) ((struct quicc_bd *) \ - (MCBASE(quicc,page) + (CHANNEL_PRAM_BASE(quicc,channel)->tbptr))) -#define RBD_32_CUR_ADDR(quicc,page,channel) ((struct quicc_bd *) \ - (MCBASE(quicc,page) + (CHANNEL_PRAM_BASE(quicc,channel)->rbptr))) -#define TBD_32_SET_CUR_ADDR(bd,quicc,page,channel) \ - CHANNEL_PRAM_BASE(quicc,channel)->tbptr = \ - ((unsigned short)((char *)(bd) - (char *)(MCBASE(quicc,page)))) -#define RBD_32_SET_CUR_ADDR(bd,quicc,page,channel) \ - CHANNEL_PRAM_BASE(quicc,channel)->rbptr = \ - ((unsigned short)((char *)(bd) - (char *)(MCBASE(quicc,page)))) - -#define INCREASE_TBD_32(bd,quicc,page,channel) { \ - if((bd)->status & T_W) \ - (bd) = TBD_32_ADDR(quicc,page,channel); \ - else \ - (bd)++; \ -} -#define DECREASE_TBD_32(bd,quicc,page,channel) { \ - if ((bd) == TBD_32_ADDR(quicc, page,channel)) \ - while (!((bd)->status & T_W)) \ - (bd)++; \ - else \ - (bd)--; \ -} -#define INCREASE_RBD_32(bd,quicc,page,channel) { \ - if((bd)->status & R_W) \ - (bd) = RBD_32_ADDR(quicc,page,channel); \ - else \ - (bd)++; \ -} -#define DECREASE_RBD_32(bd,quicc,page,channel) { \ - if ((bd) == RBD_32_ADDR(quicc, page,channel)) \ - while (!((bd)->status & T_W)) \ - (bd)++; \ - else \ - (bd)--; \ -} - -#endif diff --git a/arch/m68knommu/include/asm/machdep.h b/arch/m68knommu/include/asm/machdep.h deleted file mode 100644 index de9f47a51cc..00000000000 --- a/arch/m68knommu/include/asm/machdep.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _M68KNOMMU_MACHDEP_H -#define _M68KNOMMU_MACHDEP_H - -#include - -/* Hardware clock functions */ -extern void hw_timer_init(void); -extern unsigned long hw_timer_offset(void); - -extern irqreturn_t arch_timer_interrupt(int irq, void *dummy); - -/* Machine dependent time handling */ -extern void (*mach_gettod)(int *year, int *mon, int *day, int *hour, - int *min, int *sec); -extern int (*mach_set_clock_mmss)(unsigned long); - -/* machine dependent power off functions */ -extern void (*mach_reset)( void ); -extern void (*mach_halt)( void ); -extern void (*mach_power_off)( void ); - -extern void config_BSP(char *command, int len); - -extern void do_IRQ(int irq, struct pt_regs *fp); - -#endif /* _M68KNOMMU_MACHDEP_H */ diff --git a/arch/m68knommu/include/asm/math-emu.h b/arch/m68knommu/include/asm/math-emu.h deleted file mode 100644 index 7e7090517b7..00000000000 --- a/arch/m68knommu/include/asm/math-emu.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/mc146818rtc.h b/arch/m68knommu/include/asm/mc146818rtc.h deleted file mode 100644 index 907a0481a14..00000000000 --- a/arch/m68knommu/include/asm/mc146818rtc.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Machine dependent access functions for RTC registers. - */ -#ifndef _M68KNOMMU_MC146818RTC_H -#define _M68KNOMMU_MC146818RTC_H - -/* empty include file to satisfy the include in genrtc.c/ide-geometry.c */ - -#endif /* _M68KNOMMU_MC146818RTC_H */ diff --git a/arch/m68knommu/include/asm/mcfcache.h b/arch/m68knommu/include/asm/mcfcache.h deleted file mode 100644 index c042634fada..00000000000 --- a/arch/m68knommu/include/asm/mcfcache.h +++ /dev/null @@ -1,150 +0,0 @@ -/****************************************************************************/ - -/* - * mcfcache.h -- ColdFire CPU cache support code - * - * (C) Copyright 2004, Greg Ungerer - */ - -/****************************************************************************/ -#ifndef __M68KNOMMU_MCFCACHE_H -#define __M68KNOMMU_MCFCACHE_H -/****************************************************************************/ - - -/* - * The different ColdFire families have different cache arrangments. - * Everything from a small instruction only cache, to configurable - * data and/or instruction cache, to unified instruction/data, to - * harvard style separate instruction and data caches. - */ - -#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || defined(CONFIG_M5272) -/* - * Simple version 2 core cache. These have instruction cache only, - * we just need to invalidate it and enable it. - */ -.macro CACHE_ENABLE - movel #0x01000000,%d0 /* invalidate cache cmd */ - movec %d0,%CACR /* do invalidate cache */ - movel #0x80000100,%d0 /* setup cache mask */ - movec %d0,%CACR /* enable cache */ -.endm -#endif /* CONFIG_M5206 || CONFIG_M5206e || CONFIG_M5272 */ - -#if defined(CONFIG_M523x) || defined(CONFIG_M527x) -/* - * New version 2 cores have a configurable split cache arrangement. - * For now I am just enabling instruction cache - but ultimately I - * think a split instruction/data cache would be better. - */ -.macro CACHE_ENABLE - movel #0x01400000,%d0 - movec %d0,%CACR /* invalidate cache */ - nop - movel #0x0000c000,%d0 /* set SDRAM cached only */ - movec %d0,%ACR0 - movel #0x00000000,%d0 /* no other regions cached */ - movec %d0,%ACR1 - movel #0x80400100,%d0 /* configure cache */ - movec %d0,%CACR /* enable cache */ - nop -.endm -#endif /* CONFIG_M523x || CONFIG_M527x */ - -#if defined(CONFIG_M528x) -.macro CACHE_ENABLE - nop - movel #0x01000000, %d0 - movec %d0, %CACR /* Invalidate cache */ - nop - movel #0x0000c020, %d0 /* Set SDRAM cached only */ - movec %d0, %ACR0 - movel #0x00000000, %d0 /* No other regions cached */ - movec %d0, %ACR1 - movel #0x80000200, %d0 /* Setup cache mask */ - movec %d0, %CACR /* Enable cache */ - nop -.endm -#endif /* CONFIG_M528x */ - -#if defined(CONFIG_M5249) || defined(CONFIG_M5307) -/* - * The version 3 core cache. Oddly enough the version 2 core 5249 - * has the same SDRAM and cache setup as the version 3 cores. - * This is a single unified instruction/data cache. - */ -.macro CACHE_ENABLE - movel #0x01000000,%d0 /* invalidate whole cache */ - movec %d0,%CACR - nop -#if defined(DEBUGGER_COMPATIBLE_CACHE) || defined(CONFIG_SECUREEDGEMP3) - movel #0x0000c000,%d0 /* set SDRAM cached (write-thru) */ -#else - movel #0x0000c020,%d0 /* set SDRAM cached (copyback) */ -#endif - movec %d0,%ACR0 - movel #0x00000000,%d0 /* no other regions cached */ - movec %d0,%ACR1 - movel #0xa0000200,%d0 /* enable cache */ - movec %d0,%CACR - nop -.endm -#endif /* CONFIG_M5249 || CONFIG_M5307 */ - -#if defined(CONFIG_M532x) -.macro CACHE_ENABLE - movel #0x01000000,%d0 /* invalidate cache cmd */ - movec %d0,%CACR /* do invalidate cache */ - nop - movel #0x4001C000,%d0 /* set SDRAM cached (write-thru) */ - movec %d0,%ACR0 - movel #0x00000000,%d0 /* no other regions cached */ - movec %d0,%ACR1 - movel #0x80000200,%d0 /* setup cache mask */ - movec %d0,%CACR /* enable cache */ - nop -.endm -#endif /* CONFIG_M532x */ - -#if defined(CONFIG_M5407) -/* - * Version 4 cores have a true harvard style separate instruction - * and data cache. Invalidate and enable cache, also enable write - * buffers and branch accelerator. - */ -.macro CACHE_ENABLE - movel #0x01040100,%d0 /* invalidate whole cache */ - movec %d0,%CACR - nop - movel #0x000fc000,%d0 /* set SDRAM cached only */ - movec %d0, %ACR0 - movel #0x00000000,%d0 /* no other regions cached */ - movec %d0, %ACR1 - movel #0x000fc000,%d0 /* set SDRAM cached only */ - movec %d0, %ACR2 - movel #0x00000000,%d0 /* no other regions cached */ - movec %d0, %ACR3 - movel #0xb6088400,%d0 /* enable caches */ - movec %d0,%CACR - nop -.endm -#endif /* CONFIG_M5407 */ - -#if defined(CONFIG_M520x) -.macro CACHE_ENABLE - move.l #0x01000000,%d0 /* invalidate whole cache */ - movec %d0,%CACR - nop - move.l #0x0000c000,%d0 /* set SDRAM cached (write-thru) */ - movec %d0,%ACR0 - move.l #0x00000000,%d0 /* no other regions cached */ - movec %d0,%ACR1 - move.l #0x80400000,%d0 /* enable 8K instruction cache */ - movec %d0,%CACR - nop -.endm -#endif /* CONFIG_M520x */ - -/****************************************************************************/ -#endif /* __M68KNOMMU_MCFCACHE_H */ diff --git a/arch/m68knommu/include/asm/mcfdma.h b/arch/m68knommu/include/asm/mcfdma.h deleted file mode 100644 index 705c52c79cd..00000000000 --- a/arch/m68knommu/include/asm/mcfdma.h +++ /dev/null @@ -1,144 +0,0 @@ -/****************************************************************************/ - -/* - * mcfdma.h -- Coldfire internal DMA support defines. - * - * (C) Copyright 1999, Rob Scott (rscott@mtrob.ml.org) - */ - -/****************************************************************************/ -#ifndef mcfdma_h -#define mcfdma_h -/****************************************************************************/ - - -/* - * Get address specific defines for this Coldfire member. - */ -#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) -#define MCFDMA_BASE0 0x200 /* Base address of DMA 0 */ -#define MCFDMA_BASE1 0x240 /* Base address of DMA 1 */ -#elif defined(CONFIG_M5272) -#define MCFDMA_BASE0 0x0e0 /* Base address of DMA 0 */ -#elif defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) -/* These are relative to the IPSBAR, not MBAR */ -#define MCFDMA_BASE0 0x100 /* Base address of DMA 0 */ -#define MCFDMA_BASE1 0x140 /* Base address of DMA 1 */ -#define MCFDMA_BASE2 0x180 /* Base address of DMA 2 */ -#define MCFDMA_BASE3 0x1C0 /* Base address of DMA 3 */ -#elif defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) -#define MCFDMA_BASE0 0x300 /* Base address of DMA 0 */ -#define MCFDMA_BASE1 0x340 /* Base address of DMA 1 */ -#define MCFDMA_BASE2 0x380 /* Base address of DMA 2 */ -#define MCFDMA_BASE3 0x3C0 /* Base address of DMA 3 */ -#endif - - -#if !defined(CONFIG_M5272) - -/* - * Define the DMA register set addresses. - * Note: these are longword registers, use unsigned long as data type - */ -#define MCFDMA_SAR 0x00 /* DMA source address (r/w) */ -#define MCFDMA_DAR 0x01 /* DMA destination adr (r/w) */ -/* these are word registers, use unsigned short data type */ -#define MCFDMA_DCR 0x04 /* DMA control reg (r/w) */ -#define MCFDMA_BCR 0x06 /* DMA byte count reg (r/w) */ -/* these are byte registers, use unsiged char data type */ -#define MCFDMA_DSR 0x10 /* DMA status reg (r/w) */ -#define MCFDMA_DIVR 0x14 /* DMA interrupt vec (r/w) */ - -/* - * Bit definitions for the DMA Control Register (DCR). - */ -#define MCFDMA_DCR_INT 0x8000 /* Enable completion irq */ -#define MCFDMA_DCR_EEXT 0x4000 /* Enable external DMA req */ -#define MCFDMA_DCR_CS 0x2000 /* Enable cycle steal */ -#define MCFDMA_DCR_AA 0x1000 /* Enable auto alignment */ -#define MCFDMA_DCR_BWC_MASK 0x0E00 /* Bandwidth ctl mask */ -#define MCFDMA_DCR_BWC_512 0x0200 /* Bandwidth: 512 Bytes */ -#define MCFDMA_DCR_BWC_1024 0x0400 /* Bandwidth: 1024 Bytes */ -#define MCFDMA_DCR_BWC_2048 0x0600 /* Bandwidth: 2048 Bytes */ -#define MCFDMA_DCR_BWC_4096 0x0800 /* Bandwidth: 4096 Bytes */ -#define MCFDMA_DCR_BWC_8192 0x0a00 /* Bandwidth: 8192 Bytes */ -#define MCFDMA_DCR_BWC_16384 0x0c00 /* Bandwidth: 16384 Bytes */ -#define MCFDMA_DCR_BWC_32768 0x0e00 /* Bandwidth: 32768 Bytes */ -#define MCFDMA_DCR_SAA 0x0100 /* Single Address Access */ -#define MCFDMA_DCR_S_RW 0x0080 /* SAA read/write value */ -#define MCFDMA_DCR_SINC 0x0040 /* Source addr inc enable */ -#define MCFDMA_DCR_SSIZE_MASK 0x0030 /* Src xfer size */ -#define MCFDMA_DCR_SSIZE_LONG 0x0000 /* Src xfer size, 00 = longw */ -#define MCFDMA_DCR_SSIZE_BYTE 0x0010 /* Src xfer size, 01 = byte */ -#define MCFDMA_DCR_SSIZE_WORD 0x0020 /* Src xfer size, 10 = word */ -#define MCFDMA_DCR_SSIZE_LINE 0x0030 /* Src xfer size, 11 = line */ -#define MCFDMA_DCR_DINC 0x0008 /* Dest addr inc enable */ -#define MCFDMA_DCR_DSIZE_MASK 0x0006 /* Dest xfer size */ -#define MCFDMA_DCR_DSIZE_LONG 0x0000 /* Dest xfer size, 00 = long */ -#define MCFDMA_DCR_DSIZE_BYTE 0x0002 /* Dest xfer size, 01 = byte */ -#define MCFDMA_DCR_DSIZE_WORD 0x0004 /* Dest xfer size, 10 = word */ -#define MCFDMA_DCR_DSIZE_LINE 0x0006 /* Dest xfer size, 11 = line */ -#define MCFDMA_DCR_START 0x0001 /* Start transfer */ - -/* - * Bit definitions for the DMA Status Register (DSR). - */ -#define MCFDMA_DSR_CE 0x40 /* Config error */ -#define MCFDMA_DSR_BES 0x20 /* Bus Error on source */ -#define MCFDMA_DSR_BED 0x10 /* Bus Error on dest */ -#define MCFDMA_DSR_REQ 0x04 /* Requests remaining */ -#define MCFDMA_DSR_BSY 0x02 /* Busy */ -#define MCFDMA_DSR_DONE 0x01 /* DMA transfer complete */ - -#else /* This is an MCF5272 */ - -#define MCFDMA_DMR 0x00 /* Mode Register (r/w) */ -#define MCFDMA_DIR 0x03 /* Interrupt trigger register (r/w) */ -#define MCFDMA_DSAR 0x03 /* Source Address register (r/w) */ -#define MCFDMA_DDAR 0x04 /* Destination Address register (r/w) */ -#define MCFDMA_DBCR 0x02 /* Byte Count Register (r/w) */ - -/* Bit definitions for the DMA Mode Register (DMR) */ -#define MCFDMA_DMR_RESET 0x80000000L /* Reset bit */ -#define MCFDMA_DMR_EN 0x40000000L /* DMA enable */ -#define MCFDMA_DMR_RQM 0x000C0000L /* Request Mode Mask */ -#define MCFDMA_DMR_RQM_DUAL 0x000C0000L /* Dual address mode, the only valid mode */ -#define MCFDMA_DMR_DSTM 0x00002000L /* Destination addressing mask */ -#define MCFDMA_DMR_DSTM_SA 0x00000000L /* Destination uses static addressing */ -#define MCFDMA_DMR_DSTM_IA 0x00002000L /* Destination uses incremental addressing */ -#define MCFDMA_DMR_DSTT_UD 0x00000400L /* Destination is user data */ -#define MCFDMA_DMR_DSTT_UC 0x00000800L /* Destination is user code */ -#define MCFDMA_DMR_DSTT_SD 0x00001400L /* Destination is supervisor data */ -#define MCFDMA_DMR_DSTT_SC 0x00001800L /* Destination is supervisor code */ -#define MCFDMA_DMR_DSTS_OFF 0x8 /* offset to the destination size bits */ -#define MCFDMA_DMR_DSTS_LONG 0x00000000L /* Long destination size */ -#define MCFDMA_DMR_DSTS_BYTE 0x00000100L /* Byte destination size */ -#define MCFDMA_DMR_DSTS_WORD 0x00000200L /* Word destination size */ -#define MCFDMA_DMR_DSTS_LINE 0x00000300L /* Line destination size */ -#define MCFDMA_DMR_SRCM 0x00000020L /* Source addressing mask */ -#define MCFDMA_DMR_SRCM_SA 0x00000000L /* Source uses static addressing */ -#define MCFDMA_DMR_SRCM_IA 0x00000020L /* Source uses incremental addressing */ -#define MCFDMA_DMR_SRCT_UD 0x00000004L /* Source is user data */ -#define MCFDMA_DMR_SRCT_UC 0x00000008L /* Source is user code */ -#define MCFDMA_DMR_SRCT_SD 0x00000014L /* Source is supervisor data */ -#define MCFDMA_DMR_SRCT_SC 0x00000018L /* Source is supervisor code */ -#define MCFDMA_DMR_SRCS_OFF 0x0 /* Offset to the source size bits */ -#define MCFDMA_DMR_SRCS_LONG 0x00000000L /* Long source size */ -#define MCFDMA_DMR_SRCS_BYTE 0x00000001L /* Byte source size */ -#define MCFDMA_DMR_SRCS_WORD 0x00000002L /* Word source size */ -#define MCFDMA_DMR_SRCS_LINE 0x00000003L /* Line source size */ - -/* Bit definitions for the DMA interrupt register (DIR) */ -#define MCFDMA_DIR_INVEN 0x1000 /* Invalid Combination interrupt enable */ -#define MCFDMA_DIR_ASCEN 0x0800 /* Address Sequence Complete (Completion) interrupt enable */ -#define MCFDMA_DIR_TEEN 0x0200 /* Transfer Error interrupt enable */ -#define MCFDMA_DIR_TCEN 0x0100 /* Transfer Complete (a bus transfer, that is) interrupt enable */ -#define MCFDMA_DIR_INV 0x0010 /* Invalid Combination */ -#define MCFDMA_DIR_ASC 0x0008 /* Address Sequence Complete (DMA Completion) */ -#define MCFDMA_DIR_TE 0x0002 /* Transfer Error */ -#define MCFDMA_DIR_TC 0x0001 /* Transfer Complete */ - -#endif /* !defined(CONFIG_M5272) */ - -/****************************************************************************/ -#endif /* mcfdma_h */ diff --git a/arch/m68knommu/include/asm/mcfmbus.h b/arch/m68knommu/include/asm/mcfmbus.h deleted file mode 100644 index 319899c47a2..00000000000 --- a/arch/m68knommu/include/asm/mcfmbus.h +++ /dev/null @@ -1,77 +0,0 @@ -/****************************************************************************/ - -/* - * mcfmbus.h -- Coldfire MBUS support defines. - * - * (C) Copyright 1999, Martin Floeer (mfloeer@axcent.de) - */ - -/****************************************************************************/ - - -#ifndef mcfmbus_h -#define mcfmbus_h - - -#define MCFMBUS_BASE 0x280 -#define MCFMBUS_IRQ_VECTOR 0x19 -#define MCFMBUS_IRQ 0x1 -#define MCFMBUS_CLK 0x3f -#define MCFMBUS_IRQ_LEVEL 0x07 /*IRQ Level 1*/ -#define MCFMBUS_ADDRESS 0x01 - - -/* -* Define the 5307 MBUS register set addresses -*/ - -#define MCFMBUS_MADR 0x00 -#define MCFMBUS_MFDR 0x04 -#define MCFMBUS_MBCR 0x08 -#define MCFMBUS_MBSR 0x0C -#define MCFMBUS_MBDR 0x10 - - -#define MCFMBUS_MADR_ADDR(a) (((a)&0x7F)<<0x01) /*Slave Address*/ - -#define MCFMBUS_MFDR_MBC(a) ((a)&0x3F) /*M-Bus Clock*/ - -/* -* Define bit flags in Control Register -*/ - -#define MCFMBUS_MBCR_MEN (0x80) /* M-Bus Enable */ -#define MCFMBUS_MBCR_MIEN (0x40) /* M-Bus Interrupt Enable */ -#define MCFMBUS_MBCR_MSTA (0x20) /* Master/Slave Mode Select Bit */ -#define MCFMBUS_MBCR_MTX (0x10) /* Transmit/Rcv Mode Select Bit */ -#define MCFMBUS_MBCR_TXAK (0x08) /* Transmit Acknowledge Enable */ -#define MCFMBUS_MBCR_RSTA (0x04) /* Repeat Start */ - -/* -* Define bit flags in Status Register -*/ - -#define MCFMBUS_MBSR_MCF (0x80) /* Data Transfer Complete */ -#define MCFMBUS_MBSR_MAAS (0x40) /* Addressed as a Slave */ -#define MCFMBUS_MBSR_MBB (0x20) /* Bus Busy */ -#define MCFMBUS_MBSR_MAL (0x10) /* Arbitration Lost */ -#define MCFMBUS_MBSR_SRW (0x04) /* Slave Transmit */ -#define MCFMBUS_MBSR_MIF (0x02) /* M-Bus Interrupt */ -#define MCFMBUS_MBSR_RXAK (0x01) /* No Acknowledge Received */ - -/* -* Define bit flags in DATA I/O Register -*/ - -#define MCFMBUS_MBDR_READ (0x01) /* 1=read 0=write MBUS */ - -#define MBUSIOCSCLOCK 1 -#define MBUSIOCGCLOCK 2 -#define MBUSIOCSADDR 3 -#define MBUSIOCGADDR 4 -#define MBUSIOCSSLADDR 5 -#define MBUSIOCGSLADDR 6 -#define MBUSIOCSSUBADDR 7 -#define MBUSIOCGSUBADDR 8 - -#endif diff --git a/arch/m68knommu/include/asm/mcfne.h b/arch/m68knommu/include/asm/mcfne.h deleted file mode 100644 index 431f63aadd0..00000000000 --- a/arch/m68knommu/include/asm/mcfne.h +++ /dev/null @@ -1,325 +0,0 @@ -/****************************************************************************/ - -/* - * mcfne.h -- NE2000 in ColdFire eval boards. - * - * (C) Copyright 1999-2000, Greg Ungerer (gerg@snapgear.com) - * (C) Copyright 2000, Lineo (www.lineo.com) - * (C) Copyright 2001, SnapGear (www.snapgear.com) - * - * 19990409 David W. Miller Converted from m5206ne.h for 5307 eval board - * - * Hacked support for m5206e Cadre III evaluation board - * Fred Stevens (fred.stevens@pemstar.com) 13 April 1999 - */ - -/****************************************************************************/ -#ifndef mcfne_h -#define mcfne_h -/****************************************************************************/ - - -/* - * Support for NE2000 clones devices in ColdFire based boards. - * Not all boards address these parts the same way, some use a - * direct addressing method, others use a side-band address space - * to access odd address registers, some require byte swapping - * others do not. - */ -#define BSWAP(w) (((w) << 8) | ((w) >> 8)) -#define RSWAP(w) (w) - - -/* - * Define the basic hardware resources of NE2000 boards. - */ - -#if defined(CONFIG_ARN5206) -#define NE2000_ADDR 0x40000300 -#define NE2000_ODDOFFSET 0x00010000 -#define NE2000_IRQ_VECTOR 0xf0 -#define NE2000_IRQ_PRIORITY 2 -#define NE2000_IRQ_LEVEL 4 -#define NE2000_BYTE volatile unsigned short -#endif - -#if defined(CONFIG_M5206eC3) -#define NE2000_ADDR 0x40000300 -#define NE2000_ODDOFFSET 0x00010000 -#define NE2000_IRQ_VECTOR 0x1c -#define NE2000_IRQ_PRIORITY 2 -#define NE2000_IRQ_LEVEL 4 -#define NE2000_BYTE volatile unsigned short -#endif - -#if defined(CONFIG_M5206e) && defined(CONFIG_NETtel) -#define NE2000_ADDR 0x30000300 -#define NE2000_IRQ_VECTOR 25 -#define NE2000_IRQ_PRIORITY 1 -#define NE2000_IRQ_LEVEL 3 -#define NE2000_BYTE volatile unsigned char -#endif - -#if defined(CONFIG_M5307C3) -#define NE2000_ADDR 0x40000300 -#define NE2000_ODDOFFSET 0x00010000 -#define NE2000_IRQ_VECTOR 0x1b -#define NE2000_BYTE volatile unsigned short -#endif - -#if defined(CONFIG_M5272) && defined(CONFIG_NETtel) -#define NE2000_ADDR 0x30600300 -#define NE2000_ODDOFFSET 0x00008000 -#define NE2000_IRQ_VECTOR 67 -#undef BSWAP -#define BSWAP(w) (w) -#define NE2000_BYTE volatile unsigned short -#undef RSWAP -#define RSWAP(w) (((w) << 8) | ((w) >> 8)) -#endif - -#if defined(CONFIG_M5307) && defined(CONFIG_NETtel) -#define NE2000_ADDR0 0x30600300 -#define NE2000_ADDR1 0x30800300 -#define NE2000_ODDOFFSET 0x00008000 -#define NE2000_IRQ_VECTOR0 27 -#define NE2000_IRQ_VECTOR1 29 -#undef BSWAP -#define BSWAP(w) (w) -#define NE2000_BYTE volatile unsigned short -#undef RSWAP -#define RSWAP(w) (((w) << 8) | ((w) >> 8)) -#endif - -#if defined(CONFIG_M5307) && defined(CONFIG_SECUREEDGEMP3) -#define NE2000_ADDR 0x30600300 -#define NE2000_ODDOFFSET 0x00008000 -#define NE2000_IRQ_VECTOR 27 -#undef BSWAP -#define BSWAP(w) (w) -#define NE2000_BYTE volatile unsigned short -#undef RSWAP -#define RSWAP(w) (((w) << 8) | ((w) >> 8)) -#endif - -#if defined(CONFIG_ARN5307) -#define NE2000_ADDR 0xfe600300 -#define NE2000_ODDOFFSET 0x00010000 -#define NE2000_IRQ_VECTOR 0x1b -#define NE2000_IRQ_PRIORITY 2 -#define NE2000_IRQ_LEVEL 3 -#define NE2000_BYTE volatile unsigned short -#endif - -#if defined(CONFIG_M5407C3) -#define NE2000_ADDR 0x40000300 -#define NE2000_ODDOFFSET 0x00010000 -#define NE2000_IRQ_VECTOR 0x1b -#define NE2000_BYTE volatile unsigned short -#endif - -/****************************************************************************/ - -/* - * Side-band address space for odd address requires re-mapping - * many of the standard ISA access functions. - */ -#ifdef NE2000_ODDOFFSET - -#undef outb -#undef outb_p -#undef inb -#undef inb_p -#undef outsb -#undef outsw -#undef insb -#undef insw - -#define outb ne2000_outb -#define inb ne2000_inb -#define outb_p ne2000_outb -#define inb_p ne2000_inb -#define outsb ne2000_outsb -#define outsw ne2000_outsw -#define insb ne2000_insb -#define insw ne2000_insw - - -#ifndef COLDFIRE_NE2000_FUNCS - -void ne2000_outb(unsigned int val, unsigned int addr); -int ne2000_inb(unsigned int addr); -void ne2000_insb(unsigned int addr, void *vbuf, int unsigned long len); -void ne2000_insw(unsigned int addr, void *vbuf, unsigned long len); -void ne2000_outsb(unsigned int addr, void *vbuf, unsigned long len); -void ne2000_outsw(unsigned int addr, void *vbuf, unsigned long len); - -#else - -/* - * This macro converts a conventional register address into the - * real memory pointer of the mapped NE2000 device. - * On most NE2000 implementations on ColdFire boards the chip is - * mapped in kinda funny, due to its ISA heritage. - */ -#define NE2000_PTR(addr) ((addr&0x1)?(NE2000_ODDOFFSET+addr-1):(addr)) -#define NE2000_DATA_PTR(addr) (addr) - - -void ne2000_outb(unsigned int val, unsigned int addr) -{ - NE2000_BYTE *rp; - - rp = (NE2000_BYTE *) NE2000_PTR(addr); - *rp = RSWAP(val); -} - -int ne2000_inb(unsigned int addr) -{ - NE2000_BYTE *rp, val; - - rp = (NE2000_BYTE *) NE2000_PTR(addr); - val = *rp; - return((int) ((NE2000_BYTE) RSWAP(val))); -} - -void ne2000_insb(unsigned int addr, void *vbuf, int unsigned long len) -{ - NE2000_BYTE *rp, val; - unsigned char *buf; - - buf = (unsigned char *) vbuf; - rp = (NE2000_BYTE *) NE2000_DATA_PTR(addr); - for (; (len > 0); len--) { - val = *rp; - *buf++ = RSWAP(val); - } -} - -void ne2000_insw(unsigned int addr, void *vbuf, unsigned long len) -{ - volatile unsigned short *rp; - unsigned short w, *buf; - - buf = (unsigned short *) vbuf; - rp = (volatile unsigned short *) NE2000_DATA_PTR(addr); - for (; (len > 0); len--) { - w = *rp; - *buf++ = BSWAP(w); - } -} - -void ne2000_outsb(unsigned int addr, const void *vbuf, unsigned long len) -{ - NE2000_BYTE *rp, val; - unsigned char *buf; - - buf = (unsigned char *) vbuf; - rp = (NE2000_BYTE *) NE2000_DATA_PTR(addr); - for (; (len > 0); len--) { - val = *buf++; - *rp = RSWAP(val); - } -} - -void ne2000_outsw(unsigned int addr, const void *vbuf, unsigned long len) -{ - volatile unsigned short *rp; - unsigned short w, *buf; - - buf = (unsigned short *) vbuf; - rp = (volatile unsigned short *) NE2000_DATA_PTR(addr); - for (; (len > 0); len--) { - w = *buf++; - *rp = BSWAP(w); - } -} - -#endif /* COLDFIRE_NE2000_FUNCS */ -#endif /* NE2000_OFFOFFSET */ - -/****************************************************************************/ - -#ifdef COLDFIRE_NE2000_FUNCS - -/* - * Lastly the interrupt set up code... - * Minor differences between the different board types. - */ - -#if defined(CONFIG_ARN5206) -void ne2000_irqsetup(int irq) -{ - volatile unsigned char *icrp; - - icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_ICR4); - *icrp = MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI2; - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT4); -} -#endif - -#if defined(CONFIG_M5206eC3) -void ne2000_irqsetup(int irq) -{ - volatile unsigned char *icrp; - - icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_ICR4); - *icrp = MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI2 | MCFSIM_ICR_AUTOVEC; - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT4); -} -#endif - -#if defined(CONFIG_M5206e) && defined(CONFIG_NETtel) -void ne2000_irqsetup(int irq) -{ - mcf_autovector(irq); -} -#endif - -#if defined(CONFIG_M5272) && defined(CONFIG_NETtel) -void ne2000_irqsetup(int irq) -{ - volatile unsigned long *icrp; - volatile unsigned long *pitr; - - /* The NE2000 device uses external IRQ3 */ - icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1); - *icrp = (*icrp & 0x77077777) | 0x00d00000; - - pitr = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PITR); - *pitr = *pitr | 0x20000000; -} - -void ne2000_irqack(int irq) -{ - volatile unsigned long *icrp; - - /* The NE2000 device uses external IRQ3 */ - icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1); - *icrp = (*icrp & 0x77777777) | 0x00800000; -} -#endif - -#if defined(CONFIG_M5307) || defined(CONFIG_M5407) -#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3) - -void ne2000_irqsetup(int irq) -{ - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT3); - mcf_autovector(irq); -} - -#else - -void ne2000_irqsetup(int irq) -{ - mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT3); -} - -#endif /* ! CONFIG_NETtel || CONFIG_SECUREEDGEMP3 */ -#endif /* CONFIG_M5307 || CONFIG_M5407 */ - -#endif /* COLDFIRE_NE2000_FUNCS */ - -/****************************************************************************/ -#endif /* mcfne_h */ diff --git a/arch/m68knommu/include/asm/mcfpci.h b/arch/m68knommu/include/asm/mcfpci.h deleted file mode 100644 index f1507dd06ec..00000000000 --- a/arch/m68knommu/include/asm/mcfpci.h +++ /dev/null @@ -1,119 +0,0 @@ -/****************************************************************************/ - -/* - * mcfpci.h -- PCI bridge on ColdFire eval boards. - * - * (C) Copyright 2000, Greg Ungerer (gerg@snapgear.com) - * (C) Copyright 2000, Lineo Inc. (www.lineo.com) - */ - -/****************************************************************************/ -#ifndef mcfpci_h -#define mcfpci_h -/****************************************************************************/ - - -#ifdef CONFIG_PCI - -/* - * Address regions in the PCI address space are not mapped into the - * normal memory space of the ColdFire. They must be accessed via - * handler routines. This is easy for I/O space (inb/outb/etc) but - * needs some code changes to support ordinary memory. Interrupts - * also need to be vectored through the PCI handler first, then it - * will call the actual driver sub-handlers. - */ - -/* - * Un-define all the standard I/O access routines. - */ -#undef inb -#undef inw -#undef inl -#undef inb_p -#undef inw_p -#undef insb -#undef insw -#undef insl -#undef outb -#undef outw -#undef outl -#undef outb_p -#undef outw_p -#undef outsb -#undef outsw -#undef outsl - -#undef request_irq -#undef free_irq - -#undef bus_to_virt -#undef virt_to_bus - - -/* - * Re-direct all I/O memory accesses functions to PCI specific ones. - */ -#define inb pci_inb -#define inw pci_inw -#define inl pci_inl -#define inb_p pci_inb -#define inw_p pci_inw -#define insb pci_insb -#define insw pci_insw -#define insl pci_insl - -#define outb pci_outb -#define outw pci_outw -#define outl pci_outl -#define outb_p pci_outb -#define outw_p pci_outw -#define outsb pci_outsb -#define outsw pci_outsw -#define outsl pci_outsl - -#define request_irq pci_request_irq -#define free_irq pci_free_irq - -#define virt_to_bus pci_virt_to_bus -#define bus_to_virt pci_bus_to_virt - -#define CONFIG_COMEMPCI 1 - - -/* - * Prototypes of the real PCI functions (defined in bios32.c). - */ -unsigned char pci_inb(unsigned int addr); -unsigned short pci_inw(unsigned int addr); -unsigned int pci_inl(unsigned int addr); -void pci_insb(void *addr, void *buf, int len); -void pci_insw(void *addr, void *buf, int len); -void pci_insl(void *addr, void *buf, int len); - -void pci_outb(unsigned char val, unsigned int addr); -void pci_outw(unsigned short val, unsigned int addr); -void pci_outl(unsigned int val, unsigned int addr); -void pci_outsb(void *addr, void *buf, int len); -void pci_outsw(void *addr, void *buf, int len); -void pci_outsl(void *addr, void *buf, int len); - -int pci_request_irq(unsigned int irq, - void (*handler)(int, void *, struct pt_regs *), - unsigned long flags, - const char *device, - void *dev_id); -void pci_free_irq(unsigned int irq, void *dev_id); - -void *pci_bmalloc(int size); -void pci_bmfree(void *bmp, int len); -void pci_copytoshmem(unsigned long bmp, void *src, int size); -void pci_copyfromshmem(void *dst, unsigned long bmp, int size); -unsigned long pci_virt_to_bus(volatile void *address); -void *pci_bus_to_virt(unsigned long address); -void pci_bmcpyto(void *dst, void *src, int len); -void pci_bmcpyfrom(void *dst, void *src, int len); - -#endif /* CONFIG_PCI */ -/****************************************************************************/ -#endif /* mcfpci_h */ diff --git a/arch/m68knommu/include/asm/mcfpit.h b/arch/m68knommu/include/asm/mcfpit.h deleted file mode 100644 index f570cf64fd2..00000000000 --- a/arch/m68knommu/include/asm/mcfpit.h +++ /dev/null @@ -1,64 +0,0 @@ -/****************************************************************************/ - -/* - * mcfpit.h -- ColdFire internal PIT timer support defines. - * - * (C) Copyright 2003, Greg Ungerer (gerg@snapgear.com) - */ - -/****************************************************************************/ -#ifndef mcfpit_h -#define mcfpit_h -/****************************************************************************/ - - -/* - * Get address specific defines for the 5270/5271, 5280/5282, and 5208. - */ -#if defined(CONFIG_M520x) -#define MCFPIT_BASE1 0x00080000 /* Base address of TIMER1 */ -#define MCFPIT_BASE2 0x00084000 /* Base address of TIMER2 */ -#else -#define MCFPIT_BASE1 0x00150000 /* Base address of TIMER1 */ -#define MCFPIT_BASE2 0x00160000 /* Base address of TIMER2 */ -#define MCFPIT_BASE3 0x00170000 /* Base address of TIMER3 */ -#define MCFPIT_BASE4 0x00180000 /* Base address of TIMER4 */ -#endif - -/* - * Define the PIT timer register set addresses. - */ -#define MCFPIT_PCSR 0x0 /* PIT control register */ -#define MCFPIT_PMR 0x2 /* PIT modulus register */ -#define MCFPIT_PCNTR 0x4 /* PIT count register */ - -/* - * Bit definitions for the PIT Control and Status register. - */ -#define MCFPIT_PCSR_CLK1 0x0000 /* System clock divisor */ -#define MCFPIT_PCSR_CLK2 0x0100 /* System clock divisor */ -#define MCFPIT_PCSR_CLK4 0x0200 /* System clock divisor */ -#define MCFPIT_PCSR_CLK8 0x0300 /* System clock divisor */ -#define MCFPIT_PCSR_CLK16 0x0400 /* System clock divisor */ -#define MCFPIT_PCSR_CLK32 0x0500 /* System clock divisor */ -#define MCFPIT_PCSR_CLK64 0x0600 /* System clock divisor */ -#define MCFPIT_PCSR_CLK128 0x0700 /* System clock divisor */ -#define MCFPIT_PCSR_CLK256 0x0800 /* System clock divisor */ -#define MCFPIT_PCSR_CLK512 0x0900 /* System clock divisor */ -#define MCFPIT_PCSR_CLK1024 0x0a00 /* System clock divisor */ -#define MCFPIT_PCSR_CLK2048 0x0b00 /* System clock divisor */ -#define MCFPIT_PCSR_CLK4096 0x0c00 /* System clock divisor */ -#define MCFPIT_PCSR_CLK8192 0x0d00 /* System clock divisor */ -#define MCFPIT_PCSR_CLK16384 0x0e00 /* System clock divisor */ -#define MCFPIT_PCSR_CLK32768 0x0f00 /* System clock divisor */ -#define MCFPIT_PCSR_DOZE 0x0040 /* Clock run in doze mode */ -#define MCFPIT_PCSR_HALTED 0x0020 /* Clock run in halt mode */ -#define MCFPIT_PCSR_OVW 0x0010 /* Overwrite PIT counter now */ -#define MCFPIT_PCSR_PIE 0x0008 /* Enable PIT interrupt */ -#define MCFPIT_PCSR_PIF 0x0004 /* PIT interrupt flag */ -#define MCFPIT_PCSR_RLD 0x0002 /* Reload counter */ -#define MCFPIT_PCSR_EN 0x0001 /* Enable PIT */ -#define MCFPIT_PCSR_DISABLE 0x0000 /* Disable PIT */ - -/****************************************************************************/ -#endif /* mcfpit_h */ diff --git a/arch/m68knommu/include/asm/mcfsim.h b/arch/m68knommu/include/asm/mcfsim.h deleted file mode 100644 index da3f2ceff3a..00000000000 --- a/arch/m68knommu/include/asm/mcfsim.h +++ /dev/null @@ -1,126 +0,0 @@ -/****************************************************************************/ - -/* - * mcfsim.h -- ColdFire System Integration Module support. - * - * (C) Copyright 1999-2003, Greg Ungerer (gerg@snapgear.com) - * (C) Copyright 2000, Lineo Inc. (www.lineo.com) - */ - -/****************************************************************************/ -#ifndef mcfsim_h -#define mcfsim_h -/****************************************************************************/ - - -/* - * Include 5204, 5206/e, 5235, 5249, 5270/5271, 5272, 5280/5282, - * 5307 or 5407 specific addresses. - */ -#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) -#include -#elif defined(CONFIG_M520x) -#include -#elif defined(CONFIG_M523x) -#include -#elif defined(CONFIG_M5249) -#include -#elif defined(CONFIG_M527x) -#include -#elif defined(CONFIG_M5272) -#include -#elif defined(CONFIG_M528x) -#include -#elif defined(CONFIG_M5307) -#include -#elif defined(CONFIG_M532x) -#include -#elif defined(CONFIG_M5407) -#include -#endif - - -/* - * Define the base address of the SIM within the MBAR address space. - */ -#define MCFSIM_BASE 0x0 /* Base address of SIM */ - - -/* - * Bit definitions for the ICR family of registers. - */ -#define MCFSIM_ICR_AUTOVEC 0x80 /* Auto-vectored intr */ -#define MCFSIM_ICR_LEVEL0 0x00 /* Level 0 intr */ -#define MCFSIM_ICR_LEVEL1 0x04 /* Level 1 intr */ -#define MCFSIM_ICR_LEVEL2 0x08 /* Level 2 intr */ -#define MCFSIM_ICR_LEVEL3 0x0c /* Level 3 intr */ -#define MCFSIM_ICR_LEVEL4 0x10 /* Level 4 intr */ -#define MCFSIM_ICR_LEVEL5 0x14 /* Level 5 intr */ -#define MCFSIM_ICR_LEVEL6 0x18 /* Level 6 intr */ -#define MCFSIM_ICR_LEVEL7 0x1c /* Level 7 intr */ - -#define MCFSIM_ICR_PRI0 0x00 /* Priority 0 intr */ -#define MCFSIM_ICR_PRI1 0x01 /* Priority 1 intr */ -#define MCFSIM_ICR_PRI2 0x02 /* Priority 2 intr */ -#define MCFSIM_ICR_PRI3 0x03 /* Priority 3 intr */ - -/* - * Bit definitions for the Interrupt Mask register (IMR). - */ -#define MCFSIM_IMR_EINT1 0x0002 /* External intr # 1 */ -#define MCFSIM_IMR_EINT2 0x0004 /* External intr # 2 */ -#define MCFSIM_IMR_EINT3 0x0008 /* External intr # 3 */ -#define MCFSIM_IMR_EINT4 0x0010 /* External intr # 4 */ -#define MCFSIM_IMR_EINT5 0x0020 /* External intr # 5 */ -#define MCFSIM_IMR_EINT6 0x0040 /* External intr # 6 */ -#define MCFSIM_IMR_EINT7 0x0080 /* External intr # 7 */ - -#define MCFSIM_IMR_SWD 0x0100 /* Software Watchdog intr */ -#define MCFSIM_IMR_TIMER1 0x0200 /* TIMER 1 intr */ -#define MCFSIM_IMR_TIMER2 0x0400 /* TIMER 2 intr */ -#define MCFSIM_IMR_MBUS 0x0800 /* MBUS intr */ -#define MCFSIM_IMR_UART1 0x1000 /* UART 1 intr */ -#define MCFSIM_IMR_UART2 0x2000 /* UART 2 intr */ - -#if defined(CONFIG_M5206e) -#define MCFSIM_IMR_DMA1 0x4000 /* DMA 1 intr */ -#define MCFSIM_IMR_DMA2 0x8000 /* DMA 2 intr */ -#elif defined(CONFIG_M5249) || defined(CONFIG_M5307) -#define MCFSIM_IMR_DMA0 0x4000 /* DMA 0 intr */ -#define MCFSIM_IMR_DMA1 0x8000 /* DMA 1 intr */ -#define MCFSIM_IMR_DMA2 0x10000 /* DMA 2 intr */ -#define MCFSIM_IMR_DMA3 0x20000 /* DMA 3 intr */ -#endif - -/* - * Mask for all of the SIM devices. Some parts have more or less - * SIM devices. This is a catchall for the sandard set. - */ -#ifndef MCFSIM_IMR_MASKALL -#define MCFSIM_IMR_MASKALL 0x3ffe /* All intr sources */ -#endif - - -/* - * PIT interrupt settings, if not found in mXXXXsim.h file. - */ -#ifndef ICR_INTRCONF -#define ICR_INTRCONF 0x2b /* PIT1 level 5, priority 3 */ -#endif -#ifndef MCFPIT_IMR -#define MCFPIT_IMR MCFINTC_IMRH -#endif -#ifndef MCFPIT_IMR_IBIT -#define MCFPIT_IMR_IBIT (1 << (MCFINT_PIT1 - 32)) -#endif - - -#ifndef __ASSEMBLY__ -/* - * Definition for the interrupt auto-vectoring support. - */ -extern void mcf_autovector(unsigned int vec); -#endif /* __ASSEMBLY__ */ - -/****************************************************************************/ -#endif /* mcfsim_h */ diff --git a/arch/m68knommu/include/asm/mcfsmc.h b/arch/m68knommu/include/asm/mcfsmc.h deleted file mode 100644 index 2d7a4dbd968..00000000000 --- a/arch/m68knommu/include/asm/mcfsmc.h +++ /dev/null @@ -1,187 +0,0 @@ -/****************************************************************************/ - -/* - * mcfsmc.h -- SMC ethernet support for ColdFire environments. - * - * (C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com) - * (C) Copyright 2000, Lineo Inc. (www.lineo.com) - */ - -/****************************************************************************/ -#ifndef mcfsmc_h -#define mcfsmc_h -/****************************************************************************/ - -/* - * None of the current ColdFire targets that use the SMC91x111 - * allow 8 bit accesses. So this code is 16bit access only. - */ - - -#undef outb -#undef inb -#undef outw -#undef outwd -#undef inw -#undef outl -#undef inl - -#undef outsb -#undef outsw -#undef outsl -#undef insb -#undef insw -#undef insl - -/* - * Re-defines for ColdFire environment... The SMC part is - * mapped into memory space, so remap the PC-style in/out - * routines to handle that. - */ -#define outb smc_outb -#define inb smc_inb -#define outw smc_outw -#define outwd smc_outwd -#define inw smc_inw -#define outl smc_outl -#define inl smc_inl - -#define outsb smc_outsb -#define outsw smc_outsw -#define outsl smc_outsl -#define insb smc_insb -#define insw smc_insw -#define insl smc_insl - - -static inline int smc_inb(unsigned int addr) -{ - register unsigned short w; - w = *((volatile unsigned short *) (addr & ~0x1)); - return(((addr & 0x1) ? w : (w >> 8)) & 0xff); -} - -static inline void smc_outw(unsigned int val, unsigned int addr) -{ - *((volatile unsigned short *) addr) = (val << 8) | (val >> 8); -} - -static inline int smc_inw(unsigned int addr) -{ - register unsigned short w; - w = *((volatile unsigned short *) addr); - return(((w << 8) | (w >> 8)) & 0xffff); -} - -static inline void smc_outl(unsigned long val, unsigned int addr) -{ - *((volatile unsigned long *) addr) = - ((val << 8) & 0xff000000) | ((val >> 8) & 0x00ff0000) | - ((val << 8) & 0x0000ff00) | ((val >> 8) & 0x000000ff); -} - -static inline void smc_outwd(unsigned int val, unsigned int addr) -{ - *((volatile unsigned short *) addr) = val; -} - - -/* - * The rep* functions are used to feed the data port with - * raw data. So we do not byte swap them when copying. - */ - -static inline void smc_insb(unsigned int addr, void *vbuf, int unsigned long len) -{ - volatile unsigned short *rp; - unsigned short *buf, *ebuf; - - buf = (unsigned short *) vbuf; - rp = (volatile unsigned short *) addr; - - /* Copy as words for as long as possible */ - for (ebuf = buf + (len >> 1); (buf < ebuf); ) - *buf++ = *rp; - - /* Lastly, handle left over byte */ - if (len & 0x1) - *((unsigned char *) buf) = (*rp >> 8) & 0xff; -} - -static inline void smc_insw(unsigned int addr, void *vbuf, unsigned long len) -{ - volatile unsigned short *rp; - unsigned short *buf, *ebuf; - - buf = (unsigned short *) vbuf; - rp = (volatile unsigned short *) addr; - for (ebuf = buf + len; (buf < ebuf); ) - *buf++ = *rp; -} - -static inline void smc_insl(unsigned int addr, void *vbuf, unsigned long len) -{ - volatile unsigned long *rp; - unsigned long *buf, *ebuf; - - buf = (unsigned long *) vbuf; - rp = (volatile unsigned long *) addr; - for (ebuf = buf + len; (buf < ebuf); ) - *buf++ = *rp; -} - -static inline void smc_outsw(unsigned int addr, const void *vbuf, unsigned long len) -{ - volatile unsigned short *rp; - unsigned short *buf, *ebuf; - - buf = (unsigned short *) vbuf; - rp = (volatile unsigned short *) addr; - for (ebuf = buf + len; (buf < ebuf); ) - *rp = *buf++; -} - -static inline void smc_outsl(unsigned int addr, void *vbuf, unsigned long len) -{ - volatile unsigned long *rp; - unsigned long *buf, *ebuf; - - buf = (unsigned long *) vbuf; - rp = (volatile unsigned long *) addr; - for (ebuf = buf + len; (buf < ebuf); ) - *rp = *buf++; -} - - -#ifdef CONFIG_NETtel -/* - * Re-map the address space of at least one of the SMC ethernet - * parts. Both parts power up decoding the same address, so we - * need to move one of them first, before doing enything else. - * - * We also increase the number of wait states for this part by one. - */ - -void smc_remap(unsigned int ioaddr) -{ - static int once = 0; - extern unsigned short ppdata; - if (once++ == 0) { - *((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADDR)) = 0x00ec; - ppdata |= 0x0080; - *((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADAT)) = ppdata; - outw(0x0001, ioaddr + BANK_SELECT); - outw(0x0001, ioaddr + BANK_SELECT); - outw(0x0067, ioaddr + BASE); - - ppdata &= ~0x0080; - *((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADAT)) = ppdata; - } - - *((volatile unsigned short *)(MCF_MBAR+MCFSIM_CSCR3)) = 0x1180; -} - -#endif - -/****************************************************************************/ -#endif /* mcfsmc_h */ diff --git a/arch/m68knommu/include/asm/mcftimer.h b/arch/m68knommu/include/asm/mcftimer.h deleted file mode 100644 index 0f90f6d2227..00000000000 --- a/arch/m68knommu/include/asm/mcftimer.h +++ /dev/null @@ -1,80 +0,0 @@ -/****************************************************************************/ - -/* - * mcftimer.h -- ColdFire internal TIMER support defines. - * - * (C) Copyright 1999-2006, Greg Ungerer - * (C) Copyright 2000, Lineo Inc. (www.lineo.com) - */ - -/****************************************************************************/ -#ifndef mcftimer_h -#define mcftimer_h -/****************************************************************************/ - - -/* - * Get address specific defines for this ColdFire member. - */ -#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) -#define MCFTIMER_BASE1 0x100 /* Base address of TIMER1 */ -#define MCFTIMER_BASE2 0x120 /* Base address of TIMER2 */ -#elif defined(CONFIG_M5272) -#define MCFTIMER_BASE1 0x200 /* Base address of TIMER1 */ -#define MCFTIMER_BASE2 0x220 /* Base address of TIMER2 */ -#define MCFTIMER_BASE3 0x240 /* Base address of TIMER4 */ -#define MCFTIMER_BASE4 0x260 /* Base address of TIMER3 */ -#elif defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) -#define MCFTIMER_BASE1 0x140 /* Base address of TIMER1 */ -#define MCFTIMER_BASE2 0x180 /* Base address of TIMER2 */ -#elif defined(CONFIG_M532x) -#define MCFTIMER_BASE1 0xfc070000 /* Base address of TIMER1 */ -#define MCFTIMER_BASE2 0xfc074000 /* Base address of TIMER2 */ -#define MCFTIMER_BASE3 0xfc078000 /* Base address of TIMER3 */ -#define MCFTIMER_BASE4 0xfc07c000 /* Base address of TIMER4 */ -#endif - - -/* - * Define the TIMER register set addresses. - */ -#define MCFTIMER_TMR 0x00 /* Timer Mode reg (r/w) */ -#define MCFTIMER_TRR 0x04 /* Timer Reference (r/w) */ -#define MCFTIMER_TCR 0x08 /* Timer Capture reg (r/w) */ -#define MCFTIMER_TCN 0x0C /* Timer Counter reg (r/w) */ -#if defined(CONFIG_M532x) -#define MCFTIMER_TER 0x03 /* Timer Event reg (r/w) */ -#else -#define MCFTIMER_TER 0x11 /* Timer Event reg (r/w) */ -#endif - -/* - * Bit definitions for the Timer Mode Register (TMR). - * Register bit flags are common accross ColdFires. - */ -#define MCFTIMER_TMR_PREMASK 0xff00 /* Prescalar mask */ -#define MCFTIMER_TMR_DISCE 0x0000 /* Disable capture */ -#define MCFTIMER_TMR_ANYCE 0x00c0 /* Capture any edge */ -#define MCFTIMER_TMR_FALLCE 0x0080 /* Capture fallingedge */ -#define MCFTIMER_TMR_RISECE 0x0040 /* Capture rising edge */ -#define MCFTIMER_TMR_ENOM 0x0020 /* Enable output toggle */ -#define MCFTIMER_TMR_DISOM 0x0000 /* Do single output pulse */ -#define MCFTIMER_TMR_ENORI 0x0010 /* Enable ref interrupt */ -#define MCFTIMER_TMR_DISORI 0x0000 /* Disable ref interrupt */ -#define MCFTIMER_TMR_RESTART 0x0008 /* Restart counter */ -#define MCFTIMER_TMR_FREERUN 0x0000 /* Free running counter */ -#define MCFTIMER_TMR_CLKTIN 0x0006 /* Input clock is TIN */ -#define MCFTIMER_TMR_CLK16 0x0004 /* Input clock is /16 */ -#define MCFTIMER_TMR_CLK1 0x0002 /* Input clock is /1 */ -#define MCFTIMER_TMR_CLKSTOP 0x0000 /* Stop counter */ -#define MCFTIMER_TMR_ENABLE 0x0001 /* Enable timer */ -#define MCFTIMER_TMR_DISABLE 0x0000 /* Disable timer */ - -/* - * Bit definitions for the Timer Event Registers (TER). - */ -#define MCFTIMER_TER_CAP 0x01 /* Capture event */ -#define MCFTIMER_TER_REF 0x02 /* Refernece event */ - -/****************************************************************************/ -#endif /* mcftimer_h */ diff --git a/arch/m68knommu/include/asm/mcfuart.h b/arch/m68knommu/include/asm/mcfuart.h deleted file mode 100644 index ef229387361..00000000000 --- a/arch/m68knommu/include/asm/mcfuart.h +++ /dev/null @@ -1,216 +0,0 @@ -/****************************************************************************/ - -/* - * mcfuart.h -- ColdFire internal UART support defines. - * - * (C) Copyright 1999-2003, Greg Ungerer (gerg@snapgear.com) - * (C) Copyright 2000, Lineo Inc. (www.lineo.com) - */ - -/****************************************************************************/ -#ifndef mcfuart_h -#define mcfuart_h -/****************************************************************************/ - -/* - * Define the base address of the UARTS within the MBAR address - * space. - */ -#if defined(CONFIG_M5272) -#define MCFUART_BASE1 0x100 /* Base address of UART1 */ -#define MCFUART_BASE2 0x140 /* Base address of UART2 */ -#elif defined(CONFIG_M5206) || defined(CONFIG_M5206e) -#if defined(CONFIG_NETtel) -#define MCFUART_BASE1 0x180 /* Base address of UART1 */ -#define MCFUART_BASE2 0x140 /* Base address of UART2 */ -#else -#define MCFUART_BASE1 0x140 /* Base address of UART1 */ -#define MCFUART_BASE2 0x180 /* Base address of UART2 */ -#endif -#elif defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) -#define MCFUART_BASE1 0x200 /* Base address of UART1 */ -#define MCFUART_BASE2 0x240 /* Base address of UART2 */ -#define MCFUART_BASE3 0x280 /* Base address of UART3 */ -#elif defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) -#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3) -#define MCFUART_BASE1 0x200 /* Base address of UART1 */ -#define MCFUART_BASE2 0x1c0 /* Base address of UART2 */ -#else -#define MCFUART_BASE1 0x1c0 /* Base address of UART1 */ -#define MCFUART_BASE2 0x200 /* Base address of UART2 */ -#endif -#elif defined(CONFIG_M520x) -#define MCFUART_BASE1 0x60000 /* Base address of UART1 */ -#define MCFUART_BASE2 0x64000 /* Base address of UART2 */ -#define MCFUART_BASE3 0x68000 /* Base address of UART2 */ -#elif defined(CONFIG_M532x) -#define MCFUART_BASE1 0xfc060000 /* Base address of UART1 */ -#define MCFUART_BASE2 0xfc064000 /* Base address of UART2 */ -#define MCFUART_BASE3 0xfc068000 /* Base address of UART3 */ -#endif - - -#include -#include - -struct mcf_platform_uart { - unsigned long mapbase; /* Physical address base */ - void __iomem *membase; /* Virtual address if mapped */ - unsigned int irq; /* Interrupt vector */ - unsigned int uartclk; /* UART clock rate */ -}; - -/* - * Define the ColdFire UART register set addresses. - */ -#define MCFUART_UMR 0x00 /* Mode register (r/w) */ -#define MCFUART_USR 0x04 /* Status register (r) */ -#define MCFUART_UCSR 0x04 /* Clock Select (w) */ -#define MCFUART_UCR 0x08 /* Command register (w) */ -#define MCFUART_URB 0x0c /* Receiver Buffer (r) */ -#define MCFUART_UTB 0x0c /* Transmit Buffer (w) */ -#define MCFUART_UIPCR 0x10 /* Input Port Change (r) */ -#define MCFUART_UACR 0x10 /* Auxiliary Control (w) */ -#define MCFUART_UISR 0x14 /* Interrupt Status (r) */ -#define MCFUART_UIMR 0x14 /* Interrupt Mask (w) */ -#define MCFUART_UBG1 0x18 /* Baud Rate MSB (r/w) */ -#define MCFUART_UBG2 0x1c /* Baud Rate LSB (r/w) */ -#ifdef CONFIG_M5272 -#define MCFUART_UTF 0x28 /* Transmitter FIFO (r/w) */ -#define MCFUART_URF 0x2c /* Receiver FIFO (r/w) */ -#define MCFUART_UFPD 0x30 /* Frac Prec. Divider (r/w) */ -#else -#define MCFUART_UIVR 0x30 /* Interrupt Vector (r/w) */ -#endif -#define MCFUART_UIPR 0x34 /* Input Port (r) */ -#define MCFUART_UOP1 0x38 /* Output Port Bit Set (w) */ -#define MCFUART_UOP0 0x3c /* Output Port Bit Reset (w) */ - - -/* - * Define bit flags in Mode Register 1 (MR1). - */ -#define MCFUART_MR1_RXRTS 0x80 /* Auto RTS flow control */ -#define MCFUART_MR1_RXIRQFULL 0x40 /* RX IRQ type FULL */ -#define MCFUART_MR1_RXIRQRDY 0x00 /* RX IRQ type RDY */ -#define MCFUART_MR1_RXERRBLOCK 0x20 /* RX block error mode */ -#define MCFUART_MR1_RXERRCHAR 0x00 /* RX char error mode */ - -#define MCFUART_MR1_PARITYNONE 0x10 /* No parity */ -#define MCFUART_MR1_PARITYEVEN 0x00 /* Even parity */ -#define MCFUART_MR1_PARITYODD 0x04 /* Odd parity */ -#define MCFUART_MR1_PARITYSPACE 0x08 /* Space parity */ -#define MCFUART_MR1_PARITYMARK 0x0c /* Mark parity */ - -#define MCFUART_MR1_CS5 0x00 /* 5 bits per char */ -#define MCFUART_MR1_CS6 0x01 /* 6 bits per char */ -#define MCFUART_MR1_CS7 0x02 /* 7 bits per char */ -#define MCFUART_MR1_CS8 0x03 /* 8 bits per char */ - -/* - * Define bit flags in Mode Register 2 (MR2). - */ -#define MCFUART_MR2_LOOPBACK 0x80 /* Loopback mode */ -#define MCFUART_MR2_REMOTELOOP 0xc0 /* Remote loopback mode */ -#define MCFUART_MR2_AUTOECHO 0x40 /* Automatic echo */ -#define MCFUART_MR2_TXRTS 0x20 /* Assert RTS on TX */ -#define MCFUART_MR2_TXCTS 0x10 /* Auto CTS flow control */ - -#define MCFUART_MR2_STOP1 0x07 /* 1 stop bit */ -#define MCFUART_MR2_STOP15 0x08 /* 1.5 stop bits */ -#define MCFUART_MR2_STOP2 0x0f /* 2 stop bits */ - -/* - * Define bit flags in Status Register (USR). - */ -#define MCFUART_USR_RXBREAK 0x80 /* Received BREAK */ -#define MCFUART_USR_RXFRAMING 0x40 /* Received framing error */ -#define MCFUART_USR_RXPARITY 0x20 /* Received parity error */ -#define MCFUART_USR_RXOVERRUN 0x10 /* Received overrun error */ -#define MCFUART_USR_TXEMPTY 0x08 /* Transmitter empty */ -#define MCFUART_USR_TXREADY 0x04 /* Transmitter ready */ -#define MCFUART_USR_RXFULL 0x02 /* Receiver full */ -#define MCFUART_USR_RXREADY 0x01 /* Receiver ready */ - -#define MCFUART_USR_RXERR (MCFUART_USR_RXBREAK | MCFUART_USR_RXFRAMING | \ - MCFUART_USR_RXPARITY | MCFUART_USR_RXOVERRUN) - -/* - * Define bit flags in Clock Select Register (UCSR). - */ -#define MCFUART_UCSR_RXCLKTIMER 0xd0 /* RX clock is timer */ -#define MCFUART_UCSR_RXCLKEXT16 0xe0 /* RX clock is external x16 */ -#define MCFUART_UCSR_RXCLKEXT1 0xf0 /* RX clock is external x1 */ - -#define MCFUART_UCSR_TXCLKTIMER 0x0d /* TX clock is timer */ -#define MCFUART_UCSR_TXCLKEXT16 0x0e /* TX clock is external x16 */ -#define MCFUART_UCSR_TXCLKEXT1 0x0f /* TX clock is external x1 */ - -/* - * Define bit flags in Command Register (UCR). - */ -#define MCFUART_UCR_CMDNULL 0x00 /* No command */ -#define MCFUART_UCR_CMDRESETMRPTR 0x10 /* Reset MR pointer */ -#define MCFUART_UCR_CMDRESETRX 0x20 /* Reset receiver */ -#define MCFUART_UCR_CMDRESETTX 0x30 /* Reset transmitter */ -#define MCFUART_UCR_CMDRESETERR 0x40 /* Reset error status */ -#define MCFUART_UCR_CMDRESETBREAK 0x50 /* Reset BREAK change */ -#define MCFUART_UCR_CMDBREAKSTART 0x60 /* Start BREAK */ -#define MCFUART_UCR_CMDBREAKSTOP 0x70 /* Stop BREAK */ - -#define MCFUART_UCR_TXNULL 0x00 /* No TX command */ -#define MCFUART_UCR_TXENABLE 0x04 /* Enable TX */ -#define MCFUART_UCR_TXDISABLE 0x08 /* Disable TX */ -#define MCFUART_UCR_RXNULL 0x00 /* No RX command */ -#define MCFUART_UCR_RXENABLE 0x01 /* Enable RX */ -#define MCFUART_UCR_RXDISABLE 0x02 /* Disable RX */ - -/* - * Define bit flags in Input Port Change Register (UIPCR). - */ -#define MCFUART_UIPCR_CTSCOS 0x10 /* CTS change of state */ -#define MCFUART_UIPCR_CTS 0x01 /* CTS value */ - -/* - * Define bit flags in Input Port Register (UIP). - */ -#define MCFUART_UIPR_CTS 0x01 /* CTS value */ - -/* - * Define bit flags in Output Port Registers (UOP). - * Clear bit by writing to UOP0, set by writing to UOP1. - */ -#define MCFUART_UOP_RTS 0x01 /* RTS set or clear */ - -/* - * Define bit flags in the Auxiliary Control Register (UACR). - */ -#define MCFUART_UACR_IEC 0x01 /* Input enable control */ - -/* - * Define bit flags in Interrupt Status Register (UISR). - * These same bits are used for the Interrupt Mask Register (UIMR). - */ -#define MCFUART_UIR_COS 0x80 /* Change of state (CTS) */ -#define MCFUART_UIR_DELTABREAK 0x04 /* Break start or stop */ -#define MCFUART_UIR_RXREADY 0x02 /* Receiver ready */ -#define MCFUART_UIR_TXREADY 0x01 /* Transmitter ready */ - -#ifdef CONFIG_M5272 -/* - * Define bit flags in the Transmitter FIFO Register (UTF). - */ -#define MCFUART_UTF_TXB 0x1f /* Transmitter data level */ -#define MCFUART_UTF_FULL 0x20 /* Transmitter fifo full */ -#define MCFUART_UTF_TXS 0xc0 /* Transmitter status */ - -/* - * Define bit flags in the Receiver FIFO Register (URF). - */ -#define MCFUART_URF_RXB 0x1f /* Receiver data level */ -#define MCFUART_URF_FULL 0x20 /* Receiver fifo full */ -#define MCFUART_URF_RXS 0xc0 /* Receiver status */ -#endif - -/****************************************************************************/ -#endif /* mcfuart_h */ diff --git a/arch/m68knommu/include/asm/mcfwdebug.h b/arch/m68knommu/include/asm/mcfwdebug.h deleted file mode 100644 index 27f70e45d70..00000000000 --- a/arch/m68knommu/include/asm/mcfwdebug.h +++ /dev/null @@ -1,118 +0,0 @@ -/****************************************************************************/ - -/* - * mcfdebug.h -- ColdFire Debug Module support. - * - * (C) Copyright 2001, Lineo Inc. (www.lineo.com) - */ - -/****************************************************************************/ -#ifndef mcfdebug_h -#define mcfdebug_h -/****************************************************************************/ - -/* Define the debug module registers */ -#define MCFDEBUG_CSR 0x0 /* Configuration status */ -#define MCFDEBUG_BAAR 0x5 /* BDM address attribute */ -#define MCFDEBUG_AATR 0x6 /* Address attribute trigger */ -#define MCFDEBUG_TDR 0x7 /* Trigger definition */ -#define MCFDEBUG_PBR 0x8 /* PC breakpoint */ -#define MCFDEBUG_PBMR 0x9 /* PC breakpoint mask */ -#define MCFDEBUG_ABHR 0xc /* High address breakpoint */ -#define MCFDEBUG_ABLR 0xd /* Low address breakpoint */ -#define MCFDEBUG_DBR 0xe /* Data breakpoint */ -#define MCFDEBUG_DBMR 0xf /* Data breakpoint mask */ - -/* Define some handy constants for the trigger definition register */ -#define MCFDEBUG_TDR_TRC_DISP 0x00000000 /* display on DDATA only */ -#define MCFDEBUG_TDR_TRC_HALT 0x40000000 /* Processor halt on BP */ -#define MCFDEBUG_TDR_TRC_INTR 0x80000000 /* Debug intr on BP */ -#define MCFDEBUG_TDR_LXT1 0x00004000 /* TDR level 1 */ -#define MCFDEBUG_TDR_LXT2 0x00008000 /* TDR level 2 */ -#define MCFDEBUG_TDR_EBL1 0x00002000 /* Enable breakpoint level 1 */ -#define MCFDEBUG_TDR_EBL2 0x20000000 /* Enable breakpoint level 2 */ -#define MCFDEBUG_TDR_EDLW1 0x00001000 /* Enable data BP longword */ -#define MCFDEBUG_TDR_EDLW2 0x10000000 -#define MCFDEBUG_TDR_EDWL1 0x00000800 /* Enable data BP lower word */ -#define MCFDEBUG_TDR_EDWL2 0x08000000 -#define MCFDEBUG_TDR_EDWU1 0x00000400 /* Enable data BP upper word */ -#define MCFDEBUG_TDR_EDWU2 0x04000000 -#define MCFDEBUG_TDR_EDLL1 0x00000200 /* Enable data BP low low byte */ -#define MCFDEBUG_TDR_EDLL2 0x02000000 -#define MCFDEBUG_TDR_EDLM1 0x00000100 /* Enable data BP low mid byte */ -#define MCFDEBUG_TDR_EDLM2 0x01000000 -#define MCFDEBUG_TDR_EDUM1 0x00000080 /* Enable data BP up mid byte */ -#define MCFDEBUG_TDR_EDUM2 0x00800000 -#define MCFDEBUG_TDR_EDUU1 0x00000040 /* Enable data BP up up byte */ -#define MCFDEBUG_TDR_EDUU2 0x00400000 -#define MCFDEBUG_TDR_DI1 0x00000020 /* Data BP invert */ -#define MCFDEBUG_TDR_DI2 0x00200000 -#define MCFDEBUG_TDR_EAI1 0x00000010 /* Enable address BP inverted */ -#define MCFDEBUG_TDR_EAI2 0x00100000 -#define MCFDEBUG_TDR_EAR1 0x00000008 /* Enable address BP range */ -#define MCFDEBUG_TDR_EAR2 0x00080000 -#define MCFDEBUG_TDR_EAL1 0x00000004 /* Enable address BP low */ -#define MCFDEBUG_TDR_EAL2 0x00040000 -#define MCFDEBUG_TDR_EPC1 0x00000002 /* Enable PC BP */ -#define MCFDEBUG_TDR_EPC2 0x00020000 -#define MCFDEBUG_TDR_PCI1 0x00000001 /* PC BP invert */ -#define MCFDEBUG_TDR_PCI2 0x00010000 - -/* Constants for the address attribute trigger register */ -#define MCFDEBUG_AAR_RESET 0x00000005 -/* Fields not yet implemented */ - -/* And some definitions for the writable sections of the CSR */ -#define MCFDEBUG_CSR_RESET 0x00100000 -#define MCFDEBUG_CSR_PSTCLK 0x00020000 /* PSTCLK disable */ -#define MCFDEBUG_CSR_IPW 0x00010000 /* Inhibit processor writes */ -#define MCFDEBUG_CSR_MAP 0x00008000 /* Processor refs in emul mode */ -#define MCFDEBUG_CSR_TRC 0x00004000 /* Emul mode on trace exception */ -#define MCFDEBUG_CSR_EMU 0x00002000 /* Force emulation mode */ -#define MCFDEBUG_CSR_DDC_READ 0x00000800 /* Debug data control */ -#define MCFDEBUG_CSR_DDC_WRITE 0x00001000 -#define MCFDEBUG_CSR_UHE 0x00000400 /* User mode halt enable */ -#define MCFDEBUG_CSR_BTB0 0x00000000 /* Branch target 0 bytes */ -#define MCFDEBUG_CSR_BTB2 0x00000100 /* Branch target 2 bytes */ -#define MCFDEBUG_CSR_BTB3 0x00000200 /* Branch target 3 bytes */ -#define MCFDEBUG_CSR_BTB4 0x00000300 /* Branch target 4 bytes */ -#define MCFDEBUG_CSR_NPL 0x00000040 /* Non-pipelined mode */ -#define MCFDEBUG_CSR_SSM 0x00000010 /* Single step mode */ - -/* Constants for the BDM address attribute register */ -#define MCFDEBUG_BAAR_RESET 0x00000005 -/* Fields not yet implemented */ - - -/* This routine wrappers up the wdebug asm instruction so that the register - * and value can be relatively easily specified. The biggest hassle here is - * that the debug module instructions (2 longs) must be long word aligned and - * some pointer fiddling is performed to ensure this. - */ -static inline void wdebug(int reg, unsigned long data) { - unsigned short dbg_spc[6]; - unsigned short *dbg; - - // Force alignment to long word boundary - dbg = (unsigned short *)((((unsigned long)dbg_spc) + 3) & 0xfffffffc); - - // Build up the debug instruction - dbg[0] = 0x2c80 | (reg & 0xf); - dbg[1] = (data >> 16) & 0xffff; - dbg[2] = data & 0xffff; - dbg[3] = 0; - - // Perform the wdebug instruction -#if 0 - // This strain is for gas which doesn't have the wdebug instructions defined - asm( "move.l %0, %%a0\n\t" - ".word 0xfbd0\n\t" - ".word 0x0003\n\t" - :: "g" (dbg) : "a0"); -#else - // And this is for when it does - asm( "wdebug (%0)" :: "a" (dbg)); -#endif -} - -#endif diff --git a/arch/m68knommu/include/asm/md.h b/arch/m68knommu/include/asm/md.h deleted file mode 100644 index d810c78de5f..00000000000 --- a/arch/m68knommu/include/asm/md.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/mman.h b/arch/m68knommu/include/asm/mman.h deleted file mode 100644 index 4846c682efe..00000000000 --- a/arch/m68knommu/include/asm/mman.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/mmu.h b/arch/m68knommu/include/asm/mmu.h deleted file mode 100644 index e2da1e6f09f..00000000000 --- a/arch/m68knommu/include/asm/mmu.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __M68KNOMMU_MMU_H -#define __M68KNOMMU_MMU_H - -/* Copyright (C) 2002, David McCullough */ - -typedef struct { - unsigned long end_brk; -} mm_context_t; - -#endif /* __M68KNOMMU_MMU_H */ diff --git a/arch/m68knommu/include/asm/mmu_context.h b/arch/m68knommu/include/asm/mmu_context.h deleted file mode 100644 index 9ccee4278c9..00000000000 --- a/arch/m68knommu/include/asm/mmu_context.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __M68KNOMMU_MMU_CONTEXT_H -#define __M68KNOMMU_MMU_CONTEXT_H - -#include -#include -#include -#include - -static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) -{ -} - -static inline int -init_new_context(struct task_struct *tsk, struct mm_struct *mm) -{ - // mm->context = virt_to_phys(mm->pgd); - return(0); -} - -#define destroy_context(mm) do { } while(0) - -static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) -{ -} - -#define deactivate_mm(tsk,mm) do { } while (0) - -static inline void activate_mm(struct mm_struct *prev_mm, - struct mm_struct *next_mm) -{ -} - -#endif diff --git a/arch/m68knommu/include/asm/module.h b/arch/m68knommu/include/asm/module.h deleted file mode 100644 index 2e45ab50b23..00000000000 --- a/arch/m68knommu/include/asm/module.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef ASM_M68KNOMMU_MODULE_H -#define ASM_M68KNOMMU_MODULE_H - -struct mod_arch_specific { -}; - -#define Elf_Shdr Elf32_Shdr -#define Elf_Sym Elf32_Sym -#define Elf_Ehdr Elf32_Ehdr - -#endif /* ASM_M68KNOMMU_MODULE_H */ diff --git a/arch/m68knommu/include/asm/movs.h b/arch/m68knommu/include/asm/movs.h deleted file mode 100644 index 81a16779e83..00000000000 --- a/arch/m68knommu/include/asm/movs.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/msgbuf.h b/arch/m68knommu/include/asm/msgbuf.h deleted file mode 100644 index bdfadec4d52..00000000000 --- a/arch/m68knommu/include/asm/msgbuf.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/mutex.h b/arch/m68knommu/include/asm/mutex.h deleted file mode 100644 index 458c1f7fbc1..00000000000 --- a/arch/m68knommu/include/asm/mutex.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Pull in the generic implementation for the mutex fastpath. - * - * TODO: implement optimized primitives instead, or leave the generic - * implementation in place, or pick the atomic_xchg() based generic - * implementation. (see asm-generic/mutex-xchg.h for details) - */ - -#include diff --git a/arch/m68knommu/include/asm/nettel.h b/arch/m68knommu/include/asm/nettel.h deleted file mode 100644 index 0299f6a2dee..00000000000 --- a/arch/m68knommu/include/asm/nettel.h +++ /dev/null @@ -1,108 +0,0 @@ -/****************************************************************************/ - -/* - * nettel.h -- Lineo (formerly Moreton Bay) NETtel support. - * - * (C) Copyright 1999-2000, Moreton Bay (www.moretonbay.com) - * (C) Copyright 2000-2001, Lineo Inc. (www.lineo.com) - * (C) Copyright 2001-2002, SnapGear Inc., (www.snapgear.com) - */ - -/****************************************************************************/ -#ifndef nettel_h -#define nettel_h -/****************************************************************************/ - - -/****************************************************************************/ -#ifdef CONFIG_NETtel -/****************************************************************************/ - -#ifdef CONFIG_COLDFIRE -#include -#include -#endif - -/*---------------------------------------------------------------------------*/ -#if defined(CONFIG_M5307) -/* - * NETtel/5307 based hardware first. DTR/DCD lines are wired to - * GPIO lines. Most of the LED's are driver through a latch - * connected to CS2. - */ -#define MCFPP_DCD1 0x0001 -#define MCFPP_DCD0 0x0002 -#define MCFPP_DTR1 0x0004 -#define MCFPP_DTR0 0x0008 - -#define NETtel_LEDADDR 0x30400000 - -#ifndef __ASSEMBLY__ - -extern volatile unsigned short ppdata; - -/* - * These functions defined to give quasi generic access to the - * PPIO bits used for DTR/DCD. - */ -static __inline__ unsigned int mcf_getppdata(void) -{ - volatile unsigned short *pp; - pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT); - return((unsigned int) *pp); -} - -static __inline__ void mcf_setppdata(unsigned int mask, unsigned int bits) -{ - volatile unsigned short *pp; - pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT); - ppdata = (ppdata & ~mask) | bits; - *pp = ppdata; -} -#endif - -/*---------------------------------------------------------------------------*/ -#elif defined(CONFIG_M5206e) -/* - * NETtel/5206e based hardware has leds on latch on CS3. - * No support modem for lines?? - */ -#define NETtel_LEDADDR 0x50000000 - -/*---------------------------------------------------------------------------*/ -#elif defined(CONFIG_M5272) -/* - * NETtel/5272 based hardware. DTR/DCD lines are wired to GPB lines. - */ -#define MCFPP_DCD0 0x0080 -#define MCFPP_DCD1 0x0000 /* Port 1 no DCD support */ -#define MCFPP_DTR0 0x0040 -#define MCFPP_DTR1 0x0000 /* Port 1 no DTR support */ - -#ifndef __ASSEMBLY__ -/* - * These functions defined to give quasi generic access to the - * PPIO bits used for DTR/DCD. - */ -static __inline__ unsigned int mcf_getppdata(void) -{ - volatile unsigned short *pp; - pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PBDAT); - return((unsigned int) *pp); -} - -static __inline__ void mcf_setppdata(unsigned int mask, unsigned int bits) -{ - volatile unsigned short *pp; - pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PBDAT); - *pp = (*pp & ~mask) | bits; -} -#endif - -#endif -/*---------------------------------------------------------------------------*/ - -/****************************************************************************/ -#endif /* CONFIG_NETtel */ -/****************************************************************************/ -#endif /* nettel_h */ diff --git a/arch/m68knommu/include/asm/openprom.h b/arch/m68knommu/include/asm/openprom.h deleted file mode 100644 index fdba7953ff9..00000000000 --- a/arch/m68knommu/include/asm/openprom.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/oplib.h b/arch/m68knommu/include/asm/oplib.h deleted file mode 100644 index ce079dc332d..00000000000 --- a/arch/m68knommu/include/asm/oplib.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/page.h b/arch/m68knommu/include/asm/page.h deleted file mode 100644 index 3a1ede4544c..00000000000 --- a/arch/m68knommu/include/asm/page.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef _M68KNOMMU_PAGE_H -#define _M68KNOMMU_PAGE_H - -/* PAGE_SHIFT determines the page size */ - -#define PAGE_SHIFT (12) -#define PAGE_SIZE (1UL << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) - -#include - -#ifndef __ASSEMBLY__ - -#define get_user_page(vaddr) __get_free_page(GFP_KERNEL) -#define free_user_page(page, addr) free_page(addr) - -#define clear_page(page) memset((page), 0, PAGE_SIZE) -#define copy_page(to,from) memcpy((to), (from), PAGE_SIZE) - -#define clear_user_page(page, vaddr, pg) clear_page(page) -#define copy_user_page(to, from, vaddr, pg) copy_page(to, from) - -#define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \ - alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr) -#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE - -/* - * These are used to make use of C type-checking.. - */ -typedef struct { unsigned long pte; } pte_t; -typedef struct { unsigned long pmd[16]; } pmd_t; -typedef struct { unsigned long pgd; } pgd_t; -typedef struct { unsigned long pgprot; } pgprot_t; -typedef struct page *pgtable_t; - -#define pte_val(x) ((x).pte) -#define pmd_val(x) ((&x)->pmd[0]) -#define pgd_val(x) ((x).pgd) -#define pgprot_val(x) ((x).pgprot) - -#define __pte(x) ((pte_t) { (x) } ) -#define __pmd(x) ((pmd_t) { (x) } ) -#define __pgd(x) ((pgd_t) { (x) } ) -#define __pgprot(x) ((pgprot_t) { (x) } ) - -extern unsigned long memory_start; -extern unsigned long memory_end; - -#endif /* !__ASSEMBLY__ */ - -#include - -#define PAGE_OFFSET (PAGE_OFFSET_RAW) - -#ifndef __ASSEMBLY__ - -#define __pa(vaddr) virt_to_phys((void *)(vaddr)) -#define __va(paddr) phys_to_virt((unsigned long)(paddr)) - -#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) -#define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT) - -#define virt_to_page(addr) (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)) -#define page_to_virt(page) ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET) - -#define pfn_to_page(pfn) virt_to_page(pfn_to_virt(pfn)) -#define page_to_pfn(page) virt_to_pfn(page_to_virt(page)) -#define pfn_valid(pfn) ((pfn) < max_mapnr) - -#define virt_addr_valid(kaddr) (((void *)(kaddr) >= (void *)PAGE_OFFSET) && \ - ((void *)(kaddr) < (void *)memory_end)) - -#endif /* __ASSEMBLY__ */ - -#include - -#endif /* _M68KNOMMU_PAGE_H */ diff --git a/arch/m68knommu/include/asm/page_offset.h b/arch/m68knommu/include/asm/page_offset.h deleted file mode 100644 index d4e73e0ba64..00000000000 --- a/arch/m68knommu/include/asm/page_offset.h +++ /dev/null @@ -1,5 +0,0 @@ - - -/* This handles the memory map.. */ -#define PAGE_OFFSET_RAW CONFIG_RAMBASE - diff --git a/arch/m68knommu/include/asm/param.h b/arch/m68knommu/include/asm/param.h deleted file mode 100644 index 6044397adb6..00000000000 --- a/arch/m68knommu/include/asm/param.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _M68KNOMMU_PARAM_H -#define _M68KNOMMU_PARAM_H - -#ifdef __KERNEL__ -#define HZ CONFIG_HZ -#define USER_HZ HZ -#define CLOCKS_PER_SEC (USER_HZ) -#endif - -#ifndef HZ -#define HZ 100 -#endif - -#define EXEC_PAGESIZE 4096 - -#ifndef NOGROUP -#define NOGROUP (-1) -#endif - -#define MAXHOSTNAMELEN 64 /* max length of hostname */ - -#endif /* _M68KNOMMU_PARAM_H */ diff --git a/arch/m68knommu/include/asm/pci.h b/arch/m68knommu/include/asm/pci.h deleted file mode 100644 index a13f3cc8745..00000000000 --- a/arch/m68knommu/include/asm/pci.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef M68KNOMMU_PCI_H -#define M68KNOMMU_PCI_H - -#include - -#ifdef CONFIG_COMEMPCI -/* - * These are pretty much arbitary with the CoMEM implementation. - * We have the whole address space to ourselves. - */ -#define PCIBIOS_MIN_IO 0x100 -#define PCIBIOS_MIN_MEM 0x00010000 - -#define pcibios_scan_all_fns(a, b) 0 - -/* - * Return whether the given PCI device DMA address mask can - * be supported properly. For example, if your device can - * only drive the low 24-bits during PCI bus mastering, then - * you would pass 0x00ffffff as the mask to this function. - */ -static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask) -{ - return 1; -} - -#endif /* CONFIG_COMEMPCI */ - -#endif /* M68KNOMMU_PCI_H */ diff --git a/arch/m68knommu/include/asm/percpu.h b/arch/m68knommu/include/asm/percpu.h deleted file mode 100644 index 5de72c327ef..00000000000 --- a/arch/m68knommu/include/asm/percpu.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ARCH_M68KNOMMU_PERCPU__ -#define __ARCH_M68KNOMMU_PERCPU__ - -#include - -#endif /* __ARCH_M68KNOMMU_PERCPU__ */ diff --git a/arch/m68knommu/include/asm/pgalloc.h b/arch/m68knommu/include/asm/pgalloc.h deleted file mode 100644 index d6352f671ec..00000000000 --- a/arch/m68knommu/include/asm/pgalloc.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _M68KNOMMU_PGALLOC_H -#define _M68KNOMMU_PGALLOC_H - -#include - -#define check_pgt_cache() do { } while (0) - -#endif /* _M68KNOMMU_PGALLOC_H */ diff --git a/arch/m68knommu/include/asm/pgtable.h b/arch/m68knommu/include/asm/pgtable.h deleted file mode 100644 index 46251016e82..00000000000 --- a/arch/m68knommu/include/asm/pgtable.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef _M68KNOMMU_PGTABLE_H -#define _M68KNOMMU_PGTABLE_H - -#include - -/* - * (C) Copyright 2000-2002, Greg Ungerer - */ - -#include -#include -#include -#include - -/* - * Trivial page table functions. - */ -#define pgd_present(pgd) (1) -#define pgd_none(pgd) (0) -#define pgd_bad(pgd) (0) -#define pgd_clear(pgdp) -#define kern_addr_valid(addr) (1) -#define pmd_offset(a, b) ((void *)0) - -#define PAGE_NONE __pgprot(0) -#define PAGE_SHARED __pgprot(0) -#define PAGE_COPY __pgprot(0) -#define PAGE_READONLY __pgprot(0) -#define PAGE_KERNEL __pgprot(0) - -extern void paging_init(void); -#define swapper_pg_dir ((pgd_t *) 0) - -#define __swp_type(x) (0) -#define __swp_offset(x) (0) -#define __swp_entry(typ,off) ((swp_entry_t) { ((typ) | ((off) << 7)) }) -#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) -#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) - -static inline int pte_file(pte_t pte) { return 0; } - -/* - * ZERO_PAGE is a global shared page that is always zero: used - * for zero-mapped memory areas etc.. - */ -#define ZERO_PAGE(vaddr) (virt_to_page(0)) - -/* - * These would be in other places but having them here reduces the diffs. - */ -extern unsigned int kobjsize(const void *objp); - -/* - * No page table caches to initialise. - */ -#define pgtable_cache_init() do { } while (0) - -#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ - remap_pfn_range(vma, vaddr, pfn, size, prot) - -/* - * All 32bit addresses are effectively valid for vmalloc... - * Sort of meaningless for non-VM targets. - */ -#define VMALLOC_START 0 -#define VMALLOC_END 0xffffffff - -#include - -#endif /* _M68KNOMMU_PGTABLE_H */ diff --git a/arch/m68knommu/include/asm/poll.h b/arch/m68knommu/include/asm/poll.h deleted file mode 100644 index ee1b6cb549c..00000000000 --- a/arch/m68knommu/include/asm/poll.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/posix_types.h b/arch/m68knommu/include/asm/posix_types.h deleted file mode 100644 index 6205fb9392a..00000000000 --- a/arch/m68knommu/include/asm/posix_types.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/processor.h b/arch/m68knommu/include/asm/processor.h deleted file mode 100644 index 91cba18acdd..00000000000 --- a/arch/m68knommu/include/asm/processor.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * include/asm-m68knommu/processor.h - * - * Copyright (C) 1995 Hamish Macdonald - */ - -#ifndef __ASM_M68K_PROCESSOR_H -#define __ASM_M68K_PROCESSOR_H - -/* - * Default implementation of macro that returns current - * instruction pointer ("program counter"). - */ -#define current_text_addr() ({ __label__ _l; _l: &&_l;}) - -#include -#include -#include -#include -#include -#include -#include - -static inline unsigned long rdusp(void) -{ -#ifdef CONFIG_COLDFIRE - extern unsigned int sw_usp; - return(sw_usp); -#else - unsigned long usp; - __asm__ __volatile__("move %/usp,%0" : "=a" (usp)); - return usp; -#endif -} - -static inline void wrusp(unsigned long usp) -{ -#ifdef CONFIG_COLDFIRE - extern unsigned int sw_usp; - sw_usp = usp; -#else - __asm__ __volatile__("move %0,%/usp" : : "a" (usp)); -#endif -} - -/* - * User space process size: 3.75GB. This is hardcoded into a few places, - * so don't change it unless you know what you are doing. - */ -#define TASK_SIZE (0xF0000000UL) - -/* - * This decides where the kernel will search for a free chunk of vm - * space during mmap's. We won't be using it - */ -#define TASK_UNMAPPED_BASE 0 - -/* - * if you change this structure, you must change the code and offsets - * in m68k/machasm.S - */ - -struct thread_struct { - unsigned long ksp; /* kernel stack pointer */ - unsigned long usp; /* user stack pointer */ - unsigned short sr; /* saved status register */ - unsigned short fs; /* saved fs (sfc, dfc) */ - unsigned long crp[2]; /* cpu root pointer */ - unsigned long esp0; /* points to SR of stack frame */ - unsigned long fp[8*3]; - unsigned long fpcntl[3]; /* fp control regs */ - unsigned char fpstate[FPSTATESIZE]; /* floating point state */ -}; - -#define INIT_THREAD { \ - sizeof(init_stack) + (unsigned long) init_stack, 0, \ - PS_S, __KERNEL_DS, \ - {0, 0}, 0, {0,}, {0, 0, 0}, {0,}, \ -} - -/* - * Coldfire stacks need to be re-aligned on trap exit, conventional - * 68k can handle this case cleanly. - */ -#if defined(CONFIG_COLDFIRE) -#define reformat(_regs) do { (_regs)->format = 0x4; } while(0) -#else -#define reformat(_regs) do { } while (0) -#endif - -/* - * Do necessary setup to start up a newly executed thread. - * - * pass the data segment into user programs if it exists, - * it can't hurt anything as far as I can tell - */ -#define start_thread(_regs, _pc, _usp) \ -do { \ - set_fs(USER_DS); /* reads from user space */ \ - (_regs)->pc = (_pc); \ - ((struct switch_stack *)(_regs))[-1].a6 = 0; \ - reformat(_regs); \ - if (current->mm) \ - (_regs)->d5 = current->mm->start_data; \ - (_regs)->sr &= ~0x2000; \ - wrusp(_usp); \ -} while(0) - -/* Forward declaration, a strange C thing */ -struct task_struct; - -/* Free all resources held by a thread. */ -static inline void release_thread(struct task_struct *dead_task) -{ -} - -/* Prepare to copy thread state - unlazy all lazy status */ -#define prepare_to_copy(tsk) do { } while (0) - -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); - -/* - * Free current thread data structures etc.. - */ -static inline void exit_thread(void) -{ -} - -unsigned long thread_saved_pc(struct task_struct *tsk); -unsigned long get_wchan(struct task_struct *p); - -#define KSTK_EIP(tsk) \ - ({ \ - unsigned long eip = 0; \ - if ((tsk)->thread.esp0 > PAGE_SIZE && \ - (virt_addr_valid((tsk)->thread.esp0))) \ - eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \ - eip; }) -#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) - -#define cpu_relax() barrier() - -#endif diff --git a/arch/m68knommu/include/asm/ptrace.h b/arch/m68knommu/include/asm/ptrace.h deleted file mode 100644 index 8c9194b9854..00000000000 --- a/arch/m68knommu/include/asm/ptrace.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef _M68K_PTRACE_H -#define _M68K_PTRACE_H - -#define PT_D1 0 -#define PT_D2 1 -#define PT_D3 2 -#define PT_D4 3 -#define PT_D5 4 -#define PT_D6 5 -#define PT_D7 6 -#define PT_A0 7 -#define PT_A1 8 -#define PT_A2 9 -#define PT_A3 10 -#define PT_A4 11 -#define PT_A5 12 -#define PT_A6 13 -#define PT_D0 14 -#define PT_USP 15 -#define PT_ORIG_D0 16 -#define PT_SR 17 -#define PT_PC 18 - -#ifndef __ASSEMBLY__ - -/* this struct defines the way the registers are stored on the - stack during a system call. */ - -struct pt_regs { - long d1; - long d2; - long d3; - long d4; - long d5; - long a0; - long a1; - long a2; - long d0; - long orig_d0; - long stkadj; -#ifdef CONFIG_COLDFIRE - unsigned format : 4; /* frame format specifier */ - unsigned vector : 12; /* vector offset */ - unsigned short sr; - unsigned long pc; -#else - unsigned short sr; - unsigned long pc; - unsigned format : 4; /* frame format specifier */ - unsigned vector : 12; /* vector offset */ -#endif -}; - -/* - * This is the extended stack used by signal handlers and the context - * switcher: it's pushed after the normal "struct pt_regs". - */ -struct switch_stack { - unsigned long d6; - unsigned long d7; - unsigned long a3; - unsigned long a4; - unsigned long a5; - unsigned long a6; - unsigned long retpc; -}; - -/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ -#define PTRACE_GETREGS 12 -#define PTRACE_SETREGS 13 -#define PTRACE_GETFPREGS 14 -#define PTRACE_SETFPREGS 15 - -#ifdef __KERNEL__ - -#ifndef PS_S -#define PS_S (0x2000) -#define PS_M (0x1000) -#endif - -#define user_mode(regs) (!((regs)->sr & PS_S)) -#define instruction_pointer(regs) ((regs)->pc) -#define profile_pc(regs) instruction_pointer(regs) -extern void show_regs(struct pt_regs *); -#endif /* __KERNEL__ */ -#endif /* __ASSEMBLY__ */ -#endif /* _M68K_PTRACE_H */ diff --git a/arch/m68knommu/include/asm/quicc_simple.h b/arch/m68knommu/include/asm/quicc_simple.h deleted file mode 100644 index c3636932d4b..00000000000 --- a/arch/m68knommu/include/asm/quicc_simple.h +++ /dev/null @@ -1,52 +0,0 @@ -/*********************************** - * $Id: quicc_simple.h,v 1.1 2002/03/02 15:01:10 gerg Exp $ - *********************************** - * - *************************************** - * Simple drivers common header - *************************************** - */ - -#ifndef __SIMPLE_H -#define __SIMPLE_H - -/* #include "quicc.h" */ - -#define GLB_SCC_0 0 -#define GLB_SCC_1 1 -#define GLB_SCC_2 2 -#define GLB_SCC_3 3 - -typedef void (int_routine)(unsigned short interrupt_event); -typedef int_routine *int_routine_ptr; -typedef void *(alloc_routine)(int length); -typedef void (free_routine)(int scc_num, int channel_num, void *buf); -typedef void (store_rx_buffer_routine)(int scc_num, int channel_num, void *buff, int length); -typedef int (handle_tx_error_routine)(int scc_num, int channel_num, QUICC_BD *tbd); -typedef void (handle_rx_error_routine)(int scc_num, int channel_num, QUICC_BD *rbd); -typedef void (handle_lost_error_routine)(int scc_num, int channel_num); - -/* user defined functions for global errors */ -typedef void (handle_glob_overrun_routine)(int scc_number); -typedef void (handle_glob_underrun_routine)(int scc_number); -typedef void (glob_intr_q_overflow_routine)(int scc_number); - -/* - * General initialization and command routines - */ -void quicc_issue_cmd (unsigned short cmd, int scc_num); -void quicc_init(void); -void quicc_scc_init(int scc_number, int number_of_rx_buf, int number_of_tx_buf); -void quicc_smc_init(int smc_number, int number_of_rx_buf, int number_of_tx_buf); -void quicc_scc_start(int scc_num); -void quicc_scc_loopback(int scc_num); - -/* Interrupt enable/disable routines for critical pieces of code*/ -unsigned short IntrDis(void); -void IntrEna(unsigned short old_sr); - -/* For debugging */ -void print_rbd(int scc_num); -void print_tbd(int scc_num); - -#endif diff --git a/arch/m68knommu/include/asm/resource.h b/arch/m68knommu/include/asm/resource.h deleted file mode 100644 index 7fa63d5ea57..00000000000 --- a/arch/m68knommu/include/asm/resource.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/rtc.h b/arch/m68knommu/include/asm/rtc.h deleted file mode 100644 index eaf18ec83c8..00000000000 --- a/arch/m68knommu/include/asm/rtc.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/scatterlist.h b/arch/m68knommu/include/asm/scatterlist.h deleted file mode 100644 index afc4788b0d2..00000000000 --- a/arch/m68knommu/include/asm/scatterlist.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _M68KNOMMU_SCATTERLIST_H -#define _M68KNOMMU_SCATTERLIST_H - -#include -#include - -struct scatterlist { -#ifdef CONFIG_DEBUG_SG - unsigned long sg_magic; -#endif - unsigned long page_link; - unsigned int offset; - dma_addr_t dma_address; - unsigned int length; -}; - -#define sg_dma_address(sg) ((sg)->dma_address) -#define sg_dma_len(sg) ((sg)->length) - -#define ISA_DMA_THRESHOLD (0xffffffff) - -#endif /* !(_M68KNOMMU_SCATTERLIST_H) */ diff --git a/arch/m68knommu/include/asm/sections.h b/arch/m68knommu/include/asm/sections.h deleted file mode 100644 index dd0ecb98ec0..00000000000 --- a/arch/m68knommu/include/asm/sections.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _M68KNOMMU_SECTIONS_H -#define _M68KNOMMU_SECTIONS_H - -/* nothing to see, move along */ -#include - -#endif diff --git a/arch/m68knommu/include/asm/segment.h b/arch/m68knommu/include/asm/segment.h deleted file mode 100644 index 42318ebec7e..00000000000 --- a/arch/m68knommu/include/asm/segment.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef _M68K_SEGMENT_H -#define _M68K_SEGMENT_H - -/* define constants */ -/* Address spaces (FC0-FC2) */ -#define USER_DATA (1) -#ifndef __USER_DS -#define __USER_DS (USER_DATA) -#endif -#define USER_PROGRAM (2) -#define SUPER_DATA (5) -#ifndef __KERNEL_DS -#define __KERNEL_DS (SUPER_DATA) -#endif -#define SUPER_PROGRAM (6) -#define CPU_SPACE (7) - -#ifndef __ASSEMBLY__ - -typedef struct { - unsigned long seg; -} mm_segment_t; - -#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) -#define USER_DS MAKE_MM_SEG(__USER_DS) -#define KERNEL_DS MAKE_MM_SEG(__KERNEL_DS) - -/* - * Get/set the SFC/DFC registers for MOVES instructions - */ - -static inline mm_segment_t get_fs(void) -{ - return USER_DS; -} - -static inline mm_segment_t get_ds(void) -{ - /* return the supervisor data space code */ - return KERNEL_DS; -} - -static inline void set_fs(mm_segment_t val) -{ -} - -#define segment_eq(a,b) ((a).seg == (b).seg) - -#endif /* __ASSEMBLY__ */ - -#endif /* _M68K_SEGMENT_H */ diff --git a/arch/m68knommu/include/asm/sembuf.h b/arch/m68knommu/include/asm/sembuf.h deleted file mode 100644 index 3a634f9ecf5..00000000000 --- a/arch/m68knommu/include/asm/sembuf.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/setup.h b/arch/m68knommu/include/asm/setup.h deleted file mode 100644 index fb86bb2a607..00000000000 --- a/arch/m68knommu/include/asm/setup.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifdef __KERNEL__ - -#include - -/* We have a bigger command line buffer. */ -#undef COMMAND_LINE_SIZE - -#endif /* __KERNEL__ */ - -#define COMMAND_LINE_SIZE 512 diff --git a/arch/m68knommu/include/asm/shm.h b/arch/m68knommu/include/asm/shm.h deleted file mode 100644 index cc8e522d905..00000000000 --- a/arch/m68knommu/include/asm/shm.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/shmbuf.h b/arch/m68knommu/include/asm/shmbuf.h deleted file mode 100644 index bc34cf8eefc..00000000000 --- a/arch/m68knommu/include/asm/shmbuf.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/shmparam.h b/arch/m68knommu/include/asm/shmparam.h deleted file mode 100644 index d7ee69648eb..00000000000 --- a/arch/m68knommu/include/asm/shmparam.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/sigcontext.h b/arch/m68knommu/include/asm/sigcontext.h deleted file mode 100644 index 36c293fc133..00000000000 --- a/arch/m68knommu/include/asm/sigcontext.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef _ASM_M68KNOMMU_SIGCONTEXT_H -#define _ASM_M68KNOMMU_SIGCONTEXT_H - -struct sigcontext { - unsigned long sc_mask; /* old sigmask */ - unsigned long sc_usp; /* old user stack pointer */ - unsigned long sc_d0; - unsigned long sc_d1; - unsigned long sc_a0; - unsigned long sc_a1; - unsigned long sc_a5; - unsigned short sc_sr; - unsigned long sc_pc; - unsigned short sc_formatvec; -}; - -#endif diff --git a/arch/m68knommu/include/asm/siginfo.h b/arch/m68knommu/include/asm/siginfo.h deleted file mode 100644 index b18e5f4064a..00000000000 --- a/arch/m68knommu/include/asm/siginfo.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _M68KNOMMU_SIGINFO_H -#define _M68KNOMMU_SIGINFO_H - -#include - -#endif diff --git a/arch/m68knommu/include/asm/signal.h b/arch/m68knommu/include/asm/signal.h deleted file mode 100644 index 216c08be54a..00000000000 --- a/arch/m68knommu/include/asm/signal.h +++ /dev/null @@ -1,159 +0,0 @@ -#ifndef _M68KNOMMU_SIGNAL_H -#define _M68KNOMMU_SIGNAL_H - -#include - -/* Avoid too many header ordering problems. */ -struct siginfo; - -#ifdef __KERNEL__ -/* Most things should be clean enough to redefine this at will, if care - is taken to make libc match. */ - -#define _NSIG 64 -#define _NSIG_BPW 32 -#define _NSIG_WORDS (_NSIG / _NSIG_BPW) - -typedef unsigned long old_sigset_t; /* at least 32 bits */ - -typedef struct { - unsigned long sig[_NSIG_WORDS]; -} sigset_t; - -#else -/* Here we must cater to libcs that poke about in kernel headers. */ - -#define NSIG 32 -typedef unsigned long sigset_t; - -#endif /* __KERNEL__ */ - -#define SIGHUP 1 -#define SIGINT 2 -#define SIGQUIT 3 -#define SIGILL 4 -#define SIGTRAP 5 -#define SIGABRT 6 -#define SIGIOT 6 -#define SIGBUS 7 -#define SIGFPE 8 -#define SIGKILL 9 -#define SIGUSR1 10 -#define SIGSEGV 11 -#define SIGUSR2 12 -#define SIGPIPE 13 -#define SIGALRM 14 -#define SIGTERM 15 -#define SIGSTKFLT 16 -#define SIGCHLD 17 -#define SIGCONT 18 -#define SIGSTOP 19 -#define SIGTSTP 20 -#define SIGTTIN 21 -#define SIGTTOU 22 -#define SIGURG 23 -#define SIGXCPU 24 -#define SIGXFSZ 25 -#define SIGVTALRM 26 -#define SIGPROF 27 -#define SIGWINCH 28 -#define SIGIO 29 -#define SIGPOLL SIGIO -/* -#define SIGLOST 29 -*/ -#define SIGPWR 30 -#define SIGSYS 31 -#define SIGUNUSED 31 - -/* These should not be considered constants from userland. */ -#define SIGRTMIN 32 -#define SIGRTMAX _NSIG - -/* - * SA_FLAGS values: - * - * SA_ONSTACK indicates that a registered stack_t will be used. - * SA_RESTART flag to get restarting signals (which were the default long ago) - * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. - * SA_RESETHAND clears the handler when the signal is delivered. - * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. - * SA_NODEFER prevents the current signal from being masked in the handler. - * - * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single - * Unix names RESETHAND and NODEFER respectively. - */ -#define SA_NOCLDSTOP 0x00000001 -#define SA_NOCLDWAIT 0x00000002 -#define SA_SIGINFO 0x00000004 -#define SA_ONSTACK 0x08000000 -#define SA_RESTART 0x10000000 -#define SA_NODEFER 0x40000000 -#define SA_RESETHAND 0x80000000 - -#define SA_NOMASK SA_NODEFER -#define SA_ONESHOT SA_RESETHAND - -/* - * sigaltstack controls - */ -#define SS_ONSTACK 1 -#define SS_DISABLE 2 - -#define MINSIGSTKSZ 2048 -#define SIGSTKSZ 8192 - -#include - -#ifdef __KERNEL__ -struct old_sigaction { - __sighandler_t sa_handler; - old_sigset_t sa_mask; - unsigned long sa_flags; - void (*sa_restorer)(void); -}; - -struct sigaction { - __sighandler_t sa_handler; - unsigned long sa_flags; - void (*sa_restorer)(void); - sigset_t sa_mask; /* mask last for extensibility */ -}; - -struct k_sigaction { - struct sigaction sa; -}; -#else -/* Here we must cater to libcs that poke about in kernel headers. */ - -struct sigaction { - union { - __sighandler_t _sa_handler; - void (*_sa_sigaction)(int, struct siginfo *, void *); - } _u; - sigset_t sa_mask; - unsigned long sa_flags; - void (*sa_restorer)(void); -}; - -#define sa_handler _u._sa_handler -#define sa_sigaction _u._sa_sigaction - -#endif /* __KERNEL__ */ - -typedef struct sigaltstack { - void *ss_sp; - int ss_flags; - size_t ss_size; -} stack_t; - -#ifdef __KERNEL__ - -#include -#undef __HAVE_ARCH_SIG_BITOPS - -#define ptrace_signal_deliver(regs, cookie) do { } while (0) - -#endif /* __KERNEL__ */ - -#endif /* _M68KNOMMU_SIGNAL_H */ diff --git a/arch/m68knommu/include/asm/smp.h b/arch/m68knommu/include/asm/smp.h deleted file mode 100644 index 9e9bd7e5892..00000000000 --- a/arch/m68knommu/include/asm/smp.h +++ /dev/null @@ -1 +0,0 @@ -/* nothing required here yet */ diff --git a/arch/m68knommu/include/asm/socket.h b/arch/m68knommu/include/asm/socket.h deleted file mode 100644 index ac5478bf637..00000000000 --- a/arch/m68knommu/include/asm/socket.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/sockios.h b/arch/m68knommu/include/asm/sockios.h deleted file mode 100644 index dcc6a8900ce..00000000000 --- a/arch/m68knommu/include/asm/sockios.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/spinlock.h b/arch/m68knommu/include/asm/spinlock.h deleted file mode 100644 index 6bb1f06c478..00000000000 --- a/arch/m68knommu/include/asm/spinlock.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/stat.h b/arch/m68knommu/include/asm/stat.h deleted file mode 100644 index 3d4b260e7c0..00000000000 --- a/arch/m68knommu/include/asm/stat.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/statfs.h b/arch/m68knommu/include/asm/statfs.h deleted file mode 100644 index 2ce99eaf097..00000000000 --- a/arch/m68knommu/include/asm/statfs.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/string.h b/arch/m68knommu/include/asm/string.h deleted file mode 100644 index af09e17000f..00000000000 --- a/arch/m68knommu/include/asm/string.h +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef _M68KNOMMU_STRING_H_ -#define _M68KNOMMU_STRING_H_ - -#ifdef __KERNEL__ /* only set these up for kernel code */ - -#include -#include - -#define __HAVE_ARCH_STRCPY -static inline char * strcpy(char * dest,const char *src) -{ - char *xdest = dest; - - __asm__ __volatile__ - ("1:\tmoveb %1@+,%0@+\n\t" - "jne 1b" - : "=a" (dest), "=a" (src) - : "0" (dest), "1" (src) : "memory"); - return xdest; -} - -#define __HAVE_ARCH_STRNCPY -static inline char * strncpy(char *dest, const char *src, size_t n) -{ - char *xdest = dest; - - if (n == 0) - return xdest; - - __asm__ __volatile__ - ("1:\tmoveb %1@+,%0@+\n\t" - "jeq 2f\n\t" - "subql #1,%2\n\t" - "jne 1b\n\t" - "2:" - : "=a" (dest), "=a" (src), "=d" (n) - : "0" (dest), "1" (src), "2" (n) - : "memory"); - return xdest; -} - - -#ifndef CONFIG_COLDFIRE - -#define __HAVE_ARCH_STRCMP -static inline int strcmp(const char * cs,const char * ct) -{ - char __res; - - __asm__ - ("1:\tmoveb %0@+,%2\n\t" /* get *cs */ - "cmpb %1@+,%2\n\t" /* compare a byte */ - "jne 2f\n\t" /* not equal, break out */ - "tstb %2\n\t" /* at end of cs? */ - "jne 1b\n\t" /* no, keep going */ - "jra 3f\n\t" /* strings are equal */ - "2:\tsubb %1@-,%2\n\t" /* *cs - *ct */ - "3:" - : "=a" (cs), "=a" (ct), "=d" (__res) - : "0" (cs), "1" (ct)); - - return __res; -} - -#define __HAVE_ARCH_STRNCMP -static inline int strncmp(const char * cs,const char * ct,size_t count) -{ - char __res; - - if (!count) - return 0; - __asm__ - ("1:\tmovb %0@+,%3\n\t" /* get *cs */ - "cmpb %1@+,%3\n\t" /* compare a byte */ - "jne 3f\n\t" /* not equal, break out */ - "tstb %3\n\t" /* at end of cs? */ - "jeq 4f\n\t" /* yes, all done */ - "subql #1,%2\n\t" /* no, adjust count */ - "jne 1b\n\t" /* more to do, keep going */ - "2:\tmoveq #0,%3\n\t" /* strings are equal */ - "jra 4f\n\t" - "3:\tsubb %1@-,%3\n\t" /* *cs - *ct */ - "4:" - : "=a" (cs), "=a" (ct), "=d" (count), "=d" (__res) - : "0" (cs), "1" (ct), "2" (count)); - return __res; -} - -#endif /* CONFIG_COLDFIRE */ - -#define __HAVE_ARCH_MEMSET -extern void * memset(void * s, int c, size_t count); - -#define __HAVE_ARCH_MEMCPY -extern void * memcpy(void *d, const void *s, size_t count); - -#else /* KERNEL */ - -/* - * let user libraries deal with these, - * IMHO the kernel has no place defining these functions for user apps - */ - -#define __HAVE_ARCH_STRCPY 1 -#define __HAVE_ARCH_STRNCPY 1 -#define __HAVE_ARCH_STRCAT 1 -#define __HAVE_ARCH_STRNCAT 1 -#define __HAVE_ARCH_STRCMP 1 -#define __HAVE_ARCH_STRNCMP 1 -#define __HAVE_ARCH_STRNICMP 1 -#define __HAVE_ARCH_STRCHR 1 -#define __HAVE_ARCH_STRRCHR 1 -#define __HAVE_ARCH_STRSTR 1 -#define __HAVE_ARCH_STRLEN 1 -#define __HAVE_ARCH_STRNLEN 1 -#define __HAVE_ARCH_MEMSET 1 -#define __HAVE_ARCH_MEMCPY 1 -#define __HAVE_ARCH_MEMMOVE 1 -#define __HAVE_ARCH_MEMSCAN 1 -#define __HAVE_ARCH_MEMCMP 1 -#define __HAVE_ARCH_MEMCHR 1 -#define __HAVE_ARCH_STRTOK 1 - -#endif /* KERNEL */ - -#endif /* _M68K_STRING_H_ */ diff --git a/arch/m68knommu/include/asm/swab.h b/arch/m68knommu/include/asm/swab.h deleted file mode 100644 index e582257db30..00000000000 --- a/arch/m68knommu/include/asm/swab.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef _M68KNOMMU_SWAB_H -#define _M68KNOMMU_SWAB_H - -#include - -#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__) -# define __SWAB_64_THRU_32__ -#endif - -#if defined (__mcfisaaplus__) || defined (__mcfisac__) -static inline __attribute_const__ __u32 __arch_swab32(__u32 val) -{ - asm( - "byterev %0" - : "=d" (val) - : "0" (val) - ); - return val; -} - -#define __arch_swab32 __arch_swab32 -#endif - -#endif /* _M68KNOMMU_SWAB_H */ diff --git a/arch/m68knommu/include/asm/system.h b/arch/m68knommu/include/asm/system.h deleted file mode 100644 index 40f49de6982..00000000000 --- a/arch/m68knommu/include/asm/system.h +++ /dev/null @@ -1,324 +0,0 @@ -#ifndef _M68KNOMMU_SYSTEM_H -#define _M68KNOMMU_SYSTEM_H - -#include -#include -#include - -/* - * switch_to(n) should switch tasks to task ptr, first checking that - * ptr isn't the current task, in which case it does nothing. This - * also clears the TS-flag if the task we switched to has used the - * math co-processor latest. - */ -/* - * switch_to() saves the extra registers, that are not saved - * automatically by SAVE_SWITCH_STACK in resume(), ie. d0-d5 and - * a0-a1. Some of these are used by schedule() and its predecessors - * and so we might get see unexpected behaviors when a task returns - * with unexpected register values. - * - * syscall stores these registers itself and none of them are used - * by syscall after the function in the syscall has been called. - * - * Beware that resume now expects *next to be in d1 and the offset of - * tss to be in a1. This saves a few instructions as we no longer have - * to push them onto the stack and read them back right after. - * - * 02/17/96 - Jes Sorensen (jds@kom.auc.dk) - * - * Changed 96/09/19 by Andreas Schwab - * pass prev in a0, next in a1, offset of tss in d1, and whether - * the mm structures are shared in d2 (to avoid atc flushing). - */ -asmlinkage void resume(void); -#define switch_to(prev,next,last) \ -{ \ - void *_last; \ - __asm__ __volatile__( \ - "movel %1, %%a0\n\t" \ - "movel %2, %%a1\n\t" \ - "jbsr resume\n\t" \ - "movel %%d1, %0\n\t" \ - : "=d" (_last) \ - : "d" (prev), "d" (next) \ - : "cc", "d0", "d1", "d2", "d3", "d4", "d5", "a0", "a1"); \ - (last) = _last; \ -} - -#ifdef CONFIG_COLDFIRE -#define local_irq_enable() __asm__ __volatile__ ( \ - "move %/sr,%%d0\n\t" \ - "andi.l #0xf8ff,%%d0\n\t" \ - "move %%d0,%/sr\n" \ - : /* no outputs */ \ - : \ - : "cc", "%d0", "memory") -#define local_irq_disable() __asm__ __volatile__ ( \ - "move %/sr,%%d0\n\t" \ - "ori.l #0x0700,%%d0\n\t" \ - "move %%d0,%/sr\n" \ - : /* no outputs */ \ - : \ - : "cc", "%d0", "memory") -/* For spinlocks etc */ -#define local_irq_save(x) __asm__ __volatile__ ( \ - "movew %%sr,%0\n\t" \ - "movew #0x0700,%%d0\n\t" \ - "or.l %0,%%d0\n\t" \ - "movew %%d0,%/sr" \ - : "=d" (x) \ - : \ - : "cc", "%d0", "memory") -#else - -/* portable version */ /* FIXME - see entry.h*/ -#define ALLOWINT 0xf8ff - -#define local_irq_enable() asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory") -#define local_irq_disable() asm volatile ("oriw #0x0700,%%sr": : : "memory") -#endif - -#define local_save_flags(x) asm volatile ("movew %%sr,%0":"=d" (x) : : "memory") -#define local_irq_restore(x) asm volatile ("movew %0,%%sr": :"d" (x) : "memory") - -/* For spinlocks etc */ -#ifndef local_irq_save -#define local_irq_save(x) do { local_save_flags(x); local_irq_disable(); } while (0) -#endif - -#define irqs_disabled() \ -({ \ - unsigned long flags; \ - local_save_flags(flags); \ - ((flags & 0x0700) == 0x0700); \ -}) - -#define iret() __asm__ __volatile__ ("rte": : :"memory", "sp", "cc") - -/* - * Force strict CPU ordering. - * Not really required on m68k... - */ -#define nop() asm volatile ("nop"::) -#define mb() asm volatile ("" : : :"memory") -#define rmb() asm volatile ("" : : :"memory") -#define wmb() asm volatile ("" : : :"memory") -#define set_mb(var, value) ({ (var) = (value); wmb(); }) - -#ifdef CONFIG_SMP -#define smp_mb() mb() -#define smp_rmb() rmb() -#define smp_wmb() wmb() -#define smp_read_barrier_depends() read_barrier_depends() -#else -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() do { } while(0) -#endif - -#define read_barrier_depends() ((void)0) - -#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) - -struct __xchg_dummy { unsigned long a[100]; }; -#define __xg(x) ((volatile struct __xchg_dummy *)(x)) - -#ifndef CONFIG_RMW_INSNS -static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) -{ - unsigned long tmp, flags; - - local_irq_save(flags); - - switch (size) { - case 1: - __asm__ __volatile__ - ("moveb %2,%0\n\t" - "moveb %1,%2" - : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory"); - break; - case 2: - __asm__ __volatile__ - ("movew %2,%0\n\t" - "movew %1,%2" - : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory"); - break; - case 4: - __asm__ __volatile__ - ("movel %2,%0\n\t" - "movel %1,%2" - : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory"); - break; - } - local_irq_restore(flags); - return tmp; -} -#else -static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) -{ - switch (size) { - case 1: - __asm__ __volatile__ - ("moveb %2,%0\n\t" - "1:\n\t" - "casb %0,%1,%2\n\t" - "jne 1b" - : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); - break; - case 2: - __asm__ __volatile__ - ("movew %2,%0\n\t" - "1:\n\t" - "casw %0,%1,%2\n\t" - "jne 1b" - : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); - break; - case 4: - __asm__ __volatile__ - ("movel %2,%0\n\t" - "1:\n\t" - "casl %0,%1,%2\n\t" - "jne 1b" - : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); - break; - } - return x; -} -#endif - -#include - -/* - * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make - * them available. - */ -#define cmpxchg_local(ptr, o, n) \ - ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\ - (unsigned long)(n), sizeof(*(ptr)))) -#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) - -#ifndef CONFIG_SMP -#include -#endif - -#if defined( CONFIG_M68328 ) || defined( CONFIG_M68EZ328 ) || \ - defined (CONFIG_M68360) || defined( CONFIG_M68VZ328 ) -#define HARD_RESET_NOW() ({ \ - local_irq_disable(); \ - asm(" \ - moveal #0x10c00000, %a0; \ - moveb #0, 0xFFFFF300; \ - moveal 0(%a0), %sp; \ - moveal 4(%a0), %a0; \ - jmp (%a0); \ - "); \ -}) -#endif - -#ifdef CONFIG_COLDFIRE -#if defined(CONFIG_M5272) && defined(CONFIG_NETtel) -/* - * Need to account for broken early mask of 5272 silicon. So don't - * jump through the original start address. Jump strait into the - * known start of the FLASH code. - */ -#define HARD_RESET_NOW() ({ \ - asm(" \ - movew #0x2700, %sr; \ - jmp 0xf0000400; \ - "); \ -}) -#elif defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \ - defined(CONFIG_SECUREEDGEMP3) || defined(CONFIG_CLEOPATRA) -#define HARD_RESET_NOW() ({ \ - asm(" \ - movew #0x2700, %sr; \ - moveal #0x10000044, %a0; \ - movel #0xffffffff, (%a0); \ - moveal #0x10000001, %a0; \ - moveb #0x00, (%a0); \ - moveal #0xf0000004, %a0; \ - moveal (%a0), %a0; \ - jmp (%a0); \ - "); \ -}) -#elif defined(CONFIG_M5272) -/* - * Retrieve the boot address in flash using CSBR0 and CSOR0 - * find the reset vector at flash_address + 4 (e.g. 0x400) - * remap it in the flash's current location (e.g. 0xf0000400) - * and jump there. - */ -#define HARD_RESET_NOW() ({ \ - asm(" \ - movew #0x2700, %%sr; \ - move.l %0+0x40,%%d0; \ - and.l %0+0x44,%%d0; \ - andi.l #0xfffff000,%%d0; \ - mov.l %%d0,%%a0; \ - or.l 4(%%a0),%%d0; \ - mov.l %%d0,%%a0; \ - jmp (%%a0);" \ - : /* No output */ \ - : "o" (*(char *)MCF_MBAR) ); \ -}) -#elif defined(CONFIG_M528x) -/* - * The MCF528x has a bit (SOFTRST) in memory (Reset Control Register RCR), - * that when set, resets the MCF528x. - */ -#define HARD_RESET_NOW() \ -({ \ - unsigned char volatile *reset; \ - asm("move.w #0x2700, %sr"); \ - reset = ((volatile unsigned char *)(MCF_IPSBAR + 0x110000)); \ - while(1) \ - *reset |= (0x01 << 7);\ -}) -#elif defined(CONFIG_M523x) -#define HARD_RESET_NOW() ({ \ - asm(" \ - movew #0x2700, %sr; \ - movel #0x01000000, %sp; \ - moveal #0x40110000, %a0; \ - moveb #0x80, (%a0); \ - "); \ -}) -#elif defined(CONFIG_M520x) - /* - * The MCF5208 has a bit (SOFTRST) in memory (Reset Control Register - * RCR), that when set, resets the MCF5208. - */ -#define HARD_RESET_NOW() \ -({ \ - unsigned char volatile *reset; \ - asm("move.w #0x2700, %sr"); \ - reset = ((volatile unsigned char *)(MCF_IPSBAR + 0xA0000)); \ - while(1) \ - *reset |= 0x80; \ -}) -#else -#define HARD_RESET_NOW() ({ \ - asm(" \ - movew #0x2700, %sr; \ - moveal #0x4, %a0; \ - moveal (%a0), %a0; \ - jmp (%a0); \ - "); \ -}) -#endif -#endif -#define arch_align_stack(x) (x) - - -static inline int irqs_disabled_flags(unsigned long flags) -{ - if (flags & 0x0700) - return 0; - else - return 1; -} - -#endif /* _M68KNOMMU_SYSTEM_H */ diff --git a/arch/m68knommu/include/asm/termbits.h b/arch/m68knommu/include/asm/termbits.h deleted file mode 100644 index 05dd6bc2728..00000000000 --- a/arch/m68knommu/include/asm/termbits.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/termios.h b/arch/m68knommu/include/asm/termios.h deleted file mode 100644 index e7337881a98..00000000000 --- a/arch/m68knommu/include/asm/termios.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/thread_info.h b/arch/m68knommu/include/asm/thread_info.h deleted file mode 100644 index 82529f424ea..00000000000 --- a/arch/m68knommu/include/asm/thread_info.h +++ /dev/null @@ -1,100 +0,0 @@ -/* thread_info.h: m68knommu low-level thread information - * adapted from the i386 and PPC versions by Greg Ungerer (gerg@snapgear.com) - * - * Copyright (C) 2002 David Howells (dhowells@redhat.com) - * - Incorporating suggestions made by Linus Torvalds and Dave Miller - */ - -#ifndef _ASM_THREAD_INFO_H -#define _ASM_THREAD_INFO_H - -#include - -#ifdef __KERNEL__ - -#ifndef __ASSEMBLY__ - -/* - * Size of kernel stack for each process. This must be a power of 2... - */ -#ifdef CONFIG_4KSTACKS -#define THREAD_SIZE_ORDER (0) -#else -#define THREAD_SIZE_ORDER (1) -#endif - -/* - * for asm files, THREAD_SIZE is now generated by asm-offsets.c - */ -#define THREAD_SIZE (PAGE_SIZE< preemptable, <0 => BUG */ - struct restart_block restart_block; -}; - -/* - * macros/functions for gaining access to the thread information structure - */ -#define INIT_THREAD_INFO(tsk) \ -{ \ - .task = &tsk, \ - .exec_domain = &default_exec_domain, \ - .flags = 0, \ - .cpu = 0, \ - .restart_block = { \ - .fn = do_no_restart_syscall, \ - }, \ -} - -#define init_thread_info (init_thread_union.thread_info) -#define init_stack (init_thread_union.stack) - - -/* how to get the thread information struct from C */ -static inline struct thread_info *current_thread_info(void) -{ - struct thread_info *ti; - __asm__( - "move.l %%sp, %0 \n\t" - "and.l %1, %0" - : "=&d"(ti) - : "di" (~(THREAD_SIZE-1)) - ); - return ti; -} - -#endif /* __ASSEMBLY__ */ - -#define PREEMPT_ACTIVE 0x4000000 - -/* - * thread information flag bit numbers - */ -#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ -#define TIF_SIGPENDING 1 /* signal pending */ -#define TIF_NEED_RESCHED 2 /* rescheduling necessary */ -#define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling - TIF_NEED_RESCHED */ -#define TIF_MEMDIE 4 -#define TIF_FREEZE 16 /* is freezing for suspend */ - -/* as above, but as bit values */ -#define _TIF_SYSCALL_TRACE (1< -#define CLOCK_TICK_RATE MCF_CLK -#else -#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ -#endif - -typedef unsigned long cycles_t; - -static inline cycles_t get_cycles(void) -{ - return 0; -} - -#endif diff --git a/arch/m68knommu/include/asm/tlb.h b/arch/m68knommu/include/asm/tlb.h deleted file mode 100644 index 77a7c51ca29..00000000000 --- a/arch/m68knommu/include/asm/tlb.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/tlbflush.h b/arch/m68knommu/include/asm/tlbflush.h deleted file mode 100644 index a470cfb803e..00000000000 --- a/arch/m68knommu/include/asm/tlbflush.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef _M68KNOMMU_TLBFLUSH_H -#define _M68KNOMMU_TLBFLUSH_H - -/* - * Copyright (C) 2000 Lineo, David McCullough - * Copyright (C) 2000-2002, Greg Ungerer - */ - -#include - -/* - * flush all user-space atc entries. - */ -static inline void __flush_tlb(void) -{ - BUG(); -} - -static inline void __flush_tlb_one(unsigned long addr) -{ - BUG(); -} - -#define flush_tlb() __flush_tlb() - -/* - * flush all atc entries (both kernel and user-space entries). - */ -static inline void flush_tlb_all(void) -{ - BUG(); -} - -static inline void flush_tlb_mm(struct mm_struct *mm) -{ - BUG(); -} - -static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) -{ - BUG(); -} - -static inline void flush_tlb_range(struct mm_struct *mm, - unsigned long start, unsigned long end) -{ - BUG(); -} - -static inline void flush_tlb_kernel_page(unsigned long addr) -{ - BUG(); -} - -#endif /* _M68KNOMMU_TLBFLUSH_H */ diff --git a/arch/m68knommu/include/asm/topology.h b/arch/m68knommu/include/asm/topology.h deleted file mode 100644 index ca173e9f26f..00000000000 --- a/arch/m68knommu/include/asm/topology.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_M68K_TOPOLOGY_H -#define _ASM_M68K_TOPOLOGY_H - -#include - -#endif /* _ASM_M68K_TOPOLOGY_H */ diff --git a/arch/m68knommu/include/asm/traps.h b/arch/m68knommu/include/asm/traps.h deleted file mode 100644 index d0671e5f8e2..00000000000 --- a/arch/m68knommu/include/asm/traps.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * linux/include/asm/traps.h - * - * Copyright (C) 1993 Hamish Macdonald - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - -#ifndef _M68KNOMMU_TRAPS_H -#define _M68KNOMMU_TRAPS_H - -#ifndef __ASSEMBLY__ - -typedef void (*e_vector)(void); - -extern e_vector vectors[]; -extern void init_vectors(void); -extern void enable_vector(unsigned int irq); -extern void disable_vector(unsigned int irq); -extern void ack_vector(unsigned int irq); - -#endif - -#define VEC_BUSERR (2) -#define VEC_ADDRERR (3) -#define VEC_ILLEGAL (4) -#define VEC_ZERODIV (5) -#define VEC_CHK (6) -#define VEC_TRAP (7) -#define VEC_PRIV (8) -#define VEC_TRACE (9) -#define VEC_LINE10 (10) -#define VEC_LINE11 (11) -#define VEC_RESV1 (12) -#define VEC_COPROC (13) -#define VEC_FORMAT (14) -#define VEC_UNINT (15) -#define VEC_SPUR (24) -#define VEC_INT1 (25) -#define VEC_INT2 (26) -#define VEC_INT3 (27) -#define VEC_INT4 (28) -#define VEC_INT5 (29) -#define VEC_INT6 (30) -#define VEC_INT7 (31) -#define VEC_SYS (32) -#define VEC_TRAP1 (33) -#define VEC_TRAP2 (34) -#define VEC_TRAP3 (35) -#define VEC_TRAP4 (36) -#define VEC_TRAP5 (37) -#define VEC_TRAP6 (38) -#define VEC_TRAP7 (39) -#define VEC_TRAP8 (40) -#define VEC_TRAP9 (41) -#define VEC_TRAP10 (42) -#define VEC_TRAP11 (43) -#define VEC_TRAP12 (44) -#define VEC_TRAP13 (45) -#define VEC_TRAP14 (46) -#define VEC_TRAP15 (47) -#define VEC_FPBRUC (48) -#define VEC_FPIR (49) -#define VEC_FPDIVZ (50) -#define VEC_FPUNDER (51) -#define VEC_FPOE (52) -#define VEC_FPOVER (53) -#define VEC_FPNAN (54) -#define VEC_FPUNSUP (55) -#define VEC_UNIMPEA (60) -#define VEC_UNIMPII (61) -#define VEC_USER (64) - -#define VECOFF(vec) ((vec)<<2) - -#ifndef __ASSEMBLY__ - -/* Status register bits */ -#define PS_T (0x8000) -#define PS_S (0x2000) -#define PS_M (0x1000) -#define PS_C (0x0001) - -/* structure for stack frames */ - -struct frame { - struct pt_regs ptregs; - union { - struct { - unsigned long iaddr; /* instruction address */ - } fmt2; - struct { - unsigned long effaddr; /* effective address */ - } fmt3; - struct { - unsigned long effaddr; /* effective address */ - unsigned long pc; /* pc of faulted instr */ - } fmt4; - struct { - unsigned long effaddr; /* effective address */ - unsigned short ssw; /* special status word */ - unsigned short wb3s; /* write back 3 status */ - unsigned short wb2s; /* write back 2 status */ - unsigned short wb1s; /* write back 1 status */ - unsigned long faddr; /* fault address */ - unsigned long wb3a; /* write back 3 address */ - unsigned long wb3d; /* write back 3 data */ - unsigned long wb2a; /* write back 2 address */ - unsigned long wb2d; /* write back 2 data */ - unsigned long wb1a; /* write back 1 address */ - unsigned long wb1dpd0; /* write back 1 data/push data 0*/ - unsigned long pd1; /* push data 1*/ - unsigned long pd2; /* push data 2*/ - unsigned long pd3; /* push data 3*/ - } fmt7; - struct { - unsigned long iaddr; /* instruction address */ - unsigned short int1[4]; /* internal registers */ - } fmt9; - struct { - unsigned short int1; - unsigned short ssw; /* special status word */ - unsigned short isc; /* instruction stage c */ - unsigned short isb; /* instruction stage b */ - unsigned long daddr; /* data cycle fault address */ - unsigned short int2[2]; - unsigned long dobuf; /* data cycle output buffer */ - unsigned short int3[2]; - } fmta; - struct { - unsigned short int1; - unsigned short ssw; /* special status word */ - unsigned short isc; /* instruction stage c */ - unsigned short isb; /* instruction stage b */ - unsigned long daddr; /* data cycle fault address */ - unsigned short int2[2]; - unsigned long dobuf; /* data cycle output buffer */ - unsigned short int3[4]; - unsigned long baddr; /* stage B address */ - unsigned short int4[2]; - unsigned long dibuf; /* data cycle input buffer */ - unsigned short int5[3]; - unsigned ver : 4; /* stack frame version # */ - unsigned int6:12; - unsigned short int7[18]; - } fmtb; - } un; -}; - -#endif /* __ASSEMBLY__ */ - -#endif /* _M68KNOMMU_TRAPS_H */ diff --git a/arch/m68knommu/include/asm/types.h b/arch/m68knommu/include/asm/types.h deleted file mode 100644 index 031238c2d18..00000000000 --- a/arch/m68knommu/include/asm/types.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/m68knommu/include/asm/uaccess.h b/arch/m68knommu/include/asm/uaccess.h deleted file mode 100644 index 68bbe9b312f..00000000000 --- a/arch/m68knommu/include/asm/uaccess.h +++ /dev/null @@ -1,181 +0,0 @@ -#ifndef __M68KNOMMU_UACCESS_H -#define __M68KNOMMU_UACCESS_H - -/* - * User space memory access functions - */ -#include -#include -#include - -#include - -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - -#define access_ok(type,addr,size) _access_ok((unsigned long)(addr),(size)) - -/* - * It is not enough to just have access_ok check for a real RAM address. - * This would disallow the case of code/ro-data running XIP in flash/rom. - * Ideally we would check the possible flash ranges too, but that is - * currently not so easy. - */ -static inline int _access_ok(unsigned long addr, unsigned long size) -{ - return 1; -} - -/* - * The exception table consists of pairs of addresses: the first is the - * address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out - * what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ - -struct exception_table_entry -{ - unsigned long insn, fixup; -}; - -/* Returns 0 if exception not found and fixup otherwise. */ -extern unsigned long search_exception_table(unsigned long); - - -/* - * These are the main single-value transfer routines. They automatically - * use the right size if we just have the right pointer type. - */ - -#define put_user(x, ptr) \ -({ \ - int __pu_err = 0; \ - typeof(*(ptr)) __pu_val = (x); \ - switch (sizeof (*(ptr))) { \ - case 1: \ - __put_user_asm(__pu_err, __pu_val, ptr, b); \ - break; \ - case 2: \ - __put_user_asm(__pu_err, __pu_val, ptr, w); \ - break; \ - case 4: \ - __put_user_asm(__pu_err, __pu_val, ptr, l); \ - break; \ - case 8: \ - memcpy(ptr, &__pu_val, sizeof (*(ptr))); \ - break; \ - default: \ - __pu_err = __put_user_bad(); \ - break; \ - } \ - __pu_err; \ -}) -#define __put_user(x, ptr) put_user(x, ptr) - -extern int __put_user_bad(void); - -/* - * Tell gcc we read from memory instead of writing: this is because - * we do not write to any memory gcc knows about, so there are no - * aliasing issues. - */ - -#define __ptr(x) ((unsigned long *)(x)) - -#define __put_user_asm(err,x,ptr,bwl) \ - __asm__ ("move" #bwl " %0,%1" \ - : /* no outputs */ \ - :"d" (x),"m" (*__ptr(ptr)) : "memory") - -#define get_user(x, ptr) \ -({ \ - int __gu_err = 0; \ - typeof(x) __gu_val = 0; \ - switch (sizeof(*(ptr))) { \ - case 1: \ - __get_user_asm(__gu_err, __gu_val, ptr, b, "=d"); \ - break; \ - case 2: \ - __get_user_asm(__gu_err, __gu_val, ptr, w, "=r"); \ - break; \ - case 4: \ - __get_user_asm(__gu_err, __gu_val, ptr, l, "=r"); \ - break; \ - case 8: \ - memcpy((void *) &__gu_val, ptr, sizeof (*(ptr))); \ - break; \ - default: \ - __gu_val = 0; \ - __gu_err = __get_user_bad(); \ - break; \ - } \ - (x) = (typeof(*(ptr))) __gu_val; \ - __gu_err; \ -}) -#define __get_user(x, ptr) get_user(x, ptr) - -extern int __get_user_bad(void); - -#define __get_user_asm(err,x,ptr,bwl,reg) \ - __asm__ ("move" #bwl " %1,%0" \ - : "=d" (x) \ - : "m" (*__ptr(ptr))) - -#define copy_from_user(to, from, n) (memcpy(to, from, n), 0) -#define copy_to_user(to, from, n) (memcpy(to, from, n), 0) - -#define __copy_from_user(to, from, n) copy_from_user(to, from, n) -#define __copy_to_user(to, from, n) copy_to_user(to, from, n) -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user - -#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; }) - -#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n)) return retval; }) - -/* - * Copy a null terminated string from userspace. - */ - -static inline long -strncpy_from_user(char *dst, const char *src, long count) -{ - char *tmp; - strncpy(dst, src, count); - for (tmp = dst; *tmp && count > 0; tmp++, count--) - ; - return(tmp - dst); /* DAVIDM should we count a NUL ? check getname */ -} - -/* - * Return the size of a string (including the ending 0) - * - * Return 0 on exception, a value greater than N if too long - */ -static inline long strnlen_user(const char *src, long n) -{ - return(strlen(src) + 1); /* DAVIDM make safer */ -} - -#define strlen_user(str) strnlen_user(str, 32767) - -/* - * Zero Userspace - */ - -static inline unsigned long -__clear_user(void *to, unsigned long n) -{ - memset(to, 0, n); - return 0; -} - -#define clear_user(to,n) __clear_user(to,n) - -#endif /* _M68KNOMMU_UACCESS_H */ diff --git a/arch/m68knommu/include/asm/ucontext.h b/arch/m68knommu/include/asm/ucontext.h deleted file mode 100644 index 713a27f901c..00000000000 --- a/arch/m68knommu/include/asm/ucontext.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _M68KNOMMU_UCONTEXT_H -#define _M68KNOMMU_UCONTEXT_H - -typedef int greg_t; -#define NGREG 18 -typedef greg_t gregset_t[NGREG]; - -typedef struct fpregset { - int f_pcr; - int f_psr; - int f_fpiaddr; - int f_fpregs[8][3]; -} fpregset_t; - -struct mcontext { - int version; - gregset_t gregs; - fpregset_t fpregs; -}; - -#define MCONTEXT_VERSION 2 - -struct ucontext { - unsigned long uc_flags; - struct ucontext *uc_link; - stack_t uc_stack; - struct mcontext uc_mcontext; - unsigned long uc_filler[80]; - sigset_t uc_sigmask; /* mask last for extensibility */ -}; - -#endif diff --git a/arch/m68knommu/include/asm/unaligned.h b/arch/m68knommu/include/asm/unaligned.h deleted file mode 100644 index eb1ea4cb9a5..00000000000 --- a/arch/m68knommu/include/asm/unaligned.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _ASM_M68KNOMMU_UNALIGNED_H -#define _ASM_M68KNOMMU_UNALIGNED_H - - -#ifdef CONFIG_COLDFIRE -#include -#include -#include - -#define get_unaligned __get_unaligned_be -#define put_unaligned __put_unaligned_be - -#else -/* - * The m68k can do unaligned accesses itself. - */ -#include -#include - -#define get_unaligned __get_unaligned_be -#define put_unaligned __put_unaligned_be - -#endif - -#endif /* _ASM_M68KNOMMU_UNALIGNED_H */ diff --git a/arch/m68knommu/include/asm/unistd.h b/arch/m68knommu/include/asm/unistd.h deleted file mode 100644 index b034a2f7b44..00000000000 --- a/arch/m68knommu/include/asm/unistd.h +++ /dev/null @@ -1,372 +0,0 @@ -#ifndef _ASM_M68K_UNISTD_H_ -#define _ASM_M68K_UNISTD_H_ - -/* - * This file contains the system call numbers. - */ - -#define __NR_restart_syscall 0 -#define __NR_exit 1 -#define __NR_fork 2 -#define __NR_read 3 -#define __NR_write 4 -#define __NR_open 5 -#define __NR_close 6 -#define __NR_waitpid 7 -#define __NR_creat 8 -#define __NR_link 9 -#define __NR_unlink 10 -#define __NR_execve 11 -#define __NR_chdir 12 -#define __NR_time 13 -#define __NR_mknod 14 -#define __NR_chmod 15 -#define __NR_chown 16 -#define __NR_break 17 -#define __NR_oldstat 18 -#define __NR_lseek 19 -#define __NR_getpid 20 -#define __NR_mount 21 -#define __NR_umount 22 -#define __NR_setuid 23 -#define __NR_getuid 24 -#define __NR_stime 25 -#define __NR_ptrace 26 -#define __NR_alarm 27 -#define __NR_oldfstat 28 -#define __NR_pause 29 -#define __NR_utime 30 -#define __NR_stty 31 -#define __NR_gtty 32 -#define __NR_access 33 -#define __NR_nice 34 -#define __NR_ftime 35 -#define __NR_sync 36 -#define __NR_kill 37 -#define __NR_rename 38 -#define __NR_mkdir 39 -#define __NR_rmdir 40 -#define __NR_dup 41 -#define __NR_pipe 42 -#define __NR_times 43 -#define __NR_prof 44 -#define __NR_brk 45 -#define __NR_setgid 46 -#define __NR_getgid 47 -#define __NR_signal 48 -#define __NR_geteuid 49 -#define __NR_getegid 50 -#define __NR_acct 51 -#define __NR_umount2 52 -#define __NR_lock 53 -#define __NR_ioctl 54 -#define __NR_fcntl 55 -#define __NR_mpx 56 -#define __NR_setpgid 57 -#define __NR_ulimit 58 -#define __NR_oldolduname 59 -#define __NR_umask 60 -#define __NR_chroot 61 -#define __NR_ustat 62 -#define __NR_dup2 63 -#define __NR_getppid 64 -#define __NR_getpgrp 65 -#define __NR_setsid 66 -#define __NR_sigaction 67 -#define __NR_sgetmask 68 -#define __NR_ssetmask 69 -#define __NR_setreuid 70 -#define __NR_setregid 71 -#define __NR_sigsuspend 72 -#define __NR_sigpending 73 -#define __NR_sethostname 74 -#define __NR_setrlimit 75 -#define __NR_getrlimit 76 -#define __NR_getrusage 77 -#define __NR_gettimeofday 78 -#define __NR_settimeofday 79 -#define __NR_getgroups 80 -#define __NR_setgroups 81 -#define __NR_select 82 -#define __NR_symlink 83 -#define __NR_oldlstat 84 -#define __NR_readlink 85 -#define __NR_uselib 86 -#define __NR_swapon 87 -#define __NR_reboot 88 -#define __NR_readdir 89 -#define __NR_mmap 90 -#define __NR_munmap 91 -#define __NR_truncate 92 -#define __NR_ftruncate 93 -#define __NR_fchmod 94 -#define __NR_fchown 95 -#define __NR_getpriority 96 -#define __NR_setpriority 97 -#define __NR_profil 98 -#define __NR_statfs 99 -#define __NR_fstatfs 100 -#define __NR_ioperm 101 -#define __NR_socketcall 102 -#define __NR_syslog 103 -#define __NR_setitimer 104 -#define __NR_getitimer 105 -#define __NR_stat 106 -#define __NR_lstat 107 -#define __NR_fstat 108 -#define __NR_olduname 109 -#define __NR_iopl /* 110 */ not supported -#define __NR_vhangup 111 -#define __NR_idle /* 112 */ Obsolete -#define __NR_vm86 /* 113 */ not supported -#define __NR_wait4 114 -#define __NR_swapoff 115 -#define __NR_sysinfo 116 -#define __NR_ipc 117 -#define __NR_fsync 118 -#define __NR_sigreturn 119 -#define __NR_clone 120 -#define __NR_setdomainname 121 -#define __NR_uname 122 -#define __NR_cacheflush 123 -#define __NR_adjtimex 124 -#define __NR_mprotect 125 -#define __NR_sigprocmask 126 -#define __NR_create_module 127 -#define __NR_init_module 128 -#define __NR_delete_module 129 -#define __NR_get_kernel_syms 130 -#define __NR_quotactl 131 -#define __NR_getpgid 132 -#define __NR_fchdir 133 -#define __NR_bdflush 134 -#define __NR_sysfs 135 -#define __NR_personality 136 -#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ -#define __NR_setfsuid 138 -#define __NR_setfsgid 139 -#define __NR__llseek 140 -#define __NR_getdents 141 -#define __NR__newselect 142 -#define __NR_flock 143 -#define __NR_msync 144 -#define __NR_readv 145 -#define __NR_writev 146 -#define __NR_getsid 147 -#define __NR_fdatasync 148 -#define __NR__sysctl 149 -#define __NR_mlock 150 -#define __NR_munlock 151 -#define __NR_mlockall 152 -#define __NR_munlockall 153 -#define __NR_sched_setparam 154 -#define __NR_sched_getparam 155 -#define __NR_sched_setscheduler 156 -#define __NR_sched_getscheduler 157 -#define __NR_sched_yield 158 -#define __NR_sched_get_priority_max 159 -#define __NR_sched_get_priority_min 160 -#define __NR_sched_rr_get_interval 161 -#define __NR_nanosleep 162 -#define __NR_mremap 163 -#define __NR_setresuid 164 -#define __NR_getresuid 165 -#define __NR_getpagesize 166 -#define __NR_query_module 167 -#define __NR_poll 168 -#define __NR_nfsservctl 169 -#define __NR_setresgid 170 -#define __NR_getresgid 171 -#define __NR_prctl 172 -#define __NR_rt_sigreturn 173 -#define __NR_rt_sigaction 174 -#define __NR_rt_sigprocmask 175 -#define __NR_rt_sigpending 176 -#define __NR_rt_sigtimedwait 177 -#define __NR_rt_sigqueueinfo 178 -#define __NR_rt_sigsuspend 179 -#define __NR_pread64 180 -#define __NR_pwrite64 181 -#define __NR_lchown 182 -#define __NR_getcwd 183 -#define __NR_capget 184 -#define __NR_capset 185 -#define __NR_sigaltstack 186 -#define __NR_sendfile 187 -#define __NR_getpmsg 188 /* some people actually want streams */ -#define __NR_putpmsg 189 /* some people actually want streams */ -#define __NR_vfork 190 -#define __NR_ugetrlimit 191 -#define __NR_mmap2 192 -#define __NR_truncate64 193 -#define __NR_ftruncate64 194 -#define __NR_stat64 195 -#define __NR_lstat64 196 -#define __NR_fstat64 197 -#define __NR_chown32 198 -#define __NR_getuid32 199 -#define __NR_getgid32 200 -#define __NR_geteuid32 201 -#define __NR_getegid32 202 -#define __NR_setreuid32 203 -#define __NR_setregid32 204 -#define __NR_getgroups32 205 -#define __NR_setgroups32 206 -#define __NR_fchown32 207 -#define __NR_setresuid32 208 -#define __NR_getresuid32 209 -#define __NR_setresgid32 210 -#define __NR_getresgid32 211 -#define __NR_lchown32 212 -#define __NR_setuid32 213 -#define __NR_setgid32 214 -#define __NR_setfsuid32 215 -#define __NR_setfsgid32 216 -#define __NR_pivot_root 217 -#define __NR_getdents64 220 -#define __NR_gettid 221 -#define __NR_tkill 222 -#define __NR_setxattr 223 -#define __NR_lsetxattr 224 -#define __NR_fsetxattr 225 -#define __NR_getxattr 226 -#define __NR_lgetxattr 227 -#define __NR_fgetxattr 228 -#define __NR_listxattr 229 -#define __NR_llistxattr 230 -#define __NR_flistxattr 231 -#define __NR_removexattr 232 -#define __NR_lremovexattr 233 -#define __NR_fremovexattr 234 -#define __NR_futex 235 -#define __NR_sendfile64 236 -#define __NR_mincore 237 -#define __NR_madvise 238 -#define __NR_fcntl64 239 -#define __NR_readahead 240 -#define __NR_io_setup 241 -#define __NR_io_destroy 242 -#define __NR_io_getevents 243 -#define __NR_io_submit 244 -#define __NR_io_cancel 245 -#define __NR_fadvise64 246 -#define __NR_exit_group 247 -#define __NR_lookup_dcookie 248 -#define __NR_epoll_create 249 -#define __NR_epoll_ctl 250 -#define __NR_epoll_wait 251 -#define __NR_remap_file_pages 252 -#define __NR_set_tid_address 253 -#define __NR_timer_create 254 -#define __NR_timer_settime 255 -#define __NR_timer_gettime 256 -#define __NR_timer_getoverrun 257 -#define __NR_timer_delete 258 -#define __NR_clock_settime 259 -#define __NR_clock_gettime 260 -#define __NR_clock_getres 261 -#define __NR_clock_nanosleep 262 -#define __NR_statfs64 263 -#define __NR_fstatfs64 264 -#define __NR_tgkill 265 -#define __NR_utimes 266 -#define __NR_fadvise64_64 267 -#define __NR_mbind 268 -#define __NR_get_mempolicy 269 -#define __NR_set_mempolicy 270 -#define __NR_mq_open 271 -#define __NR_mq_unlink 272 -#define __NR_mq_timedsend 273 -#define __NR_mq_timedreceive 274 -#define __NR_mq_notify 275 -#define __NR_mq_getsetattr 276 -#define __NR_waitid 277 -#define __NR_vserver 278 -#define __NR_add_key 279 -#define __NR_request_key 280 -#define __NR_keyctl 281 -#define __NR_ioprio_set 282 -#define __NR_ioprio_get 283 -#define __NR_inotify_init 284 -#define __NR_inotify_add_watch 285 -#define __NR_inotify_rm_watch 286 -#define __NR_migrate_pages 287 -#define __NR_openat 288 -#define __NR_mkdirat 289 -#define __NR_mknodat 290 -#define __NR_fchownat 291 -#define __NR_futimesat 292 -#define __NR_fstatat64 293 -#define __NR_unlinkat 294 -#define __NR_renameat 295 -#define __NR_linkat 296 -#define __NR_symlinkat 297 -#define __NR_readlinkat 298 -#define __NR_fchmodat 299 -#define __NR_faccessat 300 -#define __NR_pselect6 301 -#define __NR_ppoll 302 -#define __NR_unshare 303 -#define __NR_set_robust_list 304 -#define __NR_get_robust_list 305 -#define __NR_splice 306 -#define __NR_sync_file_range 307 -#define __NR_tee 308 -#define __NR_vmsplice 309 -#define __NR_move_pages 310 -#define __NR_sched_setaffinity 311 -#define __NR_sched_getaffinity 312 -#define __NR_kexec_load 313 -#define __NR_getcpu 314 -#define __NR_epoll_pwait 315 -#define __NR_utimensat 316 -#define __NR_signalfd 317 -#define __NR_timerfd_create 318 -#define __NR_eventfd 319 -#define __NR_fallocate 320 -#define __NR_timerfd_settime 321 -#define __NR_timerfd_gettime 322 -#define __NR_signalfd4 323 -#define __NR_eventfd2 324 -#define __NR_epoll_create1 325 -#define __NR_dup3 326 -#define __NR_pipe2 327 -#define __NR_inotify_init1 328 - -#ifdef __KERNEL__ - -#define NR_syscalls 329 - -#define __ARCH_WANT_IPC_PARSE_VERSION -#define __ARCH_WANT_OLD_READDIR -#define __ARCH_WANT_OLD_STAT -#define __ARCH_WANT_STAT64 -#define __ARCH_WANT_SYS_ALARM -#define __ARCH_WANT_SYS_GETHOSTNAME -#define __ARCH_WANT_SYS_PAUSE -#define __ARCH_WANT_SYS_SGETMASK -#define __ARCH_WANT_SYS_SIGNAL -#define __ARCH_WANT_SYS_TIME -#define __ARCH_WANT_SYS_UTIME -#define __ARCH_WANT_SYS_WAITPID -#define __ARCH_WANT_SYS_SOCKETCALL -#define __ARCH_WANT_SYS_FADVISE64 -#define __ARCH_WANT_SYS_GETPGRP -#define __ARCH_WANT_SYS_LLSEEK -#define __ARCH_WANT_SYS_NICE -#define __ARCH_WANT_SYS_OLD_GETRLIMIT -#define __ARCH_WANT_SYS_OLDUMOUNT -#define __ARCH_WANT_SYS_SIGPENDING -#define __ARCH_WANT_SYS_SIGPROCMASK -#define __ARCH_WANT_SYS_RT_SIGACTION - -/* - * "Conditional" syscalls - * - * What we want is __attribute__((weak,alias("sys_ni_syscall"))), - * but it doesn't work on all toolchains, so we just do it by hand - */ -#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") - -#endif /* __KERNEL__ */ -#endif /* _ASM_M68K_UNISTD_H_ */ diff --git a/arch/m68knommu/include/asm/user.h b/arch/m68knommu/include/asm/user.h deleted file mode 100644 index a5a555b761c..00000000000 --- a/arch/m68knommu/include/asm/user.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-m68k/Kbuild b/include/asm-m68k/Kbuild deleted file mode 100644 index 52fd96b4142..00000000000 --- a/include/asm-m68k/Kbuild +++ /dev/null @@ -1,3 +0,0 @@ -include include/asm-generic/Kbuild.asm -header-y += cachectl.h -unifdef-y += swab.h diff --git a/include/asm-m68k/a.out-core.h b/include/asm-m68k/a.out-core.h deleted file mode 100644 index f6bfc1d63ff..00000000000 --- a/include/asm-m68k/a.out-core.h +++ /dev/null @@ -1,67 +0,0 @@ -/* a.out coredump register dumper - * - * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public Licence - * as published by the Free Software Foundation; either version - * 2 of the Licence, or (at your option) any later version. - */ - -#ifndef _ASM_A_OUT_CORE_H -#define _ASM_A_OUT_CORE_H - -#ifdef __KERNEL__ - -#include -#include - -/* - * fill in the user structure for an a.out core dump - */ -static inline void aout_dump_thread(struct pt_regs *regs, struct user *dump) -{ - struct switch_stack *sw; - -/* changed the size calculations - should hopefully work better. lbt */ - dump->magic = CMAGIC; - dump->start_code = 0; - dump->start_stack = rdusp() & ~(PAGE_SIZE - 1); - dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT; - dump->u_dsize = ((unsigned long) (current->mm->brk + - (PAGE_SIZE-1))) >> PAGE_SHIFT; - dump->u_dsize -= dump->u_tsize; - dump->u_ssize = 0; - - if (dump->start_stack < TASK_SIZE) - dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT; - - dump->u_ar0 = offsetof(struct user, regs); - sw = ((struct switch_stack *)regs) - 1; - dump->regs.d1 = regs->d1; - dump->regs.d2 = regs->d2; - dump->regs.d3 = regs->d3; - dump->regs.d4 = regs->d4; - dump->regs.d5 = regs->d5; - dump->regs.d6 = sw->d6; - dump->regs.d7 = sw->d7; - dump->regs.a0 = regs->a0; - dump->regs.a1 = regs->a1; - dump->regs.a2 = regs->a2; - dump->regs.a3 = sw->a3; - dump->regs.a4 = sw->a4; - dump->regs.a5 = sw->a5; - dump->regs.a6 = sw->a6; - dump->regs.d0 = regs->d0; - dump->regs.orig_d0 = regs->orig_d0; - dump->regs.stkadj = regs->stkadj; - dump->regs.sr = regs->sr; - dump->regs.pc = regs->pc; - dump->regs.fmtvec = (regs->format << 12) | regs->vector; - /* dump floating point stuff */ - dump->u_fpvalid = dump_fpu (regs, &dump->m68kfp); -} - -#endif /* __KERNEL__ */ -#endif /* _ASM_A_OUT_CORE_H */ diff --git a/include/asm-m68k/a.out.h b/include/asm-m68k/a.out.h deleted file mode 100644 index 3885fe43432..00000000000 --- a/include/asm-m68k/a.out.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __M68K_A_OUT_H__ -#define __M68K_A_OUT_H__ - -struct exec -{ - unsigned long a_info; /* Use macros N_MAGIC, etc for access */ - unsigned a_text; /* length of text, in bytes */ - unsigned a_data; /* length of data, in bytes */ - unsigned a_bss; /* length of uninitialized data area for file, in bytes */ - unsigned a_syms; /* length of symbol table data in file, in bytes */ - unsigned a_entry; /* start address */ - unsigned a_trsize; /* length of relocation info for text, in bytes */ - unsigned a_drsize; /* length of relocation info for data, in bytes */ -}; - -#define N_TRSIZE(a) ((a).a_trsize) -#define N_DRSIZE(a) ((a).a_drsize) -#define N_SYMSIZE(a) ((a).a_syms) - -#endif /* __M68K_A_OUT_H__ */ diff --git a/include/asm-m68k/adb_iop.h b/include/asm-m68k/adb_iop.h deleted file mode 100644 index 8a48e56f2d6..00000000000 --- a/include/asm-m68k/adb_iop.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * ADB through the IOP - * Written by Joshua M. Thompson - */ - -/* IOP number and channel number for ADB */ - -#define ADB_IOP IOP_NUM_ISM -#define ADB_CHAN 2 - -/* From the A/UX headers...maybe important, maybe not */ - -#define ADB_IOP_LISTEN 0x01 -#define ADB_IOP_TALK 0x02 -#define ADB_IOP_EXISTS 0x04 -#define ADB_IOP_FLUSH 0x08 -#define ADB_IOP_RESET 0x10 -#define ADB_IOP_INT 0x20 -#define ADB_IOP_POLL 0x40 -#define ADB_IOP_UNINT 0x80 - -#define AIF_RESET 0x00 -#define AIF_FLUSH 0x01 -#define AIF_LISTEN 0x08 -#define AIF_TALK 0x0C - -/* Flag bits in struct adb_iopmsg */ - -#define ADB_IOP_EXPLICIT 0x80 /* nonzero if explicit command */ -#define ADB_IOP_AUTOPOLL 0x40 /* auto/SRQ polling enabled */ -#define ADB_IOP_SRQ 0x04 /* SRQ detected */ -#define ADB_IOP_TIMEOUT 0x02 /* nonzero if timeout */ - -#ifndef __ASSEMBLY__ - -struct adb_iopmsg { - __u8 flags; /* ADB flags */ - __u8 count; /* no. of data bytes */ - __u8 cmd; /* ADB command */ - __u8 data[8]; /* ADB data */ - __u8 spare[21]; /* spare */ -}; - -#endif /* __ASSEMBLY__ */ diff --git a/include/asm-m68k/amigahw.h b/include/asm-m68k/amigahw.h deleted file mode 100644 index 5ca5dd951a4..00000000000 --- a/include/asm-m68k/amigahw.h +++ /dev/null @@ -1,350 +0,0 @@ -/* -** asm-m68k/amigahw.h -- This header defines some macros and pointers for -** the various Amiga custom hardware registers. -** The naming conventions used here conform to those -** used in the Amiga Hardware Reference Manual, 3rd Edition -** -** Copyright 1992 by Greg Harp -** -** This file is subject to the terms and conditions of the GNU General Public -** License. See the file COPYING in the main directory of this archive -** for more details. -** -** Created: 9/24/92 by Greg Harp -*/ - -#ifndef _M68K_AMIGAHW_H -#define _M68K_AMIGAHW_H - -#include - - /* - * Different Amiga models - */ - -#define AMI_UNKNOWN (0) -#define AMI_500 (1) -#define AMI_500PLUS (2) -#define AMI_600 (3) -#define AMI_1000 (4) -#define AMI_1200 (5) -#define AMI_2000 (6) -#define AMI_2500 (7) -#define AMI_3000 (8) -#define AMI_3000T (9) -#define AMI_3000PLUS (10) -#define AMI_4000 (11) -#define AMI_4000T (12) -#define AMI_CDTV (13) -#define AMI_CD32 (14) -#define AMI_DRACO (15) - - - /* - * Chipsets - */ - -extern unsigned long amiga_chipset; - -#define CS_STONEAGE (0) -#define CS_OCS (1) -#define CS_ECS (2) -#define CS_AGA (3) - - - /* - * Miscellaneous - */ - -extern unsigned long amiga_eclock; /* 700 kHz E Peripheral Clock */ -extern unsigned long amiga_colorclock; /* 3.5 MHz Color Clock */ -extern unsigned long amiga_chip_size; /* Chip RAM Size (bytes) */ -extern unsigned char amiga_vblank; /* VBLANK Frequency */ - - -#define AMIGAHW_DECLARE(name) unsigned name : 1 -#define AMIGAHW_SET(name) (amiga_hw_present.name = 1) -#define AMIGAHW_PRESENT(name) (amiga_hw_present.name) - -struct amiga_hw_present { - /* video hardware */ - AMIGAHW_DECLARE(AMI_VIDEO); /* Amiga Video */ - AMIGAHW_DECLARE(AMI_BLITTER); /* Amiga Blitter */ - AMIGAHW_DECLARE(AMBER_FF); /* Amber Flicker Fixer */ - /* sound hardware */ - AMIGAHW_DECLARE(AMI_AUDIO); /* Amiga Audio */ - /* disk storage interfaces */ - AMIGAHW_DECLARE(AMI_FLOPPY); /* Amiga Floppy */ - AMIGAHW_DECLARE(A3000_SCSI); /* SCSI (wd33c93, A3000 alike) */ - AMIGAHW_DECLARE(A4000_SCSI); /* SCSI (ncr53c710, A4000T alike) */ - AMIGAHW_DECLARE(A1200_IDE); /* IDE (A1200 alike) */ - AMIGAHW_DECLARE(A4000_IDE); /* IDE (A4000 alike) */ - AMIGAHW_DECLARE(CD_ROM); /* CD ROM drive */ - /* other I/O hardware */ - AMIGAHW_DECLARE(AMI_KEYBOARD); /* Amiga Keyboard */ - AMIGAHW_DECLARE(AMI_MOUSE); /* Amiga Mouse */ - AMIGAHW_DECLARE(AMI_SERIAL); /* Amiga Serial */ - AMIGAHW_DECLARE(AMI_PARALLEL); /* Amiga Parallel */ - /* real time clocks */ - AMIGAHW_DECLARE(A2000_CLK); /* Hardware Clock (A2000 alike) */ - AMIGAHW_DECLARE(A3000_CLK); /* Hardware Clock (A3000 alike) */ - /* supporting hardware */ - AMIGAHW_DECLARE(CHIP_RAM); /* Chip RAM */ - AMIGAHW_DECLARE(PAULA); /* Paula (8364) */ - AMIGAHW_DECLARE(DENISE); /* Denise (8362) */ - AMIGAHW_DECLARE(DENISE_HR); /* Denise (8373) */ - AMIGAHW_DECLARE(LISA); /* Lisa (8375) */ - AMIGAHW_DECLARE(AGNUS_PAL); /* Normal/Fat PAL Agnus (8367/8371) */ - AMIGAHW_DECLARE(AGNUS_NTSC); /* Normal/Fat NTSC Agnus (8361/8370) */ - AMIGAHW_DECLARE(AGNUS_HR_PAL); /* Fat Hires PAL Agnus (8372) */ - AMIGAHW_DECLARE(AGNUS_HR_NTSC); /* Fat Hires NTSC Agnus (8372) */ - AMIGAHW_DECLARE(ALICE_PAL); /* PAL Alice (8374) */ - AMIGAHW_DECLARE(ALICE_NTSC); /* NTSC Alice (8374) */ - AMIGAHW_DECLARE(MAGIC_REKICK); /* A3000 Magic Hard Rekick */ - AMIGAHW_DECLARE(PCMCIA); /* PCMCIA Slot */ - AMIGAHW_DECLARE(GG2_ISA); /* GG2 Zorro2ISA Bridge */ - AMIGAHW_DECLARE(ZORRO); /* Zorro AutoConfig */ - AMIGAHW_DECLARE(ZORRO3); /* Zorro III */ -}; - -extern struct amiga_hw_present amiga_hw_present; - -struct CUSTOM { - unsigned short bltddat; - unsigned short dmaconr; - unsigned short vposr; - unsigned short vhposr; - unsigned short dskdatr; - unsigned short joy0dat; - unsigned short joy1dat; - unsigned short clxdat; - unsigned short adkconr; - unsigned short pot0dat; - unsigned short pot1dat; - unsigned short potgor; - unsigned short serdatr; - unsigned short dskbytr; - unsigned short intenar; - unsigned short intreqr; - unsigned char *dskptr; - unsigned short dsklen; - unsigned short dskdat; - unsigned short refptr; - unsigned short vposw; - unsigned short vhposw; - unsigned short copcon; - unsigned short serdat; - unsigned short serper; - unsigned short potgo; - unsigned short joytest; - unsigned short strequ; - unsigned short strvbl; - unsigned short strhor; - unsigned short strlong; - unsigned short bltcon0; - unsigned short bltcon1; - unsigned short bltafwm; - unsigned short bltalwm; - unsigned char *bltcpt; - unsigned char *bltbpt; - unsigned char *bltapt; - unsigned char *bltdpt; - unsigned short bltsize; - unsigned char pad2d; - unsigned char bltcon0l; - unsigned short bltsizv; - unsigned short bltsizh; - unsigned short bltcmod; - unsigned short bltbmod; - unsigned short bltamod; - unsigned short bltdmod; - unsigned short spare2[4]; - unsigned short bltcdat; - unsigned short bltbdat; - unsigned short bltadat; - unsigned short spare3[3]; - unsigned short deniseid; - unsigned short dsksync; - unsigned short *cop1lc; - unsigned short *cop2lc; - unsigned short copjmp1; - unsigned short copjmp2; - unsigned short copins; - unsigned short diwstrt; - unsigned short diwstop; - unsigned short ddfstrt; - unsigned short ddfstop; - unsigned short dmacon; - unsigned short clxcon; - unsigned short intena; - unsigned short intreq; - unsigned short adkcon; - struct { - unsigned short *audlc; - unsigned short audlen; - unsigned short audper; - unsigned short audvol; - unsigned short auddat; - unsigned short audspare[2]; - } aud[4]; - unsigned char *bplpt[8]; - unsigned short bplcon0; - unsigned short bplcon1; - unsigned short bplcon2; - unsigned short bplcon3; - unsigned short bpl1mod; - unsigned short bpl2mod; - unsigned short bplcon4; - unsigned short clxcon2; - unsigned short bpldat[8]; - unsigned char *sprpt[8]; - struct { - unsigned short pos; - unsigned short ctl; - unsigned short dataa; - unsigned short datab; - } spr[8]; - unsigned short color[32]; - unsigned short htotal; - unsigned short hsstop; - unsigned short hbstrt; - unsigned short hbstop; - unsigned short vtotal; - unsigned short vsstop; - unsigned short vbstrt; - unsigned short vbstop; - unsigned short sprhstrt; - unsigned short sprhstop; - unsigned short bplhstrt; - unsigned short bplhstop; - unsigned short hhposw; - unsigned short hhposr; - unsigned short beamcon0; - unsigned short hsstrt; - unsigned short vsstrt; - unsigned short hcenter; - unsigned short diwhigh; - unsigned short spare4[11]; - unsigned short fmode; -}; - -/* - * DMA register bits - */ -#define DMAF_SETCLR (0x8000) -#define DMAF_AUD0 (0x0001) -#define DMAF_AUD1 (0x0002) -#define DMAF_AUD2 (0x0004) -#define DMAF_AUD3 (0x0008) -#define DMAF_DISK (0x0010) -#define DMAF_SPRITE (0x0020) -#define DMAF_BLITTER (0x0040) -#define DMAF_COPPER (0x0080) -#define DMAF_RASTER (0x0100) -#define DMAF_MASTER (0x0200) -#define DMAF_BLITHOG (0x0400) -#define DMAF_BLTNZERO (0x2000) -#define DMAF_BLTDONE (0x4000) -#define DMAF_ALL (0x01FF) - -struct CIA { - unsigned char pra; char pad0[0xff]; - unsigned char prb; char pad1[0xff]; - unsigned char ddra; char pad2[0xff]; - unsigned char ddrb; char pad3[0xff]; - unsigned char talo; char pad4[0xff]; - unsigned char tahi; char pad5[0xff]; - unsigned char tblo; char pad6[0xff]; - unsigned char tbhi; char pad7[0xff]; - unsigned char todlo; char pad8[0xff]; - unsigned char todmid; char pad9[0xff]; - unsigned char todhi; char pada[0x1ff]; - unsigned char sdr; char padb[0xff]; - unsigned char icr; char padc[0xff]; - unsigned char cra; char padd[0xff]; - unsigned char crb; char pade[0xff]; -}; - -#define zTwoBase (0x80000000) -#define ZTWO_PADDR(x) (((unsigned long)(x))-zTwoBase) -#define ZTWO_VADDR(x) (((unsigned long)(x))+zTwoBase) - -#define CUSTOM_PHYSADDR (0xdff000) -#define amiga_custom ((*(volatile struct CUSTOM *)(zTwoBase+CUSTOM_PHYSADDR))) - -#define CIAA_PHYSADDR (0xbfe001) -#define CIAB_PHYSADDR (0xbfd000) -#define ciaa ((*(volatile struct CIA *)(zTwoBase + CIAA_PHYSADDR))) -#define ciab ((*(volatile struct CIA *)(zTwoBase + CIAB_PHYSADDR))) - -#define CHIP_PHYSADDR (0x000000) - -void amiga_chip_init (void); -void *amiga_chip_alloc(unsigned long size, const char *name); -void *amiga_chip_alloc_res(unsigned long size, struct resource *res); -void amiga_chip_free(void *ptr); -unsigned long amiga_chip_avail( void ); /*MILAN*/ -extern volatile unsigned short amiga_audio_min_period; - -static inline void amifb_video_off(void) -{ - if (amiga_chipset == CS_ECS || amiga_chipset == CS_AGA) { - /* program Denise/Lisa for a higher maximum play rate */ - amiga_custom.htotal = 113; /* 31 kHz */ - amiga_custom.vtotal = 223; /* 70 Hz */ - amiga_custom.beamcon0 = 0x4390; /* HARDDIS, VAR{BEAM,VSY,HSY,CSY}EN */ - /* suspend the monitor */ - amiga_custom.hsstrt = amiga_custom.hsstop = 116; - amiga_custom.vsstrt = amiga_custom.vsstop = 226; - amiga_audio_min_period = 57; - } -} - -struct tod3000 { - unsigned int :28, second2:4; /* lower digit */ - unsigned int :28, second1:4; /* upper digit */ - unsigned int :28, minute2:4; /* lower digit */ - unsigned int :28, minute1:4; /* upper digit */ - unsigned int :28, hour2:4; /* lower digit */ - unsigned int :28, hour1:4; /* upper digit */ - unsigned int :28, weekday:4; - unsigned int :28, day2:4; /* lower digit */ - unsigned int :28, day1:4; /* upper digit */ - unsigned int :28, month2:4; /* lower digit */ - unsigned int :28, month1:4; /* upper digit */ - unsigned int :28, year2:4; /* lower digit */ - unsigned int :28, year1:4; /* upper digit */ - unsigned int :28, cntrl1:4; /* control-byte 1 */ - unsigned int :28, cntrl2:4; /* control-byte 2 */ - unsigned int :28, cntrl3:4; /* control-byte 3 */ -}; -#define TOD3000_CNTRL1_HOLD 0 -#define TOD3000_CNTRL1_FREE 9 -#define tod_3000 ((*(volatile struct tod3000 *)(zTwoBase+0xDC0000))) - -struct tod2000 { - unsigned int :28, second2:4; /* lower digit */ - unsigned int :28, second1:4; /* upper digit */ - unsigned int :28, minute2:4; /* lower digit */ - unsigned int :28, minute1:4; /* upper digit */ - unsigned int :28, hour2:4; /* lower digit */ - unsigned int :28, hour1:4; /* upper digit */ - unsigned int :28, day2:4; /* lower digit */ - unsigned int :28, day1:4; /* upper digit */ - unsigned int :28, month2:4; /* lower digit */ - unsigned int :28, month1:4; /* upper digit */ - unsigned int :28, year2:4; /* lower digit */ - unsigned int :28, year1:4; /* upper digit */ - unsigned int :28, weekday:4; - unsigned int :28, cntrl1:4; /* control-byte 1 */ - unsigned int :28, cntrl2:4; /* control-byte 2 */ - unsigned int :28, cntrl3:4; /* control-byte 3 */ -}; - -#define TOD2000_CNTRL1_HOLD (1<<0) -#define TOD2000_CNTRL1_BUSY (1<<1) -#define TOD2000_CNTRL3_24HMODE (1<<2) -#define TOD2000_HOUR1_PM (1<<2) -#define tod_2000 ((*(volatile struct tod2000 *)(zTwoBase+0xDC0000))) - -#endif /* _M68K_AMIGAHW_H */ diff --git a/include/asm-m68k/amigaints.h b/include/asm-m68k/amigaints.h deleted file mode 100644 index b1bcdb835ab..00000000000 --- a/include/asm-m68k/amigaints.h +++ /dev/null @@ -1,113 +0,0 @@ -/* -** amigaints.h -- Amiga Linux interrupt handling structs and prototypes -** -** Copyright 1992 by Greg Harp -** -** This file is subject to the terms and conditions of the GNU General Public -** License. See the file COPYING in the main directory of this archive -** for more details. -** -** Created 10/2/92 by Greg Harp -*/ - -#ifndef _ASMm68k_AMIGAINTS_H_ -#define _ASMm68k_AMIGAINTS_H_ - -#include - -/* -** Amiga Interrupt sources. -** -*/ - -#define AUTO_IRQS (8) -#define AMI_STD_IRQS (14) -#define CIA_IRQS (5) -#define AMI_IRQS (32) /* AUTO_IRQS+AMI_STD_IRQS+2*CIA_IRQS */ - -/* builtin serial port interrupts */ -#define IRQ_AMIGA_TBE (IRQ_USER+0) -#define IRQ_AMIGA_RBF (IRQ_USER+11) - -/* floppy disk interrupts */ -#define IRQ_AMIGA_DSKBLK (IRQ_USER+1) -#define IRQ_AMIGA_DSKSYN (IRQ_USER+12) - -/* software interrupts */ -#define IRQ_AMIGA_SOFT (IRQ_USER+2) - -/* interrupts from external hardware */ -#define IRQ_AMIGA_PORTS IRQ_AUTO_2 -#define IRQ_AMIGA_EXTER IRQ_AUTO_6 - -/* copper interrupt */ -#define IRQ_AMIGA_COPPER (IRQ_USER+4) - -/* vertical blanking interrupt */ -#define IRQ_AMIGA_VERTB (IRQ_USER+5) - -/* Blitter done interrupt */ -#define IRQ_AMIGA_BLIT (IRQ_USER+6) - -/* Audio interrupts */ -#define IRQ_AMIGA_AUD0 (IRQ_USER+7) -#define IRQ_AMIGA_AUD1 (IRQ_USER+8) -#define IRQ_AMIGA_AUD2 (IRQ_USER+9) -#define IRQ_AMIGA_AUD3 (IRQ_USER+10) - -/* CIA interrupt sources */ -#define IRQ_AMIGA_CIAA (IRQ_USER+14) -#define IRQ_AMIGA_CIAA_TA (IRQ_USER+14) -#define IRQ_AMIGA_CIAA_TB (IRQ_USER+15) -#define IRQ_AMIGA_CIAA_ALRM (IRQ_USER+16) -#define IRQ_AMIGA_CIAA_SP (IRQ_USER+17) -#define IRQ_AMIGA_CIAA_FLG (IRQ_USER+18) -#define IRQ_AMIGA_CIAB (IRQ_USER+19) -#define IRQ_AMIGA_CIAB_TA (IRQ_USER+19) -#define IRQ_AMIGA_CIAB_TB (IRQ_USER+20) -#define IRQ_AMIGA_CIAB_ALRM (IRQ_USER+21) -#define IRQ_AMIGA_CIAB_SP (IRQ_USER+22) -#define IRQ_AMIGA_CIAB_FLG (IRQ_USER+23) - - -/* INTREQR masks */ -#define IF_SETCLR 0x8000 /* set/clr bit */ -#define IF_INTEN 0x4000 /* master interrupt bit in INT* registers */ -#define IF_EXTER 0x2000 /* external level 6 and CIA B interrupt */ -#define IF_DSKSYN 0x1000 /* disk sync interrupt */ -#define IF_RBF 0x0800 /* serial receive buffer full interrupt */ -#define IF_AUD3 0x0400 /* audio channel 3 done interrupt */ -#define IF_AUD2 0x0200 /* audio channel 2 done interrupt */ -#define IF_AUD1 0x0100 /* audio channel 1 done interrupt */ -#define IF_AUD0 0x0080 /* audio channel 0 done interrupt */ -#define IF_BLIT 0x0040 /* blitter done interrupt */ -#define IF_VERTB 0x0020 /* vertical blanking interrupt */ -#define IF_COPER 0x0010 /* copper interrupt */ -#define IF_PORTS 0x0008 /* external level 2 and CIA A interrupt */ -#define IF_SOFT 0x0004 /* software initiated interrupt */ -#define IF_DSKBLK 0x0002 /* diskblock DMA finished */ -#define IF_TBE 0x0001 /* serial transmit buffer empty interrupt */ - -/* CIA interrupt control register bits */ - -#define CIA_ICR_TA 0x01 -#define CIA_ICR_TB 0x02 -#define CIA_ICR_ALRM 0x04 -#define CIA_ICR_SP 0x08 -#define CIA_ICR_FLG 0x10 -#define CIA_ICR_ALL 0x1f -#define CIA_ICR_SETCLR 0x80 - -extern void amiga_init_IRQ(void); - -/* to access the interrupt control registers of CIA's use only -** these functions, they behave exactly like the amiga os routines -*/ - -extern struct ciabase ciaa_base, ciab_base; - -extern void cia_init_IRQ(struct ciabase *base); -extern unsigned char cia_set_irq(struct ciabase *base, unsigned char mask); -extern unsigned char cia_able_irq(struct ciabase *base, unsigned char mask); - -#endif /* asm-m68k/amigaints.h */ diff --git a/include/asm-m68k/amigayle.h b/include/asm-m68k/amigayle.h deleted file mode 100644 index bb5a6aa329f..00000000000 --- a/include/asm-m68k/amigayle.h +++ /dev/null @@ -1,107 +0,0 @@ -/* -** asm-m68k/amigayle.h -- This header defines the registers of the gayle chip -** found on the Amiga 1200 -** This information was found by disassembling card.resource, -** so the definitions may not be 100% correct -** anyone has an official doc ? -** -** Copyright 1997 by Alain Malek -** -** This file is subject to the terms and conditions of the GNU General Public -** License. See the file COPYING in the main directory of this archive -** for more details. -** -** Created: 11/28/97 by Alain Malek -*/ - -#ifndef _M68K_AMIGAYLE_H_ -#define _M68K_AMIGAYLE_H_ - -#include -#include - -/* memory layout */ - -#define GAYLE_RAM (0x600000+zTwoBase) -#define GAYLE_RAMSIZE (0x400000) -#define GAYLE_ATTRIBUTE (0xa00000+zTwoBase) -#define GAYLE_ATTRIBUTESIZE (0x020000) -#define GAYLE_IO (0xa20000+zTwoBase) /* 16bit and even 8bit registers */ -#define GAYLE_IOSIZE (0x010000) -#define GAYLE_IO_8BITODD (0xa30000+zTwoBase) /* odd 8bit registers */ - -/* offset for accessing odd IO registers */ -#define GAYLE_ODD (GAYLE_IO_8BITODD-GAYLE_IO-1) - -/* GAYLE registers */ - -struct GAYLE { - u_char cardstatus; - u_char pad0[0x1000-1]; - - u_char intreq; - u_char pad1[0x1000-1]; - - u_char inten; - u_char pad2[0x1000-1]; - - u_char config; - u_char pad3[0x1000-1]; -}; - -#define GAYLE_ADDRESS (0xda8000) /* gayle main registers base address */ - -#define GAYLE_RESET (0xa40000) /* write 0x00 to start reset, - read 1 byte to stop reset */ - -#define gayle (*(volatile struct GAYLE *)(zTwoBase+GAYLE_ADDRESS)) -#define gayle_reset (*(volatile u_char *)(zTwoBase+GAYLE_RESET)) - -#define gayle_attribute ((volatile u_char *)(GAYLE_ATTRIBUTE)) - -#if 0 -#define gayle_inb(a) readb( GAYLE_IO+(a)+(((a)&1)*GAYLE_ODD) ) -#define gayle_outb(v,a) writeb( v, GAYLE_IO+(a)+(((a)&1)*GAYLE_ODD) ) - -#define gayle_inw(a) readw( GAYLE_IO+(a) ) -#define gayle_outw(v,a) writew( v, GAYLE_IO+(a) ) -#endif - -/* GAYLE_CARDSTATUS bit def */ - -#define GAYLE_CS_CCDET 0x40 /* credit card detect */ -#define GAYLE_CS_BVD1 0x20 /* battery voltage detect 1 */ -#define GAYLE_CS_SC 0x20 /* credit card status change */ -#define GAYLE_CS_BVD2 0x10 /* battery voltage detect 2 */ -#define GAYLE_CS_DA 0x10 /* digital audio */ -#define GAYLE_CS_WR 0x08 /* write enable (1 == enabled) */ -#define GAYLE_CS_BSY 0x04 /* credit card busy */ -#define GAYLE_CS_IRQ 0x04 /* interrupt request */ - -/* GAYLE_IRQ bit def */ - -#define GAYLE_IRQ_IDE 0x80 -#define GAYLE_IRQ_CCDET 0x40 -#define GAYLE_IRQ_BVD1 0x20 -#define GAYLE_IRQ_SC 0x20 -#define GAYLE_IRQ_BVD2 0x10 -#define GAYLE_IRQ_DA 0x10 -#define GAYLE_IRQ_WR 0x08 -#define GAYLE_IRQ_BSY 0x04 -#define GAYLE_IRQ_IRQ 0x04 -#define GAYLE_IRQ_IDEACK1 0x02 -#define GAYLE_IRQ_IDEACK0 0x01 - -/* GAYLE_CONFIG bit def - (bit 0-1 for program voltage, bit 2-3 for access speed */ - -#define GAYLE_CFG_0V 0x00 -#define GAYLE_CFG_5V 0x01 -#define GAYLE_CFG_12V 0x02 - -#define GAYLE_CFG_100NS 0x08 -#define GAYLE_CFG_150NS 0x04 -#define GAYLE_CFG_250NS 0x00 -#define GAYLE_CFG_720NS 0x0c - -#endif /* asm-m68k/amigayle.h */ diff --git a/include/asm-m68k/amipcmcia.h b/include/asm-m68k/amipcmcia.h deleted file mode 100644 index 6f1ec1887d8..00000000000 --- a/include/asm-m68k/amipcmcia.h +++ /dev/null @@ -1,110 +0,0 @@ -/* -** asm-m68k/pcmcia.h -- Amiga Linux PCMCIA Definitions -** -** Copyright 1997 by Alain Malek -** -** This file is subject to the terms and conditions of the GNU General Public -** License. See the file COPYING in the main directory of this archive -** for more details. -** -** Created: 12/10/97 by Alain Malek -*/ - -#ifndef __AMIGA_PCMCIA_H__ -#define __AMIGA_PCMCIA_H__ - -#include - -/* prototypes */ - -void pcmcia_reset(void); -int pcmcia_copy_tuple(unsigned char tuple_id, void *tuple, int max_len); -void pcmcia_program_voltage(int voltage); -void pcmcia_access_speed(int speed); -void pcmcia_write_enable(void); -void pcmcia_write_disable(void); - -static inline u_char pcmcia_read_status(void) -{ - return (gayle.cardstatus & 0x7c); -} - -static inline u_char pcmcia_get_intreq(void) -{ - return (gayle.intreq); -} - -static inline void pcmcia_ack_int(u_char intreq) -{ - gayle.intreq = 0xf8; -} - -static inline void pcmcia_enable_irq(void) -{ - gayle.inten |= GAYLE_IRQ_IRQ; -} - -static inline void pcmcia_disable_irq(void) -{ - gayle.inten &= ~GAYLE_IRQ_IRQ; -} - -#define PCMCIA_INSERTED (gayle.cardstatus & GAYLE_CS_CCDET) - -/* valid voltages for pcmcia_ProgramVoltage */ - -#define PCMCIA_0V 0 -#define PCMCIA_5V 5 -#define PCMCIA_12V 12 - -/* valid speeds for pcmcia_AccessSpeed */ - -#define PCMCIA_SPEED_100NS 100 -#define PCMCIA_SPEED_150NS 150 -#define PCMCIA_SPEED_250NS 250 -#define PCMCIA_SPEED_720NS 720 - -/* PCMCIA Tuple codes */ - -#define CISTPL_NULL 0x00 -#define CISTPL_DEVICE 0x01 -#define CISTPL_LONGLINK_CB 0x02 -#define CISTPL_CONFIG_CB 0x04 -#define CISTPL_CFTABLE_ENTRY_CB 0x05 -#define CISTPL_LONGLINK_MFC 0x06 -#define CISTPL_BAR 0x07 -#define CISTPL_CHECKSUM 0x10 -#define CISTPL_LONGLINK_A 0x11 -#define CISTPL_LONGLINK_C 0x12 -#define CISTPL_LINKTARGET 0x13 -#define CISTPL_NO_LINK 0x14 -#define CISTPL_VERS_1 0x15 -#define CISTPL_ALTSTR 0x16 -#define CISTPL_DEVICE_A 0x17 -#define CISTPL_JEDEC_C 0x18 -#define CISTPL_JEDEC_A 0x19 -#define CISTPL_CONFIG 0x1a -#define CISTPL_CFTABLE_ENTRY 0x1b -#define CISTPL_DEVICE_OC 0x1c -#define CISTPL_DEVICE_OA 0x1d -#define CISTPL_DEVICE_GEO 0x1e -#define CISTPL_DEVICE_GEO_A 0x1f -#define CISTPL_MANFID 0x20 -#define CISTPL_FUNCID 0x21 -#define CISTPL_FUNCE 0x22 -#define CISTPL_SWIL 0x23 -#define CISTPL_END 0xff - -/* FUNCID */ - -#define CISTPL_FUNCID_MULTI 0x00 -#define CISTPL_FUNCID_MEMORY 0x01 -#define CISTPL_FUNCID_SERIAL 0x02 -#define CISTPL_FUNCID_PARALLEL 0x03 -#define CISTPL_FUNCID_FIXED 0x04 -#define CISTPL_FUNCID_VIDEO 0x05 -#define CISTPL_FUNCID_NETWORK 0x06 -#define CISTPL_FUNCID_AIMS 0x07 -#define CISTPL_FUNCID_SCSI 0x08 - -#endif diff --git a/include/asm-m68k/apollodma.h b/include/asm-m68k/apollodma.h deleted file mode 100644 index 954adc851ad..00000000000 --- a/include/asm-m68k/apollodma.h +++ /dev/null @@ -1,248 +0,0 @@ -/* - * linux/include/asm/dma.h: Defines for using and allocating dma channels. - * Written by Hennus Bergman, 1992. - * High DMA channel support & info by Hannu Savolainen - * and John Boyd, Nov. 1992. - */ - -#ifndef _ASM_APOLLO_DMA_H -#define _ASM_APOLLO_DMA_H - -#include /* need byte IO */ -#include /* And spinlocks */ -#include - - -#define dma_outb(val,addr) (*((volatile unsigned char *)(addr+IO_BASE)) = (val)) -#define dma_inb(addr) (*((volatile unsigned char *)(addr+IO_BASE))) - -/* - * NOTES about DMA transfers: - * - * controller 1: channels 0-3, byte operations, ports 00-1F - * controller 2: channels 4-7, word operations, ports C0-DF - * - * - ALL registers are 8 bits only, regardless of transfer size - * - channel 4 is not used - cascades 1 into 2. - * - channels 0-3 are byte - addresses/counts are for physical bytes - * - channels 5-7 are word - addresses/counts are for physical words - * - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries - * - transfer count loaded to registers is 1 less than actual count - * - controller 2 offsets are all even (2x offsets for controller 1) - * - page registers for 5-7 don't use data bit 0, represent 128K pages - * - page registers for 0-3 use bit 0, represent 64K pages - * - * DMA transfers are limited to the lower 16MB of _physical_ memory. - * Note that addresses loaded into registers must be _physical_ addresses, - * not logical addresses (which may differ if paging is active). - * - * Address mapping for channels 0-3: - * - * A23 ... A16 A15 ... A8 A7 ... A0 (Physical addresses) - * | ... | | ... | | ... | - * | ... | | ... | | ... | - * | ... | | ... | | ... | - * P7 ... P0 A7 ... A0 A7 ... A0 - * | Page | Addr MSB | Addr LSB | (DMA registers) - * - * Address mapping for channels 5-7: - * - * A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0 (Physical addresses) - * | ... | \ \ ... \ \ \ ... \ \ - * | ... | \ \ ... \ \ \ ... \ (not used) - * | ... | \ \ ... \ \ \ ... \ - * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0 - * | Page | Addr MSB | Addr LSB | (DMA registers) - * - * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses - * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at - * the hardware level, so odd-byte transfers aren't possible). - * - * Transfer count (_not # bytes_) is limited to 64K, represented as actual - * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more, - * and up to 128K bytes may be transferred on channels 5-7 in one operation. - * - */ - -#define MAX_DMA_CHANNELS 8 - -/* The maximum address that we can perform a DMA transfer to on this platform */#define MAX_DMA_ADDRESS (PAGE_OFFSET+0x1000000) - -/* 8237 DMA controllers */ -#define IO_DMA1_BASE 0x10C00 /* 8 bit slave DMA, channels 0..3 */ -#define IO_DMA2_BASE 0x10D00 /* 16 bit master DMA, ch 4(=slave input)..7 */ - -/* DMA controller registers */ -#define DMA1_CMD_REG (IO_DMA1_BASE+0x08) /* command register (w) */ -#define DMA1_STAT_REG (IO_DMA1_BASE+0x08) /* status register (r) */ -#define DMA1_REQ_REG (IO_DMA1_BASE+0x09) /* request register (w) */ -#define DMA1_MASK_REG (IO_DMA1_BASE+0x0A) /* single-channel mask (w) */ -#define DMA1_MODE_REG (IO_DMA1_BASE+0x0B) /* mode register (w) */ -#define DMA1_CLEAR_FF_REG (IO_DMA1_BASE+0x0C) /* clear pointer flip-flop (w) */ -#define DMA1_TEMP_REG (IO_DMA1_BASE+0x0D) /* Temporary Register (r) */ -#define DMA1_RESET_REG (IO_DMA1_BASE+0x0D) /* Master Clear (w) */ -#define DMA1_CLR_MASK_REG (IO_DMA1_BASE+0x0E) /* Clear Mask */ -#define DMA1_MASK_ALL_REG (IO_DMA1_BASE+0x0F) /* all-channels mask (w) */ - -#define DMA2_CMD_REG (IO_DMA2_BASE+0x10) /* command register (w) */ -#define DMA2_STAT_REG (IO_DMA2_BASE+0x10) /* status register (r) */ -#define DMA2_REQ_REG (IO_DMA2_BASE+0x12) /* request register (w) */ -#define DMA2_MASK_REG (IO_DMA2_BASE+0x14) /* single-channel mask (w) */ -#define DMA2_MODE_REG (IO_DMA2_BASE+0x16) /* mode register (w) */ -#define DMA2_CLEAR_FF_REG (IO_DMA2_BASE+0x18) /* clear pointer flip-flop (w) */ -#define DMA2_TEMP_REG (IO_DMA2_BASE+0x1A) /* Temporary Register (r) */ -#define DMA2_RESET_REG (IO_DMA2_BASE+0x1A) /* Master Clear (w) */ -#define DMA2_CLR_MASK_REG (IO_DMA2_BASE+0x1C) /* Clear Mask */ -#define DMA2_MASK_ALL_REG (IO_DMA2_BASE+0x1E) /* all-channels mask (w) */ - -#define DMA_ADDR_0 (IO_DMA1_BASE+0x00) /* DMA address registers */ -#define DMA_ADDR_1 (IO_DMA1_BASE+0x02) -#define DMA_ADDR_2 (IO_DMA1_BASE+0x04) -#define DMA_ADDR_3 (IO_DMA1_BASE+0x06) -#define DMA_ADDR_4 (IO_DMA2_BASE+0x00) -#define DMA_ADDR_5 (IO_DMA2_BASE+0x04) -#define DMA_ADDR_6 (IO_DMA2_BASE+0x08) -#define DMA_ADDR_7 (IO_DMA2_BASE+0x0C) - -#define DMA_CNT_0 (IO_DMA1_BASE+0x01) /* DMA count registers */ -#define DMA_CNT_1 (IO_DMA1_BASE+0x03) -#define DMA_CNT_2 (IO_DMA1_BASE+0x05) -#define DMA_CNT_3 (IO_DMA1_BASE+0x07) -#define DMA_CNT_4 (IO_DMA2_BASE+0x02) -#define DMA_CNT_5 (IO_DMA2_BASE+0x06) -#define DMA_CNT_6 (IO_DMA2_BASE+0x0A) -#define DMA_CNT_7 (IO_DMA2_BASE+0x0E) - -#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */ -#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */ -#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ - -#define DMA_AUTOINIT 0x10 - -#define DMA_8BIT 0 -#define DMA_16BIT 1 -#define DMA_BUSMASTER 2 - -extern spinlock_t dma_spin_lock; - -static __inline__ unsigned long claim_dma_lock(void) -{ - unsigned long flags; - spin_lock_irqsave(&dma_spin_lock, flags); - return flags; -} - -static __inline__ void release_dma_lock(unsigned long flags) -{ - spin_unlock_irqrestore(&dma_spin_lock, flags); -} - -/* enable/disable a specific DMA channel */ -static __inline__ void enable_dma(unsigned int dmanr) -{ - if (dmanr<=3) - dma_outb(dmanr, DMA1_MASK_REG); - else - dma_outb(dmanr & 3, DMA2_MASK_REG); -} - -static __inline__ void disable_dma(unsigned int dmanr) -{ - if (dmanr<=3) - dma_outb(dmanr | 4, DMA1_MASK_REG); - else - dma_outb((dmanr & 3) | 4, DMA2_MASK_REG); -} - -/* Clear the 'DMA Pointer Flip Flop'. - * Write 0 for LSB/MSB, 1 for MSB/LSB access. - * Use this once to initialize the FF to a known state. - * After that, keep track of it. :-) - * --- In order to do that, the DMA routines below should --- - * --- only be used while holding the DMA lock ! --- - */ -static __inline__ void clear_dma_ff(unsigned int dmanr) -{ - if (dmanr<=3) - dma_outb(0, DMA1_CLEAR_FF_REG); - else - dma_outb(0, DMA2_CLEAR_FF_REG); -} - -/* set mode (above) for a specific DMA channel */ -static __inline__ void set_dma_mode(unsigned int dmanr, char mode) -{ - if (dmanr<=3) - dma_outb(mode | dmanr, DMA1_MODE_REG); - else - dma_outb(mode | (dmanr&3), DMA2_MODE_REG); -} - -/* Set transfer address & page bits for specific DMA channel. - * Assumes dma flipflop is clear. - */ -static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) -{ - if (dmanr <= 3) { - dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); - dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); - } else { - dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); - dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); - } -} - - -/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for - * a specific DMA channel. - * You must ensure the parameters are valid. - * NOTE: from a manual: "the number of transfers is one more - * than the initial word count"! This is taken into account. - * Assumes dma flip-flop is clear. - * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7. - */ -static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) -{ - count--; - if (dmanr <= 3) { - dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); - dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); - } else { - dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); - dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); - } -} - - -/* Get DMA residue count. After a DMA transfer, this - * should return zero. Reading this while a DMA transfer is - * still in progress will return unpredictable results. - * If called before the channel has been used, it may return 1. - * Otherwise, it returns the number of _bytes_ left to transfer. - * - * Assumes DMA flip-flop is clear. - */ -static __inline__ int get_dma_residue(unsigned int dmanr) -{ - unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE - : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE; - - /* using short to get 16-bit wrap around */ - unsigned short count; - - count = 1 + dma_inb(io_port); - count += dma_inb(io_port) << 8; - - return (dmanr<=3)? count : (count<<1); -} - - -/* These are in kernel/dma.c: */ -extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ -extern void free_dma(unsigned int dmanr); /* release it again */ - -/* These are in arch/m68k/apollo/dma.c: */ -extern unsigned short dma_map_page(unsigned long phys_addr,int count,int type); -extern void dma_unmap_page(unsigned short dma_addr); - -#endif /* _ASM_APOLLO_DMA_H */ diff --git a/include/asm-m68k/apollohw.h b/include/asm-m68k/apollohw.h deleted file mode 100644 index a1373b9aa28..00000000000 --- a/include/asm-m68k/apollohw.h +++ /dev/null @@ -1,108 +0,0 @@ -/* apollohw.h : some structures to access apollo HW */ - -#ifndef _ASMm68k_APOLLOHW_H_ -#define _ASMm68k_APOLLOHW_H_ - -#include - -/* - apollo models -*/ - -extern u_long apollo_model; - -#define APOLLO_UNKNOWN (0) -#define APOLLO_DN3000 (1) -#define APOLLO_DN3010 (2) -#define APOLLO_DN3500 (3) -#define APOLLO_DN4000 (4) -#define APOLLO_DN4500 (5) - -/* - see scn2681 data sheet for more info. - member names are read_write. -*/ - -#define DECLARE_2681_FIELD(x) unsigned char x; unsigned char dummy##x - -struct SCN2681 { - - DECLARE_2681_FIELD(mra); - DECLARE_2681_FIELD(sra_csra); - DECLARE_2681_FIELD(BRGtest_cra); - DECLARE_2681_FIELD(rhra_thra); - DECLARE_2681_FIELD(ipcr_acr); - DECLARE_2681_FIELD(isr_imr); - DECLARE_2681_FIELD(ctu_ctur); - DECLARE_2681_FIELD(ctl_ctlr); - DECLARE_2681_FIELD(mrb); - DECLARE_2681_FIELD(srb_csrb); - DECLARE_2681_FIELD(tst_crb); - DECLARE_2681_FIELD(rhrb_thrb); - DECLARE_2681_FIELD(reserved); - DECLARE_2681_FIELD(ip_opcr); - DECLARE_2681_FIELD(startCnt_setOutBit); - DECLARE_2681_FIELD(stopCnt_resetOutBit); - -}; - -#if 0 -struct mc146818 { - - unsigned int second1:4, second2:4, alarm_second1:4, alarm_second2:4, - minute1:4, minute2:4, alarm_minute1:4, alarm_minute2:4; - unsigned int hours1:4, hours2:4, alarm_hours1:4, alarm_hours2:4, - day_of_week1:4, day_of_week2:4, day_of_month1:4, day_of_month2:4; - unsigned int month1:4, month2:4, year1:4, year2:4, :16; - -}; -#endif - -struct mc146818 { - unsigned char second, alarm_second; - unsigned char minute, alarm_minute; - unsigned char hours, alarm_hours; - unsigned char day_of_week, day_of_month; - unsigned char month, year; -}; - - -#define IO_BASE 0x80000000 - -extern u_long sio01_physaddr; -extern u_long sio23_physaddr; -extern u_long rtc_physaddr; -extern u_long pica_physaddr; -extern u_long picb_physaddr; -extern u_long cpuctrl_physaddr; -extern u_long timer_physaddr; - -#define SAU7_SIO01_PHYSADDR 0x10400 -#define SAU7_SIO23_PHYSADDR 0x10500 -#define SAU7_RTC_PHYSADDR 0x10900 -#define SAU7_PICA 0x11000 -#define SAU7_PICB 0x11100 -#define SAU7_CPUCTRL 0x10100 -#define SAU7_TIMER 0x010800 - -#define SAU8_SIO01_PHYSADDR 0x8400 -#define SAU8_RTC_PHYSADDR 0x8900 -#define SAU8_PICA 0x9400 -#define SAU8_PICB 0x9500 -#define SAU8_CPUCTRL 0x8100 -#define SAU8_TIMER 0x8800 - -#define sio01 ((*(volatile struct SCN2681 *)(IO_BASE + sio01_physaddr))) -#define sio23 ((*(volatile struct SCN2681 *)(IO_BASE + sio23_physaddr))) -#define rtc (((volatile struct mc146818 *)(IO_BASE + rtc_physaddr))) -#define cpuctrl (*(volatile unsigned int *)(IO_BASE + cpuctrl_physaddr)) -#define pica (IO_BASE + pica_physaddr) -#define picb (IO_BASE + picb_physaddr) -#define timer (IO_BASE + timer_physaddr) -#define addr_xlat_map ((unsigned short *)(IO_BASE + 0x17000)) - -#define isaIO2mem(x) (((((x) & 0x3f8) << 7) | (((x) & 0xfc00) >> 6) | ((x) & 0x7)) + 0x40000 + IO_BASE) - -#define IRQ_APOLLO IRQ_USER - -#endif diff --git a/include/asm-m68k/atafd.h b/include/asm-m68k/atafd.h deleted file mode 100644 index 8456889ee7d..00000000000 --- a/include/asm-m68k/atafd.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _ASM_M68K_FD_H -#define _ASM_M68K_FD_H - -/* Definitions for the Atari Floppy driver */ - -struct atari_format_descr { - int track; /* to be formatted */ - int head; /* "" "" */ - int sect_offset; /* offset of first sector */ -}; - -#endif diff --git a/include/asm-m68k/atafdreg.h b/include/asm-m68k/atafdreg.h deleted file mode 100644 index bbf80949fd9..00000000000 --- a/include/asm-m68k/atafdreg.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef _LINUX_FDREG_H -#define _LINUX_FDREG_H - -/* -** WD1772 stuff - */ - -/* register codes */ - -#define FDCSELREG_STP (0x80) /* command/status register */ -#define FDCSELREG_TRA (0x82) /* track register */ -#define FDCSELREG_SEC (0x84) /* sector register */ -#define FDCSELREG_DTA (0x86) /* data register */ - -/* register names for FDC_READ/WRITE macros */ - -#define FDCREG_CMD 0 -#define FDCREG_STATUS 0 -#define FDCREG_TRACK 2 -#define FDCREG_SECTOR 4 -#define FDCREG_DATA 6 - -/* command opcodes */ - -#define FDCCMD_RESTORE (0x00) /* - */ -#define FDCCMD_SEEK (0x10) /* | */ -#define FDCCMD_STEP (0x20) /* | TYP 1 Commands */ -#define FDCCMD_STIN (0x40) /* | */ -#define FDCCMD_STOT (0x60) /* - */ -#define FDCCMD_RDSEC (0x80) /* - TYP 2 Commands */ -#define FDCCMD_WRSEC (0xa0) /* - " */ -#define FDCCMD_RDADR (0xc0) /* - */ -#define FDCCMD_RDTRA (0xe0) /* | TYP 3 Commands */ -#define FDCCMD_WRTRA (0xf0) /* - */ -#define FDCCMD_FORCI (0xd0) /* - TYP 4 Command */ - -/* command modifier bits */ - -#define FDCCMDADD_SR6 (0x00) /* step rate settings */ -#define FDCCMDADD_SR12 (0x01) -#define FDCCMDADD_SR2 (0x02) -#define FDCCMDADD_SR3 (0x03) -#define FDCCMDADD_V (0x04) /* verify */ -#define FDCCMDADD_H (0x08) /* wait for spin-up */ -#define FDCCMDADD_U (0x10) /* update track register */ -#define FDCCMDADD_M (0x10) /* multiple sector access */ -#define FDCCMDADD_E (0x04) /* head settling flag */ -#define FDCCMDADD_P (0x02) /* precompensation off */ -#define FDCCMDADD_A0 (0x01) /* DAM flag */ - -/* status register bits */ - -#define FDCSTAT_MOTORON (0x80) /* motor on */ -#define FDCSTAT_WPROT (0x40) /* write protected (FDCCMD_WR*) */ -#define FDCSTAT_SPINUP (0x20) /* motor speed stable (Type I) */ -#define FDCSTAT_DELDAM (0x20) /* sector has deleted DAM (Type II+III) */ -#define FDCSTAT_RECNF (0x10) /* record not found */ -#define FDCSTAT_CRC (0x08) /* CRC error */ -#define FDCSTAT_TR00 (0x04) /* Track 00 flag (Type I) */ -#define FDCSTAT_LOST (0x04) /* Lost Data (Type II+III) */ -#define FDCSTAT_IDX (0x02) /* Index status (Type I) */ -#define FDCSTAT_DRQ (0x02) /* DRQ status (Type II+III) */ -#define FDCSTAT_BUSY (0x01) /* FDC is busy */ - - -/* PSG Port A Bit Nr 0 .. Side Sel .. 0 -> Side 1 1 -> Side 2 */ -#define DSKSIDE (0x01) - -#define DSKDRVNONE (0x06) -#define DSKDRV0 (0x02) -#define DSKDRV1 (0x04) - -/* step rates */ -#define FDCSTEP_6 0x00 -#define FDCSTEP_12 0x01 -#define FDCSTEP_2 0x02 -#define FDCSTEP_3 0x03 - -#endif diff --git a/include/asm-m68k/atari_joystick.h b/include/asm-m68k/atari_joystick.h deleted file mode 100644 index 93be7da9f2c..00000000000 --- a/include/asm-m68k/atari_joystick.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _LINUX_ATARI_JOYSTICK_H -#define _LINUX_ATARI_JOYSTICK_H - -/* - * linux/include/linux/atari_joystick.h - * header file for Atari Joystick driver - * by Robert de Vries (robert@and.nl) on 19Jul93 - */ - -void atari_joystick_interrupt(char*); -int atari_joystick_init(void); -extern int atari_mouse_buttons; - -struct joystick_status { - char fire; - char dir; - int ready; - int active; - wait_queue_head_t wait; -}; - -#endif diff --git a/include/asm-m68k/atari_stdma.h b/include/asm-m68k/atari_stdma.h deleted file mode 100644 index 8e389b7fa70..00000000000 --- a/include/asm-m68k/atari_stdma.h +++ /dev/null @@ -1,22 +0,0 @@ - -#ifndef _atari_stdma_h -#define _atari_stdma_h - - -#include - - -/***************************** Prototypes *****************************/ - -void stdma_lock(irq_handler_t handler, void *data); -void stdma_release( void ); -int stdma_others_waiting( void ); -int stdma_islocked( void ); -void *stdma_locked_by( void ); -void stdma_init( void ); - -/************************* End of Prototypes **************************/ - - - -#endif /* _atari_stdma_h */ diff --git a/include/asm-m68k/atari_stram.h b/include/asm-m68k/atari_stram.h deleted file mode 100644 index 7546d13963b..00000000000 --- a/include/asm-m68k/atari_stram.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef _M68K_ATARI_STRAM_H -#define _M68K_ATARI_STRAM_H - -/* - * Functions for Atari ST-RAM management - */ - -/* public interface */ -void *atari_stram_alloc(long size, const char *owner); -void atari_stram_free(void *); - -/* functions called internally by other parts of the kernel */ -void atari_stram_init(void); -void atari_stram_reserve_pages(void *start_mem); -void atari_stram_mem_init_hook (void); - -#endif /*_M68K_ATARI_STRAM_H */ diff --git a/include/asm-m68k/atarihw.h b/include/asm-m68k/atarihw.h deleted file mode 100644 index 1412b4ab202..00000000000 --- a/include/asm-m68k/atarihw.h +++ /dev/null @@ -1,807 +0,0 @@ -/* -** linux/atarihw.h -- This header defines some macros and pointers for -** the various Atari custom hardware registers. -** -** Copyright 1994 by Björn Brauel -** -** 5/1/94 Roman Hodek: -** Added definitions for TT specific chips. -** -** 1996-09-13 lars brinkhoff : -** Finally added definitions for the matrix/codec and the DSP56001 host -** interface. -** -** This file is subject to the terms and conditions of the GNU General Public -** License. See the file COPYING in the main directory of this archive -** for more details. -** -*/ - -#ifndef _LINUX_ATARIHW_H_ -#define _LINUX_ATARIHW_H_ - -#include -#include -#include - -extern u_long atari_mch_cookie; -extern u_long atari_mch_type; -extern u_long atari_switches; -extern int atari_rtc_year_offset; -extern int atari_dont_touch_floppy_select; - -/* convenience macros for testing machine type */ -#define MACH_IS_ST ((atari_mch_cookie >> 16) == ATARI_MCH_ST) -#define MACH_IS_STE ((atari_mch_cookie >> 16) == ATARI_MCH_STE && \ - (atari_mch_cookie & 0xffff) == 0) -#define MACH_IS_MSTE ((atari_mch_cookie >> 16) == ATARI_MCH_STE && \ - (atari_mch_cookie & 0xffff) == 0x10) -#define MACH_IS_TT ((atari_mch_cookie >> 16) == ATARI_MCH_TT) -#define MACH_IS_FALCON ((atari_mch_cookie >> 16) == ATARI_MCH_FALCON) -#define MACH_IS_MEDUSA (atari_mch_type == ATARI_MACH_MEDUSA) -#define MACH_IS_AB40 (atari_mch_type == ATARI_MACH_AB40) - -/* values for atari_switches */ -#define ATARI_SWITCH_IKBD 0x01 -#define ATARI_SWITCH_MIDI 0x02 -#define ATARI_SWITCH_SND6 0x04 -#define ATARI_SWITCH_SND7 0x08 -#define ATARI_SWITCH_OVSC_SHIFT 16 -#define ATARI_SWITCH_OVSC_IKBD (ATARI_SWITCH_IKBD << ATARI_SWITCH_OVSC_SHIFT) -#define ATARI_SWITCH_OVSC_MIDI (ATARI_SWITCH_MIDI << ATARI_SWITCH_OVSC_SHIFT) -#define ATARI_SWITCH_OVSC_SND6 (ATARI_SWITCH_SND6 << ATARI_SWITCH_OVSC_SHIFT) -#define ATARI_SWITCH_OVSC_SND7 (ATARI_SWITCH_SND7 << ATARI_SWITCH_OVSC_SHIFT) -#define ATARI_SWITCH_OVSC_MASK 0xffff0000 - -/* - * Define several Hardware-Chips for indication so that for the ATARI we do - * no longer decide whether it is a Falcon or other machine . It's just - * important what hardware the machine uses - */ - -/* ++roman 08/08/95: rewritten from ORing constants to a C bitfield */ - -#define ATARIHW_DECLARE(name) unsigned name : 1 -#define ATARIHW_SET(name) (atari_hw_present.name = 1) -#define ATARIHW_PRESENT(name) (atari_hw_present.name) - -struct atari_hw_present { - /* video hardware */ - ATARIHW_DECLARE(STND_SHIFTER); /* ST-Shifter - no base low ! */ - ATARIHW_DECLARE(EXTD_SHIFTER); /* STe-Shifter - 24 bit address */ - ATARIHW_DECLARE(TT_SHIFTER); /* TT-Shifter */ - ATARIHW_DECLARE(VIDEL_SHIFTER); /* Falcon-Shifter */ - /* sound hardware */ - ATARIHW_DECLARE(YM_2149); /* Yamaha YM 2149 */ - ATARIHW_DECLARE(PCM_8BIT); /* PCM-Sound in STe-ATARI */ - ATARIHW_DECLARE(CODEC); /* CODEC Sound (Falcon) */ - /* disk storage interfaces */ - ATARIHW_DECLARE(TT_SCSI); /* Directly mapped NCR5380 */ - ATARIHW_DECLARE(ST_SCSI); /* NCR5380 via ST-DMA (Falcon) */ - ATARIHW_DECLARE(ACSI); /* Standard ACSI like in STs */ - ATARIHW_DECLARE(IDE); /* IDE Interface */ - ATARIHW_DECLARE(FDCSPEED); /* 8/16 MHz switch for FDC */ - /* other I/O hardware */ - ATARIHW_DECLARE(ST_MFP); /* The ST-MFP (there should be no Atari - without it... but who knows?) */ - ATARIHW_DECLARE(TT_MFP); /* 2nd MFP */ - ATARIHW_DECLARE(SCC); /* Serial Communications Contr. */ - ATARIHW_DECLARE(ST_ESCC); /* SCC Z83230 in an ST */ - ATARIHW_DECLARE(ANALOG_JOY); /* Paddle Interface for STe - and Falcon */ - ATARIHW_DECLARE(MICROWIRE); /* Microwire Interface */ - /* DMA */ - ATARIHW_DECLARE(STND_DMA); /* 24 Bit limited ST-DMA */ - ATARIHW_DECLARE(EXTD_DMA); /* 32 Bit ST-DMA */ - ATARIHW_DECLARE(SCSI_DMA); /* DMA for the NCR5380 */ - ATARIHW_DECLARE(SCC_DMA); /* DMA for the SCC */ - /* real time clocks */ - ATARIHW_DECLARE(TT_CLK); /* TT compatible clock chip */ - ATARIHW_DECLARE(MSTE_CLK); /* Mega ST(E) clock chip */ - /* supporting hardware */ - ATARIHW_DECLARE(SCU); /* System Control Unit */ - ATARIHW_DECLARE(BLITTER); /* Blitter */ - ATARIHW_DECLARE(VME); /* VME Bus */ - ATARIHW_DECLARE(DSP56K); /* DSP56k processor in Falcon */ -}; - -extern struct atari_hw_present atari_hw_present; - - -/* Reading the MFP port register gives a machine independent delay, since the - * MFP always has a 8 MHz clock. This avoids problems with the varying length - * of nops on various machines. Somebody claimed that the tstb takes 600 ns. - */ -#define MFPDELAY() \ - __asm__ __volatile__ ( "tstb %0" : : "m" (mfp.par_dt_reg) : "cc" ); - -/* Do cache push/invalidate for DMA read/write. This function obeys the - * snooping on some machines (Medusa) and processors: The Medusa itself can - * snoop, but only the '040 can source data from its cache to DMA writes i.e., - * reads from memory). Both '040 and '060 invalidate cache entries on snooped - * DMA reads (i.e., writes to memory). - */ - - -#define atari_readb raw_inb -#define atari_writeb raw_outb - -#define atari_inb_p raw_inb -#define atari_outb_p raw_outb - - - -#include -#include - -static inline void dma_cache_maintenance( unsigned long paddr, - unsigned long len, - int writeflag ) - -{ - if (writeflag) { - if (!MACH_IS_MEDUSA || CPU_IS_060) - cache_push( paddr, len ); - } - else { - if (!MACH_IS_MEDUSA) - cache_clear( paddr, len ); - } -} - - -/* -** Shifter - */ -#define ST_LOW 0 -#define ST_MID 1 -#define ST_HIGH 2 -#define TT_LOW 7 -#define TT_MID 4 -#define TT_HIGH 6 - -#define SHF_BAS (0xffff8200) -struct SHIFTER - { - u_char pad1; - u_char bas_hi; - u_char pad2; - u_char bas_md; - u_char pad3; - u_char volatile vcounthi; - u_char pad4; - u_char volatile vcountmid; - u_char pad5; - u_char volatile vcountlow; - u_char volatile syncmode; - u_char pad6; - u_char pad7; - u_char bas_lo; - }; -# define shifter ((*(volatile struct SHIFTER *)SHF_BAS)) - -#define SHF_FBAS (0xffff820e) -struct SHIFTER_F030 - { - u_short off_next; - u_short scn_width; - }; -# define shifter_f030 ((*(volatile struct SHIFTER_F030 *)SHF_FBAS)) - - -#define SHF_TBAS (0xffff8200) -struct SHIFTER_TT { - u_char char_dummy0; - u_char bas_hi; /* video mem base addr, high and mid byte */ - u_char char_dummy1; - u_char bas_md; - u_char char_dummy2; - u_char vcount_hi; /* pointer to currently displayed byte */ - u_char char_dummy3; - u_char vcount_md; - u_char char_dummy4; - u_char vcount_lo; - u_short st_sync; /* ST compatible sync mode register, unused */ - u_char char_dummy5; - u_char bas_lo; /* video mem addr, low byte */ - u_char char_dummy6[2+3*16]; - /* $ffff8240: */ - u_short color_reg[16]; /* 16 color registers */ - u_char st_shiftmode; /* ST compatible shift mode register, unused */ - u_char char_dummy7; - u_short tt_shiftmode; /* TT shift mode register */ - - -}; -#define shifter_tt ((*(volatile struct SHIFTER_TT *)SHF_TBAS)) - -/* values for shifter_tt->tt_shiftmode */ -#define TT_SHIFTER_STLOW 0x0000 -#define TT_SHIFTER_STMID 0x0100 -#define TT_SHIFTER_STHIGH 0x0200 -#define TT_SHIFTER_TTLOW 0x0700 -#define TT_SHIFTER_TTMID 0x0400 -#define TT_SHIFTER_TTHIGH 0x0600 -#define TT_SHIFTER_MODEMASK 0x0700 -#define TT_SHIFTER_NUMMODE 0x0008 -#define TT_SHIFTER_PALETTE_MASK 0x000f -#define TT_SHIFTER_GRAYMODE 0x1000 - -/* 256 TT palette registers */ -#define TT_PALETTE_BASE (0xffff8400) -#define tt_palette ((volatile u_short *)TT_PALETTE_BASE) - -#define TT_PALETTE_RED_MASK 0x0f00 -#define TT_PALETTE_GREEN_MASK 0x00f0 -#define TT_PALETTE_BLUE_MASK 0x000f - -/* -** Falcon030 VIDEL Video Controller -** for description see File 'linux\tools\atari\hardware.txt - */ -#define f030_col ((u_long *) 0xffff9800) -#define f030_xreg ((u_short*) 0xffff8282) -#define f030_yreg ((u_short*) 0xffff82a2) -#define f030_creg ((u_short*) 0xffff82c0) -#define f030_sreg ((u_short*) 0xffff8260) -#define f030_mreg ((u_short*) 0xffff820a) -#define f030_linewidth ((u_short*) 0xffff820e) -#define f030_hscroll ((u_char*) 0xffff8265) - -#define VIDEL_BAS (0xffff8260) -struct VIDEL { - u_short st_shift; - u_short pad1; - u_char xoffset_s; - u_char xoffset; - u_short f_shift; - u_char pad2[0x1a]; - u_short hht; - u_short hbb; - u_short hbe; - u_short hdb; - u_short hde; - u_short hss; - u_char pad3[0x14]; - u_short vft; - u_short vbb; - u_short vbe; - u_short vdb; - u_short vde; - u_short vss; - u_char pad4[0x12]; - u_short control; - u_short mode; -}; -#define videl ((*(volatile struct VIDEL *)VIDEL_BAS)) - -/* -** DMA/WD1772 Disk Controller - */ - -#define FWD_BAS (0xffff8604) -struct DMA_WD - { - u_short fdc_acces_seccount; - u_short dma_mode_status; - u_char dma_vhi; /* Some extended ST-DMAs can handle 32 bit addresses */ - u_char dma_hi; - u_char char_dummy2; - u_char dma_md; - u_char char_dummy3; - u_char dma_lo; - u_short fdc_speed; - }; -# define dma_wd ((*(volatile struct DMA_WD *)FWD_BAS)) -/* alias */ -#define st_dma dma_wd -/* The two highest bytes of an extended DMA as a short; this is a must - * for the Medusa. - */ -#define st_dma_ext_dmahi (*((volatile unsigned short *)0xffff8608)) - -/* -** YM2149 Sound Chip -** access in bytes - */ - -#define YM_BAS (0xffff8800) -struct SOUND_YM - { - u_char rd_data_reg_sel; - u_char char_dummy1; - u_char wd_data; - }; -#define sound_ym ((*(volatile struct SOUND_YM *)YM_BAS)) - -/* TT SCSI DMA */ - -#define TT_SCSI_DMA_BAS (0xffff8700) -struct TT_DMA { - u_char char_dummy0; - u_char dma_addr_hi; - u_char char_dummy1; - u_char dma_addr_hmd; - u_char char_dummy2; - u_char dma_addr_lmd; - u_char char_dummy3; - u_char dma_addr_lo; - u_char char_dummy4; - u_char dma_cnt_hi; - u_char char_dummy5; - u_char dma_cnt_hmd; - u_char char_dummy6; - u_char dma_cnt_lmd; - u_char char_dummy7; - u_char dma_cnt_lo; - u_long dma_restdata; - u_short dma_ctrl; -}; -#define tt_scsi_dma ((*(volatile struct TT_DMA *)TT_SCSI_DMA_BAS)) - -/* TT SCSI Controller 5380 */ - -#define TT_5380_BAS (0xffff8781) -struct TT_5380 { - u_char scsi_data; - u_char char_dummy1; - u_char scsi_icr; - u_char char_dummy2; - u_char scsi_mode; - u_char char_dummy3; - u_char scsi_tcr; - u_char char_dummy4; - u_char scsi_idstat; - u_char char_dummy5; - u_char scsi_dmastat; - u_char char_dummy6; - u_char scsi_targrcv; - u_char char_dummy7; - u_char scsi_inircv; -}; -#define tt_scsi ((*(volatile struct TT_5380 *)TT_5380_BAS)) -#define tt_scsi_regp ((volatile char *)TT_5380_BAS) - - -/* -** Falcon DMA Sound Subsystem - */ - -#define MATRIX_BASE (0xffff8930) -struct MATRIX -{ - u_short source; - u_short destination; - u_char external_frequency_divider; - u_char internal_frequency_divider; -}; -#define falcon_matrix (*(volatile struct MATRIX *)MATRIX_BASE) - -#define CODEC_BASE (0xffff8936) -struct CODEC -{ - u_char tracks; - u_char input_source; -#define CODEC_SOURCE_ADC 1 -#define CODEC_SOURCE_MATRIX 2 - u_char adc_source; -#define ADC_SOURCE_RIGHT_PSG 1 -#define ADC_SOURCE_LEFT_PSG 2 - u_char gain; -#define CODEC_GAIN_RIGHT 0x0f -#define CODEC_GAIN_LEFT 0xf0 - u_char attenuation; -#define CODEC_ATTENUATION_RIGHT 0x0f -#define CODEC_ATTENUATION_LEFT 0xf0 - u_char unused1; - u_char status; -#define CODEC_OVERFLOW_RIGHT 1 -#define CODEC_OVERFLOW_LEFT 2 - u_char unused2, unused3, unused4, unused5; - u_char gpio_directions; -#define GPIO_IN 0 -#define GPIO_OUT 1 - u_char unused6; - u_char gpio_data; -}; -#define falcon_codec (*(volatile struct CODEC *)CODEC_BASE) - -/* -** Falcon Blitter -*/ - -#define BLT_BAS (0xffff8a00) - -struct BLITTER - { - u_short halftone[16]; - u_short src_x_inc; - u_short src_y_inc; - u_long src_address; - u_short endmask1; - u_short endmask2; - u_short endmask3; - u_short dst_x_inc; - u_short dst_y_inc; - u_long dst_address; - u_short wd_per_line; - u_short ln_per_bb; - u_short hlf_op_reg; - u_short log_op_reg; - u_short lin_nm_reg; - u_short skew_reg; - }; -# define blitter ((*(volatile struct BLITTER *)BLT_BAS)) - - -/* -** SCC Z8530 - */ - -#define SCC_BAS (0xffff8c81) -struct SCC - { - u_char cha_a_ctrl; - u_char char_dummy1; - u_char cha_a_data; - u_char char_dummy2; - u_char cha_b_ctrl; - u_char char_dummy3; - u_char cha_b_data; - }; -# define scc ((*(volatile struct SCC*)SCC_BAS)) - -/* The ESCC (Z85230) in an Atari ST. The channels are reversed! */ -# define st_escc ((*(volatile struct SCC*)0xfffffa31)) -# define st_escc_dsr ((*(volatile char *)0xfffffa39)) - -/* TT SCC DMA Controller (same chip as SCSI DMA) */ - -#define TT_SCC_DMA_BAS (0xffff8c00) -#define tt_scc_dma ((*(volatile struct TT_DMA *)TT_SCC_DMA_BAS)) - -/* -** VIDEL Palette Register - */ - -#define FPL_BAS (0xffff9800) -struct VIDEL_PALETTE - { - u_long reg[256]; - }; -# define videl_palette ((*(volatile struct VIDEL_PALETTE*)FPL_BAS)) - - -/* -** Falcon DSP Host Interface - */ - -#define DSP56K_HOST_INTERFACE_BASE (0xffffa200) -struct DSP56K_HOST_INTERFACE { - u_char icr; -#define DSP56K_ICR_RREQ 0x01 -#define DSP56K_ICR_TREQ 0x02 -#define DSP56K_ICR_HF0 0x08 -#define DSP56K_ICR_HF1 0x10 -#define DSP56K_ICR_HM0 0x20 -#define DSP56K_ICR_HM1 0x40 -#define DSP56K_ICR_INIT 0x80 - - u_char cvr; -#define DSP56K_CVR_HV_MASK 0x1f -#define DSP56K_CVR_HC 0x80 - - u_char isr; -#define DSP56K_ISR_RXDF 0x01 -#define DSP56K_ISR_TXDE 0x02 -#define DSP56K_ISR_TRDY 0x04 -#define DSP56K_ISR_HF2 0x08 -#define DSP56K_ISR_HF3 0x10 -#define DSP56K_ISR_DMA 0x40 -#define DSP56K_ISR_HREQ 0x80 - - u_char ivr; - - union { - u_char b[4]; - u_short w[2]; - u_long l; - } data; -}; -#define dsp56k_host_interface ((*(volatile struct DSP56K_HOST_INTERFACE *)DSP56K_HOST_INTERFACE_BASE)) - -/* -** MFP 68901 - */ - -#define MFP_BAS (0xfffffa01) -struct MFP - { - u_char par_dt_reg; - u_char char_dummy1; - u_char active_edge; - u_char char_dummy2; - u_char data_dir; - u_char char_dummy3; - u_char int_en_a; - u_char char_dummy4; - u_char int_en_b; - u_char char_dummy5; - u_char int_pn_a; - u_char char_dummy6; - u_char int_pn_b; - u_char char_dummy7; - u_char int_sv_a; - u_char char_dummy8; - u_char int_sv_b; - u_char char_dummy9; - u_char int_mk_a; - u_char char_dummy10; - u_char int_mk_b; - u_char char_dummy11; - u_char vec_adr; - u_char char_dummy12; - u_char tim_ct_a; - u_char char_dummy13; - u_char tim_ct_b; - u_char char_dummy14; - u_char tim_ct_cd; - u_char char_dummy15; - u_char tim_dt_a; - u_char char_dummy16; - u_char tim_dt_b; - u_char char_dummy17; - u_char tim_dt_c; - u_char char_dummy18; - u_char tim_dt_d; - u_char char_dummy19; - u_char sync_char; - u_char char_dummy20; - u_char usart_ctr; - u_char char_dummy21; - u_char rcv_stat; - u_char char_dummy22; - u_char trn_stat; - u_char char_dummy23; - u_char usart_dta; - }; -# define mfp ((*(volatile struct MFP*)MFP_BAS)) - -/* TT's second MFP */ - -#define TT_MFP_BAS (0xfffffa81) -# define tt_mfp ((*(volatile struct MFP*)TT_MFP_BAS)) - - -/* TT System Control Unit */ - -#define TT_SCU_BAS (0xffff8e01) -struct TT_SCU { - u_char sys_mask; - u_char char_dummy1; - u_char sys_stat; - u_char char_dummy2; - u_char softint; - u_char char_dummy3; - u_char vmeint; - u_char char_dummy4; - u_char gp_reg1; - u_char char_dummy5; - u_char gp_reg2; - u_char char_dummy6; - u_char vme_mask; - u_char char_dummy7; - u_char vme_stat; -}; -#define tt_scu ((*(volatile struct TT_SCU *)TT_SCU_BAS)) - -/* TT real time clock */ - -#define TT_RTC_BAS (0xffff8961) -struct TT_RTC { - u_char regsel; - u_char dummy; - u_char data; -}; -#define tt_rtc ((*(volatile struct TT_RTC *)TT_RTC_BAS)) - - -/* -** ACIA 6850 - */ -/* constants for the ACIA registers */ - -/* baudrate selection and reset (Baudrate = clock/factor) */ -#define ACIA_DIV1 0 -#define ACIA_DIV16 1 -#define ACIA_DIV64 2 -#define ACIA_RESET 3 - -/* character format */ -#define ACIA_D7E2S (0<<2) /* 7 data, even parity, 2 stop */ -#define ACIA_D7O2S (1<<2) /* 7 data, odd parity, 2 stop */ -#define ACIA_D7E1S (2<<2) /* 7 data, even parity, 1 stop */ -#define ACIA_D7O1S (3<<2) /* 7 data, odd parity, 1 stop */ -#define ACIA_D8N2S (4<<2) /* 8 data, no parity, 2 stop */ -#define ACIA_D8N1S (5<<2) /* 8 data, no parity, 1 stop */ -#define ACIA_D8E1S (6<<2) /* 8 data, even parity, 1 stop */ -#define ACIA_D8O1S (7<<2) /* 8 data, odd parity, 1 stop */ - -/* transmit control */ -#define ACIA_RLTID (0<<5) /* RTS low, TxINT disabled */ -#define ACIA_RLTIE (1<<5) /* RTS low, TxINT enabled */ -#define ACIA_RHTID (2<<5) /* RTS high, TxINT disabled */ -#define ACIA_RLTIDSB (3<<5) /* RTS low, TxINT disabled, send break */ - -/* receive control */ -#define ACIA_RID (0<<7) /* RxINT disabled */ -#define ACIA_RIE (1<<7) /* RxINT enabled */ - -/* status fields of the ACIA */ -#define ACIA_RDRF 1 /* Receive Data Register Full */ -#define ACIA_TDRE (1<<1) /* Transmit Data Register Empty */ -#define ACIA_DCD (1<<2) /* Data Carrier Detect */ -#define ACIA_CTS (1<<3) /* Clear To Send */ -#define ACIA_FE (1<<4) /* Framing Error */ -#define ACIA_OVRN (1<<5) /* Receiver Overrun */ -#define ACIA_PE (1<<6) /* Parity Error */ -#define ACIA_IRQ (1<<7) /* Interrupt Request */ - -#define ACIA_BAS (0xfffffc00) -struct ACIA - { - u_char key_ctrl; - u_char char_dummy1; - u_char key_data; - u_char char_dummy2; - u_char mid_ctrl; - u_char char_dummy3; - u_char mid_data; - }; -# define acia ((*(volatile struct ACIA*)ACIA_BAS)) - -#define TT_DMASND_BAS (0xffff8900) -struct TT_DMASND { - u_char int_ctrl; /* Falcon: Interrupt control */ - u_char ctrl; - u_char pad2; - u_char bas_hi; - u_char pad3; - u_char bas_mid; - u_char pad4; - u_char bas_low; - u_char pad5; - u_char addr_hi; - u_char pad6; - u_char addr_mid; - u_char pad7; - u_char addr_low; - u_char pad8; - u_char end_hi; - u_char pad9; - u_char end_mid; - u_char pad10; - u_char end_low; - u_char pad11[12]; - u_char track_select; /* Falcon */ - u_char mode; - u_char pad12[14]; - /* Falcon only: */ - u_short cbar_src; - u_short cbar_dst; - u_char ext_div; - u_char int_div; - u_char rec_track_select; - u_char dac_src; - u_char adc_src; - u_char input_gain; - u_short output_atten; -}; -# define tt_dmasnd ((*(volatile struct TT_DMASND *)TT_DMASND_BAS)) - -#define DMASND_MFP_INT_REPLAY 0x01 -#define DMASND_MFP_INT_RECORD 0x02 -#define DMASND_TIMERA_INT_REPLAY 0x04 -#define DMASND_TIMERA_INT_RECORD 0x08 - -#define DMASND_CTRL_OFF 0x00 -#define DMASND_CTRL_ON 0x01 -#define DMASND_CTRL_REPEAT 0x02 -#define DMASND_CTRL_RECORD_ON 0x10 -#define DMASND_CTRL_RECORD_OFF 0x00 -#define DMASND_CTRL_RECORD_REPEAT 0x20 -#define DMASND_CTRL_SELECT_REPLAY 0x00 -#define DMASND_CTRL_SELECT_RECORD 0x80 -#define DMASND_MODE_MONO 0x80 -#define DMASND_MODE_STEREO 0x00 -#define DMASND_MODE_8BIT 0x00 -#define DMASND_MODE_16BIT 0x40 /* Falcon only */ -#define DMASND_MODE_6KHZ 0x00 /* Falcon: mute */ -#define DMASND_MODE_12KHZ 0x01 -#define DMASND_MODE_25KHZ 0x02 -#define DMASND_MODE_50KHZ 0x03 - - -#define DMASNDSetBase(bufstart) \ - do { \ - tt_dmasnd.bas_hi = (unsigned char)(((bufstart) & 0xff0000) >> 16); \ - tt_dmasnd.bas_mid = (unsigned char)(((bufstart) & 0x00ff00) >> 8); \ - tt_dmasnd.bas_low = (unsigned char) ((bufstart) & 0x0000ff); \ - } while( 0 ) - -#define DMASNDGetAdr() ((tt_dmasnd.addr_hi << 16) + \ - (tt_dmasnd.addr_mid << 8) + \ - (tt_dmasnd.addr_low)) - -#define DMASNDSetEnd(bufend) \ - do { \ - tt_dmasnd.end_hi = (unsigned char)(((bufend) & 0xff0000) >> 16); \ - tt_dmasnd.end_mid = (unsigned char)(((bufend) & 0x00ff00) >> 8); \ - tt_dmasnd.end_low = (unsigned char) ((bufend) & 0x0000ff); \ - } while( 0 ) - - -#define TT_MICROWIRE_BAS (0xffff8922) -struct TT_MICROWIRE { - u_short data; - u_short mask; -}; -# define tt_microwire ((*(volatile struct TT_MICROWIRE *)TT_MICROWIRE_BAS)) - -#define MW_LM1992_ADDR 0x0400 - -#define MW_LM1992_VOLUME(dB) \ - (0x0c0 | ((dB) < -80 ? 0 : (dB) > 0 ? 40 : (((dB) + 80) / 2))) -#define MW_LM1992_BALLEFT(dB) \ - (0x140 | ((dB) < -40 ? 0 : (dB) > 0 ? 20 : (((dB) + 40) / 2))) -#define MW_LM1992_BALRIGHT(dB) \ - (0x100 | ((dB) < -40 ? 0 : (dB) > 0 ? 20 : (((dB) + 40) / 2))) -#define MW_LM1992_TREBLE(dB) \ - (0x080 | ((dB) < -12 ? 0 : (dB) > 12 ? 12 : (((dB) / 2) + 6))) -#define MW_LM1992_BASS(dB) \ - (0x040 | ((dB) < -12 ? 0 : (dB) > 12 ? 12 : (((dB) / 2) + 6))) - -#define MW_LM1992_PSG_LOW 0x000 -#define MW_LM1992_PSG_HIGH 0x001 -#define MW_LM1992_PSG_OFF 0x002 - -#define MSTE_RTC_BAS (0xfffffc21) - -struct MSTE_RTC { - u_char sec_ones; - u_char dummy1; - u_char sec_tens; - u_char dummy2; - u_char min_ones; - u_char dummy3; - u_char min_tens; - u_char dummy4; - u_char hr_ones; - u_char dummy5; - u_char hr_tens; - u_char dummy6; - u_char weekday; - u_char dummy7; - u_char day_ones; - u_char dummy8; - u_char day_tens; - u_char dummy9; - u_char mon_ones; - u_char dummy10; - u_char mon_tens; - u_char dummy11; - u_char year_ones; - u_char dummy12; - u_char year_tens; - u_char dummy13; - u_char mode; - u_char dummy14; - u_char test; - u_char dummy15; - u_char reset; -}; - -#define mste_rtc ((*(volatile struct MSTE_RTC *)MSTE_RTC_BAS)) - -#endif /* linux/atarihw.h */ - diff --git a/include/asm-m68k/atariints.h b/include/asm-m68k/atariints.h deleted file mode 100644 index 5748e99f4e2..00000000000 --- a/include/asm-m68k/atariints.h +++ /dev/null @@ -1,204 +0,0 @@ -/* -** atariints.h -- Atari Linux interrupt handling structs and prototypes -** -** Copyright 1994 by Björn Brauel -** -** 5/2/94 Roman Hodek: -** TT interrupt definitions added. -** -** 12/02/96: (Roman) -** Adapted to new int handling scheme (see ataints.c); revised numbering -** -** This file is subject to the terms and conditions of the GNU General Public -** License. See the file COPYING in the main directory of this archive -** for more details. -** -*/ - -#ifndef _LINUX_ATARIINTS_H_ -#define _LINUX_ATARIINTS_H_ - -#include -#include - -/* -** Atari Interrupt sources. -** -*/ - -#define STMFP_SOURCE_BASE 8 -#define TTMFP_SOURCE_BASE 24 -#define SCC_SOURCE_BASE 40 -#define VME_SOURCE_BASE 56 -#define VME_MAX_SOURCES 16 - -#define NUM_ATARI_SOURCES (VME_SOURCE_BASE+VME_MAX_SOURCES-STMFP_SOURCE_BASE) - -/* convert vector number to int source number */ -#define IRQ_VECTOR_TO_SOURCE(v) ((v) - ((v) < 0x20 ? 0x18 : (0x40-8))) - -/* convert irq_handler index to vector number */ -#define IRQ_SOURCE_TO_VECTOR(i) ((i) + ((i) < 8 ? 0x18 : (0x40-8))) - -/* interrupt service types */ -#define IRQ_TYPE_SLOW 0 -#define IRQ_TYPE_FAST 1 -#define IRQ_TYPE_PRIO 2 - -/* ST-MFP interrupts */ -#define IRQ_MFP_BUSY (8) -#define IRQ_MFP_DCD (9) -#define IRQ_MFP_CTS (10) -#define IRQ_MFP_GPU (11) -#define IRQ_MFP_TIMD (12) -#define IRQ_MFP_TIMC (13) -#define IRQ_MFP_ACIA (14) -#define IRQ_MFP_FDC (15) -#define IRQ_MFP_ACSI IRQ_MFP_FDC -#define IRQ_MFP_FSCSI IRQ_MFP_FDC -#define IRQ_MFP_IDE IRQ_MFP_FDC -#define IRQ_MFP_TIMB (16) -#define IRQ_MFP_SERERR (17) -#define IRQ_MFP_SEREMPT (18) -#define IRQ_MFP_RECERR (19) -#define IRQ_MFP_RECFULL (20) -#define IRQ_MFP_TIMA (21) -#define IRQ_MFP_RI (22) -#define IRQ_MFP_MMD (23) - -/* TT-MFP interrupts */ -#define IRQ_TT_MFP_IO0 (24) -#define IRQ_TT_MFP_IO1 (25) -#define IRQ_TT_MFP_SCC (26) -#define IRQ_TT_MFP_RI (27) -#define IRQ_TT_MFP_TIMD (28) -#define IRQ_TT_MFP_TIMC (29) -#define IRQ_TT_MFP_DRVRDY (30) -#define IRQ_TT_MFP_SCSIDMA (31) -#define IRQ_TT_MFP_TIMB (32) -#define IRQ_TT_MFP_SERERR (33) -#define IRQ_TT_MFP_SEREMPT (34) -#define IRQ_TT_MFP_RECERR (35) -#define IRQ_TT_MFP_RECFULL (36) -#define IRQ_TT_MFP_TIMA (37) -#define IRQ_TT_MFP_RTC (38) -#define IRQ_TT_MFP_SCSI (39) - -/* SCC interrupts */ -#define IRQ_SCCB_TX (40) -#define IRQ_SCCB_STAT (42) -#define IRQ_SCCB_RX (44) -#define IRQ_SCCB_SPCOND (46) -#define IRQ_SCCA_TX (48) -#define IRQ_SCCA_STAT (50) -#define IRQ_SCCA_RX (52) -#define IRQ_SCCA_SPCOND (54) - - -#define INT_CLK 24576 /* CLK while int_clk =2.456MHz and divide = 100 */ -#define INT_TICKS 246 /* to make sched_time = 99.902... HZ */ - - -#define MFP_ENABLE 0 -#define MFP_PENDING 1 -#define MFP_SERVICE 2 -#define MFP_MASK 3 - -/* Utility functions for setting/clearing bits in the interrupt registers of - * the MFP. 'type' should be constant, if 'irq' is constant, too, code size is - * reduced. set_mfp_bit() is nonsense for PENDING and SERVICE registers. */ - -static inline int get_mfp_bit( unsigned irq, int type ) - -{ unsigned char mask, *reg; - - mask = 1 << (irq & 7); - reg = (unsigned char *)&mfp.int_en_a + type*4 + - ((irq & 8) >> 2) + (((irq-8) & 16) << 3); - return( *reg & mask ); -} - -static inline void set_mfp_bit( unsigned irq, int type ) - -{ unsigned char mask, *reg; - - mask = 1 << (irq & 7); - reg = (unsigned char *)&mfp.int_en_a + type*4 + - ((irq & 8) >> 2) + (((irq-8) & 16) << 3); - __asm__ __volatile__ ( "orb %0,%1" - : : "di" (mask), "m" (*reg) : "memory" ); -} - -static inline void clear_mfp_bit( unsigned irq, int type ) - -{ unsigned char mask, *reg; - - mask = ~(1 << (irq & 7)); - reg = (unsigned char *)&mfp.int_en_a + type*4 + - ((irq & 8) >> 2) + (((irq-8) & 16) << 3); - if (type == MFP_PENDING || type == MFP_SERVICE) - __asm__ __volatile__ ( "moveb %0,%1" - : : "di" (mask), "m" (*reg) : "memory" ); - else - __asm__ __volatile__ ( "andb %0,%1" - : : "di" (mask), "m" (*reg) : "memory" ); -} - -/* - * {en,dis}able_irq have the usual semantics of temporary blocking the - * interrupt, but not loosing requests that happen between disabling and - * enabling. This is done with the MFP mask registers. - */ - -static inline void atari_enable_irq( unsigned irq ) - -{ - if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; - set_mfp_bit( irq, MFP_MASK ); -} - -static inline void atari_disable_irq( unsigned irq ) - -{ - if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; - clear_mfp_bit( irq, MFP_MASK ); -} - -/* - * In opposite to {en,dis}able_irq, requests between turn{off,on}_irq are not - * "stored" - */ - -static inline void atari_turnon_irq( unsigned irq ) - -{ - if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; - set_mfp_bit( irq, MFP_ENABLE ); -} - -static inline void atari_turnoff_irq( unsigned irq ) - -{ - if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; - clear_mfp_bit( irq, MFP_ENABLE ); - clear_mfp_bit( irq, MFP_PENDING ); -} - -static inline void atari_clear_pending_irq( unsigned irq ) - -{ - if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return; - clear_mfp_bit( irq, MFP_PENDING ); -} - -static inline int atari_irq_pending( unsigned irq ) - -{ - if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return( 0 ); - return( get_mfp_bit( irq, MFP_PENDING ) ); -} - -unsigned long atari_register_vme_int( void ); -void atari_unregister_vme_int( unsigned long ); - -#endif /* linux/atariints.h */ diff --git a/include/asm-m68k/atarikb.h b/include/asm-m68k/atarikb.h deleted file mode 100644 index 546e7da5804..00000000000 --- a/include/asm-m68k/atarikb.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -** atarikb.h -- This header contains the prototypes of functions of -** the intelligent keyboard of the Atari needed by the -** mouse and joystick drivers. -** -** Copyright 1994 by Robert de Vries -** -** This file is subject to the terms and conditions of the GNU General Public -** License. See the file COPYING in the main directory of this archive -** for more details. -** -** Created: 20 Feb 1994 by Robert de Vries -*/ - -#ifndef _LINUX_ATARIKB_H -#define _LINUX_ATARIKB_H - -void ikbd_write(const char *, int); -void ikbd_mouse_button_action(int mode); -void ikbd_mouse_rel_pos(void); -void ikbd_mouse_abs_pos(int xmax, int ymax); -void ikbd_mouse_kbd_mode(int dx, int dy); -void ikbd_mouse_thresh(int x, int y); -void ikbd_mouse_scale(int x, int y); -void ikbd_mouse_pos_get(int *x, int *y); -void ikbd_mouse_pos_set(int x, int y); -void ikbd_mouse_y0_bot(void); -void ikbd_mouse_y0_top(void); -void ikbd_mouse_disable(void); -void ikbd_joystick_event_on(void); -void ikbd_joystick_event_off(void); -void ikbd_joystick_get_state(void); -void ikbd_joystick_disable(void); - -/* Hook for MIDI serial driver */ -extern void (*atari_MIDI_interrupt_hook) (void); -/* Hook for mouse driver */ -extern void (*atari_mouse_interrupt_hook) (char *); -/* Hook for keyboard inputdev driver */ -extern void (*atari_input_keyboard_interrupt_hook) (unsigned char, char); -/* Hook for mouse inputdev driver */ -extern void (*atari_input_mouse_interrupt_hook) (char *); - -int atari_keyb_init(void); - -#endif /* _LINUX_ATARIKB_H */ diff --git a/include/asm-m68k/atomic.h b/include/asm-m68k/atomic.h deleted file mode 100644 index eb0ab9d4ee7..00000000000 --- a/include/asm-m68k/atomic.h +++ /dev/null @@ -1,196 +0,0 @@ -#ifndef __ARCH_M68K_ATOMIC__ -#define __ARCH_M68K_ATOMIC__ - -#include -#include - -/* - * Atomic operations that C can't guarantee us. Useful for - * resource counting etc.. - */ - -/* - * We do not have SMP m68k systems, so we don't have to deal with that. - */ - -#define ATOMIC_INIT(i) { (i) } - -#define atomic_read(v) ((v)->counter) -#define atomic_set(v, i) (((v)->counter) = i) - -static inline void atomic_add(int i, atomic_t *v) -{ - __asm__ __volatile__("addl %1,%0" : "+m" (*v) : "id" (i)); -} - -static inline void atomic_sub(int i, atomic_t *v) -{ - __asm__ __volatile__("subl %1,%0" : "+m" (*v) : "id" (i)); -} - -static inline void atomic_inc(atomic_t *v) -{ - __asm__ __volatile__("addql #1,%0" : "+m" (*v)); -} - -static inline void atomic_dec(atomic_t *v) -{ - __asm__ __volatile__("subql #1,%0" : "+m" (*v)); -} - -static inline int atomic_dec_and_test(atomic_t *v) -{ - char c; - __asm__ __volatile__("subql #1,%1; seq %0" : "=d" (c), "+m" (*v)); - return c != 0; -} - -static inline int atomic_inc_and_test(atomic_t *v) -{ - char c; - __asm__ __volatile__("addql #1,%1; seq %0" : "=d" (c), "+m" (*v)); - return c != 0; -} - -#ifdef CONFIG_RMW_INSNS - -static inline int atomic_add_return(int i, atomic_t *v) -{ - int t, tmp; - - __asm__ __volatile__( - "1: movel %2,%1\n" - " addl %3,%1\n" - " casl %2,%1,%0\n" - " jne 1b" - : "+m" (*v), "=&d" (t), "=&d" (tmp) - : "g" (i), "2" (atomic_read(v))); - return t; -} - -static inline int atomic_sub_return(int i, atomic_t *v) -{ - int t, tmp; - - __asm__ __volatile__( - "1: movel %2,%1\n" - " subl %3,%1\n" - " casl %2,%1,%0\n" - " jne 1b" - : "+m" (*v), "=&d" (t), "=&d" (tmp) - : "g" (i), "2" (atomic_read(v))); - return t; -} - -#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) -#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) - -#else /* !CONFIG_RMW_INSNS */ - -static inline int atomic_add_return(int i, atomic_t * v) -{ - unsigned long flags; - int t; - - local_irq_save(flags); - t = atomic_read(v); - t += i; - atomic_set(v, t); - local_irq_restore(flags); - - return t; -} - -static inline int atomic_sub_return(int i, atomic_t * v) -{ - unsigned long flags; - int t; - - local_irq_save(flags); - t = atomic_read(v); - t -= i; - atomic_set(v, t); - local_irq_restore(flags); - - return t; -} - -static inline int atomic_cmpxchg(atomic_t *v, int old, int new) -{ - unsigned long flags; - int prev; - - local_irq_save(flags); - prev = atomic_read(v); - if (prev == old) - atomic_set(v, new); - local_irq_restore(flags); - return prev; -} - -static inline int atomic_xchg(atomic_t *v, int new) -{ - unsigned long flags; - int prev; - - local_irq_save(flags); - prev = atomic_read(v); - atomic_set(v, new); - local_irq_restore(flags); - return prev; -} - -#endif /* !CONFIG_RMW_INSNS */ - -#define atomic_dec_return(v) atomic_sub_return(1, (v)) -#define atomic_inc_return(v) atomic_add_return(1, (v)) - -static inline int atomic_sub_and_test(int i, atomic_t *v) -{ - char c; - __asm__ __volatile__("subl %2,%1; seq %0" : "=d" (c), "+m" (*v): "g" (i)); - return c != 0; -} - -static inline int atomic_add_negative(int i, atomic_t *v) -{ - char c; - __asm__ __volatile__("addl %2,%1; smi %0" : "=d" (c), "+m" (*v): "g" (i)); - return c != 0; -} - -static inline void atomic_clear_mask(unsigned long mask, unsigned long *v) -{ - __asm__ __volatile__("andl %1,%0" : "+m" (*v) : "id" (~(mask))); -} - -static inline void atomic_set_mask(unsigned long mask, unsigned long *v) -{ - __asm__ __volatile__("orl %1,%0" : "+m" (*v) : "id" (mask)); -} - -static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) -{ - int c, old; - c = atomic_read(v); - for (;;) { - if (unlikely(c == (u))) - break; - old = atomic_cmpxchg((v), c, c + (a)); - if (likely(old == c)) - break; - c = old; - } - return c != (u); -} - -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) - -/* Atomic operations are already serializing */ -#define smp_mb__before_atomic_dec() barrier() -#define smp_mb__after_atomic_dec() barrier() -#define smp_mb__before_atomic_inc() barrier() -#define smp_mb__after_atomic_inc() barrier() - -#include -#endif /* __ARCH_M68K_ATOMIC __ */ diff --git a/include/asm-m68k/auxvec.h b/include/asm-m68k/auxvec.h deleted file mode 100644 index 844d6d52204..00000000000 --- a/include/asm-m68k/auxvec.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef __ASMm68k_AUXVEC_H -#define __ASMm68k_AUXVEC_H - -#endif diff --git a/include/asm-m68k/bitops.h b/include/asm-m68k/bitops.h deleted file mode 100644 index 9bde784e7ba..00000000000 --- a/include/asm-m68k/bitops.h +++ /dev/null @@ -1,464 +0,0 @@ -#ifndef _M68K_BITOPS_H -#define _M68K_BITOPS_H -/* - * Copyright 1992, Linus Torvalds. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - -#include - -/* - * Require 68020 or better. - * - * They use the standard big-endian m680x0 bit ordering. - */ - -#define test_and_set_bit(nr,vaddr) \ - (__builtin_constant_p(nr) ? \ - __constant_test_and_set_bit(nr, vaddr) : \ - __generic_test_and_set_bit(nr, vaddr)) - -#define __test_and_set_bit(nr,vaddr) test_and_set_bit(nr,vaddr) - -static inline int __constant_test_and_set_bit(int nr, unsigned long *vaddr) -{ - char *p = (char *)vaddr + (nr ^ 31) / 8; - char retval; - - __asm__ __volatile__ ("bset %2,%1; sne %0" - : "=d" (retval), "+m" (*p) - : "di" (nr & 7)); - - return retval; -} - -static inline int __generic_test_and_set_bit(int nr, unsigned long *vaddr) -{ - char retval; - - __asm__ __volatile__ ("bfset %2{%1:#1}; sne %0" - : "=d" (retval) : "d" (nr^31), "o" (*vaddr) : "memory"); - - return retval; -} - -#define set_bit(nr,vaddr) \ - (__builtin_constant_p(nr) ? \ - __constant_set_bit(nr, vaddr) : \ - __generic_set_bit(nr, vaddr)) - -#define __set_bit(nr,vaddr) set_bit(nr,vaddr) - -static inline void __constant_set_bit(int nr, volatile unsigned long *vaddr) -{ - char *p = (char *)vaddr + (nr ^ 31) / 8; - __asm__ __volatile__ ("bset %1,%0" - : "+m" (*p) : "di" (nr & 7)); -} - -static inline void __generic_set_bit(int nr, volatile unsigned long *vaddr) -{ - __asm__ __volatile__ ("bfset %1{%0:#1}" - : : "d" (nr^31), "o" (*vaddr) : "memory"); -} - -#define test_and_clear_bit(nr,vaddr) \ - (__builtin_constant_p(nr) ? \ - __constant_test_and_clear_bit(nr, vaddr) : \ - __generic_test_and_clear_bit(nr, vaddr)) - -#define __test_and_clear_bit(nr,vaddr) test_and_clear_bit(nr,vaddr) - -static inline int __constant_test_and_clear_bit(int nr, unsigned long *vaddr) -{ - char *p = (char *)vaddr + (nr ^ 31) / 8; - char retval; - - __asm__ __volatile__ ("bclr %2,%1; sne %0" - : "=d" (retval), "+m" (*p) - : "di" (nr & 7)); - - return retval; -} - -static inline int __generic_test_and_clear_bit(int nr, unsigned long *vaddr) -{ - char retval; - - __asm__ __volatile__ ("bfclr %2{%1:#1}; sne %0" - : "=d" (retval) : "d" (nr^31), "o" (*vaddr) : "memory"); - - return retval; -} - -/* - * clear_bit() doesn't provide any barrier for the compiler. - */ -#define smp_mb__before_clear_bit() barrier() -#define smp_mb__after_clear_bit() barrier() - -#define clear_bit(nr,vaddr) \ - (__builtin_constant_p(nr) ? \ - __constant_clear_bit(nr, vaddr) : \ - __generic_clear_bit(nr, vaddr)) -#define __clear_bit(nr,vaddr) clear_bit(nr,vaddr) - -static inline void __constant_clear_bit(int nr, volatile unsigned long *vaddr) -{ - char *p = (char *)vaddr + (nr ^ 31) / 8; - __asm__ __volatile__ ("bclr %1,%0" - : "+m" (*p) : "di" (nr & 7)); -} - -static inline void __generic_clear_bit(int nr, volatile unsigned long *vaddr) -{ - __asm__ __volatile__ ("bfclr %1{%0:#1}" - : : "d" (nr^31), "o" (*vaddr) : "memory"); -} - -#define test_and_change_bit(nr,vaddr) \ - (__builtin_constant_p(nr) ? \ - __constant_test_and_change_bit(nr, vaddr) : \ - __generic_test_and_change_bit(nr, vaddr)) - -#define __test_and_change_bit(nr,vaddr) test_and_change_bit(nr,vaddr) -#define __change_bit(nr,vaddr) change_bit(nr,vaddr) - -static inline int __constant_test_and_change_bit(int nr, unsigned long *vaddr) -{ - char *p = (char *)vaddr + (nr ^ 31) / 8; - char retval; - - __asm__ __volatile__ ("bchg %2,%1; sne %0" - : "=d" (retval), "+m" (*p) - : "di" (nr & 7)); - - return retval; -} - -static inline int __generic_test_and_change_bit(int nr, unsigned long *vaddr) -{ - char retval; - - __asm__ __volatile__ ("bfchg %2{%1:#1}; sne %0" - : "=d" (retval) : "d" (nr^31), "o" (*vaddr) : "memory"); - - return retval; -} - -#define change_bit(nr,vaddr) \ - (__builtin_constant_p(nr) ? \ - __constant_change_bit(nr, vaddr) : \ - __generic_change_bit(nr, vaddr)) - -static inline void __constant_change_bit(int nr, unsigned long *vaddr) -{ - char *p = (char *)vaddr + (nr ^ 31) / 8; - __asm__ __volatile__ ("bchg %1,%0" - : "+m" (*p) : "di" (nr & 7)); -} - -static inline void __generic_change_bit(int nr, unsigned long *vaddr) -{ - __asm__ __volatile__ ("bfchg %1{%0:#1}" - : : "d" (nr^31), "o" (*vaddr) : "memory"); -} - -static inline int test_bit(int nr, const unsigned long *vaddr) -{ - return (vaddr[nr >> 5] & (1UL << (nr & 31))) != 0; -} - -static inline int find_first_zero_bit(const unsigned long *vaddr, - unsigned size) -{ - const unsigned long *p = vaddr; - int res = 32; - unsigned long num; - - if (!size) - return 0; - - size = (size + 31) >> 5; - while (!(num = ~*p++)) { - if (!--size) - goto out; - } - - __asm__ __volatile__ ("bfffo %1{#0,#0},%0" - : "=d" (res) : "d" (num & -num)); - res ^= 31; -out: - return ((long)p - (long)vaddr - 4) * 8 + res; -} - -static inline int find_next_zero_bit(const unsigned long *vaddr, int size, - int offset) -{ - const unsigned long *p = vaddr + (offset >> 5); - int bit = offset & 31UL, res; - - if (offset >= size) - return size; - - if (bit) { - unsigned long num = ~*p++ & (~0UL << bit); - offset -= bit; - - /* Look for zero in first longword */ - __asm__ __volatile__ ("bfffo %1{#0,#0},%0" - : "=d" (res) : "d" (num & -num)); - if (res < 32) - return offset + (res ^ 31); - offset += 32; - } - /* No zero yet, search remaining full bytes for a zero */ - res = find_first_zero_bit(p, size - ((long)p - (long)vaddr) * 8); - return offset + res; -} - -static inline int find_first_bit(const unsigned long *vaddr, unsigned size) -{ - const unsigned long *p = vaddr; - int res = 32; - unsigned long num; - - if (!size) - return 0; - - size = (size + 31) >> 5; - while (!(num = *p++)) { - if (!--size) - goto out; - } - - __asm__ __volatile__ ("bfffo %1{#0,#0},%0" - : "=d" (res) : "d" (num & -num)); - res ^= 31; -out: - return ((long)p - (long)vaddr - 4) * 8 + res; -} - -static inline int find_next_bit(const unsigned long *vaddr, int size, - int offset) -{ - const unsigned long *p = vaddr + (offset >> 5); - int bit = offset & 31UL, res; - - if (offset >= size) - return size; - - if (bit) { - unsigned long num = *p++ & (~0UL << bit); - offset -= bit; - - /* Look for one in first longword */ - __asm__ __volatile__ ("bfffo %1{#0,#0},%0" - : "=d" (res) : "d" (num & -num)); - if (res < 32) - return offset + (res ^ 31); - offset += 32; - } - /* No one yet, search remaining full bytes for a one */ - res = find_first_bit(p, size - ((long)p - (long)vaddr) * 8); - return offset + res; -} - -/* - * ffz = Find First Zero in word. Undefined if no zero exists, - * so code should check against ~0UL first.. - */ -static inline unsigned long ffz(unsigned long word) -{ - int res; - - __asm__ __volatile__ ("bfffo %1{#0,#0},%0" - : "=d" (res) : "d" (~word & -~word)); - return res ^ 31; -} - -#ifdef __KERNEL__ - -/* - * ffs: find first bit set. This is defined the same way as - * the libc and compiler builtin ffs routines, therefore - * differs in spirit from the above ffz (man ffs). - */ - -static inline int ffs(int x) -{ - int cnt; - - asm ("bfffo %1{#0:#0},%0" : "=d" (cnt) : "dm" (x & -x)); - - return 32 - cnt; -} -#define __ffs(x) (ffs(x) - 1) - -/* - * fls: find last bit set. - */ - -static inline int fls(int x) -{ - int cnt; - - asm ("bfffo %1{#0,#0},%0" : "=d" (cnt) : "dm" (x)); - - return 32 - cnt; -} - -static inline int __fls(int x) -{ - return fls(x) - 1; -} - -#include -#include -#include -#include - -/* Bitmap functions for the minix filesystem */ - -static inline int minix_find_first_zero_bit(const void *vaddr, unsigned size) -{ - const unsigned short *p = vaddr, *addr = vaddr; - int res; - unsigned short num; - - if (!size) - return 0; - - size = (size >> 4) + ((size & 15) > 0); - while (*p++ == 0xffff) - { - if (--size == 0) - return (p - addr) << 4; - } - - num = ~*--p; - __asm__ __volatile__ ("bfffo %1{#16,#16},%0" - : "=d" (res) : "d" (num & -num)); - return ((p - addr) << 4) + (res ^ 31); -} - -#define minix_test_and_set_bit(nr, addr) __test_and_set_bit((nr) ^ 16, (unsigned long *)(addr)) -#define minix_set_bit(nr,addr) __set_bit((nr) ^ 16, (unsigned long *)(addr)) -#define minix_test_and_clear_bit(nr, addr) __test_and_clear_bit((nr) ^ 16, (unsigned long *)(addr)) - -static inline int minix_test_bit(int nr, const void *vaddr) -{ - const unsigned short *p = vaddr; - return (p[nr >> 4] & (1U << (nr & 15))) != 0; -} - -/* Bitmap functions for the ext2 filesystem. */ - -#define ext2_set_bit(nr, addr) __test_and_set_bit((nr) ^ 24, (unsigned long *)(addr)) -#define ext2_set_bit_atomic(lock, nr, addr) test_and_set_bit((nr) ^ 24, (unsigned long *)(addr)) -#define ext2_clear_bit(nr, addr) __test_and_clear_bit((nr) ^ 24, (unsigned long *)(addr)) -#define ext2_clear_bit_atomic(lock, nr, addr) test_and_clear_bit((nr) ^ 24, (unsigned long *)(addr)) - -static inline int ext2_test_bit(int nr, const void *vaddr) -{ - const unsigned char *p = vaddr; - return (p[nr >> 3] & (1U << (nr & 7))) != 0; -} - -static inline int ext2_find_first_zero_bit(const void *vaddr, unsigned size) -{ - const unsigned long *p = vaddr, *addr = vaddr; - int res; - - if (!size) - return 0; - - size = (size >> 5) + ((size & 31) > 0); - while (*p++ == ~0UL) - { - if (--size == 0) - return (p - addr) << 5; - } - - --p; - for (res = 0; res < 32; res++) - if (!ext2_test_bit (res, p)) - break; - return (p - addr) * 32 + res; -} - -static inline int ext2_find_next_zero_bit(const void *vaddr, unsigned size, - unsigned offset) -{ - const unsigned long *addr = vaddr; - const unsigned long *p = addr + (offset >> 5); - int bit = offset & 31UL, res; - - if (offset >= size) - return size; - - if (bit) { - /* Look for zero in first longword */ - for (res = bit; res < 32; res++) - if (!ext2_test_bit (res, p)) - return (p - addr) * 32 + res; - p++; - } - /* No zero yet, search remaining full bytes for a zero */ - res = ext2_find_first_zero_bit (p, size - 32 * (p - addr)); - return (p - addr) * 32 + res; -} - -static inline int ext2_find_first_bit(const void *vaddr, unsigned size) -{ - const unsigned long *p = vaddr, *addr = vaddr; - int res; - - if (!size) - return 0; - - size = (size >> 5) + ((size & 31) > 0); - while (*p++ == 0UL) { - if (--size == 0) - return (p - addr) << 5; - } - - --p; - for (res = 0; res < 32; res++) - if (ext2_test_bit(res, p)) - break; - return (p - addr) * 32 + res; -} - -static inline int ext2_find_next_bit(const void *vaddr, unsigned size, - unsigned offset) -{ - const unsigned long *addr = vaddr; - const unsigned long *p = addr + (offset >> 5); - int bit = offset & 31UL, res; - - if (offset >= size) - return size; - - if (bit) { - /* Look for one in first longword */ - for (res = bit; res < 32; res++) - if (ext2_test_bit(res, p)) - return (p - addr) * 32 + res; - p++; - } - /* No set bit yet, search remaining full bytes for a set bit */ - res = ext2_find_first_bit(p, size - 32 * (p - addr)); - return (p - addr) * 32 + res; -} - -#endif /* __KERNEL__ */ - -#endif /* _M68K_BITOPS_H */ diff --git a/include/asm-m68k/blinken.h b/include/asm-m68k/blinken.h deleted file mode 100644 index 1a749cf7b06..00000000000 --- a/include/asm-m68k/blinken.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -** asm/blinken.h -- m68k blinkenlights support (currently hp300 only) -** -** (c) 1998 Phil Blundell -** -** This file is subject to the terms and conditions of the GNU General Public -** License. See the file COPYING in the main directory of this archive -** for more details. -** -*/ - -#ifndef _M68K_BLINKEN_H -#define _M68K_BLINKEN_H - -#include -#include - -#define HP300_LEDS 0xf001ffff - -extern unsigned char ledstate; - -static __inline__ void blinken_leds(int on, int off) -{ - if (MACH_IS_HP300) - { - ledstate |= on; - ledstate &= ~off; - out_8(HP300_LEDS, ~ledstate); - } -} - -#endif diff --git a/include/asm-m68k/bootinfo.h b/include/asm-m68k/bootinfo.h deleted file mode 100644 index fb8a06b9ab6..00000000000 --- a/include/asm-m68k/bootinfo.h +++ /dev/null @@ -1,378 +0,0 @@ -/* -** asm/bootinfo.h -- Definition of the Linux/m68k boot information structure -** -** Copyright 1992 by Greg Harp -** -** This file is subject to the terms and conditions of the GNU General Public -** License. See the file COPYING in the main directory of this archive -** for more details. -** -** Created 09/29/92 by Greg Harp -** -** 5/2/94 Roman Hodek: -** Added bi_atari part of the machine dependent union bi_un; for now it -** contains just a model field to distinguish between TT and Falcon. -** 26/7/96 Roman Zippel: -** Renamed to setup.h; added some useful macros to allow gcc some -** optimizations if possible. -** 5/10/96 Geert Uytterhoeven: -** Redesign of the boot information structure; renamed to bootinfo.h again -** 27/11/96 Geert Uytterhoeven: -** Backwards compatibility with bootinfo interface version 1.0 -*/ - -#ifndef _M68K_BOOTINFO_H -#define _M68K_BOOTINFO_H - - - /* - * Bootinfo definitions - * - * This is an easily parsable and extendable structure containing all - * information to be passed from the bootstrap to the kernel. - * - * This way I hope to keep all future changes back/forewards compatible. - * Thus, keep your fingers crossed... - * - * This structure is copied right after the kernel bss by the bootstrap - * routine. - */ - -#ifndef __ASSEMBLY__ - -struct bi_record { - unsigned short tag; /* tag ID */ - unsigned short size; /* size of record (in bytes) */ - unsigned long data[0]; /* data */ -}; - -#endif /* __ASSEMBLY__ */ - - - /* - * Tag Definitions - * - * Machine independent tags start counting from 0x0000 - * Machine dependent tags start counting from 0x8000 - */ - -#define BI_LAST 0x0000 /* last record (sentinel) */ -#define BI_MACHTYPE 0x0001 /* machine type (u_long) */ -#define BI_CPUTYPE 0x0002 /* cpu type (u_long) */ -#define BI_FPUTYPE 0x0003 /* fpu type (u_long) */ -#define BI_MMUTYPE 0x0004 /* mmu type (u_long) */ -#define BI_MEMCHUNK 0x0005 /* memory chunk address and size */ - /* (struct mem_info) */ -#define BI_RAMDISK 0x0006 /* ramdisk address and size */ - /* (struct mem_info) */ -#define BI_COMMAND_LINE 0x0007 /* kernel command line parameters */ - /* (string) */ - - /* - * Amiga-specific tags - */ - -#define BI_AMIGA_MODEL 0x8000 /* model (u_long) */ -#define BI_AMIGA_AUTOCON 0x8001 /* AutoConfig device */ - /* (struct ConfigDev) */ -#define BI_AMIGA_CHIP_SIZE 0x8002 /* size of Chip RAM (u_long) */ -#define BI_AMIGA_VBLANK 0x8003 /* VBLANK frequency (u_char) */ -#define BI_AMIGA_PSFREQ 0x8004 /* power supply frequency (u_char) */ -#define BI_AMIGA_ECLOCK 0x8005 /* EClock frequency (u_long) */ -#define BI_AMIGA_CHIPSET 0x8006 /* native chipset present (u_long) */ -#define BI_AMIGA_SERPER 0x8007 /* serial port period (u_short) */ - - /* - * Atari-specific tags - */ - -#define BI_ATARI_MCH_COOKIE 0x8000 /* _MCH cookie from TOS (u_long) */ -#define BI_ATARI_MCH_TYPE 0x8001 /* special machine type (u_long) */ - /* (values are ATARI_MACH_* defines */ - -/* mch_cookie values (upper word) */ -#define ATARI_MCH_ST 0 -#define ATARI_MCH_STE 1 -#define ATARI_MCH_TT 2 -#define ATARI_MCH_FALCON 3 - -/* mch_type values */ -#define ATARI_MACH_NORMAL 0 /* no special machine type */ -#define ATARI_MACH_MEDUSA 1 /* Medusa 040 */ -#define ATARI_MACH_HADES 2 /* Hades 040 or 060 */ -#define ATARI_MACH_AB40 3 /* Afterburner040 on Falcon */ - - /* - * VME-specific tags - */ - -#define BI_VME_TYPE 0x8000 /* VME sub-architecture (u_long) */ -#define BI_VME_BRDINFO 0x8001 /* VME board information (struct) */ - -/* BI_VME_TYPE codes */ -#define VME_TYPE_TP34V 0x0034 /* Tadpole TP34V */ -#define VME_TYPE_MVME147 0x0147 /* Motorola MVME147 */ -#define VME_TYPE_MVME162 0x0162 /* Motorola MVME162 */ -#define VME_TYPE_MVME166 0x0166 /* Motorola MVME166 */ -#define VME_TYPE_MVME167 0x0167 /* Motorola MVME167 */ -#define VME_TYPE_MVME172 0x0172 /* Motorola MVME172 */ -#define VME_TYPE_MVME177 0x0177 /* Motorola MVME177 */ -#define VME_TYPE_BVME4000 0x4000 /* BVM Ltd. BVME4000 */ -#define VME_TYPE_BVME6000 0x6000 /* BVM Ltd. BVME6000 */ - -/* BI_VME_BRDINFO is a 32 byte struct as returned by the Bug code on - * Motorola VME boards. Contains board number, Bug version, board - * configuration options, etc. See include/asm/mvme16xhw.h for details. - */ - - - /* - * Macintosh-specific tags (all u_long) - */ - -#define BI_MAC_MODEL 0x8000 /* Mac Gestalt ID (model type) */ -#define BI_MAC_VADDR 0x8001 /* Mac video base address */ -#define BI_MAC_VDEPTH 0x8002 /* Mac video depth */ -#define BI_MAC_VROW 0x8003 /* Mac video rowbytes */ -#define BI_MAC_VDIM 0x8004 /* Mac video dimensions */ -#define BI_MAC_VLOGICAL 0x8005 /* Mac video logical base */ -#define BI_MAC_SCCBASE 0x8006 /* Mac SCC base address */ -#define BI_MAC_BTIME 0x8007 /* Mac boot time */ -#define BI_MAC_GMTBIAS 0x8008 /* Mac GMT timezone offset */ -#define BI_MAC_MEMSIZE 0x8009 /* Mac RAM size (sanity check) */ -#define BI_MAC_CPUID 0x800a /* Mac CPU type (sanity check) */ -#define BI_MAC_ROMBASE 0x800b /* Mac system ROM base address */ - - /* - * Macintosh hardware profile data - unused, see macintosh.h for - * resonable type values - */ - -#define BI_MAC_VIA1BASE 0x8010 /* Mac VIA1 base address (always present) */ -#define BI_MAC_VIA2BASE 0x8011 /* Mac VIA2 base address (type varies) */ -#define BI_MAC_VIA2TYPE 0x8012 /* Mac VIA2 type (VIA, RBV, OSS) */ -#define BI_MAC_ADBTYPE 0x8013 /* Mac ADB interface type */ -#define BI_MAC_ASCBASE 0x8014 /* Mac Apple Sound Chip base address */ -#define BI_MAC_SCSI5380 0x8015 /* Mac NCR 5380 SCSI (base address, multi) */ -#define BI_MAC_SCSIDMA 0x8016 /* Mac SCSI DMA (base address) */ -#define BI_MAC_SCSI5396 0x8017 /* Mac NCR 53C96 SCSI (base address, multi) */ -#define BI_MAC_IDETYPE 0x8018 /* Mac IDE interface type */ -#define BI_MAC_IDEBASE 0x8019 /* Mac IDE interface base address */ -#define BI_MAC_NUBUS 0x801a /* Mac Nubus type (none, regular, pseudo) */ -#define BI_MAC_SLOTMASK 0x801b /* Mac Nubus slots present */ -#define BI_MAC_SCCTYPE 0x801c /* Mac SCC serial type (normal, IOP) */ -#define BI_MAC_ETHTYPE 0x801d /* Mac builtin ethernet type (Sonic, MACE */ -#define BI_MAC_ETHBASE 0x801e /* Mac builtin ethernet base address */ -#define BI_MAC_PMU 0x801f /* Mac power management / poweroff hardware */ -#define BI_MAC_IOP_SWIM 0x8020 /* Mac SWIM floppy IOP */ -#define BI_MAC_IOP_ADB 0x8021 /* Mac ADB IOP */ - - /* - * Mac: compatibility with old booter data format (temporarily) - * Fields unused with the new bootinfo can be deleted now; instead of - * adding new fields the struct might be splitted into a hardware address - * part and a hardware type part - */ - -#ifndef __ASSEMBLY__ - -struct mac_booter_data -{ - unsigned long videoaddr; - unsigned long videorow; - unsigned long videodepth; - unsigned long dimensions; - unsigned long args; - unsigned long boottime; - unsigned long gmtbias; - unsigned long bootver; - unsigned long videological; - unsigned long sccbase; - unsigned long id; - unsigned long memsize; - unsigned long serialmf; - unsigned long serialhsk; - unsigned long serialgpi; - unsigned long printmf; - unsigned long printhsk; - unsigned long printgpi; - unsigned long cpuid; - unsigned long rombase; - unsigned long adbdelay; - unsigned long timedbra; -}; - -extern struct mac_booter_data - mac_bi_data; - -#endif - - /* - * Apollo-specific tags - */ - -#define BI_APOLLO_MODEL 0x8000 /* model (u_long) */ - - /* - * HP300-specific tags - */ - -#define BI_HP300_MODEL 0x8000 /* model (u_long) */ -#define BI_HP300_UART_SCODE 0x8001 /* UART select code (u_long) */ -#define BI_HP300_UART_ADDR 0x8002 /* phys. addr of UART (u_long) */ - - /* - * Stuff for bootinfo interface versioning - * - * At the start of kernel code, a 'struct bootversion' is located. - * bootstrap checks for a matching version of the interface before booting - * a kernel, to avoid user confusion if kernel and bootstrap don't work - * together :-) - * - * If incompatible changes are made to the bootinfo interface, the major - * number below should be stepped (and the minor reset to 0) for the - * appropriate machine. If a change is backward-compatible, the minor - * should be stepped. "Backwards-compatible" means that booting will work, - * but certain features may not. - */ - -#define BOOTINFOV_MAGIC 0x4249561A /* 'BIV^Z' */ -#define MK_BI_VERSION(major,minor) (((major)<<16)+(minor)) -#define BI_VERSION_MAJOR(v) (((v) >> 16) & 0xffff) -#define BI_VERSION_MINOR(v) ((v) & 0xffff) - -#ifndef __ASSEMBLY__ - -struct bootversion { - unsigned short branch; - unsigned long magic; - struct { - unsigned long machtype; - unsigned long version; - } machversions[0]; -}; - -#endif /* __ASSEMBLY__ */ - -#define AMIGA_BOOTI_VERSION MK_BI_VERSION( 2, 0 ) -#define ATARI_BOOTI_VERSION MK_BI_VERSION( 2, 1 ) -#define MAC_BOOTI_VERSION MK_BI_VERSION( 2, 0 ) -#define MVME147_BOOTI_VERSION MK_BI_VERSION( 2, 0 ) -#define MVME16x_BOOTI_VERSION MK_BI_VERSION( 2, 0 ) -#define BVME6000_BOOTI_VERSION MK_BI_VERSION( 2, 0 ) -#define Q40_BOOTI_VERSION MK_BI_VERSION( 2, 0 ) -#define HP300_BOOTI_VERSION MK_BI_VERSION( 2, 0 ) - -#ifdef BOOTINFO_COMPAT_1_0 - - /* - * Backwards compatibility with bootinfo interface version 1.0 - */ - -#define COMPAT_AMIGA_BOOTI_VERSION MK_BI_VERSION( 1, 0 ) -#define COMPAT_ATARI_BOOTI_VERSION MK_BI_VERSION( 1, 0 ) -#define COMPAT_MAC_BOOTI_VERSION MK_BI_VERSION( 1, 0 ) - -#include - -#define COMPAT_NUM_AUTO 16 - -struct compat_bi_Amiga { - int model; - int num_autocon; - struct ConfigDev autocon[COMPAT_NUM_AUTO]; - unsigned long chip_size; - unsigned char vblank; - unsigned char psfreq; - unsigned long eclock; - unsigned long chipset; - unsigned long hw_present; -}; - -struct compat_bi_Atari { - unsigned long hw_present; - unsigned long mch_cookie; -}; - -#ifndef __ASSEMBLY__ - -struct compat_bi_Macintosh -{ - unsigned long videoaddr; - unsigned long videorow; - unsigned long videodepth; - unsigned long dimensions; - unsigned long args; - unsigned long boottime; - unsigned long gmtbias; - unsigned long bootver; - unsigned long videological; - unsigned long sccbase; - unsigned long id; - unsigned long memsize; - unsigned long serialmf; - unsigned long serialhsk; - unsigned long serialgpi; - unsigned long printmf; - unsigned long printhsk; - unsigned long printgpi; - unsigned long cpuid; - unsigned long rombase; - unsigned long adbdelay; - unsigned long timedbra; -}; - -#endif - -struct compat_mem_info { - unsigned long addr; - unsigned long size; -}; - -#define COMPAT_NUM_MEMINFO 4 - -#define COMPAT_CPUB_68020 0 -#define COMPAT_CPUB_68030 1 -#define COMPAT_CPUB_68040 2 -#define COMPAT_CPUB_68060 3 -#define COMPAT_FPUB_68881 5 -#define COMPAT_FPUB_68882 6 -#define COMPAT_FPUB_68040 7 -#define COMPAT_FPUB_68060 8 - -#define COMPAT_CPU_68020 (1< - -#endif diff --git a/include/asm-m68k/bugs.h b/include/asm-m68k/bugs.h deleted file mode 100644 index d0193559241..00000000000 --- a/include/asm-m68k/bugs.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * include/asm-m68k/bugs.h - * - * Copyright (C) 1994 Linus Torvalds - */ - -/* - * This is included by init/main.c to check for architecture-dependent bugs. - * - * Needs: - * void check_bugs(void); - */ - -extern void check_bugs(void); /* in arch/m68k/kernel/setup.c */ diff --git a/include/asm-m68k/bvme6000hw.h b/include/asm-m68k/bvme6000hw.h deleted file mode 100644 index f40d2f8510e..00000000000 --- a/include/asm-m68k/bvme6000hw.h +++ /dev/null @@ -1,150 +0,0 @@ -#ifndef _M68K_BVME6000HW_H_ -#define _M68K_BVME6000HW_H_ - -#include - -/* - * PIT structure - */ - -#define BVME_PIT_BASE 0xffa00000 - -typedef struct { - unsigned char - pad_a[3], pgcr, - pad_b[3], psrr, - pad_c[3], paddr, - pad_d[3], pbddr, - pad_e[3], pcddr, - pad_f[3], pivr, - pad_g[3], pacr, - pad_h[3], pbcr, - pad_i[3], padr, - pad_j[3], pbdr, - pad_k[3], paar, - pad_l[3], pbar, - pad_m[3], pcdr, - pad_n[3], psr, - pad_o[3], res1, - pad_p[3], res2, - pad_q[3], tcr, - pad_r[3], tivr, - pad_s[3], res3, - pad_t[3], cprh, - pad_u[3], cprm, - pad_v[3], cprl, - pad_w[3], res4, - pad_x[3], crh, - pad_y[3], crm, - pad_z[3], crl, - pad_A[3], tsr, - pad_B[3], res5; -} PitRegs_t, *PitRegsPtr; - -#define bvmepit ((*(volatile PitRegsPtr)(BVME_PIT_BASE))) - -#define BVME_RTC_BASE 0xff900000 - -typedef struct { - unsigned char - pad_a[3], msr, - pad_b[3], t0cr_rtmr, - pad_c[3], t1cr_omr, - pad_d[3], pfr_icr0, - pad_e[3], irr_icr1, - pad_f[3], bcd_tenms, - pad_g[3], bcd_sec, - pad_h[3], bcd_min, - pad_i[3], bcd_hr, - pad_j[3], bcd_dom, - pad_k[3], bcd_mth, - pad_l[3], bcd_year, - pad_m[3], bcd_ujcc, - pad_n[3], bcd_hjcc, - pad_o[3], bcd_dow, - pad_p[3], t0lsb, - pad_q[3], t0msb, - pad_r[3], t1lsb, - pad_s[3], t1msb, - pad_t[3], cmp_sec, - pad_u[3], cmp_min, - pad_v[3], cmp_hr, - pad_w[3], cmp_dom, - pad_x[3], cmp_mth, - pad_y[3], cmp_dow, - pad_z[3], sav_sec, - pad_A[3], sav_min, - pad_B[3], sav_hr, - pad_C[3], sav_dom, - pad_D[3], sav_mth, - pad_E[3], ram, - pad_F[3], test; -} RtcRegs_t, *RtcPtr_t; - - -#define BVME_I596_BASE 0xff100000 - -#define BVME_ETHIRQ_REG 0xff20000b - -#define BVME_LOCAL_IRQ_STAT 0xff20000f - -#define BVME_ETHERR 0x02 -#define BVME_ABORT_STATUS 0x08 - -#define BVME_NCR53C710_BASE 0xff000000 - -#define BVME_SCC_A_ADDR 0xffb0000b -#define BVME_SCC_B_ADDR 0xffb00003 -#define BVME_SCC_RTxC 7372800 - -#define BVME_CONFIG_REG 0xff500003 - -#define config_reg_ptr (volatile unsigned char *)BVME_CONFIG_REG - -#define BVME_CONFIG_SW1 0x08 -#define BVME_CONFIG_SW2 0x04 -#define BVME_CONFIG_SW3 0x02 -#define BVME_CONFIG_SW4 0x01 - - -#define BVME_IRQ_TYPE_PRIO 0 - -#define BVME_IRQ_PRN (IRQ_USER+20) -#define BVME_IRQ_TIMER (IRQ_USER+25) -#define BVME_IRQ_I596 IRQ_AUTO_2 -#define BVME_IRQ_SCSI IRQ_AUTO_3 -#define BVME_IRQ_RTC IRQ_AUTO_6 -#define BVME_IRQ_ABORT IRQ_AUTO_7 - -/* SCC interrupts */ -#define BVME_IRQ_SCC_BASE IRQ_USER -#define BVME_IRQ_SCCB_TX IRQ_USER -#define BVME_IRQ_SCCB_STAT (IRQ_USER+2) -#define BVME_IRQ_SCCB_RX (IRQ_USER+4) -#define BVME_IRQ_SCCB_SPCOND (IRQ_USER+6) -#define BVME_IRQ_SCCA_TX (IRQ_USER+8) -#define BVME_IRQ_SCCA_STAT (IRQ_USER+10) -#define BVME_IRQ_SCCA_RX (IRQ_USER+12) -#define BVME_IRQ_SCCA_SPCOND (IRQ_USER+14) - -/* Address control registers */ - -#define BVME_ACR_A32VBA 0xff400003 -#define BVME_ACR_A32MSK 0xff410003 -#define BVME_ACR_A24VBA 0xff420003 -#define BVME_ACR_A24MSK 0xff430003 -#define BVME_ACR_A16VBA 0xff440003 -#define BVME_ACR_A32LBA 0xff450003 -#define BVME_ACR_A24LBA 0xff460003 -#define BVME_ACR_ADDRCTL 0xff470003 - -#define bvme_acr_a32vba *(volatile unsigned char *)BVME_ACR_A32VBA -#define bvme_acr_a32msk *(volatile unsigned char *)BVME_ACR_A32MSK -#define bvme_acr_a24vba *(volatile unsigned char *)BVME_ACR_A24VBA -#define bvme_acr_a24msk *(volatile unsigned char *)BVME_ACR_A24MSK -#define bvme_acr_a16vba *(volatile unsigned char *)BVME_ACR_A16VBA -#define bvme_acr_a32lba *(volatile unsigned char *)BVME_ACR_A32LBA -#define bvme_acr_a24lba *(volatile unsigned char *)BVME_ACR_A24LBA -#define bvme_acr_addrctl *(volatile unsigned char *)BVME_ACR_ADDRCTL - -#endif diff --git a/include/asm-m68k/byteorder.h b/include/asm-m68k/byteorder.h deleted file mode 100644 index 300866523b8..00000000000 --- a/include/asm-m68k/byteorder.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _M68K_BYTEORDER_H -#define _M68K_BYTEORDER_H - -#include -#include - -#endif /* _M68K_BYTEORDER_H */ diff --git a/include/asm-m68k/cache.h b/include/asm-m68k/cache.h deleted file mode 100644 index fed3fd30de7..00000000000 --- a/include/asm-m68k/cache.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * include/asm-m68k/cache.h - */ -#ifndef __ARCH_M68K_CACHE_H -#define __ARCH_M68K_CACHE_H - -/* bytes per L1 cache line */ -#define L1_CACHE_SHIFT 4 -#define L1_CACHE_BYTES (1<< L1_CACHE_SHIFT) - -#endif diff --git a/include/asm-m68k/cachectl.h b/include/asm-m68k/cachectl.h deleted file mode 100644 index 525978e959e..00000000000 --- a/include/asm-m68k/cachectl.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _M68K_CACHECTL_H -#define _M68K_CACHECTL_H - -/* Definitions for the cacheflush system call. */ - -#define FLUSH_SCOPE_LINE 1 /* Flush a cache line */ -#define FLUSH_SCOPE_PAGE 2 /* Flush a page */ -#define FLUSH_SCOPE_ALL 3 /* Flush the whole cache -- superuser only */ - -#define FLUSH_CACHE_DATA 1 /* Writeback and flush data cache */ -#define FLUSH_CACHE_INSN 2 /* Flush instruction cache */ -#define FLUSH_CACHE_BOTH 3 /* Flush both caches */ - -#endif /* _M68K_CACHECTL_H */ diff --git a/include/asm-m68k/cacheflush.h b/include/asm-m68k/cacheflush.h deleted file mode 100644 index 16bf375fdbe..00000000000 --- a/include/asm-m68k/cacheflush.h +++ /dev/null @@ -1,156 +0,0 @@ -#ifndef _M68K_CACHEFLUSH_H -#define _M68K_CACHEFLUSH_H - -#include - -/* cache code */ -#define FLUSH_I_AND_D (0x00000808) -#define FLUSH_I (0x00000008) - -/* - * Cache handling functions - */ - -static inline void flush_icache(void) -{ - if (CPU_IS_040_OR_060) - asm volatile ( "nop\n" - " .chip 68040\n" - " cpusha %bc\n" - " .chip 68k"); - else { - unsigned long tmp; - asm volatile ( "movec %%cacr,%0\n" - " or.w %1,%0\n" - " movec %0,%%cacr" - : "=&d" (tmp) - : "id" (FLUSH_I)); - } -} - -/* - * invalidate the cache for the specified memory range. - * It starts at the physical address specified for - * the given number of bytes. - */ -extern void cache_clear(unsigned long paddr, int len); -/* - * push any dirty cache in the specified memory range. - * It starts at the physical address specified for - * the given number of bytes. - */ -extern void cache_push(unsigned long paddr, int len); - -/* - * push and invalidate pages in the specified user virtual - * memory range. - */ -extern void cache_push_v(unsigned long vaddr, int len); - -/* This is needed whenever the virtual mapping of the current - process changes. */ -#define __flush_cache_all() \ -({ \ - if (CPU_IS_040_OR_060) \ - __asm__ __volatile__("nop\n\t" \ - ".chip 68040\n\t" \ - "cpusha %dc\n\t" \ - ".chip 68k"); \ - else { \ - unsigned long _tmp; \ - __asm__ __volatile__("movec %%cacr,%0\n\t" \ - "orw %1,%0\n\t" \ - "movec %0,%%cacr" \ - : "=&d" (_tmp) \ - : "di" (FLUSH_I_AND_D)); \ - } \ -}) - -#define __flush_cache_030() \ -({ \ - if (CPU_IS_020_OR_030) { \ - unsigned long _tmp; \ - __asm__ __volatile__("movec %%cacr,%0\n\t" \ - "orw %1,%0\n\t" \ - "movec %0,%%cacr" \ - : "=&d" (_tmp) \ - : "di" (FLUSH_I_AND_D)); \ - } \ -}) - -#define flush_cache_all() __flush_cache_all() - -#define flush_cache_vmap(start, end) flush_cache_all() -#define flush_cache_vunmap(start, end) flush_cache_all() - -static inline void flush_cache_mm(struct mm_struct *mm) -{ - if (mm == current->mm) - __flush_cache_030(); -} - -#define flush_cache_dup_mm(mm) flush_cache_mm(mm) - -/* flush_cache_range/flush_cache_page must be macros to avoid - a dependency on linux/mm.h, which includes this file... */ -static inline void flush_cache_range(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - if (vma->vm_mm == current->mm) - __flush_cache_030(); -} - -static inline void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn) -{ - if (vma->vm_mm == current->mm) - __flush_cache_030(); -} - - -/* Push the page at kernel virtual address and clear the icache */ -/* RZ: use cpush %bc instead of cpush %dc, cinv %ic */ -static inline void __flush_page_to_ram(void *vaddr) -{ - if (CPU_IS_040_OR_060) { - __asm__ __volatile__("nop\n\t" - ".chip 68040\n\t" - "cpushp %%bc,(%0)\n\t" - ".chip 68k" - : : "a" (__pa(vaddr))); - } else { - unsigned long _tmp; - __asm__ __volatile__("movec %%cacr,%0\n\t" - "orw %1,%0\n\t" - "movec %0,%%cacr" - : "=&d" (_tmp) - : "di" (FLUSH_I)); - } -} - -#define flush_dcache_page(page) __flush_page_to_ram(page_address(page)) -#define flush_dcache_mmap_lock(mapping) do { } while (0) -#define flush_dcache_mmap_unlock(mapping) do { } while (0) -#define flush_icache_page(vma, page) __flush_page_to_ram(page_address(page)) - -extern void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, - unsigned long addr, int len); -extern void flush_icache_range(unsigned long address, unsigned long endaddr); - -static inline void copy_to_user_page(struct vm_area_struct *vma, - struct page *page, unsigned long vaddr, - void *dst, void *src, int len) -{ - flush_cache_page(vma, vaddr, page_to_pfn(page)); - memcpy(dst, src, len); - flush_icache_user_range(vma, page, vaddr, len); -} -static inline void copy_from_user_page(struct vm_area_struct *vma, - struct page *page, unsigned long vaddr, - void *dst, void *src, int len) -{ - flush_cache_page(vma, vaddr, page_to_pfn(page)); - memcpy(dst, src, len); -} - -#endif /* _M68K_CACHEFLUSH_H */ diff --git a/include/asm-m68k/checksum.h b/include/asm-m68k/checksum.h deleted file mode 100644 index 494f9aec37e..00000000000 --- a/include/asm-m68k/checksum.h +++ /dev/null @@ -1,148 +0,0 @@ -#ifndef _M68K_CHECKSUM_H -#define _M68K_CHECKSUM_H - -#include - -/* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -__wsum csum_partial(const void *buff, int len, __wsum sum); - -/* - * the same as csum_partial, but copies from src while it - * checksums - * - * here even more important to align src and dst on a 32-bit (or even - * better 64-bit) boundary - */ - -extern __wsum csum_partial_copy_from_user(const void __user *src, - void *dst, - int len, __wsum sum, - int *csum_err); - -extern __wsum csum_partial_copy_nocheck(const void *src, - void *dst, int len, - __wsum sum); - -/* - * This is a version of ip_compute_csum() optimized for IP headers, - * which always checksum on 4 octet boundaries. - * - */ -static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) -{ - unsigned int sum = 0; - unsigned long tmp; - - __asm__ ("subqw #1,%2\n" - "1:\t" - "movel %1@+,%3\n\t" - "addxl %3,%0\n\t" - "dbra %2,1b\n\t" - "movel %0,%3\n\t" - "swap %3\n\t" - "addxw %3,%0\n\t" - "clrw %3\n\t" - "addxw %3,%0\n\t" - : "=d" (sum), "=&a" (iph), "=&d" (ihl), "=&d" (tmp) - : "0" (sum), "1" (iph), "2" (ihl) - : "memory"); - return (__force __sum16)~sum; -} - -/* - * Fold a partial checksum - */ - -static inline __sum16 csum_fold(__wsum sum) -{ - unsigned int tmp = (__force u32)sum; - __asm__("swap %1\n\t" - "addw %1, %0\n\t" - "clrw %1\n\t" - "addxw %1, %0" - : "=&d" (sum), "=&d" (tmp) - : "0" (sum), "1" (tmp)); - return (__force __sum16)~sum; -} - - -static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) -{ - __asm__ ("addl %2,%0\n\t" - "addxl %3,%0\n\t" - "addxl %4,%0\n\t" - "clrl %1\n\t" - "addxl %1,%0" - : "=&d" (sum), "=d" (saddr) - : "g" (daddr), "1" (saddr), "d" (len + proto), - "0" (sum)); - return sum; -} - - -/* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented - */ -static inline __sum16 -csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) -{ - return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); -} - -/* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ - -static inline __sum16 ip_compute_csum(const void *buff, int len) -{ - return csum_fold (csum_partial(buff, len, 0)); -} - -#define _HAVE_ARCH_IPV6_CSUM -static __inline__ __sum16 -csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, - __u32 len, unsigned short proto, __wsum sum) -{ - register unsigned long tmp; - __asm__("addl %2@,%0\n\t" - "movel %2@(4),%1\n\t" - "addxl %1,%0\n\t" - "movel %2@(8),%1\n\t" - "addxl %1,%0\n\t" - "movel %2@(12),%1\n\t" - "addxl %1,%0\n\t" - "movel %3@,%1\n\t" - "addxl %1,%0\n\t" - "movel %3@(4),%1\n\t" - "addxl %1,%0\n\t" - "movel %3@(8),%1\n\t" - "addxl %1,%0\n\t" - "movel %3@(12),%1\n\t" - "addxl %1,%0\n\t" - "addxl %4,%0\n\t" - "clrl %1\n\t" - "addxl %1,%0" - : "=&d" (sum), "=&d" (tmp) - : "a" (saddr), "a" (daddr), "d" (len + proto), - "0" (sum)); - - return csum_fold(sum); -} - -#endif /* _M68K_CHECKSUM_H */ diff --git a/include/asm-m68k/contregs.h b/include/asm-m68k/contregs.h deleted file mode 100644 index d1ea750bddf..00000000000 --- a/include/asm-m68k/contregs.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef _M68K_CONTREGS_H -#define _M68K_CONTREGS_H - -/* contregs.h: Addresses of registers in the ASI_CONTROL alternate address - * space. These are for the mmu's context register, etc. - * - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) - */ - -/* 3=sun3 - 4=sun4 (as in sun4 sysmaint student book) - c=sun4c (according to davem) */ - -#define AC_IDPROM 0x00000000 /* 34 ID PROM, R/O, byte, 32 bytes */ -#define AC_PAGEMAP 0x10000000 /* 3 Pagemap R/W, long */ -#define AC_SEGMAP 0x20000000 /* 3 Segment map, byte */ -#define AC_CONTEXT 0x30000000 /* 34c current mmu-context */ -#define AC_SENABLE 0x40000000 /* 34c system dvma/cache/reset enable reg*/ -#define AC_UDVMA_ENB 0x50000000 /* 34 Not used on Sun boards, byte */ -#define AC_BUS_ERROR 0x60000000 /* 34 Not cleared on read, byte. */ -#define AC_SYNC_ERR 0x60000000 /* c fault type */ -#define AC_SYNC_VA 0x60000004 /* c fault virtual address */ -#define AC_ASYNC_ERR 0x60000008 /* c asynchronous fault type */ -#define AC_ASYNC_VA 0x6000000c /* c async fault virtual address */ -#define AC_LEDS 0x70000000 /* 34 Zero turns on LEDs, byte */ -#define AC_CACHETAGS 0x80000000 /* 34c direct access to the VAC tags */ -#define AC_CACHEDDATA 0x90000000 /* 3 c direct access to the VAC data */ -#define AC_UDVMA_MAP 0xD0000000 /* 4 Not used on Sun boards, byte */ -#define AC_VME_VECTOR 0xE0000000 /* 4 For non-Autovector VME, byte */ -#define AC_BOOT_SCC 0xF0000000 /* 34 bypass to access Zilog 8530. byte.*/ - -/* s=Swift, h=Ross_HyperSPARC, v=TI_Viking, t=Tsunami, r=Ross_Cypress */ -#define AC_M_PCR 0x0000 /* shv Processor Control Reg */ -#define AC_M_CTPR 0x0100 /* shv Context Table Pointer Reg */ -#define AC_M_CXR 0x0200 /* shv Context Register */ -#define AC_M_SFSR 0x0300 /* shv Synchronous Fault Status Reg */ -#define AC_M_SFAR 0x0400 /* shv Synchronous Fault Address Reg */ -#define AC_M_AFSR 0x0500 /* hv Asynchronous Fault Status Reg */ -#define AC_M_AFAR 0x0600 /* hv Asynchronous Fault Address Reg */ -#define AC_M_RESET 0x0700 /* hv Reset Reg */ -#define AC_M_RPR 0x1000 /* hv Root Pointer Reg */ -#define AC_M_TSUTRCR 0x1000 /* s TLB Replacement Ctrl Reg */ -#define AC_M_IAPTP 0x1100 /* hv Instruction Access PTP */ -#define AC_M_DAPTP 0x1200 /* hv Data Access PTP */ -#define AC_M_ITR 0x1300 /* hv Index Tag Register */ -#define AC_M_TRCR 0x1400 /* hv TLB Replacement Control Reg */ -#define AC_M_SFSRX 0x1300 /* s Synch Fault Status Reg prim */ -#define AC_M_SFARX 0x1400 /* s Synch Fault Address Reg prim */ -#define AC_M_RPR1 0x1500 /* h Root Pointer Reg (entry 2) */ -#define AC_M_IAPTP1 0x1600 /* h Instruction Access PTP (entry 2) */ -#define AC_M_DAPTP1 0x1700 /* h Data Access PTP (entry 2) */ - -#endif /* _M68K_CONTREGS_H */ diff --git a/include/asm-m68k/cputime.h b/include/asm-m68k/cputime.h deleted file mode 100644 index c79c5e89230..00000000000 --- a/include/asm-m68k/cputime.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __M68K_CPUTIME_H -#define __M68K_CPUTIME_H - -#include - -#endif /* __M68K_CPUTIME_H */ diff --git a/include/asm-m68k/current.h b/include/asm-m68k/current.h deleted file mode 100644 index 8de8f8ceda6..00000000000 --- a/include/asm-m68k/current.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _M68K_CURRENT_H -#define _M68K_CURRENT_H - -register struct task_struct *current __asm__("%a2"); - -#endif /* !(_M68K_CURRENT_H) */ diff --git a/include/asm-m68k/delay.h b/include/asm-m68k/delay.h deleted file mode 100644 index 5ed92851bc6..00000000000 --- a/include/asm-m68k/delay.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef _M68K_DELAY_H -#define _M68K_DELAY_H - -#include - -/* - * Copyright (C) 1994 Hamish Macdonald - * - * Delay routines, using a pre-computed "loops_per_jiffy" value. - */ - -static inline void __delay(unsigned long loops) -{ - __asm__ __volatile__ ("1: subql #1,%0; jcc 1b" - : "=d" (loops) : "0" (loops)); -} - -extern void __bad_udelay(void); - -/* - * Use only for very small delays ( < 1 msec). Should probably use a - * lookup table, really, as the multiplications take much too long with - * short delays. This is a "reasonable" implementation, though (and the - * first constant multiplications gets optimized away if the delay is - * a constant) - */ -static inline void __const_udelay(unsigned long xloops) -{ - unsigned long tmp; - - __asm__ ("mulul %2,%0:%1" - : "=d" (xloops), "=d" (tmp) - : "d" (xloops), "1" (loops_per_jiffy)); - __delay(xloops * HZ); -} - -static inline void __udelay(unsigned long usecs) -{ - __const_udelay(usecs * 4295); /* 2**32 / 1000000 */ -} - -#define udelay(n) (__builtin_constant_p(n) ? \ - ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 4295)) : \ - __udelay(n)) - -static inline unsigned long muldiv(unsigned long a, unsigned long b, - unsigned long c) -{ - unsigned long tmp; - - __asm__ ("mulul %2,%0:%1; divul %3,%0:%1" - : "=d" (tmp), "=d" (a) - : "d" (b), "d" (c), "1" (a)); - return a; -} - -#endif /* defined(_M68K_DELAY_H) */ diff --git a/include/asm-m68k/device.h b/include/asm-m68k/device.h deleted file mode 100644 index d8f9872b0e2..00000000000 --- a/include/asm-m68k/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include - diff --git a/include/asm-m68k/div64.h b/include/asm-m68k/div64.h deleted file mode 100644 index 8243c931b5c..00000000000 --- a/include/asm-m68k/div64.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _M68K_DIV64_H -#define _M68K_DIV64_H - -#include - -/* n = n / base; return rem; */ - -#define do_div(n, base) ({ \ - union { \ - unsigned long n32[2]; \ - unsigned long long n64; \ - } __n; \ - unsigned long __rem, __upper; \ - \ - __n.n64 = (n); \ - if ((__upper = __n.n32[0])) { \ - asm ("divul.l %2,%1:%0" \ - : "=d" (__n.n32[0]), "=d" (__upper) \ - : "d" (base), "0" (__n.n32[0])); \ - } \ - asm ("divu.l %2,%1:%0" \ - : "=d" (__n.n32[1]), "=d" (__rem) \ - : "d" (base), "1" (__upper), "0" (__n.n32[1])); \ - (n) = __n.n64; \ - __rem; \ -}) - -#endif /* _M68K_DIV64_H */ diff --git a/include/asm-m68k/dma-mapping.h b/include/asm-m68k/dma-mapping.h deleted file mode 100644 index 26f505488c1..00000000000 --- a/include/asm-m68k/dma-mapping.h +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef _M68K_DMA_MAPPING_H -#define _M68K_DMA_MAPPING_H - -#include - -struct scatterlist; - -#ifndef CONFIG_MMU_SUN3 -static inline int dma_supported(struct device *dev, u64 mask) -{ - return 1; -} - -static inline int dma_set_mask(struct device *dev, u64 mask) -{ - return 0; -} - -static inline int dma_get_cache_alignment(void) -{ - return 1 << L1_CACHE_SHIFT; -} - -static inline int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) -{ - return 0; -} - -extern void *dma_alloc_coherent(struct device *, size_t, - dma_addr_t *, gfp_t); -extern void dma_free_coherent(struct device *, size_t, - void *, dma_addr_t); - -static inline void *dma_alloc_noncoherent(struct device *dev, size_t size, - dma_addr_t *handle, gfp_t flag) -{ - return dma_alloc_coherent(dev, size, handle, flag); -} -static inline void dma_free_noncoherent(struct device *dev, size_t size, - void *addr, dma_addr_t handle) -{ - dma_free_coherent(dev, size, addr, handle); -} -static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, - enum dma_data_direction dir) -{ - /* we use coherent allocation, so not much to do here. */ -} - -extern dma_addr_t dma_map_single(struct device *, void *, size_t, - enum dma_data_direction); -static inline void dma_unmap_single(struct device *dev, dma_addr_t addr, - size_t size, enum dma_data_direction dir) -{ -} - -extern dma_addr_t dma_map_page(struct device *, struct page *, - unsigned long, size_t size, - enum dma_data_direction); -static inline void dma_unmap_page(struct device *dev, dma_addr_t address, - size_t size, enum dma_data_direction dir) -{ -} - -extern int dma_map_sg(struct device *, struct scatterlist *, int, - enum dma_data_direction); -static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg, - int nhwentries, enum dma_data_direction dir) -{ -} - -extern void dma_sync_single_for_device(struct device *, dma_addr_t, size_t, - enum dma_data_direction); -extern void dma_sync_sg_for_device(struct device *, struct scatterlist *, int, - enum dma_data_direction); - -static inline void dma_sync_single_range_for_device(struct device *dev, - dma_addr_t dma_handle, unsigned long offset, size_t size, - enum dma_data_direction direction) -{ - /* just sync everything for now */ - dma_sync_single_for_device(dev, dma_handle, offset + size, direction); -} - -static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, - size_t size, enum dma_data_direction dir) -{ -} - -static inline void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction dir) -{ -} - -static inline void dma_sync_single_range_for_cpu(struct device *dev, - dma_addr_t dma_handle, unsigned long offset, size_t size, - enum dma_data_direction direction) -{ - /* just sync everything for now */ - dma_sync_single_for_cpu(dev, dma_handle, offset + size, direction); -} - -static inline int dma_mapping_error(struct device *dev, dma_addr_t handle) -{ - return 0; -} - -#else -#include -#endif - -#endif /* _M68K_DMA_MAPPING_H */ diff --git a/include/asm-m68k/dma.h b/include/asm-m68k/dma.h deleted file mode 100644 index 4240fbc946f..00000000000 --- a/include/asm-m68k/dma.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _M68K_DMA_H -#define _M68K_DMA_H 1 - - -/* it's useless on the m68k, but unfortunately needed by the new - bootmem allocator (but this should do it for this) */ -#define MAX_DMA_ADDRESS PAGE_OFFSET - -#define MAX_DMA_CHANNELS 8 - -extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ -extern void free_dma(unsigned int dmanr); /* release it again */ - -#define isa_dma_bridge_buggy (0) - -#endif /* _M68K_DMA_H */ diff --git a/include/asm-m68k/dsp56k.h b/include/asm-m68k/dsp56k.h deleted file mode 100644 index 2d8c0c9f794..00000000000 --- a/include/asm-m68k/dsp56k.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * linux/include/asm-m68k/dsp56k.h - defines and declarations for - * DSP56k device driver - * - * Copyright (C) 1996,1997 Fredrik Noring, lars brinkhoff & Tomas Berndtsson - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - - -/* Used for uploading DSP binary code */ -struct dsp56k_upload { - int len; - char __user *bin; -}; - -/* For the DSP host flags */ -struct dsp56k_host_flags { - int dir; /* Bit field. 1 = write output bit, 0 = do nothing. - * 0x0000 means reading only, 0x0011 means - * writing the bits stored in `out' on HF0 and HF1. - * Note that HF2 and HF3 can only be read. - */ - int out; /* Bit field like above. */ - int status; /* Host register's current state is returned */ -}; - -/* ioctl command codes */ -#define DSP56K_UPLOAD 1 /* Upload DSP binary program */ -#define DSP56K_SET_TX_WSIZE 2 /* Host transmit word size (1-4) */ -#define DSP56K_SET_RX_WSIZE 3 /* Host receive word size (1-4) */ -#define DSP56K_HOST_FLAGS 4 /* Host flag registers */ -#define DSP56K_HOST_CMD 5 /* Trig Host Command (0-31) */ diff --git a/include/asm-m68k/dvma.h b/include/asm-m68k/dvma.h deleted file mode 100644 index 890bbf7e775..00000000000 --- a/include/asm-m68k/dvma.h +++ /dev/null @@ -1,240 +0,0 @@ -/* - * include/asm-m68k/dma.h - * - * Copyright 1995 (C) David S. Miller (davem@caip.rutgers.edu) - * - * Hacked to fit Sun3x needs by Thomas Bogendoerfer - */ - -#ifndef __M68K_DVMA_H -#define __M68K_DVMA_H - - -#define DVMA_PAGE_SHIFT 13 -#define DVMA_PAGE_SIZE (1UL << DVMA_PAGE_SHIFT) -#define DVMA_PAGE_MASK (~(DVMA_PAGE_SIZE-1)) -#define DVMA_PAGE_ALIGN(addr) ALIGN(addr, DVMA_PAGE_SIZE) - -extern void dvma_init(void); -extern int dvma_map_iommu(unsigned long kaddr, unsigned long baddr, - int len); - -#define dvma_malloc(x) dvma_malloc_align(x, 0) -#define dvma_map(x, y) dvma_map_align(x, y, 0) -#define dvma_map_vme(x, y) (dvma_map(x, y) & 0xfffff) -#define dvma_map_align_vme(x, y, z) (dvma_map_align (x, y, z) & 0xfffff) -extern unsigned long dvma_map_align(unsigned long kaddr, int len, - int align); -extern void *dvma_malloc_align(unsigned long len, unsigned long align); - -extern void dvma_unmap(void *baddr); -extern void dvma_free(void *vaddr); - - -#ifdef CONFIG_SUN3 -/* sun3 dvma page support */ - -/* memory and pmegs potentially reserved for dvma */ -#define DVMA_PMEG_START 10 -#define DVMA_PMEG_END 16 -#define DVMA_START 0xf00000 -#define DVMA_END 0xfe0000 -#define DVMA_SIZE (DVMA_END-DVMA_START) -#define IOMMU_TOTAL_ENTRIES 128 -#define IOMMU_ENTRIES 120 - -/* empirical kludge -- dvma regions only seem to work right on 0x10000 - byte boundaries */ -#define DVMA_REGION_SIZE 0x10000 -#define DVMA_ALIGN(addr) (((addr)+DVMA_REGION_SIZE-1) & \ - ~(DVMA_REGION_SIZE-1)) - -/* virt <-> phys conversions */ -#define dvma_vtop(x) ((unsigned long)(x) & 0xffffff) -#define dvma_ptov(x) ((unsigned long)(x) | 0xf000000) -#define dvma_vtovme(x) ((unsigned long)(x) & 0x00fffff) -#define dvma_vmetov(x) ((unsigned long)(x) | 0xff00000) -#define dvma_vtob(x) dvma_vtop(x) -#define dvma_btov(x) dvma_ptov(x) - -static inline int dvma_map_cpu(unsigned long kaddr, unsigned long vaddr, - int len) -{ - return 0; -} - -#else /* Sun3x */ - -/* sun3x dvma page support */ - -#define DVMA_START 0x0 -#define DVMA_END 0xf00000 -#define DVMA_SIZE (DVMA_END-DVMA_START) -#define IOMMU_TOTAL_ENTRIES 2048 -/* the prom takes the top meg */ -#define IOMMU_ENTRIES (IOMMU_TOTAL_ENTRIES - 0x80) - -#define dvma_vtob(x) ((unsigned long)(x) & 0x00ffffff) -#define dvma_btov(x) ((unsigned long)(x) | 0xff000000) - -extern int dvma_map_cpu(unsigned long kaddr, unsigned long vaddr, int len); - - - -/* everything below this line is specific to dma used for the onboard - ESP scsi on sun3x */ - -/* Structure to describe the current status of DMA registers on the Sparc */ -struct sparc_dma_registers { - __volatile__ unsigned long cond_reg; /* DMA condition register */ - __volatile__ unsigned long st_addr; /* Start address of this transfer */ - __volatile__ unsigned long cnt; /* How many bytes to transfer */ - __volatile__ unsigned long dma_test; /* DMA test register */ -}; - -/* DVMA chip revisions */ -enum dvma_rev { - dvmarev0, - dvmaesc1, - dvmarev1, - dvmarev2, - dvmarev3, - dvmarevplus, - dvmahme -}; - -#define DMA_HASCOUNT(rev) ((rev)==dvmaesc1) - -/* Linux DMA information structure, filled during probe. */ -struct Linux_SBus_DMA { - struct Linux_SBus_DMA *next; - struct linux_sbus_device *SBus_dev; - struct sparc_dma_registers *regs; - - /* Status, misc info */ - int node; /* Prom node for this DMA device */ - int running; /* Are we doing DMA now? */ - int allocated; /* Are we "owned" by anyone yet? */ - - /* Transfer information. */ - unsigned long addr; /* Start address of current transfer */ - int nbytes; /* Size of current transfer */ - int realbytes; /* For splitting up large transfers, etc. */ - - /* DMA revision */ - enum dvma_rev revision; -}; - -extern struct Linux_SBus_DMA *dma_chain; - -/* Broken hardware... */ -#define DMA_ISBROKEN(dma) ((dma)->revision == dvmarev1) -#define DMA_ISESC1(dma) ((dma)->revision == dvmaesc1) - -/* Fields in the cond_reg register */ -/* First, the version identification bits */ -#define DMA_DEVICE_ID 0xf0000000 /* Device identification bits */ -#define DMA_VERS0 0x00000000 /* Sunray DMA version */ -#define DMA_ESCV1 0x40000000 /* DMA ESC Version 1 */ -#define DMA_VERS1 0x80000000 /* DMA rev 1 */ -#define DMA_VERS2 0xa0000000 /* DMA rev 2 */ -#define DMA_VERHME 0xb0000000 /* DMA hme gate array */ -#define DMA_VERSPLUS 0x90000000 /* DMA rev 1 PLUS */ - -#define DMA_HNDL_INTR 0x00000001 /* An IRQ needs to be handled */ -#define DMA_HNDL_ERROR 0x00000002 /* We need to take an error */ -#define DMA_FIFO_ISDRAIN 0x0000000c /* The DMA FIFO is draining */ -#define DMA_INT_ENAB 0x00000010 /* Turn on interrupts */ -#define DMA_FIFO_INV 0x00000020 /* Invalidate the FIFO */ -#define DMA_ACC_SZ_ERR 0x00000040 /* The access size was bad */ -#define DMA_FIFO_STDRAIN 0x00000040 /* DMA_VERS1 Drain the FIFO */ -#define DMA_RST_SCSI 0x00000080 /* Reset the SCSI controller */ -#define DMA_RST_ENET DMA_RST_SCSI /* Reset the ENET controller */ -#define DMA_ST_WRITE 0x00000100 /* write from device to memory */ -#define DMA_ENABLE 0x00000200 /* Fire up DMA, handle requests */ -#define DMA_PEND_READ 0x00000400 /* DMA_VERS1/0/PLUS Pending Read */ -#define DMA_ESC_BURST 0x00000800 /* 1=16byte 0=32byte */ -#define DMA_READ_AHEAD 0x00001800 /* DMA read ahead partial longword */ -#define DMA_DSBL_RD_DRN 0x00001000 /* No EC drain on slave reads */ -#define DMA_BCNT_ENAB 0x00002000 /* If on, use the byte counter */ -#define DMA_TERM_CNTR 0x00004000 /* Terminal counter */ -#define DMA_CSR_DISAB 0x00010000 /* No FIFO drains during csr */ -#define DMA_SCSI_DISAB 0x00020000 /* No FIFO drains during reg */ -#define DMA_DSBL_WR_INV 0x00020000 /* No EC inval. on slave writes */ -#define DMA_ADD_ENABLE 0x00040000 /* Special ESC DVMA optimization */ -#define DMA_E_BURST8 0x00040000 /* ENET: SBUS r/w burst size */ -#define DMA_BRST_SZ 0x000c0000 /* SCSI: SBUS r/w burst size */ -#define DMA_BRST64 0x00080000 /* SCSI: 64byte bursts (HME on UltraSparc only) */ -#define DMA_BRST32 0x00040000 /* SCSI: 32byte bursts */ -#define DMA_BRST16 0x00000000 /* SCSI: 16byte bursts */ -#define DMA_BRST0 0x00080000 /* SCSI: no bursts (non-HME gate arrays) */ -#define DMA_ADDR_DISAB 0x00100000 /* No FIFO drains during addr */ -#define DMA_2CLKS 0x00200000 /* Each transfer = 2 clock ticks */ -#define DMA_3CLKS 0x00400000 /* Each transfer = 3 clock ticks */ -#define DMA_EN_ENETAUI DMA_3CLKS /* Put lance into AUI-cable mode */ -#define DMA_CNTR_DISAB 0x00800000 /* No IRQ when DMA_TERM_CNTR set */ -#define DMA_AUTO_NADDR 0x01000000 /* Use "auto nxt addr" feature */ -#define DMA_SCSI_ON 0x02000000 /* Enable SCSI dma */ -#define DMA_PARITY_OFF 0x02000000 /* HME: disable parity checking */ -#define DMA_LOADED_ADDR 0x04000000 /* Address has been loaded */ -#define DMA_LOADED_NADDR 0x08000000 /* Next address has been loaded */ - -/* Values describing the burst-size property from the PROM */ -#define DMA_BURST1 0x01 -#define DMA_BURST2 0x02 -#define DMA_BURST4 0x04 -#define DMA_BURST8 0x08 -#define DMA_BURST16 0x10 -#define DMA_BURST32 0x20 -#define DMA_BURST64 0x40 -#define DMA_BURSTBITS 0x7f - -/* Determine highest possible final transfer address given a base */ -#define DMA_MAXEND(addr) (0x01000000UL-(((unsigned long)(addr))&0x00ffffffUL)) - -/* Yes, I hack a lot of elisp in my spare time... */ -#define DMA_ERROR_P(regs) ((((regs)->cond_reg) & DMA_HNDL_ERROR)) -#define DMA_IRQ_P(regs) ((((regs)->cond_reg) & (DMA_HNDL_INTR | DMA_HNDL_ERROR))) -#define DMA_WRITE_P(regs) ((((regs)->cond_reg) & DMA_ST_WRITE)) -#define DMA_OFF(regs) ((((regs)->cond_reg) &= (~DMA_ENABLE))) -#define DMA_INTSOFF(regs) ((((regs)->cond_reg) &= (~DMA_INT_ENAB))) -#define DMA_INTSON(regs) ((((regs)->cond_reg) |= (DMA_INT_ENAB))) -#define DMA_PUNTFIFO(regs) ((((regs)->cond_reg) |= DMA_FIFO_INV)) -#define DMA_SETSTART(regs, addr) ((((regs)->st_addr) = (char *) addr)) -#define DMA_BEGINDMA_W(regs) \ - ((((regs)->cond_reg |= (DMA_ST_WRITE|DMA_ENABLE|DMA_INT_ENAB)))) -#define DMA_BEGINDMA_R(regs) \ - ((((regs)->cond_reg |= ((DMA_ENABLE|DMA_INT_ENAB)&(~DMA_ST_WRITE))))) - -/* For certain DMA chips, we need to disable ints upon irq entry - * and turn them back on when we are done. So in any ESP interrupt - * handler you *must* call DMA_IRQ_ENTRY upon entry and DMA_IRQ_EXIT - * when leaving the handler. You have been warned... - */ -#define DMA_IRQ_ENTRY(dma, dregs) do { \ - if(DMA_ISBROKEN(dma)) DMA_INTSOFF(dregs); \ - } while (0) - -#define DMA_IRQ_EXIT(dma, dregs) do { \ - if(DMA_ISBROKEN(dma)) DMA_INTSON(dregs); \ - } while(0) - -/* Reset the friggin' thing... */ -#define DMA_RESET(dma) do { \ - struct sparc_dma_registers *regs = dma->regs; \ - /* Let the current FIFO drain itself */ \ - sparc_dma_pause(regs, (DMA_FIFO_ISDRAIN)); \ - /* Reset the logic */ \ - regs->cond_reg |= (DMA_RST_SCSI); /* assert */ \ - __delay(400); /* let the bits set ;) */ \ - regs->cond_reg &= ~(DMA_RST_SCSI); /* de-assert */ \ - sparc_dma_enable_interrupts(regs); /* Re-enable interrupts */ \ - /* Enable FAST transfers if available */ \ - if(dma->revision>dvmarev1) regs->cond_reg |= DMA_3CLKS; \ - dma->running = 0; \ -} while(0) - - -#endif /* !CONFIG_SUN3 */ - -#endif /* !(__M68K_DVMA_H) */ diff --git a/include/asm-m68k/elf.h b/include/asm-m68k/elf.h deleted file mode 100644 index 0b0f49eb876..00000000000 --- a/include/asm-m68k/elf.h +++ /dev/null @@ -1,119 +0,0 @@ -#ifndef __ASMm68k_ELF_H -#define __ASMm68k_ELF_H - -/* - * ELF register definitions.. - */ - -#include -#include - -/* - * 68k ELF relocation types - */ -#define R_68K_NONE 0 -#define R_68K_32 1 -#define R_68K_16 2 -#define R_68K_8 3 -#define R_68K_PC32 4 -#define R_68K_PC16 5 -#define R_68K_PC8 6 -#define R_68K_GOT32 7 -#define R_68K_GOT16 8 -#define R_68K_GOT8 9 -#define R_68K_GOT32O 10 -#define R_68K_GOT16O 11 -#define R_68K_GOT8O 12 -#define R_68K_PLT32 13 -#define R_68K_PLT16 14 -#define R_68K_PLT8 15 -#define R_68K_PLT32O 16 -#define R_68K_PLT16O 17 -#define R_68K_PLT8O 18 -#define R_68K_COPY 19 -#define R_68K_GLOB_DAT 20 -#define R_68K_JMP_SLOT 21 -#define R_68K_RELATIVE 22 - -typedef unsigned long elf_greg_t; - -#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t)) -typedef elf_greg_t elf_gregset_t[ELF_NGREG]; - -typedef struct user_m68kfp_struct elf_fpregset_t; - -/* - * This is used to ensure we don't load something for the wrong architecture. - */ -#define elf_check_arch(x) ((x)->e_machine == EM_68K) - -/* - * These are used to set parameters in the core dumps. - */ -#define ELF_CLASS ELFCLASS32 -#define ELF_DATA ELFDATA2MSB -#define ELF_ARCH EM_68K - -/* For SVR4/m68k the function pointer to be registered with `atexit' is - passed in %a1. Although my copy of the ABI has no such statement, it - is actually used on ASV. */ -#define ELF_PLAT_INIT(_r, load_addr) _r->a1 = 0 - -#define USE_ELF_CORE_DUMP -#ifndef CONFIG_SUN3 -#define ELF_EXEC_PAGESIZE 4096 -#else -#define ELF_EXEC_PAGESIZE 8192 -#endif - -/* This is the location that an ET_DYN program is loaded if exec'ed. Typical - use of this is to invoke "./ld.so someprog" to test out a new version of - the loader. We need to make sure that it is out of the way of the program - that it will "exec", and that there is sufficient room for the brk. */ - -#ifndef CONFIG_SUN3 -#define ELF_ET_DYN_BASE 0xD0000000UL -#else -#define ELF_ET_DYN_BASE 0x0D800000UL -#endif - -#define ELF_CORE_COPY_REGS(pr_reg, regs) \ - /* Bleech. */ \ - pr_reg[0] = regs->d1; \ - pr_reg[1] = regs->d2; \ - pr_reg[2] = regs->d3; \ - pr_reg[3] = regs->d4; \ - pr_reg[4] = regs->d5; \ - pr_reg[7] = regs->a0; \ - pr_reg[8] = regs->a1; \ - pr_reg[9] = regs->a2; \ - pr_reg[14] = regs->d0; \ - pr_reg[15] = rdusp(); \ - pr_reg[16] = regs->orig_d0; \ - pr_reg[17] = regs->sr; \ - pr_reg[18] = regs->pc; \ - pr_reg[19] = (regs->format << 12) | regs->vector; \ - { \ - struct switch_stack *sw = ((struct switch_stack *)regs) - 1; \ - pr_reg[5] = sw->d6; \ - pr_reg[6] = sw->d7; \ - pr_reg[10] = sw->a3; \ - pr_reg[11] = sw->a4; \ - pr_reg[12] = sw->a5; \ - pr_reg[13] = sw->a6; \ - } - -/* This yields a mask that user programs can use to figure out what - instruction set this cpu supports. */ - -#define ELF_HWCAP (0) - -/* This yields a string that ld.so will use to load implementation - specific libraries for optimization. This is more specific in - intent than poking at uname or /proc/cpuinfo. */ - -#define ELF_PLATFORM (NULL) - -#define SET_PERSONALITY(ex) set_personality(PER_LINUX) - -#endif diff --git a/include/asm-m68k/emergency-restart.h b/include/asm-m68k/emergency-restart.h deleted file mode 100644 index 108d8c48e42..00000000000 --- a/include/asm-m68k/emergency-restart.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_EMERGENCY_RESTART_H -#define _ASM_EMERGENCY_RESTART_H - -#include - -#endif /* _ASM_EMERGENCY_RESTART_H */ diff --git a/include/asm-m68k/entry.h b/include/asm-m68k/entry.h deleted file mode 100644 index 5202f5a5b42..00000000000 --- a/include/asm-m68k/entry.h +++ /dev/null @@ -1,137 +0,0 @@ -#ifndef __M68K_ENTRY_H -#define __M68K_ENTRY_H - -#include -#include - -/* - * Stack layout in 'ret_from_exception': - * - * This allows access to the syscall arguments in registers d1-d5 - * - * 0(sp) - d1 - * 4(sp) - d2 - * 8(sp) - d3 - * C(sp) - d4 - * 10(sp) - d5 - * 14(sp) - a0 - * 18(sp) - a1 - * 1C(sp) - a2 - * 20(sp) - d0 - * 24(sp) - orig_d0 - * 28(sp) - stack adjustment - * 2C(sp) - sr - * 2E(sp) - pc - * 32(sp) - format & vector - */ - -/* - * 97/05/14 Andreas: Register %a2 is now set to the current task throughout - * the whole kernel. - */ - -/* the following macro is used when enabling interrupts */ -#if defined(MACH_ATARI_ONLY) - /* block out HSYNC on the atari */ -#define ALLOWINT (~0x400) -#define MAX_NOINT_IPL 3 -#else - /* portable version */ -#define ALLOWINT (~0x700) -#define MAX_NOINT_IPL 0 -#endif /* machine compilation types */ - -#ifdef __ASSEMBLY__ - -#define curptr a2 - -LFLUSH_I_AND_D = 0x00000808 -LSIGTRAP = 5 - -/* process bits for task_struct.ptrace */ -PT_TRACESYS_OFF = 3 -PT_TRACESYS_BIT = 1 -PT_PTRACED_OFF = 3 -PT_PTRACED_BIT = 0 -PT_DTRACE_OFF = 3 -PT_DTRACE_BIT = 2 - -#define SAVE_ALL_INT save_all_int -#define SAVE_ALL_SYS save_all_sys -#define RESTORE_ALL restore_all -/* - * This defines the normal kernel pt-regs layout. - * - * regs a3-a6 and d6-d7 are preserved by C code - * the kernel doesn't mess with usp unless it needs to - */ - -/* - * a -1 in the orig_d0 field signifies - * that the stack frame is NOT for syscall - */ -.macro save_all_int - clrl %sp@- | stk_adj - pea -1:w | orig d0 - movel %d0,%sp@- | d0 - moveml %d1-%d5/%a0-%a1/%curptr,%sp@- -.endm - -.macro save_all_sys - clrl %sp@- | stk_adj - movel %d0,%sp@- | orig d0 - movel %d0,%sp@- | d0 - moveml %d1-%d5/%a0-%a1/%curptr,%sp@- -.endm - -.macro restore_all - moveml %sp@+,%a0-%a1/%curptr/%d1-%d5 - movel %sp@+,%d0 - addql #4,%sp | orig d0 - addl %sp@+,%sp | stk adj - rte -.endm - -#define SWITCH_STACK_SIZE (6*4+4) /* includes return address */ - -#define SAVE_SWITCH_STACK save_switch_stack -#define RESTORE_SWITCH_STACK restore_switch_stack -#define GET_CURRENT(tmp) get_current tmp - -.macro save_switch_stack - moveml %a3-%a6/%d6-%d7,%sp@- -.endm - -.macro restore_switch_stack - moveml %sp@+,%a3-%a6/%d6-%d7 -.endm - -.macro get_current reg=%d0 - movel %sp,\reg - andw #-THREAD_SIZE,\reg - movel \reg,%curptr - movel %curptr@,%curptr -.endm - -#else /* C source */ - -#define STR(X) STR1(X) -#define STR1(X) #X - -#define PT_OFF_ORIG_D0 0x24 -#define PT_OFF_FORMATVEC 0x32 -#define PT_OFF_SR 0x2C -#define SAVE_ALL_INT \ - "clrl %%sp@-;" /* stk_adj */ \ - "pea -1:w;" /* orig d0 = -1 */ \ - "movel %%d0,%%sp@-;" /* d0 */ \ - "moveml %%d1-%%d5/%%a0-%%a2,%%sp@-" -#define GET_CURRENT(tmp) \ - "movel %%sp,"#tmp"\n\t" \ - "andw #-"STR(THREAD_SIZE)","#tmp"\n\t" \ - "movel "#tmp",%%a2\n\t" \ - "movel %%a2@,%%a2" - -#endif - -#endif /* __M68K_ENTRY_H */ diff --git a/include/asm-m68k/errno.h b/include/asm-m68k/errno.h deleted file mode 100644 index 0d4e188d6ef..00000000000 --- a/include/asm-m68k/errno.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _M68K_ERRNO_H -#define _M68K_ERRNO_H - -#include - -#endif /* _M68K_ERRNO_H */ diff --git a/include/asm-m68k/fb.h b/include/asm-m68k/fb.h deleted file mode 100644 index 380b97ae815..00000000000 --- a/include/asm-m68k/fb.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef _ASM_FB_H_ -#define _ASM_FB_H_ - -#include -#include -#include -#include - -#ifdef CONFIG_SUN3 -static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma, - unsigned long off) -{ - pgprot_val(vma->vm_page_prot) |= SUN3_PAGE_NOCACHE; -} -#else -static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma, - unsigned long off) -{ - if (CPU_IS_020_OR_030) - pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE030; - if (CPU_IS_040_OR_060) { - pgprot_val(vma->vm_page_prot) &= _CACHEMASK040; - /* Use no-cache mode, serialized */ - pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE_S; - } -} -#endif /* CONFIG_SUN3 */ - -static inline int fb_is_primary_device(struct fb_info *info) -{ - return 0; -} - -#endif /* _ASM_FB_H_ */ diff --git a/include/asm-m68k/fbio.h b/include/asm-m68k/fbio.h deleted file mode 100644 index b9215a0907d..00000000000 --- a/include/asm-m68k/fbio.h +++ /dev/null @@ -1,330 +0,0 @@ -#ifndef __LINUX_FBIO_H -#define __LINUX_FBIO_H - -#include -#include - -/* Constants used for fbio SunOS compatibility */ -/* (C) 1996 Miguel de Icaza */ - -/* Frame buffer types */ -#define FBTYPE_NOTYPE -1 -#define FBTYPE_SUN1BW 0 /* mono */ -#define FBTYPE_SUN1COLOR 1 -#define FBTYPE_SUN2BW 2 -#define FBTYPE_SUN2COLOR 3 -#define FBTYPE_SUN2GP 4 -#define FBTYPE_SUN5COLOR 5 -#define FBTYPE_SUN3COLOR 6 -#define FBTYPE_MEMCOLOR 7 -#define FBTYPE_SUN4COLOR 8 - -#define FBTYPE_NOTSUN1 9 -#define FBTYPE_NOTSUN2 10 -#define FBTYPE_NOTSUN3 11 - -#define FBTYPE_SUNFAST_COLOR 12 /* cg6 */ -#define FBTYPE_SUNROP_COLOR 13 -#define FBTYPE_SUNFB_VIDEO 14 -#define FBTYPE_SUNGIFB 15 -#define FBTYPE_SUNGPLAS 16 -#define FBTYPE_SUNGP3 17 -#define FBTYPE_SUNGT 18 -#define FBTYPE_SUNLEO 19 /* zx Leo card */ -#define FBTYPE_MDICOLOR 20 /* cg14 */ -#define FBTYPE_TCXCOLOR 21 /* SUNW,tcx card */ - -#define FBTYPE_LASTPLUSONE 21 /* This is not last + 1 in fact... */ - -/* Does not seem to be listed in the Sun file either */ -#define FBTYPE_CREATOR 22 -#define FBTYPE_PCI_IGA1682 23 -#define FBTYPE_P9100COLOR 24 - -#define FBTYPE_PCI_GENERIC 1000 -#define FBTYPE_PCI_MACH64 1001 - -/* fbio ioctls */ -/* Returned by FBIOGTYPE */ -struct fbtype { - int fb_type; /* fb type, see above */ - int fb_height; /* pixels */ - int fb_width; /* pixels */ - int fb_depth; - int fb_cmsize; /* color map entries */ - int fb_size; /* fb size in bytes */ -}; -#define FBIOGTYPE _IOR('F', 0, struct fbtype) - -struct fbcmap { - int index; /* first element (0 origin) */ - int count; - unsigned char __user *red; - unsigned char __user *green; - unsigned char __user *blue; -}; - -#ifdef __KERNEL__ -#define FBIOPUTCMAP_SPARC _IOW('F', 3, struct fbcmap) -#define FBIOGETCMAP_SPARC _IOW('F', 4, struct fbcmap) -#else -#define FBIOPUTCMAP _IOW('F', 3, struct fbcmap) -#define FBIOGETCMAP _IOW('F', 4, struct fbcmap) -#endif - -/* # of device specific values */ -#define FB_ATTR_NDEVSPECIFIC 8 -/* # of possible emulations */ -#define FB_ATTR_NEMUTYPES 4 - -struct fbsattr { - int flags; - int emu_type; /* -1 if none */ - int dev_specific[FB_ATTR_NDEVSPECIFIC]; -}; - -struct fbgattr { - int real_type; /* real frame buffer type */ - int owner; /* unknown */ - struct fbtype fbtype; /* real frame buffer fbtype */ - struct fbsattr sattr; - int emu_types[FB_ATTR_NEMUTYPES]; /* supported emulations */ -}; -#define FBIOSATTR _IOW('F', 5, struct fbgattr) /* Unsupported: */ -#define FBIOGATTR _IOR('F', 6, struct fbgattr) /* supported */ - -#define FBIOSVIDEO _IOW('F', 7, int) -#define FBIOGVIDEO _IOR('F', 8, int) - -struct fbcursor { - short set; /* what to set, choose from the list above */ - short enable; /* cursor on/off */ - struct fbcurpos pos; /* cursor position */ - struct fbcurpos hot; /* cursor hot spot */ - struct fbcmap cmap; /* color map info */ - struct fbcurpos size; /* cursor bit map size */ - char __user *image; /* cursor image bits */ - char __user *mask; /* cursor mask bits */ -}; - -/* set/get cursor attributes/shape */ -#define FBIOSCURSOR _IOW('F', 24, struct fbcursor) -#define FBIOGCURSOR _IOWR('F', 25, struct fbcursor) - -/* set/get cursor position */ -#define FBIOSCURPOS _IOW('F', 26, struct fbcurpos) -#define FBIOGCURPOS _IOW('F', 27, struct fbcurpos) - -/* get max cursor size */ -#define FBIOGCURMAX _IOR('F', 28, struct fbcurpos) - -/* wid manipulation */ -struct fb_wid_alloc { -#define FB_WID_SHARED_8 0 -#define FB_WID_SHARED_24 1 -#define FB_WID_DBL_8 2 -#define FB_WID_DBL_24 3 - __u32 wa_type; - __s32 wa_index; /* Set on return */ - __u32 wa_count; -}; -struct fb_wid_item { - __u32 wi_type; - __s32 wi_index; - __u32 wi_attrs; - __u32 wi_values[32]; -}; -struct fb_wid_list { - __u32 wl_flags; - __u32 wl_count; - struct fb_wid_item *wl_list; -}; - -#define FBIO_WID_ALLOC _IOWR('F', 30, struct fb_wid_alloc) -#define FBIO_WID_FREE _IOW('F', 31, struct fb_wid_alloc) -#define FBIO_WID_PUT _IOW('F', 32, struct fb_wid_list) -#define FBIO_WID_GET _IOWR('F', 33, struct fb_wid_list) - -/* Creator ioctls */ -#define FFB_IOCTL ('F'<<8) -#define FFB_SYS_INFO (FFB_IOCTL|80) -#define FFB_CLUTREAD (FFB_IOCTL|81) -#define FFB_CLUTPOST (FFB_IOCTL|82) -#define FFB_SETDIAGMODE (FFB_IOCTL|83) -#define FFB_GETMONITORID (FFB_IOCTL|84) -#define FFB_GETVIDEOMODE (FFB_IOCTL|85) -#define FFB_SETVIDEOMODE (FFB_IOCTL|86) -#define FFB_SETSERVER (FFB_IOCTL|87) -#define FFB_SETOVCTL (FFB_IOCTL|88) -#define FFB_GETOVCTL (FFB_IOCTL|89) -#define FFB_GETSAXNUM (FFB_IOCTL|90) -#define FFB_FBDEBUG (FFB_IOCTL|91) - -/* Cg14 ioctls */ -#define MDI_IOCTL ('M'<<8) -#define MDI_RESET (MDI_IOCTL|1) -#define MDI_GET_CFGINFO (MDI_IOCTL|2) -#define MDI_SET_PIXELMODE (MDI_IOCTL|3) -# define MDI_32_PIX 32 -# define MDI_16_PIX 16 -# define MDI_8_PIX 8 - -struct mdi_cfginfo { - int mdi_ncluts; /* Number of implemented CLUTs in this MDI */ - int mdi_type; /* FBTYPE name */ - int mdi_height; /* height */ - int mdi_width; /* widht */ - int mdi_size; /* available ram */ - int mdi_mode; /* 8bpp, 16bpp or 32bpp */ - int mdi_pixfreq; /* pixel clock (from PROM) */ -}; - -/* SparcLinux specific ioctl for the MDI, should be replaced for - * the SET_XLUT/SET_CLUTn ioctls instead - */ -#define MDI_CLEAR_XLUT (MDI_IOCTL|9) - -/* leo & ffb ioctls */ -struct fb_clut_alloc { - __u32 clutid; /* Set on return */ - __u32 flag; - __u32 index; -}; - -struct fb_clut { -#define FB_CLUT_WAIT 0x00000001 /* Not yet implemented */ - __u32 flag; - __u32 clutid; - __u32 offset; - __u32 count; - char * red; - char * green; - char * blue; -}; - -struct fb_clut32 { - __u32 flag; - __u32 clutid; - __u32 offset; - __u32 count; - __u32 red; - __u32 green; - __u32 blue; -}; - -#define LEO_CLUTALLOC _IOWR('L', 53, struct fb_clut_alloc) -#define LEO_CLUTFREE _IOW('L', 54, struct fb_clut_alloc) -#define LEO_CLUTREAD _IOW('L', 55, struct fb_clut) -#define LEO_CLUTPOST _IOW('L', 56, struct fb_clut) -#define LEO_SETGAMMA _IOW('L', 68, int) /* Not yet implemented */ -#define LEO_GETGAMMA _IOR('L', 69, int) /* Not yet implemented */ - -#ifdef __KERNEL__ -/* Addresses on the fd of a cgsix that are mappable */ -#define CG6_FBC 0x70000000 -#define CG6_TEC 0x70001000 -#define CG6_BTREGS 0x70002000 -#define CG6_FHC 0x70004000 -#define CG6_THC 0x70005000 -#define CG6_ROM 0x70006000 -#define CG6_RAM 0x70016000 -#define CG6_DHC 0x80000000 - -#define CG3_MMAP_OFFSET 0x4000000 - -/* Addresses on the fd of a tcx that are mappable */ -#define TCX_RAM8BIT 0x00000000 -#define TCX_RAM24BIT 0x01000000 -#define TCX_UNK3 0x10000000 -#define TCX_UNK4 0x20000000 -#define TCX_CONTROLPLANE 0x28000000 -#define TCX_UNK6 0x30000000 -#define TCX_UNK7 0x38000000 -#define TCX_TEC 0x70000000 -#define TCX_BTREGS 0x70002000 -#define TCX_THC 0x70004000 -#define TCX_DHC 0x70008000 -#define TCX_ALT 0x7000a000 -#define TCX_SYNC 0x7000e000 -#define TCX_UNK2 0x70010000 - -/* CG14 definitions */ - -/* Offsets into the OBIO space: */ -#define CG14_REGS 0 /* registers */ -#define CG14_CURSORREGS 0x1000 /* cursor registers */ -#define CG14_DACREGS 0x2000 /* DAC registers */ -#define CG14_XLUT 0x3000 /* X Look Up Table -- ??? */ -#define CG14_CLUT1 0x4000 /* Color Look Up Table */ -#define CG14_CLUT2 0x5000 /* Color Look Up Table */ -#define CG14_CLUT3 0x6000 /* Color Look Up Table */ -#define CG14_AUTO 0xf000 - -#endif /* KERNEL */ - -/* These are exported to userland for applications to use */ -/* Mappable offsets for the cg14: control registers */ -#define MDI_DIRECT_MAP 0x10000000 -#define MDI_CTLREG_MAP 0x20000000 -#define MDI_CURSOR_MAP 0x30000000 -#define MDI_SHDW_VRT_MAP 0x40000000 - -/* Mappable offsets for the cg14: frame buffer resolutions */ -/* 32 bits */ -#define MDI_CHUNKY_XBGR_MAP 0x50000000 -#define MDI_CHUNKY_BGR_MAP 0x60000000 - -/* 16 bits */ -#define MDI_PLANAR_X16_MAP 0x70000000 -#define MDI_PLANAR_C16_MAP 0x80000000 - -/* 8 bit is done as CG3 MMAP offset */ -/* 32 bits, planar */ -#define MDI_PLANAR_X32_MAP 0x90000000 -#define MDI_PLANAR_B32_MAP 0xa0000000 -#define MDI_PLANAR_G32_MAP 0xb0000000 -#define MDI_PLANAR_R32_MAP 0xc0000000 - -/* Mappable offsets on leo */ -#define LEO_SS0_MAP 0x00000000 -#define LEO_LC_SS0_USR_MAP 0x00800000 -#define LEO_LD_SS0_MAP 0x00801000 -#define LEO_LX_CURSOR_MAP 0x00802000 -#define LEO_SS1_MAP 0x00803000 -#define LEO_LC_SS1_USR_MAP 0x01003000 -#define LEO_LD_SS1_MAP 0x01004000 -#define LEO_UNK_MAP 0x01005000 -#define LEO_LX_KRN_MAP 0x01006000 -#define LEO_LC_SS0_KRN_MAP 0x01007000 -#define LEO_LC_SS1_KRN_MAP 0x01008000 -#define LEO_LD_GBL_MAP 0x01009000 -#define LEO_UNK2_MAP 0x0100a000 - -#ifdef __KERNEL__ -struct fbcmap32 { - int index; /* first element (0 origin) */ - int count; - u32 red; - u32 green; - u32 blue; -}; - -#define FBIOPUTCMAP32 _IOW('F', 3, struct fbcmap32) -#define FBIOGETCMAP32 _IOW('F', 4, struct fbcmap32) - -struct fbcursor32 { - short set; /* what to set, choose from the list above */ - short enable; /* cursor on/off */ - struct fbcurpos pos; /* cursor position */ - struct fbcurpos hot; /* cursor hot spot */ - struct fbcmap32 cmap; /* color map info */ - struct fbcurpos size; /* cursor bit map size */ - u32 image; /* cursor image bits */ - u32 mask; /* cursor mask bits */ -}; - -#define FBIOSCURSOR32 _IOW('F', 24, struct fbcursor32) -#define FBIOGCURSOR32 _IOW('F', 25, struct fbcursor32) -#endif - -#endif /* __LINUX_FBIO_H */ diff --git a/include/asm-m68k/fcntl.h b/include/asm-m68k/fcntl.h deleted file mode 100644 index 1c369b20dc4..00000000000 --- a/include/asm-m68k/fcntl.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _M68K_FCNTL_H -#define _M68K_FCNTL_H - -#define O_DIRECTORY 040000 /* must be a directory */ -#define O_NOFOLLOW 0100000 /* don't follow links */ -#define O_DIRECT 0200000 /* direct disk access hint - currently ignored */ -#define O_LARGEFILE 0400000 - -#include - -#endif /* _M68K_FCNTL_H */ diff --git a/include/asm-m68k/floppy.h b/include/asm-m68k/floppy.h deleted file mode 100644 index 697d50393dd..00000000000 --- a/include/asm-m68k/floppy.h +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Implementation independent bits of the Floppy driver. - * - * much of this file is derived from what was originally the Q40 floppy driver. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1999, 2000, 2001 - * - * Sun3x support added 2/4/2000 Sam Creasey (sammy@sammy.net) - * - */ - -#include - -#include - -asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id); - -/* constants... */ - -#undef MAX_DMA_ADDRESS -#define MAX_DMA_ADDRESS 0x00 /* nothing like that */ - - -/* - * Again, the CMOS information doesn't work on m68k.. - */ -#define FLOPPY0_TYPE (MACH_IS_Q40 ? 6 : 4) -#define FLOPPY1_TYPE 0 - -/* basically PC init + set use_virtual_dma */ -#define FDC1 m68k_floppy_init() - -#define N_FDC 1 -#define N_DRIVE 8 - - -/* vdma globals adapted from asm-i386/floppy.h */ - -static int virtual_dma_count=0; -static int virtual_dma_residue=0; -static char *virtual_dma_addr=NULL; -static int virtual_dma_mode=0; -static int doing_pdma=0; - -#include - -extern spinlock_t dma_spin_lock; - -static __inline__ unsigned long claim_dma_lock(void) -{ - unsigned long flags; - spin_lock_irqsave(&dma_spin_lock, flags); - return flags; -} - -static __inline__ void release_dma_lock(unsigned long flags) -{ - spin_unlock_irqrestore(&dma_spin_lock, flags); -} - - -static __inline__ unsigned char fd_inb(int port) -{ - if(MACH_IS_Q40) - return inb_p(port); - else if(MACH_IS_SUN3X) - return sun3x_82072_fd_inb(port); - return 0; -} - -static __inline__ void fd_outb(unsigned char value, int port) -{ - if(MACH_IS_Q40) - outb_p(value, port); - else if(MACH_IS_SUN3X) - sun3x_82072_fd_outb(value, port); -} - - -static int fd_request_irq(void) -{ - if(MACH_IS_Q40) - return request_irq(FLOPPY_IRQ, floppy_hardint, - IRQF_DISABLED, "floppy", floppy_hardint); - else if(MACH_IS_SUN3X) - return sun3xflop_request_irq(); - return -ENXIO; -} - -static void fd_free_irq(void) -{ - if(MACH_IS_Q40) - free_irq(FLOPPY_IRQ, floppy_hardint); -} - -#define fd_request_dma() vdma_request_dma(FLOPPY_DMA,"floppy") -#define fd_get_dma_residue() vdma_get_dma_residue(FLOPPY_DMA) -#define fd_dma_mem_alloc(size) vdma_mem_alloc(size) -#define fd_dma_setup(addr, size, mode, io) vdma_dma_setup(addr, size, mode, io) - -#define fd_enable_irq() /* nothing... */ -#define fd_disable_irq() /* nothing... */ - -#define fd_free_dma() /* nothing */ - -/* No 64k boundary crossing problems on Q40 - no DMA at all */ -#define CROSS_64KB(a,s) (0) - -#define DMA_MODE_READ 0x44 /* i386 look-alike */ -#define DMA_MODE_WRITE 0x48 - - -static int m68k_floppy_init(void) -{ - use_virtual_dma =1; - can_use_virtual_dma = 1; - - - if (MACH_IS_Q40) - return 0x3f0; - else if(MACH_IS_SUN3X) - return sun3xflop_init(); - else - return -1; -} - - -static int vdma_request_dma(unsigned int dmanr, const char * device_id) -{ - return 0; -} - - -static int vdma_get_dma_residue(unsigned int dummy) -{ - return virtual_dma_count + virtual_dma_residue; -} - - -static unsigned long vdma_mem_alloc(unsigned long size) -{ - return (unsigned long) vmalloc(size); - -} - -static void _fd_dma_mem_free(unsigned long addr, unsigned long size) -{ - vfree((void *)addr); -} -#define fd_dma_mem_free(addr,size) _fd_dma_mem_free(addr, size) - - -/* choose_dma_mode ???*/ - -static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io) -{ - doing_pdma = 1; - virtual_dma_port = (MACH_IS_Q40 ? io : 0); - virtual_dma_mode = (mode == DMA_MODE_WRITE); - virtual_dma_addr = addr; - virtual_dma_count = size; - virtual_dma_residue = 0; - return 0; -} - - - -static void fd_disable_dma(void) -{ - doing_pdma = 0; - virtual_dma_residue += virtual_dma_count; - virtual_dma_count=0; -} - - - -/* this is the only truly Q40 specific function */ - -asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id) -{ - register unsigned char st; - -#undef TRACE_FLPY_INT -#define NO_FLOPPY_ASSEMBLER - -#ifdef TRACE_FLPY_INT - static int calls=0; - static int bytes=0; - static int dma_wait=0; -#endif - if(!doing_pdma) { - floppy_interrupt(irq, dev_id); - return IRQ_HANDLED; - } - -#ifdef TRACE_FLPY_INT - if(!calls) - bytes = virtual_dma_count; -#endif - - { - register int lcount; - register char *lptr; - - /* serve 1st byte fast: */ - - st=1; - for(lcount=virtual_dma_count, lptr=virtual_dma_addr; - lcount; lcount--, lptr++) { - st=inb(virtual_dma_port+4) & 0xa0 ; - if(st != 0xa0) - break; - if(virtual_dma_mode) - outb_p(*lptr, virtual_dma_port+5); - else - *lptr = inb_p(virtual_dma_port+5); - } - - virtual_dma_count = lcount; - virtual_dma_addr = lptr; - st = inb(virtual_dma_port+4); - } - -#ifdef TRACE_FLPY_INT - calls++; -#endif - if(st == 0x20) - return IRQ_HANDLED; - if(!(st & 0x20)) { - virtual_dma_residue += virtual_dma_count; - virtual_dma_count=0; -#ifdef TRACE_FLPY_INT - printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n", - virtual_dma_count, virtual_dma_residue, calls, bytes, - dma_wait); - calls = 0; - dma_wait=0; -#endif - doing_pdma = 0; - floppy_interrupt(irq, dev_id); - return IRQ_HANDLED; - } -#ifdef TRACE_FLPY_INT - if(!virtual_dma_count) - dma_wait++; -#endif - return IRQ_HANDLED; -} - -#define EXTRA_FLOPPY_PARAMS diff --git a/include/asm-m68k/fpu.h b/include/asm-m68k/fpu.h deleted file mode 100644 index ffb6b8cfc6d..00000000000 --- a/include/asm-m68k/fpu.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __M68K_FPU_H -#define __M68K_FPU_H - - -/* - * MAX floating point unit state size (FSAVE/FRESTORE) - */ - -#if defined(CONFIG_M68020) || defined(CONFIG_M68030) -#define FPSTATESIZE (216) -#elif defined(CONFIG_M68040) -#define FPSTATESIZE (96) -#elif defined(CONFIG_M68KFPU_EMU) -#define FPSTATESIZE (28) -#elif defined(CONFIG_M68060) -#define FPSTATESIZE (12) -#else -#define FPSTATESIZE (0) -#endif - -#endif /* __M68K_FPU_H */ diff --git a/include/asm-m68k/futex.h b/include/asm-m68k/futex.h deleted file mode 100644 index 6a332a9f099..00000000000 --- a/include/asm-m68k/futex.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_FUTEX_H -#define _ASM_FUTEX_H - -#include - -#endif diff --git a/include/asm-m68k/hardirq.h b/include/asm-m68k/hardirq.h deleted file mode 100644 index 394ee946015..00000000000 --- a/include/asm-m68k/hardirq.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __M68K_HARDIRQ_H -#define __M68K_HARDIRQ_H - -#include -#include - -/* entry.S is sensitive to the offsets of these fields */ -typedef struct { - unsigned int __softirq_pending; -} ____cacheline_aligned irq_cpustat_t; - -#include /* Standard mappings for irq_cpustat_t above */ - -#define HARDIRQ_BITS 8 - -#endif diff --git a/include/asm-m68k/hp300hw.h b/include/asm-m68k/hp300hw.h deleted file mode 100644 index d998ea67c19..00000000000 --- a/include/asm-m68k/hp300hw.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _M68K_HP300HW_H -#define _M68K_HP300HW_H - -extern unsigned long hp300_model; - -/* This information was taken from NetBSD */ -#define HP_320 (0) /* 16MHz 68020+HP MMU+16K external cache */ -#define HP_330 (1) /* 16MHz 68020+68851 MMU */ -#define HP_340 (2) /* 16MHz 68030 */ -#define HP_345 (3) /* 50MHz 68030+32K external cache */ -#define HP_350 (4) /* 25MHz 68020+HP MMU+32K external cache */ -#define HP_360 (5) /* 25MHz 68030 */ -#define HP_370 (6) /* 33MHz 68030+64K external cache */ -#define HP_375 (7) /* 50MHz 68030+32K external cache */ -#define HP_380 (8) /* 25MHz 68040 */ -#define HP_385 (9) /* 33MHz 68040 */ - -#define HP_400 (10) /* 50MHz 68030+32K external cache */ -#define HP_425T (11) /* 25MHz 68040 - model 425t */ -#define HP_425S (12) /* 25MHz 68040 - model 425s */ -#define HP_425E (13) /* 25MHz 68040 - model 425e */ -#define HP_433T (14) /* 33MHz 68040 - model 433t */ -#define HP_433S (15) /* 33MHz 68040 - model 433s */ - -#endif /* _M68K_HP300HW_H */ diff --git a/include/asm-m68k/hw_irq.h b/include/asm-m68k/hw_irq.h deleted file mode 100644 index eacef0951fb..00000000000 --- a/include/asm-m68k/hw_irq.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_M68K_HW_IRQ_H -#define __ASM_M68K_HW_IRQ_H - -/* Dummy include. */ - -#endif diff --git a/include/asm-m68k/hwtest.h b/include/asm-m68k/hwtest.h deleted file mode 100644 index 402c8a4401f..00000000000 --- a/include/asm-m68k/hwtest.h +++ /dev/null @@ -1,15 +0,0 @@ -/* Routines to test for presence/absence of hardware registers: - * see arch/m68k/mm/hwtest.c. - * -- PMM 05/1998 - * - * Removed __init from decls. We might want them in modules, and - * the code is tiny anyway. 16/5/98 pb - */ - -#ifndef __ASM_HWTEST_H -#define __ASM_HWTEST_H - -extern int hwreg_present(volatile void *regp); -extern int hwreg_write(volatile void *regp, unsigned short val); - -#endif diff --git a/include/asm-m68k/ide.h b/include/asm-m68k/ide.h deleted file mode 100644 index b996a3c8cff..00000000000 --- a/include/asm-m68k/ide.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * linux/include/asm-m68k/ide.h - * - * Copyright (C) 1994-1996 Linus Torvalds & authors - */ - -/* Copyright(c) 1996 Kars de Jong */ -/* Based on the ide driver from 1.2.13pl8 */ - -/* - * Credits (alphabetical): - * - * - Bjoern Brauel - * - Kars de Jong - * - Torsten Ebeling - * - Dwight Engen - * - Thorsten Floeck - * - Roman Hodek - * - Guenther Kelleter - * - Chris Lawrence - * - Michael Rausch - * - Christian Sauer - * - Michael Schmitz - * - Jes Soerensen - * - Michael Thurm - * - Geert Uytterhoeven - */ - -#ifndef _M68K_IDE_H -#define _M68K_IDE_H - -#ifdef __KERNEL__ - - -#include -#include -#include - -#ifdef CONFIG_ATARI -#include -#include -#endif - -#ifdef CONFIG_MAC -#include -#endif - -/* - * Get rid of defs from io.h - ide has its private and conflicting versions - * Since so far no single m68k platform uses ISA/PCI I/O space for IDE, we - * always use the `raw' MMIO versions - */ -#undef inb -#undef inw -#undef insw -#undef inl -#undef insl -#undef outb -#undef outw -#undef outsw -#undef outl -#undef outsl -#undef readb -#undef readw -#undef readl -#undef writeb -#undef writew -#undef writel - -#define inb in_8 -#define inw in_be16 -#define insw(port, addr, n) raw_insw((u16 *)port, addr, n) -#define inl in_be32 -#define insl(port, addr, n) raw_insl((u32 *)port, addr, n) -#define outb(val, port) out_8(port, val) -#define outw(val, port) out_be16(port, val) -#define outsw(port, addr, n) raw_outsw((u16 *)port, addr, n) -#define outl(val, port) out_be32(port, val) -#define outsl(port, addr, n) raw_outsl((u32 *)port, addr, n) -#define readb in_8 -#define readw in_be16 -#define __ide_mm_insw(port, addr, n) raw_insw((u16 *)port, addr, n) -#define readl in_be32 -#define __ide_mm_insl(port, addr, n) raw_insl((u32 *)port, addr, n) -#define writeb(val, port) out_8(port, val) -#define writew(val, port) out_be16(port, val) -#define __ide_mm_outsw(port, addr, n) raw_outsw((u16 *)port, addr, n) -#define writel(val, port) out_be32(port, val) -#define __ide_mm_outsl(port, addr, n) raw_outsl((u32 *)port, addr, n) -#if defined(CONFIG_ATARI) || defined(CONFIG_Q40) -#define insw_swapw(port, addr, n) raw_insw_swapw((u16 *)port, addr, n) -#define outsw_swapw(port, addr, n) raw_outsw_swapw((u16 *)port, addr, n) -#endif - -#ifdef CONFIG_BLK_DEV_FALCON_IDE -#define IDE_ARCH_LOCK - -extern int falconide_intr_lock; - -static __inline__ void ide_release_lock (void) -{ - if (MACH_IS_ATARI) { - if (falconide_intr_lock == 0) { - printk("ide_release_lock: bug\n"); - return; - } - falconide_intr_lock = 0; - stdma_release(); - } -} - -static __inline__ void -ide_get_lock(irq_handler_t handler, void *data) -{ - if (MACH_IS_ATARI) { - if (falconide_intr_lock == 0) { - if (in_interrupt() > 0) - panic( "Falcon IDE hasn't ST-DMA lock in interrupt" ); - stdma_lock(handler, data); - falconide_intr_lock = 1; - } - } -} -#endif /* CONFIG_BLK_DEV_FALCON_IDE */ - -#define IDE_ARCH_ACK_INTR -#define ide_ack_intr(hwif) ((hwif)->ack_intr ? (hwif)->ack_intr(hwif) : 1) - -#endif /* __KERNEL__ */ -#endif /* _M68K_IDE_H */ diff --git a/include/asm-m68k/idprom.h b/include/asm-m68k/idprom.h deleted file mode 100644 index 160616a89e0..00000000000 --- a/include/asm-m68k/idprom.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _M68K_IDPROM_H -#define _M68K_IDPROM_H -/* - * idprom.h: Macros and defines for idprom routines - * - * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu) - */ - -#include - -struct idprom { - u8 id_format; /* Format identifier (always 0x01) */ - u8 id_machtype; /* Machine type */ - u8 id_ethaddr[6]; /* Hardware ethernet address */ - s32 id_date; /* Date of manufacture */ - u32 id_sernum:24; /* Unique serial number */ - u8 id_cksum; /* Checksum - xor of the data bytes */ - u8 reserved[16]; -}; - -extern struct idprom *idprom; -extern void idprom_init(void); - -/* Sun3: in control space */ -#define SUN3_IDPROM_BASE 0x00000000 - -#endif /* !(_M68K_IDPROM_H) */ diff --git a/include/asm-m68k/intersil.h b/include/asm-m68k/intersil.h deleted file mode 100644 index f482902cac8..00000000000 --- a/include/asm-m68k/intersil.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef _SUN3_INTERSIL_H -#define _SUN3_INTERSIL_H -/* bits 0 and 1 */ -#define INTERSIL_FREQ_32K 0x00 -#define INTERSIL_FREQ_1M 0x01 -#define INTERSIL_FREQ_2M 0x02 -#define INTERSIL_FREQ_4M 0x03 - -/* bit 2 */ -#define INTERSIL_12H_MODE 0x00 -#define INTERSIL_24H_MODE 0x04 - -/* bit 3 */ -#define INTERSIL_STOP 0x00 -#define INTERSIL_RUN 0x08 - -/* bit 4 */ -#define INTERSIL_INT_ENABLE 0x10 -#define INTERSIL_INT_DISABLE 0x00 - -/* bit 5 */ -#define INTERSIL_MODE_NORMAL 0x00 -#define INTERSIL_MODE_TEST 0x20 - -#define INTERSIL_HZ_100_MASK 0x02 - -struct intersil_dt { - unsigned char csec; - unsigned char hour; - unsigned char minute; - unsigned char second; - unsigned char month; - unsigned char day; - unsigned char year; - unsigned char weekday; -}; - -struct intersil_7170 { - struct intersil_dt counter; - struct intersil_dt alarm; - unsigned char int_reg; - unsigned char cmd_reg; -}; - -extern volatile char* clock_va; -#define intersil_clock ((volatile struct intersil_7170 *) clock_va) -#define intersil_clear() (void)intersil_clock->int_reg -#endif diff --git a/include/asm-m68k/io.h b/include/asm-m68k/io.h deleted file mode 100644 index 9e673e3bd43..00000000000 --- a/include/asm-m68k/io.h +++ /dev/null @@ -1,369 +0,0 @@ -/* - * linux/include/asm-m68k/io.h - * - * 4/1/00 RZ: - rewritten to avoid clashes between ISA/PCI and other - * IO access - * - added Q40 support - * - added skeleton for GG-II and Amiga PCMCIA - * 2/3/01 RZ: - moved a few more defs into raw_io.h - * - * inX/outX should not be used by any driver unless it does - * ISA access. Other drivers should use function defined in raw_io.h - * or define its own macros on top of these. - * - * inX(),outX() are for ISA I/O - * isa_readX(),isa_writeX() are for ISA memory - */ - -#ifndef _IO_H -#define _IO_H - -#ifdef __KERNEL__ - -#include -#include -#include - -#include - -#ifdef CONFIG_ATARI -#include -#endif - - -/* - * IO/MEM definitions for various ISA bridges - */ - - -#ifdef CONFIG_Q40 - -#define q40_isa_io_base 0xff400000 -#define q40_isa_mem_base 0xff800000 - -#define Q40_ISA_IO_B(ioaddr) (q40_isa_io_base+1+4*((unsigned long)(ioaddr))) -#define Q40_ISA_IO_W(ioaddr) (q40_isa_io_base+ 4*((unsigned long)(ioaddr))) -#define Q40_ISA_MEM_B(madr) (q40_isa_mem_base+1+4*((unsigned long)(madr))) -#define Q40_ISA_MEM_W(madr) (q40_isa_mem_base+ 4*((unsigned long)(madr))) - -#define MULTI_ISA 0 -#endif /* Q40 */ - -/* GG-II Zorro to ISA bridge */ -#ifdef CONFIG_GG2 - -extern unsigned long gg2_isa_base; -#define GG2_ISA_IO_B(ioaddr) (gg2_isa_base+1+((unsigned long)(ioaddr)*4)) -#define GG2_ISA_IO_W(ioaddr) (gg2_isa_base+ ((unsigned long)(ioaddr)*4)) -#define GG2_ISA_MEM_B(madr) (gg2_isa_base+1+(((unsigned long)(madr)*4) & 0xfffff)) -#define GG2_ISA_MEM_W(madr) (gg2_isa_base+ (((unsigned long)(madr)*4) & 0xfffff)) - -#ifndef MULTI_ISA -#define MULTI_ISA 0 -#else -#undef MULTI_ISA -#define MULTI_ISA 1 -#endif -#endif /* GG2 */ - -#ifdef CONFIG_AMIGA_PCMCIA -#include - -#define AG_ISA_IO_B(ioaddr) ( GAYLE_IO+(ioaddr)+(((ioaddr)&1)*GAYLE_ODD) ) -#define AG_ISA_IO_W(ioaddr) ( GAYLE_IO+(ioaddr) ) - -#ifndef MULTI_ISA -#define MULTI_ISA 0 -#else -#undef MULTI_ISA -#define MULTI_ISA 1 -#endif -#endif /* AMIGA_PCMCIA */ - - - -#ifdef CONFIG_ISA - -#if MULTI_ISA == 0 -#undef MULTI_ISA -#endif - -#define ISA_TYPE_Q40 (1) -#define ISA_TYPE_GG2 (2) -#define ISA_TYPE_AG (3) - -#if defined(CONFIG_Q40) && !defined(MULTI_ISA) -#define ISA_TYPE ISA_TYPE_Q40 -#define ISA_SEX 0 -#endif -#if defined(CONFIG_AMIGA_PCMCIA) && !defined(MULTI_ISA) -#define ISA_TYPE ISA_TYPE_AG -#define ISA_SEX 1 -#endif -#if defined(CONFIG_GG2) && !defined(MULTI_ISA) -#define ISA_TYPE ISA_TYPE_GG2 -#define ISA_SEX 0 -#endif - -#ifdef MULTI_ISA -extern int isa_type; -extern int isa_sex; - -#define ISA_TYPE isa_type -#define ISA_SEX isa_sex -#endif - -/* - * define inline addr translation functions. Normally only one variant will - * be compiled in so the case statement will be optimised away - */ - -static inline u8 __iomem *isa_itb(unsigned long addr) -{ - switch(ISA_TYPE) - { -#ifdef CONFIG_Q40 - case ISA_TYPE_Q40: return (u8 __iomem *)Q40_ISA_IO_B(addr); -#endif -#ifdef CONFIG_GG2 - case ISA_TYPE_GG2: return (u8 __iomem *)GG2_ISA_IO_B(addr); -#endif -#ifdef CONFIG_AMIGA_PCMCIA - case ISA_TYPE_AG: return (u8 __iomem *)AG_ISA_IO_B(addr); -#endif - default: return NULL; /* avoid warnings, just in case */ - } -} -static inline u16 __iomem *isa_itw(unsigned long addr) -{ - switch(ISA_TYPE) - { -#ifdef CONFIG_Q40 - case ISA_TYPE_Q40: return (u16 __iomem *)Q40_ISA_IO_W(addr); -#endif -#ifdef CONFIG_GG2 - case ISA_TYPE_GG2: return (u16 __iomem *)GG2_ISA_IO_W(addr); -#endif -#ifdef CONFIG_AMIGA_PCMCIA - case ISA_TYPE_AG: return (u16 __iomem *)AG_ISA_IO_W(addr); -#endif - default: return NULL; /* avoid warnings, just in case */ - } -} -static inline u32 __iomem *isa_itl(unsigned long addr) -{ - switch(ISA_TYPE) - { -#ifdef CONFIG_AMIGA_PCMCIA - case ISA_TYPE_AG: return (u32 __iomem *)AG_ISA_IO_W(addr); -#endif - default: return 0; /* avoid warnings, just in case */ - } -} -static inline u8 __iomem *isa_mtb(unsigned long addr) -{ - switch(ISA_TYPE) - { -#ifdef CONFIG_Q40 - case ISA_TYPE_Q40: return (u8 __iomem *)Q40_ISA_MEM_B(addr); -#endif -#ifdef CONFIG_GG2 - case ISA_TYPE_GG2: return (u8 __iomem *)GG2_ISA_MEM_B(addr); -#endif -#ifdef CONFIG_AMIGA_PCMCIA - case ISA_TYPE_AG: return (u8 __iomem *)addr; -#endif - default: return NULL; /* avoid warnings, just in case */ - } -} -static inline u16 __iomem *isa_mtw(unsigned long addr) -{ - switch(ISA_TYPE) - { -#ifdef CONFIG_Q40 - case ISA_TYPE_Q40: return (u16 __iomem *)Q40_ISA_MEM_W(addr); -#endif -#ifdef CONFIG_GG2 - case ISA_TYPE_GG2: return (u16 __iomem *)GG2_ISA_MEM_W(addr); -#endif -#ifdef CONFIG_AMIGA_PCMCIA - case ISA_TYPE_AG: return (u16 __iomem *)addr; -#endif - default: return NULL; /* avoid warnings, just in case */ - } -} - - -#define isa_inb(port) in_8(isa_itb(port)) -#define isa_inw(port) (ISA_SEX ? in_be16(isa_itw(port)) : in_le16(isa_itw(port))) -#define isa_inl(port) (ISA_SEX ? in_be32(isa_itl(port)) : in_le32(isa_itl(port))) -#define isa_outb(val,port) out_8(isa_itb(port),(val)) -#define isa_outw(val,port) (ISA_SEX ? out_be16(isa_itw(port),(val)) : out_le16(isa_itw(port),(val))) -#define isa_outl(val,port) (ISA_SEX ? out_be32(isa_itl(port),(val)) : out_le32(isa_itl(port),(val))) - -#define isa_readb(p) in_8(isa_mtb((unsigned long)(p))) -#define isa_readw(p) \ - (ISA_SEX ? in_be16(isa_mtw((unsigned long)(p))) \ - : in_le16(isa_mtw((unsigned long)(p)))) -#define isa_writeb(val,p) out_8(isa_mtb((unsigned long)(p)),(val)) -#define isa_writew(val,p) \ - (ISA_SEX ? out_be16(isa_mtw((unsigned long)(p)),(val)) \ - : out_le16(isa_mtw((unsigned long)(p)),(val))) - -static inline void isa_delay(void) -{ - switch(ISA_TYPE) - { -#ifdef CONFIG_Q40 - case ISA_TYPE_Q40: isa_outb(0,0x80); break; -#endif -#ifdef CONFIG_GG2 - case ISA_TYPE_GG2: break; -#endif -#ifdef CONFIG_AMIGA_PCMCIA - case ISA_TYPE_AG: break; -#endif - default: break; /* avoid warnings */ - } -} - -#define isa_inb_p(p) ({u8 v=isa_inb(p);isa_delay();v;}) -#define isa_outb_p(v,p) ({isa_outb((v),(p));isa_delay();}) -#define isa_inw_p(p) ({u16 v=isa_inw(p);isa_delay();v;}) -#define isa_outw_p(v,p) ({isa_outw((v),(p));isa_delay();}) -#define isa_inl_p(p) ({u32 v=isa_inl(p);isa_delay();v;}) -#define isa_outl_p(v,p) ({isa_outl((v),(p));isa_delay();}) - -#define isa_insb(port, buf, nr) raw_insb(isa_itb(port), (u8 *)(buf), (nr)) -#define isa_outsb(port, buf, nr) raw_outsb(isa_itb(port), (u8 *)(buf), (nr)) - -#define isa_insw(port, buf, nr) \ - (ISA_SEX ? raw_insw(isa_itw(port), (u16 *)(buf), (nr)) : \ - raw_insw_swapw(isa_itw(port), (u16 *)(buf), (nr))) - -#define isa_outsw(port, buf, nr) \ - (ISA_SEX ? raw_outsw(isa_itw(port), (u16 *)(buf), (nr)) : \ - raw_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr))) - -#define isa_insl(port, buf, nr) \ - (ISA_SEX ? raw_insl(isa_itl(port), (u32 *)(buf), (nr)) : \ - raw_insw_swapw(isa_itw(port), (u16 *)(buf), (nr)<<1)) - -#define isa_outsl(port, buf, nr) \ - (ISA_SEX ? raw_outsl(isa_itl(port), (u32 *)(buf), (nr)) : \ - raw_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr)<<1)) - - -#define inb isa_inb -#define inb_p isa_inb_p -#define outb isa_outb -#define outb_p isa_outb_p -#define inw isa_inw -#define inw_p isa_inw_p -#define outw isa_outw -#define outw_p isa_outw_p -#define inl isa_inl -#define inl_p isa_inl_p -#define outl isa_outl -#define outl_p isa_outl_p -#define insb isa_insb -#define insw isa_insw -#define insl isa_insl -#define outsb isa_outsb -#define outsw isa_outsw -#define outsl isa_outsl -#define readb isa_readb -#define readw isa_readw -#define writeb isa_writeb -#define writew isa_writew - -#else /* CONFIG_ISA */ - -/* - * We need to define dummy functions for GENERIC_IOMAP support. - */ -#define inb(port) 0xff -#define inb_p(port) 0xff -#define outb(val,port) ((void)0) -#define outb_p(val,port) ((void)0) -#define inw(port) 0xffff -#define outw(val,port) ((void)0) -#define inl(port) 0xffffffffUL -#define outl(val,port) ((void)0) - -#define insb(port,buf,nr) ((void)0) -#define outsb(port,buf,nr) ((void)0) -#define insw(port,buf,nr) ((void)0) -#define outsw(port,buf,nr) ((void)0) -#define insl(port,buf,nr) ((void)0) -#define outsl(port,buf,nr) ((void)0) - -/* - * These should be valid on any ioremap()ed region - */ -#define readb(addr) in_8(addr) -#define writeb(val,addr) out_8((addr),(val)) -#define readw(addr) in_le16(addr) -#define writew(val,addr) out_le16((addr),(val)) - -#endif /* CONFIG_ISA */ - -#define readl(addr) in_le32(addr) -#define writel(val,addr) out_le32((addr),(val)) - -#define mmiowb() - -static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); -} -static inline void __iomem *ioremap_nocache(unsigned long physaddr, unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); -} -static inline void __iomem *ioremap_writethrough(unsigned long physaddr, - unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_WRITETHROUGH); -} -static inline void __iomem *ioremap_fullcache(unsigned long physaddr, - unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_FULL_CACHING); -} - -static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count) -{ - __builtin_memset((void __force *) addr, val, count); -} -static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, int count) -{ - __builtin_memcpy(dst, (void __force *) src, count); -} -static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int count) -{ - __builtin_memcpy((void __force *) dst, src, count); -} - -#ifndef CONFIG_SUN3 -#define IO_SPACE_LIMIT 0xffff -#else -#define IO_SPACE_LIMIT 0x0fffffff -#endif - -#endif /* __KERNEL__ */ - -#define __ARCH_HAS_NO_PAGE_ZERO_MAPPED 1 - -/* - * Convert a physical pointer to a virtual kernel pointer for /dev/mem - * access - */ -#define xlate_dev_mem_ptr(p) __va(p) - -/* - * Convert a virtual cached pointer to an uncached pointer - */ -#define xlate_dev_kmem_ptr(p) p - -#endif /* _IO_H */ diff --git a/include/asm-m68k/ioctl.h b/include/asm-m68k/ioctl.h deleted file mode 100644 index b279fe06dfe..00000000000 --- a/include/asm-m68k/ioctl.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-m68k/ioctls.h b/include/asm-m68k/ioctls.h deleted file mode 100644 index b8d2f4be7fd..00000000000 --- a/include/asm-m68k/ioctls.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef __ARCH_M68K_IOCTLS_H__ -#define __ARCH_M68K_IOCTLS_H__ - -#include - -/* 0x54 is just a magic number to make these relatively unique ('T') */ - -#define TCGETS 0x5401 -#define TCSETS 0x5402 -#define TCSETSW 0x5403 -#define TCSETSF 0x5404 -#define TCGETA 0x5405 -#define TCSETA 0x5406 -#define TCSETAW 0x5407 -#define TCSETAF 0x5408 -#define TCSBRK 0x5409 -#define TCXONC 0x540A -#define TCFLSH 0x540B -#define TIOCEXCL 0x540C -#define TIOCNXCL 0x540D -#define TIOCSCTTY 0x540E -#define TIOCGPGRP 0x540F -#define TIOCSPGRP 0x5410 -#define TIOCOUTQ 0x5411 -#define TIOCSTI 0x5412 -#define TIOCGWINSZ 0x5413 -#define TIOCSWINSZ 0x5414 -#define TIOCMGET 0x5415 -#define TIOCMBIS 0x5416 -#define TIOCMBIC 0x5417 -#define TIOCMSET 0x5418 -#define TIOCGSOFTCAR 0x5419 -#define TIOCSSOFTCAR 0x541A -#define FIONREAD 0x541B -#define TIOCINQ FIONREAD -#define TIOCLINUX 0x541C -#define TIOCCONS 0x541D -#define TIOCGSERIAL 0x541E -#define TIOCSSERIAL 0x541F -#define TIOCPKT 0x5420 -#define FIONBIO 0x5421 -#define TIOCNOTTY 0x5422 -#define TIOCSETD 0x5423 -#define TIOCGETD 0x5424 -#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ -#define TIOCSBRK 0x5427 /* BSD compatibility */ -#define TIOCCBRK 0x5428 /* BSD compatibility */ -#define TIOCGSID 0x5429 /* Return the session ID of FD */ -#define TCGETS2 _IOR('T',0x2A, struct termios2) -#define TCSETS2 _IOW('T',0x2B, struct termios2) -#define TCSETSW2 _IOW('T',0x2C, struct termios2) -#define TCSETSF2 _IOW('T',0x2D, struct termios2) -#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ -#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ - -#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ -#define FIOCLEX 0x5451 -#define FIOASYNC 0x5452 -#define TIOCSERCONFIG 0x5453 -#define TIOCSERGWILD 0x5454 -#define TIOCSERSWILD 0x5455 -#define TIOCGLCKTRMIOS 0x5456 -#define TIOCSLCKTRMIOS 0x5457 -#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ -#define TIOCSERGETLSR 0x5459 /* Get line status register */ -#define TIOCSERGETMULTI 0x545A /* Get multiport config */ -#define TIOCSERSETMULTI 0x545B /* Set multiport config */ - -#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ -#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ -#define FIOQSIZE 0x545E - -/* Used for packet mode */ -#define TIOCPKT_DATA 0 -#define TIOCPKT_FLUSHREAD 1 -#define TIOCPKT_FLUSHWRITE 2 -#define TIOCPKT_STOP 4 -#define TIOCPKT_START 8 -#define TIOCPKT_NOSTOP 16 -#define TIOCPKT_DOSTOP 32 - -#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ - -#endif /* __ARCH_M68K_IOCTLS_H__ */ diff --git a/include/asm-m68k/ipcbuf.h b/include/asm-m68k/ipcbuf.h deleted file mode 100644 index a623ea3f095..00000000000 --- a/include/asm-m68k/ipcbuf.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __m68k_IPCBUF_H__ -#define __m68k_IPCBUF_H__ - -/* - * The user_ipc_perm structure for m68k architecture. - * Note extra padding because this structure is passed back and forth - * between kernel and user space. - * - * Pad space is left for: - * - 32-bit mode_t and seq - * - 2 miscellaneous 32-bit values - */ - -struct ipc64_perm -{ - __kernel_key_t key; - __kernel_uid32_t uid; - __kernel_gid32_t gid; - __kernel_uid32_t cuid; - __kernel_gid32_t cgid; - __kernel_mode_t mode; - unsigned short __pad1; - unsigned short seq; - unsigned short __pad2; - unsigned long __unused1; - unsigned long __unused2; -}; - -#endif /* __m68k_IPCBUF_H__ */ diff --git a/include/asm-m68k/irq.h b/include/asm-m68k/irq.h deleted file mode 100644 index 226bfc0f21b..00000000000 --- a/include/asm-m68k/irq.h +++ /dev/null @@ -1,125 +0,0 @@ -#ifndef _M68K_IRQ_H_ -#define _M68K_IRQ_H_ - -#include -#include -#include - -/* - * This should be the same as the max(NUM_X_SOURCES) for all the - * different m68k hosts compiled into the kernel. - * Currently the Atari has 72 and the Amiga 24, but if both are - * supported in the kernel it is better to make room for 72. - */ -#if defined(CONFIG_VME) || defined(CONFIG_SUN3) || defined(CONFIG_SUN3X) -#define NR_IRQS 200 -#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) -#define NR_IRQS 72 -#elif defined(CONFIG_Q40) -#define NR_IRQS 43 -#elif defined(CONFIG_AMIGA) -#define NR_IRQS 32 -#elif defined(CONFIG_APOLLO) -#define NR_IRQS 24 -#elif defined(CONFIG_HP300) -#define NR_IRQS 8 -#else -#define NR_IRQS 0 -#endif - -/* - * The hardirq mask has to be large enough to have - * space for potentially all IRQ sources in the system - * nesting on a single CPU: - */ -#if (1 << HARDIRQ_BITS) < NR_IRQS -# error HARDIRQ_BITS is too low! -#endif - -/* - * Interrupt source definitions - * General interrupt sources are the level 1-7. - * Adding an interrupt service routine for one of these sources - * results in the addition of that routine to a chain of routines. - * Each one is called in succession. Each individual interrupt - * service routine should determine if the device associated with - * that routine requires service. - */ - -#define IRQ_SPURIOUS 0 - -#define IRQ_AUTO_1 1 /* level 1 interrupt */ -#define IRQ_AUTO_2 2 /* level 2 interrupt */ -#define IRQ_AUTO_3 3 /* level 3 interrupt */ -#define IRQ_AUTO_4 4 /* level 4 interrupt */ -#define IRQ_AUTO_5 5 /* level 5 interrupt */ -#define IRQ_AUTO_6 6 /* level 6 interrupt */ -#define IRQ_AUTO_7 7 /* level 7 interrupt (non-maskable) */ - -#define IRQ_USER 8 - -extern unsigned int irq_canonicalize(unsigned int irq); - -struct pt_regs; - -/* - * various flags for request_irq() - the Amiga now uses the standard - * mechanism like all other architectures - IRQF_DISABLED and - * IRQF_SHARED are your friends. - */ -#ifndef MACH_AMIGA_ONLY -#define IRQ_FLG_LOCK (0x0001) /* handler is not replaceable */ -#define IRQ_FLG_REPLACE (0x0002) /* replace existing handler */ -#define IRQ_FLG_FAST (0x0004) -#define IRQ_FLG_SLOW (0x0008) -#define IRQ_FLG_STD (0x8000) /* internally used */ -#endif - -/* - * This structure is used to chain together the ISRs for a particular - * interrupt source (if it supports chaining). - */ -typedef struct irq_node { - int (*handler)(int, void *); - void *dev_id; - struct irq_node *next; - unsigned long flags; - const char *devname; -} irq_node_t; - -/* - * This structure has only 4 elements for speed reasons - */ -struct irq_handler { - int (*handler)(int, void *); - unsigned long flags; - void *dev_id; - const char *devname; -}; - -struct irq_controller { - const char *name; - spinlock_t lock; - int (*startup)(unsigned int irq); - void (*shutdown)(unsigned int irq); - void (*enable)(unsigned int irq); - void (*disable)(unsigned int irq); -}; - -extern int m68k_irq_startup(unsigned int); -extern void m68k_irq_shutdown(unsigned int); - -/* - * This function returns a new irq_node_t - */ -extern irq_node_t *new_irq_node(void); - -extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)); -extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, - void (*handler)(unsigned int, struct pt_regs *)); -extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int); - -asmlinkage void m68k_handle_int(unsigned int); -asmlinkage void __m68k_handle_int(unsigned int, struct pt_regs *); - -#endif /* _M68K_IRQ_H_ */ diff --git a/include/asm-m68k/irq_regs.h b/include/asm-m68k/irq_regs.h deleted file mode 100644 index 3dd9c0b7027..00000000000 --- a/include/asm-m68k/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-m68k/kdebug.h b/include/asm-m68k/kdebug.h deleted file mode 100644 index 6ece1b03766..00000000000 --- a/include/asm-m68k/kdebug.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-m68k/kmap_types.h b/include/asm-m68k/kmap_types.h deleted file mode 100644 index c843c63d380..00000000000 --- a/include/asm-m68k/kmap_types.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __ASM_M68K_KMAP_TYPES_H -#define __ASM_M68K_KMAP_TYPES_H - -enum km_type { - KM_BOUNCE_READ, - KM_SKB_SUNRPC_DATA, - KM_SKB_DATA_SOFTIRQ, - KM_USER0, - KM_USER1, - KM_BIO_SRC_IRQ, - KM_BIO_DST_IRQ, - KM_PTE0, - KM_PTE1, - KM_IRQ0, - KM_IRQ1, - KM_SOFTIRQ0, - KM_SOFTIRQ1, - KM_TYPE_NR -}; - -#endif /* __ASM_M68K_KMAP_TYPES_H */ diff --git a/include/asm-m68k/linkage.h b/include/asm-m68k/linkage.h deleted file mode 100644 index 5a822bb790f..00000000000 --- a/include/asm-m68k/linkage.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __ASM_LINKAGE_H -#define __ASM_LINKAGE_H - -#define __ALIGN .align 4 -#define __ALIGN_STR ".align 4" - -#endif diff --git a/include/asm-m68k/local.h b/include/asm-m68k/local.h deleted file mode 100644 index 6c259263e1f..00000000000 --- a/include/asm-m68k/local.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_M68K_LOCAL_H -#define _ASM_M68K_LOCAL_H - -#include - -#endif /* _ASM_M68K_LOCAL_H */ diff --git a/include/asm-m68k/mac_asc.h b/include/asm-m68k/mac_asc.h deleted file mode 100644 index fc2e5467b41..00000000000 --- a/include/asm-m68k/mac_asc.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Apple Sound Chip - */ - -#ifndef __ASM_MAC_ASC_H -#define __ASM_MAC_ASC_H - -/* - * ASC offsets and controls - */ - -#define ASC_BUF_BASE 0x00 /* RAM buffer offset */ -#define ASC_BUF_SIZE 0x800 - -#define ASC_CONTROL 0x800 -#define ASC_CONTROL_OFF 0x00 -#define ASC_FREQ(chan,byte) ((0x810)+((chan)<<3)+(byte)) -#define ASC_ENABLE 0x801 -#define ASC_ENABLE_SAMPLE 0x02 -#define ASC_MODE 0x802 -#define ASC_MODE_SAMPLE 0x02 - -#define ASC_VOLUME 0x806 -#define ASC_CHAN 0x807 /* ??? */ - - -#endif diff --git a/include/asm-m68k/mac_baboon.h b/include/asm-m68k/mac_baboon.h deleted file mode 100644 index c2a042b8c34..00000000000 --- a/include/asm-m68k/mac_baboon.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Definitions for the "Baboon" custom IC on the PowerBook 190. - */ - -#define BABOON_BASE (0x50F1A000) /* same as IDE controller base */ - -#ifndef __ASSEMBLY__ - -struct baboon { - char pad1[208]; /* generic IDE registers, not used here */ - short mb_control; /* Control register: - * bit 5 : slot 2 power control - * bit 6 : slot 1 power control - */ - char pad2[2]; - short mb_status; /* (0xD4) media bay status register: - * - * bit 0: ???? - * bit 1: IDE interrupt active? - * bit 2: bay status, 0 = full, 1 = empty - * bit 3: ???? - */ - char pad3[2]; /* (0xD6) not used */ - short mb_ifr; /* (0xD8) media bay interrupt flags register: - * - * bit 0: ???? - * bit 1: IDE controller interrupt - * bit 2: media bay status change interrupt - */ -}; - -#endif /* __ASSEMBLY **/ diff --git a/include/asm-m68k/mac_iop.h b/include/asm-m68k/mac_iop.h deleted file mode 100644 index a2c7e6fcca3..00000000000 --- a/include/asm-m68k/mac_iop.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * I/O Processor (IOP) defines and structures, mostly snagged from A/UX - * header files. - * - * The original header from which this was taken is copyrighted. I've done some - * rewriting (in fact my changes make this a bit more readable, IMHO) but some - * more should be done. - */ - -/* - * This is the base address of the IOPs. Use this as the address of - * a "struct iop" (see below) to see where the actual registers fall. - */ - -#define SCC_IOP_BASE_IIFX (0x50F04000) -#define ISM_IOP_BASE_IIFX (0x50F12000) - -#define SCC_IOP_BASE_QUADRA (0x50F0C000) -#define ISM_IOP_BASE_QUADRA (0x50F1E000) - -/* IOP status/control register bits: */ - -#define IOP_BYPASS 0x01 /* bypass-mode hardware access */ -#define IOP_AUTOINC 0x02 /* allow autoincrement of ramhi/lo */ -#define IOP_RUN 0x04 /* set to 0 to reset IOP chip */ -#define IOP_IRQ 0x08 /* generate IRQ to IOP if 1 */ -#define IOP_INT0 0x10 /* intr priority from IOP to host */ -#define IOP_INT1 0x20 /* intr priority from IOP to host */ -#define IOP_HWINT 0x40 /* IRQ from hardware; bypass mode only */ -#define IOP_DMAINACTIVE 0x80 /* no DMA request active; bypass mode only */ - -#define NUM_IOPS 2 -#define NUM_IOP_CHAN 7 -#define NUM_IOP_MSGS NUM_IOP_CHAN*8 -#define IOP_MSG_LEN 32 - -/* IOP reference numbers, used by the globally-visible iop_xxx functions */ - -#define IOP_NUM_SCC 0 -#define IOP_NUM_ISM 1 - -/* IOP channel states */ - -#define IOP_MSG_IDLE 0 /* idle */ -#define IOP_MSG_NEW 1 /* new message sent */ -#define IOP_MSG_RCVD 2 /* message received; processing */ -#define IOP_MSG_COMPLETE 3 /* message processing complete */ - -/* IOP message status codes */ - -#define IOP_MSGSTATUS_UNUSED 0 /* Unusued message structure */ -#define IOP_MSGSTATUS_WAITING 1 /* waiting for channel */ -#define IOP_MSGSTATUS_SENT 2 /* message sent, awaiting reply */ -#define IOP_MSGSTATUS_COMPLETE 3 /* message complete and reply rcvd */ -#define IOP_MSGSTATUS_UNSOL 6 /* message is unsolicited */ - -/* IOP memory addresses of the members of the mac_iop_kernel structure. */ - -#define IOP_ADDR_MAX_SEND_CHAN 0x0200 -#define IOP_ADDR_SEND_STATE 0x0201 -#define IOP_ADDR_PATCH_CTRL 0x021F -#define IOP_ADDR_SEND_MSG 0x0220 -#define IOP_ADDR_MAX_RECV_CHAN 0x0300 -#define IOP_ADDR_RECV_STATE 0x0301 -#define IOP_ADDR_ALIVE 0x031F -#define IOP_ADDR_RECV_MSG 0x0320 - -#ifndef __ASSEMBLY__ - -/* - * IOP Control registers, staggered because in usual Apple style they were - * too lazy to decode the A0 bit. This structure is assumed to begin at - * one of the xxx_IOP_BASE addresses given above. - */ - -struct mac_iop { - __u8 ram_addr_hi; /* shared RAM address hi byte */ - __u8 pad0; - __u8 ram_addr_lo; /* shared RAM address lo byte */ - __u8 pad1; - __u8 status_ctrl; /* status/control register */ - __u8 pad2[3]; - __u8 ram_data; /* RAM data byte at ramhi/lo */ - - __u8 pad3[23]; - - /* Bypass-mode hardware access registers */ - - union { - struct { /* SCC registers */ - __u8 sccb_cmd; /* SCC B command reg */ - __u8 pad4; - __u8 scca_cmd; /* SCC A command reg */ - __u8 pad5; - __u8 sccb_data; /* SCC B data */ - __u8 pad6; - __u8 scca_data; /* SCC A data */ - } scc_regs; - - struct { /* ISM registers */ - __u8 wdata; /* write a data byte */ - __u8 pad7; - __u8 wmark; /* write a mark byte */ - __u8 pad8; - __u8 wcrc; /* write 2-byte crc to disk */ - __u8 pad9; - __u8 wparams; /* write the param regs */ - __u8 pad10; - __u8 wphase; /* write the phase states & dirs */ - __u8 pad11; - __u8 wsetup; /* write the setup register */ - __u8 pad12; - __u8 wzeroes; /* mode reg: 1's clr bits, 0's are x */ - __u8 pad13; - __u8 wones; /* mode reg: 1's set bits, 0's are x */ - __u8 pad14; - __u8 rdata; /* read a data byte */ - __u8 pad15; - __u8 rmark; /* read a mark byte */ - __u8 pad16; - __u8 rerror; /* read the error register */ - __u8 pad17; - __u8 rparams; /* read the param regs */ - __u8 pad18; - __u8 rphase; /* read the phase states & dirs */ - __u8 pad19; - __u8 rsetup; /* read the setup register */ - __u8 pad20; - __u8 rmode; /* read the mode register */ - __u8 pad21; - __u8 rhandshake; /* read the handshake register */ - } ism_regs; - } b; -}; - -/* This structure is used to track IOP messages in the Linux kernel */ - -struct iop_msg { - struct iop_msg *next; /* next message in queue or NULL */ - uint iop_num; /* IOP number */ - uint channel; /* channel number */ - void *caller_priv; /* caller private data */ - int status; /* status of this message */ - __u8 message[IOP_MSG_LEN]; /* the message being sent/received */ - __u8 reply[IOP_MSG_LEN]; /* the reply to the message */ - void (*handler)(struct iop_msg *); - /* function to call when reply recvd */ -}; - -extern int iop_scc_present,iop_ism_present; - -extern int iop_listen(uint, uint, - void (*handler)(struct iop_msg *), - const char *); -extern int iop_send_message(uint, uint, void *, uint, __u8 *, - void (*)(struct iop_msg *)); -extern void iop_complete_message(struct iop_msg *); -extern void iop_upload_code(uint, __u8 *, uint, __u16); -extern void iop_download_code(uint, __u8 *, uint, __u16); -extern __u8 *iop_compare_code(uint, __u8 *, uint, __u16); - -#endif /* __ASSEMBLY__ */ diff --git a/include/asm-m68k/mac_mouse.h b/include/asm-m68k/mac_mouse.h deleted file mode 100644 index 39a5c292eae..00000000000 --- a/include/asm-m68k/mac_mouse.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _ASM_MAC_MOUSE_H -#define _ASM_MAC_MOUSE_H - -/* - * linux/include/asm-m68k/mac_mouse.h - * header file for Macintosh ADB mouse driver - * 27-10-97 Michael Schmitz - * copied from: - * header file for Atari Mouse driver - * by Robert de Vries (robert@and.nl) on 19Jul93 - */ - -struct mouse_status { - char buttons; - short dx; - short dy; - int ready; - int active; - wait_queue_head_t wait; - struct fasync_struct *fasyncptr; -}; - -#endif diff --git a/include/asm-m68k/mac_oss.h b/include/asm-m68k/mac_oss.h deleted file mode 100644 index 7221f725193..00000000000 --- a/include/asm-m68k/mac_oss.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * OSS - * - * This is used in place of VIA2 on the IIfx. - */ - -#define OSS_BASE (0x50f1a000) - -/* - * Interrupt level offsets for mac_oss->irq_level - */ - -#define OSS_NUBUS0 0 -#define OSS_NUBUS1 1 -#define OSS_NUBUS2 2 -#define OSS_NUBUS3 3 -#define OSS_NUBUS4 4 -#define OSS_NUBUS5 5 -#define OSS_IOPISM 6 -#define OSS_IOPSCC 7 -#define OSS_SOUND 8 -#define OSS_SCSI 9 -#define OSS_60HZ 10 -#define OSS_VIA1 11 -#define OSS_UNUSED1 12 -#define OSS_UNUSED2 13 -#define OSS_PARITY 14 -#define OSS_UNUSED3 15 - -#define OSS_NUM_SOURCES 16 - -/* - * Pending interrupt bits in mac_oss->irq_pending - */ - -#define OSS_IP_NUBUS0 0x0001 -#define OSS_IP_NUBUS1 0x0002 -#define OSS_IP_NUBUS2 0x0004 -#define OSS_IP_NUBUS3 0x0008 -#define OSS_IP_NUBUS4 0x0010 -#define OSS_IP_NUBUS5 0x0020 -#define OSS_IP_IOPISM 0x0040 -#define OSS_IP_IOPSCC 0x0080 -#define OSS_IP_SOUND 0x0100 -#define OSS_IP_SCSI 0x0200 -#define OSS_IP_60HZ 0x0400 -#define OSS_IP_VIA1 0x0800 -#define OSS_IP_UNUSED1 0x1000 -#define OSS_IP_UNUSED2 0x2000 -#define OSS_IP_PARITY 0x4000 -#define OSS_IP_UNUSED3 0x8000 - -#define OSS_IP_NUBUS (OSS_IP_NUBUS0|OSS_IP_NUBUS1|OSS_IP_NUBUS2|OSS_IP_NUBUS3|OSS_IP_NUBUS4|OSS_IP_NUBUS5) - -/* - * Rom Control Register - */ - -#define OSS_POWEROFF 0x80 - -/* - * OSS Interrupt levels for various sub-systems - * - * This mapping is layed out with two things in mind: first, we try to keep - * things on their own levels to avoid having to do double-dispatches. Second, - * the levels match as closely as possible the alternate IRQ mapping mode (aka - * "A/UX mode") available on some VIA machines. - */ - -#define OSS_IRQLEV_DISABLED 0 -#define OSS_IRQLEV_IOPISM 1 /* ADB? */ -#define OSS_IRQLEV_SCSI IRQ_AUTO_2 -#define OSS_IRQLEV_NUBUS IRQ_AUTO_3 /* keep this on its own level */ -#define OSS_IRQLEV_IOPSCC IRQ_AUTO_4 /* matches VIA alternate mapping */ -#define OSS_IRQLEV_SOUND IRQ_AUTO_5 /* matches VIA alternate mapping */ -#define OSS_IRQLEV_60HZ 6 /* matches VIA alternate mapping */ -#define OSS_IRQLEV_VIA1 IRQ_AUTO_6 /* matches VIA alternate mapping */ -#define OSS_IRQLEV_PARITY 7 /* matches VIA alternate mapping */ - -#ifndef __ASSEMBLY__ - -struct mac_oss { - __u8 irq_level[0x10]; /* [0x000-0x00f] Interrupt levels */ - __u8 padding0[0x1F2]; /* [0x010-0x201] IO space filler */ - __u16 irq_pending; /* [0x202-0x203] pending interrupts bits */ - __u8 rom_ctrl; /* [0x204-0x204] ROM cntl reg (for poweroff) */ - __u8 padding1[0x2]; /* [0x205-0x206] currently unused by A/UX */ - __u8 ack_60hz; /* [0x207-0x207] 60 Hz ack. */ -}; - -extern volatile struct mac_oss *oss; -extern int oss_present; - -#endif /* __ASSEMBLY__ */ diff --git a/include/asm-m68k/mac_psc.h b/include/asm-m68k/mac_psc.h deleted file mode 100644 index 7808bb0b232..00000000000 --- a/include/asm-m68k/mac_psc.h +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Apple Peripheral System Controller (PSC) - * - * The PSC is used on the AV Macs to control IO functions not handled - * by the VIAs (Ethernet, DSP, SCC, Sound). This includes nine DMA - * channels. - * - * The first seven DMA channels appear to be "one-shot" and are actually - * sets of two channels; one member is active while the other is being - * configured, and then you flip the active member and start all over again. - * The one-shot channels are grouped together and are: - * - * 1. SCSI - * 2. Ethernet Read - * 3. Ethernet Write - * 4. Floppy Disk Controller - * 5. SCC Channel A Receive - * 6. SCC Channel B Receive - * 7. SCC Channel A Transmit - * - * The remaining two channels are handled somewhat differently. They appear - * to be closely tied and share one set of registers. They also seem to run - * continuously, although how you keep the buffer filled in this scenario is - * not understood as there seems to be only one input and one output buffer - * pointer. - * - * Much of this was extrapolated from what was known about the Ethernet - * registers and subsequently confirmed using MacsBug (ie by pinging the - * machine with easy-to-find patterns and looking for them in the DMA - * buffers, or by sending a file over the serial ports and finding the - * file in the buffers.) - * - * 1999-05-25 (jmt) - */ - -#define PSC_BASE (0x50F31000) - -/* - * The IER/IFR registers work like the VIA, except that it has 4 - * of them each on different interrupt levels, and each register - * set only seems to handle four interrupts instead of seven. - * - * To access a particular set of registers, add 0xn0 to the base - * where n = 3,4,5 or 6. - */ - -#define pIFRbase 0x100 -#define pIERbase 0x104 - -/* - * One-shot DMA control registers - */ - -#define PSC_MYSTERY 0x804 - -#define PSC_CTL_BASE 0xC00 - -#define PSC_SCSI_CTL 0xC00 -#define PSC_ENETRD_CTL 0xC10 -#define PSC_ENETWR_CTL 0xC20 -#define PSC_FDC_CTL 0xC30 -#define PSC_SCCA_CTL 0xC40 -#define PSC_SCCB_CTL 0xC50 -#define PSC_SCCATX_CTL 0xC60 - -/* - * DMA channels. Add +0x10 for the second channel in the set. - * You're supposed to use one channel while the other runs and - * then flip channels and do the whole thing again. - */ - -#define PSC_ADDR_BASE 0x1000 -#define PSC_LEN_BASE 0x1004 -#define PSC_CMD_BASE 0x1008 - -#define PSC_SET0 0x00 -#define PSC_SET1 0x10 - -#define PSC_SCSI_ADDR 0x1000 /* confirmed */ -#define PSC_SCSI_LEN 0x1004 /* confirmed */ -#define PSC_SCSI_CMD 0x1008 /* confirmed */ -#define PSC_ENETRD_ADDR 0x1020 /* confirmed */ -#define PSC_ENETRD_LEN 0x1024 /* confirmed */ -#define PSC_ENETRD_CMD 0x1028 /* confirmed */ -#define PSC_ENETWR_ADDR 0x1040 /* confirmed */ -#define PSC_ENETWR_LEN 0x1044 /* confirmed */ -#define PSC_ENETWR_CMD 0x1048 /* confirmed */ -#define PSC_FDC_ADDR 0x1060 /* strongly suspected */ -#define PSC_FDC_LEN 0x1064 /* strongly suspected */ -#define PSC_FDC_CMD 0x1068 /* strongly suspected */ -#define PSC_SCCA_ADDR 0x1080 /* confirmed */ -#define PSC_SCCA_LEN 0x1084 /* confirmed */ -#define PSC_SCCA_CMD 0x1088 /* confirmed */ -#define PSC_SCCB_ADDR 0x10A0 /* confirmed */ -#define PSC_SCCB_LEN 0x10A4 /* confirmed */ -#define PSC_SCCB_CMD 0x10A8 /* confirmed */ -#define PSC_SCCATX_ADDR 0x10C0 /* confirmed */ -#define PSC_SCCATX_LEN 0x10C4 /* confirmed */ -#define PSC_SCCATX_CMD 0x10C8 /* confirmed */ - -/* - * Free-running DMA registers. The only part known for sure are the bits in - * the control register, the buffer addresses and the buffer length. Everything - * else is anybody's guess. - * - * These registers seem to be mirrored every thirty-two bytes up until offset - * 0x300. It's safe to assume then that a new set of registers starts there. - */ - -#define PSC_SND_CTL 0x200 /* - * [ 16-bit ] - * Sound (Singer?) control register. - * - * bit 0 : ???? - * bit 1 : ???? - * bit 2 : Set to one to enable sound - * output. Possibly a mute flag. - * bit 3 : ???? - * bit 4 : ???? - * bit 5 : ???? - * bit 6 : Set to one to enable pass-thru - * audio. In this mode the audio data - * seems to appear in both the input - * buffer and the output buffer. - * bit 7 : Set to one to activate the - * sound input DMA or zero to - * disable it. - * bit 8 : Set to one to activate the - * sound output DMA or zero to - * disable it. - * bit 9 : \ - * bit 11 : | - * These two bits control the sample - * rate. Usually set to binary 10 and - * MacOS 8.0 says I'm at 48 KHz. Using - * a binary value of 01 makes things - * sound about 1/2 speed (24 KHz?) and - * binary 00 is slower still (22 KHz?) - * - * Setting this to 0x0000 is a good way to - * kill all DMA at boot time so that the - * PSC won't overwrite the kernel image - * with sound data. - */ - -/* - * 0x0202 - 0x0203 is unused. Writing there - * seems to clobber the control register. - */ - -#define PSC_SND_SOURCE 0x204 /* - * [ 32-bit ] - * Controls input source and volume: - * - * bits 12-15 : input source volume, 0 - F - * bits 16-19 : unknown, always 0x5 - * bits 20-23 : input source selection: - * 0x3 = CD Audio - * 0x4 = External Audio - * - * The volume is definitely not the general - * output volume as it doesn't affect the - * alert sound volume. - */ -#define PSC_SND_STATUS1 0x208 /* - * [ 32-bit ] - * Appears to be a read-only status register. - * The usual value is 0x00400002. - */ -#define PSC_SND_HUH3 0x20C /* - * [ 16-bit ] - * Unknown 16-bit value, always 0x0000. - */ -#define PSC_SND_BITS2GO 0x20E /* - * [ 16-bit ] - * Counts down to zero from some constant - * value. The value appears to be the - * number of _bits_ remaining before the - * buffer is full, which would make sense - * since Apple's docs say the sound DMA - * channels are 1 bit wide. - */ -#define PSC_SND_INADDR 0x210 /* - * [ 32-bit ] - * Address of the sound input DMA buffer - */ -#define PSC_SND_OUTADDR 0x214 /* - * [ 32-bit ] - * Address of the sound output DMA buffer - */ -#define PSC_SND_LEN 0x218 /* - * [ 16-bit ] - * Length of both buffers in eight-byte units. - */ -#define PSC_SND_HUH4 0x21A /* - * [ 16-bit ] - * Unknown, always 0x0000. - */ -#define PSC_SND_STATUS2 0x21C /* - * [ 16-bit ] - * Appears to e a read-only status register. - * The usual value is 0x0200. - */ -#define PSC_SND_HUH5 0x21E /* - * [ 16-bit ] - * Unknown, always 0x0000. - */ - -#ifndef __ASSEMBLY__ - -extern volatile __u8 *psc; -extern int psc_present; - -/* - * Access functions - */ - -static inline void psc_write_byte(int offset, __u8 data) -{ - *((volatile __u8 *)(psc + offset)) = data; -} - -static inline void psc_write_word(int offset, __u16 data) -{ - *((volatile __u16 *)(psc + offset)) = data; -} - -static inline void psc_write_long(int offset, __u32 data) -{ - *((volatile __u32 *)(psc + offset)) = data; -} - -static inline u8 psc_read_byte(int offset) -{ - return *((volatile __u8 *)(psc + offset)); -} - -static inline u16 psc_read_word(int offset) -{ - return *((volatile __u16 *)(psc + offset)); -} - -static inline u32 psc_read_long(int offset) -{ - return *((volatile __u32 *)(psc + offset)); -} - -#endif /* __ASSEMBLY__ */ diff --git a/include/asm-m68k/mac_via.h b/include/asm-m68k/mac_via.h deleted file mode 100644 index 39afb438b65..00000000000 --- a/include/asm-m68k/mac_via.h +++ /dev/null @@ -1,267 +0,0 @@ -/* - * 6522 Versatile Interface Adapter (VIA) - * - * There are two of these on the Mac II. Some IRQ's are vectored - * via them as are assorted bits and bobs - eg rtc, adb. The picture - * is a bit incomplete as the Mac documentation doesn't cover this well - */ - -#ifndef _ASM_MAC_VIA_H_ -#define _ASM_MAC_VIA_H_ - -/* - * Base addresses for the VIAs. There are two in every machine, - * although on some machines the second is an RBV or an OSS. - * The OSS is different enough that it's handled separately. - * - * Do not use these values directly; use the via1 and via2 variables - * instead (and don't forget to check rbv_present when using via2!) - */ - -#define VIA1_BASE (0x50F00000) -#define VIA2_BASE (0x50F02000) -#define RBV_BASE (0x50F26000) - -/* - * Not all of these are true post MacII I think. - * CSA: probably the ones CHRP marks as 'unused' change purposes - * when the IWM becomes the SWIM. - * http://www.rs6000.ibm.com/resource/technology/chrpio/via5.mak.html - * ftp://ftp.austin.ibm.com/pub/technology/spec/chrp/inwork/CHRP_IORef_1.0.pdf - * - * also, http://developer.apple.com/technotes/hw/hw_09.html claims the - * following changes for IIfx: - * VIA1A_vSccWrReq not available and that VIA1A_vSync has moved to an IOP. - * Also, "All of the functionality of VIA2 has been moved to other chips". - */ - -#define VIA1A_vSccWrReq 0x80 /* SCC write. (input) - * [CHRP] SCC WREQ: Reflects the state of the - * Wait/Request pins from the SCC. - * [Macintosh Family Hardware] - * as CHRP on SE/30,II,IIx,IIcx,IIci. - * on IIfx, "0 means an active request" - */ -#define VIA1A_vRev8 0x40 /* Revision 8 board ??? - * [CHRP] En WaitReqB: Lets the WaitReq_L - * signal from port B of the SCC appear on - * the PA7 input pin. Output. - * [Macintosh Family] On the SE/30, this - * is the bit to flip screen buffers. - * 0=alternate, 1=main. - * on II,IIx,IIcx,IIci,IIfx this is a bit - * for Rev ID. 0=II,IIx, 1=IIcx,IIci,IIfx - */ -#define VIA1A_vHeadSel 0x20 /* Head select for IWM. - * [CHRP] unused. - * [Macintosh Family] "Floppy disk - * state-control line SEL" on all but IIfx - */ -#define VIA1A_vOverlay 0x10 /* [Macintosh Family] On SE/30,II,IIx,IIcx - * this bit enables the "Overlay" address - * map in the address decoders as it is on - * reset for mapping the ROM over the reset - * vector. 1=use overlay map. - * On the IIci,IIfx it is another bit of the - * CPU ID: 0=normal IIci, 1=IIci with parity - * feature or IIfx. - * [CHRP] En WaitReqA: Lets the WaitReq_L - * signal from port A of the SCC appear - * on the PA7 input pin (CHRP). Output. - * [MkLinux] "Drive Select" - * (with 0x20 being 'disk head select') - */ -#define VIA1A_vSync 0x08 /* [CHRP] Sync Modem: modem clock select: - * 1: select the external serial clock to - * drive the SCC's /RTxCA pin. - * 0: Select the 3.6864MHz clock to drive - * the SCC cell. - * [Macintosh Family] Correct on all but IIfx - */ - -/* Macintosh Family Hardware sez: bits 0-2 of VIA1A are volume control - * on Macs which had the PWM sound hardware. Reserved on newer models. - * On IIci,IIfx, bits 1-2 are the rest of the CPU ID: - * bit 2: 1=IIci, 0=IIfx - * bit 1: 1 on both IIci and IIfx. - * MkLinux sez bit 0 is 'burnin flag' in this case. - * CHRP sez: VIA1A bits 0-2 and 5 are 'unused': if programmed as - * inputs, these bits will read 0. - */ -#define VIA1A_vVolume 0x07 /* Audio volume mask for PWM */ -#define VIA1A_CPUID0 0x02 /* CPU id bit 0 on RBV, others */ -#define VIA1A_CPUID1 0x04 /* CPU id bit 0 on RBV, others */ -#define VIA1A_CPUID2 0x10 /* CPU id bit 0 on RBV, others */ -#define VIA1A_CPUID3 0x40 /* CPU id bit 0 on RBV, others */ - -/* Info on VIA1B is from Macintosh Family Hardware & MkLinux. - * CHRP offers no info. */ -#define VIA1B_vSound 0x80 /* Sound enable (for compatibility with - * PWM hardware) 0=enabled. - * Also, on IIci w/parity, shows parity error - * 0=error, 1=OK. */ -#define VIA1B_vMystery 0x40 /* On IIci, parity enable. 0=enabled,1=disabled - * On SE/30, vertical sync interrupt enable. - * 0=enabled. This vSync interrupt shows up - * as a slot $E interrupt. */ -#define VIA1B_vADBS2 0x20 /* ADB state input bit 1 (unused on IIfx) */ -#define VIA1B_vADBS1 0x10 /* ADB state input bit 0 (unused on IIfx) */ -#define VIA1B_vADBInt 0x08 /* ADB interrupt 0=interrupt (unused on IIfx)*/ -#define VIA1B_vRTCEnb 0x04 /* Enable Real time clock. 0=enabled. */ -#define VIA1B_vRTCClk 0x02 /* Real time clock serial-clock line. */ -#define VIA1B_vRTCData 0x01 /* Real time clock serial-data line. */ - -/* MkLinux defines the following "VIA1 Register B contents where they - * differ from standard VIA1". From the naming scheme, we assume they - * correspond to a VIA work-alike named 'EVR'. */ -#define EVRB_XCVR 0x08 /* XCVR_SESSION* */ -#define EVRB_FULL 0x10 /* VIA_FULL */ -#define EVRB_SYSES 0x20 /* SYS_SESSION */ -#define EVRB_AUXIE 0x00 /* Enable A/UX Interrupt Scheme */ -#define EVRB_AUXID 0x40 /* Disable A/UX Interrupt Scheme */ -#define EVRB_SFTWRIE 0x00 /* Software Interrupt ReQuest */ -#define EVRB_SFTWRID 0x80 /* Software Interrupt ReQuest */ - -/* - * VIA2 A register is the interrupt lines raised off the nubus - * slots. - * The below info is from 'Macintosh Family Hardware.' - * MkLinux calls the 'IIci internal video IRQ' below the 'RBV slot 0 irq.' - * It also notes that the slot $9 IRQ is the 'Ethernet IRQ' and - * defines the 'Video IRQ' as 0x40 for the 'EVR' VIA work-alike. - * Perhaps OSS uses vRAM1 and vRAM2 for ADB. - */ - -#define VIA2A_vRAM1 0x80 /* RAM size bit 1 (IIci: reserved) */ -#define VIA2A_vRAM0 0x40 /* RAM size bit 0 (IIci: internal video IRQ) */ -#define VIA2A_vIRQE 0x20 /* IRQ from slot $E */ -#define VIA2A_vIRQD 0x10 /* IRQ from slot $D */ -#define VIA2A_vIRQC 0x08 /* IRQ from slot $C */ -#define VIA2A_vIRQB 0x04 /* IRQ from slot $B */ -#define VIA2A_vIRQA 0x02 /* IRQ from slot $A */ -#define VIA2A_vIRQ9 0x01 /* IRQ from slot $9 */ - -/* RAM size bits decoded as follows: - * bit1 bit0 size of ICs in bank A - * 0 0 256 kbit - * 0 1 1 Mbit - * 1 0 4 Mbit - * 1 1 16 Mbit - */ - -/* - * Register B has the fun stuff in it - */ - -#define VIA2B_vVBL 0x80 /* VBL output to VIA1 (60.15Hz) driven by - * timer T1. - * on IIci, parity test: 0=test mode. - * [MkLinux] RBV_PARODD: 1=odd,0=even. */ -#define VIA2B_vSndJck 0x40 /* External sound jack status. - * 0=plug is inserted. On SE/30, always 0 */ -#define VIA2B_vTfr0 0x20 /* Transfer mode bit 0 ack from NuBus */ -#define VIA2B_vTfr1 0x10 /* Transfer mode bit 1 ack from NuBus */ -#define VIA2B_vMode32 0x08 /* 24/32bit switch - doubles as cache flush - * on II, AMU/PMMU control. - * if AMU, 0=24bit to 32bit translation - * if PMMU, 1=PMMU is accessing page table. - * on SE/30 tied low. - * on IIx,IIcx,IIfx, unused. - * on IIci/RBV, cache control. 0=flush cache. - */ -#define VIA2B_vPower 0x04 /* Power off, 0=shut off power. - * on SE/30 this signal sent to PDS card. */ -#define VIA2B_vBusLk 0x02 /* Lock NuBus transactions, 0=locked. - * on SE/30 sent to PDS card. */ -#define VIA2B_vCDis 0x01 /* Cache control. On IIci, 1=disable cache card - * on others, 0=disable processor's instruction - * and data caches. */ - -/* Apple sez: http://developer.apple.com/technotes/ov/ov_04.html - * Another example of a valid function that has no ROM support is the use - * of the alternate video page for page-flipping animation. Since there - * is no ROM call to flip pages, it is necessary to go play with the - * right bit in the VIA chip (6522 Versatile Interface Adapter). - * [CSA: don't know which one this is, but it's one of 'em!] - */ - -/* - * 6522 registers - see databook. - * CSA: Assignments for VIA1 confirmed from CHRP spec. - */ - -/* partial address decode. 0xYYXX : XX part for RBV, YY part for VIA */ -/* Note: 15 VIA regs, 8 RBV regs */ - -#define vBufB 0x0000 /* [VIA/RBV] Register B */ -#define vBufAH 0x0200 /* [VIA only] Buffer A, with handshake. DON'T USE! */ -#define vDirB 0x0400 /* [VIA only] Data Direction Register B. */ -#define vDirA 0x0600 /* [VIA only] Data Direction Register A. */ -#define vT1CL 0x0800 /* [VIA only] Timer one counter low. */ -#define vT1CH 0x0a00 /* [VIA only] Timer one counter high. */ -#define vT1LL 0x0c00 /* [VIA only] Timer one latches low. */ -#define vT1LH 0x0e00 /* [VIA only] Timer one latches high. */ -#define vT2CL 0x1000 /* [VIA only] Timer two counter low. */ -#define vT2CH 0x1200 /* [VIA only] Timer two counter high. */ -#define vSR 0x1400 /* [VIA only] Shift register. */ -#define vACR 0x1600 /* [VIA only] Auxilary control register. */ -#define vPCR 0x1800 /* [VIA only] Peripheral control register. */ - /* CHRP sez never ever to *write* this. - * Mac family says never to *change* this. - * In fact we need to initialize it once at start. */ -#define vIFR 0x1a00 /* [VIA/RBV] Interrupt flag register. */ -#define vIER 0x1c00 /* [VIA/RBV] Interrupt enable register. */ -#define vBufA 0x1e00 /* [VIA/RBV] register A (no handshake) */ - -/* The RBV only decodes the bottom eight address lines; the VIA doesn't - * decode the bottom eight -- so vBufB | rBufB will always get you BufB */ -/* CSA: in fact, only bits 0,1, and 4 seem to be decoded. - * BUT note the values for rIER and rIFR, where the top 8 bits *do* seem - * to matter. In fact *all* of the top 8 bits seem to matter; - * setting rIER=0x1813 and rIFR=0x1803 doesn't work, either. - * Perhaps some sort of 'compatibility mode' is built-in? [21-May-1999] - */ - -#define rBufB 0x0000 /* [VIA/RBV] Register B */ -#define rExp 0x0001 /* [RBV only] RBV future expansion (always 0) */ -#define rSIFR 0x0002 /* [RBV only] RBV slot interrupts register. */ -#define rIFR 0x1a03 /* [VIA/RBV] RBV interrupt flag register. */ -#define rMonP 0x0010 /* [RBV only] RBV video monitor type. */ -#define rChpT 0x0011 /* [RBV only] RBV test mode register (reads as 0). */ -#define rSIER 0x0012 /* [RBV only] RBV slot interrupt enables. */ -#define rIER 0x1c13 /* [VIA/RBV] RBV interrupt flag enable register. */ -#define rBufA rSIFR /* the 'slot interrupts register' is BufA on a VIA */ - -/* - * Video monitor parameters, for rMonP: - */ -#define RBV_DEPTH 0x07 /* bits per pixel: 000=1,001=2,010=4,011=8 */ -#define RBV_MONID 0x38 /* monitor type, as below. */ -#define RBV_VIDOFF 0x40 /* 1 turns off onboard video */ -/* Supported monitor types: */ -#define MON_15BW (1<<3) /* 15" BW portrait. */ -#define MON_IIGS (2<<3) /* 12" color (modified IIGS monitor). */ -#define MON_15RGB (5<<3) /* 15" RGB portrait. */ -#define MON_12OR13 (6<<3) /* 12" BW or 13" RGB. */ -#define MON_NONE (7<<3) /* No monitor attached. */ - -/* To clarify IER manipulations */ -#define IER_SET_BIT(b) (0x80 | (1<<(b)) ) -#define IER_CLR_BIT(b) (0x7F & (1<<(b)) ) - -#ifndef __ASSEMBLY__ - -extern volatile __u8 *via1,*via2; -extern int rbv_present,via_alt_mapping; - -static inline int rbv_set_video_bpp(int bpp) -{ - char val = (bpp==1)?0:(bpp==2)?1:(bpp==4)?2:(bpp==8)?3:-1; - if (!rbv_present || val<0) return -1; - via2[rMonP] = (via2[rMonP] & ~RBV_DEPTH) | val; - return 0; -} - -#endif /* __ASSEMBLY__ */ - -#endif /* _ASM_MAC_VIA_H_ */ diff --git a/include/asm-m68k/machdep.h b/include/asm-m68k/machdep.h deleted file mode 100644 index 5637dcef314..00000000000 --- a/include/asm-m68k/machdep.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _M68K_MACHDEP_H -#define _M68K_MACHDEP_H - -#include -#include - -struct pt_regs; -struct mktime; -struct rtc_time; -struct rtc_pll_info; -struct buffer_head; - -extern void (*mach_sched_init) (irq_handler_t handler); -/* machine dependent irq functions */ -extern void (*mach_init_IRQ) (void); -extern void (*mach_get_model) (char *model); -extern void (*mach_get_hardware_list) (struct seq_file *m); -/* machine dependent timer functions */ -extern unsigned long (*mach_gettimeoffset)(void); -extern int (*mach_hwclk)(int, struct rtc_time*); -extern unsigned int (*mach_get_ss)(void); -extern int (*mach_get_rtc_pll)(struct rtc_pll_info *); -extern int (*mach_set_rtc_pll)(struct rtc_pll_info *); -extern int (*mach_set_clock_mmss)(unsigned long); -extern void (*mach_reset)( void ); -extern void (*mach_halt)( void ); -extern void (*mach_power_off)( void ); -extern unsigned long (*mach_hd_init) (unsigned long, unsigned long); -extern void (*mach_hd_setup)(char *, int *); -extern long mach_max_dma_address; -extern void (*mach_heartbeat) (int); -extern void (*mach_l2_flush) (int); -extern void (*mach_beep) (unsigned int, unsigned int); - -#endif /* _M68K_MACHDEP_H */ diff --git a/include/asm-m68k/machines.h b/include/asm-m68k/machines.h deleted file mode 100644 index be667e84f01..00000000000 --- a/include/asm-m68k/machines.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * machines.h: Defines for taking apart the machine type value in the - * idprom and determining the kind of machine we are on. - * - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) - * Sun3/3x models added by David Monro (davidm@psrg.cs.usyd.edu.au) - */ -#ifndef _SPARC_MACHINES_H -#define _SPARC_MACHINES_H - -struct Sun_Machine_Models { - char *name; - unsigned char id_machtype; -}; - -/* Current number of machines we know about that has an IDPROM - * machtype entry including one entry for the 0x80 OBP machines. - */ -// reduced along with table in arch/m68k/sun3/idprom.c -// sun3 port doesn't need to know about sparc machines. -//#define NUM_SUN_MACHINES 23 -#define NUM_SUN_MACHINES 8 - -/* The machine type in the idprom area looks like this: - * - * --------------- - * | ARCH | MACH | - * --------------- - * 7 4 3 0 - * - * The ARCH field determines the architecture line (sun4, sun4c, etc). - * The MACH field determines the machine make within that architecture. - */ - -#define SM_ARCH_MASK 0xf0 -#define SM_SUN3 0x10 -#define SM_SUN4 0x20 -#define SM_SUN3X 0x40 -#define SM_SUN4C 0x50 -#define SM_SUN4M 0x70 -#define SM_SUN4M_OBP 0x80 - -#define SM_TYP_MASK 0x0f -/* Sun3 machines */ -#define SM_3_160 0x01 /* Sun 3/160 series */ -#define SM_3_50 0x02 /* Sun 3/50 series */ -#define SM_3_260 0x03 /* Sun 3/260 series */ -#define SM_3_110 0x04 /* Sun 3/110 series */ -#define SM_3_60 0x07 /* Sun 3/60 series */ -#define SM_3_E 0x08 /* Sun 3/E series */ - -/* Sun3x machines */ -#define SM_3_460 0x01 /* Sun 3/460 (460,470,480) series */ -#define SM_3_80 0x02 /* Sun 3/80 series */ - -/* Sun4 machines */ -#define SM_4_260 0x01 /* Sun 4/200 series */ -#define SM_4_110 0x02 /* Sun 4/100 series */ -#define SM_4_330 0x03 /* Sun 4/300 series */ -#define SM_4_470 0x04 /* Sun 4/400 series */ - -/* Sun4c machines Full Name - PROM NAME */ -#define SM_4C_SS1 0x01 /* Sun4c SparcStation 1 - Sun 4/60 */ -#define SM_4C_IPC 0x02 /* Sun4c SparcStation IPC - Sun 4/40 */ -#define SM_4C_SS1PLUS 0x03 /* Sun4c SparcStation 1+ - Sun 4/65 */ -#define SM_4C_SLC 0x04 /* Sun4c SparcStation SLC - Sun 4/20 */ -#define SM_4C_SS2 0x05 /* Sun4c SparcStation 2 - Sun 4/75 */ -#define SM_4C_ELC 0x06 /* Sun4c SparcStation ELC - Sun 4/25 */ -#define SM_4C_IPX 0x07 /* Sun4c SparcStation IPX - Sun 4/50 */ - -/* Sun4m machines, these predate the OpenBoot. These values only mean - * something if the value in the ARCH field is SM_SUN4M, if it is - * SM_SUN4M_OBP then you have the following situation: - * 1) You either have a sun4d, a sun4e, or a recently made sun4m. - * 2) You have to consult OpenBoot to determine which machine this is. - */ -#define SM_4M_SS60 0x01 /* Sun4m SparcSystem 600 */ -#define SM_4M_SS50 0x02 /* Sun4m SparcStation 10 */ -#define SM_4M_SS40 0x03 /* Sun4m SparcStation 5 */ - -/* Sun4d machines -- N/A */ -/* Sun4e machines -- N/A */ -/* Sun4u machines -- N/A */ - -#endif /* !(_SPARC_MACHINES_H) */ diff --git a/include/asm-m68k/machw.h b/include/asm-m68k/machw.h deleted file mode 100644 index 2b4de0c2ce4..00000000000 --- a/include/asm-m68k/machw.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -** linux/machw.h -- This header defines some macros and pointers for -** the various Macintosh custom hardware registers. -** -** Copyright 1997 by Michael Schmitz -** -** This file is subject to the terms and conditions of the GNU General Public -** License. See the file COPYING in the main directory of this archive -** for more details. -** -*/ - -#ifndef _ASM_MACHW_H_ -#define _ASM_MACHW_H_ - -/* - * head.S maps the videomem to VIDEOMEMBASE - */ - -#define VIDEOMEMBASE 0xf0000000 -#define VIDEOMEMSIZE (4096*1024) -#define VIDEOMEMMASK (-4096*1024) - -#ifndef __ASSEMBLY__ - -#include - -#if 0 -/* -** SCC Z8530 -*/ - -#define MAC_SCC_BAS (0x50F04000) -struct MAC_SCC - { - u_char cha_a_ctrl; - u_char char_dummy1; - u_char cha_a_data; - u_char char_dummy2; - u_char cha_b_ctrl; - u_char char_dummy3; - u_char cha_b_data; - }; -# define mac_scc ((*(volatile struct SCC*)MAC_SCC_BAS)) -#endif - -#endif /* __ASSEMBLY__ */ - -#endif /* linux/machw.h */ diff --git a/include/asm-m68k/macintosh.h b/include/asm-m68k/macintosh.h deleted file mode 100644 index 05309f7e3d0..00000000000 --- a/include/asm-m68k/macintosh.h +++ /dev/null @@ -1,135 +0,0 @@ -#ifndef __ASM_MACINTOSH_H -#define __ASM_MACINTOSH_H - -#include -#include - -/* - * Apple Macintoshisms - */ - -extern void mac_reset(void); -extern void mac_poweroff(void); -extern void mac_init_IRQ(void); -extern int mac_irq_pending(unsigned int); - -/* - * Floppy driver magic hook - probably shouldnt be here - */ - -extern void via1_set_head(int); - -/* - * Macintosh Table - */ - -struct mac_model -{ - short ident; - char *name; - char adb_type; - char via_type; - char scsi_type; - char ide_type; - char scc_type; - char ether_type; - char nubus_type; -}; - -#define MAC_ADB_NONE 0 -#define MAC_ADB_II 1 -#define MAC_ADB_IISI 2 -#define MAC_ADB_CUDA 3 -#define MAC_ADB_PB1 4 -#define MAC_ADB_PB2 5 -#define MAC_ADB_IOP 6 - -#define MAC_VIA_II 1 -#define MAC_VIA_IIci 2 -#define MAC_VIA_QUADRA 3 - -#define MAC_SCSI_NONE 0 -#define MAC_SCSI_OLD 1 -#define MAC_SCSI_QUADRA 2 -#define MAC_SCSI_QUADRA2 3 -#define MAC_SCSI_QUADRA3 4 - -#define MAC_IDE_NONE 0 -#define MAC_IDE_QUADRA 1 -#define MAC_IDE_PB 2 -#define MAC_IDE_BABOON 3 - -#define MAC_SCC_II 1 -#define MAC_SCC_IOP 2 -#define MAC_SCC_QUADRA 3 -#define MAC_SCC_PSC 4 - -#define MAC_ETHER_NONE 0 -#define MAC_ETHER_SONIC 1 -#define MAC_ETHER_MACE 2 - -#define MAC_NO_NUBUS 0 -#define MAC_NUBUS 1 - -/* - * Gestalt numbers - */ - -#define MAC_MODEL_II 6 -#define MAC_MODEL_IIX 7 -#define MAC_MODEL_IICX 8 -#define MAC_MODEL_SE30 9 -#define MAC_MODEL_IICI 11 -#define MAC_MODEL_IIFX 13 /* And well numbered it is too */ -#define MAC_MODEL_IISI 18 -#define MAC_MODEL_LC 19 -#define MAC_MODEL_Q900 20 -#define MAC_MODEL_PB170 21 -#define MAC_MODEL_Q700 22 -#define MAC_MODEL_CLII 23 /* aka: P200 */ -#define MAC_MODEL_PB140 25 -#define MAC_MODEL_Q950 26 /* aka: WGS95 */ -#define MAC_MODEL_LCIII 27 /* aka: P450 */ -#define MAC_MODEL_PB210 29 -#define MAC_MODEL_C650 30 -#define MAC_MODEL_PB230 32 -#define MAC_MODEL_PB180 33 -#define MAC_MODEL_PB160 34 -#define MAC_MODEL_Q800 35 /* aka: WGS80 */ -#define MAC_MODEL_Q650 36 -#define MAC_MODEL_LCII 37 /* aka: P400/405/410/430 */ -#define MAC_MODEL_PB250 38 -#define MAC_MODEL_IIVI 44 -#define MAC_MODEL_P600 45 /* aka: P600CD */ -#define MAC_MODEL_IIVX 48 -#define MAC_MODEL_CCL 49 /* aka: P250 */ -#define MAC_MODEL_PB165C 50 -#define MAC_MODEL_C610 52 /* aka: WGS60 */ -#define MAC_MODEL_Q610 53 -#define MAC_MODEL_PB145 54 /* aka: PB145B */ -#define MAC_MODEL_P520 56 /* aka: LC520 */ -#define MAC_MODEL_C660 60 -#define MAC_MODEL_P460 62 /* aka: LCIII+, P466/P467 */ -#define MAC_MODEL_PB180C 71 -#define MAC_MODEL_PB520 72 /* aka: PB520C, PB540, PB540C, PB550C */ -#define MAC_MODEL_PB270C 77 -#define MAC_MODEL_Q840 78 -#define MAC_MODEL_P550 80 /* aka: LC550, P560 */ -#define MAC_MODEL_CCLII 83 /* aka: P275 */ -#define MAC_MODEL_PB165 84 -#define MAC_MODEL_PB190 85 /* aka: PB190CS */ -#define MAC_MODEL_TV 88 -#define MAC_MODEL_P475 89 /* aka: LC475, P476 */ -#define MAC_MODEL_P475F 90 /* aka: P475 w/ FPU (no LC040) */ -#define MAC_MODEL_P575 92 /* aka: LC575, P577/P578 */ -#define MAC_MODEL_Q605 94 -#define MAC_MODEL_Q605_ACC 95 /* Q605 accelerated to 33 MHz */ -#define MAC_MODEL_Q630 98 /* aka: LC630, P630/631/635/636/637/638/640 */ -#define MAC_MODEL_P588 99 /* aka: LC580, P580 */ -#define MAC_MODEL_PB280 102 -#define MAC_MODEL_PB280C 103 -#define MAC_MODEL_PB150 115 - -extern struct mac_model *macintosh_config; - -#endif diff --git a/include/asm-m68k/macints.h b/include/asm-m68k/macints.h deleted file mode 100644 index 679c48ab440..00000000000 --- a/include/asm-m68k/macints.h +++ /dev/null @@ -1,155 +0,0 @@ -/* -** macints.h -- Macintosh Linux interrupt handling structs and prototypes -** -** Copyright 1997 by Michael Schmitz -** -** This file is subject to the terms and conditions of the GNU General Public -** License. See the file COPYING in the main directory of this archive -** for more details. -** -*/ - -#ifndef _ASM_MACINTS_H_ -#define _ASM_MACINTS_H_ - -#include - -/* Setting this prints debugging info for unclaimed interrupts */ - -#define DEBUG_SPURIOUS - -/* Setting this prints debugging info on each autovector interrupt */ - -/* #define DEBUG_IRQS */ - -/* Setting this prints debugging info on each Nubus interrupt */ - -/* #define DEBUG_NUBUS_INT */ - -/* Setting this prints debugging info on irqs as they enabled and disabled. */ - -/* #define DEBUG_IRQUSE */ - -/* - * Base IRQ number for all Mac68K interrupt sources. Each source - * has eight indexes (base -> base+7). - */ - -#define VIA1_SOURCE_BASE 8 -#define VIA2_SOURCE_BASE 16 -#define MAC_SCC_SOURCE_BASE 24 -#define PSC3_SOURCE_BASE 24 -#define PSC4_SOURCE_BASE 32 -#define PSC5_SOURCE_BASE 40 -#define PSC6_SOURCE_BASE 48 -#define NUBUS_SOURCE_BASE 56 -#define BABOON_SOURCE_BASE 64 - -/* - * Maximum IRQ number is BABOON_SOURCE_BASE + 7, - * giving us IRQs up through 71 - */ - -#define NUM_MAC_SOURCES 72 - -/* - * clean way to separate IRQ into its source and index - */ - -#define IRQ_SRC(irq) (irq >> 3) -#define IRQ_IDX(irq) (irq & 7) - -/* VIA1 interrupts */ -#define IRQ_VIA1_0 (8) /* one second int. */ -#define IRQ_VIA1_1 (9) /* VBlank int. */ -#define IRQ_MAC_VBL IRQ_VIA1_1 -#define IRQ_VIA1_2 (10) /* ADB SR shifts complete */ -#define IRQ_MAC_ADB IRQ_VIA1_2 -#define IRQ_MAC_ADB_SR IRQ_VIA1_2 -#define IRQ_VIA1_3 (11) /* ADB SR CB2 ?? */ -#define IRQ_MAC_ADB_SD IRQ_VIA1_3 -#define IRQ_VIA1_4 (12) /* ADB SR ext. clock pulse */ -#define IRQ_MAC_ADB_CL IRQ_VIA1_4 -#define IRQ_VIA1_5 (13) -#define IRQ_MAC_TIMER_2 IRQ_VIA1_5 -#define IRQ_VIA1_6 (14) -#define IRQ_MAC_TIMER_1 IRQ_VIA1_6 -#define IRQ_VIA1_7 (15) - -/* VIA2/RBV interrupts */ -#define IRQ_VIA2_0 (16) -#define IRQ_MAC_SCSIDRQ IRQ_VIA2_0 -#define IRQ_VIA2_1 (17) -#define IRQ_MAC_NUBUS IRQ_VIA2_1 -#define IRQ_VIA2_2 (18) -#define IRQ_VIA2_3 (19) -#define IRQ_MAC_SCSI IRQ_VIA2_3 -#define IRQ_VIA2_4 (20) -#define IRQ_VIA2_5 (21) -#define IRQ_VIA2_6 (22) -#define IRQ_VIA2_7 (23) - -/* Level 3 (PSC, AV Macs only) interrupts */ -#define IRQ_PSC3_0 (24) -#define IRQ_MAC_MACE IRQ_PSC3_0 -#define IRQ_PSC3_1 (25) -#define IRQ_PSC3_2 (26) -#define IRQ_PSC3_3 (27) - -/* Level 4 (SCC) interrupts */ -#define IRQ_SCC (32) -#define IRQ_SCCA (33) -#define IRQ_SCCB (34) -#if 0 /* FIXME: are there multiple interrupt conditions on the SCC ?? */ -/* SCC interrupts */ -#define IRQ_SCCB_TX (32) -#define IRQ_SCCB_STAT (33) -#define IRQ_SCCB_RX (34) -#define IRQ_SCCB_SPCOND (35) -#define IRQ_SCCA_TX (36) -#define IRQ_SCCA_STAT (37) -#define IRQ_SCCA_RX (38) -#define IRQ_SCCA_SPCOND (39) -#endif - -/* Level 4 (PSC, AV Macs only) interrupts */ -#define IRQ_PSC4_0 (32) -#define IRQ_PSC4_1 (33) -#define IRQ_PSC4_2 (34) -#define IRQ_PSC4_3 (35) -#define IRQ_MAC_MACE_DMA IRQ_PSC4_3 - -/* Level 5 (PSC, AV Macs only) interrupts */ -#define IRQ_PSC5_0 (40) -#define IRQ_PSC5_1 (41) -#define IRQ_PSC5_2 (42) -#define IRQ_PSC5_3 (43) - -/* Level 6 (PSC, AV Macs only) interrupts */ -#define IRQ_PSC6_0 (48) -#define IRQ_PSC6_1 (49) -#define IRQ_PSC6_2 (50) -#define IRQ_PSC6_3 (51) - -/* Nubus interrupts (cascaded to VIA2) */ -#define IRQ_NUBUS_9 (56) -#define IRQ_NUBUS_A (57) -#define IRQ_NUBUS_B (58) -#define IRQ_NUBUS_C (59) -#define IRQ_NUBUS_D (60) -#define IRQ_NUBUS_E (61) -#define IRQ_NUBUS_F (62) - -/* Baboon interrupts (cascaded to nubus slot $C) */ -#define IRQ_BABOON_0 (64) -#define IRQ_BABOON_1 (65) -#define IRQ_BABOON_2 (66) -#define IRQ_BABOON_3 (67) - -#define SLOT2IRQ(x) (x + 47) -#define IRQ2SLOT(x) (x - 47) - -#define INT_CLK 24576 /* CLK while int_clk =2.456MHz and divide = 100 */ -#define INT_TICKS 246 /* to make sched_time = 99.902... HZ */ - -#endif /* asm/macints.h */ diff --git a/include/asm-m68k/math-emu.h b/include/asm-m68k/math-emu.h deleted file mode 100644 index ddfab96403c..00000000000 --- a/include/asm-m68k/math-emu.h +++ /dev/null @@ -1,315 +0,0 @@ -#ifndef _ASM_M68K_SETUP_H -#define _ASM_M68K_SETUP_H - -#include -#include - -/* Status Register bits */ - -/* accrued exception bits */ -#define FPSR_AEXC_INEX 3 -#define FPSR_AEXC_DZ 4 -#define FPSR_AEXC_UNFL 5 -#define FPSR_AEXC_OVFL 6 -#define FPSR_AEXC_IOP 7 - -/* exception status bits */ -#define FPSR_EXC_INEX1 8 -#define FPSR_EXC_INEX2 9 -#define FPSR_EXC_DZ 10 -#define FPSR_EXC_UNFL 11 -#define FPSR_EXC_OVFL 12 -#define FPSR_EXC_OPERR 13 -#define FPSR_EXC_SNAN 14 -#define FPSR_EXC_BSUN 15 - -/* quotient byte, assumes big-endian, of course */ -#define FPSR_QUOTIENT(fpsr) (*((signed char *) &(fpsr) + 1)) - -/* condition code bits */ -#define FPSR_CC_NAN 24 -#define FPSR_CC_INF 25 -#define FPSR_CC_Z 26 -#define FPSR_CC_NEG 27 - - -/* Control register bits */ - -/* rounding mode */ -#define FPCR_ROUND_RN 0 /* round to nearest/even */ -#define FPCR_ROUND_RZ 1 /* round to zero */ -#define FPCR_ROUND_RM 2 /* minus infinity */ -#define FPCR_ROUND_RP 3 /* plus infinity */ - -/* rounding precision */ -#define FPCR_PRECISION_X 0 /* long double */ -#define FPCR_PRECISION_S 1 /* double */ -#define FPCR_PRECISION_D 2 /* float */ - - -/* Flags to select the debugging output */ -#define PDECODE 0 -#define PEXECUTE 1 -#define PCONV 2 -#define PNORM 3 -#define PREGISTER 4 -#define PINSTR 5 -#define PUNIMPL 6 -#define PMOVEM 7 - -#define PMDECODE (1< -#include - -union fp_mant64 { - unsigned long long m64; - unsigned long m32[2]; -}; - -union fp_mant128 { - unsigned long long m64[2]; - unsigned long m32[4]; -}; - -/* internal representation of extended fp numbers */ -struct fp_ext { - unsigned char lowmant; - unsigned char sign; - unsigned short exp; - union fp_mant64 mant; -}; - -/* C representation of FPU registers */ -/* NOTE: if you change this, you have to change the assembler offsets - below and the size in , too */ -struct fp_data { - struct fp_ext fpreg[8]; - unsigned int fpcr; - unsigned int fpsr; - unsigned int fpiar; - unsigned short prec; - unsigned short rnd; - struct fp_ext temp[2]; -}; - -#ifdef FPU_EMU_DEBUG -extern unsigned int fp_debugprint; - -#define dprint(bit, fmt, args...) ({ \ - if (fp_debugprint & (1 << (bit))) \ - printk(fmt, ## args); \ -}) -#else -#define dprint(bit, fmt, args...) -#endif - -#define uprint(str) ({ \ - static int __count = 3; \ - \ - if (__count > 0) { \ - printk("You just hit an unimplemented " \ - "fpu instruction (%s)\n", str); \ - printk("Please report this to ....\n"); \ - __count--; \ - } \ -}) - -#define FPDATA ((struct fp_data *)current->thread.fp) - -#else /* __ASSEMBLY__ */ - -#define FPDATA %a2 - -/* offsets from the base register to the floating point data in the task struct */ -#define FPD_FPREG (TASK_THREAD+THREAD_FPREG+0) -#define FPD_FPCR (TASK_THREAD+THREAD_FPREG+96) -#define FPD_FPSR (TASK_THREAD+THREAD_FPREG+100) -#define FPD_FPIAR (TASK_THREAD+THREAD_FPREG+104) -#define FPD_PREC (TASK_THREAD+THREAD_FPREG+108) -#define FPD_RND (TASK_THREAD+THREAD_FPREG+110) -#define FPD_TEMPFP1 (TASK_THREAD+THREAD_FPREG+112) -#define FPD_TEMPFP2 (TASK_THREAD+THREAD_FPREG+124) -#define FPD_SIZEOF (TASK_THREAD+THREAD_FPREG+136) - -/* offsets on the stack to access saved registers, - * these are only used during instruction decoding - * where we always know how deep we're on the stack. - */ -#define FPS_DO (PT_D0) -#define FPS_D1 (PT_D1) -#define FPS_D2 (PT_D2) -#define FPS_A0 (PT_A0) -#define FPS_A1 (PT_A1) -#define FPS_A2 (PT_A2) -#define FPS_SR (PT_SR) -#define FPS_PC (PT_PC) -#define FPS_EA (PT_PC+6) -#define FPS_PC2 (PT_PC+10) - -.macro fp_get_fp_reg - lea (FPD_FPREG,FPDATA,%d0.w*4),%a0 - lea (%a0,%d0.w*8),%a0 -.endm - -/* Macros used to get/put the current program counter. - * 020/030 use a different stack frame then 040/060, for the - * 040/060 the return pc points already to the next location, - * so this only needs to be modified for jump instructions. - */ -.macro fp_get_pc dest - move.l (FPS_PC+4,%sp),\dest -.endm - -.macro fp_put_pc src,jump=0 - move.l \src,(FPS_PC+4,%sp) -.endm - -.macro fp_get_instr_data f,s,dest,label - getuser \f,%sp@(FPS_PC+4)@(0),\dest,\label,%sp@(FPS_PC+4) - addq.l #\s,%sp@(FPS_PC+4) -.endm - -.macro fp_get_instr_word dest,label,addr - fp_get_instr_data w,2,\dest,\label,\addr -.endm - -.macro fp_get_instr_long dest,label,addr - fp_get_instr_data l,4,\dest,\label,\addr -.endm - -/* These macros are used to read from/write to user space - * on error we jump to the fixup section, load the fault - * address into %a0 and jump to the exit. - * (derived from ) - */ -.macro getuser size,src,dest,label,addr -| printf ,"[\size<%08x]",1,\addr -.Lu1\@: moves\size \src,\dest - - .section .fixup,"ax" - .even -.Lu2\@: move.l \addr,%a0 - jra \label - .previous - - .section __ex_table,"a" - .align 4 - .long .Lu1\@,.Lu2\@ - .previous -.endm - -.macro putuser size,src,dest,label,addr -| printf ,"[\size>%08x]",1,\addr -.Lu1\@: moves\size \src,\dest -.Lu2\@: - - .section .fixup,"ax" - .even -.Lu3\@: move.l \addr,%a0 - jra \label - .previous - - .section __ex_table,"a" - .align 4 - .long .Lu1\@,.Lu3\@ - .long .Lu2\@,.Lu3\@ - .previous -.endm - -/* work around binutils idiocy */ -old_gas=-1 -.irp gas_ident.x .x -old_gas=old_gas+1 -.endr -.if !old_gas -.irp m b,w,l -.macro getuser.\m src,dest,label,addr - getuser .\m,\src,\dest,\label,\addr -.endm -.macro putuser.\m src,dest,label,addr - putuser .\m,\src,\dest,\label,\addr -.endm -.endr -.endif - -.macro movestack nr,arg1,arg2,arg3,arg4,arg5 - .if \nr - movestack (\nr-1),\arg2,\arg3,\arg4,\arg5 - move.l \arg1,-(%sp) - .endif -.endm - -.macro printf bit=-1,string,nr=0,arg1,arg2,arg3,arg4,arg5 -#ifdef FPU_EMU_DEBUG - .data -.Lpdata\@: - .string "\string" - .previous - - movem.l %d0/%d1/%a0/%a1,-(%sp) - .if \bit+1 -#if 0 - moveq #\bit,%d0 - andw #7,%d0 - btst %d0,fp_debugprint+((31-\bit)/8) -#else - btst #\bit,fp_debugprint+((31-\bit)/8) -#endif - jeq .Lpskip\@ - .endif - movestack \nr,\arg1,\arg2,\arg3,\arg4,\arg5 - pea .Lpdata\@ - jsr printk - lea ((\nr+1)*4,%sp),%sp -.Lpskip\@: - movem.l (%sp)+,%d0/%d1/%a0/%a1 -#endif -.endm - -.macro printx bit,fp -#ifdef FPU_EMU_DEBUG - movem.l %d0/%a0,-(%sp) - lea \fp,%a0 -#if 0 - moveq #'+',%d0 - tst.w (%a0) - jeq .Lx1\@ - moveq #'-',%d0 -.Lx1\@: printf \bit," %c",1,%d0 - move.l (4,%a0),%d0 - bclr #31,%d0 - jne .Lx2\@ - printf \bit,"0." - jra .Lx3\@ -.Lx2\@: printf \bit,"1." -.Lx3\@: printf \bit,"%08x%08x",2,%d0,%a0@(8) - move.w (2,%a0),%d0 - ext.l %d0 - printf \bit,"E%04x",1,%d0 -#else - printf \bit," %08x%08x%08x",3,%a0@,%a0@(4),%a0@(8) -#endif - movem.l (%sp)+,%d0/%a0 -#endif -.endm - -.macro debug instr,args -#ifdef FPU_EMU_DEBUG - \instr \args -#endif -.endm - - -#endif /* __ASSEMBLY__ */ - -#endif /* _ASM_M68K_SETUP_H */ diff --git a/include/asm-m68k/mc146818rtc.h b/include/asm-m68k/mc146818rtc.h deleted file mode 100644 index 9f70a01f73d..00000000000 --- a/include/asm-m68k/mc146818rtc.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Machine dependent access functions for RTC registers. - */ -#ifndef _ASM_MC146818RTC_H -#define _ASM_MC146818RTC_H - - -#ifdef CONFIG_ATARI -/* RTC in Atari machines */ - -#include - -#define RTC_PORT(x) (TT_RTC_BAS + 2*(x)) -#define RTC_ALWAYS_BCD 0 - -#define CMOS_READ(addr) ({ \ -atari_outb_p((addr),RTC_PORT(0)); \ -atari_inb_p(RTC_PORT(1)); \ -}) -#define CMOS_WRITE(val, addr) ({ \ -atari_outb_p((addr),RTC_PORT(0)); \ -atari_outb_p((val),RTC_PORT(1)); \ -}) -#endif /* CONFIG_ATARI */ - -#endif /* _ASM_MC146818RTC_H */ diff --git a/include/asm-m68k/md.h b/include/asm-m68k/md.h deleted file mode 100644 index d2f78f226f3..00000000000 --- a/include/asm-m68k/md.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * md.h: High speed xor_block operation for RAID4/5 - * - */ - -#ifndef __ASM_MD_H -#define __ASM_MD_H - -/* #define HAVE_ARCH_XORBLOCK */ - -#define MD_XORBLOCK_ALIGNMENT sizeof(long) - -#endif /* __ASM_MD_H */ diff --git a/include/asm-m68k/mman.h b/include/asm-m68k/mman.h deleted file mode 100644 index 1626d37f489..00000000000 --- a/include/asm-m68k/mman.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __M68K_MMAN_H__ -#define __M68K_MMAN_H__ - -#include - -#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ -#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ -#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ -#define MAP_LOCKED 0x2000 /* pages are locked */ -#define MAP_NORESERVE 0x4000 /* don't check for reservations */ -#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ -#define MAP_NONBLOCK 0x10000 /* do not block on IO */ - -#define MCL_CURRENT 1 /* lock all current mappings */ -#define MCL_FUTURE 2 /* lock all future mappings */ - -#endif /* __M68K_MMAN_H__ */ diff --git a/include/asm-m68k/mmu.h b/include/asm-m68k/mmu.h deleted file mode 100644 index ccd36d26615..00000000000 --- a/include/asm-m68k/mmu.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __MMU_H -#define __MMU_H - -/* Default "unsigned long" context */ -typedef unsigned long mm_context_t; - -#endif diff --git a/include/asm-m68k/mmu_context.h b/include/asm-m68k/mmu_context.h deleted file mode 100644 index 894dacbcee1..00000000000 --- a/include/asm-m68k/mmu_context.h +++ /dev/null @@ -1,154 +0,0 @@ -#ifndef __M68K_MMU_CONTEXT_H -#define __M68K_MMU_CONTEXT_H - -#include - -static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) -{ -} - -#ifndef CONFIG_SUN3 - -#include -#include -#include - -static inline int init_new_context(struct task_struct *tsk, - struct mm_struct *mm) -{ - mm->context = virt_to_phys(mm->pgd); - return 0; -} - -#define destroy_context(mm) do { } while(0) - -static inline void switch_mm_0230(struct mm_struct *mm) -{ - unsigned long crp[2] = { - 0x80000000 | _PAGE_TABLE, mm->context - }; - unsigned long tmp; - - asm volatile (".chip 68030"); - - /* flush MC68030/MC68020 caches (they are virtually addressed) */ - asm volatile ( - "movec %%cacr,%0;" - "orw %1,%0; " - "movec %0,%%cacr" - : "=d" (tmp) : "di" (FLUSH_I_AND_D)); - - /* Switch the root pointer. For a 030-only kernel, - * avoid flushing the whole ATC, we only need to - * flush the user entries. The 68851 does this by - * itself. Avoid a runtime check here. - */ - asm volatile ( -#ifdef CPU_M68030_ONLY - "pmovefd %0,%%crp; " - "pflush #0,#4" -#else - "pmove %0,%%crp" -#endif - : : "m" (crp[0])); - - asm volatile (".chip 68k"); -} - -static inline void switch_mm_0460(struct mm_struct *mm) -{ - asm volatile (".chip 68040"); - - /* flush address translation cache (user entries) */ - asm volatile ("pflushan"); - - /* switch the root pointer */ - asm volatile ("movec %0,%%urp" : : "r" (mm->context)); - - if (CPU_IS_060) { - unsigned long tmp; - - /* clear user entries in the branch cache */ - asm volatile ( - "movec %%cacr,%0; " - "orl %1,%0; " - "movec %0,%%cacr" - : "=d" (tmp): "di" (0x00200000)); - } - - asm volatile (".chip 68k"); -} - -static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) -{ - if (prev != next) { - if (CPU_IS_020_OR_030) - switch_mm_0230(next); - else - switch_mm_0460(next); - } -} - -#define deactivate_mm(tsk,mm) do { } while (0) - -static inline void activate_mm(struct mm_struct *prev_mm, - struct mm_struct *next_mm) -{ - next_mm->context = virt_to_phys(next_mm->pgd); - - if (CPU_IS_020_OR_030) - switch_mm_0230(next_mm); - else - switch_mm_0460(next_mm); -} - -#else /* CONFIG_SUN3 */ -#include -#include - -extern unsigned long get_free_context(struct mm_struct *mm); -extern void clear_context(unsigned long context); - -/* set the context for a new task to unmapped */ -static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm) -{ - mm->context = SUN3_INVALID_CONTEXT; - return 0; -} - -/* find the context given to this process, and if it hasn't already - got one, go get one for it. */ -static inline void get_mmu_context(struct mm_struct *mm) -{ - if(mm->context == SUN3_INVALID_CONTEXT) - mm->context = get_free_context(mm); -} - -/* flush context if allocated... */ -static inline void destroy_context(struct mm_struct *mm) -{ - if(mm->context != SUN3_INVALID_CONTEXT) - clear_context(mm->context); -} - -static inline void activate_context(struct mm_struct *mm) -{ - get_mmu_context(mm); - sun3_put_context(mm->context); -} - -static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) -{ - activate_context(tsk->mm); -} - -#define deactivate_mm(tsk,mm) do { } while (0) - -static inline void activate_mm(struct mm_struct *prev_mm, - struct mm_struct *next_mm) -{ - activate_context(next_mm); -} - -#endif -#endif diff --git a/include/asm-m68k/mmzone.h b/include/asm-m68k/mmzone.h deleted file mode 100644 index e1f1ec7b700..00000000000 --- a/include/asm-m68k/mmzone.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _ASM_M68K_MMZONE_H_ -#define _ASM_M68K_MMZONE_H_ - -extern pg_data_t pg_data_map[]; - -#define NODE_DATA(nid) (&pg_data_map[nid]) -#define NODE_MEM_MAP(nid) (NODE_DATA(nid)->node_mem_map) - -#endif /* _ASM_M68K_MMZONE_H_ */ diff --git a/include/asm-m68k/module.h b/include/asm-m68k/module.h deleted file mode 100644 index 382d20a6fc1..00000000000 --- a/include/asm-m68k/module.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _ASM_M68K_MODULE_H -#define _ASM_M68K_MODULE_H - -struct mod_arch_specific { - struct m68k_fixup_info *fixup_start, *fixup_end; -}; - -#define MODULE_ARCH_INIT { \ - .fixup_start = __start_fixup, \ - .fixup_end = __stop_fixup, \ -} - -#define Elf_Shdr Elf32_Shdr -#define Elf_Sym Elf32_Sym -#define Elf_Ehdr Elf32_Ehdr - - -enum m68k_fixup_type { - m68k_fixup_memoffset, - m68k_fixup_vnode_shift, -}; - -struct m68k_fixup_info { - enum m68k_fixup_type type; - void *addr; -}; - -#define m68k_fixup(type, addr) \ - " .section \".m68k_fixup\",\"aw\"\n" \ - " .long " #type "," #addr "\n" \ - " .previous\n" - -extern struct m68k_fixup_info __start_fixup[], __stop_fixup[]; - -struct module; -extern void module_fixup(struct module *mod, struct m68k_fixup_info *start, - struct m68k_fixup_info *end); - -#endif /* _ASM_M68K_MODULE_H */ diff --git a/include/asm-m68k/motorola_pgalloc.h b/include/asm-m68k/motorola_pgalloc.h deleted file mode 100644 index d08bf6261df..00000000000 --- a/include/asm-m68k/motorola_pgalloc.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef _MOTOROLA_PGALLOC_H -#define _MOTOROLA_PGALLOC_H - -#include -#include - -extern pmd_t *get_pointer_table(void); -extern int free_pointer_table(pmd_t *); - -static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) -{ - pte_t *pte; - - pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); - if (pte) { - __flush_page_to_ram(pte); - flush_tlb_kernel_page(pte); - nocache_page(pte); - } - - return pte; -} - -static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) -{ - cache_page(pte); - free_page((unsigned long) pte); -} - -static inline pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) -{ - struct page *page = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0); - pte_t *pte; - - if(!page) - return NULL; - - pte = kmap(page); - if (pte) { - __flush_page_to_ram(pte); - flush_tlb_kernel_page(pte); - nocache_page(pte); - } - kunmap(pte); - pgtable_page_ctor(page); - return page; -} - -static inline void pte_free(struct mm_struct *mm, pgtable_t page) -{ - pgtable_page_dtor(page); - cache_page(kmap(page)); - kunmap(page); - __free_page(page); -} - -static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t page) -{ - pgtable_page_dtor(page); - cache_page(kmap(page)); - kunmap(page); - __free_page(page); -} - - -static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) -{ - return get_pointer_table(); -} - -static inline int pmd_free(struct mm_struct *mm, pmd_t *pmd) -{ - return free_pointer_table(pmd); -} - -static inline int __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) -{ - return free_pointer_table(pmd); -} - - -static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) -{ - pmd_free(mm, (pmd_t *)pgd); -} - -static inline pgd_t *pgd_alloc(struct mm_struct *mm) -{ - return (pgd_t *)get_pointer_table(); -} - - -static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte) -{ - pmd_set(pmd, pte); -} - -static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t page) -{ - pmd_set(pmd, page_address(page)); -} -#define pmd_pgtable(pmd) pmd_page(pmd) - -static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd) -{ - pgd_set(pgd, pmd); -} - -#endif /* _MOTOROLA_PGALLOC_H */ diff --git a/include/asm-m68k/motorola_pgtable.h b/include/asm-m68k/motorola_pgtable.h deleted file mode 100644 index 8e9a8a754dd..00000000000 --- a/include/asm-m68k/motorola_pgtable.h +++ /dev/null @@ -1,291 +0,0 @@ -#ifndef _MOTOROLA_PGTABLE_H -#define _MOTOROLA_PGTABLE_H - - -/* - * Definitions for MMU descriptors - */ -#define _PAGE_PRESENT 0x001 -#define _PAGE_SHORT 0x002 -#define _PAGE_RONLY 0x004 -#define _PAGE_ACCESSED 0x008 -#define _PAGE_DIRTY 0x010 -#define _PAGE_SUPER 0x080 /* 68040 supervisor only */ -#define _PAGE_GLOBAL040 0x400 /* 68040 global bit, used for kva descs */ -#define _PAGE_NOCACHE030 0x040 /* 68030 no-cache mode */ -#define _PAGE_NOCACHE 0x060 /* 68040 cache mode, non-serialized */ -#define _PAGE_NOCACHE_S 0x040 /* 68040 no-cache mode, serialized */ -#define _PAGE_CACHE040 0x020 /* 68040 cache mode, cachable, copyback */ -#define _PAGE_CACHE040W 0x000 /* 68040 cache mode, cachable, write-through */ - -#define _DESCTYPE_MASK 0x003 - -#define _CACHEMASK040 (~0x060) -#define _TABLE_MASK (0xfffffe00) - -#define _PAGE_TABLE (_PAGE_SHORT) -#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_NOCACHE) - -#define _PAGE_PROTNONE 0x004 -#define _PAGE_FILE 0x008 /* pagecache or swap? */ - -#ifndef __ASSEMBLY__ - -/* This is the cache mode to be used for pages containing page descriptors for - * processors >= '040. It is in pte_mknocache(), and the variable is defined - * and initialized in head.S */ -extern int m68k_pgtable_cachemode; - -/* This is the cache mode for normal pages, for supervisor access on - * processors >= '040. It is used in pte_mkcache(), and the variable is - * defined and initialized in head.S */ - -#if defined(CPU_M68060_ONLY) && defined(CONFIG_060_WRITETHROUGH) -#define m68k_supervisor_cachemode _PAGE_CACHE040W -#elif defined(CPU_M68040_OR_M68060_ONLY) -#define m68k_supervisor_cachemode _PAGE_CACHE040 -#elif defined(CPU_M68020_OR_M68030_ONLY) -#define m68k_supervisor_cachemode 0 -#else -extern int m68k_supervisor_cachemode; -#endif - -#if defined(CPU_M68040_OR_M68060_ONLY) -#define mm_cachebits _PAGE_CACHE040 -#elif defined(CPU_M68020_OR_M68030_ONLY) -#define mm_cachebits 0 -#else -extern unsigned long mm_cachebits; -#endif - -#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED | mm_cachebits) -#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | mm_cachebits) -#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits) -#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits) -#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | mm_cachebits) - -/* Alternate definitions that are compile time constants, for - initializing protection_map. The cachebits are fixed later. */ -#define PAGE_NONE_C __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) -#define PAGE_SHARED_C __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED) -#define PAGE_COPY_C __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED) -#define PAGE_READONLY_C __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED) - -/* - * The m68k can't do page protection for execute, and considers that the same are read. - * Also, write permissions imply read permissions. This is the closest we can get.. - */ -#define __P000 PAGE_NONE_C -#define __P001 PAGE_READONLY_C -#define __P010 PAGE_COPY_C -#define __P011 PAGE_COPY_C -#define __P100 PAGE_READONLY_C -#define __P101 PAGE_READONLY_C -#define __P110 PAGE_COPY_C -#define __P111 PAGE_COPY_C - -#define __S000 PAGE_NONE_C -#define __S001 PAGE_READONLY_C -#define __S010 PAGE_SHARED_C -#define __S011 PAGE_SHARED_C -#define __S100 PAGE_READONLY_C -#define __S101 PAGE_READONLY_C -#define __S110 PAGE_SHARED_C -#define __S111 PAGE_SHARED_C - -/* - * Conversion functions: convert a page and protection to a page entry, - * and a page entry and page directory to the page they refer to. - */ -#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) - -static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) -{ - pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); - return pte; -} - -static inline void pmd_set(pmd_t *pmdp, pte_t *ptep) -{ - unsigned long ptbl = virt_to_phys(ptep) | _PAGE_TABLE | _PAGE_ACCESSED; - unsigned long *ptr = pmdp->pmd; - short i = 16; - while (--i >= 0) { - *ptr++ = ptbl; - ptbl += (sizeof(pte_t)*PTRS_PER_PTE/16); - } -} - -static inline void pgd_set(pgd_t *pgdp, pmd_t *pmdp) -{ - pgd_val(*pgdp) = _PAGE_TABLE | _PAGE_ACCESSED | __pa(pmdp); -} - -#define __pte_page(pte) ((unsigned long)__va(pte_val(pte) & PAGE_MASK)) -#define __pmd_page(pmd) ((unsigned long)__va(pmd_val(pmd) & _TABLE_MASK)) -#define __pgd_page(pgd) ((unsigned long)__va(pgd_val(pgd) & _TABLE_MASK)) - - -#define pte_none(pte) (!pte_val(pte)) -#define pte_present(pte) (pte_val(pte) & (_PAGE_PRESENT | _PAGE_PROTNONE)) -#define pte_clear(mm,addr,ptep) ({ pte_val(*(ptep)) = 0; }) - -#define pte_page(pte) virt_to_page(__va(pte_val(pte))) -#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT) -#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) - -#define pmd_none(pmd) (!pmd_val(pmd)) -#define pmd_bad(pmd) ((pmd_val(pmd) & _DESCTYPE_MASK) != _PAGE_TABLE) -#define pmd_present(pmd) (pmd_val(pmd) & _PAGE_TABLE) -#define pmd_clear(pmdp) ({ \ - unsigned long *__ptr = pmdp->pmd; \ - short __i = 16; \ - while (--__i >= 0) \ - *__ptr++ = 0; \ -}) -#define pmd_page(pmd) virt_to_page(__va(pmd_val(pmd))) - - -#define pgd_none(pgd) (!pgd_val(pgd)) -#define pgd_bad(pgd) ((pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE) -#define pgd_present(pgd) (pgd_val(pgd) & _PAGE_TABLE) -#define pgd_clear(pgdp) ({ pgd_val(*pgdp) = 0; }) -#define pgd_page(pgd) (mem_map + ((unsigned long)(__va(pgd_val(pgd)) - PAGE_OFFSET) >> PAGE_SHIFT)) - -#define pte_ERROR(e) \ - printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) -#define pmd_ERROR(e) \ - printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) -#define pgd_ERROR(e) \ - printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) - - -/* - * The following only work if pte_present() is true. - * Undefined behaviour if not.. - */ -static inline int pte_write(pte_t pte) { return !(pte_val(pte) & _PAGE_RONLY); } -static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } -static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } -static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } -static inline int pte_special(pte_t pte) { return 0; } - -static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) |= _PAGE_RONLY; return pte; } -static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; } -static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } -static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) &= ~_PAGE_RONLY; return pte; } -static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; } -static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; } -static inline pte_t pte_mknocache(pte_t pte) -{ - pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | m68k_pgtable_cachemode; - return pte; -} -static inline pte_t pte_mkcache(pte_t pte) -{ - pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | m68k_supervisor_cachemode; - return pte; -} -static inline pte_t pte_mkspecial(pte_t pte) { return pte; } - -#define PAGE_DIR_OFFSET(tsk,address) pgd_offset((tsk),(address)) - -#define pgd_index(address) ((address) >> PGDIR_SHIFT) - -/* to find an entry in a page-table-directory */ -static inline pgd_t *pgd_offset(const struct mm_struct *mm, - unsigned long address) -{ - return mm->pgd + pgd_index(address); -} - -#define swapper_pg_dir kernel_pg_dir -extern pgd_t kernel_pg_dir[128]; - -static inline pgd_t *pgd_offset_k(unsigned long address) -{ - return kernel_pg_dir + (address >> PGDIR_SHIFT); -} - - -/* Find an entry in the second-level page table.. */ -static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address) -{ - return (pmd_t *)__pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PMD-1)); -} - -/* Find an entry in the third-level page table.. */ -static inline pte_t *pte_offset_kernel(pmd_t *pmdp, unsigned long address) -{ - return (pte_t *)__pmd_page(*pmdp) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); -} - -#define pte_offset_map(pmdp,address) ((pte_t *)__pmd_page(*pmdp) + (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))) -#define pte_offset_map_nested(pmdp, address) pte_offset_map(pmdp, address) -#define pte_unmap(pte) ((void)0) -#define pte_unmap_nested(pte) ((void)0) - -/* - * Allocate and free page tables. The xxx_kernel() versions are - * used to allocate a kernel page table - this turns on ASN bits - * if any. - */ - -/* Prior to calling these routines, the page should have been flushed - * from both the cache and ATC, or the CPU might not notice that the - * cache setting for the page has been changed. -jskov - */ -static inline void nocache_page(void *vaddr) -{ - unsigned long addr = (unsigned long)vaddr; - - if (CPU_IS_040_OR_060) { - pgd_t *dir; - pmd_t *pmdp; - pte_t *ptep; - - dir = pgd_offset_k(addr); - pmdp = pmd_offset(dir, addr); - ptep = pte_offset_kernel(pmdp, addr); - *ptep = pte_mknocache(*ptep); - } -} - -static inline void cache_page(void *vaddr) -{ - unsigned long addr = (unsigned long)vaddr; - - if (CPU_IS_040_OR_060) { - pgd_t *dir; - pmd_t *pmdp; - pte_t *ptep; - - dir = pgd_offset_k(addr); - pmdp = pmd_offset(dir, addr); - ptep = pte_offset_kernel(pmdp, addr); - *ptep = pte_mkcache(*ptep); - } -} - -#define PTE_FILE_MAX_BITS 28 - -static inline unsigned long pte_to_pgoff(pte_t pte) -{ - return pte.pte >> 4; -} - -static inline pte_t pgoff_to_pte(unsigned off) -{ - pte_t pte = { (off << 4) + _PAGE_FILE }; - return pte; -} - -/* Encode and de-code a swap entry (must be !pte_none(e) && !pte_present(e)) */ -#define __swp_type(x) (((x).val >> 4) & 0xff) -#define __swp_offset(x) ((x).val >> 12) -#define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 4) | ((offset) << 12) }) -#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) -#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) - -#endif /* !__ASSEMBLY__ */ -#endif /* _MOTOROLA_PGTABLE_H */ diff --git a/include/asm-m68k/movs.h b/include/asm-m68k/movs.h deleted file mode 100644 index 67dbea36960..00000000000 --- a/include/asm-m68k/movs.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef __MOVS_H__ -#define __MOVS_H__ - -/* -** movs.h -** -** Inline assembly macros to generate movs & related instructions -*/ - -/* Set DFC register value */ - -#define SET_DFC(x) \ - __asm__ __volatile__ (" movec %0,%/dfc" : : "d" (x)); - -/* Get DFC register value */ - -#define GET_DFC(x) \ - __asm__ __volatile__ (" movec %/dfc, %0" : "=d" (x) : ); - -/* Set SFC register value */ - -#define SET_SFC(x) \ - __asm__ __volatile__ (" movec %0,%/sfc" : : "d" (x)); - -/* Get SFC register value */ - -#define GET_SFC(x) \ - __asm__ __volatile__ (" movec %/sfc, %0" : "=d" (x) : ); - -#define SET_VBR(x) \ - __asm__ __volatile__ (" movec %0,%/vbr" : : "r" (x)); - -#define GET_VBR(x) \ - __asm__ __volatile__ (" movec %/vbr, %0" : "=g" (x) : ); - -/* Set a byte using the "movs" instruction */ - -#define SET_CONTROL_BYTE(addr,value) \ - __asm__ __volatile__ (" movsb %0, %1@" : : "d" (value), "a" (addr)); - -/* Get a byte using the "movs" instruction */ - -#define GET_CONTROL_BYTE(addr,value) \ - __asm__ __volatile__ (" movsb %1@, %0" : "=d" (value) : "a" (addr)); - -/* Set a (long)word using the "movs" instruction */ - -#define SET_CONTROL_WORD(addr,value) \ - __asm__ __volatile__ (" movsl %0, %1@" : : "d" (value), "a" (addr)); - -/* Get a (long)word using the "movs" instruction */ - -#define GET_CONTROL_WORD(addr,value) \ - __asm__ __volatile__ (" movsl %1@, %0" : "=d" (value) : "a" (addr)); -#endif diff --git a/include/asm-m68k/msgbuf.h b/include/asm-m68k/msgbuf.h deleted file mode 100644 index 243cb798de8..00000000000 --- a/include/asm-m68k/msgbuf.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef _M68K_MSGBUF_H -#define _M68K_MSGBUF_H - -/* - * The msqid64_ds structure for m68k architecture. - * Note extra padding because this structure is passed back and forth - * between kernel and user space. - * - * Pad space is left for: - * - 64-bit time_t to solve y2038 problem - * - 2 miscellaneous 32-bit values - */ - -struct msqid64_ds { - struct ipc64_perm msg_perm; - __kernel_time_t msg_stime; /* last msgsnd time */ - unsigned long __unused1; - __kernel_time_t msg_rtime; /* last msgrcv time */ - unsigned long __unused2; - __kernel_time_t msg_ctime; /* last change time */ - unsigned long __unused3; - unsigned long msg_cbytes; /* current number of bytes on queue */ - unsigned long msg_qnum; /* number of messages in queue */ - unsigned long msg_qbytes; /* max number of bytes on queue */ - __kernel_pid_t msg_lspid; /* pid of last msgsnd */ - __kernel_pid_t msg_lrpid; /* last receive pid */ - unsigned long __unused4; - unsigned long __unused5; -}; - -#endif /* _M68K_MSGBUF_H */ diff --git a/include/asm-m68k/mutex.h b/include/asm-m68k/mutex.h deleted file mode 100644 index 458c1f7fbc1..00000000000 --- a/include/asm-m68k/mutex.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Pull in the generic implementation for the mutex fastpath. - * - * TODO: implement optimized primitives instead, or leave the generic - * implementation in place, or pick the atomic_xchg() based generic - * implementation. (see asm-generic/mutex-xchg.h for details) - */ - -#include diff --git a/include/asm-m68k/mvme147hw.h b/include/asm-m68k/mvme147hw.h deleted file mode 100644 index b8104310847..00000000000 --- a/include/asm-m68k/mvme147hw.h +++ /dev/null @@ -1,113 +0,0 @@ -#ifndef _MVME147HW_H_ -#define _MVME147HW_H_ - -#include - -typedef struct { - unsigned char - ctrl, - bcd_sec, - bcd_min, - bcd_hr, - bcd_dow, - bcd_dom, - bcd_mth, - bcd_year; -} MK48T02; - -#define RTC_WRITE 0x80 -#define RTC_READ 0x40 -#define RTC_STOP 0x20 - -#define m147_rtc ((MK48T02 * volatile)0xfffe07f8) - - -struct pcc_regs { - volatile u_long dma_tadr; - volatile u_long dma_dadr; - volatile u_long dma_bcr; - volatile u_long dma_hr; - volatile u_short t1_preload; - volatile u_short t1_count; - volatile u_short t2_preload; - volatile u_short t2_count; - volatile u_char t1_int_cntrl; - volatile u_char t1_cntrl; - volatile u_char t2_int_cntrl; - volatile u_char t2_cntrl; - volatile u_char ac_fail; - volatile u_char watchdog; - volatile u_char lpt_intr; - volatile u_char lpt_cntrl; - volatile u_char dma_intr; - volatile u_char dma_cntrl; - volatile u_char bus_error; - volatile u_char dma_status; - volatile u_char abort; - volatile u_char ta_fnctl; - volatile u_char serial_cntrl; - volatile u_char general_cntrl; - volatile u_char lan_cntrl; - volatile u_char general_status; - volatile u_char scsi_interrupt; - volatile u_char slave; - volatile u_char soft1_cntrl; - volatile u_char int_base; - volatile u_char soft2_cntrl; - volatile u_char revision_level; - volatile u_char lpt_data; - volatile u_char lpt_status; - }; - -#define m147_pcc ((struct pcc_regs * volatile)0xfffe1000) - - -#define PCC_INT_ENAB 0x08 - -#define PCC_TIMER_INT_CLR 0x80 -#define PCC_TIMER_PRELOAD 63936l - -#define PCC_LEVEL_ABORT 0x07 -#define PCC_LEVEL_SERIAL 0x04 -#define PCC_LEVEL_ETH 0x04 -#define PCC_LEVEL_TIMER1 0x04 -#define PCC_LEVEL_SCSI_PORT 0x04 -#define PCC_LEVEL_SCSI_DMA 0x04 - -#define PCC_IRQ_AC_FAIL (IRQ_USER+0) -#define PCC_IRQ_BERR (IRQ_USER+1) -#define PCC_IRQ_ABORT (IRQ_USER+2) -/* #define PCC_IRQ_SERIAL (IRQ_USER+3) */ -#define PCC_IRQ_PRINTER (IRQ_USER+7) -#define PCC_IRQ_TIMER1 (IRQ_USER+8) -#define PCC_IRQ_TIMER2 (IRQ_USER+9) -#define PCC_IRQ_SOFTWARE1 (IRQ_USER+10) -#define PCC_IRQ_SOFTWARE2 (IRQ_USER+11) - - -#define M147_SCC_A_ADDR 0xfffe3002 -#define M147_SCC_B_ADDR 0xfffe3000 -#define M147_SCC_PCLK 5000000 - -#define MVME147_IRQ_SCSI_PORT (IRQ_USER+0x45) -#define MVME147_IRQ_SCSI_DMA (IRQ_USER+0x46) - -/* SCC interrupts, for MVME147 */ - -#define MVME147_IRQ_TYPE_PRIO 0 -#define MVME147_IRQ_SCC_BASE (IRQ_USER+32) -#define MVME147_IRQ_SCCB_TX (IRQ_USER+32) -#define MVME147_IRQ_SCCB_STAT (IRQ_USER+34) -#define MVME147_IRQ_SCCB_RX (IRQ_USER+36) -#define MVME147_IRQ_SCCB_SPCOND (IRQ_USER+38) -#define MVME147_IRQ_SCCA_TX (IRQ_USER+40) -#define MVME147_IRQ_SCCA_STAT (IRQ_USER+42) -#define MVME147_IRQ_SCCA_RX (IRQ_USER+44) -#define MVME147_IRQ_SCCA_SPCOND (IRQ_USER+46) - -#define MVME147_LANCE_BASE 0xfffe1800 -#define MVME147_LANCE_IRQ (IRQ_USER+4) - -#define ETHERNET_ADDRESS 0xfffe0778 - -#endif diff --git a/include/asm-m68k/mvme16xhw.h b/include/asm-m68k/mvme16xhw.h deleted file mode 100644 index 6117f56653d..00000000000 --- a/include/asm-m68k/mvme16xhw.h +++ /dev/null @@ -1,111 +0,0 @@ -#ifndef _M68K_MVME16xHW_H_ -#define _M68K_MVME16xHW_H_ - -#include - -/* Board ID data structure - pointer to this retrieved from Bug by head.S */ - -/* Note, bytes 12 and 13 are board no in BCD (0162,0166,0167,0177,etc) */ - -extern long mvme_bdid_ptr; - -typedef struct { - char bdid[4]; - u_char rev, mth, day, yr; - u_short size, reserved; - u_short brdno; - char brdsuffix[2]; - u_long options; - u_short clun, dlun, ctype, dnum; - u_long option2; -} t_bdid, *p_bdid; - - -typedef struct { - u_char ack_icr, - flt_icr, - sel_icr, - pe_icr, - bsy_icr, - spare1, - isr, - cr, - spare2, - spare3, - spare4, - data; -} MVMElp, *MVMElpPtr; - -#define MVME_LPR_BASE 0xfff42030 - -#define mvmelp ((*(volatile MVMElpPtr)(MVME_LPR_BASE))) - -typedef struct { - unsigned char - ctrl, - bcd_sec, - bcd_min, - bcd_hr, - bcd_dow, - bcd_dom, - bcd_mth, - bcd_year; -} MK48T08_t, *MK48T08ptr_t; - -#define RTC_WRITE 0x80 -#define RTC_READ 0x40 -#define RTC_STOP 0x20 - -#define MVME_RTC_BASE 0xfffc1ff8 - -#define MVME_I596_BASE 0xfff46000 - -#define MVME_SCC_A_ADDR 0xfff45005 -#define MVME_SCC_B_ADDR 0xfff45001 -#define MVME_SCC_PCLK 10000000 - -#define MVME162_IRQ_TYPE_PRIO 0 - -#define MVME167_IRQ_PRN (IRQ_USER+20) -#define MVME16x_IRQ_I596 (IRQ_USER+23) -#define MVME16x_IRQ_SCSI (IRQ_USER+21) -#define MVME16x_IRQ_FLY (IRQ_USER+63) -#define MVME167_IRQ_SER_ERR (IRQ_USER+28) -#define MVME167_IRQ_SER_MODEM (IRQ_USER+29) -#define MVME167_IRQ_SER_TX (IRQ_USER+30) -#define MVME167_IRQ_SER_RX (IRQ_USER+31) -#define MVME16x_IRQ_TIMER (IRQ_USER+25) -#define MVME167_IRQ_ABORT (IRQ_USER+46) -#define MVME162_IRQ_ABORT (IRQ_USER+30) - -/* SCC interrupts, for MVME162 */ -#define MVME162_IRQ_SCC_BASE (IRQ_USER+0) -#define MVME162_IRQ_SCCB_TX (IRQ_USER+0) -#define MVME162_IRQ_SCCB_STAT (IRQ_USER+2) -#define MVME162_IRQ_SCCB_RX (IRQ_USER+4) -#define MVME162_IRQ_SCCB_SPCOND (IRQ_USER+6) -#define MVME162_IRQ_SCCA_TX (IRQ_USER+8) -#define MVME162_IRQ_SCCA_STAT (IRQ_USER+10) -#define MVME162_IRQ_SCCA_RX (IRQ_USER+12) -#define MVME162_IRQ_SCCA_SPCOND (IRQ_USER+14) - -/* MVME162 version register */ - -#define MVME162_VERSION_REG 0xfff4202e - -extern unsigned short mvme16x_config; - -/* Lower 8 bits must match the revision register in the MC2 chip */ - -#define MVME16x_CONFIG_SPEED_32 0x0001 -#define MVME16x_CONFIG_NO_VMECHIP2 0x0002 -#define MVME16x_CONFIG_NO_SCSICHIP 0x0004 -#define MVME16x_CONFIG_NO_ETHERNET 0x0008 -#define MVME16x_CONFIG_GOT_FPU 0x0010 - -#define MVME16x_CONFIG_GOT_LP 0x0100 -#define MVME16x_CONFIG_GOT_CD2401 0x0200 -#define MVME16x_CONFIG_GOT_SCCA 0x0400 -#define MVME16x_CONFIG_GOT_SCCB 0x0800 - -#endif diff --git a/include/asm-m68k/nubus.h b/include/asm-m68k/nubus.h deleted file mode 100644 index d6be9976f1a..00000000000 --- a/include/asm-m68k/nubus.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _ASM_M68K_NUBUS_H -#define _ASM_M68K_NUBUS_H - -#include - -#define nubus_readb raw_inb -#define nubus_readw raw_inw -#define nubus_readl raw_inl - -#define nubus_writeb raw_outb -#define nubus_writew raw_outw -#define nubus_writel raw_outl - -#define nubus_memset_io(a,b,c) memset((void *)(a),(b),(c)) -#define nubus_memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) -#define nubus_memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) - -static inline void *nubus_remap_nocache_ser(unsigned long physaddr, - unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); -} - -static inline void *nubus_remap_nocache_nonser(unsigned long physaddr, - unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_NOCACHE_NONSER); -} - -static inline void *nbus_remap_writethrough(unsigned long physaddr, - unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_WRITETHROUGH); -} - -static inline void *nubus_remap_fullcache(unsigned long physaddr, - unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_FULL_CACHING); -} - -#define nubus_unmap iounmap -#define nubus_iounmap iounmap -#define nubus_ioremap nubus_remap_nocache_ser - -#endif /* _ASM_NUBUS_H */ diff --git a/include/asm-m68k/openprom.h b/include/asm-m68k/openprom.h deleted file mode 100644 index d33cdadf78e..00000000000 --- a/include/asm-m68k/openprom.h +++ /dev/null @@ -1,312 +0,0 @@ -#ifndef __SPARC_OPENPROM_H -#define __SPARC_OPENPROM_H - -/* openprom.h: Prom structures and defines for access to the OPENBOOT - * prom routines and data areas. - * - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) - */ - - -/* Empirical constants... */ -#ifdef CONFIG_SUN3 -#define KADB_DEBUGGER_BEGVM 0x0fee0000 /* There is no kadb yet but...*/ -#define LINUX_OPPROM_BEGVM 0x0fef0000 -#define LINUX_OPPROM_ENDVM 0x0ff10000 /* I think this is right - tm */ -#else -#define KADB_DEBUGGER_BEGVM 0xffc00000 /* Where kern debugger is in virt-mem */ -#define LINUX_OPPROM_BEGVM 0xffd00000 -#define LINUX_OPPROM_ENDVM 0xfff00000 -#define LINUX_OPPROM_MAGIC 0x10010407 -#endif - -#ifndef __ASSEMBLY__ -/* V0 prom device operations. */ -struct linux_dev_v0_funcs { - int (*v0_devopen)(char *device_str); - int (*v0_devclose)(int dev_desc); - int (*v0_rdblkdev)(int dev_desc, int num_blks, int blk_st, char *buf); - int (*v0_wrblkdev)(int dev_desc, int num_blks, int blk_st, char *buf); - int (*v0_wrnetdev)(int dev_desc, int num_bytes, char *buf); - int (*v0_rdnetdev)(int dev_desc, int num_bytes, char *buf); - int (*v0_rdchardev)(int dev_desc, int num_bytes, int dummy, char *buf); - int (*v0_wrchardev)(int dev_desc, int num_bytes, int dummy, char *buf); - int (*v0_seekdev)(int dev_desc, long logical_offst, int from); -}; - -/* V2 and later prom device operations. */ -struct linux_dev_v2_funcs { - int (*v2_inst2pkg)(int d); /* Convert ihandle to phandle */ - char * (*v2_dumb_mem_alloc)(char *va, unsigned sz); - void (*v2_dumb_mem_free)(char *va, unsigned sz); - - /* To map devices into virtual I/O space. */ - char * (*v2_dumb_mmap)(char *virta, int which_io, unsigned paddr, unsigned sz); - void (*v2_dumb_munmap)(char *virta, unsigned size); - - int (*v2_dev_open)(char *devpath); - void (*v2_dev_close)(int d); - int (*v2_dev_read)(int d, char *buf, int nbytes); - int (*v2_dev_write)(int d, char *buf, int nbytes); - int (*v2_dev_seek)(int d, int hi, int lo); - - /* Never issued (multistage load support) */ - void (*v2_wheee2)(void); - void (*v2_wheee3)(void); -}; - -struct linux_mlist_v0 { - struct linux_mlist_v0 *theres_more; - char *start_adr; - unsigned num_bytes; -}; - -struct linux_mem_v0 { - struct linux_mlist_v0 **v0_totphys; - struct linux_mlist_v0 **v0_prommap; - struct linux_mlist_v0 **v0_available; /* What we can use */ -}; - -/* Arguments sent to the kernel from the boot prompt. */ -struct linux_arguments_v0 { - char *argv[8]; - char args[100]; - char boot_dev[2]; - int boot_dev_ctrl; - int boot_dev_unit; - int dev_partition; - char *kernel_file_name; - void *aieee1; /* XXX */ -}; - -/* V2 and up boot things. */ -struct linux_bootargs_v2 { - char **bootpath; - char **bootargs; - int *fd_stdin; - int *fd_stdout; -}; - -#if defined(CONFIG_SUN3) || defined(CONFIG_SUN3X) -struct linux_romvec { - char *pv_initsp; - int (*pv_startmon)(void); - - int *diagberr; - - struct linux_arguments_v0 **pv_v0bootargs; - unsigned *pv_sun3mem; - - unsigned char (*pv_getchar)(void); - int (*pv_putchar)(int ch); - int (*pv_nbgetchar)(void); - int (*pv_nbputchar)(int ch); - unsigned char *pv_echo; - unsigned char *pv_insource; - unsigned char *pv_outsink; - - int (*pv_getkey)(void); - int (*pv_initgetkey)(void); - unsigned int *pv_translation; - unsigned char *pv_keybid; - int *pv_screen_x; - int *pv_screen_y; - struct keybuf *pv_keybuf; - - char *pv_monid; - - /* - * Frame buffer output and terminal emulation - */ - - int (*pv_fbwritechar)(char); - int *pv_fbaddr; - char **pv_font; - int (*pv_fbwritestr)(char); - - void (*pv_reboot)(char *bootstr); - - /* - * Line input and parsing - */ - - unsigned char *pv_linebuf; - unsigned char **pv_lineptr; - int *pv_linesize; - int (*pv_getline)(void); - unsigned char (*pv_getnextchar)(void); - unsigned char (*pv_peeknextchar)(void); - int *pv_fbthere; - int (*pv_getnum)(void); - - void (*pv_printf)(const char *fmt, ...); - int (*pv_printhex)(void); - - unsigned char *pv_leds; - int (*pv_setleds)(void); - - /* - * Non-maskable interrupt (nmi) information - */ - - int (*pv_nmiaddr)(void); - int (*pv_abortentry)(void); - int *pv_nmiclock; - - int *pv_fbtype; - - /* - * Assorted other things - */ - - unsigned pv_romvers; - struct globram *pv_globram; - char *pv_kbdzscc; - - int *pv_keyrinit; - unsigned char *pv_keyrtick; - unsigned *pv_memoryavail; - long *pv_resetaddr; - long *pv_resetmap; - - void (*pv_halt)(void); - unsigned char *pv_memorybitmap; - -#ifdef CONFIG_SUN3 - void (*pv_setctxt)(int ctxt, char *va, int pmeg); - void (*pv_vector_cmd)(void); - int dummy1z; - int dummy2z; - int dummy3z; - int dummy4z; -#endif -}; -#else -/* The top level PROM vector. */ -struct linux_romvec { - /* Version numbers. */ - unsigned int pv_magic_cookie; - unsigned int pv_romvers; - unsigned int pv_plugin_revision; - unsigned int pv_printrev; - - /* Version 0 memory descriptors. */ - struct linux_mem_v0 pv_v0mem; - - /* Node operations. */ - struct linux_nodeops *pv_nodeops; - - char **pv_bootstr; - struct linux_dev_v0_funcs pv_v0devops; - - char *pv_stdin; - char *pv_stdout; -#define PROMDEV_KBD 0 /* input from keyboard */ -#define PROMDEV_SCREEN 0 /* output to screen */ -#define PROMDEV_TTYA 1 /* in/out to ttya */ -#define PROMDEV_TTYB 2 /* in/out to ttyb */ - - /* Blocking getchar/putchar. NOT REENTRANT! (grr) */ - int (*pv_getchar)(void); - void (*pv_putchar)(int ch); - - /* Non-blocking variants. */ - int (*pv_nbgetchar)(void); - int (*pv_nbputchar)(int ch); - - void (*pv_putstr)(char *str, int len); - - /* Miscellany. */ - void (*pv_reboot)(char *bootstr); - void (*pv_printf)(__const__ char *fmt, ...); - void (*pv_abort)(void); - __volatile__ int *pv_ticks; - void (*pv_halt)(void); - void (**pv_synchook)(void); - - /* Evaluate a forth string, not different proto for V0 and V2->up. */ - union { - void (*v0_eval)(int len, char *str); - void (*v2_eval)(char *str); - } pv_fortheval; - - struct linux_arguments_v0 **pv_v0bootargs; - - /* Get ether address. */ - unsigned int (*pv_enaddr)(int d, char *enaddr); - - struct linux_bootargs_v2 pv_v2bootargs; - struct linux_dev_v2_funcs pv_v2devops; - - int filler[15]; - - /* This one is sun4c/sun4 only. */ - void (*pv_setctxt)(int ctxt, char *va, int pmeg); - - /* Prom version 3 Multiprocessor routines. This stuff is crazy. - * No joke. Calling these when there is only one cpu probably - * crashes the machine, have to test this. :-) - */ - - /* v3_cpustart() will start the cpu 'whichcpu' in mmu-context - * 'thiscontext' executing at address 'prog_counter' - */ - int (*v3_cpustart)(unsigned int whichcpu, int ctxtbl_ptr, - int thiscontext, char *prog_counter); - - /* v3_cpustop() will cause cpu 'whichcpu' to stop executing - * until a resume cpu call is made. - */ - int (*v3_cpustop)(unsigned int whichcpu); - - /* v3_cpuidle() will idle cpu 'whichcpu' until a stop or - * resume cpu call is made. - */ - int (*v3_cpuidle)(unsigned int whichcpu); - - /* v3_cpuresume() will resume processor 'whichcpu' executing - * starting with whatever 'pc' and 'npc' were left at the - * last 'idle' or 'stop' call. - */ - int (*v3_cpuresume)(unsigned int whichcpu); -}; -#endif - -/* Routines for traversing the prom device tree. */ -struct linux_nodeops { - int (*no_nextnode)(int node); - int (*no_child)(int node); - int (*no_proplen)(int node, char *name); - int (*no_getprop)(int node, char *name, char *val); - int (*no_setprop)(int node, char *name, char *val, int len); - char * (*no_nextprop)(int node, char *name); -}; - -/* More fun PROM structures for device probing. */ -#define PROMREG_MAX 16 -#define PROMVADDR_MAX 16 -#define PROMINTR_MAX 15 - -struct linux_prom_registers { - int which_io; /* is this in OBIO space? */ - char *phys_addr; /* The physical address of this register */ - int reg_size; /* How many bytes does this register take up? */ -}; - -struct linux_prom_irqs { - int pri; /* IRQ priority */ - int vector; /* This is foobar, what does it do? */ -}; - -/* Element of the "ranges" vector */ -struct linux_prom_ranges { - unsigned int ot_child_space; - unsigned int ot_child_base; /* Bus feels this */ - unsigned int ot_parent_space; - unsigned int ot_parent_base; /* CPU looks from here */ - unsigned int or_size; -}; - -#endif /* !(__ASSEMBLY__) */ - -#endif /* !(__SPARC_OPENPROM_H) */ diff --git a/include/asm-m68k/oplib.h b/include/asm-m68k/oplib.h deleted file mode 100644 index f082d03336b..00000000000 --- a/include/asm-m68k/oplib.h +++ /dev/null @@ -1,291 +0,0 @@ -/* - * oplib.h: Describes the interface and available routines in the - * Linux Prom library. - * - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) - */ - -#ifndef __SPARC_OPLIB_H -#define __SPARC_OPLIB_H - -#include - -/* The master romvec pointer... */ -extern struct linux_romvec *romvec; - -/* Enumeration to describe the prom major version we have detected. */ -enum prom_major_version { - PROM_V0, /* Original sun4c V0 prom */ - PROM_V2, /* sun4c and early sun4m V2 prom */ - PROM_V3, /* sun4m and later, up to sun4d/sun4e machines V3 */ - PROM_P1275, /* IEEE compliant ISA based Sun PROM, only sun4u */ -}; - -extern enum prom_major_version prom_vers; -/* Revision, and firmware revision. */ -extern unsigned int prom_rev, prom_prev; - -/* Root node of the prom device tree, this stays constant after - * initialization is complete. - */ -extern int prom_root_node; - -/* Pointer to prom structure containing the device tree traversal - * and usage utility functions. Only prom-lib should use these, - * users use the interface defined by the library only! - */ -extern struct linux_nodeops *prom_nodeops; - -/* The functions... */ - -/* You must call prom_init() before using any of the library services, - * preferably as early as possible. Pass it the romvec pointer. - */ -extern void prom_init(struct linux_romvec *rom_ptr); - -/* Boot argument acquisition, returns the boot command line string. */ -extern char *prom_getbootargs(void); - -/* Device utilities. */ - -/* Map and unmap devices in IO space at virtual addresses. Note that the - * virtual address you pass is a request and the prom may put your mappings - * somewhere else, so check your return value as that is where your new - * mappings really are! - * - * Another note, these are only available on V2 or higher proms! - */ -extern char *prom_mapio(char *virt_hint, int io_space, unsigned int phys_addr, unsigned int num_bytes); -extern void prom_unmapio(char *virt_addr, unsigned int num_bytes); - -/* Device operations. */ - -/* Open the device described by the passed string. Note, that the format - * of the string is different on V0 vs. V2->higher proms. The caller must - * know what he/she is doing! Returns the device descriptor, an int. - */ -extern int prom_devopen(char *device_string); - -/* Close a previously opened device described by the passed integer - * descriptor. - */ -extern int prom_devclose(int device_handle); - -/* Do a seek operation on the device described by the passed integer - * descriptor. - */ -extern void prom_seek(int device_handle, unsigned int seek_hival, - unsigned int seek_lowval); - -/* Machine memory configuration routine. */ - -/* This function returns a V0 format memory descriptor table, it has three - * entries. One for the total amount of physical ram on the machine, one - * for the amount of physical ram available, and one describing the virtual - * areas which are allocated by the prom. So, in a sense the physical - * available is a calculation of the total physical minus the physical mapped - * by the prom with virtual mappings. - * - * These lists are returned pre-sorted, this should make your life easier - * since the prom itself is way too lazy to do such nice things. - */ -extern struct linux_mem_v0 *prom_meminfo(void); - -/* Miscellaneous routines, don't really fit in any category per se. */ - -/* Reboot the machine with the command line passed. */ -extern void prom_reboot(char *boot_command); - -/* Evaluate the forth string passed. */ -extern void prom_feval(char *forth_string); - -/* Enter the prom, with possibility of continuation with the 'go' - * command in newer proms. - */ -extern void prom_cmdline(void); - -/* Enter the prom, with no chance of continuation for the stand-alone - * which calls this. - */ -extern void prom_halt(void); - -/* Set the PROM 'sync' callback function to the passed function pointer. - * When the user gives the 'sync' command at the prom prompt while the - * kernel is still active, the prom will call this routine. - * - * XXX The arguments are different on V0 vs. V2->higher proms, grrr! XXX - */ -typedef void (*sync_func_t)(void); -extern void prom_setsync(sync_func_t func_ptr); - -/* Acquire the IDPROM of the root node in the prom device tree. This - * gets passed a buffer where you would like it stuffed. The return value - * is the format type of this idprom or 0xff on error. - */ -extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size); - -/* Get the prom major version. */ -extern int prom_version(void); - -/* Get the prom plugin revision. */ -extern int prom_getrev(void); - -/* Get the prom firmware revision. */ -extern int prom_getprev(void); - -/* Character operations to/from the console.... */ - -/* Non-blocking get character from console. */ -extern int prom_nbgetchar(void); - -/* Non-blocking put character to console. */ -extern int prom_nbputchar(char character); - -/* Blocking get character from console. */ -extern char prom_getchar(void); - -/* Blocking put character to console. */ -extern void prom_putchar(char character); - -/* Prom's internal printf routine, don't use in kernel/boot code. */ -void prom_printf(char *fmt, ...); - -/* Query for input device type */ - -enum prom_input_device { - PROMDEV_IKBD, /* input from keyboard */ - PROMDEV_ITTYA, /* input from ttya */ - PROMDEV_ITTYB, /* input from ttyb */ - PROMDEV_I_UNK, -}; - -extern enum prom_input_device prom_query_input_device(void); - -/* Query for output device type */ - -enum prom_output_device { - PROMDEV_OSCREEN, /* to screen */ - PROMDEV_OTTYA, /* to ttya */ - PROMDEV_OTTYB, /* to ttyb */ - PROMDEV_O_UNK, -}; - -extern enum prom_output_device prom_query_output_device(void); - -/* Multiprocessor operations... */ - -/* Start the CPU with the given device tree node, context table, and context - * at the passed program counter. - */ -extern int prom_startcpu(int cpunode, struct linux_prom_registers *context_table, - int context, char *program_counter); - -/* Stop the CPU with the passed device tree node. */ -extern int prom_stopcpu(int cpunode); - -/* Idle the CPU with the passed device tree node. */ -extern int prom_idlecpu(int cpunode); - -/* Re-Start the CPU with the passed device tree node. */ -extern int prom_restartcpu(int cpunode); - -/* PROM memory allocation facilities... */ - -/* Allocated at possibly the given virtual address a chunk of the - * indicated size. - */ -extern char *prom_alloc(char *virt_hint, unsigned int size); - -/* Free a previously allocated chunk. */ -extern void prom_free(char *virt_addr, unsigned int size); - -/* Sun4/sun4c specific memory-management startup hook. */ - -/* Map the passed segment in the given context at the passed - * virtual address. - */ -extern void prom_putsegment(int context, unsigned long virt_addr, - int physical_segment); - -/* PROM device tree traversal functions... */ - -/* Get the child node of the given node, or zero if no child exists. */ -extern int prom_getchild(int parent_node); - -/* Get the next sibling node of the given node, or zero if no further - * siblings exist. - */ -extern int prom_getsibling(int node); - -/* Get the length, at the passed node, of the given property type. - * Returns -1 on error (ie. no such property at this node). - */ -extern int prom_getproplen(int thisnode, char *property); - -/* Fetch the requested property using the given buffer. Returns - * the number of bytes the prom put into your buffer or -1 on error. - */ -extern int prom_getproperty(int thisnode, char *property, - char *prop_buffer, int propbuf_size); - -/* Acquire an integer property. */ -extern int prom_getint(int node, char *property); - -/* Acquire an integer property, with a default value. */ -extern int prom_getintdefault(int node, char *property, int defval); - -/* Acquire a boolean property, 0=FALSE 1=TRUE. */ -extern int prom_getbool(int node, char *prop); - -/* Acquire a string property, null string on error. */ -extern void prom_getstring(int node, char *prop, char *buf, int bufsize); - -/* Does the passed node have the given "name"? YES=1 NO=0 */ -extern int prom_nodematch(int thisnode, char *name); - -/* Search all siblings starting at the passed node for "name" matching - * the given string. Returns the node on success, zero on failure. - */ -extern int prom_searchsiblings(int node_start, char *name); - -/* Return the first property type, as a string, for the given node. - * Returns a null string on error. - */ -extern char *prom_firstprop(int node); - -/* Returns the next property after the passed property for the given - * node. Returns null string on failure. - */ -extern char *prom_nextprop(int node, char *prev_property); - -/* Returns 1 if the specified node has given property. */ -extern int prom_node_has_property(int node, char *property); - -/* Set the indicated property at the given node with the passed value. - * Returns the number of bytes of your value that the prom took. - */ -extern int prom_setprop(int node, char *prop_name, char *prop_value, - int value_size); - -extern int prom_pathtoinode(char *path); -extern int prom_inst2pkg(int); - -/* Dorking with Bus ranges... */ - -/* Adjust reg values with the passed ranges. */ -extern void prom_adjust_regs(struct linux_prom_registers *regp, int nregs, - struct linux_prom_ranges *rangep, int nranges); - -/* Adjust child ranges with the passed parent ranges. */ -extern void prom_adjust_ranges(struct linux_prom_ranges *cranges, int ncranges, - struct linux_prom_ranges *pranges, int npranges); - -/* Apply promlib probed OBIO ranges to registers. */ -extern void prom_apply_obio_ranges(struct linux_prom_registers *obioregs, int nregs); - -/* Apply ranges of any prom node (and optionally parent node as well) to registers. */ -extern void prom_apply_generic_ranges(int node, int parent, - struct linux_prom_registers *sbusregs, int nregs); - - -#endif /* !(__SPARC_OPLIB_H) */ diff --git a/include/asm-m68k/page.h b/include/asm-m68k/page.h deleted file mode 100644 index a34b8bad784..00000000000 --- a/include/asm-m68k/page.h +++ /dev/null @@ -1,228 +0,0 @@ -#ifndef _M68K_PAGE_H -#define _M68K_PAGE_H - -#include - -/* PAGE_SHIFT determines the page size */ -#ifndef CONFIG_SUN3 -#define PAGE_SHIFT (12) -#else -#define PAGE_SHIFT (13) -#endif -#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) - -#include - -#if PAGE_SHIFT < 13 -#define THREAD_SIZE (8192) -#else -#define THREAD_SIZE PAGE_SIZE -#endif - -#ifndef __ASSEMBLY__ - -#include - -#include - -#define get_user_page(vaddr) __get_free_page(GFP_KERNEL) -#define free_user_page(page, addr) free_page(addr) - -/* - * We don't need to check for alignment etc. - */ -#ifdef CPU_M68040_OR_M68060_ONLY -static inline void copy_page(void *to, void *from) -{ - unsigned long tmp; - - __asm__ __volatile__("1:\t" - ".chip 68040\n\t" - "move16 %1@+,%0@+\n\t" - "move16 %1@+,%0@+\n\t" - ".chip 68k\n\t" - "dbra %2,1b\n\t" - : "=a" (to), "=a" (from), "=d" (tmp) - : "0" (to), "1" (from) , "2" (PAGE_SIZE / 32 - 1) - ); -} - -static inline void clear_page(void *page) -{ - unsigned long tmp; - unsigned long *sp = page; - - *sp++ = 0; - *sp++ = 0; - *sp++ = 0; - *sp++ = 0; - - __asm__ __volatile__("1:\t" - ".chip 68040\n\t" - "move16 %2@+,%0@+\n\t" - ".chip 68k\n\t" - "subqw #8,%2\n\t" - "subqw #8,%2\n\t" - "dbra %1,1b\n\t" - : "=a" (sp), "=d" (tmp) - : "a" (page), "0" (sp), - "1" ((PAGE_SIZE - 16) / 16 - 1)); -} - -#else -#define clear_page(page) memset((page), 0, PAGE_SIZE) -#define copy_page(to,from) memcpy((to), (from), PAGE_SIZE) -#endif - -#define clear_user_page(addr, vaddr, page) \ - do { clear_page(addr); \ - flush_dcache_page(page); \ - } while (0) -#define copy_user_page(to, from, vaddr, page) \ - do { copy_page(to, from); \ - flush_dcache_page(page); \ - } while (0) - -/* - * These are used to make use of C type-checking.. - */ -typedef struct { unsigned long pte; } pte_t; -typedef struct { unsigned long pmd[16]; } pmd_t; -typedef struct { unsigned long pgd; } pgd_t; -typedef struct { unsigned long pgprot; } pgprot_t; -typedef struct page *pgtable_t; - -#define pte_val(x) ((x).pte) -#define pmd_val(x) ((&x)->pmd[0]) -#define pgd_val(x) ((x).pgd) -#define pgprot_val(x) ((x).pgprot) - -#define __pte(x) ((pte_t) { (x) } ) -#define __pmd(x) ((pmd_t) { (x) } ) -#define __pgd(x) ((pgd_t) { (x) } ) -#define __pgprot(x) ((pgprot_t) { (x) } ) - -#endif /* !__ASSEMBLY__ */ - -#include - -#define PAGE_OFFSET (PAGE_OFFSET_RAW) - -#ifndef __ASSEMBLY__ - -extern unsigned long m68k_memoffset; - -#ifndef CONFIG_SUN3 - -#define WANT_PAGE_VIRTUAL - -static inline unsigned long ___pa(void *vaddr) -{ - unsigned long paddr; - asm ( - "1: addl #0,%0\n" - m68k_fixup(%c2, 1b+2) - : "=r" (paddr) - : "0" (vaddr), "i" (m68k_fixup_memoffset)); - return paddr; -} -#define __pa(vaddr) ___pa((void *)(vaddr)) -static inline void *__va(unsigned long paddr) -{ - void *vaddr; - asm ( - "1: subl #0,%0\n" - m68k_fixup(%c2, 1b+2) - : "=r" (vaddr) - : "0" (paddr), "i" (m68k_fixup_memoffset)); - return vaddr; -} - -#else /* !CONFIG_SUN3 */ -/* This #define is a horrible hack to suppress lots of warnings. --m */ -#define __pa(x) ___pa((unsigned long)(x)) -static inline unsigned long ___pa(unsigned long x) -{ - if(x == 0) - return 0; - if(x >= PAGE_OFFSET) - return (x-PAGE_OFFSET); - else - return (x+0x2000000); -} - -static inline void *__va(unsigned long x) -{ - if(x == 0) - return (void *)0; - - if(x < 0x2000000) - return (void *)(x+PAGE_OFFSET); - else - return (void *)(x-0x2000000); -} -#endif /* CONFIG_SUN3 */ - -/* - * NOTE: virtual isn't really correct, actually it should be the offset into the - * memory node, but we have no highmem, so that works for now. - * TODO: implement (fast) pfn<->pgdat_idx conversion functions, this makes lots - * of the shifts unnecessary. - */ -#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) -#define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT) - -extern int m68k_virt_to_node_shift; - -#ifdef CONFIG_SINGLE_MEMORY_CHUNK -#define __virt_to_node(addr) (&pg_data_map[0]) -#else -extern struct pglist_data *pg_data_table[]; - -static inline __attribute_const__ int __virt_to_node_shift(void) -{ - int shift; - - asm ( - "1: moveq #0,%0\n" - m68k_fixup(%c1, 1b) - : "=d" (shift) - : "i" (m68k_fixup_vnode_shift)); - return shift; -} - -#define __virt_to_node(addr) (pg_data_table[(unsigned long)(addr) >> __virt_to_node_shift()]) -#endif - -#define virt_to_page(addr) ({ \ - pfn_to_page(virt_to_pfn(addr)); \ -}) -#define page_to_virt(page) ({ \ - pfn_to_virt(page_to_pfn(page)); \ -}) - -#define pfn_to_page(pfn) ({ \ - unsigned long __pfn = (pfn); \ - struct pglist_data *pgdat; \ - pgdat = __virt_to_node((unsigned long)pfn_to_virt(__pfn)); \ - pgdat->node_mem_map + (__pfn - pgdat->node_start_pfn); \ -}) -#define page_to_pfn(_page) ({ \ - struct page *__p = (_page); \ - struct pglist_data *pgdat; \ - pgdat = &pg_data_map[page_to_nid(__p)]; \ - ((__p) - pgdat->node_mem_map) + pgdat->node_start_pfn; \ -}) - -#define virt_addr_valid(kaddr) ((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory) -#define pfn_valid(pfn) virt_addr_valid(pfn_to_virt(pfn)) - -#endif /* __ASSEMBLY__ */ - -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - -#include - -#endif /* _M68K_PAGE_H */ diff --git a/include/asm-m68k/page_offset.h b/include/asm-m68k/page_offset.h deleted file mode 100644 index 1cbdb7f30ac..00000000000 --- a/include/asm-m68k/page_offset.h +++ /dev/null @@ -1,8 +0,0 @@ - -/* This handles the memory map.. */ -#ifndef CONFIG_SUN3 -#define PAGE_OFFSET_RAW 0x00000000 -#else -#define PAGE_OFFSET_RAW 0x0E000000 -#endif - diff --git a/include/asm-m68k/param.h b/include/asm-m68k/param.h deleted file mode 100644 index 536a2788835..00000000000 --- a/include/asm-m68k/param.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _M68K_PARAM_H -#define _M68K_PARAM_H - -#ifdef __KERNEL__ -# define HZ CONFIG_HZ /* Internal kernel timer frequency */ -# define USER_HZ 100 /* .. some user interfaces are in "ticks" */ -# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ -#endif - -#ifndef HZ -#define HZ 100 -#endif - -#define EXEC_PAGESIZE 8192 - -#ifndef NOGROUP -#define NOGROUP (-1) -#endif - -#define MAXHOSTNAMELEN 64 /* max length of hostname */ - -#endif /* _M68K_PARAM_H */ diff --git a/include/asm-m68k/parport.h b/include/asm-m68k/parport.h deleted file mode 100644 index 646b1872f73..00000000000 --- a/include/asm-m68k/parport.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * parport.h: platform-specific PC-style parport initialisation - * - * Copyright (C) 1999, 2000 Tim Waugh - * - * This file should only be included by drivers/parport/parport_pc.c. - * - * RZ: for use with Q40 and other ISA machines - */ - -#ifndef _ASM_M68K_PARPORT_H -#define _ASM_M68K_PARPORT_H 1 - -#define insl(port,buf,len) isa_insb(port,buf,(len)<<2) -#define outsl(port,buf,len) isa_outsb(port,buf,(len)<<2) - -/* no dma, or IRQ autoprobing */ -static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma); -static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) -{ - if (! (MACH_IS_Q40)) - return 0; /* count=0 */ - return parport_pc_find_isa_ports (PARPORT_IRQ_NONE, PARPORT_DMA_NONE); -} - -#endif /* !(_ASM_M68K_PARPORT_H) */ diff --git a/include/asm-m68k/pci.h b/include/asm-m68k/pci.h deleted file mode 100644 index 4ad0aea48ab..00000000000 --- a/include/asm-m68k/pci.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _ASM_M68K_PCI_H -#define _ASM_M68K_PCI_H - -#include - -/* The PCI address space does equal the physical memory - * address space. The networking and block device layers use - * this boolean for bounce buffer decisions. - */ -#define PCI_DMA_BUS_IS_PHYS (1) - -#endif /* _ASM_M68K_PCI_H */ diff --git a/include/asm-m68k/percpu.h b/include/asm-m68k/percpu.h deleted file mode 100644 index 0859d048faf..00000000000 --- a/include/asm-m68k/percpu.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_M68K_PERCPU_H -#define __ASM_M68K_PERCPU_H - -#include - -#endif /* __ASM_M68K_PERCPU_H */ diff --git a/include/asm-m68k/pgalloc.h b/include/asm-m68k/pgalloc.h deleted file mode 100644 index 4cb1a57ab76..00000000000 --- a/include/asm-m68k/pgalloc.h +++ /dev/null @@ -1,19 +0,0 @@ - -#ifndef M68K_PGALLOC_H -#define M68K_PGALLOC_H - -#include -#include -#include -#include - - -#ifdef CONFIG_SUN3 -#include -#else -#include -#endif - -extern void m68k_setup_node(int node); - -#endif /* M68K_PGALLOC_H */ diff --git a/include/asm-m68k/pgtable.h b/include/asm-m68k/pgtable.h deleted file mode 100644 index 0b604f0f192..00000000000 --- a/include/asm-m68k/pgtable.h +++ /dev/null @@ -1,166 +0,0 @@ -#ifndef _M68K_PGTABLE_H -#define _M68K_PGTABLE_H - -#include - -#include - -#ifndef __ASSEMBLY__ -#include -#include -#include - -/* - * This file contains the functions and defines necessary to modify and use - * the m68k page table tree. - */ - -#include - -/* Certain architectures need to do special things when pte's - * within a page table are directly modified. Thus, the following - * hook is made available. - */ -#define set_pte(pteptr, pteval) \ - do{ \ - *(pteptr) = (pteval); \ - } while(0) -#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) - - -/* PMD_SHIFT determines the size of the area a second-level page table can map */ -#ifdef CONFIG_SUN3 -#define PMD_SHIFT 17 -#else -#define PMD_SHIFT 22 -#endif -#define PMD_SIZE (1UL << PMD_SHIFT) -#define PMD_MASK (~(PMD_SIZE-1)) - -/* PGDIR_SHIFT determines what a third-level page table entry can map */ -#ifdef CONFIG_SUN3 -#define PGDIR_SHIFT 17 -#else -#define PGDIR_SHIFT 25 -#endif -#define PGDIR_SIZE (1UL << PGDIR_SHIFT) -#define PGDIR_MASK (~(PGDIR_SIZE-1)) - -/* - * entries per page directory level: the m68k is configured as three-level, - * so we do have PMD level physically. - */ -#ifdef CONFIG_SUN3 -#define PTRS_PER_PTE 16 -#define PTRS_PER_PMD 1 -#define PTRS_PER_PGD 2048 -#else -#define PTRS_PER_PTE 1024 -#define PTRS_PER_PMD 8 -#define PTRS_PER_PGD 128 -#endif -#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) -#define FIRST_USER_ADDRESS 0 - -/* Virtual address region for use by kernel_map() */ -#ifdef CONFIG_SUN3 -#define KMAP_START 0x0DC00000 -#define KMAP_END 0x0E000000 -#else -#define KMAP_START 0xd0000000 -#define KMAP_END 0xf0000000 -#endif - -#ifndef CONFIG_SUN3 -/* Just any arbitrary offset to the start of the vmalloc VM area: the - * current 8MB value just means that there will be a 8MB "hole" after the - * physical memory until the kernel virtual memory starts. That means that - * any out-of-bounds memory accesses will hopefully be caught. - * The vmalloc() routines leaves a hole of 4kB between each vmalloced - * area for the same reason. ;) - */ -#define VMALLOC_OFFSET (8*1024*1024) -#define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) -#define VMALLOC_END KMAP_START -#else -extern unsigned long vmalloc_end; -#define VMALLOC_START 0x0f800000 -#define VMALLOC_END vmalloc_end -#endif /* CONFIG_SUN3 */ - -/* zero page used for uninitialized stuff */ -extern void *empty_zero_page; - -/* - * ZERO_PAGE is a global shared page that is always zero: used - * for zero-mapped memory areas etc.. - */ -#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) - -/* number of bits that fit into a memory pointer */ -#define BITS_PER_PTR (8*sizeof(unsigned long)) - -/* to align the pointer to a pointer address */ -#define PTR_MASK (~(sizeof(void*)-1)) - -/* sizeof(void*)==1< -#else -#include -#endif - -#ifndef __ASSEMBLY__ -#include - -/* - * Macro to mark a page protection value as "uncacheable". - */ -#ifdef SUN3_PAGE_NOCACHE -# define __SUN3_PAGE_NOCACHE SUN3_PAGE_NOCACHE -#else -# define __SUN3_PAGE_NOCACHE 0 -#endif -#define pgprot_noncached(prot) \ - (MMU_IS_SUN3 \ - ? (__pgprot(pgprot_val(prot) | __SUN3_PAGE_NOCACHE)) \ - : ((MMU_IS_851 || MMU_IS_030) \ - ? (__pgprot(pgprot_val(prot) | _PAGE_NOCACHE030)) \ - : (MMU_IS_040 || MMU_IS_060) \ - ? (__pgprot((pgprot_val(prot) & _CACHEMASK040) | _PAGE_NOCACHE_S)) \ - : (prot))) - -#endif /* !__ASSEMBLY__ */ - -/* - * No page table caches to initialise - */ -#define pgtable_cache_init() do { } while (0) - -#define check_pgt_cache() do { } while (0) - -#endif /* _M68K_PGTABLE_H */ diff --git a/include/asm-m68k/poll.h b/include/asm-m68k/poll.h deleted file mode 100644 index f080fcdb61b..00000000000 --- a/include/asm-m68k/poll.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __m68k_POLL_H -#define __m68k_POLL_H - -#define POLLWRNORM POLLOUT -#define POLLWRBAND 256 - -#include - -#endif diff --git a/include/asm-m68k/posix_types.h b/include/asm-m68k/posix_types.h deleted file mode 100644 index 63cdcc142d9..00000000000 --- a/include/asm-m68k/posix_types.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef __ARCH_M68K_POSIX_TYPES_H -#define __ARCH_M68K_POSIX_TYPES_H - -/* - * This file is generally used by user-level software, so you need to - * be a little careful about namespace pollution etc. Also, we cannot - * assume GCC is being used. - */ - -typedef unsigned long __kernel_ino_t; -typedef unsigned short __kernel_mode_t; -typedef unsigned short __kernel_nlink_t; -typedef long __kernel_off_t; -typedef int __kernel_pid_t; -typedef unsigned short __kernel_ipc_pid_t; -typedef unsigned short __kernel_uid_t; -typedef unsigned short __kernel_gid_t; -typedef unsigned int __kernel_size_t; -typedef int __kernel_ssize_t; -typedef int __kernel_ptrdiff_t; -typedef long __kernel_time_t; -typedef long __kernel_suseconds_t; -typedef long __kernel_clock_t; -typedef int __kernel_timer_t; -typedef int __kernel_clockid_t; -typedef int __kernel_daddr_t; -typedef char * __kernel_caddr_t; -typedef unsigned short __kernel_uid16_t; -typedef unsigned short __kernel_gid16_t; -typedef unsigned int __kernel_uid32_t; -typedef unsigned int __kernel_gid32_t; - -typedef unsigned short __kernel_old_uid_t; -typedef unsigned short __kernel_old_gid_t; -typedef unsigned short __kernel_old_dev_t; - -#ifdef __GNUC__ -typedef long long __kernel_loff_t; -#endif - -typedef struct { - int val[2]; -} __kernel_fsid_t; - -#if defined(__KERNEL__) - -#undef __FD_SET -#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) - -#undef __FD_CLR -#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) - -#undef __FD_ISSET -#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) - -#undef __FD_ZERO -#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp))) - -#endif /* defined(__KERNEL__) */ - -#endif diff --git a/include/asm-m68k/processor.h b/include/asm-m68k/processor.h deleted file mode 100644 index 1f61ef53f0e..00000000000 --- a/include/asm-m68k/processor.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * include/asm-m68k/processor.h - * - * Copyright (C) 1995 Hamish Macdonald - */ - -#ifndef __ASM_M68K_PROCESSOR_H -#define __ASM_M68K_PROCESSOR_H - -/* - * Default implementation of macro that returns current - * instruction pointer ("program counter"). - */ -#define current_text_addr() ({ __label__ _l; _l: &&_l;}) - -#include -#include -#include -#include - -static inline unsigned long rdusp(void) -{ - unsigned long usp; - - __asm__ __volatile__("move %/usp,%0" : "=a" (usp)); - return usp; -} - -static inline void wrusp(unsigned long usp) -{ - __asm__ __volatile__("move %0,%/usp" : : "a" (usp)); -} - -/* - * User space process size: 3.75GB. This is hardcoded into a few places, - * so don't change it unless you know what you are doing. - */ -#ifndef CONFIG_SUN3 -#define TASK_SIZE (0xF0000000UL) -#else -#define TASK_SIZE (0x0E000000UL) -#endif - -#ifdef __KERNEL__ -#define STACK_TOP TASK_SIZE -#define STACK_TOP_MAX STACK_TOP -#endif - -/* This decides where the kernel will search for a free chunk of vm - * space during mmap's. - */ -#ifndef CONFIG_SUN3 -#define TASK_UNMAPPED_BASE 0xC0000000UL -#else -#define TASK_UNMAPPED_BASE 0x0A000000UL -#endif -#define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr) - -struct thread_struct { - unsigned long ksp; /* kernel stack pointer */ - unsigned long usp; /* user stack pointer */ - unsigned short sr; /* saved status register */ - unsigned short fs; /* saved fs (sfc, dfc) */ - unsigned long crp[2]; /* cpu root pointer */ - unsigned long esp0; /* points to SR of stack frame */ - unsigned long faddr; /* info about last fault */ - int signo, code; - unsigned long fp[8*3]; - unsigned long fpcntl[3]; /* fp control regs */ - unsigned char fpstate[FPSTATESIZE]; /* floating point state */ - struct thread_info info; -}; - -#define INIT_THREAD { \ - .ksp = sizeof(init_stack) + (unsigned long) init_stack, \ - .sr = PS_S, \ - .fs = __KERNEL_DS, \ - .info = INIT_THREAD_INFO(init_task), \ -} - -/* - * Do necessary setup to start up a newly executed thread. - */ -static inline void start_thread(struct pt_regs * regs, unsigned long pc, - unsigned long usp) -{ - /* reads from user space */ - set_fs(USER_DS); - - regs->pc = pc; - regs->sr &= ~0x2000; - wrusp(usp); -} - -/* Forward declaration, a strange C thing */ -struct task_struct; - -/* Free all resources held by a thread. */ -static inline void release_thread(struct task_struct *dead_task) -{ -} - -/* Prepare to copy thread state - unlazy all lazy status */ -#define prepare_to_copy(tsk) do { } while (0) - -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); - -/* - * Free current thread data structures etc.. - */ -static inline void exit_thread(void) -{ -} - -extern unsigned long thread_saved_pc(struct task_struct *tsk); - -unsigned long get_wchan(struct task_struct *p); - -#define KSTK_EIP(tsk) \ - ({ \ - unsigned long eip = 0; \ - if ((tsk)->thread.esp0 > PAGE_SIZE && \ - (virt_addr_valid((tsk)->thread.esp0))) \ - eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \ - eip; }) -#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) - -#define cpu_relax() barrier() - -#endif diff --git a/include/asm-m68k/ptrace.h b/include/asm-m68k/ptrace.h deleted file mode 100644 index 57e763d79bf..00000000000 --- a/include/asm-m68k/ptrace.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef _M68K_PTRACE_H -#define _M68K_PTRACE_H - -#define PT_D1 0 -#define PT_D2 1 -#define PT_D3 2 -#define PT_D4 3 -#define PT_D5 4 -#define PT_D6 5 -#define PT_D7 6 -#define PT_A0 7 -#define PT_A1 8 -#define PT_A2 9 -#define PT_A3 10 -#define PT_A4 11 -#define PT_A5 12 -#define PT_A6 13 -#define PT_D0 14 -#define PT_USP 15 -#define PT_ORIG_D0 16 -#define PT_SR 17 -#define PT_PC 18 - -#ifndef __ASSEMBLY__ - -/* this struct defines the way the registers are stored on the - stack during a system call. */ - -struct pt_regs { - long d1; - long d2; - long d3; - long d4; - long d5; - long a0; - long a1; - long a2; - long d0; - long orig_d0; - long stkadj; - unsigned short sr; - unsigned long pc; - unsigned format : 4; /* frame format specifier */ - unsigned vector : 12; /* vector offset */ -}; - -/* - * This is the extended stack used by signal handlers and the context - * switcher: it's pushed after the normal "struct pt_regs". - */ -struct switch_stack { - unsigned long d6; - unsigned long d7; - unsigned long a3; - unsigned long a4; - unsigned long a5; - unsigned long a6; - unsigned long retpc; -}; - -/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ -#define PTRACE_GETREGS 12 -#define PTRACE_SETREGS 13 -#define PTRACE_GETFPREGS 14 -#define PTRACE_SETFPREGS 15 - -#ifdef __KERNEL__ - -#ifndef PS_S -#define PS_S (0x2000) -#define PS_M (0x1000) -#endif - -#define user_mode(regs) (!((regs)->sr & PS_S)) -#define instruction_pointer(regs) ((regs)->pc) -#define profile_pc(regs) instruction_pointer(regs) -extern void show_regs(struct pt_regs *); -#endif /* __KERNEL__ */ -#endif /* __ASSEMBLY__ */ -#endif /* _M68K_PTRACE_H */ diff --git a/include/asm-m68k/q40_master.h b/include/asm-m68k/q40_master.h deleted file mode 100644 index 3907a09d4fc..00000000000 --- a/include/asm-m68k/q40_master.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Q40 master Chip Control - * RTC stuff merged for compactnes.. -*/ - -#ifndef _Q40_MASTER_H -#define _Q40_MASTER_H - -#include - - -#define q40_master_addr 0xff000000 - -#define IIRQ_REG 0x0 /* internal IRQ reg */ -#define EIRQ_REG 0x4 /* external ... */ -#define KEYCODE_REG 0x1c /* value of received scancode */ -#define DISPLAY_CONTROL_REG 0x18 -#define FRAME_CLEAR_REG 0x24 -#define LED_REG 0x30 - -#define Q40_LED_ON() master_outb(1,LED_REG) -#define Q40_LED_OFF() master_outb(0,LED_REG) - -#define INTERRUPT_REG IIRQ_REG /* "native" ints */ -#define KEY_IRQ_ENABLE_REG 0x08 /**/ -#define KEYBOARD_UNLOCK_REG 0x20 /* clear kb int */ - -#define SAMPLE_ENABLE_REG 0x14 /* generate SAMPLE ints */ -#define SAMPLE_RATE_REG 0x2c -#define SAMPLE_CLEAR_REG 0x28 -#define SAMPLE_LOW 0x00 -#define SAMPLE_HIGH 0x01 - -#define FRAME_RATE_REG 0x38 /* generate FRAME ints at 200 HZ rate */ - -#if 0 -#define SER_ENABLE_REG 0x0c /* allow serial ints to be generated */ -#endif -#define EXT_ENABLE_REG 0x10 /* ... rest of the ISA ints ... */ - - -#define master_inb(_reg_) in_8((unsigned char *)q40_master_addr+_reg_) -#define master_outb(_b_,_reg_) out_8((unsigned char *)q40_master_addr+_reg_,_b_) - -/* RTC defines */ - -#define Q40_RTC_BASE (0xff021ffc) - -#define Q40_RTC_YEAR (*(volatile unsigned char *)(Q40_RTC_BASE+0)) -#define Q40_RTC_MNTH (*(volatile unsigned char *)(Q40_RTC_BASE-4)) -#define Q40_RTC_DATE (*(volatile unsigned char *)(Q40_RTC_BASE-8)) -#define Q40_RTC_DOW (*(volatile unsigned char *)(Q40_RTC_BASE-12)) -#define Q40_RTC_HOUR (*(volatile unsigned char *)(Q40_RTC_BASE-16)) -#define Q40_RTC_MINS (*(volatile unsigned char *)(Q40_RTC_BASE-20)) -#define Q40_RTC_SECS (*(volatile unsigned char *)(Q40_RTC_BASE-24)) -#define Q40_RTC_CTRL (*(volatile unsigned char *)(Q40_RTC_BASE-28)) - -/* some control bits */ -#define Q40_RTC_READ 64 /* prepare for reading */ -#define Q40_RTC_WRITE 128 - -/* define some Q40 specific ints */ -#include "q40ints.h" - -/* misc defs */ -#define DAC_LEFT ((unsigned char *)0xff008000) -#define DAC_RIGHT ((unsigned char *)0xff008004) - -#endif /* _Q40_MASTER_H */ diff --git a/include/asm-m68k/q40ints.h b/include/asm-m68k/q40ints.h deleted file mode 100644 index 3d970afb708..00000000000 --- a/include/asm-m68k/q40ints.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * contains some Q40 related interrupt definitions - */ - -#define Q40_IRQ_MAX (34) - -#define Q40_IRQ_SAMPLE (34) -#define Q40_IRQ_KEYBOARD (32) -#define Q40_IRQ_FRAME (33) - - -/* masks for interrupt regiosters*/ -/* internal, IIRQ_REG */ -#define Q40_IRQ_KEYB_MASK (2) -#define Q40_IRQ_SER_MASK (1<<2) -#define Q40_IRQ_FRAME_MASK (1<<3) -#define Q40_IRQ_EXT_MASK (1<<4) /* is a EIRQ */ -/* eirq, EIRQ_REG */ -#define Q40_IRQ3_MASK (1) -#define Q40_IRQ4_MASK (1<<1) -#define Q40_IRQ5_MASK (1<<2) -#define Q40_IRQ6_MASK (1<<3) -#define Q40_IRQ7_MASK (1<<4) -#define Q40_IRQ10_MASK (1<<5) -#define Q40_IRQ14_MASK (1<<6) -#define Q40_IRQ15_MASK (1<<7) - -extern unsigned long q40_probe_irq_on (void); -extern int q40_probe_irq_off (unsigned long irqs); diff --git a/include/asm-m68k/raw_io.h b/include/asm-m68k/raw_io.h deleted file mode 100644 index d9eb9834ccc..00000000000 --- a/include/asm-m68k/raw_io.h +++ /dev/null @@ -1,347 +0,0 @@ -/* - * linux/include/asm-m68k/raw_io.h - * - * 10/20/00 RZ: - created from bits of io.h and ide.h to cleanup namespace - * - */ - -#ifndef _RAW_IO_H -#define _RAW_IO_H - -#ifdef __KERNEL__ - -#include - - -/* Values for nocacheflag and cmode */ -#define IOMAP_FULL_CACHING 0 -#define IOMAP_NOCACHE_SER 1 -#define IOMAP_NOCACHE_NONSER 2 -#define IOMAP_WRITETHROUGH 3 - -extern void iounmap(void __iomem *addr); - -extern void __iomem *__ioremap(unsigned long physaddr, unsigned long size, - int cacheflag); -extern void __iounmap(void *addr, unsigned long size); - - -/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates - * two accesses to memory, which may be undesirable for some devices. - */ -#define in_8(addr) \ - ({ u8 __v = (*(__force volatile u8 *) (addr)); __v; }) -#define in_be16(addr) \ - ({ u16 __v = (*(__force volatile u16 *) (addr)); __v; }) -#define in_be32(addr) \ - ({ u32 __v = (*(__force volatile u32 *) (addr)); __v; }) -#define in_le16(addr) \ - ({ u16 __v = le16_to_cpu(*(__force volatile __le16 *) (addr)); __v; }) -#define in_le32(addr) \ - ({ u32 __v = le32_to_cpu(*(__force volatile __le32 *) (addr)); __v; }) - -#define out_8(addr,b) (void)((*(__force volatile u8 *) (addr)) = (b)) -#define out_be16(addr,w) (void)((*(__force volatile u16 *) (addr)) = (w)) -#define out_be32(addr,l) (void)((*(__force volatile u32 *) (addr)) = (l)) -#define out_le16(addr,w) (void)((*(__force volatile __le16 *) (addr)) = cpu_to_le16(w)) -#define out_le32(addr,l) (void)((*(__force volatile __le32 *) (addr)) = cpu_to_le32(l)) - -#define raw_inb in_8 -#define raw_inw in_be16 -#define raw_inl in_be32 -#define __raw_readb in_8 -#define __raw_readw in_be16 -#define __raw_readl in_be32 - -#define raw_outb(val,port) out_8((port),(val)) -#define raw_outw(val,port) out_be16((port),(val)) -#define raw_outl(val,port) out_be32((port),(val)) -#define __raw_writeb(val,addr) out_8((addr),(val)) -#define __raw_writew(val,addr) out_be16((addr),(val)) -#define __raw_writel(val,addr) out_be32((addr),(val)) - -static inline void raw_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len) -{ - unsigned int i; - - for (i = 0; i < len; i++) - *buf++ = in_8(port); -} - -static inline void raw_outsb(volatile u8 __iomem *port, const u8 *buf, - unsigned int len) -{ - unsigned int i; - - for (i = 0; i < len; i++) - out_8(port, *buf++); -} - -static inline void raw_insw(volatile u16 __iomem *port, u16 *buf, unsigned int nr) -{ - unsigned int tmp; - - if (nr & 15) { - tmp = (nr & 15) - 1; - asm volatile ( - "1: movew %2@,%0@+; dbra %1,1b" - : "=a" (buf), "=d" (tmp) - : "a" (port), "0" (buf), - "1" (tmp)); - } - if (nr >> 4) { - tmp = (nr >> 4) - 1; - asm volatile ( - "1: " - "movew %2@,%0@+; " - "movew %2@,%0@+; " - "movew %2@,%0@+; " - "movew %2@,%0@+; " - "movew %2@,%0@+; " - "movew %2@,%0@+; " - "movew %2@,%0@+; " - "movew %2@,%0@+; " - "movew %2@,%0@+; " - "movew %2@,%0@+; " - "movew %2@,%0@+; " - "movew %2@,%0@+; " - "movew %2@,%0@+; " - "movew %2@,%0@+; " - "movew %2@,%0@+; " - "movew %2@,%0@+; " - "dbra %1,1b" - : "=a" (buf), "=d" (tmp) - : "a" (port), "0" (buf), - "1" (tmp)); - } -} - -static inline void raw_outsw(volatile u16 __iomem *port, const u16 *buf, - unsigned int nr) -{ - unsigned int tmp; - - if (nr & 15) { - tmp = (nr & 15) - 1; - asm volatile ( - "1: movew %0@+,%2@; dbra %1,1b" - : "=a" (buf), "=d" (tmp) - : "a" (port), "0" (buf), - "1" (tmp)); - } - if (nr >> 4) { - tmp = (nr >> 4) - 1; - asm volatile ( - "1: " - "movew %0@+,%2@; " - "movew %0@+,%2@; " - "movew %0@+,%2@; " - "movew %0@+,%2@; " - "movew %0@+,%2@; " - "movew %0@+,%2@; " - "movew %0@+,%2@; " - "movew %0@+,%2@; " - "movew %0@+,%2@; " - "movew %0@+,%2@; " - "movew %0@+,%2@; " - "movew %0@+,%2@; " - "movew %0@+,%2@; " - "movew %0@+,%2@; " - "movew %0@+,%2@; " - "movew %0@+,%2@; " - "dbra %1,1b" - : "=a" (buf), "=d" (tmp) - : "a" (port), "0" (buf), - "1" (tmp)); - } -} - -static inline void raw_insl(volatile u32 __iomem *port, u32 *buf, unsigned int nr) -{ - unsigned int tmp; - - if (nr & 15) { - tmp = (nr & 15) - 1; - asm volatile ( - "1: movel %2@,%0@+; dbra %1,1b" - : "=a" (buf), "=d" (tmp) - : "a" (port), "0" (buf), - "1" (tmp)); - } - if (nr >> 4) { - tmp = (nr >> 4) - 1; - asm volatile ( - "1: " - "movel %2@,%0@+; " - "movel %2@,%0@+; " - "movel %2@,%0@+; " - "movel %2@,%0@+; " - "movel %2@,%0@+; " - "movel %2@,%0@+; " - "movel %2@,%0@+; " - "movel %2@,%0@+; " - "movel %2@,%0@+; " - "movel %2@,%0@+; " - "movel %2@,%0@+; " - "movel %2@,%0@+; " - "movel %2@,%0@+; " - "movel %2@,%0@+; " - "movel %2@,%0@+; " - "movel %2@,%0@+; " - "dbra %1,1b" - : "=a" (buf), "=d" (tmp) - : "a" (port), "0" (buf), - "1" (tmp)); - } -} - -static inline void raw_outsl(volatile u32 __iomem *port, const u32 *buf, - unsigned int nr) -{ - unsigned int tmp; - - if (nr & 15) { - tmp = (nr & 15) - 1; - asm volatile ( - "1: movel %0@+,%2@; dbra %1,1b" - : "=a" (buf), "=d" (tmp) - : "a" (port), "0" (buf), - "1" (tmp)); - } - if (nr >> 4) { - tmp = (nr >> 4) - 1; - asm volatile ( - "1: " - "movel %0@+,%2@; " - "movel %0@+,%2@; " - "movel %0@+,%2@; " - "movel %0@+,%2@; " - "movel %0@+,%2@; " - "movel %0@+,%2@; " - "movel %0@+,%2@; " - "movel %0@+,%2@; " - "movel %0@+,%2@; " - "movel %0@+,%2@; " - "movel %0@+,%2@; " - "movel %0@+,%2@; " - "movel %0@+,%2@; " - "movel %0@+,%2@; " - "movel %0@+,%2@; " - "movel %0@+,%2@; " - "dbra %1,1b" - : "=a" (buf), "=d" (tmp) - : "a" (port), "0" (buf), - "1" (tmp)); - } -} - - -static inline void raw_insw_swapw(volatile u16 __iomem *port, u16 *buf, - unsigned int nr) -{ - if ((nr) % 8) - __asm__ __volatile__ - ("\tmovel %0,%/a0\n\t" - "movel %1,%/a1\n\t" - "movel %2,%/d6\n\t" - "subql #1,%/d6\n" - "1:\tmovew %/a0@,%/d0\n\t" - "rolw #8,%/d0\n\t" - "movew %/d0,%/a1@+\n\t" - "dbra %/d6,1b" - : - : "g" (port), "g" (buf), "g" (nr) - : "d0", "a0", "a1", "d6"); - else - __asm__ __volatile__ - ("movel %0,%/a0\n\t" - "movel %1,%/a1\n\t" - "movel %2,%/d6\n\t" - "lsrl #3,%/d6\n\t" - "subql #1,%/d6\n" - "1:\tmovew %/a0@,%/d0\n\t" - "rolw #8,%/d0\n\t" - "movew %/d0,%/a1@+\n\t" - "movew %/a0@,%/d0\n\t" - "rolw #8,%/d0\n\t" - "movew %/d0,%/a1@+\n\t" - "movew %/a0@,%/d0\n\t" - "rolw #8,%/d0\n\t" - "movew %/d0,%/a1@+\n\t" - "movew %/a0@,%/d0\n\t" - "rolw #8,%/d0\n\t" - "movew %/d0,%/a1@+\n\t" - "movew %/a0@,%/d0\n\t" - "rolw #8,%/d0\n\t" - "movew %/d0,%/a1@+\n\t" - "movew %/a0@,%/d0\n\t" - "rolw #8,%/d0\n\t" - "movew %/d0,%/a1@+\n\t" - "movew %/a0@,%/d0\n\t" - "rolw #8,%/d0\n\t" - "movew %/d0,%/a1@+\n\t" - "movew %/a0@,%/d0\n\t" - "rolw #8,%/d0\n\t" - "movew %/d0,%/a1@+\n\t" - "dbra %/d6,1b" - : - : "g" (port), "g" (buf), "g" (nr) - : "d0", "a0", "a1", "d6"); -} - -static inline void raw_outsw_swapw(volatile u16 __iomem *port, const u16 *buf, - unsigned int nr) -{ - if ((nr) % 8) - __asm__ __volatile__ - ("movel %0,%/a0\n\t" - "movel %1,%/a1\n\t" - "movel %2,%/d6\n\t" - "subql #1,%/d6\n" - "1:\tmovew %/a1@+,%/d0\n\t" - "rolw #8,%/d0\n\t" - "movew %/d0,%/a0@\n\t" - "dbra %/d6,1b" - : - : "g" (port), "g" (buf), "g" (nr) - : "d0", "a0", "a1", "d6"); - else - __asm__ __volatile__ - ("movel %0,%/a0\n\t" - "movel %1,%/a1\n\t" - "movel %2,%/d6\n\t" - "lsrl #3,%/d6\n\t" - "subql #1,%/d6\n" - "1:\tmovew %/a1@+,%/d0\n\t" - "rolw #8,%/d0\n\t" - "movew %/d0,%/a0@\n\t" - "movew %/a1@+,%/d0\n\t" - "rolw #8,%/d0\n\t" - "movew %/d0,%/a0@\n\t" - "movew %/a1@+,%/d0\n\t" - "rolw #8,%/d0\n\t" - "movew %/d0,%/a0@\n\t" - "movew %/a1@+,%/d0\n\t" - "rolw #8,%/d0\n\t" - "movew %/d0,%/a0@\n\t" - "movew %/a1@+,%/d0\n\t" - "rolw #8,%/d0\n\t" - "movew %/d0,%/a0@\n\t" - "movew %/a1@+,%/d0\n\t" - "rolw #8,%/d0\n\t" - "movew %/d0,%/a0@\n\t" - "movew %/a1@+,%/d0\n\t" - "rolw #8,%/d0\n\t" - "movew %/d0,%/a0@\n\t" - "movew %/a1@+,%/d0\n\t" - "rolw #8,%/d0\n\t" - "movew %/d0,%/a0@\n\t" - "dbra %/d6,1b" - : - : "g" (port), "g" (buf), "g" (nr) - : "d0", "a0", "a1", "d6"); -} - -#endif /* __KERNEL__ */ - -#endif /* _RAW_IO_H */ diff --git a/include/asm-m68k/resource.h b/include/asm-m68k/resource.h deleted file mode 100644 index e7d35019f33..00000000000 --- a/include/asm-m68k/resource.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _M68K_RESOURCE_H -#define _M68K_RESOURCE_H - -#include - -#endif /* _M68K_RESOURCE_H */ diff --git a/include/asm-m68k/rtc.h b/include/asm-m68k/rtc.h deleted file mode 100644 index 5d3e0385984..00000000000 --- a/include/asm-m68k/rtc.h +++ /dev/null @@ -1,76 +0,0 @@ -/* include/asm-m68k/rtc.h - * - * Copyright Richard Zidlicky - * implementation details for genrtc/q40rtc driver - */ -/* permission is hereby granted to copy, modify and redistribute this code - * in terms of the GNU Library General Public License, Version 2 or later, - * at your option. - */ - -#ifndef _ASM_RTC_H -#define _ASM_RTC_H - -#ifdef __KERNEL__ - -#include -#include -#include - -#define RTC_PIE 0x40 /* periodic interrupt enable */ -#define RTC_AIE 0x20 /* alarm interrupt enable */ -#define RTC_UIE 0x10 /* update-finished interrupt enable */ - -/* some dummy definitions */ -#define RTC_BATT_BAD 0x100 /* battery bad */ -#define RTC_SQWE 0x08 /* enable square-wave output */ -#define RTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */ -#define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */ -#define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */ - -static inline unsigned int get_rtc_time(struct rtc_time *time) -{ - /* - * Only the values that we read from the RTC are set. We leave - * tm_wday, tm_yday and tm_isdst untouched. Even though the - * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated - * by the RTC when initially set to a non-zero value. - */ - mach_hwclk(0, time); - return RTC_24H; -} - -static inline int set_rtc_time(struct rtc_time *time) -{ - return mach_hwclk(1, time); -} - -static inline unsigned int get_rtc_ss(void) -{ - if (mach_get_ss) - return mach_get_ss(); - else{ - struct rtc_time h; - - get_rtc_time(&h); - return h.tm_sec; - } -} - -static inline int get_rtc_pll(struct rtc_pll_info *pll) -{ - if (mach_get_rtc_pll) - return mach_get_rtc_pll(pll); - else - return -EINVAL; -} -static inline int set_rtc_pll(struct rtc_pll_info *pll) -{ - if (mach_set_rtc_pll) - return mach_set_rtc_pll(pll); - else - return -EINVAL; -} -#endif /* __KERNEL__ */ - -#endif /* _ASM__RTC_H */ diff --git a/include/asm-m68k/sbus.h b/include/asm-m68k/sbus.h deleted file mode 100644 index bfe3ba147f2..00000000000 --- a/include/asm-m68k/sbus.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * some sbus structures and macros to make usage of sbus drivers possible - */ - -#ifndef __M68K_SBUS_H -#define __M68K_SBUS_H - -struct sbus_dev { - struct { - unsigned int which_io; - unsigned int phys_addr; - } reg_addrs[1]; -}; - -/* sbus IO functions stolen from include/asm-sparc/io.h for the serial driver */ -/* No SBUS on the Sun3, kludge -- sam */ - -static inline void _sbus_writeb(unsigned char val, unsigned long addr) -{ - *(volatile unsigned char *)addr = val; -} - -static inline unsigned char _sbus_readb(unsigned long addr) -{ - return *(volatile unsigned char *)addr; -} - -static inline void _sbus_writel(unsigned long val, unsigned long addr) -{ - *(volatile unsigned long *)addr = val; - -} - -extern inline unsigned long _sbus_readl(unsigned long addr) -{ - return *(volatile unsigned long *)addr; -} - - -#define sbus_readb(a) _sbus_readb((unsigned long)a) -#define sbus_writeb(v, a) _sbus_writeb(v, (unsigned long)a) -#define sbus_readl(a) _sbus_readl((unsigned long)a) -#define sbus_writel(v, a) _sbus_writel(v, (unsigned long)a) - -#endif diff --git a/include/asm-m68k/scatterlist.h b/include/asm-m68k/scatterlist.h deleted file mode 100644 index d3a7a0edfec..00000000000 --- a/include/asm-m68k/scatterlist.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _M68K_SCATTERLIST_H -#define _M68K_SCATTERLIST_H - -#include - -struct scatterlist { -#ifdef CONFIG_DEBUG_SG - unsigned long sg_magic; -#endif - unsigned long page_link; - unsigned int offset; - unsigned int length; - - __u32 dma_address; /* A place to hang host-specific addresses at. */ -}; - -/* This is bogus and should go away. */ -#define ISA_DMA_THRESHOLD (0x00ffffff) - -#define sg_dma_address(sg) ((sg)->dma_address) -#define sg_dma_len(sg) ((sg)->length) - -#endif /* !(_M68K_SCATTERLIST_H) */ diff --git a/include/asm-m68k/sections.h b/include/asm-m68k/sections.h deleted file mode 100644 index d64967ecfec..00000000000 --- a/include/asm-m68k/sections.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_M68K_SECTIONS_H -#define _ASM_M68K_SECTIONS_H - -#include - -#endif /* _ASM_M68K_SECTIONS_H */ diff --git a/include/asm-m68k/segment.h b/include/asm-m68k/segment.h deleted file mode 100644 index 7b0b2d3127f..00000000000 --- a/include/asm-m68k/segment.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef _M68K_SEGMENT_H -#define _M68K_SEGMENT_H - -/* define constants */ -/* Address spaces (FC0-FC2) */ -#define USER_DATA (1) -#ifndef __USER_DS -#define __USER_DS (USER_DATA) -#endif -#define USER_PROGRAM (2) -#define SUPER_DATA (5) -#ifndef __KERNEL_DS -#define __KERNEL_DS (SUPER_DATA) -#endif -#define SUPER_PROGRAM (6) -#define CPU_SPACE (7) - -#ifndef __ASSEMBLY__ - -typedef struct { - unsigned long seg; -} mm_segment_t; - -#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) -#define USER_DS MAKE_MM_SEG(__USER_DS) -#define KERNEL_DS MAKE_MM_SEG(__KERNEL_DS) - -/* - * Get/set the SFC/DFC registers for MOVES instructions - */ - -static inline mm_segment_t get_fs(void) -{ - mm_segment_t _v; - __asm__ ("movec %/dfc,%0":"=r" (_v.seg):); - - return _v; -} - -static inline mm_segment_t get_ds(void) -{ - /* return the supervisor data space code */ - return KERNEL_DS; -} - -static inline void set_fs(mm_segment_t val) -{ - __asm__ __volatile__ ("movec %0,%/sfc\n\t" - "movec %0,%/dfc\n\t" - : /* no outputs */ : "r" (val.seg) : "memory"); -} - -#define segment_eq(a,b) ((a).seg == (b).seg) - -#endif /* __ASSEMBLY__ */ - -#endif /* _M68K_SEGMENT_H */ diff --git a/include/asm-m68k/sembuf.h b/include/asm-m68k/sembuf.h deleted file mode 100644 index 2308052a8c2..00000000000 --- a/include/asm-m68k/sembuf.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _M68K_SEMBUF_H -#define _M68K_SEMBUF_H - -/* - * The semid64_ds structure for m68k architecture. - * Note extra padding because this structure is passed back and forth - * between kernel and user space. - * - * Pad space is left for: - * - 64-bit time_t to solve y2038 problem - * - 2 miscellaneous 32-bit values - */ - -struct semid64_ds { - struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ - __kernel_time_t sem_otime; /* last semop time */ - unsigned long __unused1; - __kernel_time_t sem_ctime; /* last change time */ - unsigned long __unused2; - unsigned long sem_nsems; /* no. of semaphores in array */ - unsigned long __unused3; - unsigned long __unused4; -}; - -#endif /* _M68K_SEMBUF_H */ diff --git a/include/asm-m68k/serial.h b/include/asm-m68k/serial.h deleted file mode 100644 index 2b90d6e6907..00000000000 --- a/include/asm-m68k/serial.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * include/asm-m68k/serial.h - * - * currently this seems useful only for a Q40, - * it's an almost exact copy of ../asm-alpha/serial.h - * - */ - - -/* - * This assumes you have a 1.8432 MHz clock for your UART. - * - * It'd be nice if someone built a serial card with a 24.576 MHz - * clock, since the 16550A is capable of handling a top speed of 1.5 - * megabits/second; but this requires the faster clock. - */ -#define BASE_BAUD ( 1843200 / 16 ) - -/* Standard COM flags (except for COM4, because of the 8514 problem) */ -#ifdef CONFIG_SERIAL_DETECT_IRQ -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ) -#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ) -#else -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) -#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF -#endif - -#define SERIAL_PORT_DFNS \ - /* UART CLK PORT IRQ FLAGS */ \ - { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ - { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \ - { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ - { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ diff --git a/include/asm-m68k/setup.h b/include/asm-m68k/setup.h deleted file mode 100644 index 4dfb3952b37..00000000000 --- a/include/asm-m68k/setup.h +++ /dev/null @@ -1,376 +0,0 @@ -/* -** asm/setup.h -- Definition of the Linux/m68k setup information -** -** Copyright 1992 by Greg Harp -** -** This file is subject to the terms and conditions of the GNU General Public -** License. See the file COPYING in the main directory of this archive -** for more details. -** -** Created 09/29/92 by Greg Harp -** -** 5/2/94 Roman Hodek: -** Added bi_atari part of the machine dependent union bi_un; for now it -** contains just a model field to distinguish between TT and Falcon. -** 26/7/96 Roman Zippel: -** Renamed to setup.h; added some useful macros to allow gcc some -** optimizations if possible. -** 5/10/96 Geert Uytterhoeven: -** Redesign of the boot information structure; moved boot information -** structure to bootinfo.h -*/ - -#ifndef _M68K_SETUP_H -#define _M68K_SETUP_H - - - - /* - * Linux/m68k Architectures - */ - -#define MACH_AMIGA 1 -#define MACH_ATARI 2 -#define MACH_MAC 3 -#define MACH_APOLLO 4 -#define MACH_SUN3 5 -#define MACH_MVME147 6 -#define MACH_MVME16x 7 -#define MACH_BVME6000 8 -#define MACH_HP300 9 -#define MACH_Q40 10 -#define MACH_SUN3X 11 - -#define COMMAND_LINE_SIZE 256 - -#ifdef __KERNEL__ - -#define CL_SIZE COMMAND_LINE_SIZE - -#ifndef __ASSEMBLY__ -extern unsigned long m68k_machtype; -#endif /* !__ASSEMBLY__ */ - -#if !defined(CONFIG_AMIGA) -# define MACH_IS_AMIGA (0) -#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) || defined(CONFIG_APOLLO) \ - || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \ - || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ - || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) -# define MACH_IS_AMIGA (m68k_machtype == MACH_AMIGA) -#else -# define MACH_AMIGA_ONLY -# define MACH_IS_AMIGA (1) -# define MACH_TYPE (MACH_AMIGA) -#endif - -#if !defined(CONFIG_ATARI) -# define MACH_IS_ATARI (0) -#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_APOLLO) \ - || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \ - || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ - || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) -# define MACH_IS_ATARI (m68k_machtype == MACH_ATARI) -#else -# define MACH_ATARI_ONLY -# define MACH_IS_ATARI (1) -# define MACH_TYPE (MACH_ATARI) -#endif - -#if !defined(CONFIG_MAC) -# define MACH_IS_MAC (0) -#elif defined(CONFIG_AMIGA) || defined(CONFIG_ATARI) || defined(CONFIG_APOLLO) \ - || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \ - || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ - || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) -# define MACH_IS_MAC (m68k_machtype == MACH_MAC) -#else -# define MACH_MAC_ONLY -# define MACH_IS_MAC (1) -# define MACH_TYPE (MACH_MAC) -#endif - -#if defined(CONFIG_SUN3) -#define MACH_IS_SUN3 (1) -#define MACH_SUN3_ONLY (1) -#define MACH_TYPE (MACH_SUN3) -#else -#define MACH_IS_SUN3 (0) -#endif - -#if !defined (CONFIG_APOLLO) -# define MACH_IS_APOLLO (0) -#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ - || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \ - || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ - || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) -# define MACH_IS_APOLLO (m68k_machtype == MACH_APOLLO) -#else -# define MACH_APOLLO_ONLY -# define MACH_IS_APOLLO (1) -# define MACH_TYPE (MACH_APOLLO) -#endif - -#if !defined (CONFIG_MVME147) -# define MACH_IS_MVME147 (0) -#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ - || defined(CONFIG_APOLLO) || defined(CONFIG_BVME6000) \ - || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ - || defined(CONFIG_SUN3X) || defined(CONFIG_MVME16x) -# define MACH_IS_MVME147 (m68k_machtype == MACH_MVME147) -#else -# define MACH_MVME147_ONLY -# define MACH_IS_MVME147 (1) -# define MACH_TYPE (MACH_MVME147) -#endif - -#if !defined (CONFIG_MVME16x) -# define MACH_IS_MVME16x (0) -#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ - || defined(CONFIG_APOLLO) || defined(CONFIG_BVME6000) \ - || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ - || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) -# define MACH_IS_MVME16x (m68k_machtype == MACH_MVME16x) -#else -# define MACH_MVME16x_ONLY -# define MACH_IS_MVME16x (1) -# define MACH_TYPE (MACH_MVME16x) -#endif - -#if !defined (CONFIG_BVME6000) -# define MACH_IS_BVME6000 (0) -#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ - || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \ - || defined(CONFIG_HP300) || defined(CONFIG_Q40) \ - || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) -# define MACH_IS_BVME6000 (m68k_machtype == MACH_BVME6000) -#else -# define MACH_BVME6000_ONLY -# define MACH_IS_BVME6000 (1) -# define MACH_TYPE (MACH_BVME6000) -#endif - -#if !defined (CONFIG_HP300) -# define MACH_IS_HP300 (0) -#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ - || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \ - || defined(CONFIG_BVME6000) || defined(CONFIG_Q40) \ - || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) -# define MACH_IS_HP300 (m68k_machtype == MACH_HP300) -#else -# define MACH_HP300_ONLY -# define MACH_IS_HP300 (1) -# define MACH_TYPE (MACH_HP300) -#endif - -#if !defined (CONFIG_Q40) -# define MACH_IS_Q40 (0) -#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ - || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \ - || defined(CONFIG_BVME6000) || defined(CONFIG_HP300) \ - || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147) -# define MACH_IS_Q40 (m68k_machtype == MACH_Q40) -#else -# define MACH_Q40_ONLY -# define MACH_IS_Q40 (1) -# define MACH_TYPE (MACH_Q40) -#endif - -#if !defined (CONFIG_SUN3X) -# define MACH_IS_SUN3X (0) -#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \ - || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \ - || defined(CONFIG_BVME6000) || defined(CONFIG_HP300) \ - || defined(CONFIG_Q40) || defined(CONFIG_MVME147) -# define MACH_IS_SUN3X (m68k_machtype == MACH_SUN3X) -#else -# define CONFIG_SUN3X_ONLY -# define MACH_IS_SUN3X (1) -# define MACH_TYPE (MACH_SUN3X) -#endif - -#ifndef MACH_TYPE -# define MACH_TYPE (m68k_machtype) -#endif - -#endif /* __KERNEL__ */ - - - /* - * CPU, FPU and MMU types - * - * Note: we may rely on the following equalities: - * - * CPU_68020 == MMU_68851 - * CPU_68030 == MMU_68030 - * CPU_68040 == FPU_68040 == MMU_68040 - * CPU_68060 == FPU_68060 == MMU_68060 - */ - -#define CPUB_68020 0 -#define CPUB_68030 1 -#define CPUB_68040 2 -#define CPUB_68060 3 - -#define CPU_68020 (1< - -typedef struct siginfo { - int si_signo; - int si_errno; - int si_code; - - union { - int _pad[SI_PAD_SIZE]; - - /* kill() */ - struct { - __kernel_pid_t _pid; /* sender's pid */ - __kernel_uid_t _uid; /* backwards compatibility */ - __kernel_uid32_t _uid32; /* sender's uid */ - } _kill; - - /* POSIX.1b timers */ - struct { - timer_t _tid; /* timer id */ - int _overrun; /* overrun count */ - char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)]; - sigval_t _sigval; /* same as below */ - int _sys_private; /* not to be passed to user */ - } _timer; - - /* POSIX.1b signals */ - struct { - __kernel_pid_t _pid; /* sender's pid */ - __kernel_uid_t _uid; /* backwards compatibility */ - sigval_t _sigval; - __kernel_uid32_t _uid32; /* sender's uid */ - } _rt; - - /* SIGCHLD */ - struct { - __kernel_pid_t _pid; /* which child */ - __kernel_uid_t _uid; /* backwards compatibility */ - int _status; /* exit code */ - clock_t _utime; - clock_t _stime; - __kernel_uid32_t _uid32; /* sender's uid */ - } _sigchld; - - /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ - struct { - void *_addr; /* faulting insn/memory ref. */ - } _sigfault; - - /* SIGPOLL */ - struct { - int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ - int _fd; - } _sigpoll; - } _sifields; -} siginfo_t; - -#define UID16_SIGINFO_COMPAT_NEEDED - -/* - * How these fields are to be accessed. - */ -#undef si_uid -#ifdef __KERNEL__ -#define si_uid _sifields._kill._uid32 -#define si_uid16 _sifields._kill._uid -#else -#define si_uid _sifields._kill._uid -#endif - -#ifdef __KERNEL__ - -#include - -static inline void copy_siginfo(struct siginfo *to, struct siginfo *from) -{ - if (from->si_code < 0) - memcpy(to, from, sizeof(*to)); - else - /* _sigchld is currently the largest know union member */ - memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld)); -} - -#endif /* __KERNEL__ */ - -#endif diff --git a/include/asm-m68k/signal.h b/include/asm-m68k/signal.h deleted file mode 100644 index 3db8a81942f..00000000000 --- a/include/asm-m68k/signal.h +++ /dev/null @@ -1,206 +0,0 @@ -#ifndef _M68K_SIGNAL_H -#define _M68K_SIGNAL_H - -#include - -/* Avoid too many header ordering problems. */ -struct siginfo; - -#ifdef __KERNEL__ -/* Most things should be clean enough to redefine this at will, if care - is taken to make libc match. */ - -#define _NSIG 64 -#define _NSIG_BPW 32 -#define _NSIG_WORDS (_NSIG / _NSIG_BPW) - -typedef unsigned long old_sigset_t; /* at least 32 bits */ - -typedef struct { - unsigned long sig[_NSIG_WORDS]; -} sigset_t; - -#else -/* Here we must cater to libcs that poke about in kernel headers. */ - -#define NSIG 32 -typedef unsigned long sigset_t; - -#endif /* __KERNEL__ */ - -#define SIGHUP 1 -#define SIGINT 2 -#define SIGQUIT 3 -#define SIGILL 4 -#define SIGTRAP 5 -#define SIGABRT 6 -#define SIGIOT 6 -#define SIGBUS 7 -#define SIGFPE 8 -#define SIGKILL 9 -#define SIGUSR1 10 -#define SIGSEGV 11 -#define SIGUSR2 12 -#define SIGPIPE 13 -#define SIGALRM 14 -#define SIGTERM 15 -#define SIGSTKFLT 16 -#define SIGCHLD 17 -#define SIGCONT 18 -#define SIGSTOP 19 -#define SIGTSTP 20 -#define SIGTTIN 21 -#define SIGTTOU 22 -#define SIGURG 23 -#define SIGXCPU 24 -#define SIGXFSZ 25 -#define SIGVTALRM 26 -#define SIGPROF 27 -#define SIGWINCH 28 -#define SIGIO 29 -#define SIGPOLL SIGIO -/* -#define SIGLOST 29 -*/ -#define SIGPWR 30 -#define SIGSYS 31 -#define SIGUNUSED 31 - -/* These should not be considered constants from userland. */ -#define SIGRTMIN 32 -#define SIGRTMAX _NSIG - -/* - * SA_FLAGS values: - * - * SA_ONSTACK indicates that a registered stack_t will be used. - * SA_RESTART flag to get restarting signals (which were the default long ago) - * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. - * SA_RESETHAND clears the handler when the signal is delivered. - * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. - * SA_NODEFER prevents the current signal from being masked in the handler. - * - * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single - * Unix names RESETHAND and NODEFER respectively. - */ -#define SA_NOCLDSTOP 0x00000001 -#define SA_NOCLDWAIT 0x00000002 -#define SA_SIGINFO 0x00000004 -#define SA_ONSTACK 0x08000000 -#define SA_RESTART 0x10000000 -#define SA_NODEFER 0x40000000 -#define SA_RESETHAND 0x80000000 - -#define SA_NOMASK SA_NODEFER -#define SA_ONESHOT SA_RESETHAND - -/* - * sigaltstack controls - */ -#define SS_ONSTACK 1 -#define SS_DISABLE 2 - -#define MINSIGSTKSZ 2048 -#define SIGSTKSZ 8192 - -#include - -#ifdef __KERNEL__ -struct old_sigaction { - __sighandler_t sa_handler; - old_sigset_t sa_mask; - unsigned long sa_flags; - __sigrestore_t sa_restorer; -}; - -struct sigaction { - __sighandler_t sa_handler; - unsigned long sa_flags; - __sigrestore_t sa_restorer; - sigset_t sa_mask; /* mask last for extensibility */ -}; - -struct k_sigaction { - struct sigaction sa; -}; -#else -/* Here we must cater to libcs that poke about in kernel headers. */ - -struct sigaction { - union { - __sighandler_t _sa_handler; - void (*_sa_sigaction)(int, struct siginfo *, void *); - } _u; - sigset_t sa_mask; - unsigned long sa_flags; - void (*sa_restorer)(void); -}; - -#define sa_handler _u._sa_handler -#define sa_sigaction _u._sa_sigaction - -#endif /* __KERNEL__ */ - -typedef struct sigaltstack { - void __user *ss_sp; - int ss_flags; - size_t ss_size; -} stack_t; - -#ifdef __KERNEL__ -#include - -#define __HAVE_ARCH_SIG_BITOPS - -static inline void sigaddset(sigset_t *set, int _sig) -{ - asm ("bfset %0{%1,#1}" - : "+od" (*set) - : "id" ((_sig - 1) ^ 31) - : "cc"); -} - -static inline void sigdelset(sigset_t *set, int _sig) -{ - asm ("bfclr %0{%1,#1}" - : "+od" (*set) - : "id" ((_sig - 1) ^ 31) - : "cc"); -} - -static inline int __const_sigismember(sigset_t *set, int _sig) -{ - unsigned long sig = _sig - 1; - return 1 & (set->sig[sig / _NSIG_BPW] >> (sig % _NSIG_BPW)); -} - -static inline int __gen_sigismember(sigset_t *set, int _sig) -{ - int ret; - asm ("bfextu %1{%2,#1},%0" - : "=d" (ret) - : "od" (*set), "id" ((_sig-1) ^ 31) - : "cc"); - return ret; -} - -#define sigismember(set,sig) \ - (__builtin_constant_p(sig) ? \ - __const_sigismember(set,sig) : \ - __gen_sigismember(set,sig)) - -static inline int sigfindinword(unsigned long word) -{ - asm ("bfffo %1{#0,#0},%0" - : "=d" (word) - : "d" (word & -word) - : "cc"); - return word ^ 31; -} - -struct pt_regs; -extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie); - -#endif /* __KERNEL__ */ - -#endif /* _M68K_SIGNAL_H */ diff --git a/include/asm-m68k/socket.h b/include/asm-m68k/socket.h deleted file mode 100644 index dbc64e92c41..00000000000 --- a/include/asm-m68k/socket.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef _ASM_SOCKET_H -#define _ASM_SOCKET_H - -#include - -/* For setsockopt(2) */ -#define SOL_SOCKET 1 - -#define SO_DEBUG 1 -#define SO_REUSEADDR 2 -#define SO_TYPE 3 -#define SO_ERROR 4 -#define SO_DONTROUTE 5 -#define SO_BROADCAST 6 -#define SO_SNDBUF 7 -#define SO_RCVBUF 8 -#define SO_SNDBUFFORCE 32 -#define SO_RCVBUFFORCE 33 -#define SO_KEEPALIVE 9 -#define SO_OOBINLINE 10 -#define SO_NO_CHECK 11 -#define SO_PRIORITY 12 -#define SO_LINGER 13 -#define SO_BSDCOMPAT 14 -/* To add :#define SO_REUSEPORT 15 */ -#define SO_PASSCRED 16 -#define SO_PEERCRED 17 -#define SO_RCVLOWAT 18 -#define SO_SNDLOWAT 19 -#define SO_RCVTIMEO 20 -#define SO_SNDTIMEO 21 - -/* Security levels - as per NRL IPv6 - don't actually do anything */ -#define SO_SECURITY_AUTHENTICATION 22 -#define SO_SECURITY_ENCRYPTION_TRANSPORT 23 -#define SO_SECURITY_ENCRYPTION_NETWORK 24 - -#define SO_BINDTODEVICE 25 - -/* Socket filtering */ -#define SO_ATTACH_FILTER 26 -#define SO_DETACH_FILTER 27 - -#define SO_PEERNAME 28 -#define SO_TIMESTAMP 29 -#define SCM_TIMESTAMP SO_TIMESTAMP - -#define SO_ACCEPTCONN 30 - -#define SO_PEERSEC 31 -#define SO_PASSSEC 34 -#define SO_TIMESTAMPNS 35 -#define SCM_TIMESTAMPNS SO_TIMESTAMPNS - -#define SO_MARK 36 - -#endif /* _ASM_SOCKET_H */ diff --git a/include/asm-m68k/sockios.h b/include/asm-m68k/sockios.h deleted file mode 100644 index c04a23943cb..00000000000 --- a/include/asm-m68k/sockios.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __ARCH_M68K_SOCKIOS__ -#define __ARCH_M68K_SOCKIOS__ - -/* Socket-level I/O control calls. */ -#define FIOSETOWN 0x8901 -#define SIOCSPGRP 0x8902 -#define FIOGETOWN 0x8903 -#define SIOCGPGRP 0x8904 -#define SIOCATMARK 0x8905 -#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */ -#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ - -#endif /* __ARCH_M68K_SOCKIOS__ */ diff --git a/include/asm-m68k/spinlock.h b/include/asm-m68k/spinlock.h deleted file mode 100644 index 20f46e27b53..00000000000 --- a/include/asm-m68k/spinlock.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __M68K_SPINLOCK_H -#define __M68K_SPINLOCK_H - -#error "m68k doesn't do SMP yet" - -#endif diff --git a/include/asm-m68k/stat.h b/include/asm-m68k/stat.h deleted file mode 100644 index dd38bc2e9f9..00000000000 --- a/include/asm-m68k/stat.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef _M68K_STAT_H -#define _M68K_STAT_H - -struct __old_kernel_stat { - unsigned short st_dev; - unsigned short st_ino; - unsigned short st_mode; - unsigned short st_nlink; - unsigned short st_uid; - unsigned short st_gid; - unsigned short st_rdev; - unsigned long st_size; - unsigned long st_atime; - unsigned long st_mtime; - unsigned long st_ctime; -}; - -struct stat { - unsigned short st_dev; - unsigned short __pad1; - unsigned long st_ino; - unsigned short st_mode; - unsigned short st_nlink; - unsigned short st_uid; - unsigned short st_gid; - unsigned short st_rdev; - unsigned short __pad2; - unsigned long st_size; - unsigned long st_blksize; - unsigned long st_blocks; - unsigned long st_atime; - unsigned long __unused1; - unsigned long st_mtime; - unsigned long __unused2; - unsigned long st_ctime; - unsigned long __unused3; - unsigned long __unused4; - unsigned long __unused5; -}; - -/* This matches struct stat64 in glibc2.1, hence the absolutely - * insane amounts of padding around dev_t's. - */ -struct stat64 { - unsigned long long st_dev; - unsigned char __pad1[2]; - -#define STAT64_HAS_BROKEN_ST_INO 1 - unsigned long __st_ino; - - unsigned int st_mode; - unsigned int st_nlink; - - unsigned long st_uid; - unsigned long st_gid; - - unsigned long long st_rdev; - unsigned char __pad3[2]; - - long long st_size; - unsigned long st_blksize; - - unsigned long long st_blocks; /* Number 512-byte blocks allocated. */ - - unsigned long st_atime; - unsigned long st_atime_nsec; - - unsigned long st_mtime; - unsigned long st_mtime_nsec; - - unsigned long st_ctime; - unsigned long st_ctime_nsec; - - unsigned long long st_ino; -}; - -#endif /* _M68K_STAT_H */ diff --git a/include/asm-m68k/statfs.h b/include/asm-m68k/statfs.h deleted file mode 100644 index 08d93f14e06..00000000000 --- a/include/asm-m68k/statfs.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _M68K_STATFS_H -#define _M68K_STATFS_H - -#include - -#endif /* _M68K_STATFS_H */ diff --git a/include/asm-m68k/string.h b/include/asm-m68k/string.h deleted file mode 100644 index 2eb7df1e0f5..00000000000 --- a/include/asm-m68k/string.h +++ /dev/null @@ -1,131 +0,0 @@ -#ifndef _M68K_STRING_H_ -#define _M68K_STRING_H_ - -#include -#include - -static inline size_t __kernel_strlen(const char *s) -{ - const char *sc; - - for (sc = s; *sc++; ) - ; - return sc - s - 1; -} - -static inline char *__kernel_strcpy(char *dest, const char *src) -{ - char *xdest = dest; - - asm volatile ("\n" - "1: move.b (%1)+,(%0)+\n" - " jne 1b" - : "+a" (dest), "+a" (src) - : : "memory"); - return xdest; -} - -#ifndef __IN_STRING_C - -#define __HAVE_ARCH_STRLEN -#define strlen(s) (__builtin_constant_p(s) ? \ - __builtin_strlen(s) : \ - __kernel_strlen(s)) - -#define __HAVE_ARCH_STRNLEN -static inline size_t strnlen(const char *s, size_t count) -{ - const char *sc = s; - - asm volatile ("\n" - "1: subq.l #1,%1\n" - " jcs 2f\n" - " tst.b (%0)+\n" - " jne 1b\n" - " subq.l #1,%0\n" - "2:" - : "+a" (sc), "+d" (count)); - return sc - s; -} - -#define __HAVE_ARCH_STRCPY -#if __GNUC__ >= 4 -#define strcpy(d, s) (__builtin_constant_p(s) && \ - __builtin_strlen(s) <= 32 ? \ - __builtin_strcpy(d, s) : \ - __kernel_strcpy(d, s)) -#else -#define strcpy(d, s) __kernel_strcpy(d, s) -#endif - -#define __HAVE_ARCH_STRNCPY -static inline char *strncpy(char *dest, const char *src, size_t n) -{ - char *xdest = dest; - - asm volatile ("\n" - " jra 2f\n" - "1: move.b (%1),(%0)+\n" - " jeq 2f\n" - " addq.l #1,%1\n" - "2: subq.l #1,%2\n" - " jcc 1b\n" - : "+a" (dest), "+a" (src), "+d" (n) - : : "memory"); - return xdest; -} - -#define __HAVE_ARCH_STRCAT -#define strcat(d, s) ({ \ - char *__d = (d); \ - strcpy(__d + strlen(__d), (s)); \ -}) - -#define __HAVE_ARCH_STRCHR -static inline char *strchr(const char *s, int c) -{ - char sc, ch = c; - - for (; (sc = *s++) != ch; ) { - if (!sc) - return NULL; - } - return (char *)s - 1; -} - -#define __HAVE_ARCH_STRCMP -static inline int strcmp(const char *cs, const char *ct) -{ - char res; - - asm ("\n" - "1: move.b (%0)+,%2\n" /* get *cs */ - " cmp.b (%1)+,%2\n" /* compare a byte */ - " jne 2f\n" /* not equal, break out */ - " tst.b %2\n" /* at end of cs? */ - " jne 1b\n" /* no, keep going */ - " jra 3f\n" /* strings are equal */ - "2: sub.b -(%1),%2\n" /* *cs - *ct */ - "3:" - : "+a" (cs), "+a" (ct), "=d" (res)); - return res; -} - -#define __HAVE_ARCH_MEMSET -extern void *memset(void *, int, __kernel_size_t); -#define memset(d, c, n) __builtin_memset(d, c, n) - -#define __HAVE_ARCH_MEMCPY -extern void *memcpy(void *, const void *, __kernel_size_t); -#define memcpy(d, s, n) __builtin_memcpy(d, s, n) - -#define __HAVE_ARCH_MEMMOVE -extern void *memmove(void *, const void *, __kernel_size_t); - -#define __HAVE_ARCH_MEMCMP -extern int memcmp(const void *, const void *, __kernel_size_t); -#define memcmp(d, s, n) __builtin_memcmp(d, s, n) - -#endif - -#endif /* _M68K_STRING_H_ */ diff --git a/include/asm-m68k/sun3-head.h b/include/asm-m68k/sun3-head.h deleted file mode 100644 index 05af2f18b3b..00000000000 --- a/include/asm-m68k/sun3-head.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __SUN3_HEAD_H -#define __SUN3_HEAD_H - -#define KERNBASE 0xE000000 /* First address the kernel will eventually be */ -#define LOAD_ADDR 0x4000 /* prom jumps to us here unless this is elf /boot */ -#define FC_CONTROL 3 -#define FC_SUPERD 5 -#define FC_CPU 7 - -#endif /* __SUN3_HEAD_H */ diff --git a/include/asm-m68k/sun3_pgalloc.h b/include/asm-m68k/sun3_pgalloc.h deleted file mode 100644 index d4c83f14381..00000000000 --- a/include/asm-m68k/sun3_pgalloc.h +++ /dev/null @@ -1,102 +0,0 @@ -/* sun3_pgalloc.h -- - * reorganization around 2.3.39, routines moved from sun3_pgtable.h - * - * - * 02/27/2002 -- Modified to support "highpte" implementation in 2.5.5 (Sam) - * - * moved 1/26/2000 Sam Creasey - */ - -#ifndef _SUN3_PGALLOC_H -#define _SUN3_PGALLOC_H - -#include - -/* FIXME - when we get this compiling */ -/* erm, now that it's compiling, what do we do with it? */ -#define _KERNPG_TABLE 0 - -extern const char bad_pmd_string[]; - -#define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); }) - - -static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) -{ - free_page((unsigned long) pte); -} - -static inline void pte_free(struct mm_struct *mm, pgtable_t page) -{ - pgtable_page_dtor(page); - __free_page(page); -} - -#define __pte_free_tlb(tlb,pte) \ -do { \ - pgtable_page_dtor(pte); \ - tlb_remove_page((tlb), pte); \ -} while (0) - -static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, - unsigned long address) -{ - unsigned long page = __get_free_page(GFP_KERNEL|__GFP_REPEAT); - - if (!page) - return NULL; - - memset((void *)page, 0, PAGE_SIZE); - return (pte_t *) (page); -} - -static inline pgtable_t pte_alloc_one(struct mm_struct *mm, - unsigned long address) -{ - struct page *page = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0); - - if (page == NULL) - return NULL; - - clear_highpage(page); - pgtable_page_ctor(page); - return page; - -} - -static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte) -{ - pmd_val(*pmd) = __pa((unsigned long)pte); -} - -static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t page) -{ - pmd_val(*pmd) = __pa((unsigned long)page_address(page)); -} -#define pmd_pgtable(pmd) pmd_page(pmd) - -/* - * allocating and freeing a pmd is trivial: the 1-entry pmd is - * inside the pgd, so has no extra memory associated with it. - */ -#define pmd_free(mm, x) do { } while (0) -#define __pmd_free_tlb(tlb, x) do { } while (0) - -static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) -{ - free_page((unsigned long) pgd); -} - -static inline pgd_t * pgd_alloc(struct mm_struct *mm) -{ - pgd_t *new_pgd; - - new_pgd = (pgd_t *)get_zeroed_page(GFP_KERNEL); - memcpy(new_pgd, swapper_pg_dir, PAGE_SIZE); - memset(new_pgd, 0, (PAGE_OFFSET >> PGDIR_SHIFT)); - return new_pgd; -} - -#define pgd_populate(mm, pmd, pte) BUG() - -#endif /* SUN3_PGALLOC_H */ diff --git a/include/asm-m68k/sun3_pgtable.h b/include/asm-m68k/sun3_pgtable.h deleted file mode 100644 index f847ec732d6..00000000000 --- a/include/asm-m68k/sun3_pgtable.h +++ /dev/null @@ -1,234 +0,0 @@ -#ifndef _SUN3_PGTABLE_H -#define _SUN3_PGTABLE_H - -#include - -#ifndef __ASSEMBLY__ -#include -#include - -/* - * This file contains all the things which change drastically for the sun3 - * pagetable stuff, to avoid making too much of a mess of the generic m68k - * `pgtable.h'; this should only be included from the generic file. --m - */ - -/* For virtual address to physical address conversion */ -#define VTOP(addr) __pa(addr) -#define PTOV(addr) __va(addr) - - -#endif /* !__ASSEMBLY__ */ - -/* These need to be defined for compatibility although the sun3 doesn't use them */ -#define _PAGE_NOCACHE030 0x040 -#define _CACHEMASK040 (~0x060) -#define _PAGE_NOCACHE_S 0x040 - -/* Page protection values within PTE. */ -#define SUN3_PAGE_VALID (0x80000000) -#define SUN3_PAGE_WRITEABLE (0x40000000) -#define SUN3_PAGE_SYSTEM (0x20000000) -#define SUN3_PAGE_NOCACHE (0x10000000) -#define SUN3_PAGE_ACCESSED (0x02000000) -#define SUN3_PAGE_MODIFIED (0x01000000) - - -/* Externally used page protection values. */ -#define _PAGE_PRESENT (SUN3_PAGE_VALID) -#define _PAGE_ACCESSED (SUN3_PAGE_ACCESSED) - -#define PTE_FILE_MAX_BITS 28 - -/* Compound page protection values. */ -//todo: work out which ones *should* have SUN3_PAGE_NOCACHE and fix... -// is it just PAGE_KERNEL and PAGE_SHARED? -#define PAGE_NONE __pgprot(SUN3_PAGE_VALID \ - | SUN3_PAGE_ACCESSED \ - | SUN3_PAGE_NOCACHE) -#define PAGE_SHARED __pgprot(SUN3_PAGE_VALID \ - | SUN3_PAGE_WRITEABLE \ - | SUN3_PAGE_ACCESSED \ - | SUN3_PAGE_NOCACHE) -#define PAGE_COPY __pgprot(SUN3_PAGE_VALID \ - | SUN3_PAGE_ACCESSED \ - | SUN3_PAGE_NOCACHE) -#define PAGE_READONLY __pgprot(SUN3_PAGE_VALID \ - | SUN3_PAGE_ACCESSED \ - | SUN3_PAGE_NOCACHE) -#define PAGE_KERNEL __pgprot(SUN3_PAGE_VALID \ - | SUN3_PAGE_WRITEABLE \ - | SUN3_PAGE_SYSTEM \ - | SUN3_PAGE_NOCACHE \ - | SUN3_PAGE_ACCESSED \ - | SUN3_PAGE_MODIFIED) -#define PAGE_INIT __pgprot(SUN3_PAGE_VALID \ - | SUN3_PAGE_WRITEABLE \ - | SUN3_PAGE_SYSTEM \ - | SUN3_PAGE_NOCACHE) - -/* - * Page protections for initialising protection_map. The sun3 has only two - * protection settings, valid (implying read and execute) and writeable. These - * are as close as we can get... - */ -#define __P000 PAGE_NONE -#define __P001 PAGE_READONLY -#define __P010 PAGE_COPY -#define __P011 PAGE_COPY -#define __P100 PAGE_READONLY -#define __P101 PAGE_READONLY -#define __P110 PAGE_COPY -#define __P111 PAGE_COPY - -#define __S000 PAGE_NONE -#define __S001 PAGE_READONLY -#define __S010 PAGE_SHARED -#define __S011 PAGE_SHARED -#define __S100 PAGE_READONLY -#define __S101 PAGE_READONLY -#define __S110 PAGE_SHARED -#define __S111 PAGE_SHARED - -/* Use these fake page-protections on PMDs. */ -#define SUN3_PMD_VALID (0x00000001) -#define SUN3_PMD_MASK (0x0000003F) -#define SUN3_PMD_MAGIC (0x0000002B) - -#ifndef __ASSEMBLY__ - -/* - * Conversion functions: convert a page and protection to a page entry, - * and a page entry and page directory to the page they refer to. - */ -#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) - -static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) -{ - pte_val(pte) = (pte_val(pte) & SUN3_PAGE_CHG_MASK) | pgprot_val(newprot); - return pte; -} - -#define pmd_set(pmdp,ptep) do {} while (0) - -static inline void pgd_set(pgd_t *pgdp, pmd_t *pmdp) -{ - pgd_val(*pgdp) = virt_to_phys(pmdp); -} - -#define __pte_page(pte) \ -((unsigned long) __va ((pte_val (pte) & SUN3_PAGE_PGNUM_MASK) << PAGE_SHIFT)) -#define __pmd_page(pmd) \ -((unsigned long) __va (pmd_val (pmd) & PAGE_MASK)) - -static inline int pte_none (pte_t pte) { return !pte_val (pte); } -static inline int pte_present (pte_t pte) { return pte_val (pte) & SUN3_PAGE_VALID; } -static inline void pte_clear (struct mm_struct *mm, unsigned long addr, pte_t *ptep) -{ - pte_val (*ptep) = 0; -} - -#define pte_pfn(pte) (pte_val(pte) & SUN3_PAGE_PGNUM_MASK) -#define pfn_pte(pfn, pgprot) \ -({ pte_t __pte; pte_val(__pte) = pfn | pgprot_val(pgprot); __pte; }) - -#define pte_page(pte) virt_to_page(__pte_page(pte)) -#define pmd_page(pmd) virt_to_page(__pmd_page(pmd)) - - -static inline int pmd_none2 (pmd_t *pmd) { return !pmd_val (*pmd); } -#define pmd_none(pmd) pmd_none2(&(pmd)) -//static inline int pmd_bad (pmd_t pmd) { return (pmd_val (pmd) & SUN3_PMD_MASK) != SUN3_PMD_MAGIC; } -static inline int pmd_bad2 (pmd_t *pmd) { return 0; } -#define pmd_bad(pmd) pmd_bad2(&(pmd)) -static inline int pmd_present2 (pmd_t *pmd) { return pmd_val (*pmd) & SUN3_PMD_VALID; } -/* #define pmd_present(pmd) pmd_present2(&(pmd)) */ -#define pmd_present(pmd) (!pmd_none2(&(pmd))) -static inline void pmd_clear (pmd_t *pmdp) { pmd_val (*pmdp) = 0; } - -static inline int pgd_none (pgd_t pgd) { return 0; } -static inline int pgd_bad (pgd_t pgd) { return 0; } -static inline int pgd_present (pgd_t pgd) { return 1; } -static inline void pgd_clear (pgd_t *pgdp) {} - - -#define pte_ERROR(e) \ - printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) -#define pmd_ERROR(e) \ - printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) -#define pgd_ERROR(e) \ - printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) - - -/* - * The following only work if pte_present() is true. - * Undefined behaviour if not... - * [we have the full set here even if they don't change from m68k] - */ -static inline int pte_write(pte_t pte) { return pte_val(pte) & SUN3_PAGE_WRITEABLE; } -static inline int pte_dirty(pte_t pte) { return pte_val(pte) & SUN3_PAGE_MODIFIED; } -static inline int pte_young(pte_t pte) { return pte_val(pte) & SUN3_PAGE_ACCESSED; } -static inline int pte_file(pte_t pte) { return pte_val(pte) & SUN3_PAGE_ACCESSED; } -static inline int pte_special(pte_t pte) { return 0; } - -static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~SUN3_PAGE_WRITEABLE; return pte; } -static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~SUN3_PAGE_MODIFIED; return pte; } -static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~SUN3_PAGE_ACCESSED; return pte; } -static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= SUN3_PAGE_WRITEABLE; return pte; } -static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= SUN3_PAGE_MODIFIED; return pte; } -static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= SUN3_PAGE_ACCESSED; return pte; } -static inline pte_t pte_mknocache(pte_t pte) { pte_val(pte) |= SUN3_PAGE_NOCACHE; return pte; } -// use this version when caches work... -//static inline pte_t pte_mkcache(pte_t pte) { pte_val(pte) &= SUN3_PAGE_NOCACHE; return pte; } -// until then, use: -static inline pte_t pte_mkcache(pte_t pte) { return pte; } -static inline pte_t pte_mkspecial(pte_t pte) { return pte; } - -extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; -extern pgd_t kernel_pg_dir[PTRS_PER_PGD]; - -/* Find an entry in a pagetable directory. */ -#define pgd_index(address) ((address) >> PGDIR_SHIFT) - -#define pgd_offset(mm, address) \ -((mm)->pgd + pgd_index(address)) - -/* Find an entry in a kernel pagetable directory. */ -#define pgd_offset_k(address) pgd_offset(&init_mm, address) - -/* Find an entry in the second-level pagetable. */ -static inline pmd_t *pmd_offset (pgd_t *pgd, unsigned long address) -{ - return (pmd_t *) pgd; -} - -static inline unsigned long pte_to_pgoff(pte_t pte) -{ - return pte.pte & SUN3_PAGE_PGNUM_MASK; -} - -static inline pte_t pgoff_to_pte(unsigned off) -{ - pte_t pte = { off + SUN3_PAGE_ACCESSED }; - return pte; -} - - -/* Find an entry in the third-level pagetable. */ -#define pte_index(address) ((address >> PAGE_SHIFT) & (PTRS_PER_PTE-1)) -#define pte_offset_kernel(pmd, address) ((pte_t *) __pmd_page(*pmd) + pte_index(address)) -/* FIXME: should we bother with kmap() here? */ -#define pte_offset_map(pmd, address) ((pte_t *)kmap(pmd_page(*pmd)) + pte_index(address)) -#define pte_offset_map_nested(pmd, address) pte_offset_map(pmd, address) -#define pte_unmap(pte) kunmap(pte) -#define pte_unmap_nested(pte) kunmap(pte) - -/* Macros to (de)construct the fake PTEs representing swap pages. */ -#define __swp_type(x) ((x).val & 0x7F) -#define __swp_offset(x) (((x).val) >> 7) -#define __swp_entry(type,offset) ((swp_entry_t) { ((type) | ((offset) << 7)) }) -#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) -#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) - -#endif /* !__ASSEMBLY__ */ -#endif /* !_SUN3_PGTABLE_H */ diff --git a/include/asm-m68k/sun3ints.h b/include/asm-m68k/sun3ints.h deleted file mode 100644 index 309d6e6a137..00000000000 --- a/include/asm-m68k/sun3ints.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * sun3ints.h -- Linux/Sun3 interrupt handling code definitions - * - * Erik Verbruggen (erik@bigmama.xtdnet.nl) - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive for - * more details. - */ - -#ifndef SUN3INTS_H -#define SUN3INTS_H - -#include -#include -#include -#include -#include -#include - -#define SUN3_INT_VECS 192 - -void sun3_enable_irq(unsigned int irq); -void sun3_disable_irq(unsigned int irq); -extern void sun3_init_IRQ (void); -extern void sun3_enable_interrupts (void); -extern void sun3_disable_interrupts (void); -extern volatile unsigned char* sun3_intreg; - -/* master list of VME vectors -- don't fuck with this */ -#define SUN3_VEC_FLOPPY (IRQ_USER+0) -#define SUN3_VEC_VMESCSI0 (IRQ_USER+0) -#define SUN3_VEC_VMESCSI1 (IRQ_USER+1) -#define SUN3_VEC_CG (IRQ_USER+104) - - -#endif /* SUN3INTS_H */ diff --git a/include/asm-m68k/sun3mmu.h b/include/asm-m68k/sun3mmu.h deleted file mode 100644 index d8f17a0d8c9..00000000000 --- a/include/asm-m68k/sun3mmu.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Definitions for Sun3 custom MMU. - */ -#ifndef __SUN3_MMU_H__ -#define __SUN3_MMU_H__ - -#include -#include -#include - -/* MMU characteristics. */ -#define SUN3_SEGMAPS_PER_CONTEXT 2048 -#define SUN3_PMEGS_NUM 256 -#define SUN3_CONTEXTS_NUM 8 - -#define SUN3_PMEG_SIZE_BITS 17 -#define SUN3_PMEG_SIZE (1 << SUN3_PMEG_SIZE_BITS) -#define SUN3_PMEG_MASK (SUN3_PMEG_SIZE - 1) - -#define SUN3_PTE_SIZE_BITS 13 -#define SUN3_PTE_SIZE (1 << SUN3_PTE_SIZE_BITS) -#define SUN3_PTE_MASK (SUN3_PTE_SIZE - 1) - -#define SUN3_CONTROL_MASK (0x0FFFFFFC) -#define SUN3_INVALID_PMEG 255 -#define SUN3_INVALID_CONTEXT 255 - -#define AC_IDPROM 0x00000000 /* 34 ID PROM, R/O, byte, 32 bytes */ -#define AC_PAGEMAP 0x10000000 /* 3 Pagemap R/W, long */ -#define AC_SEGMAP 0x20000000 /* 3 Segment map, byte */ -#define AC_CONTEXT 0x30000000 /* 34c current mmu-context */ -#define AC_SENABLE 0x40000000 /* 34c system dvma/cache/reset enable reg*/ -#define AC_UDVMA_ENB 0x50000000 /* 34 Not used on Sun boards, byte */ -#define AC_BUS_ERROR 0x60000000 /* 34 Cleared on read, byte. */ -#define AC_SYNC_ERR 0x60000000 /* c fault type */ -#define AC_SYNC_VA 0x60000004 /* c fault virtual address */ -#define AC_ASYNC_ERR 0x60000008 /* c asynchronous fault type */ -#define AC_ASYNC_VA 0x6000000c /* c async fault virtual address */ -#define AC_LEDS 0x70000000 /* 34 Zero turns on LEDs, byte */ -#define AC_CACHETAGS 0x80000000 /* 34c direct access to the VAC tags */ -#define AC_CACHEDDATA 0x90000000 /* 3 c direct access to the VAC data */ -#define AC_UDVMA_MAP 0xD0000000 /* 4 Not used on Sun boards, byte */ -#define AC_VME_VECTOR 0xE0000000 /* 4 For non-Autovector VME, byte */ -#define AC_BOOT_SCC 0xF0000000 /* 34 bypass to access Zilog 8530. byte.*/ - -#define SUN3_PAGE_CHG_MASK (SUN3_PAGE_PGNUM_MASK \ - | SUN3_PAGE_ACCESSED | SUN3_PAGE_MODIFIED) - -/* Bus access type within PTE. */ -#define SUN3_PAGE_TYPE_MASK (0x0c000000) -#define SUN3_PAGE_TYPE_MEMORY (0x00000000) -#define SUN3_PAGE_TYPE_IO (0x04000000) -#define SUN3_PAGE_TYPE_VME16 (0x08000000) -#define SUN3_PAGE_TYPE_VME32 (0x0c000000) - -/* Mask for page number within PTE. */ -#define SUN3_PAGE_PGNUM_MASK (0x0007FFFF) - -/* Bits within bus-error register. */ -#define SUN3_BUSERR_WATCHDOG (0x01) -#define SUN3_BUSERR_unused (0x02) -#define SUN3_BUSERR_FPAENERR (0x04) -#define SUN3_BUSERR_FPABERR (0x08) -#define SUN3_BUSERR_VMEBERR (0x10) -#define SUN3_BUSERR_TIMEOUT (0x20) -#define SUN3_BUSERR_PROTERR (0x40) -#define SUN3_BUSERR_INVALID (0x80) - -#ifndef __ASSEMBLY__ - -/* Read bus error status register (implicitly clearing it). */ -static inline unsigned char sun3_get_buserr(void) -{ - unsigned char sfc, c; - - GET_SFC (sfc); - SET_SFC (FC_CONTROL); - GET_CONTROL_BYTE (AC_BUS_ERROR, c); - SET_SFC (sfc); - - return c; -} - -/* Read segmap from hardware MMU. */ -static inline unsigned long sun3_get_segmap(unsigned long addr) -{ - register unsigned long entry; - unsigned char c, sfc; - - GET_SFC (sfc); - SET_SFC (FC_CONTROL); - GET_CONTROL_BYTE (AC_SEGMAP | (addr & SUN3_CONTROL_MASK), c); - SET_SFC (sfc); - entry = c; - - return entry; -} - -/* Write segmap to hardware MMU. */ -static inline void sun3_put_segmap(unsigned long addr, unsigned long entry) -{ - unsigned char sfc; - - GET_DFC (sfc); - SET_DFC (FC_CONTROL); - SET_CONTROL_BYTE (AC_SEGMAP | (addr & SUN3_CONTROL_MASK), entry); - SET_DFC (sfc); - - return; -} - -/* Read PTE from hardware MMU. */ -static inline unsigned long sun3_get_pte(unsigned long addr) -{ - register unsigned long entry; - unsigned char sfc; - - GET_SFC (sfc); - SET_SFC (FC_CONTROL); - GET_CONTROL_WORD (AC_PAGEMAP | (addr & SUN3_CONTROL_MASK), entry); - SET_SFC (sfc); - - return entry; -} - -/* Write PTE to hardware MMU. */ -static inline void sun3_put_pte(unsigned long addr, unsigned long entry) -{ - unsigned char sfc; - - GET_DFC (sfc); - SET_DFC (FC_CONTROL); - SET_CONTROL_WORD (AC_PAGEMAP | (addr & SUN3_CONTROL_MASK), entry); - SET_DFC (sfc); - - return; -} - -/* get current context */ -static inline unsigned char sun3_get_context(void) -{ - unsigned char sfc, c; - - GET_SFC(sfc); - SET_SFC(FC_CONTROL); - GET_CONTROL_BYTE(AC_CONTEXT, c); - SET_SFC(sfc); - - return c; -} - -/* set alternate context */ -static inline void sun3_put_context(unsigned char c) -{ - unsigned char dfc; - GET_DFC(dfc); - SET_DFC(FC_CONTROL); - SET_CONTROL_BYTE(AC_CONTEXT, c); - SET_DFC(dfc); - - return; -} - -extern void __iomem *sun3_ioremap(unsigned long phys, unsigned long size, - unsigned long type); - -extern int sun3_map_test(unsigned long addr, char *val); - -#endif /* !__ASSEMBLY__ */ - -#endif /* !__SUN3_MMU_H__ */ diff --git a/include/asm-m68k/sun3x.h b/include/asm-m68k/sun3x.h deleted file mode 100644 index f5691a1ed7c..00000000000 --- a/include/asm-m68k/sun3x.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef SUN3X_H -#define SUN3X_H - -/* hardware addresses */ -#define SUN3X_IOMMU 0x60000000 -#define SUN3X_ENAREG 0x61000000 -#define SUN3X_INTREG 0x61001400 -#define SUN3X_DIAGREG 0x61001800 -#define SUN3X_ZS1 0x62000000 -#define SUN3X_ZS2 0x62002000 -#define SUN3X_LANCE 0x65002000 -#define SUN3X_EEPROM 0x64000000 -#define SUN3X_IDPROM 0x640007d8 -#define SUN3X_VIDEO_BASE 0x50000000 -#define SUN3X_VIDEO_P4ID 0x50300000 -#define SUN3X_ESP_BASE 0x66000000 -#define SUN3X_ESP_DMA 0x66001000 -#define SUN3X_FDC 0x6e000000 -#define SUN3X_FDC_FCR 0x6e000400 -#define SUN3X_FDC_FVR 0x6e000800 - -/* some NVRAM addresses */ -#define SUN3X_EEPROM_CONS (SUN3X_EEPROM + 0x1f) -#define SUN3X_EEPROM_PORTA (SUN3X_EEPROM + 0x58) -#define SUN3X_EEPROM_PORTB (SUN3X_EEPROM + 0x60) - -#endif diff --git a/include/asm-m68k/sun3xflop.h b/include/asm-m68k/sun3xflop.h deleted file mode 100644 index 32c45f84ac6..00000000000 --- a/include/asm-m68k/sun3xflop.h +++ /dev/null @@ -1,263 +0,0 @@ -/* sun3xflop.h: Sun3/80 specific parts of the floppy driver. - * - * Derived partially from asm-sparc/floppy.h, which is: - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) - * - * Sun3x version 2/4/2000 Sam Creasey (sammy@sammy.net) - */ - -#ifndef __ASM_SUN3X_FLOPPY_H -#define __ASM_SUN3X_FLOPPY_H - -#include -#include -#include -#include -#include - -/* default interrupt vector */ -#define SUN3X_FDC_IRQ 0x40 - -/* some constants */ -#define FCR_TC 0x1 -#define FCR_EJECT 0x2 -#define FCR_MTRON 0x4 -#define FCR_DSEL1 0x8 -#define FCR_DSEL0 0x10 - -/* We don't need no stinkin' I/O port allocation crap. */ -#undef release_region -#undef request_region -#define release_region(X, Y) do { } while(0) -#define request_region(X, Y, Z) (1) - -struct sun3xflop_private { - volatile unsigned char *status_r; - volatile unsigned char *data_r; - volatile unsigned char *fcr_r; - volatile unsigned char *fvr_r; - unsigned char fcr; -} sun3x_fdc; - -/* Super paranoid... */ -#undef HAVE_DISABLE_HLT - -/* Routines unique to each controller type on a Sun. */ -static unsigned char sun3x_82072_fd_inb(int port) -{ - static int once = 0; -// udelay(5); - switch(port & 7) { - default: - printk("floppy: Asked to read unknown port %d\n", port); - panic("floppy: Port bolixed."); - case 4: /* FD_STATUS */ - return (*sun3x_fdc.status_r) & ~STATUS_DMA; - case 5: /* FD_DATA */ - return (*sun3x_fdc.data_r); - case 7: /* FD_DIR */ - /* ugly hack, I can't find a way to actually detect the disk */ - if(!once) { - once = 1; - return 0x80; - } - return 0; - }; - panic("sun_82072_fd_inb: How did I get here?"); -} - -static void sun3x_82072_fd_outb(unsigned char value, int port) -{ -// udelay(5); - switch(port & 7) { - default: - printk("floppy: Asked to write to unknown port %d\n", port); - panic("floppy: Port bolixed."); - case 2: /* FD_DOR */ - /* Oh geese, 82072 on the Sun has no DOR register, - * so we make do with taunting the FCR. - * - * ASSUMPTIONS: There will only ever be one floppy - * drive attached to a Sun controller - * and it will be at drive zero. - */ - - { - unsigned char fcr = sun3x_fdc.fcr; - - if(value & 0x10) { - fcr |= (FCR_DSEL0 | FCR_MTRON); - } else - fcr &= ~(FCR_DSEL0 | FCR_MTRON); - - - if(fcr != sun3x_fdc.fcr) { - *(sun3x_fdc.fcr_r) = fcr; - sun3x_fdc.fcr = fcr; - } - } - break; - case 5: /* FD_DATA */ - *(sun3x_fdc.data_r) = value; - break; - case 7: /* FD_DCR */ - *(sun3x_fdc.status_r) = value; - break; - case 4: /* FD_STATUS */ - *(sun3x_fdc.status_r) = value; - break; - }; - return; -} - - -asmlinkage irqreturn_t sun3xflop_hardint(int irq, void *dev_id) -{ - register unsigned char st; - -#undef TRACE_FLPY_INT -#define NO_FLOPPY_ASSEMBLER - -#ifdef TRACE_FLPY_INT - static int calls=0; - static int bytes=0; - static int dma_wait=0; -#endif - if(!doing_pdma) { - floppy_interrupt(irq, dev_id); - return IRQ_HANDLED; - } - -// printk("doing pdma\n");// st %x\n", sun_fdc->status_82072); - -#ifdef TRACE_FLPY_INT - if(!calls) - bytes = virtual_dma_count; -#endif - - { - register int lcount; - register char *lptr; - - for(lcount=virtual_dma_count, lptr=virtual_dma_addr; - lcount; lcount--, lptr++) { -/* st=fd_inb(virtual_dma_port+4) & 0x80 ; */ - st = *(sun3x_fdc.status_r); -/* if(st != 0xa0) */ -/* break; */ - - if((st & 0x80) == 0) { - virtual_dma_count = lcount; - virtual_dma_addr = lptr; - return IRQ_HANDLED; - } - - if((st & 0x20) == 0) - break; - - if(virtual_dma_mode) -/* fd_outb(*lptr, virtual_dma_port+5); */ - *(sun3x_fdc.data_r) = *lptr; - else -/* *lptr = fd_inb(virtual_dma_port+5); */ - *lptr = *(sun3x_fdc.data_r); - } - - virtual_dma_count = lcount; - virtual_dma_addr = lptr; -/* st = fd_inb(virtual_dma_port+4); */ - st = *(sun3x_fdc.status_r); - } - -#ifdef TRACE_FLPY_INT - calls++; -#endif -// printk("st=%02x\n", st); - if(st == 0x20) - return IRQ_HANDLED; - if(!(st & 0x20)) { - virtual_dma_residue += virtual_dma_count; - virtual_dma_count=0; - doing_pdma = 0; - -#ifdef TRACE_FLPY_INT - printk("count=%x, residue=%x calls=%d bytes=%x dma_wait=%d\n", - virtual_dma_count, virtual_dma_residue, calls, bytes, - dma_wait); - calls = 0; - dma_wait=0; -#endif - - floppy_interrupt(irq, dev_id); - return IRQ_HANDLED; - } - - -#ifdef TRACE_FLPY_INT - if(!virtual_dma_count) - dma_wait++; -#endif - return IRQ_HANDLED; -} - -static int sun3xflop_request_irq(void) -{ - static int once = 0; - int error; - - if(!once) { - once = 1; - error = request_irq(FLOPPY_IRQ, sun3xflop_hardint, - IRQF_DISABLED, "floppy", NULL); - return ((error == 0) ? 0 : -1); - } else return 0; -} - -static void __init floppy_set_flags(int *ints,int param, int param2); - -static int sun3xflop_init(void) -{ - if(FLOPPY_IRQ < 0x40) - FLOPPY_IRQ = SUN3X_FDC_IRQ; - - sun3x_fdc.status_r = (volatile unsigned char *)SUN3X_FDC; - sun3x_fdc.data_r = (volatile unsigned char *)(SUN3X_FDC+1); - sun3x_fdc.fcr_r = (volatile unsigned char *)SUN3X_FDC_FCR; - sun3x_fdc.fvr_r = (volatile unsigned char *)SUN3X_FDC_FVR; - sun3x_fdc.fcr = 0; - - /* Last minute sanity check... */ - if(*sun3x_fdc.status_r == 0xff) { - return -1; - } - - *sun3x_fdc.fvr_r = FLOPPY_IRQ; - - *sun3x_fdc.fcr_r = FCR_TC; - udelay(10); - *sun3x_fdc.fcr_r = 0; - - /* Success... */ - floppy_set_flags(NULL, 1, FD_BROKEN_DCL); // I don't know how to detect this. - allowed_drive_mask = 0x01; - return (int) SUN3X_FDC; -} - -/* I'm not precisely sure this eject routine works */ -static int sun3x_eject(void) -{ - if(MACH_IS_SUN3X) { - - sun3x_fdc.fcr |= (FCR_DSEL0 | FCR_EJECT); - *(sun3x_fdc.fcr_r) = sun3x_fdc.fcr; - udelay(10); - sun3x_fdc.fcr &= ~(FCR_DSEL0 | FCR_EJECT); - *(sun3x_fdc.fcr_r) = sun3x_fdc.fcr; - } - - return 0; -} - -#define fd_eject(drive) sun3x_eject() - -#endif /* !(__ASM_SUN3X_FLOPPY_H) */ diff --git a/include/asm-m68k/sun3xprom.h b/include/asm-m68k/sun3xprom.h deleted file mode 100644 index 6735efcf5f6..00000000000 --- a/include/asm-m68k/sun3xprom.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Useful PROM locations */ - -#ifndef SUN3X_PROM_H -#define SUN3X_PROM_H - -extern void (*sun3x_putchar)(int); -extern int (*sun3x_getchar)(void); -extern int (*sun3x_mayget)(void); -extern int (*sun3x_mayput)(int); - -void sun3x_reboot(void); -void sun3x_abort(void); -void sun3x_prom_init(void); -unsigned long sun3x_prom_ptov(unsigned long pa, unsigned long size); - -/* interesting hardware locations */ -#define SUN3X_IOMMU 0x60000000 -#define SUN3X_ENAREG 0x61000000 -#define SUN3X_INTREG 0x61001400 -#define SUN3X_DIAGREG 0x61001800 -#define SUN3X_ZS1 0x62000000 -#define SUN3X_ZS2 0x62002000 -#define SUN3X_LANCE 0x65002000 -#define SUN3X_EEPROM 0x64000000 -#define SUN3X_IDPROM 0x640007d8 -#define SUN3X_VIDEO_BASE 0x50400000 -#define SUN3X_VIDEO_REGS 0x50300000 - -/* vector table */ -#define SUN3X_PROM_BASE 0xfefe0000 -#define SUN3X_P_GETCHAR (SUN3X_PROM_BASE + 20) -#define SUN3X_P_PUTCHAR (SUN3X_PROM_BASE + 24) -#define SUN3X_P_MAYGET (SUN3X_PROM_BASE + 28) -#define SUN3X_P_MAYPUT (SUN3X_PROM_BASE + 32) -#define SUN3X_P_REBOOT (SUN3X_PROM_BASE + 96) -#define SUN3X_P_SETLEDS (SUN3X_PROM_BASE + 144) -#define SUN3X_P_ABORT (SUN3X_PROM_BASE + 152) - -/* mapped area */ -#define SUN3X_MAP_START 0xfee00000 -#define SUN3X_MAP_END 0xff000000 - -#endif diff --git a/include/asm-m68k/suspend.h b/include/asm-m68k/suspend.h deleted file mode 100644 index 57b3ddb4d26..00000000000 --- a/include/asm-m68k/suspend.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _M68K_SUSPEND_H -#define _M68K_SUSPEND_H - -/* Dummy include. */ - -#endif /* _M68K_SUSPEND_H */ diff --git a/include/asm-m68k/swab.h b/include/asm-m68k/swab.h deleted file mode 100644 index 7221e306682..00000000000 --- a/include/asm-m68k/swab.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _M68K_SWAB_H -#define _M68K_SWAB_H - -#include -#include - -#define __SWAB_64_THRU_32__ - -static inline __attribute_const__ __u32 __arch_swab32(__u32 val) -{ - __asm__("rolw #8,%0; swap %0; rolw #8,%0" : "=d" (val) : "0" (val)); - return val; -} -#define __arch_swab32 __arch_swab32 - -#endif /* _M68K_SWAB_H */ diff --git a/include/asm-m68k/system.h b/include/asm-m68k/system.h deleted file mode 100644 index dbb6515ffd5..00000000000 --- a/include/asm-m68k/system.h +++ /dev/null @@ -1,218 +0,0 @@ -#ifndef _M68K_SYSTEM_H -#define _M68K_SYSTEM_H - -#include -#include -#include -#include - -#ifdef __KERNEL__ - -/* - * switch_to(n) should switch tasks to task ptr, first checking that - * ptr isn't the current task, in which case it does nothing. This - * also clears the TS-flag if the task we switched to has used the - * math co-processor latest. - */ -/* - * switch_to() saves the extra registers, that are not saved - * automatically by SAVE_SWITCH_STACK in resume(), ie. d0-d5 and - * a0-a1. Some of these are used by schedule() and its predecessors - * and so we might get see unexpected behaviors when a task returns - * with unexpected register values. - * - * syscall stores these registers itself and none of them are used - * by syscall after the function in the syscall has been called. - * - * Beware that resume now expects *next to be in d1 and the offset of - * tss to be in a1. This saves a few instructions as we no longer have - * to push them onto the stack and read them back right after. - * - * 02/17/96 - Jes Sorensen (jds@kom.auc.dk) - * - * Changed 96/09/19 by Andreas Schwab - * pass prev in a0, next in a1 - */ -asmlinkage void resume(void); -#define switch_to(prev,next,last) do { \ - register void *_prev __asm__ ("a0") = (prev); \ - register void *_next __asm__ ("a1") = (next); \ - register void *_last __asm__ ("d1"); \ - __asm__ __volatile__("jbsr resume" \ - : "=a" (_prev), "=a" (_next), "=d" (_last) \ - : "0" (_prev), "1" (_next) \ - : "d0", "d2", "d3", "d4", "d5"); \ - (last) = _last; \ -} while (0) - - -/* - * Force strict CPU ordering. - * Not really required on m68k... - */ -#define nop() do { asm volatile ("nop"); barrier(); } while (0) -#define mb() barrier() -#define rmb() barrier() -#define wmb() barrier() -#define read_barrier_depends() ((void)0) -#define set_mb(var, value) ({ (var) = (value); wmb(); }) - -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() ((void)0) - -/* interrupt control.. */ -#if 0 -#define local_irq_enable() asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory") -#else -#include -#define local_irq_enable() ({ \ - if (MACH_IS_Q40 || !hardirq_count()) \ - asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory"); \ -}) -#endif -#define local_irq_disable() asm volatile ("oriw #0x0700,%%sr": : : "memory") -#define local_save_flags(x) asm volatile ("movew %%sr,%0":"=d" (x) : : "memory") -#define local_irq_restore(x) asm volatile ("movew %0,%%sr": :"d" (x) : "memory") - -static inline int irqs_disabled(void) -{ - unsigned long flags; - local_save_flags(flags); - return flags & ~ALLOWINT; -} - -/* For spinlocks etc */ -#define local_irq_save(x) ({ local_save_flags(x); local_irq_disable(); }) - -#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) - -struct __xchg_dummy { unsigned long a[100]; }; -#define __xg(x) ((volatile struct __xchg_dummy *)(x)) - -#ifndef CONFIG_RMW_INSNS -static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) -{ - unsigned long flags, tmp; - - local_irq_save(flags); - - switch (size) { - case 1: - tmp = *(u8 *)ptr; - *(u8 *)ptr = x; - x = tmp; - break; - case 2: - tmp = *(u16 *)ptr; - *(u16 *)ptr = x; - x = tmp; - break; - case 4: - tmp = *(u32 *)ptr; - *(u32 *)ptr = x; - x = tmp; - break; - default: - BUG(); - } - - local_irq_restore(flags); - return x; -} -#else -static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) -{ - switch (size) { - case 1: - __asm__ __volatile__ - ("moveb %2,%0\n\t" - "1:\n\t" - "casb %0,%1,%2\n\t" - "jne 1b" - : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); - break; - case 2: - __asm__ __volatile__ - ("movew %2,%0\n\t" - "1:\n\t" - "casw %0,%1,%2\n\t" - "jne 1b" - : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); - break; - case 4: - __asm__ __volatile__ - ("movel %2,%0\n\t" - "1:\n\t" - "casl %0,%1,%2\n\t" - "jne 1b" - : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); - break; - } - return x; -} -#endif - -#include - -#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) - -/* - * Atomic compare and exchange. Compare OLD with MEM, if identical, - * store NEW in MEM. Return the initial value in MEM. Success is - * indicated by comparing RETURN with OLD. - */ -#ifdef CONFIG_RMW_INSNS -#define __HAVE_ARCH_CMPXCHG 1 - -static inline unsigned long __cmpxchg(volatile void *p, unsigned long old, - unsigned long new, int size) -{ - switch (size) { - case 1: - __asm__ __volatile__ ("casb %0,%2,%1" - : "=d" (old), "=m" (*(char *)p) - : "d" (new), "0" (old), "m" (*(char *)p)); - break; - case 2: - __asm__ __volatile__ ("casw %0,%2,%1" - : "=d" (old), "=m" (*(short *)p) - : "d" (new), "0" (old), "m" (*(short *)p)); - break; - case 4: - __asm__ __volatile__ ("casl %0,%2,%1" - : "=d" (old), "=m" (*(int *)p) - : "d" (new), "0" (old), "m" (*(int *)p)); - break; - } - return old; -} - -#define cmpxchg(ptr, o, n) \ - ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \ - (unsigned long)(n), sizeof(*(ptr)))) -#define cmpxchg_local(ptr, o, n) \ - ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \ - (unsigned long)(n), sizeof(*(ptr)))) -#else - -/* - * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make - * them available. - */ -#define cmpxchg_local(ptr, o, n) \ - ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\ - (unsigned long)(n), sizeof(*(ptr)))) - -#ifndef CONFIG_SMP -#include -#endif - -#endif - -#define arch_align_stack(x) (x) - -#endif /* __KERNEL__ */ - -#endif /* _M68K_SYSTEM_H */ diff --git a/include/asm-m68k/termbits.h b/include/asm-m68k/termbits.h deleted file mode 100644 index 8c14170996b..00000000000 --- a/include/asm-m68k/termbits.h +++ /dev/null @@ -1,200 +0,0 @@ -#ifndef __ARCH_M68K_TERMBITS_H__ -#define __ARCH_M68K_TERMBITS_H__ - -#include - -typedef unsigned char cc_t; -typedef unsigned int speed_t; -typedef unsigned int tcflag_t; - -#define NCCS 19 -struct termios { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_line; /* line discipline */ - cc_t c_cc[NCCS]; /* control characters */ -}; - -struct termios2 { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_line; /* line discipline */ - cc_t c_cc[NCCS]; /* control characters */ - speed_t c_ispeed; /* input speed */ - speed_t c_ospeed; /* output speed */ -}; - -struct ktermios { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_line; /* line discipline */ - cc_t c_cc[NCCS]; /* control characters */ - speed_t c_ispeed; /* input speed */ - speed_t c_ospeed; /* output speed */ -}; - -/* c_cc characters */ -#define VINTR 0 -#define VQUIT 1 -#define VERASE 2 -#define VKILL 3 -#define VEOF 4 -#define VTIME 5 -#define VMIN 6 -#define VSWTC 7 -#define VSTART 8 -#define VSTOP 9 -#define VSUSP 10 -#define VEOL 11 -#define VREPRINT 12 -#define VDISCARD 13 -#define VWERASE 14 -#define VLNEXT 15 -#define VEOL2 16 - - -/* c_iflag bits */ -#define IGNBRK 0000001 -#define BRKINT 0000002 -#define IGNPAR 0000004 -#define PARMRK 0000010 -#define INPCK 0000020 -#define ISTRIP 0000040 -#define INLCR 0000100 -#define IGNCR 0000200 -#define ICRNL 0000400 -#define IUCLC 0001000 -#define IXON 0002000 -#define IXANY 0004000 -#define IXOFF 0010000 -#define IMAXBEL 0020000 -#define IUTF8 0040000 - -/* c_oflag bits */ -#define OPOST 0000001 -#define OLCUC 0000002 -#define ONLCR 0000004 -#define OCRNL 0000010 -#define ONOCR 0000020 -#define ONLRET 0000040 -#define OFILL 0000100 -#define OFDEL 0000200 -#define NLDLY 0000400 -#define NL0 0000000 -#define NL1 0000400 -#define CRDLY 0003000 -#define CR0 0000000 -#define CR1 0001000 -#define CR2 0002000 -#define CR3 0003000 -#define TABDLY 0014000 -#define TAB0 0000000 -#define TAB1 0004000 -#define TAB2 0010000 -#define TAB3 0014000 -#define XTABS 0014000 -#define BSDLY 0020000 -#define BS0 0000000 -#define BS1 0020000 -#define VTDLY 0040000 -#define VT0 0000000 -#define VT1 0040000 -#define FFDLY 0100000 -#define FF0 0000000 -#define FF1 0100000 - -/* c_cflag bit meaning */ -#define CBAUD 0010017 -#define B0 0000000 /* hang up */ -#define B50 0000001 -#define B75 0000002 -#define B110 0000003 -#define B134 0000004 -#define B150 0000005 -#define B200 0000006 -#define B300 0000007 -#define B600 0000010 -#define B1200 0000011 -#define B1800 0000012 -#define B2400 0000013 -#define B4800 0000014 -#define B9600 0000015 -#define B19200 0000016 -#define B38400 0000017 -#define EXTA B19200 -#define EXTB B38400 -#define CSIZE 0000060 -#define CS5 0000000 -#define CS6 0000020 -#define CS7 0000040 -#define CS8 0000060 -#define CSTOPB 0000100 -#define CREAD 0000200 -#define PARENB 0000400 -#define PARODD 0001000 -#define HUPCL 0002000 -#define CLOCAL 0004000 -#define CBAUDEX 0010000 -#define BOTHER 0010000 -#define B57600 0010001 -#define B115200 0010002 -#define B230400 0010003 -#define B460800 0010004 -#define B500000 0010005 -#define B576000 0010006 -#define B921600 0010007 -#define B1000000 0010010 -#define B1152000 0010011 -#define B1500000 0010012 -#define B2000000 0010013 -#define B2500000 0010014 -#define B3000000 0010015 -#define B3500000 0010016 -#define B4000000 0010017 -#define CIBAUD 002003600000 /* input baud rate */ -#define CMSPAR 010000000000 /* mark or space (stick) parity */ -#define CRTSCTS 020000000000 /* flow control */ - -#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ - -/* c_lflag bits */ -#define ISIG 0000001 -#define ICANON 0000002 -#define XCASE 0000004 -#define ECHO 0000010 -#define ECHOE 0000020 -#define ECHOK 0000040 -#define ECHONL 0000100 -#define NOFLSH 0000200 -#define TOSTOP 0000400 -#define ECHOCTL 0001000 -#define ECHOPRT 0002000 -#define ECHOKE 0004000 -#define FLUSHO 0010000 -#define PENDIN 0040000 -#define IEXTEN 0100000 - - -/* tcflow() and TCXONC use these */ -#define TCOOFF 0 -#define TCOON 1 -#define TCIOFF 2 -#define TCION 3 - -/* tcflush() and TCFLSH use these */ -#define TCIFLUSH 0 -#define TCOFLUSH 1 -#define TCIOFLUSH 2 - -/* tcsetattr uses these */ -#define TCSANOW 0 -#define TCSADRAIN 1 -#define TCSAFLUSH 2 - -#endif /* __ARCH_M68K_TERMBITS_H__ */ diff --git a/include/asm-m68k/termios.h b/include/asm-m68k/termios.h deleted file mode 100644 index 0823032e404..00000000000 --- a/include/asm-m68k/termios.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef _M68K_TERMIOS_H -#define _M68K_TERMIOS_H - -#include -#include - -struct winsize { - unsigned short ws_row; - unsigned short ws_col; - unsigned short ws_xpixel; - unsigned short ws_ypixel; -}; - -#define NCC 8 -struct termio { - unsigned short c_iflag; /* input mode flags */ - unsigned short c_oflag; /* output mode flags */ - unsigned short c_cflag; /* control mode flags */ - unsigned short c_lflag; /* local mode flags */ - unsigned char c_line; /* line discipline */ - unsigned char c_cc[NCC]; /* control characters */ -}; - -#ifdef __KERNEL__ -/* intr=^C quit=^| erase=del kill=^U - eof=^D vtime=\0 vmin=\1 sxtc=\0 - start=^Q stop=^S susp=^Z eol=\0 - reprint=^R discard=^U werase=^W lnext=^V - eol2=\0 -*/ -#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" -#endif - -/* modem lines */ -#define TIOCM_LE 0x001 -#define TIOCM_DTR 0x002 -#define TIOCM_RTS 0x004 -#define TIOCM_ST 0x008 -#define TIOCM_SR 0x010 -#define TIOCM_CTS 0x020 -#define TIOCM_CAR 0x040 -#define TIOCM_RNG 0x080 -#define TIOCM_DSR 0x100 -#define TIOCM_CD TIOCM_CAR -#define TIOCM_RI TIOCM_RNG -#define TIOCM_OUT1 0x2000 -#define TIOCM_OUT2 0x4000 -#define TIOCM_LOOP 0x8000 - -/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ - -#ifdef __KERNEL__ - -/* - * Translate a "termio" structure into a "termios". Ugh. - */ -#define user_termio_to_kernel_termios(termios, termio) \ -({ \ - unsigned short tmp; \ - get_user(tmp, &(termio)->c_iflag); \ - (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \ - get_user(tmp, &(termio)->c_oflag); \ - (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \ - get_user(tmp, &(termio)->c_cflag); \ - (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \ - get_user(tmp, &(termio)->c_lflag); \ - (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \ - get_user((termios)->c_line, &(termio)->c_line); \ - copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ -}) - -/* - * Translate a "termios" structure into a "termio". Ugh. - */ -#define kernel_termios_to_user_termio(termio, termios) \ -({ \ - put_user((termios)->c_iflag, &(termio)->c_iflag); \ - put_user((termios)->c_oflag, &(termio)->c_oflag); \ - put_user((termios)->c_cflag, &(termio)->c_cflag); \ - put_user((termios)->c_lflag, &(termio)->c_lflag); \ - put_user((termios)->c_line, &(termio)->c_line); \ - copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ -}) - -#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2)) -#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2)) -#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios)) -#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios)) - -#endif /* __KERNEL__ */ - -#endif /* _M68K_TERMIOS_H */ diff --git a/include/asm-m68k/thread_info.h b/include/asm-m68k/thread_info.h deleted file mode 100644 index af0fda46e94..00000000000 --- a/include/asm-m68k/thread_info.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef _ASM_M68K_THREAD_INFO_H -#define _ASM_M68K_THREAD_INFO_H - -#include -#include - -struct thread_info { - struct task_struct *task; /* main task structure */ - unsigned long flags; - struct exec_domain *exec_domain; /* execution domain */ - int preempt_count; /* 0 => preemptable, <0 => BUG */ - __u32 cpu; /* should always be 0 on m68k */ - struct restart_block restart_block; -}; - -#define PREEMPT_ACTIVE 0x4000000 - -#define INIT_THREAD_INFO(tsk) \ -{ \ - .task = &tsk, \ - .exec_domain = &default_exec_domain, \ - .restart_block = { \ - .fn = do_no_restart_syscall, \ - }, \ -} - -/* THREAD_SIZE should be 8k, so handle differently for 4k and 8k machines */ -#define THREAD_SIZE_ORDER (13 - PAGE_SHIFT) - -#define init_thread_info (init_task.thread.info) -#define init_stack (init_thread_union.stack) - -#define task_thread_info(tsk) (&(tsk)->thread.info) -#define task_stack_page(tsk) ((tsk)->stack) -#define current_thread_info() task_thread_info(current) - -#define __HAVE_THREAD_FUNCTIONS - -#define setup_thread_stack(p, org) ({ \ - *(struct task_struct **)(p)->stack = (p); \ - task_thread_info(p)->task = (p); \ -}) - -#define end_of_stack(p) ((unsigned long *)(p)->stack + 1) - -/* entry.S relies on these definitions! - * bits 0-7 are tested at every exception exit - * bits 8-15 are also tested at syscall exit - */ -#define TIF_SIGPENDING 6 /* signal pending */ -#define TIF_NEED_RESCHED 7 /* rescheduling necessary */ -#define TIF_DELAYED_TRACE 14 /* single step a syscall */ -#define TIF_SYSCALL_TRACE 15 /* syscall trace active */ -#define TIF_MEMDIE 16 -#define TIF_FREEZE 17 /* thread is freezing for suspend */ - -#endif /* _ASM_M68K_THREAD_INFO_H */ diff --git a/include/asm-m68k/timex.h b/include/asm-m68k/timex.h deleted file mode 100644 index b87f2f278f6..00000000000 --- a/include/asm-m68k/timex.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * linux/include/asm-m68k/timex.h - * - * m68k architecture timex specifications - */ -#ifndef _ASMm68k_TIMEX_H -#define _ASMm68k_TIMEX_H - -#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ - -typedef unsigned long cycles_t; - -static inline cycles_t get_cycles(void) -{ - return 0; -} - -#endif diff --git a/include/asm-m68k/tlb.h b/include/asm-m68k/tlb.h deleted file mode 100644 index 1785cff7344..00000000000 --- a/include/asm-m68k/tlb.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef _M68K_TLB_H -#define _M68K_TLB_H - -/* - * m68k doesn't need any special per-pte or - * per-vma handling.. - */ -#define tlb_start_vma(tlb, vma) do { } while (0) -#define tlb_end_vma(tlb, vma) do { } while (0) -#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0) - -/* - * .. because we flush the whole mm when it - * fills up. - */ -#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm) - -#include - -#endif /* _M68K_TLB_H */ diff --git a/include/asm-m68k/tlbflush.h b/include/asm-m68k/tlbflush.h deleted file mode 100644 index acb6bf21a32..00000000000 --- a/include/asm-m68k/tlbflush.h +++ /dev/null @@ -1,219 +0,0 @@ -#ifndef _M68K_TLBFLUSH_H -#define _M68K_TLBFLUSH_H - - -#ifndef CONFIG_SUN3 - -#include - -static inline void flush_tlb_kernel_page(void *addr) -{ - if (CPU_IS_040_OR_060) { - mm_segment_t old_fs = get_fs(); - set_fs(KERNEL_DS); - __asm__ __volatile__(".chip 68040\n\t" - "pflush (%0)\n\t" - ".chip 68k" - : : "a" (addr)); - set_fs(old_fs); - } else if (CPU_IS_020_OR_030) - __asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr)); -} - -/* - * flush all user-space atc entries. - */ -static inline void __flush_tlb(void) -{ - if (CPU_IS_040_OR_060) - __asm__ __volatile__(".chip 68040\n\t" - "pflushan\n\t" - ".chip 68k"); - else if (CPU_IS_020_OR_030) - __asm__ __volatile__("pflush #0,#4"); -} - -static inline void __flush_tlb040_one(unsigned long addr) -{ - __asm__ __volatile__(".chip 68040\n\t" - "pflush (%0)\n\t" - ".chip 68k" - : : "a" (addr)); -} - -static inline void __flush_tlb_one(unsigned long addr) -{ - if (CPU_IS_040_OR_060) - __flush_tlb040_one(addr); - else if (CPU_IS_020_OR_030) - __asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr)); -} - -#define flush_tlb() __flush_tlb() - -/* - * flush all atc entries (both kernel and user-space entries). - */ -static inline void flush_tlb_all(void) -{ - if (CPU_IS_040_OR_060) - __asm__ __volatile__(".chip 68040\n\t" - "pflusha\n\t" - ".chip 68k"); - else if (CPU_IS_020_OR_030) - __asm__ __volatile__("pflusha"); -} - -static inline void flush_tlb_mm(struct mm_struct *mm) -{ - if (mm == current->active_mm) - __flush_tlb(); -} - -static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) -{ - if (vma->vm_mm == current->active_mm) { - mm_segment_t old_fs = get_fs(); - set_fs(USER_DS); - __flush_tlb_one(addr); - set_fs(old_fs); - } -} - -static inline void flush_tlb_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end) -{ - if (vma->vm_mm == current->active_mm) - __flush_tlb(); -} - -static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end) -{ - flush_tlb_all(); -} - -#else - - -/* Reserved PMEGs. */ -extern char sun3_reserved_pmeg[SUN3_PMEGS_NUM]; -extern unsigned long pmeg_vaddr[SUN3_PMEGS_NUM]; -extern unsigned char pmeg_alloc[SUN3_PMEGS_NUM]; -extern unsigned char pmeg_ctx[SUN3_PMEGS_NUM]; - -/* Flush all userspace mappings one by one... (why no flush command, - sun?) */ -static inline void flush_tlb_all(void) -{ - unsigned long addr; - unsigned char ctx, oldctx; - - oldctx = sun3_get_context(); - for(addr = 0x00000000; addr < TASK_SIZE; addr += SUN3_PMEG_SIZE) { - for(ctx = 0; ctx < 8; ctx++) { - sun3_put_context(ctx); - sun3_put_segmap(addr, SUN3_INVALID_PMEG); - } - } - - sun3_put_context(oldctx); - /* erase all of the userspace pmeg maps, we've clobbered them - all anyway */ - for(addr = 0; addr < SUN3_INVALID_PMEG; addr++) { - if(pmeg_alloc[addr] == 1) { - pmeg_alloc[addr] = 0; - pmeg_ctx[addr] = 0; - pmeg_vaddr[addr] = 0; - } - } - -} - -/* Clear user TLB entries within the context named in mm */ -static inline void flush_tlb_mm (struct mm_struct *mm) -{ - unsigned char oldctx; - unsigned char seg; - unsigned long i; - - oldctx = sun3_get_context(); - sun3_put_context(mm->context); - - for(i = 0; i < TASK_SIZE; i += SUN3_PMEG_SIZE) { - seg = sun3_get_segmap(i); - if(seg == SUN3_INVALID_PMEG) - continue; - - sun3_put_segmap(i, SUN3_INVALID_PMEG); - pmeg_alloc[seg] = 0; - pmeg_ctx[seg] = 0; - pmeg_vaddr[seg] = 0; - } - - sun3_put_context(oldctx); - -} - -/* Flush a single TLB page. In this case, we're limited to flushing a - single PMEG */ -static inline void flush_tlb_page (struct vm_area_struct *vma, - unsigned long addr) -{ - unsigned char oldctx; - unsigned char i; - - oldctx = sun3_get_context(); - sun3_put_context(vma->vm_mm->context); - addr &= ~SUN3_PMEG_MASK; - if((i = sun3_get_segmap(addr)) != SUN3_INVALID_PMEG) - { - pmeg_alloc[i] = 0; - pmeg_ctx[i] = 0; - pmeg_vaddr[i] = 0; - sun3_put_segmap (addr, SUN3_INVALID_PMEG); - } - sun3_put_context(oldctx); - -} -/* Flush a range of pages from TLB. */ - -static inline void flush_tlb_range (struct vm_area_struct *vma, - unsigned long start, unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned char seg, oldctx; - - start &= ~SUN3_PMEG_MASK; - - oldctx = sun3_get_context(); - sun3_put_context(mm->context); - - while(start < end) - { - if((seg = sun3_get_segmap(start)) == SUN3_INVALID_PMEG) - goto next; - if(pmeg_ctx[seg] == mm->context) { - pmeg_alloc[seg] = 0; - pmeg_ctx[seg] = 0; - pmeg_vaddr[seg] = 0; - } - sun3_put_segmap(start, SUN3_INVALID_PMEG); - next: - start += SUN3_PMEG_SIZE; - } -} - -static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end) -{ - flush_tlb_all(); -} - -/* Flush kernel page from TLB. */ -static inline void flush_tlb_kernel_page (unsigned long addr) -{ - sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG); -} - -#endif - -#endif /* _M68K_TLBFLUSH_H */ diff --git a/include/asm-m68k/topology.h b/include/asm-m68k/topology.h deleted file mode 100644 index ca173e9f26f..00000000000 --- a/include/asm-m68k/topology.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_M68K_TOPOLOGY_H -#define _ASM_M68K_TOPOLOGY_H - -#include - -#endif /* _ASM_M68K_TOPOLOGY_H */ diff --git a/include/asm-m68k/traps.h b/include/asm-m68k/traps.h deleted file mode 100644 index 8caef25624c..00000000000 --- a/include/asm-m68k/traps.h +++ /dev/null @@ -1,272 +0,0 @@ -/* - * linux/include/asm/traps.h - * - * Copyright (C) 1993 Hamish Macdonald - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - -#ifndef _M68K_TRAPS_H -#define _M68K_TRAPS_H - -#ifndef __ASSEMBLY__ - -#include -#include - -typedef void (*e_vector)(void); - -asmlinkage void auto_inthandler(void); -asmlinkage void user_inthandler(void); -asmlinkage void bad_inthandler(void); - -extern e_vector vectors[]; - -#endif - -#define VEC_RESETSP (0) -#define VEC_RESETPC (1) -#define VEC_BUSERR (2) -#define VEC_ADDRERR (3) -#define VEC_ILLEGAL (4) -#define VEC_ZERODIV (5) -#define VEC_CHK (6) -#define VEC_TRAP (7) -#define VEC_PRIV (8) -#define VEC_TRACE (9) -#define VEC_LINE10 (10) -#define VEC_LINE11 (11) -#define VEC_RESV12 (12) -#define VEC_COPROC (13) -#define VEC_FORMAT (14) -#define VEC_UNINT (15) -#define VEC_RESV16 (16) -#define VEC_RESV17 (17) -#define VEC_RESV18 (18) -#define VEC_RESV19 (19) -#define VEC_RESV20 (20) -#define VEC_RESV21 (21) -#define VEC_RESV22 (22) -#define VEC_RESV23 (23) -#define VEC_SPUR (24) -#define VEC_INT1 (25) -#define VEC_INT2 (26) -#define VEC_INT3 (27) -#define VEC_INT4 (28) -#define VEC_INT5 (29) -#define VEC_INT6 (30) -#define VEC_INT7 (31) -#define VEC_SYS (32) -#define VEC_TRAP1 (33) -#define VEC_TRAP2 (34) -#define VEC_TRAP3 (35) -#define VEC_TRAP4 (36) -#define VEC_TRAP5 (37) -#define VEC_TRAP6 (38) -#define VEC_TRAP7 (39) -#define VEC_TRAP8 (40) -#define VEC_TRAP9 (41) -#define VEC_TRAP10 (42) -#define VEC_TRAP11 (43) -#define VEC_TRAP12 (44) -#define VEC_TRAP13 (45) -#define VEC_TRAP14 (46) -#define VEC_TRAP15 (47) -#define VEC_FPBRUC (48) -#define VEC_FPIR (49) -#define VEC_FPDIVZ (50) -#define VEC_FPUNDER (51) -#define VEC_FPOE (52) -#define VEC_FPOVER (53) -#define VEC_FPNAN (54) -#define VEC_FPUNSUP (55) -#define VEC_MMUCFG (56) -#define VEC_MMUILL (57) -#define VEC_MMUACC (58) -#define VEC_RESV59 (59) -#define VEC_UNIMPEA (60) -#define VEC_UNIMPII (61) -#define VEC_RESV62 (62) -#define VEC_RESV63 (63) -#define VEC_USER (64) - -#define VECOFF(vec) ((vec)<<2) - -#ifndef __ASSEMBLY__ - -/* Status register bits */ -#define PS_T (0x8000) -#define PS_S (0x2000) -#define PS_M (0x1000) -#define PS_C (0x0001) - -/* bits for 68020/68030 special status word */ - -#define FC (0x8000) -#define FB (0x4000) -#define RC (0x2000) -#define RB (0x1000) -#define DF (0x0100) -#define RM (0x0080) -#define RW (0x0040) -#define SZ (0x0030) -#define DFC (0x0007) - -/* bits for 68030 MMU status register (mmusr,psr) */ - -#define MMU_B (0x8000) /* bus error */ -#define MMU_L (0x4000) /* limit violation */ -#define MMU_S (0x2000) /* supervisor violation */ -#define MMU_WP (0x0800) /* write-protected */ -#define MMU_I (0x0400) /* invalid descriptor */ -#define MMU_M (0x0200) /* ATC entry modified */ -#define MMU_T (0x0040) /* transparent translation */ -#define MMU_NUM (0x0007) /* number of levels traversed */ - - -/* bits for 68040 special status word */ -#define CP_040 (0x8000) -#define CU_040 (0x4000) -#define CT_040 (0x2000) -#define CM_040 (0x1000) -#define MA_040 (0x0800) -#define ATC_040 (0x0400) -#define LK_040 (0x0200) -#define RW_040 (0x0100) -#define SIZ_040 (0x0060) -#define TT_040 (0x0018) -#define TM_040 (0x0007) - -/* bits for 68040 write back status word */ -#define WBV_040 (0x80) -#define WBSIZ_040 (0x60) -#define WBBYT_040 (0x20) -#define WBWRD_040 (0x40) -#define WBLNG_040 (0x00) -#define WBTT_040 (0x18) -#define WBTM_040 (0x07) - -/* bus access size codes */ -#define BA_SIZE_BYTE (0x20) -#define BA_SIZE_WORD (0x40) -#define BA_SIZE_LONG (0x00) -#define BA_SIZE_LINE (0x60) - -/* bus access transfer type codes */ -#define BA_TT_MOVE16 (0x08) - -/* bits for 68040 MMU status register (mmusr) */ -#define MMU_B_040 (0x0800) -#define MMU_G_040 (0x0400) -#define MMU_S_040 (0x0080) -#define MMU_CM_040 (0x0060) -#define MMU_M_040 (0x0010) -#define MMU_WP_040 (0x0004) -#define MMU_T_040 (0x0002) -#define MMU_R_040 (0x0001) - -/* bits in the 68060 fault status long word (FSLW) */ -#define MMU060_MA (0x08000000) /* misaligned */ -#define MMU060_LK (0x02000000) /* locked transfer */ -#define MMU060_RW (0x01800000) /* read/write */ -# define MMU060_RW_W (0x00800000) /* write */ -# define MMU060_RW_R (0x01000000) /* read */ -# define MMU060_RW_RMW (0x01800000) /* read/modify/write */ -# define MMU060_W (0x00800000) /* general write, includes rmw */ -#define MMU060_SIZ (0x00600000) /* transfer size */ -#define MMU060_TT (0x00180000) /* transfer type (TT) bits */ -#define MMU060_TM (0x00070000) /* transfer modifier (TM) bits */ -#define MMU060_IO (0x00008000) /* instruction or operand */ -#define MMU060_PBE (0x00004000) /* push buffer bus error */ -#define MMU060_SBE (0x00002000) /* store buffer bus error */ -#define MMU060_PTA (0x00001000) /* pointer A fault */ -#define MMU060_PTB (0x00000800) /* pointer B fault */ -#define MMU060_IL (0x00000400) /* double indirect descr fault */ -#define MMU060_PF (0x00000200) /* page fault (invalid descr) */ -#define MMU060_SP (0x00000100) /* supervisor protection */ -#define MMU060_WP (0x00000080) /* write protection */ -#define MMU060_TWE (0x00000040) /* bus error on table search */ -#define MMU060_RE (0x00000020) /* bus error on read */ -#define MMU060_WE (0x00000010) /* bus error on write */ -#define MMU060_TTR (0x00000008) /* error caused by TTR translation */ -#define MMU060_BPE (0x00000004) /* branch prediction error */ -#define MMU060_SEE (0x00000001) /* software emulated error */ - -/* cases of missing or invalid descriptors */ -#define MMU060_DESC_ERR (MMU060_PTA | MMU060_PTB | \ - MMU060_IL | MMU060_PF) -/* bits that indicate real errors */ -#define MMU060_ERR_BITS (MMU060_PBE | MMU060_SBE | MMU060_DESC_ERR | MMU060_SP | \ - MMU060_WP | MMU060_TWE | MMU060_RE | MMU060_WE) - -/* structure for stack frames */ - -struct frame { - struct pt_regs ptregs; - union { - struct { - unsigned long iaddr; /* instruction address */ - } fmt2; - struct { - unsigned long effaddr; /* effective address */ - } fmt3; - struct { - unsigned long effaddr; /* effective address */ - unsigned long pc; /* pc of faulted instr */ - } fmt4; - struct { - unsigned long effaddr; /* effective address */ - unsigned short ssw; /* special status word */ - unsigned short wb3s; /* write back 3 status */ - unsigned short wb2s; /* write back 2 status */ - unsigned short wb1s; /* write back 1 status */ - unsigned long faddr; /* fault address */ - unsigned long wb3a; /* write back 3 address */ - unsigned long wb3d; /* write back 3 data */ - unsigned long wb2a; /* write back 2 address */ - unsigned long wb2d; /* write back 2 data */ - unsigned long wb1a; /* write back 1 address */ - unsigned long wb1dpd0; /* write back 1 data/push data 0*/ - unsigned long pd1; /* push data 1*/ - unsigned long pd2; /* push data 2*/ - unsigned long pd3; /* push data 3*/ - } fmt7; - struct { - unsigned long iaddr; /* instruction address */ - unsigned short int1[4]; /* internal registers */ - } fmt9; - struct { - unsigned short int1; - unsigned short ssw; /* special status word */ - unsigned short isc; /* instruction stage c */ - unsigned short isb; /* instruction stage b */ - unsigned long daddr; /* data cycle fault address */ - unsigned short int2[2]; - unsigned long dobuf; /* data cycle output buffer */ - unsigned short int3[2]; - } fmta; - struct { - unsigned short int1; - unsigned short ssw; /* special status word */ - unsigned short isc; /* instruction stage c */ - unsigned short isb; /* instruction stage b */ - unsigned long daddr; /* data cycle fault address */ - unsigned short int2[2]; - unsigned long dobuf; /* data cycle output buffer */ - unsigned short int3[4]; - unsigned long baddr; /* stage B address */ - unsigned short int4[2]; - unsigned long dibuf; /* data cycle input buffer */ - unsigned short int5[3]; - unsigned ver : 4; /* stack frame version # */ - unsigned int6:12; - unsigned short int7[18]; - } fmtb; - } un; -}; - -#endif /* __ASSEMBLY__ */ - -#endif /* _M68K_TRAPS_H */ diff --git a/include/asm-m68k/types.h b/include/asm-m68k/types.h deleted file mode 100644 index 6441cb5f8e7..00000000000 --- a/include/asm-m68k/types.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef _M68K_TYPES_H -#define _M68K_TYPES_H - -/* - * This file is never included by application software unless - * explicitly requested (e.g., via linux/types.h) in which case the - * application is Linux specific so (user-) name space pollution is - * not a major issue. However, for interoperability, libraries still - * need to be careful to avoid a name clashes. - */ -#include - -#ifndef __ASSEMBLY__ - -typedef unsigned short umode_t; - -#endif /* __ASSEMBLY__ */ - -/* - * These aren't exported outside the kernel to avoid name space clashes - */ -#ifdef __KERNEL__ - -#define BITS_PER_LONG 32 - -#ifndef __ASSEMBLY__ - -/* DMA addresses are always 32-bits wide */ - -typedef u32 dma_addr_t; -typedef u32 dma64_addr_t; - -#endif /* __ASSEMBLY__ */ - -#endif /* __KERNEL__ */ - -#endif /* _M68K_TYPES_H */ diff --git a/include/asm-m68k/uaccess.h b/include/asm-m68k/uaccess.h deleted file mode 100644 index 7107f3fbdbb..00000000000 --- a/include/asm-m68k/uaccess.h +++ /dev/null @@ -1,374 +0,0 @@ -#ifndef __M68K_UACCESS_H -#define __M68K_UACCESS_H - -/* - * User space memory access functions - */ -#include -#include -#include -#include -#include - -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - -/* We let the MMU do all checking */ -static inline int access_ok(int type, const void __user *addr, - unsigned long size) -{ - return 1; -} - -/* - * The exception table consists of pairs of addresses: the first is the - * address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out - * what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ - -struct exception_table_entry -{ - unsigned long insn, fixup; -}; - -extern int __put_user_bad(void); -extern int __get_user_bad(void); - -#define __put_user_asm(res, x, ptr, bwl, reg, err) \ -asm volatile ("\n" \ - "1: moves."#bwl" %2,%1\n" \ - "2:\n" \ - " .section .fixup,\"ax\"\n" \ - " .even\n" \ - "10: moveq.l %3,%0\n" \ - " jra 2b\n" \ - " .previous\n" \ - "\n" \ - " .section __ex_table,\"a\"\n" \ - " .align 4\n" \ - " .long 1b,10b\n" \ - " .long 2b,10b\n" \ - " .previous" \ - : "+d" (res), "=m" (*(ptr)) \ - : #reg (x), "i" (err)) - -/* - * These are the main single-value transfer routines. They automatically - * use the right size if we just have the right pointer type. - */ - -#define __put_user(x, ptr) \ -({ \ - typeof(*(ptr)) __pu_val = (x); \ - int __pu_err = 0; \ - __chk_user_ptr(ptr); \ - switch (sizeof (*(ptr))) { \ - case 1: \ - __put_user_asm(__pu_err, __pu_val, ptr, b, d, -EFAULT); \ - break; \ - case 2: \ - __put_user_asm(__pu_err, __pu_val, ptr, w, d, -EFAULT); \ - break; \ - case 4: \ - __put_user_asm(__pu_err, __pu_val, ptr, l, r, -EFAULT); \ - break; \ - case 8: \ - { \ - const void __user *__pu_ptr = (ptr); \ - asm volatile ("\n" \ - "1: moves.l %2,(%1)+\n" \ - "2: moves.l %R2,(%1)\n" \ - "3:\n" \ - " .section .fixup,\"ax\"\n" \ - " .even\n" \ - "10: movel %3,%0\n" \ - " jra 3b\n" \ - " .previous\n" \ - "\n" \ - " .section __ex_table,\"a\"\n" \ - " .align 4\n" \ - " .long 1b,10b\n" \ - " .long 2b,10b\n" \ - " .long 3b,10b\n" \ - " .previous" \ - : "+d" (__pu_err), "+a" (__pu_ptr) \ - : "r" (__pu_val), "i" (-EFAULT) \ - : "memory"); \ - break; \ - } \ - default: \ - __pu_err = __put_user_bad(); \ - break; \ - } \ - __pu_err; \ -}) -#define put_user(x, ptr) __put_user(x, ptr) - - -#define __get_user_asm(res, x, ptr, type, bwl, reg, err) ({ \ - type __gu_val; \ - asm volatile ("\n" \ - "1: moves."#bwl" %2,%1\n" \ - "2:\n" \ - " .section .fixup,\"ax\"\n" \ - " .even\n" \ - "10: move.l %3,%0\n" \ - " sub."#bwl" %1,%1\n" \ - " jra 2b\n" \ - " .previous\n" \ - "\n" \ - " .section __ex_table,\"a\"\n" \ - " .align 4\n" \ - " .long 1b,10b\n" \ - " .previous" \ - : "+d" (res), "=&" #reg (__gu_val) \ - : "m" (*(ptr)), "i" (err)); \ - (x) = (typeof(*(ptr)))(unsigned long)__gu_val; \ -}) - -#define __get_user(x, ptr) \ -({ \ - int __gu_err = 0; \ - __chk_user_ptr(ptr); \ - switch (sizeof(*(ptr))) { \ - case 1: \ - __get_user_asm(__gu_err, x, ptr, u8, b, d, -EFAULT); \ - break; \ - case 2: \ - __get_user_asm(__gu_err, x, ptr, u16, w, d, -EFAULT); \ - break; \ - case 4: \ - __get_user_asm(__gu_err, x, ptr, u32, l, r, -EFAULT); \ - break; \ -/* case 8: disabled because gcc-4.1 has a broken typeof \ - { \ - const void *__gu_ptr = (ptr); \ - u64 __gu_val; \ - asm volatile ("\n" \ - "1: moves.l (%2)+,%1\n" \ - "2: moves.l (%2),%R1\n" \ - "3:\n" \ - " .section .fixup,\"ax\"\n" \ - " .even\n" \ - "10: move.l %3,%0\n" \ - " sub.l %1,%1\n" \ - " sub.l %R1,%R1\n" \ - " jra 3b\n" \ - " .previous\n" \ - "\n" \ - " .section __ex_table,\"a\"\n" \ - " .align 4\n" \ - " .long 1b,10b\n" \ - " .long 2b,10b\n" \ - " .previous" \ - : "+d" (__gu_err), "=&r" (__gu_val), \ - "+a" (__gu_ptr) \ - : "i" (-EFAULT) \ - : "memory"); \ - (x) = (typeof(*(ptr)))__gu_val; \ - break; \ - } */ \ - default: \ - __gu_err = __get_user_bad(); \ - break; \ - } \ - __gu_err; \ -}) -#define get_user(x, ptr) __get_user(x, ptr) - -unsigned long __generic_copy_from_user(void *to, const void __user *from, unsigned long n); -unsigned long __generic_copy_to_user(void __user *to, const void *from, unsigned long n); - -#define __constant_copy_from_user_asm(res, to, from, tmp, n, s1, s2, s3)\ - asm volatile ("\n" \ - "1: moves."#s1" (%2)+,%3\n" \ - " move."#s1" %3,(%1)+\n" \ - "2: moves."#s2" (%2)+,%3\n" \ - " move."#s2" %3,(%1)+\n" \ - " .ifnc \""#s3"\",\"\"\n" \ - "3: moves."#s3" (%2)+,%3\n" \ - " move."#s3" %3,(%1)+\n" \ - " .endif\n" \ - "4:\n" \ - " .section __ex_table,\"a\"\n" \ - " .align 4\n" \ - " .long 1b,10f\n" \ - " .long 2b,20f\n" \ - " .ifnc \""#s3"\",\"\"\n" \ - " .long 3b,30f\n" \ - " .endif\n" \ - " .previous\n" \ - "\n" \ - " .section .fixup,\"ax\"\n" \ - " .even\n" \ - "10: clr."#s1" (%1)+\n" \ - "20: clr."#s2" (%1)+\n" \ - " .ifnc \""#s3"\",\"\"\n" \ - "30: clr."#s3" (%1)+\n" \ - " .endif\n" \ - " moveq.l #"#n",%0\n" \ - " jra 4b\n" \ - " .previous\n" \ - : "+d" (res), "+&a" (to), "+a" (from), "=&d" (tmp) \ - : : "memory") - -static __always_inline unsigned long -__constant_copy_from_user(void *to, const void __user *from, unsigned long n) -{ - unsigned long res = 0, tmp; - - switch (n) { - case 1: - __get_user_asm(res, *(u8 *)to, (u8 __user *)from, u8, b, d, 1); - break; - case 2: - __get_user_asm(res, *(u16 *)to, (u16 __user *)from, u16, w, d, 2); - break; - case 3: - __constant_copy_from_user_asm(res, to, from, tmp, 3, w, b,); - break; - case 4: - __get_user_asm(res, *(u32 *)to, (u32 __user *)from, u32, l, r, 4); - break; - case 5: - __constant_copy_from_user_asm(res, to, from, tmp, 5, l, b,); - break; - case 6: - __constant_copy_from_user_asm(res, to, from, tmp, 6, l, w,); - break; - case 7: - __constant_copy_from_user_asm(res, to, from, tmp, 7, l, w, b); - break; - case 8: - __constant_copy_from_user_asm(res, to, from, tmp, 8, l, l,); - break; - case 9: - __constant_copy_from_user_asm(res, to, from, tmp, 9, l, l, b); - break; - case 10: - __constant_copy_from_user_asm(res, to, from, tmp, 10, l, l, w); - break; - case 12: - __constant_copy_from_user_asm(res, to, from, tmp, 12, l, l, l); - break; - default: - /* we limit the inlined version to 3 moves */ - return __generic_copy_from_user(to, from, n); - } - - return res; -} - -#define __constant_copy_to_user_asm(res, to, from, tmp, n, s1, s2, s3) \ - asm volatile ("\n" \ - " move."#s1" (%2)+,%3\n" \ - "11: moves."#s1" %3,(%1)+\n" \ - "12: move."#s2" (%2)+,%3\n" \ - "21: moves."#s2" %3,(%1)+\n" \ - "22:\n" \ - " .ifnc \""#s3"\",\"\"\n" \ - " move."#s3" (%2)+,%3\n" \ - "31: moves."#s3" %3,(%1)+\n" \ - "32:\n" \ - " .endif\n" \ - "4:\n" \ - "\n" \ - " .section __ex_table,\"a\"\n" \ - " .align 4\n" \ - " .long 11b,5f\n" \ - " .long 12b,5f\n" \ - " .long 21b,5f\n" \ - " .long 22b,5f\n" \ - " .ifnc \""#s3"\",\"\"\n" \ - " .long 31b,5f\n" \ - " .long 32b,5f\n" \ - " .endif\n" \ - " .previous\n" \ - "\n" \ - " .section .fixup,\"ax\"\n" \ - " .even\n" \ - "5: moveq.l #"#n",%0\n" \ - " jra 4b\n" \ - " .previous\n" \ - : "+d" (res), "+a" (to), "+a" (from), "=&d" (tmp) \ - : : "memory") - -static __always_inline unsigned long -__constant_copy_to_user(void __user *to, const void *from, unsigned long n) -{ - unsigned long res = 0, tmp; - - switch (n) { - case 1: - __put_user_asm(res, *(u8 *)from, (u8 __user *)to, b, d, 1); - break; - case 2: - __put_user_asm(res, *(u16 *)from, (u16 __user *)to, w, d, 2); - break; - case 3: - __constant_copy_to_user_asm(res, to, from, tmp, 3, w, b,); - break; - case 4: - __put_user_asm(res, *(u32 *)from, (u32 __user *)to, l, r, 4); - break; - case 5: - __constant_copy_to_user_asm(res, to, from, tmp, 5, l, b,); - break; - case 6: - __constant_copy_to_user_asm(res, to, from, tmp, 6, l, w,); - break; - case 7: - __constant_copy_to_user_asm(res, to, from, tmp, 7, l, w, b); - break; - case 8: - __constant_copy_to_user_asm(res, to, from, tmp, 8, l, l,); - break; - case 9: - __constant_copy_to_user_asm(res, to, from, tmp, 9, l, l, b); - break; - case 10: - __constant_copy_to_user_asm(res, to, from, tmp, 10, l, l, w); - break; - case 12: - __constant_copy_to_user_asm(res, to, from, tmp, 12, l, l, l); - break; - default: - /* limit the inlined version to 3 moves */ - return __generic_copy_to_user(to, from, n); - } - - return res; -} - -#define __copy_from_user(to, from, n) \ -(__builtin_constant_p(n) ? \ - __constant_copy_from_user(to, from, n) : \ - __generic_copy_from_user(to, from, n)) - -#define __copy_to_user(to, from, n) \ -(__builtin_constant_p(n) ? \ - __constant_copy_to_user(to, from, n) : \ - __generic_copy_to_user(to, from, n)) - -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user - -#define copy_from_user(to, from, n) __copy_from_user(to, from, n) -#define copy_to_user(to, from, n) __copy_to_user(to, from, n) - -long strncpy_from_user(char *dst, const char __user *src, long count); -long strnlen_user(const char __user *src, long n); -unsigned long __clear_user(void __user *to, unsigned long n); - -#define clear_user __clear_user - -#define strlen_user(str) strnlen_user(str, 32767) - -#endif /* _M68K_UACCESS_H */ diff --git a/include/asm-m68k/ucontext.h b/include/asm-m68k/ucontext.h deleted file mode 100644 index e4e22669edc..00000000000 --- a/include/asm-m68k/ucontext.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _M68K_UCONTEXT_H -#define _M68K_UCONTEXT_H - -typedef int greg_t; -#define NGREG 18 -typedef greg_t gregset_t[NGREG]; - -typedef struct fpregset { - int f_fpcntl[3]; - int f_fpregs[8*3]; -} fpregset_t; - -struct mcontext { - int version; - gregset_t gregs; - fpregset_t fpregs; -}; - -#define MCONTEXT_VERSION 2 - -struct ucontext { - unsigned long uc_flags; - struct ucontext *uc_link; - stack_t uc_stack; - struct mcontext uc_mcontext; - unsigned long uc_filler[80]; - sigset_t uc_sigmask; /* mask last for extensibility */ -}; - -#endif diff --git a/include/asm-m68k/unaligned.h b/include/asm-m68k/unaligned.h deleted file mode 100644 index 77698f2dc33..00000000000 --- a/include/asm-m68k/unaligned.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _ASM_M68K_UNALIGNED_H -#define _ASM_M68K_UNALIGNED_H - -/* - * The m68k can do unaligned accesses itself. - */ -#include -#include - -#define get_unaligned __get_unaligned_be -#define put_unaligned __put_unaligned_be - -#endif /* _ASM_M68K_UNALIGNED_H */ diff --git a/include/asm-m68k/unistd.h b/include/asm-m68k/unistd.h deleted file mode 100644 index 965abb8bc7f..00000000000 --- a/include/asm-m68k/unistd.h +++ /dev/null @@ -1,374 +0,0 @@ -#ifndef _ASM_M68K_UNISTD_H_ -#define _ASM_M68K_UNISTD_H_ - -/* - * This file contains the system call numbers. - */ - -#define __NR_exit 1 -#define __NR_fork 2 -#define __NR_read 3 -#define __NR_write 4 -#define __NR_open 5 -#define __NR_close 6 -#define __NR_waitpid 7 -#define __NR_creat 8 -#define __NR_link 9 -#define __NR_unlink 10 -#define __NR_execve 11 -#define __NR_chdir 12 -#define __NR_time 13 -#define __NR_mknod 14 -#define __NR_chmod 15 -#define __NR_chown 16 -#define __NR_break 17 -#define __NR_oldstat 18 -#define __NR_lseek 19 -#define __NR_getpid 20 -#define __NR_mount 21 -#define __NR_umount 22 -#define __NR_setuid 23 -#define __NR_getuid 24 -#define __NR_stime 25 -#define __NR_ptrace 26 -#define __NR_alarm 27 -#define __NR_oldfstat 28 -#define __NR_pause 29 -#define __NR_utime 30 -#define __NR_stty 31 -#define __NR_gtty 32 -#define __NR_access 33 -#define __NR_nice 34 -#define __NR_ftime 35 -#define __NR_sync 36 -#define __NR_kill 37 -#define __NR_rename 38 -#define __NR_mkdir 39 -#define __NR_rmdir 40 -#define __NR_dup 41 -#define __NR_pipe 42 -#define __NR_times 43 -#define __NR_prof 44 -#define __NR_brk 45 -#define __NR_setgid 46 -#define __NR_getgid 47 -#define __NR_signal 48 -#define __NR_geteuid 49 -#define __NR_getegid 50 -#define __NR_acct 51 -#define __NR_umount2 52 -#define __NR_lock 53 -#define __NR_ioctl 54 -#define __NR_fcntl 55 -#define __NR_mpx 56 -#define __NR_setpgid 57 -#define __NR_ulimit 58 -#define __NR_oldolduname 59 -#define __NR_umask 60 -#define __NR_chroot 61 -#define __NR_ustat 62 -#define __NR_dup2 63 -#define __NR_getppid 64 -#define __NR_getpgrp 65 -#define __NR_setsid 66 -#define __NR_sigaction 67 -#define __NR_sgetmask 68 -#define __NR_ssetmask 69 -#define __NR_setreuid 70 -#define __NR_setregid 71 -#define __NR_sigsuspend 72 -#define __NR_sigpending 73 -#define __NR_sethostname 74 -#define __NR_setrlimit 75 -#define __NR_getrlimit 76 -#define __NR_getrusage 77 -#define __NR_gettimeofday 78 -#define __NR_settimeofday 79 -#define __NR_getgroups 80 -#define __NR_setgroups 81 -#define __NR_select 82 -#define __NR_symlink 83 -#define __NR_oldlstat 84 -#define __NR_readlink 85 -#define __NR_uselib 86 -#define __NR_swapon 87 -#define __NR_reboot 88 -#define __NR_readdir 89 -#define __NR_mmap 90 -#define __NR_munmap 91 -#define __NR_truncate 92 -#define __NR_ftruncate 93 -#define __NR_fchmod 94 -#define __NR_fchown 95 -#define __NR_getpriority 96 -#define __NR_setpriority 97 -#define __NR_profil 98 -#define __NR_statfs 99 -#define __NR_fstatfs 100 -#define __NR_ioperm 101 -#define __NR_socketcall 102 -#define __NR_syslog 103 -#define __NR_setitimer 104 -#define __NR_getitimer 105 -#define __NR_stat 106 -#define __NR_lstat 107 -#define __NR_fstat 108 -#define __NR_olduname 109 -#define __NR_iopl /* 110 */ not supported -#define __NR_vhangup 111 -#define __NR_idle /* 112 */ Obsolete -#define __NR_vm86 /* 113 */ not supported -#define __NR_wait4 114 -#define __NR_swapoff 115 -#define __NR_sysinfo 116 -#define __NR_ipc 117 -#define __NR_fsync 118 -#define __NR_sigreturn 119 -#define __NR_clone 120 -#define __NR_setdomainname 121 -#define __NR_uname 122 -#define __NR_cacheflush 123 -#define __NR_adjtimex 124 -#define __NR_mprotect 125 -#define __NR_sigprocmask 126 -#define __NR_create_module 127 -#define __NR_init_module 128 -#define __NR_delete_module 129 -#define __NR_get_kernel_syms 130 -#define __NR_quotactl 131 -#define __NR_getpgid 132 -#define __NR_fchdir 133 -#define __NR_bdflush 134 -#define __NR_sysfs 135 -#define __NR_personality 136 -#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ -#define __NR_setfsuid 138 -#define __NR_setfsgid 139 -#define __NR__llseek 140 -#define __NR_getdents 141 -#define __NR__newselect 142 -#define __NR_flock 143 -#define __NR_msync 144 -#define __NR_readv 145 -#define __NR_writev 146 -#define __NR_getsid 147 -#define __NR_fdatasync 148 -#define __NR__sysctl 149 -#define __NR_mlock 150 -#define __NR_munlock 151 -#define __NR_mlockall 152 -#define __NR_munlockall 153 -#define __NR_sched_setparam 154 -#define __NR_sched_getparam 155 -#define __NR_sched_setscheduler 156 -#define __NR_sched_getscheduler 157 -#define __NR_sched_yield 158 -#define __NR_sched_get_priority_max 159 -#define __NR_sched_get_priority_min 160 -#define __NR_sched_rr_get_interval 161 -#define __NR_nanosleep 162 -#define __NR_mremap 163 -#define __NR_setresuid 164 -#define __NR_getresuid 165 -#define __NR_getpagesize 166 -#define __NR_query_module 167 -#define __NR_poll 168 -#define __NR_nfsservctl 169 -#define __NR_setresgid 170 -#define __NR_getresgid 171 -#define __NR_prctl 172 -#define __NR_rt_sigreturn 173 -#define __NR_rt_sigaction 174 -#define __NR_rt_sigprocmask 175 -#define __NR_rt_sigpending 176 -#define __NR_rt_sigtimedwait 177 -#define __NR_rt_sigqueueinfo 178 -#define __NR_rt_sigsuspend 179 -#define __NR_pread64 180 -#define __NR_pwrite64 181 -#define __NR_lchown 182 -#define __NR_getcwd 183 -#define __NR_capget 184 -#define __NR_capset 185 -#define __NR_sigaltstack 186 -#define __NR_sendfile 187 -#define __NR_getpmsg 188 /* some people actually want streams */ -#define __NR_putpmsg 189 /* some people actually want streams */ -#define __NR_vfork 190 -#define __NR_ugetrlimit 191 -#define __NR_mmap2 192 -#define __NR_truncate64 193 -#define __NR_ftruncate64 194 -#define __NR_stat64 195 -#define __NR_lstat64 196 -#define __NR_fstat64 197 -#define __NR_chown32 198 -#define __NR_getuid32 199 -#define __NR_getgid32 200 -#define __NR_geteuid32 201 -#define __NR_getegid32 202 -#define __NR_setreuid32 203 -#define __NR_setregid32 204 -#define __NR_getgroups32 205 -#define __NR_setgroups32 206 -#define __NR_fchown32 207 -#define __NR_setresuid32 208 -#define __NR_getresuid32 209 -#define __NR_setresgid32 210 -#define __NR_getresgid32 211 -#define __NR_lchown32 212 -#define __NR_setuid32 213 -#define __NR_setgid32 214 -#define __NR_setfsuid32 215 -#define __NR_setfsgid32 216 -#define __NR_pivot_root 217 -#define __NR_getdents64 220 -#define __NR_gettid 221 -#define __NR_tkill 222 -#define __NR_setxattr 223 -#define __NR_lsetxattr 224 -#define __NR_fsetxattr 225 -#define __NR_getxattr 226 -#define __NR_lgetxattr 227 -#define __NR_fgetxattr 228 -#define __NR_listxattr 229 -#define __NR_llistxattr 230 -#define __NR_flistxattr 231 -#define __NR_removexattr 232 -#define __NR_lremovexattr 233 -#define __NR_fremovexattr 234 -#define __NR_futex 235 -#define __NR_sendfile64 236 -#define __NR_mincore 237 -#define __NR_madvise 238 -#define __NR_fcntl64 239 -#define __NR_readahead 240 -#define __NR_io_setup 241 -#define __NR_io_destroy 242 -#define __NR_io_getevents 243 -#define __NR_io_submit 244 -#define __NR_io_cancel 245 -#define __NR_fadvise64 246 -#define __NR_exit_group 247 -#define __NR_lookup_dcookie 248 -#define __NR_epoll_create 249 -#define __NR_epoll_ctl 250 -#define __NR_epoll_wait 251 -#define __NR_remap_file_pages 252 -#define __NR_set_tid_address 253 -#define __NR_timer_create 254 -#define __NR_timer_settime 255 -#define __NR_timer_gettime 256 -#define __NR_timer_getoverrun 257 -#define __NR_timer_delete 258 -#define __NR_clock_settime 259 -#define __NR_clock_gettime 260 -#define __NR_clock_getres 261 -#define __NR_clock_nanosleep 262 -#define __NR_statfs64 263 -#define __NR_fstatfs64 264 -#define __NR_tgkill 265 -#define __NR_utimes 266 -#define __NR_fadvise64_64 267 -#define __NR_mbind 268 -#define __NR_get_mempolicy 269 -#define __NR_set_mempolicy 270 -#define __NR_mq_open 271 -#define __NR_mq_unlink 272 -#define __NR_mq_timedsend 273 -#define __NR_mq_timedreceive 274 -#define __NR_mq_notify 275 -#define __NR_mq_getsetattr 276 -#define __NR_waitid 277 -#define __NR_vserver 278 -#define __NR_add_key 279 -#define __NR_request_key 280 -#define __NR_keyctl 281 -#define __NR_ioprio_set 282 -#define __NR_ioprio_get 283 -#define __NR_inotify_init 284 -#define __NR_inotify_add_watch 285 -#define __NR_inotify_rm_watch 286 -#define __NR_migrate_pages 287 -#define __NR_openat 288 -#define __NR_mkdirat 289 -#define __NR_mknodat 290 -#define __NR_fchownat 291 -#define __NR_futimesat 292 -#define __NR_fstatat64 293 -#define __NR_unlinkat 294 -#define __NR_renameat 295 -#define __NR_linkat 296 -#define __NR_symlinkat 297 -#define __NR_readlinkat 298 -#define __NR_fchmodat 299 -#define __NR_faccessat 300 -#define __NR_pselect6 301 -#define __NR_ppoll 302 -#define __NR_unshare 303 -#define __NR_set_robust_list 304 -#define __NR_get_robust_list 305 -#define __NR_splice 306 -#define __NR_sync_file_range 307 -#define __NR_tee 308 -#define __NR_vmsplice 309 -#define __NR_move_pages 310 -#define __NR_sched_setaffinity 311 -#define __NR_sched_getaffinity 312 -#define __NR_kexec_load 313 -#define __NR_getcpu 314 -#define __NR_epoll_pwait 315 -#define __NR_utimensat 316 -#define __NR_signalfd 317 -#define __NR_timerfd_create 318 -#define __NR_eventfd 319 -#define __NR_fallocate 320 -#define __NR_timerfd_settime 321 -#define __NR_timerfd_gettime 322 -#define __NR_signalfd4 323 -#define __NR_eventfd2 324 -#define __NR_epoll_create1 325 -#define __NR_dup3 326 -#define __NR_pipe2 327 -#define __NR_inotify_init1 328 - -#ifdef __KERNEL__ - -#define NR_syscalls 329 - -#define __ARCH_WANT_IPC_PARSE_VERSION -#define __ARCH_WANT_OLD_READDIR -#define __ARCH_WANT_OLD_STAT -#define __ARCH_WANT_STAT64 -#define __ARCH_WANT_SYS_ALARM -#define __ARCH_WANT_SYS_GETHOSTNAME -#define __ARCH_WANT_SYS_PAUSE -#define __ARCH_WANT_SYS_SGETMASK -#define __ARCH_WANT_SYS_SIGNAL -#define __ARCH_WANT_SYS_TIME -#define __ARCH_WANT_SYS_UTIME -#define __ARCH_WANT_SYS_WAITPID -#define __ARCH_WANT_SYS_SOCKETCALL -#define __ARCH_WANT_SYS_FADVISE64 -#define __ARCH_WANT_SYS_GETPGRP -#define __ARCH_WANT_SYS_LLSEEK -#define __ARCH_WANT_SYS_NICE -#define __ARCH_WANT_SYS_OLD_GETRLIMIT -#define __ARCH_WANT_SYS_OLDUMOUNT -#define __ARCH_WANT_SYS_SIGPENDING -#define __ARCH_WANT_SYS_SIGPROCMASK -#define __ARCH_WANT_SYS_RT_SIGACTION - -/* whitelist for checksyscalls */ -#define __IGNORE_restart_syscall - -/* - * "Conditional" syscalls - * - * What we want is __attribute__((weak,alias("sys_ni_syscall"))), - * but it doesn't work on all toolchains, so we just do it by hand - */ -#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") - -#endif /* __KERNEL__ */ -#endif /* _ASM_M68K_UNISTD_H_ */ diff --git a/include/asm-m68k/user.h b/include/asm-m68k/user.h deleted file mode 100644 index f1f478d6e05..00000000000 --- a/include/asm-m68k/user.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef _M68K_USER_H -#define _M68K_USER_H - -/* Core file format: The core file is written in such a way that gdb - can understand it and provide useful information to the user (under - linux we use the 'trad-core' bfd). There are quite a number of - obstacles to being able to view the contents of the floating point - registers, and until these are solved you will not be able to view the - contents of them. Actually, you can read in the core file and look at - the contents of the user struct to find out what the floating point - registers contain. - The actual file contents are as follows: - UPAGE: 1 page consisting of a user struct that tells gdb what is present - in the file. Directly after this is a copy of the task_struct, which - is currently not used by gdb, but it may come in useful at some point. - All of the registers are stored as part of the upage. The upage should - always be only one page. - DATA: The data area is stored. We use current->end_text to - current->brk to pick up all of the user variables, plus any memory - that may have been malloced. No attempt is made to determine if a page - is demand-zero or if a page is totally unused, we just cover the entire - range. All of the addresses are rounded in such a way that an integral - number of pages is written. - STACK: We need the stack information in order to get a meaningful - backtrace. We need to write the data from (esp) to - current->start_stack, so we round each of these off in order to be able - to write an integer number of pages. - The minimum core file size is 3 pages, or 12288 bytes. -*/ - -struct user_m68kfp_struct { - unsigned long fpregs[8*3]; /* fp0-fp7 registers */ - unsigned long fpcntl[3]; /* fp control regs */ -}; - -/* This is the old layout of "struct pt_regs" as of Linux 1.x, and - is still the layout used by user (the new pt_regs doesn't have - all registers). */ -struct user_regs_struct { - long d1,d2,d3,d4,d5,d6,d7; - long a0,a1,a2,a3,a4,a5,a6; - long d0; - long usp; - long orig_d0; - short stkadj; - short sr; - long pc; - short fmtvec; - short __fill; -}; - - -/* When the kernel dumps core, it starts by dumping the user struct - - this will be used by gdb to figure out where the data and stack segments - are within the file, and what virtual addresses to use. */ -struct user{ -/* We start with the registers, to mimic the way that "memory" is returned - from the ptrace(3,...) function. */ - struct user_regs_struct regs; /* Where the registers are actually stored */ -/* ptrace does not yet supply these. Someday.... */ - int u_fpvalid; /* True if math co-processor being used. */ - /* for this mess. Not yet used. */ - struct user_m68kfp_struct m68kfp; /* Math Co-processor registers. */ -/* The rest of this junk is to help gdb figure out what goes where */ - unsigned long int u_tsize; /* Text segment size (pages). */ - unsigned long int u_dsize; /* Data segment size (pages). */ - unsigned long int u_ssize; /* Stack segment size (pages). */ - unsigned long start_code; /* Starting virtual address of text. */ - unsigned long start_stack; /* Starting virtual address of stack area. - This is actually the bottom of the stack, - the top of the stack is always found in the - esp register. */ - long int signal; /* Signal that caused the core dump. */ - int reserved; /* No longer used */ - unsigned long u_ar0; /* Used by gdb to help find the values for */ - /* the registers. */ - struct user_m68kfp_struct* u_fpstate; /* Math Co-processor pointer. */ - unsigned long magic; /* To uniquely identify a core file */ - char u_comm[32]; /* User command that was responsible */ -}; -#define NBPG 4096 -#define UPAGES 1 -#define HOST_TEXT_START_ADDR (u.start_code) -#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) - -#endif diff --git a/include/asm-m68k/virtconvert.h b/include/asm-m68k/virtconvert.h deleted file mode 100644 index 22ab05c9c52..00000000000 --- a/include/asm-m68k/virtconvert.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef __VIRT_CONVERT__ -#define __VIRT_CONVERT__ - -/* - * Macros used for converting between virtual and physical mappings. - */ - -#ifdef __KERNEL__ - -#include -#include -#include -#include - -/* - * Change virtual addresses to physical addresses and vv. - */ -static inline unsigned long virt_to_phys(void *address) -{ - return __pa(address); -} - -static inline void *phys_to_virt(unsigned long address) -{ - return __va(address); -} - -/* Permanent address of a page. */ -#ifdef CONFIG_SINGLE_MEMORY_CHUNK -#define page_to_phys(page) \ - __pa(PAGE_OFFSET + (((page) - pg_data_map[0].node_mem_map) << PAGE_SHIFT)) -#else -#define page_to_phys(_page) ({ \ - struct page *__page = _page; \ - struct pglist_data *pgdat; \ - pgdat = pg_data_table[page_to_nid(__page)]; \ - page_to_pfn(__page) << PAGE_SHIFT; \ -}) -#endif - -/* - * IO bus memory addresses are 1:1 with the physical address, - */ -#define virt_to_bus virt_to_phys -#define bus_to_virt phys_to_virt - -#endif -#endif diff --git a/include/asm-m68k/xor.h b/include/asm-m68k/xor.h deleted file mode 100644 index c82eb12a5b1..00000000000 --- a/include/asm-m68k/xor.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-m68k/zorro.h b/include/asm-m68k/zorro.h deleted file mode 100644 index 5ce97c22b58..00000000000 --- a/include/asm-m68k/zorro.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef _ASM_M68K_ZORRO_H -#define _ASM_M68K_ZORRO_H - -#include - -#define z_readb raw_inb -#define z_readw raw_inw -#define z_readl raw_inl - -#define z_writeb raw_outb -#define z_writew raw_outw -#define z_writel raw_outl - -#define z_memset_io(a,b,c) memset((void *)(a),(b),(c)) -#define z_memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) -#define z_memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) - -static inline void __iomem *z_remap_nocache_ser(unsigned long physaddr, - unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); -} - -static inline void __iomem *z_remap_nocache_nonser(unsigned long physaddr, - unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_NOCACHE_NONSER); -} - -static inline void __iomem *z_remap_writethrough(unsigned long physaddr, - unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_WRITETHROUGH); -} -static inline void __iomem *z_remap_fullcache(unsigned long physaddr, - unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_FULL_CACHING); -} - -#define z_unmap iounmap -#define z_iounmap iounmap -#define z_ioremap z_remap_nocache_ser - -#endif /* _ASM_M68K_ZORRO_H */ -- cgit From a3c6018e565dc07cf3738ace6bbe412f97b1bba8 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 16 Jan 2009 11:59:33 +0000 Subject: x86: fix assumed to be contiguous leaf page tables for kmap_atomic region (take 2) Debugging and original patch from Nick Piggin The early fixmap pmd entry inserted at the very top of the KVA is causing the subsequent fixmap mapping code to not provide physically linear pte pages over the kmap atomic portion of the fixmap (which relies on said property to calculate pte addresses). This has caused weird boot failures in kmap_atomic much later in the boot process (initial userspace faults) on a 32-bit PAE system with a larger number of CPUs (smaller CPU counts tend not to run over into the next page so don't show up the problem). Solve this by attempting to clear out the page table, and copy any of its entries to the new one. Also, add a bug if a nonlinear condition is encountered and can't be resolved, which might save some hours of debugging if this fragile scheme ever breaks again... Once we have such logic, we can also use it to eliminate the early ioremap trickery around the page table setup for the fixmap area. This also fixes potential issues with FIX_* entries sharing the leaf page table with the early ioremap ones getting discarded by early_ioremap_clear() and not restored by early_ioremap_reset(). It at once eliminates the temporary (and configuration, namely NR_CPUS, dependent) unavailability of early fixed mappings during the time the fixmap area page tables get constructed. Finally, also replace the hard coded calculation of the initial table space needed for the fixmap area with a proper one, allowing kernels configured for large CPU counts to actually boot. Based-on: Nick Piggin Signed-off-by: Jan Beulich Signed-off-by: Ingo Molnar --- arch/x86/include/asm/io.h | 1 - arch/x86/mm/init_32.c | 48 ++++++++++++++++++++++++++++++++++++++++++++--- arch/x86/mm/ioremap.c | 25 ------------------------ 3 files changed, 45 insertions(+), 29 deletions(-) diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index 05cfed4485f..1dbbdf4be9b 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h @@ -99,7 +99,6 @@ extern void __iomem *ioremap_wc(unsigned long offset, unsigned long size); * A boot-time mapping is currently limited to at most 16 pages. */ extern void early_ioremap_init(void); -extern void early_ioremap_clear(void); extern void early_ioremap_reset(void); extern void __iomem *early_ioremap(unsigned long offset, unsigned long size); extern void __iomem *early_memremap(unsigned long offset, unsigned long size); diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index 88f1b10de3b..2cef0507441 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c @@ -138,6 +138,47 @@ static pte_t * __init one_page_table_init(pmd_t *pmd) return pte_offset_kernel(pmd, 0); } +static pte_t *__init page_table_kmap_check(pte_t *pte, pmd_t *pmd, + unsigned long vaddr, pte_t *lastpte) +{ +#ifdef CONFIG_HIGHMEM + /* + * Something (early fixmap) may already have put a pte + * page here, which causes the page table allocation + * to become nonlinear. Attempt to fix it, and if it + * is still nonlinear then we have to bug. + */ + int pmd_idx_kmap_begin = fix_to_virt(FIX_KMAP_END) >> PMD_SHIFT; + int pmd_idx_kmap_end = fix_to_virt(FIX_KMAP_BEGIN) >> PMD_SHIFT; + + if (pmd_idx_kmap_begin != pmd_idx_kmap_end + && (vaddr >> PMD_SHIFT) >= pmd_idx_kmap_begin + && (vaddr >> PMD_SHIFT) <= pmd_idx_kmap_end + && ((__pa(pte) >> PAGE_SHIFT) < table_start + || (__pa(pte) >> PAGE_SHIFT) >= table_end)) { + pte_t *newpte; + int i; + + BUG_ON(after_init_bootmem); + newpte = alloc_low_page(); + for (i = 0; i < PTRS_PER_PTE; i++) + set_pte(newpte + i, pte[i]); + + paravirt_alloc_pte(&init_mm, __pa(newpte) >> PAGE_SHIFT); + set_pmd(pmd, __pmd(__pa(newpte)|_PAGE_TABLE)); + BUG_ON(newpte != pte_offset_kernel(pmd, 0)); + __flush_tlb_all(); + + paravirt_release_pte(__pa(pte) >> PAGE_SHIFT); + pte = newpte; + } + BUG_ON(vaddr < fix_to_virt(FIX_KMAP_BEGIN - 1) + && vaddr > fix_to_virt(FIX_KMAP_END) + && lastpte && lastpte + PTRS_PER_PTE != pte); +#endif + return pte; +} + /* * This function initializes a certain range of kernel virtual memory * with new bootmem page tables, everywhere page tables are missing in @@ -154,6 +195,7 @@ page_table_range_init(unsigned long start, unsigned long end, pgd_t *pgd_base) unsigned long vaddr; pgd_t *pgd; pmd_t *pmd; + pte_t *pte = NULL; vaddr = start; pgd_idx = pgd_index(vaddr); @@ -165,7 +207,8 @@ page_table_range_init(unsigned long start, unsigned long end, pgd_t *pgd_base) pmd = pmd + pmd_index(vaddr); for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) { - one_page_table_init(pmd); + pte = page_table_kmap_check(one_page_table_init(pmd), + pmd, vaddr, pte); vaddr += PMD_SIZE; } @@ -508,7 +551,6 @@ static void __init early_ioremap_page_table_range_init(pgd_t *pgd_base) * Fixed mappings, only the page table structure has to be * created - mappings will be set by set_fixmap(): */ - early_ioremap_clear(); vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; end = (FIXADDR_TOP + PMD_SIZE - 1) & PMD_MASK; page_table_range_init(vaddr, end, pgd_base); @@ -801,7 +843,7 @@ static void __init find_early_table_space(unsigned long end, int use_pse) tables += PAGE_ALIGN(ptes * sizeof(pte_t)); /* for fixmap */ - tables += PAGE_SIZE * 2; + tables += PAGE_ALIGN(__end_of_fixed_addresses * sizeof(pte_t)); /* * RED-PEN putting page tables only on node 0 could diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index bd85d42819e..af750ab973b 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -557,34 +557,9 @@ void __init early_ioremap_init(void) } } -void __init early_ioremap_clear(void) -{ - pmd_t *pmd; - - if (early_ioremap_debug) - printk(KERN_INFO "early_ioremap_clear()\n"); - - pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)); - pmd_clear(pmd); - paravirt_release_pte(__pa(bm_pte) >> PAGE_SHIFT); - __flush_tlb_all(); -} - void __init early_ioremap_reset(void) { - enum fixed_addresses idx; - unsigned long addr, phys; - pte_t *pte; - after_paging_init = 1; - for (idx = FIX_BTMAP_BEGIN; idx >= FIX_BTMAP_END; idx--) { - addr = fix_to_virt(idx); - pte = early_ioremap_pte(addr); - if (pte_present(*pte)) { - phys = pte_val(*pte) & PAGE_MASK; - set_fixmap(idx, phys); - } - } } static void __init __early_set_fixmap(enum fixed_addresses idx, -- cgit From 7de6883faad71e3a253d55b9e1a47b89ebce0a31 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 13 Jan 2009 20:41:34 +0900 Subject: x86: fix pda_to_op() There's no instruction to move a 64bit immediate into memory location. Drop "i". Signed-off-by: Tejun Heo Signed-off-by: Ingo Molnar --- arch/x86/include/asm/pda.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h index 2fbfff88df3..cbd3f48a832 100644 --- a/arch/x86/include/asm/pda.h +++ b/arch/x86/include/asm/pda.h @@ -78,7 +78,7 @@ do { \ case 8: \ asm(op "q %1,%%gs:%c2": \ "+m" (_proxy_pda.field) : \ - "ri" ((T__)val), \ + "r" ((T__)val), \ "i"(pda_offset(field))); \ break; \ default: \ -- cgit From f10fcd47120e80f66665567dbe17f5071c7aef52 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 13 Jan 2009 20:41:34 +0900 Subject: x86: make early_per_cpu() a lvalue and use it Make early_per_cpu() a lvalue as per_cpu() is and use it where applicable. Signed-off-by: Tejun Heo Signed-off-by: Ingo Molnar --- arch/x86/include/asm/percpu.h | 6 +++--- arch/x86/include/asm/topology.h | 5 +---- arch/x86/kernel/apic.c | 13 ++----------- 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index ece72053ba6..df644f3e53e 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h @@ -195,9 +195,9 @@ do { \ #define early_per_cpu_ptr(_name) (_name##_early_ptr) #define early_per_cpu_map(_name, _idx) (_name##_early_map[_idx]) #define early_per_cpu(_name, _cpu) \ - (early_per_cpu_ptr(_name) ? \ - early_per_cpu_ptr(_name)[_cpu] : \ - per_cpu(_name, _cpu)) + *(early_per_cpu_ptr(_name) ? \ + &early_per_cpu_ptr(_name)[_cpu] : \ + &per_cpu(_name, _cpu)) #else /* !CONFIG_SMP */ #define DEFINE_EARLY_PER_CPU(_type, _name, _initvalue) \ diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index 4e2f2e0aab2..87ca3fd86e8 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h @@ -102,10 +102,7 @@ static inline int cpu_to_node(int cpu) /* Same function but used if called before per_cpu areas are setup */ static inline int early_cpu_to_node(int cpu) { - if (early_per_cpu_ptr(x86_cpu_to_node_map)) - return early_per_cpu_ptr(x86_cpu_to_node_map)[cpu]; - - return per_cpu(x86_cpu_to_node_map, cpu); + return early_per_cpu(x86_cpu_to_node_map, cpu); } /* Returns a pointer to the cpumask of CPUs on Node 'node'. */ diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c index 38d6aab2358..48578795583 100644 --- a/arch/x86/kernel/apic.c +++ b/arch/x86/kernel/apic.c @@ -1877,17 +1877,8 @@ void __cpuinit generic_processor_info(int apicid, int version) #endif #if defined(CONFIG_X86_SMP) || defined(CONFIG_X86_64) - /* are we being called early in kernel startup? */ - if (early_per_cpu_ptr(x86_cpu_to_apicid)) { - u16 *cpu_to_apicid = early_per_cpu_ptr(x86_cpu_to_apicid); - u16 *bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid); - - cpu_to_apicid[cpu] = apicid; - bios_cpu_apicid[cpu] = apicid; - } else { - per_cpu(x86_cpu_to_apicid, cpu) = apicid; - per_cpu(x86_bios_cpu_apicid, cpu) = apicid; - } + early_per_cpu(x86_cpu_to_apicid, cpu) = apicid; + early_per_cpu(x86_bios_cpu_apicid, cpu) = apicid; #endif set_cpu_possible(cpu, true); -- cgit From c90aa894f0240084f2c6e42e2333b211d6cfe2b2 Mon Sep 17 00:00:00 2001 From: Mike Travis Date: Tue, 13 Jan 2009 20:41:34 +0900 Subject: x86: cleanup early setup_percpu references [ Based on original patch from Christoph Lameter and Mike Travis. ] * Ruggedize some calls in setup_percpu.c to prevent mishaps in early calls, particularly for non-critical functions. * Cleanup DEBUG_PER_CPU_MAPS usages and some comments. Signed-off-by: Mike Travis Signed-off-by: Tejun Heo Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_percpu.c | 56 ++++++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index bf63de72b64..56c63ac62b1 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -15,6 +15,12 @@ #include #include +#ifdef CONFIG_DEBUG_PER_CPU_MAPS +# define DBG(x...) printk(KERN_DEBUG x) +#else +# define DBG(x...) +#endif + #ifdef CONFIG_X86_LOCAL_APIC unsigned int num_processors; unsigned disabled_cpus __cpuinitdata; @@ -27,31 +33,39 @@ unsigned int max_physical_apicid; physid_mask_t phys_cpu_present_map; #endif -/* map cpu index to physical APIC ID */ +/* + * Map cpu index to physical APIC ID + */ DEFINE_EARLY_PER_CPU(u16, x86_cpu_to_apicid, BAD_APICID); DEFINE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid, BAD_APICID); EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_apicid); EXPORT_EARLY_PER_CPU_SYMBOL(x86_bios_cpu_apicid); #if defined(CONFIG_NUMA) && defined(CONFIG_X86_64) -#define X86_64_NUMA 1 +#define X86_64_NUMA 1 /* (used later) */ -/* map cpu index to node index */ +/* + * Map cpu index to node index + */ DEFINE_EARLY_PER_CPU(int, x86_cpu_to_node_map, NUMA_NO_NODE); EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_node_map); -/* which logical CPUs are on which nodes */ +/* + * Which logical CPUs are on which nodes + */ cpumask_t *node_to_cpumask_map; EXPORT_SYMBOL(node_to_cpumask_map); -/* setup node_to_cpumask_map */ +/* + * Setup node_to_cpumask_map + */ static void __init setup_node_to_cpumask_map(void); #else static inline void setup_node_to_cpumask_map(void) { } #endif -#if defined(CONFIG_HAVE_SETUP_PER_CPU_AREA) && defined(CONFIG_X86_SMP) +#ifdef CONFIG_HAVE_SETUP_PER_CPU_AREA /* * Copy data used in early init routines from the initial arrays to the * per cpu data areas. These arrays then become expendable and the @@ -200,6 +214,8 @@ void __init setup_per_cpu_areas(void) #endif per_cpu_offset(cpu) = ptr - __per_cpu_start; memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); + + DBG("PERCPU: cpu %4d %p\n", cpu, ptr); } /* Setup percpu data maps */ @@ -221,6 +237,7 @@ void __init setup_per_cpu_areas(void) * Requires node_possible_map to be valid. * * Note: node_to_cpumask() is not valid until after this is done. + * (Use CONFIG_DEBUG_PER_CPU_MAPS to check this.) */ static void __init setup_node_to_cpumask_map(void) { @@ -236,6 +253,7 @@ static void __init setup_node_to_cpumask_map(void) /* allocate the map */ map = alloc_bootmem_low(nr_node_ids * sizeof(cpumask_t)); + DBG("node_to_cpumask_map at %p for %d nodes\n", map, nr_node_ids); pr_debug("Node to cpumask map at %p for %d nodes\n", map, nr_node_ids); @@ -248,17 +266,23 @@ void __cpuinit numa_set_node(int cpu, int node) { int *cpu_to_node_map = early_per_cpu_ptr(x86_cpu_to_node_map); - if (cpu_pda(cpu) && node != NUMA_NO_NODE) - cpu_pda(cpu)->nodenumber = node; - - if (cpu_to_node_map) + /* early setting, no percpu area yet */ + if (cpu_to_node_map) { cpu_to_node_map[cpu] = node; + return; + } - else if (per_cpu_offset(cpu)) - per_cpu(x86_cpu_to_node_map, cpu) = node; +#ifdef CONFIG_DEBUG_PER_CPU_MAPS + if (cpu >= nr_cpu_ids || !per_cpu_offset(cpu)) { + printk(KERN_ERR "numa_set_node: invalid cpu# (%d)\n", cpu); + dump_stack(); + return; + } +#endif + per_cpu(x86_cpu_to_node_map, cpu) = node; - else - pr_debug("Setting node for non-present cpu %d\n", cpu); + if (node != NUMA_NO_NODE) + cpu_pda(cpu)->nodenumber = node; } void __cpuinit numa_clear_node(int cpu) @@ -275,7 +299,7 @@ void __cpuinit numa_add_cpu(int cpu) void __cpuinit numa_remove_cpu(int cpu) { - cpu_clear(cpu, node_to_cpumask_map[cpu_to_node(cpu)]); + cpu_clear(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]); } #else /* CONFIG_DEBUG_PER_CPU_MAPS */ @@ -285,7 +309,7 @@ void __cpuinit numa_remove_cpu(int cpu) */ static void __cpuinit numa_set_cpumask(int cpu, int enable) { - int node = cpu_to_node(cpu); + int node = early_cpu_to_node(cpu); cpumask_t *mask; char buf[64]; -- cgit From a698c823e15149941b0f0281527d0c0d1daf2639 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 13 Jan 2009 20:41:35 +0900 Subject: x86: make vmlinux_32.lds.S use PERCPU() macro Make vmlinux_32.lds.S use the generic PERCPU() macro instead of open coding it. This will ease future changes. Signed-off-by: Tejun Heo Signed-off-by: Ingo Molnar --- arch/x86/kernel/vmlinux_32.lds.S | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/arch/x86/kernel/vmlinux_32.lds.S b/arch/x86/kernel/vmlinux_32.lds.S index 82c67559dde..3eba7f7bac0 100644 --- a/arch/x86/kernel/vmlinux_32.lds.S +++ b/arch/x86/kernel/vmlinux_32.lds.S @@ -178,14 +178,7 @@ SECTIONS __initramfs_end = .; } #endif - . = ALIGN(PAGE_SIZE); - .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { - __per_cpu_start = .; - *(.data.percpu.page_aligned) - *(.data.percpu) - *(.data.percpu.shared_aligned) - __per_cpu_end = .; - } + PERCPU(PAGE_SIZE) . = ALIGN(PAGE_SIZE); /* freed after init ends here */ -- cgit From 3e5d8f978435bb9ba4dfe3f4514e65e7885db1a9 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 13 Jan 2009 20:41:35 +0900 Subject: x86: make percpu symbols zerobased on SMP [ Based on original patch from Christoph Lameter and Mike Travis. ] This patch makes percpu symbols zerobased on x86_64 SMP by adding PERCPU_VADDR() to vmlinux.lds.h which helps setting explicit vaddr on the percpu output section and using it in vmlinux_64.lds.S. A new PHDR is added as existing ones cannot contain sections near address zero. PERCPU_VADDR() also adds a new symbol __per_cpu_load which always points to the vaddr of the loaded percpu data.init region. The following adjustments have been made to accomodate the address change. * code to locate percpu gdt_page in head_64.S is updated to add the load address to the gdt_page offset. * __per_cpu_load is used in places where access to the init data area is necessary. * pda->data_offset is initialized soon after C code is entered as zero value doesn't work anymore. This patch is mostly taken from Mike Travis' "x86_64: Base percpu variables at zero" patch. Signed-off-by: Tejun Heo Signed-off-by: Ingo Molnar --- arch/x86/kernel/head64.c | 2 ++ arch/x86/kernel/head_64.S | 24 +++++++++++++++++- arch/x86/kernel/setup_percpu.c | 2 +- arch/x86/kernel/vmlinux_64.lds.S | 17 ++++++++++++- include/asm-generic/sections.h | 2 +- include/asm-generic/vmlinux.lds.h | 51 ++++++++++++++++++++++++++++++++++----- 6 files changed, 88 insertions(+), 10 deletions(-) diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index b9a4d8c4b93..bc2900ca82c 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -44,6 +44,8 @@ void __init x86_64_init_pda(void) { _cpu_pda = __cpu_pda; cpu_pda(0) = &_boot_cpu_pda; + cpu_pda(0)->data_offset = + (unsigned long)(__per_cpu_load - __per_cpu_start); pda_init(0); } diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 0e275d49556..7ee0363871e 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -204,6 +204,23 @@ ENTRY(secondary_startup_64) pushq $0 popfq +#ifdef CONFIG_SMP + /* + * early_gdt_base should point to the gdt_page in static percpu init + * data area. Computing this requires two symbols - __per_cpu_load + * and per_cpu__gdt_page. As linker can't do no such relocation, do + * it by hand. As early_gdt_descr is manipulated by C code for + * secondary CPUs, this should be done only once for the boot CPU + * when early_gdt_descr_base contains zero. + */ + movq early_gdt_descr_base(%rip), %rax + testq %rax, %rax + jnz 1f + movq $__per_cpu_load, %rax + addq $per_cpu__gdt_page, %rax + movq %rax, early_gdt_descr_base(%rip) +1: +#endif /* * We must switch to a new descriptor in kernel space for the GDT * because soon the kernel won't have access anymore to the userspace @@ -401,7 +418,12 @@ NEXT_PAGE(level2_spare_pgt) .globl early_gdt_descr early_gdt_descr: .word GDT_ENTRIES*8-1 - .quad per_cpu__gdt_page +#ifdef CONFIG_SMP +early_gdt_descr_base: + .quad 0x0000000000000000 +#else + .quad per_cpu__gdt_page +#endif ENTRY(phys_base) /* This must match the first entry in level2_kernel_pgt */ diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 56c63ac62b1..44845842e72 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -213,7 +213,7 @@ void __init setup_per_cpu_areas(void) } #endif per_cpu_offset(cpu) = ptr - __per_cpu_start; - memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); + memcpy(ptr, __per_cpu_load, __per_cpu_end - __per_cpu_start); DBG("PERCPU: cpu %4d %p\n", cpu, ptr); } diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S index 1a614c0e6be..f50280db0df 100644 --- a/arch/x86/kernel/vmlinux_64.lds.S +++ b/arch/x86/kernel/vmlinux_64.lds.S @@ -19,6 +19,9 @@ PHDRS { data PT_LOAD FLAGS(7); /* RWE */ user PT_LOAD FLAGS(7); /* RWE */ data.init PT_LOAD FLAGS(7); /* RWE */ +#ifdef CONFIG_SMP + percpu PT_LOAD FLAGS(7); /* RWE */ +#endif note PT_NOTE FLAGS(0); /* ___ */ } SECTIONS @@ -208,14 +211,26 @@ SECTIONS __initramfs_end = .; #endif +#ifdef CONFIG_SMP + /* + * percpu offsets are zero-based on SMP. PERCPU_VADDR() changes the + * output PHDR, so the next output section - __data_nosave - should + * switch it back to data.init. + */ + . = ALIGN(PAGE_SIZE); + PERCPU_VADDR(0, :percpu) +#else PERCPU(PAGE_SIZE) +#endif . = ALIGN(PAGE_SIZE); __init_end = .; . = ALIGN(PAGE_SIZE); __nosave_begin = .; - .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) } + .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { + *(.data.nosave) + } :data.init /* switch back to data.init, see PERCPU_VADDR() above */ . = ALIGN(PAGE_SIZE); __nosave_end = .; diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h index 79a7ff925bf..4ce48e87853 100644 --- a/include/asm-generic/sections.h +++ b/include/asm-generic/sections.h @@ -9,7 +9,7 @@ extern char __bss_start[], __bss_stop[]; extern char __init_begin[], __init_end[]; extern char _sinittext[], _einittext[]; extern char _end[]; -extern char __per_cpu_start[], __per_cpu_end[]; +extern char __per_cpu_load[], __per_cpu_start[], __per_cpu_end[]; extern char __kprobes_text_start[], __kprobes_text_end[]; extern char __initdata_begin[], __initdata_end[]; extern char __start_rodata[], __end_rodata[]; diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index c61fab1dd2f..fc2f55f2dcd 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -430,12 +430,51 @@ *(.initcall7.init) \ *(.initcall7s.init) -#define PERCPU(align) \ - . = ALIGN(align); \ - VMLINUX_SYMBOL(__per_cpu_start) = .; \ - .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { \ +#define PERCPU_PROLOG(vaddr) \ + VMLINUX_SYMBOL(__per_cpu_load) = .; \ + .data.percpu vaddr : AT(__per_cpu_load - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__per_cpu_start) = .; + +#define PERCPU_EPILOG(phdr) \ + VMLINUX_SYMBOL(__per_cpu_end) = .; \ + } phdr \ + . = __per_cpu_load + SIZEOF(.data.percpu); + +/** + * PERCPU_VADDR - define output section for percpu area + * @vaddr: explicit base address (optional) + * @phdr: destination PHDR (optional) + * + * Macro which expands to output section for percpu area. If @vaddr + * is not blank, it specifies explicit base address and all percpu + * symbols will be offset from the given address. If blank, @vaddr + * always equals @laddr + LOAD_OFFSET. + * + * @phdr defines the output PHDR to use if not blank. Be warned that + * output PHDR is sticky. If @phdr is specified, the next output + * section in the linker script will go there too. @phdr should have + * a leading colon. + * + * This macro defines three symbols, __per_cpu_load, __per_cpu_start + * and __per_cpu_end. The first one is the vaddr of loaded percpu + * init data. __per_cpu_start equals @vaddr and __per_cpu_end is the + * end offset. + */ +#define PERCPU_VADDR(vaddr, phdr) \ + PERCPU_PROLOG(vaddr) \ *(.data.percpu.page_aligned) \ *(.data.percpu) \ *(.data.percpu.shared_aligned) \ - } \ - VMLINUX_SYMBOL(__per_cpu_end) = .; + PERCPU_EPILOG(phdr) + +/** + * PERCPU - define output section for percpu area, simple version + * @align: required alignment + * + * Align to @align and outputs output section for percpu area. This + * macro doesn't maniuplate @vaddr or @phdr and __per_cpu_load and + * __per_cpu_start will be identical. + */ +#define PERCPU(align) \ + . = ALIGN(align); \ + PERCPU_VADDR( , ) -- cgit From f32ff5388d86518c0375ccdb330d3b459b9c405e Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 13 Jan 2009 20:41:35 +0900 Subject: x86: load pointer to pda into %gs while brining up a CPU [ Based on original patch from Christoph Lameter and Mike Travis. ] CPU startup code in head_64.S loaded address of a zero page into %gs for temporary use till pda is loaded but address to the actual pda is available at the point. Load the real address directly instead. This will help unifying percpu and pda handling later on. This patch is mostly taken from Mike Travis' "x86_64: Fold pda into per cpu area" patch. Signed-off-by: Tejun Heo --- arch/x86/include/asm/trampoline.h | 1 + arch/x86/kernel/acpi/sleep.c | 1 + arch/x86/kernel/head64.c | 4 ++-- arch/x86/kernel/head_64.S | 15 ++++++++++----- arch/x86/kernel/smpboot.c | 1 + 5 files changed, 15 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/trampoline.h b/arch/x86/include/asm/trampoline.h index 780ba0ab94f..90f06c25221 100644 --- a/arch/x86/include/asm/trampoline.h +++ b/arch/x86/include/asm/trampoline.h @@ -13,6 +13,7 @@ extern unsigned char *trampoline_base; extern unsigned long init_rsp; extern unsigned long initial_code; +extern unsigned long initial_gs; #define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE) #define TRAMPOLINE_BASE 0x6000 diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 707c1f6f95f..9ff67f8dc2c 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c @@ -101,6 +101,7 @@ int acpi_save_state_mem(void) stack_start.sp = temp_stack + sizeof(temp_stack); early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(smp_processor_id()); + initial_gs = (unsigned long)cpu_pda(smp_processor_id()); #endif initial_code = (unsigned long)wakeup_long64; saved_magic = 0x123456789abcdef0; diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index bc2900ca82c..76ffba2aa66 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -26,8 +26,8 @@ #include #include -/* boot cpu pda */ -static struct x8664_pda _boot_cpu_pda; +/* boot cpu pda, referenced by head_64.S to initialize %gs for boot CPU */ +struct x8664_pda _boot_cpu_pda; #ifdef CONFIG_SMP /* diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 7ee0363871e..2f0ab008988 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -243,12 +243,15 @@ ENTRY(secondary_startup_64) movl %eax,%fs movl %eax,%gs - /* - * Setup up a dummy PDA. this is just for some early bootup code - * that does in_interrupt() - */ + /* Set up %gs. + * + * %gs should point to the pda. For initial boot, make %gs point + * to the _boot_cpu_pda in data section. For a secondary CPU, + * initial_gs should be set to its pda address before the CPU runs + * this code. + */ movl $MSR_GS_BASE,%ecx - movq $empty_zero_page,%rax + movq initial_gs(%rip),%rax movq %rax,%rdx shrq $32,%rdx wrmsr @@ -274,6 +277,8 @@ ENTRY(secondary_startup_64) .align 8 ENTRY(initial_code) .quad x86_64_start_kernel + ENTRY(initial_gs) + .quad _boot_cpu_pda __FINITDATA ENTRY(stack_start) diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 1a712da1dfa..70d846628bb 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -854,6 +854,7 @@ do_rest: #else cpu_pda(cpu)->pcurrent = c_idle.idle; clear_tsk_thread_flag(c_idle.idle, TIF_FORK); + initial_gs = (unsigned long)cpu_pda(cpu); #endif early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); initial_code = (unsigned long)start_secondary; -- cgit From c8f3329a0ddd751241e96b4100df7eda14b2cbc6 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 13 Jan 2009 20:41:35 +0900 Subject: x86: use static _cpu_pda array _cpu_pda array first uses statically allocated storage in data.init and then switches to allocated bootmem to conserve space. However, after folding pda area into percpu area, _cpu_pda array will be removed completely. Drop the reallocation part to simplify the code for soon-to-follow changes. Signed-off-by: Tejun Heo Signed-off-by: Ingo Molnar --- arch/x86/include/asm/pda.h | 3 ++- arch/x86/kernel/cpu/common.c | 2 +- arch/x86/kernel/head64.c | 12 ------------ arch/x86/kernel/setup_percpu.c | 14 +++----------- 4 files changed, 6 insertions(+), 25 deletions(-) diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h index cbd3f48a832..2d5b49c3248 100644 --- a/arch/x86/include/asm/pda.h +++ b/arch/x86/include/asm/pda.h @@ -5,6 +5,7 @@ #include #include #include +#include #include /* Per processor datastructure. %gs points to it while the kernel runs */ @@ -39,7 +40,7 @@ struct x8664_pda { unsigned irq_spurious_count; } ____cacheline_aligned_in_smp; -extern struct x8664_pda **_cpu_pda; +extern struct x8664_pda *_cpu_pda[NR_CPUS]; extern void pda_init(int); #define cpu_pda(i) (_cpu_pda[i]) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index f0025846244..c116c599326 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -879,7 +879,7 @@ static __init int setup_disablecpuid(char *arg) __setup("clearcpuid=", setup_disablecpuid); #ifdef CONFIG_X86_64 -struct x8664_pda **_cpu_pda __read_mostly; +struct x8664_pda *_cpu_pda[NR_CPUS] __read_mostly; EXPORT_SYMBOL(_cpu_pda); struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 76ffba2aa66..462d0beccb6 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -29,20 +29,8 @@ /* boot cpu pda, referenced by head_64.S to initialize %gs for boot CPU */ struct x8664_pda _boot_cpu_pda; -#ifdef CONFIG_SMP -/* - * We install an empty cpu_pda pointer table to indicate to early users - * (numa_set_node) that the cpu_pda pointer table for cpus other than - * the boot cpu is not yet setup. - */ -static struct x8664_pda *__cpu_pda[NR_CPUS] __initdata; -#else -static struct x8664_pda *__cpu_pda[NR_CPUS] __read_mostly; -#endif - void __init x86_64_init_pda(void) { - _cpu_pda = __cpu_pda; cpu_pda(0) = &_boot_cpu_pda; cpu_pda(0)->data_offset = (unsigned long)(__per_cpu_load - __per_cpu_start); diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 44845842e72..73ab01b297c 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -114,7 +114,6 @@ static inline void setup_cpu_pda_map(void) { } static void __init setup_cpu_pda_map(void) { char *pda; - struct x8664_pda **new_cpu_pda; unsigned long size; int cpu; @@ -122,28 +121,21 @@ static void __init setup_cpu_pda_map(void) /* allocate cpu_pda array and pointer table */ { - unsigned long tsize = nr_cpu_ids * sizeof(void *); unsigned long asize = size * (nr_cpu_ids - 1); - tsize = roundup(tsize, cache_line_size()); - new_cpu_pda = alloc_bootmem(tsize + asize); - pda = (char *)new_cpu_pda + tsize; + pda = alloc_bootmem(asize); } /* initialize pointer table to static pda's */ for_each_possible_cpu(cpu) { if (cpu == 0) { /* leave boot cpu pda in place */ - new_cpu_pda[0] = cpu_pda(0); continue; } - new_cpu_pda[cpu] = (struct x8664_pda *)pda; - new_cpu_pda[cpu]->in_bootmem = 1; + cpu_pda(cpu) = (struct x8664_pda *)pda; + cpu_pda(cpu)->in_bootmem = 1; pda += size; } - - /* point to new pointer table */ - _cpu_pda = new_cpu_pda; } #endif /* CONFIG_SMP && CONFIG_X86_64 */ -- cgit From 1a51e3a0aed18767cf2762e95456ecfeb0bca5e6 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 13 Jan 2009 20:41:35 +0900 Subject: x86: fold pda into percpu area on SMP [ Based on original patch from Christoph Lameter and Mike Travis. ] Currently pdas and percpu areas are allocated separately. %gs points to local pda and percpu area can be reached using pda->data_offset. This patch folds pda into percpu area. Due to strange gcc requirement, pda needs to be at the beginning of the percpu area so that pda->stack_canary is at %gs:40. To achieve this, a new percpu output section macro - PERCPU_VADDR_PREALLOC() - is added and used to reserve pda sized chunk at the start of the percpu area. After this change, for boot cpu, %gs first points to pda in the data.init area and later during setup_per_cpu_areas() gets updated to point to the actual pda. This means that setup_per_cpu_areas() need to reload %gs for CPU0 while clearing pda area for other cpus as cpu0 already has modified it when control reaches setup_per_cpu_areas(). This patch also removes now unnecessary get_local_pda() and its call sites. A lot of this patch is taken from Mike Travis' "x86_64: Fold pda into per cpu area" patch. Signed-off-by: Tejun Heo Signed-off-by: Ingo Molnar --- arch/x86/include/asm/percpu.h | 8 +++ arch/x86/include/asm/smp.h | 2 - arch/x86/kernel/asm-offsets_64.c | 1 + arch/x86/kernel/cpu/common.c | 6 +-- arch/x86/kernel/head64.c | 8 ++- arch/x86/kernel/head_64.S | 15 ++++-- arch/x86/kernel/setup_percpu.c | 107 ++++++++++++++++---------------------- arch/x86/kernel/smpboot.c | 60 +-------------------- arch/x86/kernel/vmlinux_64.lds.S | 6 ++- arch/x86/xen/smp.c | 10 ---- include/asm-generic/vmlinux.lds.h | 25 ++++++++- 11 files changed, 104 insertions(+), 144 deletions(-) diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index df644f3e53e..0ed77cf33f7 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h @@ -1,6 +1,14 @@ #ifndef _ASM_X86_PERCPU_H #define _ASM_X86_PERCPU_H +#ifndef __ASSEMBLY__ +#ifdef CONFIG_X86_64 +extern void load_pda_offset(int cpu); +#else +static inline void load_pda_offset(int cpu) { } +#endif +#endif + #ifdef CONFIG_X86_64 #include diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index a8cea7b0943..127415402ea 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -19,8 +19,6 @@ #include #include -extern int __cpuinit get_local_pda(int cpu); - extern int smp_num_siblings; extern unsigned int num_processors; diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index 1d41d3f1edb..f8d1b047ef4 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c @@ -56,6 +56,7 @@ int main(void) ENTRY(cpunumber); ENTRY(irqstackptr); ENTRY(data_offset); + DEFINE(pda_size, sizeof(struct x8664_pda)); BLANK(); #undef ENTRY #ifdef CONFIG_PARAVIRT diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index c116c599326..7041acdf557 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -893,10 +893,8 @@ void __cpuinit pda_init(int cpu) /* Setup up data that may be needed in __get_free_pages early */ loadsegment(fs, 0); loadsegment(gs, 0); - /* Memory clobbers used to order PDA accessed */ - mb(); - wrmsrl(MSR_GS_BASE, pda); - mb(); + + load_pda_offset(cpu); pda->cpunumber = cpu; pda->irqcount = -1; diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 462d0beccb6..1a311293f73 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -26,12 +26,18 @@ #include #include -/* boot cpu pda, referenced by head_64.S to initialize %gs for boot CPU */ +#ifndef CONFIG_SMP +/* boot cpu pda, referenced by head_64.S to initialize %gs on UP */ struct x8664_pda _boot_cpu_pda; +#endif void __init x86_64_init_pda(void) { +#ifdef CONFIG_SMP + cpu_pda(0) = (void *)__per_cpu_load; +#else cpu_pda(0) = &_boot_cpu_pda; +#endif cpu_pda(0)->data_offset = (unsigned long)(__per_cpu_load - __per_cpu_start); pda_init(0); diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 2f0ab008988..7a995d0e9f7 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -245,10 +245,13 @@ ENTRY(secondary_startup_64) /* Set up %gs. * - * %gs should point to the pda. For initial boot, make %gs point - * to the _boot_cpu_pda in data section. For a secondary CPU, - * initial_gs should be set to its pda address before the CPU runs - * this code. + * On SMP, %gs should point to the per-cpu area. For initial + * boot, make %gs point to the init data section. For a + * secondary CPU,initial_gs should be set to its pda address + * before the CPU runs this code. + * + * On UP, initial_gs points to _boot_cpu_pda and doesn't + * change. */ movl $MSR_GS_BASE,%ecx movq initial_gs(%rip),%rax @@ -278,7 +281,11 @@ ENTRY(secondary_startup_64) ENTRY(initial_code) .quad x86_64_start_kernel ENTRY(initial_gs) +#ifdef CONFIG_SMP + .quad __per_cpu_load +#else .quad _boot_cpu_pda +#endif __FINITDATA ENTRY(stack_start) diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 73ab01b297c..63d46280227 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #ifdef CONFIG_DEBUG_PER_CPU_MAPS @@ -65,6 +66,36 @@ static void __init setup_node_to_cpumask_map(void); static inline void setup_node_to_cpumask_map(void) { } #endif +#ifdef CONFIG_X86_64 +void __cpuinit load_pda_offset(int cpu) +{ + /* Memory clobbers used to order pda/percpu accesses */ + mb(); + wrmsrl(MSR_GS_BASE, cpu_pda(cpu)); + mb(); +} + +#endif /* CONFIG_SMP && CONFIG_X86_64 */ + +#ifdef CONFIG_X86_64 + +/* correctly size the local cpu masks */ +static void setup_cpu_local_masks(void) +{ + alloc_bootmem_cpumask_var(&cpu_initialized_mask); + alloc_bootmem_cpumask_var(&cpu_callin_mask); + alloc_bootmem_cpumask_var(&cpu_callout_mask); + alloc_bootmem_cpumask_var(&cpu_sibling_setup_mask); +} + +#else /* CONFIG_X86_32 */ + +static inline void setup_cpu_local_masks(void) +{ +} + +#endif /* CONFIG_X86_32 */ + #ifdef CONFIG_HAVE_SETUP_PER_CPU_AREA /* * Copy data used in early init routines from the initial arrays to the @@ -101,63 +132,7 @@ static void __init setup_per_cpu_maps(void) */ unsigned long __per_cpu_offset[NR_CPUS] __read_mostly; EXPORT_SYMBOL(__per_cpu_offset); -static inline void setup_cpu_pda_map(void) { } - -#elif !defined(CONFIG_SMP) -static inline void setup_cpu_pda_map(void) { } - -#else /* CONFIG_SMP && CONFIG_X86_64 */ - -/* - * Allocate cpu_pda pointer table and array via alloc_bootmem. - */ -static void __init setup_cpu_pda_map(void) -{ - char *pda; - unsigned long size; - int cpu; - - size = roundup(sizeof(struct x8664_pda), cache_line_size()); - - /* allocate cpu_pda array and pointer table */ - { - unsigned long asize = size * (nr_cpu_ids - 1); - - pda = alloc_bootmem(asize); - } - - /* initialize pointer table to static pda's */ - for_each_possible_cpu(cpu) { - if (cpu == 0) { - /* leave boot cpu pda in place */ - continue; - } - cpu_pda(cpu) = (struct x8664_pda *)pda; - cpu_pda(cpu)->in_bootmem = 1; - pda += size; - } -} - -#endif /* CONFIG_SMP && CONFIG_X86_64 */ - -#ifdef CONFIG_X86_64 - -/* correctly size the local cpu masks */ -static void setup_cpu_local_masks(void) -{ - alloc_bootmem_cpumask_var(&cpu_initialized_mask); - alloc_bootmem_cpumask_var(&cpu_callin_mask); - alloc_bootmem_cpumask_var(&cpu_callout_mask); - alloc_bootmem_cpumask_var(&cpu_sibling_setup_mask); -} - -#else /* CONFIG_X86_32 */ - -static inline void setup_cpu_local_masks(void) -{ -} - -#endif /* CONFIG_X86_32 */ +#endif /* * Great future plan: @@ -171,9 +146,6 @@ void __init setup_per_cpu_areas(void) int cpu; unsigned long align = 1; - /* Setup cpu_pda map */ - setup_cpu_pda_map(); - /* Copy section for each CPU (we discard the original) */ old_size = PERCPU_ENOUGH_ROOM; align = max_t(unsigned long, PAGE_SIZE, align); @@ -204,8 +176,21 @@ void __init setup_per_cpu_areas(void) cpu, node, __pa(ptr)); } #endif - per_cpu_offset(cpu) = ptr - __per_cpu_start; + memcpy(ptr, __per_cpu_load, __per_cpu_end - __per_cpu_start); +#ifdef CONFIG_X86_64 + cpu_pda(cpu) = (void *)ptr; + + /* + * CPU0 modified pda in the init data area, reload pda + * offset for CPU0 and clear the area for others. + */ + if (cpu == 0) + load_pda_offset(0); + else + memset(cpu_pda(cpu), 0, sizeof(*cpu_pda(cpu))); +#endif + per_cpu_offset(cpu) = ptr - __per_cpu_start; DBG("PERCPU: cpu %4d %p\n", cpu, ptr); } diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 70d846628bb..f2f77ca494d 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -744,52 +744,6 @@ static void __cpuinit do_fork_idle(struct work_struct *work) complete(&c_idle->done); } -#ifdef CONFIG_X86_64 - -/* __ref because it's safe to call free_bootmem when after_bootmem == 0. */ -static void __ref free_bootmem_pda(struct x8664_pda *oldpda) -{ - if (!after_bootmem) - free_bootmem((unsigned long)oldpda, sizeof(*oldpda)); -} - -/* - * Allocate node local memory for the AP pda. - * - * Must be called after the _cpu_pda pointer table is initialized. - */ -int __cpuinit get_local_pda(int cpu) -{ - struct x8664_pda *oldpda, *newpda; - unsigned long size = sizeof(struct x8664_pda); - int node = cpu_to_node(cpu); - - if (cpu_pda(cpu) && !cpu_pda(cpu)->in_bootmem) - return 0; - - oldpda = cpu_pda(cpu); - newpda = kmalloc_node(size, GFP_ATOMIC, node); - if (!newpda) { - printk(KERN_ERR "Could not allocate node local PDA " - "for CPU %d on node %d\n", cpu, node); - - if (oldpda) - return 0; /* have a usable pda */ - else - return -1; - } - - if (oldpda) { - memcpy(newpda, oldpda, size); - free_bootmem_pda(oldpda); - } - - newpda->in_bootmem = 0; - cpu_pda(cpu) = newpda; - return 0; -} -#endif /* CONFIG_X86_64 */ - static int __cpuinit do_boot_cpu(int apicid, int cpu) /* * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad @@ -807,16 +761,6 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu) }; INIT_WORK(&c_idle.work, do_fork_idle); -#ifdef CONFIG_X86_64 - /* Allocate node local memory for AP pdas */ - if (cpu > 0) { - boot_error = get_local_pda(cpu); - if (boot_error) - goto restore_state; - /* if can't get pda memory, can't start cpu */ - } -#endif - alternatives_smp_switch(1); c_idle.idle = get_idle_for_cpu(cpu); @@ -931,9 +875,7 @@ do_rest: inquire_remote_apic(apicid); } } -#ifdef CONFIG_X86_64 -restore_state: -#endif + if (boot_error) { /* Try to put things back the way they were before ... */ numa_remove_cpu(cpu); /* was set by numa_add_cpu */ diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S index f50280db0df..962f21f1d4d 100644 --- a/arch/x86/kernel/vmlinux_64.lds.S +++ b/arch/x86/kernel/vmlinux_64.lds.S @@ -5,6 +5,7 @@ #define LOAD_OFFSET __START_KERNEL_map #include +#include #include #undef i386 /* in case the preprocessor is a 32bit one */ @@ -215,10 +216,11 @@ SECTIONS /* * percpu offsets are zero-based on SMP. PERCPU_VADDR() changes the * output PHDR, so the next output section - __data_nosave - should - * switch it back to data.init. + * switch it back to data.init. Also, pda should be at the head of + * percpu area. Preallocate it. */ . = ALIGN(PAGE_SIZE); - PERCPU_VADDR(0, :percpu) + PERCPU_VADDR_PREALLOC(0, :percpu, pda_size) #else PERCPU(PAGE_SIZE) #endif diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index c44e2069c7c..83fa4236477 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -283,16 +283,6 @@ static int __cpuinit xen_cpu_up(unsigned int cpu) struct task_struct *idle = idle_task(cpu); int rc; -#ifdef CONFIG_X86_64 - /* Allocate node local memory for AP pdas */ - WARN_ON(cpu == 0); - if (cpu > 0) { - rc = get_local_pda(cpu); - if (rc) - return rc; - } -#endif - #ifdef CONFIG_X86_32 init_gdt(cpu); per_cpu(current_task, cpu) = idle; diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index fc2f55f2dcd..e53319cf29c 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -441,9 +441,10 @@ . = __per_cpu_load + SIZEOF(.data.percpu); /** - * PERCPU_VADDR - define output section for percpu area + * PERCPU_VADDR_PREALLOC - define output section for percpu area with prealloc * @vaddr: explicit base address (optional) * @phdr: destination PHDR (optional) + * @prealloc: the size of prealloc area * * Macro which expands to output section for percpu area. If @vaddr * is not blank, it specifies explicit base address and all percpu @@ -455,11 +456,33 @@ * section in the linker script will go there too. @phdr should have * a leading colon. * + * If @prealloc is non-zero, the specified number of bytes will be + * reserved at the start of percpu area. As the prealloc area is + * likely to break alignment, this macro puts areas in increasing + * alignment order. + * * This macro defines three symbols, __per_cpu_load, __per_cpu_start * and __per_cpu_end. The first one is the vaddr of loaded percpu * init data. __per_cpu_start equals @vaddr and __per_cpu_end is the * end offset. */ +#define PERCPU_VADDR_PREALLOC(vaddr, segment, prealloc) \ + PERCPU_PROLOG(vaddr) \ + . += prealloc; \ + *(.data.percpu) \ + *(.data.percpu.shared_aligned) \ + *(.data.percpu.page_aligned) \ + PERCPU_EPILOG(segment) + +/** + * PERCPU_VADDR - define output section for percpu area + * @vaddr: explicit base address (optional) + * @phdr: destination PHDR (optional) + * + * Macro which expands to output section for percpu area. Mostly + * identical to PERCPU_VADDR_PREALLOC(@vaddr, @phdr, 0) other than + * using slighly different layout. + */ #define PERCPU_VADDR(vaddr, phdr) \ PERCPU_PROLOG(vaddr) \ *(.data.percpu.page_aligned) \ -- cgit From 9939ddaff52787b2a7c1adf1b2afc95421aa0884 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 13 Jan 2009 20:41:35 +0900 Subject: x86: merge 64 and 32 SMP percpu handling Now that pda is allocated as part of percpu, percpu doesn't need to be accessed through pda. Unify x86_64 SMP percpu access with x86_32 SMP one. Other than the segment register, operand size and the base of percpu symbols, they behave identical now. This patch replaces now unnecessary pda->data_offset with a dummy field which is necessary to keep stack_canary at its place. This patch also moves per_cpu_offset initialization out of init_gdt() into setup_per_cpu_areas(). Note that this change also necessitates explicit per_cpu_offset initializations in voyager_smp.c. With this change, x86_OP_percpu()'s are as efficient on x86_64 as on x86_32 and also x86_64 can use assembly PER_CPU macros. Signed-off-by: Tejun Heo Signed-off-by: Ingo Molnar --- arch/x86/include/asm/pda.h | 3 +- arch/x86/include/asm/percpu.h | 127 +++++++++++------------------------- arch/x86/kernel/asm-offsets_64.c | 1 - arch/x86/kernel/entry_64.S | 7 +- arch/x86/kernel/head64.c | 2 - arch/x86/kernel/setup_percpu.c | 15 +++-- arch/x86/kernel/smpcommon.c | 3 +- arch/x86/mach-voyager/voyager_smp.c | 2 + 8 files changed, 55 insertions(+), 105 deletions(-) diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h index 2d5b49c3248..e91558e3785 100644 --- a/arch/x86/include/asm/pda.h +++ b/arch/x86/include/asm/pda.h @@ -11,8 +11,7 @@ /* Per processor datastructure. %gs points to it while the kernel runs */ struct x8664_pda { struct task_struct *pcurrent; /* 0 Current process */ - unsigned long data_offset; /* 8 Per cpu data offset from linker - address */ + unsigned long dummy; unsigned long kernelstack; /* 16 top of kernel stack for current */ unsigned long oldrsp; /* 24 user rsp for system call */ int irqcount; /* 32 Irq nesting counter. Starts -1 */ diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index 0ed77cf33f7..556f84b9ea9 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h @@ -1,62 +1,13 @@ #ifndef _ASM_X86_PERCPU_H #define _ASM_X86_PERCPU_H -#ifndef __ASSEMBLY__ #ifdef CONFIG_X86_64 -extern void load_pda_offset(int cpu); +#define __percpu_seg gs +#define __percpu_mov_op movq #else -static inline void load_pda_offset(int cpu) { } -#endif -#endif - -#ifdef CONFIG_X86_64 -#include - -/* Same as asm-generic/percpu.h, except that we store the per cpu offset - in the PDA. Longer term the PDA and every per cpu variable - should be just put into a single section and referenced directly - from %gs */ - -#ifdef CONFIG_SMP -#include - -#define __per_cpu_offset(cpu) (cpu_pda(cpu)->data_offset) -#define __my_cpu_offset read_pda(data_offset) - -#define per_cpu_offset(x) (__per_cpu_offset(x)) - +#define __percpu_seg fs +#define __percpu_mov_op movl #endif -#include - -DECLARE_PER_CPU(struct x8664_pda, pda); - -/* - * These are supposed to be implemented as a single instruction which - * operates on the per-cpu data base segment. x86-64 doesn't have - * that yet, so this is a fairly inefficient workaround for the - * meantime. The single instruction is atomic with respect to - * preemption and interrupts, so we need to explicitly disable - * interrupts here to achieve the same effect. However, because it - * can be used from within interrupt-disable/enable, we can't actually - * disable interrupts; disabling preemption is enough. - */ -#define x86_read_percpu(var) \ - ({ \ - typeof(per_cpu_var(var)) __tmp; \ - preempt_disable(); \ - __tmp = __get_cpu_var(var); \ - preempt_enable(); \ - __tmp; \ - }) - -#define x86_write_percpu(var, val) \ - do { \ - preempt_disable(); \ - __get_cpu_var(var) = (val); \ - preempt_enable(); \ - } while(0) - -#else /* CONFIG_X86_64 */ #ifdef __ASSEMBLY__ @@ -73,42 +24,26 @@ DECLARE_PER_CPU(struct x8664_pda, pda); * PER_CPU(cpu_gdt_descr, %ebx) */ #ifdef CONFIG_SMP -#define PER_CPU(var, reg) \ - movl %fs:per_cpu__##this_cpu_off, reg; \ +#define PER_CPU(var, reg) \ + __percpu_mov_op %__percpu_seg:per_cpu__this_cpu_off, reg; \ lea per_cpu__##var(reg), reg -#define PER_CPU_VAR(var) %fs:per_cpu__##var +#define PER_CPU_VAR(var) %__percpu_seg:per_cpu__##var #else /* ! SMP */ -#define PER_CPU(var, reg) \ - movl $per_cpu__##var, reg +#define PER_CPU(var, reg) \ + __percpu_mov_op $per_cpu__##var, reg #define PER_CPU_VAR(var) per_cpu__##var #endif /* SMP */ #else /* ...!ASSEMBLY */ -/* - * PER_CPU finds an address of a per-cpu variable. - * - * Args: - * var - variable name - * cpu - 32bit register containing the current CPU number - * - * The resulting address is stored in the "cpu" argument. - * - * Example: - * PER_CPU(cpu_gdt_descr, %ebx) - */ -#ifdef CONFIG_SMP - -#define __my_cpu_offset x86_read_percpu(this_cpu_off) - -/* fs segment starts at (positive) offset == __per_cpu_offset[cpu] */ -#define __percpu_seg "%%fs:" +#include -#else /* !SMP */ - -#define __percpu_seg "" - -#endif /* SMP */ +#ifdef CONFIG_SMP +#define __percpu_seg_str "%%"__stringify(__percpu_seg)":" +#define __my_cpu_offset x86_read_percpu(this_cpu_off) +#else +#define __percpu_seg_str +#endif #include @@ -128,20 +63,25 @@ do { \ } \ switch (sizeof(var)) { \ case 1: \ - asm(op "b %1,"__percpu_seg"%0" \ + asm(op "b %1,"__percpu_seg_str"%0" \ : "+m" (var) \ : "ri" ((T__)val)); \ break; \ case 2: \ - asm(op "w %1,"__percpu_seg"%0" \ + asm(op "w %1,"__percpu_seg_str"%0" \ : "+m" (var) \ : "ri" ((T__)val)); \ break; \ case 4: \ - asm(op "l %1,"__percpu_seg"%0" \ + asm(op "l %1,"__percpu_seg_str"%0" \ : "+m" (var) \ : "ri" ((T__)val)); \ break; \ + case 8: \ + asm(op "q %1,"__percpu_seg_str"%0" \ + : "+m" (var) \ + : "r" ((T__)val)); \ + break; \ default: __bad_percpu_size(); \ } \ } while (0) @@ -151,17 +91,22 @@ do { \ typeof(var) ret__; \ switch (sizeof(var)) { \ case 1: \ - asm(op "b "__percpu_seg"%1,%0" \ + asm(op "b "__percpu_seg_str"%1,%0" \ : "=r" (ret__) \ : "m" (var)); \ break; \ case 2: \ - asm(op "w "__percpu_seg"%1,%0" \ + asm(op "w "__percpu_seg_str"%1,%0" \ : "=r" (ret__) \ : "m" (var)); \ break; \ case 4: \ - asm(op "l "__percpu_seg"%1,%0" \ + asm(op "l "__percpu_seg_str"%1,%0" \ + : "=r" (ret__) \ + : "m" (var)); \ + break; \ + case 8: \ + asm(op "q "__percpu_seg_str"%1,%0" \ : "=r" (ret__) \ : "m" (var)); \ break; \ @@ -175,8 +120,14 @@ do { \ #define x86_add_percpu(var, val) percpu_to_op("add", per_cpu__##var, val) #define x86_sub_percpu(var, val) percpu_to_op("sub", per_cpu__##var, val) #define x86_or_percpu(var, val) percpu_to_op("or", per_cpu__##var, val) + +#ifdef CONFIG_X86_64 +extern void load_pda_offset(int cpu); +#else +static inline void load_pda_offset(int cpu) { } +#endif + #endif /* !__ASSEMBLY__ */ -#endif /* !CONFIG_X86_64 */ #ifdef CONFIG_SMP diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index f8d1b047ef4..f4cc81bfbf8 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c @@ -55,7 +55,6 @@ int main(void) ENTRY(irqcount); ENTRY(cpunumber); ENTRY(irqstackptr); - ENTRY(data_offset); DEFINE(pda_size, sizeof(struct x8664_pda)); BLANK(); #undef ENTRY diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index e28c7a98779..4833f3a1965 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -52,6 +52,7 @@ #include #include #include +#include /* Avoid __ASSEMBLER__'ifying just for this. */ #include @@ -1072,10 +1073,10 @@ ENTRY(\sym) TRACE_IRQS_OFF movq %rsp,%rdi /* pt_regs pointer */ xorl %esi,%esi /* no error code */ - movq %gs:pda_data_offset, %rbp - subq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp) + PER_CPU(init_tss, %rbp) + subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp) call \do_sym - addq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp) + addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp) jmp paranoid_exit /* %ebx: no swapgs flag */ CFI_ENDPROC END(\sym) diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 1a311293f73..e99b661a97f 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -38,8 +38,6 @@ void __init x86_64_init_pda(void) #else cpu_pda(0) = &_boot_cpu_pda; #endif - cpu_pda(0)->data_offset = - (unsigned long)(__per_cpu_load - __per_cpu_start); pda_init(0); } diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 63d46280227..be1ff34db11 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -125,14 +125,14 @@ static void __init setup_per_cpu_maps(void) #endif } -#ifdef CONFIG_X86_32 -/* - * Great future not-so-futuristic plan: make i386 and x86_64 do it - * the same way - */ +#ifdef CONFIG_X86_64 +unsigned long __per_cpu_offset[NR_CPUS] __read_mostly = { + [0] = (unsigned long)__per_cpu_load, +}; +#else unsigned long __per_cpu_offset[NR_CPUS] __read_mostly; -EXPORT_SYMBOL(__per_cpu_offset); #endif +EXPORT_SYMBOL(__per_cpu_offset); /* * Great future plan: @@ -178,6 +178,7 @@ void __init setup_per_cpu_areas(void) #endif memcpy(ptr, __per_cpu_load, __per_cpu_end - __per_cpu_start); + per_cpu_offset(cpu) = ptr - __per_cpu_start; #ifdef CONFIG_X86_64 cpu_pda(cpu) = (void *)ptr; @@ -190,7 +191,7 @@ void __init setup_per_cpu_areas(void) else memset(cpu_pda(cpu), 0, sizeof(*cpu_pda(cpu))); #endif - per_cpu_offset(cpu) = ptr - __per_cpu_start; + per_cpu(this_cpu_off, cpu) = per_cpu_offset(cpu); DBG("PERCPU: cpu %4d %p\n", cpu, ptr); } diff --git a/arch/x86/kernel/smpcommon.c b/arch/x86/kernel/smpcommon.c index 397e309839d..84395fabc41 100644 --- a/arch/x86/kernel/smpcommon.c +++ b/arch/x86/kernel/smpcommon.c @@ -4,10 +4,10 @@ #include #include -#ifdef CONFIG_X86_32 DEFINE_PER_CPU(unsigned long, this_cpu_off); EXPORT_PER_CPU_SYMBOL(this_cpu_off); +#ifdef CONFIG_X86_32 /* * Initialize the CPU's GDT. This is either the boot CPU doing itself * (still using the master per-cpu area), or a CPU doing it for a @@ -24,7 +24,6 @@ __cpuinit void init_gdt(int cpu) write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S); - per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu]; per_cpu(cpu_number, cpu) = cpu; } #endif diff --git a/arch/x86/mach-voyager/voyager_smp.c b/arch/x86/mach-voyager/voyager_smp.c index 9840b7ec749..1a48368acb0 100644 --- a/arch/x86/mach-voyager/voyager_smp.c +++ b/arch/x86/mach-voyager/voyager_smp.c @@ -531,6 +531,7 @@ static void __init do_boot_cpu(__u8 cpu) stack_start.sp = (void *)idle->thread.sp; init_gdt(cpu); + per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu]; per_cpu(current_task, cpu) = idle; early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); irq_ctx_init(cpu); @@ -1748,6 +1749,7 @@ static void __init voyager_smp_prepare_cpus(unsigned int max_cpus) static void __cpuinit voyager_smp_prepare_boot_cpu(void) { init_gdt(smp_processor_id()); + per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu]; switch_to_new_gdt(); cpu_set(smp_processor_id(), cpu_online_map); -- cgit From b12d8db8fbfaed1e8222a15333a3645599636854 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 13 Jan 2009 20:41:35 +0900 Subject: x86: make pda a percpu variable [ Based on original patch from Christoph Lameter and Mike Travis. ] As pda is now allocated in percpu area, it can easily be made a proper percpu variable. Make it so by defining per cpu symbol from linker script and declaring it in C code for SMP and simply defining it for UP. This change cleans up code and brings SMP and UP closer a bit. Signed-off-by: Tejun Heo Signed-off-by: Ingo Molnar --- arch/x86/include/asm/pda.h | 5 +++-- arch/x86/kernel/cpu/common.c | 3 --- arch/x86/kernel/head64.c | 10 ---------- arch/x86/kernel/head_64.S | 5 +++-- arch/x86/kernel/setup_percpu.c | 16 ++++++++++++++-- arch/x86/kernel/vmlinux_64.lds.S | 4 +++- 6 files changed, 23 insertions(+), 20 deletions(-) diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h index e91558e3785..66ae1043393 100644 --- a/arch/x86/include/asm/pda.h +++ b/arch/x86/include/asm/pda.h @@ -7,6 +7,7 @@ #include #include #include +#include /* Per processor datastructure. %gs points to it while the kernel runs */ struct x8664_pda { @@ -39,10 +40,10 @@ struct x8664_pda { unsigned irq_spurious_count; } ____cacheline_aligned_in_smp; -extern struct x8664_pda *_cpu_pda[NR_CPUS]; +DECLARE_PER_CPU(struct x8664_pda, __pda); extern void pda_init(int); -#define cpu_pda(i) (_cpu_pda[i]) +#define cpu_pda(cpu) (&per_cpu(__pda, cpu)) /* * There is no fast way to get the base address of the PDA, all the accesses diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 7041acdf557..c49498d4083 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -879,9 +879,6 @@ static __init int setup_disablecpuid(char *arg) __setup("clearcpuid=", setup_disablecpuid); #ifdef CONFIG_X86_64 -struct x8664_pda *_cpu_pda[NR_CPUS] __read_mostly; -EXPORT_SYMBOL(_cpu_pda); - struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; static char boot_cpu_stack[IRQSTACKSIZE] __page_aligned_bss; diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index e99b661a97f..71b6f6ec96a 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -26,18 +26,8 @@ #include #include -#ifndef CONFIG_SMP -/* boot cpu pda, referenced by head_64.S to initialize %gs on UP */ -struct x8664_pda _boot_cpu_pda; -#endif - void __init x86_64_init_pda(void) { -#ifdef CONFIG_SMP - cpu_pda(0) = (void *)__per_cpu_load; -#else - cpu_pda(0) = &_boot_cpu_pda; -#endif pda_init(0); } diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 7a995d0e9f7..c8ace880661 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -19,6 +19,7 @@ #include #include #include +#include #ifdef CONFIG_PARAVIRT #include @@ -250,7 +251,7 @@ ENTRY(secondary_startup_64) * secondary CPU,initial_gs should be set to its pda address * before the CPU runs this code. * - * On UP, initial_gs points to _boot_cpu_pda and doesn't + * On UP, initial_gs points to PER_CPU_VAR(__pda) and doesn't * change. */ movl $MSR_GS_BASE,%ecx @@ -284,7 +285,7 @@ ENTRY(secondary_startup_64) #ifdef CONFIG_SMP .quad __per_cpu_load #else - .quad _boot_cpu_pda + .quad PER_CPU_VAR(__pda) #endif __FINITDATA diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index be1ff34db11..daeedf82c15 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -66,6 +66,16 @@ static void __init setup_node_to_cpumask_map(void); static inline void setup_node_to_cpumask_map(void) { } #endif +/* + * Define load_pda_offset() and per-cpu __pda for x86_64. + * load_pda_offset() is responsible for loading the offset of pda into + * %gs. + * + * On SMP, pda offset also duals as percpu base address and thus it + * should be at the start of per-cpu area. To achieve this, it's + * preallocated in vmlinux_64.lds.S directly instead of using + * DEFINE_PER_CPU(). + */ #ifdef CONFIG_X86_64 void __cpuinit load_pda_offset(int cpu) { @@ -74,6 +84,10 @@ void __cpuinit load_pda_offset(int cpu) wrmsrl(MSR_GS_BASE, cpu_pda(cpu)); mb(); } +#ifndef CONFIG_SMP +DEFINE_PER_CPU(struct x8664_pda, __pda); +EXPORT_PER_CPU_SYMBOL(__pda); +#endif #endif /* CONFIG_SMP && CONFIG_X86_64 */ @@ -180,8 +194,6 @@ void __init setup_per_cpu_areas(void) memcpy(ptr, __per_cpu_load, __per_cpu_end - __per_cpu_start); per_cpu_offset(cpu) = ptr - __per_cpu_start; #ifdef CONFIG_X86_64 - cpu_pda(cpu) = (void *)ptr; - /* * CPU0 modified pda in the init data area, reload pda * offset for CPU0 and clear the area for others. diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S index 962f21f1d4d..d2a0baa87d1 100644 --- a/arch/x86/kernel/vmlinux_64.lds.S +++ b/arch/x86/kernel/vmlinux_64.lds.S @@ -217,10 +217,12 @@ SECTIONS * percpu offsets are zero-based on SMP. PERCPU_VADDR() changes the * output PHDR, so the next output section - __data_nosave - should * switch it back to data.init. Also, pda should be at the head of - * percpu area. Preallocate it. + * percpu area. Preallocate it and define the percpu offset symbol + * so that it can be accessed as a percpu variable. */ . = ALIGN(PAGE_SIZE); PERCPU_VADDR_PREALLOC(0, :percpu, pda_size) + per_cpu____pda = __per_cpu_start; #else PERCPU(PAGE_SIZE) #endif -- cgit From 49357d19e4fb31e28796eaff83499e7584c26878 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 13 Jan 2009 20:41:35 +0900 Subject: x86: convert pda ops to wrappers around x86 percpu accessors pda is now a percpu variable and there's no reason it can't use plain x86 percpu accessors. Add x86_test_and_clear_bit_percpu() and replace pda op implementations with wrappers around x86 percpu accessors. Signed-off-by: Tejun Heo Signed-off-by: Ingo Molnar --- arch/x86/include/asm/pda.h | 88 +++------------------------------------- arch/x86/include/asm/percpu.h | 10 +++++ arch/x86/kernel/vmlinux_64.lds.S | 1 - arch/x86/kernel/x8664_ksyms_64.c | 2 - 4 files changed, 16 insertions(+), 85 deletions(-) diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h index 66ae1043393..e3d3a081d79 100644 --- a/arch/x86/include/asm/pda.h +++ b/arch/x86/include/asm/pda.h @@ -45,91 +45,15 @@ extern void pda_init(int); #define cpu_pda(cpu) (&per_cpu(__pda, cpu)) -/* - * There is no fast way to get the base address of the PDA, all the accesses - * have to mention %fs/%gs. So it needs to be done this Torvaldian way. - */ -extern void __bad_pda_field(void) __attribute__((noreturn)); - -/* - * proxy_pda doesn't actually exist, but tell gcc it is accessed for - * all PDA accesses so it gets read/write dependencies right. - */ -extern struct x8664_pda _proxy_pda; - -#define pda_offset(field) offsetof(struct x8664_pda, field) - -#define pda_to_op(op, field, val) \ -do { \ - typedef typeof(_proxy_pda.field) T__; \ - if (0) { T__ tmp__; tmp__ = (val); } /* type checking */ \ - switch (sizeof(_proxy_pda.field)) { \ - case 2: \ - asm(op "w %1,%%gs:%c2" : \ - "+m" (_proxy_pda.field) : \ - "ri" ((T__)val), \ - "i"(pda_offset(field))); \ - break; \ - case 4: \ - asm(op "l %1,%%gs:%c2" : \ - "+m" (_proxy_pda.field) : \ - "ri" ((T__)val), \ - "i" (pda_offset(field))); \ - break; \ - case 8: \ - asm(op "q %1,%%gs:%c2": \ - "+m" (_proxy_pda.field) : \ - "r" ((T__)val), \ - "i"(pda_offset(field))); \ - break; \ - default: \ - __bad_pda_field(); \ - } \ -} while (0) - -#define pda_from_op(op, field) \ -({ \ - typeof(_proxy_pda.field) ret__; \ - switch (sizeof(_proxy_pda.field)) { \ - case 2: \ - asm(op "w %%gs:%c1,%0" : \ - "=r" (ret__) : \ - "i" (pda_offset(field)), \ - "m" (_proxy_pda.field)); \ - break; \ - case 4: \ - asm(op "l %%gs:%c1,%0": \ - "=r" (ret__): \ - "i" (pda_offset(field)), \ - "m" (_proxy_pda.field)); \ - break; \ - case 8: \ - asm(op "q %%gs:%c1,%0": \ - "=r" (ret__) : \ - "i" (pda_offset(field)), \ - "m" (_proxy_pda.field)); \ - break; \ - default: \ - __bad_pda_field(); \ - } \ - ret__; \ -}) - -#define read_pda(field) pda_from_op("mov", field) -#define write_pda(field, val) pda_to_op("mov", field, val) -#define add_pda(field, val) pda_to_op("add", field, val) -#define sub_pda(field, val) pda_to_op("sub", field, val) -#define or_pda(field, val) pda_to_op("or", field, val) +#define read_pda(field) x86_read_percpu(__pda.field) +#define write_pda(field, val) x86_write_percpu(__pda.field, val) +#define add_pda(field, val) x86_add_percpu(__pda.field, val) +#define sub_pda(field, val) x86_sub_percpu(__pda.field, val) +#define or_pda(field, val) x86_or_percpu(__pda.field, val) /* This is not atomic against other CPUs -- CPU preemption needs to be off */ #define test_and_clear_bit_pda(bit, field) \ -({ \ - int old__; \ - asm volatile("btr %2,%%gs:%c3\n\tsbbl %0,%0" \ - : "=r" (old__), "+m" (_proxy_pda.field) \ - : "dIr" (bit), "i" (pda_offset(field)) : "memory");\ - old__; \ -}) + x86_test_and_clear_bit_percpu(bit, __pda.field) #endif diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index 556f84b9ea9..328b31a429d 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h @@ -121,6 +121,16 @@ do { \ #define x86_sub_percpu(var, val) percpu_to_op("sub", per_cpu__##var, val) #define x86_or_percpu(var, val) percpu_to_op("or", per_cpu__##var, val) +/* This is not atomic against other CPUs -- CPU preemption needs to be off */ +#define x86_test_and_clear_bit_percpu(bit, var) \ +({ \ + int old__; \ + asm volatile("btr %1,"__percpu_seg_str"%c2\n\tsbbl %0,%0" \ + : "=r" (old__) \ + : "dIr" (bit), "i" (&per_cpu__##var) : "memory"); \ + old__; \ +}) + #ifdef CONFIG_X86_64 extern void load_pda_offset(int cpu); #else diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S index d2a0baa87d1..a09abb8fb97 100644 --- a/arch/x86/kernel/vmlinux_64.lds.S +++ b/arch/x86/kernel/vmlinux_64.lds.S @@ -14,7 +14,6 @@ OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") OUTPUT_ARCH(i386:x86-64) ENTRY(phys_startup_64) jiffies_64 = jiffies; -_proxy_pda = 1; PHDRS { text PT_LOAD FLAGS(5); /* R_E */ data PT_LOAD FLAGS(7); /* RWE */ diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c index 695e426aa35..3909e3ba5ce 100644 --- a/arch/x86/kernel/x8664_ksyms_64.c +++ b/arch/x86/kernel/x8664_ksyms_64.c @@ -58,5 +58,3 @@ EXPORT_SYMBOL(__memcpy); EXPORT_SYMBOL(empty_zero_page); EXPORT_SYMBOL(init_level4_pgt); EXPORT_SYMBOL(load_gs_index); - -EXPORT_SYMBOL(_proxy_pda); -- cgit From 004aa322f855a765741d9437a98dd8fe2e4f32a6 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 13 Jan 2009 20:41:35 +0900 Subject: x86: misc clean up after the percpu update Do the following cleanups: * kill x86_64_init_pda() which now is equivalent to pda_init() * use per_cpu_offset() instead of cpu_pda() when initializing initial_gs Signed-off-by: Tejun Heo Signed-off-by: Ingo Molnar --- arch/x86/include/asm/setup.h | 1 - arch/x86/kernel/acpi/sleep.c | 2 +- arch/x86/kernel/head64.c | 7 +------ arch/x86/kernel/smpboot.c | 2 +- arch/x86/xen/enlighten.c | 2 +- 5 files changed, 4 insertions(+), 10 deletions(-) diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h index ebe858cdc8a..536949749bc 100644 --- a/arch/x86/include/asm/setup.h +++ b/arch/x86/include/asm/setup.h @@ -100,7 +100,6 @@ extern unsigned long init_pg_tables_start; extern unsigned long init_pg_tables_end; #else -void __init x86_64_init_pda(void); void __init x86_64_start_kernel(char *real_mode); void __init x86_64_start_reservations(char *real_mode_data); diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 9ff67f8dc2c..4abff454c55 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c @@ -101,7 +101,7 @@ int acpi_save_state_mem(void) stack_start.sp = temp_stack + sizeof(temp_stack); early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(smp_processor_id()); - initial_gs = (unsigned long)cpu_pda(smp_processor_id()); + initial_gs = per_cpu_offset(smp_processor_id()); #endif initial_code = (unsigned long)wakeup_long64; saved_magic = 0x123456789abcdef0; diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 71b6f6ec96a..af67d3227ea 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -26,11 +26,6 @@ #include #include -void __init x86_64_init_pda(void) -{ - pda_init(0); -} - static void __init zap_identity_mappings(void) { pgd_t *pgd = pgd_offset_k(0UL); @@ -96,7 +91,7 @@ void __init x86_64_start_kernel(char * real_mode_data) if (console_loglevel == 10) early_printk("Kernel alive\n"); - x86_64_init_pda(); + pda_init(0); x86_64_start_reservations(real_mode_data); } diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index f2f77ca494d..2f0e0f1090f 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -798,7 +798,7 @@ do_rest: #else cpu_pda(cpu)->pcurrent = c_idle.idle; clear_tsk_thread_flag(c_idle.idle, TIF_FORK); - initial_gs = (unsigned long)cpu_pda(cpu); + initial_gs = per_cpu_offset(cpu); #endif early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); initial_code = (unsigned long)start_secondary; diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 965539ec425..312414ef936 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -1645,7 +1645,7 @@ asmlinkage void __init xen_start_kernel(void) #ifdef CONFIG_X86_64 /* Disable until direct per-cpu data access. */ have_vcpu_info_placement = 0; - x86_64_init_pda(); + pda_init(0); #endif xen_smp_init(); -- cgit From 6dbde3530850d4d8bfc1b6bd4006d92786a2787f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 15 Jan 2009 22:15:53 +0900 Subject: percpu: add optimized generic percpu accessors It is an optimization and a cleanup, and adds the following new generic percpu methods: percpu_read() percpu_write() percpu_add() percpu_sub() percpu_and() percpu_or() percpu_xor() and implements support for them on x86. (other architectures will fall back to a default implementation) The advantage is that for example to read a local percpu variable, instead of this sequence: return __get_cpu_var(var); ffffffff8102ca2b: 48 8b 14 fd 80 09 74 mov -0x7e8bf680(,%rdi,8),%rdx ffffffff8102ca32: 81 ffffffff8102ca33: 48 c7 c0 d8 59 00 00 mov $0x59d8,%rax ffffffff8102ca3a: 48 8b 04 10 mov (%rax,%rdx,1),%rax We can get a single instruction by using the optimized variants: return percpu_read(var); ffffffff8102ca3f: 65 48 8b 05 91 8f fd mov %gs:0x7efd8f91(%rip),%rax I also cleaned up the x86-specific APIs and made the x86 code use these new generic percpu primitives. tj: * fixed generic percpu_sub() definition as Roel Kluin pointed out * added percpu_and() for completeness's sake * made generic percpu ops atomic against preemption Signed-off-by: Ingo Molnar Signed-off-by: Tejun Heo --- arch/x86/include/asm/current.h | 2 +- arch/x86/include/asm/irq_regs_32.h | 4 +-- arch/x86/include/asm/mmu_context_32.h | 12 ++++---- arch/x86/include/asm/pda.h | 10 +++---- arch/x86/include/asm/percpu.h | 24 ++++++++-------- arch/x86/include/asm/smp.h | 2 +- arch/x86/kernel/process_32.c | 2 +- arch/x86/kernel/tlb_32.c | 10 +++---- arch/x86/mach-voyager/voyager_smp.c | 4 +-- arch/x86/xen/enlighten.c | 14 +++++----- arch/x86/xen/irq.c | 8 +++--- arch/x86/xen/mmu.c | 2 +- arch/x86/xen/multicalls.h | 2 +- arch/x86/xen/smp.c | 2 +- include/asm-generic/percpu.h | 52 +++++++++++++++++++++++++++++++++++ 15 files changed, 102 insertions(+), 48 deletions(-) diff --git a/arch/x86/include/asm/current.h b/arch/x86/include/asm/current.h index 0930b4f8d67..0728480f5c5 100644 --- a/arch/x86/include/asm/current.h +++ b/arch/x86/include/asm/current.h @@ -10,7 +10,7 @@ struct task_struct; DECLARE_PER_CPU(struct task_struct *, current_task); static __always_inline struct task_struct *get_current(void) { - return x86_read_percpu(current_task); + return percpu_read(current_task); } #else /* X86_32 */ diff --git a/arch/x86/include/asm/irq_regs_32.h b/arch/x86/include/asm/irq_regs_32.h index 86afd747345..d7ed33ee94e 100644 --- a/arch/x86/include/asm/irq_regs_32.h +++ b/arch/x86/include/asm/irq_regs_32.h @@ -15,7 +15,7 @@ DECLARE_PER_CPU(struct pt_regs *, irq_regs); static inline struct pt_regs *get_irq_regs(void) { - return x86_read_percpu(irq_regs); + return percpu_read(irq_regs); } static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs) @@ -23,7 +23,7 @@ static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs) struct pt_regs *old_regs; old_regs = get_irq_regs(); - x86_write_percpu(irq_regs, new_regs); + percpu_write(irq_regs, new_regs); return old_regs; } diff --git a/arch/x86/include/asm/mmu_context_32.h b/arch/x86/include/asm/mmu_context_32.h index 7e98ce1d2c0..08b53454f83 100644 --- a/arch/x86/include/asm/mmu_context_32.h +++ b/arch/x86/include/asm/mmu_context_32.h @@ -4,8 +4,8 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) { #ifdef CONFIG_SMP - if (x86_read_percpu(cpu_tlbstate.state) == TLBSTATE_OK) - x86_write_percpu(cpu_tlbstate.state, TLBSTATE_LAZY); + if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK) + percpu_write(cpu_tlbstate.state, TLBSTATE_LAZY); #endif } @@ -19,8 +19,8 @@ static inline void switch_mm(struct mm_struct *prev, /* stop flush ipis for the previous mm */ cpu_clear(cpu, prev->cpu_vm_mask); #ifdef CONFIG_SMP - x86_write_percpu(cpu_tlbstate.state, TLBSTATE_OK); - x86_write_percpu(cpu_tlbstate.active_mm, next); + percpu_write(cpu_tlbstate.state, TLBSTATE_OK); + percpu_write(cpu_tlbstate.active_mm, next); #endif cpu_set(cpu, next->cpu_vm_mask); @@ -35,8 +35,8 @@ static inline void switch_mm(struct mm_struct *prev, } #ifdef CONFIG_SMP else { - x86_write_percpu(cpu_tlbstate.state, TLBSTATE_OK); - BUG_ON(x86_read_percpu(cpu_tlbstate.active_mm) != next); + percpu_write(cpu_tlbstate.state, TLBSTATE_OK); + BUG_ON(percpu_read(cpu_tlbstate.active_mm) != next); if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) { /* We were in lazy tlb mode and leave_mm disabled diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h index e3d3a081d79..47f274fe695 100644 --- a/arch/x86/include/asm/pda.h +++ b/arch/x86/include/asm/pda.h @@ -45,11 +45,11 @@ extern void pda_init(int); #define cpu_pda(cpu) (&per_cpu(__pda, cpu)) -#define read_pda(field) x86_read_percpu(__pda.field) -#define write_pda(field, val) x86_write_percpu(__pda.field, val) -#define add_pda(field, val) x86_add_percpu(__pda.field, val) -#define sub_pda(field, val) x86_sub_percpu(__pda.field, val) -#define or_pda(field, val) x86_or_percpu(__pda.field, val) +#define read_pda(field) percpu_read(__pda.field) +#define write_pda(field, val) percpu_write(__pda.field, val) +#define add_pda(field, val) percpu_add(__pda.field, val) +#define sub_pda(field, val) percpu_sub(__pda.field, val) +#define or_pda(field, val) percpu_or(__pda.field, val) /* This is not atomic against other CPUs -- CPU preemption needs to be off */ #define test_and_clear_bit_pda(bit, field) \ diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index 328b31a429d..03aa4b00a1c 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h @@ -40,16 +40,11 @@ #ifdef CONFIG_SMP #define __percpu_seg_str "%%"__stringify(__percpu_seg)":" -#define __my_cpu_offset x86_read_percpu(this_cpu_off) +#define __my_cpu_offset percpu_read(this_cpu_off) #else #define __percpu_seg_str #endif -#include - -/* We can use this directly for local CPU (faster). */ -DECLARE_PER_CPU(unsigned long, this_cpu_off); - /* For arch-specific code, we can use direct single-insn ops (they * don't give an lvalue though). */ extern void __bad_percpu_size(void); @@ -115,11 +110,13 @@ do { \ ret__; \ }) -#define x86_read_percpu(var) percpu_from_op("mov", per_cpu__##var) -#define x86_write_percpu(var, val) percpu_to_op("mov", per_cpu__##var, val) -#define x86_add_percpu(var, val) percpu_to_op("add", per_cpu__##var, val) -#define x86_sub_percpu(var, val) percpu_to_op("sub", per_cpu__##var, val) -#define x86_or_percpu(var, val) percpu_to_op("or", per_cpu__##var, val) +#define percpu_read(var) percpu_from_op("mov", per_cpu__##var) +#define percpu_write(var, val) percpu_to_op("mov", per_cpu__##var, val) +#define percpu_add(var, val) percpu_to_op("add", per_cpu__##var, val) +#define percpu_sub(var, val) percpu_to_op("sub", per_cpu__##var, val) +#define percpu_and(var, val) percpu_to_op("and", per_cpu__##var, val) +#define percpu_or(var, val) percpu_to_op("or", per_cpu__##var, val) +#define percpu_xor(var, val) percpu_to_op("xor", per_cpu__##var, val) /* This is not atomic against other CPUs -- CPU preemption needs to be off */ #define x86_test_and_clear_bit_percpu(bit, var) \ @@ -131,6 +128,11 @@ do { \ old__; \ }) +#include + +/* We can use this directly for local CPU (faster). */ +DECLARE_PER_CPU(unsigned long, this_cpu_off); + #ifdef CONFIG_X86_64 extern void load_pda_offset(int cpu); #else diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index 127415402ea..c7bbbbe65d3 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -160,7 +160,7 @@ extern unsigned disabled_cpus __cpuinitdata; * from the initial startup. We map APIC_BASE very early in page_setup(), * so this is correct in the x86 case. */ -#define raw_smp_processor_id() (x86_read_percpu(cpu_number)) +#define raw_smp_processor_id() (percpu_read(cpu_number)) extern int safe_smp_processor_id(void); #elif defined(CONFIG_X86_64_SMP) diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index a546f55c77b..77d546817d9 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -591,7 +591,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) if (prev->gs | next->gs) loadsegment(gs, next->gs); - x86_write_percpu(current_task, next_p); + percpu_write(current_task, next_p); return prev_p; } diff --git a/arch/x86/kernel/tlb_32.c b/arch/x86/kernel/tlb_32.c index ec53818f4e3..e65449d0f7d 100644 --- a/arch/x86/kernel/tlb_32.c +++ b/arch/x86/kernel/tlb_32.c @@ -34,8 +34,8 @@ static DEFINE_SPINLOCK(tlbstate_lock); */ void leave_mm(int cpu) { - BUG_ON(x86_read_percpu(cpu_tlbstate.state) == TLBSTATE_OK); - cpu_clear(cpu, x86_read_percpu(cpu_tlbstate.active_mm)->cpu_vm_mask); + BUG_ON(percpu_read(cpu_tlbstate.state) == TLBSTATE_OK); + cpu_clear(cpu, percpu_read(cpu_tlbstate.active_mm)->cpu_vm_mask); load_cr3(swapper_pg_dir); } EXPORT_SYMBOL_GPL(leave_mm); @@ -103,8 +103,8 @@ void smp_invalidate_interrupt(struct pt_regs *regs) * BUG(); */ - if (flush_mm == x86_read_percpu(cpu_tlbstate.active_mm)) { - if (x86_read_percpu(cpu_tlbstate.state) == TLBSTATE_OK) { + if (flush_mm == percpu_read(cpu_tlbstate.active_mm)) { + if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK) { if (flush_va == TLB_FLUSH_ALL) local_flush_tlb(); else @@ -222,7 +222,7 @@ static void do_flush_tlb_all(void *info) unsigned long cpu = smp_processor_id(); __flush_tlb_all(); - if (x86_read_percpu(cpu_tlbstate.state) == TLBSTATE_LAZY) + if (percpu_read(cpu_tlbstate.state) == TLBSTATE_LAZY) leave_mm(cpu); } diff --git a/arch/x86/mach-voyager/voyager_smp.c b/arch/x86/mach-voyager/voyager_smp.c index 1a48368acb0..96f15b09a4c 100644 --- a/arch/x86/mach-voyager/voyager_smp.c +++ b/arch/x86/mach-voyager/voyager_smp.c @@ -402,7 +402,7 @@ void __init find_smp_config(void) VOYAGER_SUS_IN_CONTROL_PORT); current_thread_info()->cpu = boot_cpu_id; - x86_write_percpu(cpu_number, boot_cpu_id); + percpu_write(cpu_number, boot_cpu_id); } /* @@ -1782,7 +1782,7 @@ static void __init voyager_smp_cpus_done(unsigned int max_cpus) void __init smp_setup_processor_id(void) { current_thread_info()->cpu = hard_smp_processor_id(); - x86_write_percpu(cpu_number, hard_smp_processor_id()); + percpu_write(cpu_number, hard_smp_processor_id()); } static void voyager_send_call_func(cpumask_t callmask) diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 312414ef936..75b94139e1f 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -695,17 +695,17 @@ static void xen_write_cr0(unsigned long cr0) static void xen_write_cr2(unsigned long cr2) { - x86_read_percpu(xen_vcpu)->arch.cr2 = cr2; + percpu_read(xen_vcpu)->arch.cr2 = cr2; } static unsigned long xen_read_cr2(void) { - return x86_read_percpu(xen_vcpu)->arch.cr2; + return percpu_read(xen_vcpu)->arch.cr2; } static unsigned long xen_read_cr2_direct(void) { - return x86_read_percpu(xen_vcpu_info.arch.cr2); + return percpu_read(xen_vcpu_info.arch.cr2); } static void xen_write_cr4(unsigned long cr4) @@ -718,12 +718,12 @@ static void xen_write_cr4(unsigned long cr4) static unsigned long xen_read_cr3(void) { - return x86_read_percpu(xen_cr3); + return percpu_read(xen_cr3); } static void set_current_cr3(void *v) { - x86_write_percpu(xen_current_cr3, (unsigned long)v); + percpu_write(xen_current_cr3, (unsigned long)v); } static void __xen_write_cr3(bool kernel, unsigned long cr3) @@ -748,7 +748,7 @@ static void __xen_write_cr3(bool kernel, unsigned long cr3) MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); if (kernel) { - x86_write_percpu(xen_cr3, cr3); + percpu_write(xen_cr3, cr3); /* Update xen_current_cr3 once the batch has actually been submitted. */ @@ -764,7 +764,7 @@ static void xen_write_cr3(unsigned long cr3) /* Update while interrupts are disabled, so its atomic with respect to ipis */ - x86_write_percpu(xen_cr3, cr3); + percpu_write(xen_cr3, cr3); __xen_write_cr3(true, cr3); diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c index bb042608c60..2e8271431e1 100644 --- a/arch/x86/xen/irq.c +++ b/arch/x86/xen/irq.c @@ -39,7 +39,7 @@ static unsigned long xen_save_fl(void) struct vcpu_info *vcpu; unsigned long flags; - vcpu = x86_read_percpu(xen_vcpu); + vcpu = percpu_read(xen_vcpu); /* flag has opposite sense of mask */ flags = !vcpu->evtchn_upcall_mask; @@ -62,7 +62,7 @@ static void xen_restore_fl(unsigned long flags) make sure we're don't switch CPUs between getting the vcpu pointer and updating the mask. */ preempt_disable(); - vcpu = x86_read_percpu(xen_vcpu); + vcpu = percpu_read(xen_vcpu); vcpu->evtchn_upcall_mask = flags; preempt_enable_no_resched(); @@ -83,7 +83,7 @@ static void xen_irq_disable(void) make sure we're don't switch CPUs between getting the vcpu pointer and updating the mask. */ preempt_disable(); - x86_read_percpu(xen_vcpu)->evtchn_upcall_mask = 1; + percpu_read(xen_vcpu)->evtchn_upcall_mask = 1; preempt_enable_no_resched(); } @@ -96,7 +96,7 @@ static void xen_irq_enable(void) the caller is confused and is trying to re-enable interrupts on an indeterminate processor. */ - vcpu = x86_read_percpu(xen_vcpu); + vcpu = percpu_read(xen_vcpu); vcpu->evtchn_upcall_mask = 0; /* Doesn't matter if we get preempted here, because any diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 503c240e26c..7bc7852cc5c 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -1074,7 +1074,7 @@ static void drop_other_mm_ref(void *info) /* If this cpu still has a stale cr3 reference, then make sure it has been flushed. */ - if (x86_read_percpu(xen_current_cr3) == __pa(mm->pgd)) { + if (percpu_read(xen_current_cr3) == __pa(mm->pgd)) { load_cr3(swapper_pg_dir); arch_flush_lazy_cpu_mode(); } diff --git a/arch/x86/xen/multicalls.h b/arch/x86/xen/multicalls.h index 85893824161..e786fa7f261 100644 --- a/arch/x86/xen/multicalls.h +++ b/arch/x86/xen/multicalls.h @@ -39,7 +39,7 @@ static inline void xen_mc_issue(unsigned mode) xen_mc_flush(); /* restore flags saved in xen_mc_batch */ - local_irq_restore(x86_read_percpu(xen_mc_irq_flags)); + local_irq_restore(percpu_read(xen_mc_irq_flags)); } /* Set up a callback to be called when the current batch is flushed */ diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 83fa4236477..3bfd6dd0b47 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -78,7 +78,7 @@ static __cpuinit void cpu_bringup(void) xen_setup_cpu_clockevents(); cpu_set(cpu, cpu_online_map); - x86_write_percpu(cpu_state, CPU_ONLINE); + percpu_write(cpu_state, CPU_ONLINE); wmb(); /* We can take interrupts now: we're officially "up". */ diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h index b0e63c672eb..00f45ff081a 100644 --- a/include/asm-generic/percpu.h +++ b/include/asm-generic/percpu.h @@ -80,4 +80,56 @@ extern void setup_per_cpu_areas(void); #define DECLARE_PER_CPU(type, name) extern PER_CPU_ATTRIBUTES \ __typeof__(type) per_cpu_var(name) +/* + * Optional methods for optimized non-lvalue per-cpu variable access. + * + * @var can be a percpu variable or a field of it and its size should + * equal char, int or long. percpu_read() evaluates to a lvalue and + * all others to void. + * + * These operations are guaranteed to be atomic w.r.t. preemption. + * The generic versions use plain get/put_cpu_var(). Archs are + * encouraged to implement single-instruction alternatives which don't + * require preemption protection. + */ +#ifndef percpu_read +# define percpu_read(var) \ + ({ \ + typeof(per_cpu_var(var)) __tmp_var__; \ + __tmp_var__ = get_cpu_var(var); \ + put_cpu_var(var); \ + __tmp_var__; \ + }) +#endif + +#define __percpu_generic_to_op(var, val, op) \ +do { \ + get_cpu_var(var) op val; \ + put_cpu_var(var); \ +} while (0) + +#ifndef percpu_write +# define percpu_write(var, val) __percpu_generic_to_op(var, (val), =) +#endif + +#ifndef percpu_add +# define percpu_add(var, val) __percpu_generic_to_op(var, (val), +=) +#endif + +#ifndef percpu_sub +# define percpu_sub(var, val) __percpu_generic_to_op(var, (val), -=) +#endif + +#ifndef percpu_and +# define percpu_and(var, val) __percpu_generic_to_op(var, (val), &=) +#endif + +#ifndef percpu_or +# define percpu_or(var, val) __percpu_generic_to_op(var, (val), |=) +#endif + +#ifndef percpu_xor +# define percpu_xor(var, val) __percpu_generic_to_op(var, (val), ^=) +#endif + #endif /* _ASM_GENERIC_PERCPU_H_ */ -- cgit From a338af2c648f5e07c582154745a6c60cd2d8bf12 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 16 Jan 2009 11:19:03 +0900 Subject: x86: fix build bug introduced during merge EXPORT_PER_CPU_SYMBOL() got misplaced during merge leading to build failure. Fix it. Signed-off-by: Tejun Heo --- arch/x86/kernel/setup_percpu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index daeedf82c15..b5c35af2011 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -86,9 +86,8 @@ void __cpuinit load_pda_offset(int cpu) } #ifndef CONFIG_SMP DEFINE_PER_CPU(struct x8664_pda, __pda); -EXPORT_PER_CPU_SYMBOL(__pda); #endif - +EXPORT_PER_CPU_SYMBOL(__pda); #endif /* CONFIG_SMP && CONFIG_X86_64 */ #ifdef CONFIG_X86_64 -- cgit From cd3adf52309867955d6e2175246b526442235805 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 16 Jan 2009 12:11:43 +0900 Subject: x86_64: initialize this_cpu_off to __per_cpu_load On x86_64, if get_per_cpu_var() is used before per cpu area is setup (if lockdep is turned on, it happens), it needs this_cpu_off to point to __per_cpu_load. Initialize accordingly. Signed-off-by: Tejun Heo --- arch/x86/kernel/smpcommon.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/x86/kernel/smpcommon.c b/arch/x86/kernel/smpcommon.c index 84395fabc41..7e157810062 100644 --- a/arch/x86/kernel/smpcommon.c +++ b/arch/x86/kernel/smpcommon.c @@ -3,8 +3,13 @@ */ #include #include +#include +#ifdef CONFIG_X86_64 +DEFINE_PER_CPU(unsigned long, this_cpu_off) = (unsigned long)__per_cpu_load; +#else DEFINE_PER_CPU(unsigned long, this_cpu_off); +#endif EXPORT_PER_CPU_SYMBOL(this_cpu_off); #ifdef CONFIG_X86_32 -- cgit From 94be9a58d7e683ac3c1df1858a17f09ebade8da0 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Fri, 16 Jan 2009 10:17:09 -0500 Subject: [libata] get-identity ioctl: Fix use of invalid memory pointer for SAS drivers. Caught by Ke Wei (and team?) at Marvell. Also, move the ata_scsi_ioctl export to libata-scsi.c, as that seems to be the general trend. Acked-by: James Bottomley Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 1 - drivers/ata/libata-scsi.c | 17 +++++++++++++---- drivers/scsi/ipr.c | 2 +- drivers/scsi/libsas/sas_scsi_host.c | 2 +- include/linux/libata.h | 2 ++ 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 71218d76d75..552ecae1343 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -6638,7 +6638,6 @@ EXPORT_SYMBOL_GPL(ata_dev_pair); EXPORT_SYMBOL_GPL(ata_port_disable); EXPORT_SYMBOL_GPL(ata_ratelimit); EXPORT_SYMBOL_GPL(ata_wait_register); -EXPORT_SYMBOL_GPL(ata_scsi_ioctl); EXPORT_SYMBOL_GPL(ata_scsi_queuecmd); EXPORT_SYMBOL_GPL(ata_scsi_slave_config); EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy); diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 9e92107691f..a1a6e6298c3 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -423,9 +423,9 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev, * RETURNS: * Zero on success, negative errno on error. */ -static int ata_get_identity(struct scsi_device *sdev, void __user *arg) +static int ata_get_identity(struct ata_port *ap, struct scsi_device *sdev, + void __user *arg) { - struct ata_port *ap = ata_shost_to_port(sdev->host); struct ata_device *dev = ata_scsi_find_dev(ap, sdev); u16 __user *dst = arg; char buf[40]; @@ -645,7 +645,8 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) return rc; } -int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg) +int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev, + int cmd, void __user *arg) { int val = -EINVAL, rc = -EINVAL; @@ -663,7 +664,7 @@ int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg) return 0; case HDIO_GET_IDENTITY: - return ata_get_identity(scsidev, arg); + return ata_get_identity(ap, scsidev, arg); case HDIO_DRIVE_CMD: if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) @@ -682,6 +683,14 @@ int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg) return rc; } +EXPORT_SYMBOL_GPL(ata_sas_scsi_ioctl); + +int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg) +{ + return ata_sas_scsi_ioctl(ata_shost_to_port(scsidev->host), + scsidev, cmd, arg); +} +EXPORT_SYMBOL_GPL(ata_scsi_ioctl); /** * ata_scsi_qc_new - acquire new ata_queued_cmd reference diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 841f460edbc..07829009a8b 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -4912,7 +4912,7 @@ static int ipr_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) if (res && ipr_is_gata(res)) { if (cmd == HDIO_GET_IDENTITY) return -ENOTTY; - return ata_scsi_ioctl(sdev, cmd, arg); + return ata_sas_scsi_ioctl(res->sata_port->ap, sdev, cmd, arg); } return -EINVAL; diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 744838780ad..1c558d3bce1 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -717,7 +717,7 @@ int sas_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) struct domain_device *dev = sdev_to_domain_dev(sdev); if (dev_is_sata(dev)) - return ata_scsi_ioctl(sdev, cmd, arg); + return ata_sas_scsi_ioctl(dev->sata_dev.ap, sdev, cmd, arg); return -EINVAL; } diff --git a/include/linux/libata.h b/include/linux/libata.h index b6b8a7f3ec6..73b69c7071c 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -927,6 +927,8 @@ extern void ata_host_init(struct ata_host *, struct device *, extern int ata_scsi_detect(struct scsi_host_template *sht); extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg); extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); +extern int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *dev, + int cmd, void __user *arg); extern void ata_sas_port_destroy(struct ata_port *); extern struct ata_port *ata_sas_port_alloc(struct ata_host *, struct ata_port_info *, struct Scsi_Host *); -- cgit From 16028232bf6dc5ed7e4bd341ef335f386229ad0b Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 16 Jan 2009 15:27:27 +0900 Subject: pata_atiixp: update port enabledness test handling Port enabledness test fits much better into init_one() instead of pre_reset(). The reason why these tests are in pre_reset() is purely historical at this point. Move it to init_one(). This will help further changes. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/pata_atiixp.c | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index 0e2cde8f997..506adde8ebb 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c @@ -32,21 +32,6 @@ enum { ATIIXP_IDE_UDMA_MODE = 0x56 }; -static int atiixp_pre_reset(struct ata_link *link, unsigned long deadline) -{ - struct ata_port *ap = link->ap; - static const struct pci_bits atiixp_enable_bits[] = { - { 0x48, 1, 0x01, 0x00 }, - { 0x48, 1, 0x08, 0x00 } - }; - struct pci_dev *pdev = to_pci_dev(ap->host->dev); - - if (!pci_test_config_bits(pdev, &atiixp_enable_bits[ap->port_no])) - return -ENOENT; - - return ata_sff_prereset(link, deadline); -} - static int atiixp_cable_detect(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); @@ -229,10 +214,9 @@ static struct ata_port_operations atiixp_port_ops = { .cable_detect = atiixp_cable_detect, .set_piomode = atiixp_set_piomode, .set_dmamode = atiixp_set_dmamode, - .prereset = atiixp_pre_reset, }; -static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id) +static int atiixp_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { static const struct ata_port_info info = { .flags = ATA_FLAG_SLAVE_POSS, @@ -241,8 +225,18 @@ static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id) .udma_mask = 0x3F, .port_ops = &atiixp_port_ops }; - const struct ata_port_info *ppi[] = { &info, NULL }; - return ata_pci_sff_init_one(dev, ppi, &atiixp_sht, NULL); + static const struct pci_bits atiixp_enable_bits[] = { + { 0x48, 1, 0x01, 0x00 }, + { 0x48, 1, 0x08, 0x00 } + }; + const struct ata_port_info *ppi[] = { &info, &info }; + int i; + + for (i = 0; i < 2; i++) + if (!pci_test_config_bits(pdev, &atiixp_enable_bits[i])) + ppi[i] = &ata_dummy_port_info; + + return ata_pci_sff_init_one(pdev, ppi, &atiixp_sht, NULL); } static const struct pci_device_id atiixp[] = { -- cgit From 6813952021a7820a505002de260bda36978671f7 Mon Sep 17 00:00:00 2001 From: "JosephChan@via.com.tw" Date: Fri, 16 Jan 2009 19:44:55 +0800 Subject: sata_via: Add VT8261 support Signed-off-by: Joseph Chan Signed-off-by: Jeff Garzik --- drivers/ata/sata_via.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index c18935f0bda..5c62da9cd49 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -92,6 +92,8 @@ static const struct pci_device_id svia_pci_tbl[] = { { PCI_VDEVICE(VIA, 0x5372), vt6420 }, { PCI_VDEVICE(VIA, 0x7372), vt6420 }, { PCI_VDEVICE(VIA, 0x5287), vt8251 }, /* 2 sata chnls (Master/Slave) */ + { PCI_VDEVICE(VIA, 0x9000), vt8251 }, + { PCI_VDEVICE(VIA, 0x9040), vt8251 }, { } /* terminate list */ }; -- cgit From 3ada9c126499dd4700dcdbd5b9fe8110ad17f578 Mon Sep 17 00:00:00 2001 From: David Daney Date: Thu, 15 Jan 2009 17:45:31 -0800 Subject: libata: Add another column to the ata_timing table. The forthcoming OCTEON SOC Compact Flash driver needs an additional timing value that was not available in the ata_timing table. I add a new column for dmack_hold time. The values were obtained from the Compact Flash specification Rev 4.1. Signed-off-by: David Daney Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 72 ++++++++++++++++++++++++----------------------- include/linux/libata.h | 9 ++++-- 2 files changed, 43 insertions(+), 38 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 552ecae1343..88c242856da 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3029,33 +3029,33 @@ int sata_set_spd(struct ata_link *link) */ static const struct ata_timing ata_timing[] = { -/* { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960, 0 }, */ - { XFER_PIO_0, 70, 290, 240, 600, 165, 150, 600, 0 }, - { XFER_PIO_1, 50, 290, 93, 383, 125, 100, 383, 0 }, - { XFER_PIO_2, 30, 290, 40, 330, 100, 90, 240, 0 }, - { XFER_PIO_3, 30, 80, 70, 180, 80, 70, 180, 0 }, - { XFER_PIO_4, 25, 70, 25, 120, 70, 25, 120, 0 }, - { XFER_PIO_5, 15, 65, 25, 100, 65, 25, 100, 0 }, - { XFER_PIO_6, 10, 55, 20, 80, 55, 20, 80, 0 }, - - { XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 960, 0 }, - { XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 480, 0 }, - { XFER_SW_DMA_2, 60, 0, 0, 0, 120, 120, 240, 0 }, - - { XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 480, 0 }, - { XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 150, 0 }, - { XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 120, 0 }, - { XFER_MW_DMA_3, 25, 0, 0, 0, 65, 25, 100, 0 }, - { XFER_MW_DMA_4, 25, 0, 0, 0, 55, 20, 80, 0 }, - -/* { XFER_UDMA_SLOW, 0, 0, 0, 0, 0, 0, 0, 150 }, */ - { XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 120 }, - { XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 80 }, - { XFER_UDMA_2, 0, 0, 0, 0, 0, 0, 0, 60 }, - { XFER_UDMA_3, 0, 0, 0, 0, 0, 0, 0, 45 }, - { XFER_UDMA_4, 0, 0, 0, 0, 0, 0, 0, 30 }, - { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 20 }, - { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 15 }, +/* { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 0, 960, 0 }, */ + { XFER_PIO_0, 70, 290, 240, 600, 165, 150, 0, 600, 0 }, + { XFER_PIO_1, 50, 290, 93, 383, 125, 100, 0, 383, 0 }, + { XFER_PIO_2, 30, 290, 40, 330, 100, 90, 0, 240, 0 }, + { XFER_PIO_3, 30, 80, 70, 180, 80, 70, 0, 180, 0 }, + { XFER_PIO_4, 25, 70, 25, 120, 70, 25, 0, 120, 0 }, + { XFER_PIO_5, 15, 65, 25, 100, 65, 25, 0, 100, 0 }, + { XFER_PIO_6, 10, 55, 20, 80, 55, 20, 0, 80, 0 }, + + { XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 50, 960, 0 }, + { XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 30, 480, 0 }, + { XFER_SW_DMA_2, 60, 0, 0, 0, 120, 120, 20, 240, 0 }, + + { XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 20, 480, 0 }, + { XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 5, 150, 0 }, + { XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 5, 120, 0 }, + { XFER_MW_DMA_3, 25, 0, 0, 0, 65, 25, 5, 100, 0 }, + { XFER_MW_DMA_4, 25, 0, 0, 0, 55, 20, 5, 80, 0 }, + +/* { XFER_UDMA_SLOW, 0, 0, 0, 0, 0, 0, 0, 0, 150 }, */ + { XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 0, 120 }, + { XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 0, 80 }, + { XFER_UDMA_2, 0, 0, 0, 0, 0, 0, 0, 0, 60 }, + { XFER_UDMA_3, 0, 0, 0, 0, 0, 0, 0, 0, 45 }, + { XFER_UDMA_4, 0, 0, 0, 0, 0, 0, 0, 0, 30 }, + { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 0, 20 }, + { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 0, 15 }, { 0xFF } }; @@ -3065,14 +3065,15 @@ static const struct ata_timing ata_timing[] = { static void ata_timing_quantize(const struct ata_timing *t, struct ata_timing *q, int T, int UT) { - q->setup = EZ(t->setup * 1000, T); - q->act8b = EZ(t->act8b * 1000, T); - q->rec8b = EZ(t->rec8b * 1000, T); - q->cyc8b = EZ(t->cyc8b * 1000, T); - q->active = EZ(t->active * 1000, T); - q->recover = EZ(t->recover * 1000, T); - q->cycle = EZ(t->cycle * 1000, T); - q->udma = EZ(t->udma * 1000, UT); + q->setup = EZ(t->setup * 1000, T); + q->act8b = EZ(t->act8b * 1000, T); + q->rec8b = EZ(t->rec8b * 1000, T); + q->cyc8b = EZ(t->cyc8b * 1000, T); + q->active = EZ(t->active * 1000, T); + q->recover = EZ(t->recover * 1000, T); + q->dmack_hold = EZ(t->dmack_hold * 1000, T); + q->cycle = EZ(t->cycle * 1000, T); + q->udma = EZ(t->udma * 1000, UT); } void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b, @@ -3084,6 +3085,7 @@ void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b, if (what & ATA_TIMING_CYC8B ) m->cyc8b = max(a->cyc8b, b->cyc8b); if (what & ATA_TIMING_ACTIVE ) m->active = max(a->active, b->active); if (what & ATA_TIMING_RECOVER) m->recover = max(a->recover, b->recover); + if (what & ATA_TIMING_DMACK_HOLD) m->dmack_hold = max(a->dmack_hold, b->dmack_hold); if (what & ATA_TIMING_CYCLE ) m->cycle = max(a->cycle, b->cycle); if (what & ATA_TIMING_UDMA ) m->udma = max(a->udma, b->udma); } diff --git a/include/linux/libata.h b/include/linux/libata.h index 73b69c7071c..2c6bd66209f 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -401,12 +401,14 @@ enum { ATA_TIMING_CYC8B, ATA_TIMING_ACTIVE = (1 << 4), ATA_TIMING_RECOVER = (1 << 5), - ATA_TIMING_CYCLE = (1 << 6), - ATA_TIMING_UDMA = (1 << 7), + ATA_TIMING_DMACK_HOLD = (1 << 6), + ATA_TIMING_CYCLE = (1 << 7), + ATA_TIMING_UDMA = (1 << 8), ATA_TIMING_ALL = ATA_TIMING_SETUP | ATA_TIMING_ACT8B | ATA_TIMING_REC8B | ATA_TIMING_CYC8B | ATA_TIMING_ACTIVE | ATA_TIMING_RECOVER | - ATA_TIMING_CYCLE | ATA_TIMING_UDMA, + ATA_TIMING_DMACK_HOLD | ATA_TIMING_CYCLE | + ATA_TIMING_UDMA, }; enum ata_xfer_mask { @@ -866,6 +868,7 @@ struct ata_timing { unsigned short cyc8b; /* t0 for 8-bit I/O */ unsigned short active; /* t2 or tD */ unsigned short recover; /* t2i or tK */ + unsigned short dmack_hold; /* tj */ unsigned short cycle; /* t0 */ unsigned short udma; /* t2CYCTYP/2 */ }; -- cgit From 3c929c6f5aa7501790586a38dd8faca8fed9a158 Mon Sep 17 00:00:00 2001 From: David Daney Date: Thu, 15 Jan 2009 17:45:32 -0800 Subject: libata: New driver for OCTEON SOC Compact Flash interface (v7). Cavium OCTEON processor support was recently merged, so now we have this CF driver for your consideration. Most OCTEON variants have *no* DMA or interrupt support on the CF interface so for these, only PIO is supported. Although if DMA is available, we do take advantage of it. Signed-off-by: David Daney Signed-off-by: Jeff Garzik --- drivers/ata/Kconfig | 9 + drivers/ata/Makefile | 1 + drivers/ata/pata_octeon_cf.c | 965 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 975 insertions(+) create mode 100644 drivers/ata/pata_octeon_cf.c diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 1a7be96d627..503a908afc8 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -698,6 +698,15 @@ config PATA_IXP4XX_CF If unsure, say N. +config PATA_OCTEON_CF + tristate "OCTEON Boot Bus Compact Flash support" + depends on CPU_CAVIUM_OCTEON + help + This option enables a polled compact flash driver for use with + compact flash cards attached to the OCTEON boot bus. + + If unsure, say N. + config PATA_SCC tristate "Toshiba's Cell Reference Set IDE support" depends on PCI && PPC_CELLEB diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index 674965fa326..7f1ecf99528 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -69,6 +69,7 @@ obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp4xx_cf.o obj-$(CONFIG_PATA_SCC) += pata_scc.o obj-$(CONFIG_PATA_SCH) += pata_sch.o obj-$(CONFIG_PATA_BF54X) += pata_bf54x.o +obj-$(CONFIG_PATA_OCTEON_CF) += pata_octeon_cf.o obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o obj-$(CONFIG_PATA_OF_PLATFORM) += pata_of_platform.o obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c new file mode 100644 index 00000000000..0fe4ef309c6 --- /dev/null +++ b/drivers/ata/pata_octeon_cf.c @@ -0,0 +1,965 @@ +/* + * Driver for the Octeon bootbus compact flash. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2005 - 2009 Cavium Networks + * Copyright (C) 2008 Wind River Systems + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * The Octeon bootbus compact flash interface is connected in at least + * 3 different configurations on various evaluation boards: + * + * -- 8 bits no irq, no DMA + * -- 16 bits no irq, no DMA + * -- 16 bits True IDE mode with DMA, but no irq. + * + * In the last case the DMA engine can generate an interrupt when the + * transfer is complete. For the first two cases only PIO is supported. + * + */ + +#define DRV_NAME "pata_octeon_cf" +#define DRV_VERSION "2.1" + + +struct octeon_cf_port { + struct workqueue_struct *wq; + struct delayed_work delayed_finish; + struct ata_port *ap; + int dma_finished; +}; + +static struct scsi_host_template octeon_cf_sht = { + ATA_PIO_SHT(DRV_NAME), +}; + +/** + * Convert nanosecond based time to setting used in the + * boot bus timing register, based on timing multiple + */ +static unsigned int ns_to_tim_reg(unsigned int tim_mult, unsigned int nsecs) +{ + unsigned int val; + + /* + * Compute # of eclock periods to get desired duration in + * nanoseconds. + */ + val = DIV_ROUND_UP(nsecs * (octeon_get_clock_rate() / 1000000), + 1000 * tim_mult); + + return val; +} + +static void octeon_cf_set_boot_reg_cfg(int cs) +{ + union cvmx_mio_boot_reg_cfgx reg_cfg; + reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(cs)); + reg_cfg.s.dmack = 0; /* Don't assert DMACK on access */ + reg_cfg.s.tim_mult = 2; /* Timing mutiplier 2x */ + reg_cfg.s.rd_dly = 0; /* Sample on falling edge of BOOT_OE */ + reg_cfg.s.sam = 0; /* Don't combine write and output enable */ + reg_cfg.s.we_ext = 0; /* No write enable extension */ + reg_cfg.s.oe_ext = 0; /* No read enable extension */ + reg_cfg.s.en = 1; /* Enable this region */ + reg_cfg.s.orbit = 0; /* Don't combine with previous region */ + reg_cfg.s.ale = 0; /* Don't do address multiplexing */ + cvmx_write_csr(CVMX_MIO_BOOT_REG_CFGX(cs), reg_cfg.u64); +} + +/** + * Called after libata determines the needed PIO mode. This + * function programs the Octeon bootbus regions to support the + * timing requirements of the PIO mode. + * + * @ap: ATA port information + * @dev: ATA device + */ +static void octeon_cf_set_piomode(struct ata_port *ap, struct ata_device *dev) +{ + struct octeon_cf_data *ocd = ap->dev->platform_data; + union cvmx_mio_boot_reg_timx reg_tim; + int cs = ocd->base_region; + int T; + struct ata_timing timing; + + int use_iordy; + int trh; + int pause; + /* These names are timing parameters from the ATA spec */ + int t1; + int t2; + int t2i; + + T = (int)(2000000000000LL / octeon_get_clock_rate()); + + if (ata_timing_compute(dev, dev->pio_mode, &timing, T, T)) + BUG(); + + t1 = timing.setup; + if (t1) + t1--; + t2 = timing.active; + if (t2) + t2--; + t2i = timing.act8b; + if (t2i) + t2i--; + + trh = ns_to_tim_reg(2, 20); + if (trh) + trh--; + + pause = timing.cycle - timing.active - timing.setup - trh; + if (pause) + pause--; + + octeon_cf_set_boot_reg_cfg(cs); + if (ocd->dma_engine >= 0) + /* True IDE mode, program both chip selects. */ + octeon_cf_set_boot_reg_cfg(cs + 1); + + + use_iordy = ata_pio_need_iordy(dev); + + reg_tim.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_TIMX(cs)); + /* Disable page mode */ + reg_tim.s.pagem = 0; + /* Enable dynamic timing */ + reg_tim.s.waitm = use_iordy; + /* Pages are disabled */ + reg_tim.s.pages = 0; + /* We don't use multiplexed address mode */ + reg_tim.s.ale = 0; + /* Not used */ + reg_tim.s.page = 0; + /* Time after IORDY to coninue to assert the data */ + reg_tim.s.wait = 0; + /* Time to wait to complete the cycle. */ + reg_tim.s.pause = pause; + /* How long to hold after a write to de-assert CE. */ + reg_tim.s.wr_hld = trh; + /* How long to wait after a read to de-assert CE. */ + reg_tim.s.rd_hld = trh; + /* How long write enable is asserted */ + reg_tim.s.we = t2; + /* How long read enable is asserted */ + reg_tim.s.oe = t2; + /* Time after CE that read/write starts */ + reg_tim.s.ce = ns_to_tim_reg(2, 5); + /* Time before CE that address is valid */ + reg_tim.s.adr = 0; + + /* Program the bootbus region timing for the data port chip select. */ + cvmx_write_csr(CVMX_MIO_BOOT_REG_TIMX(cs), reg_tim.u64); + if (ocd->dma_engine >= 0) + /* True IDE mode, program both chip selects. */ + cvmx_write_csr(CVMX_MIO_BOOT_REG_TIMX(cs + 1), reg_tim.u64); +} + +static void octeon_cf_set_dmamode(struct ata_port *ap, struct ata_device *dev) +{ + struct octeon_cf_data *ocd = dev->link->ap->dev->platform_data; + union cvmx_mio_boot_dma_timx dma_tim; + unsigned int oe_a; + unsigned int oe_n; + unsigned int dma_ackh; + unsigned int dma_arq; + unsigned int pause; + unsigned int T0, Tkr, Td; + unsigned int tim_mult; + + const struct ata_timing *timing; + + timing = ata_timing_find_mode(dev->dma_mode); + T0 = timing->cycle; + Td = timing->active; + Tkr = timing->recover; + dma_ackh = timing->dmack_hold; + + dma_tim.u64 = 0; + /* dma_tim.s.tim_mult = 0 --> 4x */ + tim_mult = 4; + + /* not spec'ed, value in eclocks, not affected by tim_mult */ + dma_arq = 8; + pause = 25 - dma_arq * 1000 / + (octeon_get_clock_rate() / 1000000); /* Tz */ + + oe_a = Td; + /* Tkr from cf spec, lengthened to meet T0 */ + oe_n = max(T0 - oe_a, Tkr); + + dma_tim.s.dmack_pi = 1; + + dma_tim.s.oe_n = ns_to_tim_reg(tim_mult, oe_n); + dma_tim.s.oe_a = ns_to_tim_reg(tim_mult, oe_a); + + /* + * This is tI, C.F. spec. says 0, but Sony CF card requires + * more, we use 20 nS. + */ + dma_tim.s.dmack_s = ns_to_tim_reg(tim_mult, 20);; + dma_tim.s.dmack_h = ns_to_tim_reg(tim_mult, dma_ackh); + + dma_tim.s.dmarq = dma_arq; + dma_tim.s.pause = ns_to_tim_reg(tim_mult, pause); + + dma_tim.s.rd_dly = 0; /* Sample right on edge */ + + /* writes only */ + dma_tim.s.we_n = ns_to_tim_reg(tim_mult, oe_n); + dma_tim.s.we_a = ns_to_tim_reg(tim_mult, oe_a); + + pr_debug("ns to ticks (mult %d) of %d is: %d\n", tim_mult, 60, + ns_to_tim_reg(tim_mult, 60)); + pr_debug("oe_n: %d, oe_a: %d, dmack_s: %d, dmack_h: " + "%d, dmarq: %d, pause: %d\n", + dma_tim.s.oe_n, dma_tim.s.oe_a, dma_tim.s.dmack_s, + dma_tim.s.dmack_h, dma_tim.s.dmarq, dma_tim.s.pause); + + cvmx_write_csr(CVMX_MIO_BOOT_DMA_TIMX(ocd->dma_engine), + dma_tim.u64); + +} + +/** + * Handle an 8 bit I/O request. + * + * @dev: Device to access + * @buffer: Data buffer + * @buflen: Length of the buffer. + * @rw: True to write. + */ +static unsigned int octeon_cf_data_xfer8(struct ata_device *dev, + unsigned char *buffer, + unsigned int buflen, + int rw) +{ + struct ata_port *ap = dev->link->ap; + void __iomem *data_addr = ap->ioaddr.data_addr; + unsigned long words; + int count; + + words = buflen; + if (rw) { + count = 16; + while (words--) { + iowrite8(*buffer, data_addr); + buffer++; + /* + * Every 16 writes do a read so the bootbus + * FIFO doesn't fill up. + */ + if (--count == 0) { + ioread8(ap->ioaddr.altstatus_addr); + count = 16; + } + } + } else { + ioread8_rep(data_addr, buffer, words); + } + return buflen; +} + +/** + * Handle a 16 bit I/O request. + * + * @dev: Device to access + * @buffer: Data buffer + * @buflen: Length of the buffer. + * @rw: True to write. + */ +static unsigned int octeon_cf_data_xfer16(struct ata_device *dev, + unsigned char *buffer, + unsigned int buflen, + int rw) +{ + struct ata_port *ap = dev->link->ap; + void __iomem *data_addr = ap->ioaddr.data_addr; + unsigned long words; + int count; + + words = buflen / 2; + if (rw) { + count = 16; + while (words--) { + iowrite16(*(uint16_t *)buffer, data_addr); + buffer += sizeof(uint16_t); + /* + * Every 16 writes do a read so the bootbus + * FIFO doesn't fill up. + */ + if (--count == 0) { + ioread8(ap->ioaddr.altstatus_addr); + count = 16; + } + } + } else { + while (words--) { + *(uint16_t *)buffer = ioread16(data_addr); + buffer += sizeof(uint16_t); + } + } + /* Transfer trailing 1 byte, if any. */ + if (unlikely(buflen & 0x01)) { + __le16 align_buf[1] = { 0 }; + + if (rw == READ) { + align_buf[0] = cpu_to_le16(ioread16(data_addr)); + memcpy(buffer, align_buf, 1); + } else { + memcpy(align_buf, buffer, 1); + iowrite16(le16_to_cpu(align_buf[0]), data_addr); + } + words++; + } + return buflen; +} + +/** + * Read the taskfile for 16bit non-True IDE only. + */ +static void octeon_cf_tf_read16(struct ata_port *ap, struct ata_taskfile *tf) +{ + u16 blob; + /* The base of the registers is at ioaddr.data_addr. */ + void __iomem *base = ap->ioaddr.data_addr; + + blob = __raw_readw(base + 0xc); + tf->feature = blob >> 8; + + blob = __raw_readw(base + 2); + tf->nsect = blob & 0xff; + tf->lbal = blob >> 8; + + blob = __raw_readw(base + 4); + tf->lbam = blob & 0xff; + tf->lbah = blob >> 8; + + blob = __raw_readw(base + 6); + tf->device = blob & 0xff; + tf->command = blob >> 8; + + if (tf->flags & ATA_TFLAG_LBA48) { + if (likely(ap->ioaddr.ctl_addr)) { + iowrite8(tf->ctl | ATA_HOB, ap->ioaddr.ctl_addr); + + blob = __raw_readw(base + 0xc); + tf->hob_feature = blob >> 8; + + blob = __raw_readw(base + 2); + tf->hob_nsect = blob & 0xff; + tf->hob_lbal = blob >> 8; + + blob = __raw_readw(base + 4); + tf->hob_lbam = blob & 0xff; + tf->hob_lbah = blob >> 8; + + iowrite8(tf->ctl, ap->ioaddr.ctl_addr); + ap->last_ctl = tf->ctl; + } else { + WARN_ON(1); + } + } +} + +static u8 octeon_cf_check_status16(struct ata_port *ap) +{ + u16 blob; + void __iomem *base = ap->ioaddr.data_addr; + + blob = __raw_readw(base + 6); + return blob >> 8; +} + +static int octeon_cf_softreset16(struct ata_link *link, unsigned int *classes, + unsigned long deadline) +{ + struct ata_port *ap = link->ap; + void __iomem *base = ap->ioaddr.data_addr; + int rc; + u8 err; + + DPRINTK("about to softreset\n"); + __raw_writew(ap->ctl, base + 0xe); + udelay(20); + __raw_writew(ap->ctl | ATA_SRST, base + 0xe); + udelay(20); + __raw_writew(ap->ctl, base + 0xe); + + rc = ata_sff_wait_after_reset(link, 1, deadline); + if (rc) { + ata_link_printk(link, KERN_ERR, "SRST failed (errno=%d)\n", rc); + return rc; + } + + /* determine by signature whether we have ATA or ATAPI devices */ + classes[0] = ata_sff_dev_classify(&link->device[0], 1, &err); + DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]); + return 0; +} + +/** + * Load the taskfile for 16bit non-True IDE only. The device_addr is + * not loaded, we do this as part of octeon_cf_exec_command16. + */ +static void octeon_cf_tf_load16(struct ata_port *ap, + const struct ata_taskfile *tf) +{ + unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; + /* The base of the registers is at ioaddr.data_addr. */ + void __iomem *base = ap->ioaddr.data_addr; + + if (tf->ctl != ap->last_ctl) { + iowrite8(tf->ctl, ap->ioaddr.ctl_addr); + ap->last_ctl = tf->ctl; + ata_wait_idle(ap); + } + if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { + __raw_writew(tf->hob_feature << 8, base + 0xc); + __raw_writew(tf->hob_nsect | tf->hob_lbal << 8, base + 2); + __raw_writew(tf->hob_lbam | tf->hob_lbah << 8, base + 4); + VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", + tf->hob_feature, + tf->hob_nsect, + tf->hob_lbal, + tf->hob_lbam, + tf->hob_lbah); + } + if (is_addr) { + __raw_writew(tf->feature << 8, base + 0xc); + __raw_writew(tf->nsect | tf->lbal << 8, base + 2); + __raw_writew(tf->lbam | tf->lbah << 8, base + 4); + VPRINTK("feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", + tf->feature, + tf->nsect, + tf->lbal, + tf->lbam, + tf->lbah); + } + ata_wait_idle(ap); +} + + +static void octeon_cf_dev_select(struct ata_port *ap, unsigned int device) +{ +/* There is only one device, do nothing. */ + return; +} + +/* + * Issue ATA command to host controller. The device_addr is also sent + * as it must be written in a combined write with the command. + */ +static void octeon_cf_exec_command16(struct ata_port *ap, + const struct ata_taskfile *tf) +{ + /* The base of the registers is at ioaddr.data_addr. */ + void __iomem *base = ap->ioaddr.data_addr; + u16 blob; + + if (tf->flags & ATA_TFLAG_DEVICE) { + VPRINTK("device 0x%X\n", tf->device); + blob = tf->device; + } else { + blob = 0; + } + + DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command); + blob |= (tf->command << 8); + __raw_writew(blob, base + 6); + + + ata_wait_idle(ap); +} + +static u8 octeon_cf_irq_on(struct ata_port *ap) +{ + return 0; +} + +static void octeon_cf_irq_clear(struct ata_port *ap) +{ + return; +} + +static void octeon_cf_dma_setup(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + struct octeon_cf_port *cf_port; + + cf_port = (struct octeon_cf_port *)ap->private_data; + DPRINTK("ENTER\n"); + /* issue r/w command */ + qc->cursg = qc->sg; + cf_port->dma_finished = 0; + ap->ops->sff_exec_command(ap, &qc->tf); + DPRINTK("EXIT\n"); +} + +/** + * Start a DMA transfer that was already setup + * + * @qc: Information about the DMA + */ +static void octeon_cf_dma_start(struct ata_queued_cmd *qc) +{ + struct octeon_cf_data *ocd = qc->ap->dev->platform_data; + union cvmx_mio_boot_dma_cfgx mio_boot_dma_cfg; + union cvmx_mio_boot_dma_intx mio_boot_dma_int; + struct scatterlist *sg; + + VPRINTK("%d scatterlists\n", qc->n_elem); + + /* Get the scatter list entry we need to DMA into */ + sg = qc->cursg; + BUG_ON(!sg); + + /* + * Clear the DMA complete status. + */ + mio_boot_dma_int.u64 = 0; + mio_boot_dma_int.s.done = 1; + cvmx_write_csr(CVMX_MIO_BOOT_DMA_INTX(ocd->dma_engine), + mio_boot_dma_int.u64); + + /* Enable the interrupt. */ + cvmx_write_csr(CVMX_MIO_BOOT_DMA_INT_ENX(ocd->dma_engine), + mio_boot_dma_int.u64); + + /* Set the direction of the DMA */ + mio_boot_dma_cfg.u64 = 0; + mio_boot_dma_cfg.s.en = 1; + mio_boot_dma_cfg.s.rw = ((qc->tf.flags & ATA_TFLAG_WRITE) != 0); + + /* + * Don't stop the DMA if the device deasserts DMARQ. Many + * compact flashes deassert DMARQ for a short time between + * sectors. Instead of stopping and restarting the DMA, we'll + * let the hardware do it. If the DMA is really stopped early + * due to an error condition, a later timeout will force us to + * stop. + */ + mio_boot_dma_cfg.s.clr = 0; + + /* Size is specified in 16bit words and minus one notation */ + mio_boot_dma_cfg.s.size = sg_dma_len(sg) / 2 - 1; + + /* We need to swap the high and low bytes of every 16 bits */ + mio_boot_dma_cfg.s.swap8 = 1; + + mio_boot_dma_cfg.s.adr = sg_dma_address(sg); + + VPRINTK("%s %d bytes address=%p\n", + (mio_boot_dma_cfg.s.rw) ? "write" : "read", sg->length, + (void *)(unsigned long)mio_boot_dma_cfg.s.adr); + + cvmx_write_csr(CVMX_MIO_BOOT_DMA_CFGX(ocd->dma_engine), + mio_boot_dma_cfg.u64); +} + +/** + * + * LOCKING: + * spin_lock_irqsave(host lock) + * + */ +static unsigned int octeon_cf_dma_finished(struct ata_port *ap, + struct ata_queued_cmd *qc) +{ + struct ata_eh_info *ehi = &ap->link.eh_info; + struct octeon_cf_data *ocd = ap->dev->platform_data; + union cvmx_mio_boot_dma_cfgx dma_cfg; + union cvmx_mio_boot_dma_intx dma_int; + struct octeon_cf_port *cf_port; + u8 status; + + VPRINTK("ata%u: protocol %d task_state %d\n", + ap->print_id, qc->tf.protocol, ap->hsm_task_state); + + + if (ap->hsm_task_state != HSM_ST_LAST) + return 0; + + cf_port = (struct octeon_cf_port *)ap->private_data; + + dma_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_DMA_CFGX(ocd->dma_engine)); + if (dma_cfg.s.size != 0xfffff) { + /* Error, the transfer was not complete. */ + qc->err_mask |= AC_ERR_HOST_BUS; + ap->hsm_task_state = HSM_ST_ERR; + } + + /* Stop and clear the dma engine. */ + dma_cfg.u64 = 0; + dma_cfg.s.size = -1; + cvmx_write_csr(CVMX_MIO_BOOT_DMA_CFGX(ocd->dma_engine), dma_cfg.u64); + + /* Disable the interrupt. */ + dma_int.u64 = 0; + cvmx_write_csr(CVMX_MIO_BOOT_DMA_INT_ENX(ocd->dma_engine), dma_int.u64); + + /* Clear the DMA complete status */ + dma_int.s.done = 1; + cvmx_write_csr(CVMX_MIO_BOOT_DMA_INTX(ocd->dma_engine), dma_int.u64); + + status = ap->ops->sff_check_status(ap); + + ata_sff_hsm_move(ap, qc, status, 0); + + if (unlikely(qc->err_mask) && (qc->tf.protocol == ATA_PROT_DMA)) + ata_ehi_push_desc(ehi, "DMA stat 0x%x", status); + + return 1; +} + +/* + * Check if any queued commands have more DMAs, if so start the next + * transfer, else do end of transfer handling. + */ +static irqreturn_t octeon_cf_interrupt(int irq, void *dev_instance) +{ + struct ata_host *host = dev_instance; + struct octeon_cf_port *cf_port; + int i; + unsigned int handled = 0; + unsigned long flags; + + spin_lock_irqsave(&host->lock, flags); + + DPRINTK("ENTER\n"); + for (i = 0; i < host->n_ports; i++) { + u8 status; + struct ata_port *ap; + struct ata_queued_cmd *qc; + union cvmx_mio_boot_dma_intx dma_int; + union cvmx_mio_boot_dma_cfgx dma_cfg; + struct octeon_cf_data *ocd; + + ap = host->ports[i]; + ocd = ap->dev->platform_data; + if (!ap || (ap->flags & ATA_FLAG_DISABLED)) + continue; + + ocd = ap->dev->platform_data; + cf_port = (struct octeon_cf_port *)ap->private_data; + dma_int.u64 = + cvmx_read_csr(CVMX_MIO_BOOT_DMA_INTX(ocd->dma_engine)); + dma_cfg.u64 = + cvmx_read_csr(CVMX_MIO_BOOT_DMA_CFGX(ocd->dma_engine)); + + qc = ata_qc_from_tag(ap, ap->link.active_tag); + + if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)) && + (qc->flags & ATA_QCFLAG_ACTIVE)) { + if (dma_int.s.done && !dma_cfg.s.en) { + if (!sg_is_last(qc->cursg)) { + qc->cursg = sg_next(qc->cursg); + handled = 1; + octeon_cf_dma_start(qc); + continue; + } else { + cf_port->dma_finished = 1; + } + } + if (!cf_port->dma_finished) + continue; + status = ioread8(ap->ioaddr.altstatus_addr); + if (status & (ATA_BUSY | ATA_DRQ)) { + /* + * We are busy, try to handle it + * later. This is the DMA finished + * interrupt, and it could take a + * little while for the card to be + * ready for more commands. + */ + /* Clear DMA irq. */ + dma_int.u64 = 0; + dma_int.s.done = 1; + cvmx_write_csr(CVMX_MIO_BOOT_DMA_INTX(ocd->dma_engine), + dma_int.u64); + + queue_delayed_work(cf_port->wq, + &cf_port->delayed_finish, 1); + handled = 1; + } else { + handled |= octeon_cf_dma_finished(ap, qc); + } + } + } + spin_unlock_irqrestore(&host->lock, flags); + DPRINTK("EXIT\n"); + return IRQ_RETVAL(handled); +} + +static void octeon_cf_delayed_finish(struct work_struct *work) +{ + struct octeon_cf_port *cf_port = container_of(work, + struct octeon_cf_port, + delayed_finish.work); + struct ata_port *ap = cf_port->ap; + struct ata_host *host = ap->host; + struct ata_queued_cmd *qc; + unsigned long flags; + u8 status; + + spin_lock_irqsave(&host->lock, flags); + + /* + * If the port is not waiting for completion, it must have + * handled it previously. The hsm_task_state is + * protected by host->lock. + */ + if (ap->hsm_task_state != HSM_ST_LAST || !cf_port->dma_finished) + goto out; + + status = ioread8(ap->ioaddr.altstatus_addr); + if (status & (ATA_BUSY | ATA_DRQ)) { + /* Still busy, try again. */ + queue_delayed_work(cf_port->wq, + &cf_port->delayed_finish, 1); + goto out; + } + qc = ata_qc_from_tag(ap, ap->link.active_tag); + if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)) && + (qc->flags & ATA_QCFLAG_ACTIVE)) + octeon_cf_dma_finished(ap, qc); +out: + spin_unlock_irqrestore(&host->lock, flags); +} + +static void octeon_cf_dev_config(struct ata_device *dev) +{ + /* + * A maximum of 2^20 - 1 16 bit transfers are possible with + * the bootbus DMA. So we need to throttle max_sectors to + * (2^12 - 1 == 4095) to assure that this can never happen. + */ + dev->max_sectors = min(dev->max_sectors, 4095U); +} + +/* + * Trap if driver tries to do standard bmdma commands. They are not + * supported. + */ +static void unreachable_qc(struct ata_queued_cmd *qc) +{ + BUG(); +} + +static u8 unreachable_port(struct ata_port *ap) +{ + BUG(); +} + +/* + * We don't do ATAPI DMA so return 0. + */ +static int octeon_cf_check_atapi_dma(struct ata_queued_cmd *qc) +{ + return 0; +} + +static unsigned int octeon_cf_qc_issue(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + + switch (qc->tf.protocol) { + case ATA_PROT_DMA: + WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING); + + ap->ops->sff_tf_load(ap, &qc->tf); /* load tf registers */ + octeon_cf_dma_setup(qc); /* set up dma */ + octeon_cf_dma_start(qc); /* initiate dma */ + ap->hsm_task_state = HSM_ST_LAST; + break; + + case ATAPI_PROT_DMA: + dev_err(ap->dev, "Error, ATAPI not supported\n"); + BUG(); + + default: + return ata_sff_qc_issue(qc); + } + + return 0; +} + +static struct ata_port_operations octeon_cf_ops = { + .inherits = &ata_sff_port_ops, + .check_atapi_dma = octeon_cf_check_atapi_dma, + .qc_prep = ata_noop_qc_prep, + .qc_issue = octeon_cf_qc_issue, + .sff_dev_select = octeon_cf_dev_select, + .sff_irq_on = octeon_cf_irq_on, + .sff_irq_clear = octeon_cf_irq_clear, + .bmdma_setup = unreachable_qc, + .bmdma_start = unreachable_qc, + .bmdma_stop = unreachable_qc, + .bmdma_status = unreachable_port, + .cable_detect = ata_cable_40wire, + .set_piomode = octeon_cf_set_piomode, + .set_dmamode = octeon_cf_set_dmamode, + .dev_config = octeon_cf_dev_config, +}; + +static int __devinit octeon_cf_probe(struct platform_device *pdev) +{ + struct resource *res_cs0, *res_cs1; + + void __iomem *cs0; + void __iomem *cs1 = NULL; + struct ata_host *host; + struct ata_port *ap; + struct octeon_cf_data *ocd; + int irq = 0; + irq_handler_t irq_handler = NULL; + void __iomem *base; + struct octeon_cf_port *cf_port; + + res_cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + if (!res_cs0) + return -EINVAL; + + ocd = pdev->dev.platform_data; + + cs0 = devm_ioremap_nocache(&pdev->dev, res_cs0->start, + res_cs0->end - res_cs0->start + 1); + + if (!cs0) + return -ENOMEM; + + /* Determine from availability of DMA if True IDE mode or not */ + if (ocd->dma_engine >= 0) { + res_cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res_cs1) + return -EINVAL; + + cs1 = devm_ioremap_nocache(&pdev->dev, res_cs1->start, + res_cs0->end - res_cs1->start + 1); + + if (!cs1) + return -ENOMEM; + } + + cf_port = kzalloc(sizeof(*cf_port), GFP_KERNEL); + if (!cf_port) + return -ENOMEM; + + /* allocate host */ + host = ata_host_alloc(&pdev->dev, 1); + if (!host) + goto free_cf_port; + + ap = host->ports[0]; + ap->private_data = cf_port; + cf_port->ap = ap; + ap->ops = &octeon_cf_ops; + ap->pio_mask = 0x7f; /* Support PIO 0-6 */ + ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY + | ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING; + + base = cs0 + ocd->base_region_bias; + if (!ocd->is16bit) { + ap->ioaddr.cmd_addr = base; + ata_sff_std_ports(&ap->ioaddr); + + ap->ioaddr.altstatus_addr = base + 0xe; + ap->ioaddr.ctl_addr = base + 0xe; + octeon_cf_ops.sff_data_xfer = octeon_cf_data_xfer8; + } else if (cs1) { + /* Presence of cs1 indicates True IDE mode. */ + ap->ioaddr.cmd_addr = base + (ATA_REG_CMD << 1) + 1; + ap->ioaddr.data_addr = base + (ATA_REG_DATA << 1); + ap->ioaddr.error_addr = base + (ATA_REG_ERR << 1) + 1; + ap->ioaddr.feature_addr = base + (ATA_REG_FEATURE << 1) + 1; + ap->ioaddr.nsect_addr = base + (ATA_REG_NSECT << 1) + 1; + ap->ioaddr.lbal_addr = base + (ATA_REG_LBAL << 1) + 1; + ap->ioaddr.lbam_addr = base + (ATA_REG_LBAM << 1) + 1; + ap->ioaddr.lbah_addr = base + (ATA_REG_LBAH << 1) + 1; + ap->ioaddr.device_addr = base + (ATA_REG_DEVICE << 1) + 1; + ap->ioaddr.status_addr = base + (ATA_REG_STATUS << 1) + 1; + ap->ioaddr.command_addr = base + (ATA_REG_CMD << 1) + 1; + ap->ioaddr.altstatus_addr = cs1 + (6 << 1) + 1; + ap->ioaddr.ctl_addr = cs1 + (6 << 1) + 1; + octeon_cf_ops.sff_data_xfer = octeon_cf_data_xfer16; + + ap->mwdma_mask = 0x1f; /* Support MWDMA 0-4 */ + irq = platform_get_irq(pdev, 0); + irq_handler = octeon_cf_interrupt; + + /* True IDE mode needs delayed work to poll for not-busy. */ + cf_port->wq = create_singlethread_workqueue(DRV_NAME); + if (!cf_port->wq) + goto free_cf_port; + INIT_DELAYED_WORK(&cf_port->delayed_finish, + octeon_cf_delayed_finish); + + } else { + /* 16 bit but not True IDE */ + octeon_cf_ops.sff_data_xfer = octeon_cf_data_xfer16; + octeon_cf_ops.softreset = octeon_cf_softreset16; + octeon_cf_ops.sff_check_status = octeon_cf_check_status16; + octeon_cf_ops.sff_tf_read = octeon_cf_tf_read16; + octeon_cf_ops.sff_tf_load = octeon_cf_tf_load16; + octeon_cf_ops.sff_exec_command = octeon_cf_exec_command16; + + ap->ioaddr.data_addr = base + ATA_REG_DATA; + ap->ioaddr.nsect_addr = base + ATA_REG_NSECT; + ap->ioaddr.lbal_addr = base + ATA_REG_LBAL; + ap->ioaddr.ctl_addr = base + 0xe; + ap->ioaddr.altstatus_addr = base + 0xe; + } + + ata_port_desc(ap, "cmd %p ctl %p", base, ap->ioaddr.ctl_addr); + + + dev_info(&pdev->dev, "version " DRV_VERSION" %d bit%s.\n", + (ocd->is16bit) ? 16 : 8, + (cs1) ? ", True IDE" : ""); + + + return ata_host_activate(host, irq, irq_handler, 0, &octeon_cf_sht); + +free_cf_port: + kfree(cf_port); + return -ENOMEM; +} + +static struct platform_driver octeon_cf_driver = { + .probe = octeon_cf_probe, + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, +}; + +static int __init octeon_cf_init(void) +{ + return platform_driver_register(&octeon_cf_driver); +} + + +MODULE_AUTHOR("David Daney "); +MODULE_DESCRIPTION("low-level driver for Cavium OCTEON Compact Flash PATA"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_VERSION); +MODULE_ALIAS("platform:" DRV_NAME); + +module_init(octeon_cf_init); -- cgit From bc42b24e6ef01ca7b23fafee7237882d27031614 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 14 Jan 2009 16:48:42 -0800 Subject: drivers/ata/pata_ali.c: s/isa_bridge/ali_isa_bridge/ to fix alpha build drivers/ata/pata_ali.c:44: error: static declaration of 'isa_bridge' follows non-static declaration arch/alpha/include/asm/pci.h:274: error: previous declaration of 'isa_bridge' was here Cc: Alan Cox Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/ata/pata_ali.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index a7999c19f0c..eb99dbe7808 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c @@ -41,7 +41,7 @@ static int ali_atapi_dma = 0; module_param_named(atapi_dma, ali_atapi_dma, int, 0644); MODULE_PARM_DESC(atapi_dma, "Enable ATAPI DMA (0=disable, 1=enable)"); -static struct pci_dev *isa_bridge; +static struct pci_dev *ali_isa_bridge; /* * Cable special cases @@ -346,13 +346,13 @@ static void ali_c2_c3_postreset(struct ata_link *link, unsigned int *classes) int port_bit = 4 << link->ap->port_no; /* If our bridge is an ALI 1533 then do the extra work */ - if (isa_bridge) { + if (ali_isa_bridge) { /* Tristate and re-enable the bus signals */ - pci_read_config_byte(isa_bridge, 0x58, &r); + pci_read_config_byte(ali_isa_bridge, 0x58, &r); r &= ~port_bit; - pci_write_config_byte(isa_bridge, 0x58, r); + pci_write_config_byte(ali_isa_bridge, 0x58, r); r |= port_bit; - pci_write_config_byte(isa_bridge, 0x58, r); + pci_write_config_byte(ali_isa_bridge, 0x58, r); } ata_sff_postreset(link, classes); } @@ -467,14 +467,14 @@ static void ali_init_chipset(struct pci_dev *pdev) pci_write_config_byte(pdev, 0x53, tmp); } north = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); - if (north && north->vendor == PCI_VENDOR_ID_AL && isa_bridge) { + if (north && north->vendor == PCI_VENDOR_ID_AL && ali_isa_bridge) { /* Configure the ALi bridge logic. For non ALi rely on BIOS. Set the south bridge enable bit */ - pci_read_config_byte(isa_bridge, 0x79, &tmp); + pci_read_config_byte(ali_isa_bridge, 0x79, &tmp); if (pdev->revision == 0xC2) - pci_write_config_byte(isa_bridge, 0x79, tmp | 0x04); + pci_write_config_byte(ali_isa_bridge, 0x79, tmp | 0x04); else if (pdev->revision > 0xC2 && pdev->revision < 0xC5) - pci_write_config_byte(isa_bridge, 0x79, tmp | 0x02); + pci_write_config_byte(ali_isa_bridge, 0x79, tmp | 0x02); } pci_dev_put(north); ata_pci_bmdma_clear_simplex(pdev); @@ -571,9 +571,9 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ali_init_chipset(pdev); - if (isa_bridge && pdev->revision >= 0x20 && pdev->revision < 0xC2) { + if (ali_isa_bridge && pdev->revision >= 0x20 && pdev->revision < 0xC2) { /* Are we paired with a UDMA capable chip */ - pci_read_config_byte(isa_bridge, 0x5E, &tmp); + pci_read_config_byte(ali_isa_bridge, 0x5E, &tmp); if ((tmp & 0x1E) == 0x12) ppi[0] = &info_20_udma; } @@ -617,11 +617,11 @@ static struct pci_driver ali_pci_driver = { static int __init ali_init(void) { int ret; - isa_bridge = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); + ali_isa_bridge = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); ret = pci_register_driver(&ali_pci_driver); if (ret < 0) - pci_dev_put(isa_bridge); + pci_dev_put(ali_isa_bridge); return ret; } @@ -629,7 +629,7 @@ static int __init ali_init(void) static void __exit ali_exit(void) { pci_unregister_driver(&ali_pci_driver); - pci_dev_put(isa_bridge); + pci_dev_put(ali_isa_bridge); } -- cgit From e4ac522bd7261829197a3d01d5feedb2aca8ae38 Mon Sep 17 00:00:00 2001 From: Michal Sojka Date: Wed, 14 Jan 2009 14:02:38 +0100 Subject: sata_fsl: Return non-zero on error in probe() while I was looking over kernel sources I've found this small bug. Formerly, zero was returned even if an error happened. Signed-off-by: Michal Sojka Signed-off-by: Jeff Garzik --- drivers/ata/sata_fsl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index 1a56db92ff7..55bc88c1707 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -1288,7 +1288,7 @@ static const struct ata_port_info sata_fsl_port_info[] = { static int sata_fsl_probe(struct of_device *ofdev, const struct of_device_id *match) { - int retval = 0; + int retval = -ENXIO; void __iomem *hcr_base = NULL; void __iomem *ssr_base = NULL; void __iomem *csr_base = NULL; -- cgit From 06a279d636734da32bb62dd2f7b0ade666f65d7c Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 17 Jan 2009 18:41:37 -0500 Subject: ext4: only use i_size_high for regular files Directories are not allowed to be bigger than 2GB, so don't use i_size_high for anything other than regular files. E2fsck should complain about these inodes, but the simplest thing to do for the kernel is to only use i_size_high for regular files. This prevents an intentially corrupted filesystem from causing the kernel to burn a huge amount of CPU and issuing error messages such as: EXT4-fs warning (device loop0): ext4_block_to_path: block 135090028 > max Thanks to David Maciejak from Fortinet's FortiGuard Global Security Research Team for reporting this issue. http://bugzilla.kernel.org/show_bug.cgi?id=12375 Signed-off-by: "Theodore Ts'o" Cc: stable@kernel.org --- fs/ext4/ext4.h | 7 +++++-- fs/ext4/inode.c | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index c668e4377d7..aafc9eba1c2 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1206,8 +1206,11 @@ static inline void ext4_r_blocks_count_set(struct ext4_super_block *es, static inline loff_t ext4_isize(struct ext4_inode *raw_inode) { - return ((loff_t)le32_to_cpu(raw_inode->i_size_high) << 32) | - le32_to_cpu(raw_inode->i_size_lo); + if (S_ISREG(le16_to_cpu(raw_inode->i_mode))) + return ((loff_t)le32_to_cpu(raw_inode->i_size_high) << 32) | + le32_to_cpu(raw_inode->i_size_lo); + else + return (loff_t) le32_to_cpu(raw_inode->i_size_lo); } static inline void ext4_isize_set(struct ext4_inode *raw_inode, loff_t i_size) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index a6444cee0c7..49484ba801c 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -360,9 +360,9 @@ static int ext4_block_to_path(struct inode *inode, final = ptrs; } else { ext4_warning(inode->i_sb, "ext4_block_to_path", - "block %lu > max", + "block %lu > max in inode %lu", i_block + direct_blocks + - indirect_blocks + double_blocks); + indirect_blocks + double_blocks, inode->i_ino); } if (boundary) *boundary = final - 1 - (i_block & (ptrs - 1)); -- cgit From e6b8bc09ba2075cd91fbffefcd2778b1a00bd76f Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 16 Jan 2009 11:13:40 -0500 Subject: ext4: Add sanity check to make_indexed_dir Make sure the rec_len field in the '..' entry is sane, lest we overrun the directory block and cause a kernel oops on a purposefully corrupted filesystem. Thanks to Sami Liedes for reporting this bug. http://bugzilla.kernel.org/show_bug.cgi?id=12430 Signed-off-by: "Theodore Ts'o" Cc: stable@kernel.org --- fs/ext4/namei.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index fec0b4c2f5f..ba702bd7910 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -1368,7 +1368,7 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry, struct fake_dirent *fde; blocksize = dir->i_sb->s_blocksize; - dxtrace(printk(KERN_DEBUG "Creating index\n")); + dxtrace(printk(KERN_DEBUG "Creating index: inode %lu\n", dir->i_ino)); retval = ext4_journal_get_write_access(handle, bh); if (retval) { ext4_std_error(dir->i_sb, retval); @@ -1377,6 +1377,20 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry, } root = (struct dx_root *) bh->b_data; + /* The 0th block becomes the root, move the dirents out */ + fde = &root->dotdot; + de = (struct ext4_dir_entry_2 *)((char *)fde + + ext4_rec_len_from_disk(fde->rec_len)); + if ((char *) de >= (((char *) root) + blocksize)) { + ext4_error(dir->i_sb, __func__, + "invalid rec_len for '..' in inode %lu", + dir->i_ino); + brelse(bh); + return -EIO; + } + len = ((char *) root) + blocksize - (char *) de; + + /* Allocate new block for the 0th block's dirents */ bh2 = ext4_append(handle, dir, &block, &retval); if (!(bh2)) { brelse(bh); @@ -1385,11 +1399,6 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry, EXT4_I(dir)->i_flags |= EXT4_INDEX_FL; data1 = bh2->b_data; - /* The 0th block becomes the root, move the dirents out */ - fde = &root->dotdot; - de = (struct ext4_dir_entry_2 *)((char *)fde + - ext4_rec_len_from_disk(fde->rec_len)); - len = ((char *) root) + blocksize - (char *) de; memcpy (data1, de, len); de = (struct ext4_dir_entry_2 *) data1; top = data1 + len; -- cgit From a21102b55c4f8dfd3adb4a15a34cd62237b46039 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 16 Jan 2009 11:13:47 -0500 Subject: ext3: Add sanity check to make_indexed_dir Make sure the rec_len field in the '..' entry is sane, lest we overrun the directory block and cause a kernel oops on a purposefully corrupted filesystem. This fixes a bug related to a bug originally reported by Sami Liedes for ext4 at: http://bugzilla.kernel.org/show_bug.cgi?id=12430 Signed-off-by: "Theodore Ts'o" Cc: stable@kernel.org --- fs/ext3/namei.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 69a3d19ca9f..4db4ffa1eda 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c @@ -1358,7 +1358,7 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry, struct fake_dirent *fde; blocksize = dir->i_sb->s_blocksize; - dxtrace(printk("Creating index\n")); + dxtrace(printk(KERN_DEBUG "Creating index: inode %lu\n", dir->i_ino)); retval = ext3_journal_get_write_access(handle, bh); if (retval) { ext3_std_error(dir->i_sb, retval); @@ -1367,6 +1367,19 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry, } root = (struct dx_root *) bh->b_data; + /* The 0th block becomes the root, move the dirents out */ + fde = &root->dotdot; + de = (struct ext3_dir_entry_2 *)((char *)fde + + ext3_rec_len_from_disk(fde->rec_len)); + if ((char *) de >= (((char *) root) + blocksize)) { + ext3_error(dir->i_sb, __func__, + "invalid rec_len for '..' in inode %lu", + dir->i_ino); + brelse(bh); + return -EIO; + } + len = ((char *) root) + blocksize - (char *) de; + bh2 = ext3_append (handle, dir, &block, &retval); if (!(bh2)) { brelse(bh); @@ -1375,11 +1388,6 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry, EXT3_I(dir)->i_flags |= EXT3_INDEX_FL; data1 = bh2->b_data; - /* The 0th block becomes the root, move the dirents out */ - fde = &root->dotdot; - de = (struct ext3_dir_entry_2 *)((char *)fde + - ext3_rec_len_from_disk(fde->rec_len)); - len = ((char *) root) + blocksize - (char *) de; memcpy (data1, de, len); de = (struct ext3_dir_entry_2 *) data1; top = data1 + len; -- cgit From 50246dd41ccbcb47beb06d6c1d9355f6b7137a11 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 16 Jan 2009 08:14:51 -0800 Subject: Revert "PCI PM: Register power state of devices during initialization" This reverts commit 98e6e286d7b01deb7453b717aa38ebb69d6cefc0, as Yinghai Lu reports that it breaks kexec with at least the e1000 and e1000e drivers. The reason is that the shutdown sequence puts the hardware into D3 sleep, and the commit causes us to claim that it then is in D0 (running) state just because we don't understand the PM capabilities. Which then later makes "pci_set_power_state()" not do anything, and the device never wakes up properly and just returns 0xff to everything. Reported-by: Yinghai Lu Acked-by: From: Rafael J. Wysocki Cc: Jesse Barnes Signed-off-by: Linus Torvalds --- drivers/pci/pci.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index c12f6c79069..e491fdedf70 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1260,15 +1260,14 @@ void pci_pm_init(struct pci_dev *dev) /* find PCI PM capability in list */ pm = pci_find_capability(dev, PCI_CAP_ID_PM); if (!pm) - goto Exit; - + return; /* Check device's ability to generate PME# */ pci_read_config_word(dev, pm + PCI_PM_PMC, &pmc); if ((pmc & PCI_PM_CAP_VER_MASK) > 3) { dev_err(&dev->dev, "unsupported PM cap regs version (%u)\n", pmc & PCI_PM_CAP_VER_MASK); - goto Exit; + return; } dev->pm_cap = pm; @@ -1307,9 +1306,6 @@ void pci_pm_init(struct pci_dev *dev) } else { dev->pme_support = 0; } - - Exit: - pci_update_current_state(dev, PCI_D0); } /** -- cgit From 591046cfc5f1b452db0a4557850ad7f394e38231 Mon Sep 17 00:00:00 2001 From: Ben Nizette Date: Fri, 16 Jan 2009 08:45:45 +1100 Subject: ASoC: atmel_pcm: Remove non-existant header doesn't exist on AVR32 and therefore this driver won't build on that arch. AFAICT this driver doesn't actually use the content of that header so easiest just to remove it. Signed-off-by: Ben Nizette Signed-off-by: Mark Brown --- sound/soc/atmel/atmel-pcm.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c index 1fac5efd285..3dcdc4e3cfa 100644 --- a/sound/soc/atmel/atmel-pcm.c +++ b/sound/soc/atmel/atmel-pcm.c @@ -44,8 +44,6 @@ #include #include -#include - #include "atmel-pcm.h" -- cgit From 08ec8c3878cea0bf91f2ba3c0badf44b383752d0 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 16 Jan 2009 11:57:00 -0500 Subject: jbd2: On a __journal_expect() assertion failure printk "JBD2", not "EXT3-fs" Otherwise it can be very confusing to find a "EXT3-fs: " failure in the middle of EXT4-fs failures, and it makes it harder to track the source of the failure. Signed-off-by: "Theodore Ts'o" --- include/linux/jbd2.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index b45109c61fb..b28b37eb11c 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -308,7 +308,8 @@ void buffer_assertion_failure(struct buffer_head *bh); int val = (expr); \ if (!val) { \ printk(KERN_ERR \ - "EXT3-fs unexpected failure: %s;\n",# expr); \ + "JBD2 unexpected failure: %s: %s;\n", \ + __func__, #expr); \ printk(KERN_ERR why "\n"); \ } \ val; \ -- cgit From 1d9e2ae949411c2f329f30e01ea0355cd02c4296 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Fri, 16 Jan 2009 11:58:19 -0500 Subject: Btrfs: Clear the device->running_pending flag before bailing on congestion Btrfs maintains a queue of async bio submissions so the checksumming threads don't have to wait on get_request_wait. In order to avoid extra wakeups, this code has a running_pending flag that is used to tell new submissions they don't need to wake the thread. When the threads notice congestion on a single device, they may decide to requeue the job and move on to other devices. This makes sure the running_pending flag is cleared before the job is requeued. It should help avoid IO stalls by making sure the task is woken up when new submissions come in. Signed-off-by: Chris Mason --- fs/btrfs/volumes.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index b187b537888..3451e1cca2b 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -220,6 +220,7 @@ loop: tail->bi_next = old_head; else device->pending_bio_tail = tail; + device->running_pending = 0; spin_unlock(&device->io_lock); btrfs_requeue_work(&device->work); -- cgit From c071fcfdb60e7abbe95e02460005d6bca165bf24 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Fri, 16 Jan 2009 11:59:08 -0500 Subject: Btrfs: fix ioctl arg size (userland incompatible change!) The structure used to send device in btrfs ioctl calls was not properly aligned, and so 32 bit ioctls would not work properly on 64 bit kernels. We could fix this with compat ioctls, but we're just one byte away and it doesn't make sense at this stage to carry about the compat ioctls forever at this stage in the project. This patch brings the ioctl arg up to an evenly aligned 4k. Signed-off-by: Chris Mason --- fs/btrfs/ioctl.h | 14 ++++++++------ fs/btrfs/super.c | 3 ++- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index 78049ea208d..b320b103fa1 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h @@ -22,13 +22,20 @@ #define BTRFS_IOCTL_MAGIC 0x94 #define BTRFS_VOL_NAME_MAX 255 -#define BTRFS_PATH_NAME_MAX 3072 +#define BTRFS_PATH_NAME_MAX 4087 +/* this should be 4k */ struct btrfs_ioctl_vol_args { __s64 fd; char name[BTRFS_PATH_NAME_MAX + 1]; }; +struct btrfs_ioctl_clone_range_args { + __s64 src_fd; + __u64 src_offset, src_length; + __u64 dest_offset; +}; + #define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \ struct btrfs_ioctl_vol_args) #define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \ @@ -52,11 +59,6 @@ struct btrfs_ioctl_vol_args { struct btrfs_ioctl_vol_args) #define BTRFS_IOC_BALANCE _IOW(BTRFS_IOCTL_MAGIC, 12, \ struct btrfs_ioctl_vol_args) -struct btrfs_ioctl_clone_range_args { - __s64 src_fd; - __u64 src_offset, src_length; - __u64 dest_offset; -}; #define BTRFS_IOC_CLONE_RANGE _IOW(BTRFS_IOCTL_MAGIC, 13, \ struct btrfs_ioctl_clone_range_args) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index b4c101d9322..92c9b543def 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -582,7 +582,7 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd, { struct btrfs_ioctl_vol_args *vol; struct btrfs_fs_devices *fs_devices; - int ret = 0; + int ret = -ENOTTY; int len; if (!capable(CAP_SYS_ADMIN)) @@ -594,6 +594,7 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd, goto out; } len = strnlen(vol->name, BTRFS_PATH_NAME_MAX); + switch (cmd) { case BTRFS_IOC_SCAN_DEV: ret = btrfs_scan_one_device(vol->name, FMODE_READ, -- cgit From cc33412fb1f11613e20f9dfc2919a77ecd63fbc4 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 12 Jan 2009 17:23:05 +0100 Subject: quota: Improve locking We implement dqget() and dqput() that need neither dqonoff_mutex nor dqptr_sem. Then move dqget() and dqput() calls so that they are not called from under dqptr_sem. This is important because filesystem callbacks aren't called from under dqptr_sem which used to cause *lots* of problems with lock ranking (and with OCFS2 they became close to unsolvable). The patch also removes two functions which were introduced solely because OCFS2 needed them to cope with the old locking scheme. As time showed, they were not enough for OCFS2 anyway and it would be unnecessary work to adapt them to the new locking scheme in which they aren't needed. As a result OCFS2 needs the following patch to compile properly with quotas. Sorry to any bisecters which hit this in advance. Signed-off-by: Jan Kara --- fs/dquot.c | 218 ++++++++++++++++++++++++++--------------------- include/linux/quotaops.h | 2 - 2 files changed, 122 insertions(+), 98 deletions(-) diff --git a/fs/dquot.c b/fs/dquot.c index 48c0571f831..bca3cac4bee 100644 --- a/fs/dquot.c +++ b/fs/dquot.c @@ -87,14 +87,17 @@ #define __DQUOT_PARANOIA /* - * There are two quota SMP locks. dq_list_lock protects all lists with quotas - * and quota formats and also dqstats structure containing statistics about the - * lists. dq_data_lock protects data from dq_dqb and also mem_dqinfo structures - * and also guards consistency of dquot->dq_dqb with inode->i_blocks, i_bytes. + * There are three quota SMP locks. dq_list_lock protects all lists with quotas + * and quota formats, dqstats structure containing statistics about the lists + * dq_data_lock protects data from dq_dqb and also mem_dqinfo structures and + * also guards consistency of dquot->dq_dqb with inode->i_blocks, i_bytes. * i_blocks and i_bytes updates itself are guarded by i_lock acquired directly - * in inode_add_bytes() and inode_sub_bytes(). + * in inode_add_bytes() and inode_sub_bytes(). dq_state_lock protects + * modifications of quota state (on quotaon and quotaoff) and readers who care + * about latest values take it as well. * - * The spinlock ordering is hence: dq_data_lock > dq_list_lock > i_lock + * The spinlock ordering is hence: dq_data_lock > dq_list_lock > i_lock, + * dq_list_lock > dq_state_lock * * Note that some things (eg. sb pointer, type, id) doesn't change during * the life of the dquot structure and so needn't to be protected by a lock @@ -103,12 +106,7 @@ * operation is just reading pointers from inode (or not using them at all) the * read lock is enough. If pointers are altered function must hold write lock * (these locking rules also apply for S_NOQUOTA flag in the inode - note that - * for altering the flag i_mutex is also needed). If operation is holding - * reference to dquot in other way (e.g. quotactl ops) it must be guarded by - * dqonoff_mutex. - * This locking assures that: - * a) update/access to dquot pointers in inode is serialized - * b) everyone is guarded against invalidate_dquots() + * for altering the flag i_mutex is also needed). * * Each dquot has its dq_lock mutex. Locked dquots might not be referenced * from inodes (dquot_alloc_space() and such don't check the dq_lock). @@ -122,10 +120,17 @@ * Lock ordering (including related VFS locks) is the following: * i_mutex > dqonoff_sem > journal_lock > dqptr_sem > dquot->dq_lock > * dqio_mutex + * The lock ordering of dqptr_sem imposed by quota code is only dqonoff_sem > + * dqptr_sem. But filesystem has to count with the fact that functions such as + * dquot_alloc_space() acquire dqptr_sem and they usually have to be called + * from inside a transaction to keep filesystem consistency after a crash. Also + * filesystems usually want to do some IO on dquot from ->mark_dirty which is + * called with dqptr_sem held. * i_mutex on quota files is special (it's below dqio_mutex) */ static DEFINE_SPINLOCK(dq_list_lock); +static DEFINE_SPINLOCK(dq_state_lock); DEFINE_SPINLOCK(dq_data_lock); static char *quotatypes[] = INITQFNAMES; @@ -428,7 +433,7 @@ static inline void do_destroy_dquot(struct dquot *dquot) * quota is disabled and pointers from inodes removed so there cannot be new * quota users. There can still be some users of quotas due to inodes being * just deleted or pruned by prune_icache() (those are not attached to any - * list). We have to wait for such users. + * list) or parallel quotactl call. We have to wait for such users. */ static void invalidate_dquots(struct super_block *sb, int type) { @@ -600,7 +605,6 @@ static struct shrinker dqcache_shrinker = { /* * Put reference to dquot * NOTE: If you change this function please check whether dqput_blocks() works right... - * MUST be called with either dqptr_sem or dqonoff_mutex held */ void dqput(struct dquot *dquot) { @@ -696,37 +700,31 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type) return dquot; } -/* - * Check whether dquot is in memory. - * MUST be called with either dqptr_sem or dqonoff_mutex held - */ -int dquot_is_cached(struct super_block *sb, unsigned int id, int type) -{ - unsigned int hashent = hashfn(sb, id, type); - int ret = 0; - - if (!sb_has_quota_active(sb, type)) - return 0; - spin_lock(&dq_list_lock); - if (find_dquot(hashent, sb, id, type) != NODQUOT) - ret = 1; - spin_unlock(&dq_list_lock); - return ret; -} - /* * Get reference to dquot - * MUST be called with either dqptr_sem or dqonoff_mutex held + * + * Locking is slightly tricky here. We are guarded from parallel quotaoff() + * destroying our dquot by: + * a) checking for quota flags under dq_list_lock and + * b) getting a reference to dquot before we release dq_list_lock */ struct dquot *dqget(struct super_block *sb, unsigned int id, int type) { unsigned int hashent = hashfn(sb, id, type); - struct dquot *dquot, *empty = NODQUOT; + struct dquot *dquot = NODQUOT, *empty = NODQUOT; if (!sb_has_quota_active(sb, type)) return NODQUOT; we_slept: spin_lock(&dq_list_lock); + spin_lock(&dq_state_lock); + if (!sb_has_quota_active(sb, type)) { + spin_unlock(&dq_state_lock); + spin_unlock(&dq_list_lock); + goto out; + } + spin_unlock(&dq_state_lock); + if ((dquot = find_dquot(hashent, sb, id, type)) == NODQUOT) { if (empty == NODQUOT) { spin_unlock(&dq_list_lock); @@ -735,6 +733,7 @@ we_slept: goto we_slept; } dquot = empty; + empty = NODQUOT; dquot->dq_id = id; /* all dquots go on the inuse_list */ put_inuse(dquot); @@ -749,8 +748,6 @@ we_slept: dqstats.cache_hits++; dqstats.lookups++; spin_unlock(&dq_list_lock); - if (empty) - do_destroy_dquot(empty); } /* Wait for dq_lock - after this we know that either dquot_release() is already * finished or it will be canceled due to dq_count > 1 test */ @@ -758,11 +755,15 @@ we_slept: /* Read the dquot and instantiate it (everything done only if needed) */ if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && sb->dq_op->acquire_dquot(dquot) < 0) { dqput(dquot); - return NODQUOT; + dquot = NODQUOT; + goto out; } #ifdef __DQUOT_PARANOIA BUG_ON(!dquot->dq_sb); /* Has somebody invalidated entry under us? */ #endif +out: + if (empty) + do_destroy_dquot(empty); return dquot; } @@ -1198,63 +1199,76 @@ static int info_bdq_free(struct dquot *dquot, qsize_t space) } /* * Initialize quota pointers in inode - * Transaction must be started at entry + * We do things in a bit complicated way but by that we avoid calling + * dqget() and thus filesystem callbacks under dqptr_sem. */ int dquot_initialize(struct inode *inode, int type) { unsigned int id = 0; int cnt, ret = 0; + struct dquot *got[MAXQUOTAS] = { NODQUOT, NODQUOT }; + struct super_block *sb = inode->i_sb; /* First test before acquiring mutex - solves deadlocks when we * re-enter the quota code and are already holding the mutex */ if (IS_NOQUOTA(inode)) return 0; - down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); + + /* First get references to structures we might need. */ + for (cnt = 0; cnt < MAXQUOTAS; cnt++) { + if (type != -1 && cnt != type) + continue; + switch (cnt) { + case USRQUOTA: + id = inode->i_uid; + break; + case GRPQUOTA: + id = inode->i_gid; + break; + } + got[cnt] = dqget(sb, id, cnt); + } + + down_write(&sb_dqopt(sb)->dqptr_sem); /* Having dqptr_sem we know NOQUOTA flags can't be altered... */ if (IS_NOQUOTA(inode)) goto out_err; for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (type != -1 && cnt != type) continue; + /* Avoid races with quotaoff() */ + if (!sb_has_quota_active(sb, cnt)) + continue; if (inode->i_dquot[cnt] == NODQUOT) { - switch (cnt) { - case USRQUOTA: - id = inode->i_uid; - break; - case GRPQUOTA: - id = inode->i_gid; - break; - } - inode->i_dquot[cnt] = dqget(inode->i_sb, id, cnt); + inode->i_dquot[cnt] = got[cnt]; + got[cnt] = NODQUOT; } } out_err: - up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); + up_write(&sb_dqopt(sb)->dqptr_sem); + /* Drop unused references */ + for (cnt = 0; cnt < MAXQUOTAS; cnt++) + dqput(got[cnt]); return ret; } /* * Release all quotas referenced by inode - * Transaction must be started at an entry */ -int dquot_drop_locked(struct inode *inode) +int dquot_drop(struct inode *inode) { int cnt; + struct dquot *put[MAXQUOTAS]; + down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (inode->i_dquot[cnt] != NODQUOT) { - dqput(inode->i_dquot[cnt]); - inode->i_dquot[cnt] = NODQUOT; - } + put[cnt] = inode->i_dquot[cnt]; + inode->i_dquot[cnt] = NODQUOT; } - return 0; -} - -int dquot_drop(struct inode *inode) -{ - down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); - dquot_drop_locked(inode); up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); + + for (cnt = 0; cnt < MAXQUOTAS; cnt++) + dqput(put[cnt]); return 0; } @@ -1470,8 +1484,9 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) qsize_t space; struct dquot *transfer_from[MAXQUOTAS]; struct dquot *transfer_to[MAXQUOTAS]; - int cnt, ret = NO_QUOTA, chuid = (iattr->ia_valid & ATTR_UID) && inode->i_uid != iattr->ia_uid, - chgid = (iattr->ia_valid & ATTR_GID) && inode->i_gid != iattr->ia_gid; + int cnt, ret = QUOTA_OK; + int chuid = iattr->ia_valid & ATTR_UID && inode->i_uid != iattr->ia_uid, + chgid = iattr->ia_valid & ATTR_GID && inode->i_gid != iattr->ia_gid; char warntype_to[MAXQUOTAS]; char warntype_from_inodes[MAXQUOTAS], warntype_from_space[MAXQUOTAS]; @@ -1479,21 +1494,11 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) * re-enter the quota code and are already holding the mutex */ if (IS_NOQUOTA(inode)) return QUOTA_OK; - /* Clear the arrays */ + /* Initialize the arrays */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - transfer_to[cnt] = transfer_from[cnt] = NODQUOT; + transfer_from[cnt] = NODQUOT; + transfer_to[cnt] = NODQUOT; warntype_to[cnt] = QUOTA_NL_NOWARN; - } - down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); - /* Now recheck reliably when holding dqptr_sem */ - if (IS_NOQUOTA(inode)) { /* File without quota accounting? */ - up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); - return QUOTA_OK; - } - /* First build the transfer_to list - here we can block on - * reading/instantiating of dquots. We know that the transaction for - * us was already started so we don't violate lock ranking here */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { switch (cnt) { case USRQUOTA: if (!chuid) @@ -1507,6 +1512,13 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) break; } } + + down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); + /* Now recheck reliably when holding dqptr_sem */ + if (IS_NOQUOTA(inode)) { /* File without quota accounting? */ + up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); + goto put_all; + } spin_lock(&dq_data_lock); space = inode_get_bytes(inode); /* Build the transfer_from list and check the limits */ @@ -1517,7 +1529,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) if (check_idq(transfer_to[cnt], 1, warntype_to + cnt) == NO_QUOTA || check_bdq(transfer_to[cnt], space, 0, warntype_to + cnt) == NO_QUOTA) - goto warn_put_all; + goto over_quota; } /* @@ -1545,28 +1557,37 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) inode->i_dquot[cnt] = transfer_to[cnt]; } - ret = QUOTA_OK; -warn_put_all: spin_unlock(&dq_data_lock); + up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); + /* Dirtify all the dquots - this can block when journalling */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (transfer_from[cnt]) mark_dquot_dirty(transfer_from[cnt]); - if (transfer_to[cnt]) + if (transfer_to[cnt]) { mark_dquot_dirty(transfer_to[cnt]); + /* The reference we got is transferred to the inode */ + transfer_to[cnt] = NODQUOT; + } } +warn_put_all: flush_warnings(transfer_to, warntype_to); flush_warnings(transfer_from, warntype_from_inodes); flush_warnings(transfer_from, warntype_from_space); - +put_all: for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (ret == QUOTA_OK && transfer_from[cnt] != NODQUOT) - dqput(transfer_from[cnt]); - if (ret == NO_QUOTA && transfer_to[cnt] != NODQUOT) - dqput(transfer_to[cnt]); + dqput(transfer_from[cnt]); + dqput(transfer_to[cnt]); } - up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); return ret; +over_quota: + spin_unlock(&dq_data_lock); + up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); + /* Clear dquot pointers we don't want to dqput() */ + for (cnt = 0; cnt < MAXQUOTAS; cnt++) + transfer_from[cnt] = NODQUOT; + ret = NO_QUOTA; + goto warn_put_all; } /* Wrapper for transferring ownership of an inode */ @@ -1651,19 +1672,24 @@ int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags) continue; if (flags & DQUOT_SUSPENDED) { + spin_lock(&dq_state_lock); dqopt->flags |= dquot_state_flag(DQUOT_SUSPENDED, cnt); + spin_unlock(&dq_state_lock); } else { + spin_lock(&dq_state_lock); dqopt->flags &= ~dquot_state_flag(flags, cnt); /* Turning off suspended quotas? */ if (!sb_has_quota_loaded(sb, cnt) && sb_has_quota_suspended(sb, cnt)) { dqopt->flags &= ~dquot_state_flag( DQUOT_SUSPENDED, cnt); + spin_unlock(&dq_state_lock); iput(dqopt->files[cnt]); dqopt->files[cnt] = NULL; continue; } + spin_unlock(&dq_state_lock); } /* We still have to keep quota loaded? */ @@ -1830,7 +1856,9 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id, } mutex_unlock(&dqopt->dqio_mutex); mutex_unlock(&inode->i_mutex); + spin_lock(&dq_state_lock); dqopt->flags |= dquot_state_flag(flags, type); + spin_unlock(&dq_state_lock); add_dquot_ref(sb, type); mutex_unlock(&dqopt->dqonoff_mutex); @@ -1872,9 +1900,11 @@ static int vfs_quota_on_remount(struct super_block *sb, int type) } inode = dqopt->files[type]; dqopt->files[type] = NULL; + spin_lock(&dq_state_lock); flags = dqopt->flags & dquot_state_flag(DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED, type); dqopt->flags &= ~dquot_state_flag(DQUOT_STATE_FLAGS, type); + spin_unlock(&dq_state_lock); mutex_unlock(&dqopt->dqonoff_mutex); flags = dquot_generic_flag(flags, type); @@ -1952,7 +1982,9 @@ int vfs_quota_enable(struct inode *inode, int type, int format_id, ret = -EBUSY; goto out_lock; } + spin_lock(&dq_state_lock); sb_dqopt(sb)->flags |= dquot_state_flag(flags, type); + spin_unlock(&dq_state_lock); out_lock: mutex_unlock(&dqopt->dqonoff_mutex); return ret; @@ -2039,14 +2071,12 @@ int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *d { struct dquot *dquot; - mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); - if (!(dquot = dqget(sb, id, type))) { - mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); + dquot = dqget(sb, id, type); + if (dquot == NODQUOT) return -ESRCH; - } do_get_dqblk(dquot, di); dqput(dquot); - mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); + return 0; } @@ -2130,7 +2160,6 @@ int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *d struct dquot *dquot; int rc; - mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); dquot = dqget(sb, id, type); if (!dquot) { rc = -ESRCH; @@ -2139,7 +2168,6 @@ int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *d rc = do_set_dqblk(dquot, di); dqput(dquot); out: - mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); return rc; } @@ -2370,11 +2398,9 @@ EXPORT_SYMBOL(dquot_release); EXPORT_SYMBOL(dquot_mark_dquot_dirty); EXPORT_SYMBOL(dquot_initialize); EXPORT_SYMBOL(dquot_drop); -EXPORT_SYMBOL(dquot_drop_locked); EXPORT_SYMBOL(vfs_dq_drop); EXPORT_SYMBOL(dqget); EXPORT_SYMBOL(dqput); -EXPORT_SYMBOL(dquot_is_cached); EXPORT_SYMBOL(dquot_alloc_space); EXPORT_SYMBOL(dquot_alloc_inode); EXPORT_SYMBOL(dquot_free_space); diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index 21b781a3350..0b35b3a1be0 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -24,10 +24,8 @@ void sync_dquots(struct super_block *sb, int type); int dquot_initialize(struct inode *inode, int type); int dquot_drop(struct inode *inode); -int dquot_drop_locked(struct inode *inode); struct dquot *dqget(struct super_block *sb, unsigned int id, int type); void dqput(struct dquot *dquot); -int dquot_is_cached(struct super_block *sb, unsigned int id, int type); int dquot_scan_active(struct super_block *sb, int (*fn)(struct dquot *dquot, unsigned long priv), unsigned long priv); -- cgit From 235c4a59278eb07e61d909f1f0c233733034a8b3 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Wed, 14 Jan 2009 02:57:47 +0300 Subject: ACPI: EC: Limit workaround for ASUS notebooks even more References: http://bugzilla.kernel.org/show_bug.cgi?id=11884 Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/ec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 8dfcbb8aff7..e0794264b9f 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -1027,7 +1027,8 @@ int __init acpi_ec_ecdt_probe(void) * which needs it, has fake EC._INI method, so use it as flag. * Keep boot_ec struct as it will be needed soon. */ - if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &dummy))) + if (!dmi_name_in_vendors("ASUS") || + ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &dummy))) return -ENODEV; install: if (!ec_install_handlers(boot_ec)) { -- cgit From 3bfafd6b136bea2de9bd96c01b7e3808635a15b2 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Fri, 16 Jan 2009 11:03:01 -0800 Subject: netxen: avoid invalid iounmap For NX3031 only one I/O range is mapped, so unmapping other two which are used by older chips, causes this warning on ppc64. "Attempt to iounmap early bolted mapping at 0x0000000000000000" Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 86867405a36..f8e26290a22 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -1004,8 +1004,10 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) iounmap(adapter->ahw.db_base); iounmap(adapter->ahw.pci_base0); - iounmap(adapter->ahw.pci_base1); - iounmap(adapter->ahw.pci_base2); + if (adapter->ahw.pci_base1 != NULL) + iounmap(adapter->ahw.pci_base1); + if (adapter->ahw.pci_base2 != NULL) + iounmap(adapter->ahw.pci_base2); pci_release_regions(pdev); pci_disable_device(pdev); -- cgit From c6cb0e878446c79f42e7833d7bb69ed6bfbb381f Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Wed, 14 Jan 2009 02:57:53 +0300 Subject: ACPI: EC: Don't trust ECDT tables from ASUS http://bugzilla.kernel.org/show_bug.cgi?id=9399 http://bugzilla.kernel.org/show_bug.cgi?id=11880 Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/ec.c | 74 ++++++++++++++++++++++--------------------------------- 1 file changed, 30 insertions(+), 44 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index e0794264b9f..a2b82c90a68 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -120,31 +120,6 @@ static struct acpi_ec { spinlock_t curr_lock; } *boot_ec, *first_ec; -/* - * Some Asus system have exchanged ECDT data/command IO addresses. - */ -static int print_ecdt_error(const struct dmi_system_id *id) -{ - printk(KERN_NOTICE PREFIX "%s detected - " - "ECDT has exchanged control/data I/O address\n", - id->ident); - return 0; -} - -static struct dmi_system_id __cpuinitdata ec_dmi_table[] = { - { - print_ecdt_error, "Asus L4R", { - DMI_MATCH(DMI_BIOS_VERSION, "1008.006"), - DMI_MATCH(DMI_PRODUCT_NAME, "L4R"), - DMI_MATCH(DMI_BOARD_NAME, "L4R") }, NULL}, - { - print_ecdt_error, "Asus M6R", { - DMI_MATCH(DMI_BIOS_VERSION, "0207"), - DMI_MATCH(DMI_PRODUCT_NAME, "M6R"), - DMI_MATCH(DMI_BOARD_NAME, "M6R") }, NULL}, - {}, -}; - /* -------------------------------------------------------------------------- Transaction Management -------------------------------------------------------------------------- */ @@ -983,8 +958,8 @@ static const struct acpi_device_id ec_device_ids[] = { int __init acpi_ec_ecdt_probe(void) { acpi_status status; + struct acpi_ec *saved_ec = NULL; struct acpi_table_ecdt *ecdt_ptr; - acpi_handle dummy; boot_ec = make_acpi_ec(); if (!boot_ec) @@ -998,21 +973,16 @@ int __init acpi_ec_ecdt_probe(void) pr_info(PREFIX "EC description table is found, configuring boot EC\n"); boot_ec->command_addr = ecdt_ptr->control.address; boot_ec->data_addr = ecdt_ptr->data.address; - if (dmi_check_system(ec_dmi_table)) { - /* - * If the board falls into ec_dmi_table, it means - * that ECDT table gives the incorrect command/status - * & data I/O address. Just fix it. - */ - boot_ec->data_addr = ecdt_ptr->control.address; - boot_ec->command_addr = ecdt_ptr->data.address; - } boot_ec->gpe = ecdt_ptr->gpe; boot_ec->handle = ACPI_ROOT_OBJECT; acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); - /* Add some basic check against completely broken table */ - if (boot_ec->data_addr != boot_ec->command_addr) + /* Don't trust ECDT, which comes from ASUSTek */ + if (!dmi_name_in_vendors("ASUS")) goto install; + saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); + if (!saved_ec) + return -ENOMEM; + memcpy(&saved_ec, boot_ec, sizeof(saved_ec)); /* fall through */ } /* This workaround is needed only on some broken machines, @@ -1023,13 +993,29 @@ int __init acpi_ec_ecdt_probe(void) /* Check that acpi_get_devices actually find something */ if (ACPI_FAILURE(status) || !boot_ec->handle) goto error; - /* We really need to limit this workaround, the only ASUS, - * which needs it, has fake EC._INI method, so use it as flag. - * Keep boot_ec struct as it will be needed soon. - */ - if (!dmi_name_in_vendors("ASUS") || - ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &dummy))) - return -ENODEV; + if (saved_ec) { + /* try to find good ECDT from ASUSTek */ + if (saved_ec->command_addr != boot_ec->command_addr || + saved_ec->data_addr != boot_ec->data_addr || + saved_ec->gpe != boot_ec->gpe || + saved_ec->handle != boot_ec->handle) + pr_info(PREFIX "ASUSTek keeps feeding us with broken " + "ECDT tables, which are very hard to workaround. " + "Trying to use DSDT EC info instead. Please send " + "output of acpidump to linux-acpi@vger.kernel.org\n"); + kfree(saved_ec); + saved_ec = NULL; + } else { + /* We really need to limit this workaround, the only ASUS, + * which needs it, has fake EC._INI method, so use it as flag. + * Keep boot_ec struct as it will be needed soon. + */ + acpi_handle dummy; + if (!dmi_name_in_vendors("ASUS") || + ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", + &dummy))) + return -ENODEV; + } install: if (!ec_install_handlers(boot_ec)) { first_ec = boot_ec; -- cgit From 009777846165fcc49352c0f1487e3a96102884c3 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Fri, 16 Jan 2009 11:03:25 -0800 Subject: netxen: include ipv6.h (fixes build failure) Fixes a build error in absence of CONFIG_IPV6: drivers/net/netxen/netxen_nic_main.c:1189: error: implicit declaration of function 'ipv6_hdr' drivers/net/netxen/netxen_nic_main.c:1189: error: invalid type argument of '->' Reported-by: Ingo Molnar Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index f8e26290a22..d854f07ef4d 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -41,6 +41,7 @@ #include #include #include +#include MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver"); MODULE_LICENSE("GPL"); -- cgit From 0e4240d94628530a912d216cad1e32d2e3827327 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Fri, 16 Jan 2009 12:53:42 -0500 Subject: thermal fixup for broken BIOS which has invalid trip points. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ACPI thermal driver only re-evaluate VALID trip points. For the broken BIOS show in http://bugzilla.kernel.org/show_bug.cgi?id=8544 the active[0] is set to invalid at boot time and it will not be re-evaluated again. We can still get a single warning message at boot time. http://marc.info/?l=linux-kernel&m=120496222629983&w=2 http://bugzilla.kernel.org/show_bug.cgi?id=12203 Signed-off-by: Zhang Rui Tested-by: Márton Németh Signed-off-by: Len Brown --- drivers/acpi/thermal.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 073ff09218a..99e6f1f8ea4 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -416,7 +416,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) } /* Passive (optional) */ - if (flag & ACPI_TRIPS_PASSIVE) { + if (((flag & ACPI_TRIPS_PASSIVE) && tz->trips.passive.flags.valid) || + (flag == ACPI_TRIPS_INIT)) { valid = tz->trips.passive.flags.valid; if (psv == -1) { status = AE_SUPPORT; @@ -462,8 +463,11 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) memset(&devices, 0, sizeof(struct acpi_handle_list)); status = acpi_evaluate_reference(tz->device->handle, "_PSL", NULL, &devices); - if (ACPI_FAILURE(status)) + if (ACPI_FAILURE(status)) { + printk(KERN_WARNING PREFIX + "Invalid passive threshold\n"); tz->trips.passive.flags.valid = 0; + } else tz->trips.passive.flags.valid = 1; @@ -487,7 +491,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) if (act == -1) break; /* disable all active trip points */ - if (flag & ACPI_TRIPS_ACTIVE) { + if ((flag == ACPI_TRIPS_INIT) || ((flag & ACPI_TRIPS_ACTIVE) && + tz->trips.active[i].flags.valid)) { status = acpi_evaluate_integer(tz->device->handle, name, NULL, &tmp); if (ACPI_FAILURE(status)) { @@ -521,8 +526,11 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) memset(&devices, 0, sizeof(struct acpi_handle_list)); status = acpi_evaluate_reference(tz->device->handle, name, NULL, &devices); - if (ACPI_FAILURE(status)) + if (ACPI_FAILURE(status)) { + printk(KERN_WARNING PREFIX + "Invalid active%d threshold\n", i); tz->trips.active[i].flags.valid = 0; + } else tz->trips.active[i].flags.valid = 1; -- cgit From 33f1d7ecc6cffff3c618a02295de969ebbacd95d Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 6 Jan 2009 21:14:04 +0100 Subject: PM: Fix freezer compilation if PM_SLEEP is unset Freezer fails to compile if with the following configuration settings: CONFIG_CGROUPS=y CONFIG_CGROUP_FREEZER=y CONFIG_MODULES=y CONFIG_FREEZER=y CONFIG_PM=y CONFIG_PM_SLEEP=n Fix this by making process.o compilation depend on CONFIG_FREEZER. Reported-by: Cheng Renquan Signed-off-by: Rafael J. Wysocki Acked-by: Pavel Machek Signed-off-by: Len Brown --- kernel/power/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/power/Makefile b/kernel/power/Makefile index 597823b5b70..d7a10167a25 100644 --- a/kernel/power/Makefile +++ b/kernel/power/Makefile @@ -4,7 +4,8 @@ EXTRA_CFLAGS += -DDEBUG endif obj-y := main.o -obj-$(CONFIG_PM_SLEEP) += process.o console.o +obj-$(CONFIG_PM_SLEEP) += console.o +obj-$(CONFIG_FREEZER) += process.o obj-$(CONFIG_HIBERNATION) += swsusp.o disk.o snapshot.o swap.o user.o obj-$(CONFIG_MAGIC_SYSRQ) += poweroff.o -- cgit From 5a4ccaf37ffece09ef33f1cfec67efa8ee56f967 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Tue, 6 Jan 2009 21:15:32 +0100 Subject: kprobes: check CONFIG_FREEZER instead of CONFIG_PM Check CONFIG_FREEZER instead of CONFIG_PM because kprobe booster depends on freeze_processes() and thaw_processes() when CONFIG_PREEMPT=y. This fixes a linkage error which occurs when CONFIG_PREEMPT=y, CONFIG_PM=y and CONFIG_FREEZER=n. Reported-by: Cheng Renquan Signed-off-by: Masami Hiramatsu Signed-off-by: Rafael J. Wysocki Acked-by: Ingo Molnar Signed-off-by: Len Brown --- arch/ia64/kernel/kprobes.c | 2 +- arch/x86/kernel/kprobes.c | 2 +- kernel/kprobes.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index f90be51b112..9adac441ac9 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c @@ -870,7 +870,7 @@ static int __kprobes pre_kprobes_handler(struct die_args *args) return 1; ss_probe: -#if !defined(CONFIG_PREEMPT) || defined(CONFIG_PM) +#if !defined(CONFIG_PREEMPT) || defined(CONFIG_FREEZER) if (p->ainsn.inst_flag == INST_FLAG_BOOSTABLE && !p->post_handler) { /* Boost up -- we can execute copied instructions directly */ ia64_psr(regs)->ri = p->ainsn.slot; diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c index 884d985b8b8..e948b28a5a9 100644 --- a/arch/x86/kernel/kprobes.c +++ b/arch/x86/kernel/kprobes.c @@ -446,7 +446,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, static void __kprobes setup_singlestep(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb) { -#if !defined(CONFIG_PREEMPT) || defined(CONFIG_PM) +#if !defined(CONFIG_PREEMPT) || defined(CONFIG_FREEZER) if (p->ainsn.boostable == 1 && !p->post_handler) { /* Boost up -- we can execute copied instructions directly */ reset_current_kprobe(); diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 1b9cbdc0127..7ba8cd9845c 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -123,7 +123,7 @@ static int collect_garbage_slots(void); static int __kprobes check_safety(void) { int ret = 0; -#if defined(CONFIG_PREEMPT) && defined(CONFIG_PM) +#if defined(CONFIG_PREEMPT) && defined(CONFIG_FREEZER) ret = freeze_processes(); if (ret == 0) { struct task_struct *p, *q; -- cgit From c3407710b76610962a5ebb244172631ef9eeb51a Mon Sep 17 00:00:00 2001 From: David Brownell Date: Fri, 9 Jan 2009 12:17:08 -0800 Subject: ACPI: fix ACPI_FADT_S4_RTC_WAKE comment Make the comment for ACPI_FADT_S4_RTC_WAKE match the ACPI spec; that bit has nothing to do with status bits. Signed-off-by: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- include/acpi/actbl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h index 813e4b6c2c0..bf8d4cfd8cf 100644 --- a/include/acpi/actbl.h +++ b/include/acpi/actbl.h @@ -245,7 +245,7 @@ struct acpi_table_fadt { #define ACPI_FADT_POWER_BUTTON (1<<4) /* 04: Power button is handled as a generic feature */ #define ACPI_FADT_SLEEP_BUTTON (1<<5) /* 05: Sleep button is handled as a generic feature, or not present */ #define ACPI_FADT_FIXED_RTC (1<<6) /* 06: RTC wakeup stat not in fixed register space */ -#define ACPI_FADT_S4_RTC_WAKE (1<<7) /* 07: RTC wakeup stat not possible from S4 */ +#define ACPI_FADT_S4_RTC_WAKE (1<<7) /* 07: RTC wakeup possible from S4 */ #define ACPI_FADT_32BIT_TIMER (1<<8) /* 08: tmr_val is 32 bits 0=24-bits */ #define ACPI_FADT_DOCKING_SUPPORTED (1<<9) /* 09: Docking supported */ #define ACPI_FADT_RESET_REGISTER (1<<10) /* 10: System reset via the FADT RESET_REG supported */ -- cgit From 3af9bfcb433c110839e4c815a9928377f66bbd0e Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Wed, 3 Dec 2008 20:31:11 +0000 Subject: eeepc-laptop: enable Bluetooth ACPI details Although rfkill support for the EEE bluetooth device has been added to 2.6.28-rc the appropriate ACPI accessor definitions were not added, so the support was non functional. The patch below adds the get and set accessors and has been verified to work on an EEE 901. Signed-off-by: Jonathan McDowell Acked-by: Matthew Garrett Acked-by: Corentin Chary Signed-off-by: Len Brown --- drivers/platform/x86/eeepc-laptop.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 02fe2b8b893..9d93cb971e5 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -90,7 +90,7 @@ enum { }; static const char *cm_getv[] = { - "WLDG", NULL, NULL, NULL, + "WLDG", "BTHG", NULL, NULL, "CAMG", NULL, NULL, NULL, NULL, "PBLG", NULL, NULL, "CFVG", NULL, NULL, NULL, @@ -99,7 +99,7 @@ static const char *cm_getv[] = { }; static const char *cm_setv[] = { - "WLDS", NULL, NULL, NULL, + "WLDS", "BTHS", NULL, NULL, "CAMS", NULL, NULL, NULL, "SDSP", "PBLS", "HDPS", NULL, "CFVS", NULL, NULL, NULL, -- cgit From cad73120ab0dfd484682229346de8c16073577e1 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 9 Jan 2009 17:23:38 -0500 Subject: dell-laptop: move to drivers/platform/x86/ from drivers/misc/ Signed-off-by: Len Brown --- drivers/misc/Makefile | 1 - drivers/misc/dell-laptop.c | 436 ------------------------------------- drivers/platform/x86/Kconfig | 12 + drivers/platform/x86/Makefile | 1 + drivers/platform/x86/dell-laptop.c | 436 +++++++++++++++++++++++++++++++++++++ 5 files changed, 449 insertions(+), 437 deletions(-) delete mode 100644 drivers/misc/dell-laptop.c create mode 100644 drivers/platform/x86/dell-laptop.c diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 9cf8ae6e4b3..d5749a7bc77 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -10,7 +10,6 @@ obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o obj-$(CONFIG_ICS932S401) += ics932s401.o obj-$(CONFIG_LKDTM) += lkdtm.o obj-$(CONFIG_TIFM_CORE) += tifm_core.o -obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o obj-$(CONFIG_PHANTOM) += phantom.o obj-$(CONFIG_SGI_IOC4) += ioc4.o diff --git a/drivers/misc/dell-laptop.c b/drivers/misc/dell-laptop.c deleted file mode 100644 index 4d33a2068b7..00000000000 --- a/drivers/misc/dell-laptop.c +++ /dev/null @@ -1,436 +0,0 @@ -/* - * Driver for Dell laptop extras - * - * Copyright (c) Red Hat - * - * Based on documentation in the libsmbios package, Copyright (C) 2005 Dell - * Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../firmware/dcdbas.h" - -#define BRIGHTNESS_TOKEN 0x7d - -/* This structure will be modified by the firmware when we enter - * system management mode, hence the volatiles */ - -struct calling_interface_buffer { - u16 class; - u16 select; - volatile u32 input[4]; - volatile u32 output[4]; -} __packed; - -struct calling_interface_token { - u16 tokenID; - u16 location; - union { - u16 value; - u16 stringlength; - }; -}; - -struct calling_interface_structure { - struct dmi_header header; - u16 cmdIOAddress; - u8 cmdIOCode; - u32 supportedCmds; - struct calling_interface_token tokens[]; -} __packed; - -static int da_command_address; -static int da_command_code; -static int da_num_tokens; -static struct calling_interface_token *da_tokens; - -static struct backlight_device *dell_backlight_device; -static struct rfkill *wifi_rfkill; -static struct rfkill *bluetooth_rfkill; -static struct rfkill *wwan_rfkill; - -static const struct dmi_system_id __initdata dell_device_table[] = { - { - .ident = "Dell laptop", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_CHASSIS_TYPE, "8"), - }, - }, - { } -}; - -static void parse_da_table(const struct dmi_header *dm) -{ - /* Final token is a terminator, so we don't want to copy it */ - int tokens = (dm->length-11)/sizeof(struct calling_interface_token)-1; - struct calling_interface_structure *table = - container_of(dm, struct calling_interface_structure, header); - - /* 4 bytes of table header, plus 7 bytes of Dell header, plus at least - 6 bytes of entry */ - - if (dm->length < 17) - return; - - da_command_address = table->cmdIOAddress; - da_command_code = table->cmdIOCode; - - da_tokens = krealloc(da_tokens, (da_num_tokens + tokens) * - sizeof(struct calling_interface_token), - GFP_KERNEL); - - if (!da_tokens) - return; - - memcpy(da_tokens+da_num_tokens, table->tokens, - sizeof(struct calling_interface_token) * tokens); - - da_num_tokens += tokens; -} - -static void find_tokens(const struct dmi_header *dm) -{ - switch (dm->type) { - case 0xd4: /* Indexed IO */ - break; - case 0xd5: /* Protected Area Type 1 */ - break; - case 0xd6: /* Protected Area Type 2 */ - break; - case 0xda: /* Calling interface */ - parse_da_table(dm); - break; - } -} - -static int find_token_location(int tokenid) -{ - int i; - for (i = 0; i < da_num_tokens; i++) { - if (da_tokens[i].tokenID == tokenid) - return da_tokens[i].location; - } - - return -1; -} - -static struct calling_interface_buffer * -dell_send_request(struct calling_interface_buffer *buffer, int class, - int select) -{ - struct smi_cmd command; - - command.magic = SMI_CMD_MAGIC; - command.command_address = da_command_address; - command.command_code = da_command_code; - command.ebx = virt_to_phys(buffer); - command.ecx = 0x42534931; - - buffer->class = class; - buffer->select = select; - - dcdbas_smi_request(&command); - - return buffer; -} - -/* Derived from information in DellWirelessCtl.cpp: - Class 17, select 11 is radio control. It returns an array of 32-bit values. - - result[0]: return code - result[1]: - Bit 0: Hardware switch supported - Bit 1: Wifi locator supported - Bit 2: Wifi is supported - Bit 3: Bluetooth is supported - Bit 4: WWAN is supported - Bit 5: Wireless keyboard supported - Bits 6-7: Reserved - Bit 8: Wifi is installed - Bit 9: Bluetooth is installed - Bit 10: WWAN is installed - Bits 11-15: Reserved - Bit 16: Hardware switch is on - Bit 17: Wifi is blocked - Bit 18: Bluetooth is blocked - Bit 19: WWAN is blocked - Bits 20-31: Reserved - result[2]: NVRAM size in bytes - result[3]: NVRAM format version number -*/ - -static int dell_rfkill_set(int radio, enum rfkill_state state) -{ - struct calling_interface_buffer buffer; - int disable = (state == RFKILL_STATE_UNBLOCKED) ? 0 : 1; - - memset(&buffer, 0, sizeof(struct calling_interface_buffer)); - buffer.input[0] = (1 | (radio<<8) | (disable << 16)); - dell_send_request(&buffer, 17, 11); - - return 0; -} - -static int dell_wifi_set(void *data, enum rfkill_state state) -{ - return dell_rfkill_set(1, state); -} - -static int dell_bluetooth_set(void *data, enum rfkill_state state) -{ - return dell_rfkill_set(2, state); -} - -static int dell_wwan_set(void *data, enum rfkill_state state) -{ - return dell_rfkill_set(3, state); -} - -static int dell_rfkill_get(int bit, enum rfkill_state *state) -{ - struct calling_interface_buffer buffer; - int status; - int new_state = RFKILL_STATE_HARD_BLOCKED; - - memset(&buffer, 0, sizeof(struct calling_interface_buffer)); - dell_send_request(&buffer, 17, 11); - status = buffer.output[1]; - - if (status & (1<<16)) - new_state = RFKILL_STATE_SOFT_BLOCKED; - - if (status & (1<name = "dell-wifi"; - wifi_rfkill->toggle_radio = dell_wifi_set; - wifi_rfkill->get_state = dell_wifi_get; - ret = rfkill_register(wifi_rfkill); - if (ret) - goto err_wifi; - } - - if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) { - bluetooth_rfkill = rfkill_allocate(NULL, RFKILL_TYPE_BLUETOOTH); - if (!bluetooth_rfkill) - goto err_bluetooth; - bluetooth_rfkill->name = "dell-bluetooth"; - bluetooth_rfkill->toggle_radio = dell_bluetooth_set; - bluetooth_rfkill->get_state = dell_bluetooth_get; - ret = rfkill_register(bluetooth_rfkill); - if (ret) - goto err_bluetooth; - } - - if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) { - wwan_rfkill = rfkill_allocate(NULL, RFKILL_TYPE_WWAN); - if (!wwan_rfkill) - goto err_wwan; - wwan_rfkill->name = "dell-wwan"; - wwan_rfkill->toggle_radio = dell_wwan_set; - wwan_rfkill->get_state = dell_wwan_get; - ret = rfkill_register(wwan_rfkill); - if (ret) - goto err_wwan; - } - - return 0; -err_wwan: - if (wwan_rfkill) - rfkill_free(wwan_rfkill); - if (bluetooth_rfkill) { - rfkill_unregister(bluetooth_rfkill); - bluetooth_rfkill = NULL; - } -err_bluetooth: - if (bluetooth_rfkill) - rfkill_free(bluetooth_rfkill); - if (wifi_rfkill) { - rfkill_unregister(wifi_rfkill); - wifi_rfkill = NULL; - } -err_wifi: - if (wifi_rfkill) - rfkill_free(wifi_rfkill); - - return ret; -} - -static int dell_send_intensity(struct backlight_device *bd) -{ - struct calling_interface_buffer buffer; - - memset(&buffer, 0, sizeof(struct calling_interface_buffer)); - buffer.input[0] = find_token_location(BRIGHTNESS_TOKEN); - buffer.input[1] = bd->props.brightness; - - if (buffer.input[0] == -1) - return -ENODEV; - - if (power_supply_is_system_supplied() > 0) - dell_send_request(&buffer, 1, 2); - else - dell_send_request(&buffer, 1, 1); - - return 0; -} - -static int dell_get_intensity(struct backlight_device *bd) -{ - struct calling_interface_buffer buffer; - - memset(&buffer, 0, sizeof(struct calling_interface_buffer)); - buffer.input[0] = find_token_location(BRIGHTNESS_TOKEN); - - if (buffer.input[0] == -1) - return -ENODEV; - - if (power_supply_is_system_supplied() > 0) - dell_send_request(&buffer, 0, 2); - else - dell_send_request(&buffer, 0, 1); - - return buffer.output[1]; -} - -static struct backlight_ops dell_ops = { - .get_brightness = dell_get_intensity, - .update_status = dell_send_intensity, -}; - -static int __init dell_init(void) -{ - struct calling_interface_buffer buffer; - int max_intensity = 0; - int ret; - - if (!dmi_check_system(dell_device_table)) - return -ENODEV; - - dmi_walk(find_tokens); - - if (!da_tokens) { - printk(KERN_INFO "dell-laptop: Unable to find dmi tokens\n"); - return -ENODEV; - } - - ret = dell_setup_rfkill(); - - if (ret) { - printk(KERN_WARNING "dell-laptop: Unable to setup rfkill\n"); - goto out; - } - -#ifdef CONFIG_ACPI - /* In the event of an ACPI backlight being available, don't - * register the platform controller. - */ - if (acpi_video_backlight_support()) - return 0; -#endif - - memset(&buffer, 0, sizeof(struct calling_interface_buffer)); - buffer.input[0] = find_token_location(BRIGHTNESS_TOKEN); - - if (buffer.input[0] != -1) { - dell_send_request(&buffer, 0, 2); - max_intensity = buffer.output[3]; - } - - if (max_intensity) { - dell_backlight_device = backlight_device_register( - "dell_backlight", - NULL, NULL, - &dell_ops); - - if (IS_ERR(dell_backlight_device)) { - ret = PTR_ERR(dell_backlight_device); - dell_backlight_device = NULL; - goto out; - } - - dell_backlight_device->props.max_brightness = max_intensity; - dell_backlight_device->props.brightness = - dell_get_intensity(dell_backlight_device); - backlight_update_status(dell_backlight_device); - } - - return 0; -out: - if (wifi_rfkill) - rfkill_unregister(wifi_rfkill); - if (bluetooth_rfkill) - rfkill_unregister(bluetooth_rfkill); - if (wwan_rfkill) - rfkill_unregister(wwan_rfkill); - kfree(da_tokens); - return ret; -} - -static void __exit dell_exit(void) -{ - backlight_device_unregister(dell_backlight_device); - if (wifi_rfkill) - rfkill_unregister(wifi_rfkill); - if (bluetooth_rfkill) - rfkill_unregister(bluetooth_rfkill); - if (wwan_rfkill) - rfkill_unregister(wwan_rfkill); -} - -module_init(dell_init); -module_exit(dell_exit); - -MODULE_AUTHOR("Matthew Garrett "); -MODULE_DESCRIPTION("Dell laptop driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("dmi:*svnDellInc.:*:ct8:*"); diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index e65448e99b4..9e8f9485f9c 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -54,6 +54,18 @@ config ASUS_LAPTOP If you have an ACPI-compatible ASUS laptop, say Y or M here. +config DELL_LAPTOP + tristate "Dell Laptop Extras (EXPERIMENTAL)" + depends on X86 + depends on DCDBAS + depends on EXPERIMENTAL + depends on BACKLIGHT_CLASS_DEVICE + depends on RFKILL + default n + ---help--- + This driver adds support for rfkill and backlight control to Dell + laptops. + config FUJITSU_LAPTOP tristate "Fujitsu Laptop Extras" depends on ACPI diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index 1e9de2ae0de..e29065120be 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o +obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o obj-$(CONFIG_ACER_WMI) += acer-wmi.o obj-$(CONFIG_HP_WMI) += hp-wmi.o obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c new file mode 100644 index 00000000000..16e11c2ee19 --- /dev/null +++ b/drivers/platform/x86/dell-laptop.c @@ -0,0 +1,436 @@ +/* + * Driver for Dell laptop extras + * + * Copyright (c) Red Hat + * + * Based on documentation in the libsmbios package, Copyright (C) 2005 Dell + * Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../firmware/dcdbas.h" + +#define BRIGHTNESS_TOKEN 0x7d + +/* This structure will be modified by the firmware when we enter + * system management mode, hence the volatiles */ + +struct calling_interface_buffer { + u16 class; + u16 select; + volatile u32 input[4]; + volatile u32 output[4]; +} __packed; + +struct calling_interface_token { + u16 tokenID; + u16 location; + union { + u16 value; + u16 stringlength; + }; +}; + +struct calling_interface_structure { + struct dmi_header header; + u16 cmdIOAddress; + u8 cmdIOCode; + u32 supportedCmds; + struct calling_interface_token tokens[]; +} __packed; + +static int da_command_address; +static int da_command_code; +static int da_num_tokens; +static struct calling_interface_token *da_tokens; + +static struct backlight_device *dell_backlight_device; +static struct rfkill *wifi_rfkill; +static struct rfkill *bluetooth_rfkill; +static struct rfkill *wwan_rfkill; + +static const struct dmi_system_id __initdata dell_device_table[] = { + { + .ident = "Dell laptop", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_CHASSIS_TYPE, "8"), + }, + }, + { } +}; + +static void parse_da_table(const struct dmi_header *dm) +{ + /* Final token is a terminator, so we don't want to copy it */ + int tokens = (dm->length-11)/sizeof(struct calling_interface_token)-1; + struct calling_interface_structure *table = + container_of(dm, struct calling_interface_structure, header); + + /* 4 bytes of table header, plus 7 bytes of Dell header, plus at least + 6 bytes of entry */ + + if (dm->length < 17) + return; + + da_command_address = table->cmdIOAddress; + da_command_code = table->cmdIOCode; + + da_tokens = krealloc(da_tokens, (da_num_tokens + tokens) * + sizeof(struct calling_interface_token), + GFP_KERNEL); + + if (!da_tokens) + return; + + memcpy(da_tokens+da_num_tokens, table->tokens, + sizeof(struct calling_interface_token) * tokens); + + da_num_tokens += tokens; +} + +static void find_tokens(const struct dmi_header *dm) +{ + switch (dm->type) { + case 0xd4: /* Indexed IO */ + break; + case 0xd5: /* Protected Area Type 1 */ + break; + case 0xd6: /* Protected Area Type 2 */ + break; + case 0xda: /* Calling interface */ + parse_da_table(dm); + break; + } +} + +static int find_token_location(int tokenid) +{ + int i; + for (i = 0; i < da_num_tokens; i++) { + if (da_tokens[i].tokenID == tokenid) + return da_tokens[i].location; + } + + return -1; +} + +static struct calling_interface_buffer * +dell_send_request(struct calling_interface_buffer *buffer, int class, + int select) +{ + struct smi_cmd command; + + command.magic = SMI_CMD_MAGIC; + command.command_address = da_command_address; + command.command_code = da_command_code; + command.ebx = virt_to_phys(buffer); + command.ecx = 0x42534931; + + buffer->class = class; + buffer->select = select; + + dcdbas_smi_request(&command); + + return buffer; +} + +/* Derived from information in DellWirelessCtl.cpp: + Class 17, select 11 is radio control. It returns an array of 32-bit values. + + result[0]: return code + result[1]: + Bit 0: Hardware switch supported + Bit 1: Wifi locator supported + Bit 2: Wifi is supported + Bit 3: Bluetooth is supported + Bit 4: WWAN is supported + Bit 5: Wireless keyboard supported + Bits 6-7: Reserved + Bit 8: Wifi is installed + Bit 9: Bluetooth is installed + Bit 10: WWAN is installed + Bits 11-15: Reserved + Bit 16: Hardware switch is on + Bit 17: Wifi is blocked + Bit 18: Bluetooth is blocked + Bit 19: WWAN is blocked + Bits 20-31: Reserved + result[2]: NVRAM size in bytes + result[3]: NVRAM format version number +*/ + +static int dell_rfkill_set(int radio, enum rfkill_state state) +{ + struct calling_interface_buffer buffer; + int disable = (state == RFKILL_STATE_UNBLOCKED) ? 0 : 1; + + memset(&buffer, 0, sizeof(struct calling_interface_buffer)); + buffer.input[0] = (1 | (radio<<8) | (disable << 16)); + dell_send_request(&buffer, 17, 11); + + return 0; +} + +static int dell_wifi_set(void *data, enum rfkill_state state) +{ + return dell_rfkill_set(1, state); +} + +static int dell_bluetooth_set(void *data, enum rfkill_state state) +{ + return dell_rfkill_set(2, state); +} + +static int dell_wwan_set(void *data, enum rfkill_state state) +{ + return dell_rfkill_set(3, state); +} + +static int dell_rfkill_get(int bit, enum rfkill_state *state) +{ + struct calling_interface_buffer buffer; + int status; + int new_state = RFKILL_STATE_HARD_BLOCKED; + + memset(&buffer, 0, sizeof(struct calling_interface_buffer)); + dell_send_request(&buffer, 17, 11); + status = buffer.output[1]; + + if (status & (1<<16)) + new_state = RFKILL_STATE_SOFT_BLOCKED; + + if (status & (1<name = "dell-wifi"; + wifi_rfkill->toggle_radio = dell_wifi_set; + wifi_rfkill->get_state = dell_wifi_get; + ret = rfkill_register(wifi_rfkill); + if (ret) + goto err_wifi; + } + + if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) { + bluetooth_rfkill = rfkill_allocate(NULL, RFKILL_TYPE_BLUETOOTH); + if (!bluetooth_rfkill) + goto err_bluetooth; + bluetooth_rfkill->name = "dell-bluetooth"; + bluetooth_rfkill->toggle_radio = dell_bluetooth_set; + bluetooth_rfkill->get_state = dell_bluetooth_get; + ret = rfkill_register(bluetooth_rfkill); + if (ret) + goto err_bluetooth; + } + + if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) { + wwan_rfkill = rfkill_allocate(NULL, RFKILL_TYPE_WWAN); + if (!wwan_rfkill) + goto err_wwan; + wwan_rfkill->name = "dell-wwan"; + wwan_rfkill->toggle_radio = dell_wwan_set; + wwan_rfkill->get_state = dell_wwan_get; + ret = rfkill_register(wwan_rfkill); + if (ret) + goto err_wwan; + } + + return 0; +err_wwan: + if (wwan_rfkill) + rfkill_free(wwan_rfkill); + if (bluetooth_rfkill) { + rfkill_unregister(bluetooth_rfkill); + bluetooth_rfkill = NULL; + } +err_bluetooth: + if (bluetooth_rfkill) + rfkill_free(bluetooth_rfkill); + if (wifi_rfkill) { + rfkill_unregister(wifi_rfkill); + wifi_rfkill = NULL; + } +err_wifi: + if (wifi_rfkill) + rfkill_free(wifi_rfkill); + + return ret; +} + +static int dell_send_intensity(struct backlight_device *bd) +{ + struct calling_interface_buffer buffer; + + memset(&buffer, 0, sizeof(struct calling_interface_buffer)); + buffer.input[0] = find_token_location(BRIGHTNESS_TOKEN); + buffer.input[1] = bd->props.brightness; + + if (buffer.input[0] == -1) + return -ENODEV; + + if (power_supply_is_system_supplied() > 0) + dell_send_request(&buffer, 1, 2); + else + dell_send_request(&buffer, 1, 1); + + return 0; +} + +static int dell_get_intensity(struct backlight_device *bd) +{ + struct calling_interface_buffer buffer; + + memset(&buffer, 0, sizeof(struct calling_interface_buffer)); + buffer.input[0] = find_token_location(BRIGHTNESS_TOKEN); + + if (buffer.input[0] == -1) + return -ENODEV; + + if (power_supply_is_system_supplied() > 0) + dell_send_request(&buffer, 0, 2); + else + dell_send_request(&buffer, 0, 1); + + return buffer.output[1]; +} + +static struct backlight_ops dell_ops = { + .get_brightness = dell_get_intensity, + .update_status = dell_send_intensity, +}; + +static int __init dell_init(void) +{ + struct calling_interface_buffer buffer; + int max_intensity = 0; + int ret; + + if (!dmi_check_system(dell_device_table)) + return -ENODEV; + + dmi_walk(find_tokens); + + if (!da_tokens) { + printk(KERN_INFO "dell-laptop: Unable to find dmi tokens\n"); + return -ENODEV; + } + + ret = dell_setup_rfkill(); + + if (ret) { + printk(KERN_WARNING "dell-laptop: Unable to setup rfkill\n"); + goto out; + } + +#ifdef CONFIG_ACPI + /* In the event of an ACPI backlight being available, don't + * register the platform controller. + */ + if (acpi_video_backlight_support()) + return 0; +#endif + + memset(&buffer, 0, sizeof(struct calling_interface_buffer)); + buffer.input[0] = find_token_location(BRIGHTNESS_TOKEN); + + if (buffer.input[0] != -1) { + dell_send_request(&buffer, 0, 2); + max_intensity = buffer.output[3]; + } + + if (max_intensity) { + dell_backlight_device = backlight_device_register( + "dell_backlight", + NULL, NULL, + &dell_ops); + + if (IS_ERR(dell_backlight_device)) { + ret = PTR_ERR(dell_backlight_device); + dell_backlight_device = NULL; + goto out; + } + + dell_backlight_device->props.max_brightness = max_intensity; + dell_backlight_device->props.brightness = + dell_get_intensity(dell_backlight_device); + backlight_update_status(dell_backlight_device); + } + + return 0; +out: + if (wifi_rfkill) + rfkill_unregister(wifi_rfkill); + if (bluetooth_rfkill) + rfkill_unregister(bluetooth_rfkill); + if (wwan_rfkill) + rfkill_unregister(wwan_rfkill); + kfree(da_tokens); + return ret; +} + +static void __exit dell_exit(void) +{ + backlight_device_unregister(dell_backlight_device); + if (wifi_rfkill) + rfkill_unregister(wifi_rfkill); + if (bluetooth_rfkill) + rfkill_unregister(bluetooth_rfkill); + if (wwan_rfkill) + rfkill_unregister(wwan_rfkill); +} + +module_init(dell_init); +module_exit(dell_exit); + +MODULE_AUTHOR("Matthew Garrett "); +MODULE_DESCRIPTION("Dell laptop driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("dmi:*svnDellInc.:*:ct8:*"); -- cgit From d08ca2ca743f324eceba59e93188f9439e966bce Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 16 Jan 2009 13:52:03 -0500 Subject: ACPI: rename main.c to sleep.c Signed-off-by: Len Brown --- drivers/acpi/Makefile | 2 +- drivers/acpi/main.c | 747 -------------------------------------------------- drivers/acpi/sleep.c | 747 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 748 insertions(+), 748 deletions(-) delete mode 100644 drivers/acpi/main.c create mode 100644 drivers/acpi/sleep.c diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index d80f4cc2e0d..65d90c720b5 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -19,7 +19,7 @@ obj-y += osl.o utils.o reboot.o\ # sleep related files obj-y += wakeup.o -obj-y += main.o +obj-y += sleep.o obj-$(CONFIG_ACPI_SLEEP) += proc.o diff --git a/drivers/acpi/main.c b/drivers/acpi/main.c deleted file mode 100644 index 7e3c609cbef..00000000000 --- a/drivers/acpi/main.c +++ /dev/null @@ -1,747 +0,0 @@ -/* - * sleep.c - ACPI sleep support. - * - * Copyright (c) 2005 Alexey Starikovskiy - * Copyright (c) 2004 David Shaohua Li - * Copyright (c) 2000-2003 Patrick Mochel - * Copyright (c) 2003 Open Source Development Lab - * - * This file is released under the GPLv2. - * - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include "sleep.h" - -u8 sleep_states[ACPI_S_STATE_COUNT]; - -static void acpi_sleep_tts_switch(u32 acpi_state) -{ - union acpi_object in_arg = { ACPI_TYPE_INTEGER }; - struct acpi_object_list arg_list = { 1, &in_arg }; - acpi_status status = AE_OK; - - in_arg.integer.value = acpi_state; - status = acpi_evaluate_object(NULL, "\\_TTS", &arg_list, NULL); - if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { - /* - * OS can't evaluate the _TTS object correctly. Some warning - * message will be printed. But it won't break anything. - */ - printk(KERN_NOTICE "Failure in evaluating _TTS object\n"); - } -} - -static int tts_notify_reboot(struct notifier_block *this, - unsigned long code, void *x) -{ - acpi_sleep_tts_switch(ACPI_STATE_S5); - return NOTIFY_DONE; -} - -static struct notifier_block tts_notifier = { - .notifier_call = tts_notify_reboot, - .next = NULL, - .priority = 0, -}; - -static int acpi_sleep_prepare(u32 acpi_state) -{ -#ifdef CONFIG_ACPI_SLEEP - /* do we have a wakeup address for S2 and S3? */ - if (acpi_state == ACPI_STATE_S3) { - if (!acpi_wakeup_address) { - return -EFAULT; - } - acpi_set_firmware_waking_vector( - (acpi_physical_address)acpi_wakeup_address); - - } - ACPI_FLUSH_CPU_CACHE(); - acpi_enable_wakeup_device_prep(acpi_state); -#endif - printk(KERN_INFO PREFIX "Preparing to enter system sleep state S%d\n", - acpi_state); - acpi_enter_sleep_state_prep(acpi_state); - return 0; -} - -#ifdef CONFIG_ACPI_SLEEP -static u32 acpi_target_sleep_state = ACPI_STATE_S0; -/* - * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the - * user to request that behavior by using the 'acpi_old_suspend_ordering' - * kernel command line option that causes the following variable to be set. - */ -static bool old_suspend_ordering; - -void __init acpi_old_suspend_ordering(void) -{ - old_suspend_ordering = true; -} - -/* - * According to the ACPI specification the BIOS should make sure that ACPI is - * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still, - * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI - * on such systems during resume. Unfortunately that doesn't help in - * particularly pathological cases in which SCI_EN has to be set directly on - * resume, although the specification states very clearly that this flag is - * owned by the hardware. The set_sci_en_on_resume variable will be set in such - * cases. - */ -static bool set_sci_en_on_resume; -/* - * The ACPI specification wants us to save NVS memory regions during hibernation - * and to restore them during the subsequent resume. However, it is not certain - * if this mechanism is going to work on all machines, so we allow the user to - * disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line - * option. - */ -static bool s4_no_nvs; - -void __init acpi_s4_no_nvs(void) -{ - s4_no_nvs = true; -} - -/** - * acpi_pm_disable_gpes - Disable the GPEs. - */ -static int acpi_pm_disable_gpes(void) -{ - acpi_disable_all_gpes(); - return 0; -} - -/** - * __acpi_pm_prepare - Prepare the platform to enter the target state. - * - * If necessary, set the firmware waking vector and do arch-specific - * nastiness to get the wakeup code to the waking vector. - */ -static int __acpi_pm_prepare(void) -{ - int error = acpi_sleep_prepare(acpi_target_sleep_state); - - if (error) - acpi_target_sleep_state = ACPI_STATE_S0; - return error; -} - -/** - * acpi_pm_prepare - Prepare the platform to enter the target sleep - * state and disable the GPEs. - */ -static int acpi_pm_prepare(void) -{ - int error = __acpi_pm_prepare(); - - if (!error) - acpi_disable_all_gpes(); - return error; -} - -/** - * acpi_pm_finish - Instruct the platform to leave a sleep state. - * - * This is called after we wake back up (or if entering the sleep state - * failed). - */ -static void acpi_pm_finish(void) -{ - u32 acpi_state = acpi_target_sleep_state; - - if (acpi_state == ACPI_STATE_S0) - return; - - printk(KERN_INFO PREFIX "Waking up from system sleep state S%d\n", - acpi_state); - acpi_disable_wakeup_device(acpi_state); - acpi_leave_sleep_state(acpi_state); - - /* reset firmware waking vector */ - acpi_set_firmware_waking_vector((acpi_physical_address) 0); - - acpi_target_sleep_state = ACPI_STATE_S0; -} - -/** - * acpi_pm_end - Finish up suspend sequence. - */ -static void acpi_pm_end(void) -{ - /* - * This is necessary in case acpi_pm_finish() is not called during a - * failing transition to a sleep state. - */ - acpi_target_sleep_state = ACPI_STATE_S0; - acpi_sleep_tts_switch(acpi_target_sleep_state); -} -#else /* !CONFIG_ACPI_SLEEP */ -#define acpi_target_sleep_state ACPI_STATE_S0 -#endif /* CONFIG_ACPI_SLEEP */ - -#ifdef CONFIG_SUSPEND -extern void do_suspend_lowlevel(void); - -static u32 acpi_suspend_states[] = { - [PM_SUSPEND_ON] = ACPI_STATE_S0, - [PM_SUSPEND_STANDBY] = ACPI_STATE_S1, - [PM_SUSPEND_MEM] = ACPI_STATE_S3, - [PM_SUSPEND_MAX] = ACPI_STATE_S5 -}; - -/** - * acpi_suspend_begin - Set the target system sleep state to the state - * associated with given @pm_state, if supported. - */ -static int acpi_suspend_begin(suspend_state_t pm_state) -{ - u32 acpi_state = acpi_suspend_states[pm_state]; - int error = 0; - - if (sleep_states[acpi_state]) { - acpi_target_sleep_state = acpi_state; - acpi_sleep_tts_switch(acpi_target_sleep_state); - } else { - printk(KERN_ERR "ACPI does not support this state: %d\n", - pm_state); - error = -ENOSYS; - } - return error; -} - -/** - * acpi_suspend_enter - Actually enter a sleep state. - * @pm_state: ignored - * - * Flush caches and go to sleep. For STR we have to call arch-specific - * assembly, which in turn call acpi_enter_sleep_state(). - * It's unfortunate, but it works. Please fix if you're feeling frisky. - */ -static int acpi_suspend_enter(suspend_state_t pm_state) -{ - acpi_status status = AE_OK; - unsigned long flags = 0; - u32 acpi_state = acpi_target_sleep_state; - - ACPI_FLUSH_CPU_CACHE(); - - /* Do arch specific saving of state. */ - if (acpi_state == ACPI_STATE_S3) { - int error = acpi_save_state_mem(); - - if (error) - return error; - } - - local_irq_save(flags); - acpi_enable_wakeup_device(acpi_state); - switch (acpi_state) { - case ACPI_STATE_S1: - barrier(); - status = acpi_enter_sleep_state(acpi_state); - break; - - case ACPI_STATE_S3: - do_suspend_lowlevel(); - break; - } - - /* If ACPI is not enabled by the BIOS, we need to enable it here. */ - if (set_sci_en_on_resume) - acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1); - else - acpi_enable(); - - /* Reprogram control registers and execute _BFS */ - acpi_leave_sleep_state_prep(acpi_state); - - /* ACPI 3.0 specs (P62) says that it's the responsibility - * of the OSPM to clear the status bit [ implying that the - * POWER_BUTTON event should not reach userspace ] - */ - if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3)) - acpi_clear_event(ACPI_EVENT_POWER_BUTTON); - - /* - * Disable and clear GPE status before interrupt is enabled. Some GPEs - * (like wakeup GPE) haven't handler, this can avoid such GPE misfire. - * acpi_leave_sleep_state will reenable specific GPEs later - */ - acpi_disable_all_gpes(); - - local_irq_restore(flags); - printk(KERN_DEBUG "Back to C!\n"); - - /* restore processor state */ - if (acpi_state == ACPI_STATE_S3) - acpi_restore_state_mem(); - - return ACPI_SUCCESS(status) ? 0 : -EFAULT; -} - -static int acpi_suspend_state_valid(suspend_state_t pm_state) -{ - u32 acpi_state; - - switch (pm_state) { - case PM_SUSPEND_ON: - case PM_SUSPEND_STANDBY: - case PM_SUSPEND_MEM: - acpi_state = acpi_suspend_states[pm_state]; - - return sleep_states[acpi_state]; - default: - return 0; - } -} - -static struct platform_suspend_ops acpi_suspend_ops = { - .valid = acpi_suspend_state_valid, - .begin = acpi_suspend_begin, - .prepare = acpi_pm_prepare, - .enter = acpi_suspend_enter, - .finish = acpi_pm_finish, - .end = acpi_pm_end, -}; - -/** - * acpi_suspend_begin_old - Set the target system sleep state to the - * state associated with given @pm_state, if supported, and - * execute the _PTS control method. This function is used if the - * pre-ACPI 2.0 suspend ordering has been requested. - */ -static int acpi_suspend_begin_old(suspend_state_t pm_state) -{ - int error = acpi_suspend_begin(pm_state); - - if (!error) - error = __acpi_pm_prepare(); - return error; -} - -/* - * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has - * been requested. - */ -static struct platform_suspend_ops acpi_suspend_ops_old = { - .valid = acpi_suspend_state_valid, - .begin = acpi_suspend_begin_old, - .prepare = acpi_pm_disable_gpes, - .enter = acpi_suspend_enter, - .finish = acpi_pm_finish, - .end = acpi_pm_end, - .recover = acpi_pm_finish, -}; - -static int __init init_old_suspend_ordering(const struct dmi_system_id *d) -{ - old_suspend_ordering = true; - return 0; -} - -static int __init init_set_sci_en_on_resume(const struct dmi_system_id *d) -{ - set_sci_en_on_resume = true; - return 0; -} - -static struct dmi_system_id __initdata acpisleep_dmi_table[] = { - { - .callback = init_old_suspend_ordering, - .ident = "Abit KN9 (nForce4 variant)", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "http://www.abit.com.tw/"), - DMI_MATCH(DMI_BOARD_NAME, "KN9 Series(NF-CK804)"), - }, - }, - { - .callback = init_old_suspend_ordering, - .ident = "HP xw4600 Workstation", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Apple MacBook 1,1", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Apple MacMini 1,1", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"), - }, - }, - {}, -}; -#endif /* CONFIG_SUSPEND */ - -#ifdef CONFIG_HIBERNATION -static unsigned long s4_hardware_signature; -static struct acpi_table_facs *facs; -static bool nosigcheck; - -void __init acpi_no_s4_hw_signature(void) -{ - nosigcheck = true; -} - -static int acpi_hibernation_begin(void) -{ - int error; - - error = s4_no_nvs ? 0 : hibernate_nvs_alloc(); - if (!error) { - acpi_target_sleep_state = ACPI_STATE_S4; - acpi_sleep_tts_switch(acpi_target_sleep_state); - } - - return error; -} - -static int acpi_hibernation_pre_snapshot(void) -{ - int error = acpi_pm_prepare(); - - if (!error) - hibernate_nvs_save(); - - return error; -} - -static int acpi_hibernation_enter(void) -{ - acpi_status status = AE_OK; - unsigned long flags = 0; - - ACPI_FLUSH_CPU_CACHE(); - - local_irq_save(flags); - acpi_enable_wakeup_device(ACPI_STATE_S4); - /* This shouldn't return. If it returns, we have a problem */ - status = acpi_enter_sleep_state(ACPI_STATE_S4); - /* Reprogram control registers and execute _BFS */ - acpi_leave_sleep_state_prep(ACPI_STATE_S4); - local_irq_restore(flags); - - return ACPI_SUCCESS(status) ? 0 : -EFAULT; -} - -static void acpi_hibernation_finish(void) -{ - hibernate_nvs_free(); - acpi_pm_finish(); -} - -static void acpi_hibernation_leave(void) -{ - /* - * If ACPI is not enabled by the BIOS and the boot kernel, we need to - * enable it here. - */ - acpi_enable(); - /* Reprogram control registers and execute _BFS */ - acpi_leave_sleep_state_prep(ACPI_STATE_S4); - /* Check the hardware signature */ - if (facs && s4_hardware_signature != facs->hardware_signature) { - printk(KERN_EMERG "ACPI: Hardware changed while hibernated, " - "cannot resume!\n"); - panic("ACPI S4 hardware signature mismatch"); - } - /* Restore the NVS memory area */ - hibernate_nvs_restore(); -} - -static void acpi_pm_enable_gpes(void) -{ - acpi_enable_all_runtime_gpes(); -} - -static struct platform_hibernation_ops acpi_hibernation_ops = { - .begin = acpi_hibernation_begin, - .end = acpi_pm_end, - .pre_snapshot = acpi_hibernation_pre_snapshot, - .finish = acpi_hibernation_finish, - .prepare = acpi_pm_prepare, - .enter = acpi_hibernation_enter, - .leave = acpi_hibernation_leave, - .pre_restore = acpi_pm_disable_gpes, - .restore_cleanup = acpi_pm_enable_gpes, -}; - -/** - * acpi_hibernation_begin_old - Set the target system sleep state to - * ACPI_STATE_S4 and execute the _PTS control method. This - * function is used if the pre-ACPI 2.0 suspend ordering has been - * requested. - */ -static int acpi_hibernation_begin_old(void) -{ - int error; - /* - * The _TTS object should always be evaluated before the _PTS object. - * When the old_suspended_ordering is true, the _PTS object is - * evaluated in the acpi_sleep_prepare. - */ - acpi_sleep_tts_switch(ACPI_STATE_S4); - - error = acpi_sleep_prepare(ACPI_STATE_S4); - - if (!error) { - if (!s4_no_nvs) - error = hibernate_nvs_alloc(); - if (!error) - acpi_target_sleep_state = ACPI_STATE_S4; - } - return error; -} - -static int acpi_hibernation_pre_snapshot_old(void) -{ - int error = acpi_pm_disable_gpes(); - - if (!error) - hibernate_nvs_save(); - - return error; -} - -/* - * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has - * been requested. - */ -static struct platform_hibernation_ops acpi_hibernation_ops_old = { - .begin = acpi_hibernation_begin_old, - .end = acpi_pm_end, - .pre_snapshot = acpi_hibernation_pre_snapshot_old, - .finish = acpi_hibernation_finish, - .prepare = acpi_pm_disable_gpes, - .enter = acpi_hibernation_enter, - .leave = acpi_hibernation_leave, - .pre_restore = acpi_pm_disable_gpes, - .restore_cleanup = acpi_pm_enable_gpes, - .recover = acpi_pm_finish, -}; -#endif /* CONFIG_HIBERNATION */ - -int acpi_suspend(u32 acpi_state) -{ - suspend_state_t states[] = { - [1] = PM_SUSPEND_STANDBY, - [3] = PM_SUSPEND_MEM, - [5] = PM_SUSPEND_MAX - }; - - if (acpi_state < 6 && states[acpi_state]) - return pm_suspend(states[acpi_state]); - if (acpi_state == 4) - return hibernate(); - return -EINVAL; -} - -#ifdef CONFIG_PM_SLEEP -/** - * acpi_pm_device_sleep_state - return preferred power state of ACPI device - * in the system sleep state given by %acpi_target_sleep_state - * @dev: device to examine; its driver model wakeup flags control - * whether it should be able to wake up the system - * @d_min_p: used to store the upper limit of allowed states range - * Return value: preferred power state of the device on success, -ENODEV on - * failure (ie. if there's no 'struct acpi_device' for @dev) - * - * Find the lowest power (highest number) ACPI device power state that - * device @dev can be in while the system is in the sleep state represented - * by %acpi_target_sleep_state. If @wake is nonzero, the device should be - * able to wake up the system from this sleep state. If @d_min_p is set, - * the highest power (lowest number) device power state of @dev allowed - * in this system sleep state is stored at the location pointed to by it. - * - * The caller must ensure that @dev is valid before using this function. - * The caller is also responsible for figuring out if the device is - * supposed to be able to wake up the system and passing this information - * via @wake. - */ - -int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p) -{ - acpi_handle handle = DEVICE_ACPI_HANDLE(dev); - struct acpi_device *adev; - char acpi_method[] = "_SxD"; - unsigned long long d_min, d_max; - - if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { - printk(KERN_DEBUG "ACPI handle has no context!\n"); - return -ENODEV; - } - - acpi_method[2] = '0' + acpi_target_sleep_state; - /* - * If the sleep state is S0, we will return D3, but if the device has - * _S0W, we will use the value from _S0W - */ - d_min = ACPI_STATE_D0; - d_max = ACPI_STATE_D3; - - /* - * If present, _SxD methods return the minimum D-state (highest power - * state) we can use for the corresponding S-states. Otherwise, the - * minimum D-state is D0 (ACPI 3.x). - * - * NOTE: We rely on acpi_evaluate_integer() not clobbering the integer - * provided -- that's our fault recovery, we ignore retval. - */ - if (acpi_target_sleep_state > ACPI_STATE_S0) - acpi_evaluate_integer(handle, acpi_method, NULL, &d_min); - - /* - * If _PRW says we can wake up the system from the target sleep state, - * the D-state returned by _SxD is sufficient for that (we assume a - * wakeup-aware driver if wake is set). Still, if _SxW exists - * (ACPI 3.x), it should return the maximum (lowest power) D-state that - * can wake the system. _S0W may be valid, too. - */ - if (acpi_target_sleep_state == ACPI_STATE_S0 || - (device_may_wakeup(dev) && adev->wakeup.state.enabled && - adev->wakeup.sleep_state <= acpi_target_sleep_state)) { - acpi_status status; - - acpi_method[3] = 'W'; - status = acpi_evaluate_integer(handle, acpi_method, NULL, - &d_max); - if (ACPI_FAILURE(status)) { - d_max = d_min; - } else if (d_max < d_min) { - /* Warn the user of the broken DSDT */ - printk(KERN_WARNING "ACPI: Wrong value from %s\n", - acpi_method); - /* Sanitize it */ - d_min = d_max; - } - } - - if (d_min_p) - *d_min_p = d_min; - return d_max; -} - -/** - * acpi_pm_device_sleep_wake - enable or disable the system wake-up - * capability of given device - * @dev: device to handle - * @enable: 'true' - enable, 'false' - disable the wake-up capability - */ -int acpi_pm_device_sleep_wake(struct device *dev, bool enable) -{ - acpi_handle handle; - struct acpi_device *adev; - - if (!device_may_wakeup(dev)) - return -EINVAL; - - handle = DEVICE_ACPI_HANDLE(dev); - if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { - printk(KERN_DEBUG "ACPI handle has no context!\n"); - return -ENODEV; - } - - return enable ? - acpi_enable_wakeup_device_power(adev, acpi_target_sleep_state) : - acpi_disable_wakeup_device_power(adev); -} -#endif - -static void acpi_power_off_prepare(void) -{ - /* Prepare to power off the system */ - acpi_sleep_prepare(ACPI_STATE_S5); - acpi_disable_all_gpes(); -} - -static void acpi_power_off(void) -{ - /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ - printk("%s called\n", __func__); - local_irq_disable(); - acpi_enable_wakeup_device(ACPI_STATE_S5); - acpi_enter_sleep_state(ACPI_STATE_S5); -} - -int __init acpi_sleep_init(void) -{ - acpi_status status; - u8 type_a, type_b; -#ifdef CONFIG_SUSPEND - int i = 0; - - dmi_check_system(acpisleep_dmi_table); -#endif - - if (acpi_disabled) - return 0; - - sleep_states[ACPI_STATE_S0] = 1; - printk(KERN_INFO PREFIX "(supports S0"); - -#ifdef CONFIG_SUSPEND - for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++) { - status = acpi_get_sleep_type_data(i, &type_a, &type_b); - if (ACPI_SUCCESS(status)) { - sleep_states[i] = 1; - printk(" S%d", i); - } - } - - suspend_set_ops(old_suspend_ordering ? - &acpi_suspend_ops_old : &acpi_suspend_ops); -#endif - -#ifdef CONFIG_HIBERNATION - status = acpi_get_sleep_type_data(ACPI_STATE_S4, &type_a, &type_b); - if (ACPI_SUCCESS(status)) { - hibernation_set_ops(old_suspend_ordering ? - &acpi_hibernation_ops_old : &acpi_hibernation_ops); - sleep_states[ACPI_STATE_S4] = 1; - printk(" S4"); - if (!nosigcheck) { - acpi_get_table(ACPI_SIG_FACS, 1, - (struct acpi_table_header **)&facs); - if (facs) - s4_hardware_signature = - facs->hardware_signature; - } - } -#endif - status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b); - if (ACPI_SUCCESS(status)) { - sleep_states[ACPI_STATE_S5] = 1; - printk(" S5"); - pm_power_off_prepare = acpi_power_off_prepare; - pm_power_off = acpi_power_off; - } - printk(")\n"); - /* - * Register the tts_notifier to reboot notifier list so that the _TTS - * object can also be evaluated when the system enters S5. - */ - register_reboot_notifier(&tts_notifier); - return 0; -} diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c new file mode 100644 index 00000000000..7e3c609cbef --- /dev/null +++ b/drivers/acpi/sleep.c @@ -0,0 +1,747 @@ +/* + * sleep.c - ACPI sleep support. + * + * Copyright (c) 2005 Alexey Starikovskiy + * Copyright (c) 2004 David Shaohua Li + * Copyright (c) 2000-2003 Patrick Mochel + * Copyright (c) 2003 Open Source Development Lab + * + * This file is released under the GPLv2. + * + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include "sleep.h" + +u8 sleep_states[ACPI_S_STATE_COUNT]; + +static void acpi_sleep_tts_switch(u32 acpi_state) +{ + union acpi_object in_arg = { ACPI_TYPE_INTEGER }; + struct acpi_object_list arg_list = { 1, &in_arg }; + acpi_status status = AE_OK; + + in_arg.integer.value = acpi_state; + status = acpi_evaluate_object(NULL, "\\_TTS", &arg_list, NULL); + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { + /* + * OS can't evaluate the _TTS object correctly. Some warning + * message will be printed. But it won't break anything. + */ + printk(KERN_NOTICE "Failure in evaluating _TTS object\n"); + } +} + +static int tts_notify_reboot(struct notifier_block *this, + unsigned long code, void *x) +{ + acpi_sleep_tts_switch(ACPI_STATE_S5); + return NOTIFY_DONE; +} + +static struct notifier_block tts_notifier = { + .notifier_call = tts_notify_reboot, + .next = NULL, + .priority = 0, +}; + +static int acpi_sleep_prepare(u32 acpi_state) +{ +#ifdef CONFIG_ACPI_SLEEP + /* do we have a wakeup address for S2 and S3? */ + if (acpi_state == ACPI_STATE_S3) { + if (!acpi_wakeup_address) { + return -EFAULT; + } + acpi_set_firmware_waking_vector( + (acpi_physical_address)acpi_wakeup_address); + + } + ACPI_FLUSH_CPU_CACHE(); + acpi_enable_wakeup_device_prep(acpi_state); +#endif + printk(KERN_INFO PREFIX "Preparing to enter system sleep state S%d\n", + acpi_state); + acpi_enter_sleep_state_prep(acpi_state); + return 0; +} + +#ifdef CONFIG_ACPI_SLEEP +static u32 acpi_target_sleep_state = ACPI_STATE_S0; +/* + * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the + * user to request that behavior by using the 'acpi_old_suspend_ordering' + * kernel command line option that causes the following variable to be set. + */ +static bool old_suspend_ordering; + +void __init acpi_old_suspend_ordering(void) +{ + old_suspend_ordering = true; +} + +/* + * According to the ACPI specification the BIOS should make sure that ACPI is + * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still, + * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI + * on such systems during resume. Unfortunately that doesn't help in + * particularly pathological cases in which SCI_EN has to be set directly on + * resume, although the specification states very clearly that this flag is + * owned by the hardware. The set_sci_en_on_resume variable will be set in such + * cases. + */ +static bool set_sci_en_on_resume; +/* + * The ACPI specification wants us to save NVS memory regions during hibernation + * and to restore them during the subsequent resume. However, it is not certain + * if this mechanism is going to work on all machines, so we allow the user to + * disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line + * option. + */ +static bool s4_no_nvs; + +void __init acpi_s4_no_nvs(void) +{ + s4_no_nvs = true; +} + +/** + * acpi_pm_disable_gpes - Disable the GPEs. + */ +static int acpi_pm_disable_gpes(void) +{ + acpi_disable_all_gpes(); + return 0; +} + +/** + * __acpi_pm_prepare - Prepare the platform to enter the target state. + * + * If necessary, set the firmware waking vector and do arch-specific + * nastiness to get the wakeup code to the waking vector. + */ +static int __acpi_pm_prepare(void) +{ + int error = acpi_sleep_prepare(acpi_target_sleep_state); + + if (error) + acpi_target_sleep_state = ACPI_STATE_S0; + return error; +} + +/** + * acpi_pm_prepare - Prepare the platform to enter the target sleep + * state and disable the GPEs. + */ +static int acpi_pm_prepare(void) +{ + int error = __acpi_pm_prepare(); + + if (!error) + acpi_disable_all_gpes(); + return error; +} + +/** + * acpi_pm_finish - Instruct the platform to leave a sleep state. + * + * This is called after we wake back up (or if entering the sleep state + * failed). + */ +static void acpi_pm_finish(void) +{ + u32 acpi_state = acpi_target_sleep_state; + + if (acpi_state == ACPI_STATE_S0) + return; + + printk(KERN_INFO PREFIX "Waking up from system sleep state S%d\n", + acpi_state); + acpi_disable_wakeup_device(acpi_state); + acpi_leave_sleep_state(acpi_state); + + /* reset firmware waking vector */ + acpi_set_firmware_waking_vector((acpi_physical_address) 0); + + acpi_target_sleep_state = ACPI_STATE_S0; +} + +/** + * acpi_pm_end - Finish up suspend sequence. + */ +static void acpi_pm_end(void) +{ + /* + * This is necessary in case acpi_pm_finish() is not called during a + * failing transition to a sleep state. + */ + acpi_target_sleep_state = ACPI_STATE_S0; + acpi_sleep_tts_switch(acpi_target_sleep_state); +} +#else /* !CONFIG_ACPI_SLEEP */ +#define acpi_target_sleep_state ACPI_STATE_S0 +#endif /* CONFIG_ACPI_SLEEP */ + +#ifdef CONFIG_SUSPEND +extern void do_suspend_lowlevel(void); + +static u32 acpi_suspend_states[] = { + [PM_SUSPEND_ON] = ACPI_STATE_S0, + [PM_SUSPEND_STANDBY] = ACPI_STATE_S1, + [PM_SUSPEND_MEM] = ACPI_STATE_S3, + [PM_SUSPEND_MAX] = ACPI_STATE_S5 +}; + +/** + * acpi_suspend_begin - Set the target system sleep state to the state + * associated with given @pm_state, if supported. + */ +static int acpi_suspend_begin(suspend_state_t pm_state) +{ + u32 acpi_state = acpi_suspend_states[pm_state]; + int error = 0; + + if (sleep_states[acpi_state]) { + acpi_target_sleep_state = acpi_state; + acpi_sleep_tts_switch(acpi_target_sleep_state); + } else { + printk(KERN_ERR "ACPI does not support this state: %d\n", + pm_state); + error = -ENOSYS; + } + return error; +} + +/** + * acpi_suspend_enter - Actually enter a sleep state. + * @pm_state: ignored + * + * Flush caches and go to sleep. For STR we have to call arch-specific + * assembly, which in turn call acpi_enter_sleep_state(). + * It's unfortunate, but it works. Please fix if you're feeling frisky. + */ +static int acpi_suspend_enter(suspend_state_t pm_state) +{ + acpi_status status = AE_OK; + unsigned long flags = 0; + u32 acpi_state = acpi_target_sleep_state; + + ACPI_FLUSH_CPU_CACHE(); + + /* Do arch specific saving of state. */ + if (acpi_state == ACPI_STATE_S3) { + int error = acpi_save_state_mem(); + + if (error) + return error; + } + + local_irq_save(flags); + acpi_enable_wakeup_device(acpi_state); + switch (acpi_state) { + case ACPI_STATE_S1: + barrier(); + status = acpi_enter_sleep_state(acpi_state); + break; + + case ACPI_STATE_S3: + do_suspend_lowlevel(); + break; + } + + /* If ACPI is not enabled by the BIOS, we need to enable it here. */ + if (set_sci_en_on_resume) + acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1); + else + acpi_enable(); + + /* Reprogram control registers and execute _BFS */ + acpi_leave_sleep_state_prep(acpi_state); + + /* ACPI 3.0 specs (P62) says that it's the responsibility + * of the OSPM to clear the status bit [ implying that the + * POWER_BUTTON event should not reach userspace ] + */ + if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3)) + acpi_clear_event(ACPI_EVENT_POWER_BUTTON); + + /* + * Disable and clear GPE status before interrupt is enabled. Some GPEs + * (like wakeup GPE) haven't handler, this can avoid such GPE misfire. + * acpi_leave_sleep_state will reenable specific GPEs later + */ + acpi_disable_all_gpes(); + + local_irq_restore(flags); + printk(KERN_DEBUG "Back to C!\n"); + + /* restore processor state */ + if (acpi_state == ACPI_STATE_S3) + acpi_restore_state_mem(); + + return ACPI_SUCCESS(status) ? 0 : -EFAULT; +} + +static int acpi_suspend_state_valid(suspend_state_t pm_state) +{ + u32 acpi_state; + + switch (pm_state) { + case PM_SUSPEND_ON: + case PM_SUSPEND_STANDBY: + case PM_SUSPEND_MEM: + acpi_state = acpi_suspend_states[pm_state]; + + return sleep_states[acpi_state]; + default: + return 0; + } +} + +static struct platform_suspend_ops acpi_suspend_ops = { + .valid = acpi_suspend_state_valid, + .begin = acpi_suspend_begin, + .prepare = acpi_pm_prepare, + .enter = acpi_suspend_enter, + .finish = acpi_pm_finish, + .end = acpi_pm_end, +}; + +/** + * acpi_suspend_begin_old - Set the target system sleep state to the + * state associated with given @pm_state, if supported, and + * execute the _PTS control method. This function is used if the + * pre-ACPI 2.0 suspend ordering has been requested. + */ +static int acpi_suspend_begin_old(suspend_state_t pm_state) +{ + int error = acpi_suspend_begin(pm_state); + + if (!error) + error = __acpi_pm_prepare(); + return error; +} + +/* + * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has + * been requested. + */ +static struct platform_suspend_ops acpi_suspend_ops_old = { + .valid = acpi_suspend_state_valid, + .begin = acpi_suspend_begin_old, + .prepare = acpi_pm_disable_gpes, + .enter = acpi_suspend_enter, + .finish = acpi_pm_finish, + .end = acpi_pm_end, + .recover = acpi_pm_finish, +}; + +static int __init init_old_suspend_ordering(const struct dmi_system_id *d) +{ + old_suspend_ordering = true; + return 0; +} + +static int __init init_set_sci_en_on_resume(const struct dmi_system_id *d) +{ + set_sci_en_on_resume = true; + return 0; +} + +static struct dmi_system_id __initdata acpisleep_dmi_table[] = { + { + .callback = init_old_suspend_ordering, + .ident = "Abit KN9 (nForce4 variant)", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "http://www.abit.com.tw/"), + DMI_MATCH(DMI_BOARD_NAME, "KN9 Series(NF-CK804)"), + }, + }, + { + .callback = init_old_suspend_ordering, + .ident = "HP xw4600 Workstation", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"), + }, + }, + { + .callback = init_set_sci_en_on_resume, + .ident = "Apple MacBook 1,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"), + }, + }, + { + .callback = init_set_sci_en_on_resume, + .ident = "Apple MacMini 1,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"), + }, + }, + {}, +}; +#endif /* CONFIG_SUSPEND */ + +#ifdef CONFIG_HIBERNATION +static unsigned long s4_hardware_signature; +static struct acpi_table_facs *facs; +static bool nosigcheck; + +void __init acpi_no_s4_hw_signature(void) +{ + nosigcheck = true; +} + +static int acpi_hibernation_begin(void) +{ + int error; + + error = s4_no_nvs ? 0 : hibernate_nvs_alloc(); + if (!error) { + acpi_target_sleep_state = ACPI_STATE_S4; + acpi_sleep_tts_switch(acpi_target_sleep_state); + } + + return error; +} + +static int acpi_hibernation_pre_snapshot(void) +{ + int error = acpi_pm_prepare(); + + if (!error) + hibernate_nvs_save(); + + return error; +} + +static int acpi_hibernation_enter(void) +{ + acpi_status status = AE_OK; + unsigned long flags = 0; + + ACPI_FLUSH_CPU_CACHE(); + + local_irq_save(flags); + acpi_enable_wakeup_device(ACPI_STATE_S4); + /* This shouldn't return. If it returns, we have a problem */ + status = acpi_enter_sleep_state(ACPI_STATE_S4); + /* Reprogram control registers and execute _BFS */ + acpi_leave_sleep_state_prep(ACPI_STATE_S4); + local_irq_restore(flags); + + return ACPI_SUCCESS(status) ? 0 : -EFAULT; +} + +static void acpi_hibernation_finish(void) +{ + hibernate_nvs_free(); + acpi_pm_finish(); +} + +static void acpi_hibernation_leave(void) +{ + /* + * If ACPI is not enabled by the BIOS and the boot kernel, we need to + * enable it here. + */ + acpi_enable(); + /* Reprogram control registers and execute _BFS */ + acpi_leave_sleep_state_prep(ACPI_STATE_S4); + /* Check the hardware signature */ + if (facs && s4_hardware_signature != facs->hardware_signature) { + printk(KERN_EMERG "ACPI: Hardware changed while hibernated, " + "cannot resume!\n"); + panic("ACPI S4 hardware signature mismatch"); + } + /* Restore the NVS memory area */ + hibernate_nvs_restore(); +} + +static void acpi_pm_enable_gpes(void) +{ + acpi_enable_all_runtime_gpes(); +} + +static struct platform_hibernation_ops acpi_hibernation_ops = { + .begin = acpi_hibernation_begin, + .end = acpi_pm_end, + .pre_snapshot = acpi_hibernation_pre_snapshot, + .finish = acpi_hibernation_finish, + .prepare = acpi_pm_prepare, + .enter = acpi_hibernation_enter, + .leave = acpi_hibernation_leave, + .pre_restore = acpi_pm_disable_gpes, + .restore_cleanup = acpi_pm_enable_gpes, +}; + +/** + * acpi_hibernation_begin_old - Set the target system sleep state to + * ACPI_STATE_S4 and execute the _PTS control method. This + * function is used if the pre-ACPI 2.0 suspend ordering has been + * requested. + */ +static int acpi_hibernation_begin_old(void) +{ + int error; + /* + * The _TTS object should always be evaluated before the _PTS object. + * When the old_suspended_ordering is true, the _PTS object is + * evaluated in the acpi_sleep_prepare. + */ + acpi_sleep_tts_switch(ACPI_STATE_S4); + + error = acpi_sleep_prepare(ACPI_STATE_S4); + + if (!error) { + if (!s4_no_nvs) + error = hibernate_nvs_alloc(); + if (!error) + acpi_target_sleep_state = ACPI_STATE_S4; + } + return error; +} + +static int acpi_hibernation_pre_snapshot_old(void) +{ + int error = acpi_pm_disable_gpes(); + + if (!error) + hibernate_nvs_save(); + + return error; +} + +/* + * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has + * been requested. + */ +static struct platform_hibernation_ops acpi_hibernation_ops_old = { + .begin = acpi_hibernation_begin_old, + .end = acpi_pm_end, + .pre_snapshot = acpi_hibernation_pre_snapshot_old, + .finish = acpi_hibernation_finish, + .prepare = acpi_pm_disable_gpes, + .enter = acpi_hibernation_enter, + .leave = acpi_hibernation_leave, + .pre_restore = acpi_pm_disable_gpes, + .restore_cleanup = acpi_pm_enable_gpes, + .recover = acpi_pm_finish, +}; +#endif /* CONFIG_HIBERNATION */ + +int acpi_suspend(u32 acpi_state) +{ + suspend_state_t states[] = { + [1] = PM_SUSPEND_STANDBY, + [3] = PM_SUSPEND_MEM, + [5] = PM_SUSPEND_MAX + }; + + if (acpi_state < 6 && states[acpi_state]) + return pm_suspend(states[acpi_state]); + if (acpi_state == 4) + return hibernate(); + return -EINVAL; +} + +#ifdef CONFIG_PM_SLEEP +/** + * acpi_pm_device_sleep_state - return preferred power state of ACPI device + * in the system sleep state given by %acpi_target_sleep_state + * @dev: device to examine; its driver model wakeup flags control + * whether it should be able to wake up the system + * @d_min_p: used to store the upper limit of allowed states range + * Return value: preferred power state of the device on success, -ENODEV on + * failure (ie. if there's no 'struct acpi_device' for @dev) + * + * Find the lowest power (highest number) ACPI device power state that + * device @dev can be in while the system is in the sleep state represented + * by %acpi_target_sleep_state. If @wake is nonzero, the device should be + * able to wake up the system from this sleep state. If @d_min_p is set, + * the highest power (lowest number) device power state of @dev allowed + * in this system sleep state is stored at the location pointed to by it. + * + * The caller must ensure that @dev is valid before using this function. + * The caller is also responsible for figuring out if the device is + * supposed to be able to wake up the system and passing this information + * via @wake. + */ + +int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p) +{ + acpi_handle handle = DEVICE_ACPI_HANDLE(dev); + struct acpi_device *adev; + char acpi_method[] = "_SxD"; + unsigned long long d_min, d_max; + + if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { + printk(KERN_DEBUG "ACPI handle has no context!\n"); + return -ENODEV; + } + + acpi_method[2] = '0' + acpi_target_sleep_state; + /* + * If the sleep state is S0, we will return D3, but if the device has + * _S0W, we will use the value from _S0W + */ + d_min = ACPI_STATE_D0; + d_max = ACPI_STATE_D3; + + /* + * If present, _SxD methods return the minimum D-state (highest power + * state) we can use for the corresponding S-states. Otherwise, the + * minimum D-state is D0 (ACPI 3.x). + * + * NOTE: We rely on acpi_evaluate_integer() not clobbering the integer + * provided -- that's our fault recovery, we ignore retval. + */ + if (acpi_target_sleep_state > ACPI_STATE_S0) + acpi_evaluate_integer(handle, acpi_method, NULL, &d_min); + + /* + * If _PRW says we can wake up the system from the target sleep state, + * the D-state returned by _SxD is sufficient for that (we assume a + * wakeup-aware driver if wake is set). Still, if _SxW exists + * (ACPI 3.x), it should return the maximum (lowest power) D-state that + * can wake the system. _S0W may be valid, too. + */ + if (acpi_target_sleep_state == ACPI_STATE_S0 || + (device_may_wakeup(dev) && adev->wakeup.state.enabled && + adev->wakeup.sleep_state <= acpi_target_sleep_state)) { + acpi_status status; + + acpi_method[3] = 'W'; + status = acpi_evaluate_integer(handle, acpi_method, NULL, + &d_max); + if (ACPI_FAILURE(status)) { + d_max = d_min; + } else if (d_max < d_min) { + /* Warn the user of the broken DSDT */ + printk(KERN_WARNING "ACPI: Wrong value from %s\n", + acpi_method); + /* Sanitize it */ + d_min = d_max; + } + } + + if (d_min_p) + *d_min_p = d_min; + return d_max; +} + +/** + * acpi_pm_device_sleep_wake - enable or disable the system wake-up + * capability of given device + * @dev: device to handle + * @enable: 'true' - enable, 'false' - disable the wake-up capability + */ +int acpi_pm_device_sleep_wake(struct device *dev, bool enable) +{ + acpi_handle handle; + struct acpi_device *adev; + + if (!device_may_wakeup(dev)) + return -EINVAL; + + handle = DEVICE_ACPI_HANDLE(dev); + if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { + printk(KERN_DEBUG "ACPI handle has no context!\n"); + return -ENODEV; + } + + return enable ? + acpi_enable_wakeup_device_power(adev, acpi_target_sleep_state) : + acpi_disable_wakeup_device_power(adev); +} +#endif + +static void acpi_power_off_prepare(void) +{ + /* Prepare to power off the system */ + acpi_sleep_prepare(ACPI_STATE_S5); + acpi_disable_all_gpes(); +} + +static void acpi_power_off(void) +{ + /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ + printk("%s called\n", __func__); + local_irq_disable(); + acpi_enable_wakeup_device(ACPI_STATE_S5); + acpi_enter_sleep_state(ACPI_STATE_S5); +} + +int __init acpi_sleep_init(void) +{ + acpi_status status; + u8 type_a, type_b; +#ifdef CONFIG_SUSPEND + int i = 0; + + dmi_check_system(acpisleep_dmi_table); +#endif + + if (acpi_disabled) + return 0; + + sleep_states[ACPI_STATE_S0] = 1; + printk(KERN_INFO PREFIX "(supports S0"); + +#ifdef CONFIG_SUSPEND + for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++) { + status = acpi_get_sleep_type_data(i, &type_a, &type_b); + if (ACPI_SUCCESS(status)) { + sleep_states[i] = 1; + printk(" S%d", i); + } + } + + suspend_set_ops(old_suspend_ordering ? + &acpi_suspend_ops_old : &acpi_suspend_ops); +#endif + +#ifdef CONFIG_HIBERNATION + status = acpi_get_sleep_type_data(ACPI_STATE_S4, &type_a, &type_b); + if (ACPI_SUCCESS(status)) { + hibernation_set_ops(old_suspend_ordering ? + &acpi_hibernation_ops_old : &acpi_hibernation_ops); + sleep_states[ACPI_STATE_S4] = 1; + printk(" S4"); + if (!nosigcheck) { + acpi_get_table(ACPI_SIG_FACS, 1, + (struct acpi_table_header **)&facs); + if (facs) + s4_hardware_signature = + facs->hardware_signature; + } + } +#endif + status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b); + if (ACPI_SUCCESS(status)) { + sleep_states[ACPI_STATE_S5] = 1; + printk(" S5"); + pm_power_off_prepare = acpi_power_off_prepare; + pm_power_off = acpi_power_off; + } + printk(")\n"); + /* + * Register the tts_notifier to reboot notifier list so that the _TTS + * object can also be evaluated when the system enters S5. + */ + register_reboot_notifier(&tts_notifier); + return 0; +} -- cgit From d45e0855488032ea62ec5638fb1dcd47367f8ddb Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Thu, 15 Jan 2009 15:12:27 -0500 Subject: ACPI PCI hotplug: harden against panic regression ACPI hotplug panic with current git head http://lkml.org/lkml/2009/1/10/136 Rather than reverting the entire commit that causes the crash: e8c331e963c58b83db24b7d0e39e8c07f687dbc6 "PCI hotplug: introduce functions for ACPI slot detection" simply harden against it while the changes to the hotplug code on this particularl machine are understood. Signed-off-by: James Bottomley Acked-by: Jesse Barnes Signed-off-by: Len Brown --- drivers/pci/hotplug/acpiphp_glue.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index f09b1010d47..803d9ddd6e7 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -266,6 +266,8 @@ static int detect_ejectable_slots(struct pci_bus *pbus) int found = acpi_pci_detect_ejectable(pbus); if (!found) { acpi_handle bridge_handle = acpi_pci_get_bridge_handle(pbus); + if (!bridge_handle) + return 0; acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle, (u32)1, is_pci_dock_device, (void *)&found, NULL); } -- cgit From 0db29af1e767464d71b89410d61a1e5b668d0370 Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Wed, 24 Dec 2008 17:27:04 +0900 Subject: PCI/MSI: bugfix/utilize for msi_capability_init() This patch fix a following bug and does a cleanup. bug: commit 5993760f7fc75b77e4701f1e56dc84c0d6cf18d5 had a wrong change (since is_64 is boolean[0|1]): - pci_write_config_dword(dev, - msi_mask_bits_reg(pos, is_64bit_address(control)), - maskbits); + pci_write_config_dword(dev, entry->msi_attrib.is_64, maskbits); utilize: Unify separated if (entry->msi_attrib.maskbit) statements. Signed-off-by: Hidetoshi Seto Acked-by: "Jike Song" Cc: stable@vger.kernel.org Signed-off-by: Jesse Barnes --- drivers/pci/msi.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index b4a90badd0a..896a15d70f5 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -398,21 +398,19 @@ static int msi_capability_init(struct pci_dev *dev) entry->msi_attrib.masked = 1; entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ entry->msi_attrib.pos = pos; - if (entry->msi_attrib.maskbit) { - entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos, - entry->msi_attrib.is_64); - } entry->dev = dev; if (entry->msi_attrib.maskbit) { - unsigned int maskbits, temp; + unsigned int base, maskbits, temp; + + base = msi_mask_bits_reg(pos, entry->msi_attrib.is_64); + entry->mask_base = (void __iomem *)(long)base; + /* All MSIs are unmasked by default, Mask them all */ - pci_read_config_dword(dev, - msi_mask_bits_reg(pos, entry->msi_attrib.is_64), - &maskbits); + pci_read_config_dword(dev, base, &maskbits); temp = (1 << multi_msi_capable(control)); temp = ((temp - 1) & ~temp); maskbits |= temp; - pci_write_config_dword(dev, entry->msi_attrib.is_64, maskbits); + pci_write_config_dword(dev, base, maskbits); entry->msi_attrib.maskbits_mask = temp; } list_add_tail(&entry->list, &dev->msi_list); -- cgit From 1de9e8e70f5acc441550ca75433563d91b269bbe Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 16 Jan 2009 12:43:00 -0800 Subject: Linux 2.6.29-rc2 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c06e250eca1..207303da397 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 29 -EXTRAVERSION = -rc1 +EXTRAVERSION = -rc2 NAME = Erotic Pickled Herring # *DOCUMENTATION* -- cgit From 0fd7e1d8559f45a6838cee93ea49adc0c5bda8f0 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 16 Jan 2009 12:47:47 -0800 Subject: IB/mlx4: Fix memory ordering problem when posting LSO sends The current work request posting code writes the LSO segment before writing any data segments. This leaves a window where the LSO segment overwrites the stamping in one cacheline that the HCA prefetches before the rest of the cacheline is filled with the correct data segments. When the HCA processes this work request, a local protection error may result. Fix this by saving the LSO header size field off and writing it only after all data segments are written. This fix is a cleaned-up version of a patch from Jack Morgenstein . This fixes . Reported-by: Jack Morgenstein Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mlx4/qp.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 39167a797f9..a91cb4c3fa5 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -1462,7 +1462,8 @@ static void __set_data_seg(struct mlx4_wqe_data_seg *dseg, struct ib_sge *sg) } static int build_lso_seg(struct mlx4_wqe_lso_seg *wqe, struct ib_send_wr *wr, - struct mlx4_ib_qp *qp, unsigned *lso_seg_len) + struct mlx4_ib_qp *qp, unsigned *lso_seg_len, + __be32 *lso_hdr_sz) { unsigned halign = ALIGN(sizeof *wqe + wr->wr.ud.hlen, 16); @@ -1479,12 +1480,8 @@ static int build_lso_seg(struct mlx4_wqe_lso_seg *wqe, struct ib_send_wr *wr, memcpy(wqe->header, wr->wr.ud.header, wr->wr.ud.hlen); - /* make sure LSO header is written before overwriting stamping */ - wmb(); - - wqe->mss_hdr_size = cpu_to_be32((wr->wr.ud.mss - wr->wr.ud.hlen) << 16 | - wr->wr.ud.hlen); - + *lso_hdr_sz = cpu_to_be32((wr->wr.ud.mss - wr->wr.ud.hlen) << 16 | + wr->wr.ud.hlen); *lso_seg_len = halign; return 0; } @@ -1518,6 +1515,9 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, int uninitialized_var(stamp); int uninitialized_var(size); unsigned uninitialized_var(seglen); + __be32 dummy; + __be32 *lso_wqe; + __be32 uninitialized_var(lso_hdr_sz); int i; spin_lock_irqsave(&qp->sq.lock, flags); @@ -1525,6 +1525,8 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, ind = qp->sq_next_wqe; for (nreq = 0; wr; ++nreq, wr = wr->next) { + lso_wqe = &dummy; + if (mlx4_wq_overflow(&qp->sq, nreq, qp->ibqp.send_cq)) { err = -ENOMEM; *bad_wr = wr; @@ -1606,11 +1608,12 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, size += sizeof (struct mlx4_wqe_datagram_seg) / 16; if (wr->opcode == IB_WR_LSO) { - err = build_lso_seg(wqe, wr, qp, &seglen); + err = build_lso_seg(wqe, wr, qp, &seglen, &lso_hdr_sz); if (unlikely(err)) { *bad_wr = wr; goto out; } + lso_wqe = (__be32 *) wqe; wqe += seglen; size += seglen / 16; } @@ -1652,6 +1655,14 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, for (i = wr->num_sge - 1; i >= 0; --i, --dseg) set_data_seg(dseg, wr->sg_list + i); + /* + * Possibly overwrite stamping in cacheline with LSO + * segment only after making sure all data segments + * are written. + */ + wmb(); + *lso_wqe = lso_hdr_sz; + ctrl->fence_size = (wr->send_flags & IB_SEND_FENCE ? MLX4_WQE_CTRL_FENCE : 0) | size; @@ -1686,7 +1697,6 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, stamp_send_wqe(qp, stamp, size * 16); ind = pad_wraparound(qp, ind); } - } out: -- cgit From aa8c6c93747f7b55fa11e1624fec8ca33763a805 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 16 Jan 2009 21:54:43 +0100 Subject: PCI PM: Restore standard config registers of all devices early There is a problem in our handling of suspend-resume of PCI devices that many of them have their standard config registers restored with interrupts enabled and they are put into the full power state with interrupts enabled as well. This may lead to the following scenario: * an interrupt vector is shared between two or more devices * one device is resumed earlier and generates an interrupt * the interrupt handler of another device tries to handle it and attempts to access the device the config space of which hasn't been restored yet and/or which still is in a low power state * the system crashes as a result To prevent this from happening we should restore the standard configuration registers of all devices with interrupts disabled and we should put them into the D0 power state right after that. Unfortunately, this cannot be done using the existing pci_set_power_state(), because it can sleep. Also, to do it we have to make sure that the config spaces of all devices were actually saved during suspend. Signed-off-by: Rafael J. Wysocki Acked-by: Linus Torvalds Signed-off-by: Jesse Barnes --- drivers/pci/pci-driver.c | 91 ++++++++++++++---------------------------------- drivers/pci/pci.c | 63 +++++++++++++++++++++++++++++---- drivers/pci/pci.h | 6 ++++ include/linux/pci.h | 5 +++ 4 files changed, 95 insertions(+), 70 deletions(-) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index c697f268085..9de07b75b99 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -355,17 +355,27 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state) int i = 0; if (drv && drv->suspend) { + pci_dev->state_saved = false; + i = drv->suspend(pci_dev, state); suspend_report_result(drv->suspend, i); - } else { - pci_save_state(pci_dev); - /* - * This is for compatibility with existing code with legacy PM - * support. - */ - pci_pm_set_unknown_state(pci_dev); + if (i) + return i; + + if (pci_dev->state_saved) + goto Fixup; + + if (WARN_ON_ONCE(pci_dev->current_state != PCI_D0)) + goto Fixup; } + pci_save_state(pci_dev); + /* + * This is for compatibility with existing code with legacy PM support. + */ + pci_pm_set_unknown_state(pci_dev); + + Fixup: pci_fixup_device(pci_fixup_suspend, pci_dev); return i; @@ -386,81 +396,34 @@ static int pci_legacy_suspend_late(struct device *dev, pm_message_t state) static int pci_legacy_resume_early(struct device *dev) { - int error = 0; struct pci_dev * pci_dev = to_pci_dev(dev); struct pci_driver * drv = pci_dev->driver; - pci_fixup_device(pci_fixup_resume_early, pci_dev); - - if (drv && drv->resume_early) - error = drv->resume_early(pci_dev); - return error; + return drv && drv->resume_early ? + drv->resume_early(pci_dev) : 0; } static int pci_legacy_resume(struct device *dev) { - int error; struct pci_dev * pci_dev = to_pci_dev(dev); struct pci_driver * drv = pci_dev->driver; pci_fixup_device(pci_fixup_resume, pci_dev); - if (drv && drv->resume) { - error = drv->resume(pci_dev); - } else { - /* restore the PCI config space */ - pci_restore_state(pci_dev); - error = pci_pm_reenable_device(pci_dev); - } - return error; + return drv && drv->resume ? + drv->resume(pci_dev) : pci_pm_reenable_device(pci_dev); } /* Auxiliary functions used by the new power management framework */ -static int pci_restore_standard_config(struct pci_dev *pci_dev) -{ - struct pci_dev *parent = pci_dev->bus->self; - int error = 0; - - /* Check if the device's bus is operational */ - if (!parent || parent->current_state == PCI_D0) { - pci_restore_state(pci_dev); - pci_update_current_state(pci_dev, PCI_D0); - } else { - dev_warn(&pci_dev->dev, "unable to restore config, " - "bridge %s in low power state D%d\n", pci_name(parent), - parent->current_state); - pci_dev->current_state = PCI_UNKNOWN; - error = -EAGAIN; - } - - return error; -} - -static bool pci_is_bridge(struct pci_dev *pci_dev) -{ - return !!(pci_dev->subordinate); -} - static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev) { - if (pci_restore_standard_config(pci_dev)) - pci_fixup_device(pci_fixup_resume_early, pci_dev); + pci_restore_standard_config(pci_dev); + pci_fixup_device(pci_fixup_resume_early, pci_dev); } static int pci_pm_default_resume(struct pci_dev *pci_dev) { - /* - * pci_restore_standard_config() should have been called once already, - * but it would have failed if the device's parent bridge had not been - * in power state D0 at that time. Check it and try again if necessary. - */ - if (pci_dev->current_state == PCI_UNKNOWN) { - int error = pci_restore_standard_config(pci_dev); - if (error) - return error; - } - pci_fixup_device(pci_fixup_resume, pci_dev); if (!pci_is_bridge(pci_dev)) @@ -575,11 +538,11 @@ static int pci_pm_resume_noirq(struct device *dev) struct device_driver *drv = dev->driver; int error = 0; + pci_pm_default_resume_noirq(pci_dev); + if (pci_has_legacy_pm_support(pci_dev)) return pci_legacy_resume_early(dev); - pci_pm_default_resume_noirq(pci_dev); - if (drv && drv->pm && drv->pm->resume_noirq) error = drv->pm->resume_noirq(dev); @@ -730,11 +693,11 @@ static int pci_pm_restore_noirq(struct device *dev) struct device_driver *drv = dev->driver; int error = 0; + pci_pm_default_resume_noirq(pci_dev); + if (pci_has_legacy_pm_support(pci_dev)) return pci_legacy_resume_early(dev); - pci_pm_default_resume_noirq(pci_dev); - if (drv && drv->pm && drv->pm->restore_noirq) error = drv->pm->restore_noirq(dev); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e491fdedf70..17bd9325a24 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -22,7 +22,7 @@ #include /* isa_dma_bridge_buggy */ #include "pci.h" -unsigned int pci_pm_d3_delay = 10; +unsigned int pci_pm_d3_delay = PCI_PM_D3_WAIT; #ifdef CONFIG_PCI_DOMAINS int pci_domains_supported = 1; @@ -426,6 +426,7 @@ static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable) * given PCI device * @dev: PCI device to handle. * @state: PCI power state (D0, D1, D2, D3hot) to put the device into. + * @wait: If 'true', wait for the device to change its power state * * RETURN VALUE: * -EINVAL if the requested state is invalid. @@ -435,7 +436,7 @@ static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable) * 0 if device's power state has been successfully changed. */ static int -pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) +pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state, bool wait) { u16 pmcsr; bool need_restore = false; @@ -480,8 +481,10 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) break; case PCI_UNKNOWN: /* Boot-up */ if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot - && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) + && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) { need_restore = true; + wait = true; + } /* Fall-through: force to D0 */ default: pmcsr = 0; @@ -491,12 +494,15 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) /* enter specified state */ pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr); + if (!wait) + return 0; + /* Mandatory power management transition delays */ /* see PCI PM 1.1 5.6.1 table 18 */ if (state == PCI_D3hot || dev->current_state == PCI_D3hot) msleep(pci_pm_d3_delay); else if (state == PCI_D2 || dev->current_state == PCI_D2) - udelay(200); + udelay(PCI_PM_D2_DELAY); dev->current_state = state; @@ -515,7 +521,7 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) if (need_restore) pci_restore_bars(dev); - if (dev->bus->self) + if (wait && dev->bus->self) pcie_aspm_pm_state_change(dev->bus->self); return 0; @@ -585,7 +591,7 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) if (state == PCI_D3hot && (dev->dev_flags & PCI_DEV_FLAGS_NO_D3)) return 0; - error = pci_raw_set_power_state(dev, state); + error = pci_raw_set_power_state(dev, state, true); if (state > PCI_D0 && platform_pci_power_manageable(dev)) { /* Allow the platform to finalize the transition */ @@ -730,6 +736,7 @@ pci_save_state(struct pci_dev *dev) /* XXX: 100% dword access ok here? */ for (i = 0; i < 16; i++) pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]); + dev->state_saved = true; if ((i = pci_save_pcie_state(dev)) != 0) return i; if ((i = pci_save_pcix_state(dev)) != 0) @@ -1373,6 +1380,50 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev) "unable to preallocate PCI-X save buffer\n"); } +/** + * pci_restore_standard_config - restore standard config registers of PCI device + * @dev: PCI device to handle + * + * This function assumes that the device's configuration space is accessible. + * If the device needs to be powered up, the function will wait for it to + * change the state. + */ +int pci_restore_standard_config(struct pci_dev *dev) +{ + pci_power_t prev_state; + int error; + + pci_restore_state(dev); + pci_update_current_state(dev, PCI_D0); + + prev_state = dev->current_state; + if (prev_state == PCI_D0) + return 0; + + error = pci_raw_set_power_state(dev, PCI_D0, false); + if (error) + return error; + + if (pci_is_bridge(dev)) { + if (prev_state > PCI_D1) + mdelay(PCI_PM_BUS_WAIT); + } else { + switch(prev_state) { + case PCI_D3cold: + case PCI_D3hot: + mdelay(pci_pm_d3_delay); + break; + case PCI_D2: + udelay(PCI_PM_D2_DELAY); + break; + } + } + + dev->current_state = PCI_D0; + + return 0; +} + /** * pci_enable_ari - enable ARI forwarding if hardware support it * @dev: the PCI device diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 1351bb4addd..26ddf78ac30 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -49,6 +49,12 @@ extern void pci_disable_enabled_device(struct pci_dev *dev); extern void pci_pm_init(struct pci_dev *dev); extern void platform_pci_wakeup_init(struct pci_dev *dev); extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); +extern int pci_restore_standard_config(struct pci_dev *dev); + +static inline bool pci_is_bridge(struct pci_dev *pci_dev) +{ + return !!(pci_dev->subordinate); +} extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val); extern int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val); diff --git a/include/linux/pci.h b/include/linux/pci.h index 80f8b8b65fd..48890cf3f96 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -117,6 +117,10 @@ typedef int __bitwise pci_power_t; #define PCI_UNKNOWN ((pci_power_t __force) 5) #define PCI_POWER_ERROR ((pci_power_t __force) -1) +#define PCI_PM_D2_DELAY 200 +#define PCI_PM_D3_WAIT 10 +#define PCI_PM_BUS_WAIT 50 + /** The pci_channel state describes connectivity between the CPU and * the pci device. If some PCI bus between here and the pci device * has crashed or locked up, this info is reflected here. @@ -252,6 +256,7 @@ struct pci_dev { unsigned int ari_enabled:1; /* ARI forwarding */ unsigned int is_managed:1; unsigned int is_pcie:1; + unsigned int state_saved:1; pci_dev_flags_t dev_flags; atomic_t enable_cnt; /* pci_enable_device has been called */ -- cgit From 3c20962086b0ceb5498ba840e5a91bf4a692aae9 Mon Sep 17 00:00:00 2001 From: Yossi Etigin Date: Fri, 16 Jan 2009 13:42:59 -0800 Subject: IPoIB: Do not print error messages for multicast join retries When IPoIB tries to join a multicast group, and the SA module's SM address handle is NULL (because of an SM change, etc), the join returns with -EAGAIN status. In that case, don't print an error message unless multicast debugging is enabled. Signed-off-by: Yossi Etigin Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 59d02e0b8df..425e31112ed 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -409,7 +409,7 @@ static int ipoib_mcast_join_complete(int status, } if (mcast->logcount++ < 20) { - if (status == -ETIMEDOUT) { + if (status == -ETIMEDOUT || status == -EAGAIN) { ipoib_dbg_mcast(priv, "multicast join failed for %pI6, status %d\n", mcast->mcmember.mgid.raw, status); } else { -- cgit From ef15aa490f2e447ce04fe643500b814ef40f6ea9 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 9 Jan 2009 21:06:30 +0100 Subject: p54: fix oops caused by bad eeproms This patch fixes a bug that could occur, if it the eeprom is incomplete or partly corrupted. BUG: unable to handle kernel NULL pointer dereference at 00000008 IP: p54_assign_address+0x108/0x15d [p54common] Oops: 0002 [#1] SMP Pid: 12988, comm: phy1 Tainted: P W 2.6.28-rc6-wl #3 RIP: 0010: p54_assign_address+0x108/0x15d [p54common] [...] Call Trace: p54_alloc_skb+0xa3/0xc0 [p54common] p54_scan+0x37/0x204 [p54common] [...] Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index c6a370fa9bc..3b44e8e7603 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -1610,7 +1610,7 @@ static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell) err: printk(KERN_ERR "%s: frequency change failed\n", wiphy_name(dev->wiphy)); - kfree_skb(skb); + p54_free_skb(dev, skb); return -EINVAL; } -- cgit From b6b50a21625bbf59a89b807dd0fc1eb5412aeff3 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 9 Jan 2009 15:25:09 -0800 Subject: mac80211: more kernel-doc fixes Fix (delete) more mac80211 kernel-doc: Warning(linux-2.6.28-git13//include/net/mac80211.h:375): Excess struct/union/enum/typedef member 'retry_count' description in 'ieee80211_tx_info' Warning(linux-2.6.28-git13//net/mac80211/sta_info.h:308): Excess struct/union/enum/typedef member 'last_txrate' description in 'sta_info' Signed-off-by: Randy Dunlap Signed-off-by: John W. Linville --- include/net/mac80211.h | 1 - net/mac80211/sta_info.h | 1 - 2 files changed, 2 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index b3bd00a9d99..559422fc094 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -322,7 +322,6 @@ struct ieee80211_tx_rate { * @control: union for control data * @status: union for status data * @driver_data: array of driver_data pointers - * @retry_count: number of retries * @ampdu_ack_len: number of aggregated frames. * relevant only if IEEE80211_TX_STATUS_AMPDU was set. * @ampdu_ack_map: block ack bit map for the aggregation. diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index dc2606d0ae7..e49a5b99cf1 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -195,7 +195,6 @@ struct sta_ampdu_mlme { * @tx_packets: number of RX/TX MSDUs * @tx_bytes: number of bytes transmitted to this STA * @tx_fragments: number of transmitted MPDUs - * @last_txrate: description of the last used transmit rate * @tid_seq: per-TID sequence numbers for sending to this STA * @ampdu_mlme: A-MPDU state machine state * @timer_to_tid: identity mapping to ID timers -- cgit From d71038c05970ad0c9d7da6f797803f69e4f91837 Mon Sep 17 00:00:00 2001 From: Andrey Yurovsky Date: Mon, 12 Jan 2009 13:14:27 -0800 Subject: libertas: Fix alignment issues in libertas core Data structures that come over the wire from the WLAN firmware must be packed. This fixes alignment problems on the blackfin architecture and, reportedly, on the AVR32. This is a replacement for the previous version of this patch which had also explicitly used get_unaligned_ macros. As Johannes Berg pointed out, these macros were unnecessary. Signed-off-by: Andrey Yurovsky Signed-off-by: Colin McCabe Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/hostcmd.h | 91 ++++++++++++++++----------------- 1 file changed, 45 insertions(+), 46 deletions(-) diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h index e173b1b46c2..f6a79a653b7 100644 --- a/drivers/net/wireless/libertas/hostcmd.h +++ b/drivers/net/wireless/libertas/hostcmd.h @@ -32,7 +32,7 @@ struct txpd { u8 pktdelay_2ms; /* reserved */ u8 reserved1; -}; +} __attribute__ ((packed)); /* RxPD Descriptor */ struct rxpd { @@ -63,7 +63,7 @@ struct rxpd { /* Pkt Priority */ u8 priority; u8 reserved[3]; -}; +} __attribute__ ((packed)); struct cmd_header { __le16 command; @@ -97,7 +97,7 @@ struct enc_key { struct lbs_offset_value { u32 offset; u32 value; -}; +} __attribute__ ((packed)); /* Define general data structure */ /* cmd_DS_GEN */ @@ -107,7 +107,7 @@ struct cmd_ds_gen { __le16 seqnum; __le16 result; void *cmdresp[0]; -}; +} __attribute__ ((packed)); #define S_DS_GEN sizeof(struct cmd_ds_gen) @@ -163,7 +163,7 @@ struct cmd_ds_802_11_subscribe_event { * bump this up a bit. */ uint8_t tlv[128]; -}; +} __attribute__ ((packed)); /* * This scan handle Country Information IE(802.11d compliant) @@ -180,7 +180,7 @@ struct cmd_ds_802_11_scan { mrvlietypes_chanlistparamset_t ChanListParamSet; mrvlietypes_ratesparamset_t OpRateSet; #endif -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_scan_rsp { struct cmd_header hdr; @@ -188,7 +188,7 @@ struct cmd_ds_802_11_scan_rsp { __le16 bssdescriptsize; uint8_t nr_sets; uint8_t bssdesc_and_tlvbuffer[0]; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_get_log { struct cmd_header hdr; @@ -206,33 +206,33 @@ struct cmd_ds_802_11_get_log { __le32 fcserror; __le32 txframe; __le32 wepundecryptable; -}; +} __attribute__ ((packed)); struct cmd_ds_mac_control { struct cmd_header hdr; __le16 action; u16 reserved; -}; +} __attribute__ ((packed)); struct cmd_ds_mac_multicast_adr { struct cmd_header hdr; __le16 action; __le16 nr_of_adrs; u8 maclist[ETH_ALEN * MRVDRV_MAX_MULTICAST_LIST_SIZE]; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_authenticate { u8 macaddr[ETH_ALEN]; u8 authtype; u8 reserved[10]; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_deauthenticate { struct cmd_header hdr; u8 macaddr[ETH_ALEN]; __le16 reasoncode; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_associate { u8 peerstaaddr[6]; @@ -251,7 +251,7 @@ struct cmd_ds_802_11_associate { struct cmd_ds_802_11_associate_rsp { struct ieeetypes_assocrsp assocRsp; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_set_wep { struct cmd_header hdr; @@ -265,7 +265,7 @@ struct cmd_ds_802_11_set_wep { /* 40, 128bit or TXWEP */ uint8_t keytype[4]; uint8_t keymaterial[4][16]; -}; +} __attribute__ ((packed)); struct cmd_ds_802_3_get_stat { __le32 xmitok; @@ -274,7 +274,7 @@ struct cmd_ds_802_3_get_stat { __le32 rcverror; __le32 rcvnobuffer; __le32 rcvcrcerror; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_get_stat { __le32 txfragmentcnt; @@ -294,7 +294,7 @@ struct cmd_ds_802_11_get_stat { __le32 txbeacon; __le32 rxbeacon; __le32 wepundecryptable; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_snmp_mib { struct cmd_header hdr; @@ -303,58 +303,58 @@ struct cmd_ds_802_11_snmp_mib { __le16 oid; __le16 bufsize; u8 value[128]; -}; +} __attribute__ ((packed)); struct cmd_ds_mac_reg_map { __le16 buffersize; u8 regmap[128]; __le16 reserved; -}; +} __attribute__ ((packed)); struct cmd_ds_bbp_reg_map { __le16 buffersize; u8 regmap[128]; __le16 reserved; -}; +} __attribute__ ((packed)); struct cmd_ds_rf_reg_map { __le16 buffersize; u8 regmap[64]; __le16 reserved; -}; +} __attribute__ ((packed)); struct cmd_ds_mac_reg_access { __le16 action; __le16 offset; __le32 value; -}; +} __attribute__ ((packed)); struct cmd_ds_bbp_reg_access { __le16 action; __le16 offset; u8 value; u8 reserved[3]; -}; +} __attribute__ ((packed)); struct cmd_ds_rf_reg_access { __le16 action; __le16 offset; u8 value; u8 reserved[3]; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_radio_control { struct cmd_header hdr; __le16 action; __le16 control; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_beacon_control { __le16 action; __le16 beacon_enable; __le16 beacon_period; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_sleep_params { struct cmd_header hdr; @@ -379,7 +379,7 @@ struct cmd_ds_802_11_sleep_params { /* reserved field, should be set to zero */ __le16 reserved; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_inactivity_timeout { struct cmd_header hdr; @@ -389,7 +389,7 @@ struct cmd_ds_802_11_inactivity_timeout { /* Inactivity timeout in msec */ __le16 timeout; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_rf_channel { struct cmd_header hdr; @@ -399,7 +399,7 @@ struct cmd_ds_802_11_rf_channel { __le16 rftype; /* unused */ __le16 reserved; /* unused */ u8 channellist[32]; /* unused */ -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_rssi { /* weighting factor */ @@ -408,21 +408,21 @@ struct cmd_ds_802_11_rssi { __le16 reserved_0; __le16 reserved_1; __le16 reserved_2; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_rssi_rsp { __le16 SNR; __le16 noisefloor; __le16 avgSNR; __le16 avgnoisefloor; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_mac_address { struct cmd_header hdr; __le16 action; u8 macadd[ETH_ALEN]; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_rf_tx_power { struct cmd_header hdr; @@ -431,7 +431,7 @@ struct cmd_ds_802_11_rf_tx_power { __le16 curlevel; s8 maxlevel; s8 minlevel; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_rf_antenna { __le16 action; @@ -439,33 +439,33 @@ struct cmd_ds_802_11_rf_antenna { /* Number of antennas or 0xffff(diversity) */ __le16 antennamode; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_monitor_mode { __le16 action; __le16 mode; -}; +} __attribute__ ((packed)); struct cmd_ds_set_boot2_ver { struct cmd_header hdr; __le16 action; __le16 version; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_fw_wake_method { struct cmd_header hdr; __le16 action; __le16 method; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_sleep_period { struct cmd_header hdr; __le16 action; __le16 period; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_ps_mode { __le16 action; @@ -473,7 +473,7 @@ struct cmd_ds_802_11_ps_mode { __le16 multipledtim; __le16 reserved; __le16 locallisteninterval; -}; +} __attribute__ ((packed)); struct cmd_confirm_sleep { struct cmd_header hdr; @@ -483,7 +483,7 @@ struct cmd_confirm_sleep { __le16 multipledtim; __le16 reserved; __le16 locallisteninterval; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_data_rate { struct cmd_header hdr; @@ -491,14 +491,14 @@ struct cmd_ds_802_11_data_rate { __le16 action; __le16 reserved; u8 rates[MAX_RATES]; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_rate_adapt_rateset { struct cmd_header hdr; __le16 action; __le16 enablehwauto; __le16 bitmap; -}; +} __attribute__ ((packed)); struct cmd_ds_802_11_ad_hoc_start { struct cmd_header hdr; @@ -520,7 +520,7 @@ struct cmd_ds_802_11_ad_hoc_result { u8 pad[3]; u8 bssid[ETH_ALEN]; -}; +} __attribute__ ((packed)); struct adhoc_bssdesc { u8 bssid[ETH_ALEN]; @@ -578,7 +578,7 @@ struct MrvlIEtype_keyParamSet { /* key material of size keylen */ u8 key[32]; -}; +} __attribute__ ((packed)); #define MAX_WOL_RULES 16 @@ -590,7 +590,7 @@ struct host_wol_rule { __le16 reserve; __be32 sig_mask; __be32 signature; -}; +} __attribute__ ((packed)); struct wol_config { uint8_t action; @@ -598,8 +598,7 @@ struct wol_config { uint8_t no_rules_in_cmd; uint8_t result; struct host_wol_rule rule[MAX_WOL_RULES]; -}; - +} __attribute__ ((packed)); struct cmd_ds_host_sleep { struct cmd_header hdr; -- cgit From b657eade2f98b5c689e405bd6e4e445471066380 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 13 Jan 2009 14:33:49 +0200 Subject: ath9k: Fix an operator typo in phy rate validation This was not supposed to be a bitwise AND operation, but a check of two separate conditions. Anyway, the old code happened to result in the same behavior, so this is just changing the code to be easier to understand and also to keep sparse from warning about dubious operators. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/rc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index 04ab457a8fa..1b71b934bb5 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c @@ -490,7 +490,7 @@ static inline int ath_rc_get_nextvalid_txrate(struct ath_rate_table *rate_table, static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw) { - if (WLAN_RC_PHY_HT(phy) & !(capflag & WLAN_RC_HT_FLAG)) + if (WLAN_RC_PHY_HT(phy) && !(capflag & WLAN_RC_HT_FLAG)) return 0; if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG)) return 0; -- cgit From 9d97f2e55e3df44e3b6b4cc58b091501ba7ee0ac Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 13 Jan 2009 14:35:08 +0200 Subject: ath9k: Fix an operator typo in REG_DOMAIN_2GHZ_MASK Incorrect operator causes the REG_DOMAIN_2GHZ_MASK to be zero which surely was not the goal of this definition. Mask out the 11a flags correctly. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/regd_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath9k/regd_common.h b/drivers/net/wireless/ath9k/regd_common.h index 9112c030b1e..6df1b3b77c2 100644 --- a/drivers/net/wireless/ath9k/regd_common.h +++ b/drivers/net/wireless/ath9k/regd_common.h @@ -228,7 +228,7 @@ enum { }; #define REG_DOMAIN_2GHZ_MASK (REQ_MASK & \ - (!(ADHOC_NO_11A | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB))) + (~(ADHOC_NO_11A | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB))) #define REG_DOMAIN_5GHZ_MASK REQ_MASK static struct reg_dmn_pair_mapping regDomainPairs[] = { -- cgit From 73e1a65d3c4a013f6fa56e47133be95143a75fe3 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 8 Jan 2009 10:19:58 -0800 Subject: iwlwifi: remove CMD_WANT_SKB flag if send_cmd_sync failure In function iwl_send_cmd_sync(), if the flag CMD_WANT_SKB is set but we are not provided with a valid SKB (cmd->meta.u.skb == NULL), we need to remove the CMD_WANT_SKB flag from the TX cmd queue. Otherwise in case the cmd comes in later, it will possibly set an invalid address. Thus it causes an invalid memory access. This fixed the bug http://bugzilla.kernel.org/show_bug.cgi?id=11326. Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-hcmd.c | 2 +- drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 8c71ad4f88c..4b35b30e493 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -224,7 +224,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) IWL_ERROR("Error: Response NULL in '%s'\n", get_cmd_string(cmd->id)); ret = -EIO; - goto out; + goto cancel; } ret = 0; diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index d64580805d6..15f5655c636 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -745,7 +745,7 @@ static int iwl3945_send_cmd_sync(struct iwl3945_priv *priv, struct iwl3945_host_ IWL_ERROR("Error: Response NULL in '%s'\n", get_cmd_string(cmd->id)); ret = -EIO; - goto out; + goto cancel; } ret = 0; -- cgit From a92a3ce72483d7f0902dff8a3be8cdcee215a37c Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 7 Jan 2009 17:43:33 -0800 Subject: cfg80211: make handle_band() and handle_channel() wiphy specific This allows us to make more wiphy specific judgements when handling the channels later on. Signed-off-by: Luis R. Rodriguez Acked-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/reg.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 4f877535e66..af805b0e157 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -778,13 +778,22 @@ static int freq_reg_info(u32 center_freq, u32 *bandwidth, return !max_bandwidth; } -static void handle_channel(struct ieee80211_channel *chan) +static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band, + unsigned int chan_idx) { int r; - u32 flags = chan->orig_flags; + u32 flags; u32 max_bandwidth = 0; const struct ieee80211_reg_rule *reg_rule = NULL; const struct ieee80211_power_rule *power_rule = NULL; + struct ieee80211_supported_band *sband; + struct ieee80211_channel *chan; + + sband = wiphy->bands[band]; + BUG_ON(chan_idx >= sband->n_channels); + chan = &sband->channels[chan_idx]; + + flags = chan->orig_flags; r = freq_reg_info(MHZ_TO_KHZ(chan->center_freq), &max_bandwidth, ®_rule); @@ -808,12 +817,16 @@ static void handle_channel(struct ieee80211_channel *chan) chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp); } -static void handle_band(struct ieee80211_supported_band *sband) +static void handle_band(struct wiphy *wiphy, enum ieee80211_band band) { - int i; + unsigned int i; + struct ieee80211_supported_band *sband; + + BUG_ON(!wiphy->bands[band]); + sband = wiphy->bands[band]; for (i = 0; i < sband->n_channels; i++) - handle_channel(&sband->channels[i]); + handle_channel(wiphy, band, i); } static bool ignore_reg_update(struct wiphy *wiphy, enum reg_set_by setby) @@ -840,7 +853,7 @@ void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby) enum ieee80211_band band; for (band = 0; band < IEEE80211_NUM_BANDS; band++) { if (wiphy->bands[band]) - handle_band(wiphy->bands[band]); + handle_band(wiphy, band); if (wiphy->reg_notifier) wiphy->reg_notifier(wiphy, setby); } -- cgit From 0c7dc45d21de6ae212b5ccb7cdff5beff795ccf0 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 7 Jan 2009 17:43:36 -0800 Subject: cfg80211: Fix regression with 11d on bands This fixes a regression on disallowing bands introduced with the new 802.11d support. The issue is that IEEE-802.11 allows APs to send a subset of what a country regulatory domain defines. This was clarified in this document: http://tinyurl.com/11d-clarification As such it is possible, and this is what is done in practice, that a single band 2.4 GHz AP will only send 2.4 GHz band regulatory information through the 802.11 country information element and then the current intersection with what CRDA provided yields a regulatory domain with no 5 GHz information -- even though that country may actually allow 5 GHz operation. We correct this by only applying the intersection rules on a channel if the the intersection yields a regulatory rule on the same band the channel is on. Signed-off-by: Luis R. Rodriguez Acked-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/reg.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 3 deletions(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index af805b0e157..5f6d20d98ee 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -421,6 +421,31 @@ static u32 freq_max_bandwidth(const struct ieee80211_freq_range *freq_range, return 0; } +/** + * freq_in_rule_band - tells us if a frequency is in a frequency band + * @freq_range: frequency rule we want to query + * @freq_khz: frequency we are inquiring about + * + * This lets us know if a specific frequency rule is or is not relevant to + * a specific frequency's band. Bands are device specific and artificial + * definitions (the "2.4 GHz band" and the "5 GHz band"), however it is + * safe for now to assume that a frequency rule should not be part of a + * frequency's band if the start freq or end freq are off by more than 2 GHz. + * This resolution can be lowered and should be considered as we add + * regulatory rule support for other "bands". + **/ +static bool freq_in_rule_band(const struct ieee80211_freq_range *freq_range, + u32 freq_khz) +{ +#define ONE_GHZ_IN_KHZ 1000000 + if (abs(freq_khz - freq_range->start_freq_khz) <= (2 * ONE_GHZ_IN_KHZ)) + return true; + if (abs(freq_khz - freq_range->end_freq_khz) <= (2 * ONE_GHZ_IN_KHZ)) + return true; + return false; +#undef ONE_GHZ_IN_KHZ +} + /* Converts a country IE to a regulatory domain. A regulatory domain * structure has a lot of information which the IE doesn't yet have, * so for the other values we use upper max values as we will intersect @@ -748,12 +773,23 @@ static u32 map_regdom_flags(u32 rd_flags) * this value to the maximum allowed bandwidth. * @reg_rule: the regulatory rule which we have for this frequency * - * Use this function to get the regulatory rule for a specific frequency. + * Use this function to get the regulatory rule for a specific frequency on + * a given wireless device. If the device has a specific regulatory domain + * it wants to follow we respect that unless a country IE has been received + * and processed already. + * + * Returns 0 if it was able to find a valid regulatory rule which does + * apply to the given center_freq otherwise it returns non-zero. It will + * also return -ERANGE if we determine the given center_freq does not even have + * a regulatory rule for a frequency range in the center_freq's band. See + * freq_in_rule_band() for our current definition of a band -- this is purely + * subjective and right now its 802.11 specific. */ static int freq_reg_info(u32 center_freq, u32 *bandwidth, const struct ieee80211_reg_rule **reg_rule) { int i; + bool band_rule_found = false; u32 max_bandwidth = 0; if (!cfg80211_regdomain) @@ -767,7 +803,15 @@ static int freq_reg_info(u32 center_freq, u32 *bandwidth, rr = &cfg80211_regdomain->reg_rules[i]; fr = &rr->freq_range; pr = &rr->power_rule; + + /* We only need to know if one frequency rule was + * was in center_freq's band, that's enough, so lets + * not overwrite it once found */ + if (!band_rule_found) + band_rule_found = freq_in_rule_band(fr, center_freq); + max_bandwidth = freq_max_bandwidth(fr, center_freq); + if (max_bandwidth && *bandwidth <= max_bandwidth) { *reg_rule = rr; *bandwidth = max_bandwidth; @@ -775,6 +819,9 @@ static int freq_reg_info(u32 center_freq, u32 *bandwidth, } } + if (!band_rule_found) + return -ERANGE; + return !max_bandwidth; } @@ -799,8 +846,37 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band, &max_bandwidth, ®_rule); if (r) { - flags |= IEEE80211_CHAN_DISABLED; - chan->flags = flags; + /* This means no regulatory rule was found in the country IE + * with a frequency range on the center_freq's band, since + * IEEE-802.11 allows for a country IE to have a subset of the + * regulatory information provided in a country we ignore + * disabling the channel unless at least one reg rule was + * found on the center_freq's band. For details see this + * clarification: + * + * http://tinyurl.com/11d-clarification + */ + if (r == -ERANGE && + last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) { +#ifdef CONFIG_CFG80211_REG_DEBUG + printk(KERN_DEBUG "cfg80211: Leaving channel %d MHz " + "intact on %s - no rule found in band on " + "Country IE\n", + chan->center_freq, wiphy_name(wiphy)); +#endif + } else { + /* In this case we know the country IE has at least one reg rule + * for the band so we respect its band definitions */ +#ifdef CONFIG_CFG80211_REG_DEBUG + if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) + printk(KERN_DEBUG "cfg80211: Disabling " + "channel %d MHz on %s due to " + "Country IE\n", + chan->center_freq, wiphy_name(wiphy)); +#endif + flags |= IEEE80211_CHAN_DISABLED; + chan->flags = flags; + } return; } -- cgit From 02e68a3da0fbdb178cdec54b7db48edeefd1691d Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 7 Jan 2009 17:43:37 -0800 Subject: cfg80211: Fix parsed country IE info for 5 GHz The country IE number of channels on 5 GHz specifies the number of 5 GHz channels, not the number of sequential channel numbers. For example, if in a country IEs if the first channel given is 36 and the number of channels passed is 4 then the individual channel numbers defined for the 5 GHz PHY by these parameters are: 36, 40, 44, 48 not: 36, 37, 38, 39 See: http://tinyurl.com/11d-clarification Signed-off-by: Luis R. Rodriguez Acked-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/reg.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 5f6d20d98ee..bc494cef210 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -563,6 +563,7 @@ static struct ieee80211_regdomain *country_ie_2_rd( /* This time around we fill in the rd */ while (country_ie_len >= 3) { + int end_channel = 0; struct ieee80211_country_ie_triplet *triplet = (struct ieee80211_country_ie_triplet *) country_ie; struct ieee80211_reg_rule *reg_rule = NULL; @@ -584,6 +585,23 @@ static struct ieee80211_regdomain *country_ie_2_rd( reg_rule->flags = flags; + /* 2 GHz */ + if (triplet->chans.first_channel <= 14) + end_channel = triplet->chans.first_channel + + triplet->chans.num_channels; + else + /* + * 5 GHz -- For example in country IEs if the first + * channel given is 36 and the number of channels is 4 + * then the individual channel numbers defined for the + * 5 GHz PHY by these parameters are: 36, 40, 44, and 48 + * and not 36, 37, 38, 39. + * + * See: http://tinyurl.com/11d-clarification + */ + end_channel = triplet->chans.first_channel + + (4 * (triplet->chans.num_channels - 1)); + /* The +10 is since the regulatory domain expects * the actual band edge, not the center of freq for * its start and end freqs, assuming 20 MHz bandwidth on @@ -593,8 +611,7 @@ static struct ieee80211_regdomain *country_ie_2_rd( triplet->chans.first_channel) - 10); freq_range->end_freq_khz = MHZ_TO_KHZ(ieee80211_channel_to_frequency( - triplet->chans.first_channel + - triplet->chans.num_channels) + 10); + end_channel) + 10); /* Large arbitrary values, we intersect later */ /* Increment this if we ever support >= 40 MHz channels -- cgit From e223b6dc051ad030a70d5c6ed6226b95bdfc3af7 Mon Sep 17 00:00:00 2001 From: Rami Rosen Date: Wed, 14 Jan 2009 00:00:13 +0200 Subject: rt2x00: fix a wrong parameter for __test_and_clear_bit() in rt2x00rfkill_free(). When running modprobe rt73usb, and then rmmod rt73usb, and then iwconfig, the wlan0 device does not disappear. When repeating this process again, we get a kernel Oops errors and "BUG: unable to handle kernel paging request..." message in the kernel log. The reason for this is that there is an error in rt2x00rfkill_free(), which is called in the process of removing the device (rt2x00lib_remove_dev() in rt2x00dev.c). rt2x00rfkill_free() clears the RFKILL_STATE_ALLOCATED bit , which is bit number 1 () in rt2x00dev->flags instead of in rt2x00dev->rfkill_state. As a result, when checking the DEVICE_STATE_REGISTERED_HW bit (bit number 1 in rt2x00dev->flags) in rt2x00lib_remove_hw() it is **unset**, and we wrongly **don't** call ieee80211_unregister_hw(). This patch corrects this: the parameter for __test_and_clear_bit() in rt2x00rfkill_free() should be &rt2x00dev->rfkill_state and not &rt2x00dev->flags. Signed-off-by: Rami Rosen Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00rfkill.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c index c3f53a92180..3298cae1e12 100644 --- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c +++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c @@ -162,7 +162,7 @@ void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev) void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev) { - if (!test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->flags)) + if (!test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state)) return; cancel_delayed_work_sync(&rt2x00dev->rfkill_work); -- cgit From 275719089bfe7dbf446b72c3e520966e7fa42b6a Mon Sep 17 00:00:00 2001 From: Artur Skawina Date: Thu, 15 Jan 2009 21:07:03 +0100 Subject: p54: set_tim must be atomic. Fix for: BUG: scheduling while atomic: named/2004/0x10000200 Pid: 2004, comm: named Not tainted 2.6.29-rc1-00271-ge9fa6b0 #45 Call Trace: [] schedule+0x2a7/0x320 [] __alloc_skb+0x34/0x110 [] __cond_resched+0x13/0x30 [] _cond_resched+0x2d/0x40 [] kmem_cache_alloc+0x95/0xc0 [] check_object+0xc4/0x230 [] __alloc_skb+0x34/0x110 [] p54_alloc_skb+0x71/0xf0 [] p54_set_tim+0x3f/0xa0 [] sta_info_set_tim_bit+0x64/0x80 [] invoke_tx_handlers+0xd57/0xd80 [] free_debug_processing+0x197/0x210 [] pskb_expand_head+0xf5/0x170 [] __ieee80211_tx_prepare+0x164/0x2f0 [] ieee80211_skb_resize+0x6d/0xe0 [] ieee80211_master_start_xmit+0x23f/0x550 [] __slab_alloc+0x2b8/0x4f0 [] getnstimeofday+0x51/0x120 [] dev_hard_start_xmit+0x1db/0x240 [] __qdisc_run+0x1ab/0x200 [] __run_hrtimer+0x31/0xf0 [] dev_queue_xmit+0x247/0x500 [] ieee80211_subif_start_xmit+0x356/0x7d0 [] packet_rcv_spkt+0x37/0x150 [] packet_rcv_spkt+0x37/0x150 [] dev_hard_start_xmit+0x1db/0x240 [] __qdisc_run+0x1ab/0x200 [] dev_queue_xmit+0x247/0x500 [] neigh_resolve_output+0xe2/0x200 [] ip_finish_output+0x0/0x290 [] ip_finish_output+0x1e7/0x290 [] ip_local_out+0x15/0x20 [] ip_push_pending_frames+0x272/0x380 [] udp_push_pending_frames+0x146/0x3a0 [] udp_sendmsg+0x2fa/0x6b0 [] inet_sendmsg+0x37/0x70 [] sock_sendmsg+0xbe/0x100 [] autoremove_wake_function+0x0/0x50 [] __wake_up_common+0x43/0x70 [] copy_from_user+0x32/0x130 [] copy_from_user+0x32/0x130 [] verify_iovec+0x2e/0xb0 [] sys_sendmsg+0x17f/0x290 [] pipe_write+0x29a/0x570 [] update_wall_time+0x492/0x8e0 [] getnstimeofday+0x51/0x120 [] sched_slice+0x3d/0x80 [] getnstimeofday+0x51/0x120 [] hrtimer_forward+0x147/0x1a0 [] lapic_next_event+0x10/0x20 [] clockevents_program_event+0xa3/0x170 [] sys_socketcall+0xa4/0x290 [] smp_apic_timer_interrupt+0x40/0x70 [] sysenter_do_call+0x12/0x25 Signed-off-by: Artur Skawina Acked-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 3b44e8e7603..ae31e3775e0 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -1147,7 +1147,7 @@ static int p54_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta, skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(struct p54_hdr) + sizeof(*tim), - P54_CONTROL_TYPE_TIM, GFP_KERNEL); + P54_CONTROL_TYPE_TIM, GFP_ATOMIC); if (!skb) return -ENOMEM; -- cgit From 674743033c1ae9f7cc94e1e0037f6f719e6d1d67 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 16 Jan 2009 19:46:28 +0100 Subject: p54: fix p54_set_key's return code p54 doesn't support AES-128-CMAC offload. This patch will fix the noisy mac80211 warnings, when 802.11w is enabled: mac80211-phy189: failed to set key (4, ff:ff:ff:ff:ff:ff) to hardware (-22) mac80211-phy189: failed to set key (5, ff:ff:ff:ff:ff:ff) to hardware (-22) Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index ae31e3775e0..12d0717c399 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -2077,7 +2077,7 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, algo = P54_CRYPTO_AESCCMP; break; default: - return -EINVAL; + return -EOPNOTSUPP; } } -- cgit From 3750f60557b68776eb749859ad68af70d1a01ad0 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 16 Jan 2009 14:55:28 -0800 Subject: IB/ehca: Fix printk format warnings from u64 type change Commit fe333321 ("powerpc: Change u64/s64 to a long long integer type") changed u64 from unsigned long to unsigned long long, which means that printk formats for printing u64 values should use "ll" instead of "l" to avoid warnings. Fix all the places affected by this in ehca. Signed-off-by: Stephen Rothwell Signed-off-by: Roland Dreier --- drivers/infiniband/hw/ehca/ehca_cq.c | 16 ++-- drivers/infiniband/hw/ehca/ehca_hca.c | 2 +- drivers/infiniband/hw/ehca/ehca_irq.c | 18 ++-- drivers/infiniband/hw/ehca/ehca_main.c | 6 +- drivers/infiniband/hw/ehca/ehca_mcast.c | 4 +- drivers/infiniband/hw/ehca/ehca_mrmw.c | 144 +++++++++++++++---------------- drivers/infiniband/hw/ehca/ehca_qp.c | 32 +++---- drivers/infiniband/hw/ehca/ehca_reqs.c | 2 +- drivers/infiniband/hw/ehca/ehca_sqp.c | 2 +- drivers/infiniband/hw/ehca/ehca_tools.h | 2 +- drivers/infiniband/hw/ehca/ehca_uverbs.c | 2 +- drivers/infiniband/hw/ehca/hcp_if.c | 30 +++---- 12 files changed, 130 insertions(+), 130 deletions(-) diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c index 2f4c28a3027..97e4b231cdc 100644 --- a/drivers/infiniband/hw/ehca/ehca_cq.c +++ b/drivers/infiniband/hw/ehca/ehca_cq.c @@ -196,7 +196,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, if (h_ret != H_SUCCESS) { ehca_err(device, "hipz_h_alloc_resource_cq() failed " - "h_ret=%li device=%p", h_ret, device); + "h_ret=%lli device=%p", h_ret, device); cq = ERR_PTR(ehca2ib_return_code(h_ret)); goto create_cq_exit2; } @@ -232,7 +232,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, if (h_ret < H_SUCCESS) { ehca_err(device, "hipz_h_register_rpage_cq() failed " - "ehca_cq=%p cq_num=%x h_ret=%li counter=%i " + "ehca_cq=%p cq_num=%x h_ret=%lli counter=%i " "act_pages=%i", my_cq, my_cq->cq_number, h_ret, counter, param.act_pages); cq = ERR_PTR(-EINVAL); @@ -244,7 +244,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, if ((h_ret != H_SUCCESS) || vpage) { ehca_err(device, "Registration of pages not " "complete ehca_cq=%p cq_num=%x " - "h_ret=%li", my_cq, my_cq->cq_number, + "h_ret=%lli", my_cq, my_cq->cq_number, h_ret); cq = ERR_PTR(-EAGAIN); goto create_cq_exit4; @@ -252,7 +252,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, } else { if (h_ret != H_PAGE_REGISTERED) { ehca_err(device, "Registration of page failed " - "ehca_cq=%p cq_num=%x h_ret=%li " + "ehca_cq=%p cq_num=%x h_ret=%lli " "counter=%i act_pages=%i", my_cq, my_cq->cq_number, h_ret, counter, param.act_pages); @@ -266,7 +266,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, gal = my_cq->galpas.kernel; cqx_fec = hipz_galpa_load(gal, CQTEMM_OFFSET(cqx_fec)); - ehca_dbg(device, "ehca_cq=%p cq_num=%x CQX_FEC=%lx", + ehca_dbg(device, "ehca_cq=%p cq_num=%x CQX_FEC=%llx", my_cq, my_cq->cq_number, cqx_fec); my_cq->ib_cq.cqe = my_cq->nr_of_entries = @@ -307,7 +307,7 @@ create_cq_exit3: h_ret = hipz_h_destroy_cq(adapter_handle, my_cq, 1); if (h_ret != H_SUCCESS) ehca_err(device, "hipz_h_destroy_cq() failed ehca_cq=%p " - "cq_num=%x h_ret=%li", my_cq, my_cq->cq_number, h_ret); + "cq_num=%x h_ret=%lli", my_cq, my_cq->cq_number, h_ret); create_cq_exit2: write_lock_irqsave(&ehca_cq_idr_lock, flags); @@ -355,7 +355,7 @@ int ehca_destroy_cq(struct ib_cq *cq) h_ret = hipz_h_destroy_cq(adapter_handle, my_cq, 0); if (h_ret == H_R_STATE) { /* cq in err: read err data and destroy it forcibly */ - ehca_dbg(device, "ehca_cq=%p cq_num=%x ressource=%lx in err " + ehca_dbg(device, "ehca_cq=%p cq_num=%x resource=%llx in err " "state. Try to delete it forcibly.", my_cq, cq_num, my_cq->ipz_cq_handle.handle); ehca_error_data(shca, my_cq, my_cq->ipz_cq_handle.handle); @@ -365,7 +365,7 @@ int ehca_destroy_cq(struct ib_cq *cq) cq_num); } if (h_ret != H_SUCCESS) { - ehca_err(device, "hipz_h_destroy_cq() failed h_ret=%li " + ehca_err(device, "hipz_h_destroy_cq() failed h_ret=%lli " "ehca_cq=%p cq_num=%x", h_ret, my_cq, cq_num); return ehca2ib_return_code(h_ret); } diff --git a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c index 46288220cfb..9209c5332df 100644 --- a/drivers/infiniband/hw/ehca/ehca_hca.c +++ b/drivers/infiniband/hw/ehca/ehca_hca.c @@ -393,7 +393,7 @@ int ehca_modify_port(struct ib_device *ibdev, hret = hipz_h_modify_port(shca->ipz_hca_handle, port, cap, props->init_type, port_modify_mask); if (hret != H_SUCCESS) { - ehca_err(&shca->ib_device, "Modify port failed h_ret=%li", + ehca_err(&shca->ib_device, "Modify port failed h_ret=%lli", hret); ret = -EINVAL; } diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c index 3128a5090db..99bcbd7ffb0 100644 --- a/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/drivers/infiniband/hw/ehca/ehca_irq.c @@ -99,7 +99,7 @@ static void print_error_data(struct ehca_shca *shca, void *data, return; ehca_err(&shca->ib_device, - "QP 0x%x (resource=%lx) has errors.", + "QP 0x%x (resource=%llx) has errors.", qp->ib_qp.qp_num, resource); break; } @@ -108,21 +108,21 @@ static void print_error_data(struct ehca_shca *shca, void *data, struct ehca_cq *cq = (struct ehca_cq *)data; ehca_err(&shca->ib_device, - "CQ 0x%x (resource=%lx) has errors.", + "CQ 0x%x (resource=%llx) has errors.", cq->cq_number, resource); break; } default: ehca_err(&shca->ib_device, - "Unknown error type: %lx on %s.", + "Unknown error type: %llx on %s.", type, shca->ib_device.name); break; } - ehca_err(&shca->ib_device, "Error data is available: %lx.", resource); + ehca_err(&shca->ib_device, "Error data is available: %llx.", resource); ehca_err(&shca->ib_device, "EHCA ----- error data begin " "---------------------------------------------------"); - ehca_dmp(rblock, length, "resource=%lx", resource); + ehca_dmp(rblock, length, "resource=%llx", resource); ehca_err(&shca->ib_device, "EHCA ----- error data end " "----------------------------------------------------"); @@ -152,7 +152,7 @@ int ehca_error_data(struct ehca_shca *shca, void *data, if (ret == H_R_STATE) ehca_err(&shca->ib_device, - "No error data is available: %lx.", resource); + "No error data is available: %llx.", resource); else if (ret == H_SUCCESS) { int length; @@ -164,7 +164,7 @@ int ehca_error_data(struct ehca_shca *shca, void *data, print_error_data(shca, data, rblock, length); } else ehca_err(&shca->ib_device, - "Error data could not be fetched: %lx", resource); + "Error data could not be fetched: %llx", resource); ehca_free_fw_ctrlblock(rblock); @@ -514,7 +514,7 @@ static inline void process_eqe(struct ehca_shca *shca, struct ehca_eqe *eqe) struct ehca_cq *cq; eqe_value = eqe->entry; - ehca_dbg(&shca->ib_device, "eqe_value=%lx", eqe_value); + ehca_dbg(&shca->ib_device, "eqe_value=%llx", eqe_value); if (EHCA_BMASK_GET(EQE_COMPLETION_EVENT, eqe_value)) { ehca_dbg(&shca->ib_device, "Got completion event"); token = EHCA_BMASK_GET(EQE_CQ_TOKEN, eqe_value); @@ -603,7 +603,7 @@ void ehca_process_eq(struct ehca_shca *shca, int is_irq) ret = hipz_h_eoi(eq->ist); if (ret != H_SUCCESS) ehca_err(&shca->ib_device, - "bad return code EOI -rc = %ld\n", ret); + "bad return code EOI -rc = %lld\n", ret); ehca_dbg(&shca->ib_device, "deadman found %x eqe", eqe_cnt); } if (unlikely(eqe_cnt == EHCA_EQE_CACHE_SIZE)) diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index c7b8a506af6..368311ce332 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c @@ -304,7 +304,7 @@ static int ehca_sense_attributes(struct ehca_shca *shca) h_ret = hipz_h_query_hca(shca->ipz_hca_handle, rblock); if (h_ret != H_SUCCESS) { - ehca_gen_err("Cannot query device properties. h_ret=%li", + ehca_gen_err("Cannot query device properties. h_ret=%lli", h_ret); ret = -EPERM; goto sense_attributes1; @@ -391,7 +391,7 @@ static int ehca_sense_attributes(struct ehca_shca *shca) port = (struct hipz_query_port *)rblock; h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port); if (h_ret != H_SUCCESS) { - ehca_gen_err("Cannot query port properties. h_ret=%li", + ehca_gen_err("Cannot query port properties. h_ret=%lli", h_ret); ret = -EPERM; goto sense_attributes1; @@ -682,7 +682,7 @@ static ssize_t ehca_show_adapter_handle(struct device *dev, { struct ehca_shca *shca = dev->driver_data; - return sprintf(buf, "%lx\n", shca->ipz_hca_handle.handle); + return sprintf(buf, "%llx\n", shca->ipz_hca_handle.handle); } static DEVICE_ATTR(adapter_handle, S_IRUGO, ehca_show_adapter_handle, NULL); diff --git a/drivers/infiniband/hw/ehca/ehca_mcast.c b/drivers/infiniband/hw/ehca/ehca_mcast.c index e3ef0264ccc..120aedf9f98 100644 --- a/drivers/infiniband/hw/ehca/ehca_mcast.c +++ b/drivers/infiniband/hw/ehca/ehca_mcast.c @@ -88,7 +88,7 @@ int ehca_attach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) if (h_ret != H_SUCCESS) ehca_err(ibqp->device, "ehca_qp=%p qp_num=%x hipz_h_attach_mcqp() failed " - "h_ret=%li", my_qp, ibqp->qp_num, h_ret); + "h_ret=%lli", my_qp, ibqp->qp_num, h_ret); return ehca2ib_return_code(h_ret); } @@ -125,7 +125,7 @@ int ehca_detach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) if (h_ret != H_SUCCESS) ehca_err(ibqp->device, "ehca_qp=%p qp_num=%x hipz_h_detach_mcqp() failed " - "h_ret=%li", my_qp, ibqp->qp_num, h_ret); + "h_ret=%lli", my_qp, ibqp->qp_num, h_ret); return ehca2ib_return_code(h_ret); } diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c index f974367cad4..72f83f7df61 100644 --- a/drivers/infiniband/hw/ehca/ehca_mrmw.c +++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c @@ -204,7 +204,7 @@ struct ib_mr *ehca_reg_phys_mr(struct ib_pd *pd, } if ((size == 0) || (((u64)iova_start + size) < (u64)iova_start)) { - ehca_err(pd->device, "bad input values: size=%lx iova_start=%p", + ehca_err(pd->device, "bad input values: size=%llx iova_start=%p", size, iova_start); ib_mr = ERR_PTR(-EINVAL); goto reg_phys_mr_exit0; @@ -309,8 +309,8 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, } if (length == 0 || virt + length < virt) { - ehca_err(pd->device, "bad input values: length=%lx " - "virt_base=%lx", length, virt); + ehca_err(pd->device, "bad input values: length=%llx " + "virt_base=%llx", length, virt); ib_mr = ERR_PTR(-EINVAL); goto reg_user_mr_exit0; } @@ -373,7 +373,7 @@ reg_user_mr_fallback: &e_mr->ib.ib_mr.rkey); if (ret == -EINVAL && pginfo.hwpage_size > PAGE_SIZE) { ehca_warn(pd->device, "failed to register mr " - "with hwpage_size=%lx", hwpage_size); + "with hwpage_size=%llx", hwpage_size); ehca_info(pd->device, "try to register mr with " "kpage_size=%lx", PAGE_SIZE); /* @@ -509,7 +509,7 @@ int ehca_rereg_phys_mr(struct ib_mr *mr, goto rereg_phys_mr_exit1; if ((new_size == 0) || (((u64)iova_start + new_size) < (u64)iova_start)) { - ehca_err(mr->device, "bad input values: new_size=%lx " + ehca_err(mr->device, "bad input values: new_size=%llx " "iova_start=%p", new_size, iova_start); ret = -EINVAL; goto rereg_phys_mr_exit1; @@ -580,8 +580,8 @@ int ehca_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr) h_ret = hipz_h_query_mr(shca->ipz_hca_handle, e_mr, &hipzout); if (h_ret != H_SUCCESS) { - ehca_err(mr->device, "hipz_mr_query failed, h_ret=%li mr=%p " - "hca_hndl=%lx mr_hndl=%lx lkey=%x", + ehca_err(mr->device, "hipz_mr_query failed, h_ret=%lli mr=%p " + "hca_hndl=%llx mr_hndl=%llx lkey=%x", h_ret, mr, shca->ipz_hca_handle.handle, e_mr->ipz_mr_handle.handle, mr->lkey); ret = ehca2ib_return_code(h_ret); @@ -630,8 +630,8 @@ int ehca_dereg_mr(struct ib_mr *mr) /* TODO: BUSY: MR still has bound window(s) */ h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_mr); if (h_ret != H_SUCCESS) { - ehca_err(mr->device, "hipz_free_mr failed, h_ret=%li shca=%p " - "e_mr=%p hca_hndl=%lx mr_hndl=%lx mr->lkey=%x", + ehca_err(mr->device, "hipz_free_mr failed, h_ret=%lli shca=%p " + "e_mr=%p hca_hndl=%llx mr_hndl=%llx mr->lkey=%x", h_ret, shca, e_mr, shca->ipz_hca_handle.handle, e_mr->ipz_mr_handle.handle, mr->lkey); ret = ehca2ib_return_code(h_ret); @@ -671,8 +671,8 @@ struct ib_mw *ehca_alloc_mw(struct ib_pd *pd) h_ret = hipz_h_alloc_resource_mw(shca->ipz_hca_handle, e_mw, e_pd->fw_pd, &hipzout); if (h_ret != H_SUCCESS) { - ehca_err(pd->device, "hipz_mw_allocate failed, h_ret=%li " - "shca=%p hca_hndl=%lx mw=%p", + ehca_err(pd->device, "hipz_mw_allocate failed, h_ret=%lli " + "shca=%p hca_hndl=%llx mw=%p", h_ret, shca, shca->ipz_hca_handle.handle, e_mw); ib_mw = ERR_PTR(ehca2ib_return_code(h_ret)); goto alloc_mw_exit1; @@ -713,8 +713,8 @@ int ehca_dealloc_mw(struct ib_mw *mw) h_ret = hipz_h_free_resource_mw(shca->ipz_hca_handle, e_mw); if (h_ret != H_SUCCESS) { - ehca_err(mw->device, "hipz_free_mw failed, h_ret=%li shca=%p " - "mw=%p rkey=%x hca_hndl=%lx mw_hndl=%lx", + ehca_err(mw->device, "hipz_free_mw failed, h_ret=%lli shca=%p " + "mw=%p rkey=%x hca_hndl=%llx mw_hndl=%llx", h_ret, shca, mw, mw->rkey, shca->ipz_hca_handle.handle, e_mw->ipz_mw_handle.handle); return ehca2ib_return_code(h_ret); @@ -840,7 +840,7 @@ int ehca_map_phys_fmr(struct ib_fmr *fmr, goto map_phys_fmr_exit0; if (iova % e_fmr->fmr_page_size) { /* only whole-numbered pages */ - ehca_err(fmr->device, "bad iova, iova=%lx fmr_page_size=%x", + ehca_err(fmr->device, "bad iova, iova=%llx fmr_page_size=%x", iova, e_fmr->fmr_page_size); ret = -EINVAL; goto map_phys_fmr_exit0; @@ -878,7 +878,7 @@ int ehca_map_phys_fmr(struct ib_fmr *fmr, map_phys_fmr_exit0: if (ret) ehca_err(fmr->device, "ret=%i fmr=%p page_list=%p list_len=%x " - "iova=%lx", ret, fmr, page_list, list_len, iova); + "iova=%llx", ret, fmr, page_list, list_len, iova); return ret; } /* end ehca_map_phys_fmr() */ @@ -964,8 +964,8 @@ int ehca_dealloc_fmr(struct ib_fmr *fmr) h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_fmr); if (h_ret != H_SUCCESS) { - ehca_err(fmr->device, "hipz_free_mr failed, h_ret=%li e_fmr=%p " - "hca_hndl=%lx fmr_hndl=%lx fmr->lkey=%x", + ehca_err(fmr->device, "hipz_free_mr failed, h_ret=%lli e_fmr=%p " + "hca_hndl=%llx fmr_hndl=%llx fmr->lkey=%x", h_ret, e_fmr, shca->ipz_hca_handle.handle, e_fmr->ipz_mr_handle.handle, fmr->lkey); ret = ehca2ib_return_code(h_ret); @@ -1007,8 +1007,8 @@ int ehca_reg_mr(struct ehca_shca *shca, (u64)iova_start, size, hipz_acl, e_pd->fw_pd, &hipzout); if (h_ret != H_SUCCESS) { - ehca_err(&shca->ib_device, "hipz_alloc_mr failed, h_ret=%li " - "hca_hndl=%lx", h_ret, shca->ipz_hca_handle.handle); + ehca_err(&shca->ib_device, "hipz_alloc_mr failed, h_ret=%lli " + "hca_hndl=%llx", h_ret, shca->ipz_hca_handle.handle); ret = ehca2ib_return_code(h_ret); goto ehca_reg_mr_exit0; } @@ -1033,9 +1033,9 @@ int ehca_reg_mr(struct ehca_shca *shca, ehca_reg_mr_exit1: h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_mr); if (h_ret != H_SUCCESS) { - ehca_err(&shca->ib_device, "h_ret=%li shca=%p e_mr=%p " - "iova_start=%p size=%lx acl=%x e_pd=%p lkey=%x " - "pginfo=%p num_kpages=%lx num_hwpages=%lx ret=%i", + ehca_err(&shca->ib_device, "h_ret=%lli shca=%p e_mr=%p " + "iova_start=%p size=%llx acl=%x e_pd=%p lkey=%x " + "pginfo=%p num_kpages=%llx num_hwpages=%llx ret=%i", h_ret, shca, e_mr, iova_start, size, acl, e_pd, hipzout.lkey, pginfo, pginfo->num_kpages, pginfo->num_hwpages, ret); @@ -1045,8 +1045,8 @@ ehca_reg_mr_exit1: ehca_reg_mr_exit0: if (ret) ehca_err(&shca->ib_device, "ret=%i shca=%p e_mr=%p " - "iova_start=%p size=%lx acl=%x e_pd=%p pginfo=%p " - "num_kpages=%lx num_hwpages=%lx", + "iova_start=%p size=%llx acl=%x e_pd=%p pginfo=%p " + "num_kpages=%llx num_hwpages=%llx", ret, shca, e_mr, iova_start, size, acl, e_pd, pginfo, pginfo->num_kpages, pginfo->num_hwpages); return ret; @@ -1116,8 +1116,8 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca, */ if (h_ret != H_SUCCESS) { ehca_err(&shca->ib_device, "last " - "hipz_reg_rpage_mr failed, h_ret=%li " - "e_mr=%p i=%x hca_hndl=%lx mr_hndl=%lx" + "hipz_reg_rpage_mr failed, h_ret=%lli " + "e_mr=%p i=%x hca_hndl=%llx mr_hndl=%llx" " lkey=%x", h_ret, e_mr, i, shca->ipz_hca_handle.handle, e_mr->ipz_mr_handle.handle, @@ -1128,8 +1128,8 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca, ret = 0; } else if (h_ret != H_PAGE_REGISTERED) { ehca_err(&shca->ib_device, "hipz_reg_rpage_mr failed, " - "h_ret=%li e_mr=%p i=%x lkey=%x hca_hndl=%lx " - "mr_hndl=%lx", h_ret, e_mr, i, + "h_ret=%lli e_mr=%p i=%x lkey=%x hca_hndl=%llx " + "mr_hndl=%llx", h_ret, e_mr, i, e_mr->ib.ib_mr.lkey, shca->ipz_hca_handle.handle, e_mr->ipz_mr_handle.handle); @@ -1145,7 +1145,7 @@ ehca_reg_mr_rpages_exit1: ehca_reg_mr_rpages_exit0: if (ret) ehca_err(&shca->ib_device, "ret=%i shca=%p e_mr=%p pginfo=%p " - "num_kpages=%lx num_hwpages=%lx", ret, shca, e_mr, + "num_kpages=%llx num_hwpages=%llx", ret, shca, e_mr, pginfo, pginfo->num_kpages, pginfo->num_hwpages); return ret; } /* end ehca_reg_mr_rpages() */ @@ -1184,7 +1184,7 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca, ret = ehca_set_pagebuf(pginfo, pginfo->num_hwpages, kpage); if (ret) { ehca_err(&shca->ib_device, "set pagebuf failed, e_mr=%p " - "pginfo=%p type=%x num_kpages=%lx num_hwpages=%lx " + "pginfo=%p type=%x num_kpages=%llx num_hwpages=%llx " "kpage=%p", e_mr, pginfo, pginfo->type, pginfo->num_kpages, pginfo->num_hwpages, kpage); goto ehca_rereg_mr_rereg1_exit1; @@ -1205,13 +1205,13 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca, * (MW bound or MR is shared) */ ehca_warn(&shca->ib_device, "hipz_h_reregister_pmr failed " - "(Rereg1), h_ret=%li e_mr=%p", h_ret, e_mr); + "(Rereg1), h_ret=%lli e_mr=%p", h_ret, e_mr); *pginfo = pginfo_save; ret = -EAGAIN; } else if ((u64 *)hipzout.vaddr != iova_start) { ehca_err(&shca->ib_device, "PHYP changed iova_start in " - "rereg_pmr, iova_start=%p iova_start_out=%lx e_mr=%p " - "mr_handle=%lx lkey=%x lkey_out=%x", iova_start, + "rereg_pmr, iova_start=%p iova_start_out=%llx e_mr=%p " + "mr_handle=%llx lkey=%x lkey_out=%x", iova_start, hipzout.vaddr, e_mr, e_mr->ipz_mr_handle.handle, e_mr->ib.ib_mr.lkey, hipzout.lkey); ret = -EFAULT; @@ -1235,7 +1235,7 @@ ehca_rereg_mr_rereg1_exit1: ehca_rereg_mr_rereg1_exit0: if ( ret && (ret != -EAGAIN) ) ehca_err(&shca->ib_device, "ret=%i lkey=%x rkey=%x " - "pginfo=%p num_kpages=%lx num_hwpages=%lx", + "pginfo=%p num_kpages=%llx num_hwpages=%llx", ret, *lkey, *rkey, pginfo, pginfo->num_kpages, pginfo->num_hwpages); return ret; @@ -1263,7 +1263,7 @@ int ehca_rereg_mr(struct ehca_shca *shca, (e_mr->num_hwpages > MAX_RPAGES) || (pginfo->num_hwpages > e_mr->num_hwpages)) { ehca_dbg(&shca->ib_device, "Rereg3 case, " - "pginfo->num_hwpages=%lx e_mr->num_hwpages=%x", + "pginfo->num_hwpages=%llx e_mr->num_hwpages=%x", pginfo->num_hwpages, e_mr->num_hwpages); rereg_1_hcall = 0; rereg_3_hcall = 1; @@ -1295,7 +1295,7 @@ int ehca_rereg_mr(struct ehca_shca *shca, h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_mr); if (h_ret != H_SUCCESS) { ehca_err(&shca->ib_device, "hipz_free_mr failed, " - "h_ret=%li e_mr=%p hca_hndl=%lx mr_hndl=%lx " + "h_ret=%lli e_mr=%p hca_hndl=%llx mr_hndl=%llx " "mr->lkey=%x", h_ret, e_mr, shca->ipz_hca_handle.handle, e_mr->ipz_mr_handle.handle, @@ -1328,8 +1328,8 @@ int ehca_rereg_mr(struct ehca_shca *shca, ehca_rereg_mr_exit0: if (ret) ehca_err(&shca->ib_device, "ret=%i shca=%p e_mr=%p " - "iova_start=%p size=%lx acl=%x e_pd=%p pginfo=%p " - "num_kpages=%lx lkey=%x rkey=%x rereg_1_hcall=%x " + "iova_start=%p size=%llx acl=%x e_pd=%p pginfo=%p " + "num_kpages=%llx lkey=%x rkey=%x rereg_1_hcall=%x " "rereg_3_hcall=%x", ret, shca, e_mr, iova_start, size, acl, e_pd, pginfo, pginfo->num_kpages, *lkey, *rkey, rereg_1_hcall, rereg_3_hcall); @@ -1371,8 +1371,8 @@ int ehca_unmap_one_fmr(struct ehca_shca *shca, * FMRs are not shared and no MW bound to FMRs */ ehca_err(&shca->ib_device, "hipz_reregister_pmr failed " - "(Rereg1), h_ret=%li e_fmr=%p hca_hndl=%lx " - "mr_hndl=%lx lkey=%x lkey_out=%x", + "(Rereg1), h_ret=%lli e_fmr=%p hca_hndl=%llx " + "mr_hndl=%llx lkey=%x lkey_out=%x", h_ret, e_fmr, shca->ipz_hca_handle.handle, e_fmr->ipz_mr_handle.handle, e_fmr->ib.ib_fmr.lkey, hipzout.lkey); @@ -1383,7 +1383,7 @@ int ehca_unmap_one_fmr(struct ehca_shca *shca, h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_fmr); if (h_ret != H_SUCCESS) { ehca_err(&shca->ib_device, "hipz_free_mr failed, " - "h_ret=%li e_fmr=%p hca_hndl=%lx mr_hndl=%lx " + "h_ret=%lli e_fmr=%p hca_hndl=%llx mr_hndl=%llx " "lkey=%x", h_ret, e_fmr, shca->ipz_hca_handle.handle, e_fmr->ipz_mr_handle.handle, @@ -1447,9 +1447,9 @@ int ehca_reg_smr(struct ehca_shca *shca, (u64)iova_start, hipz_acl, e_pd->fw_pd, &hipzout); if (h_ret != H_SUCCESS) { - ehca_err(&shca->ib_device, "hipz_reg_smr failed, h_ret=%li " + ehca_err(&shca->ib_device, "hipz_reg_smr failed, h_ret=%lli " "shca=%p e_origmr=%p e_newmr=%p iova_start=%p acl=%x " - "e_pd=%p hca_hndl=%lx mr_hndl=%lx lkey=%x", + "e_pd=%p hca_hndl=%llx mr_hndl=%llx lkey=%x", h_ret, shca, e_origmr, e_newmr, iova_start, acl, e_pd, shca->ipz_hca_handle.handle, e_origmr->ipz_mr_handle.handle, @@ -1527,7 +1527,7 @@ int ehca_reg_internal_maxmr( &e_mr->ib.ib_mr.rkey); if (ret) { ehca_err(&shca->ib_device, "reg of internal max MR failed, " - "e_mr=%p iova_start=%p size_maxmr=%lx num_kpages=%x " + "e_mr=%p iova_start=%p size_maxmr=%llx num_kpages=%x " "num_hwpages=%x", e_mr, iova_start, size_maxmr, num_kpages, num_hwpages); goto ehca_reg_internal_maxmr_exit1; @@ -1573,8 +1573,8 @@ int ehca_reg_maxmr(struct ehca_shca *shca, (u64)iova_start, hipz_acl, e_pd->fw_pd, &hipzout); if (h_ret != H_SUCCESS) { - ehca_err(&shca->ib_device, "hipz_reg_smr failed, h_ret=%li " - "e_origmr=%p hca_hndl=%lx mr_hndl=%lx lkey=%x", + ehca_err(&shca->ib_device, "hipz_reg_smr failed, h_ret=%lli " + "e_origmr=%p hca_hndl=%llx mr_hndl=%llx lkey=%x", h_ret, e_origmr, shca->ipz_hca_handle.handle, e_origmr->ipz_mr_handle.handle, e_origmr->ib.ib_mr.lkey); @@ -1651,28 +1651,28 @@ int ehca_mr_chk_buf_and_calc_size(struct ib_phys_buf *phys_buf_array, /* check first buffer */ if (((u64)iova_start & ~PAGE_MASK) != (pbuf->addr & ~PAGE_MASK)) { ehca_gen_err("iova_start/addr mismatch, iova_start=%p " - "pbuf->addr=%lx pbuf->size=%lx", + "pbuf->addr=%llx pbuf->size=%llx", iova_start, pbuf->addr, pbuf->size); return -EINVAL; } if (((pbuf->addr + pbuf->size) % PAGE_SIZE) && (num_phys_buf > 1)) { - ehca_gen_err("addr/size mismatch in 1st buf, pbuf->addr=%lx " - "pbuf->size=%lx", pbuf->addr, pbuf->size); + ehca_gen_err("addr/size mismatch in 1st buf, pbuf->addr=%llx " + "pbuf->size=%llx", pbuf->addr, pbuf->size); return -EINVAL; } for (i = 0; i < num_phys_buf; i++) { if ((i > 0) && (pbuf->addr % PAGE_SIZE)) { - ehca_gen_err("bad address, i=%x pbuf->addr=%lx " - "pbuf->size=%lx", + ehca_gen_err("bad address, i=%x pbuf->addr=%llx " + "pbuf->size=%llx", i, pbuf->addr, pbuf->size); return -EINVAL; } if (((i > 0) && /* not 1st */ (i < (num_phys_buf - 1)) && /* not last */ (pbuf->size % PAGE_SIZE)) || (pbuf->size == 0)) { - ehca_gen_err("bad size, i=%x pbuf->size=%lx", + ehca_gen_err("bad size, i=%x pbuf->size=%llx", i, pbuf->size); return -EINVAL; } @@ -1705,7 +1705,7 @@ int ehca_fmr_check_page_list(struct ehca_mr *e_fmr, page = page_list; for (i = 0; i < list_len; i++) { if (*page % e_fmr->fmr_page_size) { - ehca_gen_err("bad page, i=%x *page=%lx page=%p fmr=%p " + ehca_gen_err("bad page, i=%x *page=%llx page=%p fmr=%p " "fmr_page_size=%x", i, *page, page, e_fmr, e_fmr->fmr_page_size); return -EINVAL; @@ -1743,9 +1743,9 @@ static int ehca_set_pagebuf_user1(struct ehca_mr_pginfo *pginfo, (pginfo->next_hwpage * pginfo->hwpage_size)); if ( !(*kpage) ) { - ehca_gen_err("pgaddr=%lx " - "chunk->page_list[i]=%lx " - "i=%x next_hwpage=%lx", + ehca_gen_err("pgaddr=%llx " + "chunk->page_list[i]=%llx " + "i=%x next_hwpage=%llx", pgaddr, (u64)sg_dma_address( &chunk->page_list[i]), i, pginfo->next_hwpage); @@ -1795,11 +1795,11 @@ static int ehca_check_kpages_per_ate(struct scatterlist *page_list, for (t = start_idx; t <= end_idx; t++) { u64 pgaddr = page_to_pfn(sg_page(&page_list[t])) << PAGE_SHIFT; if (ehca_debug_level >= 3) - ehca_gen_dbg("chunk_page=%lx value=%016lx", pgaddr, + ehca_gen_dbg("chunk_page=%llx value=%016llx", pgaddr, *(u64 *)abs_to_virt(phys_to_abs(pgaddr))); if (pgaddr - PAGE_SIZE != *prev_pgaddr) { - ehca_gen_err("uncontiguous page found pgaddr=%lx " - "prev_pgaddr=%lx page_list_i=%x", + ehca_gen_err("uncontiguous page found pgaddr=%llx " + "prev_pgaddr=%llx page_list_i=%x", pgaddr, *prev_pgaddr, t); return -EINVAL; } @@ -1833,7 +1833,7 @@ static int ehca_set_pagebuf_user2(struct ehca_mr_pginfo *pginfo, << PAGE_SHIFT ); *kpage = phys_to_abs(pgaddr); if ( !(*kpage) ) { - ehca_gen_err("pgaddr=%lx i=%x", + ehca_gen_err("pgaddr=%llx i=%x", pgaddr, i); ret = -EFAULT; return ret; @@ -1846,8 +1846,8 @@ static int ehca_set_pagebuf_user2(struct ehca_mr_pginfo *pginfo, if (pginfo->hwpage_cnt) { ehca_gen_err( "invalid alignment " - "pgaddr=%lx i=%x " - "mr_pgsize=%lx", + "pgaddr=%llx i=%x " + "mr_pgsize=%llx", pgaddr, i, pginfo->hwpage_size); ret = -EFAULT; @@ -1866,8 +1866,8 @@ static int ehca_set_pagebuf_user2(struct ehca_mr_pginfo *pginfo, if (ehca_debug_level >= 3) { u64 val = *(u64 *)abs_to_virt( phys_to_abs(pgaddr)); - ehca_gen_dbg("kpage=%lx chunk_page=%lx " - "value=%016lx", + ehca_gen_dbg("kpage=%llx chunk_page=%llx " + "value=%016llx", *kpage, pgaddr, val); } prev_pgaddr = pgaddr; @@ -1944,9 +1944,9 @@ static int ehca_set_pagebuf_phys(struct ehca_mr_pginfo *pginfo, if ((pginfo->kpage_cnt >= pginfo->num_kpages) || (pginfo->hwpage_cnt >= pginfo->num_hwpages)) { ehca_gen_err("kpage_cnt >= num_kpages, " - "kpage_cnt=%lx num_kpages=%lx " - "hwpage_cnt=%lx " - "num_hwpages=%lx i=%x", + "kpage_cnt=%llx num_kpages=%llx " + "hwpage_cnt=%llx " + "num_hwpages=%llx i=%x", pginfo->kpage_cnt, pginfo->num_kpages, pginfo->hwpage_cnt, @@ -1957,8 +1957,8 @@ static int ehca_set_pagebuf_phys(struct ehca_mr_pginfo *pginfo, (pbuf->addr & ~(pginfo->hwpage_size - 1)) + (pginfo->next_hwpage * pginfo->hwpage_size)); if ( !(*kpage) && pbuf->addr ) { - ehca_gen_err("pbuf->addr=%lx pbuf->size=%lx " - "next_hwpage=%lx", pbuf->addr, + ehca_gen_err("pbuf->addr=%llx pbuf->size=%llx " + "next_hwpage=%llx", pbuf->addr, pbuf->size, pginfo->next_hwpage); return -EFAULT; } @@ -1996,8 +1996,8 @@ static int ehca_set_pagebuf_fmr(struct ehca_mr_pginfo *pginfo, *kpage = phys_to_abs((*fmrlist & ~(pginfo->hwpage_size - 1)) + pginfo->next_hwpage * pginfo->hwpage_size); if ( !(*kpage) ) { - ehca_gen_err("*fmrlist=%lx fmrlist=%p " - "next_listelem=%lx next_hwpage=%lx", + ehca_gen_err("*fmrlist=%llx fmrlist=%p " + "next_listelem=%llx next_hwpage=%llx", *fmrlist, fmrlist, pginfo->u.fmr.next_listelem, pginfo->next_hwpage); @@ -2025,7 +2025,7 @@ static int ehca_set_pagebuf_fmr(struct ehca_mr_pginfo *pginfo, ~(pginfo->hwpage_size - 1)); if (prev + pginfo->u.fmr.fmr_pgsize != p) { ehca_gen_err("uncontiguous fmr pages " - "found prev=%lx p=%lx " + "found prev=%llx p=%llx " "idx=%x", prev, p, i + j); return -EINVAL; } diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c index f161cf173db..00c10815971 100644 --- a/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/drivers/infiniband/hw/ehca/ehca_qp.c @@ -331,7 +331,7 @@ static inline int init_qp_queue(struct ehca_shca *shca, if (cnt == (nr_q_pages - 1)) { /* last page! */ if (h_ret != expected_hret) { ehca_err(ib_dev, "hipz_qp_register_rpage() " - "h_ret=%li", h_ret); + "h_ret=%lli", h_ret); ret = ehca2ib_return_code(h_ret); goto init_qp_queue1; } @@ -345,7 +345,7 @@ static inline int init_qp_queue(struct ehca_shca *shca, } else { if (h_ret != H_PAGE_REGISTERED) { ehca_err(ib_dev, "hipz_qp_register_rpage() " - "h_ret=%li", h_ret); + "h_ret=%lli", h_ret); ret = ehca2ib_return_code(h_ret); goto init_qp_queue1; } @@ -709,7 +709,7 @@ static struct ehca_qp *internal_create_qp( h_ret = hipz_h_alloc_resource_qp(shca->ipz_hca_handle, &parms); if (h_ret != H_SUCCESS) { - ehca_err(pd->device, "h_alloc_resource_qp() failed h_ret=%li", + ehca_err(pd->device, "h_alloc_resource_qp() failed h_ret=%lli", h_ret); ret = ehca2ib_return_code(h_ret); goto create_qp_exit1; @@ -1010,7 +1010,7 @@ struct ib_srq *ehca_create_srq(struct ib_pd *pd, mqpcb, my_qp->galpas.kernel); if (hret != H_SUCCESS) { ehca_err(pd->device, "Could not modify SRQ to INIT " - "ehca_qp=%p qp_num=%x h_ret=%li", + "ehca_qp=%p qp_num=%x h_ret=%lli", my_qp, my_qp->real_qp_num, hret); goto create_srq2; } @@ -1024,7 +1024,7 @@ struct ib_srq *ehca_create_srq(struct ib_pd *pd, mqpcb, my_qp->galpas.kernel); if (hret != H_SUCCESS) { ehca_err(pd->device, "Could not enable SRQ " - "ehca_qp=%p qp_num=%x h_ret=%li", + "ehca_qp=%p qp_num=%x h_ret=%lli", my_qp, my_qp->real_qp_num, hret); goto create_srq2; } @@ -1038,7 +1038,7 @@ struct ib_srq *ehca_create_srq(struct ib_pd *pd, mqpcb, my_qp->galpas.kernel); if (hret != H_SUCCESS) { ehca_err(pd->device, "Could not modify SRQ to RTR " - "ehca_qp=%p qp_num=%x h_ret=%li", + "ehca_qp=%p qp_num=%x h_ret=%lli", my_qp, my_qp->real_qp_num, hret); goto create_srq2; } @@ -1078,7 +1078,7 @@ static int prepare_sqe_rts(struct ehca_qp *my_qp, struct ehca_shca *shca, &bad_send_wqe_p, NULL, 2); if (h_ret != H_SUCCESS) { ehca_err(&shca->ib_device, "hipz_h_disable_and_get_wqe() failed" - " ehca_qp=%p qp_num=%x h_ret=%li", + " ehca_qp=%p qp_num=%x h_ret=%lli", my_qp, qp_num, h_ret); return ehca2ib_return_code(h_ret); } @@ -1134,7 +1134,7 @@ static int calc_left_cqes(u64 wqe_p, struct ipz_queue *ipz_queue, if (ipz_queue_abs_to_offset(ipz_queue, wqe_p, &q_ofs)) { ehca_gen_err("Invalid offset for calculating left cqes " - "wqe_p=%#lx wqe_v=%p\n", wqe_p, wqe_v); + "wqe_p=%#llx wqe_v=%p\n", wqe_p, wqe_v); return -EFAULT; } @@ -1168,7 +1168,7 @@ static int check_for_left_cqes(struct ehca_qp *my_qp, struct ehca_shca *shca) &send_wqe_p, &recv_wqe_p, 4); if (h_ret != H_SUCCESS) { ehca_err(&shca->ib_device, "disable_and_get_wqe() " - "failed ehca_qp=%p qp_num=%x h_ret=%li", + "failed ehca_qp=%p qp_num=%x h_ret=%lli", my_qp, qp_num, h_ret); return ehca2ib_return_code(h_ret); } @@ -1261,7 +1261,7 @@ static int internal_modify_qp(struct ib_qp *ibqp, mqpcb, my_qp->galpas.kernel); if (h_ret != H_SUCCESS) { ehca_err(ibqp->device, "hipz_h_query_qp() failed " - "ehca_qp=%p qp_num=%x h_ret=%li", + "ehca_qp=%p qp_num=%x h_ret=%lli", my_qp, ibqp->qp_num, h_ret); ret = ehca2ib_return_code(h_ret); goto modify_qp_exit1; @@ -1690,7 +1690,7 @@ static int internal_modify_qp(struct ib_qp *ibqp, if (h_ret != H_SUCCESS) { ret = ehca2ib_return_code(h_ret); - ehca_err(ibqp->device, "hipz_h_modify_qp() failed h_ret=%li " + ehca_err(ibqp->device, "hipz_h_modify_qp() failed h_ret=%lli " "ehca_qp=%p qp_num=%x", h_ret, my_qp, ibqp->qp_num); goto modify_qp_exit2; } @@ -1723,7 +1723,7 @@ static int internal_modify_qp(struct ib_qp *ibqp, ret = ehca2ib_return_code(h_ret); ehca_err(ibqp->device, "ENABLE in context of " "RESET_2_INIT failed! Maybe you didn't get " - "a LID h_ret=%li ehca_qp=%p qp_num=%x", + "a LID h_ret=%lli ehca_qp=%p qp_num=%x", h_ret, my_qp, ibqp->qp_num); goto modify_qp_exit2; } @@ -1909,7 +1909,7 @@ int ehca_query_qp(struct ib_qp *qp, if (h_ret != H_SUCCESS) { ret = ehca2ib_return_code(h_ret); ehca_err(qp->device, "hipz_h_query_qp() failed " - "ehca_qp=%p qp_num=%x h_ret=%li", + "ehca_qp=%p qp_num=%x h_ret=%lli", my_qp, qp->qp_num, h_ret); goto query_qp_exit1; } @@ -2074,7 +2074,7 @@ int ehca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, if (h_ret != H_SUCCESS) { ret = ehca2ib_return_code(h_ret); - ehca_err(ibsrq->device, "hipz_h_modify_qp() failed h_ret=%li " + ehca_err(ibsrq->device, "hipz_h_modify_qp() failed h_ret=%lli " "ehca_qp=%p qp_num=%x", h_ret, my_qp, my_qp->real_qp_num); } @@ -2108,7 +2108,7 @@ int ehca_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr) if (h_ret != H_SUCCESS) { ret = ehca2ib_return_code(h_ret); ehca_err(srq->device, "hipz_h_query_qp() failed " - "ehca_qp=%p qp_num=%x h_ret=%li", + "ehca_qp=%p qp_num=%x h_ret=%lli", my_qp, my_qp->real_qp_num, h_ret); goto query_srq_exit1; } @@ -2179,7 +2179,7 @@ static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp, h_ret = hipz_h_destroy_qp(shca->ipz_hca_handle, my_qp); if (h_ret != H_SUCCESS) { - ehca_err(dev, "hipz_h_destroy_qp() failed h_ret=%li " + ehca_err(dev, "hipz_h_destroy_qp() failed h_ret=%lli " "ehca_qp=%p qp_num=%x", h_ret, my_qp, qp_num); return ehca2ib_return_code(h_ret); } diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c index c7112686782..5a3d96f84c7 100644 --- a/drivers/infiniband/hw/ehca/ehca_reqs.c +++ b/drivers/infiniband/hw/ehca/ehca_reqs.c @@ -822,7 +822,7 @@ static int generate_flush_cqes(struct ehca_qp *my_qp, struct ib_cq *cq, offset = qmap->next_wqe_idx * ipz_queue->qe_size; wqe = (struct ehca_wqe *)ipz_qeit_calc(ipz_queue, offset); if (!wqe) { - ehca_err(cq->device, "Invalid wqe offset=%#lx on " + ehca_err(cq->device, "Invalid wqe offset=%#llx on " "qp_num=%#x", offset, my_qp->real_qp_num); return nr; } diff --git a/drivers/infiniband/hw/ehca/ehca_sqp.c b/drivers/infiniband/hw/ehca/ehca_sqp.c index 706d97ad555..44447aaa550 100644 --- a/drivers/infiniband/hw/ehca/ehca_sqp.c +++ b/drivers/infiniband/hw/ehca/ehca_sqp.c @@ -85,7 +85,7 @@ u64 ehca_define_sqp(struct ehca_shca *shca, if (ret != H_SUCCESS) { ehca_err(&shca->ib_device, - "Can't define AQP1 for port %x. h_ret=%li", + "Can't define AQP1 for port %x. h_ret=%lli", port, ret); return ret; } diff --git a/drivers/infiniband/hw/ehca/ehca_tools.h b/drivers/infiniband/hw/ehca/ehca_tools.h index 21f7d06f14a..f09914cccf5 100644 --- a/drivers/infiniband/hw/ehca/ehca_tools.h +++ b/drivers/infiniband/hw/ehca/ehca_tools.h @@ -116,7 +116,7 @@ extern int ehca_debug_level; unsigned char *deb = (unsigned char *)(adr); \ for (x = 0; x < l; x += 16) { \ printk(KERN_INFO "EHCA_DMP:%s " format \ - " adr=%p ofs=%04x %016lx %016lx\n", \ + " adr=%p ofs=%04x %016llx %016llx\n", \ __func__, ##args, deb, x, \ *((u64 *)&deb[0]), *((u64 *)&deb[8])); \ deb += 16; \ diff --git a/drivers/infiniband/hw/ehca/ehca_uverbs.c b/drivers/infiniband/hw/ehca/ehca_uverbs.c index e43ed8f8a0c..3cb688d2913 100644 --- a/drivers/infiniband/hw/ehca/ehca_uverbs.c +++ b/drivers/infiniband/hw/ehca/ehca_uverbs.c @@ -114,7 +114,7 @@ static int ehca_mmap_fw(struct vm_area_struct *vma, struct h_galpas *galpas, physical = galpas->user.fw_handle; vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - ehca_gen_dbg("vsize=%lx physical=%lx", vsize, physical); + ehca_gen_dbg("vsize=%llx physical=%llx", vsize, physical); /* VM_IO | VM_RESERVED are set by remap_pfn_range() */ ret = remap_4k_pfn(vma, vma->vm_start, physical >> EHCA_PAGESHIFT, vma->vm_page_prot); diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c index 415d3a465de..7a13a247c0f 100644 --- a/drivers/infiniband/hw/ehca/hcp_if.c +++ b/drivers/infiniband/hw/ehca/hcp_if.c @@ -249,7 +249,7 @@ u64 hipz_h_alloc_resource_eq(const struct ipz_adapter_handle adapter_handle, *eq_ist = (u32)outs[5]; if (ret == H_NOT_ENOUGH_RESOURCES) - ehca_gen_err("Not enough resource - ret=%li ", ret); + ehca_gen_err("Not enough resource - ret=%lli ", ret); return ret; } @@ -287,7 +287,7 @@ u64 hipz_h_alloc_resource_cq(const struct ipz_adapter_handle adapter_handle, hcp_galpas_ctor(&cq->galpas, outs[5], outs[6]); if (ret == H_NOT_ENOUGH_RESOURCES) - ehca_gen_err("Not enough resources. ret=%li", ret); + ehca_gen_err("Not enough resources. ret=%lli", ret); return ret; } @@ -362,7 +362,7 @@ u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle, hcp_galpas_ctor(&parms->galpas, outs[6], outs[6]); if (ret == H_NOT_ENOUGH_RESOURCES) - ehca_gen_err("Not enough resources. ret=%li", ret); + ehca_gen_err("Not enough resources. ret=%lli", ret); return ret; } @@ -454,7 +454,7 @@ u64 hipz_h_register_rpage_eq(const struct ipz_adapter_handle adapter_handle, const u64 count) { if (count != 1) { - ehca_gen_err("Ppage counter=%lx", count); + ehca_gen_err("Ppage counter=%llx", count); return H_PARAMETER; } return hipz_h_register_rpage(adapter_handle, @@ -489,7 +489,7 @@ u64 hipz_h_register_rpage_cq(const struct ipz_adapter_handle adapter_handle, const struct h_galpa gal) { if (count != 1) { - ehca_gen_err("Page counter=%lx", count); + ehca_gen_err("Page counter=%llx", count); return H_PARAMETER; } @@ -508,7 +508,7 @@ u64 hipz_h_register_rpage_qp(const struct ipz_adapter_handle adapter_handle, const struct h_galpa galpa) { if (count > 1) { - ehca_gen_err("Page counter=%lx", count); + ehca_gen_err("Page counter=%llx", count); return H_PARAMETER; } @@ -557,7 +557,7 @@ u64 hipz_h_modify_qp(const struct ipz_adapter_handle adapter_handle, 0, 0, 0, 0, 0); if (ret == H_NOT_ENOUGH_RESOURCES) - ehca_gen_err("Insufficient resources ret=%li", ret); + ehca_gen_err("Insufficient resources ret=%lli", ret); return ret; } @@ -593,7 +593,7 @@ u64 hipz_h_destroy_qp(const struct ipz_adapter_handle adapter_handle, qp->ipz_qp_handle.handle, /* r6 */ 0, 0, 0, 0, 0, 0); if (ret == H_HARDWARE) - ehca_gen_err("HCA not operational. ret=%li", ret); + ehca_gen_err("HCA not operational. ret=%lli", ret); ret = ehca_plpar_hcall_norets(H_FREE_RESOURCE, adapter_handle.handle, /* r4 */ @@ -601,7 +601,7 @@ u64 hipz_h_destroy_qp(const struct ipz_adapter_handle adapter_handle, 0, 0, 0, 0, 0); if (ret == H_RESOURCE) - ehca_gen_err("Resource still in use. ret=%li", ret); + ehca_gen_err("Resource still in use. ret=%lli", ret); return ret; } @@ -636,7 +636,7 @@ u64 hipz_h_define_aqp1(const struct ipz_adapter_handle adapter_handle, *bma_qp_nr = (u32)outs[1]; if (ret == H_ALIAS_EXIST) - ehca_gen_err("AQP1 already exists. ret=%li", ret); + ehca_gen_err("AQP1 already exists. ret=%lli", ret); return ret; } @@ -658,7 +658,7 @@ u64 hipz_h_attach_mcqp(const struct ipz_adapter_handle adapter_handle, 0, 0); if (ret == H_NOT_ENOUGH_RESOURCES) - ehca_gen_err("Not enough resources. ret=%li", ret); + ehca_gen_err("Not enough resources. ret=%lli", ret); return ret; } @@ -697,7 +697,7 @@ u64 hipz_h_destroy_cq(const struct ipz_adapter_handle adapter_handle, 0, 0, 0, 0); if (ret == H_RESOURCE) - ehca_gen_err("H_FREE_RESOURCE failed ret=%li ", ret); + ehca_gen_err("H_FREE_RESOURCE failed ret=%lli ", ret); return ret; } @@ -719,7 +719,7 @@ u64 hipz_h_destroy_eq(const struct ipz_adapter_handle adapter_handle, 0, 0, 0, 0, 0); if (ret == H_RESOURCE) - ehca_gen_err("Resource in use. ret=%li ", ret); + ehca_gen_err("Resource in use. ret=%lli ", ret); return ret; } @@ -774,9 +774,9 @@ u64 hipz_h_register_rpage_mr(const struct ipz_adapter_handle adapter_handle, if ((count > 1) && (logical_address_of_page & (EHCA_PAGESIZE-1))) { ehca_gen_err("logical_address_of_page not on a 4k boundary " - "adapter_handle=%lx mr=%p mr_handle=%lx " + "adapter_handle=%llx mr=%p mr_handle=%llx " "pagesize=%x queue_type=%x " - "logical_address_of_page=%lx count=%lx", + "logical_address_of_page=%llx count=%llx", adapter_handle.handle, mr, mr->ipz_mr_handle.handle, pagesize, queue_type, logical_address_of_page, count); -- cgit From ee96aae57381e77311538f4a1dd4326f6ae079d1 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 16 Jan 2009 14:55:40 -0800 Subject: IB/ehca: Use consistent types for ehca_plpar_hcall9() ehca_plpar_hcall9() takes an unsigned long array, so make all callers pass that in. This fixes warnings introduced by commit fe333321 ("powerpc: Change u64/s64 to a long long integer type"), which changed u64 from unsigned long to unsigned long long. Signed-off-by: Stephen Rothwell Signed-off-by: Roland Dreier --- drivers/infiniband/hw/ehca/hcp_if.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c index 7a13a247c0f..d0ab0c0d5e9 100644 --- a/drivers/infiniband/hw/ehca/hcp_if.c +++ b/drivers/infiniband/hw/ehca/hcp_if.c @@ -226,7 +226,7 @@ u64 hipz_h_alloc_resource_eq(const struct ipz_adapter_handle adapter_handle, u32 *eq_ist) { u64 ret; - u64 outs[PLPAR_HCALL9_BUFSIZE]; + unsigned long outs[PLPAR_HCALL9_BUFSIZE]; u64 allocate_controls; /* resource type */ @@ -270,7 +270,7 @@ u64 hipz_h_alloc_resource_cq(const struct ipz_adapter_handle adapter_handle, struct ehca_alloc_cq_parms *param) { u64 ret; - u64 outs[PLPAR_HCALL9_BUFSIZE]; + unsigned long outs[PLPAR_HCALL9_BUFSIZE]; ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs, adapter_handle.handle, /* r4 */ @@ -297,7 +297,7 @@ u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle, { u64 ret; u64 allocate_controls, max_r10_reg, r11, r12; - u64 outs[PLPAR_HCALL9_BUFSIZE]; + unsigned long outs[PLPAR_HCALL9_BUFSIZE]; allocate_controls = EHCA_BMASK_SET(H_ALL_RES_QP_ENHANCED_OPS, parms->ext_type) @@ -525,7 +525,7 @@ u64 hipz_h_disable_and_get_wqe(const struct ipz_adapter_handle adapter_handle, int dis_and_get_function_code) { u64 ret; - u64 outs[PLPAR_HCALL9_BUFSIZE]; + unsigned long outs[PLPAR_HCALL9_BUFSIZE]; ret = ehca_plpar_hcall9(H_DISABLE_AND_GETC, outs, adapter_handle.handle, /* r4 */ @@ -548,7 +548,7 @@ u64 hipz_h_modify_qp(const struct ipz_adapter_handle adapter_handle, struct h_galpa gal) { u64 ret; - u64 outs[PLPAR_HCALL9_BUFSIZE]; + unsigned long outs[PLPAR_HCALL9_BUFSIZE]; ret = ehca_plpar_hcall9(H_MODIFY_QP, outs, adapter_handle.handle, /* r4 */ qp_handle.handle, /* r5 */ @@ -579,7 +579,7 @@ u64 hipz_h_destroy_qp(const struct ipz_adapter_handle adapter_handle, struct ehca_qp *qp) { u64 ret; - u64 outs[PLPAR_HCALL9_BUFSIZE]; + unsigned long outs[PLPAR_HCALL9_BUFSIZE]; ret = hcp_galpas_dtor(&qp->galpas); if (ret) { @@ -625,7 +625,7 @@ u64 hipz_h_define_aqp1(const struct ipz_adapter_handle adapter_handle, u32 * bma_qp_nr) { u64 ret; - u64 outs[PLPAR_HCALL9_BUFSIZE]; + unsigned long outs[PLPAR_HCALL9_BUFSIZE]; ret = ehca_plpar_hcall9(H_DEFINE_AQP1, outs, adapter_handle.handle, /* r4 */ @@ -733,7 +733,7 @@ u64 hipz_h_alloc_resource_mr(const struct ipz_adapter_handle adapter_handle, struct ehca_mr_hipzout_parms *outparms) { u64 ret; - u64 outs[PLPAR_HCALL9_BUFSIZE]; + unsigned long outs[PLPAR_HCALL9_BUFSIZE]; ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs, adapter_handle.handle, /* r4 */ @@ -794,7 +794,7 @@ u64 hipz_h_query_mr(const struct ipz_adapter_handle adapter_handle, struct ehca_mr_hipzout_parms *outparms) { u64 ret; - u64 outs[PLPAR_HCALL9_BUFSIZE]; + unsigned long outs[PLPAR_HCALL9_BUFSIZE]; ret = ehca_plpar_hcall9(H_QUERY_MR, outs, adapter_handle.handle, /* r4 */ @@ -828,7 +828,7 @@ u64 hipz_h_reregister_pmr(const struct ipz_adapter_handle adapter_handle, struct ehca_mr_hipzout_parms *outparms) { u64 ret; - u64 outs[PLPAR_HCALL9_BUFSIZE]; + unsigned long outs[PLPAR_HCALL9_BUFSIZE]; ret = ehca_plpar_hcall9(H_REREGISTER_PMR, outs, adapter_handle.handle, /* r4 */ @@ -855,7 +855,7 @@ u64 hipz_h_register_smr(const struct ipz_adapter_handle adapter_handle, struct ehca_mr_hipzout_parms *outparms) { u64 ret; - u64 outs[PLPAR_HCALL9_BUFSIZE]; + unsigned long outs[PLPAR_HCALL9_BUFSIZE]; ret = ehca_plpar_hcall9(H_REGISTER_SMR, outs, adapter_handle.handle, /* r4 */ @@ -877,7 +877,7 @@ u64 hipz_h_alloc_resource_mw(const struct ipz_adapter_handle adapter_handle, struct ehca_mw_hipzout_parms *outparms) { u64 ret; - u64 outs[PLPAR_HCALL9_BUFSIZE]; + unsigned long outs[PLPAR_HCALL9_BUFSIZE]; ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs, adapter_handle.handle, /* r4 */ @@ -895,7 +895,7 @@ u64 hipz_h_query_mw(const struct ipz_adapter_handle adapter_handle, struct ehca_mw_hipzout_parms *outparms) { u64 ret; - u64 outs[PLPAR_HCALL9_BUFSIZE]; + unsigned long outs[PLPAR_HCALL9_BUFSIZE]; ret = ehca_plpar_hcall9(H_QUERY_MW, outs, adapter_handle.handle, /* r4 */ -- cgit From 091d71e023557136e96f0e54f301497a3fc95dc3 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 17 Jan 2009 00:10:45 +0100 Subject: PM: Fix compilation warning in kernel/power/main.c Reorder the code in kernel/power/main.c to fix compilation warning triggered by unsetting CONFIG_SUSPEND. Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown --- kernel/power/main.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/kernel/power/main.c b/kernel/power/main.c index 23998887397..b4d219016b6 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -57,16 +57,6 @@ int pm_notifier_call_chain(unsigned long val) #ifdef CONFIG_PM_DEBUG int pm_test_level = TEST_NONE; -static int suspend_test(int level) -{ - if (pm_test_level == level) { - printk(KERN_INFO "suspend debug: Waiting for 5 seconds.\n"); - mdelay(5000); - return 1; - } - return 0; -} - static const char * const pm_tests[__TEST_AFTER_LAST] = { [TEST_NONE] = "none", [TEST_CORE] = "core", @@ -125,14 +115,24 @@ static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr, } power_attr(pm_test); -#else /* !CONFIG_PM_DEBUG */ -static inline int suspend_test(int level) { return 0; } -#endif /* !CONFIG_PM_DEBUG */ +#endif /* CONFIG_PM_DEBUG */ #endif /* CONFIG_PM_SLEEP */ #ifdef CONFIG_SUSPEND +static int suspend_test(int level) +{ +#ifdef CONFIG_PM_DEBUG + if (pm_test_level == level) { + printk(KERN_INFO "suspend debug: Waiting for 5 seconds.\n"); + mdelay(5000); + return 1; + } +#endif /* !CONFIG_PM_DEBUG */ + return 0; +} + #ifdef CONFIG_PM_TEST_SUSPEND /* -- cgit From 5d8b532af9e52ea89208f5ef31889f646e67ba28 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 16 Jan 2009 23:09:14 +0100 Subject: ACPI suspend: Fix compilation warnings in drivers/acpi/sleep.c Fix two compilation warnings in drivers/acpi/sleep.c, one triggered by unsetting CONFIG_SUSPEND and the other triggered by unsetting CONFIG_HIBERNATION, by moving some code under the appropriate #ifdefs . Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown --- arch/x86/kernel/acpi/sleep.c | 4 ++-- drivers/acpi/sleep.c | 51 ++++++++++++++++++++++---------------------- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 707c1f6f95f..a60c1f3bcb8 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c @@ -156,11 +156,11 @@ static int __init acpi_sleep_setup(char *str) #ifdef CONFIG_HIBERNATION if (strncmp(str, "s4_nohwsig", 10) == 0) acpi_no_s4_hw_signature(); + if (strncmp(str, "s4_nonvs", 8) == 0) + acpi_s4_no_nvs(); #endif if (strncmp(str, "old_ordering", 12) == 0) acpi_old_suspend_ordering(); - if (strncmp(str, "s4_nonvs", 8) == 0) - acpi_s4_no_nvs(); str = strchr(str, ','); if (str != NULL) str += strspn(str, ", \t"); diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 7e3c609cbef..af85f5ba1be 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -90,31 +90,6 @@ void __init acpi_old_suspend_ordering(void) old_suspend_ordering = true; } -/* - * According to the ACPI specification the BIOS should make sure that ACPI is - * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still, - * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI - * on such systems during resume. Unfortunately that doesn't help in - * particularly pathological cases in which SCI_EN has to be set directly on - * resume, although the specification states very clearly that this flag is - * owned by the hardware. The set_sci_en_on_resume variable will be set in such - * cases. - */ -static bool set_sci_en_on_resume; -/* - * The ACPI specification wants us to save NVS memory regions during hibernation - * and to restore them during the subsequent resume. However, it is not certain - * if this mechanism is going to work on all machines, so we allow the user to - * disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line - * option. - */ -static bool s4_no_nvs; - -void __init acpi_s4_no_nvs(void) -{ - s4_no_nvs = true; -} - /** * acpi_pm_disable_gpes - Disable the GPEs. */ @@ -193,6 +168,18 @@ static void acpi_pm_end(void) #endif /* CONFIG_ACPI_SLEEP */ #ifdef CONFIG_SUSPEND +/* + * According to the ACPI specification the BIOS should make sure that ACPI is + * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still, + * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI + * on such systems during resume. Unfortunately that doesn't help in + * particularly pathological cases in which SCI_EN has to be set directly on + * resume, although the specification states very clearly that this flag is + * owned by the hardware. The set_sci_en_on_resume variable will be set in such + * cases. + */ +static bool set_sci_en_on_resume; + extern void do_suspend_lowlevel(void); static u32 acpi_suspend_states[] = { @@ -396,6 +383,20 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { #endif /* CONFIG_SUSPEND */ #ifdef CONFIG_HIBERNATION +/* + * The ACPI specification wants us to save NVS memory regions during hibernation + * and to restore them during the subsequent resume. However, it is not certain + * if this mechanism is going to work on all machines, so we allow the user to + * disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line + * option. + */ +static bool s4_no_nvs; + +void __init acpi_s4_no_nvs(void) +{ + s4_no_nvs = true; +} + static unsigned long s4_hardware_signature; static struct acpi_table_facs *facs; static bool nosigcheck; -- cgit From 145cd30bac885dffad9db9d487baad07b68a3d04 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 17 Jan 2009 14:42:50 +0900 Subject: linker script: add missing VMLINUX_SYMBOL The newly added PERCPU_*() macros define and use __per_cpu_load but VMLINUX_SYMBOL() was missing from usages causing build failures on archs where linker visible symbol is different from C symbols (e.g. blackfin). Signed-off-by: Tejun Heo --- include/asm-generic/vmlinux.lds.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index e53319cf29c..aa6b9b1b30b 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -432,13 +432,14 @@ #define PERCPU_PROLOG(vaddr) \ VMLINUX_SYMBOL(__per_cpu_load) = .; \ - .data.percpu vaddr : AT(__per_cpu_load - LOAD_OFFSET) { \ + .data.percpu vaddr : AT(VMLINUX_SYMBOL(__per_cpu_load) \ + - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__per_cpu_start) = .; #define PERCPU_EPILOG(phdr) \ VMLINUX_SYMBOL(__per_cpu_end) = .; \ } phdr \ - . = __per_cpu_load + SIZEOF(.data.percpu); + . = VMLINUX_SYMBOL(__per_cpu_load) + SIZEOF(.data.percpu); /** * PERCPU_VADDR_PREALLOC - define output section for percpu area with prealloc -- cgit From 74e7904559a10cbb9fbf9139c5c42fc87c0f62a4 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 17 Jan 2009 15:26:32 +0900 Subject: linker script: add missing .data.percpu.page_aligned arm, arm/mach-integrator and powerpc were missing .data.percpu.page_aligned in their percpu output section definitions. Add it. Signed-off-by: Tejun Heo --- arch/arm/kernel/vmlinux.lds.S | 1 + arch/ia64/kernel/vmlinux.lds.S | 1 + arch/powerpc/kernel/vmlinux.lds.S | 1 + 3 files changed, 3 insertions(+) diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index 00216071eaf..85598f7da40 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -65,6 +65,7 @@ SECTIONS #endif . = ALIGN(4096); __per_cpu_start = .; + *(.data.percpu.page_aligned) *(.data.percpu) *(.data.percpu.shared_aligned) __per_cpu_end = .; diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S index 10a7d47e851..f45e4e508ec 100644 --- a/arch/ia64/kernel/vmlinux.lds.S +++ b/arch/ia64/kernel/vmlinux.lds.S @@ -219,6 +219,7 @@ SECTIONS .data.percpu PERCPU_ADDR : AT(__phys_per_cpu_start - LOAD_OFFSET) { __per_cpu_start = .; + *(.data.percpu.page_aligned) *(.data.percpu) *(.data.percpu.shared_aligned) __per_cpu_end = .; diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index 47bf15cd2c9..04e8ecea9b4 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -182,6 +182,7 @@ SECTIONS . = ALIGN(PAGE_SIZE); .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { __per_cpu_start = .; + *(.data.percpu.page_aligned) *(.data.percpu) *(.data.percpu.shared_aligned) __per_cpu_end = .; -- cgit From 5dbdf7354821e00e4419ac3520d05d126857d56e Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 12 Jan 2009 23:25:05 +0100 Subject: move wm8400-regulator's probe function to .devinit.text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A pointer to wm8400_regulator_probe is passed to the core via platform_driver_register and so the function must not disappear when the .init sections are discarded. Otherwise (if also having HOTPLUG=y) unbinding and binding a device to the driver via sysfs will result in an oops as does a device being registered late. An alternative to this patch is using platform_driver_probe instead of platform_driver_register plus removing the pointer to the probe function from the struct platform_driver. Signed-off-by: Uwe Kleine-König Signed-off-by: Liam Girdwood --- drivers/regulator/wm8400-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c index 48b372e038a..56e23d44ba5 100644 --- a/drivers/regulator/wm8400-regulator.c +++ b/drivers/regulator/wm8400-regulator.c @@ -289,7 +289,7 @@ static struct regulator_desc regulators[] = { }, }; -static int __init wm8400_regulator_probe(struct platform_device *pdev) +static int __devinit wm8400_regulator_probe(struct platform_device *pdev) { struct regulator_dev *rdev; -- cgit From fdb6a8f4db813b4e50f4e975efe6be12ba5bf460 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Sat, 17 Jan 2009 17:13:27 +0100 Subject: oprofile: fix uninitialized use of struct op_entry Impact: fix crash In case of losing samples struct op_entry could have been used uninitialized causing e.g. a wrong preemption count or NULL pointer access. This patch fixes this. Signed-off-by: Robert Richter Signed-off-by: Ingo Molnar --- drivers/oprofile/cpu_buffer.c | 5 +++++ drivers/oprofile/cpu_buffer.h | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c index 2e03b6d796d..e76d715e434 100644 --- a/drivers/oprofile/cpu_buffer.c +++ b/drivers/oprofile/cpu_buffer.c @@ -393,16 +393,21 @@ oprofile_write_reserve(struct op_entry *entry, struct pt_regs * const regs, return; fail: + entry->event = NULL; cpu_buf->sample_lost_overflow++; } int oprofile_add_data(struct op_entry *entry, unsigned long val) { + if (!entry->event) + return 0; return op_cpu_buffer_add_data(entry, val); } int oprofile_write_commit(struct op_entry *entry) { + if (!entry->event) + return -EINVAL; return op_cpu_buffer_write_commit(entry); } diff --git a/drivers/oprofile/cpu_buffer.h b/drivers/oprofile/cpu_buffer.h index 63f81c44846..272995d2029 100644 --- a/drivers/oprofile/cpu_buffer.h +++ b/drivers/oprofile/cpu_buffer.h @@ -66,6 +66,13 @@ static inline void op_cpu_buffer_reset(int cpu) cpu_buf->last_task = NULL; } +/* + * op_cpu_buffer_add_data() and op_cpu_buffer_write_commit() may be + * called only if op_cpu_buffer_write_reserve() did not return NULL or + * entry->event != NULL, otherwise entry->size or entry->event will be + * used uninitialized. + */ + struct op_sample *op_cpu_buffer_write_reserve(struct op_entry *entry, unsigned long size); int op_cpu_buffer_write_commit(struct op_entry *entry); -- cgit From 0d54ee1c7850a954026deec4cd4885f331da35cc Mon Sep 17 00:00:00 2001 From: Vegard Nossum Date: Sat, 17 Jan 2009 17:45:45 +0100 Subject: security: introduce missing kfree Plug this leak. Acked-by: David Howells Cc: James Morris Cc: Signed-off-by: Vegard Nossum Signed-off-by: Linus Torvalds --- security/keys/keyctl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index e9335e1c6cf..b1ec3b4ee17 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -270,6 +270,7 @@ long keyctl_join_session_keyring(const char __user *_name) /* join the session */ ret = join_session_keyring(name); + kfree(name); error: return ret; -- cgit From 81156928f8fe31621e467490b9d441c0285998c3 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Sat, 17 Jan 2009 13:33:03 -0500 Subject: dell_rbu: use scnprintf() instead of less secure sprintf() Reading 0 bytes from /sys/devices/platform/dell_rbu/image_type or /sys/devices/platform/dell_rbu/packet_size by an ordinary user causes an oops. Signed-off-by: Pavel Roskin Signed-off-by: Linus Torvalds --- drivers/firmware/dell_rbu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c index 13946ebd77d..b4704e150b2 100644 --- a/drivers/firmware/dell_rbu.c +++ b/drivers/firmware/dell_rbu.c @@ -576,7 +576,7 @@ static ssize_t read_rbu_image_type(struct kobject *kobj, { int size = 0; if (!pos) - size = sprintf(buffer, "%s\n", image_type); + size = scnprintf(buffer, count, "%s\n", image_type); return size; } @@ -648,7 +648,7 @@ static ssize_t read_rbu_packet_size(struct kobject *kobj, int size = 0; if (!pos) { spin_lock(&rbu_data.lock); - size = sprintf(buffer, "%lu\n", rbu_data.packetsize); + size = scnprintf(buffer, count, "%lu\n", rbu_data.packetsize); spin_unlock(&rbu_data.lock); } return size; -- cgit From 4312495f7db63d27ef52ec83dab55f14a8c43827 Mon Sep 17 00:00:00 2001 From: Tero Roponen Date: Sat, 17 Jan 2009 13:06:02 +0200 Subject: ACPI: Fix crash on ASUS laptops This patch fixes the crash I experienced in 2.6.29-rc2. Tested on ASUS M50vm. Signed-off-by: Tero Roponen Acked-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/ec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index a2b82c90a68..5c2f5d343be 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -982,7 +982,7 @@ int __init acpi_ec_ecdt_probe(void) saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); if (!saved_ec) return -ENOMEM; - memcpy(&saved_ec, boot_ec, sizeof(saved_ec)); + memcpy(saved_ec, boot_ec, sizeof(*saved_ec)); /* fall through */ } /* This workaround is needed only on some broken machines, -- cgit From 2b190e76def5233c542f6025b4a133b1d4bd1a37 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Sat, 17 Jan 2009 15:51:27 +0100 Subject: panasonic-laptop: fix X[ ARRAY_SIZE(X) ] Ensure pcc->keymap[ ARRAY_SIZE(pcc->keymap) ] does not occur. Signed-off-by: Roel Kluin Signed-off-by: Len Brown --- drivers/platform/x86/panasonic-laptop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index f30db367c82..c47a44dcb70 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c @@ -507,7 +507,7 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc) hkey_num = result & 0xf; - if (hkey_num < 0 || hkey_num > ARRAY_SIZE(pcc->keymap)) { + if (hkey_num < 0 || hkey_num >= ARRAY_SIZE(pcc->keymap)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "hotkey number out of range: %d\n", hkey_num)); -- cgit From c275ce44929402664902cbb09d4f054b315623d7 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 17 Jan 2009 23:10:35 -0800 Subject: sparc64: fix readout of cpu/fpu type Meelis reported that on his box /proc/cpuinfo started to reported "Unknow CPU" and the same did the boot messages. It was a stupid bug I introduced when merging cpu.c for 32 and 64 bit. The code did an array reference where it had to search for the right index. Reported-by: Meelis Roos Tested-by: Meelis Roos Signed-off-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/kernel/cpu.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c index f0b825505da..32d32b4824f 100644 --- a/arch/sparc/kernel/cpu.c +++ b/arch/sparc/kernel/cpu.c @@ -239,14 +239,26 @@ unsigned int fsr_storage; static void set_cpu_and_fpu(int psr_impl, int psr_vers, int fpu_vers) { + const struct manufacturer_info *manuf; + int i; + sparc_cpu_type = NULL; sparc_fpu_type = NULL; - if (psr_impl < ARRAY_SIZE(manufacturer_info)) + manuf = NULL; + + for (i = 0; i < ARRAY_SIZE(manufacturer_info); i++) + { + if (psr_impl == manufacturer_info[i].psr_impl) { + manuf = &manufacturer_info[i]; + break; + } + } + if (manuf != NULL) { const struct cpu_info *cpu; const struct fpu_info *fpu; - cpu = &manufacturer_info[psr_impl].cpu_info[0]; + cpu = &manuf->cpu_info[0]; while (cpu->psr_vers != -1) { if (cpu->psr_vers == psr_vers) { @@ -256,7 +268,7 @@ static void set_cpu_and_fpu(int psr_impl, int psr_vers, int fpu_vers) } cpu++; } - fpu = &manufacturer_info[psr_impl].fpu_info[0]; + fpu = &manuf->fpu_info[0]; while (fpu->fp_vers != -1) { if (fpu->fp_vers == fpu_vers) { -- cgit From 62dfcd336c79c49f9aeb0acc99cf9a1832102dd5 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 17 Jan 2009 23:12:27 -0800 Subject: sparc64: fix modpost failure Previously PeeCeeI.o was a library but it was always pulled in due to insw and friends being exported (at least for a modular kernel). But this resulted in modpost failures if there where no in-kernel users because then insw & friends were not linked in. Fix this by including PeeCeeI.o in the kernel unconditionally. The only drawback for this solution is that a nonmodular kernel will always include insw & friends no matter if they are in use or not. Reported-by: Meelis Roos Signed-off-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/lib/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile index 273fc85269f..e75faf0e59a 100644 --- a/arch/sparc/lib/Makefile +++ b/arch/sparc/lib/Makefile @@ -18,7 +18,7 @@ lib-$(CONFIG_SPARC32) += lshrdi3.o ashldi3.o lib-y += rwsem_$(BITS).o lib-$(CONFIG_SPARC32) += muldi3.o bitext.o cmpdi2.o -lib-$(CONFIG_SPARC64) += PeeCeeI.o copy_page.o clear_page.o bzero.o +lib-$(CONFIG_SPARC64) += copy_page.o clear_page.o bzero.o lib-$(CONFIG_SPARC64) += csum_copy.o csum_copy_from_user.o csum_copy_to_user.o lib-$(CONFIG_SPARC64) += VISsave.o lib-$(CONFIG_SPARC64) += bitops.o @@ -43,3 +43,4 @@ lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o obj-y += iomap.o obj-$(CONFIG_SPARC32) += atomic32.o obj-y += ksyms.o +obj-$(CONFIG_SPARC64) += PeeCeeI.o -- cgit From 989738c4f82126207b9e04c9395b78e544f3d33c Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Sat, 17 Jan 2009 18:47:27 -0500 Subject: ALSA: hda: fix invalid power mapping masks Fixed invalid power mappings for ports 0xd and 0xe on 93hd83xxx codecs. They were shifted right one too many bits. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index faef1ca8660..a4d4afe6b4f 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -334,7 +334,7 @@ static hda_nid_t stac92hd83xxx_slave_dig_outs[2] = { }; static unsigned int stac92hd83xxx_pwr_mapping[4] = { - 0x03, 0x0c, 0x10, 0x40, + 0x03, 0x0c, 0x20, 0x80, }; static hda_nid_t stac92hd83xxx_amp_nids[1] = { -- cgit From cd9f8e64c232eeb1247950007ee95de00b89ba7a Mon Sep 17 00:00:00 2001 From: Henrik Kretzschmar Date: Sun, 18 Jan 2009 10:40:24 +0100 Subject: sound: Remove removed OSS kernel parameters from doc Remove removed OSS kernel parameters from kernel-parameters.txt Remove the kernel parameters from the OSS drivers of the chips es1371 (removed 10-2007/2.6.24) and cs4232 (removed 02-2008/2.6.25) from the kernel parameters documentation. Signed-off-by: Henrik Kretzschmar Signed-off-by: Takashi Iwai --- Documentation/kernel-parameters.txt | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 8511d3532c2..d8362cf9909 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -577,9 +577,6 @@ and is between 256 and 4096 characters. It is defined in the file a memory unit (amount[KMG]). See also Documentation/kdump/kdump.txt for a example. - cs4232= [HW,OSS] - Format: ,,,,, - cs89x0_dma= [HW,NET] Format: @@ -732,10 +729,6 @@ and is between 256 and 4096 characters. It is defined in the file Default value is 0. Value can be changed at runtime via /selinux/enforce. - es1371= [HW,OSS] - Format: ,[,[]] - See also header of sound/oss/es1371.c. - ether= [HW,NET] Ethernet cards parameters This option is obsoleted by the "netdev=" option, which has equivalent usage. See its documentation for details. -- cgit From 141e6ebd1b1759bd5cebf092b7216b6f1c7b4c4f Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Mon, 5 Jan 2009 14:44:11 +0100 Subject: UBI: add ioctl for map operation This patch adds ioctl for the LEB map operation (as a debugging option so far). [Re-named ioctl to make it look the same as the other one and made some minor stylistic changes. Artem Bityutskiy.] Signed-off-by: Corentin Chary Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/cdev.c | 14 ++++++++++++++ include/mtd/ubi-user.h | 15 +++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 98cf31ed081..055e3f563c1 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -518,6 +518,20 @@ static int vol_cdev_ioctl(struct inode *inode, struct file *file, err = ubi_wl_flush(ubi); break; } + + /* Logical eraseblock map command */ + case UBI_IOCEBMAP: + { + struct ubi_map_req req; + + err = copy_from_user(&req, argp, sizeof(struct ubi_map_req)); + if (err) { + err = -EFAULT; + break; + } + err = ubi_leb_map(desc, req.lnum, req.dtype); + break; + } #endif default: diff --git a/include/mtd/ubi-user.h b/include/mtd/ubi-user.h index 2dc2eb2b8e2..758574039fc 100644 --- a/include/mtd/ubi-user.h +++ b/include/mtd/ubi-user.h @@ -133,6 +133,9 @@ #define UBI_IOCEBER _IOW(UBI_VOL_IOC_MAGIC, 1, int32_t) /* An atomic eraseblock change command */ #define UBI_IOCEBCH _IOW(UBI_VOL_IOC_MAGIC, 2, int32_t) +/* Map an eraseblock, used for debugging, disabled by default */ +#define UBI_IOCEBMAP _IOW(UBI_VOL_IOC_MAGIC, 3, struct ubi_map_req) + /* Maximum MTD device name length supported by UBI */ #define MAX_UBI_MTD_NAME_LEN 127 @@ -319,4 +322,16 @@ struct ubi_leb_change_req { int8_t padding[7]; } __attribute__ ((packed)); +/** + * struct ubi_map_req - a data structure used in map eraseblock requests. + * @lnum: logical eraseblock number to unmap + * @dtype: data type (%UBI_LONGTERM, %UBI_SHORTTERM, %UBI_UNKNOWN) + * @padding: reserved for future, not used, has to be zeroed + */ +struct ubi_map_req { + int32_t lnum; + int8_t dtype; + int8_t padding[3]; +} __attribute__ ((packed)); + #endif /* __UBI_USER_H__ */ -- cgit From c3da23be1673be4e738aea235604b4e6cb259655 Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Mon, 5 Jan 2009 14:46:19 +0100 Subject: UBI: add ioctl for unmap operation This patch adds ioctl for the LEB unmap operation (as a debugging option so far). [Re-named ioctl to make it look the same as the other one and made some minor stylistic changes. Artem Bityutskiy.] Signed-off-by: Corentin Chary Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/cdev.c | 15 ++++++++++++++- include/mtd/ubi-user.h | 3 ++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 055e3f563c1..fd7e0f923b3 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -532,13 +532,26 @@ static int vol_cdev_ioctl(struct inode *inode, struct file *file, err = ubi_leb_map(desc, req.lnum, req.dtype); break; } + + /* Logical eraseblock un-map command */ + case UBI_IOCEBUNMAP: + { + int32_t lnum; + + err = get_user(lnum, (__user int32_t *)argp); + if (err) { + err = -EFAULT; + break; + } + err = ubi_leb_unmap(desc, lnum); + break; + } #endif default: err = -ENOTTY; break; } - return err; } diff --git a/include/mtd/ubi-user.h b/include/mtd/ubi-user.h index 758574039fc..ee2ea2e224a 100644 --- a/include/mtd/ubi-user.h +++ b/include/mtd/ubi-user.h @@ -135,7 +135,8 @@ #define UBI_IOCEBCH _IOW(UBI_VOL_IOC_MAGIC, 2, int32_t) /* Map an eraseblock, used for debugging, disabled by default */ #define UBI_IOCEBMAP _IOW(UBI_VOL_IOC_MAGIC, 3, struct ubi_map_req) - +/* Unmap an eraseblock, used for debugging, disabled by default */ +#define UBI_IOCEBUNMAP _IOW(UBI_VOL_IOC_MAGIC, 4, int32_t) /* Maximum MTD device name length supported by UBI */ #define MAX_UBI_MTD_NAME_LEN 127 -- cgit From a27ce8f55dd5fddf0b8ea179cce8f399c13dc94f Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Mon, 5 Jan 2009 14:48:59 +0100 Subject: UBI: add ioctl for is_mapped operation This patch adds ioctl to check if an LEB is mapped or not (as a debugging option so far). [Re-named ioctl to make it look the same as the other one and made some minor stylistic changes. Artem Bityutskiy.] Signed-off-by: Corentin Chary Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/cdev.c | 14 ++++++++++++++ include/mtd/ubi-user.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index fd7e0f923b3..9ddbade7288 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -546,6 +546,20 @@ static int vol_cdev_ioctl(struct inode *inode, struct file *file, err = ubi_leb_unmap(desc, lnum); break; } + + /* Check if logical eraseblock is mapped command */ + case UBI_IOCEBISMAP: + { + int32_t lnum; + + err = get_user(lnum, (__user int32_t *)argp); + if (err) { + err = -EFAULT; + break; + } + err = ubi_is_mapped(desc, lnum); + break; + } #endif default: diff --git a/include/mtd/ubi-user.h b/include/mtd/ubi-user.h index ee2ea2e224a..5828d787919 100644 --- a/include/mtd/ubi-user.h +++ b/include/mtd/ubi-user.h @@ -137,6 +137,8 @@ #define UBI_IOCEBMAP _IOW(UBI_VOL_IOC_MAGIC, 3, struct ubi_map_req) /* Unmap an eraseblock, used for debugging, disabled by default */ #define UBI_IOCEBUNMAP _IOW(UBI_VOL_IOC_MAGIC, 4, int32_t) +/* Check if an eraseblock is mapped, used for debugging, disabled by default */ +#define UBI_IOCEBISMAP _IOR(UBI_VOL_IOC_MAGIC, 5, int32_t) /* Maximum MTD device name length supported by UBI */ #define MAX_UBI_MTD_NAME_LEN 127 -- cgit From f7fc6f3f33703e3365c0ef9d4bf322b88cc9dae7 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 7 Jan 2009 16:10:58 +0200 Subject: UBI: improve ioctl commentaries Signed-off-by: Artem Bityutskiy --- include/mtd/ubi-user.h | 88 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 62 insertions(+), 26 deletions(-) diff --git a/include/mtd/ubi-user.h b/include/mtd/ubi-user.h index 5828d787919..82113e160a2 100644 --- a/include/mtd/ubi-user.h +++ b/include/mtd/ubi-user.h @@ -40,37 +40,37 @@ * UBI volume creation * ~~~~~~~~~~~~~~~~~~~ * - * UBI volumes are created via the %UBI_IOCMKVOL IOCTL command of UBI character + * UBI volumes are created via the %UBI_IOCMKVOL ioctl command of UBI character * device. A &struct ubi_mkvol_req object has to be properly filled and a - * pointer to it has to be passed to the IOCTL. + * pointer to it has to be passed to the ioctl. * * UBI volume deletion * ~~~~~~~~~~~~~~~~~~~ * - * To delete a volume, the %UBI_IOCRMVOL IOCTL command of the UBI character + * To delete a volume, the %UBI_IOCRMVOL ioctl command of the UBI character * device should be used. A pointer to the 32-bit volume ID hast to be passed - * to the IOCTL. + * to the ioctl. * * UBI volume re-size * ~~~~~~~~~~~~~~~~~~ * - * To re-size a volume, the %UBI_IOCRSVOL IOCTL command of the UBI character + * To re-size a volume, the %UBI_IOCRSVOL ioctl command of the UBI character * device should be used. A &struct ubi_rsvol_req object has to be properly - * filled and a pointer to it has to be passed to the IOCTL. + * filled and a pointer to it has to be passed to the ioctl. * * UBI volumes re-name * ~~~~~~~~~~~~~~~~~~~ * * To re-name several volumes atomically at one go, the %UBI_IOCRNVOL command * of the UBI character device should be used. A &struct ubi_rnvol_req object - * has to be properly filled and a pointer to it has to be passed to the IOCTL. + * has to be properly filled and a pointer to it has to be passed to the ioctl. * * UBI volume update * ~~~~~~~~~~~~~~~~~ * - * Volume update should be done via the %UBI_IOCVOLUP IOCTL command of the + * Volume update should be done via the %UBI_IOCVOLUP ioctl command of the * corresponding UBI volume character device. A pointer to a 64-bit update - * size should be passed to the IOCTL. After this, UBI expects user to write + * size should be passed to the ioctl. After this, UBI expects user to write * this number of bytes to the volume character device. The update is finished * when the claimed number of bytes is passed. So, the volume update sequence * is something like: @@ -80,14 +80,50 @@ * write(fd, buf, image_size); * close(fd); * - * Atomic eraseblock change + * Logical eraseblock erase * ~~~~~~~~~~~~~~~~~~~~~~~~ * - * Atomic eraseblock change operation is done via the %UBI_IOCEBCH IOCTL - * command of the corresponding UBI volume character device. A pointer to - * &struct ubi_leb_change_req has to be passed to the IOCTL. Then the user is - * expected to write the requested amount of bytes. This is similar to the - * "volume update" IOCTL. + * To erase a logical eraseblock, the %UBI_IOCEBER ioctl command of the + * corresponding UBI volume character device should be used. This command + * unmaps the requested logical eraseblock, makes sure the corresponding + * physical eraseblock is successfully erased, and returns. + * + * Atomic logical eraseblock change + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * Atomic logical eraseblock change operation is called using the %UBI_IOCEBCH + * ioctl command of the corresponding UBI volume character device. A pointer to + * a &struct ubi_leb_change_req object has to be passed to the ioctl. Then the + * user is expected to write the requested amount of bytes (similarly to what + * should be done in case of the "volume update" ioctl). + * + * Logical eraseblock map + * ~~~~~~~~~~~~~~~~~~~~~ + * + * To map a logical eraseblock to a physical eraseblock, the %UBI_IOCEBMAP + * ioctl command should be used. A pointer to a &struct ubi_map_req object is + * expected to be passed. The ioctl maps the requested logical eraseblock to + * a physical eraseblock and returns. Only non-mapped logical eraseblocks can + * be mapped. If the logical eraseblock specified in the request is already + * mapped to a physical eraseblock, the ioctl fails and returns error. + * + * Logical eraseblock unmap + * ~~~~~~~~~~~~~~~~~~~~~~~~ + * + * To unmap a logical eraseblock to a physical eraseblock, the %UBI_IOCEBUNMAP + * ioctl command should be used. The ioctl unmaps the logical eraseblocks, + * schedules corresponding physical eraseblock for erasure, and returns. Unlike + * the "LEB erase" command, it does not wait for the physical eraseblock being + * erased. Note, the side effect of this is that if an unclean reboot happens + * after the unmap ioctl returns, you may find the LEB mapped again to the same + * physical eraseblock after the UBI is run again. + * + * Check if logical eraseblock is mapped + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * To check if a logical eraseblock is mapped to a physical eraseblock, the + * %UBI_IOCEBISMAP ioctl command should be used. It returns %0 if the LEB is + * not mapped, and %1 if it is mapped. */ /* @@ -101,7 +137,7 @@ /* Maximum volume name length */ #define UBI_MAX_VOLUME_NAME 127 -/* IOCTL commands of UBI character devices */ +/* ioctl commands of UBI character devices */ #define UBI_IOC_MAGIC 'o' @@ -114,7 +150,7 @@ /* Re-name volumes */ #define UBI_IOCRNVOL _IOW(UBI_IOC_MAGIC, 3, struct ubi_rnvol_req) -/* IOCTL commands of the UBI control character device */ +/* ioctl commands of the UBI control character device */ #define UBI_CTRL_IOC_MAGIC 'o' @@ -123,21 +159,21 @@ /* Detach an MTD device */ #define UBI_IOCDET _IOW(UBI_CTRL_IOC_MAGIC, 65, int32_t) -/* IOCTL commands of UBI volume character devices */ +/* ioctl commands of UBI volume character devices */ #define UBI_VOL_IOC_MAGIC 'O' /* Start UBI volume update */ #define UBI_IOCVOLUP _IOW(UBI_VOL_IOC_MAGIC, 0, int64_t) -/* An eraseblock erasure command, used for debugging, disabled by default */ +/* LEB erasure command, used for debugging, disabled by default */ #define UBI_IOCEBER _IOW(UBI_VOL_IOC_MAGIC, 1, int32_t) -/* An atomic eraseblock change command */ +/* Atomic LEB change command */ #define UBI_IOCEBCH _IOW(UBI_VOL_IOC_MAGIC, 2, int32_t) -/* Map an eraseblock, used for debugging, disabled by default */ +/* Map LEB command */ #define UBI_IOCEBMAP _IOW(UBI_VOL_IOC_MAGIC, 3, struct ubi_map_req) -/* Unmap an eraseblock, used for debugging, disabled by default */ +/* Unmap LEB command */ #define UBI_IOCEBUNMAP _IOW(UBI_VOL_IOC_MAGIC, 4, int32_t) -/* Check if an eraseblock is mapped, used for debugging, disabled by default */ +/* Check if LEB is mapped command */ #define UBI_IOCEBISMAP _IOR(UBI_VOL_IOC_MAGIC, 5, int32_t) /* Maximum MTD device name length supported by UBI */ @@ -311,8 +347,8 @@ struct ubi_rnvol_req { } __attribute__ ((packed)); /** - * struct ubi_leb_change_req - a data structure used in atomic logical - * eraseblock change requests. + * struct ubi_leb_change_req - a data structure used in atomic LEB change + * requests. * @lnum: logical eraseblock number to change * @bytes: how many bytes will be written to the logical eraseblock * @dtype: data type (%UBI_LONGTERM, %UBI_SHORTTERM, %UBI_UNKNOWN) @@ -326,7 +362,7 @@ struct ubi_leb_change_req { } __attribute__ ((packed)); /** - * struct ubi_map_req - a data structure used in map eraseblock requests. + * struct ubi_map_req - a data structure used in map LEB requests. * @lnum: logical eraseblock number to unmap * @dtype: data type (%UBI_LONGTERM, %UBI_SHORTTERM, %UBI_UNKNOWN) * @padding: reserved for future, not used, has to be zeroed -- cgit From 573135b5dbc02be12940558db23158cc9ee89c66 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 16 Jan 2009 18:02:08 +0200 Subject: UBI: remove unnecessry header inclusion Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/cdev.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 9ddbade7288..98cf7a4ceea 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include "ubi.h" -- cgit From ade44ce07c9316351ae321051221c9bad3af3a44 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 16 Jan 2009 18:03:22 +0200 Subject: UBI: allow all ioctls Some ioctl's in UBI are enabled only when debugging is switched on. There is not particular reason for this, just noone needed them. However, some people need the now for their user-space development. Thus, allow these ioctl's even if UBI debugging is disabled. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/cdev.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 98cf7a4ceea..c183be99c6c 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -486,7 +486,6 @@ static int vol_cdev_ioctl(struct inode *inode, struct file *file, break; } -#ifdef CONFIG_MTD_UBI_DEBUG_USERSPACE_IO /* Logical eraseblock erasure command */ case UBI_IOCEBER: { @@ -559,7 +558,6 @@ static int vol_cdev_ioctl(struct inode *inode, struct file *file, err = ubi_is_mapped(desc, lnum); break; } -#endif default: err = -ENOTTY; -- cgit From 4d187a88d3ee3be6a1a0b6859eb00f70e1601b5e Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sun, 11 Jan 2009 23:55:39 +0100 Subject: UBI: constify file operations Signed-off-by: Jan Engelhardt Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/cdev.c | 6 +++--- drivers/mtd/ubi/ubi.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index c183be99c6c..d99935c0f3c 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -1025,20 +1025,20 @@ static int ctrl_cdev_ioctl(struct inode *inode, struct file *file, } /* UBI control character device operations */ -struct file_operations ubi_ctrl_cdev_operations = { +const struct file_operations ubi_ctrl_cdev_operations = { .ioctl = ctrl_cdev_ioctl, .owner = THIS_MODULE, }; /* UBI character device operations */ -struct file_operations ubi_cdev_operations = { +const struct file_operations ubi_cdev_operations = { .owner = THIS_MODULE, .ioctl = ubi_cdev_ioctl, .llseek = no_llseek, }; /* UBI volume character device operations */ -struct file_operations ubi_vol_cdev_operations = { +const struct file_operations ubi_vol_cdev_operations = { .owner = THIS_MODULE, .open = vol_cdev_open, .release = vol_cdev_release, diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 4a8ec485c91..381f0e1d0a7 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -449,9 +449,9 @@ struct ubi_device { }; extern struct kmem_cache *ubi_wl_entry_slab; -extern struct file_operations ubi_ctrl_cdev_operations; -extern struct file_operations ubi_cdev_operations; -extern struct file_operations ubi_vol_cdev_operations; +extern const struct file_operations ubi_ctrl_cdev_operations; +extern const struct file_operations ubi_cdev_operations; +extern const struct file_operations ubi_vol_cdev_operations; extern struct class *ubi_class; extern struct mutex ubi_devices_mutex; -- cgit From dedb0d48a9d4d57086526b94a4b64da789a646e4 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 9 Jan 2009 21:02:37 +0200 Subject: UBIFS: do not commit twice VFS calls '->sync_fs()' twice - first time with @wait = 0, second time with @wait = 1. As a result, we may commit and synchronize write-buffers twice. Avoid doing this by returning immediatelly if @wait = 0. Signed-off-by: Artem Bityutskiy --- fs/ubifs/super.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 89556ee7251..a7fc97f4d9d 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -432,18 +432,19 @@ static int ubifs_sync_fs(struct super_block *sb, int wait) int i, err; struct ubifs_info *c = sb->s_fs_info; struct writeback_control wbc = { - .sync_mode = wait ? WB_SYNC_ALL : WB_SYNC_NONE, + .sync_mode = WB_SYNC_ALL, .range_start = 0, .range_end = LLONG_MAX, .nr_to_write = LONG_MAX, }; /* - * Note by akpm about WB_SYNC_NONE used above: zero @wait is just an - * advisory thing to help the file system shove lots of data into the - * queues. If some gets missed then it'll be picked up on the second + * Zero @wait is just an advisory thing to help the file system shove + * lots of data into the queues, and there will be the second * '->sync_fs()' call, with non-zero @wait. */ + if (!wait) + return 0; if (sb->s_flags & MS_RDONLY) return 0; -- cgit From e8b815663b1bfd9c255af5176604ec0eafdf6ed7 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 15 Jan 2009 17:43:23 +0200 Subject: UBIFS: constify operations Mark super, file, and inode operation structcutes with 'const'. Signed-off-by: Artem Bityutskiy --- fs/ubifs/dir.c | 4 ++-- fs/ubifs/file.c | 8 ++++---- fs/ubifs/super.c | 2 +- fs/ubifs/ubifs.h | 14 +++++++------- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index f448ab1f9c3..d29b771cce4 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c @@ -1199,7 +1199,7 @@ int ubifs_getattr(struct vfsmount *mnt, struct dentry *dentry, return 0; } -struct inode_operations ubifs_dir_inode_operations = { +const struct inode_operations ubifs_dir_inode_operations = { .lookup = ubifs_lookup, .create = ubifs_create, .link = ubifs_link, @@ -1219,7 +1219,7 @@ struct inode_operations ubifs_dir_inode_operations = { #endif }; -struct file_operations ubifs_dir_operations = { +const struct file_operations ubifs_dir_operations = { .llseek = ubifs_dir_llseek, .release = ubifs_dir_release, .read = generic_read_dir, diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index bf37374567f..17443d97e6f 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c @@ -1541,7 +1541,7 @@ static int ubifs_file_mmap(struct file *file, struct vm_area_struct *vma) return 0; } -struct address_space_operations ubifs_file_address_operations = { +const struct address_space_operations ubifs_file_address_operations = { .readpage = ubifs_readpage, .writepage = ubifs_writepage, .write_begin = ubifs_write_begin, @@ -1551,7 +1551,7 @@ struct address_space_operations ubifs_file_address_operations = { .releasepage = ubifs_releasepage, }; -struct inode_operations ubifs_file_inode_operations = { +const struct inode_operations ubifs_file_inode_operations = { .setattr = ubifs_setattr, .getattr = ubifs_getattr, #ifdef CONFIG_UBIFS_FS_XATTR @@ -1562,14 +1562,14 @@ struct inode_operations ubifs_file_inode_operations = { #endif }; -struct inode_operations ubifs_symlink_inode_operations = { +const struct inode_operations ubifs_symlink_inode_operations = { .readlink = generic_readlink, .follow_link = ubifs_follow_link, .setattr = ubifs_setattr, .getattr = ubifs_getattr, }; -struct file_operations ubifs_file_operations = { +const struct file_operations ubifs_file_operations = { .llseek = generic_file_llseek, .read = do_sync_read, .write = do_sync_write, diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index a7fc97f4d9d..53811e567a6 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -1778,7 +1778,7 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data) return 0; } -struct super_operations ubifs_super_operations = { +const struct super_operations ubifs_super_operations = { .alloc_inode = ubifs_alloc_inode, .destroy_inode = ubifs_destroy_inode, .put_super = ubifs_put_super, diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index fc2a4cc66d0..0881897a420 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h @@ -1405,13 +1405,13 @@ extern struct list_head ubifs_infos; extern spinlock_t ubifs_infos_lock; extern atomic_long_t ubifs_clean_zn_cnt; extern struct kmem_cache *ubifs_inode_slab; -extern struct super_operations ubifs_super_operations; -extern struct address_space_operations ubifs_file_address_operations; -extern struct file_operations ubifs_file_operations; -extern struct inode_operations ubifs_file_inode_operations; -extern struct file_operations ubifs_dir_operations; -extern struct inode_operations ubifs_dir_inode_operations; -extern struct inode_operations ubifs_symlink_inode_operations; +extern const struct super_operations ubifs_super_operations; +extern const struct address_space_operations ubifs_file_address_operations; +extern const struct file_operations ubifs_file_operations; +extern const struct inode_operations ubifs_file_inode_operations; +extern const struct file_operations ubifs_dir_operations; +extern const struct inode_operations ubifs_dir_inode_operations; +extern const struct inode_operations ubifs_symlink_inode_operations; extern struct backing_dev_info ubifs_backing_dev_info; extern struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT]; -- cgit From f429b2ea8eadb5a576542a70f7fd6f5c2a7455e1 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 16 Jan 2009 18:06:55 +0200 Subject: UBI: add ioctl compatibility UBI ioctl's do not work when running 64-bit kernel and 32-bit user-land. Fix this by adding the compat_ioctl method. Also, UBI serializes all ioctls, so more than one ioctl at a time is not a problem. Amd UBI does not seem to depend on anything else, so use unlocked_ioctl instead of ioctl (no BKL needed). Reported-by: Geert Uytterhoeven Signed-off-by: Artem Bityutskiy Reviewed-by: Arnd Bergmann --- drivers/mtd/ubi/cdev.c | 80 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 23 deletions(-) diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index d99935c0f3c..0a2d835fec8 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include "ubi.h" @@ -401,8 +402,8 @@ static ssize_t vol_cdev_write(struct file *file, const char __user *buf, return count; } -static int vol_cdev_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long vol_cdev_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { int err = 0; struct ubi_volume_desc *desc = file->private_data; @@ -800,8 +801,8 @@ out_free: return err; } -static int ubi_cdev_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long ubi_cdev_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { int err = 0; struct ubi_device *ubi; @@ -811,7 +812,7 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file, if (!capable(CAP_SYS_RESOURCE)) return -EPERM; - ubi = ubi_get_by_major(imajor(inode)); + ubi = ubi_get_by_major(imajor(file->f_mapping->host)); if (!ubi) return -ENODEV; @@ -947,8 +948,8 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file, return err; } -static int ctrl_cdev_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long ctrl_cdev_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { int err = 0; void __user *argp = (void __user *)arg; @@ -1024,26 +1025,59 @@ static int ctrl_cdev_ioctl(struct inode *inode, struct file *file, return err; } -/* UBI control character device operations */ -const struct file_operations ubi_ctrl_cdev_operations = { - .ioctl = ctrl_cdev_ioctl, - .owner = THIS_MODULE, +#ifdef CONFIG_COMPAT +static long vol_cdev_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + unsigned long translated_arg = (unsigned long)compat_ptr(arg); + + return vol_cdev_ioctl(file, cmd, translated_arg); +} + +static long ubi_cdev_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + unsigned long translated_arg = (unsigned long)compat_ptr(arg); + + return ubi_cdev_ioctl(file, cmd, translated_arg); +} + +static long ctrl_cdev_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + unsigned long translated_arg = (unsigned long)compat_ptr(arg); + + return ctrl_cdev_ioctl(file, cmd, translated_arg); +} +#else +#define vol_cdev_compat_ioctl NULL +#define ubi_cdev_compat_ioctl NULL +#define ctrl_cdev_compat_ioctl NULL +#endif + +/* UBI volume character device operations */ +const struct file_operations ubi_vol_cdev_operations = { + .owner = THIS_MODULE, + .open = vol_cdev_open, + .release = vol_cdev_release, + .llseek = vol_cdev_llseek, + .read = vol_cdev_read, + .write = vol_cdev_write, + .unlocked_ioctl = vol_cdev_ioctl, + .compat_ioctl = vol_cdev_compat_ioctl, }; /* UBI character device operations */ const struct file_operations ubi_cdev_operations = { - .owner = THIS_MODULE, - .ioctl = ubi_cdev_ioctl, - .llseek = no_llseek, + .owner = THIS_MODULE, + .llseek = no_llseek, + .unlocked_ioctl = ubi_cdev_ioctl, + .compat_ioctl = ubi_cdev_compat_ioctl, }; -/* UBI volume character device operations */ -const struct file_operations ubi_vol_cdev_operations = { - .owner = THIS_MODULE, - .open = vol_cdev_open, - .release = vol_cdev_release, - .llseek = vol_cdev_llseek, - .read = vol_cdev_read, - .write = vol_cdev_write, - .ioctl = vol_cdev_ioctl, +/* UBI control character device operations */ +const struct file_operations ubi_ctrl_cdev_operations = { + .owner = THIS_MODULE, + .unlocked_ioctl = ctrl_cdev_ioctl, + .compat_ioctl = ctrl_cdev_compat_ioctl, }; -- cgit From 3013ee31b6c5fd9a49a81816d6c13e1cdb7a1288 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 16 Jan 2009 19:08:43 +0200 Subject: UBI: use nicer 64-bit math Get rid of 'do_div()' and use more user-friendly primitives from 'linux/math64.h'. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/cdev.c | 20 +++++--------------- drivers/mtd/ubi/gluebi.c | 11 +++-------- drivers/mtd/ubi/scan.c | 8 +++----- drivers/mtd/ubi/upd.c | 21 +++++++-------------- drivers/mtd/ubi/vmt.c | 17 +++++++---------- 5 files changed, 25 insertions(+), 52 deletions(-) diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 0a2d835fec8..f9631eb3fef 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -41,8 +41,8 @@ #include #include #include +#include #include -#include #include "ubi.h" /** @@ -195,7 +195,6 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count, int err, lnum, off, len, tbuf_size; size_t count_save = count; void *tbuf; - uint64_t tmp; dbg_gen("read %zd bytes from offset %lld of volume %d", count, *offp, vol->vol_id); @@ -225,10 +224,7 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count, return -ENOMEM; len = count > tbuf_size ? tbuf_size : count; - - tmp = *offp; - off = do_div(tmp, vol->usable_leb_size); - lnum = tmp; + lnum = div_u64_rem(*offp, vol->usable_leb_size, &off); do { cond_resched(); @@ -279,7 +275,6 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, int lnum, off, len, tbuf_size, err = 0; size_t count_save = count; char *tbuf; - uint64_t tmp; dbg_gen("requested: write %zd bytes to offset %lld of volume %u", count, *offp, vol->vol_id); @@ -287,10 +282,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, if (vol->vol_type == UBI_STATIC_VOLUME) return -EROFS; - tmp = *offp; - off = do_div(tmp, vol->usable_leb_size); - lnum = tmp; - + lnum = div_u64_rem(*offp, vol->usable_leb_size, &off); if (off & (ubi->min_io_size - 1)) { dbg_err("unaligned position"); return -EINVAL; @@ -882,7 +874,6 @@ static long ubi_cdev_ioctl(struct file *file, unsigned int cmd, case UBI_IOCRSVOL: { int pebs; - uint64_t tmp; struct ubi_rsvol_req req; dbg_gen("re-size volume"); @@ -902,9 +893,8 @@ static long ubi_cdev_ioctl(struct file *file, unsigned int cmd, break; } - tmp = req.bytes; - pebs = !!do_div(tmp, desc->vol->usable_leb_size); - pebs += tmp; + pebs = div_u64(req.bytes + desc->vol->usable_leb_size - 1, + desc->vol->usable_leb_size); mutex_lock(&ubi->volumes_mutex); err = ubi_resize_volume(desc, pebs); diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c index 6dd4f5e77f8..49cd55ade9c 100644 --- a/drivers/mtd/ubi/gluebi.c +++ b/drivers/mtd/ubi/gluebi.c @@ -28,7 +28,7 @@ * eraseblock size is equivalent to the logical eraseblock size of the volume. */ -#include +#include #include "ubi.h" /** @@ -109,7 +109,6 @@ static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len, int err = 0, lnum, offs, total_read; struct ubi_volume *vol; struct ubi_device *ubi; - uint64_t tmp = from; dbg_gen("read %zd bytes from offset %lld", len, from); @@ -119,9 +118,7 @@ static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len, vol = container_of(mtd, struct ubi_volume, gluebi_mtd); ubi = vol->ubi; - offs = do_div(tmp, mtd->erasesize); - lnum = tmp; - + lnum = div_u64_rem(from, mtd->erasesize, &offs); total_read = len; while (total_read) { size_t to_read = mtd->erasesize - offs; @@ -160,7 +157,6 @@ static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len, int err = 0, lnum, offs, total_written; struct ubi_volume *vol; struct ubi_device *ubi; - uint64_t tmp = to; dbg_gen("write %zd bytes to offset %lld", len, to); @@ -173,8 +169,7 @@ static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len, if (ubi->ro_mode) return -EROFS; - offs = do_div(tmp, mtd->erasesize); - lnum = tmp; + lnum = div_u64_rem(to, mtd->erasesize, &offs); if (len % mtd->writesize || offs % mtd->writesize) return -EINVAL; diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index ecde202a5a1..c3d653ba5ca 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -42,7 +42,7 @@ #include #include -#include +#include #include "ubi.h" #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID @@ -904,10 +904,8 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi) dbg_msg("scanning is finished"); /* Calculate mean erase counter */ - if (si->ec_count) { - do_div(si->ec_sum, si->ec_count); - si->mean_ec = si->ec_sum; - } + if (si->ec_count) + si->mean_ec = div_u64(si->ec_sum, si->ec_count); if (si->is_empty) ubi_msg("empty MTD device detected"); diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c index 8b89cc18ff0..6b4d1ae891a 100644 --- a/drivers/mtd/ubi/upd.c +++ b/drivers/mtd/ubi/upd.c @@ -40,7 +40,7 @@ #include #include -#include +#include #include "ubi.h" /** @@ -89,7 +89,6 @@ static int clear_update_marker(struct ubi_device *ubi, struct ubi_volume *vol, long long bytes) { int err; - uint64_t tmp; struct ubi_vtbl_record vtbl_rec; dbg_gen("clear update marker for volume %d", vol->vol_id); @@ -101,9 +100,9 @@ static int clear_update_marker(struct ubi_device *ubi, struct ubi_volume *vol, if (vol->vol_type == UBI_STATIC_VOLUME) { vol->corrupted = 0; - vol->used_bytes = tmp = bytes; - vol->last_eb_bytes = do_div(tmp, vol->usable_leb_size); - vol->used_ebs = tmp; + vol->used_bytes = bytes; + vol->used_ebs = div_u64_rem(bytes, vol->usable_leb_size, + &vol->last_eb_bytes); if (vol->last_eb_bytes) vol->used_ebs += 1; else @@ -131,7 +130,6 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol, long long bytes) { int i, err; - uint64_t tmp; dbg_gen("start update of volume %d, %llu bytes", vol->vol_id, bytes); ubi_assert(!vol->updating && !vol->changing_leb); @@ -161,9 +159,8 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol, if (!vol->upd_buf) return -ENOMEM; - tmp = bytes; - vol->upd_ebs = !!do_div(tmp, vol->usable_leb_size); - vol->upd_ebs += tmp; + vol->upd_ebs = div_u64(bytes + vol->usable_leb_size - 1, + vol->usable_leb_size); vol->upd_bytes = bytes; vol->upd_received = 0; return 0; @@ -282,7 +279,6 @@ static int write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, int ubi_more_update_data(struct ubi_device *ubi, struct ubi_volume *vol, const void __user *buf, int count) { - uint64_t tmp; int lnum, offs, err = 0, len, to_write = count; dbg_gen("write %d of %lld bytes, %lld already passed", @@ -291,10 +287,7 @@ int ubi_more_update_data(struct ubi_device *ubi, struct ubi_volume *vol, if (ubi->ro_mode) return -EROFS; - tmp = vol->upd_received; - offs = do_div(tmp, vol->usable_leb_size); - lnum = tmp; - + lnum = div_u64_rem(vol->upd_received, vol->usable_leb_size, &offs); if (vol->upd_received + count > vol->upd_bytes) to_write = count = vol->upd_bytes - vol->upd_received; diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index 22e1d7398fc..df5483562b7 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -24,7 +24,7 @@ */ #include -#include +#include #include "ubi.h" #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID @@ -205,7 +205,6 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) int i, err, vol_id = req->vol_id, do_free = 1; struct ubi_volume *vol; struct ubi_vtbl_record vtbl_rec; - uint64_t bytes; dev_t dev; if (ubi->ro_mode) @@ -255,10 +254,8 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) /* Calculate how many eraseblocks are requested */ vol->usable_leb_size = ubi->leb_size - ubi->leb_size % req->alignment; - bytes = req->bytes; - if (do_div(bytes, vol->usable_leb_size)) - vol->reserved_pebs = 1; - vol->reserved_pebs += bytes; + vol->reserved_pebs += div_u64(req->bytes + vol->usable_leb_size - 1, + vol->usable_leb_size); /* Reserve physical eraseblocks */ if (vol->reserved_pebs > ubi->avail_pebs) { @@ -301,10 +298,10 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) vol->used_bytes = (long long)vol->used_ebs * vol->usable_leb_size; } else { - bytes = vol->used_bytes; - vol->last_eb_bytes = do_div(bytes, vol->usable_leb_size); - vol->used_ebs = bytes; - if (vol->last_eb_bytes) + vol->used_ebs = div_u64_rem(vol->used_bytes, + vol->usable_leb_size, + &vol->last_eb_bytes); + if (vol->last_eb_bytes != 0) vol->used_ebs += 1; else vol->last_eb_bytes = vol->usable_leb_size; -- cgit From 1b437c8c73a36daa471dd54a63c426d72af5723d Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Mon, 19 Jan 2009 00:38:57 +0900 Subject: x86-64: Move irq stats from PDA to per-cpu and consolidate with 32-bit. Signed-off-by: Brian Gerst Signed-off-by: Tejun Heo --- arch/x86/include/asm/hardirq_64.h | 24 +++++++++++++++++++----- arch/x86/include/asm/pda.h | 10 ---------- arch/x86/kernel/irq.c | 6 +----- arch/x86/kernel/irq_64.c | 3 +++ arch/x86/kernel/nmi.c | 10 +--------- arch/x86/xen/smp.c | 18 +++--------------- 6 files changed, 27 insertions(+), 44 deletions(-) diff --git a/arch/x86/include/asm/hardirq_64.h b/arch/x86/include/asm/hardirq_64.h index b5a6b5d5670..a65bab20f6c 100644 --- a/arch/x86/include/asm/hardirq_64.h +++ b/arch/x86/include/asm/hardirq_64.h @@ -3,22 +3,36 @@ #include #include -#include #include +typedef struct { + unsigned int __softirq_pending; + unsigned int __nmi_count; /* arch dependent */ + unsigned int apic_timer_irqs; /* arch dependent */ + unsigned int irq0_irqs; + unsigned int irq_resched_count; + unsigned int irq_call_count; + unsigned int irq_tlb_count; + unsigned int irq_thermal_count; + unsigned int irq_spurious_count; + unsigned int irq_threshold_count; +} ____cacheline_aligned irq_cpustat_t; + +DECLARE_PER_CPU(irq_cpustat_t, irq_stat); + /* We can have at most NR_VECTORS irqs routed to a cpu at a time */ #define MAX_HARDIRQS_PER_CPU NR_VECTORS #define __ARCH_IRQ_STAT 1 -#define inc_irq_stat(member) add_pda(member, 1) +#define inc_irq_stat(member) percpu_add(irq_stat.member, 1) -#define local_softirq_pending() read_pda(__softirq_pending) +#define local_softirq_pending() percpu_read(irq_stat.__softirq_pending) #define __ARCH_SET_SOFTIRQ_PENDING 1 -#define set_softirq_pending(x) write_pda(__softirq_pending, (x)) -#define or_softirq_pending(x) or_pda(__softirq_pending, (x)) +#define set_softirq_pending(x) percpu_write(irq_stat.__softirq_pending, (x)) +#define or_softirq_pending(x) percpu_or(irq_stat.__softirq_pending, (x)) extern void ack_bad_irq(unsigned int irq); diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h index 47f274fe695..69a40757e21 100644 --- a/arch/x86/include/asm/pda.h +++ b/arch/x86/include/asm/pda.h @@ -25,19 +25,9 @@ struct x8664_pda { char *irqstackptr; short nodenumber; /* number of current node (32k max) */ short in_bootmem; /* pda lives in bootmem */ - unsigned int __softirq_pending; - unsigned int __nmi_count; /* number of NMI on this CPUs */ short mmu_state; short isidle; struct mm_struct *active_mm; - unsigned apic_timer_irqs; - unsigned irq0_irqs; - unsigned irq_resched_count; - unsigned irq_call_count; - unsigned irq_tlb_count; - unsigned irq_thermal_count; - unsigned irq_threshold_count; - unsigned irq_spurious_count; } ____cacheline_aligned_in_smp; DECLARE_PER_CPU(struct x8664_pda, __pda); diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 3973e2df7f8..8b30d0c2512 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -36,11 +36,7 @@ void ack_bad_irq(unsigned int irq) #endif } -#ifdef CONFIG_X86_32 -# define irq_stats(x) (&per_cpu(irq_stat, x)) -#else -# define irq_stats(x) cpu_pda(x) -#endif +#define irq_stats(x) (&per_cpu(irq_stat, x)) /* * /proc/interrupts printing: */ diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c index 0b21cb1ea11..1db05247b47 100644 --- a/arch/x86/kernel/irq_64.c +++ b/arch/x86/kernel/irq_64.c @@ -19,6 +19,9 @@ #include #include +DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); +EXPORT_PER_CPU_SYMBOL(irq_stat); + /* * Probabilistic stack overflow check: * diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c index 7228979f1e7..23b6d9e6e4f 100644 --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c @@ -61,11 +61,7 @@ static int endflag __initdata; static inline unsigned int get_nmi_count(int cpu) { -#ifdef CONFIG_X86_64 - return cpu_pda(cpu)->__nmi_count; -#else - return nmi_count(cpu); -#endif + return per_cpu(irq_stat, cpu).__nmi_count; } static inline int mce_in_progress(void) @@ -82,12 +78,8 @@ static inline int mce_in_progress(void) */ static inline unsigned int get_timer_irqs(int cpu) { -#ifdef CONFIG_X86_64 - return read_pda(apic_timer_irqs) + read_pda(irq0_irqs); -#else return per_cpu(irq_stat, cpu).apic_timer_irqs + per_cpu(irq_stat, cpu).irq0_irqs; -#endif } #ifdef CONFIG_SMP diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 3bfd6dd0b47..9ff3b0999cf 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -50,11 +50,7 @@ static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id); */ static irqreturn_t xen_reschedule_interrupt(int irq, void *dev_id) { -#ifdef CONFIG_X86_32 - __get_cpu_var(irq_stat).irq_resched_count++; -#else - add_pda(irq_resched_count, 1); -#endif + inc_irq_stat(irq_resched_count); return IRQ_HANDLED; } @@ -435,11 +431,7 @@ static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id) { irq_enter(); generic_smp_call_function_interrupt(); -#ifdef CONFIG_X86_32 - __get_cpu_var(irq_stat).irq_call_count++; -#else - add_pda(irq_call_count, 1); -#endif + inc_irq_stat(irq_call_count); irq_exit(); return IRQ_HANDLED; @@ -449,11 +441,7 @@ static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id) { irq_enter(); generic_smp_call_function_single_interrupt(); -#ifdef CONFIG_X86_32 - __get_cpu_var(irq_stat).irq_call_count++; -#else - add_pda(irq_call_count, 1); -#endif + inc_irq_stat(irq_call_count); irq_exit(); return IRQ_HANDLED; -- cgit From 9eb912d1aa6b8106e06a73ea6702ec3dab0d6a1a Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Mon, 19 Jan 2009 00:38:57 +0900 Subject: x86-64: Move TLB state from PDA to per-cpu and consolidate with 32-bit. Signed-off-by: Brian Gerst Signed-off-by: Tejun Heo --- arch/x86/include/asm/mmu_context_64.h | 16 +++++++--------- arch/x86/include/asm/pda.h | 2 -- arch/x86/include/asm/tlbflush.h | 7 ++----- arch/x86/kernel/cpu/common.c | 2 -- arch/x86/kernel/tlb_32.c | 12 ++---------- arch/x86/kernel/tlb_64.c | 13 ++++++++----- arch/x86/xen/mmu.c | 6 +----- 7 files changed, 20 insertions(+), 38 deletions(-) diff --git a/arch/x86/include/asm/mmu_context_64.h b/arch/x86/include/asm/mmu_context_64.h index 677d36e9540..c4572505ab3 100644 --- a/arch/x86/include/asm/mmu_context_64.h +++ b/arch/x86/include/asm/mmu_context_64.h @@ -1,13 +1,11 @@ #ifndef _ASM_X86_MMU_CONTEXT_64_H #define _ASM_X86_MMU_CONTEXT_64_H -#include - static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) { #ifdef CONFIG_SMP - if (read_pda(mmu_state) == TLBSTATE_OK) - write_pda(mmu_state, TLBSTATE_LAZY); + if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK) + percpu_write(cpu_tlbstate.state, TLBSTATE_LAZY); #endif } @@ -19,8 +17,8 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, /* stop flush ipis for the previous mm */ cpu_clear(cpu, prev->cpu_vm_mask); #ifdef CONFIG_SMP - write_pda(mmu_state, TLBSTATE_OK); - write_pda(active_mm, next); + percpu_write(cpu_tlbstate.state, TLBSTATE_OK); + percpu_write(cpu_tlbstate.active_mm, next); #endif cpu_set(cpu, next->cpu_vm_mask); load_cr3(next->pgd); @@ -30,9 +28,9 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, } #ifdef CONFIG_SMP else { - write_pda(mmu_state, TLBSTATE_OK); - if (read_pda(active_mm) != next) - BUG(); + percpu_write(cpu_tlbstate.state, TLBSTATE_OK); + BUG_ON(percpu_read(cpu_tlbstate.active_mm) != next); + if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) { /* We were in lazy tlb mode and leave_mm disabled * tlb flush IPI delivery. We must reload CR3 diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h index 69a40757e21..8ee835ed10e 100644 --- a/arch/x86/include/asm/pda.h +++ b/arch/x86/include/asm/pda.h @@ -25,9 +25,7 @@ struct x8664_pda { char *irqstackptr; short nodenumber; /* number of current node (32k max) */ short in_bootmem; /* pda lives in bootmem */ - short mmu_state; short isidle; - struct mm_struct *active_mm; } ____cacheline_aligned_in_smp; DECLARE_PER_CPU(struct x8664_pda, __pda); diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h index 17feaa9c7e7..d3539f998f8 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h @@ -148,20 +148,17 @@ void native_flush_tlb_others(const struct cpumask *cpumask, #define TLBSTATE_OK 1 #define TLBSTATE_LAZY 2 -#ifdef CONFIG_X86_32 struct tlb_state { struct mm_struct *active_mm; int state; - char __cacheline_padding[L1_CACHE_BYTES-8]; }; DECLARE_PER_CPU(struct tlb_state, cpu_tlbstate); -void reset_lazy_tlbstate(void); -#else static inline void reset_lazy_tlbstate(void) { + percpu_write(cpu_tlbstate.state, 0); + percpu_write(cpu_tlbstate.active_mm, &init_mm); } -#endif #endif /* SMP */ diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index c49498d4083..3d0cc6f1711 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -897,8 +897,6 @@ void __cpuinit pda_init(int cpu) pda->irqcount = -1; pda->kernelstack = (unsigned long)stack_thread_info() - PDA_STACKOFFSET + THREAD_SIZE; - pda->active_mm = &init_mm; - pda->mmu_state = 0; if (cpu == 0) { /* others are initialized in smpboot.c */ diff --git a/arch/x86/kernel/tlb_32.c b/arch/x86/kernel/tlb_32.c index e65449d0f7d..abf0808d6fc 100644 --- a/arch/x86/kernel/tlb_32.c +++ b/arch/x86/kernel/tlb_32.c @@ -4,8 +4,8 @@ #include -DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) - ____cacheline_aligned = { &init_mm, 0, }; +DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) + = { &init_mm, 0, }; /* must come after the send_IPI functions above for inlining */ #include @@ -231,14 +231,6 @@ void flush_tlb_all(void) on_each_cpu(do_flush_tlb_all, NULL, 1); } -void reset_lazy_tlbstate(void) -{ - int cpu = raw_smp_processor_id(); - - per_cpu(cpu_tlbstate, cpu).state = 0; - per_cpu(cpu_tlbstate, cpu).active_mm = &init_mm; -} - static int init_flush_cpumask(void) { alloc_cpumask_var(&flush_cpumask, GFP_KERNEL); diff --git a/arch/x86/kernel/tlb_64.c b/arch/x86/kernel/tlb_64.c index 7f4141d3b66..e64a32c4882 100644 --- a/arch/x86/kernel/tlb_64.c +++ b/arch/x86/kernel/tlb_64.c @@ -18,6 +18,9 @@ #include #include +DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) + = { &init_mm, 0, }; + #include /* * Smarter SMP flushing macros. @@ -62,9 +65,9 @@ static DEFINE_PER_CPU(union smp_flush_state, flush_state); */ void leave_mm(int cpu) { - if (read_pda(mmu_state) == TLBSTATE_OK) + if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK) BUG(); - cpu_clear(cpu, read_pda(active_mm)->cpu_vm_mask); + cpu_clear(cpu, percpu_read(cpu_tlbstate.active_mm)->cpu_vm_mask); load_cr3(swapper_pg_dir); } EXPORT_SYMBOL_GPL(leave_mm); @@ -142,8 +145,8 @@ asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs) * BUG(); */ - if (f->flush_mm == read_pda(active_mm)) { - if (read_pda(mmu_state) == TLBSTATE_OK) { + if (f->flush_mm == percpu_read(cpu_tlbstate.active_mm)) { + if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK) { if (f->flush_va == TLB_FLUSH_ALL) local_flush_tlb(); else @@ -281,7 +284,7 @@ static void do_flush_tlb_all(void *info) unsigned long cpu = smp_processor_id(); __flush_tlb_all(); - if (read_pda(mmu_state) == TLBSTATE_LAZY) + if (percpu_read(cpu_tlbstate.state) == TLBSTATE_LAZY) leave_mm(cpu); } diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 7bc7852cc5c..98cb9869eb2 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -1063,11 +1063,7 @@ static void drop_other_mm_ref(void *info) struct mm_struct *mm = info; struct mm_struct *active_mm; -#ifdef CONFIG_X86_64 - active_mm = read_pda(active_mm); -#else - active_mm = __get_cpu_var(cpu_tlbstate).active_mm; -#endif + active_mm = percpu_read(cpu_tlbstate.active_mm); if (active_mm == mm) leave_mm(smp_processor_id()); -- cgit From 26f80bd6a9ab17bc8a60b6092e7c0d05c5927ce5 Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Mon, 19 Jan 2009 00:38:58 +0900 Subject: x86-64: Convert irqstacks to per-cpu Move the irqstackptr variable from the PDA to per-cpu. Make the stacks themselves per-cpu, removing some specific allocation code. Add a seperate flag (is_boot_cpu) to simplify the per-cpu boot adjustments. tj: * sprinkle some underbars around. * irq_stack_ptr is not used till traps_init(), no reason to initialize it early. On SMP, just leaving it NULL till proper initialization in setup_per_cpu_areas() works. Dropped is_boot_cpu and early irq_stack_ptr initialization. * do DECLARE/DEFINE_PER_CPU(char[IRQ_STACK_SIZE], irq_stack) instead of (char, irq_stack[IRQ_STACK_SIZE]). Signed-off-by: Brian Gerst Signed-off-by: Tejun Heo --- arch/x86/include/asm/page_64.h | 4 ++-- arch/x86/include/asm/pda.h | 1 - arch/x86/include/asm/processor.h | 3 +++ arch/x86/kernel/asm-offsets_64.c | 1 - arch/x86/kernel/cpu/common.c | 19 +++++++------------ arch/x86/kernel/dumpstack_64.c | 33 +++++++++++++++++---------------- arch/x86/kernel/entry_64.S | 6 +++--- arch/x86/kernel/setup_percpu.c | 4 +++- 8 files changed, 35 insertions(+), 36 deletions(-) diff --git a/arch/x86/include/asm/page_64.h b/arch/x86/include/asm/page_64.h index 5ebca29f44f..e27fdbe5f9e 100644 --- a/arch/x86/include/asm/page_64.h +++ b/arch/x86/include/asm/page_64.h @@ -13,8 +13,8 @@ #define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 1) #define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER) -#define IRQSTACK_ORDER 2 -#define IRQSTACKSIZE (PAGE_SIZE << IRQSTACK_ORDER) +#define IRQ_STACK_ORDER 2 +#define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER) #define STACKFAULT_STACK 1 #define DOUBLEFAULT_STACK 2 diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h index 8ee835ed10e..09965f7a216 100644 --- a/arch/x86/include/asm/pda.h +++ b/arch/x86/include/asm/pda.h @@ -22,7 +22,6 @@ struct x8664_pda { /* gcc-ABI: this canary MUST be at offset 40!!! */ #endif - char *irqstackptr; short nodenumber; /* number of current node (32k max) */ short in_bootmem; /* pda lives in bootmem */ short isidle; diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 091cd8855f2..f511246fa6c 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -378,6 +378,9 @@ union thread_xstate { #ifdef CONFIG_X86_64 DECLARE_PER_CPU(struct orig_ist, orig_ist); + +DECLARE_PER_CPU(char[IRQ_STACK_SIZE], irq_stack); +DECLARE_PER_CPU(char *, irq_stack_ptr); #endif extern void print_cpu_info(struct cpuinfo_x86 *); diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index f4cc81bfbf8..5b821fbdaf7 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c @@ -54,7 +54,6 @@ int main(void) ENTRY(pcurrent); ENTRY(irqcount); ENTRY(cpunumber); - ENTRY(irqstackptr); DEFINE(pda_size, sizeof(struct x8664_pda)); BLANK(); #undef ENTRY diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 3d0cc6f1711..496f0a01919 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -881,7 +881,13 @@ __setup("clearcpuid=", setup_disablecpuid); #ifdef CONFIG_X86_64 struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; -static char boot_cpu_stack[IRQSTACKSIZE] __page_aligned_bss; +DEFINE_PER_CPU_PAGE_ALIGNED(char[IRQ_STACK_SIZE], irq_stack); +#ifdef CONFIG_SMP +DEFINE_PER_CPU(char *, irq_stack_ptr); /* will be set during per cpu init */ +#else +DEFINE_PER_CPU(char *, irq_stack_ptr) = + per_cpu_var(irq_stack) + IRQ_STACK_SIZE - 64; +#endif void __cpuinit pda_init(int cpu) { @@ -901,18 +907,7 @@ void __cpuinit pda_init(int cpu) if (cpu == 0) { /* others are initialized in smpboot.c */ pda->pcurrent = &init_task; - pda->irqstackptr = boot_cpu_stack; - pda->irqstackptr += IRQSTACKSIZE - 64; } else { - if (!pda->irqstackptr) { - pda->irqstackptr = (char *) - __get_free_pages(GFP_ATOMIC, IRQSTACK_ORDER); - if (!pda->irqstackptr) - panic("cannot allocate irqstack for cpu %d", - cpu); - pda->irqstackptr += IRQSTACKSIZE - 64; - } - if (pda->nodenumber == 0 && cpu_to_node(cpu) != NUMA_NO_NODE) pda->nodenumber = cpu_to_node(cpu); } diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index c302d070704..28e26a4315d 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c @@ -106,7 +106,8 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, const struct stacktrace_ops *ops, void *data) { const unsigned cpu = get_cpu(); - unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr; + unsigned long *irq_stack_end = + (unsigned long *)per_cpu(irq_stack_ptr, cpu); unsigned used = 0; struct thread_info *tinfo; int graph = 0; @@ -160,23 +161,23 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, stack = (unsigned long *) estack_end[-2]; continue; } - if (irqstack_end) { - unsigned long *irqstack; - irqstack = irqstack_end - - (IRQSTACKSIZE - 64) / sizeof(*irqstack); + if (irq_stack_end) { + unsigned long *irq_stack; + irq_stack = irq_stack_end - + (IRQ_STACK_SIZE - 64) / sizeof(*irq_stack); - if (stack >= irqstack && stack < irqstack_end) { + if (stack >= irq_stack && stack < irq_stack_end) { if (ops->stack(data, "IRQ") < 0) break; bp = print_context_stack(tinfo, stack, bp, - ops, data, irqstack_end, &graph); + ops, data, irq_stack_end, &graph); /* * We link to the next stack (which would be * the process stack normally) the last * pointer (index -1 to end) in the IRQ stack: */ - stack = (unsigned long *) (irqstack_end[-1]); - irqstack_end = NULL; + stack = (unsigned long *) (irq_stack_end[-1]); + irq_stack_end = NULL; ops->stack(data, "EOI"); continue; } @@ -199,10 +200,10 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, unsigned long *stack; int i; const int cpu = smp_processor_id(); - unsigned long *irqstack_end = - (unsigned long *) (cpu_pda(cpu)->irqstackptr); - unsigned long *irqstack = - (unsigned long *) (cpu_pda(cpu)->irqstackptr - IRQSTACKSIZE); + unsigned long *irq_stack_end = + (unsigned long *)(per_cpu(irq_stack_ptr, cpu)); + unsigned long *irq_stack = + (unsigned long *)(per_cpu(irq_stack_ptr, cpu) - IRQ_STACK_SIZE); /* * debugging aid: "show_stack(NULL, NULL);" prints the @@ -218,9 +219,9 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, stack = sp; for (i = 0; i < kstack_depth_to_print; i++) { - if (stack >= irqstack && stack <= irqstack_end) { - if (stack == irqstack_end) { - stack = (unsigned long *) (irqstack_end[-1]); + if (stack >= irq_stack && stack <= irq_stack_end) { + if (stack == irq_stack_end) { + stack = (unsigned long *) (irq_stack_end[-1]); printk(" "); } } else { diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 4833f3a1965..d22677a6643 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -345,7 +345,7 @@ ENTRY(save_args) 1: incl %gs:pda_irqcount jne 2f popq_cfi %rax /* move return address... */ - mov %gs:pda_irqstackptr,%rsp + mov PER_CPU_VAR(irq_stack_ptr),%rsp EMPTY_FRAME 0 pushq_cfi %rax /* ... to the new stack */ /* @@ -1261,7 +1261,7 @@ ENTRY(call_softirq) mov %rsp,%rbp CFI_DEF_CFA_REGISTER rbp incl %gs:pda_irqcount - cmove %gs:pda_irqstackptr,%rsp + cmove PER_CPU_VAR(irq_stack_ptr),%rsp push %rbp # backlink for old unwinder call __do_softirq leaveq @@ -1300,7 +1300,7 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) 11: incl %gs:pda_irqcount movq %rsp,%rbp CFI_DEF_CFA_REGISTER rbp - cmovzq %gs:pda_irqstackptr,%rsp + cmovzq PER_CPU_VAR(irq_stack_ptr),%rsp pushq %rbp # backlink for old unwinder call xen_evtchn_do_upcall popq %rsp diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index b5c35af2011..8b53ef83c61 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -192,7 +192,10 @@ void __init setup_per_cpu_areas(void) memcpy(ptr, __per_cpu_load, __per_cpu_end - __per_cpu_start); per_cpu_offset(cpu) = ptr - __per_cpu_start; + per_cpu(this_cpu_off, cpu) = per_cpu_offset(cpu); #ifdef CONFIG_X86_64 + per_cpu(irq_stack_ptr, cpu) = + (char *)per_cpu(irq_stack, cpu) + IRQ_STACK_SIZE - 64; /* * CPU0 modified pda in the init data area, reload pda * offset for CPU0 and clear the area for others. @@ -202,7 +205,6 @@ void __init setup_per_cpu_areas(void) else memset(cpu_pda(cpu), 0, sizeof(*cpu_pda(cpu))); #endif - per_cpu(this_cpu_off, cpu) = per_cpu_offset(cpu); DBG("PERCPU: cpu %4d %p\n", cpu, ptr); } -- cgit From 92d65b2371d86d40807e1dbfdccadc4d501edcde Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Mon, 19 Jan 2009 00:38:58 +0900 Subject: x86-64: Convert exception stacks to per-cpu Move the exception stacks to per-cpu, removing specific allocation code. Signed-off-by: Brian Gerst Signed-off-by: Tejun Heo --- arch/x86/kernel/cpu/common.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 496f0a01919..b6d7eec0be7 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -913,8 +913,9 @@ void __cpuinit pda_init(int cpu) } } -static char boot_exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + - DEBUG_STKSZ] __page_aligned_bss; +static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks + [(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]) + __aligned(PAGE_SIZE); extern asmlinkage void ignore_sysret(void); @@ -972,15 +973,12 @@ void __cpuinit cpu_init(void) struct tss_struct *t = &per_cpu(init_tss, cpu); struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu); unsigned long v; - char *estacks = NULL; struct task_struct *me; int i; /* CPU 0 is initialised in head64.c */ if (cpu != 0) pda_init(cpu); - else - estacks = boot_exception_stacks; me = current; @@ -1014,18 +1012,13 @@ void __cpuinit cpu_init(void) * set up and load the per-CPU TSS */ if (!orig_ist->ist[0]) { - static const unsigned int order[N_EXCEPTION_STACKS] = { - [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STACK_ORDER, - [DEBUG_STACK - 1] = DEBUG_STACK_ORDER + static const unsigned int sizes[N_EXCEPTION_STACKS] = { + [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STKSZ, + [DEBUG_STACK - 1] = DEBUG_STKSZ }; + char *estacks = per_cpu(exception_stacks, cpu); for (v = 0; v < N_EXCEPTION_STACKS; v++) { - if (cpu) { - estacks = (char *)__get_free_pages(GFP_ATOMIC, order[v]); - if (!estacks) - panic("Cannot allocate exception " - "stack %ld %d\n", v, cpu); - } - estacks += PAGE_SIZE << order[v]; + estacks += sizes[v]; orig_ist->ist[v] = t->x86_tss.ist[v] = (unsigned long)estacks; } -- cgit From ea9279066de44053d0c20ea855bc9f4706652d84 Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Mon, 19 Jan 2009 00:38:58 +0900 Subject: x86-64: Move cpu number from PDA to per-cpu and consolidate with 32-bit. tj: moved cpu_number definition out of CONFIG_HAVE_SETUP_PER_CPU_AREA for voyager. Signed-off-by: Brian Gerst Signed-off-by: Tejun Heo --- arch/x86/include/asm/pda.h | 2 +- arch/x86/include/asm/smp.h | 4 +--- arch/x86/kernel/asm-offsets_64.c | 1 - arch/x86/kernel/cpu/common.c | 1 - arch/x86/kernel/process_32.c | 3 --- arch/x86/kernel/setup_percpu.c | 10 ++++++++++ arch/x86/kernel/smpcommon.c | 2 -- 7 files changed, 12 insertions(+), 11 deletions(-) diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h index 09965f7a216..668d5a5b6f7 100644 --- a/arch/x86/include/asm/pda.h +++ b/arch/x86/include/asm/pda.h @@ -16,7 +16,7 @@ struct x8664_pda { unsigned long kernelstack; /* 16 top of kernel stack for current */ unsigned long oldrsp; /* 24 user rsp for system call */ int irqcount; /* 32 Irq nesting counter. Starts -1 */ - unsigned int cpunumber; /* 36 Logical CPU number */ + unsigned int unused6; /* 36 was cpunumber */ #ifdef CONFIG_CC_STACKPROTECTOR unsigned long stack_canary; /* 40 stack canary value */ /* gcc-ABI: this canary MUST be at diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index c7bbbbe65d3..68636e767a9 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -25,9 +25,7 @@ extern unsigned int num_processors; DECLARE_PER_CPU(cpumask_t, cpu_sibling_map); DECLARE_PER_CPU(cpumask_t, cpu_core_map); DECLARE_PER_CPU(u16, cpu_llc_id); -#ifdef CONFIG_X86_32 DECLARE_PER_CPU(int, cpu_number); -#endif static inline struct cpumask *cpu_sibling_mask(int cpu) { @@ -164,7 +162,7 @@ extern unsigned disabled_cpus __cpuinitdata; extern int safe_smp_processor_id(void); #elif defined(CONFIG_X86_64_SMP) -#define raw_smp_processor_id() read_pda(cpunumber) +#define raw_smp_processor_id() (percpu_read(cpu_number)) #define stack_smp_processor_id() \ ({ \ diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index 5b821fbdaf7..cae6697c099 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c @@ -53,7 +53,6 @@ int main(void) ENTRY(oldrsp); ENTRY(pcurrent); ENTRY(irqcount); - ENTRY(cpunumber); DEFINE(pda_size, sizeof(struct x8664_pda)); BLANK(); #undef ENTRY diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index b6d7eec0be7..4221e920886 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -899,7 +899,6 @@ void __cpuinit pda_init(int cpu) load_pda_offset(cpu); - pda->cpunumber = cpu; pda->irqcount = -1; pda->kernelstack = (unsigned long)stack_thread_info() - PDA_STACKOFFSET + THREAD_SIZE; diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 77d546817d9..2c00a57ccb9 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -66,9 +66,6 @@ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task; EXPORT_PER_CPU_SYMBOL(current_task); -DEFINE_PER_CPU(int, cpu_number); -EXPORT_PER_CPU_SYMBOL(cpu_number); - /* * Return saved PC of a blocked thread. */ diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 8b53ef83c61..258497f93f4 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -22,6 +22,15 @@ # define DBG(x...) #endif +/* + * Could be inside CONFIG_HAVE_SETUP_PER_CPU_AREA with other stuff but + * voyager wants cpu_number too. + */ +#ifdef CONFIG_SMP +DEFINE_PER_CPU(int, cpu_number); +EXPORT_PER_CPU_SYMBOL(cpu_number); +#endif + #ifdef CONFIG_X86_LOCAL_APIC unsigned int num_processors; unsigned disabled_cpus __cpuinitdata; @@ -193,6 +202,7 @@ void __init setup_per_cpu_areas(void) memcpy(ptr, __per_cpu_load, __per_cpu_end - __per_cpu_start); per_cpu_offset(cpu) = ptr - __per_cpu_start; per_cpu(this_cpu_off, cpu) = per_cpu_offset(cpu); + per_cpu(cpu_number, cpu) = cpu; #ifdef CONFIG_X86_64 per_cpu(irq_stack_ptr, cpu) = (char *)per_cpu(irq_stack, cpu) + IRQ_STACK_SIZE - 64; diff --git a/arch/x86/kernel/smpcommon.c b/arch/x86/kernel/smpcommon.c index 7e157810062..add36b4e37c 100644 --- a/arch/x86/kernel/smpcommon.c +++ b/arch/x86/kernel/smpcommon.c @@ -28,7 +28,5 @@ __cpuinit void init_gdt(int cpu) write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S); - - per_cpu(cpu_number, cpu) = cpu; } #endif -- cgit From c6f5e0acd5d12ee23f701f15889872e67b47caa6 Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Mon, 19 Jan 2009 00:38:58 +0900 Subject: x86-64: Move current task from PDA to per-cpu and consolidate with 32-bit. Signed-off-by: Brian Gerst Signed-off-by: Tejun Heo --- arch/x86/include/asm/current.h | 24 +++--------------------- arch/x86/include/asm/pda.h | 4 ++-- arch/x86/include/asm/system.h | 4 ++-- arch/x86/kernel/asm-offsets_64.c | 1 - arch/x86/kernel/cpu/common.c | 5 +---- arch/x86/kernel/dumpstack_64.c | 2 +- arch/x86/kernel/process_64.c | 5 ++++- arch/x86/kernel/smpboot.c | 3 +-- arch/x86/xen/smp.c | 3 +-- 9 files changed, 15 insertions(+), 36 deletions(-) diff --git a/arch/x86/include/asm/current.h b/arch/x86/include/asm/current.h index 0728480f5c5..c68c361697e 100644 --- a/arch/x86/include/asm/current.h +++ b/arch/x86/include/asm/current.h @@ -1,39 +1,21 @@ #ifndef _ASM_X86_CURRENT_H #define _ASM_X86_CURRENT_H -#ifdef CONFIG_X86_32 #include #include +#ifndef __ASSEMBLY__ struct task_struct; DECLARE_PER_CPU(struct task_struct *, current_task); -static __always_inline struct task_struct *get_current(void) -{ - return percpu_read(current_task); -} - -#else /* X86_32 */ - -#ifndef __ASSEMBLY__ -#include - -struct task_struct; static __always_inline struct task_struct *get_current(void) { - return read_pda(pcurrent); + return percpu_read(current_task); } -#else /* __ASSEMBLY__ */ - -#include -#define GET_CURRENT(reg) movq %gs:(pda_pcurrent),reg +#define current get_current() #endif /* __ASSEMBLY__ */ -#endif /* X86_32 */ - -#define current get_current() - #endif /* _ASM_X86_CURRENT_H */ diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h index 668d5a5b6f7..7209302d922 100644 --- a/arch/x86/include/asm/pda.h +++ b/arch/x86/include/asm/pda.h @@ -11,8 +11,8 @@ /* Per processor datastructure. %gs points to it while the kernel runs */ struct x8664_pda { - struct task_struct *pcurrent; /* 0 Current process */ - unsigned long dummy; + unsigned long unused1; + unsigned long unused2; unsigned long kernelstack; /* 16 top of kernel stack for current */ unsigned long oldrsp; /* 24 user rsp for system call */ int irqcount; /* 32 Irq nesting counter. Starts -1 */ diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h index 8e626ea33a1..4399aac680e 100644 --- a/arch/x86/include/asm/system.h +++ b/arch/x86/include/asm/system.h @@ -94,7 +94,7 @@ do { \ "call __switch_to\n\t" \ ".globl thread_return\n" \ "thread_return:\n\t" \ - "movq %%gs:%P[pda_pcurrent],%%rsi\n\t" \ + "movq "__percpu_seg_str"%P[current_task],%%rsi\n\t" \ "movq %P[thread_info](%%rsi),%%r8\n\t" \ LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \ "movq %%rax,%%rdi\n\t" \ @@ -106,7 +106,7 @@ do { \ [ti_flags] "i" (offsetof(struct thread_info, flags)), \ [tif_fork] "i" (TIF_FORK), \ [thread_info] "i" (offsetof(struct task_struct, stack)), \ - [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \ + [current_task] "m" (per_cpu_var(current_task)) \ : "memory", "cc" __EXTRA_CLOBBER) #endif diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index cae6697c099..4f7a210e1e5 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c @@ -51,7 +51,6 @@ int main(void) #define ENTRY(entry) DEFINE(pda_ ## entry, offsetof(struct x8664_pda, entry)) ENTRY(kernelstack); ENTRY(oldrsp); - ENTRY(pcurrent); ENTRY(irqcount); DEFINE(pda_size, sizeof(struct x8664_pda)); BLANK(); diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 4221e920886..b50e38d1688 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -903,10 +903,7 @@ void __cpuinit pda_init(int cpu) pda->kernelstack = (unsigned long)stack_thread_info() - PDA_STACKOFFSET + THREAD_SIZE; - if (cpu == 0) { - /* others are initialized in smpboot.c */ - pda->pcurrent = &init_task; - } else { + if (cpu != 0) { if (pda->nodenumber == 0 && cpu_to_node(cpu) != NUMA_NO_NODE) pda->nodenumber = cpu_to_node(cpu); } diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index 28e26a4315d..d35db5993fd 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c @@ -242,7 +242,7 @@ void show_registers(struct pt_regs *regs) int i; unsigned long sp; const int cpu = smp_processor_id(); - struct task_struct *cur = cpu_pda(cpu)->pcurrent; + struct task_struct *cur = current; sp = regs->sp; printk("CPU %d ", cpu); diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 416fb9282f4..e00c31a4b3c 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -57,6 +57,9 @@ asmlinkage extern void ret_from_fork(void); +DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task; +EXPORT_PER_CPU_SYMBOL(current_task); + unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED; static ATOMIC_NOTIFIER_HEAD(idle_notifier); @@ -615,7 +618,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) */ prev->usersp = read_pda(oldrsp); write_pda(oldrsp, next->usersp); - write_pda(pcurrent, next_p); + percpu_write(current_task, next_p); write_pda(kernelstack, (unsigned long)task_stack_page(next_p) + diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 2f0e0f1090f..5854be0fb80 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -790,13 +790,12 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu) set_idle_for_cpu(cpu, c_idle.idle); do_rest: -#ifdef CONFIG_X86_32 per_cpu(current_task, cpu) = c_idle.idle; +#ifdef CONFIG_X86_32 init_gdt(cpu); /* Stack for startup_32 can be just as for start_secondary onwards */ irq_ctx_init(cpu); #else - cpu_pda(cpu)->pcurrent = c_idle.idle; clear_tsk_thread_flag(c_idle.idle, TIF_FORK); initial_gs = per_cpu_offset(cpu); #endif diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 9ff3b0999cf..72c2eb9b64c 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -279,12 +279,11 @@ static int __cpuinit xen_cpu_up(unsigned int cpu) struct task_struct *idle = idle_task(cpu); int rc; + per_cpu(current_task, cpu) = idle; #ifdef CONFIG_X86_32 init_gdt(cpu); - per_cpu(current_task, cpu) = idle; irq_ctx_init(cpu); #else - cpu_pda(cpu)->pcurrent = idle; clear_tsk_thread_flag(idle, TIF_FORK); #endif xen_setup_timer(cpu); -- cgit From 9af45651f1f7c89942e016a1a00a7ebddfa727f8 Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Mon, 19 Jan 2009 00:38:58 +0900 Subject: x86-64: Move kernelstack from PDA to per-cpu. Also clean up PER_CPU_VAR usage in xen-asm_64.S tj: * remove now unused stack_thread_info() * s/kernelstack/kernel_stack/ * added FIXME comment in xen-asm_64.S Signed-off-by: Brian Gerst Signed-off-by: Tejun Heo --- arch/x86/ia32/ia32entry.S | 8 ++++---- arch/x86/include/asm/pda.h | 4 +--- arch/x86/include/asm/thread_info.h | 20 ++++++++------------ arch/x86/kernel/asm-offsets_64.c | 1 - arch/x86/kernel/cpu/common.c | 6 ++++-- arch/x86/kernel/entry_64.S | 4 ++-- arch/x86/kernel/process_64.c | 4 ++-- arch/x86/kernel/smpboot.c | 3 +++ arch/x86/xen/xen-asm_64.S | 23 +++++++++++------------ 9 files changed, 35 insertions(+), 38 deletions(-) diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index 256b00b6189..9c79b247700 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S @@ -112,8 +112,8 @@ ENTRY(ia32_sysenter_target) CFI_DEF_CFA rsp,0 CFI_REGISTER rsp,rbp SWAPGS_UNSAFE_STACK - movq %gs:pda_kernelstack, %rsp - addq $(PDA_STACKOFFSET),%rsp + movq PER_CPU_VAR(kernel_stack), %rsp + addq $(KERNEL_STACK_OFFSET),%rsp /* * No need to follow this irqs on/off section: the syscall * disabled irqs, here we enable it straight after entry: @@ -273,13 +273,13 @@ ENDPROC(ia32_sysenter_target) ENTRY(ia32_cstar_target) CFI_STARTPROC32 simple CFI_SIGNAL_FRAME - CFI_DEF_CFA rsp,PDA_STACKOFFSET + CFI_DEF_CFA rsp,KERNEL_STACK_OFFSET CFI_REGISTER rip,rcx /*CFI_REGISTER rflags,r11*/ SWAPGS_UNSAFE_STACK movl %esp,%r8d CFI_REGISTER rsp,r8 - movq %gs:pda_kernelstack,%rsp + movq PER_CPU_VAR(kernel_stack),%rsp /* * No need to follow this irqs on/off section: the syscall * disabled irqs and here we enable it straight after entry: diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h index 7209302d922..4d28ffba6e1 100644 --- a/arch/x86/include/asm/pda.h +++ b/arch/x86/include/asm/pda.h @@ -13,7 +13,7 @@ struct x8664_pda { unsigned long unused1; unsigned long unused2; - unsigned long kernelstack; /* 16 top of kernel stack for current */ + unsigned long unused3; unsigned long oldrsp; /* 24 user rsp for system call */ int irqcount; /* 32 Irq nesting counter. Starts -1 */ unsigned int unused6; /* 36 was cpunumber */ @@ -44,6 +44,4 @@ extern void pda_init(int); #endif -#define PDA_STACKOFFSET (5*8) - #endif /* _ASM_X86_PDA_H */ diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index 98789647baa..b46f8ca007b 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -194,25 +194,21 @@ static inline struct thread_info *current_thread_info(void) #else /* X86_32 */ -#include +#include +#define KERNEL_STACK_OFFSET (5*8) /* * macros/functions for gaining access to the thread information structure * preempt_count needs to be 1 initially, until the scheduler is functional. */ #ifndef __ASSEMBLY__ -static inline struct thread_info *current_thread_info(void) -{ - struct thread_info *ti; - ti = (void *)(read_pda(kernelstack) + PDA_STACKOFFSET - THREAD_SIZE); - return ti; -} +DECLARE_PER_CPU(unsigned long, kernel_stack); -/* do not use in interrupt context */ -static inline struct thread_info *stack_thread_info(void) +static inline struct thread_info *current_thread_info(void) { struct thread_info *ti; - asm("andq %%rsp,%0; " : "=r" (ti) : "0" (~(THREAD_SIZE - 1))); + ti = (void *)(percpu_read(kernel_stack) + + KERNEL_STACK_OFFSET - THREAD_SIZE); return ti; } @@ -220,8 +216,8 @@ static inline struct thread_info *stack_thread_info(void) /* how to get the thread information struct from ASM */ #define GET_THREAD_INFO(reg) \ - movq %gs:pda_kernelstack,reg ; \ - subq $(THREAD_SIZE-PDA_STACKOFFSET),reg + movq PER_CPU_VAR(kernel_stack),reg ; \ + subq $(THREAD_SIZE-KERNEL_STACK_OFFSET),reg #endif diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index 4f7a210e1e5..cafff5f4a03 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c @@ -49,7 +49,6 @@ int main(void) BLANK(); #undef ENTRY #define ENTRY(entry) DEFINE(pda_ ## entry, offsetof(struct x8664_pda, entry)) - ENTRY(kernelstack); ENTRY(oldrsp); ENTRY(irqcount); DEFINE(pda_size, sizeof(struct x8664_pda)); diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index b50e38d1688..06b6290088f 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -889,6 +889,10 @@ DEFINE_PER_CPU(char *, irq_stack_ptr) = per_cpu_var(irq_stack) + IRQ_STACK_SIZE - 64; #endif +DEFINE_PER_CPU(unsigned long, kernel_stack) = + (unsigned long)&init_thread_union - KERNEL_STACK_OFFSET + THREAD_SIZE; +EXPORT_PER_CPU_SYMBOL(kernel_stack); + void __cpuinit pda_init(int cpu) { struct x8664_pda *pda = cpu_pda(cpu); @@ -900,8 +904,6 @@ void __cpuinit pda_init(int cpu) load_pda_offset(cpu); pda->irqcount = -1; - pda->kernelstack = (unsigned long)stack_thread_info() - - PDA_STACKOFFSET + THREAD_SIZE; if (cpu != 0) { if (pda->nodenumber == 0 && cpu_to_node(cpu) != NUMA_NO_NODE) diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index d22677a6643..0dd45859a7a 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -468,7 +468,7 @@ END(ret_from_fork) ENTRY(system_call) CFI_STARTPROC simple CFI_SIGNAL_FRAME - CFI_DEF_CFA rsp,PDA_STACKOFFSET + CFI_DEF_CFA rsp,KERNEL_STACK_OFFSET CFI_REGISTER rip,rcx /*CFI_REGISTER rflags,r11*/ SWAPGS_UNSAFE_STACK @@ -480,7 +480,7 @@ ENTRY(system_call) ENTRY(system_call_after_swapgs) movq %rsp,%gs:pda_oldrsp - movq %gs:pda_kernelstack,%rsp + movq PER_CPU_VAR(kernel_stack),%rsp /* * No need to follow this irqs off/on section - it's straight * and short: diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index e00c31a4b3c..6c5f5760210 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -620,9 +620,9 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) write_pda(oldrsp, next->usersp); percpu_write(current_task, next_p); - write_pda(kernelstack, + percpu_write(kernel_stack, (unsigned long)task_stack_page(next_p) + - THREAD_SIZE - PDA_STACKOFFSET); + THREAD_SIZE - KERNEL_STACK_OFFSET); #ifdef CONFIG_CC_STACKPROTECTOR write_pda(stack_canary, next_p->stack_canary); /* diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 5854be0fb80..869b98840fd 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -798,6 +798,9 @@ do_rest: #else clear_tsk_thread_flag(c_idle.idle, TIF_FORK); initial_gs = per_cpu_offset(cpu); + per_cpu(kernel_stack, cpu) = + (unsigned long)task_stack_page(c_idle.idle) - + KERNEL_STACK_OFFSET + THREAD_SIZE; #endif early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); initial_code = (unsigned long)start_secondary; diff --git a/arch/x86/xen/xen-asm_64.S b/arch/x86/xen/xen-asm_64.S index 05794c566e8..5a23e899367 100644 --- a/arch/x86/xen/xen-asm_64.S +++ b/arch/x86/xen/xen-asm_64.S @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -28,12 +29,10 @@ #if 1 /* - x86-64 does not yet support direct access to percpu variables - via a segment override, so we just need to make sure this code - never gets used + FIXME: x86_64 now can support direct access to percpu variables + via a segment override. Update xen accordingly. */ #define BUG ud2a -#define PER_CPU_VAR(var, off) 0xdeadbeef #endif /* @@ -45,14 +44,14 @@ ENTRY(xen_irq_enable_direct) BUG /* Unmask events */ - movb $0, PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_mask) + movb $0, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask /* Preempt here doesn't matter because that will deal with any pending interrupts. The pending check may end up being run on the wrong CPU, but that doesn't hurt. */ /* Test for pending */ - testb $0xff, PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_pending) + testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending jz 1f 2: call check_events @@ -69,7 +68,7 @@ ENDPATCH(xen_irq_enable_direct) ENTRY(xen_irq_disable_direct) BUG - movb $1, PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_mask) + movb $1, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask ENDPATCH(xen_irq_disable_direct) ret ENDPROC(xen_irq_disable_direct) @@ -87,7 +86,7 @@ ENDPATCH(xen_irq_disable_direct) ENTRY(xen_save_fl_direct) BUG - testb $0xff, PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_mask) + testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask setz %ah addb %ah,%ah ENDPATCH(xen_save_fl_direct) @@ -107,13 +106,13 @@ ENTRY(xen_restore_fl_direct) BUG testb $X86_EFLAGS_IF>>8, %ah - setz PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_mask) + setz PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask /* Preempt here doesn't matter because that will deal with any pending interrupts. The pending check may end up being run on the wrong CPU, but that doesn't hurt. */ /* check for unmasked and pending */ - cmpw $0x0001, PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_pending) + cmpw $0x0001, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending jz 1f 2: call check_events 1: @@ -196,7 +195,7 @@ ENTRY(xen_sysret64) /* We're already on the usermode stack at this point, but still with the kernel gs, so we can easily switch back */ movq %rsp, %gs:pda_oldrsp - movq %gs:pda_kernelstack,%rsp + movq PER_CPU_VAR(kernel_stack),%rsp pushq $__USER_DS pushq %gs:pda_oldrsp @@ -213,7 +212,7 @@ ENTRY(xen_sysret32) /* We're already on the usermode stack at this point, but still with the kernel gs, so we can easily switch back */ movq %rsp, %gs:pda_oldrsp - movq %gs:pda_kernelstack, %rsp + movq PER_CPU_VAR(kernel_stack), %rsp pushq $__USER32_DS pushq %gs:pda_oldrsp -- cgit From 3d1e42a7cf945e289d6ba26159aa0e2b0645401b Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Mon, 19 Jan 2009 00:38:58 +0900 Subject: x86-64: Move oldrsp from PDA to per-cpu. tj: * in asm-offsets_64.c, pda.h inclusion shouldn't be removed as pda is still referenced in the file * s/oldrsp/old_rsp/ Signed-off-by: Brian Gerst Signed-off-by: Tejun Heo --- arch/x86/include/asm/pda.h | 2 +- arch/x86/kernel/asm-offsets_64.c | 1 - arch/x86/kernel/entry_64.S | 10 +++++----- arch/x86/kernel/process_64.c | 8 +++++--- arch/x86/xen/xen-asm_64.S | 8 ++++---- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h index 4d28ffba6e1..ae23deb9955 100644 --- a/arch/x86/include/asm/pda.h +++ b/arch/x86/include/asm/pda.h @@ -14,7 +14,7 @@ struct x8664_pda { unsigned long unused1; unsigned long unused2; unsigned long unused3; - unsigned long oldrsp; /* 24 user rsp for system call */ + unsigned long unused4; int irqcount; /* 32 Irq nesting counter. Starts -1 */ unsigned int unused6; /* 36 was cpunumber */ #ifdef CONFIG_CC_STACKPROTECTOR diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index cafff5f4a03..afda6deb851 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c @@ -49,7 +49,6 @@ int main(void) BLANK(); #undef ENTRY #define ENTRY(entry) DEFINE(pda_ ## entry, offsetof(struct x8664_pda, entry)) - ENTRY(oldrsp); ENTRY(irqcount); DEFINE(pda_size, sizeof(struct x8664_pda)); BLANK(); diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 0dd45859a7a..7c27da407da 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -210,7 +210,7 @@ ENTRY(native_usergs_sysret64) /* %rsp:at FRAMEEND */ .macro FIXUP_TOP_OF_STACK tmp offset=0 - movq %gs:pda_oldrsp,\tmp + movq PER_CPU_VAR(old_rsp),\tmp movq \tmp,RSP+\offset(%rsp) movq $__USER_DS,SS+\offset(%rsp) movq $__USER_CS,CS+\offset(%rsp) @@ -221,7 +221,7 @@ ENTRY(native_usergs_sysret64) .macro RESTORE_TOP_OF_STACK tmp offset=0 movq RSP+\offset(%rsp),\tmp - movq \tmp,%gs:pda_oldrsp + movq \tmp,PER_CPU_VAR(old_rsp) movq EFLAGS+\offset(%rsp),\tmp movq \tmp,R11+\offset(%rsp) .endm @@ -479,7 +479,7 @@ ENTRY(system_call) */ ENTRY(system_call_after_swapgs) - movq %rsp,%gs:pda_oldrsp + movq %rsp,PER_CPU_VAR(old_rsp) movq PER_CPU_VAR(kernel_stack),%rsp /* * No need to follow this irqs off/on section - it's straight @@ -523,7 +523,7 @@ sysret_check: CFI_REGISTER rip,rcx RESTORE_ARGS 0,-ARG_SKIP,1 /*CFI_REGISTER rflags,r11*/ - movq %gs:pda_oldrsp, %rsp + movq PER_CPU_VAR(old_rsp), %rsp USERGS_SYSRET64 CFI_RESTORE_STATE @@ -833,7 +833,7 @@ common_interrupt: XCPT_FRAME addq $-0x80,(%rsp) /* Adjust vector to [-256,-1] range */ interrupt do_IRQ - /* 0(%rsp): oldrsp-ARGOFFSET */ + /* 0(%rsp): old_rsp-ARGOFFSET */ ret_from_intr: DISABLE_INTERRUPTS(CLBR_NONE) TRACE_IRQS_OFF diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 6c5f5760210..48012891892 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -60,6 +60,8 @@ asmlinkage extern void ret_from_fork(void); DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task; EXPORT_PER_CPU_SYMBOL(current_task); +DEFINE_PER_CPU(unsigned long, old_rsp); + unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED; static ATOMIC_NOTIFIER_HEAD(idle_notifier); @@ -395,7 +397,7 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp) load_gs_index(0); regs->ip = new_ip; regs->sp = new_sp; - write_pda(oldrsp, new_sp); + percpu_write(old_rsp, new_sp); regs->cs = __USER_CS; regs->ss = __USER_DS; regs->flags = 0x200; @@ -616,8 +618,8 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) /* * Switch the PDA and FPU contexts. */ - prev->usersp = read_pda(oldrsp); - write_pda(oldrsp, next->usersp); + prev->usersp = percpu_read(old_rsp); + percpu_write(old_rsp, next->usersp); percpu_write(current_task, next_p); percpu_write(kernel_stack, diff --git a/arch/x86/xen/xen-asm_64.S b/arch/x86/xen/xen-asm_64.S index 5a23e899367..d6fc51f4ce8 100644 --- a/arch/x86/xen/xen-asm_64.S +++ b/arch/x86/xen/xen-asm_64.S @@ -194,11 +194,11 @@ RELOC(xen_sysexit, 1b+1) ENTRY(xen_sysret64) /* We're already on the usermode stack at this point, but still with the kernel gs, so we can easily switch back */ - movq %rsp, %gs:pda_oldrsp + movq %rsp, PER_CPU_VAR(old_rsp) movq PER_CPU_VAR(kernel_stack),%rsp pushq $__USER_DS - pushq %gs:pda_oldrsp + pushq PER_CPU_VAR(old_rsp) pushq %r11 pushq $__USER_CS pushq %rcx @@ -211,11 +211,11 @@ RELOC(xen_sysret64, 1b+1) ENTRY(xen_sysret32) /* We're already on the usermode stack at this point, but still with the kernel gs, so we can easily switch back */ - movq %rsp, %gs:pda_oldrsp + movq %rsp, PER_CPU_VAR(old_rsp) movq PER_CPU_VAR(kernel_stack), %rsp pushq $__USER32_DS - pushq %gs:pda_oldrsp + pushq PER_CPU_VAR(old_rsp) pushq %r11 pushq $__USER32_CS pushq %rcx -- cgit From 5689553076c4a67b83426b076082c63085b7567a Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Mon, 19 Jan 2009 00:38:58 +0900 Subject: x86-64: Move irqcount from PDA to per-cpu. tj: s/irqcount/irq_count/ Signed-off-by: Brian Gerst Signed-off-by: Tejun Heo --- arch/x86/include/asm/pda.h | 2 +- arch/x86/kernel/asm-offsets_64.c | 1 - arch/x86/kernel/cpu/common.c | 4 ++-- arch/x86/kernel/entry_64.S | 14 +++++++------- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h index ae23deb9955..4527d70314d 100644 --- a/arch/x86/include/asm/pda.h +++ b/arch/x86/include/asm/pda.h @@ -15,7 +15,7 @@ struct x8664_pda { unsigned long unused2; unsigned long unused3; unsigned long unused4; - int irqcount; /* 32 Irq nesting counter. Starts -1 */ + int unused5; unsigned int unused6; /* 36 was cpunumber */ #ifdef CONFIG_CC_STACKPROTECTOR unsigned long stack_canary; /* 40 stack canary value */ diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index afda6deb851..64c834a39aa 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c @@ -49,7 +49,6 @@ int main(void) BLANK(); #undef ENTRY #define ENTRY(entry) DEFINE(pda_ ## entry, offsetof(struct x8664_pda, entry)) - ENTRY(irqcount); DEFINE(pda_size, sizeof(struct x8664_pda)); BLANK(); #undef ENTRY diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 06b6290088f..e2323ecce1d 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -893,6 +893,8 @@ DEFINE_PER_CPU(unsigned long, kernel_stack) = (unsigned long)&init_thread_union - KERNEL_STACK_OFFSET + THREAD_SIZE; EXPORT_PER_CPU_SYMBOL(kernel_stack); +DEFINE_PER_CPU(unsigned int, irq_count) = -1; + void __cpuinit pda_init(int cpu) { struct x8664_pda *pda = cpu_pda(cpu); @@ -903,8 +905,6 @@ void __cpuinit pda_init(int cpu) load_pda_offset(cpu); - pda->irqcount = -1; - if (cpu != 0) { if (pda->nodenumber == 0 && cpu_to_node(cpu) != NUMA_NO_NODE) pda->nodenumber = cpu_to_node(cpu); diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 7c27da407da..c52b6091916 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -337,12 +337,12 @@ ENTRY(save_args) je 1f SWAPGS /* - * irqcount is used to check if a CPU is already on an interrupt stack + * irq_count is used to check if a CPU is already on an interrupt stack * or not. While this is essentially redundant with preempt_count it is * a little cheaper to use a separate counter in the PDA (short of * moving irq_enter into assembly, which would be too much work) */ -1: incl %gs:pda_irqcount +1: incl PER_CPU_VAR(irq_count) jne 2f popq_cfi %rax /* move return address... */ mov PER_CPU_VAR(irq_stack_ptr),%rsp @@ -837,7 +837,7 @@ common_interrupt: ret_from_intr: DISABLE_INTERRUPTS(CLBR_NONE) TRACE_IRQS_OFF - decl %gs:pda_irqcount + decl PER_CPU_VAR(irq_count) leaveq CFI_DEF_CFA_REGISTER rsp CFI_ADJUST_CFA_OFFSET -8 @@ -1260,14 +1260,14 @@ ENTRY(call_softirq) CFI_REL_OFFSET rbp,0 mov %rsp,%rbp CFI_DEF_CFA_REGISTER rbp - incl %gs:pda_irqcount + incl PER_CPU_VAR(irq_count) cmove PER_CPU_VAR(irq_stack_ptr),%rsp push %rbp # backlink for old unwinder call __do_softirq leaveq CFI_DEF_CFA_REGISTER rsp CFI_ADJUST_CFA_OFFSET -8 - decl %gs:pda_irqcount + decl PER_CPU_VAR(irq_count) ret CFI_ENDPROC END(call_softirq) @@ -1297,7 +1297,7 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) movq %rdi, %rsp # we don't return, adjust the stack frame CFI_ENDPROC DEFAULT_FRAME -11: incl %gs:pda_irqcount +11: incl PER_CPU_VAR(irq_count) movq %rsp,%rbp CFI_DEF_CFA_REGISTER rbp cmovzq PER_CPU_VAR(irq_stack_ptr),%rsp @@ -1305,7 +1305,7 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) call xen_evtchn_do_upcall popq %rsp CFI_DEF_CFA_REGISTER rsp - decl %gs:pda_irqcount + decl PER_CPU_VAR(irq_count) jmp error_exit CFI_ENDPROC END(do_hypervisor_callback) -- cgit From e7a22c1ebcc1caa8178df1819d05128bb5b45ab9 Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Mon, 19 Jan 2009 00:38:59 +0900 Subject: x86-64: Move nodenumber from PDA to per-cpu. tj: * s/nodenumber/node_number/ * removed now unused pda variable from pda_init() Signed-off-by: Brian Gerst Signed-off-by: Tejun Heo --- arch/x86/include/asm/pda.h | 1 - arch/x86/include/asm/topology.h | 3 ++- arch/x86/kernel/cpu/common.c | 13 ++++++------- arch/x86/kernel/setup_percpu.c | 4 +++- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h index 4527d70314d..b30ef6bddc4 100644 --- a/arch/x86/include/asm/pda.h +++ b/arch/x86/include/asm/pda.h @@ -22,7 +22,6 @@ struct x8664_pda { /* gcc-ABI: this canary MUST be at offset 40!!! */ #endif - short nodenumber; /* number of current node (32k max) */ short in_bootmem; /* pda lives in bootmem */ short isidle; } ____cacheline_aligned_in_smp; diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index 87ca3fd86e8..ffea1fe03a9 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h @@ -83,7 +83,8 @@ extern cpumask_t *node_to_cpumask_map; DECLARE_EARLY_PER_CPU(int, x86_cpu_to_node_map); /* Returns the number of the current Node. */ -#define numa_node_id() read_pda(nodenumber) +DECLARE_PER_CPU(int, node_number); +#define numa_node_id() percpu_read(node_number) #ifdef CONFIG_DEBUG_PER_CPU_MAPS extern int cpu_to_node(int cpu); diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index e2323ecce1d..7976a6a0f65 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -897,18 +897,11 @@ DEFINE_PER_CPU(unsigned int, irq_count) = -1; void __cpuinit pda_init(int cpu) { - struct x8664_pda *pda = cpu_pda(cpu); - /* Setup up data that may be needed in __get_free_pages early */ loadsegment(fs, 0); loadsegment(gs, 0); load_pda_offset(cpu); - - if (cpu != 0) { - if (pda->nodenumber == 0 && cpu_to_node(cpu) != NUMA_NO_NODE) - pda->nodenumber = cpu_to_node(cpu); - } } static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks @@ -978,6 +971,12 @@ void __cpuinit cpu_init(void) if (cpu != 0) pda_init(cpu); +#ifdef CONFIG_NUMA + if (cpu != 0 && percpu_read(node_number) == 0 && + cpu_to_node(cpu) != NUMA_NO_NODE) + percpu_write(node_number, cpu_to_node(cpu)); +#endif + me = current; if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)) diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 258497f93f4..efbafbbff58 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -53,6 +53,8 @@ EXPORT_EARLY_PER_CPU_SYMBOL(x86_bios_cpu_apicid); #if defined(CONFIG_NUMA) && defined(CONFIG_X86_64) #define X86_64_NUMA 1 /* (used later) */ +DEFINE_PER_CPU(int, node_number) = 0; +EXPORT_PER_CPU_SYMBOL(node_number); /* * Map cpu index to node index @@ -283,7 +285,7 @@ void __cpuinit numa_set_node(int cpu, int node) per_cpu(x86_cpu_to_node_map, cpu) = node; if (node != NUMA_NO_NODE) - cpu_pda(cpu)->nodenumber = node; + per_cpu(node_number, cpu) = node; } void __cpuinit numa_clear_node(int cpu) -- cgit From c2558e0eba66b49993e619da66c95a50a97830a3 Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Mon, 19 Jan 2009 00:38:59 +0900 Subject: x86-64: Move isidle from PDA to per-cpu. tj: s/isidle/is_idle/ Signed-off-by: Brian Gerst Signed-off-by: Tejun Heo --- arch/x86/include/asm/pda.h | 1 - arch/x86/kernel/process_64.c | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h index b30ef6bddc4..c31ca048a90 100644 --- a/arch/x86/include/asm/pda.h +++ b/arch/x86/include/asm/pda.h @@ -23,7 +23,6 @@ struct x8664_pda { offset 40!!! */ #endif short in_bootmem; /* pda lives in bootmem */ - short isidle; } ____cacheline_aligned_in_smp; DECLARE_PER_CPU(struct x8664_pda, __pda); diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 48012891892..4523ff88a69 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -61,6 +61,7 @@ DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task; EXPORT_PER_CPU_SYMBOL(current_task); DEFINE_PER_CPU(unsigned long, old_rsp); +static DEFINE_PER_CPU(unsigned char, is_idle); unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED; @@ -80,13 +81,13 @@ EXPORT_SYMBOL_GPL(idle_notifier_unregister); void enter_idle(void) { - write_pda(isidle, 1); + percpu_write(is_idle, 1); atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL); } static void __exit_idle(void) { - if (test_and_clear_bit_pda(0, isidle) == 0) + if (x86_test_and_clear_bit_percpu(0, is_idle) == 0) return; atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL); } -- cgit From 87b264065880fa696c121dad8498a60524e0f6de Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Mon, 19 Jan 2009 00:38:59 +0900 Subject: x86-64: Use absolute displacements for per-cpu accesses. Accessing memory through %gs should not use rip-relative addressing. Adding a P prefix for the argument tells gcc to not add (%rip) to the memory references. Signed-off-by: Brian Gerst Signed-off-by: Tejun Heo --- arch/x86/include/asm/percpu.h | 26 +++++++++++++------------- arch/x86/include/asm/system.h | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index 03aa4b00a1c..165d5272ece 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h @@ -39,10 +39,10 @@ #include #ifdef CONFIG_SMP -#define __percpu_seg_str "%%"__stringify(__percpu_seg)":" +#define __percpu_arg(x) "%%"__stringify(__percpu_seg)":%P" #x #define __my_cpu_offset percpu_read(this_cpu_off) #else -#define __percpu_seg_str +#define __percpu_arg(x) "%" #x #endif /* For arch-specific code, we can use direct single-insn ops (they @@ -58,22 +58,22 @@ do { \ } \ switch (sizeof(var)) { \ case 1: \ - asm(op "b %1,"__percpu_seg_str"%0" \ + asm(op "b %1,"__percpu_arg(0) \ : "+m" (var) \ : "ri" ((T__)val)); \ break; \ case 2: \ - asm(op "w %1,"__percpu_seg_str"%0" \ + asm(op "w %1,"__percpu_arg(0) \ : "+m" (var) \ : "ri" ((T__)val)); \ break; \ case 4: \ - asm(op "l %1,"__percpu_seg_str"%0" \ + asm(op "l %1,"__percpu_arg(0) \ : "+m" (var) \ : "ri" ((T__)val)); \ break; \ case 8: \ - asm(op "q %1,"__percpu_seg_str"%0" \ + asm(op "q %1,"__percpu_arg(0) \ : "+m" (var) \ : "r" ((T__)val)); \ break; \ @@ -86,22 +86,22 @@ do { \ typeof(var) ret__; \ switch (sizeof(var)) { \ case 1: \ - asm(op "b "__percpu_seg_str"%1,%0" \ + asm(op "b "__percpu_arg(1)",%0" \ : "=r" (ret__) \ : "m" (var)); \ break; \ case 2: \ - asm(op "w "__percpu_seg_str"%1,%0" \ + asm(op "w "__percpu_arg(1)",%0" \ : "=r" (ret__) \ : "m" (var)); \ break; \ case 4: \ - asm(op "l "__percpu_seg_str"%1,%0" \ + asm(op "l "__percpu_arg(1)",%0" \ : "=r" (ret__) \ : "m" (var)); \ break; \ case 8: \ - asm(op "q "__percpu_seg_str"%1,%0" \ + asm(op "q "__percpu_arg(1)",%0" \ : "=r" (ret__) \ : "m" (var)); \ break; \ @@ -122,9 +122,9 @@ do { \ #define x86_test_and_clear_bit_percpu(bit, var) \ ({ \ int old__; \ - asm volatile("btr %1,"__percpu_seg_str"%c2\n\tsbbl %0,%0" \ - : "=r" (old__) \ - : "dIr" (bit), "i" (&per_cpu__##var) : "memory"); \ + asm volatile("btr %2,"__percpu_arg(1)"\n\tsbbl %0,%0" \ + : "=r" (old__), "+m" (per_cpu__##var) \ + : "dIr" (bit)); \ old__; \ }) diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h index 4399aac680e..d1dc27dba36 100644 --- a/arch/x86/include/asm/system.h +++ b/arch/x86/include/asm/system.h @@ -94,7 +94,7 @@ do { \ "call __switch_to\n\t" \ ".globl thread_return\n" \ "thread_return:\n\t" \ - "movq "__percpu_seg_str"%P[current_task],%%rsi\n\t" \ + "movq "__percpu_arg([current_task])",%%rsi\n\t" \ "movq %P[thread_info](%%rsi),%%r8\n\t" \ LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \ "movq %%rax,%%rdi\n\t" \ -- cgit From 5662a2f8e7313f78d6b17ab383f3e4f04971c335 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 18 Jan 2009 19:37:21 +0100 Subject: x86, rdc321x: remove/move leftover files Impact: cleanup Move/remove leftover RDC321 files. Now that it's not a subarch anymore, arch/x86/mach-rdc321x and arch/x86/include/asm/mach-rdc321x/ are not needed. One include file was still in use: rdc321x_defs.h, move that to the generic x86 asm header directory. Signed-off-by: Ingo Molnar --- arch/x86/include/asm/mach-rdc321x/gpio.h | 60 ------- arch/x86/include/asm/mach-rdc321x/rdc321x_defs.h | 12 -- arch/x86/include/asm/rdc321x_defs.h | 12 ++ arch/x86/mach-rdc321x/Makefile | 5 - arch/x86/mach-rdc321x/gpio.c | 194 ----------------------- arch/x86/mach-rdc321x/platform.c | 69 -------- drivers/watchdog/rdc321x_wdt.c | 2 +- 7 files changed, 13 insertions(+), 341 deletions(-) delete mode 100644 arch/x86/include/asm/mach-rdc321x/gpio.h delete mode 100644 arch/x86/include/asm/mach-rdc321x/rdc321x_defs.h create mode 100644 arch/x86/include/asm/rdc321x_defs.h delete mode 100644 arch/x86/mach-rdc321x/Makefile delete mode 100644 arch/x86/mach-rdc321x/gpio.c delete mode 100644 arch/x86/mach-rdc321x/platform.c diff --git a/arch/x86/include/asm/mach-rdc321x/gpio.h b/arch/x86/include/asm/mach-rdc321x/gpio.h deleted file mode 100644 index c210ab5788b..00000000000 --- a/arch/x86/include/asm/mach-rdc321x/gpio.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef _ASM_X86_MACH_RDC321X_GPIO_H -#define _ASM_X86_MACH_RDC321X_GPIO_H - -#include - -extern int rdc_gpio_get_value(unsigned gpio); -extern void rdc_gpio_set_value(unsigned gpio, int value); -extern int rdc_gpio_direction_input(unsigned gpio); -extern int rdc_gpio_direction_output(unsigned gpio, int value); -extern int rdc_gpio_request(unsigned gpio, const char *label); -extern void rdc_gpio_free(unsigned gpio); -extern void __init rdc321x_gpio_setup(void); - -/* Wrappers for the arch-neutral GPIO API */ - -static inline int gpio_request(unsigned gpio, const char *label) -{ - return rdc_gpio_request(gpio, label); -} - -static inline void gpio_free(unsigned gpio) -{ - might_sleep(); - rdc_gpio_free(gpio); -} - -static inline int gpio_direction_input(unsigned gpio) -{ - return rdc_gpio_direction_input(gpio); -} - -static inline int gpio_direction_output(unsigned gpio, int value) -{ - return rdc_gpio_direction_output(gpio, value); -} - -static inline int gpio_get_value(unsigned gpio) -{ - return rdc_gpio_get_value(gpio); -} - -static inline void gpio_set_value(unsigned gpio, int value) -{ - rdc_gpio_set_value(gpio, value); -} - -static inline int gpio_to_irq(unsigned gpio) -{ - return gpio; -} - -static inline int irq_to_gpio(unsigned irq) -{ - return irq; -} - -/* For cansleep */ -#include - -#endif /* _ASM_X86_MACH_RDC321X_GPIO_H */ diff --git a/arch/x86/include/asm/mach-rdc321x/rdc321x_defs.h b/arch/x86/include/asm/mach-rdc321x/rdc321x_defs.h deleted file mode 100644 index c8e9c8bed3d..00000000000 --- a/arch/x86/include/asm/mach-rdc321x/rdc321x_defs.h +++ /dev/null @@ -1,12 +0,0 @@ -#define PFX "rdc321x: " - -/* General purpose configuration and data registers */ -#define RDC3210_CFGREG_ADDR 0x0CF8 -#define RDC3210_CFGREG_DATA 0x0CFC - -#define RDC321X_GPIO_CTRL_REG1 0x48 -#define RDC321X_GPIO_CTRL_REG2 0x84 -#define RDC321X_GPIO_DATA_REG1 0x4c -#define RDC321X_GPIO_DATA_REG2 0x88 - -#define RDC321X_MAX_GPIO 58 diff --git a/arch/x86/include/asm/rdc321x_defs.h b/arch/x86/include/asm/rdc321x_defs.h new file mode 100644 index 00000000000..c8e9c8bed3d --- /dev/null +++ b/arch/x86/include/asm/rdc321x_defs.h @@ -0,0 +1,12 @@ +#define PFX "rdc321x: " + +/* General purpose configuration and data registers */ +#define RDC3210_CFGREG_ADDR 0x0CF8 +#define RDC3210_CFGREG_DATA 0x0CFC + +#define RDC321X_GPIO_CTRL_REG1 0x48 +#define RDC321X_GPIO_CTRL_REG2 0x84 +#define RDC321X_GPIO_DATA_REG1 0x4c +#define RDC321X_GPIO_DATA_REG2 0x88 + +#define RDC321X_MAX_GPIO 58 diff --git a/arch/x86/mach-rdc321x/Makefile b/arch/x86/mach-rdc321x/Makefile deleted file mode 100644 index 8325b4ca431..00000000000 --- a/arch/x86/mach-rdc321x/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the RDC321x specific parts of the kernel -# -obj-$(CONFIG_X86_RDC321X) := gpio.o platform.o - diff --git a/arch/x86/mach-rdc321x/gpio.c b/arch/x86/mach-rdc321x/gpio.c deleted file mode 100644 index 247f33d3a40..00000000000 --- a/arch/x86/mach-rdc321x/gpio.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * GPIO support for RDC SoC R3210/R8610 - * - * Copyright (C) 2007, Florian Fainelli - * Copyright (C) 2008, Volker Weiss - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - - -#include -#include -#include -#include - -#include -#include - - -/* spin lock to protect our private copy of GPIO data register plus - the access to PCI conf registers. */ -static DEFINE_SPINLOCK(gpio_lock); - -/* copy of GPIO data registers */ -static u32 gpio_data_reg1; -static u32 gpio_data_reg2; - -static u32 gpio_request_data[2]; - - -static inline void rdc321x_conf_write(unsigned addr, u32 value) -{ - outl((1 << 31) | (7 << 11) | addr, RDC3210_CFGREG_ADDR); - outl(value, RDC3210_CFGREG_DATA); -} - -static inline void rdc321x_conf_or(unsigned addr, u32 value) -{ - outl((1 << 31) | (7 << 11) | addr, RDC3210_CFGREG_ADDR); - value |= inl(RDC3210_CFGREG_DATA); - outl(value, RDC3210_CFGREG_DATA); -} - -static inline u32 rdc321x_conf_read(unsigned addr) -{ - outl((1 << 31) | (7 << 11) | addr, RDC3210_CFGREG_ADDR); - - return inl(RDC3210_CFGREG_DATA); -} - -/* configure pin as GPIO */ -static void rdc321x_configure_gpio(unsigned gpio) -{ - unsigned long flags; - - spin_lock_irqsave(&gpio_lock, flags); - rdc321x_conf_or(gpio < 32 - ? RDC321X_GPIO_CTRL_REG1 : RDC321X_GPIO_CTRL_REG2, - 1 << (gpio & 0x1f)); - spin_unlock_irqrestore(&gpio_lock, flags); -} - -/* initially setup the 2 copies of the gpio data registers. - This function must be called by the platform setup code. */ -void __init rdc321x_gpio_setup() -{ - /* this might not be, what others (BIOS, bootloader, etc.) - wrote to these registers before, but it's a good guess. Still - better than just using 0xffffffff. */ - - gpio_data_reg1 = rdc321x_conf_read(RDC321X_GPIO_DATA_REG1); - gpio_data_reg2 = rdc321x_conf_read(RDC321X_GPIO_DATA_REG2); -} - -/* determine, if gpio number is valid */ -static inline int rdc321x_is_gpio(unsigned gpio) -{ - return gpio <= RDC321X_MAX_GPIO; -} - -/* request GPIO */ -int rdc_gpio_request(unsigned gpio, const char *label) -{ - unsigned long flags; - - if (!rdc321x_is_gpio(gpio)) - return -EINVAL; - - spin_lock_irqsave(&gpio_lock, flags); - if (gpio_request_data[(gpio & 0x20) ? 1 : 0] & (1 << (gpio & 0x1f))) - goto inuse; - gpio_request_data[(gpio & 0x20) ? 1 : 0] |= (1 << (gpio & 0x1f)); - spin_unlock_irqrestore(&gpio_lock, flags); - - return 0; -inuse: - spin_unlock_irqrestore(&gpio_lock, flags); - return -EINVAL; -} -EXPORT_SYMBOL(rdc_gpio_request); - -/* release previously-claimed GPIO */ -void rdc_gpio_free(unsigned gpio) -{ - unsigned long flags; - - if (!rdc321x_is_gpio(gpio)) - return; - - spin_lock_irqsave(&gpio_lock, flags); - gpio_request_data[(gpio & 0x20) ? 1 : 0] &= ~(1 << (gpio & 0x1f)); - spin_unlock_irqrestore(&gpio_lock, flags); -} -EXPORT_SYMBOL(rdc_gpio_free); - -/* read GPIO pin */ -int rdc_gpio_get_value(unsigned gpio) -{ - u32 reg; - unsigned long flags; - - spin_lock_irqsave(&gpio_lock, flags); - reg = rdc321x_conf_read(gpio < 32 - ? RDC321X_GPIO_DATA_REG1 : RDC321X_GPIO_DATA_REG2); - spin_unlock_irqrestore(&gpio_lock, flags); - - return (1 << (gpio & 0x1f)) & reg ? 1 : 0; -} -EXPORT_SYMBOL(rdc_gpio_get_value); - -/* set GPIO pin to value */ -void rdc_gpio_set_value(unsigned gpio, int value) -{ - unsigned long flags; - u32 reg; - - reg = 1 << (gpio & 0x1f); - if (gpio < 32) { - spin_lock_irqsave(&gpio_lock, flags); - if (value) - gpio_data_reg1 |= reg; - else - gpio_data_reg1 &= ~reg; - rdc321x_conf_write(RDC321X_GPIO_DATA_REG1, gpio_data_reg1); - spin_unlock_irqrestore(&gpio_lock, flags); - } else { - spin_lock_irqsave(&gpio_lock, flags); - if (value) - gpio_data_reg2 |= reg; - else - gpio_data_reg2 &= ~reg; - rdc321x_conf_write(RDC321X_GPIO_DATA_REG2, gpio_data_reg2); - spin_unlock_irqrestore(&gpio_lock, flags); - } -} -EXPORT_SYMBOL(rdc_gpio_set_value); - -/* configure GPIO pin as input */ -int rdc_gpio_direction_input(unsigned gpio) -{ - if (!rdc321x_is_gpio(gpio)) - return -EINVAL; - - rdc321x_configure_gpio(gpio); - - return 0; -} -EXPORT_SYMBOL(rdc_gpio_direction_input); - -/* configure GPIO pin as output and set value */ -int rdc_gpio_direction_output(unsigned gpio, int value) -{ - if (!rdc321x_is_gpio(gpio)) - return -EINVAL; - - gpio_set_value(gpio, value); - rdc321x_configure_gpio(gpio); - - return 0; -} -EXPORT_SYMBOL(rdc_gpio_direction_output); diff --git a/arch/x86/mach-rdc321x/platform.c b/arch/x86/mach-rdc321x/platform.c deleted file mode 100644 index 4f4e50c3ad3..00000000000 --- a/arch/x86/mach-rdc321x/platform.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Generic RDC321x platform devices - * - * Copyright (C) 2007 Florian Fainelli - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include -#include -#include -#include -#include -#include - -#include - -/* LEDS */ -static struct gpio_led default_leds[] = { - { .name = "rdc:dmz", .gpio = 1, }, -}; - -static struct gpio_led_platform_data rdc321x_led_data = { - .num_leds = ARRAY_SIZE(default_leds), - .leds = default_leds, -}; - -static struct platform_device rdc321x_leds = { - .name = "leds-gpio", - .id = -1, - .dev = { - .platform_data = &rdc321x_led_data, - } -}; - -/* Watchdog */ -static struct platform_device rdc321x_wdt = { - .name = "rdc321x-wdt", - .id = -1, - .num_resources = 0, -}; - -static struct platform_device *rdc321x_devs[] = { - &rdc321x_leds, - &rdc321x_wdt -}; - -static int __init rdc_board_setup(void) -{ - rdc321x_gpio_setup(); - - return platform_add_devices(rdc321x_devs, ARRAY_SIZE(rdc321x_devs)); -} - -arch_initcall(rdc_board_setup); diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c index bf92802f2bb..36e221beedc 100644 --- a/drivers/watchdog/rdc321x_wdt.c +++ b/drivers/watchdog/rdc321x_wdt.c @@ -37,7 +37,7 @@ #include #include -#include +#include #define RDC_WDT_MASK 0x80000000 /* Mask */ #define RDC_WDT_EN 0x00800000 /* Enable bit */ -- cgit From b786c6a98ef6fa81114ba7b9fbfc0d67060775e3 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Sat, 17 Jan 2009 12:04:36 +0100 Subject: relay: fix lock imbalance in relay_late_setup_files One fail path in relay_late_setup_files() omits mutex_unlock(&relay_channels_mutex); Add it. Signed-off-by: Jiri Slaby Signed-off-by: Ingo Molnar --- kernel/relay.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kernel/relay.c b/kernel/relay.c index 09ac2008f77..9d79b7854fa 100644 --- a/kernel/relay.c +++ b/kernel/relay.c @@ -663,8 +663,10 @@ int relay_late_setup_files(struct rchan *chan, mutex_lock(&relay_channels_mutex); /* Is chan already set up? */ - if (unlikely(chan->has_base_filename)) + if (unlikely(chan->has_base_filename)) { + mutex_unlock(&relay_channels_mutex); return -EEXIST; + } chan->has_base_filename = 1; chan->parent = parent; curr_cpu = get_cpu(); -- cgit From 64dec40ddee9d36d7b83f8a0513fdeaffe260a0e Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Fri, 16 Jan 2009 13:23:35 -0500 Subject: x86: define ARCH_WANT_FRAME_POINTERS Commit da4276b8299a6544dc41ac2485d3ffca5811b3fb changed a dependency for FRAME_POINTER from X86 to ARCH_WANT_FRAME_POINTERS, but didn't actually define it. This patch adds the definition for ARCH_WANT_FRAME_POINTERS. Without it, FRAME_POINTER can't be enabled on x86. Signed-off-by: Jeff Mahoney Signed-off-by: Ingo Molnar --- lib/Kconfig.debug | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 4c9ae6085c7..d30561dda90 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -570,6 +570,15 @@ config DEBUG_NOTIFIERS This is a relatively cheap check but if you care about maximum performance, say N. +# +# Select this config option from the architecture Kconfig, if it +# it is preferred to always offer frame pointers as a config +# option on the architecture (regardless of KERNEL_DEBUG): +# +config ARCH_WANT_FRAME_POINTERS + bool + help + config FRAME_POINTER bool "Compile the kernel with frame pointers" depends on DEBUG_KERNEL && \ -- cgit From b2b815d80a5c4e5b50be0a98aba8c445ce8f3e1f Mon Sep 17 00:00:00 2001 From: Mike Travis Date: Fri, 16 Jan 2009 15:22:16 -0800 Subject: x86: put trigger in to detect mismatched apic versions Impact: add debug warning Fire off one message if two apic's discovered with different apic versions. (this code is only called during CPU init) The goal of this is to pave the way of the removal of the apic_version[] array. We dont expect any apic version incompatibilities in the x86 landscape of systems [if so we dont handle them very well and probably never will handle deep apic version assymetries well], but it's prudent to have a debug check for one kernel cycle nevertheless. Signed-off-by: Mike Travis Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c index d19aa3aab62..4b6df2469fe 100644 --- a/arch/x86/kernel/apic.c +++ b/arch/x86/kernel/apic.c @@ -1837,6 +1837,11 @@ void __cpuinit generic_processor_info(int apicid, int version) num_processors++; cpu = cpumask_next_zero(-1, cpu_present_mask); + if (version != apic_version[boot_cpu_physical_apicid]) + WARN_ONCE(1, + "ACPI: apic version mismatch, bootcpu: %x cpu %d: %x\n", + apic_version[boot_cpu_physical_apicid], cpu, version); + physid_set(apicid, phys_cpu_present_map); if (apicid == boot_cpu_physical_apicid) { /* -- cgit From 1d4a7f1c4faf53eb9e822743ec8a70b3019a26d2 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sun, 18 Jan 2009 16:39:29 +0100 Subject: hrtimers: fix inconsistent lock state on resume in hres_timers_resume Andrey Borzenkov reported this lockdep assert: > [17854.688347] ================================= > [17854.688347] [ INFO: inconsistent lock state ] > [17854.688347] 2.6.29-rc2-1avb #1 > [17854.688347] --------------------------------- > [17854.688347] inconsistent {in-hardirq-W} -> {hardirq-on-W} usage. > [17854.688347] pm-suspend/18240 [HC0[0]:SC0[0]:HE1:SE1] takes: > [17854.688347] (&cpu_base->lock){++..}, at: [] retrigger_next_event+0x5c/0xa0 > [17854.688347] {in-hardirq-W} state was registered at: > [17854.688347] [] __lock_acquire+0x79d/0x1930 > [17854.688347] [] lock_acquire+0x5c/0x80 > [17854.688347] [] _spin_lock+0x35/0x70 > [17854.688347] [] hrtimer_run_queues+0x31/0x140 > [17854.688347] [] run_local_timers+0x8/0x20 > [17854.688347] [] update_process_times+0x23/0x60 > [17854.688347] [] tick_periodic+0x24/0x80 > [17854.688347] [] tick_handle_periodic+0x12/0x70 > [17854.688347] [] timer_interrupt+0x14/0x20 > [17854.688347] [] handle_IRQ_event+0x29/0x60 > [17854.688347] [] handle_level_irq+0x69/0xe0 > [17854.688347] [] 0xffffffff > [17854.688347] irq event stamp: 55771 > [17854.688347] hardirqs last enabled at (55771): [] _spin_unlock_irqrestore+0x35/0x60 > [17854.688347] hardirqs last disabled at (55770): [] _spin_lock_irqsave+0x19/0x80 > [17854.688347] softirqs last enabled at (54836): [] __do_softirq+0xc4/0x110 > [17854.688347] softirqs last disabled at (54831): [] do_softirq+0x8e/0xe0 > [17854.688347] > [17854.688347] other info that might help us debug this: > [17854.688347] 3 locks held by pm-suspend/18240: > [17854.688347] #0: (&buffer->mutex){--..}, at: [] sysfs_write_file+0x25/0x100 > [17854.688347] #1: (pm_mutex){--..}, at: [] enter_state+0x4f/0x140 > [17854.688347] #2: (dpm_list_mtx){--..}, at: [] device_pm_lock+0xf/0x20 > [17854.688347] > [17854.688347] stack backtrace: > [17854.688347] Pid: 18240, comm: pm-suspend Not tainted 2.6.29-rc2-1avb #1 > [17854.688347] Call Trace: > [17854.688347] [] ? printk+0x18/0x20 > [17854.688347] [] print_usage_bug+0x16c/0x1d0 > [17854.688347] [] mark_lock+0x8bf/0xc90 > [17854.688347] [] ? pit_next_event+0x2f/0x40 > [17854.688347] [] __lock_acquire+0x580/0x1930 > [17854.688347] [] ? _spin_unlock+0x1d/0x20 > [17854.688347] [] ? pit_next_event+0x2f/0x40 > [17854.688347] [] ? clockevents_program_event+0x98/0x160 > [17854.688347] [] ? mark_held_locks+0x48/0x90 > [17854.688347] [] ? _spin_unlock_irqrestore+0x35/0x60 > [17854.688347] [] ? trace_hardirqs_on_caller+0x139/0x190 > [17854.688347] [] ? trace_hardirqs_on+0xb/0x10 > [17854.688347] [] lock_acquire+0x5c/0x80 > [17854.688347] [] ? retrigger_next_event+0x5c/0xa0 > [17854.688347] [] _spin_lock+0x35/0x70 > [17854.688347] [] ? retrigger_next_event+0x5c/0xa0 > [17854.688347] [] retrigger_next_event+0x5c/0xa0 > [17854.688347] [] hres_timers_resume+0xa/0x10 > [17854.688347] [] timekeeping_resume+0xee/0x150 > [17854.688347] [] __sysdev_resume+0x14/0x50 > [17854.688347] [] sysdev_resume+0x47/0x80 > [17854.688347] [] device_power_up+0xb/0x20 > [17854.688347] [] suspend_devices_and_enter+0xcf/0x150 > [17854.688347] [] ? freeze_processes+0x3f/0x90 > [17854.688347] [] enter_state+0xf4/0x140 > [17854.688347] [] state_store+0x7d/0xc0 > [17854.688347] [] ? state_store+0x0/0xc0 > [17854.688347] [] kobj_attr_store+0x24/0x30 > [17854.688347] [] sysfs_write_file+0x9c/0x100 > [17854.688347] [] vfs_write+0x9c/0x160 > [17854.688347] [] ? restore_nocheck_notrace+0x0/0xe > [17854.688347] [] ? sysfs_write_file+0x0/0x100 > [17854.688347] [] sys_write+0x3d/0x70 > [17854.688347] [] sysenter_do_call+0x12/0x31 Andrey's analysis: > timekeeping_resume() is called via class ->resume > method; and according to comments in sysdev_resume() and > device_power_up(), they are called with interrupts disabled. > > Looking at suspend_enter, irqs *are* disabled at this point. > > So it actually looks like something (may be some driver) > unconditionally enabled irqs in resume path. Add a debug check to test this theory. If it triggers then it triggers because the resume code calls it with irqs enabled, which is a no-no not just for timekeeping_resume(), but also bad for a number of other resume handlers. Reported-by: Andrey Borzenkov Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- kernel/hrtimer.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 1455b7651b6..cb83c6d4c07 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -614,7 +614,9 @@ void clock_was_set(void) */ void hres_timers_resume(void) { - /* Retrigger the CPU local events: */ + WARN_ONCE(!irqs_disabled(), + KERN_INFO "hres_timers_resume() called with IRQs enabled!"); + retrigger_next_event(NULL); } -- cgit From c7f8562a51c2e5dcc1a00a2bdd232b9965ff960d Mon Sep 17 00:00:00 2001 From: Leonardo Potenza Date: Sun, 18 Jan 2009 23:03:56 +0100 Subject: x86: fix section mismatch warnings in kernel/setup_percpu.c The function setup_cpu_local_masks() has been marked __init, in order to remove the following section mismatch messages: WARNING: vmlinux.o(.text+0x3c2c7): Section mismatch in reference from the function setup_cpu_local_masks() to the function .init.text:alloc_bootmem_cpumask_var() The function setup_cpu_local_masks() references the function __init alloc_bootmem_cpumask_var(). This is often because setup_cpu_local_masks lacks a __init annotation or the annotation of alloc_bootmem_cpumask_var is wrong. WARNING: vmlinux.o(.text+0x3c2d3): Section mismatch in reference from the function setup_cpu_local_masks() to the function .init.text:alloc_bootmem_cpumask_var() The function setup_cpu_local_masks() references the function __init alloc_bootmem_cpumask_var(). This is often because setup_cpu_local_masks lacks a __init annotation or the annotation of alloc_bootmem_cpumask_var is wrong. WARNING: vmlinux.o(.text+0x3c2df): Section mismatch in reference from the function setup_cpu_local_masks() to the function .init.text:alloc_bootmem_cpumask_var() The function setup_cpu_local_masks() references the function __init alloc_bootmem_cpumask_var(). This is often because setup_cpu_local_masks lacks a __init annotation or the annotation of alloc_bootmem_cpumask_var is wrong. WARNING: vmlinux.o(.text+0x3c2eb): Section mismatch in reference from the function setup_cpu_local_masks() to the function .init.text:alloc_bootmem_cpumask_var() The function setup_cpu_local_masks() references the function __init alloc_bootmem_cpumask_var(). This is often because setup_cpu_local_masks lacks a __init annotation or the annotation of alloc_bootmem_cpumask_var is wrong. Signed-off-by: Leonardo Potenza Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_percpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 55c46074eba..01161077a49 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -136,7 +136,7 @@ static void __init setup_cpu_pda_map(void) #ifdef CONFIG_X86_64 /* correctly size the local cpu masks */ -static void setup_cpu_local_masks(void) +static void __init setup_cpu_local_masks(void) { alloc_bootmem_cpumask_var(&cpu_initialized_mask); alloc_bootmem_cpumask_var(&cpu_callin_mask); -- cgit From 3afd522de8d8ec446efe957b86e4f63e3dd8ce9d Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Mon, 19 Jan 2009 00:15:13 +0100 Subject: [MTD] slram: Handle negative devlength correctly A negative devlength won't get noticed and clean up: Signed-off-by: Roel Kluin Signed-off-by: David Woodhouse --- drivers/mtd/devices/slram.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c index a425d09f35a..00248e81ecd 100644 --- a/drivers/mtd/devices/slram.c +++ b/drivers/mtd/devices/slram.c @@ -267,22 +267,28 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength) if (*(szlength) != '+') { devlength = simple_strtoul(szlength, &buffer, 0); devlength = handle_unit(devlength, buffer) - devstart; + if (devlength < devstart) + goto err_out; + + devlength -= devstart; } else { devlength = simple_strtoul(szlength + 1, &buffer, 0); devlength = handle_unit(devlength, buffer); } T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n", devname, devstart, devlength); - if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) { - E("slram: Illegal start / length parameter.\n"); - return(-EINVAL); - } + if (devlength % SLRAM_BLK_SZ != 0) + goto err_out; if ((devstart = register_device(devname, devstart, devlength))){ unregister_devices(); return((int)devstart); } return(0); + +err_out: + E("slram: Illegal length parameter.\n"); + return(-EINVAL); } #ifndef MODULE -- cgit From f90d4118bacef87894621a3e8aba853fa0c89abc Mon Sep 17 00:00:00 2001 From: Miao Xie Date: Fri, 16 Jan 2009 10:24:10 +0800 Subject: cpuset: fix possible deadlock in async_rebuild_sched_domains Lockdep reported some possible circular locking info when we tested cpuset on NUMA/fake NUMA box. ======================================================= [ INFO: possible circular locking dependency detected ] 2.6.29-rc1-00224-ga652504 #111 ------------------------------------------------------- bash/2968 is trying to acquire lock: (events){--..}, at: [] flush_work+0x24/0xd8 but task is already holding lock: (cgroup_mutex){--..}, at: [] cgroup_lock_live_group+0x12/0x29 which lock already depends on the new lock. ...... ------------------------------------------------------- Steps to reproduce: # mkdir /dev/cpuset # mount -t cpuset xxx /dev/cpuset # mkdir /dev/cpuset/0 # echo 0 > /dev/cpuset/0/cpus # echo 0 > /dev/cpuset/0/mems # echo 1 > /dev/cpuset/0/memory_migrate # cat /dev/zero > /dev/null & # echo $! > /dev/cpuset/0/tasks This is because async_rebuild_sched_domains has the following lock sequence: run_workqueue(async_rebuild_sched_domains) -> do_rebuild_sched_domains -> cgroup_lock But, attaching tasks when memory_migrate is set has following: cgroup_lock_live_group(cgroup_tasks_write) -> do_migrate_pages -> flush_work This patch fixes it by using a separate workqueue thread. Signed-off-by: Miao Xie Signed-off-by: Lai Jiangshan Signed-off-by: Ingo Molnar --- kernel/cpuset.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/kernel/cpuset.c b/kernel/cpuset.c index a85678865c5..f76db9dcaa0 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -60,6 +60,14 @@ #include #include +/* + * Workqueue for cpuset related tasks. + * + * Using kevent workqueue may cause deadlock when memory_migrate + * is set. So we create a separate workqueue thread for cpuset. + */ +static struct workqueue_struct *cpuset_wq; + /* * Tracks how many cpusets are currently defined in system. * When there is only one cpuset (the root cpuset) we can @@ -831,7 +839,7 @@ static DECLARE_WORK(rebuild_sched_domains_work, do_rebuild_sched_domains); */ static void async_rebuild_sched_domains(void) { - schedule_work(&rebuild_sched_domains_work); + queue_work(cpuset_wq, &rebuild_sched_domains_work); } /* @@ -2111,6 +2119,9 @@ void __init cpuset_init_smp(void) hotcpu_notifier(cpuset_track_online_cpus, 0); hotplug_memory_notifier(cpuset_track_online_nodes, 10); + + cpuset_wq = create_singlethread_workqueue("cpuset"); + BUG_ON(!cpuset_wq); } /** -- cgit From 8d69abb08343706f88380edb83927ffc0fc83098 Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Sun, 18 Jan 2009 11:55:19 +0200 Subject: [ARM] pxa: fix NAND and MMC clock initialization for pxa3xx After commit 8c3abc7d903df492a7394b0adae4349d9a381aaf ("[ARM] pxa: convert to clkdev and match clocks by struct device where possible") get_clk in pxa3xx_nand fails with -ENOENT. Apparently, clk_get in pxamci will also fail for MCI2 on PXA310. The 'clk_find' and therefore 'clk_get' require driver to supply both 'dev_id' and 'con_id' if they are not NULL in the 'strcut clk_lookup', but neither pxa3xx_nand nor pxamci supply 'con_id'. This patch sets 'con_id' to NULL in NAND clock and MCI2 clock registration. Signed-off-by: Mike Rapoport Signed-off-by: Eric Miao --- arch/arm/mach-pxa/pxa300.c | 4 ++-- arch/arm/mach-pxa/pxa320.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-pxa/pxa300.c b/arch/arm/mach-pxa/pxa300.c index f735e58e666..83fb609b6eb 100644 --- a/arch/arm/mach-pxa/pxa300.c +++ b/arch/arm/mach-pxa/pxa300.c @@ -88,13 +88,13 @@ static struct pxa3xx_mfp_addr_map pxa310_mfp_addr_map[] __initdata = { static DEFINE_PXA3_CKEN(common_nand, NAND, 156000000, 0); static struct clk_lookup common_clkregs[] = { - INIT_CLKREG(&clk_common_nand, "pxa3xx-nand", "NANDCLK"), + INIT_CLKREG(&clk_common_nand, "pxa3xx-nand", NULL), }; static DEFINE_PXA3_CKEN(pxa310_mmc3, MMC3, 19500000, 0); static struct clk_lookup pxa310_clkregs[] = { - INIT_CLKREG(&clk_pxa310_mmc3, "pxa2xx-mci.2", "MMCCLK"), + INIT_CLKREG(&clk_pxa310_mmc3, "pxa2xx-mci.2", NULL), }; static int __init pxa300_init(void) diff --git a/arch/arm/mach-pxa/pxa320.c b/arch/arm/mach-pxa/pxa320.c index effe408c186..36f066196fa 100644 --- a/arch/arm/mach-pxa/pxa320.c +++ b/arch/arm/mach-pxa/pxa320.c @@ -83,7 +83,7 @@ static struct pxa3xx_mfp_addr_map pxa320_mfp_addr_map[] __initdata = { static DEFINE_PXA3_CKEN(pxa320_nand, NAND, 104000000, 0); static struct clk_lookup pxa320_clkregs[] = { - INIT_CLKREG(&clk_pxa320_nand, "pxa3xx-nand", "NANDCLK"), + INIT_CLKREG(&clk_pxa320_nand, "pxa3xx-nand", NULL), }; static int __init pxa320_init(void) -- cgit From ec971c91c55b8e2e2609f8d61eb34da13aedb37d Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 19 Jan 2009 11:39:36 +0800 Subject: [ARM] pxa: fix missing of __REG() definition for ac97 registers access This currently happens for 'drivers/input/touch/mainstone-wm97xx.c'. Signed-off-by: Eric Miao --- arch/arm/mach-pxa/include/mach/regs-ac97.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-pxa/include/mach/regs-ac97.h b/arch/arm/mach-pxa/include/mach/regs-ac97.h index e41b9d202b8..b8d14bd9ae5 100644 --- a/arch/arm/mach-pxa/include/mach/regs-ac97.h +++ b/arch/arm/mach-pxa/include/mach/regs-ac97.h @@ -1,6 +1,8 @@ #ifndef __ASM_ARCH_REGS_AC97_H #define __ASM_ARCH_REGS_AC97_H +#include + /* * AC97 Controller registers */ -- cgit From b6729deb26a131083add5b7238c7b7478ef6b502 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 19 Jan 2009 11:42:32 +0800 Subject: [ARM] pxa: make more SSCR0 bit definitions visible on multiple processors The only exclusive definitions are SSCR0_SCR and SSCR0_SerClkDiv(), loosen that exclusive #ifdef .. #else .. #endif to allow other definitions to be visible when slected multiple processors. This helps to pass the building of pxa-ssp.c. Signed-off-by: Eric Miao --- arch/arm/mach-pxa/include/mach/regs-ssp.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/mach-pxa/include/mach/regs-ssp.h b/arch/arm/mach-pxa/include/mach/regs-ssp.h index 3c04cde2cf1..cf31986f6f0 100644 --- a/arch/arm/mach-pxa/include/mach/regs-ssp.h +++ b/arch/arm/mach-pxa/include/mach/regs-ssp.h @@ -41,6 +41,9 @@ #elif defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) #define SSCR0_SCR (0x000fff00) /* Serial Clock Rate (mask) */ #define SSCR0_SerClkDiv(x) (((x) - 1) << 8) /* Divisor [1..4096] */ +#endif + +#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) #define SSCR0_EDSS (1 << 20) /* Extended data size select */ #define SSCR0_NCS (1 << 21) /* Network clock select */ #define SSCR0_RIM (1 << 22) /* Receive FIFO overrrun interrupt mask */ -- cgit From ab596ad8972f314ace538799734c7e1bdd1da2ff Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 19 Jan 2009 02:02:57 +0100 Subject: xfs: fix dentry aliasing issues in open_by_handle Open by handle just grabs an inode by handle and then creates itself a dentry for it. While this works for regular files it is horribly broken for directories, where the VFS locking relies on the fact that there is only just one single dentry for a given inode, and that these are always connected to the root of the filesystem so that it's locking algorithms work (see Documentations/filesystems/Locking) Remove all the existing open by handle code and replace it with a small wrapper around the exportfs code which deals with all these issues. At the same time we also make the checks for a valid handle strict enough to reject all not perfectly well formed handles - given that we never hand out others that's okay and simplifies the code. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner --- fs/xfs/Kconfig | 1 + fs/xfs/linux-2.6/xfs_ioctl.c | 305 ++++++++++++++++++----------------------- fs/xfs/linux-2.6/xfs_ioctl.h | 15 +- fs/xfs/linux-2.6/xfs_ioctl32.c | 175 +++++++---------------- 4 files changed, 196 insertions(+), 300 deletions(-) diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig index 3f53dd101f9..29228f5899c 100644 --- a/fs/xfs/Kconfig +++ b/fs/xfs/Kconfig @@ -1,6 +1,7 @@ config XFS_FS tristate "XFS filesystem support" depends on BLOCK + select EXPORTFS help XFS is a high performance journaling filesystem which originated on the SGI IRIX platform. It is completely multi-threaded, can diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index e5be1e0be80..4bd112313f3 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c @@ -50,12 +50,14 @@ #include "xfs_vnodeops.h" #include "xfs_quota.h" #include "xfs_inode_item.h" +#include "xfs_export.h" #include #include #include #include #include +#include /* * xfs_find_handle maps from userspace xfs_fsop_handlereq structure to @@ -164,97 +166,69 @@ xfs_find_handle( return 0; } - /* - * Convert userspace handle data into inode. - * - * We use the fact that all the fsop_handlereq ioctl calls have a data - * structure argument whose first component is always a xfs_fsop_handlereq_t, - * so we can pass that sub structure into this handy, shared routine. - * - * If no error, caller must always iput the returned inode. + * No need to do permission checks on the various pathname components + * as the handle operations are privileged. */ STATIC int -xfs_vget_fsop_handlereq( - xfs_mount_t *mp, - struct inode *parinode, /* parent inode pointer */ - xfs_fsop_handlereq_t *hreq, - struct inode **inode) +xfs_handle_acceptable( + void *context, + struct dentry *dentry) +{ + return 1; +} + +/* + * Convert userspace handle data into a dentry. + */ +struct dentry * +xfs_handle_to_dentry( + struct file *parfilp, + void __user *uhandle, + u32 hlen) { - void __user *hanp; - size_t hlen; - xfs_fid_t *xfid; - xfs_handle_t *handlep; xfs_handle_t handle; - xfs_inode_t *ip; - xfs_ino_t ino; - __u32 igen; - int error; + struct xfs_fid64 fid; /* * Only allow handle opens under a directory. */ - if (!S_ISDIR(parinode->i_mode)) - return XFS_ERROR(ENOTDIR); - - hanp = hreq->ihandle; - hlen = hreq->ihandlen; - handlep = &handle; - - if (hlen < sizeof(handlep->ha_fsid) || hlen > sizeof(*handlep)) - return XFS_ERROR(EINVAL); - if (copy_from_user(handlep, hanp, hlen)) - return XFS_ERROR(EFAULT); - if (hlen < sizeof(*handlep)) - memset(((char *)handlep) + hlen, 0, sizeof(*handlep) - hlen); - if (hlen > sizeof(handlep->ha_fsid)) { - if (handlep->ha_fid.fid_len != - (hlen - sizeof(handlep->ha_fsid) - - sizeof(handlep->ha_fid.fid_len)) || - handlep->ha_fid.fid_pad) - return XFS_ERROR(EINVAL); - } - - /* - * Crack the handle, obtain the inode # & generation # - */ - xfid = (struct xfs_fid *)&handlep->ha_fid; - if (xfid->fid_len == sizeof(*xfid) - sizeof(xfid->fid_len)) { - ino = xfid->fid_ino; - igen = xfid->fid_gen; - } else { - return XFS_ERROR(EINVAL); - } - - /* - * Get the XFS inode, building a Linux inode to go with it. - */ - error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, 0); - if (error) - return error; - if (ip == NULL) - return XFS_ERROR(EIO); - if (ip->i_d.di_gen != igen) { - xfs_iput_new(ip, XFS_ILOCK_SHARED); - return XFS_ERROR(ENOENT); - } - - xfs_iunlock(ip, XFS_ILOCK_SHARED); + if (!S_ISDIR(parfilp->f_path.dentry->d_inode->i_mode)) + return ERR_PTR(-ENOTDIR); + + if (hlen != sizeof(xfs_handle_t)) + return ERR_PTR(-EINVAL); + if (copy_from_user(&handle, uhandle, hlen)) + return ERR_PTR(-EFAULT); + if (handle.ha_fid.fid_len != + sizeof(handle.ha_fid) - sizeof(handle.ha_fid.fid_len)) + return ERR_PTR(-EINVAL); + + memset(&fid, 0, sizeof(struct fid)); + fid.ino = handle.ha_fid.fid_ino; + fid.gen = handle.ha_fid.fid_gen; + + return exportfs_decode_fh(parfilp->f_path.mnt, (struct fid *)&fid, 3, + FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG, + xfs_handle_acceptable, NULL); +} - *inode = VFS_I(ip); - return 0; +STATIC struct dentry * +xfs_handlereq_to_dentry( + struct file *parfilp, + xfs_fsop_handlereq_t *hreq) +{ + return xfs_handle_to_dentry(parfilp, hreq->ihandle, hreq->ihandlen); } int xfs_open_by_handle( - xfs_mount_t *mp, - xfs_fsop_handlereq_t *hreq, struct file *parfilp, - struct inode *parinode) + xfs_fsop_handlereq_t *hreq) { const struct cred *cred = current_cred(); int error; - int new_fd; + int fd; int permflag; struct file *filp; struct inode *inode; @@ -263,19 +237,21 @@ xfs_open_by_handle( if (!capable(CAP_SYS_ADMIN)) return -XFS_ERROR(EPERM); - error = xfs_vget_fsop_handlereq(mp, parinode, hreq, &inode); - if (error) - return -error; + dentry = xfs_handlereq_to_dentry(parfilp, hreq); + if (IS_ERR(dentry)) + return PTR_ERR(dentry); + inode = dentry->d_inode; /* Restrict xfs_open_by_handle to directories & regular files. */ if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) { - iput(inode); - return -XFS_ERROR(EINVAL); + error = -XFS_ERROR(EPERM); + goto out_dput; } #if BITS_PER_LONG != 32 hreq->oflags |= O_LARGEFILE; #endif + /* Put open permission in namei format. */ permflag = hreq->oflags; if ((permflag+1) & O_ACCMODE) @@ -285,50 +261,45 @@ xfs_open_by_handle( if ((!(permflag & O_APPEND) || (permflag & O_TRUNC)) && (permflag & FMODE_WRITE) && IS_APPEND(inode)) { - iput(inode); - return -XFS_ERROR(EPERM); + error = -XFS_ERROR(EPERM); + goto out_dput; } if ((permflag & FMODE_WRITE) && IS_IMMUTABLE(inode)) { - iput(inode); - return -XFS_ERROR(EACCES); + error = -XFS_ERROR(EACCES); + goto out_dput; } /* Can't write directories. */ - if ( S_ISDIR(inode->i_mode) && (permflag & FMODE_WRITE)) { - iput(inode); - return -XFS_ERROR(EISDIR); + if (S_ISDIR(inode->i_mode) && (permflag & FMODE_WRITE)) { + error = -XFS_ERROR(EISDIR); + goto out_dput; } - if ((new_fd = get_unused_fd()) < 0) { - iput(inode); - return new_fd; + fd = get_unused_fd(); + if (fd < 0) { + error = fd; + goto out_dput; } - dentry = d_obtain_alias(inode); - if (IS_ERR(dentry)) { - put_unused_fd(new_fd); - return PTR_ERR(dentry); - } - - /* Ensure umount returns EBUSY on umounts while this file is open. */ - mntget(parfilp->f_path.mnt); - - /* Create file pointer. */ - filp = dentry_open(dentry, parfilp->f_path.mnt, hreq->oflags, cred); + filp = dentry_open(dentry, mntget(parfilp->f_path.mnt), + hreq->oflags, cred); if (IS_ERR(filp)) { - put_unused_fd(new_fd); - return -XFS_ERROR(-PTR_ERR(filp)); + put_unused_fd(fd); + return PTR_ERR(filp); } if (inode->i_mode & S_IFREG) { - /* invisible operation should not change atime */ filp->f_flags |= O_NOATIME; filp->f_mode |= FMODE_NOCMTIME; } - fd_install(new_fd, filp); - return new_fd; + fd_install(fd, filp); + return fd; + + out_dput: + dput(dentry); + return error; } /* @@ -359,11 +330,10 @@ do_readlink( int xfs_readlink_by_handle( - xfs_mount_t *mp, - xfs_fsop_handlereq_t *hreq, - struct inode *parinode) + struct file *parfilp, + xfs_fsop_handlereq_t *hreq) { - struct inode *inode; + struct dentry *dentry; __u32 olen; void *link; int error; @@ -371,26 +341,28 @@ xfs_readlink_by_handle( if (!capable(CAP_SYS_ADMIN)) return -XFS_ERROR(EPERM); - error = xfs_vget_fsop_handlereq(mp, parinode, hreq, &inode); - if (error) - return -error; + dentry = xfs_handlereq_to_dentry(parfilp, hreq); + if (IS_ERR(dentry)) + return PTR_ERR(dentry); /* Restrict this handle operation to symlinks only. */ - if (!S_ISLNK(inode->i_mode)) { + if (!S_ISLNK(dentry->d_inode->i_mode)) { error = -XFS_ERROR(EINVAL); - goto out_iput; + goto out_dput; } if (copy_from_user(&olen, hreq->ohandlen, sizeof(__u32))) { error = -XFS_ERROR(EFAULT); - goto out_iput; + goto out_dput; } link = kmalloc(MAXPATHLEN+1, GFP_KERNEL); - if (!link) - goto out_iput; + if (!link) { + error = -XFS_ERROR(ENOMEM); + goto out_dput; + } - error = -xfs_readlink(XFS_I(inode), link); + error = -xfs_readlink(XFS_I(dentry->d_inode), link); if (error) goto out_kfree; error = do_readlink(hreq->ohandle, olen, link); @@ -399,32 +371,31 @@ xfs_readlink_by_handle( out_kfree: kfree(link); - out_iput: - iput(inode); + out_dput: + dput(dentry); return error; } STATIC int xfs_fssetdm_by_handle( - xfs_mount_t *mp, - void __user *arg, - struct inode *parinode) + struct file *parfilp, + void __user *arg) { int error; struct fsdmidata fsd; xfs_fsop_setdm_handlereq_t dmhreq; - struct inode *inode; + struct dentry *dentry; if (!capable(CAP_MKNOD)) return -XFS_ERROR(EPERM); if (copy_from_user(&dmhreq, arg, sizeof(xfs_fsop_setdm_handlereq_t))) return -XFS_ERROR(EFAULT); - error = xfs_vget_fsop_handlereq(mp, parinode, &dmhreq.hreq, &inode); - if (error) - return -error; + dentry = xfs_handlereq_to_dentry(parfilp, &dmhreq.hreq); + if (IS_ERR(dentry)) + return PTR_ERR(dentry); - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) { + if (IS_IMMUTABLE(dentry->d_inode) || IS_APPEND(dentry->d_inode)) { error = -XFS_ERROR(EPERM); goto out; } @@ -434,24 +405,23 @@ xfs_fssetdm_by_handle( goto out; } - error = -xfs_set_dmattrs(XFS_I(inode), fsd.fsd_dmevmask, + error = -xfs_set_dmattrs(XFS_I(dentry->d_inode), fsd.fsd_dmevmask, fsd.fsd_dmstate); out: - iput(inode); + dput(dentry); return error; } STATIC int xfs_attrlist_by_handle( - xfs_mount_t *mp, - void __user *arg, - struct inode *parinode) + struct file *parfilp, + void __user *arg) { - int error; + int error = -ENOMEM; attrlist_cursor_kern_t *cursor; xfs_fsop_attrlist_handlereq_t al_hreq; - struct inode *inode; + struct dentry *dentry; char *kbuf; if (!capable(CAP_SYS_ADMIN)) @@ -467,16 +437,16 @@ xfs_attrlist_by_handle( if (al_hreq.flags & ~(ATTR_ROOT | ATTR_SECURE)) return -XFS_ERROR(EINVAL); - error = xfs_vget_fsop_handlereq(mp, parinode, &al_hreq.hreq, &inode); - if (error) - goto out; + dentry = xfs_handlereq_to_dentry(parfilp, &al_hreq.hreq); + if (IS_ERR(dentry)) + return PTR_ERR(dentry); kbuf = kmalloc(al_hreq.buflen, GFP_KERNEL); if (!kbuf) - goto out_vn_rele; + goto out_dput; cursor = (attrlist_cursor_kern_t *)&al_hreq.pos; - error = xfs_attr_list(XFS_I(inode), kbuf, al_hreq.buflen, + error = -xfs_attr_list(XFS_I(dentry->d_inode), kbuf, al_hreq.buflen, al_hreq.flags, cursor); if (error) goto out_kfree; @@ -486,10 +456,9 @@ xfs_attrlist_by_handle( out_kfree: kfree(kbuf); - out_vn_rele: - iput(inode); - out: - return -error; + out_dput: + dput(dentry); + return error; } int @@ -564,15 +533,13 @@ xfs_attrmulti_attr_remove( STATIC int xfs_attrmulti_by_handle( - xfs_mount_t *mp, - void __user *arg, struct file *parfilp, - struct inode *parinode) + void __user *arg) { int error; xfs_attr_multiop_t *ops; xfs_fsop_attrmulti_handlereq_t am_hreq; - struct inode *inode; + struct dentry *dentry; unsigned int i, size; char *attr_name; @@ -581,19 +548,19 @@ xfs_attrmulti_by_handle( if (copy_from_user(&am_hreq, arg, sizeof(xfs_fsop_attrmulti_handlereq_t))) return -XFS_ERROR(EFAULT); - error = xfs_vget_fsop_handlereq(mp, parinode, &am_hreq.hreq, &inode); - if (error) - goto out; + dentry = xfs_handlereq_to_dentry(parfilp, &am_hreq.hreq); + if (IS_ERR(dentry)) + return PTR_ERR(dentry); error = E2BIG; size = am_hreq.opcount * sizeof(xfs_attr_multiop_t); if (!size || size > 16 * PAGE_SIZE) - goto out_vn_rele; + goto out_dput; error = ENOMEM; ops = kmalloc(size, GFP_KERNEL); if (!ops) - goto out_vn_rele; + goto out_dput; error = EFAULT; if (copy_from_user(ops, am_hreq.ops, size)) @@ -615,25 +582,28 @@ xfs_attrmulti_by_handle( switch (ops[i].am_opcode) { case ATTR_OP_GET: - ops[i].am_error = xfs_attrmulti_attr_get(inode, - attr_name, ops[i].am_attrvalue, - &ops[i].am_length, ops[i].am_flags); + ops[i].am_error = xfs_attrmulti_attr_get( + dentry->d_inode, attr_name, + ops[i].am_attrvalue, &ops[i].am_length, + ops[i].am_flags); break; case ATTR_OP_SET: ops[i].am_error = mnt_want_write(parfilp->f_path.mnt); if (ops[i].am_error) break; - ops[i].am_error = xfs_attrmulti_attr_set(inode, - attr_name, ops[i].am_attrvalue, - ops[i].am_length, ops[i].am_flags); + ops[i].am_error = xfs_attrmulti_attr_set( + dentry->d_inode, attr_name, + ops[i].am_attrvalue, ops[i].am_length, + ops[i].am_flags); mnt_drop_write(parfilp->f_path.mnt); break; case ATTR_OP_REMOVE: ops[i].am_error = mnt_want_write(parfilp->f_path.mnt); if (ops[i].am_error) break; - ops[i].am_error = xfs_attrmulti_attr_remove(inode, - attr_name, ops[i].am_flags); + ops[i].am_error = xfs_attrmulti_attr_remove( + dentry->d_inode, attr_name, + ops[i].am_flags); mnt_drop_write(parfilp->f_path.mnt); break; default: @@ -647,9 +617,8 @@ xfs_attrmulti_by_handle( kfree(attr_name); out_kfree_ops: kfree(ops); - out_vn_rele: - iput(inode); - out: + out_dput: + dput(dentry); return -error; } @@ -1440,23 +1409,23 @@ xfs_file_ioctl( if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t))) return -XFS_ERROR(EFAULT); - return xfs_open_by_handle(mp, &hreq, filp, inode); + return xfs_open_by_handle(filp, &hreq); } case XFS_IOC_FSSETDM_BY_HANDLE: - return xfs_fssetdm_by_handle(mp, arg, inode); + return xfs_fssetdm_by_handle(filp, arg); case XFS_IOC_READLINK_BY_HANDLE: { xfs_fsop_handlereq_t hreq; if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t))) return -XFS_ERROR(EFAULT); - return xfs_readlink_by_handle(mp, &hreq, inode); + return xfs_readlink_by_handle(filp, &hreq); } case XFS_IOC_ATTRLIST_BY_HANDLE: - return xfs_attrlist_by_handle(mp, arg, inode); + return xfs_attrlist_by_handle(filp, arg); case XFS_IOC_ATTRMULTI_BY_HANDLE: - return xfs_attrmulti_by_handle(mp, arg, filp, inode); + return xfs_attrmulti_by_handle(filp, arg); case XFS_IOC_SWAPEXT: { struct xfs_swapext sxp; diff --git a/fs/xfs/linux-2.6/xfs_ioctl.h b/fs/xfs/linux-2.6/xfs_ioctl.h index 8c16bf2d7e0..7bd7c6afc1e 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.h +++ b/fs/xfs/linux-2.6/xfs_ioctl.h @@ -34,16 +34,13 @@ xfs_find_handle( extern int xfs_open_by_handle( - xfs_mount_t *mp, - xfs_fsop_handlereq_t *hreq, struct file *parfilp, - struct inode *parinode); + xfs_fsop_handlereq_t *hreq); extern int xfs_readlink_by_handle( - xfs_mount_t *mp, - xfs_fsop_handlereq_t *hreq, - struct inode *parinode); + struct file *parfilp, + xfs_fsop_handlereq_t *hreq); extern int xfs_attrmulti_attr_get( @@ -67,6 +64,12 @@ xfs_attrmulti_attr_remove( char *name, __uint32_t flags); +extern struct dentry * +xfs_handle_to_dentry( + struct file *parfilp, + void __user *uhandle, + u32 hlen); + extern long xfs_file_ioctl( struct file *filp, diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c index 50903ad3182..fd4362063f2 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl32.c +++ b/fs/xfs/linux-2.6/xfs_ioctl32.c @@ -340,96 +340,24 @@ xfs_compat_handlereq_copyin( return 0; } -/* - * Convert userspace handle data into inode. - * - * We use the fact that all the fsop_handlereq ioctl calls have a data - * structure argument whose first component is always a xfs_fsop_handlereq_t, - * so we can pass that sub structure into this handy, shared routine. - * - * If no error, caller must always iput the returned inode. - */ -STATIC int -xfs_vget_fsop_handlereq_compat( - xfs_mount_t *mp, - struct inode *parinode, /* parent inode pointer */ - compat_xfs_fsop_handlereq_t *hreq, - struct inode **inode) +STATIC struct dentry * +xfs_compat_handlereq_to_dentry( + struct file *parfilp, + compat_xfs_fsop_handlereq_t *hreq) { - void __user *hanp; - size_t hlen; - xfs_fid_t *xfid; - xfs_handle_t *handlep; - xfs_handle_t handle; - xfs_inode_t *ip; - xfs_ino_t ino; - __u32 igen; - int error; - - /* - * Only allow handle opens under a directory. - */ - if (!S_ISDIR(parinode->i_mode)) - return XFS_ERROR(ENOTDIR); - - hanp = compat_ptr(hreq->ihandle); - hlen = hreq->ihandlen; - handlep = &handle; - - if (hlen < sizeof(handlep->ha_fsid) || hlen > sizeof(*handlep)) - return XFS_ERROR(EINVAL); - if (copy_from_user(handlep, hanp, hlen)) - return XFS_ERROR(EFAULT); - if (hlen < sizeof(*handlep)) - memset(((char *)handlep) + hlen, 0, sizeof(*handlep) - hlen); - if (hlen > sizeof(handlep->ha_fsid)) { - if (handlep->ha_fid.fid_len != - (hlen - sizeof(handlep->ha_fsid) - - sizeof(handlep->ha_fid.fid_len)) || - handlep->ha_fid.fid_pad) - return XFS_ERROR(EINVAL); - } - - /* - * Crack the handle, obtain the inode # & generation # - */ - xfid = (struct xfs_fid *)&handlep->ha_fid; - if (xfid->fid_len == sizeof(*xfid) - sizeof(xfid->fid_len)) { - ino = xfid->fid_ino; - igen = xfid->fid_gen; - } else { - return XFS_ERROR(EINVAL); - } - - /* - * Get the XFS inode, building a Linux inode to go with it. - */ - error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, 0); - if (error) - return error; - if (ip == NULL) - return XFS_ERROR(EIO); - if (ip->i_d.di_gen != igen) { - xfs_iput_new(ip, XFS_ILOCK_SHARED); - return XFS_ERROR(ENOENT); - } - - xfs_iunlock(ip, XFS_ILOCK_SHARED); - - *inode = VFS_I(ip); - return 0; + return xfs_handle_to_dentry(parfilp, + compat_ptr(hreq->ihandle), hreq->ihandlen); } STATIC int xfs_compat_attrlist_by_handle( - xfs_mount_t *mp, - void __user *arg, - struct inode *parinode) + struct file *parfilp, + void __user *arg) { int error; attrlist_cursor_kern_t *cursor; compat_xfs_fsop_attrlist_handlereq_t al_hreq; - struct inode *inode; + struct dentry *dentry; char *kbuf; if (!capable(CAP_SYS_ADMIN)) @@ -446,17 +374,17 @@ xfs_compat_attrlist_by_handle( if (al_hreq.flags & ~(ATTR_ROOT | ATTR_SECURE)) return -XFS_ERROR(EINVAL); - error = xfs_vget_fsop_handlereq_compat(mp, parinode, &al_hreq.hreq, - &inode); - if (error) - goto out; + dentry = xfs_compat_handlereq_to_dentry(parfilp, &al_hreq.hreq); + if (IS_ERR(dentry)) + return PTR_ERR(dentry); + error = -ENOMEM; kbuf = kmalloc(al_hreq.buflen, GFP_KERNEL); if (!kbuf) - goto out_vn_rele; + goto out_dput; cursor = (attrlist_cursor_kern_t *)&al_hreq.pos; - error = xfs_attr_list(XFS_I(inode), kbuf, al_hreq.buflen, + error = -xfs_attr_list(XFS_I(dentry->d_inode), kbuf, al_hreq.buflen, al_hreq.flags, cursor); if (error) goto out_kfree; @@ -466,22 +394,20 @@ xfs_compat_attrlist_by_handle( out_kfree: kfree(kbuf); - out_vn_rele: - iput(inode); - out: - return -error; + out_dput: + dput(dentry); + return error; } STATIC int xfs_compat_attrmulti_by_handle( - xfs_mount_t *mp, - void __user *arg, - struct inode *parinode) + struct file *parfilp, + void __user *arg) { int error; compat_xfs_attr_multiop_t *ops; compat_xfs_fsop_attrmulti_handlereq_t am_hreq; - struct inode *inode; + struct dentry *dentry; unsigned int i, size; char *attr_name; @@ -491,20 +417,19 @@ xfs_compat_attrmulti_by_handle( sizeof(compat_xfs_fsop_attrmulti_handlereq_t))) return -XFS_ERROR(EFAULT); - error = xfs_vget_fsop_handlereq_compat(mp, parinode, &am_hreq.hreq, - &inode); - if (error) - goto out; + dentry = xfs_compat_handlereq_to_dentry(parfilp, &am_hreq.hreq); + if (IS_ERR(dentry)) + return PTR_ERR(dentry); error = E2BIG; size = am_hreq.opcount * sizeof(compat_xfs_attr_multiop_t); if (!size || size > 16 * PAGE_SIZE) - goto out_vn_rele; + goto out_dput; error = ENOMEM; ops = kmalloc(size, GFP_KERNEL); if (!ops) - goto out_vn_rele; + goto out_dput; error = EFAULT; if (copy_from_user(ops, compat_ptr(am_hreq.ops), size)) @@ -527,20 +452,21 @@ xfs_compat_attrmulti_by_handle( switch (ops[i].am_opcode) { case ATTR_OP_GET: - ops[i].am_error = xfs_attrmulti_attr_get(inode, - attr_name, + ops[i].am_error = xfs_attrmulti_attr_get( + dentry->d_inode, attr_name, compat_ptr(ops[i].am_attrvalue), &ops[i].am_length, ops[i].am_flags); break; case ATTR_OP_SET: - ops[i].am_error = xfs_attrmulti_attr_set(inode, - attr_name, + ops[i].am_error = xfs_attrmulti_attr_set( + dentry->d_inode, attr_name, compat_ptr(ops[i].am_attrvalue), ops[i].am_length, ops[i].am_flags); break; case ATTR_OP_REMOVE: - ops[i].am_error = xfs_attrmulti_attr_remove(inode, - attr_name, ops[i].am_flags); + ops[i].am_error = xfs_attrmulti_attr_remove( + dentry->d_inode, attr_name, + ops[i].am_flags); break; default: ops[i].am_error = EINVAL; @@ -553,22 +479,20 @@ xfs_compat_attrmulti_by_handle( kfree(attr_name); out_kfree_ops: kfree(ops); - out_vn_rele: - iput(inode); - out: + out_dput: + dput(dentry); return -error; } STATIC int xfs_compat_fssetdm_by_handle( - xfs_mount_t *mp, - void __user *arg, - struct inode *parinode) + struct file *parfilp, + void __user *arg) { int error; struct fsdmidata fsd; compat_xfs_fsop_setdm_handlereq_t dmhreq; - struct inode *inode; + struct dentry *dentry; if (!capable(CAP_MKNOD)) return -XFS_ERROR(EPERM); @@ -576,12 +500,11 @@ xfs_compat_fssetdm_by_handle( sizeof(compat_xfs_fsop_setdm_handlereq_t))) return -XFS_ERROR(EFAULT); - error = xfs_vget_fsop_handlereq_compat(mp, parinode, &dmhreq.hreq, - &inode); - if (error) - return -error; + dentry = xfs_compat_handlereq_to_dentry(parfilp, &dmhreq.hreq); + if (IS_ERR(dentry)) + return PTR_ERR(dentry); - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) { + if (IS_IMMUTABLE(dentry->d_inode) || IS_APPEND(dentry->d_inode)) { error = -XFS_ERROR(EPERM); goto out; } @@ -591,11 +514,11 @@ xfs_compat_fssetdm_by_handle( goto out; } - error = -xfs_set_dmattrs(XFS_I(inode), fsd.fsd_dmevmask, + error = -xfs_set_dmattrs(XFS_I(dentry->d_inode), fsd.fsd_dmevmask, fsd.fsd_dmstate); out: - iput(inode); + dput(dentry); return error; } @@ -722,21 +645,21 @@ xfs_file_compat_ioctl( if (xfs_compat_handlereq_copyin(&hreq, arg)) return -XFS_ERROR(EFAULT); - return xfs_open_by_handle(mp, &hreq, filp, inode); + return xfs_open_by_handle(filp, &hreq); } case XFS_IOC_READLINK_BY_HANDLE_32: { struct xfs_fsop_handlereq hreq; if (xfs_compat_handlereq_copyin(&hreq, arg)) return -XFS_ERROR(EFAULT); - return xfs_readlink_by_handle(mp, &hreq, inode); + return xfs_readlink_by_handle(filp, &hreq); } case XFS_IOC_ATTRLIST_BY_HANDLE_32: - return xfs_compat_attrlist_by_handle(mp, arg, inode); + return xfs_compat_attrlist_by_handle(filp, arg); case XFS_IOC_ATTRMULTI_BY_HANDLE_32: - return xfs_compat_attrmulti_by_handle(mp, arg, inode); + return xfs_compat_attrmulti_by_handle(filp, arg); case XFS_IOC_FSSETDM_BY_HANDLE_32: - return xfs_compat_fssetdm_by_handle(mp, arg, inode); + return xfs_compat_fssetdm_by_handle(filp, arg); default: return -XFS_ERROR(ENOIOCTLCMD); } -- cgit From 62e194ecdaf8a1935991c1f8704886328d96a391 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 19 Jan 2009 02:03:03 +0100 Subject: xfs: use mnt_want_write in compat_attrmulti ioctl The compat version of the attrmulti ioctl needs to ask for and then later release write access to the mount just like the native version, otherwise we could potentially write to read-only mounts. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner --- fs/xfs/linux-2.6/xfs_ioctl32.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c index fd4362063f2..c70c4e3db79 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl32.c +++ b/fs/xfs/linux-2.6/xfs_ioctl32.c @@ -17,6 +17,7 @@ */ #include #include +#include #include #include "xfs.h" #include "xfs_fs.h" @@ -458,15 +459,23 @@ xfs_compat_attrmulti_by_handle( &ops[i].am_length, ops[i].am_flags); break; case ATTR_OP_SET: + ops[i].am_error = mnt_want_write(parfilp->f_path.mnt); + if (ops[i].am_error) + break; ops[i].am_error = xfs_attrmulti_attr_set( dentry->d_inode, attr_name, compat_ptr(ops[i].am_attrvalue), ops[i].am_length, ops[i].am_flags); + mnt_drop_write(parfilp->f_path.mnt); break; case ATTR_OP_REMOVE: + ops[i].am_error = mnt_want_write(parfilp->f_path.mnt); + if (ops[i].am_error) + break; ops[i].am_error = xfs_attrmulti_attr_remove( dentry->d_inode, attr_name, ops[i].am_flags); + mnt_drop_write(parfilp->f_path.mnt); break; default: ops[i].am_error = EINVAL; -- cgit From 080dda7f5e8e8df95bcd17a5345c276e365a2054 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 19 Jan 2009 02:03:11 +0100 Subject: xfs: add a separate lock class for the per-mount list of dquots We can have both a a quota hash chain and the per-mount list locked at the same time. But given that both use the same struct dqhash as list head we have to tell lockdep that they are different lock classes. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner --- fs/xfs/quota/xfs_qm.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 6b13960cf31..7a2beb64314 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c @@ -1070,6 +1070,13 @@ xfs_qm_sync( return 0; } +/* + * The hash chains and the mplist use the same xfs_dqhash structure as + * their list head, but we can take the mplist qh_lock and one of the + * hash qh_locks at the same time without any problem as they aren't + * related. + */ +static struct lock_class_key xfs_quota_mplist_class; /* * This initializes all the quota information that's kept in the @@ -1105,6 +1112,8 @@ xfs_qm_init_quotainfo( } xfs_qm_list_init(&qinf->qi_dqlist, "mpdqlist", 0); + lockdep_set_class(&qinf->qi_dqlist.qh_lock, &xfs_quota_mplist_class); + qinf->qi_dqreclaims = 0; /* mutex used to serialize quotaoffs */ -- cgit From 4f2d4ac6e5eb7d72e8df7f3fbf67a78dab8b91cf Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 19 Jan 2009 02:03:19 +0100 Subject: xfs: lockdep annotations for xfs_dqlock2 xfs_dqlock2 locks two xfs_dquots, which is fine as it always locks the dquot with the lower id first. Use mutex_lock_nested to tell lockdep about this fact. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner --- fs/xfs/quota/xfs_dquot.c | 24 ++++++++++++++---------- fs/xfs/quota/xfs_dquot.h | 10 ++++++++++ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index 591ca6602bf..36d1bb6140d 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c @@ -1383,6 +1383,12 @@ xfs_dqunlock_nonotify( mutex_unlock(&(dqp->q_qlock)); } +/* + * Lock two xfs_dquot structures. + * + * To avoid deadlocks we always lock the quota structure with + * the lowerd id first. + */ void xfs_dqlock2( xfs_dquot_t *d1, @@ -1392,18 +1398,16 @@ xfs_dqlock2( ASSERT(d1 != d2); if (be32_to_cpu(d1->q_core.d_id) > be32_to_cpu(d2->q_core.d_id)) { - xfs_dqlock(d2); - xfs_dqlock(d1); + mutex_lock(&d2->q_qlock); + mutex_lock_nested(&d1->q_qlock, XFS_QLOCK_NESTED); } else { - xfs_dqlock(d1); - xfs_dqlock(d2); - } - } else { - if (d1) { - xfs_dqlock(d1); - } else if (d2) { - xfs_dqlock(d2); + mutex_lock(&d1->q_qlock); + mutex_lock_nested(&d2->q_qlock, XFS_QLOCK_NESTED); } + } else if (d1) { + mutex_lock(&d1->q_qlock); + } else if (d2) { + mutex_lock(&d2->q_qlock); } } diff --git a/fs/xfs/quota/xfs_dquot.h b/fs/xfs/quota/xfs_dquot.h index 7e455337e2b..d443e93b433 100644 --- a/fs/xfs/quota/xfs_dquot.h +++ b/fs/xfs/quota/xfs_dquot.h @@ -97,6 +97,16 @@ typedef struct xfs_dquot { #define dq_hashlist q_lists.dqm_hashlist #define dq_flags q_lists.dqm_flags +/* + * Lock hierachy for q_qlock: + * XFS_QLOCK_NORMAL is the implicit default, + * XFS_QLOCK_NESTED is the dquot with the higher id in xfs_dqlock2 + */ +enum { + XFS_QLOCK_NORMAL = 0, + XFS_QLOCK_NESTED, +}; + #define XFS_DQHOLD(dqp) ((dqp)->q_nrefs++) #ifdef DEBUG -- cgit From 5aa2dc0a0697c762874241fa9ddbecd2d878b934 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 19 Jan 2009 02:03:25 +0100 Subject: xfs: add a lock class for group/project dquots We can have both a user and a group/project dquot locked at the same time, as long as the user dquot is locked first. Tell lockdep about that fact by making the group/project dquots a different lock class. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner --- fs/xfs/quota/xfs_dquot.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index 36d1bb6140d..f0bc7846580 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c @@ -73,6 +73,8 @@ int xfs_dqreq_num; int xfs_dqerror_mod = 33; #endif +static struct lock_class_key xfs_dquot_other_class; + /* * Allocate and initialize a dquot. We don't always allocate fresh memory; * we try to reclaim a free dquot if the number of incore dquots are above @@ -139,7 +141,15 @@ xfs_qm_dqinit( ASSERT(dqp->q_trace); xfs_dqtrace_entry(dqp, "DQRECLAIMED_INIT"); #endif - } + } + + /* + * In either case we need to make sure group quotas have a different + * lock class than user quotas, to make sure lockdep knows we can + * locks of one of each at the same time. + */ + if (!(type & XFS_DQ_USER)) + lockdep_set_class(&dqp->q_qlock, &xfs_dquot_other_class); /* * log item gets initialized later -- cgit From 49739140e57a65114d9e1976c4c158d2145595fb Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 19 Jan 2009 02:04:07 +0100 Subject: xfs: fix bad_features2 fixups for the root filesystem Currently the bad_features2 fixup and the alignment updates in the superblock are skipped if we mount a filesystem read-only. But for the root filesystem the typical case is to mount read-only first and only later remount writeable so we'll never perform this update at all. It's not a big problem but means the logs of people needing the fixup get spammed at every boot because they never happen on disk. Reported-by: Arkadiusz Miskiewicz Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner --- fs/xfs/linux-2.6/xfs_super.c | 17 ++++++++++++++++- fs/xfs/xfs_mount.c | 26 +++++++++++++------------- fs/xfs/xfs_mount.h | 3 +++ 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 95a97108036..c71e226da7f 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -1197,6 +1197,7 @@ xfs_fs_remount( struct xfs_mount *mp = XFS_M(sb); substring_t args[MAX_OPT_ARGS]; char *p; + int error; while ((p = strsep(&options, ",")) != NULL) { int token; @@ -1247,11 +1248,25 @@ xfs_fs_remount( } } - /* rw/ro -> rw */ + /* ro -> rw */ if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & MS_RDONLY)) { mp->m_flags &= ~XFS_MOUNT_RDONLY; if (mp->m_flags & XFS_MOUNT_BARRIER) xfs_mountfs_check_barriers(mp); + + /* + * If this is the first remount to writeable state we + * might have some superblock changes to update. + */ + if (mp->m_update_flags) { + error = xfs_mount_log_sb(mp, mp->m_update_flags); + if (error) { + cmn_err(CE_WARN, + "XFS: failed to write sb changes"); + return error; + } + mp->m_update_flags = 0; + } } /* rw -> ro */ diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 3c97c6463a4..35300250e86 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -45,7 +45,6 @@ #include "xfs_fsops.h" #include "xfs_utils.h" -STATIC int xfs_mount_log_sb(xfs_mount_t *, __int64_t); STATIC int xfs_uuid_mount(xfs_mount_t *); STATIC void xfs_unmountfs_wait(xfs_mount_t *); @@ -682,7 +681,7 @@ xfs_initialize_perag_data(xfs_mount_t *mp, xfs_agnumber_t agcount) * Update alignment values based on mount options and sb values */ STATIC int -xfs_update_alignment(xfs_mount_t *mp, __uint64_t *update_flags) +xfs_update_alignment(xfs_mount_t *mp) { xfs_sb_t *sbp = &(mp->m_sb); @@ -736,11 +735,11 @@ xfs_update_alignment(xfs_mount_t *mp, __uint64_t *update_flags) if (xfs_sb_version_hasdalign(sbp)) { if (sbp->sb_unit != mp->m_dalign) { sbp->sb_unit = mp->m_dalign; - *update_flags |= XFS_SB_UNIT; + mp->m_update_flags |= XFS_SB_UNIT; } if (sbp->sb_width != mp->m_swidth) { sbp->sb_width = mp->m_swidth; - *update_flags |= XFS_SB_WIDTH; + mp->m_update_flags |= XFS_SB_WIDTH; } } } else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN && @@ -905,7 +904,6 @@ xfs_mountfs( xfs_sb_t *sbp = &(mp->m_sb); xfs_inode_t *rip; __uint64_t resblks; - __int64_t update_flags = 0LL; uint quotamount, quotaflags; int uuid_mounted = 0; int error = 0; @@ -933,7 +931,7 @@ xfs_mountfs( "XFS: correcting sb_features alignment problem"); sbp->sb_features2 |= sbp->sb_bad_features2; sbp->sb_bad_features2 = sbp->sb_features2; - update_flags |= XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2; + mp->m_update_flags |= XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2; /* * Re-check for ATTR2 in case it was found in bad_features2 @@ -947,11 +945,11 @@ xfs_mountfs( if (xfs_sb_version_hasattr2(&mp->m_sb) && (mp->m_flags & XFS_MOUNT_NOATTR2)) { xfs_sb_version_removeattr2(&mp->m_sb); - update_flags |= XFS_SB_FEATURES2; + mp->m_update_flags |= XFS_SB_FEATURES2; /* update sb_versionnum for the clearing of the morebits */ if (!sbp->sb_features2) - update_flags |= XFS_SB_VERSIONNUM; + mp->m_update_flags |= XFS_SB_VERSIONNUM; } /* @@ -960,7 +958,7 @@ xfs_mountfs( * allocator alignment is within an ag, therefore ag has * to be aligned at stripe boundary. */ - error = xfs_update_alignment(mp, &update_flags); + error = xfs_update_alignment(mp); if (error) goto error1; @@ -1137,10 +1135,12 @@ xfs_mountfs( } /* - * If fs is not mounted readonly, then update the superblock changes. + * If this is a read-only mount defer the superblock updates until + * the next remount into writeable mode. Otherwise we would never + * perform the update e.g. for the root filesystem. */ - if (update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) { - error = xfs_mount_log_sb(mp, update_flags); + if (mp->m_update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) { + error = xfs_mount_log_sb(mp, mp->m_update_flags); if (error) { cmn_err(CE_WARN, "XFS: failed to write sb changes"); goto error4; @@ -1820,7 +1820,7 @@ xfs_uuid_mount( * be altered by the mount options, as well as any potential sb_features2 * fixup. Only the first superblock is updated. */ -STATIC int +int xfs_mount_log_sb( xfs_mount_t *mp, __int64_t fields) diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index c1e02846732..e37eff6761e 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -327,6 +327,8 @@ typedef struct xfs_mount { spinlock_t m_sync_lock; /* work item list lock */ int m_sync_seq; /* sync thread generation no. */ wait_queue_head_t m_wait_single_sync_task; + __int64_t m_update_flags; /* sb flags we need to update + on the next remount,rw */ } xfs_mount_t; /* @@ -514,6 +516,7 @@ extern int xfs_mod_incore_sb_unlocked(xfs_mount_t *, xfs_sb_field_t, int64_t, int); extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *, uint, int); +extern int xfs_mount_log_sb(xfs_mount_t *, __int64_t); extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int); extern int xfs_readsb(xfs_mount_t *, int); extern void xfs_freesb(xfs_mount_t *); -- cgit From b828d8c33867dd6479644c06500975570bfd525c Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 19 Jan 2009 02:04:16 +0100 Subject: xfs: sanity check attr fork size Recently we have quite a few kerneloops reports about dereferencing a NULL if_data in the attribute fork. From looking over the code this can only happen if we pass a 0 size argument to xfs_iformat_local. This implies some sort of corruption and in fact the only mailinglist report about this from earlier this year was after a powerfail presumably on a system with write cache and without barriers. Add a quick sanity check for the attr fork size in xfs_iformat to catch these early and without an oops. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner --- fs/xfs/xfs_inode.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 5a5e035e5d3..323ecd76a12 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -424,6 +424,19 @@ xfs_iformat( case XFS_DINODE_FMT_LOCAL: atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip); size = be16_to_cpu(atp->hdr.totsize); + + if (unlikely(size < sizeof(struct xfs_attr_sf_hdr))) { + xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, + "corrupt inode %Lu " + "(bad attr fork size %Ld).", + (unsigned long long) ip->i_ino, + (long long) size); + XFS_CORRUPTION_ERROR("xfs_iformat(8)", + XFS_ERRLEVEL_LOW, + ip->i_mount, dip); + return XFS_ERROR(EFSCORRUPTED); + } + error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, size); break; case XFS_DINODE_FMT_EXTENTS: -- cgit From b6e3222732a3551e786aa47b90a8eab2a517711c Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Wed, 14 Jan 2009 23:22:07 -0600 Subject: [XFS] Remove the rest of the macro-to-function indirections. Remove the last of the macros-defined-to-static-functions. Signed-off-by: Eric Sandeen Reviewed-by: Christoph Hellwig Signed-off-by: Lachlan McIlroy --- fs/xfs/quota/xfs_dquot.c | 2 +- fs/xfs/xfs_ag.h | 6 +- fs/xfs/xfs_alloc_btree.c | 2 +- fs/xfs/xfs_attr.c | 26 ++++---- fs/xfs/xfs_bmap.c | 166 +++++++++++++++++++++++----------------------- fs/xfs/xfs_bmap.h | 2 - fs/xfs/xfs_bmap_btree.c | 10 +-- fs/xfs/xfs_bmap_btree.h | 4 -- fs/xfs/xfs_btree.c | 6 +- fs/xfs/xfs_da_btree.c | 8 +-- fs/xfs/xfs_ialloc.c | 6 +- fs/xfs/xfs_ialloc.h | 2 - fs/xfs/xfs_ialloc_btree.h | 1 - fs/xfs/xfs_inode.c | 6 +- fs/xfs/xfs_inode_item.h | 4 -- fs/xfs/xfs_iomap.c | 10 +-- fs/xfs/xfs_itable.c | 6 +- fs/xfs/xfs_mount.h | 6 +- fs/xfs/xfs_rename.c | 2 +- fs/xfs/xfs_rtalloc.c | 2 +- fs/xfs/xfs_rw.h | 1 - fs/xfs/xfs_sb.h | 2 +- fs/xfs/xfs_vnodeops.c | 20 +++--- 23 files changed, 142 insertions(+), 158 deletions(-) diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index f0bc7846580..6543c0b2975 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c @@ -431,7 +431,7 @@ xfs_qm_dqalloc( /* * Initialize the bmap freelist prior to calling bmapi code. */ - XFS_BMAP_INIT(&flist, &firstblock); + xfs_bmap_init(&flist, &firstblock); xfs_ilock(quotip, XFS_ILOCK_EXCL); /* * Return if this type of quotas is turned off while we didn't diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h index d3b3cf74299..143d63ecb20 100644 --- a/fs/xfs/xfs_ag.h +++ b/fs/xfs/xfs_ag.h @@ -244,8 +244,8 @@ typedef struct xfs_perag #define XFS_AG_CHECK_DADDR(mp,d,len) \ ((len) == 1 ? \ ASSERT((d) == XFS_SB_DADDR || \ - XFS_DADDR_TO_AGBNO(mp, d) != XFS_SB_DADDR) : \ - ASSERT(XFS_DADDR_TO_AGNO(mp, d) == \ - XFS_DADDR_TO_AGNO(mp, (d) + (len) - 1))) + xfs_daddr_to_agbno(mp, d) != XFS_SB_DADDR) : \ + ASSERT(xfs_daddr_to_agno(mp, d) == \ + xfs_daddr_to_agno(mp, (d) + (len) - 1))) #endif /* __XFS_AG_H__ */ diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c index 733cb75a8c5..c10c3a292d3 100644 --- a/fs/xfs/xfs_alloc_btree.c +++ b/fs/xfs/xfs_alloc_btree.c @@ -115,7 +115,7 @@ xfs_allocbt_free_block( xfs_agblock_t bno; int error; - bno = XFS_DADDR_TO_AGBNO(cur->bc_mp, XFS_BUF_ADDR(bp)); + bno = xfs_daddr_to_agbno(cur->bc_mp, XFS_BUF_ADDR(bp)); error = xfs_alloc_put_freelist(cur->bc_tp, agbp, NULL, bno, 1); if (error) return error; diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index f7cdc28aff4..5fde1654b43 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c @@ -374,7 +374,7 @@ xfs_attr_set_int(xfs_inode_t *dp, struct xfs_name *name, * It won't fit in the shortform, transform to a leaf block. * GROT: another possible req'mt for a double-split btree op. */ - XFS_BMAP_INIT(args.flist, args.firstblock); + xfs_bmap_init(args.flist, args.firstblock); error = xfs_attr_shortform_to_leaf(&args); if (!error) { error = xfs_bmap_finish(&args.trans, args.flist, @@ -956,7 +956,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) * Commit that transaction so that the node_addname() call * can manage its own transactions. */ - XFS_BMAP_INIT(args->flist, args->firstblock); + xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr_leaf_to_node(args); if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, @@ -1057,7 +1057,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) * If the result is small enough, shrink it all into the inode. */ if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { - XFS_BMAP_INIT(args->flist, args->firstblock); + xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (!error) { @@ -1135,7 +1135,7 @@ xfs_attr_leaf_removename(xfs_da_args_t *args) * If the result is small enough, shrink it all into the inode. */ if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { - XFS_BMAP_INIT(args->flist, args->firstblock); + xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (!error) { @@ -1290,7 +1290,7 @@ restart: * have been a b-tree. */ xfs_da_state_free(state); - XFS_BMAP_INIT(args->flist, args->firstblock); + xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr_leaf_to_node(args); if (!error) { error = xfs_bmap_finish(&args->trans, @@ -1331,7 +1331,7 @@ restart: * in the index/blkno/rmtblkno/rmtblkcnt fields and * in the index2/blkno2/rmtblkno2/rmtblkcnt2 fields. */ - XFS_BMAP_INIT(args->flist, args->firstblock); + xfs_bmap_init(args->flist, args->firstblock); error = xfs_da_split(state); if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, @@ -1443,7 +1443,7 @@ restart: * Check to see if the tree needs to be collapsed. */ if (retval && (state->path.active > 1)) { - XFS_BMAP_INIT(args->flist, args->firstblock); + xfs_bmap_init(args->flist, args->firstblock); error = xfs_da_join(state); if (!error) { error = xfs_bmap_finish(&args->trans, @@ -1579,7 +1579,7 @@ xfs_attr_node_removename(xfs_da_args_t *args) * Check to see if the tree needs to be collapsed. */ if (retval && (state->path.active > 1)) { - XFS_BMAP_INIT(args->flist, args->firstblock); + xfs_bmap_init(args->flist, args->firstblock); error = xfs_da_join(state); if (!error) { error = xfs_bmap_finish(&args->trans, args->flist, @@ -1630,7 +1630,7 @@ xfs_attr_node_removename(xfs_da_args_t *args) == XFS_ATTR_LEAF_MAGIC); if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { - XFS_BMAP_INIT(args->flist, args->firstblock); + xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ if (!error) { @@ -2069,7 +2069,7 @@ xfs_attr_rmtval_set(xfs_da_args_t *args) /* * Allocate a single extent, up to the size of the value. */ - XFS_BMAP_INIT(args->flist, args->firstblock); + xfs_bmap_init(args->flist, args->firstblock); nmap = 1; error = xfs_bmapi(args->trans, dp, (xfs_fileoff_t)lblkno, blkcnt, @@ -2123,7 +2123,7 @@ xfs_attr_rmtval_set(xfs_da_args_t *args) /* * Try to remember where we decided to put the value. */ - XFS_BMAP_INIT(args->flist, args->firstblock); + xfs_bmap_init(args->flist, args->firstblock); nmap = 1; error = xfs_bmapi(NULL, dp, (xfs_fileoff_t)lblkno, args->rmtblkcnt, @@ -2188,7 +2188,7 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args) /* * Try to remember where we decided to put the value. */ - XFS_BMAP_INIT(args->flist, args->firstblock); + xfs_bmap_init(args->flist, args->firstblock); nmap = 1; error = xfs_bmapi(NULL, args->dp, (xfs_fileoff_t)lblkno, args->rmtblkcnt, @@ -2229,7 +2229,7 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args) blkcnt = args->rmtblkcnt; done = 0; while (!done) { - XFS_BMAP_INIT(args->flist, args->firstblock); + xfs_bmap_init(args->flist, args->firstblock); error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 1, args->firstblock, args->flist, diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 138308e70d1..c852cd65aae 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c @@ -595,9 +595,9 @@ xfs_bmap_add_extent( xfs_iext_insert(ifp, 0, 1, new); ASSERT(cur == NULL); ifp->if_lastex = 0; - if (!ISNULLSTARTBLOCK(new->br_startblock)) { + if (!isnullstartblock(new->br_startblock)) { XFS_IFORK_NEXT_SET(ip, whichfork, 1); - logflags = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); + logflags = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); } else logflags = 0; /* DELTA: single new extent */ @@ -613,7 +613,7 @@ xfs_bmap_add_extent( /* * Any kind of new delayed allocation goes here. */ - else if (ISNULLSTARTBLOCK(new->br_startblock)) { + else if (isnullstartblock(new->br_startblock)) { if (cur) ASSERT((cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL) == 0); @@ -644,11 +644,11 @@ xfs_bmap_add_extent( * in a delayed or unwritten allocation with a real one, or * converting real back to unwritten. */ - if (!ISNULLSTARTBLOCK(new->br_startblock) && + if (!isnullstartblock(new->br_startblock) && new->br_startoff + new->br_blockcount > prev.br_startoff) { if (prev.br_state != XFS_EXT_UNWRITTEN && - ISNULLSTARTBLOCK(prev.br_startblock)) { - da_old = STARTBLOCKVAL(prev.br_startblock); + isnullstartblock(prev.br_startblock)) { + da_old = startblockval(prev.br_startblock); if (cur) ASSERT(cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL); @@ -803,7 +803,7 @@ xfs_bmap_add_extent_delay_real( */ if (STATE_SET_TEST(LEFT_VALID, idx > 0)) { xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &LEFT); - STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(LEFT.br_startblock)); + STATE_SET(LEFT_DELAY, isnullstartblock(LEFT.br_startblock)); } STATE_SET(LEFT_CONTIG, STATE_TEST(LEFT_VALID) && !STATE_TEST(LEFT_DELAY) && @@ -820,7 +820,7 @@ xfs_bmap_add_extent_delay_real( idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1)) { xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx + 1), &RIGHT); - STATE_SET(RIGHT_DELAY, ISNULLSTARTBLOCK(RIGHT.br_startblock)); + STATE_SET(RIGHT_DELAY, isnullstartblock(RIGHT.br_startblock)); } STATE_SET(RIGHT_CONTIG, STATE_TEST(RIGHT_VALID) && !STATE_TEST(RIGHT_DELAY) && @@ -1019,8 +1019,8 @@ xfs_bmap_add_extent_delay_real( goto done; } temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), - STARTBLOCKVAL(PREV.br_startblock)); - xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); + startblockval(PREV.br_startblock)); + xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); XFS_BMAP_TRACE_POST_UPDATE("LF|LC", ip, idx, XFS_DATA_FORK); *dnew = temp; /* DELTA: The boundary between two in-core extents moved. */ @@ -1067,10 +1067,10 @@ xfs_bmap_add_extent_delay_real( goto done; } temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), - STARTBLOCKVAL(PREV.br_startblock) - + startblockval(PREV.br_startblock) - (cur ? cur->bc_private.b.allocated : 0)); ep = xfs_iext_get_ext(ifp, idx + 1); - xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); + xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); XFS_BMAP_TRACE_POST_UPDATE("LF", ip, idx + 1, XFS_DATA_FORK); *dnew = temp; /* DELTA: One in-core extent is split in two. */ @@ -1110,8 +1110,8 @@ xfs_bmap_add_extent_delay_real( goto done; } temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), - STARTBLOCKVAL(PREV.br_startblock)); - xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); + startblockval(PREV.br_startblock)); + xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); XFS_BMAP_TRACE_POST_UPDATE("RF|RC", ip, idx, XFS_DATA_FORK); *dnew = temp; /* DELTA: The boundary between two in-core extents moved. */ @@ -1157,10 +1157,10 @@ xfs_bmap_add_extent_delay_real( goto done; } temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), - STARTBLOCKVAL(PREV.br_startblock) - + startblockval(PREV.br_startblock) - (cur ? cur->bc_private.b.allocated : 0)); ep = xfs_iext_get_ext(ifp, idx); - xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); + xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); XFS_BMAP_TRACE_POST_UPDATE("RF", ip, idx, XFS_DATA_FORK); *dnew = temp; /* DELTA: One in-core extent is split in two. */ @@ -1213,7 +1213,7 @@ xfs_bmap_add_extent_delay_real( } temp = xfs_bmap_worst_indlen(ip, temp); temp2 = xfs_bmap_worst_indlen(ip, temp2); - diff = (int)(temp + temp2 - STARTBLOCKVAL(PREV.br_startblock) - + diff = (int)(temp + temp2 - startblockval(PREV.br_startblock) - (cur ? cur->bc_private.b.allocated : 0)); if (diff > 0 && xfs_mod_incore_sb(ip->i_mount, XFS_SBS_FDBLOCKS, -((int64_t)diff), rsvd)) { @@ -1241,11 +1241,11 @@ xfs_bmap_add_extent_delay_real( } } ep = xfs_iext_get_ext(ifp, idx); - xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); + xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); XFS_BMAP_TRACE_POST_UPDATE("0", ip, idx, XFS_DATA_FORK); XFS_BMAP_TRACE_PRE_UPDATE("0", ip, idx + 2, XFS_DATA_FORK); xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx + 2), - NULLSTARTBLOCK((int)temp2)); + nullstartblock((int)temp2)); XFS_BMAP_TRACE_POST_UPDATE("0", ip, idx + 2, XFS_DATA_FORK); *dnew = temp + temp2; /* DELTA: One in-core extent is split in three. */ @@ -1365,7 +1365,7 @@ xfs_bmap_add_extent_unwritten_real( */ if (STATE_SET_TEST(LEFT_VALID, idx > 0)) { xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &LEFT); - STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(LEFT.br_startblock)); + STATE_SET(LEFT_DELAY, isnullstartblock(LEFT.br_startblock)); } STATE_SET(LEFT_CONTIG, STATE_TEST(LEFT_VALID) && !STATE_TEST(LEFT_DELAY) && @@ -1382,7 +1382,7 @@ xfs_bmap_add_extent_unwritten_real( idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t) - 1)) { xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx + 1), &RIGHT); - STATE_SET(RIGHT_DELAY, ISNULLSTARTBLOCK(RIGHT.br_startblock)); + STATE_SET(RIGHT_DELAY, isnullstartblock(RIGHT.br_startblock)); } STATE_SET(RIGHT_CONTIG, STATE_TEST(RIGHT_VALID) && !STATE_TEST(RIGHT_DELAY) && @@ -1889,13 +1889,13 @@ xfs_bmap_add_extent_hole_delay( ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); ep = xfs_iext_get_ext(ifp, idx); state = 0; - ASSERT(ISNULLSTARTBLOCK(new->br_startblock)); + ASSERT(isnullstartblock(new->br_startblock)); /* * Check and set flags if this segment has a left neighbor */ if (STATE_SET_TEST(LEFT_VALID, idx > 0)) { xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &left); - STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(left.br_startblock)); + STATE_SET(LEFT_DELAY, isnullstartblock(left.br_startblock)); } /* * Check and set flags if the current (right) segment exists. @@ -1905,7 +1905,7 @@ xfs_bmap_add_extent_hole_delay( idx < ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) { xfs_bmbt_get_all(ep, &right); - STATE_SET(RIGHT_DELAY, ISNULLSTARTBLOCK(right.br_startblock)); + STATE_SET(RIGHT_DELAY, isnullstartblock(right.br_startblock)); } /* * Set contiguity flags on the left and right neighbors. @@ -1938,12 +1938,12 @@ xfs_bmap_add_extent_hole_delay( XFS_BMAP_TRACE_PRE_UPDATE("LC|RC", ip, idx - 1, XFS_DATA_FORK); xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp); - oldlen = STARTBLOCKVAL(left.br_startblock) + - STARTBLOCKVAL(new->br_startblock) + - STARTBLOCKVAL(right.br_startblock); + oldlen = startblockval(left.br_startblock) + + startblockval(new->br_startblock) + + startblockval(right.br_startblock); newlen = xfs_bmap_worst_indlen(ip, temp); xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1), - NULLSTARTBLOCK((int)newlen)); + nullstartblock((int)newlen)); XFS_BMAP_TRACE_POST_UPDATE("LC|RC", ip, idx - 1, XFS_DATA_FORK); XFS_BMAP_TRACE_DELETE("LC|RC", ip, idx, 1, XFS_DATA_FORK); @@ -1964,11 +1964,11 @@ xfs_bmap_add_extent_hole_delay( XFS_BMAP_TRACE_PRE_UPDATE("LC", ip, idx - 1, XFS_DATA_FORK); xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp); - oldlen = STARTBLOCKVAL(left.br_startblock) + - STARTBLOCKVAL(new->br_startblock); + oldlen = startblockval(left.br_startblock) + + startblockval(new->br_startblock); newlen = xfs_bmap_worst_indlen(ip, temp); xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1), - NULLSTARTBLOCK((int)newlen)); + nullstartblock((int)newlen)); XFS_BMAP_TRACE_POST_UPDATE("LC", ip, idx - 1, XFS_DATA_FORK); ip->i_df.if_lastex = idx - 1; @@ -1985,11 +1985,11 @@ xfs_bmap_add_extent_hole_delay( */ XFS_BMAP_TRACE_PRE_UPDATE("RC", ip, idx, XFS_DATA_FORK); temp = new->br_blockcount + right.br_blockcount; - oldlen = STARTBLOCKVAL(new->br_startblock) + - STARTBLOCKVAL(right.br_startblock); + oldlen = startblockval(new->br_startblock) + + startblockval(right.br_startblock); newlen = xfs_bmap_worst_indlen(ip, temp); xfs_bmbt_set_allf(ep, new->br_startoff, - NULLSTARTBLOCK((int)newlen), temp, right.br_state); + nullstartblock((int)newlen), temp, right.br_state); XFS_BMAP_TRACE_POST_UPDATE("RC", ip, idx, XFS_DATA_FORK); ip->i_df.if_lastex = idx; /* DELTA: One in-core extent grew into a hole. */ @@ -2085,7 +2085,7 @@ xfs_bmap_add_extent_hole_real( */ if (STATE_SET_TEST(LEFT_VALID, idx > 0)) { xfs_bmbt_get_all(xfs_iext_get_ext(ifp, idx - 1), &left); - STATE_SET(LEFT_DELAY, ISNULLSTARTBLOCK(left.br_startblock)); + STATE_SET(LEFT_DELAY, isnullstartblock(left.br_startblock)); } /* * Check and set flags if this segment has a current value. @@ -2095,7 +2095,7 @@ xfs_bmap_add_extent_hole_real( idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))) { xfs_bmbt_get_all(ep, &right); - STATE_SET(RIGHT_DELAY, ISNULLSTARTBLOCK(right.br_startblock)); + STATE_SET(RIGHT_DELAY, isnullstartblock(right.br_startblock)); } /* * We're inserting a real allocation between "left" and "right". @@ -2143,7 +2143,7 @@ xfs_bmap_add_extent_hole_real( XFS_IFORK_NEXT_SET(ip, whichfork, XFS_IFORK_NEXTENTS(ip, whichfork) - 1); if (cur == NULL) { - rval = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); + rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); } else { rval = XFS_ILOG_CORE; if ((error = xfs_bmbt_lookup_eq(cur, @@ -2185,7 +2185,7 @@ xfs_bmap_add_extent_hole_real( XFS_BMAP_TRACE_POST_UPDATE("LC", ip, idx - 1, whichfork); ifp->if_lastex = idx - 1; if (cur == NULL) { - rval = XFS_ILOG_FEXT(whichfork); + rval = xfs_ilog_fext(whichfork); } else { rval = 0; if ((error = xfs_bmbt_lookup_eq(cur, @@ -2220,7 +2220,7 @@ xfs_bmap_add_extent_hole_real( XFS_BMAP_TRACE_POST_UPDATE("RC", ip, idx, whichfork); ifp->if_lastex = idx; if (cur == NULL) { - rval = XFS_ILOG_FEXT(whichfork); + rval = xfs_ilog_fext(whichfork); } else { rval = 0; if ((error = xfs_bmbt_lookup_eq(cur, @@ -2254,7 +2254,7 @@ xfs_bmap_add_extent_hole_real( XFS_IFORK_NEXT_SET(ip, whichfork, XFS_IFORK_NEXTENTS(ip, whichfork) + 1); if (cur == NULL) { - rval = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); + rval = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); } else { rval = XFS_ILOG_CORE; if ((error = xfs_bmbt_lookup_eq(cur, @@ -2482,7 +2482,7 @@ xfs_bmap_adjacent( * try to use it's last block as our starting point. */ if (ap->eof && ap->prevp->br_startoff != NULLFILEOFF && - !ISNULLSTARTBLOCK(ap->prevp->br_startblock) && + !isnullstartblock(ap->prevp->br_startblock) && ISVALID(ap->prevp->br_startblock + ap->prevp->br_blockcount, ap->prevp->br_startblock)) { ap->rval = ap->prevp->br_startblock + ap->prevp->br_blockcount; @@ -2511,7 +2511,7 @@ xfs_bmap_adjacent( * start block based on it. */ if (ap->prevp->br_startoff != NULLFILEOFF && - !ISNULLSTARTBLOCK(ap->prevp->br_startblock) && + !isnullstartblock(ap->prevp->br_startblock) && (prevbno = ap->prevp->br_startblock + ap->prevp->br_blockcount) && ISVALID(prevbno, ap->prevp->br_startblock)) { @@ -2552,7 +2552,7 @@ xfs_bmap_adjacent( * If there's a following (right) block, select a requested * start block based on it. */ - if (!ISNULLSTARTBLOCK(ap->gotp->br_startblock)) { + if (!isnullstartblock(ap->gotp->br_startblock)) { /* * Calculate gap to start of next block. */ @@ -3082,7 +3082,7 @@ xfs_bmap_btree_to_extents( ASSERT(ifp->if_broot == NULL); ASSERT((ifp->if_flags & XFS_IFBROOT) == 0); XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); - *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); + *logflagsp = XFS_ILOG_CORE | xfs_ilog_fext(whichfork); return 0; } @@ -3136,8 +3136,8 @@ xfs_bmap_del_extent( del_endoff = del->br_startoff + del->br_blockcount; got_endoff = got.br_startoff + got.br_blockcount; ASSERT(got_endoff >= del_endoff); - delay = ISNULLSTARTBLOCK(got.br_startblock); - ASSERT(ISNULLSTARTBLOCK(del->br_startblock) == delay); + delay = isnullstartblock(got.br_startblock); + ASSERT(isnullstartblock(del->br_startblock) == delay); flags = 0; qfield = 0; error = 0; @@ -3189,7 +3189,7 @@ xfs_bmap_del_extent( } da_old = da_new = 0; } else { - da_old = STARTBLOCKVAL(got.br_startblock); + da_old = startblockval(got.br_startblock); da_new = 0; nblks = 0; do_fx = 0; @@ -3213,7 +3213,7 @@ xfs_bmap_del_extent( XFS_IFORK_NEXTENTS(ip, whichfork) - 1); flags |= XFS_ILOG_CORE; if (!cur) { - flags |= XFS_ILOG_FEXT(whichfork); + flags |= xfs_ilog_fext(whichfork); break; } if ((error = xfs_btree_delete(cur, &i))) @@ -3233,7 +3233,7 @@ xfs_bmap_del_extent( if (delay) { temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), da_old); - xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); + xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); XFS_BMAP_TRACE_POST_UPDATE("2", ip, idx, whichfork); da_new = temp; @@ -3242,7 +3242,7 @@ xfs_bmap_del_extent( xfs_bmbt_set_startblock(ep, del_endblock); XFS_BMAP_TRACE_POST_UPDATE("2", ip, idx, whichfork); if (!cur) { - flags |= XFS_ILOG_FEXT(whichfork); + flags |= xfs_ilog_fext(whichfork); break; } if ((error = xfs_bmbt_update(cur, del_endoff, del_endblock, @@ -3262,7 +3262,7 @@ xfs_bmap_del_extent( if (delay) { temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), da_old); - xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); + xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); XFS_BMAP_TRACE_POST_UPDATE("1", ip, idx, whichfork); da_new = temp; @@ -3270,7 +3270,7 @@ xfs_bmap_del_extent( } XFS_BMAP_TRACE_POST_UPDATE("1", ip, idx, whichfork); if (!cur) { - flags |= XFS_ILOG_FEXT(whichfork); + flags |= xfs_ilog_fext(whichfork); break; } if ((error = xfs_bmbt_update(cur, got.br_startoff, @@ -3345,22 +3345,22 @@ xfs_bmap_del_extent( } XFS_WANT_CORRUPTED_GOTO(i == 1, done); } else - flags |= XFS_ILOG_FEXT(whichfork); + flags |= xfs_ilog_fext(whichfork); XFS_IFORK_NEXT_SET(ip, whichfork, XFS_IFORK_NEXTENTS(ip, whichfork) + 1); } else { ASSERT(whichfork == XFS_DATA_FORK); temp = xfs_bmap_worst_indlen(ip, temp); - xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); + xfs_bmbt_set_startblock(ep, nullstartblock((int)temp)); temp2 = xfs_bmap_worst_indlen(ip, temp2); - new.br_startblock = NULLSTARTBLOCK((int)temp2); + new.br_startblock = nullstartblock((int)temp2); da_new = temp + temp2; while (da_new > da_old) { if (temp) { temp--; da_new--; xfs_bmbt_set_startblock(ep, - NULLSTARTBLOCK((int)temp)); + nullstartblock((int)temp)); } if (da_new == da_old) break; @@ -3368,7 +3368,7 @@ xfs_bmap_del_extent( temp2--; da_new--; new.br_startblock = - NULLSTARTBLOCK((int)temp2); + nullstartblock((int)temp2); } } } @@ -3545,7 +3545,7 @@ xfs_bmap_extents_to_btree( nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); for (cnt = i = 0; i < nextents; i++) { ep = xfs_iext_get_ext(ifp, i); - if (!ISNULLSTARTBLOCK(xfs_bmbt_get_startblock(ep))) { + if (!isnullstartblock(xfs_bmbt_get_startblock(ep))) { arp->l0 = cpu_to_be64(ep->l0); arp->l1 = cpu_to_be64(ep->l1); arp++; cnt++; @@ -3572,7 +3572,7 @@ xfs_bmap_extents_to_btree( xfs_btree_log_recs(cur, abp, 1, be16_to_cpu(ablock->bb_numrecs)); ASSERT(*curp == NULL); *curp = cur; - *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FBROOT(whichfork); + *logflagsp = XFS_ILOG_CORE | xfs_ilog_fbroot(whichfork); return 0; } @@ -3676,7 +3676,7 @@ xfs_bmap_local_to_extents( ip->i_d.di_nblocks = 1; XFS_TRANS_MOD_DQUOT_BYINO(args.mp, tp, ip, XFS_TRANS_DQ_BCOUNT, 1L); - flags |= XFS_ILOG_FEXT(whichfork); + flags |= xfs_ilog_fext(whichfork); } else { ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0); xfs_bmap_forkoff_reset(ip->i_mount, ip, whichfork); @@ -4082,7 +4082,7 @@ xfs_bmap_add_attrfork( XFS_IFORK_ASIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); ip->i_afp->if_flags = XFS_IFEXTENTS; logflags = 0; - XFS_BMAP_INIT(&flist, &firstblock); + xfs_bmap_init(&flist, &firstblock); switch (ip->i_d.di_format) { case XFS_DINODE_FMT_LOCAL: error = xfs_bmap_add_attrfork_local(tp, ip, &firstblock, &flist, @@ -4162,7 +4162,7 @@ xfs_bmap_add_free( ASSERT(bno != NULLFSBLOCK); ASSERT(len > 0); ASSERT(len <= MAXEXTLEN); - ASSERT(!ISNULLSTARTBLOCK(bno)); + ASSERT(!isnullstartblock(bno)); agno = XFS_FSB_TO_AGNO(mp, bno); agbno = XFS_FSB_TO_AGBNO(mp, bno); ASSERT(agno < mp->m_sb.sb_agcount); @@ -4909,7 +4909,7 @@ xfs_bmapi( got.br_startoff = end; inhole = eof || got.br_startoff > bno; wasdelay = wr && !inhole && !(flags & XFS_BMAPI_DELAY) && - ISNULLSTARTBLOCK(got.br_startblock); + isnullstartblock(got.br_startblock); /* * First, deal with the hole before the allocated space * that we found, if any. @@ -5028,7 +5028,7 @@ xfs_bmapi( } ip->i_delayed_blks += alen; - abno = NULLSTARTBLOCK(indlen); + abno = nullstartblock(indlen); } else { /* * If first time, allocate and fill in @@ -5144,8 +5144,8 @@ xfs_bmapi( aoff + alen); #ifdef DEBUG if (flags & XFS_BMAPI_DELAY) { - ASSERT(ISNULLSTARTBLOCK(got.br_startblock)); - ASSERT(STARTBLOCKVAL(got.br_startblock) > 0); + ASSERT(isnullstartblock(got.br_startblock)); + ASSERT(startblockval(got.br_startblock) > 0); } ASSERT(got.br_state == XFS_EXT_NORM || got.br_state == XFS_EXT_UNWRITTEN); @@ -5179,7 +5179,7 @@ xfs_bmapi( ASSERT((bno >= obno) || (n == 0)); ASSERT(bno < end); mval->br_startoff = bno; - if (ISNULLSTARTBLOCK(got.br_startblock)) { + if (isnullstartblock(got.br_startblock)) { ASSERT(!wr || (flags & XFS_BMAPI_DELAY)); mval->br_startblock = DELAYSTARTBLOCK; } else @@ -5201,7 +5201,7 @@ xfs_bmapi( ASSERT(mval->br_blockcount <= len); } else { *mval = got; - if (ISNULLSTARTBLOCK(mval->br_startblock)) { + if (isnullstartblock(mval->br_startblock)) { ASSERT(!wr || (flags & XFS_BMAPI_DELAY)); mval->br_startblock = DELAYSTARTBLOCK; } @@ -5329,12 +5329,12 @@ error0: * Log everything. Do this after conversion, there's no point in * logging the extent records if we've converted to btree format. */ - if ((logflags & XFS_ILOG_FEXT(whichfork)) && + if ((logflags & xfs_ilog_fext(whichfork)) && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) - logflags &= ~XFS_ILOG_FEXT(whichfork); - else if ((logflags & XFS_ILOG_FBROOT(whichfork)) && + logflags &= ~xfs_ilog_fext(whichfork); + else if ((logflags & xfs_ilog_fbroot(whichfork)) && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) - logflags &= ~XFS_ILOG_FBROOT(whichfork); + logflags &= ~xfs_ilog_fbroot(whichfork); /* * Log whatever the flags say, even if error. Otherwise we might miss * detecting a case where the data is changed, there's an error, @@ -5411,7 +5411,7 @@ xfs_bmapi_single( *fsb = NULLFSBLOCK; return 0; } - ASSERT(!ISNULLSTARTBLOCK(got.br_startblock)); + ASSERT(!isnullstartblock(got.br_startblock)); ASSERT(bno < got.br_startoff + got.br_blockcount); *fsb = got.br_startblock + (bno - got.br_startoff); ifp->if_lastex = lastx; @@ -5543,7 +5543,7 @@ xfs_bunmapi( */ ASSERT(ep != NULL); del = got; - wasdel = ISNULLSTARTBLOCK(del.br_startblock); + wasdel = isnullstartblock(del.br_startblock); if (got.br_startoff < start) { del.br_startoff = start; del.br_blockcount -= start - got.br_startoff; @@ -5638,7 +5638,7 @@ xfs_bunmapi( xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx - 1), &prev); ASSERT(prev.br_state == XFS_EXT_NORM); - ASSERT(!ISNULLSTARTBLOCK(prev.br_startblock)); + ASSERT(!isnullstartblock(prev.br_startblock)); ASSERT(del.br_startblock == prev.br_startblock + prev.br_blockcount); if (prev.br_startoff < start) { @@ -5666,7 +5666,7 @@ xfs_bunmapi( } } if (wasdel) { - ASSERT(STARTBLOCKVAL(del.br_startblock) > 0); + ASSERT(startblockval(del.br_startblock) > 0); /* Update realtime/data freespace, unreserve quota */ if (isrt) { xfs_filblks_t rtexts; @@ -5782,12 +5782,12 @@ error0: * Log everything. Do this after conversion, there's no point in * logging the extent records if we've converted to btree format. */ - if ((logflags & XFS_ILOG_FEXT(whichfork)) && + if ((logflags & xfs_ilog_fext(whichfork)) && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) - logflags &= ~XFS_ILOG_FEXT(whichfork); - else if ((logflags & XFS_ILOG_FBROOT(whichfork)) && + logflags &= ~xfs_ilog_fext(whichfork); + else if ((logflags & xfs_ilog_fbroot(whichfork)) && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) - logflags &= ~XFS_ILOG_FBROOT(whichfork); + logflags &= ~xfs_ilog_fbroot(whichfork); /* * Log inode even in the error case, if the transaction * is dirty we'll need to shut down the filesystem. @@ -5838,7 +5838,7 @@ xfs_getbmapx_fix_eof_hole( if (startblock == DELAYSTARTBLOCK) out->bmv_block = -2; else - out->bmv_block = XFS_FSB_TO_DB(ip, startblock); + out->bmv_block = xfs_fsb_to_db(ip, startblock); fileblock = XFS_BB_TO_FSB(ip->i_mount, out->bmv_offset); ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); if (xfs_iext_bno_to_ext(ifp, fileblock, &lastx) && @@ -5979,7 +5979,7 @@ xfs_getbmap( if (nex > XFS_IFORK_NEXTENTS(ip, whichfork) * 2 + 1) nex = XFS_IFORK_NEXTENTS(ip, whichfork) * 2 + 1; - bmapi_flags = XFS_BMAPI_AFLAG(whichfork) | + bmapi_flags = xfs_bmapi_aflag(whichfork) | ((iflags & BMV_IF_PREALLOC) ? 0 : XFS_BMAPI_IGSTATE); /* @@ -6098,7 +6098,7 @@ xfs_bmap_isaeof( */ *aeof = (off >= s.br_startoff && off < s.br_startoff + s.br_blockcount && - ISNULLSTARTBLOCK(s.br_startblock)) || + isnullstartblock(s.br_startblock)) || off >= s.br_startoff + s.br_blockcount; return 0; } diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h index 284571c05ed..be2979d88d3 100644 --- a/fs/xfs/xfs_bmap.h +++ b/fs/xfs/xfs_bmap.h @@ -95,7 +95,6 @@ typedef struct xfs_bmap_free /* need write cache flushing and no */ /* additional allocation alignments */ -#define XFS_BMAPI_AFLAG(w) xfs_bmapi_aflag(w) static inline int xfs_bmapi_aflag(int w) { return (w == XFS_ATTR_FORK ? XFS_BMAPI_ATTRFORK : 0); @@ -107,7 +106,6 @@ static inline int xfs_bmapi_aflag(int w) #define DELAYSTARTBLOCK ((xfs_fsblock_t)-1LL) #define HOLESTARTBLOCK ((xfs_fsblock_t)-2LL) -#define XFS_BMAP_INIT(flp,fbp) xfs_bmap_init(flp,fbp) static inline void xfs_bmap_init(xfs_bmap_free_t *flp, xfs_fsblock_t *fbp) { ((flp)->xbf_first = NULL, (flp)->xbf_count = 0, \ diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index ba6b08c2fb0..0760d352586 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c @@ -121,7 +121,7 @@ __xfs_bmbt_get_all( b = (((xfs_dfsbno_t)l0 & xfs_mask64lo(9)) << 43) | (((xfs_dfsbno_t)l1) >> 21); - ASSERT((b >> 32) == 0 || ISNULLDSTARTBLOCK(b)); + ASSERT((b >> 32) == 0 || isnulldstartblock(b)); s->br_startblock = (xfs_fsblock_t)b; } #else /* !DEBUG */ @@ -172,7 +172,7 @@ xfs_bmbt_get_startblock( b = (((xfs_dfsbno_t)r->l0 & xfs_mask64lo(9)) << 43) | (((xfs_dfsbno_t)r->l1) >> 21); - ASSERT((b >> 32) == 0 || ISNULLDSTARTBLOCK(b)); + ASSERT((b >> 32) == 0 || isnulldstartblock(b)); return (xfs_fsblock_t)b; #else /* !DEBUG */ return (xfs_fsblock_t)(((xfs_dfsbno_t)r->l1) >> 21); @@ -261,7 +261,7 @@ xfs_bmbt_set_allf( ((xfs_bmbt_rec_base_t)blockcount & (xfs_bmbt_rec_base_t)xfs_mask64lo(21)); #else /* !XFS_BIG_BLKNOS */ - if (ISNULLSTARTBLOCK(startblock)) { + if (isnullstartblock(startblock)) { r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | ((xfs_bmbt_rec_base_t)startoff << 9) | (xfs_bmbt_rec_base_t)xfs_mask64lo(9); @@ -321,7 +321,7 @@ xfs_bmbt_disk_set_allf( ((xfs_bmbt_rec_base_t)blockcount & (xfs_bmbt_rec_base_t)xfs_mask64lo(21))); #else /* !XFS_BIG_BLKNOS */ - if (ISNULLSTARTBLOCK(startblock)) { + if (isnullstartblock(startblock)) { r->l0 = cpu_to_be64( ((xfs_bmbt_rec_base_t)extent_flag << 63) | ((xfs_bmbt_rec_base_t)startoff << 9) | @@ -382,7 +382,7 @@ xfs_bmbt_set_startblock( r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)xfs_mask64lo(21)) | (xfs_bmbt_rec_base_t)(v << 21); #else /* !XFS_BIG_BLKNOS */ - if (ISNULLSTARTBLOCK(v)) { + if (isnullstartblock(v)) { r->l0 |= (xfs_bmbt_rec_base_t)xfs_mask64lo(9); r->l1 = (xfs_bmbt_rec_base_t)xfs_mask64hi(11) | ((xfs_bmbt_rec_base_t)v << 21) | diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h index a4555abb662..0e8df007615 100644 --- a/fs/xfs/xfs_bmap_btree.h +++ b/fs/xfs/xfs_bmap_btree.h @@ -76,26 +76,22 @@ typedef struct xfs_bmbt_rec_host { #define DSTARTBLOCKMASK \ (((((xfs_dfsbno_t)1) << DSTARTBLOCKMASKBITS) - 1) << STARTBLOCKVALBITS) -#define ISNULLSTARTBLOCK(x) isnullstartblock(x) static inline int isnullstartblock(xfs_fsblock_t x) { return ((x) & STARTBLOCKMASK) == STARTBLOCKMASK; } -#define ISNULLDSTARTBLOCK(x) isnulldstartblock(x) static inline int isnulldstartblock(xfs_dfsbno_t x) { return ((x) & DSTARTBLOCKMASK) == DSTARTBLOCKMASK; } -#define NULLSTARTBLOCK(k) nullstartblock(k) static inline xfs_fsblock_t nullstartblock(int k) { ASSERT(k < (1 << STARTBLOCKVALBITS)); return STARTBLOCKMASK | (k); } -#define STARTBLOCKVAL(x) startblockval(x) static inline xfs_filblks_t startblockval(xfs_fsblock_t x) { return (xfs_filblks_t)((x) & ~STARTBLOCKMASK); diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c index 2c3ef20f884..4681519ded9 100644 --- a/fs/xfs/xfs_btree.c +++ b/fs/xfs/xfs_btree.c @@ -960,7 +960,7 @@ xfs_btree_buf_to_ptr( ptr->l = cpu_to_be64(XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(bp))); else { - ptr->s = cpu_to_be32(XFS_DADDR_TO_AGBNO(cur->bc_mp, + ptr->s = cpu_to_be32(xfs_daddr_to_agbno(cur->bc_mp, XFS_BUF_ADDR(bp))); } } @@ -2454,7 +2454,7 @@ xfs_btree_new_iroot( xfs_btree_log_ptrs(cur, cbp, 1, be16_to_cpu(cblock->bb_numrecs)); *logflags |= - XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork); + XFS_ILOG_CORE | xfs_ilog_fbroot(cur->bc_private.b.whichfork); *stat = 1; XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); return 0; @@ -3048,7 +3048,7 @@ xfs_btree_kill_iroot( cur->bc_bufs[level - 1] = NULL; be16_add_cpu(&block->bb_level, -1); xfs_trans_log_inode(cur->bc_tp, ip, - XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork)); + XFS_ILOG_CORE | xfs_ilog_fbroot(cur->bc_private.b.whichfork)); cur->bc_nlevels--; out0: XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c index a11a8390bf6..c45f74ff1a5 100644 --- a/fs/xfs/xfs_da_btree.c +++ b/fs/xfs/xfs_da_btree.c @@ -1597,7 +1597,7 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno) nmap = 1; ASSERT(args->firstblock != NULL); if ((error = xfs_bmapi(tp, dp, bno, count, - XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA| + xfs_bmapi_aflag(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA| XFS_BMAPI_CONTIG, args->firstblock, args->total, &map, &nmap, args->flist, NULL))) { @@ -1618,7 +1618,7 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno) nmap = MIN(XFS_BMAP_MAX_NMAP, count); c = (int)(bno + count - b); if ((error = xfs_bmapi(tp, dp, b, c, - XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE| + xfs_bmapi_aflag(w)|XFS_BMAPI_WRITE| XFS_BMAPI_METADATA, args->firstblock, args->total, &mapp[mapi], &nmap, args->flist, @@ -1882,7 +1882,7 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, * the last block to the place we want to kill. */ if ((error = xfs_bunmapi(tp, dp, dead_blkno, count, - XFS_BMAPI_AFLAG(w)|XFS_BMAPI_METADATA, + xfs_bmapi_aflag(w)|XFS_BMAPI_METADATA, 0, args->firstblock, args->flist, NULL, &done)) == ENOSPC) { if (w != XFS_DATA_FORK) @@ -1987,7 +1987,7 @@ xfs_da_do_buf( if ((error = xfs_bmapi(trans, dp, (xfs_fileoff_t)bno, nfsb, XFS_BMAPI_METADATA | - XFS_BMAPI_AFLAG(whichfork), + xfs_bmapi_aflag(whichfork), NULL, 0, mapp, &nmap, NULL, NULL))) goto exit0; } diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index e6ebbaeb4dc..ab016e5ae7b 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c @@ -357,7 +357,7 @@ xfs_ialloc_ag_alloc( int ioffset = i << args.mp->m_sb.sb_inodelog; uint isize = sizeof(struct xfs_dinode); - free = XFS_MAKE_IPTR(args.mp, fbuf, i); + free = xfs_make_iptr(args.mp, fbuf, i); free->di_magic = cpu_to_be16(XFS_DINODE_MAGIC); free->di_version = version; free->di_gen = cpu_to_be32(gen); @@ -937,7 +937,7 @@ nextag: } } } - offset = XFS_IALLOC_FIND_FREE(&rec.ir_free); + offset = xfs_ialloc_find_free(&rec.ir_free); ASSERT(offset >= 0); ASSERT(offset < XFS_INODES_PER_CHUNK); ASSERT((XFS_AGINO_TO_OFFSET(mp, rec.ir_startino) % @@ -1279,7 +1279,7 @@ xfs_imap( offset = XFS_INO_TO_OFFSET(mp, ino); ASSERT(offset < mp->m_sb.sb_inopblock); - cluster_agbno = XFS_DADDR_TO_AGBNO(mp, imap->im_blkno); + cluster_agbno = xfs_daddr_to_agbno(mp, imap->im_blkno); offset += (agbno - cluster_agbno) * mp->m_sb.sb_inopblock; imap->im_len = XFS_FSB_TO_BB(mp, blks_per_cluster); diff --git a/fs/xfs/xfs_ialloc.h b/fs/xfs/xfs_ialloc.h index 50f558a4e0a..aeee8278f92 100644 --- a/fs/xfs/xfs_ialloc.h +++ b/fs/xfs/xfs_ialloc.h @@ -39,7 +39,6 @@ struct xfs_trans; /* * Make an inode pointer out of the buffer/offset. */ -#define XFS_MAKE_IPTR(mp,b,o) xfs_make_iptr(mp,b,o) static inline struct xfs_dinode * xfs_make_iptr(struct xfs_mount *mp, struct xfs_buf *b, int o) { @@ -50,7 +49,6 @@ xfs_make_iptr(struct xfs_mount *mp, struct xfs_buf *b, int o) /* * Find a free (set) bit in the inode bitmask. */ -#define XFS_IALLOC_FIND_FREE(fp) xfs_ialloc_find_free(fp) static inline int xfs_ialloc_find_free(xfs_inofree_t *fp) { return xfs_lowbit64(*fp); diff --git a/fs/xfs/xfs_ialloc_btree.h b/fs/xfs/xfs_ialloc_btree.h index 37e5dd01a57..5580e255ff0 100644 --- a/fs/xfs/xfs_ialloc_btree.h +++ b/fs/xfs/xfs_ialloc_btree.h @@ -36,7 +36,6 @@ typedef __uint64_t xfs_inofree_t; #define XFS_INODES_PER_CHUNK_LOG (XFS_NBBYLOG + 3) #define XFS_INOBT_ALL_FREE ((xfs_inofree_t)-1) -#define XFS_INOBT_MASKN(i,n) xfs_inobt_maskn(i,n) static inline xfs_inofree_t xfs_inobt_maskn(int i, int n) { return (((n) >= XFS_INODES_PER_CHUNK ? \ diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 323ecd76a12..e7ae08d1df4 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1614,10 +1614,10 @@ xfs_itruncate_finish( * in this file with garbage in them once recovery * runs. */ - XFS_BMAP_INIT(&free_list, &first_block); + xfs_bmap_init(&free_list, &first_block); error = xfs_bunmapi(ntp, ip, first_unmap_block, unmap_len, - XFS_BMAPI_AFLAG(fork) | + xfs_bmapi_aflag(fork) | (sync ? 0 : XFS_BMAPI_ASYNC), XFS_ITRUNC_MAX_EXTENTS, &first_block, &free_list, @@ -2570,7 +2570,7 @@ xfs_iextents_copy( for (i = 0; i < nrecs; i++) { xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); start_block = xfs_bmbt_get_startblock(ep); - if (ISNULLSTARTBLOCK(start_block)) { + if (isnullstartblock(start_block)) { /* * It's a delayed allocation extent, so skip it. */ diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h index 1ff04cc323a..9957d0602d5 100644 --- a/fs/xfs/xfs_inode_item.h +++ b/fs/xfs/xfs_inode_item.h @@ -111,20 +111,16 @@ typedef struct xfs_inode_log_format_64 { #define XFS_ILI_IOLOCKED_ANY (XFS_ILI_IOLOCKED_EXCL | XFS_ILI_IOLOCKED_SHARED) - -#define XFS_ILOG_FBROOT(w) xfs_ilog_fbroot(w) static inline int xfs_ilog_fbroot(int w) { return (w == XFS_DATA_FORK ? XFS_ILOG_DBROOT : XFS_ILOG_ABROOT); } -#define XFS_ILOG_FEXT(w) xfs_ilog_fext(w) static inline int xfs_ilog_fext(int w) { return (w == XFS_DATA_FORK ? XFS_ILOG_DEXT : XFS_ILOG_AEXT); } -#define XFS_ILOG_FDATA(w) xfs_ilog_fdata(w) static inline int xfs_ilog_fdata(int w) { return (w == XFS_DATA_FORK ? XFS_ILOG_DDATA : XFS_ILOG_ADATA); diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 911062cf73a..08ce72316bf 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -155,7 +155,7 @@ xfs_imap_to_bmap( iomapp->iomap_bn = IOMAP_DADDR_NULL; iomapp->iomap_flags |= IOMAP_DELAY; } else { - iomapp->iomap_bn = XFS_FSB_TO_DB(ip, start_block); + iomapp->iomap_bn = xfs_fsb_to_db(ip, start_block); if (ISUNWRITTEN(imap)) iomapp->iomap_flags |= IOMAP_UNWRITTEN; } @@ -261,7 +261,7 @@ xfs_iomap( xfs_iunlock(ip, lockmode); lockmode = 0; - if (nimaps && !ISNULLSTARTBLOCK(imap.br_startblock)) { + if (nimaps && !isnullstartblock(imap.br_startblock)) { xfs_iomap_map_trace(XFS_IOMAP_WRITE_MAP, ip, offset, count, iomapp, &imap, flags); break; @@ -491,7 +491,7 @@ xfs_iomap_write_direct( /* * Issue the xfs_bmapi() call to allocate the blocks */ - XFS_BMAP_INIT(&free_list, &firstfsb); + xfs_bmap_init(&free_list, &firstfsb); nimaps = 1; error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, bmapi_flag, &firstfsb, 0, &imap, &nimaps, &free_list, NULL); @@ -751,7 +751,7 @@ xfs_iomap_write_allocate( xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); xfs_trans_ihold(tp, ip); - XFS_BMAP_INIT(&free_list, &first_block); + xfs_bmap_init(&free_list, &first_block); /* * it is possible that the extents have changed since @@ -911,7 +911,7 @@ xfs_iomap_write_unwritten( /* * Modify the unwritten extent state of the buffer. */ - XFS_BMAP_INIT(&free_list, &firstfsb); + xfs_bmap_init(&free_list, &firstfsb); nimaps = 1; error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb, diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index e19d0a8d561..cf98a805ec9 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -453,7 +453,7 @@ xfs_bulkstat( (chunkidx = agino - gino + 1) < XFS_INODES_PER_CHUNK && /* there are some left allocated */ - XFS_INOBT_MASKN(chunkidx, + xfs_inobt_maskn(chunkidx, XFS_INODES_PER_CHUNK - chunkidx) & ~gfree) { /* * Grab the chunk record. Mark all the @@ -464,7 +464,7 @@ xfs_bulkstat( if (XFS_INOBT_MASK(i) & ~gfree) gcnt++; } - gfree |= XFS_INOBT_MASKN(0, chunkidx); + gfree |= xfs_inobt_maskn(0, chunkidx); irbp->ir_startino = gino; irbp->ir_freecount = gcnt; irbp->ir_free = gfree; @@ -535,7 +535,7 @@ xfs_bulkstat( chunkidx < XFS_INODES_PER_CHUNK; chunkidx += nicluster, agbno += nbcluster) { - if (XFS_INOBT_MASKN(chunkidx, + if (xfs_inobt_maskn(chunkidx, nicluster) & ~gfree) xfs_btree_reada_bufs(mp, agno, agbno, nbcluster); diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index e37eff6761e..f5e9937f9bd 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -44,9 +44,9 @@ typedef struct xfs_trans_reservations { #ifndef __KERNEL__ -#define XFS_DADDR_TO_AGNO(mp,d) \ +#define xfs_daddr_to_agno(mp,d) \ ((xfs_agnumber_t)(XFS_BB_TO_FSBT(mp, d) / (mp)->m_sb.sb_agblocks)) -#define XFS_DADDR_TO_AGBNO(mp,d) \ +#define xfs_daddr_to_agbno(mp,d) \ ((xfs_agblock_t)(XFS_BB_TO_FSBT(mp, d) % (mp)->m_sb.sb_agblocks)) #else /* __KERNEL__ */ @@ -441,7 +441,6 @@ void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname, */ #define XFS_MFSI_QUIET 0x40 /* Be silent if mount errors found */ -#define XFS_DADDR_TO_AGNO(mp,d) xfs_daddr_to_agno(mp,d) static inline xfs_agnumber_t xfs_daddr_to_agno(struct xfs_mount *mp, xfs_daddr_t d) { @@ -450,7 +449,6 @@ xfs_daddr_to_agno(struct xfs_mount *mp, xfs_daddr_t d) return (xfs_agnumber_t) ld; } -#define XFS_DADDR_TO_AGBNO(mp,d) xfs_daddr_to_agbno(mp,d) static inline xfs_agblock_t xfs_daddr_to_agbno(struct xfs_mount *mp, xfs_daddr_t d) { diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c index 86471bb40fd..58f85e9cd11 100644 --- a/fs/xfs/xfs_rename.c +++ b/fs/xfs/xfs_rename.c @@ -147,7 +147,7 @@ xfs_rename( xfs_sort_for_rename(src_dp, target_dp, src_ip, target_ip, inodes, &num_inodes); - XFS_BMAP_INIT(&free_list, &first_block); + xfs_bmap_init(&free_list, &first_block); tp = xfs_trans_alloc(mp, XFS_TRANS_RENAME); cancel_flags = XFS_TRANS_RELEASE_LOG_RES; spaceres = XFS_RENAME_SPACE_RES(mp, target_name->len); diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index edf12c7b834..c5bb86f3ec0 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -120,7 +120,7 @@ xfs_growfs_rt_alloc( if ((error = xfs_trans_iget(mp, tp, ino, 0, XFS_ILOCK_EXCL, &ip))) goto error_cancel; - XFS_BMAP_INIT(&flist, &firstblock); + xfs_bmap_init(&flist, &firstblock); /* * Allocate blocks to the bitmap file. */ diff --git a/fs/xfs/xfs_rw.h b/fs/xfs/xfs_rw.h index f87db5344ce..f76c003ec55 100644 --- a/fs/xfs/xfs_rw.h +++ b/fs/xfs/xfs_rw.h @@ -28,7 +28,6 @@ struct xfs_mount; * file is a real time file or not, because the bmap code * does. */ -#define XFS_FSB_TO_DB(ip,fsb) xfs_fsb_to_db(ip,fsb) static inline xfs_daddr_t xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb) { diff --git a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h index 1ed71916e4c..1b017c65749 100644 --- a/fs/xfs/xfs_sb.h +++ b/fs/xfs/xfs_sb.h @@ -505,7 +505,7 @@ static inline void xfs_sb_version_removeattr2(xfs_sb_t *sbp) #define XFS_HDR_BLOCK(mp,d) ((xfs_agblock_t)XFS_BB_TO_FSBT(mp,d)) #define XFS_DADDR_TO_FSB(mp,d) XFS_AGB_TO_FSB(mp, \ - XFS_DADDR_TO_AGNO(mp,d), XFS_DADDR_TO_AGBNO(mp,d)) + xfs_daddr_to_agno(mp,d), xfs_daddr_to_agbno(mp,d)) #define XFS_FSB_TO_DADDR(mp,fsbno) XFS_AGB_TO_DADDR(mp, \ XFS_FSB_TO_AGNO(mp,fsbno), XFS_FSB_TO_AGBNO(mp,fsbno)) diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index f07bf8768c3..0e55c5d7db5 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -862,7 +862,7 @@ xfs_inactive_symlink_rmt( * Find the block(s) so we can inval and unmap them. */ done = 0; - XFS_BMAP_INIT(&free_list, &first_block); + xfs_bmap_init(&free_list, &first_block); nmaps = ARRAY_SIZE(mval); if ((error = xfs_bmapi(tp, ip, 0, XFS_B_TO_FSB(mp, size), XFS_BMAPI_METADATA, &first_block, 0, mval, &nmaps, @@ -1288,7 +1288,7 @@ xfs_inactive( /* * Free the inode. */ - XFS_BMAP_INIT(&free_list, &first_block); + xfs_bmap_init(&free_list, &first_block); error = xfs_ifree(tp, ip, &free_list); if (error) { /* @@ -1461,7 +1461,7 @@ xfs_create( xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); unlock_dp_on_error = B_TRUE; - XFS_BMAP_INIT(&free_list, &first_block); + xfs_bmap_init(&free_list, &first_block); ASSERT(ip == NULL); @@ -1879,7 +1879,7 @@ xfs_remove( } } - XFS_BMAP_INIT(&free_list, &first_block); + xfs_bmap_init(&free_list, &first_block); error = xfs_dir_removename(tp, dp, name, ip->i_ino, &first_block, &free_list, resblks); if (error) { @@ -2059,7 +2059,7 @@ xfs_link( if (error) goto error_return; - XFS_BMAP_INIT(&free_list, &first_block); + xfs_bmap_init(&free_list, &first_block); error = xfs_dir_createname(tp, tdp, target_name, sip->i_ino, &first_block, &free_list, resblks); @@ -2231,7 +2231,7 @@ xfs_mkdir( xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); unlock_dp_on_error = B_FALSE; - XFS_BMAP_INIT(&free_list, &first_block); + xfs_bmap_init(&free_list, &first_block); error = xfs_dir_createname(tp, dp, dir_name, cdp->i_ino, &first_block, &free_list, resblks ? @@ -2438,7 +2438,7 @@ xfs_symlink( * Initialize the bmap freelist prior to calling either * bmapi or the directory create code. */ - XFS_BMAP_INIT(&free_list, &first_block); + xfs_bmap_init(&free_list, &first_block); /* * Allocate an inode for the symlink. @@ -2860,7 +2860,7 @@ retry: /* * Issue the xfs_bmapi() call to allocate the blocks */ - XFS_BMAP_INIT(&free_list, &firstfsb); + xfs_bmap_init(&free_list, &firstfsb); error = xfs_bmapi(tp, ip, startoffset_fsb, allocatesize_fsb, bmapi_flag, &firstfsb, 0, imapp, &nimaps, @@ -2980,7 +2980,7 @@ xfs_zero_remaining_bytes( XFS_BUF_UNDONE(bp); XFS_BUF_UNWRITE(bp); XFS_BUF_READ(bp); - XFS_BUF_SET_ADDR(bp, XFS_FSB_TO_DB(ip, imap.br_startblock)); + XFS_BUF_SET_ADDR(bp, xfs_fsb_to_db(ip, imap.br_startblock)); xfsbdstrat(mp, bp); error = xfs_iowait(bp); if (error) { @@ -3186,7 +3186,7 @@ xfs_free_file_space( /* * issue the bunmapi() call to free the blocks */ - XFS_BMAP_INIT(&free_list, &firstfsb); + xfs_bmap_init(&free_list, &firstfsb); error = xfs_bunmapi(tp, ip, startoffset_fsb, endoffset_fsb - startoffset_fsb, 0, 2, &firstfsb, &free_list, NULL, &done); -- cgit From 422e79a8b39d9ac73e410dc3cd099aecea82afd2 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Mon, 19 Jan 2009 17:06:42 +1100 Subject: x86: Remove never-called arch_setup_msi_irq() Since commit 75c46fa, "x64, x2apic/intr-remap: MSI and MSI-X support for interrupt remapping infrastructure", x86 has had an implementation of arch_setup_msi_irqs(). That implementation does not call arch_setup_msi_irq(), instead it calls setup_irq(). No other x86 code calls arch_setup_msi_irq(). That leaves only arch_setup_msi_irqs() in drivers/pci/msi.c, but that routine is overridden by the x86 version of arch_setup_msi_irqs(). So arch_setup_msi_irq() is dead code, remove it. Signed-off-by: Michael Ellerman Signed-off-by: H. Peter Anvin --- arch/x86/kernel/io_apic.c | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c index 79b8c0c72d3..157aafa4558 100644 --- a/arch/x86/kernel/io_apic.c +++ b/arch/x86/kernel/io_apic.c @@ -3462,40 +3462,6 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq) return 0; } -int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc) -{ - unsigned int irq; - int ret; - unsigned int irq_want; - - irq_want = nr_irqs_gsi; - irq = create_irq_nr(irq_want); - if (irq == 0) - return -1; - -#ifdef CONFIG_INTR_REMAP - if (!intr_remapping_enabled) - goto no_ir; - - ret = msi_alloc_irte(dev, irq, 1); - if (ret < 0) - goto error; -no_ir: -#endif - ret = setup_msi_irq(dev, msidesc, irq); - if (ret < 0) { - destroy_irq(irq); - return ret; - } - return 0; - -#ifdef CONFIG_INTR_REMAP -error: - destroy_irq(irq); - return ret; -#endif -} - int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) { unsigned int irq; -- cgit From c1ff85d97708550e634fb6fa099c463db90fc40d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 19 Jan 2009 17:17:58 +1000 Subject: drm: fix leak of device mappings since multi-master changes. Device maps now contain a link to the master that created them, so when cleaning up the master, remove any maps that are connected to it. Also delete any remaining maps at driver unload time. Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_drv.c | 4 ++++ drivers/gpu/drm/drm_stub.c | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 5ff88d95222..14c7a23dc15 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -294,6 +294,7 @@ EXPORT_SYMBOL(drm_init); */ static void drm_cleanup(struct drm_device * dev) { + struct drm_map_list *r_list, *list_temp; DRM_DEBUG("\n"); if (!dev) { @@ -325,6 +326,9 @@ static void drm_cleanup(struct drm_device * dev) drm_ht_remove(&dev->map_hash); drm_ctxbitmap_cleanup(dev); + list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) + drm_rmmap(dev, r_list->map); + if (drm_core_check_feature(dev, DRIVER_MODESET)) drm_put_minor(&dev->control); diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 5ca132afa4f..46bb923b097 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -118,12 +118,20 @@ static void drm_master_destroy(struct kref *kref) struct drm_master *master = container_of(kref, struct drm_master, refcount); struct drm_magic_entry *pt, *next; struct drm_device *dev = master->minor->dev; + struct drm_map_list *r_list, *list_temp; list_del(&master->head); if (dev->driver->master_destroy) dev->driver->master_destroy(dev, master); + list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) { + if (r_list->master == master) { + drm_rmmap_locked(dev, r_list->map); + r_list = NULL; + } + } + if (master->unique) { drm_free(master->unique, master->unique_size, DRM_MEM_DRIVER); master->unique = NULL; -- cgit From bb54affa6fbdd6fe80f193ec1b6977a93078785d Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Mon, 19 Jan 2009 13:46:56 +0100 Subject: ide: fix IDE PMAC breakage Bartlomiej Zolnierkiewicz writes: > Signed-off-by: Bartlomiej Zolnierkiewicz > --- > drivers/ide/ide-probe.c | 9 ++------- > 1 file changed, 2 insertions(+), 7 deletions(-) > > Index: b/drivers/ide/ide-probe.c > =================================================================== > --- a/drivers/ide/ide-probe.c > +++ b/drivers/ide/ide-probe.c > @@ -640,14 +640,9 @@ static int ide_register_port(ide_hwif_t > /* register with global device tree */ > dev_set_name(&hwif->gendev, hwif->name); > hwif->gendev.driver_data = hwif; > - if (hwif->gendev.parent == NULL) { > - if (hwif->dev) > - hwif->gendev.parent = hwif->dev; > - else > - /* Would like to do = &device_legacy */ > - hwif->gendev.parent = NULL; > - } > + hwif->gendev.parent = hwif->dev; This [bart: commit 96d40941236722777c259775640b8880b7dc6f33 ("ide: small ide_register_port() cleanup")] breaks ide-pmac. It overwrites the parent that pmac_ide_macio_attach has set. Signed-off-by: Andreas Schwab Cc: Benjamin Herrenschmidt Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-probe.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 312127ea443..0db1ed9f5fc 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -649,7 +649,8 @@ static int ide_register_port(ide_hwif_t *hwif) /* register with global device tree */ dev_set_name(&hwif->gendev, hwif->name); hwif->gendev.driver_data = hwif; - hwif->gendev.parent = hwif->dev; + if (hwif->gendev.parent == NULL) + hwif->gendev.parent = hwif->dev; hwif->gendev.release = hwif_release_dev; ret = device_register(&hwif->gendev); -- cgit From abb8817967cc080ee024f7d1a3d5a9830074ca1c Mon Sep 17 00:00:00 2001 From: Michael Schmitz Date: Mon, 19 Jan 2009 13:46:56 +0100 Subject: ide: fix Falcon IDE breakage [m68k] Falcon IDE: always serialize, in order to force execution of ide_get_lock() and friends. Signed-off-By: Michael Schmitz Cc: Geert Uytterhoeven [bart: set flag in falconide_port_info instead of falconide_init()] Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/falconide.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/falconide.c b/drivers/ide/falconide.c index a5ba820d69b..a638e952d67 100644 --- a/drivers/ide/falconide.c +++ b/drivers/ide/falconide.c @@ -82,7 +82,7 @@ static const struct ide_tp_ops falconide_tp_ops = { static const struct ide_port_info falconide_port_info = { .tp_ops = &falconide_tp_ops, - .host_flags = IDE_HFLAG_NO_DMA, + .host_flags = IDE_HFLAG_NO_DMA | IDE_HFLAG_SERIALIZE, }; static void __init falconide_setup_ports(hw_regs_t *hw) -- cgit From ef183f6b5982aa10499432a0cb243c92ce623512 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 19 Jan 2009 13:46:57 +0100 Subject: drivers/ide/palm_bk3710.c buildfix CC drivers/ide/palm_bk3710.o drivers/ide/palm_bk3710.c: In function 'palm_bk3710_probe': drivers/ide/palm_bk3710.c:382: warning: assignment makes integer from pointer without a cast Someone should fix hw_regs_t to neither be a typedef, nor use "unsigned long" where it should use "void __iomem *". Signed-off-by: David Brownell Cc: Kevin Hilman Cc: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/palm_bk3710.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/ide/palm_bk3710.c b/drivers/ide/palm_bk3710.c index a7ac490c9ae..f38aac78044 100644 --- a/drivers/ide/palm_bk3710.c +++ b/drivers/ide/palm_bk3710.c @@ -346,7 +346,8 @@ static int __init palm_bk3710_probe(struct platform_device *pdev) { struct clk *clk; struct resource *mem, *irq; - unsigned long base, rate; + void __iomem *base; + unsigned long rate; int i, rc; hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; @@ -382,11 +383,13 @@ static int __init palm_bk3710_probe(struct platform_device *pdev) base = IO_ADDRESS(mem->start); /* Configure the Palm Chip controller */ - palm_bk3710_chipinit((void __iomem *)base); + palm_bk3710_chipinit(base); for (i = 0; i < IDE_NR_PORTS - 2; i++) - hw.io_ports_array[i] = base + IDE_PALM_ATA_PRI_REG_OFFSET + i; - hw.io_ports.ctl_addr = base + IDE_PALM_ATA_PRI_CTL_OFFSET; + hw.io_ports_array[i] = (unsigned long) + (base + IDE_PALM_ATA_PRI_REG_OFFSET + i); + hw.io_ports.ctl_addr = (unsigned long) + (base + IDE_PALM_ATA_PRI_CTL_OFFSET); hw.irq = irq->start; hw.dev = &pdev->dev; hw.chipset = ide_palm3710; -- cgit From 22c733788bbd4b75c00279119a83da5cd74b987a Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 19 Jan 2009 10:07:21 +0100 Subject: sound: virtuoso: enable UART on Xonar HDAV1.3 This hardware has a better chance of working correctly if we don't forget to enable it. Signed-off-by: Clemens Ladisch Cc: Signed-off-by: Takashi Iwai --- sound/pci/oxygen/virtuoso.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index e9e829e83d7..a9621664305 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -908,6 +908,7 @@ static const struct oxygen_model model_xonar_hdav = { .dac_channels = 8, .dac_volume_min = 0x0f, .dac_volume_max = 0xff, + .misc_flags = OXYGEN_MISC_MIDI, .function_flags = OXYGEN_FUNCTION_2WIRE, .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, -- cgit From 45bf81011312958777f33088ac0911f241ada297 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 19 Jan 2009 10:07:58 +0100 Subject: sound: virtuoso: add newline Add a missing newline. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/virtuoso.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index a9621664305..18c7c91786b 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -683,7 +683,7 @@ static void xonar_hdav_uart_input(struct oxygen *chip) if (chip->uart_input_count >= 2 && chip->uart_input[chip->uart_input_count - 2] == 'O' && chip->uart_input[chip->uart_input_count - 1] == 'K') { - printk(KERN_DEBUG "message from Xonar HDAV HDMI chip received:"); + printk(KERN_DEBUG "message from Xonar HDAV HDMI chip received:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, chip->uart_input, chip->uart_input_count); chip->uart_input_count = 0; -- cgit From 3288a66243c8d34c299dd6b8a336a34321ccff52 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 19 Jan 2009 10:08:38 +0100 Subject: sound: virtuoso: document HDAV1.3 driver status Mention in the Kconfig help text that the HDAV1.3 code is rather experimental. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 6e3a1848447..82b9bddcdcd 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -744,8 +744,8 @@ config SND_VIRTUOSO select SND_OXYGEN_LIB help Say Y here to include support for sound cards based on the - Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X and - HDAV1.3 (Deluxe). + Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2 and D2X. + Support for the HDAV1.3 (Deluxe) is very experimental. To compile this driver as a module, choose M here: the module will be called snd-virtuoso. -- cgit From c2fdd36b550659f5ac2240d1f5a83ffa1a092289 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Sat, 17 Jan 2009 16:23:55 +0100 Subject: PCI hotplug: fix lock imbalance in pciehp set_lock_status omits mutex_unlock in fail path. Add the omitted unlock. As a result a lockup caused by this can be triggered from userspace by writing 1 to /sys/bus/pci/slots/.../lock often enough. Signed-off-by: Jiri Slaby Reviewed-by: Kenji Kaneshige Signed-off-by: Jesse Barnes --- drivers/pci/hotplug/pciehp_core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 5482d4ed825..c2485542f54 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -126,8 +126,10 @@ static int set_lock_status(struct hotplug_slot *hotplug_slot, u8 status) mutex_lock(&slot->ctrl->crit_sect); /* has it been >1 sec since our last toggle? */ - if ((get_seconds() - slot->last_emi_toggle) < 1) + if ((get_seconds() - slot->last_emi_toggle) < 1) { + mutex_unlock(&slot->ctrl->crit_sect); return -EINVAL; + } /* see what our current state is */ retval = get_lock_status(hotplug_slot, &value); -- cgit From 5cdc5e9e69d4dc3a3630ae1fa666401b2a8dcde6 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 19 Jan 2009 20:49:37 +0100 Subject: x86: fully honor "nolapic", fix Impact: build fix Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c index 48578795583..9ca12af6c87 100644 --- a/arch/x86/kernel/apic.c +++ b/arch/x86/kernel/apic.c @@ -1131,7 +1131,9 @@ void __cpuinit setup_local_APIC(void) int i, j; if (disable_apic) { +#ifdef CONFIG_X86_IO_APIC disable_ioapic_setup(); +#endif return; } -- cgit From b7c18c1b2636ecb9ad76759f99dac6efd441fa92 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 18 Jan 2009 22:42:15 -0800 Subject: sparc64: Initialize FHC/CLOCK LED platform_device 'id' field correctly. There is only one clock board, so use -1 as the 'id' so we get just the base name as the LED device name string. There are multiple FHC boards potentially in a system so use the board number as the 'id' value for that case. Reported-by: Meelis Roos Tested-by: Meelis Roos Signed-off-by: David S. Miller --- arch/sparc/kernel/central.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c index 05f1c916db0..f3b5466c389 100644 --- a/arch/sparc/kernel/central.c +++ b/arch/sparc/kernel/central.c @@ -103,6 +103,7 @@ static int __devinit clock_board_probe(struct of_device *op, p->leds_resource.name = "leds"; p->leds_pdev.name = "sunfire-clockboard-leds"; + p->leds_pdev.id = -1; p->leds_pdev.resource = &p->leds_resource; p->leds_pdev.num_resources = 1; p->leds_pdev.dev.parent = &op->dev; @@ -197,6 +198,7 @@ static int __devinit fhc_probe(struct of_device *op, p->leds_resource.name = "leds"; p->leds_pdev.name = "sunfire-fhc-leds"; + p->leds_pdev.id = p->board_num; p->leds_pdev.resource = &p->leds_resource; p->leds_pdev.num_resources = 1; p->leds_pdev.dev.parent = &op->dev; -- cgit From 31ad9081200c06ccc350625d41d1f8b2d1cef29f Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 16 Jan 2009 15:31:15 -0800 Subject: work_on_cpu: don't try to get_online_cpus() in work_on_cpu. Impact: remove potential circular lock dependency with cpu hotplug lock This has caused more problems than it solved, with a pile of cpu hotplug locking issues. Followup patches will get_online_cpus() in callers that need it, but if they don't do it they're no worse than before when they were using set_cpus_allowed without locking. Signed-off-by: Rusty Russell Signed-off-by: Mike Travis Signed-off-by: Ingo Molnar --- kernel/workqueue.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 2f445833ae3..a35afdbc016 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -991,8 +991,8 @@ static void do_work_for_cpu(struct work_struct *w) * @fn: the function to run * @arg: the function arg * - * This will return -EINVAL in the cpu is not online, or the return value - * of @fn otherwise. + * This will return the value @fn returns. + * It is up to the caller to ensure that the cpu doesn't go offline. */ long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg) { @@ -1001,14 +1001,8 @@ long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg) INIT_WORK(&wfc.work, do_work_for_cpu); wfc.fn = fn; wfc.arg = arg; - get_online_cpus(); - if (unlikely(!cpu_online(cpu))) - wfc.ret = -EINVAL; - else { - schedule_work_on(cpu, &wfc.work); - flush_work(&wfc.work); - } - put_online_cpus(); + schedule_work_on(cpu, &wfc.work); + flush_work(&wfc.work); return wfc.ret; } -- cgit From 8ccad40df8d314f786fdb06bdbedd4f43f3257cd Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 16 Jan 2009 15:31:15 -0800 Subject: work_on_cpu: Use our own workqueue. Impact: remove potential clashes with generic kevent workqueue Annoyingly, some places we want to use work_on_cpu are already in workqueues. As per Ingo's suggestion, we create a different workqueue for work_on_cpu. Signed-off-by: Rusty Russell Signed-off-by: Mike Travis Signed-off-by: Ingo Molnar --- kernel/workqueue.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index a35afdbc016..1f0c509b40d 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -971,6 +971,8 @@ undo: } #ifdef CONFIG_SMP +static struct workqueue_struct *work_on_cpu_wq __read_mostly; + struct work_for_cpu { struct work_struct work; long (*fn)(void *); @@ -1001,7 +1003,7 @@ long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg) INIT_WORK(&wfc.work, do_work_for_cpu); wfc.fn = fn; wfc.arg = arg; - schedule_work_on(cpu, &wfc.work); + queue_work_on(cpu, work_on_cpu_wq, &wfc.work); flush_work(&wfc.work); return wfc.ret; @@ -1019,4 +1021,8 @@ void __init init_workqueues(void) hotcpu_notifier(workqueue_cpu_callback, 0); keventd_wq = create_workqueue("events"); BUG_ON(!keventd_wq); +#ifdef CONFIG_SMP + work_on_cpu_wq = create_workqueue("work_on_cpu"); + BUG_ON(!work_on_cpu_wq); +#endif } -- cgit From 72859081851af2bda04117ca3d64206ffa199e5e Mon Sep 17 00:00:00 2001 From: Mike Travis Date: Fri, 16 Jan 2009 15:31:15 -0800 Subject: cpufreq: use work_on_cpu in acpi-cpufreq.c for drv_read and drv_write Impact: use new work_on_cpu function to reduce stack usage Replace the saving of current->cpus_allowed and set_cpus_allowed_ptr() with a work_on_cpu function for drv_read() and drv_write(). Basically converts do_drv_{read,write} into "work_on_cpu" functions that are now called by drv_read and drv_write. Note: This patch basically reverts 50c668d6 which reverted 7503bfba, now that the work_on_cpu() function is more stable. Signed-off-by: Mike Travis Acked-by: Rusty Russell Tested-by: Dieter Ries Tested-by: Maciej Rutecki Cc: Dave Jones Cc: Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index 8f3c95c7e61..5bf2c834a23 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -150,8 +150,9 @@ struct drv_cmd { u32 val; }; -static void do_drv_read(struct drv_cmd *cmd) +static long do_drv_read(void *_cmd) { + struct drv_cmd *cmd = _cmd; u32 h; switch (cmd->type) { @@ -166,10 +167,12 @@ static void do_drv_read(struct drv_cmd *cmd) default: break; } + return 0; } -static void do_drv_write(struct drv_cmd *cmd) +static long do_drv_write(void *_cmd) { + struct drv_cmd *cmd = _cmd; u32 lo, hi; switch (cmd->type) { @@ -186,30 +189,23 @@ static void do_drv_write(struct drv_cmd *cmd) default: break; } + return 0; } static void drv_read(struct drv_cmd *cmd) { - cpumask_t saved_mask = current->cpus_allowed; cmd->val = 0; - set_cpus_allowed_ptr(current, cmd->mask); - do_drv_read(cmd); - set_cpus_allowed_ptr(current, &saved_mask); + work_on_cpu(cpumask_any(cmd->mask), do_drv_read, cmd); } static void drv_write(struct drv_cmd *cmd) { - cpumask_t saved_mask = current->cpus_allowed; unsigned int i; for_each_cpu(i, cmd->mask) { - set_cpus_allowed_ptr(current, cpumask_of(i)); - do_drv_write(cmd); + work_on_cpu(i, do_drv_write, cmd); } - - set_cpus_allowed_ptr(current, &saved_mask); - return; } static u32 get_cur_val(const struct cpumask *mask) @@ -366,7 +362,7 @@ static unsigned int get_cur_freq_on_cpu(unsigned int cpu) return freq; } -static unsigned int check_freqs(const cpumask_t *mask, unsigned int freq, +static unsigned int check_freqs(const struct cpumask *mask, unsigned int freq, struct acpi_cpufreq_data *data) { unsigned int cur_freq; -- cgit From 83436a0560e9ef8af2f0796264dde4bed1415359 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 19 Jan 2009 14:39:10 -0700 Subject: dmaengine: kill some dubious WARN_ONCEs dma_find_channel and dma_issue_pending_all are good places to warn about improper api usage. However, warning correctly means synchronizing with dma_list_mutex, i.e. too much overhead for these fast-path calls. Reported-by: Ingo Molnar Signed-off-by: Dan Williams --- drivers/dma/dmaengine.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 6df144a65fe..a58993011ed 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -329,9 +329,6 @@ struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type) struct dma_chan *chan; int cpu; - WARN_ONCE(dmaengine_ref_count == 0, - "client called %s without a reference", __func__); - cpu = get_cpu(); chan = per_cpu_ptr(channel_table[tx_type], cpu)->chan; put_cpu(); @@ -348,9 +345,6 @@ void dma_issue_pending_all(void) struct dma_device *device; struct dma_chan *chan; - WARN_ONCE(dmaengine_ref_count == 0, - "client called %s without a reference", __func__); - rcu_read_lock(); list_for_each_entry_rcu(device, &dma_device_list, global_node) { if (dma_has_cap(DMA_PRIVATE, device->cap_mask)) -- cgit From c50331e8be32eaba5e1949f98c70d50b891262db Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 19 Jan 2009 15:33:14 -0700 Subject: dmaengine: dma_issue_pending_all == nop when CONFIG_DMA_ENGINE=n The device list will always be empty in this configuration, so no need to walk the list. Reported-by: Ingo Molnar Signed-off-by: Dan Williams --- include/linux/dmaengine.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 64dea2ab326..c4a560e72ab 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -390,11 +390,16 @@ static inline enum dma_status dma_async_is_complete(dma_cookie_t cookie, enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie); #ifdef CONFIG_DMA_ENGINE enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx); +void dma_issue_pending_all(void); #else static inline enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx) { return DMA_SUCCESS; } +static inline void dma_issue_pending_all(void) +{ + do { } while (0); +} #endif /* --- DMA device --- */ @@ -403,7 +408,6 @@ int dma_async_device_register(struct dma_device *device); void dma_async_device_unregister(struct dma_device *device); void dma_run_dependencies(struct dma_async_tx_descriptor *tx); struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type); -void dma_issue_pending_all(void); #define dma_request_channel(mask, x, y) __dma_request_channel(&(mask), x, y) struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, void *fn_param); void dma_release_channel(struct dma_chan *chan); -- cgit From ef560682a97491f62ef538931a4861b57d66c52c Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 19 Jan 2009 15:36:21 -0700 Subject: dmaengine: add async_tx_clear_ack() macro To complete the DMA_CTRL_ACK handling API add a async_tx_clear_ack() macro. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Dan Williams --- include/linux/dmaengine.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index c4a560e72ab..34f124d7fb9 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -287,6 +287,11 @@ static inline void async_tx_ack(struct dma_async_tx_descriptor *tx) tx->flags |= DMA_CTRL_ACK; } +static inline void async_tx_clear_ack(struct dma_async_tx_descriptor *tx) +{ + tx->flags &= ~DMA_CTRL_ACK; +} + static inline bool async_tx_test_ack(struct dma_async_tx_descriptor *tx) { return (tx->flags & DMA_CTRL_ACK) == DMA_CTRL_ACK; -- cgit From 5296b56d1b2000b60fb966be161c1f8fb629786b Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 19 Jan 2009 15:36:21 -0700 Subject: i.MX31: Image Processing Unit DMA and IRQ drivers i.MX3x SoCs contain an Image Processing Unit, consisting of a Control Module (CM), Display Interface (DI), Synchronous Display Controller (SDC), Asynchronous Display Controller (ADC), Image Converter (IC), Post-Filter (PF), Camera Sensor Interface (CSI), and an Image DMA Controller (IDMAC). CM contains, among other blocks, an Interrupt Generator (IG) and a Clock and Reset Control Unit (CRCU). This driver serves IDMAC and IG. They are supported over dmaengine and irq-chip APIs respectively. IDMAC is a specialised DMA controller, its DMA channels cannot be used for general-purpose operations, even though it might be possible to configure a memory-to-memory channel for memcpy operation. This driver will not work with generic dmaengine clients, clients, wishing to use it must use respective wrapper structures, they also must specify which channels they require, as channels are hard-wired to specific IPU functions. Acked-by: Sascha Hauer Signed-off-by: Guennadi Liakhovetski Signed-off-by: Dan Williams --- arch/arm/plat-mxc/include/mach/ipu.h | 181 ++++ arch/arm/plat-mxc/include/mach/irqs.h | 10 +- drivers/dma/Kconfig | 19 + drivers/dma/Makefile | 1 + drivers/dma/ipu/Makefile | 1 + drivers/dma/ipu/ipu_idmac.c | 1740 +++++++++++++++++++++++++++++++++ drivers/dma/ipu/ipu_intern.h | 176 ++++ drivers/dma/ipu/ipu_irq.c | 413 ++++++++ 8 files changed, 2540 insertions(+), 1 deletion(-) create mode 100644 arch/arm/plat-mxc/include/mach/ipu.h create mode 100644 drivers/dma/ipu/Makefile create mode 100644 drivers/dma/ipu/ipu_idmac.c create mode 100644 drivers/dma/ipu/ipu_intern.h create mode 100644 drivers/dma/ipu/ipu_irq.c diff --git a/arch/arm/plat-mxc/include/mach/ipu.h b/arch/arm/plat-mxc/include/mach/ipu.h new file mode 100644 index 00000000000..a9221f1cc1a --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/ipu.h @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2008 + * Guennadi Liakhovetski, DENX Software Engineering, + * + * Copyright (C) 2005-2007 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _IPU_H_ +#define _IPU_H_ + +#include +#include + +/* IPU DMA Controller channel definitions. */ +enum ipu_channel { + IDMAC_IC_0 = 0, /* IC (encoding task) to memory */ + IDMAC_IC_1 = 1, /* IC (viewfinder task) to memory */ + IDMAC_ADC_0 = 1, + IDMAC_IC_2 = 2, + IDMAC_ADC_1 = 2, + IDMAC_IC_3 = 3, + IDMAC_IC_4 = 4, + IDMAC_IC_5 = 5, + IDMAC_IC_6 = 6, + IDMAC_IC_7 = 7, /* IC (sensor data) to memory */ + IDMAC_IC_8 = 8, + IDMAC_IC_9 = 9, + IDMAC_IC_10 = 10, + IDMAC_IC_11 = 11, + IDMAC_IC_12 = 12, + IDMAC_IC_13 = 13, + IDMAC_SDC_0 = 14, /* Background synchronous display data */ + IDMAC_SDC_1 = 15, /* Foreground data (overlay) */ + IDMAC_SDC_2 = 16, + IDMAC_SDC_3 = 17, + IDMAC_ADC_2 = 18, + IDMAC_ADC_3 = 19, + IDMAC_ADC_4 = 20, + IDMAC_ADC_5 = 21, + IDMAC_ADC_6 = 22, + IDMAC_ADC_7 = 23, + IDMAC_PF_0 = 24, + IDMAC_PF_1 = 25, + IDMAC_PF_2 = 26, + IDMAC_PF_3 = 27, + IDMAC_PF_4 = 28, + IDMAC_PF_5 = 29, + IDMAC_PF_6 = 30, + IDMAC_PF_7 = 31, +}; + +/* Order significant! */ +enum ipu_channel_status { + IPU_CHANNEL_FREE, + IPU_CHANNEL_INITIALIZED, + IPU_CHANNEL_READY, + IPU_CHANNEL_ENABLED, +}; + +#define IPU_CHANNELS_NUM 32 + +enum pixel_fmt { + /* 1 byte */ + IPU_PIX_FMT_GENERIC, + IPU_PIX_FMT_RGB332, + IPU_PIX_FMT_YUV420P, + IPU_PIX_FMT_YUV422P, + IPU_PIX_FMT_YUV420P2, + IPU_PIX_FMT_YVU422P, + /* 2 bytes */ + IPU_PIX_FMT_RGB565, + IPU_PIX_FMT_RGB666, + IPU_PIX_FMT_BGR666, + IPU_PIX_FMT_YUYV, + IPU_PIX_FMT_UYVY, + /* 3 bytes */ + IPU_PIX_FMT_RGB24, + IPU_PIX_FMT_BGR24, + /* 4 bytes */ + IPU_PIX_FMT_GENERIC_32, + IPU_PIX_FMT_RGB32, + IPU_PIX_FMT_BGR32, + IPU_PIX_FMT_ABGR32, + IPU_PIX_FMT_BGRA32, + IPU_PIX_FMT_RGBA32, +}; + +enum ipu_color_space { + IPU_COLORSPACE_RGB, + IPU_COLORSPACE_YCBCR, + IPU_COLORSPACE_YUV +}; + +/* + * Enumeration of IPU rotation modes + */ +enum ipu_rotate_mode { + /* Note the enum values correspond to BAM value */ + IPU_ROTATE_NONE = 0, + IPU_ROTATE_VERT_FLIP = 1, + IPU_ROTATE_HORIZ_FLIP = 2, + IPU_ROTATE_180 = 3, + IPU_ROTATE_90_RIGHT = 4, + IPU_ROTATE_90_RIGHT_VFLIP = 5, + IPU_ROTATE_90_RIGHT_HFLIP = 6, + IPU_ROTATE_90_LEFT = 7, +}; + +struct ipu_platform_data { + unsigned int irq_base; +}; + +/* + * Enumeration of DI ports for ADC. + */ +enum display_port { + DISP0, + DISP1, + DISP2, + DISP3 +}; + +struct idmac_video_param { + unsigned short in_width; + unsigned short in_height; + uint32_t in_pixel_fmt; + unsigned short out_width; + unsigned short out_height; + uint32_t out_pixel_fmt; + unsigned short out_stride; + bool graphics_combine_en; + bool global_alpha_en; + bool key_color_en; + enum display_port disp; + unsigned short out_left; + unsigned short out_top; +}; + +/* + * Union of initialization parameters for a logical channel. So far only video + * parameters are used. + */ +union ipu_channel_param { + struct idmac_video_param video; +}; + +struct idmac_tx_desc { + struct dma_async_tx_descriptor txd; + struct scatterlist *sg; /* scatterlist for this */ + unsigned int sg_len; /* tx-descriptor. */ + struct list_head list; +}; + +struct idmac_channel { + struct dma_chan dma_chan; + dma_cookie_t completed; /* last completed cookie */ + union ipu_channel_param params; + enum ipu_channel link; /* input channel, linked to the output */ + enum ipu_channel_status status; + void *client; /* Only one client per channel */ + unsigned int n_tx_desc; + struct idmac_tx_desc *desc; /* allocated tx-descriptors */ + struct scatterlist *sg[2]; /* scatterlist elements in buffer-0 and -1 */ + struct list_head free_list; /* free tx-descriptors */ + struct list_head queue; /* queued tx-descriptors */ + spinlock_t lock; /* protects sg[0,1], queue */ + struct mutex chan_mutex; /* protects status, cookie, free_list */ + bool sec_chan_en; + int active_buffer; + unsigned int eof_irq; + char eof_name[16]; /* EOF IRQ name for request_irq() */ +}; + +#define to_tx_desc(tx) container_of(tx, struct idmac_tx_desc, txd) +#define to_idmac_chan(c) container_of(c, struct idmac_channel, dma_chan) + +#endif diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h index e06d3cb0ee1..c02b8fc2d82 100644 --- a/arch/arm/plat-mxc/include/mach/irqs.h +++ b/arch/arm/plat-mxc/include/mach/irqs.h @@ -35,7 +35,15 @@ #define MXC_BOARD_IRQ_START (MXC_INTERNAL_IRQS + MXC_GPIO_IRQS) #define MXC_BOARD_IRQS 16 -#define NR_IRQS (MXC_BOARD_IRQ_START + MXC_BOARD_IRQS) +#define MXC_IPU_IRQ_START (MXC_BOARD_IRQ_START + MXC_BOARD_IRQS) + +#ifdef CONFIG_MX3_IPU_IRQS +#define MX3_IPU_IRQS CONFIG_MX3_IPU_IRQS +#else +#define MX3_IPU_IRQS 0 +#endif + +#define NR_IRQS (MXC_IPU_IRQ_START + MX3_IPU_IRQS) extern void imx_irq_set_priority(unsigned char irq, unsigned char prio); diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index e34b0642081..48ea59e7967 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -62,6 +62,25 @@ config MV_XOR ---help--- Enable support for the Marvell XOR engine. +config MX3_IPU + bool "MX3x Image Processing Unit support" + depends on ARCH_MX3 + select DMA_ENGINE + default y + help + If you plan to use the Image Processing unit in the i.MX3x, say + Y here. If unsure, select Y. + +config MX3_IPU_IRQS + int "Number of dynamically mapped interrupts for IPU" + depends on MX3_IPU + range 2 137 + default 4 + help + Out of 137 interrupt sources on i.MX31 IPU only very few are used. + To avoid bloating the irq_desc[] array we allocate a sufficient + number of IRQ slots and map them dynamically to specific sources. + config DMA_ENGINE bool diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index 14f59527d4f..2e5dc96700d 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o obj-$(CONFIG_FSL_DMA) += fsldma.o obj-$(CONFIG_MV_XOR) += mv_xor.o obj-$(CONFIG_DW_DMAC) += dw_dmac.o +obj-$(CONFIG_MX3_IPU) += ipu/ diff --git a/drivers/dma/ipu/Makefile b/drivers/dma/ipu/Makefile new file mode 100644 index 00000000000..6704cf48326 --- /dev/null +++ b/drivers/dma/ipu/Makefile @@ -0,0 +1 @@ +obj-y += ipu_irq.o ipu_idmac.o diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c new file mode 100644 index 00000000000..1f154d08e98 --- /dev/null +++ b/drivers/dma/ipu/ipu_idmac.c @@ -0,0 +1,1740 @@ +/* + * Copyright (C) 2008 + * Guennadi Liakhovetski, DENX Software Engineering, + * + * Copyright (C) 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "ipu_intern.h" + +#define FS_VF_IN_VALID 0x00000002 +#define FS_ENC_IN_VALID 0x00000001 + +/* + * There can be only one, we could allocate it dynamically, but then we'd have + * to add an extra parameter to some functions, and use something as ugly as + * struct ipu *ipu = to_ipu(to_idmac(ichan->dma_chan.device)); + * in the ISR + */ +static struct ipu ipu_data; + +#define to_ipu(id) container_of(id, struct ipu, idmac) + +static u32 __idmac_read_icreg(struct ipu *ipu, unsigned long reg) +{ + return __raw_readl(ipu->reg_ic + reg); +} + +#define idmac_read_icreg(ipu, reg) __idmac_read_icreg(ipu, reg - IC_CONF) + +static void __idmac_write_icreg(struct ipu *ipu, u32 value, unsigned long reg) +{ + __raw_writel(value, ipu->reg_ic + reg); +} + +#define idmac_write_icreg(ipu, v, reg) __idmac_write_icreg(ipu, v, reg - IC_CONF) + +static u32 idmac_read_ipureg(struct ipu *ipu, unsigned long reg) +{ + return __raw_readl(ipu->reg_ipu + reg); +} + +static void idmac_write_ipureg(struct ipu *ipu, u32 value, unsigned long reg) +{ + __raw_writel(value, ipu->reg_ipu + reg); +} + +/***************************************************************************** + * IPU / IC common functions + */ +static void dump_idmac_reg(struct ipu *ipu) +{ + dev_dbg(ipu->dev, "IDMAC_CONF 0x%x, IC_CONF 0x%x, IDMAC_CHA_EN 0x%x, " + "IDMAC_CHA_PRI 0x%x, IDMAC_CHA_BUSY 0x%x\n", + idmac_read_icreg(ipu, IDMAC_CONF), + idmac_read_icreg(ipu, IC_CONF), + idmac_read_icreg(ipu, IDMAC_CHA_EN), + idmac_read_icreg(ipu, IDMAC_CHA_PRI), + idmac_read_icreg(ipu, IDMAC_CHA_BUSY)); + dev_dbg(ipu->dev, "BUF0_RDY 0x%x, BUF1_RDY 0x%x, CUR_BUF 0x%x, " + "DB_MODE 0x%x, TASKS_STAT 0x%x\n", + idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY), + idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY), + idmac_read_ipureg(ipu, IPU_CHA_CUR_BUF), + idmac_read_ipureg(ipu, IPU_CHA_DB_MODE_SEL), + idmac_read_ipureg(ipu, IPU_TASKS_STAT)); +} + +static uint32_t bytes_per_pixel(enum pixel_fmt fmt) +{ + switch (fmt) { + case IPU_PIX_FMT_GENERIC: /* generic data */ + case IPU_PIX_FMT_RGB332: + case IPU_PIX_FMT_YUV420P: + case IPU_PIX_FMT_YUV422P: + default: + return 1; + case IPU_PIX_FMT_RGB565: + case IPU_PIX_FMT_YUYV: + case IPU_PIX_FMT_UYVY: + return 2; + case IPU_PIX_FMT_BGR24: + case IPU_PIX_FMT_RGB24: + return 3; + case IPU_PIX_FMT_GENERIC_32: /* generic data */ + case IPU_PIX_FMT_BGR32: + case IPU_PIX_FMT_RGB32: + case IPU_PIX_FMT_ABGR32: + return 4; + } +} + +/* Enable / disable direct write to memory by the Camera Sensor Interface */ +static void ipu_ic_enable_task(struct ipu *ipu, enum ipu_channel channel) +{ + uint32_t ic_conf, mask; + + switch (channel) { + case IDMAC_IC_0: + mask = IC_CONF_PRPENC_EN; + break; + case IDMAC_IC_7: + mask = IC_CONF_RWS_EN | IC_CONF_PRPENC_EN; + break; + default: + return; + } + ic_conf = idmac_read_icreg(ipu, IC_CONF) | mask; + idmac_write_icreg(ipu, ic_conf, IC_CONF); +} + +static void ipu_ic_disable_task(struct ipu *ipu, enum ipu_channel channel) +{ + uint32_t ic_conf, mask; + + switch (channel) { + case IDMAC_IC_0: + mask = IC_CONF_PRPENC_EN; + break; + case IDMAC_IC_7: + mask = IC_CONF_RWS_EN | IC_CONF_PRPENC_EN; + break; + default: + return; + } + ic_conf = idmac_read_icreg(ipu, IC_CONF) & ~mask; + idmac_write_icreg(ipu, ic_conf, IC_CONF); +} + +static uint32_t ipu_channel_status(struct ipu *ipu, enum ipu_channel channel) +{ + uint32_t stat = TASK_STAT_IDLE; + uint32_t task_stat_reg = idmac_read_ipureg(ipu, IPU_TASKS_STAT); + + switch (channel) { + case IDMAC_IC_7: + stat = (task_stat_reg & TSTAT_CSI2MEM_MASK) >> + TSTAT_CSI2MEM_OFFSET; + break; + case IDMAC_IC_0: + case IDMAC_SDC_0: + case IDMAC_SDC_1: + default: + break; + } + return stat; +} + +struct chan_param_mem_planar { + /* Word 0 */ + u32 xv:10; + u32 yv:10; + u32 xb:12; + + u32 yb:12; + u32 res1:2; + u32 nsb:1; + u32 lnpb:6; + u32 ubo_l:11; + + u32 ubo_h:15; + u32 vbo_l:17; + + u32 vbo_h:9; + u32 res2:3; + u32 fw:12; + u32 fh_l:8; + + u32 fh_h:4; + u32 res3:28; + + /* Word 1 */ + u32 eba0; + + u32 eba1; + + u32 bpp:3; + u32 sl:14; + u32 pfs:3; + u32 bam:3; + u32 res4:2; + u32 npb:6; + u32 res5:1; + + u32 sat:2; + u32 res6:30; +} __attribute__ ((packed)); + +struct chan_param_mem_interleaved { + /* Word 0 */ + u32 xv:10; + u32 yv:10; + u32 xb:12; + + u32 yb:12; + u32 sce:1; + u32 res1:1; + u32 nsb:1; + u32 lnpb:6; + u32 sx:10; + u32 sy_l:1; + + u32 sy_h:9; + u32 ns:10; + u32 sm:10; + u32 sdx_l:3; + + u32 sdx_h:2; + u32 sdy:5; + u32 sdrx:1; + u32 sdry:1; + u32 sdr1:1; + u32 res2:2; + u32 fw:12; + u32 fh_l:8; + + u32 fh_h:4; + u32 res3:28; + + /* Word 1 */ + u32 eba0; + + u32 eba1; + + u32 bpp:3; + u32 sl:14; + u32 pfs:3; + u32 bam:3; + u32 res4:2; + u32 npb:6; + u32 res5:1; + + u32 sat:2; + u32 scc:1; + u32 ofs0:5; + u32 ofs1:5; + u32 ofs2:5; + u32 ofs3:5; + u32 wid0:3; + u32 wid1:3; + u32 wid2:3; + + u32 wid3:3; + u32 dec_sel:1; + u32 res6:28; +} __attribute__ ((packed)); + +union chan_param_mem { + struct chan_param_mem_planar pp; + struct chan_param_mem_interleaved ip; +}; + +static void ipu_ch_param_set_plane_offset(union chan_param_mem *params, + u32 u_offset, u32 v_offset) +{ + params->pp.ubo_l = u_offset & 0x7ff; + params->pp.ubo_h = u_offset >> 11; + params->pp.vbo_l = v_offset & 0x1ffff; + params->pp.vbo_h = v_offset >> 17; +} + +static void ipu_ch_param_set_size(union chan_param_mem *params, + uint32_t pixel_fmt, uint16_t width, + uint16_t height, uint16_t stride) +{ + u32 u_offset; + u32 v_offset; + + params->pp.fw = width - 1; + params->pp.fh_l = height - 1; + params->pp.fh_h = (height - 1) >> 8; + params->pp.sl = stride - 1; + + switch (pixel_fmt) { + case IPU_PIX_FMT_GENERIC: + /*Represents 8-bit Generic data */ + params->pp.bpp = 3; + params->pp.pfs = 7; + params->pp.npb = 31; + params->pp.sat = 2; /* SAT = use 32-bit access */ + break; + case IPU_PIX_FMT_GENERIC_32: + /*Represents 32-bit Generic data */ + params->pp.bpp = 0; + params->pp.pfs = 7; + params->pp.npb = 7; + params->pp.sat = 2; /* SAT = use 32-bit access */ + break; + case IPU_PIX_FMT_RGB565: + params->ip.bpp = 2; + params->ip.pfs = 4; + params->ip.npb = 7; + params->ip.sat = 2; /* SAT = 32-bit access */ + params->ip.ofs0 = 0; /* Red bit offset */ + params->ip.ofs1 = 5; /* Green bit offset */ + params->ip.ofs2 = 11; /* Blue bit offset */ + params->ip.ofs3 = 16; /* Alpha bit offset */ + params->ip.wid0 = 4; /* Red bit width - 1 */ + params->ip.wid1 = 5; /* Green bit width - 1 */ + params->ip.wid2 = 4; /* Blue bit width - 1 */ + break; + case IPU_PIX_FMT_BGR24: + params->ip.bpp = 1; /* 24 BPP & RGB PFS */ + params->ip.pfs = 4; + params->ip.npb = 7; + params->ip.sat = 2; /* SAT = 32-bit access */ + params->ip.ofs0 = 0; /* Red bit offset */ + params->ip.ofs1 = 8; /* Green bit offset */ + params->ip.ofs2 = 16; /* Blue bit offset */ + params->ip.ofs3 = 24; /* Alpha bit offset */ + params->ip.wid0 = 7; /* Red bit width - 1 */ + params->ip.wid1 = 7; /* Green bit width - 1 */ + params->ip.wid2 = 7; /* Blue bit width - 1 */ + break; + case IPU_PIX_FMT_RGB24: + params->ip.bpp = 1; /* 24 BPP & RGB PFS */ + params->ip.pfs = 4; + params->ip.npb = 7; + params->ip.sat = 2; /* SAT = 32-bit access */ + params->ip.ofs0 = 16; /* Red bit offset */ + params->ip.ofs1 = 8; /* Green bit offset */ + params->ip.ofs2 = 0; /* Blue bit offset */ + params->ip.ofs3 = 24; /* Alpha bit offset */ + params->ip.wid0 = 7; /* Red bit width - 1 */ + params->ip.wid1 = 7; /* Green bit width - 1 */ + params->ip.wid2 = 7; /* Blue bit width - 1 */ + break; + case IPU_PIX_FMT_BGRA32: + case IPU_PIX_FMT_BGR32: + params->ip.bpp = 0; + params->ip.pfs = 4; + params->ip.npb = 7; + params->ip.sat = 2; /* SAT = 32-bit access */ + params->ip.ofs0 = 8; /* Red bit offset */ + params->ip.ofs1 = 16; /* Green bit offset */ + params->ip.ofs2 = 24; /* Blue bit offset */ + params->ip.ofs3 = 0; /* Alpha bit offset */ + params->ip.wid0 = 7; /* Red bit width - 1 */ + params->ip.wid1 = 7; /* Green bit width - 1 */ + params->ip.wid2 = 7; /* Blue bit width - 1 */ + params->ip.wid3 = 7; /* Alpha bit width - 1 */ + break; + case IPU_PIX_FMT_RGBA32: + case IPU_PIX_FMT_RGB32: + params->ip.bpp = 0; + params->ip.pfs = 4; + params->ip.npb = 7; + params->ip.sat = 2; /* SAT = 32-bit access */ + params->ip.ofs0 = 24; /* Red bit offset */ + params->ip.ofs1 = 16; /* Green bit offset */ + params->ip.ofs2 = 8; /* Blue bit offset */ + params->ip.ofs3 = 0; /* Alpha bit offset */ + params->ip.wid0 = 7; /* Red bit width - 1 */ + params->ip.wid1 = 7; /* Green bit width - 1 */ + params->ip.wid2 = 7; /* Blue bit width - 1 */ + params->ip.wid3 = 7; /* Alpha bit width - 1 */ + break; + case IPU_PIX_FMT_ABGR32: + params->ip.bpp = 0; + params->ip.pfs = 4; + params->ip.npb = 7; + params->ip.sat = 2; /* SAT = 32-bit access */ + params->ip.ofs0 = 8; /* Red bit offset */ + params->ip.ofs1 = 16; /* Green bit offset */ + params->ip.ofs2 = 24; /* Blue bit offset */ + params->ip.ofs3 = 0; /* Alpha bit offset */ + params->ip.wid0 = 7; /* Red bit width - 1 */ + params->ip.wid1 = 7; /* Green bit width - 1 */ + params->ip.wid2 = 7; /* Blue bit width - 1 */ + params->ip.wid3 = 7; /* Alpha bit width - 1 */ + break; + case IPU_PIX_FMT_UYVY: + params->ip.bpp = 2; + params->ip.pfs = 6; + params->ip.npb = 7; + params->ip.sat = 2; /* SAT = 32-bit access */ + break; + case IPU_PIX_FMT_YUV420P2: + case IPU_PIX_FMT_YUV420P: + params->ip.bpp = 3; + params->ip.pfs = 3; + params->ip.npb = 7; + params->ip.sat = 2; /* SAT = 32-bit access */ + u_offset = stride * height; + v_offset = u_offset + u_offset / 4; + ipu_ch_param_set_plane_offset(params, u_offset, v_offset); + break; + case IPU_PIX_FMT_YVU422P: + params->ip.bpp = 3; + params->ip.pfs = 2; + params->ip.npb = 7; + params->ip.sat = 2; /* SAT = 32-bit access */ + v_offset = stride * height; + u_offset = v_offset + v_offset / 2; + ipu_ch_param_set_plane_offset(params, u_offset, v_offset); + break; + case IPU_PIX_FMT_YUV422P: + params->ip.bpp = 3; + params->ip.pfs = 2; + params->ip.npb = 7; + params->ip.sat = 2; /* SAT = 32-bit access */ + u_offset = stride * height; + v_offset = u_offset + u_offset / 2; + ipu_ch_param_set_plane_offset(params, u_offset, v_offset); + break; + default: + dev_err(ipu_data.dev, + "mxc ipu: unimplemented pixel format %d\n", pixel_fmt); + break; + } + + params->pp.nsb = 1; +} + +static void ipu_ch_param_set_burst_size(union chan_param_mem *params, + uint16_t burst_pixels) +{ + params->pp.npb = burst_pixels - 1; +}; + +static void ipu_ch_param_set_buffer(union chan_param_mem *params, + dma_addr_t buf0, dma_addr_t buf1) +{ + params->pp.eba0 = buf0; + params->pp.eba1 = buf1; +}; + +static void ipu_ch_param_set_rotation(union chan_param_mem *params, + enum ipu_rotate_mode rotate) +{ + params->pp.bam = rotate; +}; + +static void ipu_write_param_mem(uint32_t addr, uint32_t *data, + uint32_t num_words) +{ + for (; num_words > 0; num_words--) { + dev_dbg(ipu_data.dev, + "write param mem - addr = 0x%08X, data = 0x%08X\n", + addr, *data); + idmac_write_ipureg(&ipu_data, addr, IPU_IMA_ADDR); + idmac_write_ipureg(&ipu_data, *data++, IPU_IMA_DATA); + addr++; + if ((addr & 0x7) == 5) { + addr &= ~0x7; /* set to word 0 */ + addr += 8; /* increment to next row */ + } + } +} + +static int calc_resize_coeffs(uint32_t in_size, uint32_t out_size, + uint32_t *resize_coeff, + uint32_t *downsize_coeff) +{ + uint32_t temp_size; + uint32_t temp_downsize; + + *resize_coeff = 1 << 13; + *downsize_coeff = 1 << 13; + + /* Cannot downsize more than 8:1 */ + if (out_size << 3 < in_size) + return -EINVAL; + + /* compute downsizing coefficient */ + temp_downsize = 0; + temp_size = in_size; + while (temp_size >= out_size * 2 && temp_downsize < 2) { + temp_size >>= 1; + temp_downsize++; + } + *downsize_coeff = temp_downsize; + + /* + * compute resizing coefficient using the following formula: + * resize_coeff = M*(SI -1)/(SO - 1) + * where M = 2^13, SI - input size, SO - output size + */ + *resize_coeff = (8192L * (temp_size - 1)) / (out_size - 1); + if (*resize_coeff >= 16384L) { + dev_err(ipu_data.dev, "Warning! Overflow on resize coeff.\n"); + *resize_coeff = 0x3FFF; + } + + dev_dbg(ipu_data.dev, "resizing from %u -> %u pixels, " + "downsize=%u, resize=%u.%lu (reg=%u)\n", in_size, out_size, + *downsize_coeff, *resize_coeff >= 8192L ? 1 : 0, + ((*resize_coeff & 0x1FFF) * 10000L) / 8192L, *resize_coeff); + + return 0; +} + +static enum ipu_color_space format_to_colorspace(enum pixel_fmt fmt) +{ + switch (fmt) { + case IPU_PIX_FMT_RGB565: + case IPU_PIX_FMT_BGR24: + case IPU_PIX_FMT_RGB24: + case IPU_PIX_FMT_BGR32: + case IPU_PIX_FMT_RGB32: + return IPU_COLORSPACE_RGB; + default: + return IPU_COLORSPACE_YCBCR; + } +} + +static int ipu_ic_init_prpenc(struct ipu *ipu, + union ipu_channel_param *params, bool src_is_csi) +{ + uint32_t reg, ic_conf; + uint32_t downsize_coeff, resize_coeff; + enum ipu_color_space in_fmt, out_fmt; + + /* Setup vertical resizing */ + calc_resize_coeffs(params->video.in_height, + params->video.out_height, + &resize_coeff, &downsize_coeff); + reg = (downsize_coeff << 30) | (resize_coeff << 16); + + /* Setup horizontal resizing */ + calc_resize_coeffs(params->video.in_width, + params->video.out_width, + &resize_coeff, &downsize_coeff); + reg |= (downsize_coeff << 14) | resize_coeff; + + /* Setup color space conversion */ + in_fmt = format_to_colorspace(params->video.in_pixel_fmt); + out_fmt = format_to_colorspace(params->video.out_pixel_fmt); + + /* + * Colourspace conversion unsupported yet - see _init_csc() in + * Freescale sources + */ + if (in_fmt != out_fmt) { + dev_err(ipu->dev, "Colourspace conversion unsupported!\n"); + return -EOPNOTSUPP; + } + + idmac_write_icreg(ipu, reg, IC_PRP_ENC_RSC); + + ic_conf = idmac_read_icreg(ipu, IC_CONF); + + if (src_is_csi) + ic_conf &= ~IC_CONF_RWS_EN; + else + ic_conf |= IC_CONF_RWS_EN; + + idmac_write_icreg(ipu, ic_conf, IC_CONF); + + return 0; +} + +static uint32_t dma_param_addr(uint32_t dma_ch) +{ + /* Channel Parameter Memory */ + return 0x10000 | (dma_ch << 4); +}; + +static void ipu_channel_set_priority(struct ipu *ipu, enum ipu_channel channel, + bool prio) +{ + u32 reg = idmac_read_icreg(ipu, IDMAC_CHA_PRI); + + if (prio) + reg |= 1UL << channel; + else + reg &= ~(1UL << channel); + + idmac_write_icreg(ipu, reg, IDMAC_CHA_PRI); + + dump_idmac_reg(ipu); +} + +static uint32_t ipu_channel_conf_mask(enum ipu_channel channel) +{ + uint32_t mask; + + switch (channel) { + case IDMAC_IC_0: + case IDMAC_IC_7: + mask = IPU_CONF_CSI_EN | IPU_CONF_IC_EN; + break; + case IDMAC_SDC_0: + case IDMAC_SDC_1: + mask = IPU_CONF_SDC_EN | IPU_CONF_DI_EN; + break; + default: + mask = 0; + break; + } + + return mask; +} + +/** + * ipu_enable_channel() - enable an IPU channel. + * @channel: channel ID. + * @return: 0 on success or negative error code on failure. + */ +static int ipu_enable_channel(struct idmac *idmac, struct idmac_channel *ichan) +{ + struct ipu *ipu = to_ipu(idmac); + enum ipu_channel channel = ichan->dma_chan.chan_id; + uint32_t reg; + unsigned long flags; + + spin_lock_irqsave(&ipu->lock, flags); + + /* Reset to buffer 0 */ + idmac_write_ipureg(ipu, 1UL << channel, IPU_CHA_CUR_BUF); + ichan->active_buffer = 0; + ichan->status = IPU_CHANNEL_ENABLED; + + switch (channel) { + case IDMAC_SDC_0: + case IDMAC_SDC_1: + case IDMAC_IC_7: + ipu_channel_set_priority(ipu, channel, true); + default: + break; + } + + reg = idmac_read_icreg(ipu, IDMAC_CHA_EN); + + idmac_write_icreg(ipu, reg | (1UL << channel), IDMAC_CHA_EN); + + ipu_ic_enable_task(ipu, channel); + + spin_unlock_irqrestore(&ipu->lock, flags); + return 0; +} + +/** + * ipu_init_channel_buffer() - initialize a buffer for logical IPU channel. + * @channel: channel ID. + * @pixel_fmt: pixel format of buffer. Pixel format is a FOURCC ASCII code. + * @width: width of buffer in pixels. + * @height: height of buffer in pixels. + * @stride: stride length of buffer in pixels. + * @rot_mode: rotation mode of buffer. A rotation setting other than + * IPU_ROTATE_VERT_FLIP should only be used for input buffers of + * rotation channels. + * @phyaddr_0: buffer 0 physical address. + * @phyaddr_1: buffer 1 physical address. Setting this to a value other than + * NULL enables double buffering mode. + * @return: 0 on success or negative error code on failure. + */ +static int ipu_init_channel_buffer(struct idmac_channel *ichan, + enum pixel_fmt pixel_fmt, + uint16_t width, uint16_t height, + uint32_t stride, + enum ipu_rotate_mode rot_mode, + dma_addr_t phyaddr_0, dma_addr_t phyaddr_1) +{ + enum ipu_channel channel = ichan->dma_chan.chan_id; + struct idmac *idmac = to_idmac(ichan->dma_chan.device); + struct ipu *ipu = to_ipu(idmac); + union chan_param_mem params = {}; + unsigned long flags; + uint32_t reg; + uint32_t stride_bytes; + + stride_bytes = stride * bytes_per_pixel(pixel_fmt); + + if (stride_bytes % 4) { + dev_err(ipu->dev, + "Stride length must be 32-bit aligned, stride = %d, bytes = %d\n", + stride, stride_bytes); + return -EINVAL; + } + + /* IC channel's stride must be a multiple of 8 pixels */ + if ((channel <= 13) && (stride % 8)) { + dev_err(ipu->dev, "Stride must be 8 pixel multiple\n"); + return -EINVAL; + } + + /* Build parameter memory data for DMA channel */ + ipu_ch_param_set_size(¶ms, pixel_fmt, width, height, stride_bytes); + ipu_ch_param_set_buffer(¶ms, phyaddr_0, phyaddr_1); + ipu_ch_param_set_rotation(¶ms, rot_mode); + /* Some channels (rotation) have restriction on burst length */ + switch (channel) { + case IDMAC_IC_7: /* Hangs with burst 8, 16, other values + invalid - Table 44-30 */ +/* + ipu_ch_param_set_burst_size(¶ms, 8); + */ + break; + case IDMAC_SDC_0: + case IDMAC_SDC_1: + /* In original code only IPU_PIX_FMT_RGB565 was setting burst */ + ipu_ch_param_set_burst_size(¶ms, 16); + break; + case IDMAC_IC_0: + default: + break; + } + + spin_lock_irqsave(&ipu->lock, flags); + + ipu_write_param_mem(dma_param_addr(channel), (uint32_t *)¶ms, 10); + + reg = idmac_read_ipureg(ipu, IPU_CHA_DB_MODE_SEL); + + if (phyaddr_1) + reg |= 1UL << channel; + else + reg &= ~(1UL << channel); + + idmac_write_ipureg(ipu, reg, IPU_CHA_DB_MODE_SEL); + + ichan->status = IPU_CHANNEL_READY; + + spin_unlock_irqrestore(ipu->lock, flags); + + return 0; +} + +/** + * ipu_select_buffer() - mark a channel's buffer as ready. + * @channel: channel ID. + * @buffer_n: buffer number to mark ready. + */ +static void ipu_select_buffer(enum ipu_channel channel, int buffer_n) +{ + /* No locking - this is a write-one-to-set register, cleared by IPU */ + if (buffer_n == 0) + /* Mark buffer 0 as ready. */ + idmac_write_ipureg(&ipu_data, 1UL << channel, IPU_CHA_BUF0_RDY); + else + /* Mark buffer 1 as ready. */ + idmac_write_ipureg(&ipu_data, 1UL << channel, IPU_CHA_BUF1_RDY); +} + +/** + * ipu_update_channel_buffer() - update physical address of a channel buffer. + * @channel: channel ID. + * @buffer_n: buffer number to update. + * 0 or 1 are the only valid values. + * @phyaddr: buffer physical address. + * @return: Returns 0 on success or negative error code on failure. This + * function will fail if the buffer is set to ready. + */ +/* Called under spin_lock(_irqsave)(&ichan->lock) */ +static int ipu_update_channel_buffer(enum ipu_channel channel, + int buffer_n, dma_addr_t phyaddr) +{ + uint32_t reg; + unsigned long flags; + + spin_lock_irqsave(&ipu_data.lock, flags); + + if (buffer_n == 0) { + reg = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY); + if (reg & (1UL << channel)) { + spin_unlock_irqrestore(&ipu_data.lock, flags); + return -EACCES; + } + + /* 44.3.3.1.9 - Row Number 1 (WORD1, offset 0) */ + idmac_write_ipureg(&ipu_data, dma_param_addr(channel) + + 0x0008UL, IPU_IMA_ADDR); + idmac_write_ipureg(&ipu_data, phyaddr, IPU_IMA_DATA); + } else { + reg = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY); + if (reg & (1UL << channel)) { + spin_unlock_irqrestore(&ipu_data.lock, flags); + return -EACCES; + } + + /* Check if double-buffering is already enabled */ + reg = idmac_read_ipureg(&ipu_data, IPU_CHA_DB_MODE_SEL); + + if (!(reg & (1UL << channel))) + idmac_write_ipureg(&ipu_data, reg | (1UL << channel), + IPU_CHA_DB_MODE_SEL); + + /* 44.3.3.1.9 - Row Number 1 (WORD1, offset 1) */ + idmac_write_ipureg(&ipu_data, dma_param_addr(channel) + + 0x0009UL, IPU_IMA_ADDR); + idmac_write_ipureg(&ipu_data, phyaddr, IPU_IMA_DATA); + } + + spin_unlock_irqrestore(&ipu_data.lock, flags); + + return 0; +} + +/* Called under spin_lock_irqsave(&ichan->lock) */ +static int ipu_submit_channel_buffers(struct idmac_channel *ichan, + struct idmac_tx_desc *desc) +{ + struct scatterlist *sg; + int i, ret = 0; + + for (i = 0, sg = desc->sg; i < 2 && sg; i++) { + if (!ichan->sg[i]) { + ichan->sg[i] = sg; + + /* + * On first invocation this shouldn't be necessary, the + * call to ipu_init_channel_buffer() above will set + * addresses for us, so we could make it conditional + * on status >= IPU_CHANNEL_ENABLED, but doing it again + * shouldn't hurt either. + */ + ret = ipu_update_channel_buffer(ichan->dma_chan.chan_id, i, + sg_dma_address(sg)); + if (ret < 0) + return ret; + + ipu_select_buffer(ichan->dma_chan.chan_id, i); + + sg = sg_next(sg); + } + } + + return ret; +} + +static dma_cookie_t idmac_tx_submit(struct dma_async_tx_descriptor *tx) +{ + struct idmac_tx_desc *desc = to_tx_desc(tx); + struct idmac_channel *ichan = to_idmac_chan(tx->chan); + struct idmac *idmac = to_idmac(tx->chan->device); + struct ipu *ipu = to_ipu(idmac); + dma_cookie_t cookie; + unsigned long flags; + + /* Sanity check */ + if (!list_empty(&desc->list)) { + /* The descriptor doesn't belong to client */ + dev_err(&ichan->dma_chan.dev->device, + "Descriptor %p not prepared!\n", tx); + return -EBUSY; + } + + mutex_lock(&ichan->chan_mutex); + + if (ichan->status < IPU_CHANNEL_READY) { + struct idmac_video_param *video = &ichan->params.video; + /* + * Initial buffer assignment - the first two sg-entries from + * the descriptor will end up in the IDMAC buffers + */ + dma_addr_t dma_1 = sg_is_last(desc->sg) ? 0 : + sg_dma_address(&desc->sg[1]); + + WARN_ON(ichan->sg[0] || ichan->sg[1]); + + cookie = ipu_init_channel_buffer(ichan, + video->out_pixel_fmt, + video->out_width, + video->out_height, + video->out_stride, + IPU_ROTATE_NONE, + sg_dma_address(&desc->sg[0]), + dma_1); + if (cookie < 0) + goto out; + } + + /* ipu->lock can be taken under ichan->lock, but not v.v. */ + spin_lock_irqsave(&ichan->lock, flags); + + /* submit_buffers() atomically verifies and fills empty sg slots */ + cookie = ipu_submit_channel_buffers(ichan, desc); + + spin_unlock_irqrestore(&ichan->lock, flags); + + if (cookie < 0) + goto out; + + cookie = ichan->dma_chan.cookie; + + if (++cookie < 0) + cookie = 1; + + /* from dmaengine.h: "last cookie value returned to client" */ + ichan->dma_chan.cookie = cookie; + tx->cookie = cookie; + spin_lock_irqsave(&ichan->lock, flags); + list_add_tail(&desc->list, &ichan->queue); + spin_unlock_irqrestore(&ichan->lock, flags); + + if (ichan->status < IPU_CHANNEL_ENABLED) { + int ret = ipu_enable_channel(idmac, ichan); + if (ret < 0) { + cookie = ret; + spin_lock_irqsave(&ichan->lock, flags); + list_del_init(&desc->list); + spin_unlock_irqrestore(&ichan->lock, flags); + tx->cookie = cookie; + ichan->dma_chan.cookie = cookie; + } + } + + dump_idmac_reg(ipu); + +out: + mutex_unlock(&ichan->chan_mutex); + + return cookie; +} + +/* Called with ichan->chan_mutex held */ +static int idmac_desc_alloc(struct idmac_channel *ichan, int n) +{ + struct idmac_tx_desc *desc = vmalloc(n * sizeof(struct idmac_tx_desc)); + struct idmac *idmac = to_idmac(ichan->dma_chan.device); + + if (!desc) + return -ENOMEM; + + /* No interrupts, just disable the tasklet for a moment */ + tasklet_disable(&to_ipu(idmac)->tasklet); + + ichan->n_tx_desc = n; + ichan->desc = desc; + INIT_LIST_HEAD(&ichan->queue); + INIT_LIST_HEAD(&ichan->free_list); + + while (n--) { + struct dma_async_tx_descriptor *txd = &desc->txd; + + memset(txd, 0, sizeof(*txd)); + dma_async_tx_descriptor_init(txd, &ichan->dma_chan); + txd->tx_submit = idmac_tx_submit; + txd->chan = &ichan->dma_chan; + INIT_LIST_HEAD(&txd->tx_list); + + list_add(&desc->list, &ichan->free_list); + + desc++; + } + + tasklet_enable(&to_ipu(idmac)->tasklet); + + return 0; +} + +/** + * ipu_init_channel() - initialize an IPU channel. + * @idmac: IPU DMAC context. + * @ichan: pointer to the channel object. + * @return 0 on success or negative error code on failure. + */ +static int ipu_init_channel(struct idmac *idmac, struct idmac_channel *ichan) +{ + union ipu_channel_param *params = &ichan->params; + uint32_t ipu_conf; + enum ipu_channel channel = ichan->dma_chan.chan_id; + unsigned long flags; + uint32_t reg; + struct ipu *ipu = to_ipu(idmac); + int ret = 0, n_desc = 0; + + dev_dbg(ipu->dev, "init channel = %d\n", channel); + + if (channel != IDMAC_SDC_0 && channel != IDMAC_SDC_1 && + channel != IDMAC_IC_7) + return -EINVAL; + + spin_lock_irqsave(&ipu->lock, flags); + + switch (channel) { + case IDMAC_IC_7: + n_desc = 16; + reg = idmac_read_icreg(ipu, IC_CONF); + idmac_write_icreg(ipu, reg & ~IC_CONF_CSI_MEM_WR_EN, IC_CONF); + break; + case IDMAC_IC_0: + n_desc = 16; + reg = idmac_read_ipureg(ipu, IPU_FS_PROC_FLOW); + idmac_write_ipureg(ipu, reg & ~FS_ENC_IN_VALID, IPU_FS_PROC_FLOW); + ret = ipu_ic_init_prpenc(ipu, params, true); + break; + case IDMAC_SDC_0: + case IDMAC_SDC_1: + n_desc = 4; + default: + break; + } + + ipu->channel_init_mask |= 1L << channel; + + /* Enable IPU sub module */ + ipu_conf = idmac_read_ipureg(ipu, IPU_CONF) | + ipu_channel_conf_mask(channel); + idmac_write_ipureg(ipu, ipu_conf, IPU_CONF); + + spin_unlock_irqrestore(&ipu->lock, flags); + + if (n_desc && !ichan->desc) + ret = idmac_desc_alloc(ichan, n_desc); + + dump_idmac_reg(ipu); + + return ret; +} + +/** + * ipu_uninit_channel() - uninitialize an IPU channel. + * @idmac: IPU DMAC context. + * @ichan: pointer to the channel object. + */ +static void ipu_uninit_channel(struct idmac *idmac, struct idmac_channel *ichan) +{ + enum ipu_channel channel = ichan->dma_chan.chan_id; + unsigned long flags; + uint32_t reg; + unsigned long chan_mask = 1UL << channel; + uint32_t ipu_conf; + struct ipu *ipu = to_ipu(idmac); + + spin_lock_irqsave(&ipu->lock, flags); + + if (!(ipu->channel_init_mask & chan_mask)) { + dev_err(ipu->dev, "Channel already uninitialized %d\n", + channel); + spin_unlock_irqrestore(&ipu->lock, flags); + return; + } + + /* Reset the double buffer */ + reg = idmac_read_ipureg(ipu, IPU_CHA_DB_MODE_SEL); + idmac_write_ipureg(ipu, reg & ~chan_mask, IPU_CHA_DB_MODE_SEL); + + ichan->sec_chan_en = false; + + switch (channel) { + case IDMAC_IC_7: + reg = idmac_read_icreg(ipu, IC_CONF); + idmac_write_icreg(ipu, reg & ~(IC_CONF_RWS_EN | IC_CONF_PRPENC_EN), + IC_CONF); + break; + case IDMAC_IC_0: + reg = idmac_read_icreg(ipu, IC_CONF); + idmac_write_icreg(ipu, reg & ~(IC_CONF_PRPENC_EN | IC_CONF_PRPENC_CSC1), + IC_CONF); + break; + case IDMAC_SDC_0: + case IDMAC_SDC_1: + default: + break; + } + + ipu->channel_init_mask &= ~(1L << channel); + + ipu_conf = idmac_read_ipureg(ipu, IPU_CONF) & + ~ipu_channel_conf_mask(channel); + idmac_write_ipureg(ipu, ipu_conf, IPU_CONF); + + spin_unlock_irqrestore(&ipu->lock, flags); + + ichan->n_tx_desc = 0; + vfree(ichan->desc); + ichan->desc = NULL; +} + +/** + * ipu_disable_channel() - disable an IPU channel. + * @idmac: IPU DMAC context. + * @ichan: channel object pointer. + * @wait_for_stop: flag to set whether to wait for channel end of frame or + * return immediately. + * @return: 0 on success or negative error code on failure. + */ +static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan, + bool wait_for_stop) +{ + enum ipu_channel channel = ichan->dma_chan.chan_id; + struct ipu *ipu = to_ipu(idmac); + uint32_t reg; + unsigned long flags; + unsigned long chan_mask = 1UL << channel; + unsigned int timeout; + + if (wait_for_stop && channel != IDMAC_SDC_1 && channel != IDMAC_SDC_0) { + timeout = 40; + /* This waiting always fails. Related to spurious irq problem */ + while ((idmac_read_icreg(ipu, IDMAC_CHA_BUSY) & chan_mask) || + (ipu_channel_status(ipu, channel) == TASK_STAT_ACTIVE)) { + timeout--; + msleep(10); + + if (!timeout) { + dev_dbg(ipu->dev, + "Warning: timeout waiting for channel %u to " + "stop: buf0_rdy = 0x%08X, buf1_rdy = 0x%08X, " + "busy = 0x%08X, tstat = 0x%08X\n", channel, + idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY), + idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY), + idmac_read_icreg(ipu, IDMAC_CHA_BUSY), + idmac_read_ipureg(ipu, IPU_TASKS_STAT)); + break; + } + } + dev_dbg(ipu->dev, "timeout = %d * 10ms\n", 40 - timeout); + } + /* SDC BG and FG must be disabled before DMA is disabled */ + if (wait_for_stop && (channel == IDMAC_SDC_0 || + channel == IDMAC_SDC_1)) { + for (timeout = 5; + timeout && !ipu_irq_status(ichan->eof_irq); timeout--) + msleep(5); + } + + spin_lock_irqsave(&ipu->lock, flags); + + /* Disable IC task */ + ipu_ic_disable_task(ipu, channel); + + /* Disable DMA channel(s) */ + reg = idmac_read_icreg(ipu, IDMAC_CHA_EN); + idmac_write_icreg(ipu, reg & ~chan_mask, IDMAC_CHA_EN); + + /* + * Problem (observed with channel DMAIC_7): after enabling the channel + * and initialising buffers, there comes an interrupt with current still + * pointing at buffer 0, whereas it should use buffer 0 first and only + * generate an interrupt when it is done, then current should already + * point to buffer 1. This spurious interrupt also comes on channel + * DMASDC_0. With DMAIC_7 normally, is we just leave the ISR after the + * first interrupt, there comes the second with current correctly + * pointing to buffer 1 this time. But sometimes this second interrupt + * doesn't come and the channel hangs. Clearing BUFx_RDY when disabling + * the channel seems to prevent the channel from hanging, but it doesn't + * prevent the spurious interrupt. This might also be unsafe. Think + * about the IDMAC controller trying to switch to a buffer, when we + * clear the ready bit, and re-enable it a moment later. + */ + reg = idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY); + idmac_write_ipureg(ipu, 0, IPU_CHA_BUF0_RDY); + idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF0_RDY); + + reg = idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY); + idmac_write_ipureg(ipu, 0, IPU_CHA_BUF1_RDY); + idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF1_RDY); + + spin_unlock_irqrestore(&ipu->lock, flags); + + return 0; +} + +/* + * We have several possibilities here: + * current BUF next BUF + * + * not last sg next not last sg + * not last sg next last sg + * last sg first sg from next descriptor + * last sg NULL + * + * Besides, the descriptor queue might be empty or not. We process all these + * cases carefully. + */ +static irqreturn_t idmac_interrupt(int irq, void *dev_id) +{ + struct idmac_channel *ichan = dev_id; + unsigned int chan_id = ichan->dma_chan.chan_id; + struct scatterlist **sg, *sgnext, *sgnew = NULL; + /* Next transfer descriptor */ + struct idmac_tx_desc *desc = NULL, *descnew; + dma_async_tx_callback callback; + void *callback_param; + bool done = false; + u32 ready0 = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY), + ready1 = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY), + curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); + + /* IDMAC has cleared the respective BUFx_RDY bit, we manage the buffer */ + + pr_debug("IDMAC irq %d\n", irq); + /* 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)) { + int i = 100; + + /* This doesn't help. See comment in ipu_disable_channel() */ + while (--i) { + curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); + if (((curbuf >> chan_id) & 1) != ichan->active_buffer) + break; + cpu_relax(); + } + + if (!i) { + spin_unlock(&ichan->lock); + dev_dbg(ichan->dma_chan.device->dev, + "IRQ on active buffer on channel %x, active " + "%d, ready %x, %x, current %x!\n", chan_id, + ichan->active_buffer, ready0, ready1, curbuf); + return IRQ_NONE; + } + } + + if (unlikely((ichan->active_buffer && (ready1 >> chan_id) & 1) || + (!ichan->active_buffer && (ready0 >> chan_id) & 1) + )) { + spin_unlock(&ichan->lock); + dev_dbg(ichan->dma_chan.device->dev, + "IRQ with active buffer still ready on channel %x, " + "active %d, ready %x, %x!\n", chan_id, + ichan->active_buffer, ready0, ready1); + return IRQ_NONE; + } + + if (unlikely(list_empty(&ichan->queue))) { + spin_unlock(&ichan->lock); + dev_err(ichan->dma_chan.device->dev, + "IRQ without queued buffers on channel %x, active %d, " + "ready %x, %x!\n", chan_id, + ichan->active_buffer, ready0, ready1); + return IRQ_NONE; + } + + /* + * active_buffer is a software flag, it shows which buffer we are + * currently expecting back from the hardware, IDMAC should be + * processing the other buffer already + */ + sg = &ichan->sg[ichan->active_buffer]; + sgnext = ichan->sg[!ichan->active_buffer]; + + /* + * if sgnext == NULL sg must be the last element in a scatterlist and + * queue must be empty + */ + if (unlikely(!sgnext)) { + if (unlikely(sg_next(*sg))) { + dev_err(ichan->dma_chan.device->dev, + "Broken buffer-update locking on channel %x!\n", + chan_id); + /* We'll let the user catch up */ + } else { + /* Underrun */ + ipu_ic_disable_task(&ipu_data, chan_id); + dev_dbg(ichan->dma_chan.device->dev, + "Underrun on channel %x\n", chan_id); + ichan->status = IPU_CHANNEL_READY; + /* Continue to check for complete descriptor */ + } + } + + desc = list_entry(ichan->queue.next, struct idmac_tx_desc, list); + + /* First calculate and submit the next sg element */ + if (likely(sgnext)) + sgnew = sg_next(sgnext); + + if (unlikely(!sgnew)) { + /* Start a new scatterlist, if any queued */ + if (likely(desc->list.next != &ichan->queue)) { + descnew = list_entry(desc->list.next, + struct idmac_tx_desc, list); + sgnew = &descnew->sg[0]; + } + } + + if (unlikely(!sg_next(*sg)) || !sgnext) { + /* + * Last element in scatterlist done, remove from the queue, + * _init for debugging + */ + list_del_init(&desc->list); + done = true; + } + + *sg = sgnew; + + if (likely(sgnew)) { + int ret; + + ret = ipu_update_channel_buffer(chan_id, ichan->active_buffer, + sg_dma_address(*sg)); + if (ret < 0) + dev_err(ichan->dma_chan.device->dev, + "Failed to update buffer on channel %x buffer %d!\n", + chan_id, ichan->active_buffer); + else + ipu_select_buffer(chan_id, ichan->active_buffer); + } + + /* Flip the active buffer - even if update above failed */ + ichan->active_buffer = !ichan->active_buffer; + if (done) + ichan->completed = desc->txd.cookie; + + callback = desc->txd.callback; + callback_param = desc->txd.callback_param; + + spin_unlock(&ichan->lock); + + if (done && (desc->txd.flags & DMA_PREP_INTERRUPT) && callback) + callback(callback_param); + + return IRQ_HANDLED; +} + +static void ipu_gc_tasklet(unsigned long arg) +{ + struct ipu *ipu = (struct ipu *)arg; + int i; + + for (i = 0; i < IPU_CHANNELS_NUM; i++) { + struct idmac_channel *ichan = ipu->channel + i; + struct idmac_tx_desc *desc; + unsigned long flags; + int j; + + for (j = 0; j < ichan->n_tx_desc; j++) { + desc = ichan->desc + j; + spin_lock_irqsave(&ichan->lock, flags); + if (async_tx_test_ack(&desc->txd)) { + list_move(&desc->list, &ichan->free_list); + async_tx_clear_ack(&desc->txd); + } + spin_unlock_irqrestore(&ichan->lock, flags); + } + } +} + +/* + * At the time .device_alloc_chan_resources() method is called, we cannot know, + * whether the client will accept the channel. Thus we must only check, if we + * can satisfy client's request but the only real criterion to verify, whether + * the client has accepted our offer is the client_count. That's why we have to + * perform the rest of our allocation tasks on the first call to this function. + */ +static struct dma_async_tx_descriptor *idmac_prep_slave_sg(struct dma_chan *chan, + struct scatterlist *sgl, unsigned int sg_len, + enum dma_data_direction direction, unsigned long tx_flags) +{ + struct idmac_channel *ichan = to_idmac_chan(chan); + struct idmac_tx_desc *desc = NULL; + struct dma_async_tx_descriptor *txd = NULL; + unsigned long flags; + + /* We only can handle these three channels so far */ + if (ichan->dma_chan.chan_id != IDMAC_SDC_0 && ichan->dma_chan.chan_id != IDMAC_SDC_1 && + ichan->dma_chan.chan_id != IDMAC_IC_7) + return NULL; + + if (direction != DMA_FROM_DEVICE && direction != DMA_TO_DEVICE) { + dev_err(chan->device->dev, "Invalid DMA direction %d!\n", direction); + return NULL; + } + + mutex_lock(&ichan->chan_mutex); + + spin_lock_irqsave(&ichan->lock, flags); + if (!list_empty(&ichan->free_list)) { + desc = list_entry(ichan->free_list.next, + struct idmac_tx_desc, list); + + list_del_init(&desc->list); + + desc->sg_len = sg_len; + desc->sg = sgl; + txd = &desc->txd; + txd->flags = tx_flags; + } + spin_unlock_irqrestore(&ichan->lock, flags); + + mutex_unlock(&ichan->chan_mutex); + + tasklet_schedule(&to_ipu(to_idmac(chan->device))->tasklet); + + return txd; +} + +/* Re-select the current buffer and re-activate the channel */ +static void idmac_issue_pending(struct dma_chan *chan) +{ + struct idmac_channel *ichan = to_idmac_chan(chan); + struct idmac *idmac = to_idmac(chan->device); + struct ipu *ipu = to_ipu(idmac); + unsigned long flags; + + /* This is not always needed, but doesn't hurt either */ + spin_lock_irqsave(&ipu->lock, flags); + ipu_select_buffer(ichan->dma_chan.chan_id, ichan->active_buffer); + spin_unlock_irqrestore(&ipu->lock, flags); + + /* + * Might need to perform some parts of initialisation from + * ipu_enable_channel(), but not all, we do not want to reset to buffer + * 0, don't need to set priority again either, but re-enabling the task + * and the channel might be a good idea. + */ +} + +static void __idmac_terminate_all(struct dma_chan *chan) +{ + struct idmac_channel *ichan = to_idmac_chan(chan); + struct idmac *idmac = to_idmac(chan->device); + unsigned long flags; + int i; + + ipu_disable_channel(idmac, ichan, + ichan->status >= IPU_CHANNEL_ENABLED); + + tasklet_disable(&to_ipu(idmac)->tasklet); + + /* ichan->queue is modified in ISR, have to spinlock */ + spin_lock_irqsave(&ichan->lock, flags); + list_splice_init(&ichan->queue, &ichan->free_list); + + if (ichan->desc) + for (i = 0; i < ichan->n_tx_desc; i++) { + struct idmac_tx_desc *desc = ichan->desc + i; + if (list_empty(&desc->list)) + /* Descriptor was prepared, but not submitted */ + list_add(&desc->list, + &ichan->free_list); + + async_tx_clear_ack(&desc->txd); + } + + ichan->sg[0] = NULL; + ichan->sg[1] = NULL; + spin_unlock_irqrestore(&ichan->lock, flags); + + tasklet_enable(&to_ipu(idmac)->tasklet); + + ichan->status = IPU_CHANNEL_INITIALIZED; +} + +static void idmac_terminate_all(struct dma_chan *chan) +{ + struct idmac_channel *ichan = to_idmac_chan(chan); + + mutex_lock(&ichan->chan_mutex); + + __idmac_terminate_all(chan); + + mutex_unlock(&ichan->chan_mutex); +} + +static int idmac_alloc_chan_resources(struct dma_chan *chan) +{ + struct idmac_channel *ichan = to_idmac_chan(chan); + struct idmac *idmac = to_idmac(chan->device); + int ret; + + /* dmaengine.c now guarantees to only offer free channels */ + BUG_ON(chan->client_count > 1); + WARN_ON(ichan->status != IPU_CHANNEL_FREE); + + chan->cookie = 1; + ichan->completed = -ENXIO; + + ret = ipu_irq_map(ichan->dma_chan.chan_id); + if (ret < 0) + goto eimap; + + ichan->eof_irq = ret; + ret = request_irq(ichan->eof_irq, idmac_interrupt, 0, + ichan->eof_name, ichan); + if (ret < 0) + goto erirq; + + ret = ipu_init_channel(idmac, ichan); + if (ret < 0) + goto eichan; + + ichan->status = IPU_CHANNEL_INITIALIZED; + + dev_dbg(&ichan->dma_chan.dev->device, "Found channel 0x%x, irq %d\n", + ichan->dma_chan.chan_id, ichan->eof_irq); + + return ret; + +eichan: + free_irq(ichan->eof_irq, ichan); +erirq: + ipu_irq_unmap(ichan->dma_chan.chan_id); +eimap: + return ret; +} + +static void idmac_free_chan_resources(struct dma_chan *chan) +{ + struct idmac_channel *ichan = to_idmac_chan(chan); + struct idmac *idmac = to_idmac(chan->device); + + mutex_lock(&ichan->chan_mutex); + + __idmac_terminate_all(chan); + + if (ichan->status > IPU_CHANNEL_FREE) { + free_irq(ichan->eof_irq, ichan); + ipu_irq_unmap(ichan->dma_chan.chan_id); + } + + ichan->status = IPU_CHANNEL_FREE; + + ipu_uninit_channel(idmac, ichan); + + mutex_unlock(&ichan->chan_mutex); + + tasklet_schedule(&to_ipu(idmac)->tasklet); +} + +static enum dma_status idmac_is_tx_complete(struct dma_chan *chan, + dma_cookie_t cookie, dma_cookie_t *done, dma_cookie_t *used) +{ + struct idmac_channel *ichan = to_idmac_chan(chan); + + if (done) + *done = ichan->completed; + if (used) + *used = chan->cookie; + if (cookie != chan->cookie) + return DMA_ERROR; + return DMA_SUCCESS; +} + +static int __init ipu_idmac_init(struct ipu *ipu) +{ + struct idmac *idmac = &ipu->idmac; + struct dma_device *dma = &idmac->dma; + int i; + + dma_cap_set(DMA_SLAVE, dma->cap_mask); + dma_cap_set(DMA_PRIVATE, dma->cap_mask); + + /* Compulsory common fields */ + dma->dev = ipu->dev; + dma->device_alloc_chan_resources = idmac_alloc_chan_resources; + dma->device_free_chan_resources = idmac_free_chan_resources; + dma->device_is_tx_complete = idmac_is_tx_complete; + dma->device_issue_pending = idmac_issue_pending; + + /* Compulsory for DMA_SLAVE fields */ + dma->device_prep_slave_sg = idmac_prep_slave_sg; + dma->device_terminate_all = idmac_terminate_all; + + INIT_LIST_HEAD(&dma->channels); + for (i = 0; i < IPU_CHANNELS_NUM; i++) { + struct idmac_channel *ichan = ipu->channel + i; + struct dma_chan *dma_chan = &ichan->dma_chan; + + spin_lock_init(&ichan->lock); + mutex_init(&ichan->chan_mutex); + + ichan->status = IPU_CHANNEL_FREE; + ichan->sec_chan_en = false; + ichan->completed = -ENXIO; + snprintf(ichan->eof_name, sizeof(ichan->eof_name), "IDMAC EOF %d", i); + + dma_chan->device = &idmac->dma; + dma_chan->cookie = 1; + dma_chan->chan_id = i; + list_add_tail(&ichan->dma_chan.device_node, &dma->channels); + } + + idmac_write_icreg(ipu, 0x00000070, IDMAC_CONF); + + return dma_async_device_register(&idmac->dma); +} + +static void ipu_idmac_exit(struct ipu *ipu) +{ + int i; + struct idmac *idmac = &ipu->idmac; + + for (i = 0; i < IPU_CHANNELS_NUM; i++) { + struct idmac_channel *ichan = ipu->channel + i; + + idmac_terminate_all(&ichan->dma_chan); + idmac_prep_slave_sg(&ichan->dma_chan, NULL, 0, DMA_NONE, 0); + } + + dma_async_device_unregister(&idmac->dma); +} + +/***************************************************************************** + * IPU common probe / remove + */ + +static int ipu_probe(struct platform_device *pdev) +{ + struct ipu_platform_data *pdata = pdev->dev.platform_data; + struct resource *mem_ipu, *mem_ic; + int ret; + + spin_lock_init(&ipu_data.lock); + + mem_ipu = platform_get_resource(pdev, IORESOURCE_MEM, 0); + mem_ic = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!pdata || !mem_ipu || !mem_ic) + return -EINVAL; + + ipu_data.dev = &pdev->dev; + + platform_set_drvdata(pdev, &ipu_data); + + ret = platform_get_irq(pdev, 0); + if (ret < 0) + goto err_noirq; + + ipu_data.irq_fn = ret; + ret = platform_get_irq(pdev, 1); + if (ret < 0) + goto err_noirq; + + ipu_data.irq_err = ret; + ipu_data.irq_base = pdata->irq_base; + + dev_dbg(&pdev->dev, "fn irq %u, err irq %u, irq-base %u\n", + ipu_data.irq_fn, ipu_data.irq_err, ipu_data.irq_base); + + /* Remap IPU common registers */ + ipu_data.reg_ipu = ioremap(mem_ipu->start, + mem_ipu->end - mem_ipu->start + 1); + if (!ipu_data.reg_ipu) { + ret = -ENOMEM; + goto err_ioremap_ipu; + } + + /* Remap Image Converter and Image DMA Controller registers */ + ipu_data.reg_ic = ioremap(mem_ic->start, + mem_ic->end - mem_ic->start + 1); + if (!ipu_data.reg_ic) { + ret = -ENOMEM; + goto err_ioremap_ic; + } + + /* Get IPU clock */ + ipu_data.ipu_clk = clk_get(&pdev->dev, "ipu_clk"); + if (IS_ERR(ipu_data.ipu_clk)) { + ret = PTR_ERR(ipu_data.ipu_clk); + goto err_clk_get; + } + + /* Make sure IPU HSP clock is running */ + clk_enable(ipu_data.ipu_clk); + + /* Disable all interrupts */ + idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_1); + idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_2); + idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_3); + idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_4); + idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_5); + + dev_dbg(&pdev->dev, "%s @ 0x%08lx, fn irq %u, err irq %u\n", pdev->name, + (unsigned long)mem_ipu->start, ipu_data.irq_fn, ipu_data.irq_err); + + ret = ipu_irq_attach_irq(&ipu_data, pdev); + if (ret < 0) + goto err_attach_irq; + + /* Initialize DMA engine */ + ret = ipu_idmac_init(&ipu_data); + if (ret < 0) + goto err_idmac_init; + + tasklet_init(&ipu_data.tasklet, ipu_gc_tasklet, (unsigned long)&ipu_data); + + ipu_data.dev = &pdev->dev; + + dev_dbg(ipu_data.dev, "IPU initialized\n"); + + return 0; + +err_idmac_init: +err_attach_irq: + ipu_irq_detach_irq(&ipu_data, pdev); + clk_disable(ipu_data.ipu_clk); + clk_put(ipu_data.ipu_clk); +err_clk_get: + iounmap(ipu_data.reg_ic); +err_ioremap_ic: + iounmap(ipu_data.reg_ipu); +err_ioremap_ipu: +err_noirq: + dev_err(&pdev->dev, "Failed to probe IPU: %d\n", ret); + return ret; +} + +static int ipu_remove(struct platform_device *pdev) +{ + struct ipu *ipu = platform_get_drvdata(pdev); + + ipu_idmac_exit(ipu); + ipu_irq_detach_irq(ipu, pdev); + clk_disable(ipu->ipu_clk); + clk_put(ipu->ipu_clk); + iounmap(ipu->reg_ic); + iounmap(ipu->reg_ipu); + tasklet_kill(&ipu->tasklet); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +/* + * We need two MEM resources - with IPU-common and Image Converter registers, + * including PF_CONF and IDMAC_* registers, and two IRQs - function and error + */ +static struct platform_driver ipu_platform_driver = { + .driver = { + .name = "ipu-core", + .owner = THIS_MODULE, + }, + .remove = ipu_remove, +}; + +static int __init ipu_init(void) +{ + return platform_driver_probe(&ipu_platform_driver, ipu_probe); +} +subsys_initcall(ipu_init); + +MODULE_DESCRIPTION("IPU core driver"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Guennadi Liakhovetski "); +MODULE_ALIAS("platform:ipu-core"); diff --git a/drivers/dma/ipu/ipu_intern.h b/drivers/dma/ipu/ipu_intern.h new file mode 100644 index 00000000000..545cf11a94a --- /dev/null +++ b/drivers/dma/ipu/ipu_intern.h @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2008 + * Guennadi Liakhovetski, DENX Software Engineering, + * + * Copyright (C) 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _IPU_INTERN_H_ +#define _IPU_INTERN_H_ + +#include +#include +#include + +/* IPU Common registers */ +#define IPU_CONF 0x00 +#define IPU_CHA_BUF0_RDY 0x04 +#define IPU_CHA_BUF1_RDY 0x08 +#define IPU_CHA_DB_MODE_SEL 0x0C +#define IPU_CHA_CUR_BUF 0x10 +#define IPU_FS_PROC_FLOW 0x14 +#define IPU_FS_DISP_FLOW 0x18 +#define IPU_TASKS_STAT 0x1C +#define IPU_IMA_ADDR 0x20 +#define IPU_IMA_DATA 0x24 +#define IPU_INT_CTRL_1 0x28 +#define IPU_INT_CTRL_2 0x2C +#define IPU_INT_CTRL_3 0x30 +#define IPU_INT_CTRL_4 0x34 +#define IPU_INT_CTRL_5 0x38 +#define IPU_INT_STAT_1 0x3C +#define IPU_INT_STAT_2 0x40 +#define IPU_INT_STAT_3 0x44 +#define IPU_INT_STAT_4 0x48 +#define IPU_INT_STAT_5 0x4C +#define IPU_BRK_CTRL_1 0x50 +#define IPU_BRK_CTRL_2 0x54 +#define IPU_BRK_STAT 0x58 +#define IPU_DIAGB_CTRL 0x5C + +/* IPU_CONF Register bits */ +#define IPU_CONF_CSI_EN 0x00000001 +#define IPU_CONF_IC_EN 0x00000002 +#define IPU_CONF_ROT_EN 0x00000004 +#define IPU_CONF_PF_EN 0x00000008 +#define IPU_CONF_SDC_EN 0x00000010 +#define IPU_CONF_ADC_EN 0x00000020 +#define IPU_CONF_DI_EN 0x00000040 +#define IPU_CONF_DU_EN 0x00000080 +#define IPU_CONF_PXL_ENDIAN 0x00000100 + +/* Image Converter Registers */ +#define IC_CONF 0x88 +#define IC_PRP_ENC_RSC 0x8C +#define IC_PRP_VF_RSC 0x90 +#define IC_PP_RSC 0x94 +#define IC_CMBP_1 0x98 +#define IC_CMBP_2 0x9C +#define PF_CONF 0xA0 +#define IDMAC_CONF 0xA4 +#define IDMAC_CHA_EN 0xA8 +#define IDMAC_CHA_PRI 0xAC +#define IDMAC_CHA_BUSY 0xB0 + +/* Image Converter Register bits */ +#define IC_CONF_PRPENC_EN 0x00000001 +#define IC_CONF_PRPENC_CSC1 0x00000002 +#define IC_CONF_PRPENC_ROT_EN 0x00000004 +#define IC_CONF_PRPVF_EN 0x00000100 +#define IC_CONF_PRPVF_CSC1 0x00000200 +#define IC_CONF_PRPVF_CSC2 0x00000400 +#define IC_CONF_PRPVF_CMB 0x00000800 +#define IC_CONF_PRPVF_ROT_EN 0x00001000 +#define IC_CONF_PP_EN 0x00010000 +#define IC_CONF_PP_CSC1 0x00020000 +#define IC_CONF_PP_CSC2 0x00040000 +#define IC_CONF_PP_CMB 0x00080000 +#define IC_CONF_PP_ROT_EN 0x00100000 +#define IC_CONF_IC_GLB_LOC_A 0x10000000 +#define IC_CONF_KEY_COLOR_EN 0x20000000 +#define IC_CONF_RWS_EN 0x40000000 +#define IC_CONF_CSI_MEM_WR_EN 0x80000000 + +#define IDMA_CHAN_INVALID 0x000000FF +#define IDMA_IC_0 0x00000001 +#define IDMA_IC_1 0x00000002 +#define IDMA_IC_2 0x00000004 +#define IDMA_IC_3 0x00000008 +#define IDMA_IC_4 0x00000010 +#define IDMA_IC_5 0x00000020 +#define IDMA_IC_6 0x00000040 +#define IDMA_IC_7 0x00000080 +#define IDMA_IC_8 0x00000100 +#define IDMA_IC_9 0x00000200 +#define IDMA_IC_10 0x00000400 +#define IDMA_IC_11 0x00000800 +#define IDMA_IC_12 0x00001000 +#define IDMA_IC_13 0x00002000 +#define IDMA_SDC_BG 0x00004000 +#define IDMA_SDC_FG 0x00008000 +#define IDMA_SDC_MASK 0x00010000 +#define IDMA_SDC_PARTIAL 0x00020000 +#define IDMA_ADC_SYS1_WR 0x00040000 +#define IDMA_ADC_SYS2_WR 0x00080000 +#define IDMA_ADC_SYS1_CMD 0x00100000 +#define IDMA_ADC_SYS2_CMD 0x00200000 +#define IDMA_ADC_SYS1_RD 0x00400000 +#define IDMA_ADC_SYS2_RD 0x00800000 +#define IDMA_PF_QP 0x01000000 +#define IDMA_PF_BSP 0x02000000 +#define IDMA_PF_Y_IN 0x04000000 +#define IDMA_PF_U_IN 0x08000000 +#define IDMA_PF_V_IN 0x10000000 +#define IDMA_PF_Y_OUT 0x20000000 +#define IDMA_PF_U_OUT 0x40000000 +#define IDMA_PF_V_OUT 0x80000000 + +#define TSTAT_PF_H264_PAUSE 0x00000001 +#define TSTAT_CSI2MEM_MASK 0x0000000C +#define TSTAT_CSI2MEM_OFFSET 2 +#define TSTAT_VF_MASK 0x00000600 +#define TSTAT_VF_OFFSET 9 +#define TSTAT_VF_ROT_MASK 0x000C0000 +#define TSTAT_VF_ROT_OFFSET 18 +#define TSTAT_ENC_MASK 0x00000180 +#define TSTAT_ENC_OFFSET 7 +#define TSTAT_ENC_ROT_MASK 0x00030000 +#define TSTAT_ENC_ROT_OFFSET 16 +#define TSTAT_PP_MASK 0x00001800 +#define TSTAT_PP_OFFSET 11 +#define TSTAT_PP_ROT_MASK 0x00300000 +#define TSTAT_PP_ROT_OFFSET 20 +#define TSTAT_PF_MASK 0x00C00000 +#define TSTAT_PF_OFFSET 22 +#define TSTAT_ADCSYS1_MASK 0x03000000 +#define TSTAT_ADCSYS1_OFFSET 24 +#define TSTAT_ADCSYS2_MASK 0x0C000000 +#define TSTAT_ADCSYS2_OFFSET 26 + +#define TASK_STAT_IDLE 0 +#define TASK_STAT_ACTIVE 1 +#define TASK_STAT_WAIT4READY 2 + +struct idmac { + struct dma_device dma; +}; + +struct ipu { + void __iomem *reg_ipu; + void __iomem *reg_ic; + unsigned int irq_fn; /* IPU Function IRQ to the CPU */ + unsigned int irq_err; /* IPU Error IRQ to the CPU */ + unsigned int irq_base; /* Beginning of the IPU IRQ range */ + unsigned long channel_init_mask; + spinlock_t lock; + struct clk *ipu_clk; + struct device *dev; + struct idmac idmac; + struct idmac_channel channel[IPU_CHANNELS_NUM]; + struct tasklet_struct tasklet; +}; + +#define to_idmac(d) container_of(d, struct idmac, dma) + +extern int ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev); +extern void ipu_irq_detach_irq(struct ipu *ipu, struct platform_device *dev); + +extern bool ipu_irq_status(uint32_t irq); +extern int ipu_irq_map(unsigned int source); +extern int ipu_irq_unmap(unsigned int source); + +#endif diff --git a/drivers/dma/ipu/ipu_irq.c b/drivers/dma/ipu/ipu_irq.c new file mode 100644 index 00000000000..83f532cc767 --- /dev/null +++ b/drivers/dma/ipu/ipu_irq.c @@ -0,0 +1,413 @@ +/* + * Copyright (C) 2008 + * Guennadi Liakhovetski, DENX Software Engineering, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "ipu_intern.h" + +/* + * Register read / write - shall be inlined by the compiler + */ +static u32 ipu_read_reg(struct ipu *ipu, unsigned long reg) +{ + return __raw_readl(ipu->reg_ipu + reg); +} + +static void ipu_write_reg(struct ipu *ipu, u32 value, unsigned long reg) +{ + __raw_writel(value, ipu->reg_ipu + reg); +} + + +/* + * IPU IRQ chip driver + */ + +#define IPU_IRQ_NR_FN_BANKS 3 +#define IPU_IRQ_NR_ERR_BANKS 2 +#define IPU_IRQ_NR_BANKS (IPU_IRQ_NR_FN_BANKS + IPU_IRQ_NR_ERR_BANKS) + +struct ipu_irq_bank { + unsigned int control; + unsigned int status; + spinlock_t lock; + struct ipu *ipu; +}; + +static struct ipu_irq_bank irq_bank[IPU_IRQ_NR_BANKS] = { + /* 3 groups of functional interrupts */ + { + .control = IPU_INT_CTRL_1, + .status = IPU_INT_STAT_1, + }, { + .control = IPU_INT_CTRL_2, + .status = IPU_INT_STAT_2, + }, { + .control = IPU_INT_CTRL_3, + .status = IPU_INT_STAT_3, + }, + /* 2 groups of error interrupts */ + { + .control = IPU_INT_CTRL_4, + .status = IPU_INT_STAT_4, + }, { + .control = IPU_INT_CTRL_5, + .status = IPU_INT_STAT_5, + }, +}; + +struct ipu_irq_map { + unsigned int irq; + int source; + struct ipu_irq_bank *bank; + struct ipu *ipu; +}; + +static struct ipu_irq_map irq_map[CONFIG_MX3_IPU_IRQS]; +/* Protects allocations from the above array of maps */ +static DEFINE_MUTEX(map_lock); +/* Protects register accesses and individual mappings */ +static DEFINE_SPINLOCK(bank_lock); + +static struct ipu_irq_map *src2map(unsigned int src) +{ + int i; + + for (i = 0; i < CONFIG_MX3_IPU_IRQS; i++) + if (irq_map[i].source == src) + return irq_map + i; + + return NULL; +} + +static void ipu_irq_unmask(unsigned int irq) +{ + struct ipu_irq_map *map = get_irq_chip_data(irq); + struct ipu_irq_bank *bank; + uint32_t reg; + unsigned long lock_flags; + + spin_lock_irqsave(&bank_lock, lock_flags); + + bank = map->bank; + if (!bank) { + spin_unlock_irqrestore(&bank_lock, lock_flags); + pr_err("IPU: %s(%u) - unmapped!\n", __func__, irq); + return; + } + + reg = ipu_read_reg(bank->ipu, bank->control); + reg |= (1UL << (map->source & 31)); + ipu_write_reg(bank->ipu, reg, bank->control); + + spin_unlock_irqrestore(&bank_lock, lock_flags); +} + +static void ipu_irq_mask(unsigned int irq) +{ + struct ipu_irq_map *map = get_irq_chip_data(irq); + struct ipu_irq_bank *bank; + uint32_t reg; + unsigned long lock_flags; + + spin_lock_irqsave(&bank_lock, lock_flags); + + bank = map->bank; + if (!bank) { + spin_unlock_irqrestore(&bank_lock, lock_flags); + pr_err("IPU: %s(%u) - unmapped!\n", __func__, irq); + return; + } + + reg = ipu_read_reg(bank->ipu, bank->control); + reg &= ~(1UL << (map->source & 31)); + ipu_write_reg(bank->ipu, reg, bank->control); + + spin_unlock_irqrestore(&bank_lock, lock_flags); +} + +static void ipu_irq_ack(unsigned int irq) +{ + struct ipu_irq_map *map = get_irq_chip_data(irq); + struct ipu_irq_bank *bank; + unsigned long lock_flags; + + spin_lock_irqsave(&bank_lock, lock_flags); + + bank = map->bank; + if (!bank) { + spin_unlock_irqrestore(&bank_lock, lock_flags); + pr_err("IPU: %s(%u) - unmapped!\n", __func__, irq); + return; + } + + ipu_write_reg(bank->ipu, 1UL << (map->source & 31), bank->status); + spin_unlock_irqrestore(&bank_lock, lock_flags); +} + +/** + * ipu_irq_status() - returns the current interrupt status of the specified IRQ. + * @irq: interrupt line to get status for. + * @return: true if the interrupt is pending/asserted or false if the + * interrupt is not pending. + */ +bool ipu_irq_status(unsigned int irq) +{ + struct ipu_irq_map *map = get_irq_chip_data(irq); + struct ipu_irq_bank *bank; + unsigned long lock_flags; + bool ret; + + spin_lock_irqsave(&bank_lock, lock_flags); + bank = map->bank; + ret = bank && ipu_read_reg(bank->ipu, bank->status) & + (1UL << (map->source & 31)); + spin_unlock_irqrestore(&bank_lock, lock_flags); + + return ret; +} + +/** + * ipu_irq_map() - map an IPU interrupt source to an IRQ number + * @source: interrupt source bit position (see below) + * @return: mapped IRQ number or negative error code + * + * The source parameter has to be explained further. On i.MX31 IPU has 137 IRQ + * sources, they are broken down in 5 32-bit registers, like 32, 32, 24, 32, 17. + * However, the source argument of this function is not the sequence number of + * the possible IRQ, but rather its bit position. So, first interrupt in fourth + * register has source number 96, and not 88. This makes calculations easier, + * and also provides forward compatibility with any future IPU implementations + * with any interrupt bit assignments. + */ +int ipu_irq_map(unsigned int source) +{ + int i, ret = -ENOMEM; + struct ipu_irq_map *map; + + might_sleep(); + + mutex_lock(&map_lock); + map = src2map(source); + if (map) { + pr_err("IPU: Source %u already mapped to IRQ %u\n", source, map->irq); + ret = -EBUSY; + goto out; + } + + for (i = 0; i < CONFIG_MX3_IPU_IRQS; i++) { + if (irq_map[i].source < 0) { + unsigned long lock_flags; + + spin_lock_irqsave(&bank_lock, lock_flags); + irq_map[i].source = source; + irq_map[i].bank = irq_bank + source / 32; + spin_unlock_irqrestore(&bank_lock, lock_flags); + + ret = irq_map[i].irq; + pr_debug("IPU: mapped source %u to IRQ %u\n", + source, ret); + break; + } + } +out: + mutex_unlock(&map_lock); + + if (ret < 0) + pr_err("IPU: couldn't map source %u: %d\n", source, ret); + + return ret; +} + +/** + * ipu_irq_map() - map an IPU interrupt source to an IRQ number + * @source: interrupt source bit position (see ipu_irq_map()) + * @return: 0 or negative error code + */ +int ipu_irq_unmap(unsigned int source) +{ + int i, ret = -EINVAL; + + might_sleep(); + + mutex_lock(&map_lock); + for (i = 0; i < CONFIG_MX3_IPU_IRQS; i++) { + if (irq_map[i].source == source) { + unsigned long lock_flags; + + pr_debug("IPU: unmapped source %u from IRQ %u\n", + source, irq_map[i].irq); + + spin_lock_irqsave(&bank_lock, lock_flags); + irq_map[i].source = -EINVAL; + irq_map[i].bank = NULL; + spin_unlock_irqrestore(&bank_lock, lock_flags); + + ret = 0; + break; + } + } + mutex_unlock(&map_lock); + + return ret; +} + +/* Chained IRQ handler for IPU error interrupt */ +static void ipu_irq_err(unsigned int irq, struct irq_desc *desc) +{ + struct ipu *ipu = get_irq_data(irq); + u32 status; + int i, line; + + for (i = IPU_IRQ_NR_FN_BANKS; i < IPU_IRQ_NR_BANKS; i++) { + struct ipu_irq_bank *bank = irq_bank + i; + + spin_lock(&bank_lock); + status = ipu_read_reg(ipu, bank->status); + /* + * Don't think we have to clear all interrupts here, they will + * be acked by ->handle_irq() (handle_level_irq). However, we + * might want to clear unhandled interrupts after the loop... + */ + status &= ipu_read_reg(ipu, bank->control); + spin_unlock(&bank_lock); + while ((line = ffs(status))) { + struct ipu_irq_map *map; + + line--; + status &= ~(1UL << line); + + spin_lock(&bank_lock); + map = src2map(32 * i + line); + if (map) + irq = map->irq; + spin_unlock(&bank_lock); + + if (!map) { + pr_err("IPU: Interrupt on unmapped source %u bank %d\n", + line, i); + continue; + } + generic_handle_irq(irq); + } + } +} + +/* Chained IRQ handler for IPU function interrupt */ +static void ipu_irq_fn(unsigned int irq, struct irq_desc *desc) +{ + struct ipu *ipu = get_irq_data(irq); + u32 status; + int i, line; + + for (i = 0; i < IPU_IRQ_NR_FN_BANKS; i++) { + struct ipu_irq_bank *bank = irq_bank + i; + + spin_lock(&bank_lock); + status = ipu_read_reg(ipu, bank->status); + /* Not clearing all interrupts, see above */ + status &= ipu_read_reg(ipu, bank->control); + spin_unlock(&bank_lock); + while ((line = ffs(status))) { + struct ipu_irq_map *map; + + line--; + status &= ~(1UL << line); + + spin_lock(&bank_lock); + map = src2map(32 * i + line); + if (map) + irq = map->irq; + spin_unlock(&bank_lock); + + if (!map) { + pr_err("IPU: Interrupt on unmapped source %u bank %d\n", + line, i); + continue; + } + generic_handle_irq(irq); + } + } +} + +static struct irq_chip ipu_irq_chip = { + .name = "ipu_irq", + .ack = ipu_irq_ack, + .mask = ipu_irq_mask, + .unmask = ipu_irq_unmask, +}; + +/* Install the IRQ handler */ +int ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev) +{ + struct ipu_platform_data *pdata = dev->dev.platform_data; + unsigned int irq, irq_base, i; + + irq_base = pdata->irq_base; + + for (i = 0; i < IPU_IRQ_NR_BANKS; i++) + irq_bank[i].ipu = ipu; + + for (i = 0; i < CONFIG_MX3_IPU_IRQS; i++) { + int ret; + + irq = irq_base + i; + ret = set_irq_chip(irq, &ipu_irq_chip); + if (ret < 0) + return ret; + ret = set_irq_chip_data(irq, irq_map + i); + if (ret < 0) + return ret; + irq_map[i].ipu = ipu; + irq_map[i].irq = irq; + irq_map[i].source = -EINVAL; + set_irq_handler(irq, handle_level_irq); +#ifdef CONFIG_ARM + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); +#endif + } + + set_irq_data(ipu->irq_fn, ipu); + set_irq_chained_handler(ipu->irq_fn, ipu_irq_fn); + + set_irq_data(ipu->irq_err, ipu); + set_irq_chained_handler(ipu->irq_err, ipu_irq_err); + + return 0; +} + +void ipu_irq_detach_irq(struct ipu *ipu, struct platform_device *dev) +{ + struct ipu_platform_data *pdata = dev->dev.platform_data; + unsigned int irq, irq_base; + + irq_base = pdata->irq_base; + + set_irq_chained_handler(ipu->irq_fn, NULL); + set_irq_data(ipu->irq_fn, NULL); + + set_irq_chained_handler(ipu->irq_err, NULL); + set_irq_data(ipu->irq_err, NULL); + + for (irq = irq_base; irq < irq_base + CONFIG_MX3_IPU_IRQS; irq++) { +#ifdef CONFIG_ARM + set_irq_flags(irq, 0); +#endif + set_irq_chip(irq, NULL); + set_irq_chip_data(irq, NULL); + } +} -- cgit From bfa318ad52a23f1e303d176b44366cdd2bb71ad2 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 15 Jan 2009 15:46:08 +0100 Subject: fix: crash: IP: __bitmap_intersects+0x48/0x73 -tip testing found this crash: > [ 35.258515] calling acpi_cpufreq_init+0x0/0x127 @ 1 > [ 35.264127] BUG: unable to handle kernel NULL pointer dereference at (null) > [ 35.267554] IP: [] __bitmap_intersects+0x48/0x73 > [ 35.267554] PGD 0 > [ 35.267554] Oops: 0000 [#1] SMP DEBUG_PAGEALLOC arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c is still broken: there's no allocation of the variable mask, so we pass in an uninitialized cmd.mask field to drv_read(), which then passes it to the scheduler which then crashes ... Switch it over to the much simpler constant-cpumask-pointers approach. Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index 5bf2c834a23..4b1c319d30c 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -145,7 +145,7 @@ typedef union { struct drv_cmd { unsigned int type; - cpumask_var_t mask; + const struct cpumask *mask; drv_addr_union addr; u32 val; }; @@ -231,6 +231,7 @@ static u32 get_cur_val(const struct cpumask *mask) return 0; } + cmd.mask = mask; drv_read(&cmd); dprintk("get_cur_val = %u\n", cmd.val); @@ -397,9 +398,6 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, return -ENODEV; } - if (unlikely(!alloc_cpumask_var(&cmd.mask, GFP_KERNEL))) - return -ENOMEM; - perf = data->acpi_data; result = cpufreq_frequency_table_target(policy, data->freq_table, @@ -444,9 +442,9 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, /* cpufreq holds the hotplug lock, so we are safe from here on */ if (policy->shared_type != CPUFREQ_SHARED_TYPE_ANY) - cpumask_and(cmd.mask, cpu_online_mask, policy->cpus); + cmd.mask = policy->cpus; else - cpumask_copy(cmd.mask, cpumask_of(policy->cpu)); + cmd.mask = cpumask_of(policy->cpu); freqs.old = perf->states[perf->state].core_frequency * 1000; freqs.new = data->freq_table[next_state].frequency; @@ -473,7 +471,6 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, perf->state = next_perf_state; out: - free_cpumask_var(cmd.mask); return result; } -- cgit From f5495506c3c1300d249d403c36f92de71920dbeb Mon Sep 17 00:00:00 2001 From: Gary Hade Date: Mon, 19 Jan 2009 13:46:41 -0800 Subject: x86: remove kernel_physical_mapping_init() from init section Impact: fix crash with memory hotplug enabled kernel_physical_mapping_init() is called during memory hotplug so it does not belong in the init section. If the kernel is built with CONFIG_DEBUG_SECTION_MISMATCH=y on the make command line, arch/x86/mm/init_64.c is compiled with the -fno-inline-functions-called-once gcc option defeating inlining of kernel_physical_mapping_init() within init_memory_mapping(). When kernel_physical_mapping_init() is not inlined it is placed in the .init.text section according to the __init in it's current declaration. A later call to kernel_physical_mapping_init() during a memory hotplug operation encounters an int3 trap because the .init.text section memory has been freed. This patch eliminates the crash caused by the int3 trap by moving the non-inlined kernel_physical_mapping_init() from .init.text to .meminit.text. Signed-off-by: Gary Hade Signed-off-by: Ingo Molnar --- arch/x86/mm/init_64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 23f68e77ad1..e6d36b49025 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -596,7 +596,7 @@ static void __init init_gbpages(void) direct_gbpages = 0; } -static unsigned long __init kernel_physical_mapping_init(unsigned long start, +static unsigned long __meminit kernel_physical_mapping_init(unsigned long start, unsigned long end, unsigned long page_size_mask) { -- cgit From 70b9986ca4baaf6deb6f0e01d50f72457579adea Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:43:48 +0000 Subject: bnx2x: Free IRQ Error check could result with not freeing the IRQ Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 7c533797c06..ce98ecf8cb1 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -6684,6 +6684,9 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) (DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq)); bnx2x_stats_handle(bp, STATS_EVENT_STOP); + /* Release IRQs */ + bnx2x_free_irq(bp); + /* Wait until tx fast path tasks complete */ for_each_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; @@ -6711,9 +6714,6 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) /* Give HW time to discard old tx messages */ msleep(1); - /* Release IRQs */ - bnx2x_free_irq(bp); - if (CHIP_IS_E1(bp)) { struct mac_configuration_cmd *config = bnx2x_sp(bp, mcast_config); -- cgit From 693fc0d14334859430733ab902adac182fdd8153 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:43:52 +0000 Subject: bnx2x: Handling probe failures Failures in the probe not handled correctly - separate the flow to handle different failures Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index ce98ecf8cb1..911067586a4 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -10269,17 +10269,15 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, return rc; } - rc = register_netdev(dev); - if (rc) { - dev_err(&pdev->dev, "Cannot register net device\n"); - goto init_one_exit; - } - pci_set_drvdata(pdev, dev); rc = bnx2x_init_bp(bp); + if (rc) + goto init_one_exit; + + rc = register_netdev(dev); if (rc) { - unregister_netdev(dev); + dev_err(&pdev->dev, "Cannot register net device\n"); goto init_one_exit; } -- cgit From b4661739c67acd15a02f8e112f8cc52d24b609ed Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:43:56 +0000 Subject: bnx2x: Potential race after iSCSI boot The lock was release too soon. Make sure the HW is marked as locked until the boot driver was unloaded from FW perspective Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 911067586a4..70fc61033dd 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -6874,10 +6874,6 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) */ bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); val = REG_RD(bp, DORQ_REG_NORM_CID_OFST); - if (val == 0x7) - REG_WR(bp, DORQ_REG_NORM_CID_OFST, 0); - bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); - if (val == 0x7) { u32 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; /* save our func */ @@ -6885,6 +6881,9 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) u32 swap_en; u32 swap_val; + /* clear the UNDI indication */ + REG_WR(bp, DORQ_REG_NORM_CID_OFST, 0); + BNX2X_DEV_INFO("UNDI is active! reset device\n"); /* try unload UNDI on port 0 */ @@ -6910,6 +6909,9 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) bnx2x_fw_command(bp, reset_code); } + /* now it's safe to release the lock */ + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); + REG_WR(bp, (BP_PORT(bp) ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0), 0x1000); @@ -6954,7 +6956,9 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) bp->fw_seq = (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) & DRV_MSG_SEQ_NUMBER_MASK); - } + + } else + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); } } -- cgit From af2464011f0954785687071b298f066f6cbb1c84 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:43:59 +0000 Subject: bnx2x: Wrong HDR offset in CAM Has a negative side effect when sending MAC update with no content (as done in the self-test) Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 70fc61033dd..8f8271d76db 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -6144,7 +6144,7 @@ static void bnx2x_set_mac_addr_e1(struct bnx2x *bp, int set) * multicast 64-127:port0 128-191:port1 */ config->hdr.length_6b = 2; - config->hdr.offset = port ? 31 : 0; + config->hdr.offset = port ? 32 : 0; config->hdr.client_id = BP_CL_ID(bp); config->hdr.reserved1 = 0; @@ -8910,7 +8910,10 @@ static int bnx2x_test_intr(struct bnx2x *bp) return -ENODEV; config->hdr.length_6b = 0; - config->hdr.offset = 0; + if (CHIP_IS_E1(bp)) + config->hdr.offset = (BP_PORT(bp) ? 32 : 0); + else + config->hdr.offset = BP_FUNC(bp); config->hdr.client_id = BP_CL_ID(bp); config->hdr.reserved1 = 0; @@ -9863,7 +9866,7 @@ static void bnx2x_set_rx_mode(struct net_device *dev) for (; i < old; i++) { if (CAM_IS_INVALID(config-> config_table[i])) { - i--; /* already invalidated */ + /* already invalidated */ break; } /* invalidate */ -- cgit From 5a40e08e666e8caa1227333de41fd1e2cd84d4f5 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:44:04 +0000 Subject: bnx2x: Read chip ID Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 8f8271d76db..7ee6a211f9b 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -6975,7 +6975,7 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) id |= ((val & 0xf) << 12); val = REG_RD(bp, MISC_REG_CHIP_METAL); id |= ((val & 0xff) << 4); - REG_RD(bp, MISC_REG_BOND_ID); + val = REG_RD(bp, MISC_REG_BOND_ID); id |= (val & 0xf); bp->common.chip_id = id; bp->link_params.chip_id = bp->common.chip_id; -- cgit From 2add3acb11a26cc14b54669433ae6ace6406cbf2 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:44:07 +0000 Subject: bnx2x: Block nvram access when the device is inactive Don't dump eeprom when bnx2x adapter is down. Running ethtool -e causes an eeh without it when the device is down Signed-off-by: Paul Larson Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 7ee6a211f9b..ca5090c3341 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -8107,6 +8107,9 @@ static int bnx2x_get_eeprom(struct net_device *dev, struct bnx2x *bp = netdev_priv(dev); int rc; + if (!netif_running(dev)) + return -EAGAIN; + DP(BNX2X_MSG_NVM, "ethtool_eeprom: cmd %d\n" DP_LEVEL " magic 0x%x offset 0x%x (%d) len 0x%x (%d)\n", eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset, -- cgit From 632da4d66324b5baf947a048dd1f1e9093b6dd90 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:44:10 +0000 Subject: bnx2x: Overstepping array bounds If the page size is > 8KB this violation happens Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index ca5090c3341..2e00da6ab17 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -9427,6 +9427,7 @@ static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb) return rc; } +#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3) /* check if packet requires linearization (packet is too fragmented) */ static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb, u32 xmit_type) @@ -9504,6 +9505,7 @@ exit_lbl: return to_copy; } +#endif /* called with netif_tx_lock * bnx2x_tx_int() runs without netif_tx_lock unless it needs to call @@ -9544,6 +9546,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) skb->ip_summed, skb->protocol, ipv6_hdr(skb)->nexthdr, ip_hdr(skb)->protocol, skb_shinfo(skb)->gso_type, xmit_type); +#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3) /* First, check if we need to linearize the skb (due to FW restrictions) */ if (bnx2x_pkt_req_lin(bp, skb, xmit_type)) { @@ -9556,6 +9559,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } } +#endif /* Please read carefully. First we use one BD which we mark as start, -- cgit From 6c55c3cdc86881383075a933594748b30dd0054b Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:44:13 +0000 Subject: bnx2x: 1G-10G toggling race The HW should be configured so fast toggling between 1G and 10G will not be missed. Make sure that the HW is re-configured in full Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_link.c | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c index fefa6ab1306..d9e1cfcd06d 100644 --- a/drivers/net/bnx2x_link.c +++ b/drivers/net/bnx2x_link.c @@ -317,6 +317,9 @@ static u8 bnx2x_emac_enable(struct link_params *params, val &= ~0x810; EMAC_WR(bp, EMAC_REG_EMAC_MODE, val); + /* enable emac */ + REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1); + /* enable emac for jumbo packets */ EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE, (EMAC_RX_MTU_SIZE_JUMBO_ENA | @@ -1609,7 +1612,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params, u32 gp_status) { struct bnx2x *bp = params->bp; - + u16 new_line_speed; u8 rc = 0; vars->link_status = 0; @@ -1629,7 +1632,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params, switch (gp_status & GP_STATUS_SPEED_MASK) { case GP_STATUS_10M: - vars->line_speed = SPEED_10; + new_line_speed = SPEED_10; if (vars->duplex == DUPLEX_FULL) vars->link_status |= LINK_10TFD; else @@ -1637,7 +1640,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params, break; case GP_STATUS_100M: - vars->line_speed = SPEED_100; + new_line_speed = SPEED_100; if (vars->duplex == DUPLEX_FULL) vars->link_status |= LINK_100TXFD; else @@ -1646,7 +1649,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params, case GP_STATUS_1G: case GP_STATUS_1G_KX: - vars->line_speed = SPEED_1000; + new_line_speed = SPEED_1000; if (vars->duplex == DUPLEX_FULL) vars->link_status |= LINK_1000TFD; else @@ -1654,7 +1657,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params, break; case GP_STATUS_2_5G: - vars->line_speed = SPEED_2500; + new_line_speed = SPEED_2500; if (vars->duplex == DUPLEX_FULL) vars->link_status |= LINK_2500TFD; else @@ -1671,32 +1674,32 @@ static u8 bnx2x_link_settings_status(struct link_params *params, case GP_STATUS_10G_KX4: case GP_STATUS_10G_HIG: case GP_STATUS_10G_CX4: - vars->line_speed = SPEED_10000; + new_line_speed = SPEED_10000; vars->link_status |= LINK_10GTFD; break; case GP_STATUS_12G_HIG: - vars->line_speed = SPEED_12000; + new_line_speed = SPEED_12000; vars->link_status |= LINK_12GTFD; break; case GP_STATUS_12_5G: - vars->line_speed = SPEED_12500; + new_line_speed = SPEED_12500; vars->link_status |= LINK_12_5GTFD; break; case GP_STATUS_13G: - vars->line_speed = SPEED_13000; + new_line_speed = SPEED_13000; vars->link_status |= LINK_13GTFD; break; case GP_STATUS_15G: - vars->line_speed = SPEED_15000; + new_line_speed = SPEED_15000; vars->link_status |= LINK_15GTFD; break; case GP_STATUS_16G: - vars->line_speed = SPEED_16000; + new_line_speed = SPEED_16000; vars->link_status |= LINK_16GTFD; break; @@ -1708,6 +1711,15 @@ static u8 bnx2x_link_settings_status(struct link_params *params, break; } + /* Upon link speed change set the NIG into drain mode. + Comes to deals with possible FIFO glitch due to clk change + when speed is decreased without link down indicator */ + if (new_line_speed != vars->line_speed) { + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + + params->port*4, 0); + msleep(1); + } + vars->line_speed = new_line_speed; vars->link_status |= LINK_STATUS_SERDES_LINK; if ((params->req_line_speed == SPEED_AUTO_NEG) && @@ -4194,6 +4206,11 @@ static u8 bnx2x_update_link_down(struct link_params *params, /* activate nig drain */ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); + /* disable emac */ + REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); + + msleep(10); + /* reset BigMac */ bnx2x_bmac_rx_disable(bp, params->port); REG_WR(bp, GRCBASE_MISC + @@ -4238,6 +4255,7 @@ static u8 bnx2x_update_link_up(struct link_params *params, /* update shared memory */ bnx2x_update_mng(params, vars->link_status); + msleep(20); return rc; } /* This function should called upon link interrupt */ @@ -4276,6 +4294,9 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); + /* disable emac */ + REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); + ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); /* Check external link change only for non-direct */ -- cgit From 3858276b7198074bf3570470463808627f0c9e31 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:44:16 +0000 Subject: bnx2x: Prevent self test loopback failures Setting loopback requires time to take effect Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_link.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c index d9e1cfcd06d..4ce107c125d 100644 --- a/drivers/net/bnx2x_link.c +++ b/drivers/net/bnx2x_link.c @@ -3583,7 +3583,7 @@ static void bnx2x_set_xgxs_loopback(struct link_params *params, (MDIO_REG_BANK_CL73_IEEEB0 + (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)), 0x6041); - + msleep(200); /* set aer mmd back */ bnx2x_set_aer_mmd(params, vars); -- cgit From 44722d1d216c9dd4536de5f88fe8320b07e68a96 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:44:21 +0000 Subject: bnx2x: Legacy speeds autoneg failures 10M/100M autoneg was not establishing link. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_link.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c index 4ce107c125d..2fd6be0cca1 100644 --- a/drivers/net/bnx2x_link.c +++ b/drivers/net/bnx2x_link.c @@ -3882,9 +3882,15 @@ static u8 bnx2x_link_initialize(struct link_params *params, } if (vars->phy_flags & PHY_XGXS_FLAG) { - if (params->req_line_speed && + if ((params->req_line_speed && ((params->req_line_speed == SPEED_100) || - (params->req_line_speed == SPEED_10))) { + (params->req_line_speed == SPEED_10))) || + (!params->req_line_speed && + (params->speed_cap_mask >= + PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) && + (params->speed_cap_mask < + PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) + )) { vars->phy_flags |= PHY_SGMII_FLAG; } else { vars->phy_flags &= ~PHY_SGMII_FLAG; -- cgit From 16b311cc29806bb968746c1a752a087b32841af9 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:44:24 +0000 Subject: bnx2x: Handling PHY FW load failure If the default PHY version (0x4321) is read - the PHY FW load failed Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_link.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c index 2fd6be0cca1..b4527a4a60e 100644 --- a/drivers/net/bnx2x_link.c +++ b/drivers/net/bnx2x_link.c @@ -4404,10 +4404,11 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) ext_phy_addr[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &fw_ver1); - if (fw_ver1 == 0) { + if (fw_ver1 == 0 || fw_ver1 == 0x4321) { DP(NETIF_MSG_LINK, - "bnx2x_8073_common_init_phy port %x " - "fw Download failed\n", port); + "bnx2x_8073_common_init_phy port %x:" + "Download failed. fw version = 0x%x\n", + port, fw_ver1); return -EINVAL; } -- cgit From e47d7e6eb841c1850f0e69b95ae6cf3c86881f53 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:44:28 +0000 Subject: bnx2x: Driver description update The Driver supports the 57711 and 57711E as well but the description was out of date Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 2e00da6ab17..dc05e37c581 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -69,7 +69,7 @@ static char version[] __devinitdata = DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; MODULE_AUTHOR("Eliezer Tamir"); -MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver"); +MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710/57711/57711E Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_MODULE_VERSION); -- cgit From 237907c1ded8a1a447cea7c4f97ab853e8b46052 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Wed, 14 Jan 2009 06:42:44 +0000 Subject: bnx2x: Barriers for the compiler To make sure no swapping are made by the compiler, changed HAS_WORK to inline functions and added all the necessary barriers Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x.h | 9 +-------- drivers/net/bnx2x_main.c | 37 ++++++++++++++++++++++++++----------- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index 6fcccef4cf3..18f60aa3efd 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h @@ -271,14 +271,7 @@ struct bnx2x_fastpath { #define bnx2x_fp(bp, nr, var) (bp->fp[nr].var) -#define BNX2X_HAS_TX_WORK(fp) \ - ((fp->tx_pkt_prod != le16_to_cpu(*fp->tx_cons_sb)) || \ - (fp->tx_pkt_prod != fp->tx_pkt_cons)) - -#define BNX2X_HAS_RX_WORK(fp) \ - (fp->rx_comp_cons != rx_cons_sb) - -#define BNX2X_HAS_WORK(fp) (BNX2X_HAS_RX_WORK(fp) || BNX2X_HAS_TX_WORK(fp)) +#define BNX2X_HAS_WORK(fp) (bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp)) /* MC hsi */ diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index dc05e37c581..3236527477a 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -733,6 +733,17 @@ static u16 bnx2x_ack_int(struct bnx2x *bp) * fast path service functions */ +static inline int bnx2x_has_tx_work(struct bnx2x_fastpath *fp) +{ + u16 tx_cons_sb; + + /* Tell compiler that status block fields can change */ + barrier(); + tx_cons_sb = le16_to_cpu(*fp->tx_cons_sb); + return ((fp->tx_pkt_prod != tx_cons_sb) || + (fp->tx_pkt_prod != fp->tx_pkt_cons)); +} + /* free skb in the packet ring at pos idx * return idx of last bd freed */ @@ -6693,7 +6704,7 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) cnt = 1000; smp_rmb(); - while (BNX2X_HAS_TX_WORK(fp)) { + while (bnx2x_has_tx_work(fp)) { bnx2x_tx_int(fp, 1000); if (!cnt) { @@ -9281,6 +9292,18 @@ static int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state) return 0; } +static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp) +{ + u16 rx_cons_sb; + + /* Tell compiler that status block fields can change */ + barrier(); + rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb); + if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT) + rx_cons_sb++; + return (fp->rx_comp_cons != rx_cons_sb); +} + /* * net_device service functions */ @@ -9291,7 +9314,6 @@ static int bnx2x_poll(struct napi_struct *napi, int budget) napi); struct bnx2x *bp = fp->bp; int work_done = 0; - u16 rx_cons_sb; #ifdef BNX2X_STOP_ON_ERROR if (unlikely(bp->panic)) @@ -9304,19 +9326,12 @@ static int bnx2x_poll(struct napi_struct *napi, int budget) bnx2x_update_fpsb_idx(fp); - if (BNX2X_HAS_TX_WORK(fp)) + if (bnx2x_has_tx_work(fp)) bnx2x_tx_int(fp, budget); - rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb); - if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT) - rx_cons_sb++; - if (BNX2X_HAS_RX_WORK(fp)) + if (bnx2x_has_rx_work(fp)) work_done = bnx2x_rx_int(fp, budget); - rmb(); /* BNX2X_HAS_WORK() reads the status block */ - rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb); - if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT) - rx_cons_sb++; /* must not complete if we consumed full budget */ if ((work_done < budget) && !BNX2X_HAS_WORK(fp)) { -- cgit From d05c26ce690e867aabfc7d708d481e0f86f23496 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Sat, 17 Jan 2009 23:26:13 -0800 Subject: bnx2x: Version update Updating the version and the year of updated files Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x.h | 2 +- drivers/net/bnx2x_link.c | 2 +- drivers/net/bnx2x_main.c | 6 +++--- drivers/net/bnx2x_reg.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index 18f60aa3efd..15a5cf0f676 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h @@ -1,6 +1,6 @@ /* bnx2x.h: Broadcom Everest network driver. * - * Copyright (c) 2007-2008 Broadcom Corporation + * Copyright (c) 2007-2009 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c index b4527a4a60e..aea26b4dc45 100644 --- a/drivers/net/bnx2x_link.c +++ b/drivers/net/bnx2x_link.c @@ -1,4 +1,4 @@ -/* Copyright 2008 Broadcom Corporation +/* Copyright 2008-2009 Broadcom Corporation * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 3236527477a..074374ff93f 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -1,6 +1,6 @@ /* bnx2x_main.c: Broadcom Everest network driver. * - * Copyright (c) 2007-2008 Broadcom Corporation + * Copyright (c) 2007-2009 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -57,8 +57,8 @@ #include "bnx2x.h" #include "bnx2x_init.h" -#define DRV_MODULE_VERSION "1.45.23" -#define DRV_MODULE_RELDATE "2008/11/03" +#define DRV_MODULE_VERSION "1.45.24" +#define DRV_MODULE_RELDATE "2009/01/14" #define BNX2X_BC_VER 0x040200 /* Time in jiffies before concluding the transmitter is hung */ diff --git a/drivers/net/bnx2x_reg.h b/drivers/net/bnx2x_reg.h index a67b0c358ae..d084e5fc4b5 100644 --- a/drivers/net/bnx2x_reg.h +++ b/drivers/net/bnx2x_reg.h @@ -1,6 +1,6 @@ /* bnx2x_reg.h: Broadcom Everest network driver. * - * Copyright (c) 2007-2008 Broadcom Corporation + * Copyright (c) 2007-2009 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by -- cgit From 24e94de41e76134fad05552588fe01af2cab1494 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Sun, 18 Jan 2009 21:32:11 -0800 Subject: net/9p: fid->fid is used uninitialized Signed-off-by: Roel Kluin Signed-off-by: David S. Miller --- net/9p/client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/9p/client.c b/net/9p/client.c index 821f1ec0b2c..1eb580c38fb 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -618,7 +618,7 @@ static struct p9_fid *p9_fid_create(struct p9_client *clnt) return ERR_PTR(-ENOMEM); ret = p9_idpool_get(clnt->fidpool); - if (fid->fid < 0) { + if (ret < 0) { ret = -ENOSPC; goto error; } -- cgit From 39eddb4c3970e9aadbc87b8a7cab7b4fefff077f Mon Sep 17 00:00:00 2001 From: Richard Röjfors Date: Sun, 18 Jan 2009 21:57:35 -0800 Subject: macb: avoid lockup when TGO during underrun MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In rare cases when an underrun occur, all macb buffers where consumed and the netif_queue was stopped infinitely. This happens then the TGO (transfer ongoing) bit in the TSR is set (and UND). It seems like clening up after the underrun makes the driver and the macb hardware end up in an inconsistent state. The result of this is that in the following calls to macb_tx no TX buffers are released -> the netif_queue was stopped, and never woken up again. The solution is to disable the transmitter, if TGO is set, before clening up after the underrun, and re-enable the transmitter when the cleaning up is done. Signed-off-by: Richard Röjfors Signed-off-by: David S. Miller --- drivers/net/macb.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/macb.c b/drivers/net/macb.c index a04da4ecaa8..f6c4936e2fa 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -321,6 +321,10 @@ static void macb_tx(struct macb *bp) printk(KERN_ERR "%s: TX underrun, resetting buffers\n", bp->dev->name); + /* Transfer ongoing, disable transmitter, to avoid confusion */ + if (status & MACB_BIT(TGO)) + macb_writel(bp, NCR, macb_readl(bp, NCR) & ~MACB_BIT(TE)); + head = bp->tx_head; /*Mark all the buffer as used to avoid sending a lost buffer*/ @@ -343,6 +347,10 @@ static void macb_tx(struct macb *bp) } bp->tx_head = bp->tx_tail = 0; + + /* Enable the transmitter again */ + if (status & MACB_BIT(TGO)) + macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TE)); } if (!(status & MACB_BIT(COMP))) -- cgit From eed087e367591fc08490d7c6c2779b4b72c8f20c Mon Sep 17 00:00:00 2001 From: Divy Le Ray Date: Sun, 18 Jan 2009 22:01:32 -0800 Subject: cxgb3: Fix LRO misalignment The lro manager's frag_align_pad setting was missing, leading to misaligned access to the skb passed up to the stack. Tested-by: Rick Jones Signed-off-by: Divy Le Ray Signed-off-by: David S. Miller --- drivers/net/cxgb3/sge.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index 14f9fb3e879..379a1324db4 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -2104,6 +2104,7 @@ static void init_lro_mgr(struct sge_qset *qs, struct net_lro_mgr *lro_mgr) { lro_mgr->dev = qs->netdev; lro_mgr->features = LRO_F_NAPI; + lro_mgr->frag_align_pad = NET_IP_ALIGN; lro_mgr->ip_summed = CHECKSUM_UNNECESSARY; lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY; lro_mgr->max_desc = T3_MAX_LRO_SES; -- cgit From 6a2fe9834e578590f4a2fbe18a574465ab0e127c Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Thu, 15 Jan 2009 12:29:55 +0000 Subject: korina: fix loop back of receive descriptors After the last loop iteration, i has the value RC32434_NUM_RDS and therefore leads to an index overflow when used afterwards to address the last element. This is yet another another bug introduced when rewriting parts of the driver for upstream preparation, as the original driver used 'RC32434_NUM_RDS - 1' instead. Signed-off-by: Phil Sutter Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/korina.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/korina.c b/drivers/net/korina.c index 1d6e48e1336..67fbdf40ace 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -769,11 +769,12 @@ static void korina_alloc_ring(struct net_device *dev) lp->rd_ring[i].link = CPHYSADDR(&lp->rd_ring[i+1]); } - /* loop back */ - lp->rd_ring[i].link = CPHYSADDR(&lp->rd_ring[0]); - lp->rx_next_done = 0; + /* loop back receive descriptors, so the last + * descriptor points to the first one */ + lp->rd_ring[i - 1].link = CPHYSADDR(&lp->rd_ring[0]); + lp->rd_ring[i - 1].control |= DMA_DESC_COD; - lp->rd_ring[i].control |= DMA_DESC_COD; + lp->rx_next_done = 0; lp->rx_chain_head = 0; lp->rx_chain_tail = 0; lp->rx_chain_status = desc_empty; -- cgit From 63a66c6c0debcae70183849121734fd4809e1dde Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Thu, 15 Jan 2009 12:29:56 +0000 Subject: korina: adjust headroom for new skb's also This is copy and paste from the original driver. As skb_reserve() is also called within korina_alloc_ring() when initially allocating the receive descriptors, the same should be done when allocating new space after passing an skb to upper layers. Signed-off-by: Phil Sutter Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/korina.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/korina.c b/drivers/net/korina.c index 67fbdf40ace..60ae7bfb1d9 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -416,6 +416,9 @@ static int korina_rx(struct net_device *dev, int limit) if (devcs & ETH_RX_MP) dev->stats.multicast++; + /* 16 bit align */ + skb_reserve(skb_new, 2); + lp->rx_skb[lp->rx_next_done] = skb_new; } -- cgit From e85bf47e6ded66ea138f692fe149c00a4998afe8 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Thu, 15 Jan 2009 12:29:57 +0000 Subject: korina: drop leftover assignment As the assigned value is being overwritten shortly after, it can be dropped and so the whole variable definition moved to the start of the function. Signed-off-by: Phil Sutter Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/korina.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/korina.c b/drivers/net/korina.c index 60ae7bfb1d9..75010cac76a 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -743,6 +743,7 @@ static struct ethtool_ops netdev_ethtool_ops = { static void korina_alloc_ring(struct net_device *dev) { struct korina_private *lp = netdev_priv(dev); + struct sk_buff *skb; int i; /* Initialize the transmit descriptors */ @@ -758,8 +759,6 @@ static void korina_alloc_ring(struct net_device *dev) /* Initialize the receive descriptors */ for (i = 0; i < KORINA_NUM_RDS; i++) { - struct sk_buff *skb = lp->rx_skb[i]; - skb = dev_alloc_skb(KORINA_RBSIZE + 2); if (!skb) break; -- cgit From 67fd1a731ff1a990d4da7689909317756e50cb4d Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 19 Jan 2009 16:26:44 -0800 Subject: net: Add debug info to track down GSO checksum bug I'm trying to track down why people're hitting the checksum warning in skb_gso_segment. As the problem seems to be hitting lots of people and I can't reproduce it or locate the bug, here is a patch to print out more details which hopefully should help us to track this down. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/core/dev.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/net/core/dev.c b/net/core/dev.c index 8d675975d85..6e44c327710 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1534,7 +1534,19 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) skb->mac_len = skb->network_header - skb->mac_header; __skb_pull(skb, skb->mac_len); - if (WARN_ON(skb->ip_summed != CHECKSUM_PARTIAL)) { + if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) { + struct net_device *dev = skb->dev; + struct ethtool_drvinfo info = {}; + + if (dev && dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) + dev->ethtool_ops->get_drvinfo(dev, &info); + + WARN(1, "%s: caps=(0x%lx, 0x%lx) len=%d data_len=%d " + "ip_summed=%d", + info.driver, dev ? dev->features : 0L, + skb->sk ? skb->sk->sk_route_caps : 0L, + skb->len, skb->data_len, skb->ip_summed); + if (skb_header_cloned(skb) && (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) return ERR_PTR(err); -- cgit From 15005a320473b8d3676b878deb29bbe738ef9027 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Mon, 19 Jan 2009 16:54:13 -0800 Subject: ixgbe: fix dca issue with relaxed ordering turned on The is an issue where setting Relaxed Ordering (RO) bit (in a PCI-E write transaction) on 82598 causing the chipset to drop DCA hints. This patch forces RO not to be set for descriptors as well as payload. This will only be in effect while DCA is enabled and no performance difference was noticed in testing. Signed-off-by: Don Skidmore Signed-off-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 3 +++ drivers/net/ixgbe/ixgbe_type.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index acef3c65cd2..92d9b17a081 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -318,6 +318,9 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter, rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu); rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN; rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN; + rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_RRO_EN); + rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN | + IXGBE_DCA_RXCTRL_DESC_HSRO_EN); IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q), rxctrl); rx_ring->cpu = cpu; } diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 83a11ff9ffd..f011c57c920 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -404,6 +404,9 @@ #define IXGBE_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* DCA Rx Desc enable */ #define IXGBE_DCA_RXCTRL_HEAD_DCA_EN (1 << 6) /* DCA Rx Desc header enable */ #define IXGBE_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* DCA Rx Desc payload enable */ +#define IXGBE_DCA_RXCTRL_DESC_RRO_EN (1 << 9) /* DCA Rx rd Desc Relax Order */ +#define IXGBE_DCA_RXCTRL_DESC_WRO_EN (1 << 13) /* DCA Rx wr Desc Relax Order */ +#define IXGBE_DCA_RXCTRL_DESC_HSRO_EN (1 << 15) /* DCA Rx Split Header RO */ #define IXGBE_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */ #define IXGBE_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */ -- cgit From 068c89b014ebd27b1c09c3c772e9d982988e7786 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Mon, 19 Jan 2009 16:54:36 -0800 Subject: ixgbe: fix tag stripping for VLAN ID 0 Register VLAN ID 0 so that frames with VLAN ID 0 are received and get their tag stripped when ixgbe is not in DCB mode. VLAN ID 0 means that the frame is 'priority tagged' only - it is not a VLAN, but the priority value is the tag in valid. The functions ixgbe_vlan_rx_register() and ixgbe_vlan_rx_kill_vid() were moved up a couple functions to correct compiling issues with this change. Signed-off-by: Don Skidmore Signed-off-by: Peter P Waskiewicz Jr Signed-off-by: Eric W Multanen Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 53 +++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 92d9b17a081..bf36737e2ec 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -1744,6 +1744,32 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum); } +static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + + /* add VID to filter table */ + hw->mac.ops.set_vfta(&adapter->hw, vid, 0, true); +} + +static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + + if (!test_bit(__IXGBE_DOWN, &adapter->state)) + ixgbe_irq_disable(adapter); + + vlan_group_set_device(adapter->vlgrp, vid, NULL); + + if (!test_bit(__IXGBE_DOWN, &adapter->state)) + ixgbe_irq_enable(adapter); + + /* remove VID from filter table */ + hw->mac.ops.set_vfta(&adapter->hw, vid, 0, false); +} + static void ixgbe_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) { @@ -1763,6 +1789,7 @@ static void ixgbe_vlan_rx_register(struct net_device *netdev, ctrl |= IXGBE_VLNCTRL_VME; ctrl &= ~IXGBE_VLNCTRL_CFIEN; IXGBE_WRITE_REG(&adapter->hw, IXGBE_VLNCTRL, ctrl); + ixgbe_vlan_rx_add_vid(netdev, 0); if (grp) { /* enable VLAN tag insert/strip */ @@ -1776,32 +1803,6 @@ static void ixgbe_vlan_rx_register(struct net_device *netdev, ixgbe_irq_enable(adapter); } -static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid) -{ - struct ixgbe_adapter *adapter = netdev_priv(netdev); - struct ixgbe_hw *hw = &adapter->hw; - - /* add VID to filter table */ - hw->mac.ops.set_vfta(&adapter->hw, vid, 0, true); -} - -static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) -{ - struct ixgbe_adapter *adapter = netdev_priv(netdev); - struct ixgbe_hw *hw = &adapter->hw; - - if (!test_bit(__IXGBE_DOWN, &adapter->state)) - ixgbe_irq_disable(adapter); - - vlan_group_set_device(adapter->vlgrp, vid, NULL); - - if (!test_bit(__IXGBE_DOWN, &adapter->state)) - ixgbe_irq_enable(adapter); - - /* remove VID from filter table */ - hw->mac.ops.set_vfta(&adapter->hw, vid, 0, false); -} - static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter) { ixgbe_vlan_rx_register(adapter->netdev, adapter->vlgrp); -- cgit From 1da100bb47ef32cb43bb6a365f64183898f830b5 Mon Sep 17 00:00:00 2001 From: Peter P Waskiewicz Jr Date: Mon, 19 Jan 2009 16:55:03 -0800 Subject: ixgbe: Fix usage of netif_*_all_queues() with netif_carrier_{off|on}() netif_carrier_off() is sufficient to stop Tx into the driver. Stopping the Tx queues is redundant and unnecessary. By the same token, netif_carrier_on() will be sufficient to re-enable Tx, so waking the queues is unnecessary. Signed-off-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index bf36737e2ec..d2f4d5f508b 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2078,6 +2078,9 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) ixgbe_irq_enable(adapter); + /* enable transmits */ + netif_tx_start_all_queues(netdev); + /* bring the link up in the watchdog, this could race with our first * link up interrupt but shouldn't be a problem */ adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; @@ -3479,7 +3482,6 @@ static void ixgbe_watchdog_task(struct work_struct *work) (FLOW_TX ? "TX" : "None")))); netif_carrier_on(netdev); - netif_tx_wake_all_queues(netdev); } else { /* Force detection of hung controller */ adapter->detect_tx_hung = true; @@ -3491,7 +3493,6 @@ static void ixgbe_watchdog_task(struct work_struct *work) printk(KERN_INFO "ixgbe: %s NIC Link is Down\n", netdev->name); netif_carrier_off(netdev); - netif_tx_stop_all_queues(netdev); } } @@ -4222,7 +4223,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, } netif_carrier_off(netdev); - netif_tx_stop_all_queues(netdev); strcpy(netdev->name, "eth%d"); err = register_netdev(netdev); -- cgit From 9e9fd12dc0679643c191fc9795a3021807e77de4 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Mon, 19 Jan 2009 16:57:45 -0800 Subject: tg3: Fix firmware loading This patch modifies how the tg3 driver handles device firmware. The patch starts by consolidating David Woodhouse's earlier patch under the same name. Specifically, the patch moves the request_firmware call into a separate tg3_request_firmware() function and calls that function from tg3_open() rather than tg3_init_one(). The patch then goes on to limit the number of devices that will make request_firmware calls. The original firmware patch unnecessarily requested TSO firmware for devices that did not need it. This patch reduces the set of devices making TSO firmware patches to approximately the following device set : 5703, 5704, and 5705. Finally, the patch reduces the effects of a request_firmware() failure. For those devices that are requesting TSO firmware, the driver will turn off the TSO capability. If TSO firmware becomes available at a later time, the device can be closed and then opened again to reacquire the TSO capability. Signed-off-by: Matt Carlson Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 81 ++++++++++++++++++++++++++++++++++--------------------- drivers/net/tg3.h | 1 + 2 files changed, 51 insertions(+), 31 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 5e2dbaee125..8b3f8468538 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -7535,11 +7535,58 @@ static int tg3_test_msi(struct tg3 *tp) return err; } +static int tg3_request_firmware(struct tg3 *tp) +{ + const __be32 *fw_data; + + if (request_firmware(&tp->fw, tp->fw_needed, &tp->pdev->dev)) { + printk(KERN_ERR "%s: Failed to load firmware \"%s\"\n", + tp->dev->name, tp->fw_needed); + return -ENOENT; + } + + fw_data = (void *)tp->fw->data; + + /* Firmware blob starts with version numbers, followed by + * start address and _full_ length including BSS sections + * (which must be longer than the actual data, of course + */ + + tp->fw_len = be32_to_cpu(fw_data[2]); /* includes bss */ + if (tp->fw_len < (tp->fw->size - 12)) { + printk(KERN_ERR "%s: bogus length %d in \"%s\"\n", + tp->dev->name, tp->fw_len, tp->fw_needed); + release_firmware(tp->fw); + tp->fw = NULL; + return -EINVAL; + } + + /* We no longer need firmware; we have it. */ + tp->fw_needed = NULL; + return 0; +} + static int tg3_open(struct net_device *dev) { struct tg3 *tp = netdev_priv(dev); int err; + if (tp->fw_needed) { + err = tg3_request_firmware(tp); + if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0) { + if (err) + return err; + } else if (err) { + printk(KERN_WARNING "%s: TSO capability disabled.\n", + tp->dev->name); + tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE; + } else if (!(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)) { + printk(KERN_NOTICE "%s: TSO capability restored.\n", + tp->dev->name); + tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE; + } + } + netif_carrier_off(tp->dev); err = tg3_set_power_state(tp, PCI_D0); @@ -12934,7 +12981,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, struct net_device *dev; struct tg3 *tp; int err, pm_cap; - const char *fw_name = NULL; char str[40]; u64 dma_mask, persist_dma_mask; @@ -13091,7 +13137,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, tg3_init_bufmgr_config(tp); if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0) - fw_name = FIRMWARE_TG3; + tp->fw_needed = FIRMWARE_TG3; if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) { tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE; @@ -13104,37 +13150,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE; } else { tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE | TG3_FLG2_TSO_BUG; - } - if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) - fw_name = FIRMWARE_TG3TSO5; + tp->fw_needed = FIRMWARE_TG3TSO5; else - fw_name = FIRMWARE_TG3TSO; - } - - if (fw_name) { - const __be32 *fw_data; - - err = request_firmware(&tp->fw, fw_name, &tp->pdev->dev); - if (err) { - printk(KERN_ERR "tg3: Failed to load firmware \"%s\"\n", - fw_name); - goto err_out_iounmap; - } - - fw_data = (void *)tp->fw->data; - - /* Firmware blob starts with version numbers, followed by - start address and _full_ length including BSS sections - (which must be longer than the actual data, of course */ - - tp->fw_len = be32_to_cpu(fw_data[2]); /* includes bss */ - if (tp->fw_len < (tp->fw->size - 12)) { - printk(KERN_ERR "tg3: bogus length %d in \"%s\"\n", - tp->fw_len, fw_name); - err = -EINVAL; - goto err_out_fw; - } + tp->fw_needed = FIRMWARE_TG3TSO; } /* TSO is on by default on chips that support hardware TSO. diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index ae5da603c6a..508def3e077 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2764,6 +2764,7 @@ struct tg3 { struct ethtool_coalesce coal; /* firmware info */ + const char *fw_needed; const struct firmware *fw; u32 fw_len; /* includes BSS */ }; -- cgit From 8b9d3728977760f6bd1317c4420890f73695354e Mon Sep 17 00:00:00 2001 From: Jarek Poplawski Date: Mon, 19 Jan 2009 17:03:56 -0800 Subject: net: Fix data corruption when splicing from sockets. The trick in socket splicing where we try to convert the skb->data into a page based reference using virt_to_page() does not work so well. The idea is to pass the virt_to_page() reference via the pipe buffer, and refcount the buffer using a SKB reference. But if we are splicing from a socket to a socket (via sendpage) this doesn't work. The from side processing will grab the page (and SKB) references. The sendpage() calls will grab page references only, return, and then the from side processing completes and drops the SKB ref. The page based reference to skb->data is not enough to keep the kmalloc() buffer backing it from being reused. Yet, that is all that the socket send side has at this point. This leads to data corruption if the skb->data buffer is reused by SLAB before the send side socket actually gets the TX packet out to the device. The fix employed here is to simply allocate a page and copy the skb->data bytes into that page. This will hurt performance, but there is no clear way to fix this properly without a copy at the present time, and it is important to get rid of the data corruption. With fixes from Herbert Xu. Tested-by: Willy Tarreau Foreseen-by: Changli Gao Diagnosed-by: Willy Tarreau Reported-by: Willy Tarreau Fixed-by: Jens Axboe Signed-off-by: Jarek Poplawski Signed-off-by: David S. Miller --- net/core/skbuff.c | 61 ++++++++++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 65eac773903..56272ac6dfd 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -73,17 +73,13 @@ static struct kmem_cache *skbuff_fclone_cache __read_mostly; static void sock_pipe_buf_release(struct pipe_inode_info *pipe, struct pipe_buffer *buf) { - struct sk_buff *skb = (struct sk_buff *) buf->private; - - kfree_skb(skb); + put_page(buf->page); } static void sock_pipe_buf_get(struct pipe_inode_info *pipe, struct pipe_buffer *buf) { - struct sk_buff *skb = (struct sk_buff *) buf->private; - - skb_get(skb); + get_page(buf->page); } static int sock_pipe_buf_steal(struct pipe_inode_info *pipe, @@ -1334,9 +1330,19 @@ fault: */ static void sock_spd_release(struct splice_pipe_desc *spd, unsigned int i) { - struct sk_buff *skb = (struct sk_buff *) spd->partial[i].private; + put_page(spd->pages[i]); +} - kfree_skb(skb); +static inline struct page *linear_to_page(struct page *page, unsigned int len, + unsigned int offset) +{ + struct page *p = alloc_pages(GFP_KERNEL, 0); + + if (!p) + return NULL; + memcpy(page_address(p) + offset, page_address(page) + offset, len); + + return p; } /* @@ -1344,16 +1350,23 @@ static void sock_spd_release(struct splice_pipe_desc *spd, unsigned int i) */ static inline int spd_fill_page(struct splice_pipe_desc *spd, struct page *page, unsigned int len, unsigned int offset, - struct sk_buff *skb) + struct sk_buff *skb, int linear) { if (unlikely(spd->nr_pages == PIPE_BUFFERS)) return 1; + if (linear) { + page = linear_to_page(page, len, offset); + if (!page) + return 1; + } else + get_page(page); + spd->pages[spd->nr_pages] = page; spd->partial[spd->nr_pages].len = len; spd->partial[spd->nr_pages].offset = offset; - spd->partial[spd->nr_pages].private = (unsigned long) skb_get(skb); spd->nr_pages++; + return 0; } @@ -1369,7 +1382,7 @@ static inline void __segment_seek(struct page **page, unsigned int *poff, static inline int __splice_segment(struct page *page, unsigned int poff, unsigned int plen, unsigned int *off, unsigned int *len, struct sk_buff *skb, - struct splice_pipe_desc *spd) + struct splice_pipe_desc *spd, int linear) { if (!*len) return 1; @@ -1392,7 +1405,7 @@ static inline int __splice_segment(struct page *page, unsigned int poff, /* the linear region may spread across several pages */ flen = min_t(unsigned int, flen, PAGE_SIZE - poff); - if (spd_fill_page(spd, page, flen, poff, skb)) + if (spd_fill_page(spd, page, flen, poff, skb, linear)) return 1; __segment_seek(&page, &poff, &plen, flen); @@ -1419,7 +1432,7 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset, if (__splice_segment(virt_to_page(skb->data), (unsigned long) skb->data & (PAGE_SIZE - 1), skb_headlen(skb), - offset, len, skb, spd)) + offset, len, skb, spd, 1)) return 1; /* @@ -1429,7 +1442,7 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset, const skb_frag_t *f = &skb_shinfo(skb)->frags[seg]; if (__splice_segment(f->page, f->page_offset, f->size, - offset, len, skb, spd)) + offset, len, skb, spd, 0)) return 1; } @@ -1442,7 +1455,7 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset, * the frag list, if such a thing exists. We'd probably need to recurse to * handle that cleanly. */ -int skb_splice_bits(struct sk_buff *__skb, unsigned int offset, +int skb_splice_bits(struct sk_buff *skb, unsigned int offset, struct pipe_inode_info *pipe, unsigned int tlen, unsigned int flags) { @@ -1455,16 +1468,6 @@ int skb_splice_bits(struct sk_buff *__skb, unsigned int offset, .ops = &sock_pipe_buf_ops, .spd_release = sock_spd_release, }; - struct sk_buff *skb; - - /* - * I'd love to avoid the clone here, but tcp_read_sock() - * ignores reference counts and unconditonally kills the sk_buff - * on return from the actor. - */ - skb = skb_clone(__skb, GFP_KERNEL); - if (unlikely(!skb)) - return -ENOMEM; /* * __skb_splice_bits() only fails if the output has no room left, @@ -1488,15 +1491,9 @@ int skb_splice_bits(struct sk_buff *__skb, unsigned int offset, } done: - /* - * drop our reference to the clone, the pipe consumption will - * drop the rest. - */ - kfree_skb(skb); - if (spd.nr_pages) { + struct sock *sk = skb->sk; int ret; - struct sock *sk = __skb->sk; /* * Drop the socket lock, otherwise we have reverse -- cgit From e0c6ef9388b58f297937fc9651331941d1579b25 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Mon, 19 Jan 2009 17:16:00 -0800 Subject: Revert "mv643xx_eth: use longer DMA bursts". This reverts commit cd4ccf76bfd2c36d351e68be7e6a597268f98a1a. On the Pegasos board, we can't do DMA burst that are longer than one cache line. For now, go back to using 32 byte DMA bursts for all mv643xx_eth platforms -- we can switch the ARM-based platforms back to doing long 128 byte bursts in the next development cycle. Signed-off-by: Lennert Buytenhek Reported-by: Alan Curry Reported-by: Gabriel Paubert Signed-off-by: David S. Miller --- drivers/net/mv643xx_eth.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 7253a499d9c..e2aa468d40f 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -136,21 +136,23 @@ static char mv643xx_eth_driver_version[] = "1.4"; /* * SDMA configuration register. */ +#define RX_BURST_SIZE_4_64BIT (2 << 1) #define RX_BURST_SIZE_16_64BIT (4 << 1) #define BLM_RX_NO_SWAP (1 << 4) #define BLM_TX_NO_SWAP (1 << 5) +#define TX_BURST_SIZE_4_64BIT (2 << 22) #define TX_BURST_SIZE_16_64BIT (4 << 22) #if defined(__BIG_ENDIAN) #define PORT_SDMA_CONFIG_DEFAULT_VALUE \ - (RX_BURST_SIZE_16_64BIT | \ - TX_BURST_SIZE_16_64BIT) + (RX_BURST_SIZE_4_64BIT | \ + TX_BURST_SIZE_4_64BIT) #elif defined(__LITTLE_ENDIAN) #define PORT_SDMA_CONFIG_DEFAULT_VALUE \ - (RX_BURST_SIZE_16_64BIT | \ - BLM_RX_NO_SWAP | \ - BLM_TX_NO_SWAP | \ - TX_BURST_SIZE_16_64BIT) + (RX_BURST_SIZE_4_64BIT | \ + BLM_RX_NO_SWAP | \ + BLM_TX_NO_SWAP | \ + TX_BURST_SIZE_4_64BIT) #else #error One of __BIG_ENDIAN or __LITTLE_ENDIAN must be defined #endif -- cgit From 2b448334a255d34401562229f467ffd95d8ed6ef Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Mon, 19 Jan 2009 17:17:18 -0800 Subject: mv643xx_eth: fix multicast filter programming Commit 66e63ffbc04706568d8789cbb00eaa8ddbcae648 ("mv643xx_eth: implement ->set_rx_mode()") cleaned up mv643xx_eth's multicast filter programming, but broke it as well. The non-special multicast filter table (for multicast addresses that are not of the form 01:00:5e:00:00:xx) consists of 256 hash table buckets organised as 64 32-bit words, where the 'accept' bits are in the LSB of each byte, so in bits 24 16 8 0 of each 32-bit word. The old code got this right, but the referenced commit broke this by using bits 3 2 1 0 instead. This commit fixes this up. Signed-off-by: Lennert Buytenhek Signed-off-by: David S. Miller --- drivers/net/mv643xx_eth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index e2aa468d40f..8c6979a26d6 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -1596,7 +1596,7 @@ oom: entry = addr_crc(a); } - table[entry >> 2] |= 1 << (entry & 3); + table[entry >> 2] |= 1 << (8 * (entry & 3)); } for (i = 0; i < 0x100; i += 4) { -- cgit From fe65e704534de5d0661ebc3466a2b9018945f694 Mon Sep 17 00:00:00 2001 From: Gabriel Paubert Date: Mon, 19 Jan 2009 17:18:09 -0800 Subject: mv643xx_eth: prevent interrupt storm on ifconfig down Contrary to what the docs say, the 'extended interrupt cause' bit in the interrupt cause register (bit 1) appears to not be maskable on at least some of the mv643xx_eth platforms, making writing zeroes to the interrupt mask register but not the extended interrupt mask register insufficient to stop interrupts from occuring. Therefore, also write zeroes to the extended interrupt mask register when shutting down the port. This fixes the interrupt storm seen on the Pegasos board when shutting down the interface. Signed-off-by: Lennert Buytenhek Signed-off-by: David S. Miller --- drivers/net/mv643xx_eth.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 8c6979a26d6..5f31bbb614a 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -2212,6 +2212,7 @@ static int mv643xx_eth_stop(struct net_device *dev) struct mv643xx_eth_private *mp = netdev_priv(dev); int i; + wrlp(mp, INT_MASK_EXT, 0x00000000); wrlp(mp, INT_MASK, 0x00000000); rdlp(mp, INT_MASK); -- cgit From f4895b8bc83a22a36446c4aee277e1750fcc6a18 Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Mon, 19 Jan 2009 13:19:30 +0000 Subject: wimax/i2400m: error paths that need to free an skb should use kfree_skb() Roel Kluin reported a bug in two error paths where skbs were wrongly being freed using kfree(). He provided a fix where it was replaced to kfree_skb(), as it should be. However, in i2400mu_rx(), the error path was missing returning an indication of the failure. Changed to reset rx_skb to NULL and return it to the caller, i2400mu_rxd(). It will be treated as a transient error and just ignore the packet. Depending on the buffering conditions inside the device, the data packet might be dropped or the device will signal the host again for data-ready-to-read and the host will retry. Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: David S. Miller --- drivers/net/wimax/i2400m/control.c | 2 +- drivers/net/wimax/i2400m/usb-rx.c | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/wimax/i2400m/control.c b/drivers/net/wimax/i2400m/control.c index d3d37fed689..15d9f51b292 100644 --- a/drivers/net/wimax/i2400m/control.c +++ b/drivers/net/wimax/i2400m/control.c @@ -609,7 +609,7 @@ void i2400m_msg_to_dev_cancel_wait(struct i2400m *i2400m, int code) spin_lock_irqsave(&i2400m->rx_lock, flags); ack_skb = i2400m->ack_skb; if (ack_skb && !IS_ERR(ack_skb)) - kfree(ack_skb); + kfree_skb(ack_skb); i2400m->ack_skb = ERR_PTR(code); spin_unlock_irqrestore(&i2400m->rx_lock, flags); } diff --git a/drivers/net/wimax/i2400m/usb-rx.c b/drivers/net/wimax/i2400m/usb-rx.c index 074cc1f8985..a314799967c 100644 --- a/drivers/net/wimax/i2400m/usb-rx.c +++ b/drivers/net/wimax/i2400m/usb-rx.c @@ -184,6 +184,8 @@ void i2400mu_rx_size_maybe_shrink(struct i2400mu *i2400mu) * NOTE: this function might realloc the skb (if it is too small), * so always update with the one returned. * ERR_PTR() is < 0 on error. + * Will return NULL if it cannot reallocate -- this can be + * considered a transient retryable error. */ static struct sk_buff *i2400mu_rx(struct i2400mu *i2400mu, struct sk_buff *rx_skb) @@ -243,8 +245,8 @@ retry: if (printk_ratelimit()) dev_err(dev, "RX: Can't reallocate skb to %d; " "RX dropped\n", rx_size); - kfree(rx_skb); - result = 0; + kfree_skb(rx_skb); + rx_skb = NULL; goto out; /* drop it...*/ } kfree_skb(rx_skb); @@ -344,7 +346,8 @@ int i2400mu_rxd(void *_i2400mu) if (IS_ERR(rx_skb)) goto out; atomic_dec(&i2400mu->rx_pending_count); - if (rx_skb->len == 0) { /* some ignorable condition */ + if (rx_skb == NULL || rx_skb->len == 0) { + /* some "ignorable" condition */ kfree_skb(rx_skb); continue; } -- cgit From c6e50f93db5bd0895ec7c7d1b6f3886c6e1f11b6 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 20 Jan 2009 12:29:19 +0900 Subject: x86: cleanup stack protector Impact: cleanup Make the following cleanups. * remove duplicate comment from boot_init_stack_canary() which fits better in the other place - cpu_idle(). * move stack_canary offset check from __switch_to() to boot_init_stack_canary(). Signed-off-by: Tejun Heo --- arch/x86/include/asm/pda.h | 2 -- arch/x86/include/asm/stackprotector.h | 13 ++++++------- arch/x86/kernel/process_64.c | 7 ------- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h index 5976cd803e9..4a8c9d382c9 100644 --- a/arch/x86/include/asm/pda.h +++ b/arch/x86/include/asm/pda.h @@ -40,6 +40,4 @@ extern void pda_init(int); #endif -#define refresh_stack_canary() write_pda(stack_canary, current->stack_canary) - #endif /* _ASM_X86_PDA_H */ diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h index c7f0d10bae7..2383e5bb475 100644 --- a/arch/x86/include/asm/stackprotector.h +++ b/arch/x86/include/asm/stackprotector.h @@ -16,13 +16,12 @@ static __always_inline void boot_init_stack_canary(void) u64 tsc; /* - * If we're the non-boot CPU, nothing set the PDA stack - * canary up for us - and if we are the boot CPU we have - * a 0 stack canary. This is a good place for updating - * it, as we wont ever return from this function (so the - * invalid canaries already on the stack wont ever - * trigger). - * + * Build time only check to make sure the stack_canary is at + * offset 40 in the pda; this is a gcc ABI requirement + */ + BUILD_BUG_ON(offsetof(struct x8664_pda, stack_canary) != 40); + + /* * We both use the random pool and the current TSC as a source * of randomness. The TSC only matters for very early init, * there it already has some randomness on most systems. Later diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index aa89eabf09e..088bc9a0f82 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -638,13 +638,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) percpu_write(kernel_stack, (unsigned long)task_stack_page(next_p) + THREAD_SIZE - KERNEL_STACK_OFFSET); -#ifdef CONFIG_CC_STACKPROTECTOR - /* - * Build time only check to make sure the stack_canary is at - * offset 40 in the pda; this is a gcc ABI requirement - */ - BUILD_BUG_ON(offsetof(struct x8664_pda, stack_canary) != 40); -#endif /* * Now maybe reload the debug registers and handle I/O bitmaps -- cgit From b4a8f7a262e79ecb0b39beb1449af524a78887f8 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 20 Jan 2009 12:29:19 +0900 Subject: x86: conditionalize stack canary handling in hot path Impact: no unnecessary stack canary swapping during context switch There's no point in moving stack_canary around during context switch if it's not enabled. Conditionalize it. Signed-off-by: Tejun Heo --- arch/x86/include/asm/system.h | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h index 8cadfe9b119..b77bd8bd3cc 100644 --- a/arch/x86/include/asm/system.h +++ b/arch/x86/include/asm/system.h @@ -86,17 +86,28 @@ do { \ , "rcx", "rbx", "rdx", "r8", "r9", "r10", "r11", \ "r12", "r13", "r14", "r15" +#ifdef CONFIG_CC_STACKPROTECTOR +#define __switch_canary \ + "movq %P[task_canary](%%rsi),%%r8\n\t" \ + "movq %%r8,%%gs:%P[pda_canary]\n\t" +#define __switch_canary_param \ + , [task_canary] "i" (offsetof(struct task_struct, stack_canary)) \ + , [pda_canary] "i" (offsetof(struct x8664_pda, stack_canary)) +#else /* CC_STACKPROTECTOR */ +#define __switch_canary +#define __switch_canary_param +#endif /* CC_STACKPROTECTOR */ + /* Save restore flags to clear handle leaking NT */ #define switch_to(prev, next, last) \ - asm volatile(SAVE_CONTEXT \ + asm volatile(SAVE_CONTEXT \ "movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */ \ "movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */ \ "call __switch_to\n\t" \ ".globl thread_return\n" \ "thread_return:\n\t" \ "movq "__percpu_arg([current_task])",%%rsi\n\t" \ - "movq %P[task_canary](%%rsi),%%r8\n\t" \ - "movq %%r8,%%gs:%P[pda_canary]\n\t" \ + __switch_canary \ "movq %P[thread_info](%%rsi),%%r8\n\t" \ LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \ "movq %%rax,%%rdi\n\t" \ @@ -108,9 +119,8 @@ do { \ [ti_flags] "i" (offsetof(struct thread_info, flags)), \ [tif_fork] "i" (TIF_FORK), \ [thread_info] "i" (offsetof(struct task_struct, stack)), \ - [task_canary] "i" (offsetof(struct task_struct, stack_canary)),\ - [current_task] "m" (per_cpu_var(current_task)), \ - [pda_canary] "i" (offsetof(struct x8664_pda, stack_canary))\ + [current_task] "m" (per_cpu_var(current_task)) \ + __switch_canary_param \ : "memory", "cc" __EXTRA_CLOBBER) #endif -- cgit From 8ce031972b40da58c268caba8c5ea3c0856d7131 Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Mon, 19 Jan 2009 12:21:27 +0900 Subject: x86: remove pda_init() Impact: cleanup Copy the code to cpu_init() to satisfy the requirement that the cpu be reinitialized. Remove all other calls, since the segments are already initialized in head_64.S. Signed-off-by: Brian Gerst Signed-off-by: Tejun Heo --- arch/x86/include/asm/pda.h | 1 - arch/x86/kernel/cpu/common.c | 15 +++------------ arch/x86/kernel/head64.c | 2 -- arch/x86/xen/enlighten.c | 1 - 4 files changed, 3 insertions(+), 16 deletions(-) diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h index 4a8c9d382c9..b473e952439 100644 --- a/arch/x86/include/asm/pda.h +++ b/arch/x86/include/asm/pda.h @@ -24,7 +24,6 @@ struct x8664_pda { } ____cacheline_aligned_in_smp; DECLARE_PER_CPU(struct x8664_pda, __pda); -extern void pda_init(int); #define cpu_pda(cpu) (&per_cpu(__pda, cpu)) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 7976a6a0f65..f83a4d6160f 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -895,15 +895,6 @@ EXPORT_PER_CPU_SYMBOL(kernel_stack); DEFINE_PER_CPU(unsigned int, irq_count) = -1; -void __cpuinit pda_init(int cpu) -{ - /* Setup up data that may be needed in __get_free_pages early */ - loadsegment(fs, 0); - loadsegment(gs, 0); - - load_pda_offset(cpu); -} - static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks [(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]) __aligned(PAGE_SIZE); @@ -967,9 +958,9 @@ void __cpuinit cpu_init(void) struct task_struct *me; int i; - /* CPU 0 is initialised in head64.c */ - if (cpu != 0) - pda_init(cpu); + loadsegment(fs, 0); + loadsegment(gs, 0); + load_pda_offset(cpu); #ifdef CONFIG_NUMA if (cpu != 0 && percpu_read(node_number) == 0 && diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index af67d3227ea..f5b27224769 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -91,8 +91,6 @@ void __init x86_64_start_kernel(char * real_mode_data) if (console_loglevel == 10) early_printk("Kernel alive\n"); - pda_init(0); - x86_64_start_reservations(real_mode_data); } diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 75b94139e1f..bef941f6145 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -1645,7 +1645,6 @@ asmlinkage void __init xen_start_kernel(void) #ifdef CONFIG_X86_64 /* Disable until direct per-cpu data access. */ have_vcpu_info_placement = 0; - pda_init(0); #endif xen_smp_init(); -- cgit From 0bd74fa8e29dcad98f7e8ffe01ec05fb3326abaf Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Mon, 19 Jan 2009 12:21:27 +0900 Subject: percpu: refactor percpu.h Impact: cleanup Refactor the DEFINE_PER_CPU_* macros and add .data.percpu.first section. Signed-off-by: Brian Gerst Signed-off-by: Tejun Heo --- include/asm-generic/vmlinux.lds.h | 1 + include/linux/percpu.h | 41 ++++++++++++++++++++++----------------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index aa6b9b1b30b..32bbf50d305 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -486,6 +486,7 @@ */ #define PERCPU_VADDR(vaddr, phdr) \ PERCPU_PROLOG(vaddr) \ + *(.data.percpu.first) \ *(.data.percpu.page_aligned) \ *(.data.percpu) \ *(.data.percpu.shared_aligned) \ diff --git a/include/linux/percpu.h b/include/linux/percpu.h index 9f2a3751873..0e24202b5a4 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -9,34 +9,39 @@ #include #ifdef CONFIG_SMP -#define DEFINE_PER_CPU(type, name) \ - __attribute__((__section__(".data.percpu"))) \ - PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name +#define PER_CPU_BASE_SECTION ".data.percpu" #ifdef MODULE -#define SHARED_ALIGNED_SECTION ".data.percpu" +#define PER_CPU_SHARED_ALIGNED_SECTION "" #else -#define SHARED_ALIGNED_SECTION ".data.percpu.shared_aligned" +#define PER_CPU_SHARED_ALIGNED_SECTION ".shared_aligned" #endif +#define PER_CPU_FIRST_SECTION ".first" -#define DEFINE_PER_CPU_SHARED_ALIGNED(type, name) \ - __attribute__((__section__(SHARED_ALIGNED_SECTION))) \ - PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name \ - ____cacheline_aligned_in_smp +#else + +#define PER_CPU_BASE_SECTION ".data" +#define PER_CPU_SHARED_ALIGNED_SECTION "" +#define PER_CPU_FIRST_SECTION "" + +#endif -#define DEFINE_PER_CPU_PAGE_ALIGNED(type, name) \ - __attribute__((__section__(".data.percpu.page_aligned"))) \ +#define DEFINE_PER_CPU_SECTION(type, name, section) \ + __attribute__((__section__(PER_CPU_BASE_SECTION section))) \ PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name -#else + #define DEFINE_PER_CPU(type, name) \ - PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name + DEFINE_PER_CPU_SECTION(type, name, "") -#define DEFINE_PER_CPU_SHARED_ALIGNED(type, name) \ - DEFINE_PER_CPU(type, name) +#define DEFINE_PER_CPU_SHARED_ALIGNED(type, name) \ + DEFINE_PER_CPU_SECTION(type, name, PER_CPU_SHARED_ALIGNED_SECTION) \ + ____cacheline_aligned_in_smp -#define DEFINE_PER_CPU_PAGE_ALIGNED(type, name) \ - DEFINE_PER_CPU(type, name) -#endif +#define DEFINE_PER_CPU_PAGE_ALIGNED(type, name) \ + DEFINE_PER_CPU_SECTION(type, name, ".page_aligned") + +#define DEFINE_PER_CPU_FIRST(type, name) \ + DEFINE_PER_CPU_SECTION(type, name, PER_CPU_FIRST_SECTION) #define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var) #define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var) -- cgit From 8c7e58e690ae60ab4215b025f433ed4af261e103 Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Mon, 19 Jan 2009 12:21:28 +0900 Subject: x86: rework __per_cpu_load adjustments Impact: cleanup Use cpu_number to determine if the adjustment is necessary. Signed-off-by: Brian Gerst Signed-off-by: Tejun Heo --- arch/x86/kernel/head_64.S | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index c8ace880661..98ea26a2fca 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -207,19 +207,15 @@ ENTRY(secondary_startup_64) #ifdef CONFIG_SMP /* - * early_gdt_base should point to the gdt_page in static percpu init - * data area. Computing this requires two symbols - __per_cpu_load - * and per_cpu__gdt_page. As linker can't do no such relocation, do - * it by hand. As early_gdt_descr is manipulated by C code for - * secondary CPUs, this should be done only once for the boot CPU - * when early_gdt_descr_base contains zero. + * Fix up static pointers that need __per_cpu_load added. The assembler + * is unable to do this directly. This is only needed for the boot cpu. + * These values are set up with the correct base addresses by C code for + * secondary cpus. */ - movq early_gdt_descr_base(%rip), %rax - testq %rax, %rax - jnz 1f - movq $__per_cpu_load, %rax - addq $per_cpu__gdt_page, %rax - movq %rax, early_gdt_descr_base(%rip) + movq initial_gs(%rip), %rax + cmpl $0, per_cpu__cpu_number(%rax) + jne 1f + addq %rax, early_gdt_descr_base(%rip) 1: #endif /* @@ -431,12 +427,8 @@ NEXT_PAGE(level2_spare_pgt) .globl early_gdt_descr early_gdt_descr: .word GDT_ENTRIES*8-1 -#ifdef CONFIG_SMP early_gdt_descr_base: - .quad 0x0000000000000000 -#else .quad per_cpu__gdt_page -#endif ENTRY(phys_base) /* This must match the first entry in level2_kernel_pgt */ -- cgit From 947e76cdc34c782fc947313d4331380686eebbad Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Mon, 19 Jan 2009 12:21:28 +0900 Subject: x86: move stack_canary into irq_stack Impact: x86_64 percpu area layout change, irq_stack now at the beginning Now that the PDA is empty except for the stack canary, it can be removed. The irqstack is moved to the start of the per-cpu section. If the stack protector is enabled, the canary overlaps the bottom 48 bytes of the irqstack. tj: * updated subject * dropped asm relocation of irq_stack_ptr * updated comments a bit * rebased on top of stack canary changes Signed-off-by: Brian Gerst Signed-off-by: Tejun Heo --- arch/x86/include/asm/pda.h | 3 --- arch/x86/include/asm/percpu.h | 6 ------ arch/x86/include/asm/processor.h | 23 ++++++++++++++++++++++- arch/x86/include/asm/stackprotector.h | 6 +++--- arch/x86/include/asm/system.h | 4 ++-- arch/x86/kernel/asm-offsets_64.c | 4 ---- arch/x86/kernel/cpu/common.c | 7 ++++--- arch/x86/kernel/head_64.S | 13 +++++-------- arch/x86/kernel/setup_percpu.c | 34 ++++------------------------------ arch/x86/kernel/vmlinux_64.lds.S | 8 ++++++-- 10 files changed, 46 insertions(+), 62 deletions(-) diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h index b473e952439..ba46416634f 100644 --- a/arch/x86/include/asm/pda.h +++ b/arch/x86/include/asm/pda.h @@ -17,9 +17,6 @@ struct x8664_pda { unsigned long unused4; int unused5; unsigned int unused6; /* 36 was cpunumber */ - unsigned long stack_canary; /* 40 stack canary value */ - /* gcc-ABI: this canary MUST be at - offset 40!!! */ short in_bootmem; /* pda lives in bootmem */ } ____cacheline_aligned_in_smp; diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index 165d5272ece..ce980db5e59 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h @@ -133,12 +133,6 @@ do { \ /* We can use this directly for local CPU (faster). */ DECLARE_PER_CPU(unsigned long, this_cpu_off); -#ifdef CONFIG_X86_64 -extern void load_pda_offset(int cpu); -#else -static inline void load_pda_offset(int cpu) { } -#endif - #endif /* !__ASSEMBLY__ */ #ifdef CONFIG_SMP diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index f511246fa6c..48676b943b9 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -379,8 +379,29 @@ union thread_xstate { #ifdef CONFIG_X86_64 DECLARE_PER_CPU(struct orig_ist, orig_ist); -DECLARE_PER_CPU(char[IRQ_STACK_SIZE], irq_stack); +union irq_stack_union { + char irq_stack[IRQ_STACK_SIZE]; + /* + * GCC hardcodes the stack canary as %gs:40. Since the + * irq_stack is the object at %gs:0, we reserve the bottom + * 48 bytes of the irq stack for the canary. + */ + struct { + char gs_base[40]; + unsigned long stack_canary; + }; +}; + +DECLARE_PER_CPU(union irq_stack_union, irq_stack_union); DECLARE_PER_CPU(char *, irq_stack_ptr); + +static inline void load_gs_base(int cpu) +{ + /* Memory clobbers used to order pda/percpu accesses */ + mb(); + wrmsrl(MSR_GS_BASE, (unsigned long)per_cpu(irq_stack_union.gs_base, cpu)); + mb(); +} #endif extern void print_cpu_info(struct cpuinfo_x86 *); diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h index 2383e5bb475..36a700acaf2 100644 --- a/arch/x86/include/asm/stackprotector.h +++ b/arch/x86/include/asm/stackprotector.h @@ -2,7 +2,7 @@ #define _ASM_STACKPROTECTOR_H 1 #include -#include +#include /* * Initialize the stackprotector canary value. @@ -19,7 +19,7 @@ static __always_inline void boot_init_stack_canary(void) * Build time only check to make sure the stack_canary is at * offset 40 in the pda; this is a gcc ABI requirement */ - BUILD_BUG_ON(offsetof(struct x8664_pda, stack_canary) != 40); + BUILD_BUG_ON(offsetof(union irq_stack_union, stack_canary) != 40); /* * We both use the random pool and the current TSC as a source @@ -32,7 +32,7 @@ static __always_inline void boot_init_stack_canary(void) canary += tsc + (tsc << 32UL); current->stack_canary = canary; - write_pda(stack_canary, canary); + percpu_write(irq_stack_union.stack_canary, canary); } #endif diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h index b77bd8bd3cc..52eb748a68a 100644 --- a/arch/x86/include/asm/system.h +++ b/arch/x86/include/asm/system.h @@ -89,10 +89,10 @@ do { \ #ifdef CONFIG_CC_STACKPROTECTOR #define __switch_canary \ "movq %P[task_canary](%%rsi),%%r8\n\t" \ - "movq %%r8,%%gs:%P[pda_canary]\n\t" + "movq %%r8,%%gs:%P[gs_canary]\n\t" #define __switch_canary_param \ , [task_canary] "i" (offsetof(struct task_struct, stack_canary)) \ - , [pda_canary] "i" (offsetof(struct x8664_pda, stack_canary)) + , [gs_canary] "i" (offsetof(union irq_stack_union, stack_canary)) #else /* CC_STACKPROTECTOR */ #define __switch_canary #define __switch_canary_param diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index 64c834a39aa..94f9c8b39d2 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c @@ -48,10 +48,6 @@ int main(void) #endif BLANK(); #undef ENTRY -#define ENTRY(entry) DEFINE(pda_ ## entry, offsetof(struct x8664_pda, entry)) - DEFINE(pda_size, sizeof(struct x8664_pda)); - BLANK(); -#undef ENTRY #ifdef CONFIG_PARAVIRT BLANK(); OFFSET(PARAVIRT_enabled, pv_info, paravirt_enabled); diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index f83a4d6160f..098934e72a1 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -881,12 +881,13 @@ __setup("clearcpuid=", setup_disablecpuid); #ifdef CONFIG_X86_64 struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; -DEFINE_PER_CPU_PAGE_ALIGNED(char[IRQ_STACK_SIZE], irq_stack); +DEFINE_PER_CPU_FIRST(union irq_stack_union, + irq_stack_union) __aligned(PAGE_SIZE); #ifdef CONFIG_SMP DEFINE_PER_CPU(char *, irq_stack_ptr); /* will be set during per cpu init */ #else DEFINE_PER_CPU(char *, irq_stack_ptr) = - per_cpu_var(irq_stack) + IRQ_STACK_SIZE - 64; + per_cpu_var(irq_stack_union.irq_stack) + IRQ_STACK_SIZE - 64; #endif DEFINE_PER_CPU(unsigned long, kernel_stack) = @@ -960,7 +961,7 @@ void __cpuinit cpu_init(void) loadsegment(fs, 0); loadsegment(gs, 0); - load_pda_offset(cpu); + load_gs_base(cpu); #ifdef CONFIG_NUMA if (cpu != 0 && percpu_read(node_number) == 0 && diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 98ea26a2fca..a0a2b5ca9b7 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -242,13 +242,10 @@ ENTRY(secondary_startup_64) /* Set up %gs. * - * On SMP, %gs should point to the per-cpu area. For initial - * boot, make %gs point to the init data section. For a - * secondary CPU,initial_gs should be set to its pda address - * before the CPU runs this code. - * - * On UP, initial_gs points to PER_CPU_VAR(__pda) and doesn't - * change. + * The base of %gs always points to the bottom of the irqstack + * union. If the stack protector canary is enabled, it is + * located at %gs:40. Note that, on SMP, the boot cpu uses + * init data section till per cpu areas are set up. */ movl $MSR_GS_BASE,%ecx movq initial_gs(%rip),%rax @@ -281,7 +278,7 @@ ENTRY(secondary_startup_64) #ifdef CONFIG_SMP .quad __per_cpu_load #else - .quad PER_CPU_VAR(__pda) + .quad PER_CPU_VAR(irq_stack_union) #endif __FINITDATA diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index efbafbbff58..90b8e154bb5 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -77,30 +77,6 @@ static void __init setup_node_to_cpumask_map(void); static inline void setup_node_to_cpumask_map(void) { } #endif -/* - * Define load_pda_offset() and per-cpu __pda for x86_64. - * load_pda_offset() is responsible for loading the offset of pda into - * %gs. - * - * On SMP, pda offset also duals as percpu base address and thus it - * should be at the start of per-cpu area. To achieve this, it's - * preallocated in vmlinux_64.lds.S directly instead of using - * DEFINE_PER_CPU(). - */ -#ifdef CONFIG_X86_64 -void __cpuinit load_pda_offset(int cpu) -{ - /* Memory clobbers used to order pda/percpu accesses */ - mb(); - wrmsrl(MSR_GS_BASE, cpu_pda(cpu)); - mb(); -} -#ifndef CONFIG_SMP -DEFINE_PER_CPU(struct x8664_pda, __pda); -#endif -EXPORT_PER_CPU_SYMBOL(__pda); -#endif /* CONFIG_SMP && CONFIG_X86_64 */ - #ifdef CONFIG_X86_64 /* correctly size the local cpu masks */ @@ -207,15 +183,13 @@ void __init setup_per_cpu_areas(void) per_cpu(cpu_number, cpu) = cpu; #ifdef CONFIG_X86_64 per_cpu(irq_stack_ptr, cpu) = - (char *)per_cpu(irq_stack, cpu) + IRQ_STACK_SIZE - 64; + per_cpu(irq_stack_union.irq_stack, cpu) + IRQ_STACK_SIZE - 64; /* - * CPU0 modified pda in the init data area, reload pda - * offset for CPU0 and clear the area for others. + * Up to this point, CPU0 has been using .data.init + * area. Reload %gs offset for CPU0. */ if (cpu == 0) - load_pda_offset(0); - else - memset(cpu_pda(cpu), 0, sizeof(*cpu_pda(cpu))); + load_gs_base(cpu); #endif DBG("PERCPU: cpu %4d %p\n", cpu, ptr); diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S index a09abb8fb97..c9740996430 100644 --- a/arch/x86/kernel/vmlinux_64.lds.S +++ b/arch/x86/kernel/vmlinux_64.lds.S @@ -220,8 +220,7 @@ SECTIONS * so that it can be accessed as a percpu variable. */ . = ALIGN(PAGE_SIZE); - PERCPU_VADDR_PREALLOC(0, :percpu, pda_size) - per_cpu____pda = __per_cpu_start; + PERCPU_VADDR(0, :percpu) #else PERCPU(PAGE_SIZE) #endif @@ -262,3 +261,8 @@ SECTIONS */ ASSERT((_end - _text <= KERNEL_IMAGE_SIZE), "kernel image bigger than KERNEL_IMAGE_SIZE") + +#ifdef CONFIG_SMP +ASSERT((per_cpu__irq_stack_union == 0), + "irq_stack_union is not at start of per-cpu area"); +#endif -- cgit From 0d974d4592708f85044751817da4b7016e1b0602 Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Sun, 18 Jan 2009 19:52:25 -0500 Subject: x86: remove pda.h Impact: cleanup Signed-off-by: Brian Gerst --- arch/x86/include/asm/pda.h | 39 --------------------------------------- arch/x86/include/asm/pgtable_64.h | 1 - arch/x86/include/asm/smp.h | 1 - arch/x86/kernel/asm-offsets_64.c | 1 - arch/x86/kernel/cpu/common.c | 1 - arch/x86/kernel/process_64.c | 1 - arch/x86/kernel/traps.c | 1 - 7 files changed, 45 deletions(-) delete mode 100644 arch/x86/include/asm/pda.h diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h deleted file mode 100644 index ba46416634f..00000000000 --- a/arch/x86/include/asm/pda.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _ASM_X86_PDA_H -#define _ASM_X86_PDA_H - -#ifndef __ASSEMBLY__ -#include -#include -#include -#include -#include -#include - -/* Per processor datastructure. %gs points to it while the kernel runs */ -struct x8664_pda { - unsigned long unused1; - unsigned long unused2; - unsigned long unused3; - unsigned long unused4; - int unused5; - unsigned int unused6; /* 36 was cpunumber */ - short in_bootmem; /* pda lives in bootmem */ -} ____cacheline_aligned_in_smp; - -DECLARE_PER_CPU(struct x8664_pda, __pda); - -#define cpu_pda(cpu) (&per_cpu(__pda, cpu)) - -#define read_pda(field) percpu_read(__pda.field) -#define write_pda(field, val) percpu_write(__pda.field, val) -#define add_pda(field, val) percpu_add(__pda.field, val) -#define sub_pda(field, val) percpu_sub(__pda.field, val) -#define or_pda(field, val) percpu_or(__pda.field, val) - -/* This is not atomic against other CPUs -- CPU preemption needs to be off */ -#define test_and_clear_bit_pda(bit, field) \ - x86_test_and_clear_bit_percpu(bit, __pda.field) - -#endif - -#endif /* _ASM_X86_PDA_H */ diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h index ba09289acca..1df9637dfda 100644 --- a/arch/x86/include/asm/pgtable_64.h +++ b/arch/x86/include/asm/pgtable_64.h @@ -11,7 +11,6 @@ #include #include #include -#include extern pud_t level3_kernel_pgt[512]; extern pud_t level3_ident_pgt[512]; diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index 68636e767a9..45ef8a1b9d7 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -15,7 +15,6 @@ # include # endif #endif -#include #include #include diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index 94f9c8b39d2..8793ab33e2c 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 098934e72a1..3887fcf6e51 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -30,7 +30,6 @@ #include #endif -#include #include #include #include diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 088bc9a0f82..c422eebb0c5 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -47,7 +47,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 98c2d055284..ed5aee5f3fc 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -59,7 +59,6 @@ #ifdef CONFIG_X86_64 #include #include -#include #else #include #include -- cgit From 6b7c38d55587f43bcd2cbce3a98b1c0826982090 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 19 Jan 2009 12:21:28 +0900 Subject: linker script: kill PERCPU_VADDR_PREALLOC() Impact: cleanup With .data.percpu.first in place, PERCPU_VADDR_PREALLOC() is no longer necessary. Kill it. Signed-off-by: Tejun Heo --- include/asm-generic/vmlinux.lds.h | 45 +++++++-------------------------------- 1 file changed, 8 insertions(+), 37 deletions(-) diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 32bbf50d305..53e21f36a80 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -430,22 +430,10 @@ *(.initcall7.init) \ *(.initcall7s.init) -#define PERCPU_PROLOG(vaddr) \ - VMLINUX_SYMBOL(__per_cpu_load) = .; \ - .data.percpu vaddr : AT(VMLINUX_SYMBOL(__per_cpu_load) \ - - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__per_cpu_start) = .; - -#define PERCPU_EPILOG(phdr) \ - VMLINUX_SYMBOL(__per_cpu_end) = .; \ - } phdr \ - . = VMLINUX_SYMBOL(__per_cpu_load) + SIZEOF(.data.percpu); - /** - * PERCPU_VADDR_PREALLOC - define output section for percpu area with prealloc + * PERCPU_VADDR - define output section for percpu area * @vaddr: explicit base address (optional) * @phdr: destination PHDR (optional) - * @prealloc: the size of prealloc area * * Macro which expands to output section for percpu area. If @vaddr * is not blank, it specifies explicit base address and all percpu @@ -457,40 +445,23 @@ * section in the linker script will go there too. @phdr should have * a leading colon. * - * If @prealloc is non-zero, the specified number of bytes will be - * reserved at the start of percpu area. As the prealloc area is - * likely to break alignment, this macro puts areas in increasing - * alignment order. - * * This macro defines three symbols, __per_cpu_load, __per_cpu_start * and __per_cpu_end. The first one is the vaddr of loaded percpu * init data. __per_cpu_start equals @vaddr and __per_cpu_end is the * end offset. */ -#define PERCPU_VADDR_PREALLOC(vaddr, segment, prealloc) \ - PERCPU_PROLOG(vaddr) \ - . += prealloc; \ - *(.data.percpu) \ - *(.data.percpu.shared_aligned) \ - *(.data.percpu.page_aligned) \ - PERCPU_EPILOG(segment) - -/** - * PERCPU_VADDR - define output section for percpu area - * @vaddr: explicit base address (optional) - * @phdr: destination PHDR (optional) - * - * Macro which expands to output section for percpu area. Mostly - * identical to PERCPU_VADDR_PREALLOC(@vaddr, @phdr, 0) other than - * using slighly different layout. - */ #define PERCPU_VADDR(vaddr, phdr) \ - PERCPU_PROLOG(vaddr) \ + VMLINUX_SYMBOL(__per_cpu_load) = .; \ + .data.percpu vaddr : AT(VMLINUX_SYMBOL(__per_cpu_load) \ + - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__per_cpu_start) = .; \ *(.data.percpu.first) \ *(.data.percpu.page_aligned) \ *(.data.percpu) \ *(.data.percpu.shared_aligned) \ - PERCPU_EPILOG(phdr) + VMLINUX_SYMBOL(__per_cpu_end) = .; \ + } phdr \ + . = VMLINUX_SYMBOL(__per_cpu_load) + SIZEOF(.data.percpu); /** * PERCPU - define output section for percpu area, simple version -- cgit From 67605d6812691bbd2158d2f60259e0407611bc1b Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Mon, 19 Jan 2009 20:21:49 -0800 Subject: [CVE-2009-0029] sparc: Enable syscall wrappers for 64-bit sparc64 needs sign-extended function parameters. We have to enable the system call wrappers. Signed-off-by: Christian Borntraeger Signed-off-by: David S. Miller --- arch/sparc/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index de58c02633b..c3ea215334f 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -36,6 +36,7 @@ config SPARC64 select HAVE_KRETPROBES select HAVE_KPROBES select HAVE_LMB + select HAVE_SYSCALL_WRAPPERS select USE_GENERIC_SMP_HELPERS if SMP select RTC_DRV_CMOS select RTC_DRV_BQ4802 -- cgit From e42650196df34789c825fa83f8bb37a5d5e52c14 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 19 Jan 2009 21:11:27 -0800 Subject: sparc64: Annotate sparc64 specific syscalls with SYSCALL_DEFINEx() Signed-off-by: David S. Miller --- arch/sparc/kernel/sys_sparc_64.c | 48 +++++++++++++++++++--------------------- arch/sparc/kernel/syscalls.S | 2 +- arch/sparc/kernel/systbls.h | 3 --- arch/sparc/kernel/systbls_64.S | 16 +++++++------- 4 files changed, 32 insertions(+), 37 deletions(-) diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index 09058fc39e7..e2d102447a4 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c @@ -399,7 +399,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm) } } -asmlinkage unsigned long sparc_brk(unsigned long brk) +SYSCALL_DEFINE1(sparc_brk, unsigned long, brk) { /* People could try to be nasty and use ta 0x6d in 32bit programs */ if (test_thread_flag(TIF_32BIT) && brk >= STACK_TOP32) @@ -415,7 +415,7 @@ asmlinkage unsigned long sparc_brk(unsigned long brk) * sys_pipe() is the normal C calling standard for creating * a pipe. It's not the way unix traditionally does this, though. */ -asmlinkage long sparc_pipe(struct pt_regs *regs) +SYSCALL_DEFINE1(sparc_pipe_real, struct pt_regs *, regs) { int fd[2]; int error; @@ -435,8 +435,8 @@ out: * This is really horribly ugly. */ -asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second, - unsigned long third, void __user *ptr, long fifth) +SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, + unsigned long, third, void __user *, ptr, long, fifth) { long err; @@ -519,7 +519,7 @@ out: return err; } -asmlinkage long sparc64_newuname(struct new_utsname __user *name) +SYSCALL_DEFINE1(sparc64_newuname, struct new_utsname __user *, name) { int ret = sys_newuname(name); @@ -530,7 +530,7 @@ asmlinkage long sparc64_newuname(struct new_utsname __user *name) return ret; } -asmlinkage long sparc64_personality(unsigned long personality) +SYSCALL_DEFINE1(sparc64_personality, unsigned long, personality) { int ret; @@ -564,9 +564,9 @@ int sparc_mmap_check(unsigned long addr, unsigned long len) } /* Linux version of mmap */ -asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, - unsigned long prot, unsigned long flags, unsigned long fd, - unsigned long off) +SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, + unsigned long, prot, unsigned long, flags, unsigned long, fd, + unsigned long, off) { struct file * file = NULL; unsigned long retval = -EBADF; @@ -589,7 +589,7 @@ out: return retval; } -asmlinkage long sys64_munmap(unsigned long addr, size_t len) +SYSCALL_DEFINE2(64_munmap, unsigned long, addr, size_t, len) { long ret; @@ -606,9 +606,9 @@ extern unsigned long do_mremap(unsigned long addr, unsigned long old_len, unsigned long new_len, unsigned long flags, unsigned long new_addr); -asmlinkage unsigned long sys64_mremap(unsigned long addr, - unsigned long old_len, unsigned long new_len, - unsigned long flags, unsigned long new_addr) +SYSCALL_DEFINE5(64_mremap, unsigned long, addr, unsigned long, old_len, + unsigned long, new_len, unsigned long, flags, + unsigned long, new_addr) { unsigned long ret = -EINVAL; @@ -671,7 +671,7 @@ asmlinkage void sparc_breakpoint(struct pt_regs *regs) extern void check_pending(int signum); -asmlinkage long sys_getdomainname(char __user *name, int len) +SYSCALL_DEFINE2(getdomainname, char __user *, name, int, len) { int nlen, err; @@ -694,11 +694,10 @@ out: return err; } -asmlinkage long sys_utrap_install(utrap_entry_t type, - utrap_handler_t new_p, - utrap_handler_t new_d, - utrap_handler_t __user *old_p, - utrap_handler_t __user *old_d) +SYSCALL_DEFINE5(utrap_install, utrap_entry_t, type, + utrap_handler_t, new_p, utrap_handler_t, new_d, + utrap_handler_t __user *, old_p, + utrap_handler_t __user *, old_d) { if (type < UT_INSTRUCTION_EXCEPTION || type > UT_TRAP_INSTRUCTION_31) return -EINVAL; @@ -764,11 +763,9 @@ asmlinkage long sparc_memory_ordering(unsigned long model, return 0; } -asmlinkage long sys_rt_sigaction(int sig, - const struct sigaction __user *act, - struct sigaction __user *oact, - void __user *restorer, - size_t sigsetsize) +SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act, + struct sigaction __user *, oact, void __user *, restorer, + size_t, sigsetsize) { struct k_sigaction new_ka, old_ka; int ret; @@ -808,7 +805,8 @@ asmlinkage void update_perfctrs(void) reset_pic(); } -asmlinkage long sys_perfctr(int opcode, unsigned long arg0, unsigned long arg1, unsigned long arg2) +SYSCALL_DEFINE4(perfctr, int, opcode, unsigned long, arg0, + unsigned long, arg1, unsigned long, arg2) { int err = 0; diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S index 87f5a3b8a25..d150c2aa98d 100644 --- a/arch/sparc/kernel/syscalls.S +++ b/arch/sparc/kernel/syscalls.S @@ -21,7 +21,7 @@ execve_merge: .align 32 sys_sparc_pipe: - ba,pt %xcc, sparc_pipe + ba,pt %xcc, sys_sparc_pipe_real add %sp, PTREGS_OFF, %o0 sys_nis_syscall: ba,pt %xcc, c_sys_nis_syscall diff --git a/arch/sparc/kernel/systbls.h b/arch/sparc/kernel/systbls.h index bc9f5dac406..15c2d752b2b 100644 --- a/arch/sparc/kernel/systbls.h +++ b/arch/sparc/kernel/systbls.h @@ -16,9 +16,6 @@ extern asmlinkage long sys_ipc(unsigned int call, int first, void __user *ptr, long fifth); extern asmlinkage long sparc64_newuname(struct new_utsname __user *name); extern asmlinkage long sparc64_personality(unsigned long personality); -extern asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, - unsigned long prot, unsigned long flags, - unsigned long fd, unsigned long off); extern asmlinkage long sys64_munmap(unsigned long addr, size_t len); extern asmlinkage unsigned long sys64_mremap(unsigned long addr, unsigned long old_len, diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index e6007bb3704..f93c42a2b52 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S @@ -21,7 +21,7 @@ sys_call_table32: /*0*/ .word sys_restart_syscall, sys32_exit, sys_fork, sys_read, sys_write /*5*/ .word sys32_open, sys_close, sys32_wait4, sys32_creat, sys_link /*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys32_mknod -/*15*/ .word sys_chmod, sys_lchown16, sparc_brk, sys32_perfctr, sys32_lseek +/*15*/ .word sys_chmod, sys_lchown16, sys_sparc_brk, sys32_perfctr, sys32_lseek /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 /*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys_pause /*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice @@ -55,8 +55,8 @@ sys_call_table32: /*170*/ .word sys32_lsetxattr, sys32_fsetxattr, sys_getxattr, sys_lgetxattr, compat_sys_getdents .word sys_setsid, sys_fchdir, sys32_fgetxattr, sys_listxattr, sys_llistxattr /*180*/ .word sys32_flistxattr, sys_removexattr, sys_lremovexattr, compat_sys_sigpending, sys_ni_syscall - .word sys32_setpgid, sys32_fremovexattr, sys32_tkill, sys32_exit_group, sparc64_newuname -/*190*/ .word sys32_init_module, sparc64_personality, sys_remap_file_pages, sys32_epoll_create, sys32_epoll_ctl + .word sys32_setpgid, sys32_fremovexattr, sys32_tkill, sys32_exit_group, sys_sparc64_newuname +/*190*/ .word sys32_init_module, sys_sparc64_personality, sys_remap_file_pages, sys32_epoll_create, sys32_epoll_ctl .word sys32_epoll_wait, sys32_ioprio_set, sys_getppid, sys32_sigaction, sys_sgetmask /*200*/ .word sys32_ssetmask, sys_sigsuspend, compat_sys_newlstat, sys_uselib, compat_sys_old_readdir .word sys32_readahead, sys32_socketcall, sys32_syslog, sys32_lookup_dcookie, sys32_fadvise64 @@ -95,7 +95,7 @@ sys_call_table: /*0*/ .word sys_restart_syscall, sparc_exit, sys_fork, sys_read, sys_write /*5*/ .word sys_open, sys_close, sys_wait4, sys_creat, sys_link /*10*/ .word sys_unlink, sys_nis_syscall, sys_chdir, sys_chown, sys_mknod -/*15*/ .word sys_chmod, sys_lchown, sparc_brk, sys_perfctr, sys_lseek +/*15*/ .word sys_chmod, sys_lchown, sys_sparc_brk, sys_perfctr, sys_lseek /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid, sys_getuid /*25*/ .word sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_nis_syscall /*30*/ .word sys_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice @@ -106,7 +106,7 @@ sys_call_table: .word sys_reboot, sys_nis_syscall, sys_symlink, sys_readlink, sys_execve /*60*/ .word sys_umask, sys_chroot, sys_newfstat, sys_fstat64, sys_getpagesize .word sys_msync, sys_vfork, sys_pread64, sys_pwrite64, sys_nis_syscall -/*70*/ .word sys_nis_syscall, sys_mmap, sys_nis_syscall, sys64_munmap, sys_mprotect +/*70*/ .word sys_nis_syscall, sys_mmap, sys_nis_syscall, sys_64_munmap, sys_mprotect .word sys_madvise, sys_vhangup, sys_nis_syscall, sys_mincore, sys_getgroups /*80*/ .word sys_setgroups, sys_getpgrp, sys_nis_syscall, sys_setitimer, sys_nis_syscall .word sys_swapon, sys_getitimer, sys_nis_syscall, sys_sethostname, sys_nis_syscall @@ -129,8 +129,8 @@ sys_call_table: /*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr /*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_ni_syscall - .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sparc64_newuname -/*190*/ .word sys_init_module, sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl + .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_sparc64_newuname +/*190*/ .word sys_init_module, sys_sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl .word sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_nis_syscall, sys_sgetmask /*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall .word sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64 @@ -142,7 +142,7 @@ sys_call_table: .word sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall /*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler .word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep -/*250*/ .word sys64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl +/*250*/ .word sys_64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl .word sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep /*260*/ .word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy -- cgit From fcd26f7ae2ea5889134e8b3d60a42ce8b993c95f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 19 Jan 2009 22:44:04 -0800 Subject: sparc64: Fix DAX handling via userspace access from kernel. If we do a userspace access from kernel mode, and get a data access exception, we need to check the exception table just like a normal fault does. The spitfire DAX handler was doing this, but such logic was missing from the sun4v DAX code. Reported-by: Dennis Gilmore Signed-off-by: David S. Miller --- arch/sparc/kernel/traps_64.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index c2d153d4658..d809c4ebb48 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c @@ -1,6 +1,6 @@ /* arch/sparc64/kernel/traps.c * - * Copyright (C) 1995,1997,2008 David S. Miller (davem@davemloft.net) + * Copyright (C) 1995,1997,2008,2009 David S. Miller (davem@davemloft.net) * Copyright (C) 1997,1999,2000 Jakub Jelinek (jakub@redhat.com) */ @@ -314,6 +314,21 @@ void sun4v_data_access_exception(struct pt_regs *regs, unsigned long addr, unsig return; if (regs->tstate & TSTATE_PRIV) { + /* Test if this comes from uaccess places. */ + const struct exception_table_entry *entry; + + entry = search_exception_tables(regs->tpc); + if (entry) { + /* Ouch, somebody is trying VM hole tricks on us... */ +#ifdef DEBUG_EXCEPTIONS + printk("Exception: PC<%016lx> faddr\n", regs->tpc); + printk("EX_TABLE: insn<%016lx> fixup<%016lx>\n", + regs->tpc, entry->fixup); +#endif + regs->tpc = entry->fixup; + regs->tnpc = regs->tpc + 4; + return; + } printk("sun4v_data_access_exception: ADDR[%016lx] " "CTX[%04x] TYPE[%04x], going.\n", addr, ctx, type); -- cgit From a50412e3f8ce95d7ed558370d7dde5171fd04283 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Tue, 6 Jan 2009 19:54:02 +0200 Subject: UBIFS: do not treat all data as short term UBIFS wrongly tells UBI that all data is short term. Use proper hints instead. Thanks to Xiaochuan-Xu for noticing this. Signed-off-by: Artem Bityutskiy --- fs/ubifs/journal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c index 9b7c54e0cd2..a11ca0958a2 100644 --- a/fs/ubifs/journal.c +++ b/fs/ubifs/journal.c @@ -208,7 +208,7 @@ again: offs = 0; out: - err = ubifs_wbuf_seek_nolock(wbuf, lnum, offs, UBI_SHORTTERM); + err = ubifs_wbuf_seek_nolock(wbuf, lnum, offs, wbuf->dtype); if (err) goto out_unlock; -- cgit From 7078202e55b565582fcbd831a8dd3069bdc72610 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Mon, 19 Jan 2009 19:57:27 +0200 Subject: UBIFS: document dark_wm and dead_wm better Just add more commentaries. Also some commentary fixes for lprops flags. Signed-off-by: Artem Bityutskiy --- fs/ubifs/gc.c | 20 ++++++++++++++++++++ fs/ubifs/super.c | 11 ++--------- fs/ubifs/ubifs.h | 4 ++-- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c index 9832f9abe28..b2e5f113337 100644 --- a/fs/ubifs/gc.c +++ b/fs/ubifs/gc.c @@ -31,6 +31,26 @@ * to be reused. Garbage collection will cause the number of dirty index nodes * to grow, however sufficient space is reserved for the index to ensure the * commit will never run out of space. + * + * Notes about dead watermark. At current UBIFS implementation we assume that + * LEBs which have less than @c->dead_wm bytes of free + dirty space are full + * and not worth garbage-collecting. The dead watermark is one min. I/O unit + * size, or min. UBIFS node size, depending on what is greater. Indeed, UBIFS + * Garbage Collector has to synchronize the GC head's write buffer before + * returning, so this is about wasting one min. I/O unit. However, UBIFS GC can + * actually reclaim even very small pieces of dirty space by garbage collecting + * enough dirty LEBs, but we do not bother doing this at this implementation. + * + * Notes about dark watermark. The results of GC work depends on how big are + * the UBIFS nodes GC deals with. Large nodes make GC waste more space. Indeed, + * if GC move data from LEB A to LEB B and nodes in LEB A are large, GC would + * have to waste large pieces of free space at the end of LEB B, because nodes + * from LEB A would not fit. And the worst situation is when all nodes are of + * maximum size. So dark watermark is the amount of free + dirty space in LEB + * which are guaranteed to be reclaimable. If LEB has less space, the GC migh + * be unable to reclaim it. So, LEBs with free + dirty greater than dark + * watermark are "good" LEBs from GC's point of few. The other LEBs are not so + * good, and GC takes extra care when moving them. */ #include diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 53811e567a6..da99da098ef 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -573,15 +573,8 @@ static int init_constants_early(struct ubifs_info *c) c->ranges[UBIFS_IDX_NODE].max_len = INT_MAX; /* - * Initialize dead and dark LEB space watermarks. - * - * Dead space is the space which cannot be used. Its watermark is - * equivalent to min. I/O unit or minimum node size if it is greater - * then min. I/O unit. - * - * Dark space is the space which might be used, or might not, depending - * on which node should be written to the LEB. Its watermark is - * equivalent to maximum UBIFS node size. + * Initialize dead and dark LEB space watermarks. See gc.c for comments + * about these values. */ c->dead_wm = ALIGN(MIN_WRITE_SZ, c->min_io_size); c->dark_wm = ALIGN(UBIFS_MAX_NODE_SZ, c->min_io_size); diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 0881897a420..2e78d6ac007 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h @@ -426,9 +426,9 @@ struct ubifs_unclean_leb { * LEB properties flags. * * LPROPS_UNCAT: not categorized - * LPROPS_DIRTY: dirty > 0, not index + * LPROPS_DIRTY: dirty > free, dirty >= @c->dead_wm, not index * LPROPS_DIRTY_IDX: dirty + free > @c->min_idx_node_sze and index - * LPROPS_FREE: free > 0, not empty, not index + * LPROPS_FREE: free > 0, dirty < @c->dead_wm, not empty, not index * LPROPS_HEAP_CNT: number of heaps used for storing categorized LEBs * LPROPS_EMPTY: LEB is empty, not taken * LPROPS_FREEABLE: free + dirty == leb_size, not index, not taken -- cgit From 082605de5f82eb692cc90f7fda071cc01bb5ac34 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 19 Jan 2009 14:32:51 -0500 Subject: ring-buffer: fix alignment problem Impact: fix to allow some archs to use the ring buffer Commits in the ring buffer are checked by pointer arithmetic. If the calculation is incorrect, then the commits will never take place and the buffer will simply fill up and report an error. Each page in the ring buffer has a small header: struct buffer_data_page { u64 time_stamp; local_t commit; unsigned char data[]; }; Unfortuntely, some of the calculations used sizeof(struct buffer_data_page) to know the size of the header. But this is incorrect on some archs, where sizeof(struct buffer_data_page) does not equal offsetof(struct buffer_data_page, data), and on those archs, the commits are never processed. This patch replaces the sizeof with offsetof. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar --- kernel/trace/ring_buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 8b0daf0662e..1d6526361d0 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -246,7 +246,7 @@ static inline int test_time_stamp(u64 delta) return 0; } -#define BUF_PAGE_SIZE (PAGE_SIZE - sizeof(struct buffer_data_page)) +#define BUF_PAGE_SIZE (PAGE_SIZE - offsetof(struct buffer_data_page, data)) /* * head_page == tail_page && head == tail then buffer is empty. -- cgit From 92181f190b649f7ef2b79cbf5c00f26ccc66da2a Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Tue, 20 Jan 2009 04:24:26 +0100 Subject: x86: optimise x86's do_page_fault (C entry point for the page fault path) Impact: cleanup, restructure code to improve assembly gcc isn't _all_ that smart about spilling registers to stack or reusing stack slots, even with branch annotations. do_page_fault contained a lot of functionality, so split unlikely paths into their own functions, and mark them as noinline just to be sure. I consider this actually to be somewhat of a cleanup too: the main function now contains about half the number of lines so the normal path is easier to read, while the error cases are also nicely split away. Also, ensure the order of arguments to functions is always the same: regs, addr, error_code. This can reduce code size a tiny bit, and just looks neater too. And add a couple of branch annotations. Before: do_page_fault: subq $360, %rsp #, After: do_page_fault: subq $56, %rsp #, bloat-o-meter: add/remove: 8/0 grow/shrink: 0/1 up/down: 2222/-1680 (542) function old new delta __bad_area_nosemaphore - 506 +506 no_context - 474 +474 vmalloc_fault - 424 +424 spurious_fault - 358 +358 mm_fault_error - 272 +272 bad_area_access_error - 89 +89 bad_area - 89 +89 bad_area_nosemaphore - 10 +10 do_page_fault 2464 784 -1680 Yes, the total size increases by 542 bytes, due to the extra function calls. But these will very rarely be called (except for vmalloc_fault) in a normal workload. Importantly, do_page_fault is less than 1/3rd it's original size, and touches far less stack. Existing gotos and branch hints did move a lot of the infrequently used text out of the fastpath, but that's even further improved after this patch. Signed-off-by: Nick Piggin Acked-by: Linus Torvalds Signed-off-by: Ingo Molnar --- arch/x86/mm/fault.c | 438 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 256 insertions(+), 182 deletions(-) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 90dfae511a4..033292dc9e2 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -91,8 +91,8 @@ static inline int notify_page_fault(struct pt_regs *regs) * * Opcode checker based on code by Richard Brunner */ -static int is_prefetch(struct pt_regs *regs, unsigned long addr, - unsigned long error_code) +static int is_prefetch(struct pt_regs *regs, unsigned long error_code, + unsigned long addr) { unsigned char *instr; int scan_more = 1; @@ -409,15 +409,15 @@ static void show_fault_oops(struct pt_regs *regs, unsigned long error_code, } #ifdef CONFIG_X86_64 -static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs, - unsigned long error_code) +static noinline void pgtable_bad(struct pt_regs *regs, + unsigned long error_code, unsigned long address) { unsigned long flags = oops_begin(); int sig = SIGKILL; - struct task_struct *tsk; + struct task_struct *tsk = current; printk(KERN_ALERT "%s: Corrupted page table at address %lx\n", - current->comm, address); + tsk->comm, address); dump_pagetable(address); tsk = current; tsk->thread.cr2 = address; @@ -429,6 +429,190 @@ static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs, } #endif +static noinline void no_context(struct pt_regs *regs, + unsigned long error_code, unsigned long address) +{ + struct task_struct *tsk = current; +#ifdef CONFIG_X86_64 + unsigned long flags; + int sig; +#endif + + /* Are we prepared to handle this kernel fault? */ + if (fixup_exception(regs)) + return; + + /* + * X86_32 + * Valid to do another page fault here, because if this fault + * had been triggered by is_prefetch fixup_exception would have + * handled it. + * + * X86_64 + * Hall of shame of CPU/BIOS bugs. + */ + if (is_prefetch(regs, error_code, address)) + return; + + if (is_errata93(regs, address)) + return; + + /* + * Oops. The kernel tried to access some bad page. We'll have to + * terminate things with extreme prejudice. + */ +#ifdef CONFIG_X86_32 + bust_spinlocks(1); +#else + flags = oops_begin(); +#endif + + show_fault_oops(regs, error_code, address); + + tsk->thread.cr2 = address; + tsk->thread.trap_no = 14; + tsk->thread.error_code = error_code; + +#ifdef CONFIG_X86_32 + die("Oops", regs, error_code); + bust_spinlocks(0); + do_exit(SIGKILL); +#else + sig = SIGKILL; + if (__die("Oops", regs, error_code)) + sig = 0; + /* Executive summary in case the body of the oops scrolled away */ + printk(KERN_EMERG "CR2: %016lx\n", address); + oops_end(flags, regs, sig); +#endif +} + +static void __bad_area_nosemaphore(struct pt_regs *regs, + unsigned long error_code, unsigned long address, + int si_code) +{ + struct task_struct *tsk = current; + + /* User mode accesses just cause a SIGSEGV */ + if (error_code & PF_USER) { + /* + * It's possible to have interrupts off here. + */ + local_irq_enable(); + + /* + * Valid to do another page fault here because this one came + * from user space. + */ + if (is_prefetch(regs, error_code, address)) + return; + + if (is_errata100(regs, address)) + return; + + if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && + printk_ratelimit()) { + printk( + "%s%s[%d]: segfault at %lx ip %p sp %p error %lx", + task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, + tsk->comm, task_pid_nr(tsk), address, + (void *) regs->ip, (void *) regs->sp, error_code); + print_vma_addr(" in ", regs->ip); + printk("\n"); + } + + tsk->thread.cr2 = address; + /* Kernel addresses are always protection faults */ + tsk->thread.error_code = error_code | (address >= TASK_SIZE); + tsk->thread.trap_no = 14; + force_sig_info_fault(SIGSEGV, si_code, address, tsk); + return; + } + + if (is_f00f_bug(regs, address)) + return; + + no_context(regs, error_code, address); +} + +static noinline void bad_area_nosemaphore(struct pt_regs *regs, + unsigned long error_code, unsigned long address) +{ + __bad_area_nosemaphore(regs, error_code, address, SEGV_MAPERR); +} + +static void __bad_area(struct pt_regs *regs, + unsigned long error_code, unsigned long address, + int si_code) +{ + struct mm_struct *mm = current->mm; + + /* + * Something tried to access memory that isn't in our memory map.. + * Fix it, but check if it's kernel or user first.. + */ + up_read(&mm->mmap_sem); + + __bad_area_nosemaphore(regs, error_code, address, si_code); +} + +static noinline void bad_area(struct pt_regs *regs, + unsigned long error_code, unsigned long address) +{ + __bad_area(regs, error_code, address, SEGV_MAPERR); +} + +static noinline void bad_area_access_error(struct pt_regs *regs, + unsigned long error_code, unsigned long address) +{ + __bad_area(regs, error_code, address, SEGV_ACCERR); +} + +/* TODO: fixup for "mm-invoke-oom-killer-from-page-fault.patch" */ +static void out_of_memory(struct pt_regs *regs, + unsigned long error_code, unsigned long address) +{ + /* + * We ran out of memory, call the OOM killer, and return the userspace + * (which will retry the fault, or kill us if we got oom-killed). + */ + up_read(¤t->mm->mmap_sem); + pagefault_out_of_memory(); +} + +static void do_sigbus(struct pt_regs *regs, + unsigned long error_code, unsigned long address) +{ + struct task_struct *tsk = current; + struct mm_struct *mm = tsk->mm; + + up_read(&mm->mmap_sem); + + /* Kernel mode? Handle exceptions or die */ + if (!(error_code & PF_USER)) + no_context(regs, error_code, address); +#ifdef CONFIG_X86_32 + /* User space => ok to do another page fault */ + if (is_prefetch(regs, error_code, address)) + return; +#endif + tsk->thread.cr2 = address; + tsk->thread.error_code = error_code; + tsk->thread.trap_no = 14; + force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk); +} + +static noinline void mm_fault_error(struct pt_regs *regs, + unsigned long error_code, unsigned long address, unsigned int fault) +{ + if (fault & VM_FAULT_OOM) + out_of_memory(regs, error_code, address); + else if (fault & VM_FAULT_SIGBUS) + do_sigbus(regs, error_code, address); + else + BUG(); +} + static int spurious_fault_check(unsigned long error_code, pte_t *pte) { if ((error_code & PF_WRITE) && !pte_write(*pte)) @@ -448,8 +632,8 @@ static int spurious_fault_check(unsigned long error_code, pte_t *pte) * There are no security implications to leaving a stale TLB when * increasing the permissions on a page. */ -static int spurious_fault(unsigned long address, - unsigned long error_code) +static noinline int spurious_fault(unsigned long error_code, + unsigned long address) { pgd_t *pgd; pud_t *pud; @@ -494,7 +678,7 @@ static int spurious_fault(unsigned long address, * * This assumes no large pages in there. */ -static int vmalloc_fault(unsigned long address) +static noinline int vmalloc_fault(unsigned long address) { #ifdef CONFIG_X86_32 unsigned long pgd_paddr; @@ -573,6 +757,25 @@ static int vmalloc_fault(unsigned long address) int show_unhandled_signals = 1; +static inline int access_error(unsigned long error_code, int write, + struct vm_area_struct *vma) +{ + if (write) { + /* write, present and write, not present */ + if (unlikely(!(vma->vm_flags & VM_WRITE))) + return 1; + } else if (unlikely(error_code & PF_PROT)) { + /* read, present */ + return 1; + } else { + /* read, not present */ + if (unlikely(!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))) + return 1; + } + + return 0; +} + /* * This routine handles page faults. It determines the address, * and the problem, and then passes it off to one of the appropriate @@ -583,16 +786,12 @@ asmlinkage #endif void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) { + unsigned long address; struct task_struct *tsk; struct mm_struct *mm; struct vm_area_struct *vma; - unsigned long address; - int write, si_code; + int write; int fault; -#ifdef CONFIG_X86_64 - unsigned long flags; - int sig; -#endif tsk = current; mm = tsk->mm; @@ -601,9 +800,7 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) /* get the address */ address = read_cr2(); - si_code = SEGV_MAPERR; - - if (notify_page_fault(regs)) + if (unlikely(notify_page_fault(regs))) return; if (unlikely(kmmio_fault(regs, address))) return; @@ -631,17 +828,17 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) return; /* Can handle a stale RO->RW TLB */ - if (spurious_fault(address, error_code)) + if (spurious_fault(error_code, address)) return; /* * Don't take the mm semaphore here. If we fixup a prefetch * fault we could otherwise deadlock. */ - goto bad_area_nosemaphore; + bad_area_nosemaphore(regs, error_code, address); + return; } - /* * It's safe to allow irq's after cr2 has been saved and the * vmalloc fault has been handled. @@ -657,15 +854,17 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) #ifdef CONFIG_X86_64 if (unlikely(error_code & PF_RSVD)) - pgtable_bad(address, regs, error_code); + pgtable_bad(regs, error_code, address); #endif /* * If we're in an interrupt, have no user context or are running in an * atomic region then we must not take the fault. */ - if (unlikely(in_atomic() || !mm)) - goto bad_area_nosemaphore; + if (unlikely(in_atomic() || !mm)) { + bad_area_nosemaphore(regs, error_code, address); + return; + } /* * When running in the kernel we expect faults to occur only to @@ -683,20 +882,26 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) * source. If this is invalid we can skip the address space check, * thus avoiding the deadlock. */ - if (!down_read_trylock(&mm->mmap_sem)) { + if (unlikely(!down_read_trylock(&mm->mmap_sem))) { if ((error_code & PF_USER) == 0 && - !search_exception_tables(regs->ip)) - goto bad_area_nosemaphore; + !search_exception_tables(regs->ip)) { + bad_area_nosemaphore(regs, error_code, address); + return; + } down_read(&mm->mmap_sem); } vma = find_vma(mm, address); - if (!vma) - goto bad_area; - if (vma->vm_start <= address) + if (unlikely(!vma)) { + bad_area(regs, error_code, address); + return; + } + if (likely(vma->vm_start <= address)) goto good_area; - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto bad_area; + if (unlikely(!(vma->vm_flags & VM_GROWSDOWN))) { + bad_area(regs, error_code, address); + return; + } if (error_code & PF_USER) { /* * Accessing the stack below %sp is always a bug. @@ -704,31 +909,25 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) * and pusha to work. ("enter $65535,$31" pushes * 32 pointers and then decrements %sp by 65535.) */ - if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp) - goto bad_area; + if (unlikely(address + 65536 + 32 * sizeof(unsigned long) < regs->sp)) { + bad_area(regs, error_code, address); + return; + } } - if (expand_stack(vma, address)) - goto bad_area; -/* - * Ok, we have a good vm_area for this memory access, so - * we can handle it.. - */ + if (unlikely(expand_stack(vma, address))) { + bad_area(regs, error_code, address); + return; + } + + /* + * Ok, we have a good vm_area for this memory access, so + * we can handle it.. + */ good_area: - si_code = SEGV_ACCERR; - write = 0; - switch (error_code & (PF_PROT|PF_WRITE)) { - default: /* 3: write, present */ - /* fall through */ - case PF_WRITE: /* write, not present */ - if (!(vma->vm_flags & VM_WRITE)) - goto bad_area; - write++; - break; - case PF_PROT: /* read, present */ - goto bad_area; - case 0: /* read, not present */ - if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) - goto bad_area; + write = error_code & PF_WRITE; + if (unlikely(access_error(error_code, write, vma))) { + bad_area_access_error(regs, error_code, address); + return; } /* @@ -738,11 +937,8 @@ good_area: */ fault = handle_mm_fault(mm, vma, address, write); if (unlikely(fault & VM_FAULT_ERROR)) { - if (fault & VM_FAULT_OOM) - goto out_of_memory; - else if (fault & VM_FAULT_SIGBUS) - goto do_sigbus; - BUG(); + mm_fault_error(regs, error_code, address, fault); + return; } if (fault & VM_FAULT_MAJOR) tsk->maj_flt++; @@ -760,128 +956,6 @@ good_area: } #endif up_read(&mm->mmap_sem); - return; - -/* - * Something tried to access memory that isn't in our memory map.. - * Fix it, but check if it's kernel or user first.. - */ -bad_area: - up_read(&mm->mmap_sem); - -bad_area_nosemaphore: - /* User mode accesses just cause a SIGSEGV */ - if (error_code & PF_USER) { - /* - * It's possible to have interrupts off here. - */ - local_irq_enable(); - - /* - * Valid to do another page fault here because this one came - * from user space. - */ - if (is_prefetch(regs, address, error_code)) - return; - - if (is_errata100(regs, address)) - return; - - if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && - printk_ratelimit()) { - printk( - "%s%s[%d]: segfault at %lx ip %p sp %p error %lx", - task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, - tsk->comm, task_pid_nr(tsk), address, - (void *) regs->ip, (void *) regs->sp, error_code); - print_vma_addr(" in ", regs->ip); - printk("\n"); - } - - tsk->thread.cr2 = address; - /* Kernel addresses are always protection faults */ - tsk->thread.error_code = error_code | (address >= TASK_SIZE); - tsk->thread.trap_no = 14; - force_sig_info_fault(SIGSEGV, si_code, address, tsk); - return; - } - - if (is_f00f_bug(regs, address)) - return; - -no_context: - /* Are we prepared to handle this kernel fault? */ - if (fixup_exception(regs)) - return; - - /* - * X86_32 - * Valid to do another page fault here, because if this fault - * had been triggered by is_prefetch fixup_exception would have - * handled it. - * - * X86_64 - * Hall of shame of CPU/BIOS bugs. - */ - if (is_prefetch(regs, address, error_code)) - return; - - if (is_errata93(regs, address)) - return; - -/* - * Oops. The kernel tried to access some bad page. We'll have to - * terminate things with extreme prejudice. - */ -#ifdef CONFIG_X86_32 - bust_spinlocks(1); -#else - flags = oops_begin(); -#endif - - show_fault_oops(regs, error_code, address); - - tsk->thread.cr2 = address; - tsk->thread.trap_no = 14; - tsk->thread.error_code = error_code; - -#ifdef CONFIG_X86_32 - die("Oops", regs, error_code); - bust_spinlocks(0); - do_exit(SIGKILL); -#else - sig = SIGKILL; - if (__die("Oops", regs, error_code)) - sig = 0; - /* Executive summary in case the body of the oops scrolled away */ - printk(KERN_EMERG "CR2: %016lx\n", address); - oops_end(flags, regs, sig); -#endif - -out_of_memory: - /* - * We ran out of memory, call the OOM killer, and return the userspace - * (which will retry the fault, or kill us if we got oom-killed). - */ - up_read(&mm->mmap_sem); - pagefault_out_of_memory(); - return; - -do_sigbus: - up_read(&mm->mmap_sem); - - /* Kernel mode? Handle exceptions or die */ - if (!(error_code & PF_USER)) - goto no_context; -#ifdef CONFIG_X86_32 - /* User space => ok to do another page fault */ - if (is_prefetch(regs, address, error_code)) - return; -#endif - tsk->thread.cr2 = address; - tsk->thread.error_code = error_code; - tsk->thread.trap_no = 14; - force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk); } DEFINE_SPINLOCK(pgd_lock); -- cgit From 94ce1c585ed51dd9e72e812117e11f3f236a5399 Mon Sep 17 00:00:00 2001 From: Grant Erickson Date: Thu, 18 Dec 2008 12:34:05 +0000 Subject: powerpc/4xx: DTS: Add Add'l SDRAM0 Compatible and Interrupt Info Added additional information for type and compatibility strings and interrupt information to the SDRAM0 memory-controller device tree nodes for AMCC PowerPC 405EX[r]-based boards to facilitate binding with the new "ibm,sdram-4xx-ddr2" EDAC memory controller adapter driver. Signed-off-by: Grant Erickson Acked-by: Stefan Roese Signed-off-by: Josh Boyer --- arch/powerpc/boot/dts/haleakala.dts | 5 ++++- arch/powerpc/boot/dts/kilauea.dts | 5 ++++- arch/powerpc/boot/dts/makalu.dts | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/boot/dts/haleakala.dts b/arch/powerpc/boot/dts/haleakala.dts index 513bc43a71a..5b2a4947bf8 100644 --- a/arch/powerpc/boot/dts/haleakala.dts +++ b/arch/powerpc/boot/dts/haleakala.dts @@ -89,8 +89,11 @@ clock-frequency = <0>; /* Filled in by U-Boot */ SDRAM0: memory-controller { - compatible = "ibm,sdram-405exr"; + compatible = "ibm,sdram-405exr", "ibm,sdram-4xx-ddr2"; dcr-reg = <0x010 0x002>; + interrupt-parent = <&UIC2>; + interrupts = <0x5 0x4 /* ECC DED Error */ + 0x6 0x4>; /* ECC SEC Error */ }; MAL0: mcmal { diff --git a/arch/powerpc/boot/dts/kilauea.dts b/arch/powerpc/boot/dts/kilauea.dts index dececc4b5ff..2804444812e 100644 --- a/arch/powerpc/boot/dts/kilauea.dts +++ b/arch/powerpc/boot/dts/kilauea.dts @@ -90,8 +90,11 @@ clock-frequency = <0>; /* Filled in by U-Boot */ SDRAM0: memory-controller { - compatible = "ibm,sdram-405ex"; + compatible = "ibm,sdram-405ex", "ibm,sdram-4xx-ddr2"; dcr-reg = <0x010 0x002>; + interrupt-parent = <&UIC2>; + interrupts = <0x5 0x4 /* ECC DED Error */ + 0x6 0x4>; /* ECC SEC Error */ }; MAL0: mcmal { diff --git a/arch/powerpc/boot/dts/makalu.dts b/arch/powerpc/boot/dts/makalu.dts index 945508c7e7d..ffc246e7267 100644 --- a/arch/powerpc/boot/dts/makalu.dts +++ b/arch/powerpc/boot/dts/makalu.dts @@ -90,8 +90,11 @@ clock-frequency = <0>; /* Filled in by U-Boot */ SDRAM0: memory-controller { - compatible = "ibm,sdram-405ex"; + compatible = "ibm,sdram-405ex", "ibm,sdram-4xx-ddr2"; dcr-reg = <0x010 0x002>; + interrupt-parent = <&UIC2>; + interrupts = <0x5 0x4 /* ECC DED Error */ + 0x6 0x4 /* ECC SEC Error */ >; }; MAL0: mcmal { -- cgit From e275e023aa69bdc6a2f43b86ca3aa93a22e47837 Mon Sep 17 00:00:00 2001 From: Sean MacLennan Date: Fri, 9 Jan 2009 18:20:11 +0000 Subject: powerpc/44x: Warp patches for the new NDFC driver Convert the Warp platform to use the newly merged NDFC driver - warp.dts changed to work with ndfc - warp-nand.c no longer needed - removed obsolete rev A support from cuboot-warp.c Signed-off-by: Sean MacLennan Signed-off-by: Josh Boyer --- arch/powerpc/boot/cuboot-warp.c | 43 ----------- arch/powerpc/boot/dts/warp.dts | 42 +++++++++- arch/powerpc/platforms/44x/Makefile | 1 - arch/powerpc/platforms/44x/warp-nand.c | 135 --------------------------------- 4 files changed, 41 insertions(+), 180 deletions(-) delete mode 100644 arch/powerpc/platforms/44x/warp-nand.c diff --git a/arch/powerpc/boot/cuboot-warp.c b/arch/powerpc/boot/cuboot-warp.c index 21780210057..806df693fea 100644 --- a/arch/powerpc/boot/cuboot-warp.c +++ b/arch/powerpc/boot/cuboot-warp.c @@ -18,57 +18,14 @@ static bd_t bd; -static void warp_fixup_one_nor(u32 from, u32 to) -{ - void *devp; - char name[50]; - u32 v[2]; - - sprintf(name, "/plb/opb/ebc/nor_flash@0,0/partition@%x", from); - - devp = finddevice(name); - if (!devp) - return; - - if (getprop(devp, "reg", v, sizeof(v)) == sizeof(v)) { - v[0] = to; - setprop(devp, "reg", v, sizeof(v)); - - printf("NOR 64M fixup %x -> %x\r\n", from, to); - } -} - - static void warp_fixups(void) { ibm440ep_fixup_clocks(66000000, 11059200, 50000000); ibm4xx_sdram_fixup_memsize(); ibm4xx_fixup_ebc_ranges("/plb/opb/ebc"); dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr); - - /* Fixup for 64M flash on Rev A boards. */ - if (bd.bi_flashsize == 0x4000000) { - void *devp; - u32 v[3]; - - devp = finddevice("/plb/opb/ebc/nor_flash@0,0"); - if (!devp) - return; - - /* Fixup the size */ - if (getprop(devp, "reg", v, sizeof(v)) == sizeof(v)) { - v[2] = bd.bi_flashsize; - setprop(devp, "reg", v, sizeof(v)); - } - - /* Fixup parition offsets */ - warp_fixup_one_nor(0x300000, 0x3f00000); - warp_fixup_one_nor(0x340000, 0x3f40000); - warp_fixup_one_nor(0x380000, 0x3f80000); - } } - void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { diff --git a/arch/powerpc/boot/dts/warp.dts b/arch/powerpc/boot/dts/warp.dts index f4e4ba69eef..7e183ff9a31 100644 --- a/arch/powerpc/boot/dts/warp.dts +++ b/arch/powerpc/boot/dts/warp.dts @@ -149,12 +149,17 @@ reg = <0x00000002 0x00004000 0x00000A00>; }; - nor_flash@0,0 { + nor@0,0 { compatible = "amd,s29gl032a", "cfi-flash"; bank-width = <2>; reg = <0x00000000 0x00000000 0x00400000>; #address-cells = <1>; #size-cells = <1>; + + partition@0 { + label = "splash"; + reg = <0x00000000 0x00020000>; + }; partition@300000 { label = "fpga"; reg = <0x0300000 0x00040000>; @@ -168,6 +173,41 @@ reg = <0x0380000 0x00080000>; }; }; + + ndfc@1,0 { + compatible = "ibm,ndfc"; + reg = <0x00000001 0x00000000 0x00002000>; + ccr = <0x00001000>; + bank-settings = <0x80002222>; + #address-cells = <1>; + #size-cells = <1>; + + nand { + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "kernel"; + reg = <0x00000000 0x00200000>; + }; + partition@200000 { + label = "root"; + reg = <0x00200000 0x03E00000>; + }; + partition@40000000 { + label = "persistent"; + reg = <0x04000000 0x04000000>; + }; + partition@80000000 { + label = "persistent1"; + reg = <0x08000000 0x04000000>; + }; + partition@C0000000 { + label = "persistent2"; + reg = <0x0C000000 0x04000000>; + }; + }; + }; }; UART0: serial@ef600300 { diff --git a/arch/powerpc/platforms/44x/Makefile b/arch/powerpc/platforms/44x/Makefile index 698133180ae..01f51daace1 100644 --- a/arch/powerpc/platforms/44x/Makefile +++ b/arch/powerpc/platforms/44x/Makefile @@ -3,5 +3,4 @@ obj-$(CONFIG_PPC44x_SIMPLE) += ppc44x_simple.o obj-$(CONFIG_EBONY) += ebony.o obj-$(CONFIG_SAM440EP) += sam440ep.o obj-$(CONFIG_WARP) += warp.o -obj-$(CONFIG_WARP) += warp-nand.o obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o diff --git a/arch/powerpc/platforms/44x/warp-nand.c b/arch/powerpc/platforms/44x/warp-nand.c deleted file mode 100644 index 89ecd76127d..00000000000 --- a/arch/powerpc/platforms/44x/warp-nand.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * PIKA Warp(tm) NAND flash specific routines - * - * Copyright (c) 2008 PIKA Technologies - * Sean MacLennan - */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -#ifdef CONFIG_MTD_NAND_NDFC - -#define CS_NAND_0 1 /* use chip select 1 for NAND device 0 */ - -#define WARP_NAND_FLASH_REG_ADDR 0xD0000000UL -#define WARP_NAND_FLASH_REG_SIZE 0x2000 - -static struct resource warp_ndfc = { - .start = WARP_NAND_FLASH_REG_ADDR, - .end = WARP_NAND_FLASH_REG_ADDR + WARP_NAND_FLASH_REG_SIZE - 1, - .flags = IORESOURCE_MEM, -}; - -static struct mtd_partition nand_parts[] = { - { - .name = "kernel", - .offset = 0, - .size = 0x0200000 - }, - { - .name = "root", - .offset = 0x0200000, - .size = 0x3E00000 - }, - { - .name = "persistent", - .offset = 0x4000000, - .size = 0x4000000 - }, - { - .name = "persistent1", - .offset = 0x8000000, - .size = 0x4000000 - }, - { - .name = "persistent2", - .offset = 0xC000000, - .size = 0x4000000 - } -}; - -struct ndfc_controller_settings warp_ndfc_settings = { - .ccr_settings = (NDFC_CCR_BS(CS_NAND_0) | NDFC_CCR_ARAC1), - .ndfc_erpn = 0, -}; - -static struct ndfc_chip_settings warp_chip0_settings = { - .bank_settings = 0x80002222, -}; - -struct platform_nand_ctrl warp_nand_ctrl = { - .priv = &warp_ndfc_settings, -}; - -static struct platform_device warp_ndfc_device = { - .name = "ndfc-nand", - .id = 0, - .dev = { - .platform_data = &warp_nand_ctrl, - }, - .num_resources = 1, - .resource = &warp_ndfc, -}; - -/* Do NOT set the ecclayout: let it default so it is correct for both - * 64M and 256M flash chips. - */ -static struct platform_nand_chip warp_nand_chip0 = { - .nr_chips = 1, - .chip_offset = CS_NAND_0, - .nr_partitions = ARRAY_SIZE(nand_parts), - .partitions = nand_parts, - .chip_delay = 20, - .priv = &warp_chip0_settings, -}; - -static struct platform_device warp_nand_device = { - .name = "ndfc-chip", - .id = 0, - .num_resources = 0, - .dev = { - .platform_data = &warp_nand_chip0, - .parent = &warp_ndfc_device.dev, - } -}; - -static int warp_setup_nand_flash(void) -{ - struct device_node *np; - - /* Try to detect a rev A based on NOR size. */ - np = of_find_compatible_node(NULL, NULL, "cfi-flash"); - if (np) { - struct property *pp; - - pp = of_find_property(np, "reg", NULL); - if (pp && (pp->length == 12)) { - u32 *v = pp->value; - if (v[2] == 0x4000000) { - /* Rev A = 64M NAND */ - warp_nand_chip0.nr_partitions = 3; - - nand_parts[1].size = 0x3000000; - nand_parts[2].offset = 0x3200000; - nand_parts[2].size = 0x0e00000; - } - } - of_node_put(np); - } - - platform_device_register(&warp_ndfc_device); - platform_device_register(&warp_nand_device); - - return 0; -} -machine_device_initcall(warp, warp_setup_nand_flash); - -#endif -- cgit From e7f07968c16bdd9480001c0a9de013ba56889cf9 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Tue, 20 Jan 2009 09:50:19 -0500 Subject: ext4: Fix ext4_free_blocks() w/o a journal when files have indirect blocks When trying to unlink a file with indirect blocks on a filesystem without a journal, the "circular indirect block" sanity test was getting falsely triggered. Signed-off-by: "Theodore Ts'o" --- fs/ext4/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 49484ba801c..b4386dafeb0 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3622,7 +3622,7 @@ static void ext4_free_data(handle_t *handle, struct inode *inode, * block pointed to itself, it would have been detached when * the block was cleared. Check for this instead of OOPSing. */ - if (bh2jh(this_bh)) + if ((EXT4_JOURNAL(inode) == NULL) || bh2jh(this_bh)) ext4_handle_dirty_metadata(handle, inode, this_bh); else ext4_error(inode->i_sb, __func__, -- cgit From 6e11521506e592aed2eba90166e20796c0695023 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 20 Jan 2009 09:57:24 -0600 Subject: powerpc/85xx: Fix typo in mpc8572ds dts The localbus node flash had a minor typo for a read-only property. Signed-off-by: Kumar Gala --- arch/powerpc/boot/dts/mpc8572ds.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/boot/dts/mpc8572ds.dts b/arch/powerpc/boot/dts/mpc8572ds.dts index 3dcc001b8ed..359c3b72742 100644 --- a/arch/powerpc/boot/dts/mpc8572ds.dts +++ b/arch/powerpc/boot/dts/mpc8572ds.dts @@ -89,7 +89,7 @@ ramdisk@0 { reg = <0x0 0x03000000>; - readl-only; + read-only; }; diagnostic@3000000 { -- cgit From 8c4c19f1367435afdc16ac122a2a95a4d6cff9f0 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Tue, 20 Jan 2009 17:48:02 +0200 Subject: UBI: remove unused variable Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 9082768cc6c..09a326ecd05 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -380,7 +380,7 @@ static void free_user_volumes(struct ubi_device *ubi) */ static int uif_init(struct ubi_device *ubi) { - int i, err, do_free = 0; + int i, err; dev_t dev; sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num); @@ -427,13 +427,10 @@ static int uif_init(struct ubi_device *ubi) out_volumes: kill_volumes(ubi); - do_free = 0; out_sysfs: ubi_sysfs_close(ubi); cdev_del(&ubi->cdev); out_unreg: - if (do_free) - free_user_volumes(ubi); unregister_chrdev_region(ubi->cdev.dev, ubi->vtbl_slots + 1); ubi_err("cannot initialize UBI %s, error %d", ubi->ubi_name, err); return err; -- cgit From 36b477d005fbda29e7581c3cef7ee31a59d8970b Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Tue, 20 Jan 2009 18:04:09 +0200 Subject: UBI: fix resource de-allocation GregKH asked to fix UBI which has fake device release method. Indeed, we have to free UBI device description object from the release method, because otherwise we'll oops is someone opens a UBI device sysfs file, then the device is removed, and he reads the file. With this fix, he will get -ENODEV instead of an oops. Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 09a326ecd05..4048db83aef 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -263,8 +263,12 @@ static ssize_t dev_attribute_show(struct device *dev, return ret; } -/* Fake "release" method for UBI devices */ -static void dev_release(struct device *dev) { } +static void dev_release(struct device *dev) +{ + struct ubi_device *ubi = container_of(dev, struct ubi_device, dev); + + kfree(ubi); +} /** * ubi_sysfs_init - initialize sysfs for an UBI device. @@ -944,6 +948,12 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) if (ubi->bgt_thread) kthread_stop(ubi->bgt_thread); + /* + * Get a reference to the device in order to prevent 'dev_release()' + * from freeing @ubi object. + */ + get_device(&ubi->dev); + uif_close(ubi); ubi_wl_close(ubi); free_internal_volumes(ubi); @@ -955,7 +965,7 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) vfree(ubi->dbg_peb_buf); #endif ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); - kfree(ubi); + put_device(&ubi->dev); return 0; } -- cgit From afb33f8c0d7dea8c48ae1c2e3af5b437aa8dd7bb Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Mon, 12 Jan 2009 12:53:45 +0100 Subject: x86: remove byte locks Impact: cleanup Remove byte locks implementation, which was introduced by Jeremy in 8efcbab6 ("paravirt: introduce a "lock-byte" spinlock implementation"), but turned out to be dead code that is not used by any in-kernel virtualization guest (Xen uses its own variant of spinlocks implementation and KVM is not planning to move to byte locks). Signed-off-by: Jiri Kosina Signed-off-by: Ingo Molnar --- arch/x86/include/asm/paravirt.h | 2 -- arch/x86/include/asm/spinlock.h | 66 ++---------------------------------- arch/x86/kernel/paravirt-spinlocks.c | 10 ------ 3 files changed, 2 insertions(+), 76 deletions(-) diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index ba3e2ff6aed..32bc6c2c138 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h @@ -1389,8 +1389,6 @@ static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx, void _paravirt_nop(void); #define paravirt_nop ((void *)_paravirt_nop) -void paravirt_use_bytelocks(void); - #ifdef CONFIG_SMP static inline int __raw_spin_is_locked(struct raw_spinlock *lock) diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h index d17c91981da..2bd6b111a41 100644 --- a/arch/x86/include/asm/spinlock.h +++ b/arch/x86/include/asm/spinlock.h @@ -172,70 +172,8 @@ static inline int __ticket_spin_is_contended(raw_spinlock_t *lock) return (((tmp >> TICKET_SHIFT) - tmp) & ((1 << TICKET_SHIFT) - 1)) > 1; } -#ifdef CONFIG_PARAVIRT -/* - * Define virtualization-friendly old-style lock byte lock, for use in - * pv_lock_ops if desired. - * - * This differs from the pre-2.6.24 spinlock by always using xchgb - * rather than decb to take the lock; this allows it to use a - * zero-initialized lock structure. It also maintains a 1-byte - * contention counter, so that we can implement - * __byte_spin_is_contended. - */ -struct __byte_spinlock { - s8 lock; - s8 spinners; -}; - -static inline int __byte_spin_is_locked(raw_spinlock_t *lock) -{ - struct __byte_spinlock *bl = (struct __byte_spinlock *)lock; - return bl->lock != 0; -} - -static inline int __byte_spin_is_contended(raw_spinlock_t *lock) -{ - struct __byte_spinlock *bl = (struct __byte_spinlock *)lock; - return bl->spinners != 0; -} - -static inline void __byte_spin_lock(raw_spinlock_t *lock) -{ - struct __byte_spinlock *bl = (struct __byte_spinlock *)lock; - s8 val = 1; - - asm("1: xchgb %1, %0\n" - " test %1,%1\n" - " jz 3f\n" - " " LOCK_PREFIX "incb %2\n" - "2: rep;nop\n" - " cmpb $1, %0\n" - " je 2b\n" - " " LOCK_PREFIX "decb %2\n" - " jmp 1b\n" - "3:" - : "+m" (bl->lock), "+q" (val), "+m" (bl->spinners): : "memory"); -} - -static inline int __byte_spin_trylock(raw_spinlock_t *lock) -{ - struct __byte_spinlock *bl = (struct __byte_spinlock *)lock; - u8 old = 1; - - asm("xchgb %1,%0" - : "+m" (bl->lock), "+q" (old) : : "memory"); +#ifndef CONFIG_PARAVIRT - return old == 0; -} - -static inline void __byte_spin_unlock(raw_spinlock_t *lock) -{ - struct __byte_spinlock *bl = (struct __byte_spinlock *)lock; - smp_wmb(); - bl->lock = 0; -} -#else /* !CONFIG_PARAVIRT */ static inline int __raw_spin_is_locked(raw_spinlock_t *lock) { return __ticket_spin_is_locked(lock); @@ -267,7 +205,7 @@ static __always_inline void __raw_spin_lock_flags(raw_spinlock_t *lock, __raw_spin_lock(lock); } -#endif /* CONFIG_PARAVIRT */ +#endif static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) { diff --git a/arch/x86/kernel/paravirt-spinlocks.c b/arch/x86/kernel/paravirt-spinlocks.c index 95777b0faa7..3a7c5a44082 100644 --- a/arch/x86/kernel/paravirt-spinlocks.c +++ b/arch/x86/kernel/paravirt-spinlocks.c @@ -26,13 +26,3 @@ struct pv_lock_ops pv_lock_ops = { }; EXPORT_SYMBOL(pv_lock_ops); -void __init paravirt_use_bytelocks(void) -{ -#ifdef CONFIG_SMP - pv_lock_ops.spin_is_locked = __byte_spin_is_locked; - pv_lock_ops.spin_is_contended = __byte_spin_is_contended; - pv_lock_ops.spin_lock = __byte_spin_lock; - pv_lock_ops.spin_trylock = __byte_spin_trylock; - pv_lock_ops.spin_unlock = __byte_spin_unlock; -#endif -} -- cgit From 66f9a2590aa87dc77cddaeaf46177de76edd2339 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 20 Jan 2009 09:49:51 -0800 Subject: Revert "xfrm: For 32/64 compatability wrt. xfrm_usersa_info" This reverts commit fc8c7dc1b29560c016a67a34ccff32a712b5aa86. As indicated by Jiri Klimes, this won't work. These numbers are not only used the size validation, they are also used to locate attributes sitting after the message. Signed-off-by: David S. Miller --- net/xfrm/xfrm_user.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 7877e7975da..b95a2d64eb5 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -1914,17 +1914,10 @@ static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, } #endif -/* For the xfrm_usersa_info cases we have to work around some 32-bit vs. - * 64-bit compatability issues. On 32-bit the structure is 220 bytes, but - * for 64-bit it gets padded out to 224 bytes. Those bytes are just - * padding and don't have any content we care about. Therefore as long - * as we have enough bytes for the content we can make both cases work. - */ - #define XMSGSIZE(type) sizeof(struct type) static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = { - [XFRM_MSG_NEWSA - XFRM_MSG_BASE] = 220, /* see above */ + [XFRM_MSG_NEWSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info), [XFRM_MSG_DELSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_id), [XFRM_MSG_GETSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_id), [XFRM_MSG_NEWPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info), @@ -1934,7 +1927,7 @@ static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = { [XFRM_MSG_ACQUIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_acquire), [XFRM_MSG_EXPIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_expire), [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info), - [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = 220, /* see above */ + [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info), [XFRM_MSG_POLEXPIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_polexpire), [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_flush), [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = 0, -- cgit From e801c72d61173dff2bbbaa164d43d84b993c6ddb Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Tue, 20 Jan 2009 13:01:54 -0500 Subject: powerpc/40x: Update PowerPC 40x defconfigs Update the 40x defconfigs for 2.6.29-rc2 Signed-off-by: Josh Boyer --- arch/powerpc/configs/40x/acadia_defconfig | 76 +++++++++++++++++++------- arch/powerpc/configs/40x/ep405_defconfig | 87 ++++++++++++++++++++++-------- arch/powerpc/configs/40x/hcu4_defconfig | 78 ++++++++++++++++++++------- arch/powerpc/configs/40x/kilauea_defconfig | 76 +++++++++++++++++++------- arch/powerpc/configs/40x/makalu_defconfig | 76 +++++++++++++++++++------- arch/powerpc/configs/40x/virtex_defconfig | 53 ++++++++++++------ arch/powerpc/configs/40x/walnut_defconfig | 84 +++++++++++++++++++++-------- 7 files changed, 391 insertions(+), 139 deletions(-) diff --git a/arch/powerpc/configs/40x/acadia_defconfig b/arch/powerpc/configs/40x/acadia_defconfig index 25572cc837c..a32ec8d323a 100644 --- a/arch/powerpc/configs/40x/acadia_defconfig +++ b/arch/powerpc/configs/40x/acadia_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.28-rc2 -# Tue Oct 28 08:49:18 2008 +# Linux kernel version: 2.6.29-rc2 +# Tue Jan 20 08:17:46 2009 # # CONFIG_PPC64 is not set @@ -15,6 +15,7 @@ CONFIG_40x=y # CONFIG_44x is not set # CONFIG_E200 is not set CONFIG_4xx=y +CONFIG_PPC_MMU_NOHASH=y # CONFIG_PPC_MM_SLICES is not set CONFIG_NOT_COHERENT_CACHE=y CONFIG_PPC32=y @@ -40,7 +41,7 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_PPC_OF=y CONFIG_OF=y @@ -71,12 +72,12 @@ CONFIG_POSIX_MQUEUE=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set CONFIG_GROUP_SCHED=y # CONFIG_FAIR_GROUP_SCHED is not set # CONFIG_RT_GROUP_SCHED is not set CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set +# CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set @@ -89,6 +90,7 @@ CONFIG_EMBEDDED=y CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y +CONFIG_KALLSYMS_STRIP_GENERATED=y CONFIG_KALLSYMS_EXTRA_PASS=y CONFIG_HOTPLUG=y CONFIG_PRINTK=y @@ -111,7 +113,6 @@ CONFIG_SLUB_DEBUG=y CONFIG_SLUB=y # CONFIG_SLOB is not set # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y @@ -122,7 +123,6 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -130,11 +130,9 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y CONFIG_LBD=y # CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -151,6 +149,10 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set # CONFIG_FREEZER is not set # CONFIG_PPC4xx_PCI_EXPRESS is not set @@ -182,6 +184,7 @@ CONFIG_405EZ=y # CONFIG_GENERIC_IOMAP is not set # CONFIG_CPU_FREQ is not set # CONFIG_FSL_ULI1575 is not set +# CONFIG_SIMPLE_GPIO is not set # # Kernel options @@ -205,6 +208,7 @@ CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set # CONFIG_MATH_EMULATION is not set # CONFIG_IOMMU_HELPER is not set +CONFIG_PPC_NEED_DMA_SYNC_OPS=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_HAS_WALK_MEMORY=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y @@ -219,12 +223,14 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y -# CONFIG_RESOURCES_64BIT is not set # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_BOUNCE=y CONFIG_VIRT_TO_BUS=y CONFIG_UNEVICTABLE_LRU=y +CONFIG_PPC_4K_PAGES=y +# CONFIG_PPC_16K_PAGES is not set +# CONFIG_PPC_64K_PAGES is not set CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set @@ -248,6 +254,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y # CONFIG_PCI_MSI is not set CONFIG_PCI_LEGACY=y # CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_STUB is not set # CONFIG_PCCARD is not set # CONFIG_HOTPLUG_PCI is not set # CONFIG_HAS_RAPIDIO is not set @@ -272,6 +279,7 @@ CONFIG_NET=y # # Networking options # +CONFIG_COMPAT_NET_DEV_OPS=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -322,6 +330,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing @@ -334,6 +343,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set # CONFIG_PHONET is not set # CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -359,6 +369,7 @@ CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_REDBOOT_PARTS is not set CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_OF_PARTS=y @@ -430,6 +441,12 @@ CONFIG_MTD_PHYSMAP_OF=y # CONFIG_MTD_NAND is not set # CONFIG_MTD_ONENAND is not set +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set +# CONFIG_MTD_QINFO_PROBE is not set + # # UBI - Unsorted block images # @@ -524,6 +541,10 @@ CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR=y # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set # CONFIG_IWLWIFI_LEDS is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -576,9 +597,12 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_HVC_UDBG is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set # CONFIG_NVRAM is not set @@ -597,11 +621,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y # CONFIG_HWMON is not set CONFIG_THERMAL=y # CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y # # Sonics Silicon Backplane # -CONFIG_SSB_POSSIBLE=y # CONFIG_SSB is not set # @@ -611,7 +635,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set -# CONFIG_MFD_WM8400 is not set +# CONFIG_REGULATOR is not set # # Multimedia devices @@ -670,7 +694,9 @@ CONFIG_EXT2_FS=y # CONFIG_FS_POSIX_ACL is not set CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -704,10 +730,7 @@ CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -717,6 +740,7 @@ CONFIG_TMPFS=y # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set CONFIG_CRAMFS=y +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -757,6 +781,7 @@ CONFIG_MSDOS_PARTITION=y # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set # CONFIG_CRC_T10DIF is not set @@ -807,6 +832,7 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set @@ -815,18 +841,24 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_NOP_TRACER=y -CONFIG_HAVE_FTRACE=y +CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y -# CONFIG_FTRACE is not set +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y + +# +# Tracers +# +# CONFIG_FUNCTION_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set # CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set # CONFIG_STACK_TRACER is not set # CONFIG_DYNAMIC_PRINTK_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set +CONFIG_PRINT_STACK_DEPTH=64 # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_PAGEALLOC is not set @@ -853,11 +885,15 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_FIPS is not set CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y # CONFIG_CRYPTO_GF128MUL is not set # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_CRYPTD is not set diff --git a/arch/powerpc/configs/40x/ep405_defconfig b/arch/powerpc/configs/40x/ep405_defconfig index b80ba7aa312..4e9d85f39da 100644 --- a/arch/powerpc/configs/40x/ep405_defconfig +++ b/arch/powerpc/configs/40x/ep405_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.28-rc2 -# Tue Oct 28 08:49:20 2008 +# Linux kernel version: 2.6.29-rc2 +# Tue Jan 20 08:17:48 2009 # # CONFIG_PPC64 is not set @@ -15,6 +15,7 @@ CONFIG_40x=y # CONFIG_44x is not set # CONFIG_E200 is not set CONFIG_4xx=y +CONFIG_PPC_MMU_NOHASH=y # CONFIG_PPC_MM_SLICES is not set CONFIG_NOT_COHERENT_CACHE=y CONFIG_PPC32=y @@ -40,7 +41,7 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_PPC_OF=y CONFIG_OF=y @@ -71,12 +72,12 @@ CONFIG_POSIX_MQUEUE=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set CONFIG_GROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y # CONFIG_RT_GROUP_SCHED is not set CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set +# CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set @@ -89,6 +90,7 @@ CONFIG_EMBEDDED=y CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y +CONFIG_KALLSYMS_STRIP_GENERATED=y CONFIG_KALLSYMS_EXTRA_PASS=y CONFIG_HOTPLUG=y CONFIG_PRINTK=y @@ -111,7 +113,6 @@ CONFIG_SLUB_DEBUG=y CONFIG_SLUB=y # CONFIG_SLOB is not set # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y @@ -122,7 +123,6 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -130,11 +130,9 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y CONFIG_LBD=y # CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -151,6 +149,10 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set # CONFIG_FREEZER is not set # CONFIG_PPC4xx_PCI_EXPRESS is not set @@ -184,6 +186,7 @@ CONFIG_IBM405_ERR51=y # CONFIG_GENERIC_IOMAP is not set # CONFIG_CPU_FREQ is not set # CONFIG_FSL_ULI1575 is not set +# CONFIG_SIMPLE_GPIO is not set # # Kernel options @@ -207,6 +210,7 @@ CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set # CONFIG_MATH_EMULATION is not set # CONFIG_IOMMU_HELPER is not set +CONFIG_PPC_NEED_DMA_SYNC_OPS=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_HAS_WALK_MEMORY=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y @@ -221,12 +225,14 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y -# CONFIG_RESOURCES_64BIT is not set # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_BOUNCE=y CONFIG_VIRT_TO_BUS=y CONFIG_UNEVICTABLE_LRU=y +CONFIG_PPC_4K_PAGES=y +# CONFIG_PPC_16K_PAGES is not set +# CONFIG_PPC_64K_PAGES is not set CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set @@ -250,6 +256,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y # CONFIG_PCI_MSI is not set CONFIG_PCI_LEGACY=y # CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_STUB is not set # CONFIG_PCCARD is not set # CONFIG_HOTPLUG_PCI is not set # CONFIG_HAS_RAPIDIO is not set @@ -274,6 +281,7 @@ CONFIG_NET=y # # Networking options # +CONFIG_COMPAT_NET_DEV_OPS=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -324,6 +332,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing @@ -336,6 +345,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set # CONFIG_PHONET is not set # CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -361,6 +371,7 @@ CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_REDBOOT_PARTS is not set CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_OF_PARTS=y @@ -432,6 +443,12 @@ CONFIG_MTD_PHYSMAP_OF=y # CONFIG_MTD_NAND is not set # CONFIG_MTD_ONENAND is not set +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set +# CONFIG_MTD_QINFO_PROBE is not set + # # UBI - Unsorted block images # @@ -464,6 +481,7 @@ CONFIG_MISC_DEVICES=y # CONFIG_TIFM_CORE is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_HP_ILO is not set +# CONFIG_C2PORT is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -546,6 +564,7 @@ CONFIG_NETDEV_1000=y # CONFIG_JME is not set CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set +CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_CHELSIO_T3 is not set # CONFIG_ENIC is not set # CONFIG_IXGBE is not set @@ -569,6 +588,10 @@ CONFIG_NETDEV_10000=y # CONFIG_WLAN_80211 is not set # CONFIG_IWLWIFI_LEDS is not set +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + # # USB Network Adapters # @@ -629,9 +652,12 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_HVC_UDBG is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set # CONFIG_NVRAM is not set @@ -650,11 +676,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y # CONFIG_HWMON is not set CONFIG_THERMAL=y # CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y # # Sonics Silicon Backplane # -CONFIG_SSB_POSSIBLE=y # CONFIG_SSB is not set # @@ -664,7 +690,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set -# CONFIG_MFD_WM8400 is not set +# CONFIG_REGULATOR is not set # # Multimedia devices @@ -723,6 +749,7 @@ CONFIG_USB_MON=y # # CONFIG_USB_C67X00_HCD is not set # CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set # CONFIG_USB_ISP116X_HCD is not set # CONFIG_USB_ISP1760_HCD is not set CONFIG_USB_OHCI_HCD=y @@ -748,11 +775,11 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y # CONFIG_USB_TMC is not set # -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; # # -# may also be needed; see USB_STORAGE Help for more information +# see USB_STORAGE Help for more information # # CONFIG_USB_LIBUSUAL is not set @@ -791,6 +818,10 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y # CONFIG_USB_ISIGHTFW is not set # CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# # CONFIG_UWB is not set # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set @@ -816,7 +847,9 @@ CONFIG_EXT2_FS=y # CONFIG_FS_POSIX_ACL is not set CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -850,10 +883,7 @@ CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -863,6 +893,7 @@ CONFIG_TMPFS=y # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set CONFIG_CRAMFS=y +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -903,6 +934,7 @@ CONFIG_MSDOS_PARTITION=y # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set # CONFIG_CRC_T10DIF is not set @@ -953,6 +985,7 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set @@ -961,18 +994,24 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_NOP_TRACER=y -CONFIG_HAVE_FTRACE=y +CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y -# CONFIG_FTRACE is not set +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y + +# +# Tracers +# +# CONFIG_FUNCTION_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set # CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set # CONFIG_STACK_TRACER is not set # CONFIG_DYNAMIC_PRINTK_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set +CONFIG_PRINT_STACK_DEPTH=64 # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_PAGEALLOC is not set @@ -999,11 +1038,15 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_FIPS is not set CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y # CONFIG_CRYPTO_GF128MUL is not set # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_CRYPTD is not set diff --git a/arch/powerpc/configs/40x/hcu4_defconfig b/arch/powerpc/configs/40x/hcu4_defconfig index 45dcb824503..8c019d79bf2 100644 --- a/arch/powerpc/configs/40x/hcu4_defconfig +++ b/arch/powerpc/configs/40x/hcu4_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.28-rc2 -# Tue Oct 28 08:49:22 2008 +# Linux kernel version: 2.6.29-rc2 +# Tue Jan 20 08:17:50 2009 # # CONFIG_PPC64 is not set @@ -15,6 +15,7 @@ CONFIG_40x=y # CONFIG_44x is not set # CONFIG_E200 is not set CONFIG_4xx=y +CONFIG_PPC_MMU_NOHASH=y # CONFIG_PPC_MM_SLICES is not set CONFIG_NOT_COHERENT_CACHE=y CONFIG_PPC32=y @@ -40,7 +41,7 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_PPC_OF=y CONFIG_OF=y @@ -71,12 +72,12 @@ CONFIG_POSIX_MQUEUE=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set CONFIG_GROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y # CONFIG_RT_GROUP_SCHED is not set CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set +# CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set @@ -89,6 +90,7 @@ CONFIG_EMBEDDED=y CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y +CONFIG_KALLSYMS_STRIP_GENERATED=y CONFIG_KALLSYMS_EXTRA_PASS=y CONFIG_HOTPLUG=y CONFIG_PRINTK=y @@ -111,7 +113,6 @@ CONFIG_SLUB_DEBUG=y CONFIG_SLUB=y # CONFIG_SLOB is not set # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y @@ -122,7 +123,6 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -130,11 +130,9 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y CONFIG_LBD=y # CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -151,6 +149,10 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set # CONFIG_FREEZER is not set # CONFIG_PPC4xx_PCI_EXPRESS is not set @@ -182,6 +184,7 @@ CONFIG_405GPR=y # CONFIG_GENERIC_IOMAP is not set # CONFIG_CPU_FREQ is not set # CONFIG_FSL_ULI1575 is not set +# CONFIG_SIMPLE_GPIO is not set # # Kernel options @@ -205,6 +208,7 @@ CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set # CONFIG_MATH_EMULATION is not set # CONFIG_IOMMU_HELPER is not set +CONFIG_PPC_NEED_DMA_SYNC_OPS=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_HAS_WALK_MEMORY=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y @@ -219,12 +223,14 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y -CONFIG_RESOURCES_64BIT=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_BOUNCE=y CONFIG_VIRT_TO_BUS=y CONFIG_UNEVICTABLE_LRU=y +CONFIG_PPC_4K_PAGES=y +# CONFIG_PPC_16K_PAGES is not set +# CONFIG_PPC_64K_PAGES is not set CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set @@ -248,6 +254,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y # CONFIG_PCI_MSI is not set # CONFIG_PCI_LEGACY is not set # CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_STUB is not set # CONFIG_PCCARD is not set # CONFIG_HOTPLUG_PCI is not set # CONFIG_HAS_RAPIDIO is not set @@ -272,6 +279,7 @@ CONFIG_NET=y # # Networking options # +CONFIG_COMPAT_NET_DEV_OPS=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -322,6 +330,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing @@ -334,6 +343,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set # CONFIG_PHONET is not set # CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -359,6 +369,7 @@ CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_REDBOOT_PARTS is not set CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_OF_PARTS=y @@ -430,6 +441,12 @@ CONFIG_MTD_PHYSMAP_OF=y # CONFIG_MTD_NAND is not set # CONFIG_MTD_ONENAND is not set +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set +# CONFIG_MTD_QINFO_PROBE is not set + # # UBI - Unsorted block images # @@ -461,6 +478,7 @@ CONFIG_MISC_DEVICES=y # CONFIG_TIFM_CORE is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_HP_ILO is not set +# CONFIG_C2PORT is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -543,6 +561,7 @@ CONFIG_NETDEV_1000=y # CONFIG_JME is not set CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set +CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_CHELSIO_T3 is not set # CONFIG_ENIC is not set # CONFIG_IXGBE is not set @@ -565,6 +584,10 @@ CONFIG_NETDEV_10000=y # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set # CONFIG_IWLWIFI_LEDS is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -617,9 +640,12 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_HVC_UDBG is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set # CONFIG_NVRAM is not set @@ -639,11 +665,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y # CONFIG_THERMAL is not set # CONFIG_THERMAL_HWMON is not set # CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y # # Sonics Silicon Backplane # -CONFIG_SSB_POSSIBLE=y # CONFIG_SSB is not set # @@ -653,7 +679,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set -# CONFIG_MFD_WM8400 is not set +# CONFIG_REGULATOR is not set # # Multimedia devices @@ -712,7 +738,9 @@ CONFIG_EXT2_FS=y # CONFIG_FS_POSIX_ACL is not set CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -746,10 +774,7 @@ CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -759,6 +784,7 @@ CONFIG_TMPFS=y # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set CONFIG_CRAMFS=y +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -799,6 +825,7 @@ CONFIG_MSDOS_PARTITION=y # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set # CONFIG_CRC_T10DIF is not set @@ -849,6 +876,7 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set @@ -857,18 +885,24 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_NOP_TRACER=y -CONFIG_HAVE_FTRACE=y +CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y -# CONFIG_FTRACE is not set +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y + +# +# Tracers +# +# CONFIG_FUNCTION_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set # CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set # CONFIG_STACK_TRACER is not set # CONFIG_DYNAMIC_PRINTK_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set +CONFIG_PRINT_STACK_DEPTH=64 # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_PAGEALLOC is not set @@ -895,11 +929,15 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_FIPS is not set CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y # CONFIG_CRYPTO_GF128MUL is not set # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_CRYPTD is not set diff --git a/arch/powerpc/configs/40x/kilauea_defconfig b/arch/powerpc/configs/40x/kilauea_defconfig index e2f3695d9d0..9917a09bad3 100644 --- a/arch/powerpc/configs/40x/kilauea_defconfig +++ b/arch/powerpc/configs/40x/kilauea_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.28-rc2 -# Tue Oct 28 08:49:23 2008 +# Linux kernel version: 2.6.29-rc2 +# Tue Jan 20 08:17:52 2009 # # CONFIG_PPC64 is not set @@ -15,6 +15,7 @@ CONFIG_40x=y # CONFIG_44x is not set # CONFIG_E200 is not set CONFIG_4xx=y +CONFIG_PPC_MMU_NOHASH=y # CONFIG_PPC_MM_SLICES is not set CONFIG_NOT_COHERENT_CACHE=y CONFIG_PPC32=y @@ -40,7 +41,7 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_PPC_OF=y CONFIG_OF=y @@ -71,12 +72,12 @@ CONFIG_POSIX_MQUEUE=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set CONFIG_GROUP_SCHED=y # CONFIG_FAIR_GROUP_SCHED is not set # CONFIG_RT_GROUP_SCHED is not set CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set +# CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set @@ -89,6 +90,7 @@ CONFIG_EMBEDDED=y CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y +CONFIG_KALLSYMS_STRIP_GENERATED=y CONFIG_KALLSYMS_EXTRA_PASS=y CONFIG_HOTPLUG=y CONFIG_PRINTK=y @@ -111,7 +113,6 @@ CONFIG_SLUB_DEBUG=y CONFIG_SLUB=y # CONFIG_SLOB is not set # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y @@ -122,7 +123,6 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -130,11 +130,9 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y CONFIG_LBD=y # CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -151,6 +149,10 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set # CONFIG_FREEZER is not set CONFIG_PPC4xx_PCI_EXPRESS=y @@ -182,6 +184,7 @@ CONFIG_405EX=y # CONFIG_GENERIC_IOMAP is not set # CONFIG_CPU_FREQ is not set # CONFIG_FSL_ULI1575 is not set +# CONFIG_SIMPLE_GPIO is not set # # Kernel options @@ -205,6 +208,7 @@ CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set # CONFIG_MATH_EMULATION is not set # CONFIG_IOMMU_HELPER is not set +CONFIG_PPC_NEED_DMA_SYNC_OPS=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_HAS_WALK_MEMORY=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y @@ -219,12 +223,14 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y -# CONFIG_RESOURCES_64BIT is not set # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_BOUNCE=y CONFIG_VIRT_TO_BUS=y CONFIG_UNEVICTABLE_LRU=y +CONFIG_PPC_4K_PAGES=y +# CONFIG_PPC_16K_PAGES is not set +# CONFIG_PPC_64K_PAGES is not set CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set @@ -248,6 +254,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y # CONFIG_PCI_MSI is not set CONFIG_PCI_LEGACY=y # CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_STUB is not set # CONFIG_PCCARD is not set # CONFIG_HOTPLUG_PCI is not set # CONFIG_HAS_RAPIDIO is not set @@ -272,6 +279,7 @@ CONFIG_NET=y # # Networking options # +CONFIG_COMPAT_NET_DEV_OPS=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -322,6 +330,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing @@ -334,6 +343,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set # CONFIG_PHONET is not set # CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -359,6 +369,7 @@ CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_REDBOOT_PARTS is not set CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_OF_PARTS=y @@ -430,6 +441,12 @@ CONFIG_MTD_PHYSMAP_OF=y # CONFIG_MTD_NAND is not set # CONFIG_MTD_ONENAND is not set +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set +# CONFIG_MTD_QINFO_PROBE is not set + # # UBI - Unsorted block images # @@ -524,6 +541,10 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set # CONFIG_IWLWIFI_LEDS is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -576,9 +597,12 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_HVC_UDBG is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set # CONFIG_NVRAM is not set @@ -597,11 +621,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y # CONFIG_HWMON is not set CONFIG_THERMAL=y # CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y # # Sonics Silicon Backplane # -CONFIG_SSB_POSSIBLE=y # CONFIG_SSB is not set # @@ -611,7 +635,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set -# CONFIG_MFD_WM8400 is not set +# CONFIG_REGULATOR is not set # # Multimedia devices @@ -670,7 +694,9 @@ CONFIG_EXT2_FS=y # CONFIG_FS_POSIX_ACL is not set CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -704,10 +730,7 @@ CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -717,6 +740,7 @@ CONFIG_TMPFS=y # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set CONFIG_CRAMFS=y +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -757,6 +781,7 @@ CONFIG_MSDOS_PARTITION=y # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set # CONFIG_CRC_T10DIF is not set @@ -807,6 +832,7 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set @@ -815,18 +841,24 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_NOP_TRACER=y -CONFIG_HAVE_FTRACE=y +CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y -# CONFIG_FTRACE is not set +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y + +# +# Tracers +# +# CONFIG_FUNCTION_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set # CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set # CONFIG_STACK_TRACER is not set # CONFIG_DYNAMIC_PRINTK_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set +CONFIG_PRINT_STACK_DEPTH=64 # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_PAGEALLOC is not set @@ -853,11 +885,15 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_FIPS is not set CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y # CONFIG_CRYPTO_GF128MUL is not set # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_CRYPTD is not set diff --git a/arch/powerpc/configs/40x/makalu_defconfig b/arch/powerpc/configs/40x/makalu_defconfig index 413c778ecd7..58bf2ac2e0d 100644 --- a/arch/powerpc/configs/40x/makalu_defconfig +++ b/arch/powerpc/configs/40x/makalu_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.28-rc2 -# Tue Oct 28 08:49:25 2008 +# Linux kernel version: 2.6.29-rc2 +# Tue Jan 20 08:17:53 2009 # # CONFIG_PPC64 is not set @@ -15,6 +15,7 @@ CONFIG_40x=y # CONFIG_44x is not set # CONFIG_E200 is not set CONFIG_4xx=y +CONFIG_PPC_MMU_NOHASH=y # CONFIG_PPC_MM_SLICES is not set CONFIG_NOT_COHERENT_CACHE=y CONFIG_PPC32=y @@ -40,7 +41,7 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_PPC_OF=y CONFIG_OF=y @@ -71,12 +72,12 @@ CONFIG_POSIX_MQUEUE=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set CONFIG_GROUP_SCHED=y # CONFIG_FAIR_GROUP_SCHED is not set # CONFIG_RT_GROUP_SCHED is not set CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set +# CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set @@ -89,6 +90,7 @@ CONFIG_EMBEDDED=y CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y +CONFIG_KALLSYMS_STRIP_GENERATED=y CONFIG_KALLSYMS_EXTRA_PASS=y CONFIG_HOTPLUG=y CONFIG_PRINTK=y @@ -111,7 +113,6 @@ CONFIG_SLUB_DEBUG=y CONFIG_SLUB=y # CONFIG_SLOB is not set # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y @@ -122,7 +123,6 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -130,11 +130,9 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y CONFIG_LBD=y # CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -151,6 +149,10 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set # CONFIG_FREEZER is not set CONFIG_PPC4xx_PCI_EXPRESS=y @@ -182,6 +184,7 @@ CONFIG_405EX=y # CONFIG_GENERIC_IOMAP is not set # CONFIG_CPU_FREQ is not set # CONFIG_FSL_ULI1575 is not set +# CONFIG_SIMPLE_GPIO is not set # # Kernel options @@ -205,6 +208,7 @@ CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set # CONFIG_MATH_EMULATION is not set # CONFIG_IOMMU_HELPER is not set +CONFIG_PPC_NEED_DMA_SYNC_OPS=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_HAS_WALK_MEMORY=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y @@ -219,12 +223,14 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y -# CONFIG_RESOURCES_64BIT is not set # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_BOUNCE=y CONFIG_VIRT_TO_BUS=y CONFIG_UNEVICTABLE_LRU=y +CONFIG_PPC_4K_PAGES=y +# CONFIG_PPC_16K_PAGES is not set +# CONFIG_PPC_64K_PAGES is not set CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set @@ -248,6 +254,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y # CONFIG_PCI_MSI is not set CONFIG_PCI_LEGACY=y # CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_STUB is not set # CONFIG_PCCARD is not set # CONFIG_HOTPLUG_PCI is not set # CONFIG_HAS_RAPIDIO is not set @@ -272,6 +279,7 @@ CONFIG_NET=y # # Networking options # +CONFIG_COMPAT_NET_DEV_OPS=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -322,6 +330,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing @@ -334,6 +343,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set # CONFIG_PHONET is not set # CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -359,6 +369,7 @@ CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_REDBOOT_PARTS is not set CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_OF_PARTS=y @@ -430,6 +441,12 @@ CONFIG_MTD_PHYSMAP_OF=y # CONFIG_MTD_NAND is not set # CONFIG_MTD_ONENAND is not set +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set +# CONFIG_MTD_QINFO_PROBE is not set + # # UBI - Unsorted block images # @@ -524,6 +541,10 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set # CONFIG_IWLWIFI_LEDS is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -576,9 +597,12 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_HVC_UDBG is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set # CONFIG_NVRAM is not set @@ -597,11 +621,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y # CONFIG_HWMON is not set CONFIG_THERMAL=y # CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y # # Sonics Silicon Backplane # -CONFIG_SSB_POSSIBLE=y # CONFIG_SSB is not set # @@ -611,7 +635,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set -# CONFIG_MFD_WM8400 is not set +# CONFIG_REGULATOR is not set # # Multimedia devices @@ -670,7 +694,9 @@ CONFIG_EXT2_FS=y # CONFIG_FS_POSIX_ACL is not set CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -704,10 +730,7 @@ CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -717,6 +740,7 @@ CONFIG_TMPFS=y # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set CONFIG_CRAMFS=y +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -757,6 +781,7 @@ CONFIG_MSDOS_PARTITION=y # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set # CONFIG_CRC_T10DIF is not set @@ -807,6 +832,7 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set @@ -815,18 +841,24 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_NOP_TRACER=y -CONFIG_HAVE_FTRACE=y +CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y -# CONFIG_FTRACE is not set +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y + +# +# Tracers +# +# CONFIG_FUNCTION_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set # CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set # CONFIG_STACK_TRACER is not set # CONFIG_DYNAMIC_PRINTK_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set +CONFIG_PRINT_STACK_DEPTH=64 # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_PAGEALLOC is not set @@ -853,11 +885,15 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_FIPS is not set CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y # CONFIG_CRYPTO_GF128MUL is not set # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_CRYPTD is not set diff --git a/arch/powerpc/configs/40x/virtex_defconfig b/arch/powerpc/configs/40x/virtex_defconfig index 9a9350ded29..b6888384dd7 100644 --- a/arch/powerpc/configs/40x/virtex_defconfig +++ b/arch/powerpc/configs/40x/virtex_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.28-rc4 -# Fri Nov 14 10:49:16 2008 +# Linux kernel version: 2.6.29-rc2 +# Tue Jan 20 08:17:55 2009 # # CONFIG_PPC64 is not set @@ -15,6 +15,7 @@ CONFIG_40x=y # CONFIG_44x is not set # CONFIG_E200 is not set CONFIG_4xx=y +CONFIG_PPC_MMU_NOHASH=y # CONFIG_PPC_MM_SLICES is not set CONFIG_NOT_COHERENT_CACHE=y CONFIG_PPC32=y @@ -41,7 +42,7 @@ CONFIG_GENERIC_GPIO=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_PPC_OF=y CONFIG_OF=y @@ -74,8 +75,8 @@ CONFIG_POSIX_MQUEUE=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set @@ -113,7 +114,6 @@ CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y @@ -124,7 +124,6 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -132,11 +131,9 @@ CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODVERSIONS=y # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y # CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -153,6 +150,10 @@ CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set # CONFIG_FREEZER is not set # CONFIG_PPC4xx_PCI_EXPRESS is not set @@ -188,6 +189,7 @@ CONFIG_IBM405_ERR51=y # CONFIG_GENERIC_IOMAP is not set # CONFIG_CPU_FREQ is not set # CONFIG_FSL_ULI1575 is not set +# CONFIG_SIMPLE_GPIO is not set # # Kernel options @@ -205,13 +207,13 @@ CONFIG_HZ=250 # CONFIG_PREEMPT_NONE is not set # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y -# CONFIG_PREEMPT_RCU is not set CONFIG_BINFMT_ELF=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set # CONFIG_HAVE_AOUT is not set # CONFIG_BINFMT_MISC is not set CONFIG_MATH_EMULATION=y # CONFIG_IOMMU_HELPER is not set +CONFIG_PPC_NEED_DMA_SYNC_OPS=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_HAS_WALK_MEMORY=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y @@ -226,12 +228,14 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y -CONFIG_RESOURCES_64BIT=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_BOUNCE=y CONFIG_VIRT_TO_BUS=y CONFIG_UNEVICTABLE_LRU=y +CONFIG_PPC_4K_PAGES=y +# CONFIG_PPC_16K_PAGES is not set +# CONFIG_PPC_64K_PAGES is not set CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_PROC_DEVICETREE=y CONFIG_CMDLINE_BOOL=y @@ -256,6 +260,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y # CONFIG_PCI_MSI is not set CONFIG_PCI_LEGACY=y # CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_STUB is not set # CONFIG_PCCARD is not set # CONFIG_HOTPLUG_PCI is not set # CONFIG_HAS_RAPIDIO is not set @@ -280,6 +285,8 @@ CONFIG_NET=y # # Networking options # +# CONFIG_NET_NS is not set +CONFIG_COMPAT_NET_DEV_OPS=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -423,6 +430,7 @@ CONFIG_IP_NF_MANGLE=m # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing @@ -438,8 +446,9 @@ CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set CONFIG_WIRELESS_OLD_REGULATORY=y # CONFIG_WIRELESS_EXT is not set +# CONFIG_LIB80211 is not set # CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -574,6 +583,10 @@ CONFIG_NETDEV_1000=y # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set # CONFIG_IWLWIFI_LEDS is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -674,9 +687,12 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set # CONFIG_SERIAL_OF_PLATFORM is not set +# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_HVC_UDBG is not set # CONFIG_IPMI_HANDLER is not set CONFIG_HW_RANDOM=m # CONFIG_NVRAM is not set @@ -854,7 +870,6 @@ CONFIG_LOGO_LINUX_CLUT224=y # CONFIG_DMADEVICES is not set # CONFIG_UIO is not set # CONFIG_STAGING is not set -CONFIG_STAGING_EXCLUDE_BUILD=y # # File systems @@ -870,6 +885,7 @@ CONFIG_EXT2_FS=y CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -906,10 +922,7 @@ CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -918,6 +931,7 @@ CONFIG_TMPFS=y # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set CONFIG_CRAMFS=y +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -997,6 +1011,7 @@ CONFIG_NLS_UTF8=m # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=y # CONFIG_CRC16 is not set # CONFIG_CRC_T10DIF is not set @@ -1046,6 +1061,7 @@ CONFIG_DEBUG_INFO=y CONFIG_DEBUG_MEMORY_INIT=y # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set @@ -1055,6 +1071,8 @@ CONFIG_DEBUG_MEMORY_INIT=y # CONFIG_LATENCYTOP is not set CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y # # Tracers @@ -1064,11 +1082,13 @@ CONFIG_HAVE_FUNCTION_TRACER=y # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set # CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set # CONFIG_STACK_TRACER is not set # CONFIG_DYNAMIC_PRINTK_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set +CONFIG_PRINT_STACK_DEPTH=64 # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_PAGEALLOC is not set @@ -1094,6 +1114,7 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_FIPS is not set # CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_MANAGER2 is not set # CONFIG_CRYPTO_GF128MUL is not set # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_CRYPTD is not set diff --git a/arch/powerpc/configs/40x/walnut_defconfig b/arch/powerpc/configs/40x/walnut_defconfig index 5820e0a4fc5..5ab29dddd21 100644 --- a/arch/powerpc/configs/40x/walnut_defconfig +++ b/arch/powerpc/configs/40x/walnut_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.28-rc2 -# Tue Oct 28 08:49:27 2008 +# Linux kernel version: 2.6.29-rc2 +# Tue Jan 20 08:17:57 2009 # # CONFIG_PPC64 is not set @@ -15,6 +15,7 @@ CONFIG_40x=y # CONFIG_44x is not set # CONFIG_E200 is not set CONFIG_4xx=y +CONFIG_PPC_MMU_NOHASH=y # CONFIG_PPC_MM_SLICES is not set CONFIG_NOT_COHERENT_CACHE=y CONFIG_PPC32=y @@ -40,7 +41,7 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_PPC_OF=y CONFIG_OF=y @@ -71,12 +72,12 @@ CONFIG_POSIX_MQUEUE=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set CONFIG_GROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y # CONFIG_RT_GROUP_SCHED is not set CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set +# CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set @@ -89,6 +90,7 @@ CONFIG_EMBEDDED=y CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y +CONFIG_KALLSYMS_STRIP_GENERATED=y CONFIG_KALLSYMS_EXTRA_PASS=y CONFIG_HOTPLUG=y CONFIG_PRINTK=y @@ -111,7 +113,6 @@ CONFIG_SLUB_DEBUG=y CONFIG_SLUB=y # CONFIG_SLOB is not set # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y @@ -122,7 +123,6 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -130,11 +130,9 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y CONFIG_LBD=y # CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -151,6 +149,10 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set # CONFIG_FREEZER is not set # CONFIG_PPC4xx_PCI_EXPRESS is not set @@ -185,6 +187,7 @@ CONFIG_IBM405_ERR51=y # CONFIG_CPU_FREQ is not set # CONFIG_FSL_ULI1575 is not set CONFIG_OF_RTC=y +# CONFIG_SIMPLE_GPIO is not set # # Kernel options @@ -208,6 +211,7 @@ CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set # CONFIG_MATH_EMULATION is not set # CONFIG_IOMMU_HELPER is not set +CONFIG_PPC_NEED_DMA_SYNC_OPS=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_HAS_WALK_MEMORY=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y @@ -222,12 +226,14 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y -CONFIG_RESOURCES_64BIT=y # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_BOUNCE=y CONFIG_VIRT_TO_BUS=y CONFIG_UNEVICTABLE_LRU=y +CONFIG_PPC_4K_PAGES=y +# CONFIG_PPC_16K_PAGES is not set +# CONFIG_PPC_64K_PAGES is not set CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set @@ -251,6 +257,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y # CONFIG_PCI_MSI is not set # CONFIG_PCI_LEGACY is not set # CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_STUB is not set # CONFIG_PCCARD is not set # CONFIG_HOTPLUG_PCI is not set # CONFIG_HAS_RAPIDIO is not set @@ -275,6 +282,7 @@ CONFIG_NET=y # # Networking options # +CONFIG_COMPAT_NET_DEV_OPS=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -325,6 +333,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing @@ -337,6 +346,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_AF_RXRPC is not set # CONFIG_PHONET is not set # CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -362,6 +372,7 @@ CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_REDBOOT_PARTS is not set CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_OF_PARTS=y @@ -433,6 +444,12 @@ CONFIG_MTD_PHYSMAP_OF=y # CONFIG_MTD_NAND is not set # CONFIG_MTD_ONENAND is not set +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set +# CONFIG_MTD_QINFO_PROBE is not set + # # UBI - Unsorted block images # @@ -464,6 +481,7 @@ CONFIG_MISC_DEVICES=y # CONFIG_TIFM_CORE is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_HP_ILO is not set +# CONFIG_C2PORT is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -546,6 +564,7 @@ CONFIG_NETDEV_1000=y # CONFIG_JME is not set CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set +CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_CHELSIO_T3 is not set # CONFIG_ENIC is not set # CONFIG_IXGBE is not set @@ -568,6 +587,10 @@ CONFIG_NETDEV_10000=y # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set # CONFIG_IWLWIFI_LEDS is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -620,9 +643,12 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_HVC_UDBG is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set # CONFIG_NVRAM is not set @@ -641,11 +667,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y # CONFIG_HWMON is not set CONFIG_THERMAL=y # CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y # # Sonics Silicon Backplane # -CONFIG_SSB_POSSIBLE=y # CONFIG_SSB is not set # @@ -655,7 +681,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set -# CONFIG_MFD_WM8400 is not set +# CONFIG_REGULATOR is not set # # Multimedia devices @@ -701,9 +727,13 @@ CONFIG_USB_ARCH_HAS_EHCI=y # # -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; # # CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# # CONFIG_UWB is not set # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set @@ -729,7 +759,9 @@ CONFIG_EXT2_FS=y # CONFIG_FS_POSIX_ACL is not set CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -763,10 +795,7 @@ CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -776,6 +805,7 @@ CONFIG_TMPFS=y # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set CONFIG_CRAMFS=y +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -816,6 +846,7 @@ CONFIG_MSDOS_PARTITION=y # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set # CONFIG_CRC_T10DIF is not set @@ -866,6 +897,7 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set @@ -874,18 +906,24 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_NOP_TRACER=y -CONFIG_HAVE_FTRACE=y +CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y -# CONFIG_FTRACE is not set +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y + +# +# Tracers +# +# CONFIG_FUNCTION_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set # CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set # CONFIG_STACK_TRACER is not set # CONFIG_DYNAMIC_PRINTK_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set +CONFIG_PRINT_STACK_DEPTH=64 # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_PAGEALLOC is not set @@ -912,11 +950,15 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_FIPS is not set CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y # CONFIG_CRYPTO_GF128MUL is not set # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_CRYPTD is not set -- cgit From a5c7f4710fba334bf613d705f97b4471b36446f8 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Wed, 19 Mar 2008 22:02:40 +0100 Subject: firewire: insist on successive self ID complete events The whole topology code only works if the old and new topologies which are compared come from immediately successive self ID complete events. If there happened bus resets without self ID complete events in the meantime, or self ID complete events with invalid selfIDs, the topology comparison could identify nodes wrongly, or more likely just corrupt kernel memory or panic right away. We now discard all nodes of the old topology and treat all current nodes as new ones if the current self ID generation is not the previous one plus 1. Signed-off-by: Stefan Richter Signed-off-by: Jarod Wilson --- drivers/firewire/fw-topology.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c index c9be6e6948c..e7520e4bd6b 100644 --- a/drivers/firewire/fw-topology.c +++ b/drivers/firewire/fw-topology.c @@ -518,6 +518,18 @@ fw_core_handle_bus_reset(struct fw_card *card, struct fw_node *local_node; unsigned long flags; + /* + * If the selfID buffer is not the immediate successor of the + * previously processed one, we cannot reliably compare the + * old and new topologies. + */ + if ((generation & 0xff) != ((card->generation + 1) & 0xff) && + card->local_node != NULL) { + fw_notify("skipped bus generations, destroying all nodes\n"); + fw_destroy_nodes(card); + card->bm_retries = 0; + } + spin_lock_irqsave(&card->lock, flags); card->node_id = node_id; -- cgit From 8cd0bbbdff7471163cc6a058be8b8610ddd01d6b Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Mon, 24 Mar 2008 20:56:40 +0100 Subject: firewire: unnecessary BM delay after generation rollover Noticed by Jarod Wilson: The bus manager work was unnecessarily delayed each time the bus generation counter rolled over. Signed-off-by: Stefan Richter Signed-off-by: Jarod Wilson --- drivers/firewire/fw-card.c | 2 +- drivers/firewire/fw-topology.c | 2 +- drivers/firewire/fw-transaction.h | 9 +++++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c index 6bd91a15d5e..17a80cecdc1 100644 --- a/drivers/firewire/fw-card.c +++ b/drivers/firewire/fw-card.c @@ -232,7 +232,7 @@ fw_card_bm_work(struct work_struct *work) root_id = root_node->node_id; grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 10)); - if (card->bm_generation + 1 == generation || + if (is_next_generation(generation, card->bm_generation) || (card->bm_generation != generation && grace)) { /* * This first step is to figure out who is IRM and diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c index e7520e4bd6b..8dd6703b55c 100644 --- a/drivers/firewire/fw-topology.c +++ b/drivers/firewire/fw-topology.c @@ -523,7 +523,7 @@ fw_core_handle_bus_reset(struct fw_card *card, * previously processed one, we cannot reliably compare the * old and new topologies. */ - if ((generation & 0xff) != ((card->generation + 1) & 0xff) && + if (!is_next_generation(generation, card->generation) && card->local_node != NULL) { fw_notify("skipped bus generations, destroying all nodes\n"); fw_destroy_nodes(card); diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h index c9ab12a15f6..1d78e9cc594 100644 --- a/drivers/firewire/fw-transaction.h +++ b/drivers/firewire/fw-transaction.h @@ -275,6 +275,15 @@ static inline void fw_card_put(struct fw_card *card) extern void fw_schedule_bm_work(struct fw_card *card, unsigned long delay); +/* + * Check whether new_generation is the immediate successor of old_generation. + * Take counter roll-over at 255 (as per to OHCI) into account. + */ +static inline bool is_next_generation(int new_generation, int old_generation) +{ + return (new_generation & 0xff) == ((old_generation + 1) & 0xff); +} + /* * The iso packet format allows for an immediate header/payload part * stored in 'header' immediately after the packet info plus an -- cgit From 3d36a0df3b473fb53531484df227f2da8bc7494b Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 17 Jan 2009 22:45:54 +0100 Subject: firewire: keep highlevel drivers attached during brief connection loss There are situations when nodes vanish from the bus and come back quickly thereafter: - When certain bus-powered hubs are plugged in, - when certain devices are plugged into 6-port hubs, - when certain disk enclosures are switched from self-power to bus power or vice versa and break the daisy chain during the transition, - when the user plugs a cable out and quickly plugs it back in, e.g. to reorder a daisy chain (works on Mac OS X if done quickly enough), - when certain hubs temporarily malfunction during high bus traffic. Until now, firewire-core reported affected nodes as lost to the highlevel drivers (firewire-sbp2 and userspace drivers). We now delay the destruction of device representations until after at least two seconds after the last bus reset. If a "new" device is detected in this period whose bus information block and root directory header match that of a device which is pending for deletion, we resurrect that device and send update calls to highlevel drivers. Signed-off-by: Stefan Richter --- drivers/firewire/fw-device.c | 121 +++++++++++++++++++++++++++++++++++-------- drivers/firewire/fw-device.h | 1 + 2 files changed, 100 insertions(+), 22 deletions(-) diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c index 2af5a8d1e01..0925d91b261 100644 --- a/drivers/firewire/fw-device.c +++ b/drivers/firewire/fw-device.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -634,12 +635,38 @@ struct fw_device *fw_device_get_by_devt(dev_t devt) return device; } +/* + * These defines control the retry behavior for reading the config + * rom. It shouldn't be necessary to tweak these; if the device + * doesn't respond to a config rom read within 10 seconds, it's not + * going to respond at all. As for the initial delay, a lot of + * devices will be able to respond within half a second after bus + * reset. On the other hand, it's not really worth being more + * aggressive than that, since it scales pretty well; if 10 devices + * are plugged in, they're all getting read within one second. + */ + +#define MAX_RETRIES 10 +#define RETRY_DELAY (3 * HZ) +#define INITIAL_DELAY (HZ / 2) +#define SHUTDOWN_DELAY (2 * HZ) + static void fw_device_shutdown(struct work_struct *work) { struct fw_device *device = container_of(work, struct fw_device, work.work); int minor = MINOR(device->device.devt); + if (time_is_after_jiffies(device->card->reset_jiffies + SHUTDOWN_DELAY)) { + schedule_delayed_work(&device->work, SHUTDOWN_DELAY); + return; + } + + if (atomic_cmpxchg(&device->state, + FW_DEVICE_GONE, + FW_DEVICE_SHUTDOWN) != FW_DEVICE_GONE) + return; + fw_device_cdev_remove(device); device_for_each_child(&device->device, NULL, shutdown_unit); device_unregister(&device->device); @@ -647,6 +674,7 @@ static void fw_device_shutdown(struct work_struct *work) down_write(&fw_device_rwsem); idr_remove(&fw_device_idr, minor); up_write(&fw_device_rwsem); + fw_device_put(device); } @@ -654,25 +682,63 @@ static struct device_type fw_device_type = { .release = fw_device_release, }; +static void fw_device_update(struct work_struct *work); + /* - * These defines control the retry behavior for reading the config - * rom. It shouldn't be necessary to tweak these; if the device - * doesn't respond to a config rom read within 10 seconds, it's not - * going to respond at all. As for the initial delay, a lot of - * devices will be able to respond within half a second after bus - * reset. On the other hand, it's not really worth being more - * aggressive than that, since it scales pretty well; if 10 devices - * are plugged in, they're all getting read within one second. + * If a device was pending for deletion because its node went away but its + * bus info block and root directory header matches that of a newly discovered + * device, revive the existing fw_device. + * The newly allocated fw_device becomes obsolete instead. */ +static int lookup_existing_device(struct device *dev, void *data) +{ + struct fw_device *old = fw_device(dev); + struct fw_device *new = data; + struct fw_card *card = new->card; + int match = 0; + + down_read(&fw_device_rwsem); /* serialize config_rom access */ + spin_lock_irq(&card->lock); /* serialize node access */ + + if (memcmp(old->config_rom, new->config_rom, 6 * 4) == 0 && + atomic_cmpxchg(&old->state, + FW_DEVICE_GONE, + FW_DEVICE_RUNNING) == FW_DEVICE_GONE) { + struct fw_node *current_node = new->node; + struct fw_node *obsolete_node = old->node; + + new->node = obsolete_node; + new->node->data = new; + old->node = current_node; + old->node->data = old; + + old->max_speed = new->max_speed; + old->node_id = current_node->node_id; + smp_wmb(); /* update node_id before generation */ + old->generation = card->generation; + old->config_rom_retries = 0; + fw_notify("rediscovered device %s\n", dev_name(dev)); -#define MAX_RETRIES 10 -#define RETRY_DELAY (3 * HZ) -#define INITIAL_DELAY (HZ / 2) + PREPARE_DELAYED_WORK(&old->work, fw_device_update); + schedule_delayed_work(&old->work, 0); + + if (current_node == card->root_node) + fw_schedule_bm_work(card, 0); + + match = 1; + } + + spin_unlock_irq(&card->lock); + up_read(&fw_device_rwsem); + + return match; +} static void fw_device_init(struct work_struct *work) { struct fw_device *device = container_of(work, struct fw_device, work.work); + struct device *revived_dev; int minor, err; /* @@ -696,6 +762,15 @@ static void fw_device_init(struct work_struct *work) return; } + revived_dev = device_find_child(device->card->device, + device, lookup_existing_device); + if (revived_dev) { + put_device(revived_dev); + fw_device_release(&device->device); + + return; + } + device_initialize(&device->device); fw_device_get(device); @@ -734,9 +809,10 @@ static void fw_device_init(struct work_struct *work) * fw_node_event(). */ if (atomic_cmpxchg(&device->state, - FW_DEVICE_INITIALIZING, - FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) { - fw_device_shutdown(work); + FW_DEVICE_INITIALIZING, + FW_DEVICE_RUNNING) == FW_DEVICE_GONE) { + PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); + schedule_delayed_work(&device->work, SHUTDOWN_DELAY); } else { if (device->config_rom_retries) fw_notify("created device %s: GUID %08x%08x, S%d00, " @@ -847,8 +923,8 @@ static void fw_device_refresh(struct work_struct *work) case REREAD_BIB_UNCHANGED: if (atomic_cmpxchg(&device->state, - FW_DEVICE_INITIALIZING, - FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) + FW_DEVICE_INITIALIZING, + FW_DEVICE_RUNNING) == FW_DEVICE_GONE) goto gone; fw_device_update(work); @@ -879,8 +955,8 @@ static void fw_device_refresh(struct work_struct *work) create_units(device); if (atomic_cmpxchg(&device->state, - FW_DEVICE_INITIALIZING, - FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) + FW_DEVICE_INITIALIZING, + FW_DEVICE_RUNNING) == FW_DEVICE_GONE) goto gone; fw_notify("refreshed device %s\n", dev_name(&device->device)); @@ -890,8 +966,9 @@ static void fw_device_refresh(struct work_struct *work) give_up: fw_notify("giving up on refresh of device %s\n", dev_name(&device->device)); gone: - atomic_set(&device->state, FW_DEVICE_SHUTDOWN); - fw_device_shutdown(work); + atomic_set(&device->state, FW_DEVICE_GONE); + PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); + schedule_delayed_work(&device->work, SHUTDOWN_DELAY); out: if (node_id == card->root_node->node_id) fw_schedule_bm_work(card, 0); @@ -995,9 +1072,9 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) */ device = node->data; if (atomic_xchg(&device->state, - FW_DEVICE_SHUTDOWN) == FW_DEVICE_RUNNING) { + FW_DEVICE_GONE) == FW_DEVICE_RUNNING) { PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); - schedule_delayed_work(&device->work, 0); + schedule_delayed_work(&device->work, SHUTDOWN_DELAY); } break; } diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h index df51732608d..8ef6ec2ca21 100644 --- a/drivers/firewire/fw-device.h +++ b/drivers/firewire/fw-device.h @@ -28,6 +28,7 @@ enum fw_device_state { FW_DEVICE_INITIALIZING, FW_DEVICE_RUNNING, + FW_DEVICE_GONE, FW_DEVICE_SHUTDOWN, }; -- cgit From a9df80c5094ed2bac94f4a0d085651f44d549854 Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Tue, 20 Jan 2009 16:17:40 +0100 Subject: eeepc-laptop: split eeepc_backlight_exit() eeepc_backlight_exit() was doing rfkill and input stuff, which is a nonsense. This patch add two specific exit functions, one for input and one for rfkill. Signed-off-by: Corentin Chary Signed-off-by: Len Brown --- drivers/platform/x86/eeepc-laptop.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 9d93cb971e5..66d611b225f 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -737,13 +737,21 @@ static void eeepc_backlight_exit(void) { if (eeepc_backlight_device) backlight_device_unregister(eeepc_backlight_device); - if (ehotk->inputdev) - input_unregister_device(ehotk->inputdev); + eeepc_backlight_device = NULL; +} + +static void eeepc_rfkill_exit(void) +{ if (ehotk->eeepc_wlan_rfkill) rfkill_unregister(ehotk->eeepc_wlan_rfkill); if (ehotk->eeepc_bluetooth_rfkill) rfkill_unregister(ehotk->eeepc_bluetooth_rfkill); - eeepc_backlight_device = NULL; +} + +static void eeepc_input_exit(void) +{ + if (ehotk->inputdev) + input_unregister_device(ehotk->inputdev); } static void eeepc_hwmon_exit(void) @@ -762,6 +770,8 @@ static void eeepc_hwmon_exit(void) static void __exit eeepc_laptop_exit(void) { eeepc_backlight_exit(); + eeepc_rfkill_exit(); + eeepc_input_exit(); eeepc_hwmon_exit(); acpi_bus_unregister_driver(&eeepc_hotk_driver); sysfs_remove_group(&platform_device->dev.kobj, @@ -865,6 +875,8 @@ fail_platform_driver: fail_hwmon: eeepc_backlight_exit(); fail_backlight: + eeepc_input_exit(); + eeepc_rfkill_exit(); return result; } -- cgit From 1021e2119eb33a990a2b9ff1410805dd9bdf7997 Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Tue, 20 Jan 2009 16:17:41 +0100 Subject: asus_acpi: Add R1F support Add R1F support Signed-off-by: Corentin Chary Signed-off-by: Len Brown --- drivers/platform/x86/asus_acpi.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c index 1e74988c7b2..d63f26e666a 100644 --- a/drivers/platform/x86/asus_acpi.c +++ b/drivers/platform/x86/asus_acpi.c @@ -143,6 +143,7 @@ struct asus_hotk { S1300N, S5200N*/ A4S, /* Z81sp */ F3Sa, /* (Centrino) */ + R1F, END_MODEL } model; /* Models currently supported */ u16 event_count[128]; /* Count for each event TODO make this better */ @@ -420,7 +421,18 @@ static struct model_data model_conf[END_MODEL] = { .display_get = "\\ADVG", .display_set = "SDSP", }, - + { + .name = "R1F", + .mt_bt_switch = "BLED", + .mt_mled = "MLED", + .mt_wled = "WLED", + .mt_lcd_switch = "\\Q10", + .lcd_status = "\\GP06", + .brightness_set = "SPLV", + .brightness_get = "GPLV", + .display_set = "SDSP", + .display_get = "\\INFB" + } }; /* procdir we use */ @@ -1165,6 +1177,8 @@ static int asus_model_match(char *model) return W3V; else if (strncmp(model, "W5A", 3) == 0) return W5A; + else if (strncmp(model, "R1F", 3) == 0) + return R1F; else if (strncmp(model, "A4S", 3) == 0) return A4S; else if (strncmp(model, "F3Sa", 4) == 0) -- cgit From 2a7dc0d8c60325e9bf820900bf919430e5a419ab Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Tue, 20 Jan 2009 16:17:42 +0100 Subject: asus-laptop: use generic netlink interface To be prepared for /proc/acpi/event removal we export events also through generic netlink interface. Signed-off-by: Corentin Chary Signed-off-by: Len Brown --- drivers/platform/x86/asus-laptop.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index 8fb8b359104..1b7a28c1da7 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -738,8 +738,9 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) lcd_blank(FB_BLANK_POWERDOWN); } - acpi_bus_generate_proc_event(hotk->device, event, - hotk->event_count[event % 128]++); + acpi_bus_generate_netlink_event(hotk->device->pnp.device_class, + dev_name(&hotk->device->dev), event, + hotk->event_count[event % 128]++); return; } -- cgit From 034ce90a8d1051deaeb31bae7f26ff1440a5b988 Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Tue, 20 Jan 2009 16:17:43 +0100 Subject: asus-laptop: hotkeys via the generic input interface This patch is based on eeepc-laptop.c and the patchs from Nicolas Trangez and Daniel Nascimento (mainly for the keymap). Signed-off-by: Corentin Chary Signed-off-by: Len Brown --- drivers/platform/x86/asus-laptop.c | 155 ++++++++++++++++++++++++++++++++++++- 1 file changed, 154 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index 1b7a28c1da7..53dbfb42062 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -46,6 +46,7 @@ #include #include #include +#include #define ASUS_LAPTOP_VERSION "0.42" @@ -181,6 +182,8 @@ struct asus_hotk { u8 light_level; //light sensor level u8 light_switch; //light sensor switch value u16 event_count[128]; //count for each event TODO make this better + struct input_dev *inputdev; + u16 *keycode_map; }; /* @@ -250,6 +253,37 @@ ASUS_LED(rled, "record"); ASUS_LED(pled, "phone"); ASUS_LED(gled, "gaming"); +struct key_entry { + char type; + u8 code; + u16 keycode; +}; + +enum { KE_KEY, KE_END }; + +static struct key_entry asus_keymap[] = { + {KE_KEY, 0x30, KEY_VOLUMEUP}, + {KE_KEY, 0x31, KEY_VOLUMEDOWN}, + {KE_KEY, 0x32, KEY_MUTE}, + {KE_KEY, 0x33, KEY_SWITCHVIDEOMODE}, + {KE_KEY, 0x34, KEY_SWITCHVIDEOMODE}, + {KE_KEY, 0x40, KEY_PREVIOUSSONG}, + {KE_KEY, 0x41, KEY_NEXTSONG}, + {KE_KEY, 0x43, KEY_STOP}, + {KE_KEY, 0x45, KEY_PLAYPAUSE}, + {KE_KEY, 0x50, KEY_EMAIL}, + {KE_KEY, 0x51, KEY_WWW}, + {KE_KEY, 0x5C, BTN_EXTRA}, /* Performance */ + {KE_KEY, 0x5D, KEY_WLAN}, + {KE_KEY, 0x61, KEY_SWITCHVIDEOMODE}, + {KE_KEY, 0x6B, BTN_TOUCH}, /* Lock Mouse */ + {KE_KEY, 0x82, KEY_CAMERA}, + {KE_KEY, 0x8A, KEY_TV}, + {KE_KEY, 0x95, KEY_MEDIA}, + {KE_KEY, 0x99, KEY_PHONE}, + {KE_END, 0}, +}; + /* * This function evaluates an ACPI method, given an int as parameter, the * method is searched within the scope of the handle, can be NULL. The output @@ -720,8 +754,68 @@ static ssize_t store_gps(struct device *dev, struct device_attribute *attr, return store_status(buf, count, NULL, GPS_ON); } +/* + * Hotkey functions + */ +static struct key_entry *asus_get_entry_by_scancode(int code) +{ + struct key_entry *key; + + for (key = asus_keymap; key->type != KE_END; key++) + if (code == key->code) + return key; + + return NULL; +} + +static struct key_entry *asus_get_entry_by_keycode(int code) +{ + struct key_entry *key; + + for (key = asus_keymap; key->type != KE_END; key++) + if (code == key->keycode && key->type == KE_KEY) + return key; + + return NULL; +} + +static int asus_getkeycode(struct input_dev *dev, int scancode, int *keycode) +{ + struct key_entry *key = asus_get_entry_by_scancode(scancode); + + if (key && key->type == KE_KEY) { + *keycode = key->keycode; + return 0; + } + + return -EINVAL; +} + +static int asus_setkeycode(struct input_dev *dev, int scancode, int keycode) +{ + struct key_entry *key; + int old_keycode; + + if (keycode < 0 || keycode > KEY_MAX) + return -EINVAL; + + key = asus_get_entry_by_scancode(scancode); + if (key && key->type == KE_KEY) { + old_keycode = key->keycode; + key->keycode = keycode; + set_bit(keycode, dev->keybit); + if (!asus_get_entry_by_keycode(old_keycode)) + clear_bit(old_keycode, dev->keybit); + return 0; + } + + return -EINVAL; +} + static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) { + static struct key_entry *key; + /* TODO Find a better way to handle events count. */ if (!hotk) return; @@ -742,7 +836,20 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) dev_name(&hotk->device->dev), event, hotk->event_count[event % 128]++); - return; + if (hotk->inputdev) { + key = asus_get_entry_by_scancode(event); + if (!key) + return ; + + switch (key->type) { + case KE_KEY: + input_report_key(hotk->inputdev, key->keycode, 1); + input_sync(hotk->inputdev); + input_report_key(hotk->inputdev, key->keycode, 0); + input_sync(hotk->inputdev); + break; + } + } } #define ASUS_CREATE_DEVICE_ATTR(_name) \ @@ -960,6 +1067,38 @@ static int asus_hotk_get_info(void) return AE_OK; } +static int asus_input_init(void) +{ + const struct key_entry *key; + int result; + + hotk->inputdev = input_allocate_device(); + if (!hotk->inputdev) { + printk(ASUS_INFO "Unable to allocate input device\n"); + return 0; + } + hotk->inputdev->name = "Asus Laptop extra buttons"; + hotk->inputdev->phys = ASUS_HOTK_FILE "/input0"; + hotk->inputdev->id.bustype = BUS_HOST; + hotk->inputdev->getkeycode = asus_getkeycode; + hotk->inputdev->setkeycode = asus_setkeycode; + + for (key = asus_keymap; key->type != KE_END; key++) { + switch (key->type) { + case KE_KEY: + set_bit(EV_KEY, hotk->inputdev->evbit); + set_bit(key->keycode, hotk->inputdev->keybit); + break; + } + } + result = input_register_device(hotk->inputdev); + if (result) { + printk(ASUS_INFO "Unable to register input device\n"); + input_free_device(hotk->inputdev); + } + return result; +} + static int asus_hotk_check(void) { int result = 0; @@ -1092,10 +1231,17 @@ static void asus_led_exit(void) ASUS_LED_UNREGISTER(gled); } +static void asus_input_exit(void) +{ + if (hotk->inputdev) + input_unregister_device(hotk->inputdev); +} + static void __exit asus_laptop_exit(void) { asus_backlight_exit(); asus_led_exit(); + asus_input_exit(); acpi_bus_unregister_driver(&asus_hotk_driver); sysfs_remove_group(&asuspf_device->dev.kobj, &asuspf_attribute_group); @@ -1217,6 +1363,10 @@ static int __init asus_laptop_init(void) printk(ASUS_INFO "Brightness ignored, must be controlled by " "ACPI video driver\n"); + result = asus_input_init(); + if (result) + goto fail_input; + result = asus_led_init(dev); if (result) goto fail_led; @@ -1256,6 +1406,9 @@ static int __init asus_laptop_init(void) asus_led_exit(); fail_led: + asus_input_exit(); + + fail_input: asus_backlight_exit(); fail_backlight: -- cgit From 12d6f35b0ff1f446d465e95e9a2fe187263479ef Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Tue, 20 Jan 2009 16:17:44 +0100 Subject: asus-laptop: update Kconfig for input layer Update Kconfig, now asus-laptop use the input layer. Signed-off-by: Corentin Chary Signed-off-by: Len Brown --- drivers/platform/x86/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 1a266d4ab5f..94363115a42 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -42,6 +42,7 @@ config ASUS_LAPTOP depends on LEDS_CLASS depends on NEW_LEDS depends on BACKLIGHT_CLASS_DEVICE + depends on INPUT ---help--- This is the new Linux driver for Asus laptops. It may also support some MEDION, JVC or VICTOR laptops. It makes all the extra buttons generate -- cgit From ed6f44215374d94c35cbe98b582d004b9a3f5fbe Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Tue, 20 Jan 2009 16:17:45 +0100 Subject: asus-laptop: fix label indentation Fix the label indentation Signed-off-by: Corentin Chary Signed-off-by: Len Brown --- drivers/platform/x86/asus-laptop.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index 53dbfb42062..56af6cf385b 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -1184,7 +1184,7 @@ static int asus_hotk_add(struct acpi_device *device) /* GPS is on by default */ write_status(NULL, 1, GPS_ON); - end: +end: if (result) { kfree(hotk->name); kfree(hotk); @@ -1393,25 +1393,25 @@ static int __init asus_laptop_init(void) return 0; - fail_sysfs: +fail_sysfs: platform_device_del(asuspf_device); - fail_platform_device2: +fail_platform_device2: platform_device_put(asuspf_device); - fail_platform_device1: +fail_platform_device1: platform_driver_unregister(&asuspf_driver); - fail_platform_driver: +fail_platform_driver: asus_led_exit(); - fail_led: +fail_led: asus_input_exit(); - fail_input: +fail_input: asus_backlight_exit(); - fail_backlight: +fail_backlight: return result; } -- cgit From b5f6f26550700445dcc125bbf75b9104e779d353 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 20 Jan 2009 16:17:46 +0100 Subject: eeepc-laptop: Add support for extended hotkeys Newer Eees have extra hotkeys above the function keys. This patch adds support for sending them through the input layer. Signed-off-by: Matthew Garrett Signed-off-by: Corentin Chary Signed-off-by: Len Brown --- drivers/platform/x86/eeepc-laptop.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 66d611b225f..d153871fd5a 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -161,6 +161,10 @@ static struct key_entry eeepc_keymap[] = { {KE_KEY, 0x13, KEY_MUTE }, {KE_KEY, 0x14, KEY_VOLUMEDOWN }, {KE_KEY, 0x15, KEY_VOLUMEUP }, + {KE_KEY, 0x1a, KEY_COFFEE }, + {KE_KEY, 0x1b, KEY_ZOOM }, + {KE_KEY, 0x1c, KEY_PROG2 }, + {KE_KEY, 0x1d, KEY_PROG3 }, {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE }, {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE }, {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE }, -- cgit From c9ddf8fede1271bde0a512fa94f77c4cb1ef4040 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 20 Jan 2009 16:17:47 +0100 Subject: eeepc-laptop: Check return values from rfkill_register Error out if rfkill registration fails, and also set the default system state appropriately on boot Signed-off-by: Matthew Garrett Signed-off-by: Corentin Chary Signed-off-by: Len Brown --- drivers/platform/x86/eeepc-laptop.c | 51 +++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index d153871fd5a..21e5206ed28 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -562,7 +562,7 @@ static int eeepc_hotk_add(struct acpi_device *device) ehotk->device = device; result = eeepc_hotk_check(); if (result) - goto end; + goto ehotk_fail; status = acpi_install_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY, eeepc_hotk_notify, ehotk); if (ACPI_FAILURE(status)) @@ -573,18 +573,25 @@ static int eeepc_hotk_add(struct acpi_device *device) RFKILL_TYPE_WLAN); if (!ehotk->eeepc_wlan_rfkill) - goto end; + goto wlan_fail; ehotk->eeepc_wlan_rfkill->name = "eeepc-wlan"; ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set; ehotk->eeepc_wlan_rfkill->get_state = eeepc_wlan_rfkill_state; - if (get_acpi(CM_ASL_WLAN) == 1) + if (get_acpi(CM_ASL_WLAN) == 1) { ehotk->eeepc_wlan_rfkill->state = RFKILL_STATE_UNBLOCKED; - else + rfkill_set_default(RFKILL_TYPE_WLAN, + RFKILL_STATE_UNBLOCKED); + } else { ehotk->eeepc_wlan_rfkill->state = RFKILL_STATE_SOFT_BLOCKED; - rfkill_register(ehotk->eeepc_wlan_rfkill); + rfkill_set_default(RFKILL_TYPE_WLAN, + RFKILL_STATE_SOFT_BLOCKED); + } + result = rfkill_register(ehotk->eeepc_wlan_rfkill); + if (result) + goto wlan_fail; } if (get_acpi(CM_ASL_BLUETOOTH) != -1) { @@ -592,27 +599,43 @@ static int eeepc_hotk_add(struct acpi_device *device) rfkill_allocate(&device->dev, RFKILL_TYPE_BLUETOOTH); if (!ehotk->eeepc_bluetooth_rfkill) - goto end; + goto bluetooth_fail; ehotk->eeepc_bluetooth_rfkill->name = "eeepc-bluetooth"; ehotk->eeepc_bluetooth_rfkill->toggle_radio = eeepc_bluetooth_rfkill_set; ehotk->eeepc_bluetooth_rfkill->get_state = eeepc_bluetooth_rfkill_state; - if (get_acpi(CM_ASL_BLUETOOTH) == 1) + if (get_acpi(CM_ASL_BLUETOOTH) == 1) { ehotk->eeepc_bluetooth_rfkill->state = RFKILL_STATE_UNBLOCKED; - else + rfkill_set_default(RFKILL_TYPE_BLUETOOTH, + RFKILL_STATE_UNBLOCKED); + } else { ehotk->eeepc_bluetooth_rfkill->state = RFKILL_STATE_SOFT_BLOCKED; - rfkill_register(ehotk->eeepc_bluetooth_rfkill); - } + rfkill_set_default(RFKILL_TYPE_BLUETOOTH, + RFKILL_STATE_SOFT_BLOCKED); + } - end: - if (result) { - kfree(ehotk); - ehotk = NULL; + result = rfkill_register(ehotk->eeepc_bluetooth_rfkill); + if (result) + goto bluetooth_fail; } + return 0; + + bluetooth_fail: + if (ehotk->eeepc_bluetooth_rfkill) + rfkill_free(ehotk->eeepc_bluetooth_rfkill); + rfkill_unregister(ehotk->eeepc_wlan_rfkill); + ehotk->eeepc_wlan_rfkill = NULL; + wlan_fail: + if (ehotk->eeepc_wlan_rfkill) + rfkill_free(ehotk->eeepc_wlan_rfkill); + ehotk_fail: + kfree(ehotk); + ehotk = NULL; + return result; } -- cgit From 5740294ca3a9b113fe146f2826effb69ca50008d Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 20 Jan 2009 16:17:48 +0100 Subject: eeepc-laptop: Implement rfkill hotplugging in eeepc-laptop The Eee implements rfkill by logically unplugging the wireless card from the PCI bus. Despite sending ACPI notifications, this does not appear to be implemented using standard ACPI hotplug - nor does the firmware provide the _OSC method required to support native PCIe hotplug. The only sensible choice appears to be to handle the hotplugging directly in the eeepc-laptop driver. Tested successfully on a 700, 900 and 901. Signed-off-by: Matthew Garrett Signed-off-by: Corentin Chary Signed-off-by: Len Brown --- drivers/platform/x86/eeepc-laptop.c | 83 +++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 21e5206ed28..66655d2b4ce 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -30,6 +30,7 @@ #include #include #include +#include #define EEEPC_LAPTOP_VERSION "0.1" @@ -517,6 +518,41 @@ static void notify_brn(void) bd->props.brightness = read_brightness(bd); } +static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) +{ + struct pci_dev *dev; + struct pci_bus *bus = pci_find_bus(0, 1); + + if (event != ACPI_NOTIFY_BUS_CHECK) + return; + + if (!bus) { + printk(EEEPC_WARNING "Unable to find PCI bus 1?\n"); + return; + } + + if (get_acpi(CM_ASL_WLAN) == 1) { + dev = pci_get_slot(bus, 0); + if (dev) { + /* Device already present */ + pci_dev_put(dev); + return; + } + dev = pci_scan_single_device(bus, 0); + if (dev) { + pci_bus_assign_resources(bus); + if (pci_bus_add_device(dev)) + printk(EEEPC_ERR "Unable to hotplug wifi\n"); + } + } else { + dev = pci_get_slot(bus, 0); + if (dev) { + pci_remove_bus_device(dev); + pci_dev_put(dev); + } + } +} + static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) { static struct key_entry *key; @@ -543,6 +579,45 @@ static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) } } +static int eeepc_register_rfkill_notifier(char *node) +{ + acpi_status status = AE_OK; + acpi_handle handle; + + status = acpi_get_handle(NULL, node, &handle); + + if (ACPI_SUCCESS(status)) { + status = acpi_install_notify_handler(handle, + ACPI_SYSTEM_NOTIFY, + eeepc_rfkill_notify, + NULL); + if (ACPI_FAILURE(status)) + printk(EEEPC_WARNING + "Failed to register notify on %s\n", node); + } else + return -ENODEV; + + return 0; +} + +static void eeepc_unregister_rfkill_notifier(char *node) +{ + acpi_status status = AE_OK; + acpi_handle handle; + + status = acpi_get_handle(NULL, node, &handle); + + if (ACPI_SUCCESS(status)) { + status = acpi_remove_notify_handler(handle, + ACPI_SYSTEM_NOTIFY, + eeepc_rfkill_notify); + if (ACPI_FAILURE(status)) + printk(EEEPC_ERR + "Error removing rfkill notify handler %s\n", + node); + } +} + static int eeepc_hotk_add(struct acpi_device *device) { acpi_status status = AE_OK; @@ -622,6 +697,10 @@ static int eeepc_hotk_add(struct acpi_device *device) if (result) goto bluetooth_fail; } + + eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); + eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); + return 0; bluetooth_fail: @@ -649,6 +728,10 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type) eeepc_hotk_notify); if (ACPI_FAILURE(status)) printk(EEEPC_ERR "Error removing notify handler\n"); + + eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); + eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); + kfree(ehotk); return 0; } -- cgit From 2b25c9f01aa58d48129b2f93748dfb5d1f7ab0a2 Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Tue, 20 Jan 2009 16:17:49 +0100 Subject: eeepc-laptop: use netlink interface To be prepared for /proc/acpi/event removal we export events also through generic netlink interface. Signed-off-by: Corentin Chary Signed-off-by: Len Brown --- drivers/platform/x86/eeepc-laptop.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 66655d2b4ce..4348d9909bb 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -560,8 +560,9 @@ static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) return; if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) notify_brn(); - acpi_bus_generate_proc_event(ehotk->device, event, - ehotk->event_count[event % 128]++); + acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class, + dev_name(&ehotk->device->dev), event, + ehotk->event_count[event % 128]++); if (ehotk->inputdev) { key = eepc_get_entry_by_scancode(event); if (key) { -- cgit From 8a9dee59a345f96757dd45699de1c4182d8bf9a9 Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Mon, 19 Jan 2009 17:14:24 -0600 Subject: ASoC: fix registration of the SoC card in the Freescale MPC8610 drivers The Freescale MPC8610 driver was defining two SOC card (snd_soc_card) structures, partially initializing each one, but registering only one of them with ASoC. Signed-off-by: Timur Tabi Signed-off-by: Mark Brown --- sound/soc/fsl/mpc8610_hpcd.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c index bcec3f60bad..acf39a646b2 100644 --- a/sound/soc/fsl/mpc8610_hpcd.c +++ b/sound/soc/fsl/mpc8610_hpcd.c @@ -182,16 +182,6 @@ static struct snd_soc_ops mpc8610_hpcd_ops = { .startup = mpc8610_hpcd_startup, }; -/** - * mpc8610_hpcd_machine: ASoC machine data - */ -static struct snd_soc_card mpc8610_hpcd_machine = { - .probe = mpc8610_hpcd_machine_probe, - .remove = mpc8610_hpcd_machine_remove, - .name = "MPC8610 HPCD", - .num_links = 1, -}; - /** * mpc8610_hpcd_probe: OF probe function for the fabric driver * @@ -455,7 +445,11 @@ static int mpc8610_hpcd_probe(struct of_device *ofdev, machine_data->dai.codec_dai = &cs4270_dai; /* The codec_dai we want */ machine_data->dai.ops = &mpc8610_hpcd_ops; - mpc8610_hpcd_machine.dai_link = &machine_data->dai; + machine_data->machine.probe = mpc8610_hpcd_machine_probe; + machine_data->machine.remove = mpc8610_hpcd_machine_remove; + machine_data->machine.name = "MPC8610 HPCD"; + machine_data->machine.num_links = 1; + machine_data->machine.dai_link = &machine_data->dai; /* Allocate a new audio platform device structure */ sound_device = platform_device_alloc("soc-audio", -1); @@ -465,7 +459,7 @@ static int mpc8610_hpcd_probe(struct of_device *ofdev, goto error; } - machine_data->sound_devdata.card = &mpc8610_hpcd_machine; + machine_data->sound_devdata.card = &machine_data->machine; machine_data->sound_devdata.codec_dev = &soc_codec_device_cs4270; machine_data->machine.platform = &fsl_soc_platform; -- cgit From 357f5b0b91054ae23385ea4b0634bb8b43736e83 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Sat, 17 Jan 2009 06:47:12 +0000 Subject: NET: net_namespace, fix lock imbalance register_pernet_gen_subsys omits mutex_unlock in one fail path. Fix it. Signed-off-by: Jiri Slaby Signed-off-by: David S. Miller --- net/core/net_namespace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 55cffad2f32..55151faaf90 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -341,8 +341,8 @@ again: rv = register_pernet_operations(first_device, ops); if (rv < 0) ida_remove(&net_generic_ids, *id); - mutex_unlock(&net_mutex); out: + mutex_unlock(&net_mutex); return rv; } EXPORT_SYMBOL_GPL(register_pernet_gen_subsys); -- cgit From e3fd553468738e0342cbd82a63ede00c983a0eb4 Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Sat, 17 Jan 2009 08:27:19 +0000 Subject: myri10ge: don't forget pci_disable_device() Don't forget to call pci_disable_device() in myri10ge_remove() and when myri10ge_probe() fails. By the way, update the copyright years. Signed-off-by: Brice Goglin Signed-off-by: David S. Miller --- drivers/net/myri10ge/myri10ge.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 6bb71b687f7..e9c1296b267 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -1,7 +1,7 @@ /************************************************************************* * myri10ge.c: Myricom Myri-10G Ethernet driver. * - * Copyright (C) 2005 - 2007 Myricom, Inc. + * Copyright (C) 2005 - 2009 Myricom, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -75,7 +75,7 @@ #include "myri10ge_mcp.h" #include "myri10ge_mcp_gen_header.h" -#define MYRI10GE_VERSION_STR "1.4.4-1.398" +#define MYRI10GE_VERSION_STR "1.4.4-1.401" MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); MODULE_AUTHOR("Maintainer: help@myri.com"); @@ -3786,7 +3786,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (status != 0) { dev_err(&pdev->dev, "Error %d writing PCI_EXP_DEVCTL\n", status); - goto abort_with_netdev; + goto abort_with_enabled; } pci_set_master(pdev); @@ -3801,13 +3801,13 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } if (status != 0) { dev_err(&pdev->dev, "Error %d setting DMA mask\n", status); - goto abort_with_netdev; + goto abort_with_enabled; } (void)pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); mgp->cmd = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->cmd), &mgp->cmd_bus, GFP_KERNEL); if (mgp->cmd == NULL) - goto abort_with_netdev; + goto abort_with_enabled; mgp->board_span = pci_resource_len(pdev, 0); mgp->iomem_base = pci_resource_start(pdev, 0); @@ -3943,8 +3943,10 @@ abort_with_mtrr: dma_free_coherent(&pdev->dev, sizeof(*mgp->cmd), mgp->cmd, mgp->cmd_bus); -abort_with_netdev: +abort_with_enabled: + pci_disable_device(pdev); +abort_with_netdev: free_netdev(netdev); return status; } @@ -3990,6 +3992,7 @@ static void myri10ge_remove(struct pci_dev *pdev) mgp->cmd, mgp->cmd_bus); free_netdev(netdev); + pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); } -- cgit From 0d1cfd20cc5f785d5345d249d4b6a6f84b29e6a6 Mon Sep 17 00:00:00 2001 From: roel kluin Date: Sat, 17 Jan 2009 11:14:31 +0000 Subject: via-velocity: fix hot spin while(--j >= 0) keeps spinning when j is unsigned: Signed-off-by: Roel Kluin Signed-off-by: David S. Miller --- drivers/net/via-velocity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index a75f91dc315..c5691fdb707 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -1302,7 +1302,7 @@ static void velocity_free_rd_ring(struct velocity_info *vptr) static int velocity_init_td_ring(struct velocity_info *vptr) { dma_addr_t curr; - unsigned int j; + int j; /* Init the TD ring entries */ for (j = 0; j < vptr->tx.numq; j++) { -- cgit From ebad18e93fbc6bc63ee734edbc0eb38ac6b919c0 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sat, 17 Jan 2009 19:46:16 +0000 Subject: gro: Fix handling of complete checksums in IPv6 We need to perform skb_postpull_rcsum after pulling the IPv6 header in order to maintain the correctness of the complete checksum. This patch also adds a missing iph reload after pulling. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/ipv6/af_inet6.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 94f74f5b0cb..c802bc1658a 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -797,6 +797,7 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head, unsigned int nlen; int flush = 1; int proto; + __wsum csum; if (unlikely(!pskb_may_pull(skb, sizeof(*iph)))) goto out; @@ -808,6 +809,7 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head, rcu_read_lock(); proto = ipv6_gso_pull_exthdrs(skb, iph->nexthdr); + iph = ipv6_hdr(skb); IPV6_GRO_CB(skb)->proto = proto; ops = rcu_dereference(inet6_protos[proto]); if (!ops || !ops->gro_receive) @@ -839,8 +841,13 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head, NAPI_GRO_CB(skb)->flush |= flush; + csum = skb->csum; + skb_postpull_rcsum(skb, iph, skb_network_header_len(skb)); + pp = ops->gro_receive(head, skb); + skb->csum = csum; + out_unlock: rcu_read_unlock(); -- cgit From 9a8e47ffd95608f0768e1a8a0225c822aa53aa9b Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sat, 17 Jan 2009 19:47:18 +0000 Subject: gro: Fix error handling on extremely short frags When a frag is shorter than an Ethernet header, we'd return a zeroed packet instead of aborting. This patch fixes that. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/core/dev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/core/dev.c b/net/core/dev.c index 6e44c327710..5379b0c1190 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2536,6 +2536,7 @@ struct sk_buff *napi_fraginfo_skb(struct napi_struct *napi, if (!pskb_may_pull(skb, ETH_HLEN)) { napi_reuse_skb(napi, skb); + skb = NULL; goto out; } -- cgit From 37fe4732b978eb02e5433387a40f2b61706cebe3 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sat, 17 Jan 2009 19:48:13 +0000 Subject: gro: Fix merging of paged packets The previous fix to paged packets broke the merging because it reset the skb->len before we added it to the merged packet. This wasn't detected because it simply resulted in the truncation of the packet while the missing bit is subsequently retransmitted. The fix is to store skb->len before we clobber it. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/core/skbuff.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 56272ac6dfd..2e5f2ca3bdc 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -2585,8 +2585,9 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) struct sk_buff *nskb; unsigned int headroom; unsigned int hlen = p->data - skb_mac_header(p); + unsigned int len = skb->len; - if (hlen + p->len + skb->len >= 65536) + if (hlen + p->len + len >= 65536) return -E2BIG; if (skb_shinfo(p)->frag_list) @@ -2648,9 +2649,9 @@ merge: done: NAPI_GRO_CB(p)->count++; - p->data_len += skb->len; - p->truesize += skb->len; - p->len += skb->len; + p->data_len += len; + p->truesize += len; + p->len += len; NAPI_GRO_CB(skb)->same_flow = 1; return 0; -- cgit From 65557f350749e11d51d15dee759d6e04f290e256 Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Tue, 20 Jan 2009 16:50:25 -0500 Subject: ALSA: hda: 83xxx port 0xe DAC selection On the 92hd8xxx codecs port 0xe needs the connection selected to be the last DAC in the list. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index a4d4afe6b4f..3b97d1eff92 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -841,10 +841,6 @@ static struct hda_verb stac92hd73xx_10ch_core_init[] = { }; static struct hda_verb stac92hd83xxx_core_init[] = { - /* start of config #1 */ - { 0xe, AC_VERB_SET_CONNECT_SEL, 0x3}, - - /* start of config #2 */ { 0xa, AC_VERB_SET_CONNECT_SEL, 0x0}, { 0xb, AC_VERB_SET_CONNECT_SEL, 0x0}, { 0xd, AC_VERB_SET_CONNECT_SEL, 0x1}, @@ -4754,7 +4750,9 @@ static struct hda_input_mux stac92hd83xxx_dmux = { static int patch_stac92hd83xxx(struct hda_codec *codec) { struct sigmatel_spec *spec; + hda_nid_t conn[STAC92HD83_DAC_COUNT + 1]; int err; + int num_dacs; spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) @@ -4773,13 +4771,21 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); spec->multiout.dac_nids = spec->dac_nids; + + /* set port 0xe to select the last DAC + */ + num_dacs = snd_hda_get_connections(codec, 0x0e, + conn, STAC92HD83_DAC_COUNT + 1) - 1; + + snd_hda_codec_write_cache(codec, 0xe, 0, + AC_VERB_SET_CONNECT_SEL, num_dacs); + spec->init = stac92hd83xxx_core_init; switch (codec->vendor_id) { case 0x111d7605: break; default: spec->num_pwrs--; - spec->init++; /* switch to config #2 */ } spec->mixer = stac92hd83xxx_mixer; -- cgit From 26a552264bc92d2ec4747b1babb7cb1264908018 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Wed, 21 Jan 2009 11:29:19 +0800 Subject: [ARM] pxa: stop and disable IRQ for each DMA channels at startup Some broken bootloaders will leave the DMA channel state unclean, which we should really initialize correctly here. Signed-off-by: Eric Miao --- arch/arm/mach-pxa/dma.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-pxa/dma.c b/arch/arm/mach-pxa/dma.c index b1514fb20d3..7de17fc5d54 100644 --- a/arch/arm/mach-pxa/dma.c +++ b/arch/arm/mach-pxa/dma.c @@ -121,20 +121,22 @@ int __init pxa_init_dma(int num_ch) if (dma_channels == NULL) return -ENOMEM; - ret = request_irq(IRQ_DMA, dma_irq_handler, IRQF_DISABLED, "DMA", NULL); - if (ret) { - printk (KERN_CRIT "Wow! Can't register IRQ for DMA\n"); - kfree(dma_channels); - return ret; - } - /* dma channel priorities on pxa2xx processors: * ch 0 - 3, 16 - 19 <--> (0) DMA_PRIO_HIGH * ch 4 - 7, 20 - 23 <--> (1) DMA_PRIO_MEDIUM * ch 8 - 15, 24 - 31 <--> (2) DMA_PRIO_LOW */ - for (i = 0; i < num_ch; i++) + for (i = 0; i < num_ch; i++) { + DCSR(i) = 0; dma_channels[i].prio = min((i & 0xf) >> 2, DMA_PRIO_LOW); + } + + ret = request_irq(IRQ_DMA, dma_irq_handler, IRQF_DISABLED, "DMA", NULL); + if (ret) { + printk (KERN_CRIT "Wow! Can't register IRQ for DMA\n"); + kfree(dma_channels); + return ret; + } num_dma_channels = num_ch; return 0; -- cgit From 7143f7a1a3603002e4ef3719fa92e8dd6e607099 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 9 Jan 2009 22:27:42 -0800 Subject: driver core: Convert '/' to '!' in dev_set_name() Commit 3ada8b7e ("block: struct device - replace bus_id with dev_name(), dev_set_name()") deleted the code in register_disk() that changed a '/' to a '!' in the device name when registering a disk, but dev_set_name() does not perform this conversion. This leads to amusing problems with disks that have '/' in their names: for example a failure to boot with the root partition on a cciss device, even though the kernel says it knows about the root device: VFS: Cannot open root device "cciss/c0d0p6" or unknown-block(0,0) Please append a correct "root=" boot option; here are the available partitions: 6800 71652960 cciss/c0d0 driver: cciss 6802 1 cciss/c0d0p2 6805 2931831 cciss/c0d0p5 6806 34354908 cciss/c0d0p6 6810 71652960 cciss/c0d1 driver: cciss Fix this by adding code to change '/' to '!' in dev_set_name() to handle this until dev_set_name() is converted to use kobject_set_name(). Signed-off-by: Roland Dreier Acked-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/base/core.c b/drivers/base/core.c index 8079afca497..55e530942ab 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -777,10 +777,16 @@ static void device_remove_class_symlinks(struct device *dev) int dev_set_name(struct device *dev, const char *fmt, ...) { va_list vargs; + char *s; va_start(vargs, fmt); vsnprintf(dev->bus_id, sizeof(dev->bus_id), fmt, vargs); va_end(vargs); + + /* ewww... some of these buggers have / in the name... */ + while ((s = strchr(dev->bus_id, '/'))) + *s = '!'; + return 0; } EXPORT_SYMBOL_GPL(dev_set_name); -- cgit From 72638f598ec9f05a43fcb22dc1dd8dc34c43acc1 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 8 Jan 2009 03:06:42 +0100 Subject: PNP: fix broken pnp lowercasing for acpi module aliases Based on a patch from Brian, who identified the issue. Signed-off-by: Bryan Kadzban Signed-off-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- scripts/mod/file2alias.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index d4dc222a74f..491b8b1b6ab 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -366,11 +366,17 @@ static void do_pnp_device_entry(void *symval, unsigned long size, for (i = 0; i < count; i++) { const char *id = (char *)devs[i].id; + char acpi_id[sizeof(devs[0].id)]; + int j; buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"pnp:d%s*\");\n", id); + + /* fix broken pnp bus lowercasing */ + for (j = 0; j < sizeof(acpi_id); j++) + acpi_id[j] = toupper(id[j]); buf_printf(&mod->dev_table_buf, - "MODULE_ALIAS(\"acpi*:%s:*\");\n", id); + "MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id); } } @@ -416,10 +422,17 @@ static void do_pnp_card_entries(void *symval, unsigned long size, /* add an individual alias for every device entry */ if (!dup) { + char acpi_id[sizeof(card->devs[0].id)]; + int k; + buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"pnp:d%s*\");\n", id); + + /* fix broken pnp bus lowercasing */ + for (k = 0; k < sizeof(acpi_id); k++) + acpi_id[k] = toupper(id[k]); buf_printf(&mod->dev_table_buf, - "MODULE_ALIAS(\"acpi*:%s:*\");\n", id); + "MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id); } } } -- cgit From 4503efd0891c40e30928afb4b23dc3f99c62a6b2 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 20 Jan 2009 15:51:16 -0800 Subject: sysfs: fix problems with binary files Some sysfs binary files don't like having 0 passed to them as a size. Fix this up at the root by just returning to the vfs if userspace asks us for a zero sized buffer. Thanks to Pavel Roskin for pointing this out. Reported-by: Pavel Roskin Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/bin.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c index 66f6e58a7e4..f2c478c3424 100644 --- a/fs/sysfs/bin.c +++ b/fs/sysfs/bin.c @@ -63,6 +63,9 @@ read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off) int count = min_t(size_t, bytes, PAGE_SIZE); char *temp; + if (!bytes) + return 0; + if (size) { if (offs > size) return 0; @@ -131,6 +134,9 @@ static ssize_t write(struct file *file, const char __user *userbuf, int count = min_t(size_t, bytes, PAGE_SIZE); char *temp; + if (!bytes) + return 0; + if (size) { if (offs > size) return 0; -- cgit From 8adb711f3668b034e7b956fac951ed08b53e0d55 Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Tue, 20 Jan 2009 12:17:28 -0800 Subject: debugfs: introduce stub for debugfs_create_size_t() when DEBUG_FS=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Toralf Förster reported a build failure in the WiMAX stack when CONFIG_DEBUG_FS=n http://linuxwimax.org/pipermail/wimax/2009-January/000449.html This is due to debugfs_create_size_t() missing an stub that returns -ENODEV when the DEBUGFS subsystem is not configured in (like the rest of the debugfs API). This patch adds said stub. Reported-by: Toralf Förster Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- include/linux/debugfs.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index 23936b16426..0f5c33b0bd3 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -162,6 +162,13 @@ static inline struct dentry *debugfs_create_x32(const char *name, mode_t mode, return ERR_PTR(-ENODEV); } +struct dentry *debugfs_create_size_t(const char *name, mode_t mode, + struct dentry *parent, + size_t *value) +{ + return ERR_PTR(-ENODEV); +} + static inline struct dentry *debugfs_create_bool(const char *name, mode_t mode, struct dentry *parent, u32 *value) -- cgit From c0e69a5bbc6fc74184aa043aadb9a53bc58f953b Mon Sep 17 00:00:00 2001 From: Jesper Nilsson Date: Wed, 14 Jan 2009 11:19:08 +0100 Subject: klist.c: bit 0 in pointer can't be used as flag The commit a1ed5b0cffe4b16a93a6a3390e8cee0fbef94f86 (klist: don't iterate over deleted entries) introduces use of the low bit in a pointer to indicate if the knode is dead or not, assuming that this bit is always free. This is not true for all architectures, CRIS for example may align data on byte borders. The result is a bunch of warnings on bootup, devices not being added correctly etc, reported by Hinko Kocevar : ------------[ cut here ]------------ WARNING: at lib/klist.c:62 () Modules linked in: Stack from c1fe1cf0: c01cc7f4 c1fe1d11 c000eb4e c000e4de 00000000 00000000 c1f4f78f c1f50c2d c01d008c c1fdd1a0 c1fdd1a0 c1fe1d38 c0192954 c1fe0000 00000000 c1fe1dc0 00000002 7fffffff c1fe1da8 c0192d50 c1fe1dc0 00000002 7fffffff c1ff9fcc Call Trace: [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] <4>---[ end trace 4eaa2a86a8e2da22 ]--- ------------[ cut here ]------------ Repeat ad nauseam. Wed, Jan 14, 2009 at 12:11:32AM +0100, Bastien ROUCARIES wrote: > Perhaps using a pointerhackalign trick on this structure where > #define pointerhackalign(x) __attribute__ ((aligned (x))) > and declare > struct klist_node { > ... > } pointerhackalign(2); > > Because __attribute__ ((aligned (x))) could only increase alignment > it will safe to do that and serve as documentation purpose :) That works, but we need to do it not for the struct klist_node, but for the struct we insert into the void * in klist_node, which is struct klist. Reported-by: Hinko Kocevar Signed-off-by: Jesper Nilsson Cc: stable Signed-off-by: Greg Kroah-Hartman --- include/linux/klist.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/klist.h b/include/linux/klist.h index d5a27af9dba..e91a4e59b77 100644 --- a/include/linux/klist.h +++ b/include/linux/klist.h @@ -22,7 +22,7 @@ struct klist { struct list_head k_list; void (*get)(struct klist_node *); void (*put)(struct klist_node *); -}; +} __attribute__ ((aligned (4))); #define KLIST_INIT(_name, _get, _put) \ { .k_lock = __SPIN_LOCK_UNLOCKED(_name.k_lock), \ -- cgit From 67e68bde02fe783efc2ce2ca31bdb992f5235f8d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 21 Jan 2009 17:26:05 +0900 Subject: x86: update canary handling during switch Impact: cleanup In switch_to(), instead of taking offset to irq_stack_union.stack, make it a proper percpu access using __percpu_arg() and per_cpu_var(). Signed-off-by: Tejun Heo --- arch/x86/include/asm/system.h | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h index 52eb748a68a..2fcc70bc85f 100644 --- a/arch/x86/include/asm/system.h +++ b/arch/x86/include/asm/system.h @@ -89,13 +89,15 @@ do { \ #ifdef CONFIG_CC_STACKPROTECTOR #define __switch_canary \ "movq %P[task_canary](%%rsi),%%r8\n\t" \ - "movq %%r8,%%gs:%P[gs_canary]\n\t" -#define __switch_canary_param \ - , [task_canary] "i" (offsetof(struct task_struct, stack_canary)) \ - , [gs_canary] "i" (offsetof(union irq_stack_union, stack_canary)) + "movq %%r8,"__percpu_arg([gs_canary])"\n\t" +#define __switch_canary_oparam \ + , [gs_canary] "=m" (per_cpu_var(irq_stack_union.stack_canary)) +#define __switch_canary_iparam \ + , [task_canary] "i" (offsetof(struct task_struct, stack_canary)) #else /* CC_STACKPROTECTOR */ #define __switch_canary -#define __switch_canary_param +#define __switch_canary_oparam +#define __switch_canary_iparam #endif /* CC_STACKPROTECTOR */ /* Save restore flags to clear handle leaking NT */ @@ -114,13 +116,14 @@ do { \ "jc ret_from_fork\n\t" \ RESTORE_CONTEXT \ : "=a" (last) \ + __switch_canary_oparam \ : [next] "S" (next), [prev] "D" (prev), \ [threadrsp] "i" (offsetof(struct task_struct, thread.sp)), \ [ti_flags] "i" (offsetof(struct thread_info, flags)), \ [tif_fork] "i" (TIF_FORK), \ [thread_info] "i" (offsetof(struct task_struct, stack)), \ [current_task] "m" (per_cpu_var(current_task)) \ - __switch_canary_param \ + __switch_canary_iparam \ : "memory", "cc" __EXTRA_CLOBBER) #endif -- cgit From 06deef892c7327992434917fb6592c233430803d Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Wed, 21 Jan 2009 17:26:05 +0900 Subject: x86: clean up gdt_page definition Impact: cleanup && more compact percpu area layout with future changes Move 64-bit GDT to page-aligned section and clean up comment formatting. Signed-off-by: Brian Gerst Signed-off-by: Tejun Heo --- arch/x86/kernel/cpu/common.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 3887fcf6e51..a8f0dedcb0c 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -63,23 +63,23 @@ cpumask_t cpu_sibling_setup_map; static struct cpu_dev *this_cpu __cpuinitdata; +DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = { #ifdef CONFIG_X86_64 -/* We need valid kernel segments for data and code in long mode too - * IRET will check the segment types kkeil 2000/10/28 - * Also sysret mandates a special GDT layout - */ -/* The TLS descriptors are currently at a different place compared to i386. - Hopefully nobody expects them at a fixed place (Wine?) */ -DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = { + /* + * We need valid kernel segments for data and code in long mode too + * IRET will check the segment types kkeil 2000/10/28 + * Also sysret mandates a special GDT layout + * + * The TLS descriptors are currently at a different place compared to i386. + * Hopefully nobody expects them at a fixed place (Wine?) + */ [GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } }, [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } }, [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } }, [GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } }, [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } }, [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } }, -} }; #else -DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = { [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } }, [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } }, [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } }, @@ -112,8 +112,8 @@ DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = { [GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } }, [GDT_ENTRY_PERCPU] = { { { 0x00000000, 0x00000000 } } }, -} }; #endif +} }; EXPORT_PER_CPU_SYMBOL_GPL(gdt_page); #ifdef CONFIG_X86_32 -- cgit From 299e26992a737804e13e74fdb97cdab470ed19ac Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Wed, 21 Jan 2009 17:26:05 +0900 Subject: x86: fix percpu_write with 64-bit constants Impact: slightly better code generation for percpu_to_op() The processor will sign-extend 32-bit immediate values in 64-bit operations. Use the 'e' constraint ("32-bit signed integer constant, or a symbolic reference known to fit that range") for 64-bit constants. Signed-off-by: Brian Gerst Signed-off-by: Tejun Heo --- arch/x86/include/asm/percpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index ce980db5e59..0b64af4f13a 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h @@ -75,7 +75,7 @@ do { \ case 8: \ asm(op "q %1,"__percpu_arg(0) \ : "+m" (var) \ - : "r" ((T__)val)); \ + : "re" ((T__)val)); \ break; \ default: __bad_percpu_size(); \ } \ -- cgit From 0dd76d736eeb3e0ef86c5b103b47ae0e15edebad Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Wed, 21 Jan 2009 17:26:05 +0900 Subject: x86: set %fs to __KERNEL_PERCPU unconditionally for x86_32 Impact: cleanup %fs is currently set to __KERNEL_DS at boot, and conditionally switched to __KERNEL_PERCPU for secondary cpus. Instead, initialize GDT_ENTRY_PERCPU to the same attributes as GDT_ENTRY_KERNEL_DS and set %fs to __KERNEL_PERCPU unconditionally. Signed-off-by: Brian Gerst Signed-off-by: Tejun Heo --- arch/x86/kernel/cpu/common.c | 2 +- arch/x86/kernel/head_32.S | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index a8f0dedcb0c..fbebbcec001 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -111,7 +111,7 @@ DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = { [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } }, [GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } }, - [GDT_ENTRY_PERCPU] = { { { 0x00000000, 0x00000000 } } }, + [GDT_ENTRY_PERCPU] = { { { 0x0000ffff, 0x00cf9200 } } }, #endif } }; EXPORT_PER_CPU_SYMBOL_GPL(gdt_page); diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index e835b4eea70..24c0e5cd71e 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S @@ -429,12 +429,14 @@ is386: movl $2,%ecx # set MP ljmp $(__KERNEL_CS),$1f 1: movl $(__KERNEL_DS),%eax # reload all the segment registers movl %eax,%ss # after changing gdt. - movl %eax,%fs # gets reset once there's real percpu movl $(__USER_DS),%eax # DS/ES contains default USER segment movl %eax,%ds movl %eax,%es + movl $(__KERNEL_PERCPU), %eax + movl %eax,%fs # set this cpu's percpu + xorl %eax,%eax # Clear GS and LDT movl %eax,%gs lldt %ax @@ -446,8 +448,6 @@ is386: movl $2,%ecx # set MP movb $1, ready cmpb $0,%cl # the first CPU calls start_kernel je 1f - movl $(__KERNEL_PERCPU), %eax - movl %eax,%fs # set this cpu's percpu movl (stack_start), %esp 1: #endif /* CONFIG_SMP */ -- cgit From 6826c8ff07b5f95df0473a748a9831707079b940 Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Wed, 21 Jan 2009 17:26:06 +0900 Subject: x86: merge mmu_context.h Impact: cleanup tj: * changed cpu to unsigned as was done on mmu_context_64.h as cpu id is officially unsigned int * added missing ';' to 32bit version of deactivate_mm() Signed-off-by: Brian Gerst Signed-off-by: Tejun Heo --- arch/x86/include/asm/mmu_context.h | 63 ++++++++++++++++++++++++++++++++--- arch/x86/include/asm/mmu_context_32.h | 55 ------------------------------ arch/x86/include/asm/mmu_context_64.h | 52 ----------------------------- 3 files changed, 59 insertions(+), 111 deletions(-) delete mode 100644 arch/x86/include/asm/mmu_context_32.h delete mode 100644 arch/x86/include/asm/mmu_context_64.h diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index 8aeeb3fd73d..52948df9cd1 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h @@ -21,11 +21,54 @@ static inline void paravirt_activate_mm(struct mm_struct *prev, int init_new_context(struct task_struct *tsk, struct mm_struct *mm); void destroy_context(struct mm_struct *mm); -#ifdef CONFIG_X86_32 -# include "mmu_context_32.h" -#else -# include "mmu_context_64.h" + +static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) +{ +#ifdef CONFIG_SMP + if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK) + percpu_write(cpu_tlbstate.state, TLBSTATE_LAZY); +#endif +} + +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, + struct task_struct *tsk) +{ + unsigned cpu = smp_processor_id(); + + if (likely(prev != next)) { + /* stop flush ipis for the previous mm */ + cpu_clear(cpu, prev->cpu_vm_mask); +#ifdef CONFIG_SMP + percpu_write(cpu_tlbstate.state, TLBSTATE_OK); + percpu_write(cpu_tlbstate.active_mm, next); #endif + cpu_set(cpu, next->cpu_vm_mask); + + /* Re-load page tables */ + load_cr3(next->pgd); + + /* + * load the LDT, if the LDT is different: + */ + if (unlikely(prev->context.ldt != next->context.ldt)) + load_LDT_nolock(&next->context); + } +#ifdef CONFIG_SMP + else { + percpu_write(cpu_tlbstate.state, TLBSTATE_OK); + BUG_ON(percpu_read(cpu_tlbstate.active_mm) != next); + + if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) { + /* We were in lazy tlb mode and leave_mm disabled + * tlb flush IPI delivery. We must reload CR3 + * to make sure to use no freed page tables. + */ + load_cr3(next->pgd); + load_LDT_nolock(&next->context); + } + } +#endif +} #define activate_mm(prev, next) \ do { \ @@ -33,5 +76,17 @@ do { \ switch_mm((prev), (next), NULL); \ } while (0); +#ifdef CONFIG_X86_32 +#define deactivate_mm(tsk, mm) \ +do { \ + loadsegment(gs, 0); \ +} while (0) +#else +#define deactivate_mm(tsk, mm) \ +do { \ + load_gs_index(0); \ + loadsegment(fs, 0); \ +} while (0) +#endif #endif /* _ASM_X86_MMU_CONTEXT_H */ diff --git a/arch/x86/include/asm/mmu_context_32.h b/arch/x86/include/asm/mmu_context_32.h deleted file mode 100644 index 08b53454f83..00000000000 --- a/arch/x86/include/asm/mmu_context_32.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef _ASM_X86_MMU_CONTEXT_32_H -#define _ASM_X86_MMU_CONTEXT_32_H - -static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) -{ -#ifdef CONFIG_SMP - if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK) - percpu_write(cpu_tlbstate.state, TLBSTATE_LAZY); -#endif -} - -static inline void switch_mm(struct mm_struct *prev, - struct mm_struct *next, - struct task_struct *tsk) -{ - int cpu = smp_processor_id(); - - if (likely(prev != next)) { - /* stop flush ipis for the previous mm */ - cpu_clear(cpu, prev->cpu_vm_mask); -#ifdef CONFIG_SMP - percpu_write(cpu_tlbstate.state, TLBSTATE_OK); - percpu_write(cpu_tlbstate.active_mm, next); -#endif - cpu_set(cpu, next->cpu_vm_mask); - - /* Re-load page tables */ - load_cr3(next->pgd); - - /* - * load the LDT, if the LDT is different: - */ - if (unlikely(prev->context.ldt != next->context.ldt)) - load_LDT_nolock(&next->context); - } -#ifdef CONFIG_SMP - else { - percpu_write(cpu_tlbstate.state, TLBSTATE_OK); - BUG_ON(percpu_read(cpu_tlbstate.active_mm) != next); - - if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) { - /* We were in lazy tlb mode and leave_mm disabled - * tlb flush IPI delivery. We must reload %cr3. - */ - load_cr3(next->pgd); - load_LDT_nolock(&next->context); - } - } -#endif -} - -#define deactivate_mm(tsk, mm) \ - asm("movl %0,%%gs": :"r" (0)); - -#endif /* _ASM_X86_MMU_CONTEXT_32_H */ diff --git a/arch/x86/include/asm/mmu_context_64.h b/arch/x86/include/asm/mmu_context_64.h deleted file mode 100644 index c4572505ab3..00000000000 --- a/arch/x86/include/asm/mmu_context_64.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef _ASM_X86_MMU_CONTEXT_64_H -#define _ASM_X86_MMU_CONTEXT_64_H - -static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) -{ -#ifdef CONFIG_SMP - if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK) - percpu_write(cpu_tlbstate.state, TLBSTATE_LAZY); -#endif -} - -static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, - struct task_struct *tsk) -{ - unsigned cpu = smp_processor_id(); - if (likely(prev != next)) { - /* stop flush ipis for the previous mm */ - cpu_clear(cpu, prev->cpu_vm_mask); -#ifdef CONFIG_SMP - percpu_write(cpu_tlbstate.state, TLBSTATE_OK); - percpu_write(cpu_tlbstate.active_mm, next); -#endif - cpu_set(cpu, next->cpu_vm_mask); - load_cr3(next->pgd); - - if (unlikely(next->context.ldt != prev->context.ldt)) - load_LDT_nolock(&next->context); - } -#ifdef CONFIG_SMP - else { - percpu_write(cpu_tlbstate.state, TLBSTATE_OK); - BUG_ON(percpu_read(cpu_tlbstate.active_mm) != next); - - if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) { - /* We were in lazy tlb mode and leave_mm disabled - * tlb flush IPI delivery. We must reload CR3 - * to make sure to use no freed page tables. - */ - load_cr3(next->pgd); - load_LDT_nolock(&next->context); - } - } -#endif -} - -#define deactivate_mm(tsk, mm) \ -do { \ - load_gs_index(0); \ - asm volatile("movl %0,%%fs"::"r"(0)); \ -} while (0) - -#endif /* _ASM_X86_MMU_CONTEXT_64_H */ -- cgit From d650a5148593b65a3c3f9a344f46b91b7dfe7713 Mon Sep 17 00:00:00 2001 From: Brian Gerst Date: Wed, 21 Jan 2009 17:26:06 +0900 Subject: x86: merge irq_regs.h Impact: cleanup, better irq_regs code generation for x86_64 Make 64-bit use the same optimizations as 32-bit. Signed-off-by: Brian Gerst Signed-off-by: Tejun Heo --- arch/x86/include/asm/irq_regs.h | 36 +++++++++++++++++++++++++++++++----- arch/x86/include/asm/irq_regs_32.h | 31 ------------------------------- arch/x86/include/asm/irq_regs_64.h | 1 - arch/x86/kernel/irq_64.c | 3 +++ 4 files changed, 34 insertions(+), 37 deletions(-) delete mode 100644 arch/x86/include/asm/irq_regs_32.h delete mode 100644 arch/x86/include/asm/irq_regs_64.h diff --git a/arch/x86/include/asm/irq_regs.h b/arch/x86/include/asm/irq_regs.h index 89c898ab298..77843225b7e 100644 --- a/arch/x86/include/asm/irq_regs.h +++ b/arch/x86/include/asm/irq_regs.h @@ -1,5 +1,31 @@ -#ifdef CONFIG_X86_32 -# include "irq_regs_32.h" -#else -# include "irq_regs_64.h" -#endif +/* + * Per-cpu current frame pointer - the location of the last exception frame on + * the stack, stored in the per-cpu area. + * + * Jeremy Fitzhardinge + */ +#ifndef _ASM_X86_IRQ_REGS_H +#define _ASM_X86_IRQ_REGS_H + +#include + +#define ARCH_HAS_OWN_IRQ_REGS + +DECLARE_PER_CPU(struct pt_regs *, irq_regs); + +static inline struct pt_regs *get_irq_regs(void) +{ + return percpu_read(irq_regs); +} + +static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs) +{ + struct pt_regs *old_regs; + + old_regs = get_irq_regs(); + percpu_write(irq_regs, new_regs); + + return old_regs; +} + +#endif /* _ASM_X86_IRQ_REGS_32_H */ diff --git a/arch/x86/include/asm/irq_regs_32.h b/arch/x86/include/asm/irq_regs_32.h deleted file mode 100644 index d7ed33ee94e..00000000000 --- a/arch/x86/include/asm/irq_regs_32.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Per-cpu current frame pointer - the location of the last exception frame on - * the stack, stored in the per-cpu area. - * - * Jeremy Fitzhardinge - */ -#ifndef _ASM_X86_IRQ_REGS_32_H -#define _ASM_X86_IRQ_REGS_32_H - -#include - -#define ARCH_HAS_OWN_IRQ_REGS - -DECLARE_PER_CPU(struct pt_regs *, irq_regs); - -static inline struct pt_regs *get_irq_regs(void) -{ - return percpu_read(irq_regs); -} - -static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs) -{ - struct pt_regs *old_regs; - - old_regs = get_irq_regs(); - percpu_write(irq_regs, new_regs); - - return old_regs; -} - -#endif /* _ASM_X86_IRQ_REGS_32_H */ diff --git a/arch/x86/include/asm/irq_regs_64.h b/arch/x86/include/asm/irq_regs_64.h deleted file mode 100644 index 3dd9c0b7027..00000000000 --- a/arch/x86/include/asm/irq_regs_64.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c index 1db05247b47..0b254de8408 100644 --- a/arch/x86/kernel/irq_64.c +++ b/arch/x86/kernel/irq_64.c @@ -22,6 +22,9 @@ DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); EXPORT_PER_CPU_SYMBOL(irq_stat); +DEFINE_PER_CPU(struct pt_regs *, irq_regs); +EXPORT_PER_CPU_SYMBOL(irq_regs); + /* * Probabilistic stack overflow check: * -- cgit From bdbcdd48883940bbd8d17eb01172d58a261a413a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 21 Jan 2009 17:26:06 +0900 Subject: x86: uv cleanup Impact: cleanup Make the following uv related cleanups. * collect visible uv related definitions and interfaces into uv/uv.h and use it. this cleans up the messy situation where on 64bit, uv is defined properly, on 32bit generic it's dummy and on the rest undefined. after this clean up, uv is defined on 64 and dummy on 32. * update uv_flush_tlb_others() such that it takes cpumask of to-be-flushed cpus as argument, instead of that minus self, and returns yet-to-be-flushed cpumask, instead of modifying the passed in parameter. this interface change will ease dummy implementation of uv_flush_tlb_others() and makes uv tlb flush related stuff defined in tlb_uv proper. Signed-off-by: Tejun Heo --- arch/x86/include/asm/genapic_32.h | 7 ---- arch/x86/include/asm/genapic_64.h | 6 ---- arch/x86/include/asm/uv/uv.h | 33 +++++++++++++++++++ arch/x86/include/asm/uv/uv_bau.h | 2 -- arch/x86/kernel/cpu/common.c | 1 + arch/x86/kernel/genx2apic_uv_x.c | 1 + arch/x86/kernel/smpboot.c | 1 + arch/x86/kernel/tlb_64.c | 18 ++++------- arch/x86/kernel/tlb_uv.c | 68 +++++++++++++++++++++++---------------- 9 files changed, 83 insertions(+), 54 deletions(-) create mode 100644 arch/x86/include/asm/uv/uv.h diff --git a/arch/x86/include/asm/genapic_32.h b/arch/x86/include/asm/genapic_32.h index 2c05b737ee2..4334502d366 100644 --- a/arch/x86/include/asm/genapic_32.h +++ b/arch/x86/include/asm/genapic_32.h @@ -138,11 +138,4 @@ struct genapic { extern struct genapic *genapic; extern void es7000_update_genapic_to_cluster(void); -enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC}; -#define get_uv_system_type() UV_NONE -#define is_uv_system() 0 -#define uv_wakeup_secondary(a, b) 1 -#define uv_system_init() do {} while (0) - - #endif /* _ASM_X86_GENAPIC_32_H */ diff --git a/arch/x86/include/asm/genapic_64.h b/arch/x86/include/asm/genapic_64.h index adf32fb56aa..7bb092c5905 100644 --- a/arch/x86/include/asm/genapic_64.h +++ b/arch/x86/include/asm/genapic_64.h @@ -51,15 +51,9 @@ extern struct genapic apic_x2apic_phys; extern int acpi_madt_oem_check(char *, char *); extern void apic_send_IPI_self(int vector); -enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC}; -extern enum uv_system_type get_uv_system_type(void); -extern int is_uv_system(void); extern struct genapic apic_x2apic_uv_x; DECLARE_PER_CPU(int, x2apic_extra_bits); -extern void uv_cpu_init(void); -extern void uv_system_init(void); -extern int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip); extern void setup_apic_routing(void); diff --git a/arch/x86/include/asm/uv/uv.h b/arch/x86/include/asm/uv/uv.h new file mode 100644 index 00000000000..dce5fe35013 --- /dev/null +++ b/arch/x86/include/asm/uv/uv.h @@ -0,0 +1,33 @@ +#ifndef _ASM_X86_UV_UV_H +#define _ASM_X86_UV_UV_H + +enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC}; + +#ifdef CONFIG_X86_64 + +extern enum uv_system_type get_uv_system_type(void); +extern int is_uv_system(void); +extern void uv_cpu_init(void); +extern void uv_system_init(void); +extern int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip); +extern const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, + struct mm_struct *mm, + unsigned long va, + unsigned int cpu); + +#else /* X86_64 */ + +static inline enum uv_system_type get_uv_system_type(void) { return UV_NONE; } +static inline int is_uv_system(void) { return 0; } +static inline void uv_cpu_init(void) { } +static inline void uv_system_init(void) { } +static inline int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip) +{ return 1; } +static inline const struct cpumask * +uv_flush_tlb_others(const struct cpumask *cpumask, struct mm_struct *mm, + unsigned long va, unsigned int cpu) +{ return cpumask; } + +#endif /* X86_64 */ + +#endif /* _ASM_X86_UV_UV_H */ diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h index 74e6393bfdd..9b0e61bf7a8 100644 --- a/arch/x86/include/asm/uv/uv_bau.h +++ b/arch/x86/include/asm/uv/uv_bau.h @@ -325,8 +325,6 @@ static inline void bau_cpubits_clear(struct bau_local_cpumask *dstp, int nbits) #define cpubit_isset(cpu, bau_local_cpumask) \ test_bit((cpu), (bau_local_cpumask).bits) -extern int uv_flush_tlb_others(struct cpumask *, - struct mm_struct *, unsigned long); extern void uv_bau_message_intr1(void); extern void uv_bau_timeout_intr1(void); diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index fbebbcec001..99904f288d6 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -28,6 +28,7 @@ #include #include #include +#include #endif #include diff --git a/arch/x86/kernel/genx2apic_uv_x.c b/arch/x86/kernel/genx2apic_uv_x.c index b193e082f6c..bfe36249145 100644 --- a/arch/x86/kernel/genx2apic_uv_x.c +++ b/arch/x86/kernel/genx2apic_uv_x.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 869b98840fd..def770b57b5 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include diff --git a/arch/x86/kernel/tlb_64.c b/arch/x86/kernel/tlb_64.c index e64a32c4882..b8bed841ad6 100644 --- a/arch/x86/kernel/tlb_64.c +++ b/arch/x86/kernel/tlb_64.c @@ -15,8 +15,7 @@ #include #include #include -#include -#include +#include DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) = { &init_mm, 0, }; @@ -206,16 +205,13 @@ void native_flush_tlb_others(const struct cpumask *cpumask, struct mm_struct *mm, unsigned long va) { if (is_uv_system()) { - /* FIXME: could be an percpu_alloc'd thing */ - static DEFINE_PER_CPU(cpumask_t, flush_tlb_mask); - struct cpumask *after_uv_flush = &get_cpu_var(flush_tlb_mask); + unsigned int cpu; - cpumask_andnot(after_uv_flush, cpumask, - cpumask_of(smp_processor_id())); - if (!uv_flush_tlb_others(after_uv_flush, mm, va)) - flush_tlb_others_ipi(after_uv_flush, mm, va); - - put_cpu_var(flush_tlb_uv_cpumask); + cpu = get_cpu(); + cpumask = uv_flush_tlb_others(cpumask, mm, va, cpu); + if (cpumask) + flush_tlb_others_ipi(cpumask, mm, va); + put_cpu(); return; } flush_tlb_others_ipi(cpumask, mm, va); diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c index 690dcf1a27d..aae15dd7260 100644 --- a/arch/x86/kernel/tlb_uv.c +++ b/arch/x86/kernel/tlb_uv.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -209,14 +210,15 @@ static int uv_wait_completion(struct bau_desc *bau_desc, * * Send a broadcast and wait for a broadcast message to complete. * - * The cpumaskp mask contains the cpus the broadcast was sent to. + * The flush_mask contains the cpus the broadcast was sent to. * - * Returns 1 if all remote flushing was done. The mask is zeroed. - * Returns 0 if some remote flushing remains to be done. The mask will have - * some bits still set. + * Returns NULL if all remote flushing was done. The mask is zeroed. + * Returns @flush_mask if some remote flushing remains to be done. The + * mask will have some bits still set. */ -int uv_flush_send_and_wait(int cpu, int this_blade, struct bau_desc *bau_desc, - struct cpumask *cpumaskp) +const struct cpumask *uv_flush_send_and_wait(int cpu, int this_blade, + struct bau_desc *bau_desc, + struct cpumask *flush_mask) { int completion_status = 0; int right_shift; @@ -263,59 +265,69 @@ int uv_flush_send_and_wait(int cpu, int this_blade, struct bau_desc *bau_desc, * Success, so clear the remote cpu's from the mask so we don't * use the IPI method of shootdown on them. */ - for_each_cpu(bit, cpumaskp) { + for_each_cpu(bit, flush_mask) { blade = uv_cpu_to_blade_id(bit); if (blade == this_blade) continue; - cpumask_clear_cpu(bit, cpumaskp); + cpumask_clear_cpu(bit, flush_mask); } - if (!cpumask_empty(cpumaskp)) - return 0; - return 1; + if (!cpumask_empty(flush_mask)) + return flush_mask; + return NULL; } /** * uv_flush_tlb_others - globally purge translation cache of a virtual * address or all TLB's - * @cpumaskp: mask of all cpu's in which the address is to be removed + * @cpumask: mask of all cpu's in which the address is to be removed * @mm: mm_struct containing virtual address range * @va: virtual address to be removed (or TLB_FLUSH_ALL for all TLB's on cpu) + * @cpu: the current cpu * * This is the entry point for initiating any UV global TLB shootdown. * * Purges the translation caches of all specified processors of the given * virtual address, or purges all TLB's on specified processors. * - * The caller has derived the cpumaskp from the mm_struct and has subtracted - * the local cpu from the mask. This function is called only if there - * are bits set in the mask. (e.g. flush_tlb_page()) + * The caller has derived the cpumask from the mm_struct. This function + * is called only if there are bits set in the mask. (e.g. flush_tlb_page()) * - * The cpumaskp is converted into a nodemask of the nodes containing + * The cpumask is converted into a nodemask of the nodes containing * the cpus. * - * Returns 1 if all remote flushing was done. - * Returns 0 if some remote flushing remains to be done. + * Note that this function should be called with preemption disabled. + * + * Returns NULL if all remote flushing was done. + * Returns pointer to cpumask if some remote flushing remains to be + * done. The returned pointer is valid till preemption is re-enabled. */ -int uv_flush_tlb_others(struct cpumask *cpumaskp, struct mm_struct *mm, - unsigned long va) +const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, + struct mm_struct *mm, + unsigned long va, unsigned int cpu) { + static DEFINE_PER_CPU(cpumask_t, flush_tlb_mask); + struct cpumask *flush_mask = &__get_cpu_var(flush_tlb_mask); int i; int bit; int blade; - int cpu; + int uv_cpu; int this_blade; int locals = 0; struct bau_desc *bau_desc; - cpu = uv_blade_processor_id(); + WARN_ON(!in_atomic()); + + cpumask_andnot(flush_mask, cpumask, cpumask_of(cpu)); + + uv_cpu = uv_blade_processor_id(); this_blade = uv_numa_blade_id(); bau_desc = __get_cpu_var(bau_control).descriptor_base; - bau_desc += UV_ITEMS_PER_DESCRIPTOR * cpu; + bau_desc += UV_ITEMS_PER_DESCRIPTOR * uv_cpu; bau_nodes_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE); i = 0; - for_each_cpu(bit, cpumaskp) { + for_each_cpu(bit, flush_mask) { blade = uv_cpu_to_blade_id(bit); BUG_ON(blade > (UV_DISTRIBUTION_SIZE - 1)); if (blade == this_blade) { @@ -330,17 +342,17 @@ int uv_flush_tlb_others(struct cpumask *cpumaskp, struct mm_struct *mm, * no off_node flushing; return status for local node */ if (locals) - return 0; + return flush_mask; else - return 1; + return NULL; } __get_cpu_var(ptcstats).requestor++; __get_cpu_var(ptcstats).ntargeted += i; bau_desc->payload.address = va; - bau_desc->payload.sending_cpu = smp_processor_id(); + bau_desc->payload.sending_cpu = cpu; - return uv_flush_send_and_wait(cpu, this_blade, bau_desc, cpumaskp); + return uv_flush_send_and_wait(uv_cpu, this_blade, bau_desc, flush_mask); } /* -- cgit From 6dd01bedee6c3191643db303a1dc530bad56ec55 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 21 Jan 2009 17:26:06 +0900 Subject: x86: prepare for tlb merge Impact: clean up, ipi vector number reordering for x86_32 Make the following changes to prepare for tlb merge. * reorder x86_32 ip vectors * adjust tlb_32.c and tlb_64.c such that their logics coincide exactly - on spurious invalidate ipi, tlb_32 acks the irq - tlb_64 now has proper memory barriers around clearing flush_cpumask (no change in generated code) * unexport flush_tlb_page from tlb_32.c, there's no user * use unsigned int for cpu id * drop unnecessary includes from tlb_64.c Signed-off-by: Tejun Heo --- arch/x86/include/asm/irq_vectors.h | 33 ++++++++++++++++----------------- arch/x86/kernel/tlb_32.c | 10 +++++----- arch/x86/kernel/tlb_64.c | 18 +++++++----------- 3 files changed, 28 insertions(+), 33 deletions(-) diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h index a16a2ab2b42..4ee8f800504 100644 --- a/arch/x86/include/asm/irq_vectors.h +++ b/arch/x86/include/asm/irq_vectors.h @@ -49,31 +49,30 @@ * some of the following vectors are 'rare', they are merged * into a single vector (CALL_FUNCTION_VECTOR) to save vector space. * TLB, reschedule and local APIC vectors are performance-critical. - * - * Vectors 0xf0-0xfa are free (reserved for future Linux use). */ #ifdef CONFIG_X86_32 # define SPURIOUS_APIC_VECTOR 0xff # define ERROR_APIC_VECTOR 0xfe -# define INVALIDATE_TLB_VECTOR 0xfd -# define RESCHEDULE_VECTOR 0xfc -# define CALL_FUNCTION_VECTOR 0xfb -# define CALL_FUNCTION_SINGLE_VECTOR 0xfa -# define THERMAL_APIC_VECTOR 0xf0 +# define RESCHEDULE_VECTOR 0xfd +# define CALL_FUNCTION_VECTOR 0xfc +# define CALL_FUNCTION_SINGLE_VECTOR 0xfb +# define THERMAL_APIC_VECTOR 0xfa +/* 0xf1 - 0xf9 : free */ +# define INVALIDATE_TLB_VECTOR 0xf0 #else -#define SPURIOUS_APIC_VECTOR 0xff -#define ERROR_APIC_VECTOR 0xfe -#define RESCHEDULE_VECTOR 0xfd -#define CALL_FUNCTION_VECTOR 0xfc -#define CALL_FUNCTION_SINGLE_VECTOR 0xfb -#define THERMAL_APIC_VECTOR 0xfa -#define THRESHOLD_APIC_VECTOR 0xf9 -#define UV_BAU_MESSAGE 0xf8 -#define INVALIDATE_TLB_VECTOR_END 0xf7 -#define INVALIDATE_TLB_VECTOR_START 0xf0 /* f0-f7 used for TLB flush */ +# define SPURIOUS_APIC_VECTOR 0xff +# define ERROR_APIC_VECTOR 0xfe +# define RESCHEDULE_VECTOR 0xfd +# define CALL_FUNCTION_VECTOR 0xfc +# define CALL_FUNCTION_SINGLE_VECTOR 0xfb +# define THERMAL_APIC_VECTOR 0xfa +# define THRESHOLD_APIC_VECTOR 0xf9 +# define UV_BAU_MESSAGE 0xf8 +# define INVALIDATE_TLB_VECTOR_END 0xf7 +# define INVALIDATE_TLB_VECTOR_START 0xf0 /* f0-f7 used for TLB flush */ #define NUM_INVALIDATE_TLB_VECTORS 8 diff --git a/arch/x86/kernel/tlb_32.c b/arch/x86/kernel/tlb_32.c index abf0808d6fc..93fcb05c7d4 100644 --- a/arch/x86/kernel/tlb_32.c +++ b/arch/x86/kernel/tlb_32.c @@ -84,13 +84,15 @@ EXPORT_SYMBOL_GPL(leave_mm); * * 1) Flush the tlb entries if the cpu uses the mm that's being flushed. * 2) Leave the mm if we are in the lazy tlb mode. + * + * Interrupts are disabled. */ void smp_invalidate_interrupt(struct pt_regs *regs) { - unsigned long cpu; + unsigned int cpu; - cpu = get_cpu(); + cpu = smp_processor_id(); if (!cpumask_test_cpu(cpu, flush_cpumask)) goto out; @@ -112,12 +114,11 @@ void smp_invalidate_interrupt(struct pt_regs *regs) } else leave_mm(cpu); } +out: ack_APIC_irq(); smp_mb__before_clear_bit(); cpumask_clear_cpu(cpu, flush_cpumask); smp_mb__after_clear_bit(); -out: - put_cpu_no_resched(); inc_irq_stat(irq_tlb_count); } @@ -215,7 +216,6 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long va) flush_tlb_others(&mm->cpu_vm_mask, mm, va); preempt_enable(); } -EXPORT_SYMBOL(flush_tlb_page); static void do_flush_tlb_all(void *info) { diff --git a/arch/x86/kernel/tlb_64.c b/arch/x86/kernel/tlb_64.c index b8bed841ad6..19ac661422f 100644 --- a/arch/x86/kernel/tlb_64.c +++ b/arch/x86/kernel/tlb_64.c @@ -1,20 +1,14 @@ #include #include -#include #include #include -#include -#include #include +#include -#include -#include #include #include -#include -#include -#include +#include #include DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) @@ -121,8 +115,8 @@ EXPORT_SYMBOL_GPL(leave_mm); asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs) { - int cpu; - int sender; + unsigned int cpu; + unsigned int sender; union smp_flush_state *f; cpu = smp_processor_id(); @@ -155,14 +149,16 @@ asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs) } out: ack_APIC_irq(); + smp_mb__before_clear_bit(); cpumask_clear_cpu(cpu, to_cpumask(f->flush_cpumask)); + smp_mb__after_clear_bit(); inc_irq_stat(irq_tlb_count); } static void flush_tlb_others_ipi(const struct cpumask *cpumask, struct mm_struct *mm, unsigned long va) { - int sender; + unsigned int sender; union smp_flush_state *f; /* Caller has disabled preemption */ -- cgit From 02cf94c370e0dc9bf408fe45eb86fe9ad58eaf7f Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 21 Jan 2009 17:26:06 +0900 Subject: x86: make x86_32 use tlb_64.c Impact: less contention when issuing invalidate IPI, cleanup Make x86_32 use the same tlb code as 64bit. The 64bit code uses multiple IPI vectors for tlb shootdown to reduce contention. This patch makes x86_32 allocate the same 8 IPIs as x86_64 and share the code paths. Note that the usage of asmlinkage is inconsistent for x86_32 and 64 and calls for further cleanup. This has been noted with a FIXME comment in tlb_64.c. Signed-off-by: Tejun Heo --- arch/x86/include/asm/irq_vectors.h | 7 +- arch/x86/include/asm/mach-default/entry_arch.h | 18 +- arch/x86/kernel/Makefile | 2 +- arch/x86/kernel/entry_32.S | 6 +- arch/x86/kernel/irqinit_32.c | 11 +- arch/x86/kernel/tlb_32.c | 239 ------------------------- arch/x86/kernel/tlb_64.c | 12 +- 7 files changed, 47 insertions(+), 248 deletions(-) delete mode 100644 arch/x86/kernel/tlb_32.c diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h index 4ee8f800504..9a83a10a5d5 100644 --- a/arch/x86/include/asm/irq_vectors.h +++ b/arch/x86/include/asm/irq_vectors.h @@ -58,8 +58,11 @@ # define CALL_FUNCTION_VECTOR 0xfc # define CALL_FUNCTION_SINGLE_VECTOR 0xfb # define THERMAL_APIC_VECTOR 0xfa -/* 0xf1 - 0xf9 : free */ -# define INVALIDATE_TLB_VECTOR 0xf0 +/* 0xf8 - 0xf9 : free */ +# define INVALIDATE_TLB_VECTOR_END 0xf7 +# define INVALIDATE_TLB_VECTOR_START 0xf0 /* f0-f7 used for TLB flush */ + +# define NUM_INVALIDATE_TLB_VECTORS 8 #else diff --git a/arch/x86/include/asm/mach-default/entry_arch.h b/arch/x86/include/asm/mach-default/entry_arch.h index 6b1add8e31d..6fa399ad1de 100644 --- a/arch/x86/include/asm/mach-default/entry_arch.h +++ b/arch/x86/include/asm/mach-default/entry_arch.h @@ -11,10 +11,26 @@ */ #ifdef CONFIG_X86_SMP BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) -BUILD_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR) BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR) BUILD_INTERRUPT(irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR) + +BUILD_INTERRUPT3(invalidate_interrupt0,INVALIDATE_TLB_VECTOR_START+0, + smp_invalidate_interrupt) +BUILD_INTERRUPT3(invalidate_interrupt1,INVALIDATE_TLB_VECTOR_START+1, + smp_invalidate_interrupt) +BUILD_INTERRUPT3(invalidate_interrupt2,INVALIDATE_TLB_VECTOR_START+2, + smp_invalidate_interrupt) +BUILD_INTERRUPT3(invalidate_interrupt3,INVALIDATE_TLB_VECTOR_START+3, + smp_invalidate_interrupt) +BUILD_INTERRUPT3(invalidate_interrupt4,INVALIDATE_TLB_VECTOR_START+4, + smp_invalidate_interrupt) +BUILD_INTERRUPT3(invalidate_interrupt5,INVALIDATE_TLB_VECTOR_START+5, + smp_invalidate_interrupt) +BUILD_INTERRUPT3(invalidate_interrupt6,INVALIDATE_TLB_VECTOR_START+6, + smp_invalidate_interrupt) +BUILD_INTERRUPT3(invalidate_interrupt7,INVALIDATE_TLB_VECTOR_START+7, + smp_invalidate_interrupt) #endif /* diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index eb074530c7d..a62a15c2222 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -58,7 +58,7 @@ obj-$(CONFIG_PCI) += early-quirks.o apm-y := apm_32.o obj-$(CONFIG_APM) += apm.o obj-$(CONFIG_X86_SMP) += smp.o -obj-$(CONFIG_X86_SMP) += smpboot.o tsc_sync.o ipi.o tlb_$(BITS).o +obj-$(CONFIG_X86_SMP) += smpboot.o tsc_sync.o ipi.o tlb_64.o obj-$(CONFIG_X86_32_SMP) += smpcommon.o obj-$(CONFIG_X86_64_SMP) += tsc_sync.o smpcommon.o obj-$(CONFIG_X86_TRAMPOLINE) += trampoline_$(BITS).o diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 46469029e9d..a0b91aac72a 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -672,7 +672,7 @@ common_interrupt: ENDPROC(common_interrupt) CFI_ENDPROC -#define BUILD_INTERRUPT(name, nr) \ +#define BUILD_INTERRUPT3(name, nr, fn) \ ENTRY(name) \ RING0_INT_FRAME; \ pushl $~(nr); \ @@ -680,11 +680,13 @@ ENTRY(name) \ SAVE_ALL; \ TRACE_IRQS_OFF \ movl %esp,%eax; \ - call smp_##name; \ + call fn; \ jmp ret_from_intr; \ CFI_ENDPROC; \ ENDPROC(name) +#define BUILD_INTERRUPT(name, nr) BUILD_INTERRUPT3(name, nr, smp_##name) + /* The include is where all of the SMP etc. interrupts come from */ #include "entry_arch.h" diff --git a/arch/x86/kernel/irqinit_32.c b/arch/x86/kernel/irqinit_32.c index 1507ad4e674..bf629cadec1 100644 --- a/arch/x86/kernel/irqinit_32.c +++ b/arch/x86/kernel/irqinit_32.c @@ -149,8 +149,15 @@ void __init native_init_IRQ(void) */ alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt); - /* IPI for invalidation */ - alloc_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt); + /* IPIs for invalidation */ + alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+0, invalidate_interrupt0); + alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+1, invalidate_interrupt1); + alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+2, invalidate_interrupt2); + alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+3, invalidate_interrupt3); + alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+4, invalidate_interrupt4); + alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+5, invalidate_interrupt5); + alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+6, invalidate_interrupt6); + alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+7, invalidate_interrupt7); /* IPI for generic function call */ alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); diff --git a/arch/x86/kernel/tlb_32.c b/arch/x86/kernel/tlb_32.c deleted file mode 100644 index 93fcb05c7d4..00000000000 --- a/arch/x86/kernel/tlb_32.c +++ /dev/null @@ -1,239 +0,0 @@ -#include -#include -#include - -#include - -DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) - = { &init_mm, 0, }; - -/* must come after the send_IPI functions above for inlining */ -#include - -/* - * Smarter SMP flushing macros. - * c/o Linus Torvalds. - * - * These mean you can really definitely utterly forget about - * writing to user space from interrupts. (Its not allowed anyway). - * - * Optimizations Manfred Spraul - */ - -static cpumask_var_t flush_cpumask; -static struct mm_struct *flush_mm; -static unsigned long flush_va; -static DEFINE_SPINLOCK(tlbstate_lock); - -/* - * We cannot call mmdrop() because we are in interrupt context, - * instead update mm->cpu_vm_mask. - * - * We need to reload %cr3 since the page tables may be going - * away from under us.. - */ -void leave_mm(int cpu) -{ - BUG_ON(percpu_read(cpu_tlbstate.state) == TLBSTATE_OK); - cpu_clear(cpu, percpu_read(cpu_tlbstate.active_mm)->cpu_vm_mask); - load_cr3(swapper_pg_dir); -} -EXPORT_SYMBOL_GPL(leave_mm); - -/* - * - * The flush IPI assumes that a thread switch happens in this order: - * [cpu0: the cpu that switches] - * 1) switch_mm() either 1a) or 1b) - * 1a) thread switch to a different mm - * 1a1) cpu_clear(cpu, old_mm->cpu_vm_mask); - * Stop ipi delivery for the old mm. This is not synchronized with - * the other cpus, but smp_invalidate_interrupt ignore flush ipis - * for the wrong mm, and in the worst case we perform a superfluous - * tlb flush. - * 1a2) set cpu_tlbstate to TLBSTATE_OK - * Now the smp_invalidate_interrupt won't call leave_mm if cpu0 - * was in lazy tlb mode. - * 1a3) update cpu_tlbstate[].active_mm - * Now cpu0 accepts tlb flushes for the new mm. - * 1a4) cpu_set(cpu, new_mm->cpu_vm_mask); - * Now the other cpus will send tlb flush ipis. - * 1a4) change cr3. - * 1b) thread switch without mm change - * cpu_tlbstate[].active_mm is correct, cpu0 already handles - * flush ipis. - * 1b1) set cpu_tlbstate to TLBSTATE_OK - * 1b2) test_and_set the cpu bit in cpu_vm_mask. - * Atomically set the bit [other cpus will start sending flush ipis], - * and test the bit. - * 1b3) if the bit was 0: leave_mm was called, flush the tlb. - * 2) switch %%esp, ie current - * - * The interrupt must handle 2 special cases: - * - cr3 is changed before %%esp, ie. it cannot use current->{active_,}mm. - * - the cpu performs speculative tlb reads, i.e. even if the cpu only - * runs in kernel space, the cpu could load tlb entries for user space - * pages. - * - * The good news is that cpu_tlbstate is local to each cpu, no - * write/read ordering problems. - */ - -/* - * TLB flush IPI: - * - * 1) Flush the tlb entries if the cpu uses the mm that's being flushed. - * 2) Leave the mm if we are in the lazy tlb mode. - * - * Interrupts are disabled. - */ - -void smp_invalidate_interrupt(struct pt_regs *regs) -{ - unsigned int cpu; - - cpu = smp_processor_id(); - - if (!cpumask_test_cpu(cpu, flush_cpumask)) - goto out; - /* - * This was a BUG() but until someone can quote me the - * line from the intel manual that guarantees an IPI to - * multiple CPUs is retried _only_ on the erroring CPUs - * its staying as a return - * - * BUG(); - */ - - if (flush_mm == percpu_read(cpu_tlbstate.active_mm)) { - if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK) { - if (flush_va == TLB_FLUSH_ALL) - local_flush_tlb(); - else - __flush_tlb_one(flush_va); - } else - leave_mm(cpu); - } -out: - ack_APIC_irq(); - smp_mb__before_clear_bit(); - cpumask_clear_cpu(cpu, flush_cpumask); - smp_mb__after_clear_bit(); - inc_irq_stat(irq_tlb_count); -} - -void native_flush_tlb_others(const struct cpumask *cpumask, - struct mm_struct *mm, unsigned long va) -{ - /* - * - mask must exist :) - */ - BUG_ON(cpumask_empty(cpumask)); - BUG_ON(!mm); - - /* - * i'm not happy about this global shared spinlock in the - * MM hot path, but we'll see how contended it is. - * AK: x86-64 has a faster method that could be ported. - */ - spin_lock(&tlbstate_lock); - - cpumask_andnot(flush_cpumask, cpumask, cpumask_of(smp_processor_id())); -#ifdef CONFIG_HOTPLUG_CPU - /* If a CPU which we ran on has gone down, OK. */ - cpumask_and(flush_cpumask, flush_cpumask, cpu_online_mask); - if (unlikely(cpumask_empty(flush_cpumask))) { - spin_unlock(&tlbstate_lock); - return; - } -#endif - flush_mm = mm; - flush_va = va; - - /* - * Make the above memory operations globally visible before - * sending the IPI. - */ - smp_mb(); - /* - * We have to send the IPI only to - * CPUs affected. - */ - send_IPI_mask(flush_cpumask, INVALIDATE_TLB_VECTOR); - - while (!cpumask_empty(flush_cpumask)) - /* nothing. lockup detection does not belong here */ - cpu_relax(); - - flush_mm = NULL; - flush_va = 0; - spin_unlock(&tlbstate_lock); -} - -void flush_tlb_current_task(void) -{ - struct mm_struct *mm = current->mm; - - preempt_disable(); - - local_flush_tlb(); - if (cpumask_any_but(&mm->cpu_vm_mask, smp_processor_id()) < nr_cpu_ids) - flush_tlb_others(&mm->cpu_vm_mask, mm, TLB_FLUSH_ALL); - preempt_enable(); -} - -void flush_tlb_mm(struct mm_struct *mm) -{ - - preempt_disable(); - - if (current->active_mm == mm) { - if (current->mm) - local_flush_tlb(); - else - leave_mm(smp_processor_id()); - } - if (cpumask_any_but(&mm->cpu_vm_mask, smp_processor_id()) < nr_cpu_ids) - flush_tlb_others(&mm->cpu_vm_mask, mm, TLB_FLUSH_ALL); - - preempt_enable(); -} - -void flush_tlb_page(struct vm_area_struct *vma, unsigned long va) -{ - struct mm_struct *mm = vma->vm_mm; - - preempt_disable(); - - if (current->active_mm == mm) { - if (current->mm) - __flush_tlb_one(va); - else - leave_mm(smp_processor_id()); - } - - if (cpumask_any_but(&mm->cpu_vm_mask, smp_processor_id()) < nr_cpu_ids) - flush_tlb_others(&mm->cpu_vm_mask, mm, va); - preempt_enable(); -} - -static void do_flush_tlb_all(void *info) -{ - unsigned long cpu = smp_processor_id(); - - __flush_tlb_all(); - if (percpu_read(cpu_tlbstate.state) == TLBSTATE_LAZY) - leave_mm(cpu); -} - -void flush_tlb_all(void) -{ - on_each_cpu(do_flush_tlb_all, NULL, 1); -} - -static int init_flush_cpumask(void) -{ - alloc_cpumask_var(&flush_cpumask, GFP_KERNEL); - return 0; -} -early_initcall(init_flush_cpumask); diff --git a/arch/x86/kernel/tlb_64.c b/arch/x86/kernel/tlb_64.c index 19ac661422f..b3ca1b94065 100644 --- a/arch/x86/kernel/tlb_64.c +++ b/arch/x86/kernel/tlb_64.c @@ -113,7 +113,17 @@ EXPORT_SYMBOL_GPL(leave_mm); * Interrupts are disabled. */ -asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs) +/* + * FIXME: use of asmlinkage is not consistent. On x86_64 it's noop + * but still used for documentation purpose but the usage is slightly + * inconsistent. On x86_32, asmlinkage is regparm(0) but interrupt + * entry calls in with the first parameter in %eax. Maybe define + * intrlinkage? + */ +#ifdef CONFIG_X86_64 +asmlinkage +#endif +void smp_invalidate_interrupt(struct pt_regs *regs) { unsigned int cpu; unsigned int sender; -- cgit From 16c2d3f895a3bc8d8e4c76c2646a6b750c181299 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 21 Jan 2009 17:26:06 +0900 Subject: x86: rename tlb_64.c to tlb.c Impact: file rename tlb_64.c is now the tlb code for both 32 and 64. Rename it to tlb.c. Signed-off-by: Tejun Heo --- arch/x86/kernel/Makefile | 2 +- arch/x86/kernel/tlb.c | 296 +++++++++++++++++++++++++++++++++++++++++++++++ arch/x86/kernel/tlb_64.c | 296 ----------------------------------------------- 3 files changed, 297 insertions(+), 297 deletions(-) create mode 100644 arch/x86/kernel/tlb.c delete mode 100644 arch/x86/kernel/tlb_64.c diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index a62a15c2222..0626a88fbb4 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -58,7 +58,7 @@ obj-$(CONFIG_PCI) += early-quirks.o apm-y := apm_32.o obj-$(CONFIG_APM) += apm.o obj-$(CONFIG_X86_SMP) += smp.o -obj-$(CONFIG_X86_SMP) += smpboot.o tsc_sync.o ipi.o tlb_64.o +obj-$(CONFIG_X86_SMP) += smpboot.o tsc_sync.o ipi.o tlb.o obj-$(CONFIG_X86_32_SMP) += smpcommon.o obj-$(CONFIG_X86_64_SMP) += tsc_sync.o smpcommon.o obj-$(CONFIG_X86_TRAMPOLINE) += trampoline_$(BITS).o diff --git a/arch/x86/kernel/tlb.c b/arch/x86/kernel/tlb.c new file mode 100644 index 00000000000..b3ca1b94065 --- /dev/null +++ b/arch/x86/kernel/tlb.c @@ -0,0 +1,296 @@ +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) + = { &init_mm, 0, }; + +#include +/* + * Smarter SMP flushing macros. + * c/o Linus Torvalds. + * + * These mean you can really definitely utterly forget about + * writing to user space from interrupts. (Its not allowed anyway). + * + * Optimizations Manfred Spraul + * + * More scalable flush, from Andi Kleen + * + * To avoid global state use 8 different call vectors. + * Each CPU uses a specific vector to trigger flushes on other + * CPUs. Depending on the received vector the target CPUs look into + * the right per cpu variable for the flush data. + * + * With more than 8 CPUs they are hashed to the 8 available + * vectors. The limited global vector space forces us to this right now. + * In future when interrupts are split into per CPU domains this could be + * fixed, at the cost of triggering multiple IPIs in some cases. + */ + +union smp_flush_state { + struct { + struct mm_struct *flush_mm; + unsigned long flush_va; + spinlock_t tlbstate_lock; + DECLARE_BITMAP(flush_cpumask, NR_CPUS); + }; + char pad[SMP_CACHE_BYTES]; +} ____cacheline_aligned; + +/* State is put into the per CPU data section, but padded + to a full cache line because other CPUs can access it and we don't + want false sharing in the per cpu data segment. */ +static DEFINE_PER_CPU(union smp_flush_state, flush_state); + +/* + * We cannot call mmdrop() because we are in interrupt context, + * instead update mm->cpu_vm_mask. + */ +void leave_mm(int cpu) +{ + if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK) + BUG(); + cpu_clear(cpu, percpu_read(cpu_tlbstate.active_mm)->cpu_vm_mask); + load_cr3(swapper_pg_dir); +} +EXPORT_SYMBOL_GPL(leave_mm); + +/* + * + * The flush IPI assumes that a thread switch happens in this order: + * [cpu0: the cpu that switches] + * 1) switch_mm() either 1a) or 1b) + * 1a) thread switch to a different mm + * 1a1) cpu_clear(cpu, old_mm->cpu_vm_mask); + * Stop ipi delivery for the old mm. This is not synchronized with + * the other cpus, but smp_invalidate_interrupt ignore flush ipis + * for the wrong mm, and in the worst case we perform a superfluous + * tlb flush. + * 1a2) set cpu mmu_state to TLBSTATE_OK + * Now the smp_invalidate_interrupt won't call leave_mm if cpu0 + * was in lazy tlb mode. + * 1a3) update cpu active_mm + * Now cpu0 accepts tlb flushes for the new mm. + * 1a4) cpu_set(cpu, new_mm->cpu_vm_mask); + * Now the other cpus will send tlb flush ipis. + * 1a4) change cr3. + * 1b) thread switch without mm change + * cpu active_mm is correct, cpu0 already handles + * flush ipis. + * 1b1) set cpu mmu_state to TLBSTATE_OK + * 1b2) test_and_set the cpu bit in cpu_vm_mask. + * Atomically set the bit [other cpus will start sending flush ipis], + * and test the bit. + * 1b3) if the bit was 0: leave_mm was called, flush the tlb. + * 2) switch %%esp, ie current + * + * The interrupt must handle 2 special cases: + * - cr3 is changed before %%esp, ie. it cannot use current->{active_,}mm. + * - the cpu performs speculative tlb reads, i.e. even if the cpu only + * runs in kernel space, the cpu could load tlb entries for user space + * pages. + * + * The good news is that cpu mmu_state is local to each cpu, no + * write/read ordering problems. + */ + +/* + * TLB flush IPI: + * + * 1) Flush the tlb entries if the cpu uses the mm that's being flushed. + * 2) Leave the mm if we are in the lazy tlb mode. + * + * Interrupts are disabled. + */ + +/* + * FIXME: use of asmlinkage is not consistent. On x86_64 it's noop + * but still used for documentation purpose but the usage is slightly + * inconsistent. On x86_32, asmlinkage is regparm(0) but interrupt + * entry calls in with the first parameter in %eax. Maybe define + * intrlinkage? + */ +#ifdef CONFIG_X86_64 +asmlinkage +#endif +void smp_invalidate_interrupt(struct pt_regs *regs) +{ + unsigned int cpu; + unsigned int sender; + union smp_flush_state *f; + + cpu = smp_processor_id(); + /* + * orig_rax contains the negated interrupt vector. + * Use that to determine where the sender put the data. + */ + sender = ~regs->orig_ax - INVALIDATE_TLB_VECTOR_START; + f = &per_cpu(flush_state, sender); + + if (!cpumask_test_cpu(cpu, to_cpumask(f->flush_cpumask))) + goto out; + /* + * This was a BUG() but until someone can quote me the + * line from the intel manual that guarantees an IPI to + * multiple CPUs is retried _only_ on the erroring CPUs + * its staying as a return + * + * BUG(); + */ + + if (f->flush_mm == percpu_read(cpu_tlbstate.active_mm)) { + if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK) { + if (f->flush_va == TLB_FLUSH_ALL) + local_flush_tlb(); + else + __flush_tlb_one(f->flush_va); + } else + leave_mm(cpu); + } +out: + ack_APIC_irq(); + smp_mb__before_clear_bit(); + cpumask_clear_cpu(cpu, to_cpumask(f->flush_cpumask)); + smp_mb__after_clear_bit(); + inc_irq_stat(irq_tlb_count); +} + +static void flush_tlb_others_ipi(const struct cpumask *cpumask, + struct mm_struct *mm, unsigned long va) +{ + unsigned int sender; + union smp_flush_state *f; + + /* Caller has disabled preemption */ + sender = smp_processor_id() % NUM_INVALIDATE_TLB_VECTORS; + f = &per_cpu(flush_state, sender); + + /* + * Could avoid this lock when + * num_online_cpus() <= NUM_INVALIDATE_TLB_VECTORS, but it is + * probably not worth checking this for a cache-hot lock. + */ + spin_lock(&f->tlbstate_lock); + + f->flush_mm = mm; + f->flush_va = va; + cpumask_andnot(to_cpumask(f->flush_cpumask), + cpumask, cpumask_of(smp_processor_id())); + + /* + * Make the above memory operations globally visible before + * sending the IPI. + */ + smp_mb(); + /* + * We have to send the IPI only to + * CPUs affected. + */ + send_IPI_mask(to_cpumask(f->flush_cpumask), + INVALIDATE_TLB_VECTOR_START + sender); + + while (!cpumask_empty(to_cpumask(f->flush_cpumask))) + cpu_relax(); + + f->flush_mm = NULL; + f->flush_va = 0; + spin_unlock(&f->tlbstate_lock); +} + +void native_flush_tlb_others(const struct cpumask *cpumask, + struct mm_struct *mm, unsigned long va) +{ + if (is_uv_system()) { + unsigned int cpu; + + cpu = get_cpu(); + cpumask = uv_flush_tlb_others(cpumask, mm, va, cpu); + if (cpumask) + flush_tlb_others_ipi(cpumask, mm, va); + put_cpu(); + return; + } + flush_tlb_others_ipi(cpumask, mm, va); +} + +static int __cpuinit init_smp_flush(void) +{ + int i; + + for_each_possible_cpu(i) + spin_lock_init(&per_cpu(flush_state, i).tlbstate_lock); + + return 0; +} +core_initcall(init_smp_flush); + +void flush_tlb_current_task(void) +{ + struct mm_struct *mm = current->mm; + + preempt_disable(); + + local_flush_tlb(); + if (cpumask_any_but(&mm->cpu_vm_mask, smp_processor_id()) < nr_cpu_ids) + flush_tlb_others(&mm->cpu_vm_mask, mm, TLB_FLUSH_ALL); + preempt_enable(); +} + +void flush_tlb_mm(struct mm_struct *mm) +{ + preempt_disable(); + + if (current->active_mm == mm) { + if (current->mm) + local_flush_tlb(); + else + leave_mm(smp_processor_id()); + } + if (cpumask_any_but(&mm->cpu_vm_mask, smp_processor_id()) < nr_cpu_ids) + flush_tlb_others(&mm->cpu_vm_mask, mm, TLB_FLUSH_ALL); + + preempt_enable(); +} + +void flush_tlb_page(struct vm_area_struct *vma, unsigned long va) +{ + struct mm_struct *mm = vma->vm_mm; + + preempt_disable(); + + if (current->active_mm == mm) { + if (current->mm) + __flush_tlb_one(va); + else + leave_mm(smp_processor_id()); + } + + if (cpumask_any_but(&mm->cpu_vm_mask, smp_processor_id()) < nr_cpu_ids) + flush_tlb_others(&mm->cpu_vm_mask, mm, va); + + preempt_enable(); +} + +static void do_flush_tlb_all(void *info) +{ + unsigned long cpu = smp_processor_id(); + + __flush_tlb_all(); + if (percpu_read(cpu_tlbstate.state) == TLBSTATE_LAZY) + leave_mm(cpu); +} + +void flush_tlb_all(void) +{ + on_each_cpu(do_flush_tlb_all, NULL, 1); +} diff --git a/arch/x86/kernel/tlb_64.c b/arch/x86/kernel/tlb_64.c deleted file mode 100644 index b3ca1b94065..00000000000 --- a/arch/x86/kernel/tlb_64.c +++ /dev/null @@ -1,296 +0,0 @@ -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) - = { &init_mm, 0, }; - -#include -/* - * Smarter SMP flushing macros. - * c/o Linus Torvalds. - * - * These mean you can really definitely utterly forget about - * writing to user space from interrupts. (Its not allowed anyway). - * - * Optimizations Manfred Spraul - * - * More scalable flush, from Andi Kleen - * - * To avoid global state use 8 different call vectors. - * Each CPU uses a specific vector to trigger flushes on other - * CPUs. Depending on the received vector the target CPUs look into - * the right per cpu variable for the flush data. - * - * With more than 8 CPUs they are hashed to the 8 available - * vectors. The limited global vector space forces us to this right now. - * In future when interrupts are split into per CPU domains this could be - * fixed, at the cost of triggering multiple IPIs in some cases. - */ - -union smp_flush_state { - struct { - struct mm_struct *flush_mm; - unsigned long flush_va; - spinlock_t tlbstate_lock; - DECLARE_BITMAP(flush_cpumask, NR_CPUS); - }; - char pad[SMP_CACHE_BYTES]; -} ____cacheline_aligned; - -/* State is put into the per CPU data section, but padded - to a full cache line because other CPUs can access it and we don't - want false sharing in the per cpu data segment. */ -static DEFINE_PER_CPU(union smp_flush_state, flush_state); - -/* - * We cannot call mmdrop() because we are in interrupt context, - * instead update mm->cpu_vm_mask. - */ -void leave_mm(int cpu) -{ - if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK) - BUG(); - cpu_clear(cpu, percpu_read(cpu_tlbstate.active_mm)->cpu_vm_mask); - load_cr3(swapper_pg_dir); -} -EXPORT_SYMBOL_GPL(leave_mm); - -/* - * - * The flush IPI assumes that a thread switch happens in this order: - * [cpu0: the cpu that switches] - * 1) switch_mm() either 1a) or 1b) - * 1a) thread switch to a different mm - * 1a1) cpu_clear(cpu, old_mm->cpu_vm_mask); - * Stop ipi delivery for the old mm. This is not synchronized with - * the other cpus, but smp_invalidate_interrupt ignore flush ipis - * for the wrong mm, and in the worst case we perform a superfluous - * tlb flush. - * 1a2) set cpu mmu_state to TLBSTATE_OK - * Now the smp_invalidate_interrupt won't call leave_mm if cpu0 - * was in lazy tlb mode. - * 1a3) update cpu active_mm - * Now cpu0 accepts tlb flushes for the new mm. - * 1a4) cpu_set(cpu, new_mm->cpu_vm_mask); - * Now the other cpus will send tlb flush ipis. - * 1a4) change cr3. - * 1b) thread switch without mm change - * cpu active_mm is correct, cpu0 already handles - * flush ipis. - * 1b1) set cpu mmu_state to TLBSTATE_OK - * 1b2) test_and_set the cpu bit in cpu_vm_mask. - * Atomically set the bit [other cpus will start sending flush ipis], - * and test the bit. - * 1b3) if the bit was 0: leave_mm was called, flush the tlb. - * 2) switch %%esp, ie current - * - * The interrupt must handle 2 special cases: - * - cr3 is changed before %%esp, ie. it cannot use current->{active_,}mm. - * - the cpu performs speculative tlb reads, i.e. even if the cpu only - * runs in kernel space, the cpu could load tlb entries for user space - * pages. - * - * The good news is that cpu mmu_state is local to each cpu, no - * write/read ordering problems. - */ - -/* - * TLB flush IPI: - * - * 1) Flush the tlb entries if the cpu uses the mm that's being flushed. - * 2) Leave the mm if we are in the lazy tlb mode. - * - * Interrupts are disabled. - */ - -/* - * FIXME: use of asmlinkage is not consistent. On x86_64 it's noop - * but still used for documentation purpose but the usage is slightly - * inconsistent. On x86_32, asmlinkage is regparm(0) but interrupt - * entry calls in with the first parameter in %eax. Maybe define - * intrlinkage? - */ -#ifdef CONFIG_X86_64 -asmlinkage -#endif -void smp_invalidate_interrupt(struct pt_regs *regs) -{ - unsigned int cpu; - unsigned int sender; - union smp_flush_state *f; - - cpu = smp_processor_id(); - /* - * orig_rax contains the negated interrupt vector. - * Use that to determine where the sender put the data. - */ - sender = ~regs->orig_ax - INVALIDATE_TLB_VECTOR_START; - f = &per_cpu(flush_state, sender); - - if (!cpumask_test_cpu(cpu, to_cpumask(f->flush_cpumask))) - goto out; - /* - * This was a BUG() but until someone can quote me the - * line from the intel manual that guarantees an IPI to - * multiple CPUs is retried _only_ on the erroring CPUs - * its staying as a return - * - * BUG(); - */ - - if (f->flush_mm == percpu_read(cpu_tlbstate.active_mm)) { - if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK) { - if (f->flush_va == TLB_FLUSH_ALL) - local_flush_tlb(); - else - __flush_tlb_one(f->flush_va); - } else - leave_mm(cpu); - } -out: - ack_APIC_irq(); - smp_mb__before_clear_bit(); - cpumask_clear_cpu(cpu, to_cpumask(f->flush_cpumask)); - smp_mb__after_clear_bit(); - inc_irq_stat(irq_tlb_count); -} - -static void flush_tlb_others_ipi(const struct cpumask *cpumask, - struct mm_struct *mm, unsigned long va) -{ - unsigned int sender; - union smp_flush_state *f; - - /* Caller has disabled preemption */ - sender = smp_processor_id() % NUM_INVALIDATE_TLB_VECTORS; - f = &per_cpu(flush_state, sender); - - /* - * Could avoid this lock when - * num_online_cpus() <= NUM_INVALIDATE_TLB_VECTORS, but it is - * probably not worth checking this for a cache-hot lock. - */ - spin_lock(&f->tlbstate_lock); - - f->flush_mm = mm; - f->flush_va = va; - cpumask_andnot(to_cpumask(f->flush_cpumask), - cpumask, cpumask_of(smp_processor_id())); - - /* - * Make the above memory operations globally visible before - * sending the IPI. - */ - smp_mb(); - /* - * We have to send the IPI only to - * CPUs affected. - */ - send_IPI_mask(to_cpumask(f->flush_cpumask), - INVALIDATE_TLB_VECTOR_START + sender); - - while (!cpumask_empty(to_cpumask(f->flush_cpumask))) - cpu_relax(); - - f->flush_mm = NULL; - f->flush_va = 0; - spin_unlock(&f->tlbstate_lock); -} - -void native_flush_tlb_others(const struct cpumask *cpumask, - struct mm_struct *mm, unsigned long va) -{ - if (is_uv_system()) { - unsigned int cpu; - - cpu = get_cpu(); - cpumask = uv_flush_tlb_others(cpumask, mm, va, cpu); - if (cpumask) - flush_tlb_others_ipi(cpumask, mm, va); - put_cpu(); - return; - } - flush_tlb_others_ipi(cpumask, mm, va); -} - -static int __cpuinit init_smp_flush(void) -{ - int i; - - for_each_possible_cpu(i) - spin_lock_init(&per_cpu(flush_state, i).tlbstate_lock); - - return 0; -} -core_initcall(init_smp_flush); - -void flush_tlb_current_task(void) -{ - struct mm_struct *mm = current->mm; - - preempt_disable(); - - local_flush_tlb(); - if (cpumask_any_but(&mm->cpu_vm_mask, smp_processor_id()) < nr_cpu_ids) - flush_tlb_others(&mm->cpu_vm_mask, mm, TLB_FLUSH_ALL); - preempt_enable(); -} - -void flush_tlb_mm(struct mm_struct *mm) -{ - preempt_disable(); - - if (current->active_mm == mm) { - if (current->mm) - local_flush_tlb(); - else - leave_mm(smp_processor_id()); - } - if (cpumask_any_but(&mm->cpu_vm_mask, smp_processor_id()) < nr_cpu_ids) - flush_tlb_others(&mm->cpu_vm_mask, mm, TLB_FLUSH_ALL); - - preempt_enable(); -} - -void flush_tlb_page(struct vm_area_struct *vma, unsigned long va) -{ - struct mm_struct *mm = vma->vm_mm; - - preempt_disable(); - - if (current->active_mm == mm) { - if (current->mm) - __flush_tlb_one(va); - else - leave_mm(smp_processor_id()); - } - - if (cpumask_any_but(&mm->cpu_vm_mask, smp_processor_id()) < nr_cpu_ids) - flush_tlb_others(&mm->cpu_vm_mask, mm, va); - - preempt_enable(); -} - -static void do_flush_tlb_all(void *info) -{ - unsigned long cpu = smp_processor_id(); - - __flush_tlb_all(); - if (percpu_read(cpu_tlbstate.state) == TLBSTATE_LAZY) - leave_mm(cpu); -} - -void flush_tlb_all(void) -{ - on_each_cpu(do_flush_tlb_all, NULL, 1); -} -- cgit From 7bfa122c19e47b1dee47476ce6e9ed6ba16f8269 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 26 Dec 2008 08:27:24 +0100 Subject: arch/sh/mm: Move a dereference below a NULL test If the NULL test is necessary, then the dereference should be moved below the NULL test. The semantic patch that makes this change is as follows: (http://www.emn.fr/x-info/coccinelle/). // @disable is_null@ identifier f; expression E; identifier fld; statement S; @@ + if (E == NULL) S f(...,E->fld,...); - if (E == NULL) S @@ identifier f; expression E; identifier fld; statement S; @@ + if (!E) S f(...,E->fld,...); - if (!E) S // Signed-off-by: Julia Lawall Signed-off-by: Paul Mundt --- arch/sh/mm/ioremap_64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sh/mm/ioremap_64.c b/arch/sh/mm/ioremap_64.c index 6e0be24d26e..31e1bb5effb 100644 --- a/arch/sh/mm/ioremap_64.c +++ b/arch/sh/mm/ioremap_64.c @@ -71,9 +71,9 @@ void *__ioremap(unsigned long phys_addr, unsigned long size, * Ok, go for it.. */ area = get_vm_area(size, VM_IOREMAP); - pr_debug("Get vm_area returns %p addr %p\n",area,area->addr); if (!area) return NULL; + pr_debug("Get vm_area returns %p addr %p\n", area, area->addr); area->phys_addr = phys_addr; addr = area->addr; if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, -- cgit From c2bcc4a7ffa7438a8ded91fbd0313c50d420ff45 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 2 Jan 2009 02:52:57 -0500 Subject: asm-sh/posix_types_{32,64}.h: drop __GLIBC__/__USE_ALL usage Bring sh in line with all the other ports. Not sure how sh missed this change as all the other arches were being updated ... Signed-off-by: Mike Frysinger Signed-off-by: Paul Mundt --- arch/sh/include/asm/posix_types_32.h | 8 ++------ arch/sh/include/asm/posix_types_64.h | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/arch/sh/include/asm/posix_types_32.h b/arch/sh/include/asm/posix_types_32.h index 0a3d2f54ab2..2172732c55c 100644 --- a/arch/sh/include/asm/posix_types_32.h +++ b/arch/sh/include/asm/posix_types_32.h @@ -39,14 +39,10 @@ typedef long long __kernel_loff_t; #endif typedef struct { -#if defined(__KERNEL__) || defined(__USE_ALL) int val[2]; -#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ - int __val[2]; -#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ } __kernel_fsid_t; -#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) +#if defined(__KERNEL__) #undef __FD_SET static __inline__ void __FD_SET(unsigned long __fd, __kernel_fd_set *__fdsetp) @@ -117,6 +113,6 @@ static __inline__ void __FD_ZERO(__kernel_fd_set *__p) } } -#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ +#endif /* defined(__KERNEL__) */ #endif /* __ASM_SH_POSIX_TYPES_H */ diff --git a/arch/sh/include/asm/posix_types_64.h b/arch/sh/include/asm/posix_types_64.h index 0620317a6f0..f83e9bd463d 100644 --- a/arch/sh/include/asm/posix_types_64.h +++ b/arch/sh/include/asm/posix_types_64.h @@ -48,14 +48,10 @@ typedef long long __kernel_loff_t; #endif typedef struct { -#if defined(__KERNEL__) || defined(__USE_ALL) int val[2]; -#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ - int __val[2]; -#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ } __kernel_fsid_t; -#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) +#if defined(__KERNEL__) #undef __FD_SET static __inline__ void __FD_SET(unsigned long __fd, __kernel_fd_set *__fdsetp) @@ -126,6 +122,6 @@ static __inline__ void __FD_ZERO(__kernel_fd_set *__p) } } -#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ +#endif /* defined(__KERNEL__) */ #endif /* __ASM_SH64_POSIX_TYPES_H */ -- cgit From ff04ea40ea3037b26d01bdeacbab1d6c15c5df61 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 2 Dec 2008 16:38:34 +0900 Subject: sh: mach-migor: Add ov772x support. Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt --- arch/sh/boards/mach-migor/setup.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index cc1408119c2..332b90d9df4 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c @@ -20,6 +20,7 @@ #include #include #include +#include #include

is the number of -- cgit From 9480c53e9b2aa13a06283ffb96bb8f1873ac4e9a Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 11 Feb 2009 13:04:41 -0800 Subject: mm: rearrange exit_mmap() to unlock before arch_exit_mmap Christophe Saout reported [in precursor to: http://marc.info/?l=linux-kernel&m=123209902707347&w=4]: > Note that I also some a different issue with CONFIG_UNEVICTABLE_LRU. > Seems like Xen tears down current->mm early on process termination, so > that __get_user_pages in exit_mmap causes nasty messages when the > process had any mlocked pages. (in fact, it somehow manages to get into > the swapping code and produces a null pointer dereference trying to get > a swap token) Jeremy explained: Yes. In the normal case under Xen, an in-use pagetable is "pinned", meaning that it is RO to the kernel, and all updates must go via hypercall (or writes are trapped and emulated, which is much the same thing). An unpinned pagetable is not currently in use by any process, and can be directly accessed as normal RW pages. As an optimisation at process exit time, we unpin the pagetable as early as possible (switching the process to init_mm), so that all the normal pagetable teardown can happen with direct memory accesses. This happens in exit_mmap() -> arch_exit_mmap(). The munlocking happens a few lines below. The obvious thing to do would be to move arch_exit_mmap() to below the munlock code, but I think we'd want to call it even if mm->mmap is NULL, just to be on the safe side. Thus, this patch: exit_mmap() needs to unlock any locked vmas before calling arch_exit_mmap, as the latter may switch the current mm to init_mm, which would cause the former to fail. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Lee Schermerhorn Cc: Christophe Saout Cc: Keir Fraser Cc: Christophe Saout Cc: Alex Williamson Cc: [2.6.28.x] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/mmap.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mm/mmap.c b/mm/mmap.c index eb1270bebe6..00ced3ee49a 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -2084,12 +2084,8 @@ void exit_mmap(struct mm_struct *mm) unsigned long end; /* mm's last user has gone, and its about to be pulled down */ - arch_exit_mmap(mm); mmu_notifier_release(mm); - if (!mm->mmap) /* Can happen if dup_mmap() received an OOM */ - return; - if (mm->locked_vm) { vma = mm->mmap; while (vma) { @@ -2098,7 +2094,13 @@ void exit_mmap(struct mm_struct *mm) vma = vma->vm_next; } } + + arch_exit_mmap(mm); + vma = mm->mmap; + if (!vma) /* Can happen if dup_mmap() received an OOM */ + return; + lru_add_drain(); flush_cache_mm(mm); tlb = tlb_gather_mmu(mm, 1); -- cgit From 4d48a542b42747c36a5937447d9c3de7c897ea50 Mon Sep 17 00:00:00 2001 From: Paul Clements Date: Wed, 11 Feb 2009 13:04:45 -0800 Subject: nbd: fix I/O hang on disconnected nbds Fix a problem that causes I/O to a disconnected (or partially initialized) nbd device to hang indefinitely. To reproduce: # ioctl NBD_SET_SIZE_BLOCKS /dev/nbd23 514048 # dd if=/dev/nbd23 of=/dev/null bs=4096 count=1 ...hangs... This can also occur when an nbd device loses its nbd-client/server connection. Although we clear the queue of any outstanding I/Os after the client/server connection fails, any additional I/Os that get queued later will hang. This bug may also be the problem reported in this bug report: http://bugzilla.kernel.org/show_bug.cgi?id=12277 Testing would need to be performed to determine if the two issues are the same. This problem was introduced by the new request handling thread code ("NBD: allow nbd to be used locally", 3/2008), which entered into mainline around 2.6.25. The fix, which is fairly simple, is to restore the check for lo->sock being NULL in do_nbd_request. This causes I/O to an uninitialized nbd to immediately fail with an I/O error, as it did prior to the introduction of this bug. Signed-off-by: Paul Clements Reported-by: Jon Nelson Acked-by: Pavel Machek Cc: [2.6.26.x, 2.6.27.x, 2.6.28.x] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/nbd.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 34f80fa6fed..8299e2d3b61 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -549,6 +549,15 @@ static void do_nbd_request(struct request_queue * q) BUG_ON(lo->magic != LO_MAGIC); + if (unlikely(!lo->sock)) { + printk(KERN_ERR "%s: Attempted send on closed socket\n", + lo->disk->disk_name); + req->errors++; + nbd_end_request(req); + spin_lock_irq(q->queue_lock); + continue; + } + spin_lock_irq(&lo->queue_lock); list_add_tail(&req->queuelist, &lo->waiting_queue); spin_unlock_irq(&lo->queue_lock); -- cgit From 507e2fbaaacb6f164b4125b87c5002f95143174b Mon Sep 17 00:00:00 2001 From: Ian Dall Date: Wed, 11 Feb 2009 13:04:46 -0800 Subject: w1: w1 temp calculation overflow fix Addresses http://bugzilla.kernel.org/show_bug.cgi?id=12646 When the temperature exceeds 32767 milli-degrees the temperature overflows to -32768 millidegrees. These are bothe well within the -55 - +125 degree range for the sensor. Fix overflow in left-shift of a u8. Signed-off-by: Ian Dall Signed-off-by: Evgeniy Polyakov Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/w1/slaves/w1_therm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c index 2c8dff9f77d..1ed3d554e37 100644 --- a/drivers/w1/slaves/w1_therm.c +++ b/drivers/w1/slaves/w1_therm.c @@ -115,7 +115,7 @@ static struct w1_therm_family_converter w1_therm_families[] = { static inline int w1_DS18B20_convert_temp(u8 rom[9]) { - s16 t = (rom[1] << 8) | rom[0]; + int t = ((s16)rom[1] << 8) | rom[0]; t = t*1000/16; return t; } -- cgit From b924a28138572f03bc8647c2be8f876d27e2666a Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 11 Feb 2009 12:08:01 -0800 Subject: x86: rename *-defs.h to *-_types.h for consistency The kernel tends to call definition-only headers *_types.h, so rename the x86 page/pgtable headers accordingly. Signed-off-by: Jeremy Fitzhardinge --- arch/x86/include/asm/pgtable-2level-defs.h | 20 -------------------- arch/x86/include/asm/pgtable-2level_types.h | 20 ++++++++++++++++++++ arch/x86/include/asm/pgtable-3level-defs.h | 28 ---------------------------- arch/x86/include/asm/pgtable-3level_types.h | 28 ++++++++++++++++++++++++++++ arch/x86/include/asm/pgtable_32.h | 4 ++-- 5 files changed, 50 insertions(+), 50 deletions(-) delete mode 100644 arch/x86/include/asm/pgtable-2level-defs.h create mode 100644 arch/x86/include/asm/pgtable-2level_types.h delete mode 100644 arch/x86/include/asm/pgtable-3level-defs.h create mode 100644 arch/x86/include/asm/pgtable-3level_types.h diff --git a/arch/x86/include/asm/pgtable-2level-defs.h b/arch/x86/include/asm/pgtable-2level-defs.h deleted file mode 100644 index d77db8990ea..00000000000 --- a/arch/x86/include/asm/pgtable-2level-defs.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef _ASM_X86_PGTABLE_2LEVEL_DEFS_H -#define _ASM_X86_PGTABLE_2LEVEL_DEFS_H - -#define SHARED_KERNEL_PMD 0 - -/* - * traditional i386 two-level paging structure: - */ - -#define PGDIR_SHIFT 22 -#define PTRS_PER_PGD 1024 - -/* - * the i386 is two-level, so we don't really have any - * PMD directory physically. - */ - -#define PTRS_PER_PTE 1024 - -#endif /* _ASM_X86_PGTABLE_2LEVEL_DEFS_H */ diff --git a/arch/x86/include/asm/pgtable-2level_types.h b/arch/x86/include/asm/pgtable-2level_types.h new file mode 100644 index 00000000000..d77db8990ea --- /dev/null +++ b/arch/x86/include/asm/pgtable-2level_types.h @@ -0,0 +1,20 @@ +#ifndef _ASM_X86_PGTABLE_2LEVEL_DEFS_H +#define _ASM_X86_PGTABLE_2LEVEL_DEFS_H + +#define SHARED_KERNEL_PMD 0 + +/* + * traditional i386 two-level paging structure: + */ + +#define PGDIR_SHIFT 22 +#define PTRS_PER_PGD 1024 + +/* + * the i386 is two-level, so we don't really have any + * PMD directory physically. + */ + +#define PTRS_PER_PTE 1024 + +#endif /* _ASM_X86_PGTABLE_2LEVEL_DEFS_H */ diff --git a/arch/x86/include/asm/pgtable-3level-defs.h b/arch/x86/include/asm/pgtable-3level-defs.h deleted file mode 100644 index 62561367653..00000000000 --- a/arch/x86/include/asm/pgtable-3level-defs.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _ASM_X86_PGTABLE_3LEVEL_DEFS_H -#define _ASM_X86_PGTABLE_3LEVEL_DEFS_H - -#ifdef CONFIG_PARAVIRT -#define SHARED_KERNEL_PMD (pv_info.shared_kernel_pmd) -#else -#define SHARED_KERNEL_PMD 1 -#endif - -/* - * PGDIR_SHIFT determines what a top-level page table entry can map - */ -#define PGDIR_SHIFT 30 -#define PTRS_PER_PGD 4 - -/* - * PMD_SHIFT determines the size of the area a middle-level - * page table can map - */ -#define PMD_SHIFT 21 -#define PTRS_PER_PMD 512 - -/* - * entries per page directory level - */ -#define PTRS_PER_PTE 512 - -#endif /* _ASM_X86_PGTABLE_3LEVEL_DEFS_H */ diff --git a/arch/x86/include/asm/pgtable-3level_types.h b/arch/x86/include/asm/pgtable-3level_types.h new file mode 100644 index 00000000000..62561367653 --- /dev/null +++ b/arch/x86/include/asm/pgtable-3level_types.h @@ -0,0 +1,28 @@ +#ifndef _ASM_X86_PGTABLE_3LEVEL_DEFS_H +#define _ASM_X86_PGTABLE_3LEVEL_DEFS_H + +#ifdef CONFIG_PARAVIRT +#define SHARED_KERNEL_PMD (pv_info.shared_kernel_pmd) +#else +#define SHARED_KERNEL_PMD 1 +#endif + +/* + * PGDIR_SHIFT determines what a top-level page table entry can map + */ +#define PGDIR_SHIFT 30 +#define PTRS_PER_PGD 4 + +/* + * PMD_SHIFT determines the size of the area a middle-level + * page table can map + */ +#define PMD_SHIFT 21 +#define PTRS_PER_PMD 512 + +/* + * entries per page directory level + */ +#define PTRS_PER_PTE 512 + +#endif /* _ASM_X86_PGTABLE_3LEVEL_DEFS_H */ diff --git a/arch/x86/include/asm/pgtable_32.h b/arch/x86/include/asm/pgtable_32.h index 1952bb762aa..72d20e2a40f 100644 --- a/arch/x86/include/asm/pgtable_32.h +++ b/arch/x86/include/asm/pgtable_32.h @@ -39,11 +39,11 @@ extern void set_pmd_pfn(unsigned long, unsigned long, pgprot_t); * newer 3-level PAE-mode page tables. */ #ifdef CONFIG_X86_PAE -# include +# include # define PMD_SIZE (1UL << PMD_SHIFT) # define PMD_MASK (~(PMD_SIZE - 1)) #else -# include +# include #endif #define PGDIR_SIZE (1UL << PGDIR_SHIFT) -- cgit From 8d19c99faf6165ef095138dd595d46b9bbb34055 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Sun, 8 Feb 2009 18:46:18 -0800 Subject: Split pgtable.h into pgtable_types.h and pgtable.h Signed-off-by: Jeremy Fitzhardinge --- arch/x86/include/asm/pgtable.h | 212 +-------------------------------- arch/x86/include/asm/pgtable_types.h | 220 +++++++++++++++++++++++++++++++++++ 2 files changed, 221 insertions(+), 211 deletions(-) create mode 100644 arch/x86/include/asm/pgtable_types.h diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 860f1b635c4..10404e7bf32 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -3,164 +3,7 @@ #include -#define FIRST_USER_ADDRESS 0 - -#define _PAGE_BIT_PRESENT 0 /* is present */ -#define _PAGE_BIT_RW 1 /* writeable */ -#define _PAGE_BIT_USER 2 /* userspace addressable */ -#define _PAGE_BIT_PWT 3 /* page write through */ -#define _PAGE_BIT_PCD 4 /* page cache disabled */ -#define _PAGE_BIT_ACCESSED 5 /* was accessed (raised by CPU) */ -#define _PAGE_BIT_DIRTY 6 /* was written to (raised by CPU) */ -#define _PAGE_BIT_PSE 7 /* 4 MB (or 2MB) page */ -#define _PAGE_BIT_PAT 7 /* on 4KB pages */ -#define _PAGE_BIT_GLOBAL 8 /* Global TLB entry PPro+ */ -#define _PAGE_BIT_UNUSED1 9 /* available for programmer */ -#define _PAGE_BIT_IOMAP 10 /* flag used to indicate IO mapping */ -#define _PAGE_BIT_UNUSED3 11 -#define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */ -#define _PAGE_BIT_SPECIAL _PAGE_BIT_UNUSED1 -#define _PAGE_BIT_CPA_TEST _PAGE_BIT_UNUSED1 -#define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */ - -/* If _PAGE_BIT_PRESENT is clear, we use these: */ -/* - if the user mapped it with PROT_NONE; pte_present gives true */ -#define _PAGE_BIT_PROTNONE _PAGE_BIT_GLOBAL -/* - set: nonlinear file mapping, saved PTE; unset:swap */ -#define _PAGE_BIT_FILE _PAGE_BIT_DIRTY - -#define _PAGE_PRESENT (_AT(pteval_t, 1) << _PAGE_BIT_PRESENT) -#define _PAGE_RW (_AT(pteval_t, 1) << _PAGE_BIT_RW) -#define _PAGE_USER (_AT(pteval_t, 1) << _PAGE_BIT_USER) -#define _PAGE_PWT (_AT(pteval_t, 1) << _PAGE_BIT_PWT) -#define _PAGE_PCD (_AT(pteval_t, 1) << _PAGE_BIT_PCD) -#define _PAGE_ACCESSED (_AT(pteval_t, 1) << _PAGE_BIT_ACCESSED) -#define _PAGE_DIRTY (_AT(pteval_t, 1) << _PAGE_BIT_DIRTY) -#define _PAGE_PSE (_AT(pteval_t, 1) << _PAGE_BIT_PSE) -#define _PAGE_GLOBAL (_AT(pteval_t, 1) << _PAGE_BIT_GLOBAL) -#define _PAGE_UNUSED1 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED1) -#define _PAGE_IOMAP (_AT(pteval_t, 1) << _PAGE_BIT_IOMAP) -#define _PAGE_UNUSED3 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED3) -#define _PAGE_PAT (_AT(pteval_t, 1) << _PAGE_BIT_PAT) -#define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE) -#define _PAGE_SPECIAL (_AT(pteval_t, 1) << _PAGE_BIT_SPECIAL) -#define _PAGE_CPA_TEST (_AT(pteval_t, 1) << _PAGE_BIT_CPA_TEST) -#define __HAVE_ARCH_PTE_SPECIAL - -#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) -#define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_NX) -#else -#define _PAGE_NX (_AT(pteval_t, 0)) -#endif - -#define _PAGE_FILE (_AT(pteval_t, 1) << _PAGE_BIT_FILE) -#define _PAGE_PROTNONE (_AT(pteval_t, 1) << _PAGE_BIT_PROTNONE) - -#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \ - _PAGE_ACCESSED | _PAGE_DIRTY) -#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | \ - _PAGE_DIRTY) - -/* Set of bits not changed in pte_modify */ -#define _PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \ - _PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY) - -#define _PAGE_CACHE_MASK (_PAGE_PCD | _PAGE_PWT) -#define _PAGE_CACHE_WB (0) -#define _PAGE_CACHE_WC (_PAGE_PWT) -#define _PAGE_CACHE_UC_MINUS (_PAGE_PCD) -#define _PAGE_CACHE_UC (_PAGE_PCD | _PAGE_PWT) - -#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) -#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \ - _PAGE_ACCESSED | _PAGE_NX) - -#define PAGE_SHARED_EXEC __pgprot(_PAGE_PRESENT | _PAGE_RW | \ - _PAGE_USER | _PAGE_ACCESSED) -#define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \ - _PAGE_ACCESSED | _PAGE_NX) -#define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \ - _PAGE_ACCESSED) -#define PAGE_COPY PAGE_COPY_NOEXEC -#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | \ - _PAGE_ACCESSED | _PAGE_NX) -#define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \ - _PAGE_ACCESSED) - -#define __PAGE_KERNEL_EXEC \ - (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL) -#define __PAGE_KERNEL (__PAGE_KERNEL_EXEC | _PAGE_NX) - -#define __PAGE_KERNEL_RO (__PAGE_KERNEL & ~_PAGE_RW) -#define __PAGE_KERNEL_RX (__PAGE_KERNEL_EXEC & ~_PAGE_RW) -#define __PAGE_KERNEL_EXEC_NOCACHE (__PAGE_KERNEL_EXEC | _PAGE_PCD | _PAGE_PWT) -#define __PAGE_KERNEL_WC (__PAGE_KERNEL | _PAGE_CACHE_WC) -#define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT) -#define __PAGE_KERNEL_UC_MINUS (__PAGE_KERNEL | _PAGE_PCD) -#define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER) -#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT) -#define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE) -#define __PAGE_KERNEL_LARGE_NOCACHE (__PAGE_KERNEL | _PAGE_CACHE_UC | _PAGE_PSE) -#define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE) - -#define __PAGE_KERNEL_IO (__PAGE_KERNEL | _PAGE_IOMAP) -#define __PAGE_KERNEL_IO_NOCACHE (__PAGE_KERNEL_NOCACHE | _PAGE_IOMAP) -#define __PAGE_KERNEL_IO_UC_MINUS (__PAGE_KERNEL_UC_MINUS | _PAGE_IOMAP) -#define __PAGE_KERNEL_IO_WC (__PAGE_KERNEL_WC | _PAGE_IOMAP) - -#define PAGE_KERNEL __pgprot(__PAGE_KERNEL) -#define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO) -#define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC) -#define PAGE_KERNEL_RX __pgprot(__PAGE_KERNEL_RX) -#define PAGE_KERNEL_WC __pgprot(__PAGE_KERNEL_WC) -#define PAGE_KERNEL_NOCACHE __pgprot(__PAGE_KERNEL_NOCACHE) -#define PAGE_KERNEL_UC_MINUS __pgprot(__PAGE_KERNEL_UC_MINUS) -#define PAGE_KERNEL_EXEC_NOCACHE __pgprot(__PAGE_KERNEL_EXEC_NOCACHE) -#define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE) -#define PAGE_KERNEL_LARGE_NOCACHE __pgprot(__PAGE_KERNEL_LARGE_NOCACHE) -#define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC) -#define PAGE_KERNEL_VSYSCALL __pgprot(__PAGE_KERNEL_VSYSCALL) -#define PAGE_KERNEL_VSYSCALL_NOCACHE __pgprot(__PAGE_KERNEL_VSYSCALL_NOCACHE) - -#define PAGE_KERNEL_IO __pgprot(__PAGE_KERNEL_IO) -#define PAGE_KERNEL_IO_NOCACHE __pgprot(__PAGE_KERNEL_IO_NOCACHE) -#define PAGE_KERNEL_IO_UC_MINUS __pgprot(__PAGE_KERNEL_IO_UC_MINUS) -#define PAGE_KERNEL_IO_WC __pgprot(__PAGE_KERNEL_IO_WC) - -/* xwr */ -#define __P000 PAGE_NONE -#define __P001 PAGE_READONLY -#define __P010 PAGE_COPY -#define __P011 PAGE_COPY -#define __P100 PAGE_READONLY_EXEC -#define __P101 PAGE_READONLY_EXEC -#define __P110 PAGE_COPY_EXEC -#define __P111 PAGE_COPY_EXEC - -#define __S000 PAGE_NONE -#define __S001 PAGE_READONLY -#define __S010 PAGE_SHARED -#define __S011 PAGE_SHARED -#define __S100 PAGE_READONLY_EXEC -#define __S101 PAGE_READONLY_EXEC -#define __S110 PAGE_SHARED_EXEC -#define __S111 PAGE_SHARED_EXEC - -/* - * early identity mapping pte attrib macros. - */ -#ifdef CONFIG_X86_64 -#define __PAGE_KERNEL_IDENT_LARGE_EXEC __PAGE_KERNEL_LARGE_EXEC -#else -/* - * For PDE_IDENT_ATTR include USER bit. As the PDE and PTE protection - * bits are combined, this will alow user to access the high address mapped - * VDSO in the presence of CONFIG_COMPAT_VDSO - */ -#define PTE_IDENT_ATTR 0x003 /* PRESENT+RW */ -#define PDE_IDENT_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */ -#define PGD_IDENT_ATTR 0x001 /* PRESENT (no other attributes) */ -#endif +#include /* * Macro to mark a page protection value as UC- @@ -172,9 +15,6 @@ #ifndef __ASSEMBLY__ -#define pgprot_writecombine pgprot_writecombine -extern pgprot_t pgprot_writecombine(pgprot_t prot); - /* * ZERO_PAGE is a global shared page that is always zero: used * for zero-mapped memory areas etc.. @@ -316,8 +156,6 @@ static inline pte_t pte_mkspecial(pte_t pte) return pte_set_flags(pte, _PAGE_SPECIAL); } -extern pteval_t __supported_pte_mask; - static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot) { return __pte((((phys_addr_t)page_nr << PAGE_SHIFT) | @@ -376,32 +214,6 @@ static inline int is_new_memtype_allowed(unsigned long flags, return 1; } -#ifndef __ASSEMBLY__ -/* Indicate that x86 has its own track and untrack pfn vma functions */ -#define __HAVE_PFNMAP_TRACKING - -#define __HAVE_PHYS_MEM_ACCESS_PROT -struct file; -pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, - unsigned long size, pgprot_t vma_prot); -int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, - unsigned long size, pgprot_t *vma_prot); -#endif - -/* Install a pte for a particular vaddr in kernel space. */ -void set_pte_vaddr(unsigned long vaddr, pte_t pte); - -#ifdef CONFIG_X86_32 -extern void native_pagetable_setup_start(pgd_t *base); -extern void native_pagetable_setup_done(pgd_t *base); -#else -static inline void native_pagetable_setup_start(pgd_t *base) {} -static inline void native_pagetable_setup_done(pgd_t *base) {} -#endif - -struct seq_file; -extern void arch_report_meminfo(struct seq_file *m); - #ifdef CONFIG_PARAVIRT #include #else /* !CONFIG_PARAVIRT */ @@ -662,28 +474,6 @@ static inline int pgd_none(pgd_t pgd) #ifndef __ASSEMBLY__ -enum { - PG_LEVEL_NONE, - PG_LEVEL_4K, - PG_LEVEL_2M, - PG_LEVEL_1G, - PG_LEVEL_NUM -}; - -#ifdef CONFIG_PROC_FS -extern void update_page_count(int level, unsigned long pages); -#else -static inline void update_page_count(int level, unsigned long pages) { } -#endif - -/* - * Helper function that returns the kernel pagetable entry controlling - * the virtual address 'address'. NULL means no pagetable entry present. - * NOTE: the return type is pte_t but if the pmd is PSE then we return it - * as a pte too. - */ -extern pte_t *lookup_address(unsigned long address, unsigned int *level); - /* local pte updates need not use xchg for locking */ static inline pte_t native_local_ptep_get_and_clear(pte_t *ptep) { diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h new file mode 100644 index 00000000000..f80f5a66bb8 --- /dev/null +++ b/arch/x86/include/asm/pgtable_types.h @@ -0,0 +1,220 @@ +#ifndef _ASM_X86_PGTABLE_DEFS_H +#define _ASM_X86_PGTABLE_DEFS_H + +#include + +#define FIRST_USER_ADDRESS 0 + +#define _PAGE_BIT_PRESENT 0 /* is present */ +#define _PAGE_BIT_RW 1 /* writeable */ +#define _PAGE_BIT_USER 2 /* userspace addressable */ +#define _PAGE_BIT_PWT 3 /* page write through */ +#define _PAGE_BIT_PCD 4 /* page cache disabled */ +#define _PAGE_BIT_ACCESSED 5 /* was accessed (raised by CPU) */ +#define _PAGE_BIT_DIRTY 6 /* was written to (raised by CPU) */ +#define _PAGE_BIT_PSE 7 /* 4 MB (or 2MB) page */ +#define _PAGE_BIT_PAT 7 /* on 4KB pages */ +#define _PAGE_BIT_GLOBAL 8 /* Global TLB entry PPro+ */ +#define _PAGE_BIT_UNUSED1 9 /* available for programmer */ +#define _PAGE_BIT_IOMAP 10 /* flag used to indicate IO mapping */ +#define _PAGE_BIT_UNUSED3 11 +#define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */ +#define _PAGE_BIT_SPECIAL _PAGE_BIT_UNUSED1 +#define _PAGE_BIT_CPA_TEST _PAGE_BIT_UNUSED1 +#define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */ + +/* If _PAGE_BIT_PRESENT is clear, we use these: */ +/* - if the user mapped it with PROT_NONE; pte_present gives true */ +#define _PAGE_BIT_PROTNONE _PAGE_BIT_GLOBAL +/* - set: nonlinear file mapping, saved PTE; unset:swap */ +#define _PAGE_BIT_FILE _PAGE_BIT_DIRTY + +#define _PAGE_PRESENT (_AT(pteval_t, 1) << _PAGE_BIT_PRESENT) +#define _PAGE_RW (_AT(pteval_t, 1) << _PAGE_BIT_RW) +#define _PAGE_USER (_AT(pteval_t, 1) << _PAGE_BIT_USER) +#define _PAGE_PWT (_AT(pteval_t, 1) << _PAGE_BIT_PWT) +#define _PAGE_PCD (_AT(pteval_t, 1) << _PAGE_BIT_PCD) +#define _PAGE_ACCESSED (_AT(pteval_t, 1) << _PAGE_BIT_ACCESSED) +#define _PAGE_DIRTY (_AT(pteval_t, 1) << _PAGE_BIT_DIRTY) +#define _PAGE_PSE (_AT(pteval_t, 1) << _PAGE_BIT_PSE) +#define _PAGE_GLOBAL (_AT(pteval_t, 1) << _PAGE_BIT_GLOBAL) +#define _PAGE_UNUSED1 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED1) +#define _PAGE_IOMAP (_AT(pteval_t, 1) << _PAGE_BIT_IOMAP) +#define _PAGE_UNUSED3 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED3) +#define _PAGE_PAT (_AT(pteval_t, 1) << _PAGE_BIT_PAT) +#define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE) +#define _PAGE_SPECIAL (_AT(pteval_t, 1) << _PAGE_BIT_SPECIAL) +#define _PAGE_CPA_TEST (_AT(pteval_t, 1) << _PAGE_BIT_CPA_TEST) +#define __HAVE_ARCH_PTE_SPECIAL + +#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) +#define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_NX) +#else +#define _PAGE_NX (_AT(pteval_t, 0)) +#endif + +#define _PAGE_FILE (_AT(pteval_t, 1) << _PAGE_BIT_FILE) +#define _PAGE_PROTNONE (_AT(pteval_t, 1) << _PAGE_BIT_PROTNONE) + +#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \ + _PAGE_ACCESSED | _PAGE_DIRTY) +#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | \ + _PAGE_DIRTY) + +/* Set of bits not changed in pte_modify */ +#define _PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \ + _PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY) + +#define _PAGE_CACHE_MASK (_PAGE_PCD | _PAGE_PWT) +#define _PAGE_CACHE_WB (0) +#define _PAGE_CACHE_WC (_PAGE_PWT) +#define _PAGE_CACHE_UC_MINUS (_PAGE_PCD) +#define _PAGE_CACHE_UC (_PAGE_PCD | _PAGE_PWT) + +#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) +#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \ + _PAGE_ACCESSED | _PAGE_NX) + +#define PAGE_SHARED_EXEC __pgprot(_PAGE_PRESENT | _PAGE_RW | \ + _PAGE_USER | _PAGE_ACCESSED) +#define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \ + _PAGE_ACCESSED | _PAGE_NX) +#define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \ + _PAGE_ACCESSED) +#define PAGE_COPY PAGE_COPY_NOEXEC +#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | \ + _PAGE_ACCESSED | _PAGE_NX) +#define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \ + _PAGE_ACCESSED) + +#define __PAGE_KERNEL_EXEC \ + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL) +#define __PAGE_KERNEL (__PAGE_KERNEL_EXEC | _PAGE_NX) + +#define __PAGE_KERNEL_RO (__PAGE_KERNEL & ~_PAGE_RW) +#define __PAGE_KERNEL_RX (__PAGE_KERNEL_EXEC & ~_PAGE_RW) +#define __PAGE_KERNEL_EXEC_NOCACHE (__PAGE_KERNEL_EXEC | _PAGE_PCD | _PAGE_PWT) +#define __PAGE_KERNEL_WC (__PAGE_KERNEL | _PAGE_CACHE_WC) +#define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT) +#define __PAGE_KERNEL_UC_MINUS (__PAGE_KERNEL | _PAGE_PCD) +#define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER) +#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT) +#define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE) +#define __PAGE_KERNEL_LARGE_NOCACHE (__PAGE_KERNEL | _PAGE_CACHE_UC | _PAGE_PSE) +#define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE) + +#define __PAGE_KERNEL_IO (__PAGE_KERNEL | _PAGE_IOMAP) +#define __PAGE_KERNEL_IO_NOCACHE (__PAGE_KERNEL_NOCACHE | _PAGE_IOMAP) +#define __PAGE_KERNEL_IO_UC_MINUS (__PAGE_KERNEL_UC_MINUS | _PAGE_IOMAP) +#define __PAGE_KERNEL_IO_WC (__PAGE_KERNEL_WC | _PAGE_IOMAP) + +#define PAGE_KERNEL __pgprot(__PAGE_KERNEL) +#define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO) +#define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC) +#define PAGE_KERNEL_RX __pgprot(__PAGE_KERNEL_RX) +#define PAGE_KERNEL_WC __pgprot(__PAGE_KERNEL_WC) +#define PAGE_KERNEL_NOCACHE __pgprot(__PAGE_KERNEL_NOCACHE) +#define PAGE_KERNEL_UC_MINUS __pgprot(__PAGE_KERNEL_UC_MINUS) +#define PAGE_KERNEL_EXEC_NOCACHE __pgprot(__PAGE_KERNEL_EXEC_NOCACHE) +#define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE) +#define PAGE_KERNEL_LARGE_NOCACHE __pgprot(__PAGE_KERNEL_LARGE_NOCACHE) +#define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC) +#define PAGE_KERNEL_VSYSCALL __pgprot(__PAGE_KERNEL_VSYSCALL) +#define PAGE_KERNEL_VSYSCALL_NOCACHE __pgprot(__PAGE_KERNEL_VSYSCALL_NOCACHE) + +#define PAGE_KERNEL_IO __pgprot(__PAGE_KERNEL_IO) +#define PAGE_KERNEL_IO_NOCACHE __pgprot(__PAGE_KERNEL_IO_NOCACHE) +#define PAGE_KERNEL_IO_UC_MINUS __pgprot(__PAGE_KERNEL_IO_UC_MINUS) +#define PAGE_KERNEL_IO_WC __pgprot(__PAGE_KERNEL_IO_WC) + +/* xwr */ +#define __P000 PAGE_NONE +#define __P001 PAGE_READONLY +#define __P010 PAGE_COPY +#define __P011 PAGE_COPY +#define __P100 PAGE_READONLY_EXEC +#define __P101 PAGE_READONLY_EXEC +#define __P110 PAGE_COPY_EXEC +#define __P111 PAGE_COPY_EXEC + +#define __S000 PAGE_NONE +#define __S001 PAGE_READONLY +#define __S010 PAGE_SHARED +#define __S011 PAGE_SHARED +#define __S100 PAGE_READONLY_EXEC +#define __S101 PAGE_READONLY_EXEC +#define __S110 PAGE_SHARED_EXEC +#define __S111 PAGE_SHARED_EXEC + +/* + * early identity mapping pte attrib macros. + */ +#ifdef CONFIG_X86_64 +#define __PAGE_KERNEL_IDENT_LARGE_EXEC __PAGE_KERNEL_LARGE_EXEC +#else +/* + * For PDE_IDENT_ATTR include USER bit. As the PDE and PTE protection + * bits are combined, this will alow user to access the high address mapped + * VDSO in the presence of CONFIG_COMPAT_VDSO + */ +#define PTE_IDENT_ATTR 0x003 /* PRESENT+RW */ +#define PDE_IDENT_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */ +#define PGD_IDENT_ATTR 0x001 /* PRESENT (no other attributes) */ +#endif + +#ifndef __ASSEMBLY__ + +extern pteval_t __supported_pte_mask; + +#define pgprot_writecombine pgprot_writecombine +extern pgprot_t pgprot_writecombine(pgprot_t prot); + +/* Indicate that x86 has its own track and untrack pfn vma functions */ +#define __HAVE_PFNMAP_TRACKING + +#define __HAVE_PHYS_MEM_ACCESS_PROT +struct file; +pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, + unsigned long size, pgprot_t vma_prot); +int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, + unsigned long size, pgprot_t *vma_prot); + +/* Install a pte for a particular vaddr in kernel space. */ +void set_pte_vaddr(unsigned long vaddr, pte_t pte); + +#ifdef CONFIG_X86_32 +extern void native_pagetable_setup_start(pgd_t *base); +extern void native_pagetable_setup_done(pgd_t *base); +#else +static inline void native_pagetable_setup_start(pgd_t *base) {} +static inline void native_pagetable_setup_done(pgd_t *base) {} +#endif + +struct seq_file; +extern void arch_report_meminfo(struct seq_file *m); + +enum { + PG_LEVEL_NONE, + PG_LEVEL_4K, + PG_LEVEL_2M, + PG_LEVEL_1G, + PG_LEVEL_NUM +}; + +#ifdef CONFIG_PROC_FS +extern void update_page_count(int level, unsigned long pages); +#else +static inline void update_page_count(int level, unsigned long pages) { } +#endif + +/* + * Helper function that returns the kernel pagetable entry controlling + * the virtual address 'address'. NULL means no pagetable entry present. + * NOTE: the return type is pte_t but if the pmd is PSE then we return it + * as a pte too. + */ +extern pte_t *lookup_address(unsigned long address, unsigned int *level); + +#endif /* !__ASSEMBLY__ */ + +#endif /* _ASM_X86_PGTABLE_DEFS_H */ -- cgit From f402a65f93c7127b2bd93a4b2fe182cd859fb4c1 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Sun, 8 Feb 2009 18:49:05 -0800 Subject: x86: Split pgtable_32.h into pgtable_32.h and pgtable_32_types.h Signed-off-by: Jeremy Fitzhardinge --- arch/x86/include/asm/pgtable_32.h | 42 +----------------------------- arch/x86/include/asm/pgtable_32_types.h | 46 +++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 41 deletions(-) create mode 100644 arch/x86/include/asm/pgtable_32_types.h diff --git a/arch/x86/include/asm/pgtable_32.h b/arch/x86/include/asm/pgtable_32.h index 72d20e2a40f..97612fc7632 100644 --- a/arch/x86/include/asm/pgtable_32.h +++ b/arch/x86/include/asm/pgtable_32.h @@ -1,6 +1,7 @@ #ifndef _ASM_X86_PGTABLE_32_H #define _ASM_X86_PGTABLE_32_H +#include /* * The Linux memory management assumes a three-level page table setup. On @@ -33,47 +34,6 @@ void paging_init(void); extern void set_pmd_pfn(unsigned long, unsigned long, pgprot_t); -/* - * The Linux x86 paging architecture is 'compile-time dual-mode', it - * implements both the traditional 2-level x86 page tables and the - * newer 3-level PAE-mode page tables. - */ -#ifdef CONFIG_X86_PAE -# include -# define PMD_SIZE (1UL << PMD_SHIFT) -# define PMD_MASK (~(PMD_SIZE - 1)) -#else -# include -#endif - -#define PGDIR_SIZE (1UL << PGDIR_SHIFT) -#define PGDIR_MASK (~(PGDIR_SIZE - 1)) - -/* Just any arbitrary offset to the start of the vmalloc VM area: the - * current 8MB value just means that there will be a 8MB "hole" after the - * physical memory until the kernel virtual memory starts. That means that - * any out-of-bounds memory accesses will hopefully be caught. - * The vmalloc() routines leaves a hole of 4kB between each vmalloced - * area for the same reason. ;) - */ -#define VMALLOC_OFFSET (8 * 1024 * 1024) -#define VMALLOC_START ((unsigned long)high_memory + VMALLOC_OFFSET) -#ifdef CONFIG_X86_PAE -#define LAST_PKMAP 512 -#else -#define LAST_PKMAP 1024 -#endif - -#define PKMAP_BASE ((FIXADDR_BOOT_START - PAGE_SIZE * (LAST_PKMAP + 1)) \ - & PMD_MASK) - -#ifdef CONFIG_HIGHMEM -# define VMALLOC_END (PKMAP_BASE - 2 * PAGE_SIZE) -#else -# define VMALLOC_END (FIXADDR_START - 2 * PAGE_SIZE) -#endif - -#define MAXMEM (VMALLOC_END - PAGE_OFFSET - __VMALLOC_RESERVE) /* * Define this if things work differently on an i386 and an i486: diff --git a/arch/x86/include/asm/pgtable_32_types.h b/arch/x86/include/asm/pgtable_32_types.h new file mode 100644 index 00000000000..bd8df3b2fe0 --- /dev/null +++ b/arch/x86/include/asm/pgtable_32_types.h @@ -0,0 +1,46 @@ +#ifndef _ASM_X86_PGTABLE_32_DEFS_H +#define _ASM_X86_PGTABLE_32_DEFS_H + +/* + * The Linux x86 paging architecture is 'compile-time dual-mode', it + * implements both the traditional 2-level x86 page tables and the + * newer 3-level PAE-mode page tables. + */ +#ifdef CONFIG_X86_PAE +# include +# define PMD_SIZE (1UL << PMD_SHIFT) +# define PMD_MASK (~(PMD_SIZE - 1)) +#else +# include +#endif + +#define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define PGDIR_MASK (~(PGDIR_SIZE - 1)) + +/* Just any arbitrary offset to the start of the vmalloc VM area: the + * current 8MB value just means that there will be a 8MB "hole" after the + * physical memory until the kernel virtual memory starts. That means that + * any out-of-bounds memory accesses will hopefully be caught. + * The vmalloc() routines leaves a hole of 4kB between each vmalloced + * area for the same reason. ;) + */ +#define VMALLOC_OFFSET (8 * 1024 * 1024) +#define VMALLOC_START ((unsigned long)high_memory + VMALLOC_OFFSET) +#ifdef CONFIG_X86_PAE +#define LAST_PKMAP 512 +#else +#define LAST_PKMAP 1024 +#endif + +#define PKMAP_BASE ((FIXADDR_BOOT_START - PAGE_SIZE * (LAST_PKMAP + 1)) \ + & PMD_MASK) + +#ifdef CONFIG_HIGHMEM +# define VMALLOC_END (PKMAP_BASE - 2 * PAGE_SIZE) +#else +# define VMALLOC_END (FIXADDR_START - 2 * PAGE_SIZE) +#endif + +#define MAXMEM (VMALLOC_END - PAGE_OFFSET - __VMALLOC_RESERVE) + +#endif /* _ASM_X86_PGTABLE_32_DEFS_H */ -- cgit From fb3551491b20442c0de0d4debd54f40c654bbe98 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Sun, 8 Feb 2009 18:50:52 -0800 Subject: x86: Split pgtable_64.h into pgtable_64_types.h and pgtable_64.h Signed-off-by: Jeremy Fitzhardinge --- arch/x86/include/asm/pgtable_64.h | 48 ++------------------------------- arch/x86/include/asm/pgtable_64_types.h | 46 +++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 46 deletions(-) create mode 100644 arch/x86/include/asm/pgtable_64_types.h diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h index 1c4e247c51f..6b87bc6d501 100644 --- a/arch/x86/include/asm/pgtable_64.h +++ b/arch/x86/include/asm/pgtable_64.h @@ -2,6 +2,8 @@ #define _ASM_X86_PGTABLE_64_H #include +#include + #ifndef __ASSEMBLY__ /* @@ -25,32 +27,6 @@ extern void paging_init(void); #endif /* !__ASSEMBLY__ */ -#define SHARED_KERNEL_PMD 0 - -/* - * PGDIR_SHIFT determines what a top-level page table entry can map - */ -#define PGDIR_SHIFT 39 -#define PTRS_PER_PGD 512 - -/* - * 3rd level page - */ -#define PUD_SHIFT 30 -#define PTRS_PER_PUD 512 - -/* - * PMD_SHIFT determines the size of the area a middle-level - * page table can map - */ -#define PMD_SHIFT 21 -#define PTRS_PER_PMD 512 - -/* - * entries per page directory level - */ -#define PTRS_PER_PTE 512 - #ifndef __ASSEMBLY__ #define pte_ERROR(e) \ @@ -130,26 +106,6 @@ static inline void native_pgd_clear(pgd_t *pgd) native_set_pgd(pgd, native_make_pgd(0)); } -#endif /* !__ASSEMBLY__ */ - -#define PMD_SIZE (_AC(1, UL) << PMD_SHIFT) -#define PMD_MASK (~(PMD_SIZE - 1)) -#define PUD_SIZE (_AC(1, UL) << PUD_SHIFT) -#define PUD_MASK (~(PUD_SIZE - 1)) -#define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT) -#define PGDIR_MASK (~(PGDIR_SIZE - 1)) - - -#define MAXMEM _AC(__AC(1, UL) << MAX_PHYSMEM_BITS, UL) -#define VMALLOC_START _AC(0xffffc20000000000, UL) -#define VMALLOC_END _AC(0xffffe1ffffffffff, UL) -#define VMEMMAP_START _AC(0xffffe20000000000, UL) -#define MODULES_VADDR _AC(0xffffffffa0000000, UL) -#define MODULES_END _AC(0xffffffffff000000, UL) -#define MODULES_LEN (MODULES_END - MODULES_VADDR) - -#ifndef __ASSEMBLY__ - /* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h new file mode 100644 index 00000000000..ffaf1934068 --- /dev/null +++ b/arch/x86/include/asm/pgtable_64_types.h @@ -0,0 +1,46 @@ +#ifndef _ASM_X86_PGTABLE_64_DEFS_H +#define _ASM_X86_PGTABLE_64_DEFS_H + +#define SHARED_KERNEL_PMD 0 + +/* + * PGDIR_SHIFT determines what a top-level page table entry can map + */ +#define PGDIR_SHIFT 39 +#define PTRS_PER_PGD 512 + +/* + * 3rd level page + */ +#define PUD_SHIFT 30 +#define PTRS_PER_PUD 512 + +/* + * PMD_SHIFT determines the size of the area a middle-level + * page table can map + */ +#define PMD_SHIFT 21 +#define PTRS_PER_PMD 512 + +/* + * entries per page directory level + */ +#define PTRS_PER_PTE 512 + +#define PMD_SIZE (_AC(1, UL) << PMD_SHIFT) +#define PMD_MASK (~(PMD_SIZE - 1)) +#define PUD_SIZE (_AC(1, UL) << PUD_SHIFT) +#define PUD_MASK (~(PUD_SIZE - 1)) +#define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT) +#define PGDIR_MASK (~(PGDIR_SIZE - 1)) + + +#define MAXMEM _AC(__AC(1, UL) << MAX_PHYSMEM_BITS, UL) +#define VMALLOC_START _AC(0xffffc20000000000, UL) +#define VMALLOC_END _AC(0xffffe1ffffffffff, UL) +#define VMEMMAP_START _AC(0xffffe20000000000, UL) +#define MODULES_VADDR _AC(0xffffffffa0000000, UL) +#define MODULES_END _AC(0xffffffffff000000, UL) +#define MODULES_LEN (MODULES_END - MODULES_VADDR) + +#endif /* _ASM_X86_PGTABLE_64_DEFS_H */ -- cgit From 1484096ceb4d5f2b27c0fe53f125ee0903eac9af Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Sun, 8 Feb 2009 19:02:47 -0800 Subject: x86: Include pgtable_32|64_types.h in pgtable_types.h Signed-off-by: Jeremy Fitzhardinge --- arch/x86/include/asm/pgtable_types.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h index f80f5a66bb8..e5d5a8d3577 100644 --- a/arch/x86/include/asm/pgtable_types.h +++ b/arch/x86/include/asm/pgtable_types.h @@ -217,4 +217,10 @@ extern pte_t *lookup_address(unsigned long address, unsigned int *level); #endif /* !__ASSEMBLY__ */ +#ifdef CONFIG_X86_32 +# include "pgtable_32_types.h" +#else +# include "pgtable_64_types.h" +#endif + #endif /* _ASM_X86_PGTABLE_DEFS_H */ -- cgit From 51c78eb3f0eb033f9fb4f2316851df1d9b07b953 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Sun, 8 Feb 2009 22:52:14 -0800 Subject: x86: create _types.h counterparts for page*.h Signed-off-by: Jeremy Fitzhardinge --- arch/x86/include/asm/page.h | 64 +------------------- arch/x86/include/asm/page_32.h | 89 +-------------------------- arch/x86/include/asm/page_32_types.h | 90 +++++++++++++++++++++++++++ arch/x86/include/asm/page_64.h | 101 +------------------------------ arch/x86/include/asm/page_64.h.rej | 114 +++++++++++++++++++++++++++++++++++ arch/x86/include/asm/page_64_types.h | 102 +++++++++++++++++++++++++++++++ arch/x86/include/asm/page_types.h | 77 +++++++++++++++++++++++ 7 files changed, 389 insertions(+), 248 deletions(-) create mode 100644 arch/x86/include/asm/page_32_types.h create mode 100644 arch/x86/include/asm/page_64.h.rej create mode 100644 arch/x86/include/asm/page_64_types.h create mode 100644 arch/x86/include/asm/page_types.h diff --git a/arch/x86/include/asm/page.h b/arch/x86/include/asm/page.h index 40226999cbf..3b2d2af951c 100644 --- a/arch/x86/include/asm/page.h +++ b/arch/x86/include/asm/page.h @@ -1,42 +1,9 @@ #ifndef _ASM_X86_PAGE_H #define _ASM_X86_PAGE_H -#include - -/* PAGE_SHIFT determines the page size */ -#define PAGE_SHIFT 12 -#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) - #ifdef __KERNEL__ -#define __PHYSICAL_MASK ((phys_addr_t)(1ULL << __PHYSICAL_MASK_SHIFT) - 1) -#define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1) - -/* Cast PAGE_MASK to a signed type so that it is sign-extended if - virtual addresses are 32-bits but physical addresses are larger - (ie, 32-bit PAE). */ -#define PHYSICAL_PAGE_MASK (((signed long)PAGE_MASK) & __PHYSICAL_MASK) - -/* PTE_PFN_MASK extracts the PFN from a (pte|pmd|pud|pgd)val_t */ -#define PTE_PFN_MASK ((pteval_t)PHYSICAL_PAGE_MASK) - -/* PTE_FLAGS_MASK extracts the flags from a (pte|pmd|pud|pgd)val_t */ -#define PTE_FLAGS_MASK (~PTE_PFN_MASK) - -#define PMD_PAGE_SIZE (_AC(1, UL) << PMD_SHIFT) -#define PMD_PAGE_MASK (~(PMD_PAGE_SIZE-1)) - -#define HPAGE_SHIFT PMD_SHIFT -#define HPAGE_SIZE (_AC(1,UL) << HPAGE_SHIFT) -#define HPAGE_MASK (~(HPAGE_SIZE - 1)) -#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) - -#define HUGE_MAX_HSTATE 2 - -#ifndef __ASSEMBLY__ -#include -#endif +#include #ifdef CONFIG_X86_64 #include @@ -44,39 +11,18 @@ #include #endif /* CONFIG_X86_64 */ -#define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) - -#define VM_DATA_DEFAULT_FLAGS \ - (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ - VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - - #ifndef __ASSEMBLY__ -typedef struct { pgdval_t pgd; } pgd_t; -typedef struct { pgprotval_t pgprot; } pgprot_t; - -extern int page_is_ram(unsigned long pagenr); -extern int pagerange_is_ram(unsigned long start, unsigned long end); -extern int devmem_is_allowed(unsigned long pagenr); -extern void map_devmem(unsigned long pfn, unsigned long size, - pgprot_t vma_prot); -extern void unmap_devmem(unsigned long pfn, unsigned long size, - pgprot_t vma_prot); - -extern unsigned long max_low_pfn_mapped; -extern unsigned long max_pfn_mapped; - struct page; static inline void clear_user_page(void *page, unsigned long vaddr, - struct page *pg) + struct page *pg) { clear_page(page); } static inline void copy_user_page(void *to, void *from, unsigned long vaddr, - struct page *topage) + struct page *topage) { copy_page(to, from); } @@ -102,8 +48,6 @@ static inline pgdval_t pgd_flags(pgd_t pgd) #if PAGETABLE_LEVELS >= 3 #if PAGETABLE_LEVELS == 4 -typedef struct { pudval_t pud; } pud_t; - static inline pud_t native_make_pud(pmdval_t val) { return (pud_t) { val }; @@ -127,8 +71,6 @@ static inline pudval_t pud_flags(pud_t pud) return native_pud_val(pud) & PTE_FLAGS_MASK; } -typedef struct { pmdval_t pmd; } pmd_t; - static inline pmd_t native_make_pmd(pmdval_t val) { return (pmd_t) { val }; diff --git a/arch/x86/include/asm/page_32.h b/arch/x86/include/asm/page_32.h index bcde0d7b432..b3f0bf79e84 100644 --- a/arch/x86/include/asm/page_32.h +++ b/arch/x86/include/asm/page_32.h @@ -1,82 +1,12 @@ #ifndef _ASM_X86_PAGE_32_H #define _ASM_X86_PAGE_32_H -/* - * This handles the memory map. - * - * A __PAGE_OFFSET of 0xC0000000 means that the kernel has - * a virtual address space of one gigabyte, which limits the - * amount of physical memory you can use to about 950MB. - * - * If you want more physical memory than this then see the CONFIG_HIGHMEM4G - * and CONFIG_HIGHMEM64G options in the kernel configuration. - */ -#define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL) - -#ifdef CONFIG_4KSTACKS -#define THREAD_ORDER 0 -#else -#define THREAD_ORDER 1 -#endif -#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) - -#define STACKFAULT_STACK 0 -#define DOUBLEFAULT_STACK 1 -#define NMI_STACK 0 -#define DEBUG_STACK 0 -#define MCE_STACK 0 -#define N_EXCEPTION_STACKS 1 - -#ifdef CONFIG_X86_PAE -/* 44=32+12, the limit we can fit into an unsigned long pfn */ -#define __PHYSICAL_MASK_SHIFT 44 -#define __VIRTUAL_MASK_SHIFT 32 -#define PAGETABLE_LEVELS 3 - -#ifndef __ASSEMBLY__ -typedef u64 pteval_t; -typedef u64 pmdval_t; -typedef u64 pudval_t; -typedef u64 pgdval_t; -typedef u64 pgprotval_t; - -typedef union { - struct { - unsigned long pte_low, pte_high; - }; - pteval_t pte; -} pte_t; -#endif /* __ASSEMBLY__ - */ -#else /* !CONFIG_X86_PAE */ -#define __PHYSICAL_MASK_SHIFT 32 -#define __VIRTUAL_MASK_SHIFT 32 -#define PAGETABLE_LEVELS 2 - -#ifndef __ASSEMBLY__ -typedef unsigned long pteval_t; -typedef unsigned long pmdval_t; -typedef unsigned long pudval_t; -typedef unsigned long pgdval_t; -typedef unsigned long pgprotval_t; - -typedef union { - pteval_t pte; - pteval_t pte_low; -} pte_t; - -#endif /* __ASSEMBLY__ */ -#endif /* CONFIG_X86_PAE */ - -#ifndef __ASSEMBLY__ -typedef struct page *pgtable_t; -#endif +#include #ifdef CONFIG_HUGETLB_PAGE #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA #endif -#ifndef __ASSEMBLY__ #define __phys_addr_nodebug(x) ((x) - PAGE_OFFSET) #ifdef CONFIG_DEBUG_VIRTUAL extern unsigned long __phys_addr(unsigned long); @@ -89,22 +19,7 @@ extern unsigned long __phys_addr(unsigned long); #define pfn_valid(pfn) ((pfn) < max_mapnr) #endif /* CONFIG_FLATMEM */ -extern int nx_enabled; - -/* - * This much address space is reserved for vmalloc() and iomap() - * as well as fixmap mappings. - */ -extern unsigned int __VMALLOC_RESERVE; -extern int sysctl_legacy_va_layout; - -extern void find_low_pfn_range(void); -extern unsigned long init_memory_mapping(unsigned long start, - unsigned long end); -extern void initmem_init(unsigned long, unsigned long); -extern void free_initmem(void); -extern void setup_bootmem_allocator(void); - +#ifndef __ASSEMBLY__ #ifdef CONFIG_X86_USE_3DNOW #include diff --git a/arch/x86/include/asm/page_32_types.h b/arch/x86/include/asm/page_32_types.h new file mode 100644 index 00000000000..b7b5402d7ab --- /dev/null +++ b/arch/x86/include/asm/page_32_types.h @@ -0,0 +1,90 @@ +#ifndef _ASM_X86_PAGE_32_DEFS_H +#define _ASM_X86_PAGE_32_DEFS_H + +#include + +/* + * This handles the memory map. + * + * A __PAGE_OFFSET of 0xC0000000 means that the kernel has + * a virtual address space of one gigabyte, which limits the + * amount of physical memory you can use to about 950MB. + * + * If you want more physical memory than this then see the CONFIG_HIGHMEM4G + * and CONFIG_HIGHMEM64G options in the kernel configuration. + */ +#define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL) + +#ifdef CONFIG_4KSTACKS +#define THREAD_ORDER 0 +#else +#define THREAD_ORDER 1 +#endif +#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) + +#define STACKFAULT_STACK 0 +#define DOUBLEFAULT_STACK 1 +#define NMI_STACK 0 +#define DEBUG_STACK 0 +#define MCE_STACK 0 +#define N_EXCEPTION_STACKS 1 + +#ifdef CONFIG_X86_PAE +/* 44=32+12, the limit we can fit into an unsigned long pfn */ +#define __PHYSICAL_MASK_SHIFT 44 +#define __VIRTUAL_MASK_SHIFT 32 +#define PAGETABLE_LEVELS 3 + +#else /* !CONFIG_X86_PAE */ +#define __PHYSICAL_MASK_SHIFT 32 +#define __VIRTUAL_MASK_SHIFT 32 +#define PAGETABLE_LEVELS 2 +#endif /* CONFIG_X86_PAE */ + +#ifndef __ASSEMBLY__ + +#ifdef CONFIG_X86_PAE +typedef u64 pteval_t; +typedef u64 pmdval_t; +typedef u64 pudval_t; +typedef u64 pgdval_t; +typedef u64 pgprotval_t; + +typedef union { + struct { + unsigned long pte_low, pte_high; + }; + pteval_t pte; +} pte_t; +#else /* !CONFIG_X86_PAE */ +typedef unsigned long pteval_t; +typedef unsigned long pmdval_t; +typedef unsigned long pudval_t; +typedef unsigned long pgdval_t; +typedef unsigned long pgprotval_t; + +typedef union { + pteval_t pte; + pteval_t pte_low; +} pte_t; +#endif /* CONFIG_X86_PAE */ + +extern int nx_enabled; + +/* + * This much address space is reserved for vmalloc() and iomap() + * as well as fixmap mappings. + */ +extern unsigned int __VMALLOC_RESERVE; +extern int sysctl_legacy_va_layout; + +extern void find_low_pfn_range(void); +extern unsigned long init_memory_mapping(unsigned long start, + unsigned long end); +extern void initmem_init(unsigned long, unsigned long); +extern void free_initmem(void); +extern void setup_bootmem_allocator(void); + +#endif /* !__ASSEMBLY__ */ + +#endif /* _ASM_X86_PAGE_32_DEFS_H */ diff --git a/arch/x86/include/asm/page_64.h b/arch/x86/include/asm/page_64.h index e27fdbe5f9e..072694ed81a 100644 --- a/arch/x86/include/asm/page_64.h +++ b/arch/x86/include/asm/page_64.h @@ -1,105 +1,6 @@ #ifndef _ASM_X86_PAGE_64_H #define _ASM_X86_PAGE_64_H -#define PAGETABLE_LEVELS 4 - -#define THREAD_ORDER 1 -#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) -#define CURRENT_MASK (~(THREAD_SIZE - 1)) - -#define EXCEPTION_STACK_ORDER 0 -#define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER) - -#define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 1) -#define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER) - -#define IRQ_STACK_ORDER 2 -#define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER) - -#define STACKFAULT_STACK 1 -#define DOUBLEFAULT_STACK 2 -#define NMI_STACK 3 -#define DEBUG_STACK 4 -#define MCE_STACK 5 -#define N_EXCEPTION_STACKS 5 /* hw limit: 7 */ - -#define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT) -#define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1)) - -/* - * Set __PAGE_OFFSET to the most negative possible address + - * PGDIR_SIZE*16 (pgd slot 272). The gap is to allow a space for a - * hypervisor to fit. Choosing 16 slots here is arbitrary, but it's - * what Xen requires. - */ -#define __PAGE_OFFSET _AC(0xffff880000000000, UL) - -#define __PHYSICAL_START CONFIG_PHYSICAL_START -#define __KERNEL_ALIGN 0x200000 - -/* - * Make sure kernel is aligned to 2MB address. Catching it at compile - * time is better. Change your config file and compile the kernel - * for a 2MB aligned address (CONFIG_PHYSICAL_START) - */ -#if (CONFIG_PHYSICAL_START % __KERNEL_ALIGN) != 0 -#error "CONFIG_PHYSICAL_START must be a multiple of 2MB" -#endif - -#define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START) -#define __START_KERNEL_map _AC(0xffffffff80000000, UL) - -/* See Documentation/x86_64/mm.txt for a description of the memory map. */ -#define __PHYSICAL_MASK_SHIFT 46 -#define __VIRTUAL_MASK_SHIFT 48 - -/* - * Kernel image size is limited to 512 MB (see level2_kernel_pgt in - * arch/x86/kernel/head_64.S), and it is mapped here: - */ -#define KERNEL_IMAGE_SIZE (512 * 1024 * 1024) -#define KERNEL_IMAGE_START _AC(0xffffffff80000000, UL) - -#ifndef __ASSEMBLY__ -void clear_page(void *page); -void copy_page(void *to, void *from); - -/* duplicated to the one in bootmem.h */ -extern unsigned long max_pfn; -extern unsigned long phys_base; - -extern unsigned long __phys_addr(unsigned long); -#define __phys_reloc_hide(x) (x) - -/* - * These are used to make use of C type-checking.. - */ -typedef unsigned long pteval_t; -typedef unsigned long pmdval_t; -typedef unsigned long pudval_t; -typedef unsigned long pgdval_t; -typedef unsigned long pgprotval_t; - -typedef struct page *pgtable_t; - -typedef struct { pteval_t pte; } pte_t; - -#define vmemmap ((struct page *)VMEMMAP_START) - -extern unsigned long init_memory_mapping(unsigned long start, - unsigned long end); - -extern void initmem_init(unsigned long start_pfn, unsigned long end_pfn); -extern void free_initmem(void); - -extern void init_extra_mapping_uc(unsigned long phys, unsigned long size); -extern void init_extra_mapping_wb(unsigned long phys, unsigned long size); - -#endif /* !__ASSEMBLY__ */ - -#ifdef CONFIG_FLATMEM -#define pfn_valid(pfn) ((pfn) < max_pfn) -#endif - +#include #endif /* _ASM_X86_PAGE_64_H */ diff --git a/arch/x86/include/asm/page_64.h.rej b/arch/x86/include/asm/page_64.h.rej new file mode 100644 index 00000000000..9b1807f1859 --- /dev/null +++ b/arch/x86/include/asm/page_64.h.rej @@ -0,0 +1,114 @@ +*************** +*** 1,105 **** + #ifndef _ASM_X86_PAGE_64_H + #define _ASM_X86_PAGE_64_H + +- #define PAGETABLE_LEVELS 4 +- +- #define THREAD_ORDER 1 +- #define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) +- #define CURRENT_MASK (~(THREAD_SIZE - 1)) +- +- #define EXCEPTION_STACK_ORDER 0 +- #define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER) +- +- #define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 1) +- #define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER) +- +- #define IRQSTACK_ORDER 2 +- #define IRQSTACKSIZE (PAGE_SIZE << IRQSTACK_ORDER) +- +- #define STACKFAULT_STACK 1 +- #define DOUBLEFAULT_STACK 2 +- #define NMI_STACK 3 +- #define DEBUG_STACK 4 +- #define MCE_STACK 5 +- #define N_EXCEPTION_STACKS 5 /* hw limit: 7 */ +- +- #define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT) +- #define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1)) +- +- /* +- * Set __PAGE_OFFSET to the most negative possible address + +- * PGDIR_SIZE*16 (pgd slot 272). The gap is to allow a space for a +- * hypervisor to fit. Choosing 16 slots here is arbitrary, but it's +- * what Xen requires. +- */ +- #define __PAGE_OFFSET _AC(0xffff880000000000, UL) +- +- #define __PHYSICAL_START CONFIG_PHYSICAL_START +- #define __KERNEL_ALIGN 0x200000 +- +- /* +- * Make sure kernel is aligned to 2MB address. Catching it at compile +- * time is better. Change your config file and compile the kernel +- * for a 2MB aligned address (CONFIG_PHYSICAL_START) +- */ +- #if (CONFIG_PHYSICAL_START % __KERNEL_ALIGN) != 0 +- #error "CONFIG_PHYSICAL_START must be a multiple of 2MB" +- #endif +- +- #define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START) +- #define __START_KERNEL_map _AC(0xffffffff80000000, UL) +- +- /* See Documentation/x86_64/mm.txt for a description of the memory map. */ +- #define __PHYSICAL_MASK_SHIFT 46 +- #define __VIRTUAL_MASK_SHIFT 48 +- +- /* +- * Kernel image size is limited to 512 MB (see level2_kernel_pgt in +- * arch/x86/kernel/head_64.S), and it is mapped here: +- */ +- #define KERNEL_IMAGE_SIZE (512 * 1024 * 1024) +- #define KERNEL_IMAGE_START _AC(0xffffffff80000000, UL) +- +- #ifndef __ASSEMBLY__ +- void clear_page(void *page); +- void copy_page(void *to, void *from); +- +- /* duplicated to the one in bootmem.h */ +- extern unsigned long max_pfn; +- extern unsigned long phys_base; +- +- extern unsigned long __phys_addr(unsigned long); +- #define __phys_reloc_hide(x) (x) +- +- /* +- * These are used to make use of C type-checking.. +- */ +- typedef unsigned long pteval_t; +- typedef unsigned long pmdval_t; +- typedef unsigned long pudval_t; +- typedef unsigned long pgdval_t; +- typedef unsigned long pgprotval_t; +- +- typedef struct page *pgtable_t; +- +- typedef struct { pteval_t pte; } pte_t; +- +- #define vmemmap ((struct page *)VMEMMAP_START) +- +- extern unsigned long init_memory_mapping(unsigned long start, +- unsigned long end); +- +- extern void initmem_init(unsigned long start_pfn, unsigned long end_pfn); +- extern void free_initmem(void); +- +- extern void init_extra_mapping_uc(unsigned long phys, unsigned long size); +- extern void init_extra_mapping_wb(unsigned long phys, unsigned long size); +- +- #endif /* !__ASSEMBLY__ */ +- +- #ifdef CONFIG_FLATMEM +- #define pfn_valid(pfn) ((pfn) < max_pfn) +- #endif +- + + #endif /* _ASM_X86_PAGE_64_H */ +--- 1,6 ---- + #ifndef _ASM_X86_PAGE_64_H + #define _ASM_X86_PAGE_64_H + ++ #include + + #endif /* _ASM_X86_PAGE_64_H */ diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h new file mode 100644 index 00000000000..d00cd388082 --- /dev/null +++ b/arch/x86/include/asm/page_64_types.h @@ -0,0 +1,102 @@ +#ifndef _ASM_X86_PAGE_64_DEFS_H +#define _ASM_X86_PAGE_64_DEFS_H + +#define PAGETABLE_LEVELS 4 + +#define THREAD_ORDER 1 +#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) +#define CURRENT_MASK (~(THREAD_SIZE - 1)) + +#define EXCEPTION_STACK_ORDER 0 +#define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER) + +#define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 1) +#define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER) + +#define IRQ_STACK_ORDER 2 +#define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER) + +#define STACKFAULT_STACK 1 +#define DOUBLEFAULT_STACK 2 +#define NMI_STACK 3 +#define DEBUG_STACK 4 +#define MCE_STACK 5 +#define N_EXCEPTION_STACKS 5 /* hw limit: 7 */ + +#define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT) +#define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1)) + +/* + * Set __PAGE_OFFSET to the most negative possible address + + * PGDIR_SIZE*16 (pgd slot 272). The gap is to allow a space for a + * hypervisor to fit. Choosing 16 slots here is arbitrary, but it's + * what Xen requires. + */ +#define __PAGE_OFFSET _AC(0xffff880000000000, UL) + +#define __PHYSICAL_START CONFIG_PHYSICAL_START +#define __KERNEL_ALIGN 0x200000 + +/* + * Make sure kernel is aligned to 2MB address. Catching it at compile + * time is better. Change your config file and compile the kernel + * for a 2MB aligned address (CONFIG_PHYSICAL_START) + */ +#if (CONFIG_PHYSICAL_START % __KERNEL_ALIGN) != 0 +#error "CONFIG_PHYSICAL_START must be a multiple of 2MB" +#endif + +#define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START) +#define __START_KERNEL_map _AC(0xffffffff80000000, UL) + +/* See Documentation/x86_64/mm.txt for a description of the memory map. */ +#define __PHYSICAL_MASK_SHIFT 46 +#define __VIRTUAL_MASK_SHIFT 48 + +/* + * Kernel image size is limited to 512 MB (see level2_kernel_pgt in + * arch/x86/kernel/head_64.S), and it is mapped here: + */ +#define KERNEL_IMAGE_SIZE (512 * 1024 * 1024) +#define KERNEL_IMAGE_START _AC(0xffffffff80000000, UL) + +#ifndef __ASSEMBLY__ +void clear_page(void *page); +void copy_page(void *to, void *from); + +/* duplicated to the one in bootmem.h */ +extern unsigned long max_pfn; +extern unsigned long phys_base; + +extern unsigned long __phys_addr(unsigned long); +#define __phys_reloc_hide(x) (x) + +/* + * These are used to make use of C type-checking.. + */ +typedef unsigned long pteval_t; +typedef unsigned long pmdval_t; +typedef unsigned long pudval_t; +typedef unsigned long pgdval_t; +typedef unsigned long pgprotval_t; + +typedef struct { pteval_t pte; } pte_t; + +#define vmemmap ((struct page *)VMEMMAP_START) + +extern unsigned long init_memory_mapping(unsigned long start, + unsigned long end); + +extern void initmem_init(unsigned long start_pfn, unsigned long end_pfn); +extern void free_initmem(void); + +extern void init_extra_mapping_uc(unsigned long phys, unsigned long size); +extern void init_extra_mapping_wb(unsigned long phys, unsigned long size); + +#endif /* !__ASSEMBLY__ */ + +#ifdef CONFIG_FLATMEM +#define pfn_valid(pfn) ((pfn) < max_pfn) +#endif + +#endif /* _ASM_X86_PAGE_64_DEFS_H */ diff --git a/arch/x86/include/asm/page_types.h b/arch/x86/include/asm/page_types.h new file mode 100644 index 00000000000..65787ad4c59 --- /dev/null +++ b/arch/x86/include/asm/page_types.h @@ -0,0 +1,77 @@ +#ifndef _ASM_X86_PAGE_DEFS_H +#define _ASM_X86_PAGE_DEFS_H + +#include + +/* PAGE_SHIFT determines the page size */ +#define PAGE_SHIFT 12 +#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +#define __PHYSICAL_MASK ((phys_addr_t)(1ULL << __PHYSICAL_MASK_SHIFT) - 1) +#define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1) + +/* Cast PAGE_MASK to a signed type so that it is sign-extended if + virtual addresses are 32-bits but physical addresses are larger + (ie, 32-bit PAE). */ +#define PHYSICAL_PAGE_MASK (((signed long)PAGE_MASK) & __PHYSICAL_MASK) + +/* PTE_PFN_MASK extracts the PFN from a (pte|pmd|pud|pgd)val_t */ +#define PTE_PFN_MASK ((pteval_t)PHYSICAL_PAGE_MASK) + +/* PTE_FLAGS_MASK extracts the flags from a (pte|pmd|pud|pgd)val_t */ +#define PTE_FLAGS_MASK (~PTE_PFN_MASK) + +#define PMD_PAGE_SIZE (_AC(1, UL) << PMD_SHIFT) +#define PMD_PAGE_MASK (~(PMD_PAGE_SIZE-1)) + +#define HPAGE_SHIFT PMD_SHIFT +#define HPAGE_SIZE (_AC(1,UL) << HPAGE_SHIFT) +#define HPAGE_MASK (~(HPAGE_SIZE - 1)) +#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) + +#define HUGE_MAX_HSTATE 2 + +#define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) + +#define VM_DATA_DEFAULT_FLAGS \ + (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ + VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + +#ifdef CONFIG_X86_64 +#include +#else +#include +#endif /* CONFIG_X86_64 */ + +#ifndef __ASSEMBLY__ + +#include + +typedef struct { pgdval_t pgd; } pgd_t; +typedef struct { pgprotval_t pgprot; } pgprot_t; + +#if PAGETABLE_LEVELS > 3 +typedef struct { pudval_t pud; } pud_t; +#endif + +#if PAGETABLE_LEVELS > 2 +typedef struct { pmdval_t pmd; } pmd_t; +#endif + +typedef struct page *pgtable_t; + +extern int page_is_ram(unsigned long pagenr); +extern int pagerange_is_ram(unsigned long start, unsigned long end); +extern int devmem_is_allowed(unsigned long pagenr); +extern void map_devmem(unsigned long pfn, unsigned long size, + pgprot_t vma_prot); +extern void unmap_devmem(unsigned long pfn, unsigned long size, + pgprot_t vma_prot); + +extern unsigned long max_low_pfn_mapped; +extern unsigned long max_pfn_mapped; + +#endif /* !__ASSEMBLY__ */ + +#endif /* _ASM_X86_PAGE_DEFS_H */ -- cgit From 1dfc07aad5479f1fb832ff6f61a5a9ce822d9e1f Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Sun, 8 Feb 2009 23:24:26 -0800 Subject: x86: move 2 and 3 level asm-generic defs into page-defs Signed-off-by: Jeremy Fitzhardinge --- arch/x86/include/asm/page.h | 4 ---- arch/x86/include/asm/page_types.h | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/page.h b/arch/x86/include/asm/page.h index 3b2d2af951c..da54f6c48a7 100644 --- a/arch/x86/include/asm/page.h +++ b/arch/x86/include/asm/page.h @@ -58,8 +58,6 @@ static inline pudval_t native_pud_val(pud_t pud) return pud.pud; } #else /* PAGETABLE_LEVELS == 3 */ -#include - static inline pudval_t native_pud_val(pud_t pud) { return native_pgd_val(pud.pgd); @@ -82,8 +80,6 @@ static inline pmdval_t native_pmd_val(pmd_t pmd) } #else /* PAGETABLE_LEVELS == 2 */ -#include - static inline pmdval_t native_pmd_val(pmd_t pmd) { return native_pgd_val(pmd.pud.pgd); diff --git a/arch/x86/include/asm/page_types.h b/arch/x86/include/asm/page_types.h index 65787ad4c59..92dfd251a65 100644 --- a/arch/x86/include/asm/page_types.h +++ b/arch/x86/include/asm/page_types.h @@ -53,10 +53,14 @@ typedef struct { pgprotval_t pgprot; } pgprot_t; #if PAGETABLE_LEVELS > 3 typedef struct { pudval_t pud; } pud_t; +#else +#include #endif #if PAGETABLE_LEVELS > 2 typedef struct { pmdval_t pmd; } pmd_t; +#else +#include #endif typedef struct page *pgtable_t; -- cgit From e42778de31d78ae262a3b901264eabefb9c3b51b Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Sun, 8 Feb 2009 23:42:01 -0800 Subject: x86: move defs around to allow paravirt.h to just include page_types.h Signed-off-by: Jeremy Fitzhardinge --- arch/x86/include/asm/page.h | 78 ------------------------------------ arch/x86/include/asm/page_32_types.h | 2 + arch/x86/include/asm/page_types.h | 74 ++++++++++++++++++++++++++++++++++ arch/x86/include/asm/paravirt.h | 2 +- 4 files changed, 77 insertions(+), 79 deletions(-) diff --git a/arch/x86/include/asm/page.h b/arch/x86/include/asm/page.h index da54f6c48a7..28423609b00 100644 --- a/arch/x86/include/asm/page.h +++ b/arch/x86/include/asm/page.h @@ -31,84 +31,6 @@ static inline void copy_user_page(void *to, void *from, unsigned long vaddr, alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr) #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE -static inline pgd_t native_make_pgd(pgdval_t val) -{ - return (pgd_t) { val }; -} - -static inline pgdval_t native_pgd_val(pgd_t pgd) -{ - return pgd.pgd; -} - -static inline pgdval_t pgd_flags(pgd_t pgd) -{ - return native_pgd_val(pgd) & PTE_FLAGS_MASK; -} - -#if PAGETABLE_LEVELS >= 3 -#if PAGETABLE_LEVELS == 4 -static inline pud_t native_make_pud(pmdval_t val) -{ - return (pud_t) { val }; -} - -static inline pudval_t native_pud_val(pud_t pud) -{ - return pud.pud; -} -#else /* PAGETABLE_LEVELS == 3 */ -static inline pudval_t native_pud_val(pud_t pud) -{ - return native_pgd_val(pud.pgd); -} -#endif /* PAGETABLE_LEVELS == 4 */ - -static inline pudval_t pud_flags(pud_t pud) -{ - return native_pud_val(pud) & PTE_FLAGS_MASK; -} - -static inline pmd_t native_make_pmd(pmdval_t val) -{ - return (pmd_t) { val }; -} - -static inline pmdval_t native_pmd_val(pmd_t pmd) -{ - return pmd.pmd; -} - -#else /* PAGETABLE_LEVELS == 2 */ -static inline pmdval_t native_pmd_val(pmd_t pmd) -{ - return native_pgd_val(pmd.pud.pgd); -} -#endif /* PAGETABLE_LEVELS >= 3 */ - -static inline pmdval_t pmd_flags(pmd_t pmd) -{ - return native_pmd_val(pmd) & PTE_FLAGS_MASK; -} - -static inline pte_t native_make_pte(pteval_t val) -{ - return (pte_t) { .pte = val }; -} - -static inline pteval_t native_pte_val(pte_t pte) -{ - return pte.pte; -} - -static inline pteval_t pte_flags(pte_t pte) -{ - return native_pte_val(pte) & PTE_FLAGS_MASK; -} - -#define pgprot_val(x) ((x).pgprot) -#define __pgprot(x) ((pgprot_t) { (x) } ) - #ifdef CONFIG_PARAVIRT #include #else /* !CONFIG_PARAVIRT */ diff --git a/arch/x86/include/asm/page_32_types.h b/arch/x86/include/asm/page_32_types.h index b7b5402d7ab..83f820a2b10 100644 --- a/arch/x86/include/asm/page_32_types.h +++ b/arch/x86/include/asm/page_32_types.h @@ -43,6 +43,8 @@ #ifndef __ASSEMBLY__ +#include + #ifdef CONFIG_X86_PAE typedef u64 pteval_t; typedef u64 pmdval_t; diff --git a/arch/x86/include/asm/page_types.h b/arch/x86/include/asm/page_types.h index 92dfd251a65..c41e3e8f227 100644 --- a/arch/x86/include/asm/page_types.h +++ b/arch/x86/include/asm/page_types.h @@ -51,18 +51,92 @@ typedef struct { pgdval_t pgd; } pgd_t; typedef struct { pgprotval_t pgprot; } pgprot_t; +static inline pgd_t native_make_pgd(pgdval_t val) +{ + return (pgd_t) { val }; +} + +static inline pgdval_t native_pgd_val(pgd_t pgd) +{ + return pgd.pgd; +} + +static inline pgdval_t pgd_flags(pgd_t pgd) +{ + return native_pgd_val(pgd) & PTE_FLAGS_MASK; +} + #if PAGETABLE_LEVELS > 3 typedef struct { pudval_t pud; } pud_t; + +static inline pud_t native_make_pud(pmdval_t val) +{ + return (pud_t) { val }; +} + +static inline pudval_t native_pud_val(pud_t pud) +{ + return pud.pud; +} #else #include + +static inline pudval_t native_pud_val(pud_t pud) +{ + return native_pgd_val(pud.pgd); +} #endif #if PAGETABLE_LEVELS > 2 typedef struct { pmdval_t pmd; } pmd_t; + +static inline pudval_t pud_flags(pud_t pud) +{ + return native_pud_val(pud) & PTE_FLAGS_MASK; +} + +static inline pmd_t native_make_pmd(pmdval_t val) +{ + return (pmd_t) { val }; +} + +static inline pmdval_t native_pmd_val(pmd_t pmd) +{ + return pmd.pmd; +} #else #include + +static inline pmdval_t native_pmd_val(pmd_t pmd) +{ + return native_pgd_val(pmd.pud.pgd); +} #endif +static inline pmdval_t pmd_flags(pmd_t pmd) +{ + return native_pmd_val(pmd) & PTE_FLAGS_MASK; +} + +static inline pte_t native_make_pte(pteval_t val) +{ + return (pte_t) { .pte = val }; +} + +static inline pteval_t native_pte_val(pte_t pte) +{ + return pte.pte; +} + +static inline pteval_t pte_flags(pte_t pte) +{ + return native_pte_val(pte) & PTE_FLAGS_MASK; +} + +#define pgprot_val(x) ((x).pgprot) +#define __pgprot(x) ((pgprot_t) { (x) } ) + + typedef struct page *pgtable_t; extern int page_is_ram(unsigned long pagenr); diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index c85e7475e17..db570f23b22 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h @@ -4,7 +4,7 @@ * para-virtualization: those hooks are defined here. */ #ifdef CONFIG_PARAVIRT -#include +#include #include /* Bitmask of what can be clobbered: usually at least eax. */ -- cgit From e2f5bda94152fa567f6b48126741014123f982b8 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Mon, 9 Feb 2009 00:09:52 -0800 Subject: x86: define pud_flags and pud_large properly to allow non-PAE builds --- arch/x86/include/asm/page_types.h | 10 +++++----- arch/x86/include/asm/pgtable.h | 7 ++++++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/page_types.h b/arch/x86/include/asm/page_types.h index c41e3e8f227..0733853e7c8 100644 --- a/arch/x86/include/asm/page_types.h +++ b/arch/x86/include/asm/page_types.h @@ -90,11 +90,6 @@ static inline pudval_t native_pud_val(pud_t pud) #if PAGETABLE_LEVELS > 2 typedef struct { pmdval_t pmd; } pmd_t; -static inline pudval_t pud_flags(pud_t pud) -{ - return native_pud_val(pud) & PTE_FLAGS_MASK; -} - static inline pmd_t native_make_pmd(pmdval_t val) { return (pmd_t) { val }; @@ -113,6 +108,11 @@ static inline pmdval_t native_pmd_val(pmd_t pmd) } #endif +static inline pudval_t pud_flags(pud_t pud) +{ + return native_pud_val(pud) & PTE_FLAGS_MASK; +} + static inline pmdval_t pmd_flags(pmd_t pmd) { return native_pmd_val(pmd) & PTE_FLAGS_MASK; diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 10404e7bf32..9f508509797 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -398,7 +398,7 @@ static inline unsigned long pmd_pfn(pmd_t pmd) static inline int pud_large(pud_t pud) { - return (pud_flags(pud) & (_PAGE_PSE | _PAGE_PRESENT)) == + return (pud_val(pud) & (_PAGE_PSE | _PAGE_PRESENT)) == (_PAGE_PSE | _PAGE_PRESENT); } @@ -406,6 +406,11 @@ static inline int pud_bad(pud_t pud) { return (pud_flags(pud) & ~(_KERNPG_TABLE | _PAGE_USER)) != 0; } +#else +static inline int pud_large(pud_t pud) +{ + return 0; +} #endif /* PAGETABLE_LEVELS > 2 */ #if PAGETABLE_LEVELS > 3 -- cgit From 54321d947ae9d6a051b81e3eccaf2d8658aeecc6 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 11 Feb 2009 10:20:05 -0800 Subject: x86: move pte types into pgtable*.h pgtable*.h is intended for definitions relating to actual pagetables and their entries, so move all the definitions for (pte|pmd|pud|pgd)(val)?_t to the appropriate pgtable*.h headers. Signed-off-by: Jeremy Fitzhardinge --- arch/x86/include/asm/page.h | 22 ------ arch/x86/include/asm/page_32_types.h | 30 -------- arch/x86/include/asm/page_64_types.h | 11 --- arch/x86/include/asm/page_types.h | 97 +------------------------ arch/x86/include/asm/paravirt.h | 2 +- arch/x86/include/asm/pgtable-2level_types.h | 15 ++++ arch/x86/include/asm/pgtable-3level_types.h | 18 +++++ arch/x86/include/asm/pgtable.h | 103 +++++++++++++++----------- arch/x86/include/asm/pgtable_64_types.h | 16 +++++ arch/x86/include/asm/pgtable_types.h | 107 ++++++++++++++++++++++++++-- arch/x86/include/asm/processor.h | 1 + 11 files changed, 215 insertions(+), 207 deletions(-) diff --git a/arch/x86/include/asm/page.h b/arch/x86/include/asm/page.h index 28423609b00..467ce69306b 100644 --- a/arch/x86/include/asm/page.h +++ b/arch/x86/include/asm/page.h @@ -31,28 +31,6 @@ static inline void copy_user_page(void *to, void *from, unsigned long vaddr, alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr) #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE -#ifdef CONFIG_PARAVIRT -#include -#else /* !CONFIG_PARAVIRT */ - -#define pgd_val(x) native_pgd_val(x) -#define __pgd(x) native_make_pgd(x) - -#ifndef __PAGETABLE_PUD_FOLDED -#define pud_val(x) native_pud_val(x) -#define __pud(x) native_make_pud(x) -#endif - -#ifndef __PAGETABLE_PMD_FOLDED -#define pmd_val(x) native_pmd_val(x) -#define __pmd(x) native_make_pmd(x) -#endif - -#define pte_val(x) native_pte_val(x) -#define __pte(x) native_make_pte(x) - -#endif /* CONFIG_PARAVIRT */ - #define __pa(x) __phys_addr((unsigned long)(x)) #define __pa_nodebug(x) __phys_addr_nodebug((unsigned long)(x)) /* __pa_symbol should be used for C visible symbols. diff --git a/arch/x86/include/asm/page_32_types.h b/arch/x86/include/asm/page_32_types.h index 83f820a2b10..b5486aaf36e 100644 --- a/arch/x86/include/asm/page_32_types.h +++ b/arch/x86/include/asm/page_32_types.h @@ -43,36 +43,6 @@ #ifndef __ASSEMBLY__ -#include - -#ifdef CONFIG_X86_PAE -typedef u64 pteval_t; -typedef u64 pmdval_t; -typedef u64 pudval_t; -typedef u64 pgdval_t; -typedef u64 pgprotval_t; - -typedef union { - struct { - unsigned long pte_low, pte_high; - }; - pteval_t pte; -} pte_t; -#else /* !CONFIG_X86_PAE */ -typedef unsigned long pteval_t; -typedef unsigned long pmdval_t; -typedef unsigned long pudval_t; -typedef unsigned long pgdval_t; -typedef unsigned long pgprotval_t; - -typedef union { - pteval_t pte; - pteval_t pte_low; -} pte_t; -#endif /* CONFIG_X86_PAE */ - -extern int nx_enabled; - /* * This much address space is reserved for vmalloc() and iomap() * as well as fixmap mappings. diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h index d00cd388082..bc73af3eda9 100644 --- a/arch/x86/include/asm/page_64_types.h +++ b/arch/x86/include/asm/page_64_types.h @@ -71,17 +71,6 @@ extern unsigned long phys_base; extern unsigned long __phys_addr(unsigned long); #define __phys_reloc_hide(x) (x) -/* - * These are used to make use of C type-checking.. - */ -typedef unsigned long pteval_t; -typedef unsigned long pmdval_t; -typedef unsigned long pudval_t; -typedef unsigned long pgdval_t; -typedef unsigned long pgprotval_t; - -typedef struct { pteval_t pte; } pte_t; - #define vmemmap ((struct page *)VMEMMAP_START) extern unsigned long init_memory_mapping(unsigned long start, diff --git a/arch/x86/include/asm/page_types.h b/arch/x86/include/asm/page_types.h index 0733853e7c8..9f0c9596335 100644 --- a/arch/x86/include/asm/page_types.h +++ b/arch/x86/include/asm/page_types.h @@ -46,106 +46,15 @@ #ifndef __ASSEMBLY__ -#include - -typedef struct { pgdval_t pgd; } pgd_t; -typedef struct { pgprotval_t pgprot; } pgprot_t; - -static inline pgd_t native_make_pgd(pgdval_t val) -{ - return (pgd_t) { val }; -} - -static inline pgdval_t native_pgd_val(pgd_t pgd) -{ - return pgd.pgd; -} - -static inline pgdval_t pgd_flags(pgd_t pgd) -{ - return native_pgd_val(pgd) & PTE_FLAGS_MASK; -} - -#if PAGETABLE_LEVELS > 3 -typedef struct { pudval_t pud; } pud_t; - -static inline pud_t native_make_pud(pmdval_t val) -{ - return (pud_t) { val }; -} - -static inline pudval_t native_pud_val(pud_t pud) -{ - return pud.pud; -} -#else -#include - -static inline pudval_t native_pud_val(pud_t pud) -{ - return native_pgd_val(pud.pgd); -} -#endif - -#if PAGETABLE_LEVELS > 2 -typedef struct { pmdval_t pmd; } pmd_t; - -static inline pmd_t native_make_pmd(pmdval_t val) -{ - return (pmd_t) { val }; -} - -static inline pmdval_t native_pmd_val(pmd_t pmd) -{ - return pmd.pmd; -} -#else -#include - -static inline pmdval_t native_pmd_val(pmd_t pmd) -{ - return native_pgd_val(pmd.pud.pgd); -} -#endif - -static inline pudval_t pud_flags(pud_t pud) -{ - return native_pud_val(pud) & PTE_FLAGS_MASK; -} - -static inline pmdval_t pmd_flags(pmd_t pmd) -{ - return native_pmd_val(pmd) & PTE_FLAGS_MASK; -} - -static inline pte_t native_make_pte(pteval_t val) -{ - return (pte_t) { .pte = val }; -} - -static inline pteval_t native_pte_val(pte_t pte) -{ - return pte.pte; -} - -static inline pteval_t pte_flags(pte_t pte) -{ - return native_pte_val(pte) & PTE_FLAGS_MASK; -} - -#define pgprot_val(x) ((x).pgprot) -#define __pgprot(x) ((pgprot_t) { (x) } ) - - -typedef struct page *pgtable_t; +struct pgprot; extern int page_is_ram(unsigned long pagenr); extern int pagerange_is_ram(unsigned long start, unsigned long end); extern int devmem_is_allowed(unsigned long pagenr); extern void map_devmem(unsigned long pfn, unsigned long size, - pgprot_t vma_prot); + struct pgprot vma_prot); extern void unmap_devmem(unsigned long pfn, unsigned long size, - pgprot_t vma_prot); + struct pgprot vma_prot); extern unsigned long max_low_pfn_mapped; extern unsigned long max_pfn_mapped; diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index db570f23b22..7ed73ccd74e 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h @@ -4,7 +4,7 @@ * para-virtualization: those hooks are defined here. */ #ifdef CONFIG_PARAVIRT -#include +#include #include /* Bitmask of what can be clobbered: usually at least eax. */ diff --git a/arch/x86/include/asm/pgtable-2level_types.h b/arch/x86/include/asm/pgtable-2level_types.h index d77db8990ea..09ae67efceb 100644 --- a/arch/x86/include/asm/pgtable-2level_types.h +++ b/arch/x86/include/asm/pgtable-2level_types.h @@ -1,6 +1,21 @@ #ifndef _ASM_X86_PGTABLE_2LEVEL_DEFS_H #define _ASM_X86_PGTABLE_2LEVEL_DEFS_H +#ifndef __ASSEMBLY__ +#include + +typedef unsigned long pteval_t; +typedef unsigned long pmdval_t; +typedef unsigned long pudval_t; +typedef unsigned long pgdval_t; +typedef unsigned long pgprotval_t; + +typedef union { + pteval_t pte; + pteval_t pte_low; +} pte_t; +#endif /* !__ASSEMBLY__ */ + #define SHARED_KERNEL_PMD 0 /* diff --git a/arch/x86/include/asm/pgtable-3level_types.h b/arch/x86/include/asm/pgtable-3level_types.h index 62561367653..bcc89625ebe 100644 --- a/arch/x86/include/asm/pgtable-3level_types.h +++ b/arch/x86/include/asm/pgtable-3level_types.h @@ -1,6 +1,23 @@ #ifndef _ASM_X86_PGTABLE_3LEVEL_DEFS_H #define _ASM_X86_PGTABLE_3LEVEL_DEFS_H +#ifndef __ASSEMBLY__ +#include + +typedef u64 pteval_t; +typedef u64 pmdval_t; +typedef u64 pudval_t; +typedef u64 pgdval_t; +typedef u64 pgprotval_t; + +typedef union { + struct { + unsigned long pte_low, pte_high; + }; + pteval_t pte; +} pte_t; +#endif /* !__ASSEMBLY__ */ + #ifdef CONFIG_PARAVIRT #define SHARED_KERNEL_PMD (pv_info.shared_kernel_pmd) #else @@ -25,4 +42,5 @@ */ #define PTRS_PER_PTE 512 + #endif /* _ASM_X86_PGTABLE_3LEVEL_DEFS_H */ diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 9f508509797..b0d1066ab6a 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -25,6 +25,66 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; extern spinlock_t pgd_lock; extern struct list_head pgd_list; +#ifdef CONFIG_PARAVIRT +#include +#else /* !CONFIG_PARAVIRT */ +#define set_pte(ptep, pte) native_set_pte(ptep, pte) +#define set_pte_at(mm, addr, ptep, pte) native_set_pte_at(mm, addr, ptep, pte) + +#define set_pte_present(mm, addr, ptep, pte) \ + native_set_pte_present(mm, addr, ptep, pte) +#define set_pte_atomic(ptep, pte) \ + native_set_pte_atomic(ptep, pte) + +#define set_pmd(pmdp, pmd) native_set_pmd(pmdp, pmd) + +#ifndef __PAGETABLE_PUD_FOLDED +#define set_pgd(pgdp, pgd) native_set_pgd(pgdp, pgd) +#define pgd_clear(pgd) native_pgd_clear(pgd) +#endif + +#ifndef set_pud +# define set_pud(pudp, pud) native_set_pud(pudp, pud) +#endif + +#ifndef __PAGETABLE_PMD_FOLDED +#define pud_clear(pud) native_pud_clear(pud) +#endif + +#define pte_clear(mm, addr, ptep) native_pte_clear(mm, addr, ptep) +#define pmd_clear(pmd) native_pmd_clear(pmd) + +#define pte_update(mm, addr, ptep) do { } while (0) +#define pte_update_defer(mm, addr, ptep) do { } while (0) + +static inline void __init paravirt_pagetable_setup_start(pgd_t *base) +{ + native_pagetable_setup_start(base); +} + +static inline void __init paravirt_pagetable_setup_done(pgd_t *base) +{ + native_pagetable_setup_done(base); +} + +#define pgd_val(x) native_pgd_val(x) +#define __pgd(x) native_make_pgd(x) + +#ifndef __PAGETABLE_PUD_FOLDED +#define pud_val(x) native_pud_val(x) +#define __pud(x) native_make_pud(x) +#endif + +#ifndef __PAGETABLE_PMD_FOLDED +#define pmd_val(x) native_pmd_val(x) +#define __pmd(x) native_make_pmd(x) +#endif + +#define pte_val(x) native_pte_val(x) +#define __pte(x) native_make_pte(x) + +#endif /* CONFIG_PARAVIRT */ + /* * The following only work if pte_present() is true. * Undefined behaviour if not.. @@ -214,49 +274,6 @@ static inline int is_new_memtype_allowed(unsigned long flags, return 1; } -#ifdef CONFIG_PARAVIRT -#include -#else /* !CONFIG_PARAVIRT */ -#define set_pte(ptep, pte) native_set_pte(ptep, pte) -#define set_pte_at(mm, addr, ptep, pte) native_set_pte_at(mm, addr, ptep, pte) - -#define set_pte_present(mm, addr, ptep, pte) \ - native_set_pte_present(mm, addr, ptep, pte) -#define set_pte_atomic(ptep, pte) \ - native_set_pte_atomic(ptep, pte) - -#define set_pmd(pmdp, pmd) native_set_pmd(pmdp, pmd) - -#ifndef __PAGETABLE_PUD_FOLDED -#define set_pgd(pgdp, pgd) native_set_pgd(pgdp, pgd) -#define pgd_clear(pgd) native_pgd_clear(pgd) -#endif - -#ifndef set_pud -# define set_pud(pudp, pud) native_set_pud(pudp, pud) -#endif - -#ifndef __PAGETABLE_PMD_FOLDED -#define pud_clear(pud) native_pud_clear(pud) -#endif - -#define pte_clear(mm, addr, ptep) native_pte_clear(mm, addr, ptep) -#define pmd_clear(pmd) native_pmd_clear(pmd) - -#define pte_update(mm, addr, ptep) do { } while (0) -#define pte_update_defer(mm, addr, ptep) do { } while (0) - -static inline void __init paravirt_pagetable_setup_start(pgd_t *base) -{ - native_pagetable_setup_start(base); -} - -static inline void __init paravirt_pagetable_setup_done(pgd_t *base) -{ - native_pagetable_setup_done(base); -} -#endif /* CONFIG_PARAVIRT */ - #endif /* __ASSEMBLY__ */ #ifdef CONFIG_X86_32 diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h index ffaf1934068..2f59135c6f2 100644 --- a/arch/x86/include/asm/pgtable_64_types.h +++ b/arch/x86/include/asm/pgtable_64_types.h @@ -1,6 +1,22 @@ #ifndef _ASM_X86_PGTABLE_64_DEFS_H #define _ASM_X86_PGTABLE_64_DEFS_H +#ifndef __ASSEMBLY__ +#include + +/* + * These are used to make use of C type-checking.. + */ +typedef unsigned long pteval_t; +typedef unsigned long pmdval_t; +typedef unsigned long pudval_t; +typedef unsigned long pgdval_t; +typedef unsigned long pgprotval_t; + +typedef struct { pteval_t pte; } pte_t; + +#endif /* !__ASSEMBLY__ */ + #define SHARED_KERNEL_PMD 0 /* diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h index e5d5a8d3577..a7452f10930 100644 --- a/arch/x86/include/asm/pgtable_types.h +++ b/arch/x86/include/asm/pgtable_types.h @@ -162,9 +162,110 @@ #define PGD_IDENT_ATTR 0x001 /* PRESENT (no other attributes) */ #endif +#ifdef CONFIG_X86_32 +# include "pgtable_32_types.h" +#else +# include "pgtable_64_types.h" +#endif + #ifndef __ASSEMBLY__ +#include + +typedef struct pgprot { pgprotval_t pgprot; } pgprot_t; + +typedef struct { pgdval_t pgd; } pgd_t; + +static inline pgd_t native_make_pgd(pgdval_t val) +{ + return (pgd_t) { val }; +} + +static inline pgdval_t native_pgd_val(pgd_t pgd) +{ + return pgd.pgd; +} + +static inline pgdval_t pgd_flags(pgd_t pgd) +{ + return native_pgd_val(pgd) & PTE_FLAGS_MASK; +} + +#if PAGETABLE_LEVELS > 3 +typedef struct { pudval_t pud; } pud_t; + +static inline pud_t native_make_pud(pmdval_t val) +{ + return (pud_t) { val }; +} + +static inline pudval_t native_pud_val(pud_t pud) +{ + return pud.pud; +} +#else +#include + +static inline pudval_t native_pud_val(pud_t pud) +{ + return native_pgd_val(pud.pgd); +} +#endif + +#if PAGETABLE_LEVELS > 2 +typedef struct { pmdval_t pmd; } pmd_t; + +static inline pmd_t native_make_pmd(pmdval_t val) +{ + return (pmd_t) { val }; +} + +static inline pmdval_t native_pmd_val(pmd_t pmd) +{ + return pmd.pmd; +} +#else +#include + +static inline pmdval_t native_pmd_val(pmd_t pmd) +{ + return native_pgd_val(pmd.pud.pgd); +} +#endif + +static inline pudval_t pud_flags(pud_t pud) +{ + return native_pud_val(pud) & PTE_FLAGS_MASK; +} + +static inline pmdval_t pmd_flags(pmd_t pmd) +{ + return native_pmd_val(pmd) & PTE_FLAGS_MASK; +} + +static inline pte_t native_make_pte(pteval_t val) +{ + return (pte_t) { .pte = val }; +} + +static inline pteval_t native_pte_val(pte_t pte) +{ + return pte.pte; +} + +static inline pteval_t pte_flags(pte_t pte) +{ + return native_pte_val(pte) & PTE_FLAGS_MASK; +} + +#define pgprot_val(x) ((x).pgprot) +#define __pgprot(x) ((pgprot_t) { (x) } ) + + +typedef struct page *pgtable_t; + extern pteval_t __supported_pte_mask; +extern int nx_enabled; #define pgprot_writecombine pgprot_writecombine extern pgprot_t pgprot_writecombine(pgprot_t prot); @@ -217,10 +318,4 @@ extern pte_t *lookup_address(unsigned long address, unsigned int *level); #endif /* !__ASSEMBLY__ */ -#ifdef CONFIG_X86_32 -# include "pgtable_32_types.h" -#else -# include "pgtable_64_types.h" -#endif - #endif /* _ASM_X86_PGTABLE_DEFS_H */ diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 656d02ea509..96302880774 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -16,6 +16,7 @@ struct mm_struct; #include #include #include +#include #include #include #include -- cgit From 32cf9a16f4af01573ddec1eb073111fc20a9d7d4 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 12 Feb 2009 00:06:42 +0100 Subject: ALSA: mtpav - Fix initial value for input hwport Fix the initial value for input hwport. The old value (-1) may cause Oops when an realtime MIDI byte is received before the input port is explicitly given. Instead, now it's set to the broadcasting as default. Tested-by: Holger Dehnhardt Cc: Signed-off-by: Takashi Iwai --- sound/drivers/mtpav.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c index 5b89c0883d6..48b64e6b267 100644 --- a/sound/drivers/mtpav.c +++ b/sound/drivers/mtpav.c @@ -706,7 +706,6 @@ static int __devinit snd_mtpav_probe(struct platform_device *dev) mtp_card->card = card; mtp_card->irq = -1; mtp_card->share_irq = 0; - mtp_card->inmidiport = 0xffffffff; mtp_card->inmidistate = 0; mtp_card->outmidihwport = 0xffffffff; init_timer(&mtp_card->timer); @@ -719,6 +718,8 @@ static int __devinit snd_mtpav_probe(struct platform_device *dev) if (err < 0) goto __error; + mtp_card->inmidiport = mtp_card->num_ports + MTPAV_PIDX_BROADCAST; + err = snd_mtpav_get_ISA(mtp_card); if (err < 0) goto __error; -- cgit From 26a74f1f61c5bba1c0b46e67e91e921e941f76d7 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 12 Feb 2009 00:13:19 +0100 Subject: ALSA: hda - Register (new) devices at reconfig The devices that have been newly added during reconfig must be registered. Otherwise they won't be visible to user-space. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_hwdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c index 300ab407cf4..482fb0304ca 100644 --- a/sound/pci/hda/hda_hwdep.c +++ b/sound/pci/hda/hda_hwdep.c @@ -175,7 +175,7 @@ static int reconfig_codec(struct hda_codec *codec) err = snd_hda_codec_build_controls(codec); if (err < 0) return err; - return 0; + return snd_card_register(codec->bus->card); } /* -- cgit From 1d93e52eb48df986a3c4d5ad8a520bf1f6837367 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Wed, 11 Feb 2009 08:47:19 -0700 Subject: dmaengine: update kerneldoc Some of the kerneldoc comments in the dmaengine header describe already removed structure members. Remove them. Also add a short description for dma_device->device_is_tx_complete. Signed-off-by: Johannes Weiner Signed-off-by: Dan Williams --- include/linux/dmaengine.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 3e68469c188..087e79acf8c 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -97,7 +97,6 @@ typedef struct { DECLARE_BITMAP(bits, DMA_TX_TYPE_END); } dma_cap_mask_t; /** * struct dma_chan_percpu - the per-CPU part of struct dma_chan - * @refcount: local_t used for open-coded "bigref" counting * @memcpy_count: transaction counter * @bytes_transferred: byte counter */ @@ -114,9 +113,6 @@ struct dma_chan_percpu { * @cookie: last cookie value returned to client * @chan_id: channel ID for sysfs * @dev: class device for sysfs - * @refcount: kref, used in "bigref" slow-mode - * @slow_ref: indicates that the DMA channel is free - * @rcu: the DMA channel's RCU head * @device_node: used to add this to the device chan list * @local: per-cpu pointer to a struct dma_chan_percpu * @client-count: how many clients are using this channel @@ -211,8 +207,6 @@ struct dma_async_tx_descriptor { * @global_node: list_head for global dma_device_list * @cap_mask: one or more dma_capability flags * @max_xor: maximum number of xor sources, 0 if no capability - * @refcount: reference count - * @done: IO completion struct * @dev_id: unique device ID * @dev: struct device reference for dma mapping api * @device_alloc_chan_resources: allocate resources and return the @@ -225,6 +219,7 @@ struct dma_async_tx_descriptor { * @device_prep_dma_interrupt: prepares an end of chain interrupt operation * @device_prep_slave_sg: prepares a slave dma operation * @device_terminate_all: terminate all pending operations + * @device_is_tx_complete: poll for transaction completion * @device_issue_pending: push pending transactions to hardware */ struct dma_device { -- cgit From 744525092727827a9cf0044074db3e22dcf354fd Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 11 Feb 2009 16:31:40 -0800 Subject: x86: merge sys_rt_sigreturn between 32 and 64 bits Impact: cleanup With the recent changes in the 32-bit code to make system calls which use struct pt_regs take a pointer, sys_rt_sigreturn() have become identical between 32 and 64 bits, and both are empty wrappers around do_rt_sigreturn(). Remove both wrappers and rename both to sys_rt_sigreturn(). Cc: Brian Gerst Cc: Tejun Heo Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/syscalls.h | 2 +- arch/x86/kernel/signal.c | 14 +------------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h index 77bb31a88ba..68b1be10cfa 100644 --- a/arch/x86/include/asm/syscalls.h +++ b/arch/x86/include/asm/syscalls.h @@ -40,7 +40,7 @@ asmlinkage int sys_sigaction(int, const struct old_sigaction __user *, struct old_sigaction __user *); int sys_sigaltstack(struct pt_regs *); unsigned long sys_sigreturn(struct pt_regs *); -int sys_rt_sigreturn(struct pt_regs *); +long sys_rt_sigreturn(struct pt_regs *); /* kernel/ioport.c */ long sys_iopl(struct pt_regs *); diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index ccfb27412f0..7cdcd16885e 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c @@ -601,7 +601,7 @@ badframe: } #endif /* CONFIG_X86_32 */ -static long do_rt_sigreturn(struct pt_regs *regs) +long sys_rt_sigreturn(struct pt_regs *regs) { struct rt_sigframe __user *frame; unsigned long ax; @@ -632,18 +632,6 @@ badframe: return 0; } -#ifdef CONFIG_X86_32 -int sys_rt_sigreturn(struct pt_regs *regs) -{ - return do_rt_sigreturn(regs); -} -#else /* !CONFIG_X86_32 */ -asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) -{ - return do_rt_sigreturn(regs); -} -#endif /* CONFIG_X86_32 */ - /* * OK, we're invoking a handler: */ -- cgit From 58105ef1857112a186696c9b8957020090226a28 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 31 Jan 2009 12:32:26 -0800 Subject: x86: UV: fix header struct usage Impact: Fixes warning Fix uv.h struct usage: arch/x86/include/asm/uv/uv.h:16: warning: 'struct mm_struct' declared inside parameter list arch/x86/include/asm/uv/uv.h:16: warning: its scope is only this definition or declaration, which is probably not what you want Signed-off-by: Randy Dunlap Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/uv/uv.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/x86/include/asm/uv/uv.h b/arch/x86/include/asm/uv/uv.h index 8ac1d7e312f..8242bf96581 100644 --- a/arch/x86/include/asm/uv/uv.h +++ b/arch/x86/include/asm/uv/uv.h @@ -3,6 +3,9 @@ enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC}; +struct cpumask; +struct mm_struct; + #ifdef CONFIG_X86_UV extern enum uv_system_type get_uv_system_type(void); -- cgit From 4f06b0436b2ddbd3b67b10e77098a6862787b3eb Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 11 Feb 2009 09:32:19 -0800 Subject: x86/cpa: make sure cpa is safe to call in lazy mmu mode Impact: fix race leading to crash under KVM and Xen The CPA code may be called while we're in lazy mmu update mode - for example, when using DEBUG_PAGE_ALLOC and doing a slab allocation in an interrupt handler which interrupted a lazy mmu update. In this case, the in-memory pagetable state may be out of date due to pending queued updates. We need to flush any pending updates before inspecting the page table. Similarly, we must explicitly flush any modifications CPA may have made (which comes down to flushing queued operations when flushing the TLB). Signed-off-by: Jeremy Fitzhardinge Acked-by: Marcelo Tosatti Cc: Stable Kernel Signed-off-by: Ingo Molnar --- arch/x86/mm/pageattr.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 84ba74820ad..f664bc1c409 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -576,6 +576,13 @@ static int __change_page_attr(struct cpa_data *cpa, int primary) else address = *cpa->vaddr; + /* + * If we're called with lazy mmu updates enabled, the + * in-memory pte state may be stale. Flush pending updates to + * bring them up to date. + */ + arch_flush_lazy_mmu_mode(); + repeat: kpte = lookup_address(address, &level); if (!kpte) @@ -854,6 +861,13 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, } else cpa_flush_all(cache); + /* + * If we've been called with lazy mmu updates enabled, then + * make sure that everything gets flushed out before we + * return. + */ + arch_flush_lazy_mmu_mode(); + out: return ret; } -- cgit From be03d9e8022030c16abf534e33e185bfc3d40eef Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Wed, 11 Feb 2009 11:20:23 -0800 Subject: x86, pat: fix warn_on_once() while mapping 0-1MB range with /dev/mem Jeff Mahoney reported: > With Suse's hwinfo tool, on -tip: > WARNING: at arch/x86/mm/pat.c:637 reserve_pfn_range+0x5b/0x26d() reserve_pfn_range() is not tracking the memory range below 1MB as non-RAM and as such is inconsistent with similar checks in reserve_memtype() and free_memtype() Rename the pagerange_is_ram() to pat_pagerange_is_ram() and add the "track legacy 1MB region as non RAM" condition. And also, fix reserve_pfn_range() to return -EINVAL, when the pfn range is RAM. This is to be consistent with this API design. Reported-and-tested-by: Jeff Mahoney Signed-off-by: Suresh Siddha Signed-off-by: Venkatesh Pallipadi Signed-off-by: Ingo Molnar --- arch/x86/include/asm/page.h | 1 - arch/x86/mm/ioremap.c | 19 ----------- arch/x86/mm/pat.c | 83 ++++++++++++++++++++++++--------------------- 3 files changed, 45 insertions(+), 58 deletions(-) diff --git a/arch/x86/include/asm/page.h b/arch/x86/include/asm/page.h index e9873a2e869..776579119a0 100644 --- a/arch/x86/include/asm/page.h +++ b/arch/x86/include/asm/page.h @@ -57,7 +57,6 @@ typedef struct { pgdval_t pgd; } pgd_t; typedef struct { pgprotval_t pgprot; } pgprot_t; extern int page_is_ram(unsigned long pagenr); -extern int pagerange_is_ram(unsigned long start, unsigned long end); extern int devmem_is_allowed(unsigned long pagenr); extern void map_devmem(unsigned long pfn, unsigned long size, pgprot_t vma_prot); diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index af750ab973b..f45d5e29a72 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -134,25 +134,6 @@ int page_is_ram(unsigned long pagenr) return 0; } -int pagerange_is_ram(unsigned long start, unsigned long end) -{ - int ram_page = 0, not_rampage = 0; - unsigned long page_nr; - - for (page_nr = (start >> PAGE_SHIFT); page_nr < (end >> PAGE_SHIFT); - ++page_nr) { - if (page_is_ram(page_nr)) - ram_page = 1; - else - not_rampage = 1; - - if (ram_page == not_rampage) - return -1; - } - - return ram_page; -} - /* * Fix up the linear direct mapping of the kernel to avoid cache attribute * conflicts. diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index 7b61036427d..aebbf67a79d 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c @@ -211,6 +211,33 @@ chk_conflict(struct memtype *new, struct memtype *entry, unsigned long *type) static struct memtype *cached_entry; static u64 cached_start; +static int pat_pagerange_is_ram(unsigned long start, unsigned long end) +{ + int ram_page = 0, not_rampage = 0; + unsigned long page_nr; + + for (page_nr = (start >> PAGE_SHIFT); page_nr < (end >> PAGE_SHIFT); + ++page_nr) { + /* + * For legacy reasons, physical address range in the legacy ISA + * region is tracked as non-RAM. This will allow users of + * /dev/mem to map portions of legacy ISA region, even when + * some of those portions are listed(or not even listed) with + * different e820 types(RAM/reserved/..) + */ + if (page_nr >= (ISA_END_ADDRESS >> PAGE_SHIFT) && + page_is_ram(page_nr)) + ram_page = 1; + else + not_rampage = 1; + + if (ram_page == not_rampage) + return -1; + } + + return ram_page; +} + /* * For RAM pages, mark the pages as non WB memory type using * PageNonWB (PG_arch_1). We allow only one set_memory_uc() or @@ -336,20 +363,12 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type, if (new_type) *new_type = actual_type; - /* - * For legacy reasons, some parts of the physical address range in the - * legacy 1MB region is treated as non-RAM (even when listed as RAM in - * the e820 tables). So we will track the memory attributes of this - * legacy 1MB region using the linear memtype_list always. - */ - if (end >= ISA_END_ADDRESS) { - is_range_ram = pagerange_is_ram(start, end); - if (is_range_ram == 1) - return reserve_ram_pages_type(start, end, req_type, - new_type); - else if (is_range_ram < 0) - return -EINVAL; - } + is_range_ram = pat_pagerange_is_ram(start, end); + if (is_range_ram == 1) + return reserve_ram_pages_type(start, end, req_type, + new_type); + else if (is_range_ram < 0) + return -EINVAL; new = kmalloc(sizeof(struct memtype), GFP_KERNEL); if (!new) @@ -446,19 +465,11 @@ int free_memtype(u64 start, u64 end) if (is_ISA_range(start, end - 1)) return 0; - /* - * For legacy reasons, some parts of the physical address range in the - * legacy 1MB region is treated as non-RAM (even when listed as RAM in - * the e820 tables). So we will track the memory attributes of this - * legacy 1MB region using the linear memtype_list always. - */ - if (end >= ISA_END_ADDRESS) { - is_range_ram = pagerange_is_ram(start, end); - if (is_range_ram == 1) - return free_ram_pages_type(start, end); - else if (is_range_ram < 0) - return -EINVAL; - } + is_range_ram = pat_pagerange_is_ram(start, end); + if (is_range_ram == 1) + return free_ram_pages_type(start, end); + else if (is_range_ram < 0) + return -EINVAL; spin_lock(&memtype_lock); list_for_each_entry(entry, &memtype_list, nd) { @@ -626,17 +637,13 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot, unsigned long flags; unsigned long want_flags = (pgprot_val(*vma_prot) & _PAGE_CACHE_MASK); - is_ram = pagerange_is_ram(paddr, paddr + size); + is_ram = pat_pagerange_is_ram(paddr, paddr + size); - if (is_ram != 0) { - /* - * For mapping RAM pages, drivers need to call - * set_memory_[uc|wc|wb] directly, for reserve and free, before - * setting up the PTE. - */ - WARN_ON_ONCE(1); - return 0; - } + /* + * reserve_pfn_range() doesn't support RAM pages. + */ + if (is_ram != 0) + return -EINVAL; ret = reserve_memtype(paddr, paddr + size, want_flags, &flags); if (ret) @@ -693,7 +700,7 @@ static void free_pfn_range(u64 paddr, unsigned long size) { int is_ram; - is_ram = pagerange_is_ram(paddr, paddr + size); + is_ram = pat_pagerange_is_ram(paddr, paddr + size); if (is_ram == 0) free_memtype(paddr, paddr + size); } -- cgit From 270c5609e2540290d5d9b9f323b7b652cf0c5b75 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Mon, 9 Feb 2009 20:59:40 +0000 Subject: sh: Storage class should be before const qualifier The C99 specification states in section 6.11.5: The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature. Signed-off-by: Tobias Klauser Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh2a/clock-sh7201.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c index 020a96fe961..4a5e5973233 100644 --- a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c +++ b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c @@ -18,8 +18,8 @@ #include #include -const static int pll1rate[]={1,2,3,4,6,8}; -const static int pfc_divisors[]={1,2,3,4,6,8,12}; +static const int pll1rate[]={1,2,3,4,6,8}; +static const int pfc_divisors[]={1,2,3,4,6,8,12}; #define ifc_divisors pfc_divisors #if (CONFIG_SH_CLK_MD == 0) -- cgit From 34aeb43e2d3800f4d8f96feb9f1b49cd506679d5 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 10 Feb 2009 09:04:00 +0000 Subject: serial: sh-sci: fix overrun error handling for SH7785 SCIF. There was a typo for the overrun bit definition, causing it not to be handled correctly on SH7785, fix it up. Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt --- drivers/serial/sh-sci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index 3599828b976..022e89ffec1 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h @@ -133,7 +133,7 @@ # define SCSPTR3 0xffed0024 /* 16 bit SCIF */ # define SCSPTR4 0xffee0024 /* 16 bit SCIF */ # define SCSPTR5 0xffef0024 /* 16 bit SCIF */ -# define SCIF_OPER 0x0001 /* Overrun error bit */ +# define SCIF_ORER 0x0001 /* Overrun error bit */ # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ #elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \ defined(CONFIG_CPU_SUBTYPE_SH7203) || \ -- cgit From a0490fa35dc0022ef95f64802e8edf18c411c790 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 12 Feb 2009 11:35:40 +0100 Subject: sched: cpu hotplug fix rq_attach_root() does a kfree() with the runqueue lock held. That's not a very wise move, fix it. Signed-off-by: Ingo Molnar --- kernel/sched.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index c1d0ed36008..410eec40413 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -6944,20 +6944,26 @@ static void free_rootdomain(struct root_domain *rd) static void rq_attach_root(struct rq *rq, struct root_domain *rd) { + struct root_domain *old_rd = NULL; unsigned long flags; spin_lock_irqsave(&rq->lock, flags); if (rq->rd) { - struct root_domain *old_rd = rq->rd; + old_rd = rq->rd; if (cpumask_test_cpu(rq->cpu, old_rd->online)) set_rq_offline(rq); cpumask_clear_cpu(rq->cpu, old_rd->span); - if (atomic_dec_and_test(&old_rd->refcount)) - free_rootdomain(old_rd); + /* + * If we dont want to free the old_rt yet then + * set old_rd to NULL to skip the freeing later + * in this function: + */ + if (!atomic_dec_and_test(&old_rd->refcount)) + old_rd = NULL; } atomic_inc(&rd->refcount); @@ -6968,6 +6974,9 @@ static void rq_attach_root(struct rq *rq, struct root_domain *rd) set_rq_online(rq); spin_unlock_irqrestore(&rq->lock, flags); + + if (old_rd) + free_rootdomain(old_rd); } static int __init_refok init_rootdomain(struct root_domain *rd, bool bootmem) -- cgit From bc8bd002b8371ece81c9adbdce49d7e68f0a0cbc Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 12 Feb 2009 12:43:52 +0100 Subject: x86, defconfig: update the 32-bit defconfig Signed-off-by: Ingo Molnar --- arch/x86/configs/i386_defconfig | 406 ++++++++++++++++++++++++++++++++-------- 1 file changed, 324 insertions(+), 82 deletions(-) diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig index edba00d98ac..c3186ccc936 100644 --- a/arch/x86/configs/i386_defconfig +++ b/arch/x86/configs/i386_defconfig @@ -1,14 +1,13 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.27-rc5 -# Wed Sep 3 17:23:09 2008 +# Linux kernel version: 2.6.29-rc4 +# Thu Feb 12 12:42:50 2009 # # CONFIG_64BIT is not set CONFIG_X86_32=y # CONFIG_X86_64 is not set CONFIG_X86=y CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig" -# CONFIG_GENERIC_LOCKBREAK is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CMOS_UPDATE=y CONFIG_CLOCKSOURCE_WATCHDOG=y @@ -24,16 +23,14 @@ CONFIG_GENERIC_ISA_DMA=y CONFIG_GENERIC_IOMAP=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_HWEIGHT=y -# CONFIG_GENERIC_GPIO is not set CONFIG_ARCH_MAY_HAVE_PC_FDC=y # CONFIG_RWSEM_GENERIC_SPINLOCK is not set CONFIG_RWSEM_XCHGADD_ALGORITHM=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_GENERIC_CALIBRATE_DELAY=y # CONFIG_GENERIC_TIME_VSYSCALL is not set CONFIG_ARCH_HAS_CPU_RELAX=y +CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y CONFIG_HAVE_SETUP_PER_CPU_AREA=y # CONFIG_HAVE_CPUMASK_OF_CPU_MAP is not set @@ -42,12 +39,12 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y # CONFIG_ZONE_DMA32 is not set CONFIG_ARCH_POPULATES_NODE_MAP=y # CONFIG_AUDIT_ARCH is not set -CONFIG_ARCH_SUPPORTS_AOUT=y CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_PENDING_IRQ=y CONFIG_X86_SMP=y +CONFIG_USE_GENERIC_SMP_HELPERS=y CONFIG_X86_32_SMP=y CONFIG_X86_HT=y CONFIG_X86_BIOS_REBOOT=y @@ -76,30 +73,44 @@ CONFIG_TASK_IO_ACCOUNTING=y CONFIG_AUDIT=y CONFIG_AUDITSYSCALL=y CONFIG_AUDIT_TREE=y + +# +# RCU Subsystem +# +# CONFIG_CLASSIC_RCU is not set +CONFIG_TREE_RCU=y +# CONFIG_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=18 -CONFIG_CGROUPS=y -# CONFIG_CGROUP_DEBUG is not set -CONFIG_CGROUP_NS=y -# CONFIG_CGROUP_DEVICE is not set -CONFIG_CPUSETS=y CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y CONFIG_GROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y # CONFIG_RT_GROUP_SCHED is not set # CONFIG_USER_SCHED is not set CONFIG_CGROUP_SCHED=y +CONFIG_CGROUPS=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_NS=y +CONFIG_CGROUP_FREEZER=y +# CONFIG_CGROUP_DEVICE is not set +CONFIG_CPUSETS=y +CONFIG_PROC_PID_CPUSET=y CONFIG_CGROUP_CPUACCT=y CONFIG_RESOURCE_COUNTERS=y # CONFIG_CGROUP_MEM_RES_CTLR is not set # CONFIG_SYSFS_DEPRECATED_V2 is not set -CONFIG_PROC_PID_CPUSET=y CONFIG_RELAY=y CONFIG_NAMESPACES=y CONFIG_UTS_NS=y CONFIG_IPC_NS=y CONFIG_USER_NS=y CONFIG_PID_NS=y +CONFIG_NET_NS=y CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y @@ -124,12 +135,15 @@ CONFIG_SIGNALFD=y CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y +CONFIG_AIO=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_PCI_QUIRKS=y CONFIG_SLUB_DEBUG=y # CONFIG_SLAB is not set CONFIG_SLUB=y # CONFIG_SLOB is not set CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y CONFIG_MARKERS=y # CONFIG_OPROFILE is not set CONFIG_HAVE_OPROFILE=y @@ -139,15 +153,10 @@ CONFIG_KRETPROBES=y CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y -# CONFIG_HAVE_ARCH_TRACEHOOK is not set -# CONFIG_HAVE_DMA_ATTRS is not set -CONFIG_USE_GENERIC_SMP_HELPERS=y -# CONFIG_HAVE_CLK is not set -CONFIG_PROC_PAGE_MONITOR=y +CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -155,12 +164,10 @@ CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_STOP_MACHINE=y CONFIG_BLOCK=y # CONFIG_LBD is not set CONFIG_BLK_DEV_IO_TRACE=y -# CONFIG_LSF is not set CONFIG_BLK_DEV_BSG=y # CONFIG_BLK_DEV_INTEGRITY is not set @@ -176,7 +183,7 @@ CONFIG_IOSCHED_CFQ=y CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" -CONFIG_CLASSIC_RCU=y +CONFIG_FREEZER=y # # Processor type and features @@ -186,6 +193,7 @@ CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_GENERIC_CLOCKEVENTS_BUILD=y CONFIG_SMP=y +CONFIG_SPARSE_IRQ=y CONFIG_X86_FIND_SMP_CONFIG=y CONFIG_X86_MPPARSE=y CONFIG_X86_PC=y @@ -194,7 +202,7 @@ CONFIG_X86_PC=y # CONFIG_X86_GENERICARCH is not set # CONFIG_X86_VSMP is not set # CONFIG_X86_RDC321X is not set -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y # CONFIG_PARAVIRT_GUEST is not set # CONFIG_MEMTEST is not set # CONFIG_M386 is not set @@ -238,10 +246,19 @@ CONFIG_X86_TSC=y CONFIG_X86_CMOV=y CONFIG_X86_MINIMUM_CPU_FAMILY=4 CONFIG_X86_DEBUGCTLMSR=y +CONFIG_CPU_SUP_INTEL=y +CONFIG_CPU_SUP_CYRIX_32=y +CONFIG_CPU_SUP_AMD=y +CONFIG_CPU_SUP_CENTAUR_32=y +CONFIG_CPU_SUP_TRANSMETA_32=y +CONFIG_CPU_SUP_UMC_32=y +CONFIG_X86_DS=y +CONFIG_X86_PTRACE_BTS=y CONFIG_HPET_TIMER=y CONFIG_HPET_EMULATE_RTC=y CONFIG_DMI=y # CONFIG_IOMMU_HELPER is not set +# CONFIG_IOMMU_API is not set CONFIG_NR_CPUS=64 CONFIG_SCHED_SMT=y CONFIG_SCHED_MC=y @@ -250,12 +267,15 @@ CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y +CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y # CONFIG_X86_MCE is not set CONFIG_VM86=y # CONFIG_TOSHIBA is not set # CONFIG_I8K is not set CONFIG_X86_REBOOTFIXUPS=y CONFIG_MICROCODE=y +CONFIG_MICROCODE_INTEL=y +CONFIG_MICROCODE_AMD=y CONFIG_MICROCODE_OLD_INTERFACE=y CONFIG_X86_MSR=y CONFIG_X86_CPUID=y @@ -264,6 +284,7 @@ CONFIG_HIGHMEM4G=y # CONFIG_HIGHMEM64G is not set CONFIG_PAGE_OFFSET=0xC0000000 CONFIG_HIGHMEM=y +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y @@ -274,14 +295,17 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_SPARSEMEM_STATIC=y -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_RESOURCES_64BIT=y +# CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_BOUNCE=y CONFIG_VIRT_TO_BUS=y +CONFIG_UNEVICTABLE_LRU=y CONFIG_HIGHPTE=y +CONFIG_X86_CHECK_BIOS_CORRUPTION=y +CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y +CONFIG_X86_RESERVE_LOW_64K=y # CONFIG_MATH_EMULATION is not set CONFIG_MTRR=y # CONFIG_MTRR_SANITIZER is not set @@ -302,10 +326,11 @@ CONFIG_PHYSICAL_START=0x1000000 CONFIG_PHYSICAL_ALIGN=0x200000 CONFIG_HOTPLUG_CPU=y # CONFIG_COMPAT_VDSO is not set +# CONFIG_CMDLINE_BOOL is not set CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y # -# Power management options +# Power management and ACPI options # CONFIG_PM=y CONFIG_PM_DEBUG=y @@ -331,19 +356,13 @@ CONFIG_ACPI_BATTERY=y CONFIG_ACPI_BUTTON=y CONFIG_ACPI_FAN=y CONFIG_ACPI_DOCK=y -# CONFIG_ACPI_BAY is not set CONFIG_ACPI_PROCESSOR=y CONFIG_ACPI_HOTPLUG_CPU=y CONFIG_ACPI_THERMAL=y -# CONFIG_ACPI_WMI is not set -# CONFIG_ACPI_ASUS is not set -# CONFIG_ACPI_TOSHIBA is not set # CONFIG_ACPI_CUSTOM_DSDT is not set CONFIG_ACPI_BLACKLIST_YEAR=0 # CONFIG_ACPI_DEBUG is not set -CONFIG_ACPI_EC=y # CONFIG_ACPI_PCI_SLOT is not set -CONFIG_ACPI_POWER=y CONFIG_ACPI_SYSTEM=y CONFIG_X86_PM_TIMER=y CONFIG_ACPI_CONTAINER=y @@ -388,7 +407,6 @@ CONFIG_X86_ACPI_CPUFREQ=y # # shared options # -# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set # CONFIG_X86_SPEEDSTEP_LIB is not set CONFIG_CPU_IDLE=y CONFIG_CPU_IDLE_GOV_LADDER=y @@ -415,6 +433,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y CONFIG_PCI_MSI=y # CONFIG_PCI_LEGACY is not set # CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_STUB is not set CONFIG_HT_IRQ=y CONFIG_ISA_DMA_API=y # CONFIG_ISA is not set @@ -452,13 +471,17 @@ CONFIG_HOTPLUG_PCI=y # Executable file formats / Emulations # CONFIG_BINFMT_ELF=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +CONFIG_HAVE_AOUT=y # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_MISC=y +CONFIG_HAVE_ATOMIC_IOMAP=y CONFIG_NET=y # # Networking options # +CONFIG_COMPAT_NET_DEV_OPS=y CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_UNIX=y @@ -519,7 +542,6 @@ CONFIG_DEFAULT_CUBIC=y # CONFIG_DEFAULT_RENO is not set CONFIG_DEFAULT_TCP_CONG="cubic" CONFIG_TCP_MD5SIG=y -# CONFIG_IP_VS is not set CONFIG_IPV6=y # CONFIG_IPV6_PRIVACY is not set # CONFIG_IPV6_ROUTER_PREF is not set @@ -557,19 +579,21 @@ CONFIG_NF_CONNTRACK_IRC=y CONFIG_NF_CONNTRACK_SIP=y CONFIG_NF_CT_NETLINK=y CONFIG_NETFILTER_XTABLES=y +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y CONFIG_NETFILTER_XT_TARGET_MARK=y CONFIG_NETFILTER_XT_TARGET_NFLOG=y CONFIG_NETFILTER_XT_TARGET_SECMARK=y -CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y CONFIG_NETFILTER_XT_TARGET_TCPMSS=y CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y CONFIG_NETFILTER_XT_MATCH_MARK=y CONFIG_NETFILTER_XT_MATCH_POLICY=y CONFIG_NETFILTER_XT_MATCH_STATE=y +# CONFIG_IP_VS is not set # # IP: Netfilter Configuration # +CONFIG_NF_DEFRAG_IPV4=y CONFIG_NF_CONNTRACK_IPV4=y CONFIG_NF_CONNTRACK_PROC_COMPAT=y CONFIG_IP_NF_IPTABLES=y @@ -595,8 +619,8 @@ CONFIG_IP_NF_MANGLE=y CONFIG_NF_CONNTRACK_IPV6=y CONFIG_IP6_NF_IPTABLES=y CONFIG_IP6_NF_MATCH_IPV6HEADER=y -CONFIG_IP6_NF_FILTER=y CONFIG_IP6_NF_TARGET_LOG=y +CONFIG_IP6_NF_FILTER=y CONFIG_IP6_NF_TARGET_REJECT=y CONFIG_IP6_NF_MANGLE=y # CONFIG_IP_DCCP is not set @@ -604,6 +628,7 @@ CONFIG_IP6_NF_MANGLE=y # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set CONFIG_LLC=y @@ -623,6 +648,7 @@ CONFIG_NET_SCHED=y # CONFIG_NET_SCH_HTB is not set # CONFIG_NET_SCH_HFSC is not set # CONFIG_NET_SCH_PRIO is not set +# CONFIG_NET_SCH_MULTIQ is not set # CONFIG_NET_SCH_RED is not set # CONFIG_NET_SCH_SFQ is not set # CONFIG_NET_SCH_TEQL is not set @@ -630,6 +656,7 @@ CONFIG_NET_SCHED=y # CONFIG_NET_SCH_GRED is not set # CONFIG_NET_SCH_DSMARK is not set # CONFIG_NET_SCH_NETEM is not set +# CONFIG_NET_SCH_DRR is not set # CONFIG_NET_SCH_INGRESS is not set # @@ -644,6 +671,7 @@ CONFIG_NET_CLS=y # CONFIG_NET_CLS_RSVP is not set # CONFIG_NET_CLS_RSVP6 is not set # CONFIG_NET_CLS_FLOW is not set +# CONFIG_NET_CLS_CGROUP is not set CONFIG_NET_EMATCH=y CONFIG_NET_EMATCH_STACK=32 # CONFIG_NET_EMATCH_CMP is not set @@ -659,7 +687,9 @@ CONFIG_NET_CLS_ACT=y # CONFIG_NET_ACT_NAT is not set # CONFIG_NET_ACT_PEDIT is not set # CONFIG_NET_ACT_SIMP is not set +# CONFIG_NET_ACT_SKBEDIT is not set CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set # # Network testing @@ -676,29 +706,33 @@ CONFIG_HAMRADIO=y # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set +# CONFIG_PHONET is not set CONFIG_FIB_RULES=y - -# -# Wireless -# +CONFIG_WIRELESS=y CONFIG_CFG80211=y +# CONFIG_CFG80211_REG_DEBUG is not set CONFIG_NL80211=y +CONFIG_WIRELESS_OLD_REGULATORY=y CONFIG_WIRELESS_EXT=y CONFIG_WIRELESS_EXT_SYSFS=y +# CONFIG_LIB80211 is not set CONFIG_MAC80211=y # # Rate control algorithm selection # -CONFIG_MAC80211_RC_PID=y -CONFIG_MAC80211_RC_DEFAULT_PID=y -CONFIG_MAC80211_RC_DEFAULT="pid" +CONFIG_MAC80211_RC_MINSTREL=y +# CONFIG_MAC80211_RC_DEFAULT_PID is not set +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel" # CONFIG_MAC80211_MESH is not set CONFIG_MAC80211_LEDS=y # CONFIG_MAC80211_DEBUGFS is not set # CONFIG_MAC80211_DEBUG_MENU is not set -# CONFIG_IEEE80211 is not set -# CONFIG_RFKILL is not set +# CONFIG_WIMAX is not set +CONFIG_RFKILL=y +# CONFIG_RFKILL_INPUT is not set +CONFIG_RFKILL_LEDS=y # CONFIG_NET_9P is not set # @@ -722,7 +756,7 @@ CONFIG_PROC_EVENTS=y # CONFIG_MTD is not set # CONFIG_PARPORT is not set CONFIG_PNP=y -# CONFIG_PNP_DEBUG is not set +CONFIG_PNP_DEBUG_MESSAGES=y # # Protocols @@ -750,20 +784,19 @@ CONFIG_BLK_DEV_RAM_SIZE=16384 CONFIG_MISC_DEVICES=y # CONFIG_IBM_ASM is not set # CONFIG_PHANTOM is not set -# CONFIG_EEPROM_93CX6 is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set -# CONFIG_ACER_WMI is not set -# CONFIG_ASUS_LAPTOP is not set -# CONFIG_FUJITSU_LAPTOP is not set -# CONFIG_TC1100_WMI is not set -# CONFIG_MSI_LAPTOP is not set -# CONFIG_COMPAL_LAPTOP is not set -# CONFIG_SONY_LAPTOP is not set -# CONFIG_THINKPAD_ACPI is not set -# CONFIG_INTEL_MENLOW is not set +# CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_HP_ILO is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_93CX6 is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -875,6 +908,7 @@ CONFIG_PATA_OLDPIIX=y CONFIG_PATA_SCH=y CONFIG_MD=y CONFIG_BLK_DEV_MD=y +CONFIG_MD_AUTODETECT=y # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set @@ -930,6 +964,9 @@ CONFIG_PHYLIB=y # CONFIG_BROADCOM_PHY is not set # CONFIG_ICPLUS_PHY is not set # CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set # CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y @@ -953,6 +990,9 @@ CONFIG_NET_TULIP=y # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set # CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set @@ -960,7 +1000,6 @@ CONFIG_NET_PCI=y # CONFIG_B44 is not set CONFIG_FORCEDETH=y # CONFIG_FORCEDETH_NAPI is not set -# CONFIG_EEPRO100 is not set CONFIG_E100=y # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set @@ -974,15 +1013,16 @@ CONFIG_8139TOO=y # CONFIG_R6040 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set +# CONFIG_SMSC9420 is not set # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set # CONFIG_SC92031 is not set +# CONFIG_ATL2 is not set CONFIG_NETDEV_1000=y # CONFIG_ACENIC is not set # CONFIG_DL2K is not set CONFIG_E1000=y -# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set CONFIG_E1000E=y # CONFIG_IP1000 is not set # CONFIG_IGB is not set @@ -1000,18 +1040,23 @@ CONFIG_BNX2=y # CONFIG_QLA3XXX is not set # CONFIG_ATL1 is not set # CONFIG_ATL1E is not set +# CONFIG_JME is not set CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set +CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_CHELSIO_T3 is not set +# CONFIG_ENIC is not set # CONFIG_IXGBE is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set # CONFIG_NIU is not set +# CONFIG_MLX4_EN is not set # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set # CONFIG_BNX2X is not set +# CONFIG_QLGE is not set # CONFIG_SFC is not set CONFIG_TR=y # CONFIG_IBMOL is not set @@ -1025,9 +1070,8 @@ CONFIG_TR=y # CONFIG_WLAN_PRE80211 is not set CONFIG_WLAN_80211=y # CONFIG_PCMCIA_RAYCS is not set -# CONFIG_IPW2100 is not set -# CONFIG_IPW2200 is not set # CONFIG_LIBERTAS is not set +# CONFIG_LIBERTAS_THINFIRM is not set # CONFIG_AIRO is not set # CONFIG_HERMES is not set # CONFIG_ATMEL is not set @@ -1044,6 +1088,8 @@ CONFIG_WLAN_80211=y CONFIG_ATH5K=y # CONFIG_ATH5K_DEBUG is not set # CONFIG_ATH9K is not set +# CONFIG_IPW2100 is not set +# CONFIG_IPW2200 is not set # CONFIG_IWLCORE is not set # CONFIG_IWLWIFI_LEDS is not set # CONFIG_IWLAGN is not set @@ -1054,6 +1100,10 @@ CONFIG_ATH5K=y # CONFIG_ZD1211RW is not set # CONFIG_RT2X00 is not set +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + # # USB Network Adapters # @@ -1062,6 +1112,7 @@ CONFIG_ATH5K=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +# CONFIG_USB_HSO is not set CONFIG_NET_PCMCIA=y # CONFIG_PCMCIA_3C589 is not set # CONFIG_PCMCIA_3C574 is not set @@ -1123,6 +1174,7 @@ CONFIG_MOUSE_PS2_LOGIPS2PP=y CONFIG_MOUSE_PS2_SYNAPTICS=y CONFIG_MOUSE_PS2_LIFEBOOK=y CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_ELANTECH is not set # CONFIG_MOUSE_PS2_TOUCHKIT is not set # CONFIG_MOUSE_SERIAL is not set # CONFIG_MOUSE_APPLETOUCH is not set @@ -1160,15 +1212,16 @@ CONFIG_INPUT_TOUCHSCREEN=y # CONFIG_TOUCHSCREEN_FUJITSU is not set # CONFIG_TOUCHSCREEN_GUNZE is not set # CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set # CONFIG_TOUCHSCREEN_MTOUCH is not set # CONFIG_TOUCHSCREEN_INEXIO is not set # CONFIG_TOUCHSCREEN_MK712 is not set # CONFIG_TOUCHSCREEN_PENMOUNT is not set # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set # CONFIG_TOUCHSCREEN_TOUCHWIN is not set -# CONFIG_TOUCHSCREEN_UCB1400 is not set # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set CONFIG_INPUT_MISC=y # CONFIG_INPUT_PCSPKR is not set # CONFIG_INPUT_APANEL is not set @@ -1179,6 +1232,7 @@ CONFIG_INPUT_MISC=y # CONFIG_INPUT_KEYSPAN_REMOTE is not set # CONFIG_INPUT_POWERMATE is not set # CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set # CONFIG_INPUT_UINPUT is not set # @@ -1245,6 +1299,7 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set # CONFIG_IPMI_HANDLER is not set CONFIG_HW_RANDOM=y @@ -1279,6 +1334,7 @@ CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y # CONFIG_I2C_CHARDEV is not set CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=y # # I2C Hardware Bus support @@ -1331,8 +1387,6 @@ CONFIG_I2C_I801=y # Miscellaneous I2C Chip support # # CONFIG_DS1682 is not set -# CONFIG_EEPROM_AT24 is not set -# CONFIG_EEPROM_LEGACY is not set # CONFIG_SENSORS_PCF8574 is not set # CONFIG_PCF8575 is not set # CONFIG_SENSORS_PCA9539 is not set @@ -1351,8 +1405,78 @@ CONFIG_POWER_SUPPLY=y # CONFIG_POWER_SUPPLY_DEBUG is not set # CONFIG_PDA_POWER is not set # CONFIG_BATTERY_DS2760 is not set -# CONFIG_HWMON is not set +# CONFIG_BATTERY_BQ27x00 is not set +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ABITUGURU3 is not set +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7473 is not set +# CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_K8TEMP is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_I5K_AMB is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_FSCHMD is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_CORETEMP is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_SENSORS_HDAPS is not set +# CONFIG_SENSORS_LIS3LV02D is not set +# CONFIG_SENSORS_APPLESMC is not set +# CONFIG_HWMON_DEBUG_CHIP is not set CONFIG_THERMAL=y +# CONFIG_THERMAL_HWMON is not set CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -1372,6 +1496,7 @@ CONFIG_WATCHDOG=y # CONFIG_I6300ESB_WDT is not set # CONFIG_ITCO_WDT is not set # CONFIG_IT8712F_WDT is not set +# CONFIG_IT87_WDT is not set # CONFIG_HP_WATCHDOG is not set # CONFIG_SC1200_WDT is not set # CONFIG_PC87413_WDT is not set @@ -1379,9 +1504,11 @@ CONFIG_WATCHDOG=y # CONFIG_SBC8360_WDT is not set # CONFIG_SBC7240_WDT is not set # CONFIG_CPU5_WDT is not set +# CONFIG_SMSC_SCH311X_WDT is not set # CONFIG_SMSC37B787_WDT is not set # CONFIG_W83627HF_WDT is not set # CONFIG_W83697HF_WDT is not set +# CONFIG_W83697UG_WDT is not set # CONFIG_W83877F_WDT is not set # CONFIG_W83977F_WDT is not set # CONFIG_MACHZ_WDT is not set @@ -1397,11 +1524,11 @@ CONFIG_WATCHDOG=y # USB-based Watchdog Cards # # CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y # # Sonics Silicon Backplane # -CONFIG_SSB_POSSIBLE=y # CONFIG_SSB is not set # @@ -1410,7 +1537,13 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_REGULATOR is not set # # Multimedia devices @@ -1450,6 +1583,7 @@ CONFIG_DRM=y # CONFIG_DRM_I810 is not set # CONFIG_DRM_I830 is not set CONFIG_DRM_I915=y +# CONFIG_DRM_I915_KMS is not set # CONFIG_DRM_MGA is not set # CONFIG_DRM_SIS is not set # CONFIG_DRM_VIA is not set @@ -1459,6 +1593,7 @@ CONFIG_DRM_I915=y CONFIG_FB=y # CONFIG_FIRMWARE_EDID is not set # CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y @@ -1487,7 +1622,6 @@ CONFIG_FB_TILEBLITTING=y # CONFIG_FB_UVESA is not set # CONFIG_FB_VESA is not set CONFIG_FB_EFI=y -# CONFIG_FB_IMAC is not set # CONFIG_FB_N411 is not set # CONFIG_FB_HGA is not set # CONFIG_FB_S1D13XXX is not set @@ -1503,6 +1637,7 @@ CONFIG_FB_EFI=y # CONFIG_FB_S3 is not set # CONFIG_FB_SAVAGE is not set # CONFIG_FB_SIS is not set +# CONFIG_FB_VIA is not set # CONFIG_FB_NEOMAGIC is not set # CONFIG_FB_KYRO is not set # CONFIG_FB_3DFX is not set @@ -1515,12 +1650,15 @@ CONFIG_FB_EFI=y # CONFIG_FB_CARMINE is not set # CONFIG_FB_GEODE is not set # CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set CONFIG_BACKLIGHT_LCD_SUPPORT=y # CONFIG_LCD_CLASS_DEVICE is not set CONFIG_BACKLIGHT_CLASS_DEVICE=y -# CONFIG_BACKLIGHT_CORGI is not set +CONFIG_BACKLIGHT_GENERIC=y # CONFIG_BACKLIGHT_PROGEAR is not set # CONFIG_BACKLIGHT_MBP_NVIDIA is not set +# CONFIG_BACKLIGHT_SAHARA is not set # # Display device support @@ -1540,10 +1678,12 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_VGA16 is not set CONFIG_LOGO_LINUX_CLUT224=y CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y CONFIG_SND=y CONFIG_SND_TIMER=y CONFIG_SND_PCM=y CONFIG_SND_HWDEP=y +CONFIG_SND_JACK=y CONFIG_SND_SEQUENCER=y CONFIG_SND_SEQ_DUMMY=y CONFIG_SND_OSSEMUL=y @@ -1551,6 +1691,8 @@ CONFIG_SND_MIXER_OSS=y CONFIG_SND_PCM_OSS=y CONFIG_SND_PCM_OSS_PLUGINS=y CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_HRTIMER=y +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y CONFIG_SND_DYNAMIC_MINORS=y CONFIG_SND_SUPPORT_OLD_API=y CONFIG_SND_VERBOSE_PROCFS=y @@ -1605,11 +1747,16 @@ CONFIG_SND_PCI=y # CONFIG_SND_FM801 is not set CONFIG_SND_HDA_INTEL=y CONFIG_SND_HDA_HWDEP=y +# CONFIG_SND_HDA_RECONFIG is not set +# CONFIG_SND_HDA_INPUT_BEEP is not set CONFIG_SND_HDA_CODEC_REALTEK=y CONFIG_SND_HDA_CODEC_ANALOG=y CONFIG_SND_HDA_CODEC_SIGMATEL=y CONFIG_SND_HDA_CODEC_VIA=y CONFIG_SND_HDA_CODEC_ATIHDMI=y +CONFIG_SND_HDA_CODEC_NVHDMI=y +CONFIG_SND_HDA_CODEC_INTELHDMI=y +CONFIG_SND_HDA_ELD=y CONFIG_SND_HDA_CODEC_CONEXANT=y CONFIG_SND_HDA_CODEC_CMEDIA=y CONFIG_SND_HDA_CODEC_SI3054=y @@ -1643,6 +1790,7 @@ CONFIG_SND_USB=y # CONFIG_SND_USB_AUDIO is not set # CONFIG_SND_USB_USX2Y is not set # CONFIG_SND_USB_CAIAQ is not set +# CONFIG_SND_USB_US122L is not set CONFIG_SND_PCMCIA=y # CONFIG_SND_VXPOCKET is not set # CONFIG_SND_PDAUDIOCF is not set @@ -1657,15 +1805,37 @@ CONFIG_HIDRAW=y # USB Input Devices # CONFIG_USB_HID=y -CONFIG_USB_HIDINPUT_POWERBOOK=y -CONFIG_HID_FF=y CONFIG_HID_PID=y +CONFIG_USB_HIDDEV=y + +# +# Special HID drivers +# +CONFIG_HID_COMPAT=y +CONFIG_HID_A4TECH=y +CONFIG_HID_APPLE=y +CONFIG_HID_BELKIN=y +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +CONFIG_HID_CYPRESS=y +CONFIG_HID_EZKEY=y +CONFIG_HID_GYRATION=y +CONFIG_HID_LOGITECH=y CONFIG_LOGITECH_FF=y # CONFIG_LOGIRUMBLEPAD2_FF is not set +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MONTEREY=y +CONFIG_HID_NTRIG=y +CONFIG_HID_PANTHERLORD=y CONFIG_PANTHERLORD_FF=y +CONFIG_HID_PETALYNX=y +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SONY=y +CONFIG_HID_SUNPLUS=y +# CONFIG_GREENASIA_FF is not set +CONFIG_HID_TOPSEED=y CONFIG_THRUSTMASTER_FF=y CONFIG_ZEROPLUS_FF=y -CONFIG_USB_HIDDEV=y CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y @@ -1683,6 +1853,8 @@ CONFIG_USB_DEVICEFS=y CONFIG_USB_SUSPEND=y # CONFIG_USB_OTG is not set CONFIG_USB_MON=y +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set # # USB Host Controller Drivers @@ -1691,6 +1863,7 @@ CONFIG_USB_MON=y CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_ROOT_HUB_TT is not set # CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_OXU210HP_HCD is not set # CONFIG_USB_ISP116X_HCD is not set # CONFIG_USB_ISP1760_HCD is not set CONFIG_USB_OHCI_HCD=y @@ -1700,6 +1873,8 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y CONFIG_USB_UHCI_HCD=y # CONFIG_USB_SL811_HCD is not set # CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_WHCI_HCD is not set +# CONFIG_USB_HWA_HCD is not set # # USB Device Class drivers @@ -1707,20 +1882,20 @@ CONFIG_USB_UHCI_HCD=y # CONFIG_USB_ACM is not set CONFIG_USB_PRINTER=y # CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set # -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; # # -# may also be needed; see USB_STORAGE Help for more information +# see USB_STORAGE Help for more information # CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set # CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set # CONFIG_USB_STORAGE_USBAT is not set # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_SDDR55 is not set @@ -1728,7 +1903,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_ALAUDA is not set # CONFIG_USB_STORAGE_ONETOUCH is not set # CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_SIERRA is not set # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set CONFIG_USB_LIBUSUAL=y @@ -1749,6 +1923,7 @@ CONFIG_USB_LIBUSUAL=y # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set # CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set @@ -1766,7 +1941,13 @@ CONFIG_USB_LIBUSUAL=y # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +# CONFIG_UWB is not set # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set CONFIG_NEW_LEDS=y @@ -1775,6 +1956,7 @@ CONFIG_LEDS_CLASS=y # # LED drivers # +# CONFIG_LEDS_ALIX2 is not set # CONFIG_LEDS_PCA9532 is not set # CONFIG_LEDS_CLEVO_MAIL is not set # CONFIG_LEDS_PCA955X is not set @@ -1785,6 +1967,7 @@ CONFIG_LEDS_CLASS=y CONFIG_LEDS_TRIGGERS=y # CONFIG_LEDS_TRIGGER_TIMER is not set # CONFIG_LEDS_TRIGGER_HEARTBEAT is not set +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set # CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set # CONFIG_ACCESSIBILITY is not set # CONFIG_INFINIBAND is not set @@ -1824,6 +2007,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_M41T80 is not set # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set # # SPI RTC drivers @@ -1833,12 +2017,15 @@ CONFIG_RTC_INTF_DEV=y # Platform RTC drivers # CONFIG_RTC_DRV_CMOS=y +# CONFIG_RTC_DRV_DS1286 is not set # CONFIG_RTC_DRV_DS1511 is not set # CONFIG_RTC_DRV_DS1553 is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -1851,6 +2038,22 @@ CONFIG_DMADEVICES=y # # CONFIG_INTEL_IOATDMA is not set # CONFIG_UIO is not set +# CONFIG_STAGING is not set +CONFIG_X86_PLATFORM_DEVICES=y +# CONFIG_ACER_WMI is not set +# CONFIG_ASUS_LAPTOP is not set +# CONFIG_FUJITSU_LAPTOP is not set +# CONFIG_TC1100_WMI is not set +# CONFIG_MSI_LAPTOP is not set +# CONFIG_PANASONIC_LAPTOP is not set +# CONFIG_COMPAL_LAPTOP is not set +# CONFIG_SONY_LAPTOP is not set +# CONFIG_THINKPAD_ACPI is not set +# CONFIG_INTEL_MENLOW is not set +CONFIG_EEEPC_LAPTOP=y +# CONFIG_ACPI_WMI is not set +# CONFIG_ACPI_ASUS is not set +# CONFIG_ACPI_TOSHIBA is not set # # Firmware Drivers @@ -1872,21 +2075,24 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y CONFIG_EXT3_FS_SECURITY=y -# CONFIG_EXT4DEV_FS is not set +# CONFIG_EXT4_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y +CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_QUOTA_TREE=y # CONFIG_QFMT_V1 is not set CONFIG_QFMT_V2=y CONFIG_QUOTACTL=y @@ -1920,16 +2126,14 @@ CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_PROC_VMCORE=y CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y CONFIG_SYSFS=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_ECRYPT_FS is not set @@ -1939,6 +2143,7 @@ CONFIG_HUGETLB_PAGE=y # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -1960,6 +2165,7 @@ CONFIG_NFS_ACL_SUPPORT=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_REGISTER_V4 is not set CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -2066,33 +2272,54 @@ CONFIG_TIMER_STATS=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_VIRTUAL is not set # CONFIG_DEBUG_WRITECOUNT is not set CONFIG_DEBUG_MEMORY_INIT=y # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +CONFIG_ARCH_WANT_FRAME_POINTERS=y CONFIG_FRAME_POINTER=y # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_KPROBES_SANITY_TEST is not set # CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_LKDTM is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_HAVE_FTRACE=y +CONFIG_USER_STACKTRACE_SUPPORT=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y CONFIG_HAVE_DYNAMIC_FTRACE=y -# CONFIG_FTRACE is not set +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_HW_BRANCH_TRACER=y + +# +# Tracers +# +# CONFIG_FUNCTION_TRACER is not set # CONFIG_IRQSOFF_TRACER is not set # CONFIG_SYSPROF_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_POWER_TRACER is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_HW_BRANCH_TRACER is not set CONFIG_PROVIDE_OHCI1394_DMA_INIT=y +# CONFIG_DYNAMIC_PRINTK_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set # CONFIG_STRICT_DEVMEM is not set CONFIG_X86_VERBOSE_BOOTUP=y CONFIG_EARLY_PRINTK=y +CONFIG_EARLY_PRINTK_DBGP=y CONFIG_DEBUG_STACKOVERFLOW=y CONFIG_DEBUG_STACK_USAGE=y # CONFIG_DEBUG_PAGEALLOC is not set @@ -2123,8 +2350,10 @@ CONFIG_OPTIMIZE_INLINING=y CONFIG_KEYS=y CONFIG_KEYS_DEBUG_PROC_KEYS=y CONFIG_SECURITY=y +# CONFIG_SECURITYFS is not set CONFIG_SECURITY_NETWORK=y # CONFIG_SECURITY_NETWORK_XFRM is not set +# CONFIG_SECURITY_PATH is not set CONFIG_SECURITY_FILE_CAPABILITIES=y # CONFIG_SECURITY_ROOTPLUG is not set CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=65536 @@ -2135,7 +2364,6 @@ CONFIG_SECURITY_SELINUX_DISABLE=y CONFIG_SECURITY_SELINUX_DEVELOP=y CONFIG_SECURITY_SELINUX_AVC_STATS=y CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 -# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set # CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set # CONFIG_SECURITY_SMACK is not set CONFIG_CRYPTO=y @@ -2143,11 +2371,18 @@ CONFIG_CRYPTO=y # # Crypto core or helper # +# CONFIG_CRYPTO_FIPS is not set CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y # CONFIG_CRYPTO_GF128MUL is not set # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_CRYPTD is not set @@ -2182,6 +2417,7 @@ CONFIG_CRYPTO_HMAC=y # Digest # # CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CRC32C_INTEL is not set # CONFIG_CRYPTO_MD4 is not set CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_MICHAEL_MIC is not set @@ -2222,6 +2458,11 @@ CONFIG_CRYPTO_DES=y # # CONFIG_CRYPTO_DEFLATE is not set # CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_PADLOCK is not set # CONFIG_CRYPTO_DEV_GEODE is not set @@ -2239,6 +2480,7 @@ CONFIG_VIRTUALIZATION=y CONFIG_BITREVERSE=y CONFIG_GENERIC_FIND_FIRST_BIT=y CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_FIND_LAST_BIT=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set CONFIG_CRC_T10DIF=y -- cgit From dd5fc55449c5e7e4f008d7d26cda9e6e2bc94980 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 12 Feb 2009 12:48:48 +0100 Subject: x86, defconfig: update the 64-bit defconfig Signed-off-by: Ingo Molnar --- arch/x86/configs/x86_64_defconfig | 412 ++++++++++++++++++++++++++++++-------- 1 file changed, 332 insertions(+), 80 deletions(-) diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig index 322dd2748fc..4c85bfa58e1 100644 --- a/arch/x86/configs/x86_64_defconfig +++ b/arch/x86/configs/x86_64_defconfig @@ -1,14 +1,13 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.27-rc5 -# Wed Sep 3 17:13:39 2008 +# Linux kernel version: 2.6.29-rc4 +# Thu Feb 12 12:48:13 2009 # CONFIG_64BIT=y # CONFIG_X86_32 is not set CONFIG_X86_64=y CONFIG_X86=y CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig" -# CONFIG_GENERIC_LOCKBREAK is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CMOS_UPDATE=y CONFIG_CLOCKSOURCE_WATCHDOG=y @@ -23,17 +22,16 @@ CONFIG_ZONE_DMA=y CONFIG_GENERIC_ISA_DMA=y CONFIG_GENERIC_IOMAP=y CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y CONFIG_GENERIC_HWEIGHT=y -# CONFIG_GENERIC_GPIO is not set CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_ARCH_HAS_CPU_RELAX=y +CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y CONFIG_HAVE_SETUP_PER_CPU_AREA=y CONFIG_HAVE_CPUMASK_OF_CPU_MAP=y @@ -42,12 +40,12 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ZONE_DMA32=y CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_AUDIT_ARCH=y -CONFIG_ARCH_SUPPORTS_AOUT=y CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_PENDING_IRQ=y CONFIG_X86_SMP=y +CONFIG_USE_GENERIC_SMP_HELPERS=y CONFIG_X86_64_SMP=y CONFIG_X86_HT=y CONFIG_X86_BIOS_REBOOT=y @@ -76,30 +74,44 @@ CONFIG_TASK_IO_ACCOUNTING=y CONFIG_AUDIT=y CONFIG_AUDITSYSCALL=y CONFIG_AUDIT_TREE=y + +# +# RCU Subsystem +# +# CONFIG_CLASSIC_RCU is not set +CONFIG_TREE_RCU=y +# CONFIG_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=64 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=18 -CONFIG_CGROUPS=y -# CONFIG_CGROUP_DEBUG is not set -CONFIG_CGROUP_NS=y -# CONFIG_CGROUP_DEVICE is not set -CONFIG_CPUSETS=y CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y CONFIG_GROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y # CONFIG_RT_GROUP_SCHED is not set # CONFIG_USER_SCHED is not set CONFIG_CGROUP_SCHED=y +CONFIG_CGROUPS=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_NS=y +CONFIG_CGROUP_FREEZER=y +# CONFIG_CGROUP_DEVICE is not set +CONFIG_CPUSETS=y +CONFIG_PROC_PID_CPUSET=y CONFIG_CGROUP_CPUACCT=y CONFIG_RESOURCE_COUNTERS=y # CONFIG_CGROUP_MEM_RES_CTLR is not set # CONFIG_SYSFS_DEPRECATED_V2 is not set -CONFIG_PROC_PID_CPUSET=y CONFIG_RELAY=y CONFIG_NAMESPACES=y CONFIG_UTS_NS=y CONFIG_IPC_NS=y CONFIG_USER_NS=y CONFIG_PID_NS=y +CONFIG_NET_NS=y CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y @@ -124,12 +136,15 @@ CONFIG_SIGNALFD=y CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y +CONFIG_AIO=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_PCI_QUIRKS=y CONFIG_SLUB_DEBUG=y # CONFIG_SLAB is not set CONFIG_SLUB=y # CONFIG_SLOB is not set CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y CONFIG_MARKERS=y # CONFIG_OPROFILE is not set CONFIG_HAVE_OPROFILE=y @@ -139,15 +154,10 @@ CONFIG_KRETPROBES=y CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y -# CONFIG_HAVE_ARCH_TRACEHOOK is not set -# CONFIG_HAVE_DMA_ATTRS is not set -CONFIG_USE_GENERIC_SMP_HELPERS=y -# CONFIG_HAVE_CLK is not set -CONFIG_PROC_PAGE_MONITOR=y +CONFIG_HAVE_ARCH_TRACEHOOK=y # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -155,7 +165,6 @@ CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_STOP_MACHINE=y CONFIG_BLOCK=y CONFIG_BLK_DEV_IO_TRACE=y @@ -175,7 +184,7 @@ CONFIG_IOSCHED_CFQ=y CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" -CONFIG_CLASSIC_RCU=y +CONFIG_FREEZER=y # # Processor type and features @@ -185,6 +194,8 @@ CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_GENERIC_CLOCKEVENTS_BUILD=y CONFIG_SMP=y +CONFIG_SPARSE_IRQ=y +# CONFIG_NUMA_MIGRATE_IRQ_DESC is not set CONFIG_X86_FIND_SMP_CONFIG=y CONFIG_X86_MPPARSE=y CONFIG_X86_PC=y @@ -192,6 +203,7 @@ CONFIG_X86_PC=y # CONFIG_X86_VOYAGER is not set # CONFIG_X86_GENERICARCH is not set # CONFIG_X86_VSMP is not set +CONFIG_SCHED_OMIT_FRAME_POINTER=y # CONFIG_PARAVIRT_GUEST is not set # CONFIG_MEMTEST is not set # CONFIG_M386 is not set @@ -230,6 +242,11 @@ CONFIG_X86_CMPXCHG64=y CONFIG_X86_CMOV=y CONFIG_X86_MINIMUM_CPU_FAMILY=64 CONFIG_X86_DEBUGCTLMSR=y +CONFIG_CPU_SUP_INTEL=y +CONFIG_CPU_SUP_AMD=y +CONFIG_CPU_SUP_CENTAUR_64=y +CONFIG_X86_DS=y +CONFIG_X86_PTRACE_BTS=y CONFIG_HPET_TIMER=y CONFIG_HPET_EMULATE_RTC=y CONFIG_DMI=y @@ -237,8 +254,11 @@ CONFIG_GART_IOMMU=y CONFIG_CALGARY_IOMMU=y CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT=y CONFIG_AMD_IOMMU=y +CONFIG_AMD_IOMMU_STATS=y CONFIG_SWIOTLB=y CONFIG_IOMMU_HELPER=y +CONFIG_IOMMU_API=y +# CONFIG_MAXSMP is not set CONFIG_NR_CPUS=64 CONFIG_SCHED_SMT=y CONFIG_SCHED_MC=y @@ -247,12 +267,17 @@ CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y +CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y # CONFIG_X86_MCE is not set # CONFIG_I8K is not set CONFIG_MICROCODE=y +CONFIG_MICROCODE_INTEL=y +CONFIG_MICROCODE_AMD=y CONFIG_MICROCODE_OLD_INTERFACE=y CONFIG_X86_MSR=y CONFIG_X86_CPUID=y +CONFIG_ARCH_PHYS_ADDR_T_64BIT=y +CONFIG_DIRECT_GBPAGES=y CONFIG_NUMA=y CONFIG_K8_NUMA=y CONFIG_X86_64_ACPI_NUMA=y @@ -269,7 +294,6 @@ CONFIG_SPARSEMEM_MANUAL=y CONFIG_SPARSEMEM=y CONFIG_NEED_MULTIPLE_NODES=y CONFIG_HAVE_MEMORY_PRESENT=y -# CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPARSEMEM_EXTREME=y CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y CONFIG_SPARSEMEM_VMEMMAP=y @@ -280,10 +304,14 @@ CONFIG_SPARSEMEM_VMEMMAP=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y -CONFIG_RESOURCES_64BIT=y +CONFIG_PHYS_ADDR_T_64BIT=y CONFIG_ZONE_DMA_FLAG=1 CONFIG_BOUNCE=y CONFIG_VIRT_TO_BUS=y +CONFIG_UNEVICTABLE_LRU=y +CONFIG_X86_CHECK_BIOS_CORRUPTION=y +CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y +CONFIG_X86_RESERVE_LOW_64K=y CONFIG_MTRR=y # CONFIG_MTRR_SANITIZER is not set CONFIG_X86_PAT=y @@ -302,11 +330,12 @@ CONFIG_PHYSICAL_START=0x1000000 CONFIG_PHYSICAL_ALIGN=0x200000 CONFIG_HOTPLUG_CPU=y # CONFIG_COMPAT_VDSO is not set +# CONFIG_CMDLINE_BOOL is not set CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y # -# Power management options +# Power management and ACPI options # CONFIG_ARCH_HIBERNATION_HEADER=y CONFIG_PM=y @@ -333,20 +362,14 @@ CONFIG_ACPI_BATTERY=y CONFIG_ACPI_BUTTON=y CONFIG_ACPI_FAN=y CONFIG_ACPI_DOCK=y -# CONFIG_ACPI_BAY is not set CONFIG_ACPI_PROCESSOR=y CONFIG_ACPI_HOTPLUG_CPU=y CONFIG_ACPI_THERMAL=y CONFIG_ACPI_NUMA=y -# CONFIG_ACPI_WMI is not set -# CONFIG_ACPI_ASUS is not set -# CONFIG_ACPI_TOSHIBA is not set # CONFIG_ACPI_CUSTOM_DSDT is not set CONFIG_ACPI_BLACKLIST_YEAR=0 # CONFIG_ACPI_DEBUG is not set -CONFIG_ACPI_EC=y # CONFIG_ACPI_PCI_SLOT is not set -CONFIG_ACPI_POWER=y CONFIG_ACPI_SYSTEM=y CONFIG_X86_PM_TIMER=y CONFIG_ACPI_CONTAINER=y @@ -381,12 +404,16 @@ CONFIG_X86_ACPI_CPUFREQ=y # # shared options # -# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set # CONFIG_X86_SPEEDSTEP_LIB is not set CONFIG_CPU_IDLE=y CONFIG_CPU_IDLE_GOV_LADDER=y CONFIG_CPU_IDLE_GOV_MENU=y +# +# Memory power savings +# +# CONFIG_I7300_IDLE is not set + # # Bus options (PCI etc.) # @@ -395,8 +422,10 @@ CONFIG_PCI_DIRECT=y CONFIG_PCI_MMCONFIG=y CONFIG_PCI_DOMAINS=y CONFIG_DMAR=y +# CONFIG_DMAR_DEFAULT_ON is not set CONFIG_DMAR_GFX_WA=y CONFIG_DMAR_FLOPPY_WA=y +# CONFIG_INTR_REMAP is not set CONFIG_PCIEPORTBUS=y # CONFIG_HOTPLUG_PCI_PCIE is not set CONFIG_PCIEAER=y @@ -405,6 +434,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y CONFIG_PCI_MSI=y # CONFIG_PCI_LEGACY is not set # CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_STUB is not set CONFIG_HT_IRQ=y CONFIG_ISA_DMA_API=y CONFIG_K8_NB=y @@ -438,6 +468,8 @@ CONFIG_HOTPLUG_PCI=y # CONFIG_BINFMT_ELF=y CONFIG_COMPAT_BINFMT_ELF=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +# CONFIG_HAVE_AOUT is not set CONFIG_BINFMT_MISC=y CONFIG_IA32_EMULATION=y # CONFIG_IA32_AOUT is not set @@ -449,6 +481,7 @@ CONFIG_NET=y # # Networking options # +CONFIG_COMPAT_NET_DEV_OPS=y CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_UNIX=y @@ -509,7 +542,6 @@ CONFIG_DEFAULT_CUBIC=y # CONFIG_DEFAULT_RENO is not set CONFIG_DEFAULT_TCP_CONG="cubic" CONFIG_TCP_MD5SIG=y -# CONFIG_IP_VS is not set CONFIG_IPV6=y # CONFIG_IPV6_PRIVACY is not set # CONFIG_IPV6_ROUTER_PREF is not set @@ -547,19 +579,21 @@ CONFIG_NF_CONNTRACK_IRC=y CONFIG_NF_CONNTRACK_SIP=y CONFIG_NF_CT_NETLINK=y CONFIG_NETFILTER_XTABLES=y +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y CONFIG_NETFILTER_XT_TARGET_MARK=y CONFIG_NETFILTER_XT_TARGET_NFLOG=y CONFIG_NETFILTER_XT_TARGET_SECMARK=y -CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y CONFIG_NETFILTER_XT_TARGET_TCPMSS=y CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y CONFIG_NETFILTER_XT_MATCH_MARK=y CONFIG_NETFILTER_XT_MATCH_POLICY=y CONFIG_NETFILTER_XT_MATCH_STATE=y +# CONFIG_IP_VS is not set # # IP: Netfilter Configuration # +CONFIG_NF_DEFRAG_IPV4=y CONFIG_NF_CONNTRACK_IPV4=y CONFIG_NF_CONNTRACK_PROC_COMPAT=y CONFIG_IP_NF_IPTABLES=y @@ -585,8 +619,8 @@ CONFIG_IP_NF_MANGLE=y CONFIG_NF_CONNTRACK_IPV6=y CONFIG_IP6_NF_IPTABLES=y CONFIG_IP6_NF_MATCH_IPV6HEADER=y -CONFIG_IP6_NF_FILTER=y CONFIG_IP6_NF_TARGET_LOG=y +CONFIG_IP6_NF_FILTER=y CONFIG_IP6_NF_TARGET_REJECT=y CONFIG_IP6_NF_MANGLE=y # CONFIG_IP_DCCP is not set @@ -594,6 +628,7 @@ CONFIG_IP6_NF_MANGLE=y # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set CONFIG_LLC=y @@ -613,6 +648,7 @@ CONFIG_NET_SCHED=y # CONFIG_NET_SCH_HTB is not set # CONFIG_NET_SCH_HFSC is not set # CONFIG_NET_SCH_PRIO is not set +# CONFIG_NET_SCH_MULTIQ is not set # CONFIG_NET_SCH_RED is not set # CONFIG_NET_SCH_SFQ is not set # CONFIG_NET_SCH_TEQL is not set @@ -620,6 +656,7 @@ CONFIG_NET_SCHED=y # CONFIG_NET_SCH_GRED is not set # CONFIG_NET_SCH_DSMARK is not set # CONFIG_NET_SCH_NETEM is not set +# CONFIG_NET_SCH_DRR is not set # CONFIG_NET_SCH_INGRESS is not set # @@ -634,6 +671,7 @@ CONFIG_NET_CLS=y # CONFIG_NET_CLS_RSVP is not set # CONFIG_NET_CLS_RSVP6 is not set # CONFIG_NET_CLS_FLOW is not set +# CONFIG_NET_CLS_CGROUP is not set CONFIG_NET_EMATCH=y CONFIG_NET_EMATCH_STACK=32 # CONFIG_NET_EMATCH_CMP is not set @@ -649,7 +687,9 @@ CONFIG_NET_CLS_ACT=y # CONFIG_NET_ACT_NAT is not set # CONFIG_NET_ACT_PEDIT is not set # CONFIG_NET_ACT_SIMP is not set +# CONFIG_NET_ACT_SKBEDIT is not set CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set # # Network testing @@ -666,29 +706,33 @@ CONFIG_HAMRADIO=y # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set +# CONFIG_PHONET is not set CONFIG_FIB_RULES=y - -# -# Wireless -# +CONFIG_WIRELESS=y CONFIG_CFG80211=y +# CONFIG_CFG80211_REG_DEBUG is not set CONFIG_NL80211=y +CONFIG_WIRELESS_OLD_REGULATORY=y CONFIG_WIRELESS_EXT=y CONFIG_WIRELESS_EXT_SYSFS=y +# CONFIG_LIB80211 is not set CONFIG_MAC80211=y # # Rate control algorithm selection # -CONFIG_MAC80211_RC_PID=y -CONFIG_MAC80211_RC_DEFAULT_PID=y -CONFIG_MAC80211_RC_DEFAULT="pid" +CONFIG_MAC80211_RC_MINSTREL=y +# CONFIG_MAC80211_RC_DEFAULT_PID is not set +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel" # CONFIG_MAC80211_MESH is not set CONFIG_MAC80211_LEDS=y # CONFIG_MAC80211_DEBUGFS is not set # CONFIG_MAC80211_DEBUG_MENU is not set -# CONFIG_IEEE80211 is not set -# CONFIG_RFKILL is not set +# CONFIG_WIMAX is not set +CONFIG_RFKILL=y +# CONFIG_RFKILL_INPUT is not set +CONFIG_RFKILL_LEDS=y # CONFIG_NET_9P is not set # @@ -712,7 +756,7 @@ CONFIG_PROC_EVENTS=y # CONFIG_MTD is not set # CONFIG_PARPORT is not set CONFIG_PNP=y -# CONFIG_PNP_DEBUG is not set +CONFIG_PNP_DEBUG_MESSAGES=y # # Protocols @@ -740,21 +784,21 @@ CONFIG_BLK_DEV_RAM_SIZE=16384 CONFIG_MISC_DEVICES=y # CONFIG_IBM_ASM is not set # CONFIG_PHANTOM is not set -# CONFIG_EEPROM_93CX6 is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set -# CONFIG_ACER_WMI is not set -# CONFIG_ASUS_LAPTOP is not set -# CONFIG_FUJITSU_LAPTOP is not set -# CONFIG_MSI_LAPTOP is not set -# CONFIG_COMPAL_LAPTOP is not set -# CONFIG_SONY_LAPTOP is not set -# CONFIG_THINKPAD_ACPI is not set -# CONFIG_INTEL_MENLOW is not set +# CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_SGI_XP is not set # CONFIG_HP_ILO is not set # CONFIG_SGI_GRU is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_93CX6 is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -864,6 +908,7 @@ CONFIG_PATA_OLDPIIX=y CONFIG_PATA_SCH=y CONFIG_MD=y CONFIG_BLK_DEV_MD=y +CONFIG_MD_AUTODETECT=y # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set @@ -919,6 +964,9 @@ CONFIG_PHYLIB=y # CONFIG_BROADCOM_PHY is not set # CONFIG_ICPLUS_PHY is not set # CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set # CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y @@ -942,6 +990,9 @@ CONFIG_NET_TULIP=y # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set # CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set @@ -949,7 +1000,6 @@ CONFIG_NET_PCI=y # CONFIG_B44 is not set CONFIG_FORCEDETH=y # CONFIG_FORCEDETH_NAPI is not set -# CONFIG_EEPRO100 is not set CONFIG_E100=y # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set @@ -963,15 +1013,16 @@ CONFIG_8139TOO_PIO=y # CONFIG_R6040 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set +# CONFIG_SMSC9420 is not set # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set # CONFIG_SC92031 is not set +# CONFIG_ATL2 is not set CONFIG_NETDEV_1000=y # CONFIG_ACENIC is not set # CONFIG_DL2K is not set CONFIG_E1000=y -# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set # CONFIG_E1000E is not set # CONFIG_IP1000 is not set # CONFIG_IGB is not set @@ -989,18 +1040,23 @@ CONFIG_TIGON3=y # CONFIG_QLA3XXX is not set # CONFIG_ATL1 is not set # CONFIG_ATL1E is not set +# CONFIG_JME is not set CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set +CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_CHELSIO_T3 is not set +# CONFIG_ENIC is not set # CONFIG_IXGBE is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set # CONFIG_NIU is not set +# CONFIG_MLX4_EN is not set # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set # CONFIG_BNX2X is not set +# CONFIG_QLGE is not set # CONFIG_SFC is not set CONFIG_TR=y # CONFIG_IBMOL is not set @@ -1013,9 +1069,8 @@ CONFIG_TR=y # CONFIG_WLAN_PRE80211 is not set CONFIG_WLAN_80211=y # CONFIG_PCMCIA_RAYCS is not set -# CONFIG_IPW2100 is not set -# CONFIG_IPW2200 is not set # CONFIG_LIBERTAS is not set +# CONFIG_LIBERTAS_THINFIRM is not set # CONFIG_AIRO is not set # CONFIG_HERMES is not set # CONFIG_ATMEL is not set @@ -1032,6 +1087,8 @@ CONFIG_WLAN_80211=y CONFIG_ATH5K=y # CONFIG_ATH5K_DEBUG is not set # CONFIG_ATH9K is not set +# CONFIG_IPW2100 is not set +# CONFIG_IPW2200 is not set # CONFIG_IWLCORE is not set # CONFIG_IWLWIFI_LEDS is not set # CONFIG_IWLAGN is not set @@ -1042,6 +1099,10 @@ CONFIG_ATH5K=y # CONFIG_ZD1211RW is not set # CONFIG_RT2X00 is not set +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + # # USB Network Adapters # @@ -1050,6 +1111,7 @@ CONFIG_ATH5K=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +# CONFIG_USB_HSO is not set CONFIG_NET_PCMCIA=y # CONFIG_PCMCIA_3C589 is not set # CONFIG_PCMCIA_3C574 is not set @@ -1059,6 +1121,7 @@ CONFIG_NET_PCMCIA=y # CONFIG_PCMCIA_SMC91C92 is not set # CONFIG_PCMCIA_XIRC2PS is not set # CONFIG_PCMCIA_AXNET is not set +# CONFIG_PCMCIA_IBMTR is not set # CONFIG_WAN is not set CONFIG_FDDI=y # CONFIG_DEFXX is not set @@ -1110,6 +1173,7 @@ CONFIG_MOUSE_PS2_LOGIPS2PP=y CONFIG_MOUSE_PS2_SYNAPTICS=y CONFIG_MOUSE_PS2_LIFEBOOK=y CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_ELANTECH is not set # CONFIG_MOUSE_PS2_TOUCHKIT is not set # CONFIG_MOUSE_SERIAL is not set # CONFIG_MOUSE_APPLETOUCH is not set @@ -1147,15 +1211,16 @@ CONFIG_INPUT_TOUCHSCREEN=y # CONFIG_TOUCHSCREEN_FUJITSU is not set # CONFIG_TOUCHSCREEN_GUNZE is not set # CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set # CONFIG_TOUCHSCREEN_MTOUCH is not set # CONFIG_TOUCHSCREEN_INEXIO is not set # CONFIG_TOUCHSCREEN_MK712 is not set # CONFIG_TOUCHSCREEN_PENMOUNT is not set # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set # CONFIG_TOUCHSCREEN_TOUCHWIN is not set -# CONFIG_TOUCHSCREEN_UCB1400 is not set # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set CONFIG_INPUT_MISC=y # CONFIG_INPUT_PCSPKR is not set # CONFIG_INPUT_APANEL is not set @@ -1165,6 +1230,7 @@ CONFIG_INPUT_MISC=y # CONFIG_INPUT_KEYSPAN_REMOTE is not set # CONFIG_INPUT_POWERMATE is not set # CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set # CONFIG_INPUT_UINPUT is not set # @@ -1231,6 +1297,7 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set # CONFIG_IPMI_HANDLER is not set CONFIG_HW_RANDOM=y @@ -1260,6 +1327,7 @@ CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y # CONFIG_I2C_CHARDEV is not set CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=y # # I2C Hardware Bus support @@ -1311,8 +1379,6 @@ CONFIG_I2C_I801=y # Miscellaneous I2C Chip support # # CONFIG_DS1682 is not set -# CONFIG_EEPROM_AT24 is not set -# CONFIG_EEPROM_LEGACY is not set # CONFIG_SENSORS_PCF8574 is not set # CONFIG_PCF8575 is not set # CONFIG_SENSORS_PCA9539 is not set @@ -1331,8 +1397,78 @@ CONFIG_POWER_SUPPLY=y # CONFIG_POWER_SUPPLY_DEBUG is not set # CONFIG_PDA_POWER is not set # CONFIG_BATTERY_DS2760 is not set -# CONFIG_HWMON is not set +# CONFIG_BATTERY_BQ27x00 is not set +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ABITUGURU3 is not set +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7473 is not set +# CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_K8TEMP is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_I5K_AMB is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_FSCHMD is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_CORETEMP is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_SENSORS_HDAPS is not set +# CONFIG_SENSORS_LIS3LV02D is not set +# CONFIG_SENSORS_APPLESMC is not set +# CONFIG_HWMON_DEBUG_CHIP is not set CONFIG_THERMAL=y +# CONFIG_THERMAL_HWMON is not set CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -1352,15 +1488,18 @@ CONFIG_WATCHDOG=y # CONFIG_I6300ESB_WDT is not set # CONFIG_ITCO_WDT is not set # CONFIG_IT8712F_WDT is not set +# CONFIG_IT87_WDT is not set # CONFIG_HP_WATCHDOG is not set # CONFIG_SC1200_WDT is not set # CONFIG_PC87413_WDT is not set # CONFIG_60XX_WDT is not set # CONFIG_SBC8360_WDT is not set # CONFIG_CPU5_WDT is not set +# CONFIG_SMSC_SCH311X_WDT is not set # CONFIG_SMSC37B787_WDT is not set # CONFIG_W83627HF_WDT is not set # CONFIG_W83697HF_WDT is not set +# CONFIG_W83697UG_WDT is not set # CONFIG_W83877F_WDT is not set # CONFIG_W83977F_WDT is not set # CONFIG_MACHZ_WDT is not set @@ -1376,11 +1515,11 @@ CONFIG_WATCHDOG=y # USB-based Watchdog Cards # # CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y # # Sonics Silicon Backplane # -CONFIG_SSB_POSSIBLE=y # CONFIG_SSB is not set # @@ -1389,7 +1528,13 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_REGULATOR is not set # # Multimedia devices @@ -1423,6 +1568,7 @@ CONFIG_DRM=y # CONFIG_DRM_I810 is not set # CONFIG_DRM_I830 is not set CONFIG_DRM_I915=y +CONFIG_DRM_I915_KMS=y # CONFIG_DRM_MGA is not set # CONFIG_DRM_SIS is not set # CONFIG_DRM_VIA is not set @@ -1432,6 +1578,7 @@ CONFIG_DRM_I915=y CONFIG_FB=y # CONFIG_FIRMWARE_EDID is not set # CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y @@ -1460,7 +1607,6 @@ CONFIG_FB_TILEBLITTING=y # CONFIG_FB_UVESA is not set # CONFIG_FB_VESA is not set CONFIG_FB_EFI=y -# CONFIG_FB_IMAC is not set # CONFIG_FB_N411 is not set # CONFIG_FB_HGA is not set # CONFIG_FB_S1D13XXX is not set @@ -1475,6 +1621,7 @@ CONFIG_FB_EFI=y # CONFIG_FB_S3 is not set # CONFIG_FB_SAVAGE is not set # CONFIG_FB_SIS is not set +# CONFIG_FB_VIA is not set # CONFIG_FB_NEOMAGIC is not set # CONFIG_FB_KYRO is not set # CONFIG_FB_3DFX is not set @@ -1486,12 +1633,15 @@ CONFIG_FB_EFI=y # CONFIG_FB_CARMINE is not set # CONFIG_FB_GEODE is not set # CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set CONFIG_BACKLIGHT_LCD_SUPPORT=y # CONFIG_LCD_CLASS_DEVICE is not set CONFIG_BACKLIGHT_CLASS_DEVICE=y -# CONFIG_BACKLIGHT_CORGI is not set +CONFIG_BACKLIGHT_GENERIC=y # CONFIG_BACKLIGHT_PROGEAR is not set # CONFIG_BACKLIGHT_MBP_NVIDIA is not set +# CONFIG_BACKLIGHT_SAHARA is not set # # Display device support @@ -1511,10 +1661,12 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_VGA16 is not set CONFIG_LOGO_LINUX_CLUT224=y CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y CONFIG_SND=y CONFIG_SND_TIMER=y CONFIG_SND_PCM=y CONFIG_SND_HWDEP=y +CONFIG_SND_JACK=y CONFIG_SND_SEQUENCER=y CONFIG_SND_SEQ_DUMMY=y CONFIG_SND_OSSEMUL=y @@ -1522,6 +1674,8 @@ CONFIG_SND_MIXER_OSS=y CONFIG_SND_PCM_OSS=y CONFIG_SND_PCM_OSS_PLUGINS=y CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_HRTIMER=y +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y CONFIG_SND_DYNAMIC_MINORS=y CONFIG_SND_SUPPORT_OLD_API=y CONFIG_SND_VERBOSE_PROCFS=y @@ -1575,11 +1729,16 @@ CONFIG_SND_PCI=y # CONFIG_SND_FM801 is not set CONFIG_SND_HDA_INTEL=y CONFIG_SND_HDA_HWDEP=y +# CONFIG_SND_HDA_RECONFIG is not set +# CONFIG_SND_HDA_INPUT_BEEP is not set CONFIG_SND_HDA_CODEC_REALTEK=y CONFIG_SND_HDA_CODEC_ANALOG=y CONFIG_SND_HDA_CODEC_SIGMATEL=y CONFIG_SND_HDA_CODEC_VIA=y CONFIG_SND_HDA_CODEC_ATIHDMI=y +CONFIG_SND_HDA_CODEC_NVHDMI=y +CONFIG_SND_HDA_CODEC_INTELHDMI=y +CONFIG_SND_HDA_ELD=y CONFIG_SND_HDA_CODEC_CONEXANT=y CONFIG_SND_HDA_CODEC_CMEDIA=y CONFIG_SND_HDA_CODEC_SI3054=y @@ -1612,6 +1771,7 @@ CONFIG_SND_USB=y # CONFIG_SND_USB_AUDIO is not set # CONFIG_SND_USB_USX2Y is not set # CONFIG_SND_USB_CAIAQ is not set +# CONFIG_SND_USB_US122L is not set CONFIG_SND_PCMCIA=y # CONFIG_SND_VXPOCKET is not set # CONFIG_SND_PDAUDIOCF is not set @@ -1626,15 +1786,37 @@ CONFIG_HIDRAW=y # USB Input Devices # CONFIG_USB_HID=y -CONFIG_USB_HIDINPUT_POWERBOOK=y -CONFIG_HID_FF=y CONFIG_HID_PID=y +CONFIG_USB_HIDDEV=y + +# +# Special HID drivers +# +CONFIG_HID_COMPAT=y +CONFIG_HID_A4TECH=y +CONFIG_HID_APPLE=y +CONFIG_HID_BELKIN=y +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +CONFIG_HID_CYPRESS=y +CONFIG_HID_EZKEY=y +CONFIG_HID_GYRATION=y +CONFIG_HID_LOGITECH=y CONFIG_LOGITECH_FF=y # CONFIG_LOGIRUMBLEPAD2_FF is not set +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MONTEREY=y +CONFIG_HID_NTRIG=y +CONFIG_HID_PANTHERLORD=y CONFIG_PANTHERLORD_FF=y +CONFIG_HID_PETALYNX=y +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SONY=y +CONFIG_HID_SUNPLUS=y +# CONFIG_GREENASIA_FF is not set +CONFIG_HID_TOPSEED=y CONFIG_THRUSTMASTER_FF=y CONFIG_ZEROPLUS_FF=y -CONFIG_USB_HIDDEV=y CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y @@ -1652,6 +1834,8 @@ CONFIG_USB_DEVICEFS=y CONFIG_USB_SUSPEND=y # CONFIG_USB_OTG is not set CONFIG_USB_MON=y +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set # # USB Host Controller Drivers @@ -1660,6 +1844,7 @@ CONFIG_USB_MON=y CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_ROOT_HUB_TT is not set # CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_OXU210HP_HCD is not set # CONFIG_USB_ISP116X_HCD is not set # CONFIG_USB_ISP1760_HCD is not set CONFIG_USB_OHCI_HCD=y @@ -1669,6 +1854,8 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y CONFIG_USB_UHCI_HCD=y # CONFIG_USB_SL811_HCD is not set # CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_WHCI_HCD is not set +# CONFIG_USB_HWA_HCD is not set # # USB Device Class drivers @@ -1676,20 +1863,20 @@ CONFIG_USB_UHCI_HCD=y # CONFIG_USB_ACM is not set CONFIG_USB_PRINTER=y # CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set # -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; # # -# may also be needed; see USB_STORAGE Help for more information +# see USB_STORAGE Help for more information # CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set # CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set # CONFIG_USB_STORAGE_USBAT is not set # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_SDDR55 is not set @@ -1697,7 +1884,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_ALAUDA is not set # CONFIG_USB_STORAGE_ONETOUCH is not set # CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_SIERRA is not set # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set CONFIG_USB_LIBUSUAL=y @@ -1718,6 +1904,7 @@ CONFIG_USB_LIBUSUAL=y # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set # CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set @@ -1735,7 +1922,13 @@ CONFIG_USB_LIBUSUAL=y # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +# CONFIG_UWB is not set # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set CONFIG_NEW_LEDS=y @@ -1744,6 +1937,7 @@ CONFIG_LEDS_CLASS=y # # LED drivers # +# CONFIG_LEDS_ALIX2 is not set # CONFIG_LEDS_PCA9532 is not set # CONFIG_LEDS_CLEVO_MAIL is not set # CONFIG_LEDS_PCA955X is not set @@ -1754,6 +1948,7 @@ CONFIG_LEDS_CLASS=y CONFIG_LEDS_TRIGGERS=y # CONFIG_LEDS_TRIGGER_TIMER is not set # CONFIG_LEDS_TRIGGER_HEARTBEAT is not set +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set # CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set # CONFIG_ACCESSIBILITY is not set # CONFIG_INFINIBAND is not set @@ -1793,6 +1988,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_M41T80 is not set # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set # # SPI RTC drivers @@ -1802,12 +1998,15 @@ CONFIG_RTC_INTF_DEV=y # Platform RTC drivers # CONFIG_RTC_DRV_CMOS=y +# CONFIG_RTC_DRV_DS1286 is not set # CONFIG_RTC_DRV_DS1511 is not set # CONFIG_RTC_DRV_DS1553 is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -1820,6 +2019,21 @@ CONFIG_DMADEVICES=y # # CONFIG_INTEL_IOATDMA is not set # CONFIG_UIO is not set +# CONFIG_STAGING is not set +CONFIG_X86_PLATFORM_DEVICES=y +# CONFIG_ACER_WMI is not set +# CONFIG_ASUS_LAPTOP is not set +# CONFIG_FUJITSU_LAPTOP is not set +# CONFIG_MSI_LAPTOP is not set +# CONFIG_PANASONIC_LAPTOP is not set +# CONFIG_COMPAL_LAPTOP is not set +# CONFIG_SONY_LAPTOP is not set +# CONFIG_THINKPAD_ACPI is not set +# CONFIG_INTEL_MENLOW is not set +CONFIG_EEEPC_LAPTOP=y +# CONFIG_ACPI_WMI is not set +# CONFIG_ACPI_ASUS is not set +# CONFIG_ACPI_TOSHIBA is not set # # Firmware Drivers @@ -1841,22 +2055,25 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y CONFIG_EXT3_FS_SECURITY=y -# CONFIG_EXT4DEV_FS is not set +# CONFIG_EXT4_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y +CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_QUOTA_TREE=y # CONFIG_QFMT_V1 is not set CONFIG_QFMT_V2=y CONFIG_QUOTACTL=y @@ -1890,16 +2107,14 @@ CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_PROC_VMCORE=y CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y CONFIG_SYSFS=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_ECRYPT_FS is not set @@ -1909,6 +2124,7 @@ CONFIG_HUGETLB_PAGE=y # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -1930,6 +2146,7 @@ CONFIG_NFS_ACL_SUPPORT=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_REGISTER_V4 is not set CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -2035,40 +2252,60 @@ CONFIG_TIMER_STATS=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_VIRTUAL is not set # CONFIG_DEBUG_WRITECOUNT is not set CONFIG_DEBUG_MEMORY_INIT=y # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +CONFIG_ARCH_WANT_FRAME_POINTERS=y CONFIG_FRAME_POINTER=y # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_KPROBES_SANITY_TEST is not set # CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_LKDTM is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_HAVE_FTRACE=y +CONFIG_USER_STACKTRACE_SUPPORT=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y CONFIG_HAVE_DYNAMIC_FTRACE=y -# CONFIG_FTRACE is not set +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_HW_BRANCH_TRACER=y + +# +# Tracers +# +# CONFIG_FUNCTION_TRACER is not set # CONFIG_IRQSOFF_TRACER is not set # CONFIG_SYSPROF_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_POWER_TRACER is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_HW_BRANCH_TRACER is not set CONFIG_PROVIDE_OHCI1394_DMA_INIT=y +# CONFIG_DYNAMIC_PRINTK_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set # CONFIG_STRICT_DEVMEM is not set CONFIG_X86_VERBOSE_BOOTUP=y CONFIG_EARLY_PRINTK=y +CONFIG_EARLY_PRINTK_DBGP=y CONFIG_DEBUG_STACKOVERFLOW=y CONFIG_DEBUG_STACK_USAGE=y # CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_DEBUG_PER_CPU_MAPS is not set # CONFIG_X86_PTDUMP is not set CONFIG_DEBUG_RODATA=y -# CONFIG_DIRECT_GBPAGES is not set # CONFIG_DEBUG_RODATA_TEST is not set CONFIG_DEBUG_NX_TEST=m # CONFIG_IOMMU_DEBUG is not set @@ -2092,8 +2329,10 @@ CONFIG_OPTIMIZE_INLINING=y CONFIG_KEYS=y CONFIG_KEYS_DEBUG_PROC_KEYS=y CONFIG_SECURITY=y +# CONFIG_SECURITYFS is not set CONFIG_SECURITY_NETWORK=y # CONFIG_SECURITY_NETWORK_XFRM is not set +# CONFIG_SECURITY_PATH is not set CONFIG_SECURITY_FILE_CAPABILITIES=y # CONFIG_SECURITY_ROOTPLUG is not set CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=65536 @@ -2104,7 +2343,6 @@ CONFIG_SECURITY_SELINUX_DISABLE=y CONFIG_SECURITY_SELINUX_DEVELOP=y CONFIG_SECURITY_SELINUX_AVC_STATS=y CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 -# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set # CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set # CONFIG_SECURITY_SMACK is not set CONFIG_CRYPTO=y @@ -2112,11 +2350,18 @@ CONFIG_CRYPTO=y # # Crypto core or helper # +# CONFIG_CRYPTO_FIPS is not set CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y # CONFIG_CRYPTO_GF128MUL is not set # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_CRYPTD is not set @@ -2151,6 +2396,7 @@ CONFIG_CRYPTO_HMAC=y # Digest # # CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CRC32C_INTEL is not set # CONFIG_CRYPTO_MD4 is not set CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_MICHAEL_MIC is not set @@ -2191,6 +2437,11 @@ CONFIG_CRYPTO_DES=y # # CONFIG_CRYPTO_DEFLATE is not set # CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set CONFIG_HAVE_KVM=y @@ -2205,6 +2456,7 @@ CONFIG_VIRTUALIZATION=y CONFIG_BITREVERSE=y CONFIG_GENERIC_FIND_FIRST_BIT=y CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_FIND_LAST_BIT=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set CONFIG_CRC_T10DIF=y -- cgit From 556831063bcf8fd818e92227c40e3eaabe759bab Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 12 Feb 2009 12:51:29 +0100 Subject: x86, defconfig: turn off CONFIG_ENABLE_WARN_DEPRECATED MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit deprecation warnings have become rather noisy lately: drivers/i2c/i2c-core.c: In function ‘i2c_new_device’: drivers/i2c/i2c-core.c:283: warning: ‘i2c_attach_client’ is deprecated (declared at include/linux/i2c.h:434) drivers/i2c/i2c-core.c: In function ‘i2c_del_adapter’: drivers/i2c/i2c-core.c:646: warning: ‘detach_client’ is deprecated (declared at include/linux/i2c.h:154) drivers/i2c/i2c-core.c: In function ‘i2c_register_driver’: drivers/i2c/i2c-core.c:713: warning: ‘detach_client’ is deprecated (declared at include/linux/i2c.h:154) drivers/i2c/i2c-core.c: In function ‘__detach_adapter’: drivers/i2c/i2c-core.c:780: warning: ‘detach_client’ is deprecated (declared at include/linux/i2c.h:154) drivers/i2c/i2c-core.c: At top level: drivers/i2c/i2c-core.c:876: warning: ‘i2c_attach_client’ is deprecated (declared at drivers/i2c/i2c-core.c:827) drivers/i2c/i2c-core.c:876: warning: ‘i2c_attach_client’ is deprecated (declared at drivers/i2c/i2c-core.c:827) drivers/i2c/i2c-core.c:904: warning: ‘i2c_detach_client’ is deprecated (declared at drivers/i2c/i2c-core.c:879) drivers/i2c/i2c-core.c:904: warning: ‘i2c_detach_client’ is deprecated (declared at drivers/i2c/i2c-core.c:879) So turn it off for now - these reminders can obscure critical warnings. Signed-off-by: Ingo Molnar --- arch/x86/configs/i386_defconfig | 3 +-- arch/x86/configs/x86_64_defconfig | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig index c3186ccc936..0562a36f74d 100644 --- a/arch/x86/configs/i386_defconfig +++ b/arch/x86/configs/i386_defconfig @@ -2242,8 +2242,7 @@ CONFIG_NLS_UTF8=y # CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_PRINTK_TIME=y -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_ENABLE_WARN_DEPRECATED is not set CONFIG_FRAME_WARN=2048 CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig index 4c85bfa58e1..06633483b29 100644 --- a/arch/x86/configs/x86_64_defconfig +++ b/arch/x86/configs/x86_64_defconfig @@ -2223,8 +2223,7 @@ CONFIG_NLS_UTF8=y # CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_PRINTK_TIME=y -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_ENABLE_WARN_DEPRECATED is not set CONFIG_FRAME_WARN=2048 CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set -- cgit From bd282422fe9566a89bc34af325efb6d2701903be Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 12 Feb 2009 12:59:05 +0100 Subject: x86, defconfig: turn off CONFIG_SCSI_ISCSI_ATTRS=y It was enabled by mistake - iscsi is not included in a typical default PC, and no other architecture has it built-in (=y) either. Turn it off. Signed-off-by: Ingo Molnar --- arch/x86/configs/i386_defconfig | 8 ++++---- arch/x86/configs/x86_64_defconfig | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig index 0562a36f74d..8f40a80ccb5 100644 --- a/arch/x86/configs/i386_defconfig +++ b/arch/x86/configs/i386_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.29-rc4 -# Thu Feb 12 12:42:50 2009 +# Thu Feb 12 12:57:57 2009 # # CONFIG_64BIT is not set CONFIG_X86_32=y @@ -835,7 +835,7 @@ CONFIG_SCSI_WAIT_SCAN=m # CONFIG_SCSI_SPI_ATTRS=y # CONFIG_SCSI_FC_ATTRS is not set -CONFIG_SCSI_ISCSI_ATTRS=y +# CONFIG_SCSI_ISCSI_ATTRS is not set # CONFIG_SCSI_SAS_ATTRS is not set # CONFIG_SCSI_SAS_LIBSAS is not set # CONFIG_SCSI_SRP_ATTRS is not set @@ -2064,8 +2064,7 @@ CONFIG_EFI_VARS=y # CONFIG_DELL_RBU is not set # CONFIG_DCDBAS is not set CONFIG_DMIID=y -CONFIG_ISCSI_IBFT_FIND=y -CONFIG_ISCSI_IBFT=y +# CONFIG_ISCSI_IBFT_FIND is not set # # File systems @@ -2243,6 +2242,7 @@ CONFIG_NLS_UTF8=y CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_PRINTK_TIME=y # CONFIG_ENABLE_WARN_DEPRECATED is not set +CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=2048 CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig index 06633483b29..10728fd91c6 100644 --- a/arch/x86/configs/x86_64_defconfig +++ b/arch/x86/configs/x86_64_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.29-rc4 -# Thu Feb 12 12:48:13 2009 +# Thu Feb 12 12:57:29 2009 # CONFIG_64BIT=y # CONFIG_X86_32 is not set @@ -837,7 +837,7 @@ CONFIG_SCSI_WAIT_SCAN=m # CONFIG_SCSI_SPI_ATTRS=y # CONFIG_SCSI_FC_ATTRS is not set -CONFIG_SCSI_ISCSI_ATTRS=y +# CONFIG_SCSI_ISCSI_ATTRS is not set # CONFIG_SCSI_SAS_ATTRS is not set # CONFIG_SCSI_SAS_LIBSAS is not set # CONFIG_SCSI_SRP_ATTRS is not set @@ -2044,8 +2044,7 @@ CONFIG_EFI_VARS=y # CONFIG_DELL_RBU is not set # CONFIG_DCDBAS is not set CONFIG_DMIID=y -CONFIG_ISCSI_IBFT_FIND=y -CONFIG_ISCSI_IBFT=y +# CONFIG_ISCSI_IBFT_FIND is not set # # File systems @@ -2224,6 +2223,7 @@ CONFIG_NLS_UTF8=y CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_PRINTK_TIME=y # CONFIG_ENABLE_WARN_DEPRECATED is not set +CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=2048 CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set -- cgit From 3023533de43c5c01c660e1b48d3700b028eb4615 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 12 Feb 2009 13:28:43 +0100 Subject: x86: fix warning in find_low_pfn_range() Signed-off-by: Ingo Molnar --- arch/x86/mm/init_32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index d48f2560364..e77459dd38a 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c @@ -722,7 +722,7 @@ void __init find_low_pfn_range(void) highmem_pages = 0; #ifdef CONFIG_HIGHMEM if (highmem_pages >= max_pfn) { - printk(KERN_ERR "highmem size specified (%uMB) is " + printk(KERN_ERR "highmem size specified (%luMB) is " "bigger than pages available (%luMB)!.\n", pages_to_mb(highmem_pages), pages_to_mb(max_pfn)); @@ -731,7 +731,7 @@ void __init find_low_pfn_range(void) if (highmem_pages) { if (max_low_pfn - highmem_pages < 64*1024*1024/PAGE_SIZE){ - printk(KERN_ERR "highmem size %uMB results in " + printk(KERN_ERR "highmem size %luMB results in " "smaller than 64MB lowmem, ignoring it.\n" , pages_to_mb(highmem_pages)); highmem_pages = 0; -- cgit From 4769843bc265a9c24584b98709cf39e1df5c1404 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 12 Feb 2009 13:31:41 +0100 Subject: x86, 32-bit: clean up find_low_pfn_range() Impact: cleanup Split find_low_pfn_range() into two functions: - lowmem_pfn_init() - highmem_pfn_init() The former gets called if all of RAM fits into lowmem, otherwise we call highmem_pfn_init(). Signed-off-by: Ingo Molnar --- arch/x86/mm/init_32.c | 137 +++++++++++++++++++++++++++++--------------------- 1 file changed, 79 insertions(+), 58 deletions(-) diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index e77459dd38a..9d36eb9ebd5 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c @@ -675,75 +675,96 @@ static int __init parse_highmem(char *arg) } early_param("highmem", parse_highmem); +#define MSG_HIGHMEM_TOO_BIG \ + "highmem size (%luMB) is bigger than pages available (%luMB)!\n" + +#define MSG_LOWMEM_TOO_SMALL \ + "highmem size (%luMB) results in <64MB lowmem, ignoring it!\n" /* - * Determine low and high memory ranges: + * All of RAM fits into lowmem - but if user wants highmem + * artificially via the highmem=x boot parameter then create + * it: */ -void __init find_low_pfn_range(void) +void __init lowmem_pfn_init(void) { - /* it could update max_pfn */ - - /* max_low_pfn is 0, we already have early_res support */ - - max_low_pfn = max_pfn; - if (max_low_pfn > MAXMEM_PFN) { - if (highmem_pages == -1) - highmem_pages = max_pfn - MAXMEM_PFN; - if (highmem_pages + MAXMEM_PFN < max_pfn) - max_pfn = MAXMEM_PFN + highmem_pages; - if (highmem_pages + MAXMEM_PFN > max_pfn) { - printk(KERN_WARNING "only %luMB highmem pages " - "available, ignoring highmem size of %luMB.\n", - pages_to_mb(max_pfn - MAXMEM_PFN), + if (highmem_pages == -1) + highmem_pages = 0; +#ifdef CONFIG_HIGHMEM + if (highmem_pages >= max_pfn) { + printk(KERN_ERR MSG_HIGHMEM_TOO_BIG, + pages_to_mb(highmem_pages), pages_to_mb(max_pfn)); + highmem_pages = 0; + } + if (highmem_pages) { + if (max_low_pfn - highmem_pages < 64*1024*1024/PAGE_SIZE) { + printk(KERN_ERR MSG_LOWMEM_TOO_SMALL, pages_to_mb(highmem_pages)); highmem_pages = 0; } - max_low_pfn = MAXMEM_PFN; + max_low_pfn -= highmem_pages; + } +#else + if (highmem_pages) + printk(KERN_ERR "ignoring highmem size on non-highmem kernel!\n"); +#endif +} + +#define MSG_HIGHMEM_TOO_SMALL \ + "only %luMB highmem pages available, ignoring highmem size of %luMB!\n" + +#define MSG_HIGHMEM_TRIMMED \ + "Warning: only 4GB will be used. Use a HIGHMEM64G enabled kernel!\n" +/* + * We have more RAM than fits into lowmem - we try to put it into + * highmem, also taking the highmem=x boot parameter into account: + */ +void __init highmem_pfn_init(void) +{ + if (highmem_pages == -1) + highmem_pages = max_pfn - MAXMEM_PFN; + + if (highmem_pages + MAXMEM_PFN < max_pfn) + max_pfn = MAXMEM_PFN + highmem_pages; + + if (highmem_pages + MAXMEM_PFN > max_pfn) { + printk(KERN_WARNING MSG_HIGHMEM_TOO_SMALL, + pages_to_mb(max_pfn - MAXMEM_PFN), + pages_to_mb(highmem_pages)); + highmem_pages = 0; + } + max_low_pfn = MAXMEM_PFN; #ifndef CONFIG_HIGHMEM - /* Maximum memory usable is what is directly addressable */ - printk(KERN_WARNING "Warning only %ldMB will be used.\n", - MAXMEM>>20); - if (max_pfn > MAX_NONPAE_PFN) - printk(KERN_WARNING - "Use a HIGHMEM64G enabled kernel.\n"); - else - printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n"); - max_pfn = MAXMEM_PFN; + /* Maximum memory usable is what is directly addressable */ + printk(KERN_WARNING "Warning only %ldMB will be used.\n", MAXMEM>>20); + if (max_pfn > MAX_NONPAE_PFN) + printk(KERN_WARNING "Use a HIGHMEM64G enabled kernel.\n"); + else + printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n"); + max_pfn = MAXMEM_PFN; #else /* !CONFIG_HIGHMEM */ #ifndef CONFIG_HIGHMEM64G - if (max_pfn > MAX_NONPAE_PFN) { - max_pfn = MAX_NONPAE_PFN; - printk(KERN_WARNING "Warning only 4GB will be used." - "Use a HIGHMEM64G enabled kernel.\n"); - } + if (max_pfn > MAX_NONPAE_PFN) { + max_pfn = MAX_NONPAE_PFN; + printk(KERN_WARNING MSG_HIGHMEM_TRIMMED); + } #endif /* !CONFIG_HIGHMEM64G */ #endif /* !CONFIG_HIGHMEM */ - } else { - if (highmem_pages == -1) - highmem_pages = 0; -#ifdef CONFIG_HIGHMEM - if (highmem_pages >= max_pfn) { - printk(KERN_ERR "highmem size specified (%luMB) is " - "bigger than pages available (%luMB)!.\n", - pages_to_mb(highmem_pages), - pages_to_mb(max_pfn)); - highmem_pages = 0; - } - if (highmem_pages) { - if (max_low_pfn - highmem_pages < - 64*1024*1024/PAGE_SIZE){ - printk(KERN_ERR "highmem size %luMB results in " - "smaller than 64MB lowmem, ignoring it.\n" - , pages_to_mb(highmem_pages)); - highmem_pages = 0; - } - max_low_pfn -= highmem_pages; - } -#else - if (highmem_pages) - printk(KERN_ERR "ignoring highmem size on non-highmem" - " kernel!\n"); -#endif - } +} + +/* + * Determine low and high memory ranges: + */ +void __init find_low_pfn_range(void) +{ + /* it could update max_pfn */ + + /* max_low_pfn is 0, we already have early_res support */ + max_low_pfn = max_pfn; + + if (max_low_pfn > MAXMEM_PFN) + highmem_pfn_init(); + else + lowmem_pfn_init(); } #ifndef CONFIG_NEED_MULTIPLE_NODES -- cgit From d88316c243e5458a1888edbe0353c4dec6e61c73 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 12 Feb 2009 15:16:03 +0100 Subject: x86, 32-bit: refactor find_low_pfn_range() Impact: cleanup Make the max_low_pfn logic a bit more standard between lowmem_pfn_init() and highmem_pfn_init(). Signed-off-by: Ingo Molnar --- arch/x86/mm/init_32.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index 9d36eb9ebd5..1a9612499a3 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c @@ -687,6 +687,9 @@ early_param("highmem", parse_highmem); */ void __init lowmem_pfn_init(void) { + /* max_low_pfn is 0, we already have early_res support */ + max_low_pfn = max_pfn; + if (highmem_pages == -1) highmem_pages = 0; #ifdef CONFIG_HIGHMEM @@ -720,6 +723,8 @@ void __init lowmem_pfn_init(void) */ void __init highmem_pfn_init(void) { + max_low_pfn = MAXMEM_PFN; + if (highmem_pages == -1) highmem_pages = max_pfn - MAXMEM_PFN; @@ -732,7 +737,6 @@ void __init highmem_pfn_init(void) pages_to_mb(highmem_pages)); highmem_pages = 0; } - max_low_pfn = MAXMEM_PFN; #ifndef CONFIG_HIGHMEM /* Maximum memory usable is what is directly addressable */ printk(KERN_WARNING "Warning only %ldMB will be used.\n", MAXMEM>>20); @@ -758,13 +762,10 @@ void __init find_low_pfn_range(void) { /* it could update max_pfn */ - /* max_low_pfn is 0, we already have early_res support */ - max_low_pfn = max_pfn; - - if (max_low_pfn > MAXMEM_PFN) - highmem_pfn_init(); - else + if (max_pfn <= MAXMEM_PFN) lowmem_pfn_init(); + else + highmem_pfn_init(); } #ifndef CONFIG_NEED_MULTIPLE_NODES -- cgit From eb099670895f22970cd143875467c2768d6d87e5 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Thu, 12 Feb 2009 09:27:38 -0500 Subject: Btrfs: make sure all pending extent operations are complete Theres a slight problem with finish_current_insert, if we set all to 1 and then go through and don't actually skip any of the extents on the pending list, we could exit right after we've added new extents. This is a problem because by inserting the new extents we could have gotten new COW's to happen and such, so we may have some pending updates to do or even more inserts to do after that. So this patch will only exit if we have never skipped any of the extents in the pending list, and we have no extents to insert, this will make sure that all of the pending work is truly done before we return. I've been running with this patch for a few days with all of my other testing and have not seen issues. Thanks, Signed-off-by: Josef Bacik --- fs/btrfs/extent-tree.c | 71 +++++++++++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 7527523c2d2..376656f65b3 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -1323,8 +1323,25 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, int btrfs_extent_post_op(struct btrfs_trans_handle *trans, struct btrfs_root *root) { - finish_current_insert(trans, root->fs_info->extent_root, 1); - del_pending_extents(trans, root->fs_info->extent_root, 1); + u64 start; + u64 end; + int ret; + + while(1) { + finish_current_insert(trans, root->fs_info->extent_root, 1); + del_pending_extents(trans, root->fs_info->extent_root, 1); + + /* is there more work to do? */ + ret = find_first_extent_bit(&root->fs_info->pending_del, + 0, &start, &end, EXTENT_WRITEBACK); + if (!ret) + continue; + ret = find_first_extent_bit(&root->fs_info->extent_ins, + 0, &start, &end, EXTENT_WRITEBACK); + if (!ret) + continue; + break; + } return 0; } @@ -2211,13 +2228,12 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, u64 end; u64 priv; u64 search = 0; - u64 skipped = 0; struct btrfs_fs_info *info = extent_root->fs_info; struct btrfs_path *path; struct pending_extent_op *extent_op, *tmp; struct list_head insert_list, update_list; int ret; - int num_inserts = 0, max_inserts; + int num_inserts = 0, max_inserts, restart = 0; path = btrfs_alloc_path(); INIT_LIST_HEAD(&insert_list); @@ -2233,19 +2249,19 @@ again: ret = find_first_extent_bit(&info->extent_ins, search, &start, &end, EXTENT_WRITEBACK); if (ret) { - if (skipped && all && !num_inserts && + if (restart && !num_inserts && list_empty(&update_list)) { - skipped = 0; + restart = 0; search = 0; continue; } - mutex_unlock(&info->extent_ins_mutex); break; } ret = try_lock_extent(&info->extent_ins, start, end, GFP_NOFS); if (!ret) { - skipped = 1; + if (all) + restart = 1; search = end + 1; if (need_resched()) { mutex_unlock(&info->extent_ins_mutex); @@ -2264,7 +2280,7 @@ again: list_add_tail(&extent_op->list, &insert_list); search = end + 1; if (num_inserts == max_inserts) { - mutex_unlock(&info->extent_ins_mutex); + restart = 1; break; } } else if (extent_op->type == PENDING_BACKREF_UPDATE) { @@ -2280,7 +2296,6 @@ again: * somebody marked this thing for deletion then just unlock it and be * done, the free_extents will handle it */ - mutex_lock(&info->extent_ins_mutex); list_for_each_entry_safe(extent_op, tmp, &update_list, list) { clear_extent_bits(&info->extent_ins, extent_op->bytenr, extent_op->bytenr + extent_op->num_bytes - 1, @@ -2302,6 +2317,10 @@ again: if (!list_empty(&update_list)) { ret = update_backrefs(trans, extent_root, path, &update_list); BUG_ON(ret); + + /* we may have COW'ed new blocks, so lets start over */ + if (all) + restart = 1; } /* @@ -2309,9 +2328,9 @@ again: * need to make sure everything is cleaned then reset everything and * go back to the beginning */ - if (!num_inserts && all && skipped) { + if (!num_inserts && restart) { search = 0; - skipped = 0; + restart = 0; INIT_LIST_HEAD(&update_list); INIT_LIST_HEAD(&insert_list); goto again; @@ -2368,27 +2387,19 @@ again: BUG_ON(ret); /* - * if we broke out of the loop in order to insert stuff because we hit - * the maximum number of inserts at a time we can handle, then loop - * back and pick up where we left off + * if restart is set for whatever reason we need to go back and start + * searching through the pending list again. + * + * We just inserted some extents, which could have resulted in new + * blocks being allocated, which would result in new blocks needing + * updates, so if all is set we _must_ restart to get the updated + * blocks. */ - if (num_inserts == max_inserts) { - INIT_LIST_HEAD(&insert_list); - INIT_LIST_HEAD(&update_list); - num_inserts = 0; - goto again; - } - - /* - * again, if we need to make absolutely sure there are no more pending - * extent operations left and we know that we skipped some, go back to - * the beginning and do it all again - */ - if (all && skipped) { + if (restart || all) { INIT_LIST_HEAD(&insert_list); INIT_LIST_HEAD(&update_list); search = 0; - skipped = 0; + restart = 0; num_inserts = 0; goto again; } @@ -2709,6 +2720,8 @@ again: goto again; } + if (!err) + finish_current_insert(trans, extent_root, 0); return err; } -- cgit From b288052e1779261ae80138074989ef50358c4e58 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Thu, 12 Feb 2009 09:37:35 -0500 Subject: Btrfs: process mount options on mount -o remount, Btrfs wasn't parsing any new mount options during remount, making it difficult to set mount options on a root drive. Signed-off-by: Chris Mason --- fs/btrfs/super.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index f3fd7e2cbc3..66b8341e2db 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -511,6 +511,10 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) struct btrfs_root *root = btrfs_sb(sb); int ret; + ret = btrfs_parse_options(root, data); + if (ret) + return -EINVAL; + if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) return 0; -- cgit From 536ac8ae86e68bb5574d7cc81c7d229a86b82601 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Thu, 12 Feb 2009 09:41:38 -0500 Subject: Btrfs: use larger metadata clusters in ssd mode Larger metadata clusters can significantly improve writeback performance on ssd drives with large erasure blocks. The larger clusters make it more likely a given IO will completely overwrite the ssd block, so it doesn't have to do an internal rwm cycle. On spinning media, lager metadata clusters end up spreading out the metadata more over time, which makes fsck slower, so we don't want this to be the default. Signed-off-by: Chris Mason --- fs/btrfs/extent-tree.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 376656f65b3..c59e12036e2 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -2872,7 +2872,8 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, if (data & BTRFS_BLOCK_GROUP_METADATA) { last_ptr = &root->fs_info->last_alloc; - empty_cluster = 64 * 1024; + if (!btrfs_test_opt(root, SSD)) + empty_cluster = 64 * 1024; } if ((data & BTRFS_BLOCK_GROUP_DATA) && btrfs_test_opt(root, SSD)) -- cgit From e1df36d2f18254d0690a0fbe036cece74ec311b8 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Thu, 12 Feb 2009 09:45:08 -0500 Subject: Btrfs: don't clean old snapshots on sync(1) Cleaning old snapshots can make sync(1) somewhat slow, and some users and applications still use it in a global fsync kind of workload. This patch changes btrfs not to clean old snapshots during sync, which is safe from a FS consistency point of view. The major downside is that it makes it difficult to tell when old snapshots have been reaped and the space they were using has been reclaimed. A new ioctl will be added for this purpose instead. Signed-off-by: Chris Mason --- fs/btrfs/super.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 66b8341e2db..19a4daf03cc 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -379,7 +379,6 @@ int btrfs_sync_fs(struct super_block *sb, int wait) btrfs_start_delalloc_inodes(root); btrfs_wait_ordered_extents(root, 0); - btrfs_clean_old_snapshots(root); trans = btrfs_start_transaction(root, 1); ret = btrfs_commit_transaction(trans, root); sb->s_dirt = 0; -- cgit From b335b0034e252e79ec2e9c6697f5d663c4627bec Mon Sep 17 00:00:00 2001 From: Yan Zheng Date: Thu, 12 Feb 2009 10:06:04 -0500 Subject: Btrfs: Avoid using __GFP_HIGHMEM with slab allocator btrfs_releasepage may call kmem_cache_alloc indirectly, and provide same GFP flags it gets to kmem_cache_alloc. So it's possible to use __GFP_HIGHMEM with the slab allocator. Signed-off-by: Yan Zheng --- fs/btrfs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 8f0706210a4..638bcb5e49f 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4263,7 +4263,7 @@ static int btrfs_releasepage(struct page *page, gfp_t gfp_flags) { if (PageWriteback(page) || PageDirty(page)) return 0; - return __btrfs_releasepage(page, gfp_flags); + return __btrfs_releasepage(page, gfp_flags & GFP_NOFS); } static void btrfs_invalidatepage(struct page *page, unsigned long offset) -- cgit From 7951f3cefbd711f4429a0cd014aa83a844c399a0 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Thu, 12 Feb 2009 10:06:15 -0500 Subject: Btrfs: balance_level checks !child after access The BUG_ON() is in the wrong spot. Signed-off-by: Jeff Mahoney Signed-off-by: Chris Mason --- fs/btrfs/ctree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 35443cc4b9a..6674692f702 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -917,9 +917,9 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, /* promote the child to a root */ child = read_node_slot(root, mid, 0); + BUG_ON(!child); btrfs_tree_lock(child); btrfs_set_lock_blocking(child); - BUG_ON(!child); ret = btrfs_cow_block(trans, root, child, mid, 0, &child, 0); BUG_ON(ret); -- cgit From e00f7308658622fbd483cb0d9fe41165bf9050d0 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Thu, 12 Feb 2009 14:11:25 -0500 Subject: Btrfs: remove btrfs_init_path btrfs_init_path was initially used when the path objects were on the stack. Now all the work is done by btrfs_alloc_path and btrfs_init_path isn't required. This patch removes it, and just uses kmem_cache_zalloc to zero out the object. Signed-off-by: Chris Mason --- fs/btrfs/ctree.c | 11 ++--------- fs/btrfs/ctree.h | 1 - fs/btrfs/inode-map.c | 1 - fs/btrfs/inode.c | 2 -- 4 files changed, 2 insertions(+), 13 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 6674692f702..c8f4c540cc2 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -38,19 +38,12 @@ static int balance_node_right(struct btrfs_trans_handle *trans, static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, int level, int slot); -inline void btrfs_init_path(struct btrfs_path *p) -{ - memset(p, 0, sizeof(*p)); -} - struct btrfs_path *btrfs_alloc_path(void) { struct btrfs_path *path; - path = kmem_cache_alloc(btrfs_path_cachep, GFP_NOFS); - if (path) { - btrfs_init_path(path); + path = kmem_cache_zalloc(btrfs_path_cachep, GFP_NOFS); + if (path) path->reada = 1; - } return path; } diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 531db112c8b..3f7a8058df2 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -1834,7 +1834,6 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p); struct btrfs_path *btrfs_alloc_path(void); void btrfs_free_path(struct btrfs_path *p); -void btrfs_init_path(struct btrfs_path *p); void btrfs_set_path_blocking(struct btrfs_path *p); void btrfs_clear_path_blocking(struct btrfs_path *p); void btrfs_unlock_up_safe(struct btrfs_path *p, int level); diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c index 2aa79873eb4..cc7334d833c 100644 --- a/fs/btrfs/inode-map.c +++ b/fs/btrfs/inode-map.c @@ -84,7 +84,6 @@ int btrfs_find_free_objectid(struct btrfs_trans_handle *trans, search_key.type = 0; search_key.offset = 0; - btrfs_init_path(path); start_found = 0; ret = btrfs_search_slot(trans, root, &search_key, path, 0, 0); if (ret < 0) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 638bcb5e49f..3cee77ae03c 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2531,8 +2531,6 @@ noinline int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, key.offset = (u64)-1; key.type = (u8)-1; - btrfs_init_path(path); - search_again: ret = btrfs_search_slot(trans, root, &key, path, -1, 1); if (ret < 0) -- cgit From a48ddf08ba9bab91efd95e458737afa9d7699623 Mon Sep 17 00:00:00 2001 From: Qinghuang Feng Date: Thu, 12 Feb 2009 14:25:23 -0500 Subject: Btrfs: remove unused code in split_state() These two lines are not used, remove them. Signed-off-by: Qinghuang Feng Signed-off-by: Chris Mason --- fs/btrfs/extent_io.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 37d43b516b7..ebe6b29e606 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -415,8 +415,6 @@ static int split_state(struct extent_io_tree *tree, struct extent_state *orig, node = tree_insert(&tree->state, prealloc->end, &prealloc->rb_node); if (node) { - struct extent_state *found; - found = rb_entry(node, struct extent_state, rb_node); free_extent_state(prealloc); return -EEXIST; } -- cgit From 3f3420df505e47751ef76a652b5cb660e5360d6f Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 12 Feb 2009 10:16:03 -0500 Subject: Btrfs: fs/btrfs/volumes.c: remove useless kzalloc The call to kzalloc is followed by a kmalloc whose result is stored in the same variable. The semantic match that finds the problem is as follows: (http://www.emn.fr/x-info/coccinelle/) // @r exists@ local idexpression x; statement S; expression E; identifier f,l; position p1,p2; expression *ptr != NULL; @@ ( if ((x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...)) == NULL) S | x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...); ... if (x == NULL) S ) <... when != x when != if (...) { <+...x...+> } x->f = E ...> ( return \(0\|<+...x...+>\|ptr\); | return@p2 ...; ) @script:python@ p1 << r.p1; p2 << r.p2; @@ print "* file: %s kmalloc %s return %s" % (p1[0].file,p1[0].line,p2[0].line) // Signed-off-by: Julia Lawall Signed-off-by: Chris Mason --- fs/btrfs/volumes.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index bcd14ebccae..c793b6f50d8 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -2894,10 +2894,6 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, free_extent_map(em); } - map = kzalloc(sizeof(*map), GFP_NOFS); - if (!map) - return -ENOMEM; - em = alloc_extent_map(GFP_NOFS); if (!em) return -ENOMEM; -- cgit From b1aabecd55931ee754f6a913969516b26a0e682e Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Tue, 10 Feb 2009 15:21:44 +0200 Subject: mm: Export symbol ksize() Commit 7b2cd92adc5430b0c1adeb120971852b4ea1ab08 ("crypto: api - Fix zeroing on free") added modular user of ksize(). Export that to fix crypto.ko compilation. Cc: Herbert Xu Signed-off-by: Kirill A. Shutemov Signed-off-by: Pekka Enberg --- mm/slab.c | 1 + mm/slob.c | 1 + mm/slub.c | 1 + 3 files changed, 3 insertions(+) diff --git a/mm/slab.c b/mm/slab.c index ddc41f337d5..4d00855629c 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -4457,3 +4457,4 @@ size_t ksize(const void *objp) return obj_size(virt_to_cache(objp)); } +EXPORT_SYMBOL(ksize); diff --git a/mm/slob.c b/mm/slob.c index bf7e8fc3aed..52bc8a2bd9e 100644 --- a/mm/slob.c +++ b/mm/slob.c @@ -521,6 +521,7 @@ size_t ksize(const void *block) } else return sp->page.private; } +EXPORT_SYMBOL(ksize); struct kmem_cache { unsigned int size, align; diff --git a/mm/slub.c b/mm/slub.c index bdc9abb08a2..0280eee6cf3 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -2736,6 +2736,7 @@ size_t ksize(const void *object) */ return s->size; } +EXPORT_SYMBOL(ksize); void kfree(const void *x) { -- cgit From 3a4c6800f31ea8395628af5e7e490270ee5d0585 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Thu, 12 Feb 2009 04:34:23 +0100 Subject: Fix page writeback thinko, causing Berkeley DB slowdown A bug was introduced into write_cache_pages cyclic writeout by commit 31a12666d8f0c22235297e1c1575f82061480029 ("mm: write_cache_pages cyclic fix"). The intention (and comments) is that we should cycle back and look for more dirty pages at the beginning of the file if there is no more work to be done. But the !done condition was dropped from the test. This means that any time the page writeout loop breaks (eg. due to nr_to_write == 0), we will set index to 0, then goto again. This will set done_index to index, then find done is set, so will proceed to the end of the function. When updating mapping->writeback_index for cyclic writeout, we now use done_index == 0, so we're always cycling back to 0. This seemed to be causing random mmap writes (slapadd and iozone) to start writing more pages from the LRU and writeout would slowdown, and caused bugzilla entry http://bugzilla.kernel.org/show_bug.cgi?id=12604 about Berkeley DB slowing down dramatically. With this patch, iozone random write performance is increased nearly 5x on my system (iozone -B -r 4k -s 64k -s 512m -s 1200m on ext2). Signed-off-by: Nick Piggin Reported-and-tested-by: Jan Kara Signed-off-by: Linus Torvalds --- mm/page-writeback.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 6106a5c7ed4..3c84128596b 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -1079,7 +1079,7 @@ continue_unlock: pagevec_release(&pvec); cond_resched(); } - if (!cycled) { + if (!cycled && !done) { /* * range_cyclic: * We hit the last page and there is more work to be done: wrap -- cgit From 4008c04a07c73ec3cb1be4c1391d2159a8f75d6d Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Thu, 12 Feb 2009 14:09:45 -0500 Subject: Btrfs: make a lockdep class for the extent buffer locks Btrfs is currently using spin_lock_nested with a nested value based on the tree depth of the block. But, this doesn't quite work because the max tree depth is bigger than what spin_lock_nested can deal with, and because locks are sometimes taken before the level field is filled in. The solution here is to use lockdep_set_class_and_name instead, and to set the class before unlocking the pages when the block is read from the disk and just after init of a freshly allocated tree block. btrfs_clear_path_blocking is also changed to take the locks in the proper order, and it also makes sure all the locks currently held are properly set to blocking before it tries to retake the spinlocks. Otherwise, lockdep gets upset about bad lock orderin. The lockdep magic cam from Peter Zijlstra Signed-off-by: Chris Mason --- fs/btrfs/ctree.c | 45 ++++++++++++++++++++++++++++++++++----------- fs/btrfs/ctree.h | 10 +++------- fs/btrfs/disk-io.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- fs/btrfs/disk-io.h | 10 ++++++++++ fs/btrfs/extent-tree.c | 7 +++++-- fs/btrfs/locking.c | 11 ----------- fs/btrfs/volumes.c | 2 ++ 7 files changed, 99 insertions(+), 32 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index c8f4c540cc2..42491d728e9 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -62,14 +62,38 @@ noinline void btrfs_set_path_blocking(struct btrfs_path *p) /* * reset all the locked nodes in the patch to spinning locks. + * + * held is used to keep lockdep happy, when lockdep is enabled + * we set held to a blocking lock before we go around and + * retake all the spinlocks in the path. You can safely use NULL + * for held */ -noinline void btrfs_clear_path_blocking(struct btrfs_path *p) +noinline void btrfs_clear_path_blocking(struct btrfs_path *p, + struct extent_buffer *held) { int i; - for (i = 0; i < BTRFS_MAX_LEVEL; i++) { + +#ifdef CONFIG_DEBUG_LOCK_ALLOC + /* lockdep really cares that we take all of these spinlocks + * in the right order. If any of the locks in the path are not + * currently blocking, it is going to complain. So, make really + * really sure by forcing the path to blocking before we clear + * the path blocking. + */ + if (held) + btrfs_set_lock_blocking(held); + btrfs_set_path_blocking(p); +#endif + + for (i = BTRFS_MAX_LEVEL - 1; i >= 0; i--) { if (p->nodes[i] && p->locks[i]) btrfs_clear_lock_blocking(p->nodes[i]); } + +#ifdef CONFIG_DEBUG_LOCK_ALLOC + if (held) + btrfs_clear_lock_blocking(held); +#endif } /* this also releases the path */ @@ -279,7 +303,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, trans->transid, level, &ins); BUG_ON(ret); cow = btrfs_init_new_buffer(trans, root, prealloc_dest, - buf->len); + buf->len, level); } else { cow = btrfs_alloc_free_block(trans, root, buf->len, parent_start, @@ -1559,7 +1583,7 @@ cow_done: if (!p->skip_locking) p->locks[level] = 1; - btrfs_clear_path_blocking(p); + btrfs_clear_path_blocking(p, NULL); /* * we have a lock on b and as long as we aren't changing @@ -1598,7 +1622,7 @@ cow_done: btrfs_set_path_blocking(p); sret = split_node(trans, root, p, level); - btrfs_clear_path_blocking(p); + btrfs_clear_path_blocking(p, NULL); BUG_ON(sret > 0); if (sret) { @@ -1618,7 +1642,7 @@ cow_done: btrfs_set_path_blocking(p); sret = balance_level(trans, root, p, level); - btrfs_clear_path_blocking(p); + btrfs_clear_path_blocking(p, NULL); if (sret) { ret = sret; @@ -1681,13 +1705,13 @@ cow_done: if (!p->skip_locking) { int lret; - btrfs_clear_path_blocking(p); + btrfs_clear_path_blocking(p, NULL); lret = btrfs_try_spin_lock(b); if (!lret) { btrfs_set_path_blocking(p); btrfs_tree_lock(b); - btrfs_clear_path_blocking(p); + btrfs_clear_path_blocking(p, b); } } } else { @@ -1699,7 +1723,7 @@ cow_done: btrfs_set_path_blocking(p); sret = split_leaf(trans, root, key, p, ins_len, ret == 0); - btrfs_clear_path_blocking(p); + btrfs_clear_path_blocking(p, NULL); BUG_ON(sret > 0); if (sret) { @@ -3919,7 +3943,6 @@ find_next_key: btrfs_release_path(root, path); goto again; } else { - btrfs_clear_path_blocking(path); goto out; } } @@ -3939,7 +3962,7 @@ find_next_key: path->locks[level - 1] = 1; path->nodes[level - 1] = cur; unlock_up(path, level, 1); - btrfs_clear_path_blocking(path); + btrfs_clear_path_blocking(path, NULL); } out: if (ret == 0) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 3f7a8058df2..766b31ae318 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -43,11 +43,7 @@ struct btrfs_ordered_sum; #define BTRFS_ACL_NOT_CACHED ((void *)-1) -#ifdef CONFIG_LOCKDEP -# define BTRFS_MAX_LEVEL 7 -#else -# define BTRFS_MAX_LEVEL 8 -#endif +#define BTRFS_MAX_LEVEL 8 /* holds pointers to all of the tree roots */ #define BTRFS_ROOT_TREE_OBJECTID 1ULL @@ -1715,7 +1711,8 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, u64 empty_size); struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root, - u64 bytenr, u32 blocksize); + u64 bytenr, u32 blocksize, + int level); int btrfs_alloc_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 num_bytes, u64 parent, u64 min_bytes, @@ -1835,7 +1832,6 @@ void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p); struct btrfs_path *btrfs_alloc_path(void); void btrfs_free_path(struct btrfs_path *p); void btrfs_set_path_blocking(struct btrfs_path *p); -void btrfs_clear_path_blocking(struct btrfs_path *p); void btrfs_unlock_up_safe(struct btrfs_path *p, int level); int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 5aebddd7119..adda739a021 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -75,6 +75,40 @@ struct async_submit_bio { struct btrfs_work work; }; +/* These are used to set the lockdep class on the extent buffer locks. + * The class is set by the readpage_end_io_hook after the buffer has + * passed csum validation but before the pages are unlocked. + * + * The lockdep class is also set by btrfs_init_new_buffer on freshly + * allocated blocks. + * + * The class is based on the level in the tree block, which allows lockdep + * to know that lower nodes nest inside the locks of higher nodes. + * + * We also add a check to make sure the highest level of the tree is + * the same as our lockdep setup here. If BTRFS_MAX_LEVEL changes, this + * code needs update as well. + */ +#ifdef CONFIG_DEBUG_LOCK_ALLOC +# if BTRFS_MAX_LEVEL != 8 +# error +# endif +static struct lock_class_key btrfs_eb_class[BTRFS_MAX_LEVEL + 1]; +static const char *btrfs_eb_name[BTRFS_MAX_LEVEL + 1] = { + /* leaf */ + "btrfs-extent-00", + "btrfs-extent-01", + "btrfs-extent-02", + "btrfs-extent-03", + "btrfs-extent-04", + "btrfs-extent-05", + "btrfs-extent-06", + "btrfs-extent-07", + /* highest possible level */ + "btrfs-extent-08", +}; +#endif + /* * extents on the btree inode are pretty simple, there's one extent * that covers the entire device @@ -347,6 +381,15 @@ static int check_tree_block_fsid(struct btrfs_root *root, return ret; } +#ifdef CONFIG_DEBUG_LOCK_ALLOC +void btrfs_set_buffer_lockdep_class(struct extent_buffer *eb, int level) +{ + lockdep_set_class_and_name(&eb->lock, + &btrfs_eb_class[level], + btrfs_eb_name[level]); +} +#endif + static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, struct extent_state *state) { @@ -392,6 +435,8 @@ static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, } found_level = btrfs_header_level(eb); + btrfs_set_buffer_lockdep_class(eb, found_level); + ret = csum_tree_block(root, eb, 1); if (ret) ret = -EIO; @@ -1777,7 +1822,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, ret = find_and_setup_root(tree_root, fs_info, BTRFS_DEV_TREE_OBJECTID, dev_root); dev_root->track_dirty = 1; - if (ret) goto fail_extent_root; diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index 494a56eb298..95029db227b 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h @@ -101,4 +101,14 @@ int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, int btrfs_add_log_tree(struct btrfs_trans_handle *trans, struct btrfs_root *root); int btree_lock_page_hook(struct page *page); + + +#ifdef CONFIG_DEBUG_LOCK_ALLOC +void btrfs_set_buffer_lockdep_class(struct extent_buffer *eb, int level); +#else +static inline void btrfs_set_buffer_lockdep_class(struct extent_buffer *eb, + int level) +{ +} +#endif #endif diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index c59e12036e2..cd86bffbdc9 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -3416,7 +3416,8 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root, - u64 bytenr, u32 blocksize) + u64 bytenr, u32 blocksize, + int level) { struct extent_buffer *buf; @@ -3424,6 +3425,7 @@ struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, if (!buf) return ERR_PTR(-ENOMEM); btrfs_set_header_generation(buf, trans->transid); + btrfs_set_buffer_lockdep_class(buf, level); btrfs_tree_lock(buf); clean_tree_block(trans, root, buf); @@ -3467,7 +3469,8 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, return ERR_PTR(ret); } - buf = btrfs_init_new_buffer(trans, root, ins.objectid, blocksize); + buf = btrfs_init_new_buffer(trans, root, ins.objectid, + blocksize, level); return buf; } diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c index 9ebe9385129..85506c4a3af 100644 --- a/fs/btrfs/locking.c +++ b/fs/btrfs/locking.c @@ -25,21 +25,10 @@ #include "extent_io.h" #include "locking.h" -/* - * btrfs_header_level() isn't free, so don't call it when lockdep isn't - * on - */ -#ifdef CONFIG_DEBUG_LOCK_ALLOC -static inline void spin_nested(struct extent_buffer *eb) -{ - spin_lock_nested(&eb->lock, BTRFS_MAX_LEVEL - btrfs_header_level(eb)); -} -#else static inline void spin_nested(struct extent_buffer *eb) { spin_lock(&eb->lock); } -#endif /* * Setting a lock to blocking will drop the spinlock and set the diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index c793b6f50d8..1316139bf9e 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -3102,6 +3102,8 @@ int btrfs_read_sys_array(struct btrfs_root *root) if (!sb) return -ENOMEM; btrfs_set_buffer_uptodate(sb); + btrfs_set_buffer_lockdep_class(sb, 0); + write_extent_buffer(sb, super_copy, 0, BTRFS_SUPER_INFO_SIZE); array_size = btrfs_super_sys_array_size(super_copy); -- cgit From 2456242530a21cfee82646ebeeda65d3f74faa4c Mon Sep 17 00:00:00 2001 From: Yan Zheng Date: Thu, 12 Feb 2009 14:14:53 -0500 Subject: Btrfs: hold trans_mutex when using btrfs_record_root_in_trans btrfs_record_root_in_trans needs the trans_mutex held to make sure two callers don't race to setup the root in a given transaction. This adds it to all the places that were missing it. Signed-off-by: Yan Zheng --- fs/btrfs/extent-tree.c | 2 ++ fs/btrfs/transaction.c | 2 ++ fs/btrfs/tree-log.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index cd86bffbdc9..0a5d796c9f7 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -5658,7 +5658,9 @@ static noinline int relocate_one_extent(struct btrfs_root *extent_root, prev_block = block_start; } + mutex_lock(&extent_root->fs_info->trans_mutex); btrfs_record_root_in_trans(found_root); + mutex_unlock(&extent_root->fs_info->trans_mutex); if (ref_path->owner_objectid >= BTRFS_FIRST_FREE_OBJECTID) { /* * try to update data extent references while diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 919172de5c9..4112d53d4f4 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -688,7 +688,9 @@ static noinline int drop_dirty_roots(struct btrfs_root *tree_root, num_bytes -= btrfs_root_used(&dirty->root->root_item); bytes_used = btrfs_root_used(&root->root_item); if (num_bytes) { + mutex_lock(&root->fs_info->trans_mutex); btrfs_record_root_in_trans(root); + mutex_unlock(&root->fs_info->trans_mutex); btrfs_set_root_used(&root->root_item, bytes_used - num_bytes); } diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 20794290256..9c462fbd60f 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -2832,7 +2832,9 @@ again: BUG_ON(!wc.replay_dest); wc.replay_dest->log_root = log; + mutex_lock(&fs_info->trans_mutex); btrfs_record_root_in_trans(wc.replay_dest); + mutex_unlock(&fs_info->trans_mutex); ret = walk_log_tree(trans, log, &wc); BUG_ON(ret); -- cgit From d85cf93da66977dbc645352be1b2084a659d8a0b Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Thu, 12 Feb 2009 10:02:56 -0800 Subject: x86/paravirt: make arch_flush_lazy_mmu/cpu disable preemption Impact: avoid access to percpu vars in preempible context They are intended to be used whenever there's the possibility that there's some stale state which is going to be overwritten with a queued update, or to force a state change when we may be in lazy mode. Either way, we could end up calling it with preemption enabled, so wrap the functions in their own little preempt-disable section so they can be safely called in any context (though preemption should never be enabled if we're actually in a lazy state). (Move out of line to avoid #include dependencies.) Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Thomas Gleixner --- arch/x86/include/asm/paravirt.h | 17 ++--------------- arch/x86/kernel/paravirt.c | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index ba3e2ff6aed..a660eceaa27 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h @@ -1352,14 +1352,7 @@ static inline void arch_leave_lazy_cpu_mode(void) PVOP_VCALL0(pv_cpu_ops.lazy_mode.leave); } -static inline void arch_flush_lazy_cpu_mode(void) -{ - if (unlikely(paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU)) { - arch_leave_lazy_cpu_mode(); - arch_enter_lazy_cpu_mode(); - } -} - +void arch_flush_lazy_cpu_mode(void); #define __HAVE_ARCH_ENTER_LAZY_MMU_MODE static inline void arch_enter_lazy_mmu_mode(void) @@ -1372,13 +1365,7 @@ static inline void arch_leave_lazy_mmu_mode(void) PVOP_VCALL0(pv_mmu_ops.lazy_mode.leave); } -static inline void arch_flush_lazy_mmu_mode(void) -{ - if (unlikely(paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU)) { - arch_leave_lazy_mmu_mode(); - arch_enter_lazy_mmu_mode(); - } -} +void arch_flush_lazy_mmu_mode(void); static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx, unsigned long phys, pgprot_t flags) diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index e4c8fb60887..dcba6c567a2 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c @@ -268,6 +268,30 @@ enum paravirt_lazy_mode paravirt_get_lazy_mode(void) return __get_cpu_var(paravirt_lazy_mode); } +void arch_flush_lazy_mmu_mode(void) +{ + preempt_disable(); + + if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) { + arch_leave_lazy_mmu_mode(); + arch_enter_lazy_mmu_mode(); + } + + preempt_enable(); +} + +void arch_flush_lazy_cpu_mode(void) +{ + preempt_disable(); + + if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU) { + arch_leave_lazy_cpu_mode(); + arch_enter_lazy_cpu_mode(); + } + + preempt_enable(); +} + struct pv_info pv_info = { .name = "bare hardware", .paravirt_enabled = 0, -- cgit From 34b0900d323122113683685b200aae9f9b75e63b Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 12 Feb 2009 21:30:48 +0100 Subject: x86: warn if arch_flush_lazy_mmu_cpu is called in preemptible context Impact: Catch cases where lazy MMU state is active in a preemtible context arch_flush_lazy_mmu_cpu() has been changed to disable preemption so the checks in enter/leave will never trigger. Put the preemtible() check into arch_flush_lazy_mmu_cpu() to catch such cases. Signed-off-by: Thomas Gleixner --- arch/x86/kernel/paravirt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index dcba6c567a2..c6520a4e85d 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c @@ -273,6 +273,7 @@ void arch_flush_lazy_mmu_mode(void) preempt_disable(); if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) { + WARN_ON(preempt_count() == 1); arch_leave_lazy_mmu_mode(); arch_enter_lazy_mmu_mode(); } @@ -285,6 +286,7 @@ void arch_flush_lazy_cpu_mode(void) preempt_disable(); if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU) { + WARN_ON(preempt_count() == 1); arch_leave_lazy_cpu_mode(); arch_enter_lazy_cpu_mode(); } -- cgit From 7ad9de6ac83bd825996d2de98c92e0f425c31050 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 12 Feb 2009 21:16:09 +0100 Subject: x86: CPA avoid repeated lazy mmu flush Impact: Flush the lazy MMU only once Pending mmu updates only need to be flushed once to bring the in-memory pagetable state up to date. Signed-off-by: Thomas Gleixner --- arch/x86/mm/pageattr.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index f664bc1c409..8ca0d8566fc 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -575,14 +575,6 @@ static int __change_page_attr(struct cpa_data *cpa, int primary) address = cpa->vaddr[cpa->curpage]; else address = *cpa->vaddr; - - /* - * If we're called with lazy mmu updates enabled, the - * in-memory pte state may be stale. Flush pending updates to - * bring them up to date. - */ - arch_flush_lazy_mmu_mode(); - repeat: kpte = lookup_address(address, &level); if (!kpte) @@ -819,6 +811,13 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, vm_unmap_aliases(); + /* + * If we're called with lazy mmu updates enabled, the + * in-memory pte state may be stale. Flush pending updates to + * bring them up to date. + */ + arch_flush_lazy_mmu_mode(); + cpa.vaddr = addr; cpa.numpages = numpages; cpa.mask_set = mask_set; -- cgit From d4675b52a933831d4901217564cba5a434ddd922 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Thu, 12 Feb 2009 16:33:27 -0800 Subject: TG3: limit reaches -1 With while (limit--) { ... } limit reaches -1, so 0 means success. Signed-off-by: Roel Kluin Acked-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 8b3f8468538..4595962fb8e 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -852,7 +852,7 @@ static int tg3_bmcr_reset(struct tg3 *tp) } udelay(10); } - if (limit <= 0) + if (limit < 0) return -EBUSY; return 0; @@ -1603,7 +1603,7 @@ static int tg3_wait_macro_done(struct tg3 *tp) break; } } - if (limit <= 0) + if (limit < 0) return -EBUSY; return 0; -- cgit From 7a9deb661f5973b414df0c12b496d6ce49c8ed85 Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Thu, 12 Feb 2009 16:36:50 -0800 Subject: qlge: bugfix: Use netif_receive_skb() and vlan_hwaccel_receive_skb(). Replace calls to vlan_hwaccel_rx() and netif_rx(). Thanks to Dave Miller for pointing out the the driver was making the wrong upcall for passing packets into the stack. Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 3d1d7b6e55a..27c5e4de78e 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -1449,12 +1449,12 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev, if (qdev->vlgrp && (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V)) { QPRINTK(qdev, RX_STATUS, DEBUG, "Passing a VLAN packet upstream.\n"); - vlan_hwaccel_rx(skb, qdev->vlgrp, + vlan_hwaccel_receive_skb(skb, qdev->vlgrp, le16_to_cpu(ib_mac_rsp->vlan_id)); } else { QPRINTK(qdev, RX_STATUS, DEBUG, "Passing a normal packet upstream.\n"); - netif_rx(skb); + netif_receive_skb(skb); } } -- cgit From 6497b607fb2d918e7588338761bfc6d53f49eeea Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Thu, 12 Feb 2009 16:37:13 -0800 Subject: qlge: bugfix: Fix fatal error recovery hang. Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 27c5e4de78e..69f7d057dd2 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -1511,6 +1511,11 @@ void ql_queue_asic_error(struct ql_adapter *qdev) netif_stop_queue(qdev->ndev); netif_carrier_off(qdev->ndev); ql_disable_interrupts(qdev); + /* Clear adapter up bit to signal the recovery + * process that it shouldn't kill the reset worker + * thread + */ + clear_bit(QL_ADAPTER_UP, &qdev->flags); queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0); } @@ -3100,7 +3105,11 @@ static int ql_adapter_down(struct ql_adapter *qdev) netif_stop_queue(ndev); netif_carrier_off(ndev); - cancel_delayed_work_sync(&qdev->asic_reset_work); + /* Don't kill the reset worker thread if we + * are in the process of recovery. + */ + if (test_bit(QL_ADAPTER_UP, &qdev->flags)) + cancel_delayed_work_sync(&qdev->asic_reset_work); cancel_delayed_work_sync(&qdev->mpi_reset_work); cancel_delayed_work_sync(&qdev->mpi_work); @@ -3501,7 +3510,7 @@ static int qlge_set_mac_address(struct net_device *ndev, void *p) static void qlge_tx_timeout(struct net_device *ndev) { struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); - queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0); + ql_queue_asic_error(qdev); } static void ql_asic_reset_work(struct work_struct *work) -- cgit From f2603c2c571978497019a50c4df84c185ffef356 Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Thu, 12 Feb 2009 16:37:32 -0800 Subject: qlge: bugfix: Add missing put_page() call. We put the page back if we can't get mapping for it. We don't want unmapped buffers on our receive buffer queue. Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 69f7d057dd2..5b75fc9a26b 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -907,6 +907,8 @@ static void ql_update_lbq(struct ql_adapter *qdev, struct rx_ring *rx_ring) 0, PAGE_SIZE, PCI_DMA_FROMDEVICE); if (pci_dma_mapping_error(qdev->pdev, map)) { + put_page(lbq_desc->p.lbq_page); + lbq_desc->p.lbq_page = NULL; QPRINTK(qdev, RX_STATUS, ERR, "PCI mapping failed.\n"); return; -- cgit From 06a3d510faf6fdec43daaf6f4d94fe24edf650cd Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Thu, 12 Feb 2009 16:37:48 -0800 Subject: qlge: bugfix: Add missing dev_kfree_skb_any() call. We put the skb back if we can't get mapping for it. We don't want unmapped buffers on our receive buffer queue. Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 5b75fc9a26b..fc7d210ec96 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -970,6 +970,8 @@ static void ql_update_sbq(struct ql_adapter *qdev, struct rx_ring *rx_ring) if (pci_dma_mapping_error(qdev->pdev, map)) { QPRINTK(qdev, IFUP, ERR, "PCI mapping failed.\n"); rx_ring->sbq_clean_idx = clean_idx; + dev_kfree_skb_any(sbq_desc->p.skb); + sbq_desc->p.skb = NULL; return; } pci_unmap_addr_set(sbq_desc, mapaddr, map); -- cgit From 0d979f74a920bcc18eb451d363f02083a625294c Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Thu, 12 Feb 2009 16:38:03 -0800 Subject: qlge: bugfix: Fix TSO breakage. Moved the buffer mapping to a point after TSO logic has modified the iph->check field. We were seeing stale data on the PCIe bus. Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index fc7d210ec96..54b0a9e9d89 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -1936,10 +1936,6 @@ static int qlge_send(struct sk_buff *skb, struct net_device *ndev) tx_ring_desc = &tx_ring->q[tx_ring->prod_idx]; mac_iocb_ptr = tx_ring_desc->queue_entry; memset((void *)mac_iocb_ptr, 0, sizeof(mac_iocb_ptr)); - if (ql_map_send(qdev, mac_iocb_ptr, skb, tx_ring_desc) != NETDEV_TX_OK) { - QPRINTK(qdev, TX_QUEUED, ERR, "Could not map the segments.\n"); - return NETDEV_TX_BUSY; - } mac_iocb_ptr->opcode = OPCODE_OB_MAC_IOCB; mac_iocb_ptr->tid = tx_ring_desc->index; @@ -1965,6 +1961,12 @@ static int qlge_send(struct sk_buff *skb, struct net_device *ndev) ql_hw_csum_setup(skb, (struct ob_mac_tso_iocb_req *)mac_iocb_ptr); } + if (ql_map_send(qdev, mac_iocb_ptr, skb, tx_ring_desc) != + NETDEV_TX_OK) { + QPRINTK(qdev, TX_QUEUED, ERR, + "Could not map the segments.\n"); + return NETDEV_TX_BUSY; + } QL_DUMP_OB_MAC_IOCB(mac_iocb_ptr); tx_ring->prod_idx++; if (tx_ring->prod_idx == tx_ring->wq_len) -- cgit From def48b6e328c2ff9954c13e13ba8e1a03f0bde32 Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Thu, 12 Feb 2009 16:38:18 -0800 Subject: qlge: bugfix: Fix RX scaling values. Receive packets were only scaling across 2 of the receive queues. The value was hardcoded to 2 instead of being based on how many rx queues were running. Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 54b0a9e9d89..3ab03695aaf 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -2884,8 +2884,8 @@ static int ql_start_rss(struct ql_adapter *qdev) /* * Fill out the Indirection Table. */ - for (i = 0; i < 32; i++) - hash_id[i] = i & 1; + for (i = 0; i < 256; i++) + hash_id[i] = i & (qdev->rss_ring_count - 1); /* * Random values for the IPv6 and IPv4 Hash Keys. -- cgit From 79d2b29e8ab2bd460b07ff783d679d6cd3032769 Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Thu, 12 Feb 2009 16:38:34 -0800 Subject: qlge: bugfix: Add missing rx buf clean index on early exit. The large receive buffer queue is not properly tracking the current index in the case where an early exit occurs. This can happen when a page alloc or dma mapping fails. If this occurs the queue will get out of sync and invalid indexes can be written to the hardware. Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 3ab03695aaf..8ea72dc60f7 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -898,6 +898,7 @@ static void ql_update_lbq(struct ql_adapter *qdev, struct rx_ring *rx_ring) lbq_desc->index); lbq_desc->p.lbq_page = alloc_page(GFP_ATOMIC); if (lbq_desc->p.lbq_page == NULL) { + rx_ring->lbq_clean_idx = clean_idx; QPRINTK(qdev, RX_STATUS, ERR, "Couldn't get a page.\n"); return; @@ -907,6 +908,7 @@ static void ql_update_lbq(struct ql_adapter *qdev, struct rx_ring *rx_ring) 0, PAGE_SIZE, PCI_DMA_FROMDEVICE); if (pci_dma_mapping_error(qdev->pdev, map)) { + rx_ring->lbq_clean_idx = clean_idx; put_page(lbq_desc->p.lbq_page); lbq_desc->p.lbq_page = NULL; QPRINTK(qdev, RX_STATUS, ERR, -- cgit From cff71e89a8bd1175962b603f88f333883726b851 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Thu, 12 Feb 2009 16:40:20 -0800 Subject: sun3: print when lance_open() fails With while (--i > 0) { ... } i reaches 0; print when lance_open() fails Signed-off-by: Roel Kluin Signed-off-by: David S. Miller --- drivers/net/sun3lance.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c index 4bb8f72c65c..e5beb299cbd 100644 --- a/drivers/net/sun3lance.c +++ b/drivers/net/sun3lance.c @@ -428,7 +428,7 @@ static int lance_open( struct net_device *dev ) while (--i > 0) if (DREG & CSR0_IDON) break; - if (i < 0 || (DREG & CSR0_ERR)) { + if (i <= 0 || (DREG & CSR0_ERR)) { DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n", dev->name, i, DREG )); DREG = CSR0_STOP; -- cgit From acdb602fb3b7e13f3ffd2098549fab1bbfccba2f Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Thu, 12 Feb 2009 16:41:14 -0800 Subject: netxen: remove pcie workaround Remove workaround for pcie bug in early revisions of NX3031 (rev 41 or earlier). This is taken care of during firmware init. The workaround required writing pcie config reg of every pcie function on a card, not all of which are enabled. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic_main.c | 64 ------------------------------------ 1 file changed, 64 deletions(-) diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 3b17a793614..e02fe5ad215 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -372,67 +372,6 @@ static void netxen_set_port_mode(struct netxen_adapter *adapter) } } -#define PCI_CAP_ID_GEN 0x10 - -static void netxen_pcie_strap_init(struct netxen_adapter *adapter) -{ - u32 pdevfuncsave; - u32 c8c9value = 0; - u32 chicken = 0; - u32 control = 0; - int i, pos; - struct pci_dev *pdev; - - pdev = adapter->pdev; - - adapter->hw_read_wx(adapter, - NETXEN_PCIE_REG(PCIE_CHICKEN3), &chicken, 4); - /* clear chicken3.25:24 */ - chicken &= 0xFCFFFFFF; - /* - * if gen1 and B0, set F1020 - if gen 2, do nothing - * if gen2 set to F1000 - */ - pos = pci_find_capability(pdev, PCI_CAP_ID_GEN); - if (pos == 0xC0) { - pci_read_config_dword(pdev, pos + 0x10, &control); - if ((control & 0x000F0000) != 0x00020000) { - /* set chicken3.24 if gen1 */ - chicken |= 0x01000000; - } - printk(KERN_INFO "%s Gen2 strapping detected\n", - netxen_nic_driver_name); - c8c9value = 0xF1000; - } else { - /* set chicken3.24 if gen1 */ - chicken |= 0x01000000; - printk(KERN_INFO "%s Gen1 strapping detected\n", - netxen_nic_driver_name); - if (adapter->ahw.revision_id == NX_P3_B0) - c8c9value = 0xF1020; - else - c8c9value = 0; - - } - adapter->hw_write_wx(adapter, - NETXEN_PCIE_REG(PCIE_CHICKEN3), &chicken, 4); - - if (!c8c9value) - return; - - pdevfuncsave = pdev->devfn; - if (pdevfuncsave & 0x07) - return; - - for (i = 0; i < 8; i++) { - pci_read_config_dword(pdev, pos + 8, &control); - pci_read_config_dword(pdev, pos + 8, &control); - pci_write_config_dword(pdev, pos + 8, c8c9value); - pdev->devfn++; - } - pdev->devfn = pdevfuncsave; -} - static void netxen_set_msix_bit(struct pci_dev *pdev, int enable) { u32 control; @@ -812,9 +751,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } netxen_load_firmware(adapter); - if (NX_IS_REVISION_P3(revision_id)) - netxen_pcie_strap_init(adapter); - if (NX_IS_REVISION_P2(revision_id)) { /* Initialize multicast addr pool owners */ -- cgit From fb0886745a75ce98bde3aac421adc69fe61a1905 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Thu, 12 Feb 2009 16:42:31 -0800 Subject: IRDA: cnt is off by 1 If no prior break occurs, cnt reaches 101 after the loop, so we are still able to change speed when cnt has become 100. Signed-off-by: Roel Kluin Signed-off-by: David S. Miller --- drivers/net/irda/mcs7780.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c index 7eafdca19f3..85e88daab21 100644 --- a/drivers/net/irda/mcs7780.c +++ b/drivers/net/irda/mcs7780.c @@ -585,7 +585,7 @@ static int mcs_speed_change(struct mcs_cb *mcs) mcs_get_reg(mcs, MCS_RESV_REG, &rval); } while(cnt++ < 100 && (rval & MCS_IRINTX)); - if(cnt >= 100) { + if (cnt > 100) { IRDA_ERROR("unable to change speed\n"); ret = -EIO; goto error; -- cgit From 99709372736a216f99eb32b76fba835a2bfc93a8 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 12 Feb 2009 16:43:17 -0800 Subject: net: don't use in_atomic() in gfp_any() The problem is that in_atomic() will return false inside spinlocks if CONFIG_PREEMPT=n. This will lead to deadlockable GFP_KERNEL allocations from spinlocked regions. Secondly, if CONFIG_PREEMPT=y, this bug solves itself because networking will instead use GFP_ATOMIC from this callsite. Hence we won't get the might_sleep() debugging warnings which would have informed us of the buggy callsites. Solve both these problems by switching to in_interrupt(). Now, if someone runs a gfp_any() allocation from inside spinlock we will get the warning if CONFIG_PREEMPT=y. I reviewed all callsites and most of them were too complex for my little brain and none of them documented their interface requirements. I have no idea what this patch will do. Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- include/net/sock.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/net/sock.h b/include/net/sock.h index 5a3a151bd73..ce3b5b62268 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1308,7 +1308,7 @@ static inline int sock_writeable(const struct sock *sk) static inline gfp_t gfp_any(void) { - return in_atomic() ? GFP_ATOMIC : GFP_KERNEL; + return in_softirq() ? GFP_ATOMIC : GFP_KERNEL; } static inline long sock_rcvtimeo(const struct sock *sk, int noblock) -- cgit From f82da723398ff18d49275a5f03de6cae5f592e8e Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 12 Feb 2009 16:47:01 -0800 Subject: Documentation/connector/cn_test.c: don't use gfp_any() cn_test_timer_func() is a timer handler and can never use GFP_KERNEL - there's no point in using gfp_any() here. Also, use setup_timer(). Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- Documentation/connector/cn_test.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Documentation/connector/cn_test.c b/Documentation/connector/cn_test.c index be7af146dd3..6977c178729 100644 --- a/Documentation/connector/cn_test.c +++ b/Documentation/connector/cn_test.c @@ -137,7 +137,7 @@ static void cn_test_timer_func(unsigned long __data) memcpy(m + 1, data, m->len); - cn_netlink_send(m, 0, gfp_any()); + cn_netlink_send(m, 0, GFP_ATOMIC); kfree(m); } @@ -160,10 +160,8 @@ static int cn_test_init(void) goto err_out; } - init_timer(&cn_test_timer); - cn_test_timer.function = cn_test_timer_func; + setup_timer(&cn_test_timer, cn_test_timer_func, 0); cn_test_timer.expires = jiffies + HZ; - cn_test_timer.data = 0; add_timer(&cn_test_timer); return 0; -- cgit From 501aa061bd68169a5b54c123641f8dfa9ad31545 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Thu, 12 Feb 2009 16:52:31 -0800 Subject: 3c505: do not set pcb->data.raw beyond its size Ensure that we do not set pcb->data.raw beyond its size, print an error message and return false if we attempt to. A timout message was printed one too early. Signed-off-by: Roel Kluin Signed-off-by: David S. Miller --- drivers/net/3c505.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c index 6124605bef0..a8107f992fb 100644 --- a/drivers/net/3c505.c +++ b/drivers/net/3c505.c @@ -493,21 +493,27 @@ static bool receive_pcb(struct net_device *dev, pcb_struct * pcb) } /* read the data */ spin_lock_irqsave(&adapter->lock, flags); - i = 0; - do { - j = 0; - while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && j++ < 20000); - pcb->data.raw[i++] = inb_command(dev->base_addr); - if (i > MAX_PCB_DATA) - INVALID_PCB_MSG(i); - } while ((stat & ASF_PCB_MASK) != ASF_PCB_END && j < 20000); + for (i = 0; i < MAX_PCB_DATA; i++) { + for (j = 0; j < 20000; j++) { + stat = get_status(dev->base_addr); + if (stat & ACRF) + break; + } + pcb->data.raw[i] = inb_command(dev->base_addr); + if ((stat & ASF_PCB_MASK) == ASF_PCB_END || j >= 20000) + break; + } spin_unlock_irqrestore(&adapter->lock, flags); + if (i >= MAX_PCB_DATA) { + INVALID_PCB_MSG(i); + return false; + } if (j >= 20000) { TIMEOUT_MSG(__LINE__); return false; } - /* woops, the last "data" byte was really the length! */ - total_length = pcb->data.raw[--i]; + /* the last "data" byte was really the length! */ + total_length = pcb->data.raw[i]; /* safety check total length vs data length */ if (total_length != (pcb->length + 2)) { -- cgit From 86f95f9eac4370ca7b9cf5d34dea24faae5e4be6 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 12 Feb 2009 16:53:22 -0800 Subject: bnx2: Update 5706/5708 firmware. New firmware fixes a data corruption issue when receiving and placing jumbo frames into host buffers. In some cases, the buffer descriptor is not updated correctly and this will lead to the driver linking the wrong number of pages into the SKB. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2_fw.h | 8515 ++++++++++++++++++++++++------------------------- 1 file changed, 4206 insertions(+), 4309 deletions(-) diff --git a/drivers/net/bnx2_fw.h b/drivers/net/bnx2_fw.h index 24c3cc40c23..6a4f1d695de 100644 --- a/drivers/net/bnx2_fw.h +++ b/drivers/net/bnx2_fw.h @@ -15,854 +15,849 @@ */ static u8 bnx2_COM_b06FwText[] = { - 0xcd, 0x7c, 0x0d, 0x70, 0x5b, 0xd7, 0x95, 0xde, 0xc1, 0x03, 0x40, 0x82, - 0x10, 0x45, 0x3d, 0x52, 0x30, 0x0d, 0x3b, 0x4c, 0x82, 0x47, 0x3c, 0x92, - 0xb0, 0xc9, 0x64, 0x9f, 0x64, 0x46, 0x66, 0x12, 0xac, 0x05, 0x03, 0xa4, - 0x4c, 0x27, 0xea, 0x92, 0xb6, 0x19, 0x47, 0x6d, 0x35, 0x09, 0x17, 0x92, - 0x12, 0xdb, 0x4d, 0xa7, 0x9a, 0xc6, 0xe9, 0x2a, 0x1b, 0xc7, 0x82, 0x41, - 0xca, 0x51, 0x52, 0x8a, 0x60, 0x24, 0x4a, 0xf2, 0x74, 0xb3, 0xbb, 0x0c, - 0x48, 0x4a, 0x8e, 0x03, 0x09, 0x96, 0xec, 0x75, 0xdc, 0xad, 0xb3, 0x62, - 0x68, 0xad, 0xec, 0x4d, 0xb3, 0xad, 0x9d, 0x49, 0x3a, 0x9a, 0xa9, 0xb7, - 0x55, 0x95, 0xa4, 0xf9, 0x99, 0xfe, 0xb8, 0x49, 0xa6, 0x75, 0xbb, 0xf1, - 0xbe, 0x7e, 0xdf, 0x7d, 0xf7, 0x11, 0x20, 0xc5, 0x28, 0xde, 0xec, 0x64, - 0x66, 0x39, 0x83, 0xb9, 0xef, 0xde, 0x77, 0x7f, 0xce, 0x3d, 0xf7, 0xfc, - 0x7c, 0xe7, 0xde, 0xfb, 0x78, 0x87, 0x48, 0x54, 0xf4, 0xdf, 0x46, 0xfc, - 0xfa, 0xff, 0xe9, 0x3f, 0xdb, 0xb3, 0xf5, 0xdd, 0xfd, 0xef, 0x66, 0xde, - 0x30, 0x42, 0x21, 0xa6, 0x41, 0xfc, 0x62, 0xf8, 0x6d, 0xd5, 0xcf, 0xeb, - 0xfd, 0x99, 0xf8, 0x6d, 0x0b, 0x88, 0x8c, 0xff, 0x44, 0x24, 0xb0, 0xe6, - 0x5d, 0x64, 0x9d, 0xfa, 0xae, 0xfb, 0x4b, 0x3a, 0xd2, 0x7f, 0x06, 0x7e, - 0x89, 0xeb, 0x57, 0x59, 0x19, 0xf7, 0xd7, 0xfd, 0x0b, 0xea, 0xe6, 0x1b, - 0xf5, 0x4f, 0x22, 0x46, 0x5a, 0x46, 0xb2, 0xb6, 0x44, 0x82, 0xe9, 0x9f, - 0x8f, 0xec, 0xb1, 0x45, 0x32, 0x95, 0xde, 0x44, 0x4e, 0xde, 0x74, 0x0b, - 0xb1, 0x90, 0xb0, 0xfc, 0xed, 0xe9, 0x5f, 0x1c, 0xfc, 0xfa, 0xed, 0xd6, - 0xeb, 0x73, 0x41, 0x89, 0x98, 0xe9, 0x37, 0xc4, 0xec, 0x96, 0x48, 0x07, - 0xda, 0x7c, 0xa9, 0xe7, 0x49, 0x43, 0x5a, 0xfc, 0xbe, 0xcc, 0xf1, 0x60, - 0x5a, 0x46, 0xf7, 0x4e, 0x1d, 0x74, 0x0d, 0x5b, 0x0a, 0x37, 0xa7, 0xed, - 0x44, 0x51, 0x9a, 0x07, 0x26, 0xfb, 0x6f, 0x17, 0xe4, 0x47, 0xf7, 0x56, - 0x22, 0x92, 0xad, 0x16, 0x9a, 0x0d, 0xdb, 0x46, 0x1a, 0x29, 0xbc, 0x2d, - 0x2d, 0x91, 0x86, 0xf4, 0x6c, 0xe3, 0x25, 0x9b, 0xe3, 0x0f, 0x60, 0xfc, - 0xb7, 0x49, 0xc8, 0x76, 0xdd, 0x49, 0x8c, 0xbf, 0xa3, 0xf2, 0xa6, 0xfb, - 0x58, 0xc8, 0x1b, 0xdb, 0x48, 0x1f, 0x08, 0x32, 0x0d, 0xa4, 0x33, 0x23, - 0x9d, 0x15, 0x95, 0x6f, 0xf0, 0xf2, 0x83, 0x3a, 0x1f, 0x89, 0x7a, 0xb4, - 0x4b, 0x13, 0x68, 0x8f, 0x84, 0xd2, 0xe9, 0x26, 0xf4, 0x11, 0x09, 0xa7, - 0x97, 0x7e, 0x7b, 0x51, 0xd5, 0x3b, 0xac, 0xeb, 0x3d, 0x10, 0xf6, 0xda, - 0x4d, 0x8e, 0x74, 0x57, 0x98, 0xce, 0x8e, 0x74, 0xa9, 0xf4, 0x4b, 0x23, - 0x49, 0x95, 0xce, 0xa9, 0x7a, 0x81, 0xf4, 0xc2, 0x88, 0xad, 0xd2, 0xb4, - 0x2e, 0x1f, 0x1e, 0x49, 0xa8, 0x74, 0xa7, 0x4e, 0x47, 0x75, 0x3a, 0xa6, - 0xd3, 0x5d, 0x3a, 0xdd, 0xad, 0xd3, 0x71, 0x9d, 0xee, 0xd5, 0xfd, 0x3c, - 0xa0, 0xf3, 0x9f, 0xd0, 0xe9, 0x7e, 0x9d, 0x3e, 0xac, 0xd3, 0x03, 0x3a, - 0x7d, 0x44, 0xd3, 0x55, 0xd0, 0xe9, 0x94, 0x2e, 0x9f, 0xd1, 0x74, 0x3e, - 0x01, 0x7a, 0xfe, 0x71, 0xa3, 0x96, 0x5b, 0xcc, 0x37, 0x21, 0x7b, 0xa6, - 0x22, 0x52, 0x2c, 0x05, 0x25, 0xa7, 0xd6, 0xf3, 0xe3, 0x61, 0x89, 0x46, - 0x64, 0xa2, 0x1a, 0x91, 0x2b, 0x4a, 0x5c, 0x7f, 0xe4, 0x7e, 0xbd, 0xc7, - 0x94, 0xa7, 0xab, 0x31, 0xb9, 0x50, 0x95, 0xc0, 0x68, 0x4f, 0x93, 0x18, - 0x47, 0x6f, 0x96, 0x8c, 0x19, 0x90, 0xa0, 0xe2, 0x6b, 0x42, 0xb2, 0x53, - 0xed, 0xc8, 0x5b, 0x71, 0x91, 0xc5, 0xb0, 0xb7, 0x8e, 0x11, 0x09, 0x9e, - 0xe0, 0xba, 0x3c, 0x37, 0x72, 0x69, 0x36, 0x2e, 0xa1, 0xe9, 0x04, 0xfa, - 0x6f, 0x96, 0xf0, 0x09, 0xe9, 0x08, 0x4a, 0x57, 0xfc, 0x63, 0xa8, 0x31, - 0x58, 0x09, 0xc9, 0x50, 0x25, 0x80, 0xb5, 0x8a, 0x40, 0x4e, 0x9a, 0xf1, - 0x33, 0xf1, 0x8b, 0xe1, 0x17, 0xc7, 0xef, 0xaf, 0xd0, 0x4f, 0x87, 0xe4, - 0x2a, 0xec, 0x13, 0xe3, 0x96, 0x30, 0x7e, 0xc9, 0x32, 0xc7, 0x85, 0x34, - 0xc5, 0xe5, 0xeb, 0x3d, 0x1e, 0x4d, 0x17, 0xaa, 0x91, 0x40, 0xf6, 0xa4, - 0xec, 0xcf, 0x39, 0x92, 0x30, 0xec, 0xa8, 0xe4, 0xcd, 0x40, 0x62, 0x6f, - 0xaa, 0x4d, 0x0a, 0x63, 0x78, 0x57, 0x92, 0x8c, 0x81, 0xbe, 0xf3, 0xa6, - 0x8c, 0x7b, 0xef, 0x58, 0xf6, 0x7f, 0xa1, 0xaf, 0x96, 0x49, 0xc1, 0xbd, - 0x50, 0xfa, 0xd7, 0x78, 0x66, 0x5f, 0x2f, 0x86, 0x3c, 0x9a, 0xdf, 0x40, - 0x9e, 0xe5, 0xee, 0x26, 0x2f, 0xcf, 0x67, 0xd6, 0xf5, 0xc7, 0xf4, 0xe7, - 0xca, 0xb1, 0x7b, 0x30, 0x5f, 0x8e, 0xbf, 0x32, 0x5f, 0xd0, 0xd1, 0x1c, - 0xc8, 0x9d, 0x4c, 0xc8, 0xa1, 0xd2, 0x1d, 0x92, 0x75, 0x5c, 0x77, 0x8f, - 0x23, 0x31, 0x43, 0xba, 0xcc, 0x1c, 0xde, 0x96, 0x2b, 0x12, 0xc8, 0x96, - 0x7c, 0x7e, 0xb0, 0xdf, 0x10, 0xca, 0xda, 0x51, 0xbf, 0x25, 0x30, 0x78, - 0x12, 0xb4, 0xa7, 0xc9, 0x17, 0xc8, 0xac, 0xd3, 0x15, 0xdf, 0x8b, 0xf1, - 0xe6, 0x2b, 0x5d, 0xce, 0xb2, 0x98, 0xe8, 0xb3, 0x0d, 0x75, 0xc8, 0x23, - 0xf6, 0xc5, 0x3e, 0xd9, 0x5f, 0x33, 0xda, 0xc6, 0xf0, 0x8e, 0x34, 0xb9, - 0x6e, 0xd6, 0x31, 0x99, 0x97, 0x39, 0xf0, 0x6d, 0x8e, 0x7c, 0x8b, 0x76, - 0xc8, 0xa9, 0x0a, 0xc7, 0x58, 0x8f, 0xee, 0x5b, 0xff, 0x9e, 0xd1, 0x1d, - 0x47, 0xff, 0x31, 0xa4, 0x1b, 0x02, 0xd9, 0x63, 0x2e, 0xc6, 0x8f, 0xe3, - 0x79, 0xbd, 0x39, 0x5c, 0xd1, 0x32, 0x18, 0x07, 0xed, 0x31, 0x39, 0xa7, - 0xe4, 0x70, 0x83, 0x04, 0x21, 0x87, 0x5c, 0xe3, 0xd6, 0x13, 0xef, 0x91, - 0x7c, 0xcc, 0x4a, 0xd0, 0x76, 0x76, 0x6e, 0x6d, 0xc2, 0x1c, 0xb5, 0x15, - 0x9c, 0x8e, 0x41, 0x0e, 0x97, 0x5b, 0x0d, 0x94, 0x18, 0x62, 0x99, 0xff, - 0x48, 0x0a, 0x92, 0x5b, 0xf8, 0xbd, 0x80, 0x44, 0x0d, 0xd4, 0xbb, 0x25, - 0xe0, 0xf1, 0x80, 0xfc, 0xc9, 0x80, 0x3f, 0x01, 0xd1, 0xf6, 0x41, 0x3a, - 0x2b, 0x7c, 0xdf, 0x9b, 0x30, 0xd4, 0xbb, 0x41, 0xbc, 0x0b, 0x49, 0x72, - 0xab, 0xff, 0x7e, 0x10, 0xef, 0x6f, 0x96, 0x71, 0x13, 0xb4, 0x94, 0x9e, - 0x37, 0xb2, 0xa0, 0xf1, 0xce, 0x90, 0x9a, 0x2b, 0xea, 0x8e, 0xd7, 0xf5, - 0x33, 0x8e, 0x7a, 0xff, 0x0a, 0x63, 0x81, 0xde, 0x52, 0x02, 0xb4, 0xb4, - 0x83, 0x16, 0xd2, 0x58, 0x30, 0xb2, 0xd5, 0x10, 0xf2, 0x93, 0x46, 0xee, - 0xf4, 0x61, 0x3c, 0x8b, 0x69, 0xa4, 0x9f, 0x67, 0x8a, 0xf6, 0xbb, 0xeb, - 0xda, 0xef, 0x46, 0x7b, 0x8e, 0xc1, 0xf6, 0x9e, 0xfc, 0x17, 0x94, 0x2c, - 0x26, 0xae, 0xc3, 0x8f, 0xe0, 0xaf, 0xc1, 0x8f, 0x7f, 0xa3, 0xf9, 0xf1, - 0xd7, 0xf2, 0x9b, 0xe7, 0xc7, 0x7f, 0xfa, 0x0d, 0xf1, 0x43, 0x24, 0x7f, - 0x8c, 0xcf, 0x21, 0x29, 0x28, 0xbb, 0x45, 0xbd, 0xa5, 0xbc, 0xd3, 0x66, - 0x91, 0x4f, 0x94, 0x63, 0xe8, 0x40, 0x35, 0x84, 0xf4, 0x49, 0xa4, 0x1b, - 0x02, 0xa3, 0xc7, 0xae, 0x62, 0xfd, 0x5d, 0x31, 0xb7, 0xfa, 0x7e, 0xa3, - 0x10, 0x37, 0xa5, 0x43, 0xcc, 0x77, 0xc3, 0x69, 0xb7, 0x5b, 0x66, 0x5e, - 0x7e, 0x80, 0xf7, 0x6f, 0x06, 0x7c, 0xff, 0x9e, 0x9d, 0x6a, 0x7a, 0x23, - 0xa3, 0x9e, 0xc2, 0xe4, 0x67, 0xc6, 0x48, 0x87, 0x02, 0xb9, 0x52, 0x62, - 0xdc, 0x48, 0xc7, 0x60, 0xa7, 0x98, 0x1f, 0x08, 0x78, 0x34, 0xf7, 0xa3, - 0xae, 0x6f, 0xb3, 0x7c, 0xda, 0xfb, 0x41, 0xfb, 0x5a, 0xdb, 0x95, 0x01, - 0x2d, 0xa4, 0x81, 0x74, 0x15, 0x82, 0x9a, 0xf7, 0xe8, 0xe7, 0x80, 0xea, - 0x27, 0x98, 0x1e, 0x10, 0xfa, 0xd0, 0xfc, 0x14, 0xf5, 0x80, 0xed, 0xd8, - 0x97, 0x67, 0x93, 0xf3, 0x15, 0xbf, 0x8f, 0x42, 0x7d, 0x1f, 0xa0, 0x47, - 0x36, 0x19, 0x76, 0x18, 0x6b, 0xcf, 0xae, 0x0e, 0xe3, 0xdd, 0x97, 0x24, - 0x7b, 0xfa, 0x76, 0x03, 0x73, 0x40, 0xbf, 0xe4, 0xd1, 0x28, 0x6c, 0x36, - 0xf5, 0x2c, 0x22, 0xb9, 0x18, 0xcb, 0x3e, 0xa2, 0xc7, 0x0d, 0x49, 0x46, - 0xe5, 0xbf, 0xd2, 0x52, 0xa3, 0xe3, 0x79, 0x3d, 0x9f, 0x34, 0xe6, 0x43, - 0x1a, 0xfc, 0xb9, 0xa4, 0xeb, 0xe6, 0xe2, 0xf3, 0x9a, 0xbc, 0x30, 0x61, - 0xe3, 0x23, 0xda, 0x87, 0xb0, 0xdd, 0x64, 0xdd, 0xda, 0x4d, 0xa2, 0x0d, - 0x79, 0x8f, 0x3a, 0x6b, 0xfc, 0x0a, 0x7d, 0xca, 0x20, 0xfa, 0x29, 0xce, - 0x1a, 0x92, 0x73, 0xe0, 0xab, 0x9d, 0xb7, 0x69, 0x79, 0xad, 0xc9, 0x52, - 0x78, 0x5d, 0x59, 0x3a, 0x68, 0x78, 0xf6, 0x1a, 0xbe, 0x05, 0xfe, 0x67, - 0x62, 0xd6, 0x4a, 0xf9, 0xb2, 0x54, 0x9c, 0x7a, 0x2b, 0xb2, 0xe4, 0xb7, - 0x8f, 0x40, 0x76, 0xfd, 0x31, 0xd6, 0xd2, 0xec, 0xd7, 0x01, 0x8d, 0xa5, - 0xac, 0xc6, 0x28, 0x1c, 0xc7, 0xf3, 0x0d, 0x73, 0xab, 0x7c, 0xc3, 0x61, - 0xb4, 0x95, 0x40, 0xae, 0xa7, 0x59, 0xf6, 0xcd, 0xfa, 0x7d, 0x1c, 0x56, - 0x32, 0xbb, 0x77, 0xca, 0x32, 0x87, 0x82, 0x92, 0x19, 0x9a, 0x19, 0x90, - 0xc1, 0x6a, 0x07, 0xd6, 0xf4, 0x0d, 0x17, 0xbe, 0xf3, 0xdd, 0x61, 0xb1, - 0x61, 0x17, 0x31, 0xe7, 0x7e, 0xf0, 0xb8, 0x1a, 0x16, 0x23, 0xed, 0x20, - 0xad, 0xc7, 0x58, 0xa1, 0xd0, 0xd0, 0xaa, 0x7c, 0x03, 0xea, 0xa0, 0xef, - 0xfe, 0xb5, 0xf5, 0x20, 0x9f, 0xe0, 0x6d, 0xd6, 0x79, 0xd3, 0x85, 0x1f, - 0xd6, 0x3e, 0x8b, 0xa5, 0xb4, 0x13, 0xbe, 0x8d, 0xf8, 0x10, 0xf4, 0x5b, - 0xe9, 0x42, 0xc1, 0x48, 0xef, 0x47, 0x1f, 0xa2, 0xe4, 0xb4, 0x58, 0x7d, - 0xda, 0xd7, 0x7b, 0x55, 0xbe, 0xa3, 0x9f, 0xb2, 0x37, 0x07, 0x4c, 0xc0, - 0x39, 0x2d, 0x28, 0x5d, 0xcf, 0x99, 0x31, 0x99, 0x2c, 0x29, 0x4c, 0x23, - 0xc9, 0xca, 0x1f, 0x49, 0xee, 0xb4, 0xc8, 0x37, 0xa7, 0x58, 0xef, 0x05, - 0x5d, 0xef, 0x79, 0xd4, 0x4b, 0x26, 0x06, 0x03, 0x16, 0xfc, 0x80, 0x05, - 0x35, 0xe9, 0x4d, 0x20, 0x35, 0x87, 0xf1, 0x1b, 0xa4, 0x93, 0x41, 0x3d, - 0x0f, 0x03, 0x3d, 0x0f, 0x7e, 0x88, 0xdc, 0x53, 0x6a, 0x84, 0x3d, 0xf9, - 0x2f, 0xa0, 0x35, 0x26, 0x5f, 0xc0, 0x3c, 0x2e, 0x4d, 0x11, 0x67, 0xbd, - 0x20, 0x8b, 0x53, 0xc4, 0x5d, 0xcf, 0xcb, 0xe4, 0x54, 0xd2, 0xf9, 0x26, - 0xf8, 0x7c, 0x4a, 0x38, 0x97, 0x5e, 0x07, 0x29, 0x30, 0xa0, 0x95, 0x78, - 0x1c, 0xf6, 0xac, 0x67, 0xab, 0xd7, 0x5f, 0x97, 0xee, 0xcf, 0xae, 0x58, - 0x72, 0xc5, 0xa4, 0x7d, 0xba, 0x56, 0xc7, 0xb3, 0x5a, 0xc7, 0x47, 0x9d, - 0x0e, 0x31, 0xa0, 0xd7, 0x99, 0xb1, 0x02, 0xbc, 0x1f, 0xf5, 0xfa, 0x7f, - 0x1b, 0x35, 0xfc, 0x33, 0x00, 0xac, 0x6a, 0x29, 0x7f, 0xf7, 0xb7, 0xd3, - 0xf1, 0x7a, 0xdd, 0xe6, 0xf8, 0x2d, 0x68, 0x13, 0x42, 0x7a, 0x7d, 0xbd, - 0x46, 0x1f, 0x75, 0x6d, 0x07, 0xa8, 0x17, 0x68, 0xf3, 0x07, 0xe0, 0x05, - 0xf9, 0xff, 0x56, 0xf4, 0xb9, 0x37, 0xf8, 0x96, 0xf4, 0x79, 0xec, 0x7a, - 0xfa, 0x5c, 0xaf, 0xcb, 0x67, 0xc9, 0x0b, 0x8c, 0x2d, 0x33, 0x9e, 0x6c, - 0x75, 0x81, 0xd7, 0x09, 0xc8, 0x29, 0x68, 0x28, 0xfd, 0x8d, 0x9b, 0x09, - 0x79, 0x78, 0xce, 0x93, 0x27, 0xd6, 0xf3, 0xeb, 0x78, 0xb6, 0x77, 0xb0, - 0x7a, 0x45, 0xd9, 0xd9, 0x73, 0xca, 0xce, 0x5a, 0x87, 0x0b, 0x42, 0x79, - 0xbb, 0x2d, 0x48, 0xbe, 0x3f, 0xed, 0x7c, 0x16, 0x34, 0x5a, 0x89, 0x84, - 0xd1, 0x55, 0x30, 0x8c, 0xcf, 0xca, 0xfe, 0xf9, 0x87, 0x65, 0x7f, 0x89, - 0x7d, 0xa4, 0xf1, 0xde, 0x46, 0x59, 0x13, 0x6c, 0x2d, 0x6d, 0xfa, 0x1b, - 0x01, 0x6f, 0x2c, 0x03, 0xfe, 0x6b, 0x29, 0x70, 0x4f, 0xf5, 0x62, 0x20, - 0x3b, 0x4f, 0xdd, 0x45, 0x79, 0xb5, 0xde, 0xe6, 0xfb, 0xf6, 0xbe, 0x66, - 0xff, 0x06, 0x4b, 0x93, 0xc4, 0x80, 0x46, 0xd6, 0xe1, 0x9a, 0x51, 0x37, - 0x2f, 0x98, 0xde, 0x9c, 0x3f, 0x09, 0x3e, 0x51, 0xaf, 0xc9, 0x37, 0xf8, - 0xc0, 0x10, 0x75, 0x96, 0xcf, 0xe2, 0x06, 0xd3, 0xd4, 0x3b, 0x09, 0x05, - 0x41, 0x46, 0x2e, 0xc6, 0x3a, 0x77, 0x80, 0xce, 0xb5, 0x3a, 0xcd, 0x75, - 0x14, 0x6d, 0x43, 0x58, 0x36, 0x80, 0xe7, 0x4e, 0x19, 0x9f, 0xcf, 0x60, - 0xcc, 0x3b, 0x75, 0xdf, 0xab, 0x7c, 0x0c, 0xfa, 0x48, 0xe8, 0xf5, 0xd8, - 0xe0, 0xdb, 0x41, 0x94, 0x39, 0xba, 0xac, 0xa1, 0xae, 0xcc, 0x5f, 0xb7, - 0x8f, 0x62, 0x7c, 0xfa, 0x8a, 0x61, 0x8d, 0x7f, 0x5c, 0x37, 0xc7, 0xf5, - 0xee, 0xfb, 0x87, 0x42, 0xdd, 0xb8, 0x50, 0x2a, 0x98, 0x41, 0x25, 0xa3, - 0x2f, 0xfc, 0x4e, 0x4d, 0x46, 0x81, 0x97, 0x55, 0x2f, 0xe4, 0x31, 0x69, - 0x69, 0x06, 0x4f, 0x07, 0x41, 0x2b, 0x78, 0xd7, 0x1e, 0x00, 0xff, 0x9a, - 0x25, 0x5f, 0x4d, 0xeb, 0x77, 0x2c, 0x0f, 0xc9, 0x68, 0xcc, 0xf7, 0x47, - 0xb7, 0x99, 0x1e, 0xe6, 0x45, 0x9d, 0xd2, 0x8f, 0x83, 0x9e, 0x0e, 0x98, - 0x92, 0x3f, 0x39, 0x08, 0x59, 0x23, 0x26, 0x6b, 0x80, 0xac, 0xc5, 0x94, - 0xad, 0x37, 0x6c, 0xd6, 0xc7, 0xbb, 0xd3, 0xbf, 0x17, 0xf4, 0xda, 0xb0, - 0x9e, 0xdf, 0xc6, 0x1f, 0xbb, 0x6d, 0xa5, 0xed, 0xa8, 0x63, 0x48, 0x50, - 0x8d, 0x8f, 0xb2, 0xd3, 0xab, 0xc7, 0x37, 0xda, 0xfd, 0xf1, 0x1f, 0xd1, - 0x7d, 0xb5, 0xd5, 0xf5, 0x15, 0xbb, 0xce, 0xf8, 0x78, 0x77, 0xfa, 0xa3, - 0x9b, 0xbd, 0x36, 0xb1, 0xba, 0x36, 0xed, 0x6b, 0xda, 0xb0, 0xbe, 0x3f, - 0x06, 0xde, 0x9d, 0xbe, 0xab, 0xd9, 0x6b, 0xc3, 0x7a, 0x0d, 0xf0, 0x6d, - 0x7c, 0x47, 0xd9, 0xdf, 0x5f, 0x27, 0xfb, 0xfb, 0x21, 0xfb, 0xbe, 0x4c, - 0xad, 0xc5, 0xc9, 0x7e, 0xbc, 0xc3, 0x38, 0x87, 0xd8, 0xaa, 0x16, 0xd7, - 0x84, 0x4e, 0x34, 0x03, 0xb7, 0xb4, 0x30, 0x96, 0xd1, 0xb8, 0x98, 0xb1, - 0x0d, 0x71, 0xb0, 0xd8, 0x21, 0xe9, 0x82, 0x8d, 0xea, 0x8a, 0xef, 0xa3, - 0xc2, 0x55, 0x62, 0x0a, 0x2f, 0x67, 0xf4, 0x18, 0x8c, 0x6b, 0xc8, 0x77, - 0xe6, 0x73, 0x2b, 0x71, 0x4e, 0x07, 0xe2, 0x20, 0xe2, 0x5d, 0xe2, 0x25, - 0x9f, 0x7e, 0x9f, 0x9e, 0x03, 0x46, 0x4d, 0x27, 0x32, 0xc6, 0x60, 0x75, - 0xd0, 0xf0, 0x74, 0x82, 0xef, 0x0f, 0x68, 0x9f, 0xb6, 0x96, 0xde, 0xb7, - 0xaf, 0xa1, 0x97, 0xb8, 0x2a, 0x21, 0x13, 0x90, 0x91, 0xd0, 0x09, 0xda, - 0xd8, 0xe7, 0x46, 0x16, 0x67, 0x89, 0x1f, 0xfa, 0xc0, 0x17, 0xd2, 0x4b, - 0xfe, 0x51, 0x97, 0x5b, 0x60, 0x1f, 0xba, 0x52, 0x65, 0xd4, 0x67, 0x7c, - 0x3d, 0xae, 0xe2, 0xb2, 0x66, 0xa4, 0x08, 0x9e, 0x40, 0xeb, 0x38, 0x68, - 0x1d, 0xd7, 0x31, 0xd9, 0x3e, 0xd8, 0xef, 0xd0, 0xb4, 0x4f, 0xeb, 0x8d, - 0x21, 0x7f, 0x6d, 0x56, 0xd3, 0x5e, 0xef, 0x77, 0x3c, 0xfc, 0x75, 0x4f, - 0x0f, 0x65, 0xc6, 0x2a, 0x10, 0xb3, 0x8d, 0x2b, 0xf9, 0x00, 0xf6, 0x33, - 0xc4, 0xd3, 0xa5, 0x16, 0xdf, 0xff, 0x72, 0x3e, 0xf4, 0xff, 0xd4, 0x79, - 0x7f, 0x0e, 0xcd, 0xd2, 0x79, 0x82, 0x73, 0x58, 0xa1, 0x3f, 0xc6, 0xdd, - 0x8d, 0xfd, 0xb0, 0x9b, 0x79, 0x45, 0xeb, 0x4e, 0xd9, 0x5b, 0x7a, 0xa7, - 0xa6, 0xbf, 0x19, 0xf4, 0x8f, 0x42, 0xb6, 0x6b, 0x36, 0x23, 0x5f, 0x19, - 0x43, 0xde, 0xc3, 0x62, 0xe4, 0x71, 0xbe, 0x42, 0xfb, 0xa1, 0xe7, 0x13, - 0xe5, 0x7c, 0xd6, 0xda, 0x96, 0xf5, 0xf8, 0xfa, 0x8e, 0x35, 0x7c, 0x15, - 0xcd, 0xd7, 0x88, 0x34, 0x9c, 0x50, 0x71, 0x2d, 0xfa, 0x25, 0xaf, 0xe9, - 0xbf, 0x9e, 0x1b, 0x99, 0x9c, 0x95, 0xbe, 0xb0, 0x90, 0xbe, 0x38, 0xcb, - 0xfa, 0x1b, 0xa4, 0xcb, 0xb9, 0x88, 0x79, 0xe7, 0xb1, 0xde, 0xc6, 0xb4, - 0x27, 0xdf, 0xe4, 0x6f, 0xbe, 0x12, 0x45, 0x2c, 0xcd, 0xb1, 0xc9, 0x33, - 0xd2, 0x6f, 0x2a, 0x7a, 0x56, 0xf8, 0x0d, 0xfa, 0x3e, 0x56, 0x59, 0xcb, - 0xdb, 0x7a, 0x3b, 0xe3, 0xc7, 0xec, 0xdf, 0x35, 0x3d, 0xbd, 0x58, 0x2f, - 0x66, 0x6f, 0x86, 0x7d, 0x0c, 0xd1, 0x36, 0x82, 0xf7, 0xdc, 0x5f, 0x59, - 0x0a, 0x11, 0x83, 0x5f, 0x28, 0x85, 0x95, 0xcd, 0xcb, 0x3a, 0x2d, 0x5a, - 0x3f, 0x6e, 0xd3, 0xbe, 0x23, 0xac, 0x6c, 0xb6, 0x18, 0x26, 0x71, 0x09, - 0xca, 0x90, 0x9f, 0x67, 0xde, 0xa7, 0xe3, 0xde, 0x5d, 0x61, 0xfb, 0x0f, - 0x43, 0xbe, 0x4d, 0xa8, 0xd1, 0x55, 0x1f, 0x93, 0xbb, 0xc0, 0x72, 0xef, - 0x84, 0xdc, 0xde, 0x89, 0xb8, 0x3b, 0x21, 0xf9, 0x14, 0xf5, 0x68, 0x40, - 0xc5, 0x26, 0x86, 0xbd, 0x0f, 0x65, 0x4d, 0x28, 0x83, 0x13, 0x33, 0x31, - 0x7f, 0xfb, 0x77, 0x65, 0x1c, 0x32, 0x9e, 0x4f, 0xf5, 0x82, 0x0e, 0xda, - 0x60, 0x60, 0x1c, 0x3b, 0xc5, 0xb8, 0x1d, 0x7f, 0xfd, 0x61, 0x6f, 0x5e, - 0xbb, 0x90, 0x47, 0x0c, 0x9f, 0xea, 0xd4, 0x75, 0x36, 0x08, 0xf7, 0x7f, - 0xf2, 0x66, 0x0b, 0xd2, 0xee, 0x35, 0x75, 0xdf, 0x8f, 0xfc, 0x7b, 0x75, - 0xff, 0x05, 0xbc, 0xdf, 0x86, 0xdf, 0x20, 0xca, 0x6e, 0x47, 0x99, 0x83, - 0xb2, 0xf7, 0x20, 0xff, 0x7e, 0xbd, 0x1f, 0xe0, 0xb7, 0x69, 0x41, 0xfe, - 0x31, 0xbc, 0x87, 0xad, 0x30, 0x5f, 0xc6, 0xfb, 0xf7, 0xe2, 0xf7, 0xee, - 0x35, 0x75, 0xda, 0xd6, 0xe4, 0x3f, 0xb5, 0xc2, 0x83, 0x0b, 0xa5, 0x9f, - 0x69, 0xbb, 0x46, 0x79, 0x66, 0xfe, 0x94, 0x7e, 0xf7, 0xce, 0xd0, 0xea, - 0xf2, 0x1d, 0x7e, 0xbe, 0x6e, 0x0d, 0x3b, 0xb1, 0x86, 0x3e, 0xc6, 0x7c, - 0xbb, 0xf6, 0x5d, 0x6f, 0xf7, 0xe2, 0xf4, 0x92, 0xdf, 0x8e, 0x7e, 0xed, - 0xce, 0x35, 0x63, 0x3c, 0xdf, 0x50, 0xcb, 0x37, 0x07, 0x86, 0x4e, 0xb2, - 0xec, 0x72, 0xc3, 0xea, 0x3a, 0x6f, 0xd6, 0xe5, 0x37, 0x06, 0x86, 0x94, - 0x8f, 0xbb, 0xab, 0x71, 0x75, 0x9d, 0x64, 0x63, 0x6d, 0x1e, 0x35, 0x5b, - 0x18, 0x4a, 0x2f, 0x53, 0x8e, 0xa1, 0x0b, 0xdf, 0x1a, 0xc9, 0x4e, 0xb9, - 0xee, 0x84, 0xb3, 0x14, 0x0f, 0x0a, 0x7d, 0x10, 0xb1, 0x2a, 0xcb, 0x5f, - 0x46, 0x39, 0xb0, 0x4c, 0x75, 0x54, 0x68, 0x93, 0xd6, 0xc7, 0xa4, 0x09, - 0x8d, 0x49, 0x55, 0x36, 0x94, 0x55, 0x18, 0xf2, 0xf9, 0x11, 0x60, 0x1e, - 0xfd, 0xfc, 0x02, 0x9e, 0x13, 0xf5, 0xb8, 0x17, 0xfd, 0x2e, 0x8d, 0x64, - 0x67, 0xe9, 0xf3, 0x2e, 0x8e, 0xec, 0x99, 0xa5, 0xce, 0x5f, 0x82, 0xce, - 0x07, 0x64, 0x52, 0xf9, 0x3f, 0xd2, 0xc1, 0x76, 0x4b, 0x23, 0x9d, 0x0b, - 0x4c, 0x97, 0x47, 0xec, 0x85, 0xa0, 0xec, 0x8b, 0x79, 0x6d, 0x99, 0x4f, - 0x2c, 0xf8, 0x3a, 0x10, 0x95, 0x70, 0x9a, 0x32, 0x69, 0xa5, 0x80, 0xbd, - 0x31, 0x9f, 0x27, 0x47, 0x26, 0x6d, 0xca, 0xe7, 0x87, 0x1a, 0xa4, 0x25, - 0x2a, 0x0d, 0xca, 0xde, 0x3c, 0xa5, 0xc7, 0xba, 0x84, 0xb1, 0x36, 0x29, - 0x7d, 0xca, 0xda, 0xa1, 0x38, 0xc6, 0x39, 0x68, 0xd8, 0xbd, 0x18, 0x8f, - 0x91, 0x72, 0x87, 0x4c, 0x54, 0xa9, 0x37, 0xdb, 0xc2, 0xb5, 0xf8, 0xf8, - 0x3c, 0xda, 0xf9, 0x71, 0x19, 0xc7, 0x2b, 0x03, 0x97, 0x41, 0x96, 0xd3, - 0x96, 0x99, 0x0d, 0xc2, 0xcf, 0xcf, 0xfa, 0x75, 0x48, 0xd3, 0xd9, 0x91, - 0xe4, 0x42, 0x12, 0x7d, 0x75, 0xd0, 0x86, 0xc1, 0x76, 0x05, 0xf1, 0x63, - 0xdf, 0x6c, 0x07, 0x5f, 0x34, 0x40, 0x3f, 0x72, 0x1e, 0x7e, 0xa4, 0x43, - 0x0e, 0x95, 0x54, 0x1f, 0x09, 0xf6, 0x51, 0xd4, 0x6d, 0x3b, 0x17, 0x1a, - 0x10, 0xdb, 0x24, 0xcd, 0x17, 0xa5, 0xd6, 0x76, 0x48, 0xbc, 0x76, 0x5e, - 0xdf, 0x3f, 0x77, 0x33, 0xb1, 0x7a, 0xdd, 0x8f, 0x4a, 0x10, 0x74, 0xe4, - 0xd0, 0x07, 0xc7, 0xaf, 0xf5, 0xed, 0xf7, 0x97, 0x34, 0x97, 0xaf, 0xe9, - 0x6b, 0x93, 0x8e, 0xb9, 0xac, 0x44, 0xee, 0xd7, 0x1a, 0x5b, 0xc5, 0x00, - 0x90, 0x07, 0x09, 0xe5, 0x7a, 0x60, 0x17, 0xab, 0x03, 0x5a, 0x46, 0x5e, - 0x40, 0x59, 0x7d, 0x6c, 0xe3, 0xc9, 0x57, 0x01, 0x98, 0xae, 0x08, 0x3d, - 0x0f, 0xa6, 0x33, 0xad, 0xde, 0x5e, 0xd3, 0xf5, 0xe2, 0x19, 0xc8, 0x0d, - 0xfa, 0x2c, 0xae, 0xb4, 0xe5, 0x9c, 0x5e, 0x18, 0xb9, 0x34, 0x15, 0xc7, - 0x9c, 0x3c, 0xbf, 0xe0, 0xf1, 0x9a, 0x3e, 0x27, 0x20, 0x8b, 0x76, 0x02, - 0x71, 0x33, 0x7d, 0x7c, 0x42, 0x5e, 0xb2, 0x7d, 0xff, 0x43, 0x5f, 0x84, - 0xfa, 0x55, 0xd2, 0x46, 0xda, 0xcf, 0x63, 0x6e, 0xae, 0xcc, 0x38, 0x9e, - 0x0c, 0xf6, 0xc0, 0x8f, 0x7c, 0x23, 0x64, 0x1d, 0x66, 0x7c, 0x75, 0x25, - 0x54, 0x3f, 0x1f, 0x1f, 0x2b, 0x3c, 0xaf, 0xf7, 0x7e, 0xcf, 0x6b, 0x79, - 0x59, 0x82, 0xbc, 0xf4, 0x26, 0x4c, 0xe9, 0x06, 0xed, 0xa8, 0xd3, 0xd7, - 0x85, 0x38, 0x87, 0x31, 0x74, 0x1c, 0xf4, 0x98, 0xb0, 0x1d, 0x9b, 0x34, - 0x66, 0xff, 0x77, 0x61, 0xfa, 0xb6, 0x56, 0xb5, 0xaf, 0x7c, 0x5e, 0xc9, - 0xb3, 0x27, 0xdf, 0x41, 0xfd, 0xde, 0x97, 0xa9, 0x20, 0x21, 0x8d, 0xd4, - 0xf6, 0x4f, 0x59, 0xff, 0x39, 0x5d, 0xff, 0x59, 0xd4, 0x0f, 0x60, 0x4e, - 0xae, 0xbb, 0x57, 0xd1, 0xfb, 0x1c, 0xf8, 0x1e, 0x94, 0xe2, 0x8a, 0xcc, - 0x3f, 0x07, 0x99, 0xa7, 0x7c, 0x9f, 0x87, 0xbe, 0x82, 0xf8, 0x7b, 0x29, - 0xf7, 0x65, 0x19, 0x3c, 0x9d, 0x6b, 0xe0, 0x5e, 0x67, 0xc2, 0x60, 0xec, - 0x49, 0x99, 0xec, 0x90, 0xc7, 0x4b, 0x49, 0x73, 0xa2, 0x6e, 0x2d, 0x77, - 0xac, 0x5a, 0x4b, 0xca, 0x80, 0xaa, 0x9f, 0x62, 0xfd, 0x72, 0x9d, 0x0c, - 0xcc, 0xcf, 0x5e, 0xaf, 0x1d, 0x65, 0x80, 0xed, 0xd6, 0xc3, 0xe9, 0xdc, - 0x1b, 0x74, 0xdd, 0x45, 0x87, 0xfb, 0xb8, 0x8d, 0x52, 0x50, 0x32, 0x16, - 0x90, 0xa2, 0x43, 0xbd, 0xca, 0x26, 0x42, 0x62, 0x01, 0x2b, 0x7d, 0x10, - 0x74, 0x66, 0x52, 0x61, 0xf1, 0xf6, 0x12, 0xc6, 0xb1, 0x06, 0x4b, 0xa6, - 0xeb, 0x5e, 0xb2, 0x45, 0xca, 0x88, 0x3d, 0x17, 0x91, 0x16, 0x2b, 0xd0, - 0xd9, 0x68, 0x08, 0x36, 0xc0, 0x97, 0xf1, 0x88, 0xcc, 0xa1, 0xce, 0x3c, - 0xde, 0x3d, 0x5e, 0xf1, 0x25, 0xc6, 0x75, 0x0d, 0xf0, 0x68, 0x8f, 0xfd, - 0xff, 0xdc, 0x7c, 0xac, 0xbe, 0xae, 0x8f, 0x89, 0x89, 0x65, 0x89, 0x4d, - 0x89, 0x29, 0xf9, 0x8e, 0x38, 0xf1, 0x20, 0x68, 0xa1, 0xce, 0xb6, 0x48, - 0x24, 0x6d, 0xc5, 0x87, 0xc5, 0xf7, 0xfd, 0x97, 0x21, 0x4b, 0x05, 0xb7, - 0xd1, 0xee, 0x90, 0x67, 0x20, 0x37, 0xe7, 0x57, 0x70, 0x4c, 0x02, 0x72, - 0x44, 0x3f, 0xea, 0xca, 0x39, 0xc7, 0x4e, 0x7c, 0x0e, 0xe9, 0xb7, 0x9d, - 0xdf, 0x22, 0xdf, 0x9e, 0x10, 0xe9, 0x43, 0x2c, 0x04, 0xbb, 0x3e, 0xe3, - 0x63, 0xfb, 0x16, 0xc6, 0x64, 0x5a, 0x96, 0xae, 0xa0, 0x4f, 0xcb, 0x34, - 0x00, 0x6a, 0xef, 0x42, 0x3d, 0x4f, 0x37, 0xfc, 0xb2, 0x83, 0xa8, 0x4b, - 0x1a, 0x18, 0x2f, 0x7f, 0x07, 0x3a, 0xeb, 0xba, 0xf7, 0x39, 0x8b, 0x75, - 0xb6, 0xe6, 0x39, 0xac, 0xbf, 0x92, 0xf3, 0xfe, 0x56, 0xe1, 0xfe, 0xaa, - 0xf4, 0xb5, 0xa9, 0x78, 0x8e, 0xcf, 0x90, 0xf7, 0x7e, 0x62, 0xa1, 0x84, - 0xc2, 0x9a, 0xc4, 0x0d, 0xe7, 0xc1, 0xfb, 0x4f, 0x2a, 0x4c, 0x43, 0xfc, - 0x06, 0xfa, 0x4b, 0xc4, 0x14, 0x1e, 0x96, 0xf6, 0x70, 0x1d, 0xb1, 0x45, - 0x0a, 0x6b, 0xe3, 0xe3, 0x0b, 0xb6, 0x65, 0x3d, 0xb6, 0xad, 0x5f, 0x3f, - 0xd6, 0xd9, 0x14, 0xc8, 0x1d, 0xa3, 0x3c, 0xd3, 0x3f, 0xb6, 0xca, 0xbe, - 0x54, 0x23, 0xf8, 0xde, 0xa6, 0xfd, 0xf8, 0xfb, 0x80, 0xd9, 0x80, 0xbd, - 0x4d, 0xcb, 0xa9, 0xd9, 0x9e, 0xf7, 0xa0, 0xec, 0x17, 0xe0, 0x3f, 0xcb, - 0xf6, 0x37, 0x78, 0x7e, 0xf2, 0x61, 0xe8, 0xf2, 0xdc, 0x26, 0x6f, 0xef, - 0x8a, 0xeb, 0xe0, 0xe3, 0x04, 0x1f, 0xf7, 0x99, 0x1a, 0xef, 0x73, 0x6d, - 0xbc, 0x7d, 0x2e, 0x43, 0xd5, 0x65, 0xac, 0x55, 0x1f, 0x5b, 0x52, 0x87, - 0x5d, 0xf7, 0x9c, 0xe3, 0xe3, 0xc8, 0xed, 0xf0, 0xa1, 0x21, 0xcd, 0xeb, - 0x66, 0xf0, 0x9a, 0x18, 0x25, 0x22, 0x89, 0x36, 0x62, 0x8a, 0x07, 0x1b, - 0x6a, 0x58, 0xe6, 0x6f, 0xdc, 0xa0, 0xcd, 0x78, 0x8f, 0x38, 0x86, 0xb4, - 0x6f, 0xd7, 0x78, 0x86, 0xd8, 0xe6, 0x31, 0x8c, 0x11, 0x94, 0x44, 0x3b, - 0xf3, 0x7f, 0xa9, 0xdb, 0xf0, 0xd9, 0x95, 0xee, 0xad, 0xf5, 0xf2, 0x3c, - 0x00, 0x3a, 0x39, 0x1f, 0x7f, 0xef, 0xb5, 0x43, 0xd9, 0x93, 0x9a, 0x5c, - 0xf8, 0x34, 0xf9, 0xe3, 0x92, 0xb6, 0xb8, 0xb4, 0x81, 0xb6, 0x7b, 0xe0, - 0x53, 0xb6, 0xb6, 0xb1, 0x4f, 0x7f, 0xec, 0x7a, 0x9a, 0xea, 0xf1, 0x55, - 0x02, 0x63, 0x34, 0xca, 0xd6, 0x76, 0xf2, 0xae, 0x43, 0xf9, 0x96, 0xda, - 0x7a, 0xd0, 0xf7, 0x73, 0xec, 0xb5, 0xe5, 0xef, 0xad, 0xa3, 0x6b, 0x2d, - 0xe6, 0xdb, 0x86, 0x77, 0xa4, 0xc9, 0x84, 0x5d, 0x72, 0x65, 0x87, 0xe3, - 0xe3, 0xbb, 0x7a, 0x3a, 0x88, 0xf1, 0x48, 0x33, 0x69, 0xf0, 0x31, 0x39, - 0x7f, 0x5c, 0x1b, 0xd2, 0x93, 0xd6, 0xe7, 0x44, 0xfb, 0xf5, 0xbc, 0x6e, - 0xd3, 0x75, 0x92, 0x68, 0xfb, 0xc7, 0x98, 0x03, 0x9f, 0x39, 0x0f, 0x1f, - 0x1b, 0x26, 0xbd, 0x7e, 0xa2, 0xeb, 0xc5, 0x00, 0xd4, 0x19, 0x9f, 0x4f, - 0x6d, 0x7a, 0x8d, 0xb6, 0xaf, 0x19, 0xd7, 0x72, 0x56, 0xdb, 0x91, 0xf7, - 0xd4, 0xcd, 0xaf, 0x4f, 0x0a, 0xf3, 0x94, 0x8b, 0x77, 0x21, 0xf5, 0x63, - 0xa3, 0x7e, 0xf8, 0x91, 0x0c, 0x62, 0x21, 0xc6, 0x48, 0xd7, 0xc4, 0x47, - 0x3c, 0x47, 0x1c, 0xcb, 0x23, 0x5e, 0x56, 0x7e, 0xc4, 0xf3, 0x91, 0xc8, - 0xc3, 0x9e, 0x54, 0xef, 0xa5, 0x8c, 0x8d, 0x8d, 0x57, 0x9c, 0xb1, 0xbd, - 0x95, 0xfe, 0x31, 0xc6, 0x11, 0x9e, 0xcc, 0xa1, 0x7e, 0x45, 0xc6, 0x0d, - 0xb4, 0xcb, 0xaa, 0x76, 0x6a, 0x1f, 0x68, 0x9d, 0x7e, 0x84, 0xfa, 0x38, - 0xee, 0x8d, 0x15, 0x19, 0xcb, 0xc1, 0x06, 0xcd, 0xcf, 0xc0, 0xc7, 0xd9, - 0x56, 0x86, 0x72, 0xb9, 0xc7, 0xb1, 0x86, 0x95, 0xec, 0xc5, 0xac, 0x51, - 0xae, 0x65, 0x79, 0xe6, 0x1d, 0xb0, 0xa1, 0xae, 0xdc, 0x0d, 0x5b, 0xf8, - 0x10, 0x64, 0x55, 0xce, 0xc0, 0x10, 0x9e, 0x81, 0xf1, 0x3a, 0x13, 0x13, - 0xe3, 0x78, 0x87, 0x84, 0x8f, 0xc4, 0x25, 0x74, 0x84, 0xb1, 0x58, 0xd2, - 0xbc, 0x5b, 0x04, 0x3e, 0xf1, 0xc5, 0xdb, 0x0d, 0xb1, 0x06, 0x32, 0x92, - 0x44, 0x3c, 0xd9, 0x6b, 0x96, 0x91, 0x16, 0x25, 0x99, 0x3a, 0x8d, 0xbe, - 0xc2, 0x67, 0x50, 0x17, 0xed, 0x9a, 0x16, 0x13, 0xf8, 0xb5, 0x4b, 0x74, - 0xd1, 0xd3, 0x95, 0xe8, 0xe2, 0xea, 0x3d, 0x94, 0xc1, 0x95, 0x3d, 0x14, - 0xbe, 0x7f, 0x43, 0xef, 0xfd, 0x3c, 0xab, 0xe3, 0x1a, 0xca, 0x08, 0x7d, - 0x9b, 0x8a, 0xcd, 0x60, 0xc7, 0x9f, 0x45, 0x2c, 0x6c, 0x4b, 0xae, 0x04, - 0xcc, 0x9e, 0x76, 0xe5, 0x29, 0xa7, 0xe0, 0x66, 0xfb, 0x5d, 0xb9, 0xec, - 0xd8, 0x85, 0xbc, 0x58, 0x6f, 0xd0, 0xde, 0xfd, 0x4f, 0xe7, 0xfd, 0xb2, - 0xab, 0xd5, 0xda, 0x95, 0x09, 0x14, 0xdc, 0x66, 0x3b, 0x2a, 0x37, 0xa5, - 0x0f, 0xca, 0x9e, 0x2d, 0x4b, 0x66, 0x50, 0x32, 0x37, 0x01, 0x17, 0xc6, - 0xf3, 0xca, 0x56, 0xbd, 0xa6, 0xe2, 0xeb, 0x07, 0xba, 0x0e, 0xca, 0xc6, - 0x2d, 0x96, 0x79, 0x35, 0x48, 0xcc, 0x76, 0x10, 0xb1, 0x80, 0x15, 0xcf, - 0x05, 0x6d, 0x73, 0xa7, 0x58, 0xc3, 0x9f, 0x16, 0x9e, 0xdb, 0xda, 0xd2, - 0x79, 0xc4, 0x8e, 0x7f, 0x22, 0xd0, 0xbd, 0xff, 0x13, 0x8c, 0xef, 0xce, - 0x30, 0xef, 0x4a, 0x64, 0x8b, 0x89, 0xe7, 0x98, 0x74, 0x1e, 0x4f, 0x48, - 0x12, 0x7c, 0xe9, 0x51, 0x3c, 0xe1, 0xf9, 0x51, 0x5c, 0xba, 0x8f, 0x10, - 0x43, 0x29, 0xde, 0xf4, 0x80, 0x37, 0x29, 0xf0, 0x06, 0x31, 0x55, 0xaf, - 0x79, 0x15, 0xe9, 0xb2, 0x24, 0x07, 0x7e, 0x00, 0xde, 0xf4, 0x80, 0x37, - 0xdd, 0x67, 0x12, 0x68, 0x8f, 0x3e, 0x16, 0x3b, 0x91, 0x46, 0xe5, 0x83, - 0x37, 0xb4, 0xe3, 0xd9, 0x96, 0xe4, 0x91, 0x08, 0xc6, 0x08, 0xc8, 0x8e, - 0xae, 0x82, 0x0c, 0x6d, 0x41, 0x6c, 0x16, 0x3b, 0x28, 0x17, 0xe1, 0x87, - 0x4a, 0x88, 0x11, 0x9e, 0x1a, 0xb0, 0x46, 0x97, 0x60, 0x4b, 0xab, 0xf7, - 0xb8, 0xf2, 0xf2, 0x96, 0xbf, 0x70, 0xe3, 0x37, 0x58, 0xbb, 0x24, 0xd0, - 0x2f, 0x93, 0x25, 0xe5, 0x1f, 0xe2, 0xd9, 0xa0, 0xc2, 0x65, 0x98, 0x63, - 0x01, 0x3e, 0x86, 0xe7, 0xd1, 0x36, 0x6c, 0xfd, 0xa7, 0xe5, 0xa1, 0xb9, - 0x09, 0xfc, 0x10, 0x6f, 0x4e, 0xb1, 0xee, 0x7e, 0xc4, 0x73, 0x0f, 0xcb, - 0xbe, 0x29, 0x60, 0xc7, 0x34, 0xe8, 0xee, 0xb7, 0x11, 0xcf, 0xcd, 0x37, - 0x4a, 0x0b, 0xca, 0xc0, 0xdb, 0xd1, 0xea, 0xda, 0x38, 0x6e, 0x09, 0xeb, - 0x30, 0x20, 0x7f, 0x56, 0xed, 0x97, 0xaf, 0x55, 0xfb, 0xe4, 0x4f, 0xe0, - 0x5b, 0xce, 0x57, 0x3b, 0xa0, 0x2b, 0x71, 0xac, 0x49, 0x1a, 0xeb, 0xe3, - 0xc8, 0x73, 0xd5, 0x94, 0x3c, 0x0b, 0x5e, 0x3d, 0x83, 0xdf, 0x50, 0x29, - 0x25, 0x3b, 0x4a, 0x7d, 0x7a, 0x8d, 0xb8, 0x3e, 0x36, 0xe8, 0xb1, 0x31, - 0x77, 0xeb, 0xc9, 0x02, 0xf4, 0x6f, 0xbe, 0x6a, 0xbf, 0x5e, 0x96, 0x8f, - 0x37, 0x72, 0x8f, 0xf7, 0xd4, 0x8a, 0x7f, 0x29, 0xb8, 0xa6, 0x6d, 0x1d, - 0x1e, 0xc7, 0x3a, 0x94, 0xa1, 0xa7, 0xa3, 0x8a, 0xf7, 0x35, 0xdf, 0x53, - 0xf6, 0x7c, 0x8f, 0x3f, 0xbf, 0x99, 0xbc, 0x7c, 0x5b, 0xb2, 0x47, 0x27, - 0x65, 0xcf, 0x31, 0x57, 0x3e, 0xec, 0xb8, 0x90, 0x63, 0xda, 0xe2, 0x7e, - 0xda, 0xf8, 0xc4, 0x78, 0xd0, 0x50, 0xb1, 0x94, 0x87, 0x5b, 0x7a, 0x37, - 0x43, 0x67, 0x53, 0x19, 0x63, 0x42, 0x92, 0x47, 0x27, 0xa4, 0xf3, 0x28, - 0x64, 0xc1, 0x61, 0x5f, 0x4b, 0xa6, 0x71, 0x8d, 0x3c, 0x70, 0x1c, 0x6b, - 0x20, 0x27, 0xb6, 0xf9, 0xba, 0xa4, 0x30, 0xfe, 0x01, 0xe9, 0x42, 0x1b, - 0x1b, 0x6d, 0xae, 0xaa, 0xb1, 0x9b, 0x31, 0x76, 0xa3, 0x1c, 0x8a, 0x59, - 0x90, 0x35, 0xfa, 0xf0, 0xff, 0x25, 0xd9, 0x32, 0xd3, 0x9f, 0x4a, 0xf6, - 0xd4, 0x47, 0x23, 0x12, 0xe5, 0x33, 0x4c, 0xc3, 0x09, 0x96, 0x77, 0x22, - 0x65, 0xb9, 0x8d, 0x38, 0xfa, 0xe7, 0x92, 0x3d, 0xcb, 0xb1, 0x5f, 0x47, - 0xf9, 0xcb, 0x92, 0x9d, 0xfe, 0x05, 0xf2, 0x17, 0x91, 0xbe, 0x81, 0x74, - 0x54, 0x3a, 0xa7, 0x25, 0x90, 0x3d, 0xfb, 0x2d, 0xe4, 0x43, 0x48, 0x0f, - 0xa1, 0xde, 0x76, 0xd0, 0xf7, 0xa7, 0xe8, 0x2f, 0x03, 0x9b, 0xf7, 0x3b, - 0x9a, 0x7e, 0x96, 0xb3, 0x8c, 0xef, 0x0e, 0xc1, 0xa6, 0xfd, 0x67, 0xd8, - 0x34, 0xfd, 0x3c, 0xcf, 0x3c, 0x6d, 0x1b, 0x9f, 0x27, 0xc0, 0x93, 0x03, - 0xc8, 0xbb, 0xf2, 0xb0, 0x43, 0x7f, 0xb3, 0x4d, 0xc6, 0xcc, 0x82, 0x1b, - 0x05, 0xae, 0x68, 0x86, 0x1e, 0x4c, 0x6c, 0x5d, 0x5f, 0x0f, 0x0e, 0x77, - 0x1f, 0x94, 0xa6, 0x2d, 0xfe, 0xfc, 0xfd, 0xf9, 0xda, 0xe6, 0x4f, 0x14, - 0x1f, 0xac, 0xc2, 0x27, 0x84, 0xf3, 0xb0, 0xe3, 0x5f, 0x30, 0xba, 0x77, - 0x3d, 0x04, 0x3d, 0x30, 0xce, 0x32, 0xef, 0xe9, 0x81, 0x71, 0x16, 0xb6, - 0xe1, 0x04, 0x62, 0xc4, 0x13, 0x1d, 0xd2, 0x38, 0x5d, 0xd3, 0x83, 0x86, - 0xe9, 0x5f, 0xad, 0x07, 0x8d, 0x67, 0x51, 0xef, 0x2c, 0x79, 0x86, 0x3e, - 0x4e, 0x91, 0x67, 0xed, 0x48, 0x3f, 0x8d, 0xb9, 0x92, 0xf6, 0x46, 0xd0, - 0xee, 0xe1, 0xa2, 0xdb, 0x21, 0xef, 0x0f, 0x6c, 0x39, 0xa0, 0xcb, 0xff, - 0xd2, 0x1d, 0x8e, 0x59, 0x73, 0x12, 0x20, 0x4f, 0x51, 0xb7, 0x4c, 0x1e, - 0xde, 0xdc, 0x24, 0xd1, 0xfd, 0xd2, 0x49, 0xfe, 0x95, 0x77, 0x22, 0x5f, - 0x70, 0xc3, 0x76, 0xb3, 0xe6, 0x27, 0x70, 0x52, 0x3f, 0xcb, 0x5f, 0x85, - 0xcc, 0x10, 0xaf, 0xbe, 0x26, 0x7b, 0xa6, 0x5c, 0x19, 0x73, 0x38, 0xff, - 0xef, 0x63, 0xfe, 0x99, 0x2d, 0x31, 0x59, 0x4a, 0xc4, 0xc0, 0x93, 0x79, - 0xd8, 0xf6, 0x8b, 0xe2, 0xf1, 0x81, 0xe7, 0x02, 0x3b, 0xc4, 0x8e, 0x0f, - 0x89, 0x9d, 0xfa, 0x01, 0xf8, 0x30, 0x04, 0xd9, 0xcf, 0x55, 0x29, 0x3b, - 0xaf, 0xc8, 0x20, 0x64, 0xe2, 0x7b, 0x8e, 0x95, 0x02, 0x16, 0x82, 0xbd, - 0xa0, 0x5c, 0x50, 0x26, 0x5a, 0x94, 0x4d, 0x3a, 0xe1, 0x58, 0x4f, 0x94, - 0xe5, 0x56, 0x39, 0xd1, 0x46, 0xda, 0xf1, 0x6e, 0x5a, 0xf9, 0x8b, 0xd4, - 0xb8, 0xd1, 0x05, 0x1b, 0x9d, 0x12, 0xb3, 0xbb, 0xd8, 0xe8, 0xdf, 0x21, - 0xc9, 0x1f, 0x0d, 0xc8, 0x44, 0x37, 0xd7, 0x8a, 0xfd, 0x22, 0x5f, 0x2e, - 0xb8, 0x21, 0xfb, 0x75, 0xf7, 0x64, 0x7b, 0x42, 0x3e, 0xd9, 0xbd, 0x22, - 0x97, 0x73, 0x22, 0x9e, 0x5e, 0x0c, 0xaa, 0xf5, 0xf0, 0xe9, 0xf6, 0xe7, - 0xe2, 0xbf, 0xeb, 0xab, 0x7b, 0xc7, 0xb9, 0x50, 0xd6, 0x57, 0x74, 0x27, - 0x71, 0x2d, 0xad, 0xaf, 0x41, 0x9e, 0xac, 0x27, 0x8a, 0x72, 0x19, 0xb2, - 0x07, 0x1e, 0x9e, 0x65, 0x4a, 0x1e, 0x4e, 0x40, 0xee, 0x5f, 0x95, 0x1d, - 0x47, 0xa9, 0x33, 0xaf, 0x62, 0xae, 0xca, 0x96, 0xc0, 0x46, 0xb0, 0x3f, - 0x57, 0x26, 0x9d, 0xae, 0xd4, 0x29, 0xb9, 0x35, 0xbe, 0x17, 0x31, 0xe7, - 0xb8, 0xe9, 0xca, 0xa2, 0x53, 0x90, 0xc5, 0x01, 0xb4, 0x29, 0x7f, 0x1a, - 0xbf, 0x4f, 0xe9, 0xb9, 0x3d, 0x0a, 0xbe, 0x5b, 0x89, 0x39, 0xe3, 0xf7, - 0xc1, 0xf7, 0x87, 0x25, 0x39, 0xbd, 0x62, 0x6b, 0x20, 0x77, 0x9e, 0xad, - 0x49, 0x9e, 0x35, 0xa5, 0x5c, 0xb2, 0xe5, 0x23, 0xb4, 0x21, 0x25, 0xce, - 0x0b, 0x36, 0x86, 0x67, 0xec, 0x25, 0xd8, 0x99, 0x12, 0x6c, 0x0a, 0x6c, - 0xc8, 0x9f, 0xa0, 0xfc, 0x59, 0xd4, 0x79, 0x06, 0xf1, 0xd3, 0x79, 0x60, - 0xbf, 0x73, 0xc0, 0x14, 0x4f, 0x97, 0x32, 0x3a, 0x96, 0x55, 0xf3, 0x85, - 0xcf, 0x52, 0xb1, 0x8f, 0x94, 0xe7, 0xd4, 0x7d, 0x1e, 0xb5, 0xb6, 0x59, - 0x67, 0x13, 0x71, 0x16, 0x28, 0x13, 0x99, 0x9b, 0xf3, 0x79, 0x42, 0xdb, - 0xc7, 0xf3, 0x19, 0xdf, 0x56, 0x36, 0xaf, 0xb1, 0x95, 0x22, 0x2f, 0x56, - 0x3c, 0x3c, 0x49, 0x7c, 0x5c, 0x9c, 0x4a, 0xac, 0x9c, 0x63, 0x16, 0xe1, - 0x37, 0x97, 0x11, 0x67, 0x44, 0xd2, 0xdf, 0x94, 0xc8, 0x71, 0xd7, 0xfd, - 0x21, 0xfc, 0x66, 0x01, 0x6b, 0x62, 0x04, 0x50, 0xbe, 0xc0, 0x77, 0x94, - 0x7b, 0xca, 0x76, 0x80, 0xe7, 0x19, 0xf2, 0x12, 0xca, 0xca, 0x2a, 0xfe, - 0xfa, 0x16, 0xe8, 0xd1, 0xf4, 0xa9, 0x32, 0xd6, 0x6b, 0x94, 0xdc, 0x58, - 0x0a, 0x31, 0x4e, 0xaf, 0xd9, 0x88, 0xf6, 0x73, 0x0b, 0x6c, 0x63, 0x0d, - 0xf0, 0x3a, 0xd5, 0x4b, 0x0b, 0x2c, 0xef, 0x90, 0x8b, 0x88, 0x45, 0x49, - 0x43, 0x79, 0x36, 0x2d, 0xde, 0xde, 0x31, 0xed, 0x15, 0x69, 0x45, 0x1e, - 0xfc, 0xca, 0x96, 0xe8, 0x67, 0x43, 0x52, 0x88, 0x93, 0xd7, 0x71, 0x59, - 0x9e, 0xfa, 0x4c, 0x13, 0xf7, 0x66, 0xb3, 0x36, 0x9f, 0xfd, 0xbd, 0x0e, - 0xf3, 0x2d, 0xec, 0x75, 0x70, 0x7f, 0x23, 0x04, 0x5f, 0xa6, 0xf6, 0x3c, - 0x90, 0x26, 0xea, 0xe2, 0x5f, 0xbe, 0xf7, 0xb0, 0x51, 0x0d, 0x3f, 0x12, - 0x4f, 0x72, 0xbe, 0x56, 0x61, 0x09, 0xf6, 0xa3, 0x2d, 0x7d, 0x49, 0xee, - 0x3d, 0xe1, 0xcd, 0xcf, 0x38, 0x25, 0xbc, 0x4b, 0x23, 0x57, 0x67, 0x2d, - 0xe7, 0x0a, 0x30, 0x45, 0x2e, 0xe6, 0x60, 0xbd, 0x46, 0x9b, 0x60, 0xbf, - 0x06, 0x32, 0xc6, 0x99, 0x26, 0x0f, 0x9f, 0x85, 0x64, 0x62, 0x8a, 0xe7, - 0x9e, 0xb0, 0x6d, 0xc0, 0x90, 0xbf, 0x1b, 0xc2, 0x73, 0x85, 0x79, 0xc4, - 0xa4, 0x5e, 0x3c, 0x8b, 0x67, 0xaf, 0x3f, 0xf2, 0xdc, 0x38, 0xc1, 0xb9, - 0x07, 0xe4, 0x5e, 0xa0, 0x13, 0x41, 0xff, 0x9d, 0x7a, 0xac, 0xce, 0x53, - 0x29, 0xee, 0x65, 0x4b, 0x12, 0xf6, 0x22, 0x8b, 0x58, 0x32, 0x17, 0xeb, - 0xd0, 0xd8, 0x9c, 0xef, 0xd6, 0x62, 0x4f, 0x3f, 0xc6, 0x4b, 0xc9, 0xe7, - 0x4b, 0x3e, 0xd6, 0x4b, 0xc1, 0xc7, 0x4a, 0x68, 0xb8, 0xc7, 0x95, 0x1f, - 0x3a, 0xe4, 0x57, 0x1f, 0xf2, 0x8e, 0x1c, 0xae, 0xfe, 0xb2, 0xf3, 0xcd, - 0xfa, 0xbf, 0x66, 0xd0, 0xc8, 0x1f, 0xe8, 0x03, 0x3e, 0x22, 0xed, 0x06, - 0xfc, 0x79, 0x11, 0xb8, 0xcb, 0x38, 0xd3, 0xa1, 0xde, 0x19, 0xc0, 0x06, - 0xe5, 0x29, 0xd8, 0xc6, 0x33, 0x3c, 0xf3, 0x85, 0x6d, 0x3b, 0x13, 0x96, - 0xe2, 0x0c, 0xe5, 0x52, 0xda, 0x0c, 0xac, 0x17, 0xeb, 0x97, 0xa7, 0x3a, - 0x90, 0x36, 0x23, 0x4d, 0xa8, 0x7e, 0xca, 0x53, 0xb6, 0x6a, 0x5f, 0x9e, - 0x4a, 0xa9, 0x76, 0xe5, 0xa9, 0x3e, 0xa4, 0x8e, 0x34, 0x9c, 0x41, 0xe0, - 0x74, 0xa6, 0x5b, 0x26, 0x4e, 0xc2, 0xbf, 0xf4, 0x1b, 0xea, 0xbe, 0xc4, - 0x38, 0xfc, 0x4f, 0x08, 0x51, 0xd6, 0x15, 0x73, 0x00, 0x18, 0x6b, 0x1b, - 0x30, 0xc8, 0x36, 0xb1, 0x8f, 0x73, 0xfe, 0xb4, 0xbd, 0xcb, 0xdc, 0xff, - 0x8a, 0x3f, 0x28, 0x19, 0xd9, 0x37, 0xd3, 0x08, 0x7d, 0x0d, 0x99, 0x45, - 0xe9, 0x32, 0x87, 0x90, 0xcf, 0xcf, 0x91, 0x6f, 0xf7, 0xab, 0xd8, 0x2d, - 0xeb, 0xc4, 0xa2, 0x12, 0x4d, 0x63, 0x8c, 0xb7, 0xd2, 0xbe, 0x07, 0xf2, - 0x67, 0xeb, 0x3e, 0xd2, 0xa0, 0xa7, 0x9e, 0x1f, 0x3c, 0xeb, 0xcd, 0xfc, - 0x8a, 0xb3, 0x5e, 0xca, 0x35, 0xf9, 0x7b, 0xbf, 0x2c, 0xdb, 0x69, 0x79, - 0xc9, 0x4e, 0xc9, 0x45, 0x7b, 0xab, 0xfc, 0x39, 0xfc, 0xf4, 0x25, 0x7b, - 0xba, 0x89, 0x58, 0xa0, 0xac, 0xce, 0xcf, 0xfc, 0xb5, 0xb2, 0xf5, 0x3e, - 0xfa, 0x8f, 0x64, 0x71, 0x8a, 0xd8, 0xd9, 0xdd, 0xbe, 0xc7, 0x29, 0xd0, - 0x6f, 0x81, 0x06, 0x62, 0xb5, 0x02, 0xfc, 0xdf, 0x41, 0x19, 0x72, 0xe8, - 0xf7, 0x94, 0x8f, 0x8a, 0x0f, 0x79, 0xfa, 0xec, 0xe4, 0x61, 0x57, 0x97, - 0x67, 0xa0, 0x4f, 0x42, 0xf9, 0xc7, 0xf3, 0x1c, 0xd7, 0xdd, 0x96, 0x2f, - 0x94, 0x38, 0xcf, 0xe2, 0xe6, 0xa8, 0x04, 0x65, 0x58, 0xe1, 0x85, 0x16, - 0x79, 0x71, 0x61, 0x83, 0x18, 0xf0, 0x50, 0xc6, 0x2d, 0x61, 0x75, 0xd3, - 0x84, 0xf1, 0xb7, 0xb4, 0xf2, 0xbe, 0xd8, 0x87, 0xc1, 0x1b, 0xee, 0x05, - 0x60, 0x6e, 0xad, 0x9c, 0x89, 0x9f, 0xef, 0x83, 0x7e, 0xf1, 0x39, 0x20, - 0x39, 0x3b, 0x86, 0x67, 0xa6, 0xd4, 0x39, 0xee, 0x93, 0x05, 0xc5, 0xc3, - 0xdc, 0xe3, 0xea, 0x7d, 0xa3, 0x7d, 0x07, 0x70, 0x1d, 0xe5, 0x15, 0xe9, - 0xa2, 0x37, 0x6e, 0x0e, 0x38, 0x2e, 0xdf, 0xd7, 0xa4, 0xce, 0xff, 0x0a, - 0xd0, 0x85, 0x71, 0x55, 0xbf, 0x5f, 0x2e, 0x4d, 0xed, 0x8f, 0x7a, 0xfa, - 0x31, 0xa0, 0x9f, 0xf9, 0x9e, 0xf1, 0x15, 0xf7, 0x4b, 0x5e, 0x19, 0x99, - 0xb4, 0xbf, 0xa1, 0xf5, 0x47, 0x02, 0x77, 0xf7, 0x00, 0x87, 0x1e, 0x69, - 0xc0, 0x5c, 0xac, 0x44, 0x22, 0x60, 0xb4, 0x1b, 0xc0, 0xf1, 0x43, 0xca, - 0xe7, 0xf6, 0xa8, 0xfd, 0xe8, 0x53, 0xa9, 0x16, 0x29, 0x9b, 0xb6, 0xba, - 0x17, 0xb7, 0x64, 0x6e, 0x21, 0xd6, 0xc7, 0xaf, 0x09, 0x65, 0x5d, 0x48, - 0x1b, 0x91, 0xbe, 0x4b, 0x8a, 0xc7, 0xa6, 0xf5, 0x78, 0xe1, 0x35, 0xf9, - 0x3e, 0x9d, 0x7e, 0x44, 0xc7, 0x53, 0x1c, 0x27, 0x2c, 0xf6, 0x17, 0x9b, - 0xa5, 0xeb, 0x88, 0x09, 0x6c, 0x1b, 0x07, 0xd6, 0xed, 0x90, 0xd4, 0x91, - 0x84, 0xdc, 0x72, 0xc4, 0xdf, 0x73, 0xfa, 0x0f, 0x23, 0x49, 0xb5, 0xc7, - 0xf9, 0xdd, 0x11, 0x7b, 0x8e, 0xe9, 0x6b, 0xfa, 0xfe, 0xde, 0x15, 0x7d, - 0xaf, 0xef, 0x47, 0x23, 0x3d, 0x2a, 0xfd, 0x6f, 0x23, 0x29, 0x95, 0xbe, - 0x3e, 0x72, 0x4b, 0xc5, 0x8b, 0x8f, 0x8a, 0xf3, 0x29, 0xf9, 0x5c, 0x89, - 0xf8, 0xb2, 0x1f, 0xd8, 0xd1, 0x81, 0x9d, 0xe9, 0x83, 0x9d, 0x49, 0xc1, - 0xce, 0x0c, 0xd0, 0xce, 0xc0, 0x6e, 0xbf, 0x02, 0xbb, 0xed, 0xc8, 0xf7, - 0x20, 0xaf, 0x4f, 0x3b, 0x8d, 0xc0, 0x85, 0xae, 0xeb, 0xcd, 0xd5, 0x7a, - 0x62, 0x09, 0xeb, 0x5b, 0x3e, 0x2d, 0x91, 0x56, 0xd8, 0xa0, 0x2d, 0x27, - 0x1a, 0x64, 0x3e, 0xe6, 0xba, 0x47, 0x1d, 0x5b, 0xae, 0xa2, 0x7e, 0xd6, - 0xa6, 0x1e, 0xbf, 0x14, 0x65, 0x3c, 0x76, 0x75, 0x6a, 0x2b, 0x6c, 0x12, - 0xe5, 0x3d, 0x22, 0xe5, 0xb1, 0xb8, 0x2c, 0x20, 0x3e, 0xab, 0xd5, 0x49, - 0xe1, 0x99, 0xfa, 0xff, 0x5d, 0xd4, 0x4d, 0xc1, 0x3f, 0x98, 0xb2, 0xd8, - 0x93, 0x90, 0x53, 0x3d, 0xd6, 0x40, 0xc2, 0xa0, 0xed, 0x4a, 0xc8, 0x1c, - 0x62, 0xfd, 0x72, 0x89, 0xf5, 0x59, 0x0f, 0xfa, 0x59, 0xf2, 0xda, 0x4d, - 0x96, 0x7c, 0x3b, 0xd1, 0xcf, 0x7d, 0xc8, 0x50, 0xae, 0xc7, 0xf3, 0x01, - 0x86, 0xd1, 0x08, 0x39, 0x70, 0xc0, 0xff, 0x31, 0x94, 0xf7, 0xf3, 0xbe, - 0x07, 0xca, 0x88, 0x85, 0x7e, 0x1c, 0x25, 0x46, 0xcc, 0x39, 0x63, 0x28, - 0x63, 0x1b, 0x2b, 0x9e, 0x44, 0xf9, 0xa8, 0x24, 0xe3, 0x79, 0x75, 0xf7, - 0xac, 0x1d, 0x65, 0xec, 0x23, 0xa8, 0xf7, 0x63, 0xfe, 0x8f, 0x92, 0xa3, - 0xa0, 0xed, 0x97, 0xf7, 0xaa, 0xbd, 0x81, 0x8c, 0xe9, 0x40, 0x1f, 0x58, - 0x96, 0x34, 0xd9, 0x2e, 0xe7, 0x38, 0xca, 0x16, 0xde, 0x57, 0xe1, 0x19, - 0x5e, 0x44, 0xee, 0xad, 0x34, 0x4b, 0xae, 0xd2, 0x70, 0x1d, 0xfb, 0xef, - 0xeb, 0xe4, 0x72, 0xdc, 0x14, 0xde, 0x83, 0xf0, 0xf4, 0x3c, 0xb4, 0x95, - 0x3a, 0x31, 0xc0, 0x73, 0x03, 0xf8, 0x5b, 0xac, 0x05, 0xfc, 0xef, 0x39, - 0xf8, 0xdf, 0xa7, 0x4b, 0x35, 0xfb, 0xe1, 0xf9, 0x5d, 0xda, 0x80, 0x27, - 0xb1, 0x66, 0xa3, 0xc0, 0xfd, 0x3b, 0x11, 0x0f, 0x0c, 0x03, 0xfb, 0x0f, - 0x62, 0xfd, 0xd2, 0x58, 0xbb, 0x31, 0xde, 0x17, 0xc2, 0x3a, 0x0e, 0xa8, - 0x73, 0xe6, 0x19, 0x75, 0xe7, 0xe2, 0x47, 0xca, 0xf7, 0x3e, 0x5e, 0x32, - 0xe0, 0x1f, 0x0a, 0xee, 0x66, 0xdb, 0x02, 0xfe, 0x5b, 0xd1, 0xe7, 0x81, - 0x17, 0x61, 0x57, 0x7e, 0x06, 0xba, 0xce, 0xcf, 0xd0, 0x9f, 0xa3, 0x8e, - 0x87, 0xb7, 0x1d, 0xee, 0x75, 0x41, 0x9f, 0x0f, 0x2f, 0xcb, 0x12, 0x70, - 0x47, 0x86, 0x72, 0x8c, 0xf8, 0xc1, 0x7a, 0x7a, 0x4e, 0xba, 0x69, 0x03, - 0xe7, 0xa8, 0x2b, 0xfd, 0xd3, 0x71, 0x60, 0x3d, 0x20, 0x79, 0x75, 0xae, - 0x8a, 0xe7, 0xb3, 0x1b, 0xc5, 0x20, 0xde, 0x73, 0x6e, 0x40, 0x19, 0xed, - 0x86, 0x8f, 0x91, 0x96, 0x06, 0xda, 0x24, 0xb3, 0xa5, 0x4d, 0xd9, 0x0e, - 0xcb, 0x79, 0x09, 0xe3, 0xee, 0x90, 0x46, 0x60, 0xb8, 0x02, 0xc6, 0x38, - 0x20, 0xff, 0xd5, 0xe1, 0x1e, 0x95, 0x17, 0xfb, 0x81, 0x96, 0x08, 0x78, - 0xd6, 0xb4, 0xc7, 0x36, 0x23, 0x3b, 0xaa, 0xec, 0x3f, 0xa2, 0x30, 0x56, - 0x4e, 0xd8, 0x3f, 0xfc, 0x04, 0xc6, 0x4c, 0x4e, 0x53, 0xf6, 0x7b, 0xb1, - 0x6e, 0xbf, 0x0d, 0x0c, 0x44, 0xae, 0x7e, 0x75, 0x83, 0xa7, 0x2f, 0xa4, - 0x7f, 0x89, 0x78, 0x82, 0x67, 0x00, 0x5e, 0x5c, 0xbe, 0x42, 0x5b, 0x3f, - 0xe8, 0x9d, 0xdd, 0xe0, 0x9f, 0x25, 0x77, 0x4e, 0x7b, 0xfe, 0xba, 0xf3, - 0x2c, 0x5a, 0x1d, 0x95, 0x76, 0x9e, 0x4a, 0x1b, 0x72, 0x8b, 0xdc, 0x19, - 0xf2, 0xfa, 0x31, 0x4e, 0x98, 0x90, 0x55, 0xda, 0x81, 0x76, 0xc8, 0x39, - 0xf3, 0xb4, 0x29, 0xb4, 0x09, 0x94, 0x05, 0x5b, 0x8a, 0x55, 0xd8, 0x84, - 0x96, 0x0e, 0x99, 0x23, 0xcf, 0x4e, 0xd0, 0x4e, 0xfc, 0x48, 0x26, 0xd7, - 0xd8, 0xca, 0x41, 0xf1, 0xe3, 0xda, 0x66, 0x09, 0xa7, 0x6d, 0xf3, 0x3e, - 0x35, 0x47, 0xcf, 0x5e, 0xee, 0x23, 0xfe, 0x9c, 0xc9, 0x58, 0x6d, 0xa2, - 0xb1, 0xa7, 0xc2, 0x4f, 0xdf, 0xc7, 0x5c, 0xd9, 0x87, 0xe2, 0xd3, 0xc0, - 0xa0, 0x17, 0x0b, 0xa8, 0x3d, 0x3f, 0xe0, 0xe0, 0xf8, 0xcf, 0x60, 0x6b, - 0x73, 0xc4, 0x25, 0xe0, 0x73, 0xe7, 0x51, 0xca, 0xd1, 0x66, 0xda, 0x32, - 0xe0, 0xbc, 0x14, 0xed, 0xb5, 0x2c, 0x4c, 0x03, 0x73, 0x19, 0x77, 0x48, - 0x9e, 0xf2, 0xca, 0xbb, 0x0a, 0x0b, 0x86, 0x4c, 0xce, 0xb6, 0x48, 0xd7, - 0x09, 0xee, 0xaf, 0x9e, 0x8a, 0x4a, 0x0b, 0xf7, 0x58, 0xe9, 0x83, 0xfa, - 0x25, 0x87, 0xf2, 0xce, 0x13, 0x41, 0xb5, 0x1f, 0x36, 0x67, 0x90, 0x47, - 0x7d, 0xb0, 0x07, 0x56, 0x6a, 0xc9, 0xd8, 0xd6, 0xe4, 0x61, 0x48, 0xc8, - 0x52, 0x09, 0x32, 0x56, 0x82, 0x8c, 0x95, 0x20, 0x63, 0x25, 0xc8, 0x18, - 0xb0, 0xdf, 0x79, 0xe8, 0xdf, 0xb9, 0xd2, 0x80, 0xf6, 0xeb, 0xbb, 0x94, - 0x5f, 0x3f, 0x54, 0x7a, 0xc5, 0x65, 0xfa, 0xac, 0x8a, 0x4d, 0xfb, 0x20, - 0x83, 0x8c, 0x45, 0xfd, 0x18, 0xf5, 0x15, 0x79, 0x72, 0xe6, 0x55, 0x39, - 0x35, 0x53, 0xc3, 0x81, 0x13, 0x25, 0x57, 0x5e, 0x72, 0x10, 0x7f, 0xce, - 0x13, 0x53, 0x65, 0x5a, 0x1b, 0x15, 0xb6, 0x3a, 0x28, 0x79, 0x85, 0x93, - 0x95, 0x1f, 0x01, 0xbe, 0x52, 0xb8, 0x90, 0xba, 0x29, 0x6d, 0x5b, 0x2e, - 0xcb, 0x39, 0xf8, 0xf1, 0x85, 0xea, 0x6b, 0xf2, 0x8c, 0xc2, 0xe3, 0xe4, - 0xc3, 0x3b, 0xe5, 0xa7, 0xa6, 0x77, 0x9e, 0x7f, 0x0a, 0x58, 0x63, 0xa1, - 0x87, 0xb6, 0x23, 0x04, 0x5f, 0x60, 0x15, 0x3a, 0xa1, 0xd7, 0xfb, 0x8d, - 0x1b, 0x81, 0x69, 0xf8, 0x7e, 0xa3, 0xbc, 0x38, 0x53, 0xa8, 0x93, 0x09, - 0xda, 0x07, 0xeb, 0xb0, 0x18, 0xf4, 0x53, 0xf4, 0x9b, 0x9c, 0x2f, 0xfd, - 0xd4, 0x4f, 0x37, 0xf0, 0x0e, 0x57, 0xf9, 0x58, 0x6c, 0x03, 0xf7, 0x1b, - 0x63, 0x36, 0x79, 0x7a, 0x59, 0xf6, 0x57, 0x58, 0xf6, 0x2a, 0xd6, 0x87, - 0xe9, 0x0f, 0xdc, 0x7b, 0x63, 0x1c, 0x8f, 0xfd, 0x02, 0x37, 0xb5, 0x63, - 0xae, 0xa5, 0x8f, 0x68, 0xcc, 0xdd, 0xa7, 0x70, 0xf4, 0xb5, 0x78, 0x99, - 0x7c, 0x72, 0xc0, 0xa7, 0xcb, 0x6a, 0x3f, 0x70, 0x9d, 0x7d, 0xe2, 0x27, - 0xa0, 0x57, 0x85, 0x2b, 0xc2, 0x3d, 0x4b, 0xee, 0xe7, 0x72, 0xaf, 0xb8, - 0xde, 0x62, 0xa8, 0x7b, 0x03, 0x72, 0x0f, 0xec, 0xcb, 0xbd, 0xb0, 0x2f, - 0xf7, 0x5d, 0x73, 0x07, 0xda, 0x3f, 0x03, 0xe8, 0x2a, 0x04, 0x8d, 0x0e, - 0x19, 0xad, 0xd4, 0xb7, 0xe5, 0x3e, 0xee, 0x7a, 0xfb, 0xb6, 0xdc, 0xd3, - 0x4d, 0xad, 0xd9, 0x0b, 0xa4, 0x6c, 0xb8, 0x72, 0xc9, 0xe1, 0xbe, 0x9b, - 0x7f, 0x6f, 0x7e, 0x3d, 0xfc, 0x15, 0x68, 0xf6, 0xf7, 0x9c, 0x43, 0xe9, - 0x2b, 0xc2, 0xfb, 0xf3, 0xc5, 0x29, 0xe2, 0x81, 0x98, 0xba, 0x17, 0x63, - 0xa8, 0x7d, 0x3e, 0xaf, 0x6d, 0x71, 0x4a, 0x9d, 0x31, 0x15, 0xb8, 0x77, - 0x6d, 0x6e, 0xb5, 0xcc, 0xd1, 0xa0, 0x77, 0x1f, 0x93, 0xba, 0xec, 0xd9, - 0x32, 0xc8, 0x62, 0xb5, 0x76, 0xcf, 0x71, 0x50, 0xd9, 0x8b, 0x2b, 0xd0, - 0x01, 0xae, 0x17, 0xe2, 0x05, 0xe8, 0xc9, 0x04, 0xec, 0x53, 0x5e, 0xf5, - 0x17, 0xa1, 0x5c, 0x64, 0xb2, 0x41, 0x43, 0xc2, 0xc7, 0x19, 0x0b, 0x79, - 0x7b, 0x2d, 0xb9, 0xa0, 0xa5, 0xec, 0x37, 0x68, 0x07, 0x3e, 0xa3, 0x7e, - 0x26, 0xc6, 0x1b, 0xd3, 0x0d, 0xf0, 0xab, 0x58, 0xbf, 0x2a, 0xf7, 0x04, - 0xa0, 0xbb, 0x8b, 0xdf, 0x91, 0x7d, 0xb3, 0xdd, 0xcd, 0x9e, 0xfc, 0x73, - 0x1f, 0x99, 0xf3, 0xf3, 0x69, 0x58, 0xdd, 0xb7, 0x71, 0x5c, 0x22, 0x51, - 0xf8, 0xb4, 0x0f, 0x20, 0xce, 0xd8, 0x01, 0x59, 0x59, 0x8a, 0xb1, 0x5f, - 0x4f, 0x67, 0x26, 0x4b, 0xec, 0xfb, 0x3b, 0x32, 0x34, 0x5b, 0x6a, 0xa6, - 0x2f, 0x59, 0x84, 0x1d, 0x58, 0x36, 0xe9, 0x43, 0xc7, 0xe0, 0xe3, 0xda, - 0xe5, 0xfb, 0xb3, 0xf4, 0x8f, 0x49, 0xf3, 0x94, 0xf4, 0xc6, 0x4f, 0x81, - 0xa6, 0xcf, 0x3b, 0x21, 0xc6, 0x68, 0xee, 0x20, 0xca, 0xfe, 0x5c, 0x92, - 0x66, 0x67, 0x80, 0xcf, 0xbd, 0xe6, 0x17, 0x80, 0x61, 0x33, 0x66, 0xd2, - 0xbc, 0x35, 0x40, 0x39, 0x42, 0xcc, 0xbd, 0x58, 0xa3, 0xf3, 0x07, 0xb3, - 0x2a, 0x4e, 0x52, 0x76, 0x66, 0xd1, 0xe1, 0x78, 0xa0, 0x5b, 0xd9, 0xac, - 0x5b, 0x61, 0x4f, 0x22, 0xfa, 0xfc, 0x0d, 0x6d, 0x88, 0x6d, 0x9c, 0x90, - 0xce, 0x3f, 0x2a, 0xd9, 0x93, 0x31, 0xd8, 0x33, 0xf6, 0xe5, 0xc7, 0x0e, - 0xf4, 0x91, 0x3e, 0xde, 0xa6, 0xbf, 0xbb, 0x03, 0x7e, 0xef, 0x66, 0x45, - 0xcf, 0xb0, 0xd3, 0x27, 0x13, 0xc7, 0x38, 0x76, 0x0f, 0x6c, 0x79, 0x5c, - 0xc9, 0x6d, 0xb1, 0xb4, 0x1c, 0x8f, 0xc0, 0x26, 0x47, 0xb6, 0x90, 0x9f, - 0xef, 0x93, 0xbb, 0xec, 0x31, 0xb9, 0x1b, 0xb2, 0x33, 0x68, 0x3b, 0x32, - 0x84, 0xb5, 0xd8, 0x61, 0xc3, 0xef, 0x28, 0x0c, 0xdd, 0x88, 0xb8, 0x8b, - 0x63, 0xb7, 0xeb, 0xfb, 0x17, 0x1e, 0x7e, 0xfc, 0x4a, 0xd5, 0xe3, 0x51, - 0x76, 0xf6, 0x49, 0xc5, 0x9b, 0x61, 0x67, 0x9b, 0xf6, 0xb3, 0x2d, 0x92, - 0x53, 0xf5, 0xb6, 0x29, 0x7f, 0x5c, 0x5c, 0xb8, 0x1f, 0x29, 0x7c, 0xf3, - 0x02, 0xec, 0x0d, 0x30, 0x77, 0xb1, 0xb2, 0x15, 0x79, 0xf8, 0xd0, 0x85, - 0x34, 0xd2, 0xf7, 0x21, 0x65, 0xdd, 0x07, 0x9a, 0xbd, 0xbd, 0xdc, 0xb5, - 0xf7, 0xb8, 0x24, 0xf0, 0x01, 0x85, 0x4b, 0xaf, 0xa8, 0x3b, 0x80, 0x88, - 0xa1, 0x47, 0xb2, 0xb0, 0x2b, 0xcd, 0xc0, 0x40, 0x53, 0xc7, 0xad, 0xd4, - 0x50, 0x60, 0xbb, 0x7c, 0x10, 0xb1, 0x7c, 0xd9, 0xe1, 0x5a, 0x6e, 0x95, - 0x07, 0xdf, 0x4b, 0x19, 0xd9, 0x2e, 0x7b, 0xde, 0x1b, 0x90, 0x3d, 0x7d, - 0x56, 0x86, 0x74, 0xdf, 0xf2, 0x2e, 0x3f, 0x9e, 0xee, 0x1a, 0x4e, 0x06, - 0xfa, 0xe5, 0x0b, 0x90, 0xb1, 0x02, 0xe4, 0x6b, 0xa8, 0x4a, 0x9e, 0xd3, - 0xde, 0xd3, 0xce, 0xa7, 0x80, 0x95, 0x7d, 0xec, 0x67, 0xcb, 0x54, 0xb5, - 0x41, 0x12, 0x37, 0x70, 0x3f, 0x39, 0xe1, 0x9d, 0x71, 0xdc, 0x40, 0x99, - 0x40, 0x0c, 0x72, 0x83, 0xa7, 0x9f, 0xea, 0xee, 0xdd, 0x0d, 0x9e, 0x5f, - 0x41, 0xfc, 0xeb, 0x12, 0xe7, 0x79, 0x77, 0x0d, 0xbe, 0xa1, 0x6d, 0x69, - 0x68, 0xe3, 0x0a, 0xbe, 0x6b, 0x61, 0xfc, 0xf0, 0x87, 0xcd, 0xb5, 0x6f, - 0x07, 0xd6, 0xca, 0xa2, 0xbf, 0xef, 0x36, 0x87, 0x39, 0xd3, 0xa7, 0x5b, - 0x26, 0x6d, 0x61, 0xab, 0xbd, 0x4b, 0xfe, 0x0c, 0xfe, 0xfd, 0x6b, 0x2b, - 0xfe, 0x7d, 0x37, 0xf8, 0xb1, 0x16, 0x03, 0xd8, 0xe6, 0x3d, 0x98, 0xcb, - 0x30, 0xd6, 0xf3, 0x6e, 0xfc, 0xee, 0x2a, 0xad, 0xda, 0xc7, 0x9b, 0x29, - 0x00, 0x4f, 0x36, 0xd8, 0xec, 0x6f, 0xd5, 0x7e, 0x5e, 0x21, 0x2f, 0x2b, - 0x7b, 0x85, 0x03, 0x57, 0x85, 0x7e, 0xef, 0x75, 0x09, 0x77, 0xdb, 0xaf, - 0x77, 0x06, 0xec, 0xe7, 0x8d, 0x00, 0xcf, 0xc1, 0x1d, 0x39, 0x5d, 0x25, - 0x0e, 0xbb, 0x28, 0xc6, 0x59, 0x62, 0xb0, 0x97, 0xd5, 0x1e, 0x54, 0xb9, - 0xf4, 0x2d, 0xa4, 0xa8, 0x0f, 0xfb, 0x18, 0xf4, 0xf6, 0x29, 0x14, 0x56, - 0xa1, 0x9d, 0xbd, 0x1b, 0xeb, 0x30, 0x81, 0x5f, 0xe7, 0x96, 0x5b, 0xa1, - 0xbf, 0x94, 0x53, 0xee, 0x7d, 0x75, 0x9b, 0x5b, 0x02, 0x7c, 0xb7, 0xde, - 0x3e, 0xd8, 0xb7, 0x25, 0x74, 0x14, 0xbe, 0xce, 0xa0, 0x7d, 0xe0, 0x3c, - 0xe8, 0x27, 0x4d, 0x99, 0x3f, 0x46, 0x5d, 0x5f, 0xaf, 0xbe, 0x5f, 0xd7, - 0x9f, 0x8b, 0xf2, 0x1b, 0x99, 0x3c, 0xf7, 0x38, 0x4b, 0x5c, 0x03, 0x07, - 0x6b, 0xe0, 0xca, 0x71, 0xa7, 0x95, 0x36, 0x5d, 0x82, 0xc7, 0x5d, 0x19, - 0x54, 0xd8, 0xb5, 0x17, 0x98, 0x6b, 0xa3, 0xc6, 0x0d, 0x31, 0x09, 0x1d, - 0xef, 0x90, 0x46, 0xe0, 0xea, 0x86, 0x23, 0xf4, 0x91, 0xc9, 0xc4, 0x20, - 0x84, 0x20, 0xa4, 0xee, 0x93, 0x5a, 0x03, 0xdf, 0x97, 0xde, 0xc4, 0xf7, - 0x85, 0x78, 0xe9, 0x51, 0xac, 0x9f, 0xe5, 0x5c, 0x5c, 0xa7, 0x7e, 0xb1, - 0x56, 0x1f, 0x72, 0xc4, 0xbd, 0x35, 0xb6, 0xe1, 0x5e, 0x5b, 0x72, 0xe0, - 0x7b, 0xdc, 0x63, 0x43, 0xac, 0xd9, 0x70, 0xc6, 0xa3, 0xc1, 0x58, 0x6c, - 0x93, 0xf2, 0x49, 0xea, 0x28, 0xf7, 0x59, 0x4c, 0x2f, 0x4e, 0x2d, 0x31, - 0x5e, 0xe5, 0xfb, 0x84, 0x7e, 0xdf, 0xa9, 0xdf, 0x33, 0x1e, 0x2d, 0xb8, - 0x0d, 0xe0, 0xe9, 0x0e, 0xd8, 0xcf, 0xfb, 0xb7, 0xda, 0x0a, 0x37, 0xdc, - 0xbf, 0xb2, 0x66, 0x3b, 0xd5, 0xdd, 0xa2, 0x72, 0xe9, 0xa0, 0xd8, 0x5b, - 0x96, 0x52, 0x21, 0x19, 0xc5, 0x5a, 0x30, 0x9f, 0x21, 0x3d, 0xa9, 0x43, - 0xb2, 0x5f, 0xad, 0x4d, 0xf9, 0x98, 0x75, 0x38, 0x11, 0x98, 0x10, 0xa3, - 0xcc, 0xe7, 0x4f, 0x23, 0x3d, 0x04, 0xbc, 0xe3, 0xed, 0x5d, 0x1a, 0xe5, - 0xd5, 0xbc, 0x04, 0xc6, 0x30, 0x77, 0xac, 0xda, 0xc7, 0xaa, 0xed, 0x71, - 0xf1, 0xfd, 0xa0, 0x7a, 0x9f, 0x5a, 0xb5, 0xcf, 0x95, 0x33, 0x88, 0x65, - 0xfc, 0xf7, 0x5c, 0x0b, 0xae, 0x17, 0x7c, 0xf1, 0x31, 0x7f, 0xcf, 0xab, - 0x45, 0xaf, 0x0b, 0xd7, 0x67, 0x4a, 0xce, 0x99, 0xd6, 0x30, 0xe5, 0xef, - 0xb6, 0xad, 0x37, 0xc9, 0x78, 0x3b, 0xf7, 0xdb, 0xea, 0x69, 0x58, 0xbb, - 0x8f, 0x56, 0x3f, 0xfe, 0xda, 0xfd, 0x37, 0x8e, 0xed, 0xed, 0xb1, 0x65, - 0x57, 0xed, 0xb1, 0xd5, 0x8f, 0xc7, 0xb1, 0x36, 0x22, 0x7e, 0x2a, 0xb8, - 0x31, 0x9b, 0x6b, 0xd4, 0x95, 0x98, 0x65, 0xfe, 0xcb, 0x06, 0xd6, 0x31, - 0x06, 0x3f, 0xc2, 0xb5, 0xf4, 0xcf, 0x9e, 0xb9, 0xa6, 0xc9, 0xc4, 0x21, - 0x6f, 0x3d, 0x07, 0xbc, 0x75, 0xf7, 0xd6, 0xff, 0xe2, 0xca, 0x3a, 0xd2, - 0x3f, 0x70, 0x1d, 0xdb, 0x45, 0x60, 0x67, 0x8d, 0x23, 0x5c, 0x43, 0xa6, - 0x5c, 0x43, 0xbe, 0xe3, 0x1a, 0x76, 0xea, 0x77, 0x5c, 0x3f, 0xe0, 0xb4, - 0x2f, 0x02, 0x63, 0x38, 0x59, 0xf5, 0x1d, 0x54, 0x67, 0xb7, 0xaf, 0x8b, - 0x29, 0x79, 0x66, 0x3e, 0x2a, 0x66, 0xda, 0x9b, 0xd7, 0xd8, 0xaa, 0xfd, - 0x76, 0x9e, 0x5f, 0xf5, 0x11, 0x7b, 0xfa, 0xf3, 0x8a, 0x73, 0x5e, 0xfb, - 0xe5, 0xb2, 0xe4, 0xa7, 0x42, 0x88, 0x01, 0x53, 0xc0, 0x39, 0x7d, 0xb0, - 0xb7, 0xdc, 0x1f, 0x45, 0x59, 0x85, 0x78, 0x85, 0xbe, 0x2e, 0x05, 0x5d, - 0xa1, 0x0d, 0x26, 0x1e, 0x79, 0x55, 0x72, 0x73, 0xbe, 0x8d, 0x41, 0xff, - 0x86, 0xdf, 0x3f, 0xf9, 0x9c, 0xb9, 0x65, 0xb3, 0x2c, 0x25, 0x36, 0x8b, - 0x95, 0x58, 0x90, 0xda, 0xba, 0x8e, 0xad, 0xcf, 0x77, 0xe7, 0xfe, 0x60, - 0x4d, 0x36, 0xc6, 0xd6, 0x59, 0xfb, 0xbd, 0xe2, 0xbf, 0xf7, 0xd7, 0x7e, - 0xdd, 0x75, 0x28, 0xbc, 0x22, 0x5c, 0x0b, 0xf2, 0x80, 0x78, 0x38, 0x2c, - 0x9f, 0x8a, 0x51, 0x1f, 0x0b, 0xea, 0x7c, 0x33, 0x69, 0x74, 0x2b, 0x9b, - 0x31, 0xe8, 0x78, 0xf2, 0x5a, 0xc0, 0x38, 0x91, 0xae, 0x7f, 0xe1, 0x0e, - 0xc6, 0x10, 0xe7, 0x76, 0xd1, 0xbe, 0xf8, 0x3a, 0x1d, 0x55, 0x3a, 0xfd, - 0x79, 0x27, 0x20, 0x45, 0x3b, 0x20, 0x13, 0xf6, 0x41, 0x85, 0xf1, 0x3f, - 0x84, 0xbe, 0x1e, 0xd4, 0x7d, 0x4d, 0x48, 0xb7, 0xb6, 0x3f, 0x07, 0x20, - 0xe7, 0xae, 0xdc, 0xe7, 0x6c, 0x95, 0xdb, 0x5a, 0xa9, 0x03, 0xfe, 0xfc, - 0x0f, 0x4a, 0xd7, 0xd6, 0xa5, 0x04, 0x22, 0x83, 0x5b, 0xc2, 0x2b, 0x3c, - 0xa0, 0x9e, 0xf9, 0xf2, 0xed, 0xf1, 0xc1, 0x9b, 0xff, 0xaa, 0xb9, 0xea, - 0x79, 0x72, 0xce, 0xac, 0xc7, 0xb9, 0x7a, 0x58, 0xbe, 0x36, 0x57, 0xbf, - 0x7e, 0x33, 0x64, 0xc9, 0x4a, 0x48, 0xa0, 0x9e, 0x37, 0x2b, 0x36, 0x6a, - 0x98, 0x7b, 0x24, 0x4b, 0xa6, 0x95, 0x4a, 0x04, 0xfc, 0xbd, 0x68, 0x0f, - 0xeb, 0x76, 0x02, 0x87, 0xdb, 0xdd, 0xdd, 0xa9, 0xbc, 0xda, 0x23, 0x35, - 0xd4, 0xbc, 0x26, 0x80, 0xc9, 0xe6, 0x9d, 0x57, 0xdc, 0x4f, 0x02, 0xb3, - 0x8e, 0xcb, 0xc3, 0x12, 0x5c, 0xb5, 0x97, 0x8b, 0xfc, 0x59, 0xee, 0xe7, - 0x5a, 0x89, 0x0c, 0xd6, 0xf8, 0xc3, 0x88, 0xe1, 0xcb, 0xb0, 0xfb, 0x1f, - 0xa1, 0x6f, 0x28, 0xc1, 0x5f, 0x00, 0x97, 0x7c, 0xed, 0xba, 0x18, 0x7e, - 0xbc, 0x6e, 0x2f, 0xd7, 0xc3, 0xa7, 0xe7, 0x14, 0x26, 0x25, 0x6e, 0x3f, - 0x1c, 0xb8, 0xa7, 0x27, 0x88, 0x38, 0xa3, 0xe0, 0x46, 0x6c, 0xe2, 0xb8, - 0x83, 0x72, 0x17, 0xd6, 0xe7, 0xf4, 0x7c, 0x21, 0xb0, 0xa3, 0xe4, 0xcb, - 0x2a, 0xe2, 0xca, 0xaa, 0x95, 0x5a, 0x06, 0x3f, 0x9e, 0xd4, 0x98, 0x8f, - 0xe7, 0x35, 0x65, 0x1d, 0xb3, 0x70, 0x6f, 0xa8, 0x58, 0x3d, 0x28, 0x93, - 0x0e, 0xf7, 0x76, 0xba, 0xa4, 0x18, 0xcb, 0xdc, 0xd4, 0xb8, 0xc2, 0x23, - 0xcb, 0x44, 0xcc, 0x97, 0xa2, 0xfd, 0x2e, 0xeb, 0xf3, 0x8e, 0x27, 0x95, - 0x7c, 0xf9, 0xfb, 0xc2, 0x8c, 0x8f, 0x78, 0x5e, 0xd5, 0x65, 0x0e, 0xf3, - 0x79, 0x8e, 0x32, 0xa0, 0x62, 0x26, 0xf0, 0xf2, 0x21, 0xc9, 0x8c, 0x26, - 0x14, 0x6e, 0x79, 0xbc, 0x44, 0x7d, 0x21, 0xfe, 0xbf, 0x0c, 0xec, 0x1f, - 0xc2, 0x9a, 0x31, 0x0e, 0xe0, 0xd8, 0xd4, 0x0b, 0x94, 0x55, 0xcc, 0x5f, - 0xa2, 0x17, 0xdb, 0x37, 0x11, 0x63, 0x5c, 0x28, 0x7d, 0x5c, 0xf1, 0x6f, - 0x49, 0xfc, 0xbd, 0x73, 0x85, 0x05, 0x0b, 0xd9, 0x60, 0x40, 0x92, 0x47, - 0x3f, 0x03, 0x19, 0x1a, 0x41, 0x8c, 0xc4, 0x7a, 0xa2, 0xce, 0xaf, 0x06, - 0x81, 0xb9, 0x0c, 0xfb, 0x46, 0x29, 0x9a, 0x61, 0x29, 0xaa, 0x7b, 0x80, - 0x3c, 0xcf, 0x0d, 0xaa, 0xbd, 0x9d, 0xa2, 0x49, 0xcc, 0x9f, 0xd9, 0xe4, - 0xdf, 0x03, 0x2c, 0x9a, 0x6c, 0xc7, 0x3c, 0xcb, 0x27, 0x24, 0x7c, 0xf4, - 0x80, 0x34, 0x1c, 0x7d, 0x58, 0x1a, 0xa7, 0x89, 0xf1, 0xb8, 0x77, 0x6f, - 0xdc, 0xd1, 0x28, 0xc4, 0xdc, 0x5f, 0xc5, 0xd8, 0x07, 0xe5, 0x87, 0x8e, - 0x4f, 0xd3, 0x86, 0x8d, 0xd2, 0xc2, 0x3a, 0x7e, 0xde, 0xc7, 0xe3, 0x77, - 0x80, 0x1e, 0xce, 0x3f, 0xa1, 0x71, 0xdf, 0x1d, 0x75, 0xb1, 0x6b, 0x83, - 0x8e, 0x5d, 0xd9, 0xee, 0x32, 0x7c, 0xf6, 0x31, 0x09, 0xdb, 0x7e, 0xfb, - 0xed, 0xa8, 0x17, 0xaf, 0xbb, 0x03, 0xc1, 0x3a, 0xfa, 0x4e, 0x40, 0x0b, - 0x71, 0x0f, 0xcf, 0xdb, 0x59, 0xe6, 0x9d, 0xf9, 0x1b, 0xe5, 0x74, 0x70, - 0xf5, 0xf8, 0xdb, 0xea, 0xea, 0xfa, 0x65, 0x7e, 0x9b, 0xb0, 0x17, 0xf3, - 0xf7, 0x87, 0xeb, 0xda, 0x7d, 0xd7, 0xf4, 0x52, 0x2f, 0xf6, 0xf0, 0xe2, - 0x20, 0xce, 0x21, 0x55, 0x87, 0x73, 0x56, 0x7f, 0x2f, 0x9a, 0x43, 0x79, - 0x7e, 0xd6, 0xbf, 0x3b, 0x64, 0x60, 0x2e, 0x56, 0x81, 0xf1, 0x8b, 0xc9, - 0x6f, 0x33, 0x67, 0x0b, 0xa0, 0xfb, 0x66, 0x75, 0xef, 0x88, 0x77, 0x37, - 0x50, 0x2f, 0xe1, 0xe1, 0x4f, 0xe6, 0xe3, 0x58, 0xf3, 0x77, 0x75, 0x18, - 0xe9, 0xff, 0x7e, 0x53, 0xb6, 0x9f, 0xf8, 0x66, 0x13, 0xcf, 0x21, 0x81, - 0x9b, 0x29, 0x67, 0xdf, 0x81, 0x9c, 0x35, 0xaa, 0x73, 0x9f, 0x62, 0x89, - 0xf1, 0x5c, 0x1e, 0xf2, 0xc3, 0xfb, 0x7b, 0x8c, 0xfb, 0xf2, 0x7a, 0x3f, - 0x96, 0x74, 0x12, 0xd3, 0xfb, 0xf1, 0x01, 0xfb, 0x5c, 0xef, 0x9e, 0xb2, - 0x1f, 0xb3, 0x51, 0xde, 0xe2, 0x8a, 0xe6, 0xa1, 0x35, 0xf1, 0xca, 0x21, - 0xd8, 0x82, 0x79, 0xc8, 0xf3, 0x5e, 0xd8, 0xc0, 0xc1, 0x20, 0xf5, 0x33, - 0xaa, 0x63, 0x59, 0x9b, 0x71, 0x7b, 0x60, 0x14, 0x7d, 0x18, 0xd3, 0xaf, - 0xc9, 0x04, 0xec, 0xff, 0x64, 0x35, 0xa9, 0xbe, 0xe9, 0xc9, 0xc4, 0x79, - 0x9f, 0x8c, 0xe5, 0x5f, 0x83, 0xbc, 0xbe, 0x06, 0x3c, 0xbc, 0x01, 0xfc, - 0x34, 0xf4, 0x5a, 0xfd, 0x96, 0xde, 0x8b, 0x8a, 0x70, 0x2f, 0x1e, 0x76, - 0xb3, 0xe8, 0x61, 0xcd, 0xd8, 0x24, 0xd2, 0x7f, 0x1e, 0xf5, 0xe4, 0xf5, - 0xdf, 0x6a, 0x79, 0x6b, 0x42, 0xf9, 0x63, 0x6a, 0x0f, 0xd2, 0x9b, 0x93, - 0xa5, 0x63, 0x95, 0x30, 0x64, 0x8e, 0xf3, 0xfa, 0x53, 0xd4, 0xa3, 0xac, - 0xf5, 0xe8, 0xb3, 0xd9, 0xa8, 0xb2, 0x8f, 0x39, 0xc8, 0x52, 0x5e, 0xc5, - 0x11, 0xc0, 0xf7, 0x0e, 0xdb, 0x3d, 0xb7, 0x89, 0x67, 0x9f, 0x0d, 0xb6, - 0x8a, 0x2d, 0xda, 0x83, 0xe2, 0x97, 0xdd, 0x89, 0x32, 0xca, 0xd9, 0x8d, - 0x58, 0x1b, 0x96, 0x65, 0x91, 0xe7, 0x58, 0x37, 0xe9, 0x71, 0x38, 0x46, - 0x77, 0xf3, 0x6a, 0x9a, 0x38, 0x97, 0xf6, 0x35, 0xdf, 0x35, 0xb0, 0xec, - 0x46, 0x5d, 0x16, 0xd2, 0xf3, 0x1b, 0xd2, 0xdf, 0xd2, 0x5a, 0x87, 0x33, - 0x2b, 0xd8, 0x98, 0xf4, 0x45, 0x54, 0xbb, 0x8c, 0xe9, 0xc9, 0xce, 0x21, - 0xac, 0x47, 0x28, 0x1d, 0xe4, 0x99, 0x2c, 0xf8, 0xeb, 0xeb, 0x44, 0x5c, - 0xc5, 0x9d, 0x09, 0xc3, 0xbb, 0xbb, 0x74, 0xee, 0x9a, 0xfb, 0xd9, 0xde, - 0x5d, 0xf7, 0xa1, 0x9e, 0x26, 0x99, 0x9f, 0x89, 0xe8, 0x7b, 0x93, 0x71, - 0xa5, 0xb3, 0xf9, 0x31, 0xe6, 0xff, 0xc7, 0x26, 0x7e, 0xc7, 0x6c, 0xd8, - 0x2c, 0x6f, 0xd7, 0xfc, 0xbd, 0x51, 0xdd, 0x33, 0xa2, 0x2e, 0x14, 0xe7, - 0xde, 0x50, 0xef, 0x4f, 0xcf, 0x36, 0xa8, 0xfa, 0xa7, 0x67, 0xd7, 0xde, - 0x15, 0x62, 0xd9, 0xdb, 0xb8, 0xbf, 0x21, 0x0b, 0x53, 0x0d, 0xb2, 0x38, - 0x1b, 0x60, 0xbc, 0x96, 0x6e, 0xac, 0x7d, 0x0b, 0xa3, 0xbf, 0x5b, 0x73, - 0x65, 0x08, 0xeb, 0x37, 0x3f, 0x30, 0x29, 0xe5, 0x01, 0xc6, 0x23, 0xea, - 0x3e, 0x20, 0x64, 0xa4, 0x01, 0x58, 0xb4, 0xe0, 0x96, 0x6d, 0xee, 0x03, - 0xb7, 0x68, 0xbd, 0x7e, 0x45, 0xc7, 0x7c, 0xe4, 0x91, 0x21, 0xb9, 0xbe, - 0x09, 0x45, 0x57, 0x59, 0xf1, 0xca, 0xff, 0xd6, 0x88, 0xfd, 0xf3, 0x7b, - 0xa3, 0xa0, 0xc6, 0xb2, 0xfb, 0x35, 0xcf, 0xff, 0x4a, 0xa7, 0x8f, 0xca, - 0x9e, 0x63, 0xbf, 0x0f, 0x5a, 0x9b, 0xbc, 0x3b, 0x4f, 0x52, 0xff, 0x3d, - 0x49, 0x48, 0x7d, 0xcf, 0x12, 0xb2, 0x1f, 0x45, 0x19, 0xf7, 0xc1, 0x1e, - 0x55, 0xf3, 0xe0, 0xbd, 0xba, 0x82, 0xfc, 0xaa, 0xfb, 0x21, 0x7e, 0x2c, - 0xc6, 0xbb, 0x4b, 0x51, 0xdd, 0xdf, 0x0e, 0xbd, 0x8e, 0x63, 0xb2, 0x07, - 0xbe, 0x26, 0x0f, 0x4c, 0xca, 0xfb, 0x5e, 0xe3, 0xc1, 0xfa, 0x31, 0x7d, - 0x59, 0xf6, 0xe2, 0x7c, 0xff, 0xde, 0x41, 0x50, 0xc5, 0x23, 0x2b, 0x7b, - 0x06, 0xba, 0x7c, 0x4c, 0xf6, 0x95, 0xd4, 0xde, 0x81, 0x3a, 0x2f, 0x9c, - 0x84, 0x4e, 0x0e, 0x2a, 0x7f, 0x12, 0x09, 0x0c, 0x55, 0xd2, 0x92, 0x3f, - 0xb9, 0x13, 0xe3, 0x70, 0x1f, 0x2e, 0xa3, 0xcf, 0xe5, 0x76, 0xcb, 0x9e, - 0xaa, 0x37, 0xf6, 0xde, 0x12, 0xdf, 0x27, 0xe1, 0xa3, 0xf9, 0x3e, 0x17, - 0x0f, 0xaa, 0x93, 0x85, 0x5b, 0xd1, 0xb6, 0x41, 0xf3, 0x96, 0xf7, 0xfc, - 0xd9, 0x9e, 0xfa, 0xf7, 0x4f, 0x4c, 0x89, 0xe6, 0xf0, 0x9e, 0x6d, 0xfc, - 0xfe, 0xf6, 0xc2, 0x67, 0x30, 0x36, 0x7e, 0x44, 0x96, 0xe6, 0x26, 0x65, - 0x79, 0xce, 0x97, 0x33, 0xde, 0xb9, 0x26, 0xed, 0x77, 0xeb, 0x3b, 0xd7, - 0x19, 0xac, 0xc3, 0x6a, 0x5e, 0xe5, 0x56, 0x7d, 0x8f, 0xf4, 0x75, 0xd3, - 0xfb, 0x26, 0x70, 0xbb, 0xba, 0x3f, 0xb5, 0x5a, 0xde, 0xd9, 0xcf, 0x57, - 0x4c, 0x9e, 0x33, 0x78, 0x77, 0xc0, 0xda, 0xeb, 0xde, 0xc7, 0xf4, 0xbd, - 0xab, 0xaf, 0xe9, 0xbb, 0xfa, 0xe4, 0xe7, 0xa8, 0xa6, 0xf7, 0x56, 0xe8, - 0x1e, 0xfb, 0x7c, 0x4c, 0xaf, 0x1b, 0xd2, 0x79, 0x3e, 0xab, 0xbb, 0xa6, - 0xfa, 0xec, 0xd5, 0xd4, 0x63, 0xd4, 0xdf, 0x7b, 0x6b, 0xa8, 0x1b, 0x97, - 0xed, 0xe9, 0x1b, 0xfc, 0x3b, 0xe0, 0x2c, 0x3b, 0xa6, 0xef, 0xd7, 0xf9, - 0x77, 0xbe, 0x59, 0xe6, 0xdf, 0x03, 0x23, 0xbf, 0xb8, 0x9f, 0x88, 0xb4, - 0x3a, 0xaa, 0x9f, 0x47, 0xeb, 0xbe, 0x1d, 0xf2, 0xfb, 0x0c, 0xa1, 0x8f, - 0x3b, 0x83, 0xd7, 0xde, 0x11, 0xe7, 0xb7, 0x54, 0x94, 0x45, 0x83, 0xdf, - 0x78, 0x33, 0x06, 0x03, 0x6e, 0xda, 0x28, 0x7b, 0x15, 0x3d, 0x05, 0x75, - 0x57, 0x22, 0xeb, 0x34, 0xc9, 0xa0, 0xe9, 0xe5, 0xf7, 0xce, 0xaf, 0x95, - 0x53, 0x96, 0x6f, 0x8a, 0x48, 0x94, 0xdf, 0x70, 0xf1, 0xfd, 0x7a, 0xdf, - 0x2e, 0x84, 0xf5, 0xf7, 0x53, 0x0e, 0xda, 0x7c, 0x9e, 0xf2, 0x5e, 0x28, - 0xac, 0xdc, 0xd1, 0x2c, 0xa8, 0x3d, 0x52, 0x00, 0x73, 0x7d, 0x57, 0x92, - 0xdf, 0xb0, 0x8b, 0x3c, 0x5d, 0xe1, 0xb7, 0x5c, 0xdb, 0xd5, 0x1d, 0x16, - 0xef, 0x5c, 0x90, 0x74, 0x75, 0x29, 0x9b, 0x5c, 0xae, 0x14, 0xc9, 0x53, - 0xed, 0x57, 0xc3, 0xda, 0xaf, 0x92, 0xc7, 0xc3, 0xe0, 0xf1, 0x5f, 0xeb, - 0x75, 0x61, 0xfb, 0x8c, 0xba, 0x0b, 0x9e, 0x89, 0xf1, 0x6c, 0xea, 0x31, - 0x35, 0x17, 0xda, 0x68, 0xb4, 0x7d, 0x47, 0x50, 0xe9, 0xae, 0xfa, 0x46, - 0x1e, 0xf2, 0xc9, 0x6f, 0xde, 0x61, 0x5f, 0x4b, 0xfc, 0xb6, 0x7d, 0x58, - 0x7d, 0x67, 0x52, 0xae, 0x70, 0x5d, 0xf9, 0x4d, 0xfb, 0x68, 0x9d, 0x3c, - 0x06, 0xf5, 0x58, 0x9b, 0x5a, 0x25, 0xea, 0xad, 0x3b, 0xbf, 0x51, 0x29, - 0x57, 0xfc, 0xfb, 0x9d, 0x1b, 0x96, 0xa8, 0x13, 0xa2, 0x62, 0x6c, 0xef, - 0x3b, 0x9b, 0xb2, 0xfa, 0x6e, 0x25, 0xc1, 0xef, 0x2e, 0xe1, 0x3b, 0x76, - 0xe1, 0x99, 0x67, 0xba, 0xbb, 0x91, 0xc2, 0xe6, 0x54, 0xc6, 0x91, 0x3e, - 0x2c, 0x39, 0xb5, 0xe7, 0xd6, 0x8c, 0xfc, 0x5e, 0x35, 0x76, 0xb1, 0xf2, - 0x80, 0xec, 0x39, 0xf9, 0x10, 0xbf, 0xed, 0x51, 0xdf, 0xe5, 0x67, 0x1d, - 0xd2, 0x18, 0x93, 0x09, 0x35, 0xef, 0x42, 0xed, 0x9b, 0x11, 0xc5, 0xfb, - 0x5c, 0x2b, 0xd7, 0xb4, 0x50, 0x69, 0x06, 0x8d, 0x01, 0x7d, 0xc7, 0x93, - 0x58, 0xdc, 0x9f, 0x7f, 0x94, 0xf7, 0x06, 0x5d, 0x9e, 0xdd, 0xed, 0x29, - 0xf1, 0x0e, 0x67, 0x52, 0xc7, 0xe8, 0xdc, 0xb7, 0xe3, 0xd9, 0x00, 0x65, - 0xdc, 0x4a, 0x8d, 0xc3, 0xfa, 0x87, 0x25, 0xce, 0x73, 0x65, 0x3d, 0x97, - 0xe6, 0xba, 0xb9, 0xf0, 0xde, 0xaa, 0x37, 0x1f, 0x7e, 0x0b, 0x93, 0x2f, - 0xd5, 0x7f, 0xc7, 0xa3, 0xbe, 0x11, 0x57, 0xdf, 0xcd, 0x8c, 0x57, 0x3e, - 0x21, 0x1f, 0x2b, 0x6d, 0xd4, 0xdf, 0xf0, 0x44, 0xe4, 0x63, 0x95, 0xd7, - 0x14, 0x4f, 0xf3, 0xea, 0xfb, 0xa3, 0xb0, 0x5e, 0xb3, 0x98, 0xea, 0xa3, - 0xf6, 0x1d, 0x92, 0x55, 0xf7, 0x4d, 0x4a, 0x58, 0xc6, 0xe7, 0x7f, 0xd9, - 0xb7, 0x48, 0x8f, 0x08, 0xbf, 0x47, 0xb9, 0xe4, 0x4c, 0xca, 0xe3, 0x73, - 0xae, 0x7b, 0x97, 0x43, 0x5c, 0xb7, 0x41, 0x96, 0x63, 0xa3, 0x3b, 0xbe, - 0x67, 0xb7, 0x05, 0xca, 0x33, 0x8d, 0xb0, 0xd7, 0xc4, 0x12, 0x12, 0x65, - 0x7e, 0x7e, 0x86, 0x7a, 0x1a, 0xc2, 0x1c, 0x2d, 0xf3, 0xaa, 0x7c, 0xa6, - 0x95, 0x7b, 0x5e, 0x77, 0x21, 0x8e, 0xfc, 0xb8, 0xe3, 0xd9, 0xe5, 0xcf, - 0x2d, 0xec, 0x94, 0xcf, 0x55, 0x22, 0x81, 0xf2, 0x14, 0xef, 0xfa, 0x59, - 0xc3, 0x73, 0x92, 0x44, 0x3d, 0xf6, 0x0f, 0x79, 0x89, 0x6f, 0x96, 0xa7, - 0x8e, 0xfd, 0xc2, 0xbd, 0x6a, 0xe3, 0x3d, 0x6c, 0xcd, 0xb2, 0xe3, 0xef, - 0xeb, 0x21, 0x86, 0x3f, 0xc2, 0x7a, 0x9b, 0x21, 0x07, 0xf0, 0xdb, 0xd0, - 0x39, 0xc6, 0x98, 0x57, 0xb5, 0xdd, 0x32, 0x8e, 0xdc, 0x2c, 0x57, 0x57, - 0xee, 0x0a, 0x5f, 0x86, 0x6c, 0x27, 0x3c, 0xfe, 0xab, 0x7d, 0xf0, 0x03, - 0x12, 0xfc, 0x22, 0xfc, 0xc4, 0x17, 0x1b, 0x94, 0x6d, 0xa7, 0x3f, 0x43, - 0xfc, 0x81, 0x18, 0x23, 0x84, 0x7e, 0x1e, 0x6c, 0xf5, 0x64, 0x76, 0x52, - 0xe4, 0xcb, 0x4d, 0x92, 0x69, 0x65, 0x0c, 0x2b, 0xbf, 0xc2, 0x7e, 0xd5, - 0xeb, 0x59, 0x4a, 0xbe, 0x42, 0x1d, 0xaf, 0x72, 0x2e, 0xc9, 0xf8, 0x8f, - 0xe5, 0x93, 0x32, 0x1e, 0xe7, 0x5c, 0x1e, 0x91, 0xc2, 0xdc, 0x63, 0xf8, - 0x71, 0x9e, 0xa4, 0xfb, 0x1f, 0xe8, 0x7b, 0x04, 0xa3, 0x52, 0x9c, 0x4a, - 0xcb, 0xc4, 0xec, 0x5e, 0x7e, 0xa3, 0x3b, 0x7c, 0x97, 0x3a, 0x5f, 0xb3, - 0xe2, 0xc9, 0x40, 0x6f, 0x62, 0x82, 0xf7, 0x26, 0xd4, 0x7c, 0xf6, 0x62, - 0x3e, 0xdf, 0x6a, 0xe5, 0xdd, 0xf3, 0xab, 0xb0, 0xbf, 0xc6, 0x71, 0xca, - 0xa1, 0x65, 0x76, 0x06, 0x98, 0xdf, 0x8d, 0xd8, 0x99, 0x65, 0xbb, 0x25, - 0x78, 0x64, 0xc5, 0xce, 0xa3, 0x5c, 0x9f, 0xf3, 0xaa, 0xf6, 0xff, 0x11, - 0x6d, 0x51, 0xef, 0x88, 0xdf, 0xd6, 0xaf, 0xc3, 0xb6, 0x9c, 0xe7, 0x4e, - 0xc4, 0xec, 0x3e, 0x5d, 0x90, 0xc3, 0x78, 0x3d, 0xbf, 0xa3, 0x6b, 0xf8, - 0x1d, 0x22, 0xde, 0x04, 0xbf, 0xc8, 0xe3, 0xa0, 0xe6, 0xf1, 0x9b, 0xe8, - 0xdf, 0x5f, 0x83, 0xbb, 0x50, 0x66, 0xea, 0x6f, 0x03, 0xdf, 0x0a, 0xdf, - 0xc9, 0x73, 0xd6, 0x7f, 0xb0, 0xd5, 0x93, 0x35, 0xd2, 0xb3, 0x1e, 0xcf, - 0x3b, 0xdb, 0xbc, 0x75, 0xd9, 0x0d, 0x7e, 0xf1, 0x4e, 0x67, 0xaf, 0xfa, - 0x4e, 0x20, 0x33, 0xb6, 0x1b, 0xb2, 0xe3, 0xcf, 0xab, 0x17, 0x32, 0xc6, - 0x33, 0x0b, 0xd6, 0xaf, 0xe7, 0x89, 0xe7, 0xf7, 0x82, 0xdc, 0x77, 0xb0, - 0x39, 0x57, 0x60, 0xc2, 0x2f, 0xab, 0xef, 0x82, 0x60, 0x27, 0xdf, 0xb6, - 0xf2, 0x5d, 0xd0, 0xf5, 0xd7, 0x78, 0xa0, 0xcd, 0xf3, 0x51, 0x26, 0x78, - 0xd2, 0xa2, 0xdb, 0xec, 0x06, 0x3e, 0xe5, 0x5e, 0x6c, 0x32, 0xfe, 0xa0, - 0xf8, 0xe3, 0xb8, 0xdb, 0x19, 0x73, 0x0e, 0xf6, 0xf7, 0x22, 0xbe, 0x56, - 0xf7, 0x65, 0xe2, 0xbc, 0x7f, 0x93, 0x0c, 0xec, 0x56, 0x77, 0x27, 0x2e, - 0xac, 0xfa, 0xb6, 0x2b, 0x25, 0x4f, 0xd5, 0x64, 0x65, 0xf8, 0x27, 0x62, - 0x49, 0xe2, 0x26, 0xca, 0x0a, 0xfb, 0xdd, 0xcb, 0x79, 0xc6, 0x1f, 0x52, - 0xf3, 0x34, 0x11, 0xc3, 0xf1, 0x9e, 0x83, 0x19, 0x28, 0xcf, 0x72, 0xdd, - 0x91, 0x2e, 0xf0, 0xd9, 0x3f, 0x6b, 0x55, 0x76, 0x05, 0xe3, 0xb2, 0x8c, - 0xb6, 0x91, 0xef, 0xd3, 0xfa, 0x2c, 0xf6, 0xc3, 0x6d, 0xbc, 0x0f, 0x90, - 0x47, 0xd9, 0xdc, 0xc2, 0xfa, 0xb4, 0x7d, 0x5c, 0xc9, 0xc1, 0x23, 0xe0, - 0xfb, 0x1f, 0xa3, 0xee, 0x63, 0x48, 0x39, 0xc7, 0xf4, 0xca, 0xba, 0x93, - 0xdf, 0x1f, 0x90, 0x01, 0xc8, 0x05, 0xf3, 0x8f, 0x48, 0x51, 0xdd, 0x63, - 0x42, 0x3a, 0xc7, 0x67, 0xda, 0x7a, 0x5b, 0xfb, 0x53, 0xd2, 0xb2, 0x5b, - 0x7f, 0x4f, 0xe6, 0xcb, 0xd3, 0x2e, 0xdd, 0x6e, 0x6c, 0x85, 0x57, 0x0f, - 0x5d, 0x83, 0x37, 0xc2, 0x2b, 0x78, 0xc3, 0x1b, 0xeb, 0xf1, 0x36, 0x1f, - 0x6b, 0x78, 0x73, 0xf0, 0xb0, 0x86, 0x27, 0xe7, 0x7b, 0x25, 0x04, 0x39, - 0x0e, 0xd6, 0xe4, 0x18, 0xb8, 0xc7, 0xd3, 0x99, 0x09, 0x9e, 0x21, 0x2a, - 0x3e, 0x53, 0x0e, 0x29, 0xbf, 0x5c, 0xc7, 0xfa, 0xb5, 0x7e, 0xcf, 0x2f, - 0x59, 0xeb, 0x97, 0xdb, 0x7c, 0xfc, 0xf0, 0x77, 0xd3, 0x83, 0x0b, 0x6d, - 0x35, 0x3d, 0xb8, 0xf9, 0x37, 0xa4, 0x07, 0x6b, 0xe5, 0xb2, 0x5e, 0xa6, - 0x4c, 0xc8, 0x13, 0xd7, 0x8b, 0xf2, 0x44, 0x39, 0x22, 0x2f, 0x69, 0x4f, - 0x1b, 0x19, 0x3b, 0xc5, 0xaf, 0xa8, 0xef, 0x36, 0x26, 0x61, 0x83, 0xda, - 0x02, 0x73, 0x73, 0x31, 0x29, 0x2e, 0xbc, 0x4f, 0xc9, 0xf4, 0x53, 0x55, - 0xda, 0xa5, 0xeb, 0xcd, 0x7d, 0xb5, 0xcd, 0xcd, 0xaf, 0xb1, 0xb9, 0xf9, - 0x15, 0x9b, 0xdb, 0xaa, 0xe3, 0xa5, 0xbf, 0x8b, 0xcd, 0x8d, 0xd5, 0x9d, - 0xcb, 0xf8, 0x67, 0x32, 0x12, 0xc8, 0xf6, 0x44, 0x65, 0x07, 0xfc, 0xc8, - 0xf0, 0xd4, 0x4e, 0xf9, 0x97, 0x53, 0x93, 0xea, 0x8e, 0xd2, 0x5f, 0x38, - 0xc9, 0xf8, 0x03, 0x01, 0x57, 0x3e, 0x80, 0x78, 0x77, 0xbc, 0xa3, 0x41, - 0x76, 0xbc, 0x4b, 0x9d, 0x35, 0x9a, 0xd9, 0x40, 0xbb, 0x70, 0x17, 0x3c, - 0xe7, 0x58, 0x4e, 0x22, 0xc0, 0xfb, 0x6a, 0x8d, 0x32, 0x1e, 0x6b, 0x96, - 0x9d, 0xc0, 0x4e, 0x85, 0x1b, 0x1c, 0xf5, 0x2d, 0x79, 0x46, 0x9d, 0xe5, - 0xdc, 0xb2, 0xd9, 0x1b, 0x17, 0x7c, 0x68, 0x31, 0xe5, 0xab, 0xd5, 0x5b, - 0xd4, 0x77, 0xd1, 0x17, 0x4a, 0xd5, 0xd6, 0xd5, 0x79, 0x3e, 0xff, 0x7b, - 0xd4, 0x89, 0x81, 0x57, 0xf5, 0x77, 0x7f, 0x82, 0x8a, 0x9f, 0xc5, 0xb9, - 0x31, 0x75, 0xa7, 0xea, 0x4a, 0x90, 0xfc, 0x52, 0x71, 0x53, 0x3c, 0x1b, - 0x04, 0xc6, 0x99, 0x01, 0x92, 0xb6, 0x19, 0xf3, 0x69, 0xfc, 0x09, 0xfb, - 0xbf, 0x47, 0x9d, 0xed, 0x2e, 0x81, 0x37, 0xae, 0xda, 0xfb, 0xcd, 0xc7, - 0x88, 0xeb, 0x6b, 0xf7, 0x87, 0xaf, 0xc5, 0xf7, 0xde, 0xb7, 0x67, 0xfa, - 0x1c, 0x42, 0xef, 0x15, 0xe9, 0x18, 0x5c, 0x9d, 0xab, 0xad, 0xf7, 0x7f, - 0x29, 0x88, 0xf5, 0xf8, 0x7f, 0x0f, 0x88, 0xed, 0xac, 0xc3, 0x73, 0xe2, - 0xa8, 0x38, 0x30, 0x43, 0xfe, 0x96, 0xb1, 0x4e, 0xd3, 0x71, 0xdf, 0x9f, - 0x07, 0x3a, 0xcf, 0xd6, 0xc7, 0x81, 0xec, 0x23, 0xa2, 0xee, 0x63, 0xd4, - 0xfe, 0x0f, 0x0e, 0xf7, 0x77, 0x32, 0x81, 0x7b, 0x4a, 0x93, 0x12, 0x3c, - 0x3a, 0x2a, 0xa1, 0x69, 0xee, 0xa5, 0x67, 0xa4, 0x18, 0x73, 0xe5, 0x63, - 0xce, 0xea, 0xd8, 0xa4, 0xd3, 0x58, 0x4b, 0xfb, 0x23, 0x32, 0x78, 0xf2, - 0x31, 0x09, 0x1f, 0xe5, 0xbb, 0x55, 0xe7, 0x28, 0xb0, 0x47, 0x1b, 0x64, - 0x2e, 0xc6, 0xfd, 0xe4, 0xb0, 0x3a, 0x97, 0x5e, 0x1e, 0x7b, 0x2d, 0x5c, - 0x04, 0x56, 0xc8, 0x2b, 0xdb, 0x82, 0x74, 0x25, 0x96, 0x38, 0xbc, 0x99, - 0x3a, 0x85, 0x18, 0x33, 0x30, 0x3e, 0x17, 0x56, 0xf7, 0x83, 0x96, 0x63, - 0xac, 0x8b, 0xf8, 0xfd, 0x28, 0x71, 0x06, 0x6c, 0xc7, 0xa8, 0x44, 0x99, - 0x0f, 0x1e, 0xad, 0xe1, 0x0c, 0xda, 0x84, 0x41, 0x27, 0x26, 0xa1, 0x53, - 0xde, 0xdc, 0xf9, 0x8f, 0x95, 0x8c, 0x13, 0x3b, 0x25, 0x38, 0xcd, 0xe7, - 0xfa, 0x78, 0x88, 0xd8, 0x1d, 0xbe, 0xe1, 0xec, 0x67, 0xd1, 0x1f, 0xdf, - 0x65, 0xf4, 0x37, 0xba, 0xc8, 0x97, 0xff, 0xb6, 0xff, 0x43, 0x81, 0xb2, - 0xff, 0xff, 0x01, 0xe6, 0x8e, 0x9a, 0x21, 0xc0, 0x4e, 0x00, 0x00, 0x00 }; + 0xcd, 0x7c, 0x0d, 0x70, 0x5c, 0xd7, 0x75, 0xde, 0xd9, 0xb7, 0xbb, 0xc0, + 0x12, 0x04, 0xc1, 0x07, 0x68, 0x05, 0xad, 0x24, 0x24, 0xde, 0x87, 0x7d, + 0x00, 0x56, 0x22, 0xe4, 0x3c, 0x32, 0x10, 0x0d, 0xb9, 0x5b, 0x72, 0xbd, + 0x0b, 0x50, 0x90, 0x43, 0x23, 0x90, 0x84, 0x28, 0x6a, 0x86, 0xe3, 0x41, + 0x97, 0xa0, 0x62, 0x69, 0xdc, 0x86, 0x1e, 0x2b, 0x29, 0xe5, 0x2a, 0xe6, + 0x6a, 0x01, 0xca, 0x94, 0x02, 0x72, 0x61, 0x12, 0x04, 0xd5, 0x54, 0x6d, + 0xd7, 0x0b, 0x80, 0x54, 0xd4, 0x25, 0x97, 0x94, 0xfc, 0xa3, 0x99, 0xd8, + 0x21, 0x4a, 0xd1, 0x92, 0xed, 0x71, 0xa7, 0x92, 0xc7, 0x9d, 0xaa, 0x33, + 0x9a, 0x94, 0xa5, 0xe4, 0xda, 0xf1, 0x34, 0x8d, 0x6a, 0x7b, 0x1a, 0x25, + 0xb1, 0xf3, 0xfa, 0x7d, 0xf7, 0xdd, 0x0b, 0x2c, 0x20, 0x48, 0x56, 0x92, + 0xf1, 0x4c, 0x30, 0xb3, 0xbc, 0xef, 0xde, 0x77, 0x7f, 0xcf, 0x39, 0xf7, + 0x9c, 0xef, 0x9c, 0x7b, 0x1f, 0x77, 0x89, 0xb4, 0x88, 0xfe, 0xdb, 0x82, + 0xdf, 0xc0, 0xbf, 0xf8, 0x9d, 0xfd, 0xdb, 0x3f, 0xb8, 0xf3, 0x83, 0x78, + 0xdc, 0x69, 0xd9, 0x4d, 0x11, 0x96, 0x87, 0xf1, 0x8b, 0xe3, 0xb7, 0x43, + 0x3f, 0x6f, 0xf4, 0x67, 0xb3, 0x41, 0x48, 0x64, 0xe2, 0x87, 0x22, 0xa1, + 0x75, 0xef, 0x62, 0xef, 0xd2, 0xe6, 0xbd, 0xfe, 0xac, 0xf7, 0x59, 0xcf, + 0xfe, 0x7b, 0xf4, 0x6d, 0xfe, 0xc2, 0xba, 0xf9, 0x16, 0xfd, 0x93, 0x98, + 0x95, 0xb9, 0xfa, 0xb1, 0x9c, 0x2b, 0xb1, 0x70, 0xe6, 0xbb, 0xa3, 0xfb, + 0x5d, 0x91, 0x6c, 0x6d, 0x5b, 0x32, 0x2f, 0x3f, 0xf3, 0x8b, 0xf1, 0x88, + 0xb0, 0xfc, 0x97, 0x32, 0x3f, 0x3d, 0xfc, 0xb5, 0x0f, 0x39, 0x6f, 0x55, + 0xc2, 0x12, 0xb3, 0x33, 0x6f, 0x8b, 0xdd, 0x2b, 0xb1, 0x2e, 0xb4, 0x79, + 0xba, 0xef, 0x59, 0x4b, 0xda, 0x4c, 0x5f, 0xf6, 0x44, 0x38, 0x23, 0x63, + 0x93, 0x33, 0x87, 0x7d, 0xcb, 0x95, 0xe2, 0x4d, 0x19, 0x37, 0x59, 0x92, + 0xd6, 0xc1, 0xe9, 0x81, 0x0f, 0x09, 0xf2, 0x63, 0x93, 0xb5, 0x98, 0xe4, + 0xea, 0xc5, 0x56, 0xcb, 0x75, 0x91, 0xc6, 0x8a, 0x37, 0x67, 0x24, 0xd6, + 0x94, 0x79, 0xba, 0xf9, 0x25, 0x97, 0xe3, 0x27, 0x46, 0x73, 0xee, 0xcd, + 0x12, 0x71, 0x7d, 0x7f, 0x1a, 0xe3, 0xef, 0xa9, 0xfd, 0xcc, 0x7f, 0x2c, + 0x12, 0x8c, 0x6d, 0x65, 0x8a, 0x61, 0xa6, 0xa1, 0x4c, 0x72, 0xb4, 0xbb, + 0xa6, 0xf2, 0x4d, 0x41, 0xde, 0x35, 0xf9, 0x2d, 0x41, 0x7e, 0x42, 0xe7, + 0xed, 0x96, 0x60, 0x2d, 0xb1, 0x4d, 0x58, 0x4b, 0x2c, 0x92, 0x19, 0xda, + 0x84, 0x3e, 0x63, 0xd1, 0x8c, 0x9b, 0x59, 0x52, 0xf5, 0x3e, 0xa1, 0xeb, + 0x1d, 0x8c, 0x06, 0xed, 0x26, 0x47, 0x7b, 0x6b, 0x4c, 0x1f, 0x1e, 0xed, + 0x51, 0xe9, 0xa3, 0xa3, 0x29, 0x95, 0x16, 0x55, 0xbd, 0x50, 0x66, 0x7a, + 0xd4, 0x55, 0x69, 0x97, 0x2e, 0x4f, 0x8f, 0x26, 0x55, 0xda, 0xaf, 0x53, + 0x4f, 0xa7, 0x03, 0x3a, 0x1d, 0xd4, 0x69, 0x46, 0xa7, 0x59, 0x9d, 0x0e, + 0xe9, 0x7e, 0x46, 0x74, 0x7e, 0xaf, 0x4e, 0xc7, 0x74, 0x3a, 0xae, 0xd3, + 0xfb, 0x75, 0xba, 0x4f, 0xcf, 0xeb, 0x93, 0x3a, 0x7f, 0x50, 0xcf, 0xef, + 0x10, 0xe6, 0xf1, 0x93, 0x26, 0x2d, 0xbf, 0x58, 0x67, 0x52, 0xf6, 0xcf, + 0xc4, 0xa4, 0x54, 0x0e, 0x4b, 0x5e, 0xf1, 0xb5, 0x3f, 0x2a, 0x2d, 0x31, + 0x99, 0xaa, 0xc7, 0xe4, 0xaa, 0x12, 0xdb, 0x1f, 0xf8, 0x5f, 0xeb, 0xb3, + 0xe5, 0x42, 0x3d, 0x2e, 0x97, 0xea, 0x12, 0x1a, 0xeb, 0xdb, 0x24, 0xd6, + 0x89, 0x9b, 0x24, 0x6b, 0x87, 0x24, 0xac, 0xe8, 0x9b, 0x94, 0xdc, 0x4c, + 0x27, 0xf2, 0x4e, 0x42, 0x64, 0x32, 0x1a, 0xf0, 0x33, 0x26, 0xe1, 0x79, + 0xf2, 0x67, 0x7e, 0xf4, 0xa5, 0xb9, 0x84, 0x44, 0x8e, 0x27, 0xd1, 0x7f, + 0xab, 0x44, 0xe7, 0xa5, 0x2b, 0x2c, 0x3d, 0x89, 0x07, 0x50, 0x63, 0xa8, + 0x16, 0x91, 0xe1, 0x5a, 0x08, 0x3c, 0x8b, 0x41, 0x5e, 0x5a, 0xf1, 0xb3, + 0xf1, 0x8b, 0xe3, 0x97, 0xc0, 0xef, 0x09, 0xf4, 0xd3, 0x25, 0xf9, 0x1a, + 0xfb, 0xc4, 0xb8, 0x65, 0x8c, 0x5f, 0x76, 0xec, 0x09, 0xe1, 0x9c, 0x12, + 0xf2, 0xb5, 0xbe, 0x60, 0x4e, 0x97, 0xea, 0xb1, 0x50, 0xee, 0xb4, 0x1c, + 0xcc, 0x7b, 0x92, 0xb4, 0xdc, 0x16, 0x29, 0xd8, 0xa1, 0xe4, 0x64, 0xba, + 0x43, 0x8a, 0xe3, 0x78, 0x57, 0x96, 0xac, 0x85, 0xbe, 0x0b, 0xb6, 0x4c, + 0x04, 0xef, 0x58, 0xf6, 0x37, 0xd8, 0xb7, 0x8e, 0x4d, 0x01, 0xbe, 0x54, + 0xfe, 0x63, 0x3c, 0xb3, 0xaf, 0xff, 0x17, 0x0e, 0xe6, 0xfc, 0xd7, 0xc8, + 0xb3, 0xfc, 0xcb, 0x5b, 0x83, 0x3c, 0x9f, 0x59, 0xd7, 0x8c, 0x69, 0xd6, + 0xca, 0xb1, 0xfb, 0xb0, 0x5e, 0x8e, 0xbf, 0xb2, 0x5e, 0xcc, 0xa3, 0x35, + 0x94, 0x3f, 0x9d, 0x94, 0x23, 0xe5, 0x5d, 0x92, 0xf3, 0x7c, 0x7f, 0xbf, + 0x27, 0x71, 0x4b, 0x7a, 0xec, 0x3c, 0xde, 0x56, 0x6b, 0x12, 0xca, 0x95, + 0x0d, 0x3d, 0xd8, 0x6f, 0x04, 0x65, 0x9d, 0xa8, 0xdf, 0x16, 0x1a, 0x3a, + 0x8d, 0xb9, 0x67, 0x48, 0x17, 0xc8, 0xae, 0xd7, 0x93, 0x98, 0xc4, 0x78, + 0x0b, 0xb5, 0x1e, 0xef, 0xb2, 0xd8, 0xe8, 0xb3, 0x03, 0x75, 0x48, 0x23, + 0xf6, 0xc5, 0x3e, 0xd9, 0x5f, 0x2b, 0xda, 0xc6, 0xf1, 0x8e, 0x73, 0xf2, + 0xfd, 0x9c, 0x67, 0x33, 0x2f, 0x15, 0xd0, 0xad, 0x42, 0xba, 0xb5, 0x74, + 0xc9, 0x99, 0x1a, 0xc7, 0xd8, 0x68, 0xde, 0xb7, 0xfe, 0x23, 0x9b, 0x77, + 0x02, 0xfd, 0xc7, 0x91, 0x6e, 0x0e, 0xe5, 0x4e, 0xfa, 0x18, 0x3f, 0x81, + 0xe7, 0x8d, 0xd6, 0x70, 0x55, 0xcb, 0x60, 0x02, 0x73, 0x8f, 0xcb, 0x45, + 0x25, 0x87, 0x9b, 0x25, 0x0c, 0x39, 0x24, 0x8f, 0xdb, 0xe7, 0x6f, 0x97, + 0x42, 0xdc, 0x49, 0x52, 0x87, 0x76, 0xef, 0xd8, 0x84, 0x35, 0x6a, 0x6d, + 0x78, 0x3c, 0x0e, 0x39, 0xbc, 0xdc, 0x6e, 0xa1, 0xc4, 0x12, 0xc7, 0xfe, + 0x2d, 0x29, 0x4a, 0x7e, 0xf1, 0x91, 0x90, 0xb4, 0x58, 0xa8, 0xb7, 0x2d, + 0x14, 0xd0, 0x80, 0xf4, 0xc9, 0x82, 0x3e, 0x21, 0x09, 0xf6, 0x73, 0x56, + 0xba, 0x6b, 0xea, 0x7d, 0xd2, 0x52, 0xef, 0x86, 0xf0, 0x2e, 0x22, 0xa9, + 0x1d, 0xe6, 0xfd, 0x10, 0xde, 0xdf, 0x24, 0x13, 0x36, 0xe6, 0x52, 0x7e, + 0xc1, 0xca, 0x61, 0x8e, 0x1f, 0x89, 0xa8, 0xb5, 0xa2, 0xee, 0x44, 0x43, + 0x3f, 0x13, 0xa8, 0xf7, 0x34, 0xc6, 0xc2, 0x7c, 0xcb, 0x49, 0xcc, 0xa5, + 0x13, 0x73, 0xe1, 0x1c, 0x8b, 0x56, 0xae, 0x1e, 0x41, 0x7e, 0xda, 0xca, + 0x9f, 0x3d, 0x8a, 0x67, 0xb1, 0xad, 0xcc, 0x0b, 0x4c, 0xd1, 0x7e, 0x5f, + 0x43, 0xfb, 0x7d, 0x68, 0xcf, 0x31, 0xd8, 0x3e, 0x90, 0xff, 0xa2, 0x92, + 0xc5, 0xe4, 0x7b, 0xd0, 0x23, 0xfc, 0xf7, 0xa0, 0xc7, 0xd7, 0x34, 0x3d, + 0x7e, 0x26, 0xbf, 0x78, 0x7a, 0x5c, 0xfd, 0x05, 0xd1, 0x43, 0xa4, 0x70, + 0x92, 0xcf, 0x11, 0x29, 0x2a, 0xbd, 0xc5, 0x7d, 0x4b, 0x79, 0xa7, 0xce, + 0x22, 0x9d, 0x28, 0xc7, 0xd8, 0x03, 0xf5, 0x08, 0xd2, 0x67, 0x90, 0x6e, + 0x0e, 0x8d, 0x9d, 0x7c, 0x13, 0xfc, 0xf7, 0xc5, 0xde, 0x61, 0xec, 0x47, + 0x31, 0x61, 0x4b, 0x97, 0xd8, 0x1f, 0x84, 0xf1, 0xee, 0x74, 0xec, 0x82, + 0x7c, 0x9f, 0xef, 0x43, 0xc6, 0xce, 0xe7, 0x66, 0x36, 0xbd, 0x9d, 0x55, + 0x4f, 0x51, 0xd2, 0x33, 0x6b, 0x65, 0x22, 0xa1, 0x7c, 0x39, 0x39, 0x61, + 0x65, 0xe2, 0xd0, 0x53, 0xcc, 0x0f, 0x86, 0x82, 0x39, 0x0f, 0xa0, 0xae, + 0xd1, 0x59, 0x66, 0xee, 0x03, 0x98, 0xfb, 0x7a, 0xdd, 0x95, 0xc5, 0x5c, + 0x38, 0x07, 0xce, 0xab, 0xa8, 0x75, 0x10, 0xfb, 0x39, 0xa4, 0xfa, 0x09, + 0x67, 0x06, 0x85, 0xb6, 0xb4, 0x30, 0xc3, 0x7d, 0xc0, 0x76, 0xec, 0x2b, + 0xd0, 0xc9, 0x85, 0x9a, 0xe9, 0xa3, 0xd8, 0xd8, 0x07, 0xe6, 0x23, 0x5b, + 0x2d, 0x37, 0x0a, 0xde, 0xb3, 0xab, 0xa3, 0x78, 0xf7, 0xb4, 0xe4, 0xce, + 0xde, 0x61, 0x61, 0x0d, 0xe8, 0x97, 0x34, 0x1a, 0x83, 0xce, 0xe6, 0x3e, + 0x8b, 0x49, 0x3e, 0xce, 0xb2, 0x49, 0x3d, 0x6e, 0x44, 0xb2, 0x2a, 0x9f, + 0x6b, 0x5b, 0x9d, 0xc7, 0x0b, 0x7a, 0x3d, 0x19, 0xac, 0x87, 0x73, 0x30, + 0x6b, 0xc9, 0x34, 0xac, 0xc5, 0xd0, 0x9a, 0xb4, 0xb0, 0xa1, 0xe3, 0x63, + 0xda, 0x86, 0xb0, 0xdd, 0x74, 0x03, 0xef, 0xa6, 0xd1, 0x86, 0xb4, 0x47, + 0x9d, 0x75, 0x76, 0x85, 0x36, 0x65, 0x08, 0xfd, 0x94, 0xe6, 0x2c, 0xc9, + 0x7b, 0xb0, 0xd9, 0xde, 0xcd, 0x5a, 0x5e, 0x57, 0x65, 0x29, 0xba, 0xa1, + 0x2c, 0x3d, 0x66, 0x05, 0xfa, 0x1a, 0xb6, 0x05, 0xf6, 0x67, 0x6a, 0xce, + 0x49, 0x1b, 0x59, 0x2a, 0xcd, 0xbc, 0x1f, 0x59, 0x32, 0xed, 0x63, 0x90, + 0x5d, 0x33, 0xc6, 0xfa, 0x39, 0x9b, 0x3a, 0x98, 0x63, 0x79, 0x48, 0x63, + 0x15, 0x8e, 0x13, 0xd8, 0x86, 0xca, 0x1a, 0xdb, 0x70, 0x14, 0x6d, 0x25, + 0x94, 0xef, 0x6b, 0x95, 0x03, 0x73, 0xa6, 0x8f, 0xa3, 0x4a, 0x66, 0x27, + 0x67, 0x1c, 0x7b, 0x38, 0x2c, 0xd9, 0xe1, 0xd9, 0x41, 0x19, 0xaa, 0x77, + 0x81, 0xa7, 0x6f, 0xfb, 0xb0, 0x9d, 0x1f, 0x8c, 0x8a, 0x0b, 0xbd, 0x88, + 0x35, 0x0f, 0x80, 0xc6, 0xf5, 0xa8, 0x58, 0x19, 0x0f, 0x69, 0x23, 0xd6, + 0x8a, 0x44, 0x86, 0xd7, 0xe4, 0x9b, 0x50, 0x07, 0x7d, 0x0f, 0xac, 0xaf, + 0x07, 0xf9, 0x04, 0x6d, 0x73, 0xde, 0xcf, 0x7c, 0xd8, 0x61, 0x6d, 0xb3, + 0x58, 0x4a, 0x3d, 0x61, 0x74, 0xc4, 0x6f, 0x60, 0x7f, 0xab, 0xbd, 0x50, + 0x04, 0x76, 0x41, 0x1f, 0xa2, 0xe4, 0xb4, 0x54, 0x7f, 0xce, 0xec, 0x7b, + 0x55, 0xbe, 0x67, 0x80, 0xb2, 0x57, 0x01, 0x26, 0xe0, 0x9a, 0x16, 0xd5, + 0x5e, 0xcf, 0xdb, 0x71, 0x99, 0x2e, 0x73, 0x3d, 0x8b, 0x92, 0xaa, 0xfd, + 0x7b, 0xc9, 0x9f, 0x15, 0xf9, 0xd6, 0x0c, 0xeb, 0x7d, 0x55, 0xd7, 0x7b, + 0x01, 0xf5, 0x52, 0xc9, 0xa1, 0x90, 0x03, 0x3b, 0xe0, 0x60, 0x9b, 0x6c, + 0x4b, 0x22, 0xb5, 0x47, 0xf0, 0x1b, 0xa2, 0x91, 0x41, 0xbd, 0x00, 0xfb, + 0xbc, 0x00, 0x7a, 0x88, 0xdc, 0x5d, 0x6e, 0x86, 0x3e, 0xf9, 0x9f, 0x98, + 0x6b, 0x5c, 0x9e, 0xc4, 0x3a, 0x5e, 0x9a, 0x21, 0xbe, 0xfa, 0xaa, 0x2c, + 0xcd, 0x10, 0x6f, 0xbd, 0x20, 0xd3, 0x33, 0x29, 0xef, 0x5b, 0xa0, 0xf3, + 0x19, 0xe1, 0x5a, 0xb6, 0x79, 0x48, 0x81, 0x05, 0x9d, 0xe4, 0xe3, 0xd0, + 0x67, 0x7d, 0x3b, 0x82, 0xfe, 0x7a, 0x74, 0x7f, 0x6e, 0xcd, 0x91, 0xab, + 0x36, 0xf5, 0xd3, 0x3b, 0xf7, 0x78, 0x4e, 0xef, 0xf1, 0x31, 0xaf, 0x4b, + 0x2c, 0xec, 0xeb, 0xec, 0x78, 0x11, 0xd6, 0x8f, 0xfb, 0xfa, 0x6d, 0x6b, + 0x15, 0xff, 0x24, 0x80, 0x59, 0x1d, 0x65, 0xef, 0xfe, 0x6e, 0x7b, 0xbc, + 0x71, 0x6f, 0x73, 0xfc, 0x36, 0xb4, 0x89, 0x20, 0x7d, 0xef, 0x7d, 0x8d, + 0x3e, 0x1a, 0xda, 0x0e, 0x72, 0x5f, 0xa0, 0xcd, 0xbf, 0x05, 0x2d, 0x48, + 0xff, 0xf7, 0xb3, 0x9f, 0x6f, 0x0b, 0xbf, 0xaf, 0xfd, 0x3c, 0xfe, 0x5e, + 0xfb, 0xb9, 0x71, 0x2f, 0x5f, 0x20, 0x2d, 0x30, 0xb6, 0xcc, 0x06, 0xb2, + 0xd5, 0x03, 0x5a, 0x27, 0x21, 0xa7, 0x98, 0x43, 0xf9, 0x6f, 0xfd, 0x6c, + 0x24, 0xc0, 0x73, 0x81, 0x3c, 0xb1, 0x9e, 0xa9, 0x13, 0xe8, 0xde, 0xa1, + 0xfa, 0x55, 0xa5, 0x67, 0x2f, 0x2a, 0x3d, 0xeb, 0x1c, 0x2d, 0x0a, 0xe5, + 0xed, 0xf6, 0x30, 0xe9, 0x7e, 0xc1, 0xfb, 0x7d, 0xcc, 0xd1, 0x49, 0x26, + 0xad, 0x9e, 0xa2, 0x65, 0xfd, 0xbe, 0x1c, 0x5c, 0x78, 0x58, 0x0e, 0x96, + 0xd9, 0xc7, 0x2e, 0xbc, 0x77, 0x51, 0xb6, 0x09, 0xba, 0x96, 0x3a, 0xfd, + 0xed, 0x50, 0x30, 0x96, 0x05, 0xfb, 0xb5, 0x1c, 0xba, 0xbb, 0x7e, 0x25, + 0x94, 0x5b, 0xe0, 0xde, 0x45, 0x79, 0xbd, 0x51, 0xe7, 0x1b, 0x7d, 0xff, + 0x0a, 0xc6, 0x34, 0x72, 0xee, 0x35, 0xe8, 0xd4, 0x69, 0xe2, 0x41, 0x2b, + 0xe7, 0x91, 0x7f, 0xb4, 0x2d, 0x8f, 0xd8, 0xc1, 0xfa, 0x0f, 0x81, 0x66, + 0xb4, 0x49, 0xa4, 0x21, 0xec, 0x61, 0x84, 0xfb, 0x97, 0xcf, 0xe2, 0x87, + 0x33, 0xdc, 0x83, 0x12, 0x09, 0x67, 0x80, 0x7f, 0xe3, 0xac, 0xb3, 0x0b, + 0x73, 0x0e, 0xf6, 0x77, 0x71, 0x65, 0x7f, 0x77, 0xcb, 0xc4, 0x42, 0x16, + 0x3a, 0x20, 0xaf, 0xfa, 0x89, 0xba, 0x6b, 0x6c, 0x0b, 0xea, 0x27, 0x35, + 0x1f, 0x36, 0x1b, 0xfd, 0x87, 0x32, 0x4f, 0x97, 0x35, 0x35, 0x94, 0x19, + 0x7e, 0x15, 0x30, 0x16, 0x6d, 0xc4, 0x88, 0xc6, 0x3d, 0xbe, 0x9f, 0x27, + 0x9f, 0xfb, 0xf7, 0x09, 0xf7, 0xc4, 0xa5, 0x72, 0xd1, 0x0e, 0x2b, 0xd9, + 0x5c, 0xfc, 0xd8, 0xaa, 0x6c, 0x02, 0x27, 0xab, 0x5e, 0x48, 0x5b, 0xce, + 0xa5, 0x15, 0xb4, 0x1c, 0xc2, 0x1a, 0x40, 0xb3, 0xce, 0x10, 0xe8, 0xd6, + 0x2a, 0x85, 0xfa, 0x2e, 0xfd, 0x8e, 0xe5, 0x11, 0x19, 0x8b, 0x1b, 0x3b, + 0xf4, 0xe7, 0x5b, 0x03, 0xac, 0x8b, 0x3a, 0xe5, 0xff, 0x1d, 0x0e, 0x64, + 0xdf, 0x96, 0xc2, 0xe9, 0x21, 0xc8, 0x18, 0xb1, 0xd8, 0x26, 0x2d, 0x63, + 0xec, 0x07, 0xe5, 0x67, 0x29, 0xc3, 0xa2, 0xf5, 0xe7, 0x20, 0xd2, 0x1f, + 0x87, 0x69, 0xb7, 0xd9, 0x57, 0xe1, 0xb4, 0x69, 0x6f, 0xe6, 0xd1, 0xb1, + 0xd2, 0xcf, 0x98, 0x67, 0x49, 0x58, 0xcd, 0x05, 0x65, 0x67, 0xd7, 0xce, + 0xc5, 0xea, 0x34, 0x73, 0x79, 0x34, 0x1c, 0xcc, 0xa5, 0xa3, 0xa1, 0xaf, + 0x78, 0xc3, 0x5c, 0x9a, 0x30, 0x97, 0xb8, 0xb2, 0x37, 0x9c, 0xcb, 0x05, + 0xf0, 0xbe, 0x70, 0xf6, 0xc6, 0xeb, 0x82, 0x36, 0xf1, 0x86, 0x36, 0x9d, + 0xeb, 0xda, 0xb0, 0xbe, 0x19, 0x03, 0xef, 0xce, 0x5e, 0xdd, 0x1c, 0xb4, + 0x61, 0xbd, 0x26, 0xd8, 0x37, 0xbe, 0x53, 0x7e, 0x5b, 0x83, 0xfc, 0x1f, + 0x84, 0xfc, 0x1b, 0xb9, 0x32, 0xb6, 0xd9, 0xf0, 0x75, 0x53, 0x28, 0x7f, + 0xf2, 0x03, 0xf4, 0x3d, 0x43, 0x63, 0xe5, 0x25, 0xf8, 0x0f, 0x49, 0x29, + 0xa4, 0xe1, 0x9b, 0xd8, 0x83, 0xa2, 0xfc, 0x89, 0x34, 0x7c, 0x16, 0x7b, + 0xb3, 0xc2, 0x5b, 0x85, 0x74, 0xbf, 0xb6, 0x59, 0xdf, 0x97, 0x09, 0xc8, + 0x70, 0x21, 0x9d, 0xc6, 0x78, 0xd0, 0xd5, 0x6e, 0x2f, 0xda, 0x71, 0xdc, + 0xb7, 0x22, 0xb4, 0x23, 0x17, 0xca, 0x1f, 0x47, 0x7e, 0x33, 0xde, 0xff, + 0xa9, 0x9e, 0x4f, 0x1b, 0xea, 0x7c, 0x5a, 0xf9, 0x26, 0x17, 0x54, 0x1d, + 0xf6, 0x71, 0x19, 0xf9, 0x3b, 0x50, 0x07, 0x9b, 0x1c, 0x12, 0x68, 0xb9, + 0x3b, 0xf1, 0xfb, 0x36, 0xca, 0x3e, 0x84, 0xb2, 0x2f, 0xa3, 0xec, 0x76, + 0xe4, 0x5f, 0x5c, 0xd7, 0xef, 0x36, 0xe4, 0x1f, 0xc3, 0x7b, 0xac, 0xd3, + 0xfe, 0x06, 0xde, 0xdf, 0x81, 0xdf, 0x97, 0xd7, 0xd5, 0xf9, 0x37, 0xeb, + 0xf2, 0xc6, 0x2f, 0xf8, 0x63, 0x2d, 0x73, 0xc6, 0x27, 0x08, 0xf4, 0xe8, + 0x54, 0xb9, 0x35, 0x34, 0x7c, 0x3a, 0x16, 0xda, 0x73, 0x9a, 0x78, 0x23, + 0xa2, 0xfc, 0x80, 0x08, 0xfc, 0x80, 0xe9, 0x39, 0x3a, 0x88, 0x11, 0x94, + 0x11, 0xbb, 0xcb, 0x40, 0x93, 0xf4, 0x78, 0x57, 0xb0, 0x4f, 0x0a, 0xb5, + 0x2e, 0xe4, 0xb9, 0x7f, 0x20, 0x63, 0xb5, 0x16, 0xc8, 0x75, 0x4f, 0xba, + 0x0a, 0x19, 0x3b, 0x00, 0xdf, 0x64, 0x02, 0x36, 0x70, 0xa2, 0xd6, 0x25, + 0x0f, 0xd4, 0xae, 0x44, 0x02, 0x39, 0x32, 0x63, 0x3f, 0xbd, 0x6e, 0xec, + 0x18, 0xfd, 0x0a, 0xc8, 0xfd, 0xfc, 0xe8, 0xfe, 0x39, 0x8e, 0x6f, 0x75, + 0x47, 0xa4, 0x0d, 0x73, 0xa0, 0xff, 0x28, 0xbd, 0x11, 0xe9, 0x49, 0x4e, + 0x29, 0x07, 0xb5, 0x28, 0xe1, 0x4c, 0x0f, 0xec, 0x83, 0xca, 0xc3, 0x5f, + 0x84, 0xbe, 0xab, 0xad, 0xfa, 0x91, 0xc3, 0x2b, 0x7e, 0x64, 0x17, 0xfc, + 0xcc, 0x17, 0x23, 0xc1, 0xde, 0x6f, 0x85, 0x6e, 0xb8, 0x9e, 0x38, 0x47, + 0xe9, 0x77, 0xee, 0xf1, 0x9c, 0xd7, 0xae, 0xf3, 0x94, 0x65, 0xe8, 0x0b, + 0x2b, 0xaa, 0xf4, 0x95, 0x58, 0x78, 0x37, 0x40, 0xf9, 0x45, 0x7e, 0xa1, + 0x71, 0x7f, 0xff, 0x0e, 0xf6, 0x32, 0xdf, 0x1b, 0x39, 0xc3, 0x3f, 0x4a, + 0xc6, 0x18, 0xbf, 0xf8, 0x8b, 0x75, 0x6b, 0x3b, 0xb0, 0x6e, 0x6d, 0x91, + 0x15, 0xba, 0x72, 0x8d, 0x51, 0xac, 0x71, 0x69, 0x8e, 0xb4, 0xed, 0x87, + 0x7c, 0x8a, 0x1b, 0x11, 0xca, 0x31, 0xf5, 0x6a, 0x1b, 0x74, 0x35, 0x69, + 0x17, 0x11, 0xc6, 0x3c, 0x26, 0xb0, 0xa6, 0x09, 0xac, 0x69, 0xa2, 0x81, + 0x8e, 0x07, 0x56, 0xd6, 0x64, 0xe6, 0x8d, 0x7a, 0x6a, 0xbf, 0xf1, 0x99, + 0x3f, 0xe8, 0xa9, 0x36, 0x83, 0x69, 0x38, 0x97, 0xdc, 0xba, 0xb9, 0x90, + 0x16, 0x9c, 0xcb, 0xca, 0x3c, 0xe2, 0x8c, 0x1c, 0x1d, 0xac, 0x91, 0xaf, + 0x1c, 0x73, 0xaf, 0x4c, 0x96, 0x3f, 0xa0, 0xe7, 0xd1, 0x8a, 0x79, 0x8c, + 0x41, 0x6f, 0x70, 0x3c, 0xec, 0xff, 0xda, 0x38, 0x9e, 0xe3, 0xe4, 0xbf, + 0x9e, 0x8b, 0xa1, 0x05, 0xfd, 0xb6, 0x84, 0xc6, 0xe2, 0x86, 0x5e, 0xae, + 0xc2, 0x0e, 0x97, 0xca, 0xff, 0x6d, 0x6b, 0x30, 0xb7, 0xa4, 0x9e, 0x47, + 0x40, 0x63, 0x60, 0x78, 0x60, 0xa9, 0xbc, 0xd6, 0x07, 0x8d, 0x74, 0xbd, + 0xbb, 0x49, 0xeb, 0x2b, 0xc8, 0x40, 0x63, 0xf9, 0xa7, 0x9a, 0x56, 0xeb, + 0x32, 0x3f, 0xaf, 0xf3, 0x5b, 0x42, 0xc3, 0x27, 0x4d, 0xd9, 0xd5, 0xa6, + 0x77, 0xf6, 0xf7, 0xd5, 0x26, 0xa3, 0x3f, 0x2e, 0x95, 0x1b, 0xf7, 0xfb, + 0x21, 0x2b, 0xb0, 0x3b, 0x45, 0x29, 0x0d, 0x64, 0xa1, 0xe7, 0x68, 0x7f, + 0x86, 0xac, 0xc0, 0xf6, 0xb0, 0xce, 0x21, 0x85, 0x1d, 0x23, 0x99, 0x2a, + 0xe5, 0x1e, 0xb4, 0xac, 0x8d, 0xe6, 0x66, 0x7c, 0x7f, 0xca, 0x5b, 0x4e, + 0x84, 0x85, 0x7a, 0x99, 0xb8, 0x8d, 0xe5, 0xcf, 0xa0, 0x1c, 0x76, 0xbd, + 0x3e, 0x26, 0x6c, 0xb7, 0x31, 0x3e, 0x4b, 0x6a, 0x7c, 0x16, 0x00, 0xbb, + 0x9c, 0xc2, 0x53, 0x4f, 0x8d, 0xc2, 0xfe, 0xeb, 0xe7, 0xa7, 0xf1, 0x9c, + 0x6c, 0xc4, 0x80, 0xe8, 0xb7, 0x32, 0x9a, 0x9b, 0x53, 0x76, 0x00, 0xfb, + 0x81, 0xbc, 0x3a, 0x03, 0x5e, 0x85, 0x64, 0x5a, 0xd9, 0x04, 0xce, 0x83, + 0xed, 0x2a, 0xa3, 0xdd, 0x8b, 0x4c, 0xab, 0xa3, 0xee, 0x62, 0x58, 0x0e, + 0xc4, 0x83, 0xb6, 0xcc, 0x27, 0x17, 0x8d, 0xdd, 0x6e, 0x91, 0x68, 0x86, + 0xba, 0xcd, 0x49, 0x03, 0x87, 0x62, 0x3d, 0x47, 0x47, 0xa7, 0x5d, 0xda, + 0xcb, 0xff, 0x03, 0x79, 0x68, 0x91, 0x26, 0x25, 0x27, 0x4f, 0xea, 0xb1, + 0xce, 0x60, 0xac, 0xad, 0x98, 0x6b, 0x18, 0x3a, 0x32, 0x92, 0xc0, 0x38, + 0x87, 0x2d, 0x77, 0x1b, 0xc6, 0xa3, 0xd7, 0xd8, 0x25, 0x53, 0x75, 0xca, + 0xfa, 0xdf, 0x44, 0x56, 0x7d, 0xc5, 0x13, 0x68, 0x67, 0x7c, 0x14, 0x8e, + 0x57, 0x05, 0x46, 0x69, 0xc1, 0x3a, 0x1c, 0x3b, 0x17, 0x86, 0xed, 0x9b, + 0x33, 0x75, 0x38, 0xa7, 0xe3, 0xa3, 0xa9, 0xc5, 0x14, 0xfa, 0xea, 0xa2, + 0xec, 0x41, 0xe6, 0xc2, 0xf8, 0xb1, 0x6f, 0xb6, 0x83, 0x4e, 0x1e, 0x34, + 0x76, 0x7c, 0xb5, 0xbd, 0x69, 0xd7, 0xbd, 0x38, 0xa2, 0x65, 0xf7, 0xaf, + 0xfc, 0xec, 0x38, 0xdf, 0x37, 0xc6, 0x07, 0x4c, 0x3b, 0x53, 0x27, 0xac, + 0xf5, 0xf1, 0x7d, 0xd1, 0xd5, 0x79, 0x3e, 0x35, 0x1a, 0xf8, 0x31, 0x12, + 0xc9, 0xf7, 0x0d, 0x6a, 0xbe, 0x3d, 0x8d, 0x32, 0xb6, 0xc7, 0x5e, 0xa8, + 0x37, 0x62, 0xf0, 0xa0, 0xdf, 0x22, 0xb0, 0x47, 0xa9, 0xdc, 0x04, 0x5d, + 0x93, 0x6d, 0x0f, 0x62, 0x22, 0xef, 0x85, 0xbb, 0xc1, 0x53, 0xf4, 0x53, + 0x5a, 0x69, 0xab, 0xe2, 0x93, 0xa3, 0x2f, 0xa1, 0xff, 0x23, 0xe5, 0x60, + 0xaf, 0x05, 0x74, 0x20, 0x5e, 0x0a, 0xc9, 0x92, 0x9b, 0x84, 0x7f, 0x47, + 0x3b, 0x94, 0x94, 0x97, 0x5d, 0x83, 0x9f, 0x88, 0x9d, 0x50, 0xbf, 0xce, + 0xf9, 0x70, 0xdd, 0x27, 0xb0, 0x6e, 0x5f, 0x66, 0xbd, 0x40, 0x3e, 0xfa, + 0xb0, 0x37, 0xff, 0x53, 0xc4, 0x39, 0x4a, 0x3f, 0xe0, 0x6a, 0xa4, 0x71, + 0x5d, 0xc6, 0x9e, 0x3d, 0xa5, 0x63, 0x93, 0x27, 0x34, 0x2f, 0x2b, 0xe0, + 0xe5, 0xb6, 0xa4, 0x2d, 0xbd, 0x98, 0x3b, 0xea, 0xf4, 0xf7, 0x00, 0x8f, + 0xd3, 0xd7, 0x4b, 0x60, 0x3e, 0x36, 0x64, 0x7d, 0xab, 0xb6, 0xfb, 0x9f, + 0x89, 0x52, 0x5f, 0xb4, 0xab, 0xb8, 0xe7, 0x09, 0x25, 0x6b, 0x81, 0xec, + 0x85, 0xf5, 0x7b, 0xc3, 0xef, 0x30, 0xcd, 0xae, 0xac, 0xc6, 0xf9, 0x8c, + 0xae, 0x66, 0xfd, 0x39, 0xd4, 0x0f, 0x61, 0x4d, 0xbe, 0x3f, 0xa9, 0xe6, + 0x3b, 0x0f, 0x5e, 0x87, 0xa5, 0xb4, 0x22, 0x8f, 0xf3, 0x90, 0xc7, 0x26, + 0x91, 0x8e, 0x46, 0xb9, 0xa1, 0xac, 0xbc, 0x1e, 0x65, 0x4c, 0x2e, 0x69, + 0x19, 0xde, 0x45, 0x88, 0xdd, 0x90, 0x37, 0xbc, 0xe3, 0xf3, 0x46, 0x18, + 0x90, 0x71, 0x27, 0xdf, 0x5f, 0xf2, 0x18, 0x23, 0x6c, 0x96, 0xa2, 0x1d, + 0xe0, 0x97, 0x92, 0x47, 0x39, 0xcd, 0x25, 0x23, 0xe2, 0x24, 0x0e, 0xc8, + 0x9b, 0xe8, 0x3b, 0x9b, 0x8e, 0x4a, 0xe0, 0xa7, 0x4e, 0x80, 0x6e, 0xcb, + 0xb6, 0xef, 0xbf, 0x04, 0xbf, 0xba, 0x0a, 0xbf, 0x66, 0x09, 0x69, 0xa9, + 0x86, 0x3d, 0xd0, 0x12, 0xc1, 0x9e, 0x32, 0x7b, 0x25, 0x26, 0x15, 0xd4, + 0x59, 0xc0, 0xbb, 0xc7, 0x6b, 0x86, 0xcb, 0xbe, 0x6f, 0x61, 0x5d, 0xfb, + 0xdd, 0xbf, 0xf6, 0x0b, 0xf1, 0xc6, 0xba, 0x06, 0x77, 0x11, 0x33, 0x11, + 0xf3, 0x10, 0xab, 0xf0, 0x1d, 0xf1, 0xc7, 0x61, 0xcc, 0x85, 0x32, 0xdc, + 0x26, 0xb1, 0x8c, 0x93, 0x18, 0x11, 0xa3, 0x8b, 0x5f, 0x03, 0xff, 0x8b, + 0x7e, 0xb3, 0xdb, 0x25, 0xcf, 0x83, 0xd7, 0xcf, 0xd5, 0x0d, 0xef, 0x93, + 0xe0, 0xbd, 0x53, 0x2c, 0x8a, 0x2f, 0x17, 0x3d, 0x37, 0xf9, 0x39, 0xa4, + 0xdf, 0xf1, 0x7e, 0x85, 0xb4, 0x78, 0x0a, 0x26, 0x0f, 0x38, 0x1b, 0x7a, + 0x75, 0xd6, 0xe0, 0xc7, 0x36, 0xe2, 0x7d, 0x4d, 0xc7, 0xab, 0xe8, 0xd3, + 0xb1, 0x2d, 0x80, 0xa5, 0x3b, 0x51, 0x2f, 0x90, 0x6b, 0x53, 0x76, 0x18, + 0x75, 0x39, 0x07, 0xfa, 0x62, 0xdf, 0xc5, 0x5e, 0xf2, 0xfd, 0x7b, 0xbd, + 0xc9, 0x86, 0x3d, 0x31, 0x0f, 0x1e, 0x28, 0xd9, 0x1c, 0x68, 0x17, 0xc6, + 0xee, 0xa4, 0xbf, 0x43, 0xf9, 0x0a, 0x7c, 0x86, 0x8c, 0x0e, 0xd0, 0x26, + 0x24, 0x55, 0xdc, 0x8f, 0xb6, 0xe7, 0x39, 0xd0, 0xfe, 0xd3, 0x35, 0xf2, + 0xa1, 0x55, 0xe9, 0xfe, 0xe7, 0xcb, 0xb4, 0xef, 0x01, 0x46, 0x9b, 0x50, + 0xb1, 0x5c, 0xda, 0x84, 0x34, 0x78, 0x13, 0xc4, 0xf0, 0x1e, 0x50, 0x6d, + 0x59, 0x8f, 0x6d, 0x1b, 0xf9, 0xc7, 0x3a, 0x5b, 0x81, 0xaf, 0x28, 0x83, + 0x6d, 0xc0, 0x25, 0xed, 0x72, 0x20, 0xdd, 0x0c, 0xba, 0x77, 0x28, 0x3c, + 0x65, 0xb9, 0x1f, 0x86, 0xed, 0x02, 0xa6, 0xb3, 0x1d, 0x6f, 0xd5, 0xf7, + 0xb8, 0x1d, 0x65, 0x3f, 0x05, 0xfd, 0x59, 0xb6, 0x49, 0xc7, 0xaf, 0x1f, + 0xc6, 0xfe, 0xab, 0x6c, 0x0d, 0xe2, 0x22, 0xe4, 0x83, 0xd1, 0x03, 0xc6, + 0xfe, 0xd9, 0x1a, 0x47, 0x92, 0x37, 0x41, 0x0c, 0xc5, 0x52, 0x75, 0x89, + 0xe7, 0x1b, 0xfd, 0x16, 0xee, 0x3b, 0xdf, 0xbf, 0xe8, 0x29, 0x7b, 0x0a, + 0x1e, 0xec, 0x86, 0x0d, 0x8b, 0x68, 0x5a, 0xb7, 0x82, 0xd6, 0x81, 0x8d, + 0x4d, 0x76, 0x40, 0xef, 0xb8, 0x56, 0x53, 0x40, 0x3f, 0x62, 0x85, 0xbf, + 0x85, 0x1f, 0x4f, 0xff, 0x81, 0x38, 0x81, 0x73, 0x47, 0xbb, 0x05, 0xd6, + 0xa5, 0x2d, 0x7e, 0x0c, 0x63, 0x84, 0x25, 0xd9, 0xc9, 0xfc, 0x03, 0xba, + 0x0d, 0x9f, 0x7d, 0xe9, 0xdd, 0xd1, 0x28, 0xcf, 0x83, 0x98, 0x27, 0xd7, + 0x63, 0xe2, 0x7a, 0x5d, 0x4a, 0x07, 0xac, 0xca, 0x85, 0x99, 0x93, 0x19, + 0x97, 0x73, 0x4b, 0x48, 0x07, 0xe6, 0x76, 0x37, 0x74, 0xf4, 0x8e, 0x0e, + 0xf6, 0x69, 0xc6, 0x6e, 0x9c, 0x93, 0xc1, 0x2f, 0x81, 0xdd, 0x8d, 0xba, + 0xcd, 0xb2, 0xa3, 0x93, 0xb4, 0xeb, 0x52, 0xba, 0x7a, 0x95, 0x1f, 0xb4, + 0xbf, 0x1c, 0x7b, 0x7d, 0xf9, 0x1d, 0x0d, 0xf3, 0x6a, 0x3c, 0x03, 0x20, + 0x76, 0xd8, 0x89, 0x77, 0x9c, 0x13, 0x9c, 0xe4, 0xb8, 0x2f, 0x7b, 0x14, + 0xdd, 0x38, 0xb7, 0xc6, 0x79, 0x10, 0x43, 0x71, 0xce, 0x9c, 0xc3, 0x7a, + 0x6c, 0xc2, 0xf9, 0xfc, 0x57, 0xcd, 0xc3, 0x4d, 0x7a, 0x5d, 0x06, 0xcb, + 0xa4, 0xd0, 0xf6, 0x3f, 0x60, 0x0d, 0x7c, 0xe6, 0x3a, 0x8c, 0xcd, 0x4e, + 0x05, 0xfd, 0xb4, 0x98, 0x78, 0xb0, 0x89, 0x6b, 0x70, 0x5e, 0xdc, 0x33, + 0x86, 0x4e, 0x1d, 0x9a, 0x47, 0xbb, 0xd7, 0x8d, 0xeb, 0x78, 0x6b, 0xf5, + 0xc8, 0xed, 0x0d, 0xeb, 0xeb, 0x97, 0xe2, 0x02, 0xe5, 0xe2, 0x36, 0xa4, + 0x06, 0x13, 0x0c, 0x40, 0xf7, 0xbf, 0x2b, 0x26, 0xe0, 0x59, 0xd5, 0x78, + 0x01, 0x3e, 0x99, 0xd2, 0xfd, 0x6a, 0x2f, 0xc6, 0x90, 0x87, 0x3e, 0xa9, + 0xdf, 0x43, 0x19, 0x1b, 0x9f, 0xa8, 0x79, 0xe3, 0x93, 0xb5, 0x81, 0x71, + 0xe2, 0xa9, 0x40, 0xe6, 0x50, 0xbf, 0x26, 0x13, 0xf0, 0xb3, 0xc7, 0x73, + 0xaa, 0x9d, 0x8a, 0x31, 0x6c, 0xd0, 0x8f, 0x70, 0x3f, 0x4e, 0x04, 0x63, + 0xc5, 0xc6, 0xf3, 0xd0, 0x41, 0x0b, 0xb3, 0xb0, 0x4b, 0xae, 0x93, 0xa5, + 0x5c, 0xee, 0xf7, 0x9c, 0x11, 0x25, 0x7b, 0x71, 0x67, 0x8c, 0xbc, 0xac, + 0xce, 0xfe, 0xb2, 0x2c, 0xcc, 0xf9, 0x72, 0x17, 0x74, 0xe1, 0x43, 0x90, + 0x55, 0x39, 0x07, 0x45, 0x78, 0x0e, 0xca, 0xeb, 0x5c, 0x5c, 0xac, 0x53, + 0x5d, 0x12, 0x3d, 0x96, 0x90, 0xc8, 0x31, 0x62, 0xcb, 0x94, 0x7d, 0x97, + 0x08, 0xec, 0xd8, 0x8b, 0x1f, 0xb2, 0xc4, 0x19, 0xcc, 0x4a, 0x2a, 0xf9, + 0x38, 0x6c, 0x6f, 0x15, 0x69, 0x49, 0x52, 0xe9, 0xb3, 0xe8, 0x2b, 0x7a, + 0x0e, 0x75, 0xd1, 0x6e, 0xd3, 0x52, 0x12, 0xbf, 0x4e, 0x69, 0x59, 0x0a, + 0xf6, 0x4a, 0xcb, 0xd2, 0x5a, 0xff, 0x7c, 0x68, 0xc5, 0x3f, 0xe7, 0xfb, + 0xb7, 0x75, 0x5c, 0xe1, 0x8b, 0xfa, 0x8c, 0x81, 0x32, 0x42, 0x7b, 0xa4, + 0x7c, 0x63, 0xe8, 0xfd, 0x2f, 0xc2, 0xc7, 0x02, 0x0e, 0x2c, 0xc3, 0x97, + 0xca, 0xf8, 0xf2, 0xac, 0x57, 0xf4, 0x73, 0x03, 0xbe, 0xbc, 0xe6, 0xb9, + 0xc5, 0x82, 0x38, 0x6f, 0x53, 0xdf, 0xfd, 0x85, 0xf7, 0x4f, 0xe4, 0xfe, + 0x76, 0xe7, 0xfe, 0x6c, 0xa8, 0xe8, 0xb7, 0xc2, 0xb7, 0xba, 0x31, 0x73, + 0x58, 0xf6, 0x6f, 0x5f, 0x86, 0x0f, 0x9c, 0xbd, 0x11, 0x38, 0x2b, 0x51, + 0x50, 0xba, 0xea, 0x75, 0xe5, 0xb7, 0x7d, 0xa2, 0xe7, 0xb0, 0x6c, 0xd9, + 0xee, 0xd8, 0xd7, 0xc2, 0xc4, 0x40, 0x87, 0x25, 0x0f, 0xfd, 0x9f, 0x0f, + 0xbb, 0xf6, 0x5e, 0x71, 0x46, 0x1e, 0x11, 0x9e, 0x0d, 0xba, 0xd2, 0x7d, + 0xcc, 0x4d, 0x7c, 0x32, 0xd4, 0x7b, 0xf0, 0x93, 0xc0, 0xae, 0xdd, 0xe7, + 0x98, 0xf7, 0x25, 0xb6, 0xdd, 0xc6, 0x73, 0x5c, 0xba, 0x4f, 0x25, 0x25, + 0x05, 0xba, 0xf4, 0x29, 0x9a, 0xf0, 0x6c, 0x22, 0x21, 0xbd, 0xc7, 0x88, + 0x49, 0x14, 0x6d, 0xfa, 0x40, 0x9b, 0x34, 0x68, 0x03, 0x9f, 0x66, 0x9b, + 0x7d, 0x0d, 0xe9, 0x65, 0x49, 0x0d, 0x7e, 0x0f, 0xb4, 0xe9, 0x03, 0x6d, + 0x7a, 0xcf, 0x25, 0xd1, 0x1e, 0x7d, 0x2c, 0x75, 0x23, 0x6d, 0x91, 0x5f, + 0xbb, 0xbe, 0x13, 0xcf, 0xae, 0xa4, 0x8e, 0xc5, 0x30, 0x46, 0x48, 0xf6, + 0xf4, 0x14, 0x65, 0x78, 0x3b, 0x30, 0x74, 0xfc, 0xb0, 0x5c, 0x81, 0x1d, + 0x2a, 0xc3, 0x7f, 0x7b, 0x76, 0xd0, 0x19, 0x5b, 0x86, 0x2e, 0xad, 0xdf, + 0xed, 0xcb, 0x37, 0xb6, 0x7f, 0xd3, 0x4f, 0x5c, 0xef, 0xdc, 0x2f, 0xa1, + 0x01, 0x99, 0x2e, 0x2b, 0xfb, 0x90, 0xc8, 0x85, 0x15, 0xd6, 0xc1, 0x1a, + 0x8b, 0xb0, 0x31, 0x3c, 0xf3, 0x74, 0xa1, 0xeb, 0x1f, 0x91, 0x87, 0x2a, + 0x53, 0xf8, 0x01, 0x77, 0xcf, 0xb0, 0xee, 0x41, 0xe0, 0xed, 0x87, 0xe5, + 0xc0, 0x0c, 0xb0, 0x58, 0x06, 0xf3, 0x1e, 0x70, 0x81, 0xcb, 0x33, 0xcd, + 0xd2, 0x86, 0x32, 0xd0, 0x76, 0xac, 0xbe, 0x1e, 0xd7, 0x2e, 0x83, 0x0f, + 0x83, 0xf2, 0x27, 0xf5, 0x01, 0xf9, 0x4a, 0xbd, 0x5f, 0xbe, 0x04, 0xdb, + 0xf2, 0x5c, 0xbd, 0x0b, 0x7b, 0x25, 0x01, 0x9e, 0x64, 0xc0, 0x1f, 0x4f, + 0xbe, 0x5c, 0x4f, 0xcb, 0x17, 0x41, 0xab, 0xe7, 0xf1, 0x1b, 0x2e, 0xa7, + 0x65, 0x4f, 0xb9, 0x5f, 0xf3, 0x88, 0xfc, 0x71, 0x31, 0x1f, 0x17, 0x6b, + 0x77, 0x9e, 0x29, 0x62, 0xff, 0x2d, 0xd4, 0xdd, 0xb7, 0xaa, 0x34, 0xb2, + 0x6d, 0xb6, 0x9c, 0x59, 0xb1, 0x2f, 0x45, 0xdf, 0x76, 0x9d, 0xa3, 0x13, + 0xe0, 0x43, 0x15, 0xfb, 0x74, 0x4c, 0xd1, 0x7e, 0xd5, 0xf6, 0x54, 0x03, + 0xdb, 0x63, 0xd6, 0x37, 0x5b, 0x90, 0xef, 0x48, 0xee, 0xc4, 0xb4, 0xec, + 0x3f, 0xe9, 0xcb, 0x6f, 0x7a, 0x3e, 0xe4, 0x98, 0xba, 0x78, 0x80, 0x3a, + 0x3e, 0x39, 0x11, 0xb6, 0x94, 0x9f, 0x1b, 0x60, 0x8d, 0xef, 0x75, 0x60, + 0xcf, 0xa6, 0xb3, 0xd6, 0x94, 0xa4, 0x4e, 0x4c, 0x49, 0xf7, 0x09, 0xc8, + 0x82, 0xc7, 0xbe, 0x96, 0x6d, 0xeb, 0x1d, 0xf2, 0xc0, 0x71, 0x9c, 0xc1, + 0xbc, 0xb8, 0xf6, 0x5b, 0x92, 0xc6, 0xf8, 0x87, 0xa4, 0x07, 0x6d, 0x5c, + 0xb4, 0xb9, 0xa6, 0xc6, 0x6e, 0xc5, 0xd8, 0xcd, 0x72, 0x24, 0xee, 0x40, + 0xd6, 0x68, 0xc3, 0xff, 0xaf, 0xe4, 0xaa, 0x4c, 0x7f, 0x24, 0xb9, 0x33, + 0x6f, 0x37, 0x4b, 0x0b, 0x9f, 0xa1, 0x1a, 0xe6, 0x59, 0xde, 0x8d, 0x94, + 0xe5, 0xae, 0x58, 0xc7, 0x7f, 0x22, 0xb9, 0xf3, 0x1c, 0xfb, 0x2d, 0x94, + 0x7f, 0x43, 0x72, 0xc7, 0x7f, 0x8a, 0xfc, 0x15, 0xa4, 0x6f, 0x23, 0x1d, + 0x93, 0xee, 0xe3, 0xf0, 0x91, 0xcf, 0x7f, 0x1b, 0x79, 0xf8, 0x74, 0xe7, + 0x8f, 0xa0, 0xde, 0x6e, 0xcc, 0xef, 0xde, 0x18, 0xb0, 0x06, 0x74, 0x5e, + 0xec, 0xba, 0x60, 0xfe, 0x2c, 0x67, 0x19, 0xdf, 0x1d, 0x81, 0x4e, 0xfb, + 0x1f, 0xd0, 0x69, 0xfa, 0x79, 0x81, 0x79, 0xea, 0x36, 0x3e, 0x4f, 0x81, + 0x26, 0x87, 0x90, 0xf7, 0xe5, 0x61, 0x8f, 0xf6, 0x66, 0xa7, 0x8c, 0xdb, + 0x45, 0xbf, 0x05, 0xb8, 0xa2, 0x15, 0xfb, 0x60, 0x6a, 0xc7, 0xc6, 0xfb, + 0xe0, 0x68, 0xef, 0x61, 0xd9, 0xb4, 0xdd, 0xac, 0xdf, 0xac, 0xd7, 0xb5, + 0x7f, 0xa8, 0xe8, 0xe0, 0x14, 0x3f, 0x29, 0x5c, 0x87, 0x9b, 0x78, 0xd2, + 0xea, 0xbd, 0xff, 0x21, 0xec, 0x03, 0xeb, 0x3c, 0xf3, 0xc1, 0x3e, 0xb0, + 0xce, 0x43, 0x37, 0xcc, 0xc3, 0x47, 0x9b, 0xef, 0x92, 0xe6, 0xe3, 0xab, + 0xfb, 0xa0, 0xe9, 0xf8, 0xcf, 0xdf, 0x07, 0xcd, 0xe7, 0x51, 0xef, 0x3c, + 0x69, 0x86, 0x3e, 0xce, 0x90, 0x66, 0x9d, 0x48, 0x1f, 0xc1, 0x5a, 0x39, + 0xf7, 0x66, 0xcc, 0x3d, 0xc0, 0x45, 0x1f, 0x82, 0xbc, 0x7f, 0x62, 0xfb, + 0x21, 0x5d, 0xfe, 0x9f, 0xfd, 0x91, 0xb8, 0x53, 0x91, 0x10, 0x69, 0x8a, + 0xba, 0x55, 0xd2, 0xf0, 0x79, 0xd0, 0xe6, 0xa0, 0x74, 0x93, 0x7e, 0xd5, + 0xbd, 0xc8, 0x17, 0xfd, 0x28, 0x7d, 0x74, 0x45, 0x4f, 0xe0, 0xa4, 0x01, + 0x96, 0xbf, 0x0a, 0x99, 0x21, 0xc6, 0x7c, 0x5d, 0xf6, 0xcf, 0xf8, 0x32, + 0xee, 0x71, 0xfd, 0x6f, 0x62, 0xfd, 0xd9, 0xed, 0x71, 0x59, 0x4e, 0xc6, + 0x41, 0x93, 0x05, 0xe8, 0xf6, 0x2b, 0x12, 0xd0, 0x81, 0x31, 0xe7, 0x3d, + 0xe2, 0x26, 0x86, 0xc5, 0x4d, 0x7f, 0x0f, 0x74, 0x18, 0x86, 0xec, 0xe7, + 0xeb, 0x94, 0x9d, 0x57, 0x64, 0x08, 0x32, 0xf1, 0x86, 0xe7, 0xa4, 0x81, + 0x85, 0xa0, 0x2f, 0x28, 0x17, 0x94, 0x89, 0x36, 0xa5, 0x93, 0xe6, 0x3d, + 0xe7, 0xa9, 0xaa, 0xdc, 0x2a, 0xf3, 0x0a, 0x9b, 0xe2, 0xdd, 0x71, 0x65, + 0x2f, 0xd2, 0x13, 0x56, 0x0f, 0x74, 0x74, 0x5a, 0xec, 0xde, 0x9b, 0x9b, + 0xcd, 0x3d, 0x85, 0xc2, 0x89, 0x90, 0x4c, 0xf5, 0x92, 0x57, 0xec, 0x17, + 0xf9, 0x6a, 0xd1, 0x8f, 0xb8, 0x6f, 0xf9, 0xa7, 0x3b, 0x93, 0xf2, 0xe9, + 0xde, 0x15, 0xb9, 0xac, 0x88, 0x04, 0xfb, 0x62, 0x48, 0xf1, 0xc3, 0xcc, + 0xdb, 0xac, 0xc5, 0xbc, 0xeb, 0x6f, 0x78, 0xc7, 0xb5, 0x50, 0xd6, 0x57, + 0xf6, 0x4e, 0xf2, 0x9d, 0x73, 0xfd, 0x5d, 0xd0, 0xcc, 0x79, 0xaa, 0x24, + 0xaf, 0x41, 0xf6, 0x40, 0xc3, 0xf3, 0x4c, 0x49, 0xc3, 0x29, 0xc8, 0xfd, + 0xab, 0xb2, 0xe7, 0x04, 0xf7, 0xcc, 0xab, 0x58, 0xab, 0xd2, 0x25, 0xd0, + 0x11, 0xec, 0xcf, 0x97, 0x69, 0x8f, 0xb1, 0x92, 0x5b, 0x13, 0x93, 0xf0, + 0xe1, 0x26, 0x6c, 0x5f, 0x96, 0xbc, 0xa2, 0x2c, 0x0d, 0xa2, 0x4d, 0xf5, + 0x11, 0xfc, 0xda, 0xf4, 0xda, 0x3e, 0x0b, 0xba, 0x3b, 0xc9, 0x8a, 0xf5, + 0x19, 0xd0, 0xfd, 0x61, 0x49, 0x1d, 0x5f, 0xd1, 0x35, 0x90, 0xbb, 0x40, + 0xd7, 0xa4, 0xce, 0xdb, 0x52, 0x2d, 0xbb, 0xf2, 0x71, 0xea, 0x90, 0x32, + 0xd7, 0x05, 0x1d, 0xc3, 0xf3, 0xdb, 0x32, 0xf4, 0x4c, 0x19, 0x3a, 0x05, + 0x3a, 0xe4, 0x4b, 0x28, 0xff, 0x22, 0xea, 0x3c, 0x0f, 0x9f, 0xe7, 0x39, + 0x60, 0xbf, 0x8b, 0xc0, 0x14, 0x17, 0xca, 0x59, 0xed, 0x1b, 0xaa, 0xf5, + 0xc2, 0x66, 0x29, 0x7f, 0x45, 0xaa, 0x15, 0xd2, 0xe3, 0x27, 0x8a, 0xb7, + 0x39, 0x6f, 0x2b, 0x71, 0x16, 0x66, 0x26, 0x52, 0xa9, 0x18, 0x9a, 0x50, + 0xf7, 0x31, 0xf6, 0x6f, 0x74, 0x65, 0xeb, 0x3a, 0x5d, 0x29, 0xf2, 0x62, + 0x2d, 0xc0, 0x93, 0xc4, 0xc7, 0xa5, 0x99, 0xe4, 0xca, 0x19, 0x59, 0x09, + 0x76, 0xf3, 0x32, 0xfc, 0x92, 0x58, 0xe6, 0x5b, 0x12, 0x3b, 0xe5, 0xfb, + 0xdf, 0x87, 0xdd, 0x2c, 0x82, 0x27, 0x56, 0x08, 0xe5, 0x8b, 0x7c, 0x47, + 0xb9, 0xa7, 0x6c, 0x87, 0x18, 0x2b, 0x97, 0x97, 0x51, 0x56, 0x55, 0x3e, + 0xd3, 0xb7, 0x31, 0x1f, 0x3d, 0x3f, 0x55, 0xc6, 0x7a, 0xcd, 0x92, 0x1f, + 0x4f, 0xcb, 0xe3, 0xe5, 0x6d, 0x76, 0x33, 0xda, 0x57, 0x16, 0xd9, 0xc6, + 0x19, 0xe4, 0x95, 0x9d, 0x97, 0x17, 0x59, 0xde, 0x25, 0x57, 0x66, 0x32, + 0x6a, 0x0e, 0xd5, 0xb9, 0x8c, 0x04, 0x31, 0x49, 0xea, 0x2b, 0xce, 0x15, + 0x79, 0xfa, 0x96, 0x65, 0xda, 0xd9, 0x88, 0x14, 0x13, 0xa4, 0x75, 0x42, + 0x2e, 0xcf, 0xc4, 0x37, 0x31, 0x86, 0x93, 0x73, 0xf9, 0x6c, 0x62, 0x07, + 0xf6, 0xfb, 0x88, 0x1d, 0x30, 0x5e, 0x10, 0x81, 0x2d, 0x53, 0x31, 0x04, + 0xa4, 0xc9, 0x06, 0x9f, 0x95, 0xef, 0x03, 0x6c, 0xb4, 0x8a, 0x1f, 0x89, + 0x27, 0xb9, 0x5e, 0xa7, 0xb8, 0x0c, 0xfd, 0xd1, 0x91, 0x79, 0x49, 0xee, + 0x99, 0x0f, 0xd6, 0x67, 0x9d, 0x11, 0xde, 0xd3, 0x90, 0x6b, 0x73, 0x8e, + 0x77, 0x15, 0x98, 0x22, 0x1f, 0xf7, 0xc0, 0xaf, 0x3f, 0x8b, 0x41, 0x7f, + 0x0d, 0x66, 0xad, 0x3d, 0x9b, 0x02, 0x7c, 0x16, 0x91, 0xa9, 0x19, 0x9e, + 0xa9, 0x41, 0xb7, 0x01, 0x43, 0xfe, 0xf3, 0x08, 0x9e, 0x6b, 0xcc, 0xc3, + 0x4f, 0x0b, 0x7c, 0x50, 0x3c, 0x07, 0xfd, 0x91, 0xe6, 0xd6, 0x3c, 0xd7, + 0x1e, 0x92, 0x7b, 0x80, 0x4e, 0x04, 0xfd, 0x77, 0xeb, 0xb1, 0xba, 0xcf, + 0xa4, 0x19, 0xc3, 0x93, 0x14, 0xf4, 0x45, 0x6e, 0x2e, 0x82, 0xb1, 0xba, + 0x34, 0x36, 0xe7, 0xbb, 0xf5, 0xd8, 0xd3, 0xf8, 0x78, 0x69, 0x79, 0xa2, + 0x6c, 0xb0, 0x5e, 0x1a, 0x36, 0x56, 0x22, 0x23, 0x7d, 0xbe, 0x7c, 0xdf, + 0x23, 0xbd, 0xfa, 0x91, 0xf7, 0xe4, 0x68, 0xfd, 0xdd, 0xce, 0xce, 0x1a, + 0xff, 0x5a, 0x31, 0x47, 0xfe, 0x30, 0x3f, 0xe0, 0x23, 0xce, 0xdd, 0x82, + 0x3d, 0x2f, 0x01, 0x77, 0x59, 0xe7, 0xba, 0xd4, 0x3b, 0x0b, 0xd8, 0xa0, + 0x3a, 0x03, 0xdd, 0x78, 0x8e, 0xe7, 0x89, 0xd0, 0x6d, 0xe7, 0xa2, 0x52, + 0x9a, 0xa5, 0x5c, 0x4a, 0x87, 0x05, 0x7e, 0xb1, 0x7e, 0x75, 0xa6, 0x0b, + 0x69, 0x2b, 0xd2, 0xa4, 0xea, 0xa7, 0x3a, 0xe3, 0xaa, 0xf6, 0xd5, 0x99, + 0xb4, 0x6a, 0x57, 0x9d, 0xe9, 0x47, 0xea, 0x49, 0xd3, 0x39, 0x38, 0x4e, + 0xe7, 0x7a, 0x65, 0xea, 0x34, 0xec, 0xcb, 0x80, 0xa5, 0xce, 0xe2, 0x27, + 0x60, 0x7f, 0x22, 0xf0, 0xb2, 0xae, 0xda, 0x83, 0xc0, 0x58, 0x3b, 0x81, + 0x41, 0x76, 0x8a, 0x7b, 0x8a, 0xeb, 0xa7, 0xee, 0xbd, 0xcc, 0x78, 0x52, + 0xe2, 0x41, 0xc9, 0xca, 0x81, 0xd9, 0x66, 0xec, 0xd7, 0x88, 0x5d, 0x92, + 0x1e, 0x7b, 0x18, 0xf9, 0x42, 0x85, 0x74, 0xbb, 0x4f, 0xf9, 0x6e, 0x39, + 0xef, 0x1c, 0x78, 0x92, 0xc1, 0x18, 0xef, 0xa7, 0x7d, 0x1f, 0xe4, 0xcf, + 0xd5, 0x7d, 0x64, 0x30, 0x9f, 0x46, 0x7a, 0xf0, 0x1c, 0x31, 0xfb, 0x73, + 0xce, 0x11, 0x29, 0xd7, 0xa4, 0xef, 0x7d, 0x72, 0xd9, 0xcd, 0xc8, 0xcb, + 0x6e, 0x5a, 0xae, 0xb8, 0x3b, 0xe4, 0xeb, 0xb0, 0xd3, 0x2f, 0xb9, 0x7d, + 0x9b, 0x88, 0x05, 0xaa, 0xea, 0x6c, 0xc6, 0xf0, 0xca, 0xd5, 0xf1, 0xc4, + 0x1f, 0xc8, 0xd2, 0x0c, 0xb1, 0xb3, 0xbf, 0x7b, 0xbf, 0x57, 0xa4, 0xdd, + 0xc2, 0x1c, 0x88, 0xd5, 0x8a, 0xb0, 0x7f, 0x87, 0x65, 0xd8, 0xa3, 0xdd, + 0x53, 0x36, 0x2a, 0x31, 0x1c, 0xec, 0x67, 0xaf, 0x00, 0xbd, 0x7a, 0x79, + 0x16, 0xfb, 0x49, 0x28, 0xff, 0x78, 0xae, 0x90, 0xef, 0xae, 0x3c, 0x59, + 0xe6, 0x3a, 0x4b, 0xd7, 0xb5, 0x48, 0x58, 0x46, 0x14, 0x5e, 0x68, 0x93, + 0x17, 0x17, 0x37, 0x8b, 0x05, 0x0b, 0x65, 0xdd, 0x12, 0x55, 0xb7, 0x18, + 0xe8, 0x7f, 0x4b, 0x3b, 0xef, 0x22, 0xbd, 0x05, 0xda, 0x30, 0x16, 0x80, + 0xb5, 0xb5, 0x73, 0x25, 0x26, 0xdf, 0x8f, 0xfd, 0xf5, 0x96, 0xda, 0x6b, + 0x79, 0x37, 0x8e, 0x67, 0xa6, 0xdc, 0x73, 0x8c, 0x3b, 0x85, 0x75, 0xfc, + 0xf7, 0xaf, 0xd4, 0xfb, 0x66, 0x77, 0x17, 0x70, 0x1d, 0xe5, 0x15, 0xe9, + 0x52, 0x30, 0x6e, 0x1e, 0x38, 0xae, 0xd0, 0xcf, 0x3b, 0x14, 0x4e, 0xba, + 0x88, 0xbd, 0x30, 0xa1, 0xea, 0xef, 0xc4, 0x7e, 0xda, 0xd4, 0x42, 0xfc, + 0xb0, 0x07, 0xb2, 0xf8, 0xd2, 0x0c, 0x9f, 0xf9, 0x9e, 0xfe, 0x15, 0xe3, + 0x6b, 0x17, 0x46, 0xa7, 0xdd, 0xdf, 0xd2, 0xfb, 0x47, 0x42, 0x77, 0xf5, + 0x01, 0x87, 0x1e, 0x6b, 0xc2, 0x5a, 0x9c, 0x64, 0x32, 0x64, 0x75, 0x5a, + 0xc0, 0xf1, 0xc3, 0xca, 0xe6, 0xf6, 0x61, 0xfe, 0x69, 0x39, 0x93, 0x6e, + 0x93, 0xaa, 0xed, 0xaa, 0x3b, 0x57, 0xcb, 0xf6, 0x76, 0x62, 0x7d, 0xfc, + 0x36, 0xa1, 0xac, 0x07, 0x69, 0x33, 0xd2, 0xdb, 0xa4, 0x74, 0xb2, 0xaf, + 0x25, 0xe8, 0x2f, 0xba, 0x2e, 0xff, 0x75, 0x3d, 0xce, 0x5f, 0x6a, 0x7f, + 0x8a, 0xe3, 0x44, 0xc5, 0xfd, 0x7c, 0xab, 0xf4, 0x1c, 0xb3, 0x81, 0x6d, + 0x13, 0xc0, 0xba, 0x5d, 0x92, 0x3e, 0x96, 0x94, 0x5b, 0x8e, 0x99, 0x38, + 0xd1, 0x97, 0x47, 0x53, 0x2a, 0x66, 0xf8, 0xa5, 0x51, 0xb7, 0xa2, 0xce, + 0x53, 0xf5, 0xdd, 0xb0, 0x65, 0x7d, 0x67, 0xec, 0x1b, 0xa3, 0x7d, 0x2a, + 0xfd, 0xf6, 0x68, 0x5a, 0xa5, 0xaf, 0x8c, 0xde, 0x52, 0x0b, 0xfc, 0xa3, + 0xd2, 0x42, 0x5a, 0x3e, 0x57, 0x26, 0xbe, 0x1c, 0x00, 0x76, 0xf4, 0xa0, + 0x67, 0xfa, 0xa1, 0x67, 0xd2, 0xd0, 0x33, 0x83, 0xd4, 0x33, 0xd0, 0xdb, + 0xaf, 0x40, 0x6f, 0x7b, 0xf2, 0x06, 0xe4, 0xf5, 0x82, 0xd7, 0x0c, 0x5c, + 0xe8, 0xfb, 0xc1, 0x5a, 0x9d, 0xa7, 0x96, 0xc1, 0xdf, 0xea, 0x59, 0x89, + 0xb5, 0x43, 0x07, 0x6d, 0x9f, 0x6f, 0x92, 0x85, 0xb8, 0xef, 0x9f, 0xf0, + 0x5c, 0xb9, 0x86, 0xfa, 0x39, 0x97, 0xfb, 0x78, 0xa2, 0x85, 0xfe, 0xd8, + 0xb5, 0x99, 0x1d, 0xd0, 0x49, 0x94, 0xf7, 0x98, 0x54, 0xc7, 0x13, 0xb2, + 0x08, 0xff, 0x6c, 0xb5, 0x4e, 0x1a, 0xcf, 0xdc, 0xff, 0xff, 0x12, 0x75, + 0xd3, 0xb0, 0x0f, 0xb6, 0x2c, 0xf5, 0x25, 0xe5, 0x4c, 0x9f, 0x33, 0x98, + 0xb4, 0xa8, 0xbb, 0x92, 0x52, 0x81, 0xaf, 0x5f, 0x2d, 0xb3, 0x3e, 0xeb, + 0x61, 0x7f, 0x96, 0x83, 0x76, 0xd3, 0x65, 0xa3, 0x27, 0x20, 0x9f, 0x73, + 0x8c, 0x03, 0x06, 0x36, 0xc0, 0xb2, 0x9a, 0x21, 0x07, 0x1e, 0xe8, 0x3f, + 0x8e, 0xf2, 0x01, 0xde, 0x25, 0x40, 0x19, 0xb1, 0x50, 0x49, 0xf1, 0x38, + 0xef, 0x8d, 0xa3, 0x8c, 0x6d, 0x9c, 0x44, 0x0a, 0xe5, 0x63, 0x92, 0x4a, + 0x14, 0xd4, 0xbd, 0xa6, 0x4e, 0x94, 0xb1, 0x8f, 0xb0, 0x8e, 0xc7, 0xcc, + 0xb6, 0x50, 0x8e, 0xc2, 0xae, 0x29, 0xdf, 0xa6, 0x62, 0x03, 0x59, 0xdb, + 0xc3, 0x7e, 0x60, 0x59, 0xca, 0x66, 0xbb, 0xbc, 0xe7, 0x29, 0x5d, 0x78, + 0xaf, 0x3e, 0xb7, 0xb8, 0xa7, 0xd6, 0x2a, 0xf9, 0x5a, 0xd3, 0x7b, 0xe8, + 0x7f, 0xb3, 0x27, 0x2f, 0x27, 0x6c, 0xe1, 0x19, 0x7b, 0xb0, 0xcf, 0x23, + 0x3b, 0xb8, 0x27, 0x40, 0x77, 0xd8, 0xdf, 0xe7, 0xb1, 0xde, 0xe7, 0x60, + 0x7f, 0x2f, 0xc2, 0xfe, 0x5e, 0x28, 0xaf, 0xea, 0x8f, 0xc0, 0xee, 0x52, + 0x07, 0x3c, 0x03, 0x9e, 0x8d, 0x01, 0xf7, 0xef, 0x85, 0x3f, 0x30, 0x02, + 0xec, 0x3f, 0x04, 0xfe, 0x65, 0xc0, 0xbb, 0x71, 0xde, 0x45, 0x01, 0x1f, + 0x07, 0xd5, 0x59, 0xe6, 0xac, 0x3a, 0xcf, 0xff, 0x81, 0xb2, 0xbd, 0x8f, + 0x97, 0x2d, 0xd8, 0x87, 0xa2, 0x7f, 0x9d, 0xeb, 0x00, 0xff, 0xad, 0xec, + 0xe7, 0xc1, 0x17, 0xa1, 0x57, 0x7e, 0x8c, 0x79, 0x3d, 0x37, 0x4b, 0x7b, + 0x8e, 0x3a, 0x01, 0xde, 0xf6, 0x18, 0xeb, 0xc2, 0x7e, 0x3e, 0x7a, 0x59, + 0x96, 0x81, 0x3b, 0xb2, 0x94, 0x63, 0xf8, 0x0f, 0xce, 0x85, 0x8a, 0xf4, + 0x52, 0x07, 0x02, 0x13, 0x0d, 0xca, 0xc0, 0xf1, 0x04, 0xb0, 0x1e, 0x90, + 0xbc, 0x3a, 0xaf, 0xc3, 0xf3, 0xf9, 0x2d, 0x62, 0x11, 0xef, 0x79, 0x3c, + 0x9b, 0xa1, 0xde, 0x30, 0x18, 0x69, 0x79, 0xb0, 0x43, 0xb2, 0xdb, 0x3b, + 0x94, 0xee, 0x70, 0xbc, 0x97, 0x31, 0xee, 0x1e, 0xb8, 0x20, 0x6f, 0x00, + 0x21, 0x58, 0x99, 0x43, 0xf2, 0xbf, 0x3c, 0xc6, 0xa8, 0x02, 0xdf, 0x0f, + 0x73, 0x89, 0x81, 0x66, 0x9b, 0xf6, 0xbb, 0x76, 0x6c, 0x4f, 0x9d, 0xfd, + 0xc7, 0x14, 0xc6, 0xca, 0x0b, 0xfb, 0x87, 0x9d, 0xc0, 0x98, 0xa9, 0xe3, + 0x94, 0xfd, 0x6d, 0xe0, 0xdb, 0x3f, 0x05, 0x06, 0x22, 0x55, 0x87, 0x36, + 0x07, 0xfb, 0x85, 0xf3, 0x5f, 0x26, 0x9e, 0x60, 0x4c, 0x3d, 0xf0, 0xcb, + 0x57, 0xe6, 0xb6, 0x13, 0xf6, 0xeb, 0xb6, 0xcd, 0x94, 0x81, 0x71, 0x0f, + 0x7e, 0xdf, 0xf1, 0xc0, 0x5e, 0x77, 0x9f, 0x47, 0xab, 0x13, 0xd2, 0xc9, + 0xd3, 0x4e, 0x4b, 0x6e, 0x91, 0x8f, 0x44, 0x82, 0x7e, 0xac, 0x79, 0x1b, + 0xb2, 0x4a, 0x3d, 0xd0, 0x09, 0x39, 0x67, 0x9e, 0x3a, 0x85, 0x3a, 0x81, + 0xb2, 0xe0, 0x4a, 0xa9, 0x0e, 0x9d, 0xd0, 0xd6, 0x25, 0x15, 0xd2, 0x6c, + 0x9e, 0x7a, 0xe2, 0x07, 0x32, 0xbd, 0x4e, 0x57, 0x0e, 0x89, 0xf1, 0x6b, + 0x5b, 0x25, 0x9a, 0x71, 0xed, 0x7b, 0xd5, 0x1a, 0x03, 0x7d, 0x79, 0x80, + 0xf8, 0x73, 0x36, 0xeb, 0x74, 0x88, 0xc6, 0x9e, 0x0a, 0x3f, 0xbd, 0x89, + 0xb5, 0xb2, 0x0f, 0x45, 0xa7, 0xc1, 0xa1, 0xc0, 0x17, 0x50, 0x31, 0x3f, + 0xe0, 0xe0, 0xc4, 0x8f, 0xa1, 0x6b, 0xf3, 0xc4, 0x25, 0xa0, 0x73, 0xf7, + 0x09, 0xca, 0xd1, 0x75, 0xea, 0x6c, 0xbc, 0x62, 0xa5, 0xa9, 0xaf, 0x65, + 0xf1, 0x38, 0x30, 0x97, 0xb5, 0x4b, 0x0a, 0x94, 0x57, 0x9e, 0x7d, 0x2f, + 0x5a, 0x32, 0x3d, 0xd7, 0x26, 0x3d, 0xf3, 0x8c, 0xaf, 0xee, 0x6e, 0x91, + 0x36, 0xc6, 0x58, 0x69, 0x83, 0x06, 0x24, 0x8f, 0xf2, 0xee, 0xf9, 0xb0, + 0x8a, 0x87, 0x55, 0x2c, 0xd2, 0xa8, 0x1f, 0xfa, 0xc0, 0x49, 0x2f, 0x5b, + 0xff, 0x25, 0x16, 0x60, 0x48, 0xc8, 0x52, 0x19, 0x32, 0x56, 0x86, 0x8c, + 0x95, 0x21, 0x63, 0x65, 0xc8, 0x18, 0xb0, 0xdf, 0x73, 0xd8, 0x7f, 0x17, + 0xcb, 0x83, 0xda, 0xae, 0xdf, 0xaf, 0xec, 0xfa, 0x91, 0x32, 0xcf, 0xf0, + 0xe9, 0x83, 0x26, 0x95, 0x0e, 0xb9, 0xa4, 0x7c, 0x51, 0xe3, 0xa3, 0xbe, + 0x22, 0xcf, 0xcc, 0xbe, 0x2a, 0x67, 0x66, 0x57, 0x71, 0xe0, 0x54, 0xd9, + 0x97, 0x97, 0x3d, 0xf8, 0x9f, 0x0b, 0xc4, 0x54, 0xd9, 0xf6, 0x66, 0x85, + 0xad, 0x0e, 0x4b, 0x41, 0xe1, 0x64, 0x65, 0x47, 0x80, 0xaf, 0x14, 0x2e, + 0xe4, 0xde, 0x94, 0x8e, 0xed, 0xaf, 0xc9, 0x45, 0xd8, 0xf1, 0xc5, 0xfa, + 0xeb, 0xf2, 0xbc, 0xc2, 0xe3, 0xa4, 0xc3, 0x07, 0xe4, 0x47, 0x76, 0x70, + 0x4e, 0x7c, 0x06, 0x58, 0x63, 0xb1, 0x8f, 0xba, 0x23, 0x02, 0x5b, 0xe0, + 0x14, 0xbb, 0xb1, 0xaf, 0x0f, 0x5a, 0x37, 0x00, 0xd3, 0xf0, 0xfd, 0x16, + 0x79, 0x71, 0xb6, 0xd8, 0x20, 0x13, 0xd4, 0x0f, 0xce, 0x51, 0xb1, 0x68, + 0xa7, 0x68, 0x37, 0xb9, 0x5e, 0xda, 0xa9, 0x3f, 0xd8, 0xcc, 0xb3, 0xd4, + 0xea, 0xc9, 0x73, 0x2d, 0x8c, 0x37, 0xc6, 0x5d, 0xd2, 0xf4, 0x35, 0x39, + 0x58, 0x63, 0xd9, 0xab, 0xe0, 0x0f, 0xd3, 0xef, 0xf9, 0xf7, 0xc4, 0x39, + 0x1e, 0xfb, 0x05, 0x6e, 0xea, 0xc4, 0x5a, 0xcb, 0x7f, 0xa9, 0x63, 0x5e, + 0xfd, 0x0a, 0x47, 0xbf, 0x13, 0x2f, 0x9b, 0x7b, 0x0d, 0xaf, 0xa9, 0x78, + 0xe0, 0x06, 0x71, 0xe2, 0xa7, 0xb0, 0xaf, 0x8a, 0x57, 0x85, 0x31, 0x4b, + 0xc6, 0x73, 0x19, 0x2b, 0x6e, 0xd4, 0x18, 0xea, 0xbc, 0x54, 0xee, 0x86, + 0x7e, 0xb9, 0x07, 0xfa, 0xe5, 0xde, 0x77, 0xdc, 0xaf, 0x35, 0x71, 0xfb, + 0x9e, 0x62, 0xd8, 0xea, 0x92, 0xb1, 0x5a, 0x63, 0x5b, 0xc6, 0x71, 0x37, + 0x8a, 0xdb, 0x32, 0xa6, 0x9b, 0x5e, 0x17, 0x0b, 0xa4, 0x6c, 0xf8, 0xf2, + 0x92, 0xc7, 0xb8, 0x9b, 0xb9, 0x9b, 0xbd, 0x11, 0xfe, 0xfa, 0xc3, 0xcd, + 0x26, 0xe6, 0x1c, 0xc9, 0x5c, 0x15, 0xde, 0xd1, 0x2e, 0xcd, 0x10, 0x0f, + 0xa8, 0xb3, 0x40, 0x15, 0xbb, 0xce, 0x07, 0xf1, 0x03, 0x94, 0xc3, 0xea, + 0xc2, 0xdf, 0x61, 0xec, 0xda, 0xde, 0xe1, 0xd8, 0x63, 0xe1, 0xe0, 0xae, + 0x1f, 0xf7, 0x72, 0xa0, 0xcb, 0x20, 0x8b, 0xf5, 0xd5, 0x3b, 0x74, 0x43, + 0x4a, 0x5f, 0x5c, 0xc5, 0x1e, 0x20, 0xbf, 0xe0, 0x2f, 0x60, 0x9f, 0x4c, + 0x41, 0x3f, 0x15, 0x54, 0x7f, 0x31, 0xca, 0x45, 0x36, 0x17, 0xb6, 0x24, + 0x7a, 0x8a, 0xbe, 0x50, 0x10, 0x6b, 0xc9, 0x87, 0x1d, 0xa5, 0xbf, 0x31, + 0x77, 0xe0, 0x33, 0xee, 0xcf, 0xe4, 0x44, 0x73, 0xa6, 0x09, 0x76, 0x15, + 0xfc, 0xab, 0x33, 0x26, 0x80, 0xbd, 0xbb, 0xf4, 0x5d, 0x39, 0x30, 0x77, + 0x69, 0x73, 0x20, 0xff, 0x8c, 0x23, 0x73, 0x7d, 0x66, 0x0e, 0x6b, 0xfb, + 0xb6, 0x4e, 0x49, 0xac, 0x05, 0x36, 0xed, 0xa3, 0xa7, 0x88, 0x07, 0x9a, + 0x65, 0x39, 0xce, 0x7e, 0x83, 0x3d, 0x33, 0x5d, 0x66, 0xdf, 0xdf, 0x95, + 0xe1, 0xb9, 0x74, 0x2b, 0xf5, 0xc8, 0x12, 0xf4, 0xc0, 0x65, 0x9b, 0x36, + 0x74, 0x1c, 0x36, 0xae, 0x53, 0xde, 0x9c, 0xa3, 0x7d, 0x4c, 0xd9, 0x67, + 0x64, 0x5b, 0xe2, 0x0c, 0xe6, 0xf4, 0x84, 0x17, 0xa1, 0x8f, 0xe6, 0x0f, + 0xa1, 0xec, 0xeb, 0x92, 0xb2, 0xbb, 0x43, 0x7c, 0xde, 0x66, 0x3f, 0x29, + 0xbc, 0x6f, 0x90, 0xb2, 0x6f, 0x0d, 0x51, 0x8e, 0xe0, 0x73, 0x2f, 0xad, + 0xce, 0xf3, 0x7b, 0x73, 0xca, 0x4f, 0x52, 0x7a, 0x66, 0xc9, 0xe3, 0x78, + 0x97, 0xb4, 0x6e, 0xbb, 0x15, 0xfa, 0x24, 0xa6, 0xcf, 0xc2, 0xd0, 0x86, + 0xd8, 0xc6, 0x8b, 0xe8, 0xfc, 0x67, 0x25, 0x77, 0x3a, 0x0e, 0x7d, 0xc6, + 0xbe, 0x8c, 0xef, 0x40, 0x1b, 0x69, 0xf0, 0x36, 0xed, 0xdd, 0x2e, 0xd8, + 0xbd, 0x9b, 0xd4, 0x7c, 0x46, 0xbc, 0x7e, 0x99, 0x3a, 0xc9, 0xb1, 0xfb, + 0xa0, 0xcb, 0x13, 0x4a, 0x6e, 0x4b, 0xe5, 0xcb, 0x89, 0x18, 0x74, 0x72, + 0x6c, 0x3b, 0xe9, 0xf9, 0x61, 0xb9, 0xd3, 0x1d, 0x97, 0xbb, 0x20, 0x3b, + 0x43, 0xae, 0x27, 0xc3, 0xe0, 0xc5, 0x1e, 0x17, 0x76, 0x47, 0x61, 0xe8, + 0x66, 0xf8, 0x5d, 0x1c, 0x9b, 0xf7, 0xc4, 0xd9, 0x36, 0xc0, 0x8f, 0x7f, + 0x54, 0x0f, 0x68, 0x94, 0x9b, 0xfb, 0x88, 0xa2, 0xcd, 0x88, 0xb7, 0x53, + 0xdb, 0xd9, 0x36, 0xc9, 0xab, 0x7a, 0x3b, 0x95, 0x3d, 0x2e, 0x2d, 0xde, + 0x87, 0x14, 0xb6, 0x79, 0x11, 0xfa, 0x06, 0x98, 0xbb, 0x54, 0xdb, 0x81, + 0x3c, 0x6c, 0xe8, 0x62, 0x06, 0xe9, 0x87, 0x91, 0xb2, 0x6e, 0xa8, 0x35, + 0x88, 0xe5, 0x1a, 0x3c, 0xba, 0x7a, 0xbf, 0xf0, 0xa3, 0x0a, 0x97, 0x5e, + 0x55, 0xf7, 0xcb, 0x2c, 0x60, 0x9d, 0x1c, 0xf4, 0x4a, 0x2b, 0x30, 0xd0, + 0xcc, 0x29, 0x27, 0x3d, 0x1c, 0xda, 0x2d, 0xbf, 0x06, 0x5f, 0xbe, 0xea, + 0x91, 0x97, 0x3b, 0xe4, 0xc1, 0x3b, 0x28, 0x23, 0xbb, 0x65, 0xff, 0x1d, + 0x21, 0xd9, 0xdf, 0xef, 0x64, 0x39, 0xef, 0x5b, 0x6e, 0x33, 0xfe, 0x74, + 0xcf, 0x48, 0x2a, 0x34, 0x20, 0x4f, 0x42, 0xc6, 0x8a, 0x90, 0xaf, 0xe1, + 0x3a, 0x69, 0x4e, 0x7d, 0x4f, 0x3d, 0x9f, 0x06, 0x56, 0x36, 0xd8, 0xcf, + 0x95, 0x99, 0x7a, 0x93, 0x24, 0xaf, 0x67, 0x3c, 0x39, 0x19, 0x9c, 0x71, + 0x5c, 0x4f, 0x99, 0x80, 0x0f, 0x72, 0x7d, 0xb0, 0x3f, 0xd5, 0xbd, 0x2e, + 0xf5, 0x1c, 0xa7, 0xff, 0xeb, 0x13, 0xe7, 0x15, 0x14, 0x5f, 0x68, 0x23, + 0x98, 0xfe, 0xbb, 0xd6, 0x15, 0x7c, 0xd7, 0x46, 0xff, 0x61, 0x67, 0xeb, + 0xea, 0xbd, 0xf4, 0xf5, 0xb2, 0x68, 0xe2, 0x6e, 0x15, 0xac, 0x99, 0x36, + 0xdd, 0xb1, 0xa9, 0x0b, 0xdb, 0xdd, 0xfb, 0xe5, 0x4f, 0x60, 0xdf, 0xbf, + 0xb2, 0x62, 0xdf, 0xf7, 0x81, 0x1e, 0xeb, 0x31, 0x80, 0x6b, 0xdf, 0x8d, + 0xb5, 0x8c, 0x80, 0x9f, 0x77, 0xe1, 0x77, 0x67, 0x79, 0x4d, 0x1c, 0x6f, + 0xb6, 0x08, 0x3c, 0xd9, 0xe4, 0xb2, 0xbf, 0x35, 0xf1, 0xbc, 0x62, 0x41, + 0x56, 0x62, 0x85, 0x83, 0xd7, 0x84, 0x76, 0xef, 0x2d, 0x89, 0xf6, 0xba, + 0x6f, 0x75, 0x87, 0xdc, 0x17, 0xac, 0x10, 0xcf, 0x95, 0x3d, 0x39, 0x5b, + 0x27, 0x0e, 0xbb, 0x22, 0xd6, 0x79, 0x62, 0xb0, 0x6f, 0xa8, 0x18, 0x54, + 0xb5, 0xfc, 0x6d, 0xa4, 0xa8, 0x0f, 0xfd, 0x18, 0x0e, 0xe2, 0x14, 0x0a, + 0xab, 0x50, 0xcf, 0xde, 0x05, 0x3e, 0x4c, 0xe1, 0xd7, 0xbd, 0xfd, 0x56, + 0xec, 0x5f, 0xca, 0x29, 0x63, 0x5f, 0xbd, 0xf6, 0xf6, 0x10, 0xdf, 0x6d, + 0x14, 0x07, 0xfb, 0x8e, 0x44, 0x4e, 0xc0, 0xd6, 0x59, 0xd4, 0x0f, 0x5c, + 0x07, 0xed, 0xa4, 0x2d, 0x0b, 0x27, 0xb9, 0xd7, 0x37, 0xaa, 0x6f, 0xea, + 0x9a, 0xb5, 0x28, 0xbb, 0x91, 0x2d, 0x30, 0xc6, 0x59, 0x26, 0x0f, 0x3c, + 0xf0, 0xc0, 0x97, 0x53, 0x5e, 0x3b, 0xf4, 0x76, 0x5c, 0xc2, 0xa7, 0x7c, + 0x19, 0x52, 0xd8, 0x75, 0x1b, 0x30, 0xd7, 0x16, 0x8d, 0x1b, 0xe2, 0x12, + 0x39, 0xd5, 0x25, 0xcd, 0xc0, 0xd5, 0x4d, 0xc7, 0x68, 0x23, 0x53, 0xc9, + 0x21, 0x08, 0x41, 0x44, 0xdd, 0x55, 0x74, 0x06, 0xdf, 0x94, 0x6d, 0xc9, + 0x37, 0x85, 0x78, 0xe9, 0x86, 0x2d, 0xf0, 0x09, 0xbc, 0x2b, 0x1b, 0xd4, + 0x2f, 0xad, 0xd6, 0x87, 0x1c, 0x31, 0xb6, 0xc6, 0x36, 0x8c, 0xb5, 0xa5, + 0x06, 0xdf, 0x60, 0x8c, 0x0d, 0xbe, 0x66, 0xd3, 0xb9, 0x60, 0x0e, 0xd6, + 0x52, 0x87, 0x54, 0x4f, 0x73, 0x8f, 0x32, 0xce, 0x62, 0x07, 0x7e, 0x6a, + 0x99, 0xfe, 0x2a, 0xdf, 0x27, 0xf5, 0xfb, 0x6e, 0xfd, 0x9e, 0xfe, 0x68, + 0xd1, 0x6f, 0x02, 0x4d, 0xf7, 0x40, 0x7f, 0xde, 0xb7, 0xc3, 0x55, 0xb8, + 0xe1, 0xbe, 0x15, 0x9e, 0xed, 0x15, 0xeb, 0x38, 0xfc, 0xd4, 0xf2, 0x61, + 0x71, 0xb7, 0x2f, 0xa7, 0x23, 0x32, 0x06, 0x5e, 0x30, 0x9f, 0xe5, 0x7c, + 0xd2, 0x47, 0xe4, 0xa0, 0xe2, 0x4d, 0xf5, 0xa4, 0x73, 0x34, 0x19, 0x9a, + 0x12, 0xab, 0xca, 0xe7, 0x47, 0x90, 0x1e, 0x01, 0xde, 0x09, 0x62, 0x97, + 0x56, 0x75, 0x2d, 0x2d, 0x81, 0x31, 0xec, 0x3d, 0x6b, 0xe2, 0x58, 0xab, + 0x31, 0x2e, 0xbe, 0x1f, 0x52, 0xef, 0xd3, 0x6b, 0xe2, 0x5c, 0x79, 0x8b, + 0x58, 0xc6, 0xbc, 0x27, 0x2f, 0xc8, 0x2f, 0xd8, 0xe2, 0x93, 0x26, 0xe6, + 0xd5, 0xa6, 0xf9, 0x42, 0xfe, 0xcc, 0xc8, 0x45, 0xdb, 0x19, 0xa1, 0xfc, + 0xfd, 0xea, 0x8e, 0x1b, 0x65, 0xa2, 0x93, 0xf1, 0xb6, 0xc6, 0x39, 0xac, + 0x8f, 0xa3, 0x35, 0x8e, 0xbf, 0x3e, 0xfe, 0xc6, 0xb1, 0x83, 0x18, 0x5b, + 0x6e, 0x4d, 0x8c, 0xad, 0x71, 0x3c, 0x8e, 0xb5, 0x05, 0xfe, 0x53, 0xd1, + 0x8f, 0xbb, 0xe4, 0x51, 0x4f, 0x72, 0x8e, 0xf9, 0x2f, 0x58, 0xe0, 0x63, + 0x1c, 0x76, 0x84, 0xbc, 0x34, 0x67, 0xcf, 0xe4, 0x69, 0x2a, 0x79, 0x24, + 0xe0, 0xe7, 0x60, 0xc0, 0xf7, 0x80, 0xff, 0x57, 0x56, 0xf8, 0x48, 0xfb, + 0x40, 0x3e, 0x76, 0x8a, 0x40, 0xcf, 0x5a, 0xc7, 0xc8, 0x43, 0xa6, 0xe4, + 0x21, 0xdf, 0x91, 0x87, 0xdd, 0xfa, 0x1d, 0xf9, 0x07, 0x9c, 0xf6, 0x79, + 0x60, 0x0c, 0x2f, 0xa7, 0xbe, 0xb1, 0xe9, 0xee, 0x35, 0x7b, 0x31, 0x2d, + 0xcf, 0x2f, 0xb4, 0x88, 0x9d, 0x09, 0xd6, 0x35, 0xbe, 0x26, 0xde, 0xce, + 0xf3, 0xab, 0x7e, 0x62, 0x4f, 0xb3, 0xae, 0x04, 0xd7, 0x75, 0x50, 0x5e, + 0x93, 0xc2, 0x4c, 0x04, 0x3e, 0x60, 0x1a, 0x38, 0xa7, 0x1f, 0xfa, 0x96, + 0xf1, 0x51, 0x94, 0xd5, 0x88, 0x57, 0x68, 0xeb, 0xd2, 0xd8, 0x2b, 0xd4, + 0xc1, 0xc4, 0x23, 0xaf, 0x4a, 0xbe, 0x62, 0x74, 0x0c, 0xfa, 0xb7, 0x4c, + 0xff, 0xa4, 0x73, 0xf6, 0x96, 0xeb, 0x64, 0x39, 0x79, 0x9d, 0x38, 0xc9, + 0x45, 0x59, 0xe5, 0xeb, 0xf8, 0xc6, 0x74, 0xf7, 0xee, 0x0b, 0xaf, 0xca, + 0xc6, 0xf8, 0x06, 0xbc, 0x9f, 0x14, 0xf3, 0xde, 0xf0, 0x7e, 0x43, 0x3e, + 0x14, 0x5f, 0x11, 0xf2, 0x82, 0x34, 0x20, 0x1e, 0x8e, 0xca, 0xef, 0xc6, + 0xb9, 0x1f, 0x8b, 0xea, 0x7c, 0x33, 0x65, 0xf5, 0x2a, 0x9d, 0x31, 0xe4, + 0x05, 0xf2, 0x5a, 0xc4, 0x38, 0xb1, 0x9e, 0xdf, 0xf3, 0x87, 0xe2, 0xf0, + 0x73, 0x7b, 0xa8, 0x5f, 0xcc, 0x9e, 0x6e, 0x51, 0x7b, 0xfa, 0x09, 0x2f, + 0x24, 0x25, 0x37, 0x24, 0x53, 0xee, 0x61, 0x85, 0xf1, 0x7f, 0x03, 0x7d, + 0x3d, 0xa8, 0xfb, 0x9a, 0x92, 0x5e, 0xad, 0x7f, 0x0e, 0x41, 0xce, 0x7d, + 0xb9, 0xd7, 0xdb, 0x21, 0xbf, 0xda, 0xce, 0x3d, 0x60, 0xd6, 0x7f, 0x58, + 0x7a, 0x76, 0x2c, 0x27, 0xe1, 0x19, 0xdc, 0x12, 0x5d, 0xa1, 0x01, 0xf7, + 0x99, 0x91, 0xef, 0x80, 0x0e, 0xc1, 0xfa, 0xd7, 0xac, 0x55, 0xaf, 0x93, + 0x6b, 0x66, 0x3d, 0xae, 0x35, 0xc0, 0xf2, 0xab, 0x6b, 0x35, 0xf5, 0x5b, + 0x21, 0x4b, 0x4e, 0x52, 0x42, 0x8d, 0xb4, 0x59, 0xd1, 0x51, 0x23, 0x8c, + 0x91, 0x2c, 0xdb, 0x4e, 0x3a, 0x19, 0x32, 0xb1, 0xe8, 0x00, 0xeb, 0x76, + 0x03, 0x87, 0xbb, 0xbd, 0xbd, 0xe9, 0x82, 0x8a, 0x91, 0x5a, 0x6a, 0x5d, + 0x53, 0xc0, 0x64, 0x0b, 0xde, 0x2b, 0xfe, 0xa7, 0x81, 0x59, 0x27, 0xe4, + 0x61, 0x09, 0xaf, 0x89, 0xe5, 0x22, 0x7f, 0x9e, 0xf1, 0x5c, 0x27, 0x99, + 0x05, 0x8f, 0x7f, 0x13, 0x3e, 0x7c, 0x15, 0x7a, 0xff, 0xe3, 0xb4, 0x0d, + 0x65, 0xd8, 0x0b, 0xe0, 0x92, 0xaf, 0xbc, 0x27, 0x86, 0x9f, 0x68, 0x88, + 0xe5, 0x06, 0xf8, 0xf4, 0xa2, 0xc2, 0xa4, 0xc4, 0xed, 0x47, 0x43, 0x77, + 0xf7, 0x85, 0xe1, 0x67, 0x14, 0xfd, 0x98, 0x4b, 0x1c, 0x77, 0x58, 0xee, + 0x04, 0x7f, 0xce, 0x2e, 0x14, 0x43, 0x7b, 0xca, 0x46, 0x56, 0xe1, 0x57, + 0xd6, 0x9d, 0xf4, 0x65, 0xd0, 0xe3, 0x19, 0x8d, 0xf9, 0x78, 0x5e, 0x53, + 0xd5, 0x3e, 0x0b, 0x63, 0x43, 0xa5, 0xfa, 0x61, 0x99, 0xf6, 0x18, 0xdb, + 0xe9, 0x91, 0x52, 0x3c, 0x7b, 0x63, 0xf3, 0x0a, 0x8d, 0x1c, 0x1b, 0x3e, + 0x5f, 0x9a, 0xfa, 0xbb, 0xaa, 0xcf, 0x3b, 0x9e, 0x51, 0xf2, 0x65, 0xe2, + 0xc2, 0xf4, 0x8f, 0x78, 0x5e, 0xd5, 0x63, 0x8f, 0xf0, 0xb9, 0x42, 0x19, + 0x50, 0x3e, 0x13, 0x68, 0xf9, 0x90, 0x64, 0xc7, 0x92, 0x0a, 0xb7, 0x3c, + 0x5e, 0xe6, 0x7e, 0x21, 0xfe, 0x7f, 0x0d, 0xd8, 0x3f, 0x02, 0x9e, 0xd1, + 0x0f, 0xe0, 0xd8, 0xdc, 0x17, 0x28, 0xab, 0xd9, 0xef, 0xb2, 0x2f, 0x5e, + 0x6b, 0x23, 0xc6, 0xb8, 0x54, 0x16, 0x45, 0xbf, 0x65, 0x31, 0xb1, 0x73, + 0x85, 0x05, 0x8b, 0xb9, 0x70, 0x48, 0x52, 0x27, 0xfe, 0x35, 0x64, 0xe8, + 0xd7, 0xe1, 0x23, 0xa9, 0x7a, 0xea, 0xfc, 0x6a, 0x08, 0x98, 0xcb, 0x72, + 0x6f, 0x90, 0x92, 0x1d, 0x95, 0x92, 0xba, 0xa3, 0xc9, 0xf3, 0xdc, 0xb0, + 0x8a, 0xed, 0x94, 0x6c, 0x62, 0xfe, 0xff, 0xde, 0x16, 0xd8, 0xfa, 0x0e, + 0xe4, 0xd9, 0x8e, 0x79, 0x96, 0x4f, 0x49, 0xf4, 0xc4, 0x21, 0x69, 0x3a, + 0xf1, 0xb0, 0x34, 0x1f, 0x27, 0xc6, 0x63, 0xec, 0xde, 0xda, 0xd5, 0x2c, + 0xc4, 0xdc, 0x43, 0x18, 0xfb, 0xb0, 0x7c, 0xdf, 0x33, 0x73, 0x5a, 0xc4, + 0x1c, 0x59, 0xc7, 0xe4, 0x0d, 0x1e, 0xdf, 0x85, 0xf9, 0x70, 0xfd, 0x49, + 0x8d, 0xfb, 0x76, 0x35, 0xf8, 0xae, 0x4d, 0xda, 0x77, 0x65, 0xbb, 0x4f, + 0x61, 0xad, 0x27, 0x25, 0xea, 0x9a, 0xf6, 0xbb, 0x51, 0x2f, 0xd1, 0x70, + 0x07, 0x82, 0x75, 0xf4, 0x9d, 0x80, 0x36, 0xe2, 0x1e, 0x9e, 0xb7, 0xb3, + 0x2c, 0x38, 0xf3, 0xb7, 0xaa, 0xbb, 0xc2, 0x6b, 0xc7, 0xdf, 0xd9, 0x50, + 0xd7, 0x94, 0x99, 0x36, 0xd1, 0xc0, 0xe7, 0x1f, 0x88, 0x36, 0xb4, 0x83, + 0x71, 0x53, 0x69, 0xe0, 0x7b, 0x04, 0x7e, 0x10, 0xd7, 0x90, 0x6e, 0xc0, + 0x39, 0x6b, 0xbf, 0x45, 0xcc, 0xa3, 0xbc, 0x30, 0x67, 0xee, 0x91, 0x59, + 0x58, 0x8b, 0x53, 0xa4, 0xff, 0x62, 0xf3, 0x4e, 0xee, 0x5c, 0x11, 0xf3, + 0xbe, 0x49, 0xdd, 0x25, 0xe2, 0xdd, 0x0d, 0xd4, 0x4b, 0x06, 0xf8, 0x93, + 0xf9, 0x04, 0x78, 0x7e, 0x5b, 0x97, 0x95, 0xf9, 0xf3, 0x1b, 0x73, 0x03, + 0xc4, 0x37, 0x5b, 0x79, 0x0e, 0x09, 0xdc, 0x4c, 0x39, 0xfb, 0x2e, 0xe4, + 0xac, 0x59, 0x9d, 0xfb, 0x94, 0xca, 0xf4, 0xe7, 0x0a, 0x90, 0x1f, 0xde, + 0x87, 0xa3, 0xdf, 0x57, 0xd0, 0xf1, 0x58, 0xce, 0x93, 0x98, 0xde, 0xf8, + 0x07, 0xec, 0x73, 0xfd, 0x19, 0x6c, 0xe3, 0xfd, 0x12, 0xca, 0x5b, 0x42, + 0xcd, 0x79, 0x78, 0x9d, 0xbf, 0x72, 0x04, 0xba, 0x60, 0x01, 0xf2, 0x3c, + 0x09, 0x1d, 0x38, 0x14, 0xe6, 0xfe, 0x6c, 0xd1, 0xbe, 0xac, 0x4b, 0xbf, + 0x3d, 0x34, 0x86, 0x3e, 0xac, 0xe3, 0xaf, 0xcb, 0x14, 0xf4, 0xff, 0x74, + 0x3d, 0xa5, 0xbe, 0x17, 0xc9, 0x26, 0x78, 0x07, 0x8c, 0xe5, 0x63, 0x18, + 0xff, 0x75, 0xe0, 0xe1, 0xcd, 0xa0, 0xa7, 0xa5, 0x79, 0xf5, 0x2b, 0x3a, + 0x16, 0x15, 0x63, 0x2c, 0x1e, 0x7a, 0xb3, 0x14, 0x60, 0xcd, 0xf8, 0x34, + 0xd2, 0xcd, 0x2d, 0x81, 0xbc, 0x4e, 0x6e, 0xd5, 0x77, 0x2f, 0x50, 0xfe, + 0x98, 0x8a, 0x41, 0x06, 0x6b, 0x72, 0xb4, 0xaf, 0x12, 0x85, 0xcc, 0x71, + 0x5d, 0xf7, 0xa2, 0x1e, 0x65, 0xad, 0x4f, 0x9f, 0xcd, 0xb6, 0x28, 0xfd, + 0x98, 0x87, 0x2c, 0x15, 0x94, 0x1f, 0x01, 0x7c, 0xef, 0xb1, 0xdd, 0xaf, + 0x6f, 0xe5, 0xd9, 0x67, 0x93, 0xab, 0x7c, 0x8b, 0xce, 0xb0, 0x98, 0xb2, + 0x8f, 0xa0, 0x8c, 0x72, 0x76, 0x03, 0x78, 0xc3, 0xb2, 0x1c, 0xf2, 0x1c, + 0xeb, 0x46, 0x3d, 0x0e, 0xc7, 0xb8, 0xb4, 0x79, 0xed, 0x9c, 0xb8, 0x96, + 0xce, 0x75, 0x77, 0xe7, 0x59, 0x76, 0x83, 0x2e, 0x8b, 0xe8, 0xf5, 0xfd, + 0xa9, 0xfe, 0xb6, 0xc1, 0x39, 0x9a, 0x5d, 0xc1, 0xc6, 0x9c, 0x5f, 0x4c, + 0xb5, 0xcb, 0xda, 0x81, 0xec, 0x1c, 0x01, 0x3f, 0x22, 0x99, 0xaf, 0xf1, + 0x4c, 0x19, 0xf4, 0x35, 0x7b, 0x22, 0xa1, 0xfc, 0xce, 0xa4, 0x15, 0xdc, + 0x5d, 0xba, 0x58, 0x6e, 0xf4, 0x19, 0xcc, 0xfd, 0x6f, 0x57, 0xc6, 0x56, + 0x78, 0x45, 0xbe, 0x91, 0x5f, 0xef, 0xc6, 0x2b, 0xf2, 0x91, 0xfc, 0x2a, + 0x48, 0x69, 0x96, 0x7c, 0xa2, 0xbc, 0x8c, 0x29, 0x79, 0x29, 0x55, 0x0c, + 0x4e, 0xa6, 0x2e, 0xe1, 0x37, 0x0f, 0x1b, 0x9d, 0xd7, 0x9b, 0xbb, 0x61, + 0xbf, 0x44, 0xfa, 0x85, 0x86, 0xe1, 0x1e, 0x2d, 0xcc, 0x2a, 0x9d, 0x02, + 0xbb, 0x98, 0x50, 0xba, 0xa2, 0x30, 0xce, 0xfc, 0xd2, 0x56, 0x7e, 0x9b, + 0x8b, 0x79, 0xa0, 0xbc, 0x53, 0xf3, 0xf5, 0x06, 0x75, 0xbf, 0x89, 0x7b, + 0xb0, 0x54, 0xa9, 0xab, 0xf7, 0x67, 0xe7, 0x9a, 0x54, 0xfd, 0xb3, 0x73, + 0xeb, 0xef, 0x28, 0xb1, 0xec, 0x66, 0xc6, 0x55, 0x64, 0x71, 0xa6, 0x49, + 0x96, 0xe6, 0xfe, 0x90, 0x7e, 0x22, 0x8c, 0xc1, 0xca, 0xf7, 0x1d, 0xfa, + 0x5b, 0x2c, 0x5f, 0x86, 0x21, 0x37, 0x0b, 0x83, 0xd3, 0x52, 0x1d, 0xa4, + 0x1f, 0xa4, 0xee, 0x0e, 0x62, 0xbd, 0x4d, 0xc0, 0xc0, 0xc0, 0x85, 0x2e, + 0xe3, 0xcf, 0x5b, 0xb4, 0x3e, 0x79, 0xb0, 0x75, 0x25, 0x2e, 0x1d, 0x2f, + 0xfa, 0x55, 0xd7, 0x7c, 0x33, 0xc3, 0x3e, 0xf9, 0xdd, 0x0c, 0x79, 0x66, + 0xa1, 0x3d, 0xef, 0x64, 0x76, 0x33, 0xae, 0xad, 0xf9, 0x1c, 0x46, 0x7d, + 0xa6, 0xbf, 0xa7, 0xf3, 0x73, 0x3a, 0xfd, 0xac, 0xec, 0x3f, 0xf9, 0x19, + 0xcc, 0x7b, 0x53, 0x70, 0xef, 0x4a, 0x1a, 0xbf, 0x9b, 0x88, 0xe8, 0x6f, + 0x34, 0x3e, 0x8b, 0x32, 0xc6, 0xe2, 0x3e, 0xab, 0xd6, 0xc4, 0xbb, 0x7d, + 0x45, 0xf9, 0x79, 0x77, 0x54, 0x8c, 0x3f, 0xc8, 0xfb, 0x53, 0x2d, 0xba, + 0xbf, 0x3d, 0x5a, 0x96, 0xc6, 0x65, 0x3f, 0xec, 0x5d, 0x01, 0xb8, 0x98, + 0x77, 0xce, 0x26, 0xc2, 0x8d, 0x63, 0x9a, 0xfd, 0x14, 0xc4, 0x1a, 0xcc, + 0xdd, 0x87, 0xb0, 0xf2, 0x89, 0x56, 0xe2, 0x16, 0xba, 0x7c, 0x5c, 0x0e, + 0x94, 0x55, 0xfc, 0x42, 0x9d, 0x59, 0x4e, 0x43, 0x2f, 0x0c, 0x29, 0x9b, + 0x16, 0x0b, 0x0d, 0xd7, 0x32, 0x52, 0x38, 0xbd, 0x17, 0xe3, 0x30, 0x16, + 0x98, 0xd5, 0x67, 0x83, 0xfb, 0x64, 0x7f, 0x3d, 0x18, 0x7b, 0xb2, 0xcc, + 0xf7, 0x29, 0xe0, 0x04, 0xbe, 0xcf, 0x27, 0xc2, 0xea, 0x74, 0xe3, 0x56, + 0xb4, 0x6d, 0xd2, 0x74, 0xe6, 0xbd, 0x6b, 0xb6, 0xa7, 0x0e, 0x00, 0xc0, + 0x69, 0xc9, 0xe3, 0x3d, 0xdb, 0x98, 0xfe, 0x26, 0x61, 0xb7, 0xe8, 0x9f, + 0x3f, 0x2a, 0xcb, 0x95, 0x69, 0xb9, 0x5c, 0x31, 0xb2, 0xce, 0xbb, 0xd7, + 0x9c, 0xfb, 0x5d, 0xc1, 0xb7, 0xbf, 0xe5, 0x2c, 0xf8, 0xb3, 0x96, 0x56, + 0xf9, 0x35, 0xdf, 0xdb, 0xfc, 0x2b, 0x3b, 0xf8, 0xe6, 0x6d, 0xb7, 0xba, + 0xc3, 0xb5, 0x76, 0xcf, 0xb1, 0x9f, 0xfd, 0x36, 0xcf, 0x3a, 0x82, 0x7b, + 0x68, 0x9d, 0x0d, 0xef, 0xe3, 0xfa, 0xee, 0xd7, 0xa7, 0xec, 0x80, 0x8f, + 0xa4, 0xe7, 0x98, 0x9e, 0xef, 0xad, 0xd8, 0xff, 0xec, 0xf3, 0x31, 0xcd, + 0x37, 0xa4, 0x0b, 0x7c, 0xe6, 0xfe, 0x5a, 0xd6, 0xe7, 0xbf, 0xb6, 0x1e, + 0xa3, 0xf1, 0xee, 0x5d, 0x53, 0xc3, 0xb8, 0x6c, 0x4f, 0xfb, 0x64, 0xee, + 0x80, 0xb3, 0xec, 0xa4, 0xbe, 0xe3, 0x77, 0xb5, 0xa1, 0xcc, 0xdc, 0x45, + 0x23, 0xbd, 0x18, 0xd3, 0x44, 0x5a, 0x1f, 0xd3, 0xcf, 0x63, 0x0d, 0xdf, + 0xc8, 0x98, 0x3e, 0x23, 0xe8, 0xc3, 0xdc, 0x41, 0x6f, 0xbc, 0x53, 0xcc, + 0xef, 0x83, 0x28, 0x8b, 0x16, 0xbf, 0x61, 0xa6, 0x1f, 0x08, 0xec, 0xb6, + 0x45, 0x26, 0xd5, 0x7c, 0x8a, 0xea, 0xbe, 0x06, 0xbf, 0x9b, 0x19, 0xb2, + 0x83, 0xfc, 0xe4, 0xc2, 0x7a, 0x39, 0x65, 0xf9, 0x33, 0xcd, 0xd2, 0x52, + 0xc4, 0x38, 0x7c, 0xbf, 0xd1, 0xf7, 0xf4, 0x51, 0xfd, 0x9d, 0x90, 0x87, + 0x36, 0x4f, 0x50, 0xde, 0x8b, 0xc5, 0x95, 0x7b, 0xa2, 0xc5, 0xe0, 0x1b, + 0x26, 0xcb, 0xdc, 0xd7, 0xe4, 0x37, 0xda, 0x22, 0x17, 0x6a, 0xfc, 0x3e, + 0x69, 0xb7, 0xba, 0x47, 0x13, 0x9c, 0x4d, 0x72, 0x5e, 0x3d, 0xca, 0x2e, + 0x54, 0x6b, 0x25, 0xd2, 0x54, 0xdb, 0xf6, 0xa8, 0xb6, 0xed, 0xa4, 0xf1, + 0x08, 0x68, 0xfc, 0x25, 0xcd, 0x17, 0xb6, 0xcf, 0xaa, 0xfb, 0xdd, 0xd9, + 0x38, 0xcf, 0xc7, 0x1e, 0x53, 0x6b, 0xa1, 0x9d, 0x40, 0xdb, 0x5f, 0x0e, + 0xab, 0x78, 0xa7, 0xfa, 0x06, 0x1c, 0xf2, 0xc9, 0x6f, 0xba, 0xa1, 0xe3, + 0xcb, 0xfc, 0x76, 0x7b, 0x04, 0x29, 0xbf, 0xd9, 0xde, 0xab, 0xee, 0xff, + 0x57, 0xd5, 0x37, 0x01, 0x46, 0x1e, 0xc3, 0x7a, 0xac, 0x6f, 0x62, 0x8c, + 0x80, 0xef, 0x85, 0x32, 0xbf, 0xe5, 0x36, 0x77, 0x4c, 0x37, 0x2f, 0x73, + 0x4f, 0x88, 0xf2, 0xf3, 0x83, 0x6f, 0xfb, 0xab, 0xea, 0x3b, 0x82, 0x24, + 0xbf, 0x2b, 0x84, 0xfd, 0xba, 0x1f, 0xcf, 0x3c, 0x57, 0xde, 0x87, 0x14, + 0xfa, 0xa7, 0x36, 0x81, 0xf4, 0x61, 0xc9, 0xab, 0xb8, 0x5f, 0x2b, 0xf2, + 0x93, 0x6a, 0xec, 0x52, 0xed, 0x13, 0xb2, 0xff, 0xf4, 0x43, 0xfc, 0x5e, + 0x42, 0x7d, 0x77, 0x9e, 0xf3, 0x38, 0xc7, 0xb8, 0x4c, 0xa9, 0x75, 0x17, + 0x35, 0xed, 0xcd, 0x59, 0xcc, 0xcf, 0xd4, 0xb7, 0x19, 0xc5, 0x5a, 0x2b, + 0xe6, 0x18, 0xd2, 0xf7, 0x4c, 0xe9, 0x0f, 0x98, 0xf5, 0xb7, 0xf0, 0xee, + 0xa2, 0xcf, 0xf3, 0xc3, 0xfd, 0x65, 0xde, 0x23, 0x4d, 0xe9, 0x38, 0x01, + 0x63, 0x87, 0x3c, 0x9f, 0xa0, 0x8c, 0x3b, 0xe9, 0x09, 0x58, 0xa0, 0xa8, + 0x24, 0x78, 0xb6, 0xad, 0xd7, 0xd2, 0xda, 0xb0, 0x16, 0xde, 0x9d, 0x0d, + 0xd6, 0xc3, 0xef, 0x21, 0x0a, 0xe5, 0xc6, 0x6f, 0x2a, 0xd4, 0x37, 0xd0, + 0xfc, 0x76, 0x46, 0x26, 0x6a, 0x9f, 0x94, 0x07, 0xca, 0x5b, 0xf4, 0xf7, + 0x14, 0x31, 0x79, 0xa0, 0xf6, 0xba, 0xa2, 0x69, 0x41, 0x7d, 0xd7, 0x11, + 0xd5, 0x3c, 0x33, 0xdf, 0x54, 0x04, 0xfd, 0x1d, 0xa8, 0x39, 0x0d, 0xdf, + 0x2f, 0x44, 0x65, 0x62, 0xe1, 0x47, 0x91, 0x8d, 0xbf, 0x61, 0x78, 0x54, + 0x72, 0xa7, 0x69, 0xa3, 0xa7, 0xe5, 0xf1, 0x8a, 0xef, 0xdf, 0xe9, 0x11, + 0x5b, 0x6e, 0x96, 0xcb, 0xf1, 0xb1, 0x3d, 0x6f, 0xb8, 0x1d, 0xa1, 0xea, + 0x6c, 0x33, 0x74, 0x2f, 0xf1, 0x8c, 0xb4, 0x30, 0xbf, 0x30, 0xcb, 0x7d, + 0x1a, 0xc1, 0x1a, 0x1d, 0xfb, 0x9a, 0xdc, 0xde, 0xce, 0xb8, 0xdb, 0x9d, + 0xf0, 0x65, 0x7f, 0xdb, 0x0b, 0xf4, 0xf5, 0xe7, 0x16, 0xf7, 0xca, 0xe7, + 0x6a, 0xb1, 0x50, 0x75, 0x86, 0xf7, 0x0d, 0x9d, 0x91, 0x8a, 0xa4, 0x50, + 0x8f, 0xfd, 0x43, 0x5e, 0x12, 0xd7, 0xc9, 0xb3, 0x27, 0x7f, 0xea, 0x5f, + 0x73, 0xf1, 0x1e, 0xba, 0xe6, 0xb2, 0x67, 0x62, 0x8b, 0x63, 0xf0, 0x5d, + 0x59, 0xef, 0x3a, 0xc8, 0x01, 0xb0, 0x03, 0xf6, 0x1c, 0xfd, 0xdc, 0x6b, + 0x5a, 0x6f, 0x59, 0xc7, 0x6e, 0x92, 0x6b, 0x2b, 0xf7, 0x95, 0x5f, 0x83, + 0x6c, 0x27, 0x03, 0xfa, 0xab, 0x58, 0xfc, 0x21, 0x09, 0x7f, 0x1e, 0x36, + 0xe5, 0xf3, 0x4d, 0x4a, 0xb7, 0xd3, 0xb6, 0xc1, 0x07, 0x82, 0x9f, 0x13, + 0x41, 0x3f, 0xa9, 0xf6, 0x40, 0x66, 0xa7, 0x45, 0xbe, 0xb0, 0x49, 0xb2, + 0xed, 0xf4, 0xa3, 0xe5, 0xe7, 0xe8, 0xaf, 0xc6, 0x7d, 0x96, 0x96, 0x3f, + 0xe2, 0x1e, 0xaf, 0x73, 0x2d, 0xa9, 0xc4, 0x9f, 0xc9, 0xa7, 0x65, 0x22, + 0xc1, 0xb5, 0x3c, 0x2a, 0xc5, 0xca, 0x63, 0xf8, 0x71, 0x9d, 0x9c, 0xf7, + 0xc7, 0xf4, 0x5d, 0x86, 0x31, 0x29, 0xcd, 0x64, 0x64, 0x6a, 0x6e, 0x92, + 0xdf, 0xa0, 0x8e, 0xdc, 0xa9, 0xce, 0xf8, 0x9c, 0x44, 0x2a, 0xb4, 0x2d, + 0x39, 0xc5, 0xbb, 0x1b, 0x6a, 0x3d, 0x93, 0x58, 0xcf, 0xe3, 0xed, 0xbc, + 0xb3, 0x7e, 0x0d, 0xfa, 0xd7, 0x3a, 0x45, 0x39, 0x74, 0xec, 0xee, 0x10, + 0xf3, 0xfb, 0xe0, 0xbf, 0xb3, 0x6c, 0x9f, 0x84, 0x8f, 0xad, 0xe8, 0x79, + 0x94, 0xeb, 0xb3, 0x66, 0xd5, 0xfe, 0x14, 0xda, 0xa2, 0xde, 0x31, 0xd3, + 0xd6, 0xd4, 0x61, 0x5b, 0xae, 0x73, 0xaf, 0x34, 0x9f, 0x33, 0xf3, 0x82, + 0x1c, 0x26, 0x1a, 0xe9, 0xdd, 0xb2, 0x8e, 0xde, 0x11, 0x62, 0x5e, 0xd0, + 0x8b, 0x34, 0x0e, 0x6b, 0x1a, 0x7f, 0x05, 0xfd, 0x1b, 0x1e, 0xdc, 0x89, + 0x32, 0x5b, 0x7f, 0x93, 0xf4, 0x7e, 0xe8, 0x4e, 0x9a, 0xb3, 0x3e, 0xe9, + 0x4e, 0xd9, 0xe2, 0x7c, 0x36, 0xa2, 0xf9, 0xeb, 0x9a, 0x2f, 0xfb, 0x40, + 0x2f, 0xde, 0x2b, 0xdd, 0xa6, 0xbe, 0x2f, 0xc8, 0x8e, 0xef, 0x83, 0xec, + 0x98, 0x75, 0x6d, 0x83, 0x8c, 0xf1, 0xdc, 0x84, 0xf5, 0x1b, 0x69, 0x12, + 0xd8, 0xbd, 0x30, 0x63, 0x1f, 0x2e, 0xd7, 0x0a, 0x5c, 0xfa, 0x05, 0xda, + 0x28, 0x7e, 0x63, 0x7d, 0xb3, 0xb6, 0x51, 0x3f, 0x8f, 0xc7, 0x3f, 0x6a, + 0x0f, 0x6c, 0x94, 0x0d, 0x9a, 0xb4, 0xe9, 0x36, 0xfb, 0x80, 0x91, 0x19, + 0x0f, 0x4e, 0x25, 0x1e, 0x14, 0x33, 0x8e, 0xbf, 0x9b, 0x7e, 0xef, 0xd0, + 0xc0, 0x36, 0xa0, 0x16, 0x75, 0x67, 0x27, 0xc1, 0x3b, 0x40, 0xa9, 0xd0, + 0x3e, 0x75, 0x7f, 0x63, 0xed, 0xf7, 0x23, 0x69, 0x79, 0x76, 0x55, 0x56, + 0x46, 0x7e, 0x28, 0x8e, 0x24, 0x6f, 0xa4, 0xac, 0xb0, 0xdf, 0x49, 0xae, + 0x33, 0xf1, 0x90, 0x5a, 0xa7, 0x0d, 0x3f, 0x92, 0x77, 0x2d, 0xec, 0x50, + 0x75, 0x8e, 0x7c, 0x47, 0xba, 0xc8, 0x67, 0x73, 0xde, 0xab, 0xf4, 0x0a, + 0xc6, 0x65, 0x19, 0x75, 0x23, 0xdf, 0x67, 0xf4, 0x79, 0x70, 0x7b, 0x07, + 0xef, 0x24, 0x14, 0x50, 0x56, 0x59, 0xdc, 0x78, 0x6e, 0xbf, 0xad, 0xe4, + 0xe0, 0x51, 0xd0, 0xfd, 0x9f, 0xa1, 0xee, 0x63, 0x48, 0xb9, 0xc6, 0xcc, + 0x0a, 0xdf, 0x49, 0xef, 0x8f, 0xca, 0x20, 0xe4, 0x82, 0xf9, 0x47, 0x81, + 0x37, 0x69, 0x4f, 0x91, 0x56, 0xf8, 0x4c, 0x5d, 0xef, 0x6a, 0x7b, 0xca, + 0xb9, 0xec, 0xc3, 0x5c, 0xd4, 0x3a, 0xb5, 0x3c, 0xdd, 0xaf, 0xdb, 0x8d, + 0xaf, 0xd0, 0xea, 0xa1, 0x77, 0xe0, 0x8d, 0xe8, 0x0a, 0xde, 0x08, 0xc6, + 0xca, 0x76, 0x18, 0xac, 0x11, 0xac, 0x21, 0xc0, 0x1a, 0x81, 0x9c, 0x4f, + 0x4a, 0x04, 0x72, 0x1c, 0x5e, 0x95, 0x63, 0xe0, 0x9e, 0x60, 0xcf, 0x4c, + 0xf1, 0x1c, 0x53, 0xd1, 0x99, 0x72, 0x48, 0xf9, 0x25, 0x1f, 0x1b, 0x79, + 0x7d, 0xfb, 0xbb, 0xf0, 0xba, 0xd4, 0x61, 0xf0, 0xc3, 0x3f, 0x6c, 0x1f, + 0x3c, 0xd2, 0xb1, 0xba, 0x0f, 0x6e, 0xfa, 0x05, 0xed, 0x83, 0xf5, 0x72, + 0xd9, 0x28, 0x53, 0x36, 0xe4, 0x89, 0xfc, 0xa2, 0x3c, 0x51, 0x8e, 0x48, + 0x4b, 0xea, 0xd3, 0x66, 0xfa, 0x6f, 0x89, 0xab, 0xea, 0xdb, 0x91, 0x69, + 0xe8, 0xa0, 0x8e, 0x50, 0xa5, 0x12, 0x97, 0xd2, 0xe2, 0x4f, 0x94, 0x4c, + 0x3f, 0x5b, 0xa7, 0x5e, 0x7a, 0xaf, 0xb5, 0xaf, 0xd5, 0xb9, 0x85, 0x75, + 0x3a, 0xb7, 0xb0, 0xa2, 0x73, 0xdb, 0xb5, 0xcf, 0xf6, 0x0f, 0xd1, 0xb9, + 0xf1, 0x86, 0xb3, 0x21, 0x73, 0x2e, 0x24, 0xa1, 0x5c, 0x5f, 0x8b, 0xec, + 0x81, 0x1d, 0x19, 0x99, 0xd9, 0x2b, 0x7f, 0x30, 0x33, 0xad, 0xee, 0x49, + 0x7d, 0xd3, 0x4b, 0x25, 0x3e, 0x11, 0xf2, 0xe5, 0xa3, 0xf0, 0xb9, 0x27, + 0xba, 0x9a, 0x64, 0xcf, 0x6d, 0xea, 0xbc, 0xd3, 0xce, 0x85, 0x3a, 0x85, + 0x91, 0xf8, 0xbc, 0xe7, 0x78, 0xc9, 0x10, 0xef, 0xcc, 0x35, 0xcb, 0x44, + 0xbc, 0x55, 0xf6, 0x02, 0x3b, 0x15, 0xaf, 0xf7, 0xd4, 0x37, 0xd3, 0x59, + 0x75, 0x9e, 0xf4, 0x86, 0xe6, 0x3b, 0xe8, 0xd0, 0x66, 0xcb, 0x7f, 0xac, + 0x33, 0xcf, 0xf2, 0x07, 0xd7, 0xe5, 0xf9, 0xfc, 0x04, 0xfc, 0xb9, 0x38, + 0x68, 0xd5, 0x78, 0xff, 0x28, 0xac, 0xe8, 0x59, 0xaa, 0x8c, 0xab, 0x7b, + 0x5d, 0x57, 0xc3, 0xa4, 0x97, 0xf2, 0xa1, 0x12, 0xb9, 0x30, 0x30, 0xce, + 0x2c, 0x90, 0xb4, 0x4b, 0xbf, 0x53, 0xe3, 0x4f, 0xe8, 0xff, 0xfd, 0xea, + 0x7c, 0x79, 0x19, 0xb4, 0xf1, 0x55, 0xfc, 0xb9, 0x10, 0x27, 0xae, 0x5f, + 0xbd, 0xc3, 0xfc, 0x4e, 0x7c, 0xaf, 0xb0, 0xbd, 0x39, 0x0b, 0xd1, 0xf1, + 0x2a, 0x1d, 0x07, 0x50, 0x67, 0x7b, 0x1b, 0xfd, 0xbf, 0x0b, 0xc4, 0x7a, + 0xfc, 0xae, 0x9f, 0xd8, 0xce, 0x39, 0x5a, 0x91, 0x1f, 0x2a, 0x5f, 0x34, + 0x4b, 0xfa, 0x56, 0xc1, 0xa7, 0xe3, 0x09, 0x63, 0xcf, 0x43, 0xdd, 0xe7, + 0x1b, 0x7d, 0x51, 0xf6, 0x11, 0x53, 0x77, 0x42, 0x56, 0xff, 0x9f, 0x17, + 0xc6, 0x98, 0xb2, 0xa1, 0xbb, 0xcb, 0xd3, 0x12, 0x3e, 0x31, 0x26, 0x91, + 0xe3, 0x8c, 0xe7, 0x67, 0xa5, 0x14, 0xf7, 0xe5, 0x01, 0x6f, 0xad, 0x6f, + 0xd2, 0x6d, 0xad, 0x9f, 0xfb, 0xa3, 0x32, 0x74, 0xfa, 0x31, 0x89, 0x9e, + 0xe0, 0xbb, 0x35, 0x67, 0x39, 0xd0, 0x47, 0x9b, 0xa5, 0x12, 0x67, 0x4c, + 0x3b, 0xaa, 0xce, 0xc6, 0x2f, 0x8f, 0xbf, 0x1e, 0x2d, 0x01, 0x2b, 0x14, + 0x94, 0x6e, 0x41, 0xba, 0xe2, 0x4b, 0xe4, 0xae, 0xe3, 0x9e, 0x82, 0xbf, + 0x19, 0x9a, 0xa8, 0x44, 0xd5, 0x1d, 0xa5, 0xcb, 0x71, 0xd6, 0x7d, 0x0c, + 0x7e, 0x37, 0x71, 0x06, 0x74, 0xc7, 0x98, 0xb4, 0x30, 0x1f, 0x3e, 0xb1, + 0x8a, 0x33, 0xa8, 0x13, 0x86, 0xbc, 0xb8, 0x44, 0xce, 0x04, 0x6b, 0xe7, + 0x7f, 0x1c, 0x64, 0xcd, 0xef, 0x95, 0xf0, 0x71, 0x3e, 0x37, 0xfa, 0x43, + 0xc4, 0xee, 0xb0, 0x0d, 0xe7, 0x7f, 0x1f, 0xfd, 0xf1, 0x5d, 0x56, 0x7f, + 0x87, 0x8b, 0x7c, 0xf5, 0xef, 0xfa, 0x7f, 0x04, 0x50, 0xf6, 0xff, 0x3f, + 0xc3, 0x8e, 0xbb, 0xb0, 0xa8, 0x4d, 0x00, 0x00, 0x00 }; static const u32 bnx2_COM_b06FwData[(0x0/4) + 1] = { 0x0 }; static const u32 bnx2_COM_b06FwRodata[(0x14/4) + 1] = { - 0x08000e7c, 0x08000ec4, 0x08000ef8, 0x08000f44, 0x08000f78, 0x00000000 + 0x08000e7c, 0x08000ec4, 0x08000f04, 0x08000f50, 0x08000f84, 0x00000000 }; static struct fw_info bnx2_com_fw_06 = { - /* Firmware version: 4.4.2 */ + /* Firmware version: 4.6.16 */ .ver_major = 0x4, - .ver_minor = 0x4, - .ver_fix = 0x2, + .ver_minor = 0x6, + .ver_fix = 0x10, .start_addr = 0x080000f8, .text_addr = 0x08000000, - .text_len = 0x4ebc, + .text_len = 0x4da4, .text_index = 0x0, .gz_text = bnx2_COM_b06FwText, .gz_text_len = sizeof(bnx2_COM_b06FwText), @@ -872,15 +867,15 @@ static struct fw_info bnx2_com_fw_06 = { .data_index = 0x0, .data = bnx2_COM_b06FwData, - .sbss_addr = 0x08004f00, + .sbss_addr = 0x08004de0, .sbss_len = 0x38, .sbss_index = 0x0, - .bss_addr = 0x08004f38, + .bss_addr = 0x08004e18, .bss_len = 0xbc, .bss_index = 0x0, - .rodata_addr = 0x08004ebc, + .rodata_addr = 0x08004da4, .rodata_len = 0x14, .rodata_index = 0x0, .rodata = bnx2_COM_b06FwRodata, @@ -903,1232 +898,1219 @@ static const struct cpu_reg cpu_reg_com = { }; static u8 bnx2_CP_b06FwText[] = { - 0x9d, 0xbc, 0x0d, 0x78, 0x1b, 0xe5, 0x95, 0x36, 0x7c, 0xcf, 0x48, 0xb2, - 0x65, 0x5b, 0xb6, 0xc7, 0x8e, 0x9c, 0x28, 0x6c, 0x9a, 0x68, 0xf0, 0x28, - 0x51, 0xb0, 0x69, 0x47, 0x89, 0x03, 0x82, 0x55, 0x89, 0xea, 0x98, 0xc4, - 0x81, 0x50, 0x9c, 0x12, 0x5a, 0xb3, 0x4b, 0x5b, 0xe1, 0xfc, 0x60, 0x42, - 0xa0, 0xa1, 0xb0, 0xef, 0x9a, 0xef, 0x65, 0x5f, 0xab, 0xb6, 0x93, 0x38, - 0x89, 0x2c, 0x39, 0x8e, 0x21, 0x61, 0xbf, 0x5e, 0x8b, 0x89, 0x9d, 0x38, - 0x80, 0x6c, 0x85, 0x36, 0xdd, 0x0d, 0x7d, 0xd3, 0x8d, 0x36, 0x09, 0x60, - 0xfe, 0xda, 0x40, 0xbb, 0x2c, 0xed, 0xcb, 0x07, 0xde, 0x14, 0x42, 0xd8, - 0xb6, 0x40, 0xb7, 0x3f, 0x1b, 0x5a, 0xca, 0xbc, 0xf7, 0x19, 0x49, 0x89, - 0x13, 0x28, 0xed, 0x7e, 0xbe, 0xae, 0xb9, 0xac, 0x99, 0x79, 0x7e, 0xce, - 0x73, 0x9e, 0x73, 0xee, 0x73, 0x9f, 0x67, 0x9e, 0x19, 0x3f, 0x50, 0x8a, - 0xfc, 0x5f, 0x39, 0x8f, 0x4f, 0x37, 0x6c, 0x5c, 0xbd, 0x60, 0xc1, 0xa7, - 0x1b, 0xe4, 0xdc, 0x39, 0xdd, 0xe9, 0xc4, 0x9f, 0xf9, 0xe7, 0xff, 0x73, - 0x0b, 0x7e, 0xcc, 0x9f, 0x03, 0xd0, 0x0a, 0xfd, 0xcb, 0x01, 0xb7, 0x1a, - 0x71, 0xde, 0xdc, 0x68, 0xc0, 0xed, 0x88, 0x4c, 0xb4, 0xad, 0x36, 0x80, - 0x68, 0xba, 0xce, 0xbf, 0x04, 0x7f, 0xb0, 0xe2, 0x5e, 0x27, 0xe4, 0xfa, - 0xa7, 0x22, 0x1f, 0x74, 0x7e, 0xef, 0x72, 0xfd, 0xbd, 0x21, 0x07, 0xdc, - 0x5a, 0x24, 0x0e, 0x6d, 0x2e, 0xdc, 0xb3, 0x58, 0xe7, 0x9b, 0xf3, 0xbe, - 0xa9, 0xa0, 0xa2, 0xd0, 0xd6, 0x69, 0xeb, 0x7b, 0xf3, 0x7c, 0xb1, 0x92, - 0x88, 0x86, 0x23, 0x19, 0xb4, 0xd4, 0xf7, 0x75, 0x5a, 0xe5, 0x46, 0x08, - 0x6e, 0xc3, 0x68, 0xed, 0x53, 0x3c, 0xe1, 0xf5, 0x8b, 0xe0, 0x29, 0x36, - 0x10, 0xbf, 0x28, 0x82, 0x96, 0x4b, 0xc6, 0x4a, 0xe3, 0xce, 0x88, 0x1b, - 0xcd, 0x19, 0x77, 0xfc, 0x2f, 0x22, 0x06, 0x96, 0x65, 0x66, 0x95, 0xa2, - 0xc2, 0x8d, 0x9e, 0xcc, 0xeb, 0x25, 0xb9, 0xf6, 0xea, 0xf3, 0xff, 0x83, - 0xd3, 0x72, 0xff, 0xa7, 0xc7, 0x9c, 0x11, 0x60, 0x53, 0xc2, 0xb2, 0x8a, - 0x22, 0x37, 0xdc, 0xa0, 0x46, 0x0c, 0xdf, 0x3e, 0x2c, 0x46, 0x9b, 0x86, - 0xfb, 0x36, 0x37, 0xfc, 0xa7, 0x72, 0x74, 0x90, 0x0d, 0x8f, 0x3a, 0x10, - 0xd5, 0x8e, 0xf3, 0xff, 0xec, 0xd9, 0xad, 0x61, 0x03, 0xbb, 0x47, 0xcf, - 0xf0, 0xba, 0xd3, 0xbe, 0xd6, 0xbd, 0x6b, 0xf6, 0xec, 0x9b, 0xc2, 0xc7, - 0xf1, 0xe0, 0xa8, 0xfc, 0xbe, 0x15, 0x9d, 0xf5, 0x0a, 0x26, 0x6f, 0x58, - 0x07, 0x87, 0x61, 0xa0, 0x67, 0x97, 0xe2, 0xec, 0xaa, 0x57, 0x11, 0xf5, - 0xea, 0xc1, 0x18, 0x27, 0xc1, 0x69, 0x20, 0x56, 0x1c, 0x09, 0x3b, 0xdf, - 0x4e, 0x44, 0x34, 0x87, 0x61, 0x59, 0xc1, 0xd0, 0x0c, 0x38, 0xaa, 0x2c, - 0xeb, 0x09, 0xd3, 0x03, 0xff, 0x97, 0x9e, 0x42, 0x7c, 0xb8, 0x05, 0xaa, - 0xf1, 0x14, 0xba, 0x86, 0x9f, 0xc2, 0x43, 0x3b, 0x4b, 0x31, 0x39, 0x8d, - 0xe3, 0x4d, 0xf9, 0xf0, 0xbd, 0x79, 0xd2, 0xb7, 0xc8, 0x51, 0xcf, 0xc3, - 0x8d, 0x49, 0xc7, 0x6b, 0xfc, 0x2f, 0x65, 0xce, 0x58, 0x93, 0x33, 0xce, - 0x95, 0xd9, 0xc4, 0x32, 0x3d, 0x17, 0x94, 0x89, 0x0f, 0x47, 0xf0, 0x5c, - 0x42, 0xc1, 0xfa, 0x50, 0x05, 0xa2, 0x55, 0x32, 0x5e, 0xcb, 0x1a, 0x35, - 0x4f, 0x59, 0x93, 0x9a, 0xf4, 0x35, 0x81, 0xe7, 0x79, 0x6f, 0x73, 0xe8, - 0x0d, 0x2b, 0xeb, 0x95, 0xf6, 0xbe, 0x4e, 0x1b, 0x5a, 0xc9, 0xeb, 0x4e, - 0xa4, 0x12, 0x88, 0x55, 0x44, 0x6e, 0xe4, 0xb9, 0x6e, 0xbe, 0xa3, 0xb8, - 0xdd, 0xef, 0x26, 0xdc, 0x5f, 0x2a, 0x37, 0xd4, 0x7b, 0x2a, 0xe1, 0xc4, - 0x0b, 0x94, 0xf9, 0x90, 0xb9, 0x0e, 0x2e, 0xe3, 0x6e, 0xb1, 0x39, 0x8e, - 0xeb, 0x47, 0x16, 0x66, 0x14, 0xea, 0x4b, 0xbb, 0x6e, 0x6c, 0x4e, 0x59, - 0xd6, 0x56, 0x33, 0x7a, 0x45, 0x09, 0x0d, 0xe2, 0x58, 0xa2, 0x05, 0xee, - 0x48, 0xc0, 0x7f, 0x1a, 0x61, 0x2c, 0xc9, 0x78, 0xf1, 0x64, 0x02, 0xce, - 0xc6, 0x79, 0x5e, 0x74, 0x65, 0x22, 0xb8, 0x3a, 0x63, 0xa2, 0x29, 0xf3, - 0xa7, 0x2d, 0xeb, 0xda, 0x94, 0x9f, 0x63, 0xf8, 0x83, 0x95, 0x1b, 0x83, - 0x8c, 0x2f, 0xf7, 0xbf, 0x27, 0x75, 0x11, 0xb6, 0x71, 0x8e, 0xb6, 0x70, - 0xfe, 0x96, 0x87, 0xb2, 0xd1, 0x12, 0xe8, 0xe6, 0x69, 0x44, 0xb0, 0x34, - 0x63, 0x70, 0x4e, 0x23, 0x58, 0x92, 0xaa, 0xd5, 0x86, 0x31, 0x1f, 0x51, - 0x5f, 0xce, 0xb6, 0xb7, 0x73, 0xbc, 0x6d, 0x81, 0x16, 0x94, 0xd3, 0x46, - 0xd2, 0x8b, 0xc2, 0x68, 0x64, 0xff, 0x2b, 0xfe, 0x8c, 0xfe, 0xaf, 0x67, - 0xff, 0xef, 0xb0, 0xff, 0xac, 0xdd, 0x3f, 0x9c, 0xd7, 0xf0, 0xdc, 0x4d, - 0x7b, 0xdc, 0x96, 0x76, 0x3a, 0x97, 0xa7, 0xbc, 0xd8, 0x9a, 0x36, 0x69, - 0x73, 0x72, 0xcb, 0x87, 0xcd, 0x83, 0xb3, 0xb0, 0x65, 0x50, 0xf7, 0x3d, - 0xcd, 0xdf, 0xdd, 0x23, 0x17, 0x61, 0xd3, 0xa0, 0x82, 0x3d, 0xc6, 0x45, - 0xe8, 0xe2, 0xef, 0xdd, 0x83, 0xb3, 0xf1, 0xe0, 0xa0, 0x03, 0xe1, 0x69, - 0xe7, 0x8f, 0x63, 0xd2, 0x71, 0x11, 0xe2, 0x23, 0x7e, 0x74, 0x25, 0x9e, - 0xb7, 0x75, 0x58, 0x1e, 0xf9, 0x5e, 0xc1, 0x9f, 0xe9, 0x3b, 0x7e, 0xac, - 0x4e, 0x68, 0xe8, 0x4a, 0x89, 0x1f, 0xb8, 0x69, 0x9b, 0xe2, 0x07, 0xbf, - 0x06, 0x2a, 0x34, 0x74, 0x67, 0x0a, 0xf7, 0x15, 0x38, 0x39, 0x6f, 0x6b, - 0x34, 0x37, 0xb6, 0xa6, 0xc4, 0x26, 0xa4, 0x4d, 0xb1, 0x0b, 0xf9, 0x5d, - 0x4d, 0xbb, 0x2b, 0x85, 0x7f, 0x6f, 0x29, 0x82, 0xf7, 0x6b, 0x78, 0xb3, - 0x41, 0xae, 0xd3, 0xde, 0x43, 0x52, 0xa6, 0x1f, 0xfb, 0xd2, 0xe2, 0xa7, - 0x7e, 0x34, 0x26, 0x26, 0xd8, 0x7e, 0x03, 0xdb, 0x36, 0xf1, 0xcf, 0x99, - 0x7a, 0xfc, 0x53, 0x26, 0x88, 0x7f, 0xa4, 0x1e, 0xbf, 0x93, 0xf1, 0xe3, - 0x60, 0x66, 0x16, 0xbe, 0x9d, 0xf1, 0xe1, 0x5b, 0x9c, 0xbf, 0xc7, 0x33, - 0x2d, 0xb4, 0x7d, 0x0d, 0x07, 0x32, 0xa2, 0xff, 0x22, 0x8e, 0xb7, 0x14, - 0xdd, 0x83, 0xb5, 0xc1, 0x63, 0xb4, 0xad, 0x7f, 0x34, 0xaf, 0x41, 0xb6, - 0xba, 0xc1, 0xb6, 0xc9, 0xad, 0xbc, 0xbe, 0x6d, 0xb0, 0x36, 0x7a, 0x89, - 0x62, 0x59, 0x6a, 0xa8, 0x2e, 0x7c, 0x54, 0x55, 0x31, 0xe9, 0xd5, 0xfd, - 0x59, 0x55, 0xf7, 0x47, 0xe1, 0x42, 0x82, 0xbe, 0x11, 0xaf, 0xd1, 0x87, - 0xe2, 0xb4, 0x29, 0xaf, 0x31, 0xcc, 0xf1, 0xe8, 0xfe, 0xb8, 0xea, 0xc6, - 0x96, 0x94, 0xbe, 0x3b, 0xae, 0x7a, 0x10, 0xcf, 0x94, 0xe2, 0x17, 0x83, - 0x7a, 0x6f, 0x5c, 0xfd, 0x3c, 0xe2, 0xd5, 0x96, 0xf5, 0xad, 0x10, 0x36, - 0xce, 0x88, 0x20, 0x5a, 0x13, 0x41, 0x6c, 0x76, 0xc4, 0x8b, 0x54, 0x0a, - 0x78, 0xa7, 0xcf, 0xf0, 0xfd, 0x9b, 0xd2, 0x82, 0xbf, 0x69, 0xd1, 0xfd, - 0x7e, 0xb5, 0x2e, 0x3e, 0xac, 0x2e, 0xa2, 0x4b, 0xc3, 0xef, 0x8b, 0x2c, - 0x43, 0x87, 0x7d, 0x4d, 0x81, 0x66, 0x78, 0xd0, 0x9d, 0xba, 0x02, 0x31, - 0x6f, 0x6d, 0xeb, 0x0e, 0xb5, 0xf6, 0x8c, 0xa9, 0xea, 0x13, 0x2d, 0xaa, - 0x65, 0xfd, 0x72, 0xe1, 0x3b, 0x96, 0x7f, 0xba, 0x65, 0x2d, 0x58, 0x28, - 0x7d, 0xfa, 0x51, 0x15, 0x31, 0xb1, 0xd2, 0x9e, 0xc3, 0x52, 0x9c, 0x1a, - 0xac, 0x66, 0x1f, 0x1a, 0xfe, 0xf5, 0x72, 0x3d, 0xb8, 0x4e, 0x2d, 0xc5, - 0x9b, 0x23, 0xa5, 0x38, 0xc9, 0xf1, 0xfc, 0xe7, 0xa0, 0x0f, 0xbf, 0x1e, - 0xb4, 0xac, 0x2f, 0x99, 0x7f, 0x89, 0x81, 0xea, 0x7e, 0xfc, 0xd3, 0xb8, - 0x17, 0xbf, 0xe0, 0xdc, 0xbc, 0x91, 0x88, 0xde, 0x35, 0x0d, 0x7a, 0x74, - 0x5c, 0x39, 0xf6, 0xd5, 0x0a, 0xd4, 0xb5, 0x54, 0x28, 0x7a, 0xf3, 0x76, - 0xe8, 0xbe, 0x4b, 0x14, 0x2f, 0x4e, 0xa7, 0x35, 0xfc, 0x34, 0x5d, 0x1b, - 0xfe, 0x21, 0xfb, 0xfc, 0xad, 0xf9, 0x84, 0x95, 0x9d, 0x2e, 0x7a, 0x13, - 0x1d, 0x51, 0xcf, 0x29, 0xea, 0x39, 0x45, 0x3d, 0xa7, 0xa8, 0x67, 0xca, - 0x70, 0x30, 0x45, 0x3d, 0x53, 0x77, 0xdf, 0xa2, 0x4d, 0x3d, 0xce, 0x79, - 0x3c, 0x60, 0xcf, 0x63, 0x98, 0xf3, 0xf5, 0x17, 0xf8, 0x5f, 0x36, 0xb6, - 0x3e, 0x6f, 0xfd, 0xad, 0x57, 0xc6, 0xd4, 0x3d, 0x3d, 0x87, 0x5f, 0x32, - 0xb6, 0xe7, 0xac, 0x98, 0x26, 0xe3, 0x92, 0xf1, 0xd9, 0xfa, 0xf3, 0x6f, - 0x54, 0xb6, 0x28, 0x28, 0xb5, 0xac, 0x9d, 0x66, 0xfe, 0xbe, 0xb7, 0x30, - 0xbe, 0x1b, 0x94, 0x9c, 0x5d, 0xed, 0x74, 0x53, 0xdf, 0xc1, 0xa8, 0xba, - 0x8c, 0xe7, 0x7a, 0x3c, 0x8a, 0xb9, 0xc5, 0xe7, 0x9f, 0x5f, 0x5b, 0x23, - 0xf3, 0xe1, 0x3f, 0x7b, 0x4e, 0x7b, 0xb4, 0xfb, 0xbb, 0x8d, 0xe7, 0x32, - 0x16, 0xb1, 0x45, 0xb1, 0x01, 0x2f, 0xed, 0xe5, 0xf2, 0xfc, 0x3d, 0xc4, - 0xd5, 0xc8, 0x46, 0xb4, 0x34, 0x3c, 0x6a, 0xf7, 0x51, 0x94, 0x14, 0xbf, - 0x51, 0xf0, 0xce, 0x15, 0x0a, 0x8e, 0x86, 0x0c, 0xda, 0xcc, 0x10, 0x71, - 0x01, 0x28, 0x4e, 0xc2, 0xed, 0x89, 0x44, 0x90, 0xe8, 0x83, 0xbb, 0x24, - 0x12, 0xc6, 0xfc, 0xbe, 0xda, 0xf6, 0x53, 0xd0, 0x83, 0x7d, 0x8a, 0xde, - 0x02, 0xd4, 0x99, 0x63, 0xd4, 0xe3, 0x25, 0x8a, 0xee, 0x2f, 0x52, 0xe0, - 0x56, 0x58, 0x2e, 0x90, 0x1e, 0xc2, 0x96, 0x8c, 0xfc, 0x0e, 0xc3, 0x48, - 0xff, 0xb6, 0xd0, 0x17, 0xed, 0x7e, 0x23, 0xed, 0xfe, 0x14, 0xc7, 0xae, - 0xfb, 0x89, 0xaf, 0x6e, 0x57, 0xa4, 0x1d, 0x7b, 0x13, 0x70, 0x17, 0x45, - 0x36, 0xe0, 0xa9, 0x44, 0xf5, 0xf4, 0x42, 0x39, 0x85, 0xe5, 0xfc, 0xe9, - 0xa9, 0xb2, 0xbc, 0x66, 0x45, 0xbd, 0x39, 0x59, 0x4a, 0x93, 0x43, 0xd8, - 0x9e, 0x92, 0xba, 0x11, 0xbb, 0xae, 0x93, 0x7d, 0xf4, 0x24, 0x6a, 0x9b, - 0xaf, 0x55, 0xf4, 0xf0, 0x23, 0xa8, 0x8b, 0xbe, 0xcd, 0x39, 0xec, 0x82, - 0x7e, 0xa6, 0x1d, 0x39, 0x59, 0xe6, 0xa5, 0x73, 0x72, 0x2c, 0x4e, 0x43, - 0xb9, 0x29, 0x05, 0x8f, 0xcf, 0x98, 0x96, 0xf7, 0x65, 0x28, 0xd7, 0x71, - 0xfe, 0x54, 0xc3, 0x8f, 0xeb, 0x68, 0x43, 0x1b, 0x76, 0x5a, 0xe8, 0x0e, - 0x55, 0xd3, 0x57, 0x5b, 0x50, 0x41, 0xbf, 0xbc, 0x53, 0x43, 0xb4, 0x32, - 0x12, 0x56, 0xae, 0xcf, 0x0c, 0xe7, 0xf5, 0x7f, 0xb4, 0x9a, 0xf2, 0x29, - 0x4d, 0xa9, 0x0b, 0xaf, 0x57, 0xe6, 0xe3, 0xde, 0x85, 0xd7, 0x3d, 0x45, - 0x1f, 0x5f, 0xbe, 0x4e, 0x1b, 0x81, 0xc2, 0x78, 0x53, 0x42, 0xfd, 0xea, - 0x26, 0xab, 0x05, 0x5d, 0xf6, 0x35, 0x07, 0x86, 0x9c, 0x51, 0x9f, 0x03, - 0x1f, 0x58, 0xd1, 0x55, 0x72, 0xad, 0x14, 0xb1, 0x96, 0x3a, 0x9f, 0x13, - 0x75, 0xe1, 0x4d, 0xf4, 0xb7, 0xc9, 0x55, 0x8d, 0xbc, 0x17, 0x30, 0x8f, - 0xa1, 0xd6, 0xbf, 0x09, 0xf2, 0xfb, 0x7d, 0xda, 0x48, 0xa3, 0xd4, 0x65, - 0x19, 0xb1, 0x39, 0x5d, 0x3b, 0x06, 0x2f, 0x36, 0xd1, 0xfe, 0x8a, 0x23, - 0xba, 0xb9, 0xcc, 0xe1, 0xc4, 0x7e, 0xe2, 0xb8, 0xc3, 0xe8, 0x45, 0x31, - 0xc7, 0xc8, 0xf8, 0x8a, 0x47, 0x12, 0xc0, 0xb3, 0xfd, 0x16, 0x1a, 0x43, - 0x1e, 0x2c, 0xb1, 0x6d, 0xf3, 0x90, 0x72, 0x75, 0xea, 0x43, 0x6b, 0xc8, - 0x59, 0x12, 0x55, 0x23, 0x01, 0xdf, 0x49, 0xb2, 0x81, 0xa2, 0x48, 0x9d, - 0xe6, 0x44, 0x5c, 0x69, 0xce, 0xf4, 0x28, 0xcb, 0x33, 0xbd, 0xca, 0x92, - 0x8c, 0xb4, 0x7d, 0x48, 0x59, 0x9a, 0xf1, 0x20, 0xdd, 0xaf, 0x60, 0x7b, - 0x88, 0x72, 0xd5, 0xe4, 0xec, 0x38, 0xd3, 0xaf, 0x12, 0x63, 0xdf, 0x21, - 0xc6, 0xea, 0x61, 0xb0, 0xef, 0x27, 0x12, 0xd5, 0x38, 0x44, 0x2c, 0xfd, - 0x71, 0x5a, 0x57, 0x51, 0x7a, 0x11, 0x5e, 0x19, 0xa9, 0xc0, 0xd8, 0xa0, - 0xc9, 0xdf, 0xf5, 0x78, 0x61, 0xc4, 0xb2, 0x7a, 0x4c, 0xcb, 0xda, 0x6b, - 0x1e, 0x52, 0x1a, 0xd9, 0x67, 0xd4, 0x19, 0x8f, 0x16, 0x47, 0x02, 0xe6, - 0x16, 0xf6, 0xe9, 0x88, 0xc4, 0x95, 0x28, 0xfb, 0xbb, 0x9a, 0xfd, 0x2d, - 0xcd, 0xf7, 0x97, 0xeb, 0x57, 0x64, 0x91, 0x7a, 0x85, 0x3a, 0x61, 0xd6, - 0x01, 0xf6, 0x25, 0x02, 0xc1, 0x42, 0xbd, 0xa5, 0xac, 0x73, 0xf5, 0xd9, - 0x3a, 0xc0, 0x70, 0x22, 0xc8, 0x39, 0x15, 0x5b, 0xf7, 0x33, 0x76, 0x7d, - 0x83, 0x18, 0xdb, 0x80, 0xb6, 0x61, 0xc1, 0xdf, 0x6b, 0xd4, 0xdc, 0x3c, - 0xe5, 0xb0, 0x56, 0x62, 0x5e, 0x0e, 0x6f, 0x83, 0xe8, 0xa3, 0x5f, 0x77, - 0xa5, 0xc4, 0xc6, 0xef, 0xf9, 0x72, 0x22, 0xa0, 0xe0, 0xb1, 0x40, 0xb6, - 0xa5, 0x1c, 0x95, 0x68, 0x0f, 0x89, 0x6d, 0x6e, 0xfc, 0xf2, 0x53, 0x86, - 0x1e, 0x5e, 0xa1, 0x70, 0xce, 0x02, 0x7a, 0xf3, 0x52, 0x05, 0x08, 0x8c, - 0x01, 0x6f, 0xa4, 0x2b, 0xb1, 0xda, 0x74, 0x40, 0xad, 0x0a, 0xa2, 0x37, - 0x33, 0x35, 0x2e, 0x98, 0xc4, 0x78, 0x69, 0x2f, 0x48, 0xbf, 0x2e, 0xc3, - 0x32, 0x2d, 0x67, 0xd3, 0x6e, 0xb6, 0xed, 0x0e, 0x64, 0x83, 0x2a, 0xe3, - 0xdd, 0x7e, 0x5e, 0x38, 0x46, 0xfc, 0x6f, 0x34, 0x5c, 0xc4, 0xff, 0x4a, - 0x34, 0x9a, 0xbf, 0xb3, 0x96, 0xad, 0x92, 0x7b, 0x85, 0x76, 0xe0, 0x2e, - 0x66, 0xbf, 0x6f, 0x19, 0xba, 0x7f, 0x94, 0x27, 0xd9, 0x74, 0xee, 0x7a, - 0x9c, 0x31, 0xab, 0x9b, 0xed, 0x6e, 0x66, 0xbb, 0xeb, 0x34, 0x3d, 0x1a, - 0x3f, 0x5b, 0x2e, 0x1b, 0x74, 0x40, 0xd7, 0xa4, 0x6c, 0x13, 0xdb, 0x5d, - 0xcd, 0x76, 0x7b, 0x35, 0x91, 0xef, 0x77, 0xd6, 0xba, 0x55, 0x72, 0x2f, - 0x67, 0x1f, 0xb9, 0x76, 0xef, 0x91, 0x76, 0xcd, 0xd1, 0x7c, 0x5f, 0x47, - 0x13, 0xe8, 0x77, 0x44, 0x18, 0x63, 0x1b, 0x02, 0xfe, 0x2e, 0xc6, 0xdb, - 0x26, 0xc6, 0x8e, 0x9c, 0x4d, 0x4c, 0x8d, 0x77, 0x88, 0x9f, 0x2b, 0x23, - 0xd7, 0xa4, 0x9c, 0xd8, 0xda, 0x24, 0xf5, 0x2c, 0xf1, 0xc5, 0x47, 0xfd, - 0x0a, 0xb6, 0x38, 0x71, 0x20, 0x41, 0xfc, 0xc7, 0x37, 0x68, 0x77, 0x7e, - 0xb4, 0x64, 0x6a, 0xb1, 0x66, 0x27, 0xe3, 0xa0, 0x59, 0x45, 0x5b, 0xcf, - 0xd9, 0xdb, 0x32, 0xb6, 0x3d, 0x69, 0xb7, 0x1d, 0x57, 0x5a, 0x32, 0x75, - 0x5a, 0x15, 0x63, 0xee, 0x91, 0xb3, 0xd8, 0x39, 0x27, 0x5a, 0x1a, 0x09, - 0x34, 0xaf, 0xe7, 0x24, 0xb9, 0x19, 0xdf, 0xbe, 0x37, 0xaf, 0x87, 0x76, - 0xd1, 0x4b, 0x3b, 0xcc, 0xcd, 0x6f, 0x73, 0x66, 0x8f, 0x2a, 0x18, 0x07, - 0xb5, 0x16, 0xeb, 0x76, 0xca, 0x7f, 0x72, 0x95, 0x86, 0xc7, 0x78, 0xad, - 0x16, 0xab, 0x87, 0xbf, 0x47, 0x3b, 0xd3, 0x7d, 0x62, 0x87, 0x5d, 0x67, - 0xe5, 0x12, 0x99, 0x44, 0x36, 0x91, 0xa9, 0x8f, 0xe5, 0x66, 0x51, 0x3f, - 0x82, 0x8d, 0xd5, 0x94, 0x67, 0x2b, 0xf9, 0xd0, 0x21, 0xe5, 0xf3, 0x94, - 0x27, 0xeb, 0xf2, 0xe2, 0xa1, 0x94, 0xc8, 0xa3, 0x44, 0x67, 0x46, 0x66, - 0xe1, 0x4c, 0x2a, 0x10, 0x7f, 0x02, 0x22, 0x5b, 0x8f, 0xd2, 0x2a, 0xf5, - 0x53, 0xbd, 0xbc, 0x57, 0x90, 0x11, 0x5a, 0xa5, 0x2d, 0x5b, 0x4e, 0xa6, - 0xeb, 0x39, 0xd7, 0x2e, 0xe3, 0x6f, 0xcb, 0x51, 0xe1, 0xa4, 0xad, 0x49, - 0xdb, 0xff, 0x61, 0x45, 0xb5, 0x6e, 0x5e, 0xf3, 0x72, 0x9e, 0xdc, 0xe4, - 0x05, 0x7a, 0xf0, 0x3a, 0x87, 0xd2, 0xe2, 0x91, 0x78, 0x4d, 0xfb, 0x4c, - 0xa7, 0x9d, 0x38, 0x9e, 0x58, 0xba, 0xb4, 0xcc, 0xf8, 0x34, 0x1e, 0x1b, - 0xf1, 0x61, 0x84, 0x73, 0xfb, 0x6c, 0x42, 0xe2, 0xeb, 0x2c, 0x3c, 0x9a, - 0xf6, 0xe0, 0x99, 0x84, 0x1f, 0x8f, 0x30, 0xfe, 0x4c, 0x24, 0x0c, 0xec, - 0x4f, 0x7b, 0xf1, 0x34, 0xed, 0x79, 0x34, 0xed, 0xa3, 0xbd, 0xd4, 0x63, - 0x38, 0xdd, 0x66, 0x8f, 0xe1, 0xc9, 0xc4, 0xbf, 0xcb, 0x58, 0x83, 0x32, - 0xd6, 0xcd, 0xf6, 0x58, 0x0b, 0x71, 0x7e, 0xd6, 0xd9, 0x79, 0x38, 0x91, - 0xb0, 0x71, 0xa0, 0x77, 0x99, 0x43, 0xe6, 0x81, 0x36, 0x3b, 0x20, 0x58, - 0xa0, 0xf7, 0xc7, 0x61, 0x61, 0x8f, 0x39, 0x93, 0xfe, 0xdf, 0x4b, 0x79, - 0xa9, 0x53, 0x8e, 0x1f, 0xae, 0x8a, 0x68, 0x79, 0x24, 0x10, 0xeb, 0xa3, - 0xde, 0x9d, 0x11, 0xd1, 0x43, 0x4e, 0xef, 0x2b, 0x32, 0x87, 0x14, 0xe1, - 0x7a, 0x97, 0x0c, 0xc4, 0xad, 0x32, 0x43, 0xf4, 0x1d, 0x20, 0xce, 0x02, - 0xf3, 0xf7, 0x38, 0x39, 0xbe, 0x9b, 0x38, 0x66, 0x13, 0x45, 0x46, 0x9d, - 0x56, 0x4d, 0xd9, 0x8f, 0x7c, 0x24, 0x06, 0x8a, 0x8e, 0xfe, 0x36, 0x3f, - 0x5f, 0xba, 0x83, 0xf2, 0xfa, 0x81, 0xc2, 0xbc, 0x58, 0xd6, 0x0e, 0xb3, - 0x30, 0x37, 0x35, 0xf0, 0x57, 0xeb, 0xf1, 0x21, 0x5a, 0xc4, 0x48, 0x62, - 0x1a, 0xe2, 0x9a, 0x9a, 0x6f, 0x3b, 0xaa, 0x14, 0x31, 0xff, 0xc0, 0xb8, - 0xf8, 0x7e, 0x39, 0xa2, 0x4e, 0xa9, 0x8f, 0x68, 0x51, 0x24, 0x10, 0x9c, - 0xab, 0x4e, 0xb5, 0x19, 0xc1, 0x01, 0xe9, 0x2b, 0x4e, 0x59, 0xcf, 0xc7, - 0x82, 0x91, 0x44, 0x01, 0x37, 0xfe, 0x3b, 0xf5, 0x2e, 0xd4, 0xa9, 0xc8, - 0x29, 0x7a, 0x55, 0x71, 0x74, 0x50, 0xf4, 0xe7, 0xc4, 0x4a, 0x73, 0x7a, - 0x5e, 0xe6, 0x59, 0x9c, 0x17, 0x62, 0x0e, 0xe7, 0xeb, 0x85, 0x7e, 0x2f, - 0xe5, 0xb6, 0x90, 0x0e, 0x5d, 0x8c, 0x4d, 0x36, 0xe7, 0x5c, 0x95, 0xcf, - 0x5b, 0x38, 0x4f, 0xea, 0x76, 0xea, 0xfa, 0xb3, 0x8e, 0xdc, 0x79, 0x9d, - 0xef, 0xa3, 0xfa, 0xd2, 0xb5, 0x18, 0x0a, 0x3a, 0x03, 0x86, 0xd2, 0x88, - 0xb9, 0x23, 0xf5, 0x4d, 0xce, 0xbe, 0xb6, 0x0d, 0xf4, 0xef, 0x7b, 0x4f, - 0x35, 0x7c, 0x16, 0x9b, 0xa9, 0x17, 0xa7, 0x6d, 0x67, 0x51, 0xc5, 0x65, - 0x2c, 0xb1, 0xfd, 0x49, 0x1d, 0x5f, 0x91, 0xef, 0x23, 0x6a, 0xe7, 0x2c, - 0x50, 0x5b, 0xf2, 0xe7, 0x77, 0x53, 0xdf, 0x32, 0x0e, 0x15, 0x3f, 0x20, - 0x97, 0x7d, 0x27, 0xf4, 0x59, 0x64, 0x6d, 0xcc, 0x76, 0xd2, 0xdf, 0xaf, - 0x62, 0x5d, 0xe2, 0xdf, 0xb8, 0xc4, 0x52, 0xc4, 0x4b, 0xe8, 0xd7, 0x45, - 0xf4, 0xd5, 0x6b, 0x32, 0xf7, 0xa0, 0x3d, 0x15, 0x08, 0x97, 0x28, 0xf7, - 0xe0, 0xd6, 0x8c, 0x0b, 0xb1, 0x61, 0x0f, 0xd6, 0x51, 0x27, 0xce, 0xa4, - 0xf8, 0xb9, 0x86, 0x75, 0xa3, 0x47, 0x67, 0x3a, 0xe9, 0x37, 0xeb, 0x46, - 0xbd, 0x3c, 0xa6, 0xf3, 0x70, 0x63, 0x35, 0x8f, 0x3d, 0xb4, 0xcb, 0x36, - 0xc6, 0x86, 0x23, 0x09, 0x13, 0x9d, 0xd4, 0xd5, 0x13, 0x89, 0x06, 0xdc, - 0x4b, 0xbd, 0x1d, 0x4a, 0x7c, 0x8a, 0x3a, 0x0a, 0xa3, 0x83, 0x73, 0xfc, - 0x58, 0x42, 0xb5, 0xf3, 0xab, 0xdb, 0x33, 0xff, 0x62, 0x45, 0xa7, 0x8b, - 0x9c, 0xa2, 0x0b, 0x99, 0xcf, 0x8f, 0xe8, 0x81, 0xfe, 0x3b, 0x55, 0x17, - 0xf5, 0xd8, 0xb6, 0xcb, 0xc0, 0xf6, 0x5d, 0x75, 0xb4, 0xbb, 0x8c, 0xe5, - 0xaf, 0x1a, 0xa0, 0x0e, 0xa6, 0xea, 0xe1, 0x08, 0x79, 0x81, 0xe8, 0x41, - 0xda, 0xbc, 0x8f, 0x63, 0xee, 0xe6, 0x3d, 0x1f, 0x1e, 0x4f, 0x7c, 0x97, - 0xbf, 0xc3, 0xca, 0x5d, 0x19, 0xf1, 0x79, 0xf1, 0xb7, 0x7f, 0x70, 0xe4, - 0x62, 0x6f, 0xa1, 0xdc, 0x16, 0x96, 0xb3, 0xac, 0xcd, 0x67, 0xe3, 0x4a, - 0x51, 0xb4, 0x84, 0x71, 0x65, 0x7f, 0x22, 0x10, 0x7e, 0xc6, 0x8e, 0x7d, - 0x4e, 0xda, 0x8e, 0xd8, 0x47, 0x8f, 0x6d, 0x1b, 0xcb, 0xce, 0xda, 0xc6, - 0xe4, 0x59, 0x0e, 0xd5, 0x9f, 0x9a, 0xea, 0x73, 0x39, 0xbb, 0x70, 0x26, - 0xf5, 0x5e, 0xdb, 0x8e, 0xd3, 0x82, 0x8f, 0x0e, 0x38, 0x06, 0x9c, 0x68, - 0x33, 0x2f, 0xa5, 0xbe, 0xab, 0x19, 0x6f, 0x8a, 0x78, 0x30, 0x4f, 0x1d, - 0xfe, 0x0b, 0x94, 0x0e, 0x64, 0xad, 0x12, 0xfe, 0x6e, 0x0e, 0x89, 0xbe, - 0xaf, 0xc2, 0xad, 0xc3, 0x0e, 0x14, 0x0d, 0x28, 0x78, 0xd2, 0xac, 0xc7, - 0x90, 0x37, 0x87, 0xbb, 0x6a, 0xf2, 0x52, 0x7b, 0x9e, 0x2e, 0x1e, 0x3f, - 0xfa, 0x8c, 0xc4, 0x85, 0x7b, 0x47, 0x3d, 0xf0, 0x25, 0x15, 0x78, 0x88, - 0x2b, 0x65, 0x46, 0x3d, 0xf5, 0xaa, 0xa1, 0x32, 0x69, 0xe2, 0x6b, 0x19, - 0xd2, 0xa6, 0x07, 0xc2, 0xb8, 0x93, 0xf3, 0x52, 0xfe, 0xc0, 0x95, 0xb8, - 0x83, 0xe5, 0x36, 0xf0, 0xde, 0x86, 0xd1, 0x6a, 0x1e, 0x5e, 0x1e, 0xd3, - 0x79, 0x34, 0xe0, 0xf6, 0xe1, 0x5a, 0x44, 0xab, 0xf5, 0xa0, 0x5f, 0x75, - 0xa0, 0x7a, 0x40, 0xf4, 0xae, 0x62, 0xe5, 0x02, 0x05, 0xe6, 0xa7, 0x8b, - 0xa1, 0xce, 0xfd, 0x38, 0xdf, 0xfd, 0x53, 0xb2, 0xbe, 0x6c, 0x0d, 0xd9, - 0x98, 0x2e, 0x3a, 0x16, 0x3b, 0xf9, 0x57, 0xce, 0x85, 0xc8, 0x2b, 0x7d, - 0x48, 0xac, 0x15, 0x1d, 0x7f, 0x12, 0x36, 0x30, 0xb2, 0x54, 0x74, 0xb1, - 0xcc, 0x47, 0x7d, 0x01, 0x67, 0xe7, 0x7f, 0x2a, 0x67, 0x95, 0xb8, 0xaf, - 0x87, 0x87, 0x6c, 0x8e, 0xe3, 0x67, 0xbe, 0xa8, 0xc7, 0x45, 0xe7, 0xe4, - 0x34, 0x6e, 0xd5, 0x80, 0xbf, 0xc8, 0xb8, 0x19, 0xb7, 0x71, 0x9e, 0xf6, - 0x26, 0xd4, 0xa5, 0x2e, 0xa8, 0xb3, 0x5c, 0x4c, 0x9c, 0x47, 0x4c, 0x1d, - 0xed, 0xc3, 0xcc, 0xb5, 0x86, 0xcb, 0xd1, 0xa5, 0x29, 0xee, 0x6d, 0xf5, - 0x8b, 0x24, 0xa7, 0xf6, 0x57, 0x1a, 0x50, 0xcb, 0x18, 0xff, 0xb7, 0x6b, - 0x70, 0x16, 0x19, 0x8a, 0x9a, 0xa8, 0x6f, 0x42, 0xbc, 0x0a, 0xce, 0x0a, - 0x03, 0x0a, 0x73, 0x66, 0xf4, 0x69, 0x10, 0xec, 0x89, 0x16, 0x19, 0xf7, - 0xe0, 0xb6, 0x14, 0xac, 0xd2, 0x08, 0xf3, 0xa1, 0x88, 0x41, 0x8e, 0x1b, - 0xf0, 0x15, 0xd1, 0x3f, 0x56, 0x93, 0x57, 0xac, 0x1d, 0x16, 0x39, 0x3c, - 0xe4, 0x1b, 0x86, 0xbf, 0x0d, 0xcc, 0xe1, 0x5b, 0xf4, 0xe0, 0x24, 0xf3, - 0xd8, 0xd5, 0xd4, 0xfd, 0x48, 0xe2, 0x1e, 0x34, 0xa6, 0x8e, 0x58, 0x1e, - 0xf2, 0xc8, 0x22, 0xa3, 0xf6, 0x4c, 0x17, 0x62, 0xf4, 0x0d, 0xe1, 0x47, - 0x6b, 0xe8, 0x1b, 0x3e, 0x64, 0x12, 0xea, 0x71, 0xb2, 0x0b, 0x74, 0x8c, - 0xae, 0xc7, 0xd7, 0x46, 0x67, 0x61, 0x3c, 0xb1, 0x01, 0x77, 0x66, 0xc8, - 0x95, 0xfa, 0xaf, 0xc2, 0x1d, 0xc3, 0x57, 0xe1, 0xf6, 0x9d, 0x46, 0x70, - 0x03, 0x75, 0xbd, 0x76, 0x98, 0x81, 0x72, 0xba, 0xb4, 0x5b, 0xd0, 0x95, - 0xf0, 0x45, 0xea, 0x22, 0xaf, 0xa7, 0x2c, 0x0a, 0x1c, 0xe6, 0x5f, 0x2d, - 0x5e, 0x8a, 0x17, 0x35, 0x28, 0xfe, 0xdd, 0xf5, 0x2f, 0x31, 0xb7, 0x17, - 0xd9, 0x11, 0x9d, 0x69, 0xfc, 0xc0, 0x7a, 0x50, 0xa3, 0x7f, 0x47, 0x10, - 0x9f, 0xd3, 0xf0, 0xbc, 0xf5, 0xd0, 0x2a, 0xb9, 0x7e, 0x9b, 0x13, 0xa5, - 0x2a, 0xaf, 0x49, 0x9b, 0x82, 0x4b, 0x75, 0x44, 0xe2, 0x8f, 0x6b, 0x33, - 0x6b, 0x25, 0xcf, 0x96, 0x27, 0x2f, 0x24, 0x16, 0x3f, 0x91, 0xf0, 0xa2, - 0x37, 0x95, 0xe3, 0x56, 0x37, 0x65, 0x84, 0x53, 0xb9, 0x51, 0xda, 0x27, - 0x71, 0x25, 0x8a, 0xf5, 0xfc, 0x5d, 0xd2, 0xa7, 0xb7, 0xc4, 0x91, 0x60, - 0x9b, 0x4d, 0x9c, 0x0b, 0xda, 0x6b, 0x9f, 0x03, 0x25, 0x46, 0x73, 0xce, - 0x56, 0xfb, 0x56, 0xd0, 0x56, 0x35, 0x54, 0xf4, 0xf5, 0x70, 0xac, 0xb4, - 0x55, 0xd6, 0xbb, 0x83, 0xba, 0xf0, 0xf4, 0xad, 0xa2, 0xbd, 0xce, 0x42, - 0x59, 0x5f, 0x2b, 0xf1, 0x01, 0x8c, 0xeb, 0x16, 0x8e, 0x9a, 0x95, 0x79, - 0x7e, 0xda, 0x8c, 0x5b, 0x53, 0x51, 0xb4, 0xa5, 0x6a, 0xa3, 0x27, 0x65, - 0xad, 0xca, 0x95, 0xc3, 0xb0, 0x68, 0x8d, 0xe8, 0x62, 0x32, 0x8f, 0xa7, - 0x7a, 0x73, 0x8e, 0xd3, 0xe9, 0x9a, 0x5f, 0x29, 0xc8, 0xde, 0x83, 0x18, - 0xf3, 0x8f, 0x39, 0x91, 0x16, 0x58, 0x29, 0x91, 0x3b, 0x6e, 0xf9, 0x98, - 0x53, 0x7a, 0x22, 0xfa, 0xc6, 0xc5, 0x0e, 0xa3, 0xe3, 0x15, 0x25, 0x88, - 0xeb, 0x29, 0x43, 0x59, 0x5f, 0x27, 0x5e, 0x08, 0xe9, 0xbe, 0xef, 0x2a, - 0xfa, 0x99, 0x0d, 0x78, 0x05, 0x3f, 0xe3, 0xb5, 0xa2, 0xbe, 0x09, 0x3c, - 0x94, 0x79, 0x15, 0xa7, 0x28, 0xab, 0xda, 0xf7, 0xa1, 0xb5, 0xcc, 0x78, - 0x86, 0xe3, 0x77, 0x2b, 0x6f, 0x65, 0xa6, 0xda, 0xe2, 0x55, 0x58, 0xbd, - 0x53, 0xec, 0x4f, 0x0f, 0xc6, 0x89, 0xbd, 0x6d, 0x66, 0x85, 0x70, 0x79, - 0x89, 0x4f, 0x94, 0xbf, 0x45, 0xb0, 0x85, 0xfe, 0x41, 0x3b, 0xb0, 0xc7, - 0xd0, 0x6a, 0x63, 0xb2, 0x33, 0x09, 0x1b, 0x4b, 0x73, 0x7a, 0x8e, 0x28, - 0x6d, 0xa3, 0xbe, 0x52, 0x94, 0xfa, 0xf2, 0x7e, 0x90, 0x5b, 0xb3, 0x38, - 0x57, 0xf7, 0x3f, 0xad, 0x11, 0xef, 0xf9, 0x75, 0x2b, 0x98, 0x83, 0x55, - 0x72, 0x3c, 0xef, 0xf6, 0xc5, 0xad, 0xd2, 0xdc, 0x58, 0x9a, 0x7f, 0xa0, - 0x88, 0x4d, 0x06, 0xc9, 0xed, 0x3b, 0x71, 0x69, 0x48, 0x6f, 0xfd, 0xae, - 0x22, 0x65, 0xf5, 0xf0, 0x06, 0xa5, 0xd0, 0xcf, 0xcb, 0x38, 0x39, 0x22, - 0x7d, 0x48, 0x5f, 0x13, 0xcc, 0xc9, 0x72, 0x63, 0x10, 0x5f, 0x7a, 0xc4, - 0x9e, 0x4b, 0xf1, 0x27, 0x3f, 0x96, 0x73, 0x4c, 0xae, 0x3e, 0x1f, 0x0f, - 0x17, 0xed, 0xd5, 0x87, 0xb5, 0x99, 0x15, 0x58, 0xcd, 0xbc, 0x76, 0x75, - 0xa6, 0x85, 0xba, 0xdf, 0x48, 0x7c, 0x67, 0x46, 0xa0, 0xe5, 0x74, 0x7c, - 0xce, 0x3e, 0x74, 0xff, 0x24, 0x56, 0xf0, 0xfe, 0xcf, 0x9d, 0xa8, 0x68, - 0x61, 0x79, 0xfb, 0xbe, 0x29, 0xf8, 0x7d, 0xae, 0xcc, 0x47, 0x78, 0x98, - 0x1d, 0xe7, 0xf7, 0xda, 0x1c, 0xb1, 0xc5, 0xce, 0xbd, 0xae, 0xb6, 0xe7, - 0x5c, 0x38, 0x82, 0x85, 0x63, 0x66, 0x31, 0xf3, 0xaf, 0xba, 0xe0, 0xf9, - 0x9c, 0x50, 0x67, 0x16, 0x5a, 0xc0, 0x03, 0xe9, 0x4b, 0xf4, 0x72, 0xa2, - 0x26, 0xa7, 0x97, 0x4f, 0x2a, 0x7b, 0x3e, 0x76, 0xec, 0x49, 0x48, 0xdf, - 0x45, 0x36, 0x2f, 0x6d, 0xcc, 0x94, 0x22, 0xee, 0x15, 0x1d, 0x49, 0x7b, - 0xba, 0x5f, 0x64, 0x5a, 0xbb, 0x53, 0xec, 0xd8, 0xc2, 0x08, 0x65, 0xe8, - 0xb6, 0xe7, 0x2d, 0xc7, 0x25, 0x8f, 0x9c, 0x17, 0x9f, 0x65, 0x4c, 0x85, - 0xbe, 0x6f, 0x73, 0xe5, 0xf8, 0x66, 0x81, 0x2b, 0x58, 0xd6, 0x80, 0x59, - 0xe0, 0x0a, 0x32, 0xe6, 0xbf, 0x00, 0x63, 0x9d, 0x3d, 0xde, 0x35, 0xf9, - 0xb6, 0xbb, 0xcc, 0x00, 0xed, 0x5a, 0xb8, 0x54, 0x44, 0x59, 0xb3, 0x2b, - 0xc3, 0xb9, 0x95, 0xdc, 0x06, 0xb8, 0x93, 0xf7, 0xcb, 0x79, 0xff, 0xc5, - 0x90, 0x0b, 0x97, 0x4e, 0x97, 0xbe, 0xaf, 0x42, 0xc7, 0xce, 0x28, 0x2a, - 0x17, 0x06, 0x30, 0x69, 0x73, 0x89, 0x02, 0xef, 0x75, 0xe1, 0x8e, 0x9d, - 0x1f, 0x5a, 0x15, 0x36, 0x17, 0x33, 0x62, 0xe3, 0x8a, 0x8a, 0xed, 0x8b, - 0x84, 0xff, 0xba, 0x88, 0xef, 0xe4, 0xa2, 0xc2, 0xad, 0x5d, 0x65, 0xe4, - 0xb0, 0xc2, 0xe1, 0x02, 0xd9, 0x9b, 0x54, 0x68, 0x5a, 0x44, 0xb8, 0xdc, - 0x2c, 0x9b, 0xc3, 0x0a, 0x97, 0xfd, 0x56, 0xea, 0xd0, 0x14, 0x2e, 0x7b, - 0x96, 0x73, 0x30, 0xf7, 0x69, 0x61, 0x7e, 0xef, 0x81, 0x3b, 0xa2, 0xb7, - 0x6c, 0x52, 0x3a, 0xb1, 0x3c, 0x64, 0x98, 0x92, 0x53, 0x5f, 0xa9, 0xe8, - 0xc1, 0xd3, 0x08, 0x12, 0x6f, 0x5f, 0xc6, 0xc8, 0x60, 0xdc, 0x25, 0x76, - 0xb4, 0x29, 0x73, 0x4e, 0x9e, 0x5b, 0x29, 0x8f, 0x3b, 0x27, 0x8f, 0x79, - 0x1a, 0x2a, 0x9e, 0x6c, 0x70, 0x11, 0xb7, 0xfe, 0x0e, 0x6d, 0x3b, 0x55, - 0x2c, 0xb1, 0xb9, 0xf9, 0xdf, 0x11, 0x7f, 0x2f, 0x2a, 0xcd, 0x95, 0x07, - 0x3a, 0xe9, 0xdf, 0xef, 0x2f, 0x2c, 0x41, 0x68, 0x9a, 0x82, 0x2a, 0xa3, - 0x83, 0xf9, 0xf1, 0x87, 0x56, 0xdc, 0x49, 0x3a, 0x6b, 0x40, 0x2b, 0x89, - 0x44, 0x29, 0x5b, 0x93, 0x72, 0xcd, 0xf0, 0x20, 0xfb, 0xe9, 0x20, 0xef, - 0xf7, 0xe0, 0x2e, 0xda, 0xce, 0x5d, 0x8c, 0x65, 0x77, 0x31, 0x96, 0xdd, - 0x35, 0xfa, 0x2f, 0xbc, 0x3e, 0xdd, 0xfe, 0xbd, 0x29, 0x55, 0xb0, 0x65, - 0x27, 0xe3, 0x82, 0xe8, 0x77, 0x33, 0x7d, 0x47, 0xe2, 0x02, 0x28, 0x93, - 0x85, 0x93, 0x9c, 0xc7, 0x25, 0x9a, 0x1e, 0xcc, 0xe2, 0xeb, 0xae, 0x73, - 0x79, 0x5f, 0x21, 0xb6, 0xc8, 0x3c, 0xba, 0x70, 0x1b, 0x65, 0x0c, 0x86, - 0xfe, 0xcb, 0x42, 0x95, 0xf8, 0xee, 0x85, 0xf7, 0x73, 0xf3, 0x7a, 0xe4, - 0x2c, 0x07, 0x54, 0xc4, 0x4e, 0xe9, 0xf3, 0x7b, 0x6c, 0x4e, 0xf1, 0xa2, - 0xc9, 0xdc, 0x6d, 0xe7, 0xd1, 0xf9, 0x62, 0x2a, 0x6b, 0x47, 0xa3, 0xe8, - 0xe6, 0xb8, 0x57, 0x0f, 0x3f, 0x96, 0xd7, 0x4b, 0x61, 0xbc, 0x0a, 0xd5, - 0xe2, 0xa1, 0xff, 0xe4, 0x72, 0x95, 0xb6, 0x51, 0xe1, 0xb6, 0xd5, 0xfc, - 0x2f, 0xdc, 0xd6, 0xcb, 0xff, 0xc2, 0x73, 0xa7, 0xf3, 0xbf, 0x13, 0xfe, - 0xe9, 0x62, 0xc7, 0xf5, 0xe8, 0xdd, 0x65, 0x59, 0xc5, 0x81, 0x7a, 0x6c, - 0x19, 0xfd, 0x48, 0xbc, 0xbc, 0x40, 0x1e, 0x7b, 0x0e, 0xe8, 0x47, 0x2e, - 0xc1, 0x22, 0xbf, 0x5f, 0x95, 0xbe, 0x2d, 0x6c, 0x34, 0xaf, 0x62, 0x9f, - 0x8c, 0x80, 0xd5, 0x53, 0xfd, 0xa2, 0xd0, 0x46, 0x41, 0xdf, 0xc5, 0xf4, - 0x73, 0x68, 0x2e, 0xea, 0x7b, 0x65, 0x46, 0xea, 0x36, 0x29, 0x4b, 0x87, - 0xa7, 0x96, 0xef, 0x20, 0x1f, 0x3e, 0x4d, 0x5d, 0x17, 0xfc, 0xc8, 0x9b, - 0xcf, 0x2b, 0x98, 0x4b, 0xa4, 0x44, 0x97, 0x32, 0xbe, 0x5c, 0xae, 0x28, - 0xb6, 0x74, 0xe4, 0x6c, 0x1f, 0xa2, 0xb7, 0xf8, 0xf4, 0x12, 0x43, 0xec, - 0x28, 0x48, 0x5c, 0xd1, 0xc3, 0xcd, 0x84, 0xed, 0x53, 0x09, 0xc4, 0x1c, - 0x91, 0xe6, 0xa6, 0xb5, 0x89, 0xb9, 0xda, 0xf1, 0x7c, 0x2e, 0xba, 0x87, - 0x38, 0xae, 0x1a, 0xb2, 0x0e, 0x42, 0x5b, 0x19, 0x16, 0xdd, 0x75, 0x28, - 0xe7, 0xf2, 0xce, 0x28, 0x79, 0x97, 0x6a, 0xcb, 0xe8, 0x8c, 0x88, 0x6c, - 0x52, 0x87, 0xb2, 0x5f, 0xc0, 0xbf, 0x72, 0xba, 0xa8, 0x80, 0x67, 0x40, - 0x78, 0x97, 0x8e, 0x0d, 0x8c, 0xf3, 0x65, 0x03, 0x7e, 0xfa, 0x42, 0x35, - 0x4a, 0x1f, 0x88, 0x60, 0xfd, 0xa8, 0x86, 0x92, 0x07, 0x2c, 0x6b, 0x6e, - 0xa8, 0x87, 0x5c, 0xf6, 0xb2, 0x22, 0xc9, 0x9d, 0x9c, 0x49, 0x62, 0x16, - 0xf1, 0xad, 0x3d, 0xa5, 0xe0, 0x6a, 0xc6, 0xd3, 0x28, 0x71, 0xa8, 0xdd, - 0xc6, 0x39, 0xab, 0x73, 0x4e, 0xc4, 0x45, 0x1b, 0x5a, 0xc5, 0xfb, 0xad, - 0xc4, 0xc0, 0x56, 0x62, 0x9a, 0x65, 0xbd, 0x7f, 0x39, 0x3a, 0xcb, 0x22, - 0x37, 0x13, 0x0b, 0x6b, 0xc9, 0x89, 0x25, 0x7e, 0x5f, 0x8e, 0x35, 0x8c, - 0xfd, 0xc5, 0x49, 0x3b, 0x9f, 0xa2, 0xee, 0x18, 0xa3, 0x32, 0x8c, 0x71, - 0x94, 0xfd, 0x69, 0x72, 0x5c, 0xe1, 0xbb, 0x95, 0xc9, 0x0d, 0x8c, 0x75, - 0x1e, 0x54, 0x0c, 0x5c, 0x86, 0x3b, 0x19, 0xcf, 0xef, 0xd8, 0xe9, 0x47, - 0x7a, 0xd1, 0x55, 0x94, 0xef, 0x1e, 0xac, 0x4f, 0x19, 0x92, 0x43, 0x45, - 0x83, 0x8b, 0xc8, 0xb7, 0x33, 0x82, 0x3b, 0x92, 0x8f, 0x95, 0x61, 0x49, - 0x0b, 0x10, 0x4c, 0x16, 0xf0, 0x2d, 0x2a, 0x6b, 0x47, 0x30, 0x92, 0xe7, - 0x63, 0xdb, 0x39, 0x5e, 0x24, 0xeb, 0x70, 0x2d, 0x98, 0xcf, 0x58, 0x20, - 0xf6, 0xa5, 0x31, 0xc7, 0x2c, 0x51, 0x0c, 0xdf, 0x1e, 0xfa, 0xa9, 0xe4, - 0x3d, 0x57, 0x24, 0x0b, 0xb1, 0x4f, 0xcf, 0x2e, 0x76, 0x74, 0x12, 0x47, - 0xf4, 0x8d, 0xbf, 0x53, 0xf4, 0xf6, 0x13, 0xca, 0x2b, 0xd8, 0x37, 0xf6, - 0x2a, 0x86, 0xc6, 0xdc, 0xca, 0xe8, 0x98, 0xf4, 0x35, 0x81, 0xbe, 0xcc, - 0x9f, 0xea, 0x6b, 0xea, 0xfa, 0xcb, 0xa2, 0xf3, 0xd6, 0x6c, 0xae, 0xce, - 0xe7, 0x89, 0x4b, 0xcf, 0xe3, 0xc7, 0x32, 0x27, 0x62, 0x97, 0x5e, 0xf4, - 0xa4, 0xce, 0xad, 0x0b, 0xf4, 0x27, 0xb6, 0xd9, 0xfe, 0xd9, 0x92, 0x11, - 0x7b, 0x55, 0x19, 0x33, 0x2f, 0xce, 0xe7, 0x2c, 0xb5, 0xd4, 0x41, 0x9f, - 0x7d, 0x6f, 0x9f, 0xf9, 0x29, 0x64, 0xed, 0x6b, 0x8b, 0xe9, 0x9b, 0xd5, - 0x28, 0x26, 0x26, 0x06, 0x43, 0x3e, 0x14, 0x57, 0xc9, 0x3a, 0xce, 0xb9, - 0xdc, 0x7f, 0xc3, 0x4e, 0x86, 0x64, 0x1b, 0x73, 0x1a, 0x89, 0x7f, 0xb5, - 0x9c, 0xef, 0x1c, 0xce, 0xac, 0xa7, 0x0d, 0x5d, 0x27, 0x36, 0xe4, 0xca, - 0xd9, 0xd0, 0x47, 0xd7, 0x17, 0x54, 0x90, 0xfb, 0x69, 0x15, 0x76, 0xde, - 0xd7, 0xa4, 0x5c, 0x9f, 0xb7, 0xab, 0xcf, 0x67, 0x1e, 0x2d, 0xca, 0xe7, - 0x66, 0x17, 0x94, 0xff, 0x38, 0x1d, 0x5c, 0xf6, 0x67, 0xe8, 0x40, 0xe2, - 0x81, 0xe4, 0x04, 0xa2, 0x83, 0xf3, 0xf3, 0xf2, 0xfe, 0x44, 0x35, 0x71, - 0xef, 0x42, 0x5d, 0xcc, 0xcc, 0xeb, 0x62, 0x31, 0xb1, 0x4b, 0xfe, 0x5b, - 0x38, 0x65, 0x7a, 0xf1, 0xa2, 0x26, 0xe3, 0x5e, 0x8c, 0xf5, 0x1c, 0xaf, - 0x9b, 0xba, 0x58, 0x1e, 0xaa, 0x44, 0xf0, 0xbc, 0x78, 0x50, 0xcb, 0xd8, - 0xf1, 0x21, 0x79, 0xa6, 0xfc, 0xf6, 0xe3, 0x05, 0xea, 0xe2, 0x8e, 0xe1, - 0xc5, 0xb8, 0x8b, 0xfe, 0x94, 0xe3, 0x90, 0xb9, 0xd8, 0xb0, 0x76, 0x58, - 0xda, 0x14, 0x8c, 0xfb, 0xd9, 0xd9, 0x71, 0xfe, 0x71, 0x5e, 0xfe, 0x0a, - 0xe5, 0x97, 0x67, 0x07, 0xb2, 0x16, 0x2d, 0xcf, 0x11, 0x64, 0x2c, 0xc6, - 0x14, 0xdc, 0xb1, 0xac, 0x83, 0xe6, 0x3c, 0xc4, 0xaa, 0xf5, 0x7e, 0x89, - 0x8f, 0xfd, 0xc4, 0x03, 0x07, 0xf3, 0xc8, 0xa2, 0x48, 0x94, 0xfe, 0xac, - 0x5e, 0xe5, 0x80, 0x5a, 0xef, 0x40, 0x27, 0xde, 0x30, 0x8d, 0xde, 0x75, - 0xf8, 0x14, 0xba, 0xbc, 0x16, 0xf6, 0xb2, 0x9d, 0xee, 0x54, 0x09, 0xda, - 0xeb, 0x69, 0x56, 0x2b, 0x3d, 0xd8, 0x91, 0x8a, 0xb7, 0x12, 0x16, 0x18, - 0x73, 0x1a, 0xfe, 0x2a, 0x11, 0xd0, 0x5b, 0x36, 0x90, 0xb7, 0x2c, 0xef, - 0x73, 0xc3, 0xaf, 0xe4, 0x72, 0xb4, 0x01, 0x55, 0xd6, 0x09, 0x23, 0x94, - 0xbd, 0xc7, 0xce, 0xf7, 0xfc, 0xd3, 0xa5, 0x1f, 0x3f, 0xe2, 0x19, 0xa9, - 0xeb, 0x47, 0xe9, 0x5c, 0x05, 0xcb, 0xe7, 0xea, 0xf1, 0xa8, 0x62, 0x59, - 0x0b, 0x42, 0x4e, 0xfb, 0xfe, 0xb6, 0x4c, 0x5d, 0xeb, 0x0d, 0xea, 0xab, - 0x56, 0x6e, 0x6d, 0x52, 0xd7, 0xa2, 0x4c, 0x0a, 0x8e, 0xfc, 0xd1, 0xf5, - 0xf9, 0x20, 0xe4, 0xb9, 0x89, 0xdb, 0x58, 0x89, 0xfd, 0xf9, 0xf5, 0x39, - 0x57, 0xe4, 0xbd, 0x2f, 0xef, 0x35, 0x24, 0x6f, 0x11, 0x9d, 0x4b, 0x7f, - 0x62, 0x0b, 0xd7, 0x15, 0x0b, 0x06, 0x76, 0x65, 0x16, 0xd2, 0x16, 0x7f, - 0x6b, 0x8d, 0x7a, 0xa7, 0x96, 0xbd, 0x51, 0xcd, 0xad, 0xb7, 0x4b, 0xd9, - 0x42, 0xb9, 0x8b, 0x89, 0x09, 0x8d, 0x18, 0x3e, 0xaf, 0x4d, 0xc9, 0x75, - 0x0b, 0x6d, 0xde, 0xc6, 0x72, 0xd2, 0xae, 0xe0, 0xef, 0x7f, 0x59, 0xfb, - 0xce, 0x6b, 0xaf, 0xd5, 0x95, 0x6b, 0xef, 0xee, 0x62, 0xc9, 0xdd, 0xfb, - 0x53, 0x45, 0xac, 0xf3, 0x4e, 0x9e, 0x07, 0x16, 0xca, 0x7c, 0xea, 0x82, - 0x32, 0xc4, 0x79, 0xe3, 0x4d, 0x6b, 0xcf, 0x79, 0x65, 0x96, 0x3b, 0xcf, - 0x2f, 0xe3, 0xc4, 0x1c, 0xe3, 0x55, 0xeb, 0xc8, 0x79, 0x65, 0xd2, 0x17, - 0x94, 0xb9, 0x1c, 0x63, 0xf5, 0x8f, 0x58, 0x43, 0xb9, 0xb9, 0xc9, 0xd2, - 0x7d, 0xdc, 0x33, 0x23, 0xad, 0x7f, 0x75, 0xc5, 0x3c, 0xbd, 0x63, 0xa6, - 0x43, 0x9e, 0xd9, 0xb8, 0x91, 0xcd, 0xcd, 0x4d, 0x5c, 0xe6, 0xc6, 0xb5, - 0xa0, 0x30, 0x37, 0xd7, 0xe5, 0xeb, 0x17, 0xda, 0xbd, 0xae, 0xe8, 0xfc, - 0x76, 0x0b, 0xd7, 0xaf, 0xb8, 0x40, 0xee, 0xef, 0x5c, 0x50, 0xee, 0xb7, - 0x7f, 0xa4, 0xde, 0x2f, 0x1c, 0xe7, 0x5f, 0x3f, 0xa0, 0x9e, 0x7f, 0xde, - 0x9c, 0x3f, 0x2f, 0xe8, 0xbf, 0xea, 0x82, 0xf2, 0x35, 0x17, 0x94, 0x7f, - 0x59, 0xfd, 0xf8, 0x7e, 0xd6, 0x5d, 0x50, 0xcf, 0x5e, 0xab, 0xc6, 0x53, - 0x67, 0x7d, 0x1e, 0x4d, 0x45, 0x08, 0x98, 0x4e, 0x05, 0x7e, 0xfa, 0xbe, - 0xff, 0xe9, 0x0b, 0xd6, 0xac, 0x9b, 0xce, 0xfa, 0xfe, 0x79, 0x9c, 0x33, - 0x56, 0x1c, 0x91, 0x18, 0x56, 0x44, 0xee, 0x2c, 0x3c, 0xb0, 0x4e, 0x3b, - 0x97, 0x67, 0x15, 0x62, 0x65, 0x45, 0xac, 0x24, 0xd2, 0x00, 0xff, 0xd8, - 0x2c, 0xff, 0x9b, 0x09, 0x59, 0xb7, 0xfc, 0x80, 0x5c, 0xca, 0xf0, 0xed, - 0xc7, 0x2c, 0xff, 0x4f, 0xd3, 0x6f, 0x15, 0xa3, 0xc2, 0x83, 0xab, 0x13, - 0x1f, 0x5f, 0x4f, 0x8d, 0x40, 0x59, 0xd6, 0xe0, 0x63, 0x7e, 0x05, 0xe7, - 0x35, 0xf3, 0x30, 0xe5, 0xaf, 0x45, 0xf2, 0x3d, 0xf5, 0x58, 0x43, 0x98, - 0xf1, 0x39, 0xf7, 0xbc, 0x76, 0x49, 0x46, 0xf7, 0x45, 0x95, 0xdc, 0x33, - 0xd9, 0xf6, 0xd0, 0x1f, 0xc8, 0x77, 0x3a, 0x29, 0x97, 0xc5, 0xbe, 0x80, - 0x0d, 0x09, 0xcb, 0x7a, 0x8a, 0x79, 0xaa, 0x3c, 0xeb, 0xff, 0x79, 0xfa, - 0xf7, 0xd6, 0x84, 0xd7, 0x89, 0xb7, 0x8c, 0xa9, 0xed, 0xf9, 0x51, 0x19, - 0x31, 0x99, 0x2f, 0xd9, 0x27, 0xea, 0x98, 0x51, 0xb7, 0x71, 0x2f, 0xfd, - 0x6e, 0x7e, 0x40, 0xf7, 0x27, 0xf1, 0xef, 0x96, 0xbf, 0x46, 0x0f, 0x0e, - 0x29, 0x85, 0x75, 0xe2, 0x0b, 0xd7, 0x83, 0x2b, 0x62, 0x2e, 0x8e, 0x6f, - 0x8f, 0xcd, 0xf7, 0x8b, 0x88, 0x71, 0x88, 0x39, 0x23, 0xb3, 0xfc, 0x5b, - 0x12, 0xf6, 0x38, 0xc9, 0x17, 0x15, 0x1c, 0x6b, 0x98, 0xe5, 0xef, 0x4e, - 0x7b, 0xb1, 0x9d, 0xf1, 0xb8, 0xc4, 0x68, 0xc0, 0x23, 0x69, 0x15, 0xb7, - 0xdd, 0xef, 0xc5, 0x5a, 0x72, 0xd1, 0x8d, 0x7d, 0xdf, 0x80, 0x71, 0xa9, - 0x13, 0xb7, 0xd2, 0xfe, 0xd6, 0xf5, 0x15, 0xdb, 0x39, 0xc8, 0xfa, 0x3e, - 0x27, 0xea, 0x2f, 0xad, 0x40, 0xbc, 0xa6, 0x18, 0xdf, 0x37, 0x1d, 0xcc, - 0x7b, 0xca, 0x30, 0x64, 0x63, 0xa2, 0xe4, 0xb2, 0x82, 0x73, 0xa2, 0x37, - 0x87, 0xbd, 0x2e, 0xf9, 0xf1, 0x58, 0xfe, 0x5b, 0x2b, 0x5b, 0xb3, 0xdd, - 0xc6, 0x5f, 0x47, 0xc4, 0xb4, 0xe3, 0x25, 0x90, 0xe3, 0x69, 0x5d, 0xe7, - 0x3d, 0x57, 0x6e, 0x51, 0xe6, 0x44, 0x02, 0x13, 0x8b, 0x15, 0x07, 0xc2, - 0x81, 0x8a, 0x58, 0x65, 0x24, 0x8c, 0x65, 0x99, 0x2e, 0x9f, 0xcf, 0x7e, - 0x56, 0x1d, 0xc1, 0xe9, 0x45, 0x26, 0x73, 0x60, 0x38, 0x97, 0x51, 0xf7, - 0x4d, 0xd4, 0xeb, 0x66, 0xf3, 0x0f, 0x56, 0xd6, 0xf6, 0x7b, 0x37, 0x62, - 0x9a, 0x65, 0xad, 0xa3, 0x7e, 0x1d, 0xd4, 0xe3, 0xcf, 0xf2, 0xfa, 0x15, - 0x9d, 0x96, 0x8d, 0xfd, 0xde, 0x3a, 0x46, 0xfd, 0xba, 0xd9, 0x9e, 0x9b, - 0xed, 0x95, 0x8c, 0x9d, 0xaf, 0xe7, 0x62, 0xca, 0xb3, 0xcc, 0x96, 0xa1, - 0x52, 0x9e, 0xf5, 0xf9, 0xa3, 0x4a, 0x01, 0xb7, 0xff, 0xd4, 0x98, 0x5e, - 0x99, 0x92, 0x83, 0x88, 0xfe, 0xfd, 0xd4, 0xbf, 0x60, 0xb8, 0xcc, 0x41, - 0xbd, 0xac, 0xfb, 0xf4, 0x02, 0xa3, 0x4c, 0xd6, 0x15, 0x4c, 0x33, 0x22, - 0xf8, 0x76, 0x8b, 0x07, 0x6f, 0x26, 0xca, 0xed, 0x71, 0x5f, 0x3a, 0xd7, - 0xb2, 0x1e, 0x0f, 0xf9, 0xf1, 0x73, 0xa3, 0x2e, 0xbc, 0x40, 0xd5, 0x31, - 0xa9, 0x79, 0x91, 0x20, 0xce, 0x76, 0xa5, 0x66, 0x73, 0xbe, 0xbc, 0xd8, - 0x92, 0xc2, 0x46, 0xda, 0x93, 0xdf, 0x11, 0x01, 0xde, 0x48, 0x18, 0xc1, - 0xcd, 0xec, 0x7f, 0xd8, 0xdb, 0x40, 0xfe, 0xad, 0x36, 0x91, 0xaa, 0xc5, - 0x4b, 0x22, 0x46, 0x7c, 0x2b, 0xfe, 0xc3, 0x1a, 0x22, 0xce, 0x17, 0x85, - 0x64, 0x6d, 0x6e, 0x0e, 0x8e, 0x6b, 0x0e, 0x3c, 0x1b, 0x9c, 0x8e, 0x28, - 0xdd, 0xb1, 0xcc, 0x78, 0xcb, 0xfa, 0xa1, 0x57, 0xfa, 0x91, 0xb1, 0xfc, - 0x86, 0xe3, 0x50, 0x6c, 0x2c, 0xdc, 0x92, 0x6a, 0xa0, 0xbe, 0x2f, 0xec, - 0xff, 0xdf, 0xad, 0x49, 0xaf, 0xf4, 0xcf, 0x5c, 0x9e, 0xf1, 0xec, 0xc8, - 0x1f, 0xc5, 0xee, 0x97, 0xac, 0xe7, 0xec, 0x36, 0x17, 0xb9, 0x73, 0x71, - 0x50, 0xda, 0xfb, 0x17, 0x8e, 0x4f, 0xda, 0x2c, 0xf4, 0x23, 0x7a, 0xcb, - 0xba, 0xc5, 0x9f, 0xb7, 0xa4, 0x44, 0x7f, 0x82, 0x57, 0xc7, 0x2c, 0x4c, - 0x97, 0xf3, 0x87, 0xed, 0xb2, 0x71, 0xea, 0xab, 0x8b, 0x36, 0xc4, 0xd8, - 0xcb, 0x3c, 0x4e, 0x76, 0x51, 0x68, 0x76, 0x9e, 0xb6, 0x89, 0xdc, 0x7e, - 0xc8, 0x5b, 0x89, 0x2d, 0x26, 0xed, 0xce, 0x50, 0x2f, 0x76, 0x42, 0x72, - 0x53, 0x39, 0x77, 0x61, 0xd2, 0xeb, 0xc0, 0x56, 0xd3, 0x89, 0x76, 0x43, - 0xd5, 0xe5, 0xba, 0x23, 0x24, 0xe7, 0x2e, 0xf8, 0x6b, 0x14, 0x6c, 0x0f, - 0xab, 0x58, 0x6f, 0x74, 0xf9, 0xe5, 0xfa, 0x92, 0x90, 0x9c, 0x2b, 0x58, - 0x43, 0x9d, 0xc4, 0x35, 0x05, 0x1b, 0x0c, 0x79, 0xbe, 0x98, 0xe3, 0xbe, - 0x31, 0x58, 0xd6, 0x76, 0xb3, 0xf1, 0x8a, 0x32, 0x48, 0x9c, 0x17, 0x2e, - 0xf7, 0xde, 0xcd, 0xf3, 0x03, 0x71, 0x12, 0x31, 0x3d, 0x56, 0x42, 0x3f, - 0xdd, 0xd2, 0x37, 0x87, 0xf5, 0x14, 0x72, 0x1c, 0xa7, 0x6f, 0x1b, 0x24, - 0x7e, 0x06, 0xfc, 0x3f, 0x65, 0xf2, 0x34, 0xe4, 0x9d, 0x47, 0xcd, 0x1a, - 0xfe, 0x93, 0x9c, 0xb7, 0x4a, 0xc3, 0xb9, 0xf1, 0x07, 0xd0, 0xdb, 0x4b, - 0x94, 0x79, 0xc1, 0x0a, 0xe6, 0x00, 0x71, 0xe2, 0xfb, 0xc8, 0x98, 0x13, - 0x9b, 0x53, 0x86, 0xb6, 0xcf, 0xe6, 0x6e, 0x4e, 0xea, 0xc2, 0xc9, 0x1c, - 0x3f, 0xa0, 0x4d, 0x28, 0x85, 0xf3, 0x39, 0x82, 0x0d, 0xe4, 0xe2, 0x82, - 0x6f, 0x71, 0xeb, 0xc9, 0x06, 0x49, 0xdb, 0xdc, 0xfe, 0x58, 0xda, 0xc3, - 0x43, 0xe3, 0xe1, 0xf5, 0xaf, 0x4d, 0xfb, 0xfc, 0x6b, 0xd2, 0xf0, 0xb7, - 0xa5, 0x0b, 0x76, 0x59, 0xf0, 0x6d, 0xc1, 0x36, 0x8b, 0x7c, 0x33, 0x97, - 0x73, 0x75, 0x49, 0x4e, 0x03, 0x79, 0x3e, 0xf6, 0xde, 0xcd, 0x4f, 0xd1, - 0xd6, 0x5d, 0xe4, 0xf2, 0x5b, 0x8d, 0x78, 0x54, 0x9e, 0xd7, 0x19, 0x21, - 0xdd, 0x57, 0xa4, 0xf8, 0xb1, 0xa5, 0xfe, 0x77, 0x9c, 0x4f, 0x72, 0xdc, - 0xf4, 0xa7, 0x4a, 0x72, 0xf3, 0x21, 0x7e, 0x26, 0x18, 0xe0, 0x67, 0x1e, - 0xe4, 0xf3, 0x77, 0xb1, 0x9f, 0x4d, 0xe9, 0xa9, 0x3e, 0xa0, 0xe0, 0x1a, - 0xb6, 0xd5, 0x18, 0x82, 0x73, 0x69, 0xfd, 0x7f, 0x59, 0x59, 0xef, 0xd4, - 0x7d, 0x11, 0x20, 0x87, 0x80, 0xb3, 0xad, 0x5e, 0xce, 0x15, 0x34, 0x86, - 0xe5, 0x5c, 0x41, 0x9b, 0x91, 0x93, 0x4f, 0x7c, 0xb7, 0x9b, 0xb8, 0x7d, - 0xee, 0xfc, 0x42, 0x2c, 0x32, 0x71, 0x7b, 0x0a, 0xb1, 0xa2, 0x88, 0x60, - 0x91, 0xdb, 0xff, 0x5c, 0xba, 0x9e, 0x5c, 0x5c, 0x9e, 0x7f, 0xbb, 0x39, - 0xe7, 0x1e, 0xff, 0xb3, 0xe9, 0x2b, 0x71, 0xdb, 0xae, 0x30, 0xda, 0x77, - 0xc9, 0x86, 0x23, 0xe6, 0x60, 0xa1, 0x80, 0x7f, 0x14, 0x9a, 0xff, 0x38, - 0x75, 0x72, 0x94, 0x72, 0x1e, 0x3b, 0x4f, 0x4e, 0xd1, 0x21, 0xfc, 0x77, - 0x24, 0xdc, 0x48, 0x87, 0xde, 0xb7, 0xe2, 0x36, 0xe7, 0xf0, 0xfa, 0xef, - 0x4c, 0xf8, 0x91, 0xb5, 0xb9, 0xe7, 0xbf, 0xbb, 0x25, 0x47, 0xec, 0x49, - 0xc5, 0xa3, 0x4c, 0x79, 0xf3, 0xf3, 0xab, 0x87, 0x65, 0x6e, 0xdf, 0x48, - 0xc8, 0xbd, 0xe8, 0x37, 0x54, 0xe8, 0x7e, 0x95, 0xb1, 0xb4, 0xdf, 0x14, - 0xfb, 0xb5, 0xec, 0x67, 0xfb, 0xac, 0x18, 0xf7, 0x44, 0x02, 0xad, 0xf5, - 0xbc, 0xae, 0x2d, 0x40, 0xac, 0x8a, 0x7a, 0x2a, 0x35, 0xbc, 0xfe, 0xba, - 0x71, 0x9f, 0xdf, 0x1c, 0x87, 0xff, 0x92, 0xf1, 0xa9, 0x22, 0x90, 0xa3, - 0xab, 0x1f, 0x87, 0x05, 0x5e, 0xff, 0xba, 0xc4, 0x1c, 0xa8, 0x91, 0xb8, - 0xb5, 0xa4, 0xe1, 0xb4, 0x35, 0x27, 0x62, 0x64, 0x8f, 0x51, 0x86, 0xf7, - 0x2f, 0xd7, 0xe3, 0x33, 0x1d, 0x47, 0xef, 0xd5, 0xa6, 0xf4, 0xf1, 0x5e, - 0xe8, 0xff, 0x6f, 0x1f, 0x85, 0x38, 0x47, 0x7b, 0x68, 0x90, 0x31, 0x48, - 0xbc, 0x2b, 0x62, 0xce, 0x29, 0x63, 0xf9, 0x54, 0xe1, 0xb9, 0x47, 0x7e, - 0x5c, 0x0a, 0xe7, 0x1a, 0x36, 0x0f, 0xce, 0xc5, 0x30, 0xcb, 0xea, 0x36, - 0x7c, 0xf9, 0xe7, 0x67, 0x9c, 0xb3, 0xcc, 0xd1, 0x2b, 0x9c, 0x58, 0x4c, - 0x3f, 0x68, 0xfc, 0x4b, 0x27, 0xa2, 0xbe, 0x62, 0xc6, 0x56, 0x59, 0x17, - 0x3a, 0x5e, 0x3f, 0x69, 0x4d, 0x18, 0xf5, 0x68, 0xcc, 0xc8, 0xf3, 0x4c, - 0x07, 0xed, 0xdb, 0xc2, 0x23, 0xa6, 0xdc, 0x17, 0x9c, 0x89, 0xc7, 0x1c, - 0xb4, 0x15, 0xb7, 0xa1, 0xb7, 0xfe, 0xbd, 0x52, 0x81, 0xd2, 0x88, 0x33, - 0x38, 0x01, 0x3d, 0xbc, 0x5e, 0xa1, 0x1f, 0x56, 0xcd, 0x33, 0x65, 0x0a, - 0xde, 0x4e, 0x04, 0xcc, 0x40, 0x3e, 0x2e, 0x9d, 0xe2, 0xdc, 0xbd, 0x93, - 0x30, 0xda, 0x9f, 0xca, 0x9f, 0xff, 0x22, 0x3d, 0x35, 0xa7, 0x15, 0x7b, - 0x74, 0xbb, 0x37, 0x25, 0xf0, 0x9e, 0xa3, 0x01, 0xef, 0xed, 0x31, 0x8b, - 0x98, 0x8b, 0x89, 0x9d, 0xba, 0xdd, 0x5b, 0x12, 0x98, 0x74, 0xf2, 0xda, - 0x29, 0x73, 0x36, 0x31, 0x4d, 0xe5, 0xb5, 0xb0, 0xd8, 0x59, 0x4c, 0x63, - 0x7c, 0x2d, 0x8d, 0x78, 0xdd, 0xa5, 0xe3, 0xd0, 0x4a, 0x8c, 0x0a, 0xe6, - 0xba, 0x68, 0x72, 0x24, 0x75, 0x7f, 0xb3, 0xa3, 0x9e, 0x39, 0xaf, 0x5f, - 0x71, 0x19, 0xdf, 0x63, 0x5e, 0x2f, 0x6b, 0x61, 0x61, 0xda, 0xa4, 0x93, - 0x15, 0x76, 0x4c, 0x57, 0x23, 0x0a, 0xb1, 0xb0, 0x02, 0xb7, 0x6b, 0x1b, - 0x3e, 0xab, 0x46, 0xfa, 0x71, 0x7d, 0x83, 0xbb, 0xa9, 0x72, 0xbc, 0xa0, - 0x13, 0xc4, 0x3c, 0x11, 0xe6, 0x25, 0x06, 0xd4, 0xf2, 0x88, 0xe8, 0xc6, - 0xdf, 0x94, 0x1c, 0x13, 0x59, 0x35, 0x77, 0xdf, 0xd8, 0x3b, 0x25, 0x28, - 0x0d, 0x13, 0xab, 0x7e, 0xe2, 0xfb, 0xef, 0xd5, 0x3b, 0x5a, 0x22, 0x78, - 0xef, 0x32, 0xe4, 0xbf, 0x6d, 0x5b, 0x6e, 0x77, 0xe4, 0x83, 0x98, 0x3b, - 0x60, 0x59, 0x8c, 0x93, 0x3e, 0x28, 0xb3, 0x39, 0x1e, 0xfa, 0x1a, 0xe7, - 0x66, 0x4d, 0xfa, 0x0f, 0xd6, 0xe7, 0x9c, 0x36, 0x07, 0x70, 0x17, 0x47, - 0x3a, 0x6e, 0x79, 0xcb, 0xf8, 0xc0, 0x7a, 0x33, 0xc1, 0x5c, 0xd9, 0x90, - 0x67, 0x43, 0x73, 0xb0, 0xcd, 0x74, 0x36, 0x2f, 0x55, 0x14, 0xf4, 0x18, - 0xf3, 0xb4, 0x12, 0xc6, 0xa9, 0x6e, 0xfa, 0x75, 0xcc, 0x6b, 0x04, 0xf7, - 0x80, 0xe5, 0xd2, 0xeb, 0xd6, 0xb9, 0x22, 0x77, 0xde, 0x32, 0xd2, 0x20, - 0x58, 0x10, 0x6e, 0x7b, 0xca, 0x68, 0x41, 0x4f, 0x66, 0x10, 0xbd, 0x99, - 0x5c, 0x3f, 0x59, 0xcc, 0xf9, 0x98, 0x7e, 0xd6, 0xad, 0x2b, 0x8e, 0x08, - 0xf7, 0x3a, 0x73, 0xcb, 0x5e, 0x23, 0x8a, 0xcd, 0x99, 0x3b, 0x6f, 0x39, - 0xd5, 0xd0, 0xcf, 0xff, 0xb9, 0x3a, 0x43, 0xa8, 0xfc, 0xd8, 0x3a, 0x65, - 0x11, 0xe9, 0xa3, 0xe3, 0x96, 0xa7, 0x8c, 0x3b, 0x6f, 0x69, 0x5f, 0xf4, - 0x4d, 0x6c, 0xca, 0xb4, 0xff, 0xc9, 0x7e, 0xca, 0x59, 0xa7, 0x34, 0x72, - 0xa8, 0xed, 0x9a, 0xc0, 0x9d, 0xb7, 0xa4, 0x17, 0xf5, 0xb2, 0x8f, 0x55, - 0x8c, 0x2f, 0xb9, 0x3a, 0x51, 0xc6, 0xf6, 0x8f, 0xd3, 0x41, 0x49, 0x64, - 0xa2, 0x6d, 0x7e, 0xe0, 0x03, 0x6b, 0x5e, 0x5f, 0x91, 0xad, 0x03, 0x17, - 0x75, 0xf0, 0xa0, 0xe9, 0xcc, 0x06, 0x1c, 0xb6, 0x0e, 0x3a, 0x7c, 0xd4, - 0x41, 0x92, 0x3a, 0xc8, 0xd6, 0x18, 0xe1, 0x77, 0xa9, 0x83, 0x79, 0x63, - 0xeb, 0xd6, 0x95, 0x44, 0xe0, 0x74, 0x18, 0xaf, 0x3a, 0x9c, 0x9c, 0x0b, - 0x97, 0xb1, 0x8e, 0x7a, 0xbb, 0xf3, 0x96, 0x8b, 0x17, 0xd9, 0x3a, 0xff, - 0xb2, 0x3b, 0xb0, 0xc1, 0xde, 0x3b, 0xd7, 0x9d, 0x59, 0xc3, 0xa3, 0x99, - 0xc7, 0x7d, 0x3c, 0x7a, 0x98, 0xb3, 0xdc, 0x4c, 0x5d, 0x35, 0x71, 0x1c, - 0x2b, 0x28, 0xd7, 0x46, 0xfe, 0x6e, 0xe5, 0xef, 0x0e, 0xfe, 0x96, 0xf9, - 0x51, 0xcf, 0xca, 0x16, 0x3b, 0x2b, 0x9b, 0x83, 0xf2, 0x78, 0x88, 0x57, - 0x32, 0x26, 0xf7, 0x57, 0xae, 0x09, 0xc4, 0xd8, 0xc6, 0xfd, 0xa5, 0xb2, - 0x6f, 0xc8, 0x65, 0xc4, 0x7d, 0x4e, 0x88, 0x7c, 0x7a, 0x6b, 0x3b, 0xb2, - 0xc4, 0xde, 0xdf, 0xe7, 0xb0, 0x97, 0xb2, 0x55, 0x70, 0x7e, 0x5e, 0x58, - 0x34, 0x34, 0xc3, 0x63, 0xc0, 0xe7, 0x36, 0xe2, 0xcc, 0xf9, 0x13, 0xd4, - 0x81, 0xd8, 0xc9, 0x3d, 0xd4, 0x5f, 0x27, 0xeb, 0x1c, 0x65, 0x2c, 0xdb, - 0xcd, 0xfe, 0xed, 0xf5, 0xdb, 0xb0, 0xfd, 0x9c, 0x0c, 0xba, 0x79, 0x9c, - 0xed, 0xed, 0x35, 0x7e, 0x53, 0x76, 0xb4, 0x5e, 0xf6, 0x53, 0x3a, 0x31, - 0x6c, 0xcf, 0xbb, 0x42, 0x2e, 0x73, 0x11, 0x79, 0x82, 0x65, 0xfd, 0xd4, - 0x68, 0x9c, 0xef, 0xb0, 0xed, 0xea, 0x50, 0x9b, 0x3b, 0xe0, 0xc6, 0x90, - 0xbd, 0x06, 0x6e, 0x59, 0x45, 0xb6, 0x7d, 0x89, 0x2c, 0x75, 0xcd, 0x9b, - 0x68, 0x78, 0xeb, 0xd2, 0x1f, 0x90, 0x27, 0x8a, 0xfc, 0x73, 0x70, 0x92, - 0x31, 0x35, 0xaa, 0xc5, 0xdb, 0x45, 0xd6, 0x32, 0xc3, 0x19, 0xbe, 0x16, - 0xf1, 0x16, 0x27, 0xfb, 0x6b, 0x26, 0xa7, 0x3c, 0x95, 0xc7, 0xee, 0x7d, - 0x69, 0x3d, 0xb6, 0x5f, 0xc9, 0xf1, 0xd3, 0xde, 0xb1, 0x42, 0xfc, 0x09, - 0x92, 0xcf, 0x7a, 0xe0, 0x8c, 0xe8, 0xfe, 0x26, 0x47, 0x57, 0xd0, 0x05, - 0xfa, 0x58, 0xa9, 0xc8, 0x1b, 0xa7, 0xec, 0x82, 0xc7, 0x6e, 0x6d, 0x8d, - 0x8d, 0xd1, 0xf1, 0xf9, 0x2e, 0x78, 0xb4, 0xb5, 0xe9, 0x42, 0xec, 0xf2, - 0x68, 0x6d, 0x09, 0xf1, 0x77, 0x59, 0xab, 0x0f, 0xdb, 0xdc, 0xe3, 0x48, - 0xe6, 0xa5, 0x52, 0xd9, 0x8b, 0x47, 0xdf, 0xaf, 0x70, 0x1a, 0xb9, 0x76, - 0x35, 0xb6, 0xdb, 0xe2, 0xd0, 0x70, 0xce, 0x77, 0x75, 0xad, 0xc5, 0x21, - 0xfb, 0x5f, 0x89, 0x4a, 0xe9, 0x7c, 0xbd, 0x1c, 0x7e, 0x2d, 0x76, 0xd9, - 0xf8, 0xc5, 0x36, 0x4a, 0x81, 0x25, 0x89, 0x0b, 0xfb, 0x97, 0xfe, 0xa4, - 0xdf, 0xae, 0x2a, 0x15, 0x13, 0xf6, 0xb3, 0x92, 0x83, 0x99, 0x18, 0x06, - 0x53, 0x53, 0xf7, 0xe8, 0xe9, 0x87, 0xd8, 0xfe, 0x81, 0x38, 0xe7, 0x69, - 0xb6, 0x21, 0xfb, 0xf7, 0x64, 0xcf, 0xde, 0xd4, 0xfd, 0x7a, 0x22, 0x5b, - 0x65, 0x19, 0x81, 0x0d, 0x7b, 0x89, 0x7f, 0xd1, 0x16, 0xa9, 0x6f, 0x59, - 0xaf, 0xcd, 0x0b, 0x22, 0x3b, 0xcd, 0x89, 0xc1, 0xb9, 0xc0, 0x40, 0x52, - 0xf6, 0x53, 0x9d, 0x89, 0xad, 0x66, 0x1e, 0x19, 0xad, 0xae, 0xd3, 0xba, - 0x55, 0xd9, 0x0b, 0xf5, 0xc1, 0x97, 0x7b, 0x8c, 0x5a, 0xad, 0x47, 0xcd, - 0xee, 0x67, 0x7c, 0xd9, 0x0d, 0xcc, 0x2e, 0x13, 0x0c, 0xa8, 0x32, 0xa2, - 0xbd, 0x55, 0x98, 0x0b, 0x7f, 0xb5, 0x8d, 0xcb, 0xf1, 0x6f, 0xab, 0x46, - 0x70, 0xa5, 0xf0, 0x4a, 0xf5, 0x7d, 0x6b, 0x88, 0xdc, 0xe4, 0xee, 0xb9, - 0xff, 0xa7, 0x34, 0xbf, 0xee, 0xd4, 0x3e, 0x9d, 0xf3, 0xf2, 0xf3, 0x05, - 0xba, 0x3f, 0xad, 0x88, 0x8e, 0x84, 0x4b, 0x25, 0xb0, 0x95, 0x71, 0xf6, - 0xbf, 0xe6, 0x46, 0xb0, 0x8f, 0xff, 0x7f, 0x76, 0xa5, 0xec, 0x4d, 0xb5, - 0xac, 0x60, 0x60, 0x5e, 0xb8, 0x8a, 0x63, 0x78, 0x96, 0xf7, 0x7b, 0x33, - 0x6f, 0x59, 0xa7, 0xa6, 0x1b, 0xfd, 0xcb, 0x18, 0xec, 0x06, 0xc6, 0x75, - 0x6d, 0x52, 0xfd, 0xef, 0xee, 0x95, 0x83, 0xbb, 0x82, 0x63, 0xf9, 0x7e, - 0xa0, 0x4e, 0x4b, 0xaa, 0xa5, 0x65, 0xa2, 0xd7, 0x81, 0xf1, 0x57, 0xa6, - 0x3c, 0x3b, 0x28, 0xf0, 0x59, 0x7b, 0x5d, 0xa5, 0x77, 0x88, 0xbe, 0x3e, - 0xa4, 0x45, 0xe3, 0xd4, 0xbb, 0x7b, 0x1a, 0xc7, 0x7c, 0xf7, 0xdc, 0x2f, - 0xd9, 0xe3, 0xac, 0x36, 0x66, 0x72, 0x8c, 0x0a, 0xb4, 0xb9, 0xff, 0x99, - 0x5f, 0x7f, 0x6d, 0x24, 0xfb, 0x1a, 0xb2, 0x9a, 0xe8, 0x1b, 0x45, 0xac, - 0x73, 0xb5, 0xf9, 0xf0, 0x8c, 0xae, 0x7a, 0xdd, 0x77, 0x37, 0x6d, 0x34, - 0x34, 0xf7, 0xd7, 0x16, 0x6d, 0xda, 0xfc, 0x16, 0x47, 0x7d, 0x5b, 0xc2, - 0x8e, 0x55, 0x9c, 0x57, 0x23, 0x3a, 0x57, 0x79, 0xc7, 0x42, 0x4d, 0x20, - 0x3c, 0xd7, 0x1e, 0x3f, 0x70, 0x6b, 0x3a, 0x81, 0x6d, 0x29, 0x69, 0x53, - 0xc1, 0xb2, 0xc0, 0xdb, 0x96, 0x7f, 0x7a, 0x02, 0x5b, 0x32, 0x9f, 0xc4, - 0x4d, 0x07, 0xc9, 0x8d, 0xf5, 0xd6, 0x38, 0xf4, 0x68, 0xee, 0xd9, 0xd4, - 0x1c, 0x59, 0xdb, 0x96, 0xbd, 0x45, 0xb7, 0x24, 0x02, 0x70, 0x97, 0x13, - 0x83, 0xc7, 0x02, 0xf2, 0x2c, 0xd3, 0x8b, 0x6c, 0x8b, 0x94, 0xa9, 0xd5, - 0xc6, 0x90, 0x25, 0x73, 0x94, 0xb5, 0xd0, 0xfe, 0xb2, 0xdc, 0x3e, 0x09, - 0x1a, 0x5e, 0x8d, 0xae, 0xbd, 0x41, 0xae, 0xd7, 0x6c, 0x48, 0x1b, 0x0a, - 0xe6, 0x07, 0xa6, 0xa1, 0x6e, 0xe5, 0xab, 0xaf, 0x17, 0x05, 0x8a, 0x18, - 0x4f, 0xc4, 0xb7, 0x8c, 0x8d, 0xc7, 0xf0, 0x1b, 0x62, 0x90, 0xec, 0x19, - 0x4b, 0x4a, 0x3d, 0xb6, 0x35, 0x17, 0x69, 0xf1, 0x53, 0x43, 0xf6, 0x2f, - 0x5b, 0xd6, 0x35, 0x81, 0x37, 0xad, 0x68, 0x0d, 0xe5, 0x21, 0x5f, 0xcb, - 0xd5, 0x95, 0x32, 0xf9, 0xbd, 0x40, 0x4a, 0xe3, 0x2d, 0xa2, 0x93, 0x27, - 0xcd, 0x38, 0xb3, 0x01, 0xc1, 0xfd, 0x0f, 0x62, 0x6f, 0x19, 0x8a, 0xfd, - 0x8c, 0x71, 0x99, 0x52, 0xc9, 0x38, 0xea, 0xf4, 0x8f, 0xd8, 0xeb, 0x05, - 0x1d, 0xc4, 0x68, 0xe1, 0x97, 0x92, 0xf3, 0x39, 0xf1, 0x94, 0x51, 0x85, - 0x27, 0xb5, 0x1c, 0x57, 0x23, 0xd6, 0xe1, 0x07, 0x89, 0x79, 0x59, 0x7a, - 0x08, 0x39, 0xaf, 0xd1, 0x7e, 0x46, 0xf9, 0x0d, 0xfd, 0x1c, 0x78, 0x21, - 0xbd, 0x11, 0x0f, 0xca, 0x1a, 0xa2, 0x52, 0xdb, 0x5c, 0xe7, 0x90, 0xfe, - 0x36, 0x62, 0x6b, 0x46, 0xda, 0xfa, 0x20, 0xb6, 0xd7, 0xd8, 0x9d, 0x97, - 0x55, 0xb0, 0xfc, 0x83, 0xd8, 0x53, 0xc6, 0xe3, 0xf6, 0xdc, 0xc9, 0x73, - 0xaf, 0x5e, 0x53, 0x30, 0xaf, 0x14, 0x2a, 0xf3, 0x06, 0x87, 0x71, 0x33, - 0x1c, 0x55, 0xdf, 0xa4, 0xed, 0xc9, 0xbe, 0x9a, 0xaf, 0xc2, 0x59, 0xe5, - 0xa2, 0x6f, 0xde, 0x0a, 0x57, 0x95, 0x70, 0xf5, 0x02, 0x8f, 0x8e, 0xf2, - 0xbe, 0xe8, 0x36, 0xdc, 0x26, 0xba, 0x75, 0x12, 0x87, 0x7a, 0x24, 0xaf, - 0x33, 0x2a, 0xa9, 0x23, 0xbd, 0x95, 0x9c, 0x1e, 0xe5, 0xc4, 0x4c, 0xc6, - 0x47, 0x37, 0xf3, 0xb7, 0xb6, 0x77, 0xa9, 0xf7, 0x79, 0x7d, 0x65, 0xe4, - 0xf0, 0x96, 0xf5, 0x3e, 0x39, 0xfc, 0xfc, 0x40, 0x5d, 0xd6, 0x20, 0x4e, - 0xe1, 0x06, 0xbd, 0x39, 0x4e, 0xbc, 0x59, 0x6d, 0x9c, 0xb1, 0x62, 0xab, - 0xa4, 0x8c, 0xee, 0x8b, 0x29, 0x85, 0x3e, 0x16, 0xc0, 0x3f, 0xcd, 0x82, - 0x2b, 0x22, 0xcf, 0x14, 0x64, 0xbd, 0xb8, 0x51, 0x9e, 0xf5, 0xb5, 0xc8, - 0xf8, 0x5d, 0xb2, 0xee, 0x86, 0xe8, 0x84, 0x0b, 0x46, 0x76, 0x9f, 0xcc, - 0xd9, 0x0c, 0x0b, 0x81, 0x85, 0xbf, 0x67, 0x2e, 0x24, 0xf3, 0x53, 0x9b, - 0xad, 0x57, 0xb2, 0x41, 0x1f, 0x39, 0xfd, 0xa3, 0xd0, 0x5b, 0x12, 0xd4, - 0x75, 0x53, 0x48, 0x9e, 0xdf, 0x3b, 0x7d, 0x09, 0xd8, 0x3c, 0xde, 0x3c, - 0x89, 0xcf, 0xa1, 0x9c, 0xb9, 0xeb, 0xdc, 0xb1, 0x15, 0xa8, 0xa8, 0x8a, - 0xfa, 0x4a, 0x71, 0x19, 0xcf, 0xd7, 0x30, 0x3f, 0xf9, 0x22, 0x2a, 0x56, - 0xb6, 0x22, 0xc1, 0xb1, 0x97, 0x1b, 0x7f, 0xc5, 0x6b, 0xf7, 0x21, 0x99, - 0x72, 0x71, 0x1c, 0x3f, 0xb1, 0x2a, 0x6a, 0x44, 0x36, 0xd3, 0x5b, 0x66, - 0x30, 0x9f, 0xb6, 0x75, 0x41, 0xdc, 0x4e, 0x09, 0x47, 0xaa, 0x8b, 0xae, - 0x07, 0x73, 0xfb, 0x1a, 0xbd, 0x75, 0x8d, 0xd2, 0x41, 0x9b, 0xed, 0xa1, - 0xce, 0xa5, 0xac, 0x65, 0x2d, 0x0f, 0x9c, 0xa6, 0x8e, 0x3b, 0x78, 0x6e, - 0xf8, 0xdf, 0x84, 0x7a, 0x59, 0x31, 0x4e, 0x58, 0x71, 0xcd, 0x47, 0xbb, - 0x54, 0x57, 0x09, 0x9f, 0x5a, 0x1a, 0x7a, 0x8f, 0xf7, 0xb5, 0xbc, 0x9d, - 0x9e, 0xb9, 0x25, 0xa7, 0xcb, 0x30, 0x75, 0xf9, 0x6f, 0xf6, 0x75, 0x87, - 0x7d, 0xbd, 0x23, 0x7f, 0xfd, 0xcc, 0x2d, 0x3d, 0xc6, 0xcb, 0xbc, 0xde, - 0x4b, 0xdd, 0xab, 0x17, 0x49, 0xfd, 0x75, 0xa6, 0xd4, 0x67, 0x4a, 0x65, - 0xf4, 0xe4, 0xe7, 0xe3, 0x50, 0x7e, 0x3e, 0x26, 0xf2, 0x6d, 0x38, 0xd9, - 0x46, 0x3c, 0x5a, 0x0a, 0x13, 0x65, 0x01, 0xc1, 0x79, 0x91, 0x8b, 0x73, - 0x97, 0x11, 0xb9, 0xd6, 0x30, 0xde, 0x75, 0x3d, 0x53, 0x8a, 0x78, 0xc7, - 0x4c, 0xdb, 0x0e, 0xcf, 0xdc, 0x22, 0xfb, 0xde, 0xde, 0x52, 0x1a, 0x7d, - 0xb2, 0x65, 0x23, 0x45, 0x2e, 0x7b, 0xaf, 0xe9, 0x0c, 0xd7, 0x3b, 0xe6, - 0x65, 0x8b, 0x61, 0xc4, 0xce, 0x28, 0x2e, 0x8f, 0xe0, 0x43, 0x22, 0xdd, - 0xc8, 0xcc, 0x2b, 0x1e, 0x64, 0xce, 0x14, 0xcc, 0x50, 0xb7, 0x6d, 0x44, - 0xec, 0x43, 0xf6, 0xde, 0x37, 0xe7, 0xc4, 0x0a, 0x34, 0xea, 0x0e, 0xcc, - 0x0b, 0xcf, 0x64, 0xe6, 0x45, 0xbb, 0x34, 0x8b, 0x1d, 0xba, 0xff, 0x7a, - 0x2c, 0xb7, 0xeb, 0xed, 0x4b, 0x67, 0xdb, 0x4b, 0x39, 0xa7, 0x8f, 0x51, - 0x8e, 0x6d, 0x01, 0x91, 0xe3, 0x9b, 0x79, 0x39, 0x5a, 0x19, 0x4b, 0x4d, - 0xed, 0xda, 0x40, 0xef, 0x59, 0xbd, 0x3d, 0x63, 0xeb, 0xed, 0x3e, 0x9e, - 0x17, 0x33, 0xbf, 0x2f, 0xc2, 0xd1, 0x7a, 0x6f, 0x7e, 0x1f, 0x9b, 0xe4, - 0x6a, 0x82, 0xbf, 0x0d, 0x7f, 0xbd, 0xda, 0xd0, 0xc3, 0x0e, 0x9b, 0xd7, - 0xbb, 0x11, 0xb7, 0x39, 0xb3, 0x3c, 0xf3, 0xae, 0xc0, 0x23, 0x76, 0x39, - 0x17, 0x75, 0x52, 0x86, 0x47, 0xf3, 0xfe, 0x22, 0x7b, 0x0e, 0x1e, 0xb3, - 0x7f, 0xef, 0xe6, 0xdc, 0xba, 0xe8, 0xab, 0x85, 0x18, 0x25, 0xeb, 0xed, - 0xff, 0xc3, 0xf6, 0xfd, 0x21, 0x1c, 0xb7, 0xff, 0x67, 0x73, 0xf9, 0x16, - 0x7a, 0x4c, 0xd9, 0x3b, 0x53, 0x86, 0x6e, 0x7b, 0x0f, 0xb9, 0xac, 0x01, - 0x5c, 0x89, 0xcd, 0x9a, 0xac, 0x07, 0x93, 0xfb, 0x68, 0x62, 0x13, 0x9d, - 0x48, 0x6a, 0xa6, 0x37, 0x53, 0x3f, 0x35, 0x57, 0x32, 0xb1, 0xa7, 0xfe, - 0x03, 0x2b, 0x6a, 0xe7, 0x4f, 0x27, 0xac, 0xbd, 0xc6, 0xd1, 0x10, 0x3d, - 0xb8, 0xbd, 0xc8, 0xd6, 0x6f, 0xb8, 0xcd, 0xde, 0xff, 0x47, 0x99, 0x9f, - 0x49, 0x48, 0x1c, 0x9d, 0x83, 0xb4, 0x69, 0xc7, 0xe2, 0x96, 0xed, 0x9c, - 0x93, 0x9e, 0x54, 0x20, 0x7a, 0x09, 0xef, 0x4d, 0x30, 0x96, 0x75, 0x53, - 0x9f, 0xb1, 0x16, 0xe1, 0x67, 0x6b, 0xb0, 0x9b, 0x36, 0x36, 0x6e, 0x5a, - 0xd6, 0x3e, 0x62, 0x44, 0xe5, 0x3c, 0x15, 0xd9, 0x9a, 0x35, 0x48, 0x31, - 0x36, 0xed, 0x33, 0x1a, 0x3f, 0x57, 0x84, 0xb8, 0xdf, 0x0d, 0xdd, 0xb7, - 0x85, 0xa3, 0xb9, 0x97, 0xf3, 0x75, 0xd4, 0x14, 0xde, 0xe8, 0x3c, 0xb3, - 0x14, 0x46, 0x78, 0xb1, 0xe3, 0x27, 0xd6, 0xa4, 0xfd, 0xec, 0xb8, 0xeb, - 0x5f, 0x28, 0xc3, 0x46, 0x71, 0xde, 0x4a, 0xce, 0xf1, 0xbb, 0x01, 0x79, - 0x7e, 0x0d, 0xd4, 0xf5, 0x35, 0xb6, 0x8b, 0x0c, 0x7b, 0x43, 0xce, 0xd8, - 0x3e, 0x04, 0x5a, 0x36, 0x28, 0xe7, 0x72, 0x83, 0x4b, 0xc6, 0x4c, 0x8c, - 0xd6, 0x3f, 0x4b, 0x1e, 0x23, 0xf5, 0x8b, 0xf1, 0x84, 0xf9, 0xb4, 0x55, - 0x3b, 0xe3, 0xfb, 0xd6, 0x7e, 0x43, 0x5d, 0x4f, 0x6d, 0xc7, 0xca, 0xd9, - 0x56, 0x19, 0xdb, 0xba, 0x3d, 0xa0, 0x9b, 0xdb, 0xd9, 0xd6, 0xf1, 0xc4, - 0xd1, 0xa0, 0x9b, 0x6d, 0x3d, 0x6a, 0x4a, 0x6e, 0xe0, 0x6c, 0x6e, 0xe6, - 0xdc, 0x76, 0xa5, 0x02, 0xbe, 0xad, 0x94, 0x4b, 0xf2, 0xb7, 0xaf, 0x26, - 0xe4, 0x5d, 0x8f, 0x6f, 0x72, 0x3c, 0xd1, 0x8d, 0x2e, 0x34, 0xde, 0x5b, - 0x41, 0xfb, 0xa9, 0x44, 0xc1, 0xd6, 0x75, 0x1f, 0xf1, 0x0e, 0xb7, 0xb3, - 0xcc, 0xeb, 0x81, 0x39, 0x78, 0x21, 0xd4, 0xb8, 0x72, 0x0e, 0x9c, 0xe4, - 0x21, 0x81, 0xe6, 0x0d, 0x4a, 0x5c, 0x13, 0x5b, 0xbc, 0x2d, 0xad, 0x07, - 0x9b, 0x20, 0xd8, 0xdd, 0x4a, 0x7d, 0xcc, 0xc1, 0xfb, 0x0b, 0x45, 0x2e, - 0x67, 0x38, 0xe8, 0x08, 0x74, 0x3c, 0xcd, 0xf9, 0xad, 0x98, 0x97, 0xcb, - 0x53, 0x33, 0xf6, 0x7e, 0xcd, 0x56, 0x24, 0x33, 0x27, 0xde, 0xdd, 0x6b, - 0xc0, 0x79, 0xa8, 0xfe, 0x41, 0x0b, 0xf6, 0xbb, 0x21, 0x8d, 0x32, 0x0f, - 0xad, 0x32, 0x0f, 0xa5, 0xf4, 0xa7, 0x6b, 0x28, 0xf7, 0x7a, 0x5b, 0xee, - 0x39, 0x18, 0x36, 0x65, 0xfd, 0xcb, 0xa9, 0xdd, 0x86, 0x5e, 0x62, 0x67, - 0xe0, 0x4c, 0x17, 0xfb, 0x79, 0x9d, 0x32, 0xcf, 0xa3, 0xde, 0x27, 0x5b, - 0x84, 0xb7, 0xde, 0x87, 0xbe, 0x54, 0xe1, 0xdd, 0x11, 0x05, 0xe9, 0x80, - 0xf4, 0x71, 0x1f, 0x79, 0x5c, 0x97, 0x35, 0x59, 0x23, 0xd7, 0x77, 0x33, - 0xf7, 0x8f, 0x6a, 0xf4, 0x07, 0xea, 0x1d, 0xfa, 0x1c, 0xe8, 0x13, 0x6f, - 0x38, 0xa2, 0xf4, 0x01, 0xd3, 0x7b, 0x86, 0xd8, 0x70, 0x08, 0x1d, 0x16, - 0xaa, 0x6c, 0x7b, 0xf8, 0xd9, 0x88, 0xf1, 0xa1, 0x22, 0xb1, 0x3d, 0x4b, - 0x1d, 0xa8, 0x9c, 0x13, 0xd1, 0x41, 0x39, 0x7d, 0x76, 0x2c, 0xa0, 0xfb, - 0x5f, 0xa0, 0x3c, 0xdb, 0x29, 0xcf, 0x8a, 0xdc, 0x1c, 0xfa, 0x36, 0x2b, - 0xe2, 0xd3, 0x81, 0x96, 0xd5, 0xbc, 0xbe, 0x8d, 0xf2, 0x04, 0xfa, 0x14, - 0x0c, 0xb5, 0xf4, 0x90, 0x2b, 0x76, 0x50, 0x07, 0xe7, 0xe4, 0x71, 0xdb, - 0x73, 0xd6, 0x41, 0x2e, 0x50, 0x8c, 0xbd, 0xa6, 0xe0, 0xb7, 0x86, 0x61, - 0xda, 0xe9, 0x1e, 0xce, 0x48, 0xd4, 0xab, 0xa2, 0xd8, 0x10, 0x0c, 0xa8, - 0xe1, 0x35, 0x17, 0xe7, 0xa6, 0x12, 0xfb, 0xb5, 0xdd, 0xf6, 0x5e, 0xe5, - 0x1c, 0xb7, 0xfb, 0x83, 0x35, 0xea, 0x15, 0x7e, 0x26, 0xeb, 0x63, 0xb2, - 0x86, 0xd4, 0xeb, 0xc9, 0xed, 0xd7, 0x72, 0x51, 0x27, 0xb9, 0xeb, 0xcf, - 0x68, 0xc2, 0x7d, 0x0b, 0xe5, 0x7f, 0x69, 0x3d, 0x69, 0x97, 0x97, 0x72, - 0x2e, 0x9b, 0xa3, 0x97, 0xda, 0xe5, 0x7e, 0x69, 0x3d, 0xab, 0x39, 0xa7, - 0x94, 0x2b, 0x3c, 0x2f, 0x3c, 0xfa, 0x0d, 0x27, 0x31, 0xaf, 0x78, 0xee, - 0x62, 0x1c, 0x33, 0x4e, 0xd4, 0x9e, 0xac, 0xef, 0x64, 0x1c, 0x9b, 0xba, - 0x7f, 0xcb, 0xc2, 0xe3, 0x76, 0x1e, 0xde, 0x45, 0x3e, 0x7b, 0x74, 0x47, - 0x11, 0x84, 0xa3, 0xca, 0xfa, 0x5d, 0x73, 0xd9, 0xb9, 0x5c, 0x56, 0xf6, - 0x35, 0x5d, 0x66, 0x73, 0xc3, 0xa8, 0x2a, 0xb8, 0xfb, 0x49, 0x7b, 0xf8, - 0x84, 0xbb, 0x74, 0x62, 0x8f, 0x51, 0xe0, 0x2c, 0x47, 0x1f, 0x54, 0x89, - 0x93, 0x03, 0xe6, 0x62, 0x89, 0xcd, 0x7e, 0xd6, 0x0f, 0xc6, 0xd4, 0xa9, - 0xdc, 0xe6, 0x76, 0x0f, 0x2a, 0xba, 0xb6, 0x3a, 0x20, 0xfb, 0x47, 0x65, - 0x2f, 0xa8, 0xf4, 0x55, 0x92, 0x5f, 0x97, 0xfa, 0x38, 0xae, 0x51, 0xe8, - 0x4b, 0xf8, 0xc6, 0xfb, 0xa5, 0x85, 0x7d, 0x86, 0x51, 0x5b, 0xce, 0x5f, - 0x59, 0x2b, 0xb5, 0xec, 0x4c, 0x0d, 0xe7, 0xcb, 0x1e, 0xcd, 0xcb, 0x1e, - 0xfb, 0xd8, 0x75, 0xb5, 0xa9, 0xfb, 0xee, 0x82, 0xf9, 0xe7, 0x5d, 0xf2, - 0x0c, 0x46, 0xd6, 0x5c, 0xe5, 0x9e, 0x82, 0x2e, 0xe2, 0x50, 0x54, 0x6b, - 0x64, 0x9c, 0xd7, 0x7d, 0x6b, 0x39, 0x1f, 0x71, 0xaf, 0xec, 0x51, 0x2f, - 0xc4, 0xc8, 0x62, 0xe4, 0xd6, 0x3e, 0x65, 0x9f, 0x45, 0x6e, 0xbd, 0x93, - 0x76, 0x8f, 0xae, 0xf4, 0xef, 0xad, 0xac, 0xd7, 0xc9, 0x58, 0x78, 0x6e, - 0x7f, 0xf4, 0x10, 0xf5, 0x3a, 0xcc, 0x7b, 0x9b, 0xcf, 0xae, 0xa7, 0xc8, - 0x9a, 0x92, 0xc4, 0xde, 0xdf, 0x59, 0x6d, 0xe7, 0x95, 0x9d, 0xba, 0x57, - 0xbc, 0x26, 0x26, 0xcf, 0xdc, 0x46, 0xf3, 0xeb, 0xee, 0x4d, 0x1f, 0x79, - 0xe6, 0x36, 0x41, 0x5b, 0x42, 0x74, 0x33, 0xb9, 0x5d, 0x1c, 0x3d, 0x18, - 0x4d, 0xd4, 0x69, 0x5b, 0xa0, 0xc9, 0x7a, 0x33, 0xff, 0x7a, 0xb0, 0x3f, - 0x81, 0x68, 0xd1, 0xa5, 0x95, 0xe4, 0x5b, 0x88, 0x3a, 0x18, 0xa3, 0x1e, - 0x4d, 0xd4, 0x35, 0x6f, 0xe3, 0x98, 0xfc, 0x2b, 0x7b, 0x30, 0x9c, 0x68, - 0xfc, 0x2b, 0xc6, 0x11, 0x7f, 0x99, 0xcd, 0x75, 0xe2, 0x7f, 0xbd, 0x97, - 0x38, 0xb0, 0x29, 0xbf, 0xe6, 0xd5, 0x96, 0xf8, 0x35, 0xe5, 0xb7, 0x85, - 0x64, 0xbd, 0x4f, 0x2a, 0x37, 0xc1, 0x3c, 0xff, 0x04, 0xd6, 0xf5, 0x2b, - 0x78, 0xd2, 0x38, 0x81, 0xb5, 0x43, 0x22, 0xcf, 0x09, 0xac, 0xe9, 0x7f, - 0x09, 0x7b, 0xfa, 0x67, 0xa0, 0xc9, 0xd6, 0x4d, 0x07, 0x36, 0xec, 0x3c, - 0x88, 0xed, 0x29, 0x0b, 0xdb, 0x42, 0x1e, 0xac, 0x7f, 0x58, 0xc1, 0xf2, - 0xc0, 0x61, 0x6c, 0xd9, 0x69, 0xe1, 0xe2, 0x50, 0x27, 0x9a, 0xcd, 0x32, - 0x14, 0x57, 0xcd, 0x6b, 0x57, 0x59, 0xae, 0x6d, 0xb8, 0x23, 0xbf, 0x2f, - 0x79, 0x3f, 0xb1, 0x40, 0x85, 0xcf, 0x90, 0x3d, 0xc7, 0x51, 0xe5, 0xa6, - 0x4c, 0x93, 0xd2, 0x9a, 0x7f, 0x66, 0x79, 0x7d, 0xa6, 0xa8, 0x02, 0xa5, - 0x71, 0xec, 0x09, 0x9d, 0xc0, 0xd0, 0xd0, 0x07, 0xe5, 0x39, 0x7f, 0x99, - 0x20, 0x77, 0x90, 0x9c, 0xc3, 0xa4, 0x4d, 0x7d, 0xd2, 0xfb, 0x40, 0x62, - 0x77, 0x93, 0xf8, 0xe9, 0xe0, 0x49, 0x9c, 0x1c, 0xfc, 0x37, 0x2c, 0xd1, - 0x24, 0x7f, 0xb4, 0x3a, 0x9d, 0x11, 0xcb, 0xda, 0xd5, 0x10, 0xb7, 0x6a, - 0x8c, 0x5f, 0xb0, 0xed, 0x0a, 0x4c, 0x8f, 0xbc, 0x88, 0x6d, 0x1a, 0xdb, - 0x4a, 0xed, 0xc7, 0x0e, 0xc6, 0x75, 0x5f, 0xe4, 0x66, 0xf8, 0x52, 0x59, - 0xb3, 0x1a, 0xd1, 0x1d, 0xd5, 0xd0, 0x37, 0x56, 0x39, 0x8c, 0x8e, 0x7f, - 0x55, 0xea, 0x71, 0x7d, 0xe6, 0x24, 0x7e, 0x3e, 0x68, 0xef, 0xa5, 0x6a, - 0xfd, 0xae, 0x62, 0x75, 0x6e, 0x0b, 0xe9, 0xcd, 0xff, 0x43, 0x89, 0xc6, - 0x4b, 0x69, 0x53, 0x25, 0xcc, 0x09, 0x6e, 0x18, 0x94, 0x1c, 0xb1, 0x15, - 0xee, 0x3e, 0x3d, 0xbb, 0x94, 0x3c, 0xfb, 0xee, 0x05, 0xf1, 0x99, 0xd3, - 0x68, 0x97, 0x0e, 0x45, 0x0f, 0x1a, 0x6a, 0x27, 0x8e, 0x98, 0xfa, 0xc4, - 0xef, 0x1c, 0xc6, 0xd0, 0x77, 0x50, 0x8f, 0x55, 0x19, 0x7d, 0xe8, 0x32, - 0xe6, 0x61, 0x5b, 0x92, 0x26, 0x52, 0x49, 0xbd, 0xb5, 0xc3, 0xd1, 0x8b, - 0x3b, 0x02, 0xb5, 0x1b, 0xdf, 0x25, 0x97, 0xf3, 0x10, 0x53, 0x92, 0xe3, - 0x23, 0xcc, 0x5f, 0x7b, 0xb1, 0xe1, 0xe1, 0x08, 0xd6, 0xef, 0x32, 0xd1, - 0x93, 0x1c, 0xa1, 0x6c, 0x3f, 0x2c, 0x97, 0xbd, 0x34, 0x2d, 0xa1, 0xf8, - 0xb5, 0x2a, 0x02, 0x51, 0xf6, 0xd9, 0xa8, 0x46, 0x02, 0x7e, 0x55, 0x61, - 0xf4, 0x1f, 0x77, 0xa2, 0x9b, 0x65, 0xfa, 0x52, 0xb4, 0xb9, 0xa4, 0x9b, - 0xf1, 0x72, 0x16, 0x86, 0xc7, 0x7c, 0xd8, 0x37, 0xe6, 0xc1, 0xd0, 0x98, - 0xc6, 0xa3, 0x14, 0x0f, 0x0d, 0xc8, 0x9e, 0x14, 0x2f, 0x9e, 0xd8, 0xeb, - 0xc6, 0xa6, 0x07, 0x3c, 0x98, 0x13, 0x99, 0x8e, 0xbd, 0x7b, 0x4b, 0xb1, - 0x9b, 0xd7, 0xab, 0x16, 0xfa, 0xf1, 0x38, 0xaf, 0xf7, 0x3f, 0xe0, 0xe2, - 0x3c, 0x5c, 0x8c, 0x03, 0x34, 0xec, 0xa1, 0xb1, 0x32, 0xa4, 0x06, 0x68, - 0xf2, 0xe4, 0xac, 0x6f, 0x31, 0xc3, 0x18, 0xdd, 0xcb, 0xd8, 0xf8, 0xb0, - 0x89, 0x04, 0xfb, 0xd9, 0x4e, 0x5d, 0xf5, 0x10, 0xd7, 0x36, 0x8c, 0x09, - 0xc6, 0xaf, 0xc2, 0x35, 0x7d, 0x7a, 0x73, 0x93, 0x62, 0x44, 0x17, 0xd9, - 0xfb, 0xb4, 0xe4, 0xbd, 0xad, 0x55, 0x68, 0x4c, 0xe8, 0x66, 0x13, 0x3a, - 0x71, 0x8c, 0xe3, 0xfe, 0x7f, 0xe8, 0xb7, 0x8b, 0x1d, 0x7a, 0xef, 0xd5, - 0xea, 0x41, 0xec, 0xc8, 0x1c, 0x22, 0x57, 0x07, 0xc2, 0x7b, 0x0e, 0x92, - 0xbf, 0x1d, 0x21, 0xfe, 0xbc, 0x6e, 0xf9, 0x0c, 0x15, 0xd7, 0xdf, 0x6f, - 0x84, 0xdf, 0x53, 0x02, 0x1b, 0x7f, 0x45, 0x1d, 0x7c, 0x7e, 0xaf, 0x8a, - 0xeb, 0x76, 0x2c, 0x46, 0x3a, 0x14, 0xc5, 0xf6, 0x45, 0x2a, 0xae, 0x7d, - 0xf8, 0x20, 0x71, 0x7f, 0xc2, 0xe6, 0xc9, 0xd9, 0xf4, 0x7d, 0x08, 0xf6, - 0xc9, 0x9a, 0xbc, 0x9b, 0xf1, 0xbb, 0x1c, 0xc7, 0xfb, 0x3b, 0xe9, 0xb7, - 0xe5, 0x38, 0x3a, 0x74, 0x90, 0xf6, 0x58, 0x8e, 0x23, 0xfd, 0xc6, 0xc4, - 0x4f, 0x1d, 0xe5, 0x78, 0x82, 0xe7, 0x3b, 0x78, 0xbe, 0x70, 0xc0, 0xe8, - 0xef, 0x50, 0xcb, 0xb1, 0x60, 0x4f, 0x03, 0xfa, 0x93, 0x62, 0x9b, 0x1a, - 0x36, 0x8e, 0xd5, 0xe7, 0x75, 0x2f, 0x3a, 0xf7, 0xe2, 0x4e, 0xea, 0xea, - 0x8e, 0x1d, 0x9d, 0xec, 0xcf, 0x47, 0x9d, 0x1f, 0xc4, 0x43, 0xcc, 0xeb, - 0xb6, 0x25, 0x7d, 0x38, 0x9d, 0x32, 0xfc, 0x5f, 0x52, 0x0c, 0xb3, 0x44, - 0x09, 0x68, 0xc7, 0xe1, 0xc3, 0xc9, 0x4c, 0x29, 0xba, 0x07, 0x66, 0xe1, - 0xa7, 0xb4, 0xcf, 0x07, 0x1f, 0x90, 0xfe, 0x26, 0x18, 0x1f, 0x66, 0xe3, - 0x89, 0x11, 0x93, 0x6d, 0xcb, 0x3c, 0x49, 0xcc, 0xe9, 0x81, 0x2b, 0x25, - 0xbe, 0x11, 0xdd, 0x41, 0xb3, 0x20, 0x26, 0x1e, 0x46, 0xa6, 0x5f, 0xef, - 0xbd, 0x41, 0x15, 0x5e, 0xad, 0x52, 0x97, 0x0e, 0x4c, 0x6a, 0x7a, 0xbc, - 0x4a, 0x8d, 0xf7, 0x33, 0x7f, 0x8d, 0x57, 0xab, 0x87, 0xf1, 0x44, 0xbf, - 0x13, 0xf3, 0x16, 0xaa, 0xbc, 0x1e, 0x3f, 0xc3, 0xd8, 0x16, 0x9f, 0xa3, - 0x9a, 0xd8, 0x6d, 0xcb, 0x8a, 0x78, 0x11, 0xb9, 0x7d, 0xe5, 0xc2, 0x5a, - 0xc6, 0x2f, 0x87, 0xd8, 0x5e, 0xac, 0x5c, 0x75, 0x52, 0xef, 0x27, 0x31, - 0x42, 0xbb, 0x7e, 0x94, 0xc7, 0x81, 0x41, 0xab, 0x73, 0x39, 0x39, 0xf7, - 0xc5, 0x01, 0xab, 0xf3, 0x06, 0xd3, 0xf0, 0x15, 0xa9, 0x81, 0xe8, 0xdd, - 0x38, 0x89, 0xfd, 0x23, 0x52, 0x06, 0x6e, 0x6f, 0x84, 0x79, 0x75, 0xd2, - 0xea, 0xdc, 0x61, 0x5e, 0x8c, 0x06, 0x3b, 0x37, 0xfe, 0x55, 0x79, 0x0e, - 0x33, 0xc5, 0x8f, 0x64, 0x0d, 0x64, 0x12, 0xbf, 0x62, 0x3b, 0xef, 0x0d, - 0x56, 0x62, 0x5a, 0xb5, 0xf8, 0xc1, 0x09, 0xbc, 0xdd, 0xff, 0x22, 0x4e, - 0xf7, 0x5b, 0x58, 0x10, 0xb2, 0xe0, 0x0c, 0xd5, 0x99, 0x4d, 0xea, 0x65, - 0xc4, 0x08, 0x05, 0xd7, 0xcc, 0x7d, 0x09, 0xef, 0xd0, 0xff, 0xaf, 0x9d, - 0x6b, 0xd9, 0xb2, 0xf4, 0x61, 0xa1, 0xb5, 0xbd, 0x46, 0xfc, 0xc6, 0xb4, - 0xf7, 0xf5, 0x7c, 0x72, 0x1e, 0x5c, 0xd8, 0xb7, 0x26, 0xb9, 0xf0, 0x49, - 0x0c, 0x0f, 0x1a, 0xd1, 0x75, 0x05, 0x39, 0xfb, 0x4f, 0x52, 0x07, 0x16, - 0x76, 0x98, 0x47, 0x1f, 0xae, 0xc2, 0xbc, 0x33, 0xcc, 0x1a, 0xaf, 0x98, - 0x43, 0xdb, 0x59, 0xb0, 0x30, 0x60, 0x2e, 0x53, 0xdf, 0xa4, 0x9f, 0x9e, - 0xc4, 0xbe, 0xa1, 0x02, 0x5e, 0xfb, 0xd0, 0x44, 0x3f, 0xcf, 0xed, 0x65, - 0xf7, 0xa2, 0x31, 0x75, 0xc8, 0x5e, 0x7f, 0x38, 0x40, 0x7c, 0xcc, 0x3d, - 0xd3, 0xd4, 0x30, 0x92, 0x69, 0x22, 0x36, 0x44, 0xf1, 0xcf, 0x99, 0x08, - 0xf1, 0x21, 0x4c, 0x7c, 0x68, 0x20, 0x3e, 0x98, 0xc4, 0x87, 0x7a, 0xe2, - 0x43, 0xd0, 0x7e, 0xd6, 0x2f, 0x6b, 0xe6, 0x43, 0xa3, 0x2f, 0xa2, 0x68, - 0xe0, 0x04, 0x5c, 0xf4, 0x81, 0xe3, 0xa6, 0x45, 0x7e, 0x52, 0xa7, 0xad, - 0xc1, 0xc5, 0x4a, 0x54, 0xf3, 0x62, 0x28, 0x73, 0x02, 0x25, 0x03, 0x1a, - 0xc7, 0x22, 0xfb, 0x33, 0x6a, 0xc3, 0xbd, 0xc4, 0xea, 0x5f, 0x1b, 0x75, - 0xbd, 0x5e, 0xd4, 0xed, 0xae, 0x81, 0xd1, 0xbf, 0x50, 0x9d, 0xab, 0x44, - 0xbf, 0xe0, 0xe5, 0x38, 0xab, 0x31, 0xfb, 0x01, 0x0d, 0x73, 0x78, 0xfc, - 0x53, 0xaa, 0x76, 0xe2, 0x75, 0x07, 0xbc, 0x33, 0x48, 0x77, 0x66, 0x92, - 0x09, 0x90, 0xd5, 0x7a, 0x7d, 0xb8, 0xe4, 0xc0, 0x49, 0x55, 0x41, 0xf6, - 0x0b, 0x12, 0xf3, 0xea, 0x82, 0x3d, 0xaa, 0x2a, 0x6b, 0x48, 0xc4, 0x70, - 0x1e, 0x2a, 0x22, 0x64, 0x11, 0xb3, 0x98, 0x5f, 0x58, 0x6b, 0xcc, 0x12, - 0x6c, 0xae, 0x57, 0x65, 0x6f, 0xc8, 0x21, 0x89, 0x51, 0x33, 0x18, 0x23, - 0x4a, 0x93, 0xf1, 0xdb, 0x66, 0xc0, 0x83, 0x92, 0xa4, 0x65, 0x3d, 0x16, - 0xd2, 0xe0, 0x89, 0x04, 0xa2, 0x1b, 0x98, 0x46, 0x7e, 0x61, 0x5e, 0x18, - 0xd7, 0x64, 0x0e, 0x60, 0x80, 0xe3, 0x5b, 0x9e, 0x29, 0xbc, 0xe3, 0xf9, - 0xc9, 0x7f, 0xe7, 0xde, 0x15, 0xbd, 0x64, 0xf7, 0x0c, 0x18, 0xda, 0x5d, - 0x6a, 0xbc, 0x92, 0x1c, 0xfc, 0x00, 0xe3, 0x9e, 0x32, 0x79, 0xa3, 0x82, - 0xd6, 0x81, 0x38, 0xa6, 0x85, 0x7e, 0xa0, 0xc4, 0xaa, 0x75, 0xbf, 0x5f, - 0xa9, 0xc6, 0x8d, 0x0f, 0x50, 0xd7, 0x0b, 0x26, 0x68, 0x2b, 0x3e, 0x7c, - 0x67, 0x54, 0x74, 0x5b, 0x3b, 0xb4, 0x83, 0xe3, 0x98, 0x98, 0x7b, 0x40, - 0x70, 0xf2, 0xa0, 0x1b, 0x8e, 0x83, 0xd3, 0x99, 0x9b, 0xd6, 0xcf, 0xbd, - 0xa4, 0xe3, 0xdf, 0x54, 0xd1, 0x8b, 0xf0, 0x6b, 0xbd, 0x3f, 0xae, 0x18, - 0xda, 0x2f, 0x95, 0x03, 0xe4, 0x6c, 0x5e, 0x3c, 0x96, 0x39, 0x4c, 0x5d, - 0xee, 0xcf, 0xe7, 0x4b, 0xab, 0x90, 0xe8, 0x93, 0x7d, 0x81, 0x27, 0x30, - 0x7b, 0x40, 0x6f, 0xd9, 0xaa, 0x18, 0xc1, 0x6b, 0x95, 0x13, 0x98, 0x39, - 0x10, 0xe4, 0x5c, 0x6a, 0x58, 0x96, 0x2c, 0xe0, 0xa7, 0x60, 0xf0, 0x2a, - 0x62, 0xb0, 0xb5, 0xf8, 0xa7, 0x66, 0x9c, 0x39, 0x8e, 0x6e, 0x3a, 0x15, - 0xbd, 0x75, 0xae, 0x22, 0xfb, 0x80, 0x8c, 0x33, 0x6d, 0xac, 0xe3, 0x19, - 0xa8, 0xc7, 0x57, 0x39, 0xe6, 0x66, 0xce, 0xdb, 0x8b, 0x0b, 0x2d, 0x2c, - 0x5a, 0xa8, 0xef, 0x2e, 0x71, 0x44, 0xef, 0xaa, 0x42, 0xb6, 0xa3, 0x86, - 0x76, 0x73, 0xc7, 0x02, 0x3d, 0xfc, 0x03, 0xe2, 0x2e, 0x71, 0x1a, 0xdd, - 0x8c, 0x3b, 0x6b, 0x18, 0x8b, 0x4a, 0x23, 0x7a, 0x2f, 0x73, 0xd4, 0xf7, - 0x6e, 0x75, 0x44, 0x43, 0xf2, 0x1e, 0xd1, 0xdf, 0x63, 0x31, 0xdc, 0xa1, - 0x0a, 0xe2, 0xa0, 0x9e, 0x7d, 0x11, 0xfa, 0xee, 0xaf, 0x92, 0x93, 0xfe, - 0x98, 0xfc, 0xae, 0xe6, 0xd2, 0x43, 0xc4, 0xa8, 0x11, 0x3c, 0x98, 0x39, - 0x88, 0xdd, 0x99, 0x34, 0x76, 0x66, 0xb6, 0x29, 0x43, 0xf6, 0xb3, 0x45, - 0x45, 0xde, 0x99, 0x8b, 0x56, 0x28, 0x5f, 0x46, 0x79, 0xe8, 0x5b, 0xd6, - 0x50, 0x95, 0x8a, 0xca, 0x50, 0x10, 0xd7, 0x24, 0xe3, 0x70, 0x44, 0xde, - 0xb5, 0xe4, 0x7d, 0xed, 0xf5, 0xe3, 0x06, 0xae, 0x4e, 0x96, 0x22, 0xb6, - 0xc7, 0xb2, 0x7a, 0x1b, 0x9c, 0x58, 0x3b, 0x5e, 0x8f, 0x65, 0x03, 0x0f, - 0x59, 0x73, 0x18, 0x73, 0x3e, 0xbc, 0xdc, 0x83, 0x5b, 0xf7, 0x78, 0xd0, - 0x96, 0x8c, 0xc2, 0x17, 0x29, 0xe3, 0xef, 0x80, 0xb9, 0x04, 0xc6, 0xc4, - 0x04, 0x8c, 0xde, 0xab, 0x1c, 0x81, 0xfd, 0x61, 0xd5, 0x83, 0xbf, 0x21, - 0x8e, 0x2f, 0x27, 0xee, 0xc4, 0xc6, 0x2d, 0x54, 0x46, 0xbc, 0xb8, 0x8d, - 0xf5, 0xaf, 0xe3, 0xdc, 0xbf, 0xb3, 0x68, 0x3f, 0xb1, 0x40, 0xf6, 0x42, - 0x6a, 0xd8, 0x30, 0xee, 0xa6, 0xae, 0xdc, 0x88, 0xed, 0xab, 0xc6, 0xd5, - 0x0f, 0xf8, 0x71, 0xeb, 0xb8, 0x07, 0x8d, 0x49, 0x6b, 0xf1, 0x01, 0x33, - 0xbe, 0x52, 0x83, 0x81, 0xb6, 0x71, 0x2f, 0xbe, 0x92, 0xd4, 0x7d, 0xd7, - 0x32, 0xe7, 0x1f, 0x31, 0x83, 0xf8, 0x5f, 0xe3, 0x3e, 0xdc, 0x94, 0x3c, - 0x2a, 0x79, 0xe4, 0x12, 0x27, 0x63, 0xcf, 0xbd, 0xe3, 0xb3, 0xb0, 0x32, - 0xa9, 0x9f, 0x99, 0x20, 0xb7, 0xeb, 0xdc, 0x67, 0xe2, 0xae, 0x71, 0x15, - 0xad, 0x6c, 0xe7, 0xc6, 0xe4, 0x6c, 0x74, 0xec, 0x6b, 0xa0, 0x0c, 0x0b, - 0xb1, 0x7c, 0xc0, 0x09, 0x93, 0x2c, 0x1e, 0x5f, 0x04, 0x5a, 0x06, 0x26, - 0x98, 0xc7, 0xdd, 0x87, 0xed, 0x7d, 0x26, 0x6e, 0x1f, 0x97, 0xf3, 0x83, - 0xf6, 0x3b, 0xae, 0xef, 0x3d, 0xbc, 0x10, 0x9f, 0x1f, 0x50, 0x89, 0x03, - 0xc5, 0x18, 0x5a, 0xa9, 0xe0, 0x2b, 0xbc, 0xbe, 0x35, 0x25, 0x7b, 0x90, - 0x81, 0xd0, 0x8e, 0xc0, 0xfe, 0x2a, 0x72, 0x86, 0x45, 0x0f, 0xe7, 0xae, - 0x3f, 0x48, 0x9c, 0x2f, 0x21, 0xce, 0x97, 0x91, 0xc3, 0x5e, 0x35, 0x7c, - 0x10, 0xf7, 0x13, 0x97, 0x0f, 0x0d, 0x74, 0x32, 0xee, 0x94, 0xe3, 0x71, - 0xc6, 0x81, 0x24, 0xcf, 0x4f, 0xec, 0x30, 0x3a, 0x4a, 0x88, 0xd3, 0x3f, - 0x20, 0xfe, 0xf6, 0x12, 0x33, 0xee, 0x48, 0x32, 0xdc, 0xef, 0x60, 0x0e, - 0x70, 0x69, 0x74, 0xbe, 0x87, 0x39, 0xd6, 0xb5, 0x4a, 0xc0, 0xf7, 0x26, - 0xca, 0xe1, 0x78, 0xb8, 0x1a, 0x8d, 0x0f, 0x48, 0x19, 0xc1, 0x2f, 0x15, - 0xea, 0x5e, 0x27, 0x75, 0x7e, 0x18, 0x56, 0xbf, 0x83, 0xe3, 0xad, 0x35, - 0xc9, 0xc0, 0xf1, 0x9a, 0xa9, 0x6b, 0xff, 0x4c, 0xac, 0x7d, 0x9f, 0x98, - 0xea, 0x9f, 0xd1, 0x80, 0x26, 0xc3, 0xe4, 0x71, 0x18, 0x27, 0xfb, 0x0d, - 0x53, 0xf6, 0xe4, 0xbd, 0x4e, 0x9e, 0x37, 0x39, 0x83, 0x31, 0xd3, 0x10, - 0x3f, 0x1c, 0xe1, 0x78, 0x54, 0xc9, 0x4b, 0xe0, 0x18, 0x03, 0xde, 0x7e, - 0x78, 0x31, 0xc7, 0x25, 0xb1, 0x54, 0xe2, 0xdd, 0x08, 0x65, 0x5d, 0x8c, - 0x15, 0xd4, 0x47, 0x53, 0x52, 0x45, 0x7a, 0x5f, 0x04, 0xb7, 0xef, 0xca, - 0xc5, 0xe1, 0x8d, 0xa1, 0xf8, 0x0d, 0x8c, 0xc3, 0xe1, 0x52, 0xc6, 0x61, - 0x57, 0x44, 0x64, 0x73, 0x62, 0x98, 0x71, 0x7b, 0x73, 0x2a, 0x8c, 0x66, - 0xce, 0xe1, 0x44, 0x9a, 0xfd, 0x26, 0x67, 0xe1, 0x78, 0xda, 0xc3, 0x98, - 0xa5, 0xf1, 0x20, 0xaa, 0x8d, 0x4c, 0xe7, 0xe1, 0xe7, 0x71, 0x31, 0x0f, - 0xc3, 0xbe, 0xb6, 0x26, 0xa9, 0x20, 0xde, 0xa2, 0xd8, 0x7c, 0xfe, 0x78, - 0x5a, 0xb0, 0x59, 0xd6, 0x32, 0xef, 0xae, 0x94, 0x3d, 0xa8, 0xfd, 0xa9, - 0x97, 0x50, 0x49, 0x7c, 0xaa, 0xc8, 0xe3, 0xd0, 0xcf, 0x42, 0x82, 0xbb, - 0xb5, 0xc4, 0x5d, 0xd9, 0x4f, 0x64, 0x59, 0xab, 0x02, 0x53, 0xf1, 0xe8, - 0xff, 0xfb, 0x30, 0x6a, 0xef, 0xab, 0x15, 0x4c, 0x22, 0xfe, 0xa5, 0x88, - 0x7f, 0x1c, 0x43, 0xd7, 0x95, 0xc4, 0x40, 0xca, 0xf4, 0x8f, 0x29, 0x62, - 0x20, 0x71, 0xfa, 0x20, 0x71, 0xfa, 0xdb, 0xc4, 0xe9, 0x6f, 0x11, 0xa7, - 0x1f, 0x27, 0x26, 0xe4, 0xd6, 0xf4, 0x9a, 0xe5, 0xb9, 0x0a, 0xe7, 0xe3, - 0x1d, 0x7b, 0x6d, 0xb1, 0x86, 0xba, 0x9a, 0x3d, 0xa0, 0x60, 0x8e, 0xa1, - 0xef, 0x17, 0xbb, 0xff, 0x31, 0xe7, 0xc9, 0x3f, 0x2d, 0xb7, 0xe7, 0xb7, - 0x29, 0xd9, 0x03, 0x77, 0xb2, 0x4e, 0xeb, 0x85, 0xfd, 0x0d, 0x01, 0x53, - 0xb8, 0x68, 0x51, 0x72, 0x0d, 0x1c, 0xc9, 0xba, 0xfd, 0xc7, 0xe4, 0xf9, - 0xed, 0x74, 0xc9, 0xeb, 0xd7, 0xc8, 0x1e, 0xed, 0xfd, 0xb2, 0x37, 0x6c, - 0x19, 0xef, 0xb9, 0x92, 0x75, 0xe6, 0x9b, 0xb0, 0xb1, 0xcd, 0x3f, 0x69, - 0xdf, 0xab, 0x7d, 0xef, 0x7e, 0xea, 0x2b, 0xcb, 0x36, 0xd3, 0x29, 0xd9, - 0x17, 0x3b, 0x0b, 0x8f, 0x66, 0xe4, 0x77, 0x5d, 0x6b, 0x42, 0xdd, 0x8f, - 0x58, 0x8d, 0xf0, 0xf1, 0x30, 0xae, 0x4f, 0x7a, 0x68, 0x07, 0x71, 0x54, - 0xd0, 0xb7, 0xbe, 0x36, 0xde, 0x40, 0x5f, 0x7b, 0xc8, 0xd2, 0x22, 0x81, - 0xd6, 0x71, 0x72, 0x9e, 0xf5, 0xe3, 0x8b, 0xb1, 0x74, 0xc0, 0xb2, 0x3c, - 0x97, 0x19, 0xe1, 0x0d, 0x8a, 0x1f, 0x2e, 0xfa, 0xa0, 0x83, 0x7e, 0xb5, - 0x6e, 0x4f, 0x40, 0x7b, 0x93, 0x78, 0xda, 0xde, 0x70, 0x80, 0xf6, 0x61, - 0x9c, 0x69, 0x26, 0x96, 0x3a, 0x23, 0x01, 0xe6, 0x89, 0x1e, 0xda, 0xbe, - 0x17, 0x67, 0x12, 0xe2, 0x5f, 0x7a, 0xc7, 0x3f, 0x33, 0x37, 0xe9, 0xa0, - 0x6f, 0xfc, 0x32, 0x31, 0x8b, 0x3e, 0xe0, 0xc6, 0xdb, 0x09, 0x83, 0xfe, - 0xe6, 0xc1, 0x3b, 0x89, 0x7a, 0xf6, 0x15, 0x64, 0x19, 0x3f, 0xee, 0x1c, - 0x0f, 0xd3, 0xcf, 0xae, 0xe4, 0x21, 0xef, 0x53, 0xd7, 0xc6, 0xbf, 0xa3, - 0xd4, 0xf6, 0xcf, 0x56, 0xab, 0x10, 0xad, 0xd6, 0xf0, 0xf5, 0xf1, 0xcf, - 0xe2, 0x3f, 0x18, 0xb7, 0xd7, 0x26, 0xc1, 0x39, 0x44, 0x88, 0x3c, 0x70, - 0x62, 0x9f, 0x3c, 0x4b, 0x44, 0x5d, 0x74, 0xae, 0x43, 0x67, 0x6e, 0xab, - 0x67, 0x4f, 0x3b, 0x9c, 0xec, 0x93, 0xac, 0x98, 0x65, 0x7f, 0xd9, 0x5f, - 0x8a, 0xbb, 0xf6, 0x1c, 0xa0, 0x8f, 0x14, 0x61, 0xc1, 0xfd, 0x6e, 0x7c, - 0x7d, 0xdf, 0x08, 0xb9, 0x83, 0x8a, 0x99, 0xcc, 0x95, 0x86, 0x48, 0x14, - 0x66, 0x0e, 0x47, 0x70, 0xdb, 0xae, 0x11, 0x0c, 0xe4, 0x79, 0x5e, 0x28, - 0x14, 0xff, 0x9f, 0x2a, 0x0e, 0x90, 0x47, 0x04, 0xda, 0x3f, 0x43, 0x1b, - 0xab, 0x88, 0x04, 0xe2, 0x32, 0xee, 0x16, 0xda, 0x58, 0x0f, 0xe7, 0x33, - 0xcd, 0x71, 0x24, 0x68, 0x63, 0x8f, 0x51, 0xfe, 0xed, 0xb4, 0xb1, 0x38, - 0x6d, 0x2c, 0x4e, 0x7b, 0x8a, 0xd3, 0xc6, 0xe4, 0x9d, 0xfd, 0x38, 0x6d, - 0x2c, 0x4e, 0x1b, 0x8b, 0xa7, 0x17, 0x63, 0x94, 0x4c, 0x63, 0xcb, 0x48, - 0x03, 0x71, 0x4c, 0xb1, 0xa3, 0x52, 0xf6, 0x86, 0xcf, 0x92, 0xb3, 0x5f, - 0xc5, 0x43, 0x41, 0x33, 0x7d, 0xb2, 0x77, 0x68, 0x84, 0x9c, 0xc7, 0x8d, - 0xdf, 0x64, 0x84, 0xe3, 0x37, 0x30, 0x8f, 0x3d, 0x4c, 0x9e, 0xaf, 0xe2, - 0x49, 0x53, 0xf2, 0x60, 0x93, 0xe7, 0x8c, 0x35, 0x29, 0xe1, 0x6b, 0x87, - 0x71, 0x47, 0x3f, 0x70, 0x2d, 0x79, 0x61, 0x35, 0x79, 0xc9, 0xde, 0x05, - 0xfc, 0xfd, 0xf0, 0x01, 0xda, 0xbc, 0xf8, 0x63, 0x6e, 0xaf, 0xeb, 0xf1, - 0xfe, 0x5a, 0xdf, 0xd5, 0xf4, 0xc1, 0x7b, 0x59, 0xd7, 0xf9, 0xb0, 0xd4, - 0x39, 0xc0, 0xb6, 0xf5, 0xf0, 0x6f, 0x38, 0xff, 0xad, 0xf7, 0x57, 0xe3, - 0xed, 0x5d, 0x7a, 0xf8, 0x7d, 0x62, 0x5e, 0xb5, 0xc3, 0x5a, 0xfc, 0x99, - 0x50, 0x60, 0xe3, 0x67, 0xd4, 0x1c, 0xdf, 0x6b, 0xd9, 0xe1, 0xc4, 0xfe, - 0xd0, 0x62, 0x78, 0x16, 0x14, 0x38, 0x1f, 0x6d, 0xa9, 0x5a, 0x38, 0x96, - 0x1e, 0x3e, 0x4d, 0xae, 0x92, 0x64, 0xfb, 0xa3, 0xe9, 0x23, 0xc4, 0x90, - 0xfb, 0xf0, 0x02, 0xf3, 0xf3, 0x91, 0x4f, 0xbf, 0x4e, 0xee, 0xe8, 0xc6, - 0x18, 0x39, 0xe0, 0x81, 0xfe, 0xe8, 0xe7, 0x9c, 0xc4, 0x7d, 0xcf, 0x82, - 0x72, 0xa4, 0x87, 0x84, 0x2b, 0x96, 0xe3, 0xd9, 0x7e, 0x43, 0xbb, 0x56, - 0xc9, 0xf1, 0xc2, 0x2d, 0x3c, 0x7f, 0xb3, 0xdf, 0x38, 0x33, 0x8c, 0xc0, - 0xc4, 0x69, 0x72, 0xc3, 0xf7, 0x87, 0x24, 0x86, 0x1d, 0xa4, 0x8f, 0xfb, - 0x11, 0x4e, 0x6a, 0x38, 0x34, 0x66, 0x60, 0x7e, 0xd2, 0x8b, 0x47, 0xc6, - 0x82, 0xf8, 0x0c, 0x7d, 0x37, 0x43, 0x7e, 0xf8, 0xe9, 0xa4, 0xf8, 0xe2, - 0x2c, 0x8c, 0x8f, 0xcd, 0xb2, 0xf7, 0x54, 0x7a, 0x8c, 0x5f, 0xc0, 0x53, - 0x2d, 0x3e, 0x49, 0x6e, 0x9d, 0xd2, 0x7b, 0x63, 0x1c, 0x4f, 0xcc, 0xab, - 0xef, 0x8f, 0x41, 0x1f, 0x02, 0xae, 0xf8, 0x70, 0xe8, 0x8b, 0x12, 0x1f, - 0xc5, 0x1f, 0x35, 0x8c, 0x93, 0xef, 0x14, 0x13, 0x53, 0x4b, 0x23, 0xb5, - 0xef, 0xbd, 0xac, 0xe8, 0xd9, 0xa7, 0x55, 0xcb, 0x7a, 0x69, 0xa1, 0x06, - 0xdf, 0x3e, 0x8d, 0xdc, 0xc3, 0x64, 0xec, 0x16, 0x3f, 0xd5, 0x30, 0xe3, - 0x81, 0x6a, 0x4c, 0x7b, 0x20, 0x89, 0xbf, 0xad, 0x8e, 0x7f, 0x6e, 0x3a, - 0xe3, 0xfc, 0x74, 0xe2, 0x7a, 0x65, 0xf2, 0xd8, 0x0c, 0x37, 0xf9, 0xf2, - 0x84, 0x5a, 0xd7, 0xba, 0x1f, 0xfa, 0xfe, 0x93, 0x8a, 0xee, 0x7b, 0x8c, - 0xb1, 0xc1, 0x45, 0x1b, 0x75, 0x8c, 0x6b, 0xf4, 0xdd, 0xba, 0x43, 0xd3, - 0x60, 0xc4, 0x2f, 0x57, 0x5d, 0x16, 0x6c, 0x79, 0xae, 0xa8, 0xcc, 0xe5, - 0x45, 0x82, 0x3b, 0x12, 0x17, 0x1c, 0xb2, 0xff, 0x13, 0xed, 0xf4, 0x97, - 0x15, 0x76, 0x2c, 0x3a, 0x60, 0xef, 0x8f, 0xdb, 0x30, 0x1e, 0xa7, 0x8f, - 0x2c, 0x46, 0xd9, 0x80, 0x07, 0x5f, 0xb3, 0xe3, 0xd0, 0x43, 0x56, 0x15, - 0xfd, 0xe5, 0xf6, 0x3d, 0x81, 0xf6, 0xab, 0xe9, 0x2f, 0xb5, 0x97, 0x49, - 0x0c, 0x63, 0xdc, 0x4e, 0x19, 0xe6, 0x30, 0xb1, 0xe5, 0xa1, 0x06, 0x63, - 0xe2, 0x75, 0xe4, 0x7c, 0x66, 0x6b, 0x5f, 0x35, 0xfe, 0xe1, 0xfe, 0xfd, - 0xf6, 0x5a, 0xc8, 0x6d, 0x3c, 0x4f, 0xf6, 0xf9, 0x6c, 0xff, 0x88, 0xf1, - 0xf7, 0x9d, 0x8c, 0x79, 0x31, 0xfa, 0xd1, 0x96, 0x3e, 0x6b, 0xf1, 0xf7, - 0x17, 0xc6, 0x57, 0x56, 0x20, 0xc8, 0x98, 0xe4, 0x46, 0x6f, 0x9f, 0xde, - 0xdf, 0xca, 0x18, 0x74, 0x62, 0xa1, 0x49, 0x59, 0x3c, 0xd8, 0xd1, 0x27, - 0x98, 0x7a, 0xf4, 0xa6, 0x6a, 0xc4, 0xff, 0xa7, 0xc6, 0xf1, 0x7d, 0xcd, - 0x7e, 0xf6, 0x37, 0x0b, 0x6b, 0xf7, 0x5d, 0x46, 0x99, 0xeb, 0xe9, 0x83, - 0xcc, 0xab, 0x99, 0xef, 0xac, 0xde, 0x25, 0x7e, 0x81, 0x46, 0xc9, 0xd3, - 0x3a, 0xcd, 0x80, 0xf9, 0x06, 0x7d, 0xa8, 0x88, 0x5c, 0xe7, 0x41, 0x62, - 0x59, 0x31, 0x21, 0xb3, 0xcc, 0x08, 0x63, 0x21, 0x6d, 0x54, 0xde, 0xe1, - 0x98, 0x46, 0x5e, 0x37, 0x9f, 0xf3, 0x51, 0x92, 0xf1, 0x00, 0xe4, 0x10, - 0x20, 0x3e, 0x61, 0x94, 0x20, 0x38, 0xea, 0xe7, 0x71, 0x31, 0x0f, 0x2a, - 0x22, 0xa3, 0xa2, 0x66, 0x94, 0x75, 0x87, 0x47, 0x6c, 0x5b, 0xfc, 0x07, - 0xce, 0x7b, 0x82, 0xb6, 0x7e, 0x23, 0xb1, 0x7e, 0x62, 0x27, 0xd0, 0xfb, - 0x70, 0xce, 0xb6, 0x53, 0x6c, 0xbf, 0x85, 0x98, 0xf7, 0x1e, 0x6d, 0xb6, - 0x87, 0xf3, 0xbd, 0x63, 0xd0, 0x08, 0xd6, 0xa9, 0x01, 0x6d, 0x9c, 0xf3, - 0xdc, 0x35, 0xa2, 0xa2, 0xaf, 0x7f, 0x31, 0x86, 0x99, 0x07, 0x75, 0x0f, - 0x89, 0x8f, 0x48, 0x99, 0xc3, 0xe8, 0xa4, 0x8f, 0xfc, 0x6a, 0xa1, 0x82, - 0xd8, 0x17, 0xe4, 0x1d, 0x51, 0x27, 0xf3, 0xfd, 0xfb, 0xb0, 0x36, 0x71, - 0xc4, 0x2a, 0x37, 0xf4, 0xde, 0x21, 0x95, 0x79, 0x16, 0x6d, 0xb3, 0x8b, - 0xf9, 0xc9, 0x12, 0xe6, 0x27, 0xdd, 0x79, 0xbb, 0x3c, 0x4e, 0x3b, 0xec, - 0x63, 0x1c, 0x7b, 0x7d, 0x28, 0x17, 0xf7, 0x7e, 0xbc, 0xc3, 0x8f, 0xf9, - 0x97, 0x97, 0xe3, 0x99, 0x87, 0x73, 0xb2, 0xed, 0xa4, 0x4d, 0x3e, 0x4d, - 0x3d, 0xdf, 0x4a, 0xbd, 0xbe, 0x92, 0x12, 0x8c, 0x0a, 0xe2, 0x59, 0xf2, - 0xe8, 0xf5, 0xe4, 0x02, 0x2f, 0xa5, 0x72, 0x36, 0xf9, 0xf5, 0xf1, 0x2b, - 0xab, 0x72, 0xf1, 0xc1, 0x0b, 0xf5, 0x01, 0x79, 0x27, 0xcf, 0xb2, 0x96, - 0x98, 0xd9, 0x76, 0xf2, 0x1a, 0xb6, 0x1d, 0x21, 0x37, 0x72, 0x62, 0x66, - 0x32, 0x82, 0xa5, 0xa9, 0xda, 0xe6, 0xb9, 0xb2, 0x89, 0x63, 0x66, 0x8e, - 0x03, 0xba, 0x92, 0xf2, 0xcd, 0x0f, 0x0d, 0x65, 0xcc, 0x9d, 0xfe, 0x26, - 0xff, 0x9d, 0x91, 0x1b, 0xff, 0x0c, 0xee, 0xb8, 0x82, 0x32, 0xa5, 0xc8, - 0x1d, 0x27, 0xf3, 0xdf, 0x19, 0xb9, 0xc1, 0xfe, 0xce, 0x88, 0x1b, 0xd3, - 0xc6, 0x9d, 0xce, 0x2f, 0xa5, 0x3c, 0x98, 0x31, 0x7e, 0x96, 0x83, 0xba, - 0x8b, 0x22, 0x4d, 0x78, 0x2a, 0xa1, 0x60, 0xba, 0xf1, 0xbf, 0xf1, 0xb2, - 0xbd, 0x26, 0x50, 0x8d, 0x99, 0x0f, 0xc8, 0x7a, 0x42, 0x54, 0xde, 0x89, - 0x69, 0x7e, 0x82, 0xe7, 0x25, 0xc4, 0xd3, 0x8a, 0x07, 0x14, 0x3c, 0x1d, - 0xf0, 0xa2, 0x98, 0xbf, 0x7d, 0xe4, 0x9a, 0xce, 0x85, 0xcb, 0xad, 0xcd, - 0xab, 0xc4, 0xbe, 0x39, 0x87, 0xfb, 0xa6, 0x55, 0x0a, 0x06, 0xee, 0x35, - 0x65, 0xdd, 0xd2, 0x40, 0x4f, 0xa2, 0x9a, 0xfc, 0xba, 0xb6, 0xbd, 0x09, - 0xb5, 0xe6, 0x2f, 0x1c, 0xd5, 0x28, 0xda, 0x77, 0x63, 0x95, 0xac, 0xd9, - 0x7f, 0x9b, 0x73, 0xd6, 0x4d, 0xec, 0xea, 0x4a, 0xe5, 0xe2, 0x67, 0x53, - 0xfa, 0x17, 0x9a, 0xe8, 0xa5, 0x9b, 0xfc, 0x44, 0x4d, 0x9e, 0xb2, 0xcb, - 0x94, 0x45, 0x0e, 0x11, 0x7f, 0x66, 0xe1, 0x10, 0xf3, 0x1a, 0x89, 0xa5, - 0x65, 0x3c, 0xca, 0xc9, 0x1b, 0x7f, 0xc9, 0x58, 0x7a, 0x67, 0x28, 0x1b, - 0x94, 0x2f, 0xd0, 0x54, 0x91, 0x8b, 0xd3, 0x07, 0xb0, 0x2f, 0xa4, 0xb7, - 0xac, 0x76, 0x44, 0x9f, 0x61, 0x0e, 0x16, 0x5e, 0xcc, 0x9c, 0x7c, 0x79, - 0x60, 0x04, 0x5b, 0xc9, 0x03, 0xb7, 0x30, 0x17, 0x6f, 0xa5, 0x6d, 0xb6, - 0xef, 0x62, 0x6c, 0x73, 0x9c, 0xcb, 0xc5, 0xb5, 0x50, 0x7c, 0x35, 0x39, - 0x40, 0x87, 0x47, 0x15, 0x7b, 0x15, 0xdf, 0x09, 0xb4, 0xbe, 0x41, 0x8c, - 0xae, 0x63, 0xdc, 0x10, 0x7b, 0xdf, 0x9e, 0xd2, 0xdb, 0xa9, 0x80, 0xaa, - 0x72, 0xe6, 0x8e, 0x77, 0x8d, 0x35, 0xd0, 0x6f, 0xac, 0x4e, 0x37, 0xed, - 0xda, 0xb9, 0x68, 0x16, 0x73, 0xce, 0xab, 0xd0, 0xbd, 0x83, 0xf6, 0x4f, - 0x5f, 0xba, 0xb7, 0x0f, 0xe4, 0x67, 0xea, 0x16, 0xce, 0x5f, 0x76, 0x1f, - 0x02, 0x67, 0x5a, 0x50, 0xd7, 0x5c, 0xe4, 0x10, 0x19, 0xf4, 0x96, 0xb7, - 0xc9, 0xd3, 0x3a, 0x98, 0x9f, 0xae, 0x67, 0x2e, 0x1f, 0x63, 0x2e, 0x1f, - 0x63, 0xbd, 0xd4, 0x0e, 0x79, 0x4e, 0x64, 0xb4, 0x1c, 0x67, 0xfe, 0xf3, - 0x35, 0xf2, 0x9f, 0x1d, 0xf7, 0x8b, 0x5c, 0xd3, 0x71, 0xd7, 0xde, 0xab, - 0x90, 0xa4, 0x3d, 0xdd, 0xc9, 0x6b, 0x7d, 0xf7, 0x5f, 0x8c, 0x3b, 0x98, - 0xc7, 0xc7, 0xc6, 0x16, 0xa3, 0x9f, 0x99, 0xe8, 0xc6, 0xbd, 0x9f, 0x45, - 0x17, 0xf9, 0xd4, 0x12, 0x62, 0xf4, 0xea, 0x87, 0x47, 0x6c, 0xcc, 0x16, - 0xcc, 0x7f, 0x2d, 0x0d, 0xbc, 0x49, 0x4e, 0xd6, 0x9f, 0x3a, 0x60, 0xf3, - 0x34, 0x17, 0xe3, 0x43, 0x31, 0x71, 0x29, 0xbc, 0xcb, 0xe8, 0x58, 0xa6, - 0x5a, 0x8b, 0x4b, 0x16, 0x06, 0x7a, 0xdf, 0xa6, 0xaf, 0x56, 0xed, 0x53, - 0x51, 0x3d, 0x20, 0xb9, 0x3a, 0xf9, 0x11, 0x31, 0xfa, 0x05, 0x62, 0x74, - 0xf9, 0x9e, 0x5c, 0x5e, 0x9e, 0x60, 0xde, 0x55, 0x6d, 0xe4, 0x72, 0xf3, - 0xed, 0x7d, 0xb2, 0xf7, 0xc6, 0x8d, 0xe7, 0x68, 0xfb, 0x47, 0xf3, 0xb6, - 0x7f, 0x2c, 0x8f, 0xc1, 0x16, 0x73, 0xf3, 0x37, 0x6d, 0xfc, 0xcd, 0xe5, - 0xe6, 0xf3, 0x07, 0x8c, 0x8e, 0x30, 0x31, 0xfa, 0x33, 0x7b, 0xa4, 0x7f, - 0x0d, 0xd5, 0xc4, 0x93, 0x1a, 0x62, 0x49, 0xc5, 0x80, 0xac, 0xcf, 0x04, - 0xda, 0xc7, 0x55, 0x9f, 0xdd, 0xc7, 0x26, 0xca, 0xd6, 0x9d, 0x92, 0x77, - 0x6c, 0x0d, 0x6d, 0x83, 0x12, 0x30, 0xaf, 0xa1, 0x3e, 0xf7, 0xa5, 0xaf, - 0x42, 0x7b, 0xff, 0x2c, 0xec, 0x1f, 0x92, 0xf8, 0x22, 0xed, 0x4b, 0x2e, - 0xee, 0xc4, 0xfb, 0xbb, 0x66, 0xe3, 0xfd, 0x91, 0x73, 0x79, 0xf8, 0xe6, - 0x54, 0xf4, 0x5e, 0x86, 0xd7, 0xe5, 0x92, 0x87, 0xbf, 0xc4, 0x3c, 0xfc, - 0x6d, 0x45, 0xd6, 0x10, 0x55, 0xdc, 0xb8, 0xc0, 0xc1, 0xf8, 0xa2, 0xfb, - 0x5f, 0x74, 0xc4, 0xe5, 0x39, 0xb2, 0xff, 0x7e, 0xde, 0x7f, 0x9e, 0xf1, - 0x7c, 0x80, 0x33, 0x11, 0xad, 0x76, 0xe0, 0x99, 0x85, 0xf1, 0xa8, 0x8b, - 0xd7, 0x7b, 0xc9, 0x53, 0x66, 0x1a, 0x07, 0xe9, 0x9b, 0xb5, 0xe1, 0xf9, - 0x0e, 0x07, 0xce, 0x98, 0x7a, 0xcb, 0x6e, 0x5e, 0x7b, 0x36, 0x23, 0xbe, - 0x18, 0x26, 0x7e, 0x2d, 0xca, 0xfb, 0xa2, 0xbc, 0x8f, 0x01, 0xf7, 0x6c, - 0xda, 0xeb, 0x6b, 0x29, 0xbd, 0xff, 0x59, 0xda, 0x69, 0xf5, 0x59, 0x3b, - 0x2d, 0xec, 0xd3, 0x82, 0xbb, 0x2a, 0xd2, 0x82, 0x50, 0xb2, 0xb0, 0x5f, - 0x6b, 0x3f, 0x7a, 0x32, 0xf7, 0x60, 0xe3, 0x4e, 0x7d, 0xa3, 0xac, 0x11, - 0xbd, 0x10, 0x8a, 0x5b, 0x95, 0x46, 0x27, 0x5c, 0x0b, 0x8c, 0x16, 0xe6, - 0x2f, 0xb1, 0xef, 0x2a, 0xa5, 0xb4, 0xdf, 0xc3, 0xd8, 0x34, 0xac, 0x07, - 0xb7, 0x2b, 0x06, 0xe3, 0x86, 0x86, 0xfd, 0x83, 0x45, 0xb8, 0x75, 0x57, - 0x1b, 0xf6, 0xf5, 0x9b, 0xc4, 0xcf, 0x5a, 0xff, 0x69, 0xbc, 0x87, 0x63, - 0xa6, 0xbc, 0xaf, 0x54, 0x82, 0x36, 0x4d, 0xf6, 0x29, 0x31, 0xfb, 0x9c, - 0x7e, 0xde, 0x3b, 0xe0, 0x9e, 0x12, 0xa3, 0xf0, 0x2e, 0xbf, 0xc1, 0x7c, - 0x71, 0x12, 0x7b, 0x06, 0x65, 0x6d, 0x60, 0x9a, 0x72, 0xa4, 0x7f, 0xae, - 0xaf, 0x8b, 0xd8, 0x7f, 0xaf, 0x99, 0xc5, 0x99, 0x85, 0xd5, 0xc0, 0x0c, - 0x05, 0xa1, 0xcf, 0x04, 0xe4, 0x5b, 0x35, 0xfc, 0x7b, 0xd7, 0xf2, 0x7f, - 0x51, 0xda, 0xa9, 0xa9, 0xc8, 0xad, 0x17, 0xbc, 0x5e, 0x2d, 0xef, 0xf2, - 0x1d, 0x49, 0xcd, 0xac, 0xcc, 0x3d, 0x77, 0xfe, 0xa4, 0x3e, 0x5e, 0xb3, - 0xfc, 0x76, 0x1b, 0x85, 0xba, 0xaf, 0x5a, 0x51, 0xaf, 0x94, 0x2f, 0x62, - 0xdb, 0xe2, 0x9f, 0xd3, 0x94, 0x76, 0xe2, 0xa9, 0x1a, 0x9a, 0xa6, 0xb4, - 0x0d, 0x5d, 0xd8, 0xee, 0x8b, 0x56, 0xb4, 0x45, 0xce, 0x0b, 0xe5, 0xdc, - 0xd3, 0x50, 0x2a, 0x65, 0x0b, 0xf7, 0x9f, 0xc9, 0xb7, 0x55, 0x4c, 0xae, - 0x9a, 0x2b, 0x73, 0x6b, 0xbf, 0xec, 0xad, 0x8a, 0xe2, 0x68, 0xc3, 0xd4, - 0xf6, 0x0a, 0x7d, 0x7f, 0xef, 0xbc, 0xf6, 0x72, 0x65, 0x67, 0xb1, 0x4d, - 0x29, 0x9f, 0xc5, 0xff, 0x6b, 0xaf, 0x23, 0xbc, 0x61, 0xef, 0x93, 0xdc, - 0x6a, 0x36, 0x46, 0x4b, 0xf0, 0x39, 0xa8, 0x97, 0xc6, 0xe7, 0x97, 0xd8, - 0xfc, 0x36, 0xda, 0x52, 0xc2, 0x1c, 0xd7, 0x6d, 0x44, 0xef, 0x75, 0x23, - 0x9b, 0x65, 0x5c, 0x6e, 0x3d, 0xa3, 0xec, 0x57, 0x6e, 0x0d, 0xe8, 0x1b, - 0xdf, 0x25, 0xdf, 0x78, 0x3e, 0x10, 0x27, 0xd6, 0x1b, 0xbe, 0x3e, 0x45, - 0x37, 0xd7, 0x32, 0xa6, 0x3d, 0xcb, 0x1c, 0x72, 0x4d, 0xa0, 0xd7, 0x7e, - 0xc6, 0xa8, 0x44, 0x56, 0xe0, 0x12, 0xfb, 0xbb, 0x2c, 0x2d, 0x30, 0xd2, - 0xcf, 0xcb, 0x9a, 0x17, 0x7f, 0xc7, 0x30, 0xdf, 0xbe, 0xb6, 0x06, 0x41, - 0xfb, 0xff, 0xaa, 0xfc, 0xb7, 0x5b, 0x5a, 0x51, 0x6b, 0xff, 0xbf, 0x19, - 0x73, 0xd3, 0x67, 0xd7, 0x86, 0xd1, 0x6d, 0x5a, 0xd6, 0x53, 0xa6, 0x85, - 0x37, 0xce, 0xed, 0xd1, 0x5e, 0xe1, 0x60, 0xce, 0x41, 0x17, 0x8e, 0xe5, - 0xbe, 0x5d, 0x75, 0xee, 0xfd, 0x8c, 0xa5, 0xe7, 0xed, 0xd1, 0x96, 0xf7, - 0xe2, 0xab, 0xed, 0x6f, 0x93, 0xcd, 0x5b, 0xe4, 0xc4, 0x73, 0x89, 0x8a, - 0x98, 0x87, 0xbf, 0x37, 0x2d, 0x2a, 0xc2, 0xfa, 0x10, 0x39, 0xdf, 0xa5, - 0xc7, 0x71, 0xda, 0xfe, 0x46, 0x43, 0x3c, 0x24, 0xdf, 0x66, 0x38, 0x9a, - 0x50, 0x71, 0x6c, 0xb0, 0x27, 0xb4, 0xc7, 0xee, 0xfb, 0x55, 0x74, 0x8f, - 0xca, 0x73, 0xbf, 0x16, 0xac, 0x4e, 0x4c, 0xda, 0x7b, 0xda, 0x36, 0xa7, - 0x24, 0xf7, 0xd6, 0xb3, 0x6b, 0x98, 0xaf, 0xaa, 0x8e, 0x20, 0x6e, 0x62, - 0x7c, 0x79, 0x21, 0x41, 0x3b, 0x5d, 0xa8, 0x77, 0x7c, 0x97, 0x1c, 0xa1, - 0x22, 0xa2, 0x07, 0xdf, 0x51, 0x5a, 0xc9, 0xc5, 0xdc, 0x98, 0x48, 0x88, - 0x2d, 0xca, 0xb7, 0x9d, 0x6e, 0xc6, 0x7e, 0x72, 0xd2, 0xe7, 0x13, 0x1a, - 0x4e, 0x37, 0x78, 0x90, 0x26, 0x47, 0x7d, 0x2e, 0xe1, 0xc6, 0x63, 0xe4, - 0xa8, 0x8f, 0x0e, 0xca, 0x1a, 0x61, 0x13, 0x1a, 0x13, 0xb2, 0x3e, 0x4c, - 0xde, 0x35, 0xe2, 0xa5, 0x3d, 0x5a, 0x56, 0x37, 0x6d, 0xb7, 0x4d, 0x9b, - 0x60, 0x9f, 0xb2, 0xae, 0x18, 0xc5, 0x35, 0xe4, 0x1d, 0x8f, 0x8e, 0xf8, - 0xf0, 0x7d, 0x72, 0xf3, 0x24, 0xeb, 0xbd, 0x90, 0xf0, 0xa3, 0x2f, 0xed, - 0xc3, 0xd3, 0xe4, 0xe8, 0x5b, 0x78, 0x2e, 0xdf, 0x09, 0x2b, 0x32, 0x82, - 0xe4, 0xc1, 0x87, 0x51, 0xd6, 0x77, 0x11, 0xd6, 0xad, 0x3c, 0x08, 0xb5, - 0xef, 0x10, 0x8f, 0x2b, 0x19, 0xb3, 0xaf, 0x44, 0x6a, 0x30, 0x82, 0xd4, - 0xc8, 0x8f, 0xd0, 0x3b, 0x28, 0xe3, 0x92, 0xef, 0x3d, 0xc9, 0xbe, 0x27, - 0x72, 0xbd, 0x3e, 0x2f, 0x86, 0x46, 0xa4, 0x9f, 0x6a, 0xf6, 0xfd, 0xe7, - 0xb6, 0xff, 0x1f, 0xd6, 0xba, 0x1b, 0xa5, 0xed, 0x83, 0x9f, 0xd0, 0xbe, - 0xe8, 0xaa, 0xf0, 0x9e, 0xa1, 0xac, 0x75, 0xb8, 0xd9, 0xa6, 0x07, 0x8e, - 0x48, 0x76, 0x65, 0x39, 0xf4, 0xe8, 0x36, 0xc5, 0x68, 0x2e, 0x53, 0x26, - 0xb1, 0x2d, 0x23, 0xef, 0x8d, 0x15, 0xe3, 0x69, 0xe2, 0xa3, 0x2b, 0xa4, - 0x6b, 0xdf, 0xa5, 0xed, 0x2c, 0x21, 0xa6, 0xbc, 0x61, 0x7e, 0x06, 0x71, - 0x4d, 0xf4, 0x57, 0x8c, 0x1f, 0xf4, 0xbb, 0xf1, 0x4e, 0x28, 0x82, 0xdc, - 0xb7, 0xbd, 0x3c, 0xf8, 0x71, 0xc2, 0xcb, 0xf9, 0xaa, 0xcb, 0x1a, 0x8e, - 0xb9, 0xc0, 0xb4, 0xdc, 0xb5, 0xa3, 0x89, 0x35, 0xd8, 0x43, 0x79, 0x5f, - 0x48, 0x9c, 0xe1, 0xfc, 0xb4, 0x53, 0xff, 0xa2, 0xef, 0x78, 0x5e, 0xd7, - 0x3d, 0xd4, 0xf5, 0x2c, 0x3c, 0x9b, 0xb8, 0x0f, 0x8f, 0x52, 0xfe, 0x47, - 0xfa, 0x8d, 0xe8, 0xc5, 0xca, 0x61, 0xe2, 0x65, 0x31, 0x8e, 0xb1, 0xed, - 0x5b, 0x99, 0x29, 0x4f, 0x4a, 0x5f, 0x29, 0x59, 0x9f, 0x54, 0xf0, 0xce, - 0xa2, 0xc3, 0x18, 0xe7, 0xbd, 0x1f, 0xf3, 0x77, 0x78, 0x61, 0x25, 0xfb, - 0x10, 0xfd, 0xf8, 0xed, 0x5c, 0xa0, 0x8b, 0x3c, 0x67, 0x79, 0xc3, 0x61, - 0x6c, 0x1d, 0x92, 0x6b, 0x6d, 0xe8, 0xed, 0x7f, 0x0f, 0x8e, 0x10, 0x71, - 0xc8, 0xdb, 0x40, 0x5b, 0xcf, 0x62, 0x5b, 0xfa, 0xc3, 0x69, 0x39, 0x0e, - 0xfa, 0xca, 0x34, 0xd9, 0x8b, 0x7c, 0x34, 0x51, 0x8c, 0xe7, 0x58, 0x67, - 0x5d, 0xc8, 0x95, 0x7f, 0x66, 0x72, 0x98, 0xfc, 0xc9, 0x89, 0x34, 0xfb, - 0x48, 0xd8, 0x6d, 0x4c, 0x53, 0x76, 0xd3, 0x0f, 0x2b, 0x17, 0x4e, 0x53, - 0x52, 0x43, 0xc2, 0xed, 0x7f, 0x84, 0x27, 0xef, 0xcf, 0xe9, 0x70, 0x8f, - 0xb9, 0x06, 0x43, 0xe9, 0x1f, 0x17, 0xda, 0x9b, 0xf2, 0x2e, 0x9c, 0xbc, - 0x9f, 0x53, 0x78, 0x57, 0x27, 0xf7, 0x4c, 0xeb, 0xdb, 0x99, 0x0a, 0xf2, - 0xe7, 0x52, 0xda, 0x5a, 0x51, 0xcc, 0xcb, 0xb8, 0xba, 0x66, 0x81, 0x86, - 0x9d, 0x97, 0xd5, 0x4d, 0x43, 0x85, 0xe6, 0xfc, 0x75, 0xc3, 0xf3, 0xec, - 0xa7, 0x22, 0x56, 0x15, 0xd9, 0x63, 0xef, 0x83, 0x0a, 0x5d, 0x56, 0xc3, - 0xb8, 0x22, 0xcf, 0x86, 0x63, 0x78, 0x2b, 0x51, 0x1d, 0xab, 0x8e, 0x54, - 0x12, 0x6f, 0x4f, 0xa3, 0x6f, 0xd8, 0x89, 0x0a, 0xf2, 0xe6, 0xf2, 0x64, - 0x35, 0xdc, 0xf6, 0x3a, 0xde, 0x45, 0xe4, 0x2b, 0xb3, 0xc9, 0x49, 0x66, - 0xa1, 0x92, 0xbc, 0xc4, 0x13, 0xb2, 0xac, 0x9f, 0x2d, 0xb4, 0xac, 0x4b, - 0x78, 0x94, 0xf0, 0x38, 0x15, 0x12, 0x3f, 0x8d, 0xa2, 0xce, 0xf6, 0x57, - 0x03, 0xf5, 0xf6, 0xff, 0x26, 0xfa, 0x7a, 0x47, 0x68, 0xfe, 0xf8, 0x7d, - 0xa1, 0xb9, 0xe3, 0x35, 0x50, 0x07, 0xa6, 0xc3, 0xc1, 0xb6, 0xbe, 0x70, - 0x99, 0x85, 0x26, 0xfa, 0xf0, 0x5a, 0x53, 0x78, 0xd1, 0x1a, 0xf2, 0xa2, - 0xde, 0x90, 0x31, 0x7e, 0x10, 0x57, 0x33, 0xce, 0xb9, 0x07, 0x7c, 0xec, - 0x47, 0x72, 0x6c, 0x67, 0x76, 0x0e, 0xf9, 0xf6, 0x67, 0x16, 0x0a, 0x47, - 0x6a, 0x25, 0x47, 0x3a, 0x84, 0xd6, 0xf1, 0xc3, 0xb8, 0x9e, 0x65, 0x3c, - 0xe4, 0x2a, 0xc9, 0xcc, 0x8f, 0xd0, 0x97, 0xb1, 0xb0, 0x3d, 0x94, 0xc5, - 0xb5, 0x6c, 0xbb, 0x74, 0xa0, 0x99, 0xdc, 0x70, 0x05, 0xd6, 0x8d, 0xcb, - 0xbb, 0x52, 0x13, 0x58, 0x3e, 0x4e, 0xce, 0x39, 0x5e, 0xf0, 0x57, 0xe1, - 0x4b, 0x2b, 0xc8, 0x97, 0x64, 0x2d, 0x6d, 0x95, 0xbd, 0x96, 0xa6, 0xd2, - 0x0f, 0x1b, 0x13, 0xf2, 0x9e, 0x50, 0x1c, 0xab, 0xc7, 0x05, 0xab, 0xef, - 0x41, 0xf7, 0xb8, 0xac, 0xcd, 0x7e, 0x33, 0x74, 0xf1, 0xf8, 0xab, 0x68, - 0x1c, 0x1f, 0x0a, 0xcd, 0x1b, 0x1f, 0xa1, 0xdc, 0x09, 0xca, 0xd6, 0x1f, - 0xaa, 0x1d, 0x1f, 0x0c, 0x05, 0xc7, 0x77, 0x87, 0x02, 0xe3, 0x2d, 0xd8, - 0x32, 0xbe, 0x0a, 0x9b, 0xc7, 0x37, 0x62, 0xd3, 0xb8, 0xe0, 0xfc, 0x24, - 0x96, 0x8d, 0xbf, 0x81, 0xa5, 0xe3, 0xcf, 0xa3, 0x69, 0xfc, 0x04, 0x96, - 0x8c, 0xff, 0x08, 0xcd, 0xe3, 0xaf, 0x70, 0x2c, 0xb2, 0xd6, 0x2b, 0xeb, - 0xbc, 0x85, 0xe7, 0x6a, 0x53, 0xf7, 0x24, 0xcb, 0x5a, 0x86, 0x7c, 0xbf, - 0x43, 0xe6, 0xd0, 0x85, 0x95, 0xda, 0x6b, 0xe8, 0xd9, 0x25, 0xdf, 0x24, - 0xac, 0xd3, 0xba, 0xe5, 0xf9, 0xa3, 0xf7, 0x79, 0xd9, 0x63, 0x4f, 0x1b, - 0x3b, 0xff, 0xbd, 0xbc, 0xc9, 0xb3, 0xcf, 0x18, 0xe5, 0x1b, 0x18, 0xf2, - 0xec, 0x73, 0x12, 0x5d, 0x99, 0xdf, 0x5a, 0x51, 0x4d, 0xca, 0xca, 0xf7, - 0x3f, 0xc4, 0x1e, 0x5e, 0xc3, 0x43, 0xbb, 0x26, 0xc9, 0x59, 0xb2, 0xf6, - 0x5a, 0xcd, 0xbb, 0xf3, 0xe4, 0x9b, 0x56, 0xf2, 0xce, 0xfe, 0x6b, 0x48, - 0x8d, 0x02, 0xe3, 0x0f, 0x8b, 0x1f, 0xae, 0xa1, 0x1f, 0x66, 0xc5, 0x27, - 0xe3, 0xc4, 0xe4, 0xaf, 0x78, 0x70, 0x0f, 0x79, 0x49, 0x11, 0xb2, 0x23, - 0xa5, 0x78, 0x66, 0x30, 0x6e, 0xcd, 0x31, 0x3c, 0x28, 0x8f, 0x18, 0xd9, - 0x4b, 0x18, 0x67, 0x5f, 0xe1, 0xb5, 0x89, 0x7e, 0xf8, 0x7d, 0x46, 0xc0, - 0x37, 0x87, 0xe7, 0xc7, 0x86, 0xb2, 0xe4, 0x14, 0x1d, 0x98, 0xe4, 0x7f, - 0xc9, 0x41, 0x81, 0x6e, 0x0c, 0x0d, 0x89, 0x3e, 0x5b, 0xa8, 0x4f, 0xc1, - 0x45, 0xbd, 0xa3, 0x89, 0x78, 0x68, 0x29, 0x82, 0x87, 0x2a, 0xca, 0x1e, - 0xe8, 0xa4, 0xbf, 0xea, 0xb1, 0x9f, 0x30, 0x16, 0xf4, 0x29, 0x3f, 0xc2, - 0x73, 0xcc, 0x19, 0x4a, 0x1f, 0x20, 0xff, 0x20, 0x56, 0x56, 0x44, 0x14, - 0x63, 0x79, 0xe0, 0x14, 0x9e, 0x19, 0x71, 0xc2, 0x9d, 0x74, 0x62, 0x82, - 0x38, 0xe9, 0x48, 0xca, 0xf3, 0x7a, 0x8d, 0xb2, 0xc8, 0xba, 0xd0, 0x09, - 0x64, 0xed, 0xe7, 0x69, 0xf2, 0x3c, 0xe4, 0x45, 0xbb, 0x1f, 0x27, 0x65, - 0xef, 0x21, 0x96, 0x76, 0xa5, 0x5e, 0x42, 0xd3, 0x90, 0x07, 0x73, 0x92, - 0x13, 0xcc, 0x5f, 0x5e, 0x45, 0x6a, 0xd7, 0x2c, 0x7c, 0x95, 0x3c, 0x70, - 0x66, 0xd2, 0x84, 0x46, 0xbd, 0xdd, 0x34, 0x66, 0x22, 0xba, 0x77, 0x15, - 0x56, 0xee, 0xfd, 0x22, 0x8f, 0xe9, 0xb8, 0x7e, 0x6f, 0x3b, 0x3e, 0x3f, - 0x16, 0x47, 0xeb, 0x58, 0x0f, 0x8f, 0x36, 0x5c, 0xb7, 0xa3, 0x12, 0xe9, - 0x90, 0xc6, 0x9c, 0xba, 0x8d, 0x39, 0xb5, 0xf0, 0xa1, 0xd5, 0x78, 0x86, - 0xb8, 0x13, 0x0c, 0xad, 0xc6, 0x84, 0xed, 0x8b, 0xb2, 0x97, 0x71, 0x35, - 0x36, 0x31, 0x5f, 0x1e, 0xc6, 0x6a, 0x74, 0xf1, 0xda, 0x0e, 0x7b, 0x0e, - 0x0e, 0x63, 0x31, 0xf3, 0xa1, 0xf7, 0x2f, 0x3f, 0x8c, 0x2b, 0xf6, 0x48, - 0xdf, 0xa7, 0x91, 0xda, 0xb9, 0x86, 0x6d, 0x66, 0xd1, 0x32, 0xf6, 0x43, - 0x7c, 0x7e, 0x07, 0x6e, 0xab, 0x44, 0x25, 0x9e, 0x0f, 0x05, 0x5a, 0xfb, - 0x94, 0x1f, 0xda, 0x6d, 0x6f, 0xa2, 0x1f, 0x6f, 0x65, 0xb9, 0x47, 0xd2, - 0x27, 0xd0, 0x9b, 0x9a, 0x3a, 0xa7, 0xf6, 0x7b, 0xed, 0x8c, 0x07, 0x2f, - 0x63, 0xdf, 0xc8, 0x24, 0xb1, 0xf7, 0x24, 0x8f, 0x0b, 0x9f, 0x5f, 0x7b, - 0xed, 0x7c, 0x26, 0x67, 0x37, 0x92, 0xbf, 0xc8, 0x3a, 0x70, 0x0b, 0x7c, - 0x29, 0xe1, 0x44, 0xd9, 0xad, 0x33, 0xa1, 0x6f, 0x0c, 0xdb, 0x1c, 0xc9, - 0x88, 0x91, 0x1b, 0xb5, 0x7c, 0x57, 0xf1, 0x90, 0x1b, 0x05, 0xb1, 0x22, - 0xa3, 0x47, 0xaf, 0xa5, 0xbe, 0x4b, 0xee, 0x7f, 0x19, 0xce, 0xfb, 0x9d, - 0x28, 0x4e, 0xca, 0xda, 0xc9, 0x04, 0x7a, 0x33, 0xf2, 0xfe, 0x6e, 0x56, - 0x2f, 0x26, 0xae, 0x16, 0x25, 0xb3, 0x8c, 0xfd, 0xd9, 0xf9, 0x45, 0x90, - 0x77, 0xf1, 0xaf, 0xc2, 0x9a, 0xfe, 0x28, 0xba, 0x4c, 0x79, 0x57, 0x27, - 0x37, 0xfe, 0x39, 0x0d, 0x2f, 0xa3, 0x9b, 0xf1, 0xa7, 0x8d, 0x98, 0xf8, - 0x55, 0xfb, 0x59, 0xe8, 0xcb, 0xe8, 0x19, 0x2c, 0xbc, 0xbb, 0x2e, 0x6d, - 0x3e, 0x4f, 0xbd, 0xb9, 0xf2, 0xdf, 0xec, 0x91, 0x36, 0x75, 0xd3, 0xaf, - 0x4e, 0xcb, 0xbd, 0x8b, 0x03, 0xfb, 0x19, 0x36, 0xed, 0xe3, 0x35, 0xf4, - 0xee, 0x2a, 0x8c, 0x99, 0xb9, 0x41, 0xe0, 0x35, 0xf4, 0x8f, 0xca, 0xd8, - 0xaf, 0x9f, 0x96, 0x7b, 0xc7, 0x78, 0xaa, 0x3e, 0x0a, 0x75, 0x1d, 0xb4, - 0xe7, 0xc2, 0xfd, 0x8f, 0xfb, 0x6e, 0xd0, 0xa7, 0xec, 0x6f, 0xf0, 0xe4, - 0xbe, 0x81, 0x04, 0x3c, 0x99, 0x90, 0x77, 0xfb, 0xd5, 0xc5, 0x2e, 0xa8, - 0x5e, 0x17, 0x8a, 0x19, 0x2f, 0x6a, 0xd0, 0xed, 0xb5, 0x70, 0x35, 0xc7, - 0xb2, 0xbf, 0xfe, 0x3a, 0x66, 0x1a, 0xf1, 0x56, 0x97, 0xfd, 0xce, 0xe1, - 0x8a, 0xbf, 0xfe, 0xe8, 0x3b, 0x87, 0x6f, 0x10, 0x67, 0x15, 0x94, 0x1b, - 0x37, 0xe1, 0x05, 0x3b, 0xa6, 0x28, 0x28, 0x9b, 0x2b, 0xeb, 0x98, 0x7e, - 0x3c, 0x6b, 0xd4, 0xf9, 0xab, 0xe4, 0xf9, 0x94, 0x72, 0xca, 0x92, 0x6f, - 0x06, 0x6c, 0xcb, 0xfc, 0xb1, 0x3d, 0xf1, 0x4f, 0x61, 0xcb, 0xce, 0x30, - 0xe4, 0xfd, 0x15, 0xa7, 0xa1, 0x79, 0x73, 0xfc, 0x4a, 0x64, 0x93, 0xbd, - 0xe4, 0xb7, 0x12, 0x9c, 0xde, 0xa0, 0x9f, 0xbe, 0x21, 0x7b, 0xa6, 0xc8, - 0x99, 0xfe, 0x12, 0xc1, 0xaa, 0xc2, 0x38, 0x65, 0xaf, 0xa9, 0x92, 0x1b, - 0xab, 0x5d, 0x47, 0xca, 0x4a, 0xbd, 0x37, 0xec, 0x35, 0x5c, 0x97, 0xf1, - 0x5b, 0xeb, 0x4d, 0x6f, 0x35, 0xcb, 0x1e, 0xce, 0xdf, 0x9f, 0x14, 0x9f, - 0x33, 0xe5, 0x1b, 0x56, 0x4e, 0xbb, 0x8e, 0xe8, 0xf7, 0x5c, 0x9d, 0xee, - 0x94, 0x83, 0xb8, 0x79, 0xc2, 0xea, 0xf4, 0xca, 0x18, 0xee, 0xbc, 0xa0, - 0x8e, 0xac, 0x2b, 0x68, 0xd2, 0x6f, 0x58, 0xc6, 0xdc, 0x95, 0xf9, 0x68, - 0x9f, 0xb2, 0xde, 0x5b, 0x64, 0x94, 0xe1, 0x54, 0x55, 0x6e, 0x1d, 0xe6, - 0x9c, 0x8c, 0x3d, 0x35, 0xb2, 0x4f, 0xaf, 0xd8, 0x3e, 0xb7, 0xfb, 0x35, - 0xcf, 0xd5, 0xfb, 0xbb, 0xfc, 0x78, 0xab, 0xed, 0x77, 0x86, 0x1e, 0xb4, - 0x79, 0x91, 0x63, 0xca, 0xb8, 0x4b, 0x6a, 0xce, 0xef, 0xe7, 0x2b, 0xf9, - 0x7e, 0x45, 0x1e, 0xef, 0x94, 0x3e, 0x44, 0xae, 0x87, 0xf3, 0x75, 0xf4, - 0x70, 0xd4, 0xee, 0x5f, 0x65, 0xbe, 0x55, 0xe8, 0x93, 0xfe, 0xb8, 0xb0, - 0xd0, 0x46, 0x56, 0xec, 0xb3, 0xb3, 0x98, 0xb1, 0xed, 0x54, 0xc3, 0x3d, - 0xd8, 0x94, 0x10, 0x3d, 0xcb, 0xb7, 0x60, 0x89, 0xe1, 0x36, 0x57, 0x73, - 0xd1, 0x5f, 0x2f, 0xc3, 0x90, 0x16, 0xc7, 0x9e, 0x7a, 0x79, 0x47, 0xce, - 0x45, 0x9f, 0x88, 0xa3, 0xc4, 0x28, 0x96, 0xfd, 0xc7, 0xf6, 0x1e, 0x94, - 0x7d, 0xa6, 0x1e, 0x7d, 0x52, 0xbe, 0x55, 0x76, 0xa9, 0xbd, 0x5e, 0xd5, - 0x3c, 0x04, 0xb9, 0x6e, 0xe2, 0xda, 0xf3, 0xf2, 0xfe, 0x12, 0xda, 0x8e, - 0xbd, 0x27, 0xda, 0x94, 0x77, 0xe8, 0xfa, 0x12, 0xf2, 0x2e, 0x57, 0x5d, - 0x8c, 0xfc, 0x12, 0x2f, 0xa4, 0x65, 0xbf, 0xc2, 0xef, 0xac, 0x78, 0x8d, - 0xec, 0x8b, 0x9c, 0x5a, 0xa7, 0x88, 0xb8, 0x16, 0x08, 0x57, 0x28, 0x85, - 0xf7, 0xb9, 0xce, 0xfd, 0x5d, 0x4f, 0x9b, 0x39, 0x6d, 0xbf, 0x83, 0x27, - 0x67, 0x11, 0x34, 0xa6, 0xe4, 0x9b, 0xa7, 0xfa, 0xc4, 0x72, 0xd4, 0x65, - 0x6b, 0x1d, 0xce, 0x3c, 0x7f, 0x09, 0x63, 0x05, 0xed, 0x66, 0x73, 0x20, - 0x6c, 0xbf, 0x6b, 0xb6, 0x2c, 0x55, 0x1b, 0x7c, 0x04, 0x7a, 0xfb, 0xdb, - 0x2c, 0x7f, 0x5d, 0xe6, 0xfb, 0xd6, 0x90, 0x57, 0xc6, 0x54, 0xc0, 0x88, - 0x13, 0xf4, 0x0d, 0xea, 0x31, 0x22, 0xfe, 0xe1, 0x41, 0x55, 0x24, 0x4c, - 0x3f, 0x96, 0xf8, 0x2f, 0xef, 0xa9, 0xe9, 0xbb, 0xe3, 0x30, 0xd1, 0xc8, - 0x1c, 0xdd, 0x65, 0xef, 0x73, 0xd6, 0xfd, 0x2b, 0x19, 0x87, 0x8e, 0x9c, - 0xdd, 0x13, 0x20, 0x7c, 0xe1, 0xc7, 0x35, 0xf9, 0xbd, 0xd0, 0xee, 0x39, - 0x8c, 0x8f, 0x96, 0xfd, 0x9c, 0x7f, 0x8d, 0x8d, 0x2d, 0x9a, 0xa1, 0xef, - 0xff, 0x95, 0xa3, 0x13, 0x4f, 0x2c, 0x30, 0x3a, 0x0e, 0xa8, 0xd9, 0x21, - 0x1f, 0x71, 0xe6, 0x4a, 0x47, 0x74, 0x07, 0xff, 0xfb, 0x5f, 0xb4, 0xbf, - 0xa1, 0x22, 0x75, 0xf5, 0xe0, 0x2a, 0x55, 0xf6, 0x0f, 0xb5, 0x60, 0xac, - 0x4f, 0xde, 0x7d, 0xd0, 0x5b, 0xbf, 0xad, 0x74, 0x62, 0x43, 0xc8, 0x68, - 0xd9, 0xa8, 0xe8, 0xcd, 0x7f, 0xaf, 0xe8, 0xfe, 0x90, 0x22, 0xe5, 0x82, - 0xb2, 0xb6, 0x77, 0x36, 0xf6, 0xba, 0xd8, 0xc7, 0xde, 0x84, 0x1e, 0x9e, - 0xc6, 0xb2, 0xa7, 0x4c, 0xc3, 0xf7, 0x1e, 0xdb, 0xfc, 0x09, 0x8f, 0x1d, - 0xf6, 0x3b, 0xec, 0x52, 0x3e, 0x3a, 0xdf, 0x65, 0x7f, 0x8f, 0xb8, 0x95, - 0x31, 0x45, 0xbe, 0x35, 0x1c, 0x83, 0x96, 0x9c, 0x45, 0x13, 0xd3, 0x7b, - 0x6f, 0x80, 0xe4, 0xc0, 0x37, 0x4f, 0x47, 0xa9, 0x07, 0xde, 0x48, 0x27, - 0xe6, 0x2e, 0x30, 0x7c, 0x8b, 0x54, 0xbb, 0x7e, 0x30, 0xaa, 0x4a, 0x7d, - 0xdd, 0x3f, 0x08, 0x69, 0x23, 0x6b, 0x69, 0x73, 0x2b, 0xed, 0x3a, 0x0b, - 0xd4, 0xcf, 0xc1, 0xf5, 0xe9, 0x5f, 0xcb, 0x37, 0x8b, 0xb4, 0x6a, 0x43, - 0xea, 0xc4, 0x77, 0x68, 0xf8, 0x63, 0xf5, 0x04, 0x57, 0x7e, 0x65, 0x61, - 0xba, 0xd4, 0x93, 0x3d, 0x66, 0x37, 0xe3, 0x76, 0xfb, 0xbb, 0x2b, 0xe2, - 0x8f, 0x7a, 0xf4, 0x6e, 0x72, 0xd5, 0x52, 0x45, 0x78, 0xaa, 0xc4, 0xa2, - 0x36, 0xe2, 0x61, 0x27, 0xb4, 0x90, 0xde, 0x7b, 0x91, 0xea, 0x41, 0x71, - 0x64, 0x54, 0xf6, 0xd9, 0xec, 0x9e, 0xa7, 0xe6, 0xf6, 0xe3, 0xc4, 0xd8, - 0xee, 0x91, 0x3f, 0xfa, 0xdc, 0x97, 0x7d, 0x95, 0x9a, 0xf2, 0xce, 0x8e, - 0xfd, 0x9e, 0x48, 0x5b, 0xc2, 0x91, 0xdf, 0x5f, 0x58, 0x98, 0x5b, 0x0d, - 0x6b, 0x98, 0x17, 0xac, 0x95, 0x6f, 0x63, 0x72, 0xac, 0xeb, 0x12, 0xb2, - 0x0a, 0xf5, 0x7f, 0x01, 0x28, 0xfc, 0xfc, 0x40, 0x38, 0x5a, 0x00, 0x00, - 0x00 }; + 0x9d, 0xbc, 0x0d, 0x7c, 0x1b, 0xe5, 0x95, 0x2e, 0xfe, 0xcc, 0x48, 0xb2, + 0x65, 0x5b, 0xb6, 0xc7, 0x8e, 0x92, 0x28, 0xac, 0x37, 0xd1, 0xc4, 0x23, + 0x47, 0xc1, 0xa6, 0x8c, 0x12, 0x27, 0xa8, 0xac, 0x4a, 0x54, 0xc7, 0x24, + 0x4e, 0x48, 0xc1, 0x29, 0x69, 0x6b, 0xb8, 0x2d, 0xa8, 0xf9, 0xc2, 0x84, + 0x40, 0x43, 0xcb, 0xde, 0x6b, 0xee, 0xed, 0xae, 0x55, 0xdb, 0x49, 0x9c, + 0x44, 0x96, 0x6c, 0xc7, 0x24, 0xa1, 0xdb, 0xff, 0xa2, 0xc4, 0xce, 0x07, + 0x54, 0xb6, 0xd2, 0x96, 0xee, 0x86, 0xde, 0x74, 0xd1, 0x4d, 0x02, 0x18, + 0xca, 0x47, 0xda, 0xe5, 0x76, 0x69, 0x7f, 0xbd, 0xc5, 0x97, 0x42, 0x08, + 0x5b, 0x0a, 0xe9, 0xe7, 0x86, 0x7e, 0x30, 0xf7, 0x39, 0x23, 0x29, 0x31, + 0x2c, 0xdb, 0x76, 0xff, 0xfa, 0xfd, 0xe6, 0x27, 0xcd, 0xe8, 0xfd, 0x38, + 0xef, 0x79, 0xcf, 0x79, 0xce, 0x73, 0xde, 0x79, 0x67, 0xfc, 0x40, 0x39, + 0x0a, 0x9f, 0x4a, 0x1e, 0x1f, 0x6a, 0xde, 0xb6, 0x61, 0x69, 0xe8, 0x43, + 0x4b, 0xe5, 0xdc, 0xa9, 0x95, 0x38, 0xf1, 0x67, 0x7e, 0xfc, 0x7f, 0x6e, + 0xc1, 0xc2, 0x47, 0xe1, 0xd1, 0x58, 0xf8, 0xed, 0x00, 0xb4, 0x62, 0xff, + 0x72, 0xc0, 0xad, 0x46, 0xc6, 0x3a, 0x5a, 0x0c, 0xb8, 0x1d, 0x91, 0x6d, + 0xb7, 0x6f, 0x30, 0x80, 0x68, 0xa6, 0xd1, 0xbf, 0x1c, 0x7f, 0xb0, 0xe2, + 0x5e, 0x27, 0xe4, 0xfa, 0x5f, 0x46, 0x7e, 0xdf, 0xfd, 0xed, 0x6b, 0xf4, + 0x0b, 0x69, 0x07, 0xdc, 0x5a, 0x24, 0x0e, 0xad, 0x01, 0xee, 0x3a, 0xd6, + 0xf9, 0xca, 0x82, 0xaf, 0x28, 0xa8, 0x2a, 0xb6, 0x75, 0xde, 0xfa, 0xf6, + 0x02, 0x5f, 0xac, 0x2c, 0xa2, 0xe1, 0xf1, 0x2c, 0xda, 0x9b, 0x06, 0xba, + 0xad, 0x4a, 0x23, 0x04, 0xb7, 0x61, 0x74, 0x0c, 0x28, 0x9e, 0xf0, 0x96, + 0x25, 0xf0, 0x94, 0x1a, 0x88, 0x5f, 0x11, 0x41, 0xfb, 0x95, 0xe3, 0xe5, + 0x71, 0x67, 0xc4, 0x8d, 0xb6, 0xac, 0x3b, 0xfe, 0x17, 0x11, 0x03, 0x2b, + 0xb3, 0x46, 0x19, 0xaa, 0x34, 0xf4, 0x65, 0x5f, 0x77, 0xe7, 0xdb, 0x6b, + 0x2e, 0x7c, 0xdf, 0x56, 0x9b, 0xff, 0x9e, 0x15, 0x73, 0x46, 0x80, 0xed, + 0x09, 0xcb, 0x2a, 0x89, 0xdc, 0x7c, 0xb3, 0x1a, 0x31, 0x7c, 0x47, 0xb0, + 0x0c, 0xeb, 0x35, 0x7c, 0x71, 0x47, 0xf3, 0x2f, 0x94, 0x53, 0x23, 0x4d, + 0x88, 0x1f, 0x75, 0x20, 0xaa, 0x3d, 0xcb, 0xef, 0xb9, 0x73, 0x3b, 0xc2, + 0x4d, 0x38, 0x70, 0xf4, 0x22, 0xaf, 0x3b, 0xed, 0x6b, 0xbd, 0xfb, 0xe7, + 0xce, 0xbd, 0x25, 0xfc, 0x2c, 0x1e, 0x3c, 0x2a, 0xbf, 0xef, 0x40, 0x77, + 0x93, 0x82, 0xa9, 0x9b, 0x37, 0xc3, 0x61, 0x34, 0xa1, 0x6f, 0xbf, 0xe2, + 0xec, 0x69, 0x52, 0x11, 0xf5, 0xea, 0xc1, 0x18, 0x27, 0xc1, 0x69, 0x20, + 0x56, 0x1a, 0x09, 0x3b, 0xdf, 0x48, 0x44, 0x34, 0x87, 0x61, 0x59, 0xc1, + 0xd0, 0x6c, 0x38, 0x6a, 0x2c, 0xeb, 0x31, 0xd3, 0x03, 0xff, 0xa7, 0x9e, + 0x47, 0x7c, 0xb4, 0x1d, 0xaa, 0xf1, 0x3c, 0x7a, 0x46, 0x9f, 0xc7, 0x43, + 0x7b, 0xcb, 0x31, 0x35, 0x83, 0xe3, 0x4d, 0xf9, 0xf0, 0xed, 0x05, 0xd2, + 0xb7, 0xc8, 0xd1, 0xcc, 0xc3, 0x8d, 0x29, 0xc7, 0x39, 0x7e, 0x4b, 0x99, + 0x8b, 0xd6, 0xd4, 0xec, 0xcb, 0x65, 0xb6, 0xb3, 0x4c, 0xdf, 0xfb, 0xca, + 0xc4, 0x47, 0x23, 0xf8, 0x4e, 0x42, 0xc1, 0x96, 0x50, 0x15, 0xa2, 0x35, + 0x32, 0x5e, 0xcb, 0x3a, 0x6a, 0x9e, 0xb3, 0xa6, 0x34, 0xe9, 0x6b, 0x12, + 0xcf, 0xf2, 0xbf, 0x1d, 0xa1, 0x57, 0xad, 0x9c, 0x57, 0xda, 0xfb, 0x3c, + 0x6d, 0x68, 0x2d, 0xaf, 0x3b, 0x91, 0x4a, 0x20, 0x56, 0x15, 0xf9, 0x04, + 0xcf, 0x75, 0xf3, 0x2d, 0xc5, 0xed, 0x7e, 0x3b, 0xe1, 0xfe, 0x54, 0xa5, + 0xa1, 0xde, 0x57, 0x0d, 0x27, 0x9e, 0xa3, 0xcc, 0x27, 0xcc, 0xcd, 0x70, + 0x19, 0x5f, 0x10, 0x9b, 0xe3, 0xb8, 0x5e, 0xb4, 0x30, 0xbb, 0x58, 0x5f, + 0xda, 0xd5, 0xb0, 0x23, 0x65, 0x59, 0xbb, 0xcc, 0xe8, 0x87, 0xcb, 0x68, + 0x10, 0xa7, 0x13, 0xed, 0x70, 0x47, 0x02, 0xfe, 0xf3, 0x08, 0x63, 0x79, + 0xd6, 0x8b, 0x27, 0x12, 0x70, 0xb6, 0x2c, 0xa8, 0x43, 0x4f, 0x36, 0x82, + 0xeb, 0xb3, 0x26, 0x5a, 0xb3, 0x7f, 0xda, 0xca, 0x6e, 0x48, 0xf9, 0x39, + 0x86, 0x3f, 0x58, 0xf9, 0x31, 0xc8, 0xf8, 0xe4, 0x9b, 0xf3, 0x9a, 0xba, + 0x02, 0xbb, 0x47, 0x0c, 0xec, 0xe4, 0xfc, 0xad, 0x0a, 0xe5, 0xa2, 0x65, + 0xd0, 0xcd, 0xf3, 0x88, 0x60, 0x45, 0xd6, 0xe0, 0x9c, 0x46, 0xb0, 0x3c, + 0x55, 0xaf, 0x8d, 0x62, 0x21, 0xa2, 0xbe, 0xbc, 0x6d, 0xef, 0xe1, 0x78, + 0xd7, 0x07, 0xda, 0x51, 0x49, 0x1b, 0xc9, 0x2c, 0x09, 0xa3, 0x85, 0xfd, + 0xaf, 0xf9, 0x33, 0xfa, 0xbf, 0x89, 0xfd, 0xbf, 0xc5, 0xfe, 0x73, 0x76, + 0xff, 0x70, 0xae, 0xe6, 0xb9, 0x9b, 0xf6, 0xb8, 0x3b, 0xe3, 0x74, 0xae, + 0x4a, 0x79, 0xb1, 0x2b, 0x63, 0xd2, 0xe6, 0xe4, 0x2f, 0x1f, 0x76, 0x8c, + 0xd4, 0x61, 0xe7, 0x88, 0xee, 0x7b, 0x8a, 0xbf, 0x7b, 0xc7, 0xae, 0xc0, + 0xf6, 0x11, 0x05, 0x87, 0x8c, 0x2b, 0xd0, 0xc3, 0xdf, 0x07, 0x46, 0xe6, + 0xe2, 0xc1, 0x11, 0x07, 0xc2, 0x33, 0xa6, 0x8f, 0x43, 0xbe, 0xaf, 0x40, + 0x7c, 0xcc, 0x8f, 0x9e, 0xc4, 0xb3, 0xb6, 0x0e, 0x2b, 0x23, 0xdf, 0x2e, + 0xfa, 0x33, 0x7d, 0xc7, 0x8f, 0x0d, 0x09, 0x1f, 0x7a, 0x52, 0xe2, 0x07, + 0x6e, 0xda, 0xa6, 0xf8, 0xc1, 0xaf, 0x80, 0x2a, 0xb6, 0x9f, 0x2d, 0xfe, + 0xaf, 0xc0, 0xc9, 0x79, 0xdb, 0xc8, 0xff, 0x76, 0xa5, 0xc4, 0x26, 0xa4, + 0x4d, 0xb1, 0x0b, 0xf9, 0x5d, 0x4b, 0xbb, 0x2b, 0x87, 0xff, 0x70, 0x39, + 0x82, 0x0f, 0x68, 0x78, 0xad, 0x59, 0xae, 0xd3, 0xde, 0x43, 0x52, 0x66, + 0x10, 0x47, 0x32, 0xe2, 0xa7, 0x7e, 0xb4, 0x24, 0x26, 0xd9, 0x7e, 0x33, + 0xdb, 0x36, 0xf1, 0x4f, 0xd9, 0x26, 0xfc, 0x63, 0x36, 0x88, 0x7f, 0xa0, + 0x1e, 0xbf, 0x99, 0xf5, 0xe3, 0xd1, 0x6c, 0x1d, 0xbe, 0x91, 0xf5, 0xe1, + 0xeb, 0x9c, 0xbf, 0xaf, 0x65, 0xdb, 0x69, 0xfb, 0x1a, 0x8e, 0x67, 0x45, + 0xff, 0x25, 0x1c, 0x6f, 0x39, 0x7a, 0x47, 0xea, 0x83, 0xa7, 0x69, 0x5b, + 0xff, 0x60, 0xae, 0x46, 0xae, 0xb6, 0xd9, 0xb6, 0xc9, 0x5d, 0xbc, 0xbe, + 0x7b, 0xa4, 0x3e, 0x7a, 0xa5, 0x62, 0x59, 0x6a, 0xa8, 0x31, 0x7c, 0x4a, + 0x55, 0x31, 0xe5, 0xd5, 0xfd, 0x39, 0x55, 0xf7, 0x47, 0xe1, 0x42, 0x82, + 0xbe, 0x11, 0x9f, 0xa9, 0xa7, 0xe3, 0xb4, 0x29, 0xaf, 0x31, 0xca, 0xf1, + 0xe8, 0xfe, 0xb8, 0xaa, 0x61, 0x67, 0x4a, 0x3f, 0x10, 0x57, 0xbd, 0x88, + 0x67, 0xcb, 0xf1, 0xb3, 0x11, 0xbd, 0x3f, 0xae, 0xde, 0x88, 0x78, 0xad, + 0x65, 0x7d, 0x3d, 0x84, 0x6d, 0xb3, 0x23, 0x88, 0xce, 0x8c, 0x20, 0x36, + 0x37, 0x52, 0x87, 0x54, 0x0a, 0x78, 0x6b, 0xc0, 0xf0, 0xfd, 0x8b, 0xd2, + 0x8e, 0xbf, 0x6e, 0xd7, 0xfd, 0x7e, 0xb5, 0x31, 0x3e, 0xaa, 0x2e, 0xa1, + 0x4b, 0xc3, 0xef, 0x8b, 0xac, 0x44, 0x97, 0x7d, 0x4d, 0x81, 0x66, 0x78, + 0xd1, 0x9b, 0xfa, 0x30, 0x62, 0xde, 0xfa, 0x8e, 0x21, 0xb5, 0xfe, 0xa2, + 0xa9, 0xea, 0x93, 0xed, 0xaa, 0x65, 0xfd, 0x7c, 0xf1, 0x5b, 0x96, 0x7f, + 0x96, 0x65, 0x2d, 0x5a, 0x2c, 0x7d, 0xfa, 0x51, 0x13, 0x31, 0xb1, 0xd6, + 0x9e, 0xc3, 0x72, 0x9c, 0x1b, 0xa9, 0x65, 0x1f, 0x1a, 0xfe, 0xf7, 0x35, + 0x7a, 0x70, 0xb3, 0x5a, 0x8e, 0xd7, 0xc6, 0xca, 0xf1, 0x0a, 0xc7, 0xf3, + 0x8b, 0x11, 0x1f, 0x7e, 0x35, 0x62, 0x59, 0x9f, 0x32, 0xff, 0x0a, 0xc3, + 0xb5, 0x83, 0xf8, 0xc7, 0x09, 0x2f, 0x7e, 0x96, 0xd0, 0xf0, 0x6a, 0x22, + 0x7a, 0xef, 0x0c, 0xe8, 0xd1, 0x09, 0xe5, 0xf4, 0xed, 0x55, 0x68, 0x6c, + 0xaf, 0x52, 0xf4, 0xb6, 0x3d, 0xd0, 0x7d, 0x57, 0x2a, 0x5e, 0x9c, 0xcf, + 0x68, 0xf8, 0x49, 0xa6, 0x3e, 0xfc, 0xcf, 0xec, 0xf3, 0x37, 0xe6, 0x63, + 0x56, 0x6e, 0x96, 0xe8, 0x4d, 0x74, 0x44, 0x3d, 0xa7, 0xa8, 0xe7, 0x14, + 0xf5, 0x9c, 0xa2, 0x9e, 0x29, 0xc3, 0xa3, 0x29, 0xea, 0x99, 0xba, 0xfb, + 0x3a, 0x6d, 0xea, 0x6b, 0x9c, 0xc7, 0xe3, 0xf6, 0x3c, 0x86, 0x39, 0x5f, + 0x7f, 0x81, 0xbf, 0xb5, 0xb1, 0xf5, 0x59, 0xeb, 0xbf, 0x79, 0x65, 0x4c, + 0x0f, 0xcf, 0xcc, 0xe3, 0x97, 0x8c, 0xed, 0x3b, 0x56, 0x4c, 0x93, 0x71, + 0xc9, 0xf8, 0x6c, 0xfd, 0xf9, 0xb7, 0x29, 0x3b, 0x15, 0x94, 0x5b, 0xd6, + 0x5e, 0xb3, 0xf0, 0xbf, 0xb7, 0x38, 0xbe, 0x9b, 0x95, 0xbc, 0x5d, 0xfd, + 0x5d, 0x29, 0xf5, 0x1d, 0x8c, 0xaa, 0x2b, 0x79, 0xae, 0xc7, 0xa3, 0xf8, + 0xa8, 0xe3, 0xbd, 0xe7, 0xf7, 0x7a, 0x65, 0x3e, 0xfc, 0x97, 0xce, 0x69, + 0x8f, 0x76, 0x7f, 0x77, 0xf2, 0x5c, 0xc6, 0x22, 0xb6, 0x28, 0x36, 0xe0, + 0xa5, 0xbd, 0x5c, 0x53, 0xf8, 0x0f, 0x71, 0x35, 0xb2, 0x0d, 0xed, 0xcd, + 0x8f, 0xd8, 0x7d, 0x94, 0x24, 0xc5, 0x6f, 0x14, 0xbc, 0xf5, 0x61, 0x05, + 0xa7, 0x42, 0x06, 0x6d, 0xe6, 0x18, 0x71, 0x01, 0x28, 0x4d, 0xc2, 0xed, + 0x89, 0x44, 0x90, 0x18, 0x80, 0xbb, 0x2c, 0x12, 0xc6, 0xc2, 0x81, 0xfa, + 0xce, 0x73, 0xd0, 0x83, 0x03, 0x8a, 0xde, 0xce, 0x58, 0x62, 0x8e, 0x53, + 0x8f, 0x57, 0x2a, 0xba, 0xbf, 0x44, 0x81, 0x5b, 0x61, 0xb9, 0x40, 0xe6, + 0x18, 0x76, 0x66, 0xe5, 0x77, 0x18, 0x46, 0xe6, 0x37, 0xc5, 0xbe, 0x24, + 0xa6, 0xd0, 0xee, 0xcf, 0x71, 0xec, 0xba, 0x9f, 0xf8, 0xea, 0x76, 0x45, + 0x3a, 0x71, 0x38, 0x01, 0x77, 0x49, 0x64, 0x2b, 0x9e, 0x4c, 0x84, 0x67, + 0x16, 0xcb, 0x29, 0x2c, 0xe7, 0xcf, 0x4c, 0x97, 0xe5, 0xc7, 0x56, 0xd4, + 0x9b, 0x97, 0xa5, 0x3c, 0x79, 0x0c, 0x7b, 0x52, 0x52, 0x37, 0x62, 0xd7, + 0x75, 0xb2, 0x8f, 0xbe, 0x44, 0x7d, 0xdb, 0x0d, 0x8a, 0x1e, 0x7e, 0x98, + 0xf3, 0xd7, 0x83, 0xc6, 0xe8, 0x1b, 0xd0, 0xb5, 0x4e, 0xe4, 0x65, 0x59, + 0x90, 0xc9, 0xcb, 0x31, 0x3f, 0x03, 0xe5, 0xf6, 0x14, 0xac, 0x39, 0x06, + 0x3c, 0x3e, 0xc3, 0xf0, 0xbf, 0xe3, 0xa8, 0xc5, 0x01, 0xce, 0x4f, 0x1f, + 0x7d, 0x45, 0xf0, 0xec, 0xee, 0xbd, 0x7e, 0x78, 0x0c, 0x0b, 0x47, 0x42, + 0xb5, 0x78, 0x96, 0x58, 0x5b, 0x45, 0xdf, 0x7c, 0x5e, 0x43, 0x74, 0x4e, + 0x24, 0xac, 0xdc, 0x92, 0x1d, 0x2d, 0xcc, 0xc1, 0x8b, 0x35, 0x05, 0x19, + 0xdf, 0x77, 0xbd, 0x5a, 0xf9, 0xe0, 0xeb, 0x50, 0x3a, 0x52, 0x7a, 0x30, + 0x0e, 0x0b, 0xd5, 0x8b, 0x75, 0xff, 0x94, 0xf2, 0x96, 0x8a, 0x2a, 0x62, + 0x75, 0xf6, 0xfd, 0xe5, 0x1a, 0xb5, 0x31, 0xc6, 0x65, 0x07, 0x43, 0x5f, + 0x54, 0xd3, 0x4d, 0x36, 0x13, 0x74, 0xd9, 0xd7, 0x1c, 0x48, 0x3b, 0xa3, + 0x3e, 0x07, 0x7e, 0x6f, 0x45, 0xd7, 0xc9, 0xb5, 0x72, 0xc4, 0xda, 0x1b, + 0x7d, 0x4e, 0x34, 0x86, 0xb7, 0xd3, 0x07, 0xa7, 0xd6, 0xb5, 0xf0, 0xbf, + 0x80, 0x79, 0x1a, 0xf5, 0xfe, 0xed, 0x90, 0xdf, 0xef, 0xd0, 0x6e, 0x5a, + 0xa4, 0x2e, 0xcb, 0x88, 0x1d, 0xea, 0x9a, 0xf8, 0x78, 0x9f, 0x69, 0x59, + 0x87, 0xcd, 0x13, 0x4a, 0x4b, 0xea, 0x5d, 0x2b, 0xea, 0x8c, 0x47, 0x4b, + 0x23, 0x01, 0x73, 0x27, 0xc1, 0xd8, 0x11, 0x89, 0x2b, 0xd1, 0x6c, 0x9f, + 0x72, 0x7d, 0xb6, 0x5f, 0x59, 0x91, 0x95, 0xf2, 0x27, 0x94, 0xe5, 0x59, + 0x29, 0x5f, 0x2c, 0x1b, 0x66, 0x59, 0xe0, 0x48, 0x22, 0x10, 0x2c, 0x96, + 0x5f, 0xc1, 0xb2, 0xd7, 0x5f, 0x2a, 0x1b, 0xa6, 0xad, 0x9a, 0x9c, 0x97, + 0x0a, 0x6c, 0xd6, 0xf4, 0x68, 0x9c, 0x3a, 0x2f, 0x8d, 0xf8, 0x6e, 0x7d, + 0xdd, 0xc8, 0x05, 0x1d, 0x9c, 0x83, 0xa3, 0x1c, 0x59, 0x2b, 0x71, 0x6e, + 0x83, 0xe1, 0x42, 0xbf, 0x56, 0x8d, 0x0d, 0xe6, 0x6f, 0xad, 0xcd, 0xeb, + 0xe4, 0xbf, 0xbc, 0x6c, 0xb0, 0xcb, 0xd7, 0xb1, 0xbc, 0x6e, 0x1e, 0x2d, + 0x60, 0xeb, 0xa9, 0x04, 0x06, 0x1d, 0x11, 0x62, 0x7e, 0x73, 0xc0, 0xdf, + 0x03, 0x99, 0x1b, 0x3f, 0xae, 0xa7, 0x2c, 0x69, 0xe7, 0x74, 0xfc, 0x45, + 0xfc, 0x72, 0x19, 0xb9, 0x26, 0xe5, 0xa6, 0x68, 0xdf, 0x82, 0x75, 0x96, + 0x35, 0x64, 0x8a, 0x9d, 0xfb, 0x68, 0xe7, 0x33, 0xe1, 0xaf, 0xd5, 0xe3, + 0x69, 0x56, 0x38, 0x9c, 0x98, 0x81, 0xb4, 0xa6, 0x12, 0x73, 0xef, 0xf2, + 0xa0, 0x2a, 0xaa, 0x94, 0x90, 0xdb, 0x60, 0x42, 0xc6, 0x59, 0x89, 0xa8, + 0x53, 0x0f, 0xca, 0xdc, 0x95, 0x30, 0xe6, 0x35, 0xa8, 0xac, 0x77, 0xc9, + 0x97, 0x65, 0xcc, 0x7e, 0xfa, 0x72, 0xdc, 0xd6, 0x51, 0xeb, 0xa5, 0x71, + 0x4b, 0x7b, 0x45, 0x1d, 0xfd, 0x67, 0xea, 0x59, 0xd6, 0x8e, 0x4b, 0xba, + 0x2d, 0x89, 0x96, 0x51, 0xb7, 0xc7, 0x12, 0x81, 0xf0, 0xd3, 0x88, 0x2b, + 0x6d, 0x59, 0x27, 0xc6, 0x12, 0x52, 0xaf, 0x8f, 0xe5, 0xfb, 0x95, 0x95, + 0x97, 0xea, 0x4c, 0x15, 0xfc, 0x56, 0xc6, 0x23, 0xe3, 0xbb, 0x0e, 0x1b, + 0xf6, 0xea, 0xf1, 0x38, 0xc4, 0xae, 0xa2, 0x58, 0x6f, 0xea, 0x7e, 0xda, + 0x1f, 0xed, 0x06, 0xa8, 0x49, 0xc6, 0xdc, 0x79, 0x0c, 0x00, 0xee, 0xd8, + 0xdb, 0xce, 0xb1, 0x5a, 0x78, 0xcd, 0xac, 0xc5, 0x18, 0xbd, 0xb4, 0x3a, + 0x29, 0xd7, 0xa7, 0xcb, 0x18, 0x51, 0xd6, 0x1f, 0xf5, 0x97, 0xa1, 0x5c, + 0xe4, 0xfc, 0x1b, 0x35, 0x6f, 0xbf, 0x1f, 0x54, 0xff, 0x17, 0xd6, 0x98, + 0x37, 0x7f, 0xad, 0x3a, 0x29, 0x9c, 0xaf, 0x1d, 0x5a, 0xd2, 0xc3, 0x78, + 0x17, 0xb7, 0x2a, 0x0c, 0xbd, 0xfd, 0x82, 0xd2, 0x8d, 0x1b, 0x43, 0x7a, + 0xec, 0x87, 0x8a, 0x1e, 0x1d, 0x50, 0x0c, 0xfa, 0x61, 0x10, 0xab, 0xb2, + 0xef, 0xef, 0xeb, 0xfb, 0x50, 0x0f, 0x4b, 0x3f, 0xd2, 0xdf, 0x59, 0xf4, + 0xdb, 0x63, 0x2a, 0x8e, 0x47, 0xc6, 0xa6, 0x60, 0xb3, 0x3d, 0xa6, 0x15, + 0xb6, 0x7f, 0x7c, 0xd7, 0x74, 0x61, 0xe3, 0xde, 0x53, 0x0b, 0xc5, 0x40, + 0x36, 0x1d, 0x8d, 0xa2, 0xb7, 0xd9, 0x85, 0x0d, 0xa3, 0x37, 0xa9, 0x22, + 0x1b, 0xd4, 0xf9, 0x65, 0xf9, 0x6f, 0x85, 0xbc, 0xc5, 0x83, 0xf5, 0x59, + 0xce, 0x1d, 0x31, 0x74, 0xfd, 0x51, 0x99, 0xdb, 0x5a, 0x7e, 0xcb, 0xdc, + 0x7a, 0xf9, 0x2d, 0xf3, 0x3c, 0x8b, 0xdf, 0xd5, 0xf0, 0xcf, 0x12, 0x59, + 0x9a, 0x91, 0xd8, 0x0f, 0x77, 0x45, 0xa4, 0x0b, 0x77, 0x0d, 0x58, 0x56, + 0x7f, 0xc0, 0xb2, 0xca, 0x42, 0xe4, 0x59, 0x81, 0xc6, 0xf0, 0x95, 0x4a, + 0x09, 0xa6, 0xb4, 0x66, 0xf4, 0x1f, 0x2d, 0x89, 0x55, 0x47, 0x66, 0xd1, + 0xf7, 0x35, 0xfc, 0x6c, 0x49, 0x3b, 0x26, 0xc6, 0xa7, 0x8f, 0x21, 0x6f, + 0x67, 0xdf, 0x5e, 0x50, 0xb4, 0x33, 0x91, 0x5f, 0x64, 0xd7, 0xfb, 0xd3, + 0xf4, 0xcb, 0xb8, 0x86, 0x18, 0xfd, 0x83, 0x32, 0xd5, 0xa2, 0xe7, 0x12, + 0xa7, 0xfe, 0xa0, 0xfa, 0x17, 0x1b, 0x3b, 0x13, 0xef, 0x5a, 0x0c, 0xa7, + 0xfc, 0xe4, 0x1a, 0xef, 0xcd, 0xbc, 0xd7, 0x6e, 0xca, 0x6c, 0xbb, 0x91, + 0xb2, 0x17, 0x1b, 0xef, 0xcc, 0xac, 0xb0, 0xc7, 0x9c, 0x66, 0xe1, 0x4d, + 0x7b, 0x45, 0xa7, 0xa2, 0x03, 0x0b, 0xc7, 0xcd, 0xeb, 0x88, 0x15, 0xaf, + 0x5b, 0x8e, 0x59, 0xd2, 0x46, 0x97, 0xd2, 0x4a, 0x7b, 0x8a, 0x3b, 0x4b, + 0x41, 0x4e, 0xad, 0x95, 0x44, 0xa2, 0xca, 0x5a, 0x5b, 0xff, 0xad, 0xca, + 0xca, 0xd1, 0xe9, 0x6d, 0x77, 0xd1, 0x77, 0x1f, 0x57, 0xf3, 0xf3, 0x7d, + 0xde, 0x1e, 0x43, 0x5e, 0x7e, 0x3f, 0xda, 0x53, 0xd2, 0x8e, 0xe8, 0x35, + 0xef, 0x6f, 0xed, 0x12, 0x23, 0x2e, 0xc9, 0x9c, 0xe7, 0x1e, 0x97, 0x31, + 0x61, 0xc9, 0x7b, 0xf0, 0xe3, 0x7a, 0xe2, 0x47, 0xf4, 0x3f, 0xc4, 0x8f, + 0xa5, 0x7f, 0xa2, 0xec, 0x59, 0xca, 0x21, 0x3c, 0x45, 0xe2, 0x9e, 0xf0, + 0x16, 0xe1, 0x2b, 0x41, 0xca, 0x25, 0xfc, 0xa5, 0x68, 0x1b, 0x96, 0xf5, + 0x4d, 0x73, 0x01, 0x62, 0xb5, 0xfa, 0x20, 0x50, 0x87, 0x41, 0xca, 0xea, + 0x48, 0x22, 0xce, 0x71, 0x52, 0xd7, 0xea, 0x75, 0x0e, 0xa8, 0x4d, 0x0e, + 0x74, 0xe3, 0x55, 0xd3, 0xe8, 0xdf, 0x8c, 0xbf, 0x44, 0x8f, 0xd7, 0xc2, + 0x61, 0x33, 0x48, 0x5c, 0x2a, 0x47, 0x67, 0x13, 0x27, 0x62, 0xad, 0x17, + 0x43, 0xa9, 0x78, 0x07, 0x61, 0x83, 0x31, 0xec, 0xd9, 0x4f, 0x26, 0x02, + 0x7a, 0xfb, 0x56, 0xa6, 0x40, 0xab, 0x06, 0xdc, 0xf0, 0x4b, 0x2a, 0xc4, + 0x98, 0xf1, 0x75, 0xc6, 0xf9, 0x4d, 0xe6, 0x15, 0xd4, 0x6d, 0x1f, 0x6d, + 0x48, 0xa5, 0xbd, 0x48, 0x3f, 0x41, 0xf2, 0x19, 0xa9, 0xcb, 0xb8, 0xd0, + 0xa0, 0xe0, 0x86, 0x06, 0xda, 0x27, 0x79, 0xd1, 0xe7, 0x43, 0x4e, 0xfb, + 0xff, 0x44, 0xb6, 0x31, 0x7a, 0xb3, 0xfa, 0x23, 0x0b, 0x33, 0xed, 0x36, + 0xb4, 0xa8, 0x4a, 0xb9, 0xff, 0x28, 0x27, 0x30, 0x21, 0x5c, 0xad, 0xd2, + 0xf8, 0x0d, 0xc6, 0xbd, 0x52, 0xa7, 0x0a, 0x15, 0xc3, 0xf1, 0x59, 0xe5, + 0xb4, 0xe1, 0xd2, 0x88, 0x8e, 0xbb, 0x46, 0x2b, 0xe1, 0x18, 0xd6, 0x2f, + 0xae, 0x74, 0x20, 0x56, 0x22, 0xfc, 0x70, 0xb4, 0x16, 0x35, 0xfb, 0xac, + 0x6e, 0x77, 0xc4, 0xb2, 0x3c, 0x4b, 0x22, 0xb8, 0xf7, 0xa8, 0x06, 0x75, + 0x9f, 0x0b, 0x15, 0xcc, 0x43, 0xd6, 0x99, 0x7d, 0xb8, 0x8f, 0xfc, 0x6e, + 0x4e, 0x32, 0x88, 0xd5, 0xc4, 0xa2, 0x8b, 0xa9, 0xb6, 0xd6, 0x17, 0x12, + 0x0d, 0xdb, 0xe6, 0x38, 0x84, 0xfb, 0xaf, 0xc1, 0xe6, 0xec, 0x1a, 0xdc, + 0xc9, 0xd8, 0xf9, 0x9c, 0x81, 0xee, 0x39, 0xf4, 0xd7, 0x3b, 0xc9, 0xff, + 0x36, 0xa6, 0xd6, 0x61, 0x63, 0x76, 0x1b, 0xff, 0xeb, 0xc0, 0xdd, 0x3c, + 0x36, 0xa5, 0xc4, 0xbf, 0x3f, 0x8d, 0x4d, 0xd9, 0x7a, 0xc4, 0x46, 0x37, + 0x62, 0x2b, 0x39, 0xc1, 0x5d, 0xa3, 0x5e, 0xea, 0xb6, 0x0d, 0x1b, 0xb2, + 0x6d, 0xb8, 0x97, 0x63, 0xb9, 0x97, 0xf3, 0xa1, 0x26, 0xb7, 0xd2, 0xc7, + 0x3c, 0xf0, 0x0e, 0x2f, 0xc5, 0x7d, 0xa3, 0xd7, 0x61, 0x0b, 0xe3, 0xe4, + 0xed, 0x4b, 0xae, 0x43, 0xf7, 0xe8, 0x7d, 0xe8, 0x4a, 0x19, 0x5d, 0x73, + 0x98, 0x6a, 0xbd, 0xb5, 0xe4, 0x3e, 0xdc, 0x43, 0x39, 0xb6, 0xed, 0xb5, + 0x50, 0xb6, 0x68, 0xb1, 0x6a, 0xd4, 0xc4, 0x2d, 0x9f, 0x21, 0xb1, 0xf9, + 0xc0, 0xad, 0x7d, 0xc6, 0xee, 0x02, 0xb6, 0x38, 0x51, 0x62, 0x28, 0x62, + 0xa3, 0xf9, 0xeb, 0x89, 0xbf, 0xc1, 0xe6, 0x51, 0x17, 0xee, 0x18, 0xed, + 0x52, 0x56, 0x8b, 0xad, 0xb8, 0x54, 0xce, 0x67, 0x94, 0xd8, 0xd7, 0xaa, + 0xb4, 0x8c, 0xda, 0xf3, 0xac, 0x79, 0x23, 0x5d, 0xca, 0xba, 0xec, 0x9d, + 0x0e, 0x94, 0xcb, 0x5c, 0x5c, 0x83, 0xf1, 0xa6, 0xaf, 0x58, 0xe9, 0xfc, + 0x7c, 0xa6, 0xe9, 0x3e, 0x6e, 0x5f, 0xe4, 0x57, 0x9f, 0xf4, 0x2d, 0xd0, + 0xbb, 0x0e, 0xa8, 0xc2, 0x2b, 0xdd, 0xc8, 0xd9, 0xf3, 0x59, 0xc2, 0x7e, + 0x6a, 0x70, 0xc4, 0x9b, 0xe7, 0x12, 0xf3, 0xd8, 0x97, 0x95, 0x72, 0x71, + 0xac, 0x94, 0x9b, 0xe3, 0x99, 0x93, 0xf4, 0xe1, 0x7e, 0xea, 0xa7, 0x8b, + 0x73, 0xd4, 0x45, 0xbd, 0x7c, 0x2e, 0x75, 0x8a, 0x31, 0x62, 0x1b, 0x3e, + 0x57, 0xe8, 0xa7, 0x2f, 0x5b, 0x8a, 0x72, 0xa3, 0x0f, 0x8f, 0x68, 0x25, + 0xf4, 0x31, 0xe1, 0x19, 0x07, 0x6e, 0x3d, 0x6c, 0xac, 0xe3, 0x18, 0xbe, + 0xc4, 0x36, 0x44, 0xae, 0x46, 0xad, 0x06, 0xf9, 0xb2, 0x3d, 0xc4, 0xec, + 0x72, 0xe3, 0x37, 0xd6, 0x23, 0xde, 0x76, 0xbb, 0x6c, 0x15, 0xcb, 0x3e, + 0x3f, 0xe0, 0xc7, 0x8d, 0xb4, 0xef, 0xb2, 0x64, 0x94, 0x7a, 0x77, 0x93, + 0x53, 0xb5, 0x52, 0xe7, 0x9c, 0x63, 0xea, 0xf5, 0x0e, 0xda, 0xb3, 0x33, + 0xb9, 0x86, 0xf3, 0xa0, 0xa1, 0x32, 0xd9, 0xc7, 0x79, 0xf0, 0xc2, 0x9d, + 0x6c, 0x47, 0x27, 0xe5, 0x72, 0x25, 0xd7, 0x71, 0x2e, 0xea, 0xe0, 0x49, + 0x76, 0x70, 0x2e, 0x80, 0xbb, 0xa8, 0xcb, 0xfb, 0x42, 0xbf, 0x56, 0x7a, + 0x6b, 0x65, 0x18, 0x6d, 0x9c, 0xbf, 0x28, 0x36, 0xa7, 0xea, 0xc3, 0x3b, + 0x24, 0xee, 0x3b, 0x99, 0x90, 0x19, 0x3f, 0x26, 0x17, 0xa6, 0xf5, 0x1b, + 0x3d, 0xfc, 0x5d, 0x94, 0xb3, 0x88, 0xe3, 0x22, 0xa7, 0xc4, 0xd7, 0xa2, + 0x9c, 0x2e, 0x94, 0x19, 0xcf, 0x5a, 0x0f, 0x7b, 0xe1, 0x77, 0xb1, 0x6c, + 0x39, 0xcb, 0xae, 0xa6, 0x9c, 0xab, 0x29, 0xff, 0xbc, 0xe4, 0xa7, 0xd1, + 0x4d, 0x39, 0xe7, 0x0c, 0xbb, 0xc9, 0x51, 0x75, 0xdc, 0x4f, 0xdd, 0x1f, + 0x48, 0x95, 0xa1, 0x9a, 0xf3, 0xfc, 0x39, 0xfe, 0xde, 0x41, 0x3f, 0x7a, + 0x7e, 0xd0, 0xc2, 0x99, 0x90, 0x86, 0x41, 0xad, 0x0c, 0xbd, 0xc1, 0xad, + 0xe4, 0xe5, 0x32, 0x57, 0xcc, 0xa7, 0x8c, 0x0a, 0xc6, 0x75, 0xc4, 0x5d, + 0xcd, 0x3a, 0xb6, 0x07, 0xdd, 0x48, 0x7b, 0x11, 0x75, 0x19, 0x51, 0xda, + 0xb8, 0x0b, 0x03, 0x9a, 0x02, 0x17, 0xf1, 0xb0, 0x94, 0xfe, 0xb4, 0x93, + 0x71, 0xd7, 0x15, 0x91, 0xff, 0x68, 0x27, 0xe4, 0x60, 0xd5, 0x11, 0x23, + 0xfe, 0x82, 0x12, 0x68, 0x73, 0xa9, 0xf7, 0x51, 0x47, 0x15, 0x38, 0x33, + 0xf8, 0x25, 0x6c, 0x64, 0x5f, 0x7d, 0x29, 0x0f, 0x73, 0x93, 0xbf, 0x53, + 0x72, 0x36, 0x7e, 0x7a, 0x90, 0x1c, 0x79, 0xdc, 0x9a, 0x67, 0x88, 0xdd, + 0x44, 0x70, 0xcf, 0xd1, 0x2a, 0x0c, 0x0e, 0x5e, 0x87, 0x6d, 0x2c, 0xb7, + 0x2b, 0x55, 0x0d, 0x63, 0x68, 0x99, 0x5d, 0x67, 0x84, 0xfe, 0x35, 0x90, + 0xbc, 0x0f, 0x2b, 0x53, 0xf5, 0xc1, 0xa3, 0x4a, 0x8c, 0x3a, 0xf4, 0xa2, + 0x3f, 0xb9, 0xd1, 0xd6, 0x69, 0x62, 0x5f, 0x27, 0xb6, 0x1e, 0xbd, 0x02, + 0x7b, 0xf6, 0x6d, 0xc1, 0x5d, 0x47, 0x99, 0xbf, 0xda, 0xb6, 0xac, 0xa2, + 0x77, 0xdf, 0x75, 0xca, 0x06, 0xb6, 0xb7, 0x7b, 0x98, 0xf6, 0x4c, 0x9b, + 0xbe, 0x7f, 0xaf, 0x91, 0x5b, 0xe6, 0xd8, 0xa2, 0xf8, 0x6b, 0xaf, 0x43, + 0x97, 0x6d, 0x7b, 0x79, 0xbd, 0xed, 0xc8, 0xce, 0x67, 0x9e, 0xf3, 0xb7, + 0xd6, 0xa3, 0xde, 0x52, 0x7b, 0x7e, 0x55, 0xea, 0xad, 0x25, 0xc1, 0xdc, + 0xbf, 0x96, 0xb9, 0x57, 0xc1, 0x5e, 0x7a, 0xb3, 0x8b, 0xc9, 0x1b, 0xbd, + 0xc8, 0x68, 0x41, 0xea, 0xa3, 0x38, 0x0f, 0x0d, 0x05, 0x7b, 0x79, 0x8b, + 0x65, 0x6c, 0x5b, 0x7e, 0x9f, 0x2f, 0xc8, 0xfc, 0xb6, 0xa3, 0x86, 0xf1, + 0x75, 0x43, 0x68, 0x9d, 0x72, 0xaf, 0x76, 0x69, 0xce, 0x7c, 0xc5, 0x39, + 0x93, 0x3c, 0xd1, 0x6e, 0x2b, 0xf1, 0x25, 0xdb, 0x76, 0xaf, 0xcf, 0x36, + 0xa3, 0x73, 0x74, 0x7a, 0xfb, 0xc5, 0x3a, 0x65, 0x9c, 0x8b, 0xe2, 0x3c, + 0xeb, 0xfd, 0x82, 0x65, 0x81, 0x45, 0x45, 0x2c, 0xbb, 0xb3, 0xd0, 0xff, + 0x41, 0x8b, 0x31, 0xc9, 0xe9, 0x32, 0x1c, 0x18, 0x09, 0xfe, 0x57, 0x25, + 0x5e, 0xeb, 0xa4, 0xcc, 0x0a, 0xb1, 0xe4, 0xef, 0xac, 0x3d, 0xeb, 0x64, + 0x5e, 0x3e, 0x42, 0x43, 0x86, 0xe2, 0xba, 0xe4, 0xb3, 0x6b, 0xb0, 0x3e, + 0x25, 0xb2, 0xb6, 0x63, 0x43, 0xca, 0x96, 0xcb, 0x5f, 0x94, 0xab, 0x8f, + 0x36, 0xa3, 0x25, 0x77, 0xdb, 0x32, 0xb5, 0xd3, 0xae, 0xee, 0xd9, 0xab, + 0xe2, 0xe9, 0xd0, 0x26, 0xc5, 0x3f, 0x53, 0xe2, 0x70, 0x3d, 0xba, 0xf6, + 0xca, 0xb7, 0x9f, 0x7c, 0x37, 0xa6, 0x4c, 0xcd, 0x1c, 0x60, 0xb9, 0x65, + 0x58, 0xbf, 0xb7, 0x16, 0x73, 0x38, 0xd6, 0xdb, 0xcd, 0xff, 0xa2, 0xbc, + 0x33, 0x43, 0xc6, 0xb3, 0xa2, 0x10, 0xcb, 0xeb, 0x71, 0xdf, 0x5e, 0xf1, + 0x21, 0xf9, 0xdd, 0x82, 0xde, 0xa5, 0xf5, 0x85, 0x38, 0xff, 0x37, 0x9c, + 0x97, 0x2e, 0xe5, 0x06, 0xe2, 0x42, 0x8c, 0xb8, 0x40, 0x9b, 0x52, 0xda, + 0x89, 0x0b, 0xd7, 0x17, 0x70, 0xc1, 0x43, 0x5c, 0x58, 0x93, 0x7d, 0x9b, + 0xf2, 0x88, 0x2f, 0xbe, 0x57, 0x9e, 0xbb, 0x29, 0xcf, 0xb1, 0xd0, 0x1c, + 0xc0, 0x96, 0x67, 0x19, 0x79, 0x4c, 0x2d, 0xe7, 0xd0, 0x62, 0x7c, 0x50, + 0x94, 0x11, 0x5b, 0xcf, 0xcb, 0x28, 0xb3, 0xd8, 0x94, 0x45, 0xb9, 0x7f, + 0x8f, 0x06, 0x7b, 0x7d, 0xe0, 0xb2, 0x3c, 0xeb, 0xf7, 0xbe, 0xcb, 0x1c, + 0x41, 0x7e, 0x13, 0x2f, 0x9a, 0xeb, 0x89, 0x73, 0xcb, 0x88, 0x7b, 0x2e, + 0x8e, 0x4b, 0xb0, 0x4e, 0x64, 0x73, 0xd1, 0x2f, 0xa4, 0x6d, 0xd1, 0xc9, + 0x52, 0x47, 0x7e, 0x1e, 0x8a, 0xf3, 0xec, 0xa4, 0x1f, 0xbb, 0x51, 0x1d, + 0xd1, 0xa3, 0x37, 0x39, 0x64, 0xce, 0x88, 0xf2, 0x43, 0xed, 0x85, 0xbe, + 0xfe, 0xbb, 0xd2, 0x50, 0xd3, 0x4f, 0x39, 0x4f, 0x28, 0xb7, 0x70, 0x5c, + 0xfe, 0xd2, 0xaa, 0xa8, 0x27, 0x12, 0xe8, 0x48, 0xbc, 0x2f, 0x36, 0xde, + 0x90, 0xcd, 0xf3, 0x4b, 0x75, 0x28, 0x6e, 0x95, 0xd3, 0xf6, 0x9d, 0x46, + 0xe0, 0xe2, 0x6a, 0xf6, 0x30, 0xef, 0xa0, 0xf0, 0x19, 0x93, 0x6d, 0x15, + 0xfb, 0xaa, 0x23, 0x96, 0x84, 0x0a, 0x76, 0xb0, 0x46, 0x61, 0xde, 0xd0, + 0x16, 0xb5, 0xed, 0x61, 0x17, 0xf5, 0x75, 0x42, 0xf9, 0x98, 0x70, 0x66, + 0x9b, 0x63, 0xc4, 0x95, 0x55, 0xc4, 0x95, 0xea, 0xa4, 0x12, 0xf5, 0x46, + 0x1a, 0xb7, 0xd5, 0x20, 0xd0, 0xf6, 0x28, 0xfb, 0xac, 0x21, 0xcf, 0xbc, + 0x89, 0xb1, 0x36, 0xc9, 0x3e, 0x57, 0xb1, 0xcf, 0xb5, 0xd9, 0x2d, 0x6c, + 0x57, 0xb0, 0x55, 0xc5, 0x9c, 0x7d, 0x70, 0x7b, 0x69, 0x07, 0x23, 0x0d, + 0x4e, 0x84, 0x17, 0xff, 0x02, 0x98, 0x81, 0x98, 0xca, 0xfc, 0x7d, 0x5e, + 0x52, 0x72, 0xa9, 0x03, 0xb7, 0x2e, 0xcb, 0x08, 0x96, 0x6a, 0xf0, 0x0c, + 0x7b, 0x25, 0x1e, 0xa1, 0x2f, 0x54, 0xa7, 0xec, 0xb1, 0xf1, 0x56, 0x45, + 0xd9, 0x3e, 0x05, 0x57, 0x85, 0xbe, 0xae, 0xa4, 0x67, 0xe6, 0x31, 0x5f, + 0xa5, 0x3e, 0x7a, 0x26, 0x04, 0x1b, 0xd3, 0xc4, 0xc6, 0x63, 0x4a, 0x7e, + 0x3d, 0x86, 0x7e, 0x9f, 0x42, 0xbc, 0x2a, 0x22, 0x6b, 0x20, 0x81, 0xce, + 0x0f, 0x29, 0xf7, 0x11, 0x0b, 0x5d, 0x8c, 0x43, 0x1e, 0x62, 0xa3, 0xc4, + 0xe9, 0xf4, 0xad, 0x89, 0x81, 0x3a, 0xf4, 0xd3, 0xb7, 0x37, 0x1e, 0x3d, + 0x75, 0x8b, 0x07, 0xb5, 0xfc, 0xf6, 0xf2, 0x98, 0xc5, 0xc3, 0x4d, 0x5f, + 0x76, 0xc3, 0x31, 0x20, 0x7c, 0xaf, 0x89, 0xb1, 0xca, 0x83, 0xf2, 0x01, + 0x13, 0x5b, 0x28, 0x4f, 0xe9, 0x50, 0x33, 0xe3, 0x09, 0xfd, 0x3c, 0x55, + 0x83, 0xeb, 0x07, 0x97, 0x60, 0x93, 0x8d, 0x5f, 0xb5, 0x38, 0x3b, 0xb8, + 0xd4, 0xc6, 0x8d, 0x87, 0x52, 0x33, 0xf0, 0xce, 0xde, 0x6b, 0x6c, 0x8c, + 0x1b, 0x64, 0x6c, 0xf6, 0xed, 0x0b, 0xa3, 0x8b, 0x6d, 0x7a, 0xf7, 0x5d, + 0x8b, 0xfb, 0x8e, 0xfa, 0xa8, 0x23, 0x83, 0x71, 0x40, 0x7d, 0xd7, 0xff, + 0x49, 0xb1, 0xf3, 0xe9, 0xd8, 0x2f, 0x73, 0x2d, 0x75, 0x32, 0x34, 0x56, + 0xf9, 0xed, 0xb4, 0xb9, 0x70, 0x5e, 0x47, 0x79, 0x9d, 0x5c, 0x4d, 0x9d, + 0xdc, 0x94, 0xa5, 0x39, 0x0c, 0x3b, 0x39, 0xd7, 0xe4, 0x10, 0x35, 0xb5, + 0xf4, 0xcb, 0x12, 0x1e, 0xb4, 0xff, 0xd1, 0xbf, 0x60, 0x6c, 0xcf, 0x71, + 0x3e, 0xf9, 0xdb, 0x94, 0xf9, 0x94, 0xf8, 0xe9, 0x20, 0xe6, 0x2a, 0xd4, + 0xef, 0xff, 0x02, 0x66, 0xe7, 0x73, 0x9b, 0xa2, 0xae, 0x54, 0x8e, 0xbf, + 0x25, 0x91, 0xb3, 0x39, 0x3d, 0x33, 0x22, 0x5d, 0xe5, 0x7f, 0x1b, 0x8f, + 0x92, 0x73, 0x27, 0xc5, 0x67, 0xbd, 0xb4, 0xe7, 0x26, 0xea, 0x4b, 0x63, + 0xec, 0x30, 0x89, 0x73, 0xb3, 0xe0, 0xe2, 0x38, 0x36, 0x51, 0x3f, 0x1e, + 0x8e, 0x63, 0x2b, 0xcb, 0xdd, 0xc5, 0xff, 0xee, 0x3a, 0x5a, 0xcb, 0xc3, + 0xcb, 0x63, 0x16, 0x8f, 0x9f, 0x12, 0xb3, 0x9a, 0x69, 0xc7, 0x0e, 0x94, + 0x0c, 0xab, 0x78, 0xca, 0x54, 0x70, 0xa1, 0x89, 0xfd, 0x35, 0x5c, 0xc6, + 0x3a, 0x89, 0x65, 0xde, 0xe4, 0x97, 0x88, 0x73, 0x7e, 0xac, 0x23, 0x27, + 0xe8, 0xdc, 0xab, 0xc1, 0x15, 0xca, 0x30, 0x67, 0x12, 0x19, 0x4e, 0x14, + 0x38, 0xe6, 0x3c, 0xe6, 0x3a, 0x8d, 0x61, 0xda, 0x90, 0xb6, 0xd9, 0xb6, + 0xa1, 0x38, 0xe3, 0x73, 0x90, 0xb9, 0x7e, 0xde, 0x76, 0x5b, 0xde, 0x63, + 0x47, 0xf4, 0x31, 0x8e, 0x67, 0x4e, 0x44, 0xf7, 0xdf, 0x42, 0x5f, 0x10, + 0xce, 0x57, 0x9a, 0x04, 0x0e, 0x0c, 0xb6, 0xa3, 0x9a, 0x36, 0xe3, 0x5d, + 0x7c, 0x14, 0xa9, 0xda, 0x7e, 0xdb, 0x56, 0xf3, 0x6d, 0x97, 0x45, 0x2b, + 0x23, 0x8d, 0x31, 0x69, 0x7b, 0xbc, 0xd0, 0xf6, 0x0a, 0xb6, 0x9d, 0x60, + 0xdb, 0x2b, 0xff, 0x5d, 0xdb, 0xd3, 0xe3, 0x5d, 0x4f, 0x21, 0x2e, 0x4b, + 0xde, 0x5c, 0xc4, 0xed, 0x22, 0xc7, 0xf8, 0x8d, 0xf7, 0x32, 0x4e, 0xee, + 0x90, 0xb9, 0xf3, 0xe5, 0x7d, 0xf6, 0xbd, 0xd8, 0x7c, 0xb9, 0xad, 0x3d, + 0xc5, 0x18, 0x6f, 0xd6, 0x4c, 0x6b, 0x6b, 0x0e, 0xff, 0xff, 0x70, 0x4a, + 0xb8, 0x44, 0x3b, 0x2c, 0xca, 0xfa, 0xac, 0xa1, 0x77, 0x2d, 0x73, 0x18, + 0xdb, 0x2e, 0x32, 0xd7, 0xb9, 0xf1, 0x52, 0x5f, 0xb2, 0x36, 0xd2, 0x8e, + 0x85, 0x03, 0x7a, 0xe7, 0x2e, 0xf2, 0xd1, 0xc3, 0x21, 0x3d, 0xfa, 0x2d, + 0xe8, 0xf1, 0x52, 0xe5, 0x25, 0x94, 0x4c, 0x9c, 0xc5, 0x60, 0xf6, 0x47, + 0x92, 0x6f, 0xb2, 0x4d, 0xb7, 0xe2, 0x99, 0xe8, 0x43, 0x8c, 0xf5, 0xdc, + 0xac, 0xe7, 0x1e, 0x80, 0xbb, 0x92, 0xf5, 0xc6, 0x07, 0xe2, 0x96, 0x8b, + 0x5c, 0x50, 0x8d, 0xe8, 0x1d, 0x95, 0x8a, 0x11, 0xdb, 0xc4, 0xb6, 0xd7, + 0x30, 0x96, 0x95, 0x27, 0xbb, 0xc9, 0x03, 0x74, 0xdf, 0x97, 0x55, 0xbd, + 0x6b, 0x3d, 0x5e, 0xc2, 0xbf, 0x92, 0x3c, 0xce, 0x4b, 0x9e, 0x45, 0x8a, + 0xed, 0x59, 0xe3, 0x1a, 0xf9, 0xcc, 0xbb, 0x56, 0x78, 0x41, 0x85, 0x53, + 0xda, 0xbd, 0x38, 0xbe, 0xe0, 0xdd, 0xc4, 0x65, 0x3c, 0xd7, 0x5c, 0x46, + 0xe3, 0xfb, 0xf0, 0xa9, 0xa9, 0x75, 0x45, 0x62, 0xfd, 0x56, 0x57, 0x64, + 0xdb, 0xfd, 0xc7, 0x9b, 0xf3, 0x76, 0xeb, 0xcf, 0xb8, 0x71, 0xd6, 0x2b, + 0xbe, 0xc4, 0xfc, 0x67, 0x7f, 0x13, 0x76, 0xef, 0x67, 0x5e, 0xa9, 0x36, + 0x86, 0xcb, 0x95, 0x1a, 0xe6, 0x44, 0xc3, 0x36, 0x1f, 0x76, 0x1a, 0xbb, + 0xec, 0x9c, 0x59, 0xe2, 0x83, 0xd4, 0x99, 0x9f, 0x91, 0xf8, 0x27, 0xeb, + 0x39, 0x07, 0x6e, 0xdd, 0x90, 0xa0, 0xdf, 0x6a, 0xbd, 0x2c, 0xb3, 0xae, + 0xb0, 0x4e, 0x2f, 0x6b, 0x18, 0xbd, 0xd3, 0x38, 0xc9, 0xba, 0x69, 0xb1, + 0xaa, 0xd1, 0x5f, 0x73, 0x29, 0x8e, 0x74, 0x14, 0xca, 0x33, 0xd9, 0xb3, + 0x65, 0x73, 0x4f, 0xc3, 0xb3, 0x1d, 0xbc, 0x96, 0xf7, 0x85, 0xcb, 0xf1, + 0x6e, 0x67, 0x61, 0x6e, 0x0e, 0xb9, 0xf2, 0xb8, 0xff, 0x69, 0x77, 0x71, + 0xbd, 0x28, 0x5f, 0xe6, 0xda, 0x12, 0x94, 0xef, 0xb9, 0x14, 0x5b, 0xe2, + 0xc4, 0xf2, 0x6d, 0x7b, 0xf3, 0xeb, 0x93, 0x95, 0x4b, 0x05, 0xb7, 0xeb, + 0x71, 0xb7, 0xed, 0xf7, 0x5f, 0x75, 0xe5, 0xed, 0xc0, 0x59, 0x18, 0x97, + 0x49, 0x1b, 0xbc, 0x52, 0xd6, 0xfc, 0x0b, 0xf8, 0x39, 0x9b, 0xff, 0xf7, + 0x42, 0xe6, 0xc2, 0x45, 0xff, 0x7c, 0xdc, 0x74, 0x60, 0x6a, 0x46, 0x9e, + 0xaf, 0xab, 0xfb, 0x9a, 0xd0, 0x33, 0x46, 0xbc, 0xa1, 0x0f, 0xb5, 0x85, + 0xd6, 0x5a, 0xa8, 0x91, 0x75, 0x83, 0x5a, 0x54, 0xec, 0x13, 0xde, 0x4c, + 0x9e, 0x31, 0x76, 0xca, 0x1e, 0x4b, 0x6f, 0x26, 0xbf, 0x2e, 0xb2, 0x33, + 0xd5, 0xf7, 0xee, 0x1d, 0x9a, 0xe0, 0x85, 0xd8, 0x46, 0xdd, 0xad, 0x0b, + 0x03, 0x39, 0xbf, 0x03, 0xba, 0xb9, 0x4b, 0x56, 0x92, 0x12, 0xb7, 0x61, + 0x7b, 0xad, 0x82, 0x2e, 0xa3, 0x1a, 0x8e, 0xc5, 0xbf, 0xb5, 0xee, 0x58, + 0x27, 0xff, 0xbd, 0x5b, 0xc0, 0x97, 0x0f, 0xb2, 0x6f, 0x19, 0xb7, 0x70, + 0x3a, 0x37, 0x2a, 0xe8, 0x53, 0x37, 0x38, 0x84, 0x73, 0x2a, 0x8c, 0x9d, + 0xf6, 0x5c, 0xa0, 0x37, 0xad, 0x60, 0x77, 0x5a, 0x30, 0xd3, 0x49, 0x1c, + 0xf4, 0x61, 0x67, 0x5a, 0x70, 0xd0, 0x45, 0x1c, 0x9c, 0x83, 0xed, 0x69, + 0xc1, 0xc1, 0x12, 0xbc, 0x3c, 0x78, 0x05, 0x1e, 0xe2, 0xef, 0x07, 0x53, + 0xa5, 0x08, 0xef, 0xfd, 0x0b, 0x1c, 0x48, 0x0b, 0x7f, 0x72, 0x23, 0x35, + 0x5c, 0x87, 0x54, 0x3a, 0xcf, 0x25, 0xaa, 0x86, 0xff, 0x12, 0x49, 0xfe, + 0x1e, 0x20, 0xef, 0xcb, 0x0c, 0xcd, 0x45, 0x82, 0xbf, 0x65, 0xbd, 0xcd, + 0x43, 0xf9, 0x13, 0x81, 0x0a, 0x6c, 0x18, 0x92, 0x1c, 0xda, 0x77, 0xeb, + 0x5d, 0x81, 0x79, 0xec, 0xb3, 0x0e, 0xbb, 0xc9, 0xd9, 0xda, 0x86, 0xfc, + 0xe8, 0xe7, 0xef, 0x9d, 0xa9, 0x4a, 0xbc, 0x36, 0xa8, 0xdb, 0xfd, 0xf5, + 0xa4, 0x56, 0xac, 0x70, 0x19, 0x55, 0x58, 0x31, 0x38, 0x1f, 0x3b, 0xd2, + 0x82, 0xbd, 0xd5, 0xc4, 0xde, 0x7a, 0x3c, 0x98, 0x16, 0x7e, 0xa9, 0xc1, + 0xbb, 0xd7, 0xc0, 0x48, 0x5a, 0xd6, 0x84, 0x6b, 0x70, 0x61, 0x28, 0x80, + 0x41, 0xbb, 0x7f, 0x13, 0xc9, 0x54, 0x98, 0xf2, 0x79, 0x51, 0xb9, 0x2f, + 0xe7, 0xab, 0x82, 0x82, 0xc9, 0x40, 0x10, 0x03, 0x63, 0xb3, 0x50, 0xbe, + 0x4f, 0x37, 0xb7, 0x42, 0xbf, 0x78, 0x17, 0xae, 0xc4, 0xee, 0x31, 0x1f, + 0x4a, 0xf7, 0x55, 0xc3, 0x1d, 0x6a, 0xc2, 0xce, 0xb1, 0x0f, 0x61, 0xfb, + 0x58, 0x1d, 0xb1, 0x13, 0x78, 0x3a, 0x63, 0xa2, 0x9f, 0x18, 0x3c, 0x87, + 0x31, 0xe6, 0x95, 0xac, 0xcc, 0xa3, 0xcc, 0x8f, 0x02, 0x4f, 0xa0, 0x9a, + 0x31, 0x4a, 0x7e, 0xcb, 0xb5, 0xb0, 0x8d, 0xed, 0xf9, 0x75, 0x2a, 0x3d, + 0xbe, 0x13, 0xb6, 0xbe, 0x91, 0xcb, 0x88, 0xee, 0x65, 0x4d, 0x68, 0xba, + 0x3d, 0xed, 0xb4, 0xd7, 0xe8, 0x2f, 0xdb, 0xe5, 0x5f, 0x15, 0xec, 0xd2, + 0x5e, 0x53, 0xc3, 0x93, 0x97, 0xf2, 0x5c, 0xb4, 0x96, 0x20, 0x60, 0x3a, + 0x15, 0xf8, 0x99, 0xef, 0xfa, 0x9f, 0x7a, 0xdf, 0xda, 0xda, 0xe5, 0xf5, + 0x9f, 0xe9, 0x6b, 0xb0, 0x72, 0x6f, 0x49, 0x65, 0x3c, 0x2f, 0x41, 0x5c, + 0x93, 0x35, 0xaa, 0x46, 0x8d, 0x5a, 0x79, 0x5f, 0xde, 0x5d, 0x15, 0x2b, + 0x8b, 0x34, 0xc3, 0x3f, 0x5e, 0xe7, 0x7f, 0x2d, 0x21, 0x3a, 0xfd, 0xbd, + 0xe5, 0x36, 0x0c, 0xdf, 0x31, 0xd4, 0xf9, 0x7f, 0x92, 0x79, 0xbb, 0x04, + 0x55, 0x1e, 0x5c, 0x9f, 0xf8, 0xe0, 0x7a, 0x6a, 0x04, 0xca, 0xca, 0x66, + 0x1f, 0x79, 0x3f, 0x9c, 0xab, 0x17, 0x60, 0xda, 0x87, 0x7c, 0x24, 0x02, + 0xf5, 0x74, 0x73, 0x98, 0xb9, 0x7e, 0xfe, 0x7e, 0xce, 0xf2, 0xac, 0xee, + 0x8b, 0x2a, 0xf9, 0x7b, 0x36, 0x9d, 0xa1, 0x3f, 0xd0, 0xae, 0xbb, 0x85, + 0xb3, 0xb0, 0x2f, 0x60, 0x6b, 0xc2, 0xb2, 0x9e, 0xa4, 0x0e, 0xe4, 0x5e, + 0xe0, 0x9b, 0x99, 0xdf, 0x59, 0x93, 0x5e, 0x27, 0x5e, 0x37, 0xa6, 0xb7, + 0x47, 0xae, 0x17, 0x31, 0x19, 0xfb, 0xec, 0x13, 0x75, 0xdc, 0x68, 0xdc, + 0x76, 0x98, 0x79, 0xf2, 0xc2, 0x80, 0xee, 0x4f, 0xe2, 0xff, 0x5a, 0xc2, + 0x0b, 0xd3, 0x4a, 0x71, 0xdd, 0xee, 0xfd, 0x6b, 0x27, 0x55, 0x31, 0x17, + 0xc7, 0x77, 0x28, 0xa1, 0xf7, 0xc7, 0x99, 0xb7, 0x45, 0xbd, 0x88, 0x39, + 0x23, 0x75, 0xfe, 0x9d, 0x09, 0x7b, 0x9c, 0xe6, 0x79, 0xce, 0xdd, 0xe9, + 0xe6, 0x3a, 0x7f, 0x6f, 0x46, 0x6c, 0x50, 0xe1, 0x58, 0x9a, 0xf1, 0x70, + 0x46, 0xc5, 0x9d, 0x0f, 0x78, 0xb1, 0x69, 0xc0, 0x83, 0x6d, 0x03, 0x5f, + 0x82, 0x71, 0x95, 0x13, 0x77, 0x30, 0xf7, 0xdb, 0x3c, 0x50, 0x4a, 0x3d, + 0x6a, 0xd8, 0x32, 0xe0, 0x44, 0xd3, 0x55, 0x55, 0x88, 0xcf, 0x2c, 0xc5, + 0xf3, 0xf4, 0xdd, 0xab, 0x42, 0x15, 0x48, 0xdb, 0x9c, 0x43, 0xb0, 0x41, + 0x78, 0x9b, 0xe8, 0x8d, 0x71, 0xd0, 0x10, 0x0c, 0xf9, 0xa0, 0xf5, 0x99, + 0xdf, 0x58, 0xb9, 0x99, 0x7b, 0x6c, 0x3e, 0xe9, 0x88, 0x88, 0x6e, 0xa4, + 0xae, 0xac, 0x35, 0x79, 0x19, 0x23, 0xdf, 0xa3, 0x47, 0x65, 0x5e, 0x24, + 0x30, 0xb9, 0x4c, 0x71, 0x20, 0x1c, 0xa8, 0x8a, 0x55, 0x47, 0xc2, 0x58, + 0x99, 0xed, 0xf1, 0xf9, 0xec, 0x7b, 0x59, 0x11, 0x9c, 0x5f, 0x62, 0xe2, + 0x96, 0x2c, 0x9c, 0x2b, 0xa9, 0xfb, 0x56, 0xea, 0x75, 0x87, 0xf9, 0x07, + 0x2b, 0x9f, 0xd7, 0xb8, 0x89, 0x97, 0x96, 0xb5, 0x99, 0xfa, 0x65, 0x4e, + 0x81, 0x9f, 0x16, 0xf4, 0x2b, 0x3a, 0xad, 0x18, 0xff, 0x9d, 0x75, 0x9a, + 0xfa, 0x75, 0xb3, 0x3d, 0x37, 0xdb, 0x2b, 0x1b, 0x7f, 0xaf, 0x9e, 0x4b, + 0x29, 0xcf, 0x4a, 0x5b, 0x86, 0xd9, 0x72, 0x2f, 0xc0, 0x1f, 0x55, 0x8a, + 0x3c, 0xf4, 0x4f, 0x8d, 0xe9, 0x25, 0x7b, 0xbd, 0xed, 0xeb, 0x59, 0xcb, + 0x1a, 0x36, 0x45, 0xff, 0x7e, 0xea, 0x5f, 0xd6, 0x5d, 0x64, 0x0e, 0x9a, + 0x10, 0xad, 0xd5, 0xfb, 0x01, 0x49, 0x7c, 0x15, 0xcc, 0x60, 0xae, 0xf5, + 0x8d, 0x76, 0x0f, 0x5e, 0x4b, 0x54, 0xda, 0xe3, 0xbe, 0xaa, 0xc1, 0xb2, + 0xbe, 0x16, 0xf2, 0xe3, 0x4d, 0xa3, 0x31, 0xbc, 0x48, 0xd5, 0x19, 0x13, + 0x64, 0xed, 0x83, 0xba, 0x48, 0xcd, 0xe5, 0x7c, 0x89, 0xcf, 0x63, 0x1b, + 0xed, 0xc9, 0xef, 0x88, 0x00, 0xaf, 0x26, 0x8c, 0xe0, 0x0e, 0xf6, 0x3f, + 0xea, 0x8d, 0x60, 0x7b, 0x4a, 0x6d, 0x75, 0x92, 0x7c, 0x96, 0x31, 0xd7, + 0xdb, 0x85, 0x7f, 0xb5, 0xd2, 0x5e, 0x0b, 0x25, 0x21, 0x89, 0x25, 0xf3, + 0x70, 0x46, 0x73, 0xe0, 0x99, 0xe0, 0x2c, 0x44, 0x6b, 0x1c, 0xe4, 0x33, + 0xaf, 0x5b, 0xff, 0xec, 0x95, 0x7e, 0x64, 0x2c, 0x7f, 0xe0, 0x38, 0x14, + 0x1b, 0xef, 0x76, 0xa6, 0x22, 0xd4, 0xf7, 0xfb, 0xfb, 0xff, 0xbf, 0xd6, + 0x94, 0x57, 0xfa, 0xd7, 0x35, 0x3f, 0xf9, 0xf9, 0xe3, 0x1f, 0xb8, 0xce, + 0x12, 0xe4, 0x78, 0xbf, 0x67, 0x7d, 0xc7, 0x6e, 0xf3, 0x23, 0xa5, 0x79, + 0x5e, 0x2f, 0xed, 0x3d, 0xcd, 0xf1, 0x49, 0x9b, 0xc5, 0x7e, 0x44, 0x6f, + 0x93, 0xa5, 0x82, 0xd7, 0x3b, 0x53, 0xa2, 0x3f, 0xc9, 0x97, 0x4e, 0x5b, + 0x98, 0x25, 0xe7, 0x0f, 0xdb, 0x65, 0xe3, 0xd4, 0x57, 0x0f, 0x6d, 0x88, + 0xb1, 0x81, 0xf1, 0x42, 0xee, 0xb2, 0x6a, 0xc4, 0x5c, 0x0b, 0xdb, 0x19, + 0xb2, 0xd2, 0xde, 0x6a, 0xec, 0x34, 0x69, 0x77, 0x86, 0x3a, 0xdf, 0x09, + 0x0b, 0xa7, 0x4d, 0x39, 0x77, 0x61, 0xca, 0xeb, 0xc0, 0x2e, 0xd3, 0x89, + 0x4e, 0x43, 0xd5, 0xe5, 0xba, 0x23, 0x24, 0xe7, 0x2e, 0xf8, 0x67, 0x2a, + 0xd8, 0x13, 0x56, 0xb1, 0xc5, 0xe8, 0xf1, 0xcb, 0xf5, 0xe5, 0x21, 0x39, + 0x57, 0xb0, 0x91, 0x3a, 0x89, 0x33, 0x57, 0xde, 0xca, 0x76, 0x7b, 0x43, + 0xf9, 0x75, 0xf1, 0x18, 0x2c, 0x6b, 0x8f, 0xd9, 0xf2, 0xe1, 0x0a, 0x96, + 0x3b, 0x67, 0x4a, 0xec, 0x38, 0x70, 0xcb, 0xc2, 0x40, 0x3c, 0x5a, 0x02, + 0x3d, 0x56, 0x46, 0x3f, 0xdd, 0x39, 0x30, 0x8f, 0xf5, 0x04, 0xfb, 0x9d, + 0xbe, 0xdd, 0x90, 0xf5, 0xae, 0x80, 0xff, 0x27, 0xe4, 0xde, 0x69, 0xef, + 0x02, 0x6a, 0xd6, 0xf0, 0xbf, 0xc2, 0x79, 0xab, 0x36, 0x9c, 0xdb, 0x5e, + 0x80, 0xde, 0x59, 0xa6, 0x2c, 0x08, 0x56, 0xc1, 0x85, 0x38, 0xf9, 0xf9, + 0xd8, 0x38, 0xf3, 0xeb, 0x94, 0xa1, 0x1d, 0xb1, 0xd7, 0xcc, 0x3d, 0xd4, + 0x85, 0x87, 0xf1, 0x22, 0xa0, 0x4d, 0x2a, 0xc5, 0xf3, 0x79, 0x82, 0x0d, + 0x31, 0x47, 0x44, 0xf0, 0x2d, 0x6e, 0x3d, 0xd1, 0x4c, 0xd5, 0x19, 0x6e, + 0x7f, 0x2c, 0xe3, 0xe1, 0xa1, 0xf1, 0xf0, 0xfa, 0x37, 0x65, 0x7c, 0xfe, + 0x8d, 0x19, 0xf8, 0xd7, 0x67, 0x8a, 0x76, 0x59, 0xf4, 0x6d, 0xc1, 0x36, + 0xcb, 0x92, 0x7b, 0xc9, 0x8f, 0x67, 0xa5, 0xad, 0x7c, 0x1c, 0x2b, 0xa1, + 0xec, 0x4f, 0xd2, 0xd6, 0x5d, 0x8c, 0x55, 0xbb, 0x8c, 0x38, 0xa1, 0xd2, + 0xb2, 0x0c, 0xf2, 0x99, 0x12, 0xc5, 0x8f, 0x9d, 0x4d, 0xbf, 0xe5, 0x7c, + 0x02, 0x9b, 0x32, 0x01, 0x77, 0x7e, 0x3e, 0xc4, 0xcf, 0x04, 0x03, 0xfc, + 0x8c, 0xbf, 0x3e, 0x7f, 0x0f, 0xfb, 0xd9, 0x9e, 0x99, 0xee, 0x03, 0x0a, + 0x56, 0xb3, 0xad, 0x96, 0x10, 0x9c, 0x2b, 0x9a, 0xfe, 0xcd, 0xca, 0x79, + 0xa7, 0xdf, 0x37, 0x75, 0x33, 0xe6, 0xc2, 0xb9, 0xbe, 0x49, 0xce, 0x15, + 0xb4, 0x84, 0xe5, 0x5c, 0xc1, 0x7a, 0x43, 0xce, 0x89, 0xd9, 0x59, 0x39, + 0xb7, 0xac, 0xcb, 0xe7, 0xef, 0xc7, 0x22, 0x13, 0x77, 0xa5, 0x64, 0xed, + 0x4d, 0xb0, 0xc8, 0xed, 0xff, 0x4e, 0xa6, 0x09, 0x5b, 0x52, 0x72, 0x7f, + 0x8c, 0xb9, 0x86, 0xe1, 0xf1, 0x3f, 0x93, 0xb9, 0x16, 0x77, 0xee, 0x0f, + 0xa3, 0x73, 0x3f, 0x9a, 0xca, 0x38, 0x86, 0xd2, 0x50, 0xc0, 0x7f, 0x14, + 0x9a, 0xff, 0x0c, 0x75, 0x72, 0x8a, 0x72, 0x9e, 0x7e, 0x8f, 0x9c, 0xa2, + 0x43, 0xf8, 0xef, 0x4e, 0xb8, 0x91, 0x09, 0xbd, 0x63, 0xc5, 0xed, 0x5c, + 0xc8, 0xeb, 0xbf, 0x27, 0xe1, 0x47, 0xce, 0xce, 0xc9, 0xde, 0x28, 0x15, + 0xec, 0xee, 0x4b, 0xc5, 0xa3, 0x2a, 0x8a, 0xf3, 0xab, 0x87, 0x65, 0x6e, + 0x5f, 0x4d, 0xc8, 0x7f, 0xd1, 0x2f, 0xa9, 0x8c, 0x4b, 0x2a, 0x73, 0xf9, + 0x41, 0x59, 0xdf, 0x57, 0x4b, 0x45, 0x3f, 0x72, 0x8f, 0x22, 0x2e, 0x39, + 0x63, 0x13, 0xaf, 0x6b, 0x8b, 0x10, 0xab, 0xa1, 0x9e, 0xca, 0x0d, 0xaf, + 0xbf, 0x71, 0xc2, 0xe7, 0x37, 0x27, 0xe0, 0xbf, 0x72, 0x62, 0xba, 0x08, + 0xe4, 0x0a, 0xea, 0x07, 0x61, 0x81, 0xd7, 0xbf, 0x39, 0x31, 0x8f, 0x3c, + 0x33, 0x6e, 0x2d, 0x6f, 0x3e, 0x6f, 0xcd, 0x8b, 0x18, 0xb9, 0xd3, 0x94, + 0xe1, 0x9d, 0x6b, 0xf4, 0xf8, 0x1c, 0xc7, 0xa9, 0xfb, 0xb5, 0x69, 0x7d, + 0x5c, 0x08, 0xfd, 0xff, 0xed, 0xa3, 0x18, 0xe7, 0x68, 0x0f, 0xcd, 0x32, + 0x06, 0x89, 0x77, 0xcc, 0x85, 0x6a, 0x65, 0x2c, 0x81, 0x02, 0x6f, 0x2b, + 0x8e, 0x4b, 0xe1, 0x5c, 0xbb, 0xa9, 0x8b, 0x62, 0x0c, 0xb3, 0xac, 0x5e, + 0xc3, 0x57, 0x58, 0x03, 0xe7, 0x9c, 0x65, 0x4f, 0x7d, 0xd8, 0xc9, 0x9c, + 0xfd, 0x9c, 0xd9, 0xf2, 0x57, 0x4e, 0x44, 0x7d, 0xa5, 0x8c, 0xad, 0xb2, + 0xf6, 0x74, 0xa6, 0x69, 0xca, 0x9a, 0x64, 0x1e, 0xd4, 0x92, 0x95, 0xfb, + 0x4b, 0x0e, 0xda, 0xb7, 0x85, 0x87, 0x4d, 0xf9, 0x5f, 0x70, 0x26, 0x1e, + 0x73, 0xd0, 0x56, 0xdc, 0x86, 0xde, 0xf1, 0x65, 0xa5, 0x8a, 0xae, 0xec, + 0x0c, 0x4e, 0x42, 0x0f, 0x6f, 0x51, 0xe8, 0x87, 0x35, 0x0b, 0x4c, 0x99, + 0x82, 0x37, 0x12, 0x01, 0x33, 0x50, 0x88, 0x4b, 0xe7, 0x38, 0x77, 0x6f, + 0x25, 0x8c, 0xce, 0x27, 0x0b, 0xe7, 0x3f, 0xcb, 0x4c, 0x5f, 0x1f, 0x17, + 0x7b, 0x74, 0xbb, 0xb7, 0x27, 0x70, 0xc1, 0xd1, 0x8c, 0x0b, 0x87, 0xcc, + 0x12, 0x2c, 0x6f, 0x17, 0x3b, 0x75, 0xbb, 0x77, 0x26, 0x30, 0xe5, 0xe4, + 0xb5, 0x73, 0xe6, 0x5c, 0x62, 0x9a, 0xbd, 0x7e, 0x29, 0x31, 0x22, 0xa6, + 0x31, 0xbe, 0x96, 0x47, 0xbc, 0xee, 0xf2, 0x09, 0x68, 0x65, 0xe4, 0x40, + 0xee, 0x08, 0x5a, 0x1d, 0x49, 0xdd, 0xdf, 0xe6, 0x68, 0xc2, 0xaa, 0xac, + 0x9f, 0x3c, 0xfa, 0x05, 0xf2, 0x4e, 0xfb, 0x3e, 0x1f, 0x6d, 0xd2, 0xc9, + 0x0a, 0x43, 0xb3, 0xd4, 0x88, 0xe4, 0x76, 0x55, 0xb8, 0x4b, 0xdb, 0xfa, + 0x11, 0x35, 0x32, 0x88, 0x9b, 0x9a, 0xdd, 0xad, 0xd5, 0x13, 0x45, 0x9d, + 0x20, 0xe6, 0x89, 0x40, 0xab, 0x32, 0xa0, 0x56, 0x46, 0x44, 0x37, 0xfe, + 0xd6, 0xe4, 0xb8, 0xc8, 0xaa, 0xb9, 0x07, 0xc6, 0x7f, 0xe3, 0x46, 0x79, + 0x94, 0x58, 0xf5, 0x43, 0xdf, 0x7f, 0xae, 0xde, 0x33, 0x6e, 0xc1, 0x7b, + 0x97, 0x21, 0xdf, 0xb6, 0x6d, 0x31, 0x1f, 0x19, 0xfb, 0x8c, 0x3b, 0x60, + 0x59, 0x8c, 0x93, 0x3e, 0x28, 0x73, 0x39, 0x1e, 0xfa, 0x1a, 0xe3, 0xd2, + 0xc6, 0xcc, 0x1f, 0xac, 0x8f, 0x3a, 0x6d, 0x0e, 0x40, 0xde, 0xe4, 0xbf, + 0xed, 0x75, 0xe3, 0xf7, 0x96, 0xf0, 0x11, 0x27, 0x7d, 0xba, 0x84, 0x78, + 0xbe, 0xdb, 0x74, 0xb6, 0xad, 0x50, 0x14, 0xf4, 0x19, 0x0b, 0xb4, 0x32, + 0xc6, 0xa9, 0x5e, 0xfa, 0x75, 0xcc, 0x6b, 0x04, 0x0f, 0x81, 0xe5, 0x32, + 0x9b, 0x37, 0xbb, 0x22, 0xf7, 0x7c, 0x76, 0xac, 0x59, 0xb0, 0x60, 0xea, + 0xb6, 0x27, 0x8d, 0x0e, 0xf2, 0xaf, 0xaf, 0x90, 0xa7, 0xe5, 0xfb, 0xc9, + 0x61, 0xde, 0x07, 0xf4, 0xb3, 0x79, 0x73, 0x69, 0x44, 0x78, 0x58, 0xfa, + 0xb6, 0xc3, 0x46, 0x1b, 0x73, 0xb0, 0x7b, 0x3e, 0x7b, 0xae, 0xf9, 0x00, + 0xbf, 0xf3, 0x75, 0xd2, 0xa8, 0xfe, 0xc0, 0x3a, 0x15, 0x11, 0xe9, 0xc3, + 0xcf, 0x3e, 0xee, 0xf9, 0x6c, 0xe7, 0x92, 0x31, 0x6c, 0xcf, 0x6e, 0xfb, + 0x93, 0xfd, 0x54, 0x46, 0x64, 0x3d, 0x34, 0x76, 0xfb, 0xea, 0xc0, 0x3d, + 0x9f, 0xcd, 0x2c, 0x19, 0x64, 0x1f, 0x9f, 0x66, 0x7c, 0xc9, 0xd7, 0x89, + 0x2a, 0x8e, 0x0f, 0xd4, 0x41, 0x59, 0x64, 0xdb, 0xed, 0x0b, 0x03, 0xbf, + 0xb7, 0x16, 0x0c, 0x94, 0xd8, 0x3a, 0x70, 0x51, 0x07, 0x0f, 0x9a, 0xce, + 0x5c, 0xc0, 0x61, 0xeb, 0xa0, 0xcb, 0x47, 0x1d, 0x24, 0xa9, 0x83, 0xdc, + 0x4c, 0x23, 0xfc, 0x36, 0x75, 0xb0, 0x60, 0x7c, 0xf3, 0xe6, 0xb2, 0x08, + 0x9c, 0x0e, 0xe3, 0x47, 0x0e, 0xe6, 0x45, 0xaa, 0xcb, 0xd8, 0x4c, 0xbd, + 0xdd, 0xf3, 0xd9, 0xf9, 0x4b, 0x6c, 0x9d, 0xdf, 0xea, 0x0e, 0xdc, 0x47, + 0xbb, 0x69, 0xa5, 0xad, 0x6f, 0xe5, 0xd1, 0xce, 0xa3, 0x8f, 0x47, 0x02, + 0xbb, 0xb3, 0x1b, 0xa9, 0xab, 0x35, 0x1c, 0xc7, 0x3a, 0xca, 0xd5, 0xc5, + 0xdf, 0x31, 0xfe, 0x8e, 0xf3, 0xb7, 0xcc, 0x8f, 0x7a, 0x49, 0xb6, 0xd8, + 0x25, 0xd9, 0x1c, 0x94, 0xc7, 0x63, 0xaf, 0x55, 0x96, 0x47, 0x8e, 0xdf, + 0xba, 0x3a, 0xd0, 0xc9, 0x36, 0xfe, 0xbf, 0x32, 0xd9, 0x57, 0xe0, 0x32, + 0xe2, 0x3e, 0x27, 0x44, 0x3e, 0xbd, 0xa3, 0x13, 0x39, 0x62, 0xef, 0xef, + 0xf2, 0xd8, 0x4b, 0xd9, 0xaa, 0x38, 0x3f, 0xcf, 0x2d, 0x49, 0xcf, 0xf6, + 0x18, 0xf0, 0xb9, 0x8d, 0x7e, 0x0c, 0x64, 0x47, 0xa8, 0x03, 0xb1, 0x93, + 0x2f, 0x52, 0x7f, 0xdd, 0xac, 0x73, 0x8a, 0xb1, 0x4c, 0x8f, 0xd2, 0x67, + 0x69, 0xb3, 0x7a, 0x98, 0x07, 0xed, 0xe5, 0x51, 0xb6, 0x9b, 0xa6, 0x4c, + 0x25, 0xb4, 0x5f, 0x05, 0x72, 0x0f, 0xf7, 0x0c, 0xdb, 0x3f, 0x6c, 0xfc, + 0xba, 0xe2, 0x14, 0xc7, 0x1e, 0xf5, 0x6e, 0xc6, 0x68, 0x93, 0xe8, 0x2a, + 0x46, 0x5d, 0xe9, 0x3e, 0xff, 0x34, 0x5d, 0x5e, 0x96, 0xf7, 0x0a, 0xf2, + 0x09, 0xcb, 0xfa, 0x89, 0xd1, 0xb2, 0x90, 0x49, 0x21, 0xd2, 0x76, 0xae, + 0x64, 0x59, 0x25, 0xf6, 0xfe, 0xb3, 0xd8, 0xed, 0x1b, 0x0c, 0x91, 0xb7, + 0xb1, 0x7d, 0x3b, 0x8d, 0x73, 0x73, 0x86, 0xfe, 0x1c, 0xf8, 0x9d, 0x15, + 0x9d, 0x29, 0xf5, 0xe6, 0xe1, 0x15, 0xc6, 0xde, 0xa8, 0x16, 0xef, 0x74, + 0x0b, 0xbf, 0x37, 0x9c, 0xe1, 0x35, 0x88, 0x33, 0xa1, 0xd4, 0x83, 0x77, + 0x92, 0x7b, 0x9e, 0x33, 0xf2, 0x7e, 0x7c, 0x24, 0xa3, 0x47, 0x1f, 0xe6, + 0x39, 0x39, 0x30, 0xb9, 0x54, 0x31, 0x4e, 0x05, 0xc9, 0x7b, 0x3d, 0x70, + 0x32, 0x87, 0x6a, 0x75, 0xf4, 0x04, 0x5d, 0xa0, 0x2f, 0x96, 0xcb, 0xb8, + 0xe2, 0x1c, 0xa3, 0xe0, 0xb6, 0x5b, 0xdb, 0x68, 0x63, 0x79, 0x7c, 0xa1, + 0x0b, 0x1e, 0x6d, 0x53, 0xa6, 0x18, 0xe3, 0x3c, 0xda, 0xfa, 0x84, 0xe0, + 0x82, 0xdc, 0x77, 0x0d, 0x53, 0xcf, 0x82, 0x0f, 0xaf, 0xda, 0x7b, 0xd5, + 0x88, 0x11, 0x55, 0x4e, 0x23, 0xdf, 0xae, 0xc6, 0x76, 0xdb, 0x1d, 0x1a, + 0x2e, 0xfb, 0xb8, 0xae, 0xb5, 0x3b, 0x64, 0x1f, 0x1d, 0xd1, 0x2b, 0x53, + 0xa8, 0x97, 0xc7, 0xb9, 0x65, 0x2e, 0x1b, 0xe7, 0xd8, 0x06, 0xf3, 0x8e, + 0xe5, 0x89, 0xf7, 0xf7, 0x2f, 0xfd, 0x49, 0xbf, 0x3d, 0x35, 0x2a, 0x64, + 0x9f, 0x8f, 0xdc, 0x13, 0xeb, 0x64, 0xbe, 0x36, 0x7d, 0xaf, 0x8f, 0x7e, + 0x82, 0xed, 0x1f, 0x8f, 0x73, 0x3e, 0xe7, 0x1a, 0xb2, 0x0f, 0x48, 0xee, + 0xa1, 0x4d, 0xdf, 0xf7, 0x63, 0xdf, 0x9f, 0x2c, 0x17, 0x2e, 0x73, 0x98, + 0x38, 0x19, 0x6d, 0x97, 0xfa, 0x96, 0xf5, 0xe3, 0x05, 0x41, 0xe4, 0x66, + 0x38, 0x31, 0xd2, 0x00, 0x0c, 0x27, 0x45, 0xd7, 0xe9, 0xcf, 0x6c, 0x30, + 0xfe, 0xcd, 0x8a, 0xd6, 0x36, 0x6a, 0xbd, 0xaa, 0xac, 0x67, 0x8c, 0xdd, + 0xda, 0x67, 0xd4, 0x6b, 0x7d, 0x6a, 0xee, 0x18, 0xe3, 0xd0, 0x01, 0xe6, + 0xe8, 0xe5, 0x82, 0x15, 0x35, 0x46, 0xb4, 0xbf, 0x06, 0x0d, 0xf0, 0xdb, + 0xf7, 0x24, 0xf4, 0xf8, 0x37, 0x54, 0x23, 0xb8, 0x56, 0xf8, 0xa7, 0xfa, + 0x8e, 0x95, 0xa6, 0x0d, 0x7c, 0xa1, 0xe1, 0x67, 0x65, 0x79, 0x6c, 0x8f, + 0x76, 0xce, 0xe2, 0xbc, 0xbc, 0xb9, 0x48, 0xf7, 0x67, 0x14, 0xd1, 0x91, + 0x70, 0xae, 0x11, 0xec, 0x62, 0x3c, 0xfe, 0xb7, 0x86, 0x08, 0x8e, 0xf0, + 0xfb, 0xa7, 0xd7, 0xca, 0x1e, 0x37, 0xcb, 0x0a, 0x06, 0x16, 0x84, 0x6b, + 0x38, 0x86, 0x67, 0xf8, 0x7f, 0x7f, 0xf6, 0x75, 0xeb, 0xdc, 0x2c, 0x63, + 0x70, 0x25, 0x83, 0xe2, 0xf0, 0x84, 0xae, 0x4d, 0xa9, 0xff, 0xd9, 0x3d, + 0x37, 0xf6, 0x3a, 0xe3, 0x67, 0x9e, 0x0f, 0x34, 0x6a, 0x49, 0xb5, 0xae, + 0x5c, 0xf4, 0x3a, 0x3c, 0xf1, 0x52, 0x21, 0xce, 0xe7, 0xef, 0x75, 0x3e, + 0x7e, 0x49, 0x3f, 0x72, 0xdf, 0x76, 0x1e, 0x6d, 0x2e, 0x1a, 0xa7, 0xde, + 0xdd, 0x33, 0x38, 0xe6, 0x2f, 0x34, 0xdc, 0x69, 0x8f, 0xb3, 0xd6, 0x98, + 0xc3, 0x31, 0x2a, 0xd0, 0x1a, 0x9c, 0xe5, 0x79, 0xfe, 0xd8, 0x42, 0x96, + 0x96, 0xb6, 0x5a, 0xe9, 0x43, 0x25, 0xac, 0x73, 0xbd, 0x79, 0x70, 0x76, + 0x4f, 0x93, 0xee, 0xfb, 0x02, 0x6d, 0x35, 0xd4, 0xf0, 0x2b, 0x2b, 0xaa, + 0x39, 0xcd, 0xaf, 0x73, 0xd4, 0x77, 0x26, 0xa4, 0xac, 0xcc, 0xab, 0x11, + 0x6d, 0x50, 0xde, 0xb2, 0x30, 0x33, 0x10, 0x6e, 0xb0, 0xc7, 0x0f, 0xdc, + 0x91, 0x19, 0x61, 0xae, 0x2c, 0x6d, 0x2a, 0x58, 0x19, 0x78, 0xc3, 0xf2, + 0xcf, 0x1a, 0xc1, 0xce, 0xec, 0x1f, 0xe3, 0xb0, 0x5f, 0x21, 0x87, 0xd6, + 0x3b, 0xe2, 0x79, 0xbf, 0x6b, 0x03, 0xfb, 0x2d, 0x37, 0xec, 0x3c, 0xfc, + 0xb6, 0x44, 0x40, 0xd6, 0x8c, 0xc6, 0x3e, 0x33, 0x1e, 0x90, 0xbd, 0x19, + 0x5e, 0xe4, 0xda, 0xa5, 0x4c, 0xbd, 0x36, 0x8e, 0x1c, 0x19, 0xa6, 0xec, + 0x23, 0x39, 0x54, 0x9e, 0x5f, 0x47, 0x70, 0xc8, 0x3a, 0xb8, 0xf6, 0x2a, + 0x39, 0x61, 0x9b, 0x21, 0x6d, 0x28, 0x58, 0x18, 0x98, 0x81, 0xc6, 0xb5, + 0x3f, 0x7a, 0xb9, 0x24, 0x90, 0xf7, 0xdb, 0x3e, 0xc3, 0xd8, 0x76, 0x1a, + 0xbf, 0x26, 0x56, 0xc9, 0x3e, 0x93, 0xb4, 0xd4, 0x63, 0x5b, 0x0d, 0xc8, + 0x68, 0x4e, 0x8c, 0x1a, 0xb2, 0x0f, 0xd2, 0xb2, 0x56, 0x07, 0x5e, 0xa3, + 0xdf, 0x51, 0x9e, 0xac, 0xb3, 0x50, 0x57, 0xca, 0x14, 0xf6, 0x70, 0x28, + 0x2d, 0x9f, 0x15, 0x9d, 0x3c, 0x61, 0xc6, 0x99, 0x35, 0x48, 0x7c, 0x18, + 0xfb, 0xcc, 0xeb, 0x86, 0x70, 0x78, 0xdd, 0x5c, 0xa9, 0x54, 0x33, 0xde, + 0x3a, 0xfd, 0x63, 0xf6, 0x7a, 0x86, 0x9f, 0x58, 0x2e, 0x3c, 0x54, 0x72, + 0x43, 0x27, 0x9e, 0x34, 0x6a, 0xf0, 0x84, 0x96, 0xe7, 0x74, 0xc4, 0x44, + 0xbc, 0x90, 0x58, 0x90, 0xa3, 0x87, 0x90, 0x1b, 0x1b, 0x9d, 0x17, 0x95, + 0x5f, 0x33, 0x6f, 0x04, 0x9e, 0xcb, 0x74, 0xe1, 0x41, 0xb9, 0x8f, 0xa5, + 0xd4, 0xb7, 0x35, 0x3a, 0xa4, 0xbf, 0x2e, 0xec, 0xb2, 0xd7, 0x65, 0xc7, + 0x3e, 0x73, 0xd8, 0x78, 0xa4, 0x20, 0xab, 0x60, 0xfe, 0xd8, 0x67, 0x9e, + 0x34, 0x4e, 0xdb, 0x73, 0x27, 0x7b, 0x16, 0xfa, 0x4d, 0xc1, 0xc6, 0x72, + 0xa8, 0xcc, 0x2f, 0x1c, 0xc6, 0xa7, 0xe1, 0xa8, 0x19, 0xa3, 0xed, 0xc9, + 0x7a, 0xcf, 0xed, 0x70, 0xd6, 0xb8, 0xe8, 0x9b, 0x77, 0xc0, 0x55, 0x23, + 0x9c, 0xbe, 0xc8, 0xb7, 0xdb, 0xf8, 0xbf, 0xe8, 0x76, 0xca, 0xd6, 0xad, + 0x93, 0xd8, 0xd3, 0x27, 0xf9, 0x9f, 0x51, 0x4d, 0x1d, 0xe9, 0x1d, 0xb2, + 0xae, 0x5d, 0x49, 0x6c, 0x65, 0x1c, 0x75, 0x57, 0xb3, 0xcc, 0xdb, 0xd4, + 0xfb, 0x82, 0x81, 0x0a, 0x72, 0x7d, 0xcb, 0x7a, 0x87, 0x5c, 0x7f, 0x61, + 0xa0, 0x31, 0x67, 0x30, 0xfe, 0xe1, 0x66, 0xbd, 0x4d, 0xee, 0x11, 0x6f, + 0x30, 0x2e, 0x5a, 0xb1, 0x75, 0x52, 0x46, 0xf7, 0xc5, 0x94, 0x62, 0x1f, + 0x8b, 0xe0, 0x9f, 0x61, 0xc1, 0x15, 0xb1, 0x88, 0x5d, 0xba, 0x19, 0x45, + 0x8b, 0xec, 0xf5, 0x69, 0x97, 0xf1, 0xbb, 0xe4, 0x7e, 0x03, 0xa2, 0x93, + 0x2e, 0x18, 0xb9, 0x23, 0x32, 0x67, 0xb3, 0x2d, 0x04, 0x16, 0xff, 0x8e, + 0x39, 0x93, 0xcc, 0x4f, 0x7d, 0xae, 0x49, 0xc9, 0x05, 0x7d, 0xe4, 0xfe, + 0x8f, 0x40, 0x6f, 0x4f, 0x50, 0xd7, 0xad, 0x21, 0x1b, 0xf3, 0x7c, 0x09, + 0xd8, 0x7c, 0xdf, 0x7c, 0x05, 0x1f, 0x45, 0x25, 0x73, 0xdc, 0x86, 0xf1, + 0x35, 0xa8, 0xaa, 0x89, 0xfa, 0xca, 0xb1, 0x94, 0xe7, 0x5b, 0x99, 0xc7, + 0x7c, 0x12, 0x55, 0x6b, 0x63, 0x48, 0x70, 0xec, 0x95, 0xc6, 0xad, 0xbc, + 0xd6, 0x87, 0x64, 0xca, 0xc5, 0x71, 0xfc, 0xd0, 0xaa, 0x9a, 0x29, 0xb2, + 0x99, 0xde, 0x0a, 0x83, 0x79, 0xb7, 0xad, 0x0b, 0x62, 0x79, 0x4a, 0xb8, + 0x54, 0x63, 0x74, 0x0b, 0xfe, 0x40, 0xdb, 0xd5, 0x3b, 0x36, 0x2a, 0x71, + 0xda, 0x6c, 0x82, 0x3a, 0x97, 0xb2, 0x96, 0xb5, 0x2a, 0xf0, 0x5b, 0xea, + 0x38, 0xce, 0x73, 0xc3, 0xff, 0x1a, 0xd4, 0xa5, 0xa5, 0x38, 0x6b, 0xc5, + 0x35, 0x1f, 0xed, 0x52, 0x5d, 0x27, 0xbc, 0x6b, 0x45, 0x48, 0xad, 0x40, + 0xb9, 0x56, 0xb0, 0xd3, 0x74, 0x41, 0x97, 0x53, 0xb7, 0xf5, 0x19, 0x6f, + 0x94, 0xcb, 0x75, 0x87, 0x7d, 0xdd, 0x5f, 0xb8, 0x9e, 0xe6, 0xf5, 0xf3, + 0xbc, 0x3e, 0x48, 0xdd, 0xab, 0x57, 0x48, 0xfd, 0xcd, 0xa6, 0xd4, 0x27, + 0x1d, 0x31, 0x12, 0x85, 0xf9, 0x88, 0xdd, 0x9e, 0x2f, 0xbb, 0xed, 0xf6, + 0x7c, 0x1b, 0x4e, 0xb6, 0x11, 0x8f, 0x96, 0xc3, 0x44, 0x45, 0x40, 0x70, + 0x5e, 0xe4, 0xe2, 0xdc, 0x65, 0x45, 0xae, 0xad, 0x8c, 0x8b, 0x3d, 0x4f, + 0x97, 0x23, 0xde, 0x35, 0xc7, 0xb6, 0xc3, 0x34, 0x79, 0x8a, 0xee, 0x7f, + 0x5d, 0x69, 0xf1, 0xc9, 0xb2, 0x4e, 0x8a, 0x9c, 0xf7, 0x7e, 0xd3, 0x19, + 0x6e, 0x72, 0x2c, 0xc8, 0x95, 0xc2, 0x88, 0x5d, 0x54, 0x66, 0x57, 0x08, + 0x3e, 0x24, 0x32, 0x2d, 0xcc, 0xd0, 0xe2, 0x41, 0xe6, 0x56, 0xc1, 0x2c, + 0x75, 0xbb, 0x9e, 0x88, 0x7d, 0xc2, 0xde, 0xb3, 0xe4, 0x9c, 0x5c, 0x83, + 0x16, 0xdd, 0x81, 0x05, 0xe1, 0x39, 0xcc, 0xd0, 0x68, 0x97, 0x66, 0xa9, + 0x43, 0xf7, 0xdf, 0x84, 0xff, 0x62, 0xd7, 0x3b, 0x92, 0xc9, 0x75, 0x96, + 0x73, 0x4e, 0xbf, 0x4a, 0x39, 0x76, 0x07, 0x44, 0x8e, 0xb1, 0x82, 0x1c, + 0x31, 0xc6, 0x5c, 0x53, 0xbb, 0x21, 0x30, 0x78, 0x49, 0x6f, 0x4f, 0xdb, + 0x7a, 0xeb, 0xe3, 0x79, 0x29, 0x76, 0x90, 0x3f, 0x9e, 0x6a, 0xf2, 0x16, + 0xd6, 0xf6, 0x25, 0xa7, 0x13, 0xfc, 0x3d, 0xfb, 0xa9, 0x0d, 0x86, 0x1e, + 0x76, 0xd8, 0xfc, 0xdf, 0x8d, 0xb8, 0xcd, 0xad, 0x1d, 0x10, 0xee, 0xf8, + 0xb0, 0x5d, 0xce, 0x45, 0x9d, 0x54, 0xe0, 0x91, 0x82, 0xbf, 0x54, 0x30, + 0xbe, 0x7d, 0xd5, 0xfe, 0x9d, 0xe6, 0xdc, 0xba, 0xe8, 0xab, 0xc5, 0x18, + 0x25, 0xeb, 0x83, 0xfd, 0xb6, 0xef, 0xa7, 0xf1, 0x7d, 0xfb, 0x3b, 0x97, + 0xcf, 0xcb, 0xd0, 0x47, 0x9f, 0x70, 0xb0, 0x8d, 0x5e, 0x7b, 0x2f, 0xaa, + 0xac, 0x15, 0x5c, 0x8b, 0x1d, 0x1c, 0x95, 0xdb, 0xe8, 0x44, 0xbf, 0x26, + 0x36, 0xd1, 0x8d, 0xa4, 0x66, 0x7a, 0xb3, 0x4d, 0xd3, 0x73, 0x2a, 0x13, + 0x87, 0x9a, 0x7e, 0xcf, 0x58, 0x2e, 0xd7, 0xce, 0x5a, 0x87, 0x8d, 0x53, + 0x21, 0x7a, 0x70, 0x67, 0x89, 0xad, 0xdf, 0xa9, 0xdb, 0xec, 0x7d, 0x5b, + 0x94, 0xf9, 0xe9, 0x84, 0xc4, 0xd1, 0x79, 0xc8, 0x98, 0x22, 0x9b, 0xb3, + 0x7d, 0x0f, 0xe7, 0xa4, 0x2f, 0x15, 0x88, 0x5e, 0xc9, 0xff, 0x26, 0x19, + 0xcb, 0x7a, 0xa9, 0xcf, 0x58, 0xbb, 0xf0, 0xb8, 0xad, 0x38, 0x40, 0x1b, + 0x9b, 0x30, 0x2d, 0xeb, 0x08, 0x31, 0xa2, 0x7a, 0x81, 0x8a, 0xdc, 0xcc, + 0xad, 0x48, 0x31, 0x36, 0x1d, 0x31, 0x5a, 0x3e, 0x5a, 0x82, 0xb8, 0x9f, + 0x31, 0xdc, 0xb7, 0x93, 0xa3, 0xb9, 0x9f, 0xf3, 0x75, 0xca, 0x14, 0x7e, + 0xe9, 0xbc, 0xb8, 0x02, 0x46, 0x78, 0x99, 0xe3, 0x87, 0xd6, 0x94, 0xc8, + 0x9e, 0xea, 0xf9, 0x5f, 0x94, 0x61, 0x9b, 0x38, 0x6f, 0x35, 0xe7, 0xf8, + 0xed, 0x80, 0xde, 0xf6, 0x02, 0xfb, 0x69, 0x1c, 0x68, 0xe9, 0x14, 0x19, + 0x0e, 0x87, 0x9c, 0xb1, 0x23, 0x08, 0xb4, 0x6f, 0x55, 0x8a, 0x39, 0x04, + 0x70, 0xe5, 0xb8, 0x89, 0xa3, 0x4d, 0xcf, 0x90, 0xef, 0x48, 0xfd, 0x52, + 0x3c, 0x66, 0x3e, 0x65, 0xd5, 0xcf, 0x7e, 0xde, 0x3a, 0x66, 0xa8, 0x5b, + 0xa8, 0xed, 0x58, 0x25, 0x64, 0x4d, 0x33, 0x7d, 0xdb, 0x5d, 0x01, 0xdd, + 0xdc, 0xc3, 0xb6, 0xce, 0x24, 0x4e, 0x05, 0xdd, 0x6c, 0xeb, 0x11, 0x53, + 0x72, 0x08, 0x67, 0x5b, 0x1b, 0xe7, 0xb6, 0x27, 0x15, 0xf0, 0xc9, 0xba, + 0xad, 0xe4, 0x79, 0xb7, 0x27, 0x64, 0xcf, 0xf8, 0x18, 0xc7, 0x13, 0xdd, + 0xe6, 0x42, 0xcb, 0xfd, 0x55, 0xb4, 0x9f, 0x6a, 0x14, 0x6d, 0x5d, 0xf7, + 0x11, 0xef, 0x70, 0x17, 0xcb, 0xbc, 0x1c, 0x98, 0x87, 0xe7, 0x42, 0x2d, + 0x6b, 0xe7, 0xc1, 0x19, 0x3b, 0xa6, 0x04, 0xda, 0xb6, 0x2a, 0x71, 0x4d, + 0x6c, 0xf1, 0xce, 0x8c, 0x1e, 0x6c, 0x85, 0x60, 0x77, 0x8c, 0xfa, 0x98, + 0x87, 0x77, 0x16, 0x8b, 0x5c, 0xce, 0x70, 0xd0, 0x11, 0xe8, 0x7a, 0x8a, + 0xf3, 0x5b, 0xb5, 0x40, 0x64, 0x07, 0xb2, 0x19, 0x91, 0x3f, 0x86, 0x64, + 0xf6, 0xec, 0xdb, 0x87, 0x0d, 0x38, 0x4f, 0x34, 0x3d, 0x68, 0xc1, 0xde, + 0x63, 0xde, 0x22, 0xf3, 0xd0, 0x21, 0xf3, 0x50, 0x4e, 0x7f, 0x5a, 0x4d, + 0xb9, 0xb7, 0xd8, 0x72, 0xcf, 0xc3, 0xa8, 0x29, 0xeb, 0x64, 0x4e, 0xed, + 0x4e, 0x0c, 0x12, 0x3b, 0x03, 0x17, 0x7b, 0xd8, 0xcf, 0xcb, 0x94, 0x79, + 0x01, 0xf5, 0x3e, 0xd5, 0x2e, 0xfc, 0xb6, 0x0f, 0x03, 0xa9, 0xe2, 0x1e, + 0x74, 0x05, 0x92, 0x7a, 0x4f, 0x39, 0xfa, 0xc8, 0xf7, 0x7a, 0xac, 0xa9, + 0x99, 0x72, 0x3d, 0x8d, 0x1d, 0xa9, 0xa8, 0x46, 0x7f, 0xa0, 0xde, 0xa1, + 0xcf, 0x83, 0x3e, 0xf9, 0xaa, 0x23, 0x4a, 0x1f, 0x30, 0xbd, 0x17, 0x89, + 0x0d, 0x27, 0xd0, 0x65, 0xa1, 0xc6, 0xb6, 0x87, 0x9f, 0x8e, 0x19, 0x0e, + 0x59, 0x6b, 0x0f, 0xe6, 0xa8, 0x03, 0x95, 0x73, 0x22, 0x3a, 0xa8, 0xa4, + 0xcf, 0x8e, 0x07, 0x74, 0xff, 0x73, 0x94, 0x67, 0x0f, 0xe5, 0x59, 0x93, + 0x9f, 0x43, 0xdf, 0x0e, 0x45, 0x7c, 0x3a, 0xd0, 0xbe, 0x81, 0xd7, 0x77, + 0x53, 0x9e, 0xc0, 0x80, 0x82, 0x34, 0xd1, 0xac, 0x8f, 0x7c, 0xf6, 0xc0, + 0x34, 0x79, 0xdc, 0xf6, 0x9c, 0xc5, 0xc9, 0x05, 0x4a, 0x71, 0xd8, 0x14, + 0xfc, 0xd6, 0x30, 0x4a, 0x3b, 0x3d, 0xc4, 0x19, 0x89, 0x7a, 0x55, 0x94, + 0x1a, 0x82, 0x01, 0x33, 0x79, 0xcd, 0xc5, 0xb9, 0xa9, 0xc6, 0x31, 0x2d, + 0xcd, 0x38, 0x59, 0xe4, 0x76, 0x7f, 0xb0, 0x8e, 0x7a, 0x85, 0x9f, 0xc9, + 0x3a, 0x9a, 0xac, 0x35, 0x7d, 0xb9, 0x22, 0xbf, 0xbf, 0x52, 0xf6, 0x3f, + 0xe4, 0xaf, 0x3f, 0xad, 0x09, 0x47, 0x2e, 0x96, 0xff, 0xb9, 0xf5, 0x84, + 0x5d, 0x5e, 0xca, 0xb9, 0x6c, 0x2e, 0x5f, 0x6e, 0x97, 0xfb, 0xb9, 0xf5, + 0x8c, 0xe6, 0x9c, 0x56, 0xae, 0xb8, 0x07, 0xef, 0xd4, 0x97, 0x5c, 0xc4, + 0x3c, 0x47, 0xc3, 0x32, 0x3c, 0x61, 0x9c, 0xad, 0x5f, 0xdf, 0xd4, 0xcd, + 0x38, 0x56, 0xe4, 0x5a, 0x75, 0xf4, 0x2b, 0x0b, 0x43, 0xe6, 0xa9, 0xa1, + 0x12, 0xf4, 0x90, 0x3b, 0x0a, 0x17, 0x10, 0x8e, 0x2a, 0xeb, 0x7c, 0xb7, + 0x96, 0x5f, 0xce, 0x79, 0xf5, 0xa0, 0x5f, 0x6d, 0xb3, 0xb9, 0x61, 0x54, + 0x15, 0xdc, 0xad, 0xb3, 0xc7, 0x7e, 0x39, 0xfe, 0x4b, 0xac, 0x98, 0xbe, + 0x6e, 0xd7, 0x8d, 0x43, 0x46, 0x91, 0xb3, 0x9c, 0x7a, 0x50, 0x25, 0x4e, + 0x0e, 0x9b, 0xcb, 0x24, 0x36, 0xfb, 0x59, 0x3f, 0x18, 0x53, 0xa7, 0x73, + 0x9b, 0xbf, 0xa9, 0x40, 0x55, 0xcf, 0x2e, 0x07, 0x64, 0xff, 0xaf, 0xec, + 0xd9, 0x96, 0xbe, 0xca, 0x0a, 0xeb, 0x57, 0x1f, 0xc4, 0x35, 0x8a, 0x7d, + 0x09, 0xdf, 0xa8, 0x28, 0xca, 0x18, 0x8c, 0xda, 0x72, 0xfe, 0xd2, 0x5a, + 0xab, 0xe5, 0xe6, 0x68, 0x78, 0xaf, 0xec, 0xd1, 0x82, 0xec, 0xb1, 0x0f, + 0x5c, 0x7f, 0x93, 0x7e, 0xa6, 0xb7, 0x59, 0xdc, 0x7b, 0x2a, 0x6b, 0xb3, + 0xf2, 0x9f, 0x82, 0x1e, 0xe2, 0x50, 0x54, 0x6b, 0x61, 0x9c, 0xd7, 0x7d, + 0x9b, 0x38, 0x1f, 0x71, 0xaf, 0xec, 0x6b, 0x2d, 0xc6, 0xc8, 0x52, 0xe4, + 0xd7, 0x48, 0x81, 0x43, 0x85, 0x75, 0x51, 0xda, 0x3d, 0x7a, 0x32, 0xbf, + 0xb3, 0x72, 0x5e, 0x27, 0x63, 0xe1, 0xe5, 0xfd, 0xf7, 0x69, 0xea, 0x75, + 0x94, 0xff, 0xed, 0xb8, 0xb4, 0xee, 0x22, 0x6b, 0x4f, 0x12, 0x7b, 0x7f, + 0x6b, 0xad, 0x7f, 0x4f, 0xd9, 0xe9, 0x7b, 0x5f, 0x67, 0xc6, 0x64, 0x3f, + 0xda, 0xd1, 0xc2, 0xfa, 0x7c, 0xeb, 0xbf, 0xdf, 0x8f, 0x46, 0x5b, 0x42, + 0x74, 0x07, 0xb9, 0x5d, 0x1c, 0x7d, 0x38, 0x9a, 0x68, 0xd4, 0x76, 0x42, + 0x93, 0x75, 0x69, 0x7e, 0xfa, 0x70, 0x2c, 0x81, 0x68, 0xc9, 0x55, 0xd5, + 0xe4, 0x5b, 0x88, 0x3a, 0x64, 0x8f, 0x50, 0xa2, 0xb1, 0x6d, 0x37, 0xc7, + 0xe4, 0x5f, 0xdb, 0x87, 0xd1, 0x44, 0xcb, 0xad, 0x8c, 0x23, 0xfe, 0x8a, + 0x3c, 0xd7, 0xe9, 0x38, 0x4c, 0x1c, 0xd8, 0x5e, 0x58, 0x1b, 0x5b, 0x9f, + 0xf8, 0x15, 0xe5, 0xb7, 0x85, 0x64, 0xbd, 0x3f, 0x56, 0xee, 0x2c, 0x7a, + 0x53, 0x67, 0xb1, 0x79, 0x50, 0x11, 0xfb, 0xc2, 0xa6, 0xb4, 0xc8, 0x73, + 0x16, 0x1b, 0x07, 0xbf, 0x87, 0x43, 0x83, 0xb3, 0xd1, 0x6a, 0xeb, 0xa6, + 0x0b, 0x5b, 0xf7, 0x9e, 0xc4, 0x9e, 0x94, 0x85, 0xdd, 0x21, 0x0f, 0xb6, + 0x1c, 0x54, 0xb0, 0x2a, 0x70, 0x06, 0x3b, 0xf7, 0x5a, 0x98, 0x1f, 0xea, + 0x46, 0x9b, 0x59, 0x81, 0xd2, 0x9a, 0x05, 0x9d, 0x2a, 0xcb, 0xad, 0x1f, + 0xed, 0x52, 0x6e, 0xe4, 0xb8, 0x73, 0xae, 0xe3, 0xc4, 0x02, 0x15, 0x3e, + 0x03, 0x5a, 0x75, 0x24, 0xaa, 0xdc, 0x92, 0x6d, 0x55, 0x3a, 0x46, 0x6d, + 0x3e, 0xa5, 0xdc, 0x94, 0xf5, 0x55, 0x4a, 0x4c, 0x3f, 0x14, 0x3a, 0x8b, + 0x74, 0xba, 0xaa, 0x32, 0xef, 0x2f, 0x67, 0xc9, 0x1d, 0x24, 0xe7, 0x30, + 0x69, 0x53, 0x7f, 0xec, 0xb9, 0x02, 0xb1, 0xbb, 0x29, 0xfc, 0x64, 0xe4, + 0x15, 0xbc, 0x32, 0xf2, 0x2f, 0x58, 0xae, 0x49, 0x9e, 0x69, 0x75, 0x3b, + 0x23, 0x96, 0xb5, 0xbf, 0x39, 0x6e, 0xcd, 0x34, 0x2c, 0xb6, 0x57, 0x85, + 0x59, 0x91, 0xef, 0x62, 0xb7, 0xc6, 0xb6, 0x52, 0xc7, 0xed, 0x7b, 0xb7, + 0xbe, 0xc8, 0xa7, 0xe1, 0x4b, 0xe5, 0xcc, 0x5a, 0x44, 0x87, 0x6a, 0xa1, + 0x6f, 0xab, 0x71, 0x18, 0x5d, 0xff, 0x5b, 0x69, 0xc2, 0x4d, 0xd9, 0x57, + 0xf0, 0xe6, 0x48, 0x37, 0x31, 0x53, 0xef, 0xf8, 0x96, 0x62, 0x75, 0xef, + 0x0e, 0xe9, 0x6d, 0xff, 0x55, 0x89, 0xc6, 0xcb, 0x69, 0x53, 0x65, 0xcc, + 0x09, 0x6e, 0x1e, 0x91, 0x7c, 0xb9, 0x03, 0xee, 0x01, 0x3d, 0xb7, 0x82, + 0x3c, 0xfb, 0x0b, 0x8b, 0xe2, 0x73, 0x66, 0xd0, 0x2e, 0x1d, 0x8a, 0x1e, + 0x34, 0xd4, 0x6e, 0x3c, 0x6e, 0xea, 0x93, 0xbf, 0x75, 0x18, 0xe9, 0x6f, + 0xa2, 0x09, 0xeb, 0xb2, 0x7a, 0x7a, 0x29, 0xf3, 0xb0, 0x9d, 0x49, 0x13, + 0xa9, 0xa4, 0xde, 0xd1, 0xe5, 0xe8, 0xc7, 0xdd, 0x81, 0xfa, 0x6d, 0x6f, + 0x93, 0xcb, 0x79, 0x88, 0x29, 0xc9, 0x89, 0x0c, 0xf3, 0xdc, 0x7e, 0x6c, + 0x3d, 0x18, 0xc1, 0x96, 0xfd, 0x26, 0xfa, 0x92, 0x19, 0xca, 0xf6, 0x1a, + 0x6d, 0xdb, 0xb2, 0xda, 0x43, 0xf1, 0x1b, 0x54, 0x04, 0xa2, 0xec, 0xb3, + 0x45, 0x8d, 0x04, 0xfc, 0xaa, 0xc2, 0xe8, 0x3f, 0xe1, 0x44, 0x2f, 0xcb, + 0x0c, 0xa4, 0x68, 0x73, 0x49, 0x37, 0xe3, 0x65, 0x1d, 0x46, 0xc7, 0x7d, + 0x38, 0x32, 0xee, 0x41, 0x7a, 0x5c, 0xe3, 0x51, 0x8e, 0x87, 0x86, 0x2d, + 0x62, 0xb9, 0x17, 0x8f, 0x1d, 0x76, 0x63, 0xfb, 0x3e, 0x0f, 0xe6, 0x45, + 0x66, 0xe1, 0xf0, 0xe1, 0x72, 0x1c, 0xe0, 0xf5, 0x9a, 0xc5, 0x7e, 0x7c, + 0x8d, 0xd7, 0x07, 0xf7, 0xb9, 0x38, 0x0f, 0xf3, 0x71, 0x9c, 0x86, 0x9d, + 0x1e, 0xaf, 0x40, 0x6a, 0x98, 0x26, 0x4f, 0xce, 0xfa, 0x3a, 0x33, 0x8c, + 0xa3, 0x87, 0x19, 0x1b, 0x0f, 0x9a, 0x48, 0xb0, 0x9f, 0x3d, 0xd4, 0x55, + 0x1f, 0x71, 0x6d, 0xeb, 0xb8, 0x60, 0xfc, 0x3a, 0xac, 0x1e, 0xd0, 0xdb, + 0x5a, 0x15, 0x23, 0xba, 0x44, 0x09, 0xca, 0x73, 0x2b, 0x6e, 0x95, 0xd7, + 0x5a, 0x12, 0xba, 0xd9, 0x8a, 0x6e, 0x9c, 0xe6, 0xb8, 0xff, 0x3b, 0xfd, + 0x76, 0x99, 0x43, 0xef, 0xbf, 0x5e, 0x3d, 0x89, 0xa1, 0x6c, 0x8e, 0x5c, + 0x1d, 0x08, 0x1f, 0x3a, 0x49, 0xfe, 0xf6, 0x38, 0xf1, 0xe7, 0x65, 0xcb, + 0x67, 0xa8, 0xb8, 0xe9, 0x01, 0x23, 0x7c, 0x41, 0x09, 0x6c, 0xfb, 0x25, + 0x75, 0x70, 0xe3, 0x61, 0x15, 0x1f, 0x1b, 0x5a, 0x86, 0x4c, 0x28, 0x8a, + 0x3d, 0x4b, 0x54, 0xdc, 0x70, 0xf0, 0x24, 0x71, 0xff, 0xac, 0xcd, 0x93, + 0x73, 0x99, 0x2f, 0x22, 0x38, 0x20, 0x6b, 0xf7, 0x6e, 0xc6, 0xef, 0x4a, + 0x9c, 0x19, 0xec, 0xa6, 0xdf, 0x56, 0xe2, 0x54, 0xfa, 0x24, 0xed, 0xb1, + 0x12, 0x8f, 0x0f, 0x1a, 0x93, 0x3f, 0x71, 0x54, 0xe2, 0x31, 0x9e, 0x0f, + 0xf1, 0x7c, 0xf1, 0xb0, 0x31, 0xd8, 0xa5, 0x56, 0x62, 0xd1, 0xa1, 0x66, + 0x0c, 0x26, 0xc5, 0x36, 0x35, 0x6c, 0x1b, 0x6f, 0x2a, 0xe8, 0x5e, 0x74, + 0xee, 0xc5, 0x3d, 0xd4, 0xd5, 0xdd, 0x43, 0xdd, 0xec, 0xcf, 0x47, 0x9d, + 0x9f, 0xc4, 0x43, 0xcc, 0xeb, 0x76, 0x27, 0x7d, 0x38, 0x9f, 0x32, 0xfc, + 0x9f, 0x52, 0x0c, 0xb3, 0x4c, 0x09, 0x68, 0x67, 0xe0, 0xc3, 0x2b, 0xd9, + 0x72, 0xf4, 0x0e, 0xd7, 0xe1, 0x27, 0xb4, 0xcf, 0x07, 0xf7, 0x9d, 0xb4, + 0xed, 0xff, 0x40, 0x6a, 0x2e, 0x1e, 0x1b, 0x33, 0xd9, 0xb6, 0xcc, 0x93, + 0xc3, 0xde, 0xdb, 0xe4, 0x4a, 0x89, 0x6f, 0x44, 0x87, 0x68, 0x16, 0xc4, + 0xc4, 0x93, 0xc8, 0x0e, 0xea, 0xfd, 0x37, 0xab, 0xc2, 0xab, 0x55, 0xea, + 0xd2, 0x81, 0x29, 0x4d, 0x8f, 0xd7, 0xa8, 0xf1, 0x41, 0xe6, 0xaf, 0xf1, + 0x5a, 0xea, 0xe4, 0xb1, 0x41, 0x27, 0x16, 0x2c, 0x56, 0x79, 0x3d, 0x7e, + 0x91, 0xb1, 0x2d, 0x3e, 0x4f, 0x35, 0x71, 0xc0, 0x96, 0x15, 0xf1, 0x12, + 0x72, 0xfb, 0xea, 0xc5, 0xf5, 0x8c, 0x5f, 0x0e, 0xb1, 0xbd, 0x58, 0xa5, + 0xea, 0xa4, 0xde, 0x5f, 0xc1, 0x18, 0xed, 0xfa, 0x11, 0x1e, 0xc7, 0x47, + 0xac, 0xee, 0x55, 0xe4, 0xdc, 0xf3, 0x03, 0x56, 0xf7, 0xcd, 0xa6, 0xe1, + 0x2b, 0x51, 0x03, 0xd1, 0x2f, 0xe0, 0x15, 0x1c, 0x1b, 0x93, 0x32, 0xb2, + 0x0f, 0x24, 0x86, 0x91, 0xa4, 0xd5, 0x3d, 0x64, 0xce, 0x47, 0xb3, 0x9d, + 0x1b, 0xbb, 0x2a, 0xf3, 0x98, 0x29, 0x7e, 0x24, 0x6b, 0x25, 0x53, 0xf8, + 0x25, 0xdb, 0xb9, 0x30, 0x52, 0x8d, 0x19, 0xb5, 0xe2, 0x07, 0x67, 0xf1, + 0xc6, 0xe0, 0x77, 0x71, 0x7e, 0xd0, 0xc2, 0xa2, 0x90, 0x05, 0x67, 0xa8, + 0xd1, 0x6c, 0x55, 0x97, 0x12, 0x23, 0x14, 0xac, 0x6e, 0xf8, 0x1e, 0xde, + 0x1a, 0x94, 0xfd, 0xa6, 0x96, 0x2d, 0xcb, 0x00, 0x16, 0x5b, 0x7b, 0x66, + 0x8a, 0xdf, 0x48, 0xbd, 0x3f, 0x95, 0x07, 0xeb, 0x8c, 0x86, 0xc5, 0x5c, + 0xf8, 0x15, 0x8c, 0x8e, 0x18, 0xd1, 0xcd, 0x45, 0x39, 0x07, 0x5f, 0xa1, + 0x0e, 0xec, 0xf8, 0x74, 0xb0, 0x06, 0x0b, 0x2e, 0x32, 0x6b, 0xfc, 0xf0, + 0x3c, 0xda, 0xce, 0xa2, 0xc5, 0x01, 0x73, 0xa5, 0xfa, 0x6f, 0xf4, 0xd3, + 0x57, 0x70, 0x24, 0x5d, 0xc4, 0x6b, 0x1f, 0x5a, 0xe9, 0xe7, 0xf9, 0x7d, + 0xfe, 0x5e, 0xb4, 0xa4, 0x4e, 0xd8, 0xeb, 0x0f, 0xc7, 0x89, 0x8f, 0x83, + 0x29, 0x29, 0xa3, 0x61, 0x2c, 0xdb, 0x4a, 0x6c, 0x88, 0xe2, 0x9f, 0xb2, + 0x11, 0xe2, 0x43, 0x98, 0xf8, 0xd0, 0x4c, 0x7c, 0x30, 0x89, 0x0f, 0x4d, + 0xc4, 0x87, 0x20, 0xf1, 0xc1, 0xb0, 0xd7, 0xd6, 0xd3, 0x47, 0xbf, 0x8b, + 0x92, 0xe1, 0xb3, 0x70, 0xd1, 0x07, 0xce, 0x98, 0x16, 0xf9, 0x49, 0xa3, + 0xb6, 0x11, 0xf3, 0x95, 0xa8, 0xe6, 0x45, 0x9a, 0xed, 0x95, 0x0d, 0x6b, + 0x1c, 0x8b, 0x85, 0x60, 0xa8, 0x3e, 0xdc, 0x4f, 0xac, 0xfe, 0x95, 0xd1, + 0xd8, 0xef, 0x45, 0xe3, 0x81, 0x99, 0x30, 0x06, 0x17, 0xab, 0x0d, 0x4a, + 0xf4, 0xe3, 0x5e, 0x8e, 0xb3, 0x16, 0x73, 0xf7, 0x69, 0x98, 0xc7, 0xe3, + 0x1f, 0x53, 0xf5, 0x93, 0x2f, 0x3b, 0xe0, 0x9d, 0x4d, 0xba, 0x33, 0x87, + 0x4c, 0x80, 0xac, 0xd6, 0xeb, 0xc3, 0x95, 0xc7, 0x5f, 0x51, 0x15, 0xe4, + 0x3e, 0x2e, 0x31, 0xaf, 0x31, 0xd8, 0xa7, 0xaa, 0xb2, 0x96, 0x44, 0x0c, + 0xe7, 0xa1, 0x22, 0x42, 0x16, 0x51, 0xc7, 0xfc, 0xc2, 0xda, 0x68, 0x96, + 0x61, 0x47, 0x13, 0x39, 0xa7, 0x57, 0x3f, 0x21, 0x31, 0x6a, 0x36, 0x63, + 0x44, 0x79, 0x32, 0x7e, 0xe7, 0x6c, 0x78, 0x50, 0x96, 0xb4, 0xac, 0xaf, + 0x86, 0x34, 0x78, 0x22, 0x81, 0xe8, 0x56, 0xa6, 0x91, 0x1f, 0x5f, 0x10, + 0xc6, 0xea, 0xec, 0x09, 0x0c, 0x73, 0x7c, 0xab, 0xb2, 0xc5, 0x67, 0xc5, + 0xfe, 0xf8, 0xe7, 0xf2, 0x33, 0x67, 0x57, 0x1e, 0x98, 0x0d, 0x43, 0xbb, + 0x57, 0x1d, 0xae, 0x22, 0x07, 0x3f, 0xce, 0xb8, 0xa7, 0x4c, 0x7d, 0x42, + 0x41, 0xc7, 0x70, 0x1c, 0x33, 0x42, 0x2f, 0x28, 0xb1, 0x5a, 0xdd, 0xef, + 0x57, 0x6a, 0xf1, 0x89, 0x7d, 0xd4, 0xf5, 0xa2, 0x1f, 0x7a, 0xe4, 0xb9, + 0xb0, 0x6f, 0x1e, 0x15, 0xdd, 0xd6, 0xa7, 0x87, 0x38, 0x8e, 0xc9, 0x86, + 0x13, 0x82, 0x93, 0x8f, 0xba, 0xe1, 0x78, 0x74, 0x16, 0xa2, 0x68, 0x6a, + 0xb8, 0xb2, 0xeb, 0x5f, 0x54, 0xd1, 0x8b, 0xf0, 0x6b, 0x7d, 0x30, 0xae, + 0x18, 0xda, 0xcf, 0x95, 0x13, 0xf6, 0x7d, 0xb8, 0xaf, 0x66, 0x4f, 0x52, + 0x97, 0xc7, 0x0b, 0xf9, 0xd2, 0x3a, 0x24, 0x06, 0x64, 0x5f, 0xfe, 0x59, + 0xcc, 0x1d, 0xd6, 0xdb, 0x77, 0x29, 0x46, 0xf0, 0x06, 0xe5, 0x2c, 0xe6, + 0x0c, 0x07, 0x39, 0x97, 0x1a, 0x56, 0x26, 0x8b, 0xf8, 0x29, 0x18, 0xbc, + 0x8e, 0x18, 0x6c, 0x2d, 0xfb, 0x89, 0x19, 0xd7, 0x65, 0x4f, 0x82, 0x53, + 0xd1, 0x3b, 0x1a, 0x94, 0x38, 0x63, 0xa8, 0x71, 0x71, 0x3d, 0xeb, 0x78, + 0x86, 0x9b, 0x70, 0x3b, 0xc7, 0xdc, 0xc6, 0x79, 0xfb, 0xee, 0x62, 0x0b, + 0x4b, 0x16, 0xeb, 0x07, 0xca, 0x1c, 0xd1, 0x7b, 0x6b, 0x90, 0xeb, 0x9a, + 0x49, 0xbb, 0xb9, 0x7b, 0x91, 0x1e, 0x7e, 0x81, 0xb8, 0x4b, 0x9c, 0x46, + 0x2f, 0xe3, 0xce, 0x46, 0xc6, 0xa2, 0xf2, 0x88, 0xde, 0xcf, 0x1c, 0xf5, + 0xc2, 0x1d, 0x8e, 0x68, 0x48, 0x9e, 0xff, 0xf8, 0x32, 0x96, 0xc1, 0x1d, + 0xaa, 0x22, 0x0e, 0xea, 0xb9, 0xef, 0x42, 0x3f, 0x70, 0x3b, 0xfa, 0xf1, + 0x03, 0xf2, 0xbb, 0x99, 0x57, 0xe5, 0x88, 0x51, 0x19, 0x3c, 0x98, 0x3d, + 0x89, 0x03, 0xd9, 0x47, 0xb1, 0x37, 0xbb, 0x5b, 0x49, 0xdb, 0xf7, 0x20, + 0x15, 0x79, 0xee, 0x26, 0x5a, 0xa5, 0x7c, 0x06, 0x95, 0xa1, 0xaf, 0x5b, + 0xe9, 0x1a, 0x15, 0xd5, 0xa1, 0x20, 0x56, 0x27, 0xe3, 0x70, 0x44, 0xde, + 0xb6, 0xe4, 0xb9, 0xcf, 0x2d, 0x13, 0x06, 0xae, 0x4f, 0x96, 0x23, 0x76, + 0xc8, 0xb2, 0xfa, 0x9b, 0x9d, 0xd8, 0x34, 0xd1, 0x84, 0x95, 0xc3, 0x0f, + 0x59, 0xf3, 0x18, 0x73, 0xde, 0xbd, 0xc6, 0x83, 0x3b, 0x0e, 0x79, 0xb0, + 0x3e, 0x19, 0x85, 0x2f, 0x52, 0xc1, 0xdf, 0x01, 0x73, 0x39, 0x8c, 0xc9, + 0x49, 0x18, 0xfd, 0xd7, 0x39, 0x02, 0xc7, 0xc2, 0xaa, 0x07, 0x7f, 0x4d, + 0x1c, 0x5f, 0x45, 0xdc, 0x89, 0x4d, 0x58, 0xa8, 0x8e, 0x78, 0x71, 0x27, + 0xeb, 0x7f, 0x8c, 0x73, 0xff, 0xd6, 0x92, 0xe3, 0xc4, 0x02, 0x23, 0x36, + 0xa1, 0x68, 0xd8, 0x3a, 0xe1, 0xa6, 0xae, 0xdc, 0x88, 0x1d, 0xa9, 0xc5, + 0xf5, 0xfb, 0xfc, 0xb8, 0x63, 0xc2, 0x83, 0x96, 0xa4, 0xb5, 0xec, 0xb8, + 0x19, 0x5f, 0xab, 0xc1, 0xc0, 0xfa, 0x09, 0x2f, 0x6e, 0x4b, 0xea, 0xbe, + 0x1b, 0x98, 0xf3, 0x8f, 0x99, 0x41, 0xfc, 0xed, 0x84, 0x0f, 0xb7, 0x24, + 0x4f, 0x49, 0x1e, 0xb9, 0xdc, 0xc9, 0xd8, 0x73, 0xff, 0x44, 0x1d, 0xd6, + 0x26, 0xf5, 0x8b, 0x93, 0xe4, 0x76, 0xdd, 0x47, 0x4c, 0xdc, 0x3b, 0xa1, + 0xa2, 0x83, 0xed, 0x7c, 0x22, 0x39, 0x17, 0x5d, 0x47, 0x9a, 0x29, 0xc3, + 0x62, 0xac, 0x1a, 0x76, 0xc2, 0x24, 0x8b, 0xc7, 0x27, 0x81, 0x76, 0xfa, + 0x47, 0x22, 0xf5, 0x45, 0xec, 0x19, 0x30, 0x71, 0xd7, 0x84, 0x9c, 0x9f, + 0xb4, 0x9f, 0x95, 0xbb, 0x70, 0x70, 0x31, 0x6e, 0x1c, 0x56, 0x89, 0x03, + 0xa5, 0x48, 0xaf, 0x55, 0x70, 0x1b, 0xaf, 0xef, 0x4a, 0xd9, 0x7b, 0xab, + 0x11, 0x1a, 0x0a, 0x1c, 0xab, 0x21, 0x67, 0x58, 0x72, 0x30, 0x7f, 0xfd, + 0x41, 0xe2, 0x7c, 0x19, 0x71, 0xbe, 0x82, 0x1c, 0xf6, 0xba, 0xd1, 0x93, + 0x78, 0x80, 0xb8, 0x7c, 0x62, 0xb8, 0x9b, 0x71, 0xa7, 0x12, 0x5f, 0x63, + 0x1c, 0x48, 0xf2, 0xfc, 0xec, 0x90, 0xd1, 0x55, 0x46, 0x9c, 0x7e, 0x81, + 0xf8, 0xdb, 0x4f, 0xcc, 0xb8, 0x3b, 0x49, 0xb7, 0x1f, 0x62, 0x0e, 0x70, + 0x55, 0x74, 0xa1, 0x87, 0x39, 0xd6, 0x0d, 0x4a, 0xc0, 0xf7, 0x1a, 0x2a, + 0xe1, 0x38, 0x58, 0x8b, 0x96, 0x7d, 0x52, 0x46, 0xf0, 0x4b, 0x85, 0x7a, + 0xd8, 0x49, 0x9d, 0x9f, 0x84, 0x35, 0xe8, 0xe0, 0x78, 0xeb, 0x4d, 0x32, + 0x70, 0xfc, 0xd8, 0xd4, 0xb5, 0x7f, 0x22, 0xd6, 0xbe, 0x43, 0x4c, 0xf5, + 0xcf, 0x6e, 0x46, 0xab, 0x61, 0xf2, 0x38, 0x89, 0x57, 0x06, 0x0d, 0xf3, + 0x10, 0x9c, 0x78, 0x99, 0x3c, 0x6f, 0x6a, 0x36, 0x63, 0xa6, 0x21, 0x7e, + 0x98, 0xe1, 0x78, 0x54, 0xc9, 0x4b, 0xe0, 0x18, 0x07, 0xde, 0x38, 0xb8, + 0x8c, 0xe3, 0x92, 0x58, 0x2a, 0xf1, 0x2e, 0x43, 0x59, 0x97, 0x61, 0x0d, + 0xf5, 0xd1, 0x9a, 0x54, 0x91, 0x39, 0x12, 0xc1, 0x5d, 0xfb, 0xf3, 0x71, + 0x78, 0x5b, 0x28, 0x7e, 0x33, 0xe3, 0x70, 0xb8, 0x9c, 0x71, 0xd8, 0x15, + 0x11, 0xd9, 0x9c, 0x18, 0x65, 0xdc, 0xde, 0x91, 0x0a, 0xa3, 0x8d, 0x73, + 0x38, 0x99, 0x61, 0xbf, 0xc9, 0x3a, 0x9c, 0xc9, 0x78, 0x18, 0xb3, 0x34, + 0x1e, 0x44, 0xb5, 0xb1, 0x59, 0x3c, 0xfc, 0x3c, 0xe6, 0xf3, 0x30, 0xec, + 0x6b, 0x1b, 0x93, 0x0a, 0xe2, 0xed, 0x8a, 0xcd, 0xe7, 0xcf, 0x64, 0x04, + 0x9b, 0x65, 0x2d, 0x73, 0x7b, 0x95, 0x3c, 0x8b, 0x32, 0x98, 0xfa, 0x1e, + 0xaa, 0xa9, 0xff, 0xaa, 0x02, 0x0e, 0xfd, 0x34, 0x24, 0xb8, 0x5b, 0x4f, + 0xdc, 0x95, 0xe7, 0x04, 0x2c, 0x6b, 0x5d, 0x60, 0x3a, 0x1e, 0xfd, 0x9f, + 0x77, 0xa3, 0xf6, 0x33, 0x17, 0x82, 0x49, 0xc4, 0xbf, 0x14, 0xf1, 0x8f, + 0x63, 0xe8, 0xb9, 0x96, 0x18, 0x48, 0x99, 0xfe, 0x21, 0x45, 0x0c, 0x24, + 0x4e, 0x3f, 0x4a, 0x9c, 0xfe, 0x06, 0x71, 0xfa, 0xeb, 0xc4, 0xe9, 0xaf, + 0x11, 0x13, 0xf2, 0x6b, 0x7a, 0x6d, 0x72, 0xff, 0x85, 0xf3, 0xf1, 0x96, + 0xbd, 0xb6, 0x38, 0x93, 0xba, 0x9a, 0x3b, 0xac, 0x60, 0x9e, 0xa1, 0x1f, + 0x13, 0xbb, 0xff, 0x01, 0xe7, 0xc9, 0x3f, 0xa3, 0xce, 0x7e, 0x26, 0xa6, + 0x35, 0xd9, 0x07, 0x77, 0xb2, 0x51, 0xeb, 0x87, 0xfd, 0x2c, 0xb2, 0x29, + 0x5c, 0xb4, 0x24, 0xb9, 0x11, 0x8e, 0x64, 0xe3, 0xb1, 0xd3, 0x72, 0x9f, + 0x77, 0x96, 0xe4, 0xf5, 0x1b, 0xe1, 0x4c, 0xea, 0xc7, 0xe2, 0x94, 0x65, + 0x25, 0xff, 0x73, 0x25, 0x1b, 0xcd, 0xd7, 0x60, 0x63, 0x9b, 0x7f, 0xca, + 0xfe, 0xaf, 0xfe, 0xc2, 0x03, 0xd4, 0x57, 0x8e, 0x6d, 0x66, 0xa8, 0xfb, + 0x72, 0xf2, 0x95, 0x47, 0xb2, 0xf2, 0xbb, 0xb1, 0x23, 0xa1, 0x1e, 0x43, + 0x6c, 0xa6, 0xf0, 0xf1, 0x30, 0x6e, 0x4a, 0x7a, 0x68, 0x07, 0x71, 0x54, + 0xd1, 0xb7, 0x3e, 0x37, 0xd1, 0x4c, 0x5f, 0x7b, 0xc8, 0xd2, 0x22, 0x81, + 0x8e, 0x09, 0x72, 0x9e, 0x2d, 0x13, 0xcb, 0xb0, 0x62, 0xd8, 0xb2, 0x3c, + 0x4b, 0x8d, 0xf0, 0x56, 0xc5, 0x0f, 0x17, 0x7d, 0xd0, 0x41, 0xbf, 0xda, + 0x7c, 0x28, 0xa0, 0xbd, 0x46, 0x3c, 0xed, 0x6c, 0x3e, 0x41, 0xfb, 0x30, + 0x2e, 0xb6, 0x11, 0x4b, 0x9d, 0x91, 0x00, 0xf3, 0x44, 0x0f, 0x6d, 0xdf, + 0x8b, 0x8b, 0x09, 0xf1, 0x2f, 0xbd, 0xeb, 0x9f, 0x98, 0x9b, 0x74, 0xd1, + 0x37, 0x7e, 0x9e, 0xa8, 0xa3, 0x0f, 0xb8, 0xf1, 0x46, 0xc2, 0xa0, 0xbf, + 0x79, 0xf0, 0x56, 0xa2, 0x89, 0x7d, 0x05, 0x59, 0xc6, 0x8f, 0x7b, 0x26, + 0xc2, 0xf4, 0xb3, 0x6b, 0x79, 0xc8, 0x73, 0x99, 0xf5, 0xf1, 0x6f, 0x2a, + 0xf5, 0x83, 0x73, 0xd5, 0x1a, 0x44, 0x6b, 0x35, 0x7c, 0x7e, 0xe2, 0x23, + 0xf8, 0x57, 0xc6, 0xed, 0x4d, 0x49, 0x70, 0x0e, 0x11, 0x22, 0x0f, 0x9c, + 0x3c, 0x22, 0xf7, 0x1c, 0xd1, 0x18, 0x6d, 0x70, 0xe8, 0xcc, 0x6d, 0xf5, + 0xdc, 0x79, 0x87, 0x93, 0x7d, 0x92, 0x15, 0xb3, 0xec, 0xcf, 0x07, 0xcb, + 0x71, 0xef, 0xa1, 0x13, 0xf4, 0x91, 0x12, 0x2c, 0x7a, 0xc0, 0x8d, 0xcf, + 0x1f, 0xc9, 0x90, 0x3b, 0xa8, 0x90, 0xfd, 0xbc, 0x69, 0x12, 0x85, 0x39, + 0xa3, 0x11, 0xdc, 0xb9, 0x3f, 0x83, 0xe1, 0x02, 0xcf, 0x0b, 0x85, 0xe2, + 0xff, 0x43, 0xc5, 0x09, 0xf2, 0x88, 0x40, 0xe7, 0xd5, 0xb4, 0xb1, 0xaa, + 0x48, 0x20, 0x2e, 0xe3, 0x6e, 0xa7, 0x8d, 0xf5, 0x71, 0x3e, 0x33, 0x1c, + 0x47, 0x82, 0x36, 0xf6, 0x55, 0xca, 0xbf, 0x87, 0x36, 0x16, 0xa7, 0x8d, + 0xc5, 0x69, 0x4f, 0x71, 0xda, 0x98, 0x3c, 0xfb, 0x1b, 0xa7, 0x8d, 0xc5, + 0x69, 0x63, 0xf1, 0xcc, 0x32, 0x1c, 0x25, 0xd3, 0xd8, 0x39, 0xd6, 0x4c, + 0x1c, 0x53, 0xec, 0xa8, 0x94, 0xbb, 0xf9, 0x23, 0xe4, 0xec, 0xd7, 0xf1, + 0x50, 0xd0, 0x46, 0x9f, 0xec, 0x4f, 0x67, 0xc8, 0x79, 0xdc, 0xf8, 0x75, + 0x56, 0x38, 0x7e, 0x33, 0xf3, 0xd8, 0x93, 0xe4, 0xf9, 0x2a, 0x9e, 0x30, + 0x25, 0x0f, 0x36, 0x79, 0xce, 0x58, 0x93, 0x12, 0xbe, 0x76, 0x12, 0x77, + 0x0f, 0x02, 0x37, 0x90, 0x17, 0xd6, 0x92, 0x97, 0x1c, 0x5e, 0xc4, 0xdf, + 0x07, 0x4f, 0xd0, 0xe6, 0x4f, 0xda, 0x7b, 0xbb, 0x54, 0xb6, 0x75, 0x66, + 0xb0, 0xde, 0x77, 0x3d, 0x7d, 0xf0, 0x7e, 0xd6, 0x75, 0x1e, 0x94, 0x3a, + 0x27, 0xd8, 0xb6, 0x1e, 0xfe, 0x35, 0xe7, 0xbf, 0xe3, 0x81, 0x5a, 0xbc, + 0xb1, 0x5f, 0x0f, 0xbf, 0x43, 0xcc, 0xab, 0x75, 0x58, 0xcb, 0xae, 0x0e, + 0x05, 0xb6, 0x5d, 0xad, 0xe6, 0xf9, 0x5e, 0xfb, 0x90, 0x13, 0xc7, 0x42, + 0xcb, 0xe0, 0x59, 0x54, 0xe4, 0x7c, 0xb4, 0xa5, 0x5a, 0xe1, 0x58, 0x7a, + 0xf8, 0x3c, 0xb9, 0x4a, 0x92, 0xed, 0x1f, 0xcd, 0x3c, 0x4e, 0x0c, 0xf9, + 0x22, 0x9e, 0x63, 0x7e, 0x3e, 0xf6, 0xa1, 0x97, 0xc9, 0x1d, 0xdd, 0x18, + 0x27, 0x07, 0x3c, 0x3e, 0x18, 0xfd, 0xa8, 0x93, 0xb8, 0xef, 0x59, 0x54, + 0x89, 0x4c, 0x5a, 0xb8, 0x62, 0x25, 0x9e, 0x19, 0x34, 0xb4, 0x1b, 0x94, + 0x3c, 0x2f, 0xcc, 0xef, 0xfd, 0x32, 0x2e, 0x8e, 0x22, 0x30, 0x79, 0x9e, + 0xdc, 0xf0, 0x9d, 0xb4, 0xc4, 0xb0, 0x93, 0xf4, 0x71, 0x3f, 0xc2, 0x49, + 0x0d, 0x27, 0xc6, 0x0d, 0x2c, 0x4c, 0x7a, 0xf1, 0xf0, 0x78, 0x10, 0x57, + 0xd3, 0x77, 0xb3, 0xe4, 0x87, 0x1f, 0x4a, 0x8a, 0x2f, 0xd6, 0x61, 0x62, + 0xbc, 0x8e, 0x3e, 0x22, 0xbc, 0xfc, 0x67, 0xf0, 0xd4, 0x9e, 0xb5, 0xf7, + 0x36, 0x8f, 0xa6, 0xf4, 0xfe, 0x18, 0xc7, 0x13, 0xf3, 0xea, 0xc7, 0x62, + 0xd0, 0xd3, 0xc0, 0x87, 0xdf, 0x4d, 0x7f, 0x52, 0xe2, 0xa3, 0xf8, 0xa3, + 0x86, 0x09, 0xf2, 0x9d, 0x52, 0x62, 0x6a, 0x79, 0xa4, 0xfe, 0xc2, 0xf7, + 0x15, 0x3d, 0xf7, 0x94, 0x6a, 0x59, 0xdf, 0x5b, 0xac, 0xc1, 0x77, 0x44, + 0x23, 0xf7, 0x30, 0xed, 0xe7, 0x62, 0xe4, 0x79, 0xf3, 0xd9, 0xfb, 0x6a, + 0x31, 0x63, 0x5f, 0x12, 0xff, 0xad, 0x36, 0xfe, 0xd1, 0x59, 0x8c, 0xf3, + 0xb3, 0x64, 0x7f, 0x76, 0xf2, 0xf4, 0x6c, 0xb9, 0x57, 0x34, 0xa9, 0x36, + 0x76, 0x1c, 0x83, 0x7e, 0xec, 0x15, 0x45, 0xf7, 0x7d, 0x95, 0xb1, 0xc1, + 0x45, 0x1b, 0x75, 0x4c, 0x68, 0xf4, 0xdd, 0xc6, 0x13, 0x33, 0x60, 0xc4, + 0xaf, 0x51, 0x5d, 0x16, 0x6c, 0x79, 0x6e, 0xa8, 0xca, 0xe7, 0x45, 0x82, + 0x3b, 0x12, 0x17, 0xc8, 0x17, 0x89, 0xc1, 0x9d, 0xf4, 0x97, 0x35, 0x76, + 0x2c, 0x3a, 0x61, 0xef, 0xfd, 0xde, 0x3a, 0x11, 0xa7, 0x8f, 0x2c, 0x43, + 0xc5, 0xb0, 0x07, 0x9f, 0xb3, 0xe3, 0xd0, 0x43, 0x56, 0x0d, 0xfd, 0xe5, + 0xae, 0x43, 0x81, 0xce, 0xeb, 0xe9, 0x2f, 0xf5, 0x4b, 0x25, 0x86, 0x31, + 0x6e, 0xa7, 0x0c, 0x73, 0x94, 0xd8, 0xf2, 0x50, 0xb3, 0x31, 0xf9, 0x32, + 0xf2, 0x3e, 0xb3, 0x6b, 0xa0, 0x16, 0x7f, 0xff, 0xc0, 0x71, 0x7b, 0x2d, + 0xe4, 0x4e, 0x9e, 0x27, 0x07, 0x7c, 0xb6, 0x7f, 0xc4, 0xf8, 0xfb, 0x1e, + 0xc6, 0xbc, 0x18, 0xfd, 0x68, 0xe7, 0x80, 0xb5, 0xec, 0xf9, 0xc5, 0xf1, + 0xb5, 0x55, 0x08, 0x32, 0x26, 0xb9, 0xd1, 0x3f, 0xa0, 0x0f, 0x76, 0x30, + 0x06, 0x9d, 0x5d, 0x6c, 0x52, 0x16, 0x0f, 0x86, 0x06, 0x04, 0x53, 0x4f, + 0xdd, 0x52, 0x8b, 0xf8, 0xff, 0xd0, 0x38, 0xbe, 0xcf, 0xd9, 0xf7, 0x08, + 0xeb, 0xb0, 0xe9, 0xc8, 0x52, 0xca, 0xdc, 0x44, 0x1f, 0x64, 0x5e, 0xcd, + 0x7c, 0x67, 0xc3, 0x7e, 0xf1, 0x0b, 0xb4, 0x48, 0x9e, 0xd6, 0x6d, 0x06, + 0xcc, 0x57, 0xe9, 0x43, 0x25, 0xe4, 0x3a, 0x0f, 0xa6, 0xec, 0xe7, 0x73, + 0x72, 0x15, 0x46, 0x18, 0x8b, 0x69, 0xa3, 0x25, 0x86, 0x0f, 0x33, 0xc8, + 0xeb, 0x16, 0x72, 0x3e, 0xca, 0xb2, 0x1e, 0x80, 0x1c, 0x02, 0xc4, 0x27, + 0x1c, 0x25, 0x08, 0x1e, 0xf5, 0xf3, 0x98, 0xcf, 0x83, 0x8a, 0xc8, 0xaa, + 0x98, 0x79, 0x94, 0x75, 0x47, 0x33, 0xb6, 0x2d, 0xfe, 0x3d, 0xe7, 0x3d, + 0x41, 0x5b, 0xff, 0x04, 0xb1, 0x7e, 0x72, 0x2f, 0xd0, 0x7f, 0x30, 0x6f, + 0xdb, 0x29, 0xb6, 0xdf, 0x4e, 0xcc, 0xbb, 0x40, 0x9b, 0xed, 0xe3, 0x7c, + 0x0f, 0x8d, 0x18, 0xc1, 0x46, 0x35, 0xa0, 0x4d, 0x70, 0x9e, 0x7b, 0xc6, + 0x54, 0x0c, 0x0c, 0x2e, 0xc3, 0x28, 0xf3, 0xa0, 0xde, 0xb4, 0xf8, 0x88, + 0x94, 0x39, 0x89, 0x6e, 0xfa, 0xc8, 0x2f, 0x17, 0x2b, 0x88, 0x7d, 0x5c, + 0xf6, 0xbe, 0x3b, 0x99, 0xef, 0x7f, 0x11, 0x9b, 0x12, 0x8f, 0x5b, 0x95, + 0x86, 0xde, 0x9f, 0x56, 0x99, 0x67, 0xd1, 0x36, 0x7b, 0x98, 0x9f, 0x2c, + 0x67, 0x7e, 0xd2, 0x5b, 0xb0, 0xcb, 0x33, 0xb4, 0xc3, 0x01, 0xc6, 0xb1, + 0x97, 0xd3, 0xf9, 0xb8, 0xf7, 0x83, 0x21, 0x3f, 0x16, 0x5e, 0x53, 0x89, + 0xa7, 0x0f, 0xe6, 0x65, 0xdb, 0x4b, 0x9b, 0x7c, 0x8a, 0x7a, 0xbe, 0x83, + 0x7a, 0x7d, 0x29, 0x25, 0x18, 0x15, 0xc4, 0x33, 0xe4, 0xd1, 0x5b, 0xc8, + 0x05, 0xbe, 0x97, 0xca, 0xdb, 0xe4, 0xe7, 0x27, 0xd6, 0x68, 0xf9, 0xf8, + 0xe0, 0x85, 0xba, 0x4f, 0xf6, 0x00, 0x5a, 0xd6, 0x72, 0x33, 0xd7, 0x49, + 0x5e, 0xc3, 0xb6, 0x23, 0xe4, 0x46, 0x4e, 0xcc, 0x49, 0x46, 0xb0, 0x22, + 0x55, 0xdf, 0xd6, 0x20, 0x9b, 0x3d, 0xe6, 0xe4, 0x39, 0xa0, 0x2b, 0x29, + 0xef, 0x0e, 0xd0, 0x50, 0xc1, 0xdc, 0xe9, 0xaf, 0x0b, 0xef, 0x2b, 0xf8, + 0xc4, 0x9f, 0xc1, 0x1d, 0xd7, 0x50, 0xa6, 0x14, 0xb9, 0xe3, 0x54, 0xe1, + 0x7d, 0x05, 0x37, 0xdb, 0xef, 0x2b, 0x70, 0x63, 0xc6, 0x84, 0xd3, 0xf9, + 0xa9, 0x94, 0x07, 0xb3, 0x27, 0x2e, 0x71, 0x50, 0x77, 0x49, 0xa4, 0x15, + 0x4f, 0x26, 0x14, 0xcc, 0x32, 0xfe, 0x27, 0xbe, 0x6f, 0xaf, 0x09, 0xd4, + 0xda, 0x7b, 0xf6, 0x5d, 0x91, 0x28, 0x0e, 0x27, 0xf4, 0xb6, 0xc7, 0x78, + 0x5e, 0x46, 0x3c, 0xad, 0xda, 0xa7, 0xe0, 0xa9, 0x80, 0x17, 0xa5, 0x47, + 0x64, 0xaf, 0xbb, 0x65, 0x39, 0x17, 0xaf, 0xb2, 0x76, 0xac, 0x13, 0xfb, + 0xe6, 0x1c, 0x1e, 0x09, 0x54, 0x09, 0x06, 0x1e, 0x36, 0x65, 0xdd, 0xd2, + 0x40, 0x5f, 0xa2, 0x96, 0xfc, 0xba, 0xbe, 0xb3, 0x15, 0xf5, 0xe6, 0xcf, + 0x1c, 0xb5, 0x28, 0x39, 0x72, 0x87, 0x26, 0x6b, 0xf6, 0xdf, 0xe0, 0x9c, + 0xf5, 0x12, 0xbb, 0x7a, 0x52, 0xf9, 0xf8, 0xd9, 0x9a, 0xb1, 0xaa, 0x45, + 0x2f, 0xbd, 0xe4, 0x27, 0x6a, 0xf2, 0xa2, 0x5d, 0xa6, 0x22, 0x92, 0x23, + 0xfe, 0xd4, 0xe1, 0x04, 0xf9, 0x82, 0xc4, 0xd2, 0x0a, 0x1e, 0x95, 0xe4, + 0x8d, 0x3f, 0x67, 0x2c, 0xbd, 0x27, 0x94, 0x0b, 0xca, 0x9b, 0x2c, 0x6a, + 0xc8, 0xc5, 0xe9, 0x03, 0x38, 0x12, 0xd2, 0xdb, 0x37, 0x38, 0xa2, 0x4f, + 0x33, 0x07, 0x0b, 0x2f, 0x63, 0x4e, 0xbe, 0x2a, 0x90, 0xc1, 0x2e, 0xf2, + 0xc0, 0x9d, 0xcc, 0xc5, 0x3b, 0x68, 0x9b, 0x9d, 0xfb, 0x19, 0xdb, 0x1c, + 0x97, 0x73, 0x71, 0x2d, 0x14, 0xdf, 0x40, 0x0e, 0xd0, 0xe5, 0x51, 0xc5, + 0x5e, 0xc5, 0x77, 0x02, 0x1d, 0xaf, 0x12, 0xa3, 0x1b, 0x19, 0x37, 0xc4, + 0xde, 0xf7, 0xa4, 0xf4, 0x4e, 0x2a, 0xa0, 0xa6, 0x92, 0xb9, 0xe3, 0xbd, + 0xe3, 0xcd, 0xf4, 0x9b, 0xfc, 0x33, 0x73, 0xce, 0x25, 0x75, 0xcc, 0x39, + 0xaf, 0x43, 0xef, 0x10, 0xed, 0x9f, 0xbe, 0x74, 0xff, 0x00, 0xc8, 0xcf, + 0xd4, 0x9d, 0x9c, 0xbf, 0xdc, 0x11, 0x04, 0x2e, 0xb6, 0xa3, 0xb1, 0xad, + 0xc4, 0x21, 0x32, 0xe8, 0xed, 0x6f, 0x90, 0xa7, 0x75, 0x31, 0x3f, 0xdd, + 0xc2, 0x5c, 0x3e, 0xc6, 0x5c, 0x3e, 0xc6, 0x7a, 0xa9, 0x21, 0xb9, 0x4f, + 0x64, 0xb4, 0x9f, 0x61, 0xfe, 0xf3, 0x39, 0xf2, 0x9f, 0xa1, 0x07, 0x44, + 0xae, 0x59, 0xb8, 0xf7, 0xf0, 0x75, 0x48, 0xd2, 0x9e, 0xee, 0xe1, 0xb5, + 0x81, 0x07, 0xe6, 0xe3, 0x6e, 0xe6, 0xf1, 0xb1, 0xf1, 0x65, 0x18, 0x64, + 0x26, 0xba, 0xed, 0xf0, 0x47, 0xd0, 0x43, 0x3e, 0xb5, 0x9c, 0x18, 0xbd, + 0xe1, 0x60, 0xc6, 0xc6, 0x6c, 0xc1, 0xfc, 0x1f, 0x67, 0x80, 0xd7, 0xc8, + 0xc9, 0x06, 0x53, 0x27, 0x6c, 0x9e, 0xe6, 0x62, 0x7c, 0x28, 0x25, 0x2e, + 0x85, 0xf7, 0x1b, 0x5d, 0x2b, 0x55, 0x6b, 0x59, 0xd9, 0xe2, 0x40, 0xff, + 0x1b, 0xf4, 0xd5, 0x9a, 0x23, 0x2a, 0x6a, 0x87, 0x25, 0x57, 0x27, 0x3f, + 0x22, 0x46, 0x3f, 0x47, 0x8c, 0xae, 0x3c, 0x94, 0xcf, 0xcb, 0x13, 0xcc, + 0xbb, 0x6a, 0x8d, 0x7c, 0x6e, 0xbe, 0x67, 0x40, 0xf6, 0xe8, 0xb8, 0xf1, + 0x1d, 0xda, 0xfe, 0xa9, 0x82, 0xed, 0x9f, 0x2e, 0x60, 0xb0, 0xc5, 0xdc, + 0xfc, 0x35, 0x1b, 0x7f, 0xf3, 0xb9, 0xf9, 0xc2, 0x61, 0xa3, 0x2b, 0x4c, + 0x8c, 0xbe, 0xfa, 0x90, 0xf4, 0xaf, 0xa1, 0x96, 0x78, 0x32, 0x93, 0x58, + 0x52, 0x35, 0x2c, 0xeb, 0x33, 0x81, 0xce, 0x09, 0xd5, 0x67, 0xf7, 0xb1, + 0x9d, 0xb2, 0xf5, 0xd2, 0x07, 0xbe, 0x9a, 0x30, 0xb4, 0xad, 0x4a, 0xc0, + 0x5c, 0x4d, 0x7d, 0x1e, 0xc9, 0x5c, 0x87, 0xce, 0xc1, 0x3a, 0x1c, 0x4b, + 0x4b, 0x7c, 0x91, 0xf6, 0x25, 0x17, 0x77, 0xe2, 0x9d, 0xfd, 0x73, 0xf1, + 0xce, 0xd8, 0xe5, 0x3c, 0x7c, 0x47, 0x2a, 0x7a, 0x3f, 0xc3, 0xeb, 0x2a, + 0xc9, 0xc3, 0xbf, 0xc7, 0x3c, 0xfc, 0x0d, 0x45, 0xd6, 0x10, 0x55, 0x7c, + 0x62, 0x91, 0x83, 0xf1, 0x45, 0xf7, 0x7f, 0xd7, 0x11, 0x97, 0xfb, 0xc8, + 0xfe, 0x07, 0xf8, 0xff, 0xb3, 0x8c, 0xe7, 0xc3, 0x9c, 0x89, 0x68, 0xad, + 0x03, 0x4f, 0x2f, 0x8e, 0x47, 0x65, 0x9d, 0xb4, 0x9f, 0x3c, 0x65, 0x0e, + 0xe3, 0xe1, 0xdf, 0xa7, 0xea, 0xc3, 0x0b, 0x1d, 0x0e, 0x5c, 0x34, 0xf5, + 0xf6, 0x03, 0xbc, 0xf6, 0x4c, 0x56, 0x7c, 0x31, 0x4c, 0xfc, 0x5a, 0x59, + 0xf0, 0xc5, 0x5a, 0x94, 0xd3, 0xce, 0xe7, 0xd2, 0x5e, 0x7f, 0x9c, 0xd2, + 0x07, 0x9f, 0xa1, 0x9d, 0xd6, 0x5e, 0xb2, 0x53, 0x59, 0xa3, 0x95, 0xbc, + 0xa6, 0x9d, 0x79, 0xcd, 0xf4, 0xe7, 0xa5, 0x8f, 0xa3, 0x2f, 0x7b, 0x1f, + 0xee, 0xdd, 0xab, 0x77, 0x39, 0x1d, 0x71, 0x4b, 0x33, 0xba, 0x99, 0xa3, + 0x75, 0x23, 0xb0, 0xc8, 0xe8, 0xb8, 0xa0, 0xe8, 0x9d, 0x3f, 0x54, 0xca, + 0x99, 0xf3, 0x9d, 0xc1, 0xf6, 0x51, 0x3d, 0x98, 0x51, 0x0c, 0xdc, 0x40, + 0x8c, 0x7b, 0x78, 0xa4, 0x84, 0x76, 0xb8, 0x1e, 0x47, 0x06, 0xf5, 0x70, + 0x1c, 0x26, 0x31, 0xb4, 0xde, 0x5f, 0xa6, 0x5c, 0xc0, 0x69, 0xf3, 0x2c, + 0xb6, 0x67, 0xe7, 0x60, 0xbd, 0x26, 0x7b, 0x9a, 0xd6, 0x63, 0x62, 0xf0, + 0x02, 0x71, 0xa8, 0x9d, 0xdc, 0x4a, 0xf2, 0x06, 0x0b, 0x7b, 0x42, 0x57, + 0x63, 0x8b, 0xed, 0xbf, 0xa5, 0xf2, 0x4e, 0x0b, 0xcf, 0x3c, 0xc3, 0x20, + 0x4e, 0x48, 0x6e, 0xee, 0x9b, 0xb6, 0x3f, 0x57, 0xd6, 0x75, 0x1b, 0xab, + 0xf2, 0xf7, 0x95, 0xff, 0x58, 0x99, 0x29, 0x1c, 0x1a, 0x91, 0xf5, 0x85, + 0x19, 0xca, 0xe3, 0x83, 0x0d, 0xbe, 0x1e, 0xc6, 0x8f, 0xfb, 0xcd, 0x1c, + 0x5e, 0x5f, 0x5c, 0x86, 0x29, 0xaf, 0x82, 0xd0, 0xd5, 0x61, 0xe9, 0x83, + 0x9f, 0x73, 0x96, 0xff, 0x93, 0xd2, 0xce, 0x82, 0xc2, 0x9a, 0xc3, 0x3b, + 0x35, 0x8c, 0x55, 0x3c, 0x97, 0xe7, 0x03, 0xe5, 0xbc, 0x78, 0xfd, 0x47, + 0x56, 0xd4, 0x2b, 0xd7, 0x89, 0xd9, 0xb3, 0xc4, 0x7f, 0x67, 0x28, 0x77, + 0x12, 0x6f, 0xe7, 0x87, 0x66, 0x28, 0xeb, 0xd3, 0xc5, 0x3a, 0x2f, 0x22, + 0x3b, 0xf2, 0x22, 0xe7, 0x53, 0x0f, 0x4e, 0xc1, 0x55, 0x78, 0x56, 0x5e, + 0xf6, 0x81, 0xb9, 0xc8, 0x43, 0x65, 0x2d, 0xfe, 0x1c, 0x86, 0xf6, 0x0b, + 0x6f, 0xb4, 0xac, 0x40, 0xc3, 0x39, 0x6c, 0x3f, 0x7a, 0x42, 0xe9, 0x48, + 0xbd, 0x6b, 0xa1, 0x74, 0x46, 0x6c, 0x8e, 0xbd, 0xdf, 0x59, 0xda, 0xe8, + 0x53, 0xda, 0xb3, 0x81, 0xf0, 0xfd, 0x0c, 0xbe, 0x5a, 0x44, 0x9e, 0x63, + 0x97, 0xb1, 0x9d, 0xe0, 0x35, 0xc3, 0x7e, 0x66, 0xe8, 0xb8, 0x3d, 0xce, + 0xf7, 0xeb, 0xe1, 0x9b, 0x56, 0xb4, 0x5d, 0xea, 0x16, 0xe5, 0x9a, 0xcf, + 0x89, 0x16, 0xd9, 0x8a, 0xff, 0x8f, 0x17, 0x64, 0x2f, 0x25, 0x77, 0xce, + 0x97, 0xe9, 0xa4, 0xec, 0x25, 0xa1, 0x28, 0x4e, 0x35, 0x4f, 0x97, 0xbf, + 0x38, 0xd6, 0x83, 0xef, 0x69, 0x2f, 0x5f, 0xf6, 0xe3, 0xb5, 0xb2, 0x4f, + 0xea, 0x54, 0xf3, 0x24, 0xfe, 0xce, 0x5e, 0xd7, 0x78, 0xd3, 0xde, 0xdf, + 0xb9, 0xcb, 0x6c, 0x89, 0x96, 0xe1, 0xa3, 0x50, 0xaf, 0x8a, 0x2f, 0x2c, + 0xb3, 0xf9, 0x76, 0xb4, 0xbd, 0x8c, 0x39, 0xb7, 0xdb, 0x88, 0xde, 0xef, + 0x46, 0x2e, 0x47, 0x9e, 0xd0, 0x71, 0x51, 0x39, 0xa6, 0xdc, 0x11, 0xd0, + 0xb7, 0xbd, 0x4d, 0xfe, 0xf3, 0x6c, 0x20, 0xce, 0x39, 0x37, 0x7c, 0x03, + 0x8a, 0x6e, 0x6e, 0x62, 0x8c, 0x7d, 0x86, 0x39, 0xed, 0xc6, 0x40, 0xbf, + 0x7d, 0xcf, 0x53, 0x89, 0xac, 0xc1, 0x95, 0xf6, 0xfb, 0x26, 0xda, 0x61, + 0x64, 0x5e, 0x94, 0x35, 0x38, 0xfe, 0x8e, 0x61, 0xa1, 0x7d, 0x6d, 0x23, + 0x82, 0xf6, 0xf7, 0xba, 0xc2, 0x3b, 0x29, 0x3a, 0x50, 0x6f, 0x7f, 0x7f, + 0x1a, 0x0d, 0x99, 0x4b, 0x6b, 0xd5, 0xe8, 0x35, 0x2d, 0xeb, 0x49, 0x53, + 0x9e, 0x57, 0xbb, 0xb4, 0xb7, 0x7c, 0x8d, 0x83, 0x39, 0x10, 0x21, 0x25, + 0x96, 0x7f, 0x27, 0xcf, 0xe5, 0xe7, 0xc5, 0x56, 0xbc, 0x67, 0x6f, 0xb9, + 0xfd, 0xac, 0x93, 0xfd, 0xce, 0xa5, 0x05, 0x4b, 0x9c, 0xf8, 0x4e, 0xa2, + 0x2a, 0xe6, 0xe1, 0xef, 0xed, 0x4b, 0x4a, 0xb0, 0x25, 0x44, 0x0e, 0x7a, + 0xd5, 0x19, 0x9c, 0xcf, 0x38, 0x71, 0x26, 0x11, 0x0f, 0x8d, 0xb1, 0xbf, + 0x53, 0x09, 0x15, 0xa7, 0x47, 0xfa, 0x42, 0x87, 0xec, 0xbe, 0x5f, 0x45, + 0xef, 0x51, 0xb9, 0x0f, 0xd9, 0x8e, 0x0d, 0x89, 0xf3, 0x8c, 0xbb, 0xd2, + 0x96, 0xac, 0x05, 0xe8, 0xb9, 0x8d, 0xcc, 0x9f, 0x55, 0x47, 0x10, 0xb7, + 0x30, 0xde, 0x3d, 0x97, 0xe8, 0x86, 0x6b, 0xb1, 0xde, 0xf5, 0x2d, 0x72, + 0x96, 0xaa, 0x88, 0x1e, 0x7c, 0x4b, 0xe9, 0x20, 0x37, 0x74, 0x63, 0x32, + 0x21, 0x7e, 0x21, 0xef, 0xac, 0xf9, 0x34, 0x8e, 0x91, 0x23, 0x3f, 0x9b, + 0xd0, 0x70, 0xbe, 0xd9, 0x83, 0x0c, 0x39, 0xf3, 0x77, 0x12, 0x6e, 0x7c, + 0x95, 0x9c, 0xf9, 0x91, 0x11, 0x59, 0xb3, 0x6c, 0x45, 0x4b, 0x42, 0xd6, + 0xab, 0xc9, 0x03, 0xc7, 0xbc, 0xb4, 0x6d, 0xcb, 0xea, 0x35, 0x67, 0xd3, + 0x9f, 0xce, 0xb2, 0x4f, 0x59, 0xe7, 0x8c, 0x62, 0x35, 0x79, 0xd0, 0x23, + 0x63, 0x3e, 0x3c, 0xcf, 0x5c, 0x21, 0xc9, 0x7a, 0xcf, 0x25, 0xfc, 0x18, + 0xc8, 0xf8, 0xf0, 0x14, 0x73, 0x86, 0x9d, 0x3c, 0x97, 0xf7, 0x1f, 0x95, + 0x18, 0x41, 0xf2, 0xf2, 0x93, 0xa8, 0x18, 0xb8, 0x02, 0x9b, 0xd7, 0x3e, + 0x0a, 0x75, 0xe0, 0x04, 0x8f, 0x6b, 0xc9, 0x21, 0xae, 0x45, 0x6a, 0x24, + 0x82, 0xd4, 0xd8, 0x8b, 0xe8, 0x1f, 0x91, 0x71, 0xc9, 0x7b, 0x6c, 0x64, + 0x0f, 0x12, 0xb9, 0xe7, 0x80, 0x17, 0xe9, 0x31, 0xe9, 0xa7, 0x96, 0x7d, + 0xff, 0xb9, 0xed, 0xff, 0xab, 0xb5, 0xf9, 0x13, 0xd2, 0xf6, 0xa3, 0x7f, + 0xa4, 0x7d, 0xd1, 0x95, 0xac, 0xbd, 0xb4, 0x17, 0xd6, 0x5e, 0xdc, 0x6c, + 0xd3, 0x03, 0x47, 0x24, 0xb7, 0xb6, 0x12, 0x7a, 0x74, 0xb7, 0x62, 0xb4, + 0x55, 0x28, 0xe7, 0xb1, 0x3b, 0x2b, 0xef, 0x45, 0x28, 0xc5, 0x53, 0xc4, + 0x6b, 0x57, 0x48, 0xd7, 0xbe, 0x45, 0xdb, 0x59, 0x4e, 0x8c, 0x7b, 0xd5, + 0xbc, 0x1a, 0x71, 0x4d, 0xf4, 0x57, 0x8a, 0x17, 0x06, 0xdd, 0xc4, 0xa6, + 0x08, 0xf2, 0xcf, 0xc8, 0x79, 0xf0, 0x83, 0x84, 0x97, 0xf3, 0xd5, 0x98, + 0x33, 0x1c, 0x0d, 0xf2, 0x0c, 0x9e, 0x7d, 0xed, 0x54, 0x62, 0x23, 0x0e, + 0x51, 0xde, 0xe7, 0x12, 0x17, 0x39, 0x3f, 0x9d, 0xd4, 0xbf, 0xe8, 0x3b, + 0x5e, 0xd0, 0x75, 0x1f, 0x75, 0x5d, 0x87, 0x67, 0x12, 0x5f, 0xc4, 0x23, + 0x94, 0xff, 0xe1, 0x41, 0x23, 0x3a, 0x5f, 0x39, 0x49, 0xfc, 0x2e, 0xc5, + 0x69, 0xb6, 0x7d, 0x07, 0x33, 0xf7, 0x29, 0xe9, 0x2b, 0x25, 0xeb, 0xa5, + 0x0a, 0xde, 0x5a, 0x72, 0x12, 0x13, 0xfc, 0xef, 0x07, 0x83, 0xf2, 0x1c, + 0x5a, 0x35, 0xfb, 0x10, 0xfd, 0xf8, 0xed, 0xdc, 0xa4, 0x87, 0xbc, 0x6b, + 0x55, 0xf3, 0x49, 0xec, 0x4a, 0xcb, 0xb5, 0xf5, 0xe8, 0x1f, 0xbc, 0x00, + 0x47, 0xa8, 0x04, 0x77, 0x78, 0x9b, 0x69, 0xeb, 0x39, 0xec, 0xce, 0x34, + 0xcf, 0xc8, 0x73, 0xe2, 0xaa, 0x19, 0xf2, 0x4c, 0xd6, 0xa9, 0x44, 0x29, + 0xbe, 0xc3, 0x3a, 0x9b, 0x89, 0x15, 0xf9, 0x7b, 0x38, 0xe4, 0xfe, 0xc4, + 0xfa, 0x0c, 0xfb, 0x48, 0xd8, 0x6d, 0xcc, 0x50, 0x0e, 0xd0, 0x0f, 0xab, + 0x17, 0xcf, 0x50, 0x52, 0x69, 0xc9, 0x35, 0x5e, 0xc4, 0x13, 0x0f, 0xe4, + 0x75, 0x78, 0xc8, 0xdc, 0x88, 0x74, 0xa6, 0xba, 0xd0, 0xde, 0x4b, 0x85, + 0x7b, 0x6d, 0xf2, 0x3c, 0x88, 0x51, 0x78, 0x17, 0xc0, 0xe5, 0x7b, 0x6c, + 0xdf, 0xc8, 0x56, 0x91, 0xcf, 0x97, 0xd3, 0xd6, 0x4a, 0x62, 0x5e, 0xc6, + 0xf9, 0x8d, 0x8b, 0x34, 0xec, 0x5d, 0xfa, 0xd9, 0x5a, 0x54, 0x69, 0xce, + 0x5f, 0x35, 0xbf, 0xc8, 0x7e, 0xaa, 0x62, 0x35, 0x91, 0x47, 0xec, 0x7d, + 0x59, 0xa1, 0xa5, 0x33, 0x19, 0xe7, 0xe4, 0x5e, 0x75, 0x0c, 0xaf, 0x27, + 0x6a, 0x63, 0xb5, 0x91, 0x6a, 0xe6, 0xf6, 0x17, 0x30, 0x30, 0xea, 0x44, + 0x15, 0x79, 0x7c, 0x65, 0xb2, 0x16, 0x6e, 0x7b, 0x5d, 0xf1, 0x0a, 0xf2, + 0xa7, 0xb9, 0xe4, 0x48, 0x75, 0xa8, 0x26, 0x4f, 0xf2, 0x84, 0x2c, 0xeb, + 0xa7, 0x8b, 0x2d, 0xeb, 0x4a, 0x1e, 0x65, 0x3c, 0xce, 0x85, 0xc4, 0x4f, + 0xa3, 0x68, 0xb4, 0xfd, 0xd5, 0x40, 0x93, 0xfd, 0xdd, 0x4a, 0x5f, 0xef, + 0x0a, 0x2d, 0x9c, 0xf8, 0x62, 0xa8, 0x61, 0x62, 0x26, 0xd4, 0xe1, 0x59, + 0x70, 0xb0, 0xad, 0x8f, 0x2f, 0xb5, 0xd0, 0x6a, 0xca, 0xfb, 0x04, 0x84, + 0xa7, 0x6d, 0x24, 0x4f, 0xeb, 0x0f, 0x19, 0x13, 0x8f, 0xe2, 0x7a, 0xc6, + 0x5d, 0xf7, 0xb0, 0x8f, 0xfd, 0x48, 0xce, 0xef, 0xcc, 0xcd, 0x23, 0xff, + 0xbf, 0x7a, 0xb1, 0x70, 0xb6, 0x0e, 0x79, 0x97, 0x08, 0x3a, 0x26, 0x4e, + 0xe2, 0x26, 0x96, 0xf1, 0x0c, 0xbf, 0x84, 0x64, 0xf6, 0x47, 0x18, 0xc8, + 0x4a, 0x3c, 0xc9, 0xe1, 0x06, 0xb6, 0x5d, 0x3e, 0xdc, 0x46, 0xae, 0xba, + 0x06, 0x9b, 0x27, 0x2c, 0xac, 0x0a, 0x4d, 0x62, 0xd5, 0x04, 0x39, 0xf0, + 0x44, 0xd1, 0x5f, 0x85, 0xbf, 0xad, 0x81, 0x3c, 0x7f, 0xe6, 0x26, 0xb6, + 0xc8, 0xda, 0x9e, 0x4a, 0x3f, 0x6c, 0xa1, 0x7d, 0x3f, 0x9e, 0x8a, 0x63, + 0xc3, 0x84, 0x60, 0xee, 0x7d, 0xe8, 0x9d, 0x90, 0xb5, 0xe2, 0xaf, 0x84, + 0xe6, 0x4f, 0xfc, 0x08, 0x2d, 0x13, 0xe9, 0xd0, 0x82, 0x89, 0x31, 0xca, + 0x9d, 0xa0, 0x6c, 0x83, 0xa1, 0xfa, 0x89, 0x91, 0x50, 0x70, 0xe2, 0x40, + 0x28, 0x30, 0xd1, 0x8e, 0x9d, 0x13, 0xeb, 0xb0, 0x63, 0x62, 0x1b, 0xb6, + 0x4f, 0x08, 0x6e, 0x4f, 0x61, 0xe5, 0xc4, 0xab, 0x58, 0x31, 0xf1, 0x2c, + 0x5a, 0x27, 0xce, 0x62, 0xf9, 0xc4, 0x8b, 0x68, 0x9b, 0x78, 0x89, 0x63, + 0x91, 0xb5, 0x67, 0x59, 0x77, 0x2e, 0xde, 0xe7, 0x9b, 0xbe, 0x97, 0x5a, + 0xd6, 0x56, 0xe4, 0x59, 0x30, 0x99, 0x43, 0x17, 0xd6, 0x6a, 0xe7, 0xd0, + 0xb7, 0x5f, 0xde, 0xb5, 0xd6, 0xa8, 0xf5, 0x42, 0xee, 0xe1, 0xbe, 0x28, + 0xcf, 0x06, 0xd0, 0xc6, 0xa6, 0xef, 0x1b, 0xd6, 0xb5, 0xa9, 0x4b, 0xf7, + 0x3c, 0xe5, 0x99, 0x2c, 0x89, 0x3d, 0xe7, 0xd1, 0x93, 0xfd, 0x8d, 0x15, + 0xd5, 0xa4, 0xac, 0x3c, 0x2b, 0x26, 0xf6, 0x70, 0x0e, 0x0f, 0xed, 0x3f, + 0x4f, 0x0e, 0x35, 0x69, 0xaf, 0x1d, 0xbd, 0xbd, 0x40, 0xde, 0xd3, 0xe3, + 0x27, 0x36, 0x9d, 0x43, 0xea, 0x28, 0x30, 0x71, 0x50, 0xfc, 0x70, 0x23, + 0xfd, 0x70, 0x52, 0x7c, 0x32, 0x4e, 0x4c, 0xbe, 0xcd, 0x83, 0xfb, 0xc8, + 0x93, 0x4a, 0x90, 0x1b, 0x2b, 0xc7, 0xd3, 0x23, 0x71, 0x6b, 0x9e, 0x21, + 0xef, 0x2e, 0x31, 0x72, 0x57, 0x32, 0xee, 0xbf, 0xc4, 0x6b, 0x93, 0x83, + 0xf0, 0xfb, 0x8c, 0x80, 0x6f, 0x1e, 0xcf, 0x4f, 0xa7, 0x27, 0xc9, 0x71, + 0xba, 0x30, 0xc5, 0x6f, 0xc9, 0x89, 0x81, 0x5e, 0xa4, 0xd3, 0xa2, 0xcf, + 0x76, 0xea, 0x53, 0x70, 0x51, 0xef, 0x6a, 0x25, 0x1e, 0x5a, 0x8a, 0xe0, + 0xa1, 0x8a, 0x8a, 0x7d, 0xc2, 0x25, 0xec, 0x77, 0x9f, 0x98, 0x03, 0xca, + 0x8b, 0xf8, 0x0e, 0x73, 0x98, 0xf2, 0x7d, 0xe4, 0x43, 0xc4, 0xca, 0xaa, + 0x88, 0x62, 0xac, 0x0a, 0x9c, 0xc3, 0xd3, 0x63, 0x4e, 0xb8, 0x93, 0x4e, + 0x4c, 0x12, 0x27, 0x1d, 0x49, 0xd9, 0x3f, 0xa0, 0x51, 0x16, 0x59, 0xa7, + 0x3a, 0x8b, 0x9c, 0x7d, 0x7f, 0x4f, 0xee, 0xcf, 0x7c, 0xd7, 0xee, 0xc7, + 0x49, 0xd9, 0xfb, 0x88, 0xa5, 0x3d, 0xa9, 0xef, 0xa1, 0x35, 0xed, 0xb1, + 0x9f, 0xf3, 0xdb, 0x9d, 0x7a, 0x15, 0xa9, 0xfd, 0x75, 0xb8, 0xdd, 0x7e, + 0xd6, 0xcf, 0x84, 0x46, 0xbd, 0xdd, 0x32, 0x6e, 0x22, 0x7a, 0x78, 0x1d, + 0xd6, 0x1e, 0xfe, 0x24, 0x8f, 0x59, 0xb8, 0xe9, 0x70, 0x27, 0x6e, 0x1c, + 0x8f, 0xa3, 0x63, 0xbc, 0x8f, 0xc7, 0x7a, 0x7c, 0x6c, 0xa8, 0x1a, 0x99, + 0x90, 0xc6, 0x1c, 0x7f, 0x3d, 0x73, 0x7c, 0xe1, 0x67, 0x1b, 0xf0, 0x34, + 0x71, 0x27, 0x18, 0xda, 0x80, 0x49, 0xdb, 0x17, 0x65, 0x8f, 0xe5, 0x06, + 0x6c, 0x67, 0xfe, 0x3e, 0x8a, 0x0d, 0xe8, 0xe1, 0xb5, 0x21, 0x7b, 0x0e, + 0x4e, 0x62, 0x19, 0xf3, 0xb3, 0x77, 0xae, 0x39, 0x89, 0x0f, 0x1f, 0x92, + 0xbe, 0x2f, 0x20, 0xb5, 0x77, 0x23, 0xdb, 0xcc, 0xa1, 0x7d, 0xfc, 0x9f, + 0x71, 0xe3, 0x10, 0xee, 0xac, 0x46, 0x35, 0x9e, 0x0d, 0x05, 0x3a, 0x06, + 0x94, 0x7f, 0xb6, 0xdb, 0xde, 0x9e, 0xfa, 0x11, 0x76, 0xa5, 0xce, 0xe3, + 0xe1, 0xcc, 0x4b, 0xe8, 0x4f, 0x4d, 0x9f, 0x53, 0x99, 0xcb, 0x37, 0x19, + 0x0f, 0xbe, 0x8f, 0x23, 0x63, 0x53, 0xc4, 0xde, 0x57, 0x78, 0xbc, 0xff, + 0x7e, 0x7a, 0xfe, 0x39, 0xdc, 0xbc, 0xdd, 0x48, 0x3e, 0x55, 0xe4, 0x6f, + 0x71, 0xab, 0xda, 0xc8, 0xed, 0x9a, 0x03, 0x7d, 0x5b, 0x58, 0x95, 0xfb, + 0x81, 0x46, 0xec, 0x05, 0x45, 0x6f, 0xff, 0x96, 0xe2, 0x61, 0xae, 0x21, + 0xcf, 0x45, 0xea, 0xd1, 0x1b, 0xa8, 0xef, 0xb2, 0x07, 0xbe, 0x0f, 0xe7, + 0x03, 0x4e, 0x94, 0x26, 0x65, 0x2d, 0x47, 0xde, 0x2b, 0x23, 0xef, 0x30, + 0xc9, 0xe9, 0xa5, 0xf2, 0xae, 0x89, 0xe4, 0x24, 0x63, 0x7f, 0x6e, 0x61, + 0x09, 0xe4, 0x39, 0xec, 0xeb, 0xb0, 0x71, 0x30, 0x8a, 0x1e, 0x53, 0x9e, + 0x31, 0xca, 0x8f, 0x7f, 0x5e, 0xf3, 0xf7, 0xd1, 0xcb, 0xf8, 0xb3, 0x9e, + 0x98, 0x78, 0xbb, 0x7d, 0x6f, 0xf6, 0xfb, 0xe8, 0x1b, 0xf9, 0x47, 0xb7, + 0xf0, 0x9d, 0x3e, 0x53, 0x9e, 0xe3, 0xd6, 0xcd, 0xf7, 0xbe, 0xc3, 0x66, + 0xbe, 0xec, 0x69, 0xa3, 0x4d, 0xe4, 0x16, 0xba, 0xb0, 0xbd, 0x36, 0xff, + 0x1e, 0x95, 0x0f, 0x7a, 0xe7, 0xd0, 0x5f, 0xda, 0xef, 0x1c, 0x92, 0xfb, + 0xfa, 0xf2, 0xbe, 0xaa, 0x27, 0x12, 0xf2, 0x1e, 0x09, 0x75, 0x99, 0x0b, + 0xaa, 0xd7, 0x45, 0x5e, 0xf8, 0xaa, 0x39, 0x13, 0xbd, 0x5e, 0x0b, 0xd7, + 0x53, 0x96, 0x63, 0x4d, 0x1f, 0x63, 0xe6, 0x12, 0xef, 0x70, 0xd9, 0xef, + 0x26, 0x39, 0xff, 0xa9, 0x7f, 0xff, 0x6e, 0x92, 0x37, 0x89, 0x93, 0x0a, + 0x2a, 0x8d, 0x5b, 0xf0, 0x9c, 0x1d, 0x13, 0x14, 0x54, 0x34, 0xc8, 0xba, + 0xa8, 0x1f, 0xcf, 0x18, 0x8d, 0xfe, 0x1a, 0xb9, 0xdf, 0xa5, 0x9c, 0xb3, + 0xe2, 0xde, 0x3a, 0xc6, 0x97, 0xff, 0x68, 0x2f, 0xfe, 0xf3, 0xd8, 0xb9, + 0x37, 0x4c, 0xce, 0xe8, 0x95, 0x67, 0x23, 0x67, 0x14, 0x9f, 0xc5, 0xdc, + 0x91, 0x92, 0x3d, 0xec, 0x0c, 0x8a, 0xe5, 0x6f, 0xd2, 0xcf, 0xde, 0x94, + 0x3d, 0x58, 0xe4, 0x3c, 0x7f, 0x85, 0x60, 0xcd, 0x8c, 0xfc, 0x73, 0x52, + 0xf6, 0x5e, 0x5f, 0x59, 0x0f, 0xd8, 0x5e, 0x78, 0xef, 0xa2, 0x94, 0x95, + 0x7a, 0x6f, 0xda, 0x6b, 0xc2, 0x2e, 0xe3, 0x37, 0xd6, 0x6b, 0xde, 0x5a, + 0x96, 0xfd, 0x45, 0xe1, 0xff, 0xf3, 0xe2, 0x33, 0x66, 0x14, 0x72, 0x4d, + 0xea, 0x88, 0xae, 0x2e, 0xd7, 0xe9, 0x4d, 0x39, 0x88, 0x7b, 0x67, 0xad, + 0x6e, 0xaf, 0x8c, 0x61, 0xec, 0x7d, 0x75, 0x54, 0xfb, 0x1d, 0x84, 0x79, + 0xfd, 0x8a, 0x3c, 0xff, 0xbe, 0x4f, 0x59, 0x3f, 0x2e, 0x31, 0x2a, 0x70, + 0xae, 0x26, 0xbf, 0xae, 0x73, 0x59, 0xc6, 0x47, 0xbc, 0xb2, 0xef, 0xaf, + 0xd4, 0x3e, 0xb7, 0xfb, 0x35, 0x2f, 0xd7, 0xfb, 0x46, 0x61, 0xbc, 0xb5, + 0xf6, 0xb3, 0x4a, 0x0f, 0xda, 0xbc, 0xc6, 0x31, 0x6d, 0xdc, 0xcb, 0xbc, + 0xef, 0xed, 0x67, 0xa4, 0xd0, 0xaf, 0x6a, 0x3f, 0xef, 0x75, 0xb9, 0x0f, + 0x91, 0xeb, 0xa9, 0x42, 0x1d, 0x3d, 0x1c, 0xb5, 0xfb, 0x57, 0x99, 0xbf, + 0x15, 0xfb, 0xa4, 0x3f, 0x2d, 0x2e, 0xb6, 0x31, 0x29, 0xf6, 0xd5, 0x5d, + 0xca, 0xd8, 0x74, 0xae, 0xf9, 0x3e, 0x6c, 0x4f, 0x88, 0x9e, 0xe5, 0x1d, + 0x95, 0xc4, 0x60, 0x9b, 0x6b, 0xb9, 0xe8, 0x6f, 0x4b, 0x91, 0xd6, 0xe2, + 0x38, 0xd4, 0x24, 0xcf, 0xe6, 0xb9, 0x68, 0xd3, 0x71, 0x94, 0x91, 0xdb, + 0x46, 0x79, 0x4d, 0xf6, 0xb4, 0x1c, 0x31, 0xf5, 0xe8, 0x13, 0xf8, 0x12, + 0x1c, 0x57, 0xd9, 0xeb, 0x5f, 0x6d, 0x69, 0xc8, 0x75, 0x93, 0xb9, 0xc9, + 0xf4, 0x15, 0x83, 0x32, 0xda, 0x8e, 0xbd, 0x17, 0xdb, 0x94, 0x67, 0xf7, + 0x06, 0x12, 0xf2, 0x0c, 0x59, 0x63, 0x8c, 0xfc, 0x10, 0xcf, 0x65, 0x64, + 0xff, 0xc3, 0x6f, 0xad, 0xf8, 0x4c, 0xd9, 0x67, 0x39, 0xbd, 0x4e, 0x09, + 0x71, 0x29, 0x10, 0xae, 0x52, 0x8a, 0xcf, 0x91, 0x5d, 0xfe, 0xdc, 0x44, + 0x9b, 0x39, 0x6f, 0x3f, 0xfb, 0x27, 0x67, 0x11, 0xb4, 0xa4, 0xe4, 0x5d, + 0x8c, 0xfa, 0xe4, 0x2a, 0x34, 0xe6, 0xea, 0x1d, 0xce, 0x02, 0xff, 0x08, + 0x63, 0x0d, 0xed, 0x66, 0x47, 0x20, 0x6c, 0x3f, 0xe3, 0x26, 0xef, 0xdc, + 0x78, 0x18, 0x7a, 0xe7, 0x1b, 0x2c, 0xff, 0xb1, 0xec, 0xf3, 0x56, 0xda, + 0x2b, 0x63, 0x2a, 0xfa, 0xb8, 0xbc, 0xdb, 0x87, 0x7a, 0x8c, 0x88, 0x7f, + 0x78, 0x50, 0x13, 0x09, 0xd3, 0x0f, 0x25, 0x7e, 0xcb, 0xf3, 0x71, 0xfa, + 0x01, 0xc9, 0xab, 0x5a, 0xb2, 0xf2, 0xfc, 0xb7, 0xec, 0x9b, 0xd6, 0xfd, + 0x6b, 0x1d, 0xc1, 0xc2, 0xfe, 0xe5, 0x62, 0xbc, 0xb7, 0xbc, 0x85, 0xbd, + 0xd5, 0xee, 0x79, 0x8c, 0x6f, 0x96, 0xbd, 0x6f, 0x60, 0xa3, 0x8d, 0x0d, + 0x9a, 0xa1, 0x1f, 0xfb, 0xa5, 0xa3, 0x1b, 0x8f, 0x2d, 0x32, 0xba, 0x8e, + 0xab, 0xb9, 0xb4, 0x8f, 0x38, 0x71, 0xad, 0x23, 0x3a, 0xc4, 0x6f, 0xff, + 0x77, 0x89, 0xcd, 0x37, 0xd9, 0x75, 0xf5, 0xe0, 0x3a, 0xb5, 0xf8, 0x6c, + 0xb5, 0x3c, 0x73, 0xa1, 0x77, 0x7c, 0x43, 0xe9, 0xc6, 0xd6, 0x90, 0xd1, + 0xbe, 0x4d, 0xd1, 0xdb, 0xbe, 0xac, 0xe8, 0xfe, 0x90, 0x22, 0xe5, 0xec, + 0x77, 0xe8, 0x5c, 0x8a, 0x9d, 0x2e, 0xf6, 0x71, 0x38, 0xa1, 0x87, 0x67, + 0xb0, 0xec, 0x39, 0xd3, 0xf0, 0x5d, 0x60, 0x9b, 0x3f, 0xe4, 0x31, 0x84, + 0x20, 0x96, 0xdb, 0xed, 0x46, 0x17, 0xba, 0xec, 0xf7, 0xa4, 0x76, 0x30, + 0x26, 0xc8, 0xfb, 0xb0, 0x62, 0xd0, 0x92, 0x75, 0x34, 0x31, 0xbd, 0xff, + 0x66, 0x48, 0x4e, 0xdd, 0xc3, 0x80, 0xed, 0x81, 0x37, 0xd2, 0x8d, 0x86, + 0x45, 0x86, 0x6f, 0x89, 0x6a, 0xd7, 0x0f, 0xca, 0xfb, 0x81, 0x96, 0x73, + 0x9c, 0x23, 0x90, 0x36, 0x72, 0x96, 0xd6, 0x50, 0x6d, 0xd7, 0x59, 0xa4, + 0x7e, 0x14, 0xae, 0x0f, 0xfd, 0xca, 0x4a, 0x6b, 0xd0, 0x6a, 0x0d, 0xa9, + 0x13, 0x1f, 0xd2, 0xf0, 0x1f, 0xd5, 0x13, 0x5c, 0xf9, 0xa5, 0x85, 0x59, + 0x52, 0x4f, 0xf6, 0xac, 0x7d, 0x1a, 0x77, 0x0d, 0xc8, 0x7b, 0x22, 0xc4, + 0x1f, 0xf5, 0xe8, 0x17, 0xc8, 0x35, 0xcb, 0xed, 0xf7, 0x6f, 0x49, 0x2c, + 0x59, 0x4f, 0x3c, 0xeb, 0x86, 0x16, 0xd2, 0xfb, 0xaf, 0x50, 0xe5, 0x1d, + 0x43, 0x8f, 0xc9, 0xbe, 0x9d, 0x03, 0x0b, 0xd4, 0xfc, 0xfe, 0x9e, 0xd8, + 0x1f, 0x7d, 0x5f, 0x11, 0xfb, 0x2a, 0x97, 0xf7, 0x15, 0xd5, 0xd9, 0xcf, + 0xa7, 0xac, 0x4f, 0x38, 0x0a, 0xfb, 0x15, 0x2f, 0xbf, 0xc7, 0x73, 0x23, + 0x79, 0xfd, 0x26, 0x79, 0x67, 0x1f, 0xc7, 0xba, 0x39, 0x21, 0x4b, 0x5a, + 0xff, 0x0f, 0xdd, 0x0f, 0x6b, 0xf2, 0xd0, 0x56, 0x00, 0x00, 0x00 }; static const u32 bnx2_CP_b06FwData[(0x84/4) + 1] = { 0x00000000, 0x0000001b, 0x0000000f, 0x0000000a, 0x00000008, 0x00000006, @@ -2137,50 +2119,51 @@ static const u32 bnx2_CP_b06FwData[(0x84/4) + 1] = { 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000 }; -static const u32 bnx2_CP_b06FwRodata[(0x130/4) + 1] = { - 0x08001e8c, 0x08001d18, 0x08001e68, 0x08001e44, 0x08001e20, 0x08001dfc, - 0x08001dd4, 0x08001dac, 0x08001d80, 0x08001f84, 0x08001f74, 0x08001d34, - 0x08001d34, 0x08001d34, 0x08001eb4, 0x08001eb4, 0x08001d34, 0x08001d34, - 0x08001f64, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001f54, - 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, - 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, - 0x08001d34, 0x08001d34, 0x08001f44, 0x08001d34, 0x08001d34, 0x08001f34, - 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, - 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, - 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001f1c, - 0x08001d34, 0x08001d34, 0x08001f0c, 0x08001efc, 0x08003208, 0x08003210, - 0x080031d8, 0x080031e4, 0x080031f0, 0x080031fc, 0x08005694, 0x08005654, - 0x08005620, 0x080055f4, 0x080055d0, 0x0800558c, 0x00000000 }; +static const u32 bnx2_CP_b06FwRodata[(0x134/4) + 1] = { + 0x08000f30, 0x08000d88, 0x08000fc4, 0x0800106c, 0x08000f58, 0x08000f98, + 0x080011a4, 0x08000da4, 0x080011c8, 0x08000df4, 0x08001498, 0x08001440, + 0x08000da4, 0x08000da4, 0x08000da4, 0x08001254, 0x08001254, 0x08000da4, + 0x08000da4, 0x080016e0, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, + 0x080013d4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, + 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, + 0x08000da4, 0x08000da4, 0x08000da4, 0x08000fb8, 0x08000da4, 0x08000da4, + 0x08001690, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, + 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, + 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, + 0x080015bc, 0x08000da4, 0x08000da4, 0x08001348, 0x080012b8, 0x08002e50, + 0x08002e58, 0x08002e20, 0x08002e2c, 0x08002e38, 0x08002e44, 0x0800532c, + 0x080052ec, 0x080052b8, 0x0800528c, 0x08005268, 0x08005224, 0x00000000 +}; static struct fw_info bnx2_cp_fw_06 = { - /* Firmware version: 4.4.22 */ + /* Firmware version: 4.6.16 */ .ver_major = 0x4, - .ver_minor = 0x4, - .ver_fix = 0x16, + .ver_minor = 0x6, + .ver_fix = 0x10, .start_addr = 0x08000080, .text_addr = 0x08000000, - .text_len = 0x5a34, + .text_len = 0x56cc, .text_index = 0x0, .gz_text = bnx2_CP_b06FwText, .gz_text_len = sizeof(bnx2_CP_b06FwText), - .data_addr = 0x08005b80, + .data_addr = 0x08005820, .data_len = 0x84, .data_index = 0x0, .data = bnx2_CP_b06FwData, - .sbss_addr = 0x08005c04, - .sbss_len = 0xe9, + .sbss_addr = 0x080058a4, + .sbss_len = 0xf1, .sbss_index = 0x0, - .bss_addr = 0x08005cf0, + .bss_addr = 0x08005998, .bss_len = 0x5d8, .bss_index = 0x0, - .rodata_addr = 0x08005a34, - .rodata_len = 0x130, + .rodata_addr = 0x080056cc, + .rodata_len = 0x134, .rodata_index = 0x0, .rodata = bnx2_CP_b06FwRodata, }; @@ -2202,761 +2185,747 @@ static const struct cpu_reg cpu_reg_cp = { }; static u8 bnx2_RXP_b06FwText[] = { - 0xec, 0x5b, 0x5f, 0x6c, 0x5b, 0xd7, 0x79, 0xff, 0xee, 0x21, 0x25, 0x51, - 0xb2, 0xfe, 0x5c, 0xc9, 0x8c, 0x43, 0x27, 0x4a, 0x43, 0x4a, 0x57, 0x12, - 0x13, 0x69, 0xe9, 0x95, 0xc6, 0x26, 0x2a, 0x46, 0x34, 0x2c, 0x29, 0xdb, - 0x4a, 0xe3, 0x07, 0xc5, 0xf5, 0xda, 0xac, 0xeb, 0x30, 0x81, 0xb2, 0xb1, - 0xec, 0x61, 0x83, 0x67, 0xac, 0x41, 0xb6, 0xb9, 0x30, 0x41, 0x29, 0x8e, - 0x92, 0xd2, 0x22, 0x67, 0x2b, 0x73, 0xb1, 0x65, 0x80, 0x42, 0x49, 0x76, - 0xb6, 0xd1, 0x62, 0xda, 0xbd, 0x74, 0x45, 0x1c, 0x0b, 0x8a, 0xe7, 0xe5, - 0xa1, 0x0f, 0x69, 0x17, 0x60, 0xed, 0xd0, 0x61, 0x86, 0xe2, 0xda, 0x79, - 0x28, 0xb6, 0x6c, 0x40, 0x96, 0x6c, 0x71, 0x73, 0xf7, 0xfb, 0x9d, 0x7b, - 0xaf, 0x4c, 0x2b, 0x1a, 0x9a, 0x87, 0x3d, 0xde, 0x03, 0x08, 0xe7, 0x9e, - 0x73, 0xbe, 0xf3, 0x9d, 0xef, 0xfb, 0xce, 0xf7, 0xf7, 0xd0, 0xfe, 0xc3, - 0x76, 0x69, 0x13, 0xaf, 0x75, 0xe0, 0x2f, 0x75, 0xec, 0x99, 0xe3, 0x63, - 0x0f, 0xa5, 0x1e, 0xe2, 0x38, 0xa4, 0xc2, 0x61, 0xf6, 0x86, 0x04, 0x2d, - 0x68, 0x41, 0x0b, 0x5a, 0xd0, 0x82, 0x16, 0xb4, 0xa0, 0x05, 0x2d, 0x68, - 0x41, 0x0b, 0x5a, 0xd0, 0x82, 0x16, 0xb4, 0xa0, 0x05, 0x2d, 0x68, 0x41, - 0x0b, 0x5a, 0xd0, 0x82, 0x16, 0xb4, 0xa0, 0x05, 0x2d, 0x68, 0x41, 0x0b, - 0x5a, 0xd0, 0x82, 0x16, 0xb4, 0xa0, 0x05, 0x2d, 0x68, 0x41, 0x0b, 0x5a, - 0xd0, 0x82, 0x16, 0xb4, 0xa0, 0x05, 0x2d, 0x68, 0x41, 0x0b, 0x5a, 0xd0, - 0x82, 0x16, 0xb4, 0xa0, 0x05, 0xed, 0xff, 0xb3, 0x85, 0x44, 0x4c, 0xf6, - 0x1d, 0xde, 0x9f, 0x44, 0x54, 0x3a, 0x7e, 0x3c, 0x6b, 0x49, 0x24, 0x94, - 0xbe, 0xf2, 0xf4, 0x8c, 0x25, 0x92, 0xa9, 0x0d, 0xc7, 0x73, 0xf2, 0x0b, - 0xa7, 0x10, 0x0d, 0x0b, 0xe7, 0xef, 0x4b, 0xdf, 0x3a, 0x79, 0xe9, 0x91, - 0xc4, 0x7b, 0x4b, 0x21, 0x89, 0x98, 0xe9, 0xb7, 0x46, 0xcd, 0x41, 0x89, - 0xf4, 0x62, 0xcf, 0x4b, 0x43, 0x97, 0xbb, 0xa4, 0xd3, 0xc7, 0x25, 0x52, - 0x2d, 0x25, 0xec, 0xfd, 0x32, 0x6c, 0x6e, 0x48, 0x58, 0x32, 0x38, 0xe3, - 0x7c, 0x4d, 0xa4, 0x58, 0x32, 0x88, 0x43, 0x8a, 0xb5, 0x88, 0x5c, 0x0b, - 0x11, 0xea, 0x7b, 0x46, 0xb6, 0xfc, 0xb1, 0x93, 0x09, 0xe3, 0x5c, 0x0b, - 0xdf, 0x75, 0x7f, 0x3e, 0x22, 0x2a, 0x9d, 0x48, 0x66, 0x43, 0x93, 0x52, - 0x5d, 0x74, 0x9c, 0x39, 0xfb, 0x5e, 0xe0, 0xe8, 0x91, 0x39, 0xcb, 0x1d, - 0x67, 0xed, 0x07, 0xcd, 0x09, 0xb9, 0x1b, 0x73, 0x21, 0x51, 0xd6, 0x3d, - 0xf8, 0x8b, 0x1b, 0xb9, 0xb3, 0xdf, 0x32, 0xb2, 0xcb, 0xed, 0x52, 0x2c, - 0x3b, 0x32, 0x63, 0x4b, 0x26, 0x6b, 0xb7, 0x62, 0xfd, 0x63, 0x67, 0x66, - 0x6b, 0xcf, 0xb0, 0x99, 0x93, 0x26, 0xc9, 0x44, 0x63, 0x80, 0x59, 0x34, - 0x72, 0x17, 0xfe, 0xae, 0x5d, 0xda, 0x40, 0x4f, 0x8a, 0xe3, 0x8f, 0x9d, - 0x90, 0x65, 0x61, 0x9d, 0xe7, 0x63, 0x5c, 0x27, 0x5e, 0x7e, 0x13, 0xe7, - 0x35, 0xe7, 0xd2, 0x50, 0x4c, 0xbe, 0x5b, 0x8f, 0xca, 0x77, 0xea, 0xa6, - 0xbc, 0x5a, 0xef, 0x95, 0xcb, 0x75, 0xc7, 0xf9, 0x8e, 0xed, 0x38, 0x6f, - 0xe1, 0xef, 0x3f, 0xed, 0x2d, 0x1e, 0xd0, 0x0a, 0xc6, 0x44, 0xfd, 0x2f, - 0xda, 0xa5, 0x33, 0x11, 0x17, 0xd5, 0x2e, 0xb3, 0xe5, 0x98, 0xcc, 0x95, - 0x4b, 0xc6, 0x13, 0x17, 0x16, 0x8c, 0xa9, 0x0b, 0x15, 0x9c, 0x19, 0xc6, - 0x9c, 0x14, 0x8a, 0xf6, 0x2b, 0x46, 0xae, 0x3e, 0x6f, 0x1c, 0xba, 0xd0, - 0x09, 0x1a, 0x79, 0xfe, 0x1e, 0x23, 0x7b, 0xf6, 0x96, 0x64, 0x6d, 0xca, - 0x38, 0x61, 0x7e, 0x0d, 0x62, 0xcf, 0x96, 0x48, 0x73, 0xb3, 0x47, 0xaf, - 0xe3, 0xa8, 0xb4, 0x73, 0x32, 0x9b, 0xb2, 0xcc, 0xa2, 0x90, 0x3e, 0x3d, - 0x77, 0xd9, 0xa5, 0xf9, 0xbc, 0x91, 0xbd, 0xd0, 0x6e, 0xe4, 0xce, 0x85, - 0x41, 0x87, 0xf4, 0x86, 0x84, 0xfb, 0x06, 0x62, 0x79, 0xa9, 0xe1, 0x0c, - 0x31, 0x55, 0x9a, 0x72, 0x05, 0xcd, 0xa0, 0xe5, 0xbb, 0x65, 0xf0, 0x50, - 0x06, 0x0f, 0x65, 0xf2, 0x16, 0x97, 0x4b, 0x43, 0x3e, 0x6f, 0x8e, 0xf3, - 0x23, 0x9b, 0xb4, 0x27, 0xe2, 0x19, 0xe5, 0xf3, 0xe9, 0x38, 0xff, 0x61, - 0x93, 0x57, 0xf2, 0xe3, 0x38, 0xaf, 0xda, 0x31, 0xd0, 0xee, 0x5c, 0x56, - 0x56, 0x09, 0xbc, 0x58, 0xc0, 0x4f, 0x59, 0x2f, 0x80, 0x87, 0x79, 0xf0, - 0x77, 0x1e, 0xbc, 0x55, 0x40, 0xc7, 0x2f, 0x3b, 0xaf, 0x60, 0xe4, 0x86, - 0xb6, 0xe4, 0x15, 0xa7, 0x8c, 0xf3, 0x2b, 0x0a, 0xb2, 0xde, 0x25, 0xf9, - 0x25, 0x53, 0xa6, 0x57, 0xfc, 0xfd, 0xbe, 0x1e, 0x1c, 0x93, 0x83, 0xe5, - 0x1e, 0xc8, 0x86, 0xb2, 0x4c, 0xd8, 0x22, 0x0e, 0x64, 0x54, 0x4c, 0x2a, - 0x11, 0x23, 0x6f, 0x9f, 0xd4, 0xf7, 0xbf, 0x62, 0x49, 0x26, 0x6f, 0x53, - 0x8e, 0x12, 0xcf, 0xdb, 0x85, 0x58, 0x18, 0xfa, 0xb6, 0x62, 0x15, 0xcc, - 0xb0, 0x50, 0x8e, 0x89, 0xd8, 0x1f, 0x43, 0x96, 0x47, 0x4b, 0x92, 0xf9, - 0x52, 0xc9, 0x97, 0xb1, 0x2b, 0xdf, 0xc7, 0x4b, 0x5f, 0xec, 0x90, 0x36, - 0xf5, 0x99, 0x26, 0xf9, 0x3d, 0xec, 0x25, 0xee, 0x3b, 0xf6, 0x62, 0x9f, - 0x0b, 0xe7, 0xee, 0x4d, 0x3c, 0x29, 0x42, 0xd8, 0x62, 0x7f, 0x93, 0xb6, - 0x11, 0x31, 0xb2, 0x56, 0x21, 0x16, 0x02, 0x5c, 0x5e, 0x8a, 0xa3, 0xde, - 0x5c, 0x53, 0xd6, 0xba, 0x15, 0x9a, 0xb3, 0x13, 0xf1, 0xa2, 0xdc, 0x0a, - 0x5d, 0xb5, 0xf5, 0x5c, 0x6b, 0xd6, 0x72, 0x64, 0x15, 0xd8, 0x9f, 0x83, - 0x3d, 0x6c, 0x80, 0xa3, 0xdf, 0x2d, 0xe9, 0xf9, 0x0e, 0xec, 0x4f, 0x36, - 0x01, 0x67, 0x9b, 0x24, 0x92, 0x55, 0xcc, 0x5f, 0x75, 0xe7, 0xbb, 0x5d, - 0xbc, 0xc5, 0xfe, 0x36, 0x8d, 0x5b, 0xe4, 0x15, 0x77, 0xfe, 0x2e, 0x17, - 0x77, 0xf1, 0x01, 0xcc, 0x03, 0xff, 0xe0, 0xe4, 0x90, 0xa1, 0xe7, 0xf7, - 0xd2, 0x9e, 0x7e, 0xa7, 0x74, 0x2b, 0xb4, 0x6a, 0x3b, 0x92, 0x1b, 0x1d, - 0x9c, 0x1c, 0x34, 0x5c, 0x7c, 0xa7, 0xdc, 0x7d, 0xf7, 0xb9, 0xf8, 0x06, - 0x27, 0x93, 0x86, 0x8b, 0x6f, 0xa5, 0xa4, 0xf7, 0x4a, 0xbe, 0x44, 0xd8, - 0xc1, 0x49, 0xcb, 0xb8, 0x4f, 0xa6, 0xbb, 0x07, 0x27, 0xfb, 0x0c, 0xf5, - 0x99, 0x5d, 0x2e, 0x1f, 0x09, 0x9f, 0x86, 0x5d, 0x9a, 0x06, 0x9e, 0xab, - 0xe7, 0x07, 0xb2, 0x56, 0xf1, 0x81, 0x5d, 0xfa, 0x7c, 0x9e, 0xa9, 0xe7, - 0x1e, 0x20, 0x5d, 0x3c, 0x7b, 0x66, 0xf4, 0x8e, 0x73, 0x7f, 0xe5, 0xb6, - 0x7c, 0x76, 0x3a, 0x93, 0xe7, 0x49, 0x24, 0x9c, 0x0e, 0x8f, 0xce, 0x95, - 0x8e, 0x49, 0xb6, 0x1c, 0x97, 0xd9, 0x91, 0x56, 0x99, 0x36, 0xfb, 0xa7, - 0x0f, 0x0a, 0x7d, 0x4f, 0x64, 0x74, 0xc6, 0xbb, 0xc3, 0x9c, 0x18, 0x32, - 0x0b, 0x1e, 0x0f, 0xd6, 0x24, 0x62, 0x00, 0xbe, 0xbf, 0x16, 0x96, 0xe7, - 0xeb, 0x86, 0x34, 0x6b, 0xfb, 0x4c, 0x98, 0xeb, 0xd0, 0xc3, 0x67, 0xcb, - 0xd4, 0x63, 0xea, 0xac, 0x64, 0xaa, 0x5a, 0x67, 0x7d, 0x7b, 0x6d, 0xe3, - 0xdd, 0x16, 0x0a, 0x02, 0x73, 0x4c, 0x5b, 0x66, 0x55, 0x5a, 0x24, 0x33, - 0x25, 0x85, 0xaa, 0xbd, 0x65, 0x3f, 0xb1, 0x65, 0xd9, 0x80, 0x1e, 0x88, - 0x99, 0x4d, 0x71, 0x9e, 0xf0, 0x0d, 0xb0, 0xa6, 0x6b, 0x7b, 0x21, 0xd8, - 0xde, 0x4c, 0x8a, 0xb0, 0x52, 0xd0, 0xfe, 0xa2, 0x0e, 0x7d, 0xac, 0xdf, - 0xd7, 0xe1, 0xfa, 0xbb, 0x08, 0x6c, 0xb4, 0x1d, 0x76, 0xfe, 0x19, 0xd8, - 0x60, 0xaf, 0x91, 0x3d, 0xe7, 0x38, 0xf0, 0x3f, 0x51, 0x25, 0xb4, 0x41, - 0xd8, 0x7b, 0x9d, 0x6b, 0xed, 0x98, 0x17, 0x73, 0xd6, 0xee, 0x06, 0x8f, - 0x8e, 0x33, 0x69, 0xc7, 0xa5, 0x68, 0x77, 0x61, 0x5f, 0x93, 0xf4, 0x58, - 0xd4, 0x79, 0xda, 0xf5, 0x2e, 0x9c, 0x67, 0x70, 0xdc, 0x89, 0xf3, 0x3a, - 0x30, 0x17, 0x9b, 0xa5, 0x2d, 0xa7, 0xe8, 0xb7, 0x5c, 0x1f, 0x2a, 0x72, - 0x1d, 0xb4, 0x72, 0x8f, 0x86, 0x8b, 0xb4, 0xa4, 0x53, 0x72, 0xb3, 0xb4, - 0x57, 0xae, 0x45, 0x29, 0x03, 0xe0, 0x2c, 0xc3, 0x27, 0x46, 0x0d, 0xd0, - 0x4f, 0xba, 0xe9, 0x03, 0x77, 0x7b, 0x63, 0xe3, 0x7e, 0xf7, 0x0c, 0x31, - 0x43, 0xe9, 0x4e, 0xc9, 0xe9, 0x39, 0x51, 0x6a, 0x74, 0x97, 0xb7, 0xde, - 0x69, 0xec, 0x3f, 0xa7, 0xe4, 0xc0, 0xc3, 0xf0, 0x5b, 0x38, 0xeb, 0xaa, - 0xe5, 0x38, 0x57, 0xed, 0xf7, 0x61, 0xf7, 0x4a, 0x9a, 0xac, 0x6b, 0x9d, - 0xd2, 0x46, 0x7b, 0x36, 0x1a, 0x64, 0x18, 0x93, 0x53, 0x65, 0xee, 0x29, - 0x48, 0xd8, 0x22, 0x0c, 0xe1, 0xff, 0x05, 0x70, 0x21, 0x69, 0x81, 0x3d, - 0x6e, 0xd8, 0x51, 0xd2, 0xdb, 0xe5, 0xc2, 0x77, 0xe3, 0x0c, 0xd2, 0x4e, - 0xfb, 0x73, 0xb4, 0xfd, 0x65, 0x43, 0x2a, 0x33, 0xb1, 0x08, 0x6b, 0x1a, - 0xa1, 0xbc, 0xb3, 0xdd, 0x70, 0xff, 0x32, 0x3b, 0x54, 0x30, 0x95, 0xbe, - 0x6f, 0x91, 0x5c, 0xe9, 0x7e, 0x99, 0xb3, 0x71, 0x9e, 0x15, 0x06, 0xcd, - 0xf4, 0x35, 0x03, 0x85, 0x90, 0x82, 0x95, 0xf5, 0x50, 0x56, 0x3e, 0xad, - 0xff, 0x8c, 0xf3, 0x0a, 0x46, 0xd8, 0xe2, 0x19, 0xbf, 0xe5, 0xc9, 0x87, - 0xba, 0x67, 0x4b, 0xb6, 0xd4, 0xce, 0x31, 0xe8, 0x68, 0xd3, 0x74, 0x84, - 0xd2, 0xfa, 0xee, 0x0c, 0x95, 0xf6, 0x63, 0x00, 0x41, 0xef, 0xc0, 0x03, - 0x3e, 0xb8, 0xd7, 0xc2, 0xde, 0x08, 0x68, 0xec, 0x68, 0xa0, 0xbf, 0x8d, - 0xf0, 0x90, 0x55, 0xc4, 0x3b, 0x43, 0xf3, 0x6d, 0xb8, 0x7c, 0xfb, 0xb2, - 0x7a, 0x1d, 0xb2, 0xfa, 0xc8, 0x39, 0x30, 0x46, 0x1c, 0x29, 0xe0, 0x80, - 0xdc, 0x4d, 0xfa, 0x2c, 0xfa, 0x29, 0x73, 0x0b, 0x17, 0x6c, 0x41, 0x85, - 0xd2, 0xed, 0x92, 0x33, 0x75, 0x1c, 0x00, 0xec, 0xb8, 0x68, 0x3f, 0x6f, - 0x91, 0x47, 0x6f, 0x6c, 0x25, 0xb4, 0xde, 0xe4, 0x2b, 0x8c, 0x05, 0x45, - 0xd0, 0xb6, 0x9e, 0x50, 0x9a, 0xb5, 0x76, 0xc8, 0x5c, 0x22, 0x4d, 0xe9, - 0xb7, 0x64, 0xb5, 0xa4, 0xf6, 0x34, 0x4b, 0x97, 0x4c, 0x41, 0x46, 0xd5, - 0x71, 0xc4, 0xb0, 0x91, 0x76, 0x09, 0x3d, 0xc4, 0x58, 0x10, 0x03, 0xad, - 0xeb, 0x09, 0x53, 0x6e, 0x39, 0x6a, 0x10, 0xfb, 0x47, 0x70, 0x0f, 0x87, - 0x79, 0xa7, 0xca, 0x83, 0x23, 0x4c, 0x88, 0x32, 0xef, 0x69, 0x16, 0xe2, - 0xe6, 0xda, 0x70, 0xcc, 0x14, 0xce, 0x23, 0x5e, 0x4e, 0x71, 0x2f, 0xf9, - 0x73, 0xf7, 0x7c, 0x92, 0x3f, 0x7f, 0x9d, 0x32, 0xa3, 0xec, 0xa0, 0x63, - 0xa0, 0xa9, 0x1b, 0x72, 0x1b, 0x5d, 0x80, 0x4f, 0xb4, 0x1f, 0xd7, 0x3a, - 0xdc, 0x37, 0x76, 0xaf, 0x5c, 0x83, 0xdd, 0xc5, 0x95, 0x18, 0x55, 0x7b, - 0xaf, 0x9e, 0x53, 0x96, 0x2f, 0x4f, 0xca, 0x60, 0xf7, 0x36, 0x19, 0x10, - 0xe7, 0xce, 0x72, 0x38, 0x52, 0x21, 0x0d, 0x2e, 0x2d, 0x73, 0xd6, 0x7a, - 0x22, 0x2c, 0x8d, 0xf4, 0x7c, 0xec, 0x28, 0xcb, 0x2a, 0xf4, 0x29, 0xe2, - 0x6f, 0x16, 0xb5, 0x27, 0x2c, 0x4f, 0x8c, 0x19, 0x12, 0x3f, 0xa4, 0xe4, - 0xd0, 0xc3, 0xc4, 0xf9, 0x13, 0xf2, 0x38, 0x9e, 0xe1, 0xfa, 0x18, 0x75, - 0x21, 0x8c, 0x5e, 0xf3, 0x87, 0xb9, 0x46, 0x5d, 0x7f, 0xdd, 0xd3, 0xf5, - 0x8f, 0x9c, 0x43, 0x63, 0x61, 0x0f, 0x36, 0xd2, 0x00, 0x2b, 0xb8, 0xef, - 0x9d, 0x60, 0x09, 0xd3, 0xa8, 0x17, 0x84, 0x2d, 0xec, 0x00, 0x8b, 0xe0, - 0xf4, 0x15, 0xda, 0x50, 0xb7, 0xe7, 0x33, 0x7c, 0x9b, 0xe2, 0x39, 0xec, - 0x77, 0xb2, 0x3f, 0xee, 0xe3, 0x7e, 0xc2, 0x6f, 0x8f, 0xa7, 0xb8, 0x06, - 0xd9, 0x31, 0xa6, 0xa2, 0x4d, 0xe2, 0x5b, 0xc1, 0xff, 0x34, 0xc6, 0x56, - 0xce, 0x99, 0x18, 0x4f, 0xa0, 0xb7, 0x24, 0x5f, 0xa3, 0x1d, 0x71, 0x3f, - 0x63, 0xed, 0xbb, 0x9e, 0xef, 0x6c, 0x9f, 0x0e, 0xa7, 0xa3, 0xf0, 0x9d, - 0x32, 0x55, 0x2c, 0x9d, 0x44, 0x3e, 0x24, 0x85, 0x7b, 0xd2, 0xd4, 0x8b, - 0xf6, 0x71, 0xf8, 0xc6, 0xa9, 0x62, 0x8d, 0x39, 0x11, 0xdc, 0x17, 0xf6, - 0x21, 0x3e, 0x47, 0xd4, 0x42, 0xa4, 0x70, 0x6f, 0x9a, 0x3e, 0x39, 0x2e, - 0xf1, 0xda, 0x7b, 0xc8, 0x39, 0x4c, 0xc9, 0x6a, 0x1d, 0xfb, 0xf6, 0x5e, - 0xd2, 0x5c, 0x44, 0xfe, 0x10, 0x4e, 0x4b, 0x58, 0xa5, 0x9b, 0x23, 0xb3, - 0xa9, 0x76, 0xe4, 0x59, 0x93, 0x7b, 0xd5, 0xda, 0xc1, 0xbd, 0xa1, 0xb5, - 0x3d, 0xd3, 0x4d, 0xe9, 0xc2, 0x5e, 0xb5, 0x20, 0xb2, 0x5c, 0x12, 0x85, - 0x9c, 0x26, 0x76, 0x44, 0x30, 0x5e, 0xfb, 0xf2, 0x97, 0x55, 0x3a, 0x24, - 0xf9, 0xa8, 0x9c, 0x58, 0x49, 0x85, 0x99, 0x3f, 0xc6, 0xa7, 0xe4, 0x04, - 0x72, 0xc6, 0x67, 0x64, 0xb6, 0x04, 0xba, 0x34, 0xdf, 0x31, 0xf0, 0xdb, - 0x0b, 0xdc, 0xa4, 0x3d, 0x0a, 0xdf, 0xea, 0xd2, 0x0e, 0x9a, 0x33, 0x39, - 0xe6, 0x48, 0x29, 0xc6, 0x94, 0xf7, 0xa0, 0x27, 0xb4, 0x93, 0x9f, 0xcb, - 0xaa, 0xd5, 0x2a, 0x79, 0xd7, 0x2f, 0x68, 0x3d, 0x0d, 0xa7, 0xdf, 0xf5, - 0xd6, 0xae, 0x63, 0x8d, 0xfa, 0xba, 0xab, 0xe1, 0xee, 0xbe, 0xa5, 0xf3, - 0x9c, 0xab, 0x36, 0xbf, 0x09, 0xfb, 0x83, 0x51, 0x17, 0xf6, 0xcd, 0xd1, - 0x55, 0xeb, 0x2b, 0x5d, 0xd2, 0x86, 0x73, 0xca, 0x3c, 0x27, 0x4a, 0xdf, - 0x8a, 0xf5, 0x6b, 0x1e, 0xae, 0x9f, 0x02, 0x57, 0x3b, 0xe9, 0x46, 0x0b, - 0x63, 0x1d, 0xf4, 0x21, 0xdf, 0xc9, 0x6f, 0xf9, 0x18, 0xc2, 0xbe, 0xe6, - 0xe1, 0xfa, 0x5e, 0x03, 0x2e, 0xae, 0xb1, 0xe7, 0x99, 0x38, 0xbb, 0x8d, - 0xbc, 0x91, 0x1f, 0xde, 0x01, 0xef, 0x23, 0x69, 0x4c, 0xc1, 0xa7, 0x4f, - 0xd5, 0x75, 0x5e, 0x67, 0xe4, 0xca, 0xc8, 0xb7, 0xea, 0x2f, 0x82, 0x46, - 0xe4, 0x61, 0xf5, 0x01, 0x2f, 0xd7, 0xa6, 0xad, 0xac, 0x6b, 0x9f, 0x45, - 0x7f, 0x53, 0xd4, 0xf6, 0x74, 0x05, 0x63, 0x9d, 0x67, 0xe3, 0x6e, 0xae, - 0x48, 0x5f, 0xad, 0xdc, 0xe5, 0xfe, 0xbf, 0x6d, 0x53, 0x42, 0xfa, 0x3e, - 0x19, 0xd7, 0xa8, 0x67, 0x77, 0xc3, 0x9f, 0x3b, 0x1f, 0x30, 0xbe, 0x4c, - 0x31, 0xf6, 0x4c, 0x31, 0x66, 0x18, 0x9e, 0x1f, 0x8c, 0x37, 0xe0, 0x88, - 0x03, 0xc7, 0x79, 0x4f, 0x6f, 0x4f, 0x7b, 0xb8, 0xfc, 0xdc, 0xd3, 0xf7, - 0xa5, 0x2f, 0xdd, 0x73, 0xe7, 0xba, 0x61, 0xba, 0xe3, 0x66, 0xed, 0x87, - 0x61, 0xf7, 0xa0, 0x3f, 0x3e, 0xad, 0xa0, 0x5f, 0xb9, 0x9a, 0x7b, 0x1f, - 0xb0, 0x71, 0xe8, 0x1e, 0x3f, 0xfd, 0xbb, 0x75, 0x73, 0x6f, 0x57, 0x06, - 0xbc, 0xd3, 0x0c, 0xf9, 0xce, 0x84, 0x49, 0x4b, 0x7d, 0x12, 0xfb, 0xe5, - 0x18, 0x63, 0x62, 0x1e, 0x7c, 0x1c, 0x31, 0x87, 0xcd, 0x59, 0xe2, 0x8e, - 0x0a, 0x70, 0x22, 0x8f, 0x4c, 0xb7, 0x78, 0xf7, 0xfc, 0x7d, 0x9e, 0x0f, - 0xdc, 0xbb, 0x38, 0x46, 0xff, 0x7d, 0x8f, 0x9e, 0x1b, 0x9d, 0x2e, 0x3d, - 0xfe, 0xfa, 0x80, 0x79, 0xe7, 0x78, 0x75, 0xaf, 0x27, 0x4f, 0x7c, 0x3f, - 0xe3, 0xd1, 0xc5, 0xbb, 0x69, 0xa4, 0x89, 0xf7, 0xf2, 0x5f, 0xc0, 0xa3, - 0xf3, 0x8c, 0x82, 0x4a, 0x23, 0x6f, 0x49, 0x31, 0x56, 0xc1, 0xe6, 0xc5, - 0xc2, 0x9d, 0x24, 0xec, 0x69, 0xec, 0x7a, 0xb7, 0xc4, 0x7b, 0xbe, 0x05, - 0x1f, 0xcd, 0x7b, 0xff, 0x50, 0xe6, 0x4a, 0xfd, 0x76, 0xb3, 0x41, 0x7b, - 0x4d, 0x24, 0xcf, 0xcb, 0xb0, 0x7d, 0x5e, 0xe7, 0x4f, 0x89, 0xf8, 0x29, - 0xa1, 0x6c, 0x6f, 0xc9, 0x80, 0xce, 0x6b, 0x3e, 0x14, 0x0b, 0x72, 0x99, - 0x2a, 0xc3, 0xc6, 0xc6, 0xfe, 0xcd, 0xd1, 0xf9, 0x28, 0xf2, 0xa5, 0x1b, - 0x3b, 0xe0, 0x7a, 0x53, 0xe3, 0x21, 0xbe, 0x46, 0x5c, 0x86, 0xb4, 0x8c, - 0xf9, 0xf8, 0x2c, 0x99, 0xaf, 0xfb, 0x38, 0xc3, 0xf0, 0xc3, 0xf0, 0x01, - 0x63, 0xbf, 0xe1, 0xe9, 0x0b, 0xbf, 0x7f, 0xe8, 0x30, 0x07, 0x52, 0xe9, - 0x3f, 0xf7, 0xe6, 0xae, 0x50, 0x06, 0x18, 0xfb, 0x72, 0x7f, 0xd1, 0xf3, - 0x39, 0x05, 0x23, 0x53, 0xa7, 0x0c, 0xa8, 0x2b, 0xb8, 0x7f, 0xad, 0x9f, - 0xb0, 0x99, 0xf2, 0x17, 0x10, 0x1f, 0xbb, 0xdd, 0xbc, 0x01, 0xb5, 0x55, - 0xa6, 0xce, 0xb9, 0xf5, 0x96, 0xac, 0xdd, 0xe4, 0xd9, 0xd2, 0x41, 0xcc, - 0x4d, 0xe1, 0x8f, 0xb2, 0x23, 0xcc, 0x61, 0x7c, 0x67, 0x3c, 0x38, 0x19, - 0xcf, 0x22, 0x66, 0x65, 0x0e, 0x4f, 0x60, 0x6c, 0x78, 0x35, 0x96, 0x96, - 0x7b, 0x05, 0x39, 0x0a, 0xe4, 0x39, 0x00, 0x7e, 0xe2, 0x32, 0x51, 0xc7, - 0x9d, 0x6f, 0xf9, 0xb3, 0x2d, 0x98, 0xc2, 0x6d, 0x18, 0xd7, 0xf7, 0x4d, - 0xd4, 0x7f, 0xec, 0xd0, 0x1f, 0xfc, 0xad, 0xb6, 0x97, 0x78, 0x43, 0xde, - 0x97, 0x31, 0x9e, 0x28, 0x4f, 0x1a, 0x87, 0xca, 0xdc, 0xa3, 0x5e, 0xea, - 0x11, 0x2b, 0x9e, 0x55, 0xc8, 0x51, 0xc7, 0x3a, 0x71, 0xe6, 0x29, 0xe8, - 0x46, 0xc1, 0x98, 0x1a, 0xea, 0x92, 0x7c, 0xb2, 0x07, 0x34, 0x3f, 0x82, - 0x1e, 0xb1, 0xc3, 0xfa, 0x35, 0xcc, 0x43, 0x8f, 0x92, 0xb4, 0x8f, 0x56, - 0x5d, 0x57, 0x4e, 0xeb, 0xb8, 0x35, 0xe0, 0xe9, 0xd6, 0x3f, 0x99, 0xae, - 0x2e, 0x3d, 0x8d, 0xf1, 0x2e, 0xcc, 0xff, 0x26, 0x7a, 0xc4, 0xac, 0x31, - 0x7f, 0x9e, 0x36, 0x38, 0x8e, 0xf9, 0xcf, 0x01, 0xc7, 0x9f, 0xe0, 0xfb, - 0x7e, 0x7c, 0xff, 0xd1, 0xb6, 0xbd, 0xdf, 0xe0, 0xd9, 0x98, 0xcf, 0x6e, - 0x9b, 0xf7, 0xfd, 0xb7, 0x8e, 0x93, 0xd2, 0xbd, 0x06, 0xc6, 0xd7, 0x22, - 0xb2, 0xfb, 0x7c, 0x9b, 0xa8, 0xaa, 0xeb, 0xc3, 0x55, 0xd5, 0x94, 0x9e, - 0xf3, 0xf4, 0xdf, 0x3f, 0xc2, 0x1e, 0x4b, 0xd4, 0x1a, 0x2e, 0x8d, 0x77, - 0xab, 0x6d, 0xf4, 0x99, 0xe3, 0x7d, 0x4b, 0xec, 0x0b, 0xc7, 0x47, 0x6b, - 0x84, 0xe1, 0xf7, 0x89, 0xe3, 0x7d, 0xb5, 0x9f, 0x00, 0x16, 0x72, 0x29, - 0xfb, 0xf8, 0x09, 0xff, 0xda, 0xb6, 0x33, 0xb5, 0x6c, 0x71, 0x26, 0xed, - 0xfe, 0x99, 0xe3, 0xd9, 0x0a, 0xf3, 0x83, 0x44, 0x4c, 0x74, 0x1e, 0x5e, - 0x38, 0x3e, 0x53, 0x0a, 0x4b, 0x48, 0xd3, 0xe2, 0xaf, 0x73, 0x8d, 0xf7, - 0xb0, 0x13, 0x6d, 0xa4, 0xab, 0x11, 0x0f, 0xe3, 0x0c, 0xf1, 0x9c, 0x00, - 0x9e, 0x24, 0xf0, 0x30, 0xde, 0xb8, 0xf4, 0xc6, 0x97, 0x76, 0xa2, 0x8d, - 0xb8, 0x78, 0x96, 0x8f, 0xaf, 0x47, 0xd4, 0xf9, 0xb7, 0x49, 0xaf, 0xc9, - 0x9c, 0xd6, 0xf5, 0x35, 0x4d, 0x92, 0x3f, 0x8b, 0xdc, 0xc6, 0x1e, 0xf3, - 0xc6, 0x77, 0x9b, 0xac, 0xb7, 0xe3, 0x8a, 0xf3, 0xec, 0xb1, 0x96, 0x8a, - 0x63, 0x0e, 0xe3, 0x65, 0x1f, 0x56, 0x79, 0xb0, 0x1d, 0x0d, 0x7c, 0x37, - 0x79, 0xb2, 0xe6, 0x99, 0x7e, 0xdd, 0xd9, 0x48, 0x0b, 0x40, 0x71, 0x0f, - 0xdd, 0x5b, 0xf7, 0xe0, 0xf3, 0x89, 0x85, 0x35, 0xd2, 0x96, 0x04, 0xaf, - 0x3e, 0x6d, 0x9f, 0xf6, 0xfe, 0xb8, 0x37, 0x89, 0x3f, 0xff, 0x3c, 0x5f, - 0x06, 0xa4, 0x8b, 0x3d, 0x74, 0xf9, 0x13, 0x75, 0x73, 0x12, 0x76, 0xc7, - 0x37, 0x10, 0xc7, 0x59, 0xb5, 0x29, 0xfb, 0x16, 0xdc, 0xbb, 0xf6, 0xb1, - 0xa8, 0x21, 0x14, 0x73, 0xb9, 0x38, 0xeb, 0xd5, 0xa3, 0xb2, 0x09, 0x5c, - 0x19, 0xd4, 0x94, 0x6e, 0x5d, 0x34, 0x0d, 0xff, 0xb8, 0x0e, 0xfd, 0xbc, - 0x6a, 0xf1, 0x2d, 0x26, 0xcc, 0x78, 0x27, 0xc5, 0xda, 0xcf, 0x01, 0xc3, - 0x3c, 0xea, 0xf6, 0x3b, 0xcb, 0x12, 0x60, 0x96, 0xb1, 0x76, 0xca, 0xf5, - 0xcb, 0xf4, 0xed, 0xc8, 0xa9, 0x50, 0xc3, 0x58, 0xff, 0xe3, 0xe4, 0xa3, - 0x8d, 0xb0, 0x3b, 0xbd, 0x83, 0x20, 0xe6, 0x2c, 0x26, 0xe6, 0x97, 0xe0, - 0xc3, 0x2b, 0x96, 0xda, 0xad, 0xb4, 0x46, 0x26, 0x2a, 0xf0, 0x49, 0xa8, - 0x78, 0x13, 0xf1, 0x25, 0x79, 0x5f, 0xdf, 0x43, 0x93, 0x35, 0x6c, 0xf6, - 0xa8, 0xaf, 0x52, 0xaf, 0x34, 0xe5, 0xa1, 0x33, 0x88, 0xcb, 0x23, 0x4f, - 0x20, 0xe6, 0x40, 0x5e, 0x67, 0x0a, 0xa8, 0xe2, 0xa9, 0x23, 0x3f, 0xf8, - 0x83, 0x19, 0xcb, 0xcd, 0xff, 0x75, 0x3c, 0x13, 0x97, 0xc7, 0xd0, 0x99, - 0x76, 0xed, 0x67, 0xf2, 0xda, 0xdf, 0xf4, 0x9b, 0x53, 0xaa, 0x0d, 0x39, - 0x06, 0x12, 0x4f, 0x64, 0x38, 0xe6, 0xa0, 0x48, 0x1f, 0xf3, 0x4e, 0xf8, - 0xe1, 0xbe, 0x35, 0x78, 0xb7, 0x33, 0x84, 0x57, 0x12, 0x3e, 0x13, 0x92, - 0xa6, 0x33, 0x7c, 0x0b, 0x91, 0x3d, 0xa8, 0xc3, 0x88, 0xb3, 0x2f, 0x8c, - 0x7e, 0x02, 0x7f, 0xfb, 0x90, 0x5f, 0x99, 0xc8, 0x8d, 0x77, 0x80, 0x07, - 0x2c, 0xf7, 0xec, 0x04, 0xdf, 0xd5, 0x2d, 0x6d, 0x11, 0xec, 0x21, 0x3c, - 0xf2, 0x43, 0x6b, 0x0f, 0xe8, 0x71, 0xcf, 0x27, 0x8e, 0xf0, 0x19, 0x91, - 0xfe, 0x05, 0xe9, 0x51, 0x7a, 0x4f, 0x58, 0x66, 0x52, 0x5c, 0x6b, 0x07, - 0x3c, 0xf7, 0x61, 0x4d, 0xef, 0x73, 0xdf, 0x94, 0xf2, 0xb7, 0xe9, 0xc6, - 0x9c, 0x81, 0x6f, 0xe4, 0x53, 0x29, 0x53, 0xfa, 0xab, 0x2e, 0x6c, 0xdf, - 0xda, 0x53, 0xdd, 0x7c, 0x97, 0x52, 0x96, 0x4b, 0x9b, 0x42, 0xee, 0x9b, - 0x87, 0x54, 0xc3, 0x83, 0x7c, 0x9b, 0x21, 0x0c, 0xeb, 0xd9, 0x2e, 0x0d, - 0x63, 0x0e, 0x52, 0x7e, 0xee, 0x9c, 0x52, 0xff, 0xd7, 0x9b, 0x4b, 0x63, - 0x4e, 0xa1, 0x6d, 0x05, 0xfb, 0xbf, 0xa9, 0x6d, 0x45, 0x54, 0xdc, 0xb3, - 0x15, 0x8c, 0x97, 0x39, 0xf6, 0x63, 0xf1, 0xf1, 0x7b, 0x5c, 0x7f, 0xef, - 0xc8, 0xac, 0xcd, 0xf7, 0x0b, 0x47, 0xae, 0xda, 0x05, 0xe3, 0xc0, 0x1d, - 0x79, 0x66, 0x52, 0xc7, 0xe7, 0x19, 0xc8, 0x7e, 0xb3, 0xa6, 0x6b, 0x35, - 0xb9, 0x56, 0x8b, 0xc8, 0x3b, 0x2b, 0x6d, 0xb2, 0xb9, 0xe4, 0xea, 0xfc, - 0xe6, 0x12, 0xf5, 0xdc, 0x94, 0x9f, 0xad, 0x58, 0x58, 0x4b, 0xe2, 0xaf, - 0x47, 0x6e, 0xac, 0xdc, 0x99, 0x77, 0x5e, 0xae, 0x3f, 0x0a, 0x5a, 0x7a, - 0x24, 0x64, 0x39, 0xba, 0xee, 0xca, 0x21, 0xf6, 0x15, 0x64, 0x42, 0xf2, - 0xe5, 0x7e, 0xd4, 0x7e, 0x08, 0xce, 0x61, 0xc6, 0x20, 0xdc, 0x7f, 0xf9, - 0xf3, 0xc8, 0x4d, 0x12, 0x30, 0x9e, 0x7e, 0xfd, 0xa6, 0xf8, 0xc5, 0x70, - 0x8f, 0x34, 0x5b, 0xdf, 0xec, 0x76, 0x63, 0x95, 0xe9, 0xd6, 0xa7, 0x96, - 0x1f, 0xaf, 0xdf, 0x04, 0xee, 0x11, 0xe8, 0x29, 0x75, 0xd3, 0x86, 0xce, - 0x9a, 0xb2, 0x3a, 0x94, 0xa8, 0x14, 0x84, 0xfe, 0x21, 0xc5, 0x7c, 0x11, - 0xfb, 0x92, 0x90, 0x47, 0xab, 0xce, 0x85, 0x32, 0x0a, 0x77, 0xbb, 0x30, - 0x27, 0xf9, 0xfa, 0xef, 0x63, 0x3e, 0x23, 0xd3, 0xf5, 0x71, 0x9c, 0x75, - 0x1a, 0x7a, 0xfb, 0x60, 0x8f, 0xb4, 0xf1, 0x9c, 0x14, 0x68, 0x7c, 0x44, - 0x66, 0xce, 0xce, 0xc9, 0x91, 0x32, 0xe9, 0xe4, 0x1b, 0x63, 0x22, 0x99, - 0x93, 0xe1, 0xf8, 0x0a, 0x72, 0x27, 0xd7, 0x1e, 0xd3, 0x32, 0x73, 0x0e, - 0x38, 0xca, 0xac, 0xff, 0xfb, 0xa1, 0x37, 0xc3, 0xba, 0x7e, 0x99, 0xd6, - 0x7e, 0x87, 0xf3, 0x6f, 0xe3, 0x9e, 0xfa, 0x0b, 0xfb, 0x00, 0x97, 0x47, - 0xad, 0x33, 0x85, 0x7c, 0x79, 0xb9, 0x8c, 0x3a, 0xcf, 0x0e, 0x31, 0xf7, - 0x52, 0xea, 0xa1, 0x5e, 0xa9, 0x96, 0x87, 0x4d, 0xa5, 0x98, 0x53, 0xf1, - 0x2e, 0xb8, 0x46, 0xfb, 0x8e, 0xa9, 0xb0, 0xd5, 0x2b, 0x2b, 0xe5, 0x02, - 0xea, 0x65, 0xe5, 0xbd, 0x67, 0x14, 0xc4, 0xb4, 0x5c, 0xbf, 0xa7, 0x6b, - 0x1b, 0xe6, 0x9f, 0xf5, 0x2f, 0x80, 0xc6, 0x0c, 0x2e, 0xf3, 0x24, 0xe8, - 0xc3, 0xf7, 0x32, 0x74, 0x7c, 0x81, 0x39, 0x5c, 0x06, 0x6b, 0x69, 0x39, - 0x76, 0x61, 0x0a, 0x34, 0x74, 0x4a, 0xff, 0x9f, 0xd1, 0xc6, 0x9e, 0xc4, - 0x1c, 0xc7, 0x09, 0xe8, 0xeb, 0xd7, 0xf1, 0x4d, 0xd8, 0x18, 0x7a, 0xca, - 0xa1, 0x17, 0xbd, 0x09, 0x5a, 0x58, 0x07, 0x43, 0xfe, 0x87, 0xe3, 0x52, - 0x3d, 0xfb, 0xb0, 0x4c, 0x2f, 0x3f, 0x0c, 0xfc, 0xff, 0x8a, 0xba, 0x00, - 0xf1, 0x6d, 0x99, 0x67, 0x31, 0xff, 0xe3, 0x39, 0x10, 0x10, 0x6d, 0x63, - 0x81, 0xf3, 0xec, 0x0f, 0x62, 0x3f, 0x6a, 0x8c, 0x72, 0x46, 0x66, 0xca, - 0x3c, 0x0b, 0x77, 0x87, 0x7c, 0x2a, 0x7f, 0x76, 0xca, 0xbb, 0xe3, 0x1e, - 0xc9, 0x45, 0x0b, 0xac, 0x2f, 0x10, 0x27, 0x96, 0x46, 0xb3, 0xa5, 0x84, - 0x99, 0x55, 0xc4, 0x95, 0x14, 0xc6, 0x06, 0x77, 0x2e, 0x22, 0xd6, 0x02, - 0x6a, 0xda, 0x34, 0xd7, 0x4e, 0x7a, 0x6f, 0x06, 0xc4, 0xf5, 0x63, 0x99, - 0x80, 0x8e, 0xf5, 0x2f, 0x8c, 0x20, 0x17, 0xfe, 0x29, 0x72, 0xc9, 0xb8, - 0x27, 0x83, 0x71, 0x4f, 0x37, 0xda, 0x1a, 0x74, 0x02, 0xf7, 0x5c, 0xc6, - 0xdd, 0x97, 0xa1, 0x07, 0xf0, 0xd5, 0xaf, 0x6e, 0xe9, 0xc7, 0x78, 0x43, - 0x8e, 0xd9, 0x21, 0xff, 0x50, 0x49, 0x24, 0xd7, 0xa1, 0x3f, 0x37, 0x50, - 0x0b, 0xac, 0xa3, 0x3e, 0xdc, 0xb4, 0x23, 0xa8, 0x4b, 0x0e, 0x83, 0x7e, - 0xe6, 0x94, 0x1c, 0xc7, 0x74, 0xae, 0xd3, 0x62, 0x3d, 0x7f, 0x8f, 0x7e, - 0xd7, 0x95, 0xaf, 0xf6, 0xb0, 0xa6, 0x64, 0x3d, 0xce, 0x37, 0xe9, 0x77, - 0x70, 0x8f, 0xeb, 0x26, 0xd7, 0xfd, 0x7d, 0xac, 0x05, 0x7c, 0xfd, 0x21, - 0x2d, 0xd4, 0x1f, 0xee, 0x21, 0x4c, 0x8f, 0xb6, 0x93, 0xbc, 0xc6, 0x47, - 0x9d, 0xfd, 0x9b, 0x6e, 0xd7, 0xce, 0x74, 0x9e, 0x65, 0x5e, 0x13, 0x5f, - 0x7f, 0x3f, 0x74, 0x58, 0xd7, 0x65, 0x87, 0xe0, 0xbb, 0xeb, 0x8e, 0xbc, - 0x60, 0xdf, 0x69, 0x77, 0xfb, 0xcb, 0xbe, 0x9c, 0x28, 0xc7, 0xc3, 0x72, - 0xaa, 0x9e, 0x80, 0x4d, 0x50, 0x86, 0x56, 0x83, 0x0c, 0x45, 0xfe, 0xaa, - 0x2c, 0xf2, 0x4a, 0x99, 0x6b, 0x5a, 0x86, 0xb1, 0x6c, 0xa8, 0x8d, 0xef, - 0xea, 0xd0, 0xcb, 0xb7, 0xe5, 0xc8, 0xa2, 0xc8, 0x05, 0xac, 0xaf, 0x96, - 0x69, 0xab, 0x23, 0xc8, 0x5f, 0x77, 0x49, 0x75, 0x09, 0x35, 0x59, 0x59, - 0xa6, 0xb3, 0x9f, 0x63, 0xbc, 0x89, 0xc8, 0xa6, 0x7e, 0x8f, 0x15, 0x19, - 0xbc, 0x18, 0x96, 0xf0, 0x45, 0x14, 0x7f, 0x90, 0xfd, 0xa5, 0x21, 0xff, - 0x7d, 0xd6, 0xb5, 0xf9, 0x62, 0x09, 0x7b, 0xcb, 0xfd, 0xda, 0x4f, 0x16, - 0x6b, 0x33, 0x92, 0xaf, 0xf0, 0x2c, 0xf4, 0x4b, 0x71, 0xac, 0xa5, 0x64, - 0xf6, 0xec, 0x88, 0x3c, 0x8b, 0x33, 0x50, 0xff, 0xe1, 0x8c, 0x09, 0x29, - 0x5c, 0xc0, 0x7c, 0xed, 0xba, 0x2c, 0xad, 0xcc, 0x48, 0xb5, 0x72, 0xb9, - 0xe1, 0xdd, 0x1d, 0xe3, 0xa5, 0xc6, 0x5a, 0xf6, 0x30, 0xeb, 0x19, 0xd4, - 0xaa, 0x16, 0xc6, 0x90, 0x59, 0x6d, 0x76, 0xfa, 0xce, 0xf7, 0xe2, 0xc6, - 0x1a, 0x76, 0x52, 0xe6, 0xcb, 0x29, 0x29, 0x9e, 0x1d, 0xd1, 0x6f, 0x0a, - 0x2d, 0xe9, 0xca, 0xd3, 0x37, 0x11, 0x2b, 0x26, 0xf5, 0x7b, 0xf1, 0x2d, - 0x79, 0xcc, 0x9e, 0x97, 0xa3, 0xd6, 0x41, 0x39, 0x85, 0xfc, 0xfa, 0x4b, - 0x76, 0xab, 0xc4, 0xbb, 0x79, 0x8f, 0xa0, 0xd7, 0x62, 0x0d, 0xea, 0xc8, - 0x84, 0xfd, 0xa0, 0xf9, 0x3c, 0x24, 0xfb, 0x4e, 0x8d, 0x71, 0xf2, 0xbf, - 0x9d, 0x0c, 0xe2, 0xde, 0x4d, 0xd4, 0x8e, 0x19, 0x0d, 0x67, 0xb8, 0x70, - 0x15, 0xc2, 0x0d, 0x9b, 0x2f, 0x10, 0x6e, 0xc9, 0xf0, 0xe0, 0x0c, 0xc0, - 0x85, 0x64, 0xc3, 0x0e, 0x43, 0x47, 0x26, 0xc1, 0x27, 0x7c, 0xfc, 0x68, - 0x87, 0x97, 0x07, 0xb7, 0x22, 0xb6, 0xde, 0xde, 0xff, 0x86, 0xb7, 0xff, - 0x59, 0x6f, 0xff, 0xd5, 0xad, 0xfd, 0x7e, 0x7c, 0xfd, 0x85, 0x23, 0x0d, - 0x74, 0xbd, 0x51, 0x72, 0xe1, 0xe7, 0x3d, 0xba, 0xae, 0x6e, 0xd1, 0xe5, - 0xc3, 0x43, 0x9e, 0x9a, 0x67, 0xfa, 0x66, 0xfa, 0xe8, 0x7e, 0xc8, 0xd1, - 0x91, 0x9c, 0x0d, 0xdb, 0x28, 0x27, 0xc6, 0x0b, 0xfa, 0x2d, 0x4d, 0xc9, - 0x7a, 0x74, 0x5e, 0x26, 0xad, 0xc4, 0xf8, 0xac, 0x84, 0xa0, 0xcb, 0xf4, - 0x2d, 0x21, 0xa9, 0xd2, 0xe7, 0xa0, 0xcf, 0xdb, 0x3b, 0xd3, 0xfa, 0x4e, - 0x03, 0xad, 0xa1, 0x97, 0x49, 0xa3, 0x4b, 0x6b, 0x64, 0xe0, 0x36, 0xad, - 0x2e, 0xbc, 0x4b, 0xeb, 0x3b, 0xa5, 0x06, 0xf8, 0x8b, 0x61, 0x0f, 0x3e, - 0xdc, 0x00, 0x4f, 0x7d, 0x66, 0x5e, 0x41, 0x7d, 0x26, 0x6d, 0x9f, 0x85, - 0x6d, 0x48, 0xa4, 0x35, 0x5d, 0x39, 0xfe, 0xc0, 0x80, 0x23, 0x11, 0xe4, - 0x1b, 0xcd, 0x58, 0xdb, 0xac, 0x30, 0x17, 0x51, 0x7d, 0xcd, 0x32, 0x08, - 0x9d, 0xe5, 0xdd, 0xb9, 0x6f, 0x82, 0x8f, 0xe9, 0x9c, 0xc0, 0x91, 0xa3, - 0x36, 0x69, 0x79, 0xdf, 0x79, 0x25, 0x3a, 0x68, 0x17, 0x65, 0xc8, 0x6c, - 0xc6, 0xf9, 0xd5, 0xba, 0xc6, 0x99, 0x24, 0x2d, 0xe7, 0x87, 0xfa, 0xcd, - 0xbf, 0x07, 0x9f, 0x13, 0x15, 0x43, 0xaa, 0x56, 0x22, 0x76, 0x09, 0x38, - 0xf6, 0xe1, 0x6e, 0xaa, 0x23, 0xa4, 0x47, 0xe4, 0x08, 0xf4, 0xbb, 0xaa, - 0xe3, 0x22, 0xf5, 0x38, 0x31, 0x59, 0x40, 0xae, 0xf3, 0xd7, 0x3a, 0xb6, - 0x39, 0xce, 0x4d, 0xc4, 0xb7, 0xc9, 0x6d, 0xba, 0xa7, 0x2e, 0xba, 0xba, - 0xa7, 0x2e, 0xa2, 0x06, 0x3e, 0x1d, 0x91, 0x96, 0x55, 0xd8, 0xcf, 0xcb, - 0x7b, 0xdc, 0x7c, 0xee, 0x65, 0xfe, 0xe6, 0x04, 0x7f, 0x77, 0x3a, 0x2c, - 0xd6, 0x69, 0x1d, 0x0f, 0x20, 0xef, 0x09, 0x99, 0x3d, 0x47, 0x9f, 0x6a, - 0xc9, 0xc0, 0x69, 0xde, 0x07, 0xf3, 0x9a, 0xa5, 0xd1, 0x19, 0xd8, 0xc8, - 0x1c, 0xfc, 0x82, 0x5a, 0x7d, 0x57, 0x66, 0x2c, 0xca, 0xa1, 0x53, 0xda, - 0x56, 0x51, 0x8f, 0xaf, 0xc2, 0x37, 0xac, 0xc6, 0xa4, 0x09, 0xb6, 0xa5, - 0x2e, 0x46, 0x8d, 0xe2, 0xe2, 0x07, 0xb0, 0x07, 0xfe, 0x7e, 0x83, 0xdc, - 0xf2, 0x62, 0xcc, 0xa0, 0x6d, 0xa9, 0x8b, 0xd4, 0x73, 0xa4, 0x53, 0x17, - 0xa9, 0xe7, 0xa4, 0xc3, 0xb7, 0x17, 0x7c, 0x5f, 0x1c, 0xd1, 0xef, 0xd3, - 0x37, 0x6d, 0xf2, 0xf2, 0x8f, 0x92, 0xad, 0x30, 0x47, 0x24, 0x3f, 0xd2, - 0x8d, 0x5c, 0xa6, 0x2b, 0x6b, 0x0f, 0x8c, 0x6f, 0xca, 0xa7, 0xe5, 0xeb, - 0xee, 0x4f, 0xc1, 0x17, 0xf9, 0x68, 0xe4, 0x8b, 0x3c, 0x75, 0x4a, 0x93, - 0xe6, 0xcb, 0xe7, 0x07, 0x82, 0x06, 0x3f, 0x7d, 0xa7, 0x63, 0xc0, 0xff, - 0x75, 0xf8, 0x80, 0x5e, 0xf4, 0x4f, 0xa2, 0x47, 0x48, 0xbb, 0x48, 0xde, - 0xc9, 0xeb, 0x0d, 0xe4, 0x8d, 0x3e, 0x9f, 0xd3, 0xf8, 0x7e, 0x5d, 0x66, - 0x17, 0x9d, 0x93, 0x88, 0xab, 0x7c, 0x3b, 0xef, 0x71, 0xdf, 0x81, 0xb7, - 0xf3, 0xfe, 0xba, 0xb8, 0xf2, 0x49, 0x98, 0x55, 0xc1, 0xf7, 0xca, 0x76, - 0x59, 0x34, 0xfa, 0x8e, 0x98, 0xce, 0xc3, 0x8f, 0xd4, 0xe8, 0x27, 0x28, - 0xa3, 0x1b, 0x92, 0x5d, 0xe4, 0xfb, 0x97, 0x8b, 0x6f, 0xba, 0xe6, 0xfb, - 0x8d, 0xc6, 0x3d, 0x36, 0xe0, 0x7a, 0x01, 0x47, 0xba, 0xd6, 0x29, 0x3f, - 0xf8, 0x9c, 0xbd, 0x0d, 0xbe, 0xa6, 0x71, 0xdf, 0xb8, 0x3c, 0x87, 0x3c, - 0xe0, 0x0d, 0xfb, 0x0e, 0xb9, 0x4e, 0x33, 0x17, 0xaa, 0xd6, 0xa6, 0x60, - 0x93, 0x4d, 0xf0, 0x65, 0xa6, 0x6c, 0x96, 0x9a, 0xa5, 0x8a, 0x7c, 0x67, - 0x79, 0x85, 0xbe, 0x90, 0xb4, 0xb7, 0x61, 0xde, 0xf5, 0x5f, 0xf4, 0xb5, - 0x9b, 0x25, 0xc4, 0x59, 0xd8, 0xf6, 0x66, 0x29, 0x8a, 0xbe, 0x17, 0xbd, - 0x85, 0x3e, 0x8e, 0x3e, 0x89, 0x7e, 0x04, 0xfd, 0x08, 0x7a, 0x0b, 0x7b, - 0x63, 0xe8, 0xfd, 0x9a, 0x81, 0xb8, 0x6e, 0xf3, 0x5d, 0xd4, 0xe7, 0x21, - 0x57, 0xb4, 0x18, 0xd3, 0xc2, 0x76, 0x0e, 0x75, 0x44, 0x76, 0x84, 0xb9, - 0x1e, 0x73, 0xbe, 0x8f, 0x1d, 0xd3, 0x62, 0x5d, 0x5e, 0x30, 0xf6, 0x0d, - 0x31, 0x2e, 0x54, 0x10, 0x17, 0x3e, 0xd8, 0x8d, 0xfa, 0xd1, 0xdc, 0xaf, - 0xdf, 0x8e, 0x16, 0x31, 0xe6, 0x37, 0x6a, 0xde, 0xe8, 0x1c, 0xe2, 0x14, - 0xfd, 0xa7, 0x83, 0x3d, 0x79, 0xf8, 0xf1, 0x2e, 0xd8, 0x5f, 0x06, 0x7e, - 0x1b, 0xdf, 0x4b, 0x6f, 0xec, 0x76, 0x63, 0x2a, 0xf2, 0x77, 0xb5, 0xfd, - 0xbd, 0xc6, 0xc6, 0x9e, 0x9d, 0x6a, 0x83, 0x0e, 0xe0, 0x48, 0x54, 0x96, - 0x60, 0x83, 0x3f, 0xb4, 0x4f, 0xea, 0xdc, 0x8e, 0x77, 0xf1, 0x2c, 0x72, - 0xd4, 0xdc, 0x02, 0x73, 0x98, 0x13, 0xa8, 0x4b, 0x50, 0x9f, 0x45, 0x59, - 0x93, 0x33, 0x16, 0xe8, 0x5c, 0x34, 0x2a, 0x6d, 0x8c, 0x03, 0x37, 0x70, - 0x1e, 0xf8, 0x5a, 0x76, 0x20, 0xb3, 0x03, 0xc8, 0x09, 0x1d, 0x27, 0x6c, - 0xed, 0x93, 0xf8, 0x21, 0xfa, 0x1c, 0xc1, 0x7e, 0x53, 0xdc, 0xf7, 0x74, - 0xf8, 0xdd, 0x29, 0xfd, 0x5b, 0x31, 0x94, 0xeb, 0xb3, 0xd8, 0x7b, 0x17, - 0x70, 0x71, 0x9e, 0x6f, 0xd9, 0x22, 0xfb, 0x16, 0xdc, 0x9c, 0x56, 0x59, - 0x8d, 0xf8, 0x7e, 0xd5, 0xc3, 0xc7, 0x75, 0xe5, 0xfd, 0xa6, 0xb1, 0xc7, - 0x7d, 0x1b, 0xc6, 0x1d, 0x9f, 0x42, 0xfe, 0xbc, 0x81, 0x7b, 0x79, 0x03, - 0x77, 0x72, 0xa5, 0x44, 0x5d, 0x1f, 0x86, 0xde, 0x43, 0x86, 0x53, 0xc4, - 0x35, 0xa2, 0xcf, 0xde, 0x28, 0xc1, 0x77, 0xd2, 0xff, 0x29, 0x64, 0x77, - 0x6d, 0x6e, 0x4c, 0x77, 0xf1, 0xf4, 0xba, 0x70, 0xe2, 0xaf, 0xed, 0xd6, - 0xf4, 0x54, 0xf5, 0x3b, 0x18, 0xe5, 0x04, 0x1d, 0xe4, 0x6f, 0x03, 0x1a, - 0xe6, 0x6b, 0x51, 0xfd, 0xfe, 0xae, 0x38, 0x47, 0x3e, 0x46, 0x24, 0xbb, - 0xe0, 0xef, 0xeb, 0xc6, 0xbe, 0xd6, 0x06, 0x5c, 0x77, 0x6f, 0xe3, 0x41, - 0x79, 0x3c, 0x70, 0xfd, 0x93, 0x6f, 0xc3, 0x85, 0xad, 0xb7, 0x61, 0xc6, - 0x5f, 0xde, 0x4d, 0x0a, 0xfb, 0xfd, 0xfb, 0xe9, 0xf5, 0x6a, 0x81, 0xc4, - 0x7c, 0x41, 0x98, 0xab, 0xf0, 0x8e, 0xc6, 0x61, 0xd7, 0x5d, 0xc0, 0x6f, - 0x4b, 0xa5, 0xd4, 0x22, 0xaa, 0x87, 0xb5, 0x31, 0x73, 0xe5, 0xc6, 0x33, - 0x7f, 0xdb, 0x3b, 0x13, 0xf5, 0xf4, 0x19, 0xe6, 0xcd, 0x3a, 0xce, 0x00, - 0xa6, 0x7d, 0x1b, 0x6d, 0xbf, 0xee, 0xc1, 0x71, 0x3d, 0x29, 0x05, 0xe4, - 0xa1, 0xb9, 0x05, 0x64, 0xf4, 0xf0, 0xdf, 0x2a, 0xcd, 0xdf, 0xb3, 0xf8, - 0x86, 0x37, 0x1c, 0x9f, 0x05, 0x8d, 0x05, 0x33, 0xc3, 0x77, 0x33, 0xe0, - 0xd8, 0xbb, 0x0d, 0xc7, 0x84, 0x87, 0x63, 0x42, 0x8a, 0xe7, 0x26, 0x61, - 0x6b, 0x19, 0xc4, 0xf7, 0x7e, 0xf3, 0x80, 0x7c, 0x1e, 0xc5, 0x35, 0xe6, - 0x2e, 0x8c, 0xe0, 0x9e, 0x1c, 0x67, 0x9f, 0x7d, 0x18, 0x74, 0xbf, 0x86, - 0xd8, 0xea, 0xe7, 0x3c, 0xc5, 0x58, 0x08, 0x31, 0xec, 0x98, 0xfe, 0x0d, - 0xb6, 0x60, 0x9a, 0xd0, 0x57, 0x65, 0x0c, 0x27, 0x51, 0xde, 0x23, 0xbe, - 0xcd, 0x23, 0x56, 0x91, 0xcf, 0x0e, 0x29, 0x9a, 0xc6, 0xa3, 0x21, 0xe4, - 0x35, 0xd9, 0x05, 0xda, 0x91, 0x0c, 0x84, 0xd2, 0xcd, 0xc8, 0x49, 0x1d, - 0xf9, 0x99, 0xcd, 0x7f, 0xa3, 0x30, 0x2f, 0x1b, 0x35, 0x13, 0xfd, 0x3a, - 0xee, 0xe1, 0xdb, 0xf8, 0xbe, 0xde, 0x83, 0xbc, 0x0f, 0x2b, 0x19, 0xe8, - 0x6e, 0x52, 0xe7, 0x33, 0xcc, 0x23, 0xaa, 0x88, 0xb7, 0x0a, 0xb1, 0x06, - 0x79, 0xd5, 0x38, 0x73, 0xd7, 0xe7, 0x96, 0xaf, 0xcb, 0x95, 0x45, 0xfe, - 0x06, 0xca, 0xb8, 0x7c, 0x90, 0xfe, 0xc0, 0x9c, 0x4b, 0x61, 0x6e, 0x85, - 0xbe, 0x0c, 0xe3, 0x3a, 0x0c, 0xa8, 0x07, 0x39, 0x02, 0x72, 0xed, 0x4d, - 0x2b, 0x09, 0x3e, 0xaf, 0xcb, 0xc6, 0x62, 0x58, 0x96, 0x2d, 0xe6, 0x45, - 0x12, 0xcf, 0x02, 0x76, 0x63, 0xe5, 0x9a, 0xab, 0x13, 0x84, 0x47, 0xcd, - 0x53, 0x40, 0x5e, 0x77, 0x40, 0xef, 0xfd, 0x65, 0xf7, 0x4c, 0x9a, 0x1a, - 0xeb, 0xbc, 0x19, 0xd9, 0xa0, 0x3d, 0xd9, 0x7c, 0x93, 0x62, 0x6e, 0x70, - 0x02, 0x3a, 0xcb, 0xdc, 0x9d, 0xf5, 0x00, 0xbe, 0x6b, 0x5c, 0x27, 0xef, - 0xe8, 0x97, 0xfa, 0x21, 0x1b, 0xda, 0x3d, 0xdf, 0xc4, 0x10, 0x47, 0x15, - 0x6d, 0xbd, 0xa8, 0x7d, 0x41, 0xb1, 0x3c, 0x83, 0x98, 0x02, 0x1f, 0xc0, - 0xdf, 0x70, 0xa6, 0xa6, 0x70, 0x97, 0xe3, 0x80, 0xdb, 0x16, 0x4b, 0xd6, - 0x8a, 0x3a, 0x2f, 0x53, 0xe7, 0x6f, 0xbf, 0xdf, 0xe4, 0x61, 0x3f, 0x6a, - 0x0d, 0xba, 0x05, 0x1b, 0x52, 0x6b, 0x51, 0xf4, 0xf0, 0xc7, 0x6b, 0xa8, - 0x2f, 0x4a, 0x7c, 0x1f, 0x42, 0x6d, 0x50, 0xe2, 0xdb, 0x49, 0x12, 0xfd, - 0x08, 0xdf, 0x8b, 0x3c, 0xbf, 0x46, 0xfc, 0xa4, 0xc3, 0xf7, 0x2f, 0xcc, - 0x25, 0xe9, 0x5f, 0xfc, 0x7c, 0xd2, 0xd5, 0x85, 0x53, 0x65, 0xfa, 0x10, - 0xea, 0x75, 0x3f, 0xfc, 0x16, 0x75, 0xc1, 0xcd, 0x25, 0x57, 0x2a, 0xae, - 0xcc, 0x66, 0xeb, 0x97, 0x75, 0x8c, 0xd8, 0x2f, 0x16, 0x74, 0x8c, 0xb2, - 0xc3, 0x9a, 0x8e, 0x01, 0x97, 0x24, 0xa3, 0x7b, 0xca, 0xec, 0x75, 0xc9, - 0xac, 0x8c, 0xc8, 0x0b, 0xda, 0x6f, 0xf9, 0x3e, 0x8b, 0x39, 0x64, 0x0c, - 0xf2, 0x4b, 0xca, 0xf3, 0x67, 0xaf, 0x4b, 0xf6, 0x45, 0xfa, 0xad, 0xe1, - 0x58, 0xab, 0x41, 0x5f, 0xe5, 0x48, 0x0d, 0xb1, 0xe9, 0x80, 0xcd, 0x7f, - 0x07, 0x10, 0x42, 0x4d, 0xe7, 0x48, 0xf3, 0x68, 0xc2, 0x8e, 0x1b, 0xfd, - 0x4f, 0xb6, 0x1a, 0x8c, 0x8d, 0xc3, 0xe6, 0x53, 0xe2, 0xbf, 0x47, 0xb5, - 0xc8, 0x53, 0xfa, 0xad, 0x02, 0x66, 0xbb, 0xf0, 0x91, 0xfe, 0x1d, 0xe5, - 0x66, 0x8a, 0xb2, 0xc6, 0x78, 0x8d, 0xf3, 0x85, 0xc8, 0xcd, 0x54, 0x93, - 0x14, 0xef, 0x72, 0x9c, 0xa3, 0xa3, 0xa9, 0xdd, 0xee, 0xbf, 0x15, 0xf9, - 0xc6, 0x5d, 0xae, 0x2f, 0x38, 0xea, 0x8d, 0x5f, 0x41, 0x4f, 0xdd, 0x66, - 0xbc, 0x65, 0x7c, 0xe4, 0xbd, 0xa1, 0x5f, 0xe1, 0x37, 0x63, 0xef, 0x3c, - 0x62, 0x2f, 0xe3, 0x65, 0x97, 0xe4, 0x0e, 0x6b, 0x9f, 0xc1, 0xf9, 0x82, - 0x9b, 0x4b, 0x7b, 0x70, 0x95, 0x69, 0x99, 0xad, 0x30, 0x87, 0xda, 0x40, - 0x2c, 0x1b, 0x82, 0xae, 0x32, 0xa6, 0x9d, 0x44, 0x3c, 0xe7, 0xef, 0xd2, - 0x58, 0x5b, 0xe2, 0xbe, 0x44, 0x32, 0xae, 0xc0, 0xf3, 0x96, 0x4e, 0xdd, - 0x8c, 0xf2, 0x3d, 0xea, 0xd2, 0x10, 0xee, 0xfd, 0x4f, 0x59, 0x5b, 0x0c, - 0x68, 0x1d, 0xc9, 0xbe, 0x4c, 0xd9, 0xbb, 0xbf, 0x5b, 0x4b, 0xb7, 0x6b, - 0x03, 0xcc, 0x03, 0x1e, 0x87, 0x5c, 0xf6, 0xdb, 0xd7, 0x19, 0xbb, 0xff, - 0x5d, 0x59, 0xc3, 0xc9, 0xa7, 0x0c, 0xda, 0x36, 0xc6, 0x2b, 0x21, 0x59, - 0x8a, 0x92, 0x7f, 0xc8, 0xcb, 0xa0, 0xed, 0xec, 0x24, 0x87, 0xed, 0x32, - 0xf8, 0x4b, 0xc8, 0x80, 0xb2, 0xf4, 0x65, 0xc0, 0xef, 0x49, 0xdc, 0x17, - 0x6b, 0x86, 0x7e, 0x5d, 0x47, 0x16, 0xeb, 0xee, 0xd9, 0xc5, 0x72, 0x23, - 0xcd, 0xa4, 0x97, 0x77, 0x7a, 0x49, 0x72, 0xfa, 0x7e, 0xe7, 0x25, 0x57, - 0xb9, 0x24, 0xfb, 0x2a, 0xf3, 0xf2, 0x98, 0xf5, 0x28, 0xf8, 0xbd, 0xe6, - 0xcc, 0x58, 0xba, 0x56, 0x19, 0xcf, 0xff, 0x6f, 0xe7, 0x56, 0x1b, 0xdb, - 0x56, 0x75, 0x86, 0x5f, 0x5f, 0xdb, 0x69, 0x1a, 0x9a, 0x70, 0xeb, 0x3a, - 0x89, 0x9b, 0x66, 0xad, 0x1d, 0xdf, 0x7e, 0x88, 0xa4, 0xe8, 0x36, 0x64, - 0x34, 0xea, 0x82, 0x62, 0x9c, 0x50, 0xc2, 0xe8, 0x44, 0xda, 0x75, 0x55, - 0xb5, 0x31, 0x64, 0x39, 0xe9, 0x07, 0xd3, 0x06, 0xa3, 0xb0, 0x82, 0x18, - 0x52, 0x8d, 0xdb, 0x6a, 0x9d, 0x96, 0xc6, 0xe9, 0x07, 0x6b, 0x37, 0x69, - 0x9a, 0xe5, 0xa4, 0x2d, 0x48, 0x11, 0x2e, 0x88, 0x6e, 0xfb, 0xb1, 0x8d, - 0x2a, 0x65, 0xec, 0xff, 0xf6, 0x67, 0xda, 0xd0, 0x16, 0x15, 0x18, 0xfc, - 0xd8, 0xa4, 0xfe, 0xe0, 0x47, 0x25, 0xe8, 0xbc, 0xe7, 0x79, 0xcf, 0xbd, - 0x8e, 0x6d, 0x82, 0x26, 0x2d, 0x52, 0xe4, 0x7b, 0xce, 0x3d, 0xf7, 0x9c, - 0x73, 0xcf, 0xfb, 0xfd, 0xbe, 0xcf, 0xc5, 0xda, 0x13, 0x7d, 0x6b, 0xe5, - 0x63, 0xf8, 0x1d, 0x27, 0x67, 0x6d, 0xc9, 0xd8, 0x83, 0xf2, 0x63, 0xcd, - 0xe5, 0x33, 0x3e, 0x09, 0xc0, 0x27, 0x35, 0xb8, 0x02, 0x69, 0x77, 0x62, - 0x37, 0x85, 0x3e, 0x65, 0x18, 0xb4, 0x8e, 0x1b, 0xbf, 0xd9, 0x36, 0xf7, - 0x37, 0x9d, 0x81, 0xef, 0xee, 0x0e, 0xb4, 0xfb, 0x39, 0x5f, 0xe3, 0xdf, - 0xfe, 0xc5, 0xab, 0xa1, 0x0d, 0xca, 0x0c, 0xf6, 0xf3, 0x96, 0xea, 0x59, - 0x07, 0xbc, 0xc4, 0xdc, 0x74, 0x4c, 0xf3, 0x0f, 0xe1, 0x69, 0xea, 0xa8, - 0xab, 0xd0, 0x51, 0x43, 0xd4, 0x5d, 0xc3, 0xb3, 0x2e, 0xf3, 0x03, 0x51, - 0xf9, 0xf3, 0x14, 0xf5, 0x70, 0x5c, 0xfe, 0x34, 0xf5, 0x02, 0xf6, 0x93, - 0x28, 0x32, 0x47, 0x79, 0x63, 0x26, 0x47, 0x3f, 0x49, 0xfd, 0xf9, 0xb4, - 0xfb, 0xac, 0xda, 0x81, 0xb8, 0x95, 0x5f, 0x13, 0x56, 0x7d, 0xf3, 0xb4, - 0xd6, 0x74, 0xe3, 0x56, 0xb7, 0xdc, 0x38, 0x6f, 0x74, 0x6c, 0x78, 0x3a, - 0x1a, 0x18, 0x99, 0xa3, 0x5d, 0x4a, 0xc6, 0xb2, 0xd6, 0x0a, 0x39, 0x10, - 0x65, 0xee, 0x39, 0x45, 0xfd, 0x0c, 0x5b, 0xd8, 0x6b, 0x67, 0xad, 0x66, - 0xcf, 0xfe, 0xc4, 0x1a, 0xf4, 0xec, 0xd3, 0x9e, 0x9e, 0xe5, 0xbd, 0x14, - 0x68, 0x4a, 0x5b, 0x94, 0x98, 0x19, 0xb5, 0x92, 0xb0, 0x79, 0xb8, 0x9e, - 0xe7, 0xfc, 0x71, 0x39, 0x32, 0x7f, 0x18, 0xfe, 0x77, 0xaf, 0xbd, 0x87, - 0x76, 0xd5, 0x1e, 0x22, 0x16, 0x07, 0xeb, 0x7f, 0xa9, 0x61, 0xae, 0xc7, - 0xbd, 0xb9, 0x78, 0x1f, 0x72, 0x3e, 0xed, 0xc8, 0x04, 0x6c, 0xc9, 0x88, - 0x6d, 0xf6, 0x5a, 0x3f, 0x76, 0x77, 0x75, 0xdd, 0x13, 0x05, 0xc7, 0xc3, - 0x85, 0xe1, 0x17, 0xbe, 0xd0, 0xd7, 0x23, 0x5c, 0x93, 0xeb, 0xb5, 0x49, - 0x7a, 0x1f, 0xf4, 0xcb, 0x34, 0xff, 0x73, 0x5e, 0xed, 0x0a, 0xf1, 0x4a, - 0xb4, 0x6b, 0x19, 0xdb, 0xf4, 0x80, 0x37, 0xdf, 0xb6, 0x0e, 0x69, 0x89, - 0xd6, 0x8c, 0x67, 0x6e, 0x85, 0xed, 0xb8, 0xe4, 0xe6, 0xf9, 0x5b, 0xa9, - 0x44, 0x9c, 0x26, 0xd9, 0x63, 0xaf, 0x6b, 0x98, 0x63, 0x2b, 0xfa, 0x8c, - 0x4f, 0x10, 0x9c, 0x0e, 0x78, 0xbe, 0xc5, 0x06, 0xfa, 0x4d, 0xde, 0x75, - 0xb3, 0xe6, 0x64, 0xe2, 0x56, 0x57, 0xc3, 0x7b, 0x6c, 0xa8, 0xda, 0xe1, - 0xb8, 0x45, 0xdd, 0xd9, 0x14, 0x95, 0x36, 0xf2, 0x50, 0x45, 0xfd, 0xf8, - 0x90, 0x63, 0xb0, 0x16, 0x51, 0xe7, 0x60, 0x07, 0x73, 0xf6, 0x6f, 0xeb, - 0xb9, 0xb5, 0xd2, 0x27, 0xc0, 0x35, 0xf8, 0xe4, 0x73, 0xf9, 0x5e, 0xe6, - 0x7a, 0x31, 0x7f, 0x0b, 0xe7, 0x77, 0xbd, 0x73, 0x4e, 0xb8, 0x39, 0xeb, - 0x7e, 0xc9, 0x9e, 0x37, 0xfc, 0x97, 0x76, 0xc0, 0x7b, 0x6d, 0x68, 0xcf, - 0xd1, 0x26, 0x7c, 0xd1, 0x3c, 0xbe, 0x6d, 0xd8, 0xa2, 0xb6, 0xe1, 0x78, - 0x81, 0xfc, 0x49, 0xbe, 0xf4, 0xf9, 0xd1, 0xd7, 0x79, 0xe4, 0x51, 0xea, - 0xd9, 0x41, 0x39, 0x53, 0xe0, 0xd9, 0xa4, 0xb4, 0xa6, 0xb5, 0xf1, 0xec, - 0x84, 0xe2, 0xb1, 0x7a, 0xa6, 0x13, 0x17, 0x73, 0x32, 0x2c, 0x57, 0x5d, - 0x9e, 0x59, 0xa2, 0x98, 0x09, 0xb6, 0xd6, 0xbc, 0xff, 0x3e, 0x3d, 0xb3, - 0xb0, 0xfa, 0x8c, 0x31, 0x8c, 0x7d, 0xc9, 0xa3, 0x77, 0x9b, 0x9e, 0x6d, - 0xa6, 0x8e, 0x3e, 0x8f, 0xea, 0x39, 0x85, 0xa1, 0x13, 0x59, 0xc7, 0x0f, - 0x47, 0xf8, 0x0c, 0xd7, 0xa5, 0xcf, 0xc7, 0xb5, 0xc8, 0x7b, 0x3d, 0xb0, - 0xd8, 0xfd, 0x12, 0xdc, 0x01, 0xd1, 0xdf, 0xc1, 0x3a, 0x72, 0x00, 0xb2, - 0xba, 0xd1, 0x60, 0x5f, 0xc6, 0x8d, 0xaf, 0x91, 0xb1, 0xde, 0xc2, 0x39, - 0x22, 0x56, 0x81, 0x1f, 0x7d, 0xfc, 0xa7, 0x77, 0x30, 0x5f, 0xc6, 0xf3, - 0xd7, 0x07, 0x30, 0x3f, 0xcf, 0x82, 0x32, 0x36, 0xb5, 0x8d, 0xbc, 0x3a, - 0xaa, 0xf5, 0x41, 0x3e, 0x43, 0x39, 0xe6, 0x99, 0x91, 0x2e, 0x7f, 0xc3, - 0xf3, 0x6c, 0x6f, 0x6d, 0xa0, 0x63, 0xd2, 0xdb, 0x9f, 0x7f, 0x3f, 0x2c, - 0xe1, 0x0e, 0xea, 0xb8, 0xa8, 0x24, 0xa7, 0x19, 0xb3, 0xc0, 0x76, 0x8d, - 0x73, 0xae, 0xff, 0xad, 0x8b, 0x33, 0xff, 0xa7, 0x2e, 0xce, 0x58, 0x1f, - 0x29, 0xef, 0x84, 0x35, 0x8f, 0xf5, 0xc5, 0x74, 0x2d, 0xd6, 0xd1, 0xd5, - 0xaf, 0xdd, 0x47, 0xab, 0x74, 0xfc, 0x51, 0x81, 0xf6, 0x2a, 0xa5, 0x39, - 0xe5, 0x7f, 0x4e, 0xf1, 0x6c, 0xb9, 0xc7, 0xab, 0xdc, 0xe3, 0xf0, 0x82, - 0x62, 0x20, 0xbf, 0xa6, 0x32, 0x7c, 0xb2, 0x40, 0x1d, 0xd3, 0x2a, 0xb3, - 0x33, 0xbe, 0x9e, 0x19, 0xf3, 0x7c, 0xdc, 0xfc, 0x9a, 0x26, 0xd5, 0x33, - 0xf0, 0x6e, 0x9c, 0x11, 0xcf, 0xbe, 0x74, 0x4b, 0xe9, 0x3c, 0xed, 0x6e, - 0x12, 0x7d, 0xd1, 0x40, 0x69, 0x8e, 0xb5, 0x49, 0x62, 0x50, 0x86, 0x85, - 0x75, 0xff, 0x11, 0xfb, 0x38, 0xe4, 0x2d, 0x26, 0xef, 0x4f, 0xd1, 0xa7, - 0x6f, 0x82, 0x6f, 0xdc, 0xd6, 0x70, 0xbe, 0xdb, 0xab, 0x3e, 0x61, 0x3d, - 0xdd, 0x37, 0x74, 0x4a, 0x0b, 0xf9, 0xdc, 0xb1, 0x6f, 0x08, 0x7d, 0x30, - 0x5e, 0x67, 0x11, 0x0b, 0x30, 0xf6, 0x88, 0x6b, 0xec, 0x51, 0x2a, 0xb2, - 0xaf, 0xd5, 0xcb, 0x2b, 0xb5, 0x2a, 0xaf, 0x90, 0xdf, 0x32, 0xea, 0x7f, - 0x0f, 0xa9, 0xce, 0xca, 0x4f, 0xf5, 0x1a, 0xfc, 0x8a, 0x1d, 0x53, 0xde, - 0x93, 0x3a, 0xde, 0x8b, 0x79, 0x6b, 0x3f, 0xdc, 0x69, 0x7c, 0x2b, 0x5b, - 0xf5, 0x4d, 0x58, 0xc7, 0xd1, 0xae, 0x70, 0x7e, 0xf2, 0x06, 0x79, 0x84, - 0x3a, 0xcf, 0x1f, 0xe7, 0xd3, 0xc3, 0x6f, 0x73, 0x3c, 0xf9, 0xbf, 0x16, - 0x8b, 0xe0, 0xcb, 0xaa, 0xdf, 0xe7, 0xcb, 0x1d, 0xef, 0xd5, 0xda, 0x04, - 0xca, 0x5d, 0x6d, 0x7d, 0xd2, 0x96, 0xc8, 0xf4, 0x12, 0x5d, 0xd2, 0xfd, - 0xdc, 0xff, 0x4b, 0xcc, 0xed, 0x42, 0xde, 0x96, 0xa3, 0xcd, 0x51, 0xa5, - 0x4d, 0x06, 0xb4, 0x89, 0x28, 0x6d, 0x18, 0xef, 0x3d, 0xe3, 0xf1, 0x5b, - 0x2b, 0xce, 0x8b, 0xb9, 0x5a, 0xe8, 0xba, 0xbd, 0xd4, 0xf9, 0xcf, 0x77, - 0x6a, 0x7d, 0xd0, 0xa1, 0xee, 0x5b, 0x05, 0x7d, 0xc6, 0xf6, 0x66, 0xf5, - 0x47, 0x4c, 0xbc, 0x15, 0xd7, 0x3c, 0x68, 0x10, 0xfa, 0xb9, 0x34, 0x05, - 0x5f, 0x8d, 0x78, 0xb7, 0x3a, 0x5a, 0x7d, 0xc7, 0x3b, 0xaf, 0x92, 0xd2, - 0x86, 0x32, 0x40, 0xbd, 0xb9, 0x1a, 0xf3, 0xed, 0x8e, 0xf6, 0x81, 0xbf, - 0x7e, 0x81, 0xfe, 0x8d, 0x1a, 0x4f, 0x04, 0x21, 0xf3, 0x37, 0xa7, 0x3a, - 0xbc, 0x18, 0xce, 0x41, 0x1b, 0x71, 0xeb, 0x54, 0x84, 0x31, 0x05, 0xda, - 0x5b, 0xa4, 0x69, 0x1a, 0xf1, 0x2b, 0xf4, 0xf8, 0x82, 0xda, 0xa3, 0x3e, - 0xdc, 0xbf, 0x8b, 0x18, 0x3f, 0x5c, 0x1f, 0xc6, 0x73, 0xbd, 0x06, 0x8b, - 0x10, 0xdd, 0xa4, 0x67, 0x5a, 0x9a, 0x4a, 0xc4, 0x0e, 0x8a, 0xd7, 0x37, - 0xee, 0xaa, 0x3e, 0x58, 0xda, 0xd7, 0x43, 0xb2, 0xbb, 0x6a, 0x2f, 0x18, - 0x47, 0xc3, 0x87, 0x9f, 0x31, 0xf6, 0x20, 0x5f, 0xec, 0x53, 0x5c, 0x54, - 0x70, 0x68, 0x1e, 0x67, 0x49, 0x9f, 0x74, 0x11, 0x7e, 0xb8, 0x8b, 0x33, - 0xa4, 0xdf, 0x5d, 0x39, 0x76, 0xc2, 0x4d, 0xb1, 0x3e, 0x06, 0x7d, 0x70, - 0x4c, 0x46, 0x10, 0x17, 0x8c, 0x04, 0xdb, 0x98, 0x57, 0x86, 0x6f, 0x98, - 0xf3, 0x72, 0x8f, 0x7d, 0xcc, 0x99, 0xca, 0xd9, 0x39, 0xee, 0x9d, 0xb2, - 0x6d, 0x62, 0xef, 0xd2, 0x14, 0xf7, 0x6b, 0xf2, 0x10, 0x6c, 0x5b, 0xd3, - 0x2e, 0x7e, 0x79, 0x16, 0x03, 0xf8, 0x1d, 0x84, 0x3c, 0x70, 0x2c, 0x7e, - 0xe7, 0x16, 0xe5, 0xdd, 0xf3, 0xbe, 0x6d, 0x0f, 0xc8, 0x3b, 0x4e, 0xe5, - 0xd8, 0x71, 0x77, 0x0d, 0xcf, 0xc0, 0xcd, 0xb1, 0x66, 0xed, 0x38, 0x6e, - 0x5e, 0x2a, 0x95, 0x05, 0x77, 0x61, 0x8d, 0xa5, 0xb4, 0xa4, 0xfc, 0xff, - 0x03, 0x67, 0x78, 0xfd, 0x3e, 0x4b, 0x0c, 0xfd, 0x48, 0x9b, 0xcf, 0xd7, - 0xfe, 0x6a, 0x6d, 0x81, 0xaf, 0xff, 0xc8, 0x8f, 0xe4, 0xcb, 0x45, 0xd9, - 0xa9, 0xfa, 0x7f, 0xb9, 0xe7, 0x6a, 0x75, 0xbf, 0xef, 0xdf, 0x52, 0xbf, - 0x93, 0x17, 0x63, 0x1a, 0x1f, 0x6c, 0x9a, 0x6e, 0xd4, 0x09, 0x4f, 0x78, - 0x75, 0x85, 0xe5, 0x78, 0x6f, 0xbf, 0xa7, 0x17, 0x52, 0xea, 0x3b, 0xa7, - 0x6c, 0xea, 0x07, 0xee, 0xa7, 0x45, 0x26, 0x2e, 0xdc, 0x01, 0x4d, 0x7c, - 0x1d, 0xcc, 0xb8, 0xcf, 0xd7, 0x1d, 0x6d, 0x9e, 0x2f, 0x6c, 0x49, 0xcf, - 0x59, 0xfa, 0x4e, 0x0e, 0xf4, 0x68, 0xbb, 0x64, 0xc6, 0x83, 0x92, 0x3c, - 0x1b, 0x8b, 0x19, 0x5f, 0x97, 0xfc, 0x07, 0x79, 0xd3, 0x3e, 0xad, 0x45, - 0xa1, 0xff, 0x6e, 0xe1, 0xda, 0x86, 0x9f, 0x21, 0xcf, 0x7b, 0xfd, 0x7b, - 0x76, 0x03, 0x8f, 0xee, 0xf0, 0x78, 0x94, 0xf7, 0x2d, 0x53, 0xff, 0xc0, - 0xd8, 0x9e, 0xb3, 0xdc, 0xa3, 0x79, 0xae, 0xe7, 0xac, 0x89, 0xd7, 0xeb, - 0x9f, 0xeb, 0xab, 0x3e, 0x87, 0xfb, 0xf0, 0x7d, 0xcd, 0xdc, 0x3b, 0x07, - 0xe1, 0xd3, 0xf5, 0xd1, 0xe6, 0xd0, 0x7e, 0x6f, 0x74, 0x77, 0x0a, 0xf9, - 0x3d, 0xe1, 0xf1, 0x1c, 0xf5, 0x4d, 0xc4, 0xd3, 0x37, 0x4b, 0xf6, 0x65, - 0xc4, 0xe0, 0x4f, 0x98, 0x13, 0xa9, 0xb1, 0x2f, 0x4f, 0x98, 0x77, 0xab, - 0xb3, 0x2f, 0x77, 0x7b, 0xf3, 0xf8, 0xf7, 0x7c, 0xbd, 0xe2, 0xb7, 0x7d, - 0xbd, 0xd2, 0xe8, 0xd3, 0xfa, 0xb4, 0xaf, 0xed, 0xaf, 0x8f, 0xf9, 0xf2, - 0xcb, 0xe6, 0x5d, 0xb2, 0x88, 0xd9, 0xe8, 0x53, 0x26, 0x72, 0x06, 0x2f, - 0x6d, 0x9d, 0xb1, 0x88, 0xfb, 0x70, 0x7e, 0x22, 0xe9, 0xc8, 0x1d, 0x8d, - 0xad, 0x4f, 0x5e, 0x18, 0xd3, 0x3c, 0x4f, 0xc9, 0xf5, 0xf4, 0x4e, 0x74, - 0x17, 0xe4, 0xea, 0x4a, 0x64, 0x09, 0x53, 0x34, 0x73, 0x34, 0x0d, 0x3b, - 0x94, 0xd2, 0x7a, 0xd9, 0xf7, 0xb0, 0xdf, 0x41, 0xc5, 0x73, 0xad, 0x74, - 0x5e, 0x94, 0x47, 0xec, 0x8a, 0xd6, 0x6e, 0x9a, 0x87, 0x8a, 0x47, 0x9b, - 0x4f, 0xfb, 0x7c, 0x4f, 0x7e, 0x9a, 0x39, 0x3a, 0x31, 0x53, 0x19, 0x0e, - 0x6d, 0xeb, 0xb5, 0xf3, 0x42, 0xbc, 0xfe, 0xb0, 0x1c, 0x52, 0xdc, 0xf0, - 0xab, 0xb8, 0xbf, 0x97, 0xf1, 0x65, 0x22, 0xa4, 0x78, 0xe0, 0x44, 0x6c, - 0x12, 0xb2, 0x98, 0x75, 0x89, 0xef, 0x5f, 0xa5, 0x38, 0xff, 0x92, 0xd0, - 0xcf, 0x22, 0xa6, 0xe0, 0x05, 0x39, 0xe8, 0x6e, 0x74, 0x17, 0xc4, 0xf8, - 0xbf, 0x59, 0xad, 0x09, 0xad, 0x90, 0x49, 0x37, 0xd4, 0x9c, 0x2e, 0x1b, - 0x19, 0x18, 0x0d, 0xa6, 0x56, 0x9e, 0x70, 0xa2, 0xcd, 0x3b, 0xcb, 0x90, - 0xf1, 0x32, 0xf4, 0x7f, 0x39, 0x16, 0x18, 0x51, 0x6c, 0xda, 0x57, 0x24, - 0xdd, 0x41, 0x3f, 0x9f, 0xfa, 0xe4, 0x01, 0xb9, 0x69, 0x6f, 0x96, 0x9b, - 0x5b, 0x88, 0xc3, 0xec, 0x47, 0x9b, 0xba, 0x64, 0x10, 0x7d, 0x49, 0xf4, - 0x35, 0x2b, 0x3f, 0x6a, 0x7c, 0x06, 0x9d, 0x75, 0xd3, 0xa6, 0xae, 0x5a, - 0xcf, 0x5f, 0xbc, 0xeb, 0x22, 0x68, 0x42, 0x6c, 0xc7, 0x56, 0xb4, 0xa9, - 0xe3, 0xec, 0x86, 0xfe, 0x2e, 0xb4, 0xef, 0xc3, 0x1c, 0x4d, 0xfa, 0x7e, - 0x96, 0xb3, 0xcd, 0xd4, 0x39, 0xeb, 0xc6, 0xac, 0x6e, 0x68, 0xff, 0xb1, - 0xdd, 0xe0, 0x13, 0x3e, 0x25, 0xbd, 0x73, 0x29, 0xd9, 0xd5, 0x59, 0xdf, - 0xfe, 0x77, 0x43, 0xbb, 0x4d, 0x56, 0xb6, 0x93, 0x0c, 0x4f, 0x75, 0xd4, - 0xf7, 0xfb, 0xfc, 0xe4, 0xb7, 0x3b, 0xf1, 0xbe, 0x09, 0x18, 0xbc, 0xa4, - 0xc6, 0x52, 0x37, 0xa3, 0x5c, 0xeb, 0x83, 0x86, 0x67, 0x78, 0xcd, 0x67, - 0xf8, 0x2c, 0xf3, 0x7a, 0x9f, 0xb1, 0x1f, 0xcf, 0x30, 0x27, 0xc0, 0xbc, - 0x06, 0x79, 0x76, 0xb9, 0x38, 0x8b, 0x63, 0x3e, 0x9f, 0x6f, 0xc8, 0x54, - 0x79, 0xcf, 0xd7, 0x2b, 0xb1, 0x2a, 0x56, 0x6d, 0x67, 0xc1, 0xcf, 0x09, - 0x93, 0x76, 0x5a, 0x93, 0x8a, 0xdd, 0x00, 0x9d, 0x0f, 0x80, 0xce, 0x0f, - 0x05, 0x19, 0x17, 0xb6, 0x78, 0xb4, 0x76, 0x64, 0xa4, 0xfc, 0x5b, 0xc8, - 0x38, 0x79, 0x14, 0x3e, 0x45, 0xd9, 0xf2, 0xf0, 0x19, 0x03, 0xb0, 0x69, - 0xae, 0x04, 0x35, 0xef, 0x80, 0xf8, 0x7e, 0xf6, 0xba, 0x8c, 0x4c, 0x31, - 0x27, 0x40, 0x7e, 0x66, 0x5c, 0x9f, 0xc2, 0xbd, 0x5b, 0x18, 0xeb, 0x42, - 0x86, 0xc7, 0xc0, 0xaf, 0x21, 0x71, 0xa6, 0xb7, 0x4a, 0x6e, 0x7c, 0x4c, - 0x7d, 0x80, 0x1e, 0xd8, 0xa8, 0xe3, 0xee, 0xa8, 0x9c, 0xb8, 0xb2, 0x01, - 0xb2, 0xca, 0xb8, 0x5f, 0x73, 0x1a, 0x95, 0xb0, 0xfa, 0xe6, 0xf4, 0x39, - 0x98, 0x87, 0x33, 0x35, 0x66, 0x23, 0xb7, 0x93, 0x31, 0x69, 0x1b, 0x95, - 0x99, 0x0b, 0xb6, 0xe2, 0x5d, 0x52, 0x72, 0xa7, 0x42, 0xda, 0x65, 0xf7, - 0xc6, 0xa1, 0xab, 0xe8, 0xcb, 0x9f, 0x8c, 0x98, 0xb3, 0x7c, 0x74, 0x2d, - 0x63, 0xe2, 0xe4, 0x74, 0xed, 0x1c, 0x8a, 0x91, 0xc1, 0xbd, 0xd7, 0xda, - 0x8d, 0xcc, 0x30, 0x3e, 0xfe, 0xa0, 0x92, 0x8a, 0x72, 0x4d, 0x8e, 0x65, - 0xed, 0x96, 0x3c, 0xc2, 0xbd, 0x7d, 0xea, 0xf1, 0xf2, 0xcf, 0x30, 0x5f, - 0x5c, 0x7a, 0x5e, 0x1f, 0xd3, 0xb8, 0xfe, 0x78, 0x5d, 0x0c, 0x6b, 0xf2, - 0x05, 0x26, 0x8e, 0xbd, 0x2e, 0x93, 0xf3, 0xa4, 0x0f, 0x6d, 0x7c, 0x40, - 0x5e, 0x73, 0x7a, 0xed, 0x27, 0xb5, 0xd6, 0x98, 0x48, 0xb1, 0x3e, 0xd3, - 0xe2, 0x24, 0xed, 0x59, 0x09, 0x0d, 0x7e, 0x15, 0xd7, 0x8c, 0x6b, 0xf3, - 0x6e, 0xaf, 0xfb, 0xa4, 0xf8, 0x38, 0x90, 0x8d, 0xa9, 0x15, 0x81, 0xdb, - 0x95, 0xeb, 0x7b, 0x39, 0xc6, 0xe0, 0x40, 0x24, 0x40, 0x5a, 0xbd, 0xb7, - 0x9e, 0xf8, 0x99, 0xfa, 0xfc, 0xdf, 0x83, 0x4f, 0xef, 0x19, 0x48, 0x9c, - 0x62, 0x0c, 0x1b, 0x76, 0xbe, 0xb5, 0xd6, 0xbc, 0x6b, 0x2e, 0xb7, 0x5a, - 0xb4, 0x7e, 0x76, 0xe4, 0x23, 0x87, 0x78, 0x88, 0x44, 0x6c, 0x85, 0xc5, - 0x3c, 0x38, 0x75, 0x1c, 0x6b, 0x2a, 0xcc, 0xb9, 0x11, 0xc7, 0xdf, 0x2c, - 0x97, 0xfb, 0x2c, 0x79, 0x30, 0x94, 0x8a, 0x5b, 0xb2, 0x29, 0x7e, 0x56, - 0xb0, 0x26, 0xeb, 0x2b, 0xf3, 0x89, 0x1c, 0xc7, 0x87, 0xa6, 0x39, 0x5f, - 0x5c, 0xe3, 0x95, 0xe4, 0xa6, 0x4a, 0xe5, 0x19, 0x57, 0x02, 0xc9, 0x7b, - 0x3f, 0xac, 0xb0, 0x16, 0x6e, 0xbd, 0xfe, 0x45, 0x38, 0x05, 0xea, 0x8a, - 0x55, 0x93, 0x06, 0x73, 0x78, 0xe2, 0x48, 0xcf, 0x3c, 0xdb, 0xdf, 0x7d, - 0xc4, 0xb4, 0x4f, 0xa1, 0xdd, 0xe4, 0x61, 0x9d, 0xa6, 0x8e, 0xf4, 0x14, - 0x9f, 0x5a, 0x6b, 0xe2, 0xef, 0x45, 0xc5, 0x7f, 0xbd, 0x5d, 0x17, 0xd3, - 0xa4, 0x02, 0xe3, 0x85, 0xb1, 0xc0, 0x58, 0xc1, 0xea, 0x6b, 0x06, 0xad, - 0xe6, 0x5c, 0xe6, 0x6a, 0xfc, 0x9c, 0x15, 0xf3, 0xfd, 0x22, 0xdf, 0x57, - 0x8c, 0x14, 0x6b, 0x8a, 0x96, 0xfa, 0x42, 0x07, 0xe6, 0x98, 0xe3, 0x8f, - 0xa8, 0x3e, 0x38, 0x38, 0xdf, 0x26, 0x79, 0x7b, 0x8d, 0xe4, 0x55, 0xc6, - 0xa3, 0xaa, 0x03, 0x2c, 0xe7, 0x5e, 0xf4, 0x71, 0xdf, 0x4f, 0x28, 0x2e, - 0xe2, 0xcd, 0x42, 0x17, 0xda, 0xcc, 0x35, 0x6f, 0x6f, 0xe8, 0xaf, 0xad, - 0xcb, 0x26, 0x6c, 0xcb, 0x6a, 0xac, 0xc9, 0xb2, 0xaf, 0xb1, 0x16, 0x7b, - 0x52, 0xae, 0x93, 0x6f, 0xca, 0x7e, 0xce, 0xdd, 0xf5, 0x72, 0xee, 0xdf, - 0xee, 0x32, 0x18, 0x61, 0xc9, 0x84, 0x86, 0x9a, 0xfb, 0x8e, 0x4f, 0x05, - 0x6f, 0x2d, 0xe5, 0x4f, 0xd1, 0x9e, 0xaf, 0xd6, 0xca, 0x71, 0xef, 0x39, - 0x62, 0xc5, 0xe1, 0x57, 0xe4, 0xbc, 0xef, 0x0e, 0x78, 0xbf, 0xfa, 0xfc, - 0xff, 0xd8, 0x53, 0x8b, 0xd6, 0xd9, 0xad, 0xba, 0x3a, 0xfb, 0xe3, 0x78, - 0x96, 0x35, 0xf6, 0x5c, 0xa5, 0x09, 0xbc, 0xdb, 0x44, 0x9c, 0x48, 0x75, - 0x3c, 0x75, 0xbc, 0xea, 0x72, 0x9d, 0x6b, 0xa7, 0x37, 0x57, 0x10, 0x7a, - 0x7e, 0x62, 0xca, 0x1f, 0x73, 0x4c, 0x56, 0xf4, 0x27, 0x62, 0x41, 0x8b, - 0x63, 0x8c, 0xbe, 0x4f, 0xbb, 0xc7, 0xa0, 0xc7, 0xa9, 0xf3, 0xf9, 0xde, - 0x0e, 0x7c, 0x3d, 0xea, 0x02, 0xea, 0x73, 0xb5, 0x01, 0xf1, 0x3c, 0x74, - 0xfd, 0x48, 0x59, 0x73, 0xf9, 0xb1, 0x87, 0x83, 0x89, 0x99, 0xac, 0xea, - 0x06, 0xf8, 0x7b, 0xe5, 0x6b, 0xcc, 0x07, 0x9d, 0x92, 0x40, 0x6d, 0x9d, - 0x86, 0xb1, 0x19, 0x6b, 0x1a, 0xad, 0xd0, 0x0d, 0x22, 0x57, 0xc1, 0x1b, - 0x6f, 0xcc, 0x91, 0x5f, 0x83, 0x1d, 0x26, 0xbe, 0x5a, 0xd8, 0x6e, 0x49, - 0x87, 0xd6, 0x3e, 0xf3, 0x4e, 0x84, 0xfe, 0xc9, 0x70, 0xb2, 0x1f, 0x7e, - 0xb6, 0x62, 0x0f, 0x98, 0xaf, 0x9c, 0x40, 0x3c, 0x56, 0x9b, 0x63, 0x81, - 0x7c, 0x8d, 0xb3, 0x3f, 0x0b, 0xbf, 0x72, 0xa9, 0xee, 0x91, 0x2f, 0x9e, - 0xd0, 0xdc, 0x66, 0x69, 0xae, 0x55, 0x75, 0x6c, 0xa9, 0xf8, 0x30, 0xce, - 0x45, 0x36, 0x5b, 0x43, 0x79, 0xaf, 0x3f, 0x2c, 0xc5, 0x22, 0xdb, 0xd2, - 0xdd, 0xa4, 0xe7, 0xee, 0xd7, 0x76, 0x6c, 0x99, 0x85, 0xaf, 0x58, 0x9c, - 0x77, 0xf0, 0xbf, 0x05, 0xff, 0x7d, 0xf8, 0xdf, 0x25, 0xe9, 0x69, 0xfa, - 0xaf, 0xac, 0xe5, 0xb4, 0x36, 0xac, 0x1f, 0xf6, 0x70, 0xe0, 0xf4, 0x6b, - 0x4d, 0x9c, 0x93, 0x2f, 0x36, 0xca, 0x09, 0xf3, 0xa4, 0xbe, 0x8e, 0x60, - 0xbe, 0xd4, 0xaf, 0xf5, 0xd5, 0xd6, 0xb0, 0x2c, 0xaf, 0xee, 0x45, 0x9e, - 0x6e, 0x91, 0x83, 0x45, 0xbf, 0x76, 0x15, 0x93, 0x43, 0xd5, 0xda, 0x95, - 0x64, 0x82, 0x43, 0xb7, 0x1f, 0xcb, 0x4e, 0x29, 0x9e, 0xc0, 0xb2, 0x86, - 0xae, 0x3f, 0x36, 0x39, 0xff, 0xce, 0x63, 0x4b, 0x98, 0x70, 0xdc, 0x9b, - 0x5f, 0x0e, 0x33, 0x44, 0x2c, 0x1d, 0xbf, 0x93, 0x53, 0xdf, 0x0d, 0xfb, - 0xf6, 0x63, 0x1e, 0xe2, 0xec, 0xe2, 0xf6, 0x12, 0x7e, 0xd9, 0x8f, 0x47, - 0x89, 0x23, 0xe5, 0x73, 0xb5, 0xd8, 0x8f, 0x10, 0xce, 0x5f, 0x02, 0x96, - 0x93, 0xc3, 0x3e, 0x2e, 0x76, 0x19, 0x3f, 0x90, 0x38, 0xd3, 0x44, 0x0d, - 0xf6, 0xc8, 0xc7, 0x9a, 0x5e, 0xc4, 0x5c, 0x19, 0xf9, 0x7d, 0xf9, 0x71, - 0xf9, 0x75, 0x79, 0x0c, 0xf2, 0x3d, 0x89, 0x39, 0xf7, 0xcb, 0xaf, 0xca, - 0x7b, 0xe5, 0x5a, 0x79, 0x5c, 0xde, 0x2a, 0xef, 0x42, 0x4c, 0x35, 0x4a, - 0xac, 0xa7, 0x87, 0x95, 0x1e, 0x96, 0x89, 0x73, 0x8a, 0x01, 0xbc, 0x45, - 0xbf, 0xe7, 0x88, 0xfa, 0xd9, 0x01, 0xf2, 0xf4, 0x6f, 0x18, 0xcf, 0x13, - 0x9b, 0x59, 0x2c, 0xfb, 0x18, 0x8e, 0x43, 0xdd, 0x58, 0xdb, 0xe6, 0x37, - 0x29, 0x23, 0xe7, 0x22, 0x81, 0xd1, 0x73, 0xa1, 0xc0, 0x43, 0xfa, 0x7d, - 0x0b, 0xeb, 0x9d, 0x15, 0x39, 0xe1, 0x3a, 0xe4, 0xcd, 0xc1, 0x11, 0xc8, - 0xc2, 0x28, 0x54, 0xfd, 0x23, 0xce, 0x1a, 0x01, 0x49, 0x53, 0x1f, 0xc3, - 0xcf, 0x4c, 0x9e, 0x76, 0x25, 0x5b, 0x98, 0x0d, 0x18, 0x3c, 0x9a, 0x8d, - 0x76, 0x1f, 0xda, 0xbf, 0xf4, 0xda, 0x3b, 0x24, 0x7b, 0x41, 0x52, 0xef, - 0xab, 0x3f, 0xfc, 0x73, 0xaf, 0x6f, 0x10, 0x7d, 0xe0, 0xcc, 0x57, 0xd8, - 0xf7, 0x8a, 0xd7, 0xc7, 0x33, 0x61, 0xad, 0x3e, 0xae, 0x7c, 0x95, 0xb5, - 0xc7, 0x85, 0xdf, 0x2f, 0x18, 0x4c, 0xe8, 0xfb, 0x5d, 0x46, 0xb7, 0x11, - 0x13, 0xf8, 0xaf, 0x2e, 0xc6, 0x60, 0x45, 0xc8, 0xd7, 0x7a, 0xe8, 0xc4, - 0xbf, 0x6f, 0x5e, 0x6a, 0x5b, 0x43, 0x9f, 0xd4, 0x60, 0xb4, 0x3f, 0x91, - 0x9e, 0xf9, 0xdb, 0x1e, 0x9e, 0xf7, 0x30, 0xde, 0x0d, 0x67, 0x55, 0x20, - 0x6e, 0x3c, 0x0e, 0xd9, 0x6e, 0x95, 0x35, 0x67, 0x48, 0xaf, 0x5e, 0xe8, - 0xea, 0x14, 0xe4, 0xd6, 0x95, 0xb9, 0x72, 0x28, 0x30, 0x52, 0x48, 0x89, - 0xc1, 0x53, 0x5b, 0x92, 0x89, 0xa6, 0xe4, 0xe4, 0x40, 0x62, 0x0b, 0xf3, - 0x90, 0xd9, 0x7e, 0x57, 0x2e, 0x95, 0x69, 0x8f, 0x73, 0x72, 0x79, 0x20, - 0xe1, 0x16, 0x85, 0xb8, 0x18, 0x57, 0x2e, 0x43, 0x36, 0xff, 0x70, 0x6e, - 0x97, 0x1c, 0x2a, 0xa8, 0x1f, 0xdc, 0x1b, 0x96, 0x97, 0xe5, 0xd2, 0xc0, - 0xcb, 0xb7, 0x2e, 0xb9, 0x93, 0x38, 0x53, 0xf2, 0xe1, 0x81, 0x6e, 0xb3, - 0x6f, 0xc5, 0x21, 0x09, 0xf3, 0x21, 0x5a, 0x53, 0x73, 0x56, 0x48, 0x7a, - 0x5f, 0xc4, 0x8b, 0xcb, 0xe1, 0x73, 0x07, 0xee, 0x33, 0xf5, 0x94, 0x80, - 0xbf, 0xcf, 0x30, 0xfc, 0x18, 0x3e, 0xe7, 0xd3, 0xc6, 0x9f, 0xa7, 0x2b, - 0x90, 0xbe, 0xd0, 0x26, 0xa1, 0x57, 0xbe, 0x0c, 0xba, 0x86, 0xe4, 0x40, - 0x7f, 0xa5, 0xf2, 0x0d, 0x37, 0x14, 0x9f, 0x44, 0x8c, 0x82, 0xfd, 0xcb, - 0xea, 0xd3, 0xed, 0xa0, 0x49, 0xb3, 0x44, 0x4f, 0xfb, 0xeb, 0xad, 0xf0, - 0xb0, 0x0c, 0xe7, 0x57, 0x1b, 0x5b, 0xe6, 0x63, 0x1b, 0xfc, 0xf9, 0x0c, - 0xa6, 0xac, 0xc7, 0xea, 0x0f, 0x78, 0xdf, 0x49, 0x78, 0xed, 0x7b, 0x03, - 0x0f, 0x86, 0x3a, 0x24, 0xe4, 0xfc, 0x70, 0x1d, 0xb1, 0x91, 0x0b, 0x05, - 0xbf, 0x1f, 0x7e, 0x62, 0xc8, 0xf7, 0x87, 0x65, 0xdb, 0xd2, 0x59, 0xcb, - 0xb6, 0x9e, 0xf9, 0x6f, 0x7a, 0x73, 0xa6, 0xbc, 0xb1, 0x88, 0x39, 0x62, - 0xab, 0xd4, 0x3e, 0x99, 0xb1, 0x9f, 0xc9, 0xb3, 0xfd, 0x89, 0x57, 0x15, - 0x27, 0x5b, 0x7d, 0x86, 0xf7, 0x11, 0x43, 0x96, 0xf5, 0x99, 0xd8, 0x6e, - 0xd0, 0x37, 0x13, 0xbb, 0xc7, 0x9e, 0xb5, 0x82, 0x01, 0xe3, 0x8f, 0x34, - 0xc9, 0x0f, 0xa2, 0xb0, 0xdb, 0x88, 0xf1, 0xb2, 0xcc, 0x7f, 0xb9, 0x77, - 0x3c, 0x3f, 0x85, 0x7d, 0x89, 0x53, 0x49, 0x6b, 0x02, 0xfb, 0xe3, 0x19, - 0x10, 0x03, 0x6a, 0x81, 0x4e, 0x5d, 0x78, 0x3f, 0xc4, 0x4f, 0xfd, 0xfe, - 0xfb, 0xaf, 0x86, 0x0e, 0xe3, 0xfe, 0x0d, 0x2e, 0x4c, 0x2c, 0xe6, 0x42, - 0x86, 0x3d, 0x0c, 0x6c, 0xad, 0xdc, 0xfa, 0xd8, 0x58, 0x1f, 0x4f, 0x47, - 0x8c, 0x52, 0x0c, 0x7e, 0x20, 0x65, 0x82, 0xbc, 0xd9, 0x89, 0xfe, 0x95, - 0xb7, 0x53, 0xfa, 0xea, 0x7e, 0xdf, 0x87, 0x55, 0x6c, 0xf7, 0x64, 0x61, - 0xaf, 0xc1, 0xe6, 0x59, 0x8b, 0x92, 0xea, 0x4e, 0xda, 0x27, 0xb0, 0xdf, - 0x74, 0x28, 0x51, 0xcc, 0x49, 0x4c, 0x66, 0xa1, 0x2f, 0xde, 0x80, 0xec, - 0x5f, 0x2b, 0xc7, 0x03, 0x69, 0xec, 0xe9, 0x60, 0x61, 0x48, 0x26, 0x2f, - 0xe8, 0x37, 0x5f, 0xd0, 0xfb, 0x43, 0x52, 0x2a, 0x24, 0xb6, 0xcc, 0x82, - 0xff, 0x66, 0x0b, 0xc4, 0x17, 0xf5, 0xc6, 0x47, 0x31, 0xe3, 0x42, 0x61, - 0x23, 0xec, 0x83, 0xa4, 0x2e, 0xc1, 0xff, 0xb9, 0x54, 0xde, 0x02, 0x3e, - 0xc3, 0xfd, 0xb2, 0x83, 0x5f, 0xe8, 0xcc, 0xf2, 0x00, 0xe4, 0x9c, 0x7b, - 0xb1, 0x65, 0x6e, 0x33, 0xce, 0x8e, 0x38, 0x22, 0xc5, 0x8f, 0xff, 0x07, - 0xe7, 0xeb, 0xbf, 0xf7, 0x76, 0xb5, 0xd3, 0xb3, 0xba, 0x2f, 0xd8, 0x65, - 0xc4, 0x00, 0xd9, 0x7e, 0x63, 0xb7, 0xd3, 0x91, 0x76, 0x49, 0xdf, 0x43, - 0x3b, 0xde, 0xa1, 0x31, 0xa2, 0xf2, 0x62, 0x84, 0xf7, 0xdf, 0x59, 0x67, - 0xe8, 0x17, 0x6e, 0x68, 0xbf, 0x8d, 0xdf, 0x36, 0xe9, 0x74, 0xf8, 0x6b, - 0xe3, 0xf7, 0xc6, 0x3a, 0xd6, 0x77, 0x3b, 0x9d, 0x24, 0xd6, 0xfa, 0x9d, - 0x97, 0x2f, 0xc0, 0xf5, 0x2c, 0x9f, 0x59, 0xeb, 0xad, 0xcb, 0x79, 0xdb, - 0x30, 0x4f, 0xab, 0xb7, 0x56, 0x9b, 0xe6, 0x27, 0xcd, 0x5a, 0x88, 0x71, - 0x0b, 0xef, 0xad, 0xd3, 0xef, 0x8c, 0x61, 0x2f, 0xea, 0xdb, 0x7f, 0x5d, - 0x47, 0xdc, 0x5c, 0xa7, 0xd3, 0xa6, 0x18, 0xcf, 0x9b, 0x1d, 0x1d, 0xb8, - 0xe6, 0x9a, 0x1c, 0x63, 0xf2, 0xe1, 0xa5, 0x32, 0xe7, 0x67, 0x3b, 0x25, - 0x47, 0x35, 0x9f, 0x61, 0xb0, 0x7c, 0xa5, 0xc2, 0xfd, 0x32, 0x79, 0x4e, - 0xf1, 0x75, 0x33, 0x79, 0x8b, 0xdf, 0xbd, 0xf0, 0x3b, 0x39, 0xfa, 0x12, - 0x63, 0x32, 0x81, 0xf3, 0xbb, 0x0c, 0x9f, 0x6a, 0xc1, 0x7c, 0x13, 0x8b, - 0xbf, 0xfd, 0x38, 0x97, 0x10, 0x64, 0x8c, 0x32, 0x4a, 0x99, 0xc2, 0xf9, - 0x8d, 0xdb, 0xf2, 0xee, 0x00, 0xe5, 0x79, 0x40, 0xae, 0x54, 0xe5, 0x39, - 0x07, 0x79, 0xa6, 0x2c, 0xe7, 0x20, 0xd3, 0x86, 0xaf, 0xf7, 0xf1, 0x1b, - 0x6b, 0x84, 0xeb, 0x25, 0xf5, 0x21, 0x2e, 0x82, 0xaf, 0x6d, 0x13, 0x97, - 0x2b, 0x2e, 0xfe, 0x30, 0xf4, 0x5a, 0x93, 0xf7, 0x1d, 0x00, 0xae, 0xaf, - 0xbc, 0x28, 0xe9, 0x0b, 0x2d, 0xd8, 0x77, 0xbc, 0x9b, 0x67, 0x96, 0xbd, - 0xc2, 0x7f, 0x9f, 0x17, 0x89, 0x37, 0xa5, 0x3f, 0xcb, 0x6b, 0xc6, 0x79, - 0xeb, 0x31, 0x66, 0x10, 0x74, 0x6e, 0xc1, 0xfc, 0xdc, 0xe3, 0x72, 0xe3, - 0x78, 0x3f, 0x54, 0x83, 0x4f, 0xf5, 0xe9, 0xbd, 0x4a, 0xd7, 0xcc, 0xea, - 0x37, 0x5a, 0x46, 0x06, 0x27, 0x0a, 0xe4, 0xfb, 0x18, 0xf8, 0x96, 0x3e, - 0x31, 0xf9, 0x25, 0xa5, 0xe7, 0x50, 0x2a, 0x90, 0x7f, 0x43, 0x9a, 0xc3, - 0xc8, 0xc2, 0xb6, 0xec, 0xd1, 0xf1, 0xb1, 0x25, 0xf9, 0xee, 0x0e, 0x68, - 0xdc, 0x9d, 0x2d, 0xac, 0x94, 0x1e, 0xd5, 0x41, 0xdd, 0x1e, 0x6f, 0xc3, - 0x5e, 0x28, 0x96, 0x7b, 0xbf, 0x1c, 0x29, 0x0f, 0x82, 0x0e, 0x31, 0x79, - 0x06, 0x7e, 0xf3, 0x73, 0xe5, 0xbb, 0x64, 0x31, 0x82, 0x7d, 0x55, 0x65, - 0x6c, 0x58, 0x9e, 0x9f, 0x8d, 0x7b, 0xd7, 0x09, 0x77, 0xd1, 0xda, 0x8e, - 0x3d, 0x50, 0x9e, 0x28, 0x57, 0x1c, 0x17, 0x44, 0x2c, 0xc2, 0x79, 0x8f, - 0x18, 0xdd, 0x86, 0x79, 0x8b, 0x11, 0xca, 0x2f, 0xf7, 0x16, 0xf2, 0x64, - 0x96, 0x71, 0x15, 0xdf, 0xd9, 0xd8, 0xa4, 0x4c, 0xdd, 0x59, 0x24, 0x14, - 0x07, 0xba, 0x74, 0x06, 0xfe, 0x3c, 0xbe, 0x5c, 0xfa, 0xdf, 0x51, 0x50, - 0x8f, 0xc2, 0x56, 0x16, 0x60, 0x2b, 0x0b, 0xb0, 0x91, 0x90, 0x85, 0x6b, - 0x05, 0xd8, 0xc8, 0x02, 0x6c, 0x24, 0xf4, 0xd9, 0x9b, 0x88, 0xed, 0xde, - 0x00, 0x0f, 0x19, 0x5f, 0xfb, 0x30, 0x7d, 0x6d, 0xfc, 0xfd, 0x17, 0xea, - 0x52, 0x61, 0x78, 0xd0, 0x71, 0x00, 0x00, 0x00 }; + 0xec, 0x5b, 0x5d, 0x6c, 0x1c, 0xd7, 0x75, 0x3e, 0x33, 0x3b, 0x24, 0x57, + 0x14, 0x45, 0x8e, 0xa8, 0x15, 0xb5, 0xb2, 0x99, 0x64, 0x97, 0x1c, 0x89, + 0x1b, 0x93, 0x50, 0x86, 0xec, 0x5a, 0x66, 0x92, 0x45, 0xbc, 0x59, 0x52, + 0x16, 0x53, 0x08, 0xf0, 0xda, 0x56, 0x5c, 0xa3, 0x31, 0x90, 0xc5, 0x92, + 0x76, 0xd2, 0x37, 0xc9, 0xa9, 0x5d, 0x21, 0xb1, 0xab, 0xf5, 0x92, 0x91, + 0x15, 0x75, 0xc5, 0x61, 0x24, 0x26, 0x72, 0x1b, 0xb7, 0xa0, 0xf9, 0x23, + 0xaa, 0xc1, 0x4a, 0xe3, 0x9f, 0xd8, 0xf5, 0x43, 0x64, 0x31, 0xb2, 0xad, + 0xfa, 0xa5, 0x80, 0xd3, 0x1f, 0xc0, 0x28, 0x8c, 0x56, 0x90, 0x6b, 0xd9, + 0x68, 0x81, 0x42, 0x6d, 0x51, 0xd4, 0x6d, 0x64, 0x4d, 0xbf, 0xef, 0xce, + 0x0c, 0xb9, 0x22, 0x94, 0xc6, 0x2f, 0x7d, 0x9b, 0x0b, 0x2c, 0xee, 0xdc, + 0x3b, 0xe7, 0x9e, 0x7b, 0xce, 0xb9, 0xe7, 0xf7, 0x0e, 0xf9, 0x44, 0x9b, + 0xb4, 0x4a, 0xd0, 0x36, 0xe1, 0x97, 0x3d, 0x70, 0xe8, 0xb1, 0xc1, 0x5d, + 0xbb, 0x77, 0xe1, 0x71, 0x77, 0xcc, 0x6c, 0x36, 0x38, 0xaf, 0x49, 0xd4, + 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, + 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, + 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, + 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, + 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, + 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xfe, 0x3f, 0x5a, 0x4c, 0xc4, 0x64, + 0xbf, 0x29, 0xf8, 0x49, 0x5c, 0xcf, 0xa5, 0x0e, 0x16, 0x2c, 0x89, 0xc7, + 0x72, 0x6f, 0x3f, 0x3e, 0x6e, 0x89, 0xe4, 0xeb, 0xfd, 0xa9, 0x11, 0xf9, + 0xc4, 0xab, 0x24, 0x0c, 0xe1, 0xfc, 0x67, 0x72, 0xd7, 0x0f, 0x9f, 0xbf, + 0x2b, 0x7d, 0x6d, 0x2e, 0x26, 0x71, 0x33, 0xf7, 0xee, 0xa0, 0xb9, 0x53, + 0xe2, 0xdd, 0x58, 0xf3, 0x5c, 0xdf, 0xc4, 0x66, 0x69, 0x0f, 0x71, 0x79, + 0xde, 0x92, 0xed, 0xc9, 0x25, 0xbb, 0xa2, 0x8d, 0xf4, 0xbd, 0xa6, 0x15, + 0x9c, 0x1b, 0x5e, 0xde, 0xd0, 0x45, 0x07, 0xbe, 0x89, 0x7a, 0x5c, 0x1e, + 0x59, 0x6c, 0x95, 0x47, 0xe7, 0x36, 0x4a, 0x79, 0x4e, 0x4c, 0x3d, 0x97, + 0x94, 0x6f, 0x61, 0xee, 0x72, 0x0c, 0x70, 0xae, 0x94, 0x62, 0xb9, 0x8f, + 0xef, 0x2d, 0xd7, 0x08, 0x2f, 0xba, 0x9e, 0x5b, 0xb9, 0x77, 0xa2, 0xfe, + 0xe6, 0xbd, 0xe5, 0x3a, 0xe1, 0x08, 0x83, 0x77, 0xf5, 0x8f, 0xbc, 0xf3, + 0x7d, 0x09, 0xb9, 0xe0, 0x9a, 0xf2, 0x82, 0xfb, 0x32, 0xf6, 0x4c, 0x57, + 0x2a, 0xd2, 0x24, 0xe5, 0x93, 0x37, 0xbc, 0x98, 0x95, 0x4e, 0x61, 0x13, + 0x73, 0x44, 0xf0, 0xde, 0xc1, 0x7b, 0x07, 0xf3, 0x0b, 0x3f, 0xdf, 0x2c, + 0xad, 0x49, 0x39, 0xdf, 0xc7, 0x75, 0x5c, 0xc3, 0xb5, 0x8b, 0xed, 0xfe, + 0x3a, 0xc1, 0xba, 0xa2, 0xc4, 0x2c, 0x4f, 0x0a, 0xb6, 0x21, 0x23, 0x09, + 0xd1, 0x74, 0xab, 0x02, 0x3a, 0x7e, 0xd1, 0x26, 0xad, 0xc4, 0x55, 0xd1, + 0xf2, 0x2e, 0xfb, 0x10, 0xdf, 0x53, 0x1d, 0x3e, 0xae, 0x67, 0x81, 0xab, + 0x24, 0xaf, 0xbb, 0x0f, 0xcb, 0x5f, 0xb8, 0x63, 0xf2, 0x92, 0x3b, 0x01, + 0x9c, 0x0f, 0xc9, 0xab, 0xee, 0x7e, 0x79, 0xc5, 0x2d, 0xca, 0xcf, 0xdc, + 0x7d, 0xf2, 0xb2, 0x3b, 0x2a, 0x2f, 0xba, 0x79, 0xec, 0x97, 0xd1, 0x8a, + 0xce, 0xdd, 0x32, 0x7e, 0x92, 0x34, 0xa6, 0xaf, 0x41, 0x36, 0xf2, 0x98, + 0xdd, 0x67, 0xea, 0xa2, 0x61, 0xcf, 0xf4, 0x6b, 0x22, 0x8f, 0x4a, 0x3e, + 0x31, 0x2c, 0x73, 0x6e, 0x97, 0x56, 0x38, 0xd9, 0xa9, 0x8d, 0x9c, 0x24, + 0x2d, 0x9e, 0x8c, 0xdb, 0xe9, 0x54, 0x21, 0x96, 0x36, 0x47, 0x62, 0x92, + 0xdf, 0x03, 0xb9, 0x55, 0x9d, 0xa4, 0xe4, 0x4d, 0xc9, 0x1f, 0xb5, 0x0c, + 0xc8, 0x53, 0x93, 0x58, 0x8e, 0x7c, 0x6e, 0xe1, 0x1c, 0x5a, 0x9b, 0x2c, + 0xd4, 0x6c, 0x29, 0x3b, 0xf3, 0x5a, 0x39, 0xa1, 0x51, 0x04, 0x18, 0x0f, + 0x60, 0xfc, 0x67, 0xc1, 0xf8, 0x4b, 0x52, 0x3e, 0x25, 0xf9, 0xc9, 0x59, + 0xcf, 0x2b, 0xd8, 0x7f, 0x1c, 0xcc, 0x0d, 0x63, 0x4e, 0x97, 0xd8, 0x8f, + 0x38, 0x37, 0x1b, 0xcc, 0x51, 0x1e, 0x9e, 0x8c, 0xd8, 0x14, 0x23, 0xe8, + 0x35, 0x8b, 0xe8, 0x9b, 0xd1, 0x73, 0x8f, 0x8d, 0x9b, 0xfc, 0xff, 0x03, + 0xe2, 0xf9, 0x26, 0xf0, 0x6c, 0x83, 0x66, 0x89, 0x7f, 0x36, 0x77, 0xf4, + 0xe0, 0x3f, 0xf4, 0xad, 0x8d, 0xf5, 0xdc, 0x7b, 0x52, 0xa8, 0x69, 0x4a, + 0x57, 0x34, 0x3c, 0xf7, 0xd4, 0x9f, 0xea, 0xf4, 0xf5, 0xc2, 0x69, 0x97, + 0x56, 0xc8, 0xc9, 0x21, 0xfd, 0x29, 0xd0, 0xbf, 0x49, 0xb6, 0xfc, 0x90, + 0x3c, 0xf4, 0xa7, 0x74, 0xc9, 0xa7, 0x0d, 0xb1, 0x65, 0xd1, 0x35, 0xb4, + 0x11, 0x27, 0x2f, 0x7a, 0xce, 0x4a, 0x96, 0x45, 0x97, 0x52, 0x22, 0x2f, + 0xcf, 0x64, 0xd3, 0xc3, 0x15, 0x49, 0x49, 0x79, 0xc8, 0x96, 0x65, 0x17, + 0x90, 0x89, 0x8a, 0x5c, 0xcd, 0xa6, 0xed, 0xcb, 0xb2, 0x51, 0x56, 0x4c, + 0x5b, 0x4e, 0xbb, 0x71, 0x79, 0xeb, 0xe4, 0x3e, 0xf9, 0x96, 0xc3, 0x73, + 0x92, 0xfe, 0x26, 0x79, 0x5a, 0x96, 0xb2, 0x4f, 0x5f, 0x5b, 0xb2, 0x8f, + 0xb7, 0x49, 0x3b, 0x75, 0xb0, 0xd6, 0xee, 0xd3, 0xfd, 0x15, 0xf0, 0x96, + 0x87, 0x6c, 0xdb, 0x21, 0x33, 0x43, 0xf1, 0x55, 0x78, 0xb0, 0x13, 0x3d, + 0xd7, 0xfd, 0xfd, 0x16, 0xe8, 0x83, 0x2d, 0x5a, 0x48, 0x63, 0x93, 0x14, + 0xba, 0xb8, 0xe6, 0x25, 0xe0, 0xc0, 0xfb, 0x55, 0xda, 0x6f, 0xd3, 0x0a, + 0xa7, 0xda, 0xc5, 0xf8, 0xd1, 0x9d, 0x38, 0x4f, 0x43, 0x1e, 0x19, 0xf2, + 0xbc, 0xaf, 0xdb, 0x46, 0x6a, 0x42, 0x72, 0xa4, 0x5d, 0x36, 0x1f, 0xdf, + 0x2a, 0x73, 0x66, 0x5c, 0x12, 0xc7, 0xc3, 0xbd, 0x5a, 0x82, 0xf3, 0xf9, + 0x32, 0xf1, 0xa7, 0x52, 0xfa, 0xa6, 0x60, 0x1c, 0xd2, 0x34, 0x8a, 0x33, + 0xea, 0x35, 0x7b, 0xf4, 0x21, 0x2d, 0xaf, 0xfe, 0x8f, 0x6a, 0x2c, 0x18, + 0xef, 0xd2, 0xbe, 0x6a, 0x74, 0x89, 0x61, 0xcd, 0x43, 0xae, 0x86, 0x5c, + 0x74, 0xc2, 0xf9, 0xb8, 0xf8, 0x70, 0x94, 0xb3, 0x0c, 0xae, 0xc9, 0x59, + 0x06, 0x7b, 0xea, 0x4f, 0x07, 0x38, 0xf3, 0x01, 0xec, 0x06, 0xc9, 0x27, + 0xdb, 0x78, 0xa6, 0x01, 0xec, 0x75, 0xf9, 0xce, 0x50, 0xfa, 0x0c, 0xff, + 0x57, 0x6b, 0x6d, 0x0d, 0xdf, 0xdb, 0x32, 0xef, 0xaa, 0x35, 0xc9, 0xfb, + 0x70, 0xb6, 0xa5, 0xe4, 0x1d, 0xe6, 0x82, 0x1e, 0xd3, 0xf2, 0x09, 0xe2, + 0x6a, 0x96, 0xc7, 0x13, 0xbd, 0x18, 0x6b, 0x52, 0xfe, 0x12, 0xf5, 0xf5, + 0x13, 0xf1, 0xe7, 0x39, 0x97, 0x3e, 0xda, 0xab, 0x1f, 0x03, 0x7d, 0x94, + 0x41, 0x3a, 0x29, 0x10, 0x7e, 0x79, 0xe8, 0x36, 0xf0, 0x67, 0xa2, 0x0f, + 0xf9, 0xdf, 0x2c, 0xf9, 0x22, 0xe9, 0x57, 0x76, 0x0a, 0x39, 0x27, 0xb1, + 0xdf, 0xdd, 0xb0, 0xc9, 0xf5, 0xf6, 0x0a, 0x1b, 0x6d, 0xa7, 0xad, 0x7e, + 0x11, 0x3c, 0xa7, 0x33, 0x22, 0x16, 0xe4, 0x95, 0x94, 0x66, 0x6b, 0x1a, + 0x3c, 0x51, 0x2f, 0xb7, 0x61, 0x7e, 0xc3, 0xc7, 0x79, 0xc5, 0x7a, 0x38, + 0xf7, 0x41, 0x20, 0xcb, 0x7d, 0x32, 0xe1, 0xec, 0x57, 0x3c, 0x57, 0xf5, + 0xcb, 0x92, 0xef, 0xee, 0x35, 0xa7, 0x40, 0x6f, 0xc1, 0x48, 0xcf, 0x55, + 0x24, 0x29, 0x0b, 0xf0, 0x13, 0x2f, 0xc2, 0xe6, 0x5f, 0x71, 0x53, 0xb0, + 0xaf, 0xbc, 0x3c, 0xea, 0xe4, 0x64, 0xe2, 0x14, 0x6d, 0x2c, 0x9d, 0x29, + 0xc4, 0x72, 0x32, 0xef, 0xa4, 0x33, 0x0b, 0xd0, 0xbd, 0x05, 0xc7, 0xf3, + 0xa6, 0xec, 0xfe, 0xd4, 0x28, 0x30, 0x5e, 0x74, 0x76, 0x24, 0x27, 0x20, + 0xc8, 0x25, 0x2b, 0x25, 0x4b, 0x6e, 0x06, 0x3a, 0x86, 0xf7, 0xae, 0x85, + 0x7e, 0x00, 0x3a, 0x9e, 0x85, 0x7d, 0x93, 0x16, 0x53, 0x16, 0xfb, 0x20, + 0x3b, 0x47, 0x07, 0x2e, 0x4d, 0xf2, 0xfb, 0x6f, 0x40, 0xbe, 0x21, 0xdf, + 0x77, 0x81, 0xb6, 0x04, 0x70, 0x92, 0xae, 0xdb, 0xa4, 0xda, 0x05, 0xf9, + 0x0d, 0x25, 0x94, 0x5d, 0x16, 0x3a, 0xb7, 0x4a, 0xe1, 0x8e, 0x66, 0xbc, + 0xef, 0xc2, 0x98, 0xf2, 0x6f, 0xc1, 0x1c, 0xdf, 0xff, 0x4b, 0x60, 0x5f, + 0x4d, 0xeb, 0xc6, 0x57, 0xd1, 0xb7, 0xcb, 0x36, 0x8b, 0xbd, 0x89, 0xfe, + 0x9f, 0xd1, 0x77, 0xa2, 0xef, 0xc5, 0x5e, 0xe7, 0x21, 0x43, 0xca, 0x0f, + 0xcf, 0x0b, 0x5c, 0xb3, 0x3d, 0xd8, 0x97, 0x78, 0xdb, 0x81, 0x67, 0x53, + 0xb0, 0x57, 0x3b, 0xc6, 0xad, 0xc1, 0x5e, 0x16, 0x68, 0x8e, 0x29, 0x19, + 0x16, 0xac, 0xf8, 0xba, 0xb1, 0x86, 0x3e, 0x0e, 0xdc, 0x84, 0xd7, 0xe5, + 0x4a, 0x57, 0x17, 0x9e, 0xb9, 0x27, 0x61, 0xf8, 0x1e, 0xbd, 0x4b, 0xfc, + 0x1c, 0xe7, 0xe5, 0x09, 0x07, 0xfe, 0x89, 0xfa, 0xe6, 0x52, 0x8e, 0xbb, + 0x65, 0x02, 0xbc, 0x8f, 0x3b, 0xe9, 0x99, 0xaa, 0xee, 0x79, 0x7a, 0xd6, + 0x30, 0xab, 0x92, 0x86, 0x1d, 0x8f, 0xc9, 0x38, 0xe4, 0x77, 0xda, 0x89, + 0xcb, 0x45, 0x65, 0x7b, 0xe4, 0xe9, 0x21, 0xc8, 0x05, 0xf1, 0xa4, 0x8b, + 0xf6, 0x49, 0x9b, 0x82, 0xfc, 0x8a, 0xa6, 0x5c, 0xca, 0xd2, 0x96, 0xb3, + 0xb2, 0xbc, 0x6a, 0xcb, 0x15, 0xd8, 0x32, 0xed, 0xb8, 0x02, 0x7b, 0xf6, + 0xf5, 0xfa, 0x41, 0xd9, 0x06, 0xbd, 0x4e, 0x62, 0x3f, 0xea, 0xf5, 0xb3, + 0xd0, 0x6b, 0xc8, 0xd4, 0x86, 0xae, 0x9b, 0xd4, 0x89, 0x6f, 0xc3, 0xa7, + 0x81, 0xdf, 0x44, 0xf0, 0xbc, 0xfc, 0x5d, 0x29, 0x9c, 0x6a, 0x05, 0xdd, + 0x7b, 0xdb, 0x29, 0xb3, 0xf2, 0x32, 0x7f, 0xa1, 0x2e, 0x3e, 0x05, 0xf9, + 0xc1, 0x8f, 0x2a, 0x1d, 0x04, 0x6f, 0xd9, 0x3d, 0x80, 0x19, 0xc6, 0x39, + 0xb7, 0x02, 0x3f, 0x69, 0xbc, 0x15, 0x1c, 0xdf, 0x83, 0xee, 0x2c, 0xf5, + 0x15, 0xf3, 0x0b, 0xe1, 0x79, 0xb7, 0xa9, 0x3d, 0xcb, 0x43, 0xad, 0x01, + 0x7f, 0x94, 0x03, 0xf5, 0x3e, 0x09, 0xbd, 0xd5, 0x64, 0x5c, 0xe9, 0x6e, + 0x5e, 0xc9, 0x61, 0xde, 0xa1, 0xfe, 0x02, 0x87, 0x4d, 0x19, 0x98, 0x72, + 0xbf, 0x82, 0x4f, 0xae, 0xd9, 0x77, 0x37, 0x69, 0xe7, 0x78, 0x83, 0xf4, + 0x28, 0x1f, 0xd4, 0x1d, 0xe8, 0x76, 0x13, 0x6c, 0x9f, 0xef, 0x1e, 0x92, + 0xc7, 0xdc, 0x61, 0x9c, 0x43, 0x52, 0x0e, 0xba, 0xdd, 0xf2, 0xfb, 0xee, + 0x46, 0xb9, 0xdc, 0x09, 0xba, 0x56, 0x6d, 0xec, 0x6e, 0xf9, 0x03, 0xc6, + 0x3c, 0xf5, 0x0c, 0x3f, 0xa9, 0xdf, 0x05, 0x1a, 0x68, 0x4f, 0xb4, 0x2b, + 0xc2, 0xc5, 0xa4, 0xa4, 0xf6, 0xfc, 0x89, 0xef, 0xdb, 0x80, 0x77, 0xae, + 0x93, 0xf6, 0x4b, 0xda, 0x8c, 0xc0, 0x66, 0xd3, 0x66, 0x49, 0xc8, 0x33, + 0x69, 0xe5, 0x73, 0xa3, 0x2c, 0xd8, 0x37, 0xca, 0x20, 0xc4, 0x13, 0xda, + 0xe5, 0xa8, 0xe4, 0x5d, 0xf6, 0xf4, 0x97, 0x88, 0x91, 0x0e, 0x62, 0xa4, + 0x83, 0xd8, 0x08, 0x5b, 0x78, 0xc5, 0x41, 0x6c, 0x74, 0x10, 0x1b, 0xe1, + 0xcf, 0x5e, 0x72, 0x10, 0x1f, 0xa1, 0x43, 0x2f, 0x38, 0x8c, 0xeb, 0xdf, + 0x46, 0x4c, 0x35, 0xe4, 0x99, 0x9a, 0xc8, 0x91, 0x5a, 0x1a, 0xd4, 0xa5, + 0x87, 0x3f, 0x90, 0xfe, 0xcc, 0x07, 0x92, 0xb6, 0x2f, 0xe2, 0xf7, 0x96, + 0xe0, 0x9d, 0xca, 0x11, 0xf0, 0xbe, 0x1e, 0xe6, 0x13, 0x38, 0x7f, 0x8b, + 0x39, 0x83, 0x3f, 0x0f, 0x97, 0x88, 0xb8, 0x41, 0x9b, 0x1e, 0x93, 0xf9, + 0x59, 0xda, 0xf2, 0xed, 0x38, 0x8b, 0x4e, 0x99, 0xb2, 0xfc, 0x71, 0xc1, + 0xbe, 0xc3, 0x1c, 0xa5, 0xee, 0x98, 0x31, 0xd0, 0x76, 0x1b, 0x7e, 0x29, + 0xc4, 0xda, 0x3f, 0xd2, 0x0a, 0x0b, 0x71, 0xc4, 0x56, 0xc6, 0x5b, 0xc9, + 0xfb, 0x7a, 0x74, 0xc3, 0x1b, 0x5f, 0x5d, 0xd3, 0x0f, 0xfd, 0x86, 0xdc, + 0x13, 0x09, 0xc0, 0xcc, 0x6a, 0x23, 0xcb, 0x6f, 0xfb, 0x76, 0x92, 0xe5, + 0xf8, 0x46, 0x60, 0x7b, 0xdc, 0x1f, 0x63, 0x97, 0x78, 0xf9, 0x4c, 0x9c, + 0x97, 0x91, 0x1f, 0x24, 0x91, 0x17, 0x24, 0xe0, 0x7b, 0x98, 0x73, 0x74, + 0x23, 0x3f, 0xf0, 0xbc, 0x17, 0x6d, 0xcf, 0x7b, 0x07, 0xbf, 0x7f, 0xb7, + 0x57, 0x79, 0x40, 0xab, 0x68, 0xa3, 0x6e, 0x4a, 0x46, 0xdd, 0x9f, 0xb6, + 0xfb, 0x72, 0x8c, 0xcb, 0xa4, 0x93, 0x90, 0x29, 0xa7, 0xa6, 0xdd, 0xb7, + 0x3c, 0xad, 0x15, 0x97, 0x67, 0xb0, 0xaf, 0x81, 0x39, 0xa9, 0x54, 0xed, + 0x33, 0xda, 0x88, 0x7b, 0x54, 0xbb, 0x7f, 0xb9, 0x5d, 0xd9, 0x79, 0xd5, + 0x61, 0xce, 0x70, 0x5d, 0xe5, 0x2e, 0x05, 0x2b, 0x6d, 0xfe, 0x2e, 0x14, + 0xaf, 0x50, 0x23, 0xdd, 0xcd, 0x01, 0xcd, 0xb0, 0xc3, 0x9c, 0x77, 0xb8, + 0x90, 0xb5, 0x60, 0x8b, 0xa4, 0x51, 0xcd, 0x5d, 0xf0, 0xe9, 0x3e, 0xad, + 0x15, 0x96, 0xdb, 0xb4, 0x91, 0x53, 0x8c, 0xc7, 0xd2, 0x1d, 0x13, 0xae, + 0xdb, 0x01, 0x7b, 0xad, 0x63, 0x0f, 0xe6, 0x5b, 0x94, 0x2d, 0xe8, 0x86, + 0x0e, 0xbf, 0x04, 0x7a, 0x5e, 0x54, 0xf9, 0x0f, 0xf9, 0x4b, 0xe1, 0xac, + 0x42, 0xfe, 0x3c, 0xef, 0xaf, 0xed, 0x90, 0xfe, 0x74, 0x2a, 0xaf, 0x87, + 0xfc, 0x7a, 0xde, 0xbf, 0xd9, 0xe4, 0x99, 0x3c, 0x79, 0xde, 0x0b, 0x76, + 0x02, 0xf4, 0x7b, 0x17, 0x74, 0xab, 0x06, 0x7e, 0x18, 0xdb, 0x29, 0xf3, + 0x69, 0xf0, 0x71, 0x14, 0x3c, 0x9e, 0x06, 0x7f, 0x33, 0xa0, 0xe5, 0x37, + 0xed, 0xd9, 0x98, 0x4b, 0x4a, 0x8a, 0xb2, 0x2e, 0x2f, 0x32, 0xa7, 0x64, + 0x1e, 0x69, 0x4a, 0x69, 0x31, 0x5c, 0x1f, 0xea, 0xc3, 0x01, 0xd9, 0xeb, + 0x74, 0x42, 0x3e, 0x94, 0xe7, 0x35, 0xd0, 0x4b, 0x9f, 0x5f, 0xcd, 0xe8, + 0x08, 0x80, 0x65, 0x1b, 0xb1, 0x5e, 0x46, 0x94, 0x2e, 0x2c, 0x5a, 0x92, + 0x2f, 0xdb, 0x26, 0xed, 0x36, 0x55, 0xb6, 0x2b, 0xc8, 0x0c, 0x7c, 0x39, + 0x8e, 0xd4, 0x0c, 0xbc, 0xe3, 0x58, 0x60, 0xf3, 0xa1, 0x6c, 0x0d, 0xd8, + 0x5d, 0x28, 0xf3, 0x70, 0xee, 0xc1, 0x0e, 0xfa, 0xcc, 0x79, 0xf7, 0x0b, + 0xc0, 0x41, 0xbc, 0xbf, 0x09, 0x47, 0x1c, 0x31, 0x84, 0x78, 0xe2, 0x72, + 0xc6, 0x21, 0x3c, 0xf3, 0x8b, 0xb8, 0xb4, 0x22, 0x26, 0x6f, 0xc8, 0x89, + 0xf6, 0xf9, 0x1d, 0x69, 0x73, 0x31, 0x16, 0x93, 0x63, 0x09, 0xb9, 0xc3, + 0x60, 0x00, 0xd8, 0xec, 0x67, 0xea, 0x85, 0x19, 0x0d, 0xba, 0xdc, 0x26, + 0x93, 0x03, 0x69, 0x73, 0x1e, 0x7b, 0xe8, 0xd8, 0xe3, 0x6b, 0x9c, 0xaf, + 0xfd, 0x87, 0x57, 0x4a, 0xec, 0x84, 0x9d, 0x48, 0xdc, 0xc8, 0x19, 0x83, + 0x53, 0xb5, 0x03, 0xc2, 0xfc, 0x6a, 0x72, 0x60, 0x03, 0xec, 0xbc, 0x77, + 0x78, 0xaf, 0x30, 0x97, 0x8f, 0x0f, 0x8e, 0x5b, 0x3e, 0x5d, 0x23, 0xb0, + 0xeb, 0x49, 0xe4, 0x79, 0x7b, 0xeb, 0xcc, 0x01, 0x8c, 0xc1, 0xde, 0xba, + 0x21, 0x47, 0x60, 0xaf, 0xcd, 0xd0, 0x9f, 0x15, 0xa5, 0xcb, 0x26, 0x64, + 0x4d, 0xdf, 0x3a, 0x0c, 0xdc, 0xef, 0x40, 0x6e, 0x16, 0x62, 0x67, 0x37, + 0xf2, 0xd9, 0x0c, 0xce, 0x33, 0x85, 0xd8, 0xd7, 0xa8, 0xd7, 0x12, 0xdf, + 0x0a, 0xb8, 0x57, 0x76, 0x32, 0x2f, 0xf3, 0xbc, 0x07, 0xac, 0xf4, 0xb3, + 0xe4, 0x65, 0xca, 0x91, 0x7c, 0xd5, 0x56, 0xbe, 0x10, 0x3a, 0x9b, 0x62, + 0x3e, 0x07, 0xfd, 0x83, 0x4e, 0x16, 0x39, 0x5e, 0xd5, 0xc1, 0xe4, 0xa4, + 0xcc, 0x43, 0x76, 0x62, 0x16, 0xb2, 0x84, 0x0d, 0xe1, 0x5a, 0x02, 0xdd, + 0xf6, 0xbc, 0x18, 0x74, 0x77, 0x3c, 0x4b, 0x38, 0xa9, 0x28, 0x9b, 0x83, + 0xcc, 0x26, 0xdd, 0x5d, 0x1d, 0x7e, 0x3e, 0x09, 0x5f, 0x99, 0xe0, 0x5e, + 0x9f, 0x85, 0x0e, 0x77, 0x23, 0x86, 0x78, 0x1e, 0x6c, 0x38, 0xa1, 0x0b, + 0x75, 0x18, 0xf6, 0xe2, 0xf2, 0x5d, 0x1b, 0xe6, 0xc5, 0x9c, 0x84, 0x4f, + 0x2b, 0x99, 0x9e, 0x77, 0x0f, 0x68, 0xa9, 0xda, 0x1d, 0x58, 0xd7, 0x24, + 0x08, 0x7b, 0xa6, 0xbf, 0xdf, 0x46, 0x15, 0x3b, 0x30, 0x6e, 0xc7, 0x7e, + 0x9b, 0x98, 0x7b, 0x4e, 0xd2, 0x16, 0xb2, 0xb4, 0x7d, 0x23, 0xf0, 0xe7, + 0x6f, 0x82, 0x4e, 0xae, 0x51, 0x70, 0xf1, 0xa6, 0x5c, 0x56, 0x96, 0x6a, + 0xdb, 0x65, 0x6e, 0x3f, 0xf7, 0xe8, 0xa6, 0x1d, 0x22, 0xfe, 0xf3, 0x99, + 0x74, 0xd3, 0x8f, 0x74, 0x06, 0x63, 0xed, 0x73, 0xfe, 0x1e, 0x62, 0x32, + 0xdf, 0x1d, 0x51, 0xf4, 0x8a, 0x7e, 0xd1, 0xde, 0xe8, 0xc7, 0xa8, 0x5c, + 0xbb, 0x76, 0x0f, 0x72, 0xf0, 0xbd, 0xbb, 0xa9, 0x03, 0x86, 0x5c, 0xb2, + 0x3c, 0xef, 0x92, 0xdd, 0x04, 0xfe, 0x74, 0x69, 0xb2, 0x8e, 0x9b, 0xd2, + 0x0a, 0x99, 0x3b, 0x5a, 0x20, 0x97, 0x36, 0x25, 0x97, 0x49, 0x15, 0xf7, + 0xde, 0xc5, 0xd9, 0x70, 0x6d, 0x45, 0xc5, 0x97, 0x82, 0x5a, 0xc7, 0x35, + 0x3c, 0xd3, 0x77, 0x91, 0x73, 0x1f, 0xc3, 0xda, 0x98, 0xb4, 0x28, 0xdd, + 0x66, 0xfc, 0x27, 0xaf, 0xd2, 0xe1, 0xe3, 0x61, 0xac, 0xa5, 0x0e, 0x87, + 0xfc, 0x8f, 0x06, 0x3c, 0x12, 0xaf, 0x0d, 0xbc, 0x6d, 0xaa, 0xce, 0x28, + 0xfb, 0xe7, 0xd7, 0x11, 0x53, 0xf2, 0x40, 0x5d, 0x94, 0x0b, 0x7d, 0x21, + 0x41, 0x43, 0xba, 0x9f, 0xc1, 0x3e, 0xa4, 0x61, 0x13, 0xf2, 0x5e, 0xd1, + 0xaa, 0xe4, 0xcb, 0x0c, 0xf7, 0x11, 0x3d, 0x96, 0x6b, 0x91, 0x11, 0x68, + 0x5d, 0xd5, 0xb1, 0xcc, 0x07, 0xa0, 0x7b, 0x5f, 0x07, 0x8f, 0x85, 0x19, + 0xfa, 0xaa, 0x2f, 0x61, 0xdd, 0x4a, 0x5a, 0xf7, 0xb7, 0x95, 0x23, 0x0e, + 0x65, 0xfa, 0x0e, 0x64, 0xaa, 0x77, 0x35, 0x4b, 0x87, 0x14, 0x91, 0x4f, + 0xcd, 0x0f, 0x83, 0xaf, 0x81, 0x36, 0x89, 0xed, 0xa2, 0xaf, 0x42, 0xed, + 0x93, 0x58, 0x41, 0x60, 0xb8, 0xee, 0xe9, 0x3b, 0xb1, 0x7e, 0x20, 0x01, + 0xf9, 0x52, 0x66, 0x7a, 0x00, 0x47, 0x18, 0x14, 0x4a, 0x66, 0xa1, 0xb3, + 0x59, 0x88, 0x9b, 0xef, 0xfa, 0x93, 0xa6, 0x70, 0x1e, 0x3e, 0xbd, 0xc8, + 0xb5, 0xa4, 0xd9, 0x5f, 0xd3, 0x64, 0x85, 0xb2, 0xfe, 0x2b, 0xf8, 0xa7, + 0x5f, 0x79, 0x7b, 0x87, 0xc2, 0xf7, 0xe4, 0x87, 0x7c, 0xe1, 0x0c, 0x41, + 0xd3, 0xe6, 0x9c, 0x25, 0x83, 0xd3, 0xa2, 0x15, 0x90, 0x7b, 0x50, 0x47, + 0x7a, 0x86, 0xd2, 0x95, 0x94, 0xbe, 0x0d, 0xbc, 0x1a, 0xb2, 0x7f, 0x88, + 0xfc, 0x6e, 0x0d, 0xf2, 0x8e, 0x46, 0x9e, 0x3b, 0x02, 0x9e, 0xd5, 0x7e, + 0xc3, 0x79, 0x7d, 0x8d, 0xf7, 0xd1, 0x99, 0x70, 0x5f, 0x03, 0xb6, 0xbc, + 0x82, 0x9a, 0x87, 0xfb, 0x93, 0x9e, 0x1b, 0x9e, 0x6e, 0x59, 0x95, 0x1e, + 0xfd, 0x57, 0xde, 0xfd, 0x43, 0x9a, 0xca, 0xd3, 0x74, 0xe4, 0x8c, 0xfa, + 0x10, 0x78, 0x1d, 0xe2, 0x79, 0xe9, 0x72, 0xff, 0x6e, 0xe2, 0x3b, 0x42, + 0xde, 0x80, 0xb3, 0xd5, 0xaf, 0x61, 0x86, 0xc2, 0x3d, 0x1a, 0xf5, 0x27, + 0xc4, 0x49, 0x5c, 0x84, 0xe1, 0x99, 0xd0, 0xdf, 0x4a, 0xbc, 0x60, 0xc7, + 0x83, 0xb3, 0x0e, 0xd7, 0x89, 0x66, 0x58, 0xeb, 0xd7, 0xc1, 0x68, 0x1f, + 0xa4, 0xde, 0xf5, 0x04, 0x76, 0x16, 0xea, 0x21, 0xf7, 0x64, 0x7f, 0x2b, + 0x9d, 0xe5, 0x3a, 0xae, 0x27, 0x3c, 0x61, 0xe0, 0x33, 0xe0, 0x83, 0x7e, + 0x06, 0xdb, 0x78, 0xf9, 0x26, 0x5f, 0xce, 0xd8, 0x4e, 0x1f, 0x63, 0xaf, + 0xf7, 0xe7, 0xac, 0x7d, 0xf0, 0xac, 0xc3, 0x7e, 0x1b, 0xfd, 0x3a, 0xe7, + 0x50, 0x4f, 0x2c, 0x8e, 0xa2, 0xb7, 0x64, 0xed, 0x1e, 0x80, 0x7e, 0x3e, + 0xac, 0xe7, 0xdb, 0x4a, 0x46, 0x8e, 0x35, 0xbd, 0x14, 0xab, 0xb5, 0xc3, + 0x88, 0xc9, 0x52, 0xb9, 0x4d, 0xd5, 0xc6, 0x6d, 0xc3, 0x85, 0x2c, 0xe6, + 0xea, 0x8c, 0xcb, 0x30, 0x7f, 0xac, 0x43, 0x6c, 0x88, 0xeb, 0xd3, 0xf1, + 0xca, 0xed, 0x39, 0xda, 0x49, 0x4a, 0x52, 0xf5, 0x6b, 0x88, 0x79, 0xc8, + 0x1f, 0x95, 0x0e, 0x7d, 0xf1, 0x76, 0xd2, 0x5f, 0x45, 0xec, 0x32, 0x72, + 0x62, 0xe8, 0xb9, 0xe6, 0xf8, 0x64, 0xb6, 0x0d, 0xb1, 0x7e, 0x6c, 0xbb, + 0x7e, 0x6e, 0xdf, 0xf6, 0xd8, 0xb9, 0xae, 0x52, 0x53, 0xae, 0xb2, 0x5d, + 0x9f, 0x86, 0x2f, 0xaf, 0x89, 0x8e, 0x98, 0x8a, 0x1a, 0x01, 0xe3, 0x73, + 0x0f, 0x3c, 0xa0, 0xe7, 0x62, 0x52, 0x4e, 0xc8, 0x93, 0x8b, 0x59, 0xf8, + 0xf5, 0x5a, 0x3a, 0x55, 0x94, 0x27, 0xa5, 0x5a, 0x3b, 0x24, 0x93, 0xb5, + 0xf0, 0xde, 0x80, 0x77, 0x06, 0x49, 0xe5, 0xbf, 0xe8, 0x5f, 0x27, 0x03, + 0xda, 0x41, 0x73, 0x7e, 0x84, 0x31, 0x3a, 0x4b, 0xdf, 0x7d, 0x0d, 0x3a, + 0xd1, 0x12, 0xd4, 0xda, 0xbe, 0xfe, 0x19, 0xb9, 0x8f, 0x30, 0x47, 0xfd, + 0xdb, 0xb0, 0x7a, 0x6e, 0x7b, 0x4e, 0xfd, 0x89, 0x8a, 0xa9, 0x4b, 0x36, + 0x9f, 0x09, 0xf3, 0xf6, 0xe0, 0x94, 0x75, 0xdd, 0x64, 0x6d, 0x70, 0xc1, + 0x21, 0x3e, 0x53, 0x9d, 0xb5, 0x91, 0xbb, 0x8c, 0xb5, 0xad, 0xa4, 0x0b, + 0xcd, 0xc0, 0x3c, 0xf6, 0x77, 0x9a, 0x83, 0x71, 0xb8, 0xf6, 0xb5, 0x86, + 0xb5, 0x9c, 0x63, 0x4f, 0xdc, 0xd8, 0xa3, 0xe1, 0xce, 0xe4, 0x82, 0x9b, + 0x51, 0x35, 0x7b, 0xc1, 0x55, 0xb9, 0x02, 0x6a, 0x74, 0xe8, 0x93, 0xba, + 0x43, 0x81, 0x3f, 0x72, 0xff, 0xce, 0xf4, 0xcf, 0x9d, 0xfe, 0x63, 0x45, + 0x18, 0xdf, 0xa8, 0x6f, 0x53, 0xca, 0x4f, 0xbd, 0xd9, 0x70, 0x17, 0xf0, + 0x26, 0xfc, 0xd2, 0x9d, 0x9b, 0xfd, 0x9a, 0xc6, 0x0c, 0x7c, 0x5a, 0xab, + 0xca, 0x53, 0x7c, 0x9f, 0x96, 0x6a, 0x80, 0x4d, 0xf1, 0xde, 0xa0, 0xc3, + 0xaf, 0xbd, 0x7f, 0x2b, 0x58, 0xc3, 0xfc, 0xc1, 0x32, 0x99, 0x3b, 0xf8, + 0xb2, 0xf0, 0x9e, 0x59, 0x1d, 0x27, 0x4a, 0x01, 0xbe, 0xa6, 0xe0, 0xdd, + 0x5b, 0x6d, 0x3e, 0x4d, 0xe1, 0xda, 0x3f, 0x0d, 0xee, 0xa6, 0x94, 0x2f, + 0xcc, 0x03, 0x16, 0x3c, 0xa4, 0x4a, 0x3a, 0xf4, 0x66, 0xa4, 0xee, 0xcb, + 0x1b, 0xf1, 0x8e, 0xf7, 0x4f, 0x8a, 0xb6, 0x0b, 0x2a, 0xe7, 0x68, 0xe4, + 0x3f, 0x4f, 0xbe, 0xf3, 0x06, 0x69, 0x74, 0xc7, 0xb0, 0x56, 0x0e, 0xf8, + 0x77, 0x14, 0xa6, 0x4c, 0x98, 0xfd, 0xe6, 0x24, 0xf1, 0x26, 0x04, 0xf8, + 0x90, 0x97, 0xe4, 0xc2, 0x33, 0xfc, 0x26, 0xf7, 0x06, 0xde, 0x8d, 0x1c, + 0xa3, 0xff, 0x66, 0x40, 0xcb, 0x8f, 0x03, 0x79, 0x85, 0xef, 0x7f, 0xb1, + 0xf9, 0xe6, 0xf1, 0x3d, 0xb7, 0x07, 0xf2, 0xc4, 0xf3, 0xa1, 0x5f, 0x43, + 0x13, 0xf5, 0xfd, 0x34, 0xf0, 0xa8, 0x18, 0x5c, 0xd1, 0x73, 0x88, 0xf9, + 0x59, 0x64, 0x34, 0x35, 0xd8, 0xb4, 0x20, 0xf6, 0xbb, 0x69, 0xbb, 0x84, + 0x55, 0x1f, 0xd5, 0xe8, 0x57, 0xaf, 0xc3, 0xaf, 0xf2, 0xac, 0x3f, 0x96, + 0xa9, 0x5a, 0xaf, 0xdd, 0xac, 0xa9, 0xfc, 0x3a, 0x73, 0x5a, 0xfa, 0xed, + 0xd3, 0xc8, 0x3d, 0x50, 0xa3, 0xa5, 0x8e, 0x08, 0x65, 0x7e, 0x5d, 0x76, + 0xa8, 0x9c, 0xe0, 0x63, 0xb1, 0x20, 0x93, 0x22, 0xea, 0x04, 0x7d, 0xe8, + 0x5f, 0x3d, 0x95, 0xd3, 0x68, 0xa8, 0x42, 0x6f, 0x81, 0xeb, 0x6d, 0x85, + 0x87, 0xf8, 0x1a, 0x71, 0x69, 0xd2, 0x32, 0x14, 0xe2, 0x4b, 0xc9, 0x51, + 0x37, 0xc4, 0x69, 0xc8, 0x65, 0x64, 0x2d, 0xfa, 0x90, 0x17, 0xf0, 0xcf, + 0xe7, 0x5f, 0x7a, 0xcc, 0x09, 0xf4, 0xdc, 0xdd, 0x81, 0x0c, 0x7e, 0x8f, + 0x32, 0xc0, 0x18, 0x3a, 0xef, 0x7c, 0xc5, 0xaf, 0x45, 0x54, 0x2d, 0x37, + 0x86, 0x9a, 0x82, 0x73, 0x2b, 0x2d, 0x05, 0x3b, 0x3c, 0xe3, 0x7d, 0x98, + 0x2b, 0xe2, 0x47, 0xb9, 0x10, 0x66, 0x3f, 0x9e, 0xf3, 0x01, 0x9c, 0x0c, + 0xfb, 0x35, 0x79, 0x58, 0x8b, 0x84, 0x39, 0xa1, 0xcc, 0xe8, 0x39, 0xe6, + 0xef, 0x3b, 0x40, 0x2b, 0x73, 0x56, 0x9c, 0xe7, 0xaa, 0xff, 0x59, 0x85, + 0xa9, 0xac, 0xc1, 0xf8, 0xb9, 0xe7, 0xa8, 0x1b, 0xe6, 0xbb, 0xcc, 0x69, + 0xc3, 0xdc, 0x27, 0xaf, 0x15, 0x9d, 0x31, 0xed, 0x3e, 0x87, 0xf0, 0xfa, + 0xec, 0x66, 0xb1, 0x52, 0x3d, 0xba, 0x27, 0x23, 0x43, 0xac, 0x9d, 0x8f, + 0xe1, 0xcc, 0x3b, 0xa4, 0x9c, 0x41, 0x1e, 0x60, 0xde, 0x85, 0xbe, 0x19, + 0x73, 0x5f, 0xc6, 0x1c, 0x74, 0x23, 0xc3, 0xfc, 0x66, 0x83, 0xaa, 0x41, + 0x4a, 0x2a, 0x76, 0xec, 0x08, 0xf4, 0xe5, 0x89, 0x4e, 0x5f, 0x3f, 0xbe, + 0x87, 0xf1, 0x46, 0xcc, 0x7f, 0x03, 0xbd, 0xe7, 0xf5, 0x0c, 0x85, 0xf3, + 0xd4, 0xfb, 0x61, 0xcc, 0xdf, 0x09, 0x1c, 0x15, 0x3c, 0x7f, 0x0e, 0xcf, + 0x7f, 0xb8, 0x6e, 0xed, 0x77, 0x31, 0xae, 0x60, 0xbe, 0xb0, 0x6e, 0x3e, + 0xf4, 0xb3, 0xdc, 0xaf, 0xa2, 0x15, 0xdd, 0x29, 0x2d, 0xaf, 0xea, 0x88, + 0x63, 0xa8, 0x55, 0xe8, 0x6b, 0x59, 0xb3, 0xcc, 0x20, 0x17, 0xa7, 0x9f, + 0x3d, 0x88, 0x35, 0x8b, 0xd0, 0xbb, 0x56, 0x95, 0x65, 0xea, 0xca, 0x1e, + 0x0f, 0x1d, 0xec, 0x99, 0x63, 0x5f, 0x39, 0x68, 0xd7, 0x09, 0xc3, 0xe7, + 0x27, 0x0f, 0xf6, 0xd4, 0x0f, 0x01, 0x96, 0xf9, 0x7a, 0xe3, 0x1d, 0xef, + 0x37, 0xd6, 0xed, 0xe9, 0xd7, 0x38, 0x45, 0x75, 0x37, 0x78, 0xe8, 0x60, + 0x61, 0x86, 0x71, 0x9a, 0xf5, 0x26, 0xf3, 0xd2, 0xca, 0xc1, 0xf1, 0xda, + 0x54, 0x50, 0xd3, 0x84, 0xef, 0xf9, 0x8e, 0xf2, 0xbf, 0x15, 0x6d, 0xa4, + 0xab, 0x11, 0x8f, 0xca, 0x6b, 0x80, 0xe7, 0x49, 0xe0, 0x61, 0x6d, 0xa4, + 0xee, 0x90, 0x15, 0xbd, 0xa9, 0xb9, 0x5b, 0xd1, 0x46, 0x5c, 0xdc, 0x2b, + 0xc4, 0x77, 0x02, 0x75, 0xc7, 0x77, 0x48, 0x2f, 0xf0, 0x7c, 0x26, 0xc8, + 0x6d, 0x78, 0x37, 0x65, 0xf8, 0x77, 0x38, 0x6a, 0x1c, 0xd6, 0xbe, 0x4d, + 0xeb, 0x6a, 0xdf, 0xa6, 0xe0, 0x1e, 0x8b, 0xb0, 0x7a, 0x00, 0xab, 0xee, + 0xd0, 0x31, 0x97, 0x0a, 0xee, 0x94, 0xe3, 0xbc, 0x53, 0x6e, 0x90, 0x45, + 0x53, 0x20, 0x7f, 0xd2, 0x11, 0xd6, 0x2b, 0x8d, 0xf4, 0xf1, 0xbe, 0x79, + 0x0a, 0xef, 0xc3, 0xb3, 0x09, 0x79, 0x5f, 0xc4, 0x3c, 0xe9, 0x3d, 0x03, + 0xf8, 0x90, 0xde, 0x4f, 0x7b, 0xa6, 0x5c, 0x7b, 0x06, 0xbf, 0x70, 0xbf, + 0x50, 0x2e, 0xa4, 0xf5, 0xd7, 0xd5, 0x5a, 0xa1, 0xdf, 0x5b, 0x0c, 0x62, + 0x3a, 0xe9, 0xa2, 0x0f, 0xa2, 0x3f, 0x0e, 0xef, 0xc0, 0x59, 0x63, 0x33, + 0x56, 0xf0, 0xbc, 0x5a, 0xa0, 0x2b, 0x84, 0xd3, 0x90, 0x5f, 0xeb, 0xcc, + 0xc3, 0x52, 0xa8, 0x35, 0x92, 0x8f, 0xc8, 0x0f, 0xb0, 0x57, 0x3e, 0xd3, + 0xa4, 0xec, 0x88, 0xf7, 0x08, 0xcd, 0xb2, 0x02, 0x9d, 0xbe, 0x84, 0xfa, + 0x63, 0x1e, 0xb5, 0xd1, 0x12, 0xef, 0xb5, 0xeb, 0x27, 0x3b, 0x79, 0x1f, + 0x32, 0x65, 0xad, 0xd5, 0xf1, 0x73, 0x80, 0x59, 0xb0, 0x58, 0xeb, 0x4b, + 0xd0, 0x10, 0x23, 0x91, 0x67, 0x8c, 0x5b, 0xff, 0xe3, 0x95, 0x13, 0x8d, + 0xb0, 0xb7, 0xaa, 0xb3, 0xdb, 0xa4, 0x3a, 0x9b, 0x3e, 0x3a, 0x87, 0x7a, + 0x77, 0xc6, 0xd2, 0xb7, 0xe8, 0x7e, 0xad, 0x34, 0x03, 0xdf, 0xa4, 0x6a, + 0xad, 0x39, 0x79, 0xae, 0x93, 0x67, 0xd7, 0x64, 0xf5, 0x9b, 0x9d, 0xfa, + 0xef, 0x50, 0x17, 0x15, 0xe5, 0xb1, 0x13, 0x1b, 0xa4, 0x3c, 0x70, 0x1f, + 0x72, 0x2d, 0xc8, 0xf3, 0x44, 0x05, 0x95, 0x21, 0xf5, 0xea, 0xbd, 0x03, + 0xe3, 0x16, 0x6b, 0x26, 0xf1, 0xe3, 0x9a, 0xf8, 0x3c, 0xc6, 0x4e, 0xb4, + 0x29, 0x9f, 0xe4, 0xdf, 0x99, 0xf7, 0x9a, 0x45, 0xe4, 0x63, 0x85, 0x01, + 0x24, 0x8d, 0xc8, 0x5e, 0xcc, 0x9d, 0x22, 0x3d, 0xcc, 0x19, 0xe1, 0x8f, + 0x7b, 0xce, 0xc1, 0xcb, 0x9d, 0x20, 0xbc, 0x2e, 0xc6, 0x89, 0x98, 0x34, + 0x9d, 0x60, 0x9d, 0x2d, 0x5d, 0xa8, 0x51, 0x88, 0xb3, 0xc7, 0x40, 0x3f, + 0x8a, 0xdf, 0x1e, 0xe4, 0x51, 0x26, 0xf2, 0xda, 0x5b, 0xc0, 0x03, 0x96, + 0x6b, 0x6e, 0x05, 0xff, 0x6a, 0x27, 0xeb, 0xce, 0x9e, 0x73, 0x84, 0xe7, + 0x7d, 0x76, 0x17, 0xe8, 0xf1, 0xf7, 0x27, 0x0e, 0xe3, 0x84, 0x48, 0xef, + 0xb4, 0x74, 0xea, 0x6a, 0x8d, 0x21, 0xe3, 0x59, 0xbe, 0x6b, 0x03, 0xfc, + 0xab, 0xca, 0x3e, 0x7b, 0xd5, 0x3a, 0xff, 0xce, 0xa2, 0xbc, 0x46, 0x37, + 0xe6, 0x34, 0x3c, 0x23, 0x57, 0xca, 0x9a, 0xd2, 0x3b, 0xef, 0xc3, 0xf6, + 0x9c, 0xeb, 0xd8, 0xe2, 0xdf, 0xed, 0xf8, 0xb4, 0xf1, 0x6e, 0xb0, 0x0c, + 0xa9, 0x1a, 0x3b, 0x59, 0xf3, 0x13, 0x86, 0xdf, 0x52, 0xd8, 0x73, 0x2d, + 0xe5, 0xe7, 0xcf, 0xe9, 0xfa, 0xff, 0xa5, 0x5f, 0xeb, 0xbf, 0xe1, 0x84, + 0x77, 0x4b, 0xa9, 0x86, 0xbb, 0xa5, 0x74, 0xc3, 0xb7, 0x97, 0x9f, 0xb4, + 0x05, 0x7a, 0x27, 0x93, 0xb6, 0x27, 0xe1, 0xf7, 0xa5, 0xbd, 0x37, 0xe5, + 0x90, 0x19, 0x15, 0xa7, 0xc7, 0x21, 0xfb, 0x2b, 0x75, 0xd2, 0x8b, 0x98, + 0x53, 0x8f, 0xcb, 0xfb, 0x8b, 0xad, 0x72, 0x65, 0xce, 0xcf, 0x29, 0xaf, + 0xa8, 0x6f, 0x4e, 0xa6, 0x7c, 0x80, 0xc2, 0xff, 0x72, 0x3d, 0x83, 0x5f, + 0xa7, 0x5c, 0x5d, 0xbc, 0x39, 0xa7, 0xbc, 0xe0, 0xde, 0x0d, 0x5a, 0x3a, + 0x03, 0x1b, 0x46, 0xdd, 0x86, 0x18, 0x58, 0x09, 0xee, 0xea, 0x55, 0xce, + 0x62, 0xd0, 0x16, 0x78, 0x27, 0x1f, 0xde, 0x57, 0xf7, 0x9a, 0x17, 0x21, + 0xe3, 0xaf, 0x1a, 0x9d, 0xa8, 0xa3, 0x79, 0xd7, 0x16, 0xc6, 0xec, 0x30, + 0xf6, 0x90, 0xee, 0xb7, 0x81, 0x7b, 0x00, 0x7a, 0x4a, 0xdd, 0xb4, 0xa1, + 0xb3, 0xa6, 0x2c, 0xf5, 0xa5, 0x67, 0x2a, 0xc2, 0xef, 0x02, 0x59, 0xec, + 0xb9, 0x0c, 0xbd, 0xcc, 0x40, 0x1e, 0xcc, 0xf5, 0x28, 0x57, 0x9c, 0xed, + 0xf4, 0x94, 0x94, 0xdd, 0xad, 0xc0, 0x97, 0x97, 0x92, 0x3b, 0x8c, 0xbd, + 0x8e, 0x43, 0x6f, 0x7f, 0xb9, 0x85, 0x77, 0x99, 0xcd, 0x56, 0x16, 0x34, + 0xde, 0x25, 0xe3, 0x27, 0xa7, 0x64, 0xc2, 0x59, 0xfd, 0x66, 0x94, 0xe1, + 0xf7, 0x94, 0x45, 0xd4, 0xb4, 0xbe, 0x3d, 0xe6, 0x64, 0xfc, 0x14, 0x70, + 0x38, 0xac, 0x8d, 0x7b, 0xa1, 0x37, 0xfd, 0xaa, 0x36, 0x2e, 0x29, 0x9f, + 0xc4, 0xf9, 0xef, 0x01, 0x57, 0x6f, 0x65, 0x0f, 0xe0, 0xca, 0xa8, 0x9f, + 0x8b, 0xc8, 0x85, 0x17, 0x1c, 0x43, 0xca, 0x36, 0x7c, 0x6b, 0x31, 0xa9, + 0xeb, 0xbb, 0xba, 0x65, 0xde, 0xe9, 0x37, 0x75, 0xde, 0x3d, 0x26, 0x7c, + 0xdf, 0x57, 0x56, 0xf6, 0x9d, 0xd4, 0x0d, 0xab, 0x5b, 0x16, 0x9d, 0x8a, + 0x54, 0x07, 0x38, 0xe6, 0xf9, 0x55, 0xc4, 0xb4, 0x7c, 0x5f, 0x99, 0xd7, + 0x35, 0x75, 0xb7, 0x5d, 0x76, 0xd5, 0xfd, 0x68, 0xca, 0x94, 0xc3, 0xa0, + 0x0f, 0xcf, 0x0b, 0xd0, 0xf1, 0x69, 0xe6, 0x78, 0xfe, 0x9d, 0xf1, 0x81, + 0xe5, 0x22, 0x68, 0x68, 0x97, 0xde, 0x1f, 0xd3, 0xc6, 0x1e, 0xc2, 0x1c, + 0xc7, 0x69, 0xe8, 0xeb, 0xc3, 0x78, 0x26, 0x6c, 0x12, 0x3d, 0xe5, 0xd0, + 0x8d, 0xde, 0x04, 0x2d, 0xd0, 0x4b, 0xd6, 0xa5, 0xfb, 0x53, 0x32, 0x7f, + 0x72, 0xb7, 0x94, 0x16, 0x76, 0x03, 0xff, 0x3f, 0x22, 0xe7, 0xbf, 0x33, + 0xb8, 0x8b, 0x65, 0xde, 0xcf, 0x7d, 0x5e, 0xdc, 0xa2, 0x6c, 0x63, 0x9a, + 0xf3, 0xec, 0xf7, 0x61, 0x3d, 0xea, 0x07, 0x47, 0xdd, 0x4f, 0x03, 0x06, + 0x67, 0xe7, 0x36, 0x7e, 0xfb, 0xeb, 0x84, 0x9f, 0xae, 0xb0, 0x76, 0x40, + 0x6c, 0x99, 0x1b, 0x2c, 0xd4, 0xd2, 0x66, 0x41, 0x7d, 0x97, 0xc8, 0x88, + 0x1f, 0x6f, 0x38, 0x17, 0x17, 0x6b, 0x1a, 0xf5, 0x68, 0x8e, 0xef, 0x0e, + 0xab, 0xfb, 0x1f, 0xf5, 0x7d, 0x4e, 0xde, 0x95, 0x51, 0xe8, 0x58, 0xef, + 0x74, 0x06, 0x39, 0xf1, 0x7b, 0xc8, 0x27, 0x7f, 0x1e, 0xc8, 0x60, 0x38, + 0xd0, 0x8d, 0xd6, 0x06, 0x9d, 0xc0, 0x39, 0x3b, 0x38, 0x7b, 0x07, 0x7a, + 0xe0, 0xe0, 0xac, 0x57, 0xf5, 0x63, 0xb8, 0xc1, 0xe7, 0x6e, 0x92, 0xbf, + 0x9c, 0x49, 0x67, 0x56, 0xa0, 0x3f, 0x57, 0xc1, 0xeb, 0x0a, 0xea, 0xbc, + 0x2b, 0x88, 0x23, 0x0b, 0x35, 0x7e, 0x4b, 0xe0, 0xb7, 0x38, 0x8e, 0xb7, + 0xe1, 0x3c, 0x42, 0x7f, 0xfc, 0x52, 0x60, 0x17, 0x9b, 0xd4, 0x7d, 0xe7, + 0xfb, 0x38, 0xc3, 0x15, 0xd3, 0xcf, 0x17, 0xfd, 0x35, 0x9b, 0x24, 0xfc, + 0xde, 0xe7, 0xeb, 0x0f, 0x69, 0xa1, 0xfe, 0x7c, 0xb2, 0xc5, 0xcf, 0xfb, + 0xf9, 0x0d, 0x8c, 0xf5, 0x0b, 0x9f, 0xef, 0xdf, 0xe2, 0xe3, 0x6a, 0xd4, + 0xdb, 0x8f, 0x3d, 0xd6, 0x6a, 0x85, 0x3e, 0xf8, 0x6c, 0xd7, 0x93, 0x63, + 0xf6, 0xcd, 0xf6, 0x76, 0x8f, 0x13, 0xca, 0x87, 0xf2, 0x2b, 0xca, 0x11, + 0x37, 0x0d, 0x5b, 0xa0, 0xec, 0xac, 0x06, 0xd9, 0x89, 0xfc, 0xb9, 0x23, + 0xbc, 0xef, 0xc2, 0x3b, 0x25, 0xbb, 0x64, 0x21, 0xd6, 0xca, 0xfb, 0x5a, + 0xe8, 0xe3, 0xdf, 0xca, 0xc4, 0xac, 0xc8, 0x32, 0xde, 0x2f, 0x39, 0xb4, + 0xd1, 0x0c, 0xf2, 0xd7, 0x8d, 0x32, 0x3f, 0x87, 0x3a, 0xcb, 0x91, 0x52, + 0xe1, 0x4e, 0xc6, 0x99, 0xb8, 0x5c, 0x51, 0xf7, 0x7b, 0x22, 0x3b, 0xcf, + 0x1a, 0x62, 0x9c, 0x45, 0x41, 0x07, 0x99, 0x9f, 0xef, 0x0b, 0xef, 0xfb, + 0x7c, 0x5b, 0xaf, 0xd6, 0xb0, 0xd6, 0xe9, 0x55, 0xfe, 0xb1, 0x5a, 0x1f, + 0x97, 0xf2, 0x0c, 0xf7, 0x42, 0x3f, 0x97, 0xc2, 0x3b, 0x5b, 0x26, 0x4f, + 0x66, 0xe4, 0xfb, 0xfc, 0x5e, 0x93, 0x1d, 0xc5, 0x1e, 0x05, 0xa9, 0x2c, + 0x63, 0xbe, 0xfe, 0x4f, 0x32, 0xb7, 0x38, 0x2e, 0xf3, 0x33, 0x17, 0x1a, + 0xee, 0x73, 0x31, 0x9e, 0x6b, 0xac, 0x4f, 0x8b, 0xac, 0xa9, 0x50, 0x7f, + 0x5a, 0x18, 0xc3, 0x06, 0xea, 0x93, 0xa5, 0x9b, 0xef, 0x1f, 0x1b, 0xeb, + 0xd2, 0x51, 0x39, 0x8a, 0x33, 0xae, 0x9e, 0xcc, 0xa8, 0xba, 0xa6, 0x25, + 0x37, 0xfb, 0xf8, 0x87, 0x88, 0x11, 0x63, 0x42, 0x3d, 0xbb, 0x2e, 0x5f, + 0xb3, 0x8f, 0xca, 0x23, 0x88, 0x1d, 0x47, 0x90, 0x5f, 0xff, 0x36, 0xea, + 0xba, 0xd4, 0x66, 0x9e, 0x21, 0xe8, 0xb5, 0x58, 0x57, 0x7a, 0x32, 0x6a, + 0xdf, 0x61, 0xfe, 0x00, 0x92, 0x7d, 0xbf, 0xce, 0xf8, 0xf8, 0xdf, 0x5e, + 0x1e, 0xf1, 0xee, 0x43, 0x0b, 0x3e, 0x41, 0xc1, 0x69, 0x3e, 0xdc, 0x0c, + 0xe1, 0xfa, 0xcd, 0x63, 0x84, 0x9b, 0xd3, 0x02, 0x38, 0x0d, 0x70, 0x31, + 0xb9, 0x68, 0x1b, 0xd0, 0x8d, 0x51, 0xf0, 0x09, 0xdf, 0x3e, 0x18, 0x7e, + 0x6f, 0xdc, 0x80, 0x98, 0xba, 0xb6, 0xfe, 0x8d, 0x60, 0xfd, 0xf7, 0x83, + 0xf5, 0x97, 0x56, 0xd7, 0x87, 0x71, 0xf5, 0x13, 0x4f, 0x1a, 0xe8, 0x7a, + 0xa3, 0xe6, 0xc3, 0x1f, 0x0d, 0xe8, 0xba, 0xb4, 0x4a, 0x57, 0x08, 0x0f, + 0x79, 0x2a, 0x9e, 0xe9, 0x93, 0xe9, 0x9b, 0x7b, 0x21, 0x47, 0x7e, 0x47, + 0x86, 0x4d, 0x38, 0xfc, 0x7e, 0x4b, 0x3b, 0xd1, 0x65, 0x25, 0x71, 0x54, + 0xc6, 0xac, 0xf4, 0xf0, 0xa4, 0xc4, 0xa0, 0xc3, 0xf4, 0x29, 0x31, 0x99, + 0xa7, 0xaf, 0x41, 0x5f, 0xb6, 0x6f, 0x4d, 0xeb, 0xfb, 0x0d, 0xb4, 0xc6, + 0x9e, 0x27, 0x8d, 0x3e, 0xad, 0xf1, 0x1d, 0x6b, 0xb4, 0xfa, 0xf0, 0x3e, + 0xad, 0xef, 0xd7, 0x1a, 0xe0, 0xcf, 0x1a, 0x01, 0xbc, 0xd1, 0x00, 0x4f, + 0x7d, 0x66, 0x3e, 0x41, 0x7d, 0x26, 0x6d, 0x5f, 0x50, 0xf7, 0x66, 0x1b, + 0x72, 0xb3, 0x07, 0x3f, 0xbf, 0xc3, 0x93, 0x38, 0xf2, 0x8c, 0x66, 0xbc, + 0xbb, 0x32, 0xc3, 0x1c, 0x44, 0xef, 0x69, 0x96, 0x9d, 0xd0, 0x59, 0x9e, + 0x5d, 0xe3, 0x9d, 0xab, 0x27, 0x8f, 0xd8, 0xa4, 0xe5, 0x3f, 0xbd, 0x33, + 0x89, 0x9d, 0x76, 0x55, 0xfa, 0xcc, 0x66, 0xe1, 0x9d, 0xae, 0xc2, 0x99, + 0x21, 0x2d, 0xa7, 0xfb, 0x7a, 0xcd, 0xb7, 0xc0, 0xe7, 0xe8, 0x8c, 0x26, + 0xf3, 0x56, 0x3a, 0x79, 0x1e, 0x38, 0xf6, 0xe0, 0x6c, 0xe6, 0x07, 0x48, + 0x8f, 0xc8, 0x04, 0xf4, 0x7b, 0x5e, 0xc5, 0x43, 0xea, 0x71, 0x7a, 0xac, + 0x82, 0x1c, 0xe7, 0xa7, 0x2a, 0xa6, 0x79, 0xde, 0x87, 0x88, 0x6b, 0x63, + 0xeb, 0x74, 0x4f, 0x3f, 0xeb, 0xeb, 0x9e, 0x7e, 0x16, 0xb5, 0xf1, 0xf1, + 0xb8, 0xb4, 0x2c, 0xc1, 0x7e, 0x9e, 0xef, 0x52, 0xfa, 0xa7, 0x3f, 0xcf, + 0x6f, 0x19, 0xf0, 0x73, 0xc7, 0x0d, 0xb1, 0x8e, 0xab, 0x38, 0x00, 0x79, + 0x17, 0x64, 0xf2, 0x14, 0x7d, 0xa9, 0x25, 0x3b, 0x8e, 0xf3, 0x3c, 0x98, + 0xcf, 0xcc, 0x0d, 0x8e, 0xc3, 0x46, 0xa6, 0xf8, 0x7d, 0x70, 0xe9, 0x23, + 0x19, 0xb7, 0x28, 0x07, 0x94, 0xfa, 0x4b, 0xa6, 0xc4, 0x96, 0xe0, 0x13, + 0x96, 0x92, 0xd2, 0x04, 0xdb, 0xd2, 0xcf, 0x26, 0xb4, 0xea, 0xec, 0x7f, + 0xc1, 0x1e, 0xf8, 0x4d, 0x20, 0x83, 0x71, 0x52, 0xab, 0xd6, 0x06, 0xd0, + 0x53, 0xcf, 0x91, 0x46, 0x9d, 0xa5, 0x9e, 0x93, 0x8e, 0xd0, 0x5e, 0xf0, + 0x7c, 0x36, 0xa3, 0xee, 0x6c, 0x3f, 0xb4, 0xc9, 0xcb, 0xdf, 0x48, 0x61, + 0x26, 0xfc, 0x1b, 0x10, 0xd9, 0x8c, 0x1c, 0xa6, 0xa3, 0x60, 0xef, 0x18, + 0xbe, 0x22, 0x9f, 0x96, 0xaf, 0x6d, 0x9f, 0x82, 0x2f, 0xf2, 0xd1, 0xc8, + 0x17, 0x79, 0x6a, 0x97, 0x26, 0xc5, 0x57, 0xc8, 0x0f, 0x04, 0x0d, 0x7e, + 0x7a, 0x8e, 0x27, 0x81, 0xff, 0x61, 0xf8, 0x80, 0x6e, 0xf4, 0x0f, 0xa1, + 0x47, 0x28, 0x3b, 0x4b, 0xde, 0xc9, 0xeb, 0x55, 0xe4, 0x8b, 0x21, 0x9f, + 0x25, 0x3c, 0xbf, 0x2e, 0x93, 0xb3, 0xde, 0x61, 0xc4, 0x53, 0xde, 0x27, + 0x77, 0xea, 0x4a, 0x77, 0xd7, 0xf3, 0xfe, 0xba, 0xf8, 0xf2, 0xe1, 0x5d, + 0x3c, 0x9e, 0x17, 0xd7, 0xcb, 0xa2, 0xd1, 0x77, 0x24, 0x83, 0xbf, 0x7b, + 0xa1, 0x9f, 0xa0, 0x8c, 0xae, 0x4a, 0x61, 0x96, 0x77, 0x5a, 0x3e, 0xbe, + 0xd2, 0xea, 0xdf, 0xbe, 0x34, 0xae, 0x19, 0x00, 0x5c, 0x37, 0xe0, 0x48, + 0xd7, 0x0a, 0xe5, 0x07, 0x9f, 0xb3, 0xbd, 0xc1, 0xd7, 0x34, 0xae, 0xcb, + 0xca, 0x33, 0x88, 0xff, 0x6f, 0xd8, 0x37, 0xc9, 0xb5, 0xc4, 0x1c, 0x68, + 0xbe, 0xbe, 0x0f, 0x36, 0xd9, 0x04, 0x5f, 0x66, 0xca, 0x95, 0x5a, 0xb3, + 0xcc, 0x23, 0xcf, 0x59, 0x58, 0xa4, 0x2f, 0x24, 0xed, 0xad, 0x98, 0xf7, + 0xfd, 0x17, 0x7d, 0xed, 0x95, 0x1a, 0xe2, 0x2b, 0x6c, 0xfb, 0x4a, 0x2d, + 0x81, 0xbe, 0x1b, 0xbd, 0x85, 0x3e, 0x85, 0x3e, 0x83, 0x7e, 0x00, 0xfd, + 0x00, 0x7a, 0x0b, 0x6b, 0x93, 0xe8, 0xc3, 0x5a, 0x82, 0xb8, 0xd6, 0xf8, + 0xae, 0xaa, 0xfd, 0xf8, 0xdd, 0x90, 0xb1, 0xcc, 0xb0, 0x47, 0x50, 0x63, + 0x17, 0x06, 0xc2, 0xbf, 0xb9, 0xb9, 0xe1, 0x99, 0x16, 0x6b, 0xf7, 0x8a, + 0xb6, 0x47, 0x7d, 0x5f, 0x98, 0x41, 0x5c, 0x78, 0x6e, 0xab, 0xb4, 0x5a, + 0xe6, 0x3d, 0xea, 0xee, 0x68, 0x16, 0x63, 0x3e, 0xa3, 0x3e, 0x4e, 0x4c, + 0x21, 0x3e, 0xd1, 0x7f, 0xfe, 0x6f, 0xe7, 0xd6, 0x1b, 0xdb, 0xc6, 0x59, + 0xc6, 0x1f, 0x9f, 0x9d, 0x34, 0xe9, 0x9a, 0xf6, 0x92, 0x38, 0xa9, 0x93, + 0x85, 0xcd, 0x8e, 0x2f, 0xad, 0x45, 0xd2, 0x71, 0xed, 0x2c, 0x16, 0xa6, + 0x8c, 0x78, 0x76, 0x92, 0x76, 0x30, 0xa6, 0xb4, 0x74, 0xd3, 0x84, 0x10, + 0x58, 0xc9, 0xba, 0x75, 0x13, 0xd2, 0x28, 0x30, 0x34, 0x89, 0xa2, 0x18, + 0x27, 0x61, 0x19, 0x18, 0xc7, 0x0b, 0x81, 0x4e, 0xf0, 0xc5, 0x38, 0xd1, + 0x06, 0x22, 0x4a, 0x3a, 0x8d, 0x0f, 0x08, 0x6d, 0x74, 0xb8, 0x83, 0xef, + 0xfc, 0x11, 0x62, 0x12, 0x1f, 0xaa, 0xa8, 0x63, 0x20, 0x21, 0xe0, 0x23, + 0xd2, 0x98, 0x8e, 0xdf, 0xef, 0x79, 0xef, 0x12, 0xc7, 0x64, 0x54, 0xf0, + 0xc1, 0x3a, 0xbf, 0x77, 0xf7, 0xbe, 0xf7, 0xde, 0xfb, 0x3c, 0xef, 0xef, + 0xf9, 0x3d, 0x7f, 0xce, 0x43, 0x9f, 0x19, 0xe0, 0xf8, 0x11, 0x61, 0x0c, + 0x36, 0x9b, 0xc6, 0xff, 0xea, 0xc5, 0x1e, 0x63, 0x4b, 0xc1, 0xdb, 0x77, + 0xb8, 0x61, 0x60, 0xab, 0x46, 0xd0, 0x67, 0x3f, 0x9f, 0x00, 0x36, 0xb0, + 0x92, 0xa8, 0x54, 0xb1, 0x07, 0x7f, 0xed, 0xce, 0x29, 0xa7, 0xa3, 0x2c, + 0x16, 0xc1, 0x4d, 0x73, 0x65, 0x72, 0x97, 0xcb, 0xf0, 0x47, 0xe0, 0xcb, + 0x45, 0xe9, 0xbb, 0xd3, 0x16, 0x90, 0x83, 0xfe, 0x12, 0x73, 0xa3, 0x1d, + 0xf8, 0x26, 0x9e, 0x87, 0xf7, 0x5a, 0xf3, 0xb0, 0x66, 0xa7, 0xc1, 0x05, + 0x3d, 0x2f, 0xe2, 0x4c, 0x4a, 0xfc, 0x1c, 0x31, 0x47, 0xd0, 0xdf, 0xc4, + 0xb2, 0xc8, 0xab, 0x32, 0xd3, 0x9a, 0x83, 0x84, 0x72, 0xfd, 0x0e, 0x7d, + 0x7b, 0xc4, 0xc4, 0xa7, 0x18, 0x7f, 0x16, 0x99, 0x2c, 0x1b, 0x2e, 0x0b, + 0xbf, 0xac, 0x61, 0xbc, 0xbb, 0xfd, 0xf1, 0x78, 0xdd, 0xd2, 0x71, 0x6a, + 0xd2, 0x6b, 0x62, 0xbb, 0x63, 0x23, 0xb0, 0x11, 0x51, 0xa9, 0x43, 0x2e, + 0xd7, 0x21, 0x93, 0x37, 0x4b, 0xd4, 0xf5, 0x61, 0xe8, 0x7d, 0x0b, 0xf3, + 0xb3, 0x18, 0x6b, 0x44, 0x9f, 0x5d, 0x2f, 0x01, 0x3b, 0x6d, 0xf5, 0x4f, + 0x7b, 0xc9, 0x0b, 0x69, 0x07, 0xcd, 0x38, 0x03, 0xe6, 0x3e, 0x09, 0xae, + 0x75, 0xeb, 0x7c, 0x6a, 0x1a, 0x03, 0xe3, 0x3a, 0x41, 0x07, 0x4b, 0xdd, + 0xfe, 0x3d, 0x5e, 0x8f, 0xa9, 0x77, 0xe2, 0x39, 0xbe, 0xc7, 0x88, 0x64, + 0xcb, 0x41, 0xbf, 0x4e, 0xf4, 0x6b, 0x6f, 0x18, 0xeb, 0x68, 0xd3, 0x3b, + 0x58, 0xfe, 0x3b, 0xf0, 0x7a, 0x33, 0xdf, 0x4f, 0xd8, 0x05, 0x09, 0x38, + 0x3f, 0xed, 0x2f, 0x65, 0x93, 0xd6, 0xfc, 0xb6, 0x91, 0xcf, 0x80, 0xef, + 0x03, 0x24, 0x96, 0x0a, 0x02, 0xbe, 0x18, 0xa5, 0x8c, 0xd2, 0xd8, 0xd7, + 0x3f, 0x89, 0xca, 0x61, 0x57, 0x2a, 0xa5, 0x03, 0x62, 0x75, 0xb5, 0x68, + 0x8d, 0x4e, 0xdc, 0x6a, 0x7c, 0xe6, 0x67, 0xfd, 0x67, 0xc2, 0xf7, 0x5e, + 0x69, 0xd7, 0xb8, 0x34, 0xec, 0x0c, 0xee, 0x39, 0xd4, 0x34, 0xb7, 0x87, + 0xfd, 0xfb, 0x78, 0xdd, 0x91, 0x02, 0xf8, 0x67, 0xae, 0x0c, 0x26, 0x0f, + 0xfc, 0xb6, 0xc6, 0x98, 0xe3, 0x61, 0x0c, 0x6f, 0x38, 0x3e, 0x8f, 0x39, + 0x16, 0xec, 0x31, 0xc6, 0xcd, 0x30, 0x46, 0x5f, 0xd3, 0x18, 0x13, 0xfe, + 0x18, 0x59, 0x29, 0x5e, 0x99, 0xc0, 0x5e, 0x1b, 0x83, 0x7d, 0x4f, 0xda, + 0xa7, 0xe5, 0x23, 0x22, 0x9d, 0x38, 0xf7, 0x72, 0x0a, 0x72, 0xf2, 0xbc, + 0x49, 0x77, 0x1a, 0xf3, 0x7e, 0x0d, 0xb6, 0x35, 0xe0, 0x3c, 0xc5, 0x58, + 0x18, 0x36, 0xec, 0xf3, 0x2e, 0xe3, 0x62, 0x05, 0x30, 0xb2, 0x84, 0x6d, + 0x85, 0x86, 0x53, 0x35, 0xf0, 0xba, 0x2a, 0x2c, 0x69, 0xd1, 0xe1, 0x7b, + 0x76, 0x48, 0xd1, 0x0e, 0x8d, 0x87, 0xc1, 0x6b, 0xb2, 0x65, 0xee, 0x23, + 0x19, 0x0a, 0x8f, 0xb5, 0x82, 0x8b, 0x7a, 0xf2, 0x36, 0xa0, 0xa6, 0x58, + 0x5a, 0x92, 0xfa, 0x86, 0x8d, 0xe3, 0x05, 0xc8, 0xe1, 0x45, 0xfc, 0x7f, + 0x3e, 0xaa, 0x75, 0x4a, 0xe0, 0xeb, 0x8b, 0x78, 0x1f, 0xf2, 0x19, 0xf2, + 0x88, 0x1a, 0xec, 0xad, 0x05, 0x5b, 0x03, 0x5e, 0x35, 0x4a, 0xde, 0xf5, + 0xdc, 0xda, 0x4d, 0x79, 0x73, 0x35, 0x81, 0x67, 0xd1, 0x2e, 0x9f, 0x21, + 0x1e, 0xd8, 0x0b, 0x69, 0x9c, 0x5b, 0x37, 0xdc, 0xb7, 0xb8, 0x85, 0x0d, + 0xd4, 0x05, 0x8e, 0x00, 0x8e, 0xbd, 0x0d, 0x0c, 0x2c, 0xe2, 0xfe, 0xfa, + 0x6a, 0x44, 0xd6, 0x1c, 0xf2, 0x22, 0x89, 0x67, 0x71, 0x6f, 0x7d, 0x7d, + 0xb1, 0xd7, 0xe4, 0x51, 0xd8, 0x7f, 0x42, 0x0a, 0xe0, 0x75, 0xa7, 0xb5, + 0xef, 0xad, 0xe4, 0xcc, 0x39, 0x35, 0xfa, 0x77, 0xb3, 0x52, 0xe7, 0x7e, + 0xd2, 0xdc, 0x03, 0xb9, 0xc1, 0x65, 0xe8, 0x2c, 0x39, 0x3b, 0xfd, 0x00, + 0xfc, 0xdf, 0xe0, 0x75, 0xbe, 0x3b, 0x8e, 0xd5, 0x24, 0xd6, 0x86, 0xfb, + 0xbe, 0x10, 0x9a, 0x3e, 0x0e, 0x3b, 0x6a, 0x71, 0xaf, 0x17, 0x15, 0x0b, + 0x8a, 0xcb, 0xb3, 0xb0, 0x29, 0xac, 0xb5, 0xe8, 0x83, 0x2e, 0x3e, 0x08, + 0x59, 0xa6, 0x71, 0x5f, 0x93, 0x2d, 0xd9, 0x2c, 0x2a, 0x2f, 0xb3, 0x5e, + 0x32, 0xb8, 0x66, 0xd5, 0xc0, 0xd1, 0xb0, 0x7f, 0xac, 0x4d, 0xe8, 0x16, + 0xf6, 0x90, 0xb5, 0x19, 0xc5, 0x11, 0x78, 0xbc, 0x09, 0xbf, 0x02, 0xf8, + 0x66, 0x6d, 0xc2, 0x27, 0x00, 0xbe, 0x59, 0x9b, 0x29, 0x1c, 0x81, 0xf1, + 0x9b, 0x01, 0xae, 0x71, 0xfc, 0x94, 0xe6, 0xe1, 0x0d, 0xbe, 0x90, 0x4b, + 0x12, 0x5f, 0x02, 0x3e, 0x69, 0x74, 0xe1, 0xeb, 0xcb, 0xc4, 0x10, 0xea, + 0x75, 0x12, 0xb8, 0x45, 0x5d, 0x30, 0x5c, 0x72, 0xbd, 0x62, 0xd6, 0x6c, + 0x7e, 0xeb, 0x9a, 0xda, 0x88, 0x29, 0x71, 0xa0, 0x63, 0x5c, 0x3b, 0x5c, + 0x53, 0x1b, 0xf0, 0xba, 0x64, 0xf4, 0xc8, 0x35, 0xfb, 0xb9, 0x64, 0xd6, + 0x53, 0xf2, 0x0d, 0xc5, 0xad, 0x00, 0xb3, 0xc8, 0x21, 0x63, 0x58, 0x3f, + 0x47, 0x9e, 0xff, 0xf6, 0x4d, 0xc9, 0x7e, 0x87, 0xb8, 0x35, 0x1c, 0x6b, + 0x0f, 0x11, 0xab, 0x3c, 0xd9, 0x80, 0x6d, 0x3a, 0xed, 0x26, 0x1e, 0x65, + 0xfd, 0x66, 0x1e, 0xba, 0xd2, 0x7a, 0x32, 0xe1, 0xc6, 0x43, 0xc9, 0x47, + 0xdb, 0x43, 0xb4, 0x8d, 0xc3, 0xf6, 0x45, 0x39, 0xe5, 0xc7, 0xa3, 0x0e, + 0xc8, 0x45, 0xe5, 0xfe, 0x2c, 0xcf, 0x78, 0x57, 0x73, 0x23, 0xef, 0xa4, + 0xb9, 0xd6, 0x68, 0x6f, 0x6a, 0xdc, 0xa8, 0xed, 0x9d, 0x74, 0x8b, 0x14, + 0x7b, 0x3c, 0xef, 0xc2, 0xc9, 0xb7, 0xa2, 0x26, 0xce, 0xd5, 0x7f, 0xd4, + 0x60, 0x01, 0x00, 0x4c, 0xdb, 0x9f, 0xc0, 0x91, 0xba, 0x4d, 0x7b, 0x4b, + 0xfb, 0x48, 0xb9, 0xe1, 0xb8, 0xce, 0xff, 0xb4, 0xbd, 0x4b, 0xb0, 0xbd, + 0xb4, 0x97, 0x47, 0x24, 0xc7, 0x9c, 0x9c, 0xa5, 0xe7, 0x0b, 0x86, 0x4b, + 0xfb, 0xf7, 0x55, 0xf2, 0x32, 0x5f, 0x21, 0x87, 0xaa, 0xc3, 0x96, 0xb1, + 0xf6, 0x91, 0x36, 0x6d, 0x0e, 0xf6, 0x9c, 0xb9, 0x5a, 0x5c, 0xab, 0xb2, + 0x5f, 0x22, 0x15, 0xb7, 0xf0, 0xce, 0x3b, 0x3a, 0x55, 0x82, 0xfe, 0x51, + 0x9f, 0x20, 0xf7, 0x17, 0xe8, 0x5b, 0x0c, 0xa9, 0x8e, 0x64, 0x7f, 0xc0, + 0xb5, 0xf7, 0xbc, 0x33, 0x2e, 0xd4, 0xb0, 0xd3, 0xec, 0x01, 0xf2, 0x80, + 0x8f, 0x63, 0x5d, 0xa6, 0xdc, 0x9b, 0xb4, 0xdd, 0x7f, 0xb7, 0x9c, 0xe1, + 0xd4, 0xc5, 0x10, 0xf7, 0x36, 0xda, 0xeb, 0x61, 0xa9, 0x46, 0xf9, 0xfe, + 0x58, 0xaf, 0x10, 0xf7, 0xce, 0x7e, 0xeb, 0xd0, 0xbc, 0x06, 0x59, 0xac, + 0x01, 0xd7, 0x32, 0x58, 0x03, 0xfe, 0x9f, 0x80, 0xbc, 0xe8, 0x33, 0x10, + 0x87, 0xf1, 0x7f, 0xcb, 0x3c, 0x9b, 0x75, 0x99, 0xbb, 0x73, 0xe6, 0x7c, + 0x29, 0xd3, 0xd7, 0x25, 0xa7, 0xf2, 0x5d, 0x92, 0x5c, 0xe5, 0x75, 0x99, + 0xac, 0x2c, 0xc9, 0x03, 0xce, 0x38, 0xde, 0xf7, 0x86, 0x37, 0xeb, 0xa8, + 0xaf, 0x32, 0x3a, 0x83, 0x67, 0xcf, 0x8e, 0xf4, 0xc9, 0x9f, 0x5d, 0x47, + 0x16, 0xd7, 0x6c, 0xc9, 0xdb, 0x69, 0x79, 0x5e, 0x63, 0xf9, 0xf4, 0x4f, + 0x42, 0xe0, 0xa4, 0xcc, 0xc9, 0xb7, 0x89, 0xf4, 0x38, 0xb1, 0x6d, 0x21, + 0xa7, 0x6c, 0x81, 0xac, 0xe3, 0x86, 0x37, 0xdb, 0xe6, 0xfa, 0xb1, 0x17, + 0xc0, 0xdd, 0xdd, 0xb7, 0x7a, 0x83, 0xf8, 0xb0, 0xe1, 0xb7, 0x7f, 0xf0, + 0xf3, 0x62, 0x69, 0xa9, 0x30, 0x07, 0xa7, 0x38, 0xeb, 0x40, 0x97, 0x98, + 0xc3, 0x8f, 0x69, 0xdc, 0xa1, 0xa5, 0x4c, 0x8c, 0xba, 0x0a, 0x8c, 0x1a, + 0x25, 0x76, 0x8d, 0xaf, 0xb9, 0x8c, 0x0b, 0x44, 0xe5, 0xb7, 0x25, 0xe2, + 0x70, 0x5c, 0x7e, 0x53, 0x7a, 0x16, 0xf3, 0x49, 0x54, 0x19, 0xcf, 0xbc, + 0x5e, 0x29, 0x90, 0x27, 0x29, 0x9f, 0xcf, 0xba, 0x5f, 0x54, 0x3b, 0x10, + 0xb7, 0x8a, 0xdd, 0x2d, 0x8a, 0x37, 0x4f, 0x6b, 0x1e, 0x36, 0x6e, 0x0d, + 0xc8, 0xf5, 0x55, 0xbe, 0x6f, 0x0a, 0x63, 0x47, 0x43, 0xb9, 0x75, 0xda, + 0xa5, 0x64, 0x6c, 0xc6, 0x3a, 0x20, 0x17, 0xa2, 0x8c, 0x53, 0x8f, 0x11, + 0x9f, 0x61, 0x0b, 0x87, 0xed, 0x19, 0xd6, 0x38, 0xa9, 0xfd, 0x89, 0x35, + 0xe1, 0xec, 0xd3, 0x3e, 0xce, 0xf2, 0xda, 0x18, 0x64, 0x4a, 0x5b, 0x94, + 0xa8, 0x4c, 0x58, 0x49, 0xd8, 0x3c, 0xfc, 0xdf, 0xe0, 0xf8, 0x71, 0xf9, + 0xc2, 0xc6, 0x45, 0xf0, 0xef, 0x61, 0xfb, 0x1c, 0xed, 0xaa, 0x3d, 0x8a, + 0x7b, 0xf9, 0xfc, 0x0f, 0x34, 0x8d, 0xf5, 0x69, 0x7f, 0x2c, 0x5e, 0xc7, + 0x3e, 0x2f, 0x3b, 0x32, 0x5b, 0x62, 0x2e, 0xda, 0xcc, 0x75, 0xef, 0xbd, + 0x67, 0x77, 0x9e, 0xbb, 0xb0, 0x4c, 0x7e, 0x63, 0xea, 0xdc, 0x8a, 0xe0, + 0x42, 0x9f, 0xec, 0xe2, 0x33, 0xf9, 0xbc, 0xc3, 0x92, 0x7d, 0x04, 0xf8, + 0x52, 0xe6, 0xaf, 0xe0, 0xd7, 0xde, 0xc2, 0x5f, 0x89, 0xf6, 0xef, 0x63, + 0x9b, 0xee, 0xf3, 0xc7, 0xfb, 0x3d, 0x74, 0x28, 0xda, 0x70, 0x3f, 0x63, + 0x2a, 0x6c, 0xc7, 0xa5, 0xb0, 0xc1, 0xa3, 0xe7, 0x75, 0x39, 0xad, 0x72, + 0xce, 0xbe, 0xbd, 0x69, 0x8c, 0x13, 0x38, 0x67, 0x38, 0x41, 0xb8, 0x1c, + 0xf2, 0xb9, 0xc5, 0x9d, 0xe4, 0x4d, 0xfe, 0xff, 0x36, 0x8d, 0xc5, 0xc4, + 0xad, 0xfe, 0xa6, 0xf7, 0xb8, 0x73, 0xc7, 0x0e, 0xc7, 0x2d, 0x62, 0xe7, + 0x8f, 0x71, 0x8d, 0x3a, 0xe4, 0x29, 0x8f, 0x8f, 0x80, 0xe7, 0xe7, 0x80, + 0x05, 0x51, 0xe7, 0xb6, 0x18, 0x8b, 0x4d, 0xae, 0x2d, 0x9b, 0x7a, 0x54, + 0x72, 0xe0, 0x6b, 0xfb, 0xe6, 0x6a, 0x53, 0xd0, 0x65, 0x8c, 0x7f, 0x90, + 0xe3, 0x8f, 0xf8, 0xeb, 0x9c, 0x70, 0x0b, 0xd6, 0x87, 0x65, 0x66, 0xd5, + 0xe8, 0x5f, 0xd6, 0x81, 0xee, 0x1d, 0x46, 0x7b, 0x9d, 0x36, 0xe1, 0xfd, + 0xc6, 0x09, 0x6c, 0x43, 0x4a, 0x6d, 0xc3, 0xfc, 0x32, 0xf5, 0x93, 0x7a, + 0x19, 0xe8, 0x63, 0x80, 0x79, 0xd4, 0x51, 0xe2, 0x6c, 0x5a, 0x5e, 0x58, + 0xe6, 0xda, 0x64, 0x34, 0xa7, 0x35, 0xb4, 0x32, 0xab, 0xf5, 0x3d, 0x83, + 0xe5, 0xc4, 0x8b, 0x05, 0x19, 0x97, 0xab, 0x2e, 0xd7, 0x2c, 0x51, 0xcd, + 0x87, 0x3b, 0x1a, 0xde, 0xff, 0x9c, 0xbf, 0x66, 0x29, 0xd5, 0xab, 0xc1, + 0xf2, 0xe5, 0x1d, 0x79, 0xe7, 0xad, 0xc3, 0x4d, 0xeb, 0x14, 0x70, 0xb8, + 0xb8, 0x90, 0x3f, 0x44, 0xba, 0xd8, 0x87, 0xcf, 0x25, 0xe7, 0xe3, 0xb3, + 0x68, 0x5b, 0xef, 0x60, 0x3d, 0x83, 0xd0, 0x8f, 0x8b, 0x3c, 0x62, 0xb8, + 0x45, 0xde, 0x7a, 0x18, 0xeb, 0x76, 0x50, 0xeb, 0x28, 0xe7, 0xbf, 0xfb, + 0x1e, 0xfa, 0xe7, 0x7d, 0x7e, 0x9e, 0xc6, 0x78, 0x7c, 0x77, 0xee, 0xa9, + 0xd2, 0x49, 0xea, 0xe6, 0xa4, 0xe6, 0x03, 0xd9, 0x87, 0xfb, 0x96, 0x6b, + 0x44, 0x39, 0x5c, 0x8e, 0x19, 0x7b, 0x7a, 0xa2, 0x69, 0x3e, 0x49, 0x7f, + 0x3e, 0xc1, 0xf5, 0x16, 0x89, 0xf4, 0xa6, 0xb4, 0x96, 0x24, 0x59, 0xa6, + 0x8f, 0x02, 0x5b, 0x35, 0xcd, 0xb1, 0x6e, 0x8d, 0xbd, 0xf9, 0xff, 0x13, + 0x7b, 0xf3, 0x56, 0x49, 0xe7, 0xd8, 0xe2, 0xfc, 0x2f, 0x72, 0x6c, 0xac, + 0xa7, 0x37, 0x72, 0x7b, 0x6e, 0x99, 0xf6, 0x29, 0xa3, 0xb1, 0xe3, 0x3f, + 0x95, 0xb8, 0x96, 0x9c, 0xe3, 0x55, 0xce, 0x71, 0xbc, 0xae, 0xb5, 0x74, + 0x0f, 0xe9, 0x9e, 0x5d, 0x5c, 0x26, 0xa6, 0x74, 0xc8, 0x5a, 0x25, 0xc0, + 0x95, 0x07, 0x7c, 0x4e, 0x5b, 0xec, 0x6e, 0xc5, 0x3e, 0x39, 0xe3, 0x5a, + 0x5a, 0x47, 0x68, 0x3d, 0xcc, 0x73, 0x03, 0x52, 0x5b, 0xa5, 0x9d, 0x4d, + 0xc2, 0xaf, 0x88, 0x86, 0x6a, 0xeb, 0xcc, 0x45, 0xb2, 0x4e, 0x64, 0x5c, + 0x98, 0xbb, 0xcf, 0xd9, 0xf3, 0xd8, 0x5f, 0x31, 0xf8, 0xfd, 0xe4, 0xf0, + 0x8c, 0x8f, 0x35, 0xcb, 0x7b, 0x74, 0x87, 0x03, 0xee, 0x95, 0xf3, 0x2f, + 0xb0, 0xde, 0xd4, 0x6b, 0xc7, 0xbe, 0x0e, 0x3b, 0x99, 0x8b, 0xf2, 0xff, + 0x0c, 0xb8, 0x3f, 0x7d, 0x8d, 0xb8, 0xfa, 0x1a, 0xb5, 0x6a, 0x46, 0x96, + 0x54, 0xf7, 0x3b, 0xfc, 0x58, 0x52, 0x87, 0xea, 0x07, 0x75, 0x2c, 0xaf, + 0x9c, 0x7b, 0x54, 0x71, 0xaa, 0x58, 0x1a, 0x36, 0x75, 0x26, 0x76, 0xcc, + 0xaf, 0x27, 0x6f, 0x7c, 0x7e, 0xcc, 0x7f, 0xfe, 0x5f, 0x7c, 0xf9, 0xda, + 0x8a, 0x31, 0xba, 0xd6, 0x56, 0x52, 0x7d, 0xcb, 0xf9, 0x65, 0xea, 0x07, + 0xf5, 0x84, 0x38, 0x17, 0xdc, 0x17, 0xc8, 0x24, 0x68, 0xf3, 0x7e, 0xea, + 0x7c, 0x63, 0x4d, 0x41, 0xb0, 0x3f, 0x83, 0x73, 0x81, 0x8c, 0x78, 0xad, + 0xd1, 0x0e, 0x70, 0xaf, 0xc5, 0x21, 0xa7, 0xdd, 0xfd, 0xd6, 0x55, 0xde, + 0x95, 0x4d, 0xf6, 0x14, 0xe7, 0x7f, 0x99, 0x71, 0x5c, 0xec, 0xb1, 0xfd, + 0xe4, 0xf3, 0x65, 0x95, 0x4f, 0x1e, 0xf2, 0xe9, 0x52, 0xdc, 0xa7, 0x8f, + 0x77, 0xc9, 0xd7, 0xb9, 0x0e, 0xac, 0x19, 0xe3, 0xb2, 0xc0, 0xb7, 0xf3, + 0xc4, 0xf9, 0xbe, 0x3e, 0xe2, 0x0b, 0x63, 0x8a, 0x99, 0xe9, 0x43, 0xc0, + 0x30, 0xb6, 0x8f, 0x2b, 0x07, 0x31, 0x3e, 0x56, 0x5c, 0x63, 0x8b, 0x61, + 0x60, 0x72, 0xad, 0x04, 0x7e, 0xc6, 0xba, 0xaf, 0x3d, 0xf2, 0x7a, 0xca, + 0x5f, 0xaf, 0x89, 0x3e, 0xca, 0x87, 0xfb, 0x80, 0x58, 0xd9, 0x89, 0xf1, + 0xce, 0x46, 0x53, 0xd0, 0xb1, 0x71, 0x9c, 0x1f, 0x52, 0x1f, 0x22, 0x8c, + 0x7d, 0xbe, 0x5d, 0xea, 0xf5, 0xfd, 0x36, 0x07, 0x6d, 0xf8, 0xaa, 0xa5, + 0x2e, 0xfa, 0x11, 0x1a, 0x47, 0x6c, 0x2d, 0xc3, 0x67, 0x05, 0x76, 0xd7, + 0xd5, 0x06, 0x8d, 0xe0, 0xfa, 0x6d, 0xac, 0x89, 0xd3, 0xda, 0xe0, 0x6d, + 0x95, 0x19, 0x7d, 0xcd, 0x63, 0xba, 0xa6, 0xb5, 0x52, 0x22, 0xf6, 0xb8, + 0xf8, 0xe7, 0xa6, 0xf9, 0xdc, 0xc1, 0x86, 0x79, 0x4d, 0xca, 0xd9, 0x1d, + 0x1b, 0x41, 0xdf, 0x19, 0xbc, 0xbd, 0x62, 0x6c, 0x40, 0xb1, 0x9a, 0xd2, + 0xfa, 0xa5, 0xf0, 0xd8, 0x06, 0xd6, 0x92, 0x3c, 0xf4, 0x06, 0xb8, 0xf7, + 0x08, 0xd6, 0x90, 0x5c, 0xdb, 0x9b, 0x5b, 0x70, 0x33, 0xcc, 0x85, 0xc1, + 0x86, 0xcd, 0x49, 0x0e, 0xbe, 0x40, 0x2e, 0x7c, 0x98, 0x31, 0x64, 0xf0, + 0xc1, 0x82, 0x1f, 0x6f, 0x1c, 0x61, 0x9c, 0x54, 0x56, 0xd6, 0x39, 0x77, + 0xee, 0x6f, 0xe3, 0x6f, 0xd7, 0x4a, 0x9c, 0xaf, 0x89, 0x3d, 0xb0, 0x6d, + 0x95, 0x5d, 0x1c, 0xb9, 0x16, 0x69, 0x1c, 0xef, 0xc5, 0x9e, 0xe0, 0xbd, + 0x38, 0xae, 0xdf, 0x90, 0x5f, 0xad, 0x06, 0xf6, 0x3c, 0x24, 0x6f, 0x3a, + 0xde, 0xdc, 0xbc, 0xdb, 0xcd, 0x35, 0x70, 0x0b, 0xcc, 0x65, 0x3b, 0x8e, + 0x5b, 0x14, 0xcf, 0xab, 0xbb, 0xf5, 0x6e, 0x4b, 0x65, 0x49, 0x0c, 0xf8, + 0x1a, 0xd6, 0xf0, 0x8d, 0xbb, 0x2d, 0x31, 0xf2, 0xa3, 0x6c, 0xae, 0xfd, + 0x57, 0xfc, 0x0f, 0x30, 0x90, 0xfa, 0x48, 0xbd, 0xbc, 0x21, 0x53, 0x8a, + 0xf9, 0xfb, 0xf5, 0x6b, 0xc4, 0x89, 0x80, 0xd3, 0x12, 0xd3, 0xa9, 0x8b, + 0x31, 0xf5, 0x09, 0x8e, 0x95, 0x9b, 0x71, 0xe1, 0x33, 0x7e, 0x0e, 0x61, + 0x3f, 0xdd, 0x7b, 0xd4, 0xc7, 0x86, 0x31, 0xe5, 0xcb, 0x19, 0x9b, 0x18, + 0xc1, 0xf9, 0x1c, 0x94, 0xd9, 0x2b, 0x8d, 0x38, 0x4c, 0x5f, 0xcf, 0xe0, + 0x87, 0x7e, 0xe3, 0xa1, 0xfc, 0xd7, 0x92, 0xc1, 0x15, 0xf2, 0x25, 0x07, + 0x58, 0xda, 0x23, 0xf9, 0xe9, 0xb0, 0x24, 0x57, 0x7e, 0xd6, 0x67, 0xf8, + 0x2d, 0xf5, 0x0f, 0xfb, 0x4d, 0xcf, 0xb1, 0x5d, 0xc7, 0xf9, 0x23, 0xc2, + 0x67, 0x1b, 0x7d, 0xc6, 0x7e, 0x3e, 0x1f, 0x5c, 0xb3, 0x9b, 0x74, 0xf4, + 0x5e, 0x5f, 0x47, 0x79, 0xdd, 0x32, 0xb9, 0x0e, 0xdc, 0x3b, 0xb8, 0xc2, + 0x39, 0x9a, 0x7e, 0x83, 0x2b, 0xc6, 0x47, 0xdf, 0xdb, 0x6f, 0x64, 0xa7, + 0x1f, 0xae, 0x83, 0xef, 0x9a, 0xb1, 0xa7, 0x46, 0xc1, 0xe3, 0x46, 0x58, + 0x83, 0x44, 0x9b, 0x3d, 0xe4, 0x4e, 0x09, 0xf5, 0x3d, 0xe1, 0xeb, 0x1c, + 0xf1, 0xa6, 0xcb, 0xc7, 0x9b, 0x5d, 0x1b, 0x93, 0x33, 0x35, 0x27, 0x8c, + 0x83, 0x34, 0xd8, 0x18, 0xe9, 0xff, 0x4f, 0x1b, 0x73, 0xc4, 0x1f, 0x27, + 0xb8, 0x16, 0xe0, 0x4a, 0xd0, 0x0e, 0x70, 0xa5, 0x99, 0xc7, 0x06, 0xb2, + 0x6f, 0x3c, 0xdf, 0xe8, 0xe7, 0x65, 0x7c, 0x7f, 0xde, 0xd2, 0xfd, 0xf3, + 0xca, 0x8e, 0x1f, 0x4f, 0x19, 0x27, 0xa0, 0x7a, 0x25, 0xec, 0xed, 0xf7, + 0xd4, 0x6f, 0x5e, 0xbc, 0x32, 0xa1, 0xb1, 0x9c, 0x9a, 0xca, 0xfa, 0xab, + 0x58, 0x9f, 0x33, 0xd8, 0x47, 0x0f, 0x46, 0x77, 0xeb, 0x86, 0x56, 0x9f, + 0xc9, 0xfa, 0xbc, 0x25, 0x23, 0x5d, 0x98, 0x5f, 0x5a, 0xeb, 0xb0, 0xda, + 0x9d, 0xaf, 0xc8, 0x03, 0x66, 0xee, 0x6d, 0x6d, 0x63, 0xeb, 0xcf, 0xb4, + 0x7d, 0x2b, 0xd0, 0x73, 0xea, 0xcf, 0xea, 0x33, 0xb3, 0x15, 0x6f, 0x3c, + 0x72, 0x72, 0xd8, 0x2e, 0x0a, 0x6b, 0xbd, 0xc7, 0xe5, 0x09, 0x97, 0xd7, + 0x7f, 0x88, 0xeb, 0xd3, 0xf4, 0x21, 0x13, 0x11, 0xfd, 0xfe, 0x20, 0x11, + 0x7b, 0x0c, 0x7b, 0x6f, 0x46, 0xbf, 0xf7, 0x38, 0xa4, 0x35, 0xe2, 0x35, + 0x21, 0x97, 0x62, 0x8d, 0xc1, 0xb3, 0xf2, 0xb8, 0x3b, 0xe4, 0xd6, 0xc5, + 0x70, 0xdc, 0x19, 0xcd, 0xf7, 0x1c, 0x90, 0xc7, 0xdc, 0x48, 0x5b, 0x76, + 0xcb, 0xe8, 0xfc, 0x44, 0x38, 0xd3, 0xbe, 0xe0, 0x44, 0xdb, 0xa6, 0xb6, + 0xb0, 0xa7, 0xb7, 0x80, 0xf7, 0x5b, 0xb1, 0x50, 0x6e, 0x83, 0xef, 0x1e, + 0x36, 0x35, 0x1d, 0xea, 0x5f, 0x11, 0x43, 0xee, 0x93, 0x6d, 0xfb, 0xb8, + 0x6c, 0xa7, 0xf8, 0x4d, 0xd6, 0x29, 0xb4, 0x07, 0x35, 0xe7, 0xb2, 0x0d, + 0xbc, 0xd9, 0x4e, 0xb5, 0xa9, 0x0e, 0xaa, 0x1f, 0x06, 0x9c, 0xda, 0xb6, + 0x89, 0x4f, 0x77, 0xf0, 0x88, 0x77, 0x9e, 0x83, 0x1c, 0x58, 0xef, 0x71, + 0x02, 0x6d, 0xe2, 0x9a, 0xdd, 0x74, 0xbe, 0x1f, 0xed, 0xbb, 0x31, 0x46, + 0xab, 0xbe, 0xa3, 0xe5, 0x9c, 0x34, 0x79, 0xcc, 0x3d, 0xf7, 0x74, 0x36, + 0xb5, 0x3f, 0x77, 0xd4, 0x7c, 0x6f, 0xf4, 0x3d, 0xca, 0xb8, 0x90, 0x91, + 0xbf, 0xc5, 0xf6, 0xb6, 0x97, 0xfb, 0xf6, 0xb6, 0x0f, 0x4b, 0x7b, 0x0f, + 0x45, 0xd1, 0xdd, 0x74, 0x5f, 0xa0, 0x43, 0x41, 0xfb, 0x28, 0x71, 0x85, + 0x76, 0x4b, 0x7d, 0xa6, 0xed, 0x28, 0x9f, 0xb5, 0xd8, 0xd4, 0x87, 0xff, + 0xd9, 0x87, 0x7d, 0x19, 0xbf, 0xfb, 0xbe, 0xd1, 0x33, 0x8b, 0xbe, 0x3f, + 0xe3, 0x17, 0xd4, 0xd3, 0xfd, 0xfc, 0xa9, 0x84, 0x7e, 0x1f, 0xb4, 0xbf, + 0xae, 0x05, 0x38, 0x12, 0xf3, 0x63, 0x0a, 0x26, 0xef, 0x64, 0xe2, 0xbe, + 0x94, 0x9d, 0xe6, 0x9d, 0x62, 0xd7, 0x21, 0xe7, 0x0b, 0x90, 0xf3, 0x64, + 0x98, 0xbe, 0x1f, 0xf3, 0x4b, 0x8e, 0xe4, 0xb6, 0x28, 0x6f, 0xda, 0x75, + 0xea, 0x26, 0x78, 0xc4, 0x16, 0x31, 0xc5, 0x02, 0x07, 0xca, 0x60, 0x8e, + 0xaf, 0xe1, 0xbc, 0xe5, 0xd7, 0x6f, 0xa4, 0x61, 0xd3, 0x5c, 0xfc, 0x28, + 0x77, 0xf8, 0xf4, 0x6b, 0x94, 0x31, 0xeb, 0xd9, 0x18, 0x0b, 0xe0, 0xfc, + 0x98, 0x63, 0x77, 0xa1, 0xd3, 0x13, 0xd0, 0xdd, 0x88, 0x38, 0xe5, 0x13, + 0x52, 0x98, 0x9e, 0x50, 0xfb, 0x3f, 0x08, 0xfb, 0x34, 0xef, 0x66, 0x65, + 0xe1, 0xe5, 0x3b, 0xb1, 0x4f, 0xe9, 0xe7, 0x6b, 0x0c, 0xc3, 0x6b, 0x51, + 0x9d, 0x26, 0xe7, 0x60, 0xdc, 0xcd, 0xe4, 0x92, 0xfd, 0xef, 0xaa, 0xfa, + 0xe5, 0x70, 0x56, 0x2a, 0x57, 0x6c, 0xad, 0x85, 0xc9, 0xc8, 0x7b, 0x1e, + 0x65, 0x38, 0x73, 0x3e, 0x0e, 0x9c, 0x22, 0x77, 0xff, 0x60, 0xd4, 0xac, + 0xe9, 0x5f, 0xfb, 0xe9, 0x03, 0x27, 0xcb, 0x8d, 0x63, 0x68, 0xfd, 0x0c, + 0xae, 0x3d, 0x74, 0xd4, 0xec, 0x1f, 0xfa, 0xc3, 0x37, 0xbd, 0x4c, 0x94, + 0xcf, 0xe4, 0xbd, 0xcc, 0xd1, 0x52, 0x57, 0x38, 0xb7, 0x77, 0x7d, 0xbd, + 0xfe, 0x28, 0xc6, 0x8b, 0xcb, 0xe0, 0xe6, 0x84, 0xfa, 0xf1, 0xf3, 0x7b, + 0x7c, 0x56, 0x13, 0x1f, 0x30, 0x7e, 0xeb, 0x1b, 0xf2, 0xd8, 0x06, 0xe5, + 0x44, 0xfb, 0x1e, 0x92, 0x1f, 0x39, 0xc3, 0xf6, 0x93, 0x5a, 0x77, 0x9c, + 0xc8, 0x30, 0x1f, 0x73, 0xd0, 0x49, 0xda, 0x6b, 0x12, 0x19, 0xfd, 0x98, + 0xf0, 0x9b, 0x16, 0xd6, 0x7a, 0x0c, 0xbb, 0x4f, 0x4a, 0x50, 0xef, 0x31, + 0x94, 0x39, 0x10, 0xfa, 0xa7, 0xf7, 0xc6, 0x79, 0xde, 0x63, 0xea, 0x3d, + 0x24, 0x44, 0xb9, 0xfd, 0xf1, 0x0e, 0x7e, 0xe3, 0xb9, 0x37, 0xde, 0x77, + 0xff, 0xd3, 0xe7, 0xd2, 0x89, 0x25, 0xfa, 0xac, 0x2d, 0xce, 0xbf, 0xfa, + 0xcd, 0xbb, 0x16, 0x0a, 0x9d, 0xa2, 0xf9, 0xb2, 0x4b, 0xef, 0x38, 0xac, + 0x7b, 0x48, 0xc4, 0x0e, 0x58, 0x8c, 0x7b, 0x13, 0xdf, 0x98, 0x43, 0x61, + 0x8c, 0x0d, 0x6d, 0x70, 0x86, 0x97, 0x46, 0x2c, 0xb9, 0x3f, 0x92, 0x89, + 0x5b, 0x72, 0x2c, 0xbe, 0x22, 0x78, 0x26, 0xf3, 0x29, 0x1b, 0x89, 0x02, + 0xef, 0x8f, 0x94, 0x39, 0x5e, 0x5c, 0xfd, 0x93, 0xe4, 0x31, 0xcf, 0xbb, + 0xe4, 0x4a, 0x28, 0x79, 0xd7, 0xdb, 0x1e, 0x73, 0xde, 0xd6, 0xe6, 0xfb, + 0xd5, 0x23, 0x10, 0x37, 0x16, 0x9e, 0x32, 0xb5, 0x87, 0x4b, 0x97, 0x06, + 0x37, 0xf4, 0x9b, 0xb9, 0x69, 0xd3, 0x2e, 0xa1, 0xdd, 0xea, 0xd7, 0x41, + 0x55, 0x2e, 0x0d, 0x56, 0x8f, 0xdc, 0x6e, 0xfc, 0x6d, 0xf2, 0xab, 0xc0, + 0x87, 0x89, 0xef, 0xa9, 0x0b, 0x3b, 0xbb, 0x7c, 0x26, 0x74, 0x66, 0xd9, + 0x5a, 0x6d, 0x63, 0x0e, 0xec, 0x94, 0x27, 0xdd, 0x27, 0x83, 0x38, 0x15, + 0xe3, 0x5a, 0x22, 0x9d, 0x9b, 0x13, 0x26, 0xe7, 0xb1, 0x69, 0x29, 0x17, + 0xea, 0x7a, 0x89, 0xb1, 0xaa, 0xa8, 0x62, 0x43, 0xf7, 0x26, 0xeb, 0xc1, + 0x7a, 0x64, 0x46, 0x31, 0xa3, 0x47, 0xf1, 0xc0, 0xe8, 0x5d, 0x97, 0xc6, + 0x61, 0xc9, 0x97, 0xae, 0x2d, 0xbb, 0x03, 0xac, 0xe1, 0x79, 0x75, 0xf9, + 0x09, 0xb4, 0x89, 0x33, 0xf7, 0x34, 0x9d, 0x6f, 0xcc, 0xc9, 0x26, 0xec, + 0x41, 0xab, 0x39, 0x1f, 0xcb, 0x73, 0xcd, 0x79, 0xd8, 0x57, 0x25, 0xdf, + 0xcb, 0xdc, 0x6b, 0x10, 0x6f, 0x77, 0xfd, 0x78, 0xfb, 0x87, 0x06, 0xa8, + 0x83, 0xf0, 0x6f, 0xf2, 0x91, 0xb1, 0xb6, 0x91, 0xf9, 0x52, 0xf8, 0x1f, + 0xbb, 0xb1, 0x53, 0xb4, 0x37, 0x76, 0xf2, 0xe3, 0xb8, 0xf6, 0x25, 0x70, + 0x92, 0x22, 0xf8, 0x45, 0xc1, 0xaf, 0xc3, 0xe7, 0xf5, 0x9d, 0xfe, 0xb7, + 0x98, 0xd3, 0x41, 0xcd, 0xad, 0x0f, 0xee, 0xc9, 0xad, 0xdf, 0x35, 0xc0, + 0xda, 0xe3, 0xe2, 0xd6, 0x6e, 0xdf, 0x88, 0xdf, 0x77, 0xe2, 0x96, 0xef, + 0x63, 0xf6, 0x4c, 0x51, 0xf7, 0xcc, 0x65, 0x8d, 0x11, 0xcf, 0x6f, 0x2d, + 0xc9, 0x8c, 0xd3, 0x25, 0xb9, 0xd5, 0xc0, 0x4e, 0x78, 0xe3, 0xb3, 0x6e, + 0xa1, 0x2f, 0x2c, 0xec, 0xcf, 0xe7, 0x29, 0x47, 0x8b, 0xe5, 0xc2, 0x1c, + 0xff, 0x90, 0x44, 0xc6, 0x68, 0x3b, 0x68, 0x13, 0x3e, 0x05, 0x2c, 0x03, + 0x4f, 0xdf, 0x6a, 0xcc, 0x7d, 0xbf, 0x9f, 0x1c, 0x29, 0xc3, 0xe0, 0x9d, + 0x0b, 0x5e, 0x2b, 0xf6, 0xdf, 0x31, 0xd6, 0xb4, 0xec, 0xcc, 0x95, 0x36, + 0x4b, 0x6d, 0x93, 0xbe, 0xc7, 0x94, 0xff, 0x1e, 0x61, 0xcc, 0x67, 0xb6, + 0x14, 0xdc, 0x33, 0x27, 0xc7, 0x4f, 0x25, 0x62, 0x49, 0x4b, 0xe7, 0xa5, + 0xf6, 0x2b, 0xeb, 0xce, 0xc1, 0x2e, 0xd1, 0x86, 0x29, 0xae, 0x81, 0xab, + 0x12, 0xd7, 0x68, 0x9f, 0xd4, 0xa6, 0xc5, 0x8b, 0x98, 0x67, 0x6e, 0x4b, + 0xf3, 0x0f, 0xb1, 0xd3, 0xe1, 0x44, 0x65, 0x46, 0xb1, 0x0e, 0x7c, 0x55, + 0xe7, 0x0e, 0x7b, 0x1c, 0x6a, 0xcc, 0x2d, 0xd1, 0xbf, 0x64, 0x1e, 0xa6, + 0x43, 0xb2, 0x15, 0x91, 0x57, 0xa0, 0xdf, 0x57, 0xd7, 0xb9, 0xe7, 0xc2, + 0xbd, 0xc6, 0x47, 0xac, 0xdf, 0x63, 0x49, 0xaf, 0xe6, 0x6b, 0x8b, 0x58, + 0x2f, 0xf0, 0xab, 0xf1, 0xf0, 0x29, 0xf8, 0x09, 0x5a, 0x27, 0xc1, 0x18, + 0xeb, 0x2c, 0x7c, 0xca, 0xc6, 0xb8, 0x10, 0x30, 0x62, 0x9a, 0xe7, 0x67, + 0xc0, 0x8b, 0x77, 0x73, 0x35, 0xc5, 0xea, 0x82, 0xc6, 0x63, 0x6b, 0xeb, + 0x1d, 0x6a, 0x2f, 0x6a, 0xd5, 0x3e, 0xac, 0x8b, 0x1c, 0xb7, 0xc6, 0x8a, + 0xfe, 0xf9, 0x16, 0xa9, 0x56, 0xd9, 0x96, 0x81, 0x56, 0xd5, 0x97, 0x20, + 0x1f, 0x65, 0xcb, 0x1a, 0xb8, 0x6e, 0x75, 0xc3, 0xc1, 0x2f, 0x85, 0xdf, + 0x08, 0x7e, 0x0f, 0x4a, 0xb6, 0x4c, 0xfe, 0xcd, 0xfc, 0x53, 0x47, 0xd3, + 0xf3, 0x5b, 0xf4, 0xfb, 0x11, 0xd6, 0xb4, 0x15, 0x7d, 0x3f, 0xad, 0x58, + 0xdd, 0x8f, 0x9b, 0x32, 0xbe, 0x9b, 0xf2, 0xb1, 0xee, 0xa7, 0x7e, 0x6d, + 0xed, 0xbf, 0x01, 0x17, 0x24, 0x5e, 0x9d, 0xe0, 0x70, 0x00, 0x00, 0x00 }; static const u32 bnx2_RXP_b06FwData[(0x0/4) + 1] = { 0x0 }; static const u32 bnx2_RXP_b06FwRodata[(0x24/4) + 1] = { - 0x0800458c, 0x0800458c, 0x08004504, 0x0800453c, 0x08004570, 0x08004594, - 0x08004594, 0x08004594, 0x08004474, 0x00000000 }; + 0x08004c28, 0x08004c28, 0x08004ba0, 0x08004bd8, 0x08004c0c, 0x08004c30, + 0x08004c30, 0x08004c30, 0x08004b10, 0x00000000 }; static struct fw_info bnx2_rxp_fw_06 = { - /* Firmware version: 4.4.2 */ + /* Firmware version: 4.6.16 */ .ver_major = 0x4, - .ver_minor = 0x4, - .ver_fix = 0x2, + .ver_minor = 0x6, + .ver_fix = 0x10, - .start_addr = 0x080031d0, + .start_addr = 0x080031d8, .text_addr = 0x08000000, - .text_len = 0x71cc, + .text_len = 0x70dc, .text_index = 0x0, .gz_text = bnx2_RXP_b06FwText, .gz_text_len = sizeof(bnx2_RXP_b06FwText), @@ -2966,15 +2935,15 @@ static struct fw_info bnx2_rxp_fw_06 = { .data_index = 0x0, .data = bnx2_RXP_b06FwData, - .sbss_addr = 0x08007220, - .sbss_len = 0x58, + .sbss_addr = 0x08007120, + .sbss_len = 0x54, .sbss_index = 0x0, - .bss_addr = 0x08007278, - .bss_len = 0x44c, + .bss_addr = 0x08007178, + .bss_len = 0x450, .bss_index = 0x0, - .rodata_addr = 0x080071cc, + .rodata_addr = 0x080070dc, .rodata_len = 0x24, .rodata_index = 0x0, .rodata = bnx2_RXP_b06FwRodata, @@ -2997,639 +2966,571 @@ static const struct cpu_reg cpu_reg_rxp = { }; static u8 bnx2_rv2p_proc1[] = { - /* Date: 05/13/2008 13:50 */ - 0xa5, 0x56, 0x4f, 0x48, 0x14, 0x61, 0x14, 0x7f, 0x3b, 0xfb, 0x67, 0xd6, - 0xdd, 0xd9, 0x9d, 0x25, 0xff, 0x6d, 0x66, 0xb8, 0x49, 0x97, 0xd5, 0x15, - 0xb5, 0x22, 0x3a, 0x18, 0x86, 0x17, 0x21, 0x3b, 0x84, 0x20, 0x45, 0x04, - 0xd9, 0x12, 0xde, 0x82, 0x0e, 0xd1, 0x29, 0x68, 0xd1, 0x34, 0x8a, 0x0a, - 0x16, 0x52, 0x30, 0xa2, 0xa4, 0x43, 0x85, 0x04, 0xed, 0x74, 0x0a, 0x12, - 0x82, 0x8a, 0x88, 0xea, 0x12, 0x78, 0xa8, 0x4b, 0x16, 0x61, 0xd0, 0xa1, - 0x83, 0x9d, 0xba, 0xe4, 0xf4, 0xbd, 0xef, 0xbd, 0xcf, 0x9d, 0xf9, 0x9c, - 0x55, 0x21, 0x41, 0x7f, 0xbc, 0x6f, 0xde, 0x7b, 0xdf, 0x9b, 0xdf, 0x7b, - 0xef, 0x37, 0x66, 0x00, 0xc0, 0x80, 0x92, 0xd3, 0x26, 0x10, 0x52, 0x46, - 0x28, 0x2e, 0x20, 0x04, 0xf0, 0x18, 0xe8, 0x27, 0x6a, 0x49, 0xbb, 0xd4, - 0xcd, 0x76, 0x27, 0x41, 0xa9, 0x33, 0x23, 0xfe, 0x9e, 0x85, 0xfe, 0x1c, - 0x62, 0x18, 0xfa, 0x77, 0x21, 0x1e, 0x84, 0x17, 0xb9, 0xac, 0xc0, 0xbf, - 0x2e, 0x94, 0xd0, 0x6e, 0xa8, 0x3c, 0x73, 0x92, 0x32, 0xff, 0x12, 0xc7, - 0x7f, 0x0a, 0x13, 0x1e, 0x28, 0xc4, 0x29, 0x0f, 0x23, 0x74, 0x65, 0x24, - 0x2c, 0x96, 0xd1, 0x1e, 0x19, 0x81, 0x18, 0xe6, 0x99, 0x12, 0x0e, 0x68, - 0xb7, 0x86, 0x4a, 0x5d, 0x5c, 0x97, 0x41, 0x7e, 0x5f, 0xca, 0x36, 0x9e, - 0xc3, 0xd7, 0x01, 0xb4, 0xb7, 0x27, 0x2e, 0x97, 0x11, 0xb3, 0x30, 0x16, - 0xb7, 0xe8, 0x7d, 0xda, 0x28, 0xed, 0x52, 0x07, 0xc6, 0x09, 0xdf, 0x0e, - 0xce, 0x1b, 0xc5, 0xbc, 0x3f, 0x5d, 0xca, 0x8b, 0xf9, 0xbc, 0x79, 0x5a, - 0x45, 0x1e, 0x3c, 0x8f, 0x71, 0x5d, 0x31, 0xad, 0xae, 0x98, 0xa8, 0x83, - 0x79, 0x00, 0x55, 0x07, 0x62, 0xa3, 0xb8, 0x17, 0xf3, 0xae, 0xf0, 0x7b, - 0x03, 0x9c, 0xca, 0x71, 0x7e, 0x07, 0xb1, 0xc2, 0xf9, 0xc4, 0x2f, 0xbf, - 0xc7, 0xfa, 0x3c, 0x8a, 0x27, 0x7f, 0xfd, 0x66, 0x41, 0x3d, 0x57, 0xfd, - 0xc0, 0x7b, 0x3e, 0x8a, 0x7b, 0xbc, 0xfe, 0xb0, 0x89, 0xff, 0x7b, 0xe1, - 0xef, 0xcf, 0x4b, 0xe7, 0x6f, 0xab, 0xe7, 0xf9, 0x20, 0xde, 0xa2, 0x1a, - 0x6f, 0x2f, 0x99, 0xb7, 0x41, 0xd8, 0x6d, 0x64, 0xa5, 0x5f, 0x04, 0x10, - 0x77, 0x88, 0x02, 0x10, 0x77, 0x32, 0x1e, 0x63, 0xbc, 0xc9, 0x78, 0x83, - 0xb1, 0x91, 0xb1, 0x81, 0xb1, 0x9e, 0x71, 0x1b, 0xe3, 0x3b, 0xc6, 0x0c, - 0xa3, 0xcd, 0x98, 0x66, 0x7c, 0xc3, 0x68, 0x31, 0x26, 0xb5, 0x7c, 0x2d, - 0x8c, 0x71, 0xc6, 0xbb, 0x8c, 0xfb, 0xb5, 0xf8, 0xdf, 0x8c, 0x0b, 0x8c, - 0xcd, 0x21, 0xc2, 0x43, 0x6c, 0x23, 0xa1, 0x3c, 0xf7, 0x3e, 0xbe, 0xee, - 0xaf, 0xf5, 0x77, 0xb1, 0xcc, 0xcf, 0xf3, 0xca, 0x2f, 0x2e, 0xf9, 0x83, - 0x0e, 0xaf, 0xff, 0x9d, 0x0d, 0xfc, 0xc9, 0x6d, 0x20, 0x1f, 0x14, 0x37, - 0xed, 0x52, 0x1d, 0xb7, 0x38, 0xbe, 0xbe, 0xb2, 0x50, 0x63, 0x8f, 0xfa, - 0x0a, 0xfa, 0x7c, 0x05, 0xed, 0xd1, 0x4e, 0xde, 0xa3, 0xa3, 0xeb, 0xe6, - 0x97, 0xe6, 0xd4, 0xbb, 0x87, 0x32, 0x4f, 0x8d, 0x39, 0x7f, 0x1a, 0x2a, - 0x16, 0xb2, 0x34, 0x17, 0xa5, 0x8d, 0xee, 0xc5, 0x78, 0x9e, 0xcb, 0xbc, - 0x9a, 0x4f, 0xff, 0x5c, 0xd2, 0x7c, 0xc5, 0xb4, 0xf9, 0xba, 0xb0, 0x09, - 0xbf, 0x49, 0x8d, 0xa7, 0x73, 0xae, 0xea, 0x97, 0xc1, 0xc7, 0xe3, 0xb1, - 0x8c, 0xcc, 0x7b, 0xcd, 0x91, 0x66, 0x83, 0x35, 0x85, 0x76, 0x04, 0xae, - 0x3b, 0x2a, 0x8e, 0xf7, 0xb2, 0x43, 0xdd, 0x43, 0xf1, 0x29, 0x20, 0x9e, - 0xe7, 0x34, 0x9e, 0x73, 0x5b, 0xd2, 0xa9, 0x15, 0xb7, 0xaa, 0x53, 0xf4, - 0xbc, 0x0d, 0xbc, 0x3a, 0x15, 0x87, 0xd1, 0x41, 0x5b, 0xde, 0x9b, 0x8e, - 0x51, 0x9a, 0xe3, 0x36, 0xe1, 0x99, 0x04, 0xe1, 0x72, 0xa2, 0x4e, 0xfc, - 0x75, 0xdd, 0xb1, 0x24, 0xd9, 0xa7, 0x53, 0x6a, 0x3f, 0x54, 0xbc, 0xaa, - 0x6b, 0xa3, 0x7a, 0xf0, 0x7e, 0x75, 0x8f, 0xaa, 0x43, 0xdd, 0xe7, 0xe7, - 0xbf, 0xf6, 0xbd, 0x84, 0x45, 0xc3, 0xcf, 0xc3, 0xed, 0x1e, 0xc2, 0x48, - 0xaf, 0x84, 0xec, 0x8c, 0x45, 0x71, 0xb3, 0x56, 0x04, 0xed, 0x7d, 0xb3, - 0x1f, 0x30, 0xbf, 0xb1, 0x67, 0xc6, 0xe1, 0xfa, 0x6c, 0xd5, 0x3f, 0x79, - 0x0e, 0xed, 0x40, 0xf6, 0x30, 0xcf, 0xc3, 0xb0, 0x9c, 0x7b, 0xb1, 0xd7, - 0x06, 0x62, 0x0b, 0x94, 0xa4, 0xae, 0x1b, 0x89, 0xd7, 0x32, 0x3e, 0xcc, - 0xe7, 0xa2, 0x4f, 0xed, 0xfe, 0x7d, 0x59, 0xa2, 0xfe, 0xc7, 0xfd, 0x73, - 0xd3, 0xed, 0x06, 0xcf, 0x63, 0xa2, 0x32, 0x57, 0x0e, 0xea, 0xd7, 0x73, - 0xd6, 0xbd, 0x2c, 0x14, 0x7b, 0x6b, 0xe9, 0xb1, 0xfa, 0x0e, 0x2a, 0x3d, - 0x92, 0xc7, 0x95, 0x52, 0xd8, 0xc7, 0xcb, 0x21, 0x28, 0x04, 0xe5, 0x7f, - 0xa2, 0xbe, 0x2f, 0x01, 0x7b, 0xb4, 0xd9, 0xbd, 0xbe, 0xfc, 0x69, 0x28, - 0x04, 0xed, 0x81, 0xa9, 0xed, 0x8d, 0xcd, 0x7b, 0xd3, 0xbc, 0x6e, 0x7e, - 0x95, 0x4e, 0xe4, 0x36, 0xd4, 0x89, 0xff, 0xd5, 0x05, 0x03, 0x48, 0x17, - 0x50, 0x8f, 0xfd, 0xf7, 0x9b, 0xaa, 0x7e, 0x6d, 0xff, 0xa9, 0xee, 0x3f, - 0xab, 0x5b, 0xd3, 0x11, 0xef, 0xfb, 0x07, 0xe9, 0x48, 0x42, 0xd3, 0x85, - 0x5f, 0xab, 0x55, 0x1d, 0xc1, 0xe7, 0xf3, 0xf3, 0xd4, 0x97, 0x8b, 0xee, - 0x9a, 0xae, 0xfb, 0xf8, 0xac, 0x63, 0x3e, 0x85, 0x9f, 0x8c, 0x5f, 0xd6, - 0xe2, 0x55, 0x5f, 0xcf, 0x33, 0xcf, 0x46, 0x1f, 0xcd, 0x95, 0x59, 0xfc, - 0xa1, 0xf1, 0xdd, 0x5b, 0xc0, 0xbd, 0xb8, 0x04, 0x0e, 0xf3, 0xf6, 0xd9, - 0xc7, 0x5f, 0x8a, 0xf5, 0xc1, 0x84, 0x47, 0x8e, 0xe2, 0x59, 0xf5, 0x87, - 0xf0, 0xa1, 0xf4, 0xcf, 0x6c, 0xc2, 0x77, 0x06, 0x1e, 0x38, 0x6a, 0xbf, - 0x6d, 0x99, 0xaf, 0x87, 0xf5, 0x64, 0x94, 0xf7, 0xfa, 0x5b, 0x82, 0x74, - 0xa3, 0x38, 0x24, 0xf7, 0x14, 0x9a, 0x78, 0xbf, 0x8b, 0x29, 0xb2, 0x5b, - 0x52, 0xf4, 0x7f, 0x5b, 0x8f, 0x69, 0x49, 0xbf, 0x96, 0x14, 0x61, 0x53, - 0x12, 0xe3, 0xb2, 0xf0, 0xfd, 0x88, 0x74, 0x2f, 0x54, 0xf7, 0x5b, 0xdf, - 0x6b, 0x7e, 0xdf, 0xbd, 0x78, 0xde, 0x24, 0xf6, 0xd4, 0xdb, 0x0f, 0x6b, - 0x4d, 0x5f, 0xef, 0x71, 0xf5, 0x39, 0xdb, 0xcb, 0xb7, 0x9a, 0xdb, 0x67, - 0x35, 0xfa, 0x34, 0xe8, 0x2a, 0xdd, 0x6b, 0x1f, 0xc4, 0x7a, 0x6d, 0x48, - 0x9b, 0x34, 0x1f, 0x84, 0x22, 0x8f, 0x61, 0x62, 0x58, 0xeb, 0x24, 0xeb, - 0xc4, 0xe4, 0xb8, 0x4c, 0x73, 0x64, 0x52, 0x9d, 0x0f, 0xc8, 0xc1, 0x1f, - 0x9e, 0x7f, 0x25, 0xcf, 0xd3, 0x4e, 0x98, 0xce, 0xcd, 0x21, 0xc5, 0x97, - 0x2d, 0xdf, 0x7f, 0x86, 0xf8, 0x3a, 0x39, 0x4d, 0x78, 0x02, 0x0e, 0x4b, - 0x4c, 0x54, 0xf5, 0x2d, 0x2e, 0x11, 0x52, 0x5e, 0x7d, 0x8b, 0x8a, 0xf2, - 0xd0, 0xae, 0xf3, 0xf4, 0x51, 0xff, 0x6e, 0x6c, 0xb5, 0x9f, 0x5e, 0x9d, - 0xc4, 0x7e, 0xea, 0x7a, 0x27, 0xe7, 0x46, 0x9b, 0xcf, 0x72, 0x8d, 0xf9, - 0xcc, 0xd5, 0x98, 0x6f, 0x5d, 0x2f, 0xae, 0xf2, 0xde, 0x45, 0x20, 0x1a, - 0x96, 0x1f, 0x24, 0x2b, 0x32, 0x21, 0xfb, 0x6b, 0x4c, 0xd2, 0x87, 0xd4, - 0x8a, 0x4e, 0x85, 0x24, 0x6f, 0xd6, 0x14, 0xf9, 0x45, 0xe8, 0x3c, 0xab, - 0xf0, 0xca, 0x84, 0xfa, 0xee, 0xfe, 0x03, 0x65, 0x6c, 0x9a, 0x59, 0x40, - 0x0c, 0x00, 0x00, 0x00 }; + /* Date: 02/03/2009 14:20 */ + 0xa5, 0x56, 0x4f, 0x68, 0x14, 0x67, 0x14, 0x7f, 0x33, 0xbb, 0xb3, 0xb3, + 0x99, 0x9d, 0xd9, 0xdd, 0x92, 0x18, 0x96, 0x18, 0xcc, 0x1a, 0x84, 0x92, + 0x75, 0xb7, 0x6e, 0x6c, 0x0f, 0x42, 0x03, 0x29, 0xb9, 0x08, 0x35, 0x87, + 0x12, 0x11, 0x8a, 0x2d, 0x68, 0xb7, 0x22, 0x14, 0x0a, 0xa5, 0x07, 0x8f, + 0xa5, 0x83, 0x71, 0x53, 0x5a, 0xbc, 0xe4, 0xd0, 0x80, 0x42, 0x35, 0x27, + 0x5b, 0x62, 0x0e, 0x3b, 0xe0, 0xa1, 0x88, 0xe0, 0x41, 0x8f, 0x7a, 0xaa, + 0x7f, 0x5a, 0x28, 0x46, 0x29, 0xb5, 0x87, 0x82, 0xc7, 0xde, 0x9a, 0xe9, + 0xf7, 0xfe, 0x7c, 0xbb, 0x33, 0x5f, 0x66, 0x13, 0xa1, 0x42, 0xfc, 0xf1, + 0xbd, 0x79, 0xef, 0xfb, 0xde, 0x9f, 0xdf, 0x7b, 0x6f, 0xab, 0x00, 0x60, + 0x43, 0x18, 0x4d, 0x29, 0x04, 0x2b, 0x67, 0x15, 0x11, 0x00, 0x36, 0x81, + 0xff, 0x39, 0x3e, 0x9d, 0xc3, 0x23, 0x72, 0x3e, 0xcc, 0x10, 0x1e, 0xae, + 0xaa, 0xff, 0x3f, 0x85, 0xf9, 0x3a, 0x62, 0x0e, 0xe6, 0x0f, 0x22, 0x1e, + 0x85, 0xbb, 0xf5, 0x9a, 0xc2, 0x7f, 0x63, 0x08, 0xf1, 0x1c, 0xf4, 0x7e, + 0x8e, 0x4a, 0x74, 0xff, 0x96, 0xd8, 0xff, 0x9a, 0x63, 0x3c, 0xd6, 0xac, + 0x12, 0x3e, 0x5a, 0xc5, 0xf7, 0x4e, 0x9d, 0x82, 0x02, 0xda, 0x5d, 0x50, + 0x17, 0x23, 0x96, 0xd4, 0x83, 0x45, 0xb2, 0x03, 0xbb, 0xa2, 0x70, 0x12, + 0x9e, 0x2f, 0xa0, 0xfe, 0x1b, 0xde, 0xa5, 0x55, 0xc4, 0x12, 0x74, 0x9a, + 0xa8, 0x77, 0x00, 0xb2, 0xf5, 0x6a, 0x4a, 0x0f, 0xe5, 0x11, 0x84, 0x4d, + 0xc4, 0x11, 0x80, 0x56, 0xf2, 0x3d, 0xd7, 0x0a, 0x5b, 0x68, 0xff, 0x85, + 0xbc, 0xb7, 0x4f, 0xee, 0x51, 0x71, 0x47, 0x88, 0x3d, 0xb1, 0x53, 0x7f, + 0x2d, 0x96, 0xb3, 0xfe, 0x67, 0x4a, 0x4f, 0xc7, 0xe3, 0x73, 0xde, 0xa6, + 0x38, 0x1e, 0x57, 0xe2, 0x79, 0xb6, 0xaa, 0xf3, 0x86, 0xfa, 0xbf, 0xc7, + 0x69, 0x7d, 0xd8, 0x43, 0xff, 0x89, 0xd2, 0x4f, 0xdf, 0xcb, 0xf2, 0x5f, + 0x06, 0xf2, 0x99, 0xf4, 0xf7, 0xad, 0x06, 0xfa, 0xe7, 0x00, 0x34, 0x24, + 0x8f, 0xa4, 0xff, 0x30, 0xe6, 0x78, 0xe6, 0xe0, 0x90, 0x5d, 0x23, 0xbd, + 0x3c, 0xd4, 0x28, 0x3f, 0x1c, 0xef, 0x01, 0xc1, 0x25, 0xc1, 0x6b, 0x82, + 0x3f, 0x08, 0xc2, 0xff, 0xc4, 0xad, 0x21, 0xf2, 0x7d, 0x82, 0xfb, 0x0d, + 0xf9, 0x2d, 0xc1, 0xb7, 0x0c, 0x7b, 0xcf, 0x62, 0x7c, 0xac, 0xbf, 0xcb, + 0xf9, 0x5d, 0xc3, 0xfe, 0x4b, 0xe0, 0xfc, 0x58, 0x46, 0xde, 0x36, 0x85, + 0x87, 0x58, 0x77, 0xf9, 0x3e, 0xa3, 0xf5, 0x84, 0x37, 0x8d, 0xa4, 0xfe, + 0x8d, 0x5d, 0xf4, 0x59, 0x6d, 0x61, 0x26, 0xcb, 0xee, 0x7a, 0x2c, 0x79, + 0x14, 0x7b, 0xaf, 0x77, 0x67, 0x08, 0xef, 0xe7, 0x32, 0x79, 0x3f, 0x2e, + 0x71, 0xa8, 0xa6, 0x23, 0xfb, 0xdb, 0x16, 0xf3, 0xdb, 0x11, 0x5e, 0xee, + 0xc6, 0x63, 0xe1, 0xd5, 0x8c, 0xe6, 0x57, 0x9a, 0x57, 0xcc, 0x8f, 0x82, + 0xc1, 0x8f, 0x6f, 0xf7, 0xc8, 0x4b, 0xc9, 0x88, 0x6f, 0x39, 0xd6, 0xf9, + 0xb6, 0x45, 0x7c, 0xb1, 0x50, 0xa5, 0x7b, 0xbf, 0x8b, 0xe8, 0x38, 0xe6, + 0xaf, 0xe0, 0x39, 0x0f, 0x97, 0x23, 0x6d, 0x27, 0xfd, 0xd4, 0xd0, 0xef, + 0xb0, 0x7d, 0x20, 0x9f, 0x6d, 0x47, 0xfb, 0xc9, 0x72, 0x0f, 0xf0, 0x3c, + 0xda, 0x5b, 0x37, 0xf2, 0x56, 0xa7, 0xb8, 0x41, 0xe2, 0x07, 0x23, 0x7e, + 0x9d, 0xbf, 0x57, 0xc2, 0xf7, 0x49, 0x95, 0x0f, 0xfe, 0x3e, 0x05, 0xfa, + 0x7e, 0x9c, 0x0b, 0x45, 0x38, 0x7b, 0xbc, 0x42, 0xfe, 0x94, 0x0b, 0x7c, + 0xcd, 0x87, 0x15, 0xc6, 0x73, 0x1e, 0xe3, 0x9f, 0x9e, 0xca, 0x2d, 0xc4, + 0xf1, 0xf9, 0x12, 0x9f, 0x3f, 0x09, 0xf0, 0xde, 0x51, 0xf5, 0xb0, 0xb6, + 0xd7, 0x7e, 0xed, 0xe6, 0x0f, 0xbe, 0xaf, 0xdf, 0xd1, 0x7e, 0xe8, 0xf7, + 0xd2, 0x75, 0x19, 0xfe, 0x2e, 0x63, 0xc7, 0x4e, 0xe7, 0x21, 0x3f, 0xcb, + 0x78, 0xb5, 0x4d, 0x50, 0x5b, 0xf3, 0xd9, 0xee, 0x8a, 0x9f, 0xc7, 0xf3, + 0x3b, 0x57, 0x1e, 0xe0, 0xfd, 0xf6, 0xd1, 0xb5, 0x48, 0xfc, 0xab, 0xe8, + 0xba, 0x92, 0x1c, 0xa6, 0x81, 0xcf, 0x4b, 0xc2, 0x93, 0x25, 0xe2, 0x71, + 0x59, 0x7d, 0x42, 0x9c, 0x80, 0xd0, 0x26, 0x3d, 0xef, 0x3e, 0xd9, 0xe7, + 0x44, 0xae, 0xea, 0x37, 0x9d, 0xe6, 0xff, 0x16, 0xf3, 0xa2, 0x98, 0xe6, + 0xd3, 0x7c, 0x62, 0xce, 0x25, 0xf3, 0x61, 0xf5, 0x79, 0xb4, 0xb3, 0x8e, + 0xe9, 0x7a, 0x3d, 0x5a, 0xd5, 0xf9, 0x61, 0xbe, 0xb2, 0x9e, 0x2a, 0x56, + 0x8b, 0xd5, 0xc3, 0xb6, 0x24, 0x72, 0x56, 0xbe, 0xb7, 0x4c, 0xde, 0x66, + 0xf1, 0xbe, 0x6a, 0xf0, 0xb8, 0x21, 0xbc, 0x1f, 0xe9, 0xad, 0xbf, 0xd6, + 0x7e, 0xb8, 0x29, 0xbc, 0xaf, 0x0e, 0xf6, 0xc3, 0x26, 0xed, 0x27, 0x75, + 0x26, 0xf5, 0x5e, 0x98, 0x4b, 0xd5, 0xe9, 0x3d, 0xc8, 0xec, 0xef, 0xab, + 0x72, 0x4f, 0x5b, 0xfa, 0xbc, 0x90, 0xd8, 0x23, 0xa4, 0x5e, 0x06, 0xf2, + 0xc3, 0x35, 0xfa, 0x74, 0x2c, 0x96, 0x77, 0x54, 0xbf, 0x65, 0xc5, 0xeb, + 0xc2, 0x5f, 0xc2, 0x83, 0x0e, 0xf5, 0x93, 0x33, 0xf6, 0xf9, 0xed, 0x54, + 0x9d, 0x00, 0x0e, 0xea, 0xfd, 0x90, 0xf4, 0x2b, 0xb9, 0xdf, 0xf0, 0xbe, + 0x1a, 0x74, 0x66, 0x93, 0x7b, 0xee, 0x72, 0xbf, 0xdf, 0x03, 0xea, 0xa3, + 0xf2, 0x8e, 0xbe, 0xd4, 0xf3, 0xac, 0xde, 0x4c, 0xf6, 0xf7, 0x98, 0xcc, + 0x2f, 0x5b, 0xf6, 0x73, 0xc9, 0x8c, 0x53, 0xed, 0xbd, 0xec, 0x7a, 0x71, + 0xbc, 0xff, 0x6c, 0xbf, 0xde, 0xbc, 0xdb, 0xab, 0xee, 0x9e, 0x51, 0xf7, + 0xbf, 0xb7, 0x75, 0x1e, 0x6d, 0x27, 0x6b, 0xbf, 0x7f, 0xa0, 0xee, 0x15, + 0x7d, 0x99, 0x1b, 0x67, 0xea, 0x59, 0x7c, 0x2d, 0xee, 0xd0, 0x4b, 0xcf, + 0x2f, 0xed, 0xe7, 0xc6, 0x06, 0xd7, 0xfd, 0xa3, 0xb8, 0xbf, 0x97, 0x52, + 0xf3, 0x75, 0x44, 0xea, 0xac, 0xf4, 0xc8, 0xbf, 0xa7, 0xdb, 0x83, 0x79, + 0x9c, 0xe4, 0xcd, 0x49, 0xe1, 0xab, 0x3d, 0xb7, 0x4e, 0xfd, 0xe1, 0x76, + 0x5e, 0x1a, 0x75, 0x98, 0x6d, 0x62, 0xfd, 0xbf, 0x86, 0x48, 0xfc, 0xfc, + 0x2d, 0xe5, 0x6f, 0x20, 0xfd, 0x55, 0x80, 0x9f, 0x22, 0x1d, 0x97, 0xae, + 0x1b, 0xe3, 0x8f, 0x4d, 0xe9, 0x93, 0x7e, 0x7c, 0xf8, 0xee, 0xa2, 0xbc, + 0x5b, 0x85, 0x1b, 0x91, 0x9e, 0x63, 0x38, 0xd7, 0x5c, 0x68, 0xcb, 0xdc, + 0x3c, 0x2b, 0xf3, 0xeb, 0x85, 0xc7, 0xf3, 0xb1, 0x73, 0x82, 0x78, 0x08, + 0xe3, 0x32, 0xc7, 0x3a, 0x01, 0x9f, 0x27, 0x02, 0xfe, 0x7d, 0xd8, 0x76, + 0x7d, 0xd2, 0x9b, 0x08, 0x18, 0xc7, 0x4b, 0x68, 0x57, 0x83, 0x3f, 0x16, + 0x49, 0xbd, 0x39, 0x98, 0x63, 0xe6, 0xfc, 0x92, 0x38, 0xdf, 0x46, 0xb9, + 0xda, 0x93, 0xd3, 0x7c, 0xe6, 0x3a, 0xfb, 0x7d, 0x5e, 0x5f, 0x97, 0xaa, + 0xd4, 0x2b, 0xc9, 0x3c, 0xeb, 0x3e, 0xba, 0x69, 0xe4, 0x57, 0xd7, 0xe7, + 0xcd, 0x58, 0xcf, 0xf7, 0xe9, 0xe3, 0xe8, 0x6f, 0x05, 0xca, 0x2e, 0xf3, + 0x82, 0x51, 0xdd, 0x63, 0xbb, 0x68, 0x36, 0xd9, 0x95, 0x79, 0xd8, 0xbd, + 0x48, 0xd7, 0x2c, 0x76, 0xb5, 0x7c, 0x81, 0x1a, 0x61, 0x69, 0xe3, 0x1e, + 0xc9, 0xcb, 0x51, 0x8e, 0xe5, 0xee, 0x09, 0x9d, 0xaf, 0x0a, 0xc5, 0xbf, + 0xc6, 0xf9, 0xfa, 0xf8, 0x7b, 0xc6, 0xd3, 0xf0, 0x3e, 0xa1, 0x37, 0x98, + 0xe3, 0x45, 0x42, 0x08, 0x92, 0x73, 0xdc, 0x51, 0xee, 0x55, 0xc9, 0x9f, + 0x41, 0xfd, 0xcc, 0xfd, 0xb8, 0x5b, 0x1d, 0x47, 0x13, 0xfc, 0xd3, 0x75, + 0x34, 0xe7, 0x39, 0xf1, 0xc4, 0xe0, 0x63, 0x77, 0x08, 0x1f, 0xad, 0x21, + 0x7c, 0x36, 0xe7, 0xd6, 0x57, 0xd2, 0xc7, 0x79, 0x70, 0x72, 0xb4, 0x70, + 0xfd, 0xfc, 0x32, 0xd5, 0xd5, 0xee, 0xf2, 0x0f, 0x08, 0xdf, 0x59, 0xb1, + 0x28, 0x5f, 0xfe, 0x0a, 0xeb, 0xe5, 0x59, 0x5e, 0xd3, 0xf8, 0xcd, 0xb2, + 0xfe, 0xbd, 0xf1, 0x1f, 0xb6, 0x34, 0x9b, 0xb9, 0xa0, 0x0c, 0x00, 0x00, + 0x00 }; static u8 bnx2_rv2p_proc2[] = { - /* Date: 05/13/2008 13:50 */ - 0xad, 0x58, 0x4d, 0x6c, 0x54, 0x55, 0x14, 0xbe, 0x7d, 0xf3, 0xdb, 0x99, - 0x37, 0x3f, 0xb4, 0xb5, 0xbf, 0x68, 0xa1, 0x95, 0xd2, 0x92, 0x29, 0x94, - 0x69, 0x01, 0x95, 0x44, 0x49, 0x31, 0x05, 0x94, 0x84, 0x52, 0x5d, 0x10, - 0x37, 0xd0, 0x22, 0xa5, 0x83, 0x2d, 0x69, 0x28, 0x61, 0xc1, 0xc6, 0x09, - 0xc5, 0xe2, 0x62, 0x12, 0x2d, 0xb1, 0x14, 0x8c, 0xc1, 0x46, 0x37, 0xc4, - 0xb8, 0x19, 0x83, 0x52, 0xd4, 0xc4, 0x84, 0x60, 0x43, 0x70, 0x01, 0x26, - 0x9a, 0xe0, 0x42, 0x13, 0xa2, 0x50, 0x0b, 0x36, 0x58, 0x7e, 0x46, 0x17, - 0xca, 0x78, 0xef, 0xf9, 0xce, 0x7d, 0x7d, 0x6f, 0x3a, 0xb5, 0x2c, 0xe8, - 0xe6, 0xeb, 0xbd, 0xef, 0xdc, 0x73, 0xcf, 0xcf, 0x77, 0xcf, 0x39, 0x6d, - 0x54, 0x08, 0xe1, 0x16, 0xc9, 0x74, 0xb5, 0x44, 0x11, 0x32, 0x0a, 0xfc, - 0x12, 0xb2, 0x42, 0x78, 0xca, 0xd5, 0x5a, 0x18, 0x82, 0x7f, 0x56, 0x44, - 0x09, 0x7e, 0x48, 0xab, 0xef, 0x3e, 0xf1, 0xaa, 0x81, 0xef, 0x6e, 0xa1, - 0x30, 0x22, 0x44, 0x52, 0x61, 0x94, 0x71, 0x3d, 0x63, 0x86, 0x31, 0x58, - 0x00, 0x6c, 0x66, 0x7c, 0xc0, 0xfb, 0x77, 0x78, 0x7d, 0x93, 0xf1, 0x6f, - 0xde, 0x37, 0x19, 0x6f, 0xf3, 0xfe, 0xf3, 0x06, 0x30, 0xc1, 0xfb, 0x3f, - 0x4b, 0xd4, 0x76, 0xa9, 0xf5, 0x74, 0x56, 0x24, 0xe5, 0x19, 0x21, 0xc5, - 0x1b, 0xf4, 0xbe, 0x49, 0x90, 0x6c, 0x80, 0xdd, 0xaf, 0x2c, 0x51, 0x72, - 0xbf, 0xe7, 0x91, 0x53, 0xfb, 0x37, 0xb2, 0xd0, 0x3b, 0xeb, 0xaf, 0xe1, - 0x51, 0xe7, 0x96, 0xb6, 0x9c, 0x18, 0xc6, 0xf9, 0x9d, 0x4b, 0xb0, 0xff, - 0x54, 0x4c, 0xf9, 0xef, 0x15, 0x49, 0x46, 0xd1, 0xa8, 0xd0, 0x28, 0x48, - 0x36, 0xea, 0x40, 0x41, 0xfe, 0x97, 0x61, 0xac, 0x3a, 0x43, 0xd0, 0x1b, - 0x70, 0xe8, 0x2d, 0x9d, 0xa3, 0xf7, 0x5a, 0xa1, 0x5d, 0xff, 0x67, 0xac, - 0x3f, 0xb0, 0xa0, 0xfe, 0xae, 0x10, 0xb0, 0x38, 0x96, 0xef, 0x9e, 0xc2, - 0x05, 0xec, 0xdf, 0xb7, 0xa0, 0xfe, 0xc3, 0x96, 0xfd, 0x3a, 0x6e, 0xfa, - 0x3b, 0xb0, 0x1a, 0x62, 0x9f, 0x24, 0x57, 0xe9, 0x78, 0x6a, 0xbf, 0xd9, - 0x3e, 0x17, 0x70, 0x43, 0x8c, 0x20, 0xb5, 0x9b, 0x03, 0xdc, 0x56, 0xa7, - 0xee, 0x2d, 0x12, 0x6e, 0x43, 0xe9, 0x59, 0xee, 0xf7, 0x9e, 0xc7, 0xfe, - 0x8e, 0x08, 0xf0, 0x75, 0x76, 0xe4, 0x46, 0x40, 0x05, 0x26, 0x9b, 0xed, - 0x0e, 0xb2, 0x7e, 0xa4, 0x55, 0x24, 0x83, 0x38, 0x3f, 0x61, 0x2a, 0xfb, - 0x2e, 0xcb, 0xfc, 0xa9, 0xb5, 0x4b, 0x24, 0x23, 0x4e, 0x3f, 0x3e, 0x14, - 0x90, 0x5b, 0xb4, 0x1c, 0xbb, 0xef, 0x76, 0x63, 0x5d, 0xf5, 0x71, 0x94, - 0xe4, 0x4f, 0xa6, 0xb5, 0x1f, 0x6a, 0x5f, 0xbe, 0x83, 0x08, 0xf4, 0x88, - 0x1a, 0x3f, 0x5d, 0x86, 0x38, 0xc9, 0x4b, 0x1b, 0xb5, 0x3e, 0xfc, 0x9c, - 0x58, 0xa6, 0xf9, 0x85, 0x75, 0xb7, 0x97, 0xa0, 0xbc, 0x73, 0x48, 0xd9, - 0x1b, 0x11, 0xbb, 0x0c, 0x65, 0x88, 0xc1, 0xfe, 0xb9, 0xfc, 0xe6, 0x17, - 0x90, 0xff, 0xa6, 0xda, 0x24, 0xdb, 0xba, 0x9b, 0x71, 0xae, 0x24, 0x0e, - 0x1c, 0x89, 0x7b, 0x14, 0xc4, 0xba, 0x07, 0x68, 0xb9, 0xf2, 0xd7, 0xd5, - 0x7e, 0x92, 0x4b, 0x36, 0x6a, 0xfe, 0xea, 0xb8, 0x2b, 0x7f, 0xdf, 0xc9, - 0x5a, 0xfc, 0xaf, 0x45, 0x7c, 0x6e, 0x2e, 0x53, 0xf2, 0x32, 0x48, 0x35, - 0xb8, 0xa7, 0x23, 0x91, 0x8f, 0xff, 0x6f, 0xdb, 0xf8, 0xff, 0x68, 0x79, - 0xdc, 0x40, 0xfe, 0x6f, 0xe0, 0x38, 0x2c, 0x61, 0xbe, 0x2c, 0xce, 0xc3, - 0x97, 0x08, 0xfd, 0x7e, 0xab, 0x35, 0x4a, 0x71, 0xdc, 0x86, 0xfd, 0xe3, - 0x6d, 0xe7, 0x10, 0xef, 0x2d, 0x14, 0x07, 0x11, 0x38, 0xfa, 0x39, 0x4e, - 0x75, 0x86, 0xd4, 0xfa, 0xb5, 0x96, 0xee, 0x2f, 0xb1, 0xee, 0x72, 0xa9, - 0xf5, 0x0e, 0x73, 0xf7, 0x38, 0xe4, 0x3d, 0x83, 0x51, 0x8a, 0xdf, 0x36, - 0xbe, 0x65, 0x8b, 0xab, 0x40, 0x41, 0xca, 0x3b, 0x48, 0x4b, 0x73, 0x82, - 0xbe, 0x47, 0xc5, 0xb1, 0x34, 0xbe, 0xef, 0x0f, 0x52, 0x7d, 0x90, 0xfe, - 0x91, 0x5c, 0x49, 0xc2, 0x8b, 0xf3, 0xa9, 0x61, 0x3f, 0xf9, 0x3b, 0x75, - 0x56, 0xad, 0xb7, 0xc6, 0xa6, 0x20, 0x1f, 0x4b, 0x0c, 0xb1, 0x62, 0x03, - 0xf1, 0xbb, 0x65, 0x40, 0x9e, 0xe9, 0x15, 0x70, 0x53, 0xfe, 0x0a, 0x84, - 0xd9, 0x06, 0x7c, 0x8b, 0xbe, 0xff, 0x53, 0x90, 0xa2, 0x78, 0x6d, 0x0c, - 0xbb, 0xcf, 0xe9, 0xf8, 0x30, 0x46, 0xb4, 0x5f, 0xc0, 0x47, 0xe5, 0xef, - 0x90, 0xa9, 0x79, 0xcb, 0x79, 0x6b, 0x98, 0x8f, 0xb7, 0xc0, 0xb6, 0x3a, - 0xa0, 0xb7, 0x56, 0xc9, 0x79, 0xf2, 0xf0, 0xd7, 0x99, 0x17, 0xce, 0xab, - 0x8d, 0x67, 0x04, 0x92, 0x5f, 0x0e, 0xbe, 0x49, 0x3e, 0x53, 0x5d, 0x92, - 0xf1, 0xd4, 0xbc, 0x51, 0x8a, 0x7c, 0xe2, 0x0d, 0xd6, 0x97, 0x60, 0xbf, - 0x7a, 0xd9, 0xaf, 0xe9, 0x80, 0x8e, 0xbb, 0xf6, 0x07, 0x78, 0xcc, 0x04, - 0xbf, 0x3a, 0x12, 0xda, 0x2f, 0x27, 0x7f, 0xd9, 0x9e, 0xd4, 0xb7, 0x35, - 0xf8, 0xa5, 0xaa, 0x16, 0x68, 0xf9, 0x59, 0x47, 0xef, 0x25, 0x5c, 0x36, - 0xae, 0xed, 0x50, 0x79, 0xfd, 0x4b, 0xe6, 0x15, 0xf9, 0x39, 0x99, 0xb6, - 0xbf, 0xd3, 0xca, 0x3c, 0xef, 0xd4, 0xf9, 0x6e, 0xb4, 0xff, 0xfb, 0x43, - 0x54, 0x88, 0x5a, 0xae, 0x4c, 0x3a, 0xdf, 0x05, 0xf8, 0xef, 0xb3, 0x78, - 0x54, 0xb2, 0x96, 0xe3, 0xc4, 0x58, 0xba, 0x4e, 0xe9, 0x6b, 0x67, 0xfd, - 0x4d, 0xac, 0xdf, 0xb4, 0xbd, 0x4b, 0x65, 0xdf, 0x93, 0xd6, 0x7b, 0xd4, - 0xf9, 0x99, 0x7d, 0x97, 0x3a, 0x4e, 0x74, 0x7f, 0xec, 0xca, 0xa4, 0x3a, - 0x5f, 0xb5, 0xc0, 0x3b, 0x2d, 0xb6, 0xf4, 0xfd, 0x68, 0xbd, 0x47, 0xf5, - 0x3d, 0x28, 0x5e, 0xe0, 0xa5, 0xb3, 0xde, 0xfc, 0x29, 0xeb, 0x0d, 0xf9, - 0xe1, 0x37, 0xcf, 0x71, 0x7d, 0x19, 0x50, 0xf7, 0x94, 0xb3, 0xdd, 0xe5, - 0xba, 0xce, 0x4b, 0xbb, 0xb9, 0x0e, 0xed, 0xb4, 0xd7, 0x13, 0x8f, 0xad, - 0x2e, 0xa8, 0xb5, 0x2b, 0x4f, 0x9f, 0x74, 0xc4, 0x33, 0x29, 0x22, 0x98, - 0x03, 0x92, 0x11, 0x25, 0x7f, 0x4f, 0xcc, 0xad, 0x2b, 0xb9, 0xf6, 0x23, - 0x1e, 0x9d, 0x46, 0x88, 0xe4, 0xae, 0xf7, 0xab, 0x73, 0xd7, 0xac, 0x3e, - 0x8e, 0x3a, 0x73, 0x91, 0xed, 0x5d, 0xcc, 0xf6, 0x4a, 0x7d, 0x8d, 0xc4, - 0x53, 0xff, 0xf5, 0x7e, 0xbb, 0xbd, 0x77, 0x1e, 0xce, 0x7f, 0x9f, 0x33, - 0xef, 0xfd, 0xdc, 0x6f, 0xb8, 0x4f, 0xfa, 0x77, 0x7f, 0xa5, 0xed, 0xe1, - 0x7b, 0x23, 0xfa, 0x7e, 0x93, 0xf2, 0x32, 0x39, 0xa0, 0xce, 0x87, 0x05, - 0xd3, 0x44, 0xf4, 0xd5, 0xa3, 0xae, 0x4d, 0xef, 0x81, 0xfd, 0x7d, 0x75, - 0xea, 0xfe, 0x16, 0x81, 0x7e, 0xe3, 0x96, 0x21, 0x45, 0x7d, 0xbf, 0x38, - 0x9c, 0x2f, 0x8f, 0x5f, 0xb3, 0xdc, 0x38, 0xfb, 0x15, 0x65, 0xbf, 0x36, - 0x4b, 0xbf, 0x28, 0xee, 0xfc, 0x3d, 0x9f, 0xdf, 0x6c, 0xa7, 0xd0, 0xfd, - 0x9b, 0xcf, 0x91, 0x5c, 0x0f, 0xcb, 0xb9, 0xe7, 0xed, 0xdb, 0x99, 0xe5, - 0x54, 0x87, 0x4f, 0x1f, 0xa6, 0x7a, 0x1a, 0xb2, 0xf8, 0xe6, 0xb4, 0x6f, - 0xe2, 0x31, 0xc4, 0x51, 0xc9, 0x2d, 0x12, 0x7b, 0xc3, 0xf3, 0xc5, 0xcb, - 0xad, 0xb6, 0xc7, 0x66, 0xc6, 0x75, 0xbc, 0x4d, 0xf2, 0x73, 0x72, 0x80, - 0xe6, 0xc2, 0x9c, 0x38, 0x1a, 0xb6, 0x38, 0x42, 0x1e, 0xf3, 0x4a, 0xbe, - 0xf8, 0xe5, 0xeb, 0x8b, 0x9f, 0x3e, 0xd4, 0x7c, 0x3a, 0xe2, 0xd5, 0xf6, - 0x2b, 0x5c, 0x65, 0xe5, 0xf3, 0x00, 0xcf, 0x23, 0x19, 0x93, 0x7e, 0x89, - 0x4f, 0xa7, 0x68, 0x69, 0x56, 0x9c, 0x51, 0x72, 0x2b, 0xe2, 0x07, 0xd8, - 0xce, 0xcb, 0x2e, 0xf8, 0xd1, 0xb3, 0x07, 0xeb, 0x2b, 0x5c, 0xdf, 0xee, - 0x72, 0x9d, 0xda, 0xee, 0x07, 0x4e, 0xd7, 0x93, 0x7f, 0xf1, 0x03, 0xe7, - 0xb5, 0x7e, 0xd2, 0x6b, 0x66, 0x38, 0x3e, 0x2f, 0xba, 0xd8, 0xee, 0x1a, - 0xca, 0x47, 0xfc, 0x0e, 0xbd, 0x4f, 0xb7, 0x68, 0x5d, 0xaa, 0xb0, 0x42, - 0xc6, 0x81, 0xed, 0x59, 0x0f, 0xec, 0xf0, 0x71, 0x5c, 0x1b, 0x72, 0xf3, - 0x85, 0x6d, 0x6f, 0x0d, 0x9f, 0xef, 0xc4, 0xda, 0xc7, 0xf5, 0x65, 0x94, - 0xed, 0x7a, 0xaf, 0x1e, 0x18, 0x6e, 0x40, 0x7f, 0x9c, 0x34, 0x15, 0x46, - 0xe2, 0x03, 0xe3, 0xf0, 0xa7, 0x77, 0x23, 0xfc, 0xbd, 0xc7, 0x71, 0x60, - 0x0c, 0x9f, 0x1a, 0xa4, 0xbe, 0x19, 0x1e, 0x42, 0x7f, 0x0d, 0x7b, 0x07, - 0xe1, 0x47, 0x6f, 0x06, 0xeb, 0x7b, 0xcf, 0x02, 0x1f, 0x3c, 0x87, 0x73, - 0x07, 0x0f, 0x73, 0x7c, 0x36, 0xe6, 0x3f, 0xd7, 0x73, 0x1f, 0x72, 0x7d, - 0xf5, 0xd4, 0xe7, 0xc7, 0xb8, 0xef, 0x8a, 0x04, 0xf7, 0xf9, 0x0c, 0xaf, - 0xf7, 0x71, 0x1f, 0xb9, 0xcd, 0x7d, 0xb2, 0x37, 0xa7, 0x4f, 0x4e, 0xa1, - 0x6e, 0x8e, 0x65, 0x52, 0x6a, 0x43, 0xd6, 0xaf, 0x42, 0xdd, 0x1f, 0x15, - 0x06, 0xe2, 0x65, 0x9c, 0xaf, 0x92, 0x35, 0xc0, 0x91, 0x35, 0xe8, 0x6b, - 0xbd, 0x87, 0x38, 0x2e, 0x2d, 0x94, 0x9f, 0x95, 0x33, 0xe3, 0x9a, 0x0f, - 0x34, 0x3f, 0x3d, 0xd4, 0xbc, 0x43, 0xfd, 0xca, 0x58, 0xf5, 0x76, 0x8a, - 0xec, 0xab, 0x1a, 0xcb, 0x90, 0x7c, 0xa5, 0x28, 0x26, 0x7e, 0x55, 0x84, - 0x67, 0x60, 0x6f, 0x7c, 0x94, 0xfd, 0xec, 0x7f, 0x06, 0x78, 0x88, 0xf3, - 0xac, 0xf3, 0x77, 0x75, 0x9d, 0x49, 0xe7, 0x26, 0x07, 0x60, 0xb7, 0xe6, - 0x7d, 0xee, 0x9c, 0xa7, 0xf3, 0x5e, 0xd1, 0x4c, 0x6b, 0xd1, 0x73, 0x50, - 0xdd, 0x13, 0x92, 0xf9, 0x52, 0x76, 0xc9, 0x58, 0x70, 0x7f, 0x74, 0xf2, - 0x41, 0xf1, 0x45, 0xf3, 0xd2, 0xce, 0x23, 0x3b, 0x4f, 0x9c, 0xfc, 0x08, - 0x53, 0x3d, 0x97, 0x8f, 0x97, 0xfa, 0xa7, 0x37, 0x3e, 0x3a, 0xfc, 0xff, - 0xf1, 0x3a, 0x85, 0x78, 0xc5, 0xd9, 0x6e, 0x33, 0x41, 0x73, 0xd6, 0x13, - 0x62, 0x88, 0xf3, 0x35, 0x55, 0xcf, 0xef, 0xb5, 0x06, 0xf9, 0xea, 0x7f, - 0x1a, 0xf6, 0xf4, 0xf3, 0x3b, 0xf9, 0x83, 0xfb, 0x39, 0xf2, 0xec, 0x33, - 0xbb, 0xc7, 0x39, 0xaf, 0xcc, 0xb7, 0x7d, 0x1c, 0x87, 0xdb, 0x88, 0x83, - 0xa9, 0xe3, 0x90, 0xb0, 0xe2, 0xa0, 0xeb, 0x83, 0x5d, 0x4f, 0x91, 0xe4, - 0x0b, 0xd5, 0x19, 0xf3, 0x2a, 0xcd, 0x27, 0x1e, 0xf6, 0x5b, 0xca, 0x35, - 0x2b, 0xff, 0xc2, 0xec, 0x5f, 0x48, 0xec, 0x5d, 0x69, 0x3f, 0x17, 0xe4, - 0x73, 0x01, 0x79, 0x0e, 0xfb, 0x78, 0x8f, 0xe6, 0x3c, 0xf1, 0x55, 0x71, - 0xd4, 0x7a, 0x73, 0xdf, 0x9d, 0x3d, 0x9e, 0x54, 0x51, 0xe9, 0x07, 0x75, - 0x46, 0xe6, 0x8d, 0xea, 0x91, 0x69, 0xd5, 0x99, 0xbb, 0x54, 0x7f, 0x03, - 0xa7, 0xfb, 0x50, 0x17, 0x4e, 0xf7, 0x9d, 0xe1, 0xfe, 0xc7, 0x71, 0x69, - 0xa7, 0xb9, 0x58, 0xc6, 0xae, 0xc6, 0x59, 0x67, 0x9c, 0x76, 0x54, 0xd9, - 0xec, 0xd0, 0xf7, 0xce, 0xd7, 0x97, 0x31, 0xaf, 0x6d, 0xa2, 0xbe, 0xec, - 0xb7, 0xe6, 0x49, 0x67, 0xbd, 0xf7, 0x3f, 0x72, 0xbd, 0xdf, 0xde, 0x6c, - 0xd7, 0x5f, 0x2b, 0x26, 0xd2, 0xd0, 0xdf, 0xce, 0xfd, 0x72, 0x17, 0xbf, - 0xdb, 0xeb, 0x81, 0x08, 0xdd, 0xd7, 0xf5, 0x32, 0xf9, 0x27, 0x4a, 0x83, - 0xf0, 0xa7, 0x6b, 0x2b, 0xbe, 0x77, 0x85, 0xb0, 0x5f, 0x19, 0xc2, 0xdf, - 0x5b, 0xed, 0x3e, 0x93, 0xe4, 0x2b, 0x43, 0xc0, 0x52, 0x7e, 0xef, 0x13, - 0xd6, 0x5c, 0x0c, 0x3c, 0xe9, 0xb5, 0xcf, 0x8f, 0x6e, 0x71, 0xc1, 0x8b, - 0xf7, 0x2f, 0x1a, 0x30, 0x07, 0xb6, 0xd6, 0x99, 0xf4, 0xbd, 0xa3, 0x01, - 0xfd, 0x12, 0xf5, 0x75, 0xf6, 0xef, 0x33, 0x9e, 0x2b, 0x2b, 0x67, 0xe7, - 0x67, 0xfb, 0x7c, 0x5d, 0x18, 0x1f, 0xb5, 0xe6, 0x5c, 0x7d, 0x9f, 0xfd, - 0xfd, 0x28, 0xbd, 0xb4, 0x94, 0x73, 0xaa, 0x7d, 0xbe, 0x76, 0xe9, 0x79, - 0x87, 0xe7, 0xd1, 0x62, 0x71, 0x29, 0x0d, 0xbf, 0x26, 0xd2, 0xf9, 0xde, - 0xa1, 0xba, 0x4f, 0xeb, 0x83, 0xdd, 0xda, 0x8f, 0x59, 0xfd, 0xb8, 0x7f, - 0x0f, 0xdb, 0xf9, 0x1b, 0xfd, 0x5d, 0x5c, 0xca, 0xfe, 0x28, 0xbd, 0xd8, - 0xdf, 0xcc, 0xf3, 0x7e, 0xd2, 0x5a, 0x3b, 0xe7, 0xf4, 0x76, 0xb2, 0xab, - 0x88, 0xfb, 0x69, 0xa9, 0xad, 0xdf, 0x43, 0xbe, 0xa4, 0x09, 0x38, 0xd2, - 0xa4, 0xf3, 0xa0, 0xf3, 0xa5, 0xf3, 0x83, 0x3c, 0x96, 0xae, 0x26, 0xb1, - 0x96, 0xae, 0xd5, 0xf4, 0x60, 0x9b, 0xba, 0x66, 0x9c, 0xff, 0x3f, 0xd8, - 0x1e, 0x53, 0xf2, 0x6f, 0x8a, 0xef, 0x63, 0x68, 0x80, 0x3f, 0x31, 0xce, - 0xce, 0xc5, 0x9c, 0x00, 0x6b, 0x1e, 0xc1, 0x7d, 0x17, 0x3c, 0xbc, 0xdd, - 0xac, 0xe7, 0x46, 0x67, 0xff, 0xfe, 0x90, 0xea, 0xf2, 0xd9, 0x7f, 0x73, - 0xe7, 0xce, 0xd9, 0xf9, 0x51, 0xfb, 0xa9, 0xe4, 0x1b, 0x99, 0x8f, 0x7e, - 0xd1, 0xba, 0x09, 0x7f, 0x6f, 0x87, 0x7d, 0xe0, 0x7d, 0xd8, 0x67, 0xcf, - 0x97, 0xe4, 0x45, 0x21, 0x3d, 0xf0, 0xc5, 0x45, 0x85, 0xe4, 0xcf, 0xf1, - 0xcb, 0xdf, 0xd1, 0xe7, 0x8f, 0x46, 0x83, 0xd8, 0x2f, 0x6b, 0x85, 0x7a, - 0x37, 0xf1, 0xd6, 0x25, 0x8e, 0x82, 0xd7, 0x1f, 0x8c, 0x00, 0xdf, 0x17, - 0x2f, 0x41, 0x4f, 0xd1, 0x11, 0xea, 0x73, 0xfe, 0x32, 0x84, 0x35, 0x35, - 0xca, 0x7c, 0x2d, 0x37, 0xe8, 0xff, 0x65, 0x59, 0x11, 0xe2, 0xff, 0xab, - 0xf0, 0xbb, 0x03, 0x4f, 0xdd, 0xb6, 0x7c, 0x2f, 0xc4, 0x5b, 0xaa, 0x1f, - 0x92, 0x97, 0x38, 0xce, 0xfc, 0xf5, 0xe7, 0xf2, 0x57, 0xc7, 0xa5, 0xdc, - 0xc8, 0xcb, 0xd7, 0xb5, 0x4e, 0xbe, 0x7a, 0x99, 0xaf, 0xf7, 0xad, 0xfe, - 0x36, 0x57, 0x2f, 0xfe, 0xae, 0xb8, 0xf4, 0xd8, 0xf8, 0x0b, 0xdc, 0x5c, - 0xab, 0xee, 0x2f, 0x9b, 0x33, 0x77, 0x56, 0x0b, 0x7b, 0x3d, 0x3a, 0x24, - 0xf3, 0xfd, 0x1f, 0xfe, 0xac, 0x5e, 0x92, 0x80, 0x14, 0x00, 0x00, 0x00 }; + /* Date: 02/03/2009 14:20 */ + 0xad, 0x57, 0x4d, 0x68, 0x5c, 0x55, 0x14, 0x3e, 0xf3, 0xe6, 0xef, 0xcd, + 0xcc, 0x9b, 0xcc, 0x34, 0x8d, 0x93, 0x31, 0x29, 0x26, 0x4d, 0x68, 0xea, + 0xc8, 0x44, 0xf3, 0x47, 0x05, 0x5d, 0x18, 0x46, 0x48, 0x7f, 0x2c, 0x34, + 0x8d, 0x2e, 0x8a, 0x9b, 0x36, 0x53, 0x3b, 0x3a, 0x6d, 0xed, 0xc2, 0xec, + 0xdc, 0xf8, 0xb0, 0x35, 0x41, 0x98, 0x45, 0x53, 0x4c, 0x13, 0x44, 0xa8, + 0xe8, 0xce, 0xdd, 0x88, 0x9a, 0xd6, 0x8d, 0x50, 0x68, 0x28, 0x76, 0x51, + 0x04, 0x05, 0xed, 0x42, 0x10, 0xad, 0xa1, 0x15, 0x41, 0x51, 0xb3, 0x92, + 0x8c, 0xf7, 0x9e, 0xef, 0xdc, 0x37, 0xef, 0x4d, 0xa6, 0xa4, 0x0b, 0x67, + 0xf3, 0xe5, 0xdc, 0x77, 0xee, 0xb9, 0xe7, 0xe7, 0x3b, 0xe7, 0xde, 0x64, + 0x89, 0x28, 0x42, 0x6e, 0xbd, 0x4f, 0x21, 0x85, 0xc2, 0x21, 0x5b, 0x41, + 0x83, 0x28, 0x9a, 0xd7, 0x32, 0x59, 0x24, 0xbf, 0x27, 0xb2, 0x0c, 0xdf, + 0xd6, 0x1d, 0xad, 0x46, 0x6e, 0x41, 0xeb, 0xd9, 0xf4, 0x92, 0x05, 0xbd, + 0x08, 0x69, 0x54, 0x3a, 0xae, 0xc6, 0x1d, 0x82, 0xcf, 0x08, 0x46, 0x42, + 0xc0, 0xb0, 0xa0, 0xd5, 0x82, 0x24, 0x7a, 0x5d, 0x22, 0x6f, 0x8a, 0xec, + 0x08, 0xe6, 0x65, 0xfd, 0xb4, 0xe0, 0xab, 0xb2, 0x7e, 0x47, 0x70, 0x5d, + 0xa1, 0xf1, 0x53, 0xcb, 0xbf, 0x35, 0x9a, 0xb2, 0x03, 0xf3, 0x05, 0xf8, + 0xff, 0x62, 0x3f, 0xeb, 0x37, 0x82, 0xfa, 0x77, 0x1b, 0xc6, 0x0f, 0x13, + 0xaf, 0x15, 0xd5, 0xfa, 0xbb, 0x27, 0x2e, 0x2f, 0x62, 0xdf, 0xf1, 0x7e, + 0xac, 0x3f, 0x56, 0xd4, 0x71, 0xc7, 0xc8, 0x15, 0xa4, 0x61, 0x9b, 0xe3, + 0x70, 0x87, 0x4d, 0xa2, 0xa0, 0xff, 0xe3, 0x22, 0xa4, 0xd9, 0x34, 0xec, + 0x26, 0x03, 0x76, 0x73, 0x5b, 0xec, 0x7e, 0x9f, 0xf0, 0xdb, 0xff, 0x54, + 0xec, 0x27, 0xb7, 0xb5, 0x5f, 0x4e, 0x03, 0x77, 0x16, 0xdb, 0x9d, 0x93, + 0xd8, 0xc6, 0xff, 0xd3, 0xdb, 0xda, 0x7f, 0xd3, 0xf3, 0xdf, 0xac, 0x03, + 0xfb, 0xf0, 0xf9, 0x13, 0xf7, 0x29, 0x93, 0x47, 0x13, 0xaf, 0xf8, 0x15, + 0x06, 0x4e, 0x16, 0x19, 0x6a, 0x27, 0x25, 0xb1, 0x53, 0x43, 0xfa, 0xbc, + 0x4e, 0x8a, 0x58, 0xda, 0xce, 0x5e, 0x3b, 0x76, 0x0d, 0xeb, 0xc7, 0x32, + 0xc0, 0x57, 0x24, 0x80, 0xbb, 0x49, 0x9d, 0x90, 0x46, 0xa3, 0x92, 0x12, + 0xfb, 0x28, 0x23, 0xb9, 0x29, 0xec, 0x5f, 0x73, 0xb4, 0x5f, 0xb7, 0x54, + 0xdd, 0xb4, 0x1c, 0x26, 0x37, 0x13, 0xf4, 0xff, 0x0a, 0x41, 0x6f, 0xc7, + 0x5e, 0xac, 0x5e, 0xac, 0x40, 0xee, 0xfd, 0x38, 0xcb, 0xfa, 0x2b, 0x75, + 0x13, 0x87, 0x5e, 0x57, 0xfc, 0xcf, 0xc0, 0x0e, 0x0d, 0xd8, 0x7c, 0x18, + 0xf2, 0xa3, 0x0e, 0x1d, 0x36, 0xf6, 0xf0, 0xbb, 0xbc, 0xc7, 0xf0, 0x09, + 0x72, 0x25, 0xc6, 0x90, 0x9f, 0x9d, 0xd7, 0xfe, 0x66, 0xe8, 0x84, 0xa5, + 0x1d, 0xb1, 0x24, 0xbe, 0xb0, 0xed, 0x7c, 0x01, 0xfd, 0xaf, 0xfa, 0x1c, + 0xf6, 0xad, 0x32, 0x8e, 0x7d, 0x5d, 0x63, 0xc0, 0xa5, 0xb1, 0xa8, 0x86, + 0x62, 0x65, 0x8e, 0xc5, 0x27, 0x7f, 0x1e, 0xb5, 0x59, 0xcf, 0x1d, 0x36, + 0x7c, 0x35, 0x79, 0xd7, 0xf1, 0x5e, 0x6c, 0xf2, 0x76, 0x10, 0xf9, 0xf9, + 0x75, 0x8f, 0xd6, 0x57, 0x49, 0x1a, 0xc0, 0x39, 0x33, 0xd5, 0x76, 0x7c, + 0x7f, 0x57, 0xed, 0x7b, 0xb8, 0xfa, 0x4d, 0x72, 0xdc, 0x93, 0x12, 0x7f, + 0xbf, 0xf0, 0x63, 0x57, 0x1b, 0x7e, 0x64, 0xf8, 0xef, 0xfb, 0xa5, 0x2c, + 0xe7, 0xef, 0x08, 0xd6, 0x2f, 0x4d, 0xad, 0x22, 0xcf, 0x07, 0x39, 0x7e, + 0x4a, 0x5e, 0xf8, 0x1c, 0xbb, 0x66, 0xd3, 0x5a, 0x7e, 0x79, 0xa2, 0xf2, + 0x25, 0xe4, 0x72, 0x58, 0xcb, 0xc7, 0x9c, 0x93, 0x57, 0xa1, 0x1f, 0x3d, + 0x9f, 0xe5, 0xbc, 0x1d, 0x91, 0x53, 0x0e, 0xaa, 0x51, 0xa1, 0x7e, 0xb5, + 0xd8, 0x79, 0x16, 0x9d, 0x35, 0xfe, 0x9e, 0xa5, 0x85, 0x3a, 0xbe, 0x9f, + 0x4b, 0xe9, 0xb8, 0xce, 0xa8, 0xb8, 0x58, 0xaf, 0xab, 0x1a, 0xc3, 0xfe, + 0xda, 0xa2, 0xb6, 0x17, 0xa2, 0x7b, 0x9f, 0x69, 0xf9, 0x70, 0xf1, 0x1e, + 0xf4, 0x8b, 0xd5, 0x79, 0x31, 0x6c, 0x21, 0x6f, 0xf7, 0x2d, 0xe8, 0x0b, + 0xad, 0x92, 0x11, 0xae, 0x5b, 0x88, 0x9c, 0x29, 0xe0, 0x3b, 0xfc, 0xfd, + 0xdf, 0x50, 0x8d, 0xf3, 0xf5, 0x7c, 0x47, 0x64, 0xd5, 0xe4, 0x47, 0x30, + 0x63, 0xe2, 0x02, 0x3e, 0x2c, 0x6f, 0xe7, 0x1d, 0xc3, 0x57, 0xa9, 0x57, + 0xe1, 0x41, 0x7c, 0x05, 0x4e, 0x0d, 0x01, 0x63, 0x83, 0x5a, 0x2f, 0xda, + 0x86, 0xb7, 0xc1, 0xba, 0x48, 0x5d, 0x7d, 0xfc, 0x62, 0x50, 0xbc, 0x0a, + 0xf0, 0x4c, 0xf1, 0x98, 0xe7, 0x90, 0xca, 0xa7, 0xe1, 0x8b, 0x36, 0x14, + 0xa7, 0x33, 0x62, 0xaf, 0x2a, 0x71, 0x9d, 0x95, 0xb8, 0x7e, 0x4f, 0x9a, + 0xbc, 0x9b, 0x78, 0x80, 0x0b, 0x5e, 0x3c, 0x86, 0x6f, 0xb8, 0x1f, 0x66, + 0xaa, 0x01, 0x7f, 0x6a, 0x37, 0x06, 0xf0, 0x47, 0xef, 0x20, 0xd0, 0x8b, + 0x73, 0x88, 0xfb, 0xa4, 0xa3, 0xfb, 0xaa, 0xf1, 0x43, 0xd7, 0x75, 0x43, + 0xf8, 0x6a, 0xa9, 0x78, 0xfd, 0xfd, 0xd9, 0xd3, 0xa6, 0x3f, 0x83, 0xfd, + 0x62, 0xe2, 0x3f, 0x97, 0xe6, 0x01, 0x34, 0x71, 0x7b, 0x3d, 0xd8, 0x0f, + 0xe0, 0x7f, 0xdc, 0xe3, 0x51, 0xd7, 0x3e, 0xc9, 0x93, 0x60, 0xee, 0x69, + 0x6d, 0x6f, 0x5a, 0xec, 0x8f, 0x88, 0x7d, 0xc7, 0xd7, 0x8f, 0xda, 0xbf, + 0x3e, 0xaf, 0x0f, 0x4d, 0x7d, 0x9a, 0xfd, 0x68, 0xf2, 0xc4, 0xe7, 0x17, + 0x6f, 0xaf, 0xeb, 0xfd, 0xbd, 0xdb, 0xf4, 0xe7, 0x23, 0x9e, 0xbd, 0xef, + 0xbc, 0x7e, 0xd4, 0xdf, 0x53, 0xf4, 0x9c, 0x88, 0xc1, 0x39, 0xf3, 0x87, + 0x9a, 0x33, 0x1c, 0x87, 0xed, 0xac, 0xca, 0x5c, 0x99, 0xd3, 0xe7, 0xe4, + 0xc5, 0xef, 0xbc, 0x99, 0xeb, 0xca, 0x6f, 0x99, 0x3f, 0xc7, 0xfd, 0x73, + 0x24, 0xde, 0xe6, 0x3c, 0xc0, 0x64, 0xb1, 0x35, 0x5f, 0xc8, 0x3b, 0xec, + 0xaa, 0xfc, 0x9b, 0x39, 0x30, 0x6e, 0xec, 0x43, 0x74, 0x47, 0xfd, 0xfa, + 0xad, 0xf5, 0x89, 0x3c, 0x60, 0x9e, 0x6d, 0x6c, 0xe2, 0xde, 0xfd, 0x67, + 0xb3, 0x79, 0x1f, 0x07, 0xea, 0xe8, 0x12, 0xd7, 0x3d, 0xae, 0xea, 0xcf, + 0xef, 0x03, 0xef, 0x9e, 0xb7, 0xa2, 0x7a, 0x5d, 0xe5, 0x42, 0x78, 0xf5, + 0xfa, 0xe3, 0xb2, 0xbf, 0x80, 0xb9, 0xf4, 0xda, 0x29, 0xce, 0xff, 0x7b, + 0x67, 0x37, 0x78, 0x3e, 0x7d, 0xf8, 0xc6, 0x35, 0x1d, 0xd7, 0xa3, 0xb4, + 0x3e, 0xe7, 0xb0, 0x3f, 0xa5, 0xdd, 0x50, 0xdf, 0x78, 0xb6, 0xb5, 0x1e, + 0x78, 0xd7, 0xa0, 0x5e, 0x4a, 0x6f, 0x36, 0x78, 0xaf, 0x36, 0xfd, 0x43, + 0xbf, 0xec, 0xcf, 0x40, 0xdf, 0xf4, 0x73, 0xb0, 0xae, 0x77, 0x36, 0x9b, + 0x73, 0xd7, 0xe4, 0x3b, 0xc8, 0xd3, 0xa3, 0xe3, 0x7e, 0xbb, 0x83, 0xb4, + 0x56, 0x87, 0xdd, 0x69, 0xe9, 0xc3, 0x13, 0x72, 0xf0, 0x4f, 0xc9, 0x0c, + 0x9f, 0x53, 0x7e, 0x81, 0x79, 0x46, 0xb9, 0x14, 0xe2, 0x2c, 0x1f, 0xc6, + 0xf7, 0x72, 0x1a, 0xeb, 0x3d, 0x69, 0xdc, 0x6f, 0xd3, 0x71, 0x87, 0xf5, + 0x7b, 0xd2, 0xc0, 0x9c, 0xf4, 0xeb, 0x9a, 0x37, 0x8f, 0x80, 0x2b, 0x31, + 0x7f, 0xff, 0x46, 0xe8, 0x7a, 0x4c, 0x2b, 0xa8, 0xcb, 0xba, 0x80, 0xfe, + 0x2b, 0x0d, 0x39, 0xfc, 0x7d, 0xa6, 0x80, 0xb9, 0x4a, 0x03, 0xc1, 0xfb, + 0x50, 0xfa, 0xb9, 0xa7, 0x39, 0xb7, 0xfc, 0x73, 0x2d, 0x31, 0xb6, 0x5c, + 0x0f, 0xde, 0x97, 0x2b, 0x31, 0xff, 0x9c, 0xd0, 0x76, 0x59, 0x54, 0xf3, + 0xc1, 0x3f, 0xd7, 0xc2, 0x52, 0xef, 0xbf, 0x64, 0x0e, 0xec, 0xa4, 0x9b, + 0x75, 0xc4, 0xb5, 0x56, 0x6f, 0xcd, 0xb3, 0x39, 0xcf, 0xd8, 0x83, 0xdf, + 0x26, 0x8e, 0xa6, 0x7d, 0x9c, 0x7f, 0x4a, 0xfc, 0xfc, 0x85, 0xdf, 0x21, + 0x39, 0x89, 0x47, 0xdb, 0xc5, 0xfa, 0x01, 0x99, 0xb3, 0xae, 0x27, 0x07, + 0xe7, 0xe3, 0x34, 0xfb, 0xd5, 0x49, 0x78, 0x77, 0xe4, 0xbc, 0xbe, 0x36, + 0xf1, 0x75, 0x8d, 0x00, 0x97, 0x46, 0x4c, 0x1d, 0x4c, 0xbd, 0x4c, 0x7d, + 0x50, 0xc7, 0xdc, 0x28, 0xab, 0x4d, 0x94, 0x47, 0x99, 0xa7, 0x23, 0xe5, + 0x3f, 0x83, 0xef, 0xb4, 0xa3, 0x45, 0xad, 0xff, 0x16, 0x7d, 0xc3, 0x7d, + 0x44, 0xf4, 0x83, 0x60, 0x73, 0x1e, 0x49, 0x01, 0x02, 0xef, 0xb2, 0x30, + 0x5d, 0x8f, 0xca, 0xf2, 0xb8, 0xe9, 0x9b, 0x60, 0xdf, 0x5d, 0xe1, 0x77, + 0xfa, 0xc2, 0xe6, 0xd6, 0xfe, 0x37, 0xf1, 0x69, 0xbd, 0x61, 0xe1, 0xa1, + 0x4d, 0xa5, 0xfd, 0x78, 0xd7, 0x74, 0xc4, 0xc1, 0xf3, 0x8e, 0xb8, 0xbf, + 0x4e, 0x8a, 0x0f, 0x89, 0xb8, 0x16, 0x77, 0x75, 0x26, 0x38, 0x8e, 0x4b, + 0x5f, 0xdf, 0xe2, 0xcf, 0x1f, 0x2d, 0xa7, 0xb0, 0xde, 0x5d, 0x82, 0xf9, + 0x08, 0xf3, 0x35, 0x4c, 0x17, 0xc0, 0xe7, 0x0f, 0x96, 0x80, 0xef, 0xd3, + 0x21, 0xd8, 0xe9, 0x7c, 0x9b, 0xef, 0x71, 0xbb, 0x1b, 0xe9, 0xac, 0x2d, + 0x0b, 0x4f, 0xf3, 0x16, 0xff, 0x3f, 0xd2, 0xa0, 0xb4, 0xbc, 0x5b, 0xa5, + 0xcf, 0xc0, 0xcf, 0x88, 0xaf, 0xce, 0xdb, 0xf1, 0x55, 0xa3, 0xa3, 0xf8, + 0x88, 0xed, 0xc2, 0x5b, 0xbb, 0x95, 0xb7, 0xa6, 0x8e, 0x79, 0xab, 0x2d, + 0x4f, 0xf7, 0x05, 0x79, 0x1a, 0x13, 0x9e, 0xfe, 0xed, 0xcd, 0xd3, 0xad, + 0x76, 0x31, 0xc7, 0x6f, 0xfe, 0x6f, 0xbc, 0x05, 0x1e, 0x18, 0xd4, 0xe7, + 0x77, 0xfb, 0xf8, 0x67, 0xfc, 0xf2, 0xcf, 0x9f, 0x43, 0x6a, 0xae, 0xfe, + 0x07, 0x92, 0xe2, 0x88, 0x7c, 0xe0, 0x0d, 0x00, 0x00, 0x00 }; static u8 bnx2_TPAT_b06FwText[] = { - 0xbd, 0x59, 0x6d, 0x70, 0x5b, 0x55, 0x7a, 0x7e, 0xae, 0x74, 0x25, 0x5d, - 0xdb, 0xb2, 0x75, 0x8d, 0x95, 0x20, 0xb7, 0x2e, 0xd6, 0x8d, 0xaf, 0x6c, - 0x11, 0xb9, 0xe1, 0x2a, 0x36, 0x45, 0x19, 0xee, 0x94, 0x1b, 0x7f, 0x21, - 0x92, 0x10, 0x94, 0x42, 0x5b, 0x67, 0x96, 0x19, 0x4c, 0xe2, 0x4d, 0x4c, - 0x08, 0x6c, 0xba, 0xcb, 0x4c, 0xdd, 0xd9, 0x4c, 0x23, 0xfc, 0x15, 0x93, - 0xc8, 0x16, 0x6b, 0x20, 0x26, 0x3b, 0x3b, 0x43, 0xc6, 0xf9, 0x70, 0x0a, - 0x72, 0x14, 0xda, 0x3f, 0x3b, 0xd3, 0x65, 0xf0, 0x6c, 0x12, 0x12, 0x58, - 0xd8, 0xb4, 0xd3, 0x3f, 0xc9, 0xf4, 0xc7, 0x7a, 0x21, 0xa1, 0x81, 0x42, - 0x36, 0xed, 0x0c, 0x9d, 0x50, 0x68, 0x4e, 0x9f, 0x73, 0x25, 0x07, 0x13, - 0xb2, 0xfd, 0xd9, 0xcc, 0x08, 0x4b, 0xe7, 0xde, 0x73, 0xce, 0x7b, 0xce, - 0xfb, 0x3c, 0xcf, 0xfb, 0x9c, 0xc3, 0x0a, 0x05, 0x95, 0x28, 0xff, 0xab, - 0xe6, 0xa7, 0xfd, 0xc9, 0x5d, 0xcf, 0xad, 0x5e, 0xd5, 0xbe, 0x8a, 0x5f, - 0x57, 0x2b, 0xcb, 0x55, 0x15, 0xff, 0x8f, 0xff, 0xbc, 0x80, 0xbe, 0x18, - 0x87, 0xfc, 0x40, 0xf3, 0xd8, 0xf3, 0x77, 0x75, 0x98, 0xd0, 0xbc, 0xf6, - 0x63, 0x4d, 0x5b, 0x4d, 0xc0, 0x29, 0x24, 0xa2, 0x9d, 0xf8, 0x1f, 0x91, - 0x0d, 0xab, 0x90, 0xed, 0x7f, 0x64, 0x7f, 0x7d, 0xcf, 0x5b, 0xf7, 0x19, - 0xd7, 0x0e, 0x79, 0xa1, 0xe9, 0xf6, 0xb8, 0xaa, 0x37, 0x43, 0x6b, 0x60, - 0x9f, 0x9f, 0xb5, 0xf4, 0xfb, 0x50, 0xb3, 0x38, 0x16, 0x70, 0x38, 0x67, - 0x58, 0xdb, 0x90, 0xd0, 0x4f, 0x41, 0x85, 0xc3, 0x39, 0x8e, 0x15, 0x80, - 0xbd, 0x39, 0x05, 0x97, 0x39, 0xe6, 0x68, 0x41, 0xc3, 0x82, 0xd7, 0x9d, - 0xae, 0xaf, 0xc2, 0x46, 0xc6, 0x9c, 0xd8, 0x23, 0x02, 0x26, 0xb2, 0x7f, - 0x60, 0x9b, 0xf1, 0xbd, 0x08, 0xa6, 0x66, 0xda, 0x91, 0x59, 0x31, 0xa7, - 0x61, 0x73, 0xbe, 0xa1, 0x4f, 0xb3, 0xc1, 0x77, 0x14, 0xa4, 0xee, 0xd3, - 0xd0, 0x5b, 0x8c, 0x23, 0x5b, 0xcc, 0xc2, 0x29, 0x8e, 0xf0, 0xa3, 0x21, - 0x30, 0xa1, 0x69, 0xf7, 0x4c, 0x2c, 0x97, 0xef, 0x20, 0x38, 0x71, 0x4d, - 0x5c, 0x4d, 0xea, 0x78, 0x6f, 0x8d, 0x10, 0xd5, 0x36, 0xb2, 0x55, 0xed, - 0x59, 0x78, 0x6d, 0xc3, 0x5a, 0xef, 0x55, 0xd0, 0xf5, 0xc7, 0x66, 0x7c, - 0x42, 0x79, 0xf4, 0x51, 0x8f, 0x0d, 0x4d, 0xb1, 0xa3, 0x6a, 0x53, 0xa1, - 0x01, 0x63, 0x45, 0x1d, 0x7b, 0x8b, 0x61, 0x8c, 0x14, 0xb1, 0xdb, 0x7b, - 0xaf, 0x1f, 0x33, 0x3a, 0x9c, 0xef, 0xb5, 0xec, 0xc6, 0x8e, 0xdc, 0x20, - 0xb6, 0xe6, 0x52, 0xd8, 0x57, 0x94, 0x31, 0x46, 0x31, 0x5c, 0x54, 0xe1, - 0x9f, 0x30, 0x22, 0xef, 0xe2, 0x76, 0xcf, 0x84, 0x18, 0xb1, 0x02, 0x18, - 0xb2, 0xe2, 0x18, 0xcd, 0x7b, 0xb8, 0xce, 0x00, 0x86, 0xcd, 0xeb, 0xa2, - 0xdf, 0x32, 0xac, 0x51, 0x88, 0xc6, 0xd3, 0x96, 0x11, 0xe9, 0xf2, 0xc2, - 0xf9, 0xb1, 0x19, 0xc1, 0x28, 0x63, 0x1f, 0x71, 0xfb, 0x8d, 0xa0, 0xeb, - 0x66, 0x3f, 0x87, 0xfd, 0x74, 0x8c, 0x7d, 0xbb, 0x6f, 0x74, 0x14, 0x89, - 0xc8, 0x18, 0x3c, 0xe8, 0x0b, 0xb7, 0xb2, 0x5f, 0x53, 0x74, 0x0c, 0x46, - 0x9c, 0xe3, 0x64, 0xfd, 0xed, 0x0e, 0xc7, 0xc8, 0xb2, 0xbf, 0x11, 0x3d, - 0x06, 0x39, 0x56, 0x03, 0x7f, 0xb7, 0xb3, 0xbf, 0x02, 0x8f, 0x1d, 0x8b, - 0x0e, 0xb1, 0xcf, 0x29, 0x4b, 0xc5, 0x19, 0x7e, 0xfa, 0x74, 0x43, 0x66, - 0x56, 0x09, 0xb0, 0x7d, 0x2f, 0xf8, 0xdc, 0xac, 0xc2, 0xa1, 0x8c, 0x85, - 0x21, 0xae, 0x5b, 0x63, 0xdb, 0x38, 0xdb, 0x7c, 0xa6, 0xc5, 0xf1, 0xa1, - 0x77, 0x15, 0x97, 0x62, 0x62, 0x31, 0x37, 0xbf, 0xaf, 0x9d, 0x63, 0xe4, - 0x4b, 0x39, 0x95, 0xef, 0x74, 0xe6, 0x6f, 0x88, 0x27, 0xd5, 0xa5, 0xcf, - 0x07, 0x95, 0x0e, 0xb6, 0x39, 0x6a, 0x03, 0xf6, 0xe6, 0xa1, 0xf9, 0x4d, - 0x8d, 0xf3, 0x68, 0xf8, 0x28, 0x37, 0xa8, 0xf4, 0x14, 0x1d, 0xa5, 0x7b, - 0xb6, 0x43, 0x71, 0x66, 0x55, 0xa5, 0x6b, 0x5a, 0xc6, 0x2d, 0xc4, 0x0b, - 0x96, 0xc2, 0x98, 0x7f, 0x22, 0xe3, 0x75, 0xa2, 0xca, 0x0d, 0xb1, 0x32, - 0xe6, 0x41, 0x95, 0xd9, 0xa3, 0xac, 0x9f, 0x15, 0x22, 0x9d, 0x4c, 0x2b, - 0xeb, 0x66, 0xa1, 0x05, 0x6d, 0x5b, 0xcd, 0x4d, 0xec, 0x43, 0x76, 0x99, - 0x89, 0x83, 0xf9, 0x28, 0x3e, 0xb0, 0x3c, 0x38, 0xb4, 0xac, 0x02, 0xaa, - 0xa9, 0xf0, 0x83, 0xe0, 0x79, 0x0b, 0x6a, 0x0d, 0xbf, 0x5f, 0xdd, 0xa4, - 0x62, 0xa4, 0x7d, 0x9d, 0xd2, 0xc5, 0x3e, 0x3e, 0xe6, 0xf9, 0x68, 0x2e, - 0x8d, 0x20, 0xb1, 0x53, 0x65, 0xc7, 0x22, 0x05, 0xee, 0xcd, 0x7b, 0x56, - 0x2c, 0xfe, 0xb4, 0xc4, 0x63, 0xad, 0x11, 0x91, 0x7b, 0x53, 0x6d, 0xc7, - 0xe2, 0x73, 0xdc, 0x07, 0xaf, 0xa9, 0xe2, 0xd7, 0x96, 0x0f, 0xf3, 0x9b, - 0x2c, 0xe6, 0x54, 0x87, 0x9f, 0xed, 0xc7, 0xdc, 0x76, 0xf9, 0x1b, 0x7a, - 0xf7, 0xb7, 0xf6, 0xa1, 0xb4, 0x07, 0xc3, 0xf9, 0x26, 0xc6, 0x5c, 0xda, - 0x83, 0x47, 0xb8, 0xde, 0xdf, 0xfa, 0xe4, 0xd7, 0xbb, 0x6e, 0xb6, 0x6d, - 0x66, 0x9c, 0x1e, 0xdb, 0x9c, 0x5f, 0xe1, 0xad, 0x07, 0xea, 0xda, 0xb1, - 0x8f, 0x39, 0xee, 0x4a, 0x2e, 0x47, 0xd6, 0x7d, 0x1e, 0xd6, 0xd7, 0x4f, - 0xd7, 0xa1, 0x6f, 0x99, 0xbb, 0x6f, 0xfa, 0xc6, 0x69, 0x21, 0xce, 0x24, - 0xfd, 0x98, 0x33, 0x87, 0x22, 0xd5, 0xc8, 0x5a, 0x5e, 0xe6, 0xfb, 0x2c, - 0xe7, 0x2f, 0x24, 0xbd, 0x38, 0x9c, 0x3c, 0x84, 0x6c, 0x2d, 0x30, 0x93, - 0x93, 0xbc, 0x32, 0xe6, 0xcf, 0xf2, 0xbf, 0x9e, 0xa2, 0x5c, 0x9f, 0xc5, - 0xf5, 0x29, 0x38, 0x66, 0x4a, 0x4c, 0x5b, 0x6a, 0x33, 0xf9, 0xb5, 0x83, - 0xfb, 0x59, 0xdf, 0x1e, 0x24, 0x3e, 0x81, 0x0f, 0x73, 0xfd, 0xd8, 0x5c, - 0x8a, 0x05, 0xd7, 0x73, 0x50, 0x7c, 0x6d, 0x69, 0x1c, 0x2a, 0xfd, 0x26, - 0xc7, 0xd3, 0x6a, 0x47, 0xce, 0xc8, 0xa4, 0x91, 0x38, 0xd7, 0xa1, 0xc8, - 0xfe, 0x69, 0x75, 0x65, 0xc1, 0x8f, 0x68, 0x5d, 0xe9, 0x79, 0x95, 0xbd, - 0x41, 0x7d, 0x7a, 0x42, 0xc1, 0xf6, 0x98, 0x7c, 0xb6, 0x41, 0x6d, 0x29, - 0x40, 0xab, 0xb6, 0x77, 0xa9, 0x73, 0x13, 0x46, 0xdf, 0x71, 0x25, 0x11, - 0x9d, 0x70, 0xfb, 0xec, 0x52, 0x5b, 0x0b, 0x01, 0xae, 0x27, 0xce, 0x9c, - 0x40, 0xab, 0xb1, 0x9f, 0x53, 0x7f, 0xcd, 0x07, 0xe7, 0xdc, 0x3e, 0xcf, - 0xa9, 0xf1, 0x82, 0x6c, 0x37, 0xac, 0xa8, 0x12, 0xc0, 0xdd, 0x49, 0x0d, - 0x2b, 0x5b, 0x44, 0x63, 0x77, 0xd2, 0x98, 0xef, 0xf6, 0x46, 0x70, 0x90, - 0x5c, 0x20, 0xee, 0x9c, 0x3f, 0x6c, 0x19, 0x41, 0x77, 0xd1, 0x8b, 0x68, - 0xad, 0x83, 0xfd, 0xf9, 0x00, 0x7e, 0x49, 0xfc, 0xf7, 0x58, 0x3a, 0x46, - 0xf2, 0x46, 0xfc, 0x57, 0x48, 0xa4, 0x8e, 0x30, 0x67, 0x0b, 0xe4, 0xc0, - 0xfe, 0x62, 0x53, 0xfc, 0x08, 0x8c, 0x81, 0x6e, 0x72, 0x40, 0x6b, 0x97, - 0x31, 0x40, 0x57, 0x6d, 0x72, 0xa7, 0xd8, 0x80, 0x1c, 0xf9, 0xd0, 0xed, - 0xf2, 0x6a, 0x50, 0xe9, 0x2a, 0xbe, 0x4f, 0x6d, 0xed, 0x21, 0xbe, 0x10, - 0x8a, 0x98, 0x7e, 0xa4, 0xea, 0xa2, 0x38, 0x4d, 0xac, 0x64, 0xc3, 0x15, - 0xcc, 0xa5, 0xcc, 0xe7, 0x45, 0x3e, 0x5f, 0xa7, 0x74, 0xce, 0x46, 0xf1, - 0x4b, 0xeb, 0x6b, 0xe1, 0x84, 0xab, 0xd9, 0xe6, 0x5b, 0xd2, 0xae, 0xe1, - 0xf2, 0xcb, 0x95, 0xf8, 0xf4, 0xe5, 0x20, 0xbe, 0x7c, 0x99, 0xfc, 0xce, - 0xa3, 0xbd, 0x12, 0x42, 0xa4, 0xda, 0x84, 0x28, 0x5a, 0xad, 0xf8, 0xa8, - 0x36, 0x16, 0xbd, 0x00, 0xa9, 0x8d, 0x8e, 0xba, 0x35, 0x67, 0xec, 0x1a, - 0x40, 0xc2, 0x39, 0xe5, 0xee, 0x85, 0xa3, 0xae, 0x2a, 0x9c, 0x16, 0xd8, - 0x54, 0xda, 0x0b, 0xbf, 0xdd, 0xa5, 0xbe, 0xc3, 0xdc, 0x9c, 0x77, 0x73, - 0xd3, 0xa5, 0xde, 0x53, 0xb8, 0xdf, 0x83, 0xca, 0xd2, 0x33, 0xd5, 0xce, - 0xa8, 0x23, 0x39, 0xa3, 0x77, 0x9c, 0xeb, 0xeb, 0x77, 0xfb, 0x66, 0xd4, - 0x04, 0xf7, 0x7e, 0xa1, 0x9c, 0x9b, 0x6a, 0xfb, 0x31, 0xee, 0x33, 0x73, - 0xef, 0xee, 0xe3, 0x63, 0xdc, 0x63, 0x39, 0xdf, 0xe0, 0x2d, 0xf3, 0x0d, - 0x72, 0xbe, 0xe3, 0x4b, 0xe6, 0xdb, 0xbd, 0x64, 0xbe, 0xdd, 0x4b, 0xe6, - 0x4b, 0x91, 0xab, 0xff, 0x22, 0x86, 0xc2, 0xa5, 0xb1, 0x55, 0x7b, 0xe0, - 0x96, 0xb9, 0x07, 0x38, 0xf7, 0x01, 0xb1, 0x90, 0x29, 0x8d, 0x53, 0x6d, - 0xef, 0x5c, 0x32, 0xf7, 0x4e, 0xce, 0xbd, 0x38, 0x8e, 0x4e, 0x2d, 0x12, - 0x62, 0xa3, 0x25, 0x84, 0x6a, 0x9b, 0x7a, 0x17, 0x9a, 0x33, 0x5d, 0xc4, - 0x4e, 0x25, 0x12, 0xf3, 0x1e, 0x98, 0x83, 0xf5, 0x5e, 0x1f, 0x16, 0x6a, - 0x17, 0xb9, 0x51, 0x5d, 0xfe, 0xfb, 0x9a, 0x02, 0x6a, 0xfd, 0x1b, 0xb9, - 0x10, 0xc7, 0x88, 0xe9, 0xfd, 0x8a, 0x10, 0xa7, 0xd6, 0x24, 0x06, 0xbc, - 0x48, 0xf4, 0xd5, 0xc0, 0x24, 0x86, 0x7c, 0x65, 0x2e, 0x2c, 0xed, 0x73, - 0xdc, 0xed, 0x53, 0x74, 0xfb, 0x08, 0xf1, 0xe1, 0xbd, 0x57, 0xc4, 0x5b, - 0x2d, 0x61, 0xbc, 0x4d, 0x4e, 0x9e, 0x2c, 0x2e, 0xea, 0x8a, 0xd4, 0x0d, - 0x78, 0x4e, 0x59, 0x7e, 0xc6, 0x34, 0xb4, 0xc3, 0xff, 0xad, 0xfe, 0x04, - 0x8c, 0x29, 0xdb, 0xbc, 0x78, 0x3d, 0x89, 0x27, 0x2b, 0x61, 0xf4, 0xee, - 0x53, 0xb2, 0xe9, 0x2a, 0x18, 0xce, 0x4a, 0x25, 0x9b, 0xd2, 0x20, 0x79, - 0xa3, 0x36, 0x1e, 0x35, 0x8d, 0xec, 0x65, 0xbe, 0xac, 0x4e, 0xde, 0x2e, - 0x06, 0x95, 0x63, 0x04, 0xf1, 0x6c, 0xfe, 0x7d, 0xcc, 0xfb, 0xa4, 0x86, - 0x49, 0xed, 0xe4, 0xc0, 0x27, 0xa4, 0x86, 0x05, 0x48, 0x44, 0x15, 0x7b, - 0xf2, 0x9e, 0xd3, 0x8d, 0x10, 0xf0, 0xb7, 0xf9, 0x70, 0xd1, 0x1c, 0xb6, - 0xea, 0xb1, 0x16, 0xe7, 0x5b, 0xb9, 0x07, 0xcb, 0x54, 0x44, 0x66, 0x96, - 0x8e, 0x15, 0xe1, 0x58, 0x11, 0x7c, 0x92, 0x13, 0xa2, 0xd2, 0x36, 0xe2, - 0x0b, 0x30, 0x19, 0x47, 0x04, 0x57, 0x0a, 0x5b, 0xfc, 0xa8, 0x09, 0x43, - 0x6d, 0x56, 0xb1, 0x3d, 0xaf, 0x29, 0xdd, 0x79, 0xe8, 0x5e, 0xdb, 0x8c, - 0x1e, 0xc6, 0x51, 0xc6, 0xc3, 0xba, 0x76, 0x4c, 0x55, 0x36, 0x4e, 0x07, - 0x50, 0x3d, 0xf5, 0x99, 0x78, 0x9f, 0x7a, 0xf8, 0xc6, 0xbd, 0xac, 0x17, - 0xc9, 0x00, 0xaa, 0xdc, 0xb9, 0x85, 0xf8, 0xb8, 0xad, 0x0e, 0x17, 0x39, - 0x5f, 0xf4, 0x2f, 0x03, 0xf0, 0x4e, 0x05, 0xe0, 0x9b, 0x52, 0x30, 0xd3, - 0x1e, 0x80, 0x67, 0x46, 0xfe, 0x56, 0x10, 0x30, 0xa7, 0xb1, 0x5d, 0x6f, - 0xc0, 0x78, 0x9e, 0x45, 0xda, 0xfc, 0x19, 0x06, 0xdc, 0xef, 0x2a, 0x9e, - 0xca, 0x6b, 0x08, 0x1d, 0x10, 0xa2, 0xd1, 0x16, 0x22, 0x96, 0xf4, 0x60, - 0xd6, 0x1c, 0x8e, 0x06, 0xb8, 0x8e, 0x61, 0x4b, 0x6a, 0x8e, 0x0f, 0xea, - 0x8c, 0x91, 0x39, 0xc7, 0xa8, 0x37, 0x4f, 0xa8, 0x4a, 0xef, 0xf4, 0x1e, - 0xc1, 0x98, 0xfa, 0x1e, 0xf0, 0x0a, 0x51, 0xd3, 0xd6, 0x34, 0x70, 0x9e, - 0xda, 0x3c, 0x13, 0x8b, 0xf5, 0x0e, 0x29, 0xc0, 0xfa, 0x39, 0x1f, 0xfc, - 0x53, 0xff, 0xc5, 0x3a, 0x2b, 0x44, 0xe1, 0x5e, 0x81, 0x77, 0xad, 0x6c, - 0xbc, 0x02, 0x46, 0xea, 0x24, 0xc2, 0xb8, 0xf4, 0xa2, 0x10, 0xdb, 0xdb, - 0x43, 0x78, 0xcd, 0x32, 0x76, 0x7d, 0xec, 0x15, 0xb8, 0x98, 0xcc, 0x0e, - 0xd6, 0x53, 0xb7, 0xae, 0x29, 0x51, 0x54, 0xe5, 0x8d, 0xcc, 0x15, 0x85, - 0x4b, 0x9f, 0x31, 0xf5, 0x9d, 0x4a, 0x10, 0x55, 0x27, 0x82, 0xe8, 0x98, - 0xf3, 0xa3, 0x62, 0x2a, 0x08, 0xef, 0xa4, 0x79, 0xfd, 0x41, 0xb8, 0xe3, - 0x58, 0x27, 0xd1, 0x8c, 0x8b, 0x2f, 0x1b, 0xf3, 0xc7, 0x89, 0x93, 0xed, - 0x88, 0xe2, 0x37, 0x05, 0x13, 0x17, 0x0b, 0x41, 0xa8, 0x27, 0x74, 0xd4, - 0xbb, 0xf5, 0x4e, 0x47, 0xb5, 0xe9, 0x61, 0x5e, 0x1c, 0xe5, 0x61, 0xb7, - 0x9e, 0x74, 0xf1, 0xd3, 0xa3, 0x74, 0xb0, 0xae, 0x6c, 0x98, 0x26, 0x95, - 0xf9, 0xec, 0x9c, 0x75, 0x43, 0xec, 0x8f, 0xa5, 0x59, 0x47, 0x2a, 0xe0, - 0xb3, 0xd7, 0xb1, 0x8e, 0xb0, 0x38, 0xb9, 0xba, 0x5f, 0xa1, 0xf8, 0xec, - 0xef, 0x6a, 0x7e, 0x88, 0x9a, 0x5f, 0xfc, 0x3f, 0x35, 0x5f, 0x85, 0x3a, - 0xe5, 0xc1, 0x98, 0x19, 0xc0, 0x6f, 0xac, 0xa6, 0x73, 0x8d, 0x08, 0x20, - 0xd5, 0xa6, 0x23, 0x72, 0xc2, 0xc2, 0x8b, 0xdc, 0x5b, 0xdc, 0x71, 0x6b, - 0x3d, 0x04, 0x76, 0x92, 0x53, 0x15, 0xd4, 0x86, 0xbb, 0x27, 0x82, 0xd4, - 0x29, 0x55, 0x59, 0x4f, 0x9d, 0xdf, 0x91, 0xbc, 0x21, 0xd2, 0x31, 0x23, - 0x1e, 0x57, 0x12, 0xa9, 0xbf, 0x43, 0x49, 0x3b, 0x62, 0xd4, 0xd1, 0x05, - 0x7d, 0x91, 0x83, 0x5d, 0x2e, 0x07, 0x67, 0x62, 0x25, 0xed, 0x58, 0x51, - 0x28, 0xf1, 0xef, 0x01, 0xea, 0xe7, 0xf5, 0xb6, 0x92, 0x76, 0xbe, 0x4a, - 0xff, 0xd3, 0xcb, 0xf1, 0x1e, 0x99, 0x36, 0xb2, 0xbd, 0xcc, 0xcf, 0x25, - 0x62, 0x63, 0x92, 0x19, 0x9c, 0xaf, 0xa5, 0xa6, 0x36, 0x07, 0x18, 0xe3, - 0x75, 0x71, 0x9a, 0xde, 0x62, 0x98, 0xfd, 0x46, 0xf3, 0x46, 0x74, 0x98, - 0x7c, 0x1f, 0x2d, 0x6b, 0xe9, 0x30, 0xfd, 0xc4, 0x28, 0xf3, 0xf4, 0x36, - 0x9f, 0x9d, 0xcc, 0x1b, 0xe9, 0x2e, 0x57, 0x53, 0xa5, 0xaf, 0x90, 0x31, - 0x49, 0x6f, 0x11, 0xc1, 0x5b, 0x2d, 0x52, 0x5f, 0x1b, 0xa8, 0xaf, 0x8b, - 0xba, 0x2a, 0xf1, 0x70, 0x4d, 0x84, 0x5a, 0x42, 0x5e, 0xc9, 0xcb, 0x4b, - 0x49, 0x21, 0xaa, 0xec, 0x20, 0x2a, 0x27, 0xcc, 0xf4, 0x7a, 0x25, 0x16, - 0x31, 0x95, 0xbb, 0xd8, 0xce, 0x1c, 0xce, 0x6d, 0xf2, 0xba, 0xde, 0xf6, - 0x84, 0x10, 0x21, 0x5b, 0x47, 0xcd, 0x84, 0x49, 0xdc, 0xc4, 0xfa, 0x8e, - 0xb8, 0xcf, 0x75, 0x04, 0xe7, 0x16, 0xc8, 0xe7, 0x08, 0xf9, 0x1c, 0xc6, - 0x9b, 0xb7, 0x70, 0x9a, 0x5a, 0xeb, 0xe9, 0x27, 0xa7, 0xb3, 0xe1, 0xa1, - 0x2d, 0xde, 0x6f, 0xf1, 0x71, 0xbf, 0xe4, 0x34, 0xdb, 0xbc, 0x78, 0x21, - 0x89, 0xcd, 0xc4, 0x47, 0xe6, 0x29, 0x25, 0xeb, 0x90, 0xdb, 0xa9, 0x0a, - 0x25, 0x4b, 0x17, 0xf5, 0x0d, 0xa7, 0xcf, 0xf0, 0x6d, 0x2f, 0x39, 0xdd, - 0x17, 0xbe, 0x95, 0xd3, 0x2c, 0xbe, 0xcc, 0xf7, 0x33, 0xf9, 0x83, 0x98, - 0xf1, 0xf9, 0x11, 0x99, 0xf2, 0x21, 0x30, 0xa5, 0x92, 0x5f, 0x0a, 0xfd, - 0x41, 0x36, 0x1e, 0x80, 0x91, 0x3e, 0x89, 0x08, 0x12, 0x13, 0x1a, 0xfe, - 0xaa, 0xc5, 0x87, 0x63, 0x31, 0x23, 0xb3, 0x93, 0x3c, 0x5d, 0x39, 0x37, - 0xc4, 0x88, 0x8c, 0x68, 0xd4, 0x53, 0xe2, 0xab, 0xaf, 0xd9, 0x0f, 0x6d, - 0xca, 0xe5, 0xe0, 0x1e, 0x8f, 0x9d, 0x8d, 0x6a, 0x30, 0x76, 0xfd, 0x84, - 0xb8, 0xb8, 0x30, 0x21, 0x44, 0x67, 0xbb, 0x79, 0xee, 0x23, 0xaf, 0x41, - 0x2d, 0x54, 0x71, 0x7e, 0xae, 0x34, 0x7e, 0xd5, 0x94, 0x06, 0xff, 0x01, - 0x77, 0xfc, 0xeb, 0x6f, 0x32, 0x8a, 0xcf, 0xf3, 0x12, 0x9f, 0x42, 0x04, - 0x6c, 0x33, 0x32, 0x4b, 0x3d, 0xdc, 0x97, 0x34, 0xb8, 0x7f, 0x4d, 0x4e, - 0x33, 0xbf, 0x7b, 0x92, 0xb1, 0xe8, 0x16, 0xbe, 0x73, 0xa9, 0x58, 0xe2, - 0x70, 0xbd, 0xb9, 0x15, 0x7f, 0xa3, 0x7b, 0x51, 0x63, 0xfe, 0x10, 0xcf, - 0xba, 0x1a, 0x45, 0xec, 0x4f, 0x56, 0xa2, 0x91, 0x98, 0x7f, 0x82, 0x98, - 0xdf, 0x3c, 0x4b, 0xad, 0x99, 0x6a, 0x67, 0x7e, 0x25, 0xdf, 0xbb, 0x94, - 0xde, 0xd9, 0x1e, 0xd7, 0x57, 0x3d, 0x32, 0xed, 0xc1, 0x9b, 0xd6, 0x5a, - 0x7a, 0x98, 0xb4, 0xf2, 0xc8, 0xac, 0xc4, 0xfb, 0x3a, 0xe5, 0x41, 0x62, - 0x3f, 0x7a, 0x87, 0x8a, 0x19, 0x6b, 0xad, 0xe2, 0x77, 0xb1, 0xef, 0x83, - 0x93, 0x29, 0xe1, 0xde, 0x6b, 0xc7, 0xac, 0x53, 0x4b, 0x70, 0xdf, 0x73, - 0x1b, 0xaf, 0x23, 0xb5, 0x03, 0x25, 0x7d, 0xd7, 0xbb, 0x98, 0xaf, 0xe7, - 0xcb, 0xf8, 0x7e, 0x96, 0xed, 0xbe, 0x29, 0x68, 0x95, 0xc4, 0xf0, 0x3a, - 0x62, 0x7c, 0x92, 0x38, 0x79, 0x78, 0x5a, 0xe0, 0x0d, 0xd6, 0x89, 0x42, - 0xd2, 0xb0, 0x76, 0x2a, 0x46, 0xba, 0x47, 0x49, 0x64, 0x57, 0x96, 0x6b, - 0xe4, 0xdd, 0xac, 0x73, 0xb8, 0x43, 0xe0, 0xe7, 0x16, 0xb4, 0x00, 0xb1, - 0xfd, 0x6f, 0xac, 0x59, 0xff, 0x51, 0xae, 0x91, 0xc9, 0x42, 0x25, 0x42, - 0x2d, 0xd4, 0x7c, 0x62, 0xb9, 0x9b, 0x58, 0x3e, 0x44, 0x3e, 0x8c, 0xd0, - 0x13, 0x6c, 0x26, 0x96, 0x57, 0xb4, 0x19, 0xd9, 0x2e, 0xfa, 0x69, 0xcf, - 0xea, 0x08, 0x71, 0x1a, 0xa7, 0x87, 0x1d, 0x41, 0x07, 0xe7, 0x4a, 0x4f, - 0x1b, 0x91, 0x0e, 0xe2, 0x5f, 0x65, 0x9f, 0xd7, 0xd8, 0x67, 0xa1, 0x4e, - 0x7a, 0xed, 0x00, 0x5e, 0x60, 0x1f, 0x33, 0xe9, 0xb8, 0x3a, 0x21, 0xf1, - 0x3f, 0x86, 0x44, 0x46, 0xe2, 0xdf, 0x59, 0xd6, 0x4a, 0xdf, 0x2f, 0xf1, - 0x4f, 0x0c, 0xe6, 0x89, 0xc1, 0x12, 0x07, 0x06, 0x24, 0x07, 0x6a, 0xe8, - 0x2b, 0x4e, 0xd0, 0x57, 0x54, 0xd9, 0x51, 0xe2, 0x5f, 0xf2, 0xa1, 0xe4, - 0x2d, 0xba, 0xca, 0x1c, 0x58, 0xef, 0xce, 0x27, 0x35, 0x20, 0x88, 0xa6, - 0x49, 0x43, 0x57, 0x95, 0xff, 0x14, 0x4f, 0x98, 0xe6, 0xfc, 0x76, 0xfa, - 0x83, 0x2f, 0xdb, 0x62, 0xcc, 0x7b, 0x10, 0xf7, 0x9c, 0x08, 0xa9, 0x12, - 0xe7, 0xf5, 0x93, 0x41, 0x84, 0x26, 0x25, 0x0f, 0xb2, 0xe3, 0x11, 0x62, - 0xc4, 0xf2, 0xfc, 0x96, 0xf8, 0x8f, 0x12, 0x17, 0xaa, 0xd2, 0xcd, 0x31, - 0x6a, 0xa6, 0x74, 0xb4, 0x4e, 0x1a, 0x03, 0x27, 0x70, 0x55, 0xbc, 0x11, - 0x33, 0x33, 0x7b, 0x99, 0xff, 0x6d, 0xc9, 0x18, 0xf7, 0x4a, 0xc7, 0xdd, - 0x37, 0xc7, 0x70, 0x39, 0xe1, 0x6c, 0xb1, 0x82, 0x65, 0xaf, 0xad, 0x61, - 0x4b, 0x1e, 0xd8, 0x96, 0xa7, 0xd9, 0x35, 0x3d, 0xab, 0xfc, 0xb8, 0x86, - 0xc3, 0x44, 0x7f, 0xbf, 0xee, 0x30, 0xff, 0x01, 0xea, 0x7d, 0xe9, 0x9d, - 0x92, 0x07, 0xff, 0x79, 0xf9, 0x8c, 0xf9, 0x2b, 0x4f, 0xe9, 0xef, 0xdb, - 0xde, 0xc5, 0x33, 0xe7, 0x16, 0x62, 0xb0, 0x93, 0x18, 0xec, 0x61, 0x8e, - 0xb6, 0x5b, 0xe4, 0x36, 0xf3, 0x99, 0x55, 0x03, 0xf4, 0xd4, 0x4d, 0x7d, - 0xd5, 0xd4, 0xb4, 0x7d, 0xd4, 0xa7, 0x77, 0xcd, 0x4a, 0x7a, 0x70, 0x87, - 0xda, 0xd9, 0x41, 0xdd, 0xec, 0x52, 0x1e, 0x72, 0xb1, 0x95, 0x26, 0x8e, - 0x34, 0x25, 0x4d, 0x5f, 0xeb, 0x63, 0xed, 0x38, 0x14, 0x5e, 0xf4, 0xdf, - 0x32, 0x4e, 0xe9, 0xb9, 0x8d, 0xb8, 0x2c, 0xbf, 0xcf, 0xba, 0x3a, 0xb4, - 0x16, 0xaa, 0xbd, 0x56, 0x51, 0x6d, 0x79, 0xc6, 0x50, 0xf1, 0x03, 0xea, - 0xec, 0xc2, 0x26, 0x79, 0xd6, 0xe0, 0xba, 0xd8, 0x16, 0x31, 0x63, 0xd1, - 0x83, 0xc4, 0xd5, 0xab, 0xdf, 0x39, 0x7b, 0x94, 0xf0, 0x36, 0x9c, 0x57, - 0x6f, 0xfa, 0x68, 0xa9, 0x0f, 0x6b, 0x6f, 0xe2, 0x4d, 0xc3, 0x33, 0x2d, - 0x51, 0xe2, 0x51, 0x62, 0x4d, 0x43, 0xe1, 0x95, 0x4a, 0xbc, 0xf1, 0x4a, - 0x10, 0xaf, 0xbf, 0x22, 0xc4, 0x68, 0x12, 0x3c, 0xe1, 0x08, 0xf1, 0x50, - 0x72, 0x0d, 0x8e, 0xeb, 0xb1, 0xe8, 0x0b, 0xae, 0x8f, 0x75, 0xe8, 0x63, - 0x8d, 0x81, 0xb3, 0xb8, 0x21, 0x0a, 0x2e, 0xa7, 0x13, 0xe4, 0x5b, 0x09, - 0x8b, 0xae, 0xdf, 0xad, 0xd5, 0x70, 0x81, 0xf8, 0x0b, 0x11, 0x7f, 0xbf, - 0xa3, 0xe6, 0x5e, 0x2d, 0x6b, 0xee, 0xaa, 0x02, 0xf9, 0xd8, 0x16, 0x40, - 0x8f, 0x5c, 0x0b, 0x71, 0x38, 0x7c, 0x13, 0x87, 0xac, 0xbd, 0xdc, 0xf3, - 0xb3, 0x96, 0x11, 0xef, 0x24, 0x1e, 0x67, 0x2c, 0xc3, 0xe9, 0xa0, 0x9f, - 0x1d, 0x76, 0x31, 0x49, 0xed, 0x8d, 0x49, 0x5c, 0x12, 0x87, 0xcc, 0xc9, - 0x3e, 0xf6, 0x39, 0xcd, 0x3e, 0x63, 0x65, 0x3f, 0xfb, 0x1e, 0x12, 0x69, - 0xe9, 0x67, 0xa3, 0xc4, 0xe0, 0x3e, 0xd7, 0xcf, 0x4a, 0xff, 0x2a, 0xbd, - 0xab, 0x8c, 0xb3, 0xdd, 0x8d, 0xb3, 0xfb, 0x26, 0x0e, 0xa9, 0x61, 0xb5, - 0x12, 0x7f, 0x0f, 0x60, 0xec, 0xa5, 0x1a, 0x84, 0xcc, 0x3b, 0x71, 0x3e, - 0xf3, 0x80, 0x1a, 0x31, 0xa1, 0xd7, 0xdb, 0x25, 0x3c, 0x6e, 0x2e, 0xa6, - 0x90, 0xcf, 0xbf, 0x23, 0xf2, 0x61, 0xc3, 0x39, 0xeb, 0x7a, 0xd2, 0x01, - 0x7a, 0xc4, 0x1b, 0xc2, 0x13, 0x33, 0xce, 0x6d, 0xa1, 0x2f, 0x6b, 0xf2, - 0x96, 0xfc, 0xdd, 0x9a, 0xc2, 0xfb, 0x02, 0x75, 0xa5, 0x75, 0xaa, 0xf4, - 0x74, 0x23, 0xe4, 0xdc, 0xa8, 0x59, 0xf2, 0x77, 0xb1, 0xc2, 0xa7, 0xaa, - 0xd4, 0x73, 0x4f, 0x9b, 0x1c, 0x37, 0x4d, 0x0d, 0x59, 0x1c, 0xfb, 0x1b, - 0x5d, 0x1e, 0x21, 0x06, 0x87, 0xa5, 0xd7, 0xa2, 0x2f, 0xe1, 0x59, 0x7d, - 0x89, 0xa6, 0xee, 0xf6, 0xc2, 0x94, 0x6d, 0x8e, 0xf2, 0x10, 0xd7, 0xa0, - 0x99, 0x83, 0x4a, 0x9a, 0xb5, 0x79, 0x2f, 0xf1, 0xd5, 0xc3, 0x1a, 0x7c, - 0xd9, 0x6a, 0x26, 0x87, 0x05, 0xeb, 0xd0, 0x0d, 0xb1, 0xcf, 0x5c, 0x3c, - 0xd3, 0xc9, 0xf3, 0x5c, 0x9c, 0x71, 0x57, 0xb3, 0x76, 0xaf, 0x63, 0xbd, - 0xe6, 0x69, 0x91, 0x39, 0xfd, 0x32, 0x26, 0x1a, 0x57, 0xb5, 0x19, 0x03, - 0x1b, 0xbd, 0x01, 0xe4, 0x88, 0xf7, 0x57, 0x59, 0x83, 0xf2, 0xdc, 0xd3, - 0xc9, 0xa2, 0x91, 0xca, 0x62, 0x04, 0x1b, 0xb9, 0xa7, 0x3c, 0x03, 0x39, - 0xff, 0x18, 0x2b, 0x9d, 0x91, 0xb7, 0xb3, 0xb6, 0x8d, 0x97, 0xb9, 0x7d, - 0x05, 0x09, 0x4b, 0x72, 0x7b, 0x9e, 0xb5, 0x6d, 0xdc, 0xe5, 0xb6, 0x91, - 0x92, 0x7c, 0xae, 0x28, 0xd7, 0xb4, 0x4f, 0x20, 0x39, 0x7c, 0x6b, 0x3d, - 0x93, 0x78, 0x5e, 0xeb, 0x93, 0xde, 0x36, 0x9f, 0x97, 0x35, 0x49, 0xd6, - 0xa2, 0xc5, 0xba, 0xa4, 0xc9, 0xfb, 0x84, 0x4c, 0xe3, 0xc4, 0x1e, 0xe1, - 0x29, 0xdd, 0x49, 0x9c, 0xfb, 0xd0, 0x1b, 0x4c, 0xa5, 0xee, 0x43, 0x26, - 0x32, 0xa7, 0x61, 0x53, 0xbe, 0xa1, 0x2f, 0x60, 0x83, 0xef, 0x28, 0xb0, - 0xfe, 0x44, 0x43, 0xe6, 0x96, 0x3b, 0x89, 0x8f, 0x73, 0x9a, 0x16, 0x9a, - 0x58, 0x2e, 0xdf, 0xc1, 0x67, 0xb9, 0xdb, 0xde, 0x49, 0xa4, 0x7f, 0xdf, - 0x9d, 0xc4, 0x0b, 0xe4, 0xc7, 0x58, 0xe9, 0x4e, 0xc2, 0xf9, 0x5e, 0x8b, - 0x17, 0x33, 0x61, 0xec, 0xfe, 0xa8, 0x5d, 0xc5, 0xe5, 0x9c, 0x11, 0x39, - 0x8e, 0xdd, 0xe8, 0x77, 0xef, 0x1f, 0x90, 0xf5, 0xdb, 0xbb, 0xf0, 0x4f, - 0xed, 0xf2, 0xfe, 0x21, 0x25, 0xd7, 0x38, 0xce, 0xe5, 0x43, 0xa3, 0xde, - 0xac, 0x67, 0x2d, 0xd8, 0xb1, 0x46, 0xc1, 0x43, 0xc9, 0x3b, 0x5d, 0x6c, - 0x8f, 0x17, 0x8d, 0x74, 0x94, 0xcf, 0xee, 0x99, 0x90, 0x35, 0xf2, 0x71, - 0x9e, 0x17, 0xa1, 0x35, 0xda, 0xbd, 0xaa, 0xc8, 0x37, 0x45, 0xae, 0x28, - 0x86, 0x73, 0x18, 0xf2, 0x8e, 0x20, 0x71, 0xce, 0xab, 0x18, 0xf3, 0x1f, - 0x7a, 0x8d, 0x54, 0xbd, 0x8b, 0x99, 0xc7, 0x79, 0x76, 0x93, 0x7f, 0x7b, - 0xe5, 0xb9, 0x0f, 0x1b, 0x39, 0xe6, 0x07, 0x6b, 0xe4, 0x59, 0xf4, 0x73, - 0x91, 0x5d, 0x66, 0x38, 0x0b, 0x8a, 0xc6, 0xdc, 0x80, 0xfa, 0x24, 0x35, - 0xfc, 0x71, 0x6a, 0xb8, 0xf4, 0x2c, 0xbd, 0xf4, 0x2c, 0x4d, 0xf3, 0x71, - 0xaf, 0x91, 0xb9, 0x4e, 0xbd, 0xe3, 0x98, 0x7d, 0xbd, 0x8a, 0xd1, 0x7b, - 0x82, 0xfa, 0xbf, 0x53, 0x29, 0x8d, 0xb9, 0xb2, 0x3c, 0xe6, 0xdd, 0x05, - 0x4d, 0xe9, 0xcc, 0x83, 0xba, 0x83, 0xe8, 0x36, 0x8b, 0xda, 0x51, 0xac, - 0x24, 0xc7, 0x4c, 0xb9, 0x66, 0xc6, 0xd6, 0xca, 0xd8, 0x14, 0x5c, 0x69, - 0x91, 0xef, 0xb6, 0xca, 0x38, 0x9c, 0x2a, 0x3b, 0x45, 0xed, 0x7d, 0xc5, - 0x57, 0xd6, 0x2f, 0xcf, 0x16, 0x6b, 0x19, 0x9c, 0x30, 0x42, 0x3e, 0xb3, - 0x0e, 0xa3, 0xb4, 0x81, 0x41, 0xb3, 0x19, 0x39, 0xdd, 0x8f, 0x2d, 0xd6, - 0x17, 0x82, 0x3a, 0xc9, 0xf7, 0x81, 0xa7, 0x5e, 0xe2, 0x19, 0xde, 0xbc, - 0x86, 0x58, 0xf2, 0x39, 0x1c, 0xd3, 0x77, 0xd1, 0x0f, 0x6e, 0xc5, 0xeb, - 0xae, 0x9e, 0xd8, 0xc4, 0xb3, 0x42, 0x0c, 0xd9, 0xb2, 0xd6, 0xdd, 0x32, - 0xb6, 0xbc, 0x93, 0xb8, 0x24, 0xb2, 0xa5, 0x31, 0x9c, 0x6d, 0x56, 0x86, - 0x71, 0x7d, 0xa3, 0xbb, 0x3b, 0xa8, 0xbb, 0x15, 0xa6, 0xe7, 0xae, 0x4a, - 0xea, 0xee, 0x56, 0xeb, 0xcf, 0xf1, 0x14, 0x39, 0x5e, 0x65, 0x7e, 0x26, - 0x9e, 0x0e, 0xcb, 0x31, 0xa9, 0xaf, 0x35, 0x4b, 0xc7, 0xff, 0x90, 0x63, - 0xca, 0x39, 0x64, 0x3d, 0x3c, 0x2f, 0x0e, 0xd5, 0xca, 0x31, 0x07, 0x95, - 0x8d, 0xe4, 0xd4, 0x3c, 0x4b, 0xef, 0x0f, 0xc8, 0xa7, 0x05, 0xe6, 0xa7, - 0xf1, 0x36, 0x7c, 0x6a, 0x24, 0x9f, 0x9e, 0x58, 0xc2, 0xa7, 0x83, 0x79, - 0xe9, 0xbd, 0x14, 0xb4, 0xb4, 0xfd, 0x29, 0x75, 0x45, 0x08, 0x7f, 0xdb, - 0x0d, 0x71, 0xc6, 0xf5, 0xbe, 0xd2, 0xef, 0xa6, 0x95, 0xee, 0x59, 0xa9, - 0x4f, 0xd5, 0x08, 0x92, 0x4f, 0x1b, 0xc8, 0xa7, 0x7e, 0xf2, 0xe9, 0x69, - 0x53, 0x34, 0xee, 0x48, 0x1a, 0xa9, 0x79, 0xfa, 0x9a, 0x75, 0xe4, 0xd4, - 0x3b, 0xe4, 0xd4, 0x48, 0xb1, 0xa4, 0x53, 0xfb, 0xb8, 0xee, 0xfb, 0xa9, - 0x53, 0xeb, 0x8a, 0x52, 0xdb, 0x1c, 0xe2, 0x3f, 0x80, 0xcf, 0xc9, 0xa9, - 0xd9, 0xa4, 0xab, 0x53, 0xd6, 0xef, 0x90, 0xd8, 0x75, 0x5a, 0xf2, 0x89, - 0x3a, 0x95, 0x2f, 0x36, 0x59, 0xa7, 0xb9, 0xa6, 0xf1, 0xbc, 0x71, 0xbd, - 0x87, 0x9c, 0xf2, 0xb5, 0x1b, 0xe7, 0x2e, 0x13, 0xbb, 0x81, 0x18, 0xf4, - 0x88, 0x2d, 0xd7, 0xc4, 0x1a, 0xcb, 0x3a, 0x79, 0x90, 0xf8, 0xef, 0xa1, - 0x66, 0xf4, 0x16, 0x6d, 0xec, 0x2d, 0x2e, 0xdd, 0x53, 0xd6, 0xa1, 0xdb, - 0xee, 0xcb, 0xb8, 0xff, 0xf6, 0xed, 0xac, 0x57, 0xb7, 0x6d, 0x97, 0x7c, - 0x5d, 0xe6, 0x97, 0x7c, 0x1d, 0xce, 0xbf, 0xa6, 0xde, 0xfe, 0x1d, 0x79, - 0xa7, 0x26, 0xc4, 0x51, 0x4b, 0xde, 0x49, 0x48, 0xdf, 0xa3, 0x60, 0xc8, - 0x92, 0xf7, 0x6a, 0x1d, 0x51, 0x15, 0x46, 0xe4, 0xfb, 0xf8, 0x4a, 0x64, - 0xc3, 0x4e, 0xdc, 0xe7, 0xd6, 0x48, 0x43, 0xef, 0x63, 0xad, 0x9b, 0x2f, - 0x9f, 0xfd, 0x66, 0x78, 0x3e, 0x7b, 0x87, 0x75, 0xea, 0x28, 0xcf, 0x79, - 0x43, 0x85, 0xaf, 0xc4, 0x7c, 0x58, 0xc5, 0x88, 0x79, 0xf3, 0x8e, 0xd2, - 0xd5, 0xb1, 0xc3, 0x7c, 0x36, 0x56, 0x58, 0xac, 0x51, 0xd4, 0x4c, 0x53, - 0x88, 0xad, 0xe6, 0x7f, 0x8b, 0x2d, 0xdf, 0x7a, 0x57, 0x88, 0x49, 0xc6, - 0x70, 0xc1, 0xc2, 0x6e, 0x1f, 0x62, 0x7d, 0xd7, 0x59, 0xd7, 0x3f, 0x58, - 0x63, 0x64, 0x0a, 0x4a, 0xa2, 0x77, 0x83, 0x22, 0xbd, 0x9e, 0xa7, 0xab, - 0x82, 0xef, 0xb4, 0xd0, 0x1b, 0x5d, 0x61, 0x06, 0xfd, 0xfc, 0x7e, 0xc6, - 0x32, 0x22, 0x47, 0xf8, 0x77, 0x4b, 0x4a, 0x8e, 0x21, 0x44, 0x87, 0x25, - 0xef, 0xbb, 0x46, 0xd4, 0xdc, 0x44, 0x56, 0x54, 0x99, 0x17, 0xa8, 0x4d, - 0x46, 0x66, 0x44, 0x91, 0x3e, 0x3b, 0x0a, 0x57, 0x67, 0xf9, 0x4c, 0x9b, - 0x88, 0xe0, 0xef, 0x5d, 0xff, 0x1c, 0xa5, 0x66, 0x35, 0xe0, 0x1f, 0x5c, - 0xdd, 0x52, 0xb1, 0xed, 0x25, 0x23, 0xa5, 0x2a, 0x7b, 0x70, 0xc9, 0x32, - 0xf4, 0x9f, 0x32, 0x6e, 0x6a, 0xcd, 0x8b, 0x9d, 0x3c, 0x3f, 0x71, 0x8e, - 0x6c, 0x9f, 0xb7, 0x56, 0xd1, 0x58, 0x3b, 0x7e, 0xdc, 0x22, 0x6b, 0xf7, - 0x2e, 0xf4, 0x34, 0xef, 0xe4, 0x47, 0x45, 0xdd, 0x94, 0xaa, 0x6c, 0xa2, - 0x27, 0x09, 0x4d, 0x85, 0xb0, 0x7d, 0xb5, 0x10, 0xab, 0x56, 0x3b, 0xf8, - 0x3c, 0xd9, 0x14, 0x3f, 0xcb, 0x1a, 0x74, 0xa8, 0xd6, 0x48, 0x03, 0xbf, - 0xc0, 0x66, 0x7a, 0xd9, 0x54, 0x5b, 0x0e, 0xb8, 0x53, 0xae, 0xf1, 0x17, - 0xe8, 0x94, 0x1e, 0xd8, 0x0a, 0x49, 0xbf, 0xe5, 0xe2, 0xb7, 0x74, 0xaf, - 0xc4, 0xd4, 0x1d, 0xc8, 0x8a, 0x4a, 0xd3, 0xe8, 0x9b, 0x65, 0xbd, 0xfd, - 0x20, 0xb6, 0x5c, 0x7f, 0x78, 0x56, 0x7a, 0x60, 0x33, 0xba, 0x5e, 0x11, - 0xcc, 0xc5, 0xf3, 0xcc, 0x45, 0xcc, 0x09, 0xd2, 0x32, 0xf0, 0xac, 0xe5, - 0x84, 0x94, 0x41, 0xe5, 0x51, 0xf2, 0xa1, 0xcf, 0x5f, 0x49, 0x0f, 0xe1, - 0xd0, 0x3f, 0x78, 0x50, 0x7d, 0x40, 0x7a, 0x8a, 0x00, 0xb5, 0xa6, 0xa9, - 0x37, 0xc8, 0xfc, 0xec, 0x48, 0x4a, 0xff, 0x41, 0xac, 0x1f, 0xb8, 0x21, - 0x3a, 0xe9, 0x71, 0x3b, 0xcb, 0x1e, 0xf7, 0x89, 0xe9, 0x34, 0x3d, 0xb0, - 0xa6, 0xc8, 0x3b, 0xb6, 0x54, 0x1b, 0x0f, 0xa4, 0x8f, 0x4a, 0x1f, 0x22, - 0xd7, 0xa0, 0xe3, 0x6a, 0x52, 0x62, 0x57, 0xc7, 0x70, 0xbb, 0x11, 0xc9, - 0x42, 0xde, 0xe9, 0xdc, 0xea, 0x2f, 0xa0, 0xa7, 0xbf, 0xe3, 0x39, 0xa0, - 0x6f, 0x62, 0x2c, 0x86, 0x5f, 0x88, 0xba, 0xa4, 0x17, 0x7d, 0xee, 0x59, - 0x2e, 0xa2, 0xa7, 0xc9, 0xfb, 0x73, 0xf4, 0x09, 0x5e, 0x9e, 0x99, 0xf7, - 0x10, 0x4b, 0x5f, 0xb6, 0x0c, 0xbd, 0x5a, 0x8f, 0xec, 0x78, 0x1d, 0xcf, - 0xa8, 0xf7, 0x53, 0x57, 0x2f, 0xe4, 0x1e, 0x65, 0x3d, 0xf7, 0xb4, 0x47, - 0x78, 0x06, 0x68, 0x9c, 0xca, 0x8a, 0x7a, 0xfa, 0x41, 0x9e, 0x97, 0x51, - 0xdb, 0x16, 0xa7, 0xdf, 0x5e, 0xdc, 0x2b, 0x0f, 0x7e, 0x68, 0x99, 0x70, - 0xdc, 0xdf, 0x41, 0xbd, 0x7b, 0x9a, 0xe7, 0x68, 0x73, 0xb9, 0xde, 0x51, - 0x8a, 0x4b, 0xad, 0xb0, 0x2d, 0xb4, 0xdc, 0x0b, 0xfd, 0xc1, 0xdb, 0xc4, - 0xb4, 0x4e, 0x7a, 0x1f, 0x5f, 0xa9, 0xdf, 0x9f, 0x4d, 0x37, 0xe8, 0x8f, - 0xb0, 0xde, 0xcd, 0x13, 0x2b, 0x4f, 0xac, 0xb6, 0x64, 0x2c, 0xf3, 0x32, - 0x16, 0xfa, 0x4b, 0xe7, 0x7e, 0x0f, 0x7d, 0x49, 0x12, 0x08, 0xcd, 0xfd, - 0x35, 0x79, 0xe5, 0x69, 0x0d, 0x21, 0xbb, 0x8b, 0x31, 0xbe, 0xfa, 0xaf, - 0xdc, 0x9a, 0xfe, 0x49, 0xf4, 0x7b, 0xd8, 0x67, 0xc2, 0x02, 0x9e, 0x39, - 0x01, 0x3c, 0x3d, 0x19, 0xa3, 0x2f, 0xa7, 0x8f, 0x3c, 0xa1, 0xe1, 0xfb, - 0xd3, 0x95, 0xf8, 0xd1, 0x74, 0x10, 0x3b, 0xa6, 0xdd, 0xbb, 0xae, 0x0d, - 0x75, 0x7c, 0xaf, 0x83, 0x67, 0xbb, 0x59, 0x6b, 0x35, 0x3e, 0xa2, 0x87, - 0x5a, 0xa1, 0x78, 0x10, 0x39, 0x00, 0x5d, 0x27, 0x6e, 0x6a, 0x5b, 0x7e, - 0x44, 0x2e, 0x0b, 0x61, 0xae, 0x96, 0x3a, 0xf9, 0xbc, 0xfb, 0x7d, 0x84, - 0xfe, 0x31, 0x23, 0x31, 0x98, 0x27, 0x06, 0xf3, 0xc4, 0xe4, 0x4d, 0x4f, - 0x2d, 0xb1, 0x1c, 0xa7, 0x8f, 0x7e, 0x4e, 0x94, 0xb0, 0xf1, 0xb5, 0x38, - 0x6a, 0x9e, 0x24, 0x7f, 0x55, 0x6a, 0x28, 0xf0, 0xcf, 0xb9, 0x88, 0xbe, - 0xa9, 0x28, 0xf3, 0xff, 0xb7, 0xe5, 0xfc, 0x9f, 0xf1, 0x97, 0xf4, 0xc2, - 0x70, 0x66, 0xd1, 0x80, 0xc9, 0x7c, 0x83, 0xbe, 0x21, 0x3f, 0x34, 0xa8, - 0x21, 0x1b, 0x0d, 0xc1, 0x18, 0x98, 0x84, 0xa7, 0x35, 0x08, 0xb9, 0x76, - 0xa0, 0xe0, 0xae, 0x51, 0x88, 0x31, 0xea, 0x9b, 0xcc, 0xc1, 0xbf, 0xe7, - 0xd0, 0xea, 0x61, 0x3e, 0x1c, 0xc8, 0xb3, 0x35, 0xf0, 0x69, 0x41, 0xde, - 0x7d, 0xc6, 0xd2, 0xdd, 0xf8, 0xc2, 0x1d, 0xf3, 0x93, 0x42, 0x0a, 0xfb, - 0xf3, 0x1f, 0x88, 0xfd, 0xe1, 0x92, 0xc6, 0xa7, 0x79, 0x3e, 0x0a, 0x1d, - 0x28, 0x7b, 0x21, 0x72, 0xb8, 0x9a, 0xeb, 0xbd, 0x9a, 0x74, 0xbd, 0x3f, - 0x6b, 0xe4, 0x80, 0x7a, 0xd4, 0x64, 0xb1, 0xab, 0xb9, 0x21, 0xc6, 0x62, - 0x89, 0x40, 0x29, 0xa6, 0x84, 0x7e, 0x04, 0x15, 0xc4, 0xae, 0x3c, 0x23, - 0x49, 0xfd, 0x90, 0xbf, 0x79, 0x3e, 0x51, 0x9d, 0x88, 0x97, 0xeb, 0x72, - 0x1e, 0x93, 0x6d, 0x81, 0xb2, 0x5f, 0x5d, 0xf4, 0x22, 0x1d, 0x7c, 0x26, - 0xbd, 0xc8, 0x57, 0xa2, 0x2f, 0xdc, 0x71, 0x53, 0x73, 0xb2, 0x7c, 0x63, - 0x34, 0x2f, 0xef, 0xb4, 0x5a, 0xe8, 0x88, 0x15, 0x9c, 0x62, 0xe4, 0x47, - 0x5a, 0x63, 0xfa, 0x30, 0xc7, 0x73, 0x74, 0x9d, 0x5c, 0xde, 0x43, 0xbf, - 0xcc, 0x77, 0x8a, 0x2d, 0xec, 0x23, 0xb5, 0xec, 0x2f, 0xb8, 0xd6, 0x2f, - 0x9a, 0x25, 0xb6, 0x87, 0xf3, 0x6f, 0x79, 0x54, 0x53, 0xae, 0x33, 0x91, - 0x1a, 0x66, 0x3c, 0x0b, 0xba, 0xf4, 0xd6, 0x0e, 0xb5, 0x2d, 0xe1, 0xf6, - 0xcf, 0xaa, 0x32, 0x0e, 0x37, 0x1e, 0xb6, 0x49, 0xcd, 0x32, 0x32, 0xa7, - 0x90, 0x70, 0xfa, 0xa5, 0x39, 0x58, 0x26, 0x63, 0x68, 0x8a, 0xf4, 0x33, - 0x9e, 0x43, 0x61, 0x57, 0x0f, 0xf9, 0x8c, 0xf3, 0xe5, 0x3d, 0x1b, 0x2a, - 0x21, 0xb0, 0x22, 0xe9, 0x9e, 0xf9, 0xcb, 0xff, 0x5f, 0x43, 0xa5, 0x0f, - 0x91, 0x58, 0xfc, 0x5f, 0x69, 0xd7, 0x8a, 0xc0, 0xa8, 0x1a, 0x00, 0x00, - 0x00 }; + 0xbd, 0x58, 0x6d, 0x70, 0x5c, 0xd5, 0x79, 0x7e, 0xce, 0xbd, 0x77, 0xb5, + 0xd7, 0xd2, 0x4a, 0xba, 0xb2, 0xd6, 0x66, 0x5d, 0xdc, 0xfa, 0x1e, 0x74, + 0x57, 0x52, 0x58, 0x01, 0x77, 0x6d, 0x01, 0xeb, 0xe6, 0xb6, 0xbe, 0xc8, + 0xb2, 0xbc, 0xfe, 0x00, 0xe4, 0xc0, 0x4c, 0xe4, 0x96, 0x8e, 0x37, 0xc6, + 0x18, 0xd9, 0x90, 0xa9, 0x28, 0xfc, 0x58, 0x37, 0x4c, 0xbd, 0x95, 0x65, + 0x63, 0xc3, 0x4a, 0x6b, 0x0c, 0xb1, 0x4c, 0xda, 0x99, 0x78, 0x84, 0xb1, + 0x4c, 0x22, 0x7b, 0x0d, 0xe4, 0x07, 0x49, 0xc3, 0xa0, 0xc1, 0x0e, 0x08, + 0x06, 0xf3, 0x31, 0x6d, 0x67, 0x98, 0xe9, 0xa4, 0xf5, 0x18, 0xf3, 0x11, + 0x92, 0x18, 0x87, 0x4e, 0x3a, 0xa2, 0x10, 0x9f, 0x3e, 0x67, 0x77, 0xc5, + 0x57, 0x32, 0xd3, 0xfe, 0xaa, 0x66, 0x56, 0x7b, 0xf7, 0xec, 0xf9, 0x78, + 0xcf, 0xfb, 0x3e, 0xef, 0xf3, 0x3e, 0xef, 0x5e, 0x21, 0x50, 0x8f, 0xda, + 0x5f, 0x23, 0x5f, 0xdd, 0xdf, 0x1a, 0xba, 0x2f, 0x7d, 0xf5, 0x75, 0x57, + 0xf3, 0xf1, 0x3a, 0xe1, 0xd4, 0x59, 0xf8, 0x7f, 0xfc, 0x33, 0x01, 0x67, + 0xce, 0x0e, 0xfd, 0x82, 0x6d, 0x04, 0x85, 0xcb, 0x7b, 0x3c, 0xd8, 0x66, + 0x10, 0x77, 0x6f, 0xf7, 0x80, 0x70, 0x2a, 0xe5, 0xae, 0xc4, 0xef, 0x54, + 0x21, 0x6e, 0x41, 0x8f, 0xff, 0x71, 0xf0, 0xe9, 0x35, 0xcf, 0x5d, 0x2f, + 0x2f, 0x1e, 0x36, 0x61, 0x3b, 0xc1, 0x5e, 0xcb, 0x69, 0x87, 0xbd, 0x98, + 0x6b, 0xfe, 0xb1, 0xe3, 0x2f, 0x04, 0x9a, 0xe6, 0xf6, 0x52, 0x6a, 0xc4, + 0x8f, 0x62, 0xd8, 0x4f, 0x60, 0x77, 0xc9, 0x40, 0xe8, 0x44, 0xb1, 0xcb, + 0x9b, 0x55, 0x5b, 0x7c, 0xe9, 0xef, 0x86, 0x5a, 0x72, 0xda, 0x97, 0x89, + 0x5e, 0x13, 0xe1, 0x77, 0xbc, 0xc5, 0xd8, 0x5d, 0x4e, 0x60, 0xa4, 0x6c, + 0xe3, 0xac, 0x39, 0x82, 0xde, 0xf2, 0xdc, 0x3a, 0x97, 0xeb, 0x3a, 0xb1, + 0xe7, 0xcb, 0x6b, 0xdd, 0xdd, 0x48, 0x25, 0xf6, 0xc0, 0x40, 0x2e, 0xee, + 0x71, 0x5d, 0x9b, 0xbb, 0x07, 0xb2, 0x93, 0xfb, 0x14, 0xea, 0xba, 0x5d, + 0xee, 0x51, 0xe0, 0x7a, 0xe9, 0x1e, 0x85, 0xde, 0x2b, 0xc3, 0xcf, 0x6f, + 0xa9, 0xe7, 0x3a, 0x16, 0xe3, 0x19, 0xee, 0xff, 0x74, 0xd9, 0xc1, 0xc9, + 0xb2, 0x87, 0xe7, 0xcb, 0x2e, 0x7e, 0x54, 0x8e, 0xe3, 0xa9, 0xb2, 0x9d, + 0xb3, 0x03, 0xf4, 0xc7, 0x47, 0x77, 0xaa, 0x84, 0x87, 0xc2, 0x1f, 0x05, + 0xde, 0xa1, 0x43, 0x46, 0x2c, 0xf3, 0x37, 0xd7, 0xa1, 0x7f, 0xfe, 0x71, + 0x1b, 0x1b, 0x4a, 0x8b, 0x73, 0xd1, 0x00, 0x9c, 0x23, 0xe0, 0x5f, 0x67, + 0xa3, 0x9f, 0x7b, 0x14, 0xb8, 0x7f, 0x58, 0x1e, 0xe1, 0xcb, 0xc6, 0xbb, + 0x45, 0xdb, 0x6e, 0x1e, 0x5d, 0xa8, 0xe7, 0xe0, 0x57, 0xc5, 0x8b, 0xea, + 0x42, 0xda, 0xc1, 0x2b, 0xcb, 0x95, 0x6a, 0x0c, 0x50, 0x68, 0xe8, 0x2e, + 0xc0, 0x0c, 0x64, 0x76, 0x9d, 0x29, 0xd0, 0x7b, 0x95, 0xd7, 0x39, 0x2a, + 0x6e, 0xb9, 0xc5, 0x08, 0x60, 0x8b, 0xc0, 0xb5, 0xda, 0xa6, 0x32, 0xd8, + 0x57, 0xe6, 0xbd, 0x68, 0xcf, 0x48, 0x19, 0xe1, 0x5f, 0x76, 0x98, 0x98, + 0x88, 0xe3, 0xfe, 0xb7, 0xbb, 0x2d, 0x7c, 0x5c, 0x94, 0x89, 0x4e, 0xf3, + 0x7e, 0xec, 0x2c, 0xe6, 0x71, 0x47, 0x11, 0x05, 0x23, 0x18, 0xc2, 0x37, + 0xba, 0x03, 0xde, 0x33, 0xc4, 0xf7, 0xcb, 0xb0, 0x5b, 0x83, 0xd3, 0x97, + 0xdf, 0xdb, 0x2e, 0x0f, 0x87, 0x06, 0x90, 0x1d, 0x03, 0xfa, 0x4a, 0x02, + 0xa7, 0x32, 0x02, 0x5b, 0xfc, 0xcb, 0x50, 0x70, 0xba, 0xb1, 0xb7, 0x2c, + 0xb3, 0x05, 0x7e, 0x77, 0xd5, 0x28, 0xec, 0x45, 0xc1, 0x6d, 0xd6, 0xf2, + 0x12, 0xec, 0x96, 0x60, 0xc0, 0x4a, 0x8f, 0xb5, 0xcd, 0x1e, 0x13, 0x32, + 0xbf, 0xc2, 0x94, 0x21, 0x20, 0x33, 0x9d, 0x46, 0xaa, 0xa0, 0x84, 0x1c, + 0xba, 0x08, 0x6d, 0xd3, 0x6d, 0xd6, 0x35, 0x53, 0xfa, 0x7d, 0xc0, 0xba, + 0x7a, 0x0a, 0x58, 0xcf, 0x3d, 0x1f, 0x5a, 0x2e, 0xb0, 0x3d, 0xfd, 0x6b, + 0x15, 0x2e, 0x90, 0xe1, 0x61, 0xd1, 0x8d, 0xd1, 0x32, 0x70, 0xd3, 0x18, + 0xec, 0x18, 0xe7, 0x16, 0xb9, 0x77, 0x3d, 0xe7, 0xae, 0x1d, 0x6d, 0x1b, + 0x9c, 0x11, 0x92, 0x77, 0x93, 0x03, 0x40, 0xca, 0x3f, 0x0e, 0xe9, 0xae, + 0x13, 0xd2, 0xd9, 0x53, 0xdb, 0x33, 0x59, 0xdb, 0xf3, 0x8a, 0x29, 0x5b, + 0xac, 0x2a, 0x41, 0xf4, 0x96, 0xe0, 0x3e, 0xe9, 0x83, 0x77, 0x89, 0xf1, + 0xde, 0xf5, 0x70, 0x5b, 0xa4, 0x7f, 0x98, 0x73, 0xa3, 0x41, 0x97, 0xf5, + 0x5e, 0x51, 0xe0, 0x43, 0x4f, 0xcf, 0xef, 0xd2, 0xb6, 0x84, 0x4e, 0x90, + 0x11, 0xfd, 0xe5, 0xfd, 0x73, 0x39, 0x62, 0x9c, 0xf4, 0xe3, 0xc0, 0x42, + 0x34, 0xb7, 0x78, 0xf3, 0xf1, 0xb0, 0x83, 0xc6, 0xa8, 0xb7, 0xcc, 0x78, + 0xc0, 0xa9, 0xc3, 0x49, 0xff, 0xb7, 0x0a, 0xdf, 0xd0, 0xf3, 0x81, 0x6f, + 0x3f, 0xe2, 0x20, 0xe6, 0x5d, 0xc4, 0xd1, 0xf4, 0x36, 0xe3, 0x55, 0x67, + 0x08, 0x4d, 0xde, 0xcf, 0x8d, 0xd7, 0x9c, 0x38, 0x1e, 0xe2, 0x7d, 0xee, + 0x4c, 0xc6, 0xf1, 0x40, 0xf9, 0xab, 0xfb, 0x5a, 0x22, 0x3b, 0xfe, 0x8e, + 0x42, 0x4b, 0x65, 0x7d, 0xf8, 0xac, 0x3f, 0x01, 0x5c, 0xa6, 0xc7, 0xf3, + 0x62, 0x63, 0xe9, 0x92, 0x72, 0xa3, 0x19, 0x3c, 0x50, 0xb2, 0x31, 0x8f, + 0x76, 0x45, 0x3c, 0x1b, 0x6f, 0x17, 0xf3, 0x62, 0x55, 0x39, 0x14, 0x6b, + 0x26, 0x7b, 0x44, 0x38, 0x69, 0x89, 0x9e, 0x71, 0x10, 0x9b, 0x4a, 0xad, + 0xf1, 0x05, 0xfe, 0xc3, 0xff, 0x57, 0xe3, 0x6c, 0xab, 0x0c, 0x5d, 0x71, + 0x49, 0x79, 0x49, 0x03, 0xf5, 0x5e, 0x9f, 0x58, 0x3b, 0xa9, 0xd4, 0x5e, + 0x3f, 0x2b, 0x7a, 0x27, 0x61, 0x37, 0x04, 0x81, 0x75, 0xd7, 0xe8, 0x69, + 0x23, 0xb7, 0x20, 0x86, 0x52, 0xc9, 0xc5, 0x29, 0x5f, 0xe3, 0x77, 0x1e, + 0x2c, 0x4f, 0xf0, 0x85, 0xd8, 0x19, 0x1f, 0x56, 0x8c, 0xcf, 0x53, 0x1b, + 0x2c, 0x8c, 0x74, 0xaf, 0xad, 0xac, 0x89, 0x10, 0x2b, 0x4f, 0x14, 0xb3, + 0x30, 0x88, 0xbf, 0x45, 0x41, 0x72, 0x76, 0x82, 0x98, 0x7f, 0xcb, 0x4f, + 0x76, 0x7e, 0x6c, 0x92, 0x1c, 0x5a, 0x65, 0x82, 0x86, 0x0a, 0x2b, 0x48, + 0x76, 0x1e, 0x81, 0x80, 0xe9, 0x59, 0x78, 0xc5, 0x8f, 0x20, 0xdc, 0x60, + 0x63, 0x17, 0x71, 0x55, 0xc7, 0xf1, 0xa3, 0x95, 0x71, 0xfd, 0x19, 0xce, + 0xaa, 0xf2, 0x57, 0x73, 0x9e, 0xe3, 0xa5, 0x36, 0xe4, 0x2a, 0x79, 0x0f, + 0x67, 0x1d, 0xef, 0xfb, 0xad, 0x88, 0x7e, 0xfc, 0x93, 0xcf, 0xc6, 0x6e, + 0xa4, 0x9d, 0x66, 0xe0, 0xe5, 0x1e, 0x17, 0x8b, 0x50, 0x68, 0x01, 0xed, + 0x36, 0x70, 0x21, 0xbd, 0x10, 0xd3, 0x2d, 0xfa, 0xeb, 0xb8, 0xd3, 0x3f, + 0xde, 0xaa, 0x63, 0xa2, 0xf7, 0x72, 0x56, 0x8d, 0x2b, 0xf5, 0xbc, 0x5f, + 0x87, 0xd9, 0x8e, 0xe1, 0x19, 0x66, 0x89, 0xbf, 0x88, 0x39, 0xf9, 0x12, + 0xcf, 0x6f, 0x59, 0x66, 0xc2, 0x5c, 0xe6, 0x9a, 0xee, 0x7c, 0x60, 0xa2, + 0xa8, 0x39, 0x41, 0xce, 0xbe, 0xc4, 0xff, 0xe7, 0xca, 0x1a, 0x9f, 0x3e, + 0xf1, 0x29, 0xd0, 0xde, 0xa1, 0xe3, 0xee, 0x5b, 0xed, 0xc4, 0xde, 0x76, + 0xfa, 0x33, 0xc2, 0x3c, 0x78, 0x90, 0xf6, 0x9e, 0x2b, 0x7e, 0xcf, 0x58, + 0xe5, 0x48, 0x57, 0x9f, 0xf0, 0x4e, 0x11, 0xe2, 0x79, 0xff, 0xef, 0xb4, + 0x8f, 0x5d, 0x6e, 0x4b, 0xcc, 0xdc, 0x47, 0xcc, 0x68, 0xee, 0x59, 0x6f, + 0x39, 0x63, 0x72, 0xe0, 0x7d, 0x1a, 0x91, 0x08, 0x86, 0xac, 0x44, 0x29, + 0xb5, 0x77, 0x90, 0xdf, 0xdb, 0x41, 0xd6, 0xb2, 0x47, 0x65, 0x9e, 0xe7, + 0xe5, 0x2c, 0x43, 0x26, 0x9a, 0xcd, 0xd4, 0xd0, 0x88, 0x90, 0x83, 0xcd, + 0x42, 0xf6, 0xdf, 0x03, 0xe9, 0x9c, 0x10, 0xfa, 0xcc, 0xf5, 0x56, 0x57, + 0x05, 0xa3, 0x59, 0x62, 0x54, 0xbf, 0xdf, 0x67, 0xa5, 0x2a, 0xef, 0x43, + 0xd6, 0x95, 0x53, 0x09, 0x8c, 0x96, 0xa4, 0xef, 0x8a, 0x28, 0xbe, 0x96, + 0xb6, 0x71, 0x22, 0xa9, 0x96, 0xbc, 0x90, 0x96, 0xb9, 0x1e, 0x73, 0x31, + 0x73, 0x21, 0x81, 0x61, 0x62, 0xe9, 0x1f, 0x92, 0x23, 0xe8, 0x29, 0x9b, + 0xc4, 0xb1, 0x8b, 0xfd, 0xa5, 0x28, 0x66, 0xc8, 0x4f, 0x75, 0xe9, 0x4e, + 0x8c, 0x94, 0x64, 0xe7, 0x1b, 0x48, 0xe5, 0x8f, 0x30, 0x5e, 0x67, 0x17, + 0x78, 0xd8, 0x5f, 0x6e, 0x63, 0x8c, 0xa4, 0xbb, 0x8a, 0x1c, 0x65, 0x76, + 0x4b, 0x67, 0x17, 0x7d, 0x5b, 0x17, 0x90, 0xdb, 0xca, 0x19, 0xee, 0x53, + 0xc0, 0xaa, 0x72, 0x5e, 0xf4, 0x95, 0xe7, 0x70, 0xfa, 0x73, 0x62, 0x53, + 0x63, 0xd5, 0xc6, 0xe6, 0x12, 0x70, 0x67, 0xc9, 0x47, 0x8b, 0x67, 0xbc, + 0x18, 0xc5, 0x45, 0xfa, 0x71, 0x02, 0xf7, 0x38, 0x21, 0x16, 0x79, 0xeb, + 0xd4, 0x8e, 0xb8, 0x9e, 0x9f, 0x17, 0x6b, 0x19, 0xb7, 0x30, 0x02, 0x63, + 0xd2, 0x37, 0x71, 0x36, 0x3e, 0x3c, 0x3f, 0x52, 0xe1, 0x5d, 0xfd, 0x6e, + 0xa2, 0xdf, 0xc7, 0x1a, 0x07, 0x72, 0xc8, 0x17, 0x85, 0xc1, 0x26, 0xfa, + 0xe1, 0xa4, 0x28, 0x0c, 0xc4, 0x20, 0x0b, 0xf7, 0x0a, 0x3a, 0x6b, 0x8c, + 0x24, 0xb1, 0x60, 0x8e, 0xa7, 0x2d, 0xfc, 0x75, 0xe9, 0x29, 0xe3, 0x5c, + 0xa4, 0x0e, 0xe6, 0x81, 0x08, 0xa2, 0x07, 0x2c, 0x34, 0x1f, 0x10, 0xc4, + 0x5d, 0xa1, 0x33, 0xaa, 0xd7, 0x21, 0x81, 0x7d, 0xa3, 0x36, 0xee, 0xe9, + 0x88, 0xe0, 0x42, 0x52, 0x0e, 0x5e, 0x21, 0x86, 0xfd, 0x26, 0x8e, 0x8d, + 0x1e, 0x97, 0xae, 0x6b, 0x14, 0x22, 0x68, 0x8a, 0x23, 0xd2, 0x5e, 0x87, + 0x06, 0xae, 0xdb, 0x59, 0x52, 0x3b, 0xed, 0xa0, 0xe0, 0x36, 0x40, 0xfa, + 0x0f, 0x73, 0xdf, 0x53, 0x45, 0xa5, 0xea, 0xaf, 0xf5, 0x66, 0x3e, 0x30, + 0xe5, 0xf4, 0x0e, 0x7e, 0x7e, 0x6b, 0xaa, 0xba, 0xff, 0xbc, 0x03, 0x36, + 0x1a, 0x0f, 0x56, 0xf6, 0x9f, 0x7d, 0x8a, 0x16, 0x7c, 0x58, 0xd2, 0xf9, + 0xa4, 0x54, 0x34, 0xf0, 0xfa, 0xdf, 0x13, 0x4a, 0xdd, 0xe4, 0xcb, 0xdc, + 0xcb, 0xa2, 0x6d, 0x60, 0x94, 0xcf, 0x83, 0xe9, 0xa4, 0x9b, 0xa5, 0xcd, + 0xe7, 0xcb, 0x51, 0xda, 0xc7, 0x5c, 0xf0, 0xb6, 0x19, 0x3b, 0x1c, 0x13, + 0x75, 0xde, 0x0e, 0x63, 0x6b, 0x05, 0xab, 0x0e, 0x16, 0x8d, 0xd5, 0x63, + 0x89, 0x17, 0x8a, 0x4d, 0xcc, 0xcd, 0x8d, 0x93, 0x16, 0xe7, 0xe9, 0xdc, + 0x14, 0x88, 0x7a, 0xbd, 0x62, 0xe5, 0x64, 0x5f, 0x25, 0x5f, 0x07, 0xc6, + 0x0d, 0xbc, 0xe9, 0xdf, 0x80, 0x48, 0x90, 0x15, 0x03, 0x93, 0x3a, 0x7f, + 0xd6, 0x8a, 0xd5, 0x93, 0x8c, 0xdf, 0x7c, 0x9d, 0x3b, 0x37, 0x88, 0x48, + 0xa0, 0xf3, 0xe5, 0xf3, 0x1c, 0xb2, 0x99, 0x43, 0xc7, 0xfe, 0x97, 0x1c, + 0x7a, 0xa8, 0x64, 0x21, 0xd7, 0x52, 0xcd, 0x97, 0x5e, 0xc6, 0xe2, 0xef, + 0x6b, 0x75, 0x7b, 0x3b, 0xc7, 0xa3, 0x07, 0x74, 0x0e, 0xf7, 0x32, 0x87, + 0x35, 0x9e, 0x2d, 0xb1, 0x69, 0x1c, 0x76, 0x73, 0x10, 0x5a, 0x1f, 0x8e, + 0x2a, 0xbc, 0xed, 0x2b, 0xf5, 0xf1, 0x32, 0xed, 0x13, 0x39, 0xf8, 0x2c, + 0xf1, 0x08, 0x12, 0xd2, 0xbb, 0x9e, 0x52, 0x33, 0x7e, 0x2a, 0xfb, 0x2c, + 0x79, 0xf9, 0x9c, 0xd0, 0xf7, 0x8f, 0xc2, 0x49, 0x6b, 0x3c, 0xf6, 0x5a, + 0x57, 0x55, 0x70, 0x19, 0x12, 0xaf, 0xac, 0xd5, 0xf3, 0x35, 0x36, 0xa3, + 0x68, 0x48, 0xce, 0xd2, 0x37, 0x72, 0xa8, 0x51, 0xa8, 0x25, 0xaf, 0xa6, + 0xab, 0xb8, 0x2c, 0xb2, 0x36, 0xad, 0xe7, 0x59, 0xbd, 0xe3, 0xb2, 0xb0, + 0xde, 0xac, 0xd6, 0xd1, 0xbd, 0xc4, 0x86, 0xe6, 0xb8, 0xcb, 0xdb, 0xa3, + 0xd8, 0x47, 0x8c, 0x7a, 0x69, 0x17, 0xc3, 0xac, 0xab, 0xbb, 0x4b, 0xd2, + 0x1d, 0x26, 0x4e, 0x77, 0xd7, 0x70, 0x3a, 0xcc, 0x5a, 0xba, 0x1b, 0x72, + 0xaf, 0xae, 0xa5, 0x11, 0xe2, 0x94, 0x34, 0x56, 0xc1, 0xe9, 0x48, 0x0d, + 0xa7, 0xbd, 0x15, 0x9c, 0xee, 0x36, 0x34, 0x3e, 0x35, 0xf6, 0x36, 0xf1, + 0xbe, 0x67, 0xa3, 0x30, 0x7e, 0xc0, 0xfd, 0xc3, 0x05, 0xc3, 0x3d, 0x35, + 0xec, 0xf5, 0x68, 0xec, 0x19, 0x69, 0xdc, 0x63, 0xf0, 0x6e, 0x2f, 0x88, + 0x42, 0xae, 0x11, 0x32, 0x3b, 0x2c, 0x0a, 0x9d, 0xf3, 0x88, 0xbd, 0x67, + 0x38, 0xa3, 0x81, 0xd8, 0xab, 0xfa, 0x4c, 0xcf, 0x8f, 0x11, 0x7b, 0xff, + 0x29, 0xce, 0x46, 0x34, 0xd7, 0xea, 0xd8, 0x02, 0x8b, 0x4e, 0x68, 0xae, + 0x8d, 0x92, 0x30, 0x2c, 0xe4, 0x4b, 0xc6, 0xe2, 0x04, 0x14, 0xb6, 0x92, + 0xdb, 0xde, 0xf4, 0x76, 0xf9, 0x2d, 0xb8, 0x01, 0xa7, 0xbb, 0x0c, 0x68, + 0x1d, 0x62, 0x4e, 0x54, 0xb1, 0x7b, 0x17, 0x39, 0xa3, 0x29, 0x90, 0x9d, + 0x67, 0xa9, 0x37, 0xb6, 0xa4, 0x1b, 0x50, 0xf2, 0x86, 0xc3, 0x66, 0x56, + 0x43, 0x9b, 0xe7, 0xae, 0x86, 0xae, 0x85, 0x71, 0x58, 0xed, 0x36, 0x1a, + 0x8e, 0x7a, 0xb9, 0x13, 0x42, 0xe3, 0x15, 0xe8, 0x3a, 0x6e, 0xd3, 0x7e, + 0x38, 0xf5, 0x81, 0x97, 0xf9, 0xc0, 0x7c, 0x5c, 0x9c, 0x75, 0xaa, 0xf5, + 0xa0, 0x6f, 0x5c, 0x63, 0xec, 0x57, 0xea, 0x4d, 0xcf, 0xc0, 0x1d, 0xdd, + 0x4a, 0x79, 0x4b, 0xa3, 0x88, 0x4c, 0xd8, 0xa8, 0x3b, 0xd8, 0x8a, 0x97, + 0xba, 0x22, 0x38, 0x7b, 0xab, 0xfe, 0x3e, 0x8a, 0x7a, 0xe2, 0x70, 0xd3, + 0xb5, 0x51, 0x2c, 0x99, 0xa8, 0x62, 0xb2, 0xc1, 0xfb, 0x89, 0xb8, 0x8b, + 0x98, 0x9c, 0xe7, 0x9d, 0x11, 0xdb, 0x9c, 0x0c, 0xf6, 0xd2, 0xa6, 0xd7, + 0xc9, 0xf1, 0xe7, 0x93, 0xbb, 0x66, 0x2c, 0xda, 0xbf, 0x62, 0x59, 0xa1, + 0x73, 0x09, 0x22, 0x58, 0x34, 0x21, 0x07, 0x8e, 0xe9, 0x0a, 0x33, 0x6a, + 0x89, 0x0d, 0xc4, 0xbb, 0xe6, 0x57, 0x93, 0x71, 0xba, 0x62, 0x69, 0xdb, + 0xd0, 0xcd, 0xb8, 0xa4, 0xce, 0x24, 0x93, 0xd9, 0x51, 0x62, 0x7d, 0xdb, + 0xf1, 0x08, 0xea, 0x0e, 0xfc, 0x97, 0x32, 0x02, 0xe6, 0x42, 0xb7, 0x22, + 0x3e, 0x0b, 0x99, 0x7a, 0x72, 0xc8, 0x45, 0xc4, 0xf1, 0xd8, 0xfe, 0x9d, + 0x6a, 0x09, 0xc7, 0xdf, 0xbb, 0xbe, 0x19, 0x6d, 0xcb, 0x64, 0x7e, 0x2b, + 0xf7, 0x9f, 0x4d, 0x17, 0x3a, 0x13, 0x8c, 0xdd, 0x49, 0xb8, 0xb8, 0x6a, + 0x4c, 0xe6, 0x8e, 0xa1, 0x0e, 0xcd, 0x13, 0x5e, 0xf6, 0x84, 0x88, 0xa1, + 0xf1, 0x44, 0x0c, 0xfb, 0x8e, 0xeb, 0xfc, 0x8c, 0xc1, 0x1a, 0xf3, 0x66, + 0x3b, 0x44, 0xa1, 0x9f, 0xf9, 0x39, 0xd3, 0x2f, 0xda, 0xd1, 0x3e, 0x2e, + 0xa7, 0xb3, 0xc2, 0x0b, 0x1f, 0x80, 0x87, 0x76, 0xd6, 0x65, 0xfb, 0x84, + 0x8b, 0x15, 0xba, 0x7e, 0x94, 0x75, 0xfe, 0xe8, 0x7a, 0x6a, 0xf0, 0x4e, + 0xa1, 0x58, 0x5f, 0xa9, 0x79, 0xbd, 0x7c, 0xf5, 0xb1, 0xfe, 0x59, 0x62, + 0xdd, 0xb8, 0xce, 0x2d, 0x03, 0x33, 0xfe, 0x25, 0xb5, 0x3d, 0x99, 0x65, + 0xad, 0x9b, 0xc7, 0xbc, 0xaa, 0xe6, 0x13, 0x5a, 0x74, 0x6e, 0xcd, 0xab, + 0xe5, 0x93, 0x85, 0x33, 0x8c, 0xdd, 0xe1, 0xff, 0x73, 0x5d, 0xb2, 0x90, + 0x38, 0x60, 0xa0, 0xa5, 0x23, 0x8a, 0x6b, 0x96, 0xb6, 0x39, 0xcd, 0x88, + 0xe2, 0x26, 0xdf, 0x41, 0x13, 0x31, 0xb1, 0x9f, 0x39, 0x85, 0xf9, 0xd5, + 0x5c, 0x5b, 0xa9, 0xeb, 0x55, 0x2d, 0xd7, 0xf2, 0xa5, 0x04, 0x6b, 0x93, + 0xae, 0x05, 0xbd, 0xac, 0x05, 0x16, 0x0e, 0x95, 0xb5, 0x6f, 0x1d, 0xbc, + 0x4b, 0xce, 0x7e, 0xc5, 0xd7, 0xbe, 0x5d, 0x8c, 0x12, 0x73, 0xe3, 0x41, + 0xe6, 0xc6, 0xda, 0xf2, 0x25, 0xb5, 0xc6, 0xd3, 0xf5, 0x38, 0x64, 0x3d, + 0xb6, 0xc4, 0x4d, 0xe3, 0x72, 0xd0, 0x15, 0xa7, 0xee, 0x24, 0x36, 0x3b, + 0x1b, 0x0d, 0xa5, 0x5e, 0x4e, 0xa7, 0x42, 0xea, 0x98, 0xcc, 0xdd, 0x42, + 0xba, 0xef, 0x93, 0x9b, 0xd6, 0x9a, 0x51, 0x2c, 0xaf, 0xe5, 0x60, 0xb2, + 0x96, 0x83, 0x1e, 0x73, 0xd0, 0x6d, 0x45, 0xf8, 0x09, 0x6d, 0x6c, 0x63, + 0x0e, 0x6e, 0xa3, 0x4e, 0xfd, 0x7e, 0xa9, 0xc2, 0xfb, 0x99, 0x15, 0x22, + 0x35, 0x73, 0x9e, 0xf9, 0xe4, 0x5e, 0xe6, 0x51, 0xaf, 0xb5, 0x65, 0xce, + 0x33, 0x66, 0xab, 0x6b, 0xf9, 0xb4, 0xbb, 0xc6, 0xfb, 0x0f, 0xd4, 0xf2, + 0x69, 0xf5, 0x97, 0xf2, 0x49, 0xf3, 0xd3, 0x0b, 0xbf, 0x43, 0xab, 0xd6, + 0x22, 0x79, 0xa1, 0xef, 0x97, 0xb3, 0x10, 0xfe, 0xd8, 0xd7, 0x67, 0xd9, + 0xb0, 0x82, 0xc6, 0x0a, 0xdf, 0x58, 0x41, 0x28, 0x7a, 0x59, 0x3b, 0x6d, + 0x2f, 0x2f, 0xb2, 0xf4, 0x9d, 0x5e, 0xb7, 0x96, 0xb1, 0xd8, 0x99, 0xfe, + 0x05, 0xce, 0xb6, 0x2a, 0xd5, 0x97, 0xbe, 0xa4, 0xde, 0x60, 0x5c, 0x62, + 0xd4, 0x1f, 0xeb, 0x27, 0xb3, 0xa2, 0x7f, 0x52, 0xfb, 0xa6, 0x11, 0x11, + 0x6f, 0xad, 0x58, 0x35, 0x09, 0xdc, 0x43, 0x3d, 0x73, 0x8e, 0x7e, 0x59, + 0xe3, 0xcb, 0xa1, 0x35, 0xbc, 0xdb, 0x19, 0xdf, 0xc2, 0xc3, 0xe5, 0xaa, + 0x7f, 0xf6, 0x95, 0x65, 0x66, 0x1a, 0x23, 0x58, 0xc3, 0x9a, 0x76, 0x98, + 0x7c, 0xf1, 0x6f, 0xc9, 0x28, 0x5e, 0x24, 0x5f, 0xbc, 0xc4, 0xfb, 0x1d, + 0xaa, 0xde, 0xcf, 0x9f, 0x45, 0x2a, 0x73, 0x5a, 0xf3, 0x05, 0xb5, 0xf7, + 0xa1, 0x72, 0x9b, 0x7f, 0x9a, 0x78, 0x7c, 0xb0, 0x24, 0x07, 0xfa, 0x78, + 0x47, 0xbb, 0x5b, 0xce, 0x0e, 0x0a, 0x81, 0x8d, 0x49, 0x38, 0x66, 0xa0, + 0xef, 0xe1, 0x52, 0xe3, 0x66, 0xe8, 0x87, 0x02, 0xfa, 0x78, 0xd7, 0x95, + 0xac, 0x71, 0x8f, 0x95, 0xbf, 0xa4, 0xeb, 0xb0, 0xad, 0xa4, 0xb9, 0x4a, + 0xa9, 0x8e, 0xb4, 0xd6, 0x4a, 0x79, 0x71, 0xb3, 0xe6, 0x94, 0x48, 0x14, + 0xca, 0x6f, 0x4b, 0x2c, 0x61, 0xec, 0xf3, 0xc4, 0xd7, 0xbb, 0x5e, 0x3d, + 0x79, 0x21, 0x24, 0xaf, 0xf7, 0x90, 0xb7, 0x7b, 0x45, 0x5f, 0x85, 0xcf, + 0xb3, 0x22, 0x3b, 0x69, 0x8b, 0x1e, 0x6a, 0x94, 0x0d, 0xcc, 0x33, 0x77, + 0xe1, 0x3c, 0x62, 0x4a, 0xe3, 0xca, 0xc0, 0x0f, 0xfc, 0xb5, 0xe4, 0xfc, + 0x1b, 0xe8, 0x2b, 0xf2, 0x52, 0x05, 0x8b, 0x37, 0x50, 0x27, 0x55, 0xb1, + 0xf8, 0x43, 0x62, 0x31, 0x57, 0xc3, 0x62, 0x24, 0x48, 0x92, 0xef, 0x3e, + 0xc7, 0x62, 0xef, 0x1f, 0xe0, 0xf7, 0x2f, 0x62, 0x6e, 0xbd, 0xe6, 0xf7, + 0xc8, 0x1c, 0xe6, 0x58, 0x9f, 0x3b, 0x02, 0xf2, 0xb0, 0xc6, 0x9b, 0x8d, + 0xbe, 0x47, 0xeb, 0xb1, 0xe1, 0xd1, 0x18, 0x6e, 0x7e, 0x54, 0xa9, 0xd7, + 0x7c, 0x78, 0x2d, 0xe4, 0xa2, 0x5f, 0xa4, 0x27, 0x70, 0xa6, 0x25, 0xe9, + 0xee, 0x83, 0xee, 0xa3, 0x7a, 0xad, 0xdb, 0x8b, 0x5a, 0xa3, 0x84, 0xd4, + 0x28, 0xb2, 0xff, 0x7d, 0xe6, 0xfa, 0xa6, 0xa4, 0xcc, 0xef, 0xac, 0x70, + 0x7f, 0xca, 0xa7, 0x16, 0xdf, 0x6b, 0x98, 0x32, 0xdb, 0x6e, 0x54, 0xb1, + 0x76, 0x4d, 0x0d, 0x6b, 0x5f, 0x9b, 0xb2, 0xf1, 0x4b, 0xd6, 0x85, 0xcd, + 0xe9, 0x28, 0x56, 0xeb, 0x1a, 0xef, 0xe8, 0x5e, 0x2a, 0x8a, 0x7e, 0xc6, + 0xc5, 0x58, 0xaa, 0xa8, 0x37, 0xa8, 0x3b, 0x18, 0xcb, 0x55, 0xec, 0xa7, + 0xce, 0x50, 0x9f, 0xdc, 0x68, 0x56, 0x7b, 0xa9, 0xd1, 0x9a, 0x3e, 0xb9, + 0xb1, 0xac, 0xf3, 0xd1, 0x25, 0x06, 0xa2, 0x38, 0xcd, 0x35, 0x7b, 0xfc, + 0xaa, 0x3e, 0x79, 0x1d, 0xa9, 0xac, 0xd6, 0x27, 0x2e, 0x79, 0xbf, 0x54, + 0xd1, 0x27, 0x5a, 0x8f, 0x68, 0x2d, 0xa2, 0xfb, 0x85, 0x6e, 0xf6, 0x0b, + 0x72, 0x5a, 0xeb, 0x15, 0xa3, 0x5b, 0xfa, 0x86, 0x19, 0x61, 0x8d, 0xcc, + 0x30, 0x96, 0x97, 0x61, 0xd7, 0x23, 0x4d, 0x8c, 0x45, 0x23, 0x76, 0x38, + 0x2b, 0xac, 0x25, 0x9e, 0xe6, 0x4f, 0x6a, 0x90, 0xdf, 0xd3, 0x2e, 0x47, + 0x35, 0xc7, 0x32, 0xfe, 0x73, 0xe3, 0xff, 0x5e, 0x1b, 0xd7, 0xf3, 0xb3, + 0xac, 0xd1, 0x7a, 0xcd, 0x8f, 0xac, 0x2a, 0xee, 0xd1, 0xdc, 0xe4, 0xfd, + 0x19, 0x2e, 0xd0, 0xc6, 0x37, 0xbf, 0x14, 0x47, 0x9b, 0x79, 0xa1, 0xe3, + 0xf8, 0x09, 0xd7, 0xea, 0x78, 0xdb, 0x78, 0x87, 0x3e, 0x3e, 0x47, 0x1f, + 0xff, 0xf2, 0xd1, 0x80, 0xdc, 0x84, 0x4f, 0x0d, 0xfa, 0x78, 0x3b, 0x71, + 0xf3, 0x63, 0xff, 0x7a, 0xb4, 0xb7, 0x26, 0xdd, 0x0f, 0xcc, 0xb9, 0x7a, + 0x0b, 0x7b, 0x09, 0x7d, 0xa7, 0xe8, 0x67, 0xdd, 0xeb, 0x1c, 0xa3, 0x7f, + 0x99, 0xcb, 0x15, 0x0d, 0xd2, 0x6e, 0x56, 0xfd, 0xdb, 0x51, 0xf3, 0x6f, + 0x66, 0x6a, 0x1b, 0xcf, 0xd1, 0xf5, 0x54, 0xeb, 0xd1, 0xfb, 0x2b, 0xfd, + 0x92, 0x19, 0xdc, 0x5a, 0x89, 0x55, 0x5d, 0x90, 0xb7, 0x5e, 0x2c, 0xea, + 0x9a, 0xdd, 0xcf, 0x9a, 0xcd, 0x9e, 0xc9, 0x94, 0x83, 0x83, 0x48, 0x4d, + 0x73, 0xaf, 0xbd, 0xa7, 0x91, 0x0a, 0xd9, 0x4f, 0x0d, 0x9d, 0x67, 0xef, + 0x93, 0x31, 0x64, 0x6e, 0xa6, 0xa2, 0x27, 0x6f, 0xad, 0xd5, 0xe9, 0xfe, + 0x9a, 0xae, 0xbc, 0xbf, 0x76, 0x4e, 0x9e, 0xba, 0x72, 0xee, 0x1c, 0x7d, + 0x97, 0xcb, 0x2d, 0xfd, 0xac, 0xfb, 0x80, 0x37, 0xfc, 0x9f, 0x29, 0x2c, + 0x6c, 0xac, 0xe8, 0x8e, 0xcf, 0xef, 0x6c, 0x89, 0x8d, 0xe3, 0x17, 0x55, + 0xa6, 0xe3, 0x2e, 0x13, 0xf5, 0x4a, 0x59, 0xcb, 0x42, 0x14, 0x4b, 0x33, + 0xaa, 0x18, 0x97, 0x05, 0x0d, 0xca, 0x96, 0xe0, 0x6e, 0xc6, 0x07, 0xb6, + 0x15, 0x0c, 0x5a, 0x23, 0x45, 0x39, 0xc4, 0x5e, 0x2e, 0xcf, 0x3e, 0x2c, + 0xdc, 0x0f, 0xad, 0x6f, 0xf5, 0x79, 0x77, 0xeb, 0x3e, 0x8e, 0xef, 0x83, + 0xb4, 0x67, 0xee, 0xdc, 0x10, 0x8f, 0x95, 0xfe, 0x4a, 0x3d, 0x16, 0x97, + 0x39, 0xbd, 0x47, 0x84, 0x73, 0x9e, 0xa8, 0xe8, 0xe7, 0x41, 0xad, 0x9f, + 0x5d, 0x8d, 0xc7, 0x31, 0x4f, 0xce, 0x9e, 0x40, 0x6a, 0xe0, 0x82, 0x29, + 0xfb, 0x63, 0xd4, 0xcc, 0xeb, 0x6a, 0x7b, 0xad, 0xa8, 0xed, 0xd5, 0x36, + 0xf5, 0x10, 0xed, 0xd6, 0x78, 0xac, 0xd6, 0x37, 0x23, 0x88, 0xa1, 0x69, + 0xd4, 0x63, 0x8d, 0x4f, 0xe6, 0x8e, 0xb0, 0xce, 0xc4, 0x8e, 0xef, 0xa8, + 0xd8, 0xfb, 0xba, 0xff, 0xa4, 0x59, 0xc9, 0xef, 0x13, 0xba, 0x4e, 0x58, + 0xb0, 0x58, 0x77, 0xae, 0x1c, 0x93, 0xe1, 0x16, 0xf1, 0x91, 0x5a, 0x92, + 0xf4, 0x12, 0xab, 0x85, 0xd6, 0x3e, 0x49, 0x6a, 0x9f, 0x18, 0x32, 0x27, + 0xfe, 0x85, 0xf6, 0x69, 0xfd, 0xa6, 0x6b, 0xa1, 0x83, 0x96, 0x51, 0xaf, + 0xb3, 0xcd, 0x48, 0x52, 0x3b, 0x3b, 0x68, 0xfe, 0x6c, 0x3f, 0x4b, 0xac, + 0xe2, 0x3e, 0x75, 0x07, 0x1c, 0x5c, 0x33, 0x26, 0x9d, 0xa3, 0xb8, 0x40, + 0x0e, 0xf7, 0x06, 0xb5, 0x4e, 0xbc, 0x3a, 0x9d, 0x64, 0x4d, 0x77, 0xd0, + 0xf5, 0xd9, 0x3e, 0x31, 0xd4, 0x8d, 0xe9, 0xb3, 0x0b, 0xd3, 0x26, 0xe3, + 0xe4, 0x98, 0x47, 0x39, 0xee, 0xa2, 0xfd, 0x44, 0x23, 0xfb, 0x2d, 0xa5, + 0xfa, 0x59, 0x0f, 0x2c, 0xd6, 0xdc, 0x5e, 0xb4, 0x0f, 0x8e, 0x88, 0xd4, + 0x40, 0x23, 0x52, 0xfd, 0x31, 0x78, 0xce, 0x3a, 0xa1, 0x7f, 0x63, 0x98, + 0xd3, 0x24, 0xc0, 0xe3, 0xc5, 0x3f, 0xe7, 0xba, 0xa4, 0xb3, 0x85, 0x18, + 0x6b, 0xf9, 0xd3, 0x54, 0xbe, 0x05, 0xa9, 0x21, 0x07, 0x9e, 0xfb, 0x3a, + 0xe7, 0x15, 0xbe, 0x30, 0xef, 0xd9, 0xca, 0x3c, 0xfa, 0xe2, 0x7a, 0xad, + 0xb5, 0x94, 0x7a, 0x82, 0x7a, 0xab, 0xe0, 0x68, 0xce, 0x11, 0x18, 0xf6, + 0xf5, 0x9e, 0x3d, 0xae, 0x05, 0x99, 0xb8, 0x03, 0x9f, 0xa8, 0x42, 0x3c, + 0xec, 0x8c, 0x54, 0x7e, 0x97, 0x90, 0x4e, 0x8e, 0xdc, 0x36, 0x5d, 0xed, + 0xb3, 0xd8, 0x17, 0x29, 0xf5, 0x22, 0xb9, 0xe9, 0x09, 0x6a, 0x9f, 0xe1, + 0xa9, 0x4f, 0xd4, 0x34, 0xb5, 0xcd, 0x88, 0xa7, 0xe7, 0x55, 0x39, 0xe8, + 0xb0, 0xa3, 0xd4, 0xe3, 0xfc, 0x6e, 0xcf, 0xd4, 0x1c, 0x2f, 0xf1, 0x3c, + 0x72, 0xc2, 0xed, 0xde, 0x7f, 0xab, 0xcd, 0x5f, 0x9a, 0xab, 0xd4, 0x18, + 0x6d, 0x78, 0xcb, 0xc7, 0xfd, 0x11, 0x24, 0x73, 0xb3, 0xf4, 0xcf, 0x99, + 0xe5, 0xb2, 0x7f, 0x8a, 0xf7, 0x5c, 0x2f, 0x64, 0x96, 0x77, 0xec, 0x9d, + 0x07, 0xcd, 0xb5, 0x92, 0xf9, 0x60, 0x78, 0x75, 0x7c, 0xfe, 0x99, 0x2f, + 0x13, 0x47, 0xf8, 0xbe, 0x39, 0xa3, 0xf7, 0x50, 0xaa, 0xc7, 0xd7, 0x3d, + 0xfe, 0x08, 0x7b, 0xfc, 0x82, 0x6a, 0xf0, 0xde, 0x50, 0xcf, 0x75, 0xc8, + 0xfe, 0x11, 0xe1, 0x71, 0xad, 0xcb, 0xba, 0xa0, 0xfb, 0xaa, 0x11, 0xf6, + 0x55, 0x2e, 0x9e, 0x26, 0xc7, 0x9c, 0x2c, 0x77, 0xe2, 0xf9, 0xb2, 0x87, + 0x67, 0x58, 0x3f, 0x9e, 0x2a, 0x5b, 0xd8, 0xfa, 0x88, 0xcc, 0x58, 0x62, + 0x27, 0xce, 0xfb, 0xd2, 0xf9, 0x1e, 0xed, 0x36, 0x03, 0xb9, 0x7f, 0x25, + 0x79, 0x85, 0x67, 0x14, 0x72, 0x66, 0x8b, 0xb0, 0x03, 0x1b, 0xdf, 0xe9, + 0x30, 0x70, 0x38, 0x3e, 0x84, 0xbe, 0xf6, 0xbb, 0xf9, 0xb2, 0xd0, 0x7a, + 0x40, 0xd7, 0x6a, 0xdd, 0x6f, 0x34, 0xe3, 0x4e, 0xf2, 0xd9, 0xd5, 0x4b, + 0x43, 0xfc, 0x3a, 0xdd, 0xd6, 0xf9, 0x92, 0xa0, 0x66, 0x68, 0x91, 0x59, + 0xe0, 0xa7, 0xd8, 0xc8, 0x7e, 0x21, 0xb3, 0x6c, 0x7f, 0xad, 0x37, 0xff, + 0x29, 0x56, 0xea, 0x3e, 0xc3, 0x6f, 0x66, 0xbd, 0xab, 0xc6, 0xe1, 0x70, + 0xc5, 0x8f, 0x06, 0x9a, 0x0e, 0x16, 0x54, 0xbd, 0x27, 0x73, 0x93, 0x15, + 0x1d, 0xb5, 0xd0, 0xb9, 0x91, 0x7d, 0x40, 0xc3, 0x01, 0xcf, 0x5d, 0x27, + 0x14, 0x63, 0xb1, 0x9b, 0xb1, 0x48, 0x86, 0x31, 0xb6, 0xdb, 0xcd, 0x41, + 0x32, 0x6c, 0x16, 0x79, 0x71, 0x8b, 0xae, 0xb1, 0x75, 0xf5, 0xec, 0xbf, + 0x59, 0x53, 0x27, 0x0d, 0xf6, 0x23, 0xba, 0x1f, 0x8f, 0x62, 0x2a, 0xdd, + 0xc6, 0x3e, 0x29, 0x8a, 0xed, 0xe9, 0x1e, 0xea, 0x1a, 0x03, 0xc6, 0xc1, + 0x4b, 0x6a, 0xe5, 0x17, 0xfa, 0x88, 0x4d, 0xe3, 0x9a, 0xc3, 0x6c, 0xb1, + 0x91, 0xf9, 0x9b, 0x59, 0x46, 0xb1, 0x76, 0x8b, 0xee, 0xe1, 0xf5, 0x1d, + 0x1c, 0xf6, 0xc7, 0x06, 0xa6, 0x17, 0x38, 0xd8, 0xd5, 0x2d, 0x13, 0x05, + 0xe8, 0x5c, 0xfe, 0x6a, 0x4d, 0x81, 0x93, 0xfd, 0xbd, 0x3a, 0x03, 0x67, + 0x03, 0x6d, 0x91, 0x75, 0x4a, 0xb5, 0xa6, 0x4d, 0xe4, 0x2a, 0xf5, 0x26, + 0xe1, 0x64, 0xd9, 0xff, 0xcd, 0x4c, 0xb1, 0x27, 0x3b, 0xa8, 0xd4, 0x4e, + 0x62, 0xe9, 0xe3, 0x8e, 0xe1, 0x43, 0xec, 0xc4, 0xf7, 0xb6, 0xb2, 0xb7, + 0xfa, 0x3a, 0xdb, 0xb7, 0xb7, 0x8a, 0xdf, 0x24, 0x7f, 0x1b, 0xdd, 0x09, + 0xe8, 0x7e, 0xa7, 0xa0, 0x22, 0x9e, 0x37, 0xfb, 0x38, 0xb5, 0xe0, 0x6f, + 0x96, 0x75, 0xc1, 0x9d, 0x5f, 0xf5, 0xd5, 0x6a, 0x6a, 0xa9, 0x8f, 0xc8, + 0xf9, 0x61, 0xe5, 0x73, 0xcc, 0x59, 0x37, 0x7e, 0x49, 0x6d, 0xa6, 0x6f, + 0x7a, 0xaa, 0x76, 0x59, 0xf5, 0x01, 0x9b, 0xc4, 0x6b, 0xe1, 0xac, 0xf9, + 0x03, 0x36, 0x7d, 0x5e, 0xef, 0x62, 0xce, 0x9a, 0xf1, 0xc5, 0xb4, 0x51, + 0xba, 0xd3, 0x15, 0xfc, 0xf8, 0xf8, 0xc8, 0x1b, 0x4e, 0xcc, 0x47, 0xa1, + 0x93, 0x39, 0x36, 0xfb, 0x4f, 0x1c, 0x6b, 0x5f, 0x0a, 0xfc, 0xa6, 0xfc, + 0x5d, 0xf2, 0xbe, 0xd1, 0xd5, 0x82, 0xc2, 0x0c, 0x6d, 0x3c, 0xf4, 0x75, + 0x62, 0x32, 0x3f, 0x86, 0xfb, 0xd8, 0x46, 0xe0, 0x59, 0xd6, 0xdb, 0x63, + 0xe4, 0x8c, 0xe6, 0xb4, 0x83, 0x32, 0x9f, 0x8f, 0x94, 0x92, 0x83, 0xa7, + 0x99, 0xb7, 0xc7, 0xf9, 0x7c, 0x94, 0xf7, 0xdc, 0x4a, 0x7d, 0x77, 0xef, + 0x78, 0x3d, 0xbe, 0x3d, 0x1e, 0xc3, 0xd6, 0xf1, 0x80, 0x9a, 0x02, 0xb7, + 0x35, 0x72, 0xdf, 0x57, 0x89, 0xe7, 0xcd, 0x4b, 0xaf, 0xc3, 0x5a, 0x27, + 0xe9, 0xde, 0xcd, 0xdc, 0xab, 0x3b, 0x08, 0xc7, 0x21, 0x8e, 0xfe, 0xd9, + 0x5b, 0x2e, 0xd0, 0x44, 0xbd, 0xbf, 0xd4, 0x12, 0xeb, 0xc7, 0x57, 0x57, + 0x9e, 0x47, 0xd2, 0x79, 0x6a, 0x0b, 0x62, 0xb2, 0x44, 0x4c, 0x32, 0x36, + 0x4f, 0x97, 0x88, 0x4b, 0x6a, 0xc3, 0x93, 0x25, 0x8d, 0x6d, 0x1f, 0xcf, + 0x75, 0x0c, 0xa9, 0x2a, 0x56, 0x3e, 0x55, 0x4f, 0x78, 0xaf, 0x45, 0x50, + 0x6f, 0xe9, 0xdf, 0x76, 0xf0, 0x66, 0x31, 0xe1, 0x6c, 0x28, 0x6b, 0x3c, + 0xfc, 0x6d, 0x0d, 0x0f, 0x6f, 0x47, 0xaa, 0xfa, 0x44, 0xce, 0x4c, 0x42, + 0x73, 0xdd, 0x62, 0xe7, 0xa6, 0xd2, 0xf0, 0x34, 0x7d, 0x9f, 0xa7, 0xc6, + 0x76, 0xdf, 0x67, 0xc8, 0xc7, 0xa6, 0x8c, 0x2e, 0xf6, 0xd4, 0xf4, 0x87, + 0xbe, 0x33, 0xf3, 0x37, 0x2d, 0x3b, 0x75, 0x4c, 0x8e, 0x17, 0x71, 0x2b, + 0xfb, 0x1e, 0x3f, 0x44, 0xf5, 0x6e, 0x53, 0xbc, 0xf3, 0x43, 0xbc, 0xf3, + 0x0f, 0xf9, 0x3c, 0x51, 0x4a, 0x66, 0x7b, 0x78, 0xe7, 0x27, 0xf9, 0x3c, + 0x59, 0x6a, 0xad, 0xd3, 0x67, 0x4c, 0x4e, 0x85, 0xac, 0x03, 0x2f, 0xab, + 0x52, 0xbc, 0x12, 0x0e, 0xf6, 0xc0, 0x06, 0x1a, 0x0e, 0xce, 0xf1, 0xb3, + 0xfe, 0x6d, 0x49, 0xd7, 0x38, 0xcd, 0xf9, 0x83, 0xba, 0x26, 0x67, 0xae, + 0x14, 0x97, 0xd4, 0x47, 0x9e, 0x0c, 0x9f, 0xc6, 0x29, 0x35, 0x1f, 0xa9, + 0x99, 0xf9, 0x42, 0x4e, 0xaf, 0x30, 0xa4, 0xbb, 0xc8, 0xac, 0x72, 0x75, + 0x67, 0x8d, 0xab, 0xbd, 0xa9, 0x1b, 0xeb, 0xaa, 0x77, 0x48, 0x39, 0x47, + 0x30, 0x8f, 0xd8, 0xd7, 0x35, 0x55, 0xf3, 0x8f, 0xfe, 0x4c, 0x7d, 0x67, + 0x85, 0x09, 0x93, 0x7e, 0x08, 0x6f, 0xd5, 0x63, 0xd1, 0xda, 0x6f, 0x3e, + 0x29, 0x5f, 0xf7, 0x82, 0xd3, 0xf1, 0x1e, 0x7e, 0xa7, 0x7b, 0xc1, 0x4f, + 0x54, 0x2e, 0xde, 0xf3, 0x19, 0x67, 0x15, 0xd0, 0x45, 0xed, 0xf1, 0x3e, + 0x39, 0xa1, 0x83, 0x2a, 0x4a, 0xe0, 0x14, 0xfb, 0xb0, 0x23, 0x5d, 0x49, + 0x67, 0x17, 0xf7, 0x0b, 0x1d, 0x87, 0x5c, 0xb0, 0x93, 0x3a, 0x93, 0x73, + 0xca, 0x1d, 0x5c, 0xa3, 0xb9, 0xf0, 0x3e, 0xfa, 0xe6, 0xb7, 0xed, 0x96, + 0xe7, 0x63, 0x57, 0xe9, 0x39, 0xc3, 0xf2, 0xb4, 0x5f, 0x52, 0x99, 0x5d, + 0xb4, 0xe7, 0x2c, 0xed, 0x89, 0x78, 0x21, 0xb9, 0x31, 0x55, 0x59, 0x5f, + 0xb0, 0xb4, 0x1d, 0x15, 0x7b, 0x38, 0xa6, 0x39, 0x4f, 0xf6, 0x9f, 0x62, + 0x8d, 0xdd, 0x02, 0xfd, 0x3b, 0x85, 0xb6, 0xa1, 0x2d, 0xb1, 0x85, 0xf6, + 0x1c, 0x8e, 0x57, 0xf8, 0x94, 0xdf, 0xf1, 0xbc, 0x92, 0xb1, 0xbe, 0x9e, + 0x78, 0xbf, 0x22, 0x9d, 0x60, 0x6c, 0xbb, 0xa8, 0xef, 0xab, 0x71, 0xde, + 0x57, 0xc1, 0xf2, 0xff, 0x00, 0xb0, 0x60, 0x72, 0xf9, 0x60, 0x17, 0x00, + 0x00, 0x00 }; static const u32 bnx2_TPAT_b06FwData[(0x0/4) + 1] = { 0x0 }; static const u32 bnx2_TPAT_b06FwRodata[(0x0/4) + 1] = { 0x0 }; static struct fw_info bnx2_tpat_fw_06 = { - /* Firmware version: 4.4.22 */ + /* Firmware version: 4.6.16 */ .ver_major = 0x4, - .ver_minor = 0x4, - .ver_fix = 0x16, + .ver_minor = 0x6, + .ver_fix = 0x10, .start_addr = 0x08000488, .text_addr = 0x08000400, - .text_len = 0x1aa4, + .text_len = 0x175c, .text_index = 0x0, .gz_text = bnx2_TPAT_b06FwText, .gz_text_len = sizeof(bnx2_TPAT_b06FwText), @@ -3639,11 +3540,11 @@ static struct fw_info bnx2_tpat_fw_06 = { .data_index = 0x0, .data = bnx2_TPAT_b06FwData, - .sbss_addr = 0x08001ec0, + .sbss_addr = 0x08001b80, .sbss_len = 0x44, .sbss_index = 0x0, - .bss_addr = 0x08001f04, + .bss_addr = 0x08001bc4, .bss_len = 0x450, .bss_index = 0x0, @@ -3670,862 +3571,858 @@ static const struct cpu_reg cpu_reg_tpat = { }; static u8 bnx2_TXP_b06FwText[] = { - 0xad, 0x7b, 0x0d, 0x70, 0x94, 0xf7, 0x79, 0xe7, 0xef, 0xbf, 0x1f, 0xd2, - 0xae, 0xb4, 0x5a, 0xad, 0xf0, 0x82, 0x57, 0x89, 0x52, 0xf6, 0xf5, 0xbe, - 0x2b, 0x2d, 0x96, 0x80, 0x77, 0x41, 0x04, 0x11, 0x6d, 0xcd, 0x56, 0x08, - 0x21, 0x40, 0xd8, 0x32, 0x56, 0x92, 0x25, 0xc7, 0xd4, 0x2a, 0xc8, 0x20, - 0xdb, 0x18, 0x8b, 0x86, 0xe6, 0xe4, 0xd6, 0xad, 0xd6, 0x92, 0xc0, 0x60, - 0x56, 0xbc, 0x22, 0x82, 0x08, 0x77, 0xee, 0x26, 0xb2, 0x25, 0x2c, 0xec, - 0xac, 0x58, 0x3b, 0xbd, 0xeb, 0xc5, 0x33, 0xc9, 0x58, 0x67, 0x6c, 0x4c, - 0x72, 0xfe, 0xc8, 0x75, 0x3a, 0x3d, 0xf7, 0xe6, 0xee, 0xca, 0xf8, 0x83, - 0xd8, 0x6e, 0x8c, 0xdd, 0x4c, 0x3a, 0x27, 0x52, 0xdb, 0xef, 0xfd, 0x9e, - 0xf7, 0xdd, 0x05, 0xe2, 0xba, 0xd3, 0x99, 0xce, 0x69, 0x66, 0x67, 0xa5, - 0xf7, 0xe3, 0xf9, 0x3f, 0xdf, 0xcf, 0xef, 0x79, 0xfe, 0x7f, 0xd5, 0x03, - 0x15, 0x28, 0xfe, 0x54, 0xf1, 0xd3, 0x3c, 0x30, 0x78, 0x70, 0xd5, 0x8a, - 0xe6, 0x15, 0xf6, 0x05, 0x97, 0xc7, 0x23, 0x37, 0xbf, 0xaa, 0x80, 0xde, - 0x0f, 0xf0, 0x6f, 0xfa, 0xf9, 0xca, 0xbf, 0xed, 0x35, 0xfb, 0xc7, 0x0d, - 0x84, 0x4a, 0x7c, 0xc9, 0x07, 0x3e, 0x57, 0xea, 0xd2, 0xd7, 0xda, 0x74, - 0xf8, 0xdc, 0xa9, 0x93, 0xa9, 0xdd, 0x3a, 0x90, 0xce, 0x37, 0x46, 0x37, - 0xe0, 0x53, 0x2b, 0x1b, 0xf6, 0x40, 0xae, 0x7f, 0x25, 0xf5, 0xc9, 0xd0, - 0x4f, 0xd6, 0x6a, 0x1f, 0x4f, 0xb9, 0xe1, 0x0b, 0xa5, 0x4e, 0x23, 0x54, - 0x0f, 0x5f, 0x1d, 0xdf, 0xf9, 0x0f, 0x0d, 0xd5, 0x6e, 0x04, 0x4b, 0xb4, - 0x5a, 0x30, 0x62, 0x22, 0xeb, 0x4b, 0x0d, 0xa0, 0x7c, 0x0d, 0xf0, 0x6e, - 0x2e, 0x6e, 0x8c, 0x00, 0xe3, 0xae, 0x54, 0x3c, 0xfa, 0x22, 0x0c, 0x1c, - 0x2a, 0x44, 0xd1, 0xce, 0xcf, 0x66, 0xf3, 0x33, 0x2b, 0xea, 0x45, 0xd6, - 0xcd, 0xe7, 0x76, 0x35, 0x03, 0x1b, 0x73, 0x06, 0x0e, 0x9b, 0xf0, 0xd5, - 0xa6, 0x1e, 0xc6, 0x3a, 0x7e, 0x07, 0x53, 0x83, 0x78, 0x7d, 0x2c, 0x16, - 0x7d, 0x0a, 0x5a, 0x46, 0x77, 0x6b, 0x83, 0x40, 0x63, 0x7f, 0x9f, 0xd2, - 0x7a, 0xdf, 0x50, 0x5a, 0xf7, 0x98, 0x82, 0x4f, 0xf1, 0xb9, 0xc6, 0xbc, - 0x7c, 0x0f, 0xe2, 0xd6, 0xbc, 0x0f, 0x97, 0xdc, 0xb2, 0xfe, 0xef, 0x52, - 0xdf, 0x0a, 0x1e, 0xbd, 0x05, 0xa3, 0xe4, 0xc1, 0x9b, 0x52, 0x78, 0xb2, - 0x39, 0x1e, 0x19, 0x86, 0xdc, 0x8f, 0x62, 0x43, 0x41, 0xbe, 0x35, 0x4a, - 0x6d, 0x59, 0xa3, 0x86, 0x65, 0x9d, 0x31, 0xca, 0x91, 0x0d, 0x69, 0x11, - 0x40, 0x61, 0xd8, 0x70, 0x21, 0x1d, 0x6a, 0x8b, 0x7a, 0xa0, 0x45, 0xee, - 0xc1, 0x3f, 0x51, 0xe6, 0x74, 0xc2, 0x0b, 0xe7, 0xf9, 0x5e, 0x94, 0x63, - 0x3e, 0xe4, 0x68, 0xed, 0xc9, 0x9c, 0x65, 0x5d, 0xd0, 0x3d, 0x38, 0x43, - 0xfd, 0x0c, 0xe7, 0xff, 0xc9, 0x9a, 0xa7, 0x6e, 0x46, 0xf5, 0xd2, 0xfa, - 0x3e, 0x4c, 0x85, 0x2c, 0x6b, 0x9a, 0xf7, 0x0e, 0xe7, 0x4b, 0x7a, 0xb6, - 0x2c, 0x97, 0x6e, 0x59, 0xbb, 0xf5, 0xdf, 0x58, 0xbb, 0x7e, 0xeb, 0x59, - 0xcb, 0x7a, 0xcc, 0xb8, 0x09, 0x67, 0x27, 0xda, 0xd5, 0x96, 0xd9, 0x25, - 0xc1, 0xcd, 0x93, 0x16, 0x2e, 0x18, 0x08, 0xb9, 0x52, 0x1d, 0x6a, 0xf3, - 0x6c, 0xa7, 0xda, 0x58, 0xd8, 0xae, 0x3a, 0xa6, 0xbf, 0xa5, 0x3a, 0x67, - 0x7b, 0xd5, 0xa6, 0x42, 0x04, 0x33, 0x66, 0x18, 0xd3, 0x66, 0x46, 0xb5, - 0xcf, 0xf6, 0x28, 0x47, 0x8e, 0x41, 0xd5, 0x56, 0x28, 0xd1, 0xba, 0xae, - 0xc7, 0xcd, 0xb9, 0x14, 0x8e, 0x98, 0xe5, 0x5c, 0x67, 0xc1, 0xfa, 0x49, - 0xc3, 0x02, 0xe5, 0x34, 0x70, 0xb4, 0xf0, 0x18, 0xb6, 0x4d, 0x5a, 0x56, - 0x3e, 0x09, 0xe4, 0x0b, 0xc0, 0x0f, 0xcc, 0x58, 0x77, 0xbf, 0xb2, 0xac, - 0x4d, 0x71, 0x6b, 0xe9, 0x65, 0xa3, 0x31, 0xf1, 0x12, 0xfe, 0xaf, 0x35, - 0x15, 0x46, 0x36, 0x40, 0x1a, 0xc7, 0x68, 0xb3, 0xfb, 0xc6, 0xe0, 0x2b, - 0x4f, 0x8d, 0xe2, 0x17, 0x39, 0xf8, 0xca, 0x52, 0x59, 0x5c, 0xc8, 0x0d, - 0x87, 0x7c, 0x88, 0x45, 0x36, 0xab, 0xec, 0xa0, 0x0b, 0xda, 0xc0, 0xdb, - 0xd0, 0xa2, 0xb4, 0xc7, 0xc5, 0xf3, 0x4a, 0x9b, 0x7f, 0x09, 0x5a, 0xfa, - 0x37, 0x4a, 0xeb, 0xac, 0x75, 0x23, 0xed, 0x8a, 0xfb, 0xf0, 0x93, 0x06, - 0xb1, 0xc9, 0x28, 0x56, 0xd8, 0xb6, 0xc9, 0x62, 0xd9, 0x35, 0xdb, 0xa4, - 0x30, 0x4c, 0xbe, 0x0e, 0x93, 0xaf, 0x97, 0x0d, 0x2d, 0xf2, 0x24, 0xac, - 0xa5, 0x7d, 0x86, 0xdc, 0x4b, 0x61, 0xb4, 0x60, 0x45, 0x83, 0xa9, 0x4b, - 0xe4, 0x17, 0xd9, 0x2f, 0xa5, 0x7c, 0xd9, 0xea, 0xd4, 0xa7, 0xd6, 0x6b, - 0x6b, 0x22, 0x78, 0xa1, 0x10, 0xc6, 0x73, 0x85, 0x10, 0x9e, 0x2d, 0xb4, - 0xc3, 0x2c, 0x20, 0xb8, 0xad, 0xf0, 0x45, 0x7e, 0x6c, 0x21, 0xc0, 0xe7, - 0xc9, 0x77, 0x70, 0x6b, 0xc1, 0xd3, 0x5b, 0x96, 0x42, 0xf7, 0x4f, 0x73, - 0x43, 0x56, 0x85, 0x8e, 0xde, 0x9a, 0x94, 0x9e, 0xbe, 0x55, 0x05, 0x5a, - 0xe8, 0x87, 0xdd, 0xaf, 0xe4, 0x5b, 0x3c, 0xfa, 0x71, 0x3f, 0xbc, 0xd4, - 0xff, 0xc6, 0x82, 0x65, 0x8d, 0x18, 0x07, 0x56, 0xee, 0x6a, 0xf9, 0x8b, - 0xf9, 0x6e, 0xbd, 0x0b, 0xd9, 0x42, 0x1f, 0x10, 0x4c, 0xf1, 0x9b, 0xa1, - 0xb8, 0xbd, 0xa9, 0x3d, 0x7a, 0xee, 0x01, 0x8f, 0xe3, 0xcf, 0xe4, 0x81, - 0x7a, 0x7f, 0xce, 0x24, 0x0f, 0xe6, 0xe1, 0x20, 0x2a, 0xa2, 0x94, 0xef, - 0xe7, 0xe4, 0x33, 0x81, 0x1f, 0x16, 0x74, 0xf2, 0xd6, 0x44, 0x1e, 0xa3, - 0xe4, 0xcf, 0x87, 0x5d, 0x13, 0xda, 0x78, 0x16, 0xda, 0x91, 0x29, 0x2c, - 0x47, 0x3a, 0x1c, 0xa2, 0x0f, 0xfe, 0x39, 0x1c, 0x1a, 0x5d, 0x38, 0x6e, - 0x62, 0x55, 0x28, 0x45, 0xfb, 0x26, 0xf1, 0x70, 0x19, 0xe2, 0xbd, 0x1f, - 0x2b, 0x85, 0xd7, 0xe2, 0x5d, 0x18, 0xa3, 0x3c, 0x5d, 0x79, 0x3f, 0xee, - 0x9f, 0xa8, 0xc0, 0xbd, 0x13, 0x16, 0xee, 0x4b, 0x22, 0x55, 0x41, 0x79, - 0x12, 0xc9, 0x78, 0xf4, 0x3d, 0x78, 0xd0, 0x9e, 0xef, 0x62, 0x2c, 0x6d, - 0x40, 0xba, 0xcc, 0x87, 0x0d, 0xf9, 0x00, 0xe3, 0x31, 0x8d, 0xd3, 0x93, - 0x3e, 0x78, 0x57, 0xbb, 0x30, 0x15, 0x2e, 0x43, 0xa2, 0xde, 0xc5, 0x4f, - 0x38, 0xd8, 0x36, 0x59, 0x17, 0xdc, 0x68, 0x7a, 0xb0, 0xd7, 0x74, 0x61, - 0x68, 0xc2, 0xb2, 0xda, 0x0d, 0x0b, 0x57, 0x57, 0x87, 0xf0, 0x3c, 0xf5, - 0x77, 0xc0, 0x8c, 0xe0, 0x6c, 0xe1, 0x51, 0xf2, 0x12, 0x76, 0xf8, 0x35, - 0xc9, 0xbb, 0x49, 0xde, 0x4d, 0xf2, 0x6d, 0x0a, 0x9f, 0xe7, 0x19, 0x33, - 0x06, 0xe5, 0xf2, 0x93, 0x87, 0x4a, 0xf4, 0x93, 0x8f, 0x58, 0xd2, 0x82, - 0x2b, 0xa9, 0x65, 0x77, 0x31, 0x79, 0x2d, 0xad, 0xb7, 0xac, 0x8f, 0x57, - 0x8b, 0x2c, 0xb4, 0xb9, 0xab, 0x4b, 0x62, 0xf4, 0xf7, 0xaa, 0x18, 0x57, - 0x7f, 0x4b, 0xbd, 0x3d, 0x5e, 0xf0, 0x63, 0x70, 0xc2, 0xf6, 0xdb, 0x83, - 0x65, 0xe4, 0x5b, 0xf8, 0x2a, 0xe8, 0x71, 0xc6, 0x68, 0x3c, 0xc3, 0x18, - 0xc5, 0x56, 0xf2, 0x7c, 0x9f, 0x19, 0x6f, 0xd9, 0xae, 0x3c, 0xd8, 0x94, - 0x0f, 0x07, 0xdb, 0x6f, 0xe0, 0x93, 0xf2, 0x4a, 0x0c, 0x52, 0xd6, 0x10, - 0xf9, 0x0b, 0x63, 0x37, 0xf9, 0x7c, 0xae, 0xc8, 0xe7, 0x74, 0x41, 0xd6, - 0xfa, 0x3c, 0xaf, 0x25, 0x3e, 0x91, 0x5d, 0x94, 0x0a, 0x2b, 0x54, 0x04, - 0xb0, 0x3d, 0xff, 0x26, 0x6d, 0x51, 0x87, 0xbf, 0xa0, 0x0d, 0x5e, 0x60, - 0x8c, 0xfc, 0xf0, 0x9a, 0xbf, 0x88, 0x3d, 0x1e, 0xa1, 0x1d, 0xb4, 0xd3, - 0x59, 0x04, 0xd0, 0x5b, 0x48, 0xe3, 0xd0, 0x24, 0xd2, 0x33, 0xc6, 0x31, - 0xc6, 0xfb, 0x12, 0xb8, 0xf5, 0xf2, 0x74, 0x48, 0xaf, 0xc0, 0xee, 0xe9, - 0x30, 0x06, 0x0a, 0x6d, 0x30, 0x27, 0xc2, 0xd8, 0x47, 0xdf, 0xbc, 0x92, - 0x4c, 0xdf, 0x17, 0x84, 0xf0, 0x1e, 0xc6, 0xfd, 0x7c, 0xe7, 0xb1, 0xc9, - 0x30, 0xfa, 0xa9, 0xa3, 0xcd, 0xc9, 0x78, 0x8b, 0x9f, 0xd7, 0xf6, 0xf2, - 0xda, 0x61, 0xea, 0xff, 0xbc, 0x31, 0x86, 0xde, 0x6e, 0x2d, 0x01, 0x84, - 0xb1, 0xc7, 0x44, 0x88, 0x2e, 0xfc, 0x08, 0xf3, 0x5b, 0xe2, 0x3c, 0xff, - 0xbe, 0xa7, 0x50, 0x41, 0x39, 0x83, 0x88, 0xe8, 0x9f, 0x58, 0xde, 0x66, - 0xcb, 0xfa, 0xbe, 0x11, 0xbf, 0xf8, 0x96, 0xdb, 0x83, 0x87, 0x0a, 0x2e, - 0x0c, 0x4e, 0x57, 0xe0, 0x0f, 0x27, 0x3c, 0xb8, 0xb3, 0xbe, 0x02, 0x07, - 0xa6, 0xd3, 0x18, 0x99, 0xac, 0x40, 0xdf, 0x04, 0x96, 0xee, 0x31, 0x46, - 0x6a, 0xca, 0xa0, 0x2d, 0xb4, 0x23, 0x81, 0xab, 0xb4, 0xc3, 0x43, 0xd3, - 0x81, 0x60, 0x66, 0x32, 0x84, 0xc1, 0x59, 0x3f, 0x9f, 0x77, 0xf1, 0xf9, - 0x72, 0x18, 0xab, 0x62, 0x83, 0x21, 0x08, 0x8f, 0x95, 0xd8, 0x3f, 0xed, - 0xc7, 0x03, 0x13, 0x21, 0xec, 0x9b, 0x6c, 0xc6, 0xb8, 0x99, 0xc6, 0x51, - 0xe6, 0x8e, 0x1f, 0x24, 0xb5, 0xee, 0x7d, 0x4a, 0x4b, 0x6f, 0x54, 0x69, - 0x34, 0x24, 0xbd, 0xb8, 0xc4, 0x3c, 0xe4, 0x4d, 0x36, 0xb6, 0x3c, 0xcb, - 0xdc, 0x50, 0x96, 0x0a, 0xf3, 0x6f, 0xed, 0x08, 0x63, 0x36, 0xed, 0x75, - 0xad, 0x06, 0x16, 0x4b, 0xfc, 0x86, 0x83, 0x5b, 0xcc, 0x50, 0x70, 0x4b, - 0xa1, 0x2e, 0xb8, 0xd9, 0x8c, 0x04, 0x37, 0x33, 0xbe, 0x36, 0x8a, 0x3f, - 0x9a, 0x3e, 0x1c, 0x4b, 0x7e, 0x6a, 0xf5, 0xd6, 0xd8, 0xf9, 0x2c, 0xb8, - 0x6d, 0x52, 0xcb, 0x4e, 0x41, 0x33, 0x58, 0x0d, 0x30, 0x36, 0xeb, 0xa1, - 0xfd, 0x14, 0x6a, 0xf4, 0x66, 0xe6, 0xf1, 0x10, 0xf6, 0x33, 0xa7, 0xfc, - 0x15, 0x73, 0x4a, 0xdf, 0xf1, 0x58, 0x68, 0x1c, 0x7e, 0xea, 0x1b, 0xd8, - 0x75, 0x2e, 0x4c, 0x9b, 0x77, 0xe2, 0x51, 0xf2, 0xb5, 0x79, 0x4d, 0x18, - 0xf7, 0x16, 0x42, 0xc1, 0x4e, 0xda, 0xef, 0xbd, 0x7c, 0x24, 0xb8, 0x81, - 0xb6, 0x7c, 0x3b, 0xaf, 0x45, 0xe7, 0xf1, 0x8f, 0xe2, 0x4f, 0x09, 0xb8, - 0x80, 0x3d, 0xc7, 0xbd, 0x98, 0x0f, 0xcb, 0x5a, 0xd4, 0xb9, 0xf9, 0x82, - 0x15, 0xd0, 0xf5, 0xd3, 0xfb, 0xa8, 0xeb, 0x6f, 0x17, 0x02, 0x78, 0xc0, - 0xd4, 0x12, 0x3f, 0x54, 0x01, 0xea, 0xd4, 0x47, 0x3d, 0x30, 0xc1, 0x2c, - 0x91, 0xe7, 0x92, 0x88, 0x2e, 0x71, 0x72, 0xed, 0x81, 0x69, 0xf1, 0x13, - 0xda, 0xde, 0xa4, 0x0f, 0xd0, 0x7f, 0x7e, 0x78, 0x2d, 0x56, 0xb5, 0x50, - 0xd6, 0xce, 0xdd, 0x09, 0xfa, 0x8b, 0xa3, 0xa3, 0x13, 0x93, 0xa2, 0x07, - 0x6d, 0x1c, 0xae, 0x34, 0x56, 0xae, 0xfa, 0x2b, 0xeb, 0xd2, 0x62, 0xd1, - 0x47, 0x08, 0x43, 0xd4, 0xe1, 0x69, 0xd3, 0xb2, 0xae, 0xae, 0xfe, 0xd0, - 0x6a, 0xb9, 0x59, 0xf4, 0x22, 0xb2, 0x3e, 0xaf, 0xa4, 0x8e, 0xd4, 0xe8, - 0xc1, 0xff, 0x0f, 0xbe, 0xf2, 0x1d, 0xab, 0xd7, 0x96, 0x4f, 0xfc, 0xc5, - 0x43, 0x5f, 0x7c, 0x94, 0xb4, 0x5d, 0xe8, 0x25, 0xbd, 0x07, 0x4d, 0xeb, - 0xa3, 0xda, 0xd4, 0x67, 0x56, 0xcb, 0x5a, 0x7d, 0x60, 0x41, 0xfd, 0x0f, - 0x5e, 0x0f, 0x63, 0x7f, 0xa1, 0x85, 0xba, 0x6b, 0xc7, 0x63, 0xd4, 0xe1, - 0x61, 0x53, 0x72, 0x62, 0x84, 0xfe, 0x5c, 0x47, 0xff, 0xf6, 0xa8, 0x8d, - 0x66, 0x1e, 0x9b, 0xc7, 0xb2, 0xd8, 0x44, 0x7f, 0xbf, 0x98, 0x8b, 0xb5, - 0x3c, 0x0d, 0x2d, 0x4b, 0x19, 0x82, 0x9d, 0xd4, 0x71, 0xbb, 0xa9, 0x75, - 0x8a, 0x4d, 0xdb, 0x99, 0x97, 0x5e, 0xcc, 0x45, 0x82, 0x6d, 0x05, 0xd1, - 0x77, 0x5d, 0x70, 0x43, 0xe1, 0xab, 0xb4, 0xbd, 0xc2, 0xba, 0xe5, 0x3e, - 0xe6, 0x99, 0x3b, 0xe1, 0xd8, 0xd5, 0xb1, 0xdd, 0x6b, 0xc9, 0xc6, 0xde, - 0x0f, 0x99, 0x9f, 0xb2, 0x8b, 0x9d, 0x6b, 0x83, 0xbc, 0x56, 0xbd, 0x1a, - 0xc1, 0x3b, 0xe8, 0x07, 0x77, 0xd3, 0x0f, 0xae, 0xae, 0xfe, 0xd4, 0x8a, - 0xde, 0xe4, 0xf8, 0x41, 0xdb, 0xa4, 0x27, 0xd8, 0x41, 0x3d, 0x6d, 0x34, - 0x14, 0xa6, 0x8d, 0x1c, 0x7a, 0xaf, 0x61, 0x87, 0xf4, 0xd4, 0x59, 0x23, - 0xcd, 0x3c, 0xf2, 0xbb, 0xf0, 0xd4, 0x60, 0xea, 0x69, 0xe3, 0x51, 0x44, - 0x1d, 0xdf, 0xc1, 0xbe, 0x09, 0x3f, 0xb2, 0x77, 0x86, 0x30, 0xd3, 0x10, - 0xc2, 0x83, 0xa4, 0x7d, 0x25, 0xd9, 0xd8, 0xff, 0x3a, 0x75, 0x30, 0x55, - 0x23, 0xd7, 0xd2, 0xf8, 0x91, 0xf1, 0x30, 0x70, 0x93, 0xb3, 0xf6, 0xac, - 0xc4, 0xe8, 0x6c, 0x33, 0x0e, 0x17, 0x32, 0xca, 0xc9, 0x9b, 0x5a, 0x67, - 0x1a, 0x3f, 0xb7, 0x24, 0x97, 0xce, 0x9a, 0xcc, 0x71, 0xd4, 0xc7, 0x28, - 0xfd, 0x68, 0x38, 0x5f, 0x17, 0xdc, 0x44, 0x3f, 0x7a, 0x34, 0x2f, 0x32, - 0xc5, 0x0d, 0xc3, 0x5d, 0xcb, 0xda, 0x4c, 0xfd, 0x98, 0x76, 0xcd, 0xaf, - 0x0e, 0xe9, 0x47, 0x31, 0x6e, 0xf3, 0x36, 0xa8, 0x32, 0xc4, 0x18, 0x0c, - 0x99, 0xea, 0x72, 0xfd, 0x00, 0x1e, 0xb5, 0xaf, 0x85, 0x83, 0x3b, 0x26, - 0xd3, 0x2e, 0x97, 0x8e, 0x50, 0x65, 0xaa, 0x5d, 0xed, 0x60, 0xdd, 0xed, - 0x98, 0xec, 0x50, 0x1d, 0xb3, 0x12, 0x03, 0x9d, 0x6a, 0x33, 0x6b, 0x6e, - 0x9a, 0x35, 0x37, 0xcd, 0x9a, 0x9b, 0x26, 0x1f, 0x69, 0xd6, 0xda, 0xb6, - 0xc2, 0xa0, 0xda, 0x2a, 0xfa, 0xa7, 0x7f, 0x3d, 0x6b, 0x3a, 0x38, 0x82, - 0x39, 0x28, 0xb8, 0xa9, 0xb0, 0xc2, 0xe5, 0x60, 0xbb, 0x41, 0x55, 0xc4, - 0x32, 0xbe, 0x0a, 0x9d, 0xb5, 0xcc, 0x1c, 0x54, 0x5b, 0x58, 0x6f, 0x33, - 0xb6, 0x2e, 0x63, 0x03, 0xef, 0xb0, 0xce, 0xbe, 0xc6, 0x3a, 0x9b, 0x4f, - 0x32, 0xae, 0x96, 0x5f, 0xb5, 0x7a, 0x17, 0x3b, 0x35, 0x61, 0x84, 0xfc, - 0x7e, 0x9f, 0x36, 0x9b, 0x67, 0x2d, 0x6d, 0x77, 0x2b, 0xec, 0xd1, 0x51, - 0x5d, 0xcb, 0x9c, 0x7a, 0xb8, 0xc0, 0x3a, 0x60, 0xc4, 0x5a, 0xde, 0xa7, - 0x62, 0x0f, 0xeb, 0x5e, 0x5c, 0xbd, 0x89, 0x60, 0x47, 0x6f, 0xc3, 0xb1, - 0x89, 0x72, 0xf4, 0x27, 0xd3, 0x8b, 0x7c, 0xc4, 0x2a, 0x9d, 0xcd, 0x78, - 0x98, 0x4b, 0xab, 0x48, 0x2a, 0x4e, 0xbf, 0x41, 0xfa, 0x38, 0xeb, 0xc4, - 0x98, 0xf9, 0x55, 0xe4, 0x59, 0x4f, 0x67, 0x0c, 0x0f, 0x5e, 0xcb, 0xaf, - 0x60, 0x9e, 0x8b, 0x1b, 0x01, 0x55, 0xc1, 0xf8, 0x4d, 0x21, 0x67, 0x4a, - 0x7e, 0xb2, 0xac, 0x19, 0xe1, 0x21, 0x1e, 0x4f, 0x0f, 0x43, 0x72, 0x96, - 0xb5, 0xf4, 0x9e, 0x64, 0x19, 0xd6, 0xc5, 0x83, 0x58, 0xaa, 0xf7, 0xaa, - 0xce, 0x42, 0xdc, 0x38, 0x8f, 0x6f, 0xa9, 0xbb, 0x67, 0x53, 0x8c, 0xed, - 0x0c, 0x75, 0x53, 0x81, 0x4b, 0x61, 0xe1, 0x11, 0xd5, 0x5e, 0xdd, 0x85, - 0x77, 0xef, 0x52, 0x08, 0xe9, 0x69, 0x5c, 0x68, 0x0e, 0xd1, 0xaf, 0x3a, - 0x89, 0x31, 0xa2, 0x70, 0xcf, 0x45, 0x82, 0x5b, 0x69, 0x8b, 0xca, 0xb9, - 0x3a, 0xda, 0x87, 0xbe, 0x47, 0x1d, 0xb6, 0x51, 0x87, 0x5b, 0xa6, 0x11, - 0xaa, 0x48, 0xf5, 0xa8, 0x8e, 0x42, 0xbb, 0x6a, 0x2f, 0x68, 0xd4, 0x93, - 0xe8, 0xe4, 0x3b, 0xc4, 0x4a, 0xe2, 0x2b, 0x25, 0x5b, 0x8a, 0xbf, 0xde, - 0x68, 0xcf, 0x8c, 0x4b, 0x62, 0x6e, 0xdd, 0xf2, 0x14, 0xe3, 0xd1, 0x45, - 0xbe, 0x84, 0x07, 0x1f, 0xaa, 0x1b, 0xac, 0xa5, 0x57, 0x92, 0x4c, 0x9e, - 0x15, 0x29, 0x1c, 0x2f, 0x74, 0xd1, 0x2e, 0xab, 0x8b, 0xfe, 0x15, 0x0a, - 0x6e, 0x9c, 0x6c, 0x57, 0x1b, 0x67, 0x17, 0x05, 0xbb, 0x69, 0xc3, 0xee, - 0xd9, 0x88, 0xd0, 0xe5, 0xfa, 0x62, 0xdb, 0x34, 0x5c, 0xfa, 0xbf, 0x64, - 0xcb, 0x6f, 0x93, 0x96, 0xd8, 0xd3, 0x5f, 0xf2, 0xd3, 0xe0, 0xdd, 0x93, - 0x69, 0xbc, 0xbb, 0xda, 0xcb, 0x9a, 0x5a, 0xc2, 0x14, 0x55, 0xc5, 0xef, - 0xd3, 0x2e, 0xe8, 0x83, 0xaa, 0x53, 0xfc, 0xc8, 0xeb, 0xac, 0x79, 0xc7, - 0x24, 0xbc, 0x84, 0x0a, 0x51, 0x37, 0x31, 0xdd, 0x87, 0xc9, 0x78, 0xef, - 0x39, 0xd5, 0xa5, 0xba, 0x0a, 0x52, 0x83, 0x1d, 0x9f, 0x6a, 0xa3, 0x4f, - 0xb5, 0x93, 0x9f, 0x76, 0xfa, 0xd4, 0x16, 0xf2, 0xb3, 0xc5, 0xf6, 0x29, - 0xf1, 0xcd, 0xdf, 0xe6, 0x65, 0x43, 0xe1, 0x6e, 0x5b, 0x2f, 0x5b, 0xf9, - 0x6e, 0x27, 0xe5, 0xe8, 0xe4, 0x7b, 0x77, 0xf3, 0xbd, 0xbb, 0x67, 0xff, - 0x97, 0xf0, 0x47, 0x59, 0x9c, 0xd8, 0xbf, 0x5e, 0xd3, 0x24, 0x07, 0xfc, - 0xac, 0x88, 0x29, 0x90, 0x75, 0xa5, 0x24, 0x47, 0x0c, 0xa0, 0xbb, 0x19, - 0xbe, 0x45, 0xa9, 0x67, 0x5b, 0xb7, 0xd7, 0x33, 0x9f, 0x31, 0x9f, 0xfa, - 0x8e, 0x13, 0x4b, 0x33, 0x47, 0xcf, 0xb4, 0x28, 0x8c, 0x18, 0x37, 0x33, - 0x4e, 0x0d, 0x1c, 0x29, 0x68, 0x9d, 0x51, 0xde, 0x6b, 0x1a, 0x13, 0x8c, - 0xbf, 0x0f, 0x6d, 0xc4, 0x75, 0x91, 0x54, 0x3f, 0x22, 0x66, 0x2c, 0x72, - 0x44, 0x69, 0xfd, 0x1b, 0xa0, 0x5d, 0x64, 0x6d, 0x18, 0x9c, 0x56, 0xda, - 0x40, 0xad, 0x5b, 0x4b, 0xbf, 0x61, 0xe3, 0xeb, 0x7d, 0x58, 0x6e, 0x63, - 0xb8, 0x7e, 0x24, 0x88, 0x65, 0xb7, 0x92, 0xe6, 0xde, 0x75, 0x0a, 0x97, - 0x8d, 0x0f, 0x69, 0x47, 0x2d, 0x9d, 0x55, 0x06, 0x72, 0xcc, 0x13, 0x91, - 0xe3, 0x82, 0xd5, 0xf7, 0x11, 0xab, 0xc3, 0x17, 0xe0, 0xb3, 0xb9, 0xb1, - 0xd8, 0xa0, 0xcf, 0xad, 0x25, 0x88, 0xd3, 0xd3, 0xa4, 0x69, 0x14, 0x88, - 0xdf, 0xb9, 0x46, 0x74, 0x4f, 0x91, 0x66, 0xbc, 0x48, 0x53, 0xcf, 0x83, - 0x71, 0x73, 0x04, 0x9b, 0xe2, 0xac, 0x15, 0xcc, 0x79, 0x47, 0xa5, 0x27, - 0x20, 0xbd, 0xf2, 0xe3, 0x06, 0xff, 0x1e, 0x54, 0x3b, 0x24, 0xa6, 0xca, - 0x1d, 0x2b, 0x54, 0x73, 0x8d, 0xaa, 0xd4, 0x41, 0xcc, 0xd9, 0x6b, 0x0c, - 0xc8, 0x1a, 0x03, 0xbf, 0x50, 0x5a, 0xe2, 0x9c, 0x92, 0x5c, 0xdd, 0x98, - 0x39, 0xc7, 0x18, 0x3a, 0xac, 0xb4, 0x96, 0x63, 0x14, 0xdf, 0xaf, 0x0b, - 0xfd, 0x83, 0xc5, 0x75, 0x06, 0xd0, 0x90, 0x67, 0x7c, 0x16, 0x7c, 0x6a, - 0xc3, 0x44, 0x1b, 0x46, 0xa6, 0xdb, 0x30, 0x3c, 0xa1, 0x70, 0xb7, 0xb1, - 0x18, 0x97, 0x6e, 0xb6, 0xfb, 0x94, 0xaa, 0xa5, 0x7a, 0x2d, 0x86, 0x42, - 0xa8, 0x76, 0xe9, 0x5f, 0xc1, 0xae, 0x22, 0xc6, 0xdf, 0x74, 0xa2, 0x9b, - 0x79, 0xdf, 0xc2, 0xfb, 0x8c, 0xa5, 0x58, 0x0d, 0xd2, 0xde, 0x54, 0x0b, - 0xf1, 0x78, 0x9d, 0xdb, 0x89, 0xf7, 0x0f, 0x7d, 0x8e, 0x0d, 0x44, 0xff, - 0x9f, 0xbf, 0xd7, 0x86, 0xc7, 0x27, 0xca, 0xd0, 0xb2, 0x1a, 0x77, 0x46, - 0x50, 0xe5, 0x62, 0x8d, 0x7b, 0x73, 0xbb, 0x1a, 0xe4, 0x3d, 0xfb, 0x59, - 0xdf, 0x97, 0x53, 0x46, 0xea, 0x4f, 0x1a, 0xe4, 0xba, 0x9d, 0x37, 0x6e, - 0xb8, 0xde, 0xfd, 0x05, 0xd7, 0x15, 0x9e, 0x61, 0x22, 0xfb, 0x01, 0x6b, - 0x4a, 0x3e, 0x67, 0xc1, 0x9d, 0xf2, 0xa0, 0x7f, 0x2c, 0x8a, 0x7d, 0x73, - 0x61, 0xcc, 0xe5, 0xb4, 0xde, 0x4b, 0xec, 0x1f, 0x76, 0x35, 0xeb, 0x78, - 0x60, 0x2e, 0x82, 0xd9, 0x1c, 0x2c, 0x7f, 0x4a, 0x9f, 0xf7, 0xab, 0x04, - 0xf6, 0xce, 0xd5, 0xe1, 0x5c, 0x4e, 0xbf, 0x38, 0xac, 0xe2, 0x83, 0xb5, - 0xc4, 0x1d, 0x0f, 0xce, 0x35, 0x61, 0xff, 0x9c, 0x8f, 0xef, 0x58, 0xd8, - 0x92, 0xac, 0xe3, 0xf3, 0x2e, 0x3c, 0x7d, 0xd2, 0xb2, 0x04, 0x77, 0xf5, - 0xcf, 0x01, 0xb3, 0xe3, 0xac, 0x45, 0x67, 0x58, 0x97, 0x9e, 0x00, 0xf6, - 0x3e, 0xe1, 0xc2, 0xf4, 0xb8, 0x85, 0x5d, 0xc6, 0x70, 0xad, 0x8b, 0x0e, - 0xdf, 0xcb, 0xba, 0xe1, 0x65, 0x0d, 0xbc, 0x27, 0xe4, 0xe4, 0xf3, 0x4b, - 0xcc, 0x53, 0xf7, 0x3d, 0x91, 0xc0, 0x9b, 0xb9, 0x2c, 0xb6, 0x10, 0x9f, - 0x0f, 0x92, 0x97, 0x37, 0x72, 0xac, 0x63, 0x73, 0x06, 0x5e, 0xcf, 0xf9, - 0xb8, 0x4e, 0x13, 0x5e, 0xca, 0xc9, 0x33, 0xf2, 0x6c, 0x00, 0x7d, 0xe4, - 0xe5, 0xb5, 0x5c, 0x84, 0x6b, 0x86, 0xf1, 0x53, 0x3e, 0x77, 0xef, 0x9c, - 0xce, 0xba, 0xe5, 0xe3, 0xba, 0x51, 0xbc, 0x92, 0x0b, 0x90, 0xd7, 0x30, - 0x6b, 0x55, 0x1f, 0x46, 0x72, 0x8d, 0x17, 0x37, 0x30, 0x51, 0x3b, 0xb5, - 0x46, 0xae, 0xbd, 0x63, 0x75, 0xd9, 0xb1, 0x28, 0xeb, 0x94, 0xd6, 0xed, - 0xc3, 0x70, 0xee, 0x75, 0x77, 0xa9, 0x9f, 0x7e, 0x66, 0x7c, 0xc1, 0xc6, - 0x7e, 0x4f, 0x9b, 0xfc, 0x7d, 0x1a, 0x38, 0x67, 0x66, 0xad, 0xea, 0x14, - 0xb1, 0x2e, 0x6b, 0xd4, 0x5b, 0x6b, 0x9a, 0xb8, 0xae, 0xde, 0xfb, 0xa2, - 0x92, 0x7e, 0xc7, 0x83, 0xe8, 0x13, 0xa2, 0x2f, 0x62, 0xe6, 0x59, 0xe0, - 0x47, 0xc4, 0x9f, 0x0d, 0x63, 0x9a, 0xf8, 0x7d, 0x86, 0xb8, 0xa6, 0x7b, - 0x1e, 0xf5, 0x89, 0x07, 0x30, 0x64, 0x95, 0x11, 0x9f, 0x57, 0x13, 0xd7, - 0xce, 0x35, 0xb1, 0x4e, 0xad, 0xb1, 0xac, 0xbf, 0x6d, 0x86, 0xe5, 0x4a, - 0xe9, 0x46, 0xad, 0x7b, 0xfe, 0x2b, 0x55, 0xd0, 0x2f, 0x06, 0x95, 0x3e, - 0xff, 0x16, 0xe2, 0x03, 0xe7, 0x21, 0x7a, 0x05, 0x56, 0xcc, 0x79, 0xb0, - 0x92, 0xf2, 0x6c, 0x1c, 0xe3, 0xda, 0xc4, 0x27, 0x71, 0xca, 0xb4, 0x6d, - 0x8c, 0x98, 0x4b, 0x0f, 0x60, 0x39, 0x75, 0xdc, 0x7f, 0xca, 0xb2, 0xca, - 0xa9, 0xe3, 0x06, 0xda, 0x67, 0xcf, 0x09, 0x0b, 0x2f, 0x1a, 0x2f, 0x52, - 0xa7, 0x8a, 0xb8, 0xb1, 0x99, 0xef, 0x84, 0xf9, 0xbc, 0x0f, 0x7b, 0xc7, - 0xa4, 0x5f, 0xaa, 0xe3, 0x33, 0xaf, 0xe2, 0x58, 0x2e, 0x81, 0x26, 0xea, - 0x2f, 0x4a, 0x9a, 0x8d, 0x7c, 0x27, 0x4a, 0x7a, 0xd1, 0xb9, 0xaf, 0x61, - 0xf3, 0x29, 0x05, 0x3d, 0x2e, 0x3a, 0xf8, 0x1a, 0xda, 0xcf, 0x7c, 0x51, - 0x4e, 0x60, 0x96, 0x1a, 0xd7, 0x8e, 0xcc, 0x13, 0x7f, 0x57, 0xa5, 0x86, - 0xc0, 0xfa, 0x8d, 0x37, 0xa6, 0x14, 0x8e, 0x8f, 0xb3, 0xdf, 0x5b, 0x03, - 0xab, 0x82, 0x32, 0xbd, 0x3e, 0xf5, 0x3b, 0x78, 0xea, 0x24, 0xf5, 0xf0, - 0x64, 0x18, 0x3f, 0xc8, 0x79, 0xb0, 0xec, 0xb8, 0x60, 0x3a, 0x3d, 0xb1, - 0x4f, 0x49, 0x7f, 0x24, 0x7d, 0x4b, 0x3c, 0xea, 0x55, 0x2e, 0xd4, 0x3f, - 0xe5, 0x81, 0x7e, 0x2e, 0x0a, 0x6f, 0xbd, 0x0f, 0x7a, 0xfd, 0x1f, 0x32, - 0xd7, 0xb8, 0x50, 0xc6, 0x5e, 0x76, 0xd3, 0x77, 0x13, 0xbc, 0x16, 0xe6, - 0x35, 0xfc, 0x4e, 0x39, 0xdc, 0x4b, 0xdc, 0xac, 0xe1, 0x65, 0x3a, 0xf1, - 0x98, 0xc7, 0xb2, 0xdc, 0xac, 0x0d, 0x3b, 0xbe, 0x67, 0x59, 0xb1, 0xd5, - 0xf2, 0x7c, 0x08, 0xb1, 0x73, 0x3a, 0x9f, 0x73, 0xea, 0xe5, 0x75, 0x3c, - 0xe6, 0xa6, 0x1f, 0x49, 0xac, 0xb2, 0xde, 0xdb, 0x3d, 0x94, 0x83, 0xdb, - 0x9f, 0x2b, 0x08, 0xb6, 0x89, 0xda, 0x32, 0x9c, 0x1d, 0x57, 0xcc, 0xd9, - 0x29, 0x3e, 0xbb, 0x1e, 0xee, 0xa4, 0x76, 0x24, 0x4b, 0x3f, 0xd8, 0x15, - 0x6a, 0xc1, 0x33, 0xa6, 0x17, 0x95, 0xfa, 0x12, 0xdc, 0xdf, 0x1d, 0xc2, - 0x33, 0xec, 0x0b, 0x68, 0xb3, 0xc4, 0x3c, 0xd8, 0x48, 0x07, 0x49, 0xcf, - 0xf5, 0x63, 0xe8, 0xdf, 0x75, 0x31, 0xcf, 0xb9, 0xed, 0x3c, 0x57, 0x56, - 0x0f, 0xcc, 0xe7, 0x3d, 0xb8, 0xa0, 0x3b, 0x98, 0xf0, 0x39, 0xbb, 0x66, - 0x6b, 0xa1, 0xf9, 0x6b, 0x58, 0x50, 0x6b, 0x49, 0x2b, 0x32, 0x13, 0x14, - 0xdd, 0x65, 0x3c, 0x8e, 0x2f, 0xfd, 0x8d, 0x5b, 0x7a, 0x8e, 0xeb, 0x7f, - 0x57, 0xc0, 0x95, 0xd2, 0x22, 0x6d, 0x6e, 0xf8, 0x3c, 0xa9, 0xce, 0xd6, - 0x51, 0xfd, 0x4b, 0x37, 0xf0, 0xde, 0x84, 0x91, 0xc2, 0xf5, 0x5e, 0xbb, - 0x33, 0x67, 0xfb, 0x50, 0xa7, 0xe8, 0xfe, 0x31, 0x43, 0xf2, 0xec, 0xa0, - 0x6a, 0x67, 0xde, 0xca, 0x7a, 0x90, 0xad, 0xe2, 0x33, 0xd4, 0x3f, 0x0e, - 0x8f, 0x09, 0x9d, 0x83, 0x18, 0xcd, 0xc9, 0x6c, 0x63, 0x00, 0xeb, 0xcc, - 0x58, 0xe2, 0x22, 0x7b, 0xe8, 0x43, 0x90, 0x39, 0x44, 0xe3, 0xfc, 0xcb, - 0x4a, 0x1b, 0xbc, 0xc5, 0xad, 0xf5, 0x2f, 0x28, 0x27, 0x6f, 0xad, 0x28, - 0xe6, 0xad, 0xe5, 0xf9, 0x25, 0xc1, 0x2e, 0xd6, 0x83, 0xae, 0xd9, 0x52, - 0x7d, 0xe8, 0x52, 0x9b, 0xec, 0xda, 0x9a, 0x51, 0x5b, 0x67, 0x7d, 0xaa, - 0x63, 0xc2, 0x87, 0x97, 0x89, 0xc5, 0xa6, 0x7a, 0x10, 0x5a, 0xb6, 0x06, - 0xfe, 0xad, 0x13, 0xdd, 0x28, 0xd7, 0xa5, 0x87, 0x2c, 0xc7, 0x26, 0xbb, - 0xae, 0xd5, 0x05, 0xbb, 0x58, 0x7f, 0xba, 0x0a, 0x3d, 0xcc, 0x7f, 0x08, - 0xf9, 0x53, 0xce, 0xcc, 0x40, 0x72, 0xe1, 0xed, 0x7c, 0xf7, 0x62, 0x72, - 0x11, 0xe0, 0xd4, 0x3f, 0x95, 0x61, 0x2f, 0x51, 0xbd, 0x5a, 0xe1, 0xd2, - 0x9d, 0x3e, 0x90, 0x16, 0x7b, 0xfe, 0x7c, 0xeb, 0x85, 0xf1, 0x6e, 0xd5, - 0x31, 0x3d, 0xe3, 0xdf, 0x68, 0xca, 0x2c, 0x62, 0xca, 0xdf, 0x4e, 0x1e, - 0xda, 0x67, 0x9f, 0xf4, 0x6f, 0x20, 0x4f, 0x1b, 0x66, 0x3f, 0x4f, 0x53, - 0xea, 0x4a, 0x7f, 0x6b, 0x1b, 0x63, 0x7b, 0x87, 0xf1, 0x91, 0x15, 0xfd, - 0xa6, 0xd0, 0x99, 0x2b, 0xea, 0x33, 0x4d, 0xbe, 0xc2, 0xbe, 0x4d, 0x85, - 0x90, 0x2f, 0x5d, 0x68, 0xf7, 0xb7, 0x99, 0xdd, 0xfe, 0x0d, 0x66, 0x8f, - 0xbf, 0xdd, 0xdc, 0x49, 0xda, 0x5d, 0xfe, 0x0e, 0x93, 0x71, 0x5d, 0xe8, - 0xa1, 0x5e, 0xbb, 0x31, 0x5a, 0xd8, 0x49, 0xec, 0x21, 0x34, 0x7b, 0x89, - 0x83, 0xfc, 0x94, 0x71, 0x88, 0x32, 0xce, 0x47, 0xbc, 0x48, 0x6b, 0x5e, - 0xea, 0x6b, 0xc4, 0xb6, 0xe3, 0x11, 0x7b, 0x16, 0x55, 0x91, 0x7a, 0xa0, - 0x75, 0xcb, 0x09, 0xe6, 0xfb, 0xd4, 0x9e, 0xd6, 0x65, 0xa7, 0x50, 0xe3, - 0x4d, 0x49, 0xef, 0xcc, 0x7e, 0x38, 0x1e, 0x37, 0xde, 0x43, 0x3c, 0xf2, - 0x32, 0x9f, 0x1d, 0xa6, 0xef, 0x8e, 0xd8, 0xf3, 0x07, 0x1a, 0x24, 0xdf, - 0x84, 0x2d, 0xa6, 0xcf, 0xbf, 0x8d, 0xbd, 0x59, 0x30, 0xa5, 0xb5, 0xdc, - 0xee, 0x96, 0x79, 0xc8, 0xfc, 0xef, 0x05, 0xd0, 0x84, 0xce, 0x82, 0x8f, - 0x72, 0x7d, 0x09, 0x7f, 0x7f, 0x92, 0x75, 0x0d, 0xe2, 0x87, 0x96, 0x75, - 0x2f, 0xfb, 0x9a, 0xa3, 0xf9, 0x3a, 0x5c, 0xb6, 0x6d, 0xec, 0xc1, 0xe1, - 0x7c, 0x14, 0xef, 0x50, 0x3e, 0xcf, 0x5c, 0x2d, 0xde, 0x1e, 0x77, 0x63, - 0xb7, 0x71, 0x5b, 0xb1, 0x5e, 0xb8, 0x70, 0x4f, 0xe2, 0x00, 0xb1, 0x83, - 0x0b, 0xd5, 0xc4, 0x6f, 0x0f, 0xda, 0xd7, 0xdc, 0xec, 0xff, 0xbe, 0x8e, - 0x41, 0xa7, 0x9e, 0x90, 0xc7, 0x9d, 0xe4, 0xb1, 0xd9, 0xbf, 0x61, 0x42, - 0xf3, 0xdf, 0x31, 0x01, 0x9f, 0x37, 0xb5, 0xab, 0xf5, 0xcc, 0x49, 0x0b, - 0x7d, 0xc6, 0xad, 0xb8, 0x72, 0x72, 0xb8, 0xdf, 0x43, 0xff, 0xf9, 0x65, - 0x32, 0x03, 0x73, 0x12, 0x17, 0x88, 0x3c, 0x5e, 0x0d, 0x30, 0xb7, 0x37, - 0x24, 0xe3, 0x21, 0xd6, 0x62, 0x63, 0x96, 0xb1, 0xd9, 0x01, 0xad, 0x9f, - 0x35, 0x39, 0xed, 0x4e, 0xc5, 0x7b, 0x47, 0x08, 0x1e, 0xab, 0xc8, 0x8f, - 0x9f, 0xb9, 0x3b, 0x30, 0x17, 0xf5, 0xef, 0x60, 0xbd, 0x89, 0xb0, 0xbf, - 0xf3, 0xc7, 0x71, 0x5b, 0x2d, 0xe2, 0x89, 0x05, 0xca, 0xed, 0x9d, 0x6b, - 0xf2, 0xdf, 0xce, 0xfa, 0x71, 0x39, 0x6e, 0x0d, 0xbd, 0x68, 0x04, 0x10, - 0x9c, 0x33, 0xa8, 0xef, 0x0c, 0x86, 0x67, 0xd9, 0x72, 0xc5, 0xd9, 0xf3, - 0xcf, 0xb5, 0xf8, 0xb7, 0x31, 0x36, 0xab, 0x68, 0xa2, 0xc6, 0xb9, 0xb4, - 0x5f, 0x7a, 0xbe, 0xa6, 0xb9, 0xb5, 0xe4, 0x4f, 0x7c, 0x74, 0x5f, 0xeb, - 0x3a, 0xfa, 0x43, 0x74, 0x0e, 0x9b, 0x98, 0xe6, 0x5e, 0x22, 0xcd, 0x4c, - 0x84, 0x18, 0x76, 0xef, 0x9a, 0x00, 0xf3, 0x94, 0xe8, 0x92, 0x7a, 0x2c, - 0x94, 0x64, 0x92, 0xba, 0xbc, 0xa7, 0x75, 0xee, 0x94, 0xd4, 0xe5, 0x4c, - 0x6b, 0xee, 0x94, 0x8e, 0x77, 0x58, 0x5b, 0x56, 0x24, 0x35, 0xe3, 0x9c, - 0x8a, 0x45, 0x5e, 0xa5, 0x2c, 0x1e, 0xfc, 0xca, 0xda, 0xa5, 0xc7, 0xe7, - 0x6f, 0x61, 0x3c, 0x55, 0x33, 0x37, 0x46, 0x98, 0xf3, 0xab, 0xe7, 0xa8, - 0x98, 0x39, 0xb7, 0x17, 0x15, 0x11, 0xf8, 0xe2, 0x3a, 0xde, 0x3d, 0x99, - 0xa0, 0x1e, 0xae, 0xd1, 0xdc, 0x47, 0xa8, 0xd5, 0xc7, 0x52, 0xf8, 0xc8, - 0x53, 0xf4, 0xc5, 0x51, 0xae, 0x5b, 0x36, 0x27, 0x3c, 0xcb, 0xf3, 0x61, - 0x3e, 0x7f, 0x7d, 0xed, 0x6a, 0xae, 0xfd, 0xd1, 0x29, 0xf1, 0xd7, 0x4c, - 0xeb, 0x85, 0x93, 0xce, 0xda, 0xf1, 0x64, 0x02, 0x1f, 0x9e, 0xd4, 0x06, - 0xde, 0x55, 0xb1, 0xde, 0x0b, 0x4a, 0xd6, 0x47, 0x5d, 0x15, 0xae, 0x58, - 0xc3, 0xf1, 0xf8, 0xe0, 0x2e, 0xd2, 0x6c, 0x59, 0x4b, 0xfd, 0xdb, 0x7c, - 0xd0, 0xe7, 0x99, 0x67, 0xbd, 0xe4, 0xc7, 0xe1, 0xa5, 0x8e, 0xb4, 0x4f, - 0x16, 0x7b, 0x35, 0xf6, 0xa9, 0xd7, 0xf9, 0x09, 0x53, 0x0f, 0xbe, 0x1d, - 0xcd, 0x01, 0xd4, 0xda, 0xcf, 0x85, 0xf8, 0x9c, 0xe8, 0xe1, 0xd7, 0xca, - 0xa5, 0xbf, 0xc7, 0x3c, 0x26, 0xb9, 0x24, 0xcc, 0x1c, 0xb6, 0x53, 0x7a, - 0xda, 0x6c, 0x96, 0xfe, 0xee, 0xa5, 0xbf, 0x6f, 0x14, 0x9f, 0x36, 0xe9, - 0xd3, 0x26, 0x7d, 0xda, 0xd4, 0x22, 0x03, 0x88, 0x85, 0xfa, 0x68, 0xb7, - 0x74, 0x44, 0x7c, 0xbd, 0x07, 0xbb, 0xf9, 0xd9, 0xc3, 0xfb, 0x87, 0xd9, - 0xe7, 0x62, 0x91, 0xac, 0x79, 0x10, 0xed, 0xe6, 0x23, 0xe8, 0x9f, 0xc0, - 0x6f, 0xfc, 0xcd, 0xe5, 0x28, 0x5f, 0x2e, 0x3d, 0xbc, 0x16, 0x3a, 0x8a, - 0x47, 0xd8, 0x47, 0xfd, 0x5a, 0x55, 0xea, 0x9e, 0xee, 0x63, 0x4a, 0x0b, - 0xb5, 0xb3, 0x1f, 0xde, 0x55, 0xd8, 0x49, 0xfb, 0xc6, 0xfa, 0x5f, 0x56, - 0xec, 0xa5, 0x6a, 0xb9, 0x36, 0x63, 0xe9, 0x0e, 0xae, 0x63, 0x0a, 0x1f, - 0x76, 0xbe, 0xfd, 0x7d, 0x88, 0x6e, 0x7f, 0xd2, 0xd0, 0xc7, 0xf5, 0x1d, - 0x3e, 0x86, 0xd9, 0x53, 0xf6, 0x31, 0xc6, 0x76, 0xdb, 0xf1, 0xd5, 0x43, - 0x1a, 0xd7, 0xf3, 0xd8, 0x86, 0x9c, 0xd4, 0x52, 0x0b, 0x8f, 0x1a, 0x16, - 0x9e, 0xe6, 0xe7, 0x22, 0x73, 0xd9, 0xc8, 0x0d, 0xb9, 0xcc, 0xc5, 0xe7, - 0x76, 0xf0, 0xb9, 0x16, 0xa6, 0xce, 0xd9, 0x69, 0x99, 0x0d, 0x1e, 0x94, - 0xd9, 0x20, 0xf2, 0xa6, 0xe8, 0x7e, 0x00, 0x17, 0x72, 0xb1, 0x41, 0xb7, - 0xdb, 0x1a, 0x62, 0x5c, 0x5d, 0xfc, 0x88, 0xbe, 0xfb, 0xda, 0x1a, 0xad, - 0x9b, 0x3a, 0x4c, 0x8c, 0x29, 0x2d, 0xf2, 0x33, 0xcc, 0x6f, 0xf2, 0xa1, - 0x31, 0xba, 0xd2, 0x1d, 0x0f, 0x9d, 0x85, 0x36, 0xdf, 0x47, 0x49, 0x9f, - 0x2c, 0x38, 0xb9, 0x6e, 0x5d, 0x31, 0xd7, 0xb5, 0xe4, 0x2b, 0xd4, 0x1d, - 0x13, 0xac, 0xcf, 0xd3, 0x56, 0x36, 0xc8, 0x7a, 0x55, 0x98, 0x16, 0xda, - 0x43, 0x68, 0x4c, 0x0a, 0x2d, 0xbd, 0x73, 0x4c, 0xe1, 0x1b, 0x95, 0x88, - 0xb3, 0x56, 0xc1, 0x28, 0xd7, 0xb3, 0x16, 0x6b, 0x52, 0xc8, 0x9b, 0x92, - 0xda, 0xd9, 0xc5, 0xbe, 0xa5, 0x87, 0x79, 0x51, 0x30, 0xb5, 0xcc, 0x4b, - 0x9d, 0x7c, 0xb4, 0xb1, 0x20, 0x76, 0x11, 0x9b, 0x88, 0x6d, 0x0e, 0xe2, - 0x1e, 0x53, 0x7a, 0x7f, 0x0b, 0xe3, 0x46, 0x3c, 0xfa, 0x14, 0xc4, 0x4e, - 0x07, 0xa9, 0x0b, 0x2f, 0x76, 0x33, 0x0f, 0xee, 0x6a, 0xa6, 0xae, 0x82, - 0x5e, 0xec, 0xb2, 0x67, 0x09, 0x25, 0xfd, 0x79, 0x69, 0x43, 0xc5, 0x1a, - 0x37, 0xeb, 0x75, 0xf4, 0xe8, 0xcc, 0x26, 0xdd, 0x29, 0xa1, 0x57, 0x9a, - 0x4b, 0x3a, 0xba, 0xdb, 0x94, 0x13, 0xba, 0x16, 0xce, 0x1a, 0x0e, 0x6e, - 0x2d, 0xe9, 0x2c, 0x42, 0xb9, 0x6a, 0xd6, 0x02, 0x2b, 0x6f, 0xc0, 0xae, - 0x15, 0xbc, 0xb6, 0xe5, 0x3a, 0x76, 0xcd, 0x08, 0x3e, 0x26, 0x76, 0xed, - 0xdc, 0x4a, 0xec, 0x5a, 0xaf, 0x4a, 0xb8, 0x55, 0xe6, 0x12, 0x25, 0xec, - 0x5a, 0x5d, 0xcc, 0xd1, 0x07, 0xb1, 0x8b, 0xb8, 0xa6, 0xb6, 0x7e, 0x08, - 0xbe, 0x55, 0xae, 0xcf, 0x5c, 0x18, 0x62, 0xbf, 0x52, 0x06, 0x2c, 0xb6, - 0x70, 0xcb, 0xea, 0xac, 0x55, 0xae, 0xd7, 0x47, 0xcb, 0x5d, 0x32, 0x77, - 0x8e, 0x67, 0x47, 0x98, 0x4b, 0x5c, 0xab, 0xb4, 0x6c, 0x1a, 0xbe, 0x50, - 0x8d, 0xbe, 0xb3, 0xd8, 0x2f, 0x44, 0x7c, 0x9b, 0x89, 0x7b, 0xe2, 0xc9, - 0x4f, 0xad, 0xa9, 0xb0, 0xd0, 0x98, 0x9f, 0xf7, 0x21, 0xfd, 0x90, 0x8f, - 0x75, 0x68, 0x41, 0x1d, 0xc1, 0x6b, 0xf1, 0x88, 0x6f, 0x5b, 0x21, 0xeb, - 0xdf, 0xd2, 0x70, 0x0b, 0xba, 0x4e, 0x49, 0xcd, 0x89, 0x62, 0xeb, 0xa9, - 0x76, 0xd6, 0x19, 0x1d, 0x1d, 0x63, 0x9d, 0xec, 0xe3, 0xba, 0x55, 0xf7, - 0xb4, 0xe8, 0x49, 0xf4, 0xac, 0x85, 0xa2, 0xae, 0x1b, 0xe7, 0xa2, 0xa5, - 0x9e, 0xf8, 0x3d, 0xdb, 0x87, 0x46, 0x8d, 0x10, 0xf5, 0xf3, 0x2b, 0x2f, - 0x82, 0x16, 0xce, 0x18, 0xe2, 0x7b, 0xfc, 0xdb, 0x4c, 0x63, 0x63, 0xf3, - 0xb8, 0xe5, 0xd1, 0x65, 0xbe, 0x1d, 0xb1, 0xed, 0xb6, 0x81, 0xb5, 0xac, - 0x7d, 0xba, 0x87, 0xb6, 0x2a, 0xcd, 0xb2, 0x6f, 0xb4, 0xd9, 0x7a, 0xff, - 0x46, 0xe6, 0x35, 0xf6, 0xe9, 0x3e, 0x1f, 0x73, 0xa5, 0xef, 0x94, 0x85, - 0x69, 0xe3, 0x4d, 0xeb, 0x51, 0xdd, 0x43, 0xbb, 0x7c, 0x95, 0x79, 0x57, - 0x70, 0x49, 0xca, 0x7f, 0xfb, 0xa4, 0xc7, 0x55, 0x95, 0x42, 0x73, 0x19, - 0x7d, 0xee, 0xd5, 0xa4, 0x33, 0x73, 0x3c, 0x96, 0xbf, 0xcd, 0xbf, 0x65, - 0x82, 0xbd, 0x04, 0x7b, 0x5d, 0xa7, 0xbf, 0xfb, 0xaa, 0xff, 0xee, 0x09, - 0xb7, 0xaa, 0x4d, 0xc1, 0xdd, 0xb2, 0xd6, 0xc2, 0xc7, 0xab, 0xe3, 0x83, - 0x11, 0x17, 0x73, 0x24, 0x69, 0x99, 0xf9, 0x66, 0x7f, 0x86, 0x39, 0x79, - 0xdb, 0x04, 0xd2, 0x32, 0x9f, 0x0d, 0xae, 0x1e, 0xee, 0x0d, 0x42, 0x66, - 0x69, 0xf8, 0x06, 0xa3, 0x32, 0x4c, 0x9f, 0x8b, 0xb4, 0xa9, 0xf8, 0x42, - 0x3f, 0xe2, 0x17, 0x3f, 0x76, 0xbf, 0x69, 0x3d, 0x9e, 0x5f, 0xcb, 0xe7, - 0x3b, 0x99, 0x2f, 0xd3, 0xcc, 0x9f, 0xc3, 0x83, 0x5e, 0xc8, 0x3b, 0x5a, - 0xe6, 0x0d, 0x15, 0xa3, 0xaf, 0xe3, 0x9b, 0x7c, 0x3e, 0xd4, 0xc1, 0x5c, - 0x39, 0x6d, 0xc4, 0xd3, 0x1b, 0x90, 0xed, 0xac, 0x86, 0x66, 0x34, 0x28, - 0x99, 0x7d, 0x89, 0x1d, 0x12, 0xf8, 0x39, 0xd7, 0xf4, 0xe8, 0xa2, 0xc7, - 0xf5, 0xe8, 0x9b, 0x66, 0xfd, 0xbf, 0xe6, 0x6f, 0xa2, 0x03, 0xd1, 0xcb, - 0x37, 0xcb, 0x50, 0xb1, 0x88, 0xb2, 0xfd, 0xdc, 0xce, 0x2b, 0x7e, 0x5d, - 0xc7, 0x7f, 0x26, 0x3e, 0xfa, 0x4f, 0x05, 0x99, 0x71, 0x96, 0x30, 0x9f, - 0xdd, 0x47, 0xb5, 0x2e, 0x9b, 0x4a, 0x14, 0x67, 0x9e, 0x3e, 0x7f, 0xe7, - 0xa4, 0x85, 0x93, 0x46, 0x10, 0xd2, 0xe3, 0x97, 0x27, 0xe7, 0x89, 0x00, - 0x9a, 0xd0, 0xc1, 0xeb, 0xed, 0x93, 0x95, 0xaa, 0x7d, 0xc2, 0xc2, 0x5f, - 0x18, 0x5a, 0xb6, 0xcd, 0xcd, 0x98, 0x36, 0xb4, 0xb3, 0xc0, 0x3b, 0xc4, - 0x4a, 0xe2, 0x63, 0x1e, 0x04, 0x74, 0x87, 0x56, 0xd3, 0xd4, 0x6d, 0xc4, - 0x0f, 0x12, 0x63, 0xee, 0x15, 0x15, 0x48, 0xaa, 0x29, 0x8f, 0xe8, 0xad, - 0x13, 0xe9, 0x42, 0xa5, 0xda, 0x4e, 0x5d, 0xde, 0xb1, 0xaa, 0x0c, 0x97, - 0x6c, 0x5d, 0xde, 0x46, 0x5d, 0xe2, 0xf5, 0xa5, 0x70, 0x5f, 0xa8, 0x45, - 0xa7, 0x82, 0xdd, 0x9f, 0x55, 0xb2, 0x4e, 0xa7, 0x89, 0x6f, 0x89, 0x07, - 0x43, 0x3d, 0xf8, 0x2e, 0xf3, 0xcd, 0xa3, 0xf4, 0xd5, 0x5f, 0xe9, 0x4d, - 0xa8, 0xf8, 0x5e, 0x33, 0xed, 0xb8, 0xd6, 0xbf, 0x79, 0x22, 0x83, 0xc7, - 0x66, 0x2d, 0x3c, 0xc5, 0x38, 0x69, 0x48, 0x66, 0x43, 0xe5, 0xec, 0xd7, - 0x58, 0xd3, 0x16, 0x4e, 0xd8, 0x7e, 0xbe, 0xab, 0x75, 0xfd, 0x4c, 0x04, - 0xee, 0xef, 0xca, 0xef, 0x3b, 0x5b, 0xa3, 0x33, 0xf2, 0x9d, 0xe1, 0xb7, - 0x85, 0x01, 0x43, 0x4b, 0x7f, 0xec, 0xae, 0x40, 0x65, 0xdc, 0xb2, 0x06, - 0x92, 0x72, 0xbd, 0xaf, 0x35, 0x61, 0xdf, 0xdf, 0xc3, 0xef, 0xd2, 0x4c, - 0xfa, 0x6f, 0x04, 0x0b, 0x46, 0xd3, 0x94, 0x79, 0x2b, 0xeb, 0x7b, 0x86, - 0xf5, 0xbd, 0x36, 0xa5, 0xa5, 0x77, 0xb8, 0x65, 0xfe, 0x32, 0x7f, 0xa0, - 0x9a, 0xd7, 0x6f, 0x2f, 0xd6, 0xf7, 0xaa, 0x53, 0x32, 0xd3, 0x23, 0x06, - 0x84, 0xb3, 0x17, 0xd2, 0xc5, 0xfa, 0x5e, 0x31, 0xe6, 0xc1, 0x16, 0xd6, - 0x76, 0x2f, 0xb1, 0xf8, 0xc6, 0x7c, 0x2d, 0xfc, 0x27, 0xdc, 0x88, 0x25, - 0x7f, 0x82, 0x03, 0xf4, 0xb1, 0x03, 0x09, 0xb7, 0x8a, 0x2e, 0x71, 0x51, - 0x4f, 0xff, 0x88, 0x7d, 0x21, 0x37, 0xaa, 0xf4, 0x9f, 0xe1, 0x81, 0x2f, - 0xa8, 0xe9, 0x99, 0x09, 0x89, 0xed, 0x5d, 0xad, 0x5b, 0x4e, 0x39, 0x35, - 0x3d, 0x70, 0x6a, 0x78, 0x41, 0x6a, 0x7a, 0xed, 0xea, 0x0c, 0x4e, 0x4f, - 0xe2, 0x3b, 0x4b, 0x09, 0x1e, 0x6b, 0xb9, 0x66, 0x7d, 0x32, 0xce, 0xde, - 0x5a, 0xeb, 0xef, 0x50, 0xf1, 0x23, 0x55, 0xcc, 0x01, 0xa7, 0x59, 0xd3, - 0x7d, 0xa9, 0x78, 0x28, 0xe1, 0x42, 0x97, 0x97, 0xf6, 0x78, 0x9f, 0x7d, - 0xf6, 0x5b, 0xf9, 0x28, 0x69, 0x96, 0xc1, 0xc3, 0x9a, 0xfe, 0xbe, 0x8e, - 0xcf, 0xdc, 0xf4, 0xbd, 0x77, 0xdc, 0x3e, 0x5c, 0xcd, 0x3b, 0x35, 0xbd, - 0xba, 0xc1, 0x1a, 0xba, 0x9c, 0x0c, 0xe0, 0x4a, 0xde, 0xa0, 0x0f, 0x66, - 0x70, 0x98, 0x35, 0xfd, 0xb2, 0x1e, 0xc2, 0x87, 0xf9, 0x16, 0xfa, 0x65, - 0x18, 0xbf, 0x24, 0xfe, 0x5d, 0xc5, 0x9a, 0x7e, 0x27, 0x7d, 0x2a, 0xc9, - 0x9a, 0xde, 0x66, 0xe3, 0x8d, 0x7d, 0xad, 0x67, 0xc6, 0xed, 0x9a, 0xde, - 0xe0, 0x62, 0x3d, 0xf4, 0x22, 0xbe, 0xc0, 0x3c, 0x61, 0xfd, 0x6a, 0x6d, - 0x80, 0xcf, 0x52, 0x6f, 0x85, 0xd5, 0x98, 0xb2, 0x6b, 0xd0, 0x7a, 0xff, - 0x76, 0xae, 0xbd, 0xd8, 0x8e, 0x33, 0x0b, 0x5b, 0x57, 0xbd, 0x86, 0x3f, - 0xaa, 0x71, 0xd1, 0x0f, 0x53, 0xfe, 0x3b, 0x18, 0x6b, 0xc1, 0x54, 0x69, - 0xe6, 0x91, 0xe0, 0x3a, 0xb7, 0xf9, 0xef, 0xa4, 0x6f, 0xdc, 0xb2, 0x8a, - 0x99, 0x24, 0xe4, 0xc4, 0x59, 0x3b, 0xe3, 0x2c, 0xc2, 0x38, 0x5b, 0xca, - 0x38, 0x7b, 0xdc, 0x88, 0x27, 0xd6, 0x13, 0x77, 0xbd, 0x9c, 0x97, 0x58, - 0x6b, 0x26, 0x5d, 0x8d, 0x72, 0x0d, 0xf7, 0x4a, 0xcc, 0x6c, 0x5d, 0x35, - 0x7c, 0xb6, 0x12, 0xa2, 0x2b, 0x7c, 0xb6, 0x98, 0x18, 0x83, 0x99, 0xe9, - 0xe2, 0x82, 0x3b, 0x3e, 0x78, 0xab, 0x3b, 0x3e, 0xf0, 0x9e, 0x7a, 0xd3, - 0x7a, 0x9d, 0x71, 0xb6, 0x8d, 0x71, 0xb6, 0x9d, 0x71, 0xd6, 0x66, 0x5a, - 0x78, 0x2e, 0xa9, 0x65, 0x9a, 0x5c, 0x31, 0xa3, 0xcd, 0x85, 0xa5, 0x95, - 0x2c, 0x0d, 0x7e, 0xc4, 0x3b, 0xff, 0x88, 0xfc, 0x5f, 0x34, 0xe2, 0xdd, - 0x09, 0x25, 0xb1, 0x15, 0xc5, 0x07, 0x94, 0xbb, 0xbc, 0x18, 0x5b, 0x7b, - 0xa7, 0xcf, 0x17, 0x7d, 0xa3, 0x24, 0xbb, 0x1b, 0xcf, 0x1a, 0xcc, 0xa5, - 0x8b, 0xb4, 0x68, 0xd6, 0xd5, 0x83, 0x23, 0xd4, 0xa3, 0x3f, 0xde, 0x83, - 0xa3, 0xac, 0x87, 0xf7, 0xb2, 0x0e, 0xdf, 0x67, 0xc6, 0x5a, 0x36, 0xb3, - 0xff, 0xb9, 0x14, 0xd1, 0xa2, 0x51, 0xd5, 0x83, 0x3e, 0xfa, 0x70, 0x1f, - 0xeb, 0x46, 0x9b, 0xf9, 0x6b, 0xd5, 0x41, 0xac, 0xb0, 0xa7, 0x20, 0xef, - 0x69, 0x89, 0x5e, 0x57, 0x3f, 0x7a, 0x67, 0x25, 0xb7, 0x21, 0x74, 0x53, - 0xaa, 0x07, 0xc7, 0xcd, 0x32, 0xf4, 0x34, 0x77, 0xa9, 0xdb, 0x0b, 0x32, - 0x7f, 0x63, 0x3c, 0x9a, 0x8c, 0x57, 0x9b, 0x5f, 0x85, 0x7c, 0xbc, 0x0b, - 0x39, 0x89, 0x4f, 0x73, 0xbb, 0xba, 0x73, 0x5a, 0x62, 0xbc, 0x47, 0xf5, - 0x48, 0x0c, 0x9b, 0x83, 0xea, 0x2e, 0x89, 0x69, 0x7b, 0x66, 0x2d, 0x71, - 0x2f, 0x7b, 0x1a, 0xb7, 0x11, 0xc7, 0x81, 0x31, 0xe5, 0xfe, 0x5e, 0x84, - 0x71, 0xd7, 0x56, 0xe6, 0xa2, 0x9f, 0xc6, 0x68, 0x3b, 0x17, 0xda, 0x8d, - 0xdf, 0xb1, 0xb2, 0xa1, 0x5e, 0xc6, 0x54, 0x0f, 0x0e, 0x9b, 0x5f, 0xb6, - 0x2e, 0xdb, 0xf8, 0xa4, 0x94, 0xd7, 0xd7, 0xe3, 0x9e, 0x89, 0x25, 0xf0, - 0xe9, 0x52, 0xb7, 0x03, 0x48, 0xd4, 0xf8, 0x50, 0xa1, 0x4b, 0xbd, 0xd9, - 0xd7, 0x3a, 0x77, 0x42, 0x49, 0xff, 0x51, 0x8c, 0xef, 0xf5, 0xb8, 0x9f, - 0x79, 0x60, 0x77, 0xf2, 0x1e, 0xdc, 0x17, 0xaa, 0x40, 0x90, 0x7a, 0xda, - 0x1f, 0x0a, 0x30, 0xbf, 0xfe, 0x7e, 0x91, 0xce, 0xb3, 0x65, 0xc5, 0xbe, - 0xfa, 0x1a, 0xb6, 0xaa, 0x65, 0x8c, 0xad, 0x9b, 0x94, 0x39, 0x51, 0xa6, - 0x35, 0x32, 0xa9, 0x23, 0xc8, 0x7e, 0x76, 0x7d, 0x52, 0x1b, 0x5c, 0xef, - 0x8e, 0x49, 0xaf, 0x92, 0x0b, 0x12, 0xd7, 0xe5, 0xe3, 0xf1, 0xee, 0x26, - 0xd1, 0xb1, 0x1e, 0xc1, 0x26, 0xea, 0x69, 0x4b, 0x3e, 0xcc, 0x18, 0x5a, - 0x28, 0x13, 0x8c, 0x94, 0xce, 0x5f, 0xa7, 0x15, 0x21, 0xad, 0xc8, 0xa4, - 0xe0, 0xb5, 0x0c, 0xf1, 0x9a, 0xce, 0x38, 0xb4, 0xac, 0x75, 0xc4, 0x69, - 0x81, 0x53, 0x32, 0x6f, 0x8a, 0x1d, 0x21, 0xb6, 0x6d, 0x22, 0xee, 0xed, - 0xa1, 0x57, 0x5b, 0xb7, 0xd4, 0xc7, 0x8d, 0x36, 0x85, 0x47, 0x66, 0x9a, - 0xe1, 0x73, 0x93, 0xe6, 0x3b, 0xf9, 0x10, 0x2e, 0xe7, 0x23, 0x78, 0x9b, - 0xb4, 0x2f, 0xd9, 0xb4, 0xeb, 0xf0, 0x8b, 0x62, 0xde, 0x4a, 0x32, 0x6f, - 0x6d, 0x98, 0x50, 0xf4, 0xd7, 0x28, 0x86, 0x8c, 0xbf, 0xfe, 0xec, 0xd2, - 0xcd, 0x3e, 0xea, 0x4d, 0x64, 0xf1, 0xf0, 0x7b, 0x14, 0xfb, 0xed, 0x3c, - 0xfd, 0xda, 0x67, 0x53, 0x35, 0xb4, 0x15, 0x75, 0x5f, 0x5d, 0x7c, 0x6f, - 0xe5, 0x54, 0xa1, 0x28, 0xaf, 0x0e, 0xd7, 0xa9, 0x04, 0xca, 0x4e, 0x5d, - 0xe3, 0x55, 0x97, 0xf8, 0x60, 0x65, 0x7d, 0xe4, 0xfb, 0x5c, 0xff, 0x21, - 0x62, 0x3e, 0x8b, 0xeb, 0x5f, 0xb5, 0xd7, 0x0d, 0x73, 0x5d, 0x75, 0x0d, - 0x1f, 0x46, 0xae, 0xbd, 0x13, 0xa2, 0xec, 0x78, 0x38, 0x42, 0xdd, 0x5d, - 0x59, 0x23, 0xcf, 0x05, 0x70, 0x7b, 0x7e, 0x55, 0xb9, 0xe4, 0x71, 0x3f, - 0xfb, 0x01, 0xc7, 0x97, 0x88, 0xf7, 0xcc, 0xe7, 0x79, 0x4f, 0xf0, 0xd7, - 0x7a, 0x62, 0x8d, 0xcf, 0xeb, 0x3d, 0x4c, 0x5b, 0x94, 0xd1, 0x78, 0x72, - 0xef, 0x8b, 0xea, 0xe8, 0x9f, 0x61, 0x90, 0xbd, 0xd0, 0x43, 0x13, 0x59, - 0xec, 0x9f, 0xf8, 0x63, 0x7b, 0x8f, 0x6e, 0xe5, 0x6a, 0xec, 0xe1, 0x9a, - 0xfb, 0xaa, 0x19, 0x47, 0xff, 0x2d, 0x19, 0x17, 0x8c, 0xb4, 0xbd, 0x12, - 0x52, 0x6b, 0xe3, 0x2d, 0xb7, 0x2a, 0x0b, 0x65, 0x49, 0x0c, 0xb4, 0x37, - 0xc7, 0x13, 0x97, 0xf1, 0x88, 0x25, 0xf3, 0x6e, 0x77, 0xb1, 0xee, 0x12, - 0x97, 0xaa, 0x76, 0xd6, 0xde, 0xb6, 0x22, 0x56, 0xda, 0x50, 0x78, 0xf3, - 0x73, 0x33, 0x05, 0xe9, 0xc7, 0xa5, 0xde, 0xf8, 0x55, 0x1b, 0xd7, 0x39, - 0xcc, 0x9c, 0xfd, 0xac, 0xf1, 0x62, 0x84, 0xd5, 0x18, 0x9e, 0x55, 0x0a, - 0x07, 0x0c, 0x2f, 0xb2, 0x61, 0x0b, 0xdb, 0xf9, 0xbd, 0x97, 0xf8, 0xe9, - 0x5d, 0xa3, 0x0a, 0x53, 0xa1, 0x10, 0x31, 0x23, 0x73, 0xb0, 0xeb, 0xff, - 0x78, 0x65, 0x5f, 0x27, 0xea, 0x92, 0x3d, 0xf8, 0x7f, 0x6d, 0x5f, 0x66, - 0x15, 0xf1, 0x8b, 0xc8, 0xee, 0x57, 0xcc, 0xa1, 0x09, 0x10, 0xd3, 0xec, - 0x32, 0xe6, 0xa3, 0x2e, 0xa4, 0xaf, 0xba, 0xa0, 0x9d, 0x7e, 0x87, 0x7d, - 0xde, 0x43, 0xf5, 0xda, 0xe9, 0x56, 0xb7, 0x8e, 0xc1, 0xe3, 0x3e, 0x3c, - 0x78, 0xbc, 0x03, 0xd5, 0xf6, 0x7c, 0x68, 0x94, 0x3a, 0x75, 0xb1, 0xbf, - 0x1a, 0xfe, 0xd4, 0xc3, 0x3e, 0xeb, 0xea, 0xea, 0x87, 0xd1, 0x62, 0x5f, - 0x1f, 0xc1, 0x9e, 0x09, 0xbf, 0xda, 0x32, 0xe1, 0x41, 0xc7, 0x9d, 0x0f, - 0xc3, 0xbb, 0xaa, 0x97, 0x7c, 0xc9, 0x75, 0xf9, 0xfd, 0x2e, 0xf6, 0x67, - 0xc2, 0x5f, 0x19, 0xa2, 0x4b, 0xc8, 0xdb, 0x2a, 0x1d, 0x43, 0xc7, 0x3d, - 0x6a, 0x87, 0xf9, 0x37, 0xd6, 0x55, 0x7b, 0xcf, 0x47, 0xae, 0x55, 0xc8, - 0x59, 0x00, 0x3e, 0x23, 0x39, 0xa7, 0x0f, 0x13, 0x8c, 0xed, 0xbb, 0xec, - 0xf7, 0x8f, 0x97, 0x39, 0x32, 0xa5, 0xd9, 0xb7, 0xb6, 0xd3, 0x7e, 0xf2, - 0x4c, 0x6b, 0xf1, 0xda, 0x7a, 0x9f, 0x73, 0xde, 0x40, 0x7c, 0xa1, 0x0f, - 0xcb, 0x68, 0x84, 0xfa, 0xb8, 0x5d, 0xa7, 0x50, 0x9f, 0x67, 0x42, 0x5d, - 0xe2, 0xf0, 0xfb, 0x80, 0x39, 0xcf, 0x9e, 0x53, 0x67, 0xde, 0xa4, 0xee, - 0x16, 0xcb, 0xfb, 0x55, 0xbe, 0xdf, 0x7e, 0x5f, 0xf2, 0x2d, 0xb1, 0x66, - 0x50, 0x30, 0xe7, 0x17, 0xdd, 0xff, 0x5d, 0xc8, 0x3d, 0x8f, 0xfe, 0xa7, - 0x8c, 0xe3, 0x78, 0x77, 0xa5, 0x4b, 0xfc, 0xe7, 0x4f, 0x71, 0xdf, 0xf4, - 0x30, 0xef, 0x0b, 0xfd, 0x83, 0xec, 0x25, 0x3c, 0xaa, 0x93, 0xf9, 0x67, - 0xef, 0x71, 0xd7, 0xed, 0x65, 0xf8, 0x4b, 0xab, 0x7c, 0xf1, 0x10, 0xea, - 0x93, 0x23, 0x7c, 0x5e, 0xa1, 0x9d, 0xb8, 0xf1, 0x31, 0x63, 0x03, 0x3a, - 0x6a, 0x24, 0x07, 0x3c, 0x6b, 0xf5, 0xf5, 0x88, 0x0e, 0x15, 0x36, 0xf2, - 0xfa, 0x73, 0xb4, 0xef, 0x93, 0x86, 0x07, 0xf5, 0x8b, 0x64, 0xd6, 0xa7, - 0x8d, 0xa7, 0xf1, 0x75, 0x9f, 0xb3, 0xf7, 0x95, 0xb5, 0xaa, 0x75, 0x7d, - 0xe0, 0x0e, 0x57, 0xfd, 0xf8, 0x1b, 0xf4, 0xa7, 0xb6, 0x55, 0x37, 0xde, - 0x2b, 0xe9, 0xc4, 0x40, 0x64, 0xd5, 0x33, 0x16, 0x6e, 0x1a, 0x46, 0x68, - 0xd5, 0x8d, 0xf6, 0x2f, 0xf1, 0x7d, 0x90, 0x31, 0x88, 0x6c, 0x75, 0x4a, - 0xe6, 0x3f, 0x71, 0xd2, 0x39, 0x88, 0x3f, 0x2c, 0x8c, 0xe0, 0xc0, 0x44, - 0x11, 0x5b, 0xd3, 0xb7, 0xf5, 0x55, 0xd7, 0x65, 0x7b, 0x60, 0x22, 0xde, - 0x5b, 0x55, 0x94, 0x6d, 0x1f, 0xfb, 0x8c, 0x4a, 0xe6, 0xd8, 0xfb, 0xa9, - 0xd3, 0x01, 0x5b, 0xa7, 0x3d, 0x30, 0xf2, 0xd7, 0xe9, 0xf6, 0x93, 0xae, - 0x3f, 0x25, 0x7a, 0x93, 0xfd, 0xb6, 0x83, 0xd8, 0x4b, 0xba, 0xbb, 0x6f, - 0xa0, 0xdb, 0x67, 0x5c, 0xa7, 0xbb, 0x6b, 0x22, 0x7e, 0xda, 0x55, 0xa4, - 0xfb, 0xed, 0xe9, 0x12, 0x8d, 0x2c, 0xb6, 0xad, 0xca, 0x22, 0xbf, 0x6e, - 0x9f, 0xb5, 0xcf, 0xd6, 0xc7, 0x59, 0xfb, 0xfa, 0xc6, 0x7a, 0x89, 0x07, - 0xfe, 0x9a, 0xd2, 0xed, 0xbd, 0x7d, 0x07, 0x7b, 0xdd, 0x18, 0x1f, 0xda, - 0x9b, 0x5b, 0xdc, 0x69, 0xc6, 0x76, 0xd8, 0xb7, 0xf9, 0x73, 0x33, 0x8d, - 0x0e, 0xf6, 0x61, 0x9b, 0xcc, 0x2e, 0x7f, 0xa7, 0xe9, 0x23, 0xee, 0xaa, - 0x54, 0x1b, 0x27, 0x64, 0xb6, 0x21, 0xb1, 0x5c, 0xc4, 0xc2, 0x05, 0xe9, - 0xf7, 0x76, 0xb2, 0x4f, 0x58, 0x46, 0xfb, 0xf6, 0xe2, 0x48, 0xa1, 0x57, - 0xa5, 0xc3, 0x5c, 0xc7, 0x94, 0xba, 0x02, 0xd6, 0xbc, 0x6e, 0x54, 0xd2, - 0x97, 0xc2, 0xa9, 0x81, 0xd4, 0xc9, 0x7a, 0x0b, 0xc4, 0x28, 0xbe, 0x45, - 0xa9, 0x6c, 0x6a, 0x7b, 0xbd, 0x1b, 0xc7, 0x6c, 0xfc, 0xa5, 0x4d, 0xf1, - 0x33, 0x2e, 0x31, 0x73, 0xc7, 0x84, 0xd4, 0x31, 0x42, 0x48, 0x7d, 0x08, - 0xff, 0x90, 0x9c, 0x1f, 0xa8, 0x41, 0xfa, 0xde, 0x1a, 0x48, 0x5f, 0x71, - 0x04, 0x3f, 0xd2, 0x23, 0xbe, 0x4c, 0xc1, 0xa3, 0xb6, 0x98, 0x33, 0xfe, - 0xad, 0x66, 0x10, 0x01, 0xf6, 0x65, 0x5d, 0xee, 0x18, 0xfb, 0x0c, 0xd1, - 0x63, 0x67, 0xeb, 0xb2, 0x7c, 0xc6, 0xdf, 0x6e, 0x3a, 0xb9, 0xf0, 0x96, - 0x29, 0x9f, 0xbf, 0x63, 0x32, 0x16, 0x39, 0x62, 0x63, 0xb1, 0xae, 0xd6, - 0x58, 0xde, 0xb2, 0x5e, 0x31, 0xe6, 0xaf, 0x96, 0x3b, 0x3d, 0x48, 0x6b, - 0x22, 0xdf, 0x84, 0xbb, 0x89, 0x9f, 0xda, 0x26, 0x9b, 0x60, 0x4c, 0x02, - 0x27, 0x8e, 0x47, 0xb0, 0x72, 0x42, 0x3b, 0x3d, 0xe8, 0xce, 0x60, 0x7c, - 0xb6, 0x13, 0x13, 0x05, 0xff, 0x42, 0xd4, 0x45, 0x5c, 0x9d, 0x74, 0xe1, - 0x76, 0x63, 0xb5, 0x9a, 0xb7, 0x63, 0x5a, 0xe1, 0x2e, 0x63, 0xbb, 0xea, - 0xb5, 0x31, 0xc5, 0x0c, 0xb1, 0x88, 0xc2, 0x4d, 0xce, 0x5c, 0xbe, 0x35, - 0x49, 0xcc, 0x7d, 0xfb, 0x84, 0xd4, 0x77, 0x0b, 0xaf, 0x26, 0xa9, 0x97, - 0x64, 0x36, 0xe3, 0x65, 0x0f, 0xb4, 0x4f, 0x69, 0xdd, 0x86, 0x72, 0x30, - 0xde, 0xad, 0x33, 0x0e, 0x2e, 0x5c, 0x36, 0xd3, 0xec, 0x97, 0x1c, 0xd4, - 0x6e, 0x68, 0x11, 0x8f, 0x2b, 0x84, 0x01, 0x9b, 0x46, 0x6f, 0xab, 0x31, - 0x53, 0x86, 0xa5, 0x7a, 0x0f, 0x4e, 0xdb, 0x32, 0xf4, 0xb7, 0xae, 0x27, - 0xbe, 0x7e, 0xdc, 0xcc, 0xb0, 0x07, 0x96, 0xfd, 0xd0, 0x58, 0xa2, 0xc5, - 0xdd, 0x46, 0x0c, 0x1b, 0x8b, 0x2e, 0xa8, 0xb4, 0xca, 0x7a, 0x1a, 0xd3, - 0x33, 0x60, 0x45, 0xa9, 0x71, 0xea, 0x9b, 0xc8, 0x18, 0x27, 0xce, 0x6a, - 0x3b, 0xee, 0x5f, 0x48, 0xc3, 0x99, 0xdf, 0x6c, 0x32, 0xfe, 0x37, 0x2e, - 0x85, 0xb5, 0x23, 0x69, 0xf2, 0xdd, 0xc1, 0xbc, 0x3b, 0xdf, 0xe3, 0xe1, - 0x7d, 0x99, 0xdb, 0x75, 0xb7, 0x8e, 0xe6, 0x30, 0xef, 0x4e, 0x49, 0x5f, - 0x85, 0x60, 0x77, 0x01, 0x32, 0x43, 0x62, 0x6f, 0xf1, 0xa9, 0x55, 0xda, - 0x3b, 0xea, 0x9a, 0x74, 0xf6, 0xc5, 0x72, 0xb3, 0x9e, 0xe0, 0x56, 0xb3, - 0x19, 0xc7, 0x0a, 0x9e, 0x1b, 0x68, 0xc7, 0x8f, 0xdc, 0xe2, 0x72, 0x21, - 0xbe, 0xea, 0x2e, 0x55, 0xdc, 0x5b, 0x62, 0x9e, 0xc8, 0xd8, 0x35, 0xb1, - 0x8c, 0x72, 0x5e, 0x38, 0x29, 0x6b, 0x7c, 0xab, 0x75, 0xf4, 0xa4, 0xd4, - 0xc8, 0xee, 0xd6, 0x88, 0xa9, 0x75, 0x4b, 0x1f, 0x58, 0x4d, 0x3d, 0x7d, - 0x34, 0x26, 0x35, 0x78, 0x3f, 0x6b, 0xb0, 0xb6, 0xd0, 0xae, 0xa4, 0x8e, - 0x69, 0x09, 0xbf, 0xdb, 0x85, 0x2b, 0x0d, 0x5a, 0xe6, 0x79, 0x68, 0xbd, - 0xce, 0xbc, 0x70, 0x67, 0x6b, 0x63, 0x11, 0x0f, 0xdf, 0x3a, 0xd3, 0x27, - 0xe7, 0x49, 0x6c, 0x1d, 0x37, 0xe5, 0x05, 0x1b, 0x5b, 0xd6, 0x4b, 0xc9, - 0x2e, 0xe2, 0x06, 0xc1, 0xc6, 0x72, 0xfd, 0x81, 0xd6, 0x86, 0x29, 0x1f, - 0x79, 0x53, 0x78, 0x8f, 0x75, 0xe9, 0x48, 0xa1, 0xc4, 0xa3, 0x83, 0x9b, - 0x37, 0x13, 0x37, 0xbb, 0x53, 0x5a, 0xcb, 0x06, 0xe2, 0x66, 0x9d, 0x3d, - 0x84, 0x07, 0x3d, 0x78, 0xcc, 0x74, 0xfa, 0x08, 0xc1, 0xce, 0xd6, 0x49, - 0x2d, 0x2d, 0xb8, 0xf9, 0xea, 0x6a, 0x60, 0x07, 0x71, 0xf3, 0x42, 0xce, - 0x83, 0x0c, 0x71, 0xf3, 0x47, 0x39, 0x1f, 0xee, 0x20, 0x6e, 0xbe, 0x42, - 0x8c, 0x75, 0x3e, 0xf9, 0x4b, 0x7c, 0xbb, 0x38, 0x13, 0xdb, 0x95, 0xf0, - 0xd1, 0xb7, 0x05, 0x3b, 0xff, 0xa6, 0x88, 0x9d, 0xff, 0xcb, 0x3f, 0xc3, - 0xce, 0x77, 0x13, 0x13, 0x76, 0x4d, 0xc8, 0xfe, 0xd1, 0xae, 0xd6, 0xd7, - 0x4f, 0xc9, 0x99, 0x95, 0x5b, 0xf1, 0xee, 0xc9, 0xe1, 0x7e, 0x62, 0x65, - 0x8c, 0x24, 0x33, 0xc8, 0x4d, 0x62, 0x09, 0x71, 0xc1, 0x4b, 0x6e, 0xae, - 0xbb, 0x32, 0xa9, 0x19, 0x6f, 0xa8, 0x78, 0x67, 0x06, 0x71, 0xf6, 0xca, - 0xda, 0x02, 0x4d, 0x98, 0xf6, 0xa4, 0x88, 0x8d, 0x59, 0x03, 0x97, 0x12, - 0x3b, 0x57, 0xcd, 0x01, 0xb5, 0x73, 0x0e, 0x76, 0x96, 0x79, 0x58, 0x55, - 0x1c, 0x7f, 0x46, 0xec, 0xcc, 0xfe, 0x96, 0xa1, 0x36, 0xd7, 0xc4, 0x18, - 0x55, 0x38, 0x1c, 0x0f, 0xa0, 0xeb, 0x38, 0x71, 0x8f, 0x3d, 0x0f, 0xb3, - 0x86, 0x7e, 0x6a, 0x64, 0x70, 0x74, 0xd6, 0x99, 0x87, 0x6d, 0x22, 0x7e, - 0xf3, 0xc4, 0xc3, 0x28, 0x9f, 0xf3, 0xe0, 0x19, 0xe2, 0xe7, 0x8d, 0xb4, - 0xf3, 0x19, 0xe2, 0xe7, 0xbb, 0x6f, 0x98, 0x89, 0x4d, 0xcd, 0xe1, 0x15, - 0x62, 0xf9, 0xba, 0x5a, 0xc4, 0x65, 0xde, 0x61, 0x5d, 0x59, 0x13, 0xc0, - 0x39, 0x1b, 0x3f, 0xfb, 0x17, 0xb2, 0xca, 0x91, 0xad, 0x8c, 0xb6, 0x10, - 0xbb, 0xba, 0x68, 0xd7, 0xb6, 0x93, 0x5a, 0xe7, 0x8b, 0xd4, 0x45, 0x63, - 0xfc, 0xbc, 0x6d, 0x8f, 0xbe, 0xa4, 0xcc, 0x4e, 0x3a, 0x5b, 0xe5, 0x5c, - 0x55, 0x05, 0xed, 0xbd, 0x65, 0x2c, 0x96, 0xfe, 0x00, 0x4e, 0x4c, 0x26, - 0xf2, 0x65, 0xc5, 0x7a, 0x28, 0xf7, 0xfa, 0x79, 0x2f, 0x8d, 0xce, 0x35, - 0x8e, 0x7f, 0x27, 0xf2, 0xc7, 0x88, 0x5d, 0x65, 0xcf, 0x34, 0x14, 0xdc, - 0x64, 0x76, 0x62, 0xdc, 0x8c, 0xa2, 0xfc, 0x5c, 0x71, 0xef, 0xf5, 0x9c, - 0x9c, 0xc5, 0xdb, 0xd9, 0x1a, 0xfa, 0x5e, 0x09, 0x13, 0xa6, 0x89, 0xef, - 0xc2, 0xbe, 0xdb, 0x0b, 0x82, 0x17, 0xbb, 0x71, 0xd4, 0xd4, 0x22, 0x3f, - 0x67, 0x4c, 0xdc, 0x2b, 0xfb, 0xee, 0x37, 0xcc, 0x9e, 0x1e, 0xe4, 0x3d, - 0xf3, 0x73, 0xb3, 0xa7, 0xc1, 0x09, 0xfc, 0xc6, 0xdd, 0x5c, 0x0e, 0xd7, - 0x4a, 0x2f, 0x31, 0xbd, 0x16, 0x19, 0xc1, 0x23, 0xc4, 0x1c, 0xbf, 0x56, - 0x01, 0xdd, 0xd3, 0xdf, 0xe4, 0xd6, 0x22, 0x33, 0x2a, 0xc0, 0x77, 0x77, - 0x32, 0xbf, 0xed, 0xa4, 0x6f, 0xc4, 0x16, 0x2a, 0x94, 0x1b, 0x97, 0xbe, - 0x6c, 0xe3, 0x51, 0x7f, 0x37, 0xaf, 0x8d, 0x17, 0x4a, 0xb8, 0xa6, 0x47, - 0x78, 0xc5, 0xa6, 0xe3, 0x4e, 0x0e, 0xd1, 0xf3, 0xfe, 0x85, 0x4b, 0x70, - 0x64, 0xab, 0xa4, 0xac, 0xf7, 0x8f, 0x85, 0xac, 0xde, 0xc5, 0x12, 0xc3, - 0x3a, 0xb6, 0x99, 0xe2, 0x5f, 0x7d, 0xe4, 0xb3, 0x07, 0x87, 0xcc, 0xa5, - 0xec, 0xdd, 0x64, 0x0e, 0xda, 0x44, 0x6c, 0xdd, 0xcd, 0x1a, 0x6c, 0x59, - 0x83, 0x46, 0xd6, 0x6a, 0x5a, 0xab, 0x1b, 0x79, 0x35, 0x5f, 0x13, 0x21, - 0xbe, 0x59, 0xc5, 0xda, 0xdd, 0x56, 0x68, 0xc2, 0x1b, 0x67, 0x74, 0xfa, - 0x66, 0x3b, 0xf1, 0x7b, 0x37, 0xee, 0xa1, 0x3c, 0xdf, 0x2e, 0x7c, 0x07, - 0xe9, 0x6f, 0x78, 0x70, 0xe4, 0x78, 0x1a, 0xeb, 0x57, 0x0d, 0xe1, 0xd2, - 0x37, 0x7d, 0xcc, 0x55, 0x01, 0x3c, 0x7e, 0x5c, 0xf2, 0x6b, 0x09, 0x6f, - 0xdf, 0x88, 0x45, 0x7c, 0x88, 0xda, 0x38, 0xe4, 0x8b, 0xef, 0x39, 0x18, - 0xc5, 0xcf, 0xfe, 0xb7, 0xf4, 0x3e, 0xf3, 0xd0, 0xaa, 0x7f, 0x86, 0x67, - 0x88, 0x5b, 0x88, 0x05, 0x2a, 0x12, 0xf6, 0xb9, 0xb7, 0x12, 0xde, 0xf5, - 0xd0, 0x07, 0x24, 0xa6, 0x97, 0x32, 0xd6, 0x2d, 0x62, 0xe7, 0x85, 0xe2, - 0x5c, 0xf2, 0xed, 0x93, 0xda, 0xc5, 0x43, 0x88, 0x11, 0x43, 0xa3, 0x4f, - 0xb0, 0x9b, 0x9b, 0x78, 0xf7, 0x4a, 0x3c, 0x6e, 0x9c, 0x23, 0xde, 0x1d, - 0xa6, 0xad, 0x3d, 0xba, 0xf8, 0x66, 0x08, 0x65, 0x73, 0x11, 0xfa, 0xa4, - 0xcc, 0x25, 0x5f, 0xf1, 0x3b, 0x73, 0x49, 0x99, 0x85, 0xcb, 0xb9, 0x10, - 0x74, 0x94, 0xb1, 0x77, 0x2b, 0x57, 0x59, 0xe6, 0xe4, 0x29, 0xff, 0x0e, - 0xe6, 0xf7, 0x8c, 0x19, 0x0e, 0xee, 0x28, 0x84, 0xf8, 0xa9, 0x0b, 0x66, - 0x0a, 0xbf, 0xc7, 0xe7, 0x23, 0xfc, 0x8e, 0x62, 0x22, 0x5f, 0x5b, 0x21, - 0xcd, 0xc0, 0x44, 0xde, 0xc9, 0x79, 0xd1, 0xfc, 0x5e, 0xbf, 0x60, 0xcd, - 0xb6, 0xe3, 0xce, 0xdf, 0xfa, 0x0d, 0x7f, 0x7f, 0x1e, 0xf3, 0x7b, 0xc9, - 0xf7, 0x99, 0x93, 0x3a, 0x3e, 0x3a, 0x69, 0x63, 0xfe, 0x79, 0x62, 0xfe, - 0x01, 0xaf, 0x5b, 0xb0, 0xe6, 0xaf, 0xac, 0xf3, 0xf1, 0x78, 0xef, 0x34, - 0xfd, 0xa0, 0x8b, 0x74, 0x5d, 0x7a, 0xd8, 0xe6, 0xd7, 0xe1, 0xd3, 0x99, - 0xe5, 0x5e, 0x3e, 0x99, 0xc0, 0x3b, 0xd7, 0x67, 0xa7, 0x9f, 0x94, 0xd9, - 0x33, 0x60, 0x3c, 0xf2, 0xee, 0x5a, 0xf8, 0x5a, 0xd8, 0x6f, 0x7a, 0xf9, - 0x7c, 0xc4, 0x7e, 0x5e, 0x66, 0xb9, 0x9f, 0x7c, 0x56, 0xc2, 0xd3, 0x1f, - 0x5d, 0x7f, 0xe7, 0x20, 0x3b, 0x35, 0xdf, 0x79, 0xc6, 0x96, 0xdb, 0x7e, - 0x4e, 0xe6, 0xad, 0xfe, 0x05, 0xd8, 0xf1, 0xf5, 0xfb, 0x94, 0x49, 0xec, - 0x7b, 0xc0, 0x72, 0xfc, 0x36, 0x1c, 0xdc, 0xc6, 0x78, 0xf8, 0x2e, 0xed, - 0xb3, 0xed, 0x5c, 0x5d, 0xf0, 0x2e, 0xb3, 0xd3, 0x96, 0xf9, 0xae, 0x73, - 0x52, 0x93, 0xe4, 0xfe, 0x1f, 0x54, 0x08, 0x1e, 0x7f, 0x9c, 0x35, 0x6b, - 0xd8, 0x94, 0xd9, 0x3e, 0x94, 0x27, 0x75, 0x08, 0x9b, 0xc6, 0xa3, 0x78, - 0xdb, 0xf0, 0x17, 0xcf, 0xb0, 0x48, 0x4c, 0x0e, 0x30, 0x26, 0xc3, 0x18, - 0x31, 0x63, 0xd1, 0xb7, 0x89, 0x4f, 0xb3, 0x64, 0xf8, 0xe8, 0x84, 0x1b, - 0x6f, 0x13, 0x33, 0x42, 0x39, 0x67, 0x40, 0x9d, 0x77, 0x4b, 0xbf, 0x57, - 0x22, 0x5a, 0x13, 0x6b, 0xd9, 0x8b, 0x3a, 0xe4, 0x98, 0xf3, 0xfd, 0xfa, - 0x8f, 0x71, 0xec, 0x84, 0x0b, 0xf7, 0xb1, 0xef, 0x4b, 0xdf, 0x69, 0xf0, - 0xef, 0xc6, 0xfe, 0xf7, 0xf1, 0x0f, 0xd6, 0x94, 0x9c, 0xb3, 0x52, 0x72, - 0x96, 0xe3, 0x13, 0xab, 0x56, 0xd7, 0xe7, 0x9f, 0x87, 0x3e, 0x78, 0x15, - 0x8d, 0x03, 0x0b, 0xf8, 0xc0, 0x9a, 0xe7, 0xbd, 0xf7, 0x18, 0x3f, 0x2f, - 0x1a, 0xb1, 0x88, 0x8b, 0xc2, 0xcc, 0x87, 0xdd, 0xb8, 0xd7, 0x90, 0x7d, - 0x26, 0x6d, 0xe0, 0x69, 0x68, 0xfd, 0x17, 0x94, 0x9c, 0xcd, 0xb9, 0x64, - 0x65, 0x6b, 0x64, 0x5d, 0x85, 0x95, 0xcb, 0x1b, 0x3b, 0xcb, 0xa0, 0xb5, - 0x78, 0x95, 0x6e, 0xbc, 0xaf, 0xfe, 0xa7, 0x35, 0x1f, 0xfe, 0xc4, 0x7a, - 0x47, 0x2f, 0xd1, 0xd5, 0xa2, 0x3e, 0x77, 0x89, 0xb7, 0x3a, 0x1c, 0x33, - 0x65, 0x7f, 0xee, 0xc7, 0xb8, 0xef, 0x84, 0x07, 0xed, 0xc9, 0x5f, 0x5a, - 0xd9, 0xb0, 0xd0, 0x0c, 0x56, 0xa2, 0x42, 0xe8, 0x3b, 0x33, 0xeb, 0x17, - 0x0a, 0x50, 0x1d, 0xa6, 0xe0, 0x65, 0xf1, 0xd3, 0x71, 0x58, 0xa6, 0xcc, - 0x11, 0x2d, 0xdc, 0x91, 0x1c, 0xc2, 0x7b, 0xc9, 0xf4, 0x1f, 0xf8, 0xa0, - 0x5d, 0xbc, 0xec, 0xd6, 0xe6, 0x9b, 0xdc, 0x51, 0xe5, 0x6f, 0xd0, 0x07, - 0x1a, 0xec, 0x7a, 0x93, 0x67, 0xef, 0x14, 0x60, 0x6e, 0x91, 0x1e, 0x73, - 0x1c, 0x73, 0x63, 0x59, 0x78, 0x88, 0xed, 0x86, 0x9b, 0xb5, 0xcc, 0x53, - 0x4a, 0x8b, 0xec, 0x53, 0x51, 0x75, 0x8f, 0x3e, 0x88, 0x67, 0x8c, 0x78, - 0xba, 0x4d, 0xd5, 0xf9, 0x3a, 0x0b, 0x25, 0xda, 0xed, 0xc4, 0x2a, 0xda, - 0xfc, 0x65, 0x77, 0x39, 0x6a, 0x57, 0xeb, 0x9d, 0xe5, 0x6e, 0x6d, 0xf0, - 0x6b, 0x8c, 0xaf, 0xcd, 0x85, 0x79, 0xff, 0xfb, 0x71, 0x17, 0x56, 0xd8, - 0xfb, 0x08, 0xb9, 0xe2, 0x8c, 0x74, 0x1c, 0x5b, 0xc6, 0xac, 0xf5, 0xaf, - 0x26, 0xb5, 0xc8, 0x53, 0x2a, 0xbb, 0x23, 0x40, 0x4c, 0x73, 0x3f, 0xf4, - 0xe8, 0x2c, 0xeb, 0x54, 0x7b, 0xc1, 0x85, 0x5b, 0x4e, 0x09, 0xcd, 0x1c, - 0x69, 0x1e, 0x42, 0xf9, 0x09, 0x6b, 0xfd, 0x0e, 0x43, 0x1b, 0xbc, 0xec, - 0xce, 0xfe, 0xd7, 0x5a, 0xea, 0xad, 0x43, 0xc9, 0x3e, 0xda, 0x10, 0x71, - 0xc5, 0x90, 0x9c, 0x87, 0x4b, 0xfc, 0x39, 0x31, 0xc5, 0x1f, 0xd3, 0x57, - 0xdd, 0xa9, 0x20, 0xf9, 0xd4, 0x12, 0xd3, 0x90, 0xf9, 0x79, 0x14, 0x97, - 0x8d, 0xac, 0x7f, 0x53, 0x43, 0x82, 0xd8, 0x2c, 0xc2, 0x3a, 0x18, 0xc5, - 0x51, 0x62, 0xbc, 0x43, 0x6c, 0x09, 0xe7, 0x43, 0x3a, 0xb1, 0x59, 0x37, - 0x5c, 0x63, 0x01, 0x35, 0x93, 0x8b, 0x19, 0xed, 0xf8, 0xf7, 0x98, 0x8f, - 0x88, 0x8b, 0x1c, 0x42, 0xe0, 0xc4, 0xdf, 0x59, 0x55, 0xba, 0xde, 0x32, - 0xa6, 0xb8, 0xee, 0x13, 0x11, 0xea, 0x98, 0xef, 0xc9, 0xb9, 0x15, 0xb3, - 0x0b, 0xf7, 0x8c, 0x85, 0xf9, 0x7e, 0x15, 0x56, 0x9e, 0x88, 0xe2, 0x4a, - 0xf2, 0x66, 0xcc, 0xd7, 0x38, 0x18, 0xc8, 0xaf, 0xd3, 0x8f, 0xd8, 0x67, - 0x65, 0x0b, 0xba, 0xbd, 0x77, 0x74, 0xc8, 0x94, 0xfe, 0xdc, 0xc3, 0xbf, - 0x03, 0xfc, 0x88, 0x3e, 0xbf, 0x55, 0xc4, 0x3a, 0xfb, 0x5b, 0xa3, 0x33, - 0x6f, 0x55, 0xd8, 0x7b, 0x9a, 0x88, 0xf2, 0xb9, 0x90, 0x3d, 0x17, 0x1c, - 0x26, 0xcd, 0xb3, 0xe3, 0xd2, 0xb7, 0xb5, 0xad, 0xf3, 0x15, 0xf7, 0xdf, - 0xdf, 0x32, 0x5c, 0x58, 0xcf, 0xde, 0x3e, 0xa2, 0x4b, 0xbd, 0x1c, 0xd6, - 0x6a, 0xb1, 0x0e, 0xa7, 0x43, 0x6c, 0xc2, 0xf5, 0x7f, 0x87, 0x23, 0xa1, - 0x04, 0x73, 0xbe, 0x8e, 0x77, 0x73, 0x5f, 0x66, 0xbf, 0x53, 0x27, 0x67, - 0x77, 0x70, 0xcb, 0x09, 0x2f, 0xd7, 0x5c, 0x4f, 0x5c, 0xb3, 0x09, 0x3f, - 0x0b, 0x39, 0xbd, 0xc6, 0x61, 0x5e, 0x1f, 0x9d, 0x0e, 0x10, 0x8b, 0xfa, - 0xf8, 0xb9, 0x91, 0xb7, 0x2f, 0xe2, 0x49, 0x64, 0xf9, 0xd7, 0x78, 0xf2, - 0x11, 0x0f, 0xe8, 0xb8, 0x9a, 0x7b, 0x09, 0x57, 0x48, 0x3b, 0x3b, 0xed, - 0xd0, 0x3c, 0x5e, 0x10, 0xba, 0xb2, 0x5e, 0x6c, 0xb0, 0xd6, 0x2d, 0xf4, - 0x03, 0x72, 0x8e, 0xf7, 0xdf, 0xb8, 0x06, 0x91, 0xdd, 0x09, 0xf6, 0xc7, - 0x46, 0x03, 0xda, 0x43, 0xb4, 0x97, 0x29, 0x6b, 0x68, 0xec, 0x45, 0xe5, - 0xdd, 0x08, 0x56, 0x8c, 0x59, 0x43, 0x91, 0x94, 0x5c, 0xb7, 0xac, 0xea, - 0xb5, 0x7a, 0xe4, 0x0d, 0xe5, 0x61, 0xad, 0xf3, 0x50, 0x07, 0xa3, 0x38, - 0x9b, 0x6b, 0xbc, 0xf8, 0x1e, 0xb1, 0x53, 0x94, 0xbd, 0xde, 0x25, 0xf7, - 0x28, 0x66, 0x72, 0xff, 0xb1, 0x52, 0x66, 0x04, 0xa3, 0x85, 0x80, 0x9a, - 0xce, 0xfd, 0x49, 0xa5, 0xe4, 0xa2, 0x11, 0xfa, 0x42, 0xd3, 0x98, 0xf0, - 0x6a, 0x0d, 0x55, 0x91, 0xce, 0x51, 0xd2, 0x99, 0x5e, 0xa3, 0x67, 0x46, - 0x94, 0xe8, 0x2c, 0x40, 0x5c, 0xf7, 0xaa, 0xcc, 0xcf, 0xa8, 0xb7, 0xa7, - 0xf9, 0xbc, 0xe8, 0x2d, 0x8c, 0x9f, 0x15, 0xe9, 0x3c, 0x56, 0xb8, 0x88, - 0xe9, 0xdc, 0x25, 0xfb, 0xf7, 0x91, 0x42, 0x82, 0xb5, 0xaf, 0x0f, 0x79, - 0xe6, 0x93, 0xb1, 0x5c, 0x63, 0x66, 0x8c, 0x7c, 0x38, 0x67, 0xee, 0xfa, - 0xf0, 0x64, 0xf1, 0x99, 0x61, 0xbe, 0x3b, 0x7c, 0xed, 0x77, 0xd1, 0x91, - 0xb3, 0xaf, 0xef, 0xec, 0x2b, 0x94, 0xd3, 0x76, 0x4e, 0x1f, 0x7e, 0xd8, - 0xf4, 0xca, 0x0c, 0x1c, 0x2f, 0x8d, 0xaf, 0xc7, 0x88, 0xf1, 0x97, 0xd8, - 0x45, 0xb9, 0x47, 0xa9, 0xcf, 0x13, 0xa6, 0xbd, 0x7f, 0x2f, 0xe7, 0xba, - 0x98, 0xab, 0xbb, 0x5a, 0xcf, 0x10, 0x8b, 0x1d, 0x63, 0xcc, 0xec, 0x49, - 0x36, 0x76, 0xbf, 0x4c, 0xbf, 0x4b, 0x7f, 0x5d, 0xf6, 0xc8, 0x81, 0xb1, - 0x89, 0x6f, 0x63, 0xaa, 0xa6, 0x71, 0xe1, 0x59, 0xe6, 0x84, 0xd3, 0xcc, - 0x53, 0x1e, 0xe6, 0x84, 0xea, 0x09, 0x62, 0x48, 0xe6, 0xa9, 0x79, 0xe6, - 0x29, 0x8f, 0xde, 0x78, 0x71, 0x06, 0xff, 0x9d, 0x7a, 0x11, 0xfe, 0x62, - 0x89, 0x19, 0xc8, 0xb3, 0xce, 0xfc, 0x55, 0x9f, 0xe9, 0xc7, 0xa5, 0x9b, - 0x9d, 0x19, 0x9a, 0x9b, 0x35, 0x7b, 0x77, 0xae, 0x31, 0x34, 0x22, 0xb4, - 0x7b, 0xb4, 0x48, 0x96, 0xb6, 0x3a, 0x62, 0x63, 0xef, 0x6e, 0xf6, 0x0b, - 0x72, 0x8e, 0xab, 0x0a, 0x1e, 0xfa, 0xfe, 0x88, 0x21, 0xe7, 0x1b, 0x22, - 0xc1, 0xcd, 0xb4, 0xe1, 0x88, 0xd9, 0xd8, 0x12, 0x53, 0x3b, 0x70, 0xa9, - 0x98, 0x63, 0x1d, 0x2c, 0xad, 0x65, 0x8e, 0xa2, 0xb1, 0xfb, 0x7e, 0x7c, - 0x03, 0xe9, 0x9a, 0xc6, 0xde, 0x71, 0xc4, 0x8c, 0x7b, 0x21, 0xe7, 0x41, - 0x1d, 0x5a, 0xf5, 0x79, 0x37, 0xf1, 0xc8, 0x27, 0xd6, 0x52, 0xfd, 0x31, - 0x8c, 0x13, 0x33, 0x36, 0xac, 0xd2, 0x2f, 0x7e, 0xbf, 0x78, 0xcf, 0xd9, - 0x2b, 0x12, 0x7f, 0xf1, 0x51, 0x07, 0xe5, 0xf0, 0x2c, 0xaa, 0xe3, 0x1a, - 0xd4, 0x85, 0x7d, 0x56, 0xf8, 0x55, 0x1c, 0xa0, 0xbf, 0x8d, 0x17, 0x14, - 0x8c, 0xfa, 0x57, 0x31, 0x20, 0xb5, 0x89, 0xef, 0xb4, 0xe5, 0x02, 0xc4, - 0x29, 0x11, 0x94, 0xeb, 0xb1, 0xe8, 0x30, 0xe5, 0x6b, 0x63, 0x2e, 0x1f, - 0x65, 0x0e, 0xc9, 0x86, 0x02, 0xf6, 0xf9, 0xd5, 0x72, 0x3d, 0x62, 0xff, - 0xcf, 0x81, 0xf4, 0x41, 0x0d, 0x53, 0xb2, 0x4f, 0x7d, 0x08, 0xaf, 0x8e, - 0xcf, 0xe3, 0x58, 0x32, 0x8d, 0xbd, 0x35, 0x21, 0x8c, 0x99, 0x8b, 0xed, - 0xb9, 0x81, 0xf4, 0x5b, 0x5b, 0x26, 0x0e, 0xda, 0xb3, 0xc8, 0x8d, 0x49, - 0x57, 0xbd, 0x9c, 0xe3, 0x98, 0x66, 0xdf, 0x35, 0x6e, 0x0c, 0xe1, 0x80, - 0xf1, 0xc7, 0x30, 0x16, 0x49, 0xee, 0x1c, 0xc1, 0xf9, 0x29, 0xa9, 0x61, - 0xfd, 0xad, 0xcb, 0xc6, 0x44, 0x3f, 0x2e, 0x62, 0x5e, 0x1f, 0x9a, 0x6c, - 0x0c, 0x37, 0xd7, 0xba, 0x7c, 0xca, 0xc1, 0x72, 0x4d, 0x79, 0x39, 0x73, - 0x5d, 0x85, 0x20, 0xf5, 0x75, 0x21, 0xe9, 0x65, 0xce, 0x11, 0x7d, 0xca, - 0x19, 0x3f, 0x47, 0xce, 0x44, 0x5e, 0x61, 0xa4, 0xf9, 0xc6, 0xfd, 0x15, - 0xf9, 0xff, 0x83, 0x6b, 0xe7, 0x0e, 0x8b, 0xb3, 0xf1, 0x3f, 0xb7, 0x2e, - 0xdd, 0x24, 0x72, 0x27, 0x03, 0xcc, 0xe9, 0xd1, 0xa9, 0x6b, 0xfa, 0x15, - 0x9d, 0x9e, 0x93, 0x9a, 0x61, 0xeb, 0xdc, 0x99, 0xb7, 0x69, 0x03, 0xef, - 0xa8, 0x46, 0xd6, 0x13, 0xfa, 0x55, 0x0d, 0xfd, 0xad, 0x09, 0xbd, 0x4b, - 0x53, 0x9e, 0x9e, 0xab, 0xe6, 0x7a, 0xb4, 0xac, 0x7e, 0xd7, 0xc2, 0xcd, - 0x6d, 0x70, 0xeb, 0x72, 0x7d, 0xca, 0x4a, 0x87, 0xe4, 0x77, 0x33, 0x20, - 0xb5, 0xfc, 0x05, 0x73, 0xde, 0x5a, 0xbe, 0xd8, 0xc1, 0x86, 0x7f, 0x97, - 0x93, 0xbd, 0xaf, 0xac, 0xc5, 0x5e, 0xfb, 0xe2, 0xdb, 0xee, 0x83, 0xf8, - 0xdb, 0xfc, 0x21, 0xbc, 0x39, 0xee, 0x21, 0xce, 0x14, 0x59, 0xd6, 0xa3, - 0x7a, 0x75, 0x3c, 0xfd, 0x2e, 0xf3, 0xe2, 0xc5, 0xa9, 0x92, 0x5f, 0xcc, - 0xb5, 0xae, 0x98, 0x52, 0xa4, 0x55, 0x85, 0x32, 0xca, 0xf9, 0x53, 0xc3, - 0x8d, 0x68, 0x11, 0xdb, 0xba, 0xc9, 0xe7, 0xee, 0x9c, 0x83, 0x79, 0x63, - 0xf9, 0xc3, 0x01, 0x67, 0xfe, 0x15, 0x60, 0x1e, 0x1d, 0xc5, 0x91, 0x5c, - 0x63, 0xe2, 0x3d, 0x39, 0xa7, 0xc3, 0x5e, 0xec, 0x12, 0x46, 0x71, 0x22, - 0x57, 0xca, 0xa1, 0x11, 0x39, 0xdf, 0x9a, 0x88, 0xba, 0x9c, 0x1c, 0x19, - 0x75, 0x69, 0xd9, 0xa8, 0xeb, 0xe6, 0x80, 0x60, 0x83, 0xe1, 0x42, 0x2c, - 0x52, 0x0e, 0x37, 0xf6, 0x18, 0x8e, 0x7f, 0xd4, 0xcf, 0x78, 0x11, 0x5d, - 0x24, 0x75, 0x59, 0x6a, 0xb2, 0x87, 0x35, 0x79, 0x31, 0xd2, 0x8b, 0x3d, - 0x78, 0x4d, 0x17, 0x7d, 0xec, 0x2f, 0xe9, 0xc3, 0x38, 0x87, 0xfd, 0xd6, - 0x7c, 0xb7, 0xf8, 0x92, 0x17, 0x87, 0x9a, 0xa6, 0xad, 0xa9, 0xb0, 0xc8, - 0xee, 0xc6, 0x69, 0xe6, 0x57, 0xdc, 0x1c, 0x8b, 0x9c, 0x66, 0xcd, 0x1e, - 0xd1, 0x4b, 0x3e, 0x7e, 0x57, 0x91, 0x4f, 0x3d, 0x33, 0x8b, 0x3f, 0xe1, - 0xef, 0xf5, 0x91, 0xbd, 0xca, 0x59, 0x6f, 0xf9, 0xcc, 0xdb, 0x81, 0xd2, - 0xec, 0x54, 0x9e, 0x8d, 0xe6, 0x09, 0x3a, 0x2b, 0x84, 0x56, 0x80, 0xfe, - 0x59, 0x8e, 0xde, 0xb0, 0x9c, 0xf3, 0x10, 0xbd, 0xc8, 0x9e, 0x22, 0xa8, - 0x0f, 0x0b, 0x2f, 0x51, 0x1f, 0x87, 0xae, 0x9d, 0xa9, 0x72, 0xf2, 0x57, - 0x05, 0xaf, 0x6f, 0x4e, 0xbe, 0xb8, 0xce, 0x8f, 0xdf, 0x58, 0x97, 0xc2, - 0x11, 0xe6, 0x04, 0xb1, 0x69, 0xc6, 0xc6, 0x91, 0x6e, 0xe2, 0x93, 0xdd, - 0xf6, 0xf9, 0x11, 0xc6, 0x81, 0x79, 0x4d, 0x8e, 0xf9, 0x3e, 0xe2, 0xec, - 0xb9, 0x9c, 0x7d, 0x66, 0xaf, 0xf7, 0x0d, 0x15, 0x63, 0xae, 0xf9, 0x12, - 0x7a, 0x6b, 0x85, 0x5e, 0x28, 0xb8, 0x6d, 0x32, 0x41, 0x1d, 0xd4, 0x09, - 0x5d, 0xeb, 0x29, 0x76, 0x73, 0x87, 0xc6, 0x84, 0x3e, 0x30, 0x32, 0x16, - 0xeb, 0xff, 0x29, 0xb0, 0xae, 0x0a, 0xda, 0xe0, 0x6c, 0xf1, 0xff, 0x38, - 0x7e, 0xa1, 0x84, 0x96, 0xd0, 0xf1, 0xc0, 0x64, 0x8e, 0x3b, 0x3e, 0x57, - 0x41, 0xdd, 0x69, 0xdd, 0x3f, 0x50, 0x15, 0x78, 0xec, 0x89, 0x04, 0x79, - 0x5f, 0x14, 0xdc, 0x3c, 0xe9, 0x83, 0xff, 0x4c, 0x15, 0x6b, 0xae, 0x0f, - 0x97, 0x9b, 0x69, 0xd7, 0x27, 0x4a, 0xbc, 0xdb, 0x7b, 0xa3, 0x78, 0x74, - 0x22, 0x0a, 0x93, 0x3e, 0x3b, 0x67, 0xca, 0x3e, 0xb0, 0xcf, 0xce, 0x9f, - 0x17, 0xd7, 0xd4, 0xd9, 0x7b, 0x54, 0xcf, 0x16, 0xf4, 0xc8, 0x59, 0x55, - 0x85, 0x0f, 0x4e, 0xcc, 0xdf, 0x5c, 0x0e, 0xeb, 0x85, 0xa5, 0xa9, 0x78, - 0x66, 0x17, 0x7d, 0x7e, 0xc5, 0xf2, 0x30, 0x7b, 0x19, 0xf6, 0x94, 0x6b, - 0xa5, 0xff, 0x1d, 0x60, 0xff, 0x5b, 0xda, 0xd3, 0xd7, 0xfb, 0x1f, 0x52, - 0xd9, 0x4d, 0x41, 0x58, 0x1f, 0x95, 0xa7, 0xac, 0x8f, 0xbd, 0xa9, 0x38, - 0xdf, 0x97, 0x3d, 0x3d, 0xcb, 0x7a, 0xab, 0xd9, 0xb2, 0xf2, 0xcd, 0xb1, - 0x4c, 0xc8, 0x1d, 0xc2, 0x99, 0x06, 0xd9, 0x07, 0x74, 0xe1, 0x83, 0xb8, - 0x1e, 0xd9, 0x05, 0xd9, 0x7b, 0x67, 0x8e, 0x5f, 0x2c, 0xe7, 0x0e, 0xeb, - 0x82, 0x9d, 0xe6, 0x22, 0x3c, 0x33, 0xbb, 0x16, 0xbd, 0x5e, 0xd8, 0xe7, - 0x62, 0x2c, 0x03, 0x6f, 0x2c, 0x85, 0xd4, 0xed, 0x78, 0xcb, 0x43, 0x08, - 0x63, 0xb6, 0x70, 0x08, 0x0f, 0x9e, 0x90, 0xfd, 0xc5, 0x07, 0x5a, 0x7d, - 0x27, 0xac, 0xbf, 0x8b, 0xa4, 0xe6, 0x99, 0x17, 0x2d, 0xab, 0x62, 0x6d, - 0x63, 0x84, 0xe5, 0x88, 0x18, 0xa3, 0x57, 0xb0, 0x7b, 0xff, 0x07, 0xa8, - 0xc1, 0xd9, 0xe9, 0xf4, 0xcd, 0xec, 0x25, 0x3b, 0x9f, 0x54, 0x21, 0x3c, - 0x4f, 0x19, 0x9f, 0x2e, 0x08, 0x4e, 0x79, 0xb0, 0x75, 0xcb, 0x89, 0x25, - 0x78, 0x61, 0x36, 0x8c, 0xb3, 0xa6, 0x4e, 0x9c, 0x04, 0x55, 0x99, 0xb2, - 0xaa, 0xab, 0xc9, 0x6b, 0xa5, 0xdb, 0x8d, 0x4d, 0x49, 0xe9, 0x0f, 0xf5, - 0xfe, 0x80, 0xc2, 0x92, 0x72, 0xe8, 0x0b, 0xfb, 0x81, 0x01, 0x3f, 0xfb, - 0xd5, 0x27, 0x55, 0x3c, 0xf3, 0xbe, 0x3b, 0x8c, 0xe7, 0x99, 0x7f, 0x7e, - 0x50, 0x90, 0x33, 0x53, 0xcc, 0x31, 0xd3, 0x51, 0xda, 0xca, 0x07, 0x57, - 0x7d, 0x15, 0x0e, 0x33, 0x5e, 0x5e, 0x32, 0xca, 0x98, 0xa3, 0xe4, 0x0c, - 0x95, 0xe4, 0xf7, 0x9d, 0x72, 0x56, 0xc4, 0x7a, 0x56, 0x77, 0xfa, 0x7d, - 0x63, 0xe6, 0xc6, 0x73, 0xc8, 0x21, 0xe6, 0xf5, 0xc6, 0xee, 0x88, 0x7a, - 0xc5, 0x4a, 0x7f, 0x5d, 0x51, 0xce, 0xdd, 0x55, 0xa8, 0xb0, 0x65, 0xc5, - 0xf0, 0x44, 0xa9, 0xa6, 0x54, 0x4b, 0x2f, 0xd7, 0x9d, 0x2d, 0xfa, 0x60, - 0x25, 0x63, 0xfd, 0x28, 0x6b, 0x74, 0xf9, 0x09, 0xa9, 0x25, 0xec, 0x5f, - 0xd4, 0x7a, 0x62, 0x61, 0xc1, 0x0d, 0x3e, 0xdc, 0x1f, 0xd2, 0x5a, 0xe4, - 0x2c, 0xf6, 0xd3, 0x85, 0x0e, 0x8f, 0x9c, 0x89, 0x7a, 0xa6, 0x20, 0xb5, - 0x5c, 0x72, 0x41, 0x69, 0xbd, 0x08, 0x6a, 0xc7, 0xc4, 0x46, 0xdd, 0xad, - 0x1f, 0x8d, 0x05, 0xe4, 0xdc, 0xfc, 0x90, 0x8b, 0xbd, 0xb6, 0x6f, 0xcc, - 0xb2, 0xee, 0x6e, 0xd6, 0xfb, 0xd7, 0xbb, 0x65, 0x3f, 0x39, 0xd6, 0x7b, - 0x4e, 0x69, 0x2d, 0x47, 0xd4, 0x8d, 0x74, 0x9e, 0xab, 0x92, 0x18, 0xc9, - 0x52, 0xce, 0x47, 0x6d, 0x99, 0xf6, 0x53, 0xa6, 0xd2, 0x99, 0xa1, 0x2a, - 0x5c, 0x1e, 0x87, 0xce, 0xa8, 0xc5, 0x79, 0x83, 0xc9, 0x29, 0x14, 0x4f, - 0xb7, 0x43, 0xfc, 0x5f, 0xeb, 0x15, 0x0c, 0x55, 0xc9, 0x9c, 0x3c, 0x3d, - 0x2e, 0x35, 0x46, 0x09, 0x3e, 0xc9, 0x56, 0xa7, 0x06, 0x70, 0x65, 0x0d, - 0xf0, 0xca, 0x98, 0xb3, 0xdf, 0x5e, 0x3c, 0xe3, 0x6d, 0x9f, 0x65, 0x78, - 0xc8, 0x3e, 0xa3, 0x20, 0xf4, 0x0f, 0xe2, 0x4c, 0x4e, 0x30, 0xe5, 0x00, - 0x31, 0x65, 0x6c, 0x90, 0x78, 0xb3, 0xa5, 0xe0, 0x9c, 0xb7, 0x32, 0x3e, - 0xa2, 0xcf, 0x3f, 0x49, 0xac, 0x7a, 0x18, 0xce, 0x7e, 0x7b, 0x43, 0xf1, - 0x0c, 0x42, 0x2c, 0xdf, 0xa9, 0xb6, 0x16, 0xec, 0x33, 0x5a, 0x8c, 0xb1, - 0x76, 0xb5, 0x79, 0xb6, 0x43, 0x6d, 0x99, 0xed, 0x52, 0x3b, 0x0a, 0xd2, - 0xb3, 0x3e, 0xd0, 0x7a, 0xff, 0x89, 0xed, 0x6a, 0xeb, 0x74, 0x8f, 0x22, - 0xa6, 0x0d, 0xf9, 0x52, 0x19, 0xd5, 0x35, 0xeb, 0xcc, 0xcf, 0x3b, 0xd9, - 0x77, 0x6d, 0x35, 0x4b, 0xfd, 0xbc, 0xfc, 0x1f, 0x57, 0x58, 0xfe, 0x67, - 0xa2, 0x77, 0xa3, 0xb2, 0xac, 0x5b, 0x93, 0x7f, 0x2d, 0xf6, 0xb0, 0x9e, - 0x4e, 0xb2, 0x36, 0x9a, 0x55, 0xe8, 0x63, 0xdf, 0x31, 0x6c, 0x2c, 0x2b, - 0xee, 0x97, 0x89, 0x4c, 0x72, 0x4e, 0x42, 0xfc, 0x15, 0x59, 0xf6, 0x20, - 0xf8, 0x7b, 0xf2, 0xbf, 0xb7, 0x28, 0x57, 0x97, 0x9c, 0x23, 0xf0, 0x5e, - 0x3f, 0x47, 0x76, 0x6c, 0xec, 0xba, 0x5c, 0x1e, 0x5e, 0x1b, 0x25, 0x3e, - 0xdd, 0xab, 0xb4, 0xc1, 0xa7, 0x1c, 0xb9, 0x2e, 0x5e, 0x66, 0x0c, 0x0f, - 0xdb, 0x31, 0xec, 0xc8, 0xb5, 0xb2, 0x28, 0xd7, 0x8a, 0x7c, 0xa7, 0x7d, - 0x3e, 0x8b, 0x74, 0x5a, 0xe7, 0xc6, 0xe4, 0x1c, 0x99, 0xcc, 0x2e, 0x45, - 0x36, 0x91, 0xe3, 0x84, 0x55, 0xa1, 0x77, 0xa9, 0x6d, 0xf6, 0xb9, 0x32, - 0x39, 0xd3, 0x25, 0xfb, 0xfb, 0x25, 0xb9, 0xa4, 0x8e, 0x2f, 0x0a, 0x76, - 0x4c, 0xca, 0x39, 0x6b, 0xcb, 0xfa, 0x99, 0x51, 0x11, 0x14, 0x59, 0xce, - 0x1a, 0x22, 0x8b, 0x9c, 0x17, 0x29, 0xc9, 0xf3, 0xb5, 0xa2, 0x3c, 0x62, - 0xab, 0xeb, 0x76, 0x2a, 0xfd, 0xff, 0xdf, 0xdb, 0x39, 0xe7, 0x2c, 0x49, - 0x49, 0x9e, 0x60, 0x4a, 0xf8, 0xcf, 0xb7, 0x8e, 0x8e, 0x0f, 0xe0, 0x15, - 0xde, 0xff, 0x65, 0xae, 0x24, 0x97, 0x1b, 0x33, 0xd3, 0xa5, 0x33, 0x72, - 0x6c, 0x29, 0xcd, 0x98, 0x31, 0x42, 0x3f, 0x72, 0xe4, 0x93, 0x33, 0x72, - 0x8d, 0xf3, 0x97, 0xed, 0xb9, 0x57, 0x3c, 0xcd, 0x7e, 0x19, 0x67, 0x0b, - 0xbf, 0x6d, 0xbf, 0xa6, 0x7c, 0x05, 0x7b, 0x64, 0xa1, 0x3d, 0x47, 0xda, - 0x72, 0x96, 0x44, 0xe1, 0xa9, 0x69, 0x60, 0xda, 0xe4, 0xb2, 0xa9, 0x21, - 0x3c, 0x6e, 0x58, 0xd6, 0x93, 0xcd, 0xba, 0x9c, 0x01, 0xba, 0x50, 0x6b, - 0xcf, 0x85, 0x60, 0x54, 0xe9, 0xb2, 0x77, 0x27, 0xe7, 0x48, 0x7a, 0xa8, - 0x03, 0x91, 0x5d, 0x7c, 0xa0, 0x64, 0x7b, 0x39, 0xdf, 0x96, 0xa5, 0x7e, - 0x44, 0x37, 0xa5, 0x73, 0x6e, 0x32, 0x73, 0xb9, 0x51, 0x27, 0xb7, 0xd9, - 0x3a, 0x79, 0xda, 0x10, 0x7f, 0x65, 0xf6, 0xa1, 0xaf, 0xce, 0x10, 0x3f, - 0x8c, 0x18, 0x5e, 0x1b, 0xab, 0x1d, 0x26, 0x3e, 0x39, 0xc2, 0xd8, 0x79, - 0xd4, 0xbc, 0x88, 0x8b, 0xf9, 0x97, 0xf0, 0xca, 0xb5, 0xff, 0x85, 0x13, - 0x7f, 0xf1, 0xb5, 0x6c, 0xb1, 0xcf, 0x32, 0xfd, 0x75, 0xcb, 0xb2, 0xb8, - 0xe4, 0xa1, 0x93, 0x4d, 0x72, 0xb6, 0xa9, 0x3c, 0xf5, 0xde, 0x3a, 0xd9, - 0xdf, 0x2a, 0x4b, 0x0d, 0x7e, 0xf5, 0x82, 0x2e, 0xba, 0xf9, 0x64, 0xf5, - 0x19, 0x5d, 0xe4, 0xd2, 0x8d, 0x51, 0xfb, 0x7f, 0x33, 0x43, 0x6b, 0x77, - 0xeb, 0x12, 0x3b, 0xef, 0x34, 0xb7, 0xd9, 0x39, 0x61, 0x30, 0x75, 0xab, - 0xad, 0x83, 0x83, 0xa9, 0x65, 0x8e, 0x2e, 0x52, 0x09, 0xfb, 0xfb, 0xe1, - 0x94, 0xa3, 0x9b, 0x5c, 0xaa, 0xde, 0xfe, 0x1e, 0x4d, 0x39, 0x67, 0xa2, - 0xb3, 0x29, 0xdd, 0xfe, 0x1e, 0x4f, 0xc5, 0xec, 0xef, 0x23, 0xa9, 0x5b, - 0xae, 0xf3, 0xc5, 0x9f, 0xff, 0x07, 0xd8, 0xc4, 0xd3, 0xb4, 0xb4, 0x3a, + 0xad, 0x7b, 0x0f, 0x70, 0x54, 0xe7, 0x75, 0xef, 0xef, 0xee, 0x1f, 0x69, + 0x57, 0x5a, 0xad, 0x2e, 0x78, 0xc1, 0xab, 0x54, 0x29, 0x7b, 0xd9, 0xbb, + 0xd2, 0x1a, 0x09, 0xb8, 0x0b, 0xc2, 0x88, 0xe8, 0xd6, 0x6c, 0x85, 0x00, + 0x21, 0x64, 0x2c, 0x63, 0x25, 0x15, 0x7d, 0x9e, 0x5a, 0x0f, 0x64, 0x23, + 0xdb, 0xd8, 0x16, 0x35, 0x6d, 0xe5, 0xd4, 0xad, 0xd6, 0x92, 0xc0, 0xc2, + 0xac, 0xb8, 0x22, 0x0b, 0x11, 0xee, 0xf4, 0xbd, 0xc8, 0x96, 0xb0, 0xb0, + 0xb3, 0x62, 0xed, 0xa4, 0xaf, 0xd3, 0xcc, 0x34, 0xe3, 0x7d, 0xfe, 0x83, + 0x49, 0x1e, 0xb6, 0xd3, 0x4e, 0xe7, 0x3d, 0xa7, 0xf3, 0xde, 0x84, 0x17, + 0x63, 0x62, 0xa7, 0x89, 0xed, 0xe6, 0xa5, 0xf3, 0x44, 0xea, 0xf8, 0xbe, + 0xdf, 0xb9, 0x77, 0x17, 0x88, 0x9b, 0x4e, 0x67, 0x3a, 0x4f, 0x33, 0x9a, + 0xd5, 0xde, 0x3f, 0xdf, 0x77, 0xce, 0xf9, 0xce, 0xf9, 0x9d, 0xdf, 0x39, + 0xdf, 0xa7, 0x06, 0xa0, 0x0a, 0xa5, 0x9f, 0x1a, 0xfe, 0xb6, 0x0c, 0x0d, + 0x1f, 0x4a, 0xad, 0xb9, 0x75, 0x0d, 0xff, 0xbc, 0x15, 0x6a, 0x85, 0x4f, + 0x6e, 0xde, 0xaa, 0x00, 0xfd, 0x3f, 0xc6, 0xbf, 0xeb, 0xe7, 0xf3, 0xff, + 0xbe, 0xd7, 0x9c, 0x1f, 0x2f, 0xa0, 0x96, 0xe5, 0x92, 0x5f, 0x04, 0x3c, + 0xe6, 0xcc, 0x17, 0xda, 0x75, 0x04, 0xbc, 0x66, 0xaf, 0xb9, 0x4f, 0x07, + 0xd2, 0xf9, 0xa6, 0xd8, 0x16, 0xfc, 0xd2, 0xce, 0x44, 0x7c, 0x90, 0xeb, + 0x9f, 0x37, 0x3f, 0x19, 0xf9, 0xf6, 0x46, 0xed, 0xe3, 0x19, 0x2f, 0x02, + 0xaa, 0x79, 0x1a, 0x6a, 0x03, 0x02, 0xf5, 0x7c, 0xe7, 0xcf, 0x1b, 0xfd, + 0x5e, 0x84, 0xcb, 0x63, 0xb5, 0x62, 0xcc, 0x42, 0x26, 0x60, 0x0e, 0xa1, + 0x72, 0x03, 0xf0, 0x5e, 0x36, 0x61, 0x8c, 0x01, 0x53, 0x1e, 0x33, 0x11, + 0x7b, 0x05, 0x06, 0x0e, 0x17, 0x62, 0xe8, 0xe0, 0xef, 0x0e, 0xeb, 0x53, + 0x3b, 0xe6, 0x47, 0xc6, 0xcb, 0xe7, 0xf6, 0xb6, 0x00, 0x5b, 0xb3, 0x06, + 0x8e, 0x58, 0x08, 0xd4, 0x99, 0x8f, 0x63, 0x13, 0x3f, 0xc3, 0xe6, 0x30, + 0xde, 0x9a, 0x8c, 0xc7, 0x9e, 0x83, 0xd6, 0xa7, 0x7b, 0xb5, 0x61, 0xa0, + 0x69, 0x70, 0x40, 0xd1, 0xfa, 0xdf, 0x56, 0xb4, 0x9e, 0x49, 0x05, 0x01, + 0x85, 0xcf, 0x35, 0xe5, 0xe5, 0x73, 0x18, 0xab, 0xf2, 0x01, 0x5c, 0xf2, + 0xca, 0xfc, 0xbf, 0x45, 0x7b, 0x2b, 0xf0, 0xe9, 0xad, 0x18, 0xa7, 0x0c, + 0x7e, 0x53, 0xc1, 0xb3, 0x2d, 0x89, 0xe8, 0x28, 0xe4, 0x7e, 0x0c, 0x5b, + 0x0a, 0xf2, 0xa9, 0x51, 0x6b, 0xdb, 0x1e, 0x37, 0x6c, 0xfb, 0x8c, 0x51, + 0x89, 0x8c, 0xaa, 0x45, 0x01, 0x05, 0xa3, 0x86, 0x07, 0x69, 0xb5, 0x3d, + 0xe6, 0x83, 0x16, 0xbd, 0x17, 0xff, 0x4c, 0x9d, 0xd3, 0x49, 0x3f, 0xdc, + 0xe7, 0xfb, 0x51, 0x89, 0xa2, 0xea, 0x5a, 0xed, 0xd9, 0xac, 0x6d, 0x9f, + 0xd7, 0x7d, 0x38, 0x43, 0xfb, 0x8c, 0xe6, 0xff, 0xd9, 0x2e, 0xd2, 0x36, + 0xe3, 0x7a, 0x79, 0xfe, 0x00, 0x66, 0x54, 0xdb, 0x9e, 0xe5, 0xbd, 0x23, + 0xf9, 0xb2, 0x9d, 0x6d, 0xdb, 0xa3, 0xdb, 0xf6, 0x3e, 0xfd, 0x17, 0xf6, + 0xde, 0x5f, 0x79, 0xd6, 0xb6, 0x9f, 0x32, 0x6e, 0xc2, 0xd9, 0x5c, 0x87, + 0xd2, 0x35, 0xbf, 0x3c, 0xbc, 0x63, 0xda, 0xc6, 0x79, 0x03, 0xaa, 0xc7, + 0xdc, 0xa6, 0xec, 0x98, 0xef, 0x54, 0xb6, 0x16, 0x76, 0x2b, 0xdb, 0x66, + 0x7f, 0x57, 0xe9, 0x9c, 0xef, 0x57, 0xb6, 0x17, 0xa2, 0x98, 0xb3, 0x22, + 0x98, 0xb5, 0xfa, 0x94, 0x8e, 0xf9, 0x5e, 0xc5, 0xd5, 0x63, 0x58, 0x69, + 0x2f, 0x94, 0xc7, 0xba, 0x6e, 0xc7, 0x1d, 0x59, 0x13, 0x13, 0x56, 0x25, + 0xe7, 0x59, 0xb4, 0xbf, 0xdd, 0xb8, 0x48, 0x3d, 0x0d, 0x1c, 0x2d, 0x3c, + 0x85, 0xdb, 0xa7, 0x6d, 0x3b, 0x9f, 0x02, 0xf2, 0x05, 0xe0, 0xeb, 0x56, + 0xbc, 0x67, 0x50, 0xb1, 0xed, 0xed, 0x09, 0x7b, 0xc5, 0x15, 0xa3, 0x29, + 0xf9, 0x1a, 0xfe, 0xaf, 0x3d, 0x13, 0x41, 0x26, 0xc4, 0x31, 0x8e, 0x71, + 0xcd, 0x1e, 0x98, 0x44, 0xa0, 0xd2, 0x1c, 0xc7, 0x8f, 0xb2, 0x08, 0x54, + 0x98, 0x19, 0x9c, 0xcf, 0x8e, 0xaa, 0x01, 0xc4, 0xa3, 0x3b, 0x94, 0xcc, + 0xb0, 0x07, 0xda, 0xd0, 0xbb, 0xd0, 0x62, 0x5c, 0x8f, 0x0b, 0xaf, 0x2a, + 0x5a, 0xf1, 0x35, 0x68, 0xe9, 0x5f, 0x28, 0x5a, 0x67, 0x9d, 0x17, 0x69, + 0x4f, 0x22, 0x80, 0x6f, 0x37, 0xca, 0x9a, 0x8c, 0x63, 0x8d, 0xb3, 0x36, + 0x19, 0xdc, 0x72, 0x6d, 0x6d, 0x4c, 0x8c, 0x52, 0xae, 0x23, 0x94, 0xeb, + 0x75, 0x43, 0x8b, 0x3e, 0x0b, 0x7b, 0xc5, 0x80, 0x21, 0xf7, 0x4c, 0x8c, + 0x17, 0xec, 0x58, 0xd8, 0xbc, 0x44, 0x79, 0x91, 0xf9, 0x9c, 0x19, 0xc8, + 0xd4, 0x9a, 0xbf, 0xb4, 0xdf, 0xdc, 0x10, 0xc5, 0xcb, 0x85, 0x08, 0x5e, + 0x2a, 0xa8, 0x78, 0xb1, 0xd0, 0x01, 0xab, 0x80, 0xf0, 0xed, 0x85, 0x5f, + 0xe7, 0xc7, 0x36, 0x42, 0x7c, 0x9e, 0x72, 0x87, 0x77, 0x16, 0x7c, 0xfd, + 0x15, 0x26, 0x7a, 0xbe, 0x93, 0x1d, 0xb1, 0xab, 0x74, 0xf4, 0x2f, 0x31, + 0xf5, 0xf4, 0x2a, 0x25, 0xd4, 0x4a, 0x3f, 0xec, 0x79, 0x23, 0xdf, 0xea, + 0xd3, 0x8f, 0x07, 0xe1, 0xa7, 0xfd, 0xb7, 0x16, 0x6c, 0x7b, 0xcc, 0x38, + 0xb8, 0x76, 0x6f, 0xeb, 0x37, 0x8b, 0x3d, 0x7a, 0x37, 0x32, 0x85, 0x01, + 0x20, 0x6c, 0xf2, 0x93, 0xa1, 0xb8, 0xbb, 0xb9, 0x23, 0x76, 0xae, 0xdf, + 0xe7, 0xfa, 0x33, 0x65, 0xa0, 0xdd, 0x5f, 0xb2, 0x28, 0x83, 0xf5, 0x47, + 0x61, 0x54, 0xc5, 0xa8, 0xdf, 0xf7, 0x28, 0x67, 0x12, 0xdf, 0x28, 0xe8, + 0x94, 0xad, 0x99, 0x32, 0xc6, 0x28, 0x5f, 0x00, 0x7b, 0x73, 0xda, 0x54, + 0x06, 0xda, 0xc4, 0x0c, 0x56, 0x23, 0x1d, 0x51, 0xe9, 0x83, 0x7f, 0x06, + 0x77, 0x8c, 0x6e, 0x1c, 0xb7, 0xb0, 0x4e, 0x35, 0xb9, 0xbe, 0x29, 0x3c, + 0x5e, 0x81, 0x44, 0xff, 0xc7, 0x8a, 0x82, 0x37, 0x13, 0xdd, 0x98, 0xa4, + 0x3e, 0xdd, 0xf9, 0x20, 0x1e, 0xcc, 0x55, 0xe1, 0xfe, 0x9c, 0x8d, 0x07, + 0x52, 0x30, 0xab, 0xa8, 0x4f, 0x32, 0x95, 0x88, 0xbd, 0x0f, 0x1f, 0x3a, + 0xf2, 0xdd, 0x8c, 0xa5, 0x2d, 0x48, 0x57, 0x04, 0xb0, 0x25, 0x1f, 0x62, + 0x3c, 0xa6, 0x71, 0x7a, 0x3a, 0x00, 0xff, 0x7a, 0x0f, 0x66, 0x22, 0x15, + 0x48, 0x36, 0x78, 0xf8, 0x1b, 0x09, 0xb7, 0x4f, 0xd7, 0x87, 0xb7, 0x5a, + 0x3e, 0xec, 0xb7, 0x3c, 0x18, 0xc9, 0xd9, 0x76, 0x87, 0x61, 0xe3, 0xea, + 0x7a, 0x15, 0xdf, 0xa2, 0xfd, 0x0e, 0x5a, 0x51, 0x9c, 0x2d, 0x3c, 0x49, + 0x59, 0x22, 0xae, 0xbc, 0x16, 0x65, 0xb7, 0x28, 0xbb, 0x45, 0xb9, 0x2d, + 0x91, 0xf3, 0x55, 0xc6, 0x8c, 0x41, 0xbd, 0x82, 0x94, 0xa1, 0x1a, 0x83, + 0x94, 0x23, 0x9e, 0xb2, 0xe1, 0x49, 0x69, 0x99, 0xbd, 0x04, 0xaf, 0x15, + 0x0d, 0xb6, 0xfd, 0xf1, 0x7a, 0xd1, 0x85, 0x6b, 0xee, 0xe9, 0x96, 0x18, + 0xfd, 0xed, 0x1a, 0xc6, 0xd5, 0xf7, 0x69, 0xb7, 0xa7, 0x0b, 0x41, 0x0c, + 0xe7, 0x1c, 0xbf, 0x3d, 0x54, 0x41, 0xb9, 0x45, 0xae, 0x82, 0x9e, 0x60, + 0x8c, 0x26, 0xfa, 0x18, 0xa3, 0xd8, 0x49, 0x99, 0x1f, 0xb0, 0x22, 0xe1, + 0x8e, 0xe9, 0x44, 0xeb, 0x6e, 0xc5, 0x87, 0xed, 0xf9, 0xeb, 0x72, 0x52, + 0x5f, 0x89, 0x41, 0xea, 0xaa, 0x52, 0xbe, 0x08, 0xf6, 0x51, 0xce, 0x97, + 0x4a, 0x72, 0xce, 0x16, 0x64, 0xae, 0xcf, 0xca, 0x5a, 0x96, 0x13, 0x99, + 0xa5, 0x66, 0x44, 0x41, 0x55, 0x08, 0xbb, 0xf3, 0xef, 0x70, 0x2d, 0xea, + 0xf1, 0x4d, 0xae, 0xc1, 0xcb, 0x8c, 0x91, 0x6f, 0x5c, 0xf3, 0x17, 0x59, + 0x8f, 0x27, 0xb8, 0x0e, 0xda, 0xe9, 0x0c, 0x42, 0xe8, 0x2f, 0xa4, 0x71, + 0x78, 0x1a, 0xe9, 0x39, 0xe3, 0x18, 0xe3, 0x7d, 0x39, 0xbc, 0x7a, 0x65, + 0x5a, 0xd5, 0xab, 0xb0, 0x6f, 0x36, 0x82, 0xa1, 0x42, 0x3b, 0xac, 0x5c, + 0x04, 0x07, 0xe8, 0x9b, 0x1f, 0xa6, 0xd2, 0x0f, 0x84, 0x21, 0xb2, 0x47, + 0xf0, 0x20, 0xdf, 0x79, 0x6a, 0x3a, 0x82, 0x41, 0xda, 0x68, 0x47, 0x2a, + 0xd1, 0x1a, 0xe4, 0xb5, 0xfd, 0xbc, 0x76, 0x84, 0xf6, 0x7f, 0xd5, 0x98, + 0x44, 0x7f, 0x8f, 0x96, 0x04, 0x22, 0xb8, 0xcf, 0x82, 0x4a, 0x17, 0x7e, + 0x82, 0xf8, 0x96, 0x7c, 0x95, 0xdf, 0xef, 0x2d, 0x54, 0x51, 0xdf, 0x30, + 0xa2, 0xfa, 0x27, 0xb6, 0xbf, 0xc5, 0xb6, 0xbf, 0x66, 0x24, 0x2e, 0xfc, + 0xd0, 0xeb, 0xc3, 0x63, 0x05, 0x0f, 0x86, 0x67, 0xab, 0xf0, 0xfb, 0x39, + 0x1f, 0xee, 0x6c, 0xa8, 0xc2, 0xc1, 0xd9, 0x34, 0xc6, 0xa6, 0xab, 0x30, + 0x90, 0xc3, 0x8a, 0xfb, 0x8c, 0xb1, 0x25, 0x15, 0xd0, 0x16, 0x3b, 0x90, + 0xc4, 0x55, 0xae, 0xc3, 0x63, 0xb3, 0xa1, 0x70, 0xdf, 0xb4, 0x8a, 0xe1, + 0xf9, 0x20, 0x9f, 0xf7, 0xf0, 0xf9, 0x4a, 0x18, 0xeb, 0xe2, 0xc3, 0x2a, + 0x44, 0xc6, 0x6a, 0x3c, 0x3c, 0x1b, 0xc4, 0x43, 0x39, 0x15, 0x07, 0xa6, + 0x5b, 0x30, 0x65, 0xa5, 0x71, 0x94, 0xd8, 0xf1, 0xf5, 0x94, 0xd6, 0x73, + 0x40, 0xd1, 0xd2, 0x5b, 0x95, 0x34, 0x1a, 0x53, 0x7e, 0x5c, 0x22, 0x0e, + 0xf9, 0x53, 0x4d, 0xad, 0x2f, 0x12, 0x1b, 0x2a, 0xcc, 0x08, 0xbf, 0x6b, + 0x13, 0x8c, 0xd9, 0xb4, 0xdf, 0xb3, 0x1e, 0x58, 0x26, 0xf1, 0x1b, 0x09, + 0x77, 0x59, 0x6a, 0xb8, 0xab, 0x50, 0x1f, 0xde, 0x61, 0x45, 0xc3, 0x3b, + 0x18, 0x5f, 0x5b, 0xc5, 0x1f, 0xad, 0x00, 0x8e, 0xa5, 0x7e, 0x69, 0xf7, + 0x2f, 0x71, 0xf0, 0x2c, 0x7c, 0xfb, 0xb4, 0x96, 0x99, 0x81, 0x66, 0x30, + 0x1b, 0x60, 0x72, 0xde, 0xc7, 0xf5, 0x53, 0xb0, 0x44, 0x6f, 0x21, 0x8e, + 0xab, 0x78, 0x98, 0x98, 0xf2, 0xb7, 0xc4, 0x94, 0x81, 0xe3, 0x71, 0x75, + 0x0a, 0x41, 0xda, 0x1b, 0xd8, 0x7b, 0x2e, 0xc2, 0x35, 0xef, 0xc4, 0x93, + 0x94, 0x6b, 0xc7, 0x86, 0x08, 0xee, 0x2f, 0xa8, 0xe1, 0x4e, 0xae, 0xdf, + 0xfb, 0xf9, 0x68, 0x78, 0x0b, 0xd7, 0xf2, 0xdd, 0xbc, 0x16, 0x2b, 0xe2, + 0x9f, 0xc4, 0x9f, 0x92, 0xf0, 0x00, 0xf7, 0x1d, 0xf7, 0xa3, 0x18, 0x91, + 0xb9, 0x68, 0x73, 0xeb, 0x65, 0x3b, 0xa4, 0xeb, 0xa7, 0x0f, 0xd0, 0xd6, + 0x8f, 0x16, 0x42, 0x78, 0xc8, 0xd2, 0x92, 0xdf, 0x50, 0x42, 0xb4, 0x69, + 0x80, 0x76, 0x20, 0xc0, 0x2c, 0x97, 0xe7, 0x52, 0x88, 0x2d, 0x77, 0xb1, + 0xf6, 0xe0, 0xac, 0xf8, 0x09, 0xd7, 0xde, 0xa2, 0x0f, 0xd0, 0x7f, 0xbe, + 0x71, 0x2d, 0x56, 0x35, 0x35, 0xe3, 0x60, 0x77, 0x92, 0xfe, 0xe2, 0xda, + 0xe8, 0xc4, 0xb4, 0xd8, 0x41, 0x9b, 0x82, 0x27, 0x8d, 0xb5, 0xeb, 0xfe, + 0xd6, 0xbe, 0xb4, 0x4c, 0xec, 0xa1, 0x62, 0x84, 0x36, 0x3c, 0x6d, 0xd9, + 0xf6, 0xd5, 0xf5, 0x3f, 0xb5, 0x5b, 0x6f, 0x16, 0xbb, 0x88, 0xae, 0xdf, + 0x52, 0x24, 0x8f, 0x2c, 0xd1, 0xc3, 0xff, 0x1f, 0x7c, 0xe5, 0x0f, 0xed, + 0x7e, 0x47, 0x3f, 0xf1, 0x17, 0x1f, 0x7d, 0xf1, 0x49, 0x8e, 0xed, 0x41, + 0x3f, 0xc7, 0x7b, 0xc4, 0xb2, 0x3f, 0xaa, 0x33, 0x3f, 0xb5, 0x5b, 0x37, + 0xea, 0x43, 0x8b, 0xca, 0xff, 0xe0, 0xf5, 0x08, 0x1e, 0x2e, 0xb4, 0xd2, + 0x76, 0x1d, 0x78, 0xca, 0x12, 0x3c, 0xec, 0x64, 0xbc, 0x45, 0xe9, 0xcf, + 0xf5, 0xf4, 0x6f, 0x9f, 0xb2, 0xd5, 0xca, 0x63, 0xc7, 0x64, 0x06, 0xdb, + 0xe9, 0xef, 0x17, 0xb2, 0xf1, 0xd6, 0xe7, 0xa1, 0x65, 0xa8, 0x43, 0xb8, + 0x93, 0x36, 0xee, 0xb0, 0xb4, 0x4e, 0x59, 0xd3, 0x0e, 0xe2, 0xd2, 0x2b, + 0xd9, 0x68, 0xb8, 0xbd, 0x20, 0xf6, 0xae, 0x0f, 0x6f, 0x29, 0xdc, 0xca, + 0xb5, 0x57, 0xb0, 0x69, 0x75, 0x80, 0x38, 0x73, 0x07, 0xdc, 0x75, 0x75, + 0xd7, 0xee, 0xcd, 0x54, 0x53, 0xff, 0x4f, 0xd1, 0x85, 0xcc, 0x32, 0xf7, + 0xda, 0x30, 0xaf, 0xd5, 0xae, 0x47, 0xf8, 0x0e, 0xfa, 0xc1, 0x3d, 0xf4, + 0x83, 0xab, 0xeb, 0x7f, 0x69, 0xc7, 0x6e, 0x72, 0xfd, 0xa0, 0x7d, 0xda, + 0x17, 0xde, 0x46, 0x3b, 0x6d, 0x35, 0x14, 0xcc, 0x1a, 0x4f, 0xa1, 0xff, + 0x1a, 0x77, 0x48, 0xcf, 0x9c, 0x35, 0xd2, 0xc4, 0x91, 0x36, 0xf8, 0x96, + 0x60, 0xe6, 0x79, 0xe3, 0x30, 0x62, 0xae, 0xef, 0xe0, 0x40, 0x2e, 0x88, + 0xcc, 0x9d, 0x2a, 0xe6, 0x1a, 0x55, 0x3c, 0xc2, 0xb1, 0x3f, 0x4c, 0x35, + 0x0d, 0xbe, 0x45, 0x1b, 0xcc, 0x2c, 0x91, 0x6b, 0x69, 0xfc, 0x95, 0xf1, + 0x65, 0xe0, 0x26, 0x77, 0xee, 0x79, 0x89, 0xd1, 0xf9, 0x16, 0x1c, 0x29, + 0xf4, 0x29, 0x2e, 0x6e, 0x6a, 0x9d, 0x69, 0x7c, 0xcf, 0x16, 0x2c, 0x9d, + 0x27, 0x86, 0xb4, 0xd3, 0xa7, 0xc6, 0xe9, 0x47, 0xa3, 0xc4, 0x90, 0xed, + 0xf4, 0xa3, 0x27, 0xf3, 0xa2, 0x53, 0xc2, 0x30, 0xbc, 0x37, 0x33, 0x37, + 0xd3, 0x3e, 0x96, 0x93, 0xf3, 0x6b, 0x55, 0xfd, 0x30, 0xa6, 0x1c, 0xd9, + 0x86, 0x95, 0x3b, 0xc8, 0x31, 0x2e, 0xf9, 0x51, 0x1b, 0xd5, 0x1f, 0xc1, + 0x69, 0xe7, 0x5a, 0x84, 0xef, 0xa6, 0x3d, 0x1e, 0x1d, 0xaa, 0x6a, 0x76, + 0x30, 0xaf, 0x8a, 0xef, 0x77, 0x2a, 0x3b, 0x98, 0x6b, 0xd3, 0xcc, 0xb5, + 0x69, 0xe6, 0xda, 0x34, 0xe7, 0x4f, 0x33, 0xc7, 0xb6, 0x17, 0x86, 0x95, + 0x1e, 0xb1, 0xbb, 0xd8, 0xdf, 0x72, 0xf9, 0x03, 0xb1, 0x27, 0xbc, 0xbd, + 0xb0, 0xc6, 0xe3, 0x72, 0xba, 0x61, 0xa5, 0xc4, 0x61, 0x02, 0x55, 0x3a, + 0x73, 0x98, 0x35, 0xac, 0x74, 0x31, 0xcf, 0xf6, 0x39, 0x36, 0x8c, 0x0f, + 0x5d, 0x66, 0x7e, 0x7d, 0x93, 0xf9, 0x35, 0x9f, 0x62, 0x3c, 0xad, 0xbe, + 0x6a, 0xf7, 0x2f, 0x73, 0x73, 0xc1, 0x18, 0xe5, 0xfc, 0x1a, 0xd7, 0xaa, + 0xc8, 0x1c, 0xda, 0xe1, 0x55, 0x70, 0x9f, 0x8e, 0xda, 0x3a, 0x62, 0xe9, + 0x91, 0x02, 0xf1, 0xdf, 0x88, 0xb7, 0x7e, 0x40, 0x83, 0x1e, 0xd1, 0xfd, + 0xb8, 0x7a, 0x13, 0x49, 0x8e, 0xde, 0x8e, 0x63, 0xb9, 0x4a, 0x0c, 0xa6, + 0xd2, 0x4b, 0x03, 0xe4, 0x28, 0x9d, 0x2d, 0x78, 0x9c, 0x53, 0x2b, 0x51, + 0x33, 0x41, 0x7f, 0x41, 0xfa, 0x38, 0xf3, 0xc3, 0xa4, 0x75, 0x2b, 0xf2, + 0xcc, 0xa3, 0x73, 0x86, 0x0f, 0x6f, 0xe6, 0xd7, 0x10, 0xdf, 0x12, 0x46, + 0x48, 0xa9, 0x62, 0xdc, 0x9a, 0xc8, 0x5a, 0x82, 0x4b, 0xb6, 0x3d, 0x27, + 0x32, 0x24, 0x12, 0xe9, 0x51, 0x08, 0x56, 0xd9, 0x2b, 0xee, 0x4d, 0x55, + 0x60, 0x53, 0x22, 0x8c, 0x15, 0x7a, 0xbf, 0xd2, 0x59, 0x48, 0x18, 0xaf, + 0xe2, 0x77, 0x95, 0x7b, 0xe6, 0x4d, 0xc6, 0x74, 0x9f, 0xb2, 0x67, 0xbe, + 0x0a, 0x97, 0x22, 0x22, 0x23, 0x6a, 0xfd, 0xba, 0x07, 0xef, 0xdd, 0xa5, + 0x40, 0xd5, 0xd3, 0x38, 0xdf, 0xa2, 0xd2, 0x9f, 0x3a, 0xc9, 0x2d, 0x62, + 0xf0, 0x2e, 0x44, 0xc3, 0x3b, 0xb9, 0x06, 0xd5, 0x0b, 0xb2, 0x2e, 0x1d, + 0xb4, 0x55, 0x3d, 0xfd, 0xaf, 0x53, 0xe9, 0xa0, 0x1d, 0xbb, 0x66, 0xa1, + 0x56, 0x99, 0xbd, 0xca, 0xb6, 0x82, 0x46, 0x3b, 0x89, 0x4d, 0x86, 0xc9, + 0x91, 0xc4, 0x47, 0xca, 0x6b, 0x28, 0x7e, 0x7a, 0xe3, 0x3a, 0xf6, 0x79, + 0x24, 0xd6, 0x36, 0xad, 0x36, 0x19, 0x87, 0x1e, 0xca, 0x25, 0x32, 0x04, + 0x50, 0xdb, 0x68, 0xaf, 0xf8, 0x30, 0xb5, 0xc0, 0x7b, 0x26, 0x8e, 0x17, + 0xba, 0xb9, 0x2e, 0xcd, 0x25, 0xbf, 0x52, 0xe9, 0x87, 0x1d, 0x1c, 0x5f, + 0xfc, 0x3b, 0x0d, 0x77, 0x2d, 0x3b, 0xc9, 0x89, 0xfe, 0xb5, 0x35, 0x3c, + 0xc8, 0x31, 0x64, 0x1d, 0x2b, 0xca, 0x7e, 0x19, 0xbe, 0x67, 0x3a, 0x8d, + 0xf7, 0x9c, 0x1c, 0x5a, 0xf6, 0xe1, 0x61, 0xa5, 0x93, 0x6b, 0x09, 0xbf, + 0x3b, 0xfe, 0xae, 0x69, 0xf8, 0x6b, 0x4c, 0xc4, 0xbc, 0xe4, 0x6d, 0x17, + 0x53, 0x09, 0x75, 0x52, 0xe9, 0xe6, 0x58, 0x8c, 0x2d, 0x62, 0x7d, 0x35, + 0xfd, 0xa6, 0x83, 0xfa, 0x76, 0x51, 0xdf, 0x2e, 0x67, 0x4e, 0xf1, 0xbb, + 0x5f, 0x9d, 0x77, 0x4b, 0xe1, 0x1e, 0x47, 0xf7, 0x9d, 0x7c, 0x67, 0x0f, + 0x65, 0xdd, 0xc3, 0xe7, 0xb7, 0x58, 0xdf, 0xe7, 0x35, 0x91, 0x57, 0xe2, + 0xfa, 0xc6, 0x5c, 0x25, 0xb1, 0xfd, 0xdd, 0x12, 0x57, 0x40, 0xc6, 0x63, + 0x4a, 0xec, 0x0f, 0xa1, 0xa7, 0x05, 0x81, 0xa5, 0xe6, 0x50, 0xdb, 0xee, + 0x06, 0xe2, 0x14, 0x71, 0x32, 0x70, 0x9c, 0x1c, 0x99, 0xd8, 0x3b, 0xd7, + 0xaa, 0x60, 0xcc, 0xb8, 0x99, 0xf1, 0x67, 0x60, 0xa2, 0xa0, 0x75, 0xc6, + 0x78, 0xaf, 0x79, 0x52, 0xb8, 0xfb, 0x01, 0xb4, 0x93, 0xaf, 0x45, 0xcd, + 0x41, 0x44, 0xad, 0x78, 0x74, 0x42, 0xd1, 0x06, 0xb7, 0x40, 0xbb, 0x40, + 0xcc, 0x1f, 0x9e, 0x55, 0xb4, 0xa1, 0x3a, 0xaf, 0x96, 0x7e, 0xdb, 0xe1, + 0xcd, 0x07, 0xb0, 0xda, 0xe1, 0x66, 0x83, 0x48, 0x92, 0xa3, 0xee, 0xe4, + 0x98, 0xfb, 0x37, 0x29, 0xb8, 0x62, 0xfc, 0x94, 0xeb, 0xa4, 0xa5, 0x33, + 0x8a, 0x81, 0x2c, 0xe3, 0x3f, 0x7a, 0x5c, 0x38, 0xf8, 0x01, 0x72, 0x70, + 0x04, 0x42, 0x7c, 0x36, 0x3b, 0x19, 0x1f, 0x0e, 0x78, 0xb5, 0x24, 0xf9, + 0x77, 0x9a, 0x63, 0x1a, 0x05, 0xf2, 0x72, 0xce, 0x11, 0xbb, 0xaf, 0x34, + 0x66, 0xa2, 0x34, 0xa6, 0x9e, 0x07, 0xe3, 0x62, 0x02, 0xdb, 0x13, 0xcc, + 0x01, 0xc4, 0xb2, 0xa3, 0xc2, 0xf5, 0x39, 0x5e, 0xe5, 0x71, 0x83, 0xdf, + 0x87, 0x95, 0x3d, 0x12, 0x33, 0x95, 0x2e, 0x73, 0xab, 0xe5, 0x1c, 0x35, + 0xe6, 0x21, 0x2c, 0x38, 0x73, 0x0c, 0xc9, 0x1c, 0x43, 0x3f, 0x52, 0xb4, + 0xe4, 0x39, 0x45, 0x30, 0xb8, 0xa9, 0xef, 0x1c, 0x63, 0xe4, 0x88, 0xa2, + 0xb5, 0x1e, 0xa3, 0xfa, 0x41, 0x5d, 0xc6, 0x3f, 0x54, 0x9a, 0x67, 0x08, + 0x8d, 0x79, 0xc6, 0x5f, 0x21, 0xa0, 0x6c, 0xc9, 0xb5, 0x63, 0x6c, 0xb6, + 0x1d, 0xa3, 0x39, 0x05, 0xf7, 0x18, 0xcb, 0x70, 0xe9, 0x66, 0xa7, 0xfe, + 0xa8, 0x59, 0xa1, 0xd7, 0x61, 0x44, 0x45, 0xad, 0x47, 0xff, 0x3c, 0xf6, + 0x96, 0xb8, 0xfb, 0xf6, 0x13, 0x3d, 0xc4, 0x73, 0x1b, 0x1f, 0x30, 0x56, + 0xe2, 0x4b, 0x90, 0xf6, 0x9b, 0xad, 0xe4, 0xd9, 0x4b, 0xbd, 0x6e, 0x3c, + 0xff, 0x7d, 0xc0, 0x5d, 0x03, 0xb1, 0xff, 0x67, 0xef, 0xb5, 0xe3, 0xe9, + 0x5c, 0x05, 0x5a, 0xd7, 0xe3, 0xce, 0x28, 0x6a, 0x3c, 0xcc, 0x5d, 0xef, + 0xec, 0x56, 0x1e, 0xe6, 0x3d, 0xe7, 0xd9, 0xc0, 0x6f, 0x98, 0x1f, 0xb7, + 0xfd, 0x71, 0xa3, 0x5c, 0x97, 0x67, 0x6f, 0xbc, 0xae, 0x9a, 0xff, 0xf2, + 0xba, 0x82, 0x17, 0x08, 0x50, 0x5f, 0x67, 0xae, 0xc8, 0x67, 0x6d, 0x78, + 0x4d, 0x1f, 0x06, 0x27, 0x63, 0x38, 0xb0, 0x10, 0xc1, 0x42, 0x56, 0xeb, + 0xbf, 0xc4, 0xba, 0x60, 0x6f, 0x8b, 0x8e, 0x87, 0x16, 0xa2, 0x98, 0xcf, + 0xc2, 0x0e, 0x9a, 0x7a, 0x31, 0xa8, 0x24, 0xb1, 0x7f, 0xa1, 0x1e, 0xe7, + 0xb2, 0xfa, 0x85, 0x51, 0x25, 0x31, 0x5c, 0x47, 0x3e, 0xf1, 0xc8, 0x42, + 0x33, 0x1e, 0x5e, 0x08, 0xf0, 0x1d, 0x1b, 0x5d, 0xa9, 0x7a, 0x3e, 0xef, + 0xc1, 0xf3, 0x27, 0x6d, 0x5b, 0xf8, 0xd4, 0xe0, 0x02, 0x30, 0x3f, 0xc5, + 0x1c, 0x73, 0x86, 0xf9, 0xe6, 0x19, 0x60, 0xff, 0x33, 0x1e, 0xcc, 0x4e, + 0xd9, 0xd8, 0x6b, 0x8c, 0xd6, 0x79, 0xe8, 0xe4, 0xfd, 0xcc, 0x07, 0x7e, + 0xe6, 0xb6, 0x7b, 0x55, 0x17, 0xa7, 0x2f, 0x11, 0x87, 0x1e, 0x78, 0x26, + 0x89, 0x77, 0xb2, 0x19, 0x74, 0x91, 0x77, 0x0f, 0x53, 0x96, 0xb7, 0xb3, + 0xcc, 0x4f, 0x0b, 0x06, 0xde, 0xca, 0x06, 0x38, 0x4f, 0x33, 0x5e, 0xcb, + 0xca, 0x33, 0xf2, 0x6c, 0x08, 0x03, 0x94, 0xe5, 0xcd, 0x6c, 0x94, 0x73, + 0x46, 0xf0, 0x1d, 0x3e, 0x77, 0xff, 0x82, 0xce, 0x7c, 0x14, 0xe0, 0xbc, + 0x31, 0xbc, 0x91, 0x0d, 0x51, 0xd6, 0x08, 0x73, 0xd0, 0x00, 0xc6, 0xb2, + 0x4d, 0x17, 0xb6, 0x90, 0xb3, 0xb8, 0x39, 0x44, 0xae, 0x5d, 0xb6, 0xbb, + 0x9d, 0x98, 0x93, 0x79, 0xca, 0xf3, 0x0e, 0x60, 0x34, 0xfb, 0x9a, 0xb7, + 0x5c, 0x27, 0xbf, 0x30, 0xb5, 0xe8, 0x70, 0xba, 0xe7, 0x2d, 0xfe, 0x3d, + 0x0b, 0x9c, 0xb3, 0x32, 0x76, 0xad, 0x49, 0x0e, 0xcb, 0xdc, 0xf3, 0xc3, + 0x0d, 0xcd, 0x9c, 0x57, 0xef, 0x7f, 0x45, 0x91, 0x3a, 0xc6, 0x87, 0xd8, + 0x33, 0x62, 0x2f, 0xc6, 0xf1, 0x3c, 0xf0, 0x57, 0xe4, 0x95, 0x8d, 0x93, + 0x9a, 0xf8, 0x7d, 0x1f, 0xf9, 0x4a, 0x4f, 0x11, 0x0d, 0xc9, 0x87, 0x30, + 0x62, 0x57, 0x90, 0x77, 0xd7, 0x92, 0xaf, 0x2e, 0x34, 0x33, 0xff, 0x6c, + 0xb0, 0xed, 0xef, 0xb7, 0xc0, 0xf6, 0x98, 0xba, 0x51, 0xe7, 0x2d, 0x7e, + 0xbe, 0x06, 0xfa, 0x85, 0xb0, 0xa2, 0x17, 0x7f, 0x88, 0xc4, 0xd0, 0xab, + 0x10, 0xbb, 0x02, 0x6b, 0x16, 0x7c, 0x58, 0x4b, 0x7d, 0xb6, 0x4e, 0x72, + 0x6e, 0xf2, 0x8e, 0x04, 0x75, 0xba, 0x7d, 0x92, 0x5c, 0x4a, 0x0f, 0x61, + 0x35, 0x6d, 0x3c, 0x78, 0xca, 0xb6, 0x2b, 0x69, 0xe3, 0x46, 0xae, 0xcf, + 0x7d, 0x27, 0x6c, 0xbc, 0x62, 0xbc, 0x42, 0x9b, 0x2a, 0xe4, 0x83, 0x2d, + 0x7c, 0x27, 0xc2, 0xe7, 0x03, 0xd8, 0x3f, 0x29, 0x75, 0x50, 0x3d, 0x9f, + 0xb9, 0x88, 0x63, 0xd9, 0x24, 0x9a, 0x69, 0xbf, 0x18, 0xc7, 0x6c, 0xe2, + 0x3b, 0xb1, 0x05, 0x37, 0x97, 0xc4, 0x16, 0x7e, 0x1d, 0x0e, 0x00, 0xa7, + 0xa7, 0xb4, 0x89, 0x22, 0xb9, 0x74, 0x8d, 0x39, 0x02, 0xe6, 0x62, 0xbc, + 0x3d, 0xa3, 0xe0, 0xf8, 0x14, 0x6b, 0xb7, 0x0d, 0xb0, 0xab, 0xa8, 0xc7, + 0x5b, 0x33, 0xbf, 0x89, 0xe7, 0x4e, 0x52, 0xf7, 0x67, 0x23, 0xf8, 0x7a, + 0xd6, 0x87, 0x5b, 0x8e, 0x0b, 0x3f, 0xd3, 0x93, 0x07, 0x14, 0xa9, 0x75, + 0xa4, 0x06, 0x49, 0xc4, 0xfc, 0x8a, 0x07, 0x0d, 0xcf, 0xf9, 0xa0, 0x9f, + 0x8b, 0xc1, 0xdf, 0x10, 0x80, 0xde, 0xf0, 0xfb, 0xc4, 0x17, 0x0f, 0x2a, + 0x58, 0x97, 0x6e, 0xff, 0x4a, 0x92, 0xd7, 0x22, 0xbc, 0x86, 0xdf, 0xac, + 0x84, 0x77, 0xb9, 0x97, 0xf9, 0xb8, 0x42, 0x27, 0xb7, 0xf2, 0xd9, 0xb6, + 0x97, 0x78, 0xbf, 0xe7, 0xab, 0xb6, 0x1d, 0x5f, 0x2f, 0xcf, 0xab, 0x88, + 0x9f, 0xd3, 0xf9, 0x9c, 0x9b, 0x03, 0xaf, 0x73, 0x2b, 0x2f, 0x7d, 0x47, + 0xe2, 0xf3, 0x71, 0xb8, 0xf5, 0x90, 0xcb, 0xc1, 0x5f, 0x2a, 0x08, 0x4f, + 0x89, 0x39, 0x3a, 0x9c, 0x9d, 0x52, 0x88, 0x73, 0x26, 0x9f, 0xdd, 0x0c, + 0x6f, 0x4a, 0x9b, 0xc8, 0x70, 0xed, 0xf7, 0xaa, 0xad, 0x78, 0xc1, 0xf2, + 0xa3, 0x5a, 0x5f, 0x8e, 0x07, 0x7b, 0x54, 0xbc, 0x40, 0x8e, 0xcf, 0x75, + 0x4a, 0x16, 0x51, 0xc9, 0x5a, 0x8b, 0xe3, 0x79, 0xfe, 0x1a, 0xfa, 0x57, + 0x3c, 0xc4, 0x36, 0xaf, 0x83, 0x6d, 0x15, 0x0d, 0x40, 0x31, 0xef, 0xc3, + 0x79, 0xdd, 0xe5, 0x77, 0x2f, 0x39, 0x79, 0x58, 0x53, 0x8b, 0xd7, 0x78, + 0x9d, 0xd6, 0x9a, 0x56, 0x0e, 0x7b, 0x45, 0xce, 0x17, 0x0b, 0x3b, 0x7d, + 0xae, 0xff, 0x5c, 0xf4, 0x4a, 0xfd, 0x70, 0xfd, 0x7b, 0x15, 0x3c, 0xa6, + 0x16, 0x6d, 0xf7, 0x22, 0xe0, 0x33, 0x03, 0x6d, 0xe3, 0xfa, 0xe7, 0x6e, + 0x90, 0xbd, 0x19, 0x63, 0x85, 0xeb, 0x75, 0x73, 0x67, 0xd6, 0xf1, 0x9b, + 0x4e, 0xb1, 0xfd, 0x53, 0x86, 0x60, 0xeb, 0xb0, 0xd2, 0x41, 0xac, 0xca, + 0xf8, 0xdc, 0xba, 0xf8, 0x08, 0xeb, 0xe2, 0xd7, 0xb3, 0xd2, 0x1b, 0x39, + 0x84, 0x7d, 0x0e, 0xce, 0x0e, 0x09, 0xce, 0xc6, 0xce, 0x42, 0x1b, 0x1c, + 0x28, 0xe1, 0xec, 0x9c, 0x8b, 0xb3, 0xfd, 0x2e, 0xce, 0x1e, 0x2a, 0xe1, + 0xec, 0x10, 0x9a, 0xf3, 0x11, 0x72, 0xe0, 0x0e, 0xe6, 0xda, 0x6e, 0x72, + 0x0e, 0xc9, 0x91, 0x7d, 0xca, 0xce, 0xf9, 0x80, 0xb2, 0x2d, 0x17, 0xc0, + 0xeb, 0xe4, 0x53, 0x33, 0xbd, 0x50, 0x6f, 0xd9, 0x80, 0xe0, 0xce, 0x5c, + 0x0f, 0x2a, 0x75, 0xa9, 0x03, 0x2b, 0xb1, 0xdd, 0xc9, 0x55, 0x52, 0x2f, + 0x49, 0x2f, 0xa0, 0x97, 0x58, 0x07, 0x35, 0x68, 0xba, 0x75, 0xbf, 0xe0, + 0xde, 0xed, 0x7c, 0xf7, 0x2c, 0xfd, 0x10, 0x6e, 0x4e, 0x53, 0xee, 0x60, + 0x3d, 0xf0, 0x61, 0x4a, 0x41, 0xf1, 0xce, 0x00, 0x38, 0x16, 0xf5, 0x3d, + 0xd0, 0x36, 0x3e, 0xd5, 0xa3, 0x74, 0xcc, 0xce, 0x05, 0x99, 0xb7, 0x99, + 0x93, 0x66, 0x82, 0x6e, 0xae, 0xfe, 0xec, 0x58, 0xd2, 0x73, 0x49, 0xb6, + 0x6d, 0x22, 0xc7, 0x69, 0x5d, 0xff, 0x8f, 0x36, 0x7e, 0x47, 0xde, 0xff, + 0xcf, 0x25, 0xfb, 0xa5, 0x29, 0x4f, 0x24, 0xb0, 0xbd, 0xa0, 0x06, 0xd2, + 0x85, 0x0e, 0xbe, 0xdf, 0xc3, 0xb1, 0x7a, 0x83, 0x1d, 0xd6, 0xdd, 0xc1, + 0xad, 0x56, 0x77, 0x70, 0x9b, 0xc5, 0xd8, 0x2d, 0xf4, 0xd2, 0x8e, 0x3d, + 0xac, 0xe1, 0xef, 0x26, 0x7f, 0x90, 0x31, 0xfb, 0xc9, 0x65, 0x82, 0xd4, + 0x6d, 0x84, 0xba, 0x15, 0xa3, 0x7e, 0xa4, 0x35, 0x3f, 0x34, 0x75, 0xcc, + 0x59, 0xb7, 0x09, 0xa7, 0x8f, 0x54, 0x65, 0xae, 0x6e, 0xeb, 0x3a, 0x41, + 0x4c, 0x37, 0x1b, 0xda, 0x6e, 0x39, 0x85, 0x25, 0x7e, 0x53, 0xea, 0x5e, + 0xd6, 0xb2, 0x89, 0x84, 0xf1, 0x3e, 0x12, 0xd1, 0xd7, 0xf9, 0xec, 0x28, + 0x7d, 0x75, 0xcc, 0xe9, 0x1d, 0x70, 0x01, 0xf2, 0xcd, 0xe8, 0xb2, 0x02, + 0xc1, 0xdb, 0x59, 0x57, 0x85, 0x4d, 0xad, 0x75, 0x97, 0x57, 0x7a, 0x19, + 0xc5, 0xdf, 0x0e, 0xa1, 0x19, 0x9d, 0x85, 0x40, 0x70, 0xcb, 0xf4, 0xe7, + 0xf0, 0x0f, 0x27, 0x99, 0xbb, 0x20, 0x7e, 0x67, 0xdb, 0xf7, 0xb3, 0x26, + 0x39, 0x9a, 0xaf, 0xc7, 0x15, 0x67, 0x4d, 0x7d, 0x38, 0x92, 0x8f, 0xe1, + 0x32, 0xf1, 0xc9, 0xb7, 0x50, 0x87, 0x77, 0xa7, 0xbc, 0xd8, 0x67, 0xdc, + 0x56, 0xca, 0x09, 0x1e, 0xdc, 0x9b, 0x3c, 0x48, 0x1e, 0xe0, 0x41, 0x2d, + 0x39, 0xd8, 0x23, 0xce, 0x35, 0x2f, 0x6b, 0xb7, 0x2f, 0x62, 0xd8, 0xcd, + 0x19, 0x94, 0xb1, 0x9e, 0x32, 0xb6, 0x04, 0xb7, 0xe4, 0xb4, 0xe0, 0x1d, + 0x39, 0x04, 0xfc, 0xe6, 0xca, 0xb6, 0x33, 0x27, 0x6d, 0x0c, 0x18, 0xab, + 0xf0, 0xe1, 0xc9, 0xd1, 0x41, 0x1f, 0xfd, 0xe5, 0x27, 0xa9, 0x3e, 0x58, + 0xd3, 0x38, 0x4f, 0x26, 0x71, 0x31, 0x44, 0xfc, 0x6e, 0x24, 0x67, 0xa0, + 0x1f, 0x18, 0xf3, 0x8c, 0xc5, 0x6d, 0xf4, 0x0f, 0xfa, 0x43, 0xda, 0x6b, + 0x26, 0xfa, 0xc7, 0x48, 0x00, 0x6b, 0x28, 0x4f, 0x90, 0xf8, 0x1c, 0x5a, + 0x88, 0x05, 0xf7, 0x30, 0xa7, 0x44, 0x59, 0x9b, 0x05, 0x13, 0xb8, 0xad, + 0x0e, 0x89, 0xe4, 0x22, 0xf5, 0xf6, 0x2f, 0x34, 0x07, 0x77, 0x31, 0x47, + 0x5c, 0x49, 0xd8, 0x23, 0xaf, 0x18, 0x21, 0x84, 0x17, 0x0c, 0xda, 0xbb, + 0x0f, 0xa3, 0xf3, 0x2c, 0x97, 0x12, 0xac, 0xd7, 0x17, 0x5a, 0x83, 0xb7, + 0x33, 0x16, 0x6b, 0x88, 0x53, 0x4d, 0x0b, 0xe9, 0xa0, 0xd4, 0x6b, 0xcd, + 0x0b, 0x1b, 0x29, 0x9f, 0xac, 0x63, 0x73, 0xdb, 0x26, 0xfa, 0x41, 0x6c, + 0x01, 0xdb, 0x09, 0x65, 0xaf, 0x71, 0xcc, 0xbe, 0x28, 0x79, 0xe8, 0xfe, + 0x0d, 0x21, 0x62, 0x91, 0xd8, 0x92, 0x76, 0x2c, 0x94, 0x75, 0x92, 0xdc, + 0xdb, 0xd0, 0xb6, 0x70, 0x4a, 0x72, 0x6f, 0xb4, 0x2d, 0x7b, 0x4a, 0xc7, + 0x65, 0xe6, 0x8f, 0x35, 0x29, 0xcd, 0x38, 0xa7, 0xc4, 0xa3, 0x17, 0xa9, + 0x8b, 0x0f, 0x3f, 0xb3, 0xf7, 0xea, 0x89, 0xe2, 0x4a, 0xc6, 0x4f, 0x2d, + 0xf1, 0x2f, 0x4a, 0x5c, 0xaf, 0x5d, 0xa0, 0x61, 0x16, 0x7e, 0x46, 0xff, + 0x88, 0x22, 0x90, 0xd0, 0xf1, 0xde, 0xc9, 0x24, 0xed, 0x70, 0x6d, 0xcc, + 0x03, 0xa4, 0x50, 0x03, 0x4c, 0x77, 0x4f, 0x3c, 0x47, 0x1f, 0x1c, 0xe7, + 0xbc, 0x15, 0x0b, 0x22, 0xb3, 0x3c, 0x1f, 0xe1, 0xf3, 0xd7, 0xe7, 0xae, + 0xe5, 0xdc, 0x1f, 0x9d, 0x92, 0xfe, 0x52, 0xb4, 0xed, 0xfc, 0x49, 0x77, + 0xee, 0x44, 0x2a, 0x89, 0x9f, 0x9e, 0xd4, 0x86, 0xde, 0x53, 0xe2, 0xfd, + 0xe7, 0x15, 0x99, 0x1f, 0xf5, 0x35, 0xf8, 0xd0, 0x1e, 0x4d, 0x24, 0x86, + 0xf7, 0x72, 0xcc, 0xd6, 0x8d, 0xb4, 0xbf, 0x23, 0x07, 0x13, 0x3b, 0xb1, + 0xd4, 0x4f, 0x79, 0x5c, 0x59, 0xea, 0x39, 0xf6, 0xc9, 0x52, 0x9d, 0xc5, + 0x1a, 0xf3, 0xba, 0x3c, 0x11, 0xda, 0x21, 0xb0, 0xa7, 0x25, 0x84, 0x3a, + 0xe7, 0x39, 0x95, 0xcf, 0x89, 0x1d, 0x7e, 0xae, 0x78, 0xf4, 0xf7, 0x89, + 0x5b, 0x82, 0x1d, 0x11, 0x62, 0xd6, 0xdd, 0x52, 0x8f, 0x66, 0x32, 0xf4, + 0x77, 0x3f, 0xfd, 0x7d, 0xab, 0xf8, 0xb4, 0x45, 0x9f, 0xb6, 0xe8, 0xd3, + 0x96, 0x16, 0x1d, 0x42, 0x5c, 0x1d, 0xe0, 0xba, 0xa5, 0xa3, 0xe2, 0xeb, + 0xbd, 0xd8, 0xc7, 0xdf, 0xfb, 0x78, 0xff, 0x08, 0x6b, 0x54, 0x2c, 0x95, + 0x39, 0x0f, 0xa1, 0xc3, 0x7a, 0x02, 0x83, 0x39, 0xfc, 0x22, 0xd8, 0x52, + 0x89, 0xca, 0xd5, 0x52, 0x7f, 0x6b, 0xea, 0x51, 0x3c, 0xc1, 0x1a, 0xe8, + 0xe7, 0x4a, 0xb5, 0xee, 0xeb, 0x39, 0xa6, 0x68, 0x6a, 0x07, 0x6b, 0xd9, + 0xbd, 0x85, 0xbb, 0xb9, 0xbe, 0xf1, 0xc1, 0xd7, 0x15, 0xd6, 0x41, 0x75, + 0x9c, 0x9b, 0xb1, 0x74, 0x07, 0xe7, 0xb1, 0x44, 0x0e, 0x07, 0x5f, 0x7f, + 0x0f, 0x62, 0xdb, 0x6f, 0x37, 0x0e, 0x70, 0x7e, 0x57, 0x8e, 0x51, 0xd6, + 0x83, 0x03, 0x8c, 0xb1, 0x7d, 0x4e, 0x7c, 0xf5, 0x72, 0x8c, 0xeb, 0xb8, + 0xb5, 0x25, 0x2b, 0xf9, 0xd2, 0xc6, 0x93, 0x86, 0x8d, 0xe7, 0xf9, 0x7b, + 0x81, 0xd8, 0x35, 0x76, 0x03, 0x76, 0x79, 0xf8, 0xdc, 0x1e, 0x3e, 0xd7, + 0x4a, 0xdc, 0x9e, 0x9f, 0x95, 0xbe, 0xde, 0x21, 0xe9, 0xeb, 0x21, 0x6f, + 0x89, 0xed, 0x87, 0x70, 0x3e, 0x1b, 0x1f, 0xf6, 0x7a, 0xed, 0x11, 0xc6, + 0xd5, 0x85, 0x8f, 0xe8, 0xbb, 0x6f, 0x6e, 0xd0, 0x7a, 0x68, 0xc3, 0xe4, + 0xa4, 0xa2, 0x45, 0xbf, 0x8b, 0xe2, 0xf6, 0x00, 0x9a, 0x62, 0x6b, 0xbd, + 0x09, 0x95, 0x38, 0x57, 0x1c, 0xa0, 0xa6, 0xcf, 0x16, 0x5c, 0x6c, 0xdb, + 0x54, 0xc2, 0xb6, 0xd6, 0x7c, 0x15, 0xb1, 0x87, 0x39, 0x78, 0xd6, 0xce, + 0x84, 0x99, 0x9f, 0x0a, 0xb3, 0x32, 0xf6, 0x08, 0x9a, 0x52, 0x32, 0x96, + 0xde, 0x39, 0xa9, 0xe0, 0x4b, 0xd5, 0x48, 0x30, 0x37, 0xc1, 0xa8, 0xd4, + 0x33, 0x36, 0x73, 0x90, 0xea, 0x37, 0x25, 0x3f, 0x76, 0x13, 0x0f, 0x7b, + 0x89, 0x87, 0xc2, 0x99, 0xa5, 0xd7, 0xe9, 0xe2, 0xd1, 0xd6, 0x82, 0xac, + 0x8b, 0xac, 0x89, 0xac, 0xcd, 0x21, 0xdc, 0x6b, 0x49, 0xdd, 0x6e, 0x63, + 0xca, 0x48, 0xc4, 0x9e, 0x83, 0xac, 0xd3, 0x21, 0xda, 0xc2, 0x8f, 0x7d, + 0xc4, 0xbf, 0xbd, 0x2d, 0xb4, 0x55, 0xd8, 0x8f, 0xbd, 0x4e, 0x1f, 0xa0, + 0x6c, 0x3f, 0x3f, 0xd7, 0x50, 0x61, 0x4e, 0xfb, 0xaa, 0xdf, 0xb5, 0xa3, + 0xdb, 0x57, 0xf4, 0x9a, 0x32, 0x5e, 0xb9, 0xa7, 0xe8, 0xda, 0x6e, 0x7b, + 0x56, 0xc6, 0xb5, 0x71, 0xd6, 0x70, 0xb9, 0x69, 0xd9, 0x66, 0x82, 0xed, + 0x4b, 0x36, 0x02, 0x6b, 0x6f, 0xe0, 0xa7, 0x55, 0xbc, 0xd6, 0x75, 0x9d, + 0x9f, 0xf6, 0x09, 0x07, 0x26, 0x3f, 0xed, 0xdc, 0x49, 0x7e, 0xda, 0xa0, + 0x94, 0xb9, 0xa9, 0xf4, 0x14, 0xca, 0xfc, 0xb4, 0xb6, 0x84, 0xcd, 0x87, + 0xb0, 0x97, 0xdc, 0xa5, 0xae, 0x61, 0x04, 0x81, 0x75, 0x9e, 0x4f, 0x3d, + 0x18, 0x61, 0xed, 0x51, 0x01, 0x2c, 0xb3, 0xb1, 0x72, 0x7d, 0xc6, 0xae, + 0xd4, 0x1b, 0x62, 0x95, 0x1e, 0xe9, 0x19, 0x27, 0x32, 0x63, 0xc4, 0x12, + 0xcf, 0x3a, 0x2d, 0x93, 0x46, 0x40, 0x5d, 0xa2, 0xdf, 0x5d, 0xaa, 0x09, + 0xa2, 0x81, 0x1d, 0xe4, 0x36, 0x89, 0xd4, 0x2f, 0xed, 0x99, 0xc8, 0x08, + 0xa2, 0xeb, 0x8a, 0xc3, 0x51, 0xa4, 0x0f, 0x46, 0x1d, 0x5c, 0x99, 0x40, + 0x3e, 0x11, 0x0d, 0x74, 0x17, 0x32, 0xc1, 0xae, 0xc6, 0x18, 0x76, 0x4e, + 0x76, 0xb0, 0xe6, 0xd0, 0xb1, 0x6d, 0xb2, 0x93, 0xf5, 0x51, 0x8f, 0xd2, + 0x33, 0x2b, 0xf6, 0x11, 0xfb, 0x6a, 0x6a, 0xcc, 0x73, 0x63, 0x2f, 0xb3, + 0x5c, 0xcf, 0xbe, 0xef, 0xf8, 0xce, 0xb8, 0xa1, 0xd2, 0x2e, 0xff, 0xdb, + 0x8f, 0xb0, 0x8d, 0x33, 0x86, 0xf8, 0x1c, 0xbf, 0xb3, 0xb6, 0xda, 0xda, + 0x32, 0x65, 0xfb, 0x74, 0xe9, 0x49, 0x47, 0x9d, 0xf5, 0x92, 0x1a, 0xab, + 0x63, 0xb6, 0x97, 0x6b, 0x54, 0xee, 0x3f, 0xdf, 0xb8, 0x56, 0x9b, 0x83, + 0x5b, 0x89, 0x67, 0xac, 0xc7, 0x02, 0x01, 0x62, 0x64, 0xe0, 0x94, 0x8d, + 0x59, 0xe3, 0x1d, 0xfb, 0x49, 0xdd, 0xc7, 0xf5, 0xb8, 0x95, 0x78, 0x2b, + 0xfc, 0xc3, 0x0c, 0xee, 0x9a, 0xf6, 0x79, 0x58, 0x5b, 0xb5, 0x54, 0xc0, + 0xa9, 0xad, 0x9c, 0x3e, 0xe1, 0xb1, 0xfc, 0x6d, 0xc1, 0xae, 0x1c, 0xeb, + 0x04, 0xd6, 0xa9, 0x6e, 0x8d, 0x76, 0x6b, 0xf0, 0x9e, 0x9c, 0x57, 0xa9, + 0x33, 0xe1, 0x6d, 0xdd, 0x68, 0xe3, 0xe3, 0xf5, 0x89, 0xe1, 0xa8, 0x87, + 0xd8, 0xc8, 0xb1, 0xac, 0x7c, 0x4b, 0xb0, 0x8f, 0x58, 0x7c, 0x7b, 0x0e, + 0x69, 0xe9, 0xa9, 0x86, 0xd7, 0x8f, 0xf6, 0x87, 0x21, 0xfd, 0x2f, 0x7c, + 0x89, 0xd1, 0x18, 0xa1, 0xaf, 0x45, 0xdb, 0x95, 0xc4, 0xe2, 0x20, 0x12, + 0x17, 0x3e, 0xf6, 0xbe, 0x63, 0x3f, 0x9d, 0xdf, 0xc8, 0xe7, 0x3b, 0x89, + 0x93, 0x69, 0xe2, 0xe6, 0xe8, 0xb0, 0x1f, 0xf2, 0x8e, 0xd6, 0xf7, 0xb6, + 0x12, 0xa7, 0x8f, 0xe3, 0x77, 0xf8, 0xbc, 0xba, 0x8d, 0x18, 0x39, 0x6b, + 0x24, 0xd2, 0x5b, 0x90, 0xe9, 0xac, 0x85, 0x66, 0x34, 0x2a, 0xd2, 0xaf, + 0x12, 0xfb, 0x27, 0xf1, 0x3d, 0xce, 0xe9, 0xd3, 0xc5, 0x8e, 0x9b, 0x31, + 0x30, 0xab, 0xa9, 0xd7, 0xfd, 0x4c, 0x6c, 0x20, 0x76, 0xe9, 0xa8, 0x40, + 0xd5, 0x52, 0xea, 0xf6, 0x3d, 0x07, 0x4f, 0x82, 0xba, 0x8e, 0xff, 0x42, + 0x1e, 0xf4, 0x17, 0x05, 0xe9, 0x4b, 0x96, 0xb9, 0x9d, 0xf8, 0x44, 0x73, + 0xdb, 0x2d, 0x33, 0xc9, 0x52, 0x9f, 0x32, 0x10, 0xec, 0x9c, 0xb6, 0x71, + 0xd2, 0x08, 0x43, 0xea, 0xf3, 0xca, 0x54, 0x91, 0x19, 0xbf, 0x19, 0xdb, + 0x78, 0xbd, 0x63, 0xba, 0x5a, 0xe9, 0xc8, 0xd9, 0xf8, 0xa6, 0xa1, 0x65, + 0xda, 0xbd, 0x8c, 0x65, 0x43, 0x3b, 0x0b, 0x5c, 0x26, 0x27, 0x12, 0xdf, + 0xf2, 0x21, 0xa4, 0xbb, 0x63, 0x35, 0xcf, 0xdc, 0x46, 0xbe, 0x20, 0xb1, + 0xe5, 0x5d, 0x53, 0x85, 0x94, 0x32, 0xe3, 0x13, 0xbb, 0x75, 0x22, 0x5d, + 0xa8, 0x56, 0x76, 0xd3, 0x96, 0x77, 0xac, 0xab, 0xc0, 0x25, 0xc7, 0x96, + 0xb7, 0xd1, 0x96, 0x78, 0x6b, 0x05, 0xbc, 0xe7, 0xeb, 0xd0, 0xa9, 0xc0, + 0xa9, 0xbd, 0xaa, 0x99, 0x9f, 0xd3, 0xe4, 0xae, 0xe4, 0x7d, 0x6a, 0x2f, + 0xbe, 0x42, 0x9c, 0x79, 0x92, 0x3e, 0xfa, 0x33, 0xbd, 0x19, 0x55, 0x5f, + 0x6d, 0xe1, 0x3a, 0x6e, 0x0c, 0xee, 0xc8, 0xf5, 0xe1, 0xa9, 0x79, 0x1b, + 0xcf, 0x31, 0x3e, 0x1a, 0x53, 0x19, 0xb5, 0x92, 0xb5, 0x18, 0x73, 0xd9, + 0xe2, 0x09, 0xc7, 0xbf, 0x57, 0xb6, 0x6d, 0x9e, 0x8b, 0xc2, 0xfb, 0x15, + 0xf9, 0xbb, 0xbe, 0x2d, 0x36, 0x27, 0x9f, 0x51, 0x7e, 0xda, 0x18, 0x32, + 0xb4, 0xf4, 0xc7, 0xde, 0x2a, 0x54, 0x27, 0x6c, 0x7b, 0x28, 0x25, 0xd7, + 0xf5, 0xb6, 0xa4, 0x73, 0xbf, 0x81, 0x9f, 0xe5, 0x3e, 0xf2, 0xeb, 0xc2, + 0xf9, 0x62, 0x69, 0xea, 0xbc, 0x93, 0x79, 0xbd, 0x8f, 0x79, 0xbd, 0xce, + 0xd4, 0xd2, 0x7b, 0xbc, 0xd2, 0x3b, 0x29, 0x1e, 0xac, 0xe5, 0xf5, 0x5d, + 0xa5, 0xbc, 0x5e, 0x73, 0x4a, 0xfa, 0x70, 0xe4, 0x7a, 0x70, 0xf7, 0x2f, + 0xba, 0x99, 0xd7, 0xab, 0x26, 0x7d, 0xe8, 0x62, 0x4e, 0xf7, 0x93, 0x67, + 0x6f, 0xcd, 0xd7, 0x21, 0x78, 0xc2, 0x8b, 0x78, 0xea, 0xdb, 0x38, 0x48, + 0x1f, 0x3b, 0x98, 0xf4, 0x2a, 0xb1, 0xe5, 0x1e, 0xda, 0xe9, 0x9f, 0x70, + 0x40, 0xf5, 0xa2, 0x46, 0xff, 0x2e, 0x1e, 0xfa, 0x35, 0xb9, 0xbc, 0x2f, + 0x27, 0x31, 0xbd, 0xb2, 0xad, 0xeb, 0x94, 0x9b, 0xcb, 0x43, 0xa7, 0x46, + 0x17, 0x25, 0x97, 0xd7, 0xad, 0xef, 0xc3, 0xe9, 0x69, 0xfc, 0xe1, 0x0a, + 0x92, 0xc4, 0x3a, 0xce, 0xd9, 0x90, 0x4a, 0xb0, 0x6e, 0xd6, 0x06, 0xb7, + 0x29, 0x89, 0x89, 0x1a, 0xc6, 0xfe, 0x69, 0xe6, 0xf2, 0x80, 0x99, 0x50, + 0x93, 0x1e, 0x74, 0xfb, 0xb9, 0x1e, 0x1f, 0xb0, 0x86, 0xfe, 0x61, 0x3e, + 0xc6, 0x31, 0x2b, 0xe0, 0x63, 0x2e, 0xff, 0x40, 0xc7, 0xa7, 0x5e, 0xfa, + 0xde, 0x65, 0x6f, 0x00, 0x57, 0xf3, 0x6e, 0x2e, 0xaf, 0x6d, 0xb4, 0x47, + 0xae, 0xa4, 0x42, 0xf8, 0x30, 0x6f, 0xd0, 0x07, 0xfb, 0x70, 0x84, 0xb9, + 0xfc, 0x8a, 0xae, 0xe2, 0xa7, 0xf9, 0x56, 0xfa, 0x65, 0x04, 0x3f, 0x21, + 0xcf, 0x5d, 0xc7, 0x5c, 0x7e, 0x27, 0x7d, 0x2a, 0xc5, 0x5c, 0xde, 0xee, + 0xf0, 0x8c, 0xe6, 0xb6, 0x33, 0x53, 0x4e, 0x2e, 0x6f, 0x64, 0x89, 0x5f, + 0xef, 0x47, 0x62, 0x91, 0xf8, 0x60, 0xff, 0x6c, 0x63, 0x88, 0xcf, 0xd2, + 0x6e, 0x85, 0xf5, 0x98, 0x71, 0x72, 0xcf, 0xe6, 0xe0, 0x6e, 0xce, 0xbd, + 0xcc, 0x89, 0x33, 0x1b, 0x3b, 0xd7, 0xbd, 0x89, 0x3f, 0x58, 0xe2, 0xa1, + 0x1f, 0x9a, 0xc1, 0x3b, 0x18, 0x6b, 0x61, 0xfa, 0xd7, 0x4f, 0x53, 0x89, + 0xfe, 0x73, 0xac, 0x21, 0x7f, 0xc2, 0x38, 0xbb, 0x93, 0xbe, 0xb1, 0x72, + 0x5d, 0x80, 0xeb, 0xee, 0xc6, 0x59, 0x07, 0xe3, 0x2c, 0xca, 0x38, 0x5b, + 0xc1, 0x38, 0x7b, 0xda, 0x48, 0x24, 0x37, 0x93, 0x6f, 0xbd, 0x9e, 0x97, + 0x58, 0x6b, 0xe1, 0xb8, 0x1a, 0xf5, 0x1a, 0xed, 0x97, 0x98, 0xd9, 0xb9, + 0x6e, 0xf4, 0x6c, 0x35, 0xc4, 0x56, 0xf8, 0x74, 0x19, 0xb9, 0x05, 0x11, + 0xe9, 0xc2, 0xa2, 0x37, 0x31, 0xbc, 0xca, 0x9b, 0x18, 0x7a, 0x5f, 0x79, + 0xc7, 0x7e, 0x8b, 0x71, 0x76, 0x3b, 0xe3, 0x6c, 0x37, 0xe3, 0xac, 0xdd, + 0xb2, 0xf1, 0x52, 0x4a, 0xeb, 0x6b, 0xf6, 0xc4, 0x8d, 0x76, 0x0f, 0x56, + 0x54, 0x33, 0x25, 0x04, 0x91, 0xe8, 0xfc, 0x03, 0xca, 0x7f, 0xc1, 0x48, + 0xf4, 0x24, 0x15, 0x89, 0xad, 0x18, 0x7e, 0x4c, 0xbd, 0x2b, 0x4b, 0xb1, + 0xb5, 0x7f, 0xf6, 0xd5, 0x92, 0x6f, 0x94, 0x75, 0xf7, 0xe2, 0x45, 0x83, + 0x18, 0xba, 0x54, 0x8b, 0x65, 0x3c, 0xbd, 0x98, 0xa0, 0x1d, 0x83, 0x89, + 0x5e, 0x1c, 0x65, 0x1e, 0xbc, 0x9f, 0xf9, 0xf7, 0x01, 0x2b, 0xde, 0xba, + 0x83, 0x75, 0xce, 0xa5, 0xa8, 0x16, 0x8b, 0x29, 0xbd, 0x18, 0xa0, 0x0f, + 0x0f, 0x30, 0x5f, 0xb4, 0x5b, 0x3f, 0x57, 0xb6, 0x91, 0x23, 0xdc, 0x57, + 0x90, 0xf7, 0xb4, 0x64, 0xbf, 0x67, 0x10, 0xfd, 0xf3, 0x82, 0x6d, 0x50, + 0x6f, 0x32, 0x7b, 0x71, 0xdc, 0xaa, 0x40, 0x6f, 0x4b, 0xb7, 0xb2, 0xab, + 0x20, 0xbd, 0x33, 0xc6, 0xa3, 0xc5, 0x78, 0x75, 0xe4, 0x55, 0x88, 0xa5, + 0xdd, 0xc8, 0x4a, 0x7c, 0x5a, 0xbb, 0x95, 0x3b, 0x67, 0x25, 0xc6, 0x7b, + 0x95, 0x5e, 0x89, 0x61, 0x6b, 0x58, 0xb9, 0x4b, 0x62, 0xda, 0xe9, 0x33, + 0x4b, 0xdc, 0xcb, 0x3e, 0xc4, 0x6d, 0xe4, 0x6f, 0x60, 0x4c, 0x79, 0xbf, + 0x1a, 0x65, 0xdc, 0xb5, 0x57, 0x78, 0xe8, 0xa7, 0x71, 0xae, 0x9d, 0x07, + 0x1d, 0xc6, 0x6f, 0xda, 0x19, 0xb5, 0x9f, 0x31, 0xd5, 0x8b, 0x23, 0xd6, + 0x6f, 0xd8, 0x57, 0x1c, 0x5e, 0x52, 0xc6, 0xf3, 0xcd, 0xb8, 0x37, 0xb7, + 0x1c, 0x01, 0x5d, 0xf2, 0x75, 0x08, 0xc9, 0x25, 0x01, 0x54, 0xe9, 0x92, + 0x67, 0x9a, 0xdb, 0x16, 0x4e, 0x50, 0x86, 0x0d, 0xe5, 0xf8, 0xde, 0x8c, + 0x07, 0x89, 0x03, 0xfb, 0x52, 0xf7, 0xe2, 0x01, 0xb5, 0x0a, 0x61, 0xda, + 0xe9, 0x61, 0x35, 0x44, 0x7c, 0xfd, 0xbd, 0xd2, 0x38, 0xff, 0xa9, 0xa2, + 0x54, 0x33, 0x5f, 0xe3, 0x54, 0x75, 0x8c, 0xb1, 0x4d, 0xd3, 0x52, 0x9b, + 0x44, 0xdb, 0xa2, 0xd3, 0x3a, 0xc2, 0xac, 0x55, 0x37, 0xa7, 0xb4, 0xe1, + 0xcd, 0xde, 0xf8, 0xe0, 0xa2, 0x82, 0x6c, 0x98, 0x7c, 0x2e, 0x9f, 0x48, + 0xf4, 0x34, 0x8b, 0x8d, 0xf5, 0x28, 0xb6, 0xd3, 0x4e, 0x5d, 0xf9, 0x08, + 0x63, 0xe8, 0xbd, 0x0a, 0xe1, 0x46, 0xe9, 0xfc, 0xf5, 0xb1, 0xa2, 0x1c, + 0x2b, 0x3a, 0x2d, 0x3c, 0x2d, 0x4a, 0x9e, 0xa6, 0x33, 0x0e, 0x6d, 0x7b, + 0x13, 0xf9, 0x59, 0xe8, 0x94, 0xd4, 0x38, 0xf1, 0x09, 0x72, 0xda, 0x66, + 0xf2, 0xdd, 0x5e, 0x7a, 0xb5, 0xbd, 0xb2, 0x21, 0x61, 0xb4, 0x2b, 0x78, + 0x62, 0xae, 0x85, 0xf5, 0x11, 0xc7, 0xbc, 0x9c, 0x57, 0x71, 0x25, 0x1f, + 0xc5, 0xbb, 0x1c, 0xfb, 0x92, 0x33, 0x76, 0x3d, 0x7e, 0x54, 0xc2, 0xad, + 0x14, 0x71, 0x6b, 0x4b, 0x4e, 0xa1, 0xbf, 0xc6, 0x30, 0x62, 0xfc, 0xdd, + 0xa7, 0x97, 0x6e, 0x0e, 0xd0, 0x6e, 0xa2, 0x8b, 0x8f, 0x9f, 0xe3, 0x78, + 0xd8, 0xc1, 0xe9, 0x37, 0x3f, 0x9d, 0x59, 0xc2, 0xb5, 0xa2, 0xed, 0x6b, + 0x4b, 0xef, 0xad, 0x9d, 0xf9, 0xf3, 0x92, 0xbe, 0x3a, 0x3c, 0xa7, 0x92, + 0xa8, 0x38, 0x75, 0x4d, 0x56, 0x5d, 0xe2, 0x83, 0x19, 0xf5, 0x89, 0xaf, + 0x71, 0xfe, 0xc7, 0xc8, 0xf5, 0x6c, 0xce, 0x7f, 0xd5, 0x99, 0x37, 0xc2, + 0x79, 0x95, 0x6b, 0xbc, 0x30, 0x7a, 0xed, 0x1d, 0x95, 0xba, 0xe3, 0xf1, + 0x28, 0x6d, 0xf7, 0xe1, 0x06, 0x79, 0x2e, 0x84, 0x5d, 0xf9, 0x15, 0x95, + 0x82, 0xe3, 0x41, 0xd6, 0x01, 0xae, 0x2f, 0x91, 0xe7, 0x59, 0xcf, 0xf1, + 0x9e, 0xf0, 0xae, 0xcd, 0xe4, 0x18, 0x9f, 0xb5, 0x7b, 0x84, 0x6b, 0xf1, + 0x7f, 0xf8, 0x8e, 0xdc, 0xfb, 0x75, 0x79, 0xf4, 0x4f, 0x31, 0xcc, 0x1a, + 0xe8, 0xb1, 0x5c, 0x06, 0x0f, 0xe7, 0xbe, 0xec, 0xec, 0xab, 0xad, 0x5d, + 0x8f, 0xfb, 0x38, 0xe7, 0x81, 0x5a, 0xc6, 0xd1, 0x7f, 0x4b, 0x25, 0x84, + 0x1b, 0xed, 0xae, 0x86, 0xe4, 0xda, 0x44, 0xeb, 0x2a, 0xc5, 0x46, 0x45, + 0x0a, 0x43, 0x1d, 0x2d, 0x89, 0xe4, 0x15, 0x3c, 0x61, 0x4b, 0x5f, 0xd3, + 0x5b, 0xca, 0xbb, 0x52, 0xff, 0x49, 0x6f, 0xb5, 0xbd, 0xc4, 0x91, 0xb6, + 0x14, 0xde, 0xf9, 0x4c, 0xef, 0x40, 0xea, 0x6e, 0xc9, 0x37, 0x41, 0xa5, + 0x9d, 0xf3, 0x1c, 0x21, 0x66, 0xbf, 0x68, 0xbc, 0x12, 0x65, 0x36, 0x86, + 0x6f, 0x9d, 0x82, 0x83, 0x86, 0x1f, 0x99, 0x88, 0x8d, 0xdd, 0xfc, 0xdc, + 0x4f, 0xde, 0xf4, 0x9e, 0x51, 0x83, 0x19, 0x55, 0x25, 0x57, 0x24, 0x06, + 0x7b, 0xde, 0xf4, 0xcb, 0x5e, 0x4c, 0xcc, 0x23, 0xfb, 0xe6, 0xff, 0xd6, + 0x5e, 0xca, 0x3a, 0xf2, 0x16, 0xd1, 0x3d, 0xa8, 0x10, 0x43, 0x93, 0x20, + 0x97, 0xd9, 0x6b, 0x14, 0x63, 0x1e, 0xa4, 0xaf, 0x7a, 0xa0, 0x9d, 0xbe, + 0xcc, 0xfa, 0xee, 0xb1, 0x06, 0xed, 0x74, 0x9b, 0x57, 0xc7, 0xf0, 0xf1, + 0x00, 0x1e, 0x39, 0xbe, 0x0d, 0xb5, 0x4e, 0xef, 0x67, 0x9c, 0x36, 0xf5, + 0xb0, 0xae, 0x1a, 0xfd, 0xa5, 0x8f, 0xf5, 0xd5, 0xd5, 0xf5, 0x8f, 0xa3, + 0xd5, 0xb9, 0x3e, 0x86, 0xfb, 0x72, 0x41, 0xa5, 0x2b, 0xe7, 0xc3, 0xb6, + 0x3b, 0x1f, 0x87, 0x7f, 0x5d, 0x3f, 0xe5, 0x92, 0xeb, 0xf2, 0xf7, 0x5d, + 0xac, 0xcb, 0x44, 0xbe, 0x0a, 0xc4, 0x96, 0x53, 0xb6, 0x75, 0x3a, 0x46, + 0x8e, 0xfb, 0x94, 0x3d, 0xd6, 0x7f, 0xb7, 0xaf, 0x3a, 0xfb, 0x34, 0x72, + 0xad, 0x4a, 0xf6, 0xef, 0xf9, 0x8c, 0x60, 0xce, 0x00, 0x72, 0x8c, 0xed, + 0xbb, 0x9c, 0xf7, 0xff, 0xb8, 0xc2, 0xd5, 0x29, 0xcd, 0x7a, 0xb5, 0x83, + 0xeb, 0x27, 0xcf, 0x24, 0x4b, 0xd7, 0x9a, 0x03, 0xee, 0x19, 0x01, 0xf1, + 0x85, 0x01, 0xdc, 0xc2, 0x45, 0x68, 0x48, 0x88, 0x8f, 0x0d, 0xa0, 0x21, + 0x4f, 0x40, 0x5d, 0xee, 0xca, 0xfb, 0x90, 0x55, 0x64, 0xad, 0xa9, 0x13, + 0x37, 0x69, 0xbb, 0x65, 0xf2, 0xfe, 0x2f, 0x2a, 0x7f, 0xf5, 0x7d, 0xc1, + 0x5b, 0x72, 0xcc, 0xb0, 0x70, 0xcd, 0x5f, 0x77, 0xff, 0xb7, 0x20, 0xf7, + 0x7c, 0xfa, 0x9f, 0x30, 0x8e, 0x13, 0x3d, 0xd5, 0x1e, 0xf1, 0x9f, 0x3f, + 0xc1, 0x03, 0xb3, 0x8f, 0xf0, 0xbe, 0x8c, 0x7f, 0x88, 0x35, 0x84, 0x4f, + 0xe9, 0x24, 0xfe, 0xec, 0x3f, 0xee, 0xd9, 0x55, 0x81, 0xbf, 0xb4, 0x2b, + 0x97, 0x8d, 0xa0, 0x21, 0x35, 0xc6, 0xe7, 0x15, 0x74, 0x90, 0x2f, 0x3e, + 0x65, 0x6c, 0xc1, 0xb6, 0x25, 0x82, 0x01, 0x2f, 0xda, 0x03, 0xbd, 0x62, + 0x43, 0x05, 0x5b, 0x79, 0xfd, 0x25, 0xae, 0xef, 0xb3, 0x86, 0x0f, 0x0d, + 0x4b, 0xa5, 0x8f, 0xa7, 0x4d, 0xa5, 0xd1, 0x1e, 0x70, 0xf7, 0xab, 0x32, + 0x76, 0xad, 0xae, 0x0f, 0xdd, 0xe1, 0x69, 0x98, 0x7a, 0x9b, 0xfe, 0xd4, + 0xbe, 0xee, 0xc6, 0x7b, 0x65, 0x9b, 0x18, 0xe4, 0x90, 0x2f, 0xd8, 0xb8, + 0x69, 0x14, 0xea, 0xba, 0x1b, 0xd7, 0xbf, 0x2c, 0xf7, 0x21, 0xc6, 0x20, + 0x32, 0xb5, 0xa6, 0xf4, 0x79, 0x12, 0x1c, 0xe7, 0x10, 0x7e, 0xbf, 0x30, + 0x86, 0x83, 0xb9, 0x12, 0xa7, 0xa6, 0x6f, 0xeb, 0xeb, 0xae, 0xeb, 0xf6, + 0x50, 0x2e, 0xd1, 0x5f, 0x53, 0xd2, 0xed, 0x00, 0xeb, 0x8b, 0x6a, 0x62, + 0xec, 0x83, 0xb4, 0xe9, 0x90, 0x63, 0xd3, 0x5e, 0x18, 0xf9, 0xeb, 0xe3, + 0x0e, 0x72, 0xdc, 0xa0, 0x29, 0x76, 0x93, 0x3d, 0xb2, 0x43, 0xd8, 0xcf, + 0x71, 0xf7, 0xdd, 0x30, 0xee, 0x80, 0x71, 0x7d, 0xdc, 0xbd, 0xb9, 0xc4, + 0x69, 0x4f, 0x69, 0xdc, 0x47, 0x67, 0xcb, 0x63, 0x64, 0x70, 0xfb, 0xba, + 0x0c, 0xf2, 0x9b, 0x0e, 0xd8, 0x07, 0x1c, 0x7b, 0x9c, 0x72, 0xae, 0x6f, + 0x6d, 0x10, 0xee, 0xc5, 0x3f, 0x4d, 0xd9, 0x8f, 0x4f, 0x92, 0x7b, 0xe9, + 0xce, 0x9e, 0xf0, 0x37, 0x0a, 0xe5, 0xbe, 0x94, 0xf6, 0x4e, 0x97, 0x37, + 0xcd, 0xd8, 0x8e, 0x04, 0x76, 0x7c, 0xa6, 0x97, 0xb1, 0x8d, 0xf5, 0xd7, + 0x76, 0xab, 0x3b, 0xd8, 0x69, 0x05, 0xc8, 0xbb, 0xaa, 0x95, 0xad, 0x39, + 0xe9, 0x69, 0x48, 0x2c, 0x97, 0xb8, 0x70, 0x41, 0xea, 0xbc, 0xbb, 0x59, + 0x1f, 0x2c, 0x0f, 0x20, 0xdc, 0x8f, 0x89, 0xc2, 0xef, 0x2a, 0xe9, 0x88, + 0xec, 0x4d, 0x4b, 0x5e, 0x01, 0x73, 0x5e, 0x0f, 0xaa, 0xe9, 0x4b, 0x11, + 0xd3, 0x30, 0x4f, 0x36, 0xd8, 0x20, 0x47, 0x09, 0x2c, 0x35, 0xd3, 0xe6, + 0xee, 0x06, 0x2f, 0x8e, 0x39, 0xfc, 0x4b, 0x9b, 0xe1, 0xef, 0x94, 0xc4, + 0xcc, 0x1d, 0x39, 0xc9, 0x63, 0xa4, 0x90, 0xfa, 0x08, 0xfe, 0x31, 0x55, + 0x1c, 0x5a, 0x82, 0xf4, 0xfd, 0x4b, 0x20, 0xf5, 0xc4, 0x04, 0xfe, 0x4a, + 0x8f, 0x06, 0xfa, 0x0a, 0x3e, 0xa5, 0xcb, 0x9a, 0x0b, 0xee, 0xb4, 0xc2, + 0x08, 0xb1, 0x1e, 0xeb, 0xf6, 0xc6, 0x59, 0x5f, 0x88, 0x1d, 0x03, 0x6d, + 0xb7, 0xe4, 0xfb, 0x82, 0x1d, 0x96, 0x8b, 0x85, 0x2b, 0x67, 0x02, 0xc1, + 0x6d, 0xd3, 0xf1, 0xe8, 0x84, 0xc3, 0xc5, 0x42, 0x6d, 0xf1, 0xbc, 0x6d, + 0xbf, 0x61, 0x14, 0xaf, 0x56, 0x3a, 0xdf, 0x8d, 0xb6, 0x64, 0xbe, 0x19, + 0xf7, 0x90, 0x3f, 0xb5, 0x4f, 0x37, 0xc3, 0x98, 0x06, 0x4e, 0x1c, 0x8f, + 0x62, 0x6d, 0x4e, 0x3b, 0x3d, 0xec, 0xed, 0xc3, 0xd4, 0x7c, 0x27, 0x72, + 0x85, 0xe0, 0x62, 0xcc, 0x43, 0x5e, 0x9d, 0xf2, 0x60, 0x97, 0x71, 0x5c, + 0x29, 0x2e, 0x53, 0x70, 0x17, 0x11, 0xbc, 0xdf, 0xe1, 0x13, 0x73, 0xac, + 0x47, 0x15, 0xdc, 0xe4, 0xe0, 0x6e, 0x4b, 0xdb, 0x5a, 0xf2, 0xed, 0x3b, + 0xc9, 0x07, 0x77, 0x11, 0x57, 0x12, 0xeb, 0x6c, 0xbc, 0x99, 0xca, 0xf4, + 0xd7, 0x40, 0xeb, 0x39, 0xcc, 0x1a, 0xa8, 0x47, 0x71, 0xf9, 0x5d, 0xd3, + 0x9c, 0xcb, 0x09, 0x57, 0xcd, 0xb5, 0x90, 0x37, 0xb2, 0xae, 0x49, 0x69, + 0x31, 0x8f, 0x47, 0xc5, 0x94, 0x33, 0x46, 0xac, 0xcd, 0x98, 0xab, 0x60, + 0xbe, 0xeb, 0xc5, 0xd3, 0x8e, 0xfc, 0x49, 0xca, 0x77, 0x37, 0xbe, 0x66, + 0xf5, 0x05, 0xfb, 0x2c, 0xd9, 0xbf, 0x8c, 0x27, 0xaf, 0x7a, 0x4d, 0xf2, + 0xd7, 0x78, 0xac, 0xce, 0xfb, 0x05, 0x25, 0xe3, 0x6b, 0x6a, 0x9d, 0x83, + 0xa9, 0x5c, 0x2a, 0x71, 0x36, 0xd1, 0x2f, 0x41, 0x8e, 0xd5, 0x7e, 0x3c, + 0xb8, 0x98, 0x86, 0xdb, 0xb3, 0xd9, 0x66, 0xfc, 0x2f, 0x14, 0x23, 0xda, + 0x44, 0x9a, 0x18, 0xb0, 0x85, 0x98, 0xdb, 0xdf, 0xeb, 0xe3, 0x7d, 0xe9, + 0x79, 0xa9, 0x6d, 0xe3, 0x59, 0x14, 0x83, 0x66, 0x22, 0x73, 0x94, 0x9e, + 0xd3, 0x53, 0x90, 0xfd, 0x8d, 0x00, 0x1e, 0x60, 0xed, 0x94, 0x2e, 0xed, + 0xfd, 0x6c, 0x9d, 0x76, 0xf7, 0xb3, 0x0e, 0xcf, 0xfb, 0xc2, 0xdd, 0x56, + 0x0b, 0xf3, 0xbd, 0xef, 0x86, 0xb1, 0x13, 0x13, 0x2b, 0x3d, 0x1e, 0xac, + 0x5e, 0xb7, 0x47, 0x99, 0x59, 0x56, 0xce, 0xad, 0x51, 0x27, 0x1f, 0x56, + 0x50, 0xcf, 0xf3, 0x27, 0x65, 0x8e, 0xcf, 0xb5, 0x8d, 0x9f, 0x94, 0x5c, + 0xab, 0xb6, 0x6d, 0xb2, 0xb4, 0x3e, 0xa9, 0xfd, 0xa2, 0xb4, 0x53, 0x94, + 0xba, 0xad, 0x30, 0xd7, 0xb4, 0xd9, 0xd3, 0x5a, 0x74, 0x40, 0x49, 0x93, + 0xf7, 0x69, 0xc9, 0x5b, 0xbc, 0x1e, 0x3c, 0xa2, 0x6b, 0x83, 0xd2, 0x13, + 0x7c, 0x19, 0x2e, 0x07, 0x6e, 0x9a, 0x1b, 0x60, 0x5e, 0x73, 0x6d, 0xeb, + 0xf6, 0x07, 0xeb, 0xdb, 0x9a, 0x1d, 0x5e, 0x6c, 0xdb, 0x97, 0x53, 0xdd, + 0xe4, 0x0c, 0xc2, 0x8b, 0xe5, 0xfa, 0xea, 0xb6, 0xc6, 0x99, 0x00, 0x65, + 0x53, 0xf0, 0x3e, 0x73, 0xd2, 0x44, 0xa1, 0x2c, 0xa3, 0xcb, 0x99, 0x77, + 0x90, 0x33, 0x57, 0x99, 0x5a, 0x6b, 0x17, 0x39, 0xb3, 0x9e, 0x2a, 0xd6, + 0xf9, 0xd0, 0x8b, 0xa7, 0xac, 0x66, 0x39, 0xe3, 0xe4, 0xf0, 0xe6, 0x2b, + 0x27, 0xb5, 0xb4, 0x70, 0xe6, 0x1f, 0x18, 0xc0, 0x3d, 0xe4, 0xcc, 0x57, + 0xb3, 0x3e, 0xec, 0x21, 0x67, 0x5e, 0xcc, 0x06, 0xd0, 0x47, 0xce, 0xfc, + 0x11, 0xf9, 0xd5, 0xbb, 0xa9, 0x2b, 0x78, 0xb4, 0xd4, 0x07, 0xdb, 0x9b, + 0xf4, 0xd0, 0xaf, 0x85, 0x37, 0xff, 0xbc, 0xc4, 0x9b, 0xe7, 0xff, 0x05, + 0x6f, 0xde, 0x4a, 0x3e, 0xd8, 0x9d, 0x13, 0x4e, 0xb0, 0x92, 0x9c, 0xc0, + 0xc6, 0xcb, 0xa5, 0x1e, 0xd8, 0x0a, 0xe6, 0xb3, 0xa7, 0x53, 0x7d, 0xc8, + 0x4e, 0x63, 0x79, 0x8d, 0xd3, 0x77, 0x12, 0x99, 0x34, 0xe3, 0xb2, 0x92, + 0xe8, 0xec, 0x43, 0x82, 0xf5, 0xb1, 0x96, 0xbc, 0xe8, 0xf6, 0xc0, 0x16, + 0xdf, 0x85, 0xf4, 0x88, 0x7c, 0xa8, 0x59, 0x00, 0x56, 0xdc, 0xd0, 0x03, + 0xab, 0x49, 0xe0, 0x4f, 0xeb, 0x20, 0xfb, 0x9a, 0x0c, 0xb3, 0x85, 0x66, + 0xc6, 0xa7, 0x82, 0x23, 0x89, 0x10, 0xba, 0x8f, 0x93, 0xf3, 0x38, 0x3d, + 0x30, 0x7b, 0xe4, 0x3b, 0x46, 0x1f, 0x8e, 0xce, 0xbb, 0x3d, 0xb0, 0xed, + 0xe4, 0x6e, 0xbe, 0x44, 0x04, 0x95, 0x0b, 0x3e, 0xbc, 0x40, 0xee, 0xbc, + 0x95, 0xeb, 0x7c, 0xa6, 0xd4, 0x07, 0x5b, 0xc1, 0x18, 0xb1, 0x73, 0x2a, + 0x66, 0x16, 0xf0, 0x86, 0x17, 0xb8, 0xb8, 0xc2, 0xe9, 0xed, 0x4b, 0xff, + 0x3f, 0x84, 0x73, 0x0e, 0x77, 0x0e, 0x2e, 0x66, 0x14, 0x57, 0xb7, 0x0a, + 0xae, 0x89, 0xac, 0xab, 0x87, 0xeb, 0xda, 0x7e, 0x52, 0xeb, 0x7c, 0x85, + 0xb6, 0x68, 0x4a, 0xbc, 0xea, 0xac, 0xc7, 0x40, 0x4a, 0x6a, 0xd9, 0x40, + 0x5b, 0xc0, 0x39, 0x0f, 0xa5, 0xb6, 0xfd, 0x28, 0x1b, 0xef, 0xa9, 0x2c, + 0xc5, 0xe3, 0xaa, 0x7c, 0x05, 0xd2, 0x25, 0x1f, 0x09, 0xd0, 0xa7, 0x03, + 0x93, 0x69, 0x54, 0x6d, 0x70, 0xfd, 0x7b, 0x55, 0x7e, 0x9c, 0xbc, 0xb5, + 0x53, 0xea, 0xe8, 0xf0, 0x76, 0xab, 0x13, 0x53, 0x56, 0x0c, 0x95, 0xe7, + 0x4a, 0x7b, 0xa6, 0xe7, 0xe4, 0xec, 0x5c, 0x7d, 0x9b, 0xfa, 0xd5, 0x32, + 0x1f, 0x4c, 0x93, 0xe3, 0x44, 0x02, 0x77, 0x14, 0x84, 0x2b, 0xf6, 0xe0, + 0xa8, 0xa5, 0x45, 0xbf, 0x87, 0xf8, 0xd0, 0xfd, 0xb4, 0x51, 0xb1, 0xee, + 0x7a, 0xbf, 0x69, 0x40, 0xfa, 0x51, 0x9f, 0xe9, 0x37, 0x0d, 0xe7, 0xf0, + 0x8b, 0xba, 0x96, 0x4a, 0x78, 0xd6, 0xfa, 0xc9, 0xe7, 0xb5, 0xe8, 0xd3, + 0x78, 0x02, 0x23, 0xb9, 0x9f, 0x2b, 0x21, 0xdd, 0x37, 0xf8, 0x13, 0xaf, + 0x16, 0x9d, 0x53, 0x42, 0x7c, 0xf7, 0xee, 0x60, 0x97, 0x75, 0x37, 0x71, + 0x27, 0x9e, 0xec, 0x54, 0xbc, 0x98, 0x89, 0x3a, 0x5c, 0x34, 0xd8, 0xc3, + 0x6b, 0x53, 0x85, 0x32, 0xa7, 0x71, 0x6b, 0xfe, 0xed, 0xc7, 0x5d, 0xfc, + 0x88, 0xe7, 0x83, 0x8b, 0x97, 0xe0, 0xea, 0x56, 0x4d, 0x5d, 0x1f, 0x9c, + 0x54, 0xed, 0xfe, 0x65, 0x12, 0xc3, 0x3a, 0xf6, 0xd0, 0xf7, 0xee, 0x99, + 0x1e, 0xa0, 0x9c, 0xc2, 0xa5, 0x57, 0x10, 0xa7, 0xfa, 0x30, 0x4e, 0x9c, + 0xb1, 0x28, 0x5f, 0x8e, 0x35, 0xe4, 0xe2, 0xfa, 0x8c, 0x3d, 0xb9, 0x41, + 0x37, 0x56, 0x7b, 0x8b, 0x4b, 0xa2, 0xe4, 0x36, 0xeb, 0x98, 0xb7, 0xdb, + 0x0b, 0xcd, 0xb8, 0x7c, 0x46, 0x67, 0x7d, 0xdb, 0x41, 0xee, 0xde, 0x83, + 0x87, 0xa9, 0xcf, 0xa3, 0x85, 0xc7, 0x91, 0xfe, 0x92, 0x0f, 0x87, 0x8f, + 0xa7, 0xb1, 0x6a, 0x5d, 0x0a, 0xe9, 0x2f, 0x06, 0x88, 0x53, 0x21, 0x4c, + 0x30, 0x16, 0xa1, 0xb8, 0x7e, 0x2e, 0xe7, 0x7f, 0xfe, 0x82, 0x36, 0xfb, + 0x26, 0xed, 0xf7, 0x8d, 0x6b, 0x7b, 0x00, 0x65, 0xfe, 0x7d, 0x9d, 0xab, + 0x7a, 0xb9, 0x86, 0xfb, 0x9c, 0xd8, 0x8c, 0x32, 0x36, 0x75, 0x5c, 0x2d, + 0xf5, 0x12, 0x17, 0x4f, 0x6a, 0x8b, 0xf7, 0x22, 0x3e, 0x7c, 0xd9, 0x8b, + 0x81, 0x3a, 0xfa, 0x5d, 0x94, 0x5c, 0xf5, 0xc3, 0x44, 0xc2, 0x38, 0x47, + 0xae, 0x3a, 0xba, 0xc1, 0xe5, 0xaa, 0x9e, 0x05, 0x15, 0x15, 0x0b, 0xac, + 0x65, 0x9d, 0x5e, 0xe2, 0x37, 0x83, 0x6e, 0x2f, 0x51, 0xf8, 0x4d, 0xab, + 0x9c, 0x75, 0xba, 0x8d, 0xb5, 0x5c, 0xfa, 0x0a, 0x32, 0xe8, 0x2c, 0xcc, + 0x04, 0xef, 0x21, 0x36, 0xf7, 0x49, 0x6f, 0xa4, 0x10, 0x09, 0xdf, 0x43, + 0xde, 0xf5, 0x2d, 0xae, 0xaf, 0xec, 0xed, 0xf6, 0x15, 0x56, 0xf3, 0xbd, + 0x28, 0x3f, 0x05, 0x57, 0x45, 0xf6, 0x1b, 0xf5, 0xe8, 0xa9, 0x92, 0xbd, + 0x86, 0x97, 0xa9, 0x43, 0xff, 0xdc, 0x4a, 0x3c, 0x3a, 0xe7, 0xaf, 0x12, + 0xc2, 0xff, 0x68, 0xde, 0xc5, 0xb6, 0x58, 0xfe, 0xae, 0xa0, 0xf0, 0xc9, + 0xf6, 0xe3, 0xee, 0x77, 0xfd, 0x86, 0xef, 0x65, 0xfd, 0x56, 0x50, 0x3f, + 0x7b, 0x5a, 0xea, 0xa2, 0x68, 0xdb, 0x19, 0xea, 0xb7, 0x78, 0xd2, 0x89, + 0x2f, 0xd6, 0x98, 0xf1, 0xe1, 0x84, 0x57, 0xf4, 0xfa, 0x99, 0xe8, 0x45, + 0xae, 0xc2, 0x78, 0xe1, 0xb8, 0x1e, 0x3d, 0xe2, 0xe8, 0xe5, 0xea, 0xe3, + 0xf6, 0x69, 0xaf, 0x9c, 0x4c, 0xde, 0xd8, 0x17, 0xd5, 0xc9, 0x97, 0x3f, + 0x61, 0x6c, 0x3c, 0x71, 0x98, 0x9c, 0xf9, 0x2a, 0x6b, 0x4a, 0x3f, 0x9f, + 0xaf, 0x73, 0x9e, 0x97, 0x3e, 0xad, 0xe7, 0x1a, 0x67, 0x5e, 0xbc, 0xfe, + 0x4e, 0x89, 0x2f, 0x4b, 0x4f, 0x5a, 0x9e, 0x53, 0x1d, 0x3b, 0xed, 0x76, + 0x78, 0xa0, 0x70, 0x2b, 0x1b, 0x1d, 0xeb, 0xfe, 0xad, 0x35, 0x0b, 0x2e, + 0xce, 0x38, 0x6e, 0xd5, 0x55, 0x25, 0x7b, 0xe1, 0xab, 0xd6, 0x3d, 0x68, + 0xbb, 0xfe, 0x1c, 0x09, 0xef, 0x62, 0x9c, 0x7c, 0x85, 0xef, 0xec, 0x3a, + 0x57, 0x1f, 0xbe, 0xcb, 0x6a, 0x71, 0x6c, 0x74, 0xd7, 0xb9, 0x28, 0x46, + 0x2d, 0xe9, 0xeb, 0x43, 0xf1, 0x99, 0x87, 0xb1, 0x7d, 0x2a, 0x86, 0x77, + 0x8d, 0x60, 0xe9, 0xec, 0x89, 0xc4, 0xa4, 0xc1, 0x98, 0x8c, 0xd0, 0x77, + 0xe3, 0xb1, 0x77, 0xc9, 0x51, 0x33, 0x3e, 0xe0, 0x68, 0x8e, 0xb8, 0x46, + 0xde, 0x08, 0xc5, 0x3d, 0xbb, 0xe9, 0xbe, 0x5b, 0xfe, 0xbb, 0x1a, 0xb1, + 0x25, 0xf1, 0xd6, 0xfd, 0xa8, 0x47, 0x96, 0xd8, 0x1f, 0xd4, 0xff, 0x1a, + 0xc7, 0x4e, 0x78, 0x98, 0x1f, 0x08, 0x4e, 0x77, 0x1a, 0xfc, 0xde, 0x34, + 0xf8, 0x01, 0xfe, 0xd1, 0x9e, 0x91, 0xf3, 0x51, 0x8a, 0x9c, 0xc5, 0xf8, + 0xc4, 0xae, 0xd3, 0xf5, 0xe2, 0xb7, 0xa0, 0x0f, 0x5f, 0x45, 0xd3, 0xd0, + 0x22, 0x7e, 0x6c, 0x17, 0x79, 0xef, 0x7d, 0xc6, 0xd1, 0x2b, 0x46, 0x3c, + 0xea, 0xa1, 0xf0, 0xc5, 0x88, 0x17, 0xf7, 0x1b, 0xb2, 0xa7, 0xa4, 0x0d, + 0x3d, 0x0f, 0x6d, 0xf0, 0xbc, 0x22, 0x67, 0x6a, 0x2e, 0xd9, 0x99, 0x25, + 0x32, 0xaf, 0x82, 0xb5, 0xab, 0x9b, 0x3a, 0x2b, 0xa0, 0xb5, 0xfa, 0x15, + 0xdd, 0xf8, 0x40, 0xf9, 0x7b, 0xbb, 0x18, 0xf9, 0xc4, 0xbe, 0xac, 0x97, + 0xc7, 0xd5, 0x62, 0x01, 0x6f, 0x59, 0xb6, 0x7a, 0x1c, 0xb3, 0x64, 0x2f, + 0xee, 0xaf, 0xf1, 0xc0, 0x09, 0x1f, 0x3a, 0x52, 0x3f, 0xb1, 0x33, 0x11, + 0x19, 0xf3, 0x13, 0xda, 0x42, 0xc6, 0x77, 0xfb, 0xd5, 0x2f, 0x17, 0xa0, + 0x6c, 0xb3, 0x84, 0x33, 0x8b, 0x5f, 0x4c, 0xc1, 0xb6, 0xa4, 0x87, 0x68, + 0xe3, 0x8e, 0xd4, 0x08, 0xde, 0x4f, 0xa5, 0xff, 0x63, 0x00, 0xda, 0x85, + 0x2b, 0x5e, 0xad, 0xd8, 0xec, 0x8d, 0x29, 0xc1, 0x46, 0x7d, 0xa8, 0xd1, + 0xdd, 0x9f, 0x67, 0xfd, 0x14, 0x0a, 0xec, 0x2a, 0x48, 0x9d, 0x39, 0x85, + 0x85, 0xc9, 0x0c, 0x7c, 0xe4, 0x77, 0xa3, 0x2d, 0x5a, 0xdf, 0x73, 0x8a, + 0x16, 0x3d, 0xa0, 0xc4, 0x94, 0x7b, 0xf5, 0x61, 0xbc, 0x60, 0x24, 0xd2, + 0xed, 0x4a, 0x7d, 0xa0, 0xb3, 0x50, 0x1e, 0xbb, 0x83, 0xb8, 0xa1, 0x15, + 0xaf, 0x78, 0x2b, 0x51, 0xb7, 0x5e, 0xef, 0xac, 0xf4, 0x6a, 0xc3, 0x5f, + 0x60, 0x1d, 0xb0, 0xa3, 0x50, 0x0c, 0x7e, 0x90, 0xf0, 0x60, 0x8d, 0xb3, + 0x87, 0x90, 0x2d, 0xf5, 0x47, 0xa7, 0xd0, 0x35, 0x69, 0x6f, 0xbe, 0x98, + 0xd2, 0xa2, 0xcf, 0x29, 0x99, 0x3d, 0x21, 0xf2, 0x9a, 0x07, 0xa1, 0xc7, + 0xe6, 0x19, 0xc7, 0x1d, 0x05, 0x0f, 0x56, 0x3a, 0x7e, 0x9c, 0xe5, 0x98, + 0x87, 0x51, 0x79, 0xc2, 0xde, 0xbc, 0xc7, 0xd0, 0x86, 0xaf, 0x78, 0x33, + 0xff, 0xb5, 0x8e, 0x76, 0xdb, 0xa6, 0x68, 0xac, 0x4f, 0x47, 0x70, 0x91, + 0x3a, 0x7c, 0x3d, 0xa5, 0x25, 0xff, 0x4c, 0xd1, 0x7a, 0xbe, 0x4c, 0x5f, + 0xf6, 0x9a, 0x61, 0xca, 0xa9, 0x25, 0x67, 0x21, 0xbd, 0xf3, 0x18, 0xae, + 0x18, 0x99, 0xe0, 0xf6, 0xc6, 0x24, 0xf9, 0x59, 0x94, 0xf9, 0x30, 0x86, + 0xa3, 0xe4, 0x77, 0x87, 0x0b, 0x15, 0x28, 0xaa, 0x3a, 0xf9, 0x59, 0x0f, + 0x3c, 0x93, 0x21, 0x65, 0x2e, 0x1b, 0x37, 0x3a, 0xf0, 0x47, 0x28, 0x3a, + 0x38, 0x77, 0x18, 0xa1, 0x13, 0x3f, 0xb0, 0x6b, 0x74, 0xbd, 0x75, 0x52, + 0xe1, 0xbc, 0xcf, 0x44, 0x69, 0x63, 0xbe, 0x27, 0xe7, 0x4e, 0xac, 0x6e, + 0xdc, 0x3b, 0x19, 0xe1, 0xfb, 0x35, 0x58, 0x7b, 0x22, 0x86, 0x0f, 0x53, + 0x37, 0xa3, 0xe8, 0x70, 0x04, 0x85, 0x7e, 0x40, 0x3f, 0x62, 0xad, 0x95, + 0x21, 0x8f, 0x94, 0x7d, 0xa3, 0xc3, 0x96, 0xd4, 0xe8, 0x3e, 0x7e, 0x0f, + 0xf1, 0x57, 0xec, 0xf9, 0x39, 0x72, 0x1d, 0xf9, 0x5c, 0xd3, 0x16, 0x9b, + 0xfb, 0x5e, 0x95, 0xb3, 0x7f, 0x89, 0x18, 0x9f, 0x53, 0x9d, 0xde, 0xe0, + 0x28, 0xc7, 0x3c, 0x3b, 0x25, 0xb5, 0x5b, 0xfb, 0xa6, 0x40, 0x69, 0x7f, + 0xfd, 0x87, 0x86, 0x07, 0x9b, 0x59, 0xdf, 0x47, 0x75, 0x39, 0x9b, 0x39, + 0xaa, 0xd5, 0x61, 0x13, 0x4e, 0xab, 0x2c, 0xc4, 0xf5, 0xff, 0x80, 0x09, + 0x35, 0x49, 0xac, 0xd1, 0xf1, 0x5e, 0xf6, 0x37, 0x58, 0xf3, 0xd4, 0xcb, + 0xd9, 0x1b, 0xac, 0x3c, 0xe1, 0xe7, 0x9c, 0x9b, 0xc9, 0x75, 0xb6, 0xe3, + 0xbb, 0xaa, 0x5b, 0x6f, 0x10, 0x8f, 0x30, 0x3e, 0x1b, 0x22, 0x1f, 0x0d, + 0xf0, 0xf7, 0x46, 0xd9, 0x7e, 0x9d, 0x4c, 0xa2, 0xcb, 0xbf, 0x25, 0x53, + 0x80, 0x7c, 0x80, 0x78, 0x99, 0x7d, 0x0d, 0x1f, 0x72, 0xec, 0xcc, 0xac, + 0x3b, 0xe6, 0xf1, 0x82, 0x8c, 0x2b, 0xf3, 0xc5, 0x99, 0x37, 0x65, 0xfc, + 0x90, 0x9c, 0xbf, 0xfd, 0x77, 0xce, 0x41, 0x86, 0x77, 0x82, 0x35, 0xb2, + 0xd1, 0x88, 0x0e, 0x95, 0xeb, 0x65, 0xc9, 0x1c, 0x1a, 0xeb, 0x51, 0x79, + 0x37, 0x8a, 0x35, 0x93, 0xf6, 0x48, 0xd4, 0x94, 0xeb, 0xb6, 0x5d, 0xbb, + 0x51, 0x8f, 0xbe, 0xad, 0xf8, 0x98, 0xf3, 0x7c, 0xb4, 0xc1, 0x38, 0xce, + 0x66, 0x9b, 0x2e, 0xbc, 0x4f, 0x0e, 0x15, 0x63, 0xbd, 0x77, 0xc9, 0x3b, + 0x8e, 0xb9, 0xec, 0xb1, 0x6a, 0xe9, 0x13, 0x30, 0x0f, 0x2a, 0xb3, 0xd9, + 0xfb, 0xab, 0x05, 0xab, 0xc6, 0xe8, 0x0b, 0xcd, 0x93, 0x22, 0xab, 0x3d, + 0x52, 0xc3, 0x71, 0x8e, 0x72, 0x9c, 0xd9, 0x0d, 0x7a, 0xdf, 0x98, 0x22, + 0x36, 0x0b, 0xe1, 0x58, 0xe1, 0xa2, 0xf4, 0xd0, 0x68, 0xb7, 0x69, 0x3e, + 0x2f, 0x76, 0x8b, 0xe0, 0xbb, 0xa5, 0x71, 0x9e, 0x2a, 0x5c, 0xc0, 0x6c, + 0xf6, 0x2d, 0xe7, 0xef, 0x31, 0xd6, 0x0d, 0xe3, 0xac, 0x21, 0xf3, 0xc4, + 0x93, 0xc9, 0x6c, 0x53, 0xdf, 0x24, 0xe5, 0x70, 0xcf, 0xca, 0x0d, 0xe0, + 0xd9, 0xd2, 0x33, 0xa3, 0x7c, 0x77, 0xf4, 0xda, 0xdf, 0x62, 0x23, 0x77, + 0x0f, 0xdf, 0xdd, 0x53, 0xa8, 0xe4, 0xda, 0xb9, 0xb5, 0xf8, 0x11, 0xcb, + 0x2f, 0x7d, 0x70, 0xbc, 0x36, 0xb5, 0x19, 0x63, 0xc6, 0x5f, 0x62, 0x2f, + 0xf5, 0x1e, 0xa7, 0x3d, 0x4f, 0x58, 0xce, 0x5e, 0xbd, 0x9c, 0xcb, 0x22, + 0x96, 0x87, 0xda, 0xce, 0x90, 0x93, 0x1d, 0x63, 0xcc, 0xdc, 0x97, 0x6a, + 0xea, 0x79, 0x9d, 0x7e, 0x97, 0xfe, 0xa2, 0xec, 0x87, 0x03, 0x93, 0xb9, + 0x47, 0x31, 0xb3, 0xa4, 0x69, 0xf1, 0x45, 0x62, 0xc2, 0x69, 0xe2, 0x94, + 0x8f, 0x98, 0x50, 0x9b, 0xf3, 0x94, 0xf6, 0x77, 0x0d, 0x7e, 0x6f, 0xba, + 0x30, 0x87, 0xbf, 0xa1, 0x5d, 0x44, 0xbe, 0x78, 0x72, 0x0e, 0xf2, 0xac, + 0xdb, 0x83, 0xd5, 0xe7, 0x06, 0x71, 0xe9, 0x66, 0xb7, 0x8f, 0xe6, 0x65, + 0xee, 0xde, 0x97, 0x6d, 0x52, 0xc7, 0x64, 0xec, 0x5e, 0x2d, 0x9a, 0xe1, + 0x5a, 0x4d, 0x38, 0x1c, 0x5c, 0x65, 0x8e, 0x97, 0x73, 0x58, 0x35, 0xf0, + 0xd1, 0xf7, 0xc7, 0x0c, 0x39, 0xbf, 0x10, 0x0d, 0xef, 0xe0, 0x1a, 0x8e, + 0x59, 0x4d, 0xad, 0x71, 0x65, 0x0f, 0xca, 0xfc, 0xdb, 0xe5, 0xd4, 0x5a, + 0xdf, 0x51, 0x34, 0xf5, 0x3c, 0x88, 0x2f, 0x21, 0xbd, 0xa4, 0xa9, 0x7f, + 0x0a, 0x71, 0xe3, 0x7e, 0xc8, 0x39, 0x4e, 0x77, 0xac, 0x86, 0x3c, 0x33, + 0xc9, 0xd2, 0x4f, 0xec, 0x15, 0xfa, 0x53, 0x98, 0x22, 0x77, 0x6c, 0x5c, + 0xa7, 0x5f, 0xf8, 0x5a, 0xe9, 0x9e, 0xbb, 0x4f, 0x24, 0xfe, 0x12, 0xa0, + 0x0d, 0x2a, 0xe1, 0x5b, 0x5a, 0xcf, 0x39, 0x68, 0x0b, 0xe7, 0x8c, 0xef, + 0x45, 0x1c, 0xa4, 0xbf, 0x4d, 0x15, 0x14, 0x18, 0x0d, 0x17, 0x31, 0x24, + 0xb9, 0x8b, 0xef, 0xb4, 0x67, 0x43, 0xe4, 0xb2, 0x51, 0x54, 0xea, 0xf1, + 0xd8, 0x28, 0xf5, 0x6b, 0x27, 0x96, 0x8f, 0x13, 0x43, 0x32, 0x6a, 0xc8, + 0x39, 0x77, 0x5a, 0xa9, 0x47, 0x9d, 0xff, 0x15, 0x90, 0x5a, 0xa8, 0x71, + 0x46, 0xf6, 0xa8, 0x0f, 0xe3, 0xe2, 0x54, 0x11, 0xc7, 0x52, 0x69, 0xec, + 0x5f, 0xa2, 0x62, 0xd2, 0x5a, 0xe6, 0xf4, 0x0e, 0xa4, 0xe6, 0xea, 0xca, + 0x1d, 0x72, 0xfa, 0x91, 0x5b, 0x53, 0x9e, 0x06, 0x39, 0xa7, 0x31, 0xcb, + 0xda, 0x6b, 0xca, 0x18, 0xc1, 0x41, 0xe3, 0xcb, 0x30, 0x96, 0x0a, 0x76, + 0x8e, 0xe1, 0xd5, 0x19, 0xc9, 0x71, 0xc9, 0xb6, 0x5b, 0x26, 0xc5, 0x3e, + 0x1e, 0x72, 0xdf, 0x00, 0x9a, 0x1d, 0x2e, 0xf7, 0x50, 0xdb, 0xea, 0x19, + 0x97, 0xd3, 0x35, 0xe7, 0xe5, 0xac, 0x74, 0x0d, 0xc2, 0xb4, 0xd7, 0xf9, + 0x94, 0x9f, 0x98, 0x23, 0xf6, 0x94, 0x33, 0x7a, 0xae, 0x9e, 0xc9, 0xbc, + 0x82, 0xb1, 0x96, 0x1b, 0xf7, 0x58, 0xe4, 0xff, 0x06, 0xae, 0x9d, 0x1b, + 0x2c, 0xf5, 0xc7, 0xff, 0xcc, 0xbe, 0x74, 0x93, 0xe8, 0xbd, 0x22, 0x44, + 0x4c, 0x8f, 0xcd, 0x5c, 0xb3, 0xaf, 0xd8, 0xf4, 0x9c, 0xe4, 0x0c, 0xc7, + 0xe6, 0x6e, 0xcf, 0x4d, 0x1b, 0xba, 0xac, 0x34, 0x31, 0x9f, 0xd0, 0xaf, + 0x96, 0xd0, 0xdf, 0x9a, 0xd1, 0xbf, 0xc2, 0xf4, 0xf5, 0x5e, 0xb5, 0x36, + 0xa3, 0x75, 0xfd, 0x7b, 0x36, 0x6e, 0x6e, 0x87, 0x57, 0x97, 0xeb, 0x33, + 0x76, 0x5a, 0x95, 0xbf, 0xff, 0x24, 0x24, 0xb9, 0xfe, 0x65, 0xab, 0x68, + 0xaf, 0x5e, 0xe6, 0x72, 0xc4, 0x1f, 0x64, 0x65, 0xdf, 0x2b, 0x63, 0xb3, + 0xde, 0xbe, 0xf0, 0xae, 0xf7, 0x10, 0xbe, 0x9f, 0x3f, 0x8c, 0x77, 0xa6, + 0x7c, 0x08, 0xeb, 0xa2, 0xcb, 0x66, 0xd4, 0xae, 0x4f, 0xa4, 0xdf, 0x23, + 0x2e, 0x5e, 0x98, 0x29, 0xfb, 0xc5, 0x43, 0x6d, 0x6b, 0x66, 0x14, 0x8e, + 0x55, 0x83, 0x0a, 0xea, 0xf9, 0x1d, 0xc3, 0x8b, 0x58, 0x89, 0xe3, 0x7a, + 0x29, 0xa7, 0x9c, 0x7b, 0x10, 0xee, 0x1b, 0xcf, 0x1f, 0x0a, 0xb9, 0x3d, + 0xb0, 0x10, 0x71, 0x74, 0x1c, 0x13, 0xd9, 0xa6, 0xe4, 0xfb, 0x72, 0x0e, + 0x87, 0x35, 0xd9, 0x25, 0x8c, 0xe3, 0x44, 0xb6, 0x8c, 0xa1, 0x51, 0x39, + 0x97, 0x9a, 0x8c, 0x79, 0x5c, 0x8c, 0x8c, 0x79, 0xb4, 0x4c, 0xcc, 0xe3, + 0x0f, 0x09, 0x77, 0x18, 0x2d, 0xc4, 0xa3, 0x95, 0xf0, 0xe2, 0x3e, 0xc3, + 0xf5, 0x8f, 0x86, 0x39, 0x3f, 0x62, 0x4b, 0x25, 0x2f, 0x4b, 0x4e, 0xf6, + 0x31, 0x27, 0x2f, 0x23, 0xbf, 0xf6, 0xe1, 0x4d, 0x5d, 0xec, 0xb1, 0xa6, + 0x6c, 0x0f, 0xe3, 0x1c, 0x1e, 0xb6, 0x8b, 0x3d, 0xe2, 0x4b, 0x7e, 0x1c, + 0x6e, 0x9e, 0xb5, 0x67, 0x22, 0xa2, 0xbb, 0x17, 0xa7, 0x89, 0xaf, 0xb8, + 0x39, 0x1e, 0x3d, 0xcd, 0x9c, 0x3d, 0xa6, 0x97, 0x7d, 0xfc, 0xb7, 0x4b, + 0x72, 0xea, 0x7d, 0xf3, 0xb8, 0x9f, 0x7f, 0x37, 0x44, 0xf7, 0x2b, 0xee, + 0x7c, 0xab, 0xe7, 0xfe, 0x26, 0x54, 0xee, 0x9f, 0xca, 0xb3, 0xb1, 0xfc, + 0xe3, 0xfc, 0x2e, 0x63, 0x85, 0xe8, 0x9f, 0x95, 0xe8, 0x8f, 0xc8, 0xff, + 0x89, 0x88, 0x5d, 0x64, 0x3f, 0x11, 0xb4, 0x87, 0x8d, 0xd7, 0x68, 0x8f, + 0xc3, 0xd7, 0xce, 0x4c, 0xb9, 0xf8, 0x55, 0xc5, 0xeb, 0x3b, 0x52, 0xaf, + 0x6c, 0x0a, 0xe2, 0x17, 0xf6, 0xa5, 0x48, 0x94, 0x98, 0x50, 0xe6, 0xa1, + 0x62, 0x33, 0xc3, 0xb1, 0x99, 0x5b, 0x2b, 0x5e, 0xd3, 0xa3, 0x38, 0x40, + 0xbe, 0xbd, 0x90, 0x2d, 0x9f, 0x15, 0x89, 0x13, 0x6b, 0x3e, 0x8f, 0xfe, + 0x3a, 0x19, 0xaf, 0x9e, 0xfe, 0x95, 0xa4, 0x0d, 0xd4, 0xf0, 0xce, 0x69, + 0xa9, 0xb5, 0xc9, 0x8f, 0x27, 0xe3, 0xc6, 0x43, 0xe4, 0x91, 0x13, 0x93, + 0xb6, 0xfd, 0x96, 0x81, 0x3b, 0xc3, 0xcc, 0xef, 0x2f, 0x90, 0x4f, 0x90, + 0x6f, 0xc4, 0x2a, 0x95, 0xa6, 0xe8, 0x2a, 0xe6, 0xfa, 0x31, 0xd6, 0x0a, + 0x4f, 0x13, 0xe3, 0x4e, 0x2f, 0x54, 0xc1, 0x3a, 0x21, 0xfb, 0x82, 0x55, + 0x98, 0x7c, 0x26, 0x49, 0xd9, 0x97, 0x72, 0x9c, 0x00, 0xaa, 0xcf, 0xb4, + 0xa2, 0xea, 0x94, 0x82, 0x1d, 0x89, 0x56, 0x04, 0xcf, 0xd4, 0x30, 0xff, + 0x06, 0x70, 0xa5, 0x85, 0x6b, 0xfc, 0x4c, 0x59, 0x0f, 0x67, 0x8f, 0x14, + 0x4f, 0xe6, 0x62, 0xe4, 0xf1, 0x11, 0x2c, 0x58, 0xb2, 0x1f, 0x1c, 0x70, + 0xb0, 0xf4, 0xc2, 0x86, 0x7a, 0x67, 0xcf, 0xea, 0xc5, 0x82, 0x1e, 0x3d, + 0xab, 0xd4, 0xe0, 0xc7, 0x27, 0x8a, 0x37, 0x57, 0xc2, 0x7e, 0x79, 0x85, + 0x99, 0xe8, 0xdb, 0x4b, 0xff, 0x5f, 0xb3, 0x3a, 0xc2, 0xfa, 0xc6, 0xb6, + 0xaf, 0x6e, 0x94, 0x3a, 0xd8, 0x70, 0xea, 0x60, 0x77, 0x6f, 0x5f, 0x1f, + 0x7c, 0x4c, 0xc9, 0x6c, 0x0f, 0xc3, 0xfe, 0xa8, 0xd2, 0xb4, 0x3f, 0xf6, + 0x9b, 0x09, 0xbe, 0x2f, 0x7b, 0x7c, 0xb6, 0xfd, 0xc3, 0x16, 0xdb, 0xce, + 0xb7, 0xc4, 0xfb, 0x54, 0xaf, 0x8a, 0x33, 0x8d, 0xb2, 0x2f, 0xe8, 0xc1, + 0x8f, 0x13, 0x7a, 0x74, 0x2f, 0x64, 0x0f, 0x9e, 0x78, 0xbf, 0x4c, 0xce, + 0x18, 0xd6, 0x87, 0x3b, 0xad, 0xa5, 0x78, 0x61, 0x7e, 0x23, 0xfa, 0xfd, + 0x70, 0xce, 0xc5, 0xd8, 0x06, 0xde, 0x5e, 0x01, 0xc9, 0xe1, 0x89, 0xd6, + 0xc7, 0x10, 0xc1, 0x7c, 0xe1, 0x30, 0x1e, 0x39, 0x21, 0xf5, 0xd7, 0xea, + 0xb6, 0xc0, 0x09, 0xfb, 0x07, 0x51, 0xb3, 0x48, 0x8c, 0xb4, 0xed, 0xaa, + 0x8d, 0x4d, 0x51, 0xa6, 0x26, 0xf2, 0x8d, 0x18, 0x79, 0xb3, 0x3e, 0xf8, + 0x63, 0x2c, 0xc1, 0xd9, 0xd9, 0xf4, 0xcd, 0xe4, 0xf2, 0x9d, 0xcf, 0x2a, + 0xc2, 0xdb, 0x23, 0x78, 0xbe, 0x20, 0x9c, 0x65, 0x6d, 0x5b, 0xd7, 0x89, + 0xe5, 0x78, 0x79, 0x3e, 0x82, 0xb3, 0x96, 0x4e, 0xce, 0x04, 0xa5, 0xda, + 0xb4, 0x6b, 0x6b, 0x29, 0x6b, 0xb5, 0xd7, 0x8b, 0xed, 0x29, 0xa9, 0x19, + 0xf5, 0xc1, 0x90, 0x82, 0xe5, 0x95, 0xd0, 0x17, 0x1f, 0x06, 0x86, 0x82, + 0x66, 0xe2, 0xc2, 0xb3, 0x4a, 0xa2, 0xef, 0x03, 0x6f, 0x04, 0xdf, 0x22, + 0x16, 0x7d, 0xbd, 0x20, 0x67, 0xa5, 0x88, 0x37, 0xb3, 0x31, 0xae, 0x5b, + 0x00, 0x9e, 0x86, 0x1a, 0x1c, 0x61, 0xec, 0xbc, 0x66, 0x54, 0x10, 0xaf, + 0xe4, 0xec, 0x94, 0x60, 0x7d, 0xbd, 0x9c, 0x19, 0xb1, 0x5f, 0xd4, 0xdd, + 0x7a, 0xdf, 0x98, 0xbb, 0xf1, 0x4c, 0xb1, 0x4a, 0x8c, 0x6f, 0xea, 0x89, + 0x2a, 0x6f, 0xd8, 0xe9, 0x2f, 0x2a, 0xd4, 0xb3, 0xb7, 0x06, 0x55, 0x8e, + 0xae, 0x18, 0xcd, 0x95, 0xf3, 0x4b, 0xad, 0xd4, 0x77, 0x3d, 0x99, 0x92, + 0x3f, 0x56, 0x33, 0xee, 0x8f, 0x32, 0x5f, 0x57, 0x9e, 0x90, 0xbc, 0x42, + 0xfe, 0xad, 0x6c, 0x26, 0x2f, 0x16, 0x0e, 0x11, 0xc0, 0x83, 0xaa, 0xf8, + 0x86, 0x4a, 0xfd, 0x36, 0xf9, 0xe4, 0x2c, 0xd4, 0x0b, 0x05, 0xc9, 0xeb, + 0x82, 0x0b, 0xe5, 0xf9, 0xa2, 0xa8, 0x9b, 0x94, 0x35, 0x52, 0xdb, 0x3e, + 0x9a, 0x0c, 0xc9, 0xd9, 0xf7, 0x11, 0x0f, 0xeb, 0xef, 0x00, 0xfd, 0xeb, + 0x9e, 0x16, 0x7d, 0x70, 0xb3, 0x57, 0x63, 0x0d, 0x1e, 0x67, 0x2d, 0xa1, + 0xb5, 0x4e, 0x28, 0x37, 0x8e, 0xf3, 0x6c, 0x8d, 0xc4, 0x4b, 0x86, 0x7a, + 0x3e, 0xe9, 0xe8, 0xb4, 0x86, 0x3a, 0x09, 0x5e, 0x27, 0x89, 0xd7, 0x35, + 0xb8, 0x32, 0x05, 0x9d, 0x11, 0x8c, 0x57, 0x0d, 0x02, 0x95, 0x9a, 0x48, + 0x77, 0x40, 0x62, 0x41, 0xeb, 0x17, 0x3e, 0x55, 0x4d, 0x7c, 0x9e, 0x9d, + 0x92, 0x7c, 0xa3, 0x08, 0x57, 0xc9, 0xd4, 0x9a, 0x43, 0xf8, 0x70, 0x03, + 0xf0, 0xc6, 0xa4, 0xbb, 0xef, 0xde, 0x27, 0x67, 0x6f, 0x2b, 0xdd, 0x33, + 0x0d, 0x8f, 0x39, 0x67, 0x15, 0x64, 0xfc, 0x43, 0x38, 0x93, 0x15, 0x7e, + 0x39, 0x44, 0x7e, 0x19, 0x1f, 0x26, 0xf7, 0x6c, 0x2d, 0x40, 0x62, 0xb2, + 0xc9, 0xf8, 0x88, 0xbe, 0xff, 0x2c, 0x79, 0xeb, 0x11, 0xb8, 0xfb, 0xee, + 0x8d, 0xa5, 0xb3, 0x08, 0xf1, 0x7c, 0xa7, 0xb2, 0xd3, 0x39, 0xcf, 0x64, + 0x30, 0xde, 0x3a, 0x94, 0x1d, 0xf3, 0xdb, 0x94, 0xae, 0xf9, 0x6e, 0x65, + 0x4f, 0x41, 0xea, 0xd8, 0xd5, 0x6d, 0x0f, 0x9e, 0xd8, 0xad, 0xec, 0x9c, + 0xed, 0x55, 0xc8, 0x6f, 0xd5, 0x80, 0xd9, 0xa7, 0x74, 0xcf, 0xbb, 0xfd, + 0xf4, 0x4e, 0xd6, 0x70, 0x3b, 0x2d, 0xf1, 0x07, 0xb5, 0xad, 0x6b, 0x52, + 0xfe, 0x17, 0x2b, 0x22, 0xff, 0xf7, 0xd0, 0xbf, 0x55, 0xb1, 0xed, 0x55, + 0xa9, 0xd7, 0x65, 0x3d, 0xec, 0xe7, 0x53, 0xcc, 0x93, 0x56, 0x0d, 0x06, + 0x58, 0x83, 0x8c, 0x1a, 0xb7, 0x94, 0xf6, 0xcf, 0x44, 0x27, 0x39, 0x2f, + 0x21, 0xfe, 0x8a, 0x4c, 0x25, 0x65, 0xf8, 0x07, 0xca, 0xbf, 0xbf, 0xa4, + 0x57, 0xb7, 0x9c, 0x27, 0xf0, 0x23, 0x23, 0x3a, 0xe4, 0xa9, 0xef, 0xb1, + 0xc9, 0xeb, 0x7a, 0xf9, 0x78, 0x6d, 0x9c, 0x5c, 0x75, 0xbf, 0xa2, 0x0d, + 0x3f, 0xe7, 0xea, 0x75, 0xe1, 0x8a, 0xa2, 0x15, 0x47, 0x21, 0xb8, 0xe0, + 0xea, 0xb5, 0xb6, 0xa4, 0xd7, 0x9a, 0x7c, 0xa7, 0x73, 0x4e, 0xab, 0x86, + 0x7a, 0x2d, 0x4c, 0x76, 0x28, 0x9d, 0xf3, 0xd2, 0xcb, 0x14, 0xdd, 0x44, + 0x8f, 0x13, 0x76, 0x95, 0xde, 0xad, 0xdc, 0xee, 0x9c, 0x2b, 0x93, 0xb3, + 0x5d, 0xb2, 0xdf, 0x5f, 0xd6, 0x4b, 0x72, 0xfa, 0xd2, 0xf0, 0xb6, 0x69, + 0x35, 0xbc, 0x75, 0xda, 0xb6, 0xbf, 0x6b, 0xfc, 0xb3, 0xa3, 0xcb, 0x59, + 0x43, 0x74, 0x91, 0x73, 0x23, 0x65, 0x7d, 0xbe, 0x50, 0xd2, 0x47, 0xd6, + 0xea, 0xfa, 0x3a, 0x95, 0xff, 0x87, 0xef, 0xdd, 0xac, 0x7b, 0xa6, 0xa4, + 0xac, 0x4f, 0xd8, 0x2c, 0x9f, 0x2f, 0x1b, 0xc2, 0x1b, 0xbc, 0xff, 0x93, + 0x6c, 0x59, 0x2f, 0x2f, 0xe6, 0x66, 0xc5, 0xfe, 0x43, 0xf2, 0x3f, 0x7c, + 0xc4, 0x91, 0xb8, 0x31, 0x46, 0x3f, 0x72, 0xf5, 0xd3, 0x86, 0x57, 0x7a, + 0x9b, 0x8a, 0x57, 0xa0, 0xf5, 0x2f, 0x2a, 0x89, 0x34, 0x6b, 0x70, 0x9c, + 0x2d, 0xfc, 0xea, 0xfa, 0x35, 0xe7, 0xab, 0x94, 0x6d, 0x39, 0x19, 0xfb, + 0x21, 0x8e, 0x2d, 0x67, 0x4a, 0x14, 0x3c, 0x37, 0x0b, 0xcc, 0x5a, 0x9c, + 0xd6, 0x1c, 0xc1, 0xd3, 0x86, 0x6d, 0x3f, 0xdb, 0xa2, 0xcb, 0x59, 0xa0, + 0xf3, 0x6e, 0xaf, 0x08, 0x46, 0x8d, 0x2e, 0x7b, 0x79, 0x72, 0x9e, 0xa4, + 0x97, 0x36, 0x10, 0xdd, 0xc5, 0x07, 0xca, 0x6b, 0x2f, 0xe7, 0xdc, 0x32, + 0xb4, 0x8f, 0xd8, 0xa6, 0x7c, 0xde, 0x4d, 0xfa, 0x30, 0x37, 0xda, 0x64, + 0x6d, 0xd8, 0x59, 0x5f, 0x43, 0xfc, 0x95, 0xe8, 0x43, 0x5f, 0x9d, 0x23, + 0x97, 0x18, 0x33, 0xfc, 0x0e, 0x6f, 0x3b, 0x42, 0xae, 0x32, 0xc1, 0xd8, + 0x79, 0xd2, 0xba, 0x80, 0x0b, 0xf9, 0xd7, 0xf0, 0xc6, 0xb5, 0xff, 0x67, + 0x13, 0x7f, 0xb9, 0xb8, 0xb1, 0xcb, 0x39, 0xd3, 0x74, 0xba, 0xf5, 0x96, + 0x84, 0xe0, 0x50, 0x77, 0xb3, 0x9c, 0x71, 0xaa, 0x34, 0xf3, 0x9b, 0x64, + 0xbf, 0xab, 0xc2, 0x34, 0x6f, 0x3d, 0xaf, 0x8b, 0x6d, 0xfe, 0x62, 0xfd, + 0x19, 0x5d, 0xf4, 0xfa, 0x9f, 0x6b, 0xc7, 0x9d, 0xff, 0xaf, 0xfc, 0xbb, + 0x5b, 0xf7, 0xe9, 0x12, 0x3b, 0x67, 0x5b, 0xda, 0x1d, 0x4c, 0x68, 0x35, + 0x57, 0x39, 0x36, 0x68, 0x31, 0x6f, 0x71, 0x3e, 0x0d, 0x33, 0xe9, 0x7c, + 0x9a, 0xa6, 0x6b, 0x9b, 0x6e, 0xb3, 0xc1, 0xf9, 0xec, 0x30, 0xdd, 0xf3, + 0xcf, 0x69, 0x53, 0x77, 0x3e, 0x7b, 0xcc, 0xb8, 0xf3, 0xd9, 0x69, 0xae, + 0xbc, 0x2e, 0x17, 0x7f, 0xfe, 0x1f, 0x9b, 0x97, 0x53, 0xd9, 0x78, 0x3a, 0x00, 0x00, 0x00 }; static const u32 bnx2_TXP_b06FwData[(0x0/4) + 1] = { 0x0 }; static const u32 bnx2_TXP_b06FwRodata[(0x0/4) + 1] = { 0x0 }; static struct fw_info bnx2_txp_fw_06 = { - /* Firmware version: 4.4.2 */ + /* Firmware version: 4.6.16 */ .ver_major = 0x4, - .ver_minor = 0x4, - .ver_fix = 0x2, + .ver_minor = 0x6, + .ver_fix = 0x10, .start_addr = 0x08000098, .text_addr = 0x08000000, - .text_len = 0x3ab0, + .text_len = 0x3a74, .text_index = 0x0, .gz_text = bnx2_TXP_b06FwText, .gz_text_len = sizeof(bnx2_TXP_b06FwText), @@ -4535,11 +4432,11 @@ static struct fw_info bnx2_txp_fw_06 = { .data_index = 0x0, .data = bnx2_TXP_b06FwData, - .sbss_addr = 0x08003ae0, + .sbss_addr = 0x08003aa0, .sbss_len = 0x68, .sbss_index = 0x0, - .bss_addr = 0x08003b48, + .bss_addr = 0x08003b08, .bss_len = 0x14c, .bss_index = 0x0, -- cgit From 259436a505bedc59a0114f2d17fa56af71d94129 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 12 Feb 2009 16:53:48 -0800 Subject: bnx2: Update 5709 firmware. New firmware fixes a data corruption issue when receiving and placing jumbo frames into host buffers. In some cases, the buffer descriptor is not updated correctly and this will lead to the driver linking the wrong number of pages into the SKB. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2_fw2.h | 8795 ++++++++++++++++++++++++------------------------ 1 file changed, 4363 insertions(+), 4432 deletions(-) diff --git a/drivers/net/bnx2_fw2.h b/drivers/net/bnx2_fw2.h index fe753b6bcb4..c54e4886b8b 100644 --- a/drivers/net/bnx2_fw2.h +++ b/drivers/net/bnx2_fw2.h @@ -15,848 +15,847 @@ */ static u8 bnx2_COM_b09FwText[] = { - 0xcd, 0x7c, 0x7f, 0x6c, 0x5c, 0xd7, 0x75, 0xe6, 0x79, 0x6f, 0xde, 0x90, - 0x43, 0x8a, 0xa2, 0x1e, 0x99, 0x31, 0x33, 0x8e, 0xd8, 0x7a, 0x86, 0xf3, - 0x48, 0xd1, 0x21, 0xe3, 0x3e, 0x33, 0x63, 0x99, 0x76, 0xa6, 0xd6, 0x64, - 0x66, 0x28, 0x2b, 0x0e, 0x69, 0xd0, 0x8e, 0x82, 0x4d, 0x01, 0x03, 0xe5, - 0x0e, 0xa9, 0x54, 0xd9, 0xf5, 0x22, 0xda, 0x34, 0x45, 0x8a, 0xa2, 0x88, - 0x26, 0x24, 0xe5, 0x2a, 0xcd, 0x88, 0x1c, 0xcb, 0x34, 0x1b, 0x14, 0x5e, - 0x64, 0x3c, 0xa4, 0x14, 0xb7, 0x1d, 0x89, 0x72, 0xe2, 0x2d, 0xbc, 0x58, - 0x07, 0x66, 0xa9, 0x1f, 0x4e, 0x83, 0x14, 0xf0, 0x2e, 0xbc, 0x68, 0x60, - 0xa4, 0x80, 0x20, 0xbb, 0x8d, 0xb3, 0xc8, 0x62, 0x83, 0xdd, 0x00, 0x71, - 0x02, 0x27, 0x6f, 0xbf, 0xef, 0xde, 0xfb, 0xc8, 0xd1, 0x88, 0x76, 0xd2, - 0xfc, 0xb5, 0x04, 0x06, 0xf7, 0xfd, 0xb8, 0x3f, 0xce, 0x3d, 0xf7, 0xdc, - 0x73, 0xbe, 0x73, 0xee, 0x79, 0x7c, 0x40, 0xa4, 0x53, 0xcc, 0xdf, 0x5e, - 0xfc, 0x32, 0xff, 0xe1, 0xb3, 0xb3, 0x63, 0x77, 0x65, 0xee, 0xc2, 0xe5, - 0x87, 0xed, 0xf7, 0x3b, 0x0e, 0x9f, 0x47, 0xf0, 0x8b, 0xe3, 0x37, 0x66, - 0xae, 0x77, 0xfb, 0x73, 0xf1, 0x3b, 0x68, 0x89, 0xcc, 0xfc, 0x4f, 0x11, - 0xab, 0xe5, 0x5d, 0xec, 0x5d, 0xda, 0xbc, 0xd7, 0x9f, 0xfd, 0x1b, 0xb4, - 0xf9, 0xd7, 0xfe, 0x45, 0x34, 0xd9, 0x6a, 0xde, 0xfc, 0x49, 0xcc, 0xce, - 0xce, 0x4c, 0xe6, 0x3d, 0x89, 0x45, 0xb2, 0x47, 0xa7, 0x66, 0x3d, 0x91, - 0x5c, 0x63, 0x24, 0x59, 0x90, 0x5f, 0x04, 0xe5, 0xb8, 0x23, 0x7c, 0xfe, - 0x5b, 0xd9, 0x77, 0xbe, 0xf6, 0xad, 0x7b, 0x53, 0x3f, 0xae, 0x45, 0x24, - 0xe6, 0x66, 0xdf, 0x16, 0x77, 0x48, 0x62, 0xfd, 0x68, 0xf3, 0xcc, 0x81, - 0x57, 0x6d, 0xe9, 0x0e, 0xfb, 0x72, 0x67, 0x22, 0x59, 0x99, 0x3e, 0x56, - 0x39, 0x19, 0xd8, 0x9e, 0x94, 0x9d, 0xac, 0x37, 0x5c, 0x97, 0xae, 0xf1, - 0x73, 0x99, 0x7b, 0x05, 0xf7, 0xd3, 0xc7, 0x1a, 0x31, 0x99, 0x6f, 0x94, - 0xbb, 0x6c, 0xcf, 0x43, 0x29, 0xb1, 0xb6, 0xec, 0x62, 0xec, 0x9a, 0xc7, - 0xb1, 0xbf, 0x8a, 0xb1, 0xf7, 0x4b, 0xd4, 0x0b, 0x82, 0x73, 0x18, 0xfb, - 0x70, 0xe3, 0x17, 0xc1, 0xb3, 0x8e, 0x1e, 0xd7, 0xce, 0x9e, 0x88, 0xb0, - 0xb4, 0xb2, 0xb5, 0xc9, 0x81, 0x06, 0xef, 0x8b, 0xed, 0x9a, 0x4e, 0xbf, - 0x13, 0x74, 0xc6, 0x9c, 0xec, 0x89, 0xce, 0x45, 0x94, 0xd1, 0x6c, 0x7c, - 0xec, 0x9c, 0xaa, 0xb7, 0x6e, 0xea, 0x3d, 0x1e, 0xd5, 0xed, 0xde, 0x9a, - 0x1c, 0x6a, 0xb0, 0xfc, 0xc9, 0xe4, 0xa0, 0x2a, 0xdf, 0x99, 0x4c, 0xab, - 0x52, 0xa6, 0x06, 0x54, 0xe9, 0x4c, 0x79, 0xaa, 0x7c, 0xc6, 0x3c, 0x7f, - 0x6e, 0x32, 0xa9, 0xca, 0x86, 0x29, 0x2f, 0x99, 0xf2, 0x05, 0x53, 0xbe, - 0x68, 0xca, 0x97, 0x4c, 0xb9, 0x69, 0xca, 0x2b, 0x93, 0xba, 0x9f, 0x6f, - 0x9b, 0xfb, 0xef, 0x9a, 0xf2, 0x55, 0x53, 0xbe, 0x66, 0xca, 0xef, 0x99, - 0xf2, 0xfb, 0x86, 0xae, 0xeb, 0xa6, 0x7c, 0xd3, 0x94, 0x3f, 0x32, 0xef, - 0x7f, 0x6c, 0xe8, 0x7d, 0x1b, 0x74, 0xfd, 0x49, 0xd4, 0xc8, 0x2a, 0xe6, - 0x9d, 0x94, 0xd9, 0x8a, 0x23, 0xf3, 0xcb, 0x11, 0x29, 0xa8, 0x35, 0xfc, - 0xca, 0x5e, 0xe9, 0x74, 0x64, 0x61, 0x23, 0x26, 0xd7, 0x95, 0x88, 0xbe, - 0x15, 0x7c, 0xeb, 0x80, 0x94, 0xed, 0xac, 0x2b, 0x97, 0x36, 0xe2, 0xf2, - 0xf2, 0x86, 0x58, 0xd3, 0x99, 0x0e, 0xb1, 0xcf, 0x7e, 0x40, 0x72, 0xae, - 0x25, 0x11, 0xc5, 0xd3, 0xa4, 0xe4, 0x2b, 0x7d, 0xb8, 0x4f, 0x25, 0x44, - 0xae, 0xee, 0xd5, 0xeb, 0x17, 0x93, 0xc8, 0x2a, 0xd7, 0xe4, 0xfe, 0xa9, - 0x6b, 0x2b, 0x09, 0x71, 0x96, 0x46, 0x31, 0x46, 0x97, 0x44, 0x57, 0xa5, - 0x3f, 0x22, 0x83, 0x89, 0x4f, 0xa3, 0x46, 0xb1, 0xe1, 0xc8, 0x44, 0xc3, - 0x12, 0xc7, 0x8b, 0x41, 0x3e, 0xba, 0xf0, 0x73, 0xf1, 0x8b, 0xe3, 0x97, - 0xc0, 0xef, 0x47, 0xe8, 0xa7, 0x5f, 0x0a, 0x0d, 0xf6, 0x89, 0x71, 0x97, - 0x31, 0xfe, 0x72, 0xca, 0x9d, 0x11, 0xd2, 0x95, 0x90, 0x6f, 0x1d, 0x20, - 0x5d, 0x2e, 0xe9, 0x01, 0x6d, 0x31, 0x2b, 0xbf, 0x22, 0x27, 0x0a, 0xbe, - 0x24, 0x6d, 0xaf, 0x53, 0x4a, 0xae, 0x95, 0x9c, 0x1b, 0xee, 0x95, 0xf2, - 0x51, 0xbc, 0x5f, 0x96, 0x9c, 0x8d, 0xfe, 0x4b, 0xae, 0xcc, 0xe8, 0x77, - 0x7c, 0xf6, 0x36, 0xf6, 0x6a, 0xca, 0xa5, 0xd0, 0xbe, 0xbc, 0xfc, 0xb7, - 0xb8, 0x66, 0x7f, 0x3f, 0x77, 0x34, 0xdd, 0x3f, 0xc5, 0x3d, 0x9f, 0x0f, - 0x99, 0x79, 0xf0, 0x9a, 0x75, 0xc3, 0x71, 0xc3, 0xf9, 0x72, 0xfc, 0x61, - 0xcc, 0x99, 0x34, 0x84, 0x73, 0x96, 0x72, 0x14, 0xb4, 0xd4, 0x57, 0xba, - 0xac, 0xb5, 0x95, 0x51, 0x79, 0x62, 0xf9, 0x01, 0xc9, 0xfb, 0x41, 0x30, - 0xeb, 0x4b, 0xdc, 0x96, 0x41, 0xb7, 0x80, 0x0a, 0x5b, 0x0d, 0xb1, 0xea, - 0x15, 0x89, 0xb5, 0x83, 0x2f, 0x3f, 0x58, 0x61, 0xdf, 0x0e, 0x9e, 0xf5, - 0xa1, 0x7e, 0xb7, 0xb5, 0xbe, 0x02, 0xfa, 0xb3, 0xe4, 0x4f, 0x10, 0x2c, - 0xfa, 0x83, 0x89, 0x39, 0x8c, 0x79, 0xb9, 0x31, 0x38, 0x7e, 0x43, 0x5c, - 0xf4, 0xd9, 0x8b, 0x3a, 0xe4, 0x15, 0xfb, 0x62, 0x9f, 0xec, 0xaf, 0x0b, - 0x6d, 0xe3, 0x78, 0x47, 0xba, 0x82, 0x20, 0xef, 0xbb, 0xbc, 0x97, 0x4d, - 0xf0, 0x6f, 0x93, 0xfc, 0xeb, 0xec, 0x97, 0x57, 0x1a, 0x1c, 0x63, 0x37, - 0xda, 0x47, 0xfe, 0x3f, 0xa4, 0x3d, 0x81, 0xfe, 0xe3, 0x28, 0xf7, 0x58, - 0xf5, 0x6a, 0x80, 0xf1, 0x13, 0xb8, 0xde, 0x6d, 0x1e, 0xd7, 0xd5, 0xda, - 0x5f, 0xc2, 0xda, 0xbb, 0xd9, 0xb8, 0x3c, 0xbf, 0xd1, 0x8f, 0x79, 0x24, - 0xe4, 0x1b, 0x90, 0xcd, 0x9e, 0x83, 0x7b, 0x24, 0x0d, 0xd9, 0xe4, 0x9a, - 0x8f, 0xad, 0xce, 0x49, 0x29, 0x9e, 0x1a, 0xa6, 0x1e, 0xcd, 0x8f, 0xed, - 0xc3, 0x7c, 0xb5, 0xb6, 0x1a, 0x58, 0xca, 0xed, 0xb7, 0xe5, 0x90, 0xd8, - 0x59, 0x8c, 0x9b, 0x19, 0x01, 0x2d, 0x11, 0xbc, 0x8b, 0x8b, 0xb7, 0x9a, - 0xc3, 0xb3, 0x54, 0xa2, 0x04, 0x1a, 0xe7, 0x41, 0x63, 0x49, 0xca, 0x62, - 0x5f, 0x7c, 0xce, 0x0a, 0xf7, 0x8a, 0xe6, 0xdd, 0xb0, 0xe9, 0x67, 0x5b, - 0xce, 0x2d, 0x7b, 0xb5, 0xcb, 0x8a, 0xac, 0x8e, 0xca, 0xa9, 0x5d, 0x78, - 0x56, 0x07, 0xcf, 0xec, 0xa5, 0x70, 0x1f, 0x38, 0xb8, 0xef, 0x43, 0xdd, - 0x6e, 0xcb, 0x59, 0xbd, 0x95, 0x5f, 0x6b, 0x8d, 0x41, 0x7f, 0x0b, 0xfc, - 0xb2, 0x57, 0x7b, 0x51, 0xe7, 0x56, 0x7e, 0xd5, 0xc1, 0x2f, 0x7b, 0x55, - 0xf3, 0xaa, 0x0e, 0x5e, 0xd9, 0x4b, 0x71, 0x94, 0x7b, 0x2c, 0xfb, 0xac, - 0xe6, 0x55, 0xdd, 0xec, 0x99, 0xf3, 0x4a, 0x5f, 0xe5, 0x40, 0xab, 0x25, - 0x5a, 0x67, 0xe5, 0x84, 0xba, 0x29, 0x92, 0x2d, 0x62, 0xaf, 0xdb, 0xe0, - 0x85, 0x23, 0xc5, 0x31, 0x4b, 0x66, 0xd5, 0xbb, 0xa2, 0xa4, 0x1b, 0x1f, - 0x00, 0x23, 0x47, 0x86, 0x61, 0x29, 0xca, 0x6d, 0xd9, 0x17, 0xed, 0xad, - 0x4a, 0x4c, 0x0a, 0x4e, 0x52, 0xbc, 0x25, 0xa5, 0xc7, 0x9b, 0xfa, 0x99, - 0x41, 0x3f, 0xdf, 0x01, 0x3f, 0x2c, 0xe8, 0x56, 0xbe, 0x7b, 0x4c, 0xed, - 0xfb, 0xf4, 0xaa, 0x23, 0x83, 0x4b, 0xac, 0x53, 0xb6, 0xaf, 0x34, 0xde, - 0x09, 0x74, 0xbf, 0x8f, 0x71, 0x4c, 0xd7, 0xce, 0x2e, 0xda, 0x97, 0xd7, - 0x4f, 0xdb, 0x57, 0x1b, 0xe8, 0xb7, 0xc1, 0xb5, 0xc0, 0x5a, 0x2d, 0x63, - 0xad, 0x96, 0xb1, 0x6e, 0x66, 0x4f, 0xd7, 0xd4, 0xde, 0x4a, 0x9a, 0x75, - 0x25, 0x0d, 0x5c, 0xdb, 0x04, 0xd6, 0x94, 0x6b, 0x2b, 0xd6, 0xab, 0x99, - 0x3d, 0x12, 0x39, 0x1b, 0x51, 0x6b, 0xda, 0xb3, 0xfa, 0x91, 0xed, 0x35, - 0x1d, 0x68, 0x5a, 0x53, 0xfb, 0x5d, 0xd6, 0xd4, 0xd9, 0x65, 0x4d, 0xb7, - 0x1a, 0x3f, 0x31, 0x6b, 0xfa, 0x73, 0x31, 0xb2, 0xff, 0x9e, 0xfc, 0x1a, - 0x00, 0xbf, 0xbc, 0x5f, 0x83, 0x5f, 0xce, 0xae, 0xfc, 0xea, 0xb3, 0x5b, - 0xf9, 0x15, 0x01, 0xbf, 0xa2, 0xbf, 0x36, 0xbf, 0xc0, 0x87, 0x5d, 0x79, - 0x15, 0x83, 0xde, 0x2b, 0x4b, 0x3e, 0x23, 0x92, 0xaf, 0x6a, 0x5d, 0x5d, - 0x56, 0x3a, 0x9b, 0xba, 0x2a, 0xd4, 0xd9, 0xd4, 0xd7, 0x6a, 0x9f, 0x58, - 0x85, 0x4a, 0x12, 0xba, 0xd4, 0x41, 0xf9, 0x1c, 0xca, 0x3d, 0xd6, 0x74, - 0xb5, 0x1f, 0x76, 0x36, 0x10, 0x77, 0x2c, 0xb4, 0x97, 0xe5, 0x84, 0x8b, - 0xb5, 0x71, 0xef, 0x8a, 0x8a, 0xf4, 0xa5, 0xc0, 0xa7, 0x14, 0xde, 0xa7, - 0x12, 0x39, 0xc9, 0xda, 0x21, 0xae, 0xc9, 0x57, 0x3a, 0xde, 0xce, 0xa9, - 0x2b, 0x3e, 0x67, 0xbb, 0x0c, 0x9e, 0x45, 0x65, 0x06, 0x76, 0xa0, 0xe8, - 0x71, 0x3c, 0xf6, 0x9f, 0x9c, 0xe1, 0xb8, 0x85, 0x46, 0xa8, 0xb3, 0x25, - 0x07, 0x1b, 0x8e, 0x77, 0xdc, 0xb7, 0xe3, 0x56, 0x41, 0xd9, 0xa0, 0x8c, - 0x78, 0x8d, 0x66, 0xfb, 0xb2, 0x4d, 0x27, 0xf6, 0x73, 0x0e, 0x72, 0x4d, - 0xda, 0x92, 0xd8, 0x7b, 0xc7, 0x22, 0xe1, 0xfa, 0x38, 0xd9, 0x71, 0x81, - 0x5d, 0x96, 0xf9, 0x0a, 0xfb, 0xfb, 0x63, 0x2b, 0x72, 0x31, 0xec, 0x9f, - 0x7c, 0x64, 0xdf, 0xba, 0xbf, 0xf9, 0xc6, 0x5b, 0x46, 0x37, 0x28, 0x5b, - 0x85, 0xfe, 0xca, 0x4d, 0xfd, 0x95, 0xad, 0xc8, 0x92, 0xec, 0x53, 0xf6, - 0xe0, 0x28, 0xf9, 0x77, 0x1a, 0xef, 0xae, 0x4b, 0x84, 0x32, 0xa3, 0xf6, - 0x18, 0xf7, 0xfb, 0x97, 0x38, 0xdf, 0x26, 0xde, 0x4e, 0xc3, 0xc6, 0x71, - 0x7f, 0x61, 0x8d, 0xe3, 0x7c, 0x7e, 0xc8, 0xd0, 0xe4, 0x48, 0x4e, 0xdd, - 0x7f, 0x63, 0x4f, 0xa8, 0x3f, 0xb1, 0x9f, 0x41, 0xdb, 0x8b, 0x6a, 0x8e, - 0x76, 0x36, 0x0b, 0xde, 0x34, 0xd3, 0xc8, 0x79, 0x67, 0xb1, 0xc6, 0xa1, - 0x0e, 0x0b, 0xd7, 0x8a, 0xb8, 0xc6, 0xb1, 0x16, 0x2a, 0x5d, 0xb0, 0x8f, - 0x31, 0x63, 0x83, 0xd9, 0x7e, 0x11, 0xed, 0xf9, 0x9c, 0x6d, 0xbb, 0x60, - 0x8f, 0xd9, 0x7e, 0xd1, 0xb4, 0xdf, 0xb1, 0xcb, 0xdc, 0x2b, 0xb4, 0xc9, - 0x57, 0x32, 0xc0, 0x42, 0x2b, 0xb6, 0x14, 0x7c, 0xe0, 0x1c, 0xbf, 0xdf, - 0xec, 0x0b, 0x2d, 0x9b, 0x1f, 0x75, 0x2c, 0x69, 0xf7, 0x76, 0x93, 0xcd, - 0x7f, 0xb0, 0xb5, 0xad, 0xdb, 0x91, 0xcd, 0x05, 0xe8, 0xa8, 0x53, 0x90, - 0x95, 0xc5, 0xed, 0x7a, 0x94, 0x4b, 0x25, 0xa3, 0x90, 0xcd, 0xd4, 0x38, - 0xa7, 0x79, 0xa5, 0xd1, 0x2c, 0xa3, 0x61, 0x1f, 0x31, 0x25, 0x07, 0x7a, - 0x9c, 0xc5, 0xa6, 0x71, 0x16, 0x9b, 0xc6, 0x59, 0x32, 0xd8, 0x8e, 0xfd, - 0x68, 0xbb, 0x7a, 0xfd, 0x26, 0x7b, 0xce, 0x35, 0xfb, 0x24, 0xf6, 0xa4, - 0x96, 0x05, 0x60, 0x35, 0xbd, 0x06, 0x15, 0x57, 0xe6, 0x37, 0x2e, 0x84, - 0x7b, 0xb5, 0xdc, 0x8e, 0xe7, 0x3f, 0xc4, 0xf3, 0xe1, 0x33, 0x2e, 0xec, - 0x14, 0xb1, 0xda, 0x4b, 0x72, 0xae, 0x42, 0x19, 0x79, 0x11, 0x74, 0xa7, - 0xfd, 0x36, 0x8b, 0x7c, 0x4d, 0x0d, 0x9f, 0x97, 0x54, 0x72, 0x5e, 0x46, - 0x7c, 0x96, 0x4f, 0x88, 0xc2, 0x58, 0xa2, 0x31, 0xd0, 0x8b, 0x90, 0x3f, - 0x91, 0x1f, 0x57, 0xda, 0xc5, 0x1e, 0xfb, 0x61, 0x40, 0x3b, 0x78, 0x7a, - 0xa3, 0xb5, 0x1f, 0x91, 0xa1, 0x33, 0xaa, 0x1f, 0xf4, 0x91, 0xf6, 0xbf, - 0xad, 0xfa, 0x0b, 0xfb, 0xc2, 0x3c, 0xc7, 0x5a, 0xfb, 0x73, 0xe4, 0xba, - 0x6b, 0xa3, 0xbf, 0xb4, 0x99, 0x23, 0xaf, 0x21, 0x23, 0xae, 0x83, 0xf2, - 0x61, 0x3b, 0x94, 0x19, 0x7b, 0xec, 0x3b, 0x41, 0x6e, 0x9a, 0x73, 0x2b, - 0x99, 0x67, 0xff, 0xc3, 0xc8, 0x9b, 0x54, 0xed, 0x2c, 0x78, 0x96, 0x19, - 0xc4, 0x78, 0xbc, 0x4f, 0x02, 0x1f, 0x49, 0x99, 0xf8, 0xac, 0x54, 0xf9, - 0x65, 0x90, 0x73, 0x34, 0xa6, 0xd2, 0x6b, 0xcf, 0xf7, 0x96, 0x14, 0x50, - 0x77, 0xc1, 0xe8, 0x83, 0x62, 0xe3, 0xba, 0xe2, 0xdf, 0xf3, 0x6a, 0x1f, - 0xa5, 0x4e, 0x97, 0xa9, 0x37, 0x36, 0xdc, 0x08, 0xf7, 0xf8, 0x25, 0xff, - 0xa5, 0x60, 0x61, 0x39, 0x95, 0x4c, 0xda, 0x83, 0x52, 0xaa, 0x0e, 0x96, - 0x6d, 0x94, 0x27, 0x6a, 0x09, 0x39, 0x51, 0x61, 0x3f, 0xfb, 0x51, 0x07, - 0x8a, 0xc8, 0xc6, 0x26, 0xef, 0xa3, 0xae, 0xe1, 0x98, 0x6f, 0x5b, 0x7a, - 0x4c, 0xcc, 0xc1, 0xdb, 0xb4, 0xfe, 0x63, 0xe3, 0x8a, 0x55, 0xaa, 0x71, - 0xfd, 0xf1, 0xbc, 0xd1, 0xac, 0x8f, 0x42, 0x5d, 0xb4, 0x83, 0xc5, 0x22, - 0xd9, 0x45, 0xab, 0xb4, 0x22, 0x76, 0xde, 0x8f, 0x12, 0x0f, 0x26, 0x45, - 0xee, 0x75, 0xf5, 0x3c, 0x3f, 0x19, 0xa1, 0x1e, 0x74, 0xbc, 0xd3, 0xe8, - 0xbb, 0x53, 0x72, 0x0e, 0xd7, 0x9f, 0xd7, 0x12, 0x44, 0xb2, 0x1e, 0x6d, - 0xa5, 0x13, 0xc9, 0x3a, 0xd8, 0x63, 0xac, 0xf3, 0x52, 0xc0, 0xbd, 0x90, - 0xaf, 0x6a, 0x19, 0x29, 0xef, 0x60, 0x2f, 0xd0, 0x9b, 0x83, 0x8e, 0x11, - 0x1b, 0x7b, 0xcc, 0x8d, 0x64, 0xf9, 0x7c, 0x1c, 0xd7, 0x9b, 0xa8, 0x4f, - 0x1d, 0x0b, 0x4c, 0x5a, 0x53, 0xbc, 0xc3, 0x58, 0x39, 0xab, 0x58, 0x09, - 0x79, 0xf2, 0x52, 0xf0, 0xe4, 0x72, 0x88, 0x11, 0x94, 0x6c, 0xc9, 0xc0, - 0xd9, 0xa4, 0xd9, 0xd7, 0x5d, 0xdc, 0x73, 0xe4, 0x3f, 0x9e, 0xf9, 0xe6, - 0x59, 0x7b, 0xd3, 0xb3, 0x70, 0xff, 0x7f, 0x09, 0xb4, 0xf5, 0x2b, 0xfe, - 0xd8, 0xd9, 0x23, 0x56, 0x5e, 0xe1, 0x93, 0x20, 0x28, 0x78, 0x51, 0x29, - 0x8d, 0xfe, 0x09, 0xe6, 0xca, 0x77, 0x65, 0x30, 0x9c, 0x76, 0x63, 0x78, - 0x72, 0xd6, 0x4b, 0x29, 0xfb, 0x9f, 0xc7, 0xfe, 0xd3, 0x3a, 0x53, 0xca, - 0x3d, 0xa0, 0xdd, 0x5b, 0xe2, 0x9a, 0xbc, 0x14, 0x9c, 0x05, 0x16, 0x9e, - 0x5e, 0x2a, 0x5a, 0x03, 0xd8, 0x12, 0x76, 0x9f, 0x05, 0x3e, 0x77, 0x49, - 0xfe, 0x22, 0xd7, 0x82, 0x75, 0xf8, 0xbc, 0x4d, 0xa6, 0xe3, 0xad, 0xb6, - 0xf2, 0xdc, 0x3e, 0xe9, 0x24, 0xbf, 0x51, 0x77, 0xe9, 0xff, 0x46, 0xb4, - 0x5e, 0x76, 0x65, 0x60, 0x95, 0x7c, 0x2f, 0x5a, 0xb3, 0x15, 0xea, 0xb1, - 0x0e, 0xd8, 0x47, 0x3e, 0x67, 0x9f, 0x78, 0x77, 0xbe, 0xb5, 0x8f, 0xdf, - 0x8b, 0xe8, 0x3e, 0xd8, 0x2e, 0xec, 0xa3, 0x99, 0x1f, 0x7b, 0x94, 0x9e, - 0xeb, 0xcd, 0xf6, 0xb6, 0xf4, 0x9b, 0x68, 0xea, 0x17, 0xef, 0xce, 0x7f, - 0x37, 0x42, 0x5c, 0xf6, 0xf2, 0x32, 0xf8, 0xac, 0xe6, 0xc4, 0x77, 0x6c, - 0x53, 0xb4, 0x0a, 0x4b, 0x41, 0x30, 0xed, 0xdb, 0x12, 0xe9, 0x0b, 0xeb, - 0xea, 0x79, 0x15, 0x31, 0xaf, 0x3c, 0xe6, 0x65, 0xf7, 0xb5, 0xd2, 0xf4, - 0xfb, 0x86, 0xa6, 0xde, 0x26, 0x9a, 0xe2, 0xef, 0x31, 0xaf, 0xf8, 0x2e, - 0xf3, 0x7a, 0xa9, 0x57, 0xf7, 0x11, 0x6f, 0xea, 0xa3, 0xaf, 0xa5, 0x0f, - 0xe8, 0xfd, 0x38, 0xdb, 0xf7, 0xed, 0xd2, 0xfe, 0x87, 0x1d, 0xba, 0x3d, - 0xdb, 0xb4, 0x41, 0xb7, 0xf7, 0x1b, 0xbd, 0x78, 0xa2, 0x49, 0x97, 0x9d, - 0x80, 0x2e, 0x6b, 0x6e, 0xd3, 0x2c, 0xff, 0xa1, 0x8f, 0x44, 0xff, 0x28, - 0xc4, 0x8a, 0x1f, 0x50, 0x18, 0x64, 0x07, 0x63, 0xc7, 0x80, 0x47, 0xba, - 0x60, 0xff, 0xbb, 0xe9, 0x07, 0x19, 0x4c, 0x48, 0xbf, 0x88, 0x38, 0x50, - 0x3c, 0xa0, 0x28, 0xe8, 0x96, 0xc1, 0xc4, 0x31, 0x11, 0xe5, 0x07, 0x11, - 0x5f, 0xd3, 0x27, 0xe2, 0x38, 0xf4, 0x89, 0xb8, 0xee, 0xbc, 0x2f, 0x6c, - 0xfb, 0x48, 0xfd, 0xd8, 0xf7, 0xc4, 0xc7, 0xdc, 0x33, 0xa1, 0xad, 0x69, - 0xd6, 0xa7, 0xbb, 0xd1, 0xd4, 0xdf, 0x42, 0x13, 0x74, 0x12, 0x7c, 0xb3, - 0x05, 0xc8, 0x23, 0x30, 0x29, 0x74, 0xe0, 0xfd, 0x53, 0xe7, 0x56, 0x44, - 0x4a, 0x0d, 0xda, 0xc7, 0x51, 0x81, 0x5f, 0x05, 0xba, 0xd8, 0xb7, 0xb2, - 0x91, 0xd0, 0x4d, 0xdd, 0x39, 0x3b, 0x3b, 0x08, 0x3f, 0xdc, 0x91, 0x39, - 0x43, 0xdb, 0x8c, 0xf2, 0xe1, 0xba, 0x50, 0x26, 0x94, 0x5c, 0xcd, 0x80, - 0x3e, 0x5e, 0xcf, 0x18, 0xec, 0x7e, 0xac, 0xd1, 0x4a, 0xdb, 0xf7, 0x40, - 0x9b, 0x07, 0x1a, 0x92, 0xf2, 0x02, 0xb0, 0xfb, 0x37, 0xd5, 0xbe, 0x0c, - 0x75, 0x17, 0x65, 0x29, 0x55, 0x2d, 0xcb, 0x66, 0xb0, 0xb2, 0xcc, 0x7d, - 0x4b, 0x1b, 0xde, 0x25, 0x65, 0xac, 0xd7, 0xc0, 0x52, 0x2a, 0x99, 0xb3, - 0xc5, 0x7a, 0xdf, 0x41, 0xca, 0xd3, 0xe3, 0x32, 0x70, 0x51, 0x2c, 0x67, - 0x09, 0x7b, 0xbd, 0x3b, 0xc4, 0x57, 0x9c, 0xdf, 0x6f, 0x63, 0x7e, 0xe8, - 0x7b, 0x39, 0x9c, 0x5f, 0x97, 0x94, 0x56, 0x39, 0xbf, 0xed, 0xb9, 0xc5, - 0x19, 0x11, 0xf9, 0x1c, 0xf4, 0x35, 0xe6, 0x08, 0x1a, 0xc7, 0x81, 0x73, - 0xef, 0x30, 0x73, 0xea, 0xc2, 0x9c, 0x60, 0xa3, 0x97, 0xd8, 0x1e, 0x74, - 0x81, 0xe6, 0x12, 0xea, 0xcd, 0x2f, 0x71, 0xcd, 0x41, 0x2b, 0xd6, 0xbd, - 0xd4, 0xe0, 0xda, 0x73, 0x6e, 0xda, 0xae, 0x3b, 0x1e, 0xe7, 0xc7, 0x79, - 0x0e, 0x63, 0x5e, 0xac, 0xc3, 0x76, 0xad, 0x32, 0x32, 0xfc, 0x1e, 0xeb, - 0xf1, 0xdb, 0x2d, 0xeb, 0x21, 0x66, 0x3d, 0x62, 0xd2, 0xb6, 0xaa, 0xfc, - 0x65, 0x45, 0x03, 0x7d, 0x08, 0x07, 0xf4, 0x2f, 0xae, 0xc8, 0x68, 0x54, - 0x48, 0x7b, 0x82, 0xcf, 0x32, 0x6d, 0x32, 0xe8, 0x5f, 0x81, 0x5c, 0x95, - 0x20, 0x0b, 0xf4, 0x07, 0x5e, 0x5e, 0xd6, 0x6b, 0x51, 0x6a, 0x74, 0xc2, - 0x47, 0xe7, 0xf8, 0xe4, 0x37, 0xe7, 0xe6, 0xaa, 0x75, 0x68, 0x5e, 0x97, - 0x4f, 0xdf, 0xb2, 0x2e, 0xd4, 0xbb, 0xd4, 0x03, 0xc4, 0x3d, 0xd4, 0x05, - 0x61, 0x4c, 0xa0, 0xe6, 0xea, 0xfd, 0x14, 0xda, 0x9f, 0xeb, 0xdb, 0xf8, - 0x52, 0xaf, 0x59, 0xc2, 0xc4, 0x05, 0xba, 0xc4, 0x5e, 0xbd, 0x83, 0x7a, - 0x1f, 0xf6, 0x27, 0x9c, 0xdf, 0xef, 0xe0, 0x3e, 0x71, 0xd3, 0x7a, 0xd8, - 0x98, 0x93, 0xa3, 0xe6, 0xa8, 0xd6, 0x62, 0x5b, 0xe6, 0xe6, 0x1a, 0x7a, - 0x5e, 0xce, 0xd2, 0x1e, 0xb3, 0x1e, 0x31, 0x3c, 0xe3, 0xbc, 0x42, 0x9b, - 0xc3, 0x79, 0x91, 0x5e, 0xd7, 0xc8, 0x1c, 0xe7, 0xc3, 0xfd, 0xd7, 0x2c, - 0x6b, 0x2f, 0x05, 0xd5, 0xe5, 0xa8, 0x9a, 0x7b, 0xde, 0xef, 0x26, 0x46, - 0xa3, 0x8e, 0x34, 0xfa, 0x89, 0xcf, 0x69, 0x07, 0xf1, 0x2e, 0x43, 0x19, - 0xc2, 0x7d, 0x9d, 0xf7, 0xcd, 0x36, 0xed, 0x79, 0x47, 0xeb, 0x01, 0xc6, - 0x9f, 0xde, 0xdb, 0xd6, 0x45, 0xb3, 0x62, 0xad, 0x57, 0xe8, 0x33, 0x07, - 0xc0, 0x5d, 0x77, 0x40, 0xaf, 0x1c, 0x92, 0x92, 0x0b, 0x7b, 0x3d, 0x7c, - 0x3b, 0xe6, 0x3c, 0x2e, 0x2a, 0xde, 0x30, 0xbc, 0x17, 0xd7, 0x7b, 0x94, - 0xef, 0x52, 0x1a, 0xfe, 0x90, 0xe4, 0xa6, 0x69, 0xd3, 0x7e, 0x5f, 0x66, - 0x60, 0x5b, 0x4b, 0xc3, 0x77, 0x82, 0x3e, 0xde, 0x43, 0x27, 0x7a, 0x43, - 0x8c, 0x51, 0xe0, 0xef, 0x71, 0x13, 0x9b, 0x39, 0x80, 0xfb, 0x3d, 0xa8, - 0xf3, 0x49, 0x53, 0xa7, 0x1b, 0x75, 0x06, 0x5b, 0xea, 0x70, 0xbc, 0xfb, - 0x50, 0x07, 0xf6, 0x14, 0x56, 0xd2, 0xf6, 0x0e, 0xe2, 0x37, 0x81, 0x67, - 0xf7, 0xe2, 0xd9, 0x3d, 0x78, 0x76, 0x0f, 0xee, 0x7f, 0xd7, 0xc4, 0x3c, - 0xc2, 0x36, 0xdd, 0xb8, 0xff, 0x12, 0xde, 0x43, 0xc7, 0xb9, 0xdf, 0xc6, - 0xfb, 0xfb, 0xf0, 0x1b, 0x6b, 0xa9, 0xe3, 0xb6, 0xdc, 0x9f, 0x76, 0x74, - 0x8c, 0x84, 0xcf, 0x82, 0xc8, 0xce, 0xf5, 0x7f, 0x35, 0xcf, 0xbd, 0xa6, - 0xf7, 0x1f, 0x37, 0xd7, 0xad, 0xb2, 0x94, 0x86, 0x2c, 0xf1, 0xfd, 0x57, - 0xf6, 0xe9, 0xb5, 0xb8, 0x43, 0xc7, 0x1f, 0x6e, 0xc2, 0x1b, 0x4a, 0xfc, - 0x71, 0xbd, 0x09, 0x9c, 0x41, 0xec, 0xd1, 0x8c, 0x3b, 0x48, 0x8b, 0xab, - 0xe4, 0xf5, 0xe5, 0xe5, 0xd7, 0xba, 0xf5, 0x18, 0x62, 0xd5, 0x21, 0x73, - 0x13, 0x2a, 0x16, 0xf1, 0x33, 0xf3, 0xcc, 0xdb, 0xb7, 0xf3, 0x6e, 0xaf, - 0x4c, 0x54, 0xff, 0x68, 0xdf, 0x0e, 0x6d, 0x93, 0x4d, 0xd7, 0x3b, 0x98, - 0x02, 0xfe, 0x84, 0xbd, 0x83, 0x77, 0x72, 0xf6, 0x5c, 0xa3, 0x68, 0xeb, - 0x71, 0x59, 0x07, 0xef, 0x1a, 0x9b, 0x3d, 0x8e, 0x92, 0xfd, 0x9c, 0x4d, - 0x5f, 0xa3, 0xbc, 0xc6, 0xeb, 0xdb, 0x51, 0x36, 0xb7, 0xed, 0x87, 0x1e, - 0xcf, 0xd9, 0x9a, 0xee, 0xd6, 0xf6, 0xe1, 0xbe, 0xf1, 0x65, 0xa1, 0x0a, - 0x99, 0xf3, 0x52, 0xc3, 0x65, 0xac, 0xdd, 0xac, 0x9f, 0x9a, 0xa6, 0x4c, - 0xc2, 0x9f, 0xfd, 0x94, 0xc8, 0xa4, 0xcc, 0x57, 0x1f, 0x06, 0xfe, 0x0e, - 0xe4, 0x21, 0xe0, 0x8a, 0x7f, 0x0f, 0x5c, 0x52, 0x83, 0xac, 0xd7, 0x1a, - 0x1e, 0x7e, 0xfd, 0xf2, 0x57, 0x95, 0x84, 0x3c, 0x07, 0x7f, 0x02, 0xb2, - 0x06, 0x3d, 0x9c, 0x76, 0x1f, 0x12, 0xe9, 0xb1, 0xe5, 0xf2, 0xbd, 0xb6, - 0x8c, 0x24, 0x07, 0xac, 0x74, 0x02, 0x3f, 0xb7, 0x0d, 0xbf, 0x22, 0x7c, - 0xb8, 0xb5, 0x06, 0x63, 0x01, 0x71, 0xf9, 0xeb, 0xf5, 0x24, 0x7e, 0x7d, - 0xf2, 0x37, 0xeb, 0x1c, 0x7f, 0xc0, 0x94, 0x6a, 0x1f, 0xc3, 0xe7, 0x28, - 0xcb, 0x62, 0x26, 0x21, 0x0b, 0x95, 0xe0, 0xa4, 0xf6, 0x99, 0x3d, 0xf8, - 0xc8, 0xdc, 0xb3, 0x2f, 0x60, 0xcf, 0xe2, 0xb9, 0xc2, 0x9e, 0xa1, 0xdd, - 0x7b, 0x01, 0x76, 0x2f, 0x5c, 0x23, 0xce, 0xb3, 0x75, 0x7d, 0xd8, 0x2f, - 0xd7, 0x88, 0x7a, 0x9d, 0xba, 0x3c, 0x06, 0xfc, 0x10, 0xea, 0x76, 0xea, - 0x08, 0x6f, 0xdb, 0x0f, 0x7d, 0xe4, 0x60, 0x17, 0xb0, 0x86, 0xc4, 0xe2, - 0xd9, 0x9f, 0xca, 0xca, 0x59, 0xee, 0x1b, 0xda, 0xe3, 0xbb, 0x21, 0x6f, - 0xa9, 0xaf, 0x96, 0x89, 0x99, 0xbd, 0x0c, 0xf8, 0x51, 0x96, 0xe9, 0x83, - 0xab, 0xbd, 0x5a, 0x4e, 0x26, 0xc5, 0x39, 0xfb, 0x85, 0xa8, 0x74, 0x9f, - 0x94, 0x45, 0x1f, 0x7e, 0xa9, 0x5d, 0x0e, 0x22, 0x9e, 0x97, 0x28, 0x28, - 0xbf, 0x69, 0x05, 0x74, 0xc6, 0x64, 0xe2, 0x2c, 0xeb, 0x9c, 0x84, 0x8c, - 0xb5, 0x81, 0xe6, 0x76, 0x39, 0x15, 0x4f, 0x95, 0x0b, 0xf0, 0xf7, 0x6d, - 0xaf, 0x47, 0x06, 0xea, 0x2c, 0x89, 0x41, 0xfe, 0x37, 0xe4, 0x87, 0xd7, - 0xf0, 0x03, 0x57, 0xf9, 0x7c, 0x00, 0x25, 0x9f, 0x7b, 0xd0, 0x2f, 0xe4, - 0x07, 0x70, 0xc3, 0xc5, 0xb2, 0x9c, 0xca, 0x4c, 0x4a, 0xbd, 0x2a, 0xd6, - 0x42, 0x06, 0x7b, 0xa0, 0x96, 0x95, 0x3a, 0x78, 0x51, 0x6a, 0x1c, 0x87, - 0xdf, 0xf9, 0x26, 0xca, 0x39, 0x94, 0xd7, 0x51, 0x3e, 0x8e, 0xf2, 0x2d, - 0x94, 0xa4, 0xfd, 0xb8, 0xd4, 0x6b, 0x7b, 0xda, 0xa4, 0x93, 0x7d, 0x6c, - 0x18, 0x9a, 0xe1, 0x3b, 0x1e, 0x3c, 0x0e, 0x2c, 0x1a, 0x3e, 0x3f, 0x2e, - 0x52, 0xff, 0x0c, 0x7e, 0x0f, 0xaa, 0x7b, 0xfa, 0x96, 0x0b, 0x99, 0x71, - 0xe0, 0x7a, 0xb1, 0x4e, 0x65, 0x1e, 0x37, 0xfd, 0x7c, 0x06, 0xe3, 0x5d, - 0xc5, 0xd8, 0x31, 0xc8, 0x48, 0x20, 0x8f, 0xf8, 0x27, 0xe5, 0x73, 0xfe, - 0x7e, 0x19, 0xeb, 0x8d, 0x95, 0x63, 0x59, 0xce, 0x9f, 0x7a, 0x6a, 0xb7, - 0xf9, 0x87, 0xf3, 0xe6, 0x9c, 0xa1, 0x5b, 0x97, 0xf6, 0x6a, 0xdc, 0x6d, - 0x7f, 0x39, 0xaa, 0x69, 0xb1, 0x64, 0x60, 0x88, 0xfd, 0x65, 0x25, 0x72, - 0x76, 0xc8, 0xcd, 0xd8, 0x23, 0xf0, 0x52, 0xd2, 0xf8, 0x9d, 0x84, 0xfc, - 0x79, 0xa7, 0x07, 0xec, 0xdb, 0x40, 0x13, 0xde, 0xd5, 0x39, 0x0e, 0xec, - 0xe9, 0x3d, 0xaf, 0x62, 0x6e, 0x65, 0x69, 0xbf, 0x27, 0x2b, 0x37, 0x1a, - 0xbc, 0x86, 0x3d, 0xba, 0x30, 0x29, 0xff, 0x5c, 0xbd, 0x2a, 0x4f, 0x54, - 0x27, 0xe5, 0x0d, 0x94, 0x8b, 0xd5, 0x32, 0xf8, 0xc8, 0x58, 0x3c, 0xfb, - 0x08, 0xb0, 0x2e, 0x83, 0xf0, 0x8d, 0x3e, 0x98, 0x98, 0xc3, 0xfa, 0xcd, - 0xb8, 0x81, 0x9c, 0xf3, 0xcb, 0x72, 0x6e, 0x1c, 0x6d, 0x6a, 0x1d, 0x12, - 0x7d, 0x96, 0xf3, 0xed, 0x96, 0x02, 0x2c, 0x7a, 0x31, 0x43, 0x9d, 0xd9, - 0x29, 0x85, 0x5a, 0xab, 0xdc, 0x51, 0xde, 0xde, 0xb6, 0xea, 0xdb, 0x3a, - 0x60, 0xd3, 0xfa, 0x66, 0x83, 0x36, 0x78, 0x37, 0x7b, 0xaa, 0xe5, 0xae, - 0x5e, 0xa3, 0x4d, 0xdd, 0x91, 0xbd, 0x3a, 0xfc, 0xb9, 0x7a, 0xf5, 0xba, - 0x91, 0x3f, 0x25, 0xb7, 0x58, 0x17, 0x62, 0xf1, 0x9f, 0x08, 0xb0, 0x1f, - 0x78, 0x14, 0xc6, 0x09, 0xb5, 0x7f, 0x54, 0x03, 0xad, 0x85, 0x38, 0x71, - 0x06, 0xac, 0x5b, 0xed, 0x0b, 0x8a, 0x57, 0xde, 0xd9, 0x7e, 0xa9, 0x2e, - 0x93, 0xbf, 0x29, 0xd7, 0xb6, 0x95, 0x4f, 0x02, 0xbe, 0x7a, 0x58, 0x9f, - 0xf0, 0x7d, 0x0a, 0x7e, 0xd2, 0x49, 0x71, 0xc7, 0x3a, 0x31, 0x27, 0x5e, - 0x8b, 0x4c, 0x5f, 0x6c, 0xc5, 0x91, 0xa1, 0x9d, 0x68, 0x83, 0x3f, 0x1e, - 0xc5, 0x5a, 0x76, 0xc1, 0x9f, 0x86, 0x9f, 0x0a, 0x39, 0xfa, 0x33, 0x60, - 0xaf, 0xd3, 0xca, 0xb7, 0xe6, 0x9e, 0xea, 0x9e, 0x1a, 0x58, 0x67, 0xb9, - 0x77, 0x2a, 0x5d, 0x63, 0x19, 0x9f, 0xd2, 0xbe, 0x64, 0x62, 0x4a, 0xc7, - 0xed, 0x93, 0x53, 0x07, 0x54, 0xe9, 0x4d, 0x0d, 0xab, 0x72, 0x78, 0x6a, - 0x27, 0x66, 0x42, 0x9e, 0x8a, 0x95, 0xcf, 0x64, 0xa4, 0x58, 0x21, 0x8d, - 0xe2, 0x1c, 0x83, 0x3c, 0xcd, 0x01, 0xcb, 0xe4, 0x2b, 0xbe, 0x9c, 0xda, - 0xc8, 0x82, 0x66, 0xe8, 0x99, 0xac, 0x8f, 0x52, 0xcc, 0x5f, 0xd8, 0xb6, - 0x8d, 0x31, 0x32, 0xae, 0x99, 0xf1, 0x33, 0x7d, 0xfa, 0x99, 0xcd, 0x7f, - 0xec, 0x0f, 0xb2, 0x49, 0xfb, 0xf9, 0x0b, 0xf8, 0xc6, 0xe2, 0x94, 0x32, - 0x6c, 0xeb, 0xc3, 0x07, 0x17, 0xd9, 0x5a, 0x91, 0x58, 0x2c, 0xfb, 0x1d, - 0x89, 0x3d, 0x1d, 0x04, 0x3f, 0xf0, 0x53, 0x47, 0xca, 0x02, 0x5e, 0x59, - 0x78, 0xbe, 0xce, 0x77, 0xd4, 0x4d, 0x23, 0xee, 0x0d, 0xc8, 0x5c, 0xee, - 0xa8, 0xc8, 0x2b, 0x78, 0x56, 0x5f, 0xe1, 0x1a, 0x7c, 0x17, 0x6b, 0x60, - 0xd6, 0x44, 0x3d, 0x63, 0x3d, 0xf8, 0x58, 0x71, 0xce, 0x63, 0xc4, 0x6d, - 0x47, 0xfb, 0xda, 0x3a, 0xdb, 0xa4, 0xc6, 0x79, 0xe4, 0xf5, 0xca, 0xba, - 0x9e, 0xdf, 0xe1, 0xcc, 0xb0, 0x5c, 0xae, 0xa8, 0x3e, 0x20, 0xeb, 0xbf, - 0x44, 0x9b, 0x4d, 0xc8, 0x2d, 0x63, 0x53, 0x59, 0x99, 0x07, 0x4e, 0x9b, - 0xaf, 0xa4, 0x21, 0x3b, 0x8e, 0xcc, 0x24, 0x48, 0xb6, 0x27, 0x5b, 0x95, - 0x37, 0xdb, 0x88, 0x85, 0xf3, 0x1e, 0xaf, 0xc7, 0x51, 0x67, 0x5a, 0x88, - 0xb7, 0xf2, 0x19, 0xce, 0xa9, 0x99, 0x17, 0xfa, 0xaf, 0x84, 0xb5, 0x30, - 0x73, 0x54, 0x7f, 0x7a, 0x1c, 0xb4, 0x37, 0xe3, 0x14, 0x01, 0x53, 0xe0, - 0x6b, 0x4a, 0xfa, 0x82, 0xe3, 0xe4, 0x2b, 0x8e, 0x0c, 0x5c, 0xc0, 0xb6, - 0xca, 0x1a, 0x5e, 0x34, 0x42, 0x59, 0x0b, 0x31, 0x10, 0x65, 0x8b, 0x3c, - 0x48, 0x95, 0x37, 0xc1, 0xec, 0xde, 0xec, 0x35, 0x79, 0x74, 0x55, 0xcf, - 0xd9, 0x3e, 0x2f, 0x3c, 0x0b, 0x91, 0x1b, 0x2b, 0x29, 0xff, 0x3a, 0xf4, - 0x7d, 0x21, 0xee, 0x43, 0x56, 0xfe, 0x4b, 0x1b, 0xf6, 0xf4, 0x78, 0xce, - 0xde, 0xdf, 0xae, 0x6d, 0xac, 0x83, 0x3d, 0x01, 0xac, 0x59, 0xc9, 0xa1, - 0x4d, 0xbb, 0xfc, 0x5b, 0x07, 0xd7, 0xc4, 0x9e, 0x78, 0x66, 0xec, 0x22, - 0xae, 0x75, 0x7f, 0xf3, 0x98, 0x87, 0x8e, 0x03, 0x5b, 0xf2, 0x28, 0x2c, - 0x88, 0xa0, 0xff, 0x01, 0x33, 0xd6, 0xc0, 0xf9, 0x50, 0x36, 0x40, 0xf7, - 0x6a, 0x16, 0xf8, 0xdd, 0x31, 0x7e, 0x2b, 0x75, 0x8c, 0xec, 0xe2, 0xf7, - 0x34, 0xc7, 0x5e, 0x63, 0x2a, 0x4e, 0x47, 0x2c, 0x47, 0xd9, 0x3a, 0x62, - 0x64, 0xeb, 0x33, 0x90, 0xad, 0xe3, 0x4a, 0xb6, 0x02, 0xf9, 0x81, 0xef, - 0xcb, 0x97, 0x77, 0x95, 0xaf, 0xd6, 0xbf, 0x2e, 0xd0, 0xcb, 0x5f, 0x9f, - 0x2c, 0xfc, 0x05, 0xc6, 0xbd, 0xe0, 0xe2, 0x3a, 0x95, 0x9b, 0x11, 0xf2, - 0x31, 0x81, 0xeb, 0x18, 0xca, 0x7e, 0x55, 0x67, 0xe0, 0x02, 0xec, 0x1a, - 0xe4, 0x8d, 0xfc, 0x9d, 0x87, 0x8d, 0x1b, 0xb8, 0x10, 0x85, 0x2d, 0xe4, - 0x9e, 0x95, 0x5e, 0x1b, 0xba, 0x81, 0xf5, 0xeb, 0xd8, 0x3b, 0x03, 0x17, - 0xba, 0x50, 0x26, 0x55, 0x5f, 0xf5, 0x8a, 0xa7, 0xda, 0xd7, 0x2b, 0xc3, - 0xaa, 0x5d, 0xbd, 0x32, 0x8a, 0x12, 0xfa, 0x3d, 0xe3, 0xcb, 0xd0, 0x85, - 0x8c, 0x24, 0x2f, 0x58, 0x52, 0x9a, 0x0e, 0x82, 0x18, 0x68, 0x1f, 0xbe, - 0xd0, 0x23, 0xd7, 0xa7, 0x39, 0x37, 0xea, 0x62, 0xb1, 0x16, 0x33, 0xd3, - 0xd8, 0x9b, 0xe4, 0x1f, 0xb0, 0xfe, 0x85, 0x22, 0x6c, 0x6e, 0x51, 0x4e, - 0xad, 0x90, 0x3f, 0x8c, 0xb5, 0x6f, 0x25, 0x22, 0x92, 0x82, 0x2e, 0x3b, - 0x2a, 0x73, 0xd5, 0x76, 0xe8, 0x32, 0xc7, 0xad, 0xcb, 0x13, 0x58, 0xa3, - 0x41, 0xca, 0x03, 0xf8, 0x92, 0x45, 0xdf, 0x45, 0x29, 0xa0, 0x4d, 0x71, - 0x65, 0xa7, 0x7e, 0x49, 0xda, 0xb1, 0xa7, 0x8e, 0xca, 0xb1, 0x2a, 0xfb, - 0x71, 0xdc, 0x79, 0x39, 0x00, 0x19, 0xf2, 0xdc, 0x09, 0xf4, 0x03, 0x1b, - 0xd9, 0xf4, 0xc7, 0xfd, 0x97, 0x7b, 0x0f, 0x99, 0x0c, 0xf7, 0x5d, 0xac, - 0xdc, 0x96, 0x9d, 0xb6, 0xb6, 0x32, 0xe2, 0xcc, 0x66, 0x1e, 0xb2, 0x5e, - 0xc9, 0x64, 0xac, 0x2b, 0x99, 0x9c, 0x75, 0x35, 0x53, 0xb4, 0xae, 0xc1, - 0x36, 0xd5, 0x37, 0xde, 0x81, 0xfc, 0x00, 0x4f, 0x10, 0x7b, 0x6f, 0xaf, - 0x61, 0xdc, 0xf8, 0x39, 0x6f, 0xc9, 0xb9, 0x0a, 0xed, 0x74, 0x70, 0x68, - 0xd6, 0x2f, 0xdf, 0x0e, 0xfa, 0x40, 0x07, 0xe3, 0x11, 0x3b, 0xb6, 0x23, - 0x9a, 0x1d, 0x06, 0x4e, 0xa0, 0xed, 0xe8, 0xa2, 0xed, 0xf0, 0x0b, 0xb2, - 0x57, 0xb6, 0xaa, 0x3a, 0x2e, 0x97, 0x07, 0x6e, 0xda, 0xaa, 0xc5, 0xe5, - 0xcb, 0xcb, 0xa1, 0x2c, 0x71, 0xbe, 0xf3, 0xef, 0xeb, 0x90, 0x88, 0x1c, - 0x51, 0xf6, 0xba, 0x5b, 0x2e, 0xaf, 0x03, 0xd3, 0x02, 0x81, 0xd8, 0x77, - 0x32, 0xce, 0x63, 0xab, 0xf8, 0x85, 0xf4, 0xf0, 0x3c, 0xf0, 0x1f, 0xc0, - 0x2b, 0x9e, 0xd9, 0x61, 0x9e, 0x3d, 0x9c, 0x51, 0x78, 0x3f, 0x8a, 0x3d, - 0xc9, 0x6b, 0x4b, 0x0a, 0xc0, 0xed, 0x5b, 0x15, 0x96, 0x09, 0x94, 0x26, - 0x56, 0x0f, 0x5d, 0x10, 0xc9, 0xfe, 0xa3, 0x7a, 0xdf, 0xee, 0x89, 0x35, - 0x0b, 0x3b, 0x5c, 0x5a, 0xa1, 0x4c, 0xa3, 0x5c, 0xd7, 0x63, 0x17, 0x7c, - 0x60, 0xe6, 0xd1, 0x0e, 0xda, 0x37, 0xe0, 0x27, 0xec, 0x7b, 0x85, 0xed, - 0x33, 0xd8, 0x73, 0x3f, 0x68, 0xa7, 0x6d, 0x3f, 0xec, 0x8f, 0xcb, 0xb5, - 0x0a, 0xaf, 0xf9, 0x3e, 0xe5, 0x8b, 0x8a, 0x1b, 0xc7, 0xa6, 0x16, 0x3d, - 0xdf, 0xec, 0x31, 0x15, 0xd3, 0xb1, 0x3e, 0x06, 0xcc, 0x38, 0x70, 0xa6, - 0x4d, 0xd2, 0x4f, 0xdb, 0x7d, 0xfa, 0x7c, 0xe5, 0x90, 0x14, 0xfd, 0x03, - 0x98, 0xc3, 0x3e, 0x99, 0x87, 0x2f, 0xb6, 0xb0, 0x31, 0x2c, 0xf3, 0xc3, - 0xf0, 0xb9, 0xdd, 0xbb, 0x89, 0xd5, 0xf0, 0xeb, 0xc0, 0xf3, 0x41, 0x94, - 0xed, 0x28, 0x6f, 0x97, 0xf9, 0xa7, 0xba, 0x63, 0xba, 0xbf, 0x68, 0xcb, - 0xfd, 0xb3, 0x1c, 0x3b, 0x99, 0xb4, 0x7e, 0x15, 0x2e, 0x6c, 0xc6, 0x84, - 0xa4, 0x23, 0x2a, 0xde, 0x93, 0x5d, 0x32, 0x78, 0xc6, 0x95, 0xa1, 0x33, - 0x09, 0x39, 0x70, 0xa6, 0x5f, 0x86, 0xcf, 0x24, 0xe5, 0xce, 0x33, 0x21, - 0xfe, 0xea, 0x9e, 0x4a, 0x1b, 0x5b, 0xe1, 0xfd, 0x9a, 0xb6, 0xe2, 0xce, - 0x86, 0xc6, 0xa8, 0xf3, 0x6b, 0xc4, 0x74, 0xaf, 0x62, 0xef, 0x6e, 0xaa, - 0xf3, 0xca, 0x4b, 0x1b, 0x41, 0x70, 0xc9, 0x6f, 0x77, 0xa7, 0x85, 0xfc, - 0xce, 0x00, 0x9f, 0xf9, 0xd0, 0x61, 0xa3, 0xd0, 0x61, 0xe3, 0xca, 0x36, - 0xd6, 0xbf, 0x2e, 0xd6, 0xb1, 0xcc, 0x03, 0xb2, 0x06, 0xd9, 0x7e, 0xd0, - 0x4f, 0x7d, 0x75, 0x53, 0xf1, 0x47, 0x62, 0x3d, 0xd0, 0x67, 0x77, 0xaf, - 0xb6, 0xcb, 0x1b, 0xf1, 0x20, 0x38, 0x0b, 0x1d, 0x50, 0xaf, 0x68, 0xf9, - 0xcd, 0x7b, 0xd4, 0x05, 0x0f, 0x61, 0xfe, 0xa3, 0x78, 0x96, 0x33, 0xba, - 0xbd, 0x43, 0x6e, 0xc4, 0x13, 0xb2, 0x7e, 0x60, 0xbc, 0xa5, 0x5e, 0x06, - 0xf7, 0xc0, 0x3d, 0x8d, 0xdf, 0x23, 0xbf, 0xf0, 0xdc, 0x95, 0x73, 0xf0, - 0x99, 0xcf, 0x1f, 0x48, 0x8d, 0x27, 0x6d, 0xea, 0xc3, 0xa4, 0xd4, 0xbe, - 0x9e, 0x90, 0xb5, 0x65, 0x6d, 0x97, 0x66, 0xbd, 0x71, 0x29, 0x00, 0xfb, - 0xae, 0x2d, 0x67, 0x51, 0xb2, 0x7e, 0xa8, 0x73, 0xb4, 0x5c, 0x16, 0x33, - 0x79, 0xec, 0x63, 0xee, 0x0f, 0x6d, 0x77, 0x6c, 0xbb, 0x1d, 0x72, 0xc4, - 0x3d, 0xf1, 0x30, 0x9e, 0xe7, 0xb1, 0xaf, 0x69, 0xc7, 0xd3, 0x90, 0xaf, - 0xcf, 0xc6, 0x28, 0x1f, 0x05, 0x9f, 0xf8, 0x9a, 0x6d, 0x52, 0x89, 0x34, - 0x9e, 0x4f, 0x4b, 0x5a, 0x9d, 0x0b, 0xcd, 0xfa, 0x61, 0x7f, 0x59, 0xa3, - 0x17, 0x22, 0x8c, 0x81, 0xe1, 0xef, 0x64, 0x8c, 0xf2, 0x18, 0xf1, 0xc2, - 0xe7, 0x23, 0xb0, 0x3d, 0x51, 0x35, 0xc6, 0xfc, 0x32, 0x9f, 0xa5, 0x5d, - 0xb6, 0x2f, 0xf8, 0xbc, 0x17, 0xf9, 0x44, 0x83, 0xf1, 0x9a, 0x98, 0x3c, - 0xda, 0xe8, 0x02, 0xbd, 0x6d, 0xbf, 0xc2, 0xf6, 0xec, 0xec, 0x73, 0x3b, - 0xbb, 0x95, 0x70, 0x95, 0x6e, 0xa1, 0x1e, 0xa1, 0x0e, 0x69, 0x17, 0x67, - 0x8c, 0xfb, 0x0c, 0x6b, 0xb2, 0x8c, 0x35, 0x5a, 0xc6, 0x1a, 0x2d, 0x63, - 0x8d, 0x96, 0xb1, 0x7e, 0xcb, 0xd4, 0x2d, 0x83, 0xd8, 0xcf, 0x39, 0x73, - 0x86, 0x40, 0xfd, 0xf2, 0x1c, 0xd6, 0x76, 0x5a, 0xfe, 0x76, 0x63, 0x52, - 0xfe, 0xf3, 0xc6, 0x11, 0xe0, 0xee, 0x22, 0xd6, 0x35, 0x87, 0x75, 0xcd, - 0x62, 0x5d, 0x8f, 0x62, 0x5d, 0xc7, 0x55, 0xcc, 0xb3, 0x5a, 0x49, 0x5d, - 0x2a, 0x2b, 0x8c, 0xff, 0x16, 0xe4, 0x61, 0x4c, 0x9c, 0xd5, 0x7e, 0xe8, - 0x8b, 0x72, 0x10, 0xf7, 0x82, 0x43, 0xc0, 0xd6, 0x18, 0xbb, 0x9c, 0x72, - 0x94, 0xee, 0xf3, 0xdc, 0xcf, 0x63, 0xaf, 0xbc, 0x2f, 0x9b, 0xaa, 0x52, - 0x75, 0x9d, 0xab, 0x0e, 0x4b, 0xe9, 0x22, 0xea, 0x9f, 0xed, 0x02, 0xad, - 0xc4, 0x7c, 0xa9, 0xd3, 0x25, 0xd9, 0x84, 0xbe, 0xcb, 0x81, 0xc6, 0x0f, - 0xc9, 0x7c, 0x3c, 0xf5, 0x9c, 0xc8, 0xb8, 0xdc, 0x03, 0x3f, 0x9d, 0xf1, - 0xcc, 0x9c, 0x8a, 0xb1, 0xe1, 0xfa, 0x62, 0x16, 0xfe, 0x36, 0x6d, 0xec, - 0x3e, 0xe3, 0x87, 0x6b, 0x1c, 0x5b, 0x13, 0x8e, 0xcb, 0xf1, 0xfe, 0x58, - 0xe6, 0x80, 0x15, 0xe1, 0xeb, 0x03, 0x8b, 0x78, 0x09, 0x8c, 0x19, 0x9b, - 0xbd, 0xe8, 0xc6, 0xe6, 0x2e, 0xb2, 0x9f, 0x98, 0x44, 0x96, 0xa8, 0xb3, - 0xd8, 0x0f, 0x74, 0x3b, 0xfa, 0x4e, 0xab, 0x33, 0xb3, 0x11, 0xb4, 0xfb, - 0x5d, 0xe0, 0x4c, 0xcd, 0xc7, 0xfc, 0x59, 0x6d, 0xf7, 0xf2, 0xf5, 0x66, - 0xac, 0x07, 0xdd, 0x02, 0xbb, 0x98, 0xab, 0x6b, 0xdc, 0x56, 0x54, 0xb8, - 0x4e, 0x63, 0xba, 0xa3, 0x72, 0xa8, 0x43, 0x3a, 0x3d, 0x35, 0x9f, 0xc8, - 0xd9, 0x4d, 0xe2, 0x58, 0x8c, 0xc1, 0x36, 0xd1, 0x26, 0xba, 0x33, 0xb0, - 0xa7, 0xb7, 0x77, 0x50, 0x66, 0x3e, 0x09, 0xdc, 0x38, 0xb0, 0xa4, 0xcf, - 0x98, 0x06, 0x2e, 0xfa, 0x98, 0x8f, 0xf4, 0x31, 0xb2, 0x69, 0x63, 0x0e, - 0x1f, 0x55, 0x76, 0x79, 0x0c, 0xb6, 0xd8, 0x85, 0xac, 0x53, 0xe7, 0xf4, - 0x61, 0xff, 0xf0, 0x9e, 0xba, 0x87, 0x7a, 0x8c, 0x32, 0x13, 0x07, 0x6e, - 0x82, 0xfe, 0xe9, 0xee, 0x97, 0xda, 0x06, 0xdf, 0xf5, 0x2b, 0x1d, 0xed, - 0x60, 0x0d, 0x16, 0x2b, 0xc1, 0xa1, 0xbc, 0x5f, 0x86, 0x16, 0x25, 0xcf, - 0xc9, 0x0f, 0xf2, 0x7d, 0x14, 0xb4, 0x91, 0xc7, 0xdd, 0x65, 0x7d, 0x6e, - 0xb9, 0x57, 0x4a, 0x55, 0xea, 0x69, 0x94, 0xb5, 0xbd, 0xf0, 0x9d, 0x5c, - 0x85, 0x65, 0x73, 0xd3, 0x9c, 0x7b, 0xac, 0xec, 0x42, 0x6e, 0xdd, 0x83, - 0x93, 0x2a, 0xa6, 0x72, 0x79, 0x29, 0xe5, 0xd7, 0x6c, 0x8c, 0x09, 0x9d, - 0x69, 0x9f, 0x1f, 0x93, 0xb9, 0x95, 0x6e, 0x19, 0x5c, 0xe5, 0xf9, 0xf2, - 0x50, 0x4c, 0xba, 0x83, 0xe0, 0x9c, 0x9f, 0x57, 0xb1, 0xc7, 0x81, 0x55, - 0x60, 0x82, 0xa3, 0x9a, 0x77, 0x9c, 0x2f, 0x74, 0xc4, 0xbf, 0x82, 0x8f, - 0xef, 0x8e, 0x8f, 0x8b, 0xbb, 0xe0, 0xe3, 0x57, 0x2f, 0x42, 0xfe, 0x96, - 0x21, 0x9b, 0xcb, 0x90, 0xcd, 0x65, 0xc8, 0xe6, 0x32, 0x64, 0x73, 0x19, - 0xb2, 0x89, 0xfd, 0xf3, 0xfc, 0xf2, 0xb8, 0xc1, 0x1f, 0x9f, 0x82, 0x2c, - 0x7f, 0xdb, 0xe0, 0x8f, 0x51, 0xc8, 0x70, 0x12, 0xb2, 0xeb, 0x43, 0x6e, - 0x87, 0x21, 0xcb, 0x1e, 0x64, 0xb9, 0x1f, 0x72, 0x9c, 0x50, 0xfe, 0xe3, - 0x04, 0xb0, 0xe8, 0x83, 0xf0, 0x41, 0xce, 0x57, 0xfb, 0x65, 0x51, 0xd1, - 0x12, 0xc8, 0x96, 0xbf, 0x49, 0x1e, 0x62, 0x5f, 0xd0, 0x3f, 0x77, 0xe5, - 0xfc, 0x5a, 0x48, 0xdb, 0xab, 0xf2, 0xcd, 0xca, 0x6b, 0xf2, 0x42, 0x85, - 0x34, 0xe6, 0x64, 0x11, 0xef, 0xd6, 0x9e, 0xa2, 0x1f, 0xa9, 0xe8, 0x83, - 0xcc, 0x9d, 0x94, 0xff, 0x03, 0x5e, 0xae, 0x6f, 0x7c, 0x58, 0x3e, 0xe7, - 0x52, 0x86, 0xe3, 0xd0, 0x35, 0xb8, 0x3f, 0x40, 0xbd, 0x04, 0x3f, 0xb4, - 0x92, 0x2a, 0x97, 0xa0, 0x27, 0xaa, 0xf6, 0x08, 0x30, 0x58, 0x39, 0xe8, - 0xa1, 0x0e, 0xab, 0x7a, 0xee, 0x80, 0x4d, 0xde, 0xec, 0x87, 0xbc, 0xa4, - 0xbe, 0x0a, 0xe1, 0xc5, 0x33, 0xda, 0x73, 0x94, 0x35, 0xe8, 0xcf, 0xa7, - 0xc8, 0x47, 0xfa, 0xb5, 0xb8, 0x56, 0xba, 0xf7, 0x27, 0x2a, 0x7e, 0x5c, - 0x9a, 0x86, 0x2f, 0xbf, 0x46, 0x3e, 0x41, 0x56, 0x9e, 0x22, 0x1f, 0x49, - 0x9f, 0xe6, 0xe3, 0x23, 0x12, 0xf2, 0x90, 0xef, 0x5a, 0x79, 0x08, 0x27, - 0xaa, 0x33, 0x8e, 0xb9, 0x7f, 0x2d, 0x66, 0x62, 0xc8, 0xc6, 0x26, 0xbf, - 0x2a, 0xd3, 0x0d, 0xce, 0xc7, 0x92, 0xdb, 0xbc, 0xab, 0xf0, 0xa9, 0x38, - 0xf6, 0xab, 0xc1, 0xa3, 0x71, 0xce, 0x81, 0xeb, 0xba, 0x47, 0xea, 0x7d, - 0xbe, 0x89, 0xaf, 0xfc, 0x2a, 0x5b, 0xc4, 0x7a, 0xe0, 0x3b, 0xf4, 0xcb, - 0x0b, 0xcb, 0xe0, 0x37, 0xfc, 0xae, 0x6f, 0xc0, 0xef, 0x62, 0x9c, 0x53, - 0xaf, 0xcf, 0xb8, 0x89, 0xd9, 0xb6, 0xc6, 0x6a, 0x93, 0x58, 0x23, 0xfa, - 0xed, 0xa9, 0xf2, 0x75, 0xe8, 0xc1, 0xe7, 0x7d, 0xc6, 0xf8, 0x02, 0xf9, - 0xef, 0x7e, 0xb3, 0xa6, 0x53, 0xf1, 0x6d, 0x79, 0x04, 0xba, 0xf1, 0x51, - 0xe8, 0xc6, 0x4f, 0xdc, 0x92, 0xe7, 0x43, 0x79, 0xbb, 0x7f, 0x6a, 0x76, - 0x65, 0xb0, 0x1c, 0xb1, 0xfb, 0x31, 0xa7, 0xe6, 0xb6, 0x8c, 0xf1, 0x25, - 0x4d, 0x2c, 0xb6, 0x19, 0xb3, 0x86, 0xf1, 0x56, 0xca, 0x74, 0x20, 0xd7, - 0xfc, 0x72, 0x57, 0x44, 0x9d, 0x3f, 0x7b, 0xb4, 0x13, 0xbb, 0xfc, 0xbd, - 0xd8, 0xa1, 0xed, 0xf3, 0x5b, 0x46, 0xc6, 0x76, 0x72, 0x99, 0x26, 0x32, - 0xe1, 0x99, 0x73, 0x37, 0x6c, 0x1e, 0xf7, 0x6d, 0x2a, 0x99, 0xc3, 0xde, - 0x9e, 0xdf, 0xa0, 0x5d, 0x20, 0x9e, 0x6c, 0x63, 0x4c, 0x6f, 0xa6, 0x3d, - 0xcb, 0xd8, 0x41, 0x37, 0xfc, 0x97, 0xd7, 0xe5, 0xdc, 0xca, 0x3f, 0x75, - 0xe8, 0xfd, 0xa4, 0x73, 0xcf, 0xec, 0x8b, 0xad, 0x71, 0x54, 0xbd, 0x46, - 0x85, 0x4c, 0x37, 0x30, 0x0c, 0xfd, 0xa5, 0x6b, 0xca, 0x5f, 0x3a, 0xec, - 0x3b, 0xb2, 0x19, 0x67, 0x9f, 0xaf, 0xcb, 0xb1, 0x95, 0xe1, 0x4e, 0xc6, - 0x2b, 0x17, 0x97, 0x0f, 0xc8, 0x96, 0xd2, 0x65, 0x0f, 0xa3, 0x6e, 0x16, - 0x7b, 0x36, 0x08, 0x26, 0xfc, 0xb4, 0x7b, 0x5e, 0x46, 0x12, 0xe7, 0xc1, - 0xd3, 0x3f, 0x43, 0x1b, 0xf8, 0xd4, 0x41, 0x11, 0xcf, 0xae, 0xc2, 0x6f, - 0xbf, 0x21, 0xbc, 0x1e, 0x71, 0x4f, 0x43, 0x18, 0x72, 0x6e, 0xda, 0x7d, - 0x4b, 0x42, 0xdb, 0x45, 0x3b, 0xc5, 0x33, 0xeb, 0x3e, 0x29, 0xac, 0x6b, - 0x5a, 0xe7, 0x41, 0xeb, 0xa9, 0x15, 0x8e, 0xc1, 0x79, 0x91, 0xde, 0x7f, - 0xe2, 0x19, 0x07, 0xe6, 0xf2, 0x41, 0x60, 0x59, 0xe2, 0x28, 0x1d, 0x8b, - 0x28, 0xa0, 0x8d, 0xc2, 0x5a, 0x3e, 0xcf, 0x2b, 0xc9, 0xc7, 0x2f, 0xc2, - 0x6f, 0x88, 0x43, 0x8e, 0xf1, 0x7c, 0xbd, 0x39, 0xe6, 0xcb, 0xfa, 0xfa, - 0x1c, 0xed, 0x92, 0xf2, 0x11, 0xf2, 0xc0, 0x85, 0x93, 0xa8, 0xcb, 0x78, - 0x67, 0x10, 0x1c, 0xf7, 0xe1, 0xc7, 0x3f, 0x45, 0xd9, 0xbb, 0x53, 0x4a, - 0xca, 0xe7, 0x20, 0x86, 0x65, 0xfe, 0xc6, 0x96, 0x1b, 0xc3, 0xfe, 0x9c, - 0x86, 0x6d, 0xcb, 0xc3, 0xb6, 0x45, 0xee, 0x3e, 0x02, 0x3c, 0xab, 0xce, - 0xd9, 0x60, 0x3f, 0x39, 0xee, 0xc3, 0xd6, 0xdf, 0x67, 0x46, 0x81, 0x6f, - 0x1f, 0x00, 0xbe, 0x65, 0x1e, 0x59, 0x1e, 0x18, 0x97, 0xf8, 0xd6, 0x95, - 0xbf, 0xda, 0xc8, 0x43, 0xb7, 0x4d, 0x74, 0x52, 0x17, 0x1f, 0xd9, 0xb6, - 0xd3, 0x45, 0x63, 0xc7, 0xf7, 0x49, 0x41, 0x9d, 0xbb, 0x15, 0x95, 0xbd, - 0x9f, 0x5f, 0x27, 0xae, 0x87, 0xed, 0x5f, 0x87, 0xef, 0x57, 0xa1, 0x8f, - 0x96, 0xc3, 0xfd, 0x03, 0xb8, 0x7f, 0x08, 0xe5, 0x11, 0x94, 0xda, 0xf7, - 0xb9, 0xb4, 0x1c, 0xe9, 0xd4, 0x31, 0xde, 0x44, 0x93, 0xff, 0x43, 0x39, - 0x8c, 0x4f, 0xcd, 0x56, 0xc3, 0x38, 0xfd, 0x21, 0x39, 0xee, 0xeb, 0xb3, - 0xf5, 0x09, 0xf8, 0xeb, 0x9d, 0xc0, 0x60, 0x0f, 0x3d, 0x0d, 0x9b, 0x71, - 0xdf, 0x21, 0xb1, 0xef, 0xb3, 0x64, 0x76, 0x14, 0x74, 0x8f, 0x0e, 0x42, - 0x3f, 0xf7, 0xc3, 0xdf, 0x56, 0x7e, 0xb0, 0xc1, 0x9c, 0xd4, 0xfb, 0x71, - 0xf9, 0xf3, 0x8d, 0x10, 0x7b, 0xb6, 0x01, 0xa7, 0x32, 0x56, 0x98, 0x54, - 0xb8, 0xd9, 0xbe, 0x8d, 0xeb, 0xdf, 0x25, 0xf9, 0xdb, 0xc8, 0x53, 0x3e, - 0x03, 0xa6, 0x51, 0xd7, 0x71, 0x49, 0x9f, 0xe1, 0xba, 0xb5, 0x9b, 0x18, - 0x2f, 0x6d, 0x06, 0xcb, 0xbf, 0xec, 0xdc, 0xc6, 0x96, 0x8c, 0x01, 0x59, - 0xe3, 0x9d, 0x3b, 0x79, 0x69, 0xa1, 0xdc, 0x87, 0xf9, 0x04, 0x94, 0xff, - 0x4b, 0xa0, 0x9f, 0xf6, 0x9e, 0xb6, 0xc1, 0xb5, 0xa2, 0x07, 0x89, 0x05, - 0x22, 0xd2, 0xe6, 0x71, 0x9f, 0xd2, 0x4e, 0x1d, 0xc1, 0x9c, 0x88, 0x0d, - 0x3e, 0xdf, 0x2d, 0xdd, 0xc4, 0x07, 0x49, 0x3c, 0xbb, 0x8e, 0x7a, 0xbc, - 0x67, 0x3d, 0xf8, 0x52, 0xcb, 0x62, 0x45, 0x0e, 0xce, 0x41, 0xae, 0x3d, - 0x5c, 0x1f, 0x47, 0x39, 0x8c, 0xf2, 0x71, 0x94, 0xd4, 0x4f, 0x57, 0x65, - 0x56, 0xc7, 0x7f, 0x14, 0x0e, 0xa1, 0xed, 0x9c, 0xf6, 0xa9, 0x53, 0x4f, - 0x8a, 0x3d, 0xf6, 0x41, 0x3c, 0xa3, 0x1f, 0x8f, 0x91, 0xee, 0xff, 0x82, - 0x89, 0x3f, 0x6d, 0xc7, 0xac, 0x8c, 0x4e, 0x5e, 0x51, 0x31, 0xfc, 0xf5, - 0xa7, 0xe8, 0x23, 0xff, 0x54, 0x1e, 0xbd, 0x29, 0xb6, 0xb7, 0x1d, 0xcb, - 0x1a, 0x2f, 0x28, 0x5d, 0x4c, 0x7e, 0x40, 0x0f, 0xbb, 0x19, 0xf9, 0xfa, - 0x46, 0x0f, 0xf4, 0x5b, 0x5c, 0xde, 0x58, 0x09, 0x80, 0xd5, 0xb9, 0x37, - 0x47, 0x60, 0x33, 0x5d, 0x83, 0x03, 0xe2, 0xf2, 0x2f, 0x90, 0xf3, 0x7f, - 0xae, 0x24, 0xe4, 0xcd, 0x4a, 0x10, 0x5c, 0xf3, 0xd3, 0xfe, 0x61, 0x91, - 0xbb, 0xdb, 0x74, 0x0e, 0x00, 0x6a, 0xe8, 0x73, 0xfb, 0x79, 0x75, 0x76, - 0x8f, 0x7a, 0xd0, 0x3b, 0x6f, 0x36, 0x7e, 0x01, 0xbe, 0xea, 0x3e, 0x5b, - 0xdb, 0x6e, 0xe9, 0xb6, 0x3c, 0xfb, 0x4f, 0x6c, 0x4a, 0xda, 0xe4, 0x10, - 0xa4, 0xd1, 0x36, 0x3d, 0xbc, 0xb6, 0xdd, 0x9e, 0x6d, 0x33, 0xca, 0x5e, - 0x94, 0xd6, 0x7b, 0xa5, 0xfe, 0x17, 0xdc, 0x2b, 0xf0, 0x63, 0xd5, 0x99, - 0x11, 0x4b, 0x9e, 0x55, 0xb0, 0x4e, 0xd2, 0xbc, 0x1f, 0x30, 0xef, 0x3d, - 0x85, 0x5f, 0x9d, 0xed, 0x18, 0x20, 0x7c, 0xdb, 0xe5, 0xd4, 0x69, 0x65, - 0x47, 0x18, 0xb7, 0x5d, 0xa6, 0x7f, 0x4f, 0x5d, 0x3e, 0x69, 0xec, 0x09, - 0x7c, 0x8f, 0xda, 0x71, 0x99, 0x51, 0xd7, 0x9f, 0x90, 0x47, 0x5c, 0xf2, - 0xee, 0xa4, 0xf8, 0x63, 0x1a, 0x4b, 0x89, 0x89, 0x09, 0x76, 0x78, 0x27, - 0xe1, 0x9b, 0x29, 0x7b, 0xec, 0x7e, 0x4c, 0xc8, 0xe3, 0x36, 0xda, 0x8f, - 0x9c, 0x6d, 0x01, 0x83, 0x3d, 0x99, 0x91, 0xe7, 0x36, 0x50, 0x17, 0xeb, - 0xf5, 0x31, 0xc1, 0xfd, 0xb3, 0xb8, 0x67, 0x1c, 0xed, 0xe9, 0xb8, 0x44, - 0x9e, 0xee, 0x97, 0xf6, 0x33, 0xc4, 0x29, 0xe4, 0x69, 0x42, 0xda, 0xce, - 0x10, 0x2f, 0x33, 0xb6, 0x9c, 0x1a, 0xbf, 0x21, 0x8c, 0xe5, 0xa4, 0xfc, - 0x2b, 0xf8, 0x6d, 0x61, 0xde, 0xed, 0xf0, 0xc3, 0xdb, 0x2e, 0xe8, 0x76, - 0xf6, 0xb9, 0x3e, 0x00, 0xc3, 0x98, 0xd8, 0xf0, 0x59, 0xec, 0x0b, 0x2c, - 0xbb, 0x50, 0xf2, 0x1d, 0x48, 0x3a, 0x37, 0x60, 0xde, 0x41, 0x37, 0x5e, - 0xe0, 0xf8, 0xb0, 0x8f, 0xbe, 0xce, 0x17, 0x1d, 0x18, 0xf2, 0xe5, 0xd2, - 0x1a, 0x65, 0x93, 0x71, 0x74, 0x62, 0x97, 0x57, 0xc5, 0x5e, 0xca, 0x48, - 0xe4, 0x4c, 0x06, 0x72, 0xe8, 0xc3, 0xee, 0x12, 0xf3, 0xd1, 0xd6, 0xe1, - 0x39, 0xf0, 0x56, 0xfd, 0x29, 0xce, 0xe9, 0xaa, 0xd8, 0xf5, 0x5f, 0x65, - 0xc3, 0xc2, 0x7d, 0xc1, 0x31, 0x4e, 0xc2, 0xfe, 0x46, 0xe5, 0x73, 0x71, - 0xca, 0x8a, 0x96, 0xbd, 0xb4, 0x3d, 0xa4, 0x64, 0xb5, 0x48, 0xbb, 0xfc, - 0xd4, 0xed, 0x7b, 0xe0, 0xa7, 0x9d, 0x2e, 0x6f, 0xcb, 0x18, 0xf3, 0x42, - 0x03, 0xa9, 0x02, 0xef, 0xcc, 0x7b, 0x96, 0x2c, 0x78, 0x27, 0x15, 0x1e, - 0x7c, 0x14, 0xed, 0x4f, 0x98, 0xf6, 0x0b, 0x32, 0x64, 0x64, 0x5d, 0xc5, - 0x11, 0xa0, 0xc7, 0xb8, 0x66, 0xbc, 0xff, 0x2d, 0xf1, 0x7b, 0xb9, 0x9e, - 0x27, 0x65, 0x60, 0x4c, 0xe3, 0x90, 0x92, 0x4d, 0x1c, 0xf2, 0xae, 0x71, - 0x5a, 0x95, 0xcb, 0x57, 0xa8, 0xd0, 0xce, 0xec, 0x85, 0xfc, 0xc2, 0x27, - 0xda, 0x08, 0x63, 0xb5, 0x6a, 0x5f, 0x25, 0x06, 0x6c, 0x4b, 0xbc, 0xa1, - 0xa1, 0xe1, 0x12, 0xf0, 0xc9, 0x3c, 0x7c, 0x5e, 0xd2, 0xb1, 0x00, 0x3b, - 0xb7, 0xe6, 0xff, 0x4b, 0x70, 0x22, 0x9e, 0x3a, 0x3d, 0xf3, 0xae, 0xf1, - 0xfb, 0x30, 0x6e, 0xdf, 0x7c, 0x9e, 0xb2, 0x69, 0xfd, 0x61, 0xe3, 0x88, - 0xd2, 0x91, 0x37, 0xe3, 0xae, 0x30, 0x7e, 0x3f, 0x7d, 0x53, 0x1c, 0xb5, - 0xd4, 0x08, 0x73, 0xf0, 0x42, 0x3d, 0x7f, 0x1a, 0xba, 0x3a, 0x22, 0x37, - 0x80, 0x41, 0x27, 0xc0, 0xbb, 0x73, 0x6b, 0x65, 0xeb, 0x4a, 0x45, 0xd4, - 0x7d, 0xc1, 0x67, 0x4e, 0xde, 0x47, 0xc0, 0x3b, 0xd8, 0x98, 0x0d, 0xc7, - 0x9c, 0x29, 0x39, 0x78, 0x66, 0x2b, 0x9f, 0xb9, 0xa4, 0x74, 0xf3, 0xe1, - 0x2e, 0x9e, 0xb9, 0x5c, 0x5a, 0xfe, 0x28, 0xee, 0x79, 0xf6, 0x71, 0xa4, - 0xe5, 0xf9, 0x66, 0x4f, 0x54, 0x63, 0x37, 0xf0, 0x5d, 0xf3, 0xcd, 0x01, - 0xbf, 0x8b, 0x8c, 0xe7, 0x35, 0x88, 0x83, 0x3b, 0x0d, 0x0e, 0x26, 0xce, - 0xc2, 0x7a, 0x6d, 0x30, 0x0e, 0x43, 0xac, 0x15, 0x57, 0x7e, 0xa1, 0xc2, - 0x5e, 0xfe, 0x31, 0x93, 0x7f, 0x71, 0xab, 0x5c, 0xcd, 0x56, 0x42, 0x3c, - 0xd7, 0x2c, 0x57, 0xee, 0x6f, 0x20, 0x57, 0x13, 0x5d, 0x3a, 0xdf, 0x81, - 0x36, 0xcd, 0x92, 0x37, 0xaa, 0x7b, 0x64, 0xab, 0xfa, 0x20, 0x70, 0xb4, - 0xca, 0xfb, 0x90, 0x2d, 0xac, 0xc5, 0x83, 0x95, 0x49, 0x99, 0xa8, 0xc6, - 0xe4, 0x5a, 0xd5, 0x7e, 0xa0, 0x5d, 0x18, 0x07, 0x27, 0x36, 0xf9, 0x1b, - 0xa5, 0xdf, 0x7e, 0xe0, 0xef, 0xb4, 0xe7, 0xb9, 0xca, 0x0d, 0xb4, 0x9f, - 0xad, 0xde, 0x2b, 0x25, 0xd5, 0xbe, 0x7e, 0xcb, 0x18, 0x51, 0x33, 0x46, - 0xbd, 0x7a, 0x97, 0x89, 0xdf, 0x95, 0xe5, 0x12, 0xb0, 0xaf, 0x7d, 0x96, - 0xf3, 0xbd, 0xc3, 0xe4, 0x77, 0xc5, 0x9a, 0xfc, 0x91, 0xa8, 0xf1, 0x47, - 0x7e, 0x06, 0x3d, 0xfe, 0x94, 0x44, 0xbd, 0xb0, 0x2f, 0xe6, 0x6a, 0x27, - 0x4c, 0x6e, 0xc7, 0x5e, 0xf4, 0x75, 0x10, 0xef, 0xee, 0xc3, 0xef, 0x49, - 0xd4, 0xa3, 0xbd, 0xe2, 0xd9, 0x28, 0x31, 0x02, 0xcf, 0xeb, 0x7a, 0x51, - 0xaf, 0x03, 0x58, 0x72, 0xbf, 0x79, 0x16, 0xf6, 0x11, 0xd6, 0x0d, 0xef, - 0x9b, 0xcf, 0x53, 0x59, 0x2f, 0xd9, 0x74, 0x9e, 0x0a, 0x45, 0xa5, 0xda, - 0x86, 0xb6, 0x36, 0xb4, 0x51, 0xc9, 0x26, 0x1b, 0xf5, 0x56, 0x53, 0x9e, - 0xa7, 0xc6, 0x61, 0x57, 0x33, 0x9c, 0x6b, 0x5f, 0x53, 0x0e, 0x4a, 0xaa, - 0x4c, 0xfb, 0xc8, 0x78, 0xdf, 0x7a, 0x25, 0xb4, 0x1f, 0xb9, 0x1e, 0x9e, - 0x5b, 0x2c, 0xfa, 0x2a, 0x16, 0x97, 0x8c, 0x64, 0x69, 0x7f, 0xfc, 0xd8, - 0x16, 0x70, 0x65, 0x5d, 0x9d, 0xeb, 0x47, 0xf0, 0x83, 0x5d, 0x76, 0x2c, - 0x71, 0x3d, 0x3e, 0x2b, 0x1b, 0xbd, 0x03, 0x5d, 0x6e, 0xab, 0x3a, 0xc9, - 0xbc, 0xdf, 0x67, 0xee, 0x13, 0xb2, 0x56, 0xf9, 0x50, 0xbf, 0x9d, 0xfd, - 0x5f, 0xb7, 0xe7, 0x33, 0x3d, 0x3c, 0x7f, 0xc2, 0x33, 0xe2, 0xf5, 0xd7, - 0x54, 0x4e, 0xa3, 0xc6, 0x46, 0x0e, 0xcf, 0x2f, 0x81, 0x73, 0x7e, 0x04, - 0x9e, 0x84, 0xb8, 0xfb, 0x75, 0x99, 0x50, 0x98, 0xaa, 0x0d, 0xb6, 0xd2, - 0x60, 0xaa, 0xee, 0x14, 0x30, 0x15, 0xdb, 0xb7, 0xe2, 0x40, 0xbd, 0x97, - 0x22, 0x59, 0x1d, 0x57, 0x6d, 0x89, 0x15, 0x5b, 0x8f, 0x64, 0xc4, 0x3a, - 0x81, 0x1f, 0x65, 0xd4, 0x5e, 0x7a, 0x4d, 0xbc, 0xa5, 0x54, 0x95, 0xf9, - 0xb1, 0x0b, 0x1b, 0x3c, 0xc7, 0x03, 0x16, 0x4b, 0x50, 0x96, 0xf9, 0x6e, - 0x1a, 0x63, 0xbc, 0x06, 0xff, 0x73, 0x0f, 0xf8, 0x6d, 0x1b, 0x1e, 0xf9, - 0x26, 0x46, 0x11, 0x63, 0x2c, 0x18, 0x7b, 0x71, 0x5e, 0x61, 0x89, 0x52, - 0x7c, 0x11, 0xe5, 0x0f, 0x0d, 0x76, 0x78, 0xbd, 0x2b, 0x3c, 0xb7, 0x2f, - 0xc5, 0xbf, 0x84, 0xe7, 0xaf, 0xc3, 0x1f, 0x8c, 0x4a, 0x9b, 0x5a, 0xb3, - 0x10, 0x3b, 0xff, 0x3d, 0xea, 0x90, 0xfe, 0x3b, 0x4d, 0x7e, 0x0d, 0xf3, - 0x06, 0xd8, 0x1f, 0xec, 0x96, 0xca, 0xe1, 0xca, 0xa1, 0x64, 0x3b, 0xb6, - 0x79, 0x05, 0x75, 0x73, 0x98, 0x37, 0x9f, 0x4b, 0x5f, 0x44, 0x9a, 0x9f, - 0x7f, 0x14, 0xcf, 0x29, 0x87, 0xef, 0x37, 0x72, 0x18, 0xbe, 0xcb, 0x1b, - 0x3e, 0xdd, 0x8e, 0x31, 0xc8, 0xab, 0x66, 0xba, 0x38, 0x9f, 0x70, 0xcd, - 0xdb, 0x4c, 0xae, 0x01, 0x9f, 0xbd, 0xdf, 0x3c, 0x73, 0xcc, 0x1c, 0x3f, - 0xde, 0x65, 0xb0, 0x04, 0x76, 0x7b, 0xb8, 0x1f, 0x49, 0x67, 0xac, 0x09, - 0xb3, 0xfe, 0x61, 0xef, 0x4e, 0x1e, 0x26, 0x65, 0xce, 0x53, 0xb1, 0x23, - 0xe6, 0x8f, 0xe5, 0x6c, 0x9d, 0xb3, 0xf1, 0x8d, 0x9b, 0xe2, 0xdd, 0x4a, - 0xd7, 0xf2, 0x0c, 0xa4, 0x6a, 0x67, 0xdb, 0x7f, 0xed, 0xbc, 0xbb, 0x48, - 0x36, 0x6c, 0x07, 0x9c, 0xa6, 0xda, 0x24, 0x65, 0xae, 0xf1, 0x6e, 0x39, - 0x7a, 0xca, 0xbf, 0x30, 0x79, 0x10, 0xfb, 0x55, 0x1e, 0x04, 0xf5, 0xe2, - 0x5a, 0x35, 0x02, 0x5e, 0xf7, 0x31, 0x37, 0x0a, 0x7e, 0x4c, 0x0c, 0x73, - 0x45, 0x5f, 0xf1, 0xf7, 0xab, 0x5c, 0xa9, 0x88, 0x17, 0xe6, 0xf5, 0x72, - 0x1f, 0xde, 0xa1, 0xde, 0x7f, 0x7d, 0xa5, 0x9d, 0xf9, 0xaa, 0x28, 0xb9, - 0x47, 0x7f, 0x09, 0xfd, 0x18, 0x95, 0x42, 0xd5, 0x03, 0xfe, 0x89, 0x52, - 0x2e, 0xf1, 0x7c, 0x3f, 0xfc, 0x61, 0xc1, 0x3e, 0x69, 0x83, 0x6f, 0xa2, - 0x7c, 0x1d, 0xcc, 0x68, 0x87, 0x0e, 0x62, 0x70, 0x9d, 0x1f, 0x1a, 0x40, - 0x87, 0xcf, 0xcb, 0xda, 0xf8, 0xa2, 0xd4, 0xc7, 0x9b, 0x31, 0x2c, 0x30, - 0xaa, 0x5b, 0x0e, 0xea, 0x9e, 0x8a, 0x65, 0x1a, 0xdd, 0x72, 0xc2, 0xe0, - 0x4e, 0xae, 0x83, 0x2d, 0x85, 0xd1, 0x05, 0x25, 0x5f, 0x75, 0xb5, 0x1e, - 0x8e, 0x75, 0x59, 0xe5, 0xf9, 0x72, 0x0c, 0xe6, 0xfa, 0x46, 0x0c, 0x0e, - 0x3b, 0x65, 0xd6, 0xd5, 0xd9, 0x1b, 0xe6, 0xcc, 0x47, 0xb3, 0x87, 0x99, - 0xdb, 0x01, 0x6c, 0x3d, 0x3d, 0x35, 0x5b, 0xa1, 0x2d, 0x0c, 0x82, 0xba, - 0xbf, 0x89, 0x1e, 0x7f, 0xac, 0x30, 0xe4, 0x96, 0x68, 0xdd, 0xbe, 0xa0, - 0x72, 0x66, 0x27, 0xa7, 0xf2, 0x2a, 0x5e, 0xd8, 0x7c, 0x76, 0xf3, 0x5e, - 0xe7, 0x36, 0x31, 0xf8, 0xfe, 0x1d, 0x66, 0xfd, 0x63, 0x4e, 0xa9, 0xd2, - 0xe5, 0xcc, 0xaa, 0xb3, 0xb5, 0xac, 0xf9, 0x16, 0x27, 0x37, 0x95, 0x6e, - 0x7c, 0x76, 0x2f, 0xb1, 0x3e, 0xcf, 0x31, 0x0a, 0x15, 0x9e, 0xe3, 0xe8, - 0xf7, 0x69, 0xf3, 0x7e, 0xa0, 0xa1, 0xde, 0xa9, 0x78, 0x23, 0x63, 0x8c, - 0xed, 0x28, 0x6f, 0x54, 0xa8, 0x6b, 0xd0, 0x7f, 0x5c, 0xcf, 0x21, 0x92, - 0x2d, 0xc2, 0x3f, 0x25, 0x7d, 0x47, 0xa6, 0xf2, 0x2b, 0xcc, 0xdb, 0x7a, - 0x68, 0xea, 0x1a, 0xfc, 0xa5, 0x73, 0x9e, 0xce, 0x2b, 0x5f, 0x67, 0x1c, - 0x8c, 0xed, 0x54, 0x9f, 0x45, 0x13, 0xab, 0x3d, 0x3c, 0x35, 0xb8, 0x1e, - 0x91, 0x27, 0x4c, 0x1f, 0xbc, 0x4f, 0x6e, 0xfb, 0x52, 0x4a, 0xff, 0xc1, - 0x3f, 0x18, 0x85, 0x7f, 0xd0, 0x09, 0x5d, 0x4f, 0x3f, 0x83, 0xf8, 0xbb, - 0x13, 0x7b, 0x85, 0xe3, 0xdc, 0xa5, 0xc6, 0x89, 0x60, 0x9c, 0x59, 0xf8, - 0x38, 0x8c, 0x47, 0xe6, 0x3d, 0x07, 0x58, 0x02, 0xb6, 0xde, 0x63, 0xbc, - 0xdc, 0xc6, 0x9c, 0x87, 0xa1, 0x27, 0x98, 0xa3, 0x32, 0x11, 0xe6, 0x0d, - 0xa1, 0x9d, 0x6f, 0xda, 0x1d, 0x44, 0x3b, 0xfa, 0x07, 0x6c, 0x2b, 0xb7, - 0xd9, 0x32, 0xa8, 0xb0, 0x81, 0xf6, 0x6b, 0x48, 0x43, 0x0d, 0x73, 0xa5, - 0x5d, 0xc5, 0x9e, 0x53, 0xf3, 0x3a, 0xa8, 0xda, 0x59, 0xd9, 0x31, 0xd0, - 0x4e, 0xfc, 0x87, 0xbe, 0x97, 0x75, 0xbc, 0xb3, 0xa0, 0xe4, 0x08, 0x72, - 0x32, 0x1e, 0xe6, 0xbd, 0xe8, 0x76, 0x61, 0xfd, 0x81, 0xf5, 0x86, 0x19, - 0xff, 0xe7, 0x41, 0xee, 0x68, 0xa7, 0xf2, 0xad, 0x5f, 0xbe, 0x29, 0x07, - 0x8d, 0x6d, 0xc2, 0x3a, 0x91, 0x30, 0x2f, 0xb9, 0x89, 0xe6, 0xac, 0x59, - 0x73, 0xb6, 0x63, 0x6c, 0x58, 0xe5, 0xe2, 0xf3, 0x99, 0x33, 0x97, 0x61, - 0x1f, 0xcd, 0x67, 0x4d, 0xa3, 0xc0, 0x19, 0xda, 0x86, 0x94, 0x37, 0x3c, - 0xd8, 0xeb, 0x36, 0xac, 0x1d, 0x6d, 0xc2, 0xa0, 0xf1, 0x2d, 0xde, 0x2b, - 0xce, 0xca, 0x73, 0xcc, 0x51, 0xf8, 0xf5, 0x61, 0x7b, 0xae, 0x63, 0x6e, - 0xea, 0x5a, 0xc5, 0x93, 0x53, 0xcb, 0x3a, 0x3f, 0x4c, 0xf3, 0x81, 0x3a, - 0x9b, 0x6b, 0x9b, 0x94, 0x59, 0x8f, 0xb1, 0x9c, 0xa4, 0xbc, 0xe2, 0x35, - 0xe7, 0x39, 0xa1, 0xfe, 0xc6, 0xa8, 0xc9, 0xc7, 0x3e, 0x88, 0xf9, 0x13, - 0x37, 0x6a, 0x59, 0x3a, 0x00, 0x3b, 0xf4, 0x77, 0x0e, 0x70, 0x21, 0xf6, - 0xd3, 0x75, 0xa7, 0x79, 0x7e, 0xdb, 0xf9, 0xdf, 0x4a, 0x2e, 0x1d, 0xc8, - 0xc8, 0xe2, 0x36, 0xdf, 0xe1, 0xb7, 0xdf, 0x35, 0x04, 0x7d, 0x6f, 0x49, - 0x71, 0xd4, 0x4b, 0x2c, 0xf0, 0x5c, 0xc3, 0x1d, 0x01, 0xca, 0xa7, 0x1f, - 0x9d, 0x04, 0xbd, 0xbc, 0x1e, 0x04, 0x3e, 0x62, 0x4e, 0x22, 0xee, 0x99, - 0x13, 0x18, 0xf7, 0x40, 0xaf, 0xab, 0xce, 0x2b, 0xb4, 0xce, 0xfe, 0xfe, - 0x5e, 0xe6, 0xc0, 0xf5, 0x78, 0xe1, 0xda, 0xab, 0xef, 0xda, 0xd0, 0x77, - 0xc4, 0xbc, 0x9f, 0xd8, 0xe6, 0xbf, 0xf4, 0xb1, 0xdc, 0xce, 0x35, 0x33, - 0xb1, 0x17, 0xd6, 0x1f, 0x57, 0xb4, 0xcc, 0x42, 0x57, 0xcf, 0xa9, 0xf9, - 0xdc, 0x0f, 0x59, 0x88, 0xc8, 0xfc, 0xb6, 0xfc, 0xde, 0x0f, 0xf9, 0xdd, - 0xc3, 0x14, 0xcf, 0x5d, 0x64, 0x2d, 0x94, 0x31, 0xca, 0x17, 0x65, 0xeb, - 0xe3, 0xdd, 0xdc, 0x73, 0xe5, 0xed, 0x75, 0x77, 0x94, 0xcd, 0x4d, 0xda, - 0xe1, 0xba, 0xf3, 0x7a, 0xb7, 0xdc, 0xaa, 0x70, 0x7f, 0x64, 0x7e, 0x83, - 0xb5, 0xf5, 0xcd, 0xda, 0x66, 0x9a, 0xbe, 0x83, 0x08, 0xfb, 0x63, 0x0c, - 0x94, 0x36, 0x88, 0xe7, 0x50, 0xed, 0x52, 0x56, 0x32, 0x68, 0x29, 0x6c, - 0x9d, 0x73, 0xf3, 0x49, 0xc6, 0xbc, 0x8f, 0xc9, 0xbf, 0x03, 0xcd, 0xb9, - 0xe1, 0xa8, 0xe8, 0xb6, 0x33, 0xe0, 0xf7, 0xa6, 0x0b, 0x7f, 0x90, 0x67, - 0xd6, 0x15, 0x47, 0xce, 0xa9, 0x73, 0x57, 0xec, 0xd1, 0x4e, 0x47, 0x16, - 0xbd, 0xed, 0x73, 0x78, 0xa9, 0xa1, 0xce, 0x1a, 0xde, 0x3d, 0xb1, 0x4d, - 0x1b, 0xfd, 0x09, 0xf8, 0x52, 0xde, 0xcf, 0x83, 0x52, 0xfc, 0xa6, 0xba, - 0x46, 0xaf, 0x33, 0x4e, 0xc3, 0xf3, 0x01, 0x57, 0x0a, 0xf0, 0x0b, 0x0b, - 0xf0, 0x09, 0x0b, 0x4a, 0x2f, 0x30, 0x6e, 0xc3, 0x18, 0x5b, 0x19, 0x3e, - 0x48, 0x39, 0x68, 0xf7, 0x4e, 0xaa, 0x18, 0xe2, 0xa5, 0x8d, 0x54, 0xb9, - 0x2c, 0x5e, 0xf2, 0xc1, 0xed, 0x7c, 0xba, 0xee, 0x72, 0x2c, 0xdb, 0x1c, - 0x87, 0x4b, 0xaa, 0x5c, 0xb4, 0x0e, 0x60, 0xe4, 0xe3, 0xd0, 0xd5, 0xcf, - 0xfb, 0x8c, 0xbf, 0xdd, 0x49, 0x7e, 0x7f, 0x95, 0x93, 0xb4, 0x87, 0x46, - 0xc5, 0xbb, 0xe0, 0x0d, 0x3f, 0x28, 0xf4, 0x3f, 0x52, 0xc9, 0x23, 0xe4, - 0xdb, 0xf6, 0x37, 0x0d, 0xa1, 0x7d, 0x1d, 0x95, 0xc1, 0x0b, 0xaf, 0xab, - 0x33, 0x8e, 0x4f, 0xf8, 0xad, 0xb2, 0xa1, 0xe2, 0x77, 0xa3, 0x3d, 0x32, - 0x08, 0xdf, 0x57, 0x60, 0xa1, 0xf8, 0x8d, 0x83, 0x05, 0xdf, 0x43, 0xdd, - 0xcb, 0x74, 0x23, 0x69, 0xf2, 0x54, 0x69, 0x5f, 0x19, 0xdf, 0xd3, 0x79, - 0x7a, 0xcc, 0x4d, 0x65, 0xfe, 0x64, 0x51, 0xe5, 0xeb, 0x31, 0xd6, 0xc7, - 0x58, 0x1e, 0xe3, 0x7d, 0x8c, 0xdb, 0xe9, 0x5c, 0xbd, 0x89, 0xc6, 0x6e, - 0xb1, 0xbd, 0x30, 0x5f, 0x52, 0xdb, 0xad, 0xad, 0xcc, 0x3e, 0xd8, 0x3a, - 0x57, 0xc5, 0x4e, 0x4a, 0x6e, 0x8f, 0x1c, 0x1b, 0x6e, 0x07, 0xcf, 0x7b, - 0x55, 0x3e, 0x9d, 0xed, 0xdd, 0x0f, 0x1c, 0xcb, 0xf8, 0x1c, 0xb1, 0x69, - 0xc8, 0xe7, 0x7b, 0xf0, 0xec, 0x1d, 0xf0, 0x9e, 0xcf, 0x80, 0x5b, 0x95, - 0x1d, 0xfa, 0xbc, 0x6c, 0x55, 0x98, 0x03, 0x5f, 0xdb, 0x97, 0x57, 0xeb, - 0x41, 0xdf, 0x3c, 0xd4, 0x4d, 0x61, 0xfe, 0x28, 0x7d, 0x2a, 0xd7, 0x9c, - 0x93, 0xd3, 0x37, 0xef, 0x85, 0xbf, 0x4e, 0xfd, 0x63, 0xa9, 0xb1, 0xae, - 0x47, 0x3e, 0x20, 0xe5, 0xda, 0x6e, 0x67, 0xfe, 0x41, 0xf0, 0x0d, 0x5f, - 0xe5, 0xac, 0xc2, 0x9f, 0xd4, 0x6b, 0xac, 0xbf, 0x8f, 0x74, 0x76, 0xf2, - 0xcb, 0xe3, 0xda, 0x67, 0xcc, 0xf5, 0x02, 0xb3, 0x78, 0xa7, 0xbb, 0x77, - 0xb0, 0xf3, 0x2f, 0x0d, 0xae, 0x25, 0x6e, 0xee, 0x55, 0xd8, 0xc0, 0xae, - 0x87, 0x72, 0xc2, 0x7c, 0x1f, 0x62, 0xea, 0x03, 0x92, 0xab, 0x41, 0x6f, - 0xf6, 0xf1, 0xfe, 0x47, 0xa6, 0x2d, 0xaf, 0x03, 0x39, 0x3c, 0xd6, 0x7a, - 0x96, 0x3f, 0xae, 0x71, 0x7d, 0x67, 0x78, 0x9e, 0x1f, 0xe6, 0xbc, 0xdf, - 0x94, 0x5b, 0x0b, 0x79, 0x0a, 0x69, 0xd0, 0x63, 0x4d, 0x80, 0xde, 0x7a, - 0x35, 0x21, 0xbd, 0x1e, 0xf3, 0x84, 0x22, 0x32, 0xd6, 0x9b, 0x82, 0x13, - 0xaf, 0xe9, 0xa9, 0xd7, 0x60, 0xf3, 0xab, 0x21, 0x9d, 0x1a, 0xe3, 0xd7, - 0x6b, 0x7c, 0x9f, 0xc4, 0x58, 0xed, 0x32, 0xd6, 0x47, 0x3e, 0xb7, 0xd2, - 0x91, 0x34, 0xf9, 0xdc, 0xad, 0xcf, 0xef, 0x6b, 0xa2, 0xef, 0xd6, 0xef, - 0x4a, 0xf3, 0x8c, 0x8b, 0xad, 0xd0, 0x3f, 0x21, 0x8d, 0xbd, 0xd0, 0x73, - 0x98, 0xa3, 0x1f, 0xfa, 0x1a, 0x21, 0x5f, 0x42, 0x1f, 0x25, 0xaa, 0xe4, - 0x62, 0x36, 0xc3, 0xb9, 0x44, 0x8d, 0xcf, 0x42, 0xba, 0x14, 0x6d, 0x11, - 0x9e, 0x25, 0x46, 0xbd, 0xcf, 0xec, 0xd3, 0xeb, 0xff, 0xa4, 0x99, 0xaf, - 0x6b, 0xea, 0xb0, 0xaf, 0xfd, 0x68, 0xff, 0xb5, 0x00, 0x63, 0x31, 0x08, - 0x87, 0xfd, 0x1f, 0x62, 0xf7, 0xfd, 0xba, 0xaf, 0xce, 0x10, 0xbf, 0x87, - 0xdf, 0xa1, 0x91, 0x4e, 0xee, 0xaf, 0x90, 0x87, 0xec, 0xa3, 0xd7, 0xc4, - 0x5c, 0x49, 0x43, 0x47, 0x0b, 0x0d, 0x29, 0xff, 0x66, 0x1d, 0x77, 0x4f, - 0xd3, 0xdc, 0x29, 0x6b, 0xdd, 0xb2, 0x50, 0xed, 0x94, 0xf9, 0xaa, 0xf2, - 0x75, 0x86, 0x45, 0x88, 0xed, 0xb8, 0x2f, 0x55, 0x2e, 0xb3, 0xc9, 0x99, - 0x0c, 0xf7, 0x67, 0x37, 0xea, 0xd1, 0x86, 0xa0, 0xac, 0x69, 0xfd, 0x54, - 0x93, 0x5b, 0xbf, 0xd3, 0x98, 0x6b, 0xb4, 0xe6, 0xe3, 0x5d, 0x6f, 0xca, - 0xc7, 0x6b, 0xce, 0x7f, 0x2a, 0xcb, 0x23, 0x07, 0x3b, 0x64, 0xe0, 0x6c, - 0xa7, 0x91, 0xd1, 0xfb, 0xcd, 0x38, 0x18, 0x6f, 0x69, 0x5c, 0x06, 0x96, - 0xbe, 0x28, 0xa5, 0x69, 0x95, 0xff, 0xde, 0xf4, 0xfd, 0xc3, 0xa0, 0xf9, - 0xfe, 0x29, 0x67, 0x31, 0x17, 0xa6, 0xb0, 0x84, 0xf5, 0x3a, 0x98, 0x1a, - 0x4e, 0xda, 0xfc, 0x46, 0xf7, 0x31, 0x19, 0x58, 0x1d, 0x97, 0xf4, 0x12, - 0x31, 0x03, 0xb3, 0x01, 0x52, 0x2a, 0x2e, 0x9a, 0xbe, 0xa8, 0xfb, 0xf3, - 0x96, 0xf8, 0x3e, 0x0d, 0xbc, 0xca, 0xf7, 0x85, 0x44, 0x44, 0x65, 0x0c, - 0x7c, 0x10, 0xf2, 0xd4, 0x66, 0xf0, 0x80, 0x23, 0xf9, 0x25, 0xb6, 0x27, - 0xf6, 0xf8, 0x47, 0xac, 0x59, 0x21, 0x69, 0x0b, 0xdb, 0xa8, 0xfe, 0x70, - 0x1d, 0xc6, 0xd3, 0xc9, 0xeb, 0x51, 0x59, 0x6f, 0x78, 0xd8, 0x13, 0xfa, - 0x9b, 0x89, 0x52, 0x2d, 0xcc, 0x27, 0x7d, 0xc4, 0xc4, 0x00, 0x34, 0x8d, - 0xc5, 0x4a, 0xab, 0xec, 0x3d, 0x63, 0xbe, 0x9d, 0xe8, 0x50, 0x67, 0x68, - 0x4d, 0xfa, 0xcf, 0xd4, 0xbf, 0xdd, 0x65, 0xde, 0x80, 0x08, 0xdf, 0x37, - 0xf9, 0x24, 0xf1, 0xb8, 0xda, 0x07, 0x03, 0xf5, 0xb0, 0xde, 0xa8, 0xab, - 0x7d, 0x60, 0xf2, 0x29, 0x6b, 0x68, 0x1e, 0x83, 0xcf, 0xc3, 0x67, 0x07, - 0xd0, 0x96, 0xeb, 0x84, 0xb2, 0x7e, 0x40, 0xe5, 0x39, 0x46, 0xb2, 0x47, - 0xcc, 0x59, 0x5a, 0x9f, 0x1a, 0xcb, 0xcd, 0xb2, 0xff, 0x50, 0x37, 0x74, - 0x34, 0x8d, 0xdf, 0x4a, 0x2f, 0x7d, 0xf8, 0x9f, 0x19, 0x79, 0xe1, 0x7b, - 0xde, 0xb7, 0xd6, 0xf9, 0xa3, 0x7d, 0xe1, 0x7b, 0x67, 0xfb, 0x1b, 0x0c, - 0xf2, 0x92, 0x67, 0x80, 0x28, 0x2f, 0x32, 0x97, 0x9d, 0xd7, 0x28, 0xcd, - 0xb7, 0x25, 0xce, 0x12, 0x7f, 0xad, 0xfd, 0x38, 0xe8, 0x3b, 0xdc, 0xb3, - 0xbb, 0xe5, 0x06, 0x51, 0x17, 0x9f, 0xb6, 0xb6, 0x2a, 0x8c, 0x5d, 0x94, - 0xe5, 0x58, 0xa6, 0x5b, 0x66, 0xab, 0x36, 0xbf, 0x4d, 0x65, 0x2c, 0x96, - 0x67, 0x95, 0x32, 0xa7, 0x74, 0xdc, 0x90, 0xe8, 0xef, 0x76, 0x3b, 0xa4, - 0xe8, 0x52, 0x9e, 0x87, 0x64, 0xbd, 0x36, 0xdd, 0x94, 0x03, 0xdc, 0x66, - 0xe4, 0xec, 0xef, 0xa2, 0xd2, 0xc9, 0x38, 0x52, 0xb8, 0xa7, 0x87, 0xa4, - 0x58, 0x6b, 0x3e, 0x67, 0x60, 0x9e, 0x11, 0xe5, 0xb6, 0xbf, 0x69, 0xef, - 0x31, 0x57, 0x0f, 0xb8, 0x2a, 0x4e, 0x9f, 0x95, 0xf5, 0xf6, 0x1a, 0x7b, - 0xfb, 0x15, 0xac, 0xc7, 0xfb, 0x2d, 0xf1, 0x48, 0x1b, 0x6c, 0x84, 0xc9, - 0x35, 0x3e, 0x1c, 0x2f, 0xc3, 0x3f, 0x1b, 0x32, 0xe3, 0xde, 0x81, 0x7b, - 0xd6, 0xdd, 0x67, 0xde, 0xef, 0x37, 0xf7, 0x9d, 0xe6, 0x3e, 0x82, 0x7b, - 0xe6, 0x8d, 0xb3, 0x4f, 0x96, 0xfc, 0x9e, 0x88, 0xdf, 0xeb, 0x64, 0x25, - 0x7a, 0x11, 0xe8, 0xa9, 0xd1, 0x29, 0x9f, 0xae, 0x29, 0xfe, 0x5a, 0xde, - 0x12, 0x01, 0xc1, 0x7e, 0x73, 0x7d, 0xeb, 0x1e, 0xfc, 0xdc, 0x4d, 0xdf, - 0x4a, 0x55, 0x8c, 0xac, 0x34, 0xd3, 0x9b, 0x03, 0xad, 0xef, 0x96, 0x83, - 0x45, 0x1b, 0xa5, 0xfd, 0xc6, 0x62, 0x45, 0xe7, 0x1a, 0x1d, 0x83, 0xdf, - 0x78, 0xb8, 0xfa, 0xa8, 0xab, 0xf3, 0x62, 0xc2, 0x5c, 0xca, 0x4e, 0xcc, - 0x6b, 0xc8, 0x9c, 0x5b, 0xb3, 0x2d, 0x73, 0x3a, 0xc3, 0xf3, 0x99, 0x66, - 0xac, 0x4a, 0x5b, 0x44, 0x3b, 0xc3, 0xef, 0x9a, 0x7c, 0xd4, 0x5d, 0xa4, - 0xae, 0x69, 0xca, 0xcd, 0xff, 0x52, 0x4b, 0x6e, 0x3e, 0xbf, 0xfb, 0x16, - 0xf9, 0x6f, 0x0d, 0xc6, 0x95, 0x3a, 0x24, 0x72, 0x36, 0xcc, 0xc1, 0xe2, - 0x1a, 0x13, 0x87, 0xf1, 0x7b, 0xef, 0xa9, 0x5d, 0x62, 0x4e, 0xa1, 0x9c, - 0x7f, 0xc7, 0x65, 0x7e, 0xab, 0x9b, 0x0d, 0xe3, 0x54, 0xcc, 0xeb, 0x21, - 0xe6, 0x3a, 0x60, 0x62, 0x0a, 0x7c, 0x57, 0x96, 0x9e, 0x83, 0x53, 0xdc, - 0x1b, 0xbf, 0x1d, 0xd9, 0xce, 0xfd, 0x57, 0xe3, 0xc4, 0x35, 0x86, 0xe4, - 0x77, 0xe3, 0x3e, 0xf6, 0xd5, 0x9e, 0xcd, 0xf0, 0x9b, 0x8c, 0xcb, 0x8d, - 0x8c, 0xfa, 0xf6, 0x83, 0x67, 0x1e, 0x5b, 0x0d, 0xee, 0x3b, 0x7e, 0x23, - 0x9e, 0x55, 0x39, 0x01, 0x5b, 0xe6, 0x9b, 0xe7, 0xab, 0x0d, 0xfd, 0x1d, - 0xcb, 0xe2, 0xb2, 0xca, 0xcb, 0x07, 0x56, 0x4b, 0xe2, 0x3d, 0x73, 0xe8, - 0xfa, 0x55, 0x2e, 0xc1, 0x7c, 0xe3, 0x53, 0x28, 0x3f, 0x2f, 0x6b, 0x15, - 0x1d, 0x7f, 0x9d, 0x6f, 0x30, 0xa7, 0xc0, 0x55, 0x67, 0x44, 0x03, 0x4b, - 0x45, 0x8c, 0x17, 0x7e, 0xb3, 0x1d, 0xc7, 0x33, 0xd2, 0x57, 0x36, 0x7b, - 0x34, 0xcc, 0x05, 0xe9, 0xea, 0xa1, 0x4d, 0x28, 0x37, 0xba, 0x54, 0x1e, - 0x82, 0xc6, 0x23, 0xc4, 0x7a, 0x31, 0xd4, 0xe5, 0x5c, 0x3b, 0x69, 0xaf, - 0x02, 0xea, 0xa4, 0x34, 0xc6, 0xa9, 0xab, 0xdc, 0x44, 0xf2, 0xd9, 0x73, - 0x4b, 0xf4, 0xd7, 0x94, 0x8e, 0x4f, 0x0d, 0xcf, 0x48, 0xc1, 0x8d, 0xc2, - 0x17, 0x9b, 0x57, 0x7e, 0xce, 0xfd, 0xc0, 0xd0, 0x5d, 0x9b, 0x91, 0x2c, - 0xe7, 0xc6, 0xb1, 0xe9, 0x87, 0xe8, 0xf9, 0xe8, 0x33, 0x02, 0xb1, 0xe6, - 0xd5, 0xf7, 0x8f, 0x7c, 0xce, 0x78, 0x6f, 0xf8, 0xcd, 0x90, 0xfe, 0x26, - 0x64, 0xa6, 0x71, 0x44, 0x4e, 0x55, 0xf6, 0xf2, 0x5b, 0x09, 0x7f, 0x0b, - 0x7c, 0x3b, 0xd6, 0xe8, 0x52, 0xdf, 0xa5, 0xcc, 0x34, 0x98, 0x3f, 0x17, - 0xda, 0x1e, 0xae, 0x55, 0xdc, 0x7c, 0x37, 0x91, 0x30, 0xdf, 0x4d, 0xf0, - 0xdb, 0x8f, 0x1f, 0xed, 0x0d, 0xf7, 0xfb, 0xad, 0x38, 0x9c, 0x32, 0xf8, - 0xa7, 0xf0, 0x0d, 0xc3, 0x3c, 0x4c, 0xe6, 0x8b, 0x06, 0xc1, 0x31, 0x9f, - 0xf1, 0xdb, 0xe9, 0xc3, 0x6b, 0x98, 0xe3, 0x95, 0x1a, 0x78, 0x78, 0x94, - 0xcf, 0x98, 0x37, 0xd6, 0x2e, 0xf9, 0xd1, 0x76, 0xea, 0xf2, 0xce, 0x35, - 0x6f, 0xaf, 0x5c, 0xae, 0xc6, 0x55, 0x0e, 0x5c, 0x09, 0x38, 0xbf, 0x2e, - 0x1f, 0xeb, 0xe1, 0xd9, 0xdd, 0x84, 0x6a, 0x1f, 0xee, 0x77, 0x1d, 0x37, - 0x98, 0x58, 0xd7, 0xfa, 0xe4, 0x78, 0x06, 0xb8, 0xe5, 0x82, 0x58, 0x7f, - 0x90, 0xe9, 0x87, 0xef, 0xcd, 0xb1, 0xd2, 0x68, 0x07, 0xd9, 0x49, 0x70, - 0xaf, 0xbf, 0x13, 0xd4, 0x41, 0xef, 0x8d, 0x06, 0xf1, 0x3a, 0x30, 0xd4, - 0x34, 0xdb, 0x64, 0xc5, 0x3e, 0xc3, 0x3a, 0xbd, 0x90, 0xbf, 0x28, 0xe6, - 0xe3, 0xc0, 0x17, 0xd8, 0x27, 0x75, 0x97, 0xef, 0x1c, 0x7d, 0xa6, 0x12, - 0x0f, 0xfd, 0x94, 0xef, 0x81, 0x7f, 0x49, 0xa5, 0x93, 0xc2, 0xf3, 0x4e, - 0xe6, 0xb3, 0xce, 0x56, 0x27, 0xb1, 0x87, 0x1c, 0x83, 0xcd, 0x1c, 0xf4, - 0xf1, 0xe1, 0x1e, 0x8d, 0x15, 0x78, 0x1e, 0xaa, 0xb1, 0x88, 0xb6, 0x31, - 0x3c, 0xdf, 0x71, 0xe0, 0x0b, 0x84, 0xfb, 0xf2, 0x99, 0x7d, 0x37, 0x7f, - 0x0b, 0x43, 0x1c, 0x93, 0x4e, 0x9c, 0xe7, 0x79, 0xdc, 0xc6, 0xc3, 0x32, - 0x03, 0x9a, 0x4f, 0x9b, 0x79, 0x3e, 0x98, 0xf1, 0xe4, 0x7a, 0x8d, 0xe7, - 0x95, 0x07, 0x50, 0x32, 0xd7, 0x91, 0x34, 0x8f, 0x98, 0x7c, 0xce, 0x2c, - 0xe6, 0xfa, 0x98, 0xbc, 0x01, 0x7c, 0xfd, 0x66, 0x25, 0xed, 0x4f, 0xa8, - 0x3c, 0xa4, 0x54, 0xe2, 0xb2, 0x8c, 0x24, 0xe9, 0x03, 0x96, 0xdd, 0x54, - 0xe2, 0x3a, 0xe4, 0xe1, 0x46, 0xe5, 0x99, 0x1e, 0xfe, 0xaf, 0x8a, 0x3a, - 0xec, 0xe1, 0x0d, 0x95, 0x83, 0x94, 0x62, 0xcc, 0x04, 0xf7, 0xfd, 0x26, - 0x0f, 0x8a, 0xe3, 0xf0, 0x5d, 0xbf, 0xbc, 0x51, 0xd9, 0xb6, 0xbf, 0x1c, - 0xc7, 0x7c, 0x03, 0xcf, 0xb1, 0x2e, 0xf4, 0x50, 0x0f, 0x71, 0x3c, 0xdd, - 0x47, 0x58, 0x87, 0x7c, 0x0d, 0xe3, 0x9a, 0xea, 0x5b, 0xcb, 0xa4, 0x58, - 0x96, 0xb4, 0x79, 0x9c, 0xfb, 0x54, 0x8f, 0xc6, 0x40, 0x6c, 0x97, 0x76, - 0x0f, 0xab, 0xfe, 0x78, 0xb6, 0xc7, 0xf3, 0xaf, 0xb0, 0x1f, 0xe6, 0x43, - 0x31, 0xe7, 0x8a, 0xba, 0xaf, 0x99, 0x06, 0x6d, 0xff, 0xdf, 0x50, 0xb1, - 0xf4, 0x71, 0xd4, 0xa7, 0x8d, 0x86, 0xbc, 0xd4, 0x12, 0xdb, 0xdf, 0x7c, - 0x68, 0x5e, 0xf2, 0xfa, 0x99, 0xed, 0x6f, 0x32, 0xec, 0xbb, 0x5d, 0xf3, - 0x3e, 0xc4, 0xa5, 0xfd, 0xd8, 0xaf, 0x8f, 0x49, 0x7d, 0x25, 0x9d, 0xf8, - 0xb4, 0x84, 0xfd, 0x06, 0x87, 0x78, 0xde, 0x51, 0xcc, 0x8c, 0xb8, 0x0b, - 0x8a, 0x9e, 0x54, 0x82, 0x39, 0xc8, 0x97, 0x31, 0x5e, 0xbd, 0xd1, 0x1a, - 0x7b, 0x48, 0xe5, 0x36, 0x25, 0xed, 0xeb, 0xb5, 0x19, 0x92, 0x4d, 0xac, - 0xcd, 0x9f, 0x9b, 0xb5, 0xf9, 0x18, 0xfa, 0xf6, 0xce, 0x8c, 0x4a, 0xfa, - 0x4c, 0x3a, 0x79, 0x5a, 0x78, 0x96, 0xb8, 0x8f, 0x31, 0x2c, 0xeb, 0xc1, - 0x4c, 0x12, 0xf3, 0x4d, 0x61, 0xbe, 0x28, 0x1b, 0xbc, 0x1e, 0x81, 0x6f, - 0xbe, 0x87, 0x7b, 0xfb, 0x10, 0x75, 0x26, 0x79, 0x51, 0x54, 0xef, 0x80, - 0x4f, 0x9e, 0x26, 0x4d, 0x00, 0xca, 0x9d, 0x29, 0x15, 0x07, 0xbc, 0xde, - 0xe0, 0xf9, 0xa2, 0xa6, 0xaf, 0x00, 0xfa, 0xe6, 0x34, 0x7d, 0xc9, 0x99, - 0x6d, 0xec, 0x9a, 0x4a, 0x9c, 0x12, 0xe2, 0x25, 0xe2, 0x17, 0xe2, 0xfa, - 0x47, 0x7a, 0xc3, 0x6f, 0x5a, 0xf2, 0x77, 0xe7, 0xb6, 0xe7, 0xde, 0x86, - 0xba, 0x57, 0x32, 0x2a, 0xbf, 0xd9, 0x3d, 0x22, 0x1f, 0x91, 0xdc, 0xa7, - 0x52, 0xc9, 0x9c, 0xe5, 0x19, 0x0c, 0x88, 0xb2, 0xc6, 0x6b, 0xea, 0x5c, - 0xcf, 0x60, 0x0b, 0xae, 0x4d, 0x06, 0x63, 0x29, 0xde, 0xc2, 0x67, 0xea, - 0x87, 0xcc, 0x53, 0xd6, 0x7e, 0x07, 0x7b, 0x48, 0xff, 0x9f, 0x8e, 0xcb, - 0xe0, 0xe3, 0x3c, 0xf8, 0x78, 0xfc, 0x16, 0x0c, 0x16, 0xdd, 0xc6, 0x60, - 0x5b, 0x6a, 0xbc, 0x7b, 0x41, 0x53, 0xc1, 0x25, 0xfe, 0x9a, 0xdf, 0x96, - 0x15, 0xd2, 0x34, 0xca, 0xff, 0xb5, 0x23, 0x57, 0x33, 0x5c, 0x0f, 0x60, - 0x30, 0xf4, 0xb7, 0xb6, 0x23, 0x4b, 0x98, 0xbf, 0x92, 0x5f, 0xc8, 0x6e, - 0xca, 0x75, 0x2c, 0xae, 0x05, 0xfb, 0x13, 0xeb, 0x1a, 0x68, 0xd9, 0x52, - 0x72, 0xa0, 0x65, 0x60, 0xab, 0xd6, 0xf9, 0x1e, 0x32, 0xc0, 0x79, 0x52, - 0xfe, 0x42, 0xd9, 0xdb, 0xc9, 0xa7, 0xe8, 0x00, 0x4f, 0x3e, 0x78, 0x4f, - 0x56, 0xf2, 0x67, 0x78, 0x16, 0x26, 0xd6, 0xc8, 0x3d, 0x94, 0x49, 0xe2, - 0x04, 0x60, 0xc8, 0x04, 0x79, 0xac, 0xf1, 0xe0, 0xcc, 0xb3, 0x7b, 0xf1, - 0x7b, 0xb3, 0x87, 0x39, 0x33, 0xf9, 0x73, 0xd4, 0x57, 0x62, 0xdd, 0x79, - 0x8f, 0xf6, 0x0f, 0x6f, 0xc4, 0xc1, 0x73, 0xbc, 0x1f, 0x78, 0xb2, 0x0d, - 0xfa, 0xca, 0x31, 0xf3, 0xe6, 0x3d, 0xf9, 0x8a, 0xf2, 0xd9, 0x29, 0xa3, - 0x03, 0xa8, 0x47, 0xc4, 0xec, 0x8b, 0xb2, 0xcc, 0x31, 0x46, 0x9f, 0xe9, - 0x94, 0x09, 0xe8, 0xb5, 0x23, 0x95, 0x71, 0xf9, 0x72, 0xa5, 0x4b, 0xe1, - 0x86, 0xbf, 0xf6, 0xd3, 0x89, 0x61, 0x2b, 0x90, 0x07, 0x81, 0x7f, 0x66, - 0xfa, 0xdb, 0xe4, 0xcd, 0x51, 0x9d, 0xfb, 0x7b, 0x83, 0xc9, 0x8d, 0x2e, - 0xf3, 0x55, 0x39, 0x1f, 0xe8, 0x7d, 0x0b, 0xbe, 0x80, 0xd5, 0x2e, 0x33, - 0xf1, 0x2e, 0xf9, 0xb8, 0x8f, 0xf2, 0x36, 0x5f, 0x7d, 0x63, 0x9c, 0x8b, - 0x37, 0xeb, 0x91, 0x37, 0xcd, 0xd8, 0x5f, 0x34, 0xe5, 0xbf, 0xe9, 0x6d, - 0xa2, 0xc5, 0x9a, 0xcb, 0x44, 0xd4, 0xfc, 0xe6, 0x6b, 0xd4, 0x6f, 0x6c, - 0x03, 0x7d, 0xd2, 0xe0, 0x39, 0x51, 0x59, 0xd6, 0xa0, 0x5f, 0x4a, 0x55, - 0xb1, 0xce, 0x65, 0x80, 0xa8, 0x3d, 0x8d, 0x3f, 0x4b, 0x90, 0xaf, 0xd9, - 0xaa, 0x8a, 0x59, 0xaa, 0xbc, 0xed, 0x59, 0x60, 0x5d, 0xf8, 0xc4, 0xc0, - 0x10, 0x26, 0x7f, 0xa5, 0x93, 0xf1, 0x90, 0x66, 0x1d, 0x16, 0xfe, 0x2f, - 0x9d, 0xff, 0xd4, 0x2b, 0xdd, 0x65, 0xac, 0x4b, 0x88, 0xb9, 0xc1, 0x53, - 0x8c, 0x99, 0x57, 0xeb, 0x14, 0xae, 0x09, 0x75, 0x4f, 0x73, 0xbe, 0x78, - 0x88, 0x39, 0xb8, 0x67, 0x69, 0x2f, 0xa4, 0x1c, 0x03, 0xa6, 0xed, 0x38, - 0x03, 0xdb, 0x5d, 0xcd, 0x42, 0x56, 0xc6, 0x55, 0xde, 0xe7, 0x3c, 0xb0, - 0xdb, 0x1f, 0xf8, 0x7f, 0x2a, 0xf6, 0xd3, 0x07, 0x64, 0xad, 0xda, 0x01, - 0x7e, 0xd0, 0x2e, 0x44, 0x95, 0x7f, 0x7d, 0xe3, 0x28, 0xed, 0x1d, 0x6d, - 0x89, 0x5e, 0x8b, 0xad, 0xda, 0xf7, 0x7a, 0xf5, 0xb7, 0x33, 0x7b, 0x65, - 0xb3, 0x16, 0xda, 0x42, 0xf8, 0x87, 0xd5, 0xa8, 0xb1, 0xcb, 0x9d, 0xd0, - 0xdd, 0xdf, 0x8f, 0xd6, 0x95, 0xaf, 0xce, 0xf9, 0xd3, 0x06, 0x45, 0x99, - 0x17, 0xd7, 0x59, 0xf7, 0x38, 0xf7, 0x66, 0x1b, 0xa4, 0x71, 0x87, 0x7b, - 0x90, 0xe3, 0x31, 0x87, 0x82, 0x73, 0x8c, 0x4b, 0xf4, 0xfc, 0x63, 0x62, - 0xc3, 0x6f, 0x89, 0x2c, 0x11, 0xeb, 0xdd, 0xec, 0xbb, 0x44, 0x2e, 0xba, - 0xe6, 0x5b, 0xec, 0x41, 0x8d, 0x65, 0x32, 0x28, 0xeb, 0xe1, 0xf7, 0xd9, - 0xfc, 0x35, 0xdb, 0xcd, 0xd0, 0xb7, 0xd8, 0xd5, 0x96, 0xe2, 0xef, 0xff, - 0x01, 0x37, 0x64, 0x26, 0x2b, 0x1c, 0x4c, 0x00, 0x00, 0x00 }; + 0xcd, 0x7c, 0x7b, 0x6c, 0x5c, 0xd7, 0x99, 0xdf, 0x77, 0xef, 0xcc, 0x90, + 0x43, 0x6a, 0x44, 0x5d, 0x32, 0x13, 0x66, 0x1c, 0x33, 0xcd, 0x3c, 0x2e, + 0x29, 0xda, 0x64, 0x92, 0x31, 0x77, 0xa4, 0xd0, 0xc9, 0xad, 0x3d, 0x99, + 0x19, 0xc9, 0x4c, 0xa8, 0x0d, 0xe8, 0x44, 0x2e, 0x52, 0x54, 0x28, 0xd8, + 0x21, 0xe5, 0x28, 0x8b, 0xec, 0xae, 0xf2, 0x28, 0x9a, 0x2e, 0xd2, 0xd5, + 0x64, 0x48, 0x29, 0xca, 0x62, 0xc4, 0x19, 0xd3, 0x34, 0x93, 0xa2, 0x01, + 0x32, 0x19, 0x92, 0x72, 0x76, 0x31, 0x12, 0x15, 0xdb, 0xcd, 0x1a, 0x41, + 0xe2, 0xb0, 0xd4, 0x23, 0xde, 0x20, 0x2d, 0xb4, 0x1b, 0x17, 0x4d, 0xd3, + 0x45, 0x21, 0xc8, 0x4e, 0x6c, 0x6c, 0xb3, 0x6d, 0x50, 0x2c, 0x10, 0x77, + 0x91, 0x64, 0xfa, 0xfb, 0x9d, 0x73, 0xee, 0x70, 0x44, 0x31, 0x4e, 0xba, + 0x7f, 0x95, 0xc0, 0xe0, 0xdc, 0x7b, 0x9e, 0xdf, 0xf9, 0xce, 0xf7, 0x3e, + 0xdf, 0xe5, 0x43, 0x22, 0xbd, 0x62, 0xfe, 0xf6, 0xe3, 0x97, 0xf9, 0xfd, + 0x3f, 0x9c, 0x7b, 0xe0, 0x9d, 0x87, 0xdf, 0x89, 0xc7, 0x43, 0xf6, 0x81, + 0xae, 0x20, 0xeb, 0x03, 0xf8, 0x45, 0xf1, 0x9b, 0x30, 0xcf, 0x7b, 0xfd, + 0x39, 0xf8, 0x1d, 0xb6, 0x44, 0x66, 0xff, 0x46, 0xc4, 0xda, 0xd5, 0x16, + 0xfe, 0x35, 0x63, 0xde, 0xe8, 0xcf, 0xfe, 0x2d, 0xfb, 0x39, 0xff, 0x80, + 0xb9, 0xfd, 0xbf, 0x80, 0x19, 0xbe, 0xdf, 0xfc, 0x24, 0x6c, 0x7b, 0xb7, + 0x3e, 0x90, 0x73, 0x25, 0x1c, 0xf0, 0x7e, 0x38, 0x3d, 0xe7, 0x8a, 0x64, + 0x9b, 0x63, 0xf1, 0xbc, 0xfc, 0xb2, 0x55, 0x8a, 0x06, 0x85, 0xf5, 0x6f, + 0xf3, 0x7e, 0xf1, 0x95, 0x6f, 0xbf, 0x3b, 0xf1, 0xb3, 0x7a, 0x40, 0xc2, + 0x8e, 0xf7, 0xba, 0x38, 0x23, 0x12, 0x1e, 0xc2, 0x98, 0x2f, 0x1f, 0x9c, + 0xb5, 0xa5, 0xcf, 0x9f, 0xeb, 0xb5, 0xd6, 0xb7, 0x0f, 0x4a, 0xc9, 0xf6, + 0x1c, 0xb9, 0xb2, 0x19, 0x95, 0xef, 0x6c, 0x8a, 0x35, 0x93, 0xe9, 0x11, + 0x7b, 0xf9, 0xad, 0x92, 0x75, 0x2c, 0x09, 0xb8, 0x5c, 0x27, 0x2e, 0xb9, + 0xca, 0x20, 0xde, 0x13, 0x31, 0x91, 0x7f, 0xbe, 0x5f, 0x8f, 0x0d, 0x4b, + 0x60, 0x55, 0xc2, 0x5d, 0xde, 0x0b, 0xd3, 0x37, 0x56, 0x62, 0x12, 0x5c, + 0x1a, 0x97, 0x72, 0x35, 0x22, 0xa1, 0x55, 0x19, 0x0a, 0xc8, 0x70, 0xec, + 0x71, 0xf4, 0x28, 0x34, 0x83, 0x72, 0xa4, 0x69, 0x49, 0xd0, 0x0d, 0x03, + 0xb6, 0x08, 0x7e, 0x0e, 0x7e, 0x51, 0xfc, 0x62, 0xf8, 0x9d, 0xc5, 0x3c, + 0x43, 0x92, 0x6f, 0x72, 0x4e, 0xac, 0x5b, 0xc5, 0xfa, 0xd5, 0x84, 0x33, + 0x8b, 0x79, 0x6f, 0x05, 0x62, 0xf2, 0xed, 0x83, 0x84, 0xcb, 0x21, 0x3c, + 0x80, 0x2d, 0x6c, 0xe5, 0x56, 0xe4, 0x74, 0x3e, 0x2d, 0x71, 0xdb, 0xed, + 0x95, 0xa2, 0x63, 0xc5, 0xe7, 0x47, 0x07, 0xa4, 0x74, 0x1c, 0xed, 0x55, + 0xc9, 0xda, 0x98, 0xbf, 0xe8, 0xc8, 0xac, 0x6e, 0x63, 0xdd, 0x17, 0x41, + 0x27, 0x09, 0x87, 0x08, 0xfb, 0x4e, 0xf5, 0x31, 0x3c, 0x73, 0xbe, 0x78, + 0x50, 0xc3, 0xbd, 0x8a, 0x77, 0xd6, 0xff, 0x41, 0x44, 0xbf, 0xf3, 0x99, + 0x7d, 0xfd, 0x75, 0xfd, 0xfd, 0x72, 0xfd, 0x51, 0xec, 0x99, 0x30, 0xf8, + 0x7b, 0x96, 0x52, 0x08, 0xb0, 0x34, 0x56, 0x22, 0xd6, 0xda, 0xca, 0xb8, + 0x9c, 0xab, 0x3e, 0x24, 0xb9, 0x74, 0xab, 0x35, 0x97, 0x96, 0xa8, 0x2d, + 0xc3, 0x4e, 0x1e, 0x1d, 0xb6, 0x9b, 0x62, 0x35, 0x2a, 0x12, 0xee, 0x06, + 0x5e, 0x5e, 0x5d, 0xe1, 0xdc, 0x41, 0xd4, 0x0d, 0xa2, 0x7f, 0x9f, 0xb5, + 0xbe, 0x02, 0xf8, 0x3d, 0xe2, 0xa7, 0xd5, 0x5a, 0x4c, 0x0f, 0xc7, 0xe6, + 0xb1, 0xe6, 0xd5, 0xe6, 0xf0, 0xe4, 0x6d, 0x71, 0x30, 0xe7, 0x00, 0xfa, + 0x10, 0x57, 0x9c, 0x8b, 0x73, 0x72, 0xbe, 0x08, 0xc6, 0x46, 0xd1, 0x46, + 0xb8, 0x5a, 0xad, 0x5c, 0xda, 0xe1, 0xbb, 0x6c, 0x01, 0x7f, 0x5b, 0xc4, + 0x5f, 0xef, 0x90, 0x7c, 0xb7, 0xc9, 0x35, 0xda, 0xb0, 0x97, 0xba, 0xbc, + 0xe7, 0xed, 0xed, 0x0a, 0xcf, 0x2d, 0x2c, 0xef, 0x0b, 0x26, 0x46, 0x4b, + 0x8a, 0x4e, 0x66, 0xb1, 0x1f, 0x4b, 0xd1, 0x84, 0x85, 0xe7, 0x64, 0x93, + 0xfd, 0x89, 0xeb, 0xb8, 0x2c, 0xe0, 0x5c, 0xcb, 0x2b, 0x25, 0xfb, 0x6a, + 0xf3, 0x17, 0xad, 0x9c, 0xbb, 0x68, 0x6f, 0xaf, 0xb3, 0xff, 0x09, 0xf4, + 0x0f, 0xca, 0x62, 0xa5, 0x4f, 0x08, 0x93, 0x1e, 0x77, 0x02, 0xe3, 0xc4, + 0xb1, 0xbd, 0x73, 0xf6, 0xd5, 0xf5, 0xf3, 0xf6, 0x35, 0x75, 0x6e, 0x58, + 0xab, 0x3d, 0x57, 0x27, 0xde, 0xc6, 0xfe, 0x3f, 0xc4, 0x5b, 0x0c, 0xf3, + 0x47, 0x51, 0xee, 0xb3, 0x1a, 0xb5, 0x16, 0xd6, 0x8f, 0xe1, 0x79, 0x2f, + 0x1c, 0xde, 0x52, 0x74, 0x77, 0x05, 0x74, 0xe7, 0x78, 0x31, 0x79, 0x66, + 0x73, 0x08, 0xfb, 0x88, 0xca, 0xd7, 0xc1, 0x17, 0x03, 0x87, 0xf7, 0x49, + 0x1e, 0x7c, 0x41, 0x7a, 0x7b, 0x74, 0xf5, 0x9f, 0x49, 0x31, 0x9a, 0x18, + 0xa5, 0xfc, 0x48, 0x4e, 0x80, 0x9e, 0x0d, 0x6b, 0xe7, 0x96, 0xb2, 0x29, + 0x5b, 0x1e, 0x16, 0xdb, 0xc3, 0xba, 0x99, 0x31, 0xa7, 0x20, 0x41, 0xb4, + 0x65, 0x25, 0xe0, 0x45, 0x25, 0xb7, 0xfa, 0x5e, 0x0b, 0x74, 0x19, 0x5f, + 0xc0, 0xa0, 0xc0, 0x92, 0x58, 0xb6, 0xdb, 0x25, 0xc5, 0xe3, 0xac, 0x0f, + 0x83, 0xc6, 0xc1, 0xb3, 0x2b, 0x07, 0x00, 0x97, 0x0c, 0xdb, 0xc2, 0xba, + 0x61, 0xa7, 0x2c, 0x25, 0xb1, 0x2f, 0xff, 0xa1, 0x65, 0x64, 0x9e, 0xc1, + 0xef, 0xa8, 0x59, 0xab, 0xcd, 0x87, 0x96, 0xbd, 0x1a, 0xb1, 0x02, 0xab, + 0xe3, 0x72, 0x76, 0x0f, 0xbc, 0x36, 0x80, 0x57, 0x7b, 0xc9, 0xe7, 0xd3, + 0x20, 0xde, 0x07, 0xd1, 0xb7, 0xcf, 0x0a, 0xae, 0xde, 0x8d, 0xd3, 0xb5, + 0xe6, 0x70, 0x7a, 0x1b, 0x38, 0xb5, 0x57, 0x07, 0xd0, 0xe7, 0x6e, 0x9c, + 0x36, 0x80, 0x53, 0x7b, 0x55, 0xe3, 0xb3, 0x01, 0x7c, 0xda, 0x4b, 0x51, + 0x94, 0xfb, 0x2c, 0x7b, 0x59, 0xe3, 0xb3, 0x61, 0x78, 0xfa, 0x62, 0x93, + 0xb0, 0x66, 0x3b, 0x68, 0x2e, 0x4b, 0xda, 0x81, 0x9c, 0x2a, 0xc8, 0x5c, + 0xc5, 0x06, 0xbe, 0x82, 0xe2, 0x4e, 0x58, 0x32, 0xa7, 0xda, 0x0a, 0x92, + 0x02, 0x0d, 0x95, 0x9c, 0xb1, 0x51, 0x5b, 0x12, 0xf1, 0xac, 0x0d, 0x7c, + 0x57, 0x81, 0xf7, 0x2a, 0x70, 0xae, 0x64, 0xc2, 0x8b, 0xe0, 0xd7, 0x38, + 0xce, 0x65, 0x77, 0x7d, 0xc2, 0xa9, 0x2b, 0x9e, 0x8d, 0x9b, 0x33, 0x23, + 0xed, 0xf3, 0x9c, 0x62, 0x38, 0x2f, 0x75, 0x7e, 0xd6, 0x5f, 0x66, 0xf6, + 0x49, 0x6a, 0x39, 0xa0, 0xce, 0x2b, 0xbd, 0xfa, 0xae, 0xf6, 0x79, 0xd9, + 0x13, 0x94, 0x65, 0x3c, 0x23, 0x91, 0xd4, 0x12, 0xcf, 0x29, 0x9b, 0x0a, + 0x08, 0xcf, 0x2a, 0x24, 0xd9, 0x19, 0x9e, 0x4b, 0x54, 0x92, 0xab, 0x3c, + 0xb3, 0x0d, 0x73, 0x5e, 0xfa, 0x9c, 0x92, 0x7b, 0x9c, 0x53, 0xd2, 0x9c, + 0xd3, 0x76, 0xf3, 0x8a, 0x39, 0xa7, 0x7f, 0x2b, 0x86, 0xe6, 0xdf, 0x10, + 0x07, 0x36, 0x70, 0x10, 0xbc, 0x03, 0x07, 0xdd, 0x6d, 0x1c, 0xc4, 0x6d, + 0xec, 0xe1, 0xae, 0xfd, 0x77, 0xd6, 0x75, 0xee, 0x5d, 0x4a, 0x41, 0x4f, + 0xac, 0x85, 0x0a, 0xe1, 0x0e, 0x48, 0x71, 0x86, 0x30, 0x52, 0xae, 0x6b, + 0x58, 0xf3, 0x2b, 0x94, 0x6d, 0x07, 0x04, 0x34, 0xf1, 0xb6, 0x80, 0x1a, + 0x53, 0x92, 0x85, 0x26, 0xdb, 0x4a, 0x92, 0xcb, 0x80, 0x5e, 0x6b, 0xac, + 0x03, 0x83, 0x6e, 0x6a, 0x3e, 0xde, 0xd1, 0x07, 0xd1, 0x36, 0x1e, 0xf3, + 0x95, 0x38, 0xe4, 0x74, 0x10, 0xe5, 0xd7, 0x50, 0xee, 0xb3, 0x66, 0x6a, + 0x7f, 0x65, 0x49, 0x5f, 0x4b, 0x9c, 0x09, 0xee, 0x31, 0x36, 0x9d, 0x73, + 0x4b, 0x31, 0x47, 0xde, 0x26, 0xce, 0x3b, 0x43, 0x22, 0x83, 0x09, 0xa7, + 0x28, 0xff, 0x05, 0xed, 0x89, 0x58, 0x56, 0xfe, 0xb7, 0x4f, 0xbb, 0xc0, + 0x43, 0xcf, 0xeb, 0x59, 0xf5, 0xc4, 0x7a, 0x8e, 0xcb, 0xa0, 0x2e, 0x24, + 0xb3, 0xd0, 0x31, 0x05, 0x97, 0xeb, 0x71, 0xfe, 0xf8, 0x2c, 0xd7, 0xcd, + 0x37, 0x7d, 0x7d, 0x20, 0xd9, 0x80, 0xc7, 0x36, 0xf2, 0xe5, 0xa4, 0x95, + 0x6f, 0x12, 0x57, 0x19, 0x71, 0x9b, 0x1a, 0x66, 0x0d, 0x6b, 0x1b, 0x4e, + 0xf0, 0x6b, 0x16, 0x34, 0x49, 0xd8, 0xe2, 0xe0, 0x9b, 0x73, 0x01, 0xff, + 0x1c, 0x82, 0xde, 0xa4, 0x2c, 0x42, 0x3f, 0x96, 0x2b, 0x9c, 0xef, 0x33, + 0x56, 0xe0, 0xb2, 0x3f, 0x3f, 0xcf, 0x86, 0x73, 0xeb, 0xf9, 0xca, 0xcd, + 0xd7, 0x0c, 0xef, 0x2b, 0x3d, 0x88, 0xf9, 0x4a, 0x1d, 0xf3, 0x95, 0xc8, + 0xb3, 0x07, 0x94, 0xae, 0x39, 0x4e, 0xfc, 0x9d, 0x47, 0xdb, 0x2d, 0xd0, + 0x08, 0xf9, 0x81, 0xfc, 0x41, 0x5e, 0x7d, 0xb7, 0x8d, 0xfd, 0x76, 0xe0, + 0x76, 0x06, 0x72, 0x98, 0xbc, 0x11, 0x96, 0x7c, 0x94, 0xf5, 0x8f, 0x1b, + 0x98, 0x20, 0x13, 0xd4, 0xfb, 0xf1, 0x1e, 0x5f, 0x3e, 0x82, 0x16, 0x01, + 0xdb, 0xf3, 0x6a, 0x8f, 0xb6, 0xe7, 0x01, 0x37, 0x9d, 0x30, 0x72, 0xdf, + 0x9e, 0x91, 0xdb, 0x3e, 0xbc, 0x3c, 0x2b, 0xca, 0x55, 0xb1, 0xd6, 0x33, + 0x61, 0xc8, 0x70, 0x5b, 0xf2, 0x69, 0xd0, 0x66, 0x3a, 0x60, 0xe4, 0xc3, + 0x8b, 0xc6, 0x56, 0xd2, 0x38, 0x0e, 0x2a, 0x3d, 0xbe, 0x88, 0x79, 0x4f, + 0x00, 0x46, 0xce, 0x19, 0xb4, 0xd6, 0x2a, 0x11, 0xe8, 0x6c, 0xc0, 0xe6, + 0x24, 0xe2, 0x80, 0x09, 0xef, 0x7e, 0x9f, 0x88, 0x2c, 0x6c, 0xfa, 0xeb, + 0x2e, 0xb6, 0xf5, 0x45, 0x49, 0xe1, 0xdb, 0x99, 0x0d, 0xec, 0xd0, 0xc6, + 0xcc, 0xc9, 0xca, 0x99, 0x96, 0xed, 0x92, 0x06, 0xdd, 0xd1, 0x86, 0x44, + 0x26, 0x37, 0x32, 0xef, 0x06, 0xbf, 0xa1, 0x1e, 0x63, 0xca, 0xcd, 0x52, + 0xc4, 0x76, 0x5d, 0x94, 0x94, 0x3f, 0x27, 0xba, 0x6f, 0xb8, 0x3e, 0xbd, + 0x0c, 0x49, 0xc8, 0x6d, 0xb5, 0x36, 0x70, 0x26, 0x47, 0x9b, 0xbf, 0x6c, + 0x7d, 0x35, 0xa8, 0xed, 0x15, 0xdb, 0xfb, 0xa9, 0xa5, 0xd7, 0x8c, 0x4f, + 0x27, 0x15, 0x1e, 0x62, 0x5d, 0xfa, 0xdd, 0x35, 0xef, 0xd7, 0x22, 0x46, + 0x87, 0x99, 0xf7, 0xf9, 0xa0, 0xb6, 0x7f, 0xc2, 0x3d, 0xe4, 0xa3, 0xa0, + 0xe7, 0xf4, 0xe0, 0x9c, 0xc3, 0x21, 0x6f, 0x6a, 0x7c, 0x43, 0xf5, 0x2b, + 0x99, 0x7e, 0xd1, 0x6e, 0x3d, 0xee, 0xd4, 0xf4, 0x88, 0xa2, 0xa1, 0x4f, + 0x4f, 0x0f, 0xab, 0xf2, 0xb3, 0xd3, 0x29, 0x55, 0x2e, 0x4e, 0xbb, 0xaa, + 0x3c, 0xaf, 0xfa, 0x5b, 0xde, 0x90, 0xa9, 0x1f, 0x9d, 0x8e, 0xab, 0x72, + 0xdc, 0x94, 0x69, 0x53, 0x66, 0x4c, 0x39, 0x69, 0x4a, 0xcf, 0x94, 0x59, + 0x53, 0x16, 0xcc, 0x7c, 0x53, 0xe6, 0xfd, 0x98, 0x29, 0x67, 0x4c, 0x79, + 0xdc, 0x94, 0x1f, 0x31, 0xe5, 0x09, 0x03, 0xd7, 0xbc, 0x29, 0x3f, 0x6e, + 0xea, 0x4f, 0x1b, 0x38, 0x3f, 0x03, 0x78, 0x1e, 0x09, 0xed, 0xd0, 0xca, + 0x69, 0x4d, 0x5f, 0x15, 0x47, 0xca, 0x9b, 0xdc, 0x7f, 0x1c, 0x32, 0x25, + 0x88, 0xb3, 0x04, 0xbf, 0x3b, 0xa4, 0x09, 0x17, 0x72, 0x38, 0x88, 0x33, + 0xe4, 0xf3, 0x69, 0xf9, 0x53, 0xf4, 0x1d, 0xbd, 0xe0, 0xc8, 0x62, 0x95, + 0xfa, 0xf5, 0x5b, 0xf2, 0x6a, 0x85, 0xe7, 0xf1, 0xbc, 0xdc, 0xa8, 0xa4, + 0xe2, 0x41, 0x8b, 0x74, 0x94, 0x98, 0x7c, 0x45, 0x12, 0x90, 0xfd, 0x63, + 0x71, 0x96, 0xd7, 0xa8, 0x54, 0xd0, 0xef, 0xa0, 0x5a, 0xfb, 0x79, 0x01, + 0x4c, 0x72, 0xa5, 0xd2, 0x0d, 0x99, 0xf5, 0x4a, 0x8b, 0x7a, 0xfd, 0xfc, + 0xa6, 0xc8, 0xc8, 0x05, 0xe2, 0xf9, 0x5b, 0xb2, 0x51, 0x21, 0xde, 0x9f, + 0x87, 0xad, 0x90, 0x4a, 0xbf, 0x28, 0x89, 0xd1, 0x8b, 0xc2, 0xf9, 0xc6, + 0xd2, 0x28, 0xe3, 0x65, 0xfc, 0xce, 0x41, 0xde, 0x76, 0x4f, 0xe8, 0xf9, + 0x86, 0xcd, 0x7c, 0x2e, 0xec, 0xc2, 0x5b, 0x0e, 0x65, 0xe0, 0x7f, 0xb5, + 0xf4, 0x9e, 0xb4, 0x3c, 0xcc, 0x3a, 0x41, 0x96, 0xb6, 0xcf, 0x23, 0xf6, + 0xc4, 0xf5, 0x16, 0xe4, 0x31, 0xf9, 0xdf, 0xd4, 0x6d, 0x1b, 0xfe, 0x92, + 0x9a, 0xed, 0x81, 0x3e, 0x33, 0xc3, 0x58, 0x83, 0xef, 0x71, 0xd8, 0x9a, + 0x52, 0x22, 0x1e, 0x8a, 0x95, 0x5f, 0xb5, 0xb2, 0x41, 0x6d, 0x9f, 0x6a, + 0x19, 0xc1, 0x76, 0x4b, 0xf2, 0xe8, 0xbb, 0x60, 0x64, 0x66, 0xa1, 0x79, + 0x4b, 0xc9, 0x8d, 0xaf, 0x2b, 0x1a, 0x4e, 0x9c, 0x2f, 0x09, 0x75, 0x86, + 0x1d, 0xa0, 0x4c, 0xbb, 0x92, 0xae, 0xb7, 0x16, 0xaa, 0x94, 0xc1, 0xc3, + 0x52, 0xac, 0x0d, 0x97, 0x6c, 0x94, 0xa7, 0xeb, 0x31, 0x39, 0x5d, 0xe1, + 0x3c, 0xfb, 0xd1, 0xc7, 0x45, 0x1d, 0x18, 0x6b, 0x90, 0xf2, 0x98, 0x6b, + 0xbe, 0x6e, 0xe9, 0x35, 0xb1, 0x07, 0x77, 0xcb, 0xfa, 0x44, 0xf3, 0x9a, + 0x55, 0xac, 0xd3, 0x4e, 0x42, 0x7d, 0xb3, 0x53, 0x66, 0xfb, 0xf2, 0xfa, + 0x79, 0xac, 0x5d, 0xc0, 0x7a, 0x59, 0x25, 0xb3, 0xba, 0x21, 0xf7, 0x7e, + 0x52, 0xf9, 0x72, 0xab, 0x5c, 0x1d, 0x95, 0x8b, 0x9b, 0x71, 0x39, 0x52, + 0x19, 0x97, 0x8d, 0x4d, 0x4f, 0x0a, 0x95, 0xb4, 0xac, 0xa3, 0x4f, 0xbe, + 0x92, 0x91, 0xb5, 0xcd, 0x63, 0xea, 0xac, 0x2f, 0x42, 0x2e, 0x6d, 0xa0, + 0x4f, 0x63, 0x73, 0x12, 0x3f, 0xdf, 0x1e, 0x88, 0xa1, 0xdf, 0x10, 0xfa, + 0x88, 0xf5, 0xb3, 0xca, 0x3d, 0xc0, 0x21, 0xe6, 0xae, 0xfa, 0xb6, 0xc1, + 0xb8, 0x2c, 0x54, 0x79, 0x4e, 0x2f, 0x4c, 0x6f, 0xac, 0xc4, 0xb2, 0xd4, + 0x77, 0xa7, 0x9b, 0xc3, 0xe0, 0x53, 0xe8, 0xef, 0x2a, 0x65, 0x42, 0x50, + 0x8a, 0x90, 0xb5, 0x0d, 0xc0, 0x46, 0x58, 0x1b, 0xb0, 0xdf, 0x8b, 0xcd, + 0x21, 0x94, 0x0e, 0x4a, 0xac, 0x03, 0xd8, 0x8b, 0x4d, 0x17, 0x65, 0x0c, + 0xa5, 0xd6, 0xed, 0x27, 0x9b, 0x9c, 0x3f, 0xab, 0x74, 0x90, 0xc6, 0xf1, + 0xd4, 0x1d, 0xb6, 0x7a, 0xc0, 0x5b, 0xb4, 0x8a, 0x2b, 0x62, 0xe7, 0xd2, + 0x21, 0xfa, 0x0b, 0x90, 0x2b, 0x37, 0x0f, 0x68, 0x58, 0x3e, 0x1b, 0xa0, + 0xdc, 0x09, 0xba, 0xe7, 0x81, 0xaf, 0x5e, 0xc9, 0x06, 0x69, 0x73, 0xf1, + 0x59, 0x5a, 0x01, 0xcf, 0xa5, 0xad, 0x12, 0x0c, 0x50, 0x5f, 0x45, 0xd9, + 0xa7, 0xde, 0xa2, 0x5c, 0xca, 0xd5, 0xb4, 0x6d, 0x5e, 0x6a, 0xdb, 0xe6, + 0xeb, 0xa8, 0xb7, 0x20, 0x3b, 0xe0, 0x9b, 0xd4, 0x79, 0x1e, 0x03, 0x98, + 0x33, 0x6b, 0x15, 0x2a, 0xfe, 0x79, 0xd6, 0x5b, 0x4f, 0x54, 0x69, 0xaf, + 0xd1, 0x6e, 0x53, 0xf2, 0x49, 0x92, 0xcb, 0x71, 0x23, 0x83, 0x23, 0x8a, + 0x37, 0x88, 0x83, 0xe4, 0x72, 0xda, 0xd4, 0x75, 0x77, 0xd4, 0xf9, 0xb2, + 0xfa, 0x73, 0x80, 0x61, 0x48, 0x9d, 0xad, 0xed, 0x4d, 0x59, 0x39, 0x65, + 0x2b, 0xb6, 0x5a, 0x79, 0x37, 0x24, 0xc5, 0xf1, 0x3f, 0xc2, 0x9e, 0xd8, + 0x56, 0x72, 0x40, 0x5a, 0xe0, 0xbb, 0xca, 0x07, 0xe6, 0xdc, 0x84, 0xb2, + 0xb3, 0x72, 0x15, 0xf8, 0x38, 0x5a, 0xd5, 0x95, 0xfa, 0xa1, 0x87, 0xdc, + 0x25, 0xd2, 0x53, 0xbd, 0xb5, 0x0c, 0x9c, 0xce, 0x2c, 0x15, 0xac, 0xe4, + 0x12, 0xe8, 0x63, 0x10, 0xb6, 0x87, 0x1b, 0x91, 0xdc, 0x65, 0xd2, 0x11, + 0xfb, 0xb0, 0xbe, 0x4b, 0x66, 0xa2, 0xbb, 0x6d, 0x9b, 0x87, 0x0e, 0x68, + 0x9d, 0x8f, 0xbe, 0x4b, 0x70, 0xe6, 0x7a, 0xb5, 0x9f, 0x92, 0x5c, 0xa5, + 0x9c, 0x2d, 0x40, 0xd7, 0x53, 0xe7, 0xf4, 0xc0, 0x9e, 0x61, 0x3d, 0xe7, + 0x44, 0xdb, 0xc5, 0xac, 0x05, 0xfd, 0x66, 0x97, 0x95, 0x8d, 0x3e, 0x89, + 0xf2, 0xde, 0x20, 0x6d, 0x5b, 0xea, 0x90, 0xe4, 0xaa, 0x3f, 0x47, 0x27, + 0x3e, 0xf6, 0x29, 0x9d, 0x34, 0xe0, 0x0d, 0xa8, 0x79, 0x61, 0x97, 0x58, + 0x73, 0x6a, 0xde, 0x58, 0xc7, 0xbc, 0x68, 0xbb, 0xf8, 0xb7, 0x01, 0x3d, + 0x0f, 0xf0, 0xac, 0xf6, 0xc4, 0x36, 0x8e, 0x29, 0x58, 0x79, 0xd8, 0x4e, + 0x33, 0x69, 0x5b, 0x02, 0x83, 0x7e, 0x5f, 0xbd, 0xaf, 0x02, 0xf6, 0x95, + 0xc3, 0xbe, 0xec, 0xc1, 0xdd, 0xfb, 0x2a, 0x05, 0xf4, 0xbe, 0x06, 0x3a, + 0x60, 0x8a, 0xee, 0x5a, 0xbf, 0x73, 0x5f, 0x68, 0xbb, 0xb8, 0x7b, 0x8e, + 0xc7, 0x06, 0xf4, 0x1c, 0xd1, 0x8e, 0x39, 0x06, 0x77, 0xcd, 0x01, 0x7a, + 0x8e, 0x72, 0xfc, 0xe0, 0x1e, 0xe3, 0x5f, 0xef, 0xd5, 0xe3, 0x39, 0xa6, + 0x0b, 0x7a, 0x58, 0x9d, 0x75, 0x58, 0xc9, 0xd4, 0xb6, 0xad, 0x76, 0x1a, + 0x3a, 0xaf, 0x73, 0xcc, 0x9d, 0x76, 0xa6, 0xad, 0xec, 0xcc, 0x3b, 0xe8, + 0xcc, 0x7a, 0x14, 0x3e, 0x73, 0x6a, 0x19, 0xbe, 0x73, 0xe5, 0xed, 0x58, + 0xf7, 0xcf, 0xe0, 0x87, 0x42, 0x16, 0x8d, 0xd2, 0x2f, 0x98, 0x14, 0xe5, + 0x97, 0x8e, 0xc2, 0xff, 0x75, 0xf6, 0x29, 0x5b, 0xb4, 0x38, 0x3a, 0xee, + 0xfb, 0x0b, 0xd6, 0x2c, 0xe4, 0x46, 0x71, 0x14, 0x36, 0x7d, 0x14, 0xf8, + 0x72, 0x47, 0x30, 0x8e, 0xf0, 0xbc, 0x3b, 0x44, 0x9f, 0xf5, 0x99, 0xea, + 0x2c, 0xde, 0xf7, 0xa1, 0xfd, 0xe7, 0x06, 0xce, 0x3e, 0xf4, 0xf9, 0x57, + 0xa8, 0x63, 0x1b, 0xfb, 0x70, 0x8a, 0x1f, 0xe0, 0xfd, 0x41, 0xf4, 0x01, + 0x4f, 0x81, 0x53, 0x6c, 0xf7, 0x30, 0x7e, 0x2f, 0xa3, 0xee, 0xdd, 0xa8, + 0xbb, 0x8e, 0xba, 0x43, 0x78, 0xff, 0xe1, 0xae, 0x79, 0xdf, 0x81, 0xf7, + 0xcf, 0xa1, 0x1d, 0xfb, 0x77, 0x5e, 0x44, 0xfb, 0x83, 0xf8, 0xfd, 0xc5, + 0xae, 0x3e, 0x8d, 0x5d, 0xef, 0xbe, 0xbc, 0x79, 0xc9, 0xf0, 0xc0, 0x8e, + 0x6f, 0x07, 0xfe, 0xb1, 0xa8, 0x8f, 0x0a, 0x15, 0xca, 0x9b, 0xb0, 0x3c, + 0xb2, 0xe2, 0xcb, 0x1c, 0x91, 0x79, 0xc8, 0xfa, 0x42, 0x45, 0xbc, 0x6e, + 0x19, 0x9e, 0xfc, 0x31, 0x64, 0xfa, 0x3c, 0xf0, 0x5a, 0x80, 0x7d, 0x71, + 0x74, 0x25, 0x8c, 0xe7, 0x21, 0xc8, 0x3b, 0xc9, 0x74, 0x09, 0x79, 0x3e, + 0x02, 0xd9, 0xd2, 0x0b, 0x9e, 0x57, 0x3e, 0x88, 0x3c, 0x0e, 0xb9, 0x34, + 0x8b, 0xbe, 0xb3, 0xe8, 0xf3, 0xd1, 0xe6, 0xff, 0x31, 0xb4, 0xec, 0xc3, + 0xf0, 0xec, 0x2e, 0x18, 0xc2, 0xe2, 0xae, 0x92, 0x1f, 0x5f, 0x98, 0x9e, + 0x5b, 0x89, 0xc8, 0xf0, 0xaa, 0x9d, 0xa4, 0xb3, 0x3f, 0xb2, 0xca, 0x98, + 0x84, 0x8c, 0x04, 0x85, 0xb2, 0x5f, 0xc6, 0x43, 0xb0, 0xd1, 0x02, 0xde, + 0x30, 0x74, 0x94, 0x7a, 0x97, 0x2c, 0x60, 0xcb, 0x36, 0x77, 0x62, 0x13, + 0x47, 0xda, 0xb1, 0x89, 0x21, 0xe8, 0x88, 0xd7, 0x83, 0x5a, 0x5e, 0x45, + 0x40, 0x27, 0x6f, 0x01, 0xfe, 0x29, 0x5b, 0x42, 0xe0, 0x1f, 0x07, 0xbc, + 0xf3, 0x26, 0xda, 0x6f, 0xd4, 0x5b, 0xa0, 0x77, 0xc8, 0x38, 0x9b, 0xf5, + 0x2c, 0xd1, 0x96, 0x21, 0x0f, 0xe0, 0xbd, 0xd1, 0xc9, 0x6b, 0xe7, 0xb4, + 0x8d, 0x75, 0x97, 0x6f, 0xf3, 0xa0, 0xa3, 0x69, 0x91, 0xf6, 0xfa, 0xe1, + 0xd0, 0x9d, 0x7b, 0xfc, 0xa3, 0x5d, 0x7b, 0x0c, 0x4a, 0x72, 0x89, 0xf8, + 0x8d, 0xa8, 0xbd, 0xfa, 0xf8, 0x2d, 0x2a, 0x5b, 0x7e, 0x1c, 0x3e, 0x89, + 0x40, 0x9a, 0x2b, 0x5b, 0x14, 0x3a, 0xb1, 0x0f, 0xb2, 0x9e, 0x72, 0x9e, + 0xf8, 0x0e, 0x03, 0x87, 0x11, 0xfc, 0x1c, 0xfc, 0x76, 0x70, 0x7a, 0xb2, + 0xbd, 0x3f, 0x7f, 0x0f, 0xeb, 0x90, 0x55, 0x2c, 0x09, 0x3f, 0xf0, 0x71, + 0x91, 0xcf, 0x90, 0xaf, 0x7d, 0x94, 0xb7, 0x3e, 0x4c, 0x8f, 0xed, 0x82, + 0x89, 0xb8, 0x21, 0x4c, 0xf5, 0x16, 0x6c, 0x8b, 0x28, 0xa3, 0x60, 0xa7, + 0x9b, 0xd4, 0x29, 0x5c, 0x73, 0x92, 0xf6, 0xb6, 0x81, 0x93, 0x7a, 0xc5, + 0x93, 0x73, 0x95, 0xb7, 0x1b, 0xb8, 0x78, 0xbe, 0xb0, 0xf9, 0x96, 0xb8, + 0x7e, 0x54, 0xe9, 0x1e, 0x0d, 0xd3, 0x6e, 0xfc, 0xd0, 0x3f, 0x27, 0x7e, + 0xa8, 0x0f, 0x88, 0x4b, 0xda, 0xd4, 0xc4, 0xe7, 0xef, 0x00, 0x9f, 0xec, + 0xeb, 0x1a, 0xdd, 0xf2, 0x2e, 0x03, 0xd7, 0xdd, 0xfa, 0xf8, 0xf4, 0x1d, + 0xfa, 0xd8, 0xc7, 0xf1, 0x5e, 0x67, 0xf1, 0xfb, 0x7d, 0xbe, 0xcc, 0x1d, + 0x5e, 0xdd, 0xab, 0x7d, 0xd9, 0xb4, 0xb3, 0xad, 0xb3, 0xfe, 0xdb, 0x7d, + 0xfe, 0x19, 0x0e, 0x2f, 0xef, 0x6e, 0xeb, 0x3b, 0xb0, 0x33, 0x66, 0xf7, + 0x7c, 0x3f, 0xee, 0xdb, 0xdb, 0xaf, 0xdd, 0xf1, 0xeb, 0xe0, 0xab, 0xd8, + 0x3b, 0x7b, 0xc9, 0xda, 0xf3, 0xcd, 0x82, 0xad, 0xf7, 0xc2, 0x3e, 0x68, + 0x6b, 0x6e, 0xf5, 0x07, 0x95, 0x6e, 0xcc, 0xda, 0xf4, 0x63, 0x4a, 0x6b, + 0x7c, 0xbe, 0x07, 0x65, 0xe7, 0xd8, 0x21, 0xf0, 0x40, 0x16, 0x7d, 0x39, + 0xc7, 0xee, 0xf1, 0xbe, 0x8d, 0x94, 0x96, 0x85, 0x5a, 0x08, 0xed, 0x89, + 0x6c, 0x49, 0x1e, 0x86, 0xaf, 0x98, 0x98, 0xa2, 0xdf, 0x00, 0x7f, 0x79, + 0x46, 0xe4, 0x98, 0x94, 0x6b, 0x1f, 0x94, 0x85, 0x95, 0x96, 0xbc, 0x1f, + 0x7a, 0xf0, 0xf7, 0xa0, 0x47, 0xe5, 0x12, 0x84, 0xd7, 0x25, 0x1c, 0xc6, + 0xa5, 0xa8, 0xd8, 0x4f, 0xc1, 0x96, 0xbf, 0x10, 0x93, 0xe0, 0x05, 0xd2, + 0x5e, 0xca, 0x79, 0xbf, 0x48, 0xbf, 0x2d, 0x57, 0xe1, 0x08, 0x25, 0x26, + 0xb3, 0x92, 0x82, 0xfd, 0x37, 0xe6, 0x34, 0x50, 0x96, 0x25, 0x35, 0xfa, + 0xb4, 0xa0, 0xef, 0x25, 0xf4, 0xc5, 0xb8, 0x9e, 0x8d, 0x38, 0x7e, 0x83, + 0xd2, 0xbb, 0x41, 0x18, 0x92, 0xa6, 0x24, 0x2c, 0x3f, 0x6c, 0xd1, 0xd7, + 0x7d, 0x66, 0x33, 0x0c, 0xdd, 0x14, 0x97, 0xe7, 0x20, 0x67, 0x9f, 0x55, + 0xf1, 0x17, 0xb7, 0xed, 0x8f, 0x3e, 0x7a, 0x18, 0x74, 0xb7, 0x2c, 0xe1, + 0xa8, 0xf7, 0x73, 0x59, 0x59, 0x6e, 0xc1, 0xef, 0xa1, 0xac, 0x7f, 0x00, + 0xf2, 0x2a, 0xf1, 0xa5, 0x12, 0x6d, 0x49, 0x37, 0x03, 0xd8, 0x4b, 0x32, + 0x73, 0xf8, 0x5d, 0x03, 0x9a, 0x3e, 0x8e, 0x49, 0x70, 0xb9, 0x00, 0xfb, + 0xf9, 0x8c, 0x2c, 0xa6, 0xe1, 0x9f, 0xda, 0xa5, 0x56, 0xc0, 0x75, 0x63, + 0xd0, 0xdb, 0xd0, 0xa7, 0x2b, 0xf4, 0x87, 0xe5, 0xc8, 0x32, 0xfb, 0x9c, + 0x01, 0x6d, 0x75, 0x01, 0x77, 0xdd, 0x72, 0x36, 0x9a, 0x28, 0xe5, 0xc1, + 0x4f, 0xb6, 0xdb, 0x0f, 0x5e, 0x66, 0x49, 0xfd, 0xf6, 0x34, 0xe8, 0x87, + 0xcf, 0x38, 0xce, 0x55, 0xd6, 0x27, 0x51, 0xb2, 0xde, 0x15, 0x7b, 0x29, + 0x8c, 0xb9, 0xa0, 0x93, 0x2e, 0x97, 0xe4, 0x6c, 0xe6, 0x98, 0x34, 0x6a, + 0xf0, 0xc9, 0x33, 0xb0, 0xa3, 0xea, 0x9e, 0x34, 0x2a, 0xb4, 0x9f, 0x4e, + 0x81, 0x1f, 0x5e, 0x41, 0x39, 0x8f, 0xf2, 0x16, 0xca, 0x8f, 0xa3, 0x7c, + 0x0d, 0x25, 0x61, 0x3f, 0x25, 0x8d, 0xfa, 0x55, 0xcc, 0xcd, 0x39, 0xa6, + 0x0c, 0xcc, 0xf0, 0x21, 0x0f, 0x9f, 0x82, 0x9d, 0xe3, 0xd7, 0x9f, 0x12, + 0x69, 0x7c, 0x0c, 0xbf, 0x96, 0x7a, 0xa7, 0x8f, 0xb9, 0x90, 0x99, 0x84, + 0xbd, 0x2b, 0xd6, 0xd9, 0xcc, 0xc7, 0xcd, 0x3c, 0x1f, 0xc3, 0x7a, 0xd7, + 0xb1, 0x76, 0x18, 0xe7, 0xd9, 0x92, 0x47, 0xd3, 0x67, 0xe4, 0x93, 0xe9, + 0x7b, 0x65, 0x62, 0x20, 0x5c, 0x0a, 0x7b, 0xdc, 0x3f, 0xed, 0xda, 0xbd, + 0xf6, 0xef, 0xef, 0x9b, 0x7b, 0x8e, 0x60, 0x2f, 0xfb, 0xb5, 0xed, 0x66, + 0xff, 0x13, 0xe3, 0x73, 0x58, 0x92, 0x1c, 0xe1, 0x7c, 0x9e, 0x04, 0x96, + 0x47, 0x9c, 0x8c, 0x3d, 0x06, 0xeb, 0x3d, 0x85, 0xdf, 0x19, 0xd0, 0x8a, + 0x7b, 0x3e, 0x69, 0xff, 0x47, 0xc0, 0x84, 0xb6, 0x06, 0xd7, 0x11, 0x2b, + 0x78, 0xe8, 0x26, 0xf6, 0x56, 0x92, 0xee, 0x43, 0x9e, 0xdc, 0x6e, 0xf2, + 0x19, 0x92, 0xf2, 0xd2, 0x31, 0xf9, 0x71, 0xed, 0xba, 0x9c, 0xab, 0x1d, + 0x93, 0x97, 0x51, 0x2e, 0xd6, 0x4a, 0xc0, 0x23, 0x7d, 0x46, 0xce, 0xd1, + 0xc2, 0xb9, 0x50, 0x2e, 0xdf, 0x1f, 0x9b, 0xc7, 0xf9, 0xcd, 0x3a, 0x2d, + 0xd9, 0x48, 0x97, 0x64, 0x63, 0x12, 0x63, 0xea, 0x3d, 0x12, 0xfa, 0x2a, + 0xf7, 0xdb, 0x27, 0xf9, 0x5a, 0x49, 0x0a, 0x19, 0xfa, 0x34, 0xbd, 0x92, + 0x87, 0x4d, 0x0e, 0x3b, 0xe8, 0x8c, 0x8e, 0xb3, 0xb9, 0xb1, 0x22, 0x6c, + 0xf8, 0x85, 0xe6, 0xeb, 0x56, 0xa3, 0x6d, 0xff, 0x6f, 0x59, 0xcf, 0xc2, + 0x76, 0xfd, 0x0e, 0xe4, 0xc6, 0x73, 0xb0, 0x09, 0x9f, 0xbd, 0x83, 0xc7, + 0x48, 0x23, 0xd7, 0xac, 0x46, 0x7d, 0x94, 0x7c, 0x66, 0xf8, 0x01, 0x63, + 0xe1, 0xe7, 0x34, 0x6a, 0xb7, 0x0c, 0xfd, 0x29, 0x5b, 0x00, 0xe7, 0x42, + 0xbd, 0xf2, 0x77, 0xf0, 0xaf, 0x28, 0x77, 0x7c, 0xbd, 0xaf, 0xfd, 0x86, + 0x3a, 0x60, 0xcd, 0x47, 0x13, 0x80, 0x4a, 0xa4, 0x5e, 0x2f, 0x28, 0x5c, + 0xb9, 0xcb, 0x43, 0x52, 0xab, 0x12, 0xbf, 0x09, 0xc7, 0xb6, 0x95, 0x5d, + 0x0b, 0xbc, 0xba, 0x38, 0x1f, 0xbf, 0x3d, 0x01, 0xff, 0xe1, 0x8c, 0x38, + 0x13, 0xbd, 0xd8, 0x13, 0x9f, 0x45, 0x66, 0x2e, 0xff, 0x3a, 0x19, 0xd0, + 0x05, 0xbf, 0x3e, 0x84, 0xb3, 0x8c, 0xc8, 0x59, 0xd8, 0xff, 0xe7, 0x40, + 0x47, 0x9f, 0xaf, 0x0c, 0xc9, 0xf9, 0x4a, 0x1c, 0xfe, 0x16, 0xed, 0x94, + 0xe5, 0xe9, 0xe4, 0x3a, 0xcb, 0x27, 0xa6, 0x53, 0x75, 0x96, 0x5f, 0x32, + 0xfe, 0xe2, 0x97, 0x8d, 0x1f, 0xb9, 0x3e, 0xad, 0x7d, 0xb8, 0xaf, 0x4d, + 0x8f, 0xaa, 0xb2, 0x39, 0xbd, 0x13, 0x3b, 0x09, 0x1b, 0xbd, 0x9d, 0xa1, + 0x7e, 0x06, 0x8c, 0x12, 0x3c, 0x09, 0x7a, 0x9a, 0x87, 0xdc, 0xce, 0xc1, + 0xf7, 0x38, 0x0b, 0x1f, 0xa4, 0xd8, 0x84, 0x4c, 0xf0, 0xd2, 0x28, 0xc5, + 0xfc, 0xf9, 0x63, 0xbb, 0x18, 0xdf, 0xe4, 0x99, 0x19, 0xff, 0x2b, 0x4d, + 0xff, 0xab, 0xf3, 0x8f, 0xf3, 0x81, 0x36, 0xa9, 0x2b, 0x7f, 0x09, 0x9f, + 0x51, 0x82, 0xc5, 0x0c, 0xc7, 0xa6, 0xe9, 0xaf, 0xca, 0x36, 0xec, 0x83, + 0xb0, 0xf7, 0x3d, 0x09, 0x3f, 0xd5, 0x6a, 0xbd, 0x0a, 0x59, 0x53, 0x82, + 0xcf, 0x68, 0x5b, 0xa8, 0x5f, 0x67, 0x1b, 0xe5, 0xc8, 0x98, 0x73, 0x1b, + 0x34, 0x97, 0x3d, 0x2e, 0xf2, 0x5d, 0xd4, 0x35, 0x56, 0x78, 0x06, 0xdf, + 0xc7, 0x19, 0x98, 0x33, 0x51, 0x75, 0xec, 0x07, 0xfb, 0x3d, 0xca, 0x7d, + 0x8c, 0x39, 0xdd, 0x18, 0x5f, 0x5f, 0xe7, 0x98, 0xc4, 0x24, 0xaf, 0x74, + 0xbe, 0xbb, 0xae, 0xf7, 0x77, 0x34, 0x33, 0x2a, 0x57, 0x2b, 0x6a, 0x0e, + 0xd0, 0xfa, 0xaf, 0x30, 0x66, 0x0b, 0x74, 0xcb, 0x18, 0x95, 0x27, 0x65, + 0xe8, 0xa4, 0x72, 0x25, 0x05, 0xda, 0x09, 0xca, 0x6c, 0x8c, 0x60, 0xbb, + 0xb2, 0x5d, 0xf9, 0x72, 0x97, 0x8e, 0x8f, 0xf0, 0x19, 0x3a, 0xac, 0x39, + 0x23, 0xbc, 0x1b, 0x81, 0x7d, 0x83, 0x3d, 0x75, 0xe2, 0x42, 0xff, 0x15, + 0x71, 0x16, 0x66, 0x8f, 0xea, 0x4f, 0xaf, 0x83, 0xf1, 0x66, 0x9d, 0x02, + 0x14, 0x77, 0x1e, 0xeb, 0xa7, 0x2e, 0x05, 0x83, 0x8c, 0xa9, 0x27, 0x2f, + 0x81, 0xad, 0x3c, 0x83, 0x8b, 0xa6, 0x4f, 0x6b, 0xbe, 0x2f, 0x4a, 0xda, + 0x22, 0x0e, 0x12, 0xa5, 0x2d, 0x20, 0x7b, 0xc0, 0xbb, 0x21, 0x1f, 0x5a, + 0xd5, 0x7b, 0xb6, 0x2f, 0x0a, 0xef, 0x5b, 0xe4, 0xf6, 0x4a, 0x22, 0x7d, + 0x0b, 0xb2, 0x39, 0x1f, 0x4d, 0x83, 0x56, 0x3e, 0xd1, 0x05, 0x9e, 0x9e, + 0xcc, 0xda, 0x3f, 0xe8, 0xd2, 0xb6, 0x20, 0x7c, 0x7e, 0xc6, 0x01, 0x2a, + 0x59, 0x8c, 0xe9, 0x96, 0x7f, 0x11, 0xc4, 0x73, 0x93, 0xef, 0xb0, 0x73, + 0x82, 0x1a, 0xbe, 0xb2, 0xc1, 0x21, 0xfc, 0x04, 0xd1, 0xb1, 0x5c, 0x4b, + 0x3e, 0x04, 0x29, 0x2f, 0x98, 0x3f, 0x69, 0xd6, 0x4a, 0x5e, 0x0c, 0xb7, + 0x6d, 0xba, 0xd4, 0xaa, 0x07, 0xdb, 0x22, 0x68, 0x7c, 0x22, 0xca, 0x18, + 0xd9, 0xc3, 0xa6, 0xee, 0xb4, 0x8f, 0xc3, 0x2a, 0x5e, 0xc7, 0x7b, 0x24, + 0xd2, 0xd6, 0x94, 0xa1, 0xad, 0x8f, 0x81, 0xb6, 0x4e, 0x29, 0xda, 0x6a, + 0xc9, 0xab, 0xe9, 0xb4, 0x7c, 0x61, 0x4f, 0xfa, 0xda, 0xfd, 0x17, 0x01, + 0xbc, 0xfc, 0x0d, 0xca, 0xc2, 0x17, 0xb1, 0x2e, 0xf4, 0x4e, 0xb9, 0x92, + 0xc8, 0xce, 0xd2, 0x16, 0x82, 0x1e, 0x29, 0xc3, 0xe7, 0x4a, 0x5e, 0x1a, + 0x52, 0x7d, 0x92, 0xd0, 0x29, 0x0d, 0xd0, 0x1b, 0xf1, 0x5b, 0xae, 0x40, + 0x0e, 0x5f, 0x0a, 0x41, 0x6f, 0x91, 0x67, 0x65, 0xc0, 0x86, 0x6c, 0x60, + 0xff, 0x06, 0x78, 0x27, 0x79, 0x29, 0x82, 0x32, 0xae, 0xe6, 0x6a, 0x54, + 0x5c, 0x35, 0xbe, 0x51, 0x19, 0x55, 0xe3, 0x1a, 0xb0, 0x5f, 0x93, 0x97, + 0x20, 0xdf, 0x33, 0x69, 0x19, 0xb9, 0x94, 0x91, 0xf8, 0x25, 0x4b, 0x8a, + 0x33, 0xad, 0x56, 0x18, 0xb0, 0x8f, 0x5e, 0xea, 0x97, 0x5b, 0x2a, 0xb6, + 0x1a, 0x56, 0xf1, 0xd6, 0xc5, 0xcc, 0x0c, 0x78, 0x93, 0xf8, 0xf3, 0x30, + 0xa6, 0x00, 0xfd, 0x58, 0x90, 0xb3, 0x2b, 0xc4, 0x0f, 0xe3, 0xe5, 0xdb, + 0xb1, 0x80, 0x24, 0x20, 0xcb, 0x8e, 0xcb, 0x7c, 0xad, 0x1b, 0xb2, 0x2c, + 0x08, 0x1d, 0xf8, 0x50, 0xb7, 0xf4, 0x0e, 0x93, 0x1e, 0x80, 0x17, 0x0f, + 0x73, 0x17, 0x24, 0x8f, 0x31, 0x85, 0x95, 0x9d, 0xfe, 0x45, 0xe9, 0x06, + 0x4f, 0x1d, 0x97, 0x93, 0x35, 0xce, 0x13, 0x74, 0xca, 0x72, 0x10, 0x34, + 0xe4, 0x3a, 0x47, 0x30, 0x0f, 0xf4, 0x76, 0xc7, 0x1f, 0xf9, 0x2f, 0xfb, + 0x06, 0x34, 0xe9, 0xf3, 0x5d, 0xb8, 0xd4, 0xe5, 0xcd, 0x58, 0xdb, 0x19, + 0x09, 0xce, 0x65, 0x3e, 0x60, 0x7d, 0x37, 0x93, 0xb1, 0xae, 0x65, 0xb2, + 0xd6, 0xf5, 0x4c, 0xc1, 0xba, 0x01, 0xdd, 0xd4, 0xd8, 0x7c, 0x0e, 0xf4, + 0x03, 0xdd, 0xcf, 0x98, 0x79, 0xfb, 0x0c, 0xa3, 0x26, 0x66, 0xf0, 0x9a, + 0x6c, 0x54, 0x68, 0x3b, 0xb4, 0x1e, 0x9e, 0x4b, 0x97, 0xee, 0x01, 0x7c, + 0x80, 0x83, 0xbe, 0xee, 0x8e, 0xee, 0x08, 0x79, 0xa3, 0xb2, 0xa6, 0x74, + 0x47, 0x84, 0xba, 0x23, 0x9d, 0x97, 0xfd, 0xb2, 0x5d, 0x03, 0xff, 0x89, + 0xb2, 0x83, 0x65, 0xbb, 0x1e, 0x95, 0x2f, 0x54, 0x7d, 0x5a, 0xe2, 0x7e, + 0xcb, 0x6f, 0xea, 0x91, 0x80, 0x4c, 0x29, 0x7d, 0xdd, 0x27, 0x57, 0xd7, + 0xe1, 0x0f, 0xc1, 0x5a, 0xb0, 0xef, 0x63, 0xac, 0xc0, 0x56, 0xbe, 0xb1, + 0xf4, 0xf3, 0xee, 0xea, 0x2c, 0x70, 0xc5, 0xfb, 0x25, 0xec, 0xb3, 0x9f, + 0x3b, 0xf2, 0xdf, 0xc7, 0xc1, 0x93, 0x7c, 0xb6, 0x24, 0x0f, 0xbb, 0x91, + 0xf7, 0x5c, 0x79, 0xd8, 0x3d, 0xdb, 0x95, 0x31, 0xc0, 0x15, 0x80, 0x4d, + 0x1e, 0x06, 0x1c, 0x55, 0xd5, 0xde, 0xed, 0x8a, 0x35, 0x07, 0x3d, 0x5c, + 0x54, 0xf7, 0x57, 0x28, 0xd7, 0xf5, 0xda, 0x79, 0xf8, 0xab, 0xc5, 0xf1, + 0x1e, 0xea, 0xb7, 0xd1, 0x12, 0xf9, 0x5e, 0xd9, 0xf1, 0x19, 0xf0, 0xdc, + 0x57, 0xba, 0xa9, 0xdb, 0x8f, 0xa6, 0x27, 0xe5, 0x46, 0x85, 0xcf, 0x6c, + 0x4f, 0xa4, 0x45, 0xc5, 0x8f, 0x2b, 0xd3, 0x8b, 0xee, 0x6b, 0x86, 0xc7, + 0x6a, 0xa0, 0xf1, 0x53, 0xf2, 0x8d, 0xcd, 0x79, 0xf9, 0xf7, 0x9b, 0xb3, + 0xb0, 0x4f, 0x4e, 0xc0, 0x3e, 0xf9, 0x08, 0x78, 0xf8, 0x38, 0x78, 0xf8, + 0xe3, 0xa0, 0xfb, 0x19, 0x15, 0x77, 0xa8, 0x55, 0x12, 0x57, 0x4a, 0x2a, + 0xce, 0xfd, 0x1a, 0x68, 0x7e, 0x42, 0x82, 0xab, 0x43, 0xc0, 0x6b, 0xa9, + 0x15, 0x75, 0x5b, 0x0f, 0xc3, 0x06, 0xc1, 0x59, 0x97, 0x12, 0x41, 0x45, + 0x23, 0xae, 0xf3, 0x69, 0xe0, 0xf2, 0x4d, 0x5e, 0xa2, 0xc6, 0x23, 0xde, + 0xa8, 0x8d, 0x4a, 0xf1, 0x32, 0xfa, 0x2f, 0x47, 0x80, 0x37, 0xea, 0xc6, + 0xc4, 0xf9, 0xa2, 0x6c, 0x81, 0x2e, 0xb2, 0xc0, 0xcf, 0x3b, 0xa4, 0x1c, + 0x4d, 0x7c, 0x4d, 0x64, 0x52, 0x0e, 0x2d, 0x81, 0xa6, 0x97, 0x6c, 0xec, + 0x99, 0xb8, 0xc4, 0xf3, 0x65, 0x4f, 0xec, 0x65, 0xca, 0xa2, 0x03, 0xc6, + 0x37, 0xd1, 0xfa, 0xbe, 0x2e, 0x5c, 0x97, 0xeb, 0x7d, 0x46, 0xe6, 0xa1, + 0x53, 0x61, 0x7f, 0x43, 0x66, 0xbb, 0x31, 0xac, 0x19, 0x9e, 0xbb, 0xec, + 0x84, 0xe7, 0x2f, 0x73, 0x9e, 0xb0, 0x04, 0x96, 0x78, 0xb6, 0x9c, 0x07, + 0x3c, 0x80, 0xb9, 0x53, 0x4b, 0xc4, 0xdb, 0x18, 0xc6, 0xfd, 0x63, 0xe8, + 0x63, 0x4d, 0x57, 0xb9, 0x65, 0x2d, 0x1f, 0x72, 0x8d, 0x4e, 0x9d, 0x88, + 0x33, 0x80, 0xfc, 0xc8, 0x36, 0xb4, 0x7e, 0x2b, 0x28, 0xfd, 0xa7, 0x75, + 0xdf, 0x71, 0x81, 0x51, 0xd7, 0xeb, 0xaa, 0xfd, 0x04, 0x96, 0xb7, 0xa8, + 0xef, 0xb1, 0x06, 0xc7, 0x84, 0x3a, 0xe0, 0xce, 0x40, 0xee, 0xdc, 0x1b, + 0x26, 0xee, 0x1f, 0x83, 0x7e, 0x4d, 0x2e, 0xe9, 0x98, 0x7c, 0xf2, 0x72, + 0x1a, 0xfb, 0x91, 0x41, 0x46, 0x17, 0x6c, 0xec, 0xe1, 0x7d, 0x4a, 0x7e, + 0x4d, 0x40, 0x66, 0x39, 0xb2, 0x7e, 0x90, 0x67, 0x33, 0x28, 0x8d, 0xa7, + 0xf9, 0xce, 0x33, 0xe2, 0x79, 0x93, 0x17, 0xa3, 0xd0, 0x2f, 0x38, 0xa7, + 0xbe, 0x21, 0xa9, 0x6f, 0xb2, 0x6d, 0x48, 0xd1, 0x72, 0x10, 0x67, 0xb0, + 0x58, 0x69, 0x3d, 0x9c, 0x4b, 0x97, 0x40, 0x6d, 0xc4, 0x39, 0xf1, 0x41, + 0xbc, 0x8f, 0x03, 0x36, 0xe2, 0xb8, 0x8f, 0xba, 0x18, 0x75, 0xfb, 0xa5, + 0x58, 0x23, 0x3d, 0xa3, 0xac, 0xef, 0x37, 0xbe, 0xde, 0x67, 0x78, 0x27, + 0x84, 0xbd, 0x6b, 0x3a, 0x2e, 0x80, 0xa6, 0xca, 0xf0, 0xbb, 0xae, 0x2e, + 0x49, 0xf8, 0x4d, 0x90, 0xcf, 0x9f, 0xa2, 0x0c, 0x05, 0x7d, 0x95, 0xd7, + 0x27, 0x40, 0x6b, 0x7d, 0x90, 0x97, 0xad, 0xd6, 0x71, 0xd8, 0xc9, 0xa7, + 0xd3, 0xc4, 0xd1, 0x4d, 0xe0, 0xa8, 0x3b, 0x76, 0x1a, 0xe7, 0xb5, 0xf6, + 0xf4, 0x43, 0x4a, 0x5e, 0xc0, 0xd6, 0x51, 0x7a, 0x4b, 0xc7, 0x38, 0xd2, + 0xb4, 0x8d, 0x14, 0x0f, 0xe7, 0x5c, 0xca, 0xc3, 0x3c, 0xf0, 0x30, 0xae, + 0xe4, 0xb7, 0x96, 0x2d, 0x3d, 0x52, 0x3c, 0x9e, 0xc5, 0x7e, 0x27, 0x77, + 0xf5, 0xcb, 0xe0, 0x1d, 0xb6, 0x5f, 0xf3, 0x43, 0x61, 0xc6, 0x43, 0x03, + 0xde, 0xa4, 0x6c, 0x1c, 0x9c, 0x92, 0x8b, 0x07, 0x13, 0x93, 0xb3, 0x36, + 0x75, 0xc2, 0x94, 0xd4, 0x9f, 0xce, 0xca, 0x5a, 0x55, 0xeb, 0xe6, 0x39, + 0x77, 0x52, 0xf2, 0xcd, 0x02, 0xde, 0x3d, 0x94, 0xec, 0xef, 0xcb, 0x5d, + 0x7f, 0x4f, 0x39, 0xee, 0x09, 0x32, 0x42, 0xeb, 0x5e, 0xdb, 0xee, 0xc6, + 0xf9, 0x50, 0x2e, 0x7c, 0x10, 0xf5, 0x39, 0xc8, 0x36, 0x9e, 0x67, 0x0a, + 0x67, 0x77, 0x4a, 0x9d, 0x53, 0x3e, 0x4d, 0x7f, 0x80, 0x63, 0x12, 0xb1, + 0x39, 0xd4, 0xcf, 0x08, 0x75, 0x28, 0xf7, 0xe6, 0xcf, 0xe7, 0x19, 0xf8, + 0x03, 0x8c, 0x31, 0xe1, 0xef, 0x33, 0x61, 0xf2, 0x64, 0xc0, 0xf5, 0xeb, + 0xc7, 0xa0, 0x7f, 0x43, 0x6a, 0x8d, 0x72, 0x95, 0x75, 0x29, 0x87, 0xe3, + 0xf3, 0x69, 0xbe, 0x8b, 0x3c, 0x66, 0xfc, 0xf2, 0xe3, 0xf0, 0x5b, 0xf3, + 0xcd, 0xae, 0xdf, 0xa0, 0x7f, 0x77, 0x64, 0x9d, 0x96, 0xcb, 0xdb, 0x31, + 0xc7, 0xc8, 0xde, 0x93, 0x35, 0xc6, 0xac, 0x2d, 0xe9, 0x82, 0x2c, 0x3d, + 0x2a, 0xc3, 0x46, 0x8e, 0x72, 0x3f, 0x7d, 0x4a, 0xd7, 0xe5, 0x67, 0x62, + 0x72, 0x6e, 0xed, 0xff, 0x85, 0xae, 0x7f, 0xbd, 0x5d, 0x57, 0xd8, 0xc3, + 0xae, 0xbb, 0x79, 0x19, 0xf2, 0xa0, 0x0a, 0x59, 0x51, 0x85, 0xac, 0xa8, + 0x42, 0x56, 0x54, 0x21, 0x2b, 0xaa, 0x90, 0x15, 0x55, 0xc8, 0x8a, 0xea, + 0x8c, 0xd1, 0x9b, 0xa7, 0x21, 0x73, 0xe9, 0xf3, 0xd0, 0xcf, 0xe9, 0xb4, + 0x05, 0xe2, 0x90, 0x25, 0xf4, 0x67, 0x12, 0xa5, 0x5b, 0xc0, 0xcd, 0xd7, + 0xd3, 0xf4, 0xb9, 0x5b, 0xf2, 0x57, 0xe9, 0xce, 0xdd, 0xab, 0xf8, 0x86, + 0x3c, 0x0a, 0x7c, 0x7d, 0x08, 0xf8, 0xfa, 0xf0, 0x5d, 0x39, 0x16, 0x7e, + 0x4c, 0x64, 0xb8, 0x14, 0x80, 0xff, 0x39, 0x73, 0x07, 0xee, 0xe8, 0x7b, + 0x63, 0x8d, 0xbb, 0x6c, 0x63, 0xfa, 0xdc, 0xa3, 0xea, 0xde, 0x7c, 0x03, + 0x76, 0xf9, 0x8d, 0x74, 0x29, 0x12, 0x50, 0xf7, 0x73, 0x2e, 0x69, 0x67, + 0x8f, 0xbf, 0x6f, 0x84, 0xb5, 0x5c, 0xd4, 0x67, 0x9f, 0xcf, 0xf4, 0x81, + 0x0f, 0x68, 0xdf, 0xdd, 0x50, 0xf6, 0xdd, 0xd1, 0x74, 0x50, 0xb6, 0xa2, + 0xd4, 0xa9, 0x3f, 0x92, 0x93, 0x2b, 0x91, 0x1e, 0xfa, 0xdf, 0x8b, 0xd5, + 0x83, 0xb2, 0xad, 0x64, 0xca, 0x07, 0xd1, 0xd7, 0x93, 0x79, 0xd0, 0xc4, + 0x11, 0xf8, 0x8e, 0x17, 0x65, 0x2c, 0x76, 0x11, 0x7b, 0xfd, 0x3c, 0xc6, + 0xc0, 0x07, 0x68, 0x15, 0x50, 0x77, 0x1d, 0x7e, 0xc6, 0x6d, 0xe1, 0xf3, + 0x98, 0x73, 0x1e, 0x88, 0xce, 0x3a, 0x29, 0xe7, 0x35, 0xf1, 0xe9, 0x8c, + 0x34, 0xc5, 0xbb, 0xb6, 0x41, 0xc9, 0xaf, 0xd3, 0x2f, 0xeb, 0x03, 0x1f, + 0xfe, 0x08, 0x7a, 0x98, 0x6b, 0x50, 0x2e, 0x70, 0x0f, 0xff, 0x0d, 0xf0, + 0xc5, 0x67, 0xbb, 0xbd, 0xfb, 0xa1, 0x7b, 0x29, 0xf7, 0xb5, 0xef, 0x94, + 0xc7, 0x18, 0xa5, 0x1b, 0xd2, 0xbc, 0x77, 0xe0, 0xfe, 0xfe, 0x18, 0x76, + 0x4e, 0x14, 0x74, 0x80, 0xfa, 0x75, 0xdf, 0xce, 0xf5, 0xed, 0x19, 0x1d, + 0xeb, 0xbb, 0xa2, 0x6c, 0x9a, 0x1c, 0xf4, 0xd8, 0x31, 0xf4, 0x65, 0xac, + 0xbd, 0xd5, 0x3a, 0x95, 0x86, 0xdf, 0xf1, 0x24, 0x65, 0xd9, 0x7d, 0xe0, + 0x69, 0xda, 0x45, 0xd4, 0xb9, 0x62, 0xdd, 0xcc, 0x6c, 0x3b, 0x61, 0xe8, + 0xcb, 0x19, 0xd0, 0x5c, 0x0e, 0x74, 0x18, 0x78, 0x60, 0x0a, 0xfa, 0x57, + 0xc5, 0x9c, 0x41, 0xeb, 0x5c, 0xf7, 0x83, 0xd6, 0x5f, 0x64, 0xc6, 0xa1, + 0x8f, 0x1f, 0x82, 0x3e, 0xe6, 0x7d, 0x74, 0x0e, 0x3a, 0x99, 0xfa, 0xd8, + 0x91, 0x3f, 0xdd, 0xcc, 0x41, 0x76, 0xdd, 0xd7, 0x43, 0x5e, 0x9b, 0x6a, + 0xf3, 0x54, 0xc1, 0xf0, 0xdc, 0x01, 0x13, 0xfb, 0x28, 0x28, 0xde, 0x2c, + 0xaf, 0xd3, 0x0e, 0x01, 0x9f, 0xae, 0x53, 0x46, 0xd0, 0xa6, 0xa4, 0xec, + 0x80, 0xac, 0x59, 0xff, 0x00, 0xca, 0x29, 0x94, 0xda, 0x56, 0xbb, 0x52, + 0x7d, 0x35, 0xec, 0xdf, 0x23, 0xef, 0xd8, 0x6b, 0x75, 0xec, 0xef, 0x18, + 0x73, 0x1b, 0x4a, 0xfd, 0xde, 0x47, 0xb0, 0xc7, 0xe3, 0xa0, 0xc1, 0x19, + 0xd0, 0xe0, 0x14, 0xf6, 0x7a, 0xde, 0x1a, 0x39, 0x1c, 0x80, 0x3e, 0x3f, + 0x23, 0x85, 0x34, 0x64, 0xee, 0x5a, 0xc9, 0x9a, 0x58, 0x12, 0xf5, 0x9e, + 0x4f, 0xf3, 0x4e, 0xfd, 0xbd, 0x2a, 0x3e, 0xb8, 0xbc, 0x19, 0x34, 0x71, + 0xc4, 0x20, 0xea, 0xa8, 0xc3, 0x21, 0xb3, 0x1c, 0xcc, 0x55, 0xfd, 0x59, + 0xaf, 0xf4, 0x62, 0xbe, 0xea, 0x34, 0xde, 0x19, 0x5b, 0x38, 0x66, 0xdd, + 0x59, 0xcf, 0xd8, 0x45, 0xc2, 0xc9, 0xc1, 0x17, 0x0d, 0xba, 0x8c, 0x5f, + 0xb8, 0x38, 0x9f, 0xac, 0xe4, 0x47, 0x60, 0x93, 0x29, 0x99, 0xdc, 0x6b, + 0x64, 0x32, 0xe4, 0x5d, 0xcd, 0x93, 0xb5, 0x4d, 0xda, 0x4e, 0x9e, 0xf2, + 0xa7, 0x29, 0xc7, 0x8a, 0x35, 0xd8, 0x3f, 0xe9, 0xdf, 0xb3, 0xb2, 0x6a, + 0xce, 0xb0, 0xca, 0xd5, 0x28, 0xad, 0x89, 0xe5, 0x1c, 0xbe, 0x09, 0xff, + 0x35, 0x03, 0x1e, 0xf6, 0x20, 0x37, 0x1d, 0xc8, 0x45, 0xea, 0xb5, 0xaf, + 0x76, 0x4b, 0x1f, 0xea, 0x2f, 0xc3, 0xe6, 0x79, 0x92, 0x7c, 0x7b, 0x5d, + 0xec, 0xc6, 0x1b, 0xc5, 0x47, 0x18, 0x1b, 0x19, 0x32, 0x77, 0xb3, 0xff, + 0x0b, 0xf0, 0xea, 0x35, 0x42, 0xb0, 0xeb, 0xaf, 0xd6, 0xf6, 0xc1, 0x47, + 0x3c, 0x66, 0xe5, 0xa3, 0xac, 0x2b, 0xc9, 0x7a, 0x86, 0x76, 0x28, 0x63, + 0x24, 0x61, 0xd4, 0xef, 0xf6, 0x49, 0xa9, 0xff, 0x9f, 0x53, 0x77, 0x34, + 0x0b, 0x4a, 0xee, 0xfa, 0xf1, 0xe5, 0xe7, 0x24, 0xd9, 0xf4, 0xe3, 0x54, + 0x5c, 0x7f, 0xcb, 0x2a, 0x36, 0xff, 0x1c, 0xeb, 0x10, 0x06, 0xee, 0x45, + 0xaf, 0x63, 0x2f, 0x4f, 0x98, 0x75, 0x1c, 0x2b, 0x74, 0x38, 0x86, 0xfd, + 0xec, 0xef, 0x93, 0xbe, 0x00, 0xe4, 0xd9, 0x28, 0x9e, 0x6f, 0xa1, 0x6e, + 0xe7, 0xbd, 0x51, 0x15, 0x2b, 0x70, 0x18, 0xde, 0x33, 0xf4, 0x77, 0x03, + 0x32, 0xc7, 0x86, 0xfe, 0x6c, 0x54, 0x3f, 0x8e, 0x12, 0xe3, 0x9e, 0xbc, + 0x2e, 0x73, 0xda, 0xdf, 0x86, 0x4d, 0x39, 0xac, 0x74, 0xf0, 0x4c, 0x9a, + 0xb1, 0x90, 0x33, 0x90, 0x8f, 0xf7, 0xa3, 0x8e, 0x7e, 0x53, 0x49, 0x9c, + 0xf7, 0x14, 0x8c, 0xbf, 0xaf, 0xcf, 0x25, 0xa0, 0xf4, 0xf5, 0x0a, 0xce, + 0x83, 0x73, 0x50, 0xdf, 0xfd, 0x5c, 0x3e, 0xd5, 0x11, 0x47, 0xc9, 0xd9, + 0xed, 0xb8, 0x41, 0x36, 0x0f, 0x1d, 0xbd, 0x56, 0x25, 0x0f, 0x66, 0x70, + 0xde, 0x59, 0xf9, 0xda, 0xe6, 0x3d, 0xc0, 0x75, 0x54, 0x02, 0x4f, 0xb5, + 0x40, 0x3f, 0xd4, 0x0d, 0x63, 0x90, 0xc9, 0x8e, 0xb1, 0x25, 0xa2, 0x12, + 0x7c, 0x6a, 0x48, 0xba, 0x2f, 0xc4, 0xa4, 0xeb, 0x02, 0xf3, 0x4f, 0x52, + 0x71, 0xd8, 0xc5, 0xb4, 0x87, 0x78, 0x0f, 0xc9, 0xfb, 0xc3, 0xb8, 0xbe, + 0x8f, 0xe4, 0x5d, 0x24, 0xfa, 0xc1, 0x76, 0xef, 0xba, 0xe4, 0x00, 0x3f, + 0x7a, 0xce, 0xdd, 0x63, 0xcb, 0x7a, 0x2c, 0xef, 0x31, 0x63, 0x25, 0x49, + 0x99, 0x7b, 0xcc, 0x14, 0xc6, 0xa6, 0x26, 0x5f, 0x6e, 0x8f, 0xe7, 0x58, + 0xea, 0xc4, 0x28, 0xf8, 0xfb, 0xad, 0xd2, 0xf8, 0x22, 0xf9, 0xdc, 0xbf, + 0xeb, 0x1a, 0x32, 0x77, 0x5f, 0xec, 0x13, 0x37, 0xed, 0x49, 0xd3, 0xee, + 0x2a, 0x3d, 0x19, 0x6c, 0xc7, 0x5b, 0x78, 0x2f, 0x96, 0x38, 0xcf, 0xe4, + 0x11, 0x7d, 0x47, 0x46, 0x5f, 0x0a, 0xbe, 0xc5, 0x93, 0xb0, 0x31, 0xeb, + 0x2c, 0x7b, 0xa4, 0x5c, 0x3f, 0x25, 0xb3, 0xea, 0xf9, 0x43, 0xf2, 0xa8, + 0x43, 0xdc, 0x9d, 0x91, 0xf4, 0x84, 0xb6, 0xc7, 0xc4, 0xd6, 0xb8, 0xed, + 0x76, 0xcf, 0xc8, 0xd1, 0xb4, 0xd2, 0x21, 0xce, 0x23, 0xc0, 0x71, 0xb1, + 0xd9, 0x45, 0x7a, 0x07, 0xec, 0x1e, 0x78, 0x2c, 0x2b, 0x17, 0x37, 0xd1, + 0x17, 0x67, 0xf5, 0x08, 0xdf, 0xeb, 0xc0, 0x27, 0x63, 0x16, 0x4f, 0x11, + 0x9f, 0xdc, 0x3b, 0x75, 0x28, 0x71, 0x4a, 0x1c, 0x50, 0x2f, 0x33, 0xe6, + 0x96, 0x98, 0xbc, 0x2d, 0xf4, 0x9b, 0x89, 0x33, 0xce, 0xe3, 0xef, 0x5b, + 0x8f, 0xb3, 0x37, 0x06, 0x85, 0xe6, 0x98, 0x7d, 0xc1, 0x11, 0xfb, 0x12, + 0xcb, 0x08, 0x4a, 0xb6, 0x01, 0xa4, 0x8d, 0xa4, 0x69, 0x73, 0x51, 0x07, + 0x3b, 0xf2, 0x09, 0xf2, 0x96, 0xce, 0xff, 0x4b, 0x8e, 0x4c, 0xca, 0x95, + 0xb5, 0xbb, 0xf9, 0x2b, 0x70, 0x41, 0xdb, 0x25, 0x77, 0xf2, 0xd7, 0xe4, + 0x3f, 0x80, 0xbf, 0xb8, 0xc6, 0x19, 0x95, 0xbb, 0xf0, 0xa9, 0x68, 0x22, + 0x9e, 0xd5, 0xfe, 0x85, 0x93, 0xb2, 0x47, 0xe2, 0xb4, 0x47, 0x1b, 0x4f, + 0x8e, 0xe3, 0xdc, 0x5b, 0xf2, 0x44, 0xda, 0xa7, 0x2f, 0xe6, 0xf8, 0xb5, + 0xa4, 0x06, 0xfd, 0x5c, 0x76, 0x2d, 0x59, 0x70, 0xcf, 0x28, 0x7b, 0xf2, + 0xc3, 0xd1, 0x96, 0x9c, 0x4e, 0xeb, 0xb1, 0x0b, 0x32, 0x62, 0x68, 0x5c, + 0xf9, 0x6b, 0x90, 0xbf, 0x3c, 0x2f, 0xbe, 0xdf, 0x23, 0xe9, 0x81, 0x33, + 0x92, 0x9c, 0xd8, 0x22, 0xbe, 0x70, 0x0e, 0x94, 0x3b, 0xbf, 0x36, 0x16, + 0xa6, 0x72, 0x9e, 0xf2, 0x15, 0xc2, 0xb4, 0x0f, 0x74, 0x9b, 0x85, 0xbf, + 0xb4, 0x13, 0x0f, 0x4b, 0x8d, 0x94, 0x5a, 0x21, 0xac, 0x5d, 0x84, 0x3f, + 0xf1, 0xe1, 0xa8, 0x1b, 0x1f, 0xb6, 0x47, 0x62, 0x67, 0xa5, 0xa6, 0x60, + 0xfd, 0x44, 0x5a, 0xd3, 0xcb, 0x62, 0x66, 0xaf, 0x18, 0x55, 0x67, 0x8c, + 0x9a, 0x73, 0x6d, 0x59, 0x9f, 0x6c, 0xea, 0x78, 0xd4, 0x4e, 0x9c, 0x7a, + 0x47, 0xe6, 0x04, 0x8d, 0x2c, 0x28, 0xd7, 0xde, 0x25, 0xbe, 0xcc, 0xa9, + 0x65, 0x70, 0x56, 0xcb, 0x3c, 0xa3, 0xb8, 0xb9, 0x47, 0x0a, 0x77, 0xd8, + 0xca, 0x21, 0xe6, 0xfd, 0xc5, 0xb3, 0xf6, 0x32, 0x64, 0xc3, 0x93, 0x12, + 0x72, 0xfd, 0xb9, 0x98, 0xd3, 0x19, 0x33, 0xf7, 0x11, 0xfb, 0x19, 0xb7, + 0x42, 0x9f, 0x07, 0xd1, 0x7e, 0x3f, 0xfa, 0x51, 0x57, 0xf2, 0x1e, 0x80, + 0x7a, 0x93, 0xb1, 0xf6, 0x01, 0xf4, 0xeb, 0x91, 0x7c, 0x7d, 0xbf, 0xa9, + 0xf3, 0xe7, 0x38, 0xdc, 0xd1, 0xdf, 0xaf, 0xd3, 0xf7, 0x07, 0x59, 0x1b, + 0x32, 0x7e, 0x99, 0x7d, 0xe3, 0xed, 0x3b, 0x10, 0xbb, 0xf1, 0xa0, 0xa3, + 0xc7, 0xb3, 0x1f, 0x65, 0x3e, 0x74, 0x4b, 0x15, 0xfa, 0xa6, 0x3a, 0xc5, + 0xbb, 0x40, 0x63, 0x57, 0xcc, 0x9a, 0x7c, 0x16, 0xda, 0x17, 0xaf, 0x19, + 0x7d, 0xbb, 0x93, 0x8b, 0x7a, 0x24, 0xe3, 0xe7, 0xf5, 0x30, 0x17, 0x91, + 0xeb, 0xf2, 0x3c, 0x40, 0x53, 0x9b, 0xda, 0x96, 0xb6, 0x33, 0x5d, 0xbc, + 0x6b, 0x83, 0x7e, 0xd7, 0xfa, 0xbf, 0x01, 0xfd, 0xbf, 0xb1, 0x02, 0x9d, + 0xdf, 0x47, 0xdd, 0xaf, 0xf3, 0x4f, 0xec, 0x76, 0xbe, 0x8f, 0x7f, 0x8f, + 0xbc, 0xa5, 0xee, 0xf1, 0x7a, 0x3c, 0xca, 0xf4, 0x8c, 0xfc, 0x39, 0x6c, + 0xad, 0x67, 0x36, 0x27, 0xb1, 0x5e, 0x1a, 0x7e, 0xdd, 0x38, 0xfc, 0xba, + 0x51, 0xf8, 0x75, 0x2e, 0x74, 0xe1, 0x90, 0xca, 0x27, 0xa3, 0xde, 0x9f, + 0x38, 0x24, 0xd6, 0xd7, 0x32, 0x62, 0x1d, 0xbc, 0x00, 0x1b, 0x61, 0xe9, + 0x25, 0xd0, 0x7f, 0xe2, 0x79, 0x11, 0xf2, 0x04, 0xf9, 0xef, 0x31, 0xc9, + 0xc6, 0x86, 0xe4, 0xf3, 0x9b, 0x6c, 0x23, 0x3d, 0x65, 0xe5, 0x15, 0xf7, + 0x25, 0xc5, 0x67, 0x17, 0x6b, 0xd7, 0x25, 0xf4, 0x84, 0x96, 0xb5, 0x3f, + 0x80, 0x3d, 0xd5, 0x48, 0x6b, 0xda, 0xbb, 0x2d, 0xa4, 0x3d, 0xe8, 0xa7, + 0x35, 0xca, 0xd8, 0x9b, 0x12, 0xbd, 0xf0, 0x92, 0xbc, 0xf9, 0x82, 0xab, + 0xe2, 0x12, 0x6b, 0x4f, 0x2a, 0xdd, 0x07, 0xb9, 0x16, 0x95, 0xf5, 0xcd, + 0xdf, 0x91, 0x4f, 0x39, 0x89, 0x2b, 0x94, 0x99, 0x94, 0x5d, 0x5a, 0xa7, + 0x41, 0xc6, 0x56, 0x12, 0xa5, 0x32, 0x6c, 0xef, 0x2b, 0xf6, 0x98, 0x64, + 0x83, 0xa5, 0x56, 0x3f, 0xfd, 0x82, 0x9a, 0xeb, 0x24, 0x6d, 0x9e, 0xef, + 0xbd, 0xb0, 0xad, 0x13, 0x75, 0x25, 0xa3, 0xa8, 0x27, 0x33, 0xd4, 0x9b, + 0xd4, 0x7d, 0xd4, 0x3f, 0x8c, 0x97, 0xe3, 0x79, 0x8d, 0xba, 0xe9, 0xef, + 0xd4, 0x9d, 0x67, 0x71, 0xc6, 0x91, 0xfa, 0x1a, 0xe5, 0x13, 0xf4, 0xfc, + 0x93, 0xb4, 0x73, 0x45, 0xd1, 0x3f, 0xed, 0xdc, 0x47, 0xc5, 0xb7, 0x71, + 0xd9, 0xb6, 0xdb, 0xc6, 0xfd, 0x83, 0x7d, 0xd2, 0x1b, 0x05, 0x7e, 0xc8, + 0xff, 0x3b, 0x36, 0x60, 0x2e, 0x73, 0x13, 0xb6, 0x26, 0xf7, 0x61, 0xc9, + 0xa0, 0x7b, 0x1d, 0x74, 0xc4, 0xb5, 0x6f, 0xb6, 0x3e, 0x1c, 0xe5, 0x1e, + 0x2c, 0x65, 0x23, 0x6c, 0x0f, 0xfe, 0xa6, 0x3b, 0x0a, 0xca, 0x88, 0x7d, + 0xb0, 0xcd, 0x6d, 0x43, 0xb3, 0x9f, 0x34, 0xbe, 0x04, 0xf8, 0x79, 0x95, + 0x7b, 0x28, 0xf3, 0x4e, 0x04, 0x36, 0xd7, 0x22, 0x63, 0x52, 0x6a, 0xdd, + 0xf7, 0x67, 0x22, 0x92, 0xbc, 0xd0, 0x25, 0xa9, 0xa7, 0xec, 0x41, 0x9d, + 0xb7, 0xf8, 0x30, 0x74, 0xcf, 0x41, 0xb4, 0x1f, 0x90, 0xb2, 0x13, 0x85, + 0x3f, 0x33, 0x2a, 0xe5, 0xd1, 0x30, 0x78, 0xe6, 0x01, 0xde, 0x75, 0x28, + 0x38, 0xca, 0xce, 0x30, 0xca, 0x6e, 0x94, 0xf7, 0x48, 0xf9, 0xc9, 0x4b, + 0xfb, 0xb4, 0x2d, 0xbb, 0xfb, 0xfd, 0x9f, 0x76, 0xab, 0xd8, 0xb9, 0xf5, + 0x8e, 0x88, 0xb9, 0x47, 0xff, 0x2d, 0x60, 0xf7, 0xfb, 0x12, 0x9e, 0x90, + 0xb8, 0x4f, 0x44, 0x64, 0x18, 0xb2, 0x77, 0x04, 0x7a, 0xeb, 0xe0, 0x85, + 0x21, 0x19, 0xbd, 0x10, 0x97, 0xfb, 0x2e, 0xf8, 0xf6, 0xc0, 0xf2, 0x74, + 0xca, 0xc4, 0x71, 0xdd, 0xdf, 0x32, 0x8e, 0x7b, 0x9f, 0x9a, 0x1f, 0x30, + 0xae, 0x41, 0x1e, 0x46, 0x3f, 0xa7, 0xec, 0x06, 0x8d, 0xfb, 0x1f, 0xc9, + 0x91, 0x95, 0x90, 0x1c, 0x55, 0xbc, 0xe8, 0xdb, 0xf0, 0xff, 0x13, 0xfb, + 0x48, 0x80, 0x47, 0x4e, 0x18, 0xbf, 0xb3, 0x17, 0x78, 0x25, 0x0e, 0xa1, + 0xeb, 0xe0, 0x8b, 0x32, 0x3f, 0xb5, 0x98, 0xee, 0x1c, 0xcf, 0xb1, 0x3f, + 0xc5, 0x98, 0x2c, 0x6c, 0x0b, 0xb6, 0xcb, 0x60, 0x40, 0xf6, 0x6a, 0x7f, + 0x1f, 0xda, 0x29, 0x73, 0x8e, 0x42, 0xe6, 0xec, 0x6e, 0xcf, 0xa1, 0x8d, + 0xeb, 0xdf, 0x83, 0x75, 0xc9, 0x8f, 0x5c, 0xd7, 0xc7, 0x09, 0xcf, 0x75, + 0x10, 0xfe, 0x07, 0xcf, 0xb5, 0x4b, 0x0a, 0x0e, 0x73, 0x37, 0x59, 0xf7, + 0x16, 0x73, 0xd6, 0x13, 0xe6, 0xac, 0x05, 0xb6, 0x31, 0xed, 0x2d, 0x9d, + 0xaf, 0x50, 0x88, 0x26, 0x4a, 0x22, 0x71, 0x15, 0xbf, 0x5b, 0xaf, 0xf8, + 0xf6, 0x49, 0xb6, 0x9f, 0xf7, 0x10, 0x8b, 0x69, 0x15, 0x5b, 0x8b, 0x07, + 0x3c, 0xda, 0x37, 0xe9, 0x30, 0xf3, 0x92, 0x1b, 0x2b, 0xbc, 0x93, 0x0c, + 0xe0, 0x07, 0x3c, 0x07, 0x2d, 0x71, 0x5c, 0xd6, 0x95, 0xb4, 0x6e, 0x9b, + 0x01, 0xff, 0xda, 0xaa, 0x4f, 0x3c, 0x97, 0x1e, 0x34, 0xef, 0x31, 0x59, + 0xab, 0xbc, 0x63, 0xc8, 0xf6, 0xfe, 0xf6, 0x9e, 0x5c, 0xa6, 0x9f, 0xf7, + 0x49, 0xa8, 0x23, 0x9f, 0xbc, 0xa4, 0x72, 0x15, 0xb5, 0xef, 0x10, 0xe4, + 0x3d, 0x24, 0xf6, 0xf9, 0x53, 0xd0, 0xf5, 0xee, 0x3d, 0x77, 0x99, 0x3d, + 0x73, 0xbf, 0xc4, 0x37, 0xc7, 0xfb, 0x7a, 0x8e, 0x38, 0x0f, 0x77, 0xf8, + 0x1b, 0x91, 0x81, 0x9d, 0xfb, 0x73, 0xca, 0x42, 0xca, 0xbf, 0x49, 0x95, + 0xef, 0x72, 0xcb, 0x86, 0x1c, 0xaa, 0x42, 0x2e, 0x55, 0x21, 0x8b, 0xaa, + 0x90, 0x45, 0xb0, 0x41, 0x9e, 0x85, 0x5c, 0x7d, 0x06, 0xbe, 0xda, 0xd7, + 0xab, 0xbe, 0xfd, 0x9e, 0x85, 0x1c, 0x53, 0x36, 0x1d, 0xed, 0x9f, 0x9a, + 0xed, 0x75, 0xff, 0xd6, 0xf9, 0x50, 0x01, 0xcf, 0x1f, 0xd7, 0x2d, 0x45, + 0x35, 0x26, 0x2e, 0xf3, 0xcd, 0xbd, 0xfa, 0x72, 0x7f, 0xa1, 0x8e, 0xfd, + 0x9a, 0xbb, 0x7e, 0x15, 0x8b, 0xa0, 0x0c, 0xfe, 0x4d, 0x3c, 0xd0, 0x99, + 0xa7, 0xc9, 0x33, 0x56, 0x39, 0x42, 0x38, 0x53, 0xe2, 0x9d, 0x76, 0x61, + 0x59, 0x16, 0x26, 0x17, 0xa5, 0x3c, 0x69, 0xc9, 0xdc, 0x38, 0xce, 0x68, + 0x7c, 0x18, 0x3a, 0x32, 0x0d, 0x5d, 0xbb, 0x80, 0x79, 0xc8, 0x7f, 0x0f, + 0xe2, 0x5c, 0x1c, 0x73, 0x27, 0xfe, 0xa5, 0xe9, 0x5c, 0x4d, 0xac, 0x6b, + 0x2a, 0x47, 0x7c, 0x79, 0xfa, 0xd5, 0x95, 0x87, 0x61, 0x3f, 0x4d, 0xc8, + 0xd5, 0xc9, 0x87, 0x65, 0xfb, 0x8e, 0xf1, 0x38, 0x07, 0xc8, 0xe1, 0xcf, + 0x6f, 0xf2, 0x1e, 0xb4, 0x4b, 0x66, 0xa3, 0x8c, 0x81, 0xc1, 0xc6, 0x71, + 0xfb, 0x65, 0x5b, 0xf9, 0xa1, 0x07, 0xe4, 0xb6, 0xa2, 0x2d, 0xd6, 0x85, + 0x50, 0xa7, 0xed, 0xd1, 0xb5, 0x8a, 0x6f, 0x5b, 0x28, 0x1c, 0x99, 0x98, + 0x1f, 0xf5, 0x0d, 0xe3, 0x49, 0x8c, 0x2f, 0xad, 0x45, 0x76, 0x64, 0x01, + 0x4b, 0xff, 0x5c, 0x3b, 0xfd, 0xe3, 0xbf, 0x8e, 0xe8, 0x6f, 0x0b, 0xba, + 0xa4, 0x1c, 0x2d, 0xb5, 0xca, 0x6e, 0xd0, 0xba, 0xda, 0xce, 0x69, 0xf5, + 0xdb, 0x48, 0xcb, 0x36, 0x60, 0x25, 0x1d, 0x24, 0x55, 0xee, 0xce, 0x77, + 0xaa, 0x03, 0xfb, 0xf4, 0x37, 0x0a, 0x01, 0x8c, 0xe3, 0xfb, 0x89, 0x88, + 0x7e, 0xf7, 0xef, 0xdd, 0xdf, 0x86, 0xbe, 0x31, 0x25, 0xaf, 0xd6, 0x6a, + 0x01, 0xf0, 0xf0, 0x20, 0x9e, 0x5f, 0x44, 0x9f, 0x30, 0xce, 0x86, 0xb1, + 0xa4, 0xb7, 0xa8, 0xfc, 0x9b, 0x80, 0xeb, 0xe7, 0xf5, 0x52, 0x77, 0xff, + 0x67, 0xd5, 0xfe, 0xf4, 0x4a, 0x37, 0xf3, 0x55, 0x51, 0x52, 0xaf, 0xff, + 0x0a, 0xbe, 0x56, 0x48, 0xf2, 0x35, 0x17, 0xb6, 0x78, 0x88, 0xf4, 0x8b, + 0xfa, 0x7b, 0xa1, 0xa3, 0x04, 0xfc, 0xd4, 0x05, 0xbd, 0xa9, 0x70, 0x0d, + 0x4a, 0xa2, 0x4f, 0xef, 0xe7, 0x99, 0x6a, 0x38, 0x42, 0xde, 0xf7, 0x98, + 0x6f, 0x10, 0x0e, 0x78, 0x2f, 0x4d, 0xcf, 0x55, 0x68, 0x2b, 0xb5, 0x5a, + 0xd0, 0x65, 0xd8, 0xc9, 0xcf, 0x94, 0x5f, 0xb1, 0x2d, 0xda, 0x57, 0x5b, + 0x50, 0xf9, 0x96, 0x37, 0xa7, 0x35, 0x8d, 0x74, 0xde, 0x9f, 0xbc, 0xd1, + 0xdd, 0x49, 0x58, 0xb6, 0xd3, 0x3d, 0x86, 0x2f, 0xc2, 0xc1, 0x62, 0x25, + 0x12, 0x9c, 0x53, 0xf7, 0x5b, 0x5b, 0x26, 0x1f, 0xf3, 0xda, 0x74, 0xaa, + 0x19, 0x56, 0xb9, 0x00, 0xbc, 0x4b, 0xc8, 0x57, 0x78, 0x97, 0xa2, 0xdb, + 0x53, 0xa6, 0x3d, 0xd9, 0x54, 0x6d, 0x2a, 0xde, 0xc5, 0x18, 0x57, 0x37, + 0xca, 0xdb, 0x15, 0xca, 0x07, 0xcc, 0xaf, 0x65, 0x09, 0x60, 0x7f, 0x71, + 0x7a, 0x6e, 0x85, 0xf0, 0x7d, 0x7f, 0x3a, 0xb7, 0xc2, 0x1c, 0xc8, 0xff, + 0x34, 0x7d, 0x63, 0xc5, 0x92, 0x0d, 0x37, 0xa1, 0xe2, 0x57, 0xeb, 0x8c, + 0xb1, 0x72, 0x9c, 0x9a, 0xf3, 0x45, 0x23, 0x93, 0xbf, 0x37, 0x3d, 0xbc, + 0x1e, 0x90, 0x73, 0x66, 0x0e, 0xbe, 0xc7, 0xd7, 0xef, 0xa0, 0x6b, 0xd0, + 0xca, 0x15, 0xd0, 0x4a, 0x2f, 0x6c, 0x09, 0xd2, 0x37, 0x7d, 0xb2, 0x5e, + 0xc8, 0x01, 0xae, 0xf3, 0x8c, 0x5a, 0x27, 0x80, 0x75, 0xe6, 0x54, 0xce, + 0x78, 0x80, 0x79, 0xb7, 0xb0, 0x35, 0x61, 0x13, 0xba, 0x8c, 0x59, 0xdb, + 0xd8, 0xf3, 0x28, 0xf4, 0x12, 0xf3, 0x3f, 0xfe, 0x7b, 0x64, 0x27, 0x6f, + 0xfc, 0x39, 0x33, 0xee, 0x9b, 0x18, 0xc7, 0x33, 0x51, 0xf9, 0xe6, 0x6f, + 0xb6, 0x65, 0x58, 0xd9, 0x90, 0x3a, 0x07, 0x89, 0x30, 0xd4, 0xb1, 0x57, + 0xea, 0xe2, 0x2e, 0xc9, 0xab, 0x7d, 0x7d, 0x53, 0x8d, 0xb3, 0xbc, 0x6f, + 0x00, 0x76, 0xda, 0x25, 0x98, 0xbb, 0xaa, 0xe3, 0x6d, 0x79, 0xc5, 0xd3, + 0xe0, 0x91, 0x49, 0x3f, 0x57, 0x4f, 0x8f, 0xf3, 0xfb, 0x27, 0xd7, 0x8f, + 0x98, 0x9c, 0x8e, 0xbf, 0x6f, 0x65, 0x8f, 0xf7, 0x2a, 0x1b, 0x6c, 0xe7, + 0x9b, 0x08, 0x7f, 0x8c, 0xdf, 0xc7, 0xcf, 0x31, 0x7e, 0x74, 0xff, 0x0e, + 0xcc, 0x5b, 0xe6, 0xcc, 0x39, 0x8e, 0xb1, 0x49, 0x95, 0xaf, 0xcb, 0xba, + 0xe0, 0x7c, 0x86, 0x73, 0x74, 0xde, 0xf7, 0x8c, 0x83, 0x47, 0xb5, 0xcd, + 0x57, 0x82, 0x9d, 0x55, 0x06, 0xbf, 0x04, 0x3c, 0xca, 0xf1, 0x61, 0x13, + 0x57, 0x7b, 0xa3, 0x38, 0x1f, 0xef, 0x12, 0xc7, 0x21, 0x7b, 0xfc, 0xf1, + 0x3c, 0xc7, 0x6b, 0xd3, 0x37, 0x2a, 0xae, 0x9c, 0xad, 0xea, 0x7c, 0x47, + 0x8d, 0x07, 0xc6, 0x6e, 0x78, 0xb6, 0x71, 0x99, 0x73, 0xa9, 0x67, 0xe3, + 0xf2, 0x5d, 0xd7, 0x8f, 0xad, 0xf1, 0x7e, 0x0a, 0xfd, 0x61, 0xeb, 0x2d, + 0x6c, 0x72, 0xff, 0xdf, 0xc4, 0xfe, 0xe9, 0x53, 0x68, 0x5a, 0x3a, 0x08, + 0xb9, 0xf5, 0x1f, 0x82, 0xf0, 0x19, 0xa0, 0xbb, 0x6f, 0x05, 0x3b, 0xf7, + 0xe7, 0xeb, 0x6b, 0x4d, 0x97, 0x41, 0xd0, 0xc8, 0x62, 0x1b, 0xef, 0x96, + 0x04, 0xde, 0x39, 0x02, 0x1d, 0x64, 0x49, 0x61, 0xdc, 0x8d, 0x2d, 0xf0, + 0x6e, 0xc1, 0x19, 0x73, 0x1c, 0x95, 0xc7, 0x16, 0x07, 0xbc, 0x7c, 0xe6, + 0xb7, 0x02, 0xcc, 0x39, 0x8b, 0xab, 0x5c, 0xdd, 0x6c, 0xd4, 0x05, 0xbc, + 0x8e, 0xb2, 0x4f, 0xb4, 0x5e, 0xfe, 0x97, 0xfb, 0x29, 0x6b, 0xfa, 0x5d, + 0xff, 0xec, 0x39, 0xf7, 0x8b, 0x98, 0x3b, 0x60, 0xda, 0x7d, 0x1a, 0x09, + 0x30, 0xe5, 0x4d, 0x76, 0xbe, 0x01, 0xf1, 0xe3, 0x7c, 0xec, 0xff, 0x2d, + 0x05, 0xcb, 0x1c, 0xf4, 0xd0, 0xbc, 0xda, 0xcf, 0x0b, 0xa0, 0x05, 0xca, + 0x15, 0x9f, 0x7e, 0x5f, 0x00, 0xfd, 0xee, 0x63, 0x0a, 0xdf, 0x1e, 0xb4, + 0xe6, 0xd3, 0x18, 0xe9, 0x8b, 0xb4, 0xf5, 0x8a, 0xe2, 0xb9, 0x52, 0xfb, + 0xdc, 0x29, 0xb3, 0x12, 0x4e, 0xdc, 0xf6, 0xcf, 0x9d, 0xcf, 0x7b, 0xe5, + 0xb8, 0xfa, 0xfc, 0x91, 0xf9, 0x07, 0x9c, 0x6d, 0xda, 0x9c, 0x6d, 0xa6, + 0xe3, 0x9b, 0x04, 0x7f, 0x3e, 0xfa, 0xfb, 0xd4, 0xaf, 0xbc, 0x0b, 0xe2, + 0xf7, 0x12, 0xca, 0x44, 0x90, 0x72, 0x9a, 0x7c, 0x94, 0x8b, 0xf3, 0x3e, + 0xe5, 0xa4, 0x04, 0xfa, 0x60, 0xb7, 0x8c, 0x86, 0xc4, 0xff, 0x2e, 0xa9, + 0x4b, 0xb6, 0x9c, 0x56, 0xeb, 0x06, 0xef, 0x8d, 0x2b, 0x41, 0xd9, 0x50, + 0x77, 0x9f, 0xe0, 0xd1, 0xde, 0xa0, 0x2c, 0xba, 0x6d, 0x3d, 0x27, 0x75, + 0xf4, 0x59, 0x43, 0xdb, 0xb9, 0x36, 0x6c, 0xd4, 0x07, 0xb0, 0x21, 0xdd, + 0xbf, 0x6f, 0x15, 0xa3, 0x77, 0xf4, 0x35, 0x32, 0x96, 0xb1, 0x47, 0xc6, + 0xa7, 0x1d, 0xc9, 0xaf, 0x0f, 0xe0, 0x07, 0x19, 0xaf, 0xe4, 0x02, 0x63, + 0x91, 0x8c, 0xe7, 0x96, 0xe0, 0x9f, 0x6a, 0x3f, 0x9f, 0xf6, 0xf6, 0x95, + 0xcd, 0x44, 0xa9, 0x24, 0x6e, 0xfc, 0x91, 0xf6, 0x77, 0x3c, 0x7d, 0xa5, + 0xb0, 0xd7, 0x19, 0xf3, 0x8d, 0xab, 0xfc, 0xd9, 0x1e, 0x2f, 0x11, 0x3b, + 0x05, 0xdf, 0xf5, 0xeb, 0x69, 0xc6, 0x7a, 0xef, 0x23, 0xbe, 0xbf, 0xc4, + 0x4d, 0xda, 0x23, 0xe3, 0xe2, 0x5e, 0x72, 0x47, 0x1f, 0x11, 0xfa, 0xa7, + 0x89, 0xf8, 0x14, 0xf1, 0xd6, 0xfe, 0xbe, 0x20, 0x68, 0xec, 0xa5, 0x71, + 0x19, 0xbe, 0xf4, 0x23, 0x15, 0x63, 0xff, 0x70, 0x7a, 0x37, 0x6d, 0xa8, + 0x58, 0xf1, 0x78, 0xbf, 0x0c, 0x8f, 0xae, 0x89, 0x40, 0x5b, 0xf0, 0x7b, + 0x03, 0x0b, 0x3e, 0xaa, 0x7a, 0x87, 0xbd, 0x1e, 0x57, 0xdf, 0x5c, 0x65, + 0x55, 0xde, 0x23, 0x63, 0xc9, 0x3c, 0xd3, 0x88, 0xca, 0x85, 0x7b, 0x16, + 0x67, 0x5b, 0x68, 0xf2, 0x7c, 0x19, 0x57, 0x66, 0xdc, 0x98, 0xb1, 0x65, + 0xc6, 0x88, 0xf5, 0xf7, 0x53, 0x47, 0x9a, 0x7b, 0xc5, 0x91, 0x89, 0x8b, + 0x51, 0xf3, 0x4d, 0x9a, 0x58, 0xdb, 0xd0, 0xbb, 0xf9, 0x9a, 0xa3, 0xee, + 0xfd, 0x8a, 0x4e, 0xbf, 0x9c, 0x1c, 0xed, 0x06, 0xce, 0x07, 0x54, 0x3e, + 0xa4, 0xed, 0xbe, 0x07, 0x7e, 0x25, 0xfd, 0x38, 0xea, 0x5b, 0x1f, 0xcf, + 0x87, 0x50, 0xf7, 0x0b, 0xe0, 0x9e, 0x75, 0xf0, 0x39, 0x95, 0xee, 0xfd, + 0xb4, 0x6c, 0x57, 0x98, 0x9f, 0x5d, 0x3f, 0x90, 0x53, 0xe7, 0xc1, 0x98, + 0x8d, 0x2f, 0x9b, 0xfc, 0x5c, 0x35, 0xfa, 0xcc, 0x8e, 0xb9, 0xab, 0x66, + 0xcc, 0x66, 0x40, 0x8a, 0xeb, 0x94, 0x3f, 0x96, 0x5a, 0xeb, 0x56, 0xe0, + 0xad, 0x52, 0xaa, 0xef, 0x75, 0xef, 0xde, 0x6a, 0x3d, 0x93, 0x56, 0xbe, + 0xec, 0xf9, 0x92, 0x39, 0x63, 0xfd, 0x1d, 0x64, 0x70, 0x27, 0x7f, 0x38, + 0xaa, 0xe3, 0x09, 0xd9, 0x81, 0x5e, 0xfa, 0x0f, 0x7d, 0x1a, 0xbf, 0xf4, + 0x7b, 0x7f, 0x65, 0x6c, 0x51, 0xfa, 0xbc, 0x03, 0x4a, 0x4f, 0xdb, 0x0d, + 0x9f, 0x4e, 0x98, 0x73, 0x43, 0x7f, 0xf8, 0xa0, 0x64, 0xeb, 0x90, 0x9b, + 0x83, 0x7c, 0x3f, 0x6b, 0xc6, 0xf2, 0xb9, 0x25, 0x47, 0x27, 0x76, 0xdf, + 0xa7, 0x4f, 0x6a, 0x3f, 0xbb, 0xd7, 0xbf, 0x53, 0xf7, 0x73, 0x4d, 0x7d, + 0x78, 0x15, 0x9c, 0xa0, 0x27, 0x1f, 0x06, 0xbd, 0xd6, 0x11, 0xc0, 0xcb, + 0x18, 0xe4, 0x80, 0xcb, 0x5c, 0x9d, 0x80, 0x4c, 0x0c, 0x24, 0x98, 0xc3, + 0xa7, 0xe0, 0x69, 0xd4, 0x43, 0x68, 0xf3, 0xe1, 0xd4, 0xfe, 0x79, 0xa3, + 0xce, 0xf6, 0x38, 0xd6, 0xea, 0x96, 0x89, 0x41, 0xe2, 0x79, 0x37, 0x1c, + 0x03, 0x81, 0xbd, 0x73, 0xd4, 0x1e, 0xec, 0x80, 0xef, 0xee, 0xef, 0x47, + 0x73, 0xf0, 0xc3, 0x72, 0x2b, 0x8c, 0x15, 0x10, 0xc6, 0x01, 0xc8, 0x39, + 0xec, 0x31, 0xed, 0xe7, 0x0e, 0xfb, 0x78, 0xf1, 0x63, 0x0c, 0x21, 0x45, + 0x17, 0x73, 0x19, 0xee, 0x25, 0x64, 0x62, 0x0e, 0x84, 0x2b, 0x61, 0xf2, + 0x0f, 0x09, 0x9f, 0x7d, 0x40, 0x9f, 0xff, 0xfd, 0x66, 0xbf, 0x7e, 0xce, + 0x22, 0xe7, 0xba, 0x17, 0xe3, 0xbf, 0xd2, 0xc2, 0x5a, 0x34, 0xe8, 0xc0, + 0xff, 0xbe, 0xaf, 0x7f, 0xaf, 0x9e, 0xab, 0xd7, 0xff, 0xa6, 0x2f, 0x66, + 0xbe, 0xe3, 0x23, 0x9c, 0xe4, 0x2f, 0x1f, 0x87, 0x9c, 0x63, 0xc0, 0xdc, + 0x23, 0x10, 0x86, 0x9e, 0x5d, 0x30, 0x24, 0xd2, 0x77, 0xca, 0xb8, 0x43, + 0x1d, 0x7b, 0x27, 0xad, 0xf5, 0xc9, 0x42, 0xad, 0x57, 0xca, 0x35, 0xe6, + 0x53, 0xf3, 0xfb, 0x32, 0xda, 0x59, 0xe4, 0x4b, 0x95, 0x37, 0x69, 0xf2, + 0x15, 0x7d, 0xfe, 0xec, 0x43, 0x3f, 0xea, 0x10, 0x94, 0x75, 0x2d, 0x9f, + 0xea, 0x72, 0x77, 0xce, 0xe2, 0x7c, 0x3b, 0x67, 0x51, 0xe7, 0x25, 0x15, + 0xdb, 0x79, 0x22, 0xcc, 0x89, 0xeb, 0xcc, 0x41, 0x2a, 0xc9, 0xa3, 0x87, + 0x7b, 0x24, 0xb9, 0xdc, 0x6b, 0x68, 0xf4, 0x3d, 0x66, 0x1d, 0xac, 0xb7, + 0x34, 0x29, 0xc9, 0xa5, 0x3f, 0x86, 0x6f, 0xaf, 0xf2, 0x22, 0x3b, 0xf2, + 0xdb, 0x87, 0xcd, 0xb7, 0x48, 0x59, 0x8b, 0xf9, 0x28, 0xf9, 0x25, 0x9c, + 0xd7, 0xe1, 0xc4, 0x68, 0xdc, 0xe6, 0xb7, 0xb8, 0x27, 0x24, 0xb9, 0x3a, + 0xa9, 0xbf, 0x89, 0x4b, 0xf3, 0x46, 0x3e, 0xa1, 0xec, 0xe9, 0xd4, 0x65, + 0x3d, 0x9f, 0xbb, 0xc4, 0xf6, 0x14, 0x6c, 0x47, 0xb6, 0xe7, 0x63, 0x01, + 0x75, 0x6b, 0x7f, 0x3f, 0xe8, 0xa9, 0xcb, 0xd8, 0x03, 0xcc, 0xe9, 0xe4, + 0x78, 0xda, 0x1e, 0xa7, 0x71, 0x66, 0xf9, 0xb8, 0x2d, 0x1c, 0xa3, 0xe6, + 0xc3, 0xb3, 0x7f, 0x47, 0x44, 0x5c, 0x8f, 0xcb, 0x7a, 0xd3, 0x05, 0x4f, + 0xe8, 0x9c, 0xf8, 0x62, 0xdd, 0xcf, 0xe5, 0x7c, 0xb4, 0x9d, 0xcb, 0x49, + 0x18, 0x0b, 0x95, 0xdd, 0xb4, 0x77, 0xc8, 0xe4, 0x54, 0xf6, 0xa8, 0xfb, + 0xd9, 0x0e, 0xf9, 0x67, 0xfa, 0x3f, 0x73, 0x80, 0x77, 0xf7, 0x22, 0x6c, + 0x1f, 0x34, 0xed, 0xb0, 0x8f, 0xa2, 0x51, 0xc5, 0x07, 0xc9, 0x86, 0xdf, + 0xef, 0xfa, 0x01, 0x9d, 0x0b, 0x4a, 0x3c, 0x79, 0x06, 0xe6, 0x09, 0xf8, + 0xb1, 0xac, 0x3b, 0x88, 0xb1, 0x3c, 0x27, 0x94, 0x8d, 0x83, 0x2a, 0xd7, + 0x30, 0xe0, 0x4d, 0x99, 0x7b, 0xc1, 0x41, 0xb5, 0x96, 0xe3, 0x71, 0x7e, + 0x5f, 0x36, 0xf4, 0x74, 0xac, 0xbf, 0x1b, 0x5e, 0xc6, 0xe0, 0xfc, 0xdc, + 0x51, 0xb6, 0xf3, 0x7d, 0x77, 0x1f, 0x3f, 0x4f, 0x34, 0x6b, 0x05, 0xdb, + 0x39, 0xf6, 0xc4, 0x25, 0xef, 0x96, 0x51, 0x5e, 0xf6, 0x00, 0x23, 0x9f, + 0x51, 0x9a, 0x6f, 0x07, 0x82, 0x4b, 0xfc, 0xed, 0x9e, 0x27, 0x88, 0xb9, + 0x7d, 0x9e, 0xdd, 0x3b, 0xa7, 0xb4, 0xcb, 0x3b, 0x6f, 0x6d, 0x57, 0x98, + 0x27, 0x51, 0x92, 0x93, 0x99, 0x3e, 0x99, 0xab, 0xd9, 0xfc, 0xc6, 0x93, + 0x31, 0x7a, 0xde, 0x83, 0xcb, 0xbc, 0x92, 0x71, 0x23, 0xc6, 0xe7, 0xee, + 0x81, 0x6f, 0x4e, 0x7a, 0x1e, 0x91, 0xf5, 0xfa, 0x4c, 0x47, 0xfe, 0x6d, + 0x97, 0xa1, 0xb3, 0x7f, 0x1d, 0x92, 0xde, 0x12, 0x7c, 0x32, 0x9f, 0xa7, + 0x47, 0xa4, 0x50, 0xef, 0xbc, 0x3b, 0x63, 0xae, 0x4f, 0xe7, 0x37, 0xb4, + 0x4a, 0x0f, 0xd6, 0x4a, 0xb4, 0xab, 0xa2, 0x8c, 0x4b, 0xb0, 0xdf, 0x7e, + 0xa3, 0x6f, 0xe1, 0x08, 0xf5, 0xbe, 0xc5, 0x12, 0x97, 0xb0, 0x41, 0x47, + 0xa8, 0x75, 0x52, 0x72, 0x34, 0x5a, 0x82, 0x8f, 0x3a, 0x62, 0xd6, 0x7d, + 0x3b, 0xde, 0xd9, 0xf7, 0x80, 0x69, 0xbf, 0xd7, 0xbc, 0xf7, 0x9a, 0xf7, + 0x00, 0xde, 0xeb, 0xad, 0x5a, 0x95, 0x73, 0xb2, 0xe4, 0xf7, 0x22, 0xbc, + 0xdb, 0xf2, 0x24, 0x74, 0x59, 0xa0, 0xa7, 0x7a, 0xe5, 0xf1, 0xba, 0xc2, + 0xaf, 0xe5, 0x2e, 0xd1, 0x20, 0xd8, 0x6f, 0x9e, 0xef, 0xe6, 0xc1, 0x4f, + 0xde, 0x91, 0x37, 0x3c, 0xec, 0x98, 0xdc, 0xec, 0x0e, 0x78, 0xb3, 0x80, + 0xf5, 0xd7, 0xe5, 0x41, 0x51, 0x47, 0x69, 0x5f, 0xb9, 0x50, 0xd1, 0xf9, + 0x3e, 0x27, 0x2b, 0x80, 0xb5, 0xf6, 0x3f, 0x0e, 0xe8, 0xdc, 0x14, 0x3f, + 0x9f, 0x91, 0xf9, 0xee, 0x23, 0x26, 0x27, 0x82, 0x63, 0x99, 0x57, 0xe9, + 0xdf, 0x39, 0x76, 0xda, 0xaa, 0xd4, 0x45, 0xd4, 0x33, 0xfc, 0x6e, 0x25, + 0x8d, 0xbe, 0x8b, 0x94, 0x35, 0xd0, 0x53, 0xbe, 0x2d, 0xf1, 0x39, 0xe5, + 0x1f, 0x76, 0x7e, 0xf7, 0x73, 0x0e, 0xb0, 0xfe, 0x65, 0x93, 0x71, 0xe1, + 0x1e, 0x09, 0x2c, 0xfb, 0x79, 0x50, 0x3c, 0x63, 0xda, 0x61, 0xfc, 0xb6, + 0xfa, 0x77, 0x77, 0xc5, 0x8c, 0x7d, 0x5b, 0x81, 0x74, 0x3e, 0xe7, 0x30, + 0xc7, 0xd4, 0xf1, 0xfc, 0x38, 0x33, 0x73, 0x6b, 0x68, 0x73, 0x1d, 0x14, + 0x5b, 0xc5, 0x8d, 0xd8, 0x56, 0x92, 0xfe, 0xc3, 0xbf, 0x4b, 0xde, 0xf8, + 0x47, 0xfc, 0x16, 0x46, 0xe7, 0x79, 0xab, 0x75, 0xa2, 0xda, 0x86, 0xe4, + 0x37, 0xda, 0x69, 0xf0, 0xd5, 0xbe, 0x2d, 0x9d, 0xf3, 0x1d, 0xc1, 0x7b, + 0x06, 0x74, 0x0c, 0x99, 0x2a, 0xfc, 0x1e, 0x9b, 0x7c, 0xc7, 0xef, 0xb1, + 0x3d, 0x95, 0x6f, 0xb2, 0x6d, 0xbe, 0x2f, 0xba, 0xde, 0x0c, 0x8a, 0xbd, + 0x34, 0xce, 0x6f, 0xd5, 0xf8, 0x6d, 0x23, 0x6c, 0xb5, 0x38, 0xda, 0x99, + 0xc7, 0x36, 0xa4, 0xf2, 0x54, 0xca, 0xcd, 0x8f, 0xa0, 0xfc, 0x34, 0xfc, + 0x75, 0x1d, 0x9f, 0x2f, 0x37, 0x99, 0xaf, 0xe2, 0xa8, 0x7b, 0xcf, 0xe4, + 0x52, 0x01, 0xeb, 0xf9, 0xdf, 0x3e, 0x47, 0x51, 0x47, 0xf8, 0x4a, 0x86, + 0x47, 0xfd, 0x5c, 0x84, 0x0d, 0x87, 0x3a, 0xa1, 0xd4, 0x8c, 0xa8, 0x1c, + 0x17, 0x6d, 0x8f, 0xd0, 0xd6, 0x0b, 0xa3, 0x2f, 0xf7, 0xda, 0x4b, 0x7d, + 0xd5, 0xa2, 0x4c, 0x4a, 0x61, 0x9d, 0x86, 0xca, 0x0f, 0x24, 0x9e, 0x5d, + 0xa7, 0x48, 0x7f, 0x4d, 0xc9, 0xf8, 0xc4, 0xe8, 0xac, 0xe4, 0x9d, 0x10, + 0x7c, 0xb1, 0xb2, 0xf2, 0x73, 0x5e, 0x80, 0x0d, 0x1d, 0xd9, 0x0a, 0x78, + 0xdc, 0x1b, 0xd7, 0xa6, 0x1f, 0xa2, 0xf7, 0xa3, 0xef, 0x8e, 0xc4, 0x2a, + 0xab, 0xef, 0xf5, 0x58, 0xcf, 0x7b, 0x01, 0xff, 0x7b, 0x6c, 0xe6, 0xef, + 0xc3, 0x4f, 0x68, 0x4e, 0xc9, 0xd9, 0xca, 0x7e, 0xe6, 0xc6, 0xa7, 0xb7, + 0x81, 0xb7, 0x93, 0xed, 0x7c, 0x7d, 0xe6, 0xb0, 0xf9, 0xba, 0x87, 0x67, + 0xc5, 0x5c, 0x79, 0xd2, 0x19, 0xf3, 0xe5, 0x69, 0x87, 0x0d, 0xc9, 0xe3, + 0x4d, 0x3f, 0x47, 0x7e, 0x2f, 0x3b, 0x9c, 0x34, 0xf8, 0x59, 0xf8, 0x86, + 0x7e, 0x2e, 0x24, 0x73, 0x36, 0x5b, 0xad, 0x93, 0x69, 0xde, 0xc7, 0xce, + 0x1c, 0x5d, 0xc3, 0x1e, 0xaf, 0xd5, 0x81, 0xc3, 0xe3, 0xac, 0x63, 0xee, + 0x56, 0xb7, 0xe4, 0xc6, 0x55, 0xbc, 0xaf, 0x77, 0xcd, 0xdd, 0x2f, 0x57, + 0x6b, 0x51, 0x95, 0x87, 0x56, 0x84, 0x9d, 0xdf, 0x90, 0xdb, 0x0e, 0xef, + 0xa3, 0x8f, 0xa8, 0xf1, 0x3e, 0xbf, 0x73, 0x9d, 0xa8, 0x1c, 0x59, 0xd7, + 0xf2, 0xe4, 0x54, 0x06, 0x76, 0xcb, 0x25, 0xb1, 0x3e, 0x9a, 0x19, 0x82, + 0xef, 0xcd, 0xb5, 0x52, 0x18, 0x07, 0xda, 0x89, 0x91, 0xd7, 0x7f, 0xd1, + 0x6a, 0x00, 0xde, 0xdb, 0x4d, 0xda, 0xeb, 0xb0, 0xa1, 0x66, 0x38, 0xc6, + 0x13, 0xfb, 0x02, 0xfb, 0x0c, 0x80, 0xfe, 0x42, 0xfa, 0x7b, 0xb4, 0xca, + 0x01, 0x69, 0x38, 0x6c, 0xe3, 0x73, 0x4c, 0x1a, 0x51, 0xdf, 0x4f, 0xf9, + 0x21, 0xf0, 0x17, 0x57, 0x32, 0xc9, 0xbf, 0xc3, 0x67, 0x4e, 0xe9, 0x5c, + 0xed, 0x18, 0x78, 0x28, 0x68, 0x6c, 0xb3, 0x20, 0xe6, 0xf8, 0xbe, 0xa3, + 0x6d, 0x05, 0xde, 0xf1, 0x6b, 0x5b, 0x44, 0xeb, 0x18, 0xde, 0xfb, 0x05, + 0xe1, 0x0b, 0xf8, 0x7c, 0x79, 0xc8, 0xd8, 0x14, 0x9d, 0xbe, 0x7c, 0x2a, + 0x76, 0x91, 0xff, 0x0f, 0x62, 0xf3, 0x83, 0x32, 0x0b, 0x98, 0xcf, 0x9b, + 0x7d, 0x3e, 0x92, 0x71, 0xe5, 0x56, 0x9d, 0x77, 0xf0, 0x07, 0x51, 0x32, + 0xdf, 0x90, 0x30, 0x8f, 0x99, 0x9c, 0x4a, 0x0f, 0x7b, 0x3d, 0x21, 0x2f, + 0xc3, 0xbe, 0x7e, 0xa5, 0x92, 0x4a, 0x1f, 0x51, 0x71, 0xe7, 0x44, 0xec, + 0xaa, 0x8c, 0xc5, 0xe9, 0x03, 0x96, 0x9c, 0x44, 0xec, 0x16, 0xe8, 0xe1, + 0x76, 0xe5, 0x50, 0x3f, 0xff, 0x27, 0x45, 0x03, 0xfa, 0xf0, 0xb6, 0xca, + 0x81, 0x49, 0x30, 0x66, 0x82, 0xf7, 0x21, 0x93, 0x87, 0xc3, 0x75, 0xd8, + 0x36, 0x24, 0x2f, 0x57, 0xda, 0xfa, 0x97, 0xeb, 0xe8, 0xdc, 0x36, 0xa5, + 0x5f, 0x8f, 0xf6, 0x53, 0x0e, 0x71, 0x3d, 0x3d, 0x87, 0xdf, 0x87, 0x78, + 0xf5, 0x63, 0x91, 0x8e, 0xfe, 0xbe, 0xc1, 0x62, 0xde, 0x0b, 0xf7, 0xfe, + 0x13, 0x47, 0xdb, 0x40, 0x1c, 0x97, 0x72, 0x8e, 0xaa, 0xf9, 0x78, 0xdf, + 0x3b, 0x24, 0x3f, 0x6e, 0xfa, 0xf3, 0x30, 0x1f, 0x87, 0x39, 0x3f, 0x94, + 0x7d, 0x9d, 0x30, 0x68, 0xfd, 0xff, 0xb2, 0x8a, 0xeb, 0x4d, 0xa2, 0x3f, + 0x75, 0x34, 0xe8, 0xa5, 0x1e, 0xd3, 0xff, 0xdf, 0xa1, 0x2d, 0xe3, 0xf8, + 0x4c, 0x7c, 0x72, 0x1d, 0xd8, 0xf8, 0x0f, 0x38, 0xa6, 0xdd, 0xb7, 0x4b, + 0x87, 0xc0, 0xaf, 0x27, 0xa4, 0xb1, 0x92, 0x8a, 0x3d, 0x2e, 0xfe, 0xbc, + 0xad, 0x87, 0x79, 0x2f, 0x56, 0xc8, 0x8c, 0x39, 0x0b, 0x0a, 0x1e, 0xde, + 0xdd, 0x26, 0x9c, 0xab, 0x58, 0xaf, 0xd1, 0xdc, 0x1d, 0x7b, 0x48, 0x64, + 0xb7, 0x24, 0x95, 0xd6, 0x67, 0x33, 0x22, 0x5b, 0x38, 0x9b, 0x3f, 0x31, + 0x67, 0xf3, 0x7e, 0xcc, 0xed, 0x5e, 0x18, 0x97, 0xd4, 0x85, 0x54, 0xfc, + 0xbc, 0xf0, 0x8e, 0xf9, 0x00, 0xef, 0x98, 0xad, 0x47, 0x32, 0x71, 0xec, + 0x37, 0x81, 0xfd, 0xa2, 0x6c, 0xf2, 0x99, 0xdf, 0xf7, 0xef, 0x23, 0x6f, + 0x3f, 0x4c, 0x99, 0x49, 0x5c, 0x14, 0x54, 0x1b, 0xec, 0x93, 0xa7, 0x08, + 0xd3, 0xbf, 0xe3, 0xf9, 0xa8, 0x58, 0xe8, 0xad, 0x26, 0xbf, 0x5b, 0xd5, + 0xf0, 0xe5, 0x01, 0xdf, 0xbc, 0x86, 0x2f, 0x3e, 0xdb, 0xb6, 0x5d, 0x13, + 0xb1, 0xb3, 0x42, 0x7b, 0x89, 0xf6, 0x0b, 0xed, 0xfa, 0xbf, 0xe9, 0xd7, + 0xb1, 0x3d, 0xf8, 0xb1, 0x0f, 0x64, 0xdb, 0x7b, 0xef, 0x42, 0xdf, 0x6b, + 0x19, 0x95, 0x63, 0xec, 0x4c, 0xc9, 0x7b, 0x25, 0xfb, 0x91, 0x44, 0x3c, + 0x6b, 0xb9, 0xc6, 0x06, 0x44, 0x59, 0xe7, 0x33, 0x65, 0xae, 0x6b, 0x6c, + 0x0b, 0x9e, 0x4d, 0x06, 0x6b, 0x29, 0xdc, 0xc2, 0x67, 0x1a, 0x02, 0xcd, + 0x93, 0xd6, 0xde, 0x05, 0x1e, 0xd2, 0xff, 0x13, 0xe3, 0x2a, 0xf0, 0x58, + 0x06, 0x1e, 0x4f, 0xdd, 0x65, 0x83, 0x85, 0xda, 0x36, 0xd8, 0xb6, 0x5a, + 0xef, 0x26, 0x60, 0xca, 0x3b, 0xb4, 0xbf, 0xca, 0x6d, 0x5a, 0x21, 0x4c, + 0xe3, 0xfc, 0x2e, 0x5b, 0xae, 0x67, 0x78, 0x1e, 0xb0, 0xc1, 0x30, 0xdf, + 0xda, 0x0e, 0x2d, 0x61, 0xff, 0x8a, 0x7e, 0x41, 0xbb, 0x09, 0x27, 0x68, + 0xf1, 0x2c, 0x38, 0x9f, 0x58, 0x37, 0x00, 0xcb, 0xb6, 0xa2, 0x03, 0x4d, + 0x03, 0xdb, 0xf5, 0xde, 0x37, 0xa0, 0x01, 0xee, 0x93, 0xf4, 0xe7, 0xd3, + 0x5e, 0xfb, 0xbb, 0x75, 0xf8, 0xb7, 0x25, 0xb9, 0xff, 0x90, 0x27, 0xb9, + 0x0b, 0x2d, 0x59, 0x48, 0x8b, 0x35, 0x76, 0x88, 0x34, 0x49, 0x3b, 0x01, + 0x36, 0x64, 0x8c, 0x38, 0xd6, 0xf6, 0xe0, 0xec, 0x57, 0xf7, 0xe3, 0xf7, + 0x6f, 0xfa, 0x79, 0xbf, 0x94, 0xdb, 0xa0, 0xbc, 0x12, 0xeb, 0xbe, 0x43, + 0xda, 0x3f, 0xbc, 0x1d, 0x05, 0xce, 0xd1, 0x9e, 0x7c, 0xa2, 0xcb, 0xc4, + 0x51, 0xb5, 0x5e, 0x4e, 0x3e, 0x41, 0xbc, 0xa2, 0xfc, 0xea, 0x4f, 0x1c, + 0x3f, 0x27, 0x49, 0xc7, 0x04, 0xc9, 0x17, 0x25, 0x99, 0xcf, 0x30, 0x27, + 0xb4, 0x57, 0x8e, 0x40, 0xae, 0x4d, 0x55, 0x26, 0xe5, 0x0b, 0x95, 0x88, + 0xb2, 0x1b, 0xfe, 0x2c, 0x9d, 0x8a, 0x8d, 0x5a, 0x2d, 0x79, 0x04, 0xf6, + 0xcf, 0xec, 0x50, 0x97, 0xbc, 0x32, 0xae, 0xf3, 0x6f, 0x6f, 0x33, 0xb9, + 0xce, 0x61, 0xce, 0x28, 0xf7, 0x03, 0xb9, 0x6f, 0xc1, 0x17, 0xb0, 0xba, + 0x65, 0x36, 0x1a, 0x91, 0xe9, 0x34, 0xca, 0x37, 0xa7, 0xd5, 0x37, 0xa4, + 0xd9, 0x68, 0xa7, 0x1c, 0x21, 0xcc, 0x2c, 0xdf, 0x62, 0xca, 0x9f, 0xf5, + 0x77, 0xc0, 0x62, 0xcd, 0x67, 0x02, 0x6a, 0x7f, 0xe5, 0x3a, 0xe5, 0x1b, + 0xc7, 0x40, 0x9e, 0x34, 0x79, 0x0f, 0x59, 0x92, 0x35, 0xc8, 0x97, 0x62, + 0x4d, 0xac, 0x8d, 0x0c, 0x2c, 0x6a, 0x57, 0xdb, 0x9f, 0x45, 0xd0, 0xd7, + 0x5c, 0x8d, 0xf2, 0x6f, 0x4a, 0xe5, 0x4e, 0xcf, 0xc1, 0xd6, 0x85, 0x4f, + 0x3c, 0xdb, 0xed, 0x99, 0x7b, 0xce, 0x5e, 0xc6, 0x43, 0x3a, 0x65, 0x98, + 0xff, 0x3f, 0x73, 0x0e, 0x0f, 0x48, 0x5f, 0x09, 0xe7, 0xe2, 0xdb, 0xdc, + 0xc0, 0x29, 0xd6, 0xcc, 0xa9, 0x73, 0xf2, 0xcf, 0x84, 0xb2, 0xa7, 0x33, + 0x67, 0xdb, 0xb7, 0x39, 0xc8, 0xb3, 0xd4, 0x17, 0x52, 0x0a, 0xc3, 0xa6, + 0xed, 0xb9, 0x00, 0xdd, 0x5d, 0xf3, 0x40, 0x2b, 0x93, 0xd0, 0x87, 0x93, + 0x52, 0x86, 0xed, 0xf6, 0xd1, 0xf4, 0x67, 0xc5, 0x7e, 0xea, 0xa0, 0xac, + 0xd5, 0x7a, 0x80, 0x0f, 0xea, 0x85, 0x90, 0xf2, 0xaf, 0x6f, 0x1f, 0xa7, + 0xbe, 0xa3, 0x2e, 0xd1, 0x67, 0xb1, 0x5d, 0xff, 0xc4, 0x80, 0xfe, 0x7e, + 0x65, 0xbf, 0x6c, 0xd5, 0x7d, 0x5d, 0x08, 0xff, 0xb0, 0x16, 0x32, 0x7a, + 0xb9, 0x17, 0xb2, 0xfb, 0xaf, 0x43, 0x0d, 0xe5, 0xab, 0x73, 0xff, 0xd4, + 0x41, 0xea, 0xff, 0x70, 0xf4, 0x36, 0x5c, 0xee, 0xbd, 0x53, 0x07, 0x69, + 0xbb, 0xc3, 0x39, 0xcc, 0xf5, 0x78, 0x1f, 0xc7, 0x3d, 0x46, 0x25, 0x74, + 0xf1, 0x84, 0xd8, 0xf0, 0x5b, 0x02, 0x4b, 0xb4, 0xf5, 0xee, 0xf4, 0x5d, + 0x02, 0x97, 0x6d, 0xf3, 0xad, 0xed, 0xb0, 0xb6, 0x65, 0x32, 0x28, 0x1b, + 0xfe, 0xf7, 0xb7, 0xfc, 0xdd, 0xe1, 0xdb, 0x1d, 0x78, 0x03, 0x5d, 0x8a, + 0xbf, 0xff, 0x0b, 0xc4, 0xbf, 0x6d, 0x24, 0x80, 0x4a, 0x00, 0x00, 0x00 }; static const u32 bnx2_COM_b09FwData[(0x0/4) + 1] = { 0x0 }; static const u32 bnx2_COM_b09FwRodata[(0x30/4) + 1] = { - 0x80080100, 0x80080080, 0x80080000, 0x80080240, 0x08000e20, 0x08000e78, - 0x08000ebc, 0x08000f50, 0x08000f94, 0x80080100, 0x80080080, 0x80080000, + 0x80080100, 0x80080080, 0x80080000, 0x80080240, 0x08000ea4, 0x08000efc, + 0x08000f40, 0x08000fd4, 0x08001018, 0x80080100, 0x80080080, 0x80080000, 0x00000000 }; static struct fw_info bnx2_com_fw_09 = { - /* Firmware version: 4.4.23 */ + /* Firmware version: 4.6.15 */ .ver_major = 0x4, - .ver_minor = 0x4, - .ver_fix = 0x17, + .ver_minor = 0x6, + .ver_fix = 0xf, .start_addr = 0x080000f8, .text_addr = 0x08000000, - .text_len = 0x4c18, + .text_len = 0x4a7c, .text_index = 0x0, .gz_text = bnx2_COM_b09FwText, .gz_text_len = sizeof(bnx2_COM_b09FwText), @@ -866,1210 +865,1189 @@ static struct fw_info bnx2_com_fw_09 = { .data_index = 0x0, .data = bnx2_COM_b09FwData, - .sbss_addr = 0x08004c60, + .sbss_addr = 0x08004ae0, .sbss_len = 0x38, .sbss_index = 0x0, - .bss_addr = 0x08004c98, - .bss_len = 0xbc, + .bss_addr = 0x08004b18, + .bss_len = 0xc0, .bss_index = 0x0, - .rodata_addr = 0x08004c18, + .rodata_addr = 0x08004a7c, .rodata_len = 0x30, .rodata_index = 0x0, .rodata = bnx2_COM_b09FwRodata, }; static u8 bnx2_CP_b09FwText[] = { - 0xad, 0xbc, 0x0b, 0x74, 0x1c, 0xd5, 0x95, 0x2e, 0xfc, 0x55, 0x75, 0xb7, - 0xd4, 0x92, 0xda, 0x52, 0x4b, 0x6e, 0xcb, 0x6d, 0xd0, 0xe0, 0x6a, 0xab, - 0xda, 0x6a, 0x2c, 0x01, 0xd5, 0xb2, 0x0c, 0x4d, 0xa6, 0xc0, 0x1d, 0x5b, - 0x80, 0x0c, 0x26, 0x11, 0xc6, 0xb9, 0x23, 0xe6, 0x7a, 0xfe, 0xf4, 0x18, - 0x03, 0x86, 0x90, 0x5c, 0x33, 0x93, 0x9b, 0x71, 0xb8, 0x9e, 0xeb, 0x8a, - 0xe4, 0x87, 0xc0, 0xa5, 0xee, 0x96, 0x90, 0x1f, 0xac, 0x35, 0xeb, 0xa7, - 0x2d, 0xcb, 0x92, 0x21, 0xad, 0x16, 0x49, 0x98, 0x19, 0xe7, 0xe6, 0x81, - 0xc6, 0xd8, 0x60, 0x93, 0xf0, 0xc8, 0x6b, 0xfd, 0x4c, 0xfe, 0xb9, 0x7f, - 0x3c, 0xb6, 0x79, 0x83, 0xe3, 0x3c, 0x47, 0x9e, 0xc1, 0xa9, 0xff, 0xdb, - 0xd5, 0xdd, 0xb6, 0xec, 0x40, 0x1e, 0xeb, 0x8e, 0xd6, 0xaa, 0xa5, 0xee, - 0xaa, 0x73, 0xf6, 0x39, 0x67, 0x9f, 0xbd, 0xbf, 0xfd, 0xed, 0x73, 0x4e, - 0xb5, 0x06, 0x54, 0xa3, 0xf4, 0x37, 0x8b, 0xd7, 0xd5, 0x1d, 0x1b, 0xee, - 0x5e, 0xdc, 0x7e, 0x75, 0x87, 0x7c, 0xf7, 0xce, 0xf5, 0x7a, 0xf1, 0x61, - 0x7f, 0x26, 0x12, 0x97, 0xde, 0xd2, 0x3e, 0xb4, 0xe0, 0x47, 0xfc, 0x25, - 0x10, 0x91, 0x7f, 0xad, 0xa5, 0xaf, 0x1e, 0x20, 0x58, 0x6e, 0x5f, 0x2e, - 0xf8, 0x55, 0xb3, 0xf3, 0xbf, 0x2e, 0xd3, 0xe1, 0xf7, 0x98, 0x9f, 0xff, - 0x8b, 0xbb, 0x75, 0x20, 0x99, 0x6f, 0xd5, 0x96, 0xe3, 0x9c, 0x63, 0x85, - 0xbc, 0x90, 0xfb, 0x7f, 0x62, 0x7e, 0xf0, 0xc4, 0xb7, 0xae, 0x8b, 0x9c, - 0xc9, 0x79, 0xe0, 0x0f, 0x9a, 0x16, 0x82, 0x0b, 0xe1, 0x6f, 0x62, 0x9d, - 0xbf, 0x6b, 0xd9, 0xa6, 0xa2, 0xb6, 0x2c, 0x2b, 0x12, 0xce, 0x21, 0x12, - 0xb4, 0x10, 0x89, 0x59, 0x40, 0xca, 0x6b, 0x22, 0x55, 0x69, 0xfa, 0x51, - 0xa1, 0x57, 0x20, 0x15, 0xdc, 0xa8, 0x6d, 0xe1, 0x18, 0x97, 0xd9, 0x7e, - 0xed, 0x44, 0x1e, 0xb8, 0xdb, 0xf6, 0xe3, 0xb8, 0x27, 0xa0, 0x9d, 0xcc, - 0xef, 0xab, 0x2b, 0xea, 0x23, 0x09, 0x8f, 0x8e, 0x94, 0x6a, 0xca, 0x7d, - 0x68, 0xcb, 0xf3, 0x48, 0xf9, 0xcc, 0xcf, 0x6b, 0xe3, 0x36, 0xd0, 0x9b, - 0x69, 0x36, 0x4e, 0xa0, 0x35, 0x7c, 0x18, 0x95, 0x48, 0x85, 0x22, 0x31, - 0xe0, 0x83, 0x73, 0x8f, 0x66, 0x14, 0xf8, 0xf4, 0xd9, 0xe8, 0xdc, 0x0b, - 0x3c, 0x92, 0x89, 0x24, 0x75, 0x05, 0xe8, 0x9f, 0x94, 0xba, 0x91, 0x60, - 0x8e, 0xcf, 0xb7, 0x64, 0x80, 0xad, 0x99, 0xd9, 0xd8, 0x96, 0x75, 0xf0, - 0x9c, 0xd1, 0x1c, 0xdc, 0xc7, 0x16, 0x7a, 0xdd, 0xe7, 0xb3, 0x61, 0xe5, - 0xe4, 0xf9, 0x5b, 0xce, 0xb7, 0x5a, 0x82, 0x78, 0x7a, 0x32, 0x84, 0x67, - 0x27, 0xeb, 0xf1, 0x48, 0xb6, 0x1e, 0xdb, 0xb3, 0x31, 0xa8, 0xba, 0x83, - 0x58, 0x3c, 0x86, 0x8a, 0xeb, 0x1d, 0x9c, 0x34, 0xda, 0xb0, 0x95, 0x82, - 0x5f, 0x6d, 0x6b, 0xc4, 0xda, 0x60, 0x13, 0xb6, 0xe8, 0xd7, 0xa1, 0x38, - 0xd6, 0x0f, 0xce, 0x65, 0x32, 0xd2, 0x3f, 0xaf, 0xaa, 0xea, 0x37, 0xe2, - 0xf4, 0x4e, 0x13, 0xef, 0xef, 0xc4, 0x9a, 0x5a, 0x38, 0x4e, 0x3e, 0x1e, - 0xed, 0x7e, 0x50, 0x09, 0x6a, 0x4f, 0xe5, 0xd9, 0xa1, 0x55, 0x5e, 0xca, - 0x83, 0x36, 0x92, 0x9f, 0x39, 0x15, 0x6c, 0x2f, 0xc3, 0x76, 0x33, 0xd2, - 0x97, 0x30, 0xbe, 0xd5, 0xf2, 0xdf, 0x68, 0x0f, 0xc5, 0x31, 0x6d, 0xcd, - 0xbc, 0xc6, 0x3e, 0x69, 0xec, 0x4f, 0x13, 0xbe, 0x36, 0x19, 0xc6, 0x57, - 0xd9, 0xb7, 0xaf, 0x4c, 0x4a, 0x1f, 0x23, 0x7b, 0x2c, 0xd4, 0x63, 0x34, - 0xdb, 0x84, 0xa7, 0xf5, 0x36, 0x7c, 0x85, 0x7d, 0xec, 0x33, 0x62, 0x58, - 0x9b, 0xb8, 0x8b, 0xfd, 0x51, 0xb0, 0xaa, 0xed, 0x2f, 0x4b, 0xfd, 0x8a, - 0x68, 0x50, 0x55, 0x24, 0x1b, 0x22, 0x31, 0x4d, 0x15, 0x99, 0x17, 0xfa, - 0x3b, 0x90, 0x81, 0xe5, 0x37, 0xa5, 0xcf, 0x37, 0x22, 0xcf, 0xfe, 0x7e, - 0x79, 0x67, 0xd4, 0x58, 0xaf, 0x62, 0x65, 0x80, 0x7d, 0x7e, 0x20, 0x1e, - 0x4d, 0x2c, 0x62, 0x9f, 0xc7, 0xf3, 0x2a, 0xc7, 0x13, 0xd2, 0xc6, 0xd8, - 0xf7, 0xe4, 0x2a, 0x95, 0x7d, 0x67, 0x5f, 0x32, 0xec, 0x4b, 0x86, 0x7d, - 0xc9, 0xb0, 0x2f, 0x6e, 0xbf, 0x63, 0xec, 0x73, 0x71, 0x8e, 0x46, 0xf2, - 0xc7, 0xd9, 0xdf, 0x99, 0xfd, 0x6c, 0x62, 0xdf, 0x91, 0xaa, 0xe7, 0xbc, - 0x35, 0xa7, 0x65, 0xde, 0x1c, 0xe7, 0x55, 0xc3, 0x71, 0x7e, 0x6e, 0x04, - 0xa8, 0xbf, 0x0c, 0xed, 0xa0, 0xdc, 0x9f, 0xf9, 0x56, 0x85, 0x89, 0x4e, - 0x9a, 0xa0, 0x73, 0xa4, 0x23, 0x9a, 0x68, 0x50, 0x54, 0x78, 0xf5, 0xa0, - 0xd6, 0x52, 0x88, 0x18, 0xd4, 0x8f, 0x16, 0x2d, 0x40, 0xd3, 0x0b, 0x94, - 0x75, 0x51, 0xbb, 0x91, 0xe0, 0x14, 0xa4, 0x5d, 0x8d, 0xed, 0x1f, 0x2f, - 0xcd, 0x9d, 0xc8, 0x0f, 0xb3, 0x4d, 0x69, 0x5f, 0x64, 0x3b, 0xce, 0xcf, - 0x0c, 0xe8, 0x41, 0x44, 0xad, 0x41, 0xda, 0x9f, 0xc7, 0x0c, 0x6a, 0x1b, - 0xf2, 0x7c, 0x7e, 0x5e, 0x46, 0x71, 0x3e, 0xd6, 0xe6, 0xb5, 0xd2, 0x18, - 0x22, 0xec, 0x82, 0xd8, 0x41, 0x38, 0x15, 0x30, 0x83, 0xd2, 0xf7, 0xee, - 0x3d, 0x03, 0x9b, 0x9d, 0x79, 0xba, 0xe8, 0x4a, 0xdf, 0x38, 0xcf, 0x13, - 0x48, 0x9c, 0x5e, 0xf2, 0x90, 0x35, 0xab, 0x23, 0x8e, 0x6a, 0x1d, 0x81, - 0x2a, 0x1d, 0xdd, 0xe9, 0x89, 0x6a, 0xab, 0xc6, 0xfc, 0xe6, 0x9d, 0x03, - 0x13, 0x7e, 0x54, 0x4f, 0xe8, 0xa8, 0x9a, 0x78, 0xdc, 0x8b, 0x5a, 0x03, - 0x3b, 0x26, 0xff, 0xcc, 0x5b, 0x1c, 0xdb, 0xcd, 0xa5, 0x31, 0xba, 0xb6, - 0xef, 0x7f, 0xdd, 0x3e, 0xe3, 0x54, 0xe8, 0x55, 0x7f, 0xe6, 0x31, 0x75, - 0x6d, 0x0c, 0x38, 0xb3, 0xb6, 0x63, 0x39, 0x7a, 0x83, 0x0a, 0xe6, 0xeb, - 0x7f, 0x32, 0x0b, 0xb5, 0x26, 0xac, 0xc9, 0xc6, 0x54, 0x85, 0x19, 0x4a, - 0x71, 0x6e, 0xf0, 0x82, 0x9d, 0x83, 0x6f, 0xc0, 0x71, 0xa4, 0xec, 0x49, - 0xdc, 0x79, 0xa7, 0x6a, 0x1e, 0xba, 0xc6, 0x87, 0x4e, 0x96, 0xc7, 0xa6, - 0xa3, 0x1d, 0x3f, 0x57, 0xd4, 0x9d, 0xdd, 0xb0, 0xc6, 0x3d, 0x48, 0x06, - 0x53, 0xfc, 0x7f, 0xc5, 0x15, 0x2b, 0x13, 0xdd, 0xb0, 0xc7, 0xa7, 0x79, - 0xdf, 0xcb, 0x7b, 0x26, 0xd2, 0x99, 0x2b, 0xae, 0xb8, 0x3d, 0x91, 0xc2, - 0xc0, 0xb8, 0x7c, 0xf6, 0x62, 0xaa, 0x3e, 0x85, 0xed, 0xbb, 0x35, 0xd4, - 0xe9, 0xdd, 0xc8, 0x8c, 0xcb, 0x67, 0xc7, 0x39, 0x65, 0x7c, 0x09, 0x7b, - 0xda, 0xe8, 0xff, 0x73, 0xbb, 0xb1, 0x6d, 0xb7, 0x85, 0x4a, 0xdd, 0xa2, - 0xee, 0x15, 0xef, 0x3f, 0xb7, 0x29, 0xd0, 0xee, 0x84, 0xb7, 0x42, 0x17, - 0xbd, 0x25, 0xbc, 0xf7, 0xd8, 0x66, 0x70, 0xbe, 0xee, 0x38, 0x23, 0xc6, - 0x22, 0x7c, 0xba, 0x7b, 0x2d, 0xac, 0x7d, 0x01, 0x58, 0xab, 0xe5, 0x7f, - 0x37, 0x75, 0xb8, 0x16, 0xbd, 0xfb, 0xd6, 0xa2, 0xff, 0x31, 0x3a, 0x6e, - 0x7d, 0xd0, 0x9d, 0xa7, 0x6f, 0xb5, 0x48, 0x9f, 0xa4, 0x7f, 0x3d, 0xbc, - 0x44, 0xb7, 0x5f, 0xe0, 0x7f, 0x29, 0x33, 0xed, 0x60, 0xce, 0x85, 0x32, - 0xdb, 0x59, 0x66, 0xdb, 0x45, 0x65, 0x4c, 0x3c, 0x31, 0x29, 0xba, 0x10, - 0x95, 0xfd, 0x3e, 0x5d, 0x7c, 0xdb, 0xe9, 0x0d, 0x89, 0x2e, 0xac, 0x1e, - 0x1f, 0x22, 0xdd, 0xf7, 0x2a, 0x5e, 0xac, 0x18, 0x00, 0xeb, 0xd0, 0x09, - 0xaa, 0x23, 0xc9, 0x85, 0x8a, 0x89, 0xea, 0x01, 0x05, 0x2b, 0xe2, 0x55, - 0xd0, 0xea, 0x45, 0xde, 0x8f, 0x1c, 0x2b, 0x28, 0xfd, 0x3d, 0x8a, 0x1a, - 0xde, 0x5f, 0x17, 0xff, 0x01, 0xf1, 0x4c, 0xfa, 0x14, 0x67, 0xf9, 0x3b, - 0x78, 0xff, 0x95, 0x19, 0xdf, 0xa5, 0x9c, 0xe3, 0xf4, 0x19, 0x06, 0xfa, - 0x33, 0x6d, 0xd8, 0x9e, 0x49, 0x46, 0xa8, 0x25, 0xcb, 0x67, 0xf2, 0xbe, - 0x19, 0xed, 0xea, 0x85, 0xb4, 0x03, 0xa5, 0xda, 0x84, 0x37, 0xdf, 0x71, - 0xdc, 0xff, 0x92, 0xad, 0xf7, 0x3c, 0xa5, 0xf8, 0x68, 0xec, 0xd2, 0xce, - 0x71, 0xff, 0x2b, 0xb6, 0x82, 0x37, 0xf5, 0xe8, 0x86, 0x77, 0x94, 0xe3, - 0xfe, 0x97, 0xf3, 0x41, 0xcc, 0x1b, 0x88, 0xf4, 0x58, 0x4a, 0x02, 0x5f, - 0xcf, 0x87, 0x10, 0x1e, 0x30, 0x71, 0x30, 0x6f, 0xe0, 0xc9, 0x8b, 0x70, - 0xe0, 0x43, 0xff, 0x2c, 0x0f, 0xc7, 0xbe, 0xce, 0xd6, 0xd0, 0x6b, 0x9c, - 0x73, 0x92, 0x41, 0xa4, 0xea, 0xcc, 0xe3, 0xfe, 0xf7, 0x07, 0xa0, 0xd4, - 0x9a, 0x7a, 0xb8, 0xa0, 0xfc, 0xab, 0x93, 0x0a, 0x49, 0x31, 0xf6, 0xcf, - 0xc5, 0xb2, 0x24, 0xed, 0xce, 0x20, 0xce, 0x9d, 0x71, 0x6a, 0x68, 0xb3, - 0x15, 0xe6, 0x65, 0x18, 0x1f, 0xd6, 0xf1, 0xa4, 0xed, 0x38, 0xef, 0x19, - 0x53, 0x89, 0x00, 0xf4, 0xee, 0x77, 0x11, 0x49, 0x2e, 0xa2, 0x5e, 0x8e, - 0xe6, 0x75, 0x8c, 0xda, 0x26, 0x9e, 0xb3, 0x9b, 0x83, 0x7d, 0x58, 0x8c, - 0x64, 0xb8, 0x18, 0x43, 0x26, 0xd8, 0xef, 0x91, 0x68, 0x37, 0xea, 0xcc, - 0x04, 0x0e, 0xb1, 0xdf, 0xa7, 0x97, 0x88, 0x1c, 0x03, 0x2f, 0xff, 0x01, - 0x7d, 0x25, 0xbe, 0xe3, 0x71, 0xf6, 0x35, 0xb1, 0xf8, 0x9c, 0x83, 0xd9, - 0x7e, 0x9c, 0x30, 0xe6, 0xd2, 0x0e, 0x61, 0x55, 0x99, 0x7e, 0x6f, 0xbf, - 0x1d, 0xc4, 0x81, 0x7c, 0xc0, 0xdb, 0x67, 0x87, 0xb0, 0x8f, 0xfe, 0x36, - 0x8f, 0xa6, 0x1e, 0xa6, 0xdc, 0x79, 0xc4, 0xb5, 0xc2, 0x70, 0x13, 0x26, - 0x87, 0x23, 0xc6, 0x2b, 0x4a, 0x18, 0x63, 0xa3, 0x97, 0x61, 0x62, 0x58, - 0xc1, 0x78, 0x94, 0x7d, 0xe7, 0xe7, 0x2f, 0x0f, 0x5f, 0x81, 0xfc, 0xb0, - 0x07, 0x3b, 0x5c, 0xbd, 0xba, 0x38, 0x53, 0xfa, 0x7f, 0x19, 0x72, 0xa3, - 0xf0, 0x2e, 0x1a, 0x08, 0xe2, 0xa9, 0xbc, 0xd7, 0xab, 0x0f, 0x84, 0x30, - 0x9a, 0xff, 0x36, 0xe7, 0x4d, 0x64, 0x6b, 0x18, 0xb1, 0xc7, 0xdc, 0x39, - 0xac, 0x33, 0x29, 0xac, 0x18, 0x5f, 0x19, 0xcb, 0x34, 0xc6, 0x99, 0x04, - 0x71, 0x48, 0x7c, 0xdc, 0x4f, 0x0c, 0x12, 0x1f, 0x7f, 0x4d, 0x41, 0x6d, - 0x02, 0x7d, 0x93, 0xe5, 0xe7, 0x0a, 0xed, 0xdf, 0x8b, 0x75, 0x41, 0x03, - 0x76, 0x46, 0xec, 0xb4, 0x8c, 0xcb, 0xf2, 0x59, 0xe6, 0xbf, 0x1a, 0xd6, - 0xfe, 0x6a, 0xec, 0xa0, 0x8f, 0x3d, 0xba, 0x53, 0xee, 0x3b, 0xce, 0x7d, - 0xf1, 0x3a, 0xda, 0x18, 0x6e, 0xaa, 0x42, 0xd4, 0x78, 0xcb, 0xed, 0x9b, - 0x85, 0xb1, 0xbc, 0xc4, 0x50, 0x8d, 0xf1, 0xed, 0x28, 0xdb, 0xea, 0x60, - 0x3b, 0x06, 0xbe, 0x3d, 0xd9, 0x86, 0x7f, 0x9c, 0x8c, 0xe1, 0x1f, 0x26, - 0x75, 0xfc, 0xfd, 0xa4, 0x86, 0x67, 0x2e, 0xc2, 0xf5, 0x3b, 0xa9, 0x2b, - 0xc1, 0x30, 0x03, 0x5b, 0x32, 0x15, 0xd8, 0x36, 0x5c, 0x8d, 0xbe, 0xe1, - 0xe6, 0xd8, 0x73, 0xc4, 0xe3, 0x7f, 0x30, 0x6e, 0xc7, 0x54, 0x43, 0x87, - 0xeb, 0x33, 0x8f, 0xf0, 0xfe, 0xa3, 0xc3, 0xcd, 0x9c, 0x43, 0xc7, 0x51, - 0xe3, 0xad, 0x89, 0x43, 0xc4, 0xf7, 0xe3, 0xa1, 0x88, 0x36, 0xa5, 0x46, - 0xb4, 0x24, 0x7c, 0xb0, 0xdb, 0x54, 0x58, 0x73, 0x22, 0x39, 0x7a, 0x31, - 0x42, 0xfa, 0x7d, 0x1c, 0x5b, 0x44, 0xb3, 0x54, 0x83, 0xf6, 0xcb, 0x98, - 0xa1, 0x76, 0x10, 0x5f, 0xaa, 0xf1, 0xfe, 0x70, 0xa4, 0xdf, 0x52, 0xef, - 0x80, 0xd5, 0xe0, 0x38, 0x5f, 0x8d, 0x63, 0xc3, 0x5c, 0x13, 0xc9, 0x39, - 0x8c, 0x05, 0x57, 0x98, 0x49, 0x30, 0x8e, 0xe1, 0xf4, 0x80, 0x1e, 0xfe, - 0x7f, 0x94, 0x3b, 0xf1, 0xdf, 0xbb, 0x23, 0x9a, 0xa6, 0xb6, 0x5a, 0xfb, - 0x54, 0x92, 0x8d, 0x46, 0x68, 0x61, 0xf3, 0x56, 0x6c, 0x74, 0x79, 0x82, - 0x82, 0xa0, 0xde, 0x81, 0xbe, 0x0c, 0x2b, 0x85, 0x9a, 0x7b, 0x06, 0xd5, - 0xe6, 0x69, 0x43, 0x8d, 0x1c, 0xed, 0x56, 0x89, 0xb7, 0x8b, 0x4f, 0x3b, - 0x5a, 0xa3, 0xe3, 0xb4, 0x2f, 0x96, 0x36, 0x35, 0x34, 0x70, 0x9e, 0xeb, - 0x39, 0xcf, 0xed, 0x85, 0x6a, 0xbc, 0x33, 0x0c, 0x6b, 0xae, 0x19, 0xe9, - 0x7a, 0x40, 0xad, 0xc6, 0xdb, 0xa3, 0xd5, 0x38, 0x39, 0xec, 0xc5, 0x5b, - 0xc3, 0x8e, 0x73, 0x8f, 0x51, 0x87, 0x8a, 0x38, 0xe6, 0x54, 0x20, 0x7a, - 0x66, 0x04, 0x16, 0x7e, 0xc3, 0xb2, 0xbf, 0x1c, 0x0e, 0xe3, 0x57, 0xc3, - 0x1f, 0xc3, 0x33, 0x0d, 0xc9, 0x63, 0xb3, 0x19, 0x23, 0xa7, 0x69, 0x3f, - 0xa7, 0xed, 0x48, 0xcf, 0x3c, 0x4f, 0x64, 0x23, 0x79, 0xcb, 0xfa, 0x2f, - 0x2a, 0x91, 0xd4, 0x2b, 0x4a, 0x44, 0x1b, 0x50, 0x42, 0x78, 0x97, 0x76, - 0x7a, 0x2a, 0xdf, 0x9c, 0xf8, 0x01, 0xdb, 0xff, 0xb5, 0xf1, 0x0f, 0xce, - 0x54, 0xa3, 0xe8, 0x50, 0xf4, 0x45, 0x9d, 0xd3, 0x77, 0xff, 0x91, 0x31, - 0xea, 0x1f, 0x32, 0xd4, 0x39, 0xfb, 0xf3, 0xcc, 0x6f, 0xc5, 0x2f, 0x99, - 0xaf, 0x04, 0xe7, 0xf1, 0x72, 0xfc, 0x4f, 0x77, 0x6c, 0xc7, 0x9c, 0xbf, - 0x09, 0xc9, 0xf8, 0x3a, 0x1b, 0x8b, 0x18, 0x24, 0xe3, 0x3c, 0xea, 0xa4, - 0x82, 0x32, 0x46, 0x19, 0xab, 0xab, 0x4b, 0x6d, 0x83, 0xf2, 0x90, 0x8a, - 0x6a, 0xc7, 0x79, 0xcc, 0x28, 0x3d, 0x0f, 0x95, 0xc7, 0xfa, 0x31, 0xde, - 0x97, 0xf1, 0xbe, 0xe3, 0x11, 0xdd, 0x6b, 0xea, 0xd5, 0xfc, 0x1e, 0xb1, - 0x92, 0xb8, 0x33, 0xc0, 0xef, 0xb1, 0xe4, 0xf9, 0xef, 0xde, 0xba, 0x8b, - 0x9f, 0xd3, 0x4e, 0xdd, 0xf6, 0xee, 0xe4, 0x77, 0x19, 0xcb, 0xab, 0xb4, - 0x9b, 0x0f, 0xb3, 0x13, 0xb1, 0x91, 0x18, 0xed, 0xe9, 0x94, 0xc4, 0x15, - 0x2b, 0x64, 0xfa, 0x2d, 0xd5, 0x84, 0x46, 0x9c, 0xf0, 0x2b, 0xe6, 0x06, - 0x68, 0x79, 0x0b, 0x9f, 0xea, 0xf0, 0xe0, 0xaf, 0x3a, 0x14, 0xcc, 0xd6, - 0x37, 0x20, 0x7b, 0xad, 0xe5, 0xd4, 0xeb, 0x7b, 0x55, 0xf1, 0x81, 0x8a, - 0x34, 0x2c, 0xfa, 0x1d, 0x12, 0xe4, 0x4a, 0x75, 0x7f, 0xaa, 0xe0, 0x44, - 0x3c, 0x4a, 0x9b, 0xdb, 0x82, 0x6d, 0x9c, 0xf3, 0x59, 0x69, 0xf8, 0x03, - 0xa6, 0x09, 0x7b, 0x00, 0xfe, 0x2a, 0xfa, 0xfe, 0x95, 0x03, 0xcd, 0x1b, - 0xc6, 0x94, 0x48, 0x22, 0xad, 0x44, 0xba, 0xa9, 0x6f, 0xe3, 0xb4, 0x8b, - 0x1b, 0x11, 0xad, 0x42, 0x91, 0x76, 0x4c, 0xb4, 0xe4, 0xb7, 0x60, 0x60, - 0x52, 0x3e, 0x27, 0xa0, 0xe7, 0x7f, 0x5c, 0xea, 0x3b, 0xfc, 0x3e, 0xf6, - 0x61, 0xbf, 0xfd, 0xba, 0x93, 0x0b, 0x46, 0xb4, 0x9c, 0xfb, 0x7d, 0x3d, - 0xbf, 0xc3, 0x5f, 0x61, 0x3e, 0x88, 0xe7, 0xed, 0x37, 0xe7, 0x94, 0xcb, - 0x15, 0xfb, 0x7a, 0x69, 0x7f, 0xfe, 0xb7, 0x93, 0x0c, 0xb9, 0xfd, 0xf1, - 0xd7, 0xb0, 0x8d, 0xcf, 0x0c, 0xb0, 0x8d, 0x4c, 0xb9, 0x3f, 0x40, 0x20, - 0x2d, 0x71, 0x38, 0xa2, 0x2d, 0x50, 0x9a, 0x8d, 0x01, 0x25, 0x12, 0xbb, - 0x57, 0x69, 0x4d, 0x8c, 0x91, 0x5f, 0x6e, 0x47, 0xb1, 0x4f, 0xd1, 0x7c, - 0xb1, 0x3f, 0x0b, 0xf2, 0x50, 0x3c, 0x03, 0x08, 0xcc, 0xd7, 0x17, 0x62, - 0xb3, 0x3b, 0xa7, 0x50, 0xc2, 0x03, 0x1a, 0x6a, 0xc9, 0x5f, 0xc2, 0x13, - 0xc0, 0xe4, 0x10, 0xb9, 0x5c, 0xbc, 0x19, 0x9f, 0x63, 0x2c, 0x98, 0xc7, - 0x32, 0x5f, 0x0c, 0x9e, 0xc7, 0x2f, 0xa5, 0xdf, 0x26, 0xc0, 0xcc, 0x29, - 0xf2, 0xb2, 0xd4, 0x7f, 0x41, 0x52, 0xee, 0x3d, 0x6e, 0x43, 0xc9, 0xd8, - 0x91, 0x3d, 0x80, 0x3e, 0x15, 0xf7, 0x24, 0xef, 0x0f, 0x63, 0x33, 0x4e, - 0xc7, 0xa3, 0xa9, 0x82, 0x12, 0x35, 0x86, 0x14, 0xc3, 0xbf, 0x8d, 0xed, - 0xed, 0x60, 0x99, 0xed, 0xbc, 0x1e, 0x88, 0xea, 0x5d, 0x77, 0x28, 0xc9, - 0x2b, 0xab, 0x58, 0xe6, 0xa4, 0x11, 0x25, 0xcf, 0x8c, 0x4e, 0xaf, 0x82, - 0xe1, 0x7f, 0x22, 0x2f, 0xb2, 0x12, 0xca, 0x96, 0xc2, 0xe3, 0x6a, 0x11, - 0x8f, 0x7e, 0x5d, 0xd2, 0xd9, 0x49, 0xf9, 0xee, 0xb6, 0xed, 0x1d, 0x68, - 0xaa, 0xf9, 0xed, 0x7b, 0xda, 0x9c, 0x8b, 0xef, 0xb5, 0x06, 0x47, 0xe9, - 0x7f, 0x1e, 0xbd, 0x8a, 0x73, 0x27, 0xfc, 0x28, 0x19, 0xf3, 0x41, 0xee, - 0x79, 0x90, 0xf3, 0x26, 0xc3, 0x1e, 0x7c, 0xe0, 0x24, 0x57, 0xcb, 0xbd, - 0x6a, 0xa4, 0xba, 0x5b, 0xc3, 0x5e, 0xb4, 0x26, 0xb6, 0x12, 0x0b, 0x8e, - 0xaf, 0x5e, 0xc6, 0x67, 0x51, 0xe3, 0x39, 0x34, 0x6b, 0x5b, 0x21, 0x9f, - 0xcf, 0xd2, 0x66, 0x97, 0x49, 0x5d, 0x96, 0x29, 0x72, 0x1f, 0xc1, 0x9a, - 0x2d, 0x86, 0x83, 0xe7, 0x0d, 0x58, 0x95, 0xe6, 0x41, 0xe5, 0x84, 0xfd, - 0x1b, 0x27, 0xe9, 0xc5, 0x4a, 0xfa, 0xa5, 0x41, 0xda, 0xab, 0xf9, 0xcd, - 0xa8, 0x76, 0x94, 0x99, 0x82, 0xc7, 0xb4, 0x94, 0xe3, 0xf9, 0x2d, 0xca, - 0xeb, 0xf9, 0x7e, 0xe5, 0x54, 0x5e, 0xea, 0x1e, 0x54, 0x4e, 0xe6, 0x25, - 0x1e, 0x36, 0x69, 0x47, 0xc8, 0x6f, 0xc8, 0xa9, 0xd4, 0x3e, 0x03, 0xca, - 0x36, 0xa3, 0x96, 0x3c, 0x5f, 0x8f, 0x8d, 0xb0, 0xbf, 0xfb, 0x3b, 0x60, - 0x6c, 0x37, 0x7c, 0x38, 0x1e, 0x44, 0xa0, 0xcf, 0xf0, 0xca, 0x77, 0xe6, - 0x03, 0x52, 0xb7, 0x49, 0xdb, 0x9a, 0x3f, 0x47, 0xff, 0x2a, 0x7e, 0xdf, - 0xdf, 0x51, 0xbe, 0xf7, 0x0b, 0x67, 0x6a, 0xb5, 0xca, 0xef, 0x7f, 0xea, - 0xe1, 0x50, 0x58, 0x77, 0x26, 0x3f, 0x17, 0x2e, 0xa5, 0x92, 0x3f, 0xd6, - 0xc3, 0x0a, 0x46, 0xac, 0x1c, 0x73, 0x85, 0xbe, 0x4c, 0x3b, 0xfd, 0x2d, - 0xcc, 0x58, 0x99, 0x24, 0xbe, 0x93, 0xf7, 0xb2, 0xcd, 0x0a, 0x3d, 0x80, - 0x9b, 0xec, 0x66, 0x4f, 0x51, 0x7f, 0x2a, 0x31, 0xcc, 0xc3, 0x98, 0x2e, - 0x1c, 0xef, 0x52, 0xce, 0xdd, 0xa4, 0xbd, 0xc5, 0x7e, 0x57, 0xe9, 0x7a, - 0xac, 0x4a, 0x69, 0xd2, 0x5e, 0xcf, 0x27, 0xe9, 0xe3, 0x3d, 0x6c, 0x37, - 0x80, 0xd7, 0xed, 0x5a, 0xe6, 0x20, 0x91, 0xa4, 0x45, 0x81, 0x37, 0x77, - 0x84, 0x41, 0xce, 0x37, 0xe3, 0xaf, 0x1b, 0x8c, 0xff, 0x12, 0xa3, 0xd5, - 0x5b, 0x96, 0x24, 0xb0, 0x3e, 0x0f, 0xef, 0xba, 0x0e, 0x13, 0xf7, 0x30, - 0xb6, 0xdf, 0xc7, 0x78, 0xf9, 0x20, 0x63, 0xe1, 0x8e, 0x38, 0xc7, 0x56, - 0xef, 0x38, 0x95, 0xfa, 0x66, 0xc9, 0x67, 0x30, 0xc0, 0x58, 0x7c, 0x37, - 0xe3, 0xcb, 0x16, 0x7e, 0x7e, 0x29, 0xff, 0x1f, 0xce, 0x7d, 0xcc, 0xa7, - 0x9e, 0xbf, 0x48, 0x26, 0xd4, 0x51, 0xbd, 0x35, 0xb6, 0x95, 0xb1, 0x98, - 0x72, 0xad, 0x5a, 0xd3, 0x71, 0xae, 0x8c, 0x46, 0x92, 0x3e, 0xc5, 0xc0, - 0x73, 0x13, 0xc7, 0x1d, 0x6d, 0x8e, 0xe4, 0x52, 0xe5, 0x38, 0x28, 0x63, - 0x95, 0x1c, 0x41, 0xf0, 0x41, 0xf2, 0x84, 0x99, 0x18, 0xa1, 0xe2, 0xe6, - 0x61, 0xc9, 0x13, 0xc2, 0x58, 0x65, 0x7f, 0x09, 0xcf, 0xb5, 0x79, 0xd1, - 0xc5, 0x1c, 0xeb, 0x16, 0x3b, 0x80, 0x3b, 0x88, 0xa5, 0x2b, 0x6c, 0xe6, - 0x4e, 0xc1, 0x10, 0x6e, 0xb5, 0xbd, 0x38, 0xdc, 0xc6, 0x1c, 0x28, 0x54, - 0x89, 0x77, 0x0d, 0x0f, 0x8e, 0x18, 0x41, 0xe4, 0x5c, 0x7f, 0xd8, 0x41, - 0x0c, 0xa4, 0x1e, 0x55, 0xc9, 0x1d, 0x44, 0x87, 0x1e, 0xea, 0x53, 0x45, - 0xea, 0xbc, 0x0e, 0x3f, 0x2c, 0x17, 0x90, 0x7e, 0x49, 0x3e, 0xf0, 0x33, - 0x27, 0x35, 0x47, 0xea, 0xc3, 0x0a, 0x98, 0x32, 0x0e, 0xe1, 0xb7, 0x06, - 0xfa, 0x26, 0x3a, 0xc8, 0xed, 0x66, 0x0e, 0xf5, 0x0c, 0xb9, 0x75, 0x1d, - 0x5e, 0xd3, 0x85, 0x5b, 0xbf, 0x8a, 0x20, 0x7d, 0xb7, 0x7f, 0x22, 0xba, - 0xe1, 0x8c, 0xe2, 0xc1, 0x4b, 0x7a, 0x2d, 0x79, 0x9f, 0x89, 0xed, 0x13, - 0xf0, 0x6e, 0x5d, 0x62, 0x20, 0x3d, 0xd1, 0x9b, 0x98, 0xc5, 0xb4, 0xd7, - 0xbb, 0xa4, 0xc8, 0x89, 0x3e, 0x43, 0xdd, 0xae, 0x8d, 0xbb, 0x9c, 0xa8, - 0xc8, 0x07, 0x82, 0x8e, 0x73, 0x52, 0x17, 0x3d, 0x03, 0x07, 0x4a, 0x3a, - 0xde, 0xcf, 0xcf, 0xfd, 0x25, 0x1d, 0x6f, 0xa1, 0x3c, 0xfa, 0x1f, 0xb6, - 0x5d, 0xc4, 0x63, 0x34, 0x54, 0x9a, 0xc2, 0x6f, 0x88, 0xc3, 0xc4, 0x93, - 0x24, 0x75, 0xfc, 0x42, 0x7e, 0xbd, 0xe0, 0x36, 0xa7, 0xbb, 0xdd, 0xc5, - 0xef, 0xa4, 0x7a, 0x80, 0x76, 0x20, 0x7a, 0x78, 0xad, 0x94, 0xdb, 0x38, - 0xce, 0x90, 0x21, 0x3a, 0x2e, 0xe7, 0x65, 0xa2, 0xeb, 0x36, 0xc9, 0xb1, - 0xfa, 0x81, 0xdf, 0xb0, 0xac, 0x87, 0xb8, 0x6b, 0xe2, 0x6b, 0xdd, 0x62, - 0x3b, 0xb3, 0xdc, 0x58, 0x79, 0xd5, 0x42, 0xc7, 0xf9, 0x4a, 0x5c, 0xc3, - 0x7b, 0x7a, 0x6b, 0xa2, 0x5d, 0x8d, 0xb0, 0xaf, 0x49, 0xd8, 0x93, 0x1d, - 0x9c, 0xbb, 0x2b, 0x90, 0x0c, 0x89, 0xad, 0x61, 0x43, 0x45, 0x11, 0xc3, - 0x71, 0xca, 0xd6, 0x63, 0xdb, 0x38, 0x67, 0xfb, 0x42, 0x5d, 0xe4, 0x71, - 0x6a, 0x27, 0xd3, 0x7f, 0xf2, 0x27, 0xdd, 0x7a, 0x04, 0xef, 0x38, 0xb9, - 0x90, 0xc3, 0x38, 0x29, 0xb9, 0xd1, 0x7c, 0x1c, 0x0e, 0x7a, 0xf0, 0x62, - 0xac, 0x11, 0xc9, 0x7a, 0x05, 0x35, 0xfa, 0x9b, 0xce, 0x77, 0x42, 0xd2, - 0x0e, 0x73, 0x3c, 0xf5, 0x56, 0x8f, 0xe4, 0x80, 0x5e, 0x5d, 0xe4, 0x76, - 0x31, 0xc7, 0xbd, 0xb4, 0xfd, 0x7f, 0x75, 0x8e, 0x87, 0xa4, 0xfd, 0x48, - 0x50, 0x53, 0x7f, 0xd7, 0x1c, 0x7e, 0xdf, 0xf9, 0x81, 0x2b, 0x33, 0xe3, - 0xea, 0x01, 0xaa, 0xc8, 0x23, 0x54, 0x54, 0x8b, 0xcc, 0x72, 0x3b, 0xe2, - 0x67, 0x73, 0x79, 0x4f, 0x9e, 0x89, 0x8d, 0x6c, 0x61, 0xbb, 0xcf, 0x39, - 0x68, 0x94, 0xef, 0xd3, 0x1e, 0x29, 0x6b, 0x4d, 0x1e, 0x5a, 0xe1, 0xc5, - 0x52, 0xb4, 0xc4, 0x97, 0x2d, 0x97, 0xb1, 0xa8, 0x66, 0x52, 0xf3, 0xc3, - 0x6a, 0xf4, 0x10, 0x8b, 0xdf, 0x68, 0x6b, 0xc3, 0x72, 0xe6, 0x8c, 0xef, - 0x10, 0x5c, 0x7a, 0x75, 0x0f, 0xa6, 0x38, 0xbe, 0x27, 0x0d, 0x59, 0x2f, - 0x70, 0x70, 0x4b, 0xdc, 0x4a, 0xd1, 0x63, 0xad, 0x59, 0xb4, 0x9d, 0x6a, - 0x5d, 0xe2, 0x7c, 0x2d, 0x6a, 0x4c, 0x6f, 0xec, 0x1d, 0x44, 0x8c, 0x1d, - 0xe4, 0x39, 0x5a, 0x7d, 0x4b, 0xc2, 0x47, 0xed, 0xbe, 0x6c, 0x47, 0x13, - 0x47, 0x94, 0xa2, 0x3f, 0xbc, 0xc0, 0xb9, 0x7d, 0xcd, 0xd6, 0x37, 0x56, - 0x7a, 0x8a, 0xdf, 0x5f, 0x71, 0xf3, 0xd1, 0xb2, 0x3f, 0x84, 0x4b, 0xb8, - 0xe1, 0xf7, 0x9f, 0xb2, 0x71, 0x86, 0x54, 0x88, 0x79, 0x29, 0xce, 0xf4, - 0x19, 0x53, 0x8a, 0x4f, 0xaf, 0x25, 0xae, 0x0a, 0x96, 0x56, 0x90, 0x13, - 0x4a, 0xec, 0xf7, 0xfb, 0xdf, 0x61, 0x19, 0x72, 0xba, 0xe3, 0xb1, 0xeb, - 0x5b, 0x13, 0x7e, 0x24, 0xad, 0x4a, 0xfa, 0xe5, 0x2c, 0x33, 0xe4, 0xbf, - 0xaa, 0x60, 0x35, 0x06, 0x68, 0xd7, 0x35, 0xcc, 0x57, 0x5b, 0xd2, 0x13, - 0x8c, 0xe1, 0x6d, 0x78, 0x70, 0x82, 0x23, 0x6b, 0x18, 0x6c, 0x54, 0x4d, - 0x59, 0x83, 0x08, 0xc2, 0xd7, 0xf0, 0xe0, 0x0d, 0xaa, 0x79, 0x1c, 0x3d, - 0x1d, 0xfe, 0xce, 0x44, 0x01, 0xfe, 0x7a, 0x73, 0x13, 0xe2, 0x69, 0xc9, - 0x3b, 0x05, 0x23, 0x93, 0x5b, 0x89, 0x5a, 0x8d, 0x75, 0xd7, 0x96, 0xf5, - 0x0d, 0xb5, 0xd6, 0x94, 0xfc, 0x53, 0xeb, 0x7c, 0xc5, 0xc5, 0xd2, 0x20, - 0xf3, 0x85, 0x1f, 0x87, 0xff, 0xcf, 0xea, 0x27, 0x38, 0x27, 0xd2, 0x17, - 0xf9, 0x2f, 0x79, 0x3f, 0xbc, 0x2a, 0xb1, 0xb0, 0x77, 0xdc, 0xcb, 0xfc, - 0x4a, 0xe6, 0x4c, 0xe2, 0xf1, 0x6b, 0xff, 0xf5, 0x79, 0xfa, 0x8b, 0x8f, - 0xba, 0x7f, 0x44, 0xb7, 0x08, 0xf3, 0x8e, 0xa3, 0xc7, 0x23, 0xe1, 0x0a, - 0x45, 0xc3, 0xf6, 0xb6, 0x7f, 0xa7, 0x8d, 0x80, 0x38, 0x06, 0x12, 0xeb, - 0x5a, 0x6c, 0x19, 0xaf, 0x98, 0x51, 0xaf, 0x67, 0x4d, 0xb9, 0xde, 0x80, - 0x6e, 0xa5, 0xa4, 0xde, 0x68, 0x3c, 0xd2, 0xb3, 0x8d, 0xf5, 0x1e, 0x65, - 0xbd, 0x24, 0x63, 0xe7, 0x3d, 0x13, 0x41, 0x37, 0x9f, 0xb3, 0xc6, 0xab, - 0x67, 0xb6, 0x77, 0xbe, 0xde, 0xe3, 0xba, 0x35, 0xe5, 0xb6, 0xb7, 0x38, - 0xb2, 0xb1, 0xc2, 0xe3, 0x45, 0x9a, 0xf5, 0xa6, 0x58, 0xef, 0xf5, 0x09, - 0x59, 0x8f, 0xc0, 0x0d, 0xe3, 0x76, 0xe6, 0xb8, 0x47, 0xd7, 0x83, 0x27, - 0x91, 0x24, 0xe6, 0xba, 0x73, 0x79, 0xc3, 0x58, 0x7e, 0x33, 0xb6, 0xeb, - 0x87, 0xe2, 0x95, 0xac, 0x77, 0x44, 0x3f, 0x14, 0xf6, 0xd1, 0xaf, 0xd6, - 0x51, 0x5e, 0x2f, 0xf3, 0x1a, 0x95, 0xfe, 0xb2, 0x65, 0x5c, 0x62, 0xbf, - 0x41, 0x5e, 0x12, 0xa2, 0xcd, 0xc9, 0x98, 0xa5, 0x5d, 0x99, 0x53, 0x19, - 0x5f, 0x24, 0x36, 0xee, 0x8e, 0x4f, 0x99, 0x7b, 0x40, 0x72, 0xdd, 0x7a, - 0x0b, 0x7d, 0x6d, 0x12, 0xff, 0x14, 0x62, 0x6f, 0x03, 0xf3, 0x4f, 0x69, - 0x23, 0x84, 0x6d, 0xf4, 0xed, 0xfd, 0x86, 0xe3, 0x3c, 0x6f, 0xcc, 0xc7, - 0x01, 0x23, 0x92, 0x12, 0x3b, 0x7c, 0xd3, 0x58, 0x76, 0xa5, 0xe4, 0x96, - 0xc0, 0x9f, 0x60, 0x8a, 0xb6, 0x51, 0xa5, 0x8b, 0xbf, 0x29, 0x08, 0x47, - 0xbd, 0x5a, 0x8d, 0xe2, 0xc0, 0xbf, 0x78, 0xe1, 0xc6, 0x85, 0x1c, 0x7b, - 0xed, 0xf5, 0x0a, 0xde, 0xbf, 0x4a, 0xc1, 0xa1, 0xab, 0xa2, 0xe1, 0x11, - 0x65, 0x16, 0xb1, 0x35, 0xda, 0xdd, 0xa9, 0x58, 0x47, 0x59, 0x37, 0xd9, - 0xe6, 0x89, 0x84, 0xa1, 0xd4, 0xd1, 0xef, 0x5b, 0x34, 0x09, 0xfd, 0xde, - 0x81, 0x68, 0xf8, 0x51, 0xfe, 0xf7, 0x4c, 0x28, 0x98, 0xd0, 0x23, 0x49, - 0xb8, 0xf2, 0xd9, 0x36, 0xd3, 0xce, 0xab, 0xa3, 0x8e, 0x73, 0x2c, 0xde, - 0x1a, 0x3c, 0x86, 0x37, 0x89, 0x6d, 0xd2, 0x4e, 0x19, 0xeb, 0xc1, 0x5c, - 0x56, 0x4f, 0x76, 0x2a, 0x8e, 0x57, 0xf8, 0xc3, 0xfa, 0xbc, 0xc4, 0xc3, - 0x72, 0x7f, 0xcb, 0x71, 0xd1, 0x71, 0xde, 0x34, 0x8a, 0xb2, 0x82, 0x1d, - 0x91, 0x14, 0x30, 0x1f, 0x93, 0x7a, 0xa4, 0x6b, 0x8a, 0x3a, 0x08, 0xd3, - 0xdf, 0xe6, 0xe9, 0x8d, 0x38, 0xee, 0x8b, 0x04, 0x8f, 0x2b, 0xcb, 0xcf, - 0xaa, 0x58, 0xb4, 0xfe, 0x09, 0xa5, 0x75, 0x43, 0x15, 0xf4, 0x64, 0x41, - 0x99, 0x2b, 0x3a, 0x09, 0x07, 0xc8, 0xa5, 0xd6, 0xc1, 0x8d, 0xd1, 0xb8, - 0xcd, 0xf6, 0x26, 0xa7, 0xd1, 0x4c, 0xdb, 0xd7, 0x7b, 0xee, 0x23, 0x0f, - 0x04, 0x3e, 0xce, 0x24, 0x41, 0xfa, 0xda, 0x88, 0xd4, 0xa7, 0x1c, 0xe7, - 0x7e, 0xf6, 0x75, 0x07, 0xfb, 0xfa, 0x60, 0xfc, 0x3d, 0xe7, 0x5f, 0x5d, - 0x99, 0x37, 0x62, 0x44, 0xbf, 0x54, 0xee, 0xbb, 0xcc, 0xf5, 0x45, 0xae, - 0x0f, 0x37, 0xcf, 0x61, 0xbe, 0xd2, 0x21, 0xb8, 0x71, 0xd2, 0x4b, 0xdc, - 0xa0, 0x3c, 0xc6, 0x10, 0xf5, 0xd2, 0x38, 0xec, 0x01, 0xe3, 0x5b, 0x38, - 0xa5, 0xa8, 0x24, 0x42, 0x41, 0xf8, 0x75, 0x07, 0x0f, 0x90, 0x33, 0x24, - 0xe7, 0xd4, 0xe1, 0x73, 0x86, 0x1f, 0xb3, 0xa2, 0xea, 0x65, 0x1e, 0xce, - 0xc9, 0x81, 0xb8, 0x7c, 0xf7, 0x61, 0x6a, 0x8e, 0x07, 0x9b, 0xc9, 0x25, - 0x82, 0x51, 0x75, 0x9e, 0xdc, 0xf7, 0xb7, 0xcb, 0x77, 0xf6, 0x7f, 0xae, - 0x82, 0xfb, 0x69, 0x15, 0x6a, 0xb4, 0x37, 0x2c, 0xf7, 0xbb, 0x0c, 0xf9, - 0xae, 0xa0, 0x39, 0xee, 0xe5, 0xbc, 0x38, 0xf0, 0x48, 0x7a, 0x1f, 0xe5, - 0xfd, 0xb8, 0x7c, 0x4e, 0xde, 0xcf, 0x71, 0x27, 0xf7, 0x29, 0x82, 0x33, - 0x3f, 0x72, 0x5e, 0x64, 0x1c, 0x09, 0xf2, 0xf9, 0xe7, 0xd8, 0xf6, 0xd1, - 0xf8, 0xf3, 0xce, 0x3c, 0xe2, 0xeb, 0xb1, 0x84, 0x86, 0xf9, 0x57, 0x35, - 0xe1, 0xf8, 0x9d, 0x32, 0x66, 0x05, 0xb3, 0xf4, 0x2f, 0xf8, 0x24, 0xcf, - 0xac, 0xd5, 0xe7, 0xe2, 0xe6, 0x3b, 0x8a, 0xf7, 0xaa, 0xa2, 0xb2, 0x4e, - 0xa8, 0xa1, 0xea, 0xaa, 0x06, 0x68, 0xa5, 0x7b, 0xcb, 0xa3, 0xde, 0xee, - 0x59, 0x8a, 0x1e, 0xbc, 0x4d, 0x91, 0xe7, 0xbf, 0x24, 0xb7, 0x75, 0x9c, - 0x07, 0x38, 0x5f, 0x2d, 0xf1, 0x00, 0x4e, 0xb3, 0x9d, 0x5e, 0xea, 0x6f, - 0xe5, 0xf9, 0xf9, 0x2a, 0xd7, 0xff, 0xb9, 0xa3, 0x7d, 0x4a, 0xea, 0x8a, - 0x8c, 0x85, 0x5d, 0x37, 0x2b, 0x1c, 0x50, 0xb5, 0xe8, 0xd9, 0xd5, 0x19, - 0xcb, 0xf6, 0xba, 0xdf, 0x83, 0x1d, 0xaf, 0x9d, 0x5f, 0xf3, 0x3a, 0xe3, - 0xc6, 0xa3, 0x65, 0xd7, 0x07, 0x71, 0xdc, 0xa9, 0x6f, 0xb7, 0x82, 0x95, - 0x90, 0xb8, 0xd4, 0x1c, 0xfb, 0x0a, 0xe5, 0xfe, 0xc0, 0x28, 0xc6, 0xac, - 0xfd, 0x46, 0x24, 0x6b, 0xd1, 0x1f, 0x52, 0xcc, 0x13, 0x3b, 0x25, 0x76, - 0x4f, 0xd6, 0xfa, 0x50, 0x3b, 0x1f, 0x95, 0xed, 0x91, 0xfe, 0x05, 0xcc, - 0x9b, 0x3c, 0x1d, 0x12, 0xeb, 0x64, 0x7e, 0xdc, 0x32, 0x6c, 0xab, 0x0a, - 0xcb, 0xd9, 0xc7, 0x78, 0xfb, 0xef, 0x8b, 0x13, 0x22, 0x47, 0xac, 0x33, - 0xd2, 0x9f, 0xc4, 0xef, 0x2b, 0x0b, 0x46, 0x65, 0x59, 0x4f, 0xf2, 0xdf, - 0x90, 0xca, 0xab, 0xe4, 0x19, 0x15, 0xc1, 0xde, 0x8e, 0x46, 0x5e, 0xf2, - 0xdc, 0x7b, 0xc3, 0xda, 0xfc, 0xf9, 0x75, 0x3c, 0x64, 0x8d, 0x0a, 0xa8, - 0x57, 0x0b, 0x66, 0x13, 0x7d, 0x83, 0x32, 0x3e, 0x8b, 0x56, 0x2e, 0x39, - 0x7a, 0xe7, 0x5d, 0x77, 0xd3, 0x9f, 0x9f, 0x63, 0x8b, 0xa3, 0xe4, 0x33, - 0x96, 0xeb, 0x19, 0xe2, 0xeb, 0x33, 0xd7, 0xf5, 0x24, 0x86, 0x94, 0xd7, - 0x06, 0x1b, 0x30, 0xb8, 0xfb, 0x0e, 0x68, 0x8d, 0x45, 0x1c, 0x52, 0xcd, - 0xc5, 0x58, 0x96, 0x7d, 0xdb, 0x57, 0xe4, 0xe0, 0xb5, 0x18, 0xd8, 0x1d, - 0x47, 0x6e, 0x8e, 0x3c, 0x93, 0x7b, 0x7e, 0x08, 0x4e, 0x6e, 0xdf, 0x7d, - 0x99, 0xe4, 0xd4, 0x61, 0x91, 0x9b, 0xa2, 0xef, 0xa8, 0xfa, 0xdb, 0x8e, - 0x15, 0x14, 0xf9, 0x87, 0xae, 0xf4, 0x52, 0x87, 0x37, 0xa1, 0xb5, 0x67, - 0x0c, 0xa7, 0xc8, 0xeb, 0xdc, 0x35, 0x54, 0xad, 0xd2, 0x9c, 0xba, 0xdf, - 0x87, 0x68, 0x6a, 0x9c, 0x38, 0x10, 0x98, 0xf0, 0x93, 0x9f, 0xcc, 0x77, - 0xd7, 0x8e, 0x96, 0x91, 0x7f, 0xa4, 0xc8, 0x6d, 0x3f, 0xee, 0xf5, 0xe2, - 0x6e, 0x62, 0xc6, 0x7e, 0xbd, 0x75, 0xc3, 0x18, 0x7e, 0x45, 0xac, 0x93, - 0xf2, 0x3f, 0x60, 0x7b, 0x22, 0xd3, 0xcb, 0xf6, 0xe0, 0xf7, 0x12, 0x8f, - 0xc9, 0x09, 0xbd, 0x3e, 0x3d, 0xed, 0x93, 0xf8, 0x2d, 0xdc, 0x75, 0xc7, - 0x6e, 0x05, 0x9d, 0x94, 0xf3, 0x28, 0x6d, 0xe6, 0xfe, 0x28, 0xbc, 0x5d, - 0x57, 0x91, 0xa3, 0x90, 0xf3, 0x61, 0x4e, 0x00, 0x8f, 0x8c, 0x23, 0x91, - 0xd7, 0xa7, 0xe6, 0x05, 0xf0, 0x26, 0xe5, 0x08, 0xae, 0x57, 0x94, 0xe4, - 0xf4, 0xac, 0xb9, 0x58, 0x4e, 0x2d, 0x1e, 0x2f, 0xc9, 0xd9, 0x43, 0x39, - 0xd7, 0xb4, 0xc0, 0x5b, 0x7b, 0x8d, 0xcc, 0x55, 0x1b, 0xfd, 0xa7, 0x16, - 0x19, 0x17, 0xdb, 0xc9, 0xe9, 0x3e, 0x06, 0x45, 0x5f, 0x28, 0xfc, 0xff, - 0x1b, 0x6e, 0xbd, 0x9b, 0xda, 0xa6, 0xa6, 0xeb, 0x09, 0x9e, 0x67, 0x5a, - 0xa6, 0xe8, 0xa8, 0x65, 0xdd, 0x34, 0x62, 0xeb, 0xee, 0xea, 0x72, 0x7f, - 0xd9, 0x4e, 0xb9, 0x8d, 0x06, 0xde, 0x0b, 0xe1, 0x11, 0xe6, 0x71, 0x37, - 0xb1, 0x9d, 0x03, 0x86, 0x70, 0xb1, 0x56, 0xa3, 0x4a, 0x91, 0xbc, 0x36, - 0xcc, 0xb8, 0xde, 0x80, 0x3e, 0x37, 0x16, 0x84, 0x59, 0x7f, 0x77, 0x5d, - 0x91, 0x4f, 0xc0, 0x77, 0x2b, 0xcb, 0x76, 0xc6, 0x8b, 0xed, 0xf9, 0x74, - 0xc9, 0x15, 0xdb, 0xb1, 0x7f, 0xf8, 0xfc, 0xf3, 0xc8, 0x4d, 0xfa, 0xcc, - 0xf9, 0x9a, 0x8a, 0x10, 0x4b, 0x2b, 0x50, 0x5d, 0x21, 0x58, 0x7f, 0xd1, - 0xd8, 0xb7, 0x8c, 0xff, 0x29, 0xef, 0x57, 0x63, 0xeb, 0xb8, 0x83, 0x2d, - 0x6e, 0x9e, 0x50, 0x81, 0xde, 0x36, 0xc1, 0x43, 0xb1, 0xa5, 0x39, 0x92, - 0x27, 0x25, 0x72, 0x90, 0x18, 0x27, 0xf6, 0xb3, 0xc6, 0xb5, 0x1f, 0x8f, - 0x32, 0xd3, 0x7e, 0x36, 0xe3, 0xbb, 0xfa, 0xa1, 0x3b, 0x2a, 0x71, 0xe8, - 0x2e, 0x59, 0xff, 0xde, 0x10, 0xc7, 0xe1, 0x5b, 0xe8, 0x9b, 0xaf, 0x13, - 0x5b, 0xb6, 0xb4, 0x30, 0x86, 0xb8, 0x98, 0xa5, 0xa0, 0x92, 0xb1, 0x7d, - 0xdb, 0x6e, 0xe6, 0xc0, 0x6a, 0x90, 0x6d, 0x5e, 0x8a, 0x5d, 0xd2, 0x7f, - 0x83, 0xb9, 0xee, 0xa1, 0x2f, 0x56, 0x22, 0x20, 0x39, 0xc7, 0x4f, 0x4e, - 0x51, 0xc6, 0x4d, 0x46, 0x59, 0x57, 0xa2, 0xa7, 0xb2, 0x9c, 0x06, 0xa4, - 0x77, 0x97, 0xeb, 0x2b, 0x78, 0x29, 0x1a, 0x2e, 0xad, 0x3f, 0x37, 0x60, - 0x60, 0xfc, 0xd0, 0x31, 0x72, 0x0d, 0x27, 0xd1, 0x72, 0x68, 0x63, 0x98, - 0x7d, 0x39, 0x13, 0x2f, 0xcf, 0xa9, 0xf8, 0xe6, 0x4c, 0x19, 0x62, 0xbb, - 0x50, 0x6a, 0x17, 0x62, 0x4b, 0x2d, 0x6d, 0x34, 0x1f, 0x45, 0xaa, 0xc6, - 0xac, 0x85, 0x3d, 0x4e, 0xdf, 0x9a, 0xa8, 0x80, 0xf7, 0x5a, 0x89, 0x7d, - 0xc2, 0x77, 0xbc, 0x37, 0x9c, 0xb0, 0x2b, 0xf0, 0x69, 0xe3, 0x9c, 0x23, - 0xb8, 0x78, 0x4c, 0xc7, 0xe5, 0x15, 0xc4, 0xc4, 0x85, 0xf1, 0x68, 0x72, - 0x1d, 0xf3, 0xc2, 0x23, 0x6d, 0xde, 0x1b, 0xde, 0xca, 0xff, 0x9a, 0xdc, - 0xf2, 0xd2, 0xf1, 0x88, 0x3e, 0x70, 0x74, 0x45, 0x54, 0xda, 0x94, 0xf6, - 0xca, 0x36, 0x2a, 0xed, 0x3b, 0x4e, 0x34, 0x1e, 0x70, 0xe7, 0xbc, 0x3c, - 0x86, 0x37, 0xf4, 0xf2, 0x18, 0x02, 0x8c, 0xa7, 0x49, 0x72, 0x57, 0xe1, - 0xd5, 0x7e, 0xe6, 0x91, 0x5e, 0xf2, 0xf1, 0x6e, 0x08, 0xdf, 0x3b, 0x4a, - 0x7e, 0xf2, 0xa4, 0x0d, 0xbc, 0x93, 0x75, 0xb0, 0x2c, 0x3e, 0x8b, 0xf8, - 0xd2, 0x4f, 0xd9, 0xb2, 0xa6, 0x76, 0x50, 0x19, 0x67, 0xae, 0x79, 0xdc, - 0x5b, 0x95, 0x54, 0x99, 0x5b, 0x1e, 0xc8, 0x47, 0xc3, 0x87, 0x98, 0x67, - 0xfa, 0x99, 0xeb, 0x72, 0x06, 0x94, 0x27, 0x99, 0x67, 0xee, 0x2b, 0xe5, - 0x99, 0x07, 0xf2, 0x01, 0xe4, 0xb3, 0xc4, 0xc6, 0x38, 0xf3, 0x5b, 0x37, - 0x4f, 0x0f, 0x60, 0x32, 0xab, 0x32, 0x1f, 0x7f, 0xdf, 0x99, 0xaa, 0x77, - 0xf7, 0x0b, 0xf0, 0x75, 0xbb, 0x01, 0x07, 0x87, 0x9b, 0x70, 0x36, 0x3f, - 0x45, 0xbb, 0xb8, 0x0c, 0xd3, 0xa3, 0xb5, 0x98, 0x18, 0x7e, 0x95, 0x9f, - 0xdb, 0xf0, 0xfe, 0xa8, 0x9b, 0xe3, 0x12, 0x0f, 0xa5, 0x7f, 0x07, 0x95, - 0x43, 0x6e, 0x8e, 0x6b, 0x25, 0x99, 0xdb, 0x26, 0xfa, 0x4b, 0xb9, 0xed, - 0x14, 0x73, 0xdb, 0x23, 0x6c, 0xf3, 0x85, 0x52, 0x9b, 0xcf, 0xb9, 0xff, - 0xa5, 0x2f, 0x52, 0x77, 0x66, 0xbd, 0x44, 0x52, 0xd6, 0xa6, 0xc7, 0xed, - 0x68, 0xac, 0x5c, 0xf7, 0x05, 0xd6, 0x3b, 0x72, 0xbe, 0xde, 0x6a, 0x0c, - 0x64, 0xd6, 0x90, 0xe7, 0xcb, 0xda, 0xca, 0x7b, 0x6b, 0x6c, 0xea, 0xf2, - 0xcb, 0xd1, 0xa9, 0xee, 0x59, 0xa8, 0xc3, 0xfa, 0xb8, 0x70, 0xa2, 0xb7, - 0xc8, 0x89, 0x22, 0x89, 0x95, 0x8c, 0x0f, 0x9e, 0x68, 0x84, 0x58, 0x0f, - 0x44, 0x27, 0x98, 0x03, 0xe4, 0xeb, 0x70, 0x37, 0x73, 0x31, 0xb5, 0x7e, - 0x75, 0x69, 0x0f, 0xab, 0x94, 0xe3, 0x78, 0xd6, 0xa0, 0x6f, 0x52, 0xe4, - 0xad, 0x26, 0xbf, 0xae, 0xc1, 0x2d, 0xc5, 0x75, 0x0b, 0xbf, 0x9f, 0xb2, - 0xfd, 0xd1, 0xa9, 0x18, 0x5d, 0xc6, 0x38, 0xc0, 0x1b, 0xcf, 0xd9, 0x0a, - 0x96, 0xe9, 0x3e, 0xac, 0x0b, 0xd6, 0x61, 0x99, 0xf1, 0xef, 0xce, 0x2d, - 0xab, 0xe5, 0xd9, 0x79, 0x1e, 0xe1, 0xaf, 0x64, 0xbb, 0x6f, 0x92, 0x53, - 0x8f, 0xf3, 0xcb, 0x54, 0xbe, 0x78, 0xdf, 0xca, 0x53, 0x36, 0xe5, 0x6e, - 0xa3, 0xdc, 0x7b, 0x83, 0x6e, 0xbe, 0x5b, 0x2a, 0x37, 0x15, 0xf3, 0x10, - 0xd7, 0xa5, 0x6c, 0x27, 0xe5, 0xde, 0x4d, 0xb9, 0xfd, 0x41, 0xe9, 0xdf, - 0xbf, 0x3b, 0xf7, 0xae, 0x96, 0x67, 0xe5, 0x7d, 0x13, 0x29, 0xff, 0x9e, - 0xc8, 0x35, 0xc6, 0x4b, 0x6d, 0x1d, 0xb2, 0x91, 0x95, 0xdc, 0x6f, 0x6d, - 0x47, 0x54, 0xeb, 0x75, 0xd7, 0xb2, 0x35, 0xac, 0xcb, 0x6b, 0xb8, 0x87, - 0xba, 0xcb, 0x79, 0xcb, 0x63, 0x72, 0xfb, 0x64, 0x09, 0x77, 0x5e, 0xce, - 0x72, 0x7d, 0x25, 0xdc, 0xee, 0xcc, 0x8b, 0x0d, 0xcd, 0xdc, 0x4f, 0x6a, - 0x2a, 0xf9, 0xb3, 0x17, 0x4f, 0xdb, 0x1f, 0x9c, 0x1b, 0xcc, 0x48, 0x3c, - 0x93, 0xf5, 0x10, 0x0d, 0xd9, 0xfc, 0xe5, 0x68, 0x1e, 0x0a, 0x62, 0xad, - 0x31, 0x9b, 0xbe, 0xfe, 0xa5, 0xf3, 0x36, 0x75, 0x80, 0xed, 0xc0, 0xe7, - 0x8a, 0x57, 0x9e, 0xce, 0xb7, 0x06, 0x1b, 0x70, 0xe9, 0x1e, 0xd2, 0xfc, - 0x64, 0x8d, 0x19, 0xed, 0xfe, 0x0e, 0xe7, 0xae, 0xca, 0xe5, 0xd0, 0x5b, - 0x94, 0x1c, 0xe7, 0xef, 0xa9, 0xd2, 0xfc, 0x3d, 0x99, 0xbf, 0xae, 0xb2, - 0x88, 0x45, 0x97, 0xa3, 0x65, 0x48, 0xfe, 0x07, 0xf1, 0x46, 0xc7, 0xc7, - 0x79, 0xef, 0x72, 0x2c, 0x1c, 0xf9, 0x54, 0x25, 0xb9, 0xb5, 0x51, 0xcc, - 0xc1, 0x2f, 0xcd, 0x33, 0x22, 0xfd, 0x16, 0x16, 0xb0, 0x5c, 0x13, 0x75, - 0x26, 0x18, 0x28, 0xfd, 0x7a, 0xe4, 0x7c, 0xbf, 0xbe, 0xcc, 0x7e, 0xa5, - 0x7c, 0xb2, 0xd6, 0x2a, 0xfd, 0x52, 0x92, 0xb5, 0x66, 0x13, 0xde, 0x1f, - 0x40, 0x30, 0x68, 0x46, 0x53, 0x2f, 0xd3, 0xde, 0x27, 0xd8, 0xd7, 0x7a, - 0xf4, 0x2b, 0x79, 0x77, 0xaf, 0xea, 0x20, 0xcb, 0xcc, 0x8c, 0xa3, 0xd2, - 0x4f, 0xaf, 0xe4, 0x59, 0x3e, 0xd9, 0x67, 0xf2, 0xe9, 0x22, 0xff, 0x6d, - 0x72, 0xc5, 0x3e, 0xca, 0x4f, 0x72, 0xfe, 0xfc, 0x6c, 0x03, 0x56, 0xb5, - 0xd9, 0xed, 0x72, 0x55, 0x2f, 0xfd, 0x6e, 0x19, 0x6d, 0xea, 0xc9, 0x9c, - 0x82, 0x51, 0x2a, 0xfd, 0x68, 0x56, 0xd6, 0x89, 0xc3, 0x38, 0x90, 0xf3, - 0xe1, 0x85, 0xec, 0x3c, 0x8c, 0xe7, 0x2a, 0xf0, 0x5c, 0xf6, 0x32, 0xec, - 0xcb, 0x11, 0xfd, 0xb2, 0x97, 0x63, 0x24, 0xe7, 0xc7, 0x4f, 0xb2, 0xd4, - 0x53, 0xae, 0x0a, 0xff, 0x9c, 0xfd, 0x13, 0x7c, 0x3d, 0x57, 0x8d, 0xd7, - 0xb2, 0x57, 0xe0, 0x60, 0xae, 0x06, 0xaf, 0x64, 0xc9, 0x27, 0x73, 0x01, - 0xbc, 0x9c, 0xd5, 0x50, 0xc8, 0xcd, 0xc2, 0x4b, 0xd9, 0x08, 0x26, 0x72, - 0xb5, 0xf8, 0x6e, 0x76, 0x01, 0xf2, 0xb9, 0x3a, 0x7c, 0x27, 0xdb, 0x8c, - 0x2f, 0xe7, 0x82, 0x78, 0x31, 0xab, 0xe3, 0xa9, 0x5c, 0x3d, 0x8e, 0x65, - 0xa3, 0x6c, 0x37, 0x84, 0xa3, 0xc3, 0x31, 0x1c, 0x18, 0x6d, 0xc4, 0x0b, - 0xc3, 0x8b, 0x30, 0x3e, 0x1a, 0xc6, 0x73, 0xc3, 0x6d, 0xd8, 0x37, 0xfa, - 0x6f, 0x15, 0xa2, 0x9f, 0x23, 0xf6, 0xff, 0x38, 0xaf, 0xc7, 0x6d, 0x1f, - 0x31, 0xdf, 0xaf, 0xda, 0xa2, 0x37, 0xbf, 0x55, 0xcf, 0x39, 0x7a, 0x3a, - 0xef, 0xce, 0x3b, 0xf4, 0x21, 0x77, 0x7f, 0x06, 0x7d, 0xc6, 0x65, 0xcc, - 0xd9, 0xfa, 0x25, 0x7e, 0xd0, 0x16, 0x0e, 0x2a, 0xdb, 0x5d, 0x1c, 0xa9, - 0x4d, 0xce, 0xa2, 0x2e, 0x39, 0xec, 0x60, 0x0d, 0x7d, 0x32, 0x4b, 0x7f, - 0xb6, 0x38, 0xaf, 0x76, 0xfe, 0xa0, 0xb2, 0x83, 0x39, 0xe2, 0x95, 0x43, - 0x96, 0x53, 0xed, 0xe2, 0x69, 0x34, 0xb9, 0x88, 0x3e, 0x17, 0x1b, 0x11, - 0x7d, 0xde, 0x59, 0x21, 0xfa, 0xac, 0xd0, 0x3f, 0xcc, 0x4e, 0xca, 0x7a, - 0x0f, 0x94, 0xec, 0xe1, 0xfb, 0x95, 0xc5, 0xbc, 0xaa, 0x3c, 0xef, 0x8e, - 0x33, 0x68, 0x94, 0xe7, 0x9e, 0xfc, 0xaf, 0x41, 0xd6, 0xa4, 0xc0, 0x58, - 0x50, 0x8f, 0x5c, 0x48, 0xf2, 0xf5, 0x99, 0x98, 0x81, 0x64, 0xa5, 0x19, - 0xd5, 0x5a, 0xd4, 0x99, 0x7c, 0x45, 0xb0, 0x43, 0xe4, 0x5b, 0x2e, 0xee, - 0x1c, 0x3e, 0x8f, 0x1f, 0x67, 0x2b, 0x85, 0xa7, 0xec, 0xb7, 0xa5, 0x6f, - 0x50, 0x2b, 0xa4, 0xcf, 0x28, 0xde, 0x43, 0xa1, 0xac, 0xaf, 0x99, 0x76, - 0xa7, 0x52, 0xb7, 0x62, 0x7b, 0x5e, 0xfa, 0xc2, 0x72, 0x89, 0x7b, 0xec, - 0x47, 0x13, 0x5e, 0xb0, 0x8b, 0x7b, 0x33, 0xe3, 0x79, 0xd1, 0xb7, 0x86, - 0xad, 0xe4, 0x5e, 0x87, 0x87, 0x15, 0xea, 0xee, 0x2f, 0x51, 0xdc, 0x3f, - 0xf2, 0xd2, 0x57, 0xd7, 0xb2, 0x3c, 0x63, 0x7c, 0x61, 0xda, 0xdd, 0x1b, - 0xae, 0x73, 0xf3, 0xee, 0x30, 0x0a, 0x03, 0x1f, 0x9c, 0xdb, 0x96, 0xf9, - 0xe5, 0xb9, 0x3d, 0x99, 0x68, 0x4a, 0xf6, 0x67, 0xf2, 0x13, 0x3e, 0xe4, - 0xf6, 0x06, 0xf0, 0xd4, 0x84, 0x1f, 0x35, 0x69, 0xc9, 0xf3, 0x83, 0x78, - 0x6a, 0xff, 0xa1, 0x15, 0x35, 0x68, 0xe0, 0xff, 0x10, 0xaf, 0x46, 0x5e, - 0x01, 0x1c, 0x1b, 0xf5, 0xe3, 0x2d, 0x5b, 0x7c, 0x58, 0xfc, 0xa3, 0x8d, - 0xd8, 0x1f, 0x60, 0xbc, 0x55, 0x19, 0x47, 0x9a, 0x70, 0x38, 0x1f, 0xc4, - 0xf2, 0x6c, 0x3d, 0x9e, 0xcb, 0x25, 0xf1, 0x44, 0xa6, 0x1e, 0x67, 0x1f, - 0xf3, 0x63, 0xde, 0x3e, 0xf1, 0x87, 0x06, 0x9c, 0x1e, 0xfc, 0x04, 0x0a, - 0x7b, 0x93, 0xb0, 0x33, 0xb3, 0xb1, 0x63, 0xb0, 0x01, 0xdf, 0x61, 0x99, - 0x7e, 0xea, 0xa9, 0x7a, 0xa7, 0x89, 0x17, 0x69, 0x43, 0x55, 0x3b, 0x6f, - 0xa4, 0xec, 0x30, 0x7c, 0x03, 0x21, 0x1c, 0xc9, 0x7b, 0x85, 0xd7, 0x71, - 0x1e, 0x7f, 0x5a, 0x9c, 0x17, 0x08, 0x6f, 0xbd, 0x98, 0x07, 0x1e, 0x3f, - 0xcf, 0x03, 0x81, 0x5c, 0x5e, 0xd6, 0x18, 0xdb, 0x3a, 0xfb, 0xec, 0x89, - 0xff, 0xcf, 0x6f, 0xfe, 0xf4, 0xdb, 0x15, 0x4b, 0x0c, 0x62, 0x9d, 0x8c, - 0x7f, 0xed, 0x83, 0xd5, 0xe6, 0x86, 0x2f, 0xae, 0x58, 0x52, 0x89, 0xfb, - 0xdd, 0xf9, 0xea, 0x81, 0xbd, 0xbb, 0x9b, 0xf1, 0xb5, 0xb5, 0x67, 0x40, - 0xb9, 0x02, 0xa9, 0xfa, 0x21, 0xde, 0x53, 0x4b, 0x3e, 0x07, 0x55, 0x6c, - 0xad, 0x8e, 0xfa, 0x54, 0x0b, 0x1a, 0x4e, 0xd0, 0xc8, 0x6a, 0xd3, 0x11, - 0x4c, 0xd5, 0xcb, 0x38, 0x63, 0xcc, 0xb3, 0x3c, 0xb2, 0x77, 0x8d, 0x4f, - 0x33, 0xc6, 0x9d, 0x5d, 0xac, 0x20, 0xf1, 0x67, 0xe2, 0x83, 0xb7, 0x96, - 0xf6, 0x80, 0x65, 0x3f, 0x4c, 0xe6, 0xad, 0xac, 0xff, 0xbd, 0xb2, 0xee, - 0xc9, 0x3f, 0xc1, 0x0a, 0x2f, 0x0e, 0xdb, 0x39, 0xe6, 0x08, 0x32, 0x07, - 0x32, 0xa6, 0xed, 0xac, 0x27, 0xe3, 0x92, 0xe7, 0xad, 0x89, 0xfa, 0x8f, - 0x1c, 0x97, 0x8c, 0x67, 0xad, 0x1f, 0xd5, 0x32, 0x86, 0xb2, 0x2e, 0xfa, - 0x58, 0xf7, 0x51, 0xde, 0x93, 0x7a, 0x8e, 0xb3, 0xfd, 0xa2, 0x98, 0x55, - 0x91, 0xac, 0x66, 0xdf, 0x9f, 0xb4, 0xa3, 0xc9, 0x77, 0x88, 0x8b, 0xc7, - 0xa8, 0xc3, 0x51, 0x5b, 0xec, 0x6f, 0x0b, 0xed, 0xae, 0x5f, 0x39, 0x7a, - 0xde, 0xf6, 0x80, 0x83, 0xb6, 0xcc, 0xaf, 0xf0, 0x29, 0x19, 0xaf, 0x86, - 0xe9, 0x89, 0xa0, 0xcb, 0xc7, 0xdf, 0xb6, 0xc5, 0x26, 0x62, 0xcc, 0xcf, - 0xa6, 0xcf, 0xf5, 0x66, 0x0c, 0x1c, 0xe3, 0xdc, 0x9e, 0xb6, 0xab, 0x88, - 0x37, 0x1d, 0x90, 0xbd, 0xce, 0xf7, 0xed, 0x04, 0x5e, 0x22, 0x66, 0xbd, - 0x47, 0x5b, 0xfb, 0x2e, 0x31, 0xec, 0x5d, 0x5b, 0xc7, 0x77, 0x68, 0x7b, - 0xef, 0xd8, 0x31, 0xbc, 0x98, 0xaf, 0xc7, 0x51, 0xe2, 0xd0, 0x49, 0x7e, - 0x5e, 0x9e, 0xf7, 0xc1, 0x0a, 0xc9, 0xbe, 0xda, 0x1e, 0x3f, 0x6a, 0x7b, - 0xd9, 0xe7, 0x48, 0x97, 0x1c, 0x44, 0x79, 0x96, 0xe3, 0xd3, 0x94, 0x32, - 0x0f, 0x29, 0xe7, 0x04, 0x49, 0x64, 0x33, 0x33, 0xb1, 0x21, 0xd2, 0x9f, - 0xa3, 0xdd, 0xfa, 0xd2, 0xe5, 0x38, 0xc0, 0xd8, 0x59, 0x10, 0xdb, 0xf6, - 0xc0, 0x33, 0x24, 0xf6, 0x7f, 0x0d, 0x75, 0x3d, 0x7d, 0x4e, 0xf6, 0xd2, - 0x54, 0x7d, 0x8a, 0xfe, 0x5e, 0x85, 0xde, 0xdc, 0xe5, 0xa8, 0x19, 0x5a, - 0x8a, 0xfb, 0xe3, 0xe2, 0xf7, 0x7e, 0xf4, 0xe7, 0x3c, 0xa8, 0x1c, 0x22, - 0x77, 0x61, 0xd9, 0xa9, 0x50, 0x31, 0x1e, 0xa9, 0x69, 0xc3, 0xf5, 0x83, - 0x05, 0x85, 0x0f, 0xce, 0xd9, 0x99, 0x43, 0xf3, 0x54, 0x4c, 0x9f, 0x4b, - 0x67, 0x02, 0xe8, 0xa3, 0x4d, 0xab, 0x69, 0x05, 0x75, 0x7a, 0x88, 0xf9, - 0x5f, 0x1b, 0x7a, 0xa9, 0x8b, 0xf9, 0xe9, 0x26, 0x3c, 0x31, 0xd1, 0x88, - 0x79, 0xbb, 0x4c, 0x3c, 0x4e, 0xdb, 0x0f, 0xef, 0xba, 0x11, 0x7b, 0x58, - 0xee, 0x15, 0x3e, 0x7b, 0x65, 0x7f, 0x03, 0xaf, 0x10, 0xaf, 0x46, 0x5e, - 0xf5, 0x18, 0xd8, 0xab, 0x97, 0xce, 0x61, 0x78, 0xd0, 0x30, 0x24, 0xf8, - 0xa2, 0xe2, 0x8e, 0x76, 0x05, 0xc6, 0xd5, 0x6c, 0x73, 0xe1, 0x87, 0x61, - 0x4d, 0xc3, 0x1f, 0xd0, 0xef, 0x1f, 0x38, 0x53, 0xe7, 0xed, 0xc7, 0x0f, - 0x6f, 0xfa, 0xfb, 0xae, 0xfd, 0x2c, 0x28, 0x48, 0x3b, 0xef, 0x12, 0x33, - 0xc4, 0x86, 0x7e, 0x17, 0x9e, 0x95, 0xf5, 0xfe, 0xdb, 0x67, 0x2b, 0x70, - 0xde, 0xbe, 0x2e, 0x5a, 0x77, 0x47, 0x9e, 0x36, 0xb1, 0xc3, 0x3d, 0x3b, - 0x22, 0xb9, 0x4e, 0xa4, 0x2b, 0x47, 0xfd, 0xf4, 0x33, 0x87, 0xb9, 0x87, - 0x38, 0xb1, 0x3d, 0x13, 0xb1, 0x2c, 0xb6, 0xe5, 0x23, 0x36, 0x3c, 0x30, - 0xe8, 0x97, 0xf5, 0x6e, 0xcd, 0xa7, 0xcf, 0xc3, 0x3b, 0x39, 0xb1, 0xf9, - 0x2a, 0x1c, 0xce, 0x86, 0x71, 0xca, 0xfd, 0x5c, 0xcd, 0x58, 0xe3, 0xa0, - 0xd3, 0x98, 0x85, 0xbe, 0x60, 0x15, 0x06, 0x62, 0x37, 0x22, 0x77, 0x07, - 0x73, 0x6c, 0xfa, 0x58, 0xad, 0xee, 0x47, 0x3a, 0x28, 0xf9, 0x8b, 0x07, - 0x99, 0xd8, 0xed, 0x38, 0x5e, 0xef, 0xc5, 0x3c, 0x59, 0x6f, 0xe1, 0xb3, - 0x3d, 0x41, 0x28, 0xf4, 0xbd, 0xa4, 0x8f, 0xb8, 0x34, 0x6b, 0x00, 0x4e, - 0xad, 0xa9, 0xcb, 0x1e, 0x4c, 0xcf, 0x56, 0xe2, 0x52, 0xcd, 0x44, 0x0d, - 0xe3, 0x4e, 0x0b, 0xaa, 0xf7, 0xca, 0x5e, 0x40, 0x00, 0xeb, 0x86, 0xaf, - 0x95, 0xbd, 0x81, 0x98, 0xa6, 0x04, 0x70, 0xef, 0xb0, 0xc4, 0x8f, 0x35, - 0xa8, 0xd8, 0x5f, 0x8b, 0x2f, 0x66, 0xbd, 0xc4, 0x78, 0xe2, 0x0d, 0xcb, - 0xed, 0xc9, 0xd4, 0xa1, 0xee, 0xb1, 0x67, 0x9d, 0x30, 0x75, 0x5c, 0xb7, - 0x57, 0xb0, 0x88, 0xb6, 0x9b, 0xf9, 0x3c, 0x0a, 0x76, 0x33, 0xe5, 0xf6, - 0x70, 0x7c, 0x21, 0xbc, 0x4b, 0xec, 0xaa, 0x99, 0x08, 0xe3, 0x9d, 0xdd, - 0x92, 0xab, 0x24, 0xe1, 0x9d, 0xb8, 0x0c, 0x6f, 0xf2, 0xf3, 0x09, 0xa3, - 0x13, 0xea, 0x44, 0x13, 0x4e, 0x66, 0xba, 0xe0, 0x99, 0xa8, 0x2d, 0x62, - 0xd8, 0x5e, 0x3f, 0xea, 0x06, 0xf5, 0xd8, 0x34, 0xe7, 0xc8, 0xb7, 0x97, - 0x04, 0xa7, 0x51, 0xda, 0x3f, 0x6f, 0xdb, 0xc6, 0x85, 0x7d, 0x87, 0xf2, - 0xd9, 0x15, 0xb1, 0xef, 0xef, 0x3a, 0x4f, 0x04, 0xd9, 0xbf, 0x8e, 0x08, - 0xfa, 0x62, 0xc7, 0x64, 0x3f, 0x9f, 0xe3, 0x4b, 0x72, 0xee, 0x9f, 0x77, - 0xe4, 0x5c, 0x88, 0xcf, 0x94, 0x33, 0x19, 0xcf, 0x39, 0xdb, 0x57, 0xcb, - 0xfd, 0xdb, 0xab, 0x50, 0xcd, 0xc4, 0xc9, 0x14, 0x99, 0x3b, 0x64, 0x6e, - 0x19, 0x75, 0x3e, 0x4c, 0xe6, 0x3f, 0x3a, 0x8f, 0x9f, 0x2f, 0x8f, 0xa0, - 0xcf, 0x5d, 0x13, 0xbf, 0xe0, 0xcb, 0x35, 0x9c, 0xbb, 0xf5, 0x25, 0x5f, - 0x7e, 0xc7, 0x96, 0xf9, 0x93, 0xf3, 0x4b, 0x01, 0x72, 0x30, 0x03, 0xd5, - 0x9c, 0xbb, 0xf7, 0x6d, 0x28, 0xb7, 0x76, 0x74, 0x63, 0xd6, 0x44, 0x80, - 0xbe, 0x1e, 0x59, 0x6f, 0xc1, 0x66, 0x5b, 0x1d, 0xa8, 0x62, 0x9d, 0x93, - 0xb6, 0x87, 0x7e, 0x9e, 0xe0, 0x98, 0x83, 0x70, 0x5c, 0x5e, 0xbf, 0x1a, - 0xf3, 0xa9, 0xa7, 0xb3, 0xb6, 0x89, 0x79, 0xd4, 0xd3, 0xb4, 0xed, 0x25, - 0x4e, 0x34, 0x11, 0x0f, 0x34, 0xd4, 0x12, 0x1b, 0x2b, 0x06, 0x1d, 0x1c, - 0x32, 0xea, 0xc8, 0xf5, 0xc5, 0x4e, 0x3b, 0x10, 0x1e, 0x30, 0x30, 0x6f, - 0xa0, 0x79, 0xe3, 0x3c, 0x8f, 0x07, 0xc7, 0x7d, 0xc5, 0xd8, 0x93, 0x9b, - 0x23, 0xfa, 0x91, 0x31, 0xb9, 0xb9, 0xfc, 0x87, 0x60, 0xc0, 0x6a, 0x80, - 0xb2, 0x0a, 0xc4, 0x8c, 0xcf, 0xb1, 0xad, 0x37, 0xec, 0x57, 0x71, 0xf3, - 0x84, 0xe0, 0xcb, 0x0f, 0xb1, 0x92, 0xfd, 0x78, 0x97, 0xb8, 0x76, 0x5f, - 0xf4, 0x1b, 0x1c, 0x6b, 0x13, 0x6e, 0x99, 0x98, 0x3e, 0xd7, 0xe7, 0x8e, - 0xb3, 0x9c, 0xff, 0xf9, 0x71, 0x5f, 0xb6, 0x7c, 0x06, 0x2d, 0x49, 0x9f, - 0x91, 0x38, 0xe1, 0x87, 0xf8, 0x4d, 0xb7, 0xbd, 0x0d, 0xc5, 0x78, 0x2e, - 0x57, 0x59, 0x8f, 0x3b, 0xbd, 0x92, 0x97, 0x17, 0x7d, 0x43, 0xfa, 0xf3, - 0xbb, 0xca, 0x14, 0x7d, 0x43, 0xfc, 0xe2, 0xcb, 0xae, 0x7e, 0x85, 0x77, - 0x69, 0xb8, 0x6d, 0xe2, 0x97, 0xc4, 0xc7, 0x48, 0x32, 0x47, 0xcc, 0x7e, - 0x9d, 0xfa, 0xdd, 0x4e, 0xfd, 0x32, 0x07, 0x60, 0xbc, 0x4a, 0x50, 0x9f, - 0x3e, 0x72, 0x15, 0x2f, 0x31, 0xd3, 0xa4, 0x2e, 0x41, 0x0c, 0x64, 0xee, - 0x1e, 0x2c, 0x8e, 0x37, 0x77, 0x7e, 0xfe, 0xd8, 0x96, 0x92, 0xc0, 0x09, - 0xfb, 0x87, 0x55, 0x72, 0x26, 0xe8, 0xa4, 0xed, 0x3e, 0x97, 0x35, 0xcd, - 0x19, 0x65, 0x2e, 0xb4, 0xbd, 0xcf, 0x16, 0xfe, 0x5c, 0x49, 0xbb, 0xd6, - 0x28, 0xaf, 0xa6, 0x84, 0xa9, 0x52, 0x57, 0xf6, 0x60, 0xa5, 0xfd, 0x6e, - 0xe1, 0x20, 0x78, 0x83, 0x3e, 0x77, 0xc4, 0xa8, 0xc0, 0xa8, 0x3b, 0x17, - 0x62, 0x8f, 0xc5, 0x76, 0x2f, 0xd8, 0x4d, 0xba, 0xae, 0x74, 0x1e, 0xab, - 0xba, 0xc8, 0xc9, 0x2e, 0x6d, 0xa3, 0xe2, 0x3f, 0xb1, 0x8d, 0x44, 0xa9, - 0x8d, 0x8f, 0x3a, 0xe3, 0x06, 0x3c, 0x65, 0x4b, 0xec, 0x97, 0xfd, 0x0f, - 0x0d, 0x8b, 0x26, 0x04, 0x5f, 0xe8, 0xbb, 0x03, 0xd3, 0x2e, 0xf7, 0xcf, - 0x41, 0xf6, 0xb6, 0x42, 0xf0, 0x45, 0x35, 0x9c, 0xd2, 0x63, 0x58, 0x58, - 0x90, 0xfd, 0xa9, 0x7d, 0x75, 0xc2, 0xe1, 0xce, 0xe8, 0xc2, 0x3b, 0x64, - 0xbe, 0xca, 0xf7, 0xfc, 0xd8, 0xaf, 0x17, 0xfb, 0x9a, 0x54, 0x8b, 0xdc, - 0xd1, 0x43, 0xee, 0xd8, 0x6b, 0xf8, 0x69, 0x97, 0xad, 0xc1, 0xd9, 0xbf, - 0x73, 0x2f, 0xab, 0xdc, 0xdf, 0xdf, 0x57, 0xee, 0xc2, 0x7a, 0x5c, 0xf6, - 0xa2, 0xfd, 0x21, 0x19, 0xd3, 0x5c, 0xa0, 0x41, 0xe2, 0x55, 0x91, 0xa3, - 0x6e, 0x3d, 0x9f, 0xff, 0x58, 0xca, 0x60, 0xfe, 0x31, 0xd4, 0xeb, 0x0b, - 0x50, 0xdf, 0x50, 0xc3, 0xb8, 0x1c, 0xed, 0xa2, 0x7b, 0x4b, 0x2c, 0xb3, - 0x82, 0xa6, 0xe4, 0xbf, 0xc2, 0x5b, 0xa5, 0xcd, 0x7e, 0xa5, 0xaa, 0x20, - 0xed, 0x1e, 0x54, 0xfc, 0x85, 0x0f, 0x6b, 0x5b, 0xce, 0xfb, 0x4d, 0x9f, - 0x1b, 0xca, 0x74, 0xbb, 0x7b, 0x8c, 0xcb, 0x86, 0x1c, 0xdc, 0x69, 0x34, - 0xe1, 0xee, 0x06, 0x69, 0xa3, 0x98, 0xc3, 0x68, 0xea, 0x34, 0x39, 0xdc, - 0x6f, 0x1c, 0x55, 0x97, 0xcf, 0x3e, 0x78, 0x1e, 0xd3, 0xa7, 0xd7, 0x42, - 0xc5, 0xd9, 0xeb, 0x24, 0x9f, 0xf1, 0x91, 0x7f, 0x6d, 0xaa, 0x2e, 0xee, - 0x2f, 0x8b, 0x1d, 0x4b, 0x3f, 0xfc, 0xf4, 0xb3, 0x0b, 0xfd, 0xd8, 0xf6, - 0x07, 0xf5, 0xc3, 0x8f, 0x9b, 0x86, 0x92, 0x18, 0x35, 0x4e, 0x38, 0x56, - 0x68, 0x66, 0xdb, 0x3e, 0xac, 0x1c, 0xfa, 0x8d, 0x33, 0xcb, 0x6d, 0x5b, - 0x27, 0xa7, 0x52, 0xf1, 0xc0, 0x12, 0x1f, 0x6e, 0x1d, 0x89, 0x62, 0xc5, - 0x90, 0x8a, 0xd8, 0x12, 0xe9, 0x43, 0x14, 0x5d, 0x23, 0xbb, 0xbd, 0xc5, - 0xf2, 0xc0, 0x2d, 0x1c, 0xc3, 0x1b, 0x46, 0x0d, 0x7e, 0x40, 0x0c, 0xac, - 0x75, 0xb9, 0xfd, 0x46, 0x25, 0x23, 0xdc, 0xde, 0xa7, 0x62, 0xb6, 0x8e, - 0x60, 0x83, 0x99, 0xa4, 0xee, 0x3a, 0x95, 0xc7, 0x72, 0x1b, 0x95, 0xa1, - 0x7c, 0xb9, 0xef, 0x01, 0x7c, 0xa2, 0x10, 0xc4, 0x27, 0xc6, 0x1a, 0x78, - 0x85, 0x78, 0x35, 0xf2, 0x7a, 0xf1, 0xfc, 0xb8, 0xca, 0x67, 0x3c, 0x9f, - 0x65, 0x4e, 0xb1, 0xcd, 0xf5, 0x4b, 0x89, 0x0b, 0x9a, 0x9c, 0xd5, 0xc1, - 0x5b, 0x59, 0xc9, 0x27, 0xb6, 0xd1, 0x86, 0x65, 0x4d, 0xb8, 0x92, 0x39, - 0x45, 0x24, 0x36, 0x85, 0xbf, 0xaa, 0x2e, 0xce, 0x7d, 0xd1, 0x86, 0x71, - 0xde, 0x86, 0x7d, 0x78, 0x3b, 0xab, 0xa2, 0x25, 0xfe, 0x6f, 0xce, 0xf1, - 0xa0, 0xe0, 0xc9, 0xa5, 0xcf, 0xcb, 0x9c, 0x65, 0xfa, 0x5c, 0x36, 0xd3, - 0x34, 0x63, 0x5f, 0x56, 0x41, 0xc5, 0x90, 0xf0, 0xf3, 0xeb, 0x5c, 0xbe, - 0xf7, 0x7d, 0xc3, 0x07, 0xef, 0xd0, 0xa1, 0x2b, 0xe5, 0x68, 0x93, 0x6f, - 0x8c, 0x71, 0xab, 0x83, 0xf3, 0x32, 0xf2, 0xf1, 0x92, 0xce, 0xca, 0xba, - 0x50, 0xdc, 0x35, 0x49, 0xd5, 0x8d, 0xe9, 0x41, 0xa8, 0x63, 0xc2, 0x43, - 0xc9, 0x0d, 0xc6, 0x24, 0x1f, 0x08, 0xf1, 0xbf, 0xe4, 0x06, 0x8d, 0xfc, - 0xcf, 0xc4, 0xa2, 0x51, 0xe2, 0x78, 0x0f, 0xfa, 0x19, 0x9f, 0x2a, 0xa3, - 0x3d, 0xd8, 0x3e, 0xfe, 0x61, 0x31, 0xbf, 0x98, 0x63, 0x3d, 0x7b, 0xde, - 0xcf, 0xdc, 0x39, 0x62, 0x9f, 0xa6, 0xcf, 0x89, 0xcf, 0xc8, 0x5c, 0xed, - 0xcb, 0x4a, 0x1f, 0x1c, 0x6c, 0x30, 0x6e, 0x64, 0xdb, 0x3e, 0xa8, 0x0d, - 0x33, 0xb9, 0xe7, 0x79, 0x3e, 0x4d, 0xdd, 0x6d, 0x54, 0x46, 0x39, 0x27, - 0x96, 0xb7, 0x52, 0xd6, 0x87, 0x82, 0x15, 0x9c, 0x93, 0xaf, 0xe4, 0x45, - 0x46, 0xa7, 0x32, 0x9e, 0x9b, 0x59, 0x67, 0xa3, 0x32, 0x96, 0xff, 0x55, - 0xb5, 0xac, 0x99, 0x5f, 0xd0, 0x4d, 0xb9, 0x0f, 0x62, 0x63, 0x1a, 0xea, - 0xd3, 0xa2, 0x67, 0x19, 0xb3, 0x06, 0x2f, 0x79, 0x5c, 0x7d, 0xe1, 0x43, - 0xdb, 0x6c, 0xac, 0x72, 0xcf, 0x62, 0xc6, 0x18, 0x8b, 0x02, 0x56, 0x25, - 0x39, 0x1f, 0x6d, 0x34, 0xe5, 0x33, 0xbb, 0x3a, 0xf7, 0xd9, 0x0b, 0x83, - 0x87, 0x4b, 0x6b, 0x11, 0x6b, 0x21, 0xbc, 0x54, 0x71, 0x71, 0xd6, 0xa3, - 0x47, 0xb1, 0x9c, 0xb9, 0xee, 0x4d, 0xb9, 0x62, 0x7f, 0xc7, 0xd8, 0xdf, - 0x29, 0xd7, 0xf7, 0x92, 0xca, 0x68, 0x5e, 0x75, 0xfb, 0xed, 0x35, 0xa5, - 0xbf, 0x52, 0x97, 0xe3, 0xc9, 0xbf, 0x56, 0xca, 0xa9, 0x92, 0x18, 0xcc, - 0xcc, 0xf4, 0x61, 0xe9, 0x73, 0x2d, 0xda, 0x86, 0x3e, 0xa0, 0x9f, 0xc9, - 0xbc, 0x0a, 0xfe, 0xcc, 0xc3, 0xca, 0x91, 0x59, 0x68, 0x1d, 0x0a, 0xe3, - 0xb6, 0x91, 0x06, 0x2c, 0xda, 0xb5, 0x06, 0xd5, 0x63, 0x41, 0x5c, 0xb9, - 0x4b, 0xd6, 0xf8, 0x57, 0xa3, 0xb2, 0x70, 0x5b, 0x8d, 0xe4, 0xb8, 0x7a, - 0x3a, 0xc1, 0xf9, 0x4b, 0xa0, 0x22, 0x1d, 0x49, 0x24, 0x21, 0x6b, 0xa4, - 0x26, 0x2a, 0x0a, 0x26, 0xf9, 0xa4, 0xb3, 0x79, 0xbe, 0xe9, 0x73, 0xcf, - 0x9b, 0x2d, 0x2b, 0xd0, 0xe6, 0x39, 0x6e, 0x1f, 0x2f, 0x4f, 0xda, 0x71, - 0xce, 0x5e, 0x87, 0xcd, 0x35, 0x66, 0x13, 0x3c, 0x85, 0xcb, 0x91, 0x1c, - 0x69, 0xc3, 0xbc, 0x42, 0x03, 0x3a, 0x47, 0x42, 0x88, 0xa5, 0xc5, 0xc7, - 0x23, 0x5a, 0x4a, 0xed, 0x80, 0xbf, 0xc0, 0x78, 0x9a, 0xfe, 0x8d, 0xf3, - 0x16, 0xed, 0xa0, 0x87, 0xfa, 0xba, 0x26, 0xdd, 0x85, 0xba, 0x42, 0x00, - 0x57, 0x0f, 0x7d, 0x02, 0xb5, 0x23, 0x7e, 0xcc, 0x1a, 0xd2, 0x90, 0x5f, - 0xe2, 0x47, 0x60, 0x24, 0x8c, 0xea, 0xb4, 0xde, 0x75, 0x9b, 0x82, 0xe4, - 0xc2, 0x25, 0x61, 0xb6, 0x4d, 0x7b, 0xa3, 0x7f, 0x8d, 0x90, 0x7f, 0x2d, - 0xef, 0x06, 0x36, 0xa7, 0x05, 0x1b, 0x45, 0x27, 0x9f, 0x72, 0xcf, 0x9f, - 0xac, 0x4b, 0x7f, 0x18, 0xce, 0x95, 0xed, 0x5b, 0xfc, 0xdc, 0x72, 0xcf, - 0xc4, 0x32, 0x07, 0x52, 0xa6, 0x5b, 0xf4, 0xec, 0x3c, 0xde, 0xfb, 0x39, - 0xe3, 0xf3, 0x43, 0xe9, 0x80, 0x55, 0x6b, 0x6e, 0xc6, 0x55, 0xed, 0x11, - 0xab, 0xa0, 0xbc, 0xca, 0xf1, 0xff, 0x90, 0x41, 0xbb, 0x89, 0xfd, 0xfc, - 0x63, 0xe5, 0x5f, 0xba, 0xce, 0xb6, 0xe4, 0xa2, 0xf5, 0xb9, 0x23, 0xcc, - 0xe7, 0xa7, 0x2e, 0x5a, 0x9f, 0x13, 0xbc, 0x2f, 0x9f, 0x83, 0x90, 0xb9, - 0xd2, 0x66, 0xd8, 0xb7, 0xac, 0x17, 0x09, 0x36, 0xca, 0x7c, 0x95, 0xd7, - 0x8b, 0x7c, 0x58, 0x3e, 0x24, 0xb9, 0x92, 0xca, 0x3c, 0xa1, 0x05, 0xc9, - 0xd0, 0xa3, 0x9c, 0x03, 0x77, 0x4d, 0x89, 0xf7, 0x06, 0xf8, 0x59, 0xd6, - 0x7b, 0x34, 0xe2, 0x8f, 0x56, 0xca, 0x0b, 0xaa, 0x70, 0xeb, 0x50, 0x83, - 0xbb, 0x1f, 0xb5, 0x22, 0x7e, 0x39, 0x62, 0xf5, 0x5f, 0x62, 0x99, 0x0b, - 0x6b, 0x43, 0x57, 0x31, 0xdf, 0xa8, 0x71, 0xcf, 0x4a, 0x2c, 0xa3, 0xbe, - 0x2f, 0x47, 0xdb, 0x48, 0x11, 0xcf, 0x6e, 0x1b, 0x29, 0xe2, 0x56, 0x5a, - 0x6c, 0xce, 0x57, 0xb4, 0xb9, 0x2c, 0x6d, 0x2e, 0xa8, 0x77, 0x2a, 0xd9, - 0xdc, 0x47, 0xc5, 0x13, 0x04, 0xeb, 0xcc, 0xf2, 0x99, 0x6a, 0x62, 0x5e, - 0xfe, 0x48, 0xcd, 0x1f, 0x16, 0x7f, 0x2e, 0xd5, 0xd9, 0xb5, 0x7f, 0xa4, - 0xce, 0xca, 0x31, 0xeb, 0x82, 0xce, 0x06, 0x2f, 0xd1, 0xd9, 0x02, 0xea, - 0xa0, 0x41, 0x2f, 0xea, 0x6d, 0xb9, 0x71, 0x19, 0x52, 0xae, 0xde, 0xaa, - 0x64, 0x6d, 0x8c, 0xf7, 0x04, 0xaf, 0xe7, 0xe0, 0xfb, 0xc1, 0x2f, 0xb9, - 0xf7, 0x16, 0x51, 0x27, 0x45, 0x7d, 0x05, 0xa9, 0xaf, 0x0b, 0xb1, 0x00, - 0xea, 0x07, 0xcc, 0xa7, 0x8a, 0xb1, 0x40, 0x74, 0xf7, 0xda, 0xa0, 0x86, - 0xba, 0xeb, 0x2e, 0xc7, 0x2b, 0x7b, 0xab, 0xd0, 0x3e, 0xe2, 0xa3, 0x7f, - 0x49, 0x7c, 0x28, 0xc6, 0xa4, 0xd6, 0x11, 0x77, 0x3f, 0x8a, 0xf8, 0xda, - 0x10, 0xf8, 0xc3, 0x63, 0xb0, 0x8c, 0x47, 0xce, 0xe5, 0xc9, 0xb9, 0x39, - 0x19, 0x97, 0x3e, 0xc3, 0x16, 0x1c, 0xe7, 0x19, 0xce, 0x77, 0xaa, 0x21, - 0x92, 0x95, 0xf5, 0xa6, 0x2c, 0x39, 0x99, 0x27, 0x2d, 0x3a, 0x13, 0xbe, - 0xad, 0xde, 0xe8, 0x81, 0xda, 0xe6, 0xc1, 0x66, 0x9c, 0x32, 0xf4, 0xfe, - 0x7b, 0xf1, 0x27, 0xe8, 0x0d, 0x39, 0xd8, 0x6f, 0xac, 0x64, 0x3e, 0x51, - 0x8d, 0xf5, 0x6d, 0x34, 0xcf, 0x3b, 0x3a, 0x88, 0x09, 0x56, 0x8f, 0x07, - 0xb2, 0x9e, 0xbb, 0xf1, 0x2e, 0x3b, 0x1a, 0xe9, 0x7e, 0x50, 0x01, 0x56, - 0x0c, 0xf8, 0xa1, 0x29, 0x2e, 0xdf, 0x89, 0x0d, 0xa9, 0xb2, 0xb6, 0xfc, - 0x2f, 0x15, 0xc5, 0xb3, 0x10, 0x2a, 0xb4, 0x46, 0x69, 0x67, 0x25, 0xac, - 0xc9, 0x0e, 0x17, 0x4f, 0x6a, 0x16, 0x2a, 0xb8, 0x75, 0x61, 0xc4, 0x4a, - 0x29, 0x8e, 0xb3, 0x2a, 0xee, 0x75, 0x9f, 0xef, 0x98, 0x6c, 0x4d, 0xdd, - 0xa9, 0xfe, 0x8b, 0x63, 0xb9, 0xeb, 0xd9, 0x91, 0x60, 0x52, 0x65, 0x9f, - 0x3f, 0xf2, 0xac, 0xa2, 0x8c, 0x93, 0x5c, 0x9c, 0xbc, 0xfb, 0xc9, 0xd2, - 0xfa, 0xaf, 0xcf, 0x5c, 0xff, 0x17, 0xfb, 0x75, 0xc9, 0xf7, 0xbe, 0xe4, - 0x9e, 0xfb, 0xc8, 0x66, 0x64, 0xfd, 0xf0, 0xe1, 0x00, 0xaa, 0x57, 0xa2, - 0x77, 0xf2, 0x3a, 0x4c, 0xb4, 0xfd, 0xab, 0x93, 0x2b, 0xf6, 0x5d, 0xcc, - 0xd0, 0x3f, 0xcf, 0xcc, 0xdd, 0x75, 0x7d, 0x4b, 0x84, 0x1c, 0x5c, 0xce, - 0x7a, 0x92, 0x0b, 0x2b, 0x45, 0x1e, 0x3e, 0x5f, 0xbf, 0x09, 0xcf, 0x5e, - 0x24, 0x53, 0xd6, 0x12, 0xca, 0x32, 0x77, 0x51, 0x9e, 0xc8, 0x65, 0x3c, - 0xd0, 0xff, 0xcd, 0x19, 0x09, 0xcd, 0x2c, 0x17, 0xab, 0x2a, 0xc6, 0x2a, - 0x29, 0x57, 0x6e, 0xb7, 0x82, 0xf5, 0xde, 0x77, 0x46, 0x2f, 0x2a, 0xf7, - 0xd3, 0x52, 0xb9, 0x67, 0x02, 0x72, 0x66, 0x24, 0x9b, 0x11, 0xce, 0x7a, - 0xca, 0x19, 0xbb, 0xa8, 0x4c, 0x4b, 0xf5, 0xc5, 0x65, 0x9a, 0x89, 0xd1, - 0xff, 0xaf, 0x33, 0x7e, 0x51, 0x99, 0xe4, 0x25, 0x65, 0x16, 0x10, 0x13, - 0xbf, 0xef, 0xec, 0xbb, 0xa8, 0x4c, 0xed, 0x25, 0x65, 0x16, 0xd3, 0x1e, - 0x9f, 0x71, 0x0e, 0x5c, 0x54, 0x66, 0xcc, 0x7f, 0x71, 0x19, 0xd9, 0xe3, - 0x58, 0xff, 0x17, 0x5b, 0xf4, 0x75, 0x25, 0x9f, 0xbb, 0x70, 0xbf, 0x58, - 0xfe, 0xf1, 0x4b, 0xfa, 0x1f, 0xb1, 0x64, 0xbe, 0x7d, 0xed, 0xe5, 0xf9, - 0x7e, 0xb8, 0x74, 0xff, 0x7b, 0x35, 0x17, 0x97, 0xbb, 0x22, 0x70, 0x69, - 0x3b, 0x45, 0x79, 0x47, 0x2f, 0x69, 0xff, 0xe6, 0xca, 0x8b, 0xbf, 0xbf, - 0x5d, 0x51, 0xfc, 0x5e, 0xd6, 0xe9, 0xa1, 0x4b, 0x9e, 0xff, 0x7d, 0xc5, - 0xc5, 0xdf, 0x37, 0x54, 0x7e, 0x78, 0x3b, 0xb5, 0x97, 0xb4, 0xa3, 0xf4, - 0xca, 0xbb, 0x38, 0x1e, 0x53, 0xad, 0xed, 0xed, 0x58, 0x7f, 0x43, 0x2a, - 0xbf, 0x89, 0xf6, 0x29, 0xb6, 0xf5, 0xe0, 0x0d, 0x6b, 0xf3, 0x6f, 0xcd, - 0xe0, 0xb1, 0xcb, 0xc2, 0x41, 0x7c, 0x1c, 0x6b, 0xdd, 0xbd, 0x34, 0x95, - 0x38, 0x69, 0xb9, 0xb6, 0x40, 0x8e, 0xe9, 0x57, 0xcc, 0x14, 0x0c, 0xf7, - 0xbc, 0xe5, 0x3a, 0x34, 0xe7, 0xdd, 0x3d, 0xbb, 0x58, 0x0a, 0xcf, 0xaa, - 0x5d, 0xba, 0x55, 0x3a, 0x47, 0x67, 0x5d, 0x1f, 0x44, 0x72, 0x66, 0x7e, - 0xaa, 0x8d, 0x23, 0x12, 0xde, 0x86, 0x75, 0xee, 0x59, 0x6b, 0xc5, 0xec, - 0x29, 0x9d, 0xd7, 0x5c, 0x03, 0x3d, 0x5f, 0xe6, 0x4d, 0xb2, 0x9e, 0x2b, - 0xe7, 0x19, 0x1c, 0xfa, 0xa0, 0xc4, 0xf9, 0x83, 0x8a, 0x3a, 0xe0, 0xae, - 0x99, 0xae, 0xf6, 0x20, 0x9a, 0xe8, 0x54, 0x90, 0xaa, 0x32, 0xa3, 0xda, - 0xdb, 0x25, 0x4c, 0xf3, 0x4d, 0x6c, 0x51, 0x2a, 0x26, 0xfa, 0x15, 0xef, - 0x44, 0x11, 0xd3, 0x3c, 0x13, 0xb2, 0xb6, 0xd0, 0xc0, 0x32, 0x41, 0xb4, - 0x2c, 0xf1, 0xe2, 0x3b, 0x76, 0xad, 0xfb, 0x1e, 0xc7, 0xd6, 0x25, 0x15, - 0x78, 0x20, 0xae, 0xa0, 0xeb, 0xaa, 0xc3, 0x78, 0x2b, 0x2f, 0xeb, 0x6c, - 0x56, 0x7c, 0x94, 0x6d, 0x1e, 0xb2, 0x65, 0xbd, 0x74, 0x4b, 0x7c, 0xc4, - 0x6d, 0xff, 0xf3, 0xe8, 0x73, 0xf7, 0xad, 0xba, 0x9d, 0xed, 0x99, 0x1e, - 0x67, 0x1b, 0x73, 0x8d, 0x82, 0xdd, 0x90, 0xaa, 0x63, 0xfd, 0xb7, 0x96, - 0xac, 0xc7, 0x69, 0x96, 0x99, 0xb0, 0x1f, 0xc4, 0xfb, 0xf9, 0x20, 0xf2, - 0xf6, 0x4a, 0x7c, 0x37, 0x1f, 0x60, 0xce, 0xd7, 0x85, 0xef, 0xe4, 0x57, - 0xe3, 0xc5, 0x61, 0xf7, 0x7d, 0x29, 0x2c, 0xb3, 0x15, 0xac, 0x88, 0xae, - 0xc6, 0xb1, 0xd1, 0xd5, 0x38, 0x3c, 0x2c, 0xef, 0x0e, 0xcc, 0x25, 0x8f, - 0x2c, 0xda, 0x9b, 0x4a, 0x8c, 0x59, 0x66, 0xaf, 0xc2, 0xa1, 0xd1, 0x30, - 0x73, 0x29, 0x03, 0x27, 0xf3, 0x21, 0x8c, 0xd8, 0x6d, 0x38, 0x91, 0x0f, - 0xe3, 0xeb, 0x76, 0x02, 0x67, 0xf9, 0xfd, 0xa0, 0x2d, 0x9c, 0xa5, 0x03, - 0xd3, 0xf9, 0x6f, 0x32, 0xcf, 0x99, 0x87, 0x23, 0xdd, 0xcf, 0x30, 0x1c, - 0x1d, 0xe4, 0xd5, 0x85, 0x13, 0xa3, 0x5d, 0x38, 0x35, 0x7c, 0x2b, 0x4e, - 0x8d, 0xfe, 0x18, 0x6f, 0x0d, 0x4b, 0x7f, 0xe5, 0xfc, 0xb7, 0xc8, 0xd5, - 0x29, 0x77, 0x35, 0xa6, 0x46, 0xff, 0x18, 0xd9, 0xef, 0x3a, 0x47, 0x56, - 0x8b, 0xdc, 0x67, 0x7e, 0x87, 0x6c, 0xd1, 0xa5, 0x60, 0xbf, 0x1f, 0xc7, - 0x6c, 0x3f, 0x8e, 0xda, 0x53, 0x57, 0x56, 0x61, 0xea, 0x7a, 0x22, 0x1d, - 0xb6, 0xe7, 0x2b, 0xf1, 0x5c, 0x56, 0xd6, 0xd8, 0x3e, 0x86, 0x64, 0x70, - 0x23, 0xb6, 0x4e, 0x56, 0xe2, 0x3b, 0x59, 0x3f, 0x75, 0x7c, 0x3d, 0x92, - 0xf5, 0xab, 0xa9, 0xbf, 0x00, 0x5e, 0xb2, 0x43, 0x78, 0xd9, 0x6e, 0x4d, - 0x15, 0x94, 0x76, 0x58, 0x2e, 0xfe, 0x07, 0xa8, 0xef, 0x0d, 0x6e, 0x9f, - 0xbe, 0x63, 0x77, 0x3b, 0x5b, 0xa9, 0xe3, 0xfe, 0xcc, 0xe7, 0xdd, 0xb3, - 0xdb, 0x2f, 0xda, 0xd3, 0x8e, 0xbc, 0x93, 0xf1, 0x14, 0x75, 0x7a, 0xcc, - 0x4e, 0x91, 0xdb, 0x35, 0x71, 0x8e, 0xa6, 0x30, 0x4a, 0xbb, 0x3c, 0x99, - 0xd5, 0x8f, 0xae, 0xc5, 0x26, 0x9c, 0xcd, 0x55, 0xe2, 0x35, 0xb6, 0x51, - 0xb7, 0xd8, 0x8b, 0xe3, 0xae, 0xbc, 0x4d, 0x78, 0x3f, 0xab, 0x30, 0xde, - 0x6e, 0xc2, 0x7b, 0x7c, 0xf6, 0x0a, 0x3f, 0x9f, 0x8e, 0xb3, 0x87, 0xa5, - 0x67, 0xa7, 0xc8, 0xcf, 0x65, 0xcd, 0xa8, 0xb7, 0x63, 0x13, 0x4e, 0xe4, - 0xde, 0x23, 0xa7, 0x75, 0xf0, 0x45, 0x63, 0x36, 0x12, 0xb3, 0xc9, 0x9b, - 0xf4, 0x4a, 0x1c, 0xe3, 0xf3, 0x85, 0xc4, 0xdf, 0xe2, 0xfa, 0xd9, 0x26, - 0xbc, 0xcb, 0xf1, 0x3c, 0x40, 0x59, 0xef, 0xe4, 0xfe, 0x96, 0x72, 0x97, - 0x22, 0x1f, 0xff, 0x5b, 0xca, 0xfd, 0x31, 0xc6, 0x4b, 0xfa, 0x38, 0x61, - 0xc8, 0xb8, 0xbe, 0x31, 0x0b, 0xd5, 0x21, 0x8e, 0xe3, 0x9b, 0xfc, 0xbf, - 0x01, 0xc7, 0xf3, 0xff, 0x9b, 0xff, 0xbf, 0x8b, 0x03, 0x79, 0x59, 0xaf, - 0x9e, 0x19, 0x4b, 0xc5, 0x7f, 0xca, 0x1c, 0x64, 0x0e, 0x32, 0x83, 0xb5, - 0xa9, 0xd9, 0xb4, 0xa3, 0xbf, 0xbe, 0xb6, 0x0e, 0xef, 0xc6, 0x2d, 0xec, - 0xd8, 0xe7, 0x45, 0x86, 0xb8, 0xbb, 0x63, 0xa0, 0x01, 0x4f, 0xec, 0x0c, - 0xe2, 0xf1, 0x9d, 0x97, 0x61, 0xcb, 0xce, 0x2b, 0xb0, 0x67, 0x67, 0x13, - 0xd2, 0x3b, 0x1d, 0xe7, 0xfd, 0xc5, 0x8e, 0xb3, 0x88, 0xd7, 0x23, 0xf4, - 0x05, 0x3f, 0xff, 0xbf, 0x10, 0x17, 0x3f, 0xd1, 0x71, 0x95, 0xeb, 0x2f, - 0x9d, 0xb8, 0xd2, 0xfd, 0x9f, 0xc4, 0xa2, 0xfc, 0xc6, 0xf8, 0xfa, 0xc2, - 0xa6, 0xf8, 0x7d, 0x85, 0x39, 0xd8, 0x3a, 0xd8, 0x88, 0xc1, 0x9d, 0x0d, - 0xa9, 0x06, 0xb6, 0xb3, 0xea, 0x5a, 0xe1, 0x76, 0x8e, 0x63, 0xb4, 0xf7, - 0xc7, 0xd7, 0x16, 0x9e, 0x41, 0x77, 0x21, 0x84, 0xbe, 0xc1, 0x30, 0xdb, - 0x92, 0xbd, 0x5c, 0xef, 0xd1, 0x7b, 0xe1, 0x38, 0xd3, 0x8b, 0x0f, 0xe2, - 0xae, 0xc2, 0x37, 0xc9, 0x1b, 0x43, 0x48, 0x0f, 0xae, 0x47, 0x66, 0xb2, - 0x22, 0xe5, 0x37, 0x1d, 0xbc, 0x14, 0x9f, 0xc2, 0xed, 0x94, 0xf7, 0xe8, - 0x60, 0x2d, 0xfb, 0x54, 0x9d, 0xaa, 0x34, 0x25, 0x86, 0x3f, 0xc8, 0x18, - 0x25, 0xfc, 0xe2, 0x28, 0x56, 0x30, 0xbf, 0xaa, 0x5f, 0xa2, 0xcf, 0x42, - 0x6d, 0xd0, 0x7b, 0xa6, 0x43, 0xec, 0x2f, 0x45, 0xfb, 0x93, 0x7d, 0xf5, - 0x75, 0xb8, 0xdb, 0x3d, 0xe7, 0xdd, 0x83, 0xe7, 0x6d, 0xc1, 0x9d, 0x35, - 0xd8, 0x6f, 0xaf, 0x63, 0xce, 0x25, 0xf1, 0x7a, 0x25, 0x9a, 0x0b, 0x7f, - 0x17, 0xbf, 0xa7, 0xb0, 0x9a, 0x7c, 0xf6, 0x5f, 0x70, 0x53, 0x21, 0xc7, - 0x7e, 0x8d, 0xc6, 0xef, 0x2e, 0xec, 0x89, 0xdf, 0x5b, 0xe8, 0xc2, 0x02, - 0x37, 0xa7, 0x64, 0xfe, 0x55, 0x90, 0x38, 0x77, 0x9c, 0x5c, 0xf8, 0x14, - 0x96, 0x17, 0x5e, 0xc3, 0xcd, 0x05, 0xc1, 0x0d, 0x89, 0x7f, 0x2f, 0x7a, - 0x51, 0x2d, 0x71, 0xef, 0x0b, 0xd8, 0xba, 0x3b, 0x85, 0xbe, 0xdd, 0x65, - 0x8c, 0x6a, 0x0d, 0xee, 0x13, 0x7c, 0x99, 0xf4, 0x95, 0x62, 0xd4, 0xa7, - 0x68, 0x8f, 0x2a, 0x63, 0xa3, 0xac, 0xd3, 0xaf, 0xa3, 0x2f, 0x6f, 0x24, - 0x66, 0xca, 0x7a, 0xfc, 0x27, 0x4b, 0xf7, 0x25, 0xd6, 0xcb, 0x5a, 0xbc, - 0x86, 0x43, 0x79, 0x77, 0x4f, 0x5b, 0xf3, 0xeb, 0xb7, 0xf3, 0x99, 0xd4, - 0xff, 0x02, 0xd2, 0xbb, 0x57, 0x3b, 0x8f, 0x66, 0x8a, 0xfb, 0x66, 0x47, - 0xa2, 0x6c, 0x6b, 0x9c, 0xb1, 0x7d, 0x2f, 0xfc, 0xb3, 0x38, 0xb6, 0x89, - 0x01, 0x58, 0x1e, 0xbd, 0xdb, 0xd9, 0x92, 0xc1, 0xbd, 0xb3, 0x10, 0xc6, - 0xca, 0x89, 0x0a, 0x24, 0xf7, 0x57, 0xe3, 0xb6, 0x9d, 0x3d, 0xb4, 0x65, - 0x8b, 0xf6, 0xab, 0x1b, 0x77, 0x2b, 0xd5, 0xb8, 0x99, 0xf7, 0x3e, 0x3d, - 0x28, 0x6b, 0x58, 0xd1, 0xa3, 0x27, 0x3c, 0xd5, 0xb8, 0x6b, 0xaf, 0x1f, - 0xb9, 0xdc, 0x4a, 0x24, 0xf7, 0x1e, 0x81, 0x95, 0xa3, 0x4d, 0xee, 0x22, - 0xce, 0x30, 0xcd, 0x51, 0xcd, 0x1f, 0x63, 0xcf, 0xa8, 0x8a, 0xba, 0x5d, - 0xb2, 0xfe, 0xa8, 0xe8, 0xa7, 0xa3, 0x05, 0xa4, 0x47, 0xbd, 0x98, 0x95, - 0xee, 0xc4, 0x04, 0xb1, 0x26, 0x90, 0x4e, 0x22, 0x9f, 0xef, 0x46, 0x8e, - 0x58, 0x92, 0x1b, 0x0d, 0xa0, 0x26, 0x6d, 0x20, 0xa0, 0xc7, 0xb0, 0x83, - 0xfe, 0x52, 0x91, 0xd6, 0xb1, 0x2d, 0x7f, 0x23, 0xac, 0xd1, 0x4f, 0x60, - 0xfb, 0x68, 0x37, 0x2f, 0x13, 0x7d, 0xa3, 0x9f, 0xc7, 0xb2, 0x89, 0xa3, - 0xe8, 0xcf, 0xa7, 0x68, 0x8f, 0xef, 0x61, 0x7b, 0xee, 0x30, 0x9e, 0xc8, - 0x6e, 0xc6, 0xd9, 0xc5, 0x87, 0xf1, 0x38, 0x3f, 0x67, 0xb3, 0xfa, 0xc6, - 0xb0, 0x7a, 0x18, 0x99, 0xdc, 0x26, 0x7c, 0x62, 0x50, 0xc1, 0x4b, 0xb4, - 0xf5, 0xdb, 0xf7, 0xd2, 0x16, 0x1f, 0xdb, 0x80, 0xae, 0x89, 0xef, 0xc2, - 0xce, 0x3f, 0x8f, 0x1d, 0xb9, 0x07, 0xd1, 0x9f, 0x59, 0xcf, 0xfc, 0xff, - 0x19, 0xca, 0x39, 0x48, 0x3f, 0xdf, 0xc8, 0x31, 0x3e, 0xcc, 0xeb, 0xc2, - 0x1a, 0xe3, 0x85, 0x35, 0x39, 0xfa, 0x7d, 0x46, 0x72, 0xcf, 0x75, 0xc4, - 0x89, 0x27, 0x6b, 0x65, 0x5d, 0xb2, 0x4a, 0x9f, 0xb9, 0x56, 0x2f, 0xb6, - 0x1f, 0x76, 0x73, 0xed, 0xaa, 0xb4, 0xe4, 0x75, 0x53, 0x91, 0x2a, 0x72, - 0x0c, 0x7f, 0x5a, 0x74, 0xd8, 0xe3, 0xf4, 0x66, 0x04, 0x4b, 0x64, 0x3e, - 0x34, 0xbc, 0x90, 0xff, 0x31, 0xb6, 0x0e, 0xcf, 0xc6, 0xf2, 0x6c, 0x1b, - 0x39, 0xa5, 0xe3, 0x7c, 0x85, 0xbe, 0x66, 0x93, 0xeb, 0xec, 0x18, 0x4c, - 0x12, 0x53, 0x66, 0x23, 0x39, 0xa7, 0xc8, 0x4f, 0xc2, 0x69, 0x69, 0xcb, - 0x57, 0xda, 0xab, 0x9b, 0xba, 0x32, 0xcc, 0x7b, 0x75, 0x69, 0x99, 0xb7, - 0x88, 0xa1, 0xb9, 0xfb, 0x69, 0x8e, 0xf3, 0x52, 0xb4, 0xcc, 0x95, 0xa6, - 0xae, 0xac, 0xc3, 0x6c, 0x59, 0x77, 0x4d, 0xc8, 0x39, 0xdf, 0x6f, 0xb5, - 0x2c, 0xa7, 0xaf, 0x7e, 0x01, 0x03, 0xe3, 0xe5, 0x77, 0x23, 0xff, 0xb3, - 0xe4, 0xdd, 0xf5, 0x9f, 0x2c, 0xaf, 0xbc, 0x07, 0x2a, 0xe7, 0x8c, 0xcb, - 0xef, 0x50, 0x8a, 0x2e, 0xaf, 0x90, 0xfd, 0x03, 0xab, 0xb8, 0x4f, 0x0a, - 0x1c, 0xb1, 0x2b, 0x18, 0x87, 0xd5, 0xa5, 0x64, 0x63, 0x21, 0x1f, 0x2a, - 0x19, 0x2f, 0x1b, 0xd1, 0x47, 0xbe, 0x7a, 0x93, 0x51, 0x81, 0x03, 0x6d, - 0x49, 0x39, 0xcf, 0xd7, 0xe3, 0x73, 0x79, 0xea, 0xa6, 0x3f, 0xff, 0x6d, - 0x9e, 0xba, 0x09, 0xe9, 0x8c, 0x9c, 0x63, 0xeb, 0xc6, 0x4b, 0xf5, 0xf2, - 0x5e, 0xe7, 0x26, 0xf7, 0x9c, 0x70, 0xd5, 0x42, 0x62, 0x46, 0x5c, 0xc3, - 0x51, 0xbd, 0x55, 0x6b, 0x50, 0x23, 0x06, 0x94, 0xd7, 0x1d, 0x2b, 0x94, - 0x44, 0xff, 0xa4, 0x9c, 0xd5, 0xfb, 0xa8, 0x3d, 0x84, 0xb5, 0xd8, 0xfe, - 0x58, 0x07, 0x8e, 0xaf, 0x96, 0xb5, 0xbc, 0x9f, 0x95, 0xde, 0xdb, 0x93, - 0x3e, 0x46, 0xea, 0xe4, 0x0c, 0xaa, 0xc8, 0xde, 0x9e, 0x51, 0x19, 0x7b, - 0xe2, 0x78, 0x3d, 0xe8, 0x8e, 0x37, 0x56, 0x3e, 0x97, 0x59, 0xa9, 0x2f, - 0x2f, 0x95, 0x5f, 0x50, 0x27, 0xbc, 0x64, 0x5b, 0x66, 0x13, 0xb9, 0xb6, - 0xf4, 0xe7, 0xd7, 0xce, 0xda, 0x50, 0x03, 0xcb, 0x8e, 0x95, 0x9e, 0x8b, - 0xad, 0x45, 0x8c, 0x24, 0xe4, 0x9e, 0xd4, 0x11, 0x9d, 0xcd, 0xac, 0xe3, - 0x41, 0xbd, 0x7e, 0x25, 0x1e, 0xa2, 0x8f, 0xcf, 0xd7, 0x5f, 0x76, 0x36, - 0xcb, 0x39, 0xcd, 0x85, 0xc1, 0x19, 0x6d, 0x2d, 0x75, 0xfb, 0x52, 0xc9, - 0xbe, 0x0c, 0x66, 0xe4, 0xbd, 0x81, 0xb3, 0xce, 0xc2, 0x46, 0x79, 0x7e, - 0x5b, 0x6d, 0x51, 0x7e, 0xb3, 0x7b, 0x0e, 0x7b, 0x4f, 0xa6, 0xdc, 0x6f, - 0x39, 0xe3, 0x1e, 0x2a, 0xb7, 0x15, 0xbb, 0x30, 0x1e, 0xe9, 0xdb, 0xd7, - 0x6a, 0x2f, 0xee, 0xf3, 0x9d, 0xb3, 0xca, 0xef, 0x17, 0xcc, 0x73, 0xeb, - 0x94, 0xdb, 0x94, 0x3e, 0x6e, 0xc2, 0xe3, 0x93, 0x97, 0x8e, 0xf1, 0xee, - 0x19, 0x63, 0x92, 0x3a, 0x32, 0xae, 0x60, 0xc9, 0x0e, 0x36, 0xb2, 0x8c, - 0xd4, 0x91, 0x75, 0x82, 0xa0, 0x9b, 0x3f, 0xd4, 0xed, 0x16, 0x79, 0x22, - 0xc3, 0x71, 0xde, 0x70, 0x63, 0xf2, 0x02, 0xb7, 0xcc, 0xe0, 0xe4, 0x6a, - 0xfa, 0x91, 0xb3, 0x99, 0xf8, 0xec, 0xbc, 0xd1, 0x11, 0xc6, 0x56, 0x5b, - 0x74, 0xad, 0x87, 0xc7, 0x88, 0x4d, 0x7d, 0x2e, 0x9f, 0xf1, 0xa1, 0x37, - 0x57, 0x3e, 0xeb, 0x52, 0x29, 0x7b, 0x21, 0x61, 0xd1, 0x79, 0xaf, 0x41, - 0x1e, 0x17, 0x5c, 0xa6, 0x79, 0xc9, 0xc5, 0xee, 0xc1, 0x7f, 0xc8, 0xfc, - 0xc6, 0x7c, 0xa5, 0x75, 0x93, 0x14, 0xed, 0xa8, 0x18, 0x0f, 0x41, 0xfe, - 0x40, 0x1e, 0x56, 0x3a, 0x43, 0xdf, 0x9b, 0xff, 0x0f, 0x67, 0xca, 0x3d, - 0x43, 0x7f, 0xe1, 0x2c, 0x4a, 0x2e, 0xe8, 0x38, 0xfb, 0xf8, 0xec, 0xc2, - 0x79, 0x7a, 0x72, 0x06, 0x5d, 0xce, 0xdd, 0xff, 0x3b, 0xe7, 0x6e, 0x66, - 0xd9, 0xa9, 0xfa, 0xe2, 0xfb, 0x25, 0x49, 0x75, 0x99, 0x5e, 0xc6, 0x6d, - 0xd9, 0x27, 0x12, 0xdc, 0x3e, 0x58, 0x57, 0x5c, 0x3f, 0x8e, 0x74, 0x75, - 0x43, 0xf6, 0xe4, 0xcb, 0x38, 0xa3, 0x1b, 0x8b, 0x94, 0xcd, 0x68, 0x89, - 0x57, 0xcb, 0xf9, 0xba, 0x88, 0xd7, 0x8c, 0x04, 0xdf, 0x42, 0x34, 0x76, - 0xd8, 0x3d, 0x43, 0x22, 0xd8, 0xa3, 0xe3, 0x9e, 0xbc, 0x4e, 0x9b, 0x95, - 0xf7, 0xd2, 0xe5, 0x73, 0xf1, 0xdd, 0xc7, 0x64, 0x5e, 0xb0, 0xba, 0x87, - 0x58, 0x6d, 0xfd, 0xa5, 0xcf, 0x95, 0x17, 0xe9, 0x19, 0x55, 0x22, 0x5d, - 0x0f, 0x2a, 0x65, 0x79, 0x81, 0x0f, 0x91, 0x17, 0x63, 0x7d, 0xad, 0xf4, - 0x2e, 0xb8, 0x4e, 0x19, 0x97, 0x9e, 0x0d, 0x9a, 0x93, 0x92, 0x3c, 0xfa, - 0x40, 0x89, 0x73, 0x1e, 0xfe, 0xad, 0x3c, 0xfa, 0x43, 0xdb, 0x4c, 0xb2, - 0xcd, 0xae, 0x6a, 0x25, 0x19, 0x97, 0xf7, 0x80, 0x2a, 0xe3, 0xd1, 0xd8, - 0x0b, 0x74, 0x72, 0xaf, 0x19, 0x0d, 0x8f, 0xba, 0x67, 0x5d, 0x0c, 0xff, - 0xf2, 0x7c, 0xd1, 0x7f, 0xac, 0xc9, 0xdf, 0xad, 0x93, 0x1a, 0x5d, 0xef, - 0x6e, 0x55, 0x92, 0xd7, 0x57, 0x53, 0x4e, 0x2c, 0x0e, 0xad, 0xc2, 0x2c, - 0xeb, 0x28, 0x1a, 0x7b, 0x8b, 0xf3, 0x79, 0xa8, 0x23, 0x1a, 0x1e, 0x71, - 0x73, 0x74, 0xd1, 0x8b, 0xe1, 0x2f, 0xce, 0xbd, 0x2e, 0x7c, 0xde, 0xf2, - 0x31, 0x36, 0x8f, 0xdb, 0x7e, 0x8e, 0xa5, 0x35, 0xb8, 0x1d, 0xf5, 0xb4, - 0x71, 0x24, 0xfb, 0xda, 0x18, 0x1f, 0x6c, 0x24, 0x3d, 0x57, 0xd5, 0x21, - 0x45, 0x82, 0xee, 0xd1, 0x53, 0xe4, 0x5c, 0xad, 0xb1, 0x47, 0x68, 0xbf, - 0xb9, 0x50, 0x24, 0x6c, 0x21, 0x85, 0xe7, 0xec, 0x65, 0x7f, 0xee, 0x81, - 0x65, 0xd4, 0x70, 0xa2, 0xab, 0xcd, 0xa9, 0x3f, 0xbf, 0x35, 0x1a, 0xd1, - 0x5e, 0x2c, 0x9d, 0xd5, 0xe9, 0xb5, 0x7f, 0xe1, 0xee, 0x51, 0x79, 0xf4, - 0xdf, 0x55, 0x46, 0xda, 0xf6, 0x63, 0x2c, 0x9b, 0xc5, 0x96, 0xc7, 0xd8, - 0x47, 0xdd, 0xc1, 0x32, 0x63, 0x33, 0x96, 0x1b, 0x01, 0xac, 0x0b, 0xb6, - 0x24, 0xe4, 0x2c, 0xd2, 0x48, 0xae, 0xb8, 0x36, 0x52, 0x5c, 0x0b, 0xef, - 0xc7, 0xa3, 0x19, 0x37, 0x3e, 0x07, 0xfd, 0x66, 0x52, 0x79, 0x34, 0xdf, - 0xa9, 0x3c, 0x52, 0x5a, 0x8f, 0xeb, 0xcf, 0xdf, 0x10, 0x44, 0xb5, 0x85, - 0x13, 0x86, 0xbc, 0x47, 0x29, 0x72, 0x2d, 0x8c, 0x76, 0xfc, 0x21, 0xef, - 0x53, 0x8a, 0x4e, 0x37, 0xa2, 0x6f, 0xf8, 0x61, 0xf4, 0x0e, 0xbf, 0xe4, - 0x9e, 0x65, 0xf5, 0xe9, 0x7e, 0xeb, 0x0a, 0x33, 0x72, 0xd0, 0xc2, 0xbc, - 0x7a, 0x59, 0x13, 0x6e, 0x34, 0x8f, 0xe2, 0xd1, 0xa0, 0xbc, 0x27, 0xd8, - 0x4f, 0x9e, 0x22, 0xef, 0x9c, 0xad, 0xc1, 0x67, 0x06, 0x64, 0x0e, 0x6b, - 0xad, 0x4a, 0x33, 0x92, 0x5c, 0xe7, 0xce, 0x61, 0x1b, 0x8e, 0x15, 0x1e, - 0xc6, 0x1b, 0xbb, 0x36, 0x43, 0x8d, 0x47, 0xc2, 0xb7, 0xc0, 0xd9, 0x7c, - 0xc4, 0x48, 0x5a, 0x3e, 0x44, 0x0e, 0x78, 0x54, 0xe0, 0xd9, 0x5d, 0x92, - 0x4f, 0xf7, 0xe0, 0x7a, 0x72, 0x80, 0x3a, 0xdd, 0x59, 0xfa, 0xab, 0xc5, - 0x91, 0x7e, 0xdd, 0x63, 0xfd, 0xd3, 0x1c, 0x44, 0xb2, 0x09, 0x55, 0xef, - 0xf9, 0xa4, 0x0a, 0x25, 0x60, 0xca, 0x6f, 0x00, 0x6c, 0xc6, 0x27, 0xda, - 0x03, 0xd6, 0x2c, 0x33, 0x92, 0x7d, 0x49, 0x89, 0xc4, 0x2c, 0xf5, 0x1b, - 0x9c, 0xe7, 0x18, 0x5e, 0x24, 0xc7, 0xe9, 0x62, 0x6c, 0x5f, 0x21, 0x31, - 0xdd, 0xc5, 0xbe, 0xe6, 0x44, 0x95, 0x12, 0xc4, 0x2d, 0x05, 0xe0, 0x50, - 0x6e, 0x0d, 0x4e, 0xee, 0x32, 0xd0, 0xc9, 0x67, 0x83, 0x19, 0x02, 0x16, - 0x31, 0x60, 0x83, 0x61, 0xb5, 0xaa, 0xe4, 0x16, 0x3e, 0x15, 0xcb, 0xe6, - 0x9b, 0xd1, 0xa9, 0xa5, 0x1e, 0x2f, 0x12, 0x05, 0x2f, 0xee, 0x60, 0x99, - 0xed, 0x8c, 0x0b, 0x9f, 0x4c, 0xfb, 0xc9, 0x6f, 0x9b, 0xf0, 0x33, 0xf2, - 0xec, 0x9f, 0x92, 0x4f, 0x1f, 0x27, 0x5f, 0x38, 0x9e, 0xaf, 0x46, 0xf7, - 0x90, 0x4f, 0xce, 0x1f, 0x4d, 0xf9, 0x38, 0x17, 0xb5, 0xed, 0x21, 0x9c, - 0x1e, 0xf5, 0xe3, 0xf6, 0x5d, 0x91, 0x3d, 0xc7, 0xd5, 0x46, 0xbc, 0x3f, - 0x5a, 0x8d, 0x95, 0x43, 0x7e, 0xf6, 0xcd, 0xc1, 0x0e, 0xe2, 0xff, 0xbb, - 0x7c, 0xd6, 0xb9, 0x0b, 0x4a, 0x7e, 0xc9, 0x02, 0xe6, 0x04, 0x3a, 0xeb, - 0xd7, 0xe0, 0xd6, 0x21, 0xe1, 0x81, 0x2a, 0xde, 0x1e, 0x55, 0xf0, 0x56, - 0xce, 0xc0, 0x32, 0xb6, 0xd7, 0x97, 0x79, 0xd6, 0xf1, 0xd3, 0xcf, 0xd7, - 0xe6, 0x0d, 0xdc, 0x9b, 0xd3, 0x19, 0x53, 0x7e, 0xe2, 0x78, 0xf4, 0x76, - 0xfc, 0x64, 0xa7, 0x7e, 0xf4, 0x75, 0x4f, 0x74, 0x6a, 0x89, 0xa7, 0x1d, - 0xaf, 0xed, 0x6f, 0xc7, 0xf7, 0x06, 0x97, 0xe2, 0x9a, 0xf6, 0x24, 0xce, - 0x2c, 0x69, 0xc7, 0xab, 0x7b, 0x75, 0x3c, 0x92, 0xe9, 0x80, 0x36, 0x31, - 0x45, 0xfe, 0x9b, 0x40, 0xeb, 0x84, 0x09, 0x7d, 0xd0, 0xd9, 0x5c, 0x63, - 0x6e, 0xc6, 0xa3, 0x86, 0x89, 0x45, 0x7b, 0x45, 0x0f, 0x8e, 0xb3, 0x6e, - 0x89, 0x89, 0x17, 0xb2, 0x3a, 0xfd, 0xd4, 0xa4, 0x1e, 0x74, 0x3c, 0x9e, - 0x31, 0x11, 0x7d, 0x4c, 0x9f, 0xde, 0xc7, 0xef, 0x4b, 0xf7, 0x75, 0xa0, - 0x87, 0xed, 0xdb, 0xc4, 0xeb, 0x3d, 0x13, 0x6d, 0x1c, 0xb3, 0xc1, 0xf1, - 0x37, 0x5b, 0x3f, 0x53, 0x3a, 0x91, 0x9d, 0xe8, 0x22, 0x9f, 0xdd, 0x4c, - 0x1e, 0xdb, 0xe5, 0xee, 0xb9, 0x6f, 0xcd, 0x18, 0xb8, 0x35, 0xdd, 0x85, - 0x27, 0x6d, 0x39, 0x3b, 0xaf, 0x27, 0xae, 0x55, 0xe4, 0x1d, 0xdd, 0x2e, - 0x8c, 0x51, 0x27, 0xcb, 0x86, 0x56, 0xba, 0xe7, 0x9d, 0x96, 0xef, 0xd2, - 0xf1, 0x44, 0xe6, 0x13, 0x38, 0x39, 0x6e, 0xa0, 0x3b, 0x2d, 0xfa, 0x96, - 0xf3, 0x9b, 0x29, 0x1c, 0x61, 0x6c, 0xf9, 0xd9, 0x50, 0xf2, 0x9f, 0x38, - 0xcd, 0xc7, 0x54, 0xc8, 0x7a, 0x89, 0x8a, 0xab, 0xdb, 0xe5, 0x0c, 0xae, - 0x87, 0xa8, 0x16, 0xb1, 0xea, 0x54, 0x4b, 0xe3, 0x7d, 0xcb, 0xab, 0x6e, - 0xc2, 0x67, 0x87, 0xbc, 0xcc, 0x19, 0x54, 0xe6, 0x3a, 0xd6, 0x06, 0xda, - 0x86, 0x55, 0xab, 0x16, 0xe7, 0xcd, 0xdd, 0x63, 0xd0, 0x3d, 0xd8, 0x61, - 0x34, 0x77, 0xd7, 0xb0, 0xde, 0x8a, 0x78, 0x24, 0x59, 0xa5, 0x76, 0x30, - 0x0f, 0x7d, 0x18, 0xeb, 0x76, 0x3d, 0x8c, 0xb5, 0xbc, 0x36, 0xec, 0x72, - 0x36, 0xdf, 0x6c, 0x28, 0x78, 0x4e, 0x77, 0x36, 0x6f, 0x36, 0x74, 0xce, - 0xad, 0xcc, 0xeb, 0xc3, 0xd8, 0x38, 0xf6, 0x30, 0x1e, 0xa2, 0x7d, 0x35, - 0xd0, 0x8f, 0x57, 0xa5, 0x9d, 0xcd, 0xd7, 0xb4, 0xc7, 0xf0, 0x73, 0x37, - 0xbf, 0x11, 0x7b, 0x3d, 0xe3, 0xe6, 0xdc, 0x39, 0xd5, 0xb5, 0xdd, 0xa0, - 0x7c, 0xb6, 0xd4, 0x25, 0xc1, 0x72, 0x6c, 0xf9, 0x05, 0xe5, 0xfe, 0x72, - 0x57, 0x1d, 0x1e, 0x6b, 0x90, 0xf8, 0xe1, 0xb7, 0xaa, 0x4c, 0x28, 0xfa, - 0x12, 0xe6, 0x71, 0x8f, 0x1d, 0xc1, 0x76, 0xf2, 0xc2, 0x50, 0x5c, 0x72, - 0xec, 0x56, 0x63, 0x8b, 0x7a, 0x23, 0xb1, 0x5d, 0xc1, 0xa3, 0x0b, 0xb3, - 0x18, 0xa0, 0xaf, 0xee, 0x58, 0x18, 0x49, 0x0d, 0xc0, 0x74, 0x76, 0xcc, - 0xe9, 0xff, 0x23, 0xde, 0xa1, 0x2d, 0xef, 0x4b, 0xca, 0x7b, 0xb4, 0x0f, - 0x63, 0xf3, 0x2e, 0x99, 0xff, 0x87, 0xf1, 0x45, 0xf6, 0x7f, 0xe3, 0xd0, - 0xc3, 0xf8, 0x1c, 0x6d, 0xa7, 0x7e, 0xf1, 0xa1, 0x2f, 0xd6, 0xa3, 0x25, - 0x5b, 0x87, 0xa9, 0xfb, 0x1b, 0xe4, 0xbc, 0x2d, 0x31, 0x71, 0x40, 0x79, - 0x18, 0xf7, 0x8c, 0xd4, 0xd2, 0x17, 0xdd, 0x31, 0x10, 0x8b, 0xcb, 0xf1, - 0x2a, 0x8c, 0x75, 0xf9, 0xa6, 0x12, 0xae, 0x87, 0xb0, 0xd6, 0x3e, 0xe0, - 0xfa, 0x7e, 0x85, 0xb9, 0x9a, 0x7e, 0xdf, 0x4d, 0xbf, 0x5f, 0x49, 0xbf, - 0xef, 0xa2, 0xdf, 0x77, 0xd2, 0xef, 0x93, 0xf4, 0x7b, 0x93, 0x7e, 0x9f, - 0xa0, 0xdf, 0x77, 0xd0, 0xef, 0x0d, 0xd9, 0x3b, 0x54, 0x8e, 0x76, 0x1c, - 0x81, 0x6f, 0xd0, 0x4f, 0x1b, 0x2a, 0xbe, 0xd3, 0xb8, 0x9f, 0xf8, 0x73, - 0xc2, 0x58, 0x14, 0xbe, 0x89, 0xaa, 0x1a, 0x25, 0x46, 0xe4, 0xc6, 0xff, - 0xce, 0x7d, 0xff, 0x2d, 0x47, 0xdc, 0x7f, 0x91, 0xfa, 0x58, 0x11, 0x6f, - 0x36, 0x9e, 0x64, 0x0c, 0xfb, 0xa1, 0xde, 0xda, 0x1f, 0x62, 0x99, 0xaf, - 0x65, 0x5a, 0xb3, 0xb3, 0xa1, 0x5b, 0xed, 0xea, 0x56, 0x60, 0x55, 0x88, - 0x63, 0x96, 0x73, 0xdd, 0xab, 0xf0, 0xc5, 0xe1, 0x6e, 0xfc, 0xcf, 0xe1, - 0x20, 0x75, 0xd1, 0x3c, 0x75, 0xa3, 0x07, 0xdf, 0x0c, 0xc3, 0x13, 0x9a, - 0x0b, 0x7c, 0xd0, 0x88, 0x45, 0x07, 0xe4, 0x5d, 0xec, 0x5c, 0xa3, 0xa7, - 0x6d, 0x3e, 0xc4, 0x46, 0x40, 0xa4, 0xf6, 0x30, 0xd3, 0x5c, 0xe4, 0xbe, - 0xaf, 0x99, 0x5c, 0x2d, 0x98, 0x5e, 0x85, 0xad, 0x31, 0x17, 0x67, 0x9f, - 0x96, 0xf3, 0xe9, 0x8d, 0xc4, 0xa3, 0x80, 0xd9, 0x85, 0x6d, 0x03, 0xd6, - 0x5d, 0x8d, 0x58, 0x89, 0xfe, 0x81, 0xa2, 0x0e, 0xee, 0x8f, 0x13, 0xf2, - 0xcc, 0xa8, 0xb6, 0x48, 0x81, 0x77, 0x43, 0x47, 0x02, 0xf7, 0xe6, 0x6d, - 0x64, 0x39, 0xc6, 0xf5, 0xf4, 0xb3, 0x75, 0xbf, 0xff, 0x3d, 0x7c, 0x7c, - 0xce, 0xd6, 0x68, 0xff, 0xe7, 0x9c, 0x5c, 0xfd, 0xa2, 0x6c, 0x23, 0xf4, - 0x8d, 0x77, 0xa8, 0xd7, 0x32, 0x67, 0x8e, 0x1c, 0xe4, 0x23, 0x6b, 0x8e, - 0x7b, 0x8e, 0xce, 0x8f, 0x05, 0x43, 0x50, 0x46, 0xd3, 0xf2, 0xce, 0xda, - 0x66, 0xfc, 0x5f, 0xc6, 0x37, 0x5c, 0x5b, 0x9a, 0xf2, 0xc8, 0x99, 0x16, - 0xb9, 0xef, 0x2c, 0x3d, 0xbb, 0x38, 0x12, 0xd3, 0x3c, 0x3f, 0xa8, 0x93, - 0xfd, 0x8b, 0xaf, 0x33, 0xce, 0x86, 0x87, 0x96, 0x42, 0x5d, 0xec, 0xc7, - 0x9d, 0x6d, 0xb3, 0x90, 0x5a, 0x25, 0x3c, 0xd4, 0xdd, 0x5f, 0xa1, 0x3e, - 0xff, 0x02, 0xf7, 0x19, 0x5f, 0xc1, 0xf1, 0x90, 0x8d, 0x21, 0xe2, 0xd7, - 0x3a, 0xe3, 0x76, 0xc5, 0xe2, 0x67, 0xe6, 0x44, 0x58, 0x6f, 0x30, 0xd7, - 0xfa, 0x54, 0x03, 0x1a, 0x76, 0x49, 0x79, 0x91, 0x7b, 0xc6, 0x95, 0xb7, - 0x3f, 0x23, 0x9f, 0x8b, 0x36, 0x3b, 0xe5, 0xf9, 0x24, 0xd0, 0x20, 0xe7, - 0x84, 0x15, 0xbc, 0xbd, 0xd0, 0xc6, 0x63, 0x19, 0x7c, 0xb3, 0x0a, 0xcd, - 0xb9, 0x41, 0xd5, 0xf3, 0xcd, 0xb9, 0x58, 0x64, 0xfc, 0x5a, 0x95, 0xf9, - 0x48, 0xe2, 0xbe, 0x85, 0x72, 0x1e, 0x4d, 0x3f, 0xf3, 0x3d, 0xfa, 0xd6, - 0x71, 0xd8, 0xd8, 0x3e, 0xf9, 0x92, 0x33, 0x35, 0x37, 0x84, 0xa7, 0x26, - 0xa5, 0x6e, 0x37, 0x4e, 0x70, 0x4e, 0xbe, 0xec, 0xee, 0xe7, 0x45, 0x92, - 0x27, 0x54, 0x79, 0xe7, 0xb0, 0x1b, 0x6f, 0x8d, 0x1a, 0xd8, 0xc7, 0x1c, - 0xea, 0x57, 0xc3, 0xab, 0xf0, 0xeb, 0xe1, 0x66, 0xed, 0x6f, 0x14, 0x39, - 0x03, 0xff, 0x71, 0xfc, 0xa8, 0x21, 0x88, 0x83, 0xb4, 0xa1, 0x69, 0xbb, - 0x0b, 0x6f, 0xdb, 0x56, 0x64, 0x2e, 0x22, 0x7b, 0xbc, 0x9e, 0xc8, 0x01, - 0x79, 0xcf, 0x79, 0x9d, 0x1a, 0x39, 0xb8, 0x44, 0x89, 0x58, 0x6f, 0xa8, - 0x2b, 0xf1, 0x8b, 0x7c, 0x17, 0xce, 0xe4, 0x67, 0xda, 0xc2, 0x66, 0x07, - 0x8d, 0x62, 0x07, 0x62, 0x0f, 0xb4, 0x45, 0xe6, 0x8a, 0xdf, 0x26, 0x8f, - 0xee, 0xfd, 0x18, 0xed, 0x31, 0x43, 0x7b, 0xcc, 0xd0, 0x1e, 0x89, 0x49, - 0xcf, 0x10, 0xab, 0xbe, 0x96, 0xa1, 0x3d, 0xd2, 0x7f, 0xbe, 0x42, 0xff, - 0x29, 0x72, 0xe5, 0x1e, 0x77, 0x4d, 0xff, 0x15, 0xc6, 0x44, 0xfb, 0x31, - 0x79, 0x7f, 0xb8, 0x79, 0x7d, 0x01, 0x91, 0x9e, 0x01, 0x65, 0x5d, 0xbd, - 0xbc, 0xcf, 0xf1, 0xf9, 0xa8, 0xf8, 0x80, 0xbc, 0x7b, 0x46, 0xbf, 0x1a, - 0x3f, 0x55, 0x27, 0xef, 0xb2, 0xee, 0xdf, 0xfd, 0x51, 0x3a, 0xfb, 0x7b, - 0xf6, 0x43, 0xf4, 0xf5, 0xc7, 0x8e, 0x5d, 0x74, 0xf9, 0x4f, 0xce, 0x8f, - 0x1a, 0x65, 0xfc, 0xab, 0xf1, 0xf3, 0xe1, 0x4e, 0x9c, 0x65, 0xfc, 0xfd, - 0x74, 0xfb, 0x94, 0x45, 0x9b, 0xdd, 0x68, 0x78, 0x4c, 0x4c, 0xe6, 0x3b, - 0x71, 0xda, 0x36, 0x91, 0xb7, 0x9b, 0xd7, 0x7f, 0x57, 0x79, 0x53, 0xcd, - 0xcd, 0x2b, 0xf2, 0xf9, 0xdf, 0x90, 0x5f, 0x1e, 0x6a, 0x91, 0xf7, 0x5d, - 0x13, 0x18, 0xc9, 0x8b, 0x9d, 0x06, 0x71, 0xd3, 0x12, 0x43, 0xde, 0x11, - 0xfb, 0xbd, 0x7f, 0xf7, 0xd9, 0xb2, 0x97, 0x72, 0xce, 0x99, 0x0a, 0xfa, - 0xad, 0x20, 0x7d, 0xd8, 0xb3, 0x4b, 0x7e, 0x07, 0x40, 0xfc, 0x59, 0xc1, - 0x67, 0x8c, 0x29, 0xad, 0x06, 0x91, 0xa7, 0x77, 0x33, 0x81, 0x7a, 0x2d, - 0x2d, 0x67, 0x88, 0x3b, 0xf1, 0x26, 0xcb, 0x57, 0xd1, 0x2f, 0x5e, 0xcb, - 0x7b, 0xbd, 0x3f, 0x4a, 0xcb, 0x7b, 0xec, 0x2b, 0xf1, 0xa3, 0xfc, 0xcb, - 0xea, 0x2f, 0x82, 0x06, 0xde, 0x2e, 0xac, 0xc2, 0xfc, 0x5d, 0xb2, 0xbe, - 0x90, 0xc4, 0x7e, 0x3b, 0x72, 0xf4, 0x59, 0xac, 0xc2, 0xbc, 0xb1, 0xd5, - 0xcc, 0xa3, 0x15, 0xbc, 0x17, 0x5d, 0x8d, 0x00, 0x3f, 0xd7, 0xee, 0x72, - 0x9c, 0xc3, 0xf1, 0x3a, 0x67, 0xfb, 0x6a, 0x99, 0x3b, 0xc1, 0x93, 0x65, - 0xf5, 0xa8, 0x5d, 0x0d, 0x8c, 0x09, 0x57, 0xd1, 0x71, 0xeb, 0xc0, 0x2a, - 0x5c, 0xb1, 0xab, 0x39, 0x76, 0x2b, 0x9a, 0xb3, 0x47, 0x3c, 0xab, 0xd0, - 0x30, 0x76, 0x2f, 0xe7, 0x40, 0xca, 0x6a, 0xb4, 0x3f, 0x0b, 0x95, 0xe4, - 0x84, 0x9d, 0xe9, 0x9f, 0x3a, 0xf3, 0x4d, 0x77, 0x1f, 0x0e, 0xeb, 0x0a, - 0x3a, 0xe3, 0x5d, 0x35, 0x52, 0x23, 0x4f, 0x38, 0x75, 0xa6, 0x17, 0x6b, - 0x0b, 0x6d, 0xb8, 0x69, 0xc8, 0x71, 0x4e, 0x2f, 0x49, 0x22, 0x60, 0x06, - 0x88, 0x61, 0x01, 0x3c, 0x94, 0xae, 0xe1, 0x7f, 0x07, 0x15, 0x8c, 0xc9, - 0x2d, 0xaa, 0xbe, 0x7e, 0x9e, 0x47, 0xef, 0x29, 0x28, 0x12, 0xf7, 0x03, - 0x78, 0x80, 0xf1, 0x79, 0x45, 0x3a, 0x8c, 0x54, 0xc1, 0x71, 0x5e, 0xed, - 0x08, 0xe1, 0x7e, 0xd6, 0xef, 0x4a, 0xf7, 0xa3, 0x97, 0x76, 0x91, 0x1a, - 0xd3, 0xb5, 0x20, 0xe3, 0xfd, 0xba, 0x82, 0x9f, 0x31, 0xac, 0x01, 0xb7, - 0xec, 0xd2, 0xf0, 0x50, 0x21, 0xc0, 0xf8, 0xe6, 0x2c, 0x3d, 0x69, 0x58, - 0x57, 0x7a, 0xa0, 0x63, 0x63, 0x21, 0x84, 0x95, 0xe9, 0xc8, 0xb4, 0xbc, - 0x47, 0x7d, 0xd6, 0x88, 0xe1, 0xc1, 0x42, 0x18, 0xb7, 0xa5, 0x0f, 0x3d, - 0x34, 0x1f, 0xd6, 0xff, 0x98, 0x87, 0x36, 0x7c, 0xa6, 0xd0, 0x44, 0xf9, - 0x91, 0xf5, 0xaf, 0x28, 0x4d, 0xf8, 0xec, 0x98, 0x41, 0xf9, 0x2a, 0x6e, - 0xa5, 0x9c, 0x9b, 0xd3, 0x57, 0xe0, 0x81, 0xb1, 0x0e, 0xdc, 0x5b, 0x58, - 0x8c, 0xe5, 0x8c, 0x4f, 0x1b, 0x98, 0x1b, 0xe2, 0xbf, 0x00, 0xb7, 0x0d, - 0x89, 0xee, 0xa1, 0xbc, 0xda, 0x31, 0xc5, 0x7c, 0xdc, 0x00, 0x0d, 0x91, - 0xf7, 0x74, 0x72, 0x30, 0x03, 0xb7, 0xed, 0x5d, 0xec, 0xee, 0xc9, 0x37, - 0xc7, 0x2b, 0x91, 0xea, 0x56, 0xd0, 0x39, 0x24, 0x71, 0x56, 0xb8, 0x8d, - 0xc1, 0xb8, 0x1a, 0x65, 0x1b, 0x06, 0xe3, 0x6a, 0xf1, 0x7e, 0x6f, 0x46, - 0xd6, 0x2e, 0x7e, 0x42, 0xbe, 0x14, 0x47, 0xa7, 0x1b, 0xa3, 0xfd, 0xe4, - 0xd7, 0x16, 0xbc, 0x8c, 0xdd, 0x71, 0xda, 0xf8, 0xd2, 0x76, 0x89, 0xd5, - 0x3a, 0x06, 0xe8, 0x0f, 0x93, 0x83, 0xfa, 0x86, 0x69, 0xc5, 0x44, 0x61, - 0xaf, 0xc4, 0xc4, 0x10, 0x1e, 0x4c, 0x9b, 0x38, 0x29, 0xe7, 0xf8, 0xaf, - 0x4a, 0xae, 0xa8, 0x81, 0x6e, 0x3c, 0x80, 0xa8, 0x75, 0x8c, 0xb1, 0xfd, - 0x4c, 0xae, 0x01, 0x37, 0xed, 0x92, 0x32, 0xed, 0x78, 0x7d, 0xd4, 0x8b, - 0x9b, 0xd2, 0x9b, 0xf0, 0x44, 0xd6, 0x83, 0x11, 0xa3, 0xb9, 0x5f, 0x65, - 0xfc, 0xbc, 0xbe, 0x3d, 0x12, 0xfc, 0x3a, 0xb9, 0xea, 0xf4, 0x62, 0x46, - 0xe5, 0xb9, 0x1d, 0xe8, 0x64, 0xbf, 0x3a, 0x75, 0xf1, 0x49, 0x0b, 0xf7, - 0x76, 0x6c, 0xc2, 0xb1, 0xac, 0x6e, 0x3d, 0x29, 0xeb, 0x0c, 0xed, 0x7c, - 0x3e, 0xc7, 0x8b, 0x3e, 0x5d, 0x38, 0xad, 0x4e, 0xdf, 0x22, 0xeb, 0xd4, - 0x3b, 0x70, 0x92, 0xf6, 0xda, 0x9f, 0x5b, 0xca, 0xd8, 0x2f, 0x31, 0xdf, - 0x6f, 0x85, 0x59, 0xaf, 0xee, 0x3a, 0x05, 0x27, 0xf6, 0x09, 0xc7, 0x5a, - 0x8a, 0xbb, 0xa8, 0xa7, 0xce, 0xb4, 0x8a, 0xeb, 0xc7, 0xd6, 0xe0, 0xf4, - 0xce, 0x22, 0xe7, 0x7a, 0x35, 0x6e, 0x7d, 0x86, 0x9c, 0xab, 0x67, 0x16, - 0x39, 0x17, 0xb9, 0x5c, 0xec, 0x41, 0xc5, 0x8b, 0x68, 0x21, 0x41, 0x5e, - 0x21, 0xfc, 0x22, 0x8c, 0xa7, 0xf2, 0x1d, 0xb8, 0x25, 0xdd, 0x84, 0x71, - 0xf2, 0xad, 0x1c, 0xf1, 0x22, 0x97, 0x67, 0x5c, 0x19, 0x6d, 0xe4, 0xa5, - 0xf1, 0x5a, 0xc0, 0x4b, 0x77, 0xef, 0xad, 0xa5, 0x2d, 0x27, 0xbb, 0x25, - 0x4f, 0x23, 0xff, 0xcd, 0x4b, 0xac, 0x56, 0x98, 0xb7, 0xfe, 0xaf, 0x7a, - 0xc9, 0x4d, 0x83, 0xba, 0x82, 0xaf, 0x65, 0x35, 0xfc, 0x55, 0xfb, 0x76, - 0x25, 0xd9, 0xe0, 0xbe, 0x83, 0x4a, 0xdf, 0xb6, 0x70, 0x92, 0x63, 0xba, - 0x37, 0x2b, 0x76, 0x49, 0x19, 0xcc, 0xd1, 0x8f, 0x19, 0xf5, 0xd0, 0xea, - 0x35, 0x39, 0xd7, 0xc4, 0xd8, 0xc1, 0xf8, 0x6b, 0xa7, 0xc8, 0xa3, 0x5a, - 0xbb, 0x5b, 0x55, 0x8f, 0xbc, 0x9f, 0x67, 0x68, 0xaa, 0xf8, 0x58, 0x0a, - 0x15, 0x69, 0xbf, 0x55, 0x27, 0xf5, 0x97, 0x6c, 0x60, 0x3c, 0x68, 0x5d, - 0xff, 0xb2, 0xf0, 0xfb, 0x39, 0x11, 0x6d, 0x0a, 0x1b, 0xb0, 0xce, 0xd6, - 0x19, 0x03, 0xd7, 0x38, 0xbd, 0x9c, 0x87, 0x51, 0x7b, 0x03, 0xee, 0xb2, - 0x5b, 0xa7, 0x1e, 0xa7, 0x6d, 0xe1, 0xce, 0x0d, 0xe8, 0xe4, 0xb3, 0x91, - 0x4c, 0xf3, 0x74, 0x2f, 0x75, 0x7d, 0x7c, 0x76, 0xcc, 0x5d, 0xf7, 0x97, - 0x33, 0xe4, 0xa3, 0xe4, 0xd7, 0x5f, 0xcd, 0xb4, 0x26, 0x87, 0xd4, 0x1e, - 0x05, 0x73, 0x24, 0x97, 0x4c, 0x90, 0x53, 0x05, 0xf0, 0x99, 0xb4, 0x45, - 0x1f, 0x00, 0x6d, 0xae, 0x83, 0x79, 0xc5, 0x13, 0x4e, 0xbd, 0x19, 0x35, - 0x44, 0x3f, 0xeb, 0x0b, 0x4b, 0xf1, 0x14, 0x63, 0x6f, 0xf3, 0xb5, 0x7a, - 0xf0, 0x39, 0x68, 0xf0, 0x99, 0x3f, 0x75, 0x1a, 0xcc, 0x1a, 0x3c, 0x30, - 0x12, 0x4d, 0xdc, 0xc4, 0x38, 0xdb, 0x79, 0xad, 0x7e, 0xf4, 0x14, 0x63, - 0xe0, 0x7c, 0xd3, 0x96, 0xf3, 0x26, 0xe4, 0x3b, 0x01, 0xd7, 0xce, 0x4f, - 0xdb, 0xe2, 0x27, 0x3a, 0x71, 0x33, 0x84, 0xcf, 0xd1, 0xce, 0xdf, 0xb7, - 0x63, 0x98, 0x24, 0xdf, 0xf8, 0x2c, 0xfd, 0xe3, 0x8c, 0x1d, 0x49, 0x5d, - 0xa3, 0xea, 0xd8, 0x40, 0xff, 0x78, 0xd7, 0x4e, 0xd0, 0x77, 0x3e, 0xc6, - 0xab, 0x8d, 0xfe, 0x10, 0x63, 0x1d, 0x8d, 0x7e, 0x10, 0x72, 0xcf, 0x95, - 0x8e, 0x65, 0x9a, 0xbb, 0x1f, 0x42, 0x73, 0xec, 0x66, 0xa5, 0x8e, 0x79, - 0x6a, 0x10, 0xf7, 0x14, 0x6e, 0xc0, 0x89, 0x6c, 0x64, 0x9a, 0x39, 0xf9, - 0xc6, 0xa5, 0x0a, 0xee, 0x20, 0x67, 0x5b, 0x5f, 0xad, 0xb4, 0x4e, 0x3d, - 0xa5, 0x44, 0x68, 0x93, 0x8c, 0x97, 0xf4, 0xcf, 0xcf, 0xb2, 0xcc, 0x99, - 0x6c, 0x35, 0x36, 0x8c, 0xd8, 0xe8, 0xcf, 0x54, 0xa0, 0x6a, 0xa7, 0x1f, - 0xf7, 0x8f, 0xe9, 0xc8, 0x64, 0x64, 0x1d, 0xd9, 0x6f, 0xd5, 0x12, 0x37, - 0x46, 0x89, 0x0d, 0x2f, 0x2d, 0x01, 0xa6, 0xf7, 0xae, 0xc1, 0x81, 0x9d, - 0x3a, 0xe3, 0x5d, 0xd1, 0x3e, 0x82, 0x71, 0x97, 0x93, 0xa7, 0x84, 0x93, - 0x57, 0x99, 0x12, 0xfb, 0xa2, 0x3d, 0x8f, 0x50, 0x07, 0xb7, 0x15, 0xc4, - 0xee, 0x12, 0x9c, 0xa3, 0x30, 0x06, 0x69, 0x23, 0xfb, 0xec, 0x26, 0xe6, - 0xe6, 0x01, 0x58, 0xb4, 0x11, 0x4b, 0xde, 0x53, 0xa5, 0x8d, 0x58, 0xb4, - 0x11, 0x8b, 0x36, 0x62, 0xd1, 0x46, 0xac, 0xfc, 0x52, 0xe6, 0x4c, 0x3a, - 0xc6, 0xd9, 0xe6, 0xb6, 0x51, 0x72, 0xf7, 0xa0, 0xd8, 0x4a, 0x0c, 0x5f, - 0xcf, 0xf4, 0x2b, 0xda, 0x9d, 0x37, 0x60, 0x24, 0x7b, 0x23, 0x2f, 0x05, - 0xb7, 0xd2, 0x56, 0x1e, 0xcd, 0x89, 0xed, 0xe9, 0xee, 0xef, 0xd3, 0x3c, - 0x9b, 0xdf, 0x33, 0x1b, 0xd5, 0xe2, 0x03, 0x8c, 0x45, 0xee, 0x7d, 0x39, - 0x73, 0xec, 0xc7, 0x68, 0xfe, 0x82, 0x5f, 0x7c, 0x4f, 0xce, 0xab, 0xb4, - 0xcb, 0x6f, 0xc5, 0x74, 0x30, 0x0f, 0x90, 0x73, 0xee, 0x32, 0x4e, 0x19, - 0x57, 0x71, 0x4c, 0x55, 0x83, 0x9b, 0xf0, 0xf5, 0x41, 0x9d, 0xb1, 0xca, - 0xc0, 0x93, 0x39, 0x89, 0xe5, 0xe2, 0xdf, 0x32, 0x0f, 0xe2, 0xeb, 0x1e, - 0xd4, 0xb4, 0x7b, 0x11, 0x70, 0xfd, 0xbc, 0x39, 0xbc, 0x43, 0xb1, 0xe9, - 0x3b, 0xba, 0x9c, 0x03, 0x9d, 0x0a, 0xeb, 0x0d, 0x38, 0xbd, 0xbb, 0x1d, - 0xff, 0x6d, 0xa7, 0x87, 0x3c, 0xc0, 0x59, 0xfa, 0x52, 0x5c, 0x4f, 0x4e, - 0x2b, 0xd1, 0xd8, 0x2c, 0xa5, 0x1d, 0xf7, 0x90, 0xfb, 0x6f, 0x18, 0x8c, - 0x74, 0x33, 0x66, 0x1b, 0xb7, 0x28, 0x4b, 0x51, 0xc5, 0x1c, 0xa0, 0x8d, - 0x39, 0xc0, 0x83, 0xc4, 0x80, 0xaf, 0x66, 0xbc, 0x68, 0x59, 0x2c, 0xbf, - 0x4d, 0xa6, 0xbb, 0x6b, 0x3b, 0x2f, 0x90, 0xa3, 0xce, 0x37, 0x3b, 0xe4, - 0x2c, 0x8e, 0x72, 0xf6, 0xba, 0x29, 0x24, 0x28, 0x7f, 0xcc, 0xcd, 0x2f, - 0x12, 0x38, 0x98, 0x27, 0x6e, 0x70, 0xdc, 0xaf, 0xb4, 0xfd, 0x84, 0xf9, - 0xb0, 0x70, 0x7b, 0x13, 0x13, 0x39, 0x97, 0xff, 0x47, 0xea, 0x88, 0x19, - 0xd9, 0x41, 0xbd, 0xcb, 0xaf, 0x9a, 0x78, 0x64, 0xaf, 0xf8, 0xb0, 0x89, - 0xf6, 0x21, 0x3d, 0x7c, 0x9b, 0x1a, 0x0d, 0xae, 0xe3, 0xb3, 0x05, 0x9c, - 0xcf, 0xc7, 0x33, 0x32, 0x8f, 0x1a, 0x5a, 0x18, 0x9b, 0xdf, 0x9c, 0xd0, - 0xb1, 0x88, 0x71, 0xfa, 0x9d, 0x89, 0x18, 0x96, 0x32, 0x66, 0x3b, 0xcc, - 0x1f, 0x12, 0x19, 0xf1, 0x45, 0xf2, 0x81, 0x09, 0x8d, 0x71, 0x56, 0xd6, - 0x87, 0x9e, 0xc0, 0xd8, 0x6a, 0x0d, 0xfb, 0xdc, 0xf3, 0x7c, 0x7e, 0xab, - 0x81, 0x58, 0xd9, 0x39, 0xe0, 0xc7, 0xa7, 0x87, 0x36, 0xe3, 0xf5, 0xc5, - 0xc2, 0x95, 0xd6, 0x38, 0xa2, 0x9f, 0xc7, 0x29, 0x73, 0x8c, 0xbc, 0x78, - 0x94, 0x79, 0xd7, 0xc2, 0x7d, 0x6b, 0xf0, 0xc9, 0x5d, 0x17, 0xf2, 0xb4, - 0x33, 0x71, 0xeb, 0x6e, 0xda, 0xc4, 0xfa, 0x00, 0x6d, 0xa2, 0x96, 0x36, - 0x61, 0x67, 0xa2, 0xc9, 0x02, 0x6d, 0x22, 0x46, 0xdc, 0xc8, 0x0e, 0x48, - 0x39, 0xf7, 0x9d, 0x99, 0xbb, 0xe4, 0xdd, 0x65, 0x83, 0xbe, 0xb3, 0x75, - 0xc0, 0xd9, 0xec, 0x65, 0xbc, 0x79, 0xa4, 0xa3, 0x89, 0xd8, 0x72, 0x23, - 0xf6, 0x0c, 0x36, 0xa1, 0x85, 0x31, 0x63, 0x61, 0x1a, 0x77, 0x84, 0xa1, - 0xce, 0x0f, 0x23, 0xb2, 0xe1, 0x1d, 0x44, 0xa7, 0xef, 0x56, 0x5a, 0x8f, - 0xbe, 0xa8, 0x44, 0x36, 0xfe, 0x84, 0x36, 0x7c, 0x56, 0x91, 0xb6, 0x9b, - 0x70, 0x35, 0xfd, 0xe4, 0x2a, 0xfa, 0x84, 0xc6, 0x5c, 0x52, 0x63, 0xdd, - 0xfe, 0x41, 0x1f, 0xe6, 0x33, 0xd7, 0x93, 0xb3, 0xca, 0xb1, 0x31, 0x2f, - 0xb2, 0x3b, 0xf5, 0xa9, 0x47, 0xd0, 0x08, 0x63, 0xec, 0x46, 0x6c, 0x1d, - 0xd4, 0x10, 0xe5, 0xbd, 0xbe, 0x9d, 0x0b, 0xd0, 0x4c, 0xfb, 0xd6, 0xe8, - 0xa7, 0xbd, 0x83, 0x2a, 0x16, 0x8c, 0xdd, 0x80, 0x1d, 0x83, 0x0a, 0xee, - 0x8b, 0x2a, 0x68, 0x19, 0x91, 0x1c, 0x2c, 0x86, 0xa7, 0x32, 0xc2, 0x15, - 0xa1, 0xb4, 0x5c, 0x4b, 0x8e, 0x4c, 0xee, 0xf9, 0x93, 0x9c, 0xcc, 0xb9, - 0xe8, 0x53, 0x7e, 0x53, 0xa6, 0x1d, 0x9f, 0xdb, 0xd9, 0x80, 0xab, 0x76, - 0xeb, 0xd6, 0x69, 0xc5, 0x59, 0x7a, 0x80, 0x7c, 0xde, 0xaf, 0x16, 0xe7, - 0xfc, 0xc1, 0xc1, 0x67, 0x19, 0x2f, 0x7e, 0xe2, 0x04, 0xf5, 0xa5, 0xe8, - 0x8b, 0x27, 0xb1, 0xb6, 0xa3, 0x1d, 0x6b, 0xf7, 0x8a, 0xbe, 0x1c, 0xe6, - 0x87, 0xcc, 0xfd, 0x26, 0xa7, 0xf0, 0x0e, 0xfd, 0x77, 0x11, 0x39, 0xed, - 0x52, 0xc6, 0x89, 0x37, 0x16, 0x9b, 0xd4, 0x9f, 0xee, 0x9e, 0xf5, 0x9b, - 0x67, 0x9a, 0xa8, 0x1d, 0xd4, 0x19, 0x67, 0x4c, 0xcc, 0xda, 0x2b, 0xed, - 0x99, 0xb8, 0x67, 0x50, 0x4f, 0x3d, 0xcd, 0xb9, 0x14, 0xbb, 0x11, 0xcc, - 0xae, 0x61, 0xec, 0x3f, 0x39, 0x29, 0x38, 0xd5, 0x89, 0x13, 0xcc, 0x03, - 0xde, 0x7c, 0x2c, 0xda, 0xfd, 0x33, 0xe6, 0x74, 0xef, 0x50, 0x46, 0x96, - 0xfd, 0x1b, 0xe0, 0xbc, 0x56, 0xa4, 0xf5, 0x8d, 0xff, 0x8c, 0x28, 0xfd, - 0xbb, 0x0b, 0xb5, 0xd4, 0xc9, 0x81, 0xc1, 0x95, 0xf0, 0xd3, 0x16, 0x1e, - 0xc9, 0x88, 0xdd, 0x10, 0xbf, 0x77, 0x7e, 0x02, 0x5b, 0xf7, 0x17, 0xf3, - 0xbc, 0x7b, 0x06, 0x36, 0xd1, 0xc6, 0x85, 0xb3, 0xc7, 0x68, 0xef, 0x98, - 0xe7, 0x43, 0xb2, 0x9e, 0x18, 0x91, 0x58, 0x4e, 0xcc, 0x7c, 0xd4, 0x20, - 0xae, 0xd6, 0x47, 0xc2, 0x2d, 0xaa, 0x95, 0x60, 0x5e, 0x17, 0xbe, 0x0f, - 0xd2, 0xbe, 0x85, 0x75, 0x4b, 0x36, 0x61, 0x4f, 0xd6, 0x8b, 0xaa, 0xc5, - 0x1e, 0xe2, 0xb1, 0x60, 0x94, 0x15, 0x94, 0xe7, 0x6b, 0x21, 0x7e, 0x22, - 0xf3, 0xeb, 0xc1, 0x99, 0x78, 0xf3, 0x86, 0xac, 0xfc, 0x96, 0x05, 0x73, - 0xbe, 0xcf, 0xa2, 0x83, 0x73, 0x2f, 0xfe, 0x98, 0xc0, 0x3d, 0x63, 0xc2, - 0xd5, 0xc8, 0xe7, 0x6c, 0x3f, 0xfe, 0x3a, 0x2b, 0x9c, 0x6e, 0x33, 0xee, - 0x69, 0x2f, 0xe7, 0x6e, 0x62, 0x77, 0xad, 0xd3, 0x1e, 0x34, 0x93, 0x93, - 0xe9, 0xb9, 0xac, 0x1a, 0xb1, 0x52, 0x88, 0xf4, 0xa7, 0x20, 0x71, 0xa2, - 0xd5, 0xe2, 0x0c, 0x53, 0x36, 0xb9, 0xa5, 0xed, 0x41, 0x1d, 0x7d, 0x5c, - 0x7e, 0x44, 0xae, 0x9d, 0xf6, 0xf3, 0xac, 0x5d, 0x0d, 0xcd, 0xb5, 0x75, - 0x2f, 0x96, 0x16, 0x2c, 0xe2, 0xed, 0x52, 0xb4, 0x3d, 0x16, 0xc0, 0x35, - 0xe4, 0x26, 0x57, 0xa7, 0x9f, 0x70, 0x66, 0x11, 0x7b, 0xdb, 0x46, 0xa2, - 0xc1, 0x23, 0xe4, 0x81, 0x07, 0x96, 0xfc, 0xd4, 0xf1, 0x98, 0xae, 0x5f, - 0x68, 0xf4, 0x00, 0xe7, 0x33, 0x1d, 0xfa, 0xd4, 0x0e, 0x04, 0x90, 0x20, - 0x7e, 0x5e, 0x99, 0x69, 0x40, 0xfb, 0xee, 0x7e, 0xce, 0x7f, 0x10, 0x57, - 0xf2, 0xfb, 0x62, 0xc6, 0x37, 0x8d, 0xd8, 0xaa, 0xc9, 0xe7, 0x82, 0xd8, - 0x4b, 0x98, 0x7e, 0xe4, 0x2c, 0xbd, 0xb3, 0xdd, 0xba, 0x63, 0x36, 0xf5, - 0xd5, 0x42, 0x5c, 0x5e, 0x9a, 0x89, 0x6c, 0xbc, 0x59, 0x51, 0xb0, 0xb2, - 0xdd, 0x60, 0xdb, 0x01, 0xc4, 0x32, 0xb2, 0x36, 0x70, 0xe8, 0xa1, 0x3a, - 0x58, 0xad, 0x01, 0xda, 0xe9, 0x11, 0x45, 0xd6, 0x35, 0x44, 0x6f, 0x4d, - 0xb8, 0x8a, 0x7c, 0x44, 0x23, 0x66, 0xc7, 0x0a, 0xa2, 0x43, 0x60, 0x6d, - 0x6e, 0x0d, 0xf6, 0x0c, 0x8b, 0x7f, 0x0a, 0x76, 0x3a, 0x4e, 0xe5, 0xe2, - 0xa8, 0xf1, 0x36, 0x75, 0xf8, 0xc6, 0x84, 0x60, 0x90, 0x82, 0x79, 0xb4, - 0x63, 0x55, 0x97, 0x58, 0x2b, 0xb8, 0x15, 0xa6, 0xdf, 0x76, 0xe0, 0xd3, - 0x8c, 0x6d, 0xd5, 0x9c, 0x83, 0x55, 0x4b, 0x9a, 0xe8, 0xbf, 0xc4, 0xc9, - 0x89, 0x20, 0xaf, 0x10, 0x8e, 0xef, 0x6f, 0xe4, 0xa5, 0xf1, 0x5a, 0xc0, - 0x4b, 0xe7, 0x3d, 0x15, 0x67, 0xf6, 0x93, 0x33, 0xed, 0x15, 0x0e, 0x22, - 0x3e, 0xe8, 0xc7, 0xd3, 0x13, 0x20, 0x8f, 0x31, 0xc8, 0x43, 0x04, 0xff, - 0x64, 0x9e, 0x98, 0xc7, 0x0c, 0xc6, 0x11, 0x1d, 0x29, 0x72, 0x8e, 0x93, - 0xc3, 0x7a, 0xcf, 0x5a, 0x44, 0xb5, 0xbf, 0x26, 0x7e, 0x9d, 0x1a, 0x6d, - 0xc7, 0x74, 0x96, 0xb8, 0xb5, 0xb8, 0x1d, 0x6f, 0xe7, 0x36, 0xd1, 0xff, - 0x55, 0x9c, 0x25, 0x66, 0x69, 0x73, 0x05, 0xd7, 0x05, 0x43, 0xfd, 0xb4, - 0xd7, 0x0e, 0x59, 0x03, 0x55, 0xe2, 0xc4, 0xac, 0x6b, 0xd2, 0xcf, 0x3a, - 0xb5, 0x3a, 0x73, 0x2a, 0x35, 0x81, 0x0c, 0x31, 0xcb, 0xce, 0xca, 0x7c, - 0x6d, 0xc6, 0x56, 0xe2, 0xd5, 0xd6, 0x9c, 0xd8, 0x37, 0x6d, 0x7a, 0x50, - 0x0f, 0x16, 0x68, 0xdb, 0xea, 0x5e, 0x91, 0x61, 0xa2, 0x8f, 0xb1, 0xfd, - 0x33, 0x1d, 0x26, 0x76, 0xe4, 0x24, 0x0e, 0x0a, 0x07, 0xd3, 0x98, 0x97, - 0x24, 0xd1, 0x43, 0x9c, 0x7a, 0xdb, 0xee, 0xc4, 0x0a, 0xe2, 0xd4, 0x2f, - 0x98, 0xa7, 0xdc, 0x49, 0x9c, 0x7a, 0xc3, 0x2e, 0xe2, 0xd4, 0xcd, 0x13, - 0x62, 0x0b, 0x45, 0x5e, 0x7e, 0xc2, 0x6e, 0x6b, 0x90, 0xdf, 0x39, 0xab, - 0x36, 0x7f, 0x57, 0x5c, 0x58, 0x85, 0x97, 0x86, 0xcb, 0x7b, 0xc5, 0x91, - 0xe4, 0xed, 0xe4, 0xcc, 0x47, 0x47, 0xcb, 0x9c, 0xf7, 0xb8, 0x9b, 0x5b, - 0xcf, 0x32, 0xcb, 0xfb, 0x96, 0xe5, 0xfd, 0x06, 0x0b, 0x5f, 0x5d, 0x22, - 0x3c, 0x53, 0xd6, 0x81, 0x2a, 0xc8, 0x27, 0xbb, 0x31, 0xbe, 0xf3, 0x3d, - 0x3c, 0x32, 0xa8, 0xde, 0x5c, 0xc3, 0xd8, 0x7a, 0x8b, 0xb2, 0x19, 0x9e, - 0xb8, 0xbc, 0x47, 0x2a, 0x6b, 0xe5, 0xcc, 0x5d, 0x26, 0xb3, 0xe8, 0xdb, - 0x57, 0x83, 0x43, 0x41, 0xc7, 0x79, 0xda, 0x98, 0x27, 0x3f, 0x13, 0x20, - 0xb8, 0x19, 0xa8, 0xa0, 0x2f, 0xdc, 0xfc, 0x5b, 0xbf, 0xdd, 0x58, 0xde, - 0x3b, 0xd8, 0x88, 0xbb, 0x76, 0x3d, 0x8c, 0x9e, 0x5d, 0x7f, 0x8b, 0x4f, - 0x0e, 0x2d, 0xec, 0x9f, 0xe7, 0x71, 0x9c, 0xab, 0xdb, 0xa7, 0x70, 0x2a, - 0xce, 0xd8, 0x18, 0x52, 0xf0, 0xbd, 0xab, 0x16, 0x8a, 0x1c, 0xfe, 0xbd, - 0xef, 0x68, 0xae, 0xbc, 0x5b, 0x4b, 0x3e, 0x92, 0x98, 0xc3, 0xf1, 0x53, - 0xf6, 0x8a, 0xfa, 0xd2, 0xbb, 0xc2, 0x7f, 0x40, 0x5b, 0x3f, 0x16, 0x19, - 0xfc, 0x2b, 0xcb, 0x78, 0xcd, 0x49, 0xae, 0x96, 0x7a, 0x15, 0xa5, 0x36, - 0xfe, 0x96, 0x9c, 0x90, 0xbc, 0xd0, 0xe0, 0xff, 0x91, 0xeb, 0x44, 0x3e, - 0x9f, 0x95, 0xe5, 0xbf, 0xe4, 0x24, 0xbb, 0xe5, 0xbb, 0x94, 0x59, 0xc7, - 0x67, 0x52, 0xae, 0xfc, 0xec, 0xf9, 0x92, 0x9c, 0x4a, 0x68, 0x0d, 0x45, - 0x39, 0x9f, 0xa6, 0x9c, 0x33, 0x8b, 0x93, 0x50, 0xaf, 0x9d, 0x29, 0xab, - 0xdc, 0xee, 0xff, 0x3a, 0x2f, 0xab, 0x58, 0xee, 0x6f, 0xe6, 0xc8, 0xbe, - 0x80, 0x7a, 0xed, 0xcc, 0x75, 0xf2, 0x0a, 0xfa, 0x6f, 0x34, 0xb8, 0xd5, - 0x5d, 0x9f, 0x36, 0xb0, 0xf6, 0xe2, 0x1c, 0x4b, 0xb0, 0x03, 0xe3, 0x76, - 0xb0, 0x94, 0x53, 0xc9, 0x2d, 0x13, 0x5f, 0x66, 0xce, 0xf6, 0x94, 0x1d, - 0xe9, 0x5a, 0xa7, 0xb4, 0x26, 0x17, 0x31, 0xce, 0xa0, 0x5e, 0xd6, 0xb0, - 0x13, 0xee, 0xef, 0xf9, 0xe5, 0xa3, 0x09, 0xe4, 0x69, 0x8f, 0xaf, 0xd8, - 0x91, 0x0d, 0xa7, 0xdc, 0xfd, 0x3b, 0x13, 0x2f, 0xe7, 0x5f, 0x2d, 0xed, - 0x33, 0x95, 0x7f, 0x4f, 0x6c, 0xe6, 0x1a, 0xaa, 0xcc, 0xbf, 0x9c, 0xb1, - 0x6e, 0x90, 0xb5, 0x0a, 0xcb, 0xa2, 0x9f, 0xf7, 0x66, 0xac, 0xb0, 0x8a, - 0xeb, 0x90, 0x0a, 0xc9, 0xbe, 0xc4, 0xd6, 0xd2, 0x6f, 0x52, 0xb1, 0xde, - 0xef, 0x58, 0x13, 0x02, 0x8c, 0xd2, 0x39, 0xb6, 0x18, 0xac, 0xc9, 0x2b, - 0xc8, 0xc5, 0x64, 0xbd, 0x01, 0xd6, 0x6c, 0x53, 0x43, 0x48, 0x3f, 0xcc, - 0x71, 0xfb, 0x30, 0x87, 0xf9, 0x54, 0x7c, 0x61, 0x6b, 0x77, 0xbb, 0x3a, - 0x57, 0x70, 0x36, 0x98, 0x54, 0x63, 0x12, 0x07, 0x50, 0x99, 0x96, 0xb3, - 0x26, 0x56, 0x97, 0x9f, 0x98, 0xba, 0x98, 0xd8, 0x52, 0x11, 0x85, 0xf7, - 0xbe, 0xbc, 0x17, 0xc1, 0x85, 0xbf, 0x70, 0x7e, 0x18, 0x8a, 0x61, 0xdb, - 0x64, 0xb9, 0x0f, 0x06, 0xfe, 0x7b, 0xe1, 0xd2, 0x8c, 0xb3, 0x2c, 0xf3, - 0x3d, 0x27, 0x39, 0x47, 0xda, 0x2e, 0xca, 0xfd, 0xe8, 0xbe, 0x4a, 0x1f, - 0xa5, 0xaf, 0xcd, 0x1a, 0x51, 0x15, 0x5b, 0x8d, 0x89, 0x39, 0xf2, 0x9b, - 0x3f, 0xf7, 0xb8, 0x67, 0xd3, 0x65, 0x0e, 0xe4, 0xfd, 0xf1, 0x04, 0xee, - 0x93, 0xf7, 0x30, 0x19, 0xb3, 0xee, 0xcd, 0xbb, 0xef, 0x77, 0x42, 0x7e, - 0x17, 0xf1, 0xde, 0x7c, 0x51, 0x7f, 0x0f, 0xe5, 0x03, 0xe4, 0xdd, 0x01, - 0xcb, 0x6b, 0x6e, 0x80, 0x4f, 0x97, 0x33, 0x67, 0x65, 0x5d, 0xfe, 0xdf, - 0x73, 0x24, 0x97, 0xff, 0x2a, 0xfd, 0xc9, 0xbb, 0x50, 0x3e, 0x5b, 0xf2, - 0xae, 0xa2, 0x52, 0xfc, 0x7c, 0xc6, 0x7d, 0xef, 0x5d, 0x35, 0xd7, 0xd1, - 0x2f, 0x67, 0xbb, 0xef, 0xeb, 0x89, 0x7e, 0x42, 0xa6, 0xe5, 0xcc, 0xd6, - 0x03, 0xb4, 0x91, 0xde, 0x39, 0xa5, 0x77, 0x0f, 0xba, 0xee, 0x20, 0x8e, - 0x2c, 0x22, 0xb7, 0x5a, 0xac, 0x44, 0xb4, 0x55, 0x4a, 0x37, 0xeb, 0x51, - 0x4f, 0x05, 0x91, 0xa1, 0xb8, 0xbf, 0xbd, 0xeb, 0xa3, 0x8c, 0xfd, 0x76, - 0xab, 0xe6, 0x53, 0x7f, 0x5e, 0x3a, 0x7b, 0x2d, 0x7b, 0xf1, 0x29, 0x3c, - 0x6f, 0xcf, 0xc1, 0xd4, 0x6f, 0xc9, 0x3d, 0xbf, 0x66, 0xfd, 0x4f, 0x41, - 0x62, 0x88, 0x4f, 0x8f, 0x6c, 0x8c, 0x7b, 0x22, 0xeb, 0xa7, 0xe9, 0xd3, - 0x85, 0xb8, 0x9e, 0xfa, 0x1a, 0xdb, 0xf8, 0x3e, 0xb9, 0x85, 0x3d, 0x43, - 0x7e, 0x51, 0x56, 0x6b, 0x4f, 0x85, 0x7a, 0xc6, 0x29, 0xbe, 0x77, 0x2d, - 0xbf, 0xfb, 0xbb, 0x06, 0xc1, 0xb4, 0xe5, 0x84, 0x28, 0x73, 0xbe, 0x19, - 0xd9, 0x53, 0xaf, 0xea, 0xd9, 0xcf, 0xab, 0x9b, 0xb1, 0x56, 0x8e, 0x7c, - 0x98, 0x11, 0xed, 0xd3, 0xb4, 0x8f, 0x76, 0x57, 0x46, 0x32, 0x56, 0x81, - 0x8f, 0x3a, 0xd3, 0xc6, 0xf1, 0x41, 0xd6, 0x28, 0x59, 0xce, 0xdd, 0xe3, - 0x97, 0xf7, 0x77, 0x98, 0x63, 0xdb, 0xf2, 0xbb, 0xa6, 0x6e, 0x33, 0xa5, - 0x7d, 0x24, 0xe6, 0xc8, 0x8c, 0x97, 0xf7, 0xc8, 0x6f, 0xc8, 0x55, 0x07, - 0x70, 0xaf, 0x2d, 0xeb, 0x0e, 0xff, 0x3f, 0x45, 0x18, 0xff, 0x64, 0x3c, - 0x59, 0x00, 0x00, 0x00 }; + 0xa5, 0xbc, 0x0d, 0x74, 0x1c, 0xe5, 0x95, 0x26, 0xfc, 0x54, 0x75, 0xb7, + 0xd4, 0x92, 0x5a, 0x52, 0x49, 0x6e, 0x8b, 0x36, 0x68, 0x70, 0xb5, 0x55, + 0x2d, 0x0b, 0x4b, 0x40, 0xb5, 0x24, 0x3b, 0xed, 0x6c, 0x83, 0x3b, 0xb6, + 0x6c, 0x64, 0x63, 0x40, 0x36, 0x06, 0xc4, 0xb7, 0xfe, 0x3e, 0x7a, 0xfc, + 0x03, 0x86, 0x38, 0x19, 0x91, 0xcd, 0xce, 0x0a, 0xd6, 0x59, 0x55, 0xe4, + 0x3f, 0xd9, 0x6e, 0x75, 0x4b, 0x42, 0xfe, 0xe1, 0xec, 0x9c, 0xa5, 0x2d, + 0xcb, 0x96, 0x21, 0xad, 0x16, 0x24, 0x6c, 0xc6, 0x39, 0x27, 0x09, 0x1a, + 0x63, 0x83, 0x0d, 0x18, 0xc8, 0x24, 0xf9, 0x86, 0xc9, 0xd9, 0x5d, 0x34, + 0xc6, 0xfc, 0x19, 0x70, 0x1c, 0x92, 0xc9, 0x9a, 0x19, 0x4c, 0xed, 0x73, + 0xab, 0xd5, 0xb6, 0xec, 0x30, 0xc9, 0xcc, 0x59, 0x9d, 0xd3, 0xa7, 0xab, + 0xab, 0xde, 0x9f, 0xfb, 0xde, 0xf7, 0xde, 0xe7, 0x3e, 0xf7, 0x7d, 0xdf, + 0x92, 0x0e, 0x14, 0x63, 0xf2, 0xaf, 0x94, 0x9f, 0x9b, 0x9a, 0x3b, 0xd6, + 0xce, 0x0d, 0xdf, 0x34, 0x4f, 0x7e, 0xbb, 0xcb, 0x0b, 0xdc, 0xf8, 0xb2, + 0xbf, 0x28, 0x22, 0x57, 0xdf, 0xd2, 0xbf, 0xb4, 0xe0, 0xbf, 0xf0, 0x17, + 0x41, 0x50, 0xe1, 0x57, 0xfd, 0xe4, 0x4f, 0x17, 0xa0, 0xe5, 0xfb, 0x97, + 0x0f, 0xbc, 0x6a, 0xd4, 0xb8, 0x77, 0xa1, 0x01, 0xaf, 0x2b, 0xba, 0xaa, + 0x7d, 0xad, 0x01, 0xc4, 0x32, 0xf5, 0xfa, 0x22, 0x5c, 0xb4, 0x2d, 0xbf, + 0x1b, 0x72, 0xff, 0xcf, 0xa2, 0x9f, 0x3f, 0xf5, 0x93, 0xaf, 0x04, 0xcf, + 0xa7, 0x5d, 0xf0, 0x6a, 0x51, 0x0b, 0x5a, 0x2d, 0xbc, 0xd5, 0xac, 0xf3, + 0x57, 0xb3, 0xb7, 0xa9, 0x28, 0xcb, 0xb7, 0x15, 0x0c, 0xa4, 0x11, 0xd4, + 0x2c, 0x04, 0xeb, 0x2c, 0x20, 0xee, 0x8e, 0x22, 0x5e, 0x18, 0xf5, 0xa2, + 0xc0, 0x28, 0x40, 0x5c, 0xeb, 0xd4, 0xb7, 0x34, 0x03, 0x0b, 0x13, 0x5e, + 0xfd, 0x74, 0x06, 0x58, 0x9b, 0xf0, 0x62, 0xc2, 0xe5, 0xd3, 0xdf, 0xc9, + 0x44, 0xca, 0x72, 0xfa, 0x88, 0xc1, 0x65, 0x20, 0xae, 0x46, 0xe5, 0x3e, + 0xf4, 0x45, 0x19, 0xa9, 0x0b, 0x6c, 0x4b, 0x7d, 0x5b, 0x7f, 0x37, 0x11, + 0xd4, 0xb6, 0xa1, 0x3e, 0x30, 0x84, 0x42, 0xc4, 0xfd, 0xc1, 0x3a, 0xe0, + 0xf3, 0x8b, 0x3b, 0x53, 0x0a, 0x3c, 0xc6, 0x34, 0xb4, 0xec, 0x07, 0x76, + 0xa4, 0x82, 0x31, 0x83, 0xc3, 0xeb, 0x19, 0x93, 0xba, 0x41, 0x2d, 0xcd, + 0xe7, 0x5b, 0x52, 0xc0, 0xd6, 0xd4, 0x34, 0x6c, 0xeb, 0xb3, 0xf1, 0xa2, + 0x59, 0xa3, 0x1d, 0x60, 0x0f, 0xdd, 0xce, 0xf3, 0x69, 0xb0, 0xd2, 0xf2, + 0xfc, 0x03, 0xfb, 0x27, 0xb3, 0x35, 0x3c, 0x3b, 0xe6, 0xc7, 0x0b, 0x63, + 0x15, 0xd8, 0xd1, 0x57, 0x81, 0xed, 0x7d, 0x75, 0x50, 0x0d, 0x1b, 0x75, + 0xe1, 0x3a, 0x14, 0xcc, 0xb7, 0xf1, 0x8e, 0xd9, 0x80, 0xad, 0x6c, 0xf8, + 0xcd, 0x86, 0x2a, 0xac, 0xd1, 0xaa, 0xb1, 0xc5, 0xf8, 0x0a, 0x72, 0x63, + 0xfd, 0xfc, 0x62, 0x2a, 0x85, 0xb8, 0x27, 0xea, 0x56, 0x55, 0xe3, 0x56, + 0x9c, 0xdb, 0x1d, 0xc5, 0x27, 0xbb, 0xb1, 0xba, 0x0c, 0xb6, 0x9d, 0x09, + 0x87, 0xda, 0x36, 0x2a, 0x9a, 0xfe, 0x4c, 0x86, 0x02, 0xad, 0x74, 0xb3, + 0x3d, 0xe8, 0x43, 0x99, 0xa9, 0x53, 0xc1, 0xfe, 0x52, 0xec, 0x37, 0x25, + 0xb2, 0x04, 0xf0, 0x93, 0xd9, 0x7f, 0x41, 0x7b, 0xc8, 0x8d, 0x69, 0x6b, + 0xea, 0x2d, 0xca, 0xa4, 0x53, 0x9e, 0x6a, 0xfc, 0x60, 0x2c, 0x80, 0xef, + 0x53, 0xb6, 0xe7, 0xc6, 0x44, 0xc6, 0xe0, 0x3e, 0x0b, 0x15, 0x18, 0xee, + 0xab, 0xc6, 0xb3, 0x46, 0x03, 0x9e, 0xa3, 0x8c, 0x9b, 0xcd, 0x3a, 0xac, + 0x89, 0xdc, 0x4f, 0x79, 0x14, 0xac, 0x6c, 0xf8, 0xf3, 0x49, 0xb9, 0x82, + 0x3a, 0x54, 0x15, 0xb1, 0xca, 0x60, 0x9d, 0xae, 0x4a, 0x9b, 0x97, 0xe5, + 0xed, 0x4d, 0xc1, 0xf2, 0x46, 0x45, 0xe6, 0x5b, 0x91, 0xa1, 0xbc, 0xdf, + 0xdb, 0x1d, 0x32, 0x37, 0xa8, 0x58, 0xee, 0xa3, 0xcc, 0x8f, 0x84, 0x43, + 0x91, 0x39, 0x94, 0x79, 0x24, 0xa3, 0x72, 0x3c, 0x7e, 0xfd, 0x10, 0x65, + 0x8f, 0xad, 0x54, 0x29, 0x3b, 0x65, 0x49, 0x51, 0x96, 0x14, 0x65, 0x49, + 0x51, 0x16, 0x47, 0xee, 0x3a, 0xca, 0x9c, 0x9b, 0xa3, 0xa1, 0xcc, 0x04, + 0xe5, 0x9d, 0x2a, 0x67, 0x35, 0x65, 0x47, 0xbc, 0x22, 0xfa, 0x6d, 0xbd, + 0x26, 0x49, 0x7d, 0xa7, 0x6c, 0xfb, 0x4d, 0xd3, 0xb6, 0x3f, 0x35, 0x7d, + 0xd4, 0x5f, 0x8a, 0x76, 0x90, 0x97, 0x67, 0xa6, 0x55, 0x10, 0x45, 0x0b, + 0x4d, 0xd0, 0x3e, 0xde, 0x1c, 0x8a, 0x54, 0x2a, 0x2a, 0xdc, 0x86, 0xa6, + 0xcf, 0xce, 0x06, 0x4d, 0xea, 0x47, 0x0f, 0x65, 0xa1, 0x1b, 0x59, 0xb6, + 0x75, 0x45, 0xbf, 0x41, 0x6d, 0x1c, 0xd2, 0xaf, 0xce, 0xfe, 0x27, 0x26, + 0xe7, 0x4e, 0xda, 0x0f, 0xb0, 0x4f, 0xe9, 0x5f, 0xda, 0xb6, 0xed, 0xdf, + 0x98, 0x30, 0x34, 0x84, 0xac, 0x7e, 0xda, 0x9f, 0x2b, 0xaa, 0xe9, 0x1d, + 0x19, 0x3e, 0xbf, 0xd4, 0x46, 0x6e, 0x3e, 0xd6, 0x64, 0xf4, 0xc9, 0x31, + 0x04, 0x29, 0x82, 0xd8, 0x41, 0x20, 0xee, 0x8b, 0x6a, 0x22, 0x7b, 0xdb, + 0xbe, 0xde, 0x2e, 0x7b, 0x86, 0x21, 0xba, 0x32, 0x3a, 0x67, 0xb8, 0x7c, + 0x91, 0x73, 0x73, 0x1f, 0xb5, 0x4a, 0x9b, 0xc3, 0x28, 0x36, 0xe0, 0x2b, + 0x32, 0xd0, 0x96, 0x1c, 0x2d, 0xb6, 0x4a, 0xa2, 0x3f, 0xbe, 0xbb, 0x77, + 0xd4, 0x8b, 0xe2, 0x51, 0x03, 0x45, 0xa3, 0x4f, 0xbb, 0x51, 0xd6, 0x80, + 0x5d, 0x63, 0x0f, 0xb9, 0x73, 0x63, 0x5b, 0x32, 0x39, 0x46, 0xc7, 0xf6, + 0xbd, 0xef, 0x26, 0xce, 0xdb, 0x05, 0x46, 0xd1, 0x7d, 0xae, 0xa8, 0xa1, + 0x1f, 0x02, 0xce, 0xaf, 0x69, 0x5e, 0x84, 0x6e, 0x4d, 0xc1, 0x4c, 0xe3, + 0x95, 0x12, 0x94, 0x45, 0x60, 0x8d, 0x55, 0xc5, 0x0b, 0xa2, 0xfe, 0x38, + 0xe7, 0x06, 0x2f, 0x27, 0xd2, 0xf0, 0xf4, 0xda, 0xb6, 0x94, 0x7d, 0x07, + 0x77, 0xdf, 0xad, 0x46, 0x8f, 0xde, 0xec, 0x41, 0x0b, 0xcb, 0x63, 0xd3, + 0x89, 0xe6, 0x4f, 0x15, 0x75, 0x77, 0x1b, 0xac, 0x11, 0x17, 0x62, 0x5a, + 0x9c, 0xdf, 0xd7, 0x5f, 0xbf, 0x3c, 0xd2, 0x86, 0xc4, 0xc8, 0x05, 0xde, + 0x77, 0xf3, 0x5e, 0x04, 0xc9, 0xd4, 0xf5, 0xd7, 0xdf, 0x11, 0x89, 0xa3, + 0x77, 0x44, 0xae, 0xdd, 0x18, 0xaf, 0x88, 0x63, 0xfb, 0x5e, 0x1d, 0xe5, + 0x46, 0x1b, 0x52, 0x23, 0x72, 0x6d, 0xdb, 0x67, 0xcc, 0xef, 0x62, 0x5f, + 0x03, 0xfd, 0xff, 0x9a, 0x36, 0x6c, 0xdb, 0x6b, 0xa1, 0xd0, 0xb0, 0xa8, + 0x7b, 0xc5, 0xfd, 0xf7, 0x0d, 0x0a, 0xf4, 0xbb, 0xe1, 0x2e, 0x30, 0x44, + 0x6f, 0x11, 0xf7, 0xfa, 0x44, 0x54, 0x9b, 0x69, 0xd8, 0xf6, 0x90, 0x39, + 0x07, 0x0f, 0xb4, 0xad, 0x81, 0x75, 0xc0, 0x07, 0x6b, 0x95, 0x7c, 0xb7, + 0x51, 0x87, 0x6b, 0xd0, 0x7d, 0x60, 0x0d, 0x7a, 0x9e, 0xa0, 0xe3, 0x56, + 0x68, 0xce, 0x3c, 0xfd, 0x64, 0xb6, 0xc8, 0x24, 0xf2, 0xb5, 0xf3, 0x23, + 0xba, 0xfd, 0x4b, 0x7e, 0x4b, 0x99, 0x0b, 0x36, 0xa6, 0x5f, 0x2e, 0xb3, + 0x9d, 0x65, 0xb6, 0x5d, 0x51, 0x26, 0x82, 0xa7, 0xc6, 0x44, 0x17, 0xa2, + 0xb2, 0x3f, 0xa5, 0x8b, 0x9f, 0xda, 0xdd, 0x7e, 0xd1, 0x85, 0xd5, 0xee, + 0x41, 0xb0, 0xed, 0x41, 0xc5, 0x8d, 0xa5, 0xbd, 0x60, 0x1d, 0x3a, 0x41, + 0x71, 0x30, 0x56, 0xab, 0x44, 0x51, 0xdc, 0xab, 0x60, 0x69, 0xb8, 0x08, + 0x7a, 0x85, 0xb4, 0xf7, 0x4b, 0xdb, 0xd2, 0x44, 0xde, 0x13, 0x28, 0xe1, + 0xfd, 0x75, 0xe1, 0x9f, 0x13, 0xcf, 0x44, 0xa6, 0x30, 0xcb, 0xaf, 0xe0, + 0xfd, 0x37, 0xa6, 0xfc, 0x96, 0x72, 0xb6, 0xbd, 0x99, 0x3e, 0xdf, 0x43, + 0x1b, 0xdf, 0x9e, 0x8a, 0x05, 0xa9, 0x25, 0xcb, 0x13, 0xe5, 0xfd, 0x68, + 0xa8, 0xb5, 0x1b, 0xd2, 0x0f, 0x94, 0xe2, 0x28, 0xdc, 0x99, 0xe6, 0x09, + 0xef, 0xa9, 0x84, 0xd1, 0xfe, 0x8c, 0xe2, 0xa1, 0xb1, 0x4b, 0x3f, 0x13, + 0xde, 0x37, 0x12, 0x0a, 0xde, 0x37, 0x42, 0x1d, 0x67, 0x95, 0x09, 0xef, + 0xeb, 0x19, 0x0d, 0x33, 0x7a, 0x83, 0xed, 0x96, 0x12, 0xc1, 0x8f, 0x32, + 0x7e, 0x04, 0x7a, 0xa3, 0x38, 0x92, 0x31, 0xf1, 0xf4, 0x15, 0x38, 0xf0, + 0xa5, 0x7f, 0x96, 0x8b, 0x63, 0x5f, 0x97, 0xd0, 0xd1, 0x6d, 0x5e, 0xb4, + 0x63, 0x1a, 0xe2, 0xe5, 0xd1, 0x09, 0xef, 0x27, 0xbd, 0x50, 0xca, 0xa2, + 0x46, 0x20, 0xab, 0xfc, 0x83, 0x1d, 0xf7, 0x4b, 0x31, 0xca, 0xe7, 0x60, + 0x59, 0x94, 0x76, 0x47, 0x8c, 0x4a, 0x9d, 0xb7, 0x4b, 0x68, 0xb3, 0x05, + 0xd1, 0x6b, 0x31, 0x32, 0x68, 0xe0, 0xe9, 0x84, 0x6d, 0x7f, 0x6c, 0x8e, + 0x47, 0x7c, 0x30, 0xda, 0x3e, 0x42, 0x30, 0x36, 0x87, 0x7a, 0x39, 0x91, + 0x31, 0x30, 0x9c, 0x88, 0xe2, 0xc5, 0x44, 0x8d, 0xb6, 0x19, 0x4d, 0x88, + 0x05, 0x72, 0x31, 0x64, 0x94, 0x72, 0x0f, 0x85, 0xda, 0x50, 0x1e, 0x8d, + 0xe0, 0x28, 0xe5, 0x3e, 0x37, 0x57, 0xda, 0x31, 0xf1, 0xfa, 0xbf, 0x42, + 0x56, 0xe2, 0x3b, 0x9e, 0xa4, 0xac, 0x91, 0xa6, 0x8b, 0x36, 0xa6, 0x79, + 0x71, 0xda, 0xbc, 0x86, 0x76, 0x08, 0xab, 0x28, 0xea, 0x75, 0xf7, 0x24, + 0x34, 0x1c, 0xce, 0xf8, 0xdc, 0x9b, 0x13, 0x7e, 0x1c, 0xa0, 0xbf, 0xcd, + 0x88, 0xc2, 0x0a, 0xb0, 0xdd, 0x19, 0xc4, 0xb5, 0xec, 0x60, 0x35, 0xc6, + 0x06, 0x83, 0xe6, 0x1b, 0x4a, 0x00, 0x87, 0x86, 0xaf, 0xc5, 0xe8, 0xa0, + 0x82, 0x91, 0x10, 0x65, 0xe7, 0xf5, 0xf7, 0x06, 0xaf, 0x47, 0x66, 0xd0, + 0x85, 0x5d, 0x8e, 0x5e, 0x1d, 0x9c, 0x99, 0xfc, 0xbe, 0x16, 0xe9, 0x61, + 0xb8, 0xe7, 0xf4, 0x6a, 0x78, 0x26, 0xe3, 0x76, 0x1b, 0xbd, 0x7e, 0x0c, + 0x67, 0x7e, 0xca, 0x79, 0x93, 0xb6, 0x75, 0x0c, 0x25, 0x0e, 0x39, 0x73, + 0x58, 0x1e, 0x65, 0x63, 0xb9, 0xf8, 0xca, 0x58, 0xa6, 0x33, 0xce, 0x34, + 0x13, 0x87, 0xc4, 0xc7, 0xbd, 0xc4, 0x20, 0xf1, 0xf1, 0xb7, 0x14, 0x94, + 0x35, 0x63, 0xf3, 0x58, 0xfe, 0xb9, 0x42, 0xfb, 0x77, 0x63, 0x9d, 0xd6, + 0x80, 0x44, 0x4a, 0xec, 0x34, 0x8f, 0xcb, 0x72, 0x2d, 0xf3, 0x5f, 0x0c, + 0xeb, 0x60, 0x31, 0x76, 0xd1, 0xc7, 0x76, 0xee, 0x96, 0xfb, 0xb6, 0xfd, + 0x50, 0xb8, 0x9c, 0x36, 0x86, 0xc5, 0x45, 0x08, 0x99, 0x1f, 0x38, 0xb2, + 0x59, 0x38, 0x94, 0x91, 0x18, 0xaa, 0x33, 0xbe, 0x9d, 0x60, 0x5f, 0xcd, + 0xec, 0xc7, 0xc4, 0x4f, 0x39, 0x37, 0x7f, 0x3d, 0x56, 0x87, 0x1f, 0x8e, + 0x19, 0xf8, 0xef, 0x63, 0x3a, 0x9e, 0xbf, 0x02, 0xd7, 0xef, 0xa6, 0xae, + 0x04, 0xc3, 0x1a, 0xb0, 0x25, 0x55, 0x80, 0x6d, 0x83, 0xc5, 0xd8, 0x3c, + 0x58, 0x53, 0xf7, 0x22, 0xf1, 0xf8, 0x87, 0xe6, 0x1d, 0x18, 0xaf, 0x6c, + 0x76, 0x7c, 0x66, 0x07, 0xef, 0xef, 0x1c, 0xac, 0xe1, 0x1c, 0xda, 0xb6, + 0x1a, 0xae, 0x8f, 0x1c, 0x25, 0xbe, 0x4f, 0xf8, 0x83, 0xfa, 0xb8, 0x1a, + 0xd4, 0x63, 0xf0, 0x20, 0xd1, 0xa0, 0xc2, 0x9a, 0x1e, 0x4c, 0xd3, 0x8b, + 0xe1, 0x37, 0x1e, 0xe2, 0xd8, 0x82, 0xba, 0xa5, 0x36, 0xd0, 0x7e, 0x19, + 0x33, 0x54, 0x93, 0xf8, 0x52, 0x8c, 0x4f, 0x06, 0x83, 0x3d, 0x96, 0xba, + 0x02, 0x56, 0xa5, 0x6d, 0x7f, 0x3f, 0x8c, 0x8e, 0x6b, 0xa2, 0x88, 0x4d, + 0x67, 0x2c, 0xb8, 0x3e, 0x1a, 0x05, 0xe3, 0x18, 0xce, 0xf5, 0x1a, 0x81, + 0xbf, 0x53, 0xee, 0xc6, 0x7f, 0x6c, 0x0b, 0xea, 0xba, 0x5a, 0x6f, 0x1d, + 0x50, 0x49, 0x36, 0xaa, 0xa0, 0x07, 0xa2, 0xcb, 0xd0, 0xe9, 0xf0, 0x04, + 0x05, 0x9a, 0x61, 0x62, 0x73, 0x8a, 0x95, 0xfc, 0x35, 0xed, 0xfd, 0x6a, + 0xcd, 0x05, 0x53, 0x0d, 0x9e, 0x68, 0x53, 0x89, 0xb7, 0x4d, 0xe7, 0x6c, + 0xbd, 0xca, 0xb6, 0x1b, 0x9b, 0xa4, 0x4f, 0x1d, 0x95, 0x9c, 0xe7, 0x0a, + 0xce, 0x73, 0x63, 0xb6, 0x18, 0x67, 0x07, 0x61, 0x5d, 0x13, 0x0d, 0xb6, + 0x3e, 0xa2, 0x16, 0xe3, 0xc3, 0xe1, 0x62, 0xbc, 0x33, 0xe8, 0xc6, 0x07, + 0x83, 0xb6, 0xbd, 0xde, 0x2c, 0x47, 0x41, 0x18, 0xd3, 0x0b, 0x10, 0x3a, + 0x3f, 0x04, 0x0b, 0x5f, 0xb0, 0xec, 0xef, 0x06, 0x03, 0xf8, 0xc7, 0xc1, + 0xaf, 0xe2, 0xf9, 0xca, 0xd8, 0xc9, 0x69, 0x8c, 0x91, 0x17, 0x68, 0x3f, + 0xe7, 0x12, 0xc1, 0xf6, 0x19, 0xae, 0x60, 0x27, 0x79, 0xcb, 0x86, 0xc7, + 0x94, 0x60, 0xfc, 0x0d, 0x25, 0xa8, 0xf7, 0x2a, 0x7e, 0x7c, 0x44, 0x3b, + 0x3d, 0x93, 0xa9, 0x89, 0xfc, 0x9c, 0xfd, 0xff, 0xde, 0xfc, 0xa1, 0x3d, + 0x5e, 0x25, 0x3a, 0x14, 0x7d, 0x51, 0xe7, 0x29, 0xea, 0x9c, 0xfe, 0xfb, + 0xc3, 0x14, 0x75, 0x4e, 0x79, 0x9e, 0xff, 0x83, 0xf8, 0x25, 0xf3, 0x15, + 0xe1, 0x3c, 0x5e, 0x87, 0xff, 0xe2, 0x8c, 0xed, 0xa4, 0xfd, 0x9f, 0xfc, + 0x32, 0xbe, 0xcf, 0xfd, 0x39, 0x0c, 0x92, 0x71, 0x9e, 0xb0, 0xe3, 0x9a, + 0x8c, 0x51, 0xc6, 0xea, 0xe8, 0x52, 0xef, 0x50, 0x1e, 0x55, 0x51, 0x6c, + 0xdb, 0x4f, 0x98, 0x93, 0xcf, 0xfd, 0xf9, 0xb1, 0x7e, 0x95, 0xf7, 0x65, + 0xbc, 0x67, 0x5d, 0xa2, 0x7b, 0x5d, 0xbd, 0x89, 0xbf, 0x83, 0x56, 0x0c, + 0xa7, 0x0b, 0xf9, 0xbb, 0x2e, 0x76, 0xe9, 0xf7, 0x93, 0xa5, 0x57, 0x3e, + 0xa7, 0x9d, 0x3a, 0xfd, 0xdd, 0xcd, 0xdf, 0x32, 0x96, 0x37, 0x69, 0x37, + 0x5f, 0x66, 0x27, 0x62, 0x23, 0x75, 0xb4, 0xa7, 0x33, 0x12, 0x57, 0x2c, + 0x7f, 0xd4, 0x6b, 0xa9, 0x51, 0xe8, 0x74, 0x7d, 0xaf, 0x12, 0xed, 0x80, + 0x9e, 0xb1, 0x70, 0x4f, 0xb3, 0x0b, 0xdf, 0x6a, 0x56, 0x30, 0xcd, 0xe8, + 0x40, 0xdf, 0x3c, 0xcb, 0xae, 0x30, 0xf6, 0xab, 0xe2, 0x03, 0x05, 0x49, + 0x58, 0xf4, 0x3b, 0x44, 0xc8, 0x95, 0xca, 0xff, 0x9d, 0x82, 0xd3, 0xe1, + 0x10, 0x6d, 0x6e, 0x0b, 0x39, 0x15, 0x50, 0x98, 0x84, 0xb7, 0x94, 0xf3, + 0x3f, 0xda, 0x0b, 0x6f, 0x31, 0x7d, 0x7f, 0x59, 0x6f, 0x4d, 0xc7, 0x7b, + 0xc4, 0x8a, 0xac, 0x12, 0x6c, 0xa7, 0xbe, 0xcd, 0x32, 0x25, 0xd8, 0x7a, + 0x3b, 0xf5, 0x5d, 0xab, 0x48, 0x3f, 0x51, 0xd4, 0x65, 0xb6, 0x10, 0x73, + 0xe4, 0x3a, 0x02, 0x23, 0xf3, 0xab, 0x49, 0xd9, 0xe1, 0xf5, 0x50, 0x86, + 0x83, 0x89, 0x77, 0xed, 0xb4, 0x16, 0xd4, 0xd3, 0xce, 0xef, 0x0d, 0xfc, + 0x0d, 0x6f, 0x41, 0x74, 0x23, 0x5e, 0x4a, 0x3c, 0xe5, 0xcf, 0x97, 0xcb, + 0xc9, 0x7a, 0xb5, 0x3c, 0xff, 0xd3, 0x8e, 0xf9, 0x73, 0xf2, 0xf8, 0x92, + 0x5b, 0x40, 0x8e, 0xe2, 0x2d, 0x64, 0x5f, 0xef, 0x3b, 0xf5, 0x23, 0xac, + 0x5f, 0xd3, 0xde, 0xab, 0x04, 0xeb, 0x3e, 0x42, 0xbd, 0xfe, 0x3d, 0x04, + 0x5b, 0x8f, 0x92, 0x5b, 0x1a, 0x93, 0xf2, 0x84, 0x32, 0x0e, 0x9f, 0x71, + 0xe4, 0x99, 0x95, 0x81, 0xe2, 0xea, 0x85, 0x6f, 0xa6, 0x51, 0x8b, 0x2e, + 0x67, 0x4e, 0xa1, 0x04, 0x7a, 0x75, 0x94, 0x91, 0xbf, 0x04, 0x46, 0x81, + 0xb1, 0x01, 0x72, 0xb9, 0x70, 0x0d, 0xbe, 0xc9, 0x58, 0x30, 0x83, 0x65, + 0x1e, 0xd3, 0x2e, 0xe1, 0x97, 0xd2, 0x93, 0x20, 0xc0, 0x4c, 0xcf, 0xf1, + 0xb2, 0xf8, 0xbd, 0x88, 0xc9, 0xbd, 0x27, 0x13, 0x50, 0x52, 0x89, 0xe0, + 0x3e, 0xc0, 0x18, 0x0f, 0xbb, 0x62, 0x0f, 0x07, 0xd0, 0x85, 0x73, 0xe1, + 0x50, 0x3c, 0xab, 0x84, 0xda, 0x07, 0x14, 0xd3, 0xbb, 0x8b, 0xfd, 0x6d, + 0x67, 0x99, 0x1d, 0xfc, 0x9c, 0x35, 0x0c, 0x73, 0x85, 0x12, 0xbb, 0xa1, + 0x80, 0x65, 0x6a, 0xc2, 0x21, 0xf2, 0xcc, 0xd0, 0x85, 0x95, 0x30, 0xbd, + 0x4f, 0x65, 0xa4, 0xad, 0x88, 0xb2, 0x25, 0xfb, 0xa4, 0x9a, 0xc3, 0xa3, + 0xdf, 0x4f, 0xea, 0xec, 0x1d, 0xf9, 0xed, 0xf4, 0xed, 0xee, 0xfd, 0xaf, + 0x85, 0x7f, 0x78, 0xef, 0xaf, 0xa7, 0x5d, 0x79, 0xaf, 0x5e, 0x1b, 0xa6, + 0xff, 0xb9, 0x8c, 0x22, 0xce, 0x9d, 0xf0, 0xa3, 0x58, 0x9d, 0x07, 0x72, + 0xcf, 0x85, 0xb4, 0x3b, 0x16, 0x70, 0xe1, 0x73, 0x3b, 0xb6, 0x4a, 0xee, + 0x15, 0x23, 0xde, 0x56, 0x1f, 0x70, 0xa3, 0x3e, 0xb2, 0x95, 0x58, 0x30, + 0xb1, 0x6a, 0x21, 0x9f, 0x85, 0xcc, 0x17, 0x51, 0xa3, 0x6f, 0x85, 0x5c, + 0x7f, 0x46, 0x9b, 0x5d, 0x28, 0x75, 0x59, 0x26, 0xc7, 0x7d, 0x04, 0x6b, + 0xb6, 0x98, 0x36, 0x5e, 0x22, 0x4c, 0x14, 0x46, 0x8f, 0x28, 0xa7, 0x13, + 0x5f, 0xd8, 0x31, 0x37, 0x96, 0xd3, 0x2f, 0x4d, 0xea, 0x59, 0xf7, 0x46, + 0x43, 0xfa, 0x09, 0x66, 0x0a, 0xae, 0xa8, 0xa5, 0x4c, 0x64, 0xb6, 0x28, + 0xef, 0x66, 0x7a, 0x94, 0x33, 0x19, 0xa9, 0x7b, 0x44, 0x79, 0x27, 0x23, + 0xf1, 0xb0, 0x5a, 0x3f, 0x4e, 0x7e, 0x43, 0x4e, 0xa5, 0x6e, 0x36, 0xa1, + 0x6c, 0x33, 0xcb, 0xc8, 0xf3, 0x8d, 0xba, 0x21, 0xca, 0x7b, 0xb0, 0x19, + 0xe6, 0x76, 0xd3, 0x83, 0x09, 0x0d, 0xbe, 0xcd, 0xa6, 0x5b, 0x7e, 0x33, + 0x1f, 0x90, 0xba, 0xd5, 0xfa, 0xd6, 0xcc, 0x45, 0xfa, 0x57, 0xee, 0xf7, + 0xc1, 0xe6, 0xfc, 0xbd, 0xdf, 0xda, 0xe3, 0xab, 0x54, 0xfe, 0xfe, 0x77, + 0x2e, 0x0e, 0x85, 0x75, 0xa7, 0xf2, 0x73, 0xe1, 0x52, 0x2a, 0xf9, 0x63, + 0x05, 0x2c, 0x2d, 0x68, 0xa5, 0x99, 0x0e, 0x6d, 0x4e, 0x35, 0xd2, 0xdf, + 0x02, 0x8c, 0x95, 0x51, 0xe2, 0x3b, 0x79, 0x2f, 0xfb, 0x2c, 0x30, 0x7c, + 0x58, 0x9c, 0xa8, 0x71, 0xe5, 0xf4, 0xa7, 0x12, 0xc3, 0x5c, 0x8c, 0xe9, + 0xc2, 0xf1, 0xae, 0xe6, 0xdc, 0xd5, 0xfa, 0x07, 0x94, 0xbb, 0xc8, 0x30, + 0xea, 0x8a, 0x94, 0x6a, 0xfd, 0xdd, 0x4c, 0x94, 0x3e, 0xde, 0xce, 0x7e, + 0x7d, 0x78, 0x37, 0x51, 0xc6, 0x1c, 0x24, 0x18, 0xb3, 0xd8, 0xe0, 0x92, + 0xe6, 0x00, 0xc8, 0xf9, 0xa6, 0xfc, 0xb5, 0x81, 0xf1, 0x5f, 0x62, 0xb4, + 0x7a, 0xdb, 0xdc, 0x08, 0x36, 0x64, 0xe0, 0x5e, 0xd7, 0x1c, 0xc5, 0x7a, + 0xc6, 0xf6, 0x87, 0x18, 0x2f, 0x37, 0x32, 0x16, 0xee, 0x0a, 0x73, 0x6c, + 0x15, 0xb6, 0x5d, 0x68, 0x74, 0x49, 0x3e, 0x83, 0x5e, 0xc6, 0xe2, 0xb5, + 0x8c, 0x2f, 0x5b, 0x78, 0x7d, 0x2a, 0xf3, 0xcf, 0xf6, 0x43, 0xcc, 0xa7, + 0x5e, 0xba, 0xa2, 0x4d, 0xa8, 0xc3, 0x46, 0x7d, 0xdd, 0x56, 0xc6, 0x62, + 0xb6, 0x6b, 0x95, 0x45, 0x6d, 0xfb, 0x86, 0x50, 0x30, 0xe6, 0x51, 0x4c, + 0xbc, 0x38, 0x3a, 0x61, 0xeb, 0xd3, 0x25, 0x97, 0xca, 0xc7, 0x41, 0x19, + 0xab, 0xe4, 0x08, 0x82, 0x0f, 0x92, 0x27, 0x4c, 0xc5, 0x08, 0x15, 0x4b, + 0x06, 0x25, 0x4f, 0x08, 0x60, 0x65, 0xe2, 0xbb, 0x78, 0xb1, 0xc1, 0x8d, + 0x56, 0xe6, 0x58, 0xb7, 0x25, 0x7c, 0x58, 0x41, 0x2c, 0x5d, 0x9a, 0x60, + 0xee, 0xa4, 0xf9, 0xb1, 0x2c, 0xe1, 0xc6, 0xb1, 0x06, 0xe6, 0x40, 0xfe, + 0x42, 0x7c, 0x64, 0xba, 0x70, 0xdc, 0xd4, 0x90, 0x76, 0xfc, 0x61, 0x17, + 0x31, 0x90, 0x7a, 0x54, 0x25, 0x77, 0x10, 0x1d, 0xba, 0xa8, 0x4f, 0x15, + 0xf1, 0x4b, 0x3a, 0xfc, 0xb2, 0x5c, 0x40, 0xe4, 0x92, 0x7c, 0xe0, 0x37, + 0x76, 0x7c, 0xba, 0xd4, 0x87, 0xe5, 0x8b, 0xca, 0x38, 0x84, 0xdf, 0x12, + 0x27, 0x47, 0x4d, 0x72, 0xbb, 0xa9, 0x43, 0x3d, 0x4f, 0x6e, 0x5d, 0x8e, + 0xb7, 0x0c, 0xe1, 0xd6, 0x6f, 0x42, 0xa3, 0xef, 0xf6, 0x8c, 0x86, 0x3a, + 0xce, 0x2b, 0x2e, 0x9c, 0x32, 0xca, 0xc8, 0xfb, 0x38, 0x0f, 0xa3, 0x70, + 0x6f, 0x9d, 0x6b, 0x22, 0x39, 0xda, 0x1d, 0x29, 0xe5, 0x78, 0xdd, 0x73, + 0x73, 0x9c, 0xe8, 0xeb, 0xd4, 0xed, 0x9a, 0xb0, 0xc3, 0x89, 0x72, 0x7c, + 0x40, 0xb3, 0xed, 0x77, 0x0c, 0xd1, 0x33, 0x70, 0x78, 0x52, 0xc7, 0x07, + 0x79, 0xdd, 0x33, 0xa9, 0xe3, 0x2d, 0x6c, 0x8f, 0xfe, 0x87, 0x6d, 0x57, + 0xf0, 0x18, 0x1d, 0xcc, 0x29, 0xc9, 0x6f, 0x88, 0xc3, 0xc4, 0x95, 0x18, + 0x75, 0xfc, 0x72, 0x66, 0x83, 0xe0, 0x36, 0xa7, 0xbb, 0xd1, 0xc1, 0xef, + 0x98, 0x7a, 0x98, 0x76, 0x20, 0x7a, 0x78, 0x6b, 0x32, 0xb7, 0xb1, 0xed, + 0x01, 0x53, 0x74, 0x9c, 0xcf, 0xcb, 0x44, 0xd7, 0x37, 0x4a, 0x8e, 0xd5, + 0x03, 0x7c, 0xc1, 0xb2, 0x2e, 0xe2, 0xee, 0x42, 0xfc, 0xa0, 0x4d, 0x6c, + 0xa7, 0xd4, 0x89, 0x95, 0xf3, 0x6b, 0x6d, 0x3b, 0xdc, 0xa4, 0xe3, 0x82, + 0x51, 0x1f, 0x69, 0x54, 0x67, 0x51, 0xd6, 0x28, 0xf6, 0x91, 0x0f, 0x74, + 0xa7, 0x66, 0x22, 0xe6, 0x17, 0x5b, 0x43, 0x47, 0x41, 0x0e, 0xc3, 0x71, + 0x26, 0x61, 0xd4, 0x6d, 0xc3, 0x0c, 0x1c, 0xf0, 0xb7, 0x90, 0xc7, 0xa9, + 0x2d, 0x4c, 0xff, 0xc9, 0x9f, 0x0c, 0x6b, 0x07, 0xce, 0xda, 0x69, 0xbf, + 0xcd, 0x38, 0x49, 0x18, 0xa0, 0x2e, 0x5f, 0xd1, 0x5c, 0x78, 0xb5, 0xee, + 0x9a, 0x49, 0xbe, 0x29, 0x9c, 0xe5, 0x3d, 0xfb, 0x98, 0x5f, 0xfa, 0x62, + 0x9e, 0xa7, 0x2e, 0x73, 0x49, 0x1e, 0xe8, 0x36, 0xa4, 0x6d, 0xe6, 0x0b, + 0x63, 0x57, 0xcb, 0x30, 0x61, 0x4f, 0xf8, 0x45, 0x86, 0xa0, 0xa6, 0xab, + 0x7f, 0x6c, 0x1e, 0xaf, 0xc3, 0xcf, 0x35, 0x37, 0x7c, 0xe4, 0xc5, 0xaf, + 0xf9, 0x73, 0x6d, 0xf4, 0x9a, 0xe3, 0x33, 0x4a, 0x1d, 0xac, 0x3c, 0xa2, + 0x24, 0x89, 0x0f, 0xe3, 0x1e, 0x68, 0xe5, 0x51, 0xb7, 0xae, 0x11, 0x13, + 0x36, 0x13, 0x13, 0x2c, 0x62, 0x42, 0x5f, 0xe6, 0x88, 0x92, 0xca, 0x7c, + 0x46, 0x5d, 0x48, 0x1d, 0xb1, 0x9d, 0x2d, 0x94, 0xe5, 0x27, 0x36, 0xaa, + 0x44, 0x9e, 0x0b, 0xbc, 0xdf, 0x42, 0x1e, 0x92, 0x97, 0x53, 0x7c, 0x95, + 0x10, 0x54, 0x2c, 0xcf, 0x52, 0xb9, 0xdf, 0xaa, 0x5c, 0xcf, 0x70, 0x4b, + 0xb9, 0xee, 0xb1, 0xa3, 0x4b, 0xdd, 0x58, 0x80, 0xd9, 0xe1, 0x85, 0x8b, + 0x44, 0x17, 0x6a, 0x34, 0xa6, 0x7b, 0x61, 0x55, 0xb9, 0x88, 0xe5, 0xef, + 0x35, 0x34, 0x60, 0x11, 0x73, 0xce, 0xb3, 0x04, 0xa7, 0x6e, 0xc3, 0x85, + 0x71, 0xea, 0xe7, 0x69, 0x53, 0xd6, 0x1b, 0x6c, 0xdc, 0x16, 0xb6, 0xe2, + 0xf4, 0x78, 0xab, 0x94, 0xb6, 0x57, 0x6c, 0x08, 0x4f, 0x28, 0x43, 0x49, + 0xd4, 0x5d, 0x77, 0x16, 0x41, 0x73, 0x17, 0x79, 0x92, 0x5e, 0x31, 0x3b, + 0xe2, 0xa1, 0xe6, 0x5e, 0x4f, 0x84, 0x22, 0xc7, 0x95, 0x9c, 0x3f, 0xbd, + 0x4c, 0xdb, 0x78, 0x2b, 0x61, 0x74, 0x16, 0xba, 0x72, 0xbf, 0xdf, 0x70, + 0xf2, 0xd9, 0xbc, 0x3f, 0x05, 0x26, 0x71, 0xc7, 0xeb, 0x3d, 0x93, 0xc0, + 0x79, 0xb5, 0x59, 0xf2, 0x5a, 0x9c, 0xdf, 0x6c, 0x8e, 0x2b, 0x1e, 0xa3, + 0x8c, 0xfa, 0x10, 0x2c, 0x2e, 0x20, 0xa7, 0x14, 0xee, 0xe0, 0xf5, 0x9e, + 0x65, 0x19, 0x72, 0xc2, 0x89, 0xba, 0xf9, 0xf5, 0x11, 0x2f, 0x62, 0x56, + 0x21, 0xfd, 0xba, 0x34, 0xea, 0xf7, 0xde, 0x98, 0xb5, 0xaa, 0x7c, 0xf4, + 0x8b, 0x12, 0xe6, 0xbb, 0xb3, 0x93, 0x0b, 0xcb, 0x24, 0x57, 0xdc, 0x38, + 0xca, 0x91, 0x55, 0xf6, 0x57, 0xa9, 0x51, 0x59, 0xc3, 0xd0, 0xe0, 0xa9, + 0xdc, 0x78, 0x8b, 0x1a, 0x9d, 0x40, 0x7b, 0xb3, 0xb7, 0x25, 0x92, 0x85, + 0xb7, 0x22, 0xba, 0x09, 0xe1, 0xa4, 0xe4, 0xad, 0x82, 0xb1, 0xb1, 0xad, + 0x44, 0xbd, 0xaa, 0xf2, 0x79, 0xf9, 0xb9, 0x82, 0x5a, 0x16, 0x95, 0xfc, + 0x55, 0x6f, 0x79, 0xc3, 0xc1, 0x62, 0x8d, 0xf9, 0xc6, 0xaf, 0x02, 0xff, + 0x77, 0xf5, 0x5b, 0xdd, 0x32, 0x77, 0x1e, 0x43, 0xbe, 0x65, 0xdd, 0x00, + 0x6e, 0x95, 0x58, 0xda, 0x3d, 0xe2, 0x66, 0x7e, 0x26, 0xf3, 0x25, 0xf1, + 0xf8, 0xc8, 0xbd, 0x2f, 0xd1, 0xdf, 0x3c, 0xd4, 0xfd, 0x0e, 0xc3, 0x62, + 0x98, 0xb0, 0x6d, 0x23, 0x1c, 0x0c, 0x14, 0x28, 0x3a, 0xb6, 0x37, 0xfc, + 0x13, 0xed, 0x0b, 0xc4, 0x41, 0x90, 0x98, 0x97, 0x61, 0xcb, 0x48, 0xc1, + 0x94, 0x7a, 0x91, 0xfb, 0xf2, 0xf5, 0x7a, 0x0d, 0x2b, 0x2e, 0xf5, 0x86, + 0xc3, 0xc1, 0xf6, 0x6d, 0xac, 0xb7, 0x93, 0xf5, 0x62, 0x8c, 0xbd, 0xeb, + 0x47, 0x35, 0x27, 0x1f, 0xb4, 0x46, 0x8a, 0xa7, 0xf6, 0x77, 0xa9, 0xde, + 0x93, 0x86, 0x35, 0xee, 0xf4, 0xd7, 0x14, 0xec, 0x2c, 0x70, 0xb9, 0x91, + 0x64, 0xbd, 0x71, 0xd6, 0x7b, 0x77, 0x54, 0xd6, 0x33, 0x70, 0xcb, 0x48, + 0x22, 0x35, 0xe1, 0x32, 0x0c, 0xed, 0x1d, 0xc4, 0x88, 0xd9, 0xce, 0x5c, + 0xde, 0x72, 0x28, 0xd3, 0x85, 0xed, 0xc6, 0xd1, 0x70, 0x21, 0xeb, 0x1d, + 0x37, 0x8e, 0x06, 0x3c, 0xf4, 0x99, 0x75, 0x6c, 0xaf, 0x9b, 0x79, 0x91, + 0x4a, 0x8c, 0xdc, 0x32, 0x22, 0xdc, 0xc1, 0xc4, 0x6c, 0xe6, 0x67, 0x8e, + 0x6d, 0xca, 0xda, 0x09, 0x64, 0x4e, 0x65, 0x7c, 0xc1, 0xba, 0x11, 0x67, + 0x7c, 0xca, 0x35, 0x87, 0x25, 0x57, 0xae, 0xb0, 0xb0, 0xb9, 0x41, 0xe2, + 0xa7, 0x42, 0xec, 0x0e, 0xd6, 0x8d, 0x33, 0x9e, 0x6c, 0x1b, 0xfb, 0x33, + 0x8c, 0x6b, 0x95, 0xcc, 0x65, 0x6d, 0xfb, 0x15, 0x63, 0x61, 0x05, 0x43, + 0xbc, 0xd7, 0x4b, 0x99, 0xbd, 0xa1, 0x62, 0x89, 0xd3, 0x4e, 0x5b, 0x31, + 0x08, 0x3e, 0x29, 0x48, 0x1a, 0xd6, 0x06, 0x91, 0xff, 0x58, 0x38, 0x18, + 0x3f, 0xac, 0xd4, 0xb7, 0x6f, 0xc3, 0x3f, 0x11, 0x2f, 0x41, 0xac, 0x9b, + 0x89, 0x21, 0x93, 0xd6, 0xd2, 0x66, 0x31, 0x42, 0x4a, 0x8c, 0x77, 0x9f, + 0x58, 0xc4, 0x08, 0xe7, 0x46, 0xb0, 0xb3, 0x95, 0xe5, 0x23, 0xb9, 0x75, + 0x16, 0x5c, 0x18, 0x0d, 0x32, 0x0e, 0x8b, 0x2e, 0x80, 0xad, 0x99, 0x7c, + 0x2c, 0xb0, 0xed, 0x83, 0xa6, 0x6d, 0xbf, 0x64, 0xce, 0xc4, 0x61, 0x33, + 0x18, 0x17, 0x1f, 0x78, 0xdf, 0x5c, 0x78, 0x83, 0xe4, 0xc5, 0x80, 0xc8, + 0xa6, 0x30, 0x76, 0x29, 0x28, 0xe1, 0x27, 0x10, 0x72, 0xeb, 0x25, 0x8a, + 0x0d, 0x6f, 0x53, 0x6d, 0x67, 0x2d, 0xf5, 0x5e, 0x36, 0x5f, 0xc1, 0x27, + 0x37, 0x2a, 0x38, 0x7a, 0x63, 0x28, 0x30, 0xa4, 0x94, 0x32, 0x2e, 0x84, + 0xda, 0x5a, 0x14, 0xeb, 0x04, 0xeb, 0xc6, 0x1a, 0x5c, 0xc1, 0x00, 0x94, + 0x72, 0x62, 0xd6, 0x6c, 0x5d, 0x68, 0x8b, 0xbb, 0x37, 0x14, 0xd8, 0xc9, + 0x6f, 0xd7, 0xa8, 0x82, 0x51, 0x23, 0x18, 0x83, 0xd3, 0x3e, 0xfb, 0x66, + 0xca, 0x7c, 0x53, 0xc8, 0xb6, 0x4f, 0x86, 0xeb, 0xb5, 0x93, 0x78, 0x9f, + 0xb8, 0x2c, 0xfd, 0xe4, 0x65, 0x03, 0xf3, 0x70, 0x23, 0xd6, 0xa2, 0xdc, + 0x24, 0xb4, 0x84, 0x71, 0x52, 0x62, 0x79, 0x5e, 0xde, 0x7c, 0x4c, 0xb7, + 0xed, 0xf7, 0xcd, 0x5c, 0x5b, 0x5a, 0x73, 0x30, 0x0e, 0xcc, 0xc4, 0x98, + 0x11, 0x6c, 0x1d, 0xa7, 0x1e, 0x02, 0xf4, 0xf5, 0x19, 0x46, 0x15, 0x26, + 0x3c, 0x41, 0x6d, 0x42, 0x59, 0xf4, 0x99, 0x8a, 0x39, 0x1b, 0x9e, 0x52, + 0xea, 0x3b, 0x8a, 0x60, 0x90, 0x9f, 0x5e, 0x23, 0xf3, 0x11, 0xf0, 0x91, + 0x0b, 0xae, 0x83, 0xc3, 0x2f, 0x70, 0x7b, 0xc2, 0x1d, 0xbb, 0x80, 0x1a, + 0xfa, 0x9d, 0xd1, 0xfe, 0x90, 0x12, 0x64, 0xf2, 0xf2, 0x35, 0x26, 0x38, + 0x22, 0x6b, 0x15, 0xe2, 0xf7, 0xd8, 0xf6, 0xc3, 0x94, 0x75, 0x17, 0x65, + 0xdd, 0x18, 0xfe, 0xd8, 0xfe, 0x07, 0xa7, 0xcd, 0x5b, 0x31, 0x64, 0x5c, + 0xdd, 0xee, 0x47, 0x36, 0xa6, 0x4b, 0xbb, 0x1e, 0x2c, 0x99, 0xce, 0x5c, + 0xab, 0x59, 0xf0, 0xaa, 0xd2, 0x43, 0x7c, 0x62, 0x7b, 0x8c, 0x7f, 0xea, + 0xd5, 0x1c, 0xc2, 0x05, 0xc6, 0xe6, 0x40, 0x5c, 0x51, 0xab, 0x4b, 0xa0, + 0xc1, 0x6b, 0xd8, 0x78, 0x84, 0x7c, 0x27, 0x36, 0xbd, 0x1c, 0xdf, 0xe4, + 0x9c, 0x96, 0x86, 0xd4, 0x6b, 0x5d, 0x9c, 0x93, 0xc3, 0x61, 0xf9, 0xed, + 0xc1, 0xf8, 0x74, 0x17, 0xba, 0x38, 0xcb, 0x5a, 0x48, 0x9d, 0x21, 0xf7, + 0xbd, 0x8d, 0xf2, 0x9b, 0xf2, 0x5f, 0xa3, 0xe0, 0x61, 0x5a, 0xa4, 0x1a, + 0xea, 0x0e, 0xc8, 0xfd, 0x56, 0x53, 0x7e, 0x2b, 0xe4, 0x92, 0x6e, 0xce, + 0x8b, 0x0d, 0x97, 0x2c, 0x4d, 0x84, 0x78, 0x3f, 0x2c, 0xd7, 0xb1, 0x87, + 0x39, 0xee, 0xd8, 0x01, 0x45, 0x30, 0xee, 0x97, 0xf6, 0x2b, 0x8c, 0x81, + 0x1a, 0x9f, 0x7f, 0x93, 0x7d, 0x9f, 0x08, 0xbf, 0x64, 0xcf, 0xa8, 0x50, + 0x70, 0x32, 0xa2, 0x63, 0xe6, 0x8d, 0xd5, 0x98, 0xb8, 0x5b, 0xc6, 0xac, + 0xa0, 0xd4, 0x38, 0xe8, 0x91, 0x1c, 0xb9, 0xcc, 0xb8, 0x06, 0x4b, 0x56, + 0xe4, 0xee, 0x15, 0x85, 0x64, 0x8d, 0x53, 0x47, 0xd1, 0x8d, 0x95, 0xd0, + 0x27, 0xef, 0x2d, 0x0a, 0xb9, 0xdb, 0x4a, 0x15, 0x43, 0xbb, 0x5d, 0x91, + 0xe7, 0xbf, 0x23, 0x2f, 0xb7, 0xed, 0x47, 0x38, 0x5f, 0xb3, 0xc3, 0x3e, + 0x9c, 0x63, 0x3f, 0xdd, 0xd4, 0xdf, 0xf2, 0x4b, 0xf3, 0x95, 0xaf, 0xff, + 0xa9, 0xad, 0xdf, 0x23, 0x75, 0xa5, 0x8d, 0xda, 0xd6, 0x25, 0xca, 0x03, + 0x1e, 0xc9, 0x91, 0x36, 0x86, 0x1d, 0x9d, 0xb1, 0xec, 0x73, 0xce, 0x6f, + 0xad, 0xf9, 0xad, 0x4b, 0xeb, 0x75, 0xe7, 0x9d, 0x58, 0xba, 0x70, 0xbe, + 0x86, 0x09, 0xbb, 0xa2, 0xd1, 0xd2, 0x0a, 0x21, 0x31, 0xb5, 0xa6, 0xee, + 0x39, 0xb6, 0xfb, 0x73, 0x33, 0x17, 0x6f, 0x0f, 0x9a, 0xc1, 0x3e, 0x8b, + 0xfe, 0x13, 0x67, 0x8e, 0xdb, 0x22, 0xbc, 0x63, 0xec, 0x16, 0xce, 0xc3, + 0x4c, 0x14, 0x36, 0x06, 0x7b, 0x66, 0x31, 0xe7, 0x73, 0x35, 0x4b, 0x9c, + 0x96, 0xf9, 0x71, 0xca, 0xb0, 0xaf, 0x22, 0x2c, 0xa2, 0x8c, 0xe1, 0xc6, + 0x3f, 0x15, 0xdf, 0xa4, 0x1d, 0xb1, 0xce, 0x60, 0x4f, 0x0c, 0x7f, 0xaa, + 0x2c, 0xc8, 0x28, 0x64, 0x2d, 0xcc, 0x7b, 0x4b, 0x3c, 0xa3, 0x92, 0x23, + 0x15, 0x68, 0xdd, 0xcd, 0x55, 0xfc, 0xc8, 0x73, 0xf7, 0x2d, 0x6b, 0x32, + 0x97, 0xd6, 0x20, 0xd1, 0x67, 0x16, 0x40, 0xbd, 0x49, 0xe2, 0x05, 0x7d, + 0x59, 0x93, 0xf1, 0x59, 0xb4, 0x72, 0x59, 0x5f, 0x30, 0x56, 0xad, 0x25, + 0x5e, 0xbc, 0xc8, 0x1e, 0x87, 0xc9, 0xc5, 0x2c, 0xc7, 0x33, 0x9c, 0xf8, + 0x37, 0x65, 0x4d, 0x52, 0xe2, 0x57, 0x7e, 0x5d, 0xb3, 0x12, 0xfd, 0x7b, + 0x57, 0x40, 0xaf, 0xca, 0x61, 0xa0, 0x1a, 0x6d, 0xc2, 0xc2, 0xbe, 0x40, + 0x41, 0x2e, 0x7f, 0x28, 0x43, 0xef, 0xde, 0x30, 0xd2, 0xd3, 0x9d, 0xfa, + 0xbc, 0xe7, 0x85, 0x60, 0xf4, 0xf6, 0xbd, 0xd7, 0xca, 0x7a, 0x40, 0x40, + 0xda, 0x8d, 0xd3, 0x77, 0x54, 0xe3, 0x43, 0xdb, 0xd2, 0xa4, 0xfd, 0xa3, + 0x37, 0x10, 0x47, 0xcc, 0xc5, 0xa8, 0x6f, 0x3f, 0x84, 0x33, 0xe4, 0xa4, + 0x4e, 0xbe, 0xa4, 0x17, 0x46, 0xc7, 0x1f, 0xf6, 0x20, 0x14, 0x1f, 0x21, + 0x0e, 0xf8, 0x46, 0xbd, 0xe4, 0x56, 0x33, 0x9d, 0x75, 0xaf, 0x85, 0xc4, + 0x96, 0x38, 0x79, 0xf9, 0xd7, 0xdc, 0x6e, 0xac, 0x25, 0x66, 0x1c, 0x34, + 0xea, 0x3b, 0x0e, 0xe1, 0x1f, 0x89, 0xb3, 0x52, 0x5e, 0x65, 0x7f, 0xd2, + 0xa6, 0x9b, 0xfd, 0xc1, 0x4b, 0x2e, 0x70, 0x2f, 0xf9, 0xac, 0xdb, 0x63, + 0xfc, 0xc4, 0x23, 0xbc, 0x43, 0x78, 0xf7, 0xae, 0xbd, 0x0a, 0x5a, 0xd8, + 0xce, 0x4e, 0xda, 0xcc, 0xc3, 0x21, 0xb8, 0x5b, 0x6f, 0x24, 0xbf, 0x02, + 0x5d, 0x70, 0xba, 0x0f, 0x3b, 0x46, 0x10, 0xc9, 0x18, 0xe3, 0x33, 0x7c, + 0xa8, 0x62, 0x3b, 0x12, 0x53, 0x0a, 0x26, 0xdb, 0x89, 0xdc, 0x77, 0x65, + 0x3b, 0x65, 0x78, 0x72, 0xb2, 0x9d, 0x7d, 0x6c, 0xe7, 0xe6, 0xd9, 0x70, + 0x97, 0xdd, 0x2c, 0x73, 0xd5, 0x40, 0xff, 0x29, 0x43, 0xca, 0x89, 0x2b, + 0xe4, 0xa3, 0x5f, 0x85, 0x62, 0xd4, 0x4a, 0xee, 0x72, 0xd6, 0xa9, 0xb7, + 0xb8, 0x61, 0xfc, 0x02, 0x69, 0x91, 0x72, 0x7e, 0xf6, 0x38, 0x1d, 0x35, + 0xaf, 0x9b, 0x2a, 0x6c, 0xdd, 0x5b, 0x9c, 0x97, 0x97, 0xfd, 0xe4, 0xfb, + 0xa8, 0xe4, 0x3d, 0x3f, 0x76, 0x30, 0x07, 0x5d, 0xcc, 0x7e, 0x0e, 0x9b, + 0xc2, 0x23, 0xeb, 0xcd, 0x22, 0x45, 0x72, 0xf2, 0x00, 0x39, 0x45, 0x25, + 0x36, 0x3b, 0x71, 0x28, 0xc0, 0xfa, 0x0d, 0x65, 0x39, 0x7e, 0x02, 0xcf, + 0x32, 0x96, 0x6d, 0x09, 0xe7, 0xfa, 0x23, 0x0e, 0x33, 0xcf, 0x6d, 0xc4, + 0xc1, 0xc1, 0x4b, 0xcf, 0x83, 0x8b, 0x8d, 0xa9, 0xf3, 0x35, 0x1e, 0xf4, + 0xa0, 0x8d, 0xdf, 0x05, 0x12, 0x67, 0xae, 0x18, 0xfb, 0x96, 0x91, 0x47, + 0xf8, 0x5d, 0x8c, 0xad, 0x23, 0x36, 0xb6, 0x38, 0x39, 0x4e, 0x01, 0xba, + 0x1b, 0x04, 0x0f, 0xc5, 0x96, 0xa6, 0x4b, 0xec, 0x88, 0xa4, 0x21, 0xf1, + 0x55, 0xec, 0x27, 0xea, 0xd8, 0x8f, 0x4b, 0x99, 0x6a, 0x3f, 0x5d, 0x78, + 0xcd, 0x38, 0xba, 0xa2, 0x10, 0x47, 0xef, 0x97, 0xb5, 0xfb, 0x8e, 0x30, + 0x8e, 0xdd, 0x46, 0xdf, 0x7c, 0x97, 0xd8, 0xb2, 0x65, 0x36, 0xe3, 0x97, + 0x83, 0x59, 0x0a, 0x0a, 0xc9, 0x2b, 0xb6, 0xed, 0x0d, 0xea, 0x05, 0xaa, + 0xc6, 0x3e, 0xaf, 0xc6, 0x2e, 0x91, 0xdf, 0x64, 0x9e, 0x7e, 0xf4, 0xb1, + 0x42, 0xf8, 0x24, 0x5f, 0x7a, 0xfb, 0x0c, 0xdb, 0x58, 0x6c, 0xe6, 0x75, + 0xe5, 0xe8, 0x69, 0xb2, 0x9d, 0x4a, 0x24, 0xf7, 0xe6, 0xeb, 0x2b, 0x38, + 0x15, 0x0a, 0x4c, 0xae, 0x9d, 0x57, 0xa2, 0x77, 0xe4, 0xe8, 0x49, 0xf2, + 0x1c, 0xc6, 0xa9, 0xa3, 0x9d, 0x01, 0xca, 0x72, 0x3e, 0x9c, 0x9f, 0x53, + 0xf1, 0xcd, 0xa9, 0x6d, 0x88, 0xed, 0x42, 0x29, 0xab, 0xc5, 0x96, 0x32, + 0xda, 0x68, 0x26, 0x84, 0x78, 0x49, 0xb4, 0x0c, 0x89, 0x11, 0xfa, 0xd6, + 0x68, 0x01, 0xdc, 0xf3, 0x24, 0xee, 0x0a, 0xd7, 0x72, 0xdf, 0x72, 0x3a, + 0x51, 0x80, 0x07, 0xcc, 0x8b, 0xb6, 0xe0, 0xe2, 0x49, 0x03, 0xd7, 0x15, + 0x10, 0x13, 0x6b, 0xc3, 0xa1, 0xd8, 0x3a, 0xe6, 0xb4, 0xc7, 0x1b, 0xdc, + 0xb7, 0x7c, 0x90, 0xf9, 0x3d, 0x79, 0xf1, 0xd5, 0xe3, 0x11, 0x7d, 0xe0, + 0xc4, 0xd2, 0x90, 0xf4, 0x29, 0xfd, 0xe5, 0x6d, 0x54, 0xfa, 0xb7, 0xed, + 0x50, 0xd8, 0xe7, 0xcc, 0x79, 0x7e, 0x0c, 0xef, 0x19, 0xf9, 0x31, 0xf8, + 0x9c, 0xf8, 0xcd, 0x1c, 0x98, 0x98, 0x23, 0x79, 0xc1, 0x11, 0xe5, 0xa8, + 0x93, 0x03, 0x5b, 0x31, 0xe6, 0xbe, 0x91, 0x9e, 0xc9, 0xdc, 0x77, 0x9c, + 0x3c, 0xf7, 0x38, 0x79, 0xee, 0xcb, 0x93, 0xb9, 0xef, 0x8b, 0x19, 0xa9, + 0x33, 0xb5, 0x7c, 0x24, 0x26, 0x6b, 0xd6, 0x23, 0x89, 0x50, 0x5d, 0xbe, + 0xce, 0xcb, 0x2c, 0x7f, 0xfc, 0x52, 0xf9, 0xd5, 0xcc, 0x57, 0x57, 0x61, + 0x5b, 0xaa, 0x04, 0x0f, 0x6a, 0x4e, 0x6e, 0xe9, 0x2d, 0x8c, 0x9e, 0xb8, + 0xef, 0x7d, 0x63, 0xbc, 0xce, 0x45, 0x1c, 0x1a, 0xe1, 0xe0, 0x5b, 0x12, + 0x0a, 0xfd, 0xce, 0x83, 0x1e, 0xad, 0x1c, 0x6b, 0xcd, 0x7f, 0xb2, 0x1f, + 0x5c, 0x25, 0xcf, 0xf2, 0x7b, 0x14, 0x52, 0xfe, 0x35, 0x96, 0x0f, 0x9a, + 0x23, 0x93, 0xb9, 0xe0, 0xd1, 0x04, 0xfa, 0x24, 0xcf, 0x5a, 0xd3, 0x1c, + 0xd2, 0xbb, 0x9d, 0x75, 0x63, 0x1d, 0xeb, 0x32, 0x3a, 0xd6, 0x53, 0x9e, + 0xb4, 0x7b, 0x32, 0x47, 0xca, 0xc5, 0x62, 0x4b, 0x78, 0xe6, 0x22, 0x96, + 0xdb, 0x3c, 0x89, 0x33, 0x2d, 0x97, 0x78, 0xae, 0x6d, 0xf7, 0x9b, 0x79, + 0xae, 0xcb, 0x58, 0x50, 0x29, 0xb9, 0x35, 0x68, 0x17, 0x15, 0x48, 0xfb, + 0x65, 0x4f, 0x66, 0xea, 0x18, 0x11, 0x2b, 0x8c, 0x86, 0xf4, 0xd9, 0xea, + 0x54, 0xec, 0x92, 0xb1, 0x0a, 0x6e, 0x59, 0x8e, 0x7e, 0x8e, 0x5d, 0x1a, + 0x6f, 0x7d, 0xa1, 0x60, 0xd6, 0xc1, 0x44, 0x77, 0x01, 0x6d, 0x4b, 0x2d, + 0x10, 0x7b, 0x40, 0xee, 0x1e, 0xb2, 0xb6, 0xbd, 0xfd, 0x0a, 0xdd, 0x15, + 0xc4, 0x98, 0x0a, 0xe0, 0xe9, 0x44, 0x28, 0x76, 0x16, 0x96, 0x72, 0x32, + 0xe3, 0xa6, 0xad, 0x4b, 0xbb, 0x5b, 0xd8, 0x5e, 0x8f, 0x72, 0xe2, 0x52, + 0x9b, 0x17, 0x2e, 0x6e, 0x76, 0xd6, 0x71, 0xf3, 0xbe, 0xe2, 0xc5, 0x43, + 0x7d, 0xf9, 0xbd, 0xc6, 0x18, 0xde, 0x33, 0x05, 0x17, 0xbd, 0xe4, 0x3d, + 0xcc, 0xd2, 0x13, 0xdb, 0x90, 0xf3, 0x4b, 0xf9, 0xe4, 0xe7, 0xfd, 0xa0, + 0x5b, 0x30, 0xec, 0x27, 0xb3, 0x63, 0x93, 0x6b, 0x2e, 0x7f, 0xac, 0x4c, + 0x1e, 0xdb, 0x2f, 0x5c, 0xec, 0x4b, 0x55, 0x4f, 0xc9, 0xb3, 0x69, 0x5f, + 0x03, 0xc1, 0x1e, 0x0b, 0x95, 0x6c, 0xc3, 0x8d, 0xbf, 0x65, 0xfc, 0x76, + 0x0f, 0x1c, 0xbd, 0x41, 0x52, 0x32, 0xcf, 0xa1, 0x18, 0x36, 0x37, 0x7b, + 0xe0, 0x1a, 0xaa, 0x2e, 0xcc, 0xad, 0xf3, 0x91, 0x3c, 0x3b, 0xdf, 0x8a, + 0x83, 0xd3, 0x6a, 0x56, 0xf2, 0x6a, 0xd2, 0x88, 0x43, 0xa2, 0xd7, 0x4a, + 0x7e, 0x8b, 0x5e, 0xfc, 0xfc, 0x16, 0x1d, 0x55, 0xf1, 0xbb, 0x1c, 0xb1, + 0x2a, 0xd9, 0xf3, 0x6a, 0x47, 0x82, 0x98, 0x55, 0x12, 0xed, 0xc4, 0xd7, + 0x7b, 0x6d, 0xbb, 0x87, 0x7e, 0x59, 0xc4, 0x18, 0xff, 0x48, 0xa8, 0x3e, + 0x32, 0x47, 0x29, 0x20, 0xdf, 0x69, 0x47, 0xcf, 0x48, 0x41, 0xbc, 0x3c, + 0x5a, 0xc5, 0x98, 0xae, 0xe1, 0x93, 0xb9, 0x6d, 0xc8, 0x8e, 0x5e, 0xbd, + 0x57, 0x36, 0x75, 0x9f, 0x2c, 0xbf, 0x3f, 0x26, 0xe3, 0x11, 0xb9, 0x45, + 0xfe, 0x0b, 0x17, 0xb7, 0xa6, 0x44, 0x36, 0x0f, 0x0e, 0xf4, 0x89, 0xbc, + 0x36, 0x3a, 0xcc, 0x5b, 0x29, 0x27, 0x91, 0xbe, 0x72, 0xea, 0xfc, 0xe6, + 0xdb, 0x91, 0x75, 0xf0, 0x4e, 0x65, 0x98, 0xf3, 0x65, 0xb9, 0x0b, 0xc5, + 0xbf, 0x34, 0xe6, 0x15, 0xca, 0x73, 0x19, 0x69, 0xa3, 0x45, 0x19, 0x49, + 0x4f, 0xad, 0xd3, 0xa9, 0x1c, 0xca, 0x3c, 0x5c, 0x28, 0x9c, 0xe3, 0xb2, + 0x1e, 0xf3, 0x32, 0x90, 0xdc, 0xd2, 0x5e, 0x2a, 0x92, 0xa2, 0x7f, 0xd1, + 0x8f, 0x0e, 0x77, 0x96, 0xbf, 0xb3, 0x5f, 0xd6, 0xe7, 0xd5, 0x3e, 0x36, + 0xf7, 0x0a, 0x9f, 0x3c, 0x4e, 0x9f, 0x1c, 0xff, 0xa3, 0x3e, 0x39, 0xef, + 0x4f, 0x94, 0xcf, 0xaf, 0xb7, 0xda, 0xf6, 0x6e, 0x53, 0xd6, 0xe8, 0x65, + 0xdd, 0xb5, 0xe1, 0x4b, 0xf6, 0x5e, 0x65, 0x3d, 0x7e, 0x36, 0xd2, 0x95, + 0xc1, 0xb4, 0xac, 0xbf, 0x0c, 0xa4, 0x80, 0x45, 0x49, 0xe9, 0x27, 0x46, + 0x7d, 0xa9, 0xb7, 0x32, 0x1a, 0x31, 0x43, 0xe8, 0xc2, 0x19, 0xd3, 0xd8, + 0xf7, 0x20, 0x79, 0x77, 0x37, 0x73, 0xd2, 0x83, 0xe6, 0x72, 0xfa, 0x7b, + 0x31, 0x36, 0x34, 0xd0, 0x18, 0x57, 0x98, 0xf4, 0x7b, 0xab, 0x9d, 0xae, + 0xe8, 0xf5, 0x45, 0xdb, 0x57, 0x25, 0x42, 0xc1, 0xb6, 0x8d, 0xc4, 0xf3, + 0xa5, 0xbd, 0x5e, 0xe8, 0x8a, 0xc3, 0x07, 0x5a, 0x7f, 0xa1, 0x0a, 0x46, + 0x9d, 0x29, 0xc8, 0xe5, 0xcd, 0xb2, 0xe6, 0x22, 0xfd, 0x2c, 0x67, 0x5e, + 0x22, 0x75, 0x75, 0xb4, 0xd7, 0x2a, 0x48, 0xd5, 0x06, 0xfb, 0xe0, 0xb2, + 0xed, 0xdf, 0x91, 0x17, 0x8e, 0x3b, 0xb9, 0x7c, 0x7d, 0xdd, 0x6e, 0xf5, + 0x7f, 0x10, 0x0b, 0x9d, 0x36, 0x34, 0x59, 0xf3, 0x7f, 0xe1, 0x4f, 0xae, + 0x7b, 0x9b, 0x90, 0xbd, 0x89, 0x42, 0x63, 0x89, 0x32, 0xe2, 0xcf, 0x71, + 0x8a, 0xdb, 0x06, 0x3e, 0xbf, 0xf8, 0x64, 0x4a, 0xec, 0x1c, 0x55, 0x01, + 0x63, 0x06, 0x66, 0x1f, 0x28, 0xc5, 0xb2, 0x01, 0xe1, 0x0a, 0x3e, 0xab, + 0x30, 0x1a, 0xc0, 0x9c, 0x03, 0x95, 0x68, 0xd9, 0x23, 0xfb, 0x50, 0x76, + 0x57, 0x45, 0x74, 0x35, 0xdc, 0x87, 0x34, 0x3c, 0xb0, 0xc7, 0xb6, 0x67, + 0xcd, 0x23, 0xb5, 0x63, 0x4c, 0x7c, 0xb7, 0x69, 0x15, 0x3c, 0xd9, 0x6a, + 0x2c, 0x49, 0xd6, 0x39, 0x6b, 0xad, 0x1f, 0x26, 0x5a, 0x5b, 0xce, 0xf5, + 0xd6, 0x6e, 0xa8, 0x55, 0x82, 0xe6, 0x29, 0x25, 0x82, 0x82, 0x6c, 0x04, + 0xae, 0xa4, 0x82, 0x57, 0x0d, 0x74, 0x95, 0x45, 0xa3, 0x70, 0x65, 0xa3, + 0xf0, 0x25, 0xdd, 0x68, 0xa0, 0xbe, 0x4b, 0x38, 0xf7, 0xd3, 0x92, 0xd5, + 0x98, 0x96, 0xbd, 0x0e, 0xfa, 0x81, 0x06, 0xfa, 0x48, 0x25, 0xfb, 0xf3, + 0xa3, 0x25, 0xd9, 0x86, 0x69, 0x46, 0x33, 0x6d, 0xa3, 0x19, 0x33, 0x93, + 0x7e, 0x2c, 0xe0, 0x7c, 0x2c, 0x4e, 0xb6, 0xb2, 0x1f, 0x1f, 0xda, 0x07, + 0xee, 0x44, 0x60, 0xc8, 0x8b, 0xf2, 0x01, 0x1d, 0x1f, 0xce, 0xf5, 0xa2, + 0x68, 0x28, 0x80, 0xd2, 0xa4, 0xec, 0x8d, 0x21, 0xb6, 0xb1, 0x39, 0x00, + 0x5f, 0x16, 0x28, 0x19, 0xb0, 0xf1, 0xad, 0xf0, 0xa8, 0x7a, 0x77, 0xa5, + 0x65, 0x4f, 0x73, 0x62, 0x41, 0x6b, 0xfb, 0x16, 0xe3, 0xce, 0x49, 0xbf, + 0x77, 0x33, 0xcf, 0x52, 0xc8, 0xd7, 0x25, 0x06, 0xb6, 0xb6, 0x1f, 0x4c, + 0xc8, 0xda, 0x46, 0x88, 0x7e, 0xeb, 0x81, 0x77, 0xa8, 0x53, 0xe9, 0xa3, + 0xed, 0xa0, 0x40, 0xf4, 0xaf, 0xd2, 0xbf, 0xa0, 0x95, 0xd2, 0xce, 0xb7, + 0x66, 0x5a, 0x94, 0x64, 0xba, 0x53, 0xe9, 0xcd, 0x94, 0x78, 0x51, 0x2c, + 0xf3, 0xf2, 0x15, 0x8c, 0x36, 0x3c, 0x69, 0xa7, 0x2b, 0x9c, 0xb9, 0xb5, + 0x3c, 0x90, 0x9c, 0xdb, 0x5a, 0x15, 0xae, 0x0d, 0x76, 0x56, 0xa8, 0xb2, + 0x9f, 0x42, 0x1c, 0x52, 0x72, 0x7d, 0x69, 0x46, 0x12, 0xcf, 0xfa, 0x65, + 0x7d, 0x55, 0xe6, 0xbf, 0xb5, 0x3d, 0xd1, 0x7b, 0xe1, 0xa2, 0xcc, 0xe9, + 0xc7, 0xb4, 0xc3, 0xdb, 0x93, 0x9f, 0x5f, 0xdc, 0x97, 0x6a, 0x63, 0x9e, + 0x66, 0xe2, 0x55, 0xfe, 0x5e, 0xc4, 0x71, 0xbf, 0x98, 0xf1, 0x61, 0x61, + 0xb2, 0xd9, 0xd9, 0x8b, 0x5b, 0x96, 0x8c, 0xe0, 0x15, 0x7e, 0xb7, 0x24, + 0x57, 0xe1, 0x18, 0xf3, 0xd4, 0x07, 0x92, 0x51, 0xbc, 0x9d, 0x09, 0xe0, + 0x7e, 0xea, 0x6f, 0x06, 0xed, 0xf4, 0xae, 0xa4, 0x8e, 0x37, 0x32, 0xc0, + 0xcf, 0xfa, 0x6c, 0x84, 0x1a, 0xbf, 0xa3, 0x3e, 0xed, 0xac, 0x8d, 0x35, + 0xe3, 0x67, 0x09, 0x13, 0x6f, 0x24, 0x6a, 0xcc, 0x9b, 0xd5, 0xdf, 0x62, + 0xdc, 0x9d, 0xa0, 0x4d, 0x9d, 0x47, 0xbc, 0x52, 0xd6, 0xf1, 0x72, 0xf2, + 0x77, 0x8f, 0x79, 0x98, 0x63, 0x6d, 0xc0, 0x11, 0xbf, 0xb3, 0x2e, 0x71, + 0x85, 0x5c, 0xb2, 0x36, 0xb1, 0x88, 0x72, 0x3d, 0x95, 0x22, 0x57, 0x34, + 0xaa, 0x29, 0x8f, 0x17, 0x0b, 0x07, 0xbc, 0xa8, 0xa4, 0x6d, 0x9c, 0x3e, + 0x10, 0xc5, 0xce, 0x54, 0x11, 0x5a, 0xfa, 0x03, 0x38, 0xc3, 0xeb, 0xad, + 0xb4, 0xf1, 0x1f, 0xb1, 0x6f, 0xa3, 0x49, 0xc3, 0x80, 0x56, 0x84, 0x9e, + 0xba, 0x1f, 0x93, 0xef, 0xa9, 0xcc, 0x39, 0x98, 0x1b, 0x18, 0x25, 0xd8, + 0xc1, 0xb4, 0xbe, 0xb0, 0x39, 0x88, 0xfe, 0x3a, 0xda, 0x7a, 0x15, 0xe3, + 0x87, 0x11, 0x43, 0x39, 0x31, 0x26, 0xc5, 0x5c, 0xb1, 0x30, 0x6a, 0x51, + 0x06, 0x15, 0xfb, 0x34, 0x55, 0xd6, 0xe4, 0xf8, 0x2c, 0x80, 0x63, 0x09, + 0xd8, 0xc5, 0x51, 0xe3, 0xc2, 0x4e, 0x84, 0x4e, 0xbc, 0xcf, 0xb8, 0xfe, + 0xf7, 0x99, 0x12, 0x7c, 0xbf, 0x6f, 0x36, 0xfe, 0x36, 0x2d, 0xeb, 0xbd, + 0x3e, 0xac, 0x1f, 0x0c, 0xab, 0xb9, 0xb5, 0x4a, 0x1f, 0x1e, 0x1a, 0x84, + 0x35, 0x93, 0xf6, 0xf8, 0xf2, 0x70, 0x19, 0xd6, 0xf4, 0xbd, 0x60, 0x33, + 0x77, 0xa6, 0x5d, 0x7b, 0x71, 0x34, 0x2d, 0x32, 0x96, 0x53, 0xc6, 0x22, + 0x1c, 0xe3, 0x75, 0x0f, 0x6d, 0xbf, 0xb2, 0xf7, 0xdb, 0xf8, 0x2c, 0x55, + 0x53, 0x77, 0xbf, 0xda, 0x8e, 0xe3, 0xce, 0x7e, 0x6c, 0x03, 0xde, 0xa2, + 0x1e, 0xcb, 0x77, 0xdb, 0xf6, 0x6f, 0xc2, 0x31, 0xfc, 0x2c, 0x73, 0x2d, + 0x8a, 0x78, 0x6d, 0x86, 0x5b, 0xf0, 0x66, 0xa6, 0x1a, 0x65, 0xbd, 0xad, + 0x78, 0x9d, 0x9c, 0xbf, 0x74, 0x77, 0x27, 0x4e, 0xb1, 0x7d, 0x5f, 0xbf, + 0x17, 0xaf, 0xa5, 0xbd, 0x78, 0xb5, 0xcf, 0xd0, 0xd6, 0x2a, 0x7f, 0xa7, + 0xc4, 0x2b, 0x73, 0xfd, 0x0c, 0xa4, 0x72, 0xfa, 0xdc, 0x3e, 0x56, 0x00, + 0xc1, 0xf2, 0x43, 0x7e, 0x59, 0xbf, 0x95, 0xf3, 0x31, 0xad, 0xed, 0x5a, + 0xf2, 0x77, 0x17, 0x13, 0xd4, 0xe7, 0x9b, 0xa3, 0x01, 0xdc, 0x91, 0x14, + 0xdd, 0x7e, 0x7e, 0x71, 0x17, 0xb1, 0xa3, 0x77, 0x34, 0x82, 0x13, 0x09, + 0x8f, 0xb3, 0xe7, 0xd8, 0x33, 0x2a, 0xfb, 0xb1, 0xdf, 0xe5, 0xdc, 0x00, + 0x6b, 0x47, 0x73, 0x6d, 0x6d, 0x19, 0x2b, 0xa4, 0xee, 0x6e, 0xc7, 0xd3, + 0x5a, 0x81, 0xc4, 0xdf, 0x9c, 0x8d, 0x1a, 0x41, 0xda, 0xee, 0x77, 0x9d, + 0xf5, 0xbd, 0x81, 0x54, 0xbd, 0x36, 0x0d, 0xf9, 0x79, 0xac, 0xc1, 0x4c, + 0xe3, 0xf7, 0xf6, 0x0b, 0x7e, 0x59, 0x77, 0x15, 0xbe, 0xd8, 0xda, 0xbe, + 0x36, 0x21, 0xfd, 0xe8, 0xd8, 0x3c, 0x7a, 0xe1, 0x62, 0x3f, 0xf9, 0xfa, + 0x12, 0xda, 0xc8, 0xba, 0x90, 0x1f, 0x8b, 0x6b, 0xeb, 0x50, 0x9b, 0x95, + 0x35, 0xdd, 0x08, 0x39, 0xab, 0x89, 0x8e, 0x50, 0xd4, 0xd9, 0xd7, 0x82, + 0x9a, 0xbf, 0xe7, 0xc5, 0xbb, 0x7f, 0xe0, 0x2b, 0xc0, 0xac, 0x81, 0x36, + 0xf6, 0x6b, 0x63, 0x99, 0xf9, 0x0f, 0x76, 0xcb, 0x3d, 0xd2, 0x7f, 0x4d, + 0x59, 0xee, 0x19, 0x27, 0xbc, 0x58, 0x7e, 0x37, 0xd1, 0x97, 0x1a, 0x71, + 0xd8, 0x2f, 0x3c, 0x43, 0xfc, 0xa0, 0xb5, 0x3d, 0x4c, 0xfb, 0xd9, 0x41, + 0x19, 0x56, 0xd0, 0x76, 0x96, 0x11, 0x17, 0xca, 0x8d, 0x0b, 0x17, 0x7b, + 0x53, 0x26, 0xe6, 0x8c, 0xfa, 0x68, 0xcb, 0x45, 0xec, 0xaf, 0x19, 0xc6, + 0x28, 0x71, 0x84, 0xf6, 0xbd, 0x60, 0xd4, 0x4f, 0x7b, 0xd6, 0x31, 0x7f, + 0x54, 0x7c, 0xdc, 0x40, 0x88, 0xb1, 0xac, 0x9d, 0x75, 0x22, 0xa3, 0x15, + 0xb8, 0x79, 0xbf, 0x1b, 0x77, 0x26, 0xc3, 0xd4, 0x4f, 0x1d, 0x63, 0xdc, + 0x65, 0x7d, 0x6f, 0x1b, 0x9b, 0x85, 0x0a, 0xe3, 0x88, 0xfd, 0x9c, 0x83, + 0x61, 0x85, 0x8e, 0x9e, 0x02, 0xec, 0x37, 0x90, 0x82, 0x55, 0xce, 0xf8, + 0x72, 0x61, 0xf4, 0xb9, 0x2f, 0xe2, 0xf7, 0x8a, 0x2e, 0xa7, 0x8e, 0x47, + 0x30, 0xe5, 0x02, 0xb1, 0x0e, 0x68, 0x7c, 0xc2, 0xc6, 0xe2, 0xc6, 0x8d, + 0xca, 0x0f, 0x1c, 0x5b, 0x92, 0x76, 0x85, 0x3b, 0xe4, 0xf5, 0x9f, 0xd7, + 0xf9, 0x6f, 0x0a, 0x72, 0x3a, 0xcf, 0x8f, 0x33, 0xb8, 0x4f, 0x70, 0x7a, + 0x7d, 0x63, 0x1e, 0xa7, 0xa5, 0xbc, 0xdc, 0x5f, 0x61, 0xf7, 0x6a, 0x70, + 0x17, 0x1a, 0x2e, 0x6c, 0xaf, 0x7b, 0x46, 0x99, 0xd0, 0xc4, 0xe7, 0x15, + 0x62, 0xc7, 0xed, 0x36, 0xdd, 0x96, 0x76, 0xfd, 0x12, 0xcb, 0x41, 0x29, + 0xbc, 0x34, 0x97, 0xc2, 0x3f, 0xba, 0x27, 0xe7, 0x52, 0x78, 0x6f, 0x7e, + 0x4c, 0x79, 0x59, 0x23, 0xe4, 0x76, 0x22, 0xaf, 0xd8, 0x86, 0x94, 0x79, + 0xb0, 0xc8, 0x59, 0x8f, 0x46, 0xf7, 0x14, 0x7b, 0xc8, 0x73, 0x18, 0xa7, + 0x0d, 0x0d, 0x97, 0xec, 0xc1, 0x8d, 0xb6, 0xa4, 0xcc, 0x3b, 0xac, 0x62, + 0xea, 0xa1, 0x6d, 0xd4, 0xc3, 0xf9, 0x13, 0x2e, 0xae, 0x62, 0x89, 0xb9, + 0x5d, 0x19, 0xf7, 0xef, 0x64, 0x1b, 0x9f, 0x5f, 0x64, 0x1d, 0xde, 0xeb, + 0xe5, 0xf5, 0x75, 0xb8, 0x9d, 0x38, 0xba, 0x36, 0x6c, 0x29, 0xb9, 0x73, + 0x05, 0x45, 0xb8, 0x71, 0xa0, 0x12, 0x3e, 0x43, 0xd6, 0x2d, 0xfe, 0xb3, + 0xe2, 0xab, 0x90, 0xf1, 0x3b, 0x9c, 0x81, 0x76, 0x72, 0x1d, 0x16, 0x0f, + 0x30, 0x64, 0x3b, 0x7b, 0x04, 0x0b, 0xf1, 0x74, 0xf3, 0x75, 0x58, 0xea, + 0x70, 0x9d, 0x10, 0x6e, 0x1a, 0x12, 0x0c, 0xed, 0x54, 0xfa, 0x89, 0x9d, + 0x4c, 0x38, 0xe8, 0xd7, 0x31, 0xa5, 0x8f, 0x98, 0xb9, 0xcf, 0xf1, 0x11, + 0x59, 0x2f, 0xee, 0x54, 0x52, 0x99, 0x0a, 0x8e, 0x43, 0x6c, 0xf7, 0xb2, + 0x8c, 0x33, 0x29, 0xe3, 0x79, 0x62, 0xd1, 0xfc, 0x49, 0x19, 0x67, 0x37, + 0x49, 0x2e, 0x2b, 0x32, 0x16, 0xa1, 0x96, 0x72, 0x54, 0x52, 0x8e, 0x63, + 0x66, 0x85, 0x32, 0xa0, 0xe5, 0x64, 0xab, 0x61, 0xff, 0x8c, 0x39, 0x58, + 0x63, 0xfa, 0x94, 0x65, 0xce, 0xbd, 0xbc, 0x6c, 0x9f, 0x5f, 0xec, 0x49, + 0x7d, 0x61, 0xfb, 0x8c, 0x9c, 0x9c, 0x65, 0xfd, 0x3a, 0x4e, 0xcd, 0xbd, + 0x0e, 0xa5, 0xfb, 0x8b, 0xd0, 0x48, 0x5c, 0xaf, 0x1f, 0x30, 0xfa, 0x36, + 0x2a, 0x22, 0xab, 0x87, 0xbf, 0x9d, 0x75, 0x03, 0xea, 0xf3, 0xff, 0x2f, + 0xbc, 0xd2, 0x8e, 0xdd, 0x58, 0x91, 0xcc, 0xd9, 0xb0, 0xe3, 0xbf, 0xb5, + 0x62, 0xbf, 0xb2, 0x46, 0x48, 0x7b, 0xce, 0xb8, 0xb0, 0x84, 0x7d, 0x1f, + 0x33, 0x1f, 0x56, 0x2c, 0xed, 0xc2, 0x45, 0xd9, 0xaf, 0x57, 0x29, 0x63, + 0x77, 0xfa, 0x3a, 0xdc, 0x31, 0x30, 0x6e, 0x7b, 0x8d, 0x05, 0xc8, 0x84, + 0x43, 0xed, 0x3d, 0x8a, 0x17, 0xbb, 0xd2, 0x2e, 0x2c, 0x1a, 0x20, 0x5f, + 0x33, 0xe3, 0x4a, 0x6c, 0x7a, 0x8e, 0x87, 0x2f, 0x4c, 0x32, 0x1f, 0xcd, + 0x4a, 0x7e, 0xd8, 0xd6, 0xbe, 0x30, 0xf1, 0x80, 0x12, 0xd3, 0x3e, 0xbf, + 0x98, 0x4c, 0x1d, 0xfd, 0xae, 0xea, 0xf0, 0x30, 0x1f, 0xde, 0x3c, 0xe8, + 0xa3, 0x2f, 0x28, 0xf4, 0x13, 0x3f, 0x7d, 0xbf, 0x01, 0x6f, 0xd3, 0x37, + 0xee, 0x67, 0x5c, 0xfc, 0xfb, 0xd1, 0x2a, 0xdc, 0xb6, 0x27, 0x8a, 0x97, + 0x0f, 0xfa, 0xd1, 0xbe, 0xe7, 0x56, 0xbc, 0xc5, 0x72, 0x63, 0x8c, 0x07, + 0x63, 0xc3, 0x95, 0xfc, 0xf8, 0xf9, 0xa9, 0xe2, 0x67, 0x2d, 0xf1, 0xa8, + 0x02, 0x27, 0xf7, 0xbb, 0xd0, 0x32, 0xa0, 0x62, 0xc0, 0x54, 0x70, 0xf7, + 0x4d, 0x32, 0x1e, 0x2f, 0xd6, 0xd4, 0x5e, 0xb6, 0x8b, 0x25, 0x49, 0xe1, + 0x70, 0x5e, 0xce, 0x93, 0x8e, 0x43, 0xf4, 0xcb, 0xdb, 0xc8, 0xc1, 0x76, + 0xf4, 0xb5, 0xd1, 0x8f, 0x6c, 0xcc, 0x0a, 0xff, 0x18, 0x2b, 0xb4, 0x1e, + 0xc9, 0x6b, 0x9d, 0x75, 0xfe, 0x14, 0xe7, 0x71, 0xc2, 0x53, 0x6f, 0x4d, + 0x43, 0x51, 0x2c, 0x10, 0x0d, 0x69, 0x47, 0xb0, 0x1c, 0x7d, 0x63, 0xd0, + 0x64, 0xcd, 0x7f, 0x1b, 0x79, 0xd4, 0x76, 0xf2, 0xa8, 0xee, 0xcc, 0x11, + 0xce, 0xb1, 0xcf, 0x2b, 0x7b, 0xdf, 0xdb, 0xa8, 0xbb, 0xc5, 0x0e, 0x27, + 0xf2, 0x5a, 0x45, 0x6c, 0xff, 0x38, 0x63, 0xd2, 0x82, 0xfe, 0x1c, 0x6e, + 0x7c, 0xd6, 0xf4, 0x3c, 0x8c, 0x69, 0x3d, 0xf4, 0xf9, 0x5c, 0xdb, 0x3b, + 0x85, 0x9b, 0x79, 0xca, 0x62, 0x65, 0xd1, 0xd0, 0x86, 0xd7, 0xa9, 0x7c, + 0x2f, 0xdb, 0xdc, 0x3a, 0xb9, 0x8f, 0xd0, 0xcb, 0x36, 0x7b, 0x58, 0xb7, + 0xbe, 0xdf, 0xe2, 0x5c, 0xba, 0x59, 0x3f, 0x14, 0xd8, 0xa8, 0x98, 0xac, + 0xeb, 0xe4, 0x11, 0xa8, 0xd9, 0x7f, 0x79, 0xae, 0xda, 0x88, 0x31, 0xfd, + 0x93, 0xfe, 0x7e, 0x7e, 0xf4, 0x3a, 0x84, 0x68, 0x24, 0x4f, 0x9b, 0x9b, + 0xa0, 0xd3, 0x66, 0x5d, 0x93, 0x7d, 0x6d, 0x97, 0x71, 0xb8, 0x67, 0xc6, + 0x66, 0xb2, 0x8f, 0xbe, 0x4c, 0x48, 0xeb, 0x42, 0xfd, 0x89, 0x69, 0x90, + 0x71, 0x48, 0x7f, 0xcb, 0xf1, 0xe4, 0xd8, 0xd5, 0xe3, 0xa8, 0x26, 0x3e, + 0x5d, 0x2c, 0x98, 0x3c, 0x33, 0xe7, 0xe4, 0xe2, 0x31, 0xc7, 0xc7, 0x76, + 0x38, 0xf2, 0x7b, 0xd8, 0x66, 0x36, 0xb7, 0x07, 0x22, 0x69, 0x95, 0x32, + 0xc2, 0x58, 0xd1, 0x96, 0x54, 0x62, 0x15, 0xd1, 0xfa, 0xce, 0x69, 0x08, + 0x45, 0x7e, 0xc6, 0xb6, 0xa7, 0xb1, 0xed, 0x67, 0xd9, 0x76, 0x8a, 0x6d, + 0x8f, 0xb0, 0xed, 0x1f, 0x5c, 0x6a, 0x5b, 0xc5, 0xfd, 0x7b, 0xf2, 0xb6, + 0xe5, 0x46, 0xa4, 0x89, 0x59, 0xdf, 0x34, 0xd9, 0x03, 0xad, 0xe6, 0xdc, + 0x8b, 0xee, 0x74, 0xc6, 0xf6, 0x9c, 0xbd, 0x2d, 0x60, 0xec, 0xb9, 0x6b, + 0x8f, 0x82, 0xf7, 0xc3, 0xef, 0x63, 0xc2, 0x9f, 0xe3, 0x11, 0x79, 0x1b, + 0xd2, 0x68, 0x43, 0x5a, 0xf2, 0x7f, 0xd2, 0xf4, 0xa5, 0x8e, 0xd8, 0x8f, + 0xec, 0x3f, 0x90, 0x3f, 0x27, 0x44, 0x1f, 0xbf, 0x23, 0xee, 0x86, 0x4e, + 0xbc, 0xc7, 0xd8, 0xf9, 0xa3, 0x8c, 0x07, 0xe9, 0xb4, 0x0f, 0xcf, 0x66, + 0x04, 0x1b, 0xdb, 0x88, 0x8d, 0x82, 0xf7, 0xe4, 0x81, 0xc3, 0x47, 0x1f, + 0x0b, 0xb0, 0xf2, 0xb3, 0xb4, 0x9f, 0x67, 0x69, 0x3f, 0xcf, 0x0e, 0xfb, + 0x70, 0xf3, 0x21, 0x2f, 0xce, 0x11, 0x6b, 0x7a, 0x59, 0x26, 0x91, 0x6a, + 0xc0, 0x4d, 0xe4, 0x59, 0x87, 0x7b, 0x19, 0x97, 0x19, 0xff, 0xeb, 0xb2, + 0x1a, 0x76, 0xf5, 0x57, 0xa0, 0x7e, 0x48, 0x62, 0x70, 0x05, 0x1e, 0xe9, + 0xf3, 0x62, 0xce, 0x7e, 0xd9, 0x87, 0x24, 0x2f, 0xec, 0xbb, 0x13, 0xc3, + 0x8e, 0x8f, 0x4f, 0xa3, 0x7f, 0x54, 0xa2, 0x76, 0x48, 0xae, 0xc9, 0x53, + 0x68, 0xb3, 0x0b, 0x0e, 0x55, 0x71, 0xbc, 0xb7, 0x62, 0xfe, 0xa1, 0x00, + 0xf1, 0xdc, 0x8f, 0x48, 0x76, 0xf9, 0x45, 0xc1, 0xe4, 0xed, 0x63, 0x53, + 0x63, 0x9a, 0xf8, 0xa1, 0x83, 0x61, 0x91, 0x3c, 0x86, 0x5d, 0x7e, 0x3e, + 0x15, 0x27, 0x7f, 0xcb, 0x67, 0x52, 0x26, 0x1f, 0x7b, 0xa6, 0xe2, 0xe2, + 0x65, 0x7c, 0x6a, 0x1c, 0x90, 0x6f, 0x0d, 0xed, 0xf3, 0xc4, 0xd7, 0xaf, + 0x43, 0xc4, 0x91, 0xe7, 0xfe, 0x62, 0x96, 0x0b, 0xe4, 0xfc, 0x7d, 0x2a, + 0x9e, 0xfb, 0x26, 0xfd, 0xd4, 0x85, 0x58, 0x45, 0x8e, 0x0b, 0xdf, 0xbe, + 0xa7, 0x01, 0xbb, 0xa8, 0x8f, 0x56, 0xfa, 0x91, 0x2f, 0x1c, 0xb5, 0xad, + 0x0a, 0xc9, 0x5b, 0x2b, 0x71, 0xe7, 0x1e, 0x3f, 0x63, 0xf8, 0xb5, 0x48, + 0x0e, 0xcf, 0x66, 0x5b, 0xd5, 0xe8, 0x9d, 0xcc, 0xe7, 0xb7, 0xa7, 0x96, + 0xd9, 0x0f, 0x39, 0x7b, 0xf2, 0xb2, 0xf6, 0xff, 0xda, 0x7d, 0xde, 0xd0, + 0xb8, 0xce, 0x7c, 0xde, 0x64, 0xce, 0x41, 0x0e, 0x76, 0x02, 0xa1, 0x4a, + 0xe6, 0xe7, 0x46, 0x39, 0x16, 0x31, 0x9f, 0x7f, 0xc8, 0x2f, 0xcf, 0x6e, + 0x15, 0x59, 0x9c, 0xf2, 0x97, 0xc7, 0xb8, 0x6b, 0xca, 0x18, 0xeb, 0x23, + 0xd3, 0x90, 0xe7, 0x63, 0x5f, 0xd8, 0x7f, 0x6f, 0x40, 0xe9, 0x0f, 0xd1, + 0x6a, 0x1b, 0x83, 0x7d, 0x0f, 0x29, 0x86, 0xd6, 0xa4, 0x12, 0xba, 0x46, + 0xdf, 0xc4, 0x92, 0xec, 0x2f, 0x10, 0xcb, 0xae, 0xf6, 0x8a, 0x2c, 0xf7, + 0x67, 0x57, 0x61, 0x9c, 0x73, 0x5c, 0xc4, 0x3a, 0x37, 0xf4, 0xfa, 0x68, + 0xa3, 0x50, 0x0e, 0x37, 0xd7, 0xe1, 0x43, 0xf2, 0x9c, 0xb6, 0xe4, 0x9b, + 0xd0, 0x18, 0x5f, 0xef, 0x4c, 0xfe, 0x02, 0x65, 0xc4, 0x94, 0x3b, 0x92, + 0x5f, 0xd8, 0x23, 0xa1, 0x7d, 0x4e, 0xbd, 0xc2, 0xd1, 0x03, 0x17, 0xfb, + 0x2e, 0xc7, 0x27, 0xad, 0xd0, 0x78, 0xe5, 0x2a, 0x3c, 0x6c, 0x68, 0xd9, + 0x9c, 0x18, 0xfd, 0x5f, 0x9e, 0xe8, 0xaf, 0x7f, 0xfa, 0xfd, 0xe6, 0x9c, + 0x5d, 0xea, 0x99, 0xbb, 0xf0, 0x2d, 0x07, 0x77, 0xd7, 0x6c, 0x74, 0x47, + 0x3b, 0x1e, 0x93, 0xb5, 0xd0, 0x35, 0xce, 0x3a, 0x41, 0x3b, 0x76, 0xee, + 0x6d, 0xc3, 0xe6, 0xbd, 0x82, 0xad, 0xf5, 0xad, 0x8b, 0x94, 0x19, 0xf4, + 0xc3, 0x01, 0x27, 0x97, 0x71, 0x1b, 0x9f, 0xca, 0x9a, 0xab, 0xea, 0x71, + 0xf6, 0xc0, 0x74, 0xac, 0x19, 0xcd, 0xb5, 0x35, 0x2b, 0x53, 0x4a, 0xff, + 0x8a, 0x22, 0xc9, 0x9c, 0xc5, 0xc7, 0xd8, 0xc9, 0x79, 0xc1, 0xa9, 0x7e, + 0x89, 0x3b, 0x0a, 0x7c, 0xf7, 0xc8, 0x5e, 0xe6, 0x32, 0xe4, 0xf9, 0x7a, + 0x4c, 0xdb, 0xcc, 0xdf, 0x3b, 0x8a, 0x73, 0x72, 0x6d, 0xbe, 0x8a, 0x17, + 0xe5, 0xed, 0x41, 0x74, 0x97, 0xb7, 0xa1, 0x4f, 0x39, 0x06, 0xe6, 0xd8, + 0xe4, 0x83, 0x97, 0xfd, 0xf9, 0x8b, 0x22, 0x67, 0x5d, 0x30, 0x3b, 0x35, + 0xbe, 0x6f, 0x9f, 0xd4, 0xfd, 0x75, 0xc5, 0xf9, 0xd8, 0x94, 0x93, 0xd7, + 0x24, 0x16, 0x5e, 0x83, 0x98, 0x3f, 0xef, 0xff, 0xdf, 0xe4, 0xf3, 0xcd, + 0x82, 0x01, 0x93, 0x75, 0xef, 0x2e, 0x41, 0xf1, 0x76, 0x87, 0xc3, 0x5d, + 0x6e, 0x9f, 0x64, 0xf8, 0x8a, 0xf6, 0xa7, 0xda, 0xaf, 0xb4, 0x2f, 0x71, + 0x5a, 0x74, 0xda, 0xc8, 0xba, 0xa2, 0x3f, 0x07, 0xa3, 0x65, 0x4d, 0x96, + 0xdc, 0xad, 0xcd, 0xd9, 0xa7, 0x29, 0x26, 0x6f, 0xee, 0x66, 0x0e, 0x55, + 0xb2, 0x9f, 0xd7, 0xe4, 0x3e, 0x4b, 0x07, 0x02, 0x28, 0xda, 0xef, 0x21, + 0xae, 0xcf, 0x80, 0x7b, 0x7f, 0x01, 0xed, 0x55, 0x38, 0xc2, 0x6b, 0xf7, + 0x6d, 0x31, 0xae, 0x85, 0x6b, 0x7f, 0x21, 0x79, 0xb9, 0x70, 0xbe, 0x13, + 0xf7, 0xad, 0x65, 0x1c, 0x57, 0xf7, 0x7b, 0x19, 0x9f, 0xab, 0xe1, 0x61, + 0xcc, 0x5b, 0x32, 0xf0, 0x67, 0x28, 0xd8, 0x5f, 0x8c, 0x07, 0x06, 0xae, + 0xc7, 0xcc, 0xfd, 0x25, 0xb8, 0x7f, 0x60, 0x26, 0x66, 0xec, 0x97, 0xdc, + 0x49, 0x47, 0x60, 0x7f, 0x29, 0x56, 0x0c, 0x04, 0x51, 0xb1, 0xbf, 0x0c, + 0x6d, 0x03, 0xb3, 0xa0, 0xed, 0x2f, 0xc7, 0x5d, 0x03, 0x35, 0x28, 0xdf, + 0xaf, 0xe1, 0xce, 0x01, 0x03, 0x65, 0xfb, 0x2b, 0x18, 0xd3, 0x42, 0x8c, + 0x9d, 0x7e, 0x2c, 0xdf, 0xc3, 0xb9, 0x39, 0x58, 0x45, 0xbf, 0x58, 0x45, + 0x4e, 0xbd, 0x1a, 0xfb, 0x52, 0x73, 0x50, 0x72, 0x30, 0x80, 0xa5, 0x7b, + 0xc6, 0x35, 0x52, 0x1a, 0x2c, 0x0e, 0x35, 0xa0, 0xe8, 0xa0, 0xe4, 0x7e, + 0xc1, 0x13, 0x2d, 0x08, 0x5e, 0x58, 0x84, 0x72, 0xe6, 0xbe, 0xc0, 0x7b, + 0x63, 0xc0, 0xec, 0x31, 0x17, 0x8e, 0x68, 0xab, 0xb0, 0x75, 0xec, 0x9b, + 0x93, 0x36, 0x2f, 0xfb, 0x47, 0xe5, 0x9c, 0x5f, 0xb9, 0x96, 0x7b, 0xab, + 0xd1, 0x33, 0x96, 0x5f, 0x07, 0x0b, 0xf6, 0x6d, 0xa7, 0x06, 0xc7, 0x33, + 0xf2, 0x4c, 0x7c, 0x04, 0xb4, 0x6f, 0xa5, 0x5b, 0xce, 0x8f, 0xbb, 0xa2, + 0x6a, 0x59, 0x77, 0xf3, 0x86, 0x5b, 0xe2, 0x99, 0x4d, 0xcc, 0xbb, 0x24, + 0x87, 0xdd, 0x78, 0xcb, 0x9a, 0xcc, 0x07, 0x97, 0xf6, 0x13, 0xfa, 0xcc, + 0x85, 0x01, 0x0d, 0x5f, 0xc3, 0x1a, 0x67, 0x0d, 0x55, 0xe5, 0x9c, 0xc9, + 0x79, 0x56, 0xe7, 0x2c, 0x39, 0xed, 0x2c, 0x0e, 0xd3, 0xc1, 0xd4, 0x75, + 0xa8, 0xc9, 0x38, 0x6b, 0xb5, 0x75, 0x71, 0xbc, 0xa0, 0xb6, 0x1a, 0xd6, + 0xe4, 0xd9, 0x0f, 0x6b, 0xbe, 0x86, 0x98, 0xa9, 0x5d, 0x3a, 0x1f, 0x12, + 0xd4, 0x47, 0x10, 0x0c, 0x6c, 0xc3, 0x3a, 0xe7, 0x7c, 0xa0, 0x12, 0x6d, + 0x97, 0x73, 0x46, 0xfc, 0x5e, 0x0d, 0x23, 0x93, 0x5f, 0x6b, 0x94, 0xb3, + 0xd7, 0xb2, 0x8f, 0x65, 0x33, 0xe7, 0x97, 0x3c, 0xf9, 0x88, 0xa2, 0xf6, + 0x3a, 0xeb, 0x63, 0xab, 0x5c, 0x8c, 0x01, 0x2d, 0x0a, 0xe2, 0x45, 0xd1, + 0x90, 0xfe, 0xe1, 0xe4, 0xba, 0x83, 0x67, 0x74, 0x8b, 0x52, 0x30, 0xda, + 0xa3, 0xb8, 0x47, 0x73, 0xeb, 0x0e, 0x2e, 0xf2, 0xd8, 0x6d, 0xa9, 0x4a, + 0x96, 0xd1, 0x30, 0x7b, 0xae, 0x1b, 0xaf, 0x26, 0xca, 0x9c, 0xb3, 0xc7, + 0x5b, 0xe7, 0x16, 0xe0, 0x11, 0xda, 0x7e, 0xeb, 0x8d, 0xc7, 0xf0, 0x41, + 0x86, 0x5c, 0x23, 0x61, 0x85, 0x87, 0xd9, 0xe7, 0xd1, 0x84, 0x8a, 0x17, + 0x07, 0xb7, 0x84, 0x87, 0x9c, 0xfe, 0xbf, 0x8d, 0xcd, 0x23, 0x92, 0x77, + 0xb5, 0xd9, 0xdb, 0x53, 0xed, 0xb6, 0xc4, 0xdd, 0x6c, 0xa2, 0x92, 0xb9, + 0xb9, 0x86, 0x0f, 0xe6, 0x6e, 0xc0, 0x39, 0x96, 0x19, 0x4d, 0x6c, 0xc4, + 0x27, 0xe4, 0x08, 0x99, 0xc4, 0x72, 0xbc, 0xc6, 0x5c, 0xf2, 0x7b, 0x89, + 0x56, 0xe6, 0x96, 0xab, 0xf0, 0xca, 0xa0, 0xf0, 0x8f, 0x16, 0x2c, 0x4c, + 0x28, 0x58, 0x1a, 0x5a, 0x85, 0x93, 0xc3, 0xcc, 0x29, 0x07, 0xe5, 0xbc, + 0xeb, 0x35, 0x58, 0x93, 0x3b, 0x0f, 0xc5, 0xe7, 0x31, 0x3e, 0x5f, 0x89, + 0xa3, 0xc3, 0x01, 0x1c, 0x60, 0x0e, 0xf9, 0x0e, 0x31, 0x64, 0x28, 0xd1, + 0x80, 0xd3, 0xcc, 0x95, 0x7e, 0x94, 0x88, 0xe0, 0x33, 0xfe, 0x3e, 0x92, + 0x90, 0xf5, 0xef, 0x66, 0x5c, 0xc8, 0xfc, 0x18, 0x05, 0xbd, 0x33, 0x70, + 0xbc, 0xed, 0x79, 0x52, 0xc9, 0x23, 0xfc, 0xb4, 0xe2, 0xf4, 0x70, 0x2b, + 0xce, 0x0c, 0x2e, 0xc3, 0x99, 0xe1, 0x5f, 0xe1, 0x83, 0x41, 0x91, 0x57, + 0xce, 0x2c, 0x3a, 0xef, 0x16, 0xb0, 0x5d, 0xe2, 0xd4, 0xf0, 0xbf, 0xa5, + 0xed, 0x8f, 0xec, 0xe3, 0xab, 0xa4, 0xdd, 0xe7, 0xff, 0x48, 0xdb, 0xa2, + 0x4b, 0x89, 0xf5, 0x5e, 0x9c, 0x4c, 0x78, 0x99, 0x57, 0x8d, 0xdf, 0x50, + 0x84, 0xf1, 0xf9, 0xcc, 0x36, 0xb1, 0x3d, 0x53, 0x88, 0x17, 0xfb, 0xdc, + 0xe4, 0x8a, 0x5f, 0x25, 0x7e, 0x74, 0xd2, 0x0e, 0x0b, 0x99, 0xbf, 0x79, + 0xa9, 0xe3, 0xf9, 0xc4, 0xfb, 0x55, 0xd4, 0x9f, 0x0f, 0xa7, 0x12, 0x7e, + 0xbc, 0x9e, 0xa8, 0x8f, 0x67, 0x95, 0x46, 0x58, 0x15, 0xb9, 0xbc, 0xf2, + 0x68, 0xa2, 0xc3, 0x91, 0xe9, 0xd5, 0x44, 0x9b, 0xbd, 0x95, 0x3a, 0xee, + 0x49, 0x7d, 0xdb, 0x39, 0x6f, 0xf8, 0x4a, 0xe2, 0x82, 0x2d, 0xe7, 0x88, + 0x9f, 0xa1, 0x4e, 0x4f, 0x26, 0xe2, 0x28, 0x62, 0x9e, 0x72, 0x2c, 0x31, + 0x8e, 0x61, 0xda, 0xe5, 0x3b, 0x7d, 0xc6, 0x89, 0x35, 0xd8, 0x84, 0xcf, + 0xd2, 0x85, 0x78, 0x8b, 0x7d, 0x94, 0x37, 0xb9, 0x31, 0xe1, 0xb4, 0xb7, + 0x09, 0x9f, 0xf4, 0x29, 0xc8, 0xcc, 0xdd, 0x84, 0x8f, 0xf9, 0xec, 0x0d, + 0x5e, 0x9f, 0x0b, 0x53, 0xc2, 0xc9, 0x67, 0x67, 0xfa, 0x54, 0x27, 0x07, + 0xee, 0x6e, 0xde, 0x84, 0xd3, 0xe9, 0x8f, 0x71, 0x80, 0xb9, 0xf4, 0x63, + 0xe6, 0x34, 0x44, 0xa6, 0x11, 0x70, 0x8d, 0x42, 0x9c, 0xe4, 0xf3, 0x5a, + 0x59, 0xef, 0xd1, 0x72, 0xe5, 0x3f, 0xe2, 0x78, 0x1e, 0x61, 0x5b, 0x67, + 0xd3, 0xdf, 0x61, 0xbb, 0xc2, 0x39, 0xbf, 0xc3, 0x76, 0x7f, 0x85, 0x91, + 0x49, 0x7d, 0x9c, 0x36, 0x65, 0x5c, 0x1b, 0x7c, 0x28, 0xf6, 0x73, 0x1c, + 0x0f, 0xf3, 0xbb, 0x03, 0x13, 0x99, 0x9d, 0xfc, 0x7e, 0x0d, 0x87, 0x33, + 0x12, 0xdb, 0xf3, 0x67, 0x87, 0x64, 0x7d, 0x4b, 0xfc, 0x47, 0x9f, 0x5c, + 0x97, 0x9b, 0x8e, 0x54, 0x7f, 0x59, 0x7c, 0x1a, 0xed, 0xe8, 0x3f, 0xcc, + 0x2b, 0xc7, 0x47, 0x61, 0x0b, 0xbb, 0x0e, 0xb8, 0x91, 0xea, 0x25, 0x9f, + 0xed, 0xad, 0xc4, 0x53, 0xbb, 0x35, 0x3c, 0xb9, 0xfb, 0x5a, 0x6c, 0xd9, + 0x7d, 0x3d, 0xf6, 0xed, 0xae, 0x46, 0x92, 0xb9, 0xf2, 0x27, 0x4d, 0xb6, + 0x3d, 0x87, 0x9f, 0x1d, 0xf4, 0x05, 0x2f, 0xbf, 0x5f, 0x0e, 0x8b, 0x9f, + 0x18, 0xb8, 0xd1, 0xf1, 0x97, 0x16, 0xdc, 0xe0, 0x7c, 0xc7, 0x30, 0x27, + 0xd3, 0x19, 0xde, 0x90, 0xdd, 0x14, 0x7e, 0x28, 0x3b, 0x1d, 0x5b, 0xfb, + 0xab, 0xd0, 0xbf, 0xbb, 0x32, 0x5e, 0xc9, 0x7e, 0x56, 0xce, 0xb3, 0x31, + 0xc4, 0xba, 0x66, 0x63, 0x4f, 0x78, 0x4d, 0xf6, 0x79, 0xb4, 0x65, 0xfd, + 0xd8, 0xdc, 0x1f, 0x60, 0x5f, 0xb2, 0x86, 0xef, 0x3e, 0xf1, 0x20, 0x6c, + 0xfb, 0x42, 0xd3, 0x11, 0xc6, 0xb7, 0x1f, 0xa3, 0x9d, 0xcf, 0x92, 0xfd, + 0x1b, 0xc8, 0xa9, 0x0a, 0xe2, 0xde, 0xa8, 0x8d, 0x53, 0xe1, 0x71, 0xdc, + 0xc1, 0xf6, 0x76, 0xf6, 0x97, 0x51, 0xa6, 0xe2, 0x78, 0x21, 0xef, 0x2d, + 0x0d, 0x6f, 0xc4, 0xae, 0x31, 0x59, 0x03, 0x3c, 0x81, 0xa5, 0xe4, 0x2c, + 0x15, 0x73, 0x7f, 0x56, 0x82, 0x32, 0xcd, 0x7d, 0xbe, 0x59, 0xec, 0x2f, + 0x4e, 0xfb, 0x13, 0xac, 0x5c, 0x87, 0xb5, 0xce, 0xd9, 0xc2, 0x76, 0xbc, + 0x94, 0x10, 0x9c, 0x5e, 0x8d, 0x83, 0x89, 0x75, 0xd8, 0x92, 0x92, 0x7d, + 0xc0, 0xe5, 0xa8, 0xc9, 0xfe, 0x55, 0x78, 0x3d, 0xe3, 0xa9, 0x2b, 0xfb, + 0x3f, 0xb0, 0x38, 0x9b, 0xa6, 0x5c, 0xc3, 0xe1, 0xb5, 0xd9, 0x7d, 0xe1, + 0x07, 0xb3, 0xad, 0x98, 0x95, 0x95, 0xf5, 0xb4, 0x36, 0xe2, 0xbb, 0xac, + 0xa7, 0x4d, 0x60, 0x61, 0xf6, 0x0c, 0x16, 0x65, 0xdf, 0x62, 0x2c, 0x16, + 0xdc, 0x90, 0x75, 0xb6, 0x5f, 0x31, 0x39, 0x91, 0x7d, 0xc3, 0xbf, 0xc4, + 0xd6, 0xbd, 0x71, 0xc6, 0xc2, 0x3c, 0x46, 0xd5, 0x6b, 0x07, 0x04, 0x5f, + 0xc6, 0x3c, 0x4e, 0x2c, 0xe8, 0x4b, 0xdd, 0x43, 0x7b, 0x54, 0xc9, 0xf3, + 0x25, 0xce, 0xac, 0xa3, 0x2f, 0x77, 0x92, 0x9f, 0x4b, 0xfc, 0xbb, 0x6b, + 0xf2, 0xbe, 0xf0, 0x3a, 0x89, 0x7d, 0x3a, 0x8e, 0x66, 0x9c, 0xbd, 0x0c, + 0xdd, 0x6b, 0xdc, 0xc1, 0x67, 0x52, 0xff, 0x2f, 0x91, 0xdc, 0xbb, 0xca, + 0xde, 0xe9, 0xac, 0x19, 0x29, 0x38, 0x1e, 0x62, 0x5f, 0xa4, 0x91, 0x4b, + 0xf7, 0xcb, 0x59, 0xce, 0x75, 0x72, 0x96, 0xd3, 0x72, 0x19, 0x6d, 0xf6, + 0x96, 0x14, 0x1e, 0x2c, 0x45, 0x00, 0xcb, 0x47, 0x0b, 0x10, 0x3b, 0x58, + 0x8c, 0xdb, 0x77, 0xb7, 0xd3, 0x96, 0x2d, 0xda, 0xaf, 0x61, 0xae, 0x55, + 0x8a, 0xb1, 0x84, 0xf7, 0x1e, 0xe8, 0x0f, 0xb6, 0x02, 0xa1, 0x13, 0xa7, + 0x5d, 0xc5, 0xb8, 0x9f, 0xb1, 0x23, 0x9d, 0x5e, 0x8e, 0xd8, 0xfe, 0xe3, + 0xb0, 0xd2, 0xb4, 0xc9, 0x3d, 0xc4, 0x99, 0xbd, 0x6e, 0xa8, 0xd1, 0x5f, + 0x61, 0xdf, 0xb0, 0x8a, 0xf2, 0x3d, 0x2f, 0xd8, 0x01, 0x43, 0x31, 0xce, + 0x85, 0xb2, 0xe4, 0x40, 0x6e, 0x94, 0x26, 0x5b, 0x30, 0x4a, 0xac, 0xf1, + 0x25, 0x63, 0xc8, 0x64, 0xda, 0x90, 0x26, 0x96, 0xa4, 0xc9, 0x9b, 0x4a, + 0x92, 0x26, 0x63, 0x79, 0x1d, 0x76, 0xd1, 0x5f, 0x0a, 0x98, 0xcb, 0x6f, + 0xcb, 0xdc, 0x0a, 0x6b, 0xf8, 0x4e, 0x6c, 0x1f, 0x6e, 0xe3, 0x87, 0xfc, + 0x71, 0xf8, 0xdb, 0x58, 0x38, 0x7a, 0x02, 0x3d, 0x99, 0x38, 0xed, 0xf1, + 0x63, 0x6c, 0x4f, 0x1f, 0xc3, 0x53, 0x7d, 0x5d, 0xcc, 0x11, 0x8e, 0xe1, + 0x49, 0x5e, 0xf7, 0xf5, 0x19, 0x9d, 0x01, 0xf5, 0x18, 0x52, 0xe9, 0x4d, + 0xb8, 0xb3, 0x5f, 0x61, 0x0e, 0xb7, 0x09, 0x77, 0xec, 0xa7, 0x2d, 0x3e, + 0xd1, 0x81, 0xd6, 0xd1, 0xd7, 0x90, 0xc8, 0xbc, 0xc4, 0xfc, 0x6a, 0x23, + 0x7a, 0x52, 0x1b, 0xc8, 0xbd, 0x9e, 0x67, 0x3b, 0x47, 0xe8, 0xe7, 0x9d, + 0x1c, 0xe3, 0xe3, 0xfc, 0x5c, 0xc2, 0x70, 0x4d, 0x57, 0xf2, 0x58, 0x4d, + 0xbf, 0x4f, 0x49, 0xee, 0xb0, 0x8e, 0x38, 0x71, 0x6f, 0x29, 0x8a, 0x45, + 0xbf, 0xf9, 0x35, 0x69, 0x99, 0x0b, 0xb1, 0x7d, 0x59, 0x9b, 0x76, 0xa3, + 0x28, 0x29, 0xeb, 0xd1, 0xe3, 0xc1, 0x22, 0x72, 0x00, 0x6f, 0x52, 0x74, + 0xd8, 0x6e, 0x77, 0xa7, 0x04, 0x4b, 0x72, 0xdc, 0xfc, 0xe5, 0xcc, 0xaf, + 0xb0, 0x75, 0x70, 0x1a, 0x16, 0xf5, 0x55, 0x23, 0xee, 0xb7, 0xed, 0xe7, + 0xe8, 0x6b, 0x09, 0xe6, 0x58, 0xbb, 0xfa, 0x63, 0xc4, 0x94, 0x12, 0xe4, + 0x72, 0x3d, 0xd1, 0x4d, 0xd0, 0xd4, 0xaf, 0xd8, 0x23, 0x99, 0xc5, 0x79, + 0x13, 0xee, 0x3a, 0x7e, 0x43, 0x29, 0xce, 0x97, 0xe4, 0xd6, 0xc5, 0xff, + 0xfc, 0x12, 0xb7, 0xf9, 0xd7, 0x95, 0xbf, 0xff, 0xdf, 0x58, 0x7e, 0x62, + 0xca, 0xd9, 0xb5, 0xfc, 0x7b, 0x39, 0x32, 0xd6, 0xeb, 0xe5, 0xdc, 0x9a, + 0x25, 0x7c, 0x49, 0xce, 0xdc, 0x1e, 0x4f, 0x14, 0x30, 0x4e, 0xaa, 0x0b, + 0x3c, 0x50, 0xfd, 0x1e, 0x14, 0x32, 0x9e, 0x55, 0x61, 0xb3, 0xdf, 0xc6, + 0x62, 0xb3, 0x00, 0x87, 0x1b, 0x62, 0x72, 0xce, 0xa2, 0xdd, 0xe3, 0xf0, + 0xd1, 0xd5, 0xf7, 0xfc, 0xe1, 0xba, 0xf5, 0x26, 0x72, 0x37, 0x39, 0x5f, + 0xd0, 0x86, 0x53, 0x15, 0xf2, 0xae, 0xd0, 0x26, 0xe7, 0xdc, 0x59, 0x51, + 0xad, 0xac, 0xa3, 0xe9, 0x38, 0x61, 0xd4, 0xeb, 0x95, 0x2a, 0xe3, 0xb9, + 0xf2, 0xae, 0x6d, 0xf9, 0xa3, 0x8c, 0xf5, 0x72, 0x86, 0xe2, 0x5f, 0xda, + 0xa7, 0x58, 0x83, 0xed, 0x4f, 0x34, 0x63, 0x62, 0x95, 0xc4, 0xff, 0xff, + 0xe6, 0xcb, 0x73, 0xba, 0x6d, 0xa9, 0x1f, 0x96, 0xca, 0xb9, 0x24, 0x69, + 0x7b, 0x3b, 0xf3, 0x27, 0x8f, 0x11, 0xc6, 0xbb, 0xc2, 0xd2, 0x9c, 0xfd, + 0xa4, 0x1c, 0xa7, 0x28, 0x34, 0xce, 0x4f, 0xbe, 0x3b, 0xf2, 0xd7, 0xa5, + 0xc2, 0x0f, 0xb7, 0xa5, 0x36, 0x91, 0x9b, 0x8b, 0x3c, 0xbf, 0xb7, 0xd7, + 0xf8, 0x2b, 0x59, 0xf6, 0xee, 0xc9, 0xf6, 0xc4, 0x16, 0xe4, 0x4c, 0x8e, + 0xdc, 0x93, 0x3a, 0xa2, 0xb3, 0xa9, 0x75, 0x5c, 0xcc, 0x85, 0x6f, 0xc0, + 0xa3, 0xf4, 0xc1, 0x99, 0xc6, 0xeb, 0x76, 0x97, 0x9c, 0x9f, 0xa9, 0xd5, + 0xa6, 0xf4, 0xf5, 0x0b, 0x47, 0x96, 0x42, 0xca, 0xd2, 0x9f, 0x92, 0xb3, + 0xa8, 0x9f, 0xd9, 0xb5, 0x55, 0xf2, 0xfc, 0xc2, 0x64, 0xfb, 0x35, 0xce, + 0xd9, 0xbe, 0x7d, 0xa9, 0xbc, 0xdc, 0xb2, 0xde, 0xea, 0xcf, 0xf7, 0x55, + 0x77, 0x79, 0x3c, 0x22, 0x5b, 0xbc, 0xf4, 0x4a, 0x99, 0xe1, 0xcb, 0x9f, + 0x59, 0x9d, 0xe1, 0xd4, 0xc9, 0xf7, 0x29, 0x32, 0x6e, 0x62, 0x9e, 0x7a, + 0xf5, 0x18, 0xb5, 0x29, 0x63, 0x92, 0x3a, 0x32, 0x2e, 0x6d, 0xd2, 0x0e, + 0x4a, 0xcb, 0x50, 0x2c, 0x75, 0x84, 0xbb, 0x6a, 0x0e, 0x07, 0x2f, 0x17, + 0x5e, 0x2e, 0xb6, 0x51, 0x66, 0xdb, 0xef, 0x39, 0x31, 0x53, 0xda, 0xe1, + 0x38, 0xc6, 0x56, 0xd1, 0xce, 0xed, 0x2e, 0xe2, 0xa7, 0xfd, 0x5e, 0x73, + 0x00, 0x5b, 0x13, 0xa2, 0x6b, 0x23, 0x70, 0x88, 0xd8, 0xb1, 0xd9, 0xe1, + 0x1b, 0x1e, 0x74, 0xa7, 0xf3, 0xfb, 0xa3, 0x85, 0x72, 0xf6, 0x36, 0x20, + 0x3a, 0xef, 0x36, 0xc9, 0xb3, 0xb4, 0x85, 0xba, 0x9b, 0x5c, 0x69, 0x3d, + 0xfe, 0x99, 0xf3, 0x2b, 0xe7, 0x8f, 0x73, 0x7b, 0x95, 0x71, 0xda, 0x51, + 0x2e, 0x5e, 0x81, 0xf1, 0x9d, 0x3c, 0x69, 0xf2, 0x5c, 0x66, 0x77, 0xe6, + 0x9f, 0xed, 0x71, 0xe7, 0x5c, 0xe6, 0xe5, 0x77, 0x3a, 0xd2, 0x9a, 0x6d, + 0x1f, 0xe0, 0xb3, 0xcb, 0x67, 0x34, 0x19, 0xd3, 0x0d, 0x39, 0xcb, 0xf9, + 0x4f, 0x9c, 0xbb, 0xa9, 0x65, 0xc7, 0x2b, 0x72, 0x67, 0x96, 0x63, 0xea, + 0x42, 0x23, 0x8f, 0xab, 0x41, 0xcb, 0x72, 0x70, 0xf5, 0x0e, 0x67, 0x0f, + 0x3e, 0x8d, 0x60, 0x6b, 0x1b, 0x2c, 0xbb, 0xd8, 0xc8, 0xe3, 0x80, 0x61, + 0xce, 0x51, 0xba, 0x30, 0x3b, 0x5c, 0x2c, 0x1c, 0x3b, 0xe8, 0x8e, 0x06, + 0xb5, 0x0f, 0x10, 0xaa, 0x3b, 0xe6, 0xec, 0x95, 0x0a, 0x36, 0x18, 0x58, + 0x9f, 0x21, 0xdf, 0x1e, 0x93, 0x77, 0x1d, 0xe5, 0xda, 0x69, 0x9f, 0xd7, + 0x82, 0xa5, 0xed, 0xc4, 0x52, 0xeb, 0xcf, 0x3d, 0x4e, 0x7b, 0xc1, 0xf6, + 0x61, 0x25, 0xd8, 0xba, 0x51, 0xc9, 0xb7, 0xe7, 0xfb, 0x92, 0xf6, 0xea, + 0x58, 0xbf, 0x7a, 0xf2, 0xfd, 0x42, 0x83, 0x6d, 0x5c, 0xbd, 0x9f, 0x3c, + 0x3d, 0x2e, 0x7b, 0x51, 0x87, 0x27, 0x39, 0xe1, 0xb1, 0x3f, 0xd8, 0x8b, + 0xfa, 0xd2, 0x3e, 0x63, 0xec, 0xb3, 0xb5, 0x58, 0x89, 0x91, 0x31, 0x74, + 0xa1, 0x30, 0x1c, 0xaa, 0x7b, 0x19, 0xd0, 0xdd, 0xd1, 0x50, 0x60, 0xd8, + 0xd9, 0xd3, 0x35, 0xbd, 0x8b, 0x9c, 0xfa, 0xd5, 0xe4, 0xc5, 0x7f, 0x5c, + 0x27, 0x25, 0x86, 0xd1, 0x56, 0xaf, 0xc4, 0xe6, 0x17, 0xb3, 0x9d, 0xba, + 0x30, 0xf4, 0x82, 0x68, 0x5e, 0x47, 0xa1, 0xba, 0x0f, 0x38, 0x9f, 0x47, + 0x9b, 0x43, 0x81, 0x21, 0xe7, 0x8c, 0xa7, 0xe8, 0xc5, 0xf4, 0xe6, 0xe6, + 0x5e, 0x17, 0xbe, 0xcd, 0x7c, 0x32, 0x8e, 0x91, 0x84, 0x97, 0x63, 0xa9, + 0xd7, 0xb6, 0xa3, 0x82, 0x36, 0x8e, 0xd8, 0xe6, 0x06, 0xe2, 0x77, 0x02, + 0x31, 0xd7, 0x8d, 0xe5, 0x88, 0x93, 0x40, 0xbb, 0x8c, 0x38, 0x39, 0x51, + 0x7d, 0xdd, 0x0e, 0xda, 0x6f, 0xda, 0x1f, 0x0c, 0x58, 0x88, 0xe3, 0xc5, + 0xc4, 0xc2, 0xff, 0xc7, 0x05, 0xcb, 0x2c, 0x81, 0xbc, 0x5f, 0x90, 0xbe, + 0x67, 0x59, 0x28, 0xa8, 0xbf, 0x32, 0xb9, 0x27, 0xdd, 0x9d, 0xf8, 0xad, + 0xbc, 0xc7, 0xc4, 0x7a, 0x7f, 0xac, 0x8c, 0xf4, 0xed, 0xc5, 0xa1, 0xbe, + 0x3e, 0x6c, 0x79, 0x82, 0x32, 0x1a, 0x36, 0x16, 0x9a, 0x5d, 0xcc, 0xa5, + 0x7d, 0x58, 0xa7, 0xcd, 0x8e, 0xa8, 0x2c, 0x37, 0x94, 0xce, 0xad, 0x3b, + 0x6e, 0x75, 0xf6, 0xbc, 0x7b, 0x98, 0xa3, 0x38, 0xf1, 0x53, 0xf3, 0x46, + 0x63, 0xca, 0xce, 0x4c, 0x8b, 0xb2, 0x23, 0x2d, 0x6d, 0x75, 0x2a, 0x3d, + 0x99, 0xbf, 0xa5, 0x4f, 0x58, 0x38, 0x6d, 0xca, 0xbb, 0x39, 0xd2, 0xae, + 0x85, 0xe1, 0xe6, 0x7f, 0xcd, 0x3b, 0x3a, 0xa2, 0xd3, 0x4e, 0x6c, 0x1e, + 0x7c, 0x1c, 0xdd, 0x83, 0xa7, 0x9c, 0x33, 0x46, 0x1e, 0xc3, 0x6b, 0x5d, + 0x1f, 0x0d, 0x1e, 0xb1, 0x90, 0x2d, 0x97, 0xf3, 0xf9, 0x55, 0xd1, 0x13, + 0xd8, 0xa9, 0xc9, 0xbb, 0x27, 0x3d, 0xe4, 0x11, 0xb2, 0x6f, 0xbb, 0x1a, + 0x5f, 0xef, 0x95, 0x39, 0x2c, 0xb3, 0x0a, 0xa3, 0xc1, 0xd8, 0x3a, 0x67, + 0x0e, 0x1b, 0x70, 0x32, 0xfb, 0x38, 0xde, 0xdb, 0xd3, 0x05, 0x35, 0x1c, + 0x0c, 0xdc, 0x06, 0xbb, 0xeb, 0xb8, 0x19, 0xb3, 0x3c, 0x08, 0x1e, 0x76, + 0xa9, 0xc0, 0x0b, 0x7b, 0xe0, 0x9d, 0xc1, 0xf9, 0x9f, 0xcf, 0x18, 0x5d, + 0x6e, 0xd8, 0x0b, 0xfe, 0xb1, 0x29, 0xd8, 0x63, 0xb8, 0xac, 0xbf, 0x99, + 0x8e, 0x60, 0x5f, 0x44, 0x35, 0xda, 0xef, 0x52, 0xa1, 0xf8, 0xa2, 0xf2, + 0x5e, 0x69, 0x17, 0xee, 0x6c, 0xf4, 0x59, 0xa5, 0xd1, 0x60, 0xdf, 0x29, + 0x25, 0x58, 0x67, 0xa9, 0x6d, 0x9c, 0xe7, 0x3a, 0xbc, 0x42, 0x0e, 0xd2, + 0xca, 0xd8, 0xbb, 0x34, 0xa9, 0x3b, 0xeb, 0x4c, 0xaa, 0x51, 0x13, 0x29, + 0x52, 0x34, 0xdc, 0x96, 0x05, 0x8e, 0xa6, 0x57, 0xe3, 0x9d, 0x3d, 0x26, + 0xf3, 0x54, 0x9d, 0xb8, 0xf5, 0xbd, 0x32, 0xc1, 0x80, 0x0e, 0xd3, 0xaa, + 0x57, 0x19, 0xfb, 0x3d, 0x2a, 0x16, 0xce, 0x8c, 0x86, 0xc6, 0x17, 0xb8, + 0xdc, 0x88, 0x64, 0x65, 0xfd, 0x53, 0x97, 0xb3, 0xc9, 0xb8, 0x2b, 0xe9, + 0x25, 0xff, 0xac, 0xc6, 0x6f, 0xc8, 0x83, 0x7f, 0x4d, 0xbe, 0x3b, 0xc1, + 0x78, 0x3e, 0x91, 0x29, 0x66, 0xbe, 0xe8, 0x91, 0x1c, 0x78, 0xdc, 0xc3, + 0xb9, 0x28, 0x6b, 0xf4, 0xe3, 0xdc, 0xb0, 0x17, 0x77, 0xec, 0x09, 0xee, + 0x9b, 0x50, 0xab, 0xf0, 0xc9, 0x70, 0x31, 0x96, 0x0f, 0x78, 0x29, 0x9b, + 0x8d, 0x5d, 0xc4, 0xff, 0x8f, 0xf8, 0xac, 0x65, 0x0f, 0x94, 0xcc, 0xdc, + 0x59, 0xe4, 0xec, 0x06, 0xeb, 0x97, 0x60, 0xd9, 0x80, 0xf0, 0x34, 0x15, + 0x1f, 0x0e, 0x2b, 0xf8, 0x20, 0x6d, 0x62, 0x21, 0xfb, 0xdb, 0x9c, 0x7a, + 0xc1, 0xf6, 0xd2, 0xcf, 0xd7, 0x64, 0x4c, 0x3c, 0x98, 0xd6, 0x19, 0x53, + 0xde, 0xb6, 0x5d, 0x46, 0x23, 0xde, 0xde, 0x6d, 0x9c, 0x78, 0xd7, 0x15, + 0x1a, 0x9f, 0xeb, 0x6a, 0xc4, 0x5b, 0x07, 0x1b, 0xf1, 0xb3, 0xfe, 0x05, + 0xb8, 0xb9, 0x31, 0x86, 0xf3, 0x73, 0x1b, 0xf1, 0xe6, 0x7e, 0x1d, 0x3b, + 0x52, 0xcd, 0xd0, 0x47, 0xc7, 0xc9, 0x4f, 0x23, 0xa8, 0x67, 0x4e, 0x65, + 0xf4, 0xdb, 0x5d, 0x25, 0xd1, 0x2e, 0xec, 0x34, 0xa3, 0x98, 0xb3, 0x5f, + 0xf4, 0x60, 0xdb, 0xeb, 0xe6, 0x46, 0xf1, 0x72, 0x9f, 0x41, 0x3f, 0x8d, + 0x52, 0x0f, 0x3a, 0x9e, 0x24, 0x36, 0x87, 0x9e, 0x30, 0x2e, 0x1c, 0xe0, + 0xef, 0x05, 0x07, 0x9a, 0xd1, 0xce, 0xfe, 0x13, 0xa9, 0x18, 0xf6, 0x8d, + 0x36, 0x70, 0xcc, 0x26, 0xc7, 0x5f, 0x63, 0xfd, 0x46, 0x69, 0x41, 0xdf, + 0x68, 0x2b, 0xf9, 0x66, 0x17, 0x79, 0x66, 0x2b, 0x7a, 0xd9, 0xd6, 0xd6, + 0x94, 0x89, 0x65, 0xc9, 0x56, 0x3c, 0x9d, 0x90, 0x33, 0x8d, 0x46, 0x64, + 0x9e, 0x22, 0xef, 0x7d, 0xb5, 0xe2, 0x10, 0x75, 0xb2, 0x70, 0x60, 0x39, + 0xed, 0xd0, 0x8b, 0x45, 0x7b, 0x74, 0x3c, 0x95, 0xba, 0x13, 0xef, 0x8c, + 0x98, 0x68, 0x4b, 0x8a, 0xbe, 0xe5, 0x5c, 0x4d, 0x1c, 0xc7, 0x19, 0x5b, + 0x7e, 0x33, 0x10, 0xfb, 0x1b, 0x4e, 0xf3, 0x49, 0x15, 0xc1, 0xce, 0x19, + 0x9c, 0xf0, 0x9b, 0x1a, 0xe5, 0x6c, 0x94, 0x8b, 0xa8, 0x16, 0xb4, 0xca, + 0x55, 0x4b, 0xe7, 0x7d, 0xcb, 0xad, 0x6e, 0xc2, 0x37, 0x06, 0xdc, 0xe4, + 0xf4, 0x2a, 0x73, 0x11, 0xab, 0x83, 0xb6, 0x61, 0x95, 0xa9, 0xb9, 0x79, + 0xdb, 0x2e, 0xef, 0xa1, 0x19, 0x2e, 0xec, 0x32, 0x6b, 0xda, 0x4a, 0x58, + 0x6f, 0x69, 0x38, 0x18, 0x2b, 0x52, 0x9b, 0x99, 0x27, 0x3e, 0x8e, 0x75, + 0x7b, 0x1e, 0xc7, 0x1a, 0x7e, 0x3a, 0xf6, 0xd8, 0x5d, 0x4b, 0x4c, 0x05, + 0x2f, 0x1a, 0x76, 0x57, 0x97, 0x69, 0x70, 0x6e, 0x65, 0x5e, 0x1f, 0x47, + 0xe7, 0xa1, 0xc7, 0xf1, 0x28, 0xed, 0xab, 0x92, 0x7e, 0xbc, 0x32, 0x69, + 0x77, 0xdd, 0xdc, 0x58, 0x87, 0x4f, 0x9d, 0xfc, 0x43, 0xec, 0x75, 0xab, + 0x93, 0x13, 0xa7, 0x55, 0xb9, 0xde, 0xed, 0x5c, 0x5b, 0xea, 0x2b, 0x65, + 0xf9, 0xd8, 0xf2, 0x5b, 0xb6, 0xfb, 0xbb, 0x3d, 0xe5, 0x78, 0xa2, 0x52, + 0xe2, 0x87, 0xac, 0xed, 0x42, 0x31, 0xe6, 0x32, 0xcf, 0x7a, 0xe2, 0x38, + 0xb6, 0x93, 0xb7, 0xf9, 0xc3, 0x92, 0x03, 0xd7, 0x9b, 0x5b, 0xd4, 0x5b, + 0x89, 0xed, 0x0a, 0x76, 0xd6, 0xf6, 0xa1, 0x97, 0xbe, 0xba, 0xab, 0x36, + 0x18, 0xef, 0x45, 0xd4, 0xde, 0x35, 0xbd, 0xe7, 0xdf, 0xf0, 0x5e, 0x96, + 0xbc, 0xb7, 0x9d, 0x7f, 0x37, 0xeb, 0x71, 0x74, 0xed, 0x91, 0xf9, 0x7f, + 0x1c, 0x8f, 0x51, 0xfe, 0xce, 0x81, 0xc7, 0xf1, 0x4d, 0xda, 0x4e, 0x45, + 0xd3, 0xd1, 0xc7, 0x2a, 0x30, 0xbb, 0xaf, 0x1c, 0xe3, 0x0f, 0x57, 0xca, + 0x39, 0x28, 0x62, 0x62, 0xaf, 0xf2, 0x38, 0xd6, 0x0f, 0x1d, 0xa0, 0x2f, + 0x3a, 0xfe, 0x47, 0x2c, 0xce, 0xc7, 0xab, 0x00, 0xd6, 0x11, 0x93, 0x73, + 0xb8, 0xee, 0xc7, 0x9a, 0xc4, 0x61, 0xc7, 0xf7, 0x0b, 0xa2, 0xab, 0xe8, + 0xf7, 0x6d, 0xf4, 0xfb, 0xe5, 0xf4, 0xfb, 0x56, 0xfa, 0x7d, 0x0b, 0xfd, + 0x3e, 0x46, 0xbf, 0x8f, 0xd2, 0xef, 0x23, 0xf4, 0xfb, 0x66, 0xfa, 0xbd, + 0x49, 0xbf, 0x87, 0x72, 0xa2, 0xf9, 0x38, 0x3c, 0xfd, 0x5e, 0xda, 0x50, + 0xee, 0x3d, 0x99, 0x83, 0xc4, 0x9f, 0xd3, 0xe6, 0x9c, 0xc0, 0x62, 0xc6, + 0xd5, 0x61, 0x62, 0x44, 0x7a, 0xe4, 0xaf, 0x9c, 0x77, 0x2a, 0xd2, 0xc4, + 0xfd, 0x57, 0xa8, 0x8f, 0xa5, 0xe1, 0x1a, 0xf3, 0x69, 0xc6, 0xb0, 0x5f, + 0x18, 0xf5, 0x3d, 0x7e, 0x96, 0xf9, 0x41, 0xaa, 0xbe, 0x6f, 0x1a, 0x0c, + 0xab, 0x51, 0xdd, 0x0a, 0xac, 0xf4, 0x73, 0xcc, 0x72, 0xde, 0x6e, 0x25, + 0x1e, 0x1b, 0x6c, 0xc3, 0x7f, 0x19, 0xd4, 0xa8, 0x8b, 0x9a, 0xf1, 0x5b, + 0x5d, 0xf8, 0x71, 0x00, 0x2e, 0xff, 0x35, 0xc0, 0xe7, 0x55, 0x98, 0x73, + 0x58, 0xde, 0xef, 0x4b, 0x57, 0xb9, 0x1a, 0x66, 0x42, 0x6c, 0x04, 0x44, + 0x6a, 0x17, 0x33, 0xc1, 0x39, 0xce, 0x3b, 0x40, 0xb1, 0x55, 0x82, 0xe9, + 0x45, 0xd8, 0x5a, 0xe7, 0xe0, 0xec, 0xb3, 0x72, 0x6e, 0xb0, 0x8a, 0x78, + 0xe4, 0x8b, 0xb6, 0x62, 0x5b, 0xaf, 0x75, 0x7f, 0x15, 0x96, 0xa3, 0xa7, + 0x37, 0xa7, 0x83, 0x87, 0xc3, 0x1a, 0xa9, 0x42, 0x48, 0x9f, 0xa3, 0xc0, + 0xdd, 0xd1, 0x1c, 0xc1, 0x83, 0x99, 0x04, 0xfa, 0x38, 0xc6, 0x0d, 0xf4, + 0xb3, 0x75, 0x7f, 0xfa, 0xdd, 0x4e, 0x7c, 0x33, 0xa1, 0xd3, 0xfe, 0x2f, + 0xda, 0xe9, 0x8a, 0x39, 0x7d, 0x55, 0x30, 0x3a, 0x57, 0xa8, 0xf3, 0x98, + 0xd3, 0x06, 0x8f, 0xc8, 0xc2, 0xf7, 0xf4, 0xa8, 0xd7, 0xaa, 0x20, 0x36, + 0xcf, 0x1a, 0x80, 0x32, 0x9c, 0x94, 0xf7, 0x20, 0xba, 0xf0, 0xff, 0x99, + 0x6d, 0x8e, 0xfd, 0x8c, 0xbb, 0x34, 0xcc, 0x4c, 0xca, 0x7d, 0x7b, 0xc1, + 0x67, 0x4d, 0xc1, 0x3a, 0xdd, 0xb5, 0x81, 0xf7, 0xab, 0xf1, 0x23, 0xc6, + 0xd9, 0xc0, 0xc0, 0x02, 0xa8, 0x4d, 0x5e, 0xdc, 0xdd, 0x50, 0x8a, 0xf8, + 0x4a, 0xe1, 0xa1, 0x92, 0xef, 0xbb, 0xa9, 0xcf, 0xff, 0x17, 0x0f, 0x99, + 0xcf, 0x61, 0xc2, 0x9f, 0x70, 0xf6, 0xdd, 0xd7, 0x99, 0x77, 0x28, 0x16, + 0xaf, 0xb7, 0xa5, 0x2c, 0x6c, 0x30, 0x99, 0x0b, 0xdd, 0x53, 0xc9, 0x9c, + 0x44, 0xca, 0x4b, 0xbb, 0x5b, 0x9d, 0xf6, 0x0e, 0xa6, 0xe4, 0x7a, 0xf7, + 0x64, 0x9f, 0x77, 0x01, 0x95, 0x5e, 0xe2, 0xad, 0x82, 0x33, 0xb5, 0x09, + 0xfa, 0x34, 0x7e, 0xec, 0x46, 0x4d, 0xba, 0x5f, 0x75, 0xfd, 0xf8, 0x1a, + 0xcc, 0x31, 0x7f, 0xaf, 0xca, 0x7c, 0xc4, 0xf0, 0x54, 0x48, 0x41, 0xa5, + 0x61, 0x9c, 0xff, 0x19, 0x7d, 0x6b, 0xc2, 0x95, 0xc0, 0x53, 0x63, 0xa7, + 0xec, 0xf1, 0x6b, 0xfc, 0x9c, 0x73, 0xa9, 0xdb, 0x86, 0x0f, 0x06, 0x65, + 0xce, 0x64, 0x9d, 0x9f, 0xb1, 0x5d, 0xd5, 0x51, 0xca, 0x7b, 0xa7, 0x87, + 0x4d, 0xe6, 0x3a, 0x6d, 0xf8, 0xc7, 0xc1, 0x95, 0xf8, 0xfd, 0x60, 0x4d, + 0xdb, 0x7f, 0x52, 0x6d, 0x7b, 0x69, 0xf8, 0x6b, 0xf8, 0x65, 0xa5, 0x86, + 0xa7, 0x69, 0x43, 0xbf, 0x4f, 0x58, 0x4b, 0xaf, 0x21, 0x16, 0xfc, 0xef, + 0x44, 0xf0, 0xc2, 0x49, 0x67, 0x5f, 0xa9, 0xde, 0xfc, 0xd0, 0x15, 0x8c, + 0x9f, 0x51, 0x83, 0xd6, 0x36, 0x65, 0x39, 0xec, 0x4c, 0x2b, 0xce, 0x67, + 0xa6, 0xda, 0x42, 0x97, 0x8d, 0x2a, 0xb1, 0x03, 0xb1, 0x07, 0xda, 0x22, + 0x73, 0xb9, 0x9f, 0x92, 0x47, 0x77, 0x7f, 0x95, 0xf6, 0x98, 0xa2, 0x3d, + 0xa6, 0x68, 0x8f, 0xc4, 0xa4, 0xe7, 0x89, 0x55, 0x3f, 0x48, 0xd1, 0x1e, + 0xe9, 0x3f, 0xcf, 0xd1, 0x7f, 0x72, 0x5c, 0xb9, 0xdd, 0x39, 0xb7, 0xf6, + 0x06, 0x63, 0x62, 0xe2, 0x09, 0x79, 0x27, 0xad, 0x66, 0x43, 0x16, 0xc1, + 0xf6, 0x5e, 0xe5, 0xb3, 0x72, 0x39, 0x67, 0xfb, 0xed, 0x90, 0xf8, 0x40, + 0x6e, 0x3f, 0xe0, 0xc8, 0xc8, 0x63, 0x65, 0xf2, 0x7e, 0xd4, 0xc1, 0xbd, + 0xff, 0x92, 0xce, 0xfe, 0x3b, 0xe5, 0x10, 0x7d, 0xfd, 0x5b, 0xc7, 0x2e, + 0xba, 0xfc, 0x1b, 0xfb, 0x97, 0x55, 0x32, 0xfe, 0x55, 0xf8, 0x62, 0xb0, + 0x05, 0xe7, 0x19, 0x7f, 0xdf, 0x6a, 0x1a, 0xef, 0x0c, 0x20, 0xd8, 0x51, + 0xae, 0x46, 0x91, 0xcd, 0xb4, 0xe0, 0xb3, 0x44, 0x14, 0x07, 0x12, 0x35, + 0xed, 0x35, 0xae, 0xb3, 0x6a, 0x7c, 0x86, 0x58, 0x54, 0x0c, 0x9f, 0x92, + 0x5f, 0x2e, 0xac, 0x8d, 0x60, 0x88, 0x6d, 0x7a, 0xa2, 0x1a, 0x46, 0x9a, + 0xc5, 0x56, 0x73, 0xef, 0x4e, 0xfd, 0xa9, 0xbf, 0x2e, 0xda, 0xe3, 0x7b, + 0x4d, 0x17, 0xed, 0x71, 0xcd, 0x6b, 0x69, 0xf4, 0xe1, 0xd2, 0x3d, 0xf2, + 0x6e, 0xa9, 0xf8, 0xb3, 0x82, 0x1f, 0x84, 0xc7, 0xdb, 0xa6, 0x21, 0xf8, + 0xec, 0x7d, 0xb4, 0xf5, 0x93, 0x49, 0x59, 0x53, 0x6c, 0xc1, 0xfb, 0x2c, + 0xef, 0xa6, 0x5f, 0x9c, 0xcc, 0xb8, 0xdd, 0xbf, 0x4c, 0x2a, 0xcc, 0x4b, + 0x97, 0xe3, 0x97, 0x99, 0x37, 0xd5, 0x8f, 0x35, 0x13, 0x67, 0xb2, 0x2b, + 0x69, 0x4f, 0x92, 0xff, 0xc7, 0x98, 0xff, 0x07, 0x3b, 0x8f, 0x60, 0x25, + 0xca, 0x0f, 0xad, 0x42, 0xd9, 0x1e, 0xe2, 0x67, 0x88, 0xf9, 0x3f, 0xaf, + 0x67, 0xec, 0x91, 0xf7, 0x0d, 0xca, 0xed, 0xed, 0xab, 0x44, 0x2f, 0x82, + 0x27, 0x7f, 0x57, 0x8e, 0xb2, 0x55, 0xc0, 0x21, 0xa9, 0x67, 0xb0, 0xde, + 0x4a, 0x54, 0xee, 0xa9, 0x89, 0x2c, 0x46, 0xcd, 0xf9, 0xdb, 0xd4, 0x95, + 0xb8, 0xfe, 0xd0, 0x3f, 0x73, 0x0e, 0xa4, 0x6c, 0x35, 0x9e, 0xa0, 0xdd, + 0x16, 0x92, 0x13, 0xb6, 0x24, 0x7f, 0x6d, 0xcf, 0xa4, 0x2f, 0x7e, 0xf6, + 0x15, 0x60, 0x5d, 0xd6, 0x60, 0xbc, 0x2b, 0x46, 0x7c, 0xe8, 0x29, 0xbb, + 0x3c, 0xea, 0xc6, 0x9a, 0x6c, 0x03, 0x16, 0x0f, 0xd8, 0xf6, 0xb9, 0xb9, + 0x31, 0xf8, 0xa2, 0x3e, 0x62, 0x98, 0x0f, 0x8f, 0x26, 0x4b, 0xf8, 0x2d, + 0xc7, 0x4f, 0x42, 0xe3, 0xb3, 0x55, 0x63, 0xc3, 0x0c, 0x97, 0xd1, 0x9e, + 0x55, 0x24, 0xee, 0xfb, 0xf0, 0x08, 0xe3, 0xf3, 0xd2, 0x64, 0x00, 0xf1, + 0xac, 0x6d, 0xbf, 0xd9, 0xec, 0xc7, 0xc3, 0xac, 0xdf, 0x9a, 0xec, 0x41, + 0x37, 0xed, 0x22, 0x7e, 0xc8, 0xd0, 0x35, 0xc6, 0xfb, 0x75, 0x59, 0x2f, + 0x63, 0x58, 0x25, 0x6e, 0x63, 0x2c, 0x7a, 0x54, 0xce, 0xca, 0xd0, 0x07, + 0xdf, 0x31, 0xad, 0x1b, 0x5c, 0x30, 0xd0, 0x99, 0xf5, 0x63, 0x79, 0x32, + 0x78, 0x41, 0xde, 0xcd, 0xfb, 0xcc, 0xac, 0xc3, 0xc6, 0x6c, 0x00, 0xb7, + 0x27, 0x8f, 0x3e, 0x3a, 0x13, 0xd6, 0x7f, 0x9e, 0x81, 0x06, 0x7c, 0x3d, + 0x5b, 0xcd, 0xf6, 0x83, 0x1b, 0xde, 0x50, 0xaa, 0xf1, 0x8d, 0x43, 0x26, + 0xdb, 0x57, 0xb1, 0x8c, 0xed, 0x2c, 0x49, 0x5e, 0x8f, 0x47, 0x0e, 0x35, + 0xe3, 0xc1, 0x6c, 0x13, 0x16, 0x31, 0x3e, 0x75, 0x30, 0x37, 0xc4, 0xbd, + 0xc0, 0xed, 0x03, 0xa2, 0x7b, 0x28, 0x6f, 0x36, 0x8f, 0x33, 0x5f, 0x36, + 0x41, 0x43, 0x74, 0xf6, 0x92, 0x77, 0xd2, 0x56, 0x6f, 0xdf, 0xdf, 0x84, + 0xa5, 0x03, 0x2a, 0x6a, 0xc2, 0x85, 0x88, 0xb7, 0x29, 0x68, 0x19, 0x90, + 0x38, 0x2b, 0xdc, 0xc6, 0x64, 0x5c, 0x0d, 0xb1, 0x0f, 0x93, 0x71, 0x35, + 0x77, 0xbf, 0x3b, 0x25, 0x6b, 0x0b, 0x6f, 0x93, 0x2f, 0x85, 0xd1, 0xe2, + 0xc4, 0x68, 0x59, 0x13, 0xb7, 0xe0, 0x66, 0xec, 0x0e, 0xd3, 0xc6, 0x17, + 0x34, 0x4a, 0xac, 0xd6, 0x9d, 0xbd, 0xa9, 0xb1, 0x7e, 0xa3, 0xe3, 0x82, + 0x42, 0xfb, 0xda, 0x2f, 0x31, 0xd1, 0x8f, 0x8d, 0xc9, 0x28, 0xde, 0xe9, + 0x63, 0xbc, 0xb9, 0x31, 0xb6, 0xb4, 0x04, 0x86, 0xf9, 0x08, 0x42, 0xd6, + 0x49, 0xc6, 0xf6, 0xf3, 0xe9, 0x4a, 0x2c, 0xde, 0x23, 0x65, 0x1a, 0xf1, + 0xee, 0xb0, 0xec, 0x4d, 0x6e, 0xc2, 0x53, 0x7d, 0x2e, 0x0c, 0x99, 0x35, + 0x3d, 0x2a, 0xe3, 0xe7, 0xfc, 0xc6, 0xa0, 0xf6, 0x23, 0x72, 0xd5, 0x0b, + 0x4d, 0x8c, 0xca, 0xd7, 0x34, 0xa3, 0x85, 0x72, 0xb5, 0x18, 0xe2, 0x93, + 0x16, 0x1e, 0x6c, 0xde, 0x84, 0x93, 0x7d, 0x86, 0xf5, 0xb4, 0xac, 0x03, + 0x34, 0xf2, 0xf9, 0x74, 0x37, 0x36, 0x1b, 0xc2, 0x69, 0x75, 0xfa, 0x16, + 0x59, 0xa7, 0xd1, 0x8c, 0x77, 0x68, 0xaf, 0x3d, 0xe9, 0x05, 0x8c, 0xfd, + 0x12, 0xf3, 0xbd, 0x56, 0x80, 0xf5, 0xca, 0xbf, 0xa2, 0xe0, 0xf4, 0x01, + 0xe1, 0x58, 0x0b, 0x70, 0xff, 0x80, 0xec, 0x0b, 0xa8, 0x98, 0x7f, 0x68, + 0x35, 0xce, 0xed, 0xce, 0x71, 0xae, 0x37, 0xc3, 0xd6, 0xd7, 0xc9, 0xb9, + 0xda, 0x4b, 0xc9, 0xb9, 0xc8, 0xe5, 0xea, 0x36, 0x2a, 0x6e, 0x84, 0xb2, + 0x11, 0xf2, 0x0a, 0xe1, 0x17, 0x01, 0x3c, 0x93, 0x69, 0xc6, 0x6d, 0xc9, + 0x6a, 0x8c, 0x90, 0x6f, 0xa5, 0x89, 0x17, 0xe9, 0x0c, 0xe3, 0xca, 0x70, + 0x15, 0x3f, 0x3a, 0x3f, 0xb3, 0xf8, 0x31, 0x9c, 0x7b, 0x6b, 0x68, 0xcb, + 0xb1, 0x36, 0xc5, 0xd9, 0xdb, 0x18, 0xca, 0x48, 0xac, 0x56, 0x98, 0xb7, + 0xde, 0xa5, 0x49, 0x6e, 0x2a, 0xe7, 0x0e, 0x7e, 0xde, 0xa7, 0xe3, 0x5b, + 0x8d, 0x3b, 0x95, 0x58, 0xa5, 0xf3, 0x5e, 0x92, 0x55, 0x4c, 0xd9, 0x6e, + 0x9b, 0x2b, 0x6b, 0x94, 0x62, 0x97, 0x6c, 0x83, 0x39, 0xfa, 0xc3, 0x66, + 0x05, 0xf4, 0x0a, 0x5d, 0xce, 0x50, 0xd2, 0xdf, 0xfd, 0x78, 0x35, 0x11, + 0x47, 0x26, 0x51, 0xdf, 0xb3, 0x51, 0x71, 0xc9, 0xd9, 0xf3, 0xba, 0xb8, + 0x22, 0x3e, 0x16, 0x87, 0x27, 0xe9, 0xb5, 0xca, 0x59, 0xff, 0x9d, 0xb9, + 0x1d, 0x8c, 0x07, 0xf5, 0x9c, 0x62, 0xd5, 0x39, 0x7f, 0x9e, 0x46, 0x07, + 0xd6, 0x25, 0x0c, 0xc6, 0xc0, 0xd5, 0x76, 0x37, 0xe7, 0xe1, 0x58, 0xa2, + 0x03, 0xf7, 0x27, 0xea, 0xc7, 0x9f, 0xa4, 0x6d, 0xe1, 0xee, 0x0e, 0xb4, + 0xf0, 0xd9, 0x50, 0xaa, 0xe6, 0x42, 0x37, 0x75, 0x3d, 0x31, 0xad, 0xce, + 0x59, 0x97, 0x77, 0x1b, 0x3a, 0xcb, 0xeb, 0xc4, 0xb3, 0xfa, 0xd8, 0x80, + 0xfa, 0xef, 0x15, 0x4c, 0x97, 0x5c, 0x32, 0x82, 0xe3, 0x09, 0x1f, 0xbe, + 0x9e, 0xb4, 0xe8, 0x03, 0xc0, 0xfa, 0x6c, 0x33, 0xf3, 0x88, 0xa7, 0xec, + 0x0a, 0x87, 0xeb, 0xba, 0x69, 0x83, 0x0b, 0x70, 0x82, 0xb1, 0xb7, 0x66, + 0x9e, 0xa1, 0x2d, 0x52, 0xe4, 0x7d, 0xeb, 0x5f, 0xdb, 0xee, 0x68, 0x09, + 0x36, 0x0c, 0x85, 0x22, 0x2b, 0x19, 0x67, 0x9f, 0x6a, 0x36, 0xc6, 0x6d, + 0xc6, 0xc0, 0x19, 0xd1, 0x04, 0xe7, 0x3a, 0x24, 0xff, 0xaf, 0x03, 0x7f, + 0x41, 0x3b, 0xff, 0x24, 0x21, 0x7e, 0x62, 0x10, 0x37, 0xfd, 0xf8, 0x06, + 0xed, 0xfc, 0x7c, 0xa2, 0x0e, 0x59, 0xfa, 0x65, 0x07, 0xfd, 0xe3, 0xdd, + 0x44, 0x30, 0x7e, 0x93, 0xca, 0x7c, 0x8f, 0xfe, 0xf1, 0x51, 0x22, 0x42, + 0xdf, 0xf9, 0x2a, 0x3f, 0x0d, 0xf4, 0x87, 0x3a, 0xd6, 0xd1, 0xe9, 0x07, + 0x7e, 0x9c, 0x65, 0xf9, 0x03, 0xa9, 0x9a, 0xd6, 0x15, 0x4a, 0x8d, 0x59, + 0xa3, 0x54, 0x30, 0x9f, 0xd5, 0x68, 0xff, 0xb7, 0xe0, 0x43, 0x59, 0x4f, + 0x4e, 0x12, 0x8b, 0x92, 0xe8, 0x2f, 0x22, 0x97, 0x5b, 0xe9, 0x9c, 0xe5, + 0xaf, 0x3f, 0xf1, 0xa9, 0x12, 0x1c, 0x3f, 0xe3, 0x0a, 0x76, 0xcc, 0x20, + 0x8f, 0xfe, 0x0b, 0xfa, 0xc1, 0x37, 0x59, 0xf6, 0x93, 0xbe, 0x62, 0x7c, + 0x63, 0x88, 0x31, 0x37, 0x55, 0x80, 0x82, 0x3d, 0x5e, 0x3c, 0x78, 0x48, + 0xc7, 0x3e, 0x27, 0x57, 0x17, 0x9d, 0x52, 0x77, 0xc4, 0x88, 0x73, 0x73, + 0x81, 0x19, 0x07, 0x56, 0xe3, 0xd4, 0x6e, 0x9d, 0x71, 0x2f, 0x67, 0x27, + 0xcf, 0x86, 0x1d, 0x6e, 0x1e, 0x17, 0x6e, 0x5e, 0xc0, 0x71, 0x6d, 0x4d, + 0x85, 0xda, 0xb7, 0x51, 0x17, 0xb7, 0x67, 0xc5, 0xfe, 0x22, 0x78, 0x8e, + 0x63, 0xeb, 0xa7, 0xad, 0x1c, 0x48, 0x54, 0x33, 0x47, 0xf7, 0xc1, 0xa2, + 0xad, 0x58, 0xf2, 0x0e, 0x13, 0x6d, 0xc5, 0xa2, 0xad, 0x58, 0xb4, 0x15, + 0x8b, 0xb6, 0x62, 0x65, 0x16, 0xe0, 0x99, 0x3e, 0x03, 0x23, 0xec, 0x73, + 0xe7, 0x30, 0x39, 0xbc, 0xf3, 0x3e, 0x50, 0x9d, 0xe4, 0x29, 0xca, 0xc4, + 0xdd, 0xb7, 0x60, 0xa8, 0xef, 0x56, 0x7e, 0x14, 0xb4, 0xd2, 0x66, 0x7a, + 0xd2, 0x62, 0x83, 0x22, 0x93, 0x17, 0xc3, 0x99, 0x9b, 0x2b, 0x51, 0x2c, + 0xf1, 0x5d, 0xc1, 0x0e, 0xe7, 0x7e, 0xde, 0xd6, 0xe4, 0x9e, 0x85, 0x9a, + 0x79, 0x9b, 0xf0, 0x48, 0x9f, 0x8a, 0xdb, 0xc2, 0xf2, 0x7f, 0x08, 0x9a, + 0x99, 0x0f, 0xc8, 0xfe, 0x7c, 0x82, 0xfe, 0x99, 0xb3, 0x15, 0x19, 0x53, + 0xa6, 0x7f, 0x13, 0x4e, 0xf4, 0x1b, 0x8c, 0x59, 0x26, 0x32, 0xe9, 0x04, + 0x7d, 0x42, 0xfc, 0xdc, 0xc0, 0x33, 0x6c, 0x6b, 0xf6, 0x80, 0x0b, 0x95, + 0x8d, 0x6e, 0x94, 0xd0, 0xdf, 0x6f, 0x4b, 0xd7, 0x04, 0xbe, 0xa5, 0x24, + 0x9c, 0xf5, 0xd7, 0x5d, 0x29, 0x8c, 0xcf, 0x34, 0x2a, 0xb1, 0x6f, 0xb0, + 0x11, 0x8f, 0xed, 0x76, 0xd1, 0x46, 0xed, 0x05, 0xe5, 0x4d, 0x46, 0xc7, + 0x02, 0x97, 0xe0, 0x45, 0x23, 0xbe, 0xc1, 0x1c, 0x60, 0x7d, 0x7f, 0xd0, + 0x7c, 0x05, 0x41, 0xf3, 0x24, 0x16, 0xe0, 0x59, 0x93, 0xb8, 0x39, 0xaf, + 0x11, 0x1b, 0xf7, 0x1b, 0xb4, 0x29, 0x37, 0xf3, 0x63, 0xf9, 0xbf, 0x37, + 0xba, 0xb3, 0xc6, 0xf3, 0x32, 0xe4, 0x9c, 0x43, 0xb3, 0xfc, 0x4f, 0x06, + 0xa5, 0x87, 0xf8, 0x34, 0xa3, 0xd7, 0xe0, 0xb8, 0x5f, 0xb0, 0x4b, 0x0d, + 0xf9, 0x7f, 0x1c, 0xc4, 0x11, 0x8e, 0xfb, 0xc2, 0xcd, 0x6f, 0xdb, 0x95, + 0x86, 0xc4, 0x50, 0xe2, 0x49, 0x5a, 0xfa, 0x8f, 0xed, 0x08, 0x10, 0x3b, + 0x3a, 0xfa, 0x8d, 0x78, 0x29, 0x63, 0xd8, 0x46, 0x07, 0x63, 0x04, 0x5f, + 0x8c, 0xb6, 0x6f, 0x21, 0xa4, 0xad, 0x20, 0xee, 0x9c, 0xe6, 0x58, 0x7a, + 0x52, 0x82, 0x51, 0x3a, 0x8a, 0x7a, 0x63, 0xb8, 0x81, 0x39, 0x63, 0x41, + 0x6f, 0x0b, 0x6a, 0x99, 0x3f, 0xba, 0x7b, 0x5b, 0x61, 0x30, 0x97, 0x9c, + 0xd9, 0xbb, 0x1c, 0x0b, 0xc6, 0xf2, 0x1c, 0x5a, 0xc7, 0x11, 0x67, 0xdd, + 0xea, 0x29, 0x78, 0xee, 0xd3, 0x69, 0x53, 0x72, 0xe6, 0xc5, 0x6b, 0x55, + 0x12, 0x37, 0xcf, 0x50, 0xd7, 0xed, 0x03, 0xab, 0xed, 0x81, 0x94, 0xf0, + 0xa6, 0x2e, 0x78, 0x9a, 0x24, 0xf7, 0xd1, 0x31, 0x46, 0x8e, 0x3c, 0xcc, + 0x1c, 0xec, 0x8d, 0xfd, 0xab, 0x71, 0xff, 0x9e, 0xcb, 0x39, 0x9b, 0xd9, + 0x64, 0xfd, 0x7b, 0xda, 0xc5, 0x86, 0x12, 0xda, 0x85, 0x97, 0x76, 0xb1, + 0x2b, 0x15, 0x32, 0x0f, 0xd3, 0x2e, 0x6a, 0x89, 0x21, 0x1d, 0xbd, 0x92, + 0xef, 0x38, 0xef, 0xed, 0x55, 0x78, 0x10, 0xc0, 0x9b, 0xb4, 0x8f, 0x8d, + 0xbd, 0x76, 0x97, 0x9b, 0xb1, 0xa7, 0xa7, 0xb9, 0x1a, 0xaf, 0x65, 0x6e, + 0xc5, 0xa3, 0xfd, 0xd5, 0x78, 0x85, 0xb6, 0xf3, 0x76, 0x02, 0xf3, 0x2b, + 0xa0, 0xce, 0xac, 0x60, 0xac, 0xbe, 0x4d, 0x09, 0xb5, 0x2e, 0x42, 0xfd, + 0xf8, 0xcb, 0x4a, 0xb0, 0x93, 0x9c, 0xe5, 0xc4, 0x05, 0x62, 0xff, 0xeb, + 0x19, 0x39, 0x77, 0xe7, 0xc3, 0x38, 0xed, 0x6a, 0x9c, 0xf5, 0xbe, 0xd1, + 0x5f, 0xc7, 0x79, 0xf3, 0xa0, 0xd0, 0xf0, 0xe3, 0x14, 0xb1, 0xb4, 0x63, + 0x37, 0xc6, 0x03, 0x86, 0x71, 0xa2, 0x55, 0xa9, 0xc2, 0x9b, 0xc3, 0xb7, + 0x62, 0x63, 0x7f, 0x50, 0x8f, 0xd1, 0x37, 0x5f, 0xe3, 0xb3, 0xf5, 0xbb, + 0x67, 0xe1, 0x38, 0x6d, 0x6f, 0x9c, 0xb6, 0xb7, 0xb6, 0x5f, 0xc5, 0x8b, + 0xc3, 0xb7, 0xb0, 0x5f, 0x05, 0xb3, 0x6a, 0x15, 0x27, 0xff, 0xda, 0x91, + 0x72, 0xfe, 0x77, 0x81, 0xf3, 0x8e, 0xde, 0x9c, 0x51, 0x13, 0xb3, 0xf7, + 0xcb, 0xf8, 0xc8, 0xc3, 0x9c, 0xb5, 0xe9, 0x46, 0xdc, 0xbc, 0xa7, 0x12, + 0xe7, 0xf6, 0x1a, 0x56, 0xb9, 0xcb, 0x5e, 0x70, 0x2a, 0x1c, 0xe2, 0x3c, + 0x34, 0xa2, 0xe1, 0x50, 0x23, 0x42, 0x03, 0xb9, 0x18, 0xa1, 0x19, 0x0b, + 0xf0, 0x3d, 0xce, 0xfb, 0x5a, 0xe6, 0x80, 0x35, 0x43, 0x82, 0xbd, 0x36, + 0x73, 0xc5, 0x66, 0x4c, 0x8c, 0x8d, 0x73, 0x6c, 0x11, 0x9c, 0x25, 0xbf, + 0x7d, 0x9f, 0x31, 0xe3, 0x43, 0xe6, 0x80, 0x1f, 0x3a, 0x31, 0x43, 0xde, + 0xa5, 0xbd, 0x32, 0x6e, 0xec, 0xe2, 0x9c, 0x6e, 0xec, 0x37, 0xea, 0xfa, + 0xf8, 0x7b, 0xbd, 0x33, 0xc7, 0x31, 0xe2, 0xb9, 0x60, 0x85, 0xe0, 0x7f, + 0x0b, 0x73, 0xde, 0x56, 0x9c, 0xed, 0x0b, 0x99, 0x0b, 0x95, 0x56, 0xbc, + 0x47, 0x99, 0xfb, 0x28, 0x5f, 0x92, 0xbc, 0x6c, 0x66, 0xd2, 0x18, 0xff, + 0xd0, 0x25, 0x18, 0xd3, 0x8a, 0xf2, 0xec, 0xad, 0x38, 0xd5, 0xbf, 0x1c, + 0xa5, 0x43, 0xc2, 0x35, 0xa5, 0x4d, 0x37, 0xb6, 0xee, 0xbe, 0x13, 0xeb, + 0x0f, 0xe6, 0x72, 0xbe, 0xf5, 0x89, 0x4d, 0xcc, 0x75, 0x85, 0xbf, 0xd7, + 0xe1, 0x50, 0x2a, 0x26, 0x47, 0x42, 0x77, 0x30, 0x9f, 0x8b, 0xac, 0x20, + 0x7e, 0x2e, 0x0d, 0x13, 0x63, 0x2b, 0x82, 0x81, 0x97, 0x61, 0xe9, 0xbc, + 0x17, 0x58, 0x07, 0xd1, 0x89, 0x85, 0x65, 0x8c, 0x3b, 0xb7, 0xf5, 0xbb, + 0x29, 0xbb, 0x3c, 0xaf, 0xc3, 0x8f, 0x52, 0x56, 0x5c, 0x9e, 0x6f, 0x84, + 0xf8, 0x8a, 0xe8, 0xc9, 0x05, 0xb3, 0xa9, 0x26, 0xd6, 0x41, 0x8c, 0x2e, + 0x0d, 0x07, 0xcd, 0x6f, 0xa0, 0x99, 0x73, 0x2f, 0x32, 0x47, 0xb0, 0xfe, + 0x10, 0x9c, 0x7d, 0x7f, 0x79, 0x47, 0xe4, 0x3f, 0xf4, 0xed, 0x76, 0xec, + 0x69, 0x7d, 0xe3, 0x65, 0x1b, 0x3c, 0x90, 0xaa, 0xef, 0x74, 0xa1, 0xc6, + 0x2a, 0x87, 0x91, 0xee, 0x23, 0x2f, 0x8d, 0x23, 0xd8, 0x13, 0x87, 0xc4, + 0x8c, 0x7a, 0x4b, 0x43, 0x35, 0xdb, 0x8e, 0xe0, 0xad, 0x84, 0x4b, 0xb0, + 0x09, 0xf2, 0x4f, 0x8a, 0x22, 0xc4, 0xe1, 0x37, 0x12, 0xc5, 0xd0, 0x87, + 0x12, 0xce, 0xff, 0x11, 0xba, 0x39, 0x6b, 0x91, 0xaf, 0x2d, 0xc0, 0xab, + 0xfd, 0x3e, 0xcc, 0x27, 0x4f, 0xa9, 0x4b, 0x3e, 0x65, 0x97, 0x12, 0x87, + 0xeb, 0x87, 0x42, 0x9a, 0x47, 0xb1, 0xed, 0x03, 0x73, 0x7f, 0x6d, 0x4f, + 0x8b, 0x4a, 0x59, 0x23, 0xb2, 0x48, 0xfe, 0x9f, 0xd4, 0x3c, 0xa3, 0xf5, + 0x2c, 0x7c, 0xb8, 0x81, 0x58, 0x7a, 0xac, 0xb7, 0x12, 0x6f, 0xed, 0xee, + 0x91, 0x35, 0x4b, 0x18, 0xfc, 0xfd, 0x5a, 0x6f, 0x00, 0x3a, 0xb1, 0x4c, + 0xe7, 0x75, 0x03, 0x31, 0x5a, 0x27, 0x3e, 0xbf, 0xdd, 0x6b, 0x2f, 0xf0, + 0x35, 0x59, 0x6c, 0xbd, 0x0e, 0x0b, 0x88, 0xd1, 0x6f, 0xf4, 0x06, 0x4f, + 0x2c, 0x51, 0x15, 0x94, 0x34, 0x99, 0xec, 0xdb, 0x87, 0x17, 0x69, 0xdf, + 0x4f, 0xa4, 0x8e, 0x7e, 0x6d, 0x06, 0xac, 0xfa, 0x12, 0x04, 0x37, 0x78, + 0x14, 0x59, 0xe3, 0x90, 0xd8, 0x56, 0x8d, 0x1b, 0xc9, 0x4d, 0x74, 0xe2, + 0x77, 0x4d, 0x56, 0xe2, 0x1c, 0xb0, 0x66, 0x68, 0x35, 0x3e, 0x1c, 0x14, + 0x1f, 0xc5, 0x42, 0xb1, 0xff, 0x05, 0xe1, 0x90, 0x79, 0x86, 0xb8, 0x5c, + 0x3b, 0x96, 0x20, 0xfe, 0xca, 0xb9, 0x3c, 0x8c, 0xab, 0xc4, 0x81, 0xca, + 0x94, 0x60, 0x57, 0x00, 0x8d, 0xcc, 0xf7, 0xca, 0x53, 0xe2, 0x93, 0x96, + 0x9c, 0x1b, 0xc1, 0xcd, 0x63, 0x3e, 0xe8, 0x63, 0x1a, 0x3f, 0x7e, 0xe8, + 0x23, 0x55, 0xfc, 0x50, 0xd6, 0x91, 0x59, 0xfc, 0x50, 0x56, 0xc6, 0x31, + 0x73, 0x44, 0xc1, 0x4d, 0x8e, 0x6d, 0x89, 0x0f, 0x7a, 0xf1, 0xec, 0x28, + 0xb0, 0xa1, 0xdf, 0xc4, 0xe1, 0xfd, 0x39, 0x9c, 0xdb, 0xcc, 0x3e, 0x42, + 0x03, 0x61, 0xac, 0x4f, 0x8b, 0x7d, 0x36, 0xe2, 0xb7, 0x7b, 0x8d, 0xb6, + 0x35, 0x6a, 0x28, 0xb2, 0x9c, 0x18, 0xf6, 0xfe, 0x48, 0x23, 0x3e, 0x7c, + 0x62, 0x01, 0x8c, 0x70, 0x23, 0xce, 0x1c, 0xd8, 0x84, 0xf2, 0x27, 0x54, + 0xe2, 0x8f, 0x8a, 0xf1, 0xe9, 0x82, 0xed, 0x82, 0xa3, 0x5e, 0xab, 0x8c, + 0xb8, 0xb5, 0x8d, 0xb8, 0xf5, 0xb3, 0xb9, 0xe3, 0x98, 0x9f, 0x94, 0x73, + 0xad, 0xcc, 0xaf, 0xd4, 0x08, 0x9e, 0x24, 0x6e, 0xed, 0xea, 0x93, 0xf9, + 0xe2, 0xdc, 0x12, 0xb3, 0xb6, 0xa6, 0x73, 0x9c, 0xe8, 0x70, 0xbf, 0xa1, + 0xb9, 0x68, 0xcb, 0x43, 0x93, 0x78, 0xf5, 0x5b, 0xc6, 0xff, 0x47, 0xe6, + 0x45, 0x71, 0x36, 0x2d, 0x7e, 0x25, 0x71, 0x45, 0xc7, 0x87, 0xb4, 0xf1, + 0xa5, 0xd4, 0xf5, 0x19, 0xe6, 0x16, 0x2d, 0x8c, 0x73, 0x1f, 0xd3, 0x9e, + 0x97, 0x93, 0x3f, 0xbe, 0x97, 0x12, 0x1b, 0x59, 0x8e, 0x25, 0x59, 0xb1, + 0x05, 0x67, 0x9d, 0x95, 0xdf, 0x31, 0x9c, 0x4e, 0xfc, 0xb1, 0xb8, 0xb0, + 0x12, 0xaf, 0x0e, 0xca, 0x79, 0x17, 0x03, 0xde, 0xde, 0xa0, 0x56, 0xa2, + 0xc8, 0x9e, 0x6e, 0x9e, 0xfb, 0x4e, 0x38, 0x39, 0x76, 0x69, 0x34, 0xbf, + 0xbf, 0x98, 0xdf, 0x77, 0xb0, 0xf0, 0xfd, 0xb9, 0x01, 0xf2, 0x4f, 0x28, + 0x87, 0xe7, 0x16, 0xe0, 0xf6, 0x3d, 0x6d, 0x18, 0xd9, 0xfd, 0x31, 0x8a, + 0xfa, 0xd5, 0x7b, 0x7d, 0xa8, 0xa9, 0x7b, 0x48, 0xe9, 0xc2, 0xa2, 0xb0, + 0xbc, 0xe7, 0x23, 0x6b, 0xe6, 0x7d, 0xd8, 0x7c, 0x80, 0x79, 0xcc, 0xd8, + 0x75, 0x38, 0xaa, 0x31, 0x1e, 0x9a, 0x1f, 0xa3, 0xa0, 0xdf, 0xe3, 0x9c, + 0x05, 0x3c, 0x6a, 0x36, 0x61, 0xe5, 0xe4, 0x59, 0x40, 0x54, 0x5d, 0xbd, + 0x97, 0x00, 0x5f, 0xe9, 0xe4, 0xff, 0x1f, 0xc8, 0xbd, 0xdb, 0x63, 0xa0, + 0x77, 0xf4, 0x7f, 0x95, 0xe7, 0xce, 0x06, 0xfd, 0x6b, 0xca, 0x76, 0xa2, + 0x7d, 0xcf, 0xe3, 0x58, 0xb1, 0xe7, 0x3b, 0xb8, 0x73, 0xa0, 0xb6, 0x33, + 0xc2, 0x5c, 0xe7, 0x83, 0xf0, 0x38, 0x8e, 0x85, 0x8b, 0x60, 0xf9, 0xc9, + 0xb1, 0x6e, 0xfc, 0x8a, 0xbc, 0x4e, 0xca, 0xbf, 0xd3, 0xb6, 0x7e, 0xaf, + 0xb4, 0xf7, 0xf6, 0xa4, 0x7f, 0xfd, 0x7c, 0x9a, 0x9c, 0xa7, 0x79, 0x21, + 0xf5, 0x2b, 0x5b, 0x77, 0x9e, 0xe7, 0xef, 0xbf, 0x65, 0xc7, 0xfc, 0x72, + 0x7f, 0xd6, 0x64, 0xbd, 0xef, 0xe0, 0x01, 0xe6, 0xbf, 0xa7, 0x9b, 0xbe, + 0x83, 0x85, 0x43, 0x97, 0xea, 0xa0, 0x68, 0xf7, 0x3a, 0x07, 0xbb, 0xe9, + 0x61, 0xe4, 0x48, 0xb2, 0x57, 0x25, 0xfb, 0x27, 0x7f, 0x89, 0xcd, 0x7b, + 0x65, 0x6d, 0xd3, 0xb6, 0xd7, 0x1b, 0xb2, 0xc7, 0x97, 0x3f, 0x37, 0x27, + 0xed, 0x58, 0x8a, 0x95, 0x91, 0xba, 0x5b, 0x94, 0xbe, 0xcc, 0xd4, 0x31, + 0x4d, 0x93, 0xff, 0x97, 0xa7, 0x95, 0x44, 0xa7, 0x8e, 0xad, 0x47, 0xd9, + 0x9e, 0x39, 0xa2, 0xec, 0xca, 0x5c, 0xad, 0x8f, 0xe7, 0xec, 0x58, 0x9b, + 0xb4, 0x21, 0x32, 0xc1, 0x8f, 0x62, 0x91, 0x2b, 0xff, 0xec, 0x99, 0x49, + 0xb9, 0x0b, 0xa1, 0x57, 0xe6, 0xe4, 0xbe, 0x9f, 0x72, 0x9b, 0x4d, 0x31, + 0xa8, 0xf3, 0xa6, 0xca, 0x9e, 0x1f, 0xe7, 0x7f, 0xbb, 0xd4, 0x56, 0xae, + 0xdc, 0xcd, 0x7e, 0xb1, 0x21, 0x75, 0xde, 0xd4, 0x35, 0xfb, 0x02, 0xe2, + 0x47, 0x48, 0xdb, 0x8a, 0x5c, 0xbe, 0xb7, 0xe6, 0xca, 0x7c, 0x4f, 0xb0, + 0x0b, 0x23, 0x09, 0x0d, 0xef, 0x99, 0x92, 0xdf, 0xc9, 0xad, 0x28, 0xbe, + 0xc7, 0xfc, 0xf1, 0x99, 0x44, 0xb0, 0x75, 0x9d, 0x52, 0x1f, 0x9b, 0xc3, + 0x38, 0x87, 0x0a, 0x59, 0x4f, 0x8f, 0x38, 0xff, 0xaf, 0x2a, 0x13, 0x8a, + 0x20, 0x43, 0x7f, 0x78, 0x23, 0x11, 0xec, 0x38, 0xa3, 0xe4, 0xfe, 0x0f, + 0xd6, 0xeb, 0xce, 0xfb, 0x1c, 0x79, 0xbb, 0x13, 0xce, 0x39, 0x75, 0x3d, + 0x57, 0x6c, 0x30, 0xd8, 0x97, 0x46, 0xa5, 0xac, 0x9b, 0x58, 0x16, 0xf3, + 0xa1, 0xee, 0x94, 0x15, 0x50, 0xf1, 0x15, 0xc4, 0xfd, 0xb2, 0x47, 0x72, + 0xcb, 0xe4, 0xff, 0xa9, 0x11, 0x7e, 0xf4, 0x2f, 0xaf, 0x4f, 0xc9, 0xff, + 0x06, 0xca, 0xdb, 0x8b, 0x35, 0x76, 0x3d, 0xd2, 0x9a, 0xac, 0x7d, 0xc0, + 0x9a, 0x46, 0x5d, 0xfb, 0x8d, 0x4d, 0x1c, 0xb7, 0x07, 0xd3, 0x99, 0xdb, + 0x85, 0x6b, 0xeb, 0xdb, 0x1a, 0xd5, 0x6b, 0x10, 0xab, 0x08, 0x6a, 0x31, + 0x72, 0xcd, 0x1e, 0xe7, 0xff, 0xed, 0xc8, 0xb9, 0x14, 0xab, 0xd5, 0x4b, + 0x4c, 0x6f, 0x52, 0x14, 0x14, 0x84, 0xe0, 0x7e, 0x28, 0xe3, 0x86, 0x56, + 0xfb, 0x5b, 0xfb, 0x17, 0x7e, 0x03, 0xdb, 0xc6, 0x6e, 0xb9, 0xf4, 0xff, + 0x87, 0xfe, 0x63, 0xf6, 0xea, 0xec, 0x37, 0xdf, 0xe6, 0xc7, 0x76, 0x6c, + 0xba, 0xf4, 0x2d, 0xed, 0xfe, 0x31, 0x59, 0xf3, 0xef, 0x7a, 0xd4, 0xe8, + 0x2e, 0x94, 0x63, 0xab, 0xb9, 0xde, 0x2f, 0x67, 0xe5, 0xd6, 0x43, 0xf6, + 0xff, 0x65, 0x0e, 0xe4, 0x1d, 0xc3, 0x08, 0xf3, 0x6e, 0xd1, 0x4b, 0x14, + 0x0f, 0x66, 0xe4, 0x9d, 0xa0, 0x59, 0x90, 0xff, 0xfb, 0xf5, 0x60, 0x26, + 0xa7, 0xbf, 0x47, 0x33, 0x3e, 0xe6, 0x00, 0x3e, 0xda, 0x60, 0x07, 0xf9, + 0x0b, 0xf9, 0xd3, 0x25, 0x5d, 0xde, 0xeb, 0x97, 0x75, 0x85, 0xef, 0xd3, + 0xa7, 0xdd, 0xb5, 0x72, 0x6d, 0xc9, 0xb9, 0x51, 0x25, 0x77, 0x7d, 0xde, + 0x79, 0x37, 0x52, 0x8d, 0xae, 0xc3, 0xc2, 0xc4, 0x34, 0x39, 0x3f, 0x29, + 0x6b, 0x36, 0x96, 0x3f, 0x2a, 0xef, 0x61, 0xf8, 0x88, 0xb1, 0x5f, 0xf5, + 0x4f, 0xbe, 0x73, 0xd5, 0xba, 0x82, 0x38, 0x36, 0x27, 0x6c, 0xc4, 0x9a, + 0x94, 0xa0, 0xbe, 0x52, 0x69, 0x63, 0xbd, 0x3a, 0xf4, 0x64, 0xa5, 0x0d, + 0xc5, 0xf9, 0xdf, 0x92, 0x1e, 0xb6, 0x71, 0x30, 0x51, 0xaf, 0x7b, 0xd4, + 0x4f, 0x6d, 0xcb, 0x39, 0x03, 0x29, 0xfb, 0xf6, 0x71, 0xbc, 0x94, 0x98, + 0x4e, 0x94, 0xba, 0xba, 0xdd, 0x4b, 0xeb, 0xe7, 0x7f, 0xa3, 0x21, 0xc6, + 0xb6, 0x82, 0x9d, 0x61, 0x57, 0x70, 0xc3, 0x05, 0xe2, 0x4a, 0x36, 0x6c, + 0xc4, 0x7f, 0xc0, 0x3e, 0xfe, 0x56, 0xa9, 0x43, 0x62, 0x4a, 0xfb, 0xb9, + 0xb6, 0xea, 0xdb, 0x0b, 0xd4, 0xf3, 0xce, 0xbb, 0xf8, 0xd2, 0xbe, 0x16, + 0x5d, 0x0d, 0x2d, 0x69, 0xd9, 0x7e, 0xb6, 0x39, 0x33, 0x1a, 0xdc, 0x57, + 0x41, 0x30, 0xfa, 0xb6, 0xda, 0x85, 0x35, 0x72, 0x3c, 0x24, 0x1a, 0xd4, + 0x1f, 0xa0, 0x7d, 0x34, 0x3a, 0x6d, 0xc4, 0xea, 0x0a, 0x20, 0x9c, 0xf2, + 0x4b, 0xed, 0x84, 0x39, 0x81, 0x70, 0x31, 0x96, 0x73, 0xce, 0x03, 0xc8, + 0xb9, 0x49, 0xe6, 0x0d, 0x09, 0xf9, 0xbf, 0x7d, 0x4e, 0x37, 0x93, 0x7b, + 0x5a, 0xcc, 0xd7, 0x19, 0xaf, 0xd7, 0xcb, 0xff, 0x48, 0x2a, 0xf6, 0xe1, + 0xc1, 0x84, 0xac, 0x81, 0xfc, 0x1f, 0x05, 0x3f, 0x96, 0xb4, 0x1c, 0x54, + 0x00, 0x00, 0x00 }; static const u32 bnx2_CP_b09FwData[(0x84/4) + 1] = { 0x00000000, 0x0000001b, 0x0000000f, 0x0000000a, 0x00000008, 0x00000006, @@ -2079,1076 +2057,1088 @@ static const u32 bnx2_CP_b09FwData[(0x84/4) + 1] = { 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000 }; static const u32 bnx2_CP_b09FwRodata[(0x16c/4) + 1] = { - 0x80080100, 0x80080080, 0x80080000, 0x08001744, 0x08001744, 0x0800177c, - 0x0800177c, 0x08001790, 0x08001760, 0x080019b8, 0x08001984, 0x08001a10, - 0x08001a10, 0x08001a98, 0x080019c8, 0x80080240, 0x08003260, 0x080031cc, - 0x08003288, 0x080032b0, 0x080032d8, 0x080032fc, 0x08003344, 0x08003320, - 0x08003368, 0x08003234, 0x0800345c, 0x0800344c, 0x080031e8, 0x080031e8, - 0x080031e8, 0x080033bc, 0x080033bc, 0x080031e8, 0x080031e8, 0x0800343c, - 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x0800342c, 0x080031e8, - 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, - 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, - 0x080031e8, 0x0800341c, 0x080031e8, 0x080031e8, 0x0800340c, 0x080031e8, - 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, - 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, - 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080033f4, 0x080031e8, - 0x080031e8, 0x080033e4, 0x080033d4, 0x08003d6c, 0x08003d40, 0x08003d0c, - 0x08003ce0, 0x08003cc0, 0x08003c74, 0x80080100, 0x80080080, 0x80080000, + 0x80080100, 0x80080080, 0x80080000, 0x08001800, 0x08001800, 0x08001838, + 0x08001838, 0x0800184c, 0x0800181c, 0x08001a74, 0x08001a40, 0x08001acc, + 0x08001acc, 0x08001b54, 0x08001a84, 0x80080240, 0x080021c4, 0x08002010, + 0x080021ec, 0x08002284, 0x080023d4, 0x08002420, 0x08002544, 0x0800244c, + 0x080024d0, 0x08002080, 0x080029f8, 0x0800299c, 0x0800202c, 0x0800202c, + 0x0800202c, 0x080025b8, 0x080025b8, 0x0800202c, 0x0800202c, 0x08002874, + 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x080028d4, 0x0800202c, + 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, + 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, + 0x0800202c, 0x08002440, 0x0800202c, 0x0800202c, 0x08002944, 0x0800202c, + 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, + 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, + 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x08002798, 0x0800202c, + 0x0800202c, 0x08002700, 0x0800265c, 0x080037c0, 0x08003794, 0x08003760, + 0x08003734, 0x08003714, 0x080036c8, 0x80080100, 0x80080080, 0x80080000, 0x80080080, 0x00000000 }; static struct fw_info bnx2_cp_fw_09 = { - /* Firmware version: 4.4.23 */ + /* Firmware version: 4.6.15 */ .ver_major = 0x4, - .ver_minor = 0x4, - .ver_fix = 0x17, + .ver_minor = 0x6, + .ver_fix = 0xf, .start_addr = 0x08000080, .text_addr = 0x08000000, - .text_len = 0x5938, + .text_len = 0x5418, .text_index = 0x0, .gz_text = bnx2_CP_b09FwText, .gz_text_len = sizeof(bnx2_CP_b09FwText), - .data_addr = 0x08005ac0, + .data_addr = 0x080055a0, .data_len = 0x84, .data_index = 0x0, .data = bnx2_CP_b09FwData, - .sbss_addr = 0x08005b44, + .sbss_addr = 0x08005624, .sbss_len = 0x91, .sbss_index = 0x0, - .bss_addr = 0x08005bd8, + .bss_addr = 0x080056b8, .bss_len = 0x19c, .bss_index = 0x0, - .rodata_addr = 0x08005938, + .rodata_addr = 0x08005418, .rodata_len = 0x16c, .rodata_index = 0x0, .rodata = bnx2_CP_b09FwRodata, }; static u8 bnx2_RXP_b09FwText[] = { - 0xec, 0x5c, 0x7f, 0x70, 0x1c, 0xd5, 0x7d, 0xff, 0xbc, 0xbd, 0xbd, 0xbb, - 0x95, 0x74, 0x3e, 0xed, 0x9d, 0x4e, 0xb2, 0x04, 0x06, 0xef, 0xa2, 0x95, - 0x74, 0x58, 0xc6, 0xec, 0x9d, 0x4e, 0xb6, 0x48, 0xb7, 0xc9, 0xd5, 0x36, - 0x20, 0x17, 0x52, 0x84, 0xa1, 0xc1, 0xcc, 0x30, 0x9d, 0x1b, 0x63, 0x8c, - 0xb0, 0x1d, 0xa2, 0x00, 0x33, 0xc8, 0x29, 0x13, 0x16, 0xfc, 0xb3, 0xf8, - 0xa4, 0x93, 0x8d, 0x8c, 0xc9, 0xf4, 0xd7, 0x21, 0xcb, 0x8a, 0x81, 0x93, - 0xce, 0x04, 0xda, 0x98, 0x69, 0xa8, 0x15, 0x6c, 0x53, 0x87, 0x5f, 0x21, - 0x19, 0x68, 0x4d, 0x9b, 0x99, 0xa8, 0x06, 0x1c, 0xd3, 0xa6, 0xd4, 0xb4, - 0x0e, 0xb5, 0x8b, 0xeb, 0xd7, 0xef, 0x77, 0x4f, 0x97, 0x50, 0x42, 0xcb, - 0x64, 0xa6, 0x7f, 0xee, 0x77, 0xe6, 0xe6, 0xf6, 0xde, 0xfb, 0xbe, 0xef, - 0x7b, 0xdf, 0xdf, 0x9f, 0xb7, 0x1a, 0xfb, 0xbe, 0x08, 0x6a, 0x31, 0x4b, - 0x73, 0xe8, 0x93, 0x19, 0x18, 0xbc, 0x27, 0xbd, 0x28, 0xb3, 0x88, 0x1e, - 0xbb, 0x02, 0x73, 0x55, 0x95, 0xc7, 0x05, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, - 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, - 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, - 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, - 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, - 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xfa, 0xff, 0xa4, 0x00, - 0xa0, 0xf3, 0xf7, 0x9c, 0xd9, 0x0f, 0x34, 0xc5, 0x71, 0x37, 0x2e, 0xb5, - 0xa0, 0x05, 0x9c, 0x33, 0x1b, 0x6f, 0xb7, 0x80, 0x6c, 0xa9, 0xd3, 0x58, - 0x86, 0xff, 0x92, 0x6e, 0x42, 0x05, 0x8f, 0x5f, 0xe2, 0x9c, 0xff, 0xf3, - 0x17, 0x96, 0x98, 0xa7, 0x8b, 0x01, 0x68, 0xba, 0xf3, 0x46, 0x4a, 0x6f, - 0x87, 0x36, 0x8f, 0xd6, 0xfc, 0x49, 0xc7, 0x95, 0x71, 0x44, 0xab, 0xb2, - 0xe0, 0x2a, 0x8e, 0x94, 0xfb, 0x6c, 0x89, 0x97, 0x6c, 0x57, 0xf4, 0x66, - 0xe0, 0x06, 0x9c, 0x83, 0xe2, 0xae, 0xfc, 0x05, 0x69, 0x04, 0x2b, 0x3b, - 0xab, 0x93, 0x1a, 0x82, 0xfb, 0xa0, 0xab, 0x8e, 0x82, 0xa0, 0x55, 0x8b, - 0xd0, 0x13, 0x75, 0x08, 0x3e, 0xd1, 0x8c, 0xf0, 0xe4, 0x01, 0x91, 0x2b, - 0x6a, 0x98, 0x09, 0x1c, 0x14, 0x6b, 0x4a, 0xc8, 0x05, 0x9d, 0xb3, 0x37, - 0x8c, 0xd1, 0xba, 0xac, 0xf7, 0xef, 0x4b, 0xa6, 0x6f, 0x18, 0x2f, 0x41, - 0x0f, 0x38, 0x50, 0x54, 0xe7, 0x08, 0x3d, 0x33, 0xdf, 0xd9, 0x1b, 0xf6, - 0x96, 0x4e, 0xc9, 0x17, 0x3a, 0x12, 0x38, 0x54, 0xd6, 0x71, 0xa0, 0xfc, - 0x10, 0x9d, 0xc3, 0x74, 0x5d, 0x68, 0xae, 0xea, 0xb8, 0xd8, 0x92, 0x09, - 0x62, 0x62, 0xe4, 0x82, 0x0c, 0x58, 0xa6, 0x01, 0xc5, 0xd2, 0x0f, 0x83, - 0xf8, 0x0a, 0xc4, 0x57, 0x08, 0x62, 0xac, 0xb8, 0x23, 0x8e, 0xda, 0x66, - 0xbc, 0xd0, 0xc1, 0xeb, 0x79, 0x2d, 0xcb, 0xf8, 0x38, 0x5a, 0x5d, 0x1f, - 0xa2, 0xf5, 0x47, 0x33, 0xc0, 0xf8, 0x48, 0x1f, 0x2d, 0x95, 0xd8, 0x64, - 0x87, 0xb1, 0x5a, 0x87, 0x5b, 0xe3, 0xb0, 0xac, 0xaa, 0x1c, 0x57, 0x18, - 0x93, 0xff, 0x5c, 0x5f, 0x91, 0x03, 0xa1, 0x59, 0x70, 0xc3, 0x9f, 0x9a, - 0x3f, 0x55, 0xaa, 0xce, 0x6f, 0xa7, 0x7d, 0x34, 0x9a, 0xef, 0xc7, 0x5f, - 0x96, 0xd7, 0xe0, 0x2f, 0xca, 0xb7, 0xe1, 0xd9, 0x72, 0x1f, 0xed, 0x7b, - 0x1f, 0xed, 0x3b, 0x80, 0xbf, 0x2e, 0x6f, 0xc0, 0x77, 0xcb, 0x39, 0x3c, - 0x57, 0x5e, 0x85, 0xef, 0x94, 0x6f, 0xc6, 0x33, 0x65, 0x78, 0x67, 0x38, - 0x95, 0x49, 0x8a, 0x1f, 0xe5, 0x6b, 0xa0, 0xee, 0xdc, 0x8c, 0xe9, 0x52, - 0x10, 0xc1, 0x9d, 0x12, 0x23, 0xb6, 0xf9, 0x38, 0xd0, 0xa1, 0x07, 0x21, - 0xb0, 0xcc, 0x36, 0xf7, 0x03, 0x5f, 0x40, 0x2e, 0x61, 0x1e, 0x00, 0x9a, - 0xc4, 0x8f, 0x47, 0x9b, 0xc4, 0x6b, 0xa3, 0xaa, 0x78, 0x3d, 0x2f, 0x50, - 0xef, 0x20, 0xf2, 0x72, 0x46, 0xca, 0xeb, 0xd2, 0x52, 0x96, 0x52, 0x56, - 0xef, 0x0f, 0x85, 0x69, 0x3f, 0x22, 0x2e, 0x85, 0xd1, 0x68, 0x66, 0xd7, - 0x09, 0xcd, 0xad, 0x25, 0xf9, 0x2b, 0xba, 0x01, 0x6b, 0xa7, 0x41, 0x7e, - 0x60, 0x1d, 0x37, 0xe1, 0x0e, 0x2f, 0x26, 0xfa, 0xd0, 0x60, 0x2d, 0xc5, - 0xbd, 0x7d, 0x36, 0x8a, 0x65, 0x68, 0x31, 0xe7, 0x0c, 0x52, 0xc3, 0x02, - 0x36, 0xf9, 0x5b, 0xd0, 0xb3, 0x5d, 0x5a, 0xdf, 0x50, 0xf1, 0x37, 0x9d, - 0xbd, 0x40, 0x67, 0x2f, 0xd0, 0xd9, 0x0b, 0xa4, 0x57, 0x81, 0xf4, 0x2a, - 0x90, 0x0e, 0x05, 0xd2, 0xad, 0x40, 0x7a, 0x14, 0x48, 0x8f, 0x02, 0xe9, - 0x58, 0x60, 0x5f, 0x0d, 0x92, 0x0d, 0x22, 0xf8, 0xbb, 0xfc, 0x3c, 0x9c, - 0xe1, 0xcf, 0x4a, 0x1d, 0xc7, 0xe9, 0x8c, 0x8a, 0xf5, 0x9b, 0xca, 0xf8, - 0x6e, 0x84, 0x7c, 0x64, 0xfc, 0xe6, 0x7b, 0x2f, 0xc4, 0xc9, 0xfc, 0xbb, - 0x32, 0x34, 0x97, 0xf7, 0xfc, 0x22, 0xe4, 0x28, 0x70, 0xe9, 0x6e, 0x29, - 0xcf, 0x75, 0xcd, 0xc8, 0xb7, 0x6f, 0x61, 0x59, 0x0e, 0x4e, 0x8c, 0x2a, - 0x08, 0xd0, 0xd8, 0xb5, 0xf6, 0xdf, 0xcb, 0x3b, 0x13, 0xcc, 0xf7, 0x51, - 0x04, 0xb5, 0x6c, 0x27, 0x68, 0x0d, 0xce, 0xbb, 0x1b, 0xef, 0x6d, 0x87, - 0x1b, 0x75, 0x54, 0xf1, 0xe6, 0x90, 0x81, 0xb9, 0x4e, 0x16, 0x73, 0x1c, - 0x6b, 0x64, 0x8f, 0xd2, 0x39, 0x18, 0x47, 0xf6, 0xf2, 0x7a, 0xd8, 0xd8, - 0x57, 0x56, 0xc5, 0xab, 0x43, 0x73, 0x10, 0xdf, 0x69, 0xad, 0x1a, 0x12, - 0x0a, 0x72, 0x8d, 0x59, 0x8c, 0x67, 0x4c, 0xa3, 0x08, 0x03, 0xab, 0xd2, - 0x0a, 0x30, 0xd7, 0xc5, 0xd6, 0x8c, 0x69, 0xbb, 0x78, 0x08, 0xd3, 0x09, - 0x1b, 0x13, 0x65, 0x8d, 0x72, 0xc3, 0xc5, 0x9d, 0x19, 0x0d, 0x72, 0x24, - 0x8b, 0x93, 0x5d, 0x21, 0x4c, 0xf7, 0x71, 0x8c, 0xa8, 0xb4, 0xf7, 0x56, - 0x28, 0xf1, 0x38, 0xf9, 0xe5, 0xb0, 0x0c, 0xc6, 0x79, 0x0c, 0xe2, 0x5f, - 0x32, 0xbc, 0xff, 0x45, 0xe2, 0xd5, 0xdd, 0x51, 0xd4, 0xee, 0xd6, 0xf0, - 0xf4, 0x4e, 0x15, 0x2b, 0xc8, 0xb7, 0x7b, 0x52, 0xaa, 0xb1, 0x4e, 0x38, - 0x18, 0x2f, 0xab, 0x48, 0x0c, 0xb5, 0xc0, 0x88, 0x69, 0xb8, 0x74, 0xc8, - 0xc5, 0x3b, 0x24, 0x77, 0x90, 0xe4, 0xd6, 0x77, 0xe9, 0x98, 0x69, 0xac, - 0xf8, 0xf5, 0xeb, 0xf9, 0x56, 0x77, 0xa7, 0x12, 0x02, 0x42, 0x70, 0x35, - 0x27, 0x83, 0xfb, 0xf3, 0xad, 0xa4, 0xc3, 0xad, 0x58, 0x1a, 0xd2, 0xb0, - 0x7a, 0x98, 0xc7, 0x96, 0x03, 0x93, 0x73, 0xe7, 0xa0, 0x96, 0xf5, 0xe7, - 0x7c, 0x5e, 0x4a, 0xcf, 0x1c, 0x07, 0xbf, 0x9d, 0x60, 0xbb, 0xbb, 0xca, - 0x7f, 0xc8, 0x6c, 0x82, 0xf9, 0x2a, 0x39, 0x72, 0x38, 0x93, 0xc1, 0xc6, - 0x7c, 0x6b, 0xf6, 0x5b, 0x4a, 0x03, 0x10, 0x34, 0x0d, 0x43, 0x81, 0x96, - 0x70, 0x90, 0x1a, 0xa5, 0x78, 0x79, 0xd4, 0x8b, 0x17, 0xa4, 0xba, 0x4a, - 0x9c, 0x97, 0x9a, 0xab, 0x13, 0xff, 0xfc, 0xc5, 0x6d, 0xf8, 0xe8, 0x51, - 0xe6, 0x53, 0xf1, 0x03, 0x7a, 0x7e, 0x7f, 0xef, 0x8e, 0xd9, 0xda, 0xf1, - 0xa7, 0x9e, 0x5f, 0x0d, 0xa5, 0xba, 0xb7, 0x8d, 0x3b, 0xf3, 0xad, 0x67, - 0xb7, 0x29, 0xe4, 0xbf, 0x8b, 0x23, 0xa8, 0xa1, 0xfa, 0x13, 0x24, 0x59, - 0xfb, 0xf2, 0xe7, 0xb1, 0x32, 0x6d, 0x1e, 0xe4, 0x7f, 0x6f, 0x36, 0x66, - 0x55, 0xe4, 0x5f, 0x56, 0xb2, 0xf1, 0x64, 0xd9, 0xc6, 0xed, 0x74, 0x8e, - 0xfb, 0xf0, 0x8f, 0x40, 0xcb, 0x02, 0xe3, 0x94, 0x72, 0x42, 0xba, 0x37, - 0xb3, 0xbc, 0x79, 0x38, 0x15, 0x6f, 0xcd, 0x9d, 0x52, 0xcc, 0xe2, 0x76, - 0x85, 0x6d, 0xa5, 0xe0, 0xcb, 0xe9, 0x0c, 0x8a, 0x31, 0x1d, 0xb7, 0xa6, - 0x35, 0xf7, 0x52, 0x3a, 0xd3, 0x1b, 0x4b, 0x34, 0x34, 0xed, 0xca, 0xe2, - 0xad, 0xf4, 0x9b, 0x28, 0xae, 0x64, 0x3b, 0xf0, 0x3a, 0x3e, 0x73, 0x33, - 0xe2, 0x56, 0x0d, 0xe2, 0x63, 0x41, 0xd4, 0xef, 0xba, 0x20, 0x9b, 0x2d, - 0x1e, 0xb7, 0x06, 0xce, 0x0a, 0x3e, 0x73, 0x10, 0xd1, 0xb1, 0xab, 0xa0, - 0x5a, 0x66, 0x92, 0x1c, 0x9b, 0x60, 0xde, 0x90, 0x55, 0x3d, 0xbb, 0xc0, - 0x75, 0x5f, 0x10, 0x58, 0x97, 0xfa, 0xbe, 0xcc, 0x36, 0xf2, 0x9a, 0x67, - 0x68, 0x9c, 0xcf, 0x50, 0x73, 0x36, 0x8b, 0x26, 0x5a, 0x53, 0xe5, 0x8b, - 0xa0, 0x7f, 0x57, 0xe5, 0x0c, 0x6f, 0x2f, 0xc1, 0xb3, 0x1a, 0x7a, 0xd0, - 0x51, 0x78, 0x08, 0x6f, 0x2d, 0xf6, 0xf6, 0x3f, 0xbd, 0x2f, 0xbd, 0x83, - 0x6c, 0xc2, 0x75, 0xf4, 0xd3, 0x7e, 0xe1, 0xf9, 0xff, 0x64, 0x7f, 0x24, - 0x21, 0x9a, 0x69, 0x8c, 0xe3, 0x77, 0xa7, 0x34, 0x6e, 0xaa, 0xf8, 0x25, - 0x4c, 0xf2, 0xde, 0xcf, 0xf4, 0xa0, 0x75, 0x48, 0x85, 0xcc, 0xb7, 0xda, - 0x3f, 0x0d, 0x3c, 0x22, 0xa7, 0x6f, 0xe3, 0xb9, 0x56, 0xfd, 0x70, 0x40, - 0x60, 0xa9, 0x6a, 0x9e, 0xce, 0xa1, 0x19, 0xfb, 0xa9, 0xc6, 0xb4, 0x38, - 0x3a, 0xd5, 0x9c, 0x04, 0xd5, 0x1e, 0x43, 0x74, 0xec, 0xb1, 0xb1, 0x60, - 0xe8, 0x36, 0x7c, 0x69, 0xb7, 0x83, 0x83, 0x05, 0x1b, 0x4f, 0x17, 0xa4, - 0x3c, 0x69, 0x4b, 0xf9, 0xaf, 0x5d, 0x66, 0xff, 0x31, 0x6a, 0x07, 0x8b, - 0x96, 0x74, 0xe6, 0xea, 0x03, 0x2a, 0xd9, 0xa7, 0xcd, 0xd8, 0x20, 0xcc, - 0xe6, 0x29, 0x61, 0x53, 0xcc, 0xf5, 0x92, 0xed, 0x0d, 0xec, 0x2d, 0x27, - 0xf1, 0x54, 0xd9, 0xa2, 0xcf, 0x42, 0x8a, 0x95, 0x0c, 0xd5, 0x33, 0xd6, - 0x55, 0xc7, 0x78, 0x07, 0xe5, 0x45, 0x41, 0xc1, 0x7e, 0x9b, 0xe2, 0x3f, - 0x46, 0xbc, 0x85, 0x0b, 0xe4, 0x3f, 0x0d, 0xc9, 0x9d, 0x59, 0xd4, 0xa4, - 0x1a, 0x60, 0xdc, 0x68, 0x61, 0xbc, 0xa0, 0xb9, 0x41, 0x8a, 0xf9, 0xb1, - 0xfc, 0x38, 0xfe, 0x40, 0x4f, 0xa0, 0x96, 0xec, 0xb7, 0x2a, 0x1d, 0x01, - 0x6e, 0xe2, 0xb9, 0x08, 0x5a, 0xac, 0xef, 0xa3, 0x25, 0x3e, 0x07, 0xa1, - 0x05, 0x7f, 0x85, 0x69, 0x3d, 0x8a, 0x30, 0xf5, 0x8c, 0xf9, 0xc4, 0x33, - 0x9f, 0x7c, 0xd5, 0x68, 0x59, 0x24, 0x53, 0xc0, 0x6a, 0x23, 0x5e, 0xca, - 0xa7, 0x66, 0xd2, 0x3d, 0xb8, 0x24, 0x81, 0x32, 0x9d, 0x7f, 0x2a, 0x2f, - 0x65, 0x24, 0x63, 0xf6, 0x17, 0x28, 0x37, 0x27, 0x4b, 0x3d, 0x98, 0x2a, - 0xff, 0x1e, 0xd5, 0x73, 0x1b, 0x7b, 0xf3, 0x0e, 0xc6, 0x0a, 0xea, 0xaa, - 0x3c, 0xcc, 0xbe, 0xf5, 0xc8, 0xe0, 0x29, 0x8a, 0x9f, 0x89, 0x82, 0x69, - 0xbc, 0x18, 0xd0, 0x70, 0xcc, 0xae, 0xa3, 0x73, 0x52, 0xde, 0x92, 0x4e, - 0xcf, 0xe7, 0x47, 0x60, 0x35, 0xb0, 0xfd, 0xd9, 0x4f, 0x19, 0x7c, 0xbb, - 0xe0, 0xc5, 0xf7, 0x75, 0x1a, 0x5c, 0xd8, 0xdd, 0xec, 0x1b, 0xf7, 0x74, - 0x30, 0x5d, 0xa9, 0xa3, 0x7d, 0xdd, 0x36, 0xc2, 0xc3, 0x3d, 0x24, 0xb7, - 0xd5, 0x3e, 0x81, 0x3b, 0x30, 0xdd, 0xec, 0x62, 0x11, 0xc5, 0xbf, 0xea, - 0x3c, 0x9e, 0xda, 0x9c, 0x77, 0x65, 0xbd, 0x65, 0xf5, 0xff, 0x50, 0x3c, - 0x88, 0x57, 0x53, 0x5c, 0xd7, 0x55, 0xca, 0x7b, 0x1d, 0x3b, 0xec, 0x11, - 0xbc, 0x56, 0xfa, 0x2d, 0xe4, 0x62, 0x66, 0x72, 0x93, 0x58, 0x8f, 0x83, - 0x23, 0x57, 0x01, 0xb7, 0x70, 0x9e, 0x90, 0x6e, 0xd6, 0x7a, 0x1c, 0x2a, - 0x7e, 0x03, 0x47, 0x47, 0x6b, 0xf1, 0xbc, 0x15, 0x47, 0xcb, 0x44, 0x65, - 0x9f, 0xab, 0xbb, 0x35, 0x8c, 0x51, 0x4e, 0x5f, 0x6b, 0xab, 0x98, 0x49, - 0x70, 0xfd, 0xa0, 0x58, 0x4b, 0x6f, 0xa0, 0x5a, 0xe3, 0xb5, 0x5e, 0xac, - 0xc9, 0x18, 0xc8, 0xe7, 0xb3, 0x54, 0xff, 0x6a, 0xb0, 0x2b, 0x06, 0x71, - 0x3b, 0xf5, 0xb0, 0xbb, 0xf3, 0xad, 0xfd, 0xc3, 0x4a, 0x1c, 0xc5, 0x96, - 0x2c, 0xf9, 0x42, 0xa0, 0xc9, 0x32, 0xb0, 0xa5, 0x44, 0x15, 0xb4, 0xa4, - 0xe2, 0x9b, 0xa5, 0x2b, 0x50, 0x6c, 0xe2, 0xb5, 0x1d, 0x98, 0xf6, 0xbe, - 0x83, 0x98, 0x89, 0x9b, 0xcd, 0x20, 0x9b, 0x8d, 0x17, 0x54, 0xec, 0xb6, - 0xf7, 0x5c, 0x28, 0xae, 0x34, 0xf5, 0x1c, 0xe5, 0x5b, 0xc0, 0x8b, 0x5b, - 0x7e, 0x06, 0xbe, 0x96, 0xff, 0x50, 0x9e, 0xf1, 0xf6, 0x54, 0x39, 0xff, - 0xa7, 0xdf, 0x0e, 0xbc, 0x2f, 0x45, 0x98, 0xe5, 0xdf, 0x1f, 0xad, 0xfc, - 0x5b, 0xd1, 0x67, 0x99, 0x37, 0x0b, 0x70, 0x1c, 0xcc, 0xfd, 0x44, 0xcc, - 0x57, 0xea, 0x80, 0xbe, 0x98, 0xcf, 0x51, 0xcd, 0xb3, 0x38, 0x9a, 0x26, - 0xda, 0x50, 0xb3, 0x8b, 0x7f, 0xf3, 0xb8, 0xc0, 0x65, 0xdd, 0x9c, 0x63, - 0x6d, 0x50, 0xc6, 0x56, 0x47, 0x2b, 0x35, 0xb8, 0x5a, 0x1f, 0xfe, 0x70, - 0x56, 0xbe, 0xd7, 0xeb, 0xe9, 0x77, 0xa5, 0x86, 0x7e, 0x33, 0xc3, 0xcf, - 0xbc, 0xa6, 0x06, 0x6f, 0xed, 0x35, 0xed, 0xa2, 0xb2, 0x84, 0xf7, 0xac, - 0xe4, 0x08, 0x36, 0xce, 0xae, 0xa1, 0x98, 0x2f, 0x4c, 0x49, 0xdc, 0xca, - 0xf2, 0xaa, 0xeb, 0xdb, 0x10, 0xfa, 0xe5, 0xbe, 0x2a, 0x5e, 0xcc, 0x7c, - 0x7a, 0xdf, 0xdb, 0x64, 0xed, 0xca, 0x38, 0xc5, 0x59, 0x23, 0xd4, 0x05, - 0xd4, 0xe0, 0xf5, 0x26, 0xd4, 0x51, 0xde, 0x06, 0xac, 0x5b, 0x64, 0xe0, - 0x2b, 0x1c, 0xa7, 0x9a, 0x1b, 0x71, 0x2e, 0xc6, 0xf0, 0xce, 0x17, 0xc8, - 0xc7, 0x51, 0x8e, 0x47, 0xf2, 0xf3, 0xc5, 0x18, 0x7a, 0xe2, 0x92, 0x28, - 0xeb, 0xbb, 0x2a, 0x0d, 0x77, 0x3e, 0xd5, 0xec, 0xf7, 0xf6, 0xdc, 0x2d, - 0x8b, 0x7d, 0x3a, 0x5e, 0xca, 0xfc, 0x0e, 0x8d, 0x73, 0x3c, 0xd9, 0x78, - 0x2e, 0xaf, 0xe1, 0xfe, 0xe1, 0x66, 0x3a, 0x27, 0xd7, 0xca, 0x9a, 0xb3, - 0x33, 0x8a, 0x8d, 0x67, 0x29, 0x16, 0x9f, 0x29, 0xb0, 0xad, 0x54, 0x5c, - 0x96, 0x5e, 0x21, 0xc3, 0x4d, 0x1c, 0xdf, 0x49, 0x5a, 0xa3, 0x93, 0xec, - 0x28, 0x74, 0x6b, 0x99, 0x3c, 0xb0, 0x92, 0x9f, 0x3b, 0x68, 0xac, 0x89, - 0xbe, 0xbb, 0x65, 0xdd, 0xaf, 0x9d, 0x43, 0xff, 0xac, 0x73, 0x50, 0xdc, - 0x9b, 0xf6, 0x5a, 0x74, 0x12, 0x0e, 0x52, 0x91, 0xa5, 0x3e, 0x3f, 0x41, - 0x31, 0xb0, 0x8d, 0x7a, 0xf0, 0x7b, 0x84, 0xf5, 0xb6, 0x78, 0x78, 0xca, - 0x83, 0x67, 0x1e, 0x5e, 0x5b, 0x5d, 0xc1, 0x5d, 0x9a, 0x6a, 0x31, 0x16, - 0xab, 0xce, 0x71, 0x9e, 0xf6, 0x62, 0x6c, 0x54, 0xca, 0xcd, 0x76, 0x0b, - 0xc9, 0x88, 0x63, 0xb3, 0x45, 0x39, 0x3d, 0xca, 0x6b, 0xa4, 0x4c, 0xa6, - 0x16, 0xf4, 0xa8, 0xa2, 0x01, 0x33, 0xba, 0x2b, 0xd6, 0x66, 0x0c, 0xf1, - 0xd5, 0x51, 0x15, 0xf9, 0xc2, 0x45, 0x64, 0x2f, 0x29, 0x9f, 0x4a, 0x21, - 0xbb, 0x29, 0x55, 0x87, 0x57, 0x8a, 0x3a, 0x72, 0xfa, 0x05, 0xb9, 0xbc, - 0xad, 0x17, 0x65, 0x92, 0xf3, 0x41, 0xaa, 0x33, 0x79, 0x44, 0x44, 0x50, - 0x4c, 0x44, 0xf0, 0x78, 0x21, 0x81, 0x23, 0xe3, 0x11, 0x6c, 0xa5, 0x18, - 0x7d, 0x31, 0xc3, 0x7b, 0x46, 0xf0, 0x70, 0x99, 0x31, 0x55, 0x80, 0x6c, - 0xe4, 0x8a, 0x13, 0xde, 0x58, 0x1d, 0x96, 0x17, 0x99, 0xf7, 0x82, 0x6c, - 0xb1, 0x2c, 0xbd, 0x25, 0x50, 0xe5, 0x3b, 0x4e, 0xf8, 0xca, 0xa0, 0x5a, - 0x36, 0x8f, 0x70, 0x55, 0x33, 0x61, 0xa8, 0x04, 0x61, 0x28, 0x6b, 0x16, - 0x17, 0x9a, 0x94, 0x8d, 0x52, 0x3e, 0x4b, 0xb5, 0xec, 0xc7, 0xf4, 0x39, - 0x43, 0xf5, 0x34, 0x46, 0x3a, 0x5e, 0x36, 0xcc, 0x3a, 0xba, 0xc2, 0xa6, - 0x7a, 0x9b, 0x55, 0x94, 0x7a, 0xee, 0x43, 0x81, 0x29, 0xde, 0x5f, 0xc5, - 0x96, 0x02, 0xb0, 0xa9, 0x00, 0xf7, 0x08, 0xe5, 0x7e, 0xc3, 0x44, 0x14, - 0xf1, 0x09, 0x1d, 0xc1, 0x89, 0x24, 0xcd, 0x6b, 0x48, 0xd0, 0x6f, 0x97, - 0xb0, 0x60, 0xbd, 0xd3, 0x24, 0x16, 0x3e, 0x76, 0x5e, 0xee, 0x48, 0xa9, - 0x58, 0xd7, 0x66, 0xf6, 0xde, 0x28, 0x90, 0x4d, 0x0e, 0x49, 0x19, 0x4e, - 0x85, 0x29, 0x37, 0xe5, 0xa1, 0x04, 0xe9, 0x1d, 0x75, 0xe4, 0x83, 0xaf, - 0x75, 0x5b, 0xf6, 0x6b, 0x20, 0xb9, 0x65, 0x5e, 0xc3, 0xe3, 0xae, 0xf8, - 0xb0, 0xdb, 0x7a, 0xfc, 0x4d, 0xb4, 0xa3, 0x6b, 0x42, 0x15, 0xff, 0x36, - 0xb4, 0x10, 0xe9, 0x29, 0xe8, 0x21, 0xe7, 0x80, 0x98, 0x79, 0xe2, 0xa0, - 0x38, 0x39, 0x49, 0xe7, 0x2e, 0x90, 0x2e, 0x05, 0xd2, 0xa5, 0x40, 0xba, - 0x90, 0x5d, 0x9e, 0xf1, 0xf0, 0x24, 0xeb, 0x9a, 0x24, 0x2c, 0x73, 0xdc, - 0xc3, 0xbc, 0x8c, 0x11, 0x63, 0x8e, 0x99, 0x75, 0xc1, 0x7a, 0xb3, 0x9e, - 0x52, 0xbe, 0x69, 0x57, 0xf4, 0x71, 0xa9, 0xdc, 0x6a, 0x53, 0x55, 0x5b, - 0x48, 0xf9, 0xef, 0x36, 0xdb, 0x82, 0x75, 0x94, 0xf2, 0x3b, 0xa4, 0xd3, - 0x16, 0xd2, 0x71, 0x53, 0x41, 0x1e, 0x0a, 0x59, 0x96, 0x31, 0x41, 0x67, - 0x8b, 0x93, 0x4e, 0x89, 0x09, 0x8d, 0x74, 0x6d, 0x87, 0x4a, 0xba, 0x06, - 0x26, 0xa0, 0x2b, 0x74, 0x1e, 0x63, 0x8c, 0xec, 0x34, 0xf5, 0x79, 0xe7, - 0x61, 0xcc, 0xef, 0x8a, 0xab, 0x09, 0x9f, 0xa8, 0x64, 0xd7, 0x4d, 0x14, - 0x3b, 0x39, 0x15, 0x46, 0xd8, 0x52, 0xa8, 0x27, 0x6a, 0xf8, 0xf6, 0x78, - 0x1d, 0x26, 0xc8, 0xef, 0xc5, 0x71, 0xe8, 0x41, 0x92, 0xe9, 0x16, 0x0f, - 0x8a, 0x4f, 0xc6, 0x5b, 0xd0, 0x19, 0x20, 0x9c, 0x04, 0x3c, 0x92, 0x8f, - 0x8b, 0x89, 0x11, 0x15, 0x9b, 0x0b, 0xa7, 0x49, 0x3f, 0x89, 0xc3, 0xf6, - 0xc3, 0xcd, 0xc4, 0x22, 0x1e, 0xb6, 0xcd, 0x1e, 0xe0, 0x2a, 0x8a, 0xb7, - 0x00, 0xd6, 0x5a, 0xc8, 0x6e, 0xb3, 0xaf, 0xc2, 0x4c, 0x1f, 0x8c, 0xed, - 0xb6, 0xab, 0x87, 0x60, 0x1e, 0xbb, 0x9a, 0x7a, 0xd3, 0x95, 0xa4, 0xcf, - 0xa0, 0xe5, 0x0e, 0x50, 0xe1, 0x42, 0xb9, 0x6c, 0xf6, 0x1f, 0x25, 0x5f, - 0x94, 0xa8, 0xff, 0x95, 0xca, 0x4d, 0xe2, 0xe9, 0xd1, 0xf3, 0xf2, 0xae, - 0x94, 0x99, 0x6d, 0xa3, 0xb1, 0xe0, 0x90, 0x46, 0x38, 0x4d, 0xa3, 0x9c, - 0x32, 0x6d, 0x80, 0x6b, 0x03, 0xb4, 0x30, 0xd5, 0xe2, 0x9f, 0x59, 0x47, - 0x08, 0xa7, 0x6b, 0x20, 0x0c, 0x8f, 0xa5, 0x23, 0x02, 0xfb, 0x28, 0xc7, - 0x27, 0x17, 0x9a, 0xc7, 0x56, 0xc3, 0x9d, 0x6e, 0x81, 0x39, 0x18, 0x0e, - 0x9c, 0xc6, 0x07, 0x43, 0x21, 0xc2, 0x0d, 0xed, 0xf6, 0xeb, 0x30, 0xf5, - 0x7d, 0x81, 0x5f, 0xc8, 0xfd, 0x09, 0x5c, 0x14, 0xc4, 0x19, 0x69, 0xfc, - 0x3e, 0xaf, 0x61, 0xdd, 0x07, 0xb0, 0x2d, 0xc3, 0x38, 0x45, 0x25, 0x9c, - 0x02, 0xbc, 0x93, 0x37, 0xb0, 0x7f, 0x61, 0x0d, 0xf5, 0x93, 0xd6, 0x9e, - 0x75, 0x70, 0x57, 0xd1, 0xf5, 0x47, 0x8b, 0xd0, 0x5e, 0x79, 0x8a, 0x95, - 0x0d, 0x42, 0xe0, 0x29, 0xeb, 0xac, 0xdd, 0x31, 0xc9, 0x18, 0x46, 0x4d, - 0x2d, 0xa0, 0x5c, 0xdc, 0x5a, 0x16, 0xd4, 0xdb, 0x4c, 0x7d, 0x06, 0x6c, - 0x1b, 0x9d, 0xec, 0x7a, 0x5e, 0x22, 0xc6, 0xba, 0xbb, 0x39, 0xd2, 0x73, - 0xd5, 0x16, 0x3a, 0xff, 0x1a, 0xd2, 0xe9, 0x2e, 0xcb, 0xed, 0x21, 0xa9, - 0xd4, 0xa3, 0xcc, 0xe6, 0xf7, 0x48, 0xf7, 0xb5, 0x54, 0x47, 0x8a, 0xe5, - 0xe7, 0xea, 0xb9, 0x66, 0x4c, 0x94, 0xf9, 0x1e, 0xd7, 0x83, 0xa5, 0xf9, - 0x6a, 0x3e, 0xb0, 0xff, 0xd9, 0xf7, 0x1c, 0x0b, 0x1c, 0x33, 0x1c, 0x27, - 0x8c, 0xd1, 0x7a, 0x30, 0xda, 0xae, 0x20, 0x9b, 0x90, 0x72, 0xa5, 0x65, - 0x8e, 0x70, 0x1d, 0xa7, 0x98, 0xcf, 0xee, 0xb5, 0xeb, 0x29, 0x3f, 0xe1, - 0x3e, 0x69, 0x1b, 0x08, 0x39, 0x1c, 0x1b, 0x75, 0x14, 0xeb, 0x11, 0x6c, - 0xa3, 0x58, 0xd1, 0x2c, 0x2b, 0x49, 0x97, 0x0d, 0xfd, 0x9d, 0x0c, 0xf1, - 0x96, 0x61, 0x94, 0xed, 0x5a, 0xc2, 0x95, 0x2a, 0x62, 0xce, 0x21, 0xd9, - 0x60, 0x35, 0xea, 0xd4, 0xb8, 0xf5, 0x7b, 0xb1, 0x9a, 0xee, 0x17, 0x06, - 0xea, 0x1c, 0x9e, 0x3f, 0x27, 0x67, 0x62, 0x11, 0x8a, 0x33, 0xe6, 0xb1, - 0xdc, 0x67, 0xf0, 0x91, 0x44, 0x9c, 0x79, 0xb3, 0x58, 0x9d, 0x81, 0x38, - 0x48, 0x7b, 0xa1, 0x81, 0x73, 0xd7, 0xc0, 0x7c, 0xc7, 0x3a, 0x76, 0x88, - 0x7a, 0x8f, 0xd1, 0x00, 0xaa, 0xb9, 0x2a, 0x02, 0x8e, 0xa5, 0xef, 0xc5, - 0x51, 0xaf, 0x4e, 0x11, 0x52, 0x17, 0x2b, 0x76, 0xcf, 0x13, 0xbd, 0x84, - 0xcd, 0xdb, 0x53, 0x70, 0x34, 0xb4, 0x19, 0x7f, 0x43, 0xa3, 0x9b, 0x29, - 0xfe, 0xe7, 0x38, 0x11, 0x51, 0xda, 0x0d, 0xfd, 0x69, 0x5b, 0xa3, 0x3e, - 0x2a, 0xe5, 0xd6, 0x94, 0x81, 0x29, 0x9b, 0x70, 0x74, 0x63, 0x10, 0x31, - 0x0b, 0xba, 0xee, 0x58, 0x83, 0x07, 0x30, 0xc0, 0xf8, 0x37, 0x3a, 0x9f, - 0x7a, 0x25, 0x8d, 0x89, 0x31, 0xbb, 0x06, 0xd9, 0x9b, 0x05, 0x22, 0x4e, - 0x82, 0xce, 0x16, 0x42, 0xce, 0x7b, 0x66, 0x1d, 0x91, 0x7d, 0xd7, 0xde, - 0x43, 0xfa, 0x8a, 0xf9, 0xb5, 0x0e, 0x8f, 0x59, 0x76, 0x09, 0x77, 0x11, - 0x56, 0xa7, 0x21, 0x9a, 0xdf, 0x4c, 0xf3, 0x8f, 0x92, 0xec, 0x5c, 0xdc, - 0xbb, 0x87, 0xd6, 0xb7, 0x38, 0xd6, 0xf4, 0xf3, 0xd8, 0x4e, 0x3a, 0x70, - 0x8d, 0xe7, 0x31, 0x3e, 0xf3, 0x42, 0x3e, 0x33, 0xf5, 0x78, 0x8e, 0x2b, - 0x1b, 0x3f, 0xcb, 0xd3, 0xde, 0x09, 0x64, 0xb7, 0xdb, 0x10, 0x13, 0xf6, - 0x6e, 0xc2, 0x2f, 0xa8, 0x8f, 0x3a, 0x56, 0xff, 0x14, 0xa0, 0x44, 0x9c, - 0x9d, 0x28, 0xc5, 0x80, 0x47, 0x0b, 0x96, 0x7b, 0x8f, 0x62, 0x0e, 0x26, - 0x08, 0x13, 0x9f, 0x21, 0x4c, 0xbf, 0xab, 0x7d, 0xda, 0x8c, 0x83, 0xb1, - 0x7e, 0x54, 0xbc, 0xb4, 0x5b, 0x41, 0xc7, 0x62, 0xea, 0x4b, 0x54, 0x4b, - 0xae, 0xb1, 0xf9, 0xbe, 0x7c, 0x79, 0x7d, 0x05, 0x2f, 0xff, 0x6f, 0x39, - 0x69, 0x92, 0xc5, 0xaa, 0x79, 0x69, 0xf5, 0x3d, 0x8d, 0x3f, 0x93, 0xd9, - 0x18, 0xfb, 0x22, 0x42, 0xb5, 0xf8, 0x97, 0xf5, 0x28, 0x39, 0x49, 0xf2, - 0x37, 0x75, 0x07, 0x75, 0x8e, 0x19, 0xf2, 0x65, 0xf6, 0x8d, 0x3c, 0x44, - 0x7d, 0x9a, 0xf2, 0x2a, 0xc6, 0x7e, 0xe1, 0xfb, 0x3d, 0x19, 0x6f, 0x38, - 0x41, 0xba, 0xa9, 0xe8, 0x4a, 0xa3, 0x5e, 0x71, 0xac, 0xb3, 0x63, 0x74, - 0xe6, 0x16, 0xa7, 0x1e, 0xe7, 0x1a, 0xb8, 0x36, 0x46, 0xc5, 0x0f, 0x46, - 0xcd, 0x1e, 0xc2, 0xc3, 0xab, 0xee, 0x21, 0x1c, 0x75, 0x9f, 0x50, 0xd1, - 0x4b, 0x67, 0xb7, 0xda, 0xc8, 0x07, 0x84, 0x4d, 0x12, 0x6d, 0xd3, 0x66, - 0x02, 0xd5, 0xf3, 0x5e, 0x90, 0x71, 0xcb, 0x72, 0xe3, 0xca, 0xc7, 0x32, - 0x95, 0xe6, 0x18, 0xdf, 0x80, 0x70, 0x5c, 0x20, 0x94, 0x1e, 0xf2, 0x6c, - 0x4b, 0x77, 0x2a, 0xd4, 0xa7, 0x1f, 0x62, 0x1f, 0x11, 0x7e, 0x7b, 0x59, - 0xe6, 0xbe, 0xc2, 0xba, 0x6d, 0x9f, 0xd5, 0x73, 0x2d, 0xc7, 0x15, 0xfd, - 0x96, 0x73, 0xd8, 0xde, 0x87, 0xa8, 0x8e, 0x77, 0x2d, 0xe9, 0xdc, 0x3e, - 0xa8, 0x0c, 0x49, 0x63, 0x25, 0xfb, 0x93, 0x2e, 0x37, 0xb5, 0x9e, 0xaf, - 0xb5, 0xa8, 0x73, 0x1c, 0xaf, 0x0f, 0x45, 0x45, 0xfd, 0x63, 0xae, 0xd7, - 0x53, 0x5f, 0xa3, 0xb3, 0x9c, 0x4c, 0xf1, 0x19, 0x38, 0xc7, 0x8e, 0xe3, - 0x8a, 0xd2, 0xed, 0xc4, 0x1b, 0xa0, 0xfd, 0xa1, 0x51, 0xbc, 0x41, 0x52, - 0x9f, 0x39, 0xd7, 0x35, 0x25, 0x8d, 0x06, 0x96, 0x4f, 0xb6, 0x1e, 0x65, - 0x5b, 0xf3, 0xdd, 0xb2, 0x6a, 0x6f, 0xe6, 0xe7, 0xf5, 0x74, 0xe9, 0x8e, - 0xb1, 0xff, 0x50, 0x5f, 0xe7, 0xb0, 0x4d, 0x21, 0x6a, 0x9c, 0x4e, 0x63, - 0x81, 0xd8, 0x21, 0xdd, 0x44, 0xb5, 0x86, 0x45, 0xc5, 0x84, 0xb7, 0x9e, - 0xf7, 0xfe, 0xf4, 0xfa, 0x26, 0xf1, 0xce, 0x9e, 0xdf, 0xa5, 0x67, 0x2f, - 0x46, 0x7a, 0x9f, 0xa2, 0x1c, 0xd2, 0x9c, 0x7e, 0x99, 0x6c, 0xe4, 0x18, - 0x83, 0xf2, 0x8a, 0xbd, 0x56, 0xe6, 0x1a, 0x39, 0xd6, 0xe0, 0x26, 0x48, - 0xce, 0xae, 0xc7, 0x7e, 0x75, 0x8e, 0xab, 0xdb, 0xa5, 0x9c, 0xb0, 0xd7, - 0x90, 0x2d, 0x58, 0x4e, 0xd5, 0x16, 0x7b, 0x66, 0x6d, 0xd3, 0x5e, 0xf1, - 0x5f, 0xc1, 0x3b, 0x83, 0x16, 0x72, 0xde, 0xc0, 0x4b, 0x79, 0xa5, 0x89, - 0x6e, 0x2b, 0xe8, 0xb3, 0x05, 0x7e, 0xda, 0x43, 0xfa, 0x5d, 0x49, 0x58, - 0x65, 0x91, 0x35, 0xdd, 0x1a, 0x58, 0x2f, 0x31, 0x77, 0x9a, 0x82, 0xe3, - 0xbc, 0xd4, 0xda, 0x55, 0x84, 0xaf, 0xe0, 0x1e, 0xc5, 0xb6, 0x57, 0xf0, - 0x32, 0xf1, 0xad, 0xb8, 0xc2, 0x32, 0x5a, 0x05, 0xf5, 0xb5, 0xbe, 0xa5, - 0xe9, 0xe0, 0x2f, 0x63, 0x8f, 0xcf, 0x90, 0xf3, 0x74, 0xe0, 0x18, 0xec, - 0x22, 0xdf, 0xe5, 0x56, 0x2a, 0x48, 0x2d, 0x06, 0x61, 0x8d, 0xa8, 0xd8, - 0xba, 0x9b, 0xfd, 0xff, 0x3d, 0x9a, 0x67, 0xbe, 0xce, 0x66, 0x1d, 0xd6, - 0xaa, 0xc3, 0x74, 0xb1, 0x24, 0x2c, 0x4a, 0xf6, 0xe0, 0xbd, 0xaa, 0x72, - 0xaa, 0x32, 0xa2, 0x62, 0x72, 0x94, 0x79, 0x59, 0x17, 0xaa, 0xcd, 0x1c, - 0x2b, 0x29, 0x8e, 0x8f, 0x8f, 0x65, 0x47, 0x3a, 0x1a, 0x43, 0x2d, 0xaf, - 0x89, 0x0a, 0x7d, 0x0f, 0xcb, 0x85, 0x60, 0x3b, 0xc6, 0x48, 0xff, 0xf6, - 0xf4, 0xe5, 0xb3, 0xfa, 0xff, 0xb1, 0x5e, 0xc1, 0x71, 0x51, 0x71, 0xd4, - 0xdb, 0xbb, 0x62, 0xa3, 0x49, 0xb2, 0xf5, 0x44, 0xaa, 0xca, 0xf3, 0x38, - 0xf1, 0x70, 0x9c, 0x7d, 0x66, 0x4f, 0x22, 0xea, 0x15, 0x8f, 0xe4, 0xe9, - 0x92, 0x6a, 0x29, 0xd7, 0xd7, 0x52, 0x9e, 0x3c, 0x49, 0xbd, 0x69, 0x7f, - 0xb1, 0x57, 0x6c, 0xcb, 0xeb, 0xd4, 0xa7, 0x96, 0x8b, 0xad, 0x79, 0x8b, - 0x71, 0xd1, 0x6c, 0x9f, 0xaa, 0xbc, 0x8b, 0xda, 0x52, 0xfa, 0xe4, 0x3b, - 0xa2, 0x48, 0x4e, 0x77, 0xd0, 0x37, 0x7f, 0xf8, 0x41, 0xa9, 0x58, 0xfc, - 0x3e, 0xc8, 0x3a, 0x76, 0x22, 0x10, 0xe9, 0xe9, 0x59, 0x12, 0x40, 0xbd, - 0x85, 0xbe, 0x66, 0xc2, 0x07, 0x57, 0x7a, 0x35, 0xdd, 0x80, 0x51, 0x6a, - 0x6f, 0xac, 0xf8, 0x89, 0xf3, 0x0e, 0x6a, 0xad, 0x83, 0x5c, 0x0d, 0xd5, - 0x91, 0x6b, 0xba, 0x43, 0xda, 0xd1, 0xee, 0xde, 0x96, 0xf6, 0xc9, 0xa6, - 0x5c, 0xad, 0x73, 0x7d, 0x4b, 0xdb, 0xa4, 0xdb, 0xb2, 0x70, 0x08, 0xf8, - 0xf2, 0x90, 0x0e, 0xcd, 0xb9, 0xd1, 0x0d, 0x74, 0x23, 0xa7, 0x52, 0x5c, - 0xec, 0xe8, 0xb6, 0x7a, 0xa6, 0xc4, 0x4d, 0x37, 0x91, 0x1e, 0x2d, 0x9d, - 0x93, 0x86, 0xb1, 0x39, 0xf3, 0xc0, 0x4d, 0x81, 0x29, 0xee, 0x2f, 0x1b, - 0x06, 0xf7, 0xf1, 0x7b, 0x33, 0xba, 0x9b, 0x9e, 0xd0, 0xf1, 0xc0, 0xb2, - 0xee, 0x41, 0x0c, 0xe4, 0x1f, 0x40, 0x7f, 0x9e, 0xdf, 0x3b, 0x69, 0x18, - 0xe1, 0x1a, 0x5f, 0xe0, 0x77, 0x4e, 0x0f, 0x35, 0x30, 0x6e, 0xdc, 0x5e, - 0x56, 0x71, 0xed, 0x10, 0xcf, 0x99, 0xcd, 0xef, 0xa3, 0xca, 0xfb, 0x59, - 0x7c, 0x9f, 0xd4, 0x93, 0x6b, 0x1e, 0xb2, 0x81, 0x61, 0x29, 0x95, 0x0c, - 0xdf, 0x63, 0x4e, 0x13, 0xd6, 0xe3, 0xbd, 0x7f, 0x4e, 0xbd, 0x71, 0x2e, - 0xbf, 0x0b, 0x63, 0xca, 0x86, 0x87, 0x79, 0xee, 0xd4, 0xec, 0xdc, 0xbb, - 0x34, 0x07, 0x71, 0x92, 0xea, 0xfa, 0x74, 0x25, 0x2f, 0xb2, 0xb5, 0xc3, - 0x1a, 0xfe, 0xa8, 0xc0, 0x3c, 0x33, 0xb3, 0x3c, 0x3f, 0x21, 0x9e, 0x04, - 0x56, 0xc4, 0xb8, 0x76, 0x53, 0xce, 0xec, 0xae, 0xbe, 0x2b, 0x93, 0xf2, - 0x25, 0xfb, 0xc3, 0x68, 0xe5, 0x5d, 0x59, 0x54, 0x68, 0x8f, 0xd1, 0x33, - 0x61, 0x95, 0x50, 0x2a, 0x2a, 0x42, 0x8f, 0xf1, 0xfa, 0x57, 0x53, 0x95, - 0xf5, 0xc7, 0x52, 0xbc, 0xfe, 0xd7, 0xd7, 0xa8, 0xd9, 0xc8, 0x30, 0xdd, - 0xa9, 0x0a, 0xff, 0x24, 0x77, 0x34, 0x56, 0x64, 0x57, 0xd6, 0x7d, 0x6f, - 0x76, 0xdd, 0x41, 0x5a, 0xb7, 0x8f, 0x62, 0x8c, 0xd7, 0xb2, 0x9e, 0x1c, - 0xa3, 0xd5, 0xf7, 0x86, 0x49, 0x71, 0x80, 0x7a, 0xf5, 0x81, 0x92, 0x2a, - 0xf6, 0x52, 0x1d, 0x1c, 0xcf, 0x13, 0x36, 0xf2, 0xde, 0x05, 0x52, 0xcd, - 0x2f, 0x7f, 0x23, 0x56, 0xf1, 0x21, 0xf7, 0xd5, 0x69, 0xea, 0xab, 0xed, - 0x54, 0xdf, 0x55, 0x4f, 0xa7, 0xb0, 0x73, 0x84, 0xea, 0xbb, 0xc0, 0x49, - 0xaf, 0xbe, 0x1c, 0x41, 0x7b, 0x89, 0xfb, 0x80, 0x25, 0xce, 0x15, 0x8c, - 0x5c, 0x33, 0xc9, 0x6e, 0x29, 0x57, 0x6a, 0x03, 0xf5, 0x82, 0x2c, 0xf5, - 0x64, 0xf1, 0x62, 0x89, 0x7f, 0x52, 0xf1, 0x8c, 0xf3, 0x19, 0xb2, 0x62, - 0x4e, 0xbb, 0x8b, 0xfa, 0x76, 0x97, 0x71, 0xec, 0xc0, 0xf3, 0xc2, 0x9a, - 0x3e, 0x27, 0xb2, 0xb7, 0x36, 0xe3, 0x41, 0xfc, 0x3c, 0x95, 0x5d, 0x11, - 0xa5, 0x6f, 0xc2, 0xcc, 0x86, 0xc6, 0xef, 0x48, 0xbb, 0xdb, 0x7a, 0x36, - 0x88, 0x36, 0xaa, 0x37, 0x6d, 0xee, 0x16, 0xb4, 0x51, 0xcf, 0xb7, 0xb5, - 0xc3, 0x25, 0x5b, 0x7b, 0xa3, 0x54, 0xb5, 0x03, 0xc7, 0x29, 0xdb, 0x80, - 0x42, 0xdf, 0xb1, 0xb2, 0x0b, 0x04, 0xf5, 0x55, 0xea, 0xbb, 0xc3, 0xd4, - 0xb3, 0x2b, 0xf7, 0xce, 0x30, 0xe1, 0x16, 0xde, 0x7b, 0xdd, 0xec, 0xbb, - 0x96, 0x7f, 0x90, 0x95, 0x1e, 0xf5, 0x0a, 0xd9, 0x83, 0xcf, 0xfc, 0xa3, - 0x48, 0x65, 0xfc, 0x4c, 0x6c, 0xf6, 0xff, 0xf9, 0x21, 0x9c, 0x42, 0xf7, - 0xc8, 0x21, 0x81, 0x1d, 0x6d, 0x95, 0x58, 0xee, 0xe4, 0xf7, 0x98, 0xde, - 0x7b, 0xb7, 0x2a, 0x4f, 0xc5, 0x86, 0x0a, 0xe1, 0x99, 0x43, 0xe5, 0xac, - 0xb8, 0x26, 0x8f, 0x01, 0xea, 0x89, 0xd9, 0x20, 0xf1, 0x5e, 0x53, 0xea, - 0x15, 0xcb, 0xf3, 0x96, 0xb1, 0x89, 0x74, 0xdd, 0xa2, 0x77, 0xea, 0xe3, - 0x84, 0x21, 0x68, 0x3f, 0x23, 0x4c, 0xf1, 0xaf, 0x39, 0x73, 0xb1, 0x7d, - 0x36, 0x76, 0x28, 0x1f, 0x28, 0x7f, 0x06, 0xc5, 0x82, 0x49, 0xfe, 0xa9, - 0x7b, 0xb1, 0x5b, 0xd1, 0xe3, 0x9c, 0xdc, 0x76, 0x33, 0xcf, 0x5f, 0x31, - 0x6b, 0xfb, 0xa6, 0x38, 0xed, 0x49, 0xbf, 0x47, 0x66, 0xcf, 0xff, 0x7f, - 0xad, 0xbd, 0xf6, 0x92, 0xff, 0xb9, 0x66, 0x86, 0xce, 0xc9, 0x18, 0x08, - 0x6e, 0xdc, 0x61, 0xfc, 0x33, 0x6f, 0xd6, 0xe7, 0xd4, 0x15, 0xa3, 0x03, - 0xb8, 0x71, 0x31, 0xdd, 0x7c, 0xe9, 0x0e, 0xb6, 0x8d, 0x7c, 0x95, 0x1c, - 0x66, 0xbd, 0xcf, 0x93, 0xde, 0xd0, 0x6a, 0x9c, 0xb3, 0xb8, 0x7c, 0xa8, - 0xb5, 0x3f, 0x2c, 0xcc, 0xe4, 0x90, 0x30, 0xfb, 0xa8, 0xbe, 0xd9, 0x93, - 0x30, 0x9b, 0x17, 0x08, 0xd3, 0x58, 0x0b, 0xb6, 0xc9, 0x79, 0xb4, 0x95, - 0xf8, 0xfb, 0x2c, 0x2c, 0xf2, 0x6b, 0xdf, 0x70, 0x00, 0x4a, 0xfa, 0x03, - 0xb2, 0x2b, 0xe1, 0x35, 0xd1, 0x4c, 0xb9, 0xc4, 0xb1, 0x77, 0x1e, 0x9b, - 0xf3, 0xd0, 0x5a, 0x88, 0xe7, 0x2a, 0xaa, 0xd1, 0xad, 0xc3, 0xe6, 0x59, - 0xc2, 0x9c, 0x83, 0x5f, 0x0a, 0xb4, 0x26, 0xfb, 0x61, 0x0e, 0x6c, 0x41, - 0xe7, 0xf4, 0x51, 0x61, 0x66, 0xcf, 0x12, 0x16, 0x0c, 0xa7, 0x2b, 0x32, - 0x17, 0xcd, 0xca, 0x4c, 0x32, 0x3e, 0xf6, 0x72, 0x88, 0x30, 0x74, 0xfa, - 0x6f, 0xe5, 0xb4, 0x67, 0xb3, 0xe0, 0xac, 0xfe, 0x4b, 0xe2, 0x15, 0x1f, - 0x3c, 0x37, 0x6b, 0x1f, 0x42, 0x24, 0xb5, 0xcc, 0xc7, 0xf7, 0x30, 0x88, - 0x35, 0xf9, 0x2f, 0xe2, 0x61, 0xc2, 0x43, 0x59, 0x6f, 0x7d, 0x2f, 0x72, - 0x25, 0x88, 0xb5, 0xf9, 0xe9, 0xf0, 0x51, 0x3b, 0x88, 0xa2, 0x27, 0xe7, - 0x7a, 0x1a, 0xeb, 0xa3, 0x0f, 0xdb, 0x8c, 0xef, 0xe4, 0x37, 0xd3, 0x73, - 0xd6, 0xe3, 0xeb, 0xcf, 0xa3, 0x27, 0x9c, 0x22, 0xdc, 0xe6, 0xf1, 0x79, - 0xf7, 0x75, 0xe2, 0x59, 0xce, 0x73, 0x23, 0xfc, 0xae, 0x61, 0x75, 0xa6, - 0xcd, 0x78, 0xd8, 0xbb, 0x23, 0x1a, 0x58, 0x53, 0x32, 0x70, 0x07, 0xd5, - 0xd5, 0xa2, 0x57, 0x57, 0x7f, 0x85, 0xe7, 0x15, 0xe2, 0x5b, 0x46, 0x7c, - 0x9b, 0xbc, 0x31, 0x03, 0xcb, 0x4b, 0xc7, 0xbd, 0x58, 0x51, 0x1d, 0xf6, - 0x03, 0xdb, 0x9e, 0xf1, 0x68, 0xf5, 0xae, 0xc6, 0x3e, 0xc9, 0x8a, 0x47, - 0xf3, 0xbd, 0x62, 0x67, 0x3e, 0x4a, 0xfb, 0xb9, 0x62, 0x24, 0xa3, 0x8c, - 0xc6, 0x20, 0xb1, 0x2c, 0x7d, 0x35, 0xd5, 0x19, 0x2b, 0x69, 0xd1, 0xb5, - 0x65, 0x6d, 0x72, 0x2e, 0x61, 0xa7, 0x25, 0x58, 0x97, 0x0c, 0x51, 0xff, - 0xfe, 0x16, 0xee, 0xd4, 0xc3, 0xe8, 0x4f, 0xde, 0x0b, 0xdc, 0x58, 0x43, - 0xfd, 0xf6, 0x61, 0x0f, 0xb3, 0x86, 0x68, 0xdf, 0x1a, 0xaa, 0x0d, 0x77, - 0x79, 0x7a, 0x4f, 0xb1, 0xae, 0x74, 0xce, 0xe5, 0x62, 0x84, 0xea, 0x7d, - 0xa2, 0x82, 0x01, 0x36, 0x66, 0x8a, 0xfc, 0x3d, 0xb3, 0xb1, 0xcb, 0xb3, - 0xf3, 0x4f, 0x36, 0xda, 0xa5, 0x5f, 0xc4, 0x2b, 0x3d, 0x75, 0x29, 0xb2, - 0x8d, 0xdd, 0x58, 0x9f, 0xec, 0xc1, 0x1c, 0x6b, 0x39, 0xbe, 0xaa, 0xbb, - 0x88, 0x5a, 0x63, 0xb8, 0xdb, 0x93, 0xc1, 0xf2, 0xbc, 0xbf, 0x6d, 0x10, - 0x4d, 0x13, 0xc8, 0xf9, 0xbc, 0xfb, 0x50, 0xe5, 0xdd, 0x42, 0x4e, 0x09, - 0x62, 0xd3, 0x2e, 0xfe, 0x56, 0x71, 0x77, 0xa6, 0xf2, 0xce, 0x70, 0x78, - 0x2c, 0x88, 0xa1, 0x5d, 0xd4, 0xfb, 0x52, 0x21, 0xb8, 0x8d, 0x9f, 0x96, - 0xdd, 0x4f, 0xb2, 0x2b, 0xf7, 0xef, 0xaf, 0x91, 0x5d, 0x67, 0x82, 0x41, - 0x34, 0x13, 0x0c, 0x4b, 0x10, 0x4f, 0xc3, 0x54, 0x1d, 0x9a, 0xc7, 0xf8, - 0xef, 0x23, 0x07, 0xc5, 0x7d, 0xa5, 0x0a, 0xcf, 0x46, 0xfe, 0x9b, 0x4a, - 0x58, 0xc1, 0x7c, 0x8b, 0xd5, 0x55, 0x89, 0x47, 0xa3, 0x7b, 0x5c, 0x2d, - 0xe6, 0x8f, 0xd5, 0xd1, 0x47, 0x47, 0x6c, 0x82, 0x26, 0xa6, 0x96, 0x8b, - 0xaf, 0xe7, 0x93, 0x88, 0xd1, 0xfd, 0x32, 0xee, 0x54, 0xd6, 0xdf, 0x53, - 0xfa, 0xbc, 0xf3, 0x07, 0xff, 0xbb, 0xb2, 0x6f, 0x01, 0x8e, 0xea, 0xbc, - 0xd2, 0xfc, 0x6e, 0x3f, 0xa4, 0xd6, 0x93, 0xab, 0x27, 0x2d, 0x1e, 0xa6, - 0x9b, 0xbe, 0x2d, 0xb5, 0xad, 0x4e, 0xb8, 0x0d, 0xa2, 0x90, 0x3d, 0xbd, - 0xa5, 0x06, 0x0b, 0x5b, 0x04, 0x63, 0xcb, 0xb6, 0x32, 0x83, 0x67, 0x53, - 0x63, 0x05, 0x03, 0xc6, 0xd8, 0x33, 0x91, 0x09, 0x35, 0x25, 0xef, 0xce, - 0x44, 0x77, 0x25, 0x10, 0x02, 0xf5, 0x4b, 0x12, 0x04, 0x98, 0xaa, 0x2d, - 0x37, 0x92, 0x40, 0xd8, 0x69, 0x49, 0x78, 0x92, 0xec, 0x90, 0x4c, 0xd5, - 0x58, 0x01, 0x61, 0x20, 0x04, 0xe3, 0xec, 0x4e, 0x6d, 0x91, 0x5d, 0xcf, - 0x98, 0xc2, 0x06, 0x9c, 0x18, 0x3f, 0x33, 0x59, 0x8b, 0x78, 0xe2, 0xbb, - 0xdf, 0xb9, 0xdd, 0x0d, 0x82, 0x21, 0x99, 0x1a, 0x57, 0x75, 0x89, 0xee, - 0x7b, 0xff, 0xff, 0x9e, 0xff, 0xfc, 0xe7, 0x7c, 0xe7, 0x3b, 0xe7, 0xfc, - 0xb7, 0x4c, 0x2e, 0x2d, 0xfb, 0xb5, 0x08, 0xc5, 0xda, 0x94, 0xf9, 0x42, - 0x96, 0xe3, 0x48, 0x1c, 0xed, 0xbe, 0xd9, 0x8f, 0x11, 0x99, 0x84, 0xcb, - 0x41, 0xad, 0x08, 0x4b, 0x9e, 0xc7, 0x1f, 0xad, 0x3c, 0x51, 0x64, 0x90, - 0xb9, 0x0b, 0x91, 0x3f, 0x2c, 0x73, 0x17, 0x21, 0xef, 0xa6, 0x2c, 0xf2, - 0x1c, 0xa6, 0x5c, 0x13, 0x12, 0x5b, 0xe5, 0x79, 0xc7, 0x95, 0xa1, 0xb4, - 0xc8, 0x90, 0x7b, 0xee, 0x59, 0x73, 0xa3, 0x5a, 0xc4, 0x18, 0x3e, 0x62, - 0x6e, 0x62, 0x5e, 0xe2, 0x5f, 0xfa, 0x86, 0x99, 0x6a, 0x93, 0xb5, 0xba, - 0xcd, 0xbd, 0x09, 0x27, 0xfa, 0xa9, 0xb7, 0xad, 0xa1, 0xa3, 0xc2, 0x67, - 0xb3, 0xff, 0xe5, 0xf4, 0xf6, 0x97, 0xd4, 0xdb, 0xa9, 0xec, 0x3e, 0x1e, - 0x57, 0x4e, 0xde, 0x8c, 0xf5, 0x22, 0xa3, 0xc8, 0xa5, 0xa0, 0x42, 0x13, - 0xb9, 0x6c, 0x28, 0x67, 0xdc, 0xac, 0xa0, 0x7e, 0xca, 0x2d, 0x99, 0x9a, - 0x95, 0x9f, 0x47, 0xa1, 0xce, 0x21, 0x17, 0x2c, 0x9b, 0xc8, 0xc8, 0x35, - 0x45, 0xfd, 0x5c, 0xb8, 0x69, 0x13, 0xb3, 0xf5, 0x2c, 0x74, 0x46, 0x7c, - 0xfa, 0xe2, 0x4b, 0x3b, 0x92, 0x32, 0xaf, 0x5d, 0xf2, 0x04, 0x2b, 0xdf, - 0xb3, 0xd1, 0x9e, 0x56, 0x45, 0x33, 0x3a, 0xb0, 0x59, 0x7b, 0x20, 0x3e, - 0x20, 0xeb, 0xcf, 0xad, 0xbd, 0x59, 0x79, 0x3a, 0x2a, 0xe3, 0x35, 0x2c, - 0xb2, 0xc6, 0x59, 0xfb, 0xce, 0x71, 0x6f, 0x73, 0x5c, 0x80, 0x63, 0x32, - 0xb6, 0xe9, 0x49, 0x7d, 0x26, 0x7e, 0xcd, 0x7d, 0x3a, 0xae, 0x74, 0xf2, - 0x99, 0xb0, 0xf6, 0xf6, 0xfd, 0xac, 0xaf, 0x1f, 0xa7, 0x6f, 0xf2, 0x37, - 0xa7, 0x8d, 0xf6, 0x5e, 0x04, 0xc7, 0xb0, 0xcb, 0xaa, 0x49, 0xc8, 0xdc, - 0xcf, 0x45, 0xcb, 0x51, 0x70, 0x24, 0x37, 0x36, 0x13, 0xc3, 0x33, 0xbd, - 0xac, 0x9c, 0x3f, 0x0a, 0x3e, 0x0a, 0x76, 0x1b, 0x4a, 0xe4, 0x66, 0x3f, - 0x4a, 0x6a, 0x38, 0xd2, 0xa7, 0xcb, 0xa7, 0x3c, 0x52, 0xef, 0x53, 0x88, - 0x19, 0xcc, 0x07, 0xd5, 0x55, 0x1e, 0x07, 0x71, 0x6e, 0x13, 0xbe, 0x20, - 0xb7, 0x8d, 0x04, 0x9c, 0x96, 0x0f, 0x4b, 0xcd, 0x2f, 0x1f, 0x19, 0x0c, - 0x02, 0x86, 0xa3, 0x8c, 0xbb, 0x5c, 0x2b, 0x63, 0x3d, 0xba, 0xd3, 0x5f, - 0x98, 0x53, 0x95, 0xcc, 0xd9, 0xb5, 0x9b, 0x35, 0x22, 0xfa, 0x9d, 0x69, - 0x8e, 0xf0, 0x5a, 0x6f, 0x3a, 0xb7, 0x4f, 0xe4, 0x10, 0xe4, 0x68, 0xcf, - 0x68, 0xbf, 0x35, 0x37, 0xdc, 0x76, 0x6f, 0x0e, 0x9b, 0x73, 0x79, 0xa9, - 0x60, 0x73, 0x31, 0x7a, 0xf7, 0x7a, 0x93, 0x29, 0x54, 0x22, 0xa9, 0xd9, - 0xe6, 0xd3, 0x4b, 0x98, 0xf5, 0x7b, 0xfb, 0x9a, 0x61, 0xe5, 0xeb, 0x9e, - 0x14, 0xfa, 0x2b, 0xc4, 0x8f, 0x9c, 0x5a, 0xbd, 0xa7, 0xcc, 0x56, 0x2e, - 0xb2, 0x5b, 0x52, 0xd9, 0x07, 0x0b, 0xb0, 0x89, 0xb9, 0x76, 0xaa, 0x95, - 0x98, 0x35, 0x68, 0xb4, 0x70, 0x7a, 0x57, 0x61, 0x38, 0xd5, 0xf9, 0x35, - 0xbf, 0x97, 0xf1, 0x10, 0xc8, 0x67, 0xde, 0x7f, 0x09, 0x59, 0x4c, 0x1b, - 0xf4, 0x1a, 0x36, 0x9b, 0x8c, 0xff, 0xcc, 0x34, 0xda, 0x64, 0xac, 0xcc, - 0xc1, 0x67, 0xff, 0x1b, 0x5f, 0xf0, 0x50, 0x4f, 0x87, 0x2b, 0xa4, 0x7e, - 0xa6, 0xd6, 0x92, 0xab, 0x0f, 0x16, 0xa3, 0x88, 0xb9, 0x6b, 0x7f, 0x95, - 0xaf, 0x43, 0xb7, 0x15, 0xe2, 0xfc, 0x57, 0xfe, 0x13, 0x52, 0x55, 0x79, - 0x70, 0xd5, 0x02, 0x0f, 0xc6, 0x6d, 0xb0, 0xd5, 0x12, 0x7b, 0x1b, 0x80, - 0xe6, 0x09, 0xee, 0xdb, 0xa0, 0x82, 0xa7, 0x92, 0x36, 0x3c, 0x9a, 0xb4, - 0x63, 0x6d, 0x12, 0xdf, 0x59, 0x04, 0x4c, 0xd7, 0xc0, 0xdf, 0x3e, 0xa3, - 0x60, 0x6b, 0x29, 0xfc, 0xad, 0x31, 0xc5, 0xdf, 0xb2, 0x96, 0x39, 0xd3, - 0x9a, 0x09, 0xe2, 0x19, 0xef, 0x75, 0x0e, 0x70, 0x5f, 0x07, 0xec, 0xa8, - 0x19, 0xc0, 0x3d, 0xf9, 0x40, 0x83, 0x13, 0xfe, 0x19, 0xc6, 0x99, 0x72, - 0x07, 0xfc, 0x53, 0x97, 0xed, 0xfe, 0xce, 0x1a, 0x3b, 0x37, 0xb7, 0x56, - 0x64, 0x71, 0xe1, 0x31, 0xda, 0xf3, 0xa2, 0x41, 0xde, 0xcf, 0xfc, 0x5d, - 0x65, 0x9e, 0xf3, 0xc9, 0x9f, 0x48, 0xfd, 0x52, 0xae, 0x49, 0xef, 0x52, - 0x41, 0xe9, 0xa0, 0x9d, 0x18, 0x76, 0xce, 0x3c, 0x5f, 0x25, 0xf8, 0x0d, - 0x3c, 0x45, 0xd9, 0xdc, 0xfc, 0x4d, 0xad, 0x25, 0x37, 0x5d, 0xa1, 0x62, - 0xfd, 0xb0, 0xdc, 0x0b, 0x6b, 0x1e, 0x27, 0x7d, 0x2a, 0x8f, 0x3e, 0x7e, - 0xc4, 0xea, 0x77, 0xd9, 0xb8, 0x46, 0x3b, 0x8a, 0x06, 0x81, 0x35, 0x71, - 0x3c, 0x51, 0x0c, 0x7f, 0x44, 0x64, 0xac, 0x5b, 0xee, 0xe0, 0xd8, 0x62, - 0xb4, 0x4c, 0x64, 0xc6, 0x3d, 0x3c, 0xf1, 0xa3, 0x8a, 0x4c, 0x2d, 0xf7, - 0xf7, 0xf7, 0x5e, 0x7b, 0x1a, 0xfc, 0xd8, 0x94, 0xa4, 0xcd, 0xd9, 0x3c, - 0x18, 0xce, 0xd6, 0x54, 0x37, 0xa4, 0xbc, 0xb3, 0x7a, 0xa3, 0xff, 0xbd, - 0x38, 0xdb, 0x37, 0xa5, 0x2f, 0xcc, 0x70, 0x1e, 0x43, 0xd9, 0x40, 0xdd, - 0x0d, 0x4f, 0x9a, 0x88, 0xea, 0x26, 0xc6, 0xf9, 0x79, 0x53, 0x87, 0x51, - 0x44, 0x5f, 0xd8, 0x18, 0xfb, 0xd2, 0x34, 0xb2, 0xfe, 0xfc, 0x4a, 0x22, - 0xa0, 0x6c, 0x21, 0x57, 0x7e, 0x95, 0xf1, 0x74, 0x8c, 0x9f, 0x51, 0xe6, - 0x70, 0x4e, 0xca, 0x6d, 0xa3, 0x5f, 0xef, 0x4c, 0x01, 0x23, 0xcc, 0xd1, - 0x0f, 0x2e, 0x17, 0xfe, 0x5e, 0xc4, 0xe7, 0xd1, 0x6b, 0x78, 0x4f, 0x9a, - 0x9f, 0x23, 0xfc, 0x4c, 0x72, 0x4f, 0xf9, 0x3c, 0x04, 0xc6, 0x1d, 0x88, - 0x8c, 0x13, 0x68, 0xc7, 0x03, 0x98, 0x62, 0x0c, 0xbc, 0x31, 0xaa, 0xa2, - 0x64, 0xac, 0x1c, 0x1f, 0x1d, 0x26, 0x3e, 0x1e, 0xca, 0x70, 0xfe, 0x4d, - 0xe3, 0xd2, 0xdf, 0x92, 0xf5, 0x49, 0x1f, 0x58, 0xfc, 0xa9, 0x00, 0x63, - 0xa4, 0x1f, 0xd2, 0x0b, 0x7e, 0x57, 0xe7, 0xdc, 0xaa, 0xf4, 0xf1, 0x5a, - 0x71, 0x34, 0xea, 0xf3, 0xf4, 0xd1, 0xe6, 0x0d, 0x87, 0xf8, 0x58, 0x03, - 0x5e, 0x8d, 0xe6, 0x7a, 0x42, 0xbe, 0x96, 0x9f, 0x4a, 0x3d, 0x83, 0x21, - 0x3b, 0x4f, 0x93, 0x6b, 0xb9, 0x58, 0x2a, 0x6b, 0x96, 0xba, 0x74, 0x8e, - 0xb7, 0xcc, 0xfe, 0xfd, 0x8c, 0x29, 0x7d, 0xca, 0xd7, 0x26, 0xbd, 0x7d, - 0x29, 0xe8, 0x56, 0xac, 0x3c, 0x5c, 0xe7, 0x4d, 0x1a, 0x90, 0xfd, 0x6d, - 0xa0, 0x0c, 0xdf, 0xa5, 0xed, 0x07, 0x44, 0xd7, 0x8c, 0xed, 0x52, 0xef, - 0x2d, 0x43, 0xff, 0x40, 0x39, 0xf6, 0x0c, 0x18, 0xe8, 0x5d, 0xde, 0x86, - 0x33, 0x51, 0x13, 0x9b, 0x42, 0x26, 0xd6, 0x84, 0xbc, 0x81, 0x57, 0x50, - 0xdf, 0x78, 0x14, 0x8f, 0x91, 0x43, 0xa8, 0xd4, 0xc9, 0x37, 0xf0, 0xce, - 0x5e, 0x07, 0x36, 0xeb, 0x7f, 0x4c, 0x1f, 0x36, 0xcd, 0xf7, 0x96, 0x2d, - 0xc0, 0x70, 0xa2, 0x5e, 0xed, 0xa6, 0x7c, 0x91, 0x36, 0xee, 0x55, 0xd0, - 0x81, 0x67, 0xf5, 0xef, 0xf0, 0x5e, 0xb7, 0xcd, 0xa1, 0xc9, 0x77, 0x1b, - 0xe3, 0xa9, 0xec, 0xa5, 0x41, 0xfb, 0xca, 0xc4, 0xb2, 0x48, 0xb6, 0xce, - 0xbe, 0xb9, 0x41, 0x30, 0xbf, 0x18, 0xa7, 0xa9, 0xb7, 0x13, 0xc9, 0x08, - 0xc3, 0x2e, 0x94, 0x67, 0x1b, 0xba, 0xf0, 0x34, 0xf9, 0xc6, 0x3b, 0x24, - 0x02, 0xf7, 0xc7, 0x15, 0x34, 0xd6, 0xe9, 0xb8, 0x98, 0xfe, 0x06, 0xde, - 0x1a, 0x0d, 0xe3, 0x4d, 0xc6, 0xf4, 0x25, 0xdf, 0xf5, 0x92, 0x83, 0x7a, - 0x70, 0x3e, 0x1d, 0xc6, 0xb9, 0xa8, 0xb7, 0xf5, 0x05, 0x65, 0x01, 0x7e, - 0x9a, 0x76, 0xe0, 0xde, 0x38, 0xf0, 0x4b, 0xce, 0xe3, 0x8f, 0x3b, 0x70, - 0x25, 0xad, 0xe2, 0x28, 0xf7, 0xc7, 0x11, 0x5a, 0x02, 0xa3, 0xcd, 0x83, - 0x23, 0x43, 0x8f, 0x62, 0x2a, 0xf5, 0x28, 0x4e, 0x25, 0xdf, 0x31, 0x5d, - 0x9a, 0xf4, 0x75, 0x5c, 0xb8, 0xc2, 0x7c, 0x6c, 0x9a, 0xda, 0x28, 0x5e, - 0xd1, 0xca, 0x38, 0xaf, 0x19, 0xa2, 0xf7, 0xb7, 0xf8, 0xdb, 0xfd, 0xf1, - 0x46, 0x1c, 0x1c, 0xa7, 0x4a, 0x13, 0x3a, 0x12, 0x31, 0x79, 0x56, 0x03, - 0x62, 0xe4, 0x85, 0xfd, 0x4c, 0xdb, 0xb7, 0x86, 0xee, 0x95, 0x5c, 0x43, - 0x69, 0xa9, 0xed, 0xcf, 0xae, 0xa3, 0x71, 0x56, 0xcf, 0x4e, 0x72, 0x28, - 0xea, 0x95, 0xe3, 0xfe, 0x36, 0x11, 0xb4, 0x62, 0xd3, 0xb1, 0x9b, 0xfb, - 0xd1, 0xc8, 0xfd, 0xf8, 0x06, 0x2e, 0xee, 0x6d, 0xc3, 0x5b, 0xc4, 0xbb, - 0xd2, 0x65, 0xbe, 0x4e, 0xa7, 0xad, 0x9e, 0x73, 0xa7, 0xcd, 0x54, 0x95, - 0xe8, 0xb4, 0x0d, 0xbf, 0x88, 0x8a, 0x4e, 0xd3, 0xc4, 0x3f, 0x9f, 0xc7, - 0x6f, 0xff, 0xcb, 0x4a, 0xda, 0xb3, 0xad, 0x3b, 0x98, 0xe9, 0x41, 0x15, - 0xaf, 0x70, 0xe1, 0xaa, 0x25, 0x9b, 0xc8, 0xfa, 0x87, 0xe4, 0xfb, 0x85, - 0xb9, 0xa6, 0x4a, 0xe4, 0x33, 0xcc, 0x3c, 0x4d, 0x0b, 0xe4, 0x29, 0x12, - 0x67, 0x03, 0x56, 0x3d, 0xbe, 0x2e, 0xde, 0x05, 0x7b, 0xa8, 0x98, 0x79, - 0x98, 0x77, 0xa6, 0x03, 0x6f, 0xe1, 0xda, 0xa4, 0x0b, 0x8b, 0xe3, 0x1a, - 0x5e, 0x9e, 0x7c, 0x8d, 0xcf, 0xfa, 0x47, 0x5c, 0xe6, 0x77, 0x5f, 0x3c, - 0xe3, 0x6f, 0xdd, 0x0d, 0x6d, 0x78, 0x30, 0x2d, 0xeb, 0xcb, 0xe3, 0x83, - 0x74, 0x44, 0xd2, 0xb2, 0xce, 0x18, 0x7d, 0x43, 0xd6, 0x59, 0xfe, 0xef, - 0xac, 0xf3, 0xbf, 0x72, 0xbe, 0x05, 0xf4, 0xa5, 0x5c, 0xec, 0x28, 0xc1, - 0x91, 0xa4, 0x8a, 0xd3, 0x7a, 0x31, 0x2e, 0xa9, 0x52, 0x5f, 0x76, 0x31, - 0x86, 0x38, 0xd0, 0xcc, 0x9c, 0x71, 0x84, 0x9f, 0x8d, 0xcc, 0x7f, 0xce, - 0xea, 0x0e, 0x9c, 0xd2, 0x17, 0x10, 0xeb, 0xef, 0xb4, 0x61, 0xb9, 0x46, - 0xb2, 0x5f, 0x56, 0x8e, 0x73, 0x52, 0xff, 0xb3, 0xae, 0xbb, 0xa4, 0x2f, - 0x89, 0x31, 0xea, 0x2b, 0x2f, 0xf6, 0x1b, 0xf3, 0xaa, 0x85, 0x35, 0x77, - 0xca, 0x77, 0xe7, 0x3c, 0x12, 0x82, 0x7f, 0x69, 0x6e, 0xad, 0xca, 0xc6, - 0x2e, 0xe5, 0x4f, 0x2b, 0x33, 0x78, 0x21, 0x71, 0xec, 0xef, 0x72, 0xd8, - 0x21, 0xf9, 0x64, 0x1b, 0xe3, 0x10, 0xe3, 0xf2, 0xf1, 0x6d, 0x92, 0xe7, - 0xd9, 0xc2, 0xef, 0xb5, 0xad, 0xd2, 0xf2, 0x60, 0xb7, 0xf8, 0xde, 0x7b, - 0x2f, 0x65, 0x38, 0xfa, 0xfb, 0x2f, 0x69, 0xd6, 0xdf, 0xeb, 0x2f, 0x2d, - 0xb6, 0xfe, 0x7e, 0xf2, 0x92, 0x2f, 0x75, 0x2b, 0x5e, 0x65, 0x38, 0xb0, - 0x75, 0x6e, 0x05, 0x7d, 0xba, 0xa1, 0x3c, 0xdc, 0x20, 0x5c, 0x72, 0x36, - 0x8f, 0x08, 0x28, 0x67, 0xa3, 0x92, 0xa7, 0x15, 0x1a, 0xcc, 0xe3, 0x95, - 0x46, 0xbf, 0x46, 0x3c, 0xee, 0x42, 0xc9, 0x32, 0x0d, 0x17, 0xa8, 0x73, - 0xc2, 0x28, 0xed, 0xf8, 0xff, 0x20, 0xba, 0x17, 0xed, 0x85, 0x16, 0xf6, - 0x98, 0x66, 0x7f, 0x48, 0x6a, 0x0c, 0x32, 0xaf, 0x03, 0x1f, 0x70, 0x2f, - 0x7f, 0x35, 0x5a, 0x84, 0xf7, 0x53, 0x1a, 0x2e, 0xa5, 0xdb, 0xb0, 0x7b, - 0x32, 0xc3, 0x33, 0x4e, 0x59, 0xfc, 0x5b, 0x63, 0x8e, 0xe9, 0xc0, 0xc1, - 0xa8, 0x86, 0x58, 0xe2, 0x75, 0xb3, 0x40, 0xf3, 0x4d, 0xf9, 0xed, 0x0e, - 0x1c, 0x48, 0x4f, 0x63, 0x72, 0xe0, 0x63, 0xd3, 0xae, 0x75, 0xe1, 0xa3, - 0xd0, 0x34, 0x26, 0x0e, 0x49, 0x5f, 0x4f, 0x47, 0xff, 0x90, 0x86, 0xde, - 0x84, 0x0d, 0x7b, 0x96, 0xb7, 0xa0, 0x7f, 0xb2, 0x19, 0xc6, 0x98, 0x07, - 0x7b, 0xd2, 0x69, 0x4c, 0x8d, 0x4e, 0xe3, 0x4c, 0x52, 0x6b, 0x2c, 0x50, - 0xa6, 0x71, 0x9a, 0xcf, 0xd9, 0x91, 0x78, 0x1b, 0x06, 0xe7, 0xd8, 0x99, - 0x94, 0x9a, 0xa4, 0x3c, 0x67, 0x1a, 0xdd, 0xa9, 0xbb, 0xd5, 0x44, 0x28, - 0x4f, 0xa2, 0xa7, 0x3d, 0x53, 0xab, 0x27, 0xbe, 0xa6, 0x35, 0xa5, 0x8f, - 0xfb, 0x74, 0x34, 0x9d, 0xab, 0xdb, 0xdf, 0x59, 0x0b, 0xd1, 0xd1, 0x37, - 0xd4, 0xc2, 0x31, 0x1a, 0xba, 0x13, 0xd2, 0x1b, 0xf5, 0xf1, 0x99, 0x26, - 0x7e, 0xa9, 0x7b, 0xdd, 0x8b, 0xf9, 0xf7, 0xb0, 0xde, 0x89, 0x2d, 0x9c, - 0x6b, 0x8a, 0x79, 0x90, 0xa6, 0x78, 0x1b, 0x0d, 0xd8, 0xf1, 0x9e, 0x4e, - 0xce, 0x53, 0x69, 0xc7, 0xab, 0x7a, 0x09, 0x22, 0x65, 0x76, 0xd4, 0x87, - 0x18, 0xa7, 0xb3, 0x71, 0xfb, 0xc3, 0xa4, 0x82, 0x47, 0x89, 0xa9, 0x27, - 0x42, 0xf5, 0xed, 0xab, 0x85, 0xd1, 0x1d, 0x52, 0x70, 0x4d, 0xbb, 0x61, - 0x1a, 0x8c, 0x5d, 0x2e, 0x7f, 0x6e, 0x8f, 0x7e, 0x6d, 0x66, 0xfa, 0x9b, - 0x5f, 0x98, 0xb9, 0x71, 0x33, 0x94, 0xf1, 0x29, 0x8e, 0x5b, 0xbc, 0xac, - 0xbe, 0x53, 0xc6, 0xb9, 0x89, 0xe9, 0x32, 0x4e, 0xea, 0xd1, 0xb7, 0xc6, - 0xe9, 0xd8, 0x39, 0x14, 0xb1, 0xe4, 0xdd, 0x95, 0xc0, 0x52, 0x07, 0xc4, - 0x9f, 0xea, 0xd5, 0x2b, 0x40, 0xd7, 0xb4, 0x3e, 0x87, 0x5c, 0xc7, 0x1f, - 0xd8, 0x08, 0xd1, 0x95, 0xe4, 0x92, 0x6f, 0x63, 0x4f, 0x74, 0x14, 0xcc, - 0x27, 0x89, 0x73, 0xfe, 0xf5, 0x23, 0x48, 0xe1, 0xf9, 0x74, 0x0a, 0x2f, - 0x50, 0x47, 0x86, 0x75, 0x6e, 0x29, 0x8d, 0x3f, 0x8f, 0xbe, 0x8d, 0x98, - 0xb5, 0x67, 0x47, 0xb1, 0x21, 0xfa, 0xf7, 0x55, 0xc2, 0x11, 0x77, 0x24, - 0x56, 0x72, 0x7e, 0xd1, 0xab, 0xb7, 0xd5, 0xc0, 0x97, 0x9c, 0x7f, 0x25, - 0x7a, 0x46, 0x4c, 0xf3, 0x7b, 0x8c, 0x5f, 0x3f, 0x23, 0xbf, 0xba, 0x96, - 0x3d, 0x03, 0x55, 0x40, 0x7d, 0x6b, 0x56, 0x1c, 0x6b, 0xe3, 0x3e, 0x57, - 0x0b, 0xaf, 0x47, 0xc9, 0xb8, 0xa6, 0x2c, 0x8e, 0xc9, 0xbe, 0x93, 0x37, - 0x8e, 0x7b, 0xf0, 0x14, 0x39, 0x4a, 0xfe, 0xe1, 0x1f, 0x28, 0x12, 0xcb, - 0x6a, 0x0e, 0x91, 0xef, 0x1f, 0xf2, 0x28, 0x4b, 0xf6, 0xb9, 0xf0, 0x68, - 0x4c, 0xea, 0x37, 0xcd, 0xe8, 0xd9, 0xaf, 0xf1, 0x1e, 0xaf, 0x7e, 0x81, - 0x39, 0xe9, 0x69, 0xf8, 0x3c, 0x23, 0xe4, 0x55, 0x6e, 0x62, 0xb1, 0xe3, - 0x70, 0x29, 0x8a, 0x0e, 0xab, 0xb0, 0x1d, 0x2e, 0x47, 0xf1, 0x61, 0x37, - 0x6a, 0x18, 0xdb, 0xdc, 0xe3, 0x17, 0x31, 0xb9, 0x0f, 0x6a, 0x51, 0xf8, - 0x73, 0x33, 0x5f, 0x93, 0x3e, 0x5b, 0x00, 0xa5, 0xe3, 0xdb, 0x91, 0x8e, - 0x05, 0x51, 0x3c, 0x4e, 0x2a, 0x35, 0x7e, 0x5c, 0xa9, 0xe7, 0x33, 0x1f, - 0x8a, 0x69, 0x9c, 0x2b, 0xc3, 0x75, 0x56, 0x73, 0x5c, 0x5f, 0xc2, 0xbb, - 0x5e, 0x7a, 0x65, 0xd7, 0xf4, 0x37, 0x50, 0x30, 0x70, 0xeb, 0x2c, 0x97, - 0x16, 0xc2, 0x3c, 0x72, 0x91, 0xd6, 0x67, 0x91, 0x39, 0xd7, 0xf5, 0x70, - 0x76, 0x4d, 0x41, 0x59, 0x93, 0xb3, 0x8d, 0xb6, 0x30, 0x57, 0xea, 0x5f, - 0xb8, 0x4c, 0xfb, 0xb9, 0x9f, 0xf2, 0xde, 0x60, 0x6e, 0xd8, 0x19, 0x13, - 0xbb, 0xff, 0x81, 0x42, 0xbf, 0xc1, 0x4c, 0xaa, 0x08, 0x1f, 0xa7, 0x3c, - 0x8a, 0x8f, 0xeb, 0xf9, 0x0b, 0x5e, 0xff, 0x73, 0xae, 0x67, 0xc7, 0x7e, - 0x6f, 0xeb, 0x49, 0xc5, 0xdb, 0xbe, 0x4e, 0xf1, 0xa9, 0x3b, 0x94, 0x62, - 0x5c, 0x1e, 0x2d, 0xc5, 0x15, 0xc6, 0xe2, 0x1b, 0xa3, 0xe5, 0xb8, 0x3a, - 0x5a, 0x49, 0x5f, 0xd1, 0x38, 0x87, 0x69, 0x96, 0x68, 0x6e, 0xcc, 0xa4, - 0x5f, 0xc0, 0x9c, 0xd8, 0x02, 0x7c, 0x9c, 0xde, 0x82, 0xd2, 0x98, 0x70, - 0x76, 0x0f, 0x3e, 0xe2, 0xf5, 0x0f, 0xd3, 0x13, 0x28, 0xdc, 0xf7, 0x39, - 0xef, 0x31, 0xcd, 0x87, 0xb8, 0xc6, 0xab, 0xe9, 0x0e, 0x14, 0xef, 0xdb, - 0x06, 0xc7, 0x3e, 0xb3, 0xab, 0x27, 0x84, 0x9f, 0xda, 0xb9, 0x96, 0x6e, - 0xdd, 0x3b, 0xb5, 0xd8, 0x1e, 0xe4, 0x1c, 0x3a, 0xe7, 0x3c, 0xae, 0x2c, - 0x19, 0xdf, 0x86, 0xd2, 0x7d, 0x1e, 0x6c, 0xa5, 0x2e, 0x27, 0xa0, 0x05, - 0xd6, 0x29, 0xdb, 0x90, 0x77, 0x38, 0xa3, 0x83, 0x4d, 0xe3, 0x19, 0x1f, - 0x79, 0xa8, 0x41, 0xea, 0x43, 0xc7, 0x95, 0x11, 0xcb, 0x47, 0xdc, 0x72, - 0xfe, 0x04, 0xd3, 0xe9, 0x22, 0x9c, 0x4d, 0x89, 0x8e, 0xe4, 0xec, 0xda, - 0x04, 0xf2, 0xf7, 0x11, 0x23, 0x47, 0x75, 0x8b, 0x43, 0x88, 0x6f, 0x8c, - 0xa6, 0xef, 0xe6, 0x5f, 0x41, 0xec, 0x49, 0xd4, 0xd0, 0xb7, 0x16, 0x60, - 0xcd, 0x3e, 0xe9, 0x91, 0x4e, 0xdd, 0xef, 0xa2, 0x35, 0x8d, 0xa5, 0xef, - 0xe6, 0x5b, 0x0d, 0xb4, 0x53, 0x6f, 0x8b, 0x01, 0x39, 0xab, 0x61, 0x62, - 0x5a, 0x3f, 0xae, 0xd8, 0x62, 0x92, 0x6f, 0xb5, 0xd1, 0xe7, 0x5b, 0xd1, - 0x33, 0x84, 0xf6, 0x83, 0x0d, 0xd2, 0xb7, 0x75, 0x62, 0x84, 0xf9, 0xd3, - 0x65, 0xe6, 0x1c, 0xd4, 0xb9, 0x9a, 0x17, 0xce, 0xc3, 0xf0, 0xa8, 0x0b, - 0x3f, 0x1a, 0xf5, 0xa0, 0x31, 0xf6, 0x39, 0x31, 0xa3, 0x10, 0xc7, 0xa9, - 0xef, 0x49, 0xf2, 0x9f, 0x8f, 0xa2, 0x2a, 0x26, 0x18, 0x6b, 0x3f, 0x8c, - 0x56, 0x62, 0x9c, 0xb9, 0xd6, 0x75, 0xe2, 0x4c, 0x9a, 0x7b, 0xf3, 0x01, - 0xf3, 0x8e, 0xef, 0xa5, 0x83, 0xf8, 0x55, 0x34, 0x88, 0x57, 0xa9, 0xc7, - 0xba, 0x98, 0x9b, 0x32, 0x1d, 0x53, 0x70, 0xe8, 0xb8, 0x92, 0x47, 0xbb, - 0xf0, 0xc7, 0x34, 0xcf, 0x48, 0xd6, 0x2e, 0xb4, 0xf1, 0x56, 0xfa, 0x91, - 0xf4, 0xff, 0x25, 0x3e, 0x38, 0xf4, 0x11, 0x90, 0xd3, 0x05, 0x73, 0x75, - 0x42, 0xaf, 0x7b, 0x0a, 0x15, 0xf4, 0xa5, 0x2f, 0x4d, 0x55, 0x93, 0x9a, - 0x58, 0x32, 0x74, 0x2d, 0xaa, 0xa9, 0x57, 0xad, 0x35, 0x18, 0x8a, 0x73, - 0x39, 0x39, 0x46, 0xe5, 0x0e, 0xae, 0x5f, 0x23, 0x66, 0x38, 0xe8, 0x32, - 0x26, 0xef, 0xbb, 0x8e, 0xfb, 0x0e, 0xfd, 0x69, 0x75, 0x86, 0x03, 0xd1, - 0x9f, 0x6d, 0x77, 0xd6, 0xb1, 0xa4, 0x96, 0xbd, 0x37, 0xf4, 0x46, 0x34, - 0x56, 0x2d, 0x3d, 0xa5, 0x93, 0x08, 0x52, 0x2f, 0x77, 0xcb, 0x15, 0x4c, - 0xbc, 0x45, 0x4c, 0xb9, 0x9a, 0x14, 0xbe, 0x24, 0x3c, 0xa9, 0x8b, 0x31, - 0xa9, 0x84, 0x3c, 0x41, 0xc3, 0x4e, 0x72, 0x79, 0x5f, 0x7c, 0x8a, 0xb9, - 0xca, 0x57, 0xc9, 0xd5, 0x4a, 0x39, 0x8d, 0xc1, 0xe7, 0xb5, 0x62, 0x0f, - 0x7d, 0xb3, 0x40, 0x5b, 0x8c, 0x35, 0xe4, 0x41, 0x0e, 0x8d, 0xa1, 0xe4, - 0x09, 0x89, 0x27, 0x40, 0x6d, 0x5c, 0x95, 0x7e, 0xcf, 0xfa, 0x9f, 0xe1, - 0x7e, 0xb4, 0x57, 0xb9, 0x20, 0x3d, 0x9a, 0x37, 0xd1, 0x84, 0xd4, 0xd7, - 0xad, 0xde, 0x30, 0xdc, 0x61, 0xcd, 0xb8, 0x88, 0x45, 0x16, 0x23, 0x2f, - 0x0c, 0x8b, 0x3c, 0x95, 0xd4, 0xbf, 0x8a, 0x77, 0xa9, 0xd7, 0x2b, 0x51, - 0xdf, 0xcc, 0x83, 0xa8, 0x3f, 0x73, 0xc5, 0x2e, 0xfd, 0x2b, 0xb9, 0x3f, - 0x08, 0x8d, 0xf3, 0x7d, 0x1a, 0x0d, 0x61, 0x40, 0x95, 0xef, 0xc2, 0x1b, - 0x5b, 0xd1, 0x3d, 0x22, 0x32, 0x98, 0x66, 0x39, 0xf1, 0xf1, 0x09, 0xeb, - 0xf9, 0xf2, 0xec, 0x3b, 0xf3, 0x0e, 0xaf, 0x6a, 0x20, 0x97, 0x7b, 0x4c, - 0xe3, 0x68, 0xd2, 0x03, 0xc7, 0xf2, 0xff, 0x41, 0x3d, 0x4c, 0x63, 0x34, - 0xa5, 0x91, 0x53, 0x16, 0xc1, 0x53, 0x15, 0x44, 0x3f, 0xe3, 0x78, 0x8c, - 0xf7, 0xa7, 0x63, 0x45, 0x30, 0xaa, 0x32, 0xcf, 0xfc, 0x6a, 0xfc, 0xba, - 0x39, 0xf5, 0xb8, 0xcc, 0x29, 0xdf, 0x7f, 0xce, 0x31, 0x73, 0xe5, 0xd8, - 0x23, 0x36, 0xc7, 0xae, 0x9a, 0x53, 0xad, 0xb3, 0x7f, 0x2f, 0xb3, 0xce, - 0x10, 0x45, 0x6c, 0x55, 0x52, 0x6f, 0xb1, 0xf4, 0xd2, 0x4d, 0xbd, 0xcc, - 0xd1, 0xde, 0x36, 0x1f, 0xb3, 0xe4, 0x9a, 0xaa, 0x16, 0x9e, 0x5f, 0x1b, - 0xff, 0xbc, 0x5a, 0xea, 0xa5, 0x12, 0xc3, 0x5c, 0x61, 0xad, 0xf1, 0x0c, - 0xfe, 0xd1, 0xbc, 0x74, 0xdb, 0x3c, 0x15, 0xbc, 0x26, 0xf1, 0xe8, 0x52, - 0xb6, 0x1f, 0xed, 0xce, 0xe6, 0x02, 0xd3, 0x38, 0x99, 0x94, 0x58, 0xe0, - 0xc1, 0x06, 0xa9, 0x43, 0xa9, 0xde, 0x3e, 0x03, 0x53, 0xe4, 0x7e, 0xef, - 0x50, 0xf7, 0x4c, 0x80, 0xfc, 0x53, 0xe4, 0x7f, 0xb3, 0xe3, 0x55, 0x04, - 0xa9, 0x4a, 0xe9, 0x29, 0x08, 0x9e, 0x4e, 0x63, 0x57, 0xf2, 0x75, 0xe2, - 0xda, 0xc7, 0xe4, 0x43, 0x5d, 0xe4, 0xda, 0xd3, 0xe8, 0x49, 0x35, 0xe3, - 0xe5, 0xfd, 0x2d, 0xc4, 0x18, 0xc1, 0x4a, 0xdf, 0x99, 0xcb, 0xf6, 0x66, - 0x1c, 0x1c, 0x4b, 0x23, 0x75, 0x58, 0x62, 0xa4, 0x9c, 0xc7, 0x92, 0xf8, - 0xa8, 0x21, 0x9a, 0x38, 0x0d, 0x83, 0x7f, 0xf7, 0x24, 0xb6, 0x21, 0x72, - 0xf8, 0x6d, 0x72, 0xfc, 0x69, 0xac, 0x1e, 0xd0, 0xd6, 0x1f, 0xc1, 0x34, - 0xd6, 0x32, 0x7e, 0x26, 0x13, 0x2d, 0x9c, 0xbf, 0x19, 0xbd, 0xfb, 0xbd, - 0x01, 0x87, 0x6d, 0x0e, 0x63, 0x94, 0x07, 0x3b, 0x27, 0x23, 0x30, 0x46, - 0xe4, 0x8c, 0x81, 0x0b, 0xc1, 0xb8, 0x47, 0xf9, 0x90, 0x3c, 0xb9, 0x3e, - 0xee, 0x65, 0x7e, 0xe6, 0x35, 0xd6, 0x2a, 0x3e, 0x4f, 0x9e, 0x4d, 0xfa, - 0x59, 0x73, 0x70, 0x46, 0x57, 0x50, 0x70, 0xbf, 0x82, 0x10, 0x63, 0x97, - 0xa7, 0x9a, 0x31, 0x65, 0x44, 0x47, 0xef, 0x10, 0xd7, 0x7b, 0x73, 0xdf, - 0x64, 0xbf, 0x1e, 0xe1, 0x7c, 0xb2, 0x77, 0x2d, 0xe8, 0x9d, 0xf4, 0x75, - 0x9c, 0x81, 0xdb, 0xe2, 0x5c, 0xbd, 0x43, 0xb9, 0x7b, 0x50, 0xfc, 0x71, - 0x83, 0x37, 0x30, 0x47, 0x91, 0x7b, 0x77, 0x10, 0xbf, 0x66, 0xdf, 0x6f, - 0x28, 0xc9, 0xe5, 0xe4, 0xa5, 0x36, 0xf1, 0x8b, 0x6e, 0xcb, 0x5f, 0x44, - 0x17, 0xbd, 0xc9, 0x08, 0x6d, 0xfa, 0xc7, 0x66, 0xaa, 0xb5, 0x95, 0x72, - 0x36, 0x48, 0xaf, 0xc7, 0xe2, 0x26, 0xe7, 0xa5, 0xee, 0xe6, 0x94, 0xd8, - 0xdd, 0xdd, 0xee, 0xa2, 0x3d, 0xe5, 0x13, 0x9f, 0x0a, 0x26, 0x5c, 0x70, - 0x1d, 0x29, 0x42, 0xfe, 0xb0, 0xf0, 0x34, 0xa8, 0xa5, 0xcc, 0xfb, 0xe5, - 0x3c, 0xc3, 0x30, 0x6d, 0xd4, 0x36, 0x41, 0x1f, 0x8b, 0xba, 0xb1, 0x68, - 0xc2, 0x8d, 0x1f, 0x11, 0x03, 0x6a, 0x26, 0x34, 0x1c, 0x27, 0x06, 0xb8, - 0x27, 0x02, 0x98, 0x24, 0x06, 0xcc, 0xc9, 0xd6, 0x3e, 0xde, 0x4c, 0xcf, - 0x9f, 0x8b, 0x42, 0x79, 0x96, 0xe8, 0x31, 0xb7, 0xaf, 0xb2, 0xa7, 0x2d, - 0xc4, 0x3d, 0xd9, 0xdf, 0x00, 0x76, 0x0f, 0xa5, 0xb1, 0x6a, 0x9f, 0x89, - 0x9f, 0xeb, 0xf5, 0xee, 0x02, 0x45, 0xf2, 0x04, 0x13, 0x69, 0x5d, 0xce, - 0x4d, 0x7a, 0xd7, 0xcb, 0xb9, 0xe2, 0xf6, 0x4a, 0x13, 0x79, 0x21, 0xaf, - 0x4e, 0xb4, 0x5f, 0x5f, 0xa0, 0x48, 0xdc, 0xaa, 0xf7, 0x6c, 0xc1, 0x7c, - 0x64, 0x7a, 0x65, 0x0f, 0x62, 0x8b, 0xaa, 0xd0, 0x1f, 0x5b, 0xb0, 0xa7, - 0xcc, 0x70, 0x5d, 0x6b, 0x30, 0xcd, 0x4d, 0xa1, 0xdf, 0x56, 0x59, 0xb5, - 0x65, 0xdb, 0x1f, 0x71, 0xed, 0x6d, 0x5c, 0xb7, 0xac, 0xbd, 0x03, 0xb1, - 0xbd, 0x0a, 0xd2, 0xfe, 0x0e, 0x44, 0x47, 0x3b, 0xd0, 0xbf, 0x57, 0x30, - 0xa1, 0x8f, 0x98, 0x60, 0x76, 0x3d, 0x1b, 0x7a, 0x0c, 0x57, 0x2d, 0x16, - 0x20, 0x63, 0xbc, 0x01, 0x8f, 0x6d, 0xf6, 0x3e, 0xe4, 0x53, 0xfe, 0x8c, - 0xef, 0x34, 0x0f, 0x08, 0xa7, 0xf6, 0xf7, 0xf5, 0x72, 0xff, 0x1f, 0x3f, - 0x24, 0xf1, 0xc6, 0x34, 0xfb, 0xc8, 0x59, 0x51, 0x26, 0x6b, 0xd0, 0xa4, - 0x3e, 0xfe, 0x71, 0x8d, 0xe6, 0x9b, 0xe9, 0x67, 0x6c, 0xbf, 0xb8, 0xaf, - 0x7e, 0xcb, 0x16, 0xe1, 0x31, 0xcb, 0x84, 0xdb, 0xa5, 0x71, 0xe1, 0xf0, - 0x7d, 0x48, 0x3d, 0xce, 0xf5, 0x70, 0xaf, 0x9c, 0xf1, 0x2f, 0x4c, 0xe1, - 0x72, 0x76, 0x4d, 0x53, 0x8f, 0x12, 0xfb, 0x6c, 0x13, 0x7e, 0xf4, 0x94, - 0xc1, 0xb8, 0xd6, 0x20, 0xcf, 0xbf, 0x29, 0x3f, 0xd7, 0xdb, 0x8c, 0xfe, - 0xfd, 0xc2, 0x35, 0x84, 0x97, 0xf9, 0x8c, 0x0f, 0xd0, 0x82, 0xe4, 0x64, - 0xe6, 0x59, 0xd1, 0xc4, 0x9d, 0xb6, 0x22, 0xfb, 0x7e, 0x1a, 0xbb, 0x69, - 0x97, 0x2e, 0xce, 0xcf, 0xf8, 0xc2, 0xf9, 0xb4, 0x40, 0x81, 0x3c, 0x6f, - 0xe2, 0xc7, 0xe6, 0x9e, 0x2a, 0xd1, 0x8d, 0xcc, 0x7f, 0xba, 0x4a, 0x30, - 0x63, 0x53, 0xe8, 0x0f, 0xad, 0xf5, 0x75, 0xfe, 0xf5, 0xb6, 0x64, 0xf4, - 0x21, 0xf7, 0x9e, 0xfe, 0x3d, 0xf2, 0x5c, 0xe0, 0x7d, 0x22, 0x53, 0x07, - 0x76, 0xef, 0x85, 0x51, 0xa8, 0x49, 0xaf, 0xa0, 0x03, 0x7d, 0xd4, 0xef, - 0xce, 0x64, 0x07, 0x0e, 0xd2, 0x67, 0x87, 0xf5, 0x13, 0x35, 0x36, 0xd4, - 0xcd, 0xd8, 0x31, 0xf5, 0x93, 0x45, 0xc4, 0xd3, 0x25, 0xcb, 0xfc, 0xf4, - 0xaf, 0x0e, 0xc4, 0x53, 0x63, 0x73, 0xad, 0x3e, 0x9f, 0x4d, 0xe2, 0x9f, - 0xe8, 0xa2, 0x13, 0x85, 0x03, 0xa7, 0xe1, 0x1c, 0xe8, 0x44, 0x81, 0xbf, - 0x09, 0x0f, 0x87, 0x2e, 0x99, 0x57, 0x35, 0x87, 0xfb, 0x24, 0xf5, 0x73, - 0x22, 0x58, 0xc3, 0x7c, 0x92, 0x39, 0xcc, 0xc8, 0x3c, 0xfa, 0x7e, 0x03, - 0xf9, 0xae, 0xf4, 0xf4, 0x6d, 0x58, 0xbb, 0x5c, 0x72, 0x75, 0x85, 0xb6, - 0x5d, 0xcd, 0x5c, 0x53, 0x53, 0x9f, 0xb7, 0xce, 0x5f, 0x90, 0x87, 0x55, - 0x7a, 0xf0, 0x8c, 0x75, 0xee, 0x40, 0xae, 0x6f, 0x67, 0x8e, 0xb0, 0x1d, - 0x35, 0x31, 0xc3, 0x14, 0x7d, 0x9f, 0x44, 0xe4, 0x25, 0x1b, 0xe5, 0x68, - 0x5c, 0xe6, 0xdf, 0x32, 0xa3, 0x88, 0x4d, 0xfb, 0xdb, 0x27, 0x14, 0xdd, - 0xf5, 0xc8, 0xb8, 0x82, 0xc0, 0x00, 0xe7, 0x0a, 0xfd, 0xf5, 0xdc, 0x4c, - 0x7d, 0x2c, 0xc7, 0xf9, 0xb6, 0x93, 0x27, 0x6c, 0x47, 0x09, 0xc7, 0xbb, - 0x35, 0xc1, 0x86, 0xc8, 0x4a, 0xe9, 0xa5, 0xa4, 0x43, 0xfe, 0xd6, 0x62, - 0x45, 0xf8, 0x90, 0xbf, 0x71, 0xad, 0x22, 0xdc, 0x45, 0xc6, 0xe9, 0xae, - 0xba, 0xf1, 0x8b, 0xd9, 0x9e, 0x57, 0x03, 0xf1, 0xc1, 0x63, 0x9d, 0x85, - 0x7c, 0xed, 0xe6, 0x79, 0x89, 0x4c, 0xbd, 0xda, 0x19, 0x97, 0xbc, 0xe2, - 0x58, 0x68, 0x55, 0xb4, 0x91, 0x58, 0x67, 0x36, 0x8d, 0xd1, 0xee, 0x2f, - 0xa3, 0x12, 0xff, 0x33, 0x2a, 0xb8, 0xe6, 0xc1, 0xff, 0x8a, 0xe6, 0x4b, - 0xbe, 0x9c, 0x92, 0x7a, 0xe4, 0xb9, 0xa4, 0x61, 0x52, 0xaf, 0x2d, 0x6b, - 0x69, 0x4b, 0x81, 0x50, 0x31, 0x50, 0xd5, 0xfd, 0x8c, 0xd3, 0xca, 0xdf, - 0x4b, 0x50, 0xc6, 0x18, 0x30, 0x30, 0xf2, 0xfb, 0x6a, 0xaf, 0xc4, 0xe1, - 0x42, 0xa9, 0x81, 0xda, 0xb1, 0x33, 0xf4, 0x2f, 0x66, 0x2a, 0x7b, 0x76, - 0xf5, 0xc2, 0x5e, 0xb1, 0xd3, 0x00, 0xf2, 0xe3, 0x17, 0x69, 0x93, 0x2a, - 0xce, 0x47, 0x7d, 0xfa, 0x3a, 0xdb, 0x37, 0x68, 0xff, 0x8b, 0x6e, 0xc3, - 0xee, 0x45, 0xda, 0xa3, 0x78, 0xda, 0xc2, 0xee, 0x30, 0x7a, 0x18, 0x1b, - 0xc8, 0xe3, 0x0e, 0x3c, 0x63, 0x53, 0x51, 0x10, 0xf3, 0xa9, 0x3e, 0xe6, - 0xdb, 0x3d, 0x7c, 0x86, 0x70, 0xcc, 0x0a, 0x72, 0xc0, 0x67, 0xa3, 0xf5, - 0x9e, 0x5f, 0x63, 0x03, 0xfd, 0x51, 0x9e, 0x21, 0x6b, 0xd2, 0x50, 0xcc, - 0xbc, 0xf2, 0x14, 0xd7, 0xb1, 0xb3, 0x2c, 0xf3, 0xdc, 0xd2, 0xec, 0xdc, - 0xf1, 0x11, 0xe1, 0x5f, 0x2b, 0xb0, 0xce, 0x9a, 0x3b, 0x68, 0xf9, 0xe6, - 0x01, 0x39, 0x5b, 0x5e, 0xa7, 0x21, 0x91, 0x6e, 0xc6, 0xb6, 0xf2, 0x05, - 0x38, 0x98, 0xd8, 0x8e, 0xa5, 0xe4, 0xc1, 0x4f, 0x96, 0x1b, 0x8c, 0x8d, - 0xc4, 0xa1, 0xb8, 0xa6, 0xde, 0xa7, 0x3c, 0x90, 0xed, 0x3f, 0x54, 0xc2, - 0x11, 0x97, 0x98, 0x97, 0x87, 0x41, 0x75, 0x3e, 0x8a, 0xac, 0x33, 0x7f, - 0x99, 0xb9, 0xfb, 0x47, 0xbc, 0xd9, 0x38, 0x48, 0xd4, 0x88, 0x5b, 0xe7, - 0x2d, 0x02, 0x2f, 0x90, 0x4b, 0xa4, 0x18, 0x01, 0xf3, 0xc2, 0x5a, 0x6a, - 0x33, 0x0a, 0x60, 0x54, 0x0b, 0x26, 0xca, 0x98, 0x79, 0x77, 0xc8, 0x54, - 0x9e, 0x95, 0x29, 0x77, 0x3d, 0xc5, 0x6b, 0x62, 0x5b, 0xc2, 0x2f, 0xe4, - 0xf7, 0x42, 0xb4, 0xd2, 0x9e, 0x2a, 0x29, 0x73, 0xc2, 0x3a, 0xb7, 0xe9, - 0xd5, 0x0d, 0x5b, 0x03, 0x3e, 0xdb, 0x97, 0xb1, 0xc1, 0xf5, 0xb5, 0xdc, - 0xff, 0xd2, 0x06, 0xcc, 0x1c, 0x96, 0x78, 0xf6, 0xfb, 0xcf, 0x52, 0x18, - 0x37, 0xcf, 0x52, 0x88, 0x5e, 0xbd, 0x67, 0xde, 0x45, 0xfd, 0xd4, 0x53, - 0xb6, 0xa3, 0x26, 0x2a, 0x44, 0xc7, 0x9b, 0xdd, 0x92, 0x87, 0xda, 0xc8, - 0x23, 0x8c, 0x74, 0xd2, 0x2d, 0xb1, 0xd2, 0x11, 0x07, 0x16, 0xc5, 0x0d, - 0xe4, 0x87, 0xb5, 0x03, 0xd7, 0xec, 0x37, 0xcc, 0xf6, 0xea, 0x79, 0xcc, - 0x03, 0x6f, 0xad, 0xb9, 0x8f, 0xb2, 0xdb, 0xb5, 0x1f, 0x9b, 0x0f, 0x56, - 0x8a, 0x8c, 0x3f, 0x72, 0x67, 0xea, 0xcc, 0x0b, 0xa9, 0x97, 0x9c, 0x4e, - 0x4c, 0xda, 0xcf, 0xdf, 0x98, 0x5f, 0xbb, 0xed, 0xba, 0xf0, 0x19, 0xb1, - 0xd3, 0xd9, 0x67, 0xdb, 0xc4, 0x66, 0x3d, 0xb4, 0xd3, 0x69, 0x8c, 0x25, - 0x1b, 0x30, 0x90, 0x10, 0x1d, 0x47, 0x70, 0x99, 0xfc, 0xb0, 0x76, 0x70, - 0x1a, 0xc3, 0xe4, 0x87, 0xbe, 0xb8, 0xf7, 0x00, 0x35, 0x89, 0x6d, 0x6a, - 0x93, 0xc5, 0x93, 0x5c, 0x5a, 0x4e, 0x86, 0xaf, 0x5a, 0x7a, 0x97, 0x18, - 0xb3, 0x87, 0xeb, 0xbd, 0x97, 0x3c, 0xa9, 0x39, 0x96, 0x0f, 0xad, 0xac, - 0x14, 0xc5, 0x9a, 0xf4, 0x2b, 0x32, 0xf7, 0x45, 0x29, 0x4b, 0x91, 0xe6, - 0xc3, 0x5a, 0xeb, 0x5e, 0x8f, 0x75, 0xae, 0xc1, 0x51, 0x2e, 0x31, 0x58, - 0xe2, 0x2e, 0xf9, 0xf7, 0x72, 0x89, 0xbb, 0x61, 0xca, 0xb6, 0x98, 0x7b, - 0xb6, 0x14, 0xee, 0x07, 0x3c, 0xa8, 0x79, 0x80, 0x31, 0x72, 0x89, 0x82, - 0xf2, 0x25, 0x7e, 0x63, 0xa9, 0xad, 0x19, 0xa8, 0xd6, 0x88, 0x3f, 0x6e, - 0xb3, 0x27, 0xf1, 0x3b, 0xce, 0xd1, 0x01, 0x73, 0x6f, 0x21, 0x36, 0xec, - 0x9d, 0x43, 0x5b, 0xf5, 0x48, 0x7d, 0xdd, 0xe5, 0x0a, 0x47, 0x43, 0xae, - 0x58, 0xbd, 0xee, 0x54, 0x16, 0x33, 0x1e, 0xcb, 0xfe, 0xc9, 0xf3, 0xbf, - 0x72, 0x1b, 0x5f, 0xaa, 0x60, 0x7c, 0x7b, 0xd2, 0x92, 0x41, 0x6a, 0xc0, - 0x32, 0xee, 0xdf, 0xee, 0xd3, 0xd4, 0xcd, 0x7d, 0xba, 0x0f, 0x8e, 0x27, - 0x2a, 0xc9, 0xbf, 0xee, 0x1e, 0x43, 0x0a, 0x18, 0x43, 0xee, 0x8d, 0x99, - 0x5d, 0x5b, 0x43, 0x45, 0x52, 0x17, 0xb2, 0x62, 0x48, 0xbb, 0x8d, 0x38, - 0x5a, 0x2a, 0x76, 0xe1, 0xab, 0x21, 0xc6, 0xe9, 0x99, 0xdf, 0xc4, 0x3e, - 0xac, 0x3a, 0x5e, 0xf6, 0xb7, 0x0e, 0xec, 0x22, 0x66, 0xca, 0xd9, 0x6e, - 0xa7, 0xa6, 0xd1, 0xff, 0x3b, 0xd0, 0xc3, 0x39, 0x5f, 0x26, 0x6e, 0x0e, - 0x10, 0x37, 0x6f, 0x2c, 0x3b, 0xf1, 0x93, 0x1a, 0xd4, 0xd1, 0x08, 0xa6, - 0xfe, 0x5b, 0xb9, 0xe0, 0xe6, 0x52, 0x7f, 0xc7, 0x27, 0x16, 0x6e, 0xca, - 0xdc, 0x32, 0xdf, 0xec, 0xb9, 0x17, 0xf2, 0xdf, 0x85, 0x52, 0x4b, 0x34, - 0x9d, 0xda, 0xff, 0x36, 0x77, 0x56, 0x8a, 0xac, 0x77, 0x93, 0x43, 0xb0, - 0x76, 0x76, 0x4f, 0x7e, 0x9a, 0x98, 0x6b, 0xe5, 0x08, 0x8c, 0xb9, 0x11, - 0xac, 0x59, 0xae, 0xe2, 0x6a, 0x74, 0x1a, 0x05, 0x87, 0x72, 0xf8, 0x64, - 0x36, 0x9d, 0x22, 0x36, 0x0d, 0x43, 0xf0, 0xa8, 0x91, 0xfb, 0x62, 0xd0, - 0x4f, 0x4a, 0x30, 0x91, 0xd4, 0x88, 0x99, 0x26, 0xfa, 0x43, 0x2e, 0x72, - 0xdb, 0xee, 0x93, 0x79, 0x56, 0x9c, 0x28, 0x21, 0x86, 0xe7, 0x78, 0xb7, - 0x70, 0x6e, 0xc1, 0x1f, 0xe6, 0x18, 0x23, 0x76, 0xe4, 0x2d, 0x93, 0xbc, - 0xe2, 0x73, 0xf3, 0x42, 0x9b, 0xdc, 0xb7, 0x00, 0xc3, 0x7b, 0xc5, 0xfe, - 0x7c, 0xa8, 0xd1, 0x2e, 0x32, 0xcf, 0x00, 0xde, 0x8f, 0xda, 0xee, 0x71, - 0x91, 0x1b, 0x77, 0xe9, 0xcb, 0x71, 0xa3, 0xa2, 0x87, 0x3e, 0xef, 0xe6, - 0x6f, 0x53, 0x38, 0x12, 0x75, 0x21, 0xcf, 0xd2, 0x69, 0x29, 0xd7, 0x90, - 0xb1, 0xa1, 0x9d, 0xb4, 0xa1, 0x7c, 0xe6, 0x6f, 0x0f, 0x5b, 0xbe, 0x2a, - 0xf3, 0x4c, 0xe3, 0x15, 0x72, 0x5a, 0x6d, 0xb9, 0xf0, 0xd9, 0x20, 0xe3, - 0x62, 0x09, 0xe2, 0x03, 0x5d, 0x38, 0x1f, 0x2a, 0x41, 0xec, 0x90, 0xf8, - 0xd8, 0x02, 0xc1, 0x52, 0x3e, 0xb7, 0x91, 0x3a, 0x51, 0x89, 0x35, 0xf5, - 0x9d, 0x76, 0x7b, 0x09, 0x2e, 0x95, 0x31, 0xaf, 0xb5, 0xde, 0xe3, 0x69, - 0xc5, 0xc1, 0xac, 0x5d, 0xa8, 0xb4, 0x8b, 0xd6, 0x9b, 0x3c, 0x3a, 0xb7, - 0x96, 0x9c, 0xcf, 0x66, 0xfa, 0xe1, 0xbd, 0xe4, 0x36, 0x2f, 0x4b, 0xfd, - 0xc8, 0xe6, 0x63, 0x2c, 0x61, 0xce, 0x34, 0x29, 0xfa, 0xfd, 0xeb, 0xb9, - 0x19, 0xac, 0x78, 0xa5, 0x26, 0x73, 0x76, 0x25, 0xa7, 0xf7, 0xdc, 0x77, - 0x6d, 0x7d, 0xa1, 0xf2, 0x0b, 0x73, 0x6b, 0x95, 0xc8, 0x77, 0x9d, 0x79, - 0xda, 0x77, 0xf9, 0xfb, 0x2a, 0xf4, 0x8e, 0xcc, 0x8e, 0x15, 0xe2, 0x87, - 0x9e, 0xdb, 0xce, 0xd5, 0x95, 0xc5, 0xe5, 0xdd, 0xa9, 0x63, 0xa1, 0x67, - 0xb8, 0x0f, 0xfe, 0xa5, 0xf5, 0x56, 0xdd, 0x85, 0xdc, 0x97, 0x79, 0x89, - 0x60, 0xac, 0xc1, 0x18, 0x5f, 0x82, 0x9f, 0x26, 0x25, 0xe6, 0x9a, 0xc8, - 0xa7, 0xfd, 0x5d, 0xaa, 0xec, 0x7e, 0xbe, 0xcc, 0xe2, 0xd2, 0x25, 0x28, - 0xa7, 0xbd, 0x0f, 0x8e, 0xdc, 0xcd, 0xb6, 0x6f, 0xc5, 0x85, 0x74, 0x48, - 0x21, 0x4e, 0xfc, 0x8b, 0xd9, 0xff, 0xf5, 0xcc, 0x98, 0x0b, 0x49, 0x17, - 0x3e, 0x0a, 0xb5, 0x63, 0xaa, 0x2c, 0x8c, 0xa1, 0x44, 0x01, 0xda, 0xab, - 0xeb, 0xac, 0x77, 0x0a, 0x6a, 0xe2, 0x1e, 0x5c, 0x8c, 0x3a, 0xd1, 0x38, - 0xd7, 0x63, 0xd5, 0xd3, 0x6c, 0xf4, 0x85, 0x77, 0xa2, 0x11, 0xcb, 0xe7, - 0x66, 0xc7, 0x8c, 0x3c, 0x6d, 0x19, 0x1e, 0xca, 0xe2, 0xfa, 0xc1, 0xc4, - 0xe7, 0xc4, 0x9d, 0x52, 0xa3, 0x22, 0x5c, 0x82, 0x7b, 0x87, 0x0c, 0xc1, - 0x64, 0xa3, 0x24, 0xac, 0xcd, 0xdc, 0xa7, 0x94, 0xa0, 0x69, 0x44, 0x30, - 0x5e, 0x7c, 0x35, 0x4d, 0x5f, 0x6d, 0xe3, 0x1e, 0x75, 0xa2, 0x6e, 0xbf, - 0xa5, 0x57, 0xd5, 0xae, 0x98, 0x5d, 0x57, 0xf4, 0x88, 0xce, 0x18, 0xd7, - 0xf9, 0x10, 0xed, 0x7e, 0x26, 0xe4, 0x6d, 0xaf, 0xb0, 0x6b, 0x1d, 0xef, - 0x29, 0x41, 0x4c, 0x8c, 0x03, 0x03, 0x87, 0x03, 0xf8, 0x20, 0x21, 0x9c, - 0x3f, 0x80, 0x5f, 0x4d, 0x06, 0xf1, 0x2e, 0x63, 0x53, 0x41, 0xdc, 0x1b, - 0x79, 0x8e, 0x39, 0xdd, 0xfb, 0xfc, 0x9e, 0x1f, 0xd7, 0x71, 0x8d, 0xfa, - 0x73, 0xc6, 0x1b, 0x70, 0x65, 0xf2, 0x01, 0x5c, 0xdd, 0xaf, 0xe0, 0x84, - 0xf6, 0x00, 0x2e, 0x8f, 0x75, 0x62, 0xd9, 0x7e, 0x39, 0x87, 0x76, 0x2c, - 0xa4, 0x32, 0x36, 0x3c, 0x53, 0x6b, 0x76, 0xbd, 0xa8, 0xd7, 0x41, 0x2f, - 0xf7, 0xea, 0xed, 0xcc, 0x99, 0x04, 0xd3, 0x23, 0x36, 0xd9, 0x33, 0xd9, - 0xbb, 0x4e, 0x5c, 0xb5, 0x70, 0xfc, 0xee, 0xd8, 0x70, 0x0b, 0xc3, 0xe5, - 0x39, 0x82, 0x27, 0x0b, 0xf1, 0x7d, 0x26, 0xab, 0x3d, 0xbc, 0xcf, 0x45, - 0xec, 0x7b, 0x36, 0x5a, 0x80, 0xfc, 0xaa, 0x52, 0x2b, 0x97, 0x29, 0x8c, - 0x07, 0x70, 0x96, 0xba, 0x5b, 0x53, 0xe5, 0xe5, 0x77, 0x89, 0xbb, 0x41, - 0xe6, 0x2d, 0x15, 0xf8, 0xe0, 0xb6, 0x78, 0xfb, 0x7d, 0xf3, 0x49, 0x0b, - 0x9f, 0xeb, 0xe7, 0x09, 0xff, 0x7a, 0x3d, 0xf1, 0xeb, 0x1a, 0xc1, 0x69, - 0xa9, 0x21, 0x96, 0x6a, 0xda, 0x96, 0xbf, 0x80, 0xbc, 0x6f, 0x75, 0xe2, - 0x3f, 0x17, 0x93, 0x17, 0xbf, 0x18, 0xaa, 0x33, 0xca, 0xa0, 0xf1, 0xbe, - 0xa9, 0x65, 0x2a, 0x56, 0xf1, 0xaf, 0x9f, 0xf7, 0x05, 0x29, 0xc7, 0x75, - 0x33, 0xa5, 0xfa, 0xf8, 0xef, 0x05, 0x8c, 0xef, 0xdb, 0x71, 0x3e, 0x56, - 0xdf, 0x7e, 0x58, 0xb9, 0x66, 0x1a, 0x55, 0xb5, 0xfc, 0xad, 0x12, 0x17, - 0xa2, 0xde, 0xa9, 0x31, 0xd4, 0x7b, 0x66, 0x94, 0x83, 0xa6, 0xa1, 0xca, - 0xfe, 0xc8, 0x7a, 0x65, 0xfc, 0x62, 0x5e, 0xbf, 0x34, 0xcb, 0x0e, 0x6f, - 0xe5, 0x5d, 0xce, 0x9b, 0xf6, 0x27, 0xbc, 0xc4, 0x6c, 0x1a, 0xd5, 0xeb, - 0xd5, 0x1e, 0x62, 0x41, 0x44, 0xbd, 0x9b, 0xfd, 0x15, 0xd0, 0xfe, 0xc2, - 0xcc, 0x23, 0x4b, 0xa0, 0x5a, 0xf1, 0xa9, 0x15, 0xc9, 0x91, 0xd9, 0xdc, - 0x52, 0xec, 0x2e, 0xc3, 0x53, 0xdb, 0xcb, 0xba, 0x4f, 0x3a, 0x89, 0x45, - 0x09, 0xe2, 0x78, 0x9c, 0x38, 0x9e, 0x4f, 0x1c, 0xbf, 0xbe, 0xaf, 0x10, - 0xe7, 0xf7, 0x35, 0x22, 0x5d, 0x26, 0x63, 0xec, 0x70, 0x72, 0x75, 0xa9, - 0xec, 0x79, 0x85, 0x9a, 0xc1, 0x95, 0x72, 0x8e, 0x13, 0x82, 0x5f, 0x79, - 0x71, 0xe6, 0x59, 0xad, 0x76, 0x38, 0xac, 0x33, 0xf6, 0x73, 0x6e, 0xb3, - 0x3f, 0x97, 0x96, 0x8f, 0x96, 0x4a, 0xc1, 0x87, 0xd7, 0xe7, 0x49, 0x1c, - 0x7d, 0x9d, 0xb2, 0x9c, 0xa4, 0x4d, 0x6f, 0xd4, 0x57, 0x48, 0x5f, 0x8f, - 0xf7, 0xcb, 0x38, 0xc9, 0x6d, 0x4c, 0xec, 0xa6, 0x85, 0xd5, 0x55, 0x99, - 0x48, 0xe8, 0x61, 0xc6, 0xac, 0x10, 0x22, 0x65, 0x41, 0xc6, 0x2a, 0xf9, - 0xae, 0xe2, 0x0a, 0xf3, 0xb2, 0xf1, 0xa0, 0x82, 0x8f, 0xbe, 0x22, 0x5c, - 0xc0, 0xaf, 0x9f, 0x57, 0x84, 0x0b, 0xc8, 0x78, 0xc1, 0x88, 0x52, 0x0b, - 0x23, 0xf2, 0x2d, 0x5e, 0x34, 0xd7, 0xc2, 0x16, 0x79, 0x47, 0xa9, 0x86, - 0x71, 0xe7, 0xfe, 0x44, 0xfd, 0x94, 0xcf, 0x4e, 0x8e, 0xf6, 0x27, 0x5f, - 0x21, 0x37, 0xb3, 0x38, 0x02, 0xf1, 0x3e, 0x87, 0x0d, 0x72, 0xee, 0x76, - 0xb6, 0x3e, 0x72, 0xe7, 0x72, 0x3d, 0x19, 0xac, 0x2c, 0x15, 0x2e, 0xf7, - 0xff, 0xcc, 0xd6, 0xdb, 0xe4, 0xcf, 0xe1, 0xc8, 0x3f, 0xf0, 0xbb, 0x8c, - 0x17, 0xbf, 0xa3, 0x5d, 0xc4, 0x7f, 0x62, 0x3e, 0x6d, 0xf1, 0xb9, 0x97, - 0xe7, 0xc9, 0xf9, 0x43, 0xc7, 0xe0, 0xd0, 0x3c, 0x39, 0x6f, 0x65, 0x9b, - 0xc5, 0x0b, 0x32, 0xb1, 0xf6, 0x5d, 0x73, 0xad, 0x25, 0xeb, 0x91, 0xec, - 0x7d, 0x92, 0x43, 0x8b, 0x2c, 0x0a, 0x5e, 0xd1, 0xea, 0xd5, 0xb3, 0x28, - 0x16, 0x3c, 0x89, 0x48, 0x0f, 0xb3, 0x50, 0xf3, 0xb9, 0x8f, 0xf0, 0x6f, - 0x3f, 0xaf, 0xbf, 0xa1, 0x39, 0x1a, 0xb7, 0x42, 0xfa, 0xb6, 0x36, 0xee, - 0x55, 0xbd, 0xfb, 0x2c, 0xfc, 0x91, 0x7c, 0x65, 0xc6, 0x6c, 0xaf, 0x94, - 0x7b, 0x32, 0xfd, 0x5b, 0x28, 0x17, 0xad, 0xfa, 0x49, 0xc6, 0x66, 0x16, - 0xd0, 0x66, 0x04, 0xbb, 0x84, 0x8b, 0x2c, 0xe1, 0xda, 0x55, 0x8c, 0x4c, - 0x02, 0x79, 0x83, 0x2e, 0x8b, 0x1b, 0xa9, 0xb5, 0xb5, 0x9e, 0xcd, 0xf8, - 0xe7, 0x79, 0xf2, 0xee, 0xd1, 0x0e, 0x1d, 0xf7, 0xd8, 0xf0, 0xf6, 0x3d, - 0xb6, 0xf0, 0xca, 0x6f, 0x3d, 0xd4, 0x90, 0x37, 0x5f, 0xde, 0xff, 0x20, - 0xc3, 0x93, 0xfa, 0xad, 0x5b, 0x7a, 0x8d, 0xab, 0x19, 0xc3, 0x86, 0x99, - 0xe3, 0xaf, 0x0e, 0xfe, 0xd6, 0xfc, 0xa6, 0x23, 0xe2, 0xb1, 0xa3, 0xd6, - 0xd3, 0x8b, 0x1b, 0x66, 0xaa, 0x52, 0xae, 0xcb, 0x1c, 0xf2, 0x6e, 0xa1, - 0xf4, 0x4b, 0x4c, 0xf3, 0xde, 0x5a, 0x93, 0xf9, 0xb3, 0x6d, 0x95, 0x9d, - 0x7e, 0x91, 0xaf, 0x5d, 0x36, 0xeb, 0xaa, 0x6b, 0xdd, 0x36, 0xa5, 0x8e, - 0xd6, 0x51, 0x89, 0x57, 0x69, 0xbf, 0xaf, 0x4e, 0x4a, 0xcc, 0x53, 0x71, - 0x94, 0x7e, 0x3a, 0x56, 0xe7, 0xeb, 0xbc, 0xca, 0x5c, 0xf2, 0x43, 0x72, - 0xfc, 0x37, 0x35, 0x6f, 0xfb, 0x19, 0xa9, 0x3b, 0x86, 0x1c, 0x38, 0x17, - 0xbc, 0x61, 0xd5, 0x82, 0x63, 0x87, 0x54, 0x0c, 0x27, 0x32, 0xfe, 0xfe, - 0x1a, 0xfd, 0xf8, 0xd6, 0xd9, 0x05, 0x1d, 0x3d, 0x43, 0xe2, 0x1f, 0x0d, - 0x96, 0x1f, 0xdd, 0xaa, 0x15, 0x09, 0x5e, 0x8b, 0x5f, 0x6c, 0x90, 0xde, - 0x9d, 0x91, 0x02, 0xb9, 0xcc, 0xe0, 0x6a, 0x72, 0x60, 0x89, 0xb1, 0x01, - 0xe6, 0xbb, 0x0e, 0xfa, 0xcf, 0x19, 0xe6, 0x1e, 0x94, 0x2d, 0x6c, 0x9a, - 0xef, 0x32, 0x17, 0x1b, 0x41, 0xbd, 0x7a, 0x0a, 0xeb, 0xc8, 0x63, 0xc9, - 0x71, 0x26, 0x9b, 0xb1, 0xc7, 0xca, 0xa5, 0x7c, 0xea, 0xc3, 0xca, 0x52, - 0xae, 0xbf, 0x19, 0xdd, 0x63, 0x0b, 0x70, 0x80, 0xeb, 0x7a, 0x44, 0xff, - 0x2b, 0x94, 0x0f, 0x75, 0x77, 0x96, 0x53, 0x1f, 0x9f, 0x86, 0x8c, 0x0e, - 0x62, 0xfa, 0x96, 0x53, 0x4a, 0xfd, 0xfa, 0x98, 0xf2, 0x4d, 0xee, 0x87, - 0xd4, 0x47, 0x3c, 0xcc, 0xd3, 0x1f, 0x61, 0x3c, 0xfb, 0x33, 0xec, 0x56, - 0x95, 0x26, 0x5b, 0x58, 0x38, 0x22, 0xfc, 0xaa, 0x75, 0x76, 0xf0, 0xbf, - 0x40, 0x9f, 0xdb, 0xc0, 0x6b, 0x12, 0xd7, 0xe5, 0x5e, 0x39, 0x37, 0xde, - 0x89, 0x93, 0x69, 0xda, 0x75, 0xb4, 0x0f, 0xa7, 0xd2, 0xf2, 0x4c, 0xe1, - 0x58, 0x01, 0xc4, 0x86, 0xec, 0x98, 0xd0, 0x7d, 0x91, 0x52, 0xea, 0xa5, - 0x30, 0xe4, 0x8d, 0xac, 0x53, 0x02, 0xe4, 0x72, 0x69, 0x9c, 0xdb, 0xeb, - 0x6d, 0xaf, 0x63, 0xde, 0x18, 0x9d, 0x84, 0xfa, 0xdc, 0xf2, 0x34, 0xce, - 0x8e, 0x3e, 0x0e, 0x4f, 0xb5, 0xd7, 0xb3, 0x5a, 0x69, 0xc1, 0x8e, 0xc9, - 0x7f, 0xaf, 0xc6, 0xe4, 0xe1, 0xb3, 0x5b, 0x60, 0x50, 0xf7, 0xbb, 0xf0, - 0xad, 0xf9, 0xe2, 0xf3, 0xbd, 0x93, 0xc5, 0x58, 0xc4, 0x78, 0xf4, 0xb2, - 0x15, 0x67, 0x33, 0x7e, 0x54, 0xa3, 0x7d, 0x64, 0x3e, 0x95, 0x8d, 0xe1, - 0x7f, 0x58, 0x5f, 0x3f, 0x34, 0x23, 0xaa, 0xe8, 0x4b, 0xc6, 0xd5, 0xa0, - 0x80, 0xf3, 0xec, 0xce, 0xc6, 0xeb, 0x32, 0xed, 0x9f, 0xcc, 0xc7, 0xad, - 0x39, 0x56, 0xce, 0x97, 0x44, 0x61, 0xa7, 0x95, 0xe7, 0xcb, 0xba, 0x75, - 0x7c, 0x16, 0x95, 0x5a, 0x87, 0x8a, 0x53, 0xba, 0xe0, 0x48, 0x0b, 0x7d, - 0xd5, 0x89, 0x2d, 0x41, 0xba, 0xa3, 0x55, 0xf7, 0x9f, 0xc6, 0x9e, 0xe4, - 0xbf, 0x9a, 0xcf, 0xd3, 0x8e, 0xd6, 0x90, 0xc3, 0x78, 0x88, 0x03, 0x1b, - 0x43, 0x8f, 0x90, 0x87, 0x72, 0xcd, 0x09, 0x07, 0x31, 0x48, 0x41, 0xa2, - 0x91, 0xfe, 0x1f, 0x5a, 0x82, 0x29, 0xeb, 0xfe, 0x4f, 0xe7, 0x65, 0x6a, - 0x8b, 0x67, 0xe6, 0x67, 0x72, 0x43, 0xd1, 0xff, 0x7f, 0x44, 0x7f, 0xaf, - 0x99, 0x9e, 0x72, 0xd1, 0x9f, 0x03, 0x6e, 0xc6, 0xad, 0x03, 0xbc, 0xe7, - 0xc2, 0x5e, 0x07, 0x06, 0xb5, 0x16, 0x0c, 0x4e, 0xc2, 0xf3, 0x29, 0xef, - 0xf9, 0xf9, 0x68, 0xc7, 0xfc, 0x0c, 0x57, 0x78, 0x1b, 0xdd, 0xd1, 0x17, - 0xcc, 0x55, 0xe5, 0xb2, 0x5e, 0x39, 0xaf, 0xd3, 0xca, 0xfb, 0x73, 0x75, - 0xbe, 0xcd, 0xe6, 0x13, 0x56, 0x9c, 0x78, 0x71, 0xbe, 0xf4, 0xd7, 0x5e, - 0x4f, 0x98, 0xb8, 0xa2, 0xf7, 0x58, 0xb9, 0xb9, 0x60, 0x43, 0x6f, 0x42, - 0xf6, 0x56, 0x64, 0xfb, 0x66, 0x56, 0x1f, 0x13, 0x55, 0xb7, 0xcb, 0xbd, - 0x2a, 0x6b, 0xcb, 0xd2, 0xdf, 0xce, 0xf1, 0x7e, 0xb1, 0x65, 0xb1, 0x63, - 0xeb, 0xbd, 0x96, 0xa4, 0xbc, 0xd3, 0xb9, 0x41, 0xfd, 0x1d, 0x9f, 0x21, - 0x75, 0x96, 0x16, 0xce, 0x61, 0x9a, 0x9b, 0xf5, 0x7a, 0xcf, 0x29, 0xfc, - 0x31, 0x6d, 0x5b, 0xc7, 0xae, 0x21, 0xa9, 0xc3, 0x7a, 0x14, 0xc7, 0xbe, - 0x75, 0xb8, 0xc2, 0xf8, 0xbf, 0xc7, 0xb2, 0x43, 0xc1, 0x15, 0x91, 0x43, - 0xb0, 0xa5, 0x8d, 0x71, 0x5c, 0x6a, 0xdd, 0x46, 0xa4, 0x26, 0xdc, 0xa9, - 0x7c, 0x58, 0xd7, 0x89, 0x63, 0x21, 0xc3, 0x2c, 0xd5, 0xfc, 0xeb, 0x6b, - 0x6c, 0x28, 0x98, 0x6c, 0xc8, 0xc7, 0xf1, 0x90, 0xf0, 0x47, 0xb8, 0xd2, - 0x69, 0xaf, 0x31, 0xc7, 0xae, 0xba, 0xbe, 0x97, 0xce, 0x62, 0xa5, 0xad, - 0x7e, 0xbe, 0xe4, 0x50, 0x49, 0x0b, 0x47, 0xbe, 0x8a, 0x07, 0xad, 0xbd, - 0x55, 0x19, 0x43, 0xa5, 0x0e, 0x7c, 0x2c, 0x74, 0x2d, 0x2a, 0x98, 0x62, - 0x36, 0x35, 0x87, 0xea, 0xd5, 0x5d, 0xb8, 0x87, 0xd8, 0xd5, 0x84, 0x73, - 0xba, 0xf4, 0x3f, 0x8c, 0x6f, 0x3a, 0xac, 0xb3, 0x34, 0x47, 0x43, 0x3b, - 0xa2, 0x2b, 0x71, 0x60, 0xc8, 0x50, 0x9c, 0x61, 0x6f, 0x24, 0x46, 0x2e, - 0xc4, 0x1c, 0xdd, 0xaa, 0x03, 0x4a, 0x8d, 0x61, 0xb8, 0xa1, 0x13, 0xbb, - 0xf4, 0x7c, 0xf4, 0xea, 0x91, 0x82, 0x9e, 0xe5, 0x5d, 0x38, 0xa8, 0x17, - 0x1b, 0x8b, 0xc2, 0x06, 0x31, 0x5d, 0xdb, 0x92, 0x84, 0xbf, 0xe5, 0x32, - 0x39, 0xc7, 0x49, 0x78, 0x3b, 0x9a, 0xec, 0xc4, 0xdc, 0x15, 0x0e, 0x57, - 0x6c, 0xbc, 0x11, 0x89, 0xc9, 0x4a, 0xd7, 0xee, 0xf1, 0x20, 0xe2, 0x93, - 0xdc, 0x6f, 0xe6, 0xba, 0x8e, 0xf1, 0x95, 0xe4, 0xa0, 0xa2, 0x47, 0x3b, - 0x6d, 0xb1, 0x0e, 0xcf, 0xb5, 0x5e, 0x32, 0x9f, 0xf1, 0x0b, 0x7e, 0x2e, - 0xc0, 0x56, 0xd5, 0x67, 0x71, 0xca, 0x88, 0xed, 0x0f, 0xf9, 0x87, 0x9d, - 0x36, 0xf7, 0x7d, 0xd3, 0xf3, 0x75, 0xd1, 0x9b, 0x63, 0x01, 0x0a, 0x1f, - 0x21, 0x7e, 0xca, 0xbf, 0x45, 0x77, 0xa2, 0x43, 0x13, 0x9b, 0x74, 0xa9, - 0xf1, 0x35, 0xd0, 0x67, 0xdc, 0x78, 0x47, 0xbd, 0xb5, 0x0f, 0xcf, 0xea, - 0x3e, 0x7d, 0x0c, 0x52, 0xdb, 0x5b, 0xc1, 0x71, 0x52, 0x83, 0x69, 0xc4, - 0x4b, 0xd9, 0x9c, 0xc3, 0x63, 0x2b, 0x22, 0xee, 0xe6, 0xe2, 0x88, 0x5c, - 0xf7, 0x26, 0x23, 0xb4, 0xd3, 0x6d, 0xc1, 0x19, 0x33, 0x52, 0x6e, 0x74, - 0xca, 0xf9, 0x15, 0x77, 0x78, 0xba, 0xd3, 0x5d, 0xe7, 0xed, 0x98, 0x51, - 0x80, 0x73, 0x31, 0xc6, 0x61, 0xeb, 0x7f, 0xb1, 0x28, 0x73, 0x3b, 0x31, - 0x12, 0x5c, 0x88, 0xf6, 0x36, 0x79, 0x56, 0x33, 0xfa, 0xf6, 0x9b, 0x66, - 0x71, 0xc8, 0xa7, 0xa6, 0xe1, 0xc4, 0xc3, 0x41, 0x3b, 0x2e, 0xa9, 0x26, - 0x1c, 0xa1, 0x7f, 0x35, 0xc7, 0x19, 0x1f, 0x47, 0xe9, 0x27, 0xbb, 0x69, - 0x63, 0xf2, 0xbe, 0x8f, 0x9f, 0x7e, 0x12, 0xa7, 0x9f, 0x9c, 0x0b, 0xdd, - 0x97, 0x7d, 0x5f, 0x50, 0x23, 0xaf, 0x98, 0x46, 0xd3, 0x90, 0x8a, 0x4f, - 0x57, 0x4c, 0x23, 0x34, 0x92, 0x93, 0x5d, 0xfc, 0x32, 0x27, 0xbf, 0xf4, - 0x11, 0x45, 0x76, 0x91, 0x51, 0xd6, 0x22, 0xff, 0xce, 0x5d, 0xcb, 0xfd, - 0x26, 0x71, 0xd6, 0x89, 0x56, 0x6b, 0x6d, 0x7f, 0x56, 0x93, 0xc1, 0x8c, - 0xdc, 0x9a, 0x2e, 0xb9, 0x6f, 0xff, 0x7e, 0xe2, 0x8e, 0xeb, 0x2b, 0xee, - 0xb8, 0xbe, 0x71, 0xde, 0xed, 0xdf, 0x73, 0x3e, 0x71, 0x4b, 0xaf, 0x1d, - 0xba, 0x6f, 0xea, 0x18, 0xd7, 0x3a, 0x67, 0xc9, 0x98, 0x79, 0xa9, 0x4c, - 0x64, 0x91, 0x3c, 0x36, 0x23, 0xeb, 0xaa, 0xf1, 0xd9, 0xb2, 0xbe, 0x95, - 0xed, 0x19, 0x58, 0x67, 0x7c, 0xe9, 0x37, 0x1a, 0x7e, 0x78, 0xdb, 0xb9, - 0x43, 0xb1, 0xb5, 0x80, 0xd2, 0x17, 0x93, 0xf7, 0x33, 0x0b, 0xad, 0x77, - 0xac, 0x55, 0xbf, 0x81, 0x22, 0xbf, 0xb6, 0x65, 0x8e, 0xad, 0x0b, 0xce, - 0xa5, 0x5a, 0xc7, 0xb7, 0x94, 0x24, 0xe2, 0xe3, 0xde, 0xc0, 0x18, 0x75, - 0x15, 0x1b, 0xbf, 0xce, 0x5c, 0xbb, 0x0b, 0xcf, 0x85, 0x1c, 0x46, 0x61, - 0x58, 0xce, 0x82, 0xae, 0xc2, 0xae, 0x91, 0xbf, 0xc2, 0xe6, 0xa4, 0x70, - 0xfc, 0x05, 0xe8, 0x99, 0xb4, 0xe1, 0x04, 0xed, 0xbb, 0x8f, 0xcf, 0x21, - 0xfe, 0xb9, 0x53, 0x90, 0xf7, 0x6b, 0x1a, 0x98, 0x37, 0xeb, 0xd6, 0x67, - 0xc7, 0xc8, 0xcf, 0xb0, 0x39, 0x6a, 0xe2, 0x53, 0x9d, 0xb1, 0x47, 0x13, - 0xf9, 0x1c, 0xd0, 0xca, 0x5b, 0x2d, 0x2c, 0x7d, 0x32, 0xce, 0xfd, 0xac, - 0x16, 0x5f, 0x5d, 0x49, 0x9f, 0x55, 0xf0, 0x99, 0xf4, 0x27, 0xcb, 0x29, - 0x33, 0xb9, 0xe1, 0xf1, 0xe8, 0x76, 0x8c, 0x5a, 0xfd, 0x67, 0xad, 0xaf, - 0xc6, 0x1e, 0x79, 0xb1, 0x8c, 0x3c, 0x3b, 0xa1, 0xfb, 0xdb, 0x2f, 0x28, - 0xf0, 0x94, 0x84, 0xfd, 0x8c, 0x33, 0x5f, 0xe2, 0x37, 0xba, 0xd4, 0xd8, - 0x74, 0xd7, 0x5a, 0xda, 0xfb, 0xbe, 0x91, 0x80, 0x55, 0x33, 0xf8, 0xe1, - 0x5d, 0x6b, 0x1a, 0x99, 0x77, 0xab, 0x33, 0xf5, 0xc7, 0x9f, 0xe1, 0x48, - 0xda, 0x85, 0xa7, 0xe2, 0x1e, 0x65, 0xd1, 0x3e, 0x15, 0x0f, 0xc5, 0xbd, - 0x53, 0x4d, 0x76, 0xf2, 0x8f, 0x65, 0x73, 0x38, 0x9f, 0x82, 0x1f, 0x2c, - 0x95, 0x58, 0xf0, 0x47, 0x30, 0xaa, 0x23, 0x9c, 0x13, 0xc5, 0x79, 0xcb, - 0xbd, 0xea, 0x11, 0x9b, 0xcf, 0xfd, 0x1b, 0xec, 0x80, 0x7d, 0xfc, 0x11, - 0x74, 0x53, 0xfe, 0x35, 0x71, 0xe9, 0x69, 0xd5, 0x03, 0x65, 0xcd, 0xd8, - 0x3d, 0x26, 0xbe, 0x09, 0xa3, 0x2a, 0x0c, 0x4f, 0x65, 0xd8, 0xbf, 0x10, - 0x85, 0x5f, 0x92, 0x6b, 0x4f, 0x4b, 0xfe, 0xb9, 0xa5, 0xd4, 0x66, 0x32, - 0x7f, 0xb9, 0x2f, 0xdb, 0xab, 0x58, 0x89, 0x1d, 0x43, 0x52, 0x87, 0x27, - 0x6e, 0xeb, 0xcc, 0x83, 0xca, 0xb4, 0xc0, 0x46, 0x9b, 0xf4, 0x87, 0xb6, - 0xc3, 0x17, 0xdb, 0x8e, 0x40, 0x4c, 0x7c, 0x56, 0x53, 0x3b, 0x10, 0x39, - 0x2b, 0xb5, 0xbf, 0x45, 0x21, 0x3f, 0xe5, 0xf2, 0xf7, 0x55, 0xda, 0x75, - 0xd7, 0x6b, 0x13, 0x2a, 0xa6, 0xd4, 0x4c, 0x1e, 0x39, 0x96, 0xd4, 0xd6, - 0xe7, 0xdb, 0xe4, 0x0c, 0xc5, 0x55, 0xeb, 0x3d, 0xeb, 0x88, 0xed, 0x9f, - 0x89, 0x47, 0xcd, 0x18, 0xd8, 0xff, 0x3e, 0x63, 0x90, 0x3c, 0xe3, 0x77, - 0xcc, 0xaf, 0x9d, 0x58, 0xdd, 0xe6, 0xc1, 0x83, 0x71, 0xa9, 0x9d, 0xae, - 0xaf, 0xca, 0x9c, 0x01, 0x91, 0xef, 0x0e, 0x74, 0xe8, 0x04, 0xd9, 0xea, - 0x2f, 0xcc, 0x4a, 0x2b, 0x2f, 0xfd, 0xbf, 0x19, 0x9b, 0x49, 0xe4, 0x2d, - 0x14, 0x1f, 0xef, 0x9d, 0x64, 0x02, 0x69, 0xd9, 0x5d, 0x15, 0xbf, 0xcb, - 0x5c, 0xda, 0x81, 0xed, 0xd8, 0x56, 0x25, 0x7c, 0xe6, 0xc9, 0x89, 0xd9, - 0xf7, 0xe7, 0xea, 0x32, 0x95, 0x59, 0x4e, 0x95, 0xb3, 0x37, 0xe9, 0x05, - 0x46, 0x94, 0x27, 0xa2, 0x2d, 0xca, 0xda, 0xa8, 0xf4, 0x03, 0x6d, 0xd1, - 0x22, 0x72, 0x18, 0xdf, 0x52, 0x13, 0xdf, 0x0e, 0x1d, 0x57, 0x76, 0x5a, - 0xe7, 0x66, 0xe5, 0xac, 0x2b, 0x50, 0x3e, 0xd1, 0xac, 0xec, 0x8a, 0x7e, - 0x62, 0x6e, 0xb4, 0x7a, 0xf0, 0x79, 0xd6, 0x79, 0x9c, 0xfc, 0x09, 0x17, - 0xca, 0x8e, 0xc8, 0xf9, 0x41, 0x0d, 0x15, 0x13, 0x8f, 0x91, 0xb7, 0x0a, - 0xd7, 0x31, 0x5a, 0x1c, 0xd6, 0xb9, 0xb6, 0xe6, 0x97, 0x72, 0xe7, 0xda, - 0x1c, 0x31, 0x79, 0x1b, 0xd9, 0xfa, 0x8f, 0xb9, 0xd2, 0x51, 0xe6, 0x4a, - 0x66, 0xd3, 0xb7, 0x43, 0xc6, 0xee, 0x0a, 0x78, 0x03, 0xe5, 0x36, 0xc3, - 0x94, 0x7a, 0xce, 0x6b, 0x24, 0x8c, 0xeb, 0x6a, 0x0d, 0x3c, 0x5c, 0x2b, - 0xef, 0x1f, 0xca, 0xbb, 0xc7, 0x5d, 0x38, 0x1a, 0xea, 0xc2, 0x2f, 0xf5, - 0x2e, 0xec, 0xd1, 0xe5, 0x4c, 0x43, 0x31, 0x65, 0xd5, 0xa6, 0xa2, 0xd0, - 0xf4, 0xb4, 0xa2, 0x9d, 0xb9, 0x0e, 0xef, 0x01, 0x9f, 0xe2, 0x35, 0x56, - 0x29, 0x1a, 0xae, 0x8e, 0x7b, 0x67, 0x4a, 0xe9, 0x03, 0x37, 0xc6, 0x03, - 0x98, 0x21, 0xae, 0x26, 0x27, 0xe5, 0xfc, 0xc9, 0x02, 0x0c, 0x4d, 0x7e, - 0x4d, 0xb8, 0x81, 0x41, 0x4c, 0xb2, 0xce, 0x48, 0x3e, 0x2f, 0xbd, 0x4e, - 0x67, 0x30, 0xcb, 0x61, 0x0c, 0x65, 0x53, 0x43, 0x09, 0x6e, 0x30, 0x3a, - 0xfd, 0x6d, 0xba, 0x93, 0xf9, 0x1c, 0xde, 0xa8, 0x81, 0xfd, 0x3b, 0x6e, - 0xd4, 0x25, 0xe7, 0xe0, 0x44, 0x5d, 0x39, 0xf2, 0x70, 0x6c, 0xf4, 0x45, - 0x72, 0xfc, 0xee, 0xf6, 0x52, 0xe6, 0xa7, 0x13, 0xa3, 0x4e, 0xa4, 0x52, - 0x52, 0x73, 0xb0, 0x7a, 0x96, 0xd3, 0x0e, 0xfa, 0x52, 0x7f, 0x02, 0x75, - 0x35, 0x61, 0x7f, 0xb2, 0xc6, 0xae, 0x72, 0x8e, 0x4a, 0xa4, 0xd2, 0x1a, - 0x3f, 0x01, 0x7e, 0x82, 0xfc, 0x34, 0xe2, 0xdb, 0xf4, 0xd9, 0x32, 0xe2, - 0xed, 0xf7, 0xd3, 0x25, 0xf8, 0x24, 0xa9, 0x05, 0x74, 0xda, 0xc1, 0x28, - 0x73, 0x04, 0xc3, 0xd2, 0x53, 0x09, 0xae, 0xd3, 0x4f, 0x5f, 0x0e, 0x95, - 0xc0, 0x4c, 0xdd, 0x2d, 0x27, 0x94, 0xdc, 0x16, 0x6a, 0x61, 0x58, 0xf8, - 0xe2, 0x31, 0x25, 0x95, 0x3d, 0xf3, 0xf5, 0xea, 0x38, 0xda, 0xcb, 0xc3, - 0xae, 0xe0, 0xea, 0xb8, 0xfd, 0x13, 0x79, 0x9f, 0x75, 0x43, 0x83, 0xbc, - 0xf3, 0xe4, 0x0a, 0x3e, 0x3d, 0xe1, 0x0a, 0xae, 0x8f, 0x1f, 0x53, 0x28, - 0xcf, 0x81, 0x1a, 0xbb, 0x2b, 0xf8, 0xe4, 0xc4, 0xb1, 0x85, 0x99, 0xbc, - 0x0f, 0xca, 0xd3, 0xb5, 0x06, 0x6d, 0x8c, 0x79, 0xef, 0x32, 0xe9, 0xcb, - 0x68, 0x9d, 0x57, 0xec, 0x85, 0x46, 0x4d, 0xd8, 0xeb, 0xa9, 0xb1, 0xcb, - 0xd9, 0x90, 0x69, 0xc4, 0x93, 0xf2, 0xae, 0x97, 0xd8, 0xfe, 0x3f, 0x99, - 0x46, 0x99, 0x9c, 0xf5, 0xe8, 0x44, 0x5c, 0x2b, 0x67, 0xee, 0x24, 0x67, - 0xcd, 0x8f, 0x86, 0xa2, 0xb1, 0x62, 0x79, 0x77, 0xb6, 0xe9, 0x7b, 0x21, - 0x6f, 0xcb, 0xa0, 0x62, 0x3c, 0x5e, 0x04, 0xd9, 0xd7, 0x2e, 0xe2, 0xb7, - 0xa6, 0x3a, 0x15, 0x6f, 0x63, 0x0f, 0x02, 0x38, 0x91, 0x16, 0x5d, 0x07, - 0xe5, 0x8c, 0xba, 0xa5, 0xeb, 0x5b, 0x67, 0xae, 0x33, 0xb6, 0xb3, 0x2d, - 0xea, 0xe0, 0x5f, 0xb1, 0x17, 0x1b, 0x63, 0x0a, 0xe3, 0x8a, 0x65, 0x33, - 0xb7, 0x64, 0x5c, 0x57, 0xdb, 0x85, 0xc9, 0x50, 0xa1, 0xbc, 0x77, 0xcd, - 0xb8, 0xee, 0x0d, 0x7c, 0xa2, 0x58, 0xf1, 0xdc, 0x28, 0x62, 0x9c, 0x7d, - 0x61, 0xfc, 0xef, 0xcc, 0xf6, 0x6a, 0xc1, 0x2b, 0x3b, 0xc7, 0x5e, 0xc7, - 0x6b, 0xa9, 0x5b, 0xe3, 0x5a, 0x38, 0xae, 0x90, 0xe3, 0x8a, 0xc2, 0x92, - 0x3b, 0x7a, 0xf5, 0xb5, 0x8a, 0xe6, 0x29, 0x50, 0xa4, 0x57, 0xa6, 0xe1, - 0xbd, 0xf4, 0xe4, 0x42, 0xc9, 0x79, 0x7b, 0x27, 0xcb, 0xb1, 0x6e, 0xaf, - 0xd9, 0xb4, 0x68, 0xa9, 0xd9, 0x94, 0x0e, 0x45, 0xcd, 0x97, 0xab, 0x64, - 0x4f, 0xa5, 0xff, 0x27, 0x63, 0x34, 0xd5, 0xc7, 0x5c, 0xf3, 0x6b, 0x7a, - 0x6f, 0xf6, 0xcc, 0x2e, 0xed, 0x9a, 0xcf, 0x38, 0x9d, 0x12, 0x3b, 0xd9, - 0xd1, 0xee, 0x62, 0x3e, 0x2a, 0xef, 0x87, 0x1e, 0xe5, 0xfe, 0x1f, 0x49, - 0xfd, 0xcd, 0x42, 0x39, 0xc3, 0x2e, 0x67, 0x08, 0x80, 0xff, 0x0f, 0x1d, - 0xab, 0x22, 0x97, 0x70, 0x78, 0x00, 0x00, 0x00 }; + 0xec, 0x5c, 0x7d, 0x70, 0x1c, 0xe5, 0x79, 0xff, 0xbd, 0x7b, 0x7b, 0xd2, + 0x4a, 0x3a, 0x9d, 0x56, 0xa7, 0x93, 0x7c, 0x22, 0x04, 0xef, 0xa2, 0x3d, + 0xf9, 0xb0, 0x0c, 0xec, 0x9d, 0x4f, 0xb6, 0xa0, 0xdb, 0xb2, 0x83, 0x0d, + 0x11, 0x21, 0x13, 0x84, 0x4d, 0x52, 0x33, 0x49, 0x27, 0x37, 0xc6, 0x18, + 0x81, 0x4d, 0x70, 0x0d, 0x6d, 0x55, 0x86, 0x19, 0x6f, 0x2c, 0x7f, 0x01, + 0x27, 0x9d, 0x62, 0x64, 0x63, 0xd2, 0x0e, 0x68, 0x6c, 0x59, 0x08, 0x7c, + 0xd2, 0x61, 0x20, 0xad, 0xe8, 0x84, 0xfa, 0x26, 0xd8, 0xe0, 0x94, 0xcf, + 0x21, 0x0c, 0xc3, 0x1f, 0xcd, 0xa0, 0x62, 0x3e, 0xcc, 0x94, 0xa1, 0x26, + 0x38, 0xa9, 0xdd, 0xb8, 0x7e, 0xfb, 0x3c, 0x7b, 0x3a, 0x9b, 0x90, 0x26, + 0x9d, 0xfc, 0xd1, 0xff, 0xf6, 0x99, 0xb9, 0xb9, 0xbd, 0x77, 0xdf, 0xf7, + 0xf9, 0xfe, 0x7c, 0x3d, 0xf2, 0x5f, 0x47, 0x50, 0x8f, 0x39, 0x68, 0xa4, + 0x4f, 0x76, 0xc3, 0xc0, 0xc6, 0xf4, 0x65, 0x4b, 0x2e, 0xa3, 0xc7, 0xee, + 0x50, 0x53, 0x8d, 0xca, 0xeb, 0x02, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, + 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, + 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, + 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, + 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, + 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0xfc, 0x7f, 0x40, 0x08, 0xd0, + 0xf9, 0xbb, 0x71, 0xee, 0x03, 0x4d, 0x71, 0xdc, 0x7b, 0xaf, 0xb6, 0xa0, + 0x85, 0x9c, 0x99, 0x7b, 0x6f, 0xb1, 0x00, 0xb7, 0xd8, 0x65, 0x2c, 0xc3, + 0x7f, 0x4b, 0x2f, 0xae, 0x82, 0xd7, 0xbf, 0xea, 0x9c, 0x79, 0xec, 0xf9, + 0xa5, 0xe6, 0x89, 0xb1, 0x10, 0x34, 0xdd, 0x79, 0x27, 0xad, 0x77, 0x42, + 0xbb, 0x90, 0xce, 0xfc, 0xfd, 0x82, 0x95, 0x31, 0x44, 0xab, 0xb8, 0xe0, + 0x29, 0x8e, 0x94, 0xfb, 0x6d, 0x89, 0x17, 0x6d, 0x4f, 0x2c, 0xcb, 0xc2, + 0xd3, 0x9c, 0x19, 0x51, 0x37, 0x74, 0x56, 0x1a, 0xe1, 0x0a, 0xe5, 0x35, + 0x45, 0x05, 0xaa, 0xa5, 0xe1, 0xd6, 0xf1, 0x7a, 0xac, 0x1d, 0x6b, 0xc0, + 0x9a, 0xb1, 0x04, 0x6e, 0x2b, 0x42, 0x0f, 0x39, 0x1a, 0x66, 0x43, 0x33, + 0x22, 0x34, 0x85, 0x5c, 0xd8, 0x39, 0x75, 0xc3, 0xde, 0xfc, 0x59, 0xe9, + 0xfa, 0x7f, 0x63, 0x52, 0xbe, 0x61, 0xdc, 0x7f, 0x0f, 0x45, 0x75, 0x0e, + 0xd3, 0x33, 0xef, 0x3b, 0x75, 0xc3, 0xbe, 0xe2, 0x71, 0xf9, 0xfc, 0x82, + 0x38, 0x0e, 0x95, 0x74, 0x3c, 0x55, 0xda, 0x4f, 0x3c, 0x98, 0x9e, 0x07, + 0xcd, 0x53, 0x1d, 0x0f, 0x5b, 0xb3, 0x61, 0x4c, 0x8c, 0x9c, 0x95, 0x21, + 0xcb, 0x34, 0xa0, 0x58, 0xfa, 0x0b, 0xa0, 0x7d, 0x05, 0xda, 0x57, 0x08, + 0x63, 0xef, 0x58, 0x29, 0x86, 0xfa, 0x04, 0x9e, 0x5f, 0xc0, 0xe7, 0xf9, + 0x2c, 0xe3, 0x78, 0x3b, 0x5a, 0x3d, 0x5f, 0x43, 0xe7, 0x8f, 0x64, 0x81, + 0xf1, 0x91, 0x3e, 0x3a, 0x2a, 0x31, 0x68, 0xd7, 0x62, 0xb5, 0x0e, 0xaf, + 0xce, 0x61, 0x5c, 0x55, 0x3c, 0x9e, 0x30, 0xa6, 0x8e, 0x34, 0x55, 0xf0, + 0x40, 0x68, 0x16, 0xbc, 0xda, 0x2f, 0xbd, 0x3f, 0x5e, 0xac, 0xbe, 0xdf, + 0x41, 0x74, 0x34, 0xd2, 0xc3, 0x06, 0xfc, 0x73, 0xa9, 0x1f, 0xff, 0x50, + 0xca, 0xe1, 0xd9, 0x52, 0x1f, 0xd1, 0xbd, 0x87, 0xe8, 0xae, 0xc7, 0x3f, + 0x96, 0xd6, 0xe0, 0xc7, 0xa5, 0xef, 0xe2, 0x99, 0xd2, 0x2a, 0x3c, 0x5d, + 0xba, 0x09, 0x07, 0x4b, 0x1e, 0xc2, 0xdd, 0x8c, 0x2f, 0x25, 0x3e, 0xcb, + 0xd7, 0x11, 0x1f, 0x5b, 0x30, 0x5b, 0x64, 0x79, 0x24, 0x46, 0x6c, 0x73, + 0x0c, 0x58, 0x90, 0xa8, 0x81, 0xc0, 0x6a, 0xdb, 0x7c, 0x0a, 0xb8, 0x0d, + 0x6e, 0xdc, 0x3c, 0xc1, 0x5a, 0x7a, 0x62, 0xc4, 0x40, 0x98, 0xf8, 0xb5, + 0xd2, 0x6d, 0xd8, 0xaa, 0xf7, 0xa1, 0xde, 0x1a, 0xc2, 0x03, 0xbe, 0x8d, + 0xa1, 0x45, 0x9c, 0x7f, 0x45, 0x7e, 0x48, 0xe0, 0xc1, 0x24, 0x34, 0x41, + 0xcf, 0x5d, 0xc5, 0xbf, 0x6b, 0xa9, 0xd8, 0x8c, 0x78, 0x28, 0x10, 0x5f, + 0x05, 0xe2, 0xa3, 0x40, 0xbc, 0x15, 0x88, 0x97, 0x02, 0xf1, 0x57, 0x20, + 0x7e, 0x0a, 0xc4, 0x4f, 0x81, 0xf8, 0x29, 0x10, 0xaf, 0x05, 0xd6, 0xf9, + 0x00, 0xc9, 0x52, 0xb1, 0x71, 0xab, 0x63, 0x63, 0xac, 0xd4, 0x26, 0xf6, + 0xee, 0x56, 0xc5, 0x73, 0xc3, 0x06, 0xe6, 0x3b, 0x88, 0x3c, 0xbd, 0xc4, + 0x2a, 0x5f, 0x15, 0xea, 0x9a, 0x49, 0xc0, 0x4d, 0xcf, 0x83, 0x8d, 0x89, + 0x92, 0x2a, 0xa6, 0x87, 0xa5, 0x5c, 0x69, 0xbb, 0x68, 0x72, 0xcc, 0x9e, + 0x8d, 0x8a, 0xd5, 0xff, 0xba, 0x68, 0xc4, 0x2f, 0x47, 0x7a, 0x31, 0xd6, + 0xec, 0xe2, 0x70, 0xd6, 0xc0, 0xb2, 0x8c, 0x82, 0x5c, 0xdc, 0xc3, 0xb6, + 0xac, 0x69, 0x7b, 0x18, 0x45, 0x39, 0xce, 0xe7, 0x34, 0xd2, 0xb5, 0x87, + 0x64, 0xb7, 0x86, 0xc9, 0x11, 0x17, 0x35, 0xe9, 0x1a, 0x94, 0xfb, 0x58, + 0x7f, 0x2a, 0xc9, 0xb4, 0x0f, 0xf5, 0xb1, 0x18, 0x1a, 0xac, 0x4b, 0xd0, + 0x10, 0xe3, 0x35, 0x88, 0x56, 0xd2, 0xd5, 0x3c, 0xe7, 0x02, 0xf1, 0xf9, + 0xee, 0x28, 0x3e, 0x1d, 0xd5, 0x50, 0xda, 0xa9, 0xe2, 0x1b, 0x19, 0x29, + 0xff, 0x2a, 0xa3, 0xf6, 0x7f, 0x2a, 0x1c, 0x4c, 0x95, 0x54, 0x7c, 0x9e, + 0x4f, 0xc3, 0x6b, 0xd6, 0xf0, 0x9f, 0x79, 0x0f, 0x21, 0xc2, 0x3b, 0x40, + 0x78, 0x6b, 0x17, 0xa7, 0x30, 0x1b, 0x67, 0x71, 0xfa, 0xb0, 0x31, 0xdf, + 0xb1, 0x63, 0xa3, 0x52, 0x03, 0xa3, 0x06, 0x64, 0xff, 0x2c, 0x36, 0xe5, + 0x3b, 0x8e, 0x6e, 0x52, 0xb6, 0xe0, 0xe2, 0x5a, 0x0d, 0x9b, 0x87, 0x79, + 0x6d, 0x39, 0xca, 0x45, 0x41, 0xfe, 0xf0, 0xc7, 0xea, 0x6b, 0x26, 0x42, + 0x7e, 0x65, 0xfc, 0xf1, 0x7a, 0x4e, 0x34, 0xa2, 0xde, 0x34, 0xca, 0x58, + 0x1f, 0xe7, 0xf3, 0x39, 0xe5, 0x5d, 0xe9, 0xc6, 0x99, 0x0f, 0xcd, 0x0b, + 0x91, 0x6e, 0x6e, 0xc9, 0x66, 0xb1, 0x26, 0xdf, 0xa1, 0xaf, 0x51, 0x48, + 0xdb, 0x6a, 0xc5, 0xc6, 0x71, 0x07, 0xe9, 0xd1, 0x61, 0x81, 0x91, 0x4e, + 0xb6, 0x31, 0xd2, 0x76, 0xd1, 0x8f, 0x09, 0xc3, 0x50, 0x2a, 0x31, 0xf1, + 0x58, 0x36, 0x89, 0xb3, 0x0f, 0xf1, 0x6f, 0x15, 0x3f, 0x5b, 0x9a, 0xc4, + 0xc7, 0xfb, 0x4a, 0x73, 0x71, 0xfb, 0x68, 0xa4, 0xb2, 0xef, 0x1a, 0xa2, + 0xc9, 0x32, 0x32, 0xae, 0xc9, 0x7b, 0x47, 0x3b, 0x6b, 0xe9, 0x77, 0xc5, + 0xd6, 0xfd, 0xf9, 0x0e, 0xbb, 0x5f, 0xd1, 0x50, 0x4e, 0x44, 0x48, 0xf7, + 0xd0, 0xea, 0x08, 0xff, 0x25, 0x43, 0x67, 0xb0, 0x22, 0x63, 0x4e, 0xf2, + 0xdf, 0x80, 0x25, 0x93, 0x15, 0x9a, 0xc9, 0xa2, 0x8d, 0x03, 0x25, 0x1b, + 0x77, 0xe4, 0x3b, 0xdc, 0x95, 0x62, 0x16, 0x68, 0x5f, 0x98, 0x9b, 0x54, + 0x7e, 0x21, 0xbd, 0x56, 0xa6, 0xb3, 0x10, 0x93, 0xb1, 0x8e, 0x81, 0x49, + 0xc5, 0xdc, 0xd3, 0xaf, 0x48, 0xf9, 0xab, 0xb4, 0x82, 0xaf, 0x65, 0xb2, + 0x98, 0xd5, 0x75, 0xdc, 0x9c, 0xd1, 0xbc, 0x16, 0xe2, 0x71, 0xc3, 0x12, + 0x0d, 0x17, 0xed, 0x74, 0xf1, 0xf6, 0xe2, 0x9f, 0xa3, 0xbc, 0x82, 0x75, + 0xcf, 0x7c, 0xb1, 0x1c, 0x09, 0xc4, 0xac, 0x3a, 0xc4, 0xf6, 0x86, 0x31, + 0x6f, 0xe7, 0x59, 0x99, 0xb0, 0x78, 0xdd, 0x9a, 0x3c, 0xa5, 0xb0, 0x0c, + 0x61, 0xb4, 0xee, 0xbd, 0x82, 0x72, 0x8a, 0x99, 0x02, 0xbe, 0x16, 0xe7, + 0xbd, 0x35, 0x56, 0x55, 0x96, 0x08, 0x76, 0xef, 0xac, 0xc8, 0xff, 0x68, + 0xb6, 0x07, 0x2f, 0x15, 0xb0, 0xaf, 0x0d, 0x3f, 0xc0, 0xc8, 0x12, 0xce, + 0x4f, 0x8c, 0x63, 0x88, 0x64, 0xff, 0xc1, 0x89, 0x70, 0xa6, 0x6a, 0xe3, + 0xea, 0x39, 0x81, 0x6f, 0x5e, 0x29, 0xf0, 0x6a, 0x7a, 0x5a, 0x8e, 0xb5, + 0x32, 0xbf, 0x0f, 0x37, 0x56, 0xfe, 0x16, 0xae, 0xee, 0x94, 0x8b, 0x36, + 0xa2, 0x55, 0xdd, 0xc7, 0x38, 0x2e, 0x69, 0x25, 0xfd, 0xa5, 0x66, 0xf1, + 0x5f, 0x11, 0xd4, 0xb3, 0x9d, 0xef, 0x96, 0x46, 0x4b, 0x85, 0xe6, 0xfd, + 0x44, 0xb3, 0x63, 0x48, 0xc5, 0xe6, 0x7c, 0xc7, 0xa9, 0xf7, 0x94, 0xef, + 0xcb, 0xd9, 0xf9, 0x4c, 0xa7, 0xc3, 0x3e, 0xa6, 0x08, 0xfc, 0x54, 0x35, + 0x67, 0x72, 0x48, 0x60, 0xb2, 0x04, 0xaf, 0xdd, 0xd1, 0x29, 0xfe, 0xe3, + 0x94, 0x07, 0x0c, 0xd1, 0xf9, 0xb0, 0x8d, 0x85, 0x43, 0xdf, 0x85, 0xb5, + 0xcb, 0xc1, 0x4c, 0xc1, 0xc6, 0x54, 0x41, 0xca, 0xed, 0xb6, 0x94, 0xef, + 0xda, 0xe6, 0x86, 0xe3, 0x21, 0xb8, 0x97, 0x2f, 0xed, 0x4a, 0xd5, 0x86, + 0x54, 0xd6, 0x4d, 0xee, 0x75, 0x91, 0x5c, 0xb5, 0x5f, 0xf4, 0xe2, 0x89, + 0x92, 0x81, 0x62, 0x29, 0x85, 0x27, 0x4b, 0xac, 0x7f, 0x8b, 0xbe, 0x17, + 0x51, 0x7c, 0x66, 0x29, 0xb7, 0x30, 0xbf, 0x3a, 0xc6, 0x17, 0xd8, 0x98, + 0x2c, 0x28, 0x08, 0x91, 0xce, 0x73, 0x3a, 0xed, 0x2f, 0x9c, 0x25, 0xdb, + 0x69, 0xe8, 0xf8, 0xa1, 0x8b, 0xdb, 0xed, 0x16, 0x18, 0x37, 0x5a, 0x18, + 0x2f, 0x68, 0x94, 0xbb, 0x55, 0xf4, 0xe6, 0xc7, 0x31, 0xaf, 0x39, 0x4e, + 0xb1, 0x26, 0xb0, 0x2a, 0x13, 0x01, 0x56, 0xf2, 0xbb, 0x08, 0xda, 0xad, + 0x32, 0xda, 0x63, 0x8d, 0x98, 0xbf, 0xf0, 0x9f, 0x30, 0xdb, 0x12, 0x25, + 0x1d, 0xd7, 0x93, 0x1e, 0x04, 0x54, 0xb2, 0x53, 0x9b, 0x65, 0x11, 0x4e, + 0x01, 0x2b, 0x49, 0x7b, 0x29, 0x7e, 0x13, 0x24, 0x7b, 0x78, 0x69, 0x1c, + 0x8f, 0x13, 0xff, 0xa5, 0xbc, 0x94, 0x91, 0xac, 0xb9, 0x61, 0x3b, 0xe5, + 0x84, 0xe9, 0x62, 0x0f, 0x4a, 0xa5, 0x6f, 0x62, 0x6a, 0x84, 0xf8, 0xcc, + 0x3b, 0xc4, 0x93, 0xaa, 0x17, 0x85, 0xd9, 0xb7, 0x5a, 0x64, 0xf1, 0x24, + 0xf9, 0xce, 0x44, 0xc1, 0x34, 0x8e, 0x93, 0x9f, 0xbd, 0x60, 0x37, 0x10, + 0x9f, 0x2e, 0xe1, 0x32, 0xf0, 0x5c, 0xbe, 0x00, 0xab, 0x85, 0xed, 0x15, + 0xc1, 0xfd, 0x3b, 0xb3, 0x84, 0x13, 0x83, 0x75, 0xf0, 0xa0, 0x2e, 0xf1, + 0x4e, 0x6c, 0xb5, 0x87, 0x22, 0x55, 0x1f, 0xaf, 0x27, 0x9a, 0x7d, 0xdd, + 0x36, 0x42, 0xc3, 0x3d, 0x84, 0x97, 0xfc, 0x15, 0xb7, 0x92, 0xbf, 0x7a, + 0xb8, 0x9c, 0xe2, 0x21, 0xea, 0xec, 0x49, 0xbf, 0x36, 0xe4, 0xc9, 0x5a, + 0xcb, 0xea, 0xff, 0x48, 0x6c, 0xc2, 0x27, 0x69, 0xb6, 0x83, 0x4a, 0xf2, + 0xea, 0x78, 0x39, 0x3d, 0x82, 0x57, 0x8b, 0x7f, 0x82, 0x5c, 0xb3, 0x99, + 0xda, 0x2c, 0xd6, 0x61, 0x66, 0xe4, 0x0a, 0xe0, 0xcf, 0xd9, 0x7e, 0x02, + 0xf3, 0xad, 0x75, 0x38, 0x34, 0x76, 0x2f, 0x8e, 0x8c, 0xd6, 0xe3, 0x39, + 0x2b, 0x86, 0xf6, 0x89, 0x0a, 0x9d, 0x6b, 0xe6, 0x72, 0x93, 0x9e, 0xa6, + 0xe0, 0x6b, 0xe3, 0x98, 0x14, 0xb8, 0x3e, 0xb3, 0x0e, 0x39, 0xdf, 0xcf, + 0x3d, 0xac, 0xa1, 0xdc, 0x96, 0xcf, 0xbb, 0x14, 0xd7, 0x75, 0xd8, 0xd9, + 0x0c, 0x71, 0x0b, 0xd5, 0x93, 0x3b, 0x29, 0x5e, 0xef, 0x54, 0x62, 0x70, + 0x13, 0x2e, 0xd9, 0x55, 0xe0, 0x22, 0xcb, 0xc0, 0x9e, 0x22, 0x70, 0x77, + 0x51, 0xc5, 0xdf, 0x14, 0x2f, 0x45, 0xb9, 0x8d, 0xcf, 0x2e, 0x40, 0x79, + 0x1e, 0x7f, 0x87, 0x31, 0x16, 0x33, 0x13, 0x20, 0x9d, 0xed, 0x2f, 0xa8, + 0xf8, 0xb1, 0xbd, 0xeb, 0xec, 0xd8, 0x0a, 0x53, 0xcf, 0x51, 0xac, 0x85, + 0xac, 0xd3, 0xe4, 0x67, 0xfc, 0x0c, 0x7c, 0x3f, 0xff, 0x99, 0xfc, 0xb9, + 0x4f, 0x53, 0xc5, 0x6d, 0xf9, 0x8e, 0x81, 0x8f, 0x94, 0x8f, 0xe5, 0xbf, + 0x85, 0x19, 0xff, 0x77, 0xa2, 0x15, 0x7f, 0xdd, 0xc3, 0x79, 0xc4, 0xad, + 0xf8, 0xed, 0xbc, 0x2f, 0xf8, 0x6d, 0xc5, 0x3f, 0x47, 0xb2, 0xcc, 0x47, + 0x35, 0xc6, 0x62, 0xb8, 0x68, 0x22, 0x89, 0xba, 0x9d, 0xfc, 0x9b, 0xd7, + 0x05, 0x2e, 0xee, 0xe6, 0xf8, 0x4a, 0x42, 0xd9, 0x7b, 0x2d, 0xe1, 0x63, + 0xd9, 0xab, 0xb9, 0xe2, 0x7b, 0x73, 0xf8, 0xcf, 0xe7, 0x98, 0x76, 0xc2, + 0xb7, 0x74, 0x29, 0x3f, 0xf3, 0x99, 0x3a, 0xfc, 0x7a, 0xaf, 0x69, 0x97, + 0x95, 0xa5, 0x44, 0x93, 0x63, 0x92, 0x63, 0xf3, 0x2f, 0xe6, 0xce, 0x24, + 0xc8, 0xce, 0xd3, 0xb2, 0xbc, 0x8a, 0xf1, 0x55, 0xcf, 0x27, 0x11, 0x3a, + 0x47, 0x57, 0xc5, 0xea, 0xec, 0x97, 0xe9, 0xda, 0x94, 0xf7, 0x5b, 0xd1, + 0xb0, 0xd0, 0x22, 0x3b, 0xb5, 0xa1, 0x91, 0xe2, 0x3a, 0x62, 0xad, 0x92, + 0x91, 0x6f, 0xb3, 0x8f, 0x6a, 0x5e, 0xd8, 0xf9, 0x0a, 0x4a, 0x23, 0xcf, + 0x93, 0x7d, 0xa3, 0xec, 0x8b, 0x1b, 0x3e, 0x12, 0x5f, 0xc1, 0xf4, 0x98, + 0x88, 0xb2, 0xac, 0xab, 0x28, 0xb6, 0xe7, 0x53, 0x7d, 0xf8, 0xe0, 0xe1, + 0xbb, 0xe4, 0x58, 0x9f, 0x8e, 0x17, 0xb3, 0x49, 0x5a, 0x67, 0x5f, 0xb2, + 0xf1, 0x4c, 0x5e, 0xc3, 0xee, 0xe1, 0x84, 0xef, 0xc7, 0xf7, 0x74, 0xd6, + 0x9d, 0x2a, 0x2b, 0x36, 0x9e, 0x25, 0x3f, 0x3c, 0x58, 0x60, 0x1d, 0xab, + 0xb8, 0x38, 0xf3, 0x75, 0x59, 0xd3, 0xc6, 0xbe, 0x1d, 0xa1, 0x33, 0x3a, + 0xe1, 0x8e, 0x42, 0xb7, 0x96, 0xcb, 0x37, 0x56, 0xf0, 0x73, 0x03, 0xad, + 0xb5, 0xd1, 0xf7, 0x12, 0xd9, 0xf8, 0x3b, 0x7c, 0xe8, 0xff, 0x1b, 0x1f, + 0xf4, 0x1d, 0xa3, 0x75, 0x90, 0xbf, 0xcc, 0x88, 0xd5, 0x95, 0xfe, 0x46, + 0x53, 0xad, 0x19, 0xb1, 0xc6, 0xef, 0x69, 0xfc, 0x34, 0x4e, 0x38, 0x7a, + 0xb1, 0x77, 0x54, 0xca, 0x2d, 0x76, 0x3b, 0x5c, 0x3d, 0x86, 0x2d, 0x16, + 0xc5, 0xeb, 0x28, 0x9f, 0x91, 0x32, 0x95, 0x5e, 0xd8, 0xa3, 0x8a, 0x16, + 0xca, 0x99, 0x9e, 0x58, 0x9b, 0x35, 0xc4, 0x9d, 0xa3, 0x2a, 0xf2, 0x85, + 0x0b, 0x28, 0x27, 0x4b, 0xf9, 0x64, 0x1a, 0xee, 0x60, 0xba, 0x01, 0x2f, + 0x8f, 0xe9, 0x14, 0x3b, 0x67, 0xe5, 0xf2, 0x64, 0x2f, 0x4a, 0x84, 0xe7, + 0xd3, 0x74, 0x57, 0xea, 0xb0, 0x88, 0x60, 0x2c, 0x1e, 0xc1, 0x9e, 0x42, + 0x1c, 0x87, 0xc7, 0x23, 0xd8, 0x46, 0xfe, 0xf7, 0xd3, 0x2c, 0xd3, 0x8c, + 0x60, 0x73, 0x89, 0x7b, 0x8d, 0x10, 0xe9, 0xc0, 0x13, 0xef, 0xf9, 0x6b, + 0x0d, 0x58, 0x3e, 0xc6, 0x7b, 0xcf, 0xca, 0x76, 0xcb, 0xd2, 0xdb, 0x43, + 0xd5, 0x7d, 0xef, 0x50, 0x1f, 0x63, 0x50, 0xef, 0x72, 0x21, 0xe5, 0xaa, + 0x04, 0xf5, 0x2a, 0x71, 0xea, 0x55, 0xac, 0xb9, 0xfe, 0xcb, 0xa4, 0x48, + 0x93, 0xf2, 0x19, 0xca, 0x53, 0x6f, 0xd2, 0xe7, 0xa4, 0x4d, 0xe5, 0x96, + 0x64, 0xbc, 0x78, 0x98, 0x65, 0xf4, 0x84, 0xbd, 0x84, 0x3a, 0xce, 0x69, + 0xd3, 0x70, 0x95, 0x5f, 0x50, 0x9f, 0x65, 0xa0, 0x63, 0x9a, 0x79, 0x50, + 0xb1, 0xb5, 0x00, 0x0c, 0x16, 0xe0, 0x1d, 0xa6, 0xd8, 0x6e, 0x99, 0x88, + 0x22, 0x36, 0xa1, 0x23, 0x3c, 0x91, 0xa2, 0xbd, 0x1a, 0xe2, 0xf4, 0xdb, + 0xa3, 0xbe, 0xab, 0xc9, 0x69, 0x13, 0x8b, 0x76, 0x9f, 0x91, 0x0f, 0x52, + 0xac, 0xdd, 0x91, 0x34, 0x7b, 0x6f, 0x14, 0x70, 0x53, 0x43, 0x52, 0xd6, + 0xa6, 0x6b, 0xa9, 0x7e, 0xcb, 0x43, 0x71, 0x92, 0x3d, 0xea, 0xc8, 0x4d, + 0xaf, 0x76, 0x5b, 0xf6, 0xab, 0x20, 0xbc, 0x25, 0x3e, 0xc3, 0xeb, 0x9e, + 0xf8, 0xac, 0xdb, 0xda, 0xf3, 0x16, 0x3a, 0xb1, 0x78, 0x42, 0x15, 0xbf, + 0x1c, 0x5a, 0x84, 0xcc, 0x34, 0xf4, 0x1a, 0xe2, 0xeb, 0xc3, 0x29, 0xe2, + 0xbb, 0x40, 0xb2, 0x14, 0x48, 0x96, 0x02, 0xc9, 0x42, 0x7a, 0x39, 0xe8, + 0xf7, 0x6d, 0x2c, 0x6b, 0x8a, 0xea, 0xef, 0x3b, 0x7e, 0x6f, 0x79, 0xb0, + 0xc4, 0x72, 0x98, 0xae, 0x07, 0x96, 0x9b, 0xe5, 0x94, 0xf2, 0x2d, 0x9b, + 0xe5, 0x31, 0x0d, 0x4f, 0x21, 0x6b, 0x4d, 0x1b, 0x48, 0x4d, 0x57, 0xf5, + 0x21, 0xe5, 0xe7, 0x36, 0xeb, 0x83, 0x65, 0x94, 0xf2, 0x69, 0x92, 0x69, + 0x2b, 0xc9, 0x38, 0x58, 0x90, 0x87, 0x6a, 0x2c, 0xcb, 0x98, 0x20, 0xde, + 0x62, 0x24, 0x53, 0x7c, 0x42, 0x23, 0x59, 0x3b, 0xa1, 0x92, 0xac, 0xa1, + 0x09, 0xe8, 0x0a, 0xeb, 0x69, 0xfa, 0xff, 0xe2, 0x87, 0xfb, 0x6a, 0x4f, + 0x5c, 0x43, 0xfd, 0xb4, 0x4a, 0xfb, 0x07, 0xc9, 0x77, 0x72, 0x2a, 0x8c, + 0x5a, 0x4b, 0xa1, 0x3c, 0xac, 0xe1, 0xf1, 0xf1, 0x06, 0x4c, 0x90, 0xdd, + 0xc7, 0xc6, 0xa1, 0x87, 0xe9, 0xfd, 0xd6, 0x73, 0xfe, 0x04, 0xf2, 0xa7, + 0x0d, 0x18, 0xa7, 0xfc, 0xf3, 0x40, 0x3e, 0x26, 0x26, 0x46, 0x54, 0x6c, + 0x29, 0x9c, 0x20, 0xd9, 0x24, 0xe5, 0xd8, 0xcd, 0x09, 0xda, 0x22, 0x36, + 0xdb, 0x66, 0x0f, 0x70, 0x05, 0xf9, 0x5a, 0x08, 0x6b, 0x2d, 0xb8, 0xdb, + 0xed, 0x2b, 0x30, 0xdb, 0x07, 0x63, 0x87, 0xed, 0xe9, 0x35, 0x30, 0x8f, + 0x5e, 0x43, 0xa3, 0xc0, 0xe5, 0x24, 0xc7, 0x80, 0xe5, 0x6d, 0xa0, 0x84, + 0x44, 0xf9, 0xdb, 0xec, 0x3f, 0x42, 0x36, 0x28, 0x52, 0x5d, 0x2b, 0x52, + 0x0f, 0x78, 0x60, 0xf4, 0x8c, 0xbc, 0x3d, 0x6d, 0xba, 0x49, 0x5a, 0x0b, + 0x0f, 0x69, 0xd8, 0x5f, 0xd2, 0x28, 0x5e, 0x4c, 0x1b, 0xe0, 0x98, 0x87, + 0x56, 0x4b, 0x3d, 0xda, 0x47, 0xd6, 0xa3, 0xd4, 0x0b, 0x6b, 0xa0, 0x3e, + 0x19, 0x57, 0x8f, 0x08, 0xec, 0xa7, 0xf8, 0x9d, 0x5a, 0x64, 0x1e, 0x5d, + 0x0d, 0xaf, 0xdc, 0x0e, 0x73, 0xa0, 0x96, 0x18, 0xf9, 0x74, 0xa8, 0x86, + 0xfa, 0xc2, 0x4e, 0xfb, 0x35, 0x98, 0xfa, 0xfe, 0xd0, 0xaf, 0xe4, 0x64, + 0x1c, 0x17, 0x84, 0x71, 0x52, 0x1a, 0xdf, 0xe2, 0x33, 0x2c, 0xf7, 0x06, + 0x6c, 0xcf, 0x42, 0x0b, 0x3b, 0x6a, 0x7a, 0x7f, 0x1e, 0x38, 0x96, 0x37, + 0x30, 0xb9, 0xa8, 0x0e, 0x68, 0xee, 0xe8, 0xb9, 0x03, 0xde, 0xaa, 0xb0, + 0xdf, 0xe7, 0x6a, 0xe9, 0x3c, 0xf9, 0xc8, 0x7a, 0x21, 0xf0, 0x24, 0xd1, + 0x5a, 0x30, 0xc5, 0x7d, 0x89, 0x9a, 0x5e, 0x48, 0x79, 0x76, 0x5b, 0x49, + 0xa0, 0xd6, 0x32, 0xf5, 0x59, 0xb0, 0x6e, 0x74, 0xd2, 0xe9, 0x19, 0x89, + 0x66, 0x96, 0xdd, 0xcb, 0x91, 0x9c, 0xab, 0xb6, 0x12, 0xff, 0x6b, 0x48, + 0xa6, 0xdb, 0x2d, 0xaf, 0x87, 0xb0, 0x52, 0xed, 0x31, 0x13, 0x1f, 0x90, + 0xec, 0x6b, 0x29, 0x47, 0x8c, 0x95, 0x86, 0x9b, 0x38, 0x1f, 0x4c, 0x94, + 0x78, 0x4e, 0xea, 0xc1, 0xd5, 0xf9, 0x6a, 0x2c, 0xb0, 0xdd, 0xd9, 0xe6, + 0x17, 0xfa, 0xf5, 0xfb, 0xa0, 0xef, 0x23, 0xdc, 0x3f, 0xf5, 0x60, 0xb4, + 0x53, 0xa1, 0xde, 0x5c, 0xca, 0x15, 0x96, 0x39, 0xc2, 0xf9, 0x99, 0x7c, + 0xdd, 0xdd, 0x67, 0x37, 0x51, 0x6c, 0xc2, 0x7b, 0xc2, 0x36, 0x50, 0xe3, + 0xb0, 0x4f, 0x34, 0x90, 0x8f, 0x47, 0xb0, 0x9d, 0x7c, 0x44, 0xb3, 0xac, + 0x14, 0x35, 0x53, 0xfa, 0xb1, 0x2c, 0xed, 0x2d, 0xc1, 0x28, 0xd9, 0xf5, + 0x98, 0x6d, 0x55, 0xd1, 0xec, 0x1c, 0x92, 0x2d, 0xd6, 0x7f, 0x10, 0x7d, + 0x4b, 0xbf, 0x1b, 0xab, 0x61, 0xb4, 0x1a, 0x68, 0x70, 0xf8, 0xfd, 0x69, + 0x39, 0xdb, 0x1c, 0x21, 0xff, 0xe2, 0x3d, 0x96, 0x77, 0x10, 0xbf, 0x96, + 0x88, 0xf1, 0x5e, 0x97, 0xf2, 0x27, 0xc4, 0x0c, 0xd1, 0x42, 0x0b, 0xc7, + 0x2d, 0xf7, 0xe7, 0xd6, 0xd1, 0x43, 0x54, 0x53, 0x8c, 0x16, 0x50, 0x2e, + 0x55, 0x11, 0x72, 0x2c, 0x7d, 0x1f, 0x8e, 0x92, 0xcd, 0xd9, 0x45, 0x2e, + 0x12, 0xd7, 0xed, 0xba, 0x50, 0xf4, 0xee, 0x92, 0xb2, 0x33, 0x0d, 0x9a, + 0xc2, 0x92, 0xc6, 0x4b, 0xb4, 0xba, 0x85, 0x7c, 0xbf, 0xd1, 0x89, 0x88, + 0xe2, 0x2e, 0xe8, 0x07, 0x6c, 0x8d, 0xf2, 0xae, 0x94, 0xdb, 0xd2, 0x06, + 0xa6, 0x6d, 0xea, 0xc7, 0x5b, 0xc3, 0x68, 0xb6, 0xa0, 0xeb, 0x8e, 0x35, + 0xf0, 0x14, 0xee, 0x26, 0x3e, 0x11, 0x99, 0x4f, 0x35, 0x90, 0xd6, 0xc4, + 0x5e, 0xbb, 0x0e, 0xee, 0x4d, 0x02, 0x11, 0x27, 0x4e, 0xbc, 0xd5, 0x20, + 0xe7, 0x3f, 0xb3, 0x8c, 0x70, 0xdf, 0xb7, 0x7f, 0x44, 0xf2, 0x8a, 0xf9, + 0xf5, 0x0e, 0xaf, 0x59, 0x76, 0x11, 0xeb, 0xa9, 0xe7, 0xa7, 0x25, 0x7a, + 0xbf, 0x85, 0xde, 0x3f, 0x44, 0xb8, 0x73, 0x31, 0x7f, 0xd6, 0x6b, 0x6a, + 0x77, 0xac, 0xf2, 0x73, 0x78, 0x90, 0x64, 0xe0, 0xfc, 0xcd, 0x6b, 0xcc, + 0xf3, 0x22, 0xe6, 0x99, 0x6a, 0x37, 0xfb, 0x95, 0x8d, 0x8f, 0xf2, 0x77, + 0x73, 0x0f, 0xef, 0xee, 0xb0, 0x21, 0x26, 0xec, 0x3d, 0x28, 0xeb, 0x68, + 0x8a, 0x3a, 0x56, 0xff, 0x34, 0xa0, 0x44, 0x9c, 0x51, 0x14, 0x9b, 0x81, + 0x87, 0x0a, 0x96, 0xb7, 0x51, 0x31, 0x07, 0xe2, 0xd4, 0xf7, 0x9e, 0xfc, + 0xa1, 0x8a, 0x9d, 0x9d, 0x65, 0x33, 0x46, 0x46, 0x8f, 0x3a, 0x51, 0xf1, + 0xe2, 0x2e, 0x05, 0x0b, 0x96, 0xa8, 0x78, 0x8b, 0x72, 0xc8, 0x36, 0x9a, + 0x45, 0xc2, 0x96, 0xda, 0x54, 0xe9, 0x89, 0x7f, 0x5f, 0x3c, 0x9a, 0xa4, + 0xb1, 0x6a, 0x4c, 0x5a, 0x7d, 0x07, 0xf0, 0xa8, 0x74, 0x9b, 0xd9, 0x16, + 0x11, 0xca, 0xc3, 0xe7, 0xf2, 0x50, 0x6a, 0x8a, 0xf0, 0x0f, 0x76, 0xbf, + 0xeb, 0xfb, 0x0c, 0xd9, 0xd2, 0x7d, 0x23, 0x0f, 0xd1, 0x94, 0x71, 0x30, + 0xdb, 0xcc, 0x76, 0xe1, 0xf9, 0x99, 0x94, 0x37, 0x4c, 0xc3, 0x47, 0x8b, + 0x8a, 0xc5, 0x19, 0x34, 0x29, 0x8e, 0x75, 0x6a, 0x2f, 0xf1, 0xdc, 0xee, + 0x34, 0xe1, 0x74, 0x0b, 0xe7, 0xc4, 0xa8, 0xf8, 0xd9, 0xa8, 0xd9, 0x43, + 0x3d, 0xee, 0xaa, 0x8d, 0x30, 0xfb, 0xee, 0x11, 0xd4, 0x97, 0x11, 0xef, + 0x56, 0x92, 0xf8, 0xb4, 0x55, 0xc4, 0x93, 0x65, 0x33, 0x8e, 0x2a, 0xbf, + 0x67, 0x65, 0xcc, 0xb2, 0xbc, 0x98, 0xf2, 0x1b, 0x99, 0xce, 0xb0, 0x8f, + 0xdf, 0x85, 0xda, 0x98, 0x40, 0x4d, 0x66, 0xc4, 0xd7, 0x6d, 0x94, 0xec, + 0xdd, 0x94, 0x51, 0x89, 0xb6, 0x4a, 0x39, 0x9d, 0x68, 0x2f, 0x1e, 0xa0, + 0x9e, 0x85, 0x75, 0xfa, 0x92, 0xcc, 0x7d, 0x9b, 0xe5, 0xbc, 0x65, 0x4e, + 0x66, 0xd2, 0x6c, 0x3d, 0xff, 0x96, 0x0d, 0xac, 0xfb, 0x43, 0x94, 0xcf, + 0x17, 0x2f, 0xed, 0xda, 0x31, 0xa0, 0x3c, 0x20, 0x8d, 0x15, 0x6c, 0xdb, + 0x46, 0x7a, 0xef, 0xdb, 0x9d, 0xfa, 0xa9, 0x77, 0xf0, 0xda, 0x50, 0x54, + 0x34, 0xed, 0xf6, 0xfc, 0xda, 0xf9, 0x2a, 0xf1, 0xf5, 0x61, 0x9a, 0xf9, + 0xe1, 0x78, 0x7b, 0x07, 0x97, 0x16, 0xff, 0x94, 0xf6, 0x86, 0x88, 0x17, + 0x68, 0x31, 0x92, 0x75, 0x05, 0xcd, 0x25, 0x57, 0x67, 0x0e, 0x48, 0x57, + 0x67, 0xfc, 0xa4, 0xf7, 0x51, 0xd6, 0x3b, 0xcf, 0x45, 0x55, 0xdd, 0xf3, + 0x7e, 0x3e, 0x3f, 0x4c, 0x31, 0xc9, 0xb6, 0x44, 0x53, 0x83, 0xc3, 0xfa, + 0x85, 0xa8, 0x73, 0xba, 0x8c, 0x85, 0x62, 0x87, 0xf4, 0xe2, 0xd5, 0x7c, + 0x16, 0x15, 0x13, 0xfe, 0x79, 0xa6, 0xfd, 0xe5, 0xf3, 0x6d, 0xe2, 0xd8, + 0xc3, 0x54, 0x7c, 0xeb, 0x7d, 0x7f, 0xe9, 0x7d, 0x92, 0xe2, 0x49, 0x73, + 0x6e, 0x95, 0xa9, 0x56, 0xf6, 0x37, 0x28, 0x2f, 0xdb, 0xb7, 0xc8, 0x5c, + 0x2b, 0xfb, 0x1d, 0xbc, 0x38, 0xe1, 0xd9, 0xb9, 0xfb, 0x3c, 0x1f, 0xd7, + 0x74, 0x4a, 0x39, 0x61, 0x5f, 0x45, 0xba, 0x60, 0x3c, 0x55, 0x5d, 0xfc, + 0xe5, 0x9c, 0x6e, 0xa8, 0x89, 0xae, 0xaf, 0xd4, 0x2b, 0xce, 0x69, 0x35, + 0xce, 0x1b, 0x78, 0x31, 0xaf, 0xb4, 0x85, 0xd1, 0x84, 0x3e, 0x5b, 0xe0, + 0xdd, 0x1e, 0x81, 0xd3, 0x97, 0x47, 0x10, 0xba, 0xcc, 0x2a, 0x77, 0x84, + 0xfa, 0x25, 0xe6, 0x95, 0xc9, 0x51, 0xce, 0x48, 0xad, 0x53, 0x45, 0xed, + 0xa5, 0x5c, 0xa7, 0xd8, 0x0e, 0x0a, 0xfe, 0x85, 0xf6, 0x5d, 0x77, 0xa9, + 0x65, 0x74, 0x50, 0x4b, 0xe0, 0xf5, 0x5d, 0x9d, 0x09, 0x9f, 0xf3, 0x43, + 0xe6, 0xe1, 0x4a, 0x5f, 0x06, 0xf6, 0xc7, 0xc5, 0x64, 0xc7, 0xdc, 0x0a, + 0x05, 0xe9, 0x25, 0xf0, 0x22, 0xf4, 0x7e, 0xdb, 0x2e, 0xf6, 0x85, 0x47, + 0x74, 0x9e, 0x09, 0x81, 0xae, 0x84, 0x0e, 0x6b, 0xd5, 0x0b, 0x44, 0x9b, + 0xfa, 0x4d, 0xd2, 0x07, 0xd3, 0xaa, 0xe2, 0xa9, 0xe2, 0x88, 0x8a, 0xd3, + 0x0f, 0xf3, 0x19, 0x08, 0xd6, 0x51, 0x7a, 0x01, 0xc5, 0x76, 0x46, 0x9d, + 0x93, 0x6d, 0x40, 0xaf, 0xf4, 0x61, 0x51, 0x31, 0x35, 0xca, 0xf8, 0x7c, + 0x3f, 0x42, 0x91, 0x7d, 0x2b, 0xcd, 0x7b, 0x7e, 0x23, 0x17, 0x64, 0xfe, + 0x9d, 0xf6, 0x30, 0xde, 0xa8, 0x38, 0xe2, 0xd3, 0xae, 0xe8, 0x68, 0x8a, + 0x74, 0x3d, 0x91, 0xae, 0xe2, 0xd9, 0x48, 0x7b, 0xd8, 0xe7, 0x98, 0x87, + 0x5e, 0xf1, 0x78, 0x9e, 0xf2, 0x0a, 0xd5, 0xdc, 0x89, 0xac, 0x62, 0xd5, + 0x42, 0x62, 0xb3, 0xad, 0x63, 0x99, 0x5e, 0xa9, 0x57, 0xf7, 0xe7, 0xab, + 0xf7, 0x3f, 0xbd, 0xa2, 0x90, 0x57, 0xa8, 0x7f, 0x83, 0x5e, 0xef, 0x28, + 0xf7, 0x34, 0x51, 0x2c, 0xbd, 0x46, 0xb5, 0xeb, 0xd5, 0xb1, 0x5e, 0x91, + 0xcf, 0xeb, 0x78, 0x65, 0x7c, 0xb9, 0x78, 0x30, 0x6f, 0xe1, 0xe5, 0x62, + 0xe5, 0x2e, 0xe8, 0x81, 0xa2, 0x2b, 0xc6, 0xf3, 0xdc, 0xfb, 0x98, 0xa9, + 0x32, 0x66, 0xc4, 0x5a, 0xc2, 0x53, 0x56, 0x2f, 0xf4, 0xeb, 0xc8, 0x78, + 0xb1, 0x01, 0x93, 0x63, 0x95, 0x7a, 0x77, 0xeb, 0xb9, 0x7a, 0xf7, 0xc5, + 0x3b, 0x9d, 0x48, 0x4e, 0x77, 0xd0, 0xd7, 0x38, 0xbc, 0x49, 0x46, 0xad, + 0x10, 0xd5, 0x49, 0x2b, 0x37, 0x2d, 0x22, 0x3d, 0x3b, 0xba, 0x99, 0x5f, + 0xf4, 0x69, 0xd4, 0x63, 0x4c, 0x14, 0xd9, 0x5f, 0x0d, 0x18, 0xc5, 0x6f, + 0xb5, 0x56, 0xec, 0xdc, 0x96, 0xd3, 0x1c, 0xa0, 0x9e, 0xfa, 0x8b, 0x06, + 0x9a, 0x0d, 0xea, 0x9c, 0x1b, 0xbd, 0x8e, 0x6e, 0xe4, 0x54, 0xc7, 0xea, + 0xb9, 0x5e, 0xac, 0x5c, 0xa9, 0x38, 0xf7, 0xad, 0x0c, 0x4d, 0x1b, 0xc6, + 0x16, 0xbf, 0x0e, 0x9d, 0x1c, 0xd8, 0x4f, 0x33, 0x50, 0x0d, 0xcd, 0xa5, + 0xef, 0xe9, 0xb8, 0x2f, 0xd4, 0x7d, 0x1f, 0x36, 0xe5, 0x07, 0xf0, 0xb7, + 0x79, 0xce, 0x13, 0x3a, 0x1e, 0x63, 0x1e, 0x0a, 0x7c, 0xff, 0x73, 0xb0, + 0x85, 0x6b, 0xdf, 0x23, 0x25, 0x8a, 0xc3, 0x21, 0xe4, 0x12, 0x8e, 0x9f, + 0x47, 0x12, 0xa7, 0xc4, 0xf9, 0xfd, 0xbf, 0xbb, 0x97, 0xf5, 0x46, 0xfd, + 0x1c, 0xcd, 0x4e, 0x4a, 0xf6, 0x4a, 0xbe, 0x7f, 0xf2, 0x03, 0x74, 0x3b, + 0xe5, 0x91, 0x0f, 0x6c, 0x13, 0x63, 0x7a, 0xc5, 0x7e, 0xdb, 0x47, 0xb9, + 0x1e, 0x7d, 0x42, 0xf5, 0x28, 0x2a, 0xb6, 0xd2, 0x73, 0xa3, 0xf3, 0x4a, + 0x7a, 0x8a, 0x78, 0x3f, 0x46, 0x39, 0x26, 0xe1, 0x1c, 0x47, 0xa2, 0xc0, + 0xb3, 0xfa, 0x51, 0x9a, 0xd5, 0xcd, 0xdc, 0x32, 0x8a, 0xe7, 0x03, 0x76, + 0xd7, 0xc0, 0xa0, 0x30, 0x8f, 0x52, 0x6d, 0x4e, 0x1c, 0xa0, 0xb9, 0x8b, + 0xbe, 0x37, 0xb4, 0x87, 0xba, 0xec, 0x75, 0x30, 0xdd, 0x85, 0xc2, 0x34, + 0x5e, 0x17, 0xa6, 0x5e, 0x23, 0x58, 0x27, 0x9f, 0x60, 0x91, 0xaf, 0x9b, + 0xe3, 0xb0, 0xfc, 0xef, 0x57, 0xd2, 0x1d, 0xfe, 0xf7, 0xd1, 0xf4, 0xc5, + 0xe7, 0x7b, 0x0b, 0x77, 0x07, 0xd5, 0xc6, 0x7c, 0x21, 0x83, 0x48, 0x33, + 0xd7, 0x8a, 0xa8, 0x38, 0xb0, 0x0b, 0x5a, 0xbd, 0xf3, 0x3e, 0xbe, 0x3e, + 0x04, 0x4d, 0x73, 0xa8, 0xd2, 0x12, 0x2f, 0xd4, 0x1b, 0xa4, 0xae, 0x13, + 0xdc, 0x0f, 0x74, 0xe5, 0x9e, 0x80, 0xd9, 0x53, 0x43, 0x34, 0x3e, 0x01, + 0xe3, 0x7a, 0x1f, 0x49, 0x1f, 0xe7, 0x2c, 0xce, 0xe3, 0x8c, 0x8a, 0xc1, + 0xd1, 0xa8, 0xd8, 0x4c, 0xb2, 0xb4, 0x3b, 0x27, 0x71, 0x85, 0xcf, 0xff, + 0x2b, 0xc4, 0x3f, 0xe7, 0x9c, 0x13, 0x94, 0x73, 0x18, 0xef, 0xd1, 0x34, + 0xe3, 0x1d, 0xa0, 0x3e, 0xf3, 0x7a, 0xdb, 0x4c, 0xf5, 0x84, 0xcc, 0x44, + 0x97, 0x30, 0x29, 0xa9, 0xb1, 0x3c, 0x5d, 0xfd, 0x33, 0xe0, 0xb9, 0xd8, + 0x97, 0xa9, 0xa7, 0x9e, 0x64, 0x1a, 0x22, 0x7a, 0x1f, 0xfa, 0xf4, 0x4e, + 0xce, 0xd1, 0x3b, 0xf1, 0x07, 0x64, 0x52, 0xdd, 0xfb, 0xc9, 0x1e, 0xdb, + 0x0a, 0xaf, 0xc8, 0xce, 0xd6, 0x8a, 0x4c, 0x83, 0x3e, 0x2f, 0x3f, 0x49, + 0x33, 0x2f, 0x51, 0x67, 0x86, 0xe6, 0x48, 0xa6, 0x6d, 0xae, 0x22, 0xba, + 0x44, 0xb3, 0xcb, 0x18, 0x10, 0x66, 0x3f, 0xe9, 0xad, 0x6f, 0xdc, 0xd7, + 0xdb, 0x4f, 0xd2, 0x5d, 0x3e, 0xce, 0x19, 0xea, 0x39, 0xbe, 0xe8, 0x93, + 0xec, 0x73, 0xd5, 0xbb, 0xca, 0x94, 0x78, 0x8a, 0x7a, 0x97, 0xa7, 0x8a, + 0xaa, 0xd8, 0x47, 0xf6, 0x1c, 0xa7, 0xb8, 0x19, 0xf4, 0xef, 0x1f, 0xa9, + 0x06, 0x96, 0xbe, 0xd7, 0x3c, 0x97, 0x6f, 0xc8, 0xae, 0x65, 0xb2, 0x6b, + 0x27, 0x65, 0x65, 0xee, 0xd9, 0xb8, 0xde, 0x1d, 0xa6, 0x7a, 0x27, 0xf0, + 0xa1, 0x9f, 0x63, 0x0f, 0xa3, 0xb3, 0xc8, 0x3d, 0xa1, 0x25, 0x96, 0xe7, + 0x8d, 0xdc, 0x7c, 0xc2, 0xfd, 0x7e, 0xa9, 0x92, 0x1f, 0xa9, 0x36, 0xba, + 0x21, 0xa7, 0x47, 0xbc, 0x50, 0xe4, 0x9f, 0x54, 0x4c, 0x62, 0xec, 0x5b, + 0xae, 0x68, 0xea, 0xf4, 0xd0, 0xde, 0xe9, 0x49, 0xd5, 0xb2, 0xca, 0xef, + 0x0b, 0xeb, 0x94, 0x15, 0x72, 0x6f, 0x9f, 0x8f, 0x4d, 0xb8, 0x6c, 0xb1, + 0x7b, 0x73, 0x02, 0xfe, 0x4c, 0x6c, 0x50, 0x4c, 0xa2, 0xb7, 0x3b, 0xd9, + 0x33, 0x2d, 0x92, 0xd4, 0x43, 0x25, 0xbd, 0x94, 0x48, 0xa6, 0x8e, 0xc3, + 0xd6, 0x8e, 0x14, 0x6d, 0xed, 0x8d, 0x62, 0xf5, 0x6e, 0x93, 0xe5, 0x62, + 0x5f, 0xe5, 0xf8, 0xb0, 0xdc, 0xfb, 0x29, 0x0f, 0xc1, 0xef, 0x43, 0xe4, + 0xa1, 0x46, 0x8a, 0xb1, 0x3b, 0x51, 0x4b, 0x4d, 0xb3, 0xdc, 0xde, 0x44, + 0xf3, 0xcf, 0x5d, 0x44, 0xbf, 0xdc, 0x9a, 0x03, 0xd7, 0x93, 0x47, 0xf8, + 0xc2, 0xb9, 0x85, 0x79, 0x7a, 0x33, 0x52, 0x91, 0x91, 0xca, 0x70, 0xe5, + 0xff, 0x17, 0xd2, 0x1a, 0x28, 0x06, 0xd7, 0x0d, 0x09, 0xea, 0xef, 0x2b, + 0xf1, 0xb8, 0x90, 0xef, 0x4e, 0xfd, 0x7b, 0xb3, 0x57, 0x64, 0xa5, 0xde, + 0x7f, 0xdc, 0xcc, 0x77, 0x51, 0x8a, 0x33, 0x1c, 0xfb, 0xed, 0xb3, 0x15, + 0xdd, 0xf2, 0x1c, 0x7f, 0xa8, 0xe4, 0x8a, 0x6b, 0xf3, 0xd8, 0x40, 0xbd, + 0x83, 0x1b, 0x26, 0x1c, 0xd7, 0x16, 0x7b, 0x49, 0x37, 0x96, 0x31, 0x48, + 0x44, 0xb7, 0xea, 0x5d, 0xfa, 0x38, 0xf5, 0x5a, 0x84, 0xcb, 0xa0, 0x7e, + 0x94, 0x62, 0x7c, 0x1e, 0x76, 0xcc, 0xc5, 0x54, 0xbd, 0xc3, 0x77, 0xbb, + 0x03, 0x62, 0xe1, 0x54, 0x25, 0xcd, 0x1f, 0x3a, 0x27, 0xdf, 0x69, 0xb9, + 0xfd, 0x26, 0x7e, 0x5f, 0x3f, 0x67, 0x93, 0x2b, 0x99, 0x26, 0xfd, 0x7e, + 0x76, 0x8e, 0x87, 0x3f, 0x74, 0xf6, 0x8e, 0xaf, 0xfe, 0xf6, 0x99, 0x59, + 0xe2, 0x93, 0x7b, 0x45, 0x78, 0x31, 0x87, 0xfb, 0xc4, 0x0b, 0xe7, 0x7c, + 0xe1, 0x52, 0xc2, 0xbd, 0x01, 0x37, 0xd2, 0x7c, 0xd4, 0x49, 0x73, 0x28, + 0xcd, 0x2e, 0x48, 0x0d, 0xb3, 0x3e, 0xce, 0x90, 0x3e, 0xd8, 0xe6, 0xa7, + 0xc8, 0xe6, 0x1d, 0x39, 0x8a, 0x99, 0xd4, 0x7a, 0x61, 0xf6, 0x92, 0xbf, + 0x51, 0xed, 0x32, 0x13, 0x1f, 0xc3, 0x34, 0xd6, 0xfa, 0x3e, 0x7d, 0x66, + 0xce, 0xa7, 0x4f, 0xb1, 0x4f, 0xa3, 0x6f, 0x38, 0x04, 0x25, 0xf3, 0x29, + 0xe9, 0x8c, 0xe2, 0x4d, 0x30, 0x4e, 0xce, 0x53, 0x67, 0x40, 0xfd, 0xb2, + 0x36, 0x9f, 0xf6, 0xc8, 0x42, 0x47, 0xe2, 0x28, 0xf5, 0xdb, 0xfb, 0xc0, + 0x25, 0xa3, 0xeb, 0xe8, 0x31, 0x61, 0x96, 0xdf, 0x0b, 0x71, 0x0e, 0x10, + 0x68, 0xcc, 0x54, 0xf0, 0x5d, 0x5e, 0x4c, 0x60, 0x47, 0xa9, 0x82, 0xf3, + 0x32, 0xf2, 0xe1, 0x31, 0xff, 0x7e, 0x41, 0x81, 0x96, 0x79, 0x9b, 0x6b, + 0x33, 0xc1, 0x25, 0x73, 0xf2, 0x7f, 0x67, 0xce, 0x06, 0x6f, 0xce, 0xe9, + 0x67, 0x4b, 0x8c, 0x6b, 0x8f, 0x96, 0xe1, 0x7c, 0x0d, 0xb1, 0x26, 0xff, + 0x67, 0x54, 0x03, 0x34, 0xea, 0x81, 0xfd, 0xbc, 0x8f, 0x5c, 0x11, 0x94, + 0xbf, 0xcb, 0xb5, 0x47, 0xec, 0xf0, 0x5c, 0xfe, 0xfa, 0x06, 0xad, 0xf5, + 0xd1, 0x87, 0x75, 0xc6, 0x77, 0x12, 0x37, 0xd1, 0xb3, 0xeb, 0xef, 0xeb, + 0xcf, 0xa3, 0xa7, 0x36, 0x4d, 0xfd, 0xad, 0xbf, 0xcf, 0xbf, 0xaf, 0xa0, + 0x3d, 0xcb, 0xf9, 0xdd, 0x08, 0xdf, 0xb5, 0xac, 0xce, 0x26, 0x8d, 0xcd, + 0x60, 0x3a, 0x06, 0xd6, 0x14, 0x0d, 0xdc, 0x4a, 0x75, 0x61, 0xcc, 0xbf, + 0x07, 0x3d, 0x3f, 0xf7, 0x28, 0xb4, 0x6f, 0x19, 0xed, 0x1b, 0xf4, 0xd7, + 0x0c, 0x2c, 0x2f, 0x9e, 0x9f, 0xe9, 0x54, 0x3a, 0x77, 0xe8, 0xdc, 0x1c, + 0xcb, 0x76, 0x70, 0xc5, 0xce, 0x7c, 0xaf, 0x18, 0xc9, 0x47, 0x89, 0x96, + 0x42, 0x19, 0x40, 0xa2, 0x23, 0x73, 0x33, 0xe5, 0x5d, 0x2b, 0xa5, 0x2a, + 0x4d, 0x58, 0x9b, 0x22, 0x3f, 0xd6, 0x97, 0xe2, 0x8e, 0x54, 0x0d, 0xf5, + 0x34, 0xc3, 0xb8, 0x4d, 0xaf, 0x45, 0x7f, 0xea, 0x52, 0xe0, 0xc6, 0x3a, + 0xea, 0x41, 0x06, 0xfc, 0x9e, 0xbe, 0x86, 0xe8, 0xd5, 0x59, 0x4f, 0xe1, + 0xf6, 0x73, 0xff, 0xae, 0x42, 0x34, 0x7e, 0xef, 0x3c, 0x77, 0x33, 0xdc, + 0xe6, 0x1e, 0xaa, 0x83, 0xdd, 0x58, 0x97, 0x0a, 0x53, 0x6f, 0xcd, 0xf9, + 0x61, 0x3e, 0x22, 0xd6, 0x67, 0x72, 0xfd, 0xb9, 0x3e, 0x67, 0x46, 0xcc, + 0x90, 0x5c, 0xa8, 0xf5, 0xc4, 0x73, 0x34, 0xbf, 0x65, 0x4a, 0x7c, 0x1f, + 0xa5, 0x20, 0x66, 0xf1, 0xcc, 0x48, 0xc3, 0x1f, 0xcd, 0x59, 0xe9, 0xc7, + 0xeb, 0x71, 0xd5, 0xbe, 0x06, 0x64, 0xf6, 0xe9, 0xb0, 0x1f, 0xb7, 0x68, + 0x2d, 0x45, 0x9f, 0x19, 0xb1, 0xb7, 0xf8, 0x87, 0x68, 0x77, 0x60, 0x8d, + 0xfe, 0x3f, 0x95, 0x7d, 0x0b, 0x70, 0x54, 0xe7, 0x95, 0xe6, 0x77, 0xfb, + 0x21, 0xb5, 0x9e, 0x5c, 0x09, 0x09, 0x5a, 0x20, 0x9b, 0x6e, 0xf7, 0x6d, + 0xa9, 0x8d, 0x3a, 0xe1, 0x36, 0x88, 0xb5, 0x9c, 0xed, 0x2d, 0x1a, 0x2c, + 0x8c, 0x08, 0x60, 0xcb, 0xb6, 0x3c, 0x83, 0x77, 0x32, 0x6b, 0xc5, 0x36, + 0x18, 0x3f, 0x92, 0x91, 0x09, 0x5b, 0x25, 0x53, 0x53, 0xd1, 0x1d, 0x01, + 0x42, 0x40, 0xbf, 0x24, 0xc1, 0x00, 0x33, 0x53, 0xe3, 0x46, 0x0f, 0x20, + 0xb8, 0x5b, 0xc2, 0x71, 0x66, 0x4a, 0xc9, 0xd4, 0x56, 0x34, 0x20, 0x0c, + 0x04, 0x63, 0x3c, 0x93, 0x99, 0x29, 0xb2, 0xeb, 0x2d, 0x13, 0x1c, 0xc0, + 0x0f, 0xfc, 0x4c, 0xb2, 0x16, 0xf1, 0xc4, 0x77, 0xbf, 0x73, 0xbb, 0x1b, + 0x04, 0x45, 0x3c, 0x35, 0x54, 0x75, 0xb5, 0x6e, 0xdf, 0xff, 0xfe, 0x8f, + 0xf3, 0x9f, 0xf3, 0x9d, 0xef, 0x9c, 0xf3, 0xdf, 0xa2, 0x84, 0xfe, 0xfb, + 0xdf, 0xcc, 0x75, 0x8c, 0x4f, 0xdc, 0x0b, 0x69, 0x66, 0xb3, 0x65, 0xbc, + 0x0b, 0x5f, 0x0e, 0x24, 0x9c, 0xe8, 0xea, 0x77, 0xe0, 0xda, 0xa2, 0x73, + 0xa6, 0x67, 0xf6, 0x8d, 0xfc, 0x4e, 0xc4, 0xe6, 0xc4, 0x33, 0xfd, 0xf2, + 0xed, 0x40, 0x60, 0x71, 0x36, 0xe7, 0xba, 0x61, 0xd0, 0x89, 0xa7, 0xd9, + 0xf6, 0xa2, 0x6e, 0xcb, 0xed, 0xb1, 0x55, 0x1b, 0xc0, 0x73, 0xfd, 0x8c, + 0x6d, 0x34, 0x13, 0xcf, 0x86, 0x8a, 0x71, 0x7f, 0x75, 0x76, 0x1d, 0xc3, + 0x5c, 0x87, 0xe1, 0x30, 0x94, 0x4c, 0xa3, 0x13, 0xe5, 0x9c, 0x3f, 0xb9, + 0x18, 0x7e, 0x98, 0x29, 0xc1, 0xe8, 0x81, 0x71, 0x25, 0x9d, 0xce, 0xb6, + 0x19, 0xb2, 0x62, 0x5a, 0x43, 0x19, 0x6b, 0xb4, 0x61, 0x26, 0xfd, 0xfb, + 0x85, 0x8c, 0x03, 0x9f, 0x65, 0x5c, 0xf8, 0x74, 0xa4, 0x18, 0xbf, 0x3e, + 0x50, 0xc2, 0x8f, 0x8a, 0x4f, 0x46, 0x34, 0xfe, 0xde, 0xac, 0xbc, 0x12, + 0x95, 0xd8, 0x23, 0x80, 0x4f, 0x33, 0xe3, 0xca, 0xd1, 0xaf, 0x5c, 0x6b, + 0xc6, 0xfc, 0x8e, 0x6a, 0x70, 0xcc, 0xbf, 0x36, 0xbf, 0x3b, 0x4d, 0xae, + 0xd3, 0xc7, 0xaa, 0xd4, 0x4a, 0xf0, 0xd9, 0x01, 0x19, 0x47, 0xfa, 0x6f, + 0x56, 0x5e, 0x8d, 0x8a, 0x7c, 0x2b, 0xf1, 0xeb, 0x11, 0x91, 0xe3, 0x27, + 0xd4, 0x69, 0xe9, 0x7f, 0x5c, 0x39, 0x9e, 0x7b, 0xe6, 0xe7, 0xdc, 0x8b, + 0x8d, 0xa3, 0x0e, 0x90, 0x4c, 0xf0, 0x59, 0x17, 0x5e, 0x38, 0x68, 0x23, + 0x27, 0x2e, 0xc6, 0xc6, 0xc1, 0x12, 0xbc, 0x30, 0xa8, 0xa2, 0xe3, 0x60, + 0xb3, 0x42, 0xbe, 0xaf, 0xce, 0x20, 0xef, 0xed, 0x18, 0x0d, 0xb0, 0xdd, + 0xb8, 0x72, 0x2e, 0xdd, 0x30, 0x33, 0xdb, 0x4f, 0x36, 0xf7, 0x93, 0xe5, + 0x31, 0x86, 0xc2, 0x38, 0x8d, 0x5c, 0x72, 0xdf, 0xe6, 0xd7, 0x18, 0x21, + 0x3e, 0x9c, 0xb6, 0x53, 0xc7, 0x24, 0x1e, 0x15, 0xbb, 0x4f, 0x6d, 0xbe, + 0x12, 0x95, 0xb9, 0x1a, 0xca, 0x91, 0x46, 0x9b, 0xc5, 0xb1, 0x5f, 0x67, + 0x5c, 0xb8, 0x82, 0xb6, 0xf2, 0x10, 0xe5, 0xb1, 0x9a, 0xf2, 0x68, 0xa6, + 0x3c, 0x5a, 0x39, 0xdf, 0x97, 0xa3, 0x82, 0x93, 0xde, 0x40, 0x44, 0xd1, + 0xb0, 0x2a, 0x23, 0x7d, 0x58, 0xe3, 0xb8, 0x1c, 0xe1, 0xbf, 0xd9, 0xbc, + 0x35, 0x7a, 0xab, 0x5c, 0xa0, 0x96, 0x87, 0xc5, 0xaf, 0x89, 0x6c, 0x02, + 0xe4, 0x50, 0xe3, 0xca, 0xa8, 0x15, 0x23, 0xef, 0xdb, 0xec, 0x49, 0xe5, + 0x6d, 0xa7, 0x44, 0xec, 0x53, 0xf2, 0xe1, 0xca, 0x3e, 0x72, 0xb5, 0x1a, + 0x2d, 0x7b, 0xff, 0xde, 0x94, 0x7c, 0xa7, 0x36, 0x2f, 0xb4, 0xf0, 0xe6, + 0x6f, 0x36, 0x37, 0x5d, 0x5f, 0xd3, 0xb8, 0xf2, 0x36, 0xd7, 0x73, 0x81, + 0x7a, 0x7a, 0x92, 0x73, 0x2d, 0x92, 0xbd, 0x4b, 0x73, 0xef, 0x38, 0xd7, + 0x4f, 0x87, 0x8b, 0xf1, 0x5e, 0xaa, 0x84, 0x1f, 0xca, 0x76, 0x98, 0x7b, + 0x97, 0x6e, 0x56, 0x4e, 0x59, 0xf2, 0x0d, 0xe0, 0x5d, 0x8e, 0x7d, 0xec, + 0x7a, 0x1f, 0x59, 0xde, 0x96, 0xad, 0xc3, 0xe5, 0xed, 0x57, 0xf0, 0x54, + 0xd6, 0x66, 0x28, 0x91, 0xeb, 0xb5, 0x34, 0xc9, 0x8b, 0x49, 0x7d, 0x91, + 0x3e, 0x46, 0x95, 0xfc, 0xa8, 0x42, 0x8c, 0xa1, 0xfe, 0xa9, 0xcb, 0x3c, + 0x0e, 0xe2, 0xe2, 0x3a, 0x7c, 0xc1, 0x38, 0x21, 0x42, 0x8b, 0x92, 0xb5, + 0x48, 0x8e, 0xb4, 0x50, 0x62, 0x42, 0xeb, 0xdf, 0x20, 0xb9, 0xd4, 0x6b, + 0xe4, 0xb9, 0x54, 0x21, 0x74, 0xa7, 0xbf, 0x30, 0x27, 0xaa, 0xe8, 0x57, + 0xb5, 0xeb, 0x79, 0x37, 0xae, 0xd9, 0x34, 0x87, 0x78, 0xaf, 0x27, 0x8d, + 0xdc, 0x3f, 0x72, 0x2f, 0xf2, 0xdd, 0x27, 0xb5, 0xdf, 0x99, 0x4f, 0xdc, + 0xd4, 0x36, 0x8f, 0xe5, 0xf9, 0x78, 0x5f, 0xb0, 0xbc, 0x14, 0x3d, 0xbb, + 0xbd, 0xc9, 0x14, 0xaa, 0x90, 0xd4, 0x6c, 0x73, 0x0b, 0x38, 0x3b, 0x3b, + 0xbc, 0xbd, 0xcd, 0xb0, 0xf2, 0x20, 0x9e, 0x14, 0xfe, 0x61, 0xa6, 0xd8, + 0x8c, 0x53, 0x6b, 0xf0, 0x54, 0xd8, 0x2a, 0x65, 0xee, 0xd6, 0xac, 0xec, + 0xfd, 0x45, 0x58, 0x17, 0x2c, 0x42, 0xaa, 0x95, 0x18, 0xd7, 0x6f, 0xb4, + 0xb0, 0x7b, 0xf2, 0xa7, 0xc0, 0x8b, 0xdf, 0xf4, 0x0b, 0x1f, 0x03, 0x0a, + 0x63, 0x1c, 0x13, 0x39, 0x0c, 0xec, 0xf7, 0x1a, 0x36, 0x9b, 0x3c, 0xff, + 0x99, 0x69, 0xb4, 0xc9, 0xb3, 0xd2, 0x47, 0xad, 0xc5, 0x1b, 0x6f, 0xd6, + 0x7b, 0x0f, 0xe5, 0xf4, 0xaf, 0x33, 0x25, 0xe7, 0xa8, 0xd6, 0x31, 0xee, + 0xe9, 0x97, 0x9a, 0x4d, 0x04, 0xbb, 0xaa, 0x7d, 0x1d, 0xba, 0xad, 0x18, + 0x67, 0xbf, 0xf6, 0xdf, 0x88, 0xe9, 0x05, 0x70, 0xd5, 0x01, 0xf7, 0xc5, + 0x6d, 0xb0, 0xd5, 0x11, 0xab, 0xa9, 0xd3, 0xcd, 0xa3, 0x36, 0xcc, 0xeb, + 0x57, 0xf0, 0x58, 0xd2, 0x86, 0x07, 0x92, 0x76, 0xac, 0x4a, 0xe2, 0xfb, + 0xf3, 0x80, 0xc9, 0x1a, 0xf8, 0xdb, 0xa7, 0xe8, 0x9a, 0xcb, 0xe1, 0x6f, + 0x8d, 0x91, 0x17, 0xac, 0x62, 0x2c, 0xba, 0x72, 0x94, 0x38, 0xc8, 0xb6, + 0xce, 0x3e, 0xea, 0x66, 0x9f, 0x1d, 0x35, 0x7d, 0xb8, 0xb3, 0x10, 0xa0, + 0x75, 0xfb, 0xa7, 0xe8, 0x97, 0x2a, 0x1d, 0xf0, 0xd3, 0xaf, 0xf8, 0x3b, + 0x6b, 0xec, 0x0c, 0xc4, 0xea, 0xfe, 0xd5, 0xe2, 0xb4, 0x0f, 0xd2, 0x5e, + 0xe6, 0xf5, 0xb3, 0x7d, 0x9d, 0x0d, 0x2a, 0xf5, 0xf9, 0x93, 0x3f, 0x96, + 0x7c, 0xaf, 0xdc, 0x93, 0xba, 0xab, 0x82, 0xf2, 0x7e, 0x3b, 0xf1, 0xf0, + 0x8c, 0x79, 0xb6, 0xda, 0xaa, 0x41, 0xe1, 0x31, 0xce, 0xcd, 0xcd, 0xdf, + 0xd4, 0x3a, 0x17, 0x16, 0xdc, 0xa3, 0x62, 0xed, 0xa0, 0xb4, 0x85, 0xd5, + 0x8f, 0x93, 0xb8, 0x53, 0xa0, 0x4d, 0x98, 0x07, 0xab, 0xa4, 0xad, 0x8d, + 0x6b, 0xb4, 0xa3, 0xa4, 0x1f, 0x58, 0x19, 0xc7, 0xc3, 0xa5, 0xf0, 0x47, + 0x64, 0x8e, 0xf5, 0x8b, 0x1d, 0x7c, 0xb6, 0x14, 0x2d, 0xa3, 0xd9, 0xe7, + 0x56, 0x8c, 0xbe, 0x37, 0x33, 0x9b, 0xfb, 0xfe, 0xc3, 0x75, 0xe3, 0x2d, + 0x8d, 0x7e, 0xac, 0x4b, 0x52, 0xe7, 0x6c, 0x1e, 0x0c, 0xe6, 0x72, 0xd0, + 0x4f, 0xa4, 0xbc, 0xd3, 0xea, 0xba, 0x7f, 0x5b, 0x9a, 0xab, 0xf9, 0xd2, + 0x8e, 0xa7, 0xd8, 0x8f, 0x65, 0xc3, 0x18, 0x1c, 0x33, 0x11, 0xd5, 0x4d, + 0x64, 0xf8, 0x79, 0x43, 0x87, 0x51, 0x42, 0x1b, 0x7f, 0x2a, 0x26, 0x98, + 0x97, 0xd5, 0xa4, 0x1f, 0x24, 0x02, 0xca, 0x86, 0x18, 0x70, 0x84, 0xf1, + 0xe3, 0x21, 0x7e, 0x86, 0x13, 0x5c, 0x03, 0xe7, 0x6d, 0x23, 0x6e, 0x6c, + 0x4b, 0x01, 0x43, 0x09, 0x44, 0xf6, 0x2f, 0x96, 0x58, 0xa6, 0x84, 0xe3, + 0x01, 0xe3, 0x6c, 0x93, 0xe6, 0xe7, 0x20, 0x3f, 0x63, 0xdc, 0x53, 0x8e, + 0x87, 0x00, 0xf1, 0x30, 0x92, 0xd1, 0x60, 0x64, 0x02, 0x98, 0xa0, 0x6d, + 0x5d, 0x1b, 0x56, 0x51, 0x76, 0xa8, 0x12, 0x1f, 0x8d, 0x64, 0x63, 0xa5, + 0x75, 0x19, 0xa9, 0x5d, 0xcb, 0xda, 0xa4, 0x7e, 0x2d, 0xb6, 0x54, 0x84, + 0x43, 0xc9, 0x4a, 0xab, 0x86, 0xfd, 0x8e, 0xce, 0x7e, 0x55, 0xa9, 0xb1, + 0xb6, 0xe2, 0x70, 0xd4, 0xe7, 0xe9, 0xa5, 0xbe, 0x1b, 0x0e, 0xb1, 0xaf, + 0x46, 0x1c, 0x89, 0xe6, 0x6b, 0x67, 0xbe, 0x96, 0x9f, 0x49, 0x8e, 0xc8, + 0x59, 0x49, 0xd9, 0xca, 0xbd, 0xbc, 0xdf, 0x95, 0xf5, 0x4a, 0x0e, 0x3f, + 0xcf, 0x71, 0xa6, 0xff, 0x7e, 0x8a, 0xe3, 0x05, 0x69, 0x07, 0xde, 0xde, + 0x14, 0x74, 0xcb, 0x97, 0x8e, 0xd4, 0x7b, 0x93, 0x06, 0x64, 0x6f, 0x1b, + 0x39, 0x87, 0xd7, 0xa8, 0xf7, 0x01, 0xca, 0xf9, 0x2f, 0xe8, 0x23, 0x5c, + 0x8c, 0x65, 0x2b, 0xb0, 0xab, 0xaf, 0x12, 0x3b, 0xfb, 0x0c, 0xf4, 0x2c, + 0x6e, 0xc3, 0xa9, 0xa8, 0x89, 0x75, 0x21, 0x13, 0x2b, 0x19, 0x23, 0xfc, + 0x00, 0x0d, 0x4d, 0x87, 0xf1, 0x20, 0x63, 0x65, 0x95, 0xf2, 0xf8, 0x16, + 0xde, 0xde, 0xed, 0xc0, 0x7a, 0xfd, 0x8f, 0x68, 0xbf, 0xa6, 0xf9, 0xab, + 0x45, 0xb5, 0x18, 0x4c, 0x34, 0xa8, 0xdd, 0x9c, 0x5f, 0xa4, 0x8d, 0xfb, + 0x14, 0x74, 0xe0, 0x69, 0xfd, 0xfb, 0x6c, 0xeb, 0xb6, 0x39, 0x34, 0xb9, + 0x96, 0xba, 0x96, 0xec, 0xa3, 0x41, 0xdd, 0xca, 0xfb, 0xac, 0x6c, 0xad, + 0x74, 0x7d, 0xa3, 0xe4, 0x44, 0x4a, 0x71, 0x92, 0x32, 0x3b, 0x96, 0x8c, + 0xd0, 0x55, 0x43, 0x79, 0xba, 0xb1, 0x0b, 0x8f, 0x93, 0x9b, 0xbc, 0x4d, + 0xd2, 0x70, 0x6f, 0x5c, 0x41, 0x53, 0xbd, 0x8e, 0xf3, 0xe9, 0x6f, 0xe1, + 0xcd, 0xe1, 0x30, 0xde, 0x20, 0x07, 0x58, 0xf0, 0x97, 0xc2, 0xe9, 0x3d, + 0x38, 0x9b, 0x0e, 0xe3, 0x4c, 0xd4, 0xdb, 0xfa, 0xbc, 0x52, 0x8b, 0x9f, + 0x11, 0xd3, 0xee, 0x8e, 0x03, 0xef, 0xb1, 0x1f, 0x7f, 0xdc, 0x81, 0x4b, + 0x69, 0x15, 0x87, 0xb9, 0x37, 0x8e, 0xd0, 0x02, 0x18, 0x6d, 0x1e, 0x1c, + 0x1c, 0x78, 0x00, 0x13, 0xa9, 0x07, 0x70, 0x22, 0xf9, 0xb6, 0xe9, 0xd2, + 0xa4, 0x06, 0xe6, 0xc2, 0x25, 0x62, 0xea, 0x24, 0xa5, 0x51, 0x7a, 0x4f, + 0x2b, 0x71, 0x51, 0x33, 0x44, 0xee, 0x6f, 0xf2, 0xb7, 0x7b, 0xe3, 0x4d, + 0xd8, 0x9f, 0xa1, 0x48, 0x13, 0x3a, 0x12, 0x31, 0x19, 0xab, 0x11, 0x31, + 0x72, 0xc8, 0x5d, 0x7d, 0xe2, 0x37, 0xef, 0xc6, 0xca, 0x0a, 0x28, 0x2d, + 0x75, 0x63, 0xb9, 0x75, 0x34, 0x4d, 0xab, 0x6d, 0x4a, 0xbc, 0x49, 0xb9, + 0xf2, 0xb9, 0x1f, 0x26, 0x28, 0xf7, 0x04, 0x65, 0x7b, 0x7d, 0x3f, 0x9a, + 0xb8, 0x1f, 0xdf, 0xc2, 0xf9, 0xdd, 0x6d, 0x78, 0x93, 0x58, 0x57, 0xbe, + 0xc8, 0xd7, 0xe9, 0xb4, 0x35, 0xb0, 0xef, 0xb4, 0x99, 0xaa, 0x16, 0x99, + 0xb6, 0xe1, 0x17, 0x51, 0x91, 0x69, 0x9a, 0xd8, 0xe7, 0xf3, 0xf8, 0xed, + 0x23, 0x55, 0xd4, 0x65, 0x5b, 0x77, 0x30, 0x5b, 0xaf, 0x2b, 0xbd, 0xc7, + 0x85, 0xcb, 0xd6, 0xdc, 0x64, 0xae, 0x5f, 0x35, 0xbf, 0x5f, 0x98, 0x2b, + 0xab, 0x65, 0x7e, 0x86, 0xc9, 0x98, 0x3a, 0xc0, 0x78, 0x91, 0xb6, 0x13, + 0x80, 0xe4, 0x9c, 0xeb, 0xe3, 0x5d, 0xb0, 0x87, 0x4a, 0x0d, 0x35, 0xec, + 0x9d, 0xea, 0xc0, 0x9b, 0xb8, 0x42, 0x8e, 0x72, 0x57, 0x5c, 0x63, 0x7c, + 0x7b, 0x81, 0x63, 0xfd, 0x0b, 0x2e, 0xf2, 0xda, 0x17, 0xcf, 0xda, 0x5a, + 0x77, 0x63, 0x1b, 0xee, 0x4b, 0xcb, 0xfa, 0xfe, 0x0b, 0x07, 0xd2, 0x11, + 0x49, 0xcb, 0x3a, 0x63, 0xb4, 0x0b, 0x59, 0x67, 0xe5, 0x7f, 0xb0, 0xce, + 0x23, 0xec, 0xaf, 0x96, 0x76, 0x94, 0xf7, 0x1b, 0x65, 0x38, 0x98, 0x54, + 0x71, 0x52, 0x2f, 0xc5, 0x05, 0x55, 0xf2, 0xf5, 0xd9, 0x5a, 0x66, 0x33, + 0xe3, 0xd3, 0x21, 0x7e, 0x9e, 0x62, 0x0c, 0x75, 0x5a, 0x77, 0xe0, 0x84, + 0x5e, 0x4b, 0x9c, 0xbf, 0x55, 0x87, 0xe5, 0x1e, 0x03, 0x83, 0x8a, 0x4a, + 0x9c, 0x91, 0x9c, 0xaa, 0x75, 0x5f, 0xce, 0x16, 0xb8, 0x20, 0x39, 0x8d, + 0x82, 0xd8, 0x6f, 0xcd, 0xcb, 0x16, 0xce, 0xdc, 0x3a, 0xbf, 0x5b, 0xfb, + 0x21, 0x55, 0xd0, 0xde, 0x33, 0x9f, 0xad, 0xce, 0xf9, 0x2d, 0x65, 0x47, + 0x55, 0x16, 0x2b, 0xc4, 0x87, 0x8d, 0xe7, 0x71, 0x83, 0x7c, 0x7c, 0xdf, + 0xa3, 0xf4, 0x41, 0xf4, 0xcf, 0xcd, 0xdf, 0xdb, 0xaa, 0x49, 0x9c, 0x97, + 0x7a, 0x74, 0x99, 0x56, 0x00, 0xbb, 0xe5, 0x67, 0x0f, 0x6f, 0xce, 0xf2, + 0xf9, 0xf4, 0xe6, 0x6c, 0x8c, 0x7a, 0x74, 0xf3, 0x5d, 0xd6, 0xf7, 0x8f, + 0x36, 0xfb, 0x52, 0x37, 0x7c, 0x55, 0x96, 0x2f, 0x5b, 0x67, 0x6d, 0xd0, + 0xab, 0x1b, 0xca, 0x8a, 0x46, 0xf1, 0xd7, 0x79, 0x8e, 0x22, 0x6d, 0x02, + 0xca, 0x89, 0xa8, 0x61, 0xba, 0xb5, 0x62, 0xfa, 0x7a, 0x28, 0x63, 0x8c, + 0xc5, 0xa6, 0xac, 0xba, 0xa7, 0x86, 0x37, 0xd2, 0x12, 0x13, 0x83, 0xfa, + 0xfb, 0xbf, 0xb1, 0x6b, 0x37, 0xda, 0x8b, 0x16, 0x93, 0xb3, 0xd3, 0xcf, + 0x3d, 0x1b, 0x72, 0xe0, 0xfd, 0x74, 0x76, 0x3d, 0xef, 0x0d, 0x97, 0xe0, + 0xdd, 0x94, 0xf8, 0x6b, 0xa8, 0x85, 0xec, 0xf7, 0x64, 0x5a, 0x63, 0x6c, + 0x2a, 0xe3, 0xb6, 0x61, 0xdb, 0x98, 0x03, 0xfb, 0xa3, 0x1a, 0x62, 0x89, + 0x9f, 0x9a, 0x45, 0x9a, 0x6f, 0xc2, 0x6f, 0x77, 0x60, 0x5f, 0x7a, 0x12, + 0x63, 0x7d, 0x1f, 0x9b, 0x76, 0xad, 0x0b, 0x1f, 0x85, 0x26, 0xc9, 0xeb, + 0xa4, 0xfe, 0xa9, 0x63, 0xd7, 0x80, 0xc6, 0x58, 0xda, 0x86, 0x9d, 0x8b, + 0x5b, 0xb0, 0x6b, 0xac, 0x19, 0xc6, 0x21, 0x0f, 0x76, 0x92, 0xf0, 0x4d, + 0x0c, 0x4f, 0xe2, 0x54, 0x52, 0x6b, 0x2a, 0x52, 0x26, 0x71, 0x92, 0xe3, + 0x6c, 0x4d, 0xbc, 0x05, 0x83, 0x7d, 0x6c, 0x4b, 0x4a, 0x8e, 0x57, 0xc6, + 0x99, 0x44, 0x77, 0xea, 0x76, 0x35, 0x8f, 0x36, 0xec, 0x48, 0x6c, 0x69, + 0xcf, 0xd6, 0x3d, 0x88, 0xab, 0x69, 0x4d, 0xe9, 0xe5, 0x1e, 0x1d, 0x4e, + 0xe7, 0x6b, 0x20, 0x82, 0xa1, 0x59, 0x3c, 0xdc, 0x96, 0xd6, 0xd1, 0x3b, + 0xd0, 0xc2, 0xf6, 0x1a, 0xba, 0x13, 0x52, 0x3f, 0xf6, 0x71, 0x3c, 0x13, + 0xef, 0xe9, 0x5e, 0xf7, 0x5d, 0xfc, 0x1e, 0xd1, 0x3b, 0xb1, 0x81, 0xfd, + 0x08, 0xe7, 0xd2, 0x14, 0x6f, 0x93, 0x01, 0x3b, 0x7e, 0xa5, 0xdb, 0x61, + 0x54, 0xd9, 0x71, 0x44, 0x2f, 0x23, 0x3f, 0xb7, 0xa3, 0x21, 0x44, 0xdf, + 0x9c, 0xf3, 0xd5, 0x1f, 0x26, 0x15, 0x3c, 0x40, 0x2c, 0x3d, 0x16, 0x6a, + 0x68, 0x5f, 0x2e, 0x6c, 0xf7, 0x80, 0x82, 0x2b, 0xda, 0x35, 0xd3, 0xa0, + 0xbf, 0x72, 0xf9, 0xf3, 0x7b, 0xf3, 0x6b, 0x33, 0x5b, 0x03, 0xfe, 0xc2, + 0xcc, 0x3f, 0x37, 0xc5, 0xf9, 0x3d, 0xc6, 0xe7, 0xee, 0x5a, 0xd4, 0xd0, + 0x29, 0xcf, 0xb9, 0x89, 0xe3, 0xf2, 0x9c, 0xe4, 0xf6, 0x6f, 0x3c, 0xa7, + 0x63, 0xdb, 0x40, 0xc4, 0x9a, 0xef, 0xf6, 0x04, 0x16, 0x3a, 0x20, 0x76, + 0xd4, 0xa0, 0x5e, 0x02, 0xba, 0x26, 0xf5, 0x19, 0xe4, 0x37, 0xfe, 0xc0, + 0x53, 0x10, 0x39, 0x49, 0xbc, 0xf9, 0x16, 0x76, 0x46, 0x87, 0xc1, 0x98, + 0x93, 0xf8, 0xe6, 0x5f, 0x3b, 0x84, 0x14, 0x9e, 0x4b, 0xa7, 0xf0, 0xbc, + 0x70, 0x6c, 0x2b, 0xc7, 0x96, 0xc6, 0x77, 0xa2, 0x6f, 0x21, 0x66, 0xc5, + 0x55, 0x87, 0xf1, 0x44, 0xf4, 0xdd, 0x6a, 0xc9, 0x65, 0x6e, 0x4d, 0x2c, + 0x65, 0xff, 0x22, 0x53, 0x6f, 0xab, 0x81, 0x2f, 0xd9, 0xff, 0x52, 0x6c, + 0x19, 0x92, 0x9c, 0x90, 0x89, 0xd7, 0xc9, 0xa9, 0xae, 0x50, 0x8f, 0x5a, + 0x1a, 0xa5, 0xff, 0x71, 0x45, 0xb3, 0x7c, 0x57, 0x1b, 0xf7, 0x78, 0x16, + 0xdc, 0x94, 0x73, 0x59, 0x46, 0x53, 0xee, 0x8a, 0xc9, 0x9e, 0x3b, 0x60, + 0xcb, 0x78, 0xf0, 0x18, 0x79, 0x49, 0xe1, 0xc8, 0x8f, 0x14, 0xf1, 0x5f, + 0x35, 0xe4, 0xa2, 0xee, 0x03, 0x1e, 0x65, 0xc1, 0x1e, 0x17, 0x1e, 0x88, + 0x91, 0xa3, 0xc6, 0x9a, 0xb1, 0x65, 0xaf, 0xc6, 0x36, 0x5e, 0xfd, 0x1c, + 0xe3, 0xd6, 0x93, 0xf0, 0x79, 0x86, 0xc8, 0xa5, 0xdc, 0xc4, 0x60, 0xc7, + 0x48, 0x39, 0x4a, 0xc8, 0xb3, 0xa5, 0xdc, 0x5c, 0x3a, 0xe2, 0x46, 0x0d, + 0xfd, 0x99, 0x3b, 0x73, 0x1e, 0x63, 0x7b, 0xa0, 0x96, 0x84, 0x3f, 0x37, + 0x0b, 0x35, 0xa9, 0x57, 0x06, 0x50, 0x9e, 0xd9, 0x84, 0x74, 0x2c, 0x88, + 0x52, 0xf2, 0xfb, 0x06, 0x8e, 0x77, 0x7f, 0x4c, 0x63, 0x3f, 0x59, 0x6e, + 0xb3, 0x9c, 0xcf, 0xf4, 0x26, 0xbc, 0x6b, 0xa5, 0xde, 0x78, 0x45, 0x7f, + 0x0d, 0x45, 0x7d, 0x37, 0xce, 0x9c, 0x69, 0x21, 0xcc, 0x21, 0xf7, 0x68, + 0x7d, 0x1a, 0xd9, 0xf3, 0x67, 0x2b, 0x72, 0xeb, 0x09, 0xca, 0x7a, 0x9c, + 0x6d, 0xd4, 0x83, 0xd9, 0x98, 0xc1, 0xf5, 0x5c, 0xa4, 0xde, 0xdc, 0xcb, + 0xb9, 0x5e, 0x63, 0xec, 0xd0, 0xc9, 0xb5, 0xbc, 0x3f, 0xfc, 0x23, 0xa5, + 0x86, 0x6b, 0x99, 0x22, 0x57, 0xfd, 0x38, 0xe5, 0x51, 0x7c, 0x5c, 0xcb, + 0x77, 0x79, 0xff, 0x3b, 0x5c, 0xcb, 0xd6, 0xbd, 0xde, 0xd6, 0xe3, 0x8a, + 0xb7, 0x7d, 0x8d, 0xe2, 0x53, 0xb7, 0x2a, 0xa5, 0xb8, 0x38, 0x5c, 0x8e, + 0x4b, 0xf4, 0xbd, 0xd7, 0x86, 0x2b, 0x71, 0x79, 0xb8, 0x8a, 0x36, 0xa2, + 0xb1, 0x0f, 0xd3, 0x2c, 0xd3, 0xdc, 0x98, 0x4a, 0x3f, 0x8f, 0x19, 0xb1, + 0x5a, 0x7c, 0x9c, 0xde, 0x80, 0xf2, 0x98, 0xc4, 0x00, 0x1e, 0x7c, 0xc4, + 0xfb, 0x1f, 0xa6, 0x47, 0x51, 0xbc, 0xe7, 0x73, 0xb6, 0x31, 0xcd, 0xfb, + 0xb9, 0xbe, 0xcb, 0xe9, 0x0e, 0x94, 0xee, 0xd9, 0x08, 0xc7, 0x1e, 0xb3, + 0x6b, 0x4b, 0x08, 0x3f, 0xb3, 0x73, 0x2d, 0xdd, 0xba, 0x77, 0xe2, 0x2e, + 0x7b, 0x90, 0x7d, 0x8c, 0x2b, 0x0b, 0x32, 0x1b, 0x51, 0xbe, 0xc7, 0x83, + 0x67, 0x29, 0xc3, 0x51, 0x68, 0x81, 0x35, 0xca, 0x46, 0x14, 0x8c, 0x64, + 0xd7, 0xbf, 0x2e, 0x93, 0xb5, 0x8b, 0xfb, 0x1b, 0xa7, 0xc7, 0x32, 0x6e, + 0x8b, 0x77, 0x4f, 0xa6, 0x4b, 0x70, 0x3a, 0x25, 0xf2, 0x81, 0xea, 0x08, + 0x8f, 0xa2, 0x70, 0x0f, 0x31, 0x71, 0x58, 0xb7, 0xf8, 0x82, 0xd8, 0xc4, + 0x70, 0xfa, 0x76, 0x36, 0x15, 0xc4, 0xce, 0x44, 0x0d, 0xed, 0xa9, 0x16, + 0x2b, 0xf7, 0x48, 0x8d, 0x79, 0xe2, 0x5e, 0x17, 0xb5, 0xe8, 0x50, 0xfa, + 0x56, 0x7b, 0x6a, 0xa4, 0x6e, 0x0a, 0xb6, 0x9a, 0x98, 0xd4, 0xb3, 0x78, + 0x73, 0xcc, 0xaa, 0x61, 0x8b, 0x4d, 0xb6, 0x62, 0xcb, 0x00, 0xda, 0xf7, + 0x37, 0x8a, 0x4d, 0x3a, 0x31, 0x44, 0xbe, 0x7f, 0x91, 0xb1, 0xc3, 0x0c, + 0xed, 0x73, 0x62, 0x42, 0x01, 0x06, 0x87, 0x5d, 0xf8, 0xf1, 0xb0, 0x07, + 0xee, 0x58, 0x31, 0xc6, 0x29, 0xe3, 0x31, 0x72, 0x9c, 0x8f, 0x18, 0x65, + 0x8f, 0xd2, 0xa7, 0x7e, 0x18, 0xad, 0x42, 0x26, 0x5d, 0x8b, 0xab, 0xc4, + 0x94, 0x34, 0xf7, 0xe3, 0x83, 0x68, 0x00, 0x2f, 0xa7, 0x83, 0x78, 0x3f, + 0x2a, 0xd8, 0x13, 0xc4, 0x11, 0xca, 0xaf, 0x28, 0xe6, 0x66, 0xbf, 0x82, + 0x43, 0x1e, 0x38, 0x63, 0x9a, 0x67, 0x28, 0xa7, 0x0b, 0x8e, 0x4c, 0x2b, + 0xed, 0x46, 0xce, 0x44, 0x88, 0x1f, 0x70, 0xe8, 0x43, 0x8c, 0xb9, 0x07, + 0x83, 0xf9, 0xfc, 0xaf, 0xd7, 0x3d, 0x81, 0x99, 0xb4, 0x9d, 0x2f, 0x4d, + 0x55, 0x93, 0x98, 0x2a, 0x19, 0xba, 0x12, 0xd5, 0x24, 0x17, 0x48, 0x6c, + 0x37, 0x14, 0xe7, 0x62, 0x72, 0x89, 0xaa, 0xad, 0x92, 0x17, 0xe6, 0xfc, + 0xe5, 0x6c, 0x99, 0xc9, 0x76, 0x57, 0x31, 0xff, 0xc0, 0xd6, 0x59, 0xb9, + 0x1c, 0x93, 0x7a, 0x83, 0xf7, 0xe5, 0x31, 0x5e, 0xe2, 0xb5, 0xdd, 0xa1, + 0xd7, 0xa2, 0x7f, 0x3f, 0x4b, 0xea, 0x71, 0xc7, 0x11, 0xa4, 0x4c, 0x6e, + 0x17, 0x0f, 0x98, 0x78, 0x93, 0x18, 0x72, 0x39, 0x29, 0xbc, 0x48, 0xf8, + 0x50, 0x17, 0x7d, 0x4f, 0x19, 0xf9, 0x80, 0x86, 0x6d, 0xe4, 0xeb, 0xbe, + 0xf8, 0x04, 0xe3, 0x91, 0xaf, 0x93, 0x93, 0x95, 0xb3, 0x9b, 0x1f, 0x70, + 0xbc, 0x56, 0xec, 0xa4, 0x2d, 0x16, 0x69, 0x77, 0x61, 0x25, 0xf9, 0x8e, + 0x43, 0xa3, 0xcb, 0x78, 0x58, 0xfc, 0x86, 0xe4, 0x70, 0x54, 0xa9, 0x95, + 0xad, 0x7d, 0x1d, 0xf7, 0xa2, 0xbd, 0xda, 0x05, 0xa9, 0x6f, 0xbd, 0x81, + 0x25, 0x48, 0x3d, 0x2a, 0xbe, 0x93, 0x1c, 0x39, 0xac, 0x19, 0xe7, 0x31, + 0xcf, 0x62, 0xdd, 0xc5, 0x61, 0x99, 0x4f, 0x15, 0x65, 0xaf, 0xe2, 0x1d, + 0xca, 0xf5, 0x52, 0xd4, 0x37, 0x75, 0x1f, 0x1a, 0x4e, 0x5d, 0xb2, 0x4b, + 0xed, 0x4f, 0xda, 0x07, 0xa1, 0xb1, 0xbf, 0x4f, 0xa3, 0x21, 0xf4, 0xa9, + 0x72, 0x2d, 0xfc, 0xb0, 0x15, 0xdd, 0x43, 0x32, 0x07, 0xd3, 0xac, 0x24, + 0x1e, 0x3e, 0x6c, 0x8d, 0x2f, 0x63, 0xdf, 0x1a, 0x5b, 0x78, 0x19, 0x49, + 0xe7, 0xe3, 0x8b, 0x49, 0x1c, 0x4e, 0x52, 0xfe, 0x8b, 0xdf, 0xa6, 0x1c, + 0x26, 0x31, 0x9c, 0xd2, 0xc8, 0x1d, 0x4b, 0xe0, 0xa9, 0x0e, 0x62, 0x17, + 0xfd, 0x75, 0x8c, 0xed, 0xd3, 0xb1, 0x12, 0x18, 0xd5, 0xd9, 0x31, 0xbf, + 0x1e, 0xbf, 0x6a, 0x4e, 0x3c, 0x64, 0xc5, 0xa9, 0xbc, 0xfe, 0x1d, 0x9f, + 0x99, 0x2d, 0xc7, 0x32, 0xb1, 0x3e, 0x76, 0xd9, 0x9c, 0x68, 0x9d, 0xfe, + 0x7b, 0x85, 0x75, 0xa6, 0x2a, 0x62, 0xab, 0xe6, 0x77, 0x56, 0x2e, 0xdd, + 0x94, 0xcb, 0x0c, 0xed, 0x2d, 0xf3, 0x41, 0x6b, 0x5e, 0xef, 0xcd, 0x12, + 0x2e, 0x5f, 0x17, 0xf7, 0xcc, 0x46, 0x71, 0x15, 0xdb, 0x10, 0x43, 0xc3, + 0x5a, 0xd3, 0x29, 0xfc, 0x8b, 0x79, 0xe1, 0xa6, 0x7e, 0x66, 0xf2, 0x9e, + 0xf8, 0x9e, 0x0b, 0xb9, 0x9c, 0x8f, 0x3b, 0xc7, 0xf7, 0x27, 0x71, 0x3c, + 0x29, 0xd8, 0xef, 0xc1, 0x13, 0x92, 0x9b, 0x52, 0xbd, 0xbd, 0x06, 0x26, + 0xc8, 0xf1, 0xde, 0xa6, 0xec, 0x25, 0xff, 0x38, 0x41, 0x9e, 0x37, 0xdd, + 0x37, 0x45, 0x90, 0xaa, 0x92, 0x1a, 0x8c, 0xe0, 0xe7, 0x24, 0xb6, 0x27, + 0x7f, 0x4a, 0x1c, 0xfb, 0x98, 0xbc, 0xa7, 0x8b, 0x9c, 0x7a, 0x12, 0x5b, + 0x52, 0xcd, 0x78, 0x69, 0x6f, 0x0b, 0x71, 0x45, 0xb0, 0xd1, 0x77, 0xea, + 0xa2, 0xbd, 0x19, 0xfb, 0x0f, 0xa5, 0x91, 0x1a, 0x11, 0x7f, 0x28, 0x3e, + 0x57, 0x7c, 0xa1, 0x86, 0x68, 0xe2, 0x24, 0x0c, 0x7e, 0xef, 0x4c, 0x6c, + 0x44, 0x64, 0xe4, 0x2d, 0xf2, 0xf8, 0x49, 0x2c, 0xef, 0xd3, 0xd6, 0x1e, + 0xc4, 0x24, 0x56, 0xd1, 0x57, 0x26, 0x13, 0x2d, 0xec, 0xbf, 0x19, 0x3d, + 0x7b, 0xbd, 0x56, 0xbe, 0x49, 0x62, 0xf8, 0x6d, 0x63, 0x11, 0x18, 0x43, + 0x72, 0x36, 0xc3, 0x85, 0x60, 0xdc, 0xa3, 0x7c, 0x48, 0x3e, 0xdc, 0x10, + 0xf7, 0x32, 0x06, 0xf3, 0x1a, 0xab, 0x14, 0x9f, 0xa7, 0xc0, 0x26, 0xb5, + 0xc0, 0x19, 0x38, 0xa5, 0x2b, 0x28, 0xba, 0x57, 0x41, 0x88, 0xbe, 0xca, + 0x33, 0x8b, 0x3e, 0x64, 0x48, 0x47, 0xcf, 0x00, 0xd7, 0x7b, 0x7d, 0xdf, + 0x64, 0xbf, 0x56, 0xb3, 0x3f, 0xd9, 0xbb, 0x16, 0xf4, 0x8c, 0xf9, 0x3a, + 0x4e, 0xc1, 0x6d, 0x71, 0xab, 0x9e, 0x81, 0xeb, 0x79, 0x81, 0xd2, 0x8f, + 0x1b, 0xbd, 0x81, 0x19, 0x8a, 0xb4, 0xdd, 0x4a, 0xcc, 0x9a, 0xde, 0xde, + 0x50, 0x92, 0x8b, 0xc9, 0x3f, 0x6d, 0x62, 0x17, 0xdd, 0x96, 0xbd, 0x88, + 0x2c, 0x7a, 0x92, 0x11, 0xea, 0xf4, 0x4f, 0xcc, 0x54, 0x6b, 0x2b, 0xe7, + 0xd9, 0x28, 0xb5, 0x31, 0x0b, 0x13, 0xce, 0x4a, 0x2e, 0xce, 0x29, 0x98, + 0xd0, 0xdd, 0xee, 0xa2, 0x3e, 0x15, 0x12, 0x97, 0x8a, 0x46, 0x5d, 0x70, + 0x1d, 0x2c, 0x41, 0xe1, 0xa0, 0xf0, 0x31, 0xc9, 0x41, 0xa8, 0xb0, 0x8f, + 0x96, 0xd2, 0x06, 0xb8, 0x87, 0xa3, 0xb4, 0xb1, 0xa8, 0x1b, 0xf3, 0x46, + 0xdd, 0xf8, 0x31, 0x31, 0xa0, 0x66, 0x54, 0xc3, 0x38, 0x31, 0xc0, 0x3d, + 0x1a, 0xc0, 0x58, 0x34, 0x88, 0x19, 0xa3, 0xe3, 0xca, 0x1b, 0xe9, 0x66, + 0xee, 0xb7, 0x8c, 0x23, 0x32, 0xcc, 0xef, 0xa9, 0xec, 0x67, 0x0b, 0xb1, + 0x4e, 0xf6, 0x36, 0x80, 0x1d, 0x03, 0x69, 0x2c, 0xdb, 0x63, 0xe2, 0x9f, + 0xf4, 0x06, 0x77, 0x91, 0x22, 0xb1, 0x80, 0x89, 0x34, 0xfd, 0xda, 0x0a, + 0xdd, 0xbb, 0x56, 0xce, 0x3b, 0xb7, 0x57, 0x99, 0x28, 0x08, 0x79, 0x75, + 0xa2, 0xfb, 0xda, 0x22, 0x45, 0x7c, 0x54, 0x83, 0x67, 0x03, 0xe6, 0x22, + 0x5b, 0x57, 0xbc, 0x0f, 0x1b, 0x54, 0x85, 0xb6, 0xd8, 0x82, 0x9d, 0x15, + 0x86, 0xeb, 0x4a, 0xa3, 0x69, 0xae, 0x0b, 0xd5, 0xcd, 0xb2, 0x72, 0xd0, + 0xb6, 0xf5, 0xfc, 0x6e, 0xe3, 0x9a, 0x65, 0xdd, 0x1d, 0x88, 0xed, 0x56, + 0x90, 0xf6, 0x77, 0x20, 0x3a, 0xdc, 0x21, 0xfc, 0x89, 0x78, 0xd0, 0x4b, + 0x3c, 0x30, 0xbb, 0x9e, 0x0e, 0x3d, 0x88, 0xcb, 0x96, 0xc7, 0x97, 0x67, + 0xbc, 0x01, 0x8f, 0x6d, 0xfa, 0x1e, 0xe8, 0xb3, 0x25, 0xcf, 0x21, 0x76, + 0xd3, 0xdc, 0x27, 0xbc, 0xd9, 0xdf, 0xdb, 0xc3, 0xbd, 0x7f, 0xe8, 0x80, + 0xf8, 0x17, 0xd3, 0xec, 0x25, 0x2f, 0x45, 0x85, 0xac, 0x41, 0x43, 0x3c, + 0x61, 0x7e, 0x5c, 0xa3, 0xf9, 0xa6, 0x76, 0xd1, 0x8f, 0x9f, 0xdf, 0xd3, + 0xb0, 0x61, 0x83, 0x70, 0x96, 0x45, 0x1a, 0x63, 0xe9, 0x34, 0xce, 0x8d, + 0xcc, 0x47, 0xea, 0x21, 0xae, 0x87, 0xfb, 0xe4, 0x8c, 0x7f, 0xc1, 0x38, + 0x43, 0xb0, 0x4f, 0x53, 0x0f, 0x13, 0xf7, 0x6c, 0xa3, 0x7e, 0x6c, 0xa9, + 0x80, 0x71, 0xa5, 0x51, 0xc6, 0xbf, 0x3e, 0x7f, 0xae, 0xb7, 0x19, 0xbb, + 0xf6, 0x0a, 0xaf, 0x10, 0xfe, 0xe5, 0x33, 0x3e, 0x40, 0x0b, 0x92, 0x63, + 0xd9, 0xb1, 0xa2, 0x89, 0x5b, 0xf5, 0x44, 0xf6, 0xfc, 0x24, 0x76, 0x50, + 0x27, 0x5d, 0xec, 0x9f, 0x3e, 0x85, 0xfd, 0x69, 0x81, 0x22, 0x19, 0x6f, + 0xf4, 0x27, 0xe6, 0xce, 0x6a, 0x91, 0x8d, 0xf4, 0xff, 0x9b, 0x6a, 0xc1, + 0x8b, 0x75, 0xa1, 0xaf, 0x5a, 0xeb, 0x15, 0x7e, 0x4b, 0xce, 0x3a, 0x3f, + 0x1f, 0x79, 0xe6, 0x76, 0xf3, 0xf9, 0x9c, 0xed, 0x64, 0x4e, 0x1d, 0xd8, + 0xb1, 0x1b, 0x46, 0xb1, 0xa6, 0x45, 0xe6, 0x2b, 0x1d, 0xe8, 0xa5, 0x7c, + 0xb7, 0x25, 0x3b, 0xb0, 0x9f, 0xf6, 0x3a, 0xa8, 0x1f, 0xab, 0xb1, 0xa1, + 0x7e, 0xca, 0x8e, 0x89, 0x7f, 0x94, 0x9a, 0xc5, 0x82, 0x45, 0x7e, 0xda, + 0x56, 0x07, 0xe2, 0xa9, 0x73, 0xb3, 0xad, 0x9a, 0xa8, 0x4d, 0x7c, 0x9e, + 0xc8, 0xa2, 0x13, 0xc5, 0x7d, 0x27, 0xe1, 0xec, 0xeb, 0x44, 0x91, 0x7f, + 0x09, 0x56, 0x84, 0x2e, 0x98, 0x97, 0x35, 0x87, 0xfb, 0x38, 0xe5, 0x73, + 0x2c, 0x58, 0xc3, 0x98, 0x91, 0x71, 0xca, 0xd0, 0x1c, 0xda, 0x7d, 0x23, + 0x76, 0x8c, 0xc9, 0x59, 0x08, 0x1b, 0x56, 0x2d, 0x96, 0x58, 0x5c, 0xa1, + 0x5e, 0xcf, 0x62, 0x3c, 0xa9, 0xa9, 0xcf, 0x59, 0xe7, 0x56, 0xc8, 0xb9, + 0xaa, 0x3c, 0x78, 0xd2, 0x3a, 0xaf, 0x21, 0xf7, 0x37, 0x31, 0x0e, 0xd8, + 0x84, 0x9a, 0x98, 0x61, 0x8a, 0xbc, 0x8f, 0x23, 0xf2, 0xa2, 0x8d, 0xf3, + 0x68, 0x5a, 0xe4, 0xdf, 0x30, 0xa5, 0x88, 0x3e, 0xfb, 0xdb, 0x47, 0x15, + 0xdd, 0xb5, 0x3a, 0xa3, 0x20, 0xd0, 0xc7, 0xbe, 0x42, 0x23, 0xb3, 0xb3, + 0xb9, 0xf1, 0x3c, 0xbf, 0xdb, 0x44, 0x5e, 0xb0, 0x09, 0x65, 0x31, 0xe1, + 0xe4, 0x82, 0x0b, 0x91, 0xa5, 0xe5, 0x7c, 0x3e, 0x1d, 0xf2, 0xb7, 0x96, + 0x2a, 0xc2, 0x7d, 0xfc, 0x4d, 0xab, 0x14, 0xe1, 0x2a, 0xf2, 0x9c, 0xee, + 0xaa, 0xcf, 0x9c, 0xcf, 0xd5, 0x31, 0x1b, 0x89, 0x0d, 0x72, 0xce, 0x24, + 0x7f, 0xd6, 0xea, 0x46, 0xce, 0xda, 0x19, 0x97, 0xd8, 0xe1, 0x68, 0x68, + 0x59, 0xb4, 0x89, 0x38, 0x67, 0x2e, 0x39, 0x44, 0xbd, 0xbf, 0x88, 0x2a, + 0xfc, 0x73, 0x54, 0x30, 0xcd, 0x83, 0x9f, 0x47, 0x0b, 0x25, 0x26, 0x4e, + 0x49, 0x5e, 0xf6, 0x4c, 0xd2, 0x30, 0x29, 0xd7, 0x96, 0x55, 0xd4, 0xa5, + 0x40, 0xa8, 0x14, 0xa8, 0xee, 0x7e, 0xd2, 0x69, 0xc5, 0xe8, 0x65, 0xa8, + 0x20, 0xfe, 0xf7, 0x0d, 0xfd, 0xa1, 0xf3, 0x0e, 0xc4, 0xe0, 0x62, 0xc9, + 0x15, 0xda, 0xb1, 0x2d, 0xf4, 0x1b, 0x33, 0xd5, 0x26, 0xcf, 0xd4, 0xe2, + 0xdc, 0x6e, 0xd1, 0xd3, 0x00, 0x0a, 0xe3, 0xe7, 0xa9, 0x93, 0x2a, 0xce, + 0x46, 0x7d, 0xfa, 0x1a, 0xdb, 0xb7, 0xa8, 0xff, 0xf3, 0x6e, 0xc2, 0xed, + 0x79, 0xda, 0x03, 0x78, 0xdc, 0xc2, 0xed, 0x30, 0xb6, 0xd0, 0x2f, 0x90, + 0xb7, 0xed, 0x7b, 0xd2, 0xa6, 0xd2, 0x9f, 0xfb, 0x54, 0x1f, 0x63, 0xea, + 0x2d, 0x1c, 0x43, 0xf8, 0xe4, 0x4c, 0xf2, 0xbd, 0xa7, 0xa3, 0x0d, 0x9e, + 0x5f, 0xe3, 0x09, 0xda, 0xa3, 0x8c, 0x21, 0x6b, 0xd2, 0x50, 0xca, 0xd8, + 0xf1, 0x04, 0xd7, 0xb1, 0xad, 0x22, 0x3b, 0x6e, 0x79, 0xae, 0xef, 0xf8, + 0x90, 0xf0, 0xad, 0x7b, 0xb0, 0xc6, 0xea, 0x3b, 0x68, 0xd9, 0xe6, 0xbe, + 0xa8, 0x82, 0x19, 0xf5, 0x1a, 0x12, 0xe9, 0x66, 0x6c, 0xac, 0xac, 0xc5, + 0xfe, 0xc4, 0x26, 0x2c, 0x24, 0xe7, 0x7d, 0xa4, 0xd2, 0xa0, 0x5f, 0x24, + 0x06, 0xc5, 0x35, 0x75, 0xbe, 0xf2, 0x8d, 0x5c, 0xae, 0xba, 0x0a, 0x8e, + 0xb8, 0xf8, 0xbb, 0x02, 0xf4, 0xab, 0x73, 0x51, 0x62, 0x9d, 0x81, 0xcc, + 0xf6, 0xbd, 0x6b, 0xc8, 0x9b, 0xf3, 0x81, 0x44, 0x8d, 0xb8, 0x75, 0x4e, + 0x25, 0xf0, 0x3c, 0x79, 0x44, 0x8a, 0xde, 0xaf, 0x20, 0xac, 0xa5, 0xd6, + 0xa3, 0x08, 0xc6, 0x2c, 0xc1, 0x43, 0x79, 0x66, 0xce, 0x2d, 0x73, 0xaa, + 0xcc, 0xcd, 0x29, 0x7f, 0xff, 0x34, 0xef, 0x89, 0x6e, 0x09, 0xb7, 0x90, + 0xdf, 0x8b, 0xd1, 0x4a, 0x7d, 0xaa, 0xe2, 0x9c, 0x13, 0x09, 0xb9, 0xef, + 0xd5, 0x0d, 0x5b, 0x23, 0x3e, 0xdb, 0x93, 0xd5, 0xc1, 0xb5, 0x75, 0xdc, + 0xff, 0xf2, 0x46, 0x4c, 0x8d, 0x88, 0x2f, 0xfb, 0xc3, 0x67, 0x50, 0x8c, + 0xeb, 0x67, 0x50, 0x44, 0xae, 0xde, 0x53, 0xef, 0xa0, 0x61, 0xe2, 0x31, + 0xdb, 0x61, 0x13, 0x33, 0x45, 0xc6, 0x71, 0xb7, 0xc4, 0x9a, 0x36, 0x72, + 0x08, 0x23, 0x3d, 0xee, 0x16, 0x3f, 0xe9, 0x88, 0x03, 0xf3, 0xe2, 0x06, + 0x0a, 0xc3, 0xda, 0xbe, 0x2b, 0xf6, 0x6b, 0x66, 0xfb, 0xac, 0x39, 0x8c, + 0xf9, 0x6e, 0xac, 0xb9, 0x97, 0x73, 0xb7, 0x6b, 0x3f, 0x31, 0xef, 0xab, + 0x92, 0x39, 0xfe, 0xd2, 0x9d, 0x3d, 0xfb, 0x70, 0x07, 0xe5, 0x92, 0x97, + 0x89, 0x49, 0xfd, 0xf9, 0x2b, 0xf3, 0x9b, 0x37, 0xdd, 0x17, 0x2e, 0x23, + 0x7a, 0x3a, 0xfd, 0x3c, 0xa0, 0xe8, 0xac, 0xd4, 0x56, 0x26, 0x71, 0x28, + 0x29, 0xba, 0x2b, 0x32, 0x8e, 0xe0, 0x22, 0x79, 0x61, 0x41, 0xff, 0x24, + 0x06, 0xc9, 0x0b, 0xed, 0x71, 0xef, 0x3e, 0x4a, 0x12, 0x1b, 0xd5, 0x25, + 0xc4, 0xea, 0x32, 0xce, 0x23, 0x3f, 0x87, 0x3a, 0x4b, 0xee, 0xe2, 0x5f, + 0x76, 0x72, 0xbd, 0x45, 0xe4, 0x48, 0xcd, 0xb1, 0x42, 0x68, 0x15, 0xe5, + 0x28, 0xd5, 0xe4, 0x0c, 0x7c, 0xb6, 0x5d, 0x94, 0x73, 0x29, 0xd1, 0xe6, + 0x62, 0x95, 0xd5, 0xd6, 0x63, 0x9d, 0x01, 0xd1, 0x2a, 0xc5, 0xff, 0x8a, + 0xcf, 0x25, 0xdf, 0x5e, 0x2c, 0x3e, 0x37, 0xcc, 0xb9, 0xcd, 0xc9, 0xd5, + 0x99, 0x56, 0x59, 0xf7, 0xf7, 0x25, 0x2e, 0x7c, 0xd9, 0x9f, 0xf8, 0x3d, + 0x9f, 0xe9, 0x80, 0xba, 0xb7, 0x18, 0x0f, 0xfd, 0x65, 0x09, 0xf4, 0xca, + 0x6c, 0xae, 0x7c, 0x5e, 0x38, 0x1a, 0x32, 0x13, 0xc2, 0x93, 0xee, 0x84, + 0x67, 0xb6, 0x8c, 0x25, 0x18, 0x20, 0x7b, 0x21, 0x7b, 0x27, 0x39, 0xdc, + 0xdb, 0xd5, 0x18, 0xbc, 0xea, 0xc4, 0xf5, 0x7d, 0x98, 0x0f, 0xed, 0xe1, + 0x2a, 0xae, 0x2d, 0xeb, 0x23, 0x76, 0xd0, 0x47, 0x04, 0xfc, 0x59, 0x0c, + 0x93, 0x1a, 0xbd, 0x93, 0x3e, 0x62, 0x84, 0x3e, 0xe2, 0xa2, 0x5e, 0x8e, + 0xe5, 0x39, 0x1f, 0xd1, 0x6e, 0xd3, 0xad, 0xfe, 0x9d, 0xda, 0x7d, 0x35, + 0xc4, 0x30, 0x8e, 0xf1, 0xb5, 0x9b, 0xb8, 0xd8, 0x4c, 0xed, 0x97, 0xe6, + 0x23, 0x55, 0xb2, 0xc6, 0xe6, 0x9a, 0x6c, 0x8e, 0xbc, 0x03, 0xfb, 0x88, + 0x8f, 0x35, 0x9a, 0x3c, 0xa3, 0x25, 0x6b, 0xec, 0x1d, 0xe8, 0x67, 0xff, + 0x7d, 0xc4, 0xc8, 0x18, 0x31, 0x52, 0x5f, 0x78, 0xec, 0x45, 0x15, 0xf5, + 0x1d, 0x64, 0x0f, 0xdf, 0x16, 0x6c, 0x79, 0x99, 0xd8, 0xf2, 0x3c, 0x31, + 0x72, 0x67, 0x4a, 0xc6, 0x91, 0xf1, 0xf2, 0xe3, 0x48, 0x9f, 0xff, 0x66, + 0xae, 0xaf, 0x92, 0xb9, 0xde, 0x6e, 0x1e, 0xf2, 0xdb, 0x9f, 0xf2, 0xef, + 0x62, 0x8b, 0x43, 0xf5, 0x26, 0xa6, 0x9f, 0xa9, 0x98, 0x24, 0xbe, 0x5a, + 0x71, 0x00, 0xfd, 0x6b, 0x04, 0x2b, 0x17, 0xab, 0xb8, 0x1c, 0x9d, 0x44, + 0xd1, 0x81, 0x3c, 0x16, 0x99, 0x4b, 0x4e, 0x10, 0x87, 0x06, 0x21, 0xd8, + 0xd3, 0xc4, 0x3d, 0x30, 0x68, 0x13, 0x65, 0x18, 0x4d, 0xca, 0xd9, 0x0b, + 0x13, 0xbb, 0x42, 0x2e, 0x72, 0xd8, 0xee, 0xe3, 0x05, 0x96, 0x4f, 0x28, + 0x23, 0x5e, 0xe7, 0xf9, 0xb5, 0x70, 0x6b, 0xc1, 0x1a, 0xc6, 0x11, 0x43, + 0x76, 0x14, 0x2c, 0xca, 0xc6, 0x0e, 0xe7, 0xda, 0xa4, 0x5d, 0x2d, 0x06, + 0x77, 0x8b, 0xae, 0xf9, 0x50, 0xa3, 0x9d, 0x67, 0x2c, 0x01, 0xbc, 0x1b, + 0xb5, 0xdd, 0xe9, 0x22, 0x07, 0xee, 0xd2, 0x17, 0xe3, 0xda, 0xcc, 0x2d, + 0xb4, 0x6f, 0x37, 0x7f, 0x9b, 0xc0, 0xc1, 0xa8, 0x0b, 0x05, 0x56, 0x8d, + 0xb2, 0x9c, 0xeb, 0xc9, 0xea, 0xcb, 0x36, 0xea, 0x4b, 0x21, 0x63, 0xb3, + 0x15, 0x96, 0x5d, 0x4a, 0x3f, 0x93, 0xd6, 0xbb, 0x32, 0xda, 0x62, 0xe1, + 0xad, 0x41, 0xfa, 0xc0, 0x32, 0xc4, 0xfb, 0xba, 0x70, 0x36, 0x54, 0x86, + 0xd8, 0x01, 0xb1, 0xa7, 0x5a, 0xc1, 0x4d, 0x8e, 0xdb, 0x44, 0xf9, 0xa8, + 0xc4, 0x95, 0x86, 0x4e, 0xbb, 0xbd, 0x0c, 0x17, 0x2a, 0x18, 0xaf, 0x5a, + 0xef, 0x13, 0xb5, 0x62, 0x7f, 0x6e, 0x8f, 0x54, 0xf2, 0x9b, 0xd6, 0xeb, + 0x7c, 0x39, 0xbf, 0x96, 0xbc, 0x7d, 0x66, 0x6b, 0xe4, 0x3d, 0xe4, 0x30, + 0x2f, 0x49, 0x3e, 0xc8, 0xe6, 0xa3, 0xdf, 0x60, 0x5c, 0x34, 0x26, 0xb2, + 0xce, 0xeb, 0xd6, 0xeb, 0x35, 0xd9, 0x33, 0x3d, 0xf9, 0x3d, 0xc8, 0x5f, + 0x6b, 0x6b, 0x8b, 0x95, 0x5f, 0x98, 0xcf, 0x56, 0xcb, 0xfc, 0xae, 0x32, + 0x0e, 0xfb, 0x31, 0x7f, 0x5f, 0x86, 0x9e, 0xa1, 0xe9, 0x7e, 0x41, 0x6c, + 0xce, 0x73, 0xd3, 0xd9, 0xc3, 0x8a, 0xb8, 0xbc, 0xbf, 0x75, 0x34, 0xf4, + 0x24, 0xf7, 0xc1, 0xbf, 0xb0, 0xc1, 0xca, 0xa5, 0x90, 0xe3, 0x32, 0xfe, + 0x10, 0x3c, 0x35, 0xe8, 0xcf, 0xcb, 0xf0, 0xb3, 0xa4, 0xf8, 0x57, 0x13, + 0x85, 0xa1, 0x12, 0xfa, 0xbb, 0xee, 0xe7, 0x2a, 0x2c, 0xce, 0x5c, 0x86, + 0x4a, 0xea, 0x5e, 0xff, 0xd0, 0xed, 0xf4, 0xfc, 0x86, 0x0f, 0x48, 0x87, + 0x14, 0x62, 0xc2, 0x6f, 0xcc, 0x5d, 0x8f, 0x66, 0x9f, 0x39, 0x97, 0x74, + 0xe1, 0xa3, 0x50, 0x3b, 0x26, 0x2a, 0xc2, 0x18, 0x48, 0x14, 0xa1, 0x7d, + 0x56, 0xbd, 0xf5, 0xce, 0x45, 0x4d, 0xdc, 0x83, 0xf3, 0x51, 0x27, 0x9a, + 0x66, 0x7b, 0xac, 0x7c, 0x92, 0x8d, 0x76, 0xf1, 0x76, 0x34, 0x42, 0x5f, + 0xe0, 0xb9, 0xc9, 0x3f, 0x14, 0x68, 0x8b, 0x70, 0x7f, 0x0e, 0xc3, 0xf7, + 0x27, 0x3e, 0x27, 0xc6, 0x94, 0x1b, 0x33, 0xc3, 0x65, 0xb8, 0x7b, 0x40, + 0xce, 0x29, 0x48, 0x9d, 0x4a, 0x9b, 0x9a, 0xaf, 0x94, 0x61, 0xc9, 0x90, + 0xe0, 0xb9, 0x9c, 0xfd, 0x48, 0x87, 0x5c, 0xb1, 0x36, 0xee, 0x51, 0x27, + 0xea, 0xf7, 0x5a, 0x72, 0x55, 0xed, 0x8a, 0xd9, 0x75, 0x49, 0x8f, 0xe8, + 0xf4, 0x67, 0x9d, 0xf7, 0x53, 0xef, 0xa7, 0x42, 0xde, 0xf6, 0x99, 0x76, + 0xad, 0xe3, 0x57, 0x4a, 0x10, 0xa3, 0x19, 0xa0, 0x6f, 0x24, 0x80, 0x0f, + 0x12, 0xc2, 0xed, 0x03, 0x78, 0x7f, 0x2c, 0x88, 0x77, 0xe8, 0x87, 0x8a, + 0xe2, 0xde, 0xc8, 0x33, 0x8c, 0xdd, 0xde, 0xe5, 0x75, 0x61, 0x5c, 0xc7, + 0x15, 0xca, 0xcf, 0x19, 0x6f, 0xc4, 0xa5, 0xb1, 0x6f, 0xe0, 0xf2, 0x5e, + 0x05, 0xc7, 0xb4, 0x6f, 0xe0, 0xe2, 0xa1, 0x4e, 0x2c, 0xda, 0x2b, 0x67, + 0xf5, 0x8e, 0x86, 0x54, 0xfa, 0x81, 0x27, 0xeb, 0xcc, 0xae, 0x17, 0xf4, + 0x7a, 0x62, 0x86, 0x57, 0x6f, 0x67, 0x6c, 0x24, 0xf8, 0x1d, 0xb1, 0xc9, + 0x9e, 0xc9, 0xde, 0x75, 0xe2, 0xb2, 0x85, 0xd9, 0xb7, 0xc7, 0x89, 0x1b, + 0x78, 0x2d, 0xe3, 0x88, 0x6d, 0xdf, 0x81, 0x57, 0x19, 0x94, 0x6e, 0x61, + 0x3b, 0x17, 0x71, 0xee, 0xe9, 0x68, 0x11, 0x0a, 0xab, 0xcb, 0x2d, 0x7b, + 0x2b, 0x8e, 0x07, 0x70, 0x9a, 0xb2, 0x5b, 0x59, 0xed, 0xe5, 0xb5, 0xf8, + 0xd8, 0x20, 0xe3, 0x93, 0x99, 0xf8, 0xe0, 0x26, 0xdf, 0xfa, 0xaa, 0x85, + 0x0d, 0x0e, 0xed, 0x81, 0x39, 0x59, 0x6c, 0x20, 0xa0, 0x13, 0x93, 0x25, + 0x27, 0x58, 0xae, 0x69, 0x1b, 0xbe, 0x4b, 0x1b, 0x4f, 0x87, 0x8e, 0xfd, + 0x49, 0x29, 0x39, 0xf0, 0x0b, 0xa1, 0x7a, 0xa3, 0x02, 0x2b, 0x78, 0x7f, + 0x62, 0x91, 0x8a, 0x75, 0xfc, 0xf6, 0xb3, 0x5d, 0x90, 0xf3, 0xb8, 0x6a, + 0xa6, 0x54, 0x1f, 0xff, 0xae, 0xa5, 0x2f, 0xdf, 0x84, 0xb3, 0xb1, 0x86, + 0xf6, 0x11, 0xe5, 0x8a, 0x69, 0x54, 0xd7, 0xf1, 0xb7, 0x2a, 0x9c, 0x8b, + 0x7a, 0x27, 0x0e, 0xa1, 0xc1, 0x33, 0xa5, 0xec, 0x37, 0x0d, 0x55, 0xf6, + 0x47, 0xd6, 0x2b, 0xcf, 0xdf, 0xc5, 0xfb, 0x17, 0xa6, 0xe9, 0xe1, 0x8d, + 0xf8, 0xca, 0x79, 0x5d, 0xff, 0x84, 0x83, 0x98, 0x4b, 0x86, 0xf5, 0x06, + 0x75, 0x0b, 0xb1, 0x20, 0xa2, 0xde, 0x4e, 0xff, 0x8a, 0xa8, 0x7f, 0x61, + 0xc6, 0x8b, 0x65, 0x50, 0x2d, 0x5f, 0xd4, 0x8a, 0xe4, 0xd0, 0x74, 0x1e, + 0x29, 0x7a, 0x97, 0xe5, 0xa4, 0xed, 0x15, 0xdd, 0xc7, 0x9d, 0xf4, 0x87, + 0x09, 0x62, 0x78, 0x9c, 0x18, 0x5e, 0x48, 0x0c, 0xbf, 0xba, 0xa7, 0x18, + 0x67, 0xf7, 0x34, 0x21, 0x5d, 0x21, 0xcf, 0xd8, 0xe1, 0xe4, 0xea, 0x52, + 0x96, 0x6f, 0xb7, 0xa1, 0xa6, 0x7f, 0xa9, 0x9c, 0x75, 0x85, 0xf8, 0xd0, + 0x82, 0x38, 0x11, 0xb1, 0xd5, 0x0e, 0x87, 0xf5, 0x7e, 0xc1, 0x8c, 0x9b, + 0xf4, 0xcf, 0xa5, 0x15, 0xa2, 0xa5, 0x4a, 0xf0, 0xe1, 0xe2, 0x1c, 0xf1, + 0x99, 0x3f, 0xe5, 0x5c, 0x8e, 0x53, 0xa7, 0x9f, 0xd2, 0xef, 0x91, 0x1a, + 0x1d, 0xdb, 0xcb, 0x73, 0x12, 0xc3, 0x98, 0xd8, 0x41, 0x0d, 0xab, 0xaf, + 0x36, 0x91, 0xd0, 0xc3, 0xf4, 0x4f, 0x21, 0x44, 0x2a, 0x82, 0xf4, 0x4b, + 0x72, 0xad, 0xe2, 0x12, 0xe3, 0xaf, 0x4c, 0x50, 0xc1, 0x47, 0x5f, 0x13, + 0xbf, 0xef, 0xd7, 0xcf, 0x2a, 0xa7, 0x67, 0x65, 0xdf, 0x6b, 0x10, 0x8c, + 0x28, 0xb7, 0x30, 0xa2, 0xd0, 0xe2, 0x40, 0xb3, 0x2d, 0x6c, 0xf1, 0xd8, + 0xe4, 0x4c, 0x51, 0x34, 0x74, 0x6f, 0xa2, 0x61, 0xc2, 0x67, 0x27, 0x1f, + 0xfb, 0xe3, 0xaf, 0x91, 0x87, 0x59, 0x7c, 0x60, 0xba, 0xdf, 0x69, 0x02, + 0xa6, 0xcb, 0x23, 0x7f, 0x76, 0xd9, 0x93, 0xc5, 0xca, 0x72, 0xe1, 0x6d, + 0xff, 0xcf, 0x6c, 0xbd, 0x69, 0xfe, 0x79, 0x1c, 0xf9, 0x25, 0xaf, 0xe5, + 0x79, 0xb1, 0x3b, 0xea, 0x45, 0xfc, 0x1f, 0xcd, 0xc7, 0x2d, 0xee, 0x76, + 0x6c, 0x8e, 0x9c, 0xcb, 0x74, 0xf4, 0xff, 0xfd, 0x1c, 0x79, 0x9f, 0xc1, + 0x36, 0x8d, 0x03, 0x64, 0xfd, 0xea, 0x3b, 0xe6, 0x2a, 0x6b, 0xae, 0xa7, + 0x73, 0xed, 0x24, 0x56, 0x96, 0xb9, 0x28, 0xf8, 0x81, 0xd6, 0xa0, 0x9e, + 0x46, 0xa9, 0xe0, 0x49, 0x44, 0xea, 0x91, 0xc5, 0x9a, 0xcf, 0x7d, 0x90, + 0xdf, 0xbb, 0x78, 0xff, 0x35, 0xcd, 0xd1, 0xf4, 0x2c, 0xa4, 0x06, 0x6b, + 0xe3, 0x5e, 0x35, 0xb8, 0x4f, 0xc3, 0x1f, 0x29, 0x54, 0xa6, 0xcc, 0xf6, + 0x2a, 0x69, 0x93, 0xad, 0xc5, 0x42, 0x39, 0x6f, 0xe5, 0x49, 0xb2, 0x3a, + 0x53, 0x4b, 0x9d, 0x11, 0xec, 0x12, 0xde, 0xb1, 0x80, 0x6b, 0x57, 0x31, + 0x34, 0x26, 0x1c, 0xc1, 0x65, 0xf1, 0x20, 0xb5, 0xae, 0xce, 0xb3, 0x1e, + 0xca, 0x5c, 0x62, 0x2c, 0xb6, 0xea, 0xb8, 0xd3, 0x86, 0xb7, 0xee, 0xb4, + 0x85, 0x97, 0xfe, 0xd9, 0xfd, 0x8d, 0x77, 0xcf, 0x95, 0x77, 0x5f, 0xc8, + 0xe6, 0x24, 0x2f, 0xeb, 0x96, 0xba, 0xe1, 0x72, 0xf2, 0xaa, 0x41, 0xc6, + 0xf2, 0xcb, 0x83, 0xbf, 0x33, 0xbf, 0xed, 0x88, 0x78, 0xec, 0xa8, 0xf3, + 0xf4, 0xe0, 0x9a, 0x99, 0xaa, 0xb2, 0xee, 0xcf, 0x95, 0xf7, 0x0d, 0x9c, + 0xd2, 0x3f, 0xb9, 0xc8, 0xdd, 0x75, 0x26, 0xe3, 0x64, 0xdb, 0x32, 0x3b, + 0xed, 0x82, 0x32, 0x33, 0xeb, 0x67, 0xd5, 0xb9, 0x6d, 0x4a, 0x3d, 0xb5, + 0xa3, 0x0a, 0x47, 0xa8, 0xbf, 0x47, 0xc6, 0xc4, 0xff, 0xa9, 0x38, 0x4c, + 0x3b, 0x3d, 0x54, 0xef, 0xeb, 0xbc, 0xcc, 0xb8, 0xf1, 0x43, 0xf2, 0xf9, + 0x37, 0x34, 0x6f, 0xfb, 0x29, 0xc9, 0x29, 0x86, 0x1c, 0x38, 0x13, 0xbc, + 0x66, 0xe5, 0x78, 0x63, 0x07, 0x54, 0x0c, 0x26, 0xb2, 0xf6, 0xfe, 0x0a, + 0xed, 0xf8, 0xc6, 0x99, 0x03, 0x1d, 0x5b, 0x06, 0xc4, 0x3e, 0x1a, 0x2d, + 0x3b, 0xba, 0x91, 0x13, 0x12, 0xbc, 0x16, 0xbb, 0x78, 0x42, 0x6a, 0x71, + 0x46, 0x0a, 0x0e, 0xca, 0x77, 0x39, 0xf9, 0xae, 0xf8, 0xd8, 0x00, 0x63, + 0x5b, 0x07, 0xed, 0xe7, 0x14, 0xe3, 0x0c, 0xce, 0x2d, 0x6c, 0x9a, 0xef, + 0x30, 0xee, 0x1a, 0x42, 0x83, 0x7a, 0x02, 0x6b, 0xc8, 0x59, 0xc9, 0x67, + 0xc6, 0x9a, 0xb1, 0xd3, 0x8a, 0x9b, 0x7c, 0xea, 0x0a, 0x65, 0x21, 0xd7, + 0xdf, 0x8c, 0xee, 0x43, 0xb5, 0xe4, 0x35, 0xa6, 0xb9, 0x5a, 0xff, 0x73, + 0x54, 0x0e, 0x74, 0x77, 0x56, 0x52, 0x1e, 0x9f, 0x86, 0x8c, 0x0e, 0x62, + 0xfa, 0x86, 0x13, 0x4a, 0xc3, 0xda, 0x98, 0xf2, 0x6d, 0xee, 0x87, 0xe4, + 0x41, 0x3c, 0x8c, 0xc7, 0x57, 0xd3, 0x9f, 0xfd, 0x0f, 0xec, 0x50, 0x95, + 0x25, 0xb6, 0xb0, 0xf0, 0x41, 0xf8, 0xd5, 0xb0, 0x76, 0xea, 0xa2, 0x7d, + 0x33, 0xbd, 0x4f, 0x23, 0xef, 0x89, 0x5f, 0x97, 0xb6, 0x72, 0xb6, 0xbe, + 0x13, 0xc7, 0xd3, 0xd4, 0xeb, 0x68, 0x2f, 0x4e, 0xa4, 0x65, 0x4c, 0xe1, + 0x53, 0x01, 0xc4, 0x06, 0xec, 0x18, 0xd5, 0x7d, 0x91, 0x72, 0xca, 0xa5, + 0x38, 0xe4, 0x8d, 0xac, 0x51, 0x02, 0xe4, 0x6d, 0x69, 0x9c, 0xd9, 0xed, + 0x6d, 0xaf, 0x67, 0x8c, 0x18, 0x1d, 0x83, 0xfa, 0xcc, 0xe2, 0x34, 0x4e, + 0x0f, 0x3f, 0x04, 0xcf, 0x2c, 0xaf, 0x67, 0xb9, 0xd2, 0x82, 0xad, 0x63, + 0xff, 0x51, 0x2e, 0xc9, 0xc3, 0xb1, 0x5b, 0x60, 0x50, 0xf6, 0xdb, 0xd1, + 0x3f, 0x57, 0x6c, 0xbe, 0x67, 0xac, 0x14, 0xf3, 0xe8, 0x8f, 0x5e, 0xb2, + 0xfc, 0x6c, 0xd6, 0x8e, 0x6a, 0xb4, 0x8f, 0xcc, 0xc7, 0x72, 0x3e, 0xfc, + 0xab, 0xe5, 0xf5, 0x77, 0x66, 0x44, 0x15, 0x79, 0xc9, 0x73, 0x35, 0x28, + 0x62, 0x3f, 0x3b, 0x72, 0xfe, 0xba, 0x42, 0xfb, 0xbf, 0xe6, 0x43, 0x56, + 0x1f, 0x4f, 0xcd, 0x95, 0xa0, 0x60, 0x9b, 0x15, 0xd3, 0xcb, 0xba, 0x75, + 0x7c, 0x16, 0x95, 0x9c, 0x86, 0x8a, 0x13, 0xba, 0xe0, 0x48, 0x0b, 0x6d, + 0xd5, 0x89, 0x0d, 0x41, 0x9a, 0xa3, 0x95, 0xcf, 0x9f, 0xc4, 0xce, 0xe4, + 0xbf, 0x9b, 0xcf, 0x51, 0x8f, 0x56, 0x92, 0xc3, 0x78, 0x88, 0x03, 0x4f, + 0x85, 0x56, 0x93, 0x73, 0x72, 0xcd, 0x09, 0x07, 0x31, 0x48, 0x41, 0xa2, + 0x89, 0xf6, 0x1f, 0x5a, 0x80, 0x09, 0xab, 0x7d, 0xd5, 0xdc, 0x6c, 0x0e, + 0xf1, 0x83, 0xb9, 0xd9, 0x38, 0x50, 0xe4, 0xff, 0x9f, 0x91, 0xdf, 0x2b, + 0xa6, 0xa7, 0x52, 0xe4, 0xe7, 0x80, 0x9b, 0x7e, 0x6b, 0x1f, 0xdb, 0x9c, + 0xdb, 0xed, 0x40, 0xbf, 0xd6, 0x82, 0xfe, 0x31, 0x78, 0x3e, 0x65, 0x9b, + 0x7f, 0x1a, 0x1e, 0x98, 0x9b, 0xe5, 0x0a, 0x6f, 0xa1, 0x3b, 0xfa, 0xbc, + 0xb9, 0xac, 0x52, 0xd6, 0xeb, 0x84, 0x9b, 0xeb, 0xdd, 0x77, 0x3d, 0x9f, + 0xb7, 0xde, 0x7c, 0xd8, 0xf2, 0x13, 0xbb, 0xe7, 0x4a, 0xbd, 0xec, 0xa7, + 0x09, 0x13, 0x97, 0xf4, 0xa3, 0x56, 0x1c, 0x2e, 0xd8, 0xd0, 0x93, 0x90, + 0xbd, 0x95, 0xb9, 0x6d, 0xcd, 0xc9, 0xe3, 0xff, 0x54, 0xdf, 0x3c, 0xef, + 0x65, 0x39, 0x5d, 0x96, 0x5a, 0x75, 0x9e, 0xe3, 0x8b, 0x2e, 0x8b, 0x1e, + 0x5b, 0xef, 0xfd, 0x24, 0xe5, 0xfd, 0xd9, 0x27, 0xd4, 0xdf, 0x73, 0x0c, + 0xc9, 0xa9, 0xb4, 0xb0, 0x0f, 0xd3, 0x5c, 0xaf, 0x37, 0x78, 0x4e, 0xe0, + 0x8f, 0xa8, 0xdb, 0x3a, 0xb6, 0x0f, 0x48, 0xbe, 0xd5, 0xa3, 0x38, 0xf6, + 0xac, 0xc1, 0x25, 0xfa, 0xff, 0x9d, 0x96, 0x1e, 0x0a, 0xae, 0xc8, 0x3c, + 0x04, 0x5b, 0xda, 0xe8, 0xc7, 0xad, 0xb3, 0x2e, 0x91, 0x9a, 0x70, 0xa7, + 0xf2, 0x61, 0x7d, 0x27, 0x8e, 0x86, 0x0c, 0xb3, 0x5c, 0xf3, 0xaf, 0x65, + 0xd0, 0x5f, 0x34, 0xd6, 0x58, 0x88, 0xf1, 0x90, 0xf0, 0x47, 0xb8, 0xd2, + 0x69, 0xaf, 0x31, 0xc3, 0xae, 0xba, 0x5e, 0x4e, 0xe7, 0xb0, 0xd2, 0xf6, + 0xc0, 0x5c, 0x89, 0x97, 0x92, 0x16, 0x8e, 0x7c, 0x1d, 0xf7, 0x59, 0x7b, + 0xab, 0xd2, 0x87, 0x4a, 0xbe, 0xf7, 0x68, 0xe8, 0x4a, 0x54, 0x30, 0xc5, + 0x5c, 0xd2, 0x1c, 0x6a, 0x50, 0xb7, 0xe3, 0x4e, 0x62, 0xd7, 0x12, 0x9c, + 0xd1, 0xa5, 0xae, 0x61, 0x7c, 0xdb, 0x01, 0xa9, 0xc1, 0x1d, 0x0e, 0x6d, + 0x8d, 0x2e, 0xc5, 0xbe, 0x01, 0x43, 0x71, 0x86, 0xbd, 0x91, 0x18, 0xb9, + 0x10, 0xe3, 0x71, 0x2b, 0xdf, 0x27, 0xf9, 0x84, 0xc1, 0xc6, 0x4e, 0x6c, + 0xd7, 0x0b, 0xd1, 0xa3, 0x47, 0x8a, 0xb6, 0x2c, 0xee, 0xc2, 0x7e, 0xbd, + 0xd4, 0x98, 0x17, 0x36, 0x88, 0xe9, 0xda, 0x86, 0x24, 0xfc, 0x2d, 0x17, + 0xc9, 0x39, 0x8e, 0xc3, 0xdb, 0xb1, 0xc4, 0x4e, 0xcc, 0xbd, 0xc7, 0xe1, + 0x8a, 0x65, 0x9a, 0x90, 0x18, 0xab, 0x72, 0xed, 0xc8, 0x04, 0x11, 0x1f, + 0xe3, 0x7e, 0x33, 0xae, 0x75, 0x64, 0x96, 0x92, 0x83, 0x8a, 0x1c, 0xed, + 0xd4, 0xc5, 0x7a, 0x3c, 0xd3, 0x7a, 0xc1, 0x7c, 0xd2, 0x2f, 0xf8, 0x59, + 0x8b, 0x67, 0x55, 0x9f, 0xc5, 0x29, 0x23, 0xb6, 0xaf, 0xb2, 0x0f, 0x3b, + 0x75, 0xee, 0x55, 0xd3, 0xf3, 0xa8, 0xc8, 0x8d, 0xc1, 0x56, 0xf1, 0x6a, + 0xe2, 0xa7, 0xfc, 0x2d, 0xb2, 0x13, 0x19, 0x9a, 0x58, 0xa7, 0x4b, 0x2e, + 0xaf, 0x91, 0x36, 0xe3, 0xc6, 0xdb, 0xea, 0x8d, 0x7d, 0x78, 0x5a, 0xf7, + 0xe9, 0x87, 0x20, 0x39, 0xbc, 0xff, 0xce, 0xe7, 0x24, 0xdf, 0xd2, 0x84, + 0x17, 0x2b, 0xb2, 0xf1, 0x87, 0xc7, 0x56, 0x42, 0xdc, 0xcd, 0xfb, 0x11, + 0xb9, 0xef, 0x4d, 0x46, 0xa8, 0xa7, 0x1b, 0x83, 0x53, 0x66, 0xa4, 0xd2, + 0xe8, 0x94, 0xb3, 0x28, 0xee, 0xf0, 0xea, 0x17, 0xdd, 0xf5, 0xde, 0x8e, + 0x29, 0x05, 0x38, 0x13, 0xa3, 0x1f, 0xb6, 0xfe, 0xbb, 0x47, 0xe9, 0xdb, + 0x89, 0xa1, 0xe0, 0x1d, 0x68, 0x6f, 0x93, 0xb1, 0x9a, 0xd1, 0xbb, 0xd7, + 0x34, 0x4b, 0x43, 0x3e, 0x35, 0x0d, 0x27, 0x56, 0x04, 0xed, 0xb8, 0xa0, + 0x9a, 0x70, 0x84, 0xfe, 0xdd, 0xcc, 0xd0, 0x3f, 0x0e, 0xd3, 0x4e, 0x76, + 0x50, 0xc7, 0xe4, 0x5d, 0x28, 0x3f, 0xed, 0x24, 0x4e, 0x3b, 0x39, 0x13, + 0x9a, 0x9f, 0x7b, 0x57, 0x52, 0x23, 0xaf, 0x98, 0xc4, 0x92, 0x01, 0x15, + 0x9f, 0xde, 0x33, 0x89, 0xd0, 0x50, 0x7e, 0xee, 0x62, 0x97, 0xf9, 0xf9, + 0x4b, 0x6d, 0x50, 0xe6, 0x2e, 0x73, 0x94, 0xb5, 0xc8, 0xdf, 0xf9, 0x7b, + 0xf9, 0xdf, 0xc4, 0xcf, 0x3a, 0xd1, 0x6a, 0xad, 0xed, 0x2f, 0x6a, 0xb2, + 0x98, 0x91, 0x5f, 0x93, 0xeb, 0x96, 0xeb, 0x4b, 0xb7, 0x5c, 0x3f, 0xee, + 0xbe, 0xf9, 0x7a, 0xfb, 0x9c, 0x9b, 0xaf, 0xf3, 0x36, 0x71, 0x43, 0xae, + 0x1d, 0xba, 0x6f, 0xe2, 0x28, 0xd7, 0x3a, 0x63, 0xc1, 0x21, 0xf3, 0x42, + 0x85, 0xcc, 0x45, 0x62, 0xd6, 0xec, 0x5c, 0x97, 0x65, 0xa6, 0xcf, 0xf5, + 0xcd, 0x5c, 0x6d, 0xc0, 0x3a, 0xf7, 0x4b, 0xbb, 0xd1, 0xe4, 0x1d, 0xdf, + 0xdc, 0x3b, 0x74, 0xd9, 0xb3, 0x88, 0xa5, 0xe1, 0x80, 0xd2, 0x1b, 0x33, + 0xcc, 0x19, 0x5a, 0xb1, 0x21, 0xef, 0x4a, 0xa9, 0x7e, 0x03, 0x25, 0x7e, + 0x6d, 0xc3, 0x0c, 0x5b, 0x17, 0x9c, 0x0b, 0xb5, 0x8e, 0x3f, 0x53, 0x92, + 0x88, 0x67, 0xbc, 0x81, 0x43, 0x94, 0x55, 0x2c, 0x73, 0x95, 0x71, 0x75, + 0x17, 0x9e, 0x09, 0x39, 0x8c, 0xe2, 0xb0, 0xd7, 0x3d, 0x5f, 0x59, 0x86, + 0xed, 0x43, 0x7f, 0x8e, 0xf5, 0x49, 0xe1, 0xf8, 0xb5, 0xd8, 0x32, 0x66, + 0xc3, 0x31, 0xea, 0x77, 0x2f, 0xc7, 0x21, 0xfe, 0xb9, 0x53, 0x90, 0xb3, + 0x79, 0x8d, 0x8c, 0x91, 0x75, 0xeb, 0xb3, 0x75, 0xe8, 0x75, 0xac, 0x8f, + 0x9a, 0xf8, 0x54, 0xa7, 0xef, 0xd1, 0x64, 0x7e, 0x12, 0x3b, 0xb7, 0x5a, + 0x58, 0xfa, 0x48, 0x9c, 0xfb, 0x39, 0x4b, 0x6c, 0x75, 0x29, 0x6d, 0x56, + 0xc1, 0x67, 0x52, 0x77, 0xac, 0xe4, 0x9c, 0xc9, 0x0d, 0xc7, 0xa3, 0x9b, + 0x30, 0x1c, 0x35, 0xe4, 0x7d, 0xc0, 0xde, 0x1a, 0x7b, 0xe4, 0x85, 0x0a, + 0xf2, 0xec, 0x84, 0xee, 0x6f, 0x3f, 0xa7, 0xc0, 0x53, 0x16, 0xf6, 0xd3, + 0xcf, 0x7c, 0x89, 0xdf, 0xea, 0x92, 0x4f, 0xd3, 0x5d, 0xab, 0xa8, 0xef, + 0x7b, 0x86, 0x02, 0x56, 0x7e, 0xe0, 0xef, 0x6e, 0x9b, 0xbf, 0x90, 0x1a, + 0xb3, 0x9e, 0xcb, 0x35, 0xbe, 0x8e, 0x83, 0x69, 0x17, 0x1e, 0x8b, 0x7b, + 0x94, 0x79, 0x7b, 0x54, 0xdc, 0x1f, 0xf7, 0x4e, 0x2c, 0xb1, 0x93, 0x7f, + 0x2c, 0x9a, 0xc1, 0xfe, 0x14, 0xfc, 0x68, 0xa1, 0xf8, 0x82, 0xff, 0x0a, + 0x63, 0x56, 0x84, 0x7d, 0xa2, 0xb4, 0x60, 0xb1, 0x57, 0x3d, 0x68, 0xf3, + 0xb9, 0x7f, 0x8b, 0xad, 0xb0, 0x67, 0x56, 0xa3, 0x9b, 0xf3, 0x5f, 0x19, + 0x97, 0x9a, 0x55, 0x03, 0x50, 0xd1, 0x8c, 0x1d, 0x87, 0xc4, 0x36, 0xe5, + 0x9d, 0x75, 0x78, 0xaa, 0xc2, 0x2d, 0x77, 0xa0, 0xf8, 0x4b, 0x72, 0xed, + 0x49, 0x89, 0x3f, 0x37, 0x94, 0xdb, 0x4c, 0xc6, 0x2f, 0xf3, 0x73, 0x35, + 0x89, 0xa5, 0xd8, 0x3a, 0x20, 0xf9, 0x76, 0xe2, 0xb6, 0xce, 0x38, 0xa8, + 0x42, 0x0b, 0x3c, 0x65, 0x93, 0x3a, 0xd0, 0x26, 0xf8, 0x62, 0x9b, 0x10, + 0x88, 0x89, 0xcd, 0x6a, 0x6a, 0x07, 0x22, 0xa7, 0x25, 0xcf, 0x37, 0x2f, + 0xe4, 0xe7, 0xbc, 0xfc, 0xbd, 0x55, 0x76, 0xdd, 0xf5, 0xca, 0xa8, 0x8a, + 0x09, 0x35, 0x1b, 0x47, 0x1e, 0x4a, 0x6a, 0x6b, 0x0b, 0x6d, 0x72, 0x26, + 0xe2, 0xb2, 0x19, 0xb1, 0xfa, 0x55, 0x6a, 0x51, 0xde, 0x8c, 0xbe, 0xbd, + 0xef, 0xd2, 0x07, 0xc9, 0x18, 0xbf, 0x37, 0x9d, 0xd4, 0xcb, 0xe5, 0x6d, + 0x1e, 0xdc, 0x17, 0x97, 0x3c, 0x69, 0x4f, 0x75, 0xf6, 0x4c, 0x87, 0x5c, + 0x3b, 0xd0, 0xa1, 0x13, 0x64, 0x67, 0x7d, 0x61, 0x56, 0x59, 0x71, 0xe9, + 0x97, 0x59, 0x9d, 0x49, 0xdc, 0x7d, 0x87, 0xd8, 0x78, 0xcf, 0x58, 0x83, + 0x3b, 0xab, 0x77, 0x4d, 0xbc, 0x96, 0xbe, 0xb4, 0x7d, 0x9b, 0xe4, 0x34, + 0x2e, 0xf9, 0xcc, 0x23, 0xa3, 0xd3, 0xdb, 0xe7, 0x73, 0x30, 0x55, 0x39, + 0x4e, 0x95, 0xd7, 0x37, 0xa9, 0xf5, 0x45, 0x94, 0x87, 0xa3, 0x2d, 0xca, + 0xaa, 0xa8, 0xd4, 0xfb, 0x6c, 0xd1, 0x12, 0xeb, 0x5c, 0xab, 0x89, 0xef, + 0x85, 0xc6, 0x95, 0x6d, 0xd6, 0x99, 0x59, 0x43, 0x49, 0x36, 0x02, 0x95, + 0xa3, 0xcd, 0xca, 0xf6, 0xe8, 0x27, 0xe6, 0x53, 0x56, 0x5d, 0x7d, 0xa6, + 0x75, 0xbe, 0xa6, 0x70, 0xd4, 0x85, 0x8a, 0x83, 0x25, 0x28, 0x18, 0xd4, + 0x30, 0x73, 0xf4, 0x41, 0xf2, 0x56, 0xe1, 0x3a, 0x46, 0x8b, 0xc3, 0x3a, + 0xa3, 0xf6, 0xfa, 0xf5, 0x33, 0x6a, 0x0e, 0xe2, 0x82, 0x01, 0xeb, 0x1f, + 0x63, 0xa5, 0xc3, 0x8c, 0x95, 0xcc, 0x25, 0xdf, 0x0b, 0x19, 0x3b, 0x66, + 0xc2, 0x1b, 0xa8, 0xb4, 0x19, 0xa6, 0xe4, 0x6e, 0x5e, 0x21, 0x61, 0x5c, + 0x53, 0x67, 0x60, 0x45, 0x9d, 0xbc, 0x9b, 0xe9, 0x30, 0xec, 0xe1, 0x2e, + 0x1c, 0x0e, 0x75, 0xe1, 0x3d, 0xbd, 0x0b, 0x3b, 0xf5, 0x62, 0xa3, 0x3c, + 0x5c, 0x2a, 0x67, 0xd9, 0x27, 0xa2, 0xd0, 0xf4, 0xb4, 0xa2, 0x9d, 0xba, + 0x0a, 0xef, 0x3e, 0x9f, 0xe2, 0x35, 0x96, 0x29, 0x1a, 0x2e, 0x67, 0xbc, + 0x53, 0xe5, 0xb4, 0x81, 0x6b, 0x99, 0x00, 0xa6, 0x88, 0xab, 0xc9, 0x31, + 0x39, 0x4f, 0x52, 0x8b, 0x81, 0xb1, 0xff, 0x29, 0xdc, 0xc0, 0x20, 0x26, + 0x59, 0x67, 0x2a, 0x9f, 0x93, 0x5a, 0xa6, 0x33, 0x98, 0xe3, 0x30, 0x86, + 0xb2, 0xae, 0xb1, 0x0c, 0xd7, 0xe8, 0x9d, 0x7e, 0x98, 0xee, 0x64, 0x3c, + 0x87, 0xd7, 0x6a, 0x60, 0xff, 0xbe, 0x1b, 0xf5, 0xc9, 0x19, 0x38, 0x56, + 0x5f, 0x89, 0x02, 0x1c, 0x1d, 0xee, 0x20, 0xc7, 0xef, 0x6e, 0x2f, 0x67, + 0x7c, 0x3a, 0x3a, 0xec, 0x44, 0x2a, 0x25, 0x39, 0x07, 0xab, 0x36, 0x39, + 0xe9, 0xa0, 0x2d, 0xed, 0x4a, 0xa0, 0xbe, 0x26, 0xec, 0x4f, 0xd6, 0xd8, + 0x55, 0xf6, 0x51, 0x85, 0x54, 0x5a, 0xe3, 0x27, 0xc0, 0x4f, 0x90, 0x9f, + 0x26, 0x7c, 0x8f, 0x36, 0x5b, 0x41, 0xbc, 0x7d, 0x35, 0x5d, 0x86, 0x4f, + 0x92, 0x5a, 0x40, 0xa7, 0x1e, 0x0c, 0x33, 0x46, 0x30, 0x2c, 0x39, 0x95, + 0xe1, 0x2a, 0xed, 0xf4, 0xa5, 0x50, 0x19, 0xcc, 0xd4, 0xed, 0x62, 0x42, + 0x79, 0xff, 0x25, 0x7f, 0x0e, 0x33, 0x5b, 0x5f, 0x3d, 0x92, 0x81, 0xf2, + 0x78, 0x9d, 0x41, 0x7d, 0x61, 0x0c, 0xbb, 0x48, 0x6a, 0x29, 0x5a, 0xe7, + 0x25, 0x7b, 0xb1, 0x51, 0x13, 0xf6, 0x7a, 0x6a, 0xec, 0x1a, 0xce, 0xa5, + 0x27, 0x11, 0x4f, 0xca, 0xbb, 0x6d, 0xa2, 0xc7, 0xef, 0x9b, 0x46, 0x85, + 0x9c, 0xc9, 0xe8, 0x44, 0x5c, 0xab, 0x64, 0x1c, 0x24, 0xef, 0x3e, 0x1e, + 0x0e, 0x45, 0x63, 0xa5, 0xf2, 0x9e, 0xf0, 0x92, 0x97, 0x43, 0xde, 0x96, + 0x7e, 0xc5, 0x78, 0xa8, 0xc4, 0x7a, 0xaf, 0xa3, 0x8b, 0x58, 0xac, 0xa9, + 0x4e, 0xc5, 0xdb, 0xb4, 0x05, 0x01, 0x1c, 0x4b, 0x8b, 0xdc, 0x28, 0xa7, + 0xb1, 0xac, 0xdc, 0x6e, 0x9c, 0x9d, 0xce, 0xea, 0xc1, 0xc6, 0xa8, 0x83, + 0xdf, 0xb2, 0xf7, 0x72, 0xae, 0x95, 0x3e, 0xc2, 0xda, 0xff, 0x9f, 0xdf, + 0x91, 0x3b, 0xbf, 0xda, 0x5e, 0x19, 0x76, 0x05, 0x97, 0xc7, 0xed, 0x9f, + 0xc8, 0xfb, 0xc8, 0x4f, 0x34, 0xca, 0x7b, 0x6b, 0xae, 0xe0, 0xe3, 0xa3, + 0xae, 0xe0, 0xda, 0xf8, 0x51, 0x85, 0xf2, 0xda, 0x57, 0x63, 0x77, 0x05, + 0x1f, 0xb9, 0xd1, 0x9e, 0xfb, 0xde, 0x85, 0xb1, 0x50, 0xb1, 0xa1, 0x86, + 0xc5, 0xa7, 0x7b, 0x03, 0x9f, 0x28, 0x96, 0x2f, 0x37, 0x4a, 0xe8, 0x63, + 0x9f, 0xcf, 0x8c, 0x9b, 0xed, 0xb3, 0x04, 0xab, 0xec, 0x1c, 0xeb, 0x2a, + 0x5e, 0x49, 0xdd, 0x78, 0xae, 0x85, 0xcf, 0x15, 0xf3, 0xb9, 0x92, 0xb0, + 0xc4, 0x8d, 0x5e, 0x7d, 0x95, 0xa2, 0x79, 0x8a, 0x14, 0xa9, 0x87, 0x69, + 0xf8, 0x55, 0xfa, 0x9f, 0xef, 0x90, 0x78, 0xb7, 0x67, 0xac, 0x12, 0x6b, + 0x76, 0x9b, 0x4b, 0xe6, 0x2d, 0x34, 0x97, 0xa4, 0x43, 0x31, 0xf3, 0xa5, + 0x6a, 0xd9, 0x4f, 0xa9, 0xf1, 0xc9, 0x33, 0x9a, 0xea, 0x63, 0x9c, 0xf9, + 0x4d, 0x7d, 0xbb, 0xbc, 0xa3, 0x07, 0x79, 0x7f, 0xa9, 0x90, 0x63, 0x9c, + 0x4c, 0x89, 0x8e, 0x6c, 0x6d, 0x77, 0x31, 0x16, 0x95, 0x77, 0x67, 0x0f, + 0x73, 0xef, 0x0f, 0xa6, 0xfe, 0xd7, 0x1d, 0x72, 0x76, 0x5d, 0xce, 0x06, + 0x00, 0xff, 0x1f, 0x17, 0x23, 0xca, 0x76, 0xf8, 0x78, 0x00, 0x00, 0x00 }; static const u32 bnx2_RXP_b09FwData[(0x0/4) + 1] = { 0x0 }; -static const u32 bnx2_RXP_b09FwRodata[(0xf0/4) + 1] = { +static const u32 bnx2_RXP_b09FwRodata[(0x124/4) + 1] = { 0x5f865437, 0xe4ac62cc, 0x50103a45, 0x36621985, 0xbf14c0e8, 0x1bc27a1e, 0x84f4b556, 0x094ea6fe, 0x7dda01e7, 0xc04d7481, 0x80080100, 0x80080080, - 0x80080000, 0x08004efc, 0x08004efc, 0x08004fd8, 0x08004fac, 0x08004f90, - 0x08004ecc, 0x08004ecc, 0x08004ecc, 0x08004f04, 0x08007220, 0x0800726c, - 0x0800722c, 0x08007150, 0x0800722c, 0x0800725c, 0x0800722c, 0x08007150, - 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150, - 0x08007150, 0x08007150, 0x08007150, 0x0800724c, 0x0800723c, 0x08007150, - 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150, - 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x0800723c, - 0x080077f4, 0x080076bc, 0x080077bc, 0x08007718, 0x080076e8, 0x080075a4, - 0x00000000 }; + 0x80080000, 0x08004fbc, 0x08004fbc, 0x08005098, 0x0800506c, 0x08005050, + 0x08004f8c, 0x08004f8c, 0x08004f8c, 0x08004fc4, 0x080072ac, 0x080072f8, + 0x080072b8, 0x080071dc, 0x080072b8, 0x080072e8, 0x080072b8, 0x080071dc, + 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, + 0x080071dc, 0x080071dc, 0x080071dc, 0x080072d8, 0x080072c8, 0x080071dc, + 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, + 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080072c8, + 0x0800787c, 0x08007748, 0x08007844, 0x08007748, 0x08007814, 0x08007630, + 0x08007748, 0x08007748, 0x08007748, 0x08007748, 0x08007748, 0x08007748, + 0x08007748, 0x08007748, 0x08007748, 0x08007748, 0x08007748, 0x08007748, + 0x08007770, 0x00000000 }; static struct fw_info bnx2_rxp_fw_09 = { - /* Firmware version: 4.4.23 */ + /* Firmware version: 4.6.15 */ .ver_major = 0x4, - .ver_minor = 0x4, - .ver_fix = 0x17, + .ver_minor = 0x6, + .ver_fix = 0xf, - .start_addr = 0x080031d0, + .start_addr = 0x080031d8, .text_addr = 0x08000000, - .text_len = 0x786c, + .text_len = 0x78f4, .text_index = 0x0, .gz_text = bnx2_RXP_b09FwText, .gz_text_len = sizeof(bnx2_RXP_b09FwText), @@ -3158,548 +3148,492 @@ static struct fw_info bnx2_rxp_fw_09 = { .data_index = 0x0, .data = bnx2_RXP_b09FwData, - .sbss_addr = 0x08007980, + .sbss_addr = 0x08007a40, .sbss_len = 0x58, .sbss_index = 0x0, - .bss_addr = 0x080079d8, - .bss_len = 0x1c, + .bss_addr = 0x08007a98, + .bss_len = 0x20, .bss_index = 0x0, - .rodata_addr = 0x0800786c, - .rodata_len = 0xf0, + .rodata_addr = 0x080078f4, + .rodata_len = 0x124, .rodata_index = 0x0, .rodata = bnx2_RXP_b09FwRodata, }; static u8 bnx2_xi_rv2p_proc1[] = { - /* Date: 06/17/2008 16:52 */ - 0xbd, 0x56, 0xcf, 0x6b, 0x1c, 0x75, 0x14, 0x7f, 0x3b, 0xbb, 0x33, 0x3b, - 0x99, 0x9d, 0xdd, 0x99, 0xda, 0x34, 0x4c, 0xb7, 0x2b, 0xd9, 0x86, 0x5e, - 0x36, 0x99, 0x62, 0xa2, 0x11, 0x0a, 0x46, 0x5b, 0x72, 0x09, 0xd8, 0x9e, - 0x02, 0x95, 0x22, 0x82, 0x71, 0xa9, 0x3d, 0xd8, 0x96, 0xe2, 0x5f, 0xe0, - 0x90, 0x9a, 0x08, 0x45, 0x0f, 0x0b, 0x36, 0x90, 0x20, 0x1a, 0x7b, 0x50, - 0x09, 0x0a, 0x3b, 0x07, 0x41, 0x44, 0x2d, 0xa8, 0x88, 0x60, 0x3d, 0x08, - 0x85, 0xda, 0x8b, 0x51, 0x8b, 0x8a, 0x07, 0x0f, 0x01, 0x8f, 0x9a, 0xf1, - 0xfb, 0x7e, 0x7c, 0x37, 0x33, 0x93, 0xdd, 0x24, 0x27, 0x03, 0xed, 0x87, - 0xf7, 0x9d, 0xf7, 0x7d, 0xdf, 0xf7, 0xde, 0xf7, 0xf3, 0x3e, 0xdf, 0xf5, - 0x01, 0xc0, 0x80, 0x28, 0x1e, 0x55, 0x08, 0x87, 0x8c, 0xa2, 0xad, 0xa0, - 0x00, 0xf0, 0x21, 0xf0, 0x9f, 0xe9, 0x92, 0x1d, 0x3d, 0x22, 0xf6, 0x04, - 0x43, 0x34, 0xe1, 0xab, 0xff, 0xaf, 0xc2, 0xe9, 0x26, 0x62, 0x11, 0x4e, - 0x1f, 0x47, 0x7c, 0x12, 0x6e, 0x37, 0x03, 0x85, 0xff, 0x26, 0x10, 0xa1, - 0x3d, 0xdc, 0xfd, 0x24, 0xae, 0x50, 0xfc, 0x4d, 0xd9, 0xff, 0x63, 0x91, - 0xf1, 0x54, 0x68, 0x73, 0x1c, 0x41, 0x38, 0xe9, 0x13, 0xdc, 0xed, 0xa0, - 0x7d, 0xfe, 0x3c, 0x58, 0x18, 0xe7, 0x6d, 0xe5, 0x80, 0x76, 0xa3, 0x10, - 0x9d, 0x94, 0xbc, 0x0c, 0xf6, 0xfb, 0xa9, 0xe3, 0xe1, 0x3a, 0xfc, 0x3c, - 0x8b, 0xf6, 0x51, 0xe7, 0xd5, 0x0e, 0x62, 0x00, 0x97, 0x6c, 0x97, 0xeb, - 0x19, 0xe5, 0xb0, 0x9b, 0xe3, 0xb8, 0x4f, 0xf9, 0x8e, 0x4b, 0x5c, 0x13, - 0xe3, 0xfe, 0x99, 0x70, 0x5c, 0x8c, 0x97, 0x8e, 0xd3, 0x50, 0x71, 0x70, - 0xdd, 0x92, 0xbc, 0xac, 0x5c, 0x5e, 0x96, 0xca, 0x43, 0xfa, 0x00, 0x3a, - 0x0f, 0xc4, 0x23, 0xea, 0x5c, 0x8c, 0xbb, 0x25, 0x75, 0x03, 0x3c, 0xdf, - 0x94, 0xf8, 0x31, 0xa2, 0x5b, 0xe0, 0x78, 0xea, 0x9f, 0xd4, 0xb1, 0x3b, - 0x8e, 0xee, 0x53, 0x36, 0xff, 0x72, 0xa8, 0xbf, 0xeb, 0xfb, 0xc0, 0x73, - 0x7e, 0x50, 0xe7, 0xa4, 0xfd, 0x61, 0x1f, 0xff, 0xef, 0x94, 0x7f, 0x36, - 0x2e, 0xaf, 0x7f, 0xbb, 0xb3, 0xde, 0xea, 0xd7, 0x37, 0x33, 0xd7, 0xb7, - 0x2f, 0xa5, 0x6f, 0x73, 0x70, 0xc2, 0x08, 0xc8, 0xaf, 0x04, 0x88, 0xc7, - 0x54, 0x02, 0x88, 0x0f, 0x0b, 0x5e, 0x13, 0xbc, 0x25, 0xf8, 0xae, 0xe0, - 0x11, 0xc1, 0x61, 0xc1, 0xc3, 0x82, 0x0f, 0x09, 0x6e, 0x09, 0xfa, 0x82, - 0x9e, 0x60, 0x4d, 0xf0, 0x2f, 0x41, 0x57, 0xb0, 0x92, 0x8b, 0x57, 0x17, - 0xb4, 0x05, 0x3f, 0x17, 0x7c, 0x22, 0xb7, 0xff, 0x68, 0x81, 0xf1, 0x81, - 0xd8, 0x4f, 0x89, 0x7d, 0x41, 0x6c, 0x6c, 0xa8, 0xf0, 0x3e, 0xd3, 0xaf, - 0x5b, 0xbd, 0xfb, 0xbd, 0xdb, 0x91, 0xef, 0x2d, 0xed, 0x67, 0x53, 0xff, - 0x60, 0x3c, 0xed, 0xff, 0xd6, 0x1e, 0xfe, 0xec, 0x36, 0xdb, 0xea, 0xb7, - 0xef, 0x66, 0xc2, 0x79, 0xbc, 0x29, 0xfb, 0x83, 0xee, 0x67, 0x03, 0xe6, - 0x68, 0x26, 0xcc, 0xf3, 0xab, 0xdf, 0x1c, 0x3d, 0x2e, 0x73, 0x34, 0xbd, - 0x8b, 0xbf, 0xcc, 0xd3, 0x33, 0xb2, 0x7f, 0x46, 0xf8, 0xd9, 0x18, 0xe0, - 0x17, 0xa5, 0xe6, 0x95, 0xce, 0x1b, 0x30, 0x0f, 0x1f, 0x15, 0xda, 0x61, - 0xc0, 0xfc, 0x89, 0xf6, 0xca, 0x0f, 0xf7, 0x0b, 0x7f, 0x5b, 0x9a, 0xc7, - 0x59, 0xfe, 0x32, 0x0f, 0xad, 0x1c, 0x0f, 0x5f, 0xde, 0xe7, 0x1e, 0x2a, - 0xb9, 0x7e, 0x5e, 0x56, 0xfe, 0x6c, 0x1a, 0x06, 0xe3, 0x1a, 0x63, 0xe8, - 0x5a, 0x25, 0xc4, 0x69, 0xf7, 0x1b, 0x8e, 0x37, 0x4a, 0x75, 0xb8, 0xc1, - 0x0a, 0xcd, 0x6d, 0x09, 0x56, 0xac, 0x21, 0x85, 0xff, 0x24, 0x6f, 0xb0, - 0x5f, 0xdd, 0xfc, 0x9e, 0x30, 0x58, 0xbb, 0xc3, 0xfe, 0xf7, 0x9a, 0x9c, - 0xf7, 0x33, 0x13, 0x90, 0xfb, 0xd3, 0xdf, 0x65, 0xde, 0x3d, 0xb4, 0xff, - 0x2e, 0x44, 0xb1, 0x3e, 0x47, 0xf6, 0x5d, 0xd6, 0x73, 0xc4, 0x7f, 0x8b, - 0x96, 0x4f, 0xf5, 0xde, 0x88, 0xc9, 0x1c, 0x76, 0x97, 0x7d, 0xfa, 0xfa, - 0x7a, 0xac, 0xeb, 0x11, 0x5d, 0x19, 0xd7, 0xf5, 0xf3, 0xfe, 0x2a, 0x9d, - 0x77, 0xb8, 0xbb, 0x9e, 0xe3, 0x49, 0xf3, 0x40, 0x3a, 0xbb, 0x95, 0xec, - 0xe8, 0x6c, 0xba, 0x0f, 0x5a, 0x67, 0x6d, 0x58, 0x98, 0xf3, 0xe8, 0xdc, - 0x9a, 0xc5, 0x61, 0x2e, 0x78, 0x8c, 0x17, 0x1d, 0xc6, 0xdf, 0x1c, 0xec, - 0x53, 0x92, 0x5c, 0xaa, 0xb0, 0xfd, 0x42, 0x55, 0xcf, 0xb7, 0xde, 0xaf, - 0xf3, 0xda, 0x2b, 0x1f, 0x3c, 0x5f, 0x9f, 0xa3, 0xf3, 0xd0, 0xe7, 0x65, - 0x79, 0x31, 0xf8, 0x5c, 0xc6, 0xb6, 0x91, 0xed, 0xc3, 0xda, 0x24, 0x63, - 0x69, 0x0a, 0xf3, 0xba, 0x9d, 0xf4, 0xe6, 0xbb, 0xe5, 0x93, 0xdf, 0x18, - 0xb0, 0x3d, 0x2f, 0x3c, 0x9c, 0xa7, 0xb9, 0x54, 0xba, 0x63, 0x20, 0xd6, - 0x21, 0xa2, 0x77, 0xc7, 0x70, 0xbe, 0x26, 0x5e, 0x14, 0x65, 0x5d, 0xdd, - 0xc3, 0x58, 0x76, 0x9e, 0x37, 0x99, 0x77, 0x76, 0x96, 0xaf, 0xc7, 0x84, - 0xaf, 0x4e, 0x77, 0xbd, 0xb3, 0xdf, 0x3c, 0x48, 0xc1, 0xbd, 0xfe, 0x6b, - 0x3d, 0xd4, 0xef, 0xb2, 0xd6, 0x3d, 0xfa, 0xdc, 0x8d, 0x8a, 0x99, 0x3a, - 0xcf, 0x40, 0xd8, 0xef, 0x7e, 0x3f, 0x16, 0x3d, 0x99, 0x16, 0x7d, 0x53, - 0x97, 0x18, 0x65, 0xf6, 0xd5, 0x80, 0xf2, 0x29, 0xe7, 0xe6, 0xac, 0xd4, - 0x9b, 0x9b, 0x45, 0x6b, 0x80, 0xde, 0x99, 0xfc, 0x7e, 0x2e, 0xcc, 0xe1, - 0xb9, 0x76, 0xe3, 0x06, 0xcd, 0x7f, 0x19, 0xfe, 0x70, 0xf9, 0x5e, 0xda, - 0x26, 0xda, 0xe6, 0xf0, 0x95, 0x4f, 0x33, 0xfd, 0x01, 0x38, 0xae, 0xdf, - 0x97, 0xf4, 0x1c, 0x07, 0xd0, 0x9e, 0x3a, 0xe8, 0x7b, 0x99, 0xe6, 0x7d, - 0x6d, 0x17, 0xef, 0xb5, 0x3e, 0x36, 0xc3, 0xf4, 0x9c, 0xe0, 0x3b, 0xc1, - 0xf7, 0xcd, 0xfa, 0x54, 0xc9, 0xf7, 0x41, 0xbd, 0x9f, 0xba, 0xbe, 0x7e, - 0xef, 0xe8, 0xaf, 0xdb, 0x07, 0xd3, 0xb3, 0x74, 0x9f, 0xfa, 0xe9, 0x99, - 0x93, 0xd3, 0xa7, 0x7b, 0xdb, 0x3d, 0x7d, 0x32, 0xfb, 0xd5, 0xff, 0x7f, - 0xe8, 0x36, 0xf7, 0xd3, 0x81, 0x74, 0x3d, 0x1b, 0x1b, 0xcc, 0x9f, 0xab, - 0xa9, 0x79, 0x49, 0xdf, 0xff, 0x90, 0xf0, 0x45, 0xf9, 0x51, 0x1d, 0x5f, - 0x6c, 0xef, 0xe8, 0x72, 0x9a, 0x7f, 0x2f, 0x0a, 0xff, 0x8d, 0x99, 0x75, - 0xe6, 0x47, 0xfb, 0xf7, 0xdc, 0x7d, 0x4d, 0x85, 0xc8, 0x97, 0x57, 0x20, - 0x96, 0x3c, 0xef, 0x67, 0xf2, 0xad, 0x8a, 0x2e, 0x95, 0xe1, 0x83, 0x58, - 0xd7, 0xc5, 0x9f, 0x9b, 0x21, 0xe3, 0xfb, 0xe4, 0xef, 0xef, 0xf3, 0x2e, - 0xf9, 0xf0, 0x5e, 0x4f, 0x7f, 0x3d, 0x8a, 0x37, 0x29, 0x3a, 0xb6, 0x20, - 0x7a, 0xf2, 0x8b, 0xc3, 0x7a, 0xd5, 0x3e, 0x4b, 0xfc, 0x85, 0x11, 0xd1, - 0x95, 0x76, 0x95, 0xed, 0x7a, 0x95, 0x7f, 0xef, 0x4e, 0x96, 0x5d, 0xf2, - 0xab, 0x57, 0x19, 0x47, 0x2a, 0xb8, 0x2f, 0x80, 0x07, 0xe7, 0xc8, 0x3d, - 0x5c, 0x75, 0xf9, 0x5d, 0x59, 0xbd, 0x23, 0x7a, 0xe7, 0xe9, 0xfe, 0x49, - 0xbd, 0x8f, 0xe1, 0xfa, 0x88, 0xd2, 0x0f, 0xb6, 0x99, 0x17, 0x6e, 0x6f, - 0x1e, 0xde, 0x91, 0xec, 0x9b, 0x5e, 0xba, 0xdf, 0x7a, 0x2e, 0x3b, 0xb9, - 0x3e, 0xeb, 0x7b, 0x3a, 0x95, 0x68, 0xbd, 0x1d, 0x9b, 0xc3, 0x7c, 0x3d, - 0xa8, 0x95, 0x99, 0x47, 0x8c, 0x2a, 0x8e, 0x51, 0xc6, 0x6d, 0x8d, 0x25, - 0xd1, 0xaf, 0xa5, 0x45, 0x0a, 0x73, 0x6e, 0x49, 0xaf, 0xcf, 0xd2, 0xe0, - 0xcc, 0x6f, 0x7c, 0x45, 0xeb, 0xb5, 0xb8, 0xc8, 0xeb, 0xe5, 0xb3, 0xba, - 0x5f, 0x1e, 0xd5, 0xbf, 0xc2, 0xfd, 0x7a, 0xee, 0x26, 0xe3, 0xb3, 0xf0, - 0x34, 0xa1, 0xb3, 0x22, 0x73, 0xbf, 0xea, 0xda, 0x84, 0x40, 0xfd, 0x32, - 0x1e, 0xe5, 0xf7, 0xd4, 0x94, 0x77, 0x70, 0x28, 0x75, 0x8f, 0xf9, 0xf7, - 0xea, 0xa0, 0xf7, 0x99, 0xd6, 0x6f, 0xfd, 0x9e, 0x16, 0x72, 0xbf, 0x5f, - 0xab, 0x39, 0x7e, 0xbe, 0x34, 0x80, 0x9f, 0x87, 0x06, 0xf0, 0x3b, 0xaf, - 0x87, 0x6d, 0x99, 0xff, 0x12, 0x98, 0x45, 0x7a, 0x08, 0xdd, 0xd2, 0x75, - 0xba, 0x5f, 0x63, 0x89, 0x7f, 0x4f, 0xb8, 0xe6, 0x72, 0x81, 0xfa, 0xe6, - 0x2e, 0xb3, 0x5f, 0x89, 0xd7, 0x03, 0x8d, 0xaf, 0x5d, 0xe7, 0x39, 0x33, - 0xe0, 0x3f, 0xdd, 0xd1, 0x99, 0x07, 0x78, 0x0d, 0x00, 0x00, 0x00 }; + /* Date: 01/27/2009 19:01 */ +#define XI_RV2P_PROC1_POST_WAIT_TIMEOUT_MSK 0xffff + 0xa5, 0x56, 0xdd, 0x6b, 0x1c, 0x55, 0x14, 0x3f, 0x33, 0xbb, 0x33, 0xb3, + 0xd9, 0x9d, 0xd9, 0x5d, 0x9a, 0x34, 0x8e, 0xb1, 0x34, 0xdb, 0x20, 0xca, + 0xa6, 0x13, 0xdd, 0x68, 0x1f, 0x04, 0x03, 0x2d, 0x01, 0x29, 0x98, 0xe2, + 0x43, 0xa0, 0x52, 0x8a, 0x60, 0x5c, 0xb4, 0x08, 0xf6, 0x2f, 0x10, 0xc1, + 0x21, 0x31, 0x11, 0xc4, 0xaf, 0x7d, 0xe8, 0x42, 0x02, 0x6a, 0x40, 0x50, + 0x09, 0x11, 0x77, 0xdf, 0x24, 0x16, 0x7c, 0x68, 0xf1, 0x41, 0xda, 0xa7, + 0x16, 0xd4, 0x97, 0x46, 0x11, 0xbf, 0x5e, 0x04, 0xd1, 0xc7, 0x9a, 0xf1, + 0x9e, 0x8f, 0xbb, 0x3b, 0x73, 0xb3, 0x9b, 0x14, 0x5c, 0x48, 0x7e, 0x9c, + 0x7b, 0xcf, 0x39, 0xf7, 0x7c, 0x9f, 0xa9, 0x02, 0x80, 0x0d, 0x71, 0x77, + 0x52, 0x21, 0x58, 0xb9, 0x5c, 0x01, 0x01, 0x60, 0x1b, 0xf8, 0xe7, 0xf8, + 0x44, 0xc7, 0x8f, 0x0a, 0x7d, 0x92, 0x21, 0x3e, 0x59, 0x55, 0xff, 0x2f, + 0xc3, 0xe9, 0x1a, 0x62, 0x0e, 0x4e, 0x9f, 0x40, 0x7c, 0x12, 0xbe, 0xae, + 0x85, 0x0a, 0xff, 0x4d, 0x20, 0x46, 0xfa, 0x68, 0xe7, 0xcb, 0x6e, 0x89, + 0xf4, 0xef, 0x8a, 0xfc, 0xf7, 0x39, 0xc6, 0x27, 0xa2, 0x02, 0xeb, 0x11, + 0x84, 0x99, 0x2a, 0xc1, 0xed, 0x16, 0xd2, 0xe7, 0xcf, 0x83, 0x8b, 0x7a, + 0xde, 0x53, 0x0c, 0x48, 0x1f, 0xb3, 0xe2, 0x19, 0xb1, 0xcb, 0x66, 0xbe, + 0x3b, 0xad, 0x0a, 0x9e, 0xc3, 0x8f, 0xf3, 0x48, 0xdf, 0x57, 0x7c, 0xa3, + 0x85, 0x38, 0x0e, 0x97, 0x0a, 0x3e, 0xfb, 0x53, 0x17, 0x9c, 0x64, 0xf5, + 0xbb, 0xd3, 0x28, 0xaf, 0x64, 0xa6, 0x45, 0xbf, 0x83, 0xfa, 0x7f, 0x4f, + 0x58, 0x3f, 0xea, 0x4d, 0xeb, 0xbb, 0x5f, 0xe9, 0xc3, 0x73, 0x57, 0xec, + 0x73, 0x0d, 0xfb, 0x5c, 0x65, 0x0f, 0xca, 0xaf, 0x00, 0xfb, 0x39, 0xaa, + 0xde, 0x45, 0xfa, 0xaf, 0xbe, 0xbe, 0x2e, 0xa2, 0x6f, 0xb1, 0xbc, 0xfa, + 0x13, 0xfb, 0x59, 0xee, 0x35, 0x25, 0xa7, 0xe3, 0x92, 0xb5, 0xd3, 0x8b, + 0xb4, 0x7f, 0x3a, 0xfe, 0xc8, 0x7f, 0x2b, 0xc9, 0xf2, 0xc3, 0x21, 0xfc, + 0x37, 0x15, 0x7f, 0x56, 0x2f, 0x9f, 0x7f, 0xdb, 0x3f, 0x1f, 0x18, 0x1f, + 0xc7, 0x88, 0xcf, 0x75, 0xf1, 0xe7, 0x29, 0x78, 0xd0, 0x0e, 0x89, 0x2f, + 0x0f, 0x21, 0xc5, 0x09, 0x62, 0xc4, 0xe3, 0x82, 0x2f, 0x09, 0x7e, 0x2e, + 0xb8, 0x2d, 0x08, 0xff, 0x13, 0xff, 0x1e, 0x72, 0x7e, 0x54, 0xf0, 0x01, + 0xe3, 0xfc, 0x9a, 0xe0, 0x23, 0x86, 0xfc, 0x71, 0x8b, 0xf1, 0x0f, 0xa1, + 0xe7, 0x85, 0x7e, 0xc6, 0x90, 0x8f, 0x81, 0xe3, 0x63, 0x19, 0x71, 0xfb, + 0x58, 0xea, 0x19, 0xf3, 0x2f, 0xf7, 0x75, 0xcd, 0x57, 0xa0, 0x38, 0xc2, + 0x74, 0x9a, 0xff, 0x83, 0x03, 0xf8, 0x99, 0x6d, 0xbe, 0x3e, 0x48, 0xae, + 0x9d, 0xb0, 0x1d, 0x57, 0x44, 0xbe, 0xd8, 0xb9, 0x3a, 0xa4, 0x7f, 0xe6, + 0xa2, 0x41, 0xfd, 0x52, 0x17, 0x3f, 0xbe, 0x92, 0xba, 0xdc, 0xb1, 0x9a, + 0x51, 0xc8, 0x79, 0xa5, 0x3c, 0x06, 0x52, 0x8f, 0x23, 0x46, 0x3d, 0x7b, + 0xaa, 0x9e, 0xa5, 0xae, 0xea, 0xba, 0xbe, 0xb2, 0x75, 0xc5, 0xf5, 0xe1, + 0x1a, 0xf5, 0x11, 0x1f, 0x12, 0x97, 0x92, 0xe1, 0xdf, 0xab, 0x09, 0x86, + 0x18, 0x7f, 0xb6, 0xcd, 0xb8, 0xc1, 0x18, 0xf9, 0x6e, 0x1e, 0xf1, 0x94, + 0xff, 0x0d, 0xeb, 0x9b, 0x04, 0x44, 0x3f, 0x6c, 0x53, 0x1f, 0xe5, 0xa1, + 0xed, 0x2a, 0x9b, 0xe1, 0x6e, 0xf2, 0x0e, 0xf3, 0x4d, 0x38, 0x37, 0x09, + 0xc3, 0x8d, 0x1b, 0xcc, 0xff, 0x5d, 0x8d, 0xed, 0x7e, 0x56, 0xe6, 0x53, + 0xff, 0xa7, 0xef, 0xa5, 0xff, 0x2a, 0x48, 0xff, 0x63, 0xc5, 0x5d, 0xfd, + 0x8e, 0xc8, 0xbd, 0xa2, 0xeb, 0x9b, 0x7f, 0xcb, 0x6e, 0x95, 0xfc, 0x7d, + 0xab, 0x4b, 0xe4, 0x98, 0xbf, 0x56, 0xa5, 0xdb, 0xb7, 0xbb, 0xda, 0x1f, + 0xe9, 0xf3, 0x69, 0xed, 0x3f, 0xcb, 0x07, 0x72, 0x6d, 0x3b, 0x3a, 0x7e, + 0x7c, 0x5e, 0x24, 0x3b, 0x46, 0x3b, 0x9b, 0x46, 0x3e, 0x6b, 0xf7, 0x34, + 0x07, 0xff, 0x4c, 0xfa, 0x73, 0x30, 0x1d, 0x1f, 0x3d, 0x07, 0x0b, 0xb0, + 0x74, 0xb6, 0x42, 0xf6, 0x94, 0x5d, 0x56, 0x73, 0xa1, 0xc2, 0xf8, 0x62, + 0x91, 0xf1, 0x97, 0x22, 0xc6, 0x2f, 0x49, 0x2e, 0x95, 0x98, 0x7e, 0x21, + 0x40, 0xbd, 0xa3, 0xea, 0x61, 0x2d, 0xaf, 0xed, 0x3a, 0xc8, 0x1e, 0x7c, + 0x5f, 0xbf, 0xa3, 0xed, 0xd0, 0xef, 0x65, 0xeb, 0x65, 0xf8, 0xbb, 0x8c, + 0x4d, 0x3b, 0x1b, 0x87, 0xfc, 0x2c, 0xe3, 0x46, 0x03, 0xed, 0xba, 0x9a, + 0xf4, 0xfa, 0xb0, 0x5e, 0x25, 0xbe, 0x29, 0x60, 0x7a, 0x51, 0xea, 0x73, + 0x91, 0xfa, 0xa7, 0xac, 0xae, 0x10, 0x27, 0x20, 0xa6, 0xbd, 0x60, 0x17, + 0xaf, 0x53, 0xbd, 0xe4, 0xe4, 0x5c, 0xe5, 0x67, 0x2a, 0xdb, 0x77, 0xbb, + 0x5c, 0x8f, 0x85, 0x6c, 0x1d, 0x3f, 0x9c, 0x9a, 0xaf, 0x69, 0x7f, 0xad, + 0x5e, 0xfd, 0xee, 0xcf, 0x53, 0x36, 0x1f, 0xb7, 0x5b, 0xda, 0x7f, 0x73, + 0x6f, 0x30, 0x7b, 0xdc, 0x90, 0x40, 0xcd, 0xca, 0xfd, 0x8c, 0xd9, 0x2f, + 0x83, 0xfa, 0xad, 0x6a, 0xf4, 0xcf, 0x11, 0xe9, 0xb7, 0x91, 0xce, 0x66, + 0xeb, 0xb0, 0x7e, 0x46, 0xfe, 0x2f, 0x64, 0x9e, 0x54, 0xa1, 0xb7, 0x97, + 0xb6, 0x91, 0x2e, 0x81, 0xf4, 0x61, 0x27, 0xce, 0x65, 0xf2, 0x70, 0x06, + 0x06, 0xce, 0x95, 0x0f, 0x45, 0x4f, 0x43, 0xe6, 0x8b, 0x9b, 0xda, 0x5f, + 0xc4, 0x5e, 0x06, 0xb2, 0xc3, 0x33, 0xe6, 0xc3, 0xdd, 0x3d, 0xdd, 0xef, + 0xcb, 0xee, 0x20, 0x7f, 0x3d, 0xf8, 0xcd, 0xe7, 0xfa, 0x68, 0x52, 0xbf, + 0x38, 0x63, 0x97, 0x77, 0x32, 0x79, 0x02, 0x38, 0xa1, 0xf7, 0x52, 0xda, + 0xae, 0xf4, 0x5e, 0x45, 0x7d, 0x21, 0x34, 0x67, 0xd3, 0xfb, 0xf5, 0xfd, + 0x44, 0xcf, 0xf5, 0x80, 0xfa, 0xa4, 0xbc, 0xaf, 0xef, 0xf4, 0x1c, 0xad, + 0x45, 0xe9, 0xfe, 0x1d, 0x93, 0xb9, 0x69, 0x03, 0xcf, 0xcd, 0x92, 0xe9, + 0xa7, 0xda, 0xb7, 0x83, 0xf3, 0xc5, 0xfe, 0xde, 0xd9, 0xbb, 0xb7, 0x39, + 0x7b, 0x58, 0xde, 0x8b, 0x46, 0xde, 0x6f, 0xf5, 0xe2, 0x68, 0x3b, 0x83, + 0xbe, 0x2b, 0x4e, 0x29, 0xbd, 0xc2, 0x2f, 0x73, 0xe1, 0x79, 0x9a, 0x77, + 0x67, 0x84, 0x6f, 0x2e, 0x55, 0xaf, 0x83, 0xf8, 0x62, 0xa3, 0xae, 0x0b, + 0xfb, 0xf8, 0xb2, 0x73, 0x4c, 0xfb, 0xb3, 0xb5, 0xc5, 0xf5, 0x71, 0x31, + 0xd5, 0xaf, 0xe9, 0xf9, 0x3f, 0x22, 0xf5, 0xa0, 0xf8, 0xc8, 0x8f, 0x9d, + 0xbd, 0xfe, 0xbe, 0x48, 0xd7, 0xd7, 0xa2, 0xd4, 0xb5, 0x3d, 0xb7, 0x49, + 0x7d, 0xe4, 0x35, 0x7f, 0x35, 0xf2, 0x35, 0x1b, 0x61, 0x9d, 0xbc, 0x0e, + 0x5d, 0xb1, 0xf3, 0x87, 0x8c, 0xbd, 0x81, 0xf4, 0xa1, 0x0b, 0x9f, 0x75, + 0xb5, 0x5f, 0x7c, 0x5d, 0x8b, 0x18, 0x3f, 0x8d, 0xa4, 0x9f, 0x7a, 0xfe, + 0xe1, 0xbb, 0x0b, 0xf2, 0x6e, 0x15, 0x3e, 0xe9, 0xed, 0x03, 0x9c, 0x6f, + 0x1e, 0x34, 0x64, 0x7e, 0x2e, 0xc9, 0x1c, 0xfb, 0xa9, 0xc8, 0x73, 0xb2, + 0xb9, 0x40, 0xf5, 0x0a, 0xe3, 0x32, 0xcf, 0x9a, 0x01, 0xd3, 0x13, 0x01, + 0x7f, 0x07, 0x37, 0x3c, 0x9f, 0xf8, 0x26, 0x02, 0xc6, 0xf1, 0x12, 0xca, + 0x85, 0xf0, 0xf3, 0x39, 0x62, 0x8f, 0xd6, 0x7d, 0xde, 0x73, 0xeb, 0x37, + 0x64, 0x9e, 0x54, 0x74, 0xdc, 0xc4, 0xcf, 0xc7, 0xf1, 0x7c, 0x5c, 0xcd, + 0x2d, 0xa6, 0xb9, 0x1e, 0xfc, 0x5e, 0xfd, 0x7f, 0x24, 0x59, 0xa9, 0x55, + 0xd2, 0x71, 0xd6, 0xfd, 0xf6, 0xae, 0x11, 0x5f, 0x9d, 0x9f, 0x87, 0x12, + 0x3d, 0xe7, 0xa7, 0xce, 0xa2, 0xbd, 0x15, 0x28, 0x7b, 0x5c, 0x3f, 0x8c, + 0x4a, 0x8f, 0xed, 0xa1, 0xd8, 0xb1, 0x55, 0x99, 0x9b, 0xab, 0xcb, 0xa4, + 0xe6, 0xdc, 0xaa, 0x3e, 0x9f, 0xa7, 0x86, 0x59, 0xdc, 0xba, 0x46, 0xe7, + 0xe5, 0x6e, 0x8e, 0xcf, 0xbd, 0x05, 0x1d, 0xaf, 0x0a, 0xf9, 0xdf, 0xe6, + 0x78, 0x3d, 0x77, 0x85, 0xf1, 0x22, 0x3c, 0x4d, 0x58, 0x6c, 0x4b, 0x9f, + 0xaf, 0xfb, 0x05, 0x42, 0xa0, 0x78, 0xd9, 0x8f, 0xf1, 0x7e, 0x77, 0x64, + 0x2f, 0x17, 0x52, 0xf9, 0x33, 0xf7, 0xe4, 0x41, 0x79, 0x3c, 0x62, 0xec, + 0x0b, 0xbd, 0xd7, 0x2d, 0xe3, 0xfb, 0x36, 0x30, 0xea, 0xf1, 0xe5, 0x21, + 0xf5, 0x08, 0x43, 0xea, 0xd9, 0x9c, 0x6f, 0x4b, 0xd2, 0xef, 0x79, 0x70, + 0x72, 0xb4, 0x78, 0xfd, 0xfc, 0x0a, 0xe5, 0xd5, 0x5e, 0xe5, 0xef, 0x1a, + 0xdf, 0x59, 0xb3, 0x28, 0x5e, 0xfe, 0x1a, 0xf3, 0xe5, 0xf9, 0x3c, 0xd4, + 0xf8, 0xe6, 0x0a, 0xf7, 0x95, 0x0d, 0xff, 0x01, 0xd7, 0x0e, 0x41, 0x60, + 0x88, 0x0d, 0x00, 0x00, 0x00 }; static u8 bnx2_xi_rv2p_proc2[] = { - /* Date: 06/17/2008 16:52 */ + /* Date: 01/27/2009 19:01 */ #define XI_RV2P_PROC2_MAX_BD_PAGE_LOC 5 #define XI_RV2P_PROC2_BD_PAGE_SIZE_MSK 0xffff #define XI_RV2P_PROC2_BD_PAGE_SIZE ((BCM_PAGE_SIZE / 16) - 1) - 0xad, 0x58, 0x4d, 0x4c, 0x54, 0x57, 0x14, 0xbe, 0xf3, 0xc3, 0xcc, 0x30, - 0xbc, 0x99, 0x41, 0x98, 0x0e, 0x7f, 0xa6, 0x22, 0x28, 0x82, 0x1d, 0x14, - 0x06, 0xd4, 0xb6, 0x36, 0xa9, 0xc1, 0x06, 0xb5, 0xb5, 0x11, 0x69, 0x63, - 0xba, 0x68, 0x8a, 0x60, 0x45, 0x06, 0xc1, 0x10, 0x31, 0x2e, 0xdc, 0x74, - 0x02, 0x16, 0xbb, 0x98, 0x85, 0x98, 0xe2, 0x60, 0xd3, 0x18, 0x52, 0x37, - 0xa6, 0x3b, 0x92, 0xb6, 0x62, 0xbb, 0x30, 0x31, 0x2d, 0xb1, 0xb6, 0x89, - 0x36, 0xb1, 0x7f, 0x9b, 0xa6, 0xa6, 0x5a, 0x8a, 0x4a, 0x2d, 0xda, 0xb2, - 0xaa, 0xd0, 0x77, 0xcf, 0x77, 0xee, 0x9b, 0x37, 0x33, 0x6f, 0x44, 0x53, - 0xd9, 0x1c, 0xee, 0x7d, 0xe7, 0x9e, 0x7b, 0xce, 0x77, 0x7e, 0xef, 0xe4, - 0x0b, 0x21, 0x9c, 0x22, 0x36, 0xbe, 0x4c, 0xa7, 0x62, 0x89, 0xdd, 0xe1, - 0xd1, 0xc9, 0x82, 0x10, 0x39, 0xc5, 0x72, 0x2d, 0xec, 0x82, 0xff, 0x56, - 0xe7, 0x13, 0xb9, 0x36, 0x2e, 0xbf, 0xbb, 0xc5, 0xeb, 0x76, 0x7c, 0x77, - 0x0a, 0x49, 0x03, 0x42, 0xc4, 0x24, 0xcd, 0x67, 0xba, 0x9d, 0xe9, 0x4a, - 0x1b, 0xe8, 0x46, 0xa6, 0x51, 0xa6, 0x2b, 0x98, 0xd6, 0xdb, 0x41, 0x57, - 0x31, 0xad, 0xe6, 0x7d, 0x8d, 0xcf, 0xd7, 0xf2, 0xfe, 0x7b, 0x4c, 0x8f, - 0xf2, 0xbe, 0xa6, 0xf3, 0x29, 0xbd, 0xe4, 0x7a, 0x66, 0x41, 0xc4, 0xf4, - 0x33, 0x42, 0xdf, 0xae, 0x51, 0xfb, 0x1a, 0x91, 0x58, 0x0d, 0xf4, 0x7e, - 0xad, 0x5c, 0xf2, 0xfd, 0x61, 0xc1, 0x27, 0xf7, 0x6f, 0x2e, 0x28, 0x79, - 0x03, 0x0e, 0xb9, 0xfe, 0x55, 0x5f, 0xdb, 0xe4, 0x32, 0x18, 0x82, 0x98, - 0x60, 0x71, 0x5c, 0xca, 0x71, 0x88, 0xd1, 0x61, 0x0f, 0xa1, 0x72, 0x52, - 0xc3, 0x3a, 0x46, 0x78, 0xd8, 0xf4, 0x35, 0xcb, 0x63, 0x5a, 0xe2, 0xc3, - 0xbd, 0xbb, 0xca, 0x71, 0xdf, 0x8f, 0xcf, 0x80, 0x2f, 0x16, 0x50, 0x80, - 0xe2, 0xfb, 0x32, 0xc1, 0xdf, 0xf7, 0xcb, 0xf5, 0xac, 0xad, 0xd0, 0x06, - 0x5c, 0xdd, 0xcc, 0x65, 0xcf, 0x91, 0xfb, 0xcb, 0x1b, 0x4f, 0x0e, 0x83, - 0xbf, 0xad, 0x1c, 0xfb, 0x4f, 0x87, 0xa5, 0x3c, 0x97, 0x88, 0x31, 0x15, - 0xb5, 0xa4, 0x97, 0x2d, 0x56, 0x9b, 0x2a, 0xff, 0x97, 0x61, 0xac, 0xda, - 0x7d, 0x90, 0xeb, 0x4d, 0x91, 0x1b, 0xca, 0x90, 0xfb, 0x53, 0xae, 0x59, - 0xbe, 0xdf, 0x06, 0xf9, 0xde, 0x45, 0xe5, 0x77, 0xf8, 0x40, 0x0b, 0xc3, - 0x56, 0xf7, 0xe4, 0x2e, 0xa2, 0x7f, 0xf7, 0xa2, 0xf2, 0x8f, 0x18, 0xfa, - 0x2b, 0xff, 0xa9, 0xef, 0xe9, 0x38, 0xd2, 0xf2, 0xe3, 0xd8, 0x5a, 0x16, - 0xb3, 0x5a, 0xd9, 0xcf, 0x7a, 0x3a, 0x40, 0x37, 0x85, 0x89, 0xc4, 0xf7, - 0x70, 0x80, 0x37, 0x57, 0xc9, 0xfb, 0x0b, 0x84, 0xd3, 0x2e, 0xe5, 0xd5, - 0x79, 0x5c, 0xe7, 0xb1, 0xff, 0x06, 0xfb, 0xeb, 0x6d, 0x36, 0xe8, 0xa6, - 0x57, 0x02, 0xb4, 0xb0, 0xd0, 0x99, 0xc7, 0xf2, 0xd9, 0xdf, 0xb1, 0x3c, - 0x9c, 0x9f, 0xd4, 0xa4, 0x9e, 0x5f, 0xeb, 0xf1, 0x63, 0xe5, 0x7f, 0xc7, - 0x43, 0xfc, 0x8f, 0xf3, 0x4b, 0x56, 0xe1, 0xeb, 0xf1, 0x4e, 0xac, 0xcb, - 0xce, 0xe4, 0x13, 0x4e, 0xa3, 0xe3, 0x56, 0xf1, 0x92, 0x2e, 0x5f, 0xcf, - 0xe3, 0x00, 0xee, 0x11, 0x15, 0x1e, 0x52, 0x0e, 0xf8, 0xea, 0x3c, 0xb5, - 0x96, 0x38, 0x89, 0x93, 0x2b, 0xe5, 0xbe, 0x5d, 0xb4, 0x3a, 0x34, 0xba, - 0xa7, 0x35, 0xaa, 0xf2, 0x06, 0xdf, 0x3b, 0x5d, 0x44, 0x8a, 0xdb, 0x87, - 0xa4, 0xdd, 0x01, 0xb1, 0xdb, 0x1e, 0x20, 0x7e, 0xe0, 0xe4, 0xf0, 0x68, - 0x9f, 0x81, 0xff, 0xc2, 0x32, 0x8d, 0x6c, 0xea, 0x6c, 0xc0, 0xb9, 0x60, - 0x04, 0x74, 0x24, 0x92, 0x23, 0x49, 0xb8, 0xb3, 0x9f, 0x96, 0x6b, 0x7e, - 0xab, 0xf7, 0x10, 0x5f, 0xac, 0x56, 0xe5, 0xa5, 0xf2, 0xa3, 0xc4, 0xed, - 0x90, 0x91, 0x87, 0xa2, 0x12, 0x38, 0xff, 0xbe, 0x52, 0xf2, 0xeb, 0x60, - 0x57, 0xe0, 0x9e, 0xa4, 0x7e, 0xe6, 0xbc, 0xee, 0x35, 0xe5, 0xf5, 0xe3, - 0xc5, 0xc5, 0x26, 0xc2, 0x67, 0x13, 0xe3, 0x54, 0xce, 0x71, 0xb8, 0xd4, - 0x22, 0x0e, 0x03, 0xf4, 0xff, 0xad, 0xa6, 0x7c, 0xc2, 0x79, 0x07, 0xf6, - 0x4f, 0x34, 0x9f, 0x83, 0x9f, 0xb6, 0x11, 0x1e, 0xc2, 0x7b, 0xf4, 0x53, - 0x9c, 0x6a, 0xa7, 0xfc, 0xef, 0x6d, 0xec, 0xfc, 0x1c, 0xeb, 0x0e, 0x87, - 0x5c, 0xef, 0xd7, 0xf6, 0x4c, 0x80, 0x3f, 0x67, 0x10, 0xb8, 0xef, 0xe0, - 0x5b, 0xb6, 0x39, 0xa8, 0xde, 0xc4, 0x5d, 0x83, 0xb4, 0xd4, 0x26, 0xe9, - 0x7b, 0xbe, 0x38, 0x36, 0x8e, 0xef, 0x07, 0xf2, 0xa4, 0x9d, 0xaf, 0x1a, - 0x75, 0x29, 0xea, 0xc2, 0xf9, 0xf8, 0x30, 0xea, 0xca, 0xf4, 0x27, 0x72, - 0xdd, 0x16, 0x9e, 0x06, 0x7f, 0x38, 0x3a, 0xc4, 0x82, 0xed, 0xc0, 0xf1, - 0x96, 0x1d, 0xfc, 0x1c, 0xae, 0x5e, 0x27, 0xf9, 0xd1, 0x26, 0xb4, 0x66, - 0xd0, 0x77, 0xe9, 0xfb, 0xbf, 0xb6, 0x38, 0xe1, 0xb6, 0xcb, 0xef, 0x3c, - 0xa7, 0xf0, 0x61, 0x1a, 0x50, 0x76, 0x81, 0x3e, 0x6a, 0x3e, 0x0c, 0x69, - 0xd9, 0xf2, 0x80, 0xfd, 0x59, 0xb3, 0x58, 0x1e, 0x80, 0x36, 0x57, 0x81, - 0xba, 0x2a, 0xa9, 0x9e, 0x3c, 0x46, 0x3e, 0xb0, 0x5e, 0x19, 0xf9, 0x86, - 0xdd, 0x64, 0x9c, 0x12, 0xd1, 0xe3, 0x33, 0x25, 0x5e, 0x39, 0x3f, 0x96, - 0xeb, 0x7e, 0x50, 0x71, 0x27, 0x05, 0xba, 0xc5, 0x7e, 0x96, 0x1b, 0x65, - 0x3c, 0x7a, 0x18, 0x8f, 0x19, 0xa6, 0x07, 0xf2, 0x14, 0x0e, 0xa0, 0xc7, - 0x34, 0xdc, 0xdb, 0x1a, 0x95, 0x7e, 0x0c, 0x5a, 0xf4, 0x17, 0xd5, 0x47, - 0xe0, 0xa7, 0x51, 0xf6, 0xeb, 0x29, 0xa3, 0x9f, 0x28, 0x7c, 0xb3, 0xf5, - 0x95, 0xd4, 0x7c, 0x4a, 0xb3, 0x33, 0xfe, 0x55, 0x05, 0x8e, 0x17, 0x54, - 0x82, 0x1a, 0xf8, 0x56, 0x51, 0x1e, 0xfb, 0x8b, 0x26, 0x94, 0x7d, 0x52, - 0xbf, 0x3b, 0x2a, 0x0f, 0xfd, 0x89, 0x01, 0xa2, 0xde, 0x82, 0x33, 0xf2, - 0x9e, 0x52, 0x8b, 0xba, 0x92, 0x9a, 0xcf, 0xe9, 0xf8, 0x1e, 0xf0, 0x51, - 0xc1, 0x6d, 0xbc, 0x32, 0x95, 0x9a, 0xb7, 0xc8, 0x4f, 0xb7, 0x11, 0xdf, - 0xc1, 0xf5, 0xec, 0x07, 0xa6, 0xa1, 0x0d, 0x52, 0x6e, 0x0b, 0xdf, 0x53, - 0xc7, 0xf7, 0x68, 0xa6, 0xba, 0x21, 0xf5, 0xfc, 0x73, 0x5e, 0xd5, 0x0b, - 0x15, 0x1f, 0xc9, 0xba, 0xa1, 0xfc, 0x40, 0xf7, 0x87, 0xaf, 0x4c, 0xc9, - 0xf3, 0x65, 0x8b, 0xd4, 0x91, 0x1b, 0x86, 0xbc, 0xef, 0x8d, 0x3a, 0x21, - 0xbf, 0xe7, 0x89, 0x17, 0x79, 0x99, 0x5a, 0x0f, 0xff, 0xd2, 0xeb, 0x21, - 0xd9, 0xe1, 0xd1, 0xce, 0x71, 0xfd, 0xeb, 0x97, 0xf7, 0x14, 0xb3, 0xde, - 0xc5, 0xaa, 0xaf, 0xe9, 0x7a, 0x73, 0x9d, 0x6c, 0x33, 0xd7, 0xbb, 0x1f, - 0xe6, 0x93, 0x75, 0x4b, 0xae, 0xaf, 0xcd, 0x67, 0xce, 0x27, 0x96, 0xb8, - 0xc6, 0x44, 0x00, 0x73, 0x58, 0x2c, 0x20, 0xcf, 0xe5, 0xd8, 0x32, 0xeb, - 0x5f, 0xba, 0x1d, 0xc0, 0xa5, 0xdd, 0xee, 0x23, 0xbe, 0xeb, 0x7d, 0xf2, - 0xdc, 0xb4, 0x50, 0xf6, 0xa2, 0x0e, 0x96, 0x73, 0xbf, 0x5f, 0xca, 0x7a, - 0xeb, 0xf2, 0x6a, 0x29, 0x1f, 0x3c, 0xd7, 0xfb, 0xcc, 0x7a, 0x5f, 0x98, - 0xcf, 0x7e, 0x9f, 0x75, 0x1c, 0xf4, 0x71, 0x9f, 0xe5, 0x39, 0xc1, 0xb3, - 0xe7, 0x0b, 0xa5, 0x17, 0xdf, 0x1f, 0x50, 0x7a, 0x68, 0xe4, 0xa7, 0xa9, - 0x7e, 0x29, 0xa7, 0x50, 0x70, 0xd8, 0x88, 0xde, 0x6a, 0xd4, 0xdf, 0x99, - 0xbd, 0xb0, 0xa3, 0xb7, 0x4a, 0xea, 0xa1, 0x7b, 0x25, 0x86, 0x3c, 0x17, - 0xdc, 0x8f, 0xbe, 0x1c, 0xb6, 0xf2, 0xeb, 0xb7, 0xcc, 0x17, 0x64, 0xfb, - 0xf2, 0xd9, 0xbe, 0xb0, 0x48, 0xaf, 0xf3, 0x6d, 0xe5, 0xd4, 0x0f, 0x98, - 0xef, 0x05, 0xd5, 0x0f, 0x74, 0x3e, 0xc2, 0x99, 0xe5, 0x58, 0xe1, 0x64, - 0x25, 0x67, 0x82, 0xe3, 0xa0, 0x8b, 0xf9, 0x9c, 0x59, 0xe7, 0x9b, 0xb9, - 0x55, 0xd4, 0x57, 0x4e, 0x1f, 0xa1, 0xfe, 0xe0, 0x33, 0xe2, 0x34, 0xd5, - 0x8e, 0xe3, 0x4f, 0x10, 0x77, 0x9a, 0xff, 0xc4, 0x3e, 0x7f, 0x36, 0x7c, - 0x9d, 0x72, 0x7b, 0x6c, 0x76, 0x42, 0xf9, 0x47, 0x23, 0x7b, 0xa7, 0xfa, - 0xd5, 0x9c, 0x6f, 0xc6, 0xdd, 0x6e, 0xc2, 0x1d, 0xfc, 0x98, 0xef, 0xfe, - 0x0f, 0xde, 0x56, 0xf3, 0x41, 0x9f, 0x91, 0x9f, 0x03, 0x2e, 0xab, 0xfa, - 0xbf, 0xd6, 0x88, 0x97, 0x83, 0x3c, 0xe7, 0xcd, 0x69, 0xf4, 0x4f, 0x64, - 0x26, 0x4e, 0x4b, 0xad, 0xe4, 0xac, 0xe4, 0x5b, 0x1d, 0x39, 0xc8, 0x76, - 0x5d, 0x76, 0xc0, 0xee, 0xae, 0xbd, 0x58, 0x5f, 0xe1, 0x7a, 0x7d, 0x8f, - 0xeb, 0xe3, 0x4e, 0x0f, 0xe8, 0x4c, 0x35, 0xe1, 0x11, 0x39, 0x78, 0x5e, - 0xc9, 0x27, 0xb9, 0xda, 0x1c, 0xe3, 0xf9, 0x92, 0x83, 0xed, 0xac, 0x20, - 0x3f, 0x46, 0xee, 0x52, 0x3d, 0x70, 0x8a, 0xa6, 0xe5, 0x92, 0x96, 0xe8, - 0xb8, 0xb1, 0x3e, 0x1b, 0x41, 0x5b, 0xd5, 0x80, 0x5f, 0x93, 0xee, 0x67, - 0x6c, 0xbb, 0x2a, 0xf8, 0x7c, 0x3b, 0xd6, 0x6e, 0xae, 0x67, 0x09, 0xd6, - 0xeb, 0xfd, 0x6a, 0x50, 0x7f, 0x0d, 0xe6, 0x84, 0x29, 0xea, 0x0b, 0x81, - 0x48, 0xff, 0x04, 0xec, 0xe9, 0xd9, 0x0c, 0x7b, 0xef, 0x33, 0x0e, 0x4c, - 0xfd, 0xa7, 0x06, 0xa9, 0xef, 0xf8, 0x87, 0x30, 0x67, 0xf8, 0x5d, 0x83, - 0xb0, 0xa3, 0x67, 0x0e, 0xeb, 0xfb, 0xcf, 0x81, 0xfe, 0xf3, 0x3c, 0xce, - 0x1d, 0x3a, 0xc2, 0xf8, 0x6c, 0xb6, 0x3e, 0xd7, 0xf5, 0x37, 0xf8, 0x7a, - 0xab, 0xe5, 0xfd, 0x6f, 0x8d, 0xf1, 0xfc, 0x21, 0xa2, 0x34, 0xef, 0xbc, - 0xa9, 0xcd, 0xf1, 0xba, 0x9b, 0xfb, 0xe2, 0x6d, 0x9e, 0x17, 0x7a, 0xd2, - 0xe6, 0x85, 0x69, 0xd4, 0xe9, 0xb1, 0xb9, 0xb8, 0xdc, 0xd0, 0xeb, 0x65, - 0xae, 0x95, 0x7f, 0x7d, 0x91, 0x22, 0xf6, 0x5b, 0x70, 0x1d, 0xe8, 0xc8, - 0x3a, 0xf4, 0xeb, 0x9e, 0xc3, 0x8c, 0x4f, 0x23, 0xf9, 0x69, 0xcd, 0xec, - 0x44, 0xfa, 0x79, 0x19, 0x3f, 0xed, 0xf3, 0x78, 0x3f, 0x6e, 0xd6, 0xa9, - 0xba, 0x0f, 0xe7, 0x3a, 0xe8, 0x7d, 0x71, 0xcf, 0x98, 0x3f, 0xa7, 0x49, - 0xff, 0xb2, 0xb1, 0x39, 0x92, 0x53, 0x2a, 0x0a, 0x29, 0x0e, 0x4b, 0xfc, - 0xb3, 0xb0, 0x27, 0x92, 0x60, 0x1c, 0xfa, 0x9e, 0x05, 0x3d, 0xcc, 0x71, - 0xa0, 0xfc, 0x7b, 0x75, 0x83, 0x46, 0xe7, 0xa6, 0xfa, 0x71, 0x8f, 0xca, - 0xa3, 0xf4, 0xb9, 0x58, 0xc5, 0x45, 0x49, 0x03, 0xad, 0x45, 0xd7, 0x21, - 0xb2, 0x53, 0xf7, 0xa7, 0x8c, 0x27, 0x1d, 0x2b, 0xee, 0xdb, 0xa9, 0xf1, - 0x22, 0xe3, 0x49, 0xc5, 0xad, 0x39, 0xce, 0xcc, 0x71, 0x94, 0x1a, 0x3f, - 0x7e, 0xea, 0x2f, 0x7a, 0x31, 0xa0, 0x77, 0x89, 0x2b, 0x92, 0x18, 0x7e, - 0x38, 0x8e, 0xa7, 0x80, 0x63, 0x84, 0xf5, 0xd6, 0xa2, 0x34, 0x8f, 0x3e, - 0x25, 0x86, 0xd8, 0x9f, 0xd3, 0xd5, 0x9c, 0xff, 0x15, 0xf0, 0x67, 0xdf, - 0x0a, 0xe8, 0xd3, 0xc7, 0x79, 0x74, 0x87, 0xe7, 0x0c, 0xc4, 0x81, 0x5b, - 0xeb, 0x9c, 0x60, 0xbf, 0x73, 0x3c, 0x76, 0x33, 0x0e, 0xb7, 0x81, 0x83, - 0xa6, 0x70, 0x88, 0x1a, 0x38, 0xa8, 0x7a, 0x63, 0x96, 0x53, 0xa0, 0xc7, - 0x93, 0xa4, 0x4b, 0xb4, 0xab, 0x34, 0x8f, 0xe5, 0xb0, 0xdd, 0x3a, 0x5f, - 0x83, 0xb4, 0xcf, 0xcf, 0xf6, 0xf9, 0xc4, 0xbe, 0x35, 0xe6, 0x73, 0x79, - 0x7c, 0xce, 0xab, 0x9f, 0xc3, 0x3e, 0xf2, 0x55, 0xcb, 0x82, 0xaf, 0xc4, - 0x51, 0xc9, 0x4d, 0xcf, 0x4b, 0x33, 0x9e, 0x54, 0xa9, 0xe9, 0x0f, 0xf5, - 0x48, 0xf7, 0x1b, 0xd5, 0x2d, 0xcd, 0xa8, 0x43, 0xf7, 0xa8, 0xae, 0x7b, - 0x4f, 0xf7, 0xa2, 0x6e, 0x9c, 0xee, 0x3d, 0xcb, 0x7d, 0x98, 0x71, 0x69, - 0xa1, 0xf7, 0x83, 0x8e, 0x5d, 0x45, 0x6a, 0x1d, 0x4a, 0xd5, 0xa3, 0xcc, - 0xa4, 0x87, 0xba, 0x77, 0xb1, 0x39, 0x01, 0x73, 0xea, 0x16, 0x9a, 0x13, - 0x3c, 0xc6, 0xbc, 0x9d, 0xda, 0x4f, 0x26, 0x1f, 0x3c, 0x6e, 0x3f, 0xd9, - 0xd9, 0x60, 0xbe, 0xaf, 0x46, 0x4c, 0x8e, 0xe3, 0x9e, 0x16, 0xee, 0xdf, - 0xbb, 0x39, 0xcf, 0xaf, 0x7b, 0x03, 0x74, 0x6f, 0xc7, 0x2b, 0x64, 0xaf, - 0x08, 0xe5, 0xc1, 0xbe, 0x8e, 0xed, 0xf8, 0xde, 0xe1, 0xc3, 0x7e, 0xa9, - 0x0f, 0xbf, 0xa3, 0xb4, 0xb8, 0x35, 0xe2, 0x2f, 0xf5, 0x81, 0x86, 0xb8, - 0x3e, 0x4c, 0x1a, 0xef, 0x09, 0xd0, 0x51, 0x57, 0xb6, 0xf7, 0x04, 0xde, - 0x65, 0x17, 0x5d, 0xa8, 0x1f, 0xa2, 0x06, 0x73, 0x74, 0x53, 0x95, 0x46, - 0xdf, 0x5b, 0x6b, 0xd0, 0xa7, 0x51, 0x9f, 0x33, 0xed, 0x2a, 0x43, 0xbc, - 0x96, 0x26, 0xdf, 0x1d, 0xe6, 0xf7, 0x89, 0x16, 0x49, 0x18, 0xf3, 0x7f, - 0xaa, 0x1e, 0xc8, 0x33, 0x29, 0x9f, 0x96, 0xfa, 0x9c, 0xfd, 0x28, 0xef, - 0x12, 0x07, 0xcf, 0x6d, 0x77, 0xf9, 0x77, 0x82, 0x42, 0x71, 0x69, 0x1c, - 0x38, 0x4c, 0x8e, 0x5b, 0xe5, 0xb1, 0xd4, 0x43, 0xdd, 0x03, 0xbb, 0x94, - 0x9d, 0xc9, 0x7b, 0xa1, 0xd7, 0x5e, 0xd6, 0xff, 0x06, 0xfd, 0x9e, 0x11, - 0x62, 0x7b, 0xa5, 0x5c, 0xec, 0x6f, 0xa5, 0xf7, 0x53, 0x8e, 0x88, 0x19, - 0xeb, 0xd4, 0x77, 0x4d, 0x0b, 0xe9, 0x55, 0xc0, 0xfd, 0x3d, 0x64, 0x9a, - 0x43, 0xc0, 0x1f, 0xac, 0x03, 0x1d, 0xa9, 0x53, 0x7e, 0x53, 0xfe, 0x55, - 0xfe, 0x84, 0xdf, 0x43, 0xf5, 0xc4, 0xd6, 0xd8, 0x51, 0x4f, 0x09, 0x5f, - 0xd7, 0x31, 0xab, 0xfa, 0x3d, 0xce, 0xef, 0x0c, 0x4b, 0xfe, 0x77, 0xc4, - 0x77, 0x61, 0x34, 0xd8, 0x9f, 0x99, 0x26, 0xe7, 0x7c, 0xc1, 0x7f, 0xe6, - 0xf7, 0x82, 0x43, 0x5c, 0xcc, 0xe1, 0xed, 0x06, 0x35, 0xff, 0x66, 0x7b, - 0xf7, 0x48, 0x3b, 0xba, 0x1f, 0xa4, 0xcf, 0xd3, 0xc9, 0x79, 0x58, 0xd9, - 0x2b, 0xcf, 0xd5, 0x71, 0x1c, 0x7b, 0x44, 0xd3, 0x16, 0xfc, 0xce, 0xe1, - 0x77, 0x23, 0x6f, 0xfc, 0x6e, 0xab, 0xf7, 0xa9, 0x1e, 0x47, 0xb9, 0x54, - 0x30, 0x96, 0x16, 0xe4, 0x92, 0x7d, 0x27, 0x2e, 0x7f, 0x43, 0x6c, 0x1f, - 0x25, 0xf2, 0xb0, 0x5f, 0xd4, 0x84, 0x6b, 0x9c, 0x14, 0xf7, 0x0e, 0x71, - 0x14, 0x79, 0xf1, 0xe1, 0x08, 0xe8, 0x07, 0xe2, 0x65, 0xc8, 0x29, 0x18, - 0xa0, 0xbe, 0xea, 0x29, 0x02, 0xcc, 0xf1, 0x04, 0xc7, 0x7b, 0xb1, 0x9d, - 0x7e, 0x87, 0x5d, 0x10, 0x3e, 0xfe, 0x9d, 0x8c, 0xf3, 0x17, 0x71, 0xed, - 0x34, 0xf9, 0xff, 0x51, 0xe3, 0x1c, 0xfd, 0x33, 0xc1, 0x7e, 0xe7, 0x78, - 0xf7, 0xa4, 0xc7, 0xbb, 0xc2, 0xa9, 0xd8, 0x6e, 0x19, 0xdf, 0xeb, 0x33, - 0xe3, 0x5b, 0xe9, 0x97, 0xda, 0x3f, 0x33, 0xe5, 0xe3, 0x1d, 0x75, 0xe9, - 0x89, 0xc5, 0x37, 0xe8, 0xd6, 0x4a, 0x79, 0x7f, 0x51, 0xc6, 0xbc, 0x9c, - 0x9e, 0x7f, 0xa8, 0x77, 0xd5, 0x7a, 0x3c, 0xfc, 0x07, 0xd7, 0x0d, 0x36, - 0x4f, 0xf0, 0x16, 0x00, 0x00, 0x00 }; + 0xad, 0x57, 0x4d, 0x68, 0x5c, 0x55, 0x14, 0xbe, 0x33, 0x6f, 0x7e, 0xde, + 0xcc, 0xbc, 0xc9, 0x4c, 0x93, 0x38, 0x99, 0x26, 0xc5, 0xa4, 0x09, 0x8d, + 0x4e, 0x9d, 0x69, 0x27, 0x3f, 0x44, 0xb0, 0x42, 0x43, 0x90, 0xb4, 0xb5, + 0x4a, 0xd3, 0x28, 0xc5, 0x5d, 0x92, 0xa9, 0x1d, 0x8c, 0x69, 0x23, 0x18, + 0x70, 0xe1, 0xc6, 0x47, 0x5a, 0xd3, 0xcd, 0x2c, 0x4c, 0x31, 0x3f, 0x8a, + 0xa0, 0xd8, 0x9d, 0xb8, 0x19, 0x50, 0xdb, 0x8a, 0x22, 0x14, 0x0c, 0x52, + 0x17, 0x45, 0xb0, 0x58, 0x37, 0x8a, 0x58, 0x1b, 0x1a, 0x11, 0x8d, 0x8b, + 0xae, 0x24, 0xe3, 0xbd, 0xe7, 0x3b, 0xf7, 0xcd, 0xbc, 0xc9, 0x8b, 0x89, + 0x62, 0x36, 0x27, 0xe7, 0xbe, 0x73, 0xcf, 0x39, 0xf7, 0x9c, 0xef, 0x7c, + 0xf7, 0x4e, 0x52, 0x08, 0x11, 0x10, 0x76, 0xb9, 0x5d, 0x4a, 0xe1, 0x33, + 0x0c, 0x53, 0x8a, 0x8a, 0x10, 0xc1, 0xb4, 0xd2, 0x85, 0x5f, 0xf0, 0xdf, + 0xfe, 0x24, 0x89, 0x6f, 0xcb, 0x96, 0x32, 0x13, 0x76, 0x46, 0xd9, 0x45, + 0xc4, 0xb3, 0xfe, 0x88, 0x94, 0x87, 0xc5, 0x68, 0x06, 0xf6, 0x01, 0xa1, + 0xa4, 0xb4, 0xb5, 0x95, 0xdc, 0xc5, 0xf2, 0x38, 0xcb, 0xc7, 0x7d, 0x90, + 0x87, 0x58, 0x3e, 0x56, 0x27, 0x05, 0xdb, 0x3d, 0xcd, 0xfa, 0x00, 0x4b, + 0x8b, 0xd7, 0x47, 0x59, 0xff, 0x90, 0xa5, 0xcd, 0xeb, 0x61, 0xd6, 0x1f, + 0xf0, 0xa9, 0x25, 0xe4, 0xab, 0xf4, 0xb5, 0x4a, 0x55, 0xb7, 0xe0, 0x3e, + 0x83, 0x73, 0x3c, 0xd3, 0xa1, 0xbe, 0xdf, 0xad, 0xb8, 0xed, 0xef, 0x38, + 0xfa, 0xac, 0xa1, 0xf4, 0x1f, 0xa5, 0xee, 0x53, 0x6a, 0x73, 0x0a, 0xdb, + 0x9b, 0xd3, 0x25, 0xb5, 0xdf, 0x10, 0xcb, 0xf3, 0x26, 0x55, 0x67, 0xd1, + 0x82, 0x6e, 0x97, 0x4d, 0xaa, 0xcb, 0xa2, 0xc5, 0xfe, 0x58, 0xee, 0x8e, + 0x23, 0xde, 0xa9, 0x0e, 0xd4, 0xed, 0xbb, 0x47, 0x60, 0x67, 0x27, 0x74, + 0x61, 0xf1, 0xbd, 0x5d, 0xf0, 0xf7, 0x29, 0xa5, 0xaf, 0xfb, 0x9a, 0x7c, + 0xa8, 0x47, 0x98, 0xad, 0xfc, 0x41, 0xb5, 0xbe, 0xb7, 0x7f, 0x71, 0x1e, + 0xf6, 0x63, 0x1d, 0x58, 0x7f, 0x30, 0xab, 0xfc, 0x85, 0x84, 0xcd, 0x52, + 0xe4, 0x28, 0x2f, 0x9f, 0x9d, 0x73, 0xfb, 0xff, 0x61, 0x1e, 0xda, 0x44, + 0x1c, 0x7e, 0xa3, 0x2e, 0xbf, 0xa9, 0x4d, 0x7e, 0x6f, 0x47, 0x6a, 0xfd, + 0x37, 0xf8, 0xe0, 0x3f, 0xba, 0xad, 0xff, 0x42, 0x1c, 0xb2, 0x29, 0xeb, + 0x15, 0x27, 0xb2, 0x4d, 0xfe, 0x2f, 0x6e, 0xeb, 0xff, 0x55, 0x27, 0x7f, + 0xbd, 0x5e, 0x5f, 0x3f, 0x52, 0x3f, 0xb0, 0x0f, 0xf2, 0xf6, 0xfd, 0xfa, + 0xdc, 0x9c, 0x9f, 0x01, 0x39, 0x98, 0x25, 0x51, 0x3a, 0xcd, 0x00, 0x1f, + 0xee, 0x56, 0x71, 0x1b, 0x45, 0xc0, 0xaf, 0xfc, 0x1d, 0x30, 0x43, 0xd7, + 0xb0, 0xfe, 0x1c, 0xf7, 0xe9, 0x79, 0x3e, 0xc8, 0x2f, 0x51, 0x55, 0x98, + 0x4a, 0xa5, 0x18, 0x63, 0xff, 0xdc, 0x67, 0x3b, 0x86, 0xfd, 0x2b, 0x96, + 0xca, 0xef, 0x86, 0xc4, 0x8d, 0x57, 0xdf, 0x8d, 0x7f, 0xe8, 0x3b, 0xf6, + 0xef, 0x7a, 0x08, 0x5f, 0xdf, 0x28, 0x42, 0x6f, 0xbb, 0x9c, 0xa4, 0xfa, + 0x2c, 0x97, 0xbd, 0x70, 0x52, 0xef, 0x5f, 0xce, 0x71, 0x02, 0x71, 0x44, + 0xa7, 0x49, 0xc9, 0xa1, 0xae, 0xd2, 0x26, 0xe7, 0x59, 0x27, 0xb1, 0xb8, + 0x4f, 0xcf, 0x05, 0xf4, 0x62, 0x88, 0x44, 0x7a, 0x62, 0x4e, 0x9d, 0x33, + 0x21, 0xc6, 0xfd, 0x2a, 0x61, 0x3f, 0xd7, 0xc5, 0x30, 0xad, 0x4f, 0x60, + 0xff, 0x45, 0xbb, 0x45, 0x67, 0x28, 0xf6, 0x61, 0x5f, 0x73, 0x2f, 0xe4, + 0x42, 0x6f, 0x50, 0x89, 0x6c, 0x71, 0x86, 0xd4, 0x03, 0x3f, 0xf7, 0x98, + 0x64, 0x67, 0xe7, 0xf4, 0xdc, 0xe9, 0xbe, 0xa9, 0x3a, 0xbd, 0x52, 0x9d, + 0xbf, 0x2e, 0xd4, 0xf5, 0xee, 0x3e, 0x65, 0x2f, 0x8b, 0xdb, 0x89, 0x38, + 0xa3, 0x93, 0x5e, 0x73, 0xfb, 0x92, 0x53, 0xdf, 0x9d, 0xf6, 0x7f, 0x90, + 0xea, 0x30, 0xc8, 0xf5, 0xe8, 0x60, 0x9c, 0xed, 0xf1, 0xc0, 0x59, 0x82, + 0xfe, 0x5f, 0x1b, 0x4a, 0x52, 0x3d, 0x4f, 0x60, 0xfd, 0xd2, 0xf0, 0x15, + 0xf4, 0xe3, 0x18, 0xd5, 0x41, 0x44, 0x2f, 0x7c, 0x8c, 0x5d, 0x13, 0x34, + 0xdf, 0xe7, 0xfa, 0x8b, 0x9f, 0x42, 0x2f, 0x18, 0x4a, 0x9f, 0xb2, 0x4e, + 0x5f, 0x85, 0x7d, 0xf0, 0x7c, 0x92, 0xea, 0x77, 0x82, 0xa3, 0x1c, 0x33, + 0x88, 0x4f, 0x4a, 0xa1, 0xf3, 0xa4, 0x5a, 0x2b, 0xf4, 0x3d, 0x29, 0x2e, + 0x96, 0xf1, 0x7d, 0x3a, 0xa6, 0xce, 0x37, 0xe2, 0xf0, 0xce, 0x64, 0x08, + 0xfb, 0x4b, 0xf3, 0xe0, 0x8d, 0x7b, 0x1f, 0x29, 0x7d, 0x2c, 0x7b, 0x0f, + 0xf6, 0xd9, 0xc9, 0x39, 0x76, 0xec, 0x47, 0xfd, 0xd6, 0xfc, 0xb0, 0x67, + 0x58, 0x46, 0x03, 0xd4, 0x3f, 0x9f, 0xb0, 0x86, 0x21, 0x5f, 0xa7, 0xef, + 0x7f, 0xf9, 0x4a, 0x54, 0xb7, 0x53, 0x0d, 0x81, 0x2b, 0xba, 0x3e, 0x2c, + 0x13, 0xfa, 0x5c, 0x90, 0x3b, 0xc5, 0xfd, 0x9c, 0xb5, 0x15, 0xde, 0xb9, + 0x8f, 0x99, 0xed, 0xf0, 0x0e, 0x39, 0xdc, 0x0d, 0x19, 0xea, 0x22, 0xbe, + 0xf8, 0x17, 0xb8, 0xe7, 0xbc, 0x36, 0xcd, 0x15, 0x56, 0xab, 0xf8, 0x24, + 0x21, 0x71, 0xe9, 0xc2, 0xa9, 0x9c, 0x03, 0xe2, 0x57, 0xd9, 0x07, 0x8d, + 0x37, 0xe5, 0x30, 0x2c, 0xa6, 0xd8, 0xef, 0x24, 0xd7, 0xe3, 0x2c, 0xd7, + 0xe3, 0x37, 0x96, 0xd3, 0x31, 0x5d, 0x07, 0xc8, 0x8b, 0x34, 0xff, 0x69, + 0x8f, 0x7b, 0x43, 0xdf, 0x0f, 0xe8, 0xcf, 0x32, 0xf7, 0xf3, 0x2d, 0xe7, + 0x9e, 0xd0, 0x75, 0xdd, 0xea, 0xbe, 0xd0, 0xf8, 0xc7, 0xfa, 0xe8, 0xa4, + 0xe7, 0x39, 0x4b, 0x5f, 0x76, 0xc2, 0x4d, 0x63, 0x17, 0xa4, 0x53, 0xdf, + 0x6e, 0x9a, 0xdf, 0x86, 0x96, 0xab, 0xfa, 0x7c, 0x2a, 0xcf, 0x5f, 0xf5, + 0xfc, 0x35, 0x2c, 0xcd, 0x92, 0x8c, 0x36, 0x5e, 0x56, 0xf1, 0x5a, 0x3d, + 0xf8, 0xc3, 0x3d, 0xc7, 0xf5, 0xf5, 0x9d, 0x8e, 0x13, 0xb1, 0xf6, 0xdf, + 0x5c, 0x75, 0xcf, 0x2b, 0xe6, 0x33, 0xec, 0xe0, 0xbb, 0x79, 0x80, 0xfb, + 0xc0, 0x32, 0xf5, 0xa8, 0xf2, 0x3b, 0xc2, 0x71, 0xf2, 0x1c, 0xc7, 0xaa, + 0xe1, 0x0b, 0x95, 0xe7, 0xfa, 0x86, 0xe6, 0x09, 0x8d, 0x8f, 0x2a, 0x5f, + 0xe8, 0x3e, 0x50, 0xfc, 0xec, 0xcd, 0x55, 0xb5, 0xbf, 0x6d, 0x1b, 0xfe, + 0x58, 0x75, 0xfc, 0xdd, 0x72, 0x78, 0x22, 0x49, 0x71, 0x0f, 0xb3, 0xea, + 0xe6, 0xc1, 0x3f, 0x24, 0x0f, 0xaa, 0xef, 0xa6, 0x69, 0x39, 0xf3, 0xc2, + 0xfc, 0x37, 0xa3, 0xe2, 0xa5, 0x39, 0xff, 0xb4, 0xbe, 0xbf, 0x64, 0xfe, + 0xcc, 0x93, 0x63, 0xb5, 0x7c, 0x77, 0xdb, 0x23, 0xee, 0x7f, 0xf5, 0xc7, + 0xf3, 0x95, 0x65, 0xbe, 0xcf, 0x51, 0x9e, 0x95, 0xf1, 0x3c, 0xe3, 0x25, + 0x57, 0xdf, 0x07, 0xf4, 0x15, 0xf6, 0xb2, 0xbf, 0x9a, 0xf7, 0xfa, 0xb4, + 0x7f, 0xa8, 0x76, 0x4f, 0xad, 0x7d, 0x7d, 0xff, 0x03, 0x5b, 0xf0, 0xf8, + 0xe7, 0x1b, 0x78, 0x7f, 0x7d, 0xb6, 0x51, 0x7d, 0x4f, 0x79, 0xe2, 0xc4, + 0x16, 0x74, 0x3f, 0x85, 0x25, 0x9e, 0xe9, 0xbd, 0x26, 0xb4, 0xbd, 0x3f, + 0x88, 0xf7, 0xa4, 0x60, 0xfc, 0x9e, 0x7b, 0x98, 0xfd, 0x64, 0xc0, 0xc7, + 0x2f, 0x9c, 0xa1, 0xfe, 0xbe, 0x79, 0xf6, 0x3e, 0xf1, 0xf2, 0x7b, 0x2f, + 0x5f, 0x53, 0x7e, 0x77, 0x8b, 0xd5, 0x19, 0x8b, 0xf2, 0x1a, 0xda, 0x0b, + 0xf3, 0xfb, 0x87, 0xea, 0xfb, 0xad, 0xfc, 0x9a, 0x8c, 0x07, 0x69, 0x37, + 0xe1, 0x7e, 0x97, 0x6c, 0xce, 0x13, 0x73, 0x7f, 0x24, 0x81, 0x7d, 0x9a, + 0xbf, 0xdc, 0xf8, 0x79, 0x77, 0xa3, 0x7a, 0xff, 0xc0, 0xcd, 0xad, 0x83, + 0xde, 0x73, 0x71, 0xb2, 0xaf, 0x36, 0x4e, 0x46, 0xac, 0x94, 0xe1, 0x7f, + 0x84, 0x79, 0x65, 0x9c, 0x13, 0xf9, 0x29, 0x9a, 0xa0, 0x78, 0x85, 0xe3, + 0x84, 0x6b, 0x91, 0x8a, 0xe1, 0xdc, 0x85, 0xa7, 0xf0, 0xbd, 0x10, 0xc7, + 0x7a, 0x6b, 0x1c, 0xef, 0xcd, 0x91, 0xb0, 0x45, 0xf6, 0xad, 0x71, 0xc8, + 0x14, 0xf3, 0xcf, 0x8a, 0xc3, 0xcb, 0x90, 0xcb, 0xa1, 0xad, 0x78, 0x19, + 0xf7, 0xdb, 0xf5, 0x90, 0x5a, 0x97, 0x8f, 0xa0, 0x0c, 0x78, 0x69, 0xa8, + 0xdb, 0xa2, 0xef, 0xa3, 0x19, 0xe0, 0x48, 0x74, 0x7a, 0x9f, 0xab, 0x0d, + 0xfc, 0xd2, 0x5a, 0xe5, 0xef, 0x5a, 0x9e, 0xb7, 0x7a, 0x97, 0x1c, 0x1e, + 0x75, 0xe7, 0x01, 0xfe, 0x52, 0xfe, 0x49, 0x95, 0x7c, 0xb5, 0x13, 0x7e, + 0x37, 0x18, 0x2f, 0xbf, 0xf3, 0xbd, 0xdf, 0x24, 0xbe, 0x2a, 0xa3, 0x0e, + 0x2b, 0xe5, 0xfa, 0xfe, 0xe8, 0x3c, 0x74, 0x1c, 0x9c, 0x4b, 0x9f, 0xb3, + 0x1a, 0x17, 0x79, 0x9d, 0xe1, 0xfc, 0xef, 0xd0, 0xfb, 0x2f, 0xc5, 0xe7, + 0x55, 0x7e, 0xb1, 0x7e, 0x94, 0xee, 0xa1, 0xa0, 0x7c, 0xdf, 0x6b, 0xdd, + 0x7d, 0x3f, 0x8c, 0x50, 0x5e, 0x8d, 0x72, 0x41, 0xef, 0x77, 0x9f, 0xbb, + 0x39, 0x0f, 0xb9, 0x90, 0xd7, 0x7d, 0xd3, 0xfd, 0xd5, 0xfd, 0x44, 0xdf, + 0x53, 0x3d, 0x64, 0xd6, 0x5f, 0xe8, 0x21, 0x9c, 0xe7, 0x0b, 0xeb, 0xee, + 0x77, 0xf2, 0xc9, 0xac, 0xb2, 0x7f, 0x4d, 0x7c, 0x43, 0xf3, 0x28, 0xc4, + 0xf7, 0x2c, 0xab, 0x7c, 0x29, 0xf8, 0xaf, 0x96, 0x77, 0x0d, 0x71, 0x3d, + 0xc8, 0xcb, 0x7d, 0x7a, 0xee, 0xdc, 0xf3, 0x5b, 0xad, 0xbb, 0x3a, 0xc7, + 0x13, 0x1e, 0xfc, 0xa4, 0xcf, 0xa9, 0xec, 0xf3, 0x8c, 0x5f, 0x53, 0x0c, + 0x1d, 0xc1, 0xfb, 0xb0, 0x21, 0x8c, 0x39, 0x69, 0x08, 0x7b, 0xdd, 0xef, + 0x12, 0x3f, 0x11, 0xfa, 0x05, 0xb3, 0xa7, 0x31, 0x42, 0xe7, 0xba, 0x74, + 0xe3, 0x6b, 0x32, 0x7b, 0x7f, 0x29, 0x86, 0xf5, 0x96, 0x21, 0x84, 0x09, + 0x10, 0xde, 0x0d, 0x71, 0x01, 0xf3, 0xf0, 0xce, 0x02, 0xe4, 0xdb, 0xe2, + 0x49, 0xf8, 0x69, 0x9c, 0xa5, 0xfb, 0xd4, 0x6c, 0x41, 0x79, 0x4b, 0x4b, + 0x8c, 0xf3, 0xb4, 0x9f, 0x7e, 0xaf, 0x56, 0x44, 0x9c, 0x7f, 0x47, 0xf0, + 0xbc, 0x02, 0xcf, 0x81, 0x9a, 0xbe, 0xef, 0x14, 0xdf, 0x4a, 0x8f, 0x4b, + 0xfc, 0xc2, 0x0d, 0xe3, 0xdc, 0xac, 0xc7, 0xb9, 0xee, 0x6f, 0xda, 0xef, + 0x89, 0xeb, 0x81, 0xcd, 0xb8, 0xd6, 0xf9, 0xa9, 0x3a, 0xff, 0xe9, 0xbc, + 0x7b, 0x37, 0xfb, 0x57, 0xfb, 0x62, 0x12, 0xdf, 0xff, 0x17, 0xae, 0x21, + 0x8f, 0x76, 0xa9, 0xf8, 0x2d, 0x35, 0xf8, 0xf4, 0x9e, 0x3b, 0xf0, 0x9b, + 0x21, 0x79, 0xfc, 0x6f, 0x6a, 0x8c, 0x09, 0xd0, 0x18, 0x10, 0x00, 0x00, + 0x00 }; static u8 bnx2_TPAT_b09FwText[] = { - 0xbd, 0x58, 0x5d, 0x6c, 0x1c, 0x57, 0x15, 0x3e, 0x73, 0xe7, 0xee, 0x7a, - 0x6d, 0x39, 0xf1, 0xb8, 0x99, 0x96, 0x4d, 0x63, 0xd4, 0x99, 0x78, 0xfc, - 0x43, 0x6d, 0x95, 0x69, 0x59, 0x15, 0x17, 0x56, 0x68, 0xba, 0xbb, 0x71, - 0xad, 0xaa, 0xaa, 0x5c, 0x29, 0x88, 0x4a, 0x8d, 0x90, 0x59, 0x37, 0x6d, - 0x79, 0x4b, 0x11, 0x0f, 0x48, 0x45, 0xca, 0xb2, 0x76, 0xd2, 0x08, 0x2d, - 0x99, 0xd6, 0x85, 0x44, 0x42, 0x7d, 0x88, 0x9c, 0x3a, 0xee, 0xc3, 0xca, - 0x9b, 0x8a, 0x07, 0x24, 0xa4, 0xa8, 0x55, 0x80, 0xc0, 0x1b, 0x7d, 0xa8, - 0xf8, 0x79, 0x22, 0x12, 0x0f, 0x54, 0x08, 0x90, 0x85, 0x04, 0x2a, 0xa5, - 0xe4, 0xf2, 0x7d, 0x77, 0x67, 0x92, 0xc5, 0x4d, 0x41, 0xe5, 0x81, 0x95, - 0x56, 0x77, 0xe6, 0xde, 0x73, 0xce, 0x3d, 0xf7, 0xfc, 0x7c, 0xe7, 0xdc, - 0x39, 0xec, 0xc8, 0x88, 0x64, 0xbf, 0x7d, 0xf8, 0x57, 0xbe, 0x72, 0xe2, - 0xeb, 0x0f, 0xdc, 0x57, 0xb9, 0x0f, 0x8f, 0x0f, 0x3a, 0x77, 0x6b, 0x2d, - 0xff, 0xc7, 0x9f, 0x2b, 0xe2, 0xe5, 0x7a, 0xf0, 0x2f, 0x25, 0x55, 0x4d, - 0x0e, 0xd6, 0x22, 0x29, 0xb9, 0xd5, 0xea, 0xfc, 0x6a, 0x24, 0x92, 0x74, - 0xe7, 0x82, 0xba, 0xfc, 0xd3, 0xb4, 0x7c, 0x2d, 0x9c, 0xff, 0x64, 0xf5, - 0x83, 0x4f, 0x5f, 0xf9, 0x6c, 0xb8, 0x7b, 0xc1, 0x95, 0x92, 0x57, 0x3d, - 0xa3, 0xbd, 0x69, 0x29, 0x4d, 0x80, 0xe7, 0xd5, 0x99, 0x6f, 0x17, 0x64, - 0x7f, 0x2e, 0xab, 0x65, 0x54, 0x74, 0xdd, 0x5c, 0x99, 0x89, 0xbc, 0x36, - 0x36, 0xb8, 0xdc, 0x0b, 0xa4, 0xd6, 0x2b, 0xcb, 0x9b, 0x3d, 0x5f, 0xde, - 0xe8, 0x69, 0x39, 0xfe, 0xca, 0x49, 0x59, 0x8f, 0xc3, 0x72, 0xc3, 0x2d, - 0x89, 0xaa, 0x86, 0xe5, 0xa6, 0x04, 0xb2, 0x15, 0x87, 0xad, 0x15, 0x77, - 0xdc, 0x29, 0x55, 0x4b, 0xf2, 0xc2, 0x8c, 0x92, 0x0b, 0xfe, 0x31, 0x79, - 0x26, 0x7a, 0x12, 0x7f, 0x2d, 0x6a, 0x43, 0x3b, 0xf5, 0xf3, 0x5a, 0xf4, - 0xc6, 0x98, 0x3c, 0x12, 0x1b, 0xb3, 0x1a, 0x27, 0xe0, 0x9f, 0x9c, 0x7d, - 0x56, 0x86, 0xa5, 0xe5, 0x85, 0x4b, 0x22, 0x05, 0xd2, 0x48, 0x2d, 0x2e, - 0x48, 0xe2, 0xf5, 0xcf, 0x75, 0xc1, 0x8e, 0x1f, 0x98, 0x2d, 0xf0, 0x0f, - 0x47, 0xf9, 0xfa, 0x1d, 0xd9, 0xba, 0x97, 0xad, 0x2b, 0x51, 0xe7, 0xc2, - 0x60, 0x5b, 0xa6, 0x12, 0xed, 0xdc, 0x30, 0xb5, 0xe8, 0x2e, 0xaf, 0xb6, - 0xad, 0xc5, 0xdd, 0xa0, 0xfe, 0x91, 0x57, 0x17, 0x03, 0x1e, 0x97, 0x3c, - 0x5a, 0x55, 0xbf, 0x06, 0xbf, 0x4d, 0x25, 0xca, 0x11, 0xb9, 0xda, 0x29, - 0x7b, 0xb5, 0xde, 0x37, 0x9c, 0x5a, 0x7a, 0xc3, 0x24, 0x7a, 0x44, 0x54, - 0x94, 0x38, 0xb5, 0x6d, 0xca, 0x1a, 0x16, 0x1d, 0x0d, 0x81, 0x67, 0xd2, - 0x53, 0xc2, 0xb1, 0x96, 0xcd, 0x53, 0x76, 0x03, 0xcf, 0x8b, 0x4e, 0xb2, - 0xad, 0x9d, 0xda, 0xf9, 0x25, 0x3c, 0x97, 0xc0, 0x0f, 0xbb, 0xc4, 0x8e, - 0x24, 0xcb, 0x0e, 0xf8, 0x78, 0x4e, 0x0f, 0xef, 0x4a, 0x12, 0xdf, 0x93, - 0xb5, 0x4a, 0x58, 0x6e, 0xc9, 0xa3, 0x4e, 0x7d, 0xfb, 0x43, 0x4e, 0xf3, - 0x96, 0x7a, 0x1f, 0x9e, 0xa3, 0x2e, 0x0f, 0x6b, 0x63, 0xd4, 0xfd, 0x43, - 0xd9, 0x19, 0x29, 0x2f, 0xe9, 0xeb, 0xef, 0xf3, 0x1d, 0x3a, 0xa7, 0xd0, - 0xbd, 0x5b, 0x84, 0x3e, 0xc6, 0x70, 0x9f, 0x5a, 0x54, 0x87, 0x9e, 0x09, - 0xfe, 0xe1, 0x99, 0x26, 0x42, 0xe1, 0xf0, 0xb9, 0x7d, 0x12, 0x8c, 0x1b, - 0xd3, 0x88, 0x43, 0x6f, 0x5b, 0x26, 0x64, 0x2d, 0x9d, 0xf0, 0x8e, 0xa4, - 0x6d, 0xac, 0xb7, 0x48, 0x03, 0x7b, 0x88, 0x1c, 0xe9, 0x1a, 0x73, 0x29, - 0x3e, 0x50, 0x94, 0xfd, 0x6a, 0xbe, 0x20, 0x61, 0x90, 0x60, 0xee, 0xf0, - 0xa5, 0xbd, 0x36, 0xbb, 0x27, 0xd3, 0x81, 0x76, 0xc7, 0x3e, 0xf1, 0xa1, - 0xec, 0x7d, 0xd4, 0xab, 0x9d, 0xcf, 0xed, 0x6c, 0xf5, 0x86, 0x5d, 0x63, - 0xa9, 0x55, 0xa0, 0xff, 0x47, 0x9e, 0x29, 0xe7, 0xa3, 0x2e, 0xd4, 0x1b, - 0xf4, 0xd1, 0x2d, 0x9d, 0x9e, 0xfa, 0x90, 0x4e, 0xd4, 0x47, 0x89, 0x3e, - 0x57, 0x92, 0xf5, 0xe8, 0x71, 0x25, 0xfb, 0x8d, 0x59, 0x8f, 0xb5, 0xd3, - 0x38, 0x7f, 0x2c, 0x7b, 0x46, 0x1c, 0xa6, 0x88, 0xc3, 0x14, 0x71, 0x99, - 0x8a, 0xa7, 0xaa, 0x81, 0x5c, 0x99, 0x29, 0xc9, 0x75, 0x17, 0xfe, 0xec, - 0xcd, 0x79, 0xaf, 0x21, 0xa6, 0x12, 0xcf, 0x11, 0x37, 0x4a, 0x66, 0x0b, - 0xc2, 0x77, 0xc4, 0x92, 0x4e, 0xca, 0x2e, 0x62, 0x29, 0x39, 0xca, 0xb9, - 0x21, 0x59, 0xb1, 0x67, 0x99, 0xf3, 0x4e, 0x09, 0x7d, 0x55, 0xc3, 0xda, - 0x64, 0x70, 0x4a, 0x76, 0x11, 0x1f, 0x35, 0xac, 0x53, 0x56, 0xe8, 0xb5, - 0x40, 0xd1, 0x4e, 0xdf, 0x45, 0x0e, 0xf8, 0x88, 0xfb, 0x99, 0xb2, 0x12, - 0x47, 0x56, 0xe7, 0x61, 0x8b, 0xf9, 0x29, 0xd8, 0x88, 0x39, 0xc1, 0xb8, - 0xfa, 0xeb, 0xb4, 0x8e, 0x4e, 0x22, 0x7e, 0x40, 0x8b, 0xf3, 0x9f, 0x4a, - 0x67, 0xc0, 0x1f, 0x15, 0xa9, 0xe7, 0x56, 0xac, 0x65, 0x3d, 0xbd, 0xa2, - 0x0a, 0xd1, 0xef, 0x1d, 0xd9, 0x1f, 0xb6, 0x12, 0x09, 0x5b, 0x4a, 0x29, - 0x9f, 0x5b, 0xbf, 0x84, 0x3c, 0x7a, 0xd3, 0xea, 0xaf, 0xc1, 0x57, 0xce, - 0xf4, 0xa7, 0xdd, 0x45, 0x36, 0x3b, 0x61, 0xbc, 0x08, 0xdd, 0xae, 0xc2, - 0xff, 0xb4, 0xf9, 0xa5, 0x2e, 0x64, 0x77, 0x1c, 0xe6, 0xae, 0xb4, 0xbb, - 0xa4, 0xb3, 0x69, 0xbe, 0xa2, 0xab, 0xb2, 0xdc, 0xee, 0x9c, 0x34, 0x6e, - 0x24, 0x2b, 0x85, 0x2a, 0xfd, 0x36, 0xba, 0x00, 0x3f, 0x2c, 0xb7, 0xbb, - 0x13, 0x8f, 0x6d, 0x76, 0xa4, 0x75, 0x77, 0x55, 0x5a, 0x6e, 0x45, 0xdd, - 0xa5, 0x64, 0x0c, 0x72, 0xab, 0xd8, 0x87, 0x71, 0x15, 0x06, 0x75, 0x77, - 0xe2, 0xb1, 0x8b, 0x9d, 0x7b, 0x90, 0xb7, 0xf2, 0x41, 0xad, 0x12, 0x21, - 0x77, 0xaf, 0x1e, 0x74, 0x25, 0x92, 0xb5, 0x5e, 0x49, 0x6a, 0xe9, 0x84, - 0xac, 0xf7, 0x24, 0x79, 0x6a, 0x06, 0xfb, 0x55, 0xf0, 0xde, 0x9b, 0x97, - 0x56, 0x6f, 0x62, 0x45, 0x55, 0x5b, 0x92, 0xf4, 0xd6, 0xf1, 0x2f, 0x49, - 0xa3, 0x53, 0x2a, 0x5d, 0xec, 0xb4, 0xc8, 0x5f, 0x72, 0xaa, 0x81, 0x3e, - 0xdc, 0xdd, 0x65, 0xdc, 0x40, 0xce, 0xf0, 0x97, 0x54, 0x55, 0x4b, 0xd3, - 0xf7, 0x21, 0xc3, 0x81, 0x4d, 0xa8, 0xeb, 0x2c, 0xf6, 0xed, 0x8f, 0xad, - 0x1e, 0x7d, 0x37, 0x24, 0xed, 0x78, 0x1e, 0x76, 0x62, 0xd4, 0x0e, 0xc9, - 0x5a, 0xf4, 0x9e, 0x79, 0x1a, 0xb1, 0xfa, 0x9a, 0x98, 0x7b, 0x6a, 0xc0, - 0x93, 0x1a, 0x4c, 0xfa, 0x42, 0x54, 0x96, 0x53, 0xd8, 0xb7, 0xcf, 0xb7, - 0x0e, 0x1d, 0xc8, 0x37, 0x06, 0xbe, 0x06, 0xf8, 0x7c, 0x39, 0x6d, 0x79, - 0xc7, 0xc0, 0xbb, 0x9b, 0xf1, 0xce, 0x95, 0x17, 0x25, 0x06, 0xcf, 0x64, - 0xb0, 0x08, 0x7f, 0xae, 0xf8, 0x0d, 0xf0, 0x36, 0xa0, 0x03, 0xc6, 0x54, - 0x5a, 0xba, 0x42, 0xb9, 0x61, 0xf9, 0x69, 0xe6, 0x83, 0x95, 0xd9, 0x82, - 0x4c, 0xe8, 0x95, 0x96, 0x20, 0x67, 0x01, 0xe3, 0x3b, 0xa6, 0x9d, 0x02, - 0x77, 0x7c, 0x3e, 0xbf, 0x69, 0x54, 0x15, 0x31, 0x5a, 0x89, 0x82, 0xb6, - 0xf0, 0xbd, 0x28, 0x75, 0xe4, 0x99, 0x8a, 0xc6, 0xa4, 0xe9, 0x39, 0x8e, - 0xaa, 0xba, 0xd2, 0x44, 0x84, 0x26, 0xcb, 0xda, 0xce, 0xad, 0x20, 0xce, - 0x54, 0xf5, 0x7b, 0xaa, 0x5f, 0x0f, 0x0a, 0xa0, 0x41, 0x6e, 0x46, 0xa3, - 0xb0, 0xc1, 0x38, 0x68, 0xcf, 0x62, 0x7e, 0x0a, 0xf8, 0x39, 0x0e, 0x1a, - 0x8e, 0xcc, 0x11, 0xda, 0x85, 0xf4, 0x15, 0xe8, 0x98, 0xcf, 0x55, 0x60, - 0x9b, 0xc1, 0xb4, 0xc9, 0x7d, 0x0c, 0x9a, 0x54, 0x67, 0x79, 0x37, 0x98, - 0x4b, 0xf9, 0x7a, 0x80, 0xf5, 0xab, 0x9f, 0x52, 0xb2, 0x6b, 0x2e, 0x46, - 0x8c, 0x61, 0x79, 0xaf, 0x11, 0x25, 0xe3, 0xae, 0xcd, 0xf3, 0x3c, 0xdf, - 0x39, 0xb2, 0x16, 0x9c, 0x39, 0xb8, 0x1a, 0x39, 0xee, 0xfa, 0xfc, 0x01, - 0x69, 0xf9, 0x61, 0x5c, 0x87, 0xbf, 0xd7, 0x53, 0xe6, 0xc6, 0x18, 0xce, - 0x1d, 0x22, 0xea, 0x26, 0xf1, 0x9c, 0x1c, 0x04, 0x0f, 0xfc, 0xd8, 0x82, - 0x2c, 0x8e, 0x88, 0x99, 0x34, 0x84, 0x8e, 0xb0, 0x47, 0x34, 0xe7, 0x1d, - 0x61, 0x3c, 0xfa, 0x5c, 0x63, 0x8d, 0x79, 0xf5, 0x50, 0x2d, 0x0a, 0xe3, - 0x66, 0x96, 0x2b, 0x6f, 0xc1, 0xb6, 0xed, 0x94, 0xf5, 0x22, 0xaf, 0x11, - 0xcc, 0x0f, 0xc6, 0x4a, 0x8e, 0xb1, 0xe0, 0x89, 0x98, 0x9f, 0xa5, 0x0c, - 0x6b, 0x6b, 0x19, 0x8e, 0x2e, 0x40, 0x0f, 0x63, 0x9e, 0x00, 0x86, 0xb6, - 0x63, 0x1b, 0x9f, 0xad, 0x40, 0xdd, 0x30, 0x93, 0xd3, 0xb4, 0xb9, 0x31, - 0x27, 0xe2, 0x45, 0xd0, 0xfe, 0x16, 0xf6, 0x5a, 0x02, 0x8e, 0x12, 0x7b, - 0xb9, 0x77, 0x55, 0xd7, 0x3a, 0xfb, 0xa0, 0x4b, 0x00, 0x7c, 0x83, 0x0d, - 0x2c, 0xde, 0x0e, 0x23, 0xdf, 0x99, 0xf3, 0x61, 0xb0, 0x22, 0x9c, 0x97, - 0x61, 0x85, 0xf7, 0x26, 0xfc, 0xb4, 0x5e, 0x79, 0xd4, 0x69, 0x6c, 0xbf, - 0x9f, 0xf9, 0x48, 0xc6, 0x14, 0x6a, 0x49, 0xd3, 0x27, 0x5f, 0x11, 0x7c, - 0xfb, 0xc0, 0xf3, 0x77, 0xac, 0x15, 0x30, 0x0e, 0xca, 0xb1, 0xb8, 0x8d, - 0xbd, 0x02, 0xec, 0xb5, 0x24, 0xba, 0xfa, 0x3c, 0xb0, 0x67, 0x2a, 0x68, - 0xc8, 0xf7, 0x55, 0xbf, 0x46, 0xd2, 0x37, 0x5f, 0x18, 0xf0, 0x4d, 0x20, - 0xae, 0xcd, 0xc1, 0x87, 0xb2, 0x98, 0x22, 0x66, 0x3e, 0x98, 0xad, 0xfb, - 0xc0, 0xbe, 0xcf, 0x64, 0x18, 0x5e, 0x22, 0x0e, 0xca, 0x19, 0x8b, 0x83, - 0x45, 0xe2, 0x20, 0x70, 0xa5, 0xb5, 0x00, 0x7b, 0xc7, 0xef, 0x02, 0x5f, - 0xea, 0xf0, 0xc4, 0x4f, 0x3a, 0x1a, 0x71, 0xe5, 0x82, 0x9f, 0x75, 0xf8, - 0xf3, 0xae, 0x8c, 0x84, 0xde, 0xbb, 0xc0, 0x9b, 0xe4, 0x28, 0xf3, 0xc0, - 0x18, 0xe4, 0x3a, 0xb0, 0x6a, 0xba, 0x7c, 0x0a, 0x71, 0xef, 0x02, 0x27, - 0xb4, 0x70, 0xdf, 0xbc, 0x6e, 0xe6, 0xf5, 0x9b, 0xbf, 0xb7, 0x1d, 0xb8, - 0x19, 0xb5, 0xee, 0x73, 0x90, 0x31, 0x15, 0x1c, 0x81, 0x1f, 0xd7, 0x16, - 0xfe, 0x1b, 0xcf, 0x6f, 0x32, 0x1e, 0xd4, 0x90, 0x0a, 0xf7, 0x15, 0x69, - 0x74, 0x69, 0x87, 0x18, 0x76, 0xb0, 0x18, 0x84, 0x9c, 0x8f, 0x91, 0xf3, - 0x22, 0x4d, 0x62, 0x05, 0x30, 0x8c, 0xb8, 0xb7, 0x06, 0x7a, 0x55, 0x19, - 0x82, 0x5d, 0x11, 0x4b, 0x4a, 0x4a, 0xba, 0x7a, 0x54, 0xaf, 0x83, 0xb6, - 0x50, 0x5d, 0xd6, 0x5b, 0xd1, 0x31, 0x37, 0xef, 0x97, 0xda, 0x1d, 0x71, - 0x6a, 0x7d, 0x3f, 0x67, 0x74, 0x8f, 0x65, 0x74, 0x4b, 0x83, 0x74, 0x98, - 0x6f, 0x64, 0xf3, 0x09, 0xe6, 0x3f, 0x91, 0xd9, 0x9c, 0xb5, 0xa0, 0x84, - 0x3a, 0xcb, 0x3a, 0x10, 0x06, 0x81, 0xfa, 0x4f, 0x75, 0x60, 0x61, 0x00, - 0xbb, 0x45, 0xd9, 0xbe, 0xc2, 0x67, 0x4c, 0x0e, 0x9e, 0x75, 0x58, 0x49, - 0x74, 0x33, 0x3e, 0xf1, 0xdb, 0xcc, 0xf6, 0x21, 0x2d, 0xf1, 0x7a, 0x90, - 0x16, 0x69, 0x04, 0xbb, 0xa8, 0xb3, 0xb7, 0xb3, 0xd9, 0x01, 0xac, 0x21, - 0xe7, 0x53, 0x57, 0x1e, 0xd6, 0xcc, 0xef, 0x7b, 0xb5, 0x3d, 0xc7, 0x0e, - 0xe8, 0x77, 0x26, 0x2c, 0xce, 0x2c, 0x75, 0x86, 0x20, 0x7e, 0x54, 0x8e, - 0x23, 0x9f, 0x9f, 0x86, 0xef, 0x2f, 0xc6, 0x0a, 0xdd, 0x02, 0x6b, 0x8e, - 0x41, 0x1c, 0x86, 0xd6, 0x17, 0xb5, 0x68, 0x0d, 0x91, 0xfc, 0x2d, 0xb9, - 0x3a, 0x3f, 0x22, 0x85, 0x4b, 0xd4, 0x01, 0xfd, 0xd2, 0xe6, 0xe0, 0x3e, - 0x73, 0xd8, 0x67, 0x02, 0x18, 0x78, 0x3f, 0xea, 0x8b, 0x2f, 0x7a, 0x1a, - 0x58, 0x9b, 0x96, 0x9c, 0x3a, 0xe4, 0xab, 0x4b, 0x3c, 0x3f, 0x31, 0xb8, - 0x94, 0xd5, 0x36, 0xe6, 0xd6, 0x10, 0x6a, 0xfa, 0x1f, 0x91, 0xbb, 0x4a, - 0x56, 0x2b, 0xc6, 0x1c, 0x89, 0x7f, 0x00, 0xfb, 0x62, 0x6e, 0x93, 0x6b, - 0xbb, 0x98, 0xe7, 0x1c, 0x65, 0x30, 0x16, 0x0f, 0xa0, 0xae, 0x61, 0xcf, - 0xa3, 0xe4, 0x19, 0x42, 0xcd, 0x27, 0xfe, 0x63, 0xdc, 0xe4, 0x3b, 0xcf, - 0x44, 0x6c, 0x73, 0x31, 0x8e, 0x60, 0xe4, 0x99, 0x7e, 0x91, 0xf9, 0x8a, - 0xcf, 0xc6, 0xe8, 0xea, 0xa8, 0xd4, 0x3b, 0x11, 0x30, 0x76, 0xaa, 0x7c, - 0x5c, 0xb8, 0x86, 0xf7, 0x2e, 0xe7, 0xbd, 0x81, 0x79, 0x3c, 0x77, 0xad, - 0xce, 0xa8, 0xed, 0x79, 0xff, 0xb2, 0x06, 0xc3, 0xa2, 0xc7, 0xd8, 0x64, - 0xaf, 0xc2, 0xfa, 0x67, 0x71, 0x6b, 0x96, 0x7d, 0xca, 0xeb, 0x1d, 0xd6, - 0x42, 0xcd, 0xbc, 0x44, 0x00, 0x1c, 0x92, 0xba, 0x9f, 0x9f, 0x0b, 0x71, - 0x1c, 0x53, 0x36, 0x65, 0x4c, 0xc2, 0x76, 0xec, 0x47, 0xa2, 0xb2, 0x76, - 0xa6, 0x92, 0x26, 0xf9, 0xba, 0x05, 0x29, 0x6c, 0xcc, 0x8b, 0x7b, 0xd6, - 0xc8, 0x66, 0x5f, 0x9e, 0xb7, 0x2c, 0xbe, 0xd4, 0x5e, 0xa2, 0x1e, 0x98, - 0xdf, 0x61, 0x3d, 0x0c, 0x81, 0x67, 0xc5, 0x6c, 0xdf, 0xb2, 0x34, 0x3b, - 0x91, 0xd7, 0x10, 0x8c, 0xdd, 0x3b, 0xe0, 0xbb, 0x22, 0xce, 0xac, 0xe5, - 0x62, 0xa7, 0xbf, 0x17, 0x73, 0xee, 0xb9, 0xb8, 0xbf, 0x57, 0x43, 0x7e, - 0x89, 0xbd, 0xc4, 0x57, 0xc2, 0x3e, 0x12, 0x7d, 0xe3, 0x39, 0x8d, 0xfd, - 0x68, 0xa3, 0x02, 0x7a, 0xdb, 0xd9, 0xec, 0x3c, 0x21, 0xe8, 0x34, 0x6c, - 0x4e, 0x5b, 0x73, 0x0f, 0xc6, 0xe2, 0x3f, 0x0c, 0xf1, 0x05, 0x75, 0x05, - 0xfa, 0xe2, 0xbd, 0xc7, 0x3d, 0x26, 0xe4, 0xc5, 0xd4, 0x62, 0xad, 0x77, - 0x02, 0x98, 0xd5, 0xe8, 0xfc, 0x2d, 0xaf, 0x3d, 0x49, 0x1b, 0xf8, 0xfb, - 0xac, 0x8c, 0x8a, 0xde, 0x19, 0x95, 0xe7, 0xd0, 0xef, 0x15, 0x36, 0x50, - 0xe7, 0x61, 0x63, 0x75, 0xb6, 0x35, 0xcb, 0x9e, 0xed, 0x32, 0x72, 0x79, - 0xb5, 0x12, 0xc5, 0xae, 0x33, 0x2d, 0x67, 0xbe, 0x1b, 0xce, 0x6e, 0xdb, - 0x7c, 0xc6, 0xfa, 0x4e, 0x20, 0xa7, 0xbb, 0x91, 0x9c, 0xe9, 0x7a, 0xd0, - 0xcb, 0xbb, 0xd5, 0xd7, 0x46, 0xc4, 0xdb, 0x06, 0xfe, 0xc4, 0x53, 0x9e, - 0x0b, 0x3e, 0xa8, 0xd2, 0x6e, 0xec, 0x63, 0xe9, 0x5f, 0xe2, 0xdb, 0xa3, - 0x78, 0x1e, 0x11, 0xf7, 0x1c, 0xfb, 0x4e, 0xc6, 0x24, 0xfd, 0x33, 0xd8, - 0x0b, 0x13, 0xfb, 0x20, 0x73, 0x87, 0xb9, 0x9f, 0xe7, 0x66, 0x9e, 0xab, - 0xc4, 0x01, 0xed, 0x2c, 0xc2, 0x5e, 0xd7, 0x62, 0xe6, 0xeb, 0x0d, 0x73, - 0xcd, 0xf6, 0x6e, 0x1e, 0xfb, 0xe2, 0x81, 0xde, 0x2d, 0xef, 0x7b, 0x18, - 0xaf, 0xe5, 0x81, 0x7c, 0xbd, 0x6e, 0x73, 0xf5, 0x0d, 0xe4, 0xed, 0xcb, - 0x69, 0xd9, 0xe6, 0xec, 0xe1, 0x07, 0x6e, 0x97, 0xb3, 0x97, 0x3f, 0x46, - 0xce, 0xfe, 0x30, 0xcb, 0xd9, 0xa2, 0x8d, 0x6b, 0xb5, 0x31, 0xb8, 0xf6, - 0x23, 0xac, 0x0d, 0x65, 0x77, 0x0a, 0x6d, 0x3b, 0xe8, 0xc3, 0x0f, 0xd2, - 0x47, 0xb9, 0x7f, 0xfa, 0x71, 0x5a, 0xd7, 0xa4, 0x81, 0x0f, 0x37, 0x46, - 0x11, 0x4f, 0xcc, 0xe9, 0x3c, 0x9e, 0x02, 0xc4, 0x72, 0xce, 0x8f, 0x7e, - 0xf3, 0x28, 0x63, 0xa1, 0x60, 0xf3, 0xc6, 0xad, 0xe6, 0x34, 0x65, 0x59, - 0x44, 0x2f, 0xf7, 0x63, 0x8e, 0xdd, 0x7e, 0xac, 0x14, 0x37, 0x4a, 0xf2, - 0xfc, 0x0c, 0xb1, 0x2b, 0x8c, 0xaf, 0x42, 0xe7, 0x6b, 0x91, 0x2f, 0x85, - 0x69, 0xe6, 0x33, 0xab, 0x51, 0x11, 0x31, 0x84, 0xbb, 0x55, 0x6a, 0x4e, - 0xa2, 0xdf, 0x0a, 0x34, 0xfc, 0xfc, 0x32, 0xe2, 0x88, 0xd8, 0x8a, 0x98, - 0x98, 0xdd, 0x44, 0x4c, 0x1c, 0xe7, 0xbb, 0xdd, 0xb7, 0x60, 0x69, 0x5d, - 0xbb, 0xbf, 0x0f, 0xfd, 0x4b, 0x32, 0x74, 0xce, 0xe0, 0x4e, 0x75, 0x8b, - 0xef, 0xb4, 0x8d, 0x5f, 0x60, 0x09, 0xe6, 0x57, 0x6d, 0xfc, 0xd2, 0xa7, - 0x8c, 0x7b, 0x63, 0x7e, 0x67, 0xf3, 0xe6, 0xd7, 0x16, 0x03, 0xae, 0xc5, - 0x36, 0x9e, 0x63, 0xf6, 0x9b, 0xa7, 0xbb, 0x3f, 0xd7, 0x16, 0x23, 0x36, - 0x8c, 0x9c, 0x8a, 0x6d, 0xac, 0xcd, 0xbe, 0x81, 0x63, 0xbf, 0xd6, 0xcf, - 0x85, 0x01, 0x39, 0x93, 0xde, 0x23, 0x90, 0x83, 0x9a, 0x17, 0xac, 0xb1, - 0x3f, 0x88, 0xa7, 0xd0, 0x2f, 0x81, 0xae, 0xbb, 0x17, 0x2f, 0xc6, 0x31, - 0xd2, 0xde, 0x7f, 0x80, 0x5c, 0x0f, 0x36, 0xa4, 0x1c, 0xea, 0x4d, 0xbd, - 0x46, 0x25, 0x3a, 0x9b, 0xeb, 0xf4, 0x17, 0xab, 0xcb, 0xbf, 0xcb, 0xc3, - 0xfa, 0xce, 0xed, 0xf8, 0xbc, 0x01, 0xbe, 0x3f, 0xdf, 0x86, 0x0f, 0xeb, - 0x3b, 0xe4, 0x19, 0xb9, 0xd9, 0x6b, 0xd4, 0x6f, 0xc6, 0x75, 0x82, 0xb8, - 0x27, 0xef, 0xde, 0xbb, 0xdc, 0x60, 0x0e, 0xe4, 0x35, 0x9e, 0x71, 0xce, - 0x3d, 0xf3, 0x58, 0xcf, 0x63, 0x3c, 0x8f, 0xf9, 0x3c, 0xd6, 0xc3, 0xf8, - 0x19, 0xe9, 0xfb, 0x57, 0x6f, 0x84, 0xd8, 0x7f, 0xe4, 0x7f, 0xb8, 0xb7, - 0x10, 0x23, 0x24, 0xb9, 0x75, 0xd7, 0xfb, 0x69, 0xd6, 0xaf, 0x94, 0x98, - 0x6b, 0xf8, 0xb3, 0x8f, 0xdf, 0x45, 0x7f, 0x10, 0x67, 0xb6, 0x4d, 0xb2, - 0xb1, 0x4f, 0xd3, 0xef, 0x07, 0xbf, 0x9a, 0x61, 0xf2, 0x17, 0xfb, 0xf5, - 0x47, 0xf2, 0x9c, 0x62, 0x0e, 0xd9, 0x9c, 0xe2, 0x79, 0x70, 0x0f, 0x37, - 0x66, 0x19, 0x7e, 0x7c, 0x3e, 0xce, 0xf3, 0x08, 0xf1, 0xf4, 0x40, 0x9e, - 0xe3, 0xb0, 0x53, 0x74, 0xc3, 0xe8, 0xe9, 0x04, 0x36, 0xe3, 0xdd, 0xb7, - 0x81, 0xde, 0x89, 0x76, 0x5a, 0x72, 0x9e, 0xb8, 0x79, 0xdf, 0xdd, 0xdb, - 0x27, 0xd1, 0x6e, 0xb4, 0xeb, 0xa0, 0xdd, 0xc2, 0x78, 0x5c, 0x11, 0x03, - 0x6e, 0x87, 0x13, 0x79, 0x3d, 0x07, 0x06, 0x4d, 0xe7, 0x76, 0xfa, 0xd8, - 0x35, 0x3d, 0xe9, 0x7f, 0x2b, 0xd8, 0x8b, 0x0f, 0xdb, 0xee, 0x00, 0x3e, - 0xdc, 0xa6, 0xe7, 0xa4, 0x0c, 0xda, 0x00, 0xf5, 0xcd, 0xf6, 0x21, 0xec, - 0x31, 0x6f, 0x18, 0xd7, 0xf6, 0x9b, 0xc4, 0x46, 0xf6, 0x99, 0xdf, 0x2c, - 0xc8, 0xc8, 0x3e, 0xfb, 0x9e, 0x6c, 0x73, 0x64, 0x4c, 0x48, 0xbf, 0x6e, - 0x59, 0xfd, 0x1f, 0xcf, 0xf4, 0xef, 0xeb, 0x2c, 0xea, 0xa3, 0x30, 0x8d, - 0xba, 0x7a, 0xd0, 0x35, 0xcc, 0xed, 0xd2, 0x52, 0xd5, 0x13, 0xd2, 0xa8, - 0xb0, 0x5f, 0x12, 0xdc, 0xb5, 0xa0, 0xc3, 0x02, 0xf5, 0x28, 0x43, 0x8f, - 0x51, 0xdc, 0x4d, 0xc2, 0xa5, 0x96, 0x84, 0xc9, 0x0a, 0x08, 0x67, 0xbe, - 0x43, 0xbb, 0x1d, 0xd3, 0x5b, 0x1d, 0xda, 0xed, 0x49, 0xbd, 0xde, 0x99, - 0x44, 0x7f, 0x18, 0xc2, 0xdb, 0xe1, 0xec, 0x25, 0x61, 0x8c, 0xcd, 0xc5, - 0x1c, 0x4f, 0x0b, 0xfb, 0xb1, 0x63, 0x7a, 0xaa, 0xcb, 0xf1, 0x49, 0x1d, - 0x75, 0x07, 0xe5, 0xfe, 0xc9, 0x00, 0x13, 0x93, 0xeb, 0xc8, 0xa3, 0x17, - 0x7b, 0xfd, 0xbd, 0x71, 0x3f, 0xcc, 0xe4, 0x62, 0x2e, 0xcd, 0x65, 0x0b, - 0x71, 0x8a, 0xb2, 0x21, 0x77, 0x32, 0xfe, 0x99, 0xdd, 0x83, 0xf7, 0xa3, - 0x8f, 0xda, 0xe3, 0xae, 0xfc, 0xfb, 0x04, 0x72, 0xa7, 0x60, 0xb1, 0x67, - 0x2d, 0xc5, 0x9d, 0xda, 0x37, 0xa6, 0x19, 0xbd, 0x0d, 0xdb, 0xa1, 0x47, - 0x98, 0xf7, 0xf0, 0x07, 0xae, 0x2e, 0x73, 0x0d, 0x7d, 0x38, 0xee, 0x82, - 0xbc, 0xcf, 0xad, 0xa5, 0x5c, 0x63, 0x8c, 0xa3, 0x57, 0x9c, 0xff, 0x15, - 0x68, 0xdf, 0x31, 0xad, 0x9e, 0xb2, 0xf7, 0x75, 0x15, 0xe1, 0x1e, 0xd6, - 0x63, 0x3f, 0x23, 0x4e, 0x23, 0x95, 0xa0, 0x19, 0x2f, 0xd8, 0xfb, 0x5a, - 0xe2, 0x05, 0xbc, 0x93, 0xa2, 0x07, 0x9d, 0x1f, 0xe8, 0x41, 0xe7, 0xd1, - 0x83, 0x8e, 0x15, 0x11, 0xe7, 0x09, 0xee, 0xa1, 0xaa, 0xd9, 0xcf, 0x9b, - 0x31, 0xde, 0x39, 0xdb, 0xbe, 0xec, 0x43, 0x77, 0x05, 0xdd, 0x22, 0xec, - 0xcf, 0xf5, 0x3b, 0xb3, 0xef, 0x5a, 0xa3, 0xa0, 0x4f, 0x6c, 0x3f, 0xd6, - 0xf6, 0x8b, 0xd2, 0x8c, 0x49, 0x73, 0x28, 0xa3, 0xf9, 0xf2, 0x1e, 0x9a, - 0x3b, 0x79, 0x46, 0xca, 0x96, 0xe6, 0x2b, 0xcc, 0x3b, 0xd6, 0xd2, 0x62, - 0x96, 0x6f, 0x27, 0xf0, 0x3c, 0x94, 0x3d, 0xe7, 0xf4, 0xf7, 0xee, 0xe1, - 0x7f, 0xc8, 0xe9, 0xbf, 0xf3, 0x99, 0x3a, 0x27, 0xec, 0x93, 0x21, 0x6f, - 0xc1, 0xe9, 0x7f, 0x27, 0xc1, 0x85, 0x73, 0x84, 0x3e, 0xe9, 0xf7, 0x17, - 0xc0, 0x60, 0x74, 0x5f, 0x53, 0xb0, 0xbb, 0x31, 0xed, 0x05, 0xe2, 0xda, - 0xdc, 0xec, 0x11, 0x8b, 0x6f, 0x6a, 0x42, 0x49, 0x8e, 0xb9, 0x83, 0xcf, - 0x18, 0x17, 0xec, 0x37, 0x03, 0xbc, 0xf7, 0x65, 0x6c, 0xe1, 0xfe, 0x2c, - 0xc8, 0xe1, 0x96, 0xd5, 0xcb, 0xe9, 0xdf, 0x8b, 0xbc, 0x1a, 0xeb, 0x01, - 0xea, 0xc6, 0x0c, 0xf5, 0xba, 0xf9, 0x6d, 0x63, 0x05, 0xb5, 0xe6, 0x2d, - 0xc4, 0x3e, 0xf2, 0xd3, 0xf6, 0x58, 0x5b, 0xf6, 0xdb, 0x02, 0xea, 0xd0, - 0x08, 0xee, 0x4b, 0xd1, 0xcd, 0x6f, 0x0c, 0x72, 0x01, 0x34, 0x17, 0xb1, - 0x76, 0xba, 0x9b, 0xf7, 0xbc, 0xe8, 0xf3, 0x81, 0x7b, 0xab, 0xd1, 0xfb, - 0xa6, 0xe9, 0x0f, 0xd2, 0xf2, 0xf7, 0x2f, 0x97, 0xa2, 0x15, 0x3a, 0x18, - 0x15, 0x00, 0x00, 0x00 }; + 0xbd, 0x58, 0x5d, 0x6c, 0x1c, 0x57, 0x15, 0x3e, 0x73, 0xe7, 0xee, 0xee, + 0x78, 0xb1, 0xe3, 0x71, 0x3b, 0xa4, 0xdb, 0x62, 0xc8, 0x8c, 0x7d, 0xfd, + 0x03, 0xb6, 0xc2, 0x94, 0x6e, 0xdb, 0xad, 0x18, 0x45, 0xc3, 0xec, 0xda, + 0xb1, 0xa2, 0x3c, 0xb8, 0x52, 0xa4, 0x46, 0x6a, 0x04, 0x66, 0x1d, 0x93, + 0x3e, 0xa6, 0x88, 0x07, 0xa4, 0x3e, 0x64, 0x59, 0x3b, 0xa9, 0x1f, 0x96, + 0x2c, 0xb8, 0xc8, 0x7e, 0x41, 0x28, 0x72, 0x6a, 0xbb, 0x48, 0x8b, 0x37, + 0x11, 0x48, 0x3c, 0x45, 0x8d, 0x1c, 0x14, 0x55, 0xea, 0x0b, 0x0f, 0xfc, + 0x3d, 0x46, 0x6a, 0x45, 0xfb, 0x50, 0x90, 0x55, 0xa9, 0xa8, 0x82, 0xe0, + 0xcb, 0x77, 0x66, 0x67, 0x9c, 0x4d, 0xec, 0x08, 0x9e, 0xb0, 0xb4, 0xba, + 0x33, 0x73, 0xef, 0x39, 0xf7, 0xdc, 0x73, 0xbe, 0xef, 0x9c, 0x73, 0x3d, + 0x64, 0x50, 0x9e, 0x92, 0xbf, 0x3e, 0xfc, 0x8a, 0xdf, 0xbd, 0xf8, 0x83, + 0x67, 0x8f, 0xbf, 0x70, 0x1c, 0x8f, 0xcf, 0x1b, 0xfd, 0x59, 0x49, 0xff, + 0xc7, 0x3f, 0x93, 0xc8, 0x4e, 0xed, 0xe0, 0x1f, 0x59, 0x22, 0xb8, 0xfd, + 0x54, 0xa4, 0xc8, 0x32, 0x83, 0xdf, 0x7c, 0x6d, 0x5e, 0x11, 0x85, 0xad, + 0x09, 0xb7, 0x4c, 0xff, 0xd6, 0x35, 0x47, 0x12, 0x7f, 0xff, 0x72, 0x70, + 0xff, 0xeb, 0xb7, 0x5e, 0xf4, 0x76, 0xaf, 0x99, 0x64, 0xd9, 0xc1, 0xb2, + 0xb4, 0x47, 0xc9, 0x1a, 0x84, 0xcc, 0xcf, 0xc7, 0xbe, 0x2d, 0xe8, 0x48, + 0xaa, 0xab, 0xa6, 0x85, 0xba, 0xa7, 0x6f, 0x8d, 0x29, 0xbb, 0x8e, 0x0d, + 0x6e, 0xb4, 0x5d, 0x8a, 0xda, 0x05, 0x7a, 0xb7, 0xed, 0xd0, 0xcd, 0xb6, + 0xa4, 0x85, 0xb7, 0x2e, 0xd1, 0x92, 0xef, 0x15, 0x2a, 0xa6, 0x45, 0x22, + 0xf0, 0x0a, 0x55, 0x72, 0x69, 0xc3, 0xf7, 0x6a, 0x73, 0xe6, 0x80, 0x61, + 0x05, 0x16, 0xbd, 0x31, 0x26, 0xe8, 0x9a, 0x73, 0x8e, 0xbe, 0xa7, 0xce, + 0xe2, 0x27, 0x49, 0xac, 0x48, 0xa3, 0xbc, 0x26, 0x49, 0xae, 0xf4, 0xd3, + 0x49, 0x5f, 0xeb, 0x79, 0x3f, 0x84, 0xfc, 0xf0, 0xf8, 0x05, 0xea, 0xa1, + 0x9a, 0xed, 0xcd, 0x10, 0x65, 0x78, 0x0d, 0x45, 0x7e, 0x86, 0x42, 0xbb, + 0x73, 0xae, 0x6b, 0xf1, 0x78, 0x5f, 0x6f, 0x40, 0xbe, 0x47, 0xa5, 0xf3, + 0x4f, 0x24, 0xf3, 0x76, 0x32, 0x2f, 0x48, 0xac, 0x7a, 0xee, 0x16, 0x8d, + 0x84, 0xd2, 0xd8, 0xd3, 0x91, 0x3a, 0x6a, 0x47, 0x5b, 0x92, 0xcc, 0x15, + 0xb6, 0x5f, 0xd9, 0x65, 0xd2, 0x90, 0x31, 0x59, 0x46, 0x8a, 0xe0, 0xfb, + 0x88, 0xdb, 0x48, 0x28, 0x0c, 0xa2, 0x9d, 0x46, 0xc1, 0x8e, 0xda, 0x3f, + 0x34, 0xa2, 0xe6, 0x9e, 0x0e, 0x65, 0x9e, 0x84, 0x0a, 0x8d, 0x68, 0x8b, + 0x75, 0xf5, 0x90, 0x54, 0x39, 0xc8, 0x0c, 0xdb, 0x82, 0x78, 0x8c, 0x92, + 0xef, 0xac, 0xbb, 0x82, 0xe7, 0x69, 0x23, 0xdc, 0x92, 0x46, 0xb4, 0x36, + 0x83, 0x67, 0x0b, 0xf2, 0xf0, 0x8b, 0x6f, 0x50, 0x38, 0x6b, 0x40, 0x8e, + 0xcf, 0x69, 0xe3, 0x5d, 0x50, 0xe8, 0xd8, 0xb4, 0x58, 0xf4, 0x0a, 0x35, + 0x3a, 0x65, 0x94, 0xb7, 0x0e, 0x04, 0xcd, 0x9e, 0x69, 0x1f, 0xfc, 0xc6, + 0xb6, 0x7c, 0x4b, 0x6a, 0x2d, 0x9e, 0xcd, 0x25, 0x67, 0x64, 0x7d, 0x61, + 0xc7, 0x7e, 0x87, 0xdf, 0x61, 0x73, 0x13, 0xb6, 0xb7, 0xb2, 0xb0, 0x47, + 0x6b, 0xde, 0x27, 0x52, 0x65, 0xd8, 0x19, 0xe2, 0xe7, 0x2d, 0x57, 0x01, + 0x85, 0xa1, 0xd5, 0x3e, 0x72, 0x07, 0xb4, 0xae, 0xf8, 0x9e, 0xbd, 0x45, + 0x01, 0x2d, 0x36, 0x07, 0xed, 0xa9, 0x66, 0x1d, 0xf3, 0x35, 0x5e, 0x03, + 0x7f, 0x10, 0x4d, 0xb5, 0xb4, 0xde, 0xf4, 0x7f, 0x9b, 0xa1, 0x23, 0x62, + 0x32, 0x43, 0x9e, 0x1b, 0xe2, 0xdb, 0xd0, 0xe6, 0xa3, 0x3e, 0x3b, 0x96, + 0xd8, 0xc0, 0x7e, 0xc7, 0x3e, 0xfe, 0x97, 0x92, 0xf7, 0x5e, 0x3b, 0x5a, + 0x4b, 0xfd, 0x1c, 0xdb, 0x0d, 0xbf, 0xfa, 0x14, 0x15, 0x61, 0xff, 0x63, + 0xcf, 0x94, 0xca, 0xb1, 0x2d, 0x6c, 0x37, 0xd6, 0xab, 0x07, 0x36, 0xbd, + 0x7a, 0xc0, 0x26, 0xb6, 0x47, 0x90, 0x5c, 0xb5, 0x68, 0x49, 0x7d, 0x64, + 0xd0, 0x11, 0xad, 0x97, 0x7c, 0x69, 0x54, 0xd6, 0x3e, 0x4b, 0x9e, 0x81, + 0xc3, 0x26, 0x70, 0xd8, 0x04, 0x2e, 0x9b, 0x64, 0x8b, 0xc0, 0xa5, 0x5b, + 0x63, 0x16, 0xdd, 0x33, 0x11, 0xcf, 0x36, 0xcf, 0xe7, 0xa8, 0xee, 0x2b, + 0xba, 0xdc, 0x64, 0xcf, 0xe4, 0x68, 0x51, 0x7d, 0xae, 0xcf, 0xc3, 0x1f, + 0x6f, 0x93, 0x3e, 0x16, 0x01, 0xb3, 0x11, 0xdc, 0xf9, 0x86, 0x1a, 0xa7, + 0xcb, 0x6d, 0x45, 0xf5, 0x36, 0xcb, 0x2d, 0x51, 0x47, 0xae, 0x1f, 0x72, + 0x93, 0x90, 0x2b, 0xd2, 0x95, 0x58, 0xb6, 0x1f, 0xb2, 0xbb, 0x89, 0xec, + 0x44, 0x61, 0x9a, 0x7c, 0xc8, 0x0c, 0xbb, 0xd3, 0xc0, 0xdc, 0x9c, 0x33, + 0x09, 0xd9, 0x49, 0x5a, 0xc2, 0xaf, 0xde, 0xa4, 0x9a, 0x2c, 0xb2, 0x5e, + 0xaf, 0x70, 0x9e, 0x7d, 0x1e, 0xeb, 0xac, 0x41, 0xa7, 0x83, 0x39, 0x0b, + 0x7a, 0x24, 0xc6, 0x0f, 0x75, 0xbd, 0x09, 0x6c, 0x3b, 0xfc, 0xfc, 0xae, + 0x16, 0x01, 0xfc, 0x50, 0x54, 0x6e, 0x9d, 0xf8, 0x3d, 0x4b, 0x65, 0xc4, + 0x52, 0xa8, 0x7e, 0xaa, 0xda, 0x86, 0x21, 0x02, 0x93, 0xaa, 0xf0, 0x42, + 0x38, 0x2b, 0xe3, 0x6f, 0x73, 0xb6, 0x01, 0x8e, 0x1d, 0x17, 0x9d, 0x9c, + 0x93, 0xc1, 0x1a, 0xc4, 0x5f, 0xf5, 0x52, 0xd5, 0x19, 0xc0, 0x5a, 0x10, + 0x2d, 0x3f, 0x02, 0x8e, 0x0e, 0x60, 0x0d, 0x8f, 0x1c, 0x07, 0xac, 0x57, + 0xbc, 0xbe, 0x17, 0x36, 0xa6, 0xdf, 0x7a, 0xa9, 0xf6, 0x50, 0x7c, 0xd8, + 0xc6, 0x38, 0x2e, 0xd8, 0x5f, 0x26, 0xb1, 0xed, 0x8e, 0x57, 0x3a, 0x6f, + 0x63, 0x7e, 0xe7, 0xab, 0x82, 0x76, 0xf5, 0x75, 0x15, 0x15, 0xf0, 0xe9, + 0xf3, 0x8a, 0x0a, 0x07, 0xcc, 0x18, 0x4b, 0x29, 0xa6, 0x78, 0xe4, 0x7c, + 0x43, 0x85, 0x79, 0x65, 0x98, 0x4b, 0x93, 0x4f, 0x52, 0xcd, 0xf1, 0xfc, + 0x32, 0x15, 0x68, 0xa9, 0x39, 0x01, 0xdf, 0xf5, 0xe3, 0xdc, 0x9e, 0x4f, + 0x34, 0x8c, 0xe7, 0xf0, 0x69, 0xc8, 0x20, 0x5f, 0xd4, 0xa0, 0x8b, 0xc7, + 0x41, 0xe8, 0xf7, 0x60, 0x23, 0xfc, 0xa1, 0x26, 0xec, 0x29, 0xf8, 0x23, + 0x74, 0x78, 0x8e, 0xf3, 0x98, 0xf3, 0x4c, 0xa4, 0x3c, 0xbf, 0x1a, 0xdb, + 0xe2, 0xd9, 0xb7, 0x89, 0xf3, 0x51, 0x9a, 0x83, 0x38, 0x27, 0x59, 0x73, + 0x32, 0xa0, 0xd9, 0x7a, 0xe3, 0x92, 0x36, 0x15, 0xcd, 0x65, 0x03, 0xc6, + 0x6e, 0x6f, 0x09, 0x58, 0x9c, 0xad, 0xb7, 0x06, 0x4f, 0xef, 0x34, 0xa8, + 0xf6, 0x4c, 0x20, 0x8e, 0x0a, 0xec, 0x1f, 0xf9, 0xcc, 0x29, 0xec, 0xd5, + 0x1e, 0x3c, 0x7d, 0xa7, 0x71, 0x0c, 0xbe, 0xa2, 0xfb, 0xf0, 0x3f, 0xf6, + 0xdf, 0x79, 0xda, 0x84, 0x9d, 0x1c, 0x33, 0x70, 0x2b, 0x7c, 0x75, 0xcc, + 0x00, 0x96, 0xf1, 0x0c, 0x6c, 0xd4, 0xda, 0x83, 0x73, 0x22, 0xa8, 0x51, + 0xd8, 0x5e, 0xc2, 0xcf, 0xa2, 0xa9, 0x86, 0x65, 0xdd, 0x81, 0x4e, 0x51, + 0xf4, 0xdc, 0xc8, 0xdc, 0x65, 0xae, 0xf0, 0x39, 0x58, 0x97, 0x65, 0x04, + 0xae, 0x1c, 0x6a, 0xf5, 0xbc, 0x22, 0x82, 0x00, 0x98, 0x90, 0x88, 0x4d, + 0x11, 0x58, 0xe1, 0x38, 0x5c, 0x45, 0x1c, 0x80, 0x03, 0xd8, 0x0c, 0xff, + 0xd7, 0x44, 0x70, 0x91, 0x2a, 0x45, 0xa2, 0xc5, 0x06, 0x61, 0x3f, 0xec, + 0x55, 0xc2, 0x0f, 0x78, 0x0e, 0xed, 0x12, 0x6c, 0xf0, 0xc2, 0x1a, 0x79, + 0xfe, 0x1c, 0xbc, 0x9e, 0xfb, 0x31, 0x59, 0x99, 0xe0, 0x9c, 0xdc, 0x68, + 0x90, 0x25, 0x83, 0xb3, 0x72, 0xa9, 0x31, 0xec, 0xff, 0x15, 0xbe, 0x26, + 0xf2, 0xc6, 0x37, 0x69, 0xc2, 0xdf, 0x04, 0x6f, 0xeb, 0xf8, 0x5d, 0x21, + 0xde, 0xfb, 0x9c, 0x1c, 0x69, 0xf1, 0x78, 0x56, 0xaa, 0x56, 0xb7, 0xde, + 0xbf, 0x69, 0xf6, 0xfb, 0x3d, 0x2a, 0xd1, 0x9b, 0xc9, 0xde, 0xf0, 0x0d, + 0x9d, 0x6c, 0x94, 0x80, 0xef, 0x03, 0xfa, 0x4b, 0xa9, 0xfe, 0xad, 0x58, + 0x37, 0x63, 0x77, 0xc2, 0xdf, 0x3a, 0x74, 0x8f, 0xa3, 0x69, 0x7e, 0x42, + 0x1e, 0xec, 0xe4, 0xeb, 0xc5, 0x66, 0x0e, 0x9c, 0xd0, 0xba, 0xaa, 0x7e, + 0x8f, 0xf3, 0xe6, 0x81, 0x5f, 0x1b, 0x3f, 0xc4, 0x72, 0x96, 0xe7, 0x0c, + 0xaa, 0xa2, 0x0e, 0xd5, 0xdb, 0xfc, 0xcc, 0x73, 0x9c, 0xcf, 0x72, 0x18, + 0xff, 0x8c, 0xb5, 0x1f, 0xea, 0x5a, 0x9b, 0xb9, 0xc6, 0xbe, 0x02, 0x47, + 0xda, 0x96, 0x51, 0x6e, 0x92, 0x51, 0x69, 0x92, 0x5b, 0xf5, 0x65, 0x1c, + 0x97, 0xd0, 0xb6, 0xe1, 0x53, 0xc6, 0xc3, 0xa4, 0x8c, 0x1a, 0x46, 0x5c, + 0xc3, 0x0c, 0x3c, 0x0f, 0xb5, 0x7e, 0x9d, 0x01, 0x27, 0x42, 0xf8, 0x5f, + 0x2c, 0x20, 0x47, 0x5e, 0x73, 0xa8, 0x5f, 0xa8, 0x39, 0x51, 0x77, 0xa8, + 0x4f, 0x28, 0xb6, 0xed, 0x3d, 0x01, 0xdb, 0x78, 0x3e, 0xac, 0xfa, 0xbf, + 0xc2, 0x9e, 0x41, 0xcc, 0xc7, 0x4a, 0x23, 0xcd, 0xfb, 0xd0, 0xa9, 0x38, + 0x67, 0x58, 0x49, 0xfe, 0x8f, 0x92, 0xdc, 0x2e, 0x81, 0x5b, 0xad, 0x5f, + 0x46, 0x5e, 0xaf, 0xc7, 0xb8, 0xf1, 0x6a, 0xae, 0xd8, 0xd3, 0xc3, 0xa3, + 0xcc, 0x51, 0xad, 0x2f, 0xfa, 0xd3, 0x58, 0x2b, 0x4d, 0xca, 0xcf, 0x20, + 0xb7, 0x73, 0x3d, 0x60, 0xdb, 0x02, 0xd8, 0xd6, 0xd7, 0xc9, 0xfb, 0xa8, + 0x09, 0xf5, 0xb8, 0x06, 0xf4, 0x90, 0xa9, 0x0c, 0xfc, 0x3c, 0x77, 0x8e, + 0xf8, 0x3b, 0xf5, 0x08, 0xbc, 0x57, 0xc1, 0xeb, 0xa5, 0xe2, 0x29, 0xa3, + 0xb2, 0x75, 0xcc, 0x4c, 0xfa, 0x08, 0xd8, 0x0d, 0x5e, 0x3b, 0x2c, 0x97, + 0x85, 0x5c, 0x1f, 0x64, 0xbe, 0x82, 0xb9, 0x0c, 0xc6, 0x6e, 0x3d, 0x71, + 0x2d, 0xc1, 0x5e, 0x2e, 0xf6, 0x9a, 0x21, 0x19, 0xe4, 0x51, 0xaf, 0x47, + 0xdc, 0x0a, 0x3d, 0x97, 0xd4, 0x6d, 0xe6, 0xf2, 0x89, 0x2e, 0x2e, 0xbb, + 0x64, 0xc6, 0x9c, 0x78, 0x29, 0xc9, 0x41, 0x9c, 0xc7, 0x5f, 0x48, 0xe6, + 0x1d, 0xe4, 0xe3, 0xe7, 0x92, 0xba, 0x62, 0xe1, 0x39, 0xa0, 0xe5, 0x38, + 0x37, 0x67, 0x39, 0x37, 0x17, 0x90, 0x9b, 0x4b, 0xe0, 0xa7, 0xff, 0x31, + 0x19, 0xc8, 0x4d, 0x44, 0xbf, 0x6b, 0x48, 0xe4, 0x21, 0x13, 0xf2, 0xdc, + 0x1b, 0xcc, 0xc1, 0x36, 0xcf, 0xfe, 0x18, 0x67, 0x0a, 0xcf, 0x70, 0xde, + 0xd4, 0x3a, 0x13, 0x28, 0xf7, 0x32, 0x8d, 0x16, 0x2e, 0x23, 0x4f, 0x9a, + 0x34, 0x81, 0xdd, 0x78, 0xdf, 0xb4, 0x96, 0xa7, 0x3d, 0x05, 0xff, 0xbd, + 0x6f, 0x90, 0xe2, 0xfa, 0xfb, 0x1d, 0xe8, 0x18, 0x71, 0xa7, 0xc0, 0xfb, + 0xc5, 0xd2, 0x7f, 0x93, 0xf9, 0x43, 0x22, 0x83, 0xba, 0x56, 0xe4, 0x7d, + 0x89, 0x2a, 0x2d, 0xf6, 0x83, 0xdf, 0x85, 0x07, 0x1f, 0x78, 0x20, 0xaa, + 0x36, 0xc1, 0x3f, 0xc4, 0x38, 0xc6, 0x1a, 0xd6, 0x8b, 0x22, 0x72, 0xaa, + 0xc3, 0xb8, 0x66, 0xbc, 0x9f, 0x49, 0xf0, 0x3e, 0x0b, 0xbc, 0x7b, 0xe3, + 0x37, 0xc0, 0xa3, 0x1b, 0x0f, 0xf1, 0xe8, 0x4c, 0x82, 0xf1, 0x59, 0x60, + 0xfc, 0x97, 0xc0, 0x96, 0x85, 0x9a, 0x0e, 0xdc, 0x36, 0xc8, 0x88, 0x50, + 0x1b, 0x80, 0x83, 0x44, 0xcf, 0xe9, 0x44, 0xcf, 0xcc, 0x63, 0xf4, 0x9c, + 0x4e, 0xf4, 0xcc, 0x74, 0xeb, 0x81, 0x5c, 0x25, 0x91, 0x0b, 0x1f, 0x23, + 0x57, 0x49, 0xe4, 0xc2, 0x2e, 0x39, 0x0b, 0x67, 0xe2, 0x73, 0x71, 0x1e, + 0xdb, 0x45, 0x2c, 0x7c, 0x8a, 0xb1, 0x62, 0x87, 0x18, 0xef, 0x61, 0x04, + 0x66, 0x9a, 0x37, 0xb1, 0x96, 0xfd, 0x90, 0x61, 0x0e, 0x3c, 0xe2, 0xbb, + 0x3d, 0xf8, 0x6e, 0x1f, 0xef, 0xf8, 0xfb, 0x66, 0x82, 0x15, 0xae, 0x45, + 0x5e, 0x2d, 0x7c, 0x68, 0x6d, 0x46, 0xb0, 0x9f, 0xc5, 0xd5, 0xc3, 0x62, + 0x60, 0x61, 0x0e, 0x35, 0xa7, 0x69, 0x52, 0x59, 0x32, 0x57, 0x5f, 0x91, + 0x31, 0x76, 0xb7, 0xb1, 0x7e, 0xbb, 0xc3, 0xab, 0x99, 0x46, 0x8e, 0x68, + 0xbd, 0x97, 0x16, 0x50, 0x4f, 0xce, 0x03, 0x4b, 0xd7, 0x7d, 0xb0, 0x90, + 0x86, 0x81, 0x0b, 0x0d, 0x5c, 0x7b, 0x71, 0x6c, 0x23, 0xb5, 0x08, 0x66, + 0xfc, 0x88, 0x76, 0x26, 0xf3, 0x94, 0xd9, 0xec, 0xd4, 0x43, 0xb9, 0xde, + 0xbd, 0x8f, 0x8b, 0x7d, 0x02, 0xd4, 0xe0, 0x3f, 0xa2, 0x17, 0x70, 0x48, + 0x8e, 0x22, 0x97, 0x36, 0x39, 0x27, 0x80, 0xa3, 0x9b, 0x5c, 0xeb, 0x39, + 0xe7, 0x5a, 0xc0, 0x62, 0x9a, 0x7f, 0x72, 0xe8, 0x5b, 0x3e, 0x41, 0xed, + 0x10, 0x34, 0x5f, 0xd4, 0x7a, 0xca, 0xff, 0x04, 0xb8, 0xc2, 0xb7, 0x75, + 0x9e, 0xdb, 0xc5, 0x77, 0xfe, 0x66, 0x51, 0x76, 0xf5, 0x49, 0xec, 0x89, + 0xfd, 0xce, 0xf0, 0xfa, 0x1c, 0x7a, 0x1a, 0xce, 0xf3, 0x18, 0xd7, 0xf9, + 0xdd, 0x48, 0x7c, 0x6a, 0x62, 0xfc, 0x02, 0x46, 0x3e, 0x4f, 0x0f, 0xce, + 0xa7, 0xf5, 0x5d, 0x9f, 0x9f, 0xb5, 0x96, 0x41, 0x2f, 0x95, 0x1b, 0x0a, + 0xf5, 0x7d, 0xa4, 0xb0, 0x00, 0x9e, 0x95, 0x5b, 0xe9, 0x3c, 0xcf, 0xd9, + 0x5d, 0x73, 0x78, 0x6e, 0xf1, 0x77, 0x41, 0x3b, 0x6a, 0x11, 0x75, 0x11, + 0xfd, 0xd3, 0x3a, 0xf7, 0x61, 0xdc, 0x53, 0xc5, 0xf5, 0x72, 0x9c, 0x7b, + 0xb0, 0x77, 0x90, 0xff, 0xd7, 0xc1, 0x29, 0xf0, 0xfb, 0x29, 0x41, 0x4f, + 0x50, 0xd9, 0x49, 0xcf, 0xa3, 0x35, 0x38, 0x5b, 0x30, 0x0d, 0xe6, 0xe2, + 0xb0, 0x3d, 0x4d, 0xdc, 0x6b, 0x8d, 0x84, 0x55, 0x96, 0x69, 0x21, 0x1f, + 0xac, 0x68, 0xaa, 0x76, 0xf4, 0xd8, 0xb3, 0xc8, 0xd1, 0xd1, 0x4f, 0xb8, + 0xb6, 0xb1, 0x6f, 0x4f, 0xc0, 0x1e, 0xf4, 0x05, 0xeb, 0x92, 0xde, 0x6e, + 0xb0, 0x9e, 0x3c, 0x99, 0xe8, 0x11, 0x97, 0xfd, 0x54, 0xcf, 0x9f, 0xa0, + 0x87, 0x1c, 0x41, 0xdc, 0xff, 0x4a, 0xe8, 0x62, 0x1f, 0x64, 0xd0, 0x8f, + 0x8f, 0xd3, 0xbc, 0x5a, 0x8c, 0x6b, 0xf1, 0x79, 0xd4, 0xde, 0xa8, 0x98, + 0x85, 0xef, 0x72, 0xb1, 0x9e, 0x7a, 0xf3, 0x5f, 0x9a, 0xf3, 0x0f, 0xea, + 0x24, 0xf4, 0xe3, 0xbd, 0x8d, 0xb9, 0x95, 0x80, 0xde, 0x6c, 0xc6, 0xb5, + 0xdb, 0xbe, 0x88, 0x9e, 0xbf, 0xd2, 0xf8, 0x47, 0xda, 0xcb, 0x84, 0xc0, + 0x71, 0xe1, 0x02, 0x7c, 0x23, 0xb7, 0x7b, 0xe9, 0x35, 0xf4, 0xa8, 0x99, + 0x15, 0xd4, 0x65, 0xf8, 0x4d, 0x5c, 0xad, 0x8d, 0x73, 0x9f, 0x79, 0x03, + 0x5c, 0x9f, 0x2f, 0x2a, 0xdf, 0x34, 0x46, 0x69, 0xf9, 0x67, 0x5c, 0x67, + 0xe2, 0x7a, 0x0d, 0xfc, 0xb8, 0x74, 0xa5, 0xa5, 0x68, 0xb9, 0x65, 0xc3, + 0x2e, 0xfb, 0x41, 0x2f, 0xae, 0x38, 0x1f, 0x57, 0xf0, 0x8b, 0xf3, 0x2d, + 0xce, 0x04, 0x3e, 0x04, 0xec, 0x0f, 0xee, 0xbd, 0x39, 0x66, 0x9c, 0xff, + 0x4e, 0xe1, 0x99, 0xcf, 0xca, 0xbd, 0x32, 0xfb, 0x81, 0x7b, 0xe2, 0xee, + 0xfe, 0x9d, 0x73, 0x23, 0x74, 0x6e, 0x33, 0x87, 0xb8, 0x47, 0xa9, 0xc8, + 0xf9, 0x86, 0x1d, 0xf3, 0xaa, 0xde, 0xee, 0xf8, 0x3b, 0xf2, 0x59, 0xa7, + 0x57, 0x0a, 0xe9, 0xce, 0x8b, 0x22, 0xee, 0x3b, 0x42, 0xe4, 0x15, 0x3e, + 0xcb, 0x04, 0xee, 0x27, 0x1e, 0x7c, 0xe7, 0xa1, 0x2f, 0xe9, 0xf0, 0x73, + 0x38, 0xe1, 0xe7, 0x50, 0xeb, 0x44, 0x26, 0xed, 0xc7, 0x0e, 0x72, 0xee, + 0x17, 0xe2, 0x7f, 0xe7, 0xdc, 0x46, 0xc2, 0xb9, 0x6c, 0x8c, 0x4d, 0xb1, + 0xd2, 0x3d, 0xf7, 0x0e, 0xe6, 0x72, 0x5d, 0xf7, 0xa2, 0xc3, 0x62, 0x12, + 0xf3, 0x03, 0x9c, 0xe4, 0x75, 0x88, 0xff, 0x4a, 0x2f, 0x99, 0x57, 0x99, + 0x97, 0x29, 0x46, 0x5c, 0xe0, 0x31, 0xd5, 0xd1, 0x83, 0x3d, 0x70, 0xd7, + 0x59, 0xcd, 0xc4, 0xf8, 0x37, 0x83, 0x74, 0x4d, 0x81, 0xa6, 0x1b, 0x9e, + 0x7f, 0x87, 0xc7, 0x16, 0xcf, 0x4b, 0xca, 0xae, 0x58, 0xf4, 0xfa, 0x98, + 0xe7, 0xba, 0xc2, 0xf3, 0x77, 0x60, 0xf7, 0x5d, 0xe5, 0x50, 0x66, 0x94, + 0x39, 0xc9, 0x15, 0x2a, 0x0b, 0xdc, 0xe0, 0x0e, 0xd8, 0xd4, 0x97, 0xd0, + 0x1f, 0xb9, 0x12, 0xb1, 0xfd, 0x29, 0x6c, 0xe1, 0x7c, 0x0b, 0xbb, 0xc6, + 0xd7, 0x81, 0x83, 0x05, 0x7e, 0xdf, 0xc7, 0x18, 0xdf, 0x2d, 0x78, 0x7f, + 0x07, 0x67, 0xb0, 0x28, 0xb7, 0xaa, 0x71, 0xf7, 0x7b, 0x20, 0x77, 0x25, + 0xc1, 0x6b, 0x06, 0xdf, 0xe7, 0x63, 0xbc, 0x72, 0x1c, 0xd9, 0xe7, 0x5a, + 0x7f, 0x80, 0x38, 0x96, 0xe9, 0x2f, 0x31, 0x8f, 0xef, 0xfa, 0x31, 0x7e, + 0x61, 0x0f, 0x64, 0x5a, 0x9f, 0xca, 0x98, 0xe7, 0xe0, 0xc3, 0x65, 0x3f, + 0xc6, 0xd7, 0xf8, 0x4d, 0x1c, 0xbb, 0x83, 0xfd, 0x6e, 0x3d, 0xc3, 0xf6, + 0x49, 0x8a, 0x39, 0xe5, 0x2e, 0x72, 0x8f, 0xe9, 0x8f, 0x20, 0xdf, 0x62, + 0x5d, 0x2b, 0xe5, 0x7d, 0x16, 0x7c, 0x67, 0x5f, 0x33, 0xf7, 0x07, 0x92, + 0xe7, 0x2f, 0x22, 0xb6, 0x36, 0xfc, 0xd8, 0xe9, 0x05, 0xcc, 0x15, 0xb6, + 0xad, 0x97, 0xd4, 0xd5, 0xd4, 0xae, 0x4f, 0x63, 0x7b, 0x1e, 0xd6, 0x89, + 0xf9, 0xed, 0xc3, 0xe4, 0xec, 0x2e, 0xb9, 0xbf, 0x1f, 0x22, 0x87, 0xf9, + 0x6d, 0x96, 0xc9, 0xef, 0xf7, 0x20, 0xe5, 0x7d, 0x3c, 0x87, 0xc0, 0x3b, + 0xcb, 0x3e, 0x7a, 0xef, 0xec, 0xc6, 0x7e, 0x5a, 0xfb, 0x19, 0xdf, 0xbc, + 0xa7, 0xe7, 0x72, 0xef, 0xde, 0xc1, 0x76, 0x1e, 0x79, 0x2f, 0xf6, 0x03, + 0x72, 0xa6, 0x37, 0x3e, 0x47, 0x29, 0xfe, 0x1f, 0x60, 0x7c, 0x01, 0x76, + 0x55, 0x68, 0xa2, 0xc4, 0xe3, 0xc9, 0x03, 0x18, 0xe7, 0xfb, 0x3a, 0xd7, + 0xa6, 0x3c, 0xee, 0x61, 0x5c, 0xe7, 0xf9, 0x2e, 0xd6, 0xc9, 0x53, 0x95, + 0x35, 0x7e, 0xff, 0x2c, 0x79, 0xe7, 0xbc, 0xcc, 0x7d, 0xd4, 0x0d, 0x9c, + 0x9f, 0xeb, 0xd1, 0x18, 0xd5, 0x1d, 0xf8, 0xd5, 0x67, 0x1b, 0x2e, 0xd0, + 0x83, 0x1e, 0xec, 0xb0, 0xba, 0xb2, 0x6a, 0x76, 0x71, 0xe5, 0xb0, 0x7e, + 0x8c, 0xef, 0x27, 0x46, 0x79, 0xcd, 0x48, 0x7a, 0x78, 0xee, 0xbf, 0xf6, + 0xb4, 0x19, 0xf7, 0x62, 0x9c, 0x17, 0xb8, 0x07, 0x7b, 0x0d, 0xfb, 0xf6, + 0xc5, 0xef, 0xe1, 0x16, 0x8f, 0xec, 0x17, 0x8a, 0x79, 0xd1, 0xe1, 0x79, + 0x6a, 0x77, 0x84, 0x75, 0xf0, 0x8f, 0x88, 0x52, 0x9b, 0xa8, 0xfa, 0x16, + 0xd7, 0x54, 0x3b, 0xc9, 0xff, 0x17, 0x31, 0x3e, 0x9f, 0x60, 0x20, 0x3d, + 0x4b, 0xec, 0x57, 0xec, 0xaf, 0xf5, 0x2c, 0x30, 0xf5, 0xba, 0x9f, 0xda, + 0x0a, 0x6c, 0x7f, 0x23, 0xcd, 0x31, 0x88, 0x97, 0xda, 0xd3, 0x72, 0x34, + 0x84, 0x2d, 0xfc, 0xff, 0x82, 0x0a, 0x7a, 0x3b, 0xb6, 0x65, 0xc6, 0x78, + 0x79, 0xff, 0x7f, 0x04, 0x8f, 0xf6, 0x71, 0x1c, 0x3f, 0x8e, 0xef, 0x7e, + 0xfc, 0xac, 0x1c, 0x7c, 0xff, 0x51, 0xc3, 0xb3, 0x07, 0x04, 0xe7, 0x23, + 0xb2, 0xb2, 0x88, 0xc1, 0x5d, 0xc4, 0x28, 0x24, 0xaf, 0xf4, 0x41, 0xdc, + 0x9b, 0x13, 0x38, 0x37, 0x11, 0xe2, 0x19, 0x1c, 0xc0, 0xd9, 0x46, 0x3d, + 0xff, 0x3d, 0xe2, 0x38, 0x58, 0xb8, 0x6b, 0x74, 0x62, 0x37, 0x96, 0xc4, + 0x6e, 0xb4, 0xf5, 0xf0, 0x99, 0x5d, 0xf1, 0x52, 0xf2, 0xce, 0x67, 0xe2, + 0x5e, 0xc1, 0xe5, 0x1e, 0x09, 0x3e, 0x28, 0x19, 0x9d, 0x7b, 0x7b, 0x93, + 0xef, 0x97, 0x35, 0xce, 0xe5, 0xdc, 0xcf, 0x81, 0x6b, 0xa8, 0x96, 0x23, + 0xb8, 0x6b, 0x68, 0x5d, 0x2f, 0x31, 0x76, 0x27, 0xc6, 0xa7, 0x62, 0x0c, + 0x8b, 0x41, 0x41, 0x29, 0xb7, 0xba, 0x9f, 0x31, 0x96, 0xf8, 0x9e, 0xc6, + 0xef, 0x1d, 0x1d, 0x1b, 0xc0, 0x1d, 0x6e, 0x32, 0xb8, 0x1d, 0xb2, 0x7e, + 0xa3, 0xd3, 0x13, 0xdb, 0x11, 0xf3, 0x1e, 0xb8, 0x7b, 0x1f, 0x76, 0x85, + 0xe0, 0x6d, 0xe7, 0x6e, 0x37, 0x87, 0x9c, 0x72, 0x1b, 0xb1, 0xbd, 0xab, + 0x3a, 0x75, 0x71, 0x83, 0xfb, 0xae, 0x16, 0xf2, 0x4d, 0x1e, 0xbd, 0xb2, + 0x4a, 0xef, 0xa2, 0x16, 0x5d, 0xc3, 0x9a, 0xeb, 0x98, 0xbb, 0xd2, 0x4a, + 0x71, 0x84, 0x1e, 0x0f, 0xd8, 0x9c, 0x57, 0xff, 0xd4, 0x55, 0xa7, 0x7b, + 0x2d, 0xff, 0xfd, 0x07, 0x5d, 0xe7, 0x92, 0xbb, 0xa8, 0x13, 0x00, 0x00, + 0x00 }; static const u32 bnx2_TPAT_b09FwData[(0x0/4) + 1] = { 0x0 }; static const u32 bnx2_TPAT_b09FwRodata[(0x4/4) + 1] = { 0x00000001, 0x00000000 }; static struct fw_info bnx2_tpat_fw_09 = { - /* Firmware version: 4.4.26 */ + /* Firmware version: 4.6.15 */ .ver_major = 0x4, - .ver_minor = 0x4, - .ver_fix = 0x1a, + .ver_minor = 0x6, + .ver_fix = 0xf, .start_addr = 0x08000488, .text_addr = 0x08000400, - .text_len = 0x1514, + .text_len = 0x13a4, .text_index = 0x0, .gz_text = bnx2_TPAT_b09FwText, .gz_text_len = sizeof(bnx2_TPAT_b09FwText), @@ -3709,871 +3643,868 @@ static struct fw_info bnx2_tpat_fw_09 = { .data_index = 0x0, .data = bnx2_TPAT_b09FwData, - .sbss_addr = 0x08001940, - .sbss_len = 0x48, + .sbss_addr = 0x080017c0, + .sbss_len = 0x40, .sbss_index = 0x0, - .bss_addr = 0x08001988, + .bss_addr = 0x08001800, .bss_len = 0x12b4, .bss_index = 0x0, - .rodata_addr = 0x08001914, + .rodata_addr = 0x080017a4, .rodata_len = 0x4, .rodata_index = 0x0, .rodata = bnx2_TPAT_b09FwRodata, }; static u8 bnx2_TXP_b09FwText[] = { - 0xc5, 0x7b, 0x7b, 0x74, 0x1c, 0x55, 0x9a, 0xdf, 0xef, 0x56, 0x3f, 0x54, - 0xdd, 0x6a, 0xb5, 0x4a, 0x72, 0xdb, 0x6e, 0xed, 0x68, 0xc6, 0x5d, 0xee, - 0x6a, 0xb9, 0xb1, 0x84, 0x5d, 0x2d, 0xb5, 0xec, 0x66, 0x5d, 0xb1, 0x7b, - 0x8c, 0xb0, 0x65, 0x10, 0x3b, 0xc2, 0xeb, 0x9d, 0x88, 0x09, 0x27, 0xf4, - 0x18, 0x19, 0x64, 0x63, 0x40, 0x30, 0x64, 0xa3, 0xd9, 0x25, 0xeb, 0x1a, - 0xf9, 0x81, 0x1f, 0xad, 0xee, 0xd6, 0xc3, 0xc8, 0xec, 0xd9, 0x13, 0x64, - 0x49, 0xb6, 0xcc, 0xd0, 0x0f, 0x33, 0xc0, 0xcc, 0x30, 0x27, 0x13, 0x77, - 0x8c, 0x01, 0x03, 0x63, 0x98, 0xdd, 0x6c, 0x92, 0x99, 0x3d, 0x49, 0xd6, - 0x07, 0xf3, 0xb0, 0xc1, 0x60, 0x32, 0x43, 0x12, 0xb1, 0xcb, 0x4c, 0xe5, - 0xfb, 0xaa, 0x25, 0x63, 0x58, 0xb2, 0x9b, 0x6c, 0xfe, 0x88, 0xce, 0xd1, - 0xe9, 0xee, 0xaa, 0x5b, 0xf7, 0x7e, 0xef, 0xef, 0xf7, 0x7d, 0xf7, 0x56, - 0x04, 0xf0, 0x62, 0xee, 0xaf, 0x86, 0xfe, 0xe3, 0xfd, 0x03, 0x0f, 0xb7, - 0xae, 0x88, 0xaf, 0xa0, 0xaf, 0x6d, 0x58, 0xec, 0x74, 0xf2, 0xcd, 0x55, - 0x02, 0x48, 0xbd, 0x87, 0x7f, 0xd4, 0xdf, 0x57, 0xff, 0x71, 0x8f, 0xc1, - 0x01, 0x28, 0xf3, 0x34, 0xf1, 0x3f, 0x64, 0xc9, 0x30, 0xd7, 0xac, 0xd7, - 0x20, 0x3b, 0x8c, 0xc4, 0xda, 0xbb, 0x34, 0x20, 0x99, 0x6f, 0x0e, 0xdd, - 0x88, 0xdf, 0x58, 0x66, 0xc0, 0x09, 0xbe, 0xfe, 0x55, 0xe3, 0xd3, 0x5d, - 0x3f, 0x5d, 0xad, 0x7e, 0x34, 0xe1, 0x80, 0xac, 0x18, 0x63, 0x50, 0x9a, - 0x20, 0x37, 0xd2, 0x33, 0x7f, 0xb6, 0xec, 0x79, 0x27, 0xfc, 0xf3, 0x73, - 0xc1, 0x74, 0x19, 0x3a, 0x76, 0x67, 0xfb, 0x31, 0x13, 0x07, 0x2e, 0xa6, - 0x23, 0xfa, 0x6e, 0x20, 0x27, 0x19, 0x91, 0xd0, 0x69, 0x84, 0x30, 0x9d, - 0x87, 0x59, 0x65, 0x68, 0xd8, 0x5f, 0x0a, 0xe1, 0x52, 0xfa, 0xb7, 0x56, - 0xc8, 0xd5, 0x8f, 0xb7, 0xe2, 0x90, 0x83, 0xc6, 0x23, 0x08, 0x66, 0x21, - 0xd7, 0x18, 0x03, 0x28, 0x0c, 0x01, 0x7b, 0xd3, 0x6a, 0x3f, 0xa0, 0xf6, - 0x14, 0x45, 0xf8, 0xec, 0x09, 0xa8, 0xdd, 0x0d, 0x8e, 0xe6, 0xd4, 0xed, - 0x42, 0x4d, 0xee, 0x14, 0x90, 0x05, 0x8d, 0x5d, 0x9e, 0xe7, 0xcf, 0x01, - 0x44, 0xf3, 0x32, 0xce, 0x3b, 0x78, 0x59, 0x83, 0xe4, 0x2c, 0xe0, 0xd4, - 0x74, 0xec, 0xcd, 0xc2, 0x74, 0x1a, 0x02, 0xbb, 0xe3, 0x11, 0x65, 0x0a, - 0x7c, 0x3f, 0x84, 0x41, 0x7b, 0x9c, 0x4a, 0x1c, 0x5b, 0xd6, 0x1e, 0xdd, - 0xb2, 0x8e, 0xe9, 0x55, 0x30, 0x15, 0x35, 0x08, 0x08, 0x0c, 0xea, 0x12, - 0x92, 0xca, 0xfa, 0x90, 0x13, 0x6a, 0x70, 0x1b, 0xfe, 0x96, 0xf8, 0x4d, - 0x46, 0x5d, 0xa8, 0x8c, 0x4f, 0xa1, 0x0a, 0x65, 0xa5, 0x22, 0xb1, 0xc9, - 0xb4, 0x65, 0xbd, 0xa4, 0x39, 0x71, 0x8c, 0x64, 0x33, 0x98, 0xff, 0x5b, - 0xab, 0x4c, 0x72, 0xd9, 0xa3, 0xcd, 0xaf, 0x2f, 0x63, 0x42, 0xb1, 0xac, - 0x29, 0xba, 0xb7, 0x2f, 0x3f, 0x2f, 0x63, 0xcb, 0x92, 0x34, 0xcb, 0xba, - 0x4b, 0xfb, 0x1b, 0x6b, 0xeb, 0xe7, 0xc6, 0xc6, 0xf0, 0xfd, 0x9c, 0x82, - 0xa7, 0xb2, 0x49, 0xe4, 0xd3, 0x16, 0x1c, 0x86, 0x13, 0x7d, 0x43, 0x21, - 0xec, 0x2c, 0x74, 0xa0, 0x90, 0x56, 0x53, 0xe7, 0xe9, 0xb9, 0xad, 0x71, - 0x0d, 0xf7, 0x15, 0x3a, 0x31, 0x93, 0x86, 0xe5, 0x31, 0xb4, 0xb2, 0x47, - 0x44, 0x71, 0x4f, 0xa1, 0x0b, 0xc5, 0xb4, 0x76, 0x76, 0x50, 0x44, 0x06, - 0x1a, 0x1c, 0x4e, 0x3c, 0x50, 0x68, 0xc1, 0xfd, 0x85, 0x04, 0x3d, 0x63, - 0xe1, 0xe6, 0x58, 0x23, 0x8d, 0x6f, 0xc5, 0x93, 0x63, 0x96, 0x15, 0x8d, - 0x29, 0xe8, 0x2b, 0xe8, 0x98, 0xc9, 0x49, 0x48, 0x1d, 0x73, 0x22, 0x75, - 0x14, 0xb8, 0xe7, 0x68, 0x2b, 0xa6, 0x72, 0x16, 0xb6, 0xea, 0x83, 0x0d, - 0x12, 0x5c, 0x48, 0x29, 0x02, 0x2e, 0xcd, 0x8f, 0x6d, 0x4a, 0x85, 0xf6, - 0xf3, 0x0e, 0x81, 0x1d, 0x47, 0xa3, 0xf8, 0x45, 0xda, 0xc4, 0xcd, 0xed, - 0x41, 0x0c, 0x14, 0x02, 0x78, 0x23, 0x1d, 0xa0, 0x35, 0x74, 0xbc, 0x9e, - 0x96, 0x69, 0x9d, 0x16, 0x9c, 0x49, 0xf3, 0x18, 0x1e, 0xeb, 0x43, 0x6f, - 0xa1, 0x11, 0xe7, 0xd2, 0x41, 0x5a, 0x33, 0x80, 0x57, 0x68, 0xdc, 0xf6, - 0x82, 0x86, 0xb3, 0x34, 0xae, 0xaf, 0x10, 0xc2, 0xcb, 0x69, 0x1f, 0xd1, - 0x1a, 0xc0, 0xe9, 0x74, 0x3f, 0x76, 0xa7, 0x9b, 0xcf, 0xde, 0x48, 0x32, - 0x0c, 0x2d, 0xe0, 0x75, 0xf8, 0xda, 0x5b, 0x56, 0x57, 0xc0, 0x36, 0x13, - 0x5a, 0x67, 0x7e, 0xdd, 0x7e, 0x0c, 0xa6, 0xcf, 0xcc, 0xf9, 0x89, 0x8e, - 0x03, 0xb9, 0x59, 0xeb, 0xa7, 0xcb, 0x1a, 0x71, 0x22, 0x0b, 0x3c, 0x39, - 0x05, 0x4c, 0x65, 0x4d, 0xab, 0xc6, 0xb0, 0xac, 0xc9, 0xf6, 0x16, 0x92, - 0x97, 0xd6, 0xb3, 0x95, 0x46, 0x3d, 0x55, 0x72, 0x02, 0x47, 0xd5, 0x9e, - 0x32, 0x24, 0x4c, 0xcc, 0x38, 0xe1, 0x1e, 0x52, 0x3b, 0x27, 0xa0, 0x9e, - 0xbd, 0x87, 0x3c, 0xe9, 0x58, 0x56, 0xed, 0x36, 0xb1, 0xcb, 0x0a, 0x1a, - 0x4d, 0xa1, 0x16, 0x87, 0x05, 0x3f, 0xd9, 0x42, 0xba, 0xc5, 0xb2, 0x6a, - 0x57, 0x5b, 0xd6, 0xb9, 0x76, 0x58, 0x92, 0xa1, 0x9d, 0x2d, 0x41, 0x2b, - 0x7f, 0x00, 0x6d, 0xe0, 0x34, 0xca, 0x5f, 0xf5, 0x21, 0xd2, 0x17, 0x76, - 0x44, 0xfa, 0x67, 0xe9, 0xd9, 0x9a, 0x02, 0x99, 0x32, 0xf1, 0xa2, 0x91, - 0x0d, 0x16, 0x4a, 0x32, 0x9c, 0xc4, 0x4f, 0xcb, 0x90, 0x65, 0x39, 0x35, - 0x1f, 0x7c, 0x24, 0xdf, 0x8d, 0x87, 0x2d, 0xeb, 0x1d, 0x5d, 0x81, 0x9b, - 0x74, 0x73, 0xd3, 0xb0, 0x85, 0x49, 0xfd, 0x34, 0xc9, 0x53, 0x20, 0xd5, - 0x1d, 0xa7, 0x67, 0x02, 0x34, 0x3e, 0x81, 0x8d, 0x43, 0x41, 0x7c, 0x3f, - 0x2b, 0xe3, 0xa7, 0xcb, 0xa2, 0xa8, 0xa6, 0xb9, 0xbc, 0x24, 0xab, 0x2a, - 0x92, 0x1f, 0x0a, 0x64, 0x6e, 0x85, 0x8a, 0x3d, 0xa2, 0x70, 0x9e, 0x78, - 0x0c, 0xe2, 0x07, 0xa5, 0x00, 0x9e, 0x2e, 0x29, 0x38, 0x59, 0x6a, 0xc4, - 0xa9, 0x92, 0x8e, 0x6c, 0x4e, 0xdd, 0x5f, 0x86, 0x85, 0x1a, 0x32, 0xe7, - 0x37, 0x26, 0x62, 0xc8, 0xe4, 0x2c, 0x2b, 0x4f, 0x34, 0x7b, 0x89, 0x87, - 0xd7, 0x27, 0xbe, 0x86, 0xe3, 0x63, 0x4e, 0x84, 0x26, 0x03, 0x78, 0x2a, - 0xed, 0xc4, 0x75, 0x19, 0xd5, 0x9c, 0x80, 0x16, 0xdd, 0x29, 0xb4, 0xe4, - 0x72, 0xa1, 0xe6, 0x4c, 0x44, 0x42, 0x2e, 0x21, 0xa1, 0xe9, 0xb8, 0x13, - 0x5a, 0x31, 0x04, 0x57, 0x93, 0x0c, 0xad, 0x89, 0xdc, 0xc8, 0x2f, 0xc1, - 0x4d, 0x7e, 0xb1, 0x71, 0x24, 0x4a, 0xd7, 0x02, 0x74, 0x0d, 0x5f, 0xab, - 0x82, 0x63, 0x91, 0x03, 0x24, 0x37, 0xcd, 0x81, 0xa4, 0xd3, 0xb2, 0x1c, - 0x5a, 0x2b, 0x7a, 0x1e, 0xa3, 0xcf, 0x36, 0x1e, 0xaf, 0x20, 0x5c, 0x24, - 0x19, 0x34, 0x11, 0x4d, 0x59, 0xa2, 0x31, 0x4b, 0x34, 0x66, 0x89, 0xc6, - 0xac, 0x83, 0x6c, 0x46, 0xd5, 0x81, 0x3f, 0x22, 0x5d, 0x85, 0x88, 0xbf, - 0x5f, 0xd8, 0x7a, 0x7a, 0xba, 0x14, 0x24, 0xfa, 0x43, 0x36, 0xfd, 0x4f, - 0xe6, 0x04, 0x24, 0x4d, 0xed, 0x3e, 0x8f, 0x75, 0x08, 0xc7, 0xd4, 0xe4, - 0x04, 0x92, 0xf4, 0x9c, 0xba, 0xdf, 0x84, 0xda, 0x59, 0x26, 0xfd, 0x6f, - 0x55, 0x12, 0x98, 0xc9, 0xba, 0x50, 0xad, 0xa9, 0x21, 0xd2, 0x57, 0xb4, - 0x8c, 0x05, 0xb8, 0x57, 0xa1, 0x39, 0x25, 0xb7, 0xa8, 0xc4, 0x90, 0x47, - 0x10, 0x19, 0x91, 0x30, 0xad, 0x3b, 0xc8, 0x3f, 0x75, 0x38, 0x9a, 0x68, - 0xb9, 0x62, 0x9c, 0x3e, 0x69, 0xfe, 0x2c, 0xad, 0x45, 0xf4, 0xd0, 0x7c, - 0xe4, 0x97, 0x2c, 0xc7, 0x28, 0xd1, 0xb0, 0xd7, 0xa6, 0xf7, 0x64, 0xa9, - 0x4b, 0x54, 0xec, 0xc7, 0x20, 0x7b, 0x51, 0x43, 0x10, 0x6a, 0x34, 0x24, - 0x54, 0x3d, 0x29, 0x14, 0x4c, 0x95, 0x7e, 0x46, 0x63, 0x02, 0xd7, 0x8c, - 0xe9, 0xc6, 0x60, 0x56, 0xe0, 0x46, 0xcd, 0xc2, 0x7a, 0xbd, 0x1b, 0xbb, - 0x4b, 0xf3, 0x7e, 0xc9, 0xb1, 0x4b, 0xf1, 0x4f, 0xa5, 0x3b, 0xb0, 0x27, - 0x1b, 0xc2, 0xee, 0x7c, 0xd0, 0x3f, 0x99, 0xe6, 0x7b, 0x1a, 0xf9, 0x3b, - 0xdf, 0x0b, 0x5c, 0x73, 0xaf, 0xf1, 0x9a, 0x7b, 0x09, 0x0c, 0x8e, 0x7e, - 0x85, 0x62, 0x48, 0x2d, 0x76, 0x6b, 0x1f, 0x91, 0xad, 0x68, 0x89, 0x5e, - 0x34, 0xe0, 0xbc, 0xd2, 0x82, 0x43, 0xe3, 0x5d, 0xd8, 0x33, 0xbe, 0x02, - 0x07, 0x46, 0x1b, 0x53, 0x5e, 0x63, 0x88, 0xd6, 0x0f, 0x27, 0x7b, 0x85, - 0xda, 0xef, 0x10, 0xe1, 0x68, 0x2f, 0xd9, 0x6e, 0x53, 0x9d, 0x65, 0x9d, - 0x8e, 0x91, 0x6d, 0xeb, 0xcd, 0xfa, 0x46, 0x12, 0x40, 0xb9, 0x5b, 0xed, - 0x7c, 0x0b, 0x3e, 0xdc, 0x4a, 0x36, 0x37, 0x15, 0x43, 0xaf, 0x03, 0x8e, - 0x16, 0x1f, 0x7e, 0x6d, 0x1d, 0x75, 0xb2, 0xdc, 0xad, 0x5d, 0x77, 0xe9, - 0x7b, 0x05, 0xc7, 0x39, 0xf7, 0xd5, 0x58, 0xc2, 0xf3, 0xf3, 0x33, 0x96, - 0x15, 0xa6, 0x79, 0xfa, 0x62, 0xcd, 0x89, 0x3e, 0xcc, 0x5a, 0xe7, 0xb7, - 0x74, 0x61, 0xf7, 0xcc, 0x0a, 0x1c, 0x1c, 0x75, 0x21, 0x59, 0x27, 0x50, - 0xab, 0x85, 0xcb, 0xf7, 0x62, 0x05, 0xcc, 0x29, 0x7e, 0xae, 0x0b, 0x47, - 0x66, 0x2a, 0xbf, 0xb3, 0x57, 0x7f, 0xcf, 0xcf, 0x77, 0x91, 0x74, 0xca, - 0xf2, 0xe4, 0x38, 0x49, 0x2a, 0x30, 0x9a, 0x71, 0x62, 0x34, 0x40, 0xba, - 0xed, 0x10, 0xce, 0xe3, 0x8b, 0xfc, 0xde, 0xc7, 0x2c, 0xbc, 0xa4, 0x93, - 0x9e, 0xb3, 0x1b, 0x84, 0xf7, 0x78, 0xa7, 0x70, 0x15, 0x37, 0x0b, 0xf7, - 0xe4, 0xb7, 0x84, 0x7c, 0x3c, 0x25, 0xaa, 0x8a, 0x2d, 0x24, 0xfb, 0x1e, - 0xe1, 0x39, 0xae, 0x86, 0x42, 0xe2, 0xbb, 0xa4, 0xcf, 0x2d, 0xc2, 0x51, - 0x84, 0x22, 0x19, 0x03, 0x42, 0x2a, 0xd2, 0x1c, 0xb6, 0x0d, 0xf1, 0x3a, - 0x41, 0xd2, 0x1b, 0x4c, 0x87, 0xd1, 0x8f, 0xad, 0x94, 0x23, 0x6e, 0x49, - 0x1b, 0x38, 0x98, 0xad, 0xa2, 0xf8, 0xc8, 0x7e, 0x3f, 0x4b, 0xeb, 0x6a, - 0x38, 0x54, 0x82, 0xe9, 0x31, 0x0e, 0x62, 0x05, 0xf9, 0xdb, 0xb9, 0x18, - 0xfb, 0x22, 0x90, 0xcf, 0x86, 0x93, 0x07, 0x85, 0x65, 0x55, 0x45, 0xac, - 0x25, 0xef, 0xe8, 0xcd, 0xd1, 0x33, 0xf8, 0x9f, 0xd6, 0x44, 0xa0, 0x1f, - 0xd1, 0x76, 0xc8, 0x55, 0xc6, 0x1e, 0xbc, 0x9b, 0x86, 0xec, 0x36, 0x4c, - 0xbc, 0x94, 0x06, 0x7c, 0x43, 0x83, 0x8a, 0x17, 0x64, 0x07, 0x08, 0x07, - 0x0f, 0x09, 0xb5, 0xfb, 0x02, 0xa5, 0xb3, 0x44, 0xbb, 0x39, 0x20, 0x81, - 0xe2, 0x91, 0x50, 0x7b, 0xce, 0x90, 0x3d, 0x7e, 0x57, 0xa8, 0xca, 0xac, - 0x60, 0x3f, 0xe5, 0x5c, 0xb2, 0x67, 0x2e, 0xa7, 0x98, 0xb8, 0xee, 0x9a, - 0x9c, 0x32, 0x48, 0x74, 0xed, 0x23, 0xba, 0x5e, 0xd4, 0xd5, 0xe0, 0x24, - 0xac, 0x25, 0xbd, 0x3a, 0xdf, 0x33, 0xb0, 0xa7, 0x64, 0x85, 0x1c, 0x06, - 0xcb, 0x0a, 0xa9, 0x2a, 0x03, 0xa6, 0x6c, 0x28, 0xe4, 0x1b, 0xbf, 0xb1, - 0x7a, 0xe3, 0xb2, 0xfe, 0x76, 0x5e, 0x21, 0x79, 0xc1, 0xef, 0x2c, 0x7c, - 0x59, 0xde, 0xb5, 0x20, 0x19, 0xbf, 0xb1, 0xee, 0x8c, 0xc3, 0xbf, 0xa4, - 0xe0, 0x4c, 0x55, 0x1b, 0xe8, 0x1e, 0x18, 0xda, 0x65, 0x35, 0x68, 0x12, - 0xc5, 0x29, 0x8d, 0xe2, 0xba, 0x2f, 0x71, 0xb9, 0xdd, 0x23, 0xce, 0xb5, - 0x07, 0xbb, 0x3e, 0xc8, 0x7b, 0x48, 0xcf, 0xe8, 0xde, 0x59, 0x48, 0x38, - 0xdf, 0x23, 0x5b, 0x73, 0x53, 0x4c, 0x45, 0xa1, 0xb1, 0xeb, 0x12, 0xe5, - 0xa1, 0x9b, 0x62, 0x9e, 0x7f, 0xea, 0x36, 0xa4, 0xaf, 0x79, 0xf0, 0xe0, - 0xca, 0xe9, 0x44, 0x2d, 0xc5, 0x75, 0x05, 0x67, 0xe3, 0x9d, 0x18, 0x2c, - 0x55, 0x91, 0x1d, 0x3e, 0x53, 0xde, 0xab, 0x35, 0x76, 0xbd, 0x9f, 0x5e, - 0xc2, 0x71, 0xe4, 0xd3, 0x7c, 0xbb, 0xd6, 0xbd, 0x53, 0x9c, 0xde, 0xe4, - 0x45, 0x1c, 0x07, 0x4a, 0xb2, 0xfc, 0x49, 0x1a, 0x1f, 0x2d, 0xd1, 0xb4, - 0xf2, 0x3a, 0x47, 0x53, 0xbf, 0xec, 0x68, 0x1a, 0x70, 0x53, 0x0c, 0xbe, - 0x78, 0xbd, 0xc0, 0x4b, 0xd7, 0x47, 0x12, 0x6e, 0xe1, 0xc1, 0xf9, 0xee, - 0x04, 0xd9, 0x49, 0x63, 0xca, 0x63, 0x50, 0xfc, 0x20, 0x93, 0x75, 0x68, - 0x09, 0xec, 0x9e, 0xc2, 0x23, 0x83, 0x7a, 0x17, 0xcc, 0x19, 0xb6, 0xa1, - 0x16, 0x0c, 0xce, 0x74, 0xc3, 0x2c, 0x39, 0x30, 0x11, 0x20, 0xe6, 0x4b, - 0x48, 0xb9, 0x8c, 0x96, 0x8e, 0x89, 0x7c, 0xaf, 0xab, 0xe2, 0xc3, 0xc4, - 0x7f, 0xf6, 0xa8, 0x1f, 0x5e, 0xd6, 0xf3, 0x59, 0x92, 0x51, 0x0b, 0x9e, - 0x29, 0x45, 0x29, 0xd6, 0xe9, 0x24, 0x17, 0x8d, 0xe2, 0x45, 0x88, 0xec, - 0x4b, 0xc6, 0xd6, 0x51, 0xf5, 0x08, 0xc5, 0x85, 0xdc, 0x04, 0xda, 0x91, - 0x0c, 0x28, 0x94, 0xbb, 0x5f, 0x9a, 0x8b, 0x01, 0xdb, 0xe8, 0x53, 0x35, - 0x93, 0xc0, 0x19, 0x09, 0x68, 0x6d, 0x30, 0x22, 0xfb, 0x1b, 0x48, 0x1f, - 0x75, 0x45, 0x0f, 0x1e, 0x18, 0xad, 0xc7, 0xfd, 0xe3, 0x5e, 0xec, 0x18, - 0xb5, 0x70, 0x39, 0xc6, 0xb6, 0xa1, 0xf6, 0x10, 0x89, 0x1d, 0xd5, 0x24, - 0xd7, 0x4d, 0xb1, 0x48, 0xc2, 0x23, 0x9c, 0xa8, 0x2a, 0x76, 0x13, 0x06, - 0x48, 0xb2, 0x5f, 0xe8, 0x34, 0x47, 0x68, 0xb7, 0x7e, 0x2b, 0x52, 0x01, - 0x19, 0xae, 0xa2, 0x8f, 0x62, 0x09, 0xfb, 0x31, 0xdf, 0xfb, 0x06, 0xb6, - 0xba, 0x7d, 0x70, 0x64, 0x64, 0xe4, 0x28, 0xff, 0x63, 0x91, 0x1b, 0x9d, - 0x4d, 0x12, 0xfd, 0x07, 0xfc, 0xd3, 0x63, 0x8d, 0xfe, 0x63, 0x14, 0x5f, - 0xef, 0xc9, 0x4a, 0xbc, 0x0e, 0xe3, 0x05, 0x9a, 0x5b, 0xc1, 0x93, 0x14, - 0xab, 0x1f, 0xa2, 0xf8, 0x73, 0xa2, 0x94, 0x17, 0x1c, 0x4f, 0x6c, 0x7e, - 0xb2, 0xc4, 0x5b, 0x96, 0x78, 0xcb, 0x12, 0x5f, 0x14, 0x17, 0x4e, 0x66, - 0x99, 0x8f, 0x2b, 0xe4, 0xa3, 0x09, 0xe2, 0xdd, 0x83, 0x6d, 0x44, 0xef, - 0x83, 0xe3, 0xd5, 0xb8, 0x8f, 0xe8, 0x2d, 0xea, 0x6a, 0xcf, 0x9f, 0x0b, - 0x0b, 0xf9, 0x98, 0x6a, 0xee, 0x14, 0x5e, 0x48, 0x4d, 0x96, 0xd5, 0xad, - 0x33, 0xcf, 0x64, 0xa7, 0x92, 0xcd, 0xf3, 0xfe, 0x24, 0x3c, 0xe8, 0xa3, - 0x67, 0x7a, 0xc7, 0xf1, 0xa9, 0x44, 0x3c, 0x79, 0x88, 0xc7, 0x83, 0xba, - 0x9a, 0x58, 0x4e, 0x71, 0xfd, 0x82, 0x16, 0x29, 0x5f, 0x70, 0xe0, 0xeb, - 0x24, 0x0f, 0x9d, 0xe5, 0xd1, 0x44, 0xfc, 0x3c, 0x40, 0x58, 0xc7, 0x6f, - 0x30, 0x9f, 0x91, 0xe8, 0xaf, 0x89, 0xf7, 0x48, 0x31, 0xe0, 0x3f, 0x77, - 0xb8, 0xd1, 0xff, 0xe2, 0x50, 0x85, 0xfe, 0x9d, 0x44, 0xff, 0x74, 0xcc, - 0xc2, 0x21, 0xa2, 0xff, 0x29, 0xa2, 0xbf, 0x8f, 0xe3, 0xf9, 0x1c, 0xfd, - 0x27, 0x4a, 0xbc, 0xee, 0x97, 0xf1, 0x30, 0x4f, 0x7f, 0x3d, 0xb6, 0x8e, - 0xcf, 0xcb, 0xcb, 0xb2, 0xee, 0xd4, 0x9f, 0xb5, 0xbe, 0x4d, 0x32, 0x5b, - 0x52, 0x64, 0xb9, 0x31, 0x8e, 0x8b, 0x1c, 0xb9, 0x07, 0x7d, 0x12, 0xbc, - 0x3e, 0x2c, 0x28, 0x72, 0x2e, 0x08, 0xe1, 0x59, 0xd2, 0xef, 0x29, 0xca, - 0x65, 0xcf, 0x94, 0xae, 0xcd, 0x6d, 0xac, 0xeb, 0x31, 0xd2, 0xb1, 0x3a, - 0x61, 0x52, 0x6c, 0x4b, 0x95, 0x92, 0xd8, 0x3b, 0x8e, 0xe4, 0xb4, 0xfe, - 0xaf, 0x29, 0xc0, 0x2c, 0x22, 0xfb, 0xaa, 0x4a, 0x2a, 0x9a, 0x17, 0x77, - 0x4d, 0x05, 0xd0, 0x5f, 0x5a, 0x8f, 0x2c, 0xc5, 0x9b, 0x9d, 0x14, 0x9f, - 0x3f, 0x8c, 0x25, 0x77, 0xf8, 0x11, 0x21, 0xfd, 0x06, 0x70, 0x2f, 0x3d, - 0x73, 0x70, 0x9c, 0xe9, 0x57, 0xe6, 0xf4, 0x1c, 0xc0, 0x3d, 0x74, 0x6d, - 0xdf, 0xb8, 0x8c, 0x17, 0xf4, 0x27, 0x08, 0xcf, 0x54, 0xf0, 0xc5, 0xdd, - 0x59, 0x28, 0xe4, 0x9e, 0x84, 0xff, 0x22, 0xd1, 0x17, 0xe8, 0xf7, 0xb6, - 0x92, 0xd7, 0x3f, 0x38, 0x86, 0xef, 0x2d, 0x31, 0xfc, 0x58, 0x40, 0x58, - 0xec, 0x76, 0x3d, 0x42, 0x76, 0xef, 0xc4, 0x40, 0x49, 0xc2, 0x77, 0xa6, - 0xbc, 0x78, 0x68, 0xf4, 0x53, 0xcb, 0x1d, 0x77, 0xe2, 0xb6, 0x26, 0x2f, - 0x1e, 0x9c, 0x4a, 0x62, 0xff, 0x38, 0x42, 0x55, 0xb1, 0x61, 0x8a, 0xdd, - 0x95, 0x7c, 0x50, 0x4d, 0xbc, 0x1f, 0x18, 0xf7, 0xf9, 0xfb, 0x0e, 0xb3, - 0x0c, 0xd6, 0x07, 0x3d, 0x40, 0xb9, 0x2a, 0xe6, 0xc0, 0x36, 0xdd, 0xb1, - 0xa0, 0x8a, 0x0c, 0xfd, 0x09, 0x9a, 0x6f, 0x12, 0x8e, 0x57, 0x97, 0x20, - 0x72, 0xa4, 0xc1, 0x51, 0xce, 0x2d, 0x40, 0x3d, 0x1e, 0x9a, 0x49, 0x62, - 0x98, 0x6c, 0xf4, 0x81, 0xd1, 0xc1, 0xef, 0xd5, 0x51, 0x0c, 0xf1, 0xb7, - 0xaa, 0x7d, 0x6f, 0x08, 0x03, 0xf9, 0x88, 0x07, 0x3b, 0xa7, 0x7c, 0xfe, - 0x1d, 0x87, 0xad, 0x75, 0x6c, 0x4f, 0xdb, 0x67, 0xea, 0x71, 0xdf, 0x38, - 0x5d, 0x1b, 0x65, 0x1b, 0x26, 0x5b, 0x8b, 0x54, 0x11, 0x6f, 0xe1, 0xa4, - 0x87, 0xf0, 0x92, 0x23, 0x56, 0x4d, 0xf2, 0xf0, 0xe0, 0x1e, 0xdb, 0x16, - 0x14, 0x6c, 0x1b, 0xb7, 0xf0, 0xa6, 0x1e, 0x45, 0x8e, 0xec, 0xfa, 0xc8, - 0xb8, 0x3a, 0xdb, 0x41, 0x58, 0xe7, 0x6d, 0x87, 0x7a, 0xa4, 0xc9, 0x91, - 0x44, 0x7d, 0x1b, 0xc5, 0xf8, 0x7a, 0xcb, 0xba, 0xbb, 0xb5, 0xb9, 0xff, - 0xe7, 0x44, 0x73, 0x9d, 0xb1, 0x08, 0xe5, 0x3a, 0x35, 0x07, 0x34, 0x0f, - 0xb8, 0xa5, 0xeb, 0x71, 0x7e, 0x21, 0xc7, 0x41, 0x8e, 0xe5, 0x01, 0x7f, - 0x7d, 0xa6, 0x92, 0xe3, 0xea, 0x8b, 0x8d, 0xfe, 0xba, 0x4c, 0xd0, 0x5f, - 0x57, 0x84, 0xdf, 0x5d, 0x04, 0x7e, 0x4c, 0xf1, 0x65, 0x41, 0xdb, 0x6f, - 0xac, 0x54, 0xbd, 0x8d, 0x07, 0xfd, 0xcf, 0x8f, 0xa9, 0x66, 0x19, 0xea, - 0x7e, 0x0a, 0x9b, 0x78, 0x7c, 0xc6, 0xe9, 0x3f, 0x4e, 0xd8, 0xaf, 0x5e, - 0x8b, 0x62, 0x1f, 0xe9, 0x73, 0x17, 0xd9, 0xc2, 0xaf, 0xdb, 0x80, 0x03, - 0x99, 0x70, 0x48, 0x17, 0x3d, 0x34, 0x31, 0xb0, 0xa7, 0x48, 0x31, 0x5f, - 0x4a, 0x52, 0x10, 0x53, 0xa3, 0x94, 0xd6, 0x90, 0xce, 0xb8, 0x60, 0x2e, - 0xac, 0xe8, 0xe4, 0xbe, 0xec, 0x29, 0xcb, 0xaf, 0x69, 0x13, 0x45, 0xd2, - 0xd9, 0xc3, 0x25, 0x1f, 0x06, 0x08, 0x0f, 0x2c, 0x20, 0x0c, 0xf9, 0x20, - 0xd9, 0xc5, 0x03, 0xa3, 0x0e, 0xa2, 0x8f, 0xc7, 0x25, 0x91, 0x5c, 0x54, - 0xc1, 0xa2, 0x0f, 0x4d, 0xb1, 0x5d, 0x92, 0x1d, 0x91, 0x2d, 0x3e, 0x4b, - 0x39, 0xff, 0x99, 0xcf, 0x61, 0x10, 0x55, 0x31, 0xaf, 0xe6, 0xfe, 0x8a, - 0x3c, 0x06, 0xc7, 0x99, 0x67, 0xf5, 0x08, 0xa4, 0x24, 0x6e, 0xd2, 0x7f, - 0x49, 0x39, 0x81, 0x79, 0x27, 0x0c, 0x3c, 0x1e, 0xc5, 0xa3, 0x59, 0xc2, - 0x34, 0xb1, 0xcb, 0xd6, 0x3d, 0x01, 0x96, 0x01, 0xf3, 0xb3, 0xca, 0xc1, - 0xf9, 0xb3, 0x9e, 0xb0, 0xef, 0xff, 0xbb, 0xdd, 0xdd, 0x65, 0xa5, 0x6c, - 0x2c, 0x4b, 0x18, 0x9b, 0xec, 0x29, 0x75, 0xd5, 0x7e, 0x1e, 0xb4, 0xce, - 0x07, 0x38, 0x5f, 0xd7, 0x23, 0x75, 0xd5, 0x16, 0xd8, 0x96, 0xb0, 0x44, - 0x6f, 0xdd, 0xfd, 0xa0, 0x02, 0xb6, 0x87, 0xe8, 0x35, 0xf6, 0x50, 0x45, - 0x34, 0x29, 0xd8, 0x31, 0xc3, 0xf6, 0x6b, 0x5d, 0x59, 0x62, 0xfc, 0xd6, - 0xfa, 0x64, 0xb5, 0x76, 0xe4, 0x97, 0xe8, 0xa2, 0xeb, 0x01, 0x7c, 0x87, - 0xfc, 0xe8, 0x5e, 0xe2, 0x73, 0x47, 0xfb, 0xbd, 0xb6, 0xdf, 0xee, 0x28, - 0xad, 0xa1, 0xeb, 0x2c, 0xef, 0x0e, 0xec, 0xcf, 0xea, 0x48, 0x67, 0xcb, - 0x9c, 0x87, 0xc8, 0xe6, 0xe3, 0xf8, 0x11, 0xc5, 0xd9, 0x67, 0x4b, 0x8c, - 0xc9, 0x12, 0x36, 0x1e, 0xfb, 0x61, 0xa9, 0x05, 0xcf, 0x91, 0x4f, 0x3e, - 0x43, 0x31, 0xf7, 0x07, 0x36, 0x4e, 0x73, 0x8a, 0x43, 0x69, 0xc2, 0xa4, - 0x43, 0x26, 0xd2, 0xf9, 0x10, 0x3c, 0x87, 0xc3, 0xfb, 0x77, 0x08, 0xf5, - 0xc7, 0x24, 0x2f, 0xff, 0x81, 0xe9, 0xa5, 0xa8, 0x3a, 0xac, 0x4e, 0x10, - 0xdd, 0xfe, 0x47, 0xa7, 0x35, 0xc2, 0xd4, 0x41, 0xff, 0xbe, 0xbc, 0xe2, - 0xdf, 0x3b, 0x16, 0xf0, 0xef, 0x9d, 0xae, 0x27, 0x3f, 0x5a, 0xe4, 0x1f, - 0x9c, 0x0e, 0xfa, 0x77, 0xa7, 0x1b, 0xfd, 0xbb, 0xf3, 0x6d, 0x08, 0xd5, - 0xc3, 0x5c, 0x44, 0x39, 0xe2, 0xbe, 0xd1, 0x6f, 0x62, 0xa2, 0xae, 0x12, - 0xf7, 0xfb, 0xc9, 0x36, 0x6a, 0xc9, 0x0e, 0x57, 0x4a, 0xb7, 0xa1, 0xbc, - 0xb0, 0x72, 0xed, 0x3b, 0x74, 0xed, 0xa1, 0x56, 0xf8, 0xff, 0xc2, 0x8e, - 0xbd, 0xc0, 0x73, 0x64, 0x6b, 0xcf, 0xb6, 0x52, 0x5d, 0x79, 0xd5, 0xd6, - 0x9c, 0x14, 0x6f, 0x2d, 0x4b, 0x6f, 0x13, 0x08, 0xb6, 0x6e, 0x00, 0x16, - 0xcc, 0xd7, 0x92, 0xc9, 0x09, 0x67, 0x6b, 0x12, 0x4b, 0xb4, 0x8d, 0x78, - 0x42, 0xa1, 0x54, 0xd3, 0xfa, 0x75, 0xcc, 0x3d, 0x83, 0xef, 0x8c, 0x7a, - 0x90, 0xda, 0xac, 0x60, 0x9a, 0xb0, 0xca, 0x76, 0x9a, 0x7f, 0x59, 0xac, - 0x59, 0x99, 0x21, 0x3d, 0x24, 0x15, 0xbe, 0x46, 0x3e, 0xd1, 0xba, 0x8a, - 0x7c, 0xa2, 0xb2, 0xfe, 0xd3, 0xa4, 0xaf, 0xdc, 0x4c, 0x14, 0x7b, 0x4b, - 0x3f, 0x91, 0x2a, 0xf9, 0x45, 0x9d, 0x48, 0xe2, 0xac, 0x3d, 0xf6, 0xe9, - 0xec, 0x1b, 0x56, 0xc8, 0xb6, 0x3b, 0x81, 0xc7, 0x56, 0x44, 0xf6, 0xff, - 0x27, 0xa9, 0x81, 0xf8, 0x22, 0xd9, 0x65, 0xed, 0x3a, 0xb2, 0x76, 0xb1, - 0xf6, 0x2f, 0xf0, 0x23, 0x85, 0x65, 0x3b, 0x20, 0xf6, 0x53, 0xbd, 0x4a, - 0xa5, 0x53, 0xed, 0x02, 0xed, 0x30, 0x9e, 0xe9, 0xe6, 0x6b, 0x01, 0xff, - 0x81, 0xb1, 0xa4, 0x14, 0xd0, 0xa0, 0xb8, 0x8c, 0x0e, 0x71, 0x60, 0x7a, - 0x91, 0xff, 0xd1, 0xb1, 0x0d, 0xe2, 0xd1, 0xe9, 0x46, 0xff, 0x60, 0xba, - 0x53, 0x0c, 0xe6, 0x37, 0x0b, 0x73, 0xe2, 0x5b, 0xc2, 0x9c, 0x4e, 0x09, - 0x33, 0xdf, 0x43, 0x9f, 0x5b, 0xc4, 0x58, 0x7e, 0x40, 0xec, 0xcd, 0xf3, - 0xfc, 0xa4, 0x2b, 0x5a, 0xe3, 0x87, 0x14, 0x7b, 0x9f, 0xa3, 0xd8, 0xfb, - 0x2c, 0xc5, 0xde, 0x67, 0xc8, 0xde, 0x7f, 0x70, 0x15, 0xe3, 0xb2, 0x8d, - 0x27, 0x19, 0x9b, 0xf8, 0xff, 0xbc, 0x78, 0x86, 0xf4, 0xcd, 0xb2, 0xfb, - 0x37, 0x64, 0xdb, 0x2c, 0x93, 0x87, 0x38, 0x57, 0x90, 0x9e, 0xde, 0xb7, - 0x6d, 0xf9, 0xb1, 0x15, 0x8c, 0xa5, 0x06, 0xc4, 0x56, 0xa2, 0x2f, 0xe9, - 0x24, 0x0c, 0xa4, 0x11, 0x3e, 0xc9, 0x0e, 0x88, 0xbb, 0xf3, 0x7c, 0xfd, - 0x20, 0x76, 0x52, 0x4d, 0x78, 0x28, 0x16, 0xee, 0xee, 0x25, 0xec, 0xb4, - 0x89, 0xb0, 0xd3, 0xb2, 0x98, 0x8c, 0x8b, 0x2d, 0x9f, 0x58, 0x58, 0x88, - 0xe4, 0xfd, 0x71, 0x75, 0x62, 0xa2, 0x92, 0x6f, 0x73, 0x19, 0x70, 0xdd, - 0x8e, 0xda, 0x1a, 0x4d, 0x3d, 0x91, 0x44, 0x78, 0x7f, 0x5c, 0x82, 0xe9, - 0x36, 0x5c, 0xb8, 0xcf, 0xae, 0x15, 0xd7, 0x63, 0x74, 0x54, 0x60, 0x5b, - 0x6b, 0xf2, 0x8f, 0x5c, 0x24, 0xab, 0xb7, 0xdb, 0x11, 0x20, 0xf5, 0x0a, - 0x99, 0xea, 0xfa, 0x4e, 0x92, 0x5e, 0x07, 0xe5, 0xdc, 0x27, 0xb2, 0xab, - 0xd0, 0xd0, 0x2a, 0x93, 0x0e, 0x9d, 0xb8, 0xb3, 0x78, 0x13, 0xe9, 0x31, - 0x72, 0xe4, 0x79, 0x78, 0xfd, 0x2f, 0x8c, 0x19, 0x18, 0xca, 0xe2, 0x7b, - 0x3e, 0xaa, 0xe1, 0xee, 0x25, 0xfc, 0xf4, 0x03, 0xa2, 0x61, 0x63, 0x6b, - 0xa4, 0x93, 0x6a, 0x79, 0xc5, 0x6b, 0xb8, 0x31, 0xd2, 0xe4, 0x87, 0xa2, - 0xa5, 0xc4, 0x2b, 0xf9, 0xc8, 0x91, 0x1d, 0xd2, 0xb7, 0xc4, 0xcf, 0xa7, - 0x0d, 0x3c, 0x5a, 0xea, 0x11, 0x7f, 0x31, 0x2d, 0x83, 0x74, 0x43, 0x71, - 0x4b, 0xc7, 0x11, 0xa2, 0xcb, 0x45, 0x18, 0xc9, 0xf5, 0xfb, 0x02, 0x8b, - 0xb5, 0x24, 0xbe, 0xb3, 0x8a, 0x7d, 0xa1, 0x12, 0xd3, 0x9c, 0xab, 0x80, - 0xfd, 0x64, 0x93, 0x0d, 0x99, 0x0e, 0xb1, 0x84, 0xbe, 0x5f, 0xa4, 0xbc, - 0x96, 0x94, 0x3a, 0x45, 0x03, 0x61, 0xd3, 0x85, 0x93, 0x5b, 0xc4, 0x82, - 0x22, 0x63, 0x51, 0x28, 0x0b, 0x49, 0x46, 0x0b, 0x8b, 0x17, 0x1d, 0x95, - 0x1a, 0xc0, 0xc5, 0xb6, 0x64, 0xfa, 0x0c, 0xd9, 0x7f, 0x88, 0x62, 0xfb, - 0x8e, 0x58, 0x27, 0xe1, 0x64, 0xbe, 0x3e, 0x20, 0x86, 0x48, 0x8e, 0x13, - 0x2e, 0xdb, 0x76, 0xfc, 0x4f, 0x8c, 0xc1, 0xd5, 0x60, 0x20, 0xe4, 0xa6, - 0xdc, 0xf1, 0xdf, 0xdb, 0x22, 0xe6, 0xf3, 0x52, 0x97, 0xc8, 0xe5, 0x03, - 0xfe, 0x23, 0x63, 0x9c, 0x67, 0x3a, 0xc4, 0x11, 0xd2, 0x79, 0x96, 0x74, - 0x9e, 0x25, 0x9d, 0x67, 0x48, 0xe7, 0x99, 0x2f, 0xd1, 0xf9, 0x3e, 0xd2, - 0xf9, 0xee, 0xfc, 0xaf, 0x6c, 0x1d, 0x3a, 0x0d, 0x03, 0x59, 0xca, 0xcb, - 0x23, 0x4d, 0x15, 0xfe, 0x3e, 0x24, 0x59, 0xbc, 0x14, 0xfb, 0x86, 0x13, - 0x5e, 0x83, 0x62, 0x6b, 0x17, 0x3d, 0xf3, 0x95, 0x39, 0x1b, 0x57, 0xfc, - 0xc3, 0x63, 0x1d, 0x62, 0x98, 0xfc, 0x6e, 0x84, 0xe6, 0x1f, 0x21, 0xbf, - 0x1b, 0x4c, 0xff, 0x9f, 0xd8, 0x0d, 0xdb, 0x1d, 0x4c, 0x2f, 0xe5, 0xad, - 0x6a, 0xb2, 0x4b, 0xa7, 0xc1, 0x36, 0xb4, 0x59, 0x24, 0x8f, 0x7e, 0x4b, - 0x24, 0x8f, 0xa5, 0x44, 0xb2, 0xd0, 0x43, 0x9f, 0x5b, 0xc4, 0x2d, 0x76, - 0x1d, 0x3a, 0x20, 0x3a, 0x0a, 0x01, 0xff, 0x38, 0xad, 0x33, 0x4e, 0x7c, - 0x3c, 0x46, 0xeb, 0x3c, 0x66, 0xdb, 0x2e, 0x15, 0x99, 0x5e, 0x5e, 0x8b, - 0xed, 0x8c, 0xed, 0xeb, 0x32, 0xd1, 0xce, 0xbe, 0x71, 0xb5, 0xc7, 0x43, - 0x7f, 0x37, 0x38, 0xa0, 0xed, 0x74, 0x56, 0x78, 0xe2, 0xdc, 0xcf, 0xb9, - 0x9e, 0xe3, 0xb0, 0x62, 0xd7, 0x82, 0xcf, 0x5e, 0xc5, 0x00, 0x8c, 0x07, - 0x20, 0x2f, 0x30, 0xb6, 0x18, 0xdf, 0x69, 0xfa, 0x1f, 0x34, 0x5f, 0x3f, - 0xf4, 0x55, 0x90, 0x03, 0xc6, 0x5f, 0x1a, 0x63, 0x4d, 0x14, 0xa7, 0x69, - 0x4e, 0x39, 0x03, 0x68, 0x19, 0x81, 0xdd, 0x09, 0x41, 0x38, 0x76, 0x11, - 0xf9, 0x25, 0xd3, 0xaf, 0x76, 0x52, 0x36, 0xc1, 0xd2, 0x21, 0xc8, 0x4b, - 0x8c, 0x9d, 0xb0, 0xb2, 0x90, 0x6b, 0x8d, 0x3e, 0x5c, 0x19, 0x0a, 0x07, - 0x3b, 0xa1, 0xa6, 0x2e, 0x38, 0xd4, 0x32, 0xe5, 0xb7, 0xfe, 0xdd, 0x42, - 0xed, 0x9b, 0x15, 0xdc, 0x27, 0x62, 0xec, 0xbe, 0x13, 0x2d, 0x36, 0x86, - 0xef, 0x43, 0x73, 0x1e, 0x54, 0x87, 0x0b, 0xbc, 0x43, 0x73, 0xbe, 0xa8, - 0x7f, 0xc0, 0x39, 0x21, 0x49, 0x58, 0xf0, 0x0b, 0x73, 0x81, 0x70, 0x0c, - 0xcf, 0xc3, 0x73, 0x84, 0x95, 0x3e, 0x9a, 0xf7, 0x4d, 0x47, 0x73, 0xff, - 0xa0, 0x50, 0x13, 0x5f, 0x9c, 0x6f, 0x59, 0x1e, 0x62, 0x59, 0xc6, 0xb4, - 0xaa, 0x35, 0x2f, 0xe3, 0x21, 0xe9, 0x1d, 0x4d, 0x4b, 0xbe, 0x86, 0x10, - 0x96, 0x51, 0x9d, 0x1c, 0x2d, 0x32, 0x0f, 0xbb, 0x70, 0x46, 0x57, 0xbb, - 0xa9, 0x1a, 0xa5, 0xba, 0xa5, 0x03, 0x07, 0x29, 0xf6, 0x3e, 0x5a, 0xe2, - 0x3e, 0xd7, 0x80, 0x58, 0x3e, 0x44, 0x7e, 0x69, 0xdb, 0x13, 0xe4, 0x06, - 0xe3, 0x61, 0xdc, 0x40, 0xeb, 0xfb, 0xa9, 0xf6, 0x79, 0x9d, 0xd6, 0x97, - 0x32, 0xea, 0x00, 0xad, 0x9f, 0x7a, 0x43, 0x84, 0x67, 0x89, 0xaf, 0x9e, - 0x75, 0x8e, 0xe6, 0xbe, 0x5d, 0x42, 0x4d, 0x12, 0xe9, 0xe4, 0xc7, 0xbc, - 0xf6, 0xc3, 0xcc, 0x0b, 0x7d, 0x52, 0x9d, 0x43, 0x76, 0xd4, 0x54, 0x90, - 0x45, 0x64, 0x78, 0x3d, 0xf6, 0x4e, 0xad, 0xc7, 0x1e, 0xf2, 0xc7, 0x03, - 0x7a, 0x2d, 0x42, 0x75, 0xa8, 0xa9, 0xd5, 0x30, 0x7b, 0x41, 0x13, 0x8e, - 0x1d, 0x2d, 0x8d, 0x64, 0xc7, 0xa7, 0x1b, 0xaa, 0xf0, 0x91, 0xd5, 0xab, - 0xad, 0xef, 0xa4, 0x88, 0x78, 0x83, 0x07, 0xe3, 0x0e, 0xf2, 0xef, 0x5f, - 0xfc, 0x9a, 0x02, 0xaa, 0xc7, 0x60, 0xdc, 0x96, 0x10, 0x97, 0xf2, 0x67, - 0x9d, 0x15, 0x3f, 0x68, 0xc2, 0x15, 0x05, 0xb5, 0x41, 0x6d, 0x39, 0x66, - 0x15, 0x99, 0xe2, 0x85, 0x69, 0xd7, 0x64, 0x37, 0xe7, 0xba, 0xd1, 0x40, - 0xf5, 0xf1, 0x9d, 0xb1, 0x5f, 0x5b, 0x9f, 0x2c, 0xe6, 0xe7, 0x4e, 0x7a, - 0x2a, 0xb1, 0xf3, 0xcb, 0xe6, 0x88, 0x53, 0xbc, 0x69, 0xa6, 0x7a, 0xb6, - 0x9a, 0x82, 0x74, 0x27, 0xe5, 0x23, 0xb5, 0x27, 0x4d, 0xf5, 0x68, 0x5f, - 0xa4, 0x59, 0x77, 0x08, 0x37, 0xca, 0x81, 0x70, 0x7f, 0x2f, 0x92, 0xdb, - 0xfd, 0x73, 0x74, 0x3c, 0x2b, 0x34, 0x17, 0x3d, 0xc7, 0xf3, 0x5c, 0x63, - 0x4f, 0x27, 0xc9, 0x9e, 0xf8, 0x3e, 0x7f, 0xbf, 0x7a, 0x5f, 0xfe, 0x8a, - 0xf1, 0x97, 0xff, 0xe4, 0x8f, 0x97, 0x7d, 0xd9, 0xf5, 0x8f, 0xbf, 0xe4, - 0xfa, 0xff, 0xae, 0xae, 0x2f, 0xd7, 0x39, 0x6d, 0xcc, 0x90, 0x94, 0xb8, - 0x8f, 0xe9, 0x34, 0x2e, 0xaf, 0xd9, 0xa3, 0xfd, 0x0e, 0xc5, 0x34, 0xee, - 0x63, 0x70, 0x9e, 0x3e, 0x6f, 0xf7, 0x31, 0x4e, 0x7d, 0x0e, 0xb3, 0x72, - 0x6c, 0xf1, 0x88, 0xea, 0x11, 0xd3, 0xaa, 0xd7, 0xbe, 0x4d, 0x75, 0xcd, - 0x2e, 0xf4, 0xc6, 0x74, 0x0c, 0x67, 0xd5, 0xee, 0xdb, 0xa0, 0x25, 0x37, - 0x0b, 0x9a, 0xa8, 0xe8, 0x11, 0x8e, 0x91, 0xb9, 0x7b, 0xba, 0x49, 0xb5, - 0x5a, 0x19, 0x55, 0x14, 0x9b, 0x9c, 0x9a, 0x22, 0xa3, 0x18, 0x90, 0x9d, - 0xc5, 0xa0, 0xec, 0x2e, 0x36, 0xca, 0x55, 0x34, 0xce, 0x37, 0xa2, 0xce, - 0xde, 0x86, 0x5d, 0x98, 0x6d, 0xf3, 0x9a, 0x0d, 0x86, 0xaa, 0x34, 0x38, - 0x76, 0x61, 0x4f, 0x8c, 0x9f, 0xed, 0xa0, 0x9a, 0x0d, 0xa2, 0x2e, 0x43, - 0xc8, 0xd8, 0x10, 0xd8, 0xdb, 0xae, 0x0e, 0x2c, 0x95, 0xb4, 0xce, 0x5f, - 0x09, 0xa7, 0xec, 0x29, 0x42, 0xf8, 0x33, 0x12, 0x8e, 0xb4, 0xc3, 0xe3, - 0x59, 0xa5, 0xf6, 0x9d, 0x16, 0x03, 0x78, 0x2a, 0x16, 0xe9, 0xde, 0x26, - 0x42, 0xb2, 0x97, 0xee, 0xb9, 0x32, 0x14, 0x7f, 0x33, 0xa6, 0xc7, 0xb5, - 0x4a, 0x0d, 0x4a, 0x22, 0x89, 0x5e, 0x4d, 0xd3, 0x47, 0x20, 0xd3, 0x9a, - 0x10, 0x55, 0x19, 0x75, 0xf6, 0x4d, 0xc2, 0x54, 0x9f, 0x2c, 0x1b, 0x40, - 0x6b, 0x5b, 0x64, 0x7f, 0x8f, 0xa4, 0xc9, 0x84, 0xf5, 0x84, 0x33, 0xe3, - 0xc3, 0xca, 0xc3, 0xf3, 0x7d, 0x1d, 0xcb, 0xfa, 0x30, 0x56, 0x26, 0xbd, - 0x40, 0xae, 0x29, 0x46, 0x65, 0x1f, 0xe1, 0xfa, 0xe6, 0xc3, 0x8c, 0xb3, - 0x2c, 0x6b, 0x47, 0xac, 0xfc, 0x75, 0x2f, 0x5a, 0x88, 0xc7, 0x6e, 0x4c, - 0xa5, 0x19, 0x77, 0x19, 0x98, 0xa4, 0x9a, 0x48, 0x1b, 0x6a, 0xc4, 0x71, - 0x8a, 0x43, 0x33, 0x69, 0xee, 0xff, 0xf4, 0x91, 0x8c, 0x7b, 0x88, 0xfe, - 0x2d, 0x54, 0x0f, 0xa7, 0x28, 0x7e, 0xb1, 0x8c, 0x7b, 0xc9, 0xee, 0x21, - 0x7b, 0x8d, 0x3a, 0xe3, 0xe6, 0x61, 0xc8, 0x1e, 0xc3, 0x6b, 0x5c, 0x77, - 0x18, 0x75, 0x94, 0xf7, 0x0d, 0xaa, 0x78, 0x10, 0x8d, 0x44, 0xf4, 0x8b, - 0x88, 0x04, 0x5f, 0x24, 0x7d, 0x0c, 0x6a, 0xc0, 0x6e, 0xbb, 0xd6, 0x76, - 0xc2, 0xcc, 0x73, 0x0d, 0x0d, 0x4f, 0x55, 0x7b, 0x1d, 0xde, 0xc9, 0x45, - 0xed, 0x1e, 0x92, 0x49, 0xf5, 0xcf, 0x0b, 0xba, 0x9a, 0x9a, 0xa0, 0xe7, - 0xb6, 0x2a, 0xff, 0x65, 0x5f, 0x75, 0x1c, 0x32, 0xc5, 0x34, 0xb2, 0xbd, - 0x3f, 0xf5, 0xbe, 0x49, 0x36, 0x7a, 0xfb, 0xd8, 0x9f, 0x79, 0xaf, 0xc4, - 0x27, 0xbc, 0x1f, 0xc4, 0x2d, 0x2b, 0x41, 0x78, 0xb4, 0x87, 0xea, 0xed, - 0x0f, 0x87, 0x4c, 0xef, 0xc5, 0x38, 0xf7, 0x81, 0x9d, 0xf8, 0x3d, 0xfa, - 0xfd, 0xe4, 0x90, 0x8c, 0x4d, 0x85, 0x06, 0xb8, 0x86, 0x1d, 0x98, 0xd2, - 0x6f, 0x44, 0xaf, 0x22, 0xe1, 0xee, 0xe8, 0x49, 0xb2, 0x49, 0x89, 0xc6, - 0x1c, 0xa2, 0xdf, 0xdc, 0xd3, 0x7a, 0x0c, 0xdb, 0x94, 0x69, 0xef, 0x3b, - 0x71, 0xa6, 0x17, 0x4c, 0xaf, 0x2c, 0x69, 0xb7, 0x62, 0xeb, 0x6d, 0x5c, - 0x5b, 0xd9, 0xff, 0x9e, 0x17, 0xdb, 0xeb, 0x71, 0x3c, 0xd7, 0x80, 0xe7, - 0x73, 0xa6, 0xe7, 0xb5, 0xf6, 0x28, 0xfa, 0x86, 0x2c, 0xbc, 0xac, 0x9b, - 0x03, 0x55, 0x64, 0xe7, 0x09, 0xaa, 0xaf, 0xc2, 0x6d, 0xdc, 0x4b, 0x40, - 0xc4, 0x81, 0x48, 0x3f, 0x81, 0xcc, 0x3b, 0x28, 0x74, 0xa5, 0x6a, 0xa8, - 0x4e, 0x3b, 0x27, 0x2c, 0xf7, 0xf6, 0x76, 0x27, 0xd1, 0x00, 0x6c, 0x28, - 0xb4, 0x90, 0xdc, 0xa2, 0xd8, 0x14, 0x91, 0xb1, 0xb1, 0xa0, 0xe3, 0xf9, - 0xb4, 0x0f, 0xb7, 0x17, 0xe2, 0x84, 0xbd, 0x15, 0xa2, 0x3d, 0x81, 0x52, - 0x3a, 0x80, 0x6f, 0x14, 0x1a, 0x49, 0xde, 0x41, 0xdc, 0x58, 0x08, 0xe1, - 0x44, 0x9a, 0xf3, 0xb7, 0xe1, 0xd9, 0x1a, 0x6f, 0x44, 0x67, 0x41, 0xc3, - 0x74, 0x1a, 0x9e, 0x07, 0xe2, 0x21, 0x74, 0x14, 0xa2, 0x28, 0x10, 0x86, - 0xbb, 0x95, 0xe6, 0xbc, 0x9d, 0x74, 0xd2, 0x52, 0x08, 0x60, 0x69, 0x84, - 0x22, 0x72, 0xc1, 0x27, 0x06, 0x08, 0x5b, 0x25, 0x0a, 0xf5, 0xb8, 0x38, - 0xcc, 0x76, 0xae, 0x18, 0x7b, 0x72, 0x0a, 0x42, 0x05, 0xac, 0x94, 0x01, - 0x0a, 0xd6, 0x91, 0x54, 0x81, 0xe8, 0x3d, 0xd8, 0x5e, 0xe9, 0xe1, 0x2e, - 0x2f, 0x7c, 0xc6, 0x6f, 0x2d, 0xe9, 0xe9, 0xca, 0xe1, 0x69, 0xef, 0x27, - 0x71, 0x8e, 0x4d, 0x9f, 0xae, 0x79, 0xfd, 0x30, 0x10, 0x1d, 0x67, 0xde, - 0xec, 0xd8, 0xc8, 0xf1, 0xb0, 0x45, 0xc6, 0xaf, 0x2c, 0xaa, 0x41, 0x43, - 0x53, 0xbc, 0x57, 0xa0, 0xf9, 0x88, 0x0e, 0x05, 0x49, 0x5a, 0xfb, 0x96, - 0xc2, 0x0f, 0xad, 0xad, 0x0b, 0x83, 0xb8, 0x39, 0x52, 0x91, 0xd5, 0x39, - 0xd2, 0xe1, 0xe4, 0x70, 0x03, 0x66, 0x88, 0x06, 0x97, 0xe1, 0x36, 0x8e, - 0x8d, 0x59, 0xd8, 0xa0, 0x9b, 0xde, 0xd7, 0xda, 0x97, 0xe3, 0xfe, 0xc3, - 0x83, 0x67, 0xdd, 0xa4, 0xd7, 0x59, 0xfd, 0x0e, 0x3c, 0x3a, 0x8e, 0xaf, - 0x35, 0x00, 0x8f, 0x04, 0xc1, 0x3d, 0x6b, 0x35, 0x74, 0x02, 0x91, 0xce, - 0x07, 0x10, 0x51, 0x34, 0xa1, 0xea, 0x2f, 0x0b, 0x24, 0xab, 0x8d, 0xc8, - 0xd9, 0x5b, 0x80, 0x33, 0x6e, 0xf2, 0xe0, 0xdb, 0x0b, 0x4e, 0x92, 0x51, - 0x10, 0xa5, 0x61, 0x37, 0x1c, 0xe4, 0x27, 0x97, 0x34, 0x6c, 0xa8, 0x25, - 0x59, 0x3b, 0x84, 0x4c, 0x7a, 0x6e, 0xc1, 0xb1, 0xa1, 0x79, 0x59, 0xf9, - 0x70, 0x13, 0xc9, 0xf0, 0xa9, 0x21, 0x6b, 0x97, 0x16, 0x0b, 0x90, 0xac, - 0x15, 0xa2, 0x6f, 0x5e, 0x4e, 0x2c, 0xbf, 0x79, 0x39, 0xdd, 0x81, 0x3d, - 0x33, 0x2c, 0xb7, 0xff, 0x1b, 0x79, 0x4d, 0xdb, 0x76, 0xb7, 0x61, 0x2c, - 0x8a, 0x86, 0xc3, 0x57, 0x65, 0xc7, 0xf4, 0x3d, 0x42, 0x7c, 0x7c, 0xcf, - 0xbf, 0x3a, 0xd2, 0xf7, 0xbe, 0xf0, 0x11, 0x3d, 0x0a, 0xe9, 0xe6, 0x03, - 0x17, 0x63, 0x77, 0x92, 0xc9, 0x55, 0x19, 0x07, 0x49, 0xc6, 0xc1, 0x71, - 0x96, 0xf5, 0xa7, 0x6b, 0xae, 0x90, 0x7c, 0x5f, 0x27, 0x5c, 0x76, 0x43, - 0x2c, 0x8a, 0x9a, 0xc3, 0x6a, 0xb2, 0xc1, 0x11, 0x4e, 0xd4, 0x0a, 0x50, - 0x55, 0x82, 0x96, 0x1a, 0x7c, 0xc8, 0x72, 0xd6, 0x49, 0xce, 0xdf, 0x1b, - 0x24, 0x7e, 0xd6, 0xd3, 0x7c, 0x1b, 0x48, 0xce, 0x49, 0xe2, 0xff, 0x16, - 0x7b, 0xde, 0x46, 0x9a, 0x77, 0x0b, 0xd5, 0x1e, 0xd3, 0xde, 0x4b, 0x44, - 0x4f, 0xf4, 0x33, 0x5a, 0x08, 0x8d, 0x47, 0x82, 0xef, 0x53, 0x8d, 0x7d, - 0xa3, 0x3d, 0x4e, 0xa1, 0x71, 0x4c, 0xfb, 0xcf, 0xab, 0x24, 0xed, 0xcb, - 0xfa, 0xcd, 0xdf, 0x02, 0xf7, 0x1c, 0x4c, 0xf4, 0x50, 0x1d, 0xb1, 0x85, - 0x6a, 0x25, 0x99, 0x72, 0x9b, 0x89, 0x1f, 0xc4, 0xd5, 0x68, 0x9d, 0xe0, - 0xf8, 0x67, 0x92, 0x1f, 0x96, 0xa9, 0x4e, 0x0a, 0x87, 0x66, 0x10, 0x94, - 0xa5, 0xa2, 0x4c, 0x78, 0xb0, 0x51, 0x76, 0x14, 0xc9, 0x5f, 0x83, 0x3d, - 0x84, 0xa7, 0x9d, 0x78, 0x31, 0xef, 0xc4, 0x2b, 0xe9, 0x2d, 0x38, 0x50, - 0xf2, 0x10, 0x6e, 0x36, 0x3d, 0xce, 0x55, 0x13, 0xee, 0x4a, 0x4c, 0x5e, - 0x86, 0xae, 0x91, 0x87, 0x51, 0x9d, 0x71, 0x76, 0x53, 0x3e, 0xd5, 0x6f, - 0x21, 0xb9, 0x6c, 0x28, 0xf2, 0xfd, 0x46, 0x64, 0xd2, 0x29, 0xc2, 0x40, - 0x61, 0xaa, 0x81, 0x9c, 0x98, 0x68, 0x68, 0xb4, 0xfb, 0xba, 0x39, 0xba, - 0x96, 0x2b, 0x7d, 0xb1, 0xdf, 0x7c, 0xc7, 0x5c, 0x9f, 0xb9, 0x0f, 0xfb, - 0xb2, 0x3d, 0x84, 0x4d, 0xb7, 0x50, 0x7c, 0xaf, 0xd0, 0x38, 0x1d, 0xef, - 0xc6, 0xbe, 0xbc, 0x71, 0x35, 0x7e, 0x4c, 0xda, 0xf1, 0xa3, 0x1f, 0x55, - 0xed, 0xbc, 0x7f, 0xb5, 0x05, 0x77, 0xa5, 0x81, 0xf7, 0xd2, 0xdc, 0x4f, - 0x24, 0x4c, 0x41, 0xf9, 0xe0, 0x90, 0xce, 0x39, 0x74, 0x0b, 0x96, 0xe6, - 0x2d, 0xe4, 0x75, 0x0b, 0x67, 0x75, 0x8d, 0x72, 0x34, 0xe7, 0xea, 0x01, - 0xa1, 0x51, 0x7e, 0x36, 0x9d, 0xfd, 0x88, 0xb4, 0xb3, 0x8e, 0x1e, 0x9e, - 0xdb, 0x87, 0xea, 0xb7, 0xf7, 0xa1, 0x66, 0xd2, 0x0e, 0x3c, 0x45, 0x8a, - 0x78, 0x3e, 0x1b, 0x0e, 0xbd, 0x07, 0x6b, 0x97, 0xc3, 0x50, 0x13, 0x4e, - 0x07, 0xef, 0xcf, 0xf0, 0xfe, 0x94, 0xd6, 0xbd, 0xd4, 0xa1, 0xea, 0x45, - 0xd1, 0xdc, 0xf3, 0x16, 0xca, 0x1b, 0x65, 0xa8, 0xa1, 0xd7, 0x10, 0x89, - 0x76, 0xf2, 0x1e, 0x44, 0xa9, 0x92, 0xbb, 0x97, 0xcd, 0xe5, 0x6e, 0x2d, - 0xef, 0x15, 0xe1, 0x61, 0x09, 0x13, 0x53, 0x96, 0x29, 0x91, 0xfd, 0x4e, - 0xd1, 0x9c, 0x3f, 0xce, 0xee, 0x42, 0x36, 0x66, 0x59, 0xb7, 0xc7, 0xb5, - 0xbe, 0x06, 0x07, 0xfe, 0x90, 0x32, 0x39, 0xc8, 0xe6, 0x53, 0xe4, 0x6b, - 0xa1, 0x1d, 0xed, 0xa6, 0xe5, 0xb6, 0xeb, 0x0a, 0xee, 0x4f, 0x76, 0x89, - 0x96, 0xc2, 0x16, 0xb1, 0x9c, 0xb0, 0x5b, 0xe8, 0xd8, 0x66, 0xd1, 0x74, - 0xb4, 0x82, 0xdd, 0x22, 0x85, 0xcf, 0x7a, 0xa8, 0x37, 0xa7, 0x2d, 0xa4, - 0x89, 0xaf, 0xa7, 0xfe, 0x0e, 0x5f, 0xac, 0x8b, 0x7e, 0x5c, 0xd7, 0xce, - 0xbe, 0xf8, 0x30, 0x8e, 0xa5, 0xd9, 0xce, 0xfb, 0xb1, 0x87, 0xe4, 0xb3, - 0x62, 0x88, 0xf7, 0xc3, 0xd4, 0xb3, 0x83, 0x08, 0xf7, 0xbd, 0x2a, 0xd4, - 0x72, 0x01, 0xcd, 0x7a, 0x8d, 0x83, 0xe3, 0xab, 0x3a, 0xd0, 0xe4, 0xa8, - 0xd0, 0x9f, 0xc8, 0x83, 0xe2, 0x69, 0x85, 0x87, 0x95, 0xf9, 0xa5, 0x64, - 0xab, 0xa6, 0xe7, 0x52, 0xbc, 0xb9, 0xbf, 0x1a, 0x1b, 0xc4, 0x07, 0xd3, - 0x21, 0x78, 0x0f, 0x27, 0x17, 0xfa, 0xd1, 0x21, 0xde, 0xb3, 0xeb, 0xc5, - 0x4e, 0xf1, 0x4e, 0xbe, 0x5b, 0x5c, 0x9e, 0xe8, 0x42, 0x64, 0xf8, 0x3e, - 0xf1, 0xf6, 0x04, 0xd3, 0xd9, 0x23, 0xce, 0x4f, 0x73, 0x9f, 0xd4, 0xc2, - 0x1e, 0x9d, 0xfb, 0xa2, 0x8b, 0xab, 0xe0, 0xb7, 0x70, 0x4c, 0x67, 0x7d, - 0x72, 0x9f, 0xb0, 0xd2, 0x5f, 0xda, 0x10, 0xcf, 0x59, 0x4e, 0x8d, 0x7b, - 0xc5, 0x41, 0x9b, 0xdf, 0x29, 0xc2, 0xd1, 0xd3, 0x13, 0x5b, 0xc4, 0xf1, - 0x7c, 0x85, 0xd7, 0xc9, 0x3c, 0xdb, 0xaf, 0x4c, 0x3a, 0xfe, 0x62, 0x9e, - 0x36, 0xa1, 0xb4, 0x07, 0xe1, 0xb6, 0xfb, 0x51, 0x16, 0x46, 0xf4, 0x48, - 0xe8, 0x65, 0x04, 0xe1, 0x2c, 0xb2, 0x6d, 0x5b, 0x78, 0x5a, 0x77, 0xc1, - 0x31, 0x22, 0x93, 0x8c, 0xc8, 0x96, 0xfc, 0x2e, 0x48, 0x93, 0x5c, 0x1b, - 0x7c, 0xbd, 0x8a, 0xfb, 0x14, 0x21, 0x89, 0xbf, 0x7f, 0xd1, 0xe6, 0x5c, - 0x94, 0x0f, 0xb8, 0xbf, 0xfe, 0x57, 0xee, 0x8a, 0xed, 0xb1, 0x5d, 0xcd, - 0xf7, 0xc4, 0x29, 0xd7, 0xb6, 0x73, 0x2f, 0xdc, 0x83, 0x99, 0x9c, 0x9b, - 0x5b, 0x14, 0x1e, 0x77, 0xbb, 0x85, 0x0b, 0xba, 0x93, 0xea, 0x97, 0x87, - 0x28, 0x47, 0x49, 0x90, 0xb5, 0x3b, 0x50, 0x1c, 0x73, 0x4a, 0xbc, 0x5f, - 0xf5, 0xb3, 0x18, 0xf7, 0x10, 0x80, 0x43, 0xc4, 0xc3, 0xf7, 0x73, 0x21, - 0x6c, 0xa2, 0xba, 0x2b, 0x64, 0xd7, 0x18, 0xbf, 0x87, 0x53, 0x39, 0x87, - 0xa0, 0xba, 0xc2, 0x91, 0x58, 0x6d, 0xe1, 0x4a, 0x5b, 0x24, 0xca, 0x7d, - 0x68, 0x85, 0x72, 0xd6, 0xde, 0x7c, 0x1d, 0x7e, 0x96, 0xab, 0xc3, 0x2b, - 0x39, 0x0b, 0x07, 0x63, 0x83, 0x3d, 0x5e, 0x8a, 0x95, 0xcb, 0x62, 0x2e, - 0xec, 0x88, 0x98, 0x8a, 0x17, 0x51, 0x5c, 0x48, 0x5c, 0x87, 0x54, 0x20, - 0xdc, 0x39, 0x88, 0x7a, 0xbc, 0x91, 0x03, 0x61, 0x09, 0x78, 0x96, 0xd2, - 0x1c, 0x6f, 0xc7, 0xcc, 0x7e, 0x17, 0xe1, 0xd8, 0x9f, 0x0b, 0xc4, 0x6b, - 0x60, 0xb9, 0xcf, 0xc4, 0x29, 0x57, 0x17, 0xea, 0xd0, 0x95, 0xab, 0x47, - 0x0f, 0xe5, 0xac, 0x75, 0xab, 0xe3, 0x78, 0x2b, 0xeb, 0x13, 0x2b, 0xb3, - 0x83, 0x3d, 0x0a, 0xcd, 0xe9, 0x6a, 0x53, 0xfb, 0x9f, 0x22, 0xe0, 0x26, - 0x23, 0x4c, 0xe6, 0x8e, 0x07, 0xfc, 0x14, 0x77, 0x8f, 0x8b, 0x4f, 0xf1, - 0x04, 0xd9, 0xe3, 0x3d, 0xba, 0x5a, 0xbe, 0xe4, 0x88, 0x9c, 0xdd, 0x08, - 0x75, 0xe0, 0x16, 0x61, 0x46, 0x6b, 0x29, 0x9e, 0x34, 0x54, 0x62, 0x85, - 0x19, 0x11, 0x32, 0x61, 0x73, 0x27, 0x3c, 0x9a, 0x89, 0xce, 0x76, 0x96, - 0xa9, 0x07, 0x9e, 0xa3, 0x64, 0x47, 0xd2, 0x17, 0xfb, 0xfb, 0x75, 0x78, - 0x9d, 0xf2, 0xe5, 0xb9, 0x1c, 0xf7, 0xe6, 0xdd, 0xc6, 0xbb, 0x94, 0x03, - 0x5e, 0x8a, 0x0d, 0x86, 0x38, 0xf6, 0xe7, 0x63, 0xf8, 0xe7, 0x64, 0x96, - 0x8d, 0x3e, 0x5a, 0xf3, 0x2e, 0xc1, 0xeb, 0x20, 0xb9, 0xc4, 0xe0, 0xbe, - 0x9c, 0xcd, 0x0f, 0xc5, 0x63, 0xe6, 0xe9, 0xff, 0x27, 0xed, 0x8f, 0x54, - 0xc1, 0x5b, 0x4f, 0xba, 0x9c, 0xef, 0x69, 0x5e, 0xdb, 0xcf, 0xe4, 0x7a, - 0xa6, 0x82, 0x0f, 0xdd, 0x46, 0xb5, 0x78, 0x21, 0xc7, 0x36, 0x67, 0xe1, - 0x19, 0x5d, 0xa7, 0xda, 0x85, 0x6b, 0xf2, 0x7e, 0xaa, 0x5f, 0xb8, 0xcf, - 0x64, 0x7a, 0xce, 0x10, 0x85, 0xfb, 0x73, 0x58, 0x2b, 0xc3, 0xb1, 0xa2, - 0x0a, 0xe3, 0x98, 0x70, 0x3a, 0x09, 0x73, 0x70, 0xac, 0x65, 0x7f, 0x52, - 0x0c, 0x6d, 0x82, 0xeb, 0xcf, 0x4e, 0x98, 0xb6, 0x1f, 0x57, 0x8b, 0xfb, - 0xc9, 0x46, 0x5e, 0x8c, 0x55, 0x61, 0x82, 0xea, 0x1f, 0xc9, 0x30, 0x3d, - 0xdf, 0xa5, 0xe7, 0x13, 0xa3, 0xd8, 0x17, 0x84, 0xe3, 0x4f, 0x14, 0xfc, - 0x19, 0xde, 0x74, 0xc9, 0x74, 0x1d, 0x9e, 0xee, 0xb8, 0xe9, 0xdd, 0x18, - 0xaf, 0x16, 0xb7, 0xe6, 0x5a, 0xf0, 0xfe, 0x58, 0x1d, 0xd9, 0x77, 0x3d, - 0x96, 0x8c, 0x04, 0xf1, 0x36, 0xd1, 0x32, 0x40, 0xb4, 0x7c, 0xd2, 0x66, - 0x0e, 0x34, 0x40, 0xed, 0xa7, 0xba, 0xa8, 0x9b, 0xfb, 0xcd, 0x4f, 0xeb, - 0x6a, 0xe7, 0x6d, 0xc2, 0x0b, 0x2d, 0x92, 0x24, 0xd9, 0x5b, 0xd6, 0xb0, - 0xde, 0xac, 0xfb, 0xc0, 0xfd, 0xa3, 0x3b, 0x70, 0x68, 0x86, 0x69, 0x71, - 0x1b, 0xcb, 0xa7, 0xf9, 0x53, 0x36, 0xae, 0xb3, 0x3f, 0xbd, 0x73, 0x9f, - 0x30, 0x42, 0xf6, 0xe7, 0xa7, 0x6b, 0x42, 0xd3, 0xdc, 0xa7, 0x0e, 0x9b, - 0x6e, 0xf1, 0x53, 0x17, 0xf7, 0xab, 0x93, 0xe0, 0xff, 0x57, 0x5d, 0x95, - 0x7e, 0xdf, 0x1d, 0x30, 0xed, 0x1e, 0xca, 0x15, 0xbb, 0x97, 0x1d, 0x22, - 0x37, 0x90, 0x89, 0x3f, 0x99, 0x30, 0x57, 0x20, 0x46, 0x05, 0x7c, 0xbd, - 0x6c, 0x2e, 0x31, 0x7a, 0xa8, 0x46, 0x90, 0x89, 0x5f, 0x13, 0xfb, 0xda, - 0x05, 0x0e, 0x69, 0x06, 0x5e, 0xcb, 0x73, 0x2c, 0x77, 0xe2, 0xfb, 0x69, - 0x35, 0x94, 0x12, 0xe1, 0xce, 0x5b, 0x84, 0x84, 0x50, 0x43, 0x0f, 0x0e, - 0x51, 0x5e, 0x99, 0x4e, 0x73, 0x1e, 0x71, 0xda, 0xe7, 0x05, 0x6a, 0x29, - 0x0e, 0x7d, 0x38, 0x54, 0x89, 0xfb, 0x85, 0xb8, 0xba, 0xff, 0xf7, 0x48, - 0xa7, 0x4f, 0x17, 0x78, 0x4e, 0x13, 0x9f, 0xac, 0x66, 0x1f, 0x56, 0xa3, - 0x29, 0xe9, 0x5e, 0x84, 0xa6, 0x38, 0xb6, 0xd0, 0x72, 0xb4, 0xd6, 0x91, - 0xac, 0x1b, 0xdd, 0xf1, 0x2e, 0xd1, 0x53, 0xfc, 0x67, 0xbc, 0x27, 0xa1, - 0x2c, 0x30, 0x36, 0x8b, 0xf5, 0x93, 0xdc, 0x53, 0xdc, 0x22, 0xba, 0x8b, - 0xdc, 0x57, 0x1c, 0x10, 0xbf, 0x5f, 0x64, 0x9f, 0x9f, 0xef, 0x2f, 0xce, - 0xeb, 0x9f, 0xfb, 0x8a, 0xa6, 0xe7, 0x05, 0x92, 0xfd, 0x03, 0x39, 0x8e, - 0xc9, 0x8e, 0xfb, 0xfd, 0x68, 0xc3, 0x84, 0x0b, 0x9e, 0xd3, 0xf1, 0xaf, - 0xe0, 0x76, 0xc2, 0x07, 0x4b, 0xb4, 0x8a, 0xfe, 0xd6, 0x4d, 0x48, 0x48, - 0xb4, 0x91, 0xd0, 0x17, 0xb0, 0x4e, 0x7b, 0x29, 0x9e, 0x65, 0xac, 0xbe, - 0x00, 0xeb, 0x92, 0xed, 0xcd, 0x2e, 0xf7, 0x28, 0x0e, 0x9b, 0x94, 0x57, - 0x3c, 0x98, 0xce, 0x2d, 0xa2, 0xda, 0xc0, 0xc2, 0x7e, 0xbd, 0x06, 0x55, - 0x76, 0x0c, 0xf0, 0x10, 0x9e, 0x84, 0xec, 0xa3, 0x79, 0xd2, 0xc3, 0x32, - 0xbc, 0x74, 0xef, 0x8c, 0x4e, 0x72, 0x69, 0xaf, 0xcc, 0xdd, 0x3c, 0xb1, - 0x12, 0x07, 0xc9, 0xe3, 0x6b, 0xb4, 0x28, 0x86, 0x14, 0x1f, 0xc5, 0x9a, - 0x3b, 0xe6, 0xe6, 0xf4, 0xd0, 0x60, 0x5e, 0xaf, 0xbf, 0xaa, 0xa2, 0x87, - 0x35, 0x72, 0xa5, 0x06, 0x93, 0xcd, 0x6a, 0x5a, 0x6b, 0x47, 0xfb, 0x16, - 0x74, 0x0e, 0xf9, 0xc4, 0x2b, 0xe9, 0xbb, 0xad, 0x50, 0x1d, 0x8d, 0x23, - 0x9b, 0x75, 0xcf, 0xd1, 0xdb, 0x34, 0x21, 0xf3, 0x58, 0xee, 0x79, 0xe0, - 0xc1, 0x9c, 0x84, 0xc0, 0xdc, 0xf5, 0xf8, 0x44, 0x08, 0x7a, 0x6b, 0x35, - 0x50, 0x2f, 0xe8, 0x1a, 0xcf, 0xcd, 0x6b, 0xc8, 0xa8, 0x23, 0x3f, 0xb9, - 0x33, 0x9e, 0xc0, 0xbb, 0x59, 0x27, 0x36, 0x52, 0x9e, 0xbf, 0x31, 0x6d, - 0xe0, 0x42, 0x29, 0x60, 0xcf, 0x21, 0x19, 0xf3, 0xe3, 0x9c, 0x34, 0xce, - 0x83, 0xc9, 0x89, 0x2f, 0xd2, 0x17, 0x20, 0x9a, 0x7f, 0x42, 0xdf, 0xf9, - 0xde, 0x45, 0xbb, 0x3f, 0x70, 0xea, 0x9a, 0xba, 0x4a, 0x1a, 0xe1, 0x9e, - 0x52, 0x25, 0x17, 0x74, 0xe8, 0xac, 0x4b, 0x3f, 0x66, 0x47, 0x4d, 0x5c, - 0x58, 0x5d, 0x8b, 0x4f, 0x46, 0x9b, 0x70, 0x7f, 0xce, 0x8b, 0x4b, 0xa3, - 0x16, 0x56, 0xb6, 0xe1, 0xee, 0x20, 0x61, 0xb1, 0x5a, 0xf2, 0xfb, 0xd7, - 0xa8, 0xf6, 0xa1, 0x78, 0x4a, 0x94, 0x46, 0x12, 0x1b, 0xc8, 0xae, 0xa3, - 0x31, 0xa4, 0x6e, 0x8a, 0x47, 0x42, 0x17, 0xf1, 0x3d, 0x8b, 0x62, 0xb1, - 0xe2, 0x30, 0xba, 0x84, 0xd3, 0xde, 0x67, 0xdc, 0x62, 0xef, 0x4b, 0x4a, - 0x93, 0x03, 0xc2, 0x51, 0xbc, 0xd6, 0xaf, 0xbf, 0x2c, 0x0f, 0x71, 0xee, - 0xe1, 0x1e, 0xc6, 0x88, 0xe5, 0xd2, 0xb8, 0x57, 0xb3, 0x59, 0xec, 0x9d, - 0xb8, 0x9a, 0x9b, 0xae, 0xe6, 0xa3, 0xdd, 0x73, 0x79, 0x68, 0x30, 0xff, - 0x8b, 0x2f, 0xe0, 0xa8, 0xd0, 0xdc, 0x7e, 0x07, 0xe7, 0x1f, 0x8f, 0x78, - 0x93, 0xcc, 0x61, 0x1f, 0xf9, 0xe0, 0x49, 0xfd, 0x74, 0x90, 0x32, 0x04, - 0x9c, 0xad, 0x02, 0x0f, 0xf2, 0x59, 0x93, 0x80, 0x85, 0xcd, 0x7a, 0xc5, - 0x1e, 0xda, 0xda, 0x5d, 0xe8, 0xa3, 0x9c, 0xe4, 0x8a, 0xf9, 0xc8, 0xd7, - 0x15, 0xbc, 0xaa, 0xb3, 0x0d, 0x6f, 0x9e, 0xcb, 0x49, 0xbc, 0x7f, 0x5e, - 0xd9, 0xeb, 0xfe, 0x7c, 0xdf, 0x7b, 0xde, 0x36, 0x75, 0x24, 0x17, 0xc2, - 0xfb, 0x76, 0x5c, 0xa3, 0xfa, 0x41, 0xa6, 0xda, 0x61, 0x23, 0x12, 0x0b, - 0x54, 0x6e, 0x6d, 0x10, 0xf6, 0x36, 0xf1, 0xef, 0xdb, 0xfb, 0x70, 0xdf, - 0x88, 0x84, 0x6a, 0x8d, 0xe3, 0xac, 0x89, 0x43, 0x75, 0x1c, 0xa7, 0xba, - 0xb0, 0x6b, 0xc4, 0x23, 0xce, 0xe4, 0x9c, 0x78, 0xa2, 0xfb, 0x11, 0x2c, - 0x68, 0xbd, 0x07, 0xb0, 0x6d, 0x90, 0xbf, 0x7f, 0x0b, 0xa9, 0x45, 0xbc, - 0x3e, 0xf7, 0xda, 0x04, 0x7c, 0xad, 0xcc, 0x07, 0xbc, 0xef, 0xd3, 0xfc, - 0xdb, 0x86, 0x9c, 0xe2, 0x62, 0xfa, 0x3f, 0x5b, 0x27, 0x02, 0x8c, 0x13, - 0xf8, 0x5e, 0x0d, 0xcc, 0x3a, 0x1e, 0xcb, 0x3a, 0xf4, 0x51, 0x6d, 0xda, - 0x87, 0x21, 0xa2, 0xeb, 0x9c, 0x3d, 0xd7, 0x95, 0x39, 0xfa, 0x7d, 0xa2, - 0x36, 0x23, 0x9b, 0x41, 0xa2, 0x45, 0x59, 0xdd, 0x8d, 0xda, 0xe2, 0xb5, - 0xf9, 0xb6, 0xc6, 0xc3, 0xfd, 0x4a, 0xd2, 0x15, 0xe5, 0x84, 0x5e, 0xbc, - 0x9b, 0x16, 0x78, 0xc7, 0xb6, 0xc1, 0x5e, 0x34, 0xe5, 0x6b, 0x00, 0x3b, - 0x86, 0xf0, 0xb8, 0xaf, 0x57, 0x6c, 0x5b, 0xea, 0xc3, 0x03, 0xc4, 0x4b, - 0x0d, 0xf1, 0xf2, 0x61, 0x6c, 0x29, 0xad, 0xc3, 0xd7, 0xfe, 0x9d, 0x3c, - 0x77, 0xd6, 0x68, 0x6e, 0x2e, 0x4a, 0x18, 0x7e, 0xae, 0xf7, 0x22, 0xd8, - 0x39, 0x12, 0xe9, 0xf1, 0x49, 0x6c, 0x87, 0x11, 0xdc, 0x3b, 0x79, 0x2b, - 0xdd, 0xe7, 0xb9, 0x82, 0xb8, 0x2b, 0xe3, 0x14, 0x6f, 0x51, 0xbd, 0x74, - 0x2a, 0x2d, 0x2d, 0x72, 0xe0, 0x39, 0xeb, 0x89, 0xc0, 0x2e, 0xdc, 0xa4, - 0x77, 0x61, 0x3b, 0xd9, 0x60, 0x47, 0xd3, 0x2e, 0x8c, 0x92, 0x0d, 0x6c, - 0xab, 0xa7, 0x1a, 0x2e, 0x56, 0xb2, 0x7a, 0x03, 0x2c, 0x47, 0x81, 0x4e, - 0xba, 0x5e, 0x47, 0x75, 0x9d, 0x14, 0x23, 0x6b, 0x23, 0xbf, 0x90, 0x35, - 0x35, 0x97, 0xc4, 0xef, 0xd8, 0x6b, 0xd6, 0x51, 0x9e, 0x76, 0x31, 0x3e, - 0xf0, 0x33, 0x4e, 0xf8, 0x22, 0x3d, 0xa6, 0x55, 0xa5, 0x69, 0xd1, 0x8d, - 0x52, 0x53, 0x6e, 0x86, 0x6c, 0x76, 0x7d, 0xeb, 0xb5, 0xcf, 0xcd, 0xcb, - 0x48, 0x87, 0xbb, 0x75, 0xca, 0x2a, 0x2b, 0x83, 0x50, 0x5a, 0xaf, 0xd5, - 0xfd, 0xfc, 0x1c, 0x4c, 0x73, 0x25, 0xae, 0x85, 0xa4, 0x88, 0x72, 0x37, - 0x2e, 0xd0, 0x1a, 0x41, 0x6c, 0x2d, 0x76, 0xa1, 0x77, 0xc4, 0xf1, 0x19, - 0x3e, 0xf1, 0xb3, 0x2d, 0x7f, 0xc6, 0xff, 0x8e, 0x91, 0x48, 0xa7, 0x77, - 0x8e, 0xff, 0xed, 0x93, 0x9f, 0xcd, 0x35, 0x90, 0xe1, 0xbc, 0xca, 0xf3, - 0xf1, 0xb9, 0xa1, 0x79, 0xf9, 0x06, 0xf1, 0x80, 0x3d, 0xdf, 0x61, 0x0f, - 0xfb, 0xb0, 0x8b, 0x7c, 0x7d, 0x43, 0xab, 0x89, 0x57, 0x13, 0xf7, 0x5b, - 0x3b, 0x6c, 0x19, 0xdc, 0x6f, 0x3f, 0xdf, 0xd9, 0x74, 0x76, 0x0e, 0xfb, - 0x54, 0xfa, 0xb0, 0xa7, 0x4a, 0x2d, 0xf6, 0x1e, 0xc3, 0x0f, 0x29, 0x0f, - 0x3e, 0xf7, 0xb9, 0x3e, 0xdf, 0x76, 0x17, 0xef, 0x4d, 0x3c, 0x5d, 0x92, - 0x85, 0x73, 0xa4, 0x5a, 0xb8, 0x46, 0x98, 0xb6, 0x8f, 0xe5, 0x8a, 0x8f, - 0xfd, 0x57, 0x24, 0x03, 0xbc, 0xcf, 0x58, 0xb1, 0xff, 0x68, 0xfb, 0xbd, - 0xc0, 0x51, 0xd3, 0x53, 0xb5, 0x0a, 0x54, 0xeb, 0x77, 0xdb, 0xf6, 0xb0, - 0xd0, 0x08, 0xac, 0x7d, 0xae, 0x89, 0xeb, 0x7d, 0xee, 0x0d, 0x6a, 0x6b, - 0xc7, 0x08, 0x80, 0x6e, 0x55, 0x78, 0x4d, 0xf5, 0x04, 0xf7, 0xeb, 0xb9, - 0x8f, 0x4f, 0x71, 0xd7, 0x5b, 0xb7, 0xca, 0xf4, 0x2c, 0x58, 0xe5, 0x14, - 0x8b, 0x33, 0x3d, 0x64, 0x7b, 0x1a, 0x12, 0x19, 0xd3, 0xdb, 0xb0, 0x2a, - 0x84, 0x87, 0x32, 0xf3, 0x31, 0xb9, 0x05, 0x2d, 0xe3, 0xc0, 0x0f, 0x33, - 0x41, 0x34, 0x8f, 0x86, 0xfb, 0x6f, 0x95, 0xc2, 0x03, 0xb3, 0x12, 0xdf, - 0xbb, 0xbc, 0x66, 0xa5, 0x8d, 0xc5, 0x3f, 0x5a, 0xb3, 0xc2, 0xfe, 0x0c, - 0x18, 0xd7, 0xe7, 0xef, 0x40, 0x7a, 0xc6, 0x33, 0x5b, 0x96, 0x2c, 0x3c, - 0x14, 0x93, 0x70, 0xb3, 0xfe, 0x6f, 0xc9, 0xb7, 0x04, 0xd9, 0xc6, 0xab, - 0x9c, 0x83, 0xed, 0x60, 0xb6, 0x64, 0x95, 0x86, 0x55, 0x99, 0x3a, 0x8a, - 0x49, 0xf5, 0x14, 0x9f, 0xea, 0x70, 0x85, 0x62, 0xd2, 0x8a, 0x36, 0x0b, - 0x8b, 0xdb, 0xcc, 0xbe, 0xc5, 0xe0, 0x3d, 0x68, 0xd5, 0x2c, 0x0a, 0xb5, - 0xa7, 0x4b, 0x52, 0xbb, 0xeb, 0x25, 0x05, 0xdb, 0x23, 0x3c, 0x77, 0xd0, - 0x58, 0x95, 0xaf, 0xe4, 0xd3, 0x4a, 0x5e, 0x75, 0xce, 0xe5, 0x53, 0xb7, - 0xa1, 0x4f, 0xab, 0x3f, 0x4e, 0x49, 0xbc, 0x6f, 0xd2, 0x83, 0x91, 0x6c, - 0x0a, 0x7b, 0xb3, 0x21, 0xfc, 0x3a, 0xe3, 0x26, 0xdb, 0x08, 0xeb, 0x3f, - 0x00, 0x8f, 0xf1, 0x19, 0xb1, 0x7c, 0x38, 0xfa, 0x90, 0xf4, 0x13, 0x94, - 0x9d, 0xea, 0x11, 0xaa, 0x12, 0x08, 0x37, 0x34, 0x87, 0x5e, 0xc4, 0x4f, - 0xec, 0x7d, 0x36, 0xa0, 0xc2, 0x43, 0x53, 0x1e, 0xc8, 0x65, 0x3c, 0xb3, - 0xb0, 0x7b, 0xb2, 0xbc, 0x6f, 0x2c, 0x61, 0xbd, 0x7e, 0x3f, 0xc9, 0x59, - 0xa0, 0xa9, 0xb5, 0x0e, 0xe5, 0x2d, 0x4e, 0x8c, 0x64, 0x38, 0x0f, 0x7f, - 0xbc, 0x46, 0x1e, 0x42, 0x79, 0x6e, 0x4f, 0x34, 0xe1, 0xa0, 0x0c, 0xfd, - 0x72, 0x11, 0x38, 0x48, 0xb1, 0x63, 0x53, 0xec, 0x37, 0x56, 0x05, 0x8f, - 0xca, 0xfe, 0xf4, 0x98, 0xc0, 0x02, 0x2d, 0x49, 0xf2, 0x70, 0xfa, 0x0f, - 0xa5, 0xa3, 0x76, 0x0e, 0x1e, 0xa1, 0xf9, 0x93, 0xf6, 0xfc, 0x91, 0xfd, - 0x4b, 0x25, 0x09, 0xd7, 0xb7, 0x1e, 0xc5, 0xc4, 0xc2, 0x0a, 0x0d, 0x41, - 0xc2, 0x04, 0x5c, 0xcb, 0xd6, 0x13, 0x8f, 0x9b, 0x1f, 0xe3, 0xbe, 0xe6, - 0x6f, 0xd7, 0xdc, 0x30, 0xce, 0x7e, 0xfd, 0xf1, 0x9a, 0x77, 0xd3, 0x6a, - 0xb2, 0x9e, 0xea, 0x87, 0x6a, 0x92, 0xc3, 0xbd, 0x43, 0xdc, 0x4f, 0xa8, - 0x37, 0x5e, 0x3f, 0xcc, 0x79, 0x59, 0x1d, 0x68, 0x10, 0x3e, 0x71, 0x73, - 0x46, 0xed, 0x63, 0xc2, 0x2f, 0x47, 0xd4, 0x20, 0xc9, 0xae, 0xf3, 0x1e, - 0xd1, 0xc7, 0x35, 0x8b, 0x2d, 0xb7, 0xeb, 0xf2, 0x15, 0xdc, 0x11, 0x9e, - 0xc3, 0x21, 0x51, 0x1b, 0x77, 0x58, 0xd6, 0x9e, 0x18, 0xe7, 0x71, 0xfb, - 0x4c, 0x00, 0x5d, 0xaf, 0x33, 0x96, 0x52, 0x6d, 0x31, 0xc8, 0xf4, 0xf1, - 0x19, 0x0f, 0x89, 0x6a, 0xd1, 0xec, 0xab, 0x73, 0xb8, 0xc4, 0x87, 0x7d, - 0x74, 0xbd, 0x6c, 0xe3, 0x13, 0x3e, 0xa7, 0xe8, 0x35, 0x94, 0xc7, 0xf8, - 0x6c, 0xe3, 0x6f, 0xd7, 0xac, 0x1f, 0x53, 0x43, 0x12, 0xf1, 0xb1, 0x97, - 0xf7, 0xe7, 0x69, 0xce, 0x69, 0x9d, 0xe9, 0xbe, 0xbc, 0x86, 0xfb, 0xb1, - 0x4b, 0x88, 0x6e, 0x2b, 0x1b, 0x66, 0x0c, 0x6a, 0xdb, 0x4a, 0x22, 0x4f, - 0x55, 0xfd, 0xe2, 0x0a, 0xaf, 0x2e, 0xd2, 0xc9, 0xb1, 0x74, 0x12, 0xa7, - 0xe2, 0x15, 0xfd, 0xac, 0xcb, 0x7f, 0x03, 0xa9, 0xfa, 0x0e, 0xe4, 0xb2, - 0x8a, 0x7f, 0x43, 0xa6, 0x03, 0xa3, 0xa4, 0xc3, 0xbb, 0x8b, 0x41, 0x7f, - 0x47, 0x46, 0x43, 0x6f, 0x91, 0xeb, 0x2b, 0x18, 0x7b, 0xc6, 0x26, 0xe7, - 0xea, 0xe0, 0x4a, 0x2e, 0x39, 0x90, 0xa9, 0xd8, 0x5c, 0x38, 0xef, 0x99, - 0x0d, 0x89, 0xca, 0xbc, 0x32, 0xad, 0x23, 0x0f, 0xfd, 0x89, 0x85, 0x85, - 0x6c, 0x0b, 0x77, 0x60, 0x6c, 0xdc, 0x6f, 0x2e, 0x36, 0x14, 0xac, 0x6a, - 0xfd, 0x73, 0x7a, 0xb6, 0x05, 0x1f, 0x1f, 0xff, 0x3a, 0xca, 0xdf, 0x24, - 0x7c, 0x94, 0x49, 0xa2, 0xb9, 0xf5, 0x16, 0xa4, 0xfe, 0x40, 0xc6, 0xd3, - 0x19, 0x1f, 0x9e, 0xcf, 0x54, 0xf6, 0xec, 0x7f, 0x94, 0x25, 0x3f, 0x24, - 0x1f, 0x78, 0xee, 0x4b, 0xf7, 0x49, 0x29, 0x9e, 0x3b, 0x78, 0x0f, 0xff, - 0x1f, 0x1e, 0x77, 0xde, 0x1e, 0xe7, 0x11, 0x75, 0x23, 0xf3, 0xf3, 0x5a, - 0xd0, 0x5a, 0xff, 0xbe, 0x67, 0x08, 0xf3, 0x81, 0x62, 0x48, 0xe5, 0x8c, - 0x83, 0x90, 0x47, 0xec, 0x7d, 0x23, 0xc2, 0xb9, 0x11, 0xfd, 0x02, 0x4c, - 0xb8, 0x09, 0x5f, 0x2d, 0x25, 0x59, 0x68, 0x99, 0x80, 0x5f, 0x2a, 0x2a, - 0xf4, 0xdf, 0xe8, 0x77, 0x92, 0x7c, 0x9c, 0xc5, 0x8f, 0x28, 0xa6, 0xb0, - 0x4f, 0x55, 0x72, 0x9c, 0x54, 0x7c, 0xc4, 0x4b, 0xc0, 0x87, 0x3e, 0x2b, - 0x36, 0x1d, 0xca, 0x2f, 0xf6, 0x32, 0x96, 0xc9, 0x65, 0x2a, 0xbf, 0x23, - 0x57, 0x7f, 0x93, 0x9e, 0x6d, 0x99, 0x8d, 0xd0, 0x6f, 0x96, 0xc5, 0x73, - 0x56, 0x6a, 0x33, 0xcb, 0x2b, 0xe0, 0x7f, 0x83, 0xe4, 0x3f, 0x46, 0x34, - 0x66, 0x69, 0x8d, 0xd7, 0x69, 0xcd, 0x4c, 0xf1, 0x10, 0x8d, 0xe1, 0x7b, - 0x24, 0x67, 0xdb, 0x76, 0x0f, 0x7b, 0xf9, 0x7c, 0xc2, 0xf3, 0x19, 0x60, - 0x30, 0x6b, 0xaa, 0xce, 0xb9, 0x73, 0x9d, 0x83, 0x94, 0x2f, 0xab, 0x28, - 0x16, 0xbd, 0x19, 0xdf, 0x8e, 0x1b, 0x73, 0x6a, 0xd2, 0x24, 0x3c, 0x96, - 0x52, 0x20, 0x48, 0x77, 0x64, 0xc3, 0x01, 0xe3, 0xdd, 0x74, 0x23, 0xf1, - 0x14, 0x0e, 0x5d, 0xa0, 0xf1, 0xa6, 0x53, 0xc6, 0x81, 0x51, 0x07, 0x2e, - 0xf0, 0x1e, 0xb2, 0xa8, 0x3c, 0x6f, 0x82, 0xc7, 0xce, 0x7f, 0xaf, 0xa6, - 0xba, 0x2e, 0x9c, 0xa0, 0xac, 0x6a, 0xd6, 0x10, 0x6e, 0xcf, 0xb7, 0x3f, - 0x82, 0x43, 0x54, 0xeb, 0xef, 0x88, 0x85, 0x90, 0xac, 0x8b, 0x53, 0xbd, - 0xd1, 0xdc, 0x7f, 0x09, 0xff, 0xcd, 0x2a, 0xf3, 0x3e, 0xbc, 0x08, 0x27, - 0x2e, 0xe1, 0x53, 0xcb, 0xa1, 0x69, 0x67, 0xa7, 0xa0, 0x95, 0x2f, 0xa0, - 0x79, 0xe0, 0x13, 0xbc, 0x67, 0xf1, 0x1e, 0xbd, 0xec, 0x70, 0x10, 0x06, - 0x0c, 0x2b, 0x4e, 0x04, 0x50, 0x0e, 0x38, 0xb0, 0x49, 0xe7, 0xde, 0xb4, - 0x3a, 0xf0, 0x24, 0x61, 0xf9, 0x77, 0x44, 0x73, 0xdf, 0x87, 0x38, 0x6f, - 0x4d, 0xd4, 0xf1, 0xba, 0x02, 0x89, 0xeb, 0x9b, 0xcf, 0xba, 0xa1, 0x76, - 0xba, 0x84, 0x96, 0x68, 0x70, 0xfc, 0x95, 0x75, 0x3e, 0xf0, 0xa9, 0xa5, - 0x45, 0x3e, 0x25, 0x1c, 0xa4, 0x05, 0x27, 0xc9, 0xf6, 0xfb, 0x30, 0x4f, - 0x9b, 0xa8, 0x86, 0x57, 0x27, 0x1a, 0x18, 0xf7, 0x99, 0x9e, 0x7d, 0x44, - 0xdb, 0x6b, 0x84, 0x03, 0x76, 0xc4, 0x2e, 0x59, 0xc9, 0x85, 0x7c, 0xfe, - 0x4f, 0xa9, 0xae, 0xf4, 0xc0, 0xb9, 0x6f, 0x72, 0x07, 0xee, 0x4a, 0x3b, - 0x49, 0x4e, 0xf3, 0x78, 0xcd, 0x45, 0x31, 0x98, 0x63, 0x7f, 0xf9, 0x3a, - 0x2a, 0xcd, 0x24, 0x2a, 0xf1, 0xb1, 0x87, 0xe2, 0xc2, 0x6e, 0x3b, 0x17, - 0xc0, 0xbb, 0x64, 0x55, 0x2b, 0x3e, 0x19, 0x7f, 0xd3, 0x4b, 0xbe, 0xb4, - 0x4e, 0x6b, 0x83, 0x08, 0x66, 0x4c, 0x51, 0x6b, 0x38, 0xf0, 0x61, 0xbb, - 0xda, 0x29, 0x39, 0x06, 0x70, 0x7d, 0xcc, 0xb4, 0x7c, 0x9a, 0xd6, 0xd3, - 0x22, 0x22, 0xdd, 0x45, 0x11, 0x45, 0x75, 0xd1, 0x27, 0x57, 0x17, 0x5b, - 0x64, 0x6f, 0xd1, 0xf4, 0x28, 0xab, 0xb6, 0x53, 0xdd, 0xb2, 0x8b, 0x6a, - 0x5b, 0x1f, 0xd5, 0xd7, 0xaa, 0x7e, 0x11, 0x6e, 0x92, 0x7f, 0x08, 0xfb, - 0x4a, 0x06, 0x9c, 0x99, 0x9d, 0x70, 0x65, 0xc2, 0xca, 0x5e, 0xec, 0x42, - 0x32, 0x58, 0xc1, 0xb6, 0x32, 0xe9, 0xaa, 0xaa, 0x9d, 0xb1, 0xcc, 0x76, - 0x9c, 0x9f, 0x60, 0x7c, 0x9e, 0xc0, 0xd6, 0x34, 0xff, 0x86, 0xf7, 0xc5, - 0xb8, 0x81, 0x93, 0x54, 0x3b, 0x79, 0x5a, 0x1b, 0x48, 0x0f, 0x8d, 0x18, - 0x2c, 0x09, 0x36, 0x2b, 0xd2, 0x05, 0xbc, 0x27, 0xdb, 0x65, 0x1c, 0x9c, - 0xa2, 0x44, 0x42, 0xf9, 0xca, 0x99, 0x51, 0x28, 0x4e, 0xc8, 0xf0, 0x69, - 0x3e, 0xfa, 0x1d, 0xe0, 0x73, 0x4b, 0x64, 0x67, 0xbf, 0x5d, 0xd3, 0x62, - 0xc7, 0x9a, 0x7a, 0xaa, 0x75, 0xde, 0x21, 0x5e, 0x58, 0x16, 0x06, 0xaa, - 0x47, 0xe6, 0x6b, 0xc2, 0xf5, 0xb7, 0x55, 0x23, 0x48, 0x73, 0x32, 0x0e, - 0xac, 0x9c, 0x57, 0x5d, 0x1f, 0x6b, 0x45, 0x21, 0x27, 0xe6, 0x30, 0xd6, - 0xa0, 0xea, 0xc3, 0x3a, 0x1c, 0xa2, 0xda, 0xdf, 0xaf, 0x6d, 0x45, 0x46, - 0x29, 0x7b, 0x7f, 0x11, 0xe7, 0x1a, 0x00, 0xde, 0x5e, 0xc2, 0x50, 0x43, - 0xe9, 0xaf, 0x72, 0xcc, 0xf4, 0xdc, 0x1d, 0xd7, 0x71, 0x24, 0x47, 0x21, - 0x4a, 0x5b, 0x87, 0xda, 0xb6, 0x2e, 0x7c, 0x58, 0xc7, 0xf8, 0x97, 0x62, - 0x15, 0xd1, 0xb3, 0x77, 0x2a, 0x60, 0x9f, 0xab, 0xd8, 0x57, 0x9a, 0xa7, - 0xf9, 0x5a, 0x5a, 0xbf, 0x8c, 0x46, 0x96, 0xc9, 0x3f, 0x44, 0x23, 0xd9, - 0x2c, 0x61, 0x9e, 0x5c, 0xba, 0x17, 0x2f, 0xa7, 0x79, 0xde, 0x70, 0x52, - 0x17, 0x0a, 0xf7, 0xe6, 0x6d, 0x99, 0x98, 0x53, 0xbc, 0x06, 0xaf, 0x3f, - 0xbf, 0x4e, 0x80, 0x6a, 0x85, 0x7f, 0xec, 0x5a, 0x14, 0x37, 0x72, 0xeb, - 0xa8, 0xee, 0x8c, 0x42, 0xfb, 0xfd, 0x32, 0xe9, 0x83, 0x7b, 0xd5, 0x4b, - 0x09, 0xf3, 0xc2, 0xf3, 0x4a, 0x9c, 0xcf, 0x30, 0x5b, 0xbb, 0x64, 0xc3, - 0xb2, 0x5c, 0xed, 0x9a, 0xf2, 0x36, 0xd8, 0x0e, 0x7d, 0xbc, 0xe7, 0xe1, - 0xd9, 0xdb, 0xee, 0xc3, 0x41, 0xca, 0x81, 0x4f, 0xa5, 0x9b, 0x4d, 0xae, - 0xfd, 0xc0, 0x38, 0x54, 0xa4, 0xe8, 0xd9, 0x7f, 0x55, 0xcd, 0x3e, 0xbb, - 0xa7, 0xb4, 0x13, 0x52, 0xa6, 0xa7, 0x9a, 0xeb, 0x0d, 0x37, 0xd5, 0xc9, - 0x83, 0x69, 0xa6, 0xd7, 0xda, 0xe5, 0xa4, 0xb9, 0x76, 0xc7, 0xb5, 0xd9, - 0x1b, 0xc9, 0x2e, 0x1a, 0x0c, 0x96, 0x63, 0x00, 0x4f, 0xd0, 0xd8, 0x50, - 0x89, 0x65, 0x79, 0xa8, 0x9a, 0xfb, 0x9e, 0xfb, 0x48, 0xbf, 0xb5, 0xd9, - 0xca, 0x3c, 0xd9, 0x52, 0x1f, 0x96, 0x0e, 0xbd, 0x58, 0x5d, 0xa9, 0x7d, - 0xb8, 0x2e, 0xef, 0xc7, 0xbe, 0x74, 0x00, 0x53, 0xe9, 0x66, 0xe5, 0x05, - 0xfb, 0xcc, 0x40, 0xa5, 0x47, 0x36, 0x98, 0x9e, 0x1f, 0x13, 0xc0, 0xe4, - 0xd5, 0xef, 0x2c, 0x9f, 0x4a, 0xef, 0xf4, 0x94, 0x8d, 0xf9, 0x65, 0x4c, - 0x04, 0x2a, 0x78, 0x88, 0x62, 0x85, 0xf7, 0x51, 0xd2, 0xeb, 0x3b, 0xa4, - 0x57, 0x89, 0xf4, 0xfa, 0x82, 0xfe, 0x23, 0xc6, 0x2c, 0x9e, 0x3d, 0x71, - 0x1f, 0xef, 0x13, 0x99, 0x04, 0x5a, 0xec, 0x31, 0x99, 0xb8, 0x13, 0xe7, - 0x86, 0xf8, 0x6c, 0xe2, 0x47, 0x6b, 0x5e, 0x4a, 0x5b, 0xeb, 0x66, 0x62, - 0xcd, 0xa9, 0x77, 0x08, 0x4f, 0x9b, 0x7f, 0xa0, 0xea, 0xe7, 0xc9, 0x4f, - 0xb3, 0xa3, 0x7f, 0x88, 0xf3, 0x75, 0xcd, 0xca, 0xcf, 0x61, 0x7a, 0x1e, - 0x8f, 0x3f, 0x42, 0x35, 0x3f, 0xd5, 0x0d, 0x6d, 0xff, 0x92, 0x9c, 0x2c, - 0x0e, 0x87, 0xd6, 0x3c, 0xfb, 0x02, 0xfe, 0x23, 0xce, 0x2f, 0x0e, 0xeb, - 0x2f, 0x80, 0xc7, 0x54, 0xea, 0xf1, 0xf0, 0xf4, 0x7d, 0x7c, 0x9e, 0x2a, - 0x48, 0x69, 0xb4, 0xb2, 0x9f, 0x95, 0xe6, 0xfd, 0x37, 0x81, 0x89, 0x2d, - 0x54, 0x4b, 0xdb, 0xe7, 0x58, 0xe1, 0x7d, 0x92, 0xfc, 0x22, 0x3a, 0xcc, - 0xe3, 0x3f, 0x5e, 0xa3, 0xe5, 0x43, 0x70, 0x10, 0xc6, 0x49, 0x05, 0xd4, - 0x4e, 0x20, 0xe8, 0x7f, 0x32, 0x1d, 0xa4, 0x1a, 0xad, 0xb9, 0x3b, 0x2a, - 0xee, 0x9c, 0xdb, 0xf7, 0xe6, 0x3c, 0xf7, 0xf1, 0x9a, 0x63, 0x69, 0x35, - 0xf5, 0x24, 0x9a, 0x7b, 0x7c, 0xe2, 0x0e, 0xa4, 0xea, 0x9a, 0xfb, 0x4e, - 0x22, 0x9c, 0xf0, 0x08, 0x35, 0x7a, 0x1e, 0x95, 0x79, 0x96, 0xe5, 0x1d, - 0x54, 0x27, 0x72, 0x9c, 0x49, 0xe3, 0xa4, 0xe2, 0xc0, 0xf2, 0x56, 0x6d, - 0x76, 0x12, 0xf3, 0xf6, 0x52, 0x19, 0xb3, 0x2e, 0x4f, 0xe3, 0x1d, 0x0a, - 0xd5, 0xfb, 0x6e, 0x38, 0xeb, 0x79, 0x4f, 0x71, 0x27, 0x76, 0xa4, 0x39, - 0x4f, 0x93, 0x5c, 0xc8, 0x37, 0xbb, 0x23, 0x3b, 0xd1, 0x9f, 0x0f, 0xe0, - 0x50, 0x36, 0xbc, 0x7f, 0x2f, 0xe1, 0xba, 0xe1, 0x52, 0x38, 0xb4, 0x4d, - 0x04, 0x48, 0xdf, 0x54, 0xff, 0xd7, 0x07, 0xa9, 0x4e, 0x56, 0xe8, 0xbf, - 0x52, 0xcf, 0xbc, 0x44, 0xf5, 0xcc, 0x39, 0xf2, 0x35, 0xdf, 0x5c, 0xad, - 0xba, 0x6c, 0xc2, 0xc2, 0x4c, 0x6c, 0x23, 0x2e, 0xdb, 0x3a, 0x0b, 0x92, - 0x8d, 0x71, 0x2e, 0xe2, 0xb3, 0x35, 0x1e, 0xb1, 0x6d, 0xd8, 0xf4, 0x3c, - 0xd8, 0x1e, 0x44, 0x38, 0xc3, 0x98, 0x53, 0xfa, 0xa6, 0x83, 0xe4, 0x31, - 0xa5, 0xed, 0xc2, 0x86, 0xd8, 0x2e, 0xf4, 0xeb, 0x7f, 0x02, 0x77, 0x3d, - 0xc7, 0x23, 0xd9, 0xac, 0xa5, 0x79, 0x2f, 0xb5, 0x77, 0x21, 0x7c, 0x94, - 0x73, 0x30, 0x55, 0xc3, 0x43, 0xec, 0xbb, 0x3c, 0xff, 0x6d, 0xc6, 0x0a, - 0xc2, 0x15, 0x35, 0xed, 0x95, 0x3c, 0x7f, 0x7d, 0x9e, 0xcf, 0x74, 0x82, - 0x6a, 0x53, 0x78, 0xdf, 0x5a, 0x6d, 0xe0, 0x71, 0x8a, 0x31, 0x89, 0x36, - 0x17, 0xb0, 0x80, 0xcf, 0x2e, 0x57, 0xea, 0x18, 0xe6, 0x77, 0x69, 0x5e, - 0x60, 0x3a, 0x4e, 0xf6, 0xf1, 0x77, 0xce, 0x28, 0x85, 0xe6, 0xce, 0x96, - 0x72, 0xff, 0xe4, 0xb0, 0x95, 0xe4, 0xf7, 0x0d, 0xa4, 0xa0, 0x8f, 0xe2, - 0x6d, 0xb0, 0x0c, 0x2a, 0xea, 0x29, 0x2e, 0x3b, 0xb4, 0x79, 0xb9, 0xb3, - 0xac, 0x4f, 0x58, 0x13, 0x73, 0xba, 0x70, 0xd2, 0x33, 0x7b, 0xc6, 0xd4, - 0x81, 0xbd, 0x68, 0xee, 0x7f, 0x57, 0x54, 0xd9, 0x3b, 0x98, 0x93, 0x2d, - 0x48, 0x2d, 0x31, 0x9c, 0x5b, 0x3e, 0xc9, 0xae, 0x23, 0x3a, 0x2e, 0x10, - 0x08, 0x5d, 0x6f, 0xef, 0x73, 0x4d, 0xb6, 0xfc, 0x29, 0xcd, 0xcd, 0xdf, - 0xff, 0xd8, 0xc7, 0x67, 0x2e, 0x4f, 0x65, 0x9f, 0xb7, 0xa2, 0x0b, 0x2b, - 0xf2, 0x39, 0x4d, 0xbe, 0x1f, 0x34, 0x24, 0x34, 0x68, 0x91, 0xd9, 0x1e, - 0xfa, 0xfd, 0xd7, 0x79, 0x42, 0xfb, 0xab, 0xfb, 0xf0, 0xcb, 0x09, 0x03, - 0x07, 0x28, 0x0f, 0xd4, 0x6a, 0xaa, 0x32, 0x81, 0x10, 0xd7, 0xd2, 0x36, - 0xff, 0x2b, 0x27, 0xc8, 0x0f, 0xeb, 0x14, 0xbb, 0xc6, 0xa8, 0xf0, 0x77, - 0x99, 0xf8, 0x7b, 0xd0, 0xc7, 0xbe, 0xb0, 0x84, 0xfc, 0x62, 0x3f, 0xf9, - 0xeb, 0x01, 0xb2, 0x35, 0xaa, 0xe0, 0xc9, 0x0f, 0xd4, 0xfd, 0x20, 0x7f, - 0x1d, 0x4e, 0xb3, 0xfc, 0x83, 0xfe, 0x5e, 0x3e, 0xde, 0xac, 0xd9, 0x7d, - 0x55, 0x3d, 0x24, 0x71, 0xdc, 0xb5, 0xe3, 0xa9, 0x19, 0x92, 0xac, 0x6a, - 0xa6, 0x6b, 0xb0, 0x14, 0x0e, 0x7a, 0xf9, 0x5d, 0x00, 0x02, 0x87, 0xbd, - 0x7a, 0x25, 0x57, 0xce, 0x50, 0x3e, 0xba, 0x4c, 0x74, 0x1c, 0x8a, 0x35, - 0x20, 0x45, 0xf9, 0x28, 0xa3, 0x55, 0x6c, 0x49, 0x9b, 0x66, 0x8c, 0x59, - 0x6f, 0x04, 0xc7, 0xd5, 0x90, 0xcb, 0xd1, 0x3c, 0x70, 0x06, 0x3b, 0xad, - 0xf3, 0x75, 0x6c, 0x53, 0x2e, 0x1c, 0x6f, 0x99, 0xb6, 0xca, 0x01, 0xe6, - 0xd7, 0x81, 0xe7, 0x75, 0xb2, 0x99, 0xc5, 0xe1, 0xe0, 0xf3, 0x94, 0x53, - 0xa7, 0xe6, 0xf4, 0x11, 0xce, 0xcf, 0xdb, 0xe3, 0x5a, 0x96, 0x75, 0x34, - 0x05, 0x2d, 0x91, 0x47, 0x2f, 0x7d, 0x6f, 0x0a, 0x5e, 0x9e, 0xb3, 0xd5, - 0x15, 0xd3, 0xaf, 0xfb, 0xe6, 0xde, 0xcb, 0xb1, 0x9f, 0x09, 0xe5, 0xff, - 0x88, 0x7e, 0xf3, 0x9c, 0x01, 0xc6, 0x32, 0x7c, 0x56, 0xcb, 0xbb, 0xa3, - 0xdd, 0xcd, 0xfe, 0xa2, 0xf0, 0x3b, 0x09, 0x1b, 0x86, 0xb9, 0x2f, 0xcc, - 0x3d, 0x1a, 0x07, 0xf6, 0x5e, 0x7d, 0x67, 0x82, 0x3f, 0x3b, 0xb1, 0x69, - 0x98, 0x7b, 0x11, 0xa7, 0x6f, 0x90, 0xf1, 0x37, 0x94, 0x87, 0x65, 0xf6, - 0x79, 0xf2, 0xf5, 0x4f, 0xd7, 0xbc, 0x34, 0xc6, 0x39, 0x35, 0x60, 0xdc, - 0x95, 0x9e, 0xd7, 0xf1, 0x55, 0x9e, 0xce, 0xde, 0x4d, 0x71, 0x27, 0x93, - 0x56, 0x07, 0x22, 0x0e, 0x7b, 0x7f, 0x2d, 0x55, 0x14, 0x5f, 0xa5, 0x22, - 0x8d, 0xe7, 0x53, 0xfc, 0x03, 0x87, 0x43, 0xc8, 0x64, 0xbb, 0xf0, 0x8d, - 0x61, 0xcb, 0x72, 0xb7, 0x39, 0xf1, 0xca, 0x90, 0x85, 0x0f, 0x62, 0xc0, - 0xcb, 0x43, 0xe1, 0x81, 0x73, 0xc0, 0xb7, 0x6b, 0xa9, 0x46, 0x6e, 0x11, - 0x6a, 0x37, 0x61, 0x83, 0xd0, 0x7b, 0x68, 0x0e, 0xe6, 0xa1, 0x9e, 0xdd, - 0x4d, 0xf3, 0xbd, 0x58, 0x00, 0x7e, 0x59, 0xf0, 0xe2, 0x17, 0xc3, 0x3c, - 0xa7, 0x17, 0xe7, 0x8e, 0xd6, 0xfb, 0x77, 0xd2, 0x5c, 0x07, 0x29, 0xbe, - 0x77, 0x1d, 0x4b, 0x60, 0xd3, 0x61, 0x81, 0x68, 0x24, 0x81, 0xce, 0x63, - 0x35, 0xd8, 0x38, 0x2c, 0xe3, 0xfd, 0x78, 0x0d, 0x6e, 0x39, 0x3a, 0xcf, - 0x47, 0xa5, 0xaf, 0xc1, 0x67, 0x35, 0xf9, 0x1c, 0xdc, 0xc9, 0x2c, 0xc7, - 0x6c, 0xca, 0x17, 0x59, 0x8e, 0x81, 0x96, 0x15, 0x6c, 0xaf, 0xf4, 0x39, - 0x9e, 0xa6, 0xfc, 0xf1, 0x78, 0xbb, 0x16, 0x0c, 0x4a, 0x06, 0x96, 0x8f, - 0x96, 0xef, 0xac, 0x85, 0x75, 0x8a, 0xf7, 0x33, 0x3e, 0x6a, 0xb1, 0xac, - 0x4d, 0xf1, 0xc8, 0xec, 0xbd, 0x36, 0xae, 0x0d, 0x90, 0x4f, 0x35, 0xe2, - 0xf1, 0xec, 0xfc, 0x9e, 0x97, 0xd6, 0x73, 0xc9, 0x61, 0xee, 0x52, 0x60, - 0x5d, 0xa9, 0x32, 0xac, 0x8f, 0x5c, 0x46, 0x24, 0xf8, 0x80, 0xe0, 0xb3, - 0x22, 0xdc, 0x13, 0xb7, 0xac, 0x37, 0xe3, 0x96, 0x55, 0x88, 0x9b, 0x9e, - 0x15, 0xab, 0x14, 0x1c, 0x5b, 0xc6, 0xef, 0x2a, 0x84, 0x93, 0x0d, 0x64, - 0x5f, 0xde, 0x65, 0x5a, 0x70, 0x2b, 0x54, 0xd3, 0xa4, 0x20, 0x17, 0x5a, - 0xa8, 0xf6, 0x00, 0x8d, 0xfe, 0x43, 0x43, 0xf5, 0xf8, 0xfe, 0xcc, 0xef, - 0xf2, 0xf1, 0x1d, 0xbb, 0x9f, 0x76, 0x45, 0xc7, 0xba, 0x5a, 0x44, 0x92, - 0xf7, 0x80, 0x7b, 0xa3, 0x7c, 0xa6, 0xd5, 0xc4, 0x2d, 0xf1, 0x3e, 0xec, - 0x18, 0xe6, 0x7d, 0xb6, 0x3a, 0xe3, 0xca, 0xb0, 0xf5, 0xd7, 0x1e, 0xa2, - 0x7f, 0x5d, 0x7b, 0x73, 0xca, 0x6b, 0xbf, 0xe3, 0xe4, 0x34, 0xd6, 0x8f, - 0xd5, 0xa1, 0x34, 0xa5, 0x95, 0x97, 0x88, 0xe4, 0x1b, 0x3e, 0x44, 0x82, - 0x0d, 0x14, 0xab, 0x66, 0xc8, 0x77, 0xa7, 0x4a, 0x5c, 0x07, 0x2c, 0x30, - 0xac, 0xd1, 0x45, 0x98, 0x9c, 0xa1, 0xb9, 0xb2, 0x5a, 0xe7, 0x07, 0x84, - 0xf3, 0xaa, 0x0d, 0xab, 0xd6, 0x6b, 0x44, 0xce, 0x36, 0x0b, 0x07, 0x66, - 0xdb, 0x2c, 0xab, 0xab, 0x5d, 0x1b, 0xa8, 0x11, 0xe8, 0x97, 0x0c, 0x2d, - 0xd1, 0xe2, 0xc0, 0xd7, 0x82, 0x88, 0x74, 0xbe, 0x89, 0x48, 0xcf, 0x05, - 0x8a, 0x61, 0x4f, 0x95, 0xf8, 0x9c, 0xf0, 0x23, 0xf8, 0xeb, 0xe1, 0x85, - 0x38, 0x35, 0xd5, 0x3f, 0xd7, 0x13, 0x83, 0xf7, 0xfa, 0x55, 0x06, 0x8e, - 0x0f, 0x87, 0xc8, 0x7e, 0xdc, 0x14, 0xd7, 0x65, 0x48, 0x4d, 0x90, 0xeb, - 0xa8, 0x4e, 0x88, 0x3d, 0x66, 0x59, 0x2b, 0x9a, 0x2a, 0x35, 0xcf, 0x8a, - 0xe9, 0x6b, 0xdf, 0x71, 0x98, 0xef, 0xf7, 0x04, 0x49, 0x7f, 0xcd, 0xa9, - 0x1d, 0xe2, 0x8c, 0x65, 0xfe, 0x81, 0x20, 0x9e, 0x7b, 0x6a, 0xe0, 0x65, - 0xbe, 0x65, 0xec, 0x1e, 0xe5, 0x3e, 0x1c, 0xeb, 0x0d, 0xde, 0xce, 0x38, - 0xef, 0x97, 0xb3, 0x8e, 0xca, 0xde, 0x0d, 0x71, 0x8a, 0x89, 0xc2, 0x4f, - 0x78, 0xca, 0xf4, 0x74, 0x50, 0x7e, 0xaa, 0x1a, 0xe6, 0xf7, 0x2d, 0x7c, - 0x38, 0x40, 0x71, 0xe3, 0xb2, 0x5e, 0x8d, 0x43, 0x75, 0x6a, 0x82, 0xeb, - 0xe9, 0x27, 0x4b, 0xdc, 0x33, 0xdc, 0x89, 0xed, 0xfc, 0xbe, 0x4a, 0x69, - 0xb5, 0x7d, 0xb6, 0x90, 0xae, 0x11, 0x36, 0x60, 0x3a, 0xe6, 0xd7, 0xef, - 0xc4, 0x92, 0x21, 0xd6, 0xe3, 0xc7, 0x6b, 0x82, 0x24, 0xa3, 0xc7, 0xc9, - 0x2e, 0x24, 0xa3, 0x03, 0xf2, 0x90, 0x65, 0xdd, 0x18, 0xbf, 0x76, 0x0e, - 0xad, 0xff, 0x82, 0x83, 0xea, 0x3b, 0x07, 0xef, 0xeb, 0xa9, 0x89, 0x13, - 0xe2, 0xda, 0x39, 0x0b, 0x35, 0xdc, 0x4f, 0x34, 0xa7, 0x2a, 0x79, 0xe9, - 0x38, 0xe5, 0xa5, 0x97, 0x73, 0xec, 0x23, 0xf5, 0x06, 0xfb, 0x88, 0x44, - 0xb1, 0x76, 0x7d, 0x3a, 0x84, 0x0b, 0x3a, 0x34, 0x37, 0x62, 0x44, 0x77, - 0xa4, 0xbb, 0x63, 0x0e, 0xf3, 0xb9, 0x28, 0xfe, 0x4f, 0xe5, 0x78, 0xaf, - 0x4d, 0xa0, 0x46, 0x63, 0x1b, 0xb0, 0x73, 0x01, 0xc5, 0xb4, 0x7e, 0xd4, - 0xae, 0x06, 0x2e, 0x0d, 0xf1, 0xfe, 0x8c, 0x86, 0x03, 0xa5, 0x01, 0xd1, - 0x30, 0xf4, 0x5b, 0x2b, 0x54, 0x35, 0xbf, 0x07, 0xf8, 0x30, 0xef, 0x01, - 0x92, 0x0d, 0xf4, 0xdb, 0xe7, 0x7c, 0xde, 0x4c, 0xf3, 0x39, 0x9f, 0x70, - 0x68, 0x13, 0xf9, 0x4e, 0x2f, 0x9a, 0xf5, 0x69, 0xc2, 0xce, 0xb3, 0x44, - 0x67, 0x93, 0xa8, 0xec, 0x73, 0x45, 0xe6, 0xf6, 0xe9, 0x96, 0xe5, 0x3b, - 0x45, 0x4d, 0x81, 0x69, 0x0a, 0x10, 0x4d, 0x1d, 0xa2, 0xfa, 0xd8, 0x06, - 0xe1, 0x3b, 0xd6, 0x25, 0xa4, 0x02, 0xc7, 0xe4, 0x3a, 0x63, 0x4f, 0x8e, - 0xf3, 0xd9, 0x66, 0xe1, 0x3c, 0xba, 0x45, 0x78, 0x0b, 0x3d, 0xc2, 0x7f, - 0xcc, 0xc4, 0xfd, 0xf1, 0x2e, 0x9c, 0x1b, 0xe6, 0xb3, 0x6c, 0xf7, 0x89, - 0x9a, 0xb9, 0xbd, 0x39, 0x6f, 0xa1, 0xd1, 0x5f, 0x48, 0x73, 0x7f, 0xf7, - 0xe3, 0x35, 0xe9, 0xa1, 0x45, 0xfe, 0xa7, 0xc6, 0x02, 0xfe, 0x27, 0xc7, - 0xd4, 0xfe, 0x7d, 0xc2, 0xb2, 0x76, 0xc6, 0xfe, 0x03, 0xeb, 0xd0, 0x6a, - 0x8e, 0x55, 0xf0, 0xc1, 0x6e, 0x92, 0xc7, 0x36, 0xca, 0x2d, 0x93, 0x7a, - 0xf3, 0x1c, 0x16, 0x51, 0x53, 0xfc, 0xee, 0x1b, 0xfd, 0x77, 0x73, 0x6e, - 0xe3, 0x7d, 0x4d, 0x67, 0x3b, 0x28, 0xee, 0x7e, 0xc6, 0x6b, 0xcd, 0x10, - 0x9f, 0x51, 0xeb, 0x87, 0xff, 0x4b, 0xf6, 0xf5, 0xce, 0x7d, 0xb6, 0xaf, - 0x97, 0x78, 0x52, 0xa8, 0xe5, 0x19, 0xe2, 0xb7, 0xca, 0xf1, 0xb9, 0x3d, - 0xbd, 0xb9, 0xfd, 0xbc, 0x4e, 0xe1, 0x2b, 0x70, 0x7d, 0x1e, 0x30, 0x5e, - 0x1f, 0xea, 0x10, 0xde, 0x63, 0xc3, 0x94, 0x1f, 0x37, 0x10, 0xcf, 0x7c, - 0x76, 0xac, 0x4b, 0xf8, 0x0b, 0x9b, 0x85, 0x8f, 0xf8, 0xac, 0x26, 0x3e, - 0x71, 0xcc, 0x23, 0xbc, 0xc4, 0xa3, 0x87, 0x78, 0xf4, 0xce, 0xf1, 0xe8, - 0x29, 0x04, 0xfd, 0xe9, 0x74, 0xbd, 0xff, 0xd1, 0x31, 0xc5, 0xbf, 0x6f, - 0xcc, 0xb2, 0xde, 0xd7, 0x15, 0x3f, 0xf3, 0xf5, 0xaa, 0xfe, 0x45, 0xbe, - 0x6e, 0x20, 0xbe, 0x2a, 0x7b, 0xb1, 0xa4, 0xc3, 0x14, 0xeb, 0x90, 0xcf, - 0x71, 0xcc, 0xf3, 0x75, 0x30, 0xcd, 0xfb, 0x95, 0xbc, 0x6f, 0x39, 0x20, - 0x56, 0x10, 0x5f, 0x65, 0xe2, 0x6b, 0xe5, 0x97, 0xf0, 0xf5, 0xe1, 0x35, - 0x7c, 0xbd, 0xfa, 0xf7, 0xf2, 0xe5, 0x11, 0xcb, 0x87, 0x39, 0x0e, 0xdd, - 0x66, 0xc8, 0xc3, 0x16, 0x61, 0x47, 0x07, 0xbe, 0x3f, 0x05, 0x14, 0xb3, - 0xbb, 0x20, 0x53, 0xbc, 0x39, 0x1d, 0x8f, 0x84, 0x5e, 0xa1, 0x7a, 0x72, - 0xba, 0xe4, 0x15, 0xcb, 0xec, 0x3d, 0x59, 0xac, 0x90, 0x89, 0xa6, 0x19, - 0xfb, 0x5d, 0x33, 0xe8, 0xb5, 0x1a, 0xeb, 0x52, 0x3b, 0xbb, 0x15, 0x91, - 0x72, 0xc4, 0xd1, 0x25, 0x12, 0x05, 0xde, 0x83, 0xdd, 0x22, 0x56, 0xda, - 0xfb, 0xaf, 0x9d, 0xe2, 0xfa, 0x42, 0x87, 0x68, 0x21, 0xbb, 0x68, 0x3e, - 0xc6, 0xe7, 0xc1, 0x36, 0x8b, 0xe6, 0x39, 0x79, 0x2c, 0x27, 0x79, 0x0c, - 0x7d, 0x4e, 0x1e, 0x1b, 0x6c, 0x79, 0xfc, 0x4c, 0xbf, 0x78, 0x4d, 0x0f, - 0x8d, 0xeb, 0x2a, 0xca, 0x86, 0x54, 0x3b, 0xd5, 0xce, 0xd5, 0x4e, 0x6f, - 0xc5, 0xf8, 0x9c, 0x8f, 0x69, 0xd5, 0x68, 0x08, 0x39, 0x0d, 0xb5, 0xe7, - 0xb4, 0xd0, 0x52, 0xf7, 0x89, 0xe4, 0x26, 0x1f, 0xd5, 0x3f, 0x3b, 0x62, - 0x91, 0xe4, 0x72, 0x11, 0x49, 0x38, 0x05, 0xe7, 0x15, 0x5d, 0xae, 0x2a, - 0x9a, 0xd8, 0x47, 0xf1, 0xed, 0xc5, 0x9c, 0x44, 0xd8, 0x81, 0xdf, 0x3f, - 0x73, 0xe2, 0x46, 0x82, 0x12, 0x4f, 0x10, 0xee, 0x78, 0x3c, 0xdb, 0x87, - 0x27, 0xf2, 0xbd, 0x78, 0x3c, 0xff, 0x77, 0xde, 0xb5, 0x91, 0xbd, 0x46, - 0x63, 0xa2, 0x72, 0x16, 0xe1, 0xe3, 0xc4, 0x75, 0x11, 0x96, 0xcd, 0x89, - 0x16, 0x39, 0xc2, 0xb5, 0xae, 0xf3, 0x77, 0xdf, 0xd5, 0xd8, 0x17, 0x7b, - 0x56, 0xbd, 0x64, 0x63, 0x91, 0x93, 0x6d, 0xc7, 0xec, 0x33, 0x52, 0xe5, - 0x95, 0x7b, 0xec, 0x77, 0x41, 0x7d, 0xab, 0xef, 0xd2, 0xd8, 0x1f, 0x4e, - 0xc4, 0xd7, 0xdb, 0xf9, 0xb5, 0x71, 0x6d, 0xe5, 0x3d, 0x99, 0xe0, 0xda, - 0x4a, 0xaf, 0x26, 0xb0, 0x36, 0x6a, 0x7f, 0x86, 0xd6, 0x56, 0xf6, 0xba, - 0xf5, 0xb5, 0x4d, 0xf6, 0x67, 0x74, 0x6d, 0xc5, 0xa7, 0xb4, 0xb5, 0x9a, - 0xfd, 0x19, 0x5f, 0x5b, 0xc9, 0xcb, 0x2d, 0x6b, 0x97, 0x5e, 0x7d, 0xbf, - 0x86, 0xff, 0xfe, 0x17, 0x9f, 0xed, 0x4e, 0xb2, 0x20, 0x3b, 0x00, 0x00, - 0x00 }; + 0xc5, 0x7b, 0x7d, 0x70, 0x1b, 0xe7, 0x79, 0xe7, 0xef, 0xc5, 0x02, 0xe4, + 0x02, 0x04, 0x41, 0x90, 0x82, 0x64, 0xf0, 0xca, 0x44, 0x58, 0x61, 0x41, + 0xc1, 0x26, 0x2d, 0x2f, 0x28, 0x50, 0x82, 0xcb, 0x55, 0x85, 0x4a, 0xb4, + 0x44, 0xc7, 0x74, 0x43, 0x3b, 0x6a, 0x4b, 0x67, 0x3c, 0x09, 0x2a, 0x51, + 0x16, 0x2d, 0xcb, 0x16, 0xed, 0xf8, 0x7a, 0xec, 0x9c, 0x27, 0xda, 0x50, + 0x1f, 0x96, 0x25, 0x10, 0x00, 0x3f, 0x64, 0xca, 0x9d, 0xce, 0x19, 0x26, + 0x29, 0x51, 0xb6, 0xf1, 0x21, 0xc7, 0x4a, 0x6a, 0xcf, 0x24, 0x11, 0x4e, + 0x96, 0x65, 0xd9, 0x89, 0x3f, 0x92, 0xf8, 0x7a, 0x4e, 0xa7, 0x37, 0xd5, + 0x48, 0xfe, 0x90, 0x2c, 0xf9, 0xa3, 0x69, 0x6f, 0x2a, 0xb5, 0x4e, 0xf7, + 0x9e, 0x67, 0x17, 0x94, 0x15, 0xd7, 0x9d, 0x9b, 0xf6, 0xfe, 0x38, 0xce, + 0x70, 0x00, 0xec, 0xbe, 0xfb, 0xbe, 0xcf, 0xf7, 0xf3, 0x7b, 0x9e, 0xf7, + 0xdd, 0x56, 0xc0, 0x83, 0xea, 0x5f, 0x3d, 0xfd, 0xc7, 0x87, 0x86, 0x1f, + 0x8e, 0x2d, 0x5b, 0xb1, 0x8c, 0xbe, 0x76, 0xa2, 0xa1, 0xc6, 0xc9, 0x37, + 0x57, 0x08, 0x20, 0xf5, 0x21, 0xfe, 0x43, 0x7f, 0x5f, 0xf9, 0x8f, 0x3d, + 0x66, 0xfd, 0x49, 0x80, 0x7f, 0x9e, 0x2e, 0xfe, 0x87, 0xec, 0xd0, 0x93, + 0x5d, 0x6b, 0x54, 0xc8, 0x92, 0x7e, 0x79, 0xd5, 0x26, 0x15, 0x48, 0x16, + 0xda, 0x42, 0x6b, 0xf1, 0x1b, 0xd3, 0x08, 0x38, 0xc1, 0xd7, 0xbf, 0xa2, + 0x7f, 0xb6, 0xe3, 0xc7, 0x2b, 0x95, 0x4f, 0xf3, 0x12, 0x64, 0xbf, 0x7e, + 0x10, 0xfe, 0x56, 0xc8, 0x2d, 0xf4, 0xcc, 0x5f, 0x2c, 0x2d, 0x39, 0xe1, + 0x9b, 0x9f, 0x0b, 0x86, 0x4b, 0xd7, 0xb0, 0x33, 0x3b, 0x84, 0x23, 0x71, + 0xa0, 0x76, 0x34, 0xa2, 0xed, 0x04, 0x72, 0x0e, 0x3d, 0x12, 0x3a, 0x81, + 0x10, 0x66, 0x0b, 0x2a, 0x1e, 0x2d, 0xc3, 0x70, 0xea, 0x21, 0x3c, 0x96, + 0xfe, 0x17, 0x33, 0xe4, 0xe2, 0x47, 0x86, 0xb0, 0x8b, 0xc6, 0xee, 0x4e, + 0x43, 0x0e, 0xea, 0x8f, 0x20, 0x98, 0x85, 0x5c, 0xaf, 0x0f, 0xa3, 0x38, + 0x1a, 0x3e, 0x3d, 0x07, 0xa5, 0xaf, 0x59, 0x52, 0x86, 0x80, 0xb6, 0xd4, + 0x5d, 0x42, 0xe9, 0x2f, 0x09, 0x25, 0xb1, 0x4d, 0x40, 0x16, 0x34, 0xee, + 0x86, 0x02, 0x7f, 0x0e, 0x63, 0x69, 0x41, 0xc6, 0x19, 0x89, 0xe7, 0x59, + 0x45, 0xf2, 0x16, 0x70, 0xaa, 0x1a, 0x76, 0x67, 0x79, 0x0d, 0x81, 0x9d, + 0xf1, 0x88, 0x7f, 0x06, 0x7c, 0x3f, 0x84, 0x11, 0x6b, 0x9c, 0x42, 0x5c, + 0x9b, 0xe6, 0x2e, 0xcd, 0x34, 0x0f, 0x69, 0xb5, 0x30, 0xfc, 0x4a, 0x10, + 0x10, 0x18, 0xd1, 0x1c, 0x48, 0xfa, 0xd7, 0x84, 0x9c, 0x50, 0x82, 0x9b, + 0xf1, 0xcf, 0xc4, 0x73, 0x32, 0xea, 0x82, 0x3d, 0x3e, 0x85, 0x5a, 0x54, + 0xfc, 0xb6, 0xd4, 0xa6, 0xd3, 0xa6, 0x79, 0x4a, 0x75, 0xe2, 0x10, 0xc9, + 0x67, 0xa4, 0xf0, 0xcf, 0x66, 0x85, 0x64, 0xb3, 0x4b, 0x9d, 0x5f, 0x5f, + 0x46, 0xde, 0x6f, 0x9a, 0x33, 0x74, 0x6f, 0x4f, 0x61, 0x5e, 0xce, 0xa6, + 0xe9, 0x50, 0x4d, 0x73, 0x93, 0xfa, 0x4f, 0xe6, 0xc6, 0xdf, 0x1a, 0x1b, + 0xc3, 0x33, 0x39, 0x3f, 0x9e, 0xcd, 0x26, 0x51, 0x48, 0x9b, 0x90, 0x74, + 0x27, 0x06, 0x47, 0x43, 0xd8, 0x56, 0xec, 0x46, 0x31, 0xad, 0xa4, 0xce, + 0xd0, 0x73, 0x1b, 0xe3, 0x2a, 0xee, 0x2f, 0xf6, 0x60, 0x2e, 0x0d, 0xd3, + 0xad, 0xab, 0x15, 0xb7, 0x88, 0x62, 0x4b, 0xb1, 0x17, 0xa5, 0xb4, 0x7a, + 0x7a, 0x44, 0x44, 0x86, 0x9b, 0x25, 0x27, 0xb6, 0x17, 0xdb, 0xf1, 0x40, + 0x31, 0x41, 0xcf, 0x98, 0xf8, 0x5a, 0xac, 0x85, 0xc6, 0x77, 0xe0, 0xe9, + 0x49, 0xd3, 0x8c, 0xc6, 0xfc, 0x18, 0x2c, 0x6a, 0x98, 0xcb, 0x39, 0x90, + 0x3a, 0xe4, 0x44, 0xea, 0x29, 0x60, 0xcb, 0x53, 0x1d, 0x98, 0xc9, 0x99, + 0xd8, 0xa8, 0x8d, 0x34, 0x3b, 0xe0, 0x42, 0xca, 0x2f, 0xe0, 0x52, 0x7d, + 0xd8, 0xec, 0xb7, 0x69, 0x3f, 0x23, 0x09, 0x6c, 0x7d, 0x2a, 0x8a, 0x77, + 0xd2, 0x06, 0xbe, 0xd6, 0x19, 0xc4, 0x70, 0x31, 0x80, 0x37, 0xd3, 0x01, + 0x5a, 0x43, 0xc3, 0x1b, 0x69, 0x99, 0xd6, 0x69, 0xc7, 0xc9, 0x34, 0x8f, + 0xe1, 0xb1, 0x5e, 0x0c, 0x14, 0x5b, 0xf0, 0x7a, 0x3a, 0x48, 0x6b, 0x06, + 0xf0, 0x2a, 0x8d, 0xbb, 0xb7, 0xa8, 0xe2, 0x34, 0x8d, 0x1b, 0x2c, 0x86, + 0xf0, 0x4a, 0xda, 0x4b, 0xb4, 0x06, 0x70, 0x22, 0x3d, 0x84, 0x9d, 0xe9, + 0xb6, 0xd3, 0x6b, 0x49, 0x86, 0xa1, 0x05, 0xbc, 0x0e, 0x5f, 0x7b, 0xd7, + 0xec, 0x0d, 0x58, 0xa6, 0x42, 0xeb, 0xcc, 0xaf, 0x3b, 0x84, 0x91, 0xf4, + 0xa9, 0xaa, 0xbf, 0x68, 0x78, 0x2c, 0x77, 0xd9, 0xfc, 0xf1, 0xd2, 0x16, + 0x1c, 0xc9, 0x02, 0x4f, 0xcf, 0x00, 0x33, 0x59, 0xc3, 0xac, 0xd7, 0x4d, + 0x73, 0xba, 0xb3, 0x9d, 0xe4, 0xa5, 0xf6, 0x6f, 0xa4, 0x51, 0xcf, 0x96, + 0x9d, 0xc0, 0x53, 0x4a, 0x7f, 0x05, 0x0e, 0xe4, 0xe7, 0x9c, 0xa8, 0x19, + 0x55, 0x7a, 0xf2, 0x50, 0x4e, 0x6f, 0x21, 0x8f, 0x3a, 0x94, 0x55, 0xfa, + 0x0c, 0xec, 0x30, 0x83, 0x7a, 0x6b, 0xa8, 0x5d, 0x32, 0xe1, 0x23, 0x5b, + 0x48, 0xb7, 0x9b, 0x66, 0xc3, 0x4a, 0xd3, 0x7c, 0xbd, 0x13, 0xa6, 0x43, + 0x57, 0x4f, 0x97, 0xa1, 0x56, 0x3e, 0x82, 0x3a, 0x7c, 0x02, 0x95, 0xaf, + 0x78, 0x11, 0x19, 0x0c, 0x4b, 0x91, 0xa1, 0xcb, 0xf4, 0x6c, 0x7d, 0x91, + 0xcc, 0x99, 0x78, 0x51, 0x47, 0x81, 0x62, 0x59, 0x86, 0x93, 0xf8, 0x69, + 0x1f, 0x35, 0x4d, 0xa7, 0xea, 0x85, 0x97, 0xe4, 0xbb, 0xfe, 0x80, 0x69, + 0xbe, 0xaf, 0xf9, 0x51, 0x43, 0xba, 0xb9, 0x65, 0xcc, 0xc4, 0xb4, 0x76, + 0x82, 0xe4, 0x29, 0x90, 0xea, 0x8b, 0xd3, 0x33, 0x01, 0x1a, 0x9f, 0xc0, + 0xfa, 0xd1, 0x20, 0x9e, 0xc9, 0xca, 0xf8, 0xf1, 0xd2, 0x28, 0xea, 0x68, + 0x2e, 0x0f, 0xc9, 0xaa, 0x96, 0xe4, 0x87, 0x22, 0x99, 0x5b, 0xd1, 0xb6, + 0x47, 0x14, 0xcf, 0x10, 0x8f, 0x41, 0x7c, 0xbf, 0x1c, 0xc0, 0x73, 0x65, + 0x3f, 0x8e, 0x96, 0x5b, 0x70, 0xbc, 0xac, 0xe1, 0x60, 0x4e, 0xd9, 0x5b, + 0x81, 0x89, 0x7a, 0x7d, 0x07, 0x1a, 0x96, 0x03, 0x6f, 0xe6, 0x63, 0xc8, + 0xe4, 0x4c, 0xb3, 0x40, 0x74, 0x7b, 0x88, 0x8f, 0x37, 0xf2, 0x5f, 0xc5, + 0xe1, 0x49, 0x27, 0x42, 0xd3, 0x01, 0x3c, 0x9b, 0x76, 0xe2, 0xfa, 0x8c, + 0x62, 0xe4, 0xa1, 0x46, 0xb7, 0x09, 0x35, 0x79, 0x83, 0x50, 0x72, 0x06, + 0x22, 0x21, 0x97, 0x70, 0xa0, 0xf5, 0xb0, 0x13, 0x6a, 0x29, 0x04, 0x57, + 0xab, 0x0c, 0xb5, 0xf5, 0x21, 0xc0, 0xe7, 0x40, 0x0d, 0xf9, 0xc6, 0xfa, + 0xf1, 0x28, 0x5d, 0x0b, 0xd0, 0x35, 0x7c, 0xb5, 0x16, 0xd2, 0x22, 0x09, + 0x24, 0x3b, 0x55, 0x42, 0xd2, 0x69, 0x9a, 0x92, 0xda, 0x81, 0xbb, 0x1e, + 0x37, 0xcd, 0xf0, 0x72, 0x1e, 0xef, 0x47, 0xb8, 0x44, 0x72, 0x68, 0x25, + 0xba, 0xb2, 0x44, 0x67, 0x96, 0xe8, 0xcc, 0x12, 0x9d, 0x59, 0x89, 0xec, + 0x46, 0xd1, 0x80, 0x47, 0x48, 0x5f, 0x21, 0xe2, 0xf1, 0x1d, 0x4b, 0x57, + 0xcf, 0x95, 0x83, 0xc4, 0x43, 0xc8, 0xe2, 0xe1, 0xe9, 0x9c, 0x80, 0x43, + 0x55, 0xfa, 0xce, 0x60, 0x35, 0xc2, 0x31, 0x25, 0x99, 0x47, 0x92, 0x9e, + 0x53, 0xf6, 0x1a, 0x50, 0x7a, 0x2a, 0x64, 0x03, 0x1b, 0xfd, 0x09, 0xcc, + 0x65, 0x5d, 0xa8, 0x53, 0x95, 0x10, 0xe9, 0x2c, 0x5a, 0xc1, 0x02, 0xdc, + 0xe7, 0xa7, 0x39, 0x1d, 0xb2, 0xb0, 0x63, 0xc9, 0x23, 0x88, 0x8c, 0x3b, + 0x30, 0xab, 0x49, 0xe4, 0xa3, 0x1a, 0xa4, 0x56, 0x5a, 0xae, 0x14, 0xa7, + 0x4f, 0x9a, 0x3f, 0x4b, 0x6b, 0x11, 0x3d, 0x34, 0x1f, 0xf9, 0x26, 0xcb, + 0x32, 0x4a, 0x34, 0x3c, 0x6a, 0xd1, 0x7b, 0xb4, 0xfc, 0x75, 0x61, 0xdb, + 0x90, 0x4e, 0x36, 0xa3, 0x84, 0x20, 0x94, 0x68, 0x48, 0x28, 0x5a, 0x52, + 0xf8, 0x31, 0x53, 0x7e, 0x83, 0xc6, 0x04, 0xae, 0x19, 0xd3, 0x87, 0x91, + 0xac, 0xc0, 0x5a, 0xd5, 0xc4, 0x1a, 0xad, 0x0f, 0x3b, 0xcb, 0xf3, 0xbe, + 0xc9, 0x31, 0xcc, 0xef, 0x9b, 0x49, 0x77, 0x63, 0x57, 0x36, 0x84, 0x9d, + 0x85, 0xa0, 0x6f, 0x3a, 0xcd, 0xf7, 0x54, 0xf2, 0x79, 0xbe, 0x17, 0xb8, + 0xe6, 0x5e, 0xcb, 0x35, 0xf7, 0x12, 0x18, 0x99, 0xf8, 0x1d, 0x8a, 0x23, + 0x0d, 0xd8, 0xa9, 0x7e, 0x4a, 0xf6, 0xa2, 0x26, 0x06, 0xd0, 0x8c, 0x33, + 0xfe, 0x76, 0xec, 0x9f, 0xea, 0xc5, 0xae, 0xa9, 0x65, 0x78, 0x6c, 0xa2, + 0x25, 0xe5, 0xd1, 0x49, 0x38, 0x9e, 0x70, 0x72, 0x40, 0x28, 0x43, 0x92, + 0x08, 0x47, 0x07, 0xc8, 0x7e, 0x5b, 0x1b, 0x4d, 0xf3, 0x44, 0x8c, 0xec, + 0x5b, 0x6b, 0xd3, 0xd6, 0x93, 0x00, 0x2a, 0x7d, 0x4a, 0xcf, 0xbb, 0xf0, + 0xe2, 0x76, 0xb2, 0xbb, 0x99, 0x18, 0x06, 0x24, 0x48, 0xed, 0x5e, 0xfc, + 0xbd, 0xf9, 0x94, 0x93, 0xe5, 0x6e, 0xee, 0xd8, 0xa4, 0xed, 0x15, 0x1c, + 0xeb, 0x6a, 0xae, 0xc6, 0x13, 0x9e, 0x9f, 0x9f, 0x21, 0xdd, 0xd1, 0x3c, + 0x83, 0xb1, 0xb6, 0xc4, 0x20, 0x2e, 0x9b, 0x67, 0x36, 0xf4, 0x62, 0xe7, + 0xdc, 0x32, 0xec, 0x9b, 0x70, 0x21, 0xd9, 0x28, 0xd0, 0xa0, 0x86, 0x2b, + 0xf7, 0x61, 0x19, 0x8c, 0x19, 0x7e, 0xae, 0x17, 0x07, 0xe7, 0xec, 0xdf, + 0xd9, 0xab, 0xbf, 0xe7, 0xe7, 0x3b, 0x4f, 0x3a, 0x65, 0x79, 0x72, 0xac, + 0x24, 0x15, 0xe8, 0x6d, 0x38, 0x32, 0x11, 0x20, 0xdd, 0x76, 0x0b, 0xe7, + 0xe1, 0x45, 0x3e, 0xcf, 0xe3, 0x26, 0x4e, 0x69, 0xa4, 0xe7, 0xec, 0x3a, + 0xe1, 0x39, 0xdc, 0x23, 0x5c, 0xa5, 0x3b, 0x45, 0xcd, 0xf4, 0x37, 0x85, + 0x7c, 0x38, 0x25, 0x6a, 0x4b, 0xed, 0x24, 0xfb, 0x7e, 0xe1, 0x3e, 0xac, + 0x84, 0x42, 0xe2, 0x11, 0xd2, 0xe7, 0x06, 0x21, 0x95, 0xe0, 0x77, 0xe8, + 0xc3, 0xc2, 0x51, 0xa2, 0x39, 0x2c, 0x1b, 0xe2, 0x75, 0x82, 0xa4, 0x37, + 0x18, 0x92, 0x3e, 0x84, 0x8d, 0x14, 0xff, 0x6f, 0x4d, 0xeb, 0x78, 0x34, + 0x5b, 0x4b, 0x31, 0x92, 0x7d, 0xff, 0x32, 0xad, 0xab, 0xe2, 0x31, 0xca, + 0x15, 0xb2, 0xbe, 0x0f, 0x3e, 0xf2, 0xb9, 0xd7, 0x63, 0xec, 0x8f, 0x40, + 0x21, 0x1b, 0xee, 0x7f, 0x54, 0x98, 0xe6, 0xd6, 0x88, 0xb9, 0x78, 0x5d, + 0xac, 0x2d, 0x7a, 0x12, 0xff, 0x68, 0xe6, 0x03, 0x43, 0xa8, 0xef, 0xa4, + 0x7b, 0xa3, 0x90, 0x5d, 0xfa, 0x2e, 0x1c, 0xa2, 0x5c, 0xe2, 0xd1, 0x29, + 0xbe, 0x8c, 0x86, 0xfb, 0x1f, 0x13, 0x1c, 0xf3, 0x95, 0xca, 0xb3, 0x18, + 0x39, 0x5d, 0x0b, 0x25, 0xb4, 0x46, 0xb4, 0x69, 0x75, 0x92, 0x91, 0x68, + 0xa6, 0x14, 0xe7, 0xee, 0x54, 0x86, 0xf7, 0x40, 0xf1, 0x5f, 0x00, 0xfb, + 0x2a, 0xe7, 0x93, 0x5d, 0x48, 0x58, 0x79, 0xc5, 0xc0, 0x4d, 0x57, 0xf3, + 0x8a, 0x4e, 0x76, 0x52, 0x8b, 0x3d, 0x44, 0xd7, 0xcb, 0x9a, 0x12, 0x9c, + 0x86, 0xb9, 0x78, 0x40, 0xe3, 0x7b, 0x3a, 0x76, 0x95, 0xcd, 0x90, 0xa4, + 0xb3, 0xac, 0x90, 0xaa, 0xd5, 0x99, 0x56, 0x3f, 0xf9, 0xc6, 0x6f, 0xcc, + 0x81, 0xb8, 0xac, 0xbd, 0x57, 0xf0, 0x93, 0xbc, 0xe0, 0x73, 0x16, 0xbf, + 0x2c, 0xff, 0x9a, 0x70, 0xe8, 0xbf, 0x31, 0xbf, 0x1d, 0x87, 0x6f, 0x71, + 0xd1, 0x99, 0xaa, 0xd3, 0xd1, 0x37, 0x3c, 0xba, 0xc3, 0x6c, 0x56, 0x1d, + 0x14, 0xab, 0x54, 0x8a, 0xed, 0xde, 0xc4, 0xa5, 0x4e, 0xb7, 0x78, 0xbd, + 0x33, 0xd8, 0xfb, 0x51, 0xc1, 0x4d, 0x7a, 0x46, 0xdf, 0xb6, 0x62, 0xc2, + 0xf9, 0x21, 0xd9, 0x5a, 0x0d, 0xc5, 0x55, 0x14, 0x5b, 0x7a, 0x2f, 0x50, + 0x2e, 0xba, 0x25, 0xe6, 0xfe, 0xe3, 0x1a, 0xdd, 0xf1, 0x55, 0x37, 0x1e, + 0xbc, 0x69, 0x36, 0xd1, 0x40, 0xb1, 0xdd, 0x8f, 0xd3, 0xf1, 0x1e, 0x8c, + 0x94, 0x6b, 0xc9, 0x0e, 0x9f, 0xaf, 0xec, 0x56, 0x5b, 0x7a, 0x2f, 0xa6, + 0x17, 0x53, 0x2c, 0xc1, 0x67, 0x85, 0x4e, 0xb5, 0x6f, 0x9b, 0x38, 0x71, + 0xab, 0x07, 0x71, 0x92, 0xab, 0x2c, 0x5f, 0x49, 0xe3, 0xd3, 0xc5, 0xaa, + 0x5a, 0x59, 0x2d, 0xb5, 0x0e, 0xc9, 0x52, 0xeb, 0x70, 0x0d, 0xc5, 0xe1, + 0xf3, 0x37, 0x0a, 0x9c, 0xba, 0x31, 0x92, 0xa8, 0x11, 0x6e, 0x9c, 0xe9, + 0x4b, 0x90, 0x9d, 0xb4, 0xa4, 0xdc, 0x3a, 0xc5, 0x8f, 0x51, 0x01, 0x49, + 0x4d, 0x60, 0xe7, 0x0c, 0x1e, 0x19, 0xd1, 0x7a, 0x61, 0xcc, 0xb1, 0x0d, + 0xb5, 0x63, 0x64, 0xae, 0x0f, 0x46, 0x59, 0x42, 0x3e, 0x40, 0xcc, 0x97, + 0x91, 0x72, 0xe9, 0xed, 0xdd, 0xf9, 0xc2, 0x5d, 0x2e, 0xdb, 0x87, 0x89, + 0xff, 0xec, 0xa4, 0x0f, 0x1e, 0xd6, 0xf3, 0x69, 0x92, 0x51, 0x3b, 0x9e, + 0x2f, 0x47, 0x29, 0xde, 0x69, 0x24, 0x17, 0x95, 0xe2, 0x45, 0x88, 0xec, + 0x4b, 0xc6, 0xc6, 0x09, 0xe5, 0x20, 0xc5, 0x85, 0x5c, 0x9e, 0x40, 0x51, + 0x32, 0xe0, 0xa7, 0xfc, 0xfd, 0x6a, 0x35, 0x06, 0x0c, 0xd2, 0xa7, 0x62, + 0x24, 0x81, 0x93, 0x0e, 0xa0, 0xa3, 0x59, 0x8f, 0xec, 0x6d, 0x26, 0x7d, + 0x34, 0x96, 0xdc, 0xd8, 0x3e, 0xd1, 0x84, 0x07, 0xa6, 0x3c, 0xd8, 0x3a, + 0x61, 0xe2, 0x52, 0x8c, 0x6d, 0x43, 0xe9, 0x27, 0x12, 0xbb, 0xeb, 0x48, + 0xae, 0xb7, 0xc6, 0x22, 0x09, 0xb7, 0x70, 0xa2, 0xb6, 0xd4, 0x47, 0x38, + 0x20, 0xc9, 0x7e, 0xa1, 0xd1, 0x1c, 0xa1, 0x9d, 0xda, 0xed, 0x48, 0x05, + 0x64, 0xb8, 0x4a, 0x5e, 0x8a, 0x25, 0xec, 0xc7, 0x7c, 0xef, 0xeb, 0xd8, + 0x58, 0xe3, 0x85, 0x94, 0x91, 0x91, 0x23, 0x0c, 0x80, 0x45, 0x35, 0xe8, + 0x69, 0x75, 0xd0, 0x7f, 0xc0, 0x37, 0x3b, 0xd9, 0xe2, 0x3b, 0x44, 0xf1, + 0x75, 0x4b, 0xd6, 0xc1, 0xeb, 0x30, 0x66, 0xa0, 0xb9, 0xfd, 0x78, 0x9a, + 0xe2, 0xf5, 0x43, 0x14, 0x7f, 0x8e, 0x94, 0xcb, 0x82, 0xe3, 0x89, 0xc5, + 0x4f, 0x96, 0x78, 0xcb, 0x12, 0x6f, 0x59, 0xe2, 0x8b, 0xe2, 0xc2, 0xd1, + 0x2c, 0xf3, 0xf1, 0x6b, 0xf2, 0xd1, 0x04, 0xf1, 0xee, 0xc6, 0x66, 0xa2, + 0xf7, 0xc1, 0xa9, 0x3a, 0x6c, 0x23, 0x7a, 0x8b, 0x9a, 0xa2, 0x3d, 0x27, + 0x4c, 0xec, 0x8f, 0x29, 0xc6, 0x4f, 0x29, 0x10, 0x39, 0x5a, 0x4d, 0xb3, + 0x4f, 0x63, 0x9e, 0x29, 0x5e, 0x39, 0x2c, 0x9e, 0xf7, 0x26, 0xe1, 0xc6, + 0x20, 0x3d, 0x33, 0x30, 0x85, 0xcf, 0x1c, 0xc4, 0x93, 0x9b, 0x78, 0xdc, + 0xa7, 0x29, 0x89, 0x1b, 0x28, 0xae, 0x9f, 0x53, 0x23, 0x95, 0x73, 0x12, + 0x7e, 0x9f, 0xe4, 0x31, 0xcc, 0xf2, 0xb8, 0x89, 0xf8, 0x79, 0x80, 0xf0, + 0x4e, 0x3d, 0xc5, 0xa5, 0xc2, 0x81, 0x48, 0xf4, 0x97, 0xc4, 0x7b, 0xa4, + 0x44, 0xb4, 0x8f, 0xda, 0xb4, 0xdf, 0xc7, 0xb4, 0xc7, 0x4c, 0xdc, 0x43, + 0xb4, 0x1f, 0x26, 0xda, 0x07, 0xb3, 0x2c, 0x0f, 0xce, 0x3b, 0x36, 0xfd, + 0x47, 0xca, 0xbc, 0xee, 0x97, 0xf1, 0x30, 0x4f, 0x7f, 0x13, 0x36, 0x4e, + 0xcd, 0xcb, 0xcb, 0x34, 0xbf, 0xad, 0x1d, 0x33, 0xff, 0x84, 0x64, 0xb6, + 0xb8, 0xc4, 0x72, 0x83, 0x51, 0xab, 0x47, 0x0e, 0x6e, 0xc1, 0x7d, 0x0e, + 0x78, 0xbc, 0x58, 0x50, 0xe2, 0x5c, 0x10, 0xc2, 0x31, 0xd2, 0xef, 0x71, + 0xca, 0x67, 0xcf, 0x97, 0xaf, 0xcd, 0x6f, 0xac, 0xeb, 0x49, 0xd2, 0xb1, + 0x92, 0x37, 0x28, 0xb6, 0xa5, 0xca, 0x49, 0xec, 0x9e, 0x42, 0x72, 0x56, + 0xfb, 0x6f, 0x14, 0x60, 0x16, 0x91, 0x7d, 0xd5, 0x26, 0xfd, 0xaa, 0x07, + 0x9b, 0x66, 0x02, 0x18, 0x2a, 0xaf, 0x41, 0x96, 0xe2, 0xcd, 0x36, 0x8a, + 0xcf, 0x1f, 0xc7, 0x92, 0x5b, 0x7d, 0x88, 0x90, 0x7e, 0x03, 0xb8, 0x8f, + 0x9e, 0xd9, 0x37, 0xc5, 0x3c, 0xf8, 0xab, 0x7a, 0x0e, 0x60, 0x0b, 0x5d, + 0xdb, 0x33, 0x25, 0xe3, 0x25, 0xed, 0x49, 0xc2, 0x34, 0x36, 0xc6, 0xb8, + 0x27, 0x0b, 0x3f, 0xb9, 0x27, 0x61, 0xc0, 0x48, 0xf4, 0x25, 0xfa, 0xbd, + 0xb9, 0xec, 0xf1, 0x8d, 0x4c, 0xe2, 0x7b, 0x8b, 0x75, 0x1f, 0x16, 0x10, + 0x1e, 0xbb, 0x4b, 0x8b, 0x90, 0xdd, 0x3b, 0x31, 0x5c, 0x76, 0xe0, 0x3b, + 0x33, 0x1e, 0x3c, 0x34, 0xf1, 0x99, 0x59, 0x13, 0x77, 0xe2, 0x8e, 0x56, + 0x0f, 0x1e, 0x9c, 0x49, 0x62, 0xef, 0x14, 0x42, 0xb5, 0xb1, 0x31, 0x8a, + 0xdd, 0x76, 0x3e, 0xa8, 0x23, 0xde, 0x1f, 0x9b, 0xf2, 0xfa, 0x06, 0x0f, + 0xb0, 0x0c, 0xd6, 0x04, 0xdd, 0x40, 0xa5, 0x36, 0x26, 0x61, 0xb3, 0x26, + 0x2d, 0xa8, 0x25, 0x43, 0x7f, 0x92, 0xe6, 0x9b, 0x86, 0xf4, 0xda, 0x62, + 0x44, 0x0e, 0x36, 0x4b, 0x95, 0xdc, 0x02, 0x34, 0xe1, 0xa1, 0xb9, 0x24, + 0xc6, 0xc8, 0x46, 0xb7, 0x4f, 0x8c, 0x7c, 0xaf, 0x91, 0x62, 0x88, 0xaf, + 0x43, 0x19, 0x7c, 0x53, 0xe8, 0x28, 0x44, 0xdc, 0xd8, 0x36, 0xe3, 0xf5, + 0x6d, 0x3d, 0x60, 0xae, 0x66, 0x7b, 0xba, 0x77, 0xae, 0x09, 0xf7, 0x4f, + 0xd1, 0xb5, 0x09, 0xb6, 0x61, 0xb2, 0xb5, 0x48, 0x2d, 0xf1, 0x16, 0x4e, + 0xba, 0x09, 0x33, 0x49, 0xb1, 0x3a, 0x92, 0x87, 0x1b, 0x5b, 0x2c, 0x5b, + 0xf0, 0x63, 0xf3, 0x94, 0x89, 0xb3, 0x5a, 0x14, 0x39, 0xb2, 0xeb, 0x83, + 0x53, 0xca, 0xe5, 0x6e, 0xc2, 0x3b, 0xef, 0x49, 0xca, 0xc1, 0x56, 0x29, + 0x89, 0xa6, 0xe5, 0x14, 0xe3, 0x9b, 0x4c, 0xf3, 0x9e, 0x8e, 0xb6, 0xa1, + 0xb7, 0x88, 0xe6, 0x46, 0x7d, 0x11, 0x2a, 0x8d, 0x4a, 0x8e, 0xb0, 0xf3, + 0x70, 0x8d, 0xe3, 0x46, 0x9c, 0x59, 0x48, 0x7a, 0x06, 0xc7, 0xf2, 0x80, + 0xaf, 0x29, 0x63, 0xe7, 0xb8, 0x26, 0xb2, 0x93, 0xc6, 0x4c, 0xd0, 0xd7, + 0x58, 0x82, 0xaf, 0xa6, 0x04, 0xbc, 0x40, 0xf1, 0x65, 0xc1, 0xf2, 0xdf, + 0x98, 0xa9, 0x26, 0x0b, 0x13, 0xfa, 0x5e, 0x9c, 0x54, 0x8c, 0x0a, 0x94, + 0xbd, 0x14, 0x2a, 0xf1, 0xc4, 0x9c, 0xd3, 0x77, 0x98, 0xf0, 0x5f, 0x93, + 0x1a, 0xc5, 0x1e, 0xd2, 0xe7, 0x0e, 0xb2, 0x85, 0xbf, 0x27, 0x7c, 0xf2, + 0x58, 0x26, 0x1c, 0xd2, 0x44, 0x3f, 0x4d, 0x0c, 0xec, 0x2a, 0x51, 0xcc, + 0x77, 0xac, 0xa5, 0x20, 0xa6, 0x44, 0x29, 0xad, 0x21, 0x9d, 0x71, 0xc1, + 0x58, 0x68, 0xeb, 0xe4, 0xfe, 0xec, 0x71, 0xd3, 0xa7, 0xaa, 0xf9, 0x12, + 0xe9, 0xec, 0xe1, 0xb2, 0x17, 0xc3, 0x84, 0x07, 0x16, 0x10, 0x8e, 0x7c, + 0x90, 0xec, 0x62, 0xfb, 0x84, 0x44, 0xf4, 0xf1, 0xb8, 0x24, 0x92, 0x8b, + 0x6c, 0x3c, 0xfa, 0xd0, 0x0c, 0xdb, 0x25, 0xd9, 0x11, 0xd9, 0xe2, 0x31, + 0xca, 0xf9, 0xcf, 0xff, 0x16, 0x06, 0x51, 0xfc, 0xc6, 0xd5, 0xdc, 0x6f, + 0xcb, 0x63, 0x64, 0x8a, 0x79, 0x56, 0x0e, 0xc2, 0x91, 0xc4, 0x2d, 0xda, + 0xaf, 0x28, 0x27, 0x30, 0xef, 0x84, 0x83, 0xa7, 0xa2, 0x94, 0x57, 0x08, + 0xdb, 0xc4, 0x2e, 0x99, 0x5b, 0x02, 0x2c, 0x03, 0xe6, 0xe7, 0x66, 0x89, + 0xf3, 0x67, 0x13, 0xe1, 0xdf, 0xff, 0x77, 0xbb, 0xdb, 0x64, 0xa6, 0x2c, + 0x3c, 0x4b, 0x38, 0x9b, 0xec, 0x29, 0x75, 0xd5, 0x7e, 0x1e, 0x34, 0xcf, + 0x04, 0x38, 0x5f, 0x37, 0x21, 0x75, 0xd5, 0x16, 0xd8, 0x96, 0xb0, 0x58, + 0xeb, 0xd8, 0xf9, 0xa0, 0x1f, 0x6c, 0x0f, 0xd1, 0x6b, 0xec, 0xc1, 0x43, + 0x34, 0xf9, 0xb1, 0x75, 0x8e, 0xed, 0xd7, 0xfc, 0x64, 0xb1, 0xfe, 0x2f, + 0xe6, 0x95, 0x95, 0xea, 0xc1, 0x5f, 0xe1, 0xeb, 0x74, 0x3d, 0x80, 0xef, + 0x90, 0x1f, 0xdd, 0x47, 0x7c, 0x6e, 0xed, 0x7c, 0xc0, 0xf2, 0xdb, 0xad, + 0xe5, 0xdf, 0xa3, 0xeb, 0x2c, 0xef, 0x6e, 0x8a, 0x73, 0x1a, 0xf6, 0x65, + 0x2b, 0x9c, 0x87, 0xc8, 0xe6, 0xe3, 0xf8, 0x4b, 0x8a, 0xb3, 0xc7, 0xca, + 0x8c, 0xc9, 0x12, 0x16, 0x1e, 0xfb, 0x61, 0xb9, 0x1d, 0x3f, 0x20, 0x9f, + 0x7c, 0x9e, 0x62, 0xee, 0xf7, 0x2d, 0x9c, 0xe6, 0x14, 0x8f, 0xa6, 0x55, + 0x3c, 0x4d, 0x58, 0x7f, 0x5f, 0x21, 0x84, 0x23, 0xe9, 0xf0, 0xde, 0x0b, + 0x50, 0x5e, 0x20, 0x79, 0xf9, 0xf6, 0x52, 0x8d, 0x76, 0x38, 0xad, 0xe4, + 0x81, 0xa0, 0x6f, 0x4f, 0xc1, 0xef, 0x1b, 0x49, 0x07, 0x7c, 0x23, 0x84, + 0x81, 0x76, 0xa6, 0x5b, 0x7c, 0x3b, 0x0b, 0xcb, 0x11, 0x6a, 0x82, 0xb1, + 0x88, 0x72, 0xc2, 0x7d, 0x13, 0x1b, 0x90, 0x6a, 0xb4, 0xe3, 0xfc, 0x03, + 0x53, 0x1c, 0x83, 0xdb, 0x52, 0x37, 0x3a, 0xbe, 0x5e, 0xd5, 0xb7, 0x1f, + 0x43, 0x74, 0xad, 0xa1, 0x03, 0xbe, 0x37, 0xad, 0x58, 0x0b, 0x3c, 0x4f, + 0xb6, 0xf5, 0x50, 0xc7, 0x6f, 0xcc, 0x64, 0xd5, 0xb6, 0x7e, 0x30, 0xe9, + 0xa4, 0xf8, 0x6a, 0x9a, 0x47, 0x3b, 0x04, 0x02, 0x1d, 0xdd, 0x30, 0x9a, + 0xe6, 0x6b, 0xc8, 0x64, 0xbe, 0xb9, 0x83, 0x22, 0x94, 0x7a, 0x0b, 0x12, + 0x0b, 0x28, 0xb5, 0x74, 0xac, 0xae, 0xde, 0x93, 0xf1, 0x9d, 0x09, 0x37, + 0x52, 0x4d, 0x7e, 0xcc, 0x12, 0x36, 0xd9, 0x68, 0xc5, 0xa2, 0xb6, 0xd3, + 0xc7, 0xa9, 0x96, 0x09, 0x7d, 0xc3, 0x4f, 0xbc, 0x26, 0x21, 0x77, 0x10, + 0x90, 0xa8, 0xd2, 0xc4, 0xbf, 0x73, 0x73, 0x51, 0xec, 0x2e, 0xff, 0xd8, + 0x61, 0xe7, 0x13, 0x25, 0x9f, 0xc4, 0x4f, 0x28, 0x2f, 0xd2, 0xbd, 0xec, + 0x9b, 0x66, 0xc8, 0xb2, 0x33, 0x81, 0xc7, 0x97, 0x45, 0xf6, 0xfe, 0x4f, + 0xc7, 0x75, 0xc4, 0x17, 0xc9, 0x2a, 0x6b, 0xd5, 0x8e, 0x0d, 0xd7, 0xa9, + 0x0f, 0xe2, 0x2f, 0xfd, 0x2c, 0xcb, 0x61, 0x91, 0xa5, 0x3a, 0xf5, 0x8c, + 0x0b, 0x0d, 0x41, 0x35, 0x8b, 0x17, 0xfa, 0xf8, 0x5a, 0xc0, 0xf7, 0x44, + 0x3a, 0xe9, 0x08, 0xa8, 0xf0, 0xbb, 0xf4, 0x6e, 0xf1, 0x04, 0x61, 0xc0, + 0x89, 0x74, 0x8f, 0x98, 0x28, 0xdc, 0x29, 0x8c, 0xfc, 0x37, 0x85, 0x31, + 0x9b, 0x12, 0x46, 0xa1, 0x9f, 0x3e, 0x37, 0x88, 0xc9, 0xc2, 0xb0, 0xd8, + 0x5d, 0xe0, 0x79, 0x49, 0x27, 0x34, 0xf7, 0x0f, 0x29, 0xc6, 0xfe, 0x80, + 0x62, 0xec, 0x31, 0x8a, 0xb1, 0xcf, 0x93, 0x5d, 0x7f, 0xff, 0x2a, 0x96, + 0x65, 0x5b, 0x4e, 0x32, 0x06, 0xf1, 0xfd, 0xbc, 0xf4, 0x12, 0xe9, 0x95, + 0x65, 0xf6, 0x13, 0xb2, 0x61, 0x96, 0xc5, 0x7f, 0xe6, 0x9c, 0x40, 0xfa, + 0xf8, 0xd0, 0xb2, 0xd9, 0xc7, 0x97, 0x31, 0x66, 0x1a, 0x16, 0x3b, 0x98, + 0xae, 0x5a, 0xaa, 0xdb, 0x55, 0xc2, 0x21, 0xd9, 0x61, 0xb1, 0xb1, 0xc0, + 0xd7, 0xf7, 0xe1, 0x3e, 0xaa, 0xff, 0xb6, 0xc6, 0xc2, 0x89, 0x6e, 0xc2, + 0x48, 0x17, 0x54, 0x73, 0x71, 0x34, 0x46, 0x98, 0xe1, 0xc6, 0x2b, 0x54, + 0xab, 0x22, 0xb9, 0x2d, 0xae, 0xe4, 0xf3, 0x76, 0x5e, 0xcd, 0xa5, 0xc1, + 0x75, 0x3a, 0x1a, 0x9c, 0xaa, 0x72, 0x24, 0x89, 0xf0, 0xde, 0xb8, 0x03, + 0x46, 0x8d, 0xee, 0xc2, 0x80, 0x55, 0x17, 0xae, 0x41, 0x66, 0x42, 0xe0, + 0x65, 0xf2, 0x01, 0x17, 0xc9, 0xe8, 0x50, 0x27, 0x3e, 0x23, 0xb5, 0x0a, + 0xaa, 0xe3, 0x4f, 0x9f, 0xa5, 0x9c, 0x73, 0x17, 0xe5, 0xd6, 0x89, 0xec, + 0x0a, 0x04, 0x3b, 0x64, 0x34, 0x74, 0x38, 0xf1, 0x8d, 0xd2, 0xef, 0xe3, + 0x4c, 0x63, 0xe4, 0xe0, 0x0b, 0xf0, 0xf8, 0x5e, 0x9a, 0x64, 0x7a, 0xf0, + 0xbd, 0x3a, 0xaa, 0xd7, 0xb6, 0x12, 0x4e, 0x1a, 0x27, 0x1a, 0x7a, 0x3a, + 0x22, 0x3d, 0xb7, 0x09, 0xf8, 0x6b, 0xf5, 0x1a, 0x8c, 0xb7, 0xfa, 0xe0, + 0x57, 0x53, 0xe2, 0xd5, 0x02, 0xe5, 0x0d, 0xc7, 0x37, 0xc5, 0x5b, 0xb3, + 0x3a, 0xf6, 0x96, 0xfb, 0xc5, 0x2f, 0x66, 0x65, 0x90, 0x4e, 0x28, 0x3e, + 0x69, 0xc8, 0x10, 0x5d, 0x2e, 0xc2, 0x42, 0x2f, 0xdf, 0x21, 0x70, 0x9d, + 0x9a, 0xc4, 0x77, 0x56, 0xb0, 0xcd, 0xdb, 0xb1, 0x2b, 0x98, 0x51, 0x42, + 0x49, 0x47, 0xb7, 0x08, 0x52, 0xec, 0x6a, 0xc8, 0xf4, 0x88, 0x06, 0xc2, + 0x9e, 0x0b, 0xa7, 0x37, 0x88, 0x05, 0x25, 0xc6, 0x9a, 0xf0, 0x2f, 0x24, + 0xd9, 0x2c, 0x2c, 0x7d, 0x20, 0xd9, 0x18, 0xdf, 0xc5, 0xb6, 0x43, 0x39, + 0x4a, 0xf6, 0xfd, 0x7a, 0x32, 0x89, 0x5b, 0x3b, 0xd6, 0x20, 0x64, 0xd9, + 0xc7, 0xb0, 0xd8, 0x47, 0xf2, 0x4b, 0x5a, 0xfd, 0x07, 0xbf, 0xef, 0xc0, + 0x24, 0x5c, 0x7e, 0x1d, 0x21, 0x89, 0x72, 0x43, 0xa9, 0x23, 0x32, 0xf8, + 0x96, 0xe8, 0x15, 0xa3, 0x85, 0x80, 0x2f, 0x9d, 0x86, 0xbf, 0x8e, 0x74, + 0x9c, 0x26, 0x1d, 0xef, 0x21, 0x1d, 0xef, 0xf9, 0x12, 0x1d, 0xef, 0x24, + 0x1d, 0xef, 0x2f, 0xfc, 0x9d, 0xa5, 0x33, 0xa7, 0xae, 0x63, 0x94, 0x72, + 0xee, 0x78, 0xab, 0xcd, 0x4f, 0x81, 0x30, 0xea, 0x9e, 0x58, 0xaf, 0x13, + 0x1e, 0x9d, 0x62, 0x66, 0x2f, 0x3d, 0xd3, 0x5c, 0xb5, 0x65, 0xbf, 0xef, + 0xc9, 0x74, 0xb7, 0x78, 0xd2, 0xf2, 0x2b, 0xc6, 0x8d, 0x49, 0x34, 0xaa, + 0x3d, 0x34, 0x17, 0xdb, 0xca, 0x9d, 0x02, 0x4f, 0xb1, 0xbd, 0x7c, 0x93, + 0x04, 0xcf, 0x36, 0x93, 0x12, 0x28, 0xb2, 0xdd, 0xf4, 0xd3, 0x6f, 0xb6, + 0x9d, 0x0d, 0xa2, 0xb1, 0xf8, 0x45, 0xfb, 0x81, 0xdf, 0xa9, 0xb3, 0xfd, + 0xb0, 0x1d, 0x0d, 0x0b, 0x67, 0x91, 0x7c, 0x96, 0xe6, 0x1f, 0x21, 0xba, + 0x77, 0xa6, 0xf7, 0x3b, 0x99, 0x36, 0x59, 0x67, 0x3b, 0x62, 0xfb, 0xb9, + 0x48, 0xb4, 0xb2, 0xcd, 0x5f, 0xed, 0xd9, 0xd0, 0xdf, 0xef, 0x4a, 0x50, + 0xb7, 0x38, 0x6d, 0x1e, 0x38, 0x87, 0x73, 0xce, 0xe6, 0x78, 0xea, 0xb7, + 0x6a, 0xba, 0x63, 0x57, 0x73, 0x39, 0xe7, 0x75, 0xc8, 0x0b, 0xf4, 0x80, + 0xfe, 0x9d, 0xd6, 0x2b, 0x34, 0xdf, 0x10, 0xb4, 0x15, 0x90, 0x03, 0xfa, + 0xa4, 0x3e, 0xd9, 0x4a, 0xf1, 0x96, 0xe6, 0x94, 0x33, 0x80, 0x9a, 0x11, + 0xd8, 0x99, 0x10, 0x84, 0x47, 0x17, 0x91, 0xbf, 0xc1, 0xf0, 0xe8, 0x4a, + 0x4f, 0x92, 0xee, 0x2d, 0x25, 0x7c, 0xbe, 0x58, 0xdf, 0x06, 0x33, 0x0b, + 0xb9, 0x41, 0x1f, 0xc4, 0x27, 0xa3, 0x61, 0xff, 0x79, 0x28, 0xa9, 0xb3, + 0x92, 0x52, 0xa1, 0x3c, 0x35, 0x34, 0x22, 0x94, 0xc1, 0xcb, 0x42, 0x49, + 0x96, 0xac, 0x1e, 0xcf, 0x36, 0xb4, 0x5b, 0x58, 0x7c, 0x10, 0xd1, 0x02, + 0x70, 0x1b, 0x01, 0xbc, 0x7b, 0x6e, 0x26, 0x9b, 0xd4, 0x3e, 0xe2, 0xd8, + 0x9e, 0x3c, 0x43, 0x54, 0x2f, 0xce, 0x70, 0xcf, 0x68, 0x5b, 0xb5, 0x67, + 0x34, 0x68, 0xf5, 0x8c, 0xce, 0x4b, 0x4a, 0x62, 0xbe, 0x67, 0x74, 0x05, + 0x3c, 0x97, 0xd2, 0xef, 0xad, 0xce, 0xb7, 0xb4, 0x3a, 0x5f, 0x5b, 0x01, + 0x22, 0x9a, 0x31, 0xcc, 0x1a, 0xd5, 0x43, 0xfc, 0x26, 0x1d, 0xae, 0x88, + 0xda, 0x73, 0x18, 0x21, 0x44, 0xa9, 0xde, 0xbd, 0x9e, 0xf2, 0xa0, 0x3b, + 0xb3, 0x03, 0x33, 0x9a, 0xd2, 0x37, 0x00, 0xb6, 0x9d, 0x6e, 0xec, 0xa3, + 0x18, 0xba, 0xb7, 0xcc, 0xf5, 0xc8, 0xb0, 0x38, 0xcb, 0x76, 0xe3, 0xb4, + 0xa5, 0x66, 0xaf, 0xff, 0x70, 0x75, 0xfd, 0x21, 0x6b, 0xfd, 0x0b, 0x92, + 0xd2, 0x5f, 0x5d, 0x5f, 0xfb, 0x33, 0xa1, 0xa4, 0x68, 0xfd, 0x9e, 0x3d, + 0xb4, 0xbe, 0x4b, 0xe5, 0xb5, 0x1f, 0xe6, 0xb5, 0xe9, 0x73, 0x08, 0xd7, + 0x93, 0xdd, 0xbc, 0x57, 0x90, 0xc5, 0xbb, 0xb9, 0x35, 0xd8, 0x35, 0xb3, + 0x06, 0x3b, 0xc9, 0xdf, 0xb6, 0x6a, 0x0d, 0x54, 0xa7, 0xa1, 0xde, 0xa7, + 0xe2, 0xb2, 0x23, 0x22, 0xa4, 0xf5, 0xed, 0x2d, 0x84, 0x41, 0x4e, 0x34, + 0xcb, 0xf8, 0xd4, 0x1c, 0x50, 0xd7, 0xf4, 0x39, 0x91, 0xfc, 0x7d, 0x0f, + 0xfe, 0x5c, 0x22, 0xff, 0x7d, 0x67, 0x81, 0x40, 0xd2, 0x63, 0xd5, 0x1c, + 0x09, 0xe1, 0x29, 0xfe, 0xd8, 0x69, 0xdb, 0x7b, 0x2b, 0x7c, 0x8d, 0x68, + 0x68, 0x50, 0x6f, 0x40, 0x43, 0xa3, 0x6c, 0x38, 0xa8, 0x8e, 0x59, 0x4f, + 0x21, 0xd1, 0xcc, 0xf5, 0x51, 0x3c, 0x35, 0x71, 0x65, 0xf9, 0xdf, 0x9b, + 0x89, 0xeb, 0xf8, 0x39, 0x02, 0x15, 0x56, 0x4c, 0xfc, 0xb2, 0x39, 0xe2, + 0xe4, 0xbf, 0x6d, 0x54, 0x97, 0xd6, 0x51, 0xf0, 0xed, 0xc1, 0x9e, 0xac, + 0x92, 0xda, 0x43, 0x75, 0xe5, 0xfe, 0x48, 0x5b, 0xcf, 0x26, 0x51, 0x83, + 0xd0, 0xc2, 0xf0, 0xe0, 0x00, 0x92, 0xcd, 0xf5, 0x55, 0x3a, 0x1e, 0x46, + 0xb3, 0x8b, 0x9e, 0xe3, 0x79, 0xae, 0xb1, 0xa7, 0x22, 0xd9, 0x13, 0xdf, + 0xe7, 0xef, 0x57, 0xef, 0xcb, 0xbf, 0xa3, 0x4f, 0xae, 0xfa, 0xaf, 0x4b, + 0xbf, 0xec, 0xfa, 0xb1, 0x2f, 0xb9, 0xfe, 0x6f, 0xd5, 0xe7, 0x95, 0x46, + 0xa7, 0x95, 0xfb, 0x93, 0x0e, 0xee, 0x4b, 0x3a, 0xf5, 0x42, 0xd7, 0x2e, + 0xf5, 0x3f, 0x51, 0xcc, 0xe2, 0x7e, 0x04, 0xe7, 0xdb, 0x33, 0x56, 0x3f, + 0xe2, 0xf8, 0x6f, 0x61, 0x4f, 0x8e, 0x1d, 0x6e, 0x51, 0x37, 0x6e, 0x98, + 0x4d, 0xea, 0x1f, 0x51, 0x7d, 0xb2, 0x03, 0x03, 0x31, 0x0d, 0x63, 0x59, + 0xa5, 0xef, 0x0e, 0xa8, 0xc9, 0x3b, 0x05, 0x4d, 0x54, 0x72, 0x0b, 0x69, + 0xbc, 0x7a, 0x4f, 0x33, 0xa8, 0xe6, 0xaa, 0xa0, 0x96, 0x62, 0x8f, 0x53, + 0xf5, 0xcb, 0x28, 0x05, 0x64, 0x67, 0x29, 0x28, 0xd7, 0x94, 0x5a, 0xe4, + 0x5a, 0x1a, 0xe7, 0x1d, 0x57, 0x2e, 0xdf, 0x81, 0x1d, 0xb8, 0xbc, 0xdc, + 0x63, 0x34, 0xeb, 0x8a, 0xbf, 0x59, 0xda, 0x81, 0x5d, 0x31, 0x7e, 0xb6, + 0x9b, 0x6a, 0x2f, 0x88, 0xc6, 0x0c, 0x21, 0x5c, 0x5d, 0x60, 0x37, 0xd5, + 0x97, 0x4b, 0x1c, 0x6a, 0xcf, 0xaf, 0x85, 0x53, 0x76, 0x97, 0x20, 0x7c, + 0x19, 0x07, 0x0e, 0x76, 0xc2, 0xed, 0x5e, 0xa1, 0x0c, 0x9e, 0x10, 0xc3, + 0x78, 0x36, 0x16, 0xe9, 0xdb, 0x2c, 0x42, 0xb2, 0x87, 0xee, 0xb9, 0x32, + 0x10, 0x72, 0xc6, 0x70, 0xbb, 0x56, 0x28, 0x41, 0x87, 0x48, 0x62, 0x40, + 0x55, 0xb5, 0x71, 0xc8, 0xb4, 0x26, 0x44, 0x6d, 0x46, 0xb9, 0x7c, 0x96, + 0xb0, 0xd1, 0x95, 0xa5, 0xc3, 0xe8, 0x58, 0x1e, 0xd9, 0xdb, 0xef, 0x50, + 0x65, 0xc2, 0x6c, 0xc2, 0x99, 0xf1, 0xe2, 0xa6, 0x03, 0xf3, 0xfd, 0x19, + 0xd3, 0xfc, 0x38, 0x56, 0xb9, 0x97, 0x44, 0x28, 0xd7, 0x97, 0xa2, 0xb2, + 0x97, 0xf0, 0x79, 0xdb, 0x01, 0xc6, 0x4b, 0x9c, 0x0f, 0x2a, 0x64, 0x37, + 0xed, 0xc4, 0x63, 0x1f, 0x66, 0xd2, 0x8c, 0x9f, 0x74, 0x4c, 0x53, 0x6d, + 0xa3, 0x8e, 0xb6, 0x50, 0xae, 0x4f, 0x60, 0x2e, 0xcd, 0x7d, 0x9c, 0x41, + 0x92, 0x71, 0x3f, 0xd1, 0xbf, 0x81, 0xea, 0xda, 0x14, 0xc5, 0x2b, 0x96, + 0xf1, 0x00, 0xf7, 0x6b, 0xa9, 0x96, 0xfe, 0x79, 0xd7, 0xd7, 0xc6, 0x20, + 0xbb, 0xf5, 0xd7, 0xba, 0xae, 0x3f, 0x80, 0x46, 0xca, 0xe7, 0x3a, 0x55, + 0x2e, 0x88, 0x46, 0x22, 0xda, 0x79, 0x44, 0x82, 0x2f, 0x93, 0x3e, 0x46, + 0x54, 0x60, 0xa7, 0x55, 0x33, 0x3b, 0x61, 0x14, 0xd8, 0xa6, 0xe0, 0xae, + 0xed, 0x6c, 0xc4, 0xfb, 0xb9, 0xa8, 0xd5, 0x0b, 0x32, 0xa8, 0x8e, 0x79, + 0x49, 0x53, 0x52, 0x79, 0x7a, 0x6e, 0xa3, 0xff, 0x7f, 0xed, 0xa9, 0x8b, + 0x43, 0xae, 0x53, 0xd9, 0xbf, 0xfe, 0xdc, 0x73, 0x96, 0x6c, 0xf4, 0xae, + 0xc9, 0xbf, 0xf0, 0x7c, 0x12, 0xcf, 0x7b, 0x3e, 0x8a, 0x9b, 0x66, 0x82, + 0x70, 0x65, 0x3f, 0xd5, 0xcd, 0x1f, 0x8f, 0x1a, 0x9e, 0xf3, 0x71, 0xee, + 0xe9, 0x3a, 0xf1, 0x07, 0xf4, 0xfb, 0xe9, 0x51, 0x19, 0xb7, 0x16, 0x9b, + 0xe1, 0x1a, 0x93, 0xc8, 0x3f, 0xd7, 0x52, 0xae, 0x72, 0xe0, 0x9e, 0xe8, + 0x51, 0x54, 0x02, 0x0e, 0x1a, 0xb3, 0x9f, 0x7e, 0x73, 0x6f, 0xea, 0x71, + 0x6c, 0xf6, 0xcf, 0x7a, 0xde, 0x8f, 0x33, 0xbd, 0x15, 0xa6, 0x97, 0x72, + 0xe4, 0xed, 0xd8, 0x78, 0x07, 0x0c, 0x9f, 0x6e, 0xfd, 0xbb, 0x5f, 0xee, + 0x6c, 0xc2, 0xe1, 0x5c, 0x33, 0x5e, 0xcc, 0x19, 0xee, 0x9f, 0x76, 0x46, + 0x31, 0x38, 0x6a, 0xe2, 0x15, 0xcd, 0x18, 0xae, 0x25, 0x3b, 0x4f, 0x50, + 0xad, 0x14, 0x5e, 0xae, 0xf8, 0x2f, 0x0b, 0x44, 0x24, 0x44, 0x86, 0x08, + 0x2c, 0xde, 0x4d, 0xa1, 0x2b, 0x55, 0xaf, 0x47, 0xb4, 0xd7, 0x85, 0x59, + 0x73, 0x6f, 0xa7, 0x93, 0x68, 0x00, 0xd6, 0x51, 0x4c, 0x9e, 0x4b, 0x47, + 0x71, 0x6b, 0x44, 0xc6, 0xfa, 0xa2, 0x86, 0x17, 0xd3, 0x5e, 0xdc, 0x55, + 0x8c, 0x13, 0x86, 0xf6, 0x13, 0xed, 0x09, 0x94, 0xd3, 0x01, 0x7c, 0xbd, + 0xd8, 0x42, 0xf2, 0x0e, 0x62, 0x6d, 0x91, 0x31, 0x16, 0xe7, 0x67, 0xdd, + 0xbd, 0x31, 0xde, 0x82, 0x1e, 0x8a, 0xdf, 0xb3, 0x69, 0xb8, 0xb7, 0xc7, + 0x43, 0xe8, 0x2e, 0x46, 0x51, 0x24, 0x2c, 0x76, 0x3b, 0xcd, 0x79, 0x17, + 0xe9, 0xa4, 0x9d, 0xea, 0xfb, 0x25, 0x11, 0x42, 0xa8, 0x45, 0xaf, 0x18, + 0x26, 0xcc, 0x94, 0x28, 0x36, 0xe1, 0xfc, 0x18, 0xdb, 0xf9, 0x5b, 0x5d, + 0xbb, 0x72, 0x7e, 0x84, 0x8a, 0xb8, 0x49, 0x06, 0xb6, 0x51, 0x95, 0x97, + 0x2a, 0x12, 0xbd, 0xfb, 0x3a, 0xed, 0x7e, 0xec, 0x0d, 0xc5, 0xcf, 0xf9, + 0x6d, 0x20, 0x3d, 0x7d, 0x72, 0x60, 0xd6, 0x73, 0x85, 0x64, 0xe0, 0xd3, + 0x7f, 0xd4, 0xf5, 0xc6, 0x01, 0x20, 0x3a, 0xc5, 0xbc, 0x71, 0x7c, 0x0d, + 0x27, 0x28, 0xbe, 0xb6, 0xcb, 0xf8, 0xb5, 0x49, 0xb5, 0x64, 0x68, 0x86, + 0x7b, 0xff, 0xaa, 0x97, 0xe8, 0xf0, 0x23, 0x49, 0x6b, 0xdf, 0x56, 0xfc, + 0xa1, 0xb9, 0x71, 0x61, 0x10, 0x5f, 0x8b, 0xd8, 0xb2, 0x7a, 0x9d, 0x74, + 0x38, 0x3d, 0xd6, 0x8c, 0xb9, 0x31, 0xee, 0xad, 0x9c, 0xea, 0x3a, 0x34, + 0x69, 0x62, 0x9d, 0x66, 0x78, 0x7e, 0xda, 0x79, 0x03, 0x1e, 0x38, 0x30, + 0x72, 0xba, 0x86, 0xf4, 0x7a, 0x59, 0xbb, 0x1b, 0x8f, 0x4e, 0xe1, 0xab, + 0xcd, 0xc0, 0x23, 0x41, 0x70, 0xff, 0x59, 0x09, 0x1d, 0x41, 0xa4, 0x67, + 0x3b, 0x22, 0x7e, 0x55, 0x28, 0xda, 0x2b, 0x14, 0xab, 0xea, 0x08, 0x3b, + 0xdc, 0x46, 0xb5, 0x7c, 0x0d, 0x79, 0xf0, 0x5d, 0x45, 0x27, 0xc9, 0x28, + 0x88, 0xf2, 0x58, 0x0d, 0x24, 0xf2, 0x93, 0x0b, 0x2a, 0xd6, 0x35, 0x90, + 0xac, 0x25, 0x21, 0x93, 0x9e, 0xdb, 0x71, 0x68, 0x74, 0x5e, 0x56, 0x5e, + 0xdc, 0x42, 0x32, 0x7c, 0x76, 0xd4, 0xdc, 0xa1, 0xc6, 0x02, 0x24, 0x6b, + 0x3f, 0xd1, 0x37, 0x2f, 0x27, 0x96, 0xdf, 0xbc, 0x9c, 0xee, 0xc6, 0xae, + 0x39, 0x96, 0xdb, 0xbf, 0x47, 0x5e, 0xb3, 0x96, 0xdd, 0xad, 0x9b, 0x8c, + 0xa2, 0xf9, 0xc0, 0x55, 0xd9, 0x31, 0x7d, 0x8f, 0x10, 0x1f, 0xdf, 0xf3, + 0xad, 0x8c, 0x0c, 0x5e, 0x14, 0x5e, 0xa2, 0xc7, 0x4f, 0xba, 0x39, 0xeb, + 0x62, 0x0c, 0x4e, 0x32, 0xb9, 0x2a, 0xe3, 0x20, 0xc9, 0x38, 0x38, 0xc5, + 0xb2, 0xfe, 0x11, 0xc9, 0x1a, 0x78, 0x83, 0x70, 0xd7, 0xcd, 0xb1, 0x28, + 0xea, 0x0f, 0x28, 0xc9, 0x66, 0x29, 0x9c, 0x68, 0x10, 0xa0, 0xea, 0x02, + 0xed, 0xf5, 0xf8, 0x98, 0xe5, 0xac, 0x91, 0x9c, 0xbf, 0x37, 0x42, 0xfc, + 0xac, 0xa1, 0xf9, 0xd6, 0x91, 0x9c, 0x93, 0xc4, 0xff, 0x6d, 0xd6, 0xbc, + 0x2d, 0x34, 0xef, 0x06, 0xaa, 0x21, 0x66, 0x3d, 0x17, 0x88, 0x9e, 0xe8, + 0xe7, 0xb4, 0x10, 0xca, 0x8e, 0x04, 0x2f, 0x52, 0xad, 0xbc, 0xd6, 0x1a, + 0xe7, 0xa7, 0x71, 0x4c, 0xfb, 0x5b, 0xb5, 0x0e, 0xf5, 0xcb, 0x7a, 0xc7, + 0x77, 0x83, 0x7b, 0x07, 0x06, 0xfa, 0xb1, 0x37, 0xbb, 0x81, 0x6a, 0x1e, + 0x99, 0x30, 0xa4, 0x81, 0xef, 0xc7, 0x95, 0x68, 0xa3, 0xe0, 0xf8, 0x67, + 0x90, 0x1f, 0x56, 0xa8, 0xde, 0x09, 0x87, 0xe6, 0x10, 0x94, 0x1d, 0x25, + 0x99, 0xf0, 0x5e, 0x8b, 0x2c, 0x95, 0xc8, 0x5f, 0x83, 0xfd, 0x84, 0x93, + 0x9d, 0x78, 0xb9, 0xe0, 0xc4, 0xab, 0xe9, 0x0d, 0x94, 0xe7, 0xdc, 0x84, + 0x87, 0x0d, 0xb7, 0x73, 0xc5, 0x81, 0x1a, 0x3b, 0x26, 0x2f, 0x45, 0xef, + 0xf8, 0xc3, 0xa8, 0xcb, 0x38, 0xfb, 0x28, 0x47, 0x6b, 0xb7, 0x91, 0x5c, + 0xd6, 0x95, 0xf8, 0x7e, 0x0b, 0x32, 0xe9, 0x14, 0xb2, 0xd9, 0x30, 0xd5, + 0x32, 0x4e, 0xe4, 0x9b, 0x5b, 0xac, 0xfe, 0x6c, 0x8e, 0xae, 0xe5, 0xca, + 0x5f, 0xec, 0x1b, 0x7f, 0xab, 0xda, 0x2f, 0x1e, 0xa4, 0x9c, 0xd2, 0x4f, + 0xd8, 0x73, 0x03, 0xc5, 0x77, 0x9b, 0xc6, 0xd9, 0x78, 0x1f, 0xf6, 0x14, + 0xf4, 0xab, 0xf1, 0x63, 0xba, 0x60, 0xf7, 0x05, 0xb7, 0x90, 0x3c, 0xce, + 0xa5, 0x4d, 0x3c, 0xaa, 0xb1, 0x3e, 0x29, 0x2e, 0xa5, 0xb9, 0x37, 0x68, + 0xe2, 0x19, 0x4d, 0x70, 0xbc, 0xa1, 0x3c, 0xba, 0x01, 0x4b, 0x0a, 0x26, + 0x4e, 0x6b, 0x2a, 0xc5, 0x2e, 0x18, 0x6e, 0xc2, 0x7e, 0x91, 0xd1, 0x7f, + 0x31, 0xf3, 0xce, 0x21, 0xb4, 0x75, 0x02, 0x9b, 0x47, 0x25, 0xcc, 0xcd, + 0x5c, 0xcd, 0xd1, 0x78, 0xf1, 0xf3, 0x3c, 0x9d, 0x98, 0x81, 0xb9, 0xc3, + 0xa9, 0x2b, 0xc3, 0xbc, 0xd7, 0x32, 0x12, 0x57, 0x12, 0xb5, 0x56, 0xce, + 0x56, 0xfb, 0x97, 0x48, 0x8a, 0x56, 0x12, 0x6d, 0xa9, 0x4f, 0x50, 0x59, + 0x2f, 0x43, 0x09, 0xfe, 0x0c, 0x91, 0xe8, 0x20, 0xef, 0x29, 0x94, 0xed, + 0xfc, 0xbd, 0xb4, 0x9a, 0xbf, 0xc3, 0x05, 0x8f, 0x50, 0xc7, 0x1c, 0xc8, + 0xcf, 0x98, 0x94, 0x67, 0x05, 0x66, 0x49, 0xc1, 0x2f, 0x64, 0x77, 0xe0, + 0xeb, 0x31, 0xd3, 0xbc, 0x2b, 0xae, 0x0e, 0x36, 0x4b, 0xf8, 0xd3, 0x06, + 0xc2, 0x14, 0x64, 0xf7, 0x84, 0x01, 0x10, 0xda, 0xda, 0x69, 0x98, 0x32, + 0xd5, 0x0c, 0x35, 0x3a, 0xf7, 0x1a, 0x7b, 0x45, 0x7b, 0x71, 0x83, 0xb8, + 0xa1, 0xd8, 0x2f, 0x42, 0x87, 0xee, 0x14, 0xd1, 0xa7, 0x6c, 0xdc, 0xd6, + 0x5a, 0xfc, 0xbc, 0x1f, 0xda, 0x43, 0x7c, 0xef, 0xd3, 0x4c, 0x3c, 0x4d, + 0xbc, 0xed, 0x2d, 0xdb, 0xb5, 0xc8, 0xee, 0xb4, 0xcd, 0xdb, 0xa3, 0x74, + 0xff, 0x62, 0x9a, 0xfd, 0xf1, 0x61, 0xab, 0xd7, 0xd9, 0x4c, 0xcf, 0xdc, + 0x9c, 0x0d, 0x87, 0x06, 0x85, 0x32, 0x34, 0x0b, 0xee, 0x77, 0xb6, 0x55, + 0x4e, 0x0a, 0xca, 0x3d, 0x12, 0xc7, 0x57, 0xf6, 0x79, 0x9b, 0xf6, 0x65, + 0x05, 0x58, 0x71, 0x91, 0xe9, 0xbf, 0x91, 0xea, 0xbe, 0x9f, 0xa5, 0xdb, + 0xfa, 0xdd, 0x24, 0xb6, 0xf3, 0xf1, 0x6e, 0x71, 0x89, 0xea, 0xbe, 0x57, + 0xd3, 0xc9, 0x85, 0x75, 0xe8, 0x11, 0x17, 0x0a, 0x7d, 0xe2, 0xc3, 0x7c, + 0x2f, 0x9c, 0x63, 0xf7, 0x8b, 0x77, 0xf3, 0x4c, 0x5b, 0xbf, 0x38, 0x33, + 0x7b, 0xde, 0x92, 0xfd, 0x2e, 0x8d, 0xfb, 0x9a, 0xf5, 0xb5, 0xf0, 0x99, + 0x04, 0x4f, 0x59, 0x8f, 0xdc, 0xe7, 0xb3, 0xfb, 0x43, 0xeb, 0xe2, 0x39, + 0xd3, 0xa9, 0x72, 0xaf, 0x37, 0x68, 0xf1, 0x38, 0x43, 0x78, 0x79, 0x36, + 0xbf, 0x41, 0x1c, 0x2e, 0xd8, 0xfc, 0x4d, 0x17, 0xd8, 0x6e, 0x65, 0xca, + 0x0d, 0x5f, 0xcc, 0xcf, 0x06, 0xfc, 0x9d, 0x41, 0xd4, 0x58, 0xfd, 0x24, + 0x13, 0xe3, 0x5a, 0x24, 0xf4, 0x0a, 0x82, 0x70, 0x96, 0xd8, 0xa6, 0x4d, + 0x3c, 0xa7, 0xb9, 0x20, 0x8d, 0xcb, 0x24, 0x17, 0xb2, 0x21, 0x9f, 0x0b, + 0x8e, 0x69, 0xae, 0x01, 0xe2, 0xb5, 0xdc, 0x67, 0x08, 0x39, 0xf8, 0xfb, + 0x17, 0x6d, 0xcd, 0x45, 0x79, 0x80, 0xfb, 0xe3, 0x6f, 0xd6, 0xd8, 0x36, + 0xc7, 0xf9, 0x68, 0xbe, 0xa7, 0x4d, 0x39, 0xb6, 0x93, 0x7b, 0xd9, 0x6e, + 0xcc, 0xe5, 0x6a, 0xb8, 0xc5, 0xe0, 0xae, 0xe9, 0x34, 0x71, 0x4e, 0x73, + 0x52, 0x5d, 0xf2, 0x10, 0xe5, 0x26, 0x07, 0x64, 0xf5, 0x6e, 0x94, 0x26, + 0x9d, 0x0e, 0xde, 0x73, 0xfa, 0x59, 0x8c, 0x7b, 0x00, 0xc0, 0x7e, 0xe2, + 0xe1, 0x99, 0x5c, 0x88, 0xea, 0x7f, 0xb9, 0x5a, 0x43, 0xfc, 0x01, 0x8e, + 0xe7, 0x24, 0xd1, 0xac, 0x43, 0x4a, 0xac, 0x34, 0xf1, 0xc9, 0xf2, 0x48, + 0xf4, 0x32, 0xc5, 0x2f, 0x3f, 0xe5, 0xaa, 0xdd, 0x85, 0x46, 0xfc, 0x2c, + 0xd7, 0x88, 0x57, 0x73, 0xa4, 0xc3, 0xd8, 0x48, 0xbf, 0x87, 0x62, 0xe4, + 0xd2, 0x98, 0x0b, 0x5b, 0x23, 0x86, 0xdf, 0x83, 0x28, 0xce, 0x25, 0xae, + 0x47, 0x2a, 0x10, 0xee, 0x19, 0x41, 0x13, 0xde, 0xcc, 0x81, 0x30, 0x04, + 0xdc, 0x4b, 0x68, 0x8e, 0xf7, 0x62, 0xc6, 0x90, 0x0b, 0x0a, 0xd5, 0x1f, + 0x88, 0xd7, 0xc3, 0xac, 0x39, 0x19, 0xa7, 0x1c, 0x5d, 0x6c, 0x44, 0x6f, + 0xae, 0x09, 0xfd, 0x94, 0xab, 0x56, 0xaf, 0x8c, 0xe3, 0xdd, 0xac, 0x57, + 0xdc, 0x94, 0x1d, 0xe9, 0xf7, 0xd3, 0x9c, 0xae, 0xe5, 0xca, 0xd0, 0xb3, + 0x04, 0xd8, 0x64, 0x84, 0xd9, 0xbc, 0xb7, 0xfb, 0x28, 0xde, 0x1e, 0x16, + 0x9f, 0xe1, 0x49, 0xb2, 0xc1, 0x2d, 0x9a, 0x52, 0xb9, 0x20, 0x45, 0x4e, + 0xaf, 0x87, 0x32, 0x7c, 0x9b, 0x30, 0xa2, 0x0d, 0x14, 0x47, 0x9a, 0xed, + 0x18, 0x61, 0x44, 0x84, 0x4c, 0x98, 0xdc, 0x09, 0xb7, 0x6a, 0xa0, 0xa7, + 0x93, 0x65, 0xea, 0x86, 0xfb, 0x29, 0xb2, 0x1b, 0xc7, 0x17, 0xfb, 0xf3, + 0x8d, 0x78, 0x83, 0xf2, 0xe4, 0xeb, 0x39, 0xc8, 0xb5, 0x14, 0xfb, 0x3f, + 0xa0, 0xd8, 0x7f, 0x2a, 0x36, 0x12, 0xe2, 0x98, 0x5f, 0x88, 0xe1, 0x5b, + 0x04, 0x83, 0x5b, 0xbc, 0xb4, 0xe6, 0x26, 0xc1, 0xeb, 0x20, 0xb9, 0x58, + 0xe7, 0xbe, 0x9a, 0xc5, 0x0f, 0xc5, 0x61, 0xe6, 0xe9, 0xff, 0x27, 0xed, + 0xdb, 0x6b, 0xe1, 0x69, 0x22, 0x5d, 0xce, 0xf7, 0x24, 0xaf, 0xed, 0x47, + 0x72, 0x1d, 0x63, 0xe3, 0xc2, 0x1a, 0xbd, 0x4e, 0xbc, 0x94, 0x63, 0x9b, + 0x33, 0xf1, 0xbc, 0xa6, 0x51, 0xcd, 0xc2, 0xb5, 0xf6, 0x10, 0xd5, 0x2d, + 0xdc, 0x27, 0x32, 0xdc, 0x27, 0x89, 0xc2, 0xbd, 0x39, 0xfc, 0x9e, 0x0c, + 0x69, 0x59, 0x2d, 0xa6, 0x90, 0x77, 0x3a, 0x09, 0x6b, 0x70, 0x8c, 0x65, + 0x3f, 0x7a, 0xab, 0x4b, 0xcd, 0xc3, 0xf0, 0xea, 0x3d, 0x30, 0x2c, 0xdf, + 0xad, 0x13, 0x0f, 0x90, 0x8d, 0xbc, 0x1c, 0xab, 0x45, 0x9e, 0xea, 0x1e, + 0xc2, 0xdf, 0xee, 0x3f, 0xa3, 0xe7, 0x13, 0x13, 0xd8, 0x13, 0x84, 0xf4, + 0x5d, 0x3f, 0xfe, 0x02, 0x67, 0x5d, 0x8c, 0xcb, 0xe1, 0xee, 0x8b, 0x1b, + 0x9e, 0xf5, 0xf1, 0x3a, 0x71, 0x7b, 0xae, 0x1d, 0x17, 0x27, 0x1b, 0xc9, + 0xbe, 0x9b, 0xb0, 0x78, 0x3c, 0x88, 0xf7, 0x88, 0x96, 0x61, 0x8d, 0xb1, + 0xba, 0x31, 0xdc, 0x0c, 0x65, 0x88, 0xea, 0xa1, 0xbe, 0x9f, 0x0b, 0xf6, + 0x01, 0xa5, 0xe7, 0x0e, 0xe1, 0x81, 0x1a, 0x49, 0x92, 0xec, 0x4d, 0x73, + 0x4c, 0x6b, 0xd3, 0xbc, 0xe0, 0xfe, 0xcf, 0xdd, 0xd8, 0x3f, 0xc7, 0xb4, + 0x9c, 0xea, 0xba, 0x61, 0x96, 0x3f, 0x4f, 0x77, 0x5d, 0x6f, 0x7d, 0xbe, + 0x56, 0xfd, 0xac, 0x74, 0x85, 0xac, 0xcf, 0x1f, 0xd1, 0x27, 0xf7, 0x99, + 0xc3, 0x46, 0x8d, 0xf8, 0xbe, 0x8b, 0xfb, 0xcd, 0x49, 0xf0, 0xff, 0x71, + 0x97, 0xdd, 0xaf, 0xbb, 0x1b, 0x86, 0xd5, 0x13, 0xf9, 0xb5, 0xd5, 0x8b, + 0x0e, 0x91, 0x1b, 0xc8, 0xc4, 0x9f, 0x4c, 0x58, 0x2b, 0x10, 0xa3, 0xc2, + 0xbc, 0x49, 0x36, 0x16, 0xeb, 0xfd, 0x54, 0x1b, 0xc8, 0xc4, 0xaf, 0x81, + 0x3d, 0x9d, 0x02, 0xfb, 0x55, 0x1d, 0x3f, 0x2d, 0x70, 0x0c, 0x77, 0xe2, + 0x99, 0xb4, 0x12, 0x4a, 0x89, 0x30, 0xd5, 0xf9, 0x0e, 0x84, 0x9a, 0xfb, + 0xb1, 0x9f, 0xf2, 0xc9, 0x6c, 0x9a, 0xf3, 0x07, 0x7d, 0x52, 0x3c, 0x6f, + 0xa0, 0xf8, 0xf3, 0xf1, 0xa8, 0x1d, 0xef, 0x8b, 0x71, 0x65, 0xef, 0x1f, + 0x90, 0x4e, 0x9f, 0x2b, 0xf2, 0x9c, 0x06, 0xae, 0xac, 0x64, 0x1f, 0x56, + 0xa2, 0x29, 0xc7, 0x7d, 0x08, 0xcd, 0x70, 0x6c, 0xa1, 0xe5, 0x68, 0xad, + 0x83, 0xd9, 0x1a, 0xf4, 0xc5, 0x7b, 0x45, 0x7f, 0xa9, 0x8f, 0xf7, 0x14, + 0xfc, 0x0b, 0xf4, 0x3b, 0xc5, 0x9a, 0x69, 0xee, 0x09, 0x6e, 0x10, 0x7d, + 0x25, 0xee, 0x0b, 0x0e, 0x8b, 0x6f, 0x94, 0xd8, 0xe7, 0xe7, 0xfb, 0x83, + 0xf3, 0xfa, 0xe7, 0xbe, 0xa0, 0xe1, 0x7e, 0x89, 0x64, 0xbf, 0x3d, 0xc7, + 0x71, 0x58, 0x7a, 0xc0, 0x87, 0xe5, 0xc8, 0xbb, 0xe0, 0x3e, 0x11, 0xff, + 0x1d, 0xdc, 0x45, 0xb8, 0x60, 0xb1, 0x6a, 0xeb, 0x6f, 0x75, 0xde, 0x81, + 0xc4, 0x72, 0x12, 0xfa, 0x02, 0xd6, 0xe9, 0x00, 0xc5, 0xb3, 0x8c, 0x39, + 0x18, 0x60, 0x5d, 0xb2, 0xbd, 0x59, 0x7d, 0x27, 0xca, 0x2b, 0x06, 0x22, + 0x9d, 0x6e, 0xcc, 0xe6, 0x16, 0x51, 0x4d, 0x60, 0x62, 0xaf, 0x56, 0x8f, + 0x5a, 0x2b, 0x06, 0xb8, 0x09, 0x47, 0x42, 0xf6, 0xd2, 0x3c, 0xe9, 0x31, + 0x19, 0x1e, 0xba, 0x77, 0x92, 0x72, 0xd3, 0xfe, 0x4e, 0x7b, 0xee, 0xb6, + 0xfc, 0x4d, 0xd8, 0x47, 0x1e, 0x5f, 0xaf, 0x46, 0x31, 0xea, 0xf7, 0x52, + 0xac, 0xf9, 0x56, 0x75, 0xce, 0xcf, 0xc8, 0x36, 0x79, 0xbd, 0x4d, 0xb5, + 0xb6, 0x1e, 0x96, 0xc9, 0x76, 0xed, 0x25, 0x1b, 0x75, 0xb4, 0xd6, 0xd6, + 0xce, 0x0d, 0xe8, 0x19, 0xf5, 0x8a, 0x57, 0xd3, 0xf7, 0x98, 0xa1, 0x46, + 0x1a, 0x47, 0x36, 0x5b, 0x53, 0xa5, 0xb7, 0x35, 0xff, 0xcf, 0xb5, 0x5c, + 0xa7, 0x7b, 0x29, 0x8f, 0x3c, 0x98, 0x73, 0x20, 0x50, 0xbd, 0x1e, 0xcf, + 0x87, 0xa0, 0x75, 0xd4, 0x01, 0x4d, 0x82, 0xae, 0xf1, 0xdc, 0xbc, 0x86, + 0x8c, 0x46, 0xf2, 0x93, 0x6f, 0xc7, 0x13, 0xf8, 0x20, 0xeb, 0xc4, 0x7a, + 0xca, 0xef, 0x6b, 0xd3, 0x3a, 0xce, 0x95, 0x6b, 0x79, 0x3d, 0xb2, 0xc3, + 0xf9, 0x71, 0x4e, 0x1a, 0xe7, 0xc6, 0x74, 0xfe, 0x8b, 0xf4, 0x05, 0x88, + 0xe6, 0x22, 0x8d, 0xe5, 0x7b, 0xe7, 0xad, 0xbe, 0xc0, 0xf1, 0x6b, 0xea, + 0x29, 0xc7, 0x38, 0xf7, 0x8a, 0xec, 0x5c, 0xd0, 0xad, 0xb1, 0x2e, 0x7d, + 0xb8, 0x3c, 0x61, 0xe0, 0xdc, 0xca, 0x06, 0x5c, 0x99, 0x68, 0xc5, 0x03, + 0x39, 0x0f, 0x2e, 0x4c, 0x98, 0xb8, 0x69, 0x39, 0xee, 0x09, 0x12, 0x06, + 0x6b, 0x20, 0xbf, 0xff, 0x29, 0xd5, 0x3c, 0x14, 0x4f, 0x89, 0xd2, 0x48, + 0x62, 0x1d, 0xd9, 0x75, 0x34, 0x86, 0xd4, 0x2d, 0xf1, 0x48, 0xe8, 0x3c, + 0xbe, 0x67, 0x52, 0x2c, 0xf6, 0x4b, 0x7a, 0xaf, 0x70, 0x5a, 0xfb, 0x84, + 0x1b, 0xac, 0x7d, 0x45, 0xc7, 0xf4, 0xb0, 0x90, 0x4a, 0xd7, 0xfa, 0xf5, + 0x97, 0xe5, 0x21, 0xce, 0x3d, 0x9c, 0x23, 0xc7, 0x4d, 0x97, 0xba, 0xc1, + 0xea, 0xd3, 0xec, 0xce, 0x5f, 0xcd, 0x4d, 0x57, 0xf3, 0xd1, 0xce, 0x6a, + 0x1e, 0x1a, 0x29, 0xbc, 0xf3, 0x05, 0xfc, 0x14, 0xaa, 0xee, 0x57, 0x70, + 0xfe, 0x71, 0x8b, 0xb3, 0x64, 0x0e, 0x7b, 0xc8, 0x07, 0x8f, 0x6a, 0x27, + 0x82, 0x94, 0x21, 0xe0, 0xec, 0x10, 0x78, 0x90, 0xcf, 0x8b, 0x04, 0x4c, + 0xdc, 0xa9, 0xd9, 0xf6, 0xb0, 0xbc, 0xd3, 0x85, 0x41, 0xca, 0x49, 0xae, + 0x98, 0x97, 0x7c, 0xdd, 0x8f, 0xd7, 0x34, 0xb6, 0xe1, 0x5b, 0xaa, 0x39, + 0x89, 0xf7, 0xbf, 0xed, 0xbd, 0xea, 0xdf, 0xee, 0x5b, 0xcf, 0xdb, 0xa6, + 0x86, 0xe4, 0x42, 0x78, 0xde, 0x8b, 0xab, 0x54, 0x37, 0xc8, 0x54, 0x33, + 0xac, 0x47, 0x62, 0x81, 0x92, 0x64, 0xfd, 0xfb, 0x68, 0xee, 0x5f, 0x76, + 0x0e, 0xe2, 0xfe, 0x71, 0x07, 0xea, 0x54, 0x8e, 0xb3, 0x06, 0xf6, 0x37, + 0x72, 0x9c, 0xea, 0xc5, 0x8e, 0x71, 0xb7, 0x38, 0x99, 0x73, 0xe2, 0xc9, + 0xbe, 0x47, 0xb0, 0xa0, 0x63, 0x4b, 0xb5, 0xd7, 0xc9, 0xdf, 0xbf, 0x89, + 0xd4, 0x22, 0x5e, 0x9f, 0x7b, 0x68, 0x02, 0xde, 0x0e, 0xe6, 0x03, 0x9e, + 0x8b, 0x34, 0xff, 0xe6, 0x51, 0xa7, 0x38, 0x9f, 0xfe, 0x1b, 0xf3, 0x48, + 0x80, 0x71, 0x01, 0xdf, 0xab, 0x87, 0xd1, 0xc8, 0x63, 0x59, 0x87, 0x5e, + 0xaa, 0x49, 0x07, 0x31, 0x4a, 0x74, 0xbd, 0x6e, 0xcd, 0x75, 0xb6, 0x4a, + 0xbf, 0x57, 0x34, 0x64, 0x64, 0x23, 0x48, 0xb4, 0xf8, 0x57, 0xf6, 0xa1, + 0xa1, 0x74, 0x6d, 0xbe, 0x25, 0xa3, 0xf7, 0x30, 0x7f, 0x9c, 0x13, 0x06, + 0xf0, 0x41, 0x5a, 0xe0, 0x7d, 0xcb, 0x06, 0x07, 0xd0, 0x5a, 0xa0, 0xfa, + 0xdf, 0x8a, 0x21, 0x3c, 0x2e, 0x6e, 0xdb, 0xb6, 0x63, 0x10, 0xdb, 0x89, + 0x97, 0x7a, 0xe2, 0xe5, 0xe3, 0xd8, 0x12, 0x5a, 0x87, 0xaf, 0x1d, 0x93, + 0xab, 0xfd, 0x87, 0xea, 0x5c, 0xab, 0xc0, 0xbd, 0x29, 0xa7, 0x1a, 0xc1, + 0xb6, 0xf1, 0x48, 0xbf, 0xd7, 0xc1, 0x76, 0x18, 0xc1, 0x7d, 0xd3, 0x49, + 0xba, 0xcf, 0x73, 0x05, 0xb1, 0x29, 0xe3, 0x14, 0xef, 0x52, 0x9d, 0x74, + 0x3c, 0xed, 0x58, 0x24, 0xe1, 0x07, 0xe6, 0x93, 0x81, 0x1d, 0xb8, 0x45, + 0xeb, 0xc5, 0xbd, 0x64, 0x83, 0xdd, 0xad, 0x3b, 0x30, 0x41, 0x36, 0xb0, + 0xb9, 0x89, 0x6a, 0xb7, 0x58, 0xd9, 0x1c, 0x08, 0xb0, 0x1c, 0x05, 0x7a, + 0xe8, 0x7a, 0x23, 0xd5, 0x73, 0x8e, 0x18, 0x59, 0x1b, 0xf9, 0x85, 0xac, + 0x2a, 0xb9, 0x24, 0xea, 0xad, 0x35, 0x1b, 0x29, 0x4f, 0xbb, 0x18, 0x1f, + 0xf8, 0x18, 0x27, 0x7c, 0x91, 0x1e, 0xc3, 0xac, 0x55, 0xd5, 0xe8, 0x7a, + 0x47, 0x6b, 0x6e, 0x8e, 0x6c, 0x76, 0x4d, 0xc7, 0xb5, 0xcf, 0xcd, 0xcb, + 0x48, 0x43, 0x4d, 0xc7, 0x8c, 0x59, 0xf1, 0x8f, 0xc0, 0xdf, 0x71, 0xad, + 0xee, 0xe7, 0xe7, 0x60, 0x9a, 0xed, 0xb8, 0x16, 0x72, 0x44, 0xfc, 0xf7, + 0xe0, 0xaf, 0x68, 0x8d, 0x20, 0x36, 0x96, 0x7a, 0x31, 0x30, 0x2e, 0x7d, + 0x8e, 0x4f, 0x7c, 0x6c, 0xcb, 0x9f, 0xf3, 0xbf, 0x75, 0x3c, 0xd2, 0xe3, + 0xa9, 0xf2, 0x7f, 0xef, 0xf4, 0xe7, 0x73, 0x0d, 0x67, 0x38, 0xaf, 0xf2, + 0x7c, 0xbc, 0xef, 0x37, 0x2f, 0xdf, 0x20, 0xb6, 0x5b, 0xf3, 0xed, 0x75, + 0xb3, 0x0f, 0xbb, 0xc8, 0xd7, 0xd7, 0x75, 0x18, 0x78, 0x2d, 0xf1, 0x80, + 0xb9, 0xd5, 0x92, 0xc1, 0x9f, 0x58, 0xcf, 0xf7, 0xb4, 0x56, 0x2c, 0x7b, + 0xb7, 0xfd, 0x96, 0xf7, 0x04, 0x78, 0x8f, 0x60, 0x7e, 0x5f, 0x20, 0x6a, + 0xed, 0xd7, 0xd9, 0x7b, 0x03, 0xdf, 0xa2, 0x38, 0xcb, 0xfb, 0x06, 0xb2, + 0x70, 0x8e, 0xd7, 0x09, 0xd7, 0x38, 0xd3, 0xf6, 0x81, 0x6c, 0xfb, 0xd8, + 0x5f, 0x21, 0x19, 0xe0, 0xfe, 0xa4, 0x6d, 0xff, 0xd1, 0xce, 0xfb, 0x80, + 0xa7, 0x0c, 0x77, 0xed, 0x0a, 0x50, 0x8d, 0xdf, 0x67, 0xd9, 0xc3, 0x75, + 0xfa, 0xdb, 0xab, 0xfe, 0xb1, 0x95, 0xeb, 0x7c, 0xee, 0x09, 0xbe, 0xbb, + 0x6a, 0xb2, 0x55, 0x22, 0x3c, 0xc5, 0x6b, 0xf2, 0xde, 0x02, 0xe7, 0x55, + 0x2b, 0xee, 0x7a, 0x1a, 0x57, 0x18, 0xee, 0x05, 0x2b, 0x9c, 0x62, 0x51, + 0xa6, 0x9f, 0x6c, 0x4f, 0x45, 0x22, 0x63, 0x78, 0x9a, 0x57, 0x84, 0xf0, + 0x50, 0x66, 0x3e, 0x26, 0xb7, 0xa3, 0x7d, 0x0a, 0xf8, 0xdf, 0x99, 0x20, + 0xda, 0x26, 0xc2, 0x43, 0xb7, 0x3b, 0xc2, 0xc3, 0xef, 0x38, 0xf8, 0x5e, + 0xa1, 0xeb, 0x26, 0x0b, 0x7f, 0x1f, 0xed, 0x5a, 0x66, 0x7d, 0xbe, 0xdd, + 0x75, 0x63, 0xe1, 0x6e, 0xa4, 0xe7, 0xdc, 0x97, 0xf3, 0x0e, 0x13, 0x0f, + 0xc5, 0x1c, 0xf8, 0x9a, 0xf6, 0xd7, 0xe4, 0x5b, 0x82, 0x6c, 0xe3, 0x18, + 0xe7, 0x60, 0x4b, 0xa7, 0xae, 0x15, 0x2a, 0xda, 0x32, 0x8d, 0x84, 0xd7, + 0x9a, 0xa8, 0xe6, 0x6f, 0xc4, 0x0f, 0x73, 0x8c, 0xd7, 0x4c, 0x8a, 0xfb, + 0x26, 0x5e, 0xef, 0x30, 0x86, 0x82, 0x50, 0x8c, 0x37, 0x85, 0x92, 0xba, + 0xdd, 0xa1, 0x1c, 0x69, 0x72, 0xf8, 0xb1, 0x2f, 0x62, 0xe7, 0xd1, 0x4e, + 0x2b, 0x6f, 0xbe, 0xd3, 0x65, 0xf7, 0xec, 0x4e, 0x56, 0xf3, 0xeb, 0xa9, + 0x2e, 0x6d, 0x56, 0x39, 0x9a, 0x22, 0xff, 0x59, 0x48, 0xf1, 0x73, 0x3c, + 0x9b, 0xb2, 0xce, 0x82, 0xfc, 0x32, 0x53, 0x43, 0xb6, 0x11, 0xd6, 0xc6, + 0x11, 0x8e, 0x3e, 0x64, 0xd1, 0xfa, 0xb3, 0xae, 0x58, 0xa1, 0x8c, 0x8a, + 0x53, 0x39, 0x08, 0x14, 0x09, 0x37, 0xb4, 0xf9, 0x5f, 0x46, 0x99, 0xfb, + 0xa1, 0x56, 0xa0, 0x67, 0x1e, 0x5a, 0x0b, 0x40, 0x2e, 0xe3, 0xbe, 0x0c, + 0xab, 0x17, 0xeb, 0xc0, 0x5a, 0x6d, 0x3b, 0xe1, 0x42, 0xde, 0xff, 0x15, + 0x54, 0x63, 0x37, 0xa2, 0xb2, 0xc1, 0x89, 0xf1, 0x0c, 0xe7, 0xe1, 0x63, + 0x5d, 0xf2, 0x28, 0x2a, 0x6e, 0x7b, 0x4f, 0x33, 0xe1, 0xa6, 0x0c, 0x3d, + 0x57, 0x22, 0x4c, 0x4a, 0xb1, 0x63, 0x6b, 0xec, 0x37, 0x66, 0xb2, 0xd1, + 0xde, 0x53, 0x19, 0x9d, 0x14, 0x58, 0xa0, 0x26, 0x31, 0x3a, 0xe7, 0xf4, + 0xa5, 0xd3, 0x51, 0xa4, 0xcb, 0xfc, 0xbc, 0xfb, 0x72, 0xd2, 0x9a, 0x3f, + 0xb2, 0x77, 0x89, 0xc3, 0x81, 0x65, 0x1d, 0x87, 0x50, 0x59, 0x68, 0xd3, + 0x10, 0x24, 0x4c, 0xc0, 0x35, 0x6c, 0x13, 0xf1, 0x7a, 0xe7, 0xe3, 0x5c, + 0x47, 0xfc, 0xa4, 0xeb, 0xe6, 0x29, 0xf6, 0xeb, 0x63, 0x5d, 0x1f, 0xa4, + 0x95, 0x64, 0x93, 0x04, 0xb9, 0x8e, 0xf8, 0xbf, 0x6f, 0x94, 0xfb, 0x08, + 0xbf, 0xe0, 0x3e, 0x02, 0xe5, 0x65, 0x65, 0xb8, 0x59, 0x78, 0xc5, 0xba, + 0x0c, 0xd5, 0x15, 0x44, 0xf3, 0xa5, 0x88, 0xd2, 0x53, 0x22, 0x8c, 0xb2, + 0x45, 0x50, 0x5d, 0x57, 0xb6, 0xe5, 0x65, 0x9f, 0xcd, 0xab, 0x5c, 0xc5, + 0x21, 0x51, 0x0b, 0x77, 0xf0, 0x3e, 0x34, 0xe7, 0x71, 0x6b, 0x4f, 0x9f, + 0xae, 0xff, 0xbc, 0x6b, 0x09, 0xd5, 0x16, 0x23, 0x4c, 0x1f, 0x78, 0xaf, + 0x8f, 0x6a, 0xd0, 0xec, 0xf1, 0x2a, 0x2e, 0xf1, 0x56, 0xe5, 0xc2, 0xdf, + 0xf9, 0x4c, 0xe2, 0x6b, 0x5d, 0x9b, 0x26, 0xf9, 0x8c, 0xe2, 0x4f, 0xba, + 0xd6, 0x4c, 0x2a, 0xa1, 0x8d, 0xb4, 0xee, 0x6e, 0xde, 0x5f, 0xa7, 0x39, + 0x67, 0x35, 0xa6, 0xbb, 0xd0, 0x75, 0x73, 0x96, 0x7b, 0xcb, 0xc7, 0xba, + 0xcc, 0x6c, 0x98, 0x31, 0xa8, 0x65, 0x2b, 0x89, 0x02, 0x55, 0xf3, 0xd7, + 0xd9, 0xbc, 0xba, 0x48, 0x1f, 0x87, 0xd2, 0x84, 0x76, 0xe2, 0xb6, 0x6e, + 0x56, 0x17, 0xd6, 0x20, 0xd5, 0xd4, 0x4d, 0x35, 0xa8, 0xdf, 0xb7, 0x36, + 0xd3, 0x8d, 0x09, 0xd2, 0xe1, 0xa6, 0x52, 0xd0, 0xd7, 0x9d, 0x51, 0x31, + 0x50, 0xe2, 0x7a, 0xb3, 0xd2, 0xb5, 0x6b, 0x72, 0xaa, 0x5a, 0xff, 0xf6, + 0x53, 0xcd, 0x4a, 0x76, 0x91, 0xb1, 0x6d, 0xae, 0xb5, 0x40, 0x34, 0x0b, + 0x7b, 0x5e, 0x37, 0xad, 0x73, 0xfd, 0xe8, 0x77, 0xcd, 0xd0, 0x42, 0xb6, + 0x85, 0xbb, 0xf1, 0xf8, 0x94, 0xcf, 0x08, 0xe8, 0x7e, 0x74, 0x76, 0x9c, + 0xa2, 0x67, 0xdb, 0xf1, 0xf8, 0xe1, 0x5b, 0x90, 0xff, 0x23, 0x27, 0x2e, + 0x66, 0x92, 0x58, 0xda, 0xf1, 0x55, 0x9c, 0xd9, 0x20, 0xe3, 0xef, 0x32, + 0x5e, 0x5c, 0x22, 0xfe, 0x0c, 0x6b, 0x8e, 0x7f, 0xcf, 0xfe, 0x90, 0x5b, + 0xb8, 0xc7, 0x35, 0xc6, 0x9e, 0xbf, 0xe7, 0x06, 0xf7, 0xde, 0x0c, 0xd4, + 0x10, 0x0e, 0x0a, 0x13, 0xcd, 0x6a, 0x86, 0xcf, 0x38, 0x05, 0x7c, 0x9c, + 0x2b, 0xa7, 0x89, 0x27, 0x47, 0xa9, 0xc5, 0xe7, 0x24, 0x7e, 0x9c, 0xa5, + 0x73, 0x14, 0x03, 0xd8, 0x07, 0xdc, 0x97, 0x43, 0x96, 0x1d, 0x5c, 0xbb, + 0xf6, 0x7e, 0x0f, 0xef, 0xf1, 0x1f, 0xcf, 0x72, 0x6c, 0x14, 0x54, 0xbb, + 0x84, 0x90, 0x9c, 0x5d, 0x82, 0x9e, 0xd9, 0xed, 0x74, 0x5d, 0x45, 0x5f, + 0xd5, 0xd7, 0x42, 0x05, 0x8f, 0x87, 0xf1, 0x49, 0x2e, 0x63, 0xff, 0x8e, + 0x5c, 0xfd, 0xed, 0x16, 0x8d, 0xe3, 0x84, 0x1d, 0x11, 0xb7, 0xf2, 0xb0, + 0xda, 0xf1, 0xef, 0xe2, 0xe5, 0x72, 0xca, 0xa2, 0x61, 0x37, 0xcd, 0xc5, + 0xb2, 0x79, 0xce, 0x4c, 0xdd, 0xc9, 0xf2, 0x0b, 0xf8, 0x7e, 0x48, 0xfa, + 0x98, 0xa4, 0x67, 0x1e, 0x27, 0x1e, 0xca, 0xc4, 0x5b, 0xb6, 0xf4, 0x5d, + 0x1a, 0xc3, 0xf7, 0x40, 0xfa, 0x32, 0x14, 0x67, 0xf5, 0x6c, 0xe6, 0x08, + 0xe5, 0xcb, 0x5a, 0x8a, 0x45, 0x67, 0xe3, 0xf7, 0x62, 0x6d, 0x4e, 0x49, + 0x1a, 0x14, 0x2e, 0x53, 0x7e, 0x08, 0xa7, 0xce, 0x36, 0xfc, 0x36, 0xd9, + 0x70, 0x0b, 0x61, 0x80, 0x70, 0xe8, 0x1c, 0x8d, 0x37, 0x9c, 0x32, 0x1e, + 0x9b, 0x90, 0x70, 0x8e, 0xf7, 0x80, 0x85, 0xfd, 0xbc, 0x01, 0x1e, 0x3b, + 0xff, 0xbd, 0x8e, 0xea, 0xba, 0x70, 0x82, 0xb2, 0xaa, 0x51, 0x4f, 0xb8, + 0xbd, 0xd0, 0xf9, 0x08, 0xf6, 0x53, 0x7d, 0xbf, 0x35, 0x46, 0x32, 0x69, + 0x8c, 0x53, 0xbd, 0xd1, 0x36, 0x74, 0x01, 0x7f, 0x67, 0x56, 0x78, 0x1f, + 0x5d, 0x84, 0x13, 0x17, 0xf0, 0x99, 0x29, 0xa9, 0xea, 0xe9, 0x19, 0xa8, + 0x95, 0x73, 0x68, 0x1b, 0xbe, 0x82, 0x0f, 0x4d, 0xde, 0x63, 0x97, 0x25, + 0x89, 0x30, 0x60, 0xd8, 0xef, 0x44, 0x00, 0x95, 0x80, 0x84, 0x5b, 0x35, + 0xee, 0x49, 0x2b, 0xc3, 0x4f, 0x13, 0x96, 0x7f, 0x5f, 0xb4, 0x0d, 0x7e, + 0x8c, 0x33, 0x66, 0xbe, 0x91, 0xd7, 0x15, 0x48, 0xdc, 0xd8, 0x76, 0xba, + 0x06, 0x4a, 0x8f, 0x4b, 0xa8, 0x89, 0x66, 0xe9, 0xaf, 0xcd, 0x33, 0x81, + 0xcf, 0x4c, 0x35, 0xf2, 0x19, 0xe1, 0x20, 0x35, 0x38, 0x4d, 0x3e, 0x31, + 0x88, 0x79, 0xda, 0xfe, 0x81, 0xf8, 0xd7, 0x88, 0x06, 0xc6, 0x7d, 0x86, + 0x7b, 0x0f, 0xd1, 0xf6, 0x53, 0xc2, 0x01, 0x5b, 0x63, 0x17, 0xcc, 0xe4, + 0x42, 0xeb, 0xfc, 0x5e, 0x9d, 0xdd, 0xfb, 0x66, 0x5f, 0xb9, 0x1b, 0x9b, + 0xd2, 0x4e, 0x92, 0xd3, 0x3c, 0x5e, 0x73, 0x51, 0x0c, 0x66, 0x8c, 0x53, + 0xb9, 0x9e, 0x4a, 0x33, 0xc7, 0xac, 0x0a, 0xec, 0xa2, 0xb8, 0xb0, 0xd3, + 0xca, 0x05, 0xf0, 0x2c, 0x5e, 0xd1, 0x81, 0x2b, 0x53, 0xff, 0xc3, 0x43, + 0xfa, 0x5b, 0xad, 0x2e, 0x87, 0x08, 0x66, 0x0c, 0xd1, 0xa0, 0x4b, 0xf8, + 0xb8, 0x53, 0xe9, 0x71, 0x48, 0xc3, 0xb8, 0x31, 0x66, 0x98, 0x5e, 0x55, + 0xed, 0x6f, 0x17, 0x91, 0xbe, 0x92, 0x88, 0xa2, 0xae, 0xe4, 0x95, 0xeb, + 0x4a, 0xed, 0xb2, 0xa7, 0x64, 0xb8, 0xfd, 0x2b, 0xee, 0xa5, 0xba, 0x65, + 0x07, 0xd5, 0xb6, 0x5e, 0xaa, 0xaf, 0x15, 0xb2, 0xc7, 0x1a, 0x92, 0x7f, + 0x88, 0xe2, 0x80, 0x0e, 0x67, 0x66, 0x1b, 0x5c, 0x99, 0xb0, 0x7f, 0x37, + 0x76, 0x20, 0x19, 0xb4, 0xb1, 0xad, 0x4c, 0xba, 0xaa, 0xed, 0x64, 0x2c, + 0x73, 0x2f, 0xce, 0xe4, 0x19, 0x9f, 0x27, 0xb0, 0x31, 0xcd, 0xbf, 0xe1, + 0x79, 0x39, 0xae, 0xe3, 0x28, 0xd5, 0x4e, 0xee, 0x8e, 0x66, 0xd2, 0x43, + 0x0b, 0x46, 0xca, 0x82, 0x4d, 0x90, 0x74, 0x01, 0xcf, 0xd1, 0x4e, 0x19, + 0xfb, 0x66, 0x28, 0x91, 0x50, 0x9e, 0x72, 0x92, 0x9d, 0xef, 0x26, 0x1b, + 0xf2, 0xaa, 0x5e, 0xfa, 0x1d, 0xe0, 0x73, 0x47, 0x64, 0x93, 0x3f, 0xe9, + 0x6a, 0xb7, 0x62, 0xcd, 0x2f, 0xa8, 0xc6, 0xf9, 0x15, 0xf1, 0xc2, 0xb2, + 0xd0, 0x51, 0x37, 0x3e, 0x5f, 0x13, 0xae, 0xb9, 0xa3, 0x0e, 0x41, 0x9a, + 0x33, 0x58, 0xdd, 0x23, 0x13, 0x58, 0x13, 0xeb, 0x40, 0x31, 0x27, 0xaa, + 0x18, 0x6b, 0x44, 0xf1, 0x62, 0x35, 0xf6, 0x53, 0xed, 0xef, 0x53, 0x37, + 0x22, 0xe3, 0xaf, 0x78, 0xde, 0x89, 0x73, 0x0d, 0x00, 0xcf, 0x00, 0x61, + 0xa8, 0xd1, 0xf4, 0x57, 0x90, 0x5f, 0x08, 0xf7, 0x3d, 0x71, 0x3e, 0x9f, + 0x49, 0x21, 0x4a, 0x5d, 0x8d, 0x86, 0xe5, 0xbd, 0xf8, 0xb8, 0x91, 0xf1, + 0xaf, 0x97, 0x62, 0x83, 0x8c, 0xdd, 0x33, 0x01, 0xeb, 0x5c, 0x04, 0xc5, + 0xc0, 0x2a, 0xcd, 0xd7, 0xd2, 0xfa, 0x65, 0x34, 0xb2, 0x4c, 0xfe, 0x6f, + 0x34, 0x92, 0xcd, 0x12, 0xe6, 0xc9, 0xa5, 0x07, 0xf0, 0x4a, 0x9a, 0xe7, + 0x0d, 0x27, 0x35, 0xe1, 0xe7, 0x9e, 0xbc, 0x25, 0x13, 0x63, 0x86, 0xd7, + 0xf0, 0x5a, 0xb1, 0xc9, 0x5e, 0x27, 0xc0, 0xbd, 0xa2, 0xff, 0xe0, 0x5a, + 0x1a, 0xe5, 0xc7, 0xd5, 0x54, 0x77, 0x46, 0xa1, 0x7e, 0xa3, 0x42, 0xfa, + 0xe0, 0x1e, 0xf5, 0x12, 0xc2, 0xbc, 0x70, 0xbf, 0x1a, 0xe7, 0x73, 0xc8, + 0xe6, 0x0e, 0x59, 0x37, 0x4d, 0x57, 0xa7, 0xea, 0x7f, 0x0f, 0x6c, 0x87, + 0x5e, 0xde, 0xeb, 0x70, 0xef, 0xee, 0xf4, 0x62, 0x1f, 0xe5, 0xc0, 0x67, + 0xd3, 0x6d, 0x06, 0xd7, 0x7e, 0x60, 0x1c, 0x2a, 0x52, 0xf4, 0xec, 0x50, + 0x1d, 0x9f, 0x09, 0xda, 0x55, 0xde, 0x06, 0x47, 0xe6, 0xb6, 0x3a, 0xae, + 0x37, 0x6a, 0xa8, 0x4e, 0x1e, 0x49, 0x33, 0xbd, 0xdc, 0x7b, 0x33, 0xcd, + 0x9d, 0x71, 0xf5, 0xf2, 0x5a, 0xb2, 0x8b, 0x66, 0x9d, 0xe5, 0x18, 0xc0, + 0x93, 0x34, 0x36, 0x54, 0x66, 0x59, 0x7e, 0xb7, 0x8e, 0xfb, 0x9d, 0x7b, + 0x48, 0xbf, 0x0d, 0x59, 0x7b, 0x9e, 0x6c, 0x79, 0x10, 0x4b, 0x46, 0x5f, + 0xa8, 0xb3, 0x6b, 0x1f, 0xae, 0xcb, 0x87, 0xb0, 0x27, 0x1d, 0xc0, 0x4c, + 0xba, 0xcd, 0xff, 0x12, 0x9c, 0xd5, 0xbc, 0xca, 0xe7, 0x88, 0xe7, 0xc7, + 0x04, 0x30, 0x7d, 0xf5, 0x3b, 0xcb, 0xc7, 0xee, 0x99, 0x1e, 0xb7, 0x30, + 0xbf, 0x8c, 0x7c, 0xc0, 0xae, 0x63, 0x28, 0x56, 0x78, 0x1e, 0x25, 0xbd, + 0xbe, 0x4f, 0x7a, 0x75, 0x90, 0x5e, 0x5f, 0xd2, 0xfe, 0x92, 0x31, 0x8b, + 0x7b, 0x57, 0xdc, 0xcb, 0xfb, 0x43, 0x06, 0x81, 0x16, 0x6b, 0x4c, 0x26, + 0xee, 0xc4, 0xeb, 0x94, 0x07, 0x6b, 0x28, 0xfe, 0x9d, 0x4a, 0x9b, 0xab, + 0xe7, 0x62, 0x6d, 0xa9, 0xf7, 0x29, 0x4f, 0x1b, 0x7f, 0xa8, 0x68, 0x67, + 0xc8, 0x4f, 0xb3, 0x13, 0x7f, 0x8a, 0x33, 0x8d, 0x6d, 0xfe, 0xb7, 0x60, + 0xb8, 0x9f, 0x88, 0x3f, 0x42, 0x35, 0x3f, 0xd5, 0x0d, 0xcb, 0xff, 0x0b, + 0x39, 0x59, 0x1c, 0x92, 0xda, 0x76, 0xf9, 0x25, 0xfc, 0x15, 0xce, 0x5c, + 0x17, 0xd6, 0x5e, 0x02, 0x8f, 0xb1, 0xeb, 0xf1, 0xf0, 0xec, 0xfd, 0x7c, + 0x1e, 0x2a, 0x48, 0xe9, 0xcc, 0xde, 0xc7, 0x4a, 0xf3, 0xbe, 0x9b, 0x40, + 0x7e, 0x03, 0xd5, 0xd2, 0xd6, 0x39, 0x54, 0x78, 0x9e, 0x26, 0xbf, 0x88, + 0x8e, 0xf1, 0xf8, 0x63, 0x5d, 0x6a, 0x21, 0x04, 0x89, 0x30, 0x0e, 0x61, + 0x84, 0x1e, 0x3e, 0x9f, 0xf1, 0x74, 0x3a, 0x48, 0xb9, 0xa0, 0xad, 0x2f, + 0x2a, 0xbe, 0x0d, 0x1b, 0x03, 0x70, 0x9e, 0x3b, 0x46, 0x79, 0x4e, 0x49, + 0x3d, 0x8d, 0xb6, 0x7e, 0xaf, 0xb8, 0x1b, 0xa9, 0xc6, 0xb6, 0xc1, 0xa3, + 0x08, 0x13, 0x66, 0x50, 0xa2, 0x67, 0x60, 0xcf, 0xb3, 0xb4, 0x20, 0x51, + 0x9d, 0xc8, 0x71, 0x26, 0x8d, 0xa3, 0x7e, 0x09, 0x37, 0x74, 0xa8, 0x97, + 0xa7, 0x31, 0x6f, 0x2f, 0xf6, 0x98, 0xd5, 0x05, 0x1a, 0x2f, 0xf9, 0x09, + 0xdb, 0xd4, 0xc0, 0x49, 0xb5, 0xbf, 0xa4, 0x6f, 0xc3, 0xd6, 0x34, 0xe7, + 0x69, 0x92, 0x0b, 0xf9, 0x66, 0x5f, 0x64, 0x1b, 0x86, 0x0a, 0x01, 0xec, + 0xcf, 0x86, 0xf7, 0xee, 0x26, 0x5c, 0x37, 0x56, 0x0e, 0x87, 0x36, 0x8b, + 0x00, 0xe9, 0x9b, 0xea, 0xff, 0xa6, 0x20, 0xd5, 0xc9, 0x7e, 0xfa, 0xb7, + 0xeb, 0x99, 0x53, 0x54, 0xcf, 0xbc, 0x4e, 0xbe, 0xe6, 0xad, 0xd6, 0xaa, + 0x4b, 0xf3, 0x26, 0xe6, 0x62, 0xeb, 0x71, 0xc9, 0xd2, 0x59, 0x90, 0x6c, + 0x8c, 0x73, 0x08, 0x9f, 0x8d, 0x71, 0x8b, 0xcd, 0x63, 0x86, 0xfb, 0xc1, + 0xce, 0x20, 0xe5, 0x34, 0xc6, 0x9c, 0x8e, 0x3f, 0x92, 0x48, 0x1e, 0x33, + 0xea, 0x0e, 0xac, 0x8b, 0xed, 0xc0, 0x90, 0xf6, 0x5d, 0xd4, 0x34, 0x71, + 0x3c, 0x92, 0x8d, 0x06, 0x9a, 0xf7, 0x42, 0x67, 0x2f, 0xc2, 0x4f, 0x31, + 0x3e, 0xfa, 0x19, 0xe1, 0x23, 0xf6, 0x5d, 0x9e, 0xbf, 0x51, 0x5f, 0x46, + 0xb8, 0xa2, 0xbe, 0xd3, 0xce, 0xf3, 0x37, 0x16, 0xf8, 0x4c, 0x26, 0xa8, + 0x36, 0x85, 0xe7, 0xdd, 0x95, 0x3a, 0x9e, 0xa0, 0x18, 0x93, 0x58, 0xee, + 0x02, 0x16, 0xf0, 0xd9, 0x63, 0xbb, 0x8e, 0x61, 0x7e, 0x97, 0x14, 0x04, + 0x66, 0xe3, 0x64, 0x1f, 0xff, 0xea, 0x8c, 0x51, 0xa8, 0x7a, 0x36, 0x94, + 0xfb, 0x27, 0x07, 0xcc, 0x24, 0xbf, 0x33, 0xe0, 0xa8, 0xf3, 0x52, 0xbc, + 0x0d, 0x56, 0x20, 0x79, 0x39, 0x2e, 0x4b, 0xea, 0xbc, 0xdc, 0x59, 0xd6, + 0x47, 0x38, 0xbe, 0x5b, 0xba, 0x70, 0xd2, 0x33, 0xbb, 0x26, 0x95, 0xe1, + 0xdd, 0x68, 0x1b, 0xfa, 0x40, 0xd4, 0x5a, 0x3b, 0x97, 0xd3, 0xed, 0x48, + 0x2d, 0xd6, 0x9d, 0x1b, 0xae, 0x64, 0x57, 0x13, 0x1d, 0xe7, 0x4c, 0x5c, + 0xb7, 0xc6, 0xda, 0xdf, 0x9a, 0x6e, 0xff, 0x73, 0x9a, 0x9b, 0xbf, 0x3f, + 0xe0, 0xe5, 0x33, 0x93, 0xc7, 0xb3, 0x2f, 0x9a, 0xd1, 0x85, 0xb6, 0x7c, + 0x4e, 0x90, 0xef, 0x07, 0x75, 0x07, 0x9a, 0xd5, 0xc8, 0xe5, 0x7e, 0xfa, + 0xfd, 0xb7, 0x05, 0x42, 0xfb, 0x2b, 0x07, 0xf1, 0xab, 0xbc, 0x8e, 0xc7, + 0x28, 0x0f, 0x34, 0xa8, 0x8a, 0x3f, 0xcf, 0xfb, 0xd7, 0x31, 0x9b, 0xff, + 0x9b, 0xf2, 0xe4, 0x87, 0x8d, 0x7e, 0xab, 0xc6, 0xb0, 0xf9, 0x2b, 0x10, + 0x7f, 0x03, 0x5e, 0xf6, 0x85, 0xc5, 0xe4, 0x17, 0x7b, 0xc9, 0x5f, 0x1f, + 0x23, 0x5b, 0xa3, 0x0a, 0x9e, 0xfc, 0x40, 0xd9, 0x0b, 0xf2, 0xd7, 0xb1, + 0x34, 0xcb, 0x3f, 0xe8, 0x1b, 0x18, 0xe5, 0xb8, 0x6b, 0xf5, 0x55, 0xb5, + 0x90, 0x83, 0xe3, 0xae, 0x15, 0x4f, 0x8d, 0x90, 0xe3, 0xd7, 0x75, 0x4c, + 0xd7, 0x48, 0x39, 0x1c, 0xf4, 0xf0, 0x79, 0x7e, 0x02, 0x87, 0x03, 0x9a, + 0x9d, 0x2b, 0xe7, 0x28, 0x1f, 0x5d, 0x22, 0x3a, 0xf6, 0xc7, 0x9a, 0x91, + 0xa2, 0x7c, 0x94, 0x51, 0x6d, 0x5b, 0x52, 0x67, 0x19, 0x63, 0xfe, 0x82, + 0x30, 0xa6, 0x12, 0x72, 0x49, 0x6d, 0xc3, 0x27, 0xb1, 0xcd, 0x3c, 0xd3, + 0xc8, 0x36, 0xe5, 0xc2, 0xe1, 0xf6, 0x59, 0xb3, 0x12, 0x60, 0x7e, 0x25, + 0xbc, 0xa8, 0x91, 0xcd, 0x5c, 0x17, 0x0e, 0xbe, 0x48, 0x39, 0x75, 0xa6, + 0xaa, 0x8f, 0x70, 0x61, 0xde, 0x1e, 0x63, 0x2c, 0xeb, 0x68, 0x0a, 0x6a, + 0xa2, 0x80, 0x3f, 0xa6, 0xef, 0xad, 0xc1, 0x4b, 0x55, 0x5b, 0x5d, 0x36, + 0xfb, 0xdf, 0xbd, 0xd5, 0x77, 0x6c, 0xac, 0x67, 0x42, 0x85, 0xfb, 0xe9, + 0x37, 0xcf, 0x19, 0xe0, 0xb3, 0x2d, 0x7c, 0xd6, 0xca, 0xb3, 0xb5, 0xb3, + 0x86, 0xfd, 0xc5, 0xcf, 0xef, 0x15, 0xac, 0x1b, 0xe3, 0xbe, 0x30, 0xf7, + 0x68, 0x24, 0xec, 0xbe, 0xfa, 0xde, 0x03, 0x7f, 0xf6, 0xe0, 0xd6, 0x31, + 0xee, 0x45, 0x9c, 0xb8, 0x59, 0xc6, 0x3f, 0x51, 0x1e, 0x96, 0xd9, 0xe7, + 0xc9, 0xd7, 0x7f, 0xd4, 0x75, 0x6a, 0x92, 0x73, 0xea, 0xdb, 0x5d, 0x9b, + 0xd2, 0xf3, 0x3a, 0xbe, 0xca, 0xd3, 0xe9, 0x7b, 0x28, 0xee, 0x64, 0xd2, + 0xca, 0x70, 0x44, 0xb2, 0xf6, 0xd5, 0x52, 0x25, 0xf1, 0x15, 0x2a, 0xd2, + 0x78, 0xbe, 0x5e, 0xf4, 0x8f, 0x85, 0xa8, 0xb6, 0xf1, 0xfb, 0x1e, 0x38, + 0x60, 0x52, 0xae, 0x70, 0xe2, 0xe9, 0xd1, 0xb0, 0xf6, 0x26, 0xe1, 0x9d, + 0x67, 0x46, 0x4d, 0xf3, 0x4d, 0x0d, 0x7f, 0xd2, 0x40, 0x35, 0x72, 0xbb, + 0x50, 0x12, 0x84, 0x0d, 0x42, 0xeb, 0x45, 0x5b, 0xb0, 0x00, 0xe5, 0xf4, + 0x4e, 0x9a, 0xef, 0x50, 0x11, 0x78, 0xb1, 0xe8, 0xc1, 0x0b, 0x63, 0xdc, + 0xfb, 0xf3, 0xa0, 0xf4, 0x54, 0x93, 0x6f, 0xdb, 0x81, 0x10, 0xc5, 0x58, + 0x19, 0xbd, 0x87, 0x12, 0xb8, 0xf5, 0x80, 0x40, 0x34, 0x92, 0x40, 0xcf, + 0xa1, 0x7a, 0xac, 0x1f, 0x93, 0x71, 0x31, 0x5e, 0x8f, 0xdb, 0x9e, 0x9a, + 0xe7, 0xe3, 0x9d, 0x6a, 0x9d, 0x27, 0x5b, 0xe7, 0xd8, 0x8e, 0x66, 0x39, + 0x66, 0x53, 0xbe, 0xc8, 0x72, 0x0c, 0x34, 0xcd, 0x60, 0xa7, 0xdd, 0xe7, + 0x78, 0x8e, 0xf2, 0xc7, 0x13, 0x9d, 0x6a, 0x30, 0xe8, 0xd0, 0x71, 0xc3, + 0x44, 0xe5, 0xdb, 0x0d, 0x30, 0x8f, 0xf3, 0x1e, 0xc6, 0xa7, 0xed, 0xa6, + 0x79, 0x6b, 0x3c, 0x72, 0x99, 0x2a, 0x3b, 0xf2, 0xa9, 0xb7, 0xc9, 0xa7, + 0x5a, 0xf0, 0x44, 0x76, 0x7e, 0xaf, 0x4b, 0xed, 0xbf, 0x20, 0x19, 0x3b, + 0xfc, 0x30, 0x3f, 0xa9, 0xd5, 0xcd, 0x4f, 0x5d, 0x7a, 0x24, 0xb8, 0x5d, + 0xf0, 0x19, 0x11, 0xee, 0x89, 0x9b, 0xe6, 0xd9, 0xb8, 0x69, 0x16, 0xe3, + 0x86, 0x7b, 0xd9, 0x0a, 0x3f, 0x0e, 0x2d, 0xe5, 0x77, 0x0d, 0xc2, 0xc9, + 0x66, 0xb2, 0x2f, 0xcf, 0x52, 0x35, 0xb8, 0x91, 0xea, 0x2b, 0x83, 0x82, + 0x5c, 0x68, 0xa1, 0xd2, 0x0f, 0xb4, 0xf8, 0xf6, 0x8f, 0x36, 0xe1, 0x99, + 0xb9, 0xdf, 0xe5, 0xe3, 0x39, 0x56, 0x3f, 0xed, 0x13, 0x0d, 0xab, 0x1b, + 0x10, 0x49, 0x6e, 0x01, 0xf7, 0x46, 0xf9, 0x4c, 0xaa, 0x81, 0xdb, 0xe2, + 0x83, 0xd8, 0x3a, 0xc6, 0xfb, 0x6b, 0x3f, 0xef, 0xfa, 0x64, 0xcc, 0xfc, + 0x5b, 0x37, 0xd1, 0xbf, 0xba, 0xb3, 0x2d, 0xe5, 0xb1, 0xde, 0x55, 0x3a, + 0x49, 0x75, 0x40, 0x23, 0xca, 0x33, 0x6a, 0x65, 0xb1, 0x48, 0xbe, 0xe9, + 0x45, 0x24, 0xd8, 0x4c, 0xb1, 0x6a, 0x8e, 0x7c, 0x77, 0xa6, 0xcc, 0x75, + 0xc0, 0x2f, 0xbb, 0xcc, 0x89, 0x45, 0x98, 0x9e, 0xa3, 0xb9, 0xb2, 0x6a, + 0xcf, 0x47, 0x84, 0xf3, 0xea, 0x74, 0xb3, 0xc1, 0xa3, 0x47, 0x4e, 0xb7, + 0x09, 0x09, 0x97, 0x97, 0x9b, 0x66, 0x6f, 0xa7, 0x3a, 0x5c, 0x2f, 0x30, + 0xe4, 0xd0, 0xd5, 0x44, 0xbb, 0x84, 0xaf, 0x06, 0x11, 0xe9, 0x39, 0x8b, + 0x48, 0xff, 0x39, 0x8a, 0x61, 0xcf, 0x96, 0xf9, 0x9c, 0xef, 0x23, 0xf8, + 0xdb, 0xb1, 0x85, 0x38, 0x3e, 0xf3, 0x50, 0xb5, 0x27, 0x06, 0xcf, 0x8d, + 0x2b, 0x74, 0x1c, 0x26, 0xbd, 0x9e, 0xd4, 0x6a, 0x28, 0xae, 0xcb, 0x70, + 0xb4, 0x42, 0x6e, 0xa4, 0x3a, 0x21, 0xf6, 0xb8, 0x69, 0x2e, 0x6b, 0xb5, + 0x6b, 0x9e, 0x65, 0xb3, 0xd7, 0xbe, 0xa3, 0x30, 0xdf, 0xef, 0x09, 0x92, + 0xfe, 0xda, 0x52, 0x5b, 0xc5, 0x49, 0xd3, 0xf8, 0x43, 0x41, 0x3c, 0xdf, + 0x56, 0x0f, 0x0f, 0xf3, 0x2d, 0x63, 0xe7, 0x04, 0xf7, 0xe1, 0x58, 0x6f, + 0xf0, 0xf4, 0xc4, 0x79, 0x9f, 0x9c, 0x75, 0x54, 0xf1, 0xac, 0x8b, 0x53, + 0x4c, 0x14, 0x3e, 0xc2, 0x53, 0x86, 0xbb, 0x9b, 0xf2, 0x53, 0xed, 0x18, + 0xbf, 0x2f, 0xe1, 0xc5, 0x63, 0x14, 0x37, 0x2e, 0x69, 0x75, 0xd8, 0xdf, + 0xc8, 0xb6, 0xc3, 0x74, 0x72, 0xcf, 0x70, 0x1b, 0xee, 0xe5, 0x77, 0x4e, + 0xca, 0xbf, 0x6b, 0x9d, 0x0d, 0xa4, 0x6b, 0x84, 0x0d, 0x98, 0x8e, 0xf9, + 0xf5, 0x7b, 0xb0, 0x78, 0x94, 0xf5, 0x78, 0xac, 0x2b, 0x48, 0x32, 0x7a, + 0x82, 0xec, 0xc2, 0xa1, 0x77, 0x43, 0x26, 0x5b, 0x5c, 0x1b, 0xbf, 0x76, + 0x0e, 0x75, 0xe8, 0x9c, 0x44, 0xf5, 0x9d, 0xc4, 0xfb, 0x79, 0x4a, 0xe2, + 0x88, 0xb8, 0x76, 0xce, 0x7c, 0x3d, 0xf7, 0x13, 0x8d, 0x19, 0x3b, 0x2f, + 0x1d, 0xa6, 0xbc, 0xf4, 0x4a, 0x8e, 0x7d, 0xe4, 0x17, 0x96, 0x8f, 0x38, + 0x28, 0xd6, 0xae, 0x49, 0x87, 0x70, 0x4e, 0x83, 0x5a, 0x83, 0x18, 0xd1, + 0x1d, 0xe9, 0xe9, 0xae, 0x62, 0x3e, 0x17, 0xc5, 0xff, 0x99, 0x9c, 0x32, + 0x68, 0xf5, 0x9f, 0x54, 0xa5, 0x8f, 0x3f, 0x79, 0xef, 0x3f, 0xa8, 0x0f, + 0xa1, 0x61, 0x25, 0x70, 0x7e, 0x94, 0xfb, 0x55, 0xbc, 0xcf, 0x35, 0x2c, + 0xae, 0xf0, 0x7b, 0x61, 0xb5, 0x43, 0x78, 0x2f, 0xce, 0xef, 0x5b, 0xb1, + 0xef, 0x3d, 0x0c, 0xf6, 0xbd, 0x06, 0x1a, 0xfb, 0xc9, 0x68, 0x38, 0xd4, + 0x43, 0x7e, 0x33, 0x00, 0xeb, 0xbc, 0x90, 0x36, 0x6b, 0xf7, 0xc7, 0x93, + 0xa7, 0xaa, 0xfb, 0x5b, 0x91, 0xea, 0xde, 0x5c, 0xb4, 0xd0, 0x23, 0x2e, + 0x15, 0x98, 0xa6, 0xb7, 0x89, 0xa6, 0x6e, 0xf1, 0xe1, 0xec, 0x3a, 0x71, + 0x71, 0xb6, 0x57, 0x9c, 0x2d, 0x70, 0x4c, 0xfe, 0x79, 0xd7, 0xae, 0x1c, + 0xe7, 0xb3, 0x3b, 0xc5, 0xbb, 0xf9, 0x0d, 0xe2, 0x42, 0xa1, 0x5f, 0x7c, + 0x34, 0x6b, 0xe0, 0xfe, 0x78, 0x2f, 0x0a, 0x63, 0xf0, 0xbb, 0xf5, 0xfb, + 0xc5, 0xa5, 0xbc, 0xdd, 0x27, 0xbc, 0x50, 0x68, 0xf1, 0x15, 0xd2, 0x5c, + 0x03, 0x1f, 0xa3, 0x1a, 0x78, 0x91, 0xef, 0x99, 0xc9, 0x80, 0xaf, 0x34, + 0xa9, 0x0c, 0xde, 0x23, 0x4c, 0xf3, 0xb6, 0xd8, 0x69, 0xd6, 0xa1, 0xf9, + 0x5a, 0xcc, 0xc6, 0x07, 0x3b, 0x49, 0x1e, 0x9b, 0x29, 0xb7, 0x4c, 0x6b, + 0x6d, 0x55, 0x2c, 0xc2, 0xb6, 0xce, 0xbc, 0x72, 0xae, 0xe6, 0xfd, 0xa7, + 0x21, 0x38, 0x3b, 0x81, 0xbd, 0xe9, 0xcf, 0x79, 0xbd, 0x44, 0xbc, 0x1a, + 0xae, 0x21, 0x7c, 0x4c, 0xbc, 0xbe, 0x3e, 0xfa, 0xf9, 0x7e, 0x9e, 0x93, + 0xc6, 0xee, 0x4a, 0x87, 0x53, 0x47, 0x84, 0x52, 0x29, 0xd8, 0xfb, 0x79, + 0x9a, 0x57, 0x52, 0x4e, 0x8f, 0x50, 0x1d, 0xd1, 0x2a, 0xd9, 0xbc, 0x26, + 0xaa, 0xbc, 0xde, 0x44, 0xbc, 0x5e, 0x2c, 0x70, 0x7d, 0xfe, 0x76, 0xd7, + 0x1b, 0xa3, 0x63, 0x66, 0x3d, 0xd5, 0xff, 0x75, 0x6a, 0xb7, 0xb8, 0x40, + 0x3c, 0x7f, 0x48, 0x3c, 0x7f, 0x5c, 0xb8, 0x53, 0x7c, 0x44, 0x7c, 0x5e, + 0x2c, 0xf0, 0x1e, 0x9e, 0x5b, 0x7c, 0x98, 0xb3, 0x79, 0xfc, 0xf0, 0x2a, + 0x8f, 0x41, 0xdf, 0xfe, 0x74, 0x93, 0xef, 0xd1, 0x49, 0xbf, 0x6f, 0xcf, + 0xa4, 0x69, 0x7e, 0xa8, 0x49, 0x3e, 0xe6, 0xeb, 0x55, 0xed, 0x8b, 0x7c, + 0xdd, 0x4c, 0x7c, 0xf1, 0xfe, 0xeb, 0x6f, 0xeb, 0x70, 0x9e, 0xaf, 0xc7, + 0xac, 0x73, 0x6c, 0xf6, 0x19, 0xa9, 0x7a, 0xde, 0x83, 0x25, 0xbe, 0x7c, + 0x74, 0xfd, 0x95, 0x7f, 0xcd, 0xd7, 0xe0, 0x05, 0xd2, 0x5f, 0xb1, 0xca, + 0x57, 0xfd, 0xbf, 0xc9, 0x17, 0xd5, 0xba, 0x63, 0xcc, 0x57, 0xa3, 0xfe, + 0xc6, 0x98, 0x49, 0xfa, 0x92, 0xac, 0x77, 0xc1, 0x8a, 0xd9, 0x1d, 0x78, + 0x25, 0xc6, 0xef, 0xc7, 0x45, 0x42, 0x47, 0x28, 0x9e, 0xce, 0x96, 0x3d, + 0xa2, 0xc6, 0xda, 0x87, 0xc5, 0x1b, 0xb5, 0x44, 0xd3, 0xe1, 0x19, 0x7e, + 0xff, 0x0b, 0x1a, 0x61, 0x01, 0x3f, 0xbf, 0x37, 0x37, 0x0d, 0xee, 0x97, + 0xf5, 0x8a, 0x86, 0x22, 0xef, 0xbb, 0x6e, 0x10, 0xbe, 0x22, 0x9f, 0xa3, + 0xeb, 0x11, 0xde, 0x62, 0xb7, 0xf0, 0x1c, 0x32, 0x4c, 0x8f, 0xba, 0x4e, + 0xd4, 0x1d, 0xba, 0x53, 0x78, 0xaa, 0x7b, 0xb0, 0xee, 0x62, 0xd0, 0x97, + 0xbe, 0x46, 0x1e, 0x17, 0xb5, 0x9b, 0x2d, 0x79, 0xbc, 0xa6, 0xcd, 0xef, + 0x1f, 0x5a, 0xe7, 0x10, 0xf9, 0x1c, 0x9c, 0x27, 0x48, 0xb5, 0x53, 0x43, + 0xb5, 0x76, 0x7a, 0x37, 0xc6, 0xe7, 0x7b, 0x0c, 0x92, 0x3f, 0x42, 0x4e, + 0x5d, 0xe9, 0x3f, 0x21, 0xd4, 0xd4, 0xfd, 0x22, 0x79, 0xab, 0x97, 0xea, + 0x9f, 0xad, 0xb1, 0x48, 0xf2, 0x06, 0x11, 0x49, 0x38, 0x05, 0xe7, 0x15, + 0x4d, 0xae, 0x2d, 0x19, 0xd8, 0x43, 0xf1, 0xed, 0xe5, 0x9c, 0x83, 0xb0, + 0x03, 0xbf, 0x43, 0xe6, 0xc4, 0x5a, 0xbf, 0x17, 0x4f, 0x12, 0xee, 0x78, + 0x22, 0x3b, 0x88, 0x27, 0x0b, 0x03, 0x78, 0xa2, 0xf0, 0xaf, 0xde, 0x95, + 0x91, 0x3d, 0xfa, 0xf9, 0x95, 0xd5, 0x33, 0x08, 0x89, 0xeb, 0x23, 0x1c, + 0xa3, 0x1f, 0x6e, 0x97, 0x23, 0x5c, 0xeb, 0xbe, 0x75, 0xf3, 0x07, 0x2a, + 0xfb, 0xa2, 0xba, 0xe2, 0x94, 0x85, 0x45, 0x1e, 0x59, 0x7e, 0xc8, 0x3a, + 0x1b, 0x95, 0xbe, 0x69, 0x97, 0xf5, 0x4e, 0xe7, 0x3b, 0x2b, 0x36, 0xa9, + 0xec, 0x0f, 0x0f, 0xc7, 0xd7, 0x58, 0xf9, 0xf5, 0x6f, 0x56, 0xd9, 0x3d, + 0x9a, 0x77, 0x56, 0x5d, 0x6f, 0xf7, 0xd1, 0x56, 0x45, 0xad, 0xcf, 0x33, + 0xab, 0xec, 0xfd, 0xed, 0x4f, 0x57, 0xb5, 0x5a, 0x9f, 0xe7, 0x57, 0xd9, + 0x3e, 0xf5, 0xee, 0x2a, 0xd5, 0xfa, 0xfc, 0x87, 0x55, 0x76, 0x5e, 0xbe, + 0xb4, 0x6a, 0xc9, 0xd5, 0xf7, 0x63, 0xf8, 0xef, 0xff, 0x00, 0x88, 0xf4, + 0x23, 0x6f, 0xec, 0x3a, 0x00, 0x00, 0x00 }; static const u32 bnx2_TXP_b09FwData[(0x0/4) + 1] = { 0x0 }; static const u32 bnx2_TXP_b09FwRodata[(0x30/4) + 1] = { @@ -4582,15 +4513,15 @@ static const u32 bnx2_TXP_b09FwRodata[(0x30/4) + 1] = { 0x00000000 }; static struct fw_info bnx2_txp_fw_09 = { - /* Firmware version: 4.4.23 */ + /* Firmware version: 4.6.15 */ .ver_major = 0x4, - .ver_minor = 0x4, - .ver_fix = 0x17, + .ver_minor = 0x6, + .ver_fix = 0xf, - .start_addr = 0x08000094, + .start_addr = 0x08000098, .text_addr = 0x08000000, - .text_len = 0x3b1c, + .text_len = 0x3ae8, .text_index = 0x0, .gz_text = bnx2_TXP_b09FwText, .gz_text_len = sizeof(bnx2_TXP_b09FwText), @@ -4600,15 +4531,15 @@ static struct fw_info bnx2_txp_fw_09 = { .data_index = 0x0, .data = bnx2_TXP_b09FwData, - .sbss_addr = 0x08003b80, + .sbss_addr = 0x08003b40, .sbss_len = 0x6c, .sbss_index = 0x0, - .bss_addr = 0x08003bec, + .bss_addr = 0x08003bac, .bss_len = 0x24c, .bss_index = 0x0, - .rodata_addr = 0x08003b1c, + .rodata_addr = 0x08003ae8, .rodata_len = 0x30, .rodata_index = 0x0, .rodata = bnx2_TXP_b09FwRodata, -- cgit From 990ec3804bb9fd37fcce3e165c95e8b79a783aa3 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 12 Feb 2009 16:54:13 -0800 Subject: bnx2: Fix jumbo frames error handling. If errors are reported on a frame descriptor, we need to account for the buffer pages that may have been used for this error packet and recycle them. Otherwise, we may get the wrong pages for the next packet. Signed-off-by: Michael Chan Signed-off-by: Matt Carlson Signed-off-by: Benjamin Li Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index d4a3dac21dc..7a610b1b773 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -2910,18 +2910,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) rx_hdr = (struct l2_fhdr *) skb->data; len = rx_hdr->l2_fhdr_pkt_len; + status = rx_hdr->l2_fhdr_status; - if ((status = rx_hdr->l2_fhdr_status) & - (L2_FHDR_ERRORS_BAD_CRC | - L2_FHDR_ERRORS_PHY_DECODE | - L2_FHDR_ERRORS_ALIGNMENT | - L2_FHDR_ERRORS_TOO_SHORT | - L2_FHDR_ERRORS_GIANT_FRAME)) { - - bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons, - sw_ring_prod); - goto next_rx; - } hdr_len = 0; if (status & L2_FHDR_STATUS_SPLIT) { hdr_len = rx_hdr->l2_fhdr_ip_xsum; @@ -2931,6 +2921,24 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) pg_ring_used = 1; } + if (unlikely(status & (L2_FHDR_ERRORS_BAD_CRC | + L2_FHDR_ERRORS_PHY_DECODE | + L2_FHDR_ERRORS_ALIGNMENT | + L2_FHDR_ERRORS_TOO_SHORT | + L2_FHDR_ERRORS_GIANT_FRAME))) { + + bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons, + sw_ring_prod); + if (pg_ring_used) { + int pages; + + pages = PAGE_ALIGN(len - hdr_len) >> PAGE_SHIFT; + + bnx2_reuse_rx_skb_pages(bp, rxr, NULL, pages); + } + goto next_rx; + } + len -= 4; if (len <= bp->rx_copy_thresh) { -- cgit From a6952b5299ab506051f05395f7c26ff1352759ad Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 12 Feb 2009 16:54:48 -0800 Subject: bnx2: Update version to 1.9.2 and copyright. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 6 +++--- drivers/net/bnx2.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 7a610b1b773..6500b7c4739 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -1,6 +1,6 @@ /* bnx2.c: Broadcom NX2 network driver. * - * Copyright (c) 2004-2008 Broadcom Corporation + * Copyright (c) 2004-2009 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -57,8 +57,8 @@ #define DRV_MODULE_NAME "bnx2" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.9.0" -#define DRV_MODULE_RELDATE "Dec 16, 2008" +#define DRV_MODULE_VERSION "1.9.2" +#define DRV_MODULE_RELDATE "Feb 11, 2009" #define RUN_AT(x) (jiffies + (x)) diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 900641ac63e..704cbbcbf97 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -1,6 +1,6 @@ /* bnx2.h: Broadcom NX2 network driver. * - * Copyright (c) 2004-2007 Broadcom Corporation + * Copyright (c) 2004-2009 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by -- cgit From 354b45fff90c3448c1eadabfad6ae7b8b8a2a237 Mon Sep 17 00:00:00 2001 From: Yang Hongyang Date: Thu, 12 Feb 2009 16:57:12 -0800 Subject: netxen: fix compile waring "label ‘set_32_bit_mask’ defined but not used" on IA64 platform MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When compile the latest kernel on IA64 platform,I got a warning: drivers/net/netxen/netxen_nic_main.c:203: warning: label ‘set_32_bit_mask’ defined but not used We do not need label ‘set_32_bit_mask’ on IA64 platform,So move it to #else. Signed-off-by: Yang Hongyang Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index e02fe5ad215..9f33e442f40 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -201,9 +201,9 @@ static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id) adapter->pci_using_dac = 1; return 0; } +set_32_bit_mask: #endif /* CONFIG_IA64 */ -set_32_bit_mask: err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); if (!err) err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); -- cgit From df0bca049d01c0ee94afb7cd5dfd959541e6c8da Mon Sep 17 00:00:00 2001 From: Clément Lecigne Date: Thu, 12 Feb 2009 16:59:09 -0800 Subject: net: 4 bytes kernel memory disclosure in SO_BSDCOMPAT gsopt try #2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In function sock_getsockopt() located in net/core/sock.c, optval v.val is not correctly initialized and directly returned in userland in case we have SO_BSDCOMPAT option set. This dummy code should trigger the bug: int main(void) { unsigned char buf[4] = { 0, 0, 0, 0 }; int len; int sock; sock = socket(33, 2, 2); getsockopt(sock, 1, SO_BSDCOMPAT, &buf, &len); printf("%x%x%x%x\n", buf[0], buf[1], buf[2], buf[3]); close(sock); } Here is a patch that fix this bug by initalizing v.val just after its declaration. Signed-off-by: Clément Lecigne Signed-off-by: David S. Miller --- net/core/sock.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/core/sock.c b/net/core/sock.c index f3a0d08cbb4..6f2e1337975 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -696,6 +696,8 @@ int sock_getsockopt(struct socket *sock, int level, int optname, if (len < 0) return -EINVAL; + v.val = 0; + switch(optname) { case SO_DEBUG: v.val = sock_flag(sk, SOCK_DBG); -- cgit From 1d7b33f77b2d8b0b1ee767e6f8f05cbd9d72cb7c Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Thu, 12 Feb 2009 17:00:20 -0800 Subject: wimax: fix oops in wimax_dev_get_by_genl_info() when looking up non-wimax iface When a non-wimax interface is looked up by the stack, a bad pointer is returned when the looked-up interface is not found in the list (of registered WiMAX interfaces). This causes an oops in the caller when trying to use the pointer. Fix by properly setting the pointer to NULL if we don't exit from the list_for_each() with a found entry. Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: David S. Miller --- net/wimax/id-table.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/net/wimax/id-table.c b/net/wimax/id-table.c index 5e685f7eda9..72273abfcb1 100644 --- a/net/wimax/id-table.c +++ b/net/wimax/id-table.c @@ -94,12 +94,13 @@ struct wimax_dev *wimax_dev_get_by_genl_info( list_for_each_entry(wimax_dev, &wimax_id_table, id_table_node) { if (wimax_dev->net_dev->ifindex == ifindex) { dev_hold(wimax_dev->net_dev); - break; + goto found; } } - if (wimax_dev == NULL) - d_printf(1, NULL, "wimax: no devices found with ifindex %d\n", - ifindex); + wimax_dev = NULL; + d_printf(1, NULL, "wimax: no devices found with ifindex %d\n", + ifindex); +found: spin_unlock(&wimax_id_table_lock); d_fnend(3, NULL, "(info %p ifindex %d) = %p\n", info, ifindex, wimax_dev); -- cgit From fbc78b07ba53ace155f27491c81a009e541a93ad Mon Sep 17 00:00:00 2001 From: Philippe Gerum Date: Thu, 12 Feb 2009 12:18:46 +0000 Subject: powerpc/mm: Fix _PAGE_CHG_MASK to protect _PAGE_SPECIAL Fix _PAGE_CHG_MASK so that pte_modify() does not affect the _PAGE_SPECIAL bit. Signed-off-by: Philippe Gerum Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/pgtable-4k.h | 2 +- arch/powerpc/include/asm/pgtable-64k.h | 2 +- arch/powerpc/include/asm/pgtable-ppc32.h | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/include/asm/pgtable-4k.h b/arch/powerpc/include/asm/pgtable-4k.h index 6b18ba9d2d8..1dbca4e7de6 100644 --- a/arch/powerpc/include/asm/pgtable-4k.h +++ b/arch/powerpc/include/asm/pgtable-4k.h @@ -60,7 +60,7 @@ /* It should be preserving the high 48 bits and then specifically */ /* preserving _PAGE_SECONDARY | _PAGE_GROUP_IX */ #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | \ - _PAGE_HPTEFLAGS) + _PAGE_HPTEFLAGS | _PAGE_SPECIAL) /* Bits to mask out from a PMD to get to the PTE page */ #define PMD_MASKED_BITS 0 diff --git a/arch/powerpc/include/asm/pgtable-64k.h b/arch/powerpc/include/asm/pgtable-64k.h index 07b0d8f09cb..7389003349a 100644 --- a/arch/powerpc/include/asm/pgtable-64k.h +++ b/arch/powerpc/include/asm/pgtable-64k.h @@ -114,7 +114,7 @@ static inline struct subpage_prot_table *pgd_subpage_prot(pgd_t *pgd) * pgprot changes */ #define _PAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \ - _PAGE_ACCESSED) + _PAGE_ACCESSED | _PAGE_SPECIAL) /* Bits to mask out from a PMD to get to the PTE page */ #define PMD_MASKED_BITS 0x1ff diff --git a/arch/powerpc/include/asm/pgtable-ppc32.h b/arch/powerpc/include/asm/pgtable-ppc32.h index f69a4d97772..820b5f0a35c 100644 --- a/arch/powerpc/include/asm/pgtable-ppc32.h +++ b/arch/powerpc/include/asm/pgtable-ppc32.h @@ -429,7 +429,8 @@ extern int icache_44x_need_flush; #define PMD_PAGE_SIZE(pmd) bad_call_to_PMD_PAGE_SIZE() #endif -#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) +#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | \ + _PAGE_SPECIAL) #define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \ -- cgit From 06eccea6c34e00c8fedce49229ed35fa84619fb7 Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Thu, 12 Feb 2009 12:36:04 +0000 Subject: powerpc/mm: Fix numa reserve bootmem page selection Fix the powerpc NUMA reserve bootmem page selection logic. commit 8f64e1f2d1e09267ac926e15090fd505c1c0cbcb (powerpc: Reserve in bootmem lmb reserved regions that cross NUMA nodes) changed the logic for how the powerpc LMB reserved regions were converted to bootmen reserved regions. As the folowing discussion reports, the new logic was not correct. mark_reserved_regions_for_nid() goes through each LMB on the system that specifies a reserved area. It searches for active regions that intersect with that LMB and are on the specified node. It attempts to bootmem-reserve only the area where the active region and the reserved LMB intersect. We can not reserve things on other nodes as they may not have bootmem structures allocated, yet. We base the size of the bootmem reservation on two possible things. Normally, we just make the reservation start and stop exactly at the start and end of the LMB. However, the LMB reservations are not aware of NUMA nodes and on occasion a single LMB may cross into several adjacent active regions. Those may even be on different NUMA nodes and will require separate calls to the bootmem reserve functions. So, the bootmem reservation must be trimmed to fit inside the current active region. That's all fine and dandy, but we trim the reservation in a page-aligned fashion. That's bad because we start the reservation at a non-page-aligned address: physbase. The reservation may only span 2 bytes, but that those bytes may span two pfns and cause a reserve_size of 2*PAGE_SIZE. Take the case where you reserve 0x2 bytes at 0x0fff and where the active region ends at 0x1000. You'll jump into that if() statment, but node_ar.end_pfn=0x1 and start_pfn=0x0. You'll end up with a reserve_size=0x1000, and then call reserve_bootmem_node(node, physbase=0xfff, size=0x1000); 0x1000 may not be on the same node as 0xfff. Oops. In almost all the vm code, end_ is not inclusive. If you have an end_pfn of 0x1234, page 0x1234 is not included in the range. Using PFN_UP instead of the (>> >> PAGE_SHIFT) will make this consistent with the other VM code. We also need to do math for the reserved size with physbase instead of start_pfn. node_ar.end_pfn << PAGE_SHIFT is *precisely* the end of the node. However, (start_pfn << PAGE_SHIFT) is *NOT* precisely the beginning of the reserved area. That is, of course, physbase. If we don't use physbase here, the reserve_size can be made too large. From: Dave Hansen Tested-by: Geoff Levand Tested on PS3. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/numa.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 7393bd76d69..5ac08b8ab65 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -882,7 +883,7 @@ static void mark_reserved_regions_for_nid(int nid) unsigned long physbase = lmb.reserved.region[i].base; unsigned long size = lmb.reserved.region[i].size; unsigned long start_pfn = physbase >> PAGE_SHIFT; - unsigned long end_pfn = ((physbase + size) >> PAGE_SHIFT); + unsigned long end_pfn = PFN_UP(physbase + size); struct node_active_region node_ar; unsigned long node_end_pfn = node->node_start_pfn + node->node_spanned_pages; @@ -908,7 +909,7 @@ static void mark_reserved_regions_for_nid(int nid) */ if (end_pfn > node_ar.end_pfn) reserve_size = (node_ar.end_pfn << PAGE_SHIFT) - - (start_pfn << PAGE_SHIFT); + - physbase; /* * Only worry about *this* node, others may not * yet have valid NODE_DATA(). -- cgit From 0047656e2a97d4452dd7df9e52591a7afe21a263 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Thu, 12 Feb 2009 12:36:16 +0000 Subject: powerpc/ps3: Move ps3_mm_add_memory to device_initcall Change the PS3 hotplug memory routine ps3_mm_add_memory() from a core_initcall to a device_initcall. core_initcall routines run before the powerpc topology_init() startup routine, which is a subsys_initcall, resulting in failure of ps3_mm_add_memory() when CONFIG_NUMA=y. When ps3_mm_add_memory() fails the system will boot with just the 128 MiB of boot memory Signed-off-by: Geoff Levand Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/ps3/mm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c index 67de6bf3db3..d281cc0bca7 100644 --- a/arch/powerpc/platforms/ps3/mm.c +++ b/arch/powerpc/platforms/ps3/mm.c @@ -328,7 +328,7 @@ static int __init ps3_mm_add_memory(void) return result; } -core_initcall(ps3_mm_add_memory); +device_initcall(ps3_mm_add_memory); /*============================================================================*/ /* dma routines */ -- cgit From 26456dcfb8d8e43b1b64b2a14710694cf7a72f05 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Thu, 12 Feb 2009 19:08:58 +0000 Subject: powerpc/vsx: Fix VSX alignment handler for regs 32-63 Fix the VSX alignment handler for VSX registers > 32. 32-63 are stored in the VMX part of the thread_struct not the FPR part. Signed-off-by: Michael Neuling CC: stable@kernel.org (2.6.27 & .28 please) Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/align.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index 5af4e9b2dbe..ada06924a42 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c @@ -646,11 +646,16 @@ static int emulate_vsx(unsigned char __user *addr, unsigned int reg, unsigned int areg, struct pt_regs *regs, unsigned int flags, unsigned int length) { - char *ptr = (char *) ¤t->thread.TS_FPR(reg); + char *ptr; int ret = 0; flush_vsx_to_thread(current); + if (reg < 32) + ptr = (char *) ¤t->thread.TS_FPR(reg); + else + ptr = (char *) ¤t->thread.vr[reg - 32]; + if (flags & ST) ret = __copy_to_user(addr, ptr, length); else { -- cgit From 92258a3ed2f583c8720ef570f5c62b28e6c58d71 Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Thu, 12 Feb 2009 17:27:27 -0200 Subject: ALSA: hda - Change HP dv7 (103c:30f4) quirk from hp-m4 to hp-dv5 model Change HP dv7 quirk: although reported to work with hp-m4 model (https://bugzilla.novell.com/show_bug.cgi?id=445321), the original report doesn't contain info about testing of internal microphone. Recently I received a report about internal mic not working (https://qa.mandriva.com/show_bug.cgi?id=44855#c193), this must be related with the forced line in on pin 0x0e done with hp-m4 model. Thus change the current quirk from STAC_HP_M4 to STAC_HP_DV5, later reported to be fixed on a provided kernel with this change (https://qa.mandriva.com/show_bug.cgi?id=44855#c196). Signed-off-by: Herton Ronaldo Krzesinski Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 38428e22428..aa814a3c2d8 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1799,7 +1799,7 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f2, "HP dv5", STAC_HP_M4), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4, - "HP dv7", STAC_HP_M4), + "HP dv7", STAC_HP_DV5), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f7, "HP dv4", STAC_HP_DV5), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fc, -- cgit From b13e24644c138d0ddbc451403c30a96b09bfd556 Mon Sep 17 00:00:00 2001 From: john stultz Date: Thu, 12 Feb 2009 18:48:53 -0800 Subject: x86, hpet: fix for LS21 + HPET = boot hang Between 2.6.23 and 2.6.24-rc1 a change was made that broke IBM LS21 systems that had the HPET enabled in the BIOS, resulting in boot hangs for x86_64. Specifically commit b8ce33590687888ebb900d09557b8807c4539022, which merges the i386 and x86_64 HPET code. Prior to this commit, when we setup the HPET timers in x86_64, we did the following: hpet_writel(HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL | HPET_TN_32BIT, HPET_T0_CFG); However after the i386/x86_64 HPET merge, we do the following: cfg = hpet_readl(HPET_Tn_CFG(timer)); cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL | HPET_TN_32BIT; hpet_writel(cfg, HPET_Tn_CFG(timer)); However on LS21s with HPET enabled in the BIOS, the HPET_T0_CFG register boots with Level triggered interrupts (HPET_TN_LEVEL) enabled. This causes the periodic interrupt to be not so periodic, and that results in the boot time hang I reported earlier in the delay calibration. My fix: Always disable HPET_TN_LEVEL when setting up periodic mode. Signed-off-by: John Stultz Signed-off-by: Ingo Molnar --- arch/x86/kernel/hpet.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 64d5ad0b8ad..5c8da2c2c18 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -269,6 +269,8 @@ static void hpet_set_mode(enum clock_event_mode mode, now = hpet_readl(HPET_COUNTER); cmp = now + (unsigned long) delta; cfg = hpet_readl(HPET_Tn_CFG(timer)); + /* Make sure we use edge triggered interrupts */ + cfg &= ~HPET_TN_LEVEL; cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL | HPET_TN_32BIT; hpet_writel(cfg, HPET_Tn_CFG(timer)); -- cgit From 3a08e30de2facffe8e1a25bf4fa62cbc920fbaf6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 13 Feb 2009 11:37:08 +0100 Subject: ALSA: hda - Add missing terminator in slave dig-out array Added the missing terminator for ad1989b_slave_dig_outs[]. Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_analog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 2e7371ec2e2..7006d62ca6c 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -1885,8 +1885,8 @@ static hda_nid_t ad1988_capsrc_nids[3] = { #define AD1988_SPDIF_OUT_HDMI 0x0b #define AD1988_SPDIF_IN 0x07 -static hda_nid_t ad1989b_slave_dig_outs[2] = { - AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI +static hda_nid_t ad1989b_slave_dig_outs[] = { + AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0 }; static struct hda_input_mux ad1988_6stack_capture_source = { -- cgit From 9411e21cd0cc4fd046b4f448417b0e103e80951c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 13 Feb 2009 11:32:28 +0100 Subject: ALSA: hda - Add snd_hda_multi_out_dig_cleanup() Added the helper function snd_hda_multi_out_dig_cleanup() to clean up the digital outputs with multi setup. This call is needed in cases the codec supports multiple digital outputs as slaves. Otherwise the slave widgets aren't properly cleaned up. For a single digital output (e.g. in patch_conexant.c), this call isn't needed. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 10 ++++++++++ sound/pci/hda/hda_local.h | 2 ++ sound/pci/hda/patch_analog.c | 11 ++++++++++- sound/pci/hda/patch_sigmatel.c | 11 ++++++++++- 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 0b708134d12..d03f99298be 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -3088,6 +3088,16 @@ int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, } EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_prepare); +int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec, + struct hda_multi_out *mout) +{ + mutex_lock(&codec->spdif_mutex); + cleanup_dig_out_stream(codec, mout->dig_out_nid); + mutex_unlock(&codec->spdif_mutex); + return 0; +} +EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_cleanup); + /* * release the digital out */ diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 1dd8716c387..44f189cb97a 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -251,6 +251,8 @@ int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, unsigned int stream_tag, unsigned int format, struct snd_pcm_substream *substream); +int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec, + struct hda_multi_out *mout); int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout, struct snd_pcm_substream *substream, diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 7006d62ca6c..e48612323aa 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -275,6 +275,14 @@ static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, format, substream); } +static int ad198x_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream) +{ + struct ad198x_spec *spec = codec->spec; + return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); +} + /* * Analog capture */ @@ -333,7 +341,8 @@ static struct hda_pcm_stream ad198x_pcm_digital_playback = { .ops = { .open = ad198x_dig_playback_pcm_open, .close = ad198x_dig_playback_pcm_close, - .prepare = ad198x_dig_playback_pcm_prepare + .prepare = ad198x_dig_playback_pcm_prepare, + .cleanup = ad198x_dig_playback_pcm_cleanup }, }; diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index aa814a3c2d8..8027edf3c8f 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -2442,6 +2442,14 @@ static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, stream_tag, format, substream); } +static int stac92xx_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream) +{ + struct sigmatel_spec *spec = codec->spec; + return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); +} + /* * Analog capture callbacks @@ -2486,7 +2494,8 @@ static struct hda_pcm_stream stac92xx_pcm_digital_playback = { .ops = { .open = stac92xx_dig_playback_pcm_open, .close = stac92xx_dig_playback_pcm_close, - .prepare = stac92xx_dig_playback_pcm_prepare + .prepare = stac92xx_dig_playback_pcm_prepare, + .cleanup = stac92xx_dig_playback_pcm_cleanup }, }; -- cgit From 3997ad317fdf9ecdb5702e2b4fd1f8229814ff8c Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 12 Feb 2009 15:00:52 +0100 Subject: timers: more consistently use clock vs timer While reviewing the manpages, I noticed I'd missed some clock vs timer sites. Make sure that all timer functions call cpu_timer_sample_group() and not cpu_clock_sample_group(). This ensures that we enable the process wide timer in time, and therefore pay the O(n) thread group cost from the syscall. Not doing it here, will result in the first jiffy tick after setting the timer doing this, resulting in a very expensive tick (but only once) and a delay in actually starting the timer. Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- kernel/posix-cpu-timers.c | 60 +++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index 2313a4cc14e..e976e505648 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c @@ -680,6 +680,33 @@ static void cpu_timer_fire(struct k_itimer *timer) } } +/* + * Sample a process (thread group) timer for the given group_leader task. + * Must be called with tasklist_lock held for reading. + */ +static int cpu_timer_sample_group(const clockid_t which_clock, + struct task_struct *p, + union cpu_time_count *cpu) +{ + struct task_cputime cputime; + + thread_group_cputimer(p, &cputime); + switch (CPUCLOCK_WHICH(which_clock)) { + default: + return -EINVAL; + case CPUCLOCK_PROF: + cpu->cpu = cputime_add(cputime.utime, cputime.stime); + break; + case CPUCLOCK_VIRT: + cpu->cpu = cputime.utime; + break; + case CPUCLOCK_SCHED: + cpu->sched = cputime.sum_exec_runtime + task_delta_exec(p); + break; + } + return 0; +} + /* * Guts of sys_timer_settime for CPU timers. * This is called with the timer locked and interrupts disabled. @@ -741,7 +768,7 @@ int posix_cpu_timer_set(struct k_itimer *timer, int flags, if (CPUCLOCK_PERTHREAD(timer->it_clock)) { cpu_clock_sample(timer->it_clock, p, &val); } else { - cpu_clock_sample_group(timer->it_clock, p, &val); + cpu_timer_sample_group(timer->it_clock, p, &val); } if (old) { @@ -889,7 +916,7 @@ void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp) read_unlock(&tasklist_lock); goto dead; } else { - cpu_clock_sample_group(timer->it_clock, p, &now); + cpu_timer_sample_group(timer->it_clock, p, &now); clear_dead = (unlikely(p->exit_state) && thread_group_empty(p)); } @@ -1244,7 +1271,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer) clear_dead_task(timer, now); goto out_unlock; } - cpu_clock_sample_group(timer->it_clock, p, &now); + cpu_timer_sample_group(timer->it_clock, p, &now); bump_cpu_timer(timer, now); /* Leave the tasklist_lock locked for the call below. */ } @@ -1408,33 +1435,6 @@ void run_posix_cpu_timers(struct task_struct *tsk) } } -/* - * Sample a process (thread group) timer for the given group_leader task. - * Must be called with tasklist_lock held for reading. - */ -static int cpu_timer_sample_group(const clockid_t which_clock, - struct task_struct *p, - union cpu_time_count *cpu) -{ - struct task_cputime cputime; - - thread_group_cputimer(p, &cputime); - switch (CPUCLOCK_WHICH(which_clock)) { - default: - return -EINVAL; - case CPUCLOCK_PROF: - cpu->cpu = cputime_add(cputime.utime, cputime.stime); - break; - case CPUCLOCK_VIRT: - cpu->cpu = cputime.utime; - break; - case CPUCLOCK_SCHED: - cpu->sched = cputime.sum_exec_runtime + task_delta_exec(p); - break; - } - return 0; -} - /* * Set one of the process-wide special case CPU timers. * The tsk->sighand->siglock must be held by the caller. -- cgit From 999c7880cc8eeb0cbe6610b8c6d0ab0ec51cd848 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 13 Feb 2009 13:15:55 +0100 Subject: x86 headers: remove duplicate pud_large() definition Signed-off-by: Ingo Molnar --- arch/x86/include/asm/pgtable.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 62024ff897d..1c097a3a666 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -387,13 +387,6 @@ static inline unsigned long pages_to_mb(unsigned long npg) #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ remap_pfn_range(vma, vaddr, pfn, size, prot) -#if PAGETABLE_LEVELS == 2 -static inline int pud_large(pud_t pud) -{ - return 0; -} -#endif - #if PAGETABLE_LEVELS > 2 static inline int pud_none(pud_t pud) { -- cgit From 56cefcea7c8769ffc04a5609e6ac849e36685468 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 13 Feb 2009 13:23:02 +0100 Subject: x86 headers: include linux/types.h To properly pick up types relied on by prototypes like 'bool'. Signed-off-by: Ingo Molnar --- arch/x86/include/asm/page.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/include/asm/page.h b/arch/x86/include/asm/page.h index 467ce69306b..89ed9d70b0a 100644 --- a/arch/x86/include/asm/page.h +++ b/arch/x86/include/asm/page.h @@ -1,6 +1,8 @@ #ifndef _ASM_X86_PAGE_H #define _ASM_X86_PAGE_H +#include + #ifdef __KERNEL__ #include -- cgit From e43623b4ed1d0a1a86f0e05a2df8b9637b90ddd7 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 13 Feb 2009 13:24:19 +0100 Subject: x86 headers: include page_types.h in pgtable_types.h To properly pick up details like PTE_FLAGS_MASK. Signed-off-by: Ingo Molnar --- arch/x86/include/asm/pgtable_types.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h index a7452f10930..9dafe87be2d 100644 --- a/arch/x86/include/asm/pgtable_types.h +++ b/arch/x86/include/asm/pgtable_types.h @@ -2,6 +2,7 @@ #define _ASM_X86_PGTABLE_DEFS_H #include +#include #define FIRST_USER_ADDRESS 0 -- cgit From beb6943d8df7ce9278282101af4e0f6f7b648451 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 13 Feb 2009 13:36:47 +0100 Subject: x86 headers: protect page_32.h via __ASSEMBLY__ Signed-off-by: Ingo Molnar --- arch/x86/include/asm/page_32.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/page_32.h b/arch/x86/include/asm/page_32.h index b3f0bf79e84..da4e762406f 100644 --- a/arch/x86/include/asm/page_32.h +++ b/arch/x86/include/asm/page_32.h @@ -3,6 +3,8 @@ #include +#ifndef __ASSEMBLY__ + #ifdef CONFIG_HUGETLB_PAGE #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA #endif @@ -19,8 +21,6 @@ extern unsigned long __phys_addr(unsigned long); #define pfn_valid(pfn) ((pfn) < max_mapnr) #endif /* CONFIG_FLATMEM */ -#ifndef __ASSEMBLY__ - #ifdef CONFIG_X86_USE_3DNOW #include -- cgit From 694aa960608d2976666d850bd4ef78053bbd0c84 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 12 Feb 2009 16:25:42 -0800 Subject: xen: fix xen_flush_tlb_others The commit commit 4595f9620cda8a1e973588e743cf5f8436dd20c6 Author: Rusty Russell Date: Sat Jan 10 21:58:09 2009 -0800 x86: change flush_tlb_others to take a const struct cpumask causes xen_flush_tlb_others to allocate a multicall and then issue it without initializing it in the case where the cpumask is empty, leading to: [ 8.354898] 1 multicall(s) failed: cpu 1 [ 8.354921] Pid: 2213, comm: bootclean Not tainted 2.6.29-rc3-x86_32p-xenU-tip #135 [ 8.354937] Call Trace: [ 8.354955] [] xen_mc_flush+0x133/0x1b0 [ 8.354971] [] ? xen_force_evtchn_callback+0x1a/0x30 [ 8.354988] [] xen_flush_tlb_others+0xb0/0xd0 [ 8.355003] [] flush_tlb_page+0x53/0xa0 [ 8.355018] [] do_wp_page+0x2a0/0x7c0 [ 8.355034] [] ? notify_remote_via_irq+0x3a/0x70 [ 8.355049] [] handle_mm_fault+0x7b0/0xa50 [ 8.355065] [] ? wake_up_new_task+0x8e/0xb0 [ 8.355079] [] ? do_fork+0xe5/0x320 [ 8.355095] [] do_page_fault+0xe9/0x240 [ 8.355109] [] ? do_page_fault+0x0/0x240 [ 8.355125] [] error_code+0x72/0x78 [ 8.355139] call 1/1: op=2863311530 arg=[aaaaaaaa] result=-38 xen_flush_tlb_others+0x41/0xd0 Since empty cpumasks are rare and undoing an xen_mc_entry() is tricky just issue such requests normally. Signed-off-by: Ian Campbell Signed-off-by: Ingo Molnar --- arch/x86/xen/mmu.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index d2e8ed1aff3..319bd40a57c 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -1273,8 +1273,6 @@ static void xen_flush_tlb_others(const struct cpumask *cpus, /* Remove us, and any offline CPUS. */ cpumask_and(to_cpumask(args->mask), cpus, cpu_online_mask); cpumask_clear_cpu(smp_processor_id(), to_cpumask(args->mask)); - if (unlikely(cpumask_empty(to_cpumask(args->mask)))) - goto issue; if (va == TLB_FLUSH_ALL) { args->op.cmd = MMUEXT_TLB_FLUSH_MULTI; @@ -1285,7 +1283,6 @@ static void xen_flush_tlb_others(const struct cpumask *cpus, MULTI_mmuext_op(mcs.mc, &args->op, 1, NULL, DOMID_SELF); -issue: xen_mc_issue(PARAVIRT_LAZY_MMU); } -- cgit From 14fa43f53ff3a9c3d8b9662574b7369812a31a97 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 12 Feb 2009 19:33:19 +0000 Subject: ASoC: Only register AC97 bus if it's not done already ASoC supports both explicit codec drivers for AC97 devices and a simple driver which uses the standard ALSA AC97 framework for codec support. When used with the generic AC97 codec support that will provide the ad hoc AC97 device for drivers like touchscreens to attach to so the core shouldn't do so. Reported-by: Manuel Lauss Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 55fdb4abb17..ec3f8bb4b51 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1385,7 +1385,10 @@ int snd_soc_init_card(struct snd_soc_device *socdev) mutex_lock(&codec->mutex); #ifdef CONFIG_SND_SOC_AC97_BUS - if (ac97) { + /* Only instantiate AC97 if not already done by the adaptor + * for the generic AC97 subsystem. + */ + if (ac97 && strcmp(codec->name, "AC97") != 0) { ret = soc_ac97_dev_register(codec); if (ret < 0) { printk(KERN_ERR "asoc: AC97 device register failed\n"); -- cgit From fb5ae64fdde29236e1a15e0366946df7060f41f2 Mon Sep 17 00:00:00 2001 From: "Serge E. Hallyn" Date: Fri, 13 Feb 2009 14:04:21 +0000 Subject: User namespaces: Only put the userns when we unhash the uid uids in namespaces other than init don't get a sysfs entry. For those in the init namespace, while we're waiting to remove the sysfs entry for the uid the uid is still hashed, and alloc_uid() may re-grab that uid without getting a new reference to the user_ns, which we've already put in free_user before scheduling remove_user_sysfs_dir(). Reported-and-tested-by: KOSAKI Motohiro Signed-off-by: Serge E. Hallyn Acked-by: David Howells Tested-by: Ingo Molnar Signed-off-by: Linus Torvalds --- kernel/user.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kernel/user.c b/kernel/user.c index 477b6660f44..3551ac74239 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -72,6 +72,7 @@ static void uid_hash_insert(struct user_struct *up, struct hlist_head *hashent) static void uid_hash_remove(struct user_struct *up) { hlist_del_init(&up->uidhash_node); + put_user_ns(up->user_ns); } static struct user_struct *uid_hash_find(uid_t uid, struct hlist_head *hashent) @@ -334,7 +335,6 @@ static void free_user(struct user_struct *up, unsigned long flags) atomic_inc(&up->__count); spin_unlock_irqrestore(&uidhash_lock, flags); - put_user_ns(up->user_ns); INIT_WORK(&up->work, remove_user_sysfs_dir); schedule_work(&up->work); } @@ -357,7 +357,6 @@ static void free_user(struct user_struct *up, unsigned long flags) sched_destroy_user(up); key_put(up->uid_keyring); key_put(up->session_keyring); - put_user_ns(up->user_ns); kmem_cache_free(uid_cachep, up); } -- cgit From c466ed2e4337c5eb03b283da507eb5328ab06c73 Mon Sep 17 00:00:00 2001 From: Dimitri Sivanich Date: Fri, 13 Feb 2009 08:40:55 -0600 Subject: x86, UV: set full apicid in uv_hub_send_ipi The uv_hub_send_ipi() function needs to set the full apicid in the UVH_IPI_INT mmr. Signed-off-by: Dimitri Sivanich Signed-off-by: Ingo Molnar --- arch/x86/kernel/genx2apic_uv_x.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/genx2apic_uv_x.c b/arch/x86/kernel/genx2apic_uv_x.c index 6adb5e6f4d9..89b84e004f0 100644 --- a/arch/x86/kernel/genx2apic_uv_x.c +++ b/arch/x86/kernel/genx2apic_uv_x.c @@ -114,16 +114,15 @@ int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip) static void uv_send_IPI_one(int cpu, int vector) { - unsigned long val, apicid, lapicid; + unsigned long val, apicid; int pnode; apicid = per_cpu(x86_cpu_to_apicid, cpu); - lapicid = apicid & 0x3f; /* ZZZ macro needed */ pnode = uv_apicid_to_pnode(apicid); - val = ( 1UL << UVH_IPI_INT_SEND_SHFT ) | - ( lapicid << UVH_IPI_INT_APIC_ID_SHFT ) | - ( vector << UVH_IPI_INT_VECTOR_SHFT ); + val = (1UL << UVH_IPI_INT_SEND_SHFT) | + (apicid << UVH_IPI_INT_APIC_ID_SHFT) | + (vector << UVH_IPI_INT_VECTOR_SHFT); uv_write_global_mmr64(pnode, UVH_IPI_INT, val); } -- cgit From 0341c14da49e7b93d2998926f6ac89a3129e3fa1 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Fri, 13 Feb 2009 11:14:01 -0800 Subject: x86: use _types.h headers in asm where available In general, the only definitions that assembly files can use are in _types.S headers (where available), so convert them. Signed-off-by: Jeremy Fitzhardinge --- arch/x86/boot/compressed/head_32.S | 2 +- arch/x86/boot/compressed/head_64.S | 4 ++-- arch/x86/boot/header.S | 2 +- arch/x86/kernel/acpi/realmode/wakeup.S | 4 ++-- arch/x86/kernel/acpi/wakeup_32.S | 2 +- arch/x86/kernel/acpi/wakeup_64.S | 4 ++-- arch/x86/kernel/efi_stub_32.S | 2 +- arch/x86/kernel/entry_32.S | 2 +- arch/x86/kernel/entry_64.S | 2 +- arch/x86/kernel/head_32.S | 4 ++-- arch/x86/kernel/relocate_kernel_32.S | 2 +- arch/x86/kernel/relocate_kernel_64.S | 4 ++-- arch/x86/kernel/trampoline_32.S | 2 +- arch/x86/kernel/trampoline_64.S | 4 ++-- arch/x86/kernel/vmlinux_32.lds.S | 2 +- arch/x86/kernel/vmlinux_64.lds.S | 2 +- arch/x86/lib/getuser.S | 2 +- arch/x86/power/hibernate_asm_32.S | 2 +- arch/x86/power/hibernate_asm_64.S | 2 +- arch/x86/xen/xen-head.S | 2 +- 20 files changed, 26 insertions(+), 26 deletions(-) diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index 29c5fbf0839..112f81abfa6 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index 1d5dff4123e..36743525e37 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S @@ -26,8 +26,8 @@ #include #include -#include -#include +#include +#include #include #include #include diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index b993062e9a5..7ccff4884a2 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include "boot.h" #include "offsets.h" diff --git a/arch/x86/kernel/acpi/realmode/wakeup.S b/arch/x86/kernel/acpi/realmode/wakeup.S index 3355973b12a..580b4e29601 100644 --- a/arch/x86/kernel/acpi/realmode/wakeup.S +++ b/arch/x86/kernel/acpi/realmode/wakeup.S @@ -3,8 +3,8 @@ */ #include #include -#include -#include +#include +#include #include .code16 diff --git a/arch/x86/kernel/acpi/wakeup_32.S b/arch/x86/kernel/acpi/wakeup_32.S index a12e6a9fb65..8ded418b059 100644 --- a/arch/x86/kernel/acpi/wakeup_32.S +++ b/arch/x86/kernel/acpi/wakeup_32.S @@ -1,7 +1,7 @@ .section .text.page_aligned #include #include -#include +#include # Copyright 2003, 2008 Pavel Machek , distribute under GPLv2 diff --git a/arch/x86/kernel/acpi/wakeup_64.S b/arch/x86/kernel/acpi/wakeup_64.S index bcc293423a7..82add8b804b 100644 --- a/arch/x86/kernel/acpi/wakeup_64.S +++ b/arch/x86/kernel/acpi/wakeup_64.S @@ -1,8 +1,8 @@ .text #include #include -#include -#include +#include +#include #include #include diff --git a/arch/x86/kernel/efi_stub_32.S b/arch/x86/kernel/efi_stub_32.S index ef00bb77d7e..8b9171b9cbd 100644 --- a/arch/x86/kernel/efi_stub_32.S +++ b/arch/x86/kernel/efi_stub_32.S @@ -6,7 +6,7 @@ */ #include -#include +#include /* * efi_call_phys(void *, ...) is a function with variable parameters. diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index e9920683145..999e827ef9c 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -47,7 +47,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index fbcf96b295f..dcf31283f94 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -48,7 +48,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 2a0aad7718d..c32ca19d591 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S @@ -11,8 +11,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include diff --git a/arch/x86/kernel/relocate_kernel_32.S b/arch/x86/kernel/relocate_kernel_32.S index a160f311972..2064d0aa8d2 100644 --- a/arch/x86/kernel/relocate_kernel_32.S +++ b/arch/x86/kernel/relocate_kernel_32.S @@ -7,7 +7,7 @@ */ #include -#include +#include #include #include diff --git a/arch/x86/kernel/relocate_kernel_64.S b/arch/x86/kernel/relocate_kernel_64.S index b0bbdd4829c..d32cfb27a47 100644 --- a/arch/x86/kernel/relocate_kernel_64.S +++ b/arch/x86/kernel/relocate_kernel_64.S @@ -7,10 +7,10 @@ */ #include -#include +#include #include #include -#include +#include /* * Must be relocatable PIC code callable as a C function diff --git a/arch/x86/kernel/trampoline_32.S b/arch/x86/kernel/trampoline_32.S index d8ccc3c6552..66d874e5404 100644 --- a/arch/x86/kernel/trampoline_32.S +++ b/arch/x86/kernel/trampoline_32.S @@ -29,7 +29,7 @@ #include #include -#include +#include /* We can free up trampoline after bootup if cpu hotplug is not supported. */ #ifndef CONFIG_HOTPLUG_CPU diff --git a/arch/x86/kernel/trampoline_64.S b/arch/x86/kernel/trampoline_64.S index 95a012a4664..cddfb8d386b 100644 --- a/arch/x86/kernel/trampoline_64.S +++ b/arch/x86/kernel/trampoline_64.S @@ -25,8 +25,8 @@ */ #include -#include -#include +#include +#include #include #include #include diff --git a/arch/x86/kernel/vmlinux_32.lds.S b/arch/x86/kernel/vmlinux_32.lds.S index 3eba7f7bac0..0d860963f26 100644 --- a/arch/x86/kernel/vmlinux_32.lds.S +++ b/arch/x86/kernel/vmlinux_32.lds.S @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S index 087a7f2c639..fbfced6f680 100644 --- a/arch/x86/kernel/vmlinux_64.lds.S +++ b/arch/x86/kernel/vmlinux_64.lds.S @@ -6,7 +6,7 @@ #include #include -#include +#include #undef i386 /* in case the preprocessor is a 32bit one */ diff --git a/arch/x86/lib/getuser.S b/arch/x86/lib/getuser.S index ad374003742..51f1504cddd 100644 --- a/arch/x86/lib/getuser.S +++ b/arch/x86/lib/getuser.S @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/x86/power/hibernate_asm_32.S b/arch/x86/power/hibernate_asm_32.S index d1e9b53f9d3..b641388d828 100644 --- a/arch/x86/power/hibernate_asm_32.S +++ b/arch/x86/power/hibernate_asm_32.S @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/arch/x86/power/hibernate_asm_64.S b/arch/x86/power/hibernate_asm_64.S index 000415947d9..9356547d8c0 100644 --- a/arch/x86/power/hibernate_asm_64.S +++ b/arch/x86/power/hibernate_asm_64.S @@ -18,7 +18,7 @@ .text #include #include -#include +#include #include #include diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S index 63d49a523ed..1a5ff24e29c 100644 --- a/arch/x86/xen/xen-head.S +++ b/arch/x86/xen/xen-head.S @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include -- cgit From 9b3651cbc26cfcea8276ecaff66718ea087f2e91 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Fri, 13 Feb 2009 11:01:54 -0800 Subject: x86: move more pagetable-related definitions into pgtable*.h PAGETABLE_LEVELS and the PTE masks should be in pgtable*.h Signed-off-by: Jeremy Fitzhardinge --- arch/x86/include/asm/page_32_types.h | 2 -- arch/x86/include/asm/page_64_types.h | 2 -- arch/x86/include/asm/page_types.h | 6 ------ arch/x86/include/asm/pgtable-2level_types.h | 2 ++ arch/x86/include/asm/pgtable-3level_types.h | 2 ++ arch/x86/include/asm/pgtable_64_types.h | 1 + arch/x86/include/asm/pgtable_types.h | 6 ++++++ 7 files changed, 11 insertions(+), 10 deletions(-) diff --git a/arch/x86/include/asm/page_32_types.h b/arch/x86/include/asm/page_32_types.h index b5486aaf36e..f1e4a79a6e4 100644 --- a/arch/x86/include/asm/page_32_types.h +++ b/arch/x86/include/asm/page_32_types.h @@ -33,12 +33,10 @@ /* 44=32+12, the limit we can fit into an unsigned long pfn */ #define __PHYSICAL_MASK_SHIFT 44 #define __VIRTUAL_MASK_SHIFT 32 -#define PAGETABLE_LEVELS 3 #else /* !CONFIG_X86_PAE */ #define __PHYSICAL_MASK_SHIFT 32 #define __VIRTUAL_MASK_SHIFT 32 -#define PAGETABLE_LEVELS 2 #endif /* CONFIG_X86_PAE */ #ifndef __ASSEMBLY__ diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h index bc73af3eda9..d38c91b7024 100644 --- a/arch/x86/include/asm/page_64_types.h +++ b/arch/x86/include/asm/page_64_types.h @@ -1,8 +1,6 @@ #ifndef _ASM_X86_PAGE_64_DEFS_H #define _ASM_X86_PAGE_64_DEFS_H -#define PAGETABLE_LEVELS 4 - #define THREAD_ORDER 1 #define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) #define CURRENT_MASK (~(THREAD_SIZE - 1)) diff --git a/arch/x86/include/asm/page_types.h b/arch/x86/include/asm/page_types.h index 2c52ff76758..2d625da6603 100644 --- a/arch/x86/include/asm/page_types.h +++ b/arch/x86/include/asm/page_types.h @@ -16,12 +16,6 @@ (ie, 32-bit PAE). */ #define PHYSICAL_PAGE_MASK (((signed long)PAGE_MASK) & __PHYSICAL_MASK) -/* PTE_PFN_MASK extracts the PFN from a (pte|pmd|pud|pgd)val_t */ -#define PTE_PFN_MASK ((pteval_t)PHYSICAL_PAGE_MASK) - -/* PTE_FLAGS_MASK extracts the flags from a (pte|pmd|pud|pgd)val_t */ -#define PTE_FLAGS_MASK (~PTE_PFN_MASK) - #define PMD_PAGE_SIZE (_AC(1, UL) << PMD_SHIFT) #define PMD_PAGE_MASK (~(PMD_PAGE_SIZE-1)) diff --git a/arch/x86/include/asm/pgtable-2level_types.h b/arch/x86/include/asm/pgtable-2level_types.h index 09ae67efceb..daacc23e3fb 100644 --- a/arch/x86/include/asm/pgtable-2level_types.h +++ b/arch/x86/include/asm/pgtable-2level_types.h @@ -17,6 +17,7 @@ typedef union { #endif /* !__ASSEMBLY__ */ #define SHARED_KERNEL_PMD 0 +#define PAGETABLE_LEVELS 2 /* * traditional i386 two-level paging structure: @@ -25,6 +26,7 @@ typedef union { #define PGDIR_SHIFT 22 #define PTRS_PER_PGD 1024 + /* * the i386 is two-level, so we don't really have any * PMD directory physically. diff --git a/arch/x86/include/asm/pgtable-3level_types.h b/arch/x86/include/asm/pgtable-3level_types.h index bcc89625ebe..1bd5876c864 100644 --- a/arch/x86/include/asm/pgtable-3level_types.h +++ b/arch/x86/include/asm/pgtable-3level_types.h @@ -24,6 +24,8 @@ typedef union { #define SHARED_KERNEL_PMD 1 #endif +#define PAGETABLE_LEVELS 3 + /* * PGDIR_SHIFT determines what a top-level page table entry can map */ diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h index 2f59135c6f2..fbf42b8e038 100644 --- a/arch/x86/include/asm/pgtable_64_types.h +++ b/arch/x86/include/asm/pgtable_64_types.h @@ -18,6 +18,7 @@ typedef struct { pteval_t pte; } pte_t; #endif /* !__ASSEMBLY__ */ #define SHARED_KERNEL_PMD 0 +#define PAGETABLE_LEVELS 4 /* * PGDIR_SHIFT determines what a top-level page table entry can map diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h index 9dafe87be2d..4d258ad76a0 100644 --- a/arch/x86/include/asm/pgtable_types.h +++ b/arch/x86/include/asm/pgtable_types.h @@ -173,6 +173,12 @@ #include +/* PTE_PFN_MASK extracts the PFN from a (pte|pmd|pud|pgd)val_t */ +#define PTE_PFN_MASK ((pteval_t)PHYSICAL_PAGE_MASK) + +/* PTE_FLAGS_MASK extracts the flags from a (pte|pmd|pud|pgd)val_t */ +#define PTE_FLAGS_MASK (~PTE_PFN_MASK) + typedef struct pgprot { pgprotval_t pgprot; } pgprot_t; typedef struct { pgdval_t pgd; } pgd_t; -- cgit From 0b49ec37a20bc7eb7178105aadaa8d1ecba825f8 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sun, 8 Feb 2009 20:27:47 -0700 Subject: PCI/MSI: fix msi_mask() shift fix Hidetoshi Seto points out that commit bffac3c593eba1f9da3efd0199e49ea6558a40ce has wrong values in the array. Rather than correct the array, we can just use a bounds check and perform the calculation specified in the comment. As a bonus, this will not run off the end of the array if the device specifies an illegal value in the MSI capability. Signed-off-by: Matthew Wilcox Signed-off-by: Hidetoshi Seto Signed-off-by: Jesse Barnes --- drivers/pci/msi.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 44f15ff70c1..baba2eb5367 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -103,14 +103,12 @@ static void msix_set_enable(struct pci_dev *dev, int enable) } } -/* - * Essentially, this is ((1 << (1 << x)) - 1), but without the - * undefinedness of a << 32. - */ static inline __attribute_const__ u32 msi_mask(unsigned x) { - static const u32 mask[] = { 1, 2, 4, 0xf, 0xff, 0xffff, 0xffffffff }; - return mask[x]; + /* Don't shift by >= width of type */ + if (x >= 5) + return 0xffffffff; + return (1 << (1 << x)) - 1; } static void msix_flush_writes(struct irq_desc *desc) -- cgit From 4cc59c721cba27a4644e29103afac0f91af8da3c Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 9 Feb 2009 09:31:20 -0800 Subject: PCI: fix rom.c kernel-doc warning Fix PCI kernel-doc warning: Warning(linux-2.6.29-rc4-git1/drivers/pci/rom.c:67): No description found for parameter 'pdev' Signed-off-by: Randy Dunlap cc: Jesse Barnes Signed-off-by: Jesse Barnes --- drivers/pci/rom.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index 29cbe47f219..36864a935d6 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c @@ -55,6 +55,7 @@ void pci_disable_rom(struct pci_dev *pdev) /** * pci_get_rom_size - obtain the actual size of the ROM image + * @pdev: target PCI device * @rom: kernel virtual pointer to image of ROM * @size: size of PCI window * return: size of actual ROM image -- cgit From bf33a70a73876b163d62612e9567cbac6604ba7e Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 13 Feb 2009 12:52:44 -0600 Subject: x86: fix "__udivdi3" [drivers/scsi/aha1542.ko] undefined Commit 976e8f677e42757e5586ea04a9ac8bb8ddaa037e ("x86: asm/io.h: unify virt_to_phys/phys_to_virt") changed the return of virt_to_phys from long to phys_addr_t which is unsigned long long on a PAE platform. So, I could suggest a fix below since isa addresses may never be above 32 bits. Signed-off-by: Ingo Molnar --- arch/x86/include/asm/io.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index e5a2ab44cd5..4f8e820cf38 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h @@ -125,7 +125,7 @@ static inline void *phys_to_virt(phys_addr_t address) /* * ISA I/O bus memory addresses are 1:1 with the physical address. */ -#define isa_virt_to_bus virt_to_phys +#define isa_virt_to_bus (unsigned long)virt_to_phys #define isa_page_to_bus page_to_phys #define isa_bus_to_virt phys_to_virt -- cgit From b33bfdef24565fe54da91adf3cd4eea13488d7fc Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 9 Jan 2009 17:04:26 -0800 Subject: PCI: fix struct pci_platform_pm_ops kernel-doc Fix struct pci_platform_pm_ops kernel-doc notation. Signed-off-by: Randy Dunlap Signed-off-by: Jesse Barnes --- drivers/pci/pci.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 26ddf78ac30..07c0aa5275e 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -16,21 +16,21 @@ extern int pci_mmap_fits(struct pci_dev *pdev, int resno, #endif /** - * Firmware PM callbacks + * struct pci_platform_pm_ops - Firmware PM callbacks * - * @is_manageable - returns 'true' if given device is power manageable by the - * platform firmware + * @is_manageable: returns 'true' if given device is power manageable by the + * platform firmware * - * @set_state - invokes the platform firmware to set the device's power state + * @set_state: invokes the platform firmware to set the device's power state * - * @choose_state - returns PCI power state of given device preferred by the - * platform; to be used during system-wide transitions from a - * sleeping state to the working state and vice versa + * @choose_state: returns PCI power state of given device preferred by the + * platform; to be used during system-wide transitions from a + * sleeping state to the working state and vice versa * - * @can_wakeup - returns 'true' if given device is capable of waking up the - * system from a sleeping state + * @can_wakeup: returns 'true' if given device is capable of waking up the + * system from a sleeping state * - * @sleep_wake - enables/disables the system wake up capability of given device + * @sleep_wake: enables/disables the system wake up capability of given device * * If given platform is generally capable of power managing PCI devices, all of * these callbacks are mandatory. -- cgit From f5ddcac435b6c6133a9c137c345abef53b93cf55 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 9 Jan 2009 17:03:20 -0800 Subject: PCI: fix missing kernel-doc and typos Fix pci kernel-doc parameter missing notation, correct function name, and fix typo: Warning(linux-2.6.28-git10//drivers/pci/pci.c:1511): No description found for parameter 'exclusive' Signed-off-by: Randy Dunlap Signed-off-by: Jesse Barnes --- drivers/pci/pci.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e3efe6b19ee..6d6120007af 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1540,16 +1540,21 @@ void pci_release_region(struct pci_dev *pdev, int bar) } /** - * pci_request_region - Reserved PCI I/O and memory resource + * __pci_request_region - Reserved PCI I/O and memory resource * @pdev: PCI device whose resources are to be reserved * @bar: BAR to be reserved * @res_name: Name to be associated with resource. + * @exclusive: whether the region access is exclusive or not * * Mark the PCI region associated with PCI device @pdev BR @bar as * being reserved by owner @res_name. Do not access any * address inside the PCI regions unless this call returns * successfully. * + * If @exclusive is set, then the region is marked so that userspace + * is explicitly not allowed to map the resource via /dev/mem or + * sysfs MMIO access. + * * Returns 0 on success, or %EBUSY on error. A warning * message is also printed on failure. */ @@ -1588,12 +1593,12 @@ err_out: } /** - * pci_request_region - Reserved PCI I/O and memory resource + * pci_request_region - Reserve PCI I/O and memory resource * @pdev: PCI device whose resources are to be reserved * @bar: BAR to be reserved - * @res_name: Name to be associated with resource. + * @res_name: Name to be associated with resource * - * Mark the PCI region associated with PCI device @pdev BR @bar as + * Mark the PCI region associated with PCI device @pdev BAR @bar as * being reserved by owner @res_name. Do not access any * address inside the PCI regions unless this call returns * successfully. -- cgit From a08f6e04d74478d91f34a0484e69e89870adb33d Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Fri, 13 Feb 2009 12:03:17 -0700 Subject: PCI: Documentation: fix minor PCIe HOWTO thinko Update doc to correctly refer to replacing the pci_register_driver API, and not the non-existent "pci_module_init" API. Signed-off-by: Alex Chiang Signed-off-by: Jesse Barnes --- Documentation/PCI/PCIEBUS-HOWTO.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/PCI/PCIEBUS-HOWTO.txt b/Documentation/PCI/PCIEBUS-HOWTO.txt index 9a07e38631b..6bd5f372ade 100644 --- a/Documentation/PCI/PCIEBUS-HOWTO.txt +++ b/Documentation/PCI/PCIEBUS-HOWTO.txt @@ -93,7 +93,7 @@ the PCI Express Port Bus driver from loading a service driver. int pcie_port_service_register(struct pcie_port_service_driver *new) -This API replaces the Linux Driver Model's pci_module_init API. A +This API replaces the Linux Driver Model's pci_register_driver API. A service driver should always calls pcie_port_service_register at module init. Note that after service driver being loaded, calls such as pci_enable_device(dev) and pci_set_master(dev) are no longer -- cgit From d2f8d7ee1a9b4650b4e43325b321801264f7c37a Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 13 Feb 2009 15:31:30 -0800 Subject: Linux 2.6.29-rc5 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 681c1d23b4d..22d758495ad 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 29 -EXTRAVERSION = -rc4 +EXTRAVERSION = -rc5 NAME = Erotic Pickled Herring # *DOCUMENTATION* -- cgit From e480814f138cd5d78a8efe397756ba6b6518fdb6 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Wed, 11 Feb 2009 13:12:17 -0800 Subject: [MTD] [MAPS] physmap: fix wrong free and del_mtd_{partition,device} commit 176bf2e0f10ecf1d20a97db3bd5bb2e6ba0b5668 ("physmap: fix leak of memory returned by parse_mtd_partitions") deals with a memory leak and frees the pointer array of mtd_partition after the call to add_mtd_partitions(). the problem is that mtd_table[x]->name still points to the freed memory. Aldo physmap_flash_remove() should call del_mtd_partitions() or del_mtd_device() only once. Signed-off-by: Atsushi Nemoto Reported-by: Matthias Kaehlcke Tested-by: Matthias Kaehlcke Signed-off-by: Andrew Morton Signed-off-by: David Woodhouse --- drivers/mtd/maps/physmap.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c index 87743661d48..4b122e7ab4b 100644 --- a/drivers/mtd/maps/physmap.c +++ b/drivers/mtd/maps/physmap.c @@ -29,6 +29,7 @@ struct physmap_flash_info { struct map_info map[MAX_RESOURCES]; #ifdef CONFIG_MTD_PARTITIONS int nr_parts; + struct mtd_partition *parts; #endif }; @@ -45,25 +46,26 @@ static int physmap_flash_remove(struct platform_device *dev) physmap_data = dev->dev.platform_data; -#ifdef CONFIG_MTD_CONCAT - if (info->cmtd != info->mtd[0]) { +#ifdef CONFIG_MTD_PARTITIONS + if (info->nr_parts) { + del_mtd_partitions(info->cmtd); + kfree(info->parts); + } else if (physmap_data->nr_parts) + del_mtd_partitions(info->cmtd); + else del_mtd_device(info->cmtd); +#else + del_mtd_device(info->cmtd); +#endif + +#ifdef CONFIG_MTD_CONCAT + if (info->cmtd != info->mtd[0]) mtd_concat_destroy(info->cmtd); - } #endif for (i = 0; i < MAX_RESOURCES; i++) { - if (info->mtd[i] != NULL) { -#ifdef CONFIG_MTD_PARTITIONS - if (info->nr_parts || physmap_data->nr_parts) - del_mtd_partitions(info->mtd[i]); - else - del_mtd_device(info->mtd[i]); -#else - del_mtd_device(info->mtd[i]); -#endif + if (info->mtd[i] != NULL) map_destroy(info->mtd[i]); - } } return 0; } @@ -86,9 +88,6 @@ static int physmap_flash_probe(struct platform_device *dev) int err = 0; int i; int devices_found = 0; -#ifdef CONFIG_MTD_PARTITIONS - struct mtd_partition *parts; -#endif physmap_data = dev->dev.platform_data; if (physmap_data == NULL) @@ -167,10 +166,11 @@ static int physmap_flash_probe(struct platform_device *dev) goto err_out; #ifdef CONFIG_MTD_PARTITIONS - err = parse_mtd_partitions(info->cmtd, part_probe_types, &parts, 0); + err = parse_mtd_partitions(info->cmtd, part_probe_types, + &info->parts, 0); if (err > 0) { - add_mtd_partitions(info->cmtd, parts, err); - kfree(parts); + add_mtd_partitions(info->cmtd, info->parts, err); + info->nr_parts = err; return 0; } -- cgit From 10715b8751dfc403aeb7fbc35166417fa1664eda Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 11 Feb 2009 13:12:18 -0800 Subject: [MTD] [MAPS] blackfin: fix memory leak in error path Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu Signed-off-by: Andrew Morton Signed-off-by: David Woodhouse --- drivers/mtd/maps/bfin-async-flash.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/maps/bfin-async-flash.c b/drivers/mtd/maps/bfin-async-flash.c index 6fec86aaed7..576611f605d 100644 --- a/drivers/mtd/maps/bfin-async-flash.c +++ b/drivers/mtd/maps/bfin-async-flash.c @@ -152,14 +152,18 @@ static int __devinit bfin_flash_probe(struct platform_device *pdev) if (gpio_request(state->enet_flash_pin, DRIVER_NAME)) { pr_devinit(KERN_ERR DRIVER_NAME ": Failed to request gpio %d\n", state->enet_flash_pin); + kfree(state); return -EBUSY; } gpio_direction_output(state->enet_flash_pin, 1); pr_devinit(KERN_NOTICE DRIVER_NAME ": probing %d-bit flash bus\n", state->map.bankwidth * 8); state->mtd = do_map_probe(memory->name, &state->map); - if (!state->mtd) + if (!state->mtd) { + gpio_free(state->enet_flash_pin); + kfree(state); return -ENXIO; + } #ifdef CONFIG_MTD_PARTITIONS ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0); -- cgit From ab00d68276295a1b4da7ad924a35a3566e9c2698 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 11 Feb 2009 13:12:19 -0800 Subject: [MTD] [MAPS] blackfin async requires complex mappings Correct a build error. bfin-async uses complex mappings and so needs it. Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu Cc: David Woodhouse Signed-off-by: Andrew Morton Signed-off-by: David Woodhouse --- drivers/mtd/maps/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index 0225cbbf22d..043d50fb6ef 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig @@ -491,7 +491,7 @@ config MTD_PCMCIA_ANONYMOUS config MTD_BFIN_ASYNC tristate "Blackfin BF533-STAMP Flash Chip Support" - depends on BFIN533_STAMP && MTD_CFI + depends on BFIN533_STAMP && MTD_CFI && MTD_COMPLEX_MAPPINGS select MTD_PARTITIONS default y help -- cgit From 084eb960e81505680a9963665722d1bfd94af6a7 Mon Sep 17 00:00:00 2001 From: Tony Battersby Date: Wed, 11 Feb 2009 13:24:19 -0800 Subject: intel-iommu: fix endless "Unknown DMAR structure type" loop I have a SuperMicro C2SBX motherboard with BIOS revision 1.0b. With vt-d enabled in the BIOS, Linux gets into an endless loop printing "DMAR:Unknown DMAR structure type" when booting. Here is the DMAR ACPI table: DMAR @ 0x7fe86dec 0000: 44 4d 41 52 98 00 00 00 01 6f 49 6e 74 65 6c 20 DMAR.....oIntel 0010: 4f 45 4d 44 4d 41 52 20 00 00 04 06 4c 4f 48 52 OEMDMAR ....LOHR 0020: 01 00 00 00 23 00 00 00 00 00 00 00 00 00 00 00 ....#........... 0030: 01 00 58 00 00 00 00 00 00 a0 e8 7f 00 00 00 00 ..X............. 0040: ff ff ef 7f 00 00 00 00 01 08 00 00 00 00 1d 00 ................ 0050: 01 08 00 00 00 00 1d 01 01 08 00 00 00 00 1d 02 ................ 0060: 01 08 00 00 00 00 1d 07 01 08 00 00 00 00 1a 00 ................ 0070: 01 08 00 00 00 00 1a 01 01 08 00 00 00 00 1a 02 ................ 0080: 01 08 00 00 00 00 1a 07 01 08 00 00 00 00 1a 07 ................ 0090: c0 00 68 00 04 10 66 60 ..h...f` Here are the messages printed by the kernel: DMAR:Host address width 36 DMAR:RMRR base: 0x000000007fe8a000 end: 0x000000007fefffff DMAR:Unknown DMAR structure type DMAR:Unknown DMAR structure type DMAR:Unknown DMAR structure type ... Although I not very familiar with ACPI, to me it looks like struct acpi_dmar_header::length == 0x0058 is incorrect, causing parse_dmar_table() to look at an invalid offset on the next loop. This offset happens to have struct acpi_dmar_header::length == 0x0000, which prevents the loop from ever terminating. This patch checks for this condition and bails out instead of looping forever. Signed-off-by: Tony Battersby Signed-off-by: Andrew Morton Signed-off-by: David Woodhouse --- drivers/pci/dmar.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 8d3e9c26106..26c536b51c5 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c @@ -330,6 +330,14 @@ parse_dmar_table(void) entry_header = (struct acpi_dmar_header *)(dmar + 1); while (((unsigned long)entry_header) < (((unsigned long)dmar) + dmar_tbl->length)) { + /* Avoid looping forever on bad ACPI tables */ + if (entry_header->length == 0) { + printk(KERN_WARNING PREFIX + "Invalid 0-length structure\n"); + ret = -EINVAL; + break; + } + dmar_table_print_dmar_entry(entry_header); switch (entry_header->type) { -- cgit From 12d60e28bed3f593aac5385acbdbb089eb8ae21e Mon Sep 17 00:00:00 2001 From: Wim Van Sebroeck Date: Wed, 28 Jan 2009 20:51:04 +0000 Subject: [WATCHDOG] iTCO_wdt: fix SMI_EN regression 2 bugzilla: #12363 commit 7cd5b08be3c489df11b559fef210b81133764ad4 added a second regression: some Dell's and Compaq's lockup on boot. So we revert most of the code. The ICH9 reboot issue remains in place and will need some more fixing... :-( Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/Kconfig | 2 +- drivers/watchdog/iTCO_vendor_support.c | 32 +++++++++++++++++++++++++++---- drivers/watchdog/iTCO_wdt.c | 35 ++++++++++++++-------------------- 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 09a3d5522b4..325c10ff6a2 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -406,7 +406,7 @@ config ITCO_WDT ---help--- Hardware driver for the intel TCO timer based watchdog devices. These drivers are included in the Intel 82801 I/O Controller - Hub family (from ICH0 up to ICH8) and in the Intel 6300ESB + Hub family (from ICH0 up to ICH10) and in the Intel 63xxESB controller hub. The TCO (Total Cost of Ownership) timer is a watchdog timer diff --git a/drivers/watchdog/iTCO_vendor_support.c b/drivers/watchdog/iTCO_vendor_support.c index 2474ebca88f..d8264ad0be4 100644 --- a/drivers/watchdog/iTCO_vendor_support.c +++ b/drivers/watchdog/iTCO_vendor_support.c @@ -1,7 +1,7 @@ /* * intel TCO vendor specific watchdog driver support * - * (c) Copyright 2006-2008 Wim Van Sebroeck . + * (c) Copyright 2006-2009 Wim Van Sebroeck . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -19,7 +19,7 @@ /* Module and version information */ #define DRV_NAME "iTCO_vendor_support" -#define DRV_VERSION "1.02" +#define DRV_VERSION "1.03" #define PFX DRV_NAME ": " /* Includes */ @@ -77,6 +77,26 @@ MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=0 (n * 20.6 seconds. */ +static void supermicro_old_pre_start(unsigned long acpibase) +{ + unsigned long val32; + + /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ + val32 = inl(SMI_EN); + val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ + outl(val32, SMI_EN); /* Needed to activate watchdog */ +} + +static void supermicro_old_pre_stop(unsigned long acpibase) +{ + unsigned long val32; + + /* Bit 13: TCO_EN -> 1 = Enables the TCO logic to generate SMI# */ + val32 = inl(SMI_EN); + val32 |= 0x00002000; /* Turn on SMI clearing watchdog */ + outl(val32, SMI_EN); /* Needed to deactivate watchdog */ +} + static void supermicro_old_pre_keepalive(unsigned long acpibase) { /* Reload TCO Timer (done in iTCO_wdt_keepalive) + */ @@ -228,14 +248,18 @@ static void supermicro_new_pre_set_heartbeat(unsigned int heartbeat) void iTCO_vendor_pre_start(unsigned long acpibase, unsigned int heartbeat) { - if (vendorsupport == SUPERMICRO_NEW_BOARD) + if (vendorsupport == SUPERMICRO_OLD_BOARD) + supermicro_old_pre_start(acpibase); + else if (vendorsupport == SUPERMICRO_NEW_BOARD) supermicro_new_pre_start(heartbeat); } EXPORT_SYMBOL(iTCO_vendor_pre_start); void iTCO_vendor_pre_stop(unsigned long acpibase) { - if (vendorsupport == SUPERMICRO_NEW_BOARD) + if (vendorsupport == SUPERMICRO_OLD_BOARD) + supermicro_old_pre_stop(acpibase); + else if (vendorsupport == SUPERMICRO_NEW_BOARD) supermicro_new_pre_stop(); } EXPORT_SYMBOL(iTCO_vendor_pre_stop); diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index 5b395a4ddfd..352334947ea 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c @@ -1,7 +1,7 @@ /* - * intel TCO Watchdog Driver (Used in i82801 and i6300ESB chipsets) + * intel TCO Watchdog Driver (Used in i82801 and i63xxESB chipsets) * - * (c) Copyright 2006-2008 Wim Van Sebroeck . + * (c) Copyright 2006-2009 Wim Van Sebroeck . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -63,7 +63,7 @@ /* Module and version information */ #define DRV_NAME "iTCO_wdt" -#define DRV_VERSION "1.04" +#define DRV_VERSION "1.05" #define PFX DRV_NAME ": " /* Includes */ @@ -236,16 +236,16 @@ MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); /* Address definitions for the TCO */ /* TCO base address */ -#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60 +#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60 /* SMI Control and Enable Register */ -#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30 +#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30 #define TCO_RLD TCOBASE + 0x00 /* TCO Timer Reload and Curr. Value */ #define TCOv1_TMR TCOBASE + 0x01 /* TCOv1 Timer Initial Value */ -#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */ -#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */ -#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ -#define TCO2_STS TCOBASE + 0x06 /* TCO2 Status Register */ +#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */ +#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */ +#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ +#define TCO2_STS TCOBASE + 0x06 /* TCO2 Status Register */ #define TCO1_CNT TCOBASE + 0x08 /* TCO1 Control Register */ #define TCO2_CNT TCOBASE + 0x0a /* TCO2 Control Register */ #define TCOv2_TMR TCOBASE + 0x12 /* TCOv2 Timer Initial Value */ @@ -338,7 +338,6 @@ static int iTCO_wdt_unset_NO_REBOOT_bit(void) static int iTCO_wdt_start(void) { unsigned int val; - unsigned long val32; spin_lock(&iTCO_wdt_private.io_lock); @@ -351,11 +350,6 @@ static int iTCO_wdt_start(void) return -EIO; } - /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ - val32 = inl(SMI_EN); - val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ - outl(val32, SMI_EN); - /* Force the timer to its reload value by writing to the TCO_RLD register */ if (iTCO_wdt_private.iTCO_version == 2) @@ -378,7 +372,6 @@ static int iTCO_wdt_start(void) static int iTCO_wdt_stop(void) { unsigned int val; - unsigned long val32; spin_lock(&iTCO_wdt_private.io_lock); @@ -390,11 +383,6 @@ static int iTCO_wdt_stop(void) outw(val, TCO1_CNT); val = inw(TCO1_CNT); - /* Bit 13: TCO_EN -> 1 = Enables the TCO logic to generate SMI# */ - val32 = inl(SMI_EN); - val32 |= 0x00002000; - outl(val32, SMI_EN); - /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ iTCO_wdt_set_NO_REBOOT_bit(); @@ -649,6 +637,7 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, int ret; u32 base_address; unsigned long RCBA; + unsigned long val32; /* * Find the ACPI/PM base I/O address which is the base @@ -695,6 +684,10 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, ret = -EIO; goto out; } + /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ + val32 = inl(SMI_EN); + val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ + outl(val32, SMI_EN); /* The TCO I/O registers reside in a 32-byte range pointed to by the TCOBASE value */ -- cgit From efab0b5d3eed6aa71f8e3233e4e11774eedc04dc Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Wed, 11 Feb 2009 13:27:02 -0800 Subject: [JFFS2] force the jffs2 GC daemon to behave a bit better I've noticed some pretty poor behavior on OLPC machines after bootup, when gdm/X are starting. The GCD monopolizes the scheduler (which in turns means it gets to do more nand i/o), which results in processes taking much much longer than they should to start. As an example, on an OLPC machine going from OFW to a usable X (via auto-login gdm) takes 2m 30s. The majority of this time is consumed by the switch into graphical mode. With this patch, we cut a full 60s off of bootup time. After bootup, things are much snappier as well. Note that we have seen a CRC node error with this patch that causes the machine to fail to boot, but we've also seen that problem without this patch. Signed-off-by: Andres Salomon Signed-off-by: Andrew Morton Signed-off-by: David Woodhouse --- fs/jffs2/background.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/fs/jffs2/background.c b/fs/jffs2/background.c index 3cceef4ad2b..e9580104b6b 100644 --- a/fs/jffs2/background.c +++ b/fs/jffs2/background.c @@ -95,13 +95,17 @@ static int jffs2_garbage_collect_thread(void *_c) spin_unlock(&c->erase_completion_lock); - /* This thread is purely an optimisation. But if it runs when - other things could be running, it actually makes things a - lot worse. Use yield() and put it at the back of the runqueue - every time. Especially during boot, pulling an inode in - with read_inode() is much preferable to having the GC thread - get there first. */ - yield(); + /* Problem - immediately after bootup, the GCD spends a lot + * of time in places like jffs2_kill_fragtree(); so much so + * that userspace processes (like gdm and X) are starved + * despite plenty of cond_resched()s and renicing. Yield() + * doesn't help, either (presumably because userspace and GCD + * are generally competing for a higher latency resource - + * disk). + * This forces the GCD to slow the hell down. Pulling an + * inode in with read_inode() is much preferable to having + * the GC thread get there first. */ + schedule_timeout_interruptible(msecs_to_jiffies(50)); /* Put_super will send a SIGKILL and then wait on the sem. */ -- cgit From 9132f1b453924e7595ce2dc1853704b2a31f42de Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 14 Feb 2009 13:24:10 +0000 Subject: [ARM] omap: fix omap2_divisor_to_clksel() error return value The error checks for omap2_divisor_to_clksel() and comment disagree with the actual value returned on error. Fix this to return the correct error value. Signed-off-by: Russell King --- arch/arm/mach-omap2/clock.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index ad721e0cbf7..2899cba2aaa 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -565,7 +565,7 @@ u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val) * * Given a struct clk of a rate-selectable clksel clock, and a clock divisor, * find the corresponding register field value. The return register value is - * the value before left-shifting. Returns 0xffffffff on error + * the value before left-shifting. Returns ~0 on error */ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div) { @@ -577,7 +577,7 @@ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div) clks = omap2_get_clksel_by_parent(clk, clk->parent); if (clks == NULL) - return 0; + return ~0; for (clkr = clks->rates; clkr->div; clkr++) { if ((clkr->flags & cpu_mask) && (clkr->div == div)) @@ -588,7 +588,7 @@ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div) printk(KERN_ERR "clock: Could not find divisor %d for " "clock %s parent %s\n", div, clk->name, clk->parent->name); - return 0; + return ~0; } return clkr->val; -- cgit From abf239657b88fa7e75d5b44a65a4177e7bb8acce Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 14 Feb 2009 13:25:38 +0000 Subject: [ARM] omap: fix _omap2_clksel_get_src_field() _omap2_clksel_get_src_field() was returning the first entry which was either the default _or_ applicable to the SoC. This is wrong - we should be returning the first default which is applicable to the SoC. Signed-off-by: Russell King --- arch/arm/mach-omap2/clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 2899cba2aaa..e64549e4e32 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -708,7 +708,7 @@ static u32 omap2_clksel_get_src_field(void __iomem **src_addr, return 0; for (clkr = clks->rates; clkr->div; clkr++) { - if (clkr->flags & (cpu_mask | DEFAULT_RATE)) + if (clkr->flags & cpu_mask && clkr->flags & DEFAULT_RATE) break; /* Found the default rate for this platform */ } -- cgit From d794bf8e0936dce45104565cd48c571061f4c1e3 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Sat, 14 Feb 2009 10:31:16 -0500 Subject: ext4: Initialize preallocation list_head's properly When creating a new ext4_prealloc_space structure, we have to initialize its list_head pointers before we add them to any prealloc lists. Otherwise, with list debug enabled, we will get list corruption warnings. Signed-off-by: Aneesh Kumar K.V Signed-off-by: "Theodore Ts'o" --- fs/ext4/mballoc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index c962d069050..4415beeb0b6 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -3693,6 +3693,8 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac) pa->pa_free = pa->pa_len; atomic_set(&pa->pa_count, 1); spin_lock_init(&pa->pa_lock); + INIT_LIST_HEAD(&pa->pa_inode_list); + INIT_LIST_HEAD(&pa->pa_group_list); pa->pa_deleted = 0; pa->pa_linear = 0; @@ -3755,6 +3757,7 @@ ext4_mb_new_group_pa(struct ext4_allocation_context *ac) atomic_set(&pa->pa_count, 1); spin_lock_init(&pa->pa_lock); INIT_LIST_HEAD(&pa->pa_inode_list); + INIT_LIST_HEAD(&pa->pa_group_list); pa->pa_deleted = 0; pa->pa_linear = 1; -- cgit From 2acf2c261b823d9d9ed954f348b97620297a36b5 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Sat, 14 Feb 2009 10:42:58 -0500 Subject: ext4: Implement range_cyclic in ext4_da_writepages instead of write_cache_pages With delayed allocation we lock the page in write_cache_pages() and try to build an in memory extent of contiguous blocks. This is needed so that we can get large contiguous blocks request. If range_cyclic mode is enabled, write_cache_pages() will loop back to the 0 index if no I/O has been done yet, and try to start writing from the beginning of the range. That causes an attempt to take the page lock of lower index page while holding the page lock of higher index page, which can cause a dead lock with another writeback thread. The solution is to implement the range_cyclic behavior in ext4_da_writepages() instead. http://bugzilla.kernel.org/show_bug.cgi?id=12579 Signed-off-by: Aneesh Kumar K.V Signed-off-by: "Theodore Ts'o" --- fs/ext4/inode.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 658c4a7f257..cbd2ca99d11 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2439,6 +2439,7 @@ static int ext4_da_writepages(struct address_space *mapping, int no_nrwrite_index_update; int pages_written = 0; long pages_skipped; + int range_cyclic, cycled = 1, io_done = 0; int needed_blocks, ret = 0, nr_to_writebump = 0; struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb); @@ -2490,9 +2491,15 @@ static int ext4_da_writepages(struct address_space *mapping, if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) range_whole = 1; - if (wbc->range_cyclic) + range_cyclic = wbc->range_cyclic; + if (wbc->range_cyclic) { index = mapping->writeback_index; - else + if (index) + cycled = 0; + wbc->range_start = index << PAGE_CACHE_SHIFT; + wbc->range_end = LLONG_MAX; + wbc->range_cyclic = 0; + } else index = wbc->range_start >> PAGE_CACHE_SHIFT; mpd.wbc = wbc; @@ -2506,6 +2513,7 @@ static int ext4_da_writepages(struct address_space *mapping, wbc->no_nrwrite_index_update = 1; pages_skipped = wbc->pages_skipped; +retry: while (!ret && wbc->nr_to_write > 0) { /* @@ -2548,6 +2556,7 @@ static int ext4_da_writepages(struct address_space *mapping, pages_written += mpd.pages_written; wbc->pages_skipped = pages_skipped; ret = 0; + io_done = 1; } else if (wbc->nr_to_write) /* * There is no more writeout needed @@ -2556,6 +2565,13 @@ static int ext4_da_writepages(struct address_space *mapping, */ break; } + if (!io_done && !cycled) { + cycled = 1; + index = 0; + wbc->range_start = index << PAGE_CACHE_SHIFT; + wbc->range_end = mapping->writeback_index - 1; + goto retry; + } if (pages_skipped != wbc->pages_skipped) printk(KERN_EMERG "This should not happen leaving %s " "with nr_to_write = %ld ret = %d\n", @@ -2563,6 +2579,7 @@ static int ext4_da_writepages(struct address_space *mapping, /* Update index */ index += pages_written; + wbc->range_cyclic = range_cyclic; if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) /* * set the writeback_index so that range_cyclic -- cgit From 98ad6e3b1f5f2303815c063ece91291a597f6044 Mon Sep 17 00:00:00 2001 From: wanzongshun Date: Fri, 13 Feb 2009 06:04:32 +0100 Subject: [ARM] 5398/1: Add Wan ZongShun to MAINTAINERS for W90P910 Add Wan ZongShun to MAINTAINERS for W90P910. Signed-off-by: Wan ZongShun Signed-off-by: Russell King --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index db65b4e6d13..2a91b10a8a2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -692,6 +692,13 @@ M: kernel@wantstofly.org L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) S: Maintained +ARM/NUVOTON W90X900 ARM ARCHITECTURE +P: Wan ZongShun +M: mcuos.com@gmail.com +L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) +W: http://www.mcuos.com +S: Maintained + ARPD SUPPORT P: Jonathan Layes L: netdev@vger.kernel.org -- cgit From 2af29b78618ac8b3a8746337002f108f8fdf56ad Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Wed, 11 Feb 2009 21:23:10 +0100 Subject: [ARM] 5390/1: AT91: Watchdog fixes The recently merged AT91SAM9 watchdog driver uses the AT91SAM9X_WATCHDOG config variable, whereas the original version of the driver (and the platform support code) used AT91SAM9_WATCHDOG. This causes the watchdog platform_device to never be registered, and therefore the driver not to be initialized. This patch: - updates the platform support code to use AT91SAM9X_WATCHDOG. - includes to fix compile error (same fix as was applied to at91rm9200_wdt.c) - fixes comment regarding watchdog clock-rates in at91rm9200. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/configs/at91sam9260ek_defconfig | 2 +- arch/arm/configs/at91sam9261ek_defconfig | 2 +- arch/arm/configs/at91sam9263ek_defconfig | 2 +- arch/arm/configs/at91sam9rlek_defconfig | 2 +- arch/arm/configs/qil-a9260_defconfig | 2 +- arch/arm/mach-at91/at91cap9_devices.c | 2 +- arch/arm/mach-at91/at91sam9260_devices.c | 2 +- arch/arm/mach-at91/at91sam9261_devices.c | 2 +- arch/arm/mach-at91/at91sam9263_devices.c | 2 +- arch/arm/mach-at91/at91sam9rl_devices.c | 2 +- drivers/watchdog/at91rm9200_wdt.c | 4 ++-- drivers/watchdog/at91sam9_wdt.c | 1 + 12 files changed, 13 insertions(+), 12 deletions(-) diff --git a/arch/arm/configs/at91sam9260ek_defconfig b/arch/arm/configs/at91sam9260ek_defconfig index e0ee7060f9a..98e2f3de4bc 100644 --- a/arch/arm/configs/at91sam9260ek_defconfig +++ b/arch/arm/configs/at91sam9260ek_defconfig @@ -608,7 +608,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set -CONFIG_AT91SAM9_WATCHDOG=y +CONFIG_AT91SAM9X_WATCHDOG=y # # USB-based Watchdog Cards diff --git a/arch/arm/configs/at91sam9261ek_defconfig b/arch/arm/configs/at91sam9261ek_defconfig index 01d1ef97d8b..14945614239 100644 --- a/arch/arm/configs/at91sam9261ek_defconfig +++ b/arch/arm/configs/at91sam9261ek_defconfig @@ -700,7 +700,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set -CONFIG_AT91SAM9_WATCHDOG=y +CONFIG_AT91SAM9X_WATCHDOG=y # # USB-based Watchdog Cards diff --git a/arch/arm/configs/at91sam9263ek_defconfig b/arch/arm/configs/at91sam9263ek_defconfig index 036a126725c..21599f3c627 100644 --- a/arch/arm/configs/at91sam9263ek_defconfig +++ b/arch/arm/configs/at91sam9263ek_defconfig @@ -710,7 +710,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set -CONFIG_AT91SAM9_WATCHDOG=y +CONFIG_AT91SAM9X_WATCHDOG=y # # USB-based Watchdog Cards diff --git a/arch/arm/configs/at91sam9rlek_defconfig b/arch/arm/configs/at91sam9rlek_defconfig index 237a2a6a851..e2df81a3e80 100644 --- a/arch/arm/configs/at91sam9rlek_defconfig +++ b/arch/arm/configs/at91sam9rlek_defconfig @@ -606,7 +606,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set -CONFIG_AT91SAM9_WATCHDOG=y +CONFIG_AT91SAM9X_WATCHDOG=y # # Sonics Silicon Backplane diff --git a/arch/arm/configs/qil-a9260_defconfig b/arch/arm/configs/qil-a9260_defconfig index cd1d717903a..9b32d0eb89b 100644 --- a/arch/arm/configs/qil-a9260_defconfig +++ b/arch/arm/configs/qil-a9260_defconfig @@ -727,7 +727,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set -# CONFIG_AT91SAM9_WATCHDOG is not set +# CONFIG_AT91SAM9X_WATCHDOG is not set # # USB-based Watchdog Cards diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c index 9eca2209cde..412aa49ad2f 100644 --- a/arch/arm/mach-at91/at91cap9_devices.c +++ b/arch/arm/mach-at91/at91cap9_devices.c @@ -697,7 +697,7 @@ static void __init at91_add_device_rtt(void) * Watchdog * -------------------------------------------------------------------- */ -#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE) +#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) static struct platform_device at91cap9_wdt_device = { .name = "at91_wdt", .id = -1, diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index fdde1ea21b0..d74c9ac007e 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -643,7 +643,7 @@ static void __init at91_add_device_rtt(void) * Watchdog * -------------------------------------------------------------------- */ -#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE) +#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) static struct platform_device at91sam9260_wdt_device = { .name = "at91_wdt", .id = -1, diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index 17289756f80..59fc48311fb 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -621,7 +621,7 @@ static void __init at91_add_device_rtt(void) * Watchdog * -------------------------------------------------------------------- */ -#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE) +#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) static struct platform_device at91sam9261_wdt_device = { .name = "at91_wdt", .id = -1, diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index b753cb879d8..134af97ff34 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -854,7 +854,7 @@ static void __init at91_add_device_rtt(void) * Watchdog * -------------------------------------------------------------------- */ -#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE) +#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) static struct platform_device at91sam9263_wdt_device = { .name = "at91_wdt", .id = -1, diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index 145324f4ec5..728186515cd 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -609,7 +609,7 @@ static void __init at91_add_device_rtt(void) * Watchdog * -------------------------------------------------------------------- */ -#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE) +#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) static struct platform_device at91sam9rl_wdt_device = { .name = "at91_wdt", .id = -1, diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c index 5531691f46e..e35d5458923 100644 --- a/drivers/watchdog/at91rm9200_wdt.c +++ b/drivers/watchdog/at91rm9200_wdt.c @@ -107,10 +107,10 @@ static int at91_wdt_close(struct inode *inode, struct file *file) static int at91_wdt_settimeout(int new_time) { /* - * All counting occurs at SLOW_CLOCK / 128 = 0.256 Hz + * All counting occurs at SLOW_CLOCK / 128 = 256 Hz * * Since WDV is a 16-bit counter, the maximum period is - * 65536 / 0.256 = 256 seconds. + * 65536 / 256 = 256 seconds. */ if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) return -EINVAL; diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c index b1da287f90e..a56ac84381b 100644 --- a/drivers/watchdog/at91sam9_wdt.c +++ b/drivers/watchdog/at91sam9_wdt.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include -- cgit From 2b768b6cdbcf7fa0761e6c35c6ea288297582c43 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Wed, 11 Feb 2009 21:39:05 +0100 Subject: [ARM] 5391/1: AT91: Enable GPIO clocks earlier Enable the GPIO clocks earlier in the initialization sequence. This allow the board-setup code to read and set GPIO pins. Signed-off-by: Marc Pignat Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91/gpio.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index 9b0447c3d59..2f7d4977dce 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -490,7 +490,8 @@ postcore_initcall(at91_gpio_debugfs_init); /*--------------------------------------------------------------------------*/ -/* This lock class tells lockdep that GPIO irqs are in a different +/* + * This lock class tells lockdep that GPIO irqs are in a different * category than their parents, so it won't report false recursion. */ static struct lock_class_key gpio_lock_class; @@ -509,9 +510,6 @@ void __init at91_gpio_irq_setup(void) unsigned id = this->id; unsigned i; - /* enable PIO controller's clock */ - clk_enable(this->clock); - __raw_writel(~0, this->regbase + PIO_IDR); for (i = 0, pin = this->chipbase; i < 32; i++, pin++) { @@ -556,7 +554,14 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) data->chipbase = PIN_BASE + i * 32; data->regbase = data->offset + (void __iomem *)AT91_VA_BASE_SYS; - /* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */ + /* enable PIO controller's clock */ + clk_enable(data->clock); + + /* + * Some processors share peripheral ID between multiple GPIO banks. + * SAM9263 (PIOC, PIOD, PIOE) + * CAP9 (PIOA, PIOB, PIOC, PIOD) + */ if (last && last->id == data->id) last->next = data; } -- cgit From 9af88143b277f52fc6ce0d69137f435c73c39c1a Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 13 Feb 2009 23:18:03 +0000 Subject: iommu: fix Intel IOMMU write-buffer flushing This is the cause of the DMA faults and disk corruption that people have been seeing. Some chipsets neglect to report the RWBF "capability" -- the flag which says that we need to flush the chipset write-buffer when changing the DMA page tables, to ensure that the change is visible to the IOMMU. Override that bit on the affected chipsets, and everything is happy again. Thanks to Chris and Bhavesh and others for helping to debug. Should resolve: https://bugzilla.redhat.com/show_bug.cgi?id=479996 http://bugzilla.kernel.org/show_bug.cgi?id=12578 Signed-off-by: David Woodhouse Cc: Linus Torvalds Tested-and-acked-by: Chris Wright Reviewed-by: Bhavesh Davda Signed-off-by: Ingo Molnar --- drivers/pci/intel-iommu.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index f4b7c79023f..f3f686581a9 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -61,6 +61,8 @@ /* global iommu list, set NULL for ignored DMAR units */ static struct intel_iommu **g_iommus; +static int rwbf_quirk; + /* * 0: Present * 1-11: Reserved @@ -785,7 +787,7 @@ static void iommu_flush_write_buffer(struct intel_iommu *iommu) u32 val; unsigned long flag; - if (!cap_rwbf(iommu->cap)) + if (!rwbf_quirk && !cap_rwbf(iommu->cap)) return; val = iommu->gcmd | DMA_GCMD_WBF; @@ -3137,3 +3139,15 @@ static struct iommu_ops intel_iommu_ops = { .unmap = intel_iommu_unmap_range, .iova_to_phys = intel_iommu_iova_to_phys, }; + +static void __devinit quirk_iommu_rwbf(struct pci_dev *dev) +{ + /* + * Mobile 4 Series Chipset neglects to set RWBF capability, + * but needs it: + */ + printk(KERN_INFO "DMAR: Forcing write-buffer flush capability\n"); + rwbf_quirk = 1; +} + +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf); -- cgit From e49590b6dd356f8ef10ba3531a29e5086f6f2e3a Mon Sep 17 00:00:00 2001 From: Chris Ball Date: Fri, 13 Feb 2009 20:56:18 -0500 Subject: x86, olpc: fix model detection without OFW Impact: fix "garbled display, laptop is unusable" bug Commit e51a1ac2dfca9ad869471e88f828281db7e810c0 ("x86, olpc: fix endian bug in openfirmware workaround") breaks model comparison on OLPC; the value 0xc2 needs to be scaled up by olpc_board(). The pre-patch version was wrong, but accidentally worked anyway (big-endian 0xc2 is big enough to satisfy all other board revisions, but little endian 0xc2 is not). Signed-off-by: Chris Ball Cc: Andrew Morton Acked-by: Andres Salomon Cc: Harvey Harrison Signed-off-by: Ingo Molnar --- arch/x86/kernel/olpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/olpc.c b/arch/x86/kernel/olpc.c index 7a13fac63a1..4006c522adc 100644 --- a/arch/x86/kernel/olpc.c +++ b/arch/x86/kernel/olpc.c @@ -203,7 +203,7 @@ static void __init platform_detect(void) static void __init platform_detect(void) { /* stopgap until OFW support is added to the kernel */ - olpc_platform_info.boardrev = 0xc2; + olpc_platform_info.boardrev = olpc_board(0xc2); } #endif -- cgit From d39123a486524fed9b4e43e08a8757fd90a5859a Mon Sep 17 00:00:00 2001 From: Yang Zhang Date: Thu, 8 Jan 2009 15:13:31 +0800 Subject: KVM: ia64: fix fp fault/trap handler The floating-point registers f6-f11 is used by vmm and saved in kvm-pt-regs, so should set the correct bit mask and the pointer in fp_state, otherwise, fpswa may touch vmm's fp registers instead of guests'. In addition, for fp trap handling, since the instruction which leads to fp trap is completely executed, so can't use retry machanism to re-execute it, because it may pollute some registers. Signed-off-by: Yang Zhang Signed-off-by: Avi Kivity --- arch/ia64/kvm/process.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/arch/ia64/kvm/process.c b/arch/ia64/kvm/process.c index 552d0772420..230eae482f3 100644 --- a/arch/ia64/kvm/process.c +++ b/arch/ia64/kvm/process.c @@ -455,13 +455,18 @@ fpswa_ret_t vmm_fp_emulate(int fp_fault, void *bundle, unsigned long *ipsr, if (!vmm_fpswa_interface) return (fpswa_ret_t) {-1, 0, 0, 0}; - /* - * Just let fpswa driver to use hardware fp registers. - * No fp register is valid in memory. - */ memset(&fp_state, 0, sizeof(fp_state_t)); /* + * compute fp_state. only FP registers f6 - f11 are used by the + * vmm, so set those bits in the mask and set the low volatile + * pointer to point to these registers. + */ + fp_state.bitmask_low64 = 0xfc0; /* bit6..bit11 */ + + fp_state.fp_state_low_volatile = (fp_state_low_volatile_t *) ®s->f6; + + /* * unsigned long (*EFI_FPSWA) ( * unsigned long trap_type, * void *Bundle, @@ -545,10 +550,6 @@ void reflect_interruption(u64 ifa, u64 isr, u64 iim, status = vmm_handle_fpu_swa(0, regs, isr); if (!status) return ; - else if (-EAGAIN == status) { - vcpu_decrement_iip(vcpu); - return ; - } break; } -- cgit From 7a0eb1960e8ddcb68ea631caf16815485af0e228 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Mon, 19 Jan 2009 14:57:52 +0200 Subject: KVM: Avoid using CONFIG_ in userspace visible headers Kconfig symbols are not available in userspace, and are not stripped by headers-install. Avoid their use by adding #defines in to suit each architecture. Signed-off-by: Avi Kivity --- arch/ia64/include/asm/kvm.h | 4 ++++ arch/x86/include/asm/kvm.h | 7 +++++++ include/linux/kvm.h | 10 +++++----- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/arch/ia64/include/asm/kvm.h b/arch/ia64/include/asm/kvm.h index 68aa6da807c..bfa86b6af7c 100644 --- a/arch/ia64/include/asm/kvm.h +++ b/arch/ia64/include/asm/kvm.h @@ -25,6 +25,10 @@ #include +/* Select x86 specific features in */ +#define __KVM_HAVE_IOAPIC +#define __KVM_HAVE_DEVICE_ASSIGNMENT + /* Architectural interrupt line count. */ #define KVM_NR_INTERRUPTS 256 diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h index d2e3bf3608a..886c9402ec4 100644 --- a/arch/x86/include/asm/kvm.h +++ b/arch/x86/include/asm/kvm.h @@ -9,6 +9,13 @@ #include #include +/* Select x86 specific features in */ +#define __KVM_HAVE_PIT +#define __KVM_HAVE_IOAPIC +#define __KVM_HAVE_DEVICE_ASSIGNMENT +#define __KVM_HAVE_MSI +#define __KVM_HAVE_USER_NMI + /* Architectural interrupt line count. */ #define KVM_NR_INTERRUPTS 256 diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 5715f190760..0424326f167 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -58,10 +58,10 @@ struct kvm_irqchip { __u32 pad; union { char dummy[512]; /* reserving space */ -#ifdef CONFIG_X86 +#ifdef __KVM_HAVE_PIT struct kvm_pic_state pic; #endif -#if defined(CONFIG_X86) || defined(CONFIG_IA64) +#ifdef __KVM_HAVE_IOAPIC struct kvm_ioapic_state ioapic; #endif } chip; @@ -384,16 +384,16 @@ struct kvm_trace_rec { #define KVM_CAP_MP_STATE 14 #define KVM_CAP_COALESCED_MMIO 15 #define KVM_CAP_SYNC_MMU 16 /* Changes to host mmap are reflected in guest */ -#if defined(CONFIG_X86)||defined(CONFIG_IA64) +#ifdef __KVM_HAVE_DEVICE_ASSIGNMENT #define KVM_CAP_DEVICE_ASSIGNMENT 17 #endif #define KVM_CAP_IOMMU 18 -#if defined(CONFIG_X86) +#ifdef __KVM_HAVE_MSI #define KVM_CAP_DEVICE_MSI 20 #endif /* Bug in KVM_SET_USER_MEMORY_REGION fixed: */ #define KVM_CAP_DESTROY_MEMORY_REGION_WORKS 21 -#if defined(CONFIG_X86) +#ifdef __KVM_HAVE_USER_NMI #define KVM_CAP_USER_NMI 22 #endif -- cgit From 85db06e514422ae429b5f85742d8111b70bd56f3 Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Wed, 10 Dec 2008 21:23:26 +0100 Subject: KVM: mmu_notifiers release method The destructor for huge pages uses the backing inode for adjusting hugetlbfs accounting. Hugepage mappings are destroyed by exit_mmap, after mmu_notifier_release, so there are no notifications through unmap_hugepage_range at this point. The hugetlbfs inode can be freed with pages backed by it referenced by the shadow. When the shadow releases its reference, the huge page destructor will access a now freed inode. Implement the release operation for kvm mmu notifiers to release page refs before the hugetlbfs inode is gone. Signed-off-by: Marcelo Tosatti Signed-off-by: Avi Kivity --- virt/kvm/kvm_main.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 3a5a08298aa..0b6f2f71271 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -789,11 +789,19 @@ static int kvm_mmu_notifier_clear_flush_young(struct mmu_notifier *mn, return young; } +static void kvm_mmu_notifier_release(struct mmu_notifier *mn, + struct mm_struct *mm) +{ + struct kvm *kvm = mmu_notifier_to_kvm(mn); + kvm_arch_flush_shadow(kvm); +} + static const struct mmu_notifier_ops kvm_mmu_notifier_ops = { .invalidate_page = kvm_mmu_notifier_invalidate_page, .invalidate_range_start = kvm_mmu_notifier_invalidate_range_start, .invalidate_range_end = kvm_mmu_notifier_invalidate_range_end, .clear_flush_young = kvm_mmu_notifier_clear_flush_young, + .release = kvm_mmu_notifier_release, }; #endif /* CONFIG_MMU_NOTIFIER && KVM_ARCH_WANT_MMU_NOTIFIER */ -- cgit From ad8ba2cd44d4d39fb3fe55d5dcc565b19fc3a7fb Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Tue, 6 Jan 2009 10:03:02 +0800 Subject: KVM: Add kvm_arch_sync_events to sync with asynchronize events kvm_arch_sync_events is introduced to quiet down all other events may happen contemporary with VM destroy process, like IRQ handler and work struct for assigned device. For kvm_arch_sync_events is called at the very beginning of kvm_destroy_vm(), so the state of KVM here is legal and can provide a environment to quiet down other events. Signed-off-by: Sheng Yang Signed-off-by: Avi Kivity --- arch/ia64/kvm/kvm-ia64.c | 4 ++++ arch/powerpc/kvm/powerpc.c | 4 ++++ arch/s390/kvm/kvm-s390.c | 4 ++++ arch/x86/kvm/x86.c | 4 ++++ include/linux/kvm_host.h | 1 + virt/kvm/kvm_main.c | 1 + 6 files changed, 18 insertions(+) diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 4e586f6110a..28f982045f2 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c @@ -1337,6 +1337,10 @@ static void kvm_release_vm_pages(struct kvm *kvm) } } +void kvm_arch_sync_events(struct kvm *kvm) +{ +} + void kvm_arch_destroy_vm(struct kvm *kvm) { kvm_iommu_unmap_guest(kvm); diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 2822c8ccfaa..5f81256287f 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -125,6 +125,10 @@ static void kvmppc_free_vcpus(struct kvm *kvm) } } +void kvm_arch_sync_events(struct kvm *kvm) +{ +} + void kvm_arch_destroy_vm(struct kvm *kvm) { kvmppc_free_vcpus(kvm); diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index be8497186b9..0d33893e1e8 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -212,6 +212,10 @@ static void kvm_free_vcpus(struct kvm *kvm) } } +void kvm_arch_sync_events(struct kvm *kvm) +{ +} + void kvm_arch_destroy_vm(struct kvm *kvm) { kvm_free_vcpus(kvm); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index cc17546a240..b0fc079f1be 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4127,6 +4127,10 @@ static void kvm_free_vcpus(struct kvm *kvm) } +void kvm_arch_sync_events(struct kvm *kvm) +{ +} + void kvm_arch_destroy_vm(struct kvm *kvm) { kvm_free_all_assigned_devices(kvm); diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index ec49d0be7f5..bf6f703642f 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -285,6 +285,7 @@ void kvm_free_physmem(struct kvm *kvm); struct kvm *kvm_arch_create_vm(void); void kvm_arch_destroy_vm(struct kvm *kvm); void kvm_free_all_assigned_devices(struct kvm *kvm); +void kvm_arch_sync_events(struct kvm *kvm); int kvm_cpu_get_interrupt(struct kvm_vcpu *v); int kvm_cpu_has_interrupt(struct kvm_vcpu *v); diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 0b6f2f71271..68e3f1ec167 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -891,6 +891,7 @@ static void kvm_destroy_vm(struct kvm *kvm) { struct mm_struct *mm = kvm->mm; + kvm_arch_sync_events(kvm); spin_lock(&kvm_lock); list_del(&kvm->vm_list); spin_unlock(&kvm_lock); -- cgit From ba4cef31d5a397b64ba6d3ff713ce06c62f0c597 Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Tue, 6 Jan 2009 10:03:03 +0800 Subject: KVM: Fix racy in kvm_free_assigned_irq In the past, kvm_get_kvm() and kvm_put_kvm() was called in assigned device irq handler and interrupt_work, in order to prevent cancel_work_sync() in kvm_free_assigned_irq got a illegal state when waiting for interrupt_work done. But it's tricky and still got two problems: 1. A bug ignored two conditions that cancel_work_sync() would return true result in a additional kvm_put_kvm(). 2. If interrupt type is MSI, we would got a window between cancel_work_sync() and free_irq(), which interrupt would be injected again... This patch discard the reference count used for irq handler and interrupt_work, and ensure the legal state by moving the free function at the very beginning of kvm_destroy_vm(). And the patch fix the second bug by disable irq before cancel_work_sync(), which may result in nested disable of irq but OK for we are going to free it. Signed-off-by: Sheng Yang Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 2 +- virt/kvm/kvm_main.c | 27 +++++++++++++++++++-------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index b0fc079f1be..fc3e329f6ad 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4129,11 +4129,11 @@ static void kvm_free_vcpus(struct kvm *kvm) void kvm_arch_sync_events(struct kvm *kvm) { + kvm_free_all_assigned_devices(kvm); } void kvm_arch_destroy_vm(struct kvm *kvm) { - kvm_free_all_assigned_devices(kvm); kvm_iommu_unmap_guest(kvm); kvm_free_pit(kvm); kfree(kvm->arch.vpic); diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 68e3f1ec167..277ea7f39fc 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -173,7 +173,6 @@ static void kvm_assigned_dev_interrupt_work_handler(struct work_struct *work) assigned_dev->host_irq_disabled = false; } mutex_unlock(&assigned_dev->kvm->lock); - kvm_put_kvm(assigned_dev->kvm); } static irqreturn_t kvm_assigned_dev_intr(int irq, void *dev_id) @@ -181,8 +180,6 @@ static irqreturn_t kvm_assigned_dev_intr(int irq, void *dev_id) struct kvm_assigned_dev_kernel *assigned_dev = (struct kvm_assigned_dev_kernel *) dev_id; - kvm_get_kvm(assigned_dev->kvm); - schedule_work(&assigned_dev->interrupt_work); disable_irq_nosync(irq); @@ -213,6 +210,7 @@ static void kvm_assigned_dev_ack_irq(struct kvm_irq_ack_notifier *kian) } } +/* The function implicit hold kvm->lock mutex due to cancel_work_sync() */ static void kvm_free_assigned_irq(struct kvm *kvm, struct kvm_assigned_dev_kernel *assigned_dev) { @@ -228,11 +226,24 @@ static void kvm_free_assigned_irq(struct kvm *kvm, if (!assigned_dev->irq_requested_type) return; - if (cancel_work_sync(&assigned_dev->interrupt_work)) - /* We had pending work. That means we will have to take - * care of kvm_put_kvm. - */ - kvm_put_kvm(kvm); + /* + * In kvm_free_device_irq, cancel_work_sync return true if: + * 1. work is scheduled, and then cancelled. + * 2. work callback is executed. + * + * The first one ensured that the irq is disabled and no more events + * would happen. But for the second one, the irq may be enabled (e.g. + * for MSI). So we disable irq here to prevent further events. + * + * Notice this maybe result in nested disable if the interrupt type is + * INTx, but it's OK for we are going to free it. + * + * If this function is a part of VM destroy, please ensure that till + * now, the kvm state is still legal for probably we also have to wait + * interrupt_work done. + */ + disable_irq_nosync(assigned_dev->host_irq); + cancel_work_sync(&assigned_dev->interrupt_work); free_irq(assigned_dev->host_irq, (void *)assigned_dev); -- cgit From d2a8284e8fca9e2a938bee6cd074064d23864886 Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Tue, 30 Dec 2008 15:55:05 -0200 Subject: KVM: PIT: fix i8254 pending count read count_load_time assignment is bogus: its supposed to contain what it means, not the expiration time. Signed-off-by: Marcelo Tosatti Signed-off-by: Avi Kivity --- arch/x86/kvm/i8254.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index e665d1c623c..72bd275a9b5 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c @@ -207,7 +207,7 @@ static int __pit_timer_fn(struct kvm_kpit_state *ps) hrtimer_add_expires_ns(&pt->timer, pt->period); pt->scheduled = hrtimer_get_expires_ns(&pt->timer); if (pt->period) - ps->channels[0].count_load_time = hrtimer_get_expires(&pt->timer); + ps->channels[0].count_load_time = ktime_get(); return (pt->period == 0 ? 0 : 1); } -- cgit From abe6655dd699069b53bcccbc65b2717f60203b12 Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Tue, 10 Feb 2009 20:59:45 -0200 Subject: KVM: x86: disable kvmclock on non constant TSC hosts This is better. Currently, this code path is posing us big troubles, and we won't have a decent patch in time. So, temporarily disable it. Signed-off-by: Glauber Costa Signed-off-by: Marcelo Tosatti Signed-off-by: Avi Kivity --- arch/x86/kvm/x86.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index fc3e329f6ad..758b7a155ae 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -967,7 +967,6 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_MMU_SHADOW_CACHE_CONTROL: case KVM_CAP_SET_TSS_ADDR: case KVM_CAP_EXT_CPUID: - case KVM_CAP_CLOCKSOURCE: case KVM_CAP_PIT: case KVM_CAP_NOP_IO_DELAY: case KVM_CAP_MP_STATE: @@ -992,6 +991,9 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_IOMMU: r = iommu_found(); break; + case KVM_CAP_CLOCKSOURCE: + r = boot_cpu_has(X86_FEATURE_CONSTANT_TSC); + break; default: r = 0; break; -- cgit From 2aaf69dcee864f4fb6402638dd2f263324ac839f Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Wed, 21 Jan 2009 16:52:16 +0800 Subject: KVM: MMU: Map device MMIO as UC in EPT Software are not allow to access device MMIO using cacheable memory type, the patch limit MMIO region with UC and WC(guest can select WC using PAT and PCD/PWT). Signed-off-by: Sheng Yang Signed-off-by: Avi Kivity --- arch/x86/kvm/mmu.c | 9 +++++++-- arch/x86/kvm/vmx.c | 3 +-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 83f11c7474a..2d4477c7147 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -1698,8 +1698,13 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, if (largepage) spte |= PT_PAGE_SIZE_MASK; if (mt_mask) { - mt_mask = get_memory_type(vcpu, gfn) << - kvm_x86_ops->get_mt_mask_shift(); + if (!kvm_is_mmio_pfn(pfn)) { + mt_mask = get_memory_type(vcpu, gfn) << + kvm_x86_ops->get_mt_mask_shift(); + mt_mask |= VMX_EPT_IGMT_BIT; + } else + mt_mask = MTRR_TYPE_UNCACHABLE << + kvm_x86_ops->get_mt_mask_shift(); spte |= mt_mask; } diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 6259d746764..07491c9c6ed 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -3687,8 +3687,7 @@ static int __init vmx_init(void) if (vm_need_ept()) { bypass_guest_pf = 0; kvm_mmu_set_base_ptes(VMX_EPT_READABLE_MASK | - VMX_EPT_WRITABLE_MASK | - VMX_EPT_IGMT_BIT); + VMX_EPT_WRITABLE_MASK); kvm_mmu_set_mask_ptes(0ull, 0ull, 0ull, 0ull, VMX_EPT_EXECUTABLE_MASK, VMX_EPT_DEFAULT_MT << VMX_EPT_MT_EPTE_SHIFT); -- cgit From d7cff1c37664971aae32bb0de82231ed34933d8e Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Tue, 6 Jan 2009 16:25:10 +0800 Subject: KVM: Fix INTx for device assignment Missing buckets and wrong parameter for free_irq() Signed-off-by: Sheng Yang Signed-off-by: Avi Kivity --- virt/kvm/kvm_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 277ea7f39fc..d9bbb20f230 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -296,8 +296,8 @@ static int assigned_device_update_intx(struct kvm *kvm, if (irqchip_in_kernel(kvm)) { if (!msi2intx && - adev->irq_requested_type & KVM_ASSIGNED_DEV_HOST_MSI) { - free_irq(adev->host_irq, (void *)kvm); + (adev->irq_requested_type & KVM_ASSIGNED_DEV_HOST_MSI)) { + free_irq(adev->host_irq, (void *)adev); pci_disable_msi(adev->dev); } -- cgit From b682b814e3cc340f905c14dff87ce8bdba7c5eba Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Tue, 10 Feb 2009 20:41:41 -0200 Subject: KVM: x86: fix LAPIC pending count calculation Simplify LAPIC TMCCT calculation by using hrtimer provided function to query remaining time until expiration. Fixes host hang with nested ESX. Signed-off-by: Marcelo Tosatti Signed-off-by: Alexander Graf Signed-off-by: Avi Kivity --- arch/x86/kvm/irq.c | 7 ------ arch/x86/kvm/irq.h | 1 - arch/x86/kvm/lapic.c | 66 ++++++++++++---------------------------------------- arch/x86/kvm/lapic.h | 2 -- arch/x86/kvm/svm.c | 1 - arch/x86/kvm/vmx.c | 1 - 6 files changed, 15 insertions(+), 63 deletions(-) diff --git a/arch/x86/kvm/irq.c b/arch/x86/kvm/irq.c index c019b8edcdb..cf17ed52f6f 100644 --- a/arch/x86/kvm/irq.c +++ b/arch/x86/kvm/irq.c @@ -87,13 +87,6 @@ void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu) } EXPORT_SYMBOL_GPL(kvm_inject_pending_timer_irqs); -void kvm_timer_intr_post(struct kvm_vcpu *vcpu, int vec) -{ - kvm_apic_timer_intr_post(vcpu, vec); - /* TODO: PIT, RTC etc. */ -} -EXPORT_SYMBOL_GPL(kvm_timer_intr_post); - void __kvm_migrate_timers(struct kvm_vcpu *vcpu) { __kvm_migrate_apic_timer(vcpu); diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h index 2bf32a03cee..82579ee538d 100644 --- a/arch/x86/kvm/irq.h +++ b/arch/x86/kvm/irq.h @@ -89,7 +89,6 @@ static inline int irqchip_in_kernel(struct kvm *kvm) void kvm_pic_reset(struct kvm_kpic_state *s); -void kvm_timer_intr_post(struct kvm_vcpu *vcpu, int vec); void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu); void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu); void kvm_apic_nmi_wd_deliver(struct kvm_vcpu *vcpu); diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index afac68c0815..f0b67f2cdd6 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -35,6 +35,12 @@ #include "kvm_cache_regs.h" #include "irq.h" +#ifndef CONFIG_X86_64 +#define mod_64(x, y) ((x) - (y) * div64_u64(x, y)) +#else +#define mod_64(x, y) ((x) % (y)) +#endif + #define PRId64 "d" #define PRIx64 "llx" #define PRIu64 "u" @@ -511,52 +517,22 @@ static void apic_send_ipi(struct kvm_lapic *apic) static u32 apic_get_tmcct(struct kvm_lapic *apic) { - u64 counter_passed; - ktime_t passed, now; + ktime_t remaining; + s64 ns; u32 tmcct; ASSERT(apic != NULL); - now = apic->timer.dev.base->get_time(); - tmcct = apic_get_reg(apic, APIC_TMICT); - /* if initial count is 0, current count should also be 0 */ - if (tmcct == 0) + if (apic_get_reg(apic, APIC_TMICT) == 0) return 0; - if (unlikely(ktime_to_ns(now) <= - ktime_to_ns(apic->timer.last_update))) { - /* Wrap around */ - passed = ktime_add(( { - (ktime_t) { - .tv64 = KTIME_MAX - - (apic->timer.last_update).tv64}; } - ), now); - apic_debug("time elapsed\n"); - } else - passed = ktime_sub(now, apic->timer.last_update); - - counter_passed = div64_u64(ktime_to_ns(passed), - (APIC_BUS_CYCLE_NS * apic->timer.divide_count)); - - if (counter_passed > tmcct) { - if (unlikely(!apic_lvtt_period(apic))) { - /* one-shot timers stick at 0 until reset */ - tmcct = 0; - } else { - /* - * periodic timers reset to APIC_TMICT when they - * hit 0. The while loop simulates this happening N - * times. (counter_passed %= tmcct) would also work, - * but might be slower or not work on 32-bit?? - */ - while (counter_passed > tmcct) - counter_passed -= tmcct; - tmcct -= counter_passed; - } - } else { - tmcct -= counter_passed; - } + remaining = hrtimer_expires_remaining(&apic->timer.dev); + if (ktime_to_ns(remaining) < 0) + remaining = ktime_set(0, 0); + + ns = mod_64(ktime_to_ns(remaining), apic->timer.period); + tmcct = div64_u64(ns, (APIC_BUS_CYCLE_NS * apic->timer.divide_count)); return tmcct; } @@ -653,8 +629,6 @@ static void start_apic_timer(struct kvm_lapic *apic) { ktime_t now = apic->timer.dev.base->get_time(); - apic->timer.last_update = now; - apic->timer.period = apic_get_reg(apic, APIC_TMICT) * APIC_BUS_CYCLE_NS * apic->timer.divide_count; atomic_set(&apic->timer.pending, 0); @@ -1110,16 +1084,6 @@ void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu) } } -void kvm_apic_timer_intr_post(struct kvm_vcpu *vcpu, int vec) -{ - struct kvm_lapic *apic = vcpu->arch.apic; - - if (apic && apic_lvt_vector(apic, APIC_LVTT) == vec) - apic->timer.last_update = ktime_add_ns( - apic->timer.last_update, - apic->timer.period); -} - int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu) { int vector = kvm_apic_has_interrupt(vcpu); diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index 81858881287..45ab6ee7120 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h @@ -12,7 +12,6 @@ struct kvm_lapic { atomic_t pending; s64 period; /* unit: ns */ u32 divide_count; - ktime_t last_update; struct hrtimer dev; } timer; struct kvm_vcpu *vcpu; @@ -42,7 +41,6 @@ void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data); void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu); int kvm_lapic_enabled(struct kvm_vcpu *vcpu); int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu); -void kvm_apic_timer_intr_post(struct kvm_vcpu *vcpu, int vec); void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr); void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu); diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 1452851ae25..a9e769e4e25 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1600,7 +1600,6 @@ static void svm_intr_assist(struct kvm_vcpu *vcpu) /* Okay, we can deliver the interrupt: grab it and update PIC state. */ intr_vector = kvm_cpu_get_interrupt(vcpu); svm_inject_irq(svm, intr_vector); - kvm_timer_intr_post(vcpu, intr_vector); out: update_cr8_intercept(vcpu); } diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 07491c9c6ed..b1fe1422afb 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -3285,7 +3285,6 @@ static void vmx_intr_assist(struct kvm_vcpu *vcpu) } if (vcpu->arch.interrupt.pending) { vmx_inject_irq(vcpu, vcpu->arch.interrupt.nr); - kvm_timer_intr_post(vcpu, vcpu->arch.interrupt.nr); if (kvm_cpu_has_interrupt(vcpu)) enable_irq_window(vcpu); } -- cgit From 682edb4c01e690c7c7cd772dbd6f4e0fd74dc572 Mon Sep 17 00:00:00 2001 From: Mark McLoughlin Date: Thu, 5 Feb 2009 18:23:46 +0000 Subject: KVM: Fix assigned devices circular locking dependency kvm->slots_lock is outer to kvm->lock, so take slots_lock in kvm_vm_ioctl_assign_device() before taking kvm->lock, rather than taking it in kvm_iommu_map_memslots(). Cc: stable@kernel.org Signed-off-by: Mark McLoughlin Acked-by: Marcelo Tosatti Signed-off-by: Avi Kivity --- virt/kvm/iommu.c | 6 ++---- virt/kvm/kvm_main.c | 3 +++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c index e9693a29d00..4c403750360 100644 --- a/virt/kvm/iommu.c +++ b/virt/kvm/iommu.c @@ -73,14 +73,13 @@ static int kvm_iommu_map_memslots(struct kvm *kvm) { int i, r = 0; - down_read(&kvm->slots_lock); for (i = 0; i < kvm->nmemslots; i++) { r = kvm_iommu_map_pages(kvm, kvm->memslots[i].base_gfn, kvm->memslots[i].npages); if (r) break; } - up_read(&kvm->slots_lock); + return r; } @@ -190,12 +189,11 @@ static void kvm_iommu_put_pages(struct kvm *kvm, static int kvm_iommu_unmap_memslots(struct kvm *kvm) { int i; - down_read(&kvm->slots_lock); + for (i = 0; i < kvm->nmemslots; i++) { kvm_iommu_put_pages(kvm, kvm->memslots[i].base_gfn, kvm->memslots[i].npages); } - up_read(&kvm->slots_lock); return 0; } diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index d9bbb20f230..29a667ce35b 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -466,6 +466,7 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, struct kvm_assigned_dev_kernel *match; struct pci_dev *dev; + down_read(&kvm->slots_lock); mutex_lock(&kvm->lock); match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head, @@ -527,6 +528,7 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, out: mutex_unlock(&kvm->lock); + up_read(&kvm->slots_lock); return r; out_list_del: list_del(&match->list); @@ -538,6 +540,7 @@ out_put: out_free: kfree(match); mutex_unlock(&kvm->lock); + up_read(&kvm->slots_lock); return r; } #endif -- cgit From 516a1a7e9dc80358030fe01aabb3bedf882db9e2 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 15 Feb 2009 02:32:07 +0200 Subject: KVM: VMX: Flush volatile msrs before emulating rdmsr Some msrs (notable MSR_KERNEL_GS_BASE) are held in the processor registers and need to be flushed to the vcpu struture before they can be read. This fixes cygwin longjmp() failure on Windows x64. Signed-off-by: Avi Kivity --- arch/x86/kvm/vmx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index b1fe1422afb..7611af57682 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -903,6 +903,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) data = vmcs_readl(GUEST_SYSENTER_ESP); break; default: + vmx_load_host_state(to_vmx(vcpu)); msr = find_msr_entry(to_vmx(vcpu), msr_index); if (msr) { data = msr->data; -- cgit From f6db44df5bd39ed33883786d35342759af796e4a Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sat, 14 Feb 2009 23:59:18 -0800 Subject: x86: fix typo in filter_cpuid_features() Impact: fix wrong disabling of cpu features an amd system got this strange output: CPU: CPU feature monitor disabled due to lack of CPUID level 0x5 but in /proc/cpuinfo I have: cpuid level : 5 on intel system: CPU: CPU feature monitor disabled due to lack of CPUID level 0x5 CPU: CPU feature dca disabled due to lack of CPUID level 0x9 but in /proc/cpuinfo i have: cpuid level : 11 Tt turns out there is a typo, and we should use level member in df. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/common.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 21f086b4c1a..32093d08d87 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -241,9 +241,9 @@ static void __cpuinit filter_cpuid_features(struct cpuinfo_x86 *c, bool warn) * signs here... */ if (cpu_has(c, df->feature) && - ((s32)df->feature < 0 ? - (u32)df->feature > (u32)c->extended_cpuid_level : - (s32)df->feature > (s32)c->cpuid_level)) { + ((s32)df->level < 0 ? + (u32)df->level > (u32)c->extended_cpuid_level : + (s32)df->level > (s32)c->cpuid_level)) { clear_cpu_cap(c, df->feature); if (warn) printk(KERN_WARNING @@ -253,7 +253,7 @@ static void __cpuinit filter_cpuid_features(struct cpuinfo_x86 *c, bool warn) df->level); } } -} +} /* * Naming convention should be: [()] -- cgit From be716615fe596ee117292dc615e95f707fb67fd1 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 13 Jan 2009 23:36:34 +0100 Subject: x86, vm86: fix preemption bug Commit 3d2a71a596bd9c761c8487a2178e95f8a61da083 ("x86, traps: converge do_debug handlers") changed the preemption disable logic of do_debug() so vm86_handle_trap() is called with preemption disabled resulting in: BUG: sleeping function called from invalid context at include/linux/kernel.h:155 in_atomic(): 1, irqs_disabled(): 0, pid: 3005, name: dosemu.bin Pid: 3005, comm: dosemu.bin Tainted: G W 2.6.29-rc1 #51 Call Trace: [] copy_to_user+0x33/0x108 [] save_v86_state+0x65/0x149 [] handle_vm86_trap+0x20/0x8f [] do_debug+0x15b/0x1a4 [] debug_stack_correct+0x27/0x2c [] sysenter_do_call+0x12/0x2f BUG: scheduling while atomic: dosemu.bin/3005/0x10000001 Restore the original calling convention and reenable preemption before calling handle_vm86_trap(). Reported-by: Michal Suchanek Cc: stable@kernel.org Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- arch/x86/kernel/traps.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 7932338d7cb..a9e7548e179 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -99,6 +99,12 @@ static inline void preempt_conditional_sti(struct pt_regs *regs) local_irq_enable(); } +static inline void conditional_cli(struct pt_regs *regs) +{ + if (regs->flags & X86_EFLAGS_IF) + local_irq_disable(); +} + static inline void preempt_conditional_cli(struct pt_regs *regs) { if (regs->flags & X86_EFLAGS_IF) @@ -626,8 +632,10 @@ clear_dr7: #ifdef CONFIG_X86_32 debug_vm86: + /* reenable preemption: handle_vm86_trap() might sleep */ + dec_preempt_count(); handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1); - preempt_conditional_cli(regs); + conditional_cli(regs); return; #endif -- cgit From d21d52d4a155e36d4dc93d642cd52cb63f7ef91b Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 5 Feb 2009 16:13:32 +0800 Subject: kbuild,setlocalversion: shorten the make time when using svn Don't bother doing `svn st` as it takes a retarded amount of time when the source is cold Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu Signed-off-by: Sam Ravnborg --- scripts/setlocalversion | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/scripts/setlocalversion b/scripts/setlocalversion index f6946cf99ce..f1c4b35bc32 100755 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion @@ -58,14 +58,7 @@ fi # Check for svn and a svn repo. if rev=`svn info 2>/dev/null | grep '^Last Changed Rev'`; then rev=`echo $rev | awk '{print $NF}'` - changes=`svn status 2>/dev/null | grep '^[AMD]' | wc -l` - - # Are there uncommitted changes? - if [ $changes != 0 ]; then - printf -- '-svn%s%s' "$rev" -dirty - else - printf -- '-svn%s' "$rev" - fi + printf -- '-svn%s' "$rev" # All done with svn exit -- cgit From fc370ecfdb37b853bd8e2118c7ad9f99fa9ac5cd Mon Sep 17 00:00:00 2001 From: Josh Hunt Date: Wed, 11 Feb 2009 21:10:57 -0800 Subject: kbuild: add vmlinux to kernel rpm We are building an automated system to test kernels weekly and need to provide an rpm to our QA dept. We would like to use the ability to create kernel rpms already in the kernel's Makefile, but need the vmlinux file included in the rpm for later debugging. This patch adds a compressed vmlinux to the kernel rpm when doing a make rpm-pkg or binrpm-pkg and upon install places the vmlinux file in /boot. Signed-off-by: Josh Hunt Signed-off-by: Sam Ravnborg --- scripts/package/mkspec | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/scripts/package/mkspec b/scripts/package/mkspec index 2500886fb90..ee448cdc6a2 100755 --- a/scripts/package/mkspec +++ b/scripts/package/mkspec @@ -86,6 +86,14 @@ echo "%endif" echo 'cp System.map $RPM_BUILD_ROOT'"/boot/System.map-$KERNELRELEASE" echo 'cp .config $RPM_BUILD_ROOT'"/boot/config-$KERNELRELEASE" + +echo "%ifnarch ppc64" +echo 'cp vmlinux vmlinux.orig' +echo 'bzip2 -9 vmlinux' +echo 'mv vmlinux.bz2 $RPM_BUILD_ROOT'"/boot/vmlinux-$KERNELRELEASE.bz2" +echo 'mv vmlinux.orig vmlinux' +echo "%endif" + echo "" echo "%clean" echo '#echo -rf $RPM_BUILD_ROOT' -- cgit From 0bb98e231803860e978c302b9faccaf776881137 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Sun, 15 Feb 2009 10:20:30 +0100 Subject: bootgraph: fix for use with dot symbols powerpc has dot symbols, so the dmesg output looks like: <4>[ 0.327310] calling .migration_init+0x0/0x9c @ 1 <4>[ 0.327595] initcall .migration_init+0x0/0x9c returned 1 after 0 usecs The below fixes bootgraph.pl so it handles this correctly. Signed-off-by: Michael Neuling Signed-off-by: Arjan van de Ven Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- scripts/bootgraph.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl index b0246307aac..12caa822a23 100644 --- a/scripts/bootgraph.pl +++ b/scripts/bootgraph.pl @@ -51,7 +51,7 @@ my %pidctr; while (<>) { my $line = $_; - if ($line =~ /([0-9\.]+)\] calling ([a-zA-Z0-9\_]+)\+/) { + if ($line =~ /([0-9\.]+)\] calling ([a-zA-Z0-9\_\.]+)\+/) { my $func = $2; if ($done == 0) { $start{$func} = $1; @@ -87,7 +87,7 @@ while (<>) { $count = $count + 1; } - if ($line =~ /([0-9\.]+)\] initcall ([a-zA-Z0-9\_]+)\+.*returned/) { + if ($line =~ /([0-9\.]+)\] initcall ([a-zA-Z0-9\_\.]+)\+.*returned/) { if ($done == 0) { $end{$2} = $1; $maxtime = $1; -- cgit From 953fae66d124486c9e284806429c52c5402f59ac Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Wed, 11 Feb 2009 13:24:09 -0800 Subject: kbuild: fix tags generation of config symbols commit 4f628248a578585472e19e4cba2c604643af8c6c aka "kbuild: reintroduce ALLSOURCE_ARCHS support for tags/cscope" breaks tags generation for Kconfig symbols. Steps to reproduce: make tags vi -t PROC_FS It should jump to 'config PROC_FS' line. Signed-off-by: Alexey Dobriyan Tested-by: Pete Wyckoff Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- scripts/tags.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/tags.sh b/scripts/tags.sh index fdbe78bb5e2..7e21e914611 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -76,7 +76,10 @@ all_sources() all_kconfigs() { - find_sources $ALLSOURCE_ARCHS 'Kconfig*' + for arch in $ALLSOURCE_ARCHS; do + find_sources $arch 'Kconfig*' + done + find_other_sources 'Kconfig*' } all_defconfigs() -- cgit From 5123b327c107db9e560fd62d50c27a3816e5a078 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Sun, 25 Jan 2009 18:39:12 +0530 Subject: kbuild: add sys_* entries for syscalls in tags Currently, it is no longer possible to use the tags file to jump to system call function definitions with sys_foo, because the definitions are obscured by use of the SYSCALL_DEFINE* macros. This patch adds the appropriate option to ctags to make it see through the macro. Also, it adds the ENTRY() work already done for Exuberant to Emacs too. Signed-off-by: Rabin Vincent Signed-off-by: Sam Ravnborg --- scripts/tags.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/scripts/tags.sh b/scripts/tags.sh index 7e21e914611..5bd8b1003d4 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -102,7 +102,8 @@ exuberant() -I ____cacheline_internodealigned_in_smp \ -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \ --extra=+f --c-kinds=+px \ - --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' + --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \ + --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' all_kconfigs | xargs $1 -a \ --langdef=kconfig --language-force=kconfig \ @@ -120,7 +121,9 @@ exuberant() emacs() { - all_sources | xargs $1 -a + all_sources | xargs $1 -a \ + --regex='/^ENTRY(\([^)]*\)).*/\1/' \ + --regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' all_kconfigs | xargs $1 -a \ --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/' -- cgit From c19ef7fd8e534c870166213e9e30de9c44b34a76 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Sun, 15 Feb 2009 11:30:52 +0100 Subject: scripts: add x86 register parser to markup_oops.pl An oops dump also contains the register values. This patch parses these for (32 bit) x86, and then annotates the disassembly with these values; this helps in analysis of the oops by the developer, for example, NULL pointer or other pointer bugs show up clearly this way. Signed-off-by: Arjan van de Ven Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- scripts/markup_oops.pl | 106 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 100 insertions(+), 6 deletions(-) diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl index d40449cafa8..bb2046891c9 100644 --- a/scripts/markup_oops.pl +++ b/scripts/markup_oops.pl @@ -32,6 +32,78 @@ my $module = ""; my $func_offset; my $vmaoffset = 0; +my %regs; + + +sub parse_x86_regs +{ + my ($line) = @_; + if ($line =~ /EAX: ([0-9a-f]+) EBX: ([0-9a-f]+) ECX: ([0-9a-f]+) EDX: ([0-9a-f]+)/) { + $regs{"%eax"} = $1; + $regs{"%ebx"} = $2; + $regs{"%ecx"} = $3; + $regs{"%edx"} = $4; + } + if ($line =~ /ESI: ([0-9a-f]+) EDI: ([0-9a-f]+) EBP: ([0-9a-f]+) ESP: ([0-9a-f]+)/) { + $regs{"%esi"} = $1; + $regs{"%edi"} = $2; + $regs{"%esp"} = $4; + } +} + +sub process_x86_regs +{ + my ($line, $cntr) = @_; + my $str = ""; + if (length($line) < 40) { + return ""; # not an asm istruction + } + + # find the arguments to the instruction + if ($line =~ /([0-9a-zA-Z\,\%\(\)\-\+]+)$/) { + $lastword = $1; + } else { + return ""; + } + + # we need to find the registers that get clobbered, + # since their value is no longer relevant for previous + # instructions in the stream. + + $clobber = $lastword; + # first, remove all memory operands, they're read only + $clobber =~ s/\([a-z0-9\%\,]+\)//g; + # then, remove everything before the comma, thats the read part + $clobber =~ s/.*\,//g; + + # if this is the instruction that faulted, we haven't actually done + # the write yet... nothing is clobbered. + if ($cntr == 0) { + $clobber = ""; + } + + foreach $reg (keys(%regs)) { + my $val = $regs{$reg}; + # first check if we're clobbering this register; if we do + # we print it with a =>, and then delete its value + if ($clobber =~ /$reg/) { + if (length($val) > 0) { + $str = $str . " $reg => $val "; + } + $regs{$reg} = ""; + $val = ""; + } + # now check if we're reading this register + if ($lastword =~ /$reg/) { + if (length($val) > 0) { + $str = $str . " $reg = $val "; + } + } + } + return $str; +} + +# parse the oops while () { my $line = $_; if ($line =~ /EIP: 0060:\[\<([a-z0-9]+)\>\]/) { @@ -46,10 +118,11 @@ while () { if ($line =~ /EIP is at ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]+\W\[([a-zA-Z0-9\_\-]+)\]/) { $module = $3; } + parse_x86_regs($line); } my $decodestart = hex($target) - hex($func_offset); -my $decodestop = $decodestart + 8192; +my $decodestop = hex($target) + 8192; if ($target eq "0") { print "No oops found!\n"; print "Usage: \n"; @@ -84,6 +157,7 @@ my $counter = 0; my $state = 0; my $center = 0; my @lines; +my @reglines; sub InRange { my ($address, $target) = @_; @@ -188,16 +262,36 @@ while ($finish < $counter) { my $i; -my $fulltext = ""; + +# start annotating the registers in the asm. +# this goes from the oopsing point back, so that the annotator +# can track (opportunistically) which registers got written and +# whos value no longer is relevant. + +$i = $center; +while ($i >= $start) { + $reglines[$i] = process_x86_regs($lines[$i], $center - $i); + $i = $i - 1; +} + $i = $start; while ($i < $finish) { + my $line; if ($i == $center) { - $fulltext = $fulltext . "*$lines[$i] <----- faulting instruction\n"; + $line = "*$lines[$i] "; } else { - $fulltext = $fulltext . " $lines[$i]\n"; + $line = " $lines[$i] "; + } + print $line; + if (defined($reglines[$i]) && length($reglines[$i]) > 0) { + my $c = 60 - length($line); + while ($c > 0) { print " "; $c = $c - 1; }; + print "| $reglines[$i]"; } + if ($i == $center) { + print "<--- faulting instruction"; + } + print "\n"; $i = $i +1; } -print $fulltext; - -- cgit From 11df65c3c6f7fdc837a5be8787d31011e8bb93c1 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Sun, 15 Feb 2009 11:30:55 +0100 Subject: scripts: add x86 64 bit support to the markup_oops.pl script Signed-off-by: Arjan van de Ven Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- scripts/markup_oops.pl | 59 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl index bb2046891c9..528492bcba5 100644 --- a/scripts/markup_oops.pl +++ b/scripts/markup_oops.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl use File::Basename; @@ -29,7 +29,7 @@ my $filename = $vmlinux_name; my $target = "0"; my $function; my $module = ""; -my $func_offset; +my $func_offset = 0; my $vmaoffset = 0; my %regs; @@ -49,6 +49,39 @@ sub parse_x86_regs $regs{"%edi"} = $2; $regs{"%esp"} = $4; } + if ($line =~ /RAX: ([0-9a-f]+) RBX: ([0-9a-f]+) RCX: ([0-9a-f]+)/) { + $regs{"%eax"} = $1; + $regs{"%ebx"} = $2; + $regs{"%ecx"} = $3; + } + if ($line =~ /RDX: ([0-9a-f]+) RSI: ([0-9a-f]+) RDI: ([0-9a-f]+)/) { + $regs{"%edx"} = $1; + $regs{"%esi"} = $2; + $regs{"%edi"} = $3; + } + if ($line =~ /RBP: ([0-9a-f]+) R08: ([0-9a-f]+) R09: ([0-9a-f]+)/) { + $regs{"%r08"} = $2; + $regs{"%r09"} = $3; + } + if ($line =~ /R10: ([0-9a-f]+) R11: ([0-9a-f]+) R12: ([0-9a-f]+)/) { + $regs{"%r10"} = $1; + $regs{"%r11"} = $2; + $regs{"%r12"} = $3; + } + if ($line =~ /R13: ([0-9a-f]+) R14: ([0-9a-f]+) R15: ([0-9a-f]+)/) { + $regs{"%r13"} = $1; + $regs{"%r14"} = $2; + $regs{"%r15"} = $3; + } +} + +sub reg_name +{ + my ($reg) = @_; + $reg =~ s/r(.)x/e\1x/; + $reg =~ s/r(.)i/e\1i/; + $reg =~ s/r(.)p/e\1p/; + return $reg; } sub process_x86_regs @@ -83,10 +116,18 @@ sub process_x86_regs } foreach $reg (keys(%regs)) { + my $clobberprime = reg_name($clobber); + my $lastwordprime = reg_name($lastword); my $val = $regs{$reg}; + if ($val =~ /^[0]+$/) { + $val = "0"; + } else { + $val =~ s/^0*//; + } + # first check if we're clobbering this register; if we do # we print it with a =>, and then delete its value - if ($clobber =~ /$reg/) { + if ($clobber =~ /$reg/ || $clobberprime =~ /$reg/) { if (length($val) > 0) { $str = $str . " $reg => $val "; } @@ -94,7 +135,7 @@ sub process_x86_regs $val = ""; } # now check if we're reading this register - if ($lastword =~ /$reg/) { + if ($lastword =~ /$reg/ || $lastwordprime =~ /$reg/) { if (length($val) > 0) { $str = $str . " $reg = $val "; } @@ -109,15 +150,25 @@ while () { if ($line =~ /EIP: 0060:\[\<([a-z0-9]+)\>\]/) { $target = $1; } + if ($line =~ /RIP: 0010:\[\<([a-z0-9]+)\>\]/) { + $target = $1; + } if ($line =~ /EIP is at ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]/) { $function = $1; $func_offset = $2; } + if ($line =~ /RIP: 0010:\[\<[0-9a-f]+\>\] \[\<[0-9a-f]+\>\] ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]/) { + $function = $1; + $func_offset = $2; + } # check if it's a module if ($line =~ /EIP is at ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]+\W\[([a-zA-Z0-9\_\-]+)\]/) { $module = $3; } + if ($line =~ /RIP: 0010:\[\<[0-9a-f]+\>\] \[\<[0-9a-f]+\>\] ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]+\W\[([a-zA-Z0-9\_\-]+)\]/) { + $module = $3; + } parse_x86_regs($line); } -- cgit From 929799973ba4a40f7b8001e9cc461c13d04c4124 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 10 Jan 2009 04:56:13 +0100 Subject: kbuild: create the source symlink earlier in the objdir It's useful to already have the source symlink in a objdir when one just runs make *config. Then one can do mkdir obj-allyes cd obj-allyes make -C ../sourcedir O=$(pwd) allyesconfig ./source/scripts/config --disable debug_info make CC=icecc -j18 without having to interrupt the make first just to get the source symlink. Signed-off-by: Andi Kleen [sam: deleted the other source symlink statement] Signed-off-by: Sam Ravnborg --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 22d758495ad..59cf6dacec0 100644 --- a/Makefile +++ b/Makefile @@ -389,6 +389,7 @@ PHONY += outputmakefile # output directory. outputmakefile: ifneq ($(KBUILD_SRC),) + $(Q)ln -fsn $(srctree) source $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \ $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL) endif @@ -946,7 +947,6 @@ ifneq ($(KBUILD_SRC),) mkdir -p include2; \ ln -fsn $(srctree)/include/asm-$(SRCARCH) include2/asm; \ fi - ln -fsn $(srctree) source endif # prepare2 creates a makefile if using a separate output directory -- cgit From 88d0f550d71493cd975a11a03c166211b2f3bd32 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sat, 14 Feb 2009 23:57:28 -0800 Subject: x86: make 32bit to call enable_IO_APIC early like 64bit Impact: cleanup So we remove some #ifdefs. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic.c | 8 ++++---- arch/x86/kernel/io_apic.c | 4 ---- arch/x86/kernel/smpboot.c | 3 +-- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c index 8bd801db24d..b8616aaa168 100644 --- a/arch/x86/kernel/apic.c +++ b/arch/x86/kernel/apic.c @@ -1646,19 +1646,19 @@ int __init APIC_init_uniprocessor(void) physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map); setup_local_APIC(); -#ifdef CONFIG_X86_64 +#ifdef CONFIG_X86_IO_APIC /* * Now enable IO-APICs, actually call clear_IO_APIC * We need clear_IO_APIC before enabling vector on BP */ if (!skip_ioapic_setup && nr_ioapics) enable_IO_APIC(); -#endif -#ifdef CONFIG_X86_IO_APIC if (!smp_found_config || skip_ioapic_setup || !nr_ioapics) -#endif localise_nmi_watchdog(); +#else + localise_nmi_watchdog(); +#endif end_local_APIC_setup(); #ifdef CONFIG_X86_IO_APIC diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c index 7248ca11bdc..0b7cde3da48 100644 --- a/arch/x86/kernel/io_apic.c +++ b/arch/x86/kernel/io_apic.c @@ -3057,13 +3057,9 @@ out: void __init setup_IO_APIC(void) { -#ifdef CONFIG_X86_32 - enable_IO_APIC(); -#else /* * calling enable_IO_APIC() is moved to setup_local_APIC for BP */ -#endif io_apic_irqs = ~PIC_IRQS; diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index af57f88186e..10834954e30 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -1154,13 +1154,12 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) */ setup_local_APIC(); -#ifdef CONFIG_X86_64 /* * Enable IO APIC before setting up error vector */ if (!skip_ioapic_setup && nr_ioapics) enable_IO_APIC(); -#endif + end_local_APIC_setup(); map_cpu_to_logical_apicid(); -- cgit From 391b170f10e669dd429aa47bce998c2fa839404c Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Tue, 6 Jan 2009 13:57:11 +0200 Subject: mmiotrace: count events lost due to not recording Impact: enhances lost events counting in mmiotrace The tracing framework, or the ring buffer facility it uses, has a switch to stop recording data. When recording is off, the trace events will be lost. The framework does not count these, so mmiotrace has to count them itself. Signed-off-by: Pekka Paalanen Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar --- kernel/trace/trace_mmiotrace.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c index fffcb069f1d..80e503ef613 100644 --- a/kernel/trace/trace_mmiotrace.c +++ b/kernel/trace/trace_mmiotrace.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "trace.h" @@ -19,6 +20,7 @@ struct header_iter { static struct trace_array *mmio_trace_array; static bool overrun_detected; static unsigned long prev_overruns; +static atomic_t dropped_count; static void mmio_reset_data(struct trace_array *tr) { @@ -121,11 +123,11 @@ static void mmio_close(struct trace_iterator *iter) static unsigned long count_overruns(struct trace_iterator *iter) { - unsigned long cnt = 0; + unsigned long cnt = atomic_xchg(&dropped_count, 0); unsigned long over = ring_buffer_overruns(iter->tr->buffer); if (over > prev_overruns) - cnt = over - prev_overruns; + cnt += over - prev_overruns; prev_overruns = over; return cnt; } @@ -310,8 +312,10 @@ static void __trace_mmiotrace_rw(struct trace_array *tr, event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry), &irq_flags); - if (!event) + if (!event) { + atomic_inc(&dropped_count); return; + } entry = ring_buffer_event_data(event); tracing_generic_entry_update(&entry->ent, 0, preempt_count()); entry->ent.type = TRACE_MMIO_RW; @@ -338,8 +342,10 @@ static void __trace_mmiotrace_map(struct trace_array *tr, event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry), &irq_flags); - if (!event) + if (!event) { + atomic_inc(&dropped_count); return; + } entry = ring_buffer_event_data(event); tracing_generic_entry_update(&entry->ent, 0, preempt_count()); entry->ent.type = TRACE_MMIO_MAP; -- cgit From 6bc5c366b1a45ca18fba6851f62db5743b3f6db5 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Sat, 3 Jan 2009 21:23:51 +0200 Subject: trace: mmiotrace to the tracer menu in Kconfig Impact: cosmetic change in Kconfig menu layout This patch was originally suggested by Peter Zijlstra, but seems it was forgotten. CONFIG_MMIOTRACE and CONFIG_MMIOTRACE_TEST were selectable directly under the Kernel hacking / debugging menu in the kernel configuration system. They were present only for x86 and x86_64. Other tracers that use the ftrace tracing framework are in their own sub-menu. This patch moves the mmiotrace configuration options there. Since the Kconfig file, where the tracer menu is, is not architecture specific, HAVE_MMIOTRACE_SUPPORT is introduced and provided only by x86/x86_64. CONFIG_MMIOTRACE now depends on it. Signed-off-by: Pekka Paalanen Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar --- arch/x86/Kconfig.debug | 24 ++---------------------- kernel/trace/Kconfig | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 10d6cc3fd05..e1983fa025d 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -174,28 +174,8 @@ config IOMMU_LEAK Add a simple leak tracer to the IOMMU code. This is useful when you are debugging a buggy device driver that leaks IOMMU mappings. -config MMIOTRACE - bool "Memory mapped IO tracing" - depends on DEBUG_KERNEL && PCI - select TRACING - help - Mmiotrace traces Memory Mapped I/O access and is meant for - debugging and reverse engineering. It is called from the ioremap - implementation and works via page faults. Tracing is disabled by - default and can be enabled at run-time. - - See Documentation/tracers/mmiotrace.txt. - If you are not helping to develop drivers, say N. - -config MMIOTRACE_TEST - tristate "Test module for mmiotrace" - depends on MMIOTRACE && m - help - This is a dumb module for testing mmiotrace. It is very dangerous - as it will write garbage to IO memory starting at a given address. - However, it should be safe to use on e.g. unused portion of VRAM. - - Say N, unless you absolutely know what you are doing. +config HAVE_MMIOTRACE_SUPPORT + def_bool y # # IO delay types: diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index e2a4ff6fc3a..58a93fbd68a 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -302,4 +302,27 @@ config FTRACE_STARTUP_TEST functioning properly. It will do tests on all the configured tracers of ftrace. +config MMIOTRACE + bool "Memory mapped IO tracing" + depends on HAVE_MMIOTRACE_SUPPORT && DEBUG_KERNEL && PCI + select TRACING + help + Mmiotrace traces Memory Mapped I/O access and is meant for + debugging and reverse engineering. It is called from the ioremap + implementation and works via page faults. Tracing is disabled by + default and can be enabled at run-time. + + See Documentation/tracers/mmiotrace.txt. + If you are not helping to develop drivers, say N. + +config MMIOTRACE_TEST + tristate "Test module for mmiotrace" + depends on MMIOTRACE && m + help + This is a dumb module for testing mmiotrace. It is very dangerous + as it will write garbage to IO memory starting at a given address. + However, it should be safe to use on e.g. unused portion of VRAM. + + Say N, unless you absolutely know what you are doing. + endmenu -- cgit From f9aa28adfc6a4b01268ebb6d88566cca8627905f Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Sat, 3 Jan 2009 21:09:27 +0200 Subject: doc: mmiotrace.txt, buffer size control change Impact: prevents confusing the user when buffer size is inadequate The tracing framework offers a resizeable buffer, which mmiotrace uses to record events. If the buffer is full, the following events will be lost. Events should not be lost, so the documentation instructs the user to increase the buffer size. The buffer size is set via a debugfs file. Mmiotrace documentation was not updated the same time the debugfs file was changed. The old file was tracing/trace_entries and first contained the number of entries the buffer had space for, per cpu. Nowadays this file is replaced with the file tracing/buffer_size_kb, which tells the amount of memory reserved for the buffer, per cpu, in kilobytes. Previously, a flag had to be toggled via the debugfs file tracing/tracing_enabled when the buffer size was changed. This is no longer necessary. The mmiotrace documentation is updated to reflect the current state of the tracing framework. Signed-off-by: Pekka Paalanen Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar --- Documentation/tracers/mmiotrace.txt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Documentation/tracers/mmiotrace.txt b/Documentation/tracers/mmiotrace.txt index cde23b4a12a..5731c67abc5 100644 --- a/Documentation/tracers/mmiotrace.txt +++ b/Documentation/tracers/mmiotrace.txt @@ -78,12 +78,10 @@ to view your kernel log and look for "mmiotrace has lost events" warning. If events were lost, the trace is incomplete. You should enlarge the buffers and try again. Buffers are enlarged by first seeing how large the current buffers are: -$ cat /debug/tracing/trace_entries +$ cat /debug/tracing/buffer_size_kb gives you a number. Approximately double this number and write it back, for instance: -$ echo 0 > /debug/tracing/tracing_enabled -$ echo 128000 > /debug/tracing/trace_entries -$ echo 1 > /debug/tracing/tracing_enabled +$ echo 128000 > /debug/tracing/buffer_size_kb Then start again from the top. If you are doing a trace for a driver project, e.g. Nouveau, you should also -- cgit From 970ec1a8213cd1a1ea29972ebbe4575a8b30bca1 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sun, 15 Feb 2009 14:06:13 -0800 Subject: [IA64] fix __apci_unmap_table Impact: fix build error to fix: tip/arch/ia64/kernel/acpi.c:203: error: conflicting types for '__acpi_unmap_table' tip/include/linux/acpi.h:82: error: previous declaration of '__acpi_unmap_table' was here tip/arch/ia64/kernel/acpi.c:203: error: conflicting types for '__acpi_unmap_table' tip/include/linux/acpi.h:82: error: previous declaration of '__acpi_unmap_table' was here Signed-off-by: Yinghai Lu Cc: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar --- arch/ia64/kernel/acpi.c | 2 +- include/linux/acpi.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 2363ed17319..bdef2ce38c8 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -199,7 +199,7 @@ char *__init __acpi_map_table(unsigned long phys_addr, unsigned long size) return __va(phys_addr); } -char *__init __acpi_unmap_table(unsigned long virt_addr, unsigned long size) +void __init __acpi_unmap_table(char *map, unsigned long size) { } diff --git a/include/linux/acpi.h b/include/linux/acpi.h index d59f0fa4d77..78199151c00 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -79,7 +79,7 @@ typedef int (*acpi_table_handler) (struct acpi_table_header *table); typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end); char * __acpi_map_table (unsigned long phys_addr, unsigned long size); -void __init __acpi_unmap_table(char *map, unsigned long size); +void __acpi_unmap_table(char *map, unsigned long size); int early_acpi_boot_init(void); int acpi_boot_init (void); int acpi_boot_table_init (void); -- cgit From 090542641de833c6f756895fc2f139f046e298f9 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 15 Feb 2009 20:02:19 -0500 Subject: ext4: Fix NULL dereference in ext4_ext_migrate()'s error handling This was found through a code checker (http://repo.or.cz/w/smatch.git/). It looks like you might be able to trigger the error by trying to migrate a readonly file system. Signed-off-by: Dan Carpenter Signed-off-by: "Theodore Ts'o" --- fs/ext4/migrate.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c index 734abca25e3..fe64d9f7985 100644 --- a/fs/ext4/migrate.c +++ b/fs/ext4/migrate.c @@ -481,7 +481,7 @@ int ext4_ext_migrate(struct inode *inode) + 1); if (IS_ERR(handle)) { retval = PTR_ERR(handle); - goto err_out; + return retval; } tmp_inode = ext4_new_inode(handle, inode->i_sb->s_root->d_inode, @@ -489,8 +489,7 @@ int ext4_ext_migrate(struct inode *inode) if (IS_ERR(tmp_inode)) { retval = -ENOMEM; ext4_journal_stop(handle); - tmp_inode = NULL; - goto err_out; + return retval; } i_size_write(tmp_inode, i_size_read(inode)); /* @@ -618,8 +617,7 @@ err_out: ext4_journal_stop(handle); - if (tmp_inode) - iput(tmp_inode); + iput(tmp_inode); return retval; } -- cgit From a0abd520fd69295f4a3735e29a9448a32e101d47 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 16 Feb 2009 17:31:58 -0600 Subject: cpumask: fix powernow-k8: partial revert of 2fdf66b491ac706657946442789ec644cc317e1a Impact: fix powernow-k8 when acpi=off (or other error). There was a spurious change introduced into powernow-k8 in this patch: so that we try to "restore" the cpus_allowed we never saved. We revert that file. See lkml "[PATCH] x86/powernow: fix cpus_allowed brokage when acpi=off" from Yinghai for the bug report. Cc: Mike Travis Cc: Yinghai Lu Signed-off-by: Rusty Russell Acked-by: Ingo Molnar --- arch/x86/kernel/cpu/cpufreq/powernow-k8.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index fb039cd345d..6428aa17b40 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c @@ -1157,8 +1157,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) data->cpu = pol->cpu; data->currpstate = HW_PSTATE_INVALID; - rc = powernow_k8_cpu_init_acpi(data); - if (rc) { + if (powernow_k8_cpu_init_acpi(data)) { /* * Use the PSB BIOS structure. This is only availabe on * an UP version, and is deprecated by AMD. @@ -1176,17 +1175,20 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) "ACPI maintainers and complain to your BIOS " "vendor.\n"); #endif - goto err_out; + kfree(data); + return -ENODEV; } if (pol->cpu != 0) { printk(KERN_ERR FW_BUG PFX "No ACPI _PSS objects for " "CPU other than CPU0. Complain to your BIOS " "vendor.\n"); - goto err_out; + kfree(data); + return -ENODEV; } rc = find_psb_table(data); if (rc) { - goto err_out; + kfree(data); + return -ENODEV; } /* Take a crude guess here. * That guess was in microseconds, so multiply with 1000 */ -- cgit From 1371be0f7c8f6141b2dbfde6a7ae7885bedb9834 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 16 Feb 2009 17:31:59 -0600 Subject: cpumask: Use cpu_*_mask accessors code: alpha Impact: use new API, fix SMP bug. Use the new accessors rather than frobbing bits directly. This also removes the bug introduced in ee0c468b (alpha: compile fixes) which had Alpha setting bits on an on-stack cpumask, not the cpu_online_map. Cc: Richard Henderson Cc: FUJITA Tomonori Signed-off-by: Rusty Russell Signed-off-by: Mike Travis Acked-by: Ivan Kokshaysky Acked-by: Ingo Molnar --- arch/alpha/kernel/process.c | 8 ++++---- arch/alpha/kernel/smp.c | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index f238370c907..8d0097f1020 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -93,8 +93,8 @@ common_shutdown_1(void *generic_ptr) if (cpuid != boot_cpuid) { flags |= 0x00040000UL; /* "remain halted" */ *pflags = flags; - cpu_clear(cpuid, cpu_present_map); - cpu_clear(cpuid, cpu_possible_map); + set_cpu_present(cpuid, false); + set_cpu_possible(cpuid, false); halt(); } #endif @@ -120,8 +120,8 @@ common_shutdown_1(void *generic_ptr) #ifdef CONFIG_SMP /* Wait for the secondaries to halt. */ - cpu_clear(boot_cpuid, cpu_present_map); - cpu_clear(boot_cpuid, cpu_possible_map); + set_cpu_present(boot_cpuid, false); + set_cpu_possible(boot_cpuid, false); while (cpus_weight(cpu_present_map)) barrier(); #endif diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index 00f1dc3dfd5..b1fe5674c3a 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c @@ -120,12 +120,12 @@ void __cpuinit smp_callin(void) { int cpuid = hard_smp_processor_id(); - cpumask_t mask = cpu_online_map; - if (cpu_test_and_set(cpuid, mask)) { + if (cpu_online(cpuid)) { printk("??, cpu 0x%x already present??\n", cpuid); BUG(); } + set_cpu_online(cpuid, true); /* Turn on machine checks. */ wrmces(7); @@ -436,8 +436,8 @@ setup_smp(void) ((char *)cpubase + i*hwrpb->processor_size); if ((cpu->flags & 0x1cc) == 0x1cc) { smp_num_probed++; - cpu_set(i, cpu_possible_map); - cpu_set(i, cpu_present_map); + set_cpu_possible(i, true); + set_cpu_present(i, true); cpu->pal_revision = boot_cpu_palrev; } @@ -470,8 +470,8 @@ smp_prepare_cpus(unsigned int max_cpus) /* Nothing to do on a UP box, or when told not to. */ if (smp_num_probed == 1 || max_cpus == 0) { - cpu_possible_map = cpumask_of_cpu(boot_cpuid); - cpu_present_map = cpumask_of_cpu(boot_cpuid); + init_cpu_possible(cpumask_of(boot_cpuid)); + init_cpu_present(cpumask_of(boot_cpuid)); printk(KERN_INFO "SMP mode deactivated.\n"); return; } -- cgit From 9033304a1520df346862c95743a6c2023f21f057 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Fri, 6 Feb 2009 13:35:44 -0800 Subject: x86, xen: short-circuit tests for dom0 When testing for a dom0/initial/privileged domain, make sure the predicate evaluates to a compile-time 0 if CONFIG_XEN_DOM0 isn't enabled. This will make most of the dom0 code evaporate without much more effort. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar --- arch/x86/include/asm/xen/hypervisor.h | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/arch/x86/include/asm/xen/hypervisor.h b/arch/x86/include/asm/xen/hypervisor.h index 81fbd735aec..d5b7e90c0ed 100644 --- a/arch/x86/include/asm/xen/hypervisor.h +++ b/arch/x86/include/asm/xen/hypervisor.h @@ -38,22 +38,30 @@ extern struct shared_info *HYPERVISOR_shared_info; extern struct start_info *xen_start_info; enum xen_domain_type { - XEN_NATIVE, - XEN_PV_DOMAIN, - XEN_HVM_DOMAIN, + XEN_NATIVE, /* running on bare hardware */ + XEN_PV_DOMAIN, /* running in a PV domain */ + XEN_HVM_DOMAIN, /* running in a Xen hvm domain */ }; -extern enum xen_domain_type xen_domain_type; - #ifdef CONFIG_XEN -#define xen_domain() (xen_domain_type != XEN_NATIVE) +extern enum xen_domain_type xen_domain_type; #else -#define xen_domain() (0) +#define xen_domain_type XEN_NATIVE #endif -#define xen_pv_domain() (xen_domain() && xen_domain_type == XEN_PV_DOMAIN) -#define xen_hvm_domain() (xen_domain() && xen_domain_type == XEN_HVM_DOMAIN) +#define xen_domain() (xen_domain_type != XEN_NATIVE) +#define xen_pv_domain() (xen_domain() && \ + xen_domain_type == XEN_PV_DOMAIN) +#define xen_hvm_domain() (xen_domain() && \ + xen_domain_type == XEN_HVM_DOMAIN) + +#ifdef CONFIG_XEN_DOM0 +#include -#define xen_initial_domain() (xen_pv_domain() && xen_start_info->flags & SIF_INITDOMAIN) +#define xen_initial_domain() (xen_pv_domain() && \ + xen_start_info->flags & SIF_INITDOMAIN) +#else /* !CONFIG_XEN_DOM0 */ +#define xen_initial_domain() (0) +#endif /* CONFIG_XEN_DOM0 */ #endif /* _ASM_X86_XEN_HYPERVISOR_H */ -- cgit From b93d51dc62a41b5c2d6f32a0870709dc0cc55545 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Fri, 6 Feb 2009 13:35:57 -0800 Subject: x86, xen: record and display initiator of each multicall when debugging Store the caller for each multicall so we can report it on failure. Signed-off-by: Ian Campbell Signed-off-by: Ingo Molnar --- arch/x86/xen/multicalls.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/x86/xen/multicalls.c b/arch/x86/xen/multicalls.c index c738644b543..82f2513e975 100644 --- a/arch/x86/xen/multicalls.c +++ b/arch/x86/xen/multicalls.c @@ -39,6 +39,7 @@ struct mc_buffer { struct multicall_entry entries[MC_BATCH]; #if MC_DEBUG struct multicall_entry debug[MC_BATCH]; + void *caller[MC_BATCH]; #endif unsigned char args[MC_ARGS]; struct callback { @@ -154,11 +155,12 @@ void xen_mc_flush(void) ret, smp_processor_id()); dump_stack(); for (i = 0; i < b->mcidx; i++) { - printk(KERN_DEBUG " call %2d/%d: op=%lu arg=[%lx] result=%ld\n", + printk(KERN_DEBUG " call %2d/%d: op=%lu arg=[%lx] result=%ld\t%pF\n", i+1, b->mcidx, b->debug[i].op, b->debug[i].args[0], - b->entries[i].result); + b->entries[i].result, + b->caller[i]); } } #endif @@ -197,6 +199,9 @@ struct multicall_space __xen_mc_entry(size_t args) } ret.mc = &b->entries[b->mcidx]; +#ifdef MC_DEBUG + b->caller[b->mcidx] = __builtin_return_address(0); +#endif b->mcidx++; ret.args = &b->args[argidx]; b->argidx = argidx + args; -- cgit From 3d39e9d07b576ee72f2c94cfad9e618fe21763b2 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Fri, 6 Feb 2009 13:38:51 -0800 Subject: x86, xen: degrade BUG to WARN when multicall fails If one of the components of a multicall fails, WARN rather than BUG, to help with debugging. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar --- arch/x86/xen/multicalls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/xen/multicalls.c b/arch/x86/xen/multicalls.c index 82f2513e975..6cffd5532b9 100644 --- a/arch/x86/xen/multicalls.c +++ b/arch/x86/xen/multicalls.c @@ -179,7 +179,7 @@ void xen_mc_flush(void) } b->cbidx = 0; - BUG_ON(ret); + WARN_ON(ret); } struct multicall_space __xen_mc_entry(size_t args) -- cgit From c99608637eac8834d830496c462c054137772122 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Fri, 6 Feb 2009 13:38:56 -0800 Subject: x86, xen: do multicall callbacks with interrupts disabled We can't call the callbacks after enabling interrupts, as we may get a nested multicall call, which would cause a great deal of havok. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar --- arch/x86/xen/multicalls.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/xen/multicalls.c b/arch/x86/xen/multicalls.c index 6cffd5532b9..8bff7e7c290 100644 --- a/arch/x86/xen/multicalls.c +++ b/arch/x86/xen/multicalls.c @@ -170,8 +170,6 @@ void xen_mc_flush(void) } else BUG_ON(b->argidx != 0); - local_irq_restore(flags); - for (i = 0; i < b->cbidx; i++) { struct callback *cb = &b->callbacks[i]; @@ -179,6 +177,8 @@ void xen_mc_flush(void) } b->cbidx = 0; + local_irq_restore(flags); + WARN_ON(ret); } -- cgit From 34edaa88324004baf4884fb0388f86059d9c4878 Mon Sep 17 00:00:00 2001 From: Tobias Diedrich Date: Mon, 16 Feb 2009 00:13:20 -0800 Subject: net: forcedeth: Fix wake-on-lan regression Commit f55c21fd9a92a444e55ad1ca4e4732d56661bf2e ("forcedeth: call restore mac addr in nv_shutdown path"), which was introduced to fix the regression tracked at http://bugzilla.kernel.org/show_bug.cgi?id=11358 causes the wake-on-lan mac to be reversed in the shutdown path. Apparently the forcedeth situation is rather messy in that the mac we need to writeback for a subsequent modprobe to work is exactly the reverse of what is needed for proper wake-on-lan. The following patch explains the situation in the comments and makes the call to nv_restore_mac_addr() conditional (only called if we are not really going for poweroff). Tobias Diedrich wrote: > Hmm, I had not tried WOL for some time. > With 2.6.29-rc3 is see the following behaviour: > > State WOL Behaviour > ------------------------------ > shutdown reversed MAC > disk/shutdown reversed MAC > disk/platform OK > > Apparently nv_restore_mac_addr() restores the MAC in the wrong order > for WOL (at least for my PCI_DEVICE_ID_NVIDIA_NVENET_15). platform > works, because the MAC is not touched in the nv_suspend() path. > > A possible fix might be to only call nv_restore_mac_addr() if > system_state != SYSTEM_POWER_OFF. With the following patch: shutdown OK disk/shutdown OK disk/platform OK kexec OK Signed-off-by: Tobias Diedrich Tested-by: Philipp Matthias Hahn Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 5b910cf6374..b8251e82705 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -6011,9 +6011,20 @@ static void nv_shutdown(struct pci_dev *pdev) if (netif_running(dev)) nv_close(dev); - nv_restore_mac_addr(pdev); + /* + * Restore the MAC so a kernel started by kexec won't get confused. + * If we really go for poweroff, we must not restore the MAC, + * otherwise the MAC for WOL will be reversed at least on some boards. + */ + if (system_state != SYSTEM_POWER_OFF) { + nv_restore_mac_addr(pdev); + } pci_disable_device(pdev); + /* + * Apparently it is not possible to reinitialise from D3 hot, + * only put the device into D3 if we really go for poweroff. + */ if (system_state == SYSTEM_POWER_OFF) { if (pci_enable_wake(pdev, PCI_D3cold, np->wolenabled)) pci_enable_wake(pdev, PCI_D3hot, np->wolenabled); -- cgit From 3bd25d0fa3ed588a6735b815cb0c146c23888ace Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sun, 15 Feb 2009 02:54:03 -0800 Subject: x86: pre init pirq_entries[] Impact: cleanup set default value early - this allows the removal of a number of dynamic initialization codepaths, and an #ifdef. Signed-off-by: Yinghai Lu Cc: Andrew Morton Signed-off-by: Ingo Molnar --- arch/x86/kernel/io_apic.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c index 0b7cde3da48..a89878e08a4 100644 --- a/arch/x86/kernel/io_apic.c +++ b/arch/x86/kernel/io_apic.c @@ -813,8 +813,9 @@ static void clear_IO_APIC (void) */ #define MAX_PIRQS 8 -static int pirq_entries [MAX_PIRQS]; -static int pirqs_enabled; +static int pirq_entries[MAX_PIRQS] = { + [0 ... MAX_PIRQS - 1] = -1 +}; static int __init ioapic_pirq_setup(char *str) { @@ -823,10 +824,6 @@ static int __init ioapic_pirq_setup(char *str) get_options(str, ARRAY_SIZE(ints), ints); - for (i = 0; i < MAX_PIRQS; i++) - pirq_entries[i] = -1; - - pirqs_enabled = 1; apic_printk(APIC_VERBOSE, KERN_INFO "PIRQ redirection, working around broken MP-BIOS.\n"); max = MAX_PIRQS; @@ -1976,13 +1973,6 @@ void __init enable_IO_APIC(void) int apic; unsigned long flags; -#ifdef CONFIG_X86_32 - int i; - if (!pirqs_enabled) - for (i = 0; i < MAX_PIRQS; i++) - pirq_entries[i] = -1; -#endif - /* * The number of IO-APIC IRQ registers (== #pins): */ -- cgit From 98c061b6cf2e7a1010286a7a4f672c4623e1b3e0 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 16 Feb 2009 00:00:50 -0800 Subject: x86: make APIC_init_uniprocessor() more like smp_prepare_cpus() Impact: cleanup 1. move localise_nmi_watchdog() later 2. change setup_boot_APIC_clock() to setup_boot_clock() for 64-bit Signed-off-by: Yinghai Lu Cc: Andrew Morton Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c index b8616aaa168..c03f4cc135c 100644 --- a/arch/x86/kernel/apic.c +++ b/arch/x86/kernel/apic.c @@ -1649,32 +1649,28 @@ int __init APIC_init_uniprocessor(void) #ifdef CONFIG_X86_IO_APIC /* * Now enable IO-APICs, actually call clear_IO_APIC - * We need clear_IO_APIC before enabling vector on BP + * We need clear_IO_APIC before enabling error vector */ if (!skip_ioapic_setup && nr_ioapics) enable_IO_APIC(); - - if (!smp_found_config || skip_ioapic_setup || !nr_ioapics) - localise_nmi_watchdog(); -#else - localise_nmi_watchdog(); #endif + end_local_APIC_setup(); #ifdef CONFIG_X86_IO_APIC if (smp_found_config && !skip_ioapic_setup && nr_ioapics) setup_IO_APIC(); -# ifdef CONFIG_X86_64 - else + else { nr_ioapics = 0; -# endif + localise_nmi_watchdog(); + } +#else + localise_nmi_watchdog(); #endif + setup_boot_clock(); #ifdef CONFIG_X86_64 - setup_boot_APIC_clock(); check_nmi_watchdog(); -#else - setup_boot_clock(); #endif return 0; -- cgit From d14a7e0bfc4aed6452a436c9836903fbd1a5d6ad Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 16 Feb 2009 10:13:03 +0100 Subject: Revert "Sound: hda - Restore PCI configuration space with interrupts off" This reverts commit 32e176c14d7a425b681ef003c9061001ddb7fc7b. That commit caused a regression with suspend on Thinkpad SL300. Reference: kernel bug#12711 http://bugzilla.kernel.org/show_bug.cgi?id=12711 Tested-by: Alexandre Rostovtsev Acked-by: Rafael J. Wysocki Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 11e791b965f..c8d9178f47e 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1947,16 +1947,13 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state) return 0; } -static int azx_resume_early(struct pci_dev *pci) -{ - return pci_restore_state(pci); -} - static int azx_resume(struct pci_dev *pci) { struct snd_card *card = pci_get_drvdata(pci); struct azx *chip = card->private_data; + pci_set_power_state(pci, PCI_D0); + pci_restore_state(pci); if (pci_enable_device(pci) < 0) { printk(KERN_ERR "hda-intel: pci_enable_device failed, " "disabling device\n"); @@ -2468,7 +2465,6 @@ static struct pci_driver driver = { .remove = __devexit_p(azx_remove), #ifdef CONFIG_PM .suspend = azx_suspend, - .resume_early = azx_resume_early, .resume = azx_resume, #endif }; -- cgit From e156ac4c571e3be741bc411e58820b74a9295c72 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 16 Feb 2009 15:22:39 +0100 Subject: sound: usb-audio: fix uninitialized variable with M-Audio MIDI interfaces Fix the snd_usbmidi_create_endpoints_midiman() function, which forgot to set the out_interval member of the endpoint info structure for Midiman/ M-Audio devices. Since kernel 2.6.24, any non-zero value makes the driver use interrupt transfers instead of bulk transfers. With EHCI controllers, these random interval values result in unbearably large latencies for output MIDI transfers. Signed-off-by: Clemens Ladisch Reported-by: David Tested-by: David Cc: Signed-off-by: Takashi Iwai --- sound/usb/usbmidi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c index 320641ab5be..26bad373fe6 100644 --- a/sound/usb/usbmidi.c +++ b/sound/usb/usbmidi.c @@ -1625,6 +1625,7 @@ static int snd_usbmidi_create_endpoints_midiman(struct snd_usb_midi* umidi, } ep_info.out_ep = get_endpoint(hostif, 2)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + ep_info.out_interval = 0; ep_info.out_cables = endpoint->out_cables & 0x5555; err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]); if (err < 0) -- cgit From a3c1239eb59c0a907f8be5587d42e950f44543f8 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Mon, 16 Feb 2009 14:37:12 +0000 Subject: wusb: whci-hcd: always lock whc->lock with interrupts disabled Always lock whc->lock with spin_lock_irq() or spin_lock_irqsave(). Signed-off-by: David Vrabel --- drivers/usb/host/whci/asl.c | 4 ++-- drivers/usb/host/whci/pzl.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c index 2291c5f5af5..958751ccea4 100644 --- a/drivers/usb/host/whci/asl.c +++ b/drivers/usb/host/whci/asl.c @@ -227,13 +227,13 @@ void scan_async_work(struct work_struct *work) * Now that the ASL is updated, complete the removal of any * removed qsets. */ - spin_lock(&whc->lock); + spin_lock_irq(&whc->lock); list_for_each_entry_safe(qset, t, &whc->async_removed_list, list_node) { qset_remove_complete(whc, qset); } - spin_unlock(&whc->lock); + spin_unlock_irq(&whc->lock); } /** diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c index 7dc85a0bee7..df8b85f0709 100644 --- a/drivers/usb/host/whci/pzl.c +++ b/drivers/usb/host/whci/pzl.c @@ -255,13 +255,13 @@ void scan_periodic_work(struct work_struct *work) * Now that the PZL is updated, complete the removal of any * removed qsets. */ - spin_lock(&whc->lock); + spin_lock_irq(&whc->lock); list_for_each_entry_safe(qset, t, &whc->periodic_removed_list, list_node) { qset_remove_complete(whc, qset); } - spin_unlock(&whc->lock); + spin_unlock_irq(&whc->lock); } /** -- cgit From 744f6592727a7ab9e3ca4266bedaa786825a31bb Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Mon, 16 Feb 2009 21:21:47 +0100 Subject: [ARM] 5400/1: Add support for inverted rdy_busy pin for Atmel nand device controller Add support for inverted rdy_busy pin for Atmel nand device controller It will fix building error on NeoCore926 board. Acked-by: Andrew Victor Acked-by: David Woodhouse Signed-off-by: Gregory CLEMENT Signed-off-by: Russell King --- arch/arm/mach-at91/include/mach/board.h | 1 + arch/avr32/mach-at32ap/include/mach/board.h | 1 + drivers/mtd/nand/atmel_nand.c | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h index fb51f0e0a83..0b3ae21b456 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h @@ -93,6 +93,7 @@ struct atmel_nand_data { u8 enable_pin; /* chip enable */ u8 det_pin; /* card detect */ u8 rdy_pin; /* ready/busy */ + u8 rdy_pin_active_low; /* rdy_pin value is inverted */ u8 ale; /* address line number connected to ALE */ u8 cle; /* address line number connected to CLE */ u8 bus_width_16; /* buswidth is 16 bit */ diff --git a/arch/avr32/mach-at32ap/include/mach/board.h b/arch/avr32/mach-at32ap/include/mach/board.h index aafaf7a7888..cff8e84f78f 100644 --- a/arch/avr32/mach-at32ap/include/mach/board.h +++ b/arch/avr32/mach-at32ap/include/mach/board.h @@ -116,6 +116,7 @@ struct atmel_nand_data { int enable_pin; /* chip enable */ int det_pin; /* card detect */ int rdy_pin; /* ready/busy */ + u8 rdy_pin_active_low; /* rdy_pin value is inverted */ u8 ale; /* address line number connected to ALE */ u8 cle; /* address line number connected to CLE */ u8 bus_width_16; /* buswidth is 16 bit */ diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index c98c1570a40..47a33cec379 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -139,7 +139,8 @@ static int atmel_nand_device_ready(struct mtd_info *mtd) struct nand_chip *nand_chip = mtd->priv; struct atmel_nand_host *host = nand_chip->priv; - return gpio_get_value(host->board->rdy_pin); + return gpio_get_value(host->board->rdy_pin) ^ + !!host->board->rdy_pin_active_low; } /* -- cgit From 0412558c873f716efe902b397af0653a550f7341 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 16 Feb 2009 22:48:12 +0100 Subject: ALSA: usb-audio - Fix non-continuous rate detection The detection of non-continuous rates (given via rate tables) isn't processed properly (e.g. for type II). This patch fixes and simplifies the detection code. Tested-by: Joris van Rantwijk Cc: Signed-off-by: Takashi Iwai --- sound/usb/usbaudio.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 2ab83129d9b..80863093d2c 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -2524,7 +2524,6 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform * build the rate table and bitmap flags */ int r, idx; - unsigned int nonzero_rates = 0; fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL); if (fp->rate_table == NULL) { @@ -2532,24 +2531,26 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform return -1; } - fp->nr_rates = nr_rates; - fp->rate_min = fp->rate_max = combine_triple(&fmt[8]); + fp->nr_rates = 0; + fp->rate_min = fp->rate_max = 0; for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) { unsigned int rate = combine_triple(&fmt[idx]); + if (!rate) + continue; /* C-Media CM6501 mislabels its 96 kHz altsetting */ if (rate == 48000 && nr_rates == 1 && chip->usb_id == USB_ID(0x0d8c, 0x0201) && fp->altsetting == 5 && fp->maxpacksize == 392) rate = 96000; - fp->rate_table[r] = rate; - nonzero_rates |= rate; - if (rate < fp->rate_min) + fp->rate_table[fp->nr_rates] = rate; + if (!fp->rate_min || rate < fp->rate_min) fp->rate_min = rate; - else if (rate > fp->rate_max) + if (!fp->rate_max || rate > fp->rate_max) fp->rate_max = rate; fp->rates |= snd_pcm_rate_to_rate_bit(rate); + fp->nr_rates++; } - if (!nonzero_rates) { + if (!fp->nr_rates) { hwc_debug("All rates were zero. Skipping format!\n"); return -1; } -- cgit From 3b03cc5b86e2052295b9b484f37226ee15c87924 Mon Sep 17 00:00:00 2001 From: Joris van Rantwijk Date: Mon, 16 Feb 2009 22:58:23 +0100 Subject: ALSA: usb-audio - Workaround for misdetected sample rate with CM6207 The CM6207 incorrectly advertises its 96 kHz playback setting as 48 kHz in its USB device descriptor. This patch extends an existing workaround in usbaudio.c to also cover the CM6207. This resolves issue 0004249 in the ALSA bug tracker. Signed-off-by: Joris van Rantwijk Cc: Signed-off-by: Takashi Iwai --- sound/usb/usbaudio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 80863093d2c..19e37451c21 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -2539,7 +2539,8 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform continue; /* C-Media CM6501 mislabels its 96 kHz altsetting */ if (rate == 48000 && nr_rates == 1 && - chip->usb_id == USB_ID(0x0d8c, 0x0201) && + (chip->usb_id == USB_ID(0x0d8c, 0x0201) || + chip->usb_id == USB_ID(0x0d8c, 0x0102)) && fp->altsetting == 5 && fp->maxpacksize == 392) rate = 96000; fp->rate_table[fp->nr_rates] = rate; -- cgit From d1b3525b4126d7acad0493b62642b80b71442661 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sun, 15 Feb 2009 23:24:24 +0400 Subject: libata-sff: fix 32-bit PIO ATAPI regression Commit 871af1210f13966ab911ed2166e4ab2ce775b99d (libata: Add 32bit PIO support) has caused all kinds of errors on the ATAPI devices, so it has been empirically proven that one shouldn't try to read/write an extra data word when a device is not expecting it already. "Don't do it then"; however, still use a chance to do 32-bit read/write one last time when there are exactly 3 trailing bytes. Oh, and stop pointlessly swapping the bytes to and fro on big-endian machines by using io*_rep() accessors which shouldn't byte-swap. This patch should fix the kernel.org bug #12609. Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/libata-sff.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 0b299b0f817..714cb046b59 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -773,18 +773,32 @@ unsigned int ata_sff_data_xfer32(struct ata_device *dev, unsigned char *buf, else iowrite32_rep(data_addr, buf, words); + /* Transfer trailing bytes, if any */ if (unlikely(slop)) { - __le32 pad; + unsigned char pad[4]; + + /* Point buf to the tail of buffer */ + buf += buflen - slop; + + /* + * Use io*_rep() accessors here as well to avoid pointlessly + * swapping bytes to and fro on the big endian machines... + */ if (rw == READ) { - pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); - memcpy(buf + buflen - slop, &pad, slop); + if (slop < 3) + ioread16_rep(data_addr, pad, 1); + else + ioread32_rep(data_addr, pad, 1); + memcpy(buf, pad, slop); } else { - memcpy(&pad, buf + buflen - slop, slop); - iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); + memcpy(pad, buf, slop); + if (slop < 3) + iowrite16_rep(data_addr, pad, 1); + else + iowrite32_rep(data_addr, pad, 1); } - words++; } - return words << 2; + return (buflen + 1) & ~1; } EXPORT_SYMBOL_GPL(ata_sff_data_xfer32); -- cgit From 7dac745b8e367c99175b8f0d014d996f0e5ed9e5 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 12 Feb 2009 10:34:32 +0900 Subject: sata_nv: give up hardreset on nf2 Kernel bz#12176 reports that nf2 hardreset simply doesn't work. Give up. Argh... Signed-off-by: Tejun Heo Cc: Robert Hancock Reported-by: Saro Signed-off-by: Jeff Garzik --- drivers/ata/sata_nv.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 444af0415ca..55a8eed3f3a 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -421,19 +421,21 @@ static struct ata_port_operations nv_generic_ops = { .hardreset = ATA_OP_NULL, }; -/* OSDL bz3352 reports that nf2/3 controllers can't determine device - * signature reliably. Also, the following thread reports detection - * failure on cold boot with the standard debouncing timing. +/* nf2 is ripe with hardreset related problems. + * + * kernel bz#3352 reports nf2/3 controllers can't determine device + * signature reliably. The following thread reports detection failure + * on cold boot with the standard debouncing timing. * * http://thread.gmane.org/gmane.linux.ide/34098 * - * Debounce with hotplug timing and request follow-up SRST. + * And bz#12176 reports that hardreset simply doesn't work on nf2. + * Give up on it and just don't do hardreset. */ static struct ata_port_operations nv_nf2_ops = { - .inherits = &nv_common_ops, + .inherits = &nv_generic_ops, .freeze = nv_nf2_freeze, .thaw = nv_nf2_thaw, - .hardreset = nv_noclassify_hardreset, }; /* For initial probing after boot and hot plugging, hardreset mostly -- cgit From 720fd66dfad1b0286721dbb2ed4d6076c0aa953b Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 4 Feb 2009 20:44:01 +0100 Subject: mfd: Fix egpio kzalloc return test Since ei is already known to be non-NULL, I assume that what was intended was to test the result of kzalloc. Signed-off-by: Julia Lawall Signed-off-by: Samuel Ortiz --- drivers/mfd/htc-egpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/htc-egpio.c b/drivers/mfd/htc-egpio.c index 1a4d04664d6..194df7b8256 100644 --- a/drivers/mfd/htc-egpio.c +++ b/drivers/mfd/htc-egpio.c @@ -307,7 +307,7 @@ static int __init egpio_probe(struct platform_device *pdev) ei->nchips = pdata->num_chips; ei->chip = kzalloc(sizeof(struct egpio_chip) * ei->nchips, GFP_KERNEL); - if (!ei) { + if (!ei->chip) { ret = -ENOMEM; goto fail; } -- cgit From 62571c29a8343839e85e741db6a489f30686697c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 4 Feb 2009 20:49:52 +0100 Subject: mfd: Initialise WM8350 interrupts earlier Ensure that the interrupt handling is configured before we do platform specific init. This allows the platform specific initialisation to configure things which use interrupts safely. Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/wm8350-core.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c index f92595c8f16..70f5e773954 100644 --- a/drivers/mfd/wm8350-core.c +++ b/drivers/mfd/wm8350-core.c @@ -1404,15 +1404,6 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq, return ret; } - if (pdata && pdata->init) { - ret = pdata->init(wm8350); - if (ret != 0) { - dev_err(wm8350->dev, "Platform init() failed: %d\n", - ret); - goto err; - } - } - mutex_init(&wm8350->auxadc_mutex); mutex_init(&wm8350->irq_mutex); INIT_WORK(&wm8350->irq_work, wm8350_irq_worker); @@ -1430,6 +1421,15 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq, } wm8350->chip_irq = irq; + if (pdata && pdata->init) { + ret = pdata->init(wm8350); + if (ret != 0) { + dev_err(wm8350->dev, "Platform init() failed: %d\n", + ret); + goto err; + } + } + wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0x0); wm8350_client_dev_register(wm8350, "wm8350-codec", -- cgit From 85c93ea7dca475a6ee3bf414befe94b2c42f1001 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 4 Feb 2009 21:09:38 +0100 Subject: mfd: Improve diagnostics for WM8350 ID register probe Check the return value of the device I/O functions when reading the ID registers so we can provide a more useful diagnostic when we're having trouble talking to the device. Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/wm8350-core.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c index 70f5e773954..e5e82c7cc52 100644 --- a/drivers/mfd/wm8350-core.c +++ b/drivers/mfd/wm8350-core.c @@ -1297,14 +1297,29 @@ static void wm8350_client_dev_register(struct wm8350 *wm8350, int wm8350_device_init(struct wm8350 *wm8350, int irq, struct wm8350_platform_data *pdata) { - int ret = -EINVAL; + int ret; u16 id1, id2, mask_rev; u16 cust_id, mode, chip_rev; /* get WM8350 revision and config mode */ - wm8350->read_dev(wm8350, WM8350_RESET_ID, sizeof(id1), &id1); - wm8350->read_dev(wm8350, WM8350_ID, sizeof(id2), &id2); - wm8350->read_dev(wm8350, WM8350_REVISION, sizeof(mask_rev), &mask_rev); + ret = wm8350->read_dev(wm8350, WM8350_RESET_ID, sizeof(id1), &id1); + if (ret != 0) { + dev_err(wm8350->dev, "Failed to read ID: %d\n", ret); + goto err; + } + + ret = wm8350->read_dev(wm8350, WM8350_ID, sizeof(id2), &id2); + if (ret != 0) { + dev_err(wm8350->dev, "Failed to read ID: %d\n", ret); + goto err; + } + + ret = wm8350->read_dev(wm8350, WM8350_REVISION, sizeof(mask_rev), + &mask_rev); + if (ret != 0) { + dev_err(wm8350->dev, "Failed to read revision: %d\n", ret); + goto err; + } id1 = be16_to_cpu(id1); id2 = be16_to_cpu(id2); -- cgit From a39a021fd73ce06aad8d1081ac711a36930e6cb8 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 4 Feb 2009 21:10:58 +0100 Subject: mfd: Mark WM835x USB_SLV_500MA bit as accessible The code is out of sync with the silicon. Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/wm8350-regmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/wm8350-regmap.c b/drivers/mfd/wm8350-regmap.c index 68887b817d1..9a4cc954cb7 100644 --- a/drivers/mfd/wm8350-regmap.c +++ b/drivers/mfd/wm8350-regmap.c @@ -3188,7 +3188,7 @@ const struct wm8350_reg_access wm8350_reg_io_map[] = { { 0x7CFF, 0x0C00, 0x7FFF }, /* R1 - ID */ { 0x0000, 0x0000, 0x0000 }, /* R2 */ { 0xBE3B, 0xBE3B, 0x8000 }, /* R3 - System Control 1 */ - { 0xFCF7, 0xFCF7, 0xF800 }, /* R4 - System Control 2 */ + { 0xFEF7, 0xFEF7, 0xF800 }, /* R4 - System Control 2 */ { 0x80FF, 0x80FF, 0x8000 }, /* R5 - System Hibernate */ { 0xFB0E, 0xFB0E, 0x0000 }, /* R6 - Interface Control */ { 0x0000, 0x0000, 0x0000 }, /* R7 */ -- cgit From 29c6a2e6f88225ae2673aabd2de0fa2126653231 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Wed, 4 Feb 2009 21:23:22 +0100 Subject: mfd: wm8350 tries reaches -1 With a postfix decrement tries will reach -1 rather than 0, so the warning will not be issued even upon timeout. Signed-off-by: Roel Kluin Acked-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/wm8350-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c index e5e82c7cc52..ea380183317 100644 --- a/drivers/mfd/wm8350-core.c +++ b/drivers/mfd/wm8350-core.c @@ -1111,7 +1111,7 @@ int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref) do { schedule_timeout_interruptible(1); reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1); - } while (tries-- && (reg & WM8350_AUXADC_POLL)); + } while (--tries && (reg & WM8350_AUXADC_POLL)); if (!tries) dev_err(wm8350->dev, "adc chn %d read timeout\n", channel); -- cgit From a313d758cc7956d7f1e7a727c8fa571b6468fabf Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 4 Feb 2009 21:26:07 +0100 Subject: mfd: Fix TWL4030 build on some ARM variants Many ARM platforms do not provide a mach/cpu.h so rather than guarding the use of that header with CONFIG_ARM guard it with the guards used when testing for the OMAP variants in the body of the code. Signed-off-by: Mark Brown Acked-by: David Brownell Signed-off-by: Samuel Ortiz --- drivers/mfd/twl4030-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/twl4030-core.c b/drivers/mfd/twl4030-core.c index e7ab0035d30..68826f1e36b 100644 --- a/drivers/mfd/twl4030-core.c +++ b/drivers/mfd/twl4030-core.c @@ -38,7 +38,7 @@ #include #include -#ifdef CONFIG_ARM +#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) #include #endif -- cgit From 9427c34bc72f05b519e8466f27c38a3327bae157 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 4 Feb 2009 21:27:48 +0100 Subject: mfd: fix htc-egpio iomem resource handling using resource_size Fixes an off-by-one error in the iomem resource mapping. Signed-off-by: Philipp Zabel Signed-off-by: Samuel Ortiz --- drivers/mfd/htc-egpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/htc-egpio.c b/drivers/mfd/htc-egpio.c index 194df7b8256..aa266e1f69b 100644 --- a/drivers/mfd/htc-egpio.c +++ b/drivers/mfd/htc-egpio.c @@ -286,7 +286,7 @@ static int __init egpio_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) goto fail; - ei->base_addr = ioremap_nocache(res->start, res->end - res->start); + ei->base_addr = ioremap_nocache(res->start, resource_size(res)); if (!ei->base_addr) goto fail; pr_debug("EGPIO phys=%08x virt=%p\n", (u32)res->start, ei->base_addr); -- cgit From 2f161f4485535df85451a8cfdf2487c315f665f5 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 6 Feb 2009 15:28:15 +0100 Subject: mfd: Ensure all WM8350 IRQs are masked at startup The IRQs might have been left enabled in hardware, generating spurious IRQs before the drivers have registered. Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/wm8350-core.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c index ea380183317..84d5ea1ec17 100644 --- a/drivers/mfd/wm8350-core.c +++ b/drivers/mfd/wm8350-core.c @@ -1419,6 +1419,13 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq, return ret; } + wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0xFFFF); + wm8350_reg_write(wm8350, WM8350_INT_STATUS_1_MASK, 0xFFFF); + wm8350_reg_write(wm8350, WM8350_INT_STATUS_2_MASK, 0xFFFF); + wm8350_reg_write(wm8350, WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, 0xFFFF); + wm8350_reg_write(wm8350, WM8350_GPIO_INT_STATUS_MASK, 0xFFFF); + wm8350_reg_write(wm8350, WM8350_COMPARATOR_INT_STATUS_MASK, 0xFFFF); + mutex_init(&wm8350->auxadc_mutex); mutex_init(&wm8350->irq_mutex); INIT_WORK(&wm8350->irq_work, wm8350_irq_worker); -- cgit From 8915e5402809ae6228e15c76417351dad752826e Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 17 Feb 2009 09:07:02 +0100 Subject: mfd: terminate pcf50633 i2c_device_id list The i2c_device_id list is supposed to be zero-terminated. Signed-off-by: Jean Delvare Cc: Balaji Rao Signed-off-by: Samuel Ortiz Signed-off-by: Andrew Morton --- drivers/mfd/pcf50633-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index ea9488e7ad6..2e36057659e 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c @@ -678,6 +678,7 @@ static int __devexit pcf50633_remove(struct i2c_client *client) static struct i2c_device_id pcf50633_id_table[] = { {"pcf50633", 0x73}, + {/* end of list */} }; static struct i2c_driver pcf50633_driver = { -- cgit From 158abca5f699a047ff7b67a64ab19e8ec824e37d Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Tue, 17 Feb 2009 09:10:19 +0100 Subject: mfd: fix sm501 section mismatches drv => driver renaming is needed otherwise modpost will spit false positives re pointing to __devinit function from regular data. Signed-off-by: Alexey Dobriyan Cc: Ben Dooks Signed-off-by: Andrew Morton Signed-off-by: Samuel Ortiz --- drivers/mfd/sm501.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index 0e5761f1263..6c3786f8e9a 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c @@ -1321,7 +1321,7 @@ static unsigned int sm501_mem_local[] = { * Common init code for an SM501 */ -static int sm501_init_dev(struct sm501_devdata *sm) +static int __devinit sm501_init_dev(struct sm501_devdata *sm) { struct sm501_initdata *idata; struct sm501_platdata *pdata; @@ -1397,7 +1397,7 @@ static int sm501_init_dev(struct sm501_devdata *sm) return 0; } -static int sm501_plat_probe(struct platform_device *dev) +static int __devinit sm501_plat_probe(struct platform_device *dev) { struct sm501_devdata *sm; int ret; @@ -1586,8 +1586,8 @@ static struct sm501_platdata sm501_pci_platdata = { .gpio_base = -1, }; -static int sm501_pci_probe(struct pci_dev *dev, - const struct pci_device_id *id) +static int __devinit sm501_pci_probe(struct pci_dev *dev, + const struct pci_device_id *id) { struct sm501_devdata *sm; int err; @@ -1693,7 +1693,7 @@ static void sm501_dev_remove(struct sm501_devdata *sm) sm501_gpio_remove(sm); } -static void sm501_pci_remove(struct pci_dev *dev) +static void __devexit sm501_pci_remove(struct pci_dev *dev) { struct sm501_devdata *sm = pci_get_drvdata(dev); @@ -1727,16 +1727,16 @@ static struct pci_device_id sm501_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, sm501_pci_tbl); -static struct pci_driver sm501_pci_drv = { +static struct pci_driver sm501_pci_driver = { .name = "sm501", .id_table = sm501_pci_tbl, .probe = sm501_pci_probe, - .remove = sm501_pci_remove, + .remove = __devexit_p(sm501_pci_remove), }; MODULE_ALIAS("platform:sm501"); -static struct platform_driver sm501_plat_drv = { +static struct platform_driver sm501_plat_driver = { .driver = { .name = "sm501", .owner = THIS_MODULE, @@ -1749,14 +1749,14 @@ static struct platform_driver sm501_plat_drv = { static int __init sm501_base_init(void) { - platform_driver_register(&sm501_plat_drv); - return pci_register_driver(&sm501_pci_drv); + platform_driver_register(&sm501_plat_driver); + return pci_register_driver(&sm501_pci_driver); } static void __exit sm501_base_exit(void) { - platform_driver_unregister(&sm501_plat_drv); - pci_unregister_driver(&sm501_pci_drv); + platform_driver_unregister(&sm501_plat_driver); + pci_unregister_driver(&sm501_pci_driver); } module_init(sm501_base_init); -- cgit From dcd9651ecd652a186dd9ad0dde76d43320b9c0a2 Mon Sep 17 00:00:00 2001 From: Rakib Mullick Date: Tue, 17 Feb 2009 09:21:52 +0100 Subject: mfd: Fix sm501_register_gpio section mismatch WARNING: drivers/mfd/built-in.o(.text+0x1706): Section mismatch in reference from the function sm501_register_gpio() to the function .devinit.text:sm501_gpio_register_chip() The function sm501_register_gpio() references the function __devinit sm501_gpio_register_chip(). This is often because sm501_register_gpio lacks a __devinit annotation or the annotation of sm501_gpio_register_chip is wrong. Signed-off-by: Rakib Mullick Signed-off-by: Samuel Ortiz --- drivers/mfd/sm501.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index 6c3786f8e9a..4c7b7962f6b 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c @@ -1050,7 +1050,7 @@ static int __devinit sm501_gpio_register_chip(struct sm501_devdata *sm, return gpiochip_add(gchip); } -static int sm501_register_gpio(struct sm501_devdata *sm) +static int __devinit sm501_register_gpio(struct sm501_devdata *sm) { struct sm501_gpio *gpio = &sm->gpio; resource_size_t iobase = sm->io_res->start + SM501_GPIO; -- cgit From ee8b53c1cfe33aecf0c77c0aa3ce437f0d84d831 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 17 Feb 2009 12:20:13 +0100 Subject: x86: remove stale arch/x86/include/asm/page_64.h.rej file Introduced by: 51c78eb: x86: create _types.h counterparts for page*.h Cc: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar --- arch/x86/include/asm/page_64.h.rej | 114 ------------------------------------- 1 file changed, 114 deletions(-) delete mode 100644 arch/x86/include/asm/page_64.h.rej diff --git a/arch/x86/include/asm/page_64.h.rej b/arch/x86/include/asm/page_64.h.rej deleted file mode 100644 index 9b1807f1859..00000000000 --- a/arch/x86/include/asm/page_64.h.rej +++ /dev/null @@ -1,114 +0,0 @@ -*************** -*** 1,105 **** - #ifndef _ASM_X86_PAGE_64_H - #define _ASM_X86_PAGE_64_H - -- #define PAGETABLE_LEVELS 4 -- -- #define THREAD_ORDER 1 -- #define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) -- #define CURRENT_MASK (~(THREAD_SIZE - 1)) -- -- #define EXCEPTION_STACK_ORDER 0 -- #define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER) -- -- #define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 1) -- #define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER) -- -- #define IRQSTACK_ORDER 2 -- #define IRQSTACKSIZE (PAGE_SIZE << IRQSTACK_ORDER) -- -- #define STACKFAULT_STACK 1 -- #define DOUBLEFAULT_STACK 2 -- #define NMI_STACK 3 -- #define DEBUG_STACK 4 -- #define MCE_STACK 5 -- #define N_EXCEPTION_STACKS 5 /* hw limit: 7 */ -- -- #define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT) -- #define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1)) -- -- /* -- * Set __PAGE_OFFSET to the most negative possible address + -- * PGDIR_SIZE*16 (pgd slot 272). The gap is to allow a space for a -- * hypervisor to fit. Choosing 16 slots here is arbitrary, but it's -- * what Xen requires. -- */ -- #define __PAGE_OFFSET _AC(0xffff880000000000, UL) -- -- #define __PHYSICAL_START CONFIG_PHYSICAL_START -- #define __KERNEL_ALIGN 0x200000 -- -- /* -- * Make sure kernel is aligned to 2MB address. Catching it at compile -- * time is better. Change your config file and compile the kernel -- * for a 2MB aligned address (CONFIG_PHYSICAL_START) -- */ -- #if (CONFIG_PHYSICAL_START % __KERNEL_ALIGN) != 0 -- #error "CONFIG_PHYSICAL_START must be a multiple of 2MB" -- #endif -- -- #define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START) -- #define __START_KERNEL_map _AC(0xffffffff80000000, UL) -- -- /* See Documentation/x86_64/mm.txt for a description of the memory map. */ -- #define __PHYSICAL_MASK_SHIFT 46 -- #define __VIRTUAL_MASK_SHIFT 48 -- -- /* -- * Kernel image size is limited to 512 MB (see level2_kernel_pgt in -- * arch/x86/kernel/head_64.S), and it is mapped here: -- */ -- #define KERNEL_IMAGE_SIZE (512 * 1024 * 1024) -- #define KERNEL_IMAGE_START _AC(0xffffffff80000000, UL) -- -- #ifndef __ASSEMBLY__ -- void clear_page(void *page); -- void copy_page(void *to, void *from); -- -- /* duplicated to the one in bootmem.h */ -- extern unsigned long max_pfn; -- extern unsigned long phys_base; -- -- extern unsigned long __phys_addr(unsigned long); -- #define __phys_reloc_hide(x) (x) -- -- /* -- * These are used to make use of C type-checking.. -- */ -- typedef unsigned long pteval_t; -- typedef unsigned long pmdval_t; -- typedef unsigned long pudval_t; -- typedef unsigned long pgdval_t; -- typedef unsigned long pgprotval_t; -- -- typedef struct page *pgtable_t; -- -- typedef struct { pteval_t pte; } pte_t; -- -- #define vmemmap ((struct page *)VMEMMAP_START) -- -- extern unsigned long init_memory_mapping(unsigned long start, -- unsigned long end); -- -- extern void initmem_init(unsigned long start_pfn, unsigned long end_pfn); -- extern void free_initmem(void); -- -- extern void init_extra_mapping_uc(unsigned long phys, unsigned long size); -- extern void init_extra_mapping_wb(unsigned long phys, unsigned long size); -- -- #endif /* !__ASSEMBLY__ */ -- -- #ifdef CONFIG_FLATMEM -- #define pfn_valid(pfn) ((pfn) < max_pfn) -- #endif -- - - #endif /* _ASM_X86_PAGE_64_H */ ---- 1,6 ---- - #ifndef _ASM_X86_PAGE_64_H - #define _ASM_X86_PAGE_64_H - -+ #include - - #endif /* _ASM_X86_PAGE_64_H */ -- cgit From 06cd9a7dc8a58186060a91b6ddc031057435fd34 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 16 Feb 2009 17:29:58 -0800 Subject: x86: add x2apic config Impact: cleanup so could deselect x2apic and INTR_REMAP will select x2apic Signed-off-by: Yinghai Lu Cc: Andrew Morton Signed-off-by: Ingo Molnar --- arch/x86/Kconfig | 15 +++++++++++++++ arch/x86/include/asm/apic.h | 18 +++++++++++++++--- arch/x86/kernel/Makefile | 4 ++-- arch/x86/kernel/apic.c | 24 ++++++++++++------------ arch/x86/kernel/cpu/common.c | 2 +- arch/x86/kernel/genapic_64.c | 4 ++++ arch/x86/kernel/setup.c | 3 +-- arch/x86/kernel/smpboot.c | 2 +- 8 files changed, 51 insertions(+), 21 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 1042d69b267..bce241fe1d2 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -235,6 +235,20 @@ config SMP If you don't know what to do here, say N. +config X86_X2APIC + bool "Support x2apic" + depends on X86_LOCAL_APIC && X86_64 + ---help--- + This enables x2apic support on CPUs that have this feature. + + This allows 32-bit apic IDs (so it can support very large systems), + and accesses the local apic via MSRs not via mmio. + + ( On certain CPU models you may need to enable INTR_REMAP too, + to get functional x2apic mode. ) + + If you don't know what to do here, say N. + config SPARSE_IRQ bool "Support sparse irq numbering" depends on PCI_MSI || HT_IRQ @@ -1828,6 +1842,7 @@ config DMAR_FLOPPY_WA config INTR_REMAP bool "Support for Interrupt Remapping (EXPERIMENTAL)" depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI && EXPERIMENTAL + select X86_X2APIC ---help--- Supports Interrupt remapping for IO-APIC and MSI devices. To use x2apic mode in the CPU's which support x2APIC enhancements or diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index fba49f66228..dc1db99cd40 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -112,7 +112,7 @@ static inline u32 native_apic_msr_read(u32 reg) return low; } -#ifndef CONFIG_X86_32 +#ifdef CONFIG_X86_X2APIC extern int x2apic; extern void check_x2apic(void); extern void enable_x2apic(void); @@ -131,7 +131,19 @@ static inline int x2apic_enabled(void) return 0; } #else -#define x2apic_enabled() 0 +static inline void check_x2apic(void) +{ +} +static inline void enable_x2apic(void) +{ +} +static inline void enable_IR_x2apic(void) +{ +} +static inline int x2apic_enabled(void) +{ + return 0; +} #endif struct apic_ops { @@ -177,7 +189,7 @@ static inline u32 safe_apic_wait_icr_idle(void) extern int get_physical_broadcast(void); -#ifdef CONFIG_X86_64 +#ifdef CONFIG_X86_X2APIC static inline void ack_x2APIC_irq(void) { /* Docs say use 0 for future compatibility */ diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 24f357e7557..1cefd218f76 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -117,8 +117,8 @@ obj-$(CONFIG_SWIOTLB) += pci-swiotlb_64.o # NB rename without _64 # 64 bit specific files ifeq ($(CONFIG_X86_64),y) obj-y += genapic_64.o genapic_flat_64.o - obj-y += genx2apic_cluster.o - obj-y += genx2apic_phys.o + obj-$(CONFIG_X86_X2APIC) += genx2apic_cluster.o + obj-$(CONFIG_X86_X2APIC) += genx2apic_phys.o obj-$(CONFIG_X86_UV) += genx2apic_uv_x.o tlb_uv.o obj-$(CONFIG_X86_UV) += bios_uv.o uv_irq.o uv_sysfs.o obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c index a894eea9d51..004aa1c31e4 100644 --- a/arch/x86/kernel/apic.c +++ b/arch/x86/kernel/apic.c @@ -112,11 +112,7 @@ static __init int setup_apicpmtimer(char *s) __setup("apicpmtimer", setup_apicpmtimer); #endif -#ifdef CONFIG_X86_64 -#define HAVE_X2APIC -#endif - -#ifdef HAVE_X2APIC +#ifdef CONFIG_X86_X2APIC int x2apic; /* x2apic enabled before OS handover */ static int x2apic_preenabled; @@ -269,7 +265,7 @@ static struct apic_ops xapic_ops = { struct apic_ops __read_mostly *apic_ops = &xapic_ops; EXPORT_SYMBOL_GPL(apic_ops); -#ifdef HAVE_X2APIC +#ifdef CONFIG_X86_X2APIC static void x2apic_wait_icr_idle(void) { /* no need to wait for icr idle in x2apic */ @@ -1320,11 +1316,14 @@ void __cpuinit end_local_APIC_setup(void) apic_pm_activate(); } -#ifdef HAVE_X2APIC +#ifdef CONFIG_X86_X2APIC void check_x2apic(void) { int msr, msr2; + if (!cpu_has_x2apic) + return; + rdmsr(MSR_IA32_APICBASE, msr, msr2); if (msr & X2APIC_ENABLE) { @@ -1338,6 +1337,9 @@ void enable_x2apic(void) { int msr, msr2; + if (!x2apic) + return; + rdmsr(MSR_IA32_APICBASE, msr, msr2); if (!(msr & X2APIC_ENABLE)) { pr_info("Enabling x2apic\n"); @@ -1439,7 +1441,7 @@ end: return; } -#endif /* HAVE_X2APIC */ +#endif /* CONFIG_X86_X2APIC */ #ifdef CONFIG_X86_64 /* @@ -1570,7 +1572,7 @@ void __init early_init_lapic_mapping(void) */ void __init init_apic_mappings(void) { -#ifdef HAVE_X2APIC +#ifdef CONFIG_X86_X2APIC if (x2apic) { boot_cpu_physical_apicid = read_apic_id(); return; @@ -1634,9 +1636,7 @@ int __init APIC_init_uniprocessor(void) } #endif -#ifdef HAVE_X2APIC enable_IR_x2apic(); -#endif #ifdef CONFIG_X86_64 default_setup_apic_routing(); #endif @@ -2021,7 +2021,7 @@ static int lapic_resume(struct sys_device *dev) local_irq_save(flags); -#ifdef HAVE_X2APIC +#ifdef CONFIG_X86_X2APIC if (x2apic) enable_x2apic(); else diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 4db150ed446..4b5d13e472d 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1051,7 +1051,7 @@ void __cpuinit cpu_init(void) barrier(); check_efer(); - if (cpu != 0 && x2apic) + if (cpu != 0) enable_x2apic(); /* diff --git a/arch/x86/kernel/genapic_64.c b/arch/x86/kernel/genapic_64.c index 820dea5d0eb..cdc4772d9c8 100644 --- a/arch/x86/kernel/genapic_64.c +++ b/arch/x86/kernel/genapic_64.c @@ -35,8 +35,10 @@ static struct genapic *apic_probe[] __initdata = { #ifdef CONFIG_X86_UV &apic_x2apic_uv_x, #endif +#ifdef CONFIG_X86_X2APIC &apic_x2apic_phys, &apic_x2apic_cluster, +#endif &apic_physflat, NULL, }; @@ -46,10 +48,12 @@ static struct genapic *apic_probe[] __initdata = { */ void __init default_setup_apic_routing(void) { +#ifdef CONFIG_X86_X2APIC if (apic == &apic_x2apic_phys || apic == &apic_x2apic_cluster) { if (!intr_remapping_enabled) apic = &apic_flat; } +#endif if (apic == &apic_flat) { if (max_physical_apicid >= 8) diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 8fce6c71451..43d964411c0 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -836,8 +836,7 @@ void __init setup_arch(char **cmdline_p) #else num_physpages = max_pfn; - if (cpu_has_x2apic) - check_x2apic(); + check_x2apic(); /* How many end-of-memory variables you have, grandma! */ /* need this before calling reserve_initrd */ diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 10834954e30..b5f2b698973 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -1128,8 +1128,8 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) current_thread_info()->cpu = 0; /* needed? */ set_cpu_sibling_map(0); -#ifdef CONFIG_X86_64 enable_IR_x2apic(); +#ifdef CONFIG_X86_64 default_setup_apic_routing(); #endif -- cgit From c1eeb2de41d7015678bdd412b48a5f071b84e29a Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 16 Feb 2009 23:02:14 -0800 Subject: x86: fold apic_ops into genapic Impact: cleanup make it simpler, don't need have one extra struct. v2: fix the sgi_uv build Signed-off-by: Yinghai Lu Cc: Andrew Morton Signed-off-by: Ingo Molnar --- arch/x86/include/asm/apic.h | 97 ++++++++++--------------------- arch/x86/include/asm/genapic.h | 61 +++++++++++++++++++ arch/x86/kernel/apic.c | 63 ++------------------ arch/x86/kernel/bigsmp_32.c | 7 +++ arch/x86/kernel/cpu/mcheck/mce_amd_64.c | 2 +- arch/x86/kernel/cpu/mcheck/mce_intel_64.c | 2 +- arch/x86/kernel/cpu/perfctr-watchdog.c | 2 +- arch/x86/kernel/es7000_32.c | 7 +++ arch/x86/kernel/genapic_64.c | 2 +- arch/x86/kernel/genapic_flat_64.c | 16 ++++- arch/x86/kernel/genx2apic_cluster.c | 11 +++- arch/x86/kernel/genx2apic_phys.c | 11 +++- arch/x86/kernel/genx2apic_uv_x.c | 9 ++- arch/x86/kernel/ipi.c | 2 +- arch/x86/kernel/irq.c | 2 +- arch/x86/kernel/nmi.c | 2 +- arch/x86/kernel/numaq_32.c | 7 +++ arch/x86/kernel/probe_32.c | 7 +++ arch/x86/kernel/summit_32.c | 7 +++ arch/x86/kernel/uv_irq.c | 2 +- arch/x86/kernel/vmi_32.c | 6 +- arch/x86/kernel/vmiclock_32.c | 2 +- arch/x86/lguest/boot.c | 19 +++--- arch/x86/xen/enlighten.c | 21 +++---- 24 files changed, 205 insertions(+), 162 deletions(-) diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index dc1db99cd40..4f56e053d34 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -92,6 +92,12 @@ static inline u32 native_apic_mem_read(u32 reg) return *((volatile u32 *)(APIC_BASE + reg)); } +extern void native_apic_wait_icr_idle(void); +extern u32 native_safe_apic_wait_icr_idle(void); +extern void native_apic_icr_write(u32 low, u32 id); +extern u64 native_apic_icr_read(void); + +#ifdef CONFIG_X86_X2APIC static inline void native_apic_msr_write(u32 reg, u32 v) { if (reg == APIC_DFR || reg == APIC_ID || reg == APIC_LDR || @@ -112,7 +118,31 @@ static inline u32 native_apic_msr_read(u32 reg) return low; } -#ifdef CONFIG_X86_X2APIC +static inline void native_x2apic_wait_icr_idle(void) +{ + /* no need to wait for icr idle in x2apic */ + return; +} + +static inline u32 native_safe_x2apic_wait_icr_idle(void) +{ + /* no need to wait for icr idle in x2apic */ + return 0; +} + +static inline void native_x2apic_icr_write(u32 low, u32 id) +{ + wrmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), ((__u64) id) << 32 | low); +} + +static inline u64 native_x2apic_icr_read(void) +{ + unsigned long val; + + rdmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), val); + return val; +} + extern int x2apic; extern void check_x2apic(void); extern void enable_x2apic(void); @@ -146,47 +176,6 @@ static inline int x2apic_enabled(void) } #endif -struct apic_ops { - u32 (*read)(u32 reg); - void (*write)(u32 reg, u32 v); - u64 (*icr_read)(void); - void (*icr_write)(u32 low, u32 high); - void (*wait_icr_idle)(void); - u32 (*safe_wait_icr_idle)(void); -}; - -extern struct apic_ops *apic_ops; - -static inline u32 apic_read(u32 reg) -{ - return apic_ops->read(reg); -} - -static inline void apic_write(u32 reg, u32 val) -{ - apic_ops->write(reg, val); -} - -static inline u64 apic_icr_read(void) -{ - return apic_ops->icr_read(); -} - -static inline void apic_icr_write(u32 low, u32 high) -{ - apic_ops->icr_write(low, high); -} - -static inline void apic_wait_icr_idle(void) -{ - apic_ops->wait_icr_idle(); -} - -static inline u32 safe_apic_wait_icr_idle(void) -{ - return apic_ops->safe_wait_icr_idle(); -} - extern int get_physical_broadcast(void); #ifdef CONFIG_X86_X2APIC @@ -197,18 +186,6 @@ static inline void ack_x2APIC_irq(void) } #endif - -static inline void ack_APIC_irq(void) -{ - /* - * ack_APIC_irq() actually gets compiled as a single instruction - * ... yummie. - */ - - /* Docs say use 0 for future compatibility */ - apic_write(APIC_EOI, 0); -} - extern int lapic_get_maxlvt(void); extern void clear_local_APIC(void); extern void connect_bsp_APIC(void); @@ -256,18 +233,6 @@ static inline void disable_local_APIC(void) { } #define SET_APIC_ID(x) (apic->set_apic_id(x)) #else -#ifdef CONFIG_X86_LOCAL_APIC -static inline unsigned default_get_apic_id(unsigned long x) -{ - unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR)); - - if (APIC_XAPIC(ver)) - return (x >> 24) & 0xFF; - else - return (x >> 24) & 0x0F; -} -#endif - #endif #endif /* _ASM_X86_APIC_H */ diff --git a/arch/x86/include/asm/genapic.h b/arch/x86/include/asm/genapic.h index 273b99452ae..a6d0b00a544 100644 --- a/arch/x86/include/asm/genapic.h +++ b/arch/x86/include/asm/genapic.h @@ -5,6 +5,7 @@ #include #include +#include /* * Copyright 2004 James Cleverdon, IBM. @@ -83,10 +84,70 @@ struct genapic { void (*smp_callin_clear_local_apic)(void); void (*store_NMI_vector)(unsigned short *high, unsigned short *low); void (*inquire_remote_apic)(int apicid); + + /* apic ops */ + u32 (*read)(u32 reg); + void (*write)(u32 reg, u32 v); + u64 (*icr_read)(void); + void (*icr_write)(u32 low, u32 high); + void (*wait_icr_idle)(void); + u32 (*safe_wait_icr_idle)(void); }; extern struct genapic *apic; +static inline u32 apic_read(u32 reg) +{ + return apic->read(reg); +} + +static inline void apic_write(u32 reg, u32 val) +{ + apic->write(reg, val); +} + +static inline u64 apic_icr_read(void) +{ + return apic->icr_read(); +} + +static inline void apic_icr_write(u32 low, u32 high) +{ + apic->icr_write(low, high); +} + +static inline void apic_wait_icr_idle(void) +{ + apic->wait_icr_idle(); +} + +static inline u32 safe_apic_wait_icr_idle(void) +{ + return apic->safe_wait_icr_idle(); +} + + +static inline void ack_APIC_irq(void) +{ + /* + * ack_APIC_irq() actually gets compiled as a single instruction + * ... yummie. + */ + + /* Docs say use 0 for future compatibility */ + apic_write(APIC_EOI, 0); +} + +static inline unsigned default_get_apic_id(unsigned long x) +{ + unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR)); + + if (APIC_XAPIC(ver)) + return (x >> 24) & 0xFF; + else + return (x >> 24) & 0x0F; +} + /* * Warm reset vector default position: */ diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c index 004aa1c31e4..af494bad885 100644 --- a/arch/x86/kernel/apic.c +++ b/arch/x86/kernel/apic.c @@ -210,18 +210,13 @@ static int modern_apic(void) return lapic_get_version() >= 0x14; } -/* - * Paravirt kernels also might be using these below ops. So we still - * use generic apic_read()/apic_write(), which might be pointing to different - * ops in PARAVIRT case. - */ -void xapic_wait_icr_idle(void) +void native_apic_wait_icr_idle(void) { while (apic_read(APIC_ICR) & APIC_ICR_BUSY) cpu_relax(); } -u32 safe_xapic_wait_icr_idle(void) +u32 native_safe_apic_wait_icr_idle(void) { u32 send_status; int timeout; @@ -237,13 +232,13 @@ u32 safe_xapic_wait_icr_idle(void) return send_status; } -void xapic_icr_write(u32 low, u32 id) +void native_apic_icr_write(u32 low, u32 id) { apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(id)); apic_write(APIC_ICR, low); } -static u64 xapic_icr_read(void) +u64 native_apic_icr_read(void) { u32 icr1, icr2; @@ -253,54 +248,6 @@ static u64 xapic_icr_read(void) return icr1 | ((u64)icr2 << 32); } -static struct apic_ops xapic_ops = { - .read = native_apic_mem_read, - .write = native_apic_mem_write, - .icr_read = xapic_icr_read, - .icr_write = xapic_icr_write, - .wait_icr_idle = xapic_wait_icr_idle, - .safe_wait_icr_idle = safe_xapic_wait_icr_idle, -}; - -struct apic_ops __read_mostly *apic_ops = &xapic_ops; -EXPORT_SYMBOL_GPL(apic_ops); - -#ifdef CONFIG_X86_X2APIC -static void x2apic_wait_icr_idle(void) -{ - /* no need to wait for icr idle in x2apic */ - return; -} - -static u32 safe_x2apic_wait_icr_idle(void) -{ - /* no need to wait for icr idle in x2apic */ - return 0; -} - -void x2apic_icr_write(u32 low, u32 id) -{ - wrmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), ((__u64) id) << 32 | low); -} - -static u64 x2apic_icr_read(void) -{ - unsigned long val; - - rdmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), val); - return val; -} - -static struct apic_ops x2apic_ops = { - .read = native_apic_msr_read, - .write = native_apic_msr_write, - .icr_read = x2apic_icr_read, - .icr_write = x2apic_icr_write, - .wait_icr_idle = x2apic_wait_icr_idle, - .safe_wait_icr_idle = safe_x2apic_wait_icr_idle, -}; -#endif - /** * enable_NMI_through_LVT0 - enable NMI through local vector table 0 */ @@ -1329,7 +1276,6 @@ void check_x2apic(void) if (msr & X2APIC_ENABLE) { pr_info("x2apic enabled by BIOS, switching to x2apic ops\n"); x2apic_preenabled = x2apic = 1; - apic_ops = &x2apic_ops; } } @@ -1403,7 +1349,6 @@ void __init enable_IR_x2apic(void) if (!x2apic) { x2apic = 1; - apic_ops = &x2apic_ops; enable_x2apic(); } diff --git a/arch/x86/kernel/bigsmp_32.c b/arch/x86/kernel/bigsmp_32.c index 47a62f46afd..9eeb714c5de 100644 --- a/arch/x86/kernel/bigsmp_32.c +++ b/arch/x86/kernel/bigsmp_32.c @@ -263,4 +263,11 @@ struct genapic apic_bigsmp = { .smp_callin_clear_local_apic = NULL, .store_NMI_vector = NULL, .inquire_remote_apic = default_inquire_remote_apic, + + .read = native_apic_mem_read, + .write = native_apic_mem_write, + .icr_read = native_apic_icr_read, + .icr_write = native_apic_icr_write, + .wait_icr_idle = native_apic_wait_icr_idle, + .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, }; diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c index 4772e91e824..e22d6ed26e6 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c index 5e8c79e748a..42f090702f0 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c index 9abd48b2267..f6c70a164e3 100644 --- a/arch/x86/kernel/cpu/perfctr-watchdog.c +++ b/arch/x86/kernel/cpu/perfctr-watchdog.c @@ -19,7 +19,7 @@ #include #include -#include +#include #include struct nmi_watchdog_ctlblk { diff --git a/arch/x86/kernel/es7000_32.c b/arch/x86/kernel/es7000_32.c index 55515d73d9c..23f1df4ce18 100644 --- a/arch/x86/kernel/es7000_32.c +++ b/arch/x86/kernel/es7000_32.c @@ -806,4 +806,11 @@ struct genapic apic_es7000 = { .smp_callin_clear_local_apic = NULL, .store_NMI_vector = NULL, .inquire_remote_apic = default_inquire_remote_apic, + + .read = native_apic_mem_read, + .write = native_apic_mem_write, + .icr_read = native_apic_icr_read, + .icr_write = native_apic_icr_write, + .wait_icr_idle = native_apic_wait_icr_idle, + .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, }; diff --git a/arch/x86/kernel/genapic_64.c b/arch/x86/kernel/genapic_64.c index cdc4772d9c8..70b616b4c62 100644 --- a/arch/x86/kernel/genapic_64.c +++ b/arch/x86/kernel/genapic_64.c @@ -19,8 +19,8 @@ #include #include -#include #include +#include #include extern struct genapic apic_flat; diff --git a/arch/x86/kernel/genapic_flat_64.c b/arch/x86/kernel/genapic_flat_64.c index 249d2d3c034..36ee760fd13 100644 --- a/arch/x86/kernel/genapic_flat_64.c +++ b/arch/x86/kernel/genapic_flat_64.c @@ -17,8 +17,8 @@ #include #include #include -#include #include +#include #ifdef CONFIG_ACPI #include @@ -229,6 +229,13 @@ struct genapic apic_flat = { .smp_callin_clear_local_apic = NULL, .store_NMI_vector = NULL, .inquire_remote_apic = NULL, + + .read = native_apic_mem_read, + .write = native_apic_mem_write, + .icr_read = native_apic_icr_read, + .icr_write = native_apic_icr_write, + .wait_icr_idle = native_apic_wait_icr_idle, + .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, }; /* @@ -374,4 +381,11 @@ struct genapic apic_physflat = { .smp_callin_clear_local_apic = NULL, .store_NMI_vector = NULL, .inquire_remote_apic = NULL, + + .read = native_apic_mem_read, + .write = native_apic_mem_write, + .icr_read = native_apic_icr_read, + .icr_write = native_apic_icr_write, + .wait_icr_idle = native_apic_wait_icr_idle, + .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, }; diff --git a/arch/x86/kernel/genx2apic_cluster.c b/arch/x86/kernel/genx2apic_cluster.c index 7c87156b641..dd6e8d68542 100644 --- a/arch/x86/kernel/genx2apic_cluster.c +++ b/arch/x86/kernel/genx2apic_cluster.c @@ -7,8 +7,8 @@ #include #include -#include #include +#include DEFINE_PER_CPU(u32, x86_cpu_to_logical_apicid); @@ -46,7 +46,7 @@ static void /* * send the IPI. */ - x2apic_icr_write(cfg, apicid); + native_x2apic_icr_write(cfg, apicid); } /* @@ -234,4 +234,11 @@ struct genapic apic_x2apic_cluster = { .smp_callin_clear_local_apic = NULL, .store_NMI_vector = NULL, .inquire_remote_apic = NULL, + + .read = native_apic_msr_read, + .write = native_apic_msr_write, + .icr_read = native_x2apic_icr_read, + .icr_write = native_x2apic_icr_write, + .wait_icr_idle = native_x2apic_wait_icr_idle, + .safe_wait_icr_idle = native_safe_x2apic_wait_icr_idle, }; diff --git a/arch/x86/kernel/genx2apic_phys.c b/arch/x86/kernel/genx2apic_phys.c index 5cbae8aa040..eb1486bb002 100644 --- a/arch/x86/kernel/genx2apic_phys.c +++ b/arch/x86/kernel/genx2apic_phys.c @@ -7,8 +7,8 @@ #include #include -#include #include +#include static int x2apic_phys; @@ -50,7 +50,7 @@ static void __x2apic_send_IPI_dest(unsigned int apicid, int vector, /* * send the IPI. */ - x2apic_icr_write(cfg, apicid); + native_x2apic_icr_write(cfg, apicid); } static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector) @@ -220,4 +220,11 @@ struct genapic apic_x2apic_phys = { .smp_callin_clear_local_apic = NULL, .store_NMI_vector = NULL, .inquire_remote_apic = NULL, + + .read = native_apic_msr_read, + .write = native_apic_msr_write, + .icr_read = native_x2apic_icr_read, + .icr_write = native_x2apic_icr_write, + .wait_icr_idle = native_x2apic_wait_icr_idle, + .safe_wait_icr_idle = native_safe_x2apic_wait_icr_idle, }; diff --git a/arch/x86/kernel/genx2apic_uv_x.c b/arch/x86/kernel/genx2apic_uv_x.c index 89b84e004f0..9ae4a92fac8 100644 --- a/arch/x86/kernel/genx2apic_uv_x.c +++ b/arch/x86/kernel/genx2apic_uv_x.c @@ -22,8 +22,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -292,6 +292,13 @@ struct genapic apic_x2apic_uv_x = { .smp_callin_clear_local_apic = NULL, .store_NMI_vector = NULL, .inquire_remote_apic = NULL, + + .read = native_apic_msr_read, + .write = native_apic_msr_write, + .icr_read = native_x2apic_icr_read, + .icr_write = native_x2apic_icr_write, + .wait_icr_idle = native_x2apic_wait_icr_idle, + .safe_wait_icr_idle = native_safe_x2apic_wait_icr_idle, }; static __cpuinit void set_x2apic_extra_bits(int pnode) diff --git a/arch/x86/kernel/ipi.c b/arch/x86/kernel/ipi.c index dbf5445727a..1326272cae4 100644 --- a/arch/x86/kernel/ipi.c +++ b/arch/x86/kernel/ipi.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index f13ca1650aa..3957776b193 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c index bdfad80c3cf..48b9ca5e088 100644 --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c @@ -11,7 +11,7 @@ * Mikael Pettersson : PM converted to driver model. Disable/enable API. */ -#include +#include #include #include diff --git a/arch/x86/kernel/numaq_32.c b/arch/x86/kernel/numaq_32.c index 0cc41a1d255..f0f0c2f0596 100644 --- a/arch/x86/kernel/numaq_32.c +++ b/arch/x86/kernel/numaq_32.c @@ -569,4 +569,11 @@ struct genapic apic_numaq = { .smp_callin_clear_local_apic = numaq_smp_callin_clear_local_apic, .store_NMI_vector = numaq_store_NMI_vector, .inquire_remote_apic = NULL, + + .read = native_apic_mem_read, + .write = native_apic_mem_write, + .icr_read = native_apic_icr_read, + .icr_write = native_apic_icr_write, + .wait_icr_idle = native_apic_wait_icr_idle, + .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, }; diff --git a/arch/x86/kernel/probe_32.c b/arch/x86/kernel/probe_32.c index 22337b75de6..1f701caa95b 100644 --- a/arch/x86/kernel/probe_32.c +++ b/arch/x86/kernel/probe_32.c @@ -127,6 +127,13 @@ struct genapic apic_default = { .smp_callin_clear_local_apic = NULL, .store_NMI_vector = NULL, .inquire_remote_apic = default_inquire_remote_apic, + + .read = native_apic_mem_read, + .write = native_apic_mem_write, + .icr_read = native_apic_icr_read, + .icr_write = native_apic_icr_write, + .wait_icr_idle = native_apic_wait_icr_idle, + .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, }; extern struct genapic apic_numaq; diff --git a/arch/x86/kernel/summit_32.c b/arch/x86/kernel/summit_32.c index 1e733eff9b3..1cf32c325d1 100644 --- a/arch/x86/kernel/summit_32.c +++ b/arch/x86/kernel/summit_32.c @@ -599,4 +599,11 @@ struct genapic apic_summit = { .smp_callin_clear_local_apic = NULL, .store_NMI_vector = NULL, .inquire_remote_apic = default_inquire_remote_apic, + + .read = native_apic_mem_read, + .write = native_apic_mem_write, + .icr_read = native_apic_icr_read, + .icr_write = native_apic_icr_write, + .wait_icr_idle = native_apic_wait_icr_idle, + .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, }; diff --git a/arch/x86/kernel/uv_irq.c b/arch/x86/kernel/uv_irq.c index aeef529917e..75eb5ec5dd2 100644 --- a/arch/x86/kernel/uv_irq.c +++ b/arch/x86/kernel/uv_irq.c @@ -11,7 +11,7 @@ #include #include -#include +#include #include static void uv_noop(unsigned int irq) diff --git a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c index f052c84ecbe..a1c7b71dc0d 100644 --- a/arch/x86/kernel/vmi_32.c +++ b/arch/x86/kernel/vmi_32.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include @@ -798,8 +798,8 @@ static inline int __init activate_vmi(void) #endif #ifdef CONFIG_X86_LOCAL_APIC - para_fill(apic_ops->read, APICRead); - para_fill(apic_ops->write, APICWrite); + para_fill(apic->read, APICRead); + para_fill(apic->write, APICWrite); #endif /* diff --git a/arch/x86/kernel/vmiclock_32.c b/arch/x86/kernel/vmiclock_32.c index a4791ef412d..2a5e0e6a7c0 100644 --- a/arch/x86/kernel/vmiclock_32.c +++ b/arch/x86/kernel/vmiclock_32.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index da2e314f61b..bc9893f2c38 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c @@ -55,7 +55,7 @@ #include #include #include -#include +#include #include #include #include @@ -828,13 +828,14 @@ static u32 lguest_apic_safe_wait_icr_idle(void) return 0; } -static struct apic_ops lguest_basic_apic_ops = { - .read = lguest_apic_read, - .write = lguest_apic_write, - .icr_read = lguest_apic_icr_read, - .icr_write = lguest_apic_icr_write, - .wait_icr_idle = lguest_apic_wait_icr_idle, - .safe_wait_icr_idle = lguest_apic_safe_wait_icr_idle, +static void set_lguest_basic_apic_ops(void) +{ + apic->read = lguest_apic_read; + apic->write = lguest_apic_write; + apic->icr_read = lguest_apic_icr_read; + apic->icr_write = lguest_apic_icr_write; + apic->wait_icr_idle = lguest_apic_wait_icr_idle; + apic->safe_wait_icr_idle = lguest_apic_safe_wait_icr_idle; }; #endif @@ -1035,7 +1036,7 @@ __init void lguest_init(void) #ifdef CONFIG_X86_LOCAL_APIC /* apic read/write intercepts */ - apic_ops = &lguest_basic_apic_ops; + set_lguest_basic_apic_ops(); #endif /* time operations */ diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 95ff6a0e942..e3dd3fb6729 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -36,7 +36,7 @@ #include #include -#include +#include #include #include #include @@ -554,14 +554,15 @@ static u32 xen_safe_apic_wait_icr_idle(void) return 0; } -static struct apic_ops xen_basic_apic_ops = { - .read = xen_apic_read, - .write = xen_apic_write, - .icr_read = xen_apic_icr_read, - .icr_write = xen_apic_icr_write, - .wait_icr_idle = xen_apic_wait_icr_idle, - .safe_wait_icr_idle = xen_safe_apic_wait_icr_idle, -}; +static void set_xen_basic_apic_ops(void) +{ + apic->read = xen_apic_read; + apic->write = xen_apic_write; + apic->icr_read = xen_apic_icr_read; + apic->icr_write = xen_apic_icr_write; + apic->wait_icr_idle = xen_apic_wait_icr_idle; + apic->safe_wait_icr_idle = xen_safe_apic_wait_icr_idle; +} #endif @@ -898,7 +899,7 @@ asmlinkage void __init xen_start_kernel(void) /* * set up the basic apic ops. */ - apic_ops = &xen_basic_apic_ops; + set_xen_basic_apic_ops(); #endif if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) { -- cgit From 8eb2dfac41c71701bb741f496f0cb7b7e4a3c3f6 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 17 Feb 2009 20:00:11 +0800 Subject: crypto: lrw - Fix big endian support It turns out that LRW has never worked properly on big endian. This was never discussed because nobody actually used it that way. In fact, it was only discovered when Geert Uytterhoeven loaded it through tcrypt which failed the test on it. The fix is straightforward, on big endian the to find the nth bit we should be grouping them by words instead of bytes. So setbit128_bbe should xor with 128 - BITS_PER_LONG instead of 128 - BITS_PER_BYTE == 0x78. Tested-by: Geert Uytterhoeven Signed-off-by: Herbert Xu --- crypto/lrw.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/crypto/lrw.c b/crypto/lrw.c index 8ef664e3bcd..358f80be2bf 100644 --- a/crypto/lrw.c +++ b/crypto/lrw.c @@ -45,7 +45,13 @@ struct priv { static inline void setbit128_bbe(void *b, int bit) { - __set_bit(bit ^ 0x78, b); + __set_bit(bit ^ (0x80 - +#ifdef __BIG_ENDIAN + BITS_PER_LONG +#else + BITS_PER_BYTE +#endif + ), b); } static int setkey(struct crypto_tfm *parent, const u8 *key, -- cgit From 7d01d32d3b9becd6deba318b718db3d9fc181d23 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 17 Feb 2009 12:33:20 +0100 Subject: x86, apic: fix build fallout of genapic changes - make oprofile build - select X86_X2APIC from X86_UV - it relies on it - export genapic for oprofile modular build Signed-off-by: Ingo Molnar --- arch/x86/Kconfig | 1 + arch/x86/kernel/cpu/mcheck/p4.c | 2 +- arch/x86/kernel/genapic_64.c | 1 + arch/x86/kernel/probe_32.c | 2 ++ arch/x86/oprofile/nmi_int.c | 2 +- arch/x86/oprofile/op_model_p4.c | 2 +- arch/x86/oprofile/op_model_ppro.c | 2 +- 7 files changed, 8 insertions(+), 4 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index bce241fe1d2..8955262caa3 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -316,6 +316,7 @@ config X86_UV bool "SGI Ultraviolet" depends on X86_64 depends on X86_EXTENDED_PLATFORM + select X86_X2APIC ---help--- This option is needed in order to support SGI Ultraviolet systems. If you don't have one of these, you should say N here. diff --git a/arch/x86/kernel/cpu/mcheck/p4.c b/arch/x86/kernel/cpu/mcheck/p4.c index 9b60fce09f7..f9c92b66dfb 100644 --- a/arch/x86/kernel/cpu/mcheck/p4.c +++ b/arch/x86/kernel/cpu/mcheck/p4.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include diff --git a/arch/x86/kernel/genapic_64.c b/arch/x86/kernel/genapic_64.c index 70b616b4c62..ef788635324 100644 --- a/arch/x86/kernel/genapic_64.c +++ b/arch/x86/kernel/genapic_64.c @@ -30,6 +30,7 @@ extern struct genapic apic_x2apic_phys; extern struct genapic apic_x2apic_cluster; struct genapic __read_mostly *apic = &apic_flat; +EXPORT_SYMBOL_GPL(apic); static struct genapic *apic_probe[] __initdata = { #ifdef CONFIG_X86_UV diff --git a/arch/x86/kernel/probe_32.c b/arch/x86/kernel/probe_32.c index 1f701caa95b..6e31b17d546 100644 --- a/arch/x86/kernel/probe_32.c +++ b/arch/x86/kernel/probe_32.c @@ -8,6 +8,7 @@ */ #include #include +#include #include #include #include @@ -143,6 +144,7 @@ extern struct genapic apic_es7000; extern struct genapic apic_default; struct genapic *apic = &apic_default; +EXPORT_SYMBOL_GPL(apic); static struct genapic *apic_probe[] __initdata = { #ifdef CONFIG_X86_NUMAQ diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index 202864ad49a..a32a5c7a8ef 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include "op_counter.h" #include "op_x86_model.h" diff --git a/arch/x86/oprofile/op_model_p4.c b/arch/x86/oprofile/op_model_p4.c index 4c4a51c90bc..09a237bc9ef 100644 --- a/arch/x86/oprofile/op_model_p4.c +++ b/arch/x86/oprofile/op_model_p4.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include "op_x86_model.h" diff --git a/arch/x86/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c index e9f80c744cf..5ebd8f605d7 100644 --- a/arch/x86/oprofile/op_model_ppro.c +++ b/arch/x86/oprofile/op_model_ppro.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include -- cgit From 35cfd1d964f3c2420862f2167a0eb85ff1208999 Mon Sep 17 00:00:00 2001 From: Michael Tokarev Date: Sun, 1 Feb 2009 16:11:04 +0100 Subject: HID: blacklist Powercom USB UPS For quite some time users with various UPSes from Powercom were forced to play magic with bind/unbind in /sys in order to be able to see the UPSes. The beasts does not work as HID devices, even if claims to do so. cypress_m8 driver works with the devices instead, creating a normal serial port with which normal UPS controlling software works. The manufacturer confirmed the upcoming models with proper HID support will have different device IDs. In any way, it's wrong to have two completely different modules for one device in kernel. Blacklist the device in HID (add it to hid_ignore_list) to stop this mess, finally. Signed-off-By: Michael Tokarev Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 3 +++ 2 files changed, 4 insertions(+) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 6cad69ed21c..0e96b1fcc14 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1605,6 +1605,7 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0002) }, { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) }, { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) }, + { HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) }, { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD) }, { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2) }, { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index e899f510ebe..88511970508 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -348,6 +348,9 @@ #define USB_VENDOR_ID_PLAYDOTCOM 0x0b43 #define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003 +#define USB_VENDOR_ID_POWERCOM 0x0d9f +#define USB_DEVICE_ID_POWERCOM_UPS 0x0002 + #define USB_VENDOR_ID_SAITEK 0x06a3 #define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 -- cgit From dfd395aff4cb16d2480b280064bea1b19ededef1 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 3 Feb 2009 16:35:17 +0300 Subject: HID: unlock properly on error paths in hidraw_ioctl() We can't return immediately because lock_kernel() is held. Signed-off-by: Dan Carpenter Signed-off-by: Jiri Kosina --- drivers/hid/hidraw.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 73244962897..02b19db5442 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -267,8 +267,10 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd, default: { struct hid_device *hid = dev->hid; - if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ) - return -EINVAL; + if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ) { + ret = -EINVAL; + break; + } if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWNAME(0))) { int len; @@ -277,8 +279,9 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd, len = strlen(hid->name) + 1; if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); - return copy_to_user(user_arg, hid->name, len) ? + ret = copy_to_user(user_arg, hid->name, len) ? -EFAULT : len; + break; } if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWPHYS(0))) { @@ -288,12 +291,13 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd, len = strlen(hid->phys) + 1; if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); - return copy_to_user(user_arg, hid->phys, len) ? + ret = copy_to_user(user_arg, hid->phys, len) ? -EFAULT : len; + break; } } - ret = -ENOTTY; + ret = -ENOTTY; } unlock_kernel(); return ret; -- cgit From daedb3d6a91f9626ab4c921378ac52e44de833d5 Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Sat, 14 Feb 2009 11:45:05 +0200 Subject: HID: move tmff and zpff devices from ignore_list to blacklist The devices handled by hid-tmff and hid-zpff were added in the hid_ignore_list[] instead of hid_blacklist[] in hid-core.c, thus disabling them completely. hid_ignore_list[] causes hid layer to skip the device, while hid_blacklist[] indicates there is a specific driver in hid bus. Re-enable the devices by moving them to the correct list. Signed-off-by: Anssi Hannula Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 0e96b1fcc14..1cc967448f4 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1300,7 +1300,13 @@ static const struct hid_device_id hid_blacklist[] = { { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, + { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, + { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, + { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) }, + { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) }, { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) }, @@ -1613,10 +1619,6 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD5) }, { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) }, { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) }, - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) }, - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) }, { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) }, { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, @@ -1627,8 +1629,6 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20) }, { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT) }, { HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, { } }; -- cgit From 2b639386a2a26c84c8d26c649cf657ebd43a7bc8 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 17 Feb 2009 12:38:36 +0100 Subject: HID: fix bus endianity in file2alias Fix endianness of bus member of hid_device_id in modpost. Signed-off-by: Jiri Slaby Reported-by: Nye Liu Cc: Jiri Kosina Signed-off-by: Jiri Kosina --- scripts/mod/file2alias.c | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 491b8b1b6ab..4eea60b1693 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -210,6 +210,7 @@ static void do_usb_table(void *symval, unsigned long size, static int do_hid_entry(const char *filename, struct hid_device_id *id, char *alias) { + id->bus = TO_NATIVE(id->bus); id->vendor = TO_NATIVE(id->vendor); id->product = TO_NATIVE(id->product); -- cgit From f63145e28934a0b3ad8baf31adc195ec81423351 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Sat, 24 Jan 2009 20:52:41 -0300 Subject: V4L/DVB (10516a): zoran: Update MAINTAINERS entry Ronald Bultje hasn't been maintaining the zoran driver for some time. Re-direct people to the mailing lists and web pages. MAINTAINERS | 6 +++--- Signed-off-by: Trent Piepho Acked-by: Jean Delvare Acked-by: Ronald S. Bultje Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index db65b4e6d13..53b50c8d5f3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4924,11 +4924,11 @@ L: zd1211-devs@lists.sourceforge.net (subscribers-only) S: Maintained ZR36067 VIDEO FOR LINUX DRIVER -P: Ronald Bultje -M: rbultje@ronald.bitfreak.net L: mjpeg-users@lists.sourceforge.net +L: linux-media@vger.kernel.org W: http://mjpeg.sourceforge.net/driver-zoran/ -S: Maintained +T: Mercurial http://linuxtv.org/hg/v4l-dvb +S: Odd Fixes ZS DECSTATION Z85C30 SERIAL DRIVER P: Maciej W. Rozycki -- cgit From ef88f2b563275d156beebc9f76ed134f3f90f210 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 13 Feb 2009 08:24:34 -0300 Subject: V4L/DVB (10527): tuner: fix TUV1236D analog/digital setup As reported by David Engel , ATSC115 doesn't work fine with mythtv. This software opens both analog and dvb interfaces of saa7134. What happens is that some tuner commands are going to the wrong place, as shown at the logs: Feb 12 20:37:48 opus kernel: tuner-simple 1-0061: using tuner params #0 (ntsc) Feb 12 20:37:48 opus kernel: tuner-simple 1-0061: freq = 67.25 (1076), range = 0, config = 0xce, cb = 0x01 Feb 12 20:37:48 opus kernel: tuner-simple 1-0061: Freq= 67.25 MHz, V_IF=45.75 MHz, Offset=0.00 MHz, div=1808 Feb 12 20:37:48 opus kernel: tuner 1-0061: tv freq set to 67.25 Feb 12 20:37:48 opus kernel: tuner-simple 1-000a: using tuner params #0 (ntsc) Feb 12 20:37:48 opus kernel: tuner-simple 1-000a: freq = 67.25 (1076), range = 0, config = 0xce, cb = 0x01 Feb 12 20:37:48 opus kernel: tuner-simple 1-000a: Freq= 67.25 MHz, V_IF=45.75 MHz, Offset=0.00 MHz, div=1808 Feb 12 20:37:48 opus kernel: tuner-simple 1-000a: tv 0x07 0x10 0xce 0x01 Feb 12 20:37:48 opus kernel: tuner-simple 1-0061: tv 0x07 0x10 0xce 0x01 This happens due to a hack at TUV1236D analog setup, where it replaces tuner address, at 0x61 for 0x0a, in order to save a few memory bytes. The code assumes that nobody else would try to access the tuner during that setup, but the point is that there's no lock to protect such access. So, this opens the possibility of race conditions to happen. Instead of hacking tuner address, this patch uses a temporary var with the proper tuner value to be used during the setup. This should save the issue, although we should consider to write some analog/digital lock at saa7134 driver. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/tuner-simple.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c index de7adaf5fa5..78412c9c424 100644 --- a/drivers/media/common/tuners/tuner-simple.c +++ b/drivers/media/common/tuners/tuner-simple.c @@ -318,7 +318,6 @@ static int simple_std_setup(struct dvb_frontend *fe, u8 *config, u8 *cb) { struct tuner_simple_priv *priv = fe->tuner_priv; - u8 tuneraddr; int rc; /* tv norm specific stuff for multi-norm tuners */ @@ -387,6 +386,7 @@ static int simple_std_setup(struct dvb_frontend *fe, case TUNER_PHILIPS_TUV1236D: { + struct tuner_i2c_props i2c = priv->i2c_props; /* 0x40 -> ATSC antenna input 1 */ /* 0x48 -> ATSC antenna input 2 */ /* 0x00 -> NTSC antenna input 1 */ @@ -398,17 +398,15 @@ static int simple_std_setup(struct dvb_frontend *fe, buffer[1] = 0x04; } /* set to the correct mode (analog or digital) */ - tuneraddr = priv->i2c_props.addr; - priv->i2c_props.addr = 0x0a; - rc = tuner_i2c_xfer_send(&priv->i2c_props, &buffer[0], 2); + i2c.addr = 0x0a; + rc = tuner_i2c_xfer_send(&i2c, &buffer[0], 2); if (2 != rc) tuner_warn("i2c i/o error: rc == %d " "(should be 2)\n", rc); - rc = tuner_i2c_xfer_send(&priv->i2c_props, &buffer[2], 2); + rc = tuner_i2c_xfer_send(&i2c, &buffer[2], 2); if (2 != rc) tuner_warn("i2c i/o error: rc == %d " "(should be 2)\n", rc); - priv->i2c_props.addr = tuneraddr; break; } } -- cgit From d807dec59d3c850b332b5bf95fe33f18def00068 Mon Sep 17 00:00:00 2001 From: Tobias Lorenz Date: Thu, 12 Feb 2009 14:56:10 -0300 Subject: V4L/DVB (10532): Correction of Stereo detection/setting and signal strength indication Thanks to Bob Ross - correction of stereo detection/setting - correction of signal strength indicator scaling Signed-off-by: Tobias Lorenz Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-si470x.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index 67cbce82cb9..fd81a97a0fd 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c @@ -98,6 +98,9 @@ * - blacklisted KWorld radio in hid-core.c and hid-ids.h * 2008-12-03 Mark Lord * - add support for DealExtreme USB Radio + * 2009-01-31 Bob Ross + * - correction of stereo detection/setting + * - correction of signal strength indicator scaling * * ToDo: * - add firmware download/update support @@ -1385,20 +1388,22 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, }; /* stereo indicator == stereo (instead of mono) */ - if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 1) - tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; - else + if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 0) tuner->rxsubchans = V4L2_TUNER_SUB_MONO; + else + tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; /* mono/stereo selector */ - if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 1) - tuner->audmode = V4L2_TUNER_MODE_MONO; - else + if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 0) tuner->audmode = V4L2_TUNER_MODE_STEREO; + else + tuner->audmode = V4L2_TUNER_MODE_MONO; /* min is worst, max is best; signal:0..0xffff; rssi: 0..0xff */ - tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI) - * 0x0101; + /* measured in units of dbµV in 1 db increments (max at ~75 dbµV) */ + tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI); + /* the ideal factor is 0xffff/75 = 873,8 */ + tuner->signal = (tuner->signal * 873) + (8 * tuner->signal / 10); /* automatic frequency control: -1: freq to low, 1 freq to high */ /* AFCRL does only indicate that freq. differs, not if too low/high */ -- cgit From 2f94fc465a6504443bb986ba9d36e28e2b422c6e Mon Sep 17 00:00:00 2001 From: Tobias Lorenz Date: Thu, 12 Feb 2009 14:56:19 -0300 Subject: V4L/DVB (10533): fix LED status output This patch closes one of my todos that was since long on my list. Some people reported clicks and glitches in the audio stream, correlated to the LED color changing cycle. Thanks to Rick Bronson . Signed-off-by: Tobias Lorenz Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-si470x.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index fd81a97a0fd..4dfed6aa2db 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c @@ -101,11 +101,13 @@ * 2009-01-31 Bob Ross * - correction of stereo detection/setting * - correction of signal strength indicator scaling + * 2009-01-31 Rick Bronson + * Tobias Lorenz + * - add LED status output * * ToDo: * - add firmware download/update support * - RDS support: interrupt mode, instead of polling - * - add LED status output (check if that's not already done in firmware) */ @@ -884,6 +886,30 @@ static int si470x_rds_on(struct si470x_device *radio) +/************************************************************************** + * General Driver Functions - LED_REPORT + **************************************************************************/ + +/* + * si470x_set_led_state - sets the led state + */ +static int si470x_set_led_state(struct si470x_device *radio, + unsigned char led_state) +{ + unsigned char buf[LED_REPORT_SIZE]; + int retval; + + buf[0] = LED_REPORT; + buf[1] = LED_COMMAND; + buf[2] = led_state; + + retval = si470x_set_report(radio, (void *) &buf, sizeof(buf)); + + return (retval < 0) ? -EINVAL : 0; +} + + + /************************************************************************** * RDS Driver Functions **************************************************************************/ @@ -1637,6 +1663,9 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, /* set initial frequency */ si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */ + /* set led to connect state */ + si470x_set_led_state(radio, BLINK_GREEN_LED); + /* rds buffer allocation */ radio->buf_size = rds_buf * 3; radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL); @@ -1720,6 +1749,9 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf) cancel_delayed_work_sync(&radio->work); usb_set_intfdata(intf, NULL); if (radio->users == 0) { + /* set led to disconnect state */ + si470x_set_led_state(radio, BLINK_ORANGE_LED); + video_unregister_device(radio->videodev); kfree(radio->buffer); kfree(radio); -- cgit From 28100165c3f27f681fee8b60e4e44f64a739c454 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 16 Feb 2009 15:27:44 -0300 Subject: V4L/DVB (10572): Revert commit dda06a8e4610757def753ee3a541a0b1a1feb36b On Mon, 02 Feb 2009, Hartmut wrote: This change set is wrong. The affected functions cannot be called from an interrupt context, because they may process large buffers. In this case, interrupts are disabled for a long time. Functions, like dvb_dmx_swfilter_packets(), could be called only from a tasklet. This change set does hide some strong design bugs in dm1105.c and au0828-dvb.c. Please revert this change set and do fix the bugs in dm1105.c and au0828-dvb.c (and other files). On Sun, 15 Feb 2009, Oliver Endriss wrote: This changeset _must_ be reverted! It breaks all kernels since 2.6.27 for applications which use DVB and require a low interrupt latency. It is a very bad idea to call the demuxer to process data buffers with interrupts disabled! On Mon, 16 Feb 2009, Trent Piepho wrote: I agree, this is bad. The demuxer is far too much work to be done with IRQs off. IMHO, even doing it under a spin-lock is excessive. It should be a mutex. Drivers should use a work-queue to feed the demuxer. Thank you for testing this changeset and discovering the issues on it. Cc: Trent Piepho Cc: Hartmut Cc: Oliver Endriss Cc: Andreas Oberritter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-core/dmxdev.c | 16 +++++++--------- drivers/media/dvb/dvb-core/dvb_demux.c | 16 ++++++---------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c index 0c733c66a44..069d847ba88 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.c +++ b/drivers/media/dvb/dvb-core/dmxdev.c @@ -364,16 +364,15 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, enum dmx_success success) { struct dmxdev_filter *dmxdevfilter = filter->priv; - unsigned long flags; int ret; if (dmxdevfilter->buffer.error) { wake_up(&dmxdevfilter->buffer.queue); return 0; } - spin_lock_irqsave(&dmxdevfilter->dev->lock, flags); + spin_lock(&dmxdevfilter->dev->lock); if (dmxdevfilter->state != DMXDEV_STATE_GO) { - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + spin_unlock(&dmxdevfilter->dev->lock); return 0; } del_timer(&dmxdevfilter->timer); @@ -392,7 +391,7 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, } if (dmxdevfilter->params.sec.flags & DMX_ONESHOT) dmxdevfilter->state = DMXDEV_STATE_DONE; - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + spin_unlock(&dmxdevfilter->dev->lock); wake_up(&dmxdevfilter->buffer.queue); return 0; } @@ -404,12 +403,11 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, { struct dmxdev_filter *dmxdevfilter = feed->priv; struct dvb_ringbuffer *buffer; - unsigned long flags; int ret; - spin_lock_irqsave(&dmxdevfilter->dev->lock, flags); + spin_lock(&dmxdevfilter->dev->lock); if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) { - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + spin_unlock(&dmxdevfilter->dev->lock); return 0; } @@ -419,7 +417,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, else buffer = &dmxdevfilter->dev->dvr_buffer; if (buffer->error) { - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + spin_unlock(&dmxdevfilter->dev->lock); wake_up(&buffer->queue); return 0; } @@ -430,7 +428,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, dvb_ringbuffer_flush(buffer); buffer->error = ret; } - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + spin_unlock(&dmxdevfilter->dev->lock); wake_up(&buffer->queue); return 0; } diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c index a2c1fd5d2f6..e2eca0b1fe7 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/drivers/media/dvb/dvb-core/dvb_demux.c @@ -399,9 +399,7 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, size_t count) { - unsigned long flags; - - spin_lock_irqsave(&demux->lock, flags); + spin_lock(&demux->lock); while (count--) { if (buf[0] == 0x47) @@ -409,17 +407,16 @@ void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, buf += 188; } - spin_unlock_irqrestore(&demux->lock, flags); + spin_unlock(&demux->lock); } EXPORT_SYMBOL(dvb_dmx_swfilter_packets); void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) { - unsigned long flags; int p = 0, i, j; - spin_lock_irqsave(&demux->lock, flags); + spin_lock(&demux->lock); if (demux->tsbufp) { i = demux->tsbufp; @@ -452,18 +449,17 @@ void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) } bailout: - spin_unlock_irqrestore(&demux->lock, flags); + spin_unlock(&demux->lock); } EXPORT_SYMBOL(dvb_dmx_swfilter); void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) { - unsigned long flags; int p = 0, i, j; u8 tmppack[188]; - spin_lock_irqsave(&demux->lock, flags); + spin_lock(&demux->lock); if (demux->tsbufp) { i = demux->tsbufp; @@ -504,7 +500,7 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) } bailout: - spin_unlock_irqrestore(&demux->lock, flags); + spin_unlock(&demux->lock); } EXPORT_SYMBOL(dvb_dmx_swfilter_204); -- cgit From ad28127d7c7c617bca1d426f95b6ffa1fb8f700f Mon Sep 17 00:00:00 2001 From: Adam Baker Date: Wed, 4 Feb 2009 15:33:21 -0300 Subject: V4L/DVB (10619): gspca - main: Destroy the URBs at disconnection time. If a device using the gspca framework is unplugged while it is still streaming then the call that is used to free the URBs that have been allocated occurs after the pointer it uses becomes invalid at the end of gspca_disconnect. Make another cleanup call in gspca_disconnect while the pointer is still valid (multiple calls are OK as destroy_urbs checks for pointers already being NULL. Signed-off-by: Adam Baker Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 2ed24527ecd..65e4901f4db 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -422,6 +422,7 @@ static void destroy_urbs(struct gspca_dev *gspca_dev) if (urb == NULL) break; + BUG_ON(!gspca_dev->dev); gspca_dev->urb[i] = NULL; if (!gspca_dev->present) usb_kill_urb(urb); @@ -1950,8 +1951,12 @@ void gspca_disconnect(struct usb_interface *intf) { struct gspca_dev *gspca_dev = usb_get_intfdata(intf); + mutex_lock(&gspca_dev->usb_lock); gspca_dev->present = 0; + mutex_unlock(&gspca_dev->usb_lock); + destroy_urbs(gspca_dev); + gspca_dev->dev = NULL; usb_set_intfdata(intf, NULL); /* release the device */ -- cgit From ac9575f75c52bcb455120f8c43376b556acba048 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 14 Feb 2009 19:58:33 -0300 Subject: V4L/DVB (10625): ivtv: fix decoder crash regression The video_ioctl2 conversion of ivtv in kernel 2.6.27 introduced a bug causing decoder commands to crash. The decoder commands should have been handled from the video_ioctl2 default handler, ensuring correct mapping of the argument between user and kernel space. Unfortunately they ended up before the video_ioctl2 call, causing random crashes. Thanks to hannes@linus.priv.at for testing and helping me track down the cause! Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-ioctl.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index f6b3ef6e691..9be6244573e 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1748,6 +1748,18 @@ static long ivtv_default(struct file *file, void *fh, int cmd, void *arg) break; } + case IVTV_IOC_DMA_FRAME: + case VIDEO_GET_PTS: + case VIDEO_GET_FRAME_COUNT: + case VIDEO_GET_EVENT: + case VIDEO_PLAY: + case VIDEO_STOP: + case VIDEO_FREEZE: + case VIDEO_CONTINUE: + case VIDEO_COMMAND: + case VIDEO_TRY_COMMAND: + return ivtv_decoder_ioctls(file, cmd, (void *)arg); + default: return -EINVAL; } @@ -1790,18 +1802,6 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp, ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); return 0; - case IVTV_IOC_DMA_FRAME: - case VIDEO_GET_PTS: - case VIDEO_GET_FRAME_COUNT: - case VIDEO_GET_EVENT: - case VIDEO_PLAY: - case VIDEO_STOP: - case VIDEO_FREEZE: - case VIDEO_CONTINUE: - case VIDEO_COMMAND: - case VIDEO_TRY_COMMAND: - return ivtv_decoder_ioctls(filp, cmd, (void *)arg); - default: break; } -- cgit From 7bf432d64c47f77111fbce5d48d7774df8b48948 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 16 Feb 2009 04:25:32 -0300 Subject: V4L/DVB (10626): ivtv: fix regression in get sliced vbi format The new v4l2_subdev_call used s_fmt instead of g_fmt. Thanks-to: Andy Walls Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 9be6244573e..c13bd2aa0be 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -393,7 +393,7 @@ static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo return 0; } - v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt); + v4l2_subdev_call(itv->sd_video, video, g_fmt, fmt); vbifmt->service_set = ivtv_get_service_set(vbifmt); return 0; } -- cgit From 28aa29eeb3918f820b914679cfc4404972f2df32 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 17 Feb 2009 14:36:42 +0100 Subject: remove: genapic prepare Signed-off-by: Ingo Molnar --- arch/x86/include/asm/genapic.h | 13 +------------ arch/x86/kernel/probe_32.c | 9 +++++++++ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/arch/x86/include/asm/genapic.h b/arch/x86/include/asm/genapic.h index a6d0b00a544..9b874a38683 100644 --- a/arch/x86/include/asm/genapic.h +++ b/arch/x86/include/asm/genapic.h @@ -168,8 +168,6 @@ extern void apic_send_IPI_self(int vector); extern struct genapic apic_x2apic_uv_x; DECLARE_PER_CPU(int, x2apic_extra_bits); -extern void default_setup_apic_routing(void); - extern int default_cpu_present_to_apicid(int mps_cpu); extern int default_check_phys_apicid_present(int boot_cpu_physical_apicid); #endif @@ -211,10 +209,9 @@ static inline unsigned int read_apic_id(void) return apic->get_apic_id(reg); } -#ifdef CONFIG_X86_64 extern void default_setup_apic_routing(void); -#else +#ifdef CONFIG_X86_32 /* * Set up the logical destination ID. * @@ -251,14 +248,6 @@ static inline int default_phys_pkg_id(int cpuid_apic, int index_msb) return cpuid_apic >> index_msb; } -static inline void default_setup_apic_routing(void) -{ -#ifdef CONFIG_X86_IO_APIC - printk("Enabling APIC mode: %s. Using %d I/O APICs\n", - "Flat", nr_ioapics); -#endif -} - extern int default_apicid_to_node(int logical_apicid); #endif diff --git a/arch/x86/kernel/probe_32.c b/arch/x86/kernel/probe_32.c index 6e31b17d546..b3d5d74e522 100644 --- a/arch/x86/kernel/probe_32.c +++ b/arch/x86/kernel/probe_32.c @@ -53,6 +53,15 @@ int no_broadcast = DEFAULT_SEND_IPI; #ifdef CONFIG_X86_LOCAL_APIC +void default_setup_apic_routing(void) +{ +#ifdef CONFIG_X86_IO_APIC + printk(KERN_INFO + "Enabling APIC mode: Flat. Using %d I/O APICs\n", + nr_ioapics); +#endif +} + static void default_vector_allocation_domain(int cpu, struct cpumask *retmask) { /* -- cgit From e2780a68f889c9d7ec8e78d58a3a2be8cfebf202 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 17 Feb 2009 13:52:29 +0100 Subject: x86, apic: merge genapic.h into apic.h Impact: cleanup Reduce the number of include files to worry about. Also, most of the users of APIC facilities had to include genapic.h already, which embedded apic.h, so the distinction was meaningless. [ include apic.h from genapic.h for compatibility. ] Signed-off-by: Ingo Molnar --- arch/x86/include/asm/apic.h | 314 ++++++++++++++++++++++++++++++++++++++++- arch/x86/include/asm/genapic.h | 312 ---------------------------------------- 2 files changed, 310 insertions(+), 316 deletions(-) diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 4f56e053d34..c07f5fbf43c 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -1,15 +1,18 @@ #ifndef _ASM_X86_APIC_H #define _ASM_X86_APIC_H -#include +#include #include +#include #include -#include -#include +#include #include +#include +#include +#include +#include #include -#include #include #define ARCH_APICTIMER_STOPS_ON_C3 1 @@ -235,4 +238,307 @@ static inline void disable_local_APIC(void) { } #endif +/* + * Copyright 2004 James Cleverdon, IBM. + * Subject to the GNU Public License, v.2 + * + * Generic APIC sub-arch data struct. + * + * Hacked for x86-64 by James Cleverdon from i386 architecture code by + * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and + * James Cleverdon. + */ +struct genapic { + char *name; + + int (*probe)(void); + int (*acpi_madt_oem_check)(char *oem_id, char *oem_table_id); + int (*apic_id_registered)(void); + + u32 irq_delivery_mode; + u32 irq_dest_mode; + + const struct cpumask *(*target_cpus)(void); + + int disable_esr; + + int dest_logical; + unsigned long (*check_apicid_used)(physid_mask_t bitmap, int apicid); + unsigned long (*check_apicid_present)(int apicid); + + void (*vector_allocation_domain)(int cpu, struct cpumask *retmask); + void (*init_apic_ldr)(void); + + physid_mask_t (*ioapic_phys_id_map)(physid_mask_t map); + + void (*setup_apic_routing)(void); + int (*multi_timer_check)(int apic, int irq); + int (*apicid_to_node)(int logical_apicid); + int (*cpu_to_logical_apicid)(int cpu); + int (*cpu_present_to_apicid)(int mps_cpu); + physid_mask_t (*apicid_to_cpu_present)(int phys_apicid); + void (*setup_portio_remap)(void); + int (*check_phys_apicid_present)(int boot_cpu_physical_apicid); + void (*enable_apic_mode)(void); + int (*phys_pkg_id)(int cpuid_apic, int index_msb); + + /* + * When one of the next two hooks returns 1 the genapic + * is switched to this. Essentially they are additional + * probe functions: + */ + int (*mps_oem_check)(struct mpc_table *mpc, char *oem, char *productid); + + unsigned int (*get_apic_id)(unsigned long x); + unsigned long (*set_apic_id)(unsigned int id); + unsigned long apic_id_mask; + + unsigned int (*cpu_mask_to_apicid)(const struct cpumask *cpumask); + unsigned int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask, + const struct cpumask *andmask); + + /* ipi */ + void (*send_IPI_mask)(const struct cpumask *mask, int vector); + void (*send_IPI_mask_allbutself)(const struct cpumask *mask, + int vector); + void (*send_IPI_allbutself)(int vector); + void (*send_IPI_all)(int vector); + void (*send_IPI_self)(int vector); + + /* wakeup_secondary_cpu */ + int (*wakeup_cpu)(int apicid, unsigned long start_eip); + + int trampoline_phys_low; + int trampoline_phys_high; + + void (*wait_for_init_deassert)(atomic_t *deassert); + void (*smp_callin_clear_local_apic)(void); + void (*store_NMI_vector)(unsigned short *high, unsigned short *low); + void (*inquire_remote_apic)(int apicid); + + /* apic ops */ + u32 (*read)(u32 reg); + void (*write)(u32 reg, u32 v); + u64 (*icr_read)(void); + void (*icr_write)(u32 low, u32 high); + void (*wait_icr_idle)(void); + u32 (*safe_wait_icr_idle)(void); +}; + +extern struct genapic *apic; + +static inline u32 apic_read(u32 reg) +{ + return apic->read(reg); +} + +static inline void apic_write(u32 reg, u32 val) +{ + apic->write(reg, val); +} + +static inline u64 apic_icr_read(void) +{ + return apic->icr_read(); +} + +static inline void apic_icr_write(u32 low, u32 high) +{ + apic->icr_write(low, high); +} + +static inline void apic_wait_icr_idle(void) +{ + apic->wait_icr_idle(); +} + +static inline u32 safe_apic_wait_icr_idle(void) +{ + return apic->safe_wait_icr_idle(); +} + + +static inline void ack_APIC_irq(void) +{ + /* + * ack_APIC_irq() actually gets compiled as a single instruction + * ... yummie. + */ + + /* Docs say use 0 for future compatibility */ + apic_write(APIC_EOI, 0); +} + +static inline unsigned default_get_apic_id(unsigned long x) +{ + unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR)); + + if (APIC_XAPIC(ver)) + return (x >> 24) & 0xFF; + else + return (x >> 24) & 0x0F; +} + +/* + * Warm reset vector default position: + */ +#define DEFAULT_TRAMPOLINE_PHYS_LOW 0x467 +#define DEFAULT_TRAMPOLINE_PHYS_HIGH 0x469 + +#ifdef CONFIG_X86_32 +extern void es7000_update_genapic_to_cluster(void); +#else +extern struct genapic apic_flat; +extern struct genapic apic_physflat; +extern struct genapic apic_x2apic_cluster; +extern struct genapic apic_x2apic_phys; +extern int default_acpi_madt_oem_check(char *, char *); + +extern void apic_send_IPI_self(int vector); + +extern struct genapic apic_x2apic_uv_x; +DECLARE_PER_CPU(int, x2apic_extra_bits); + +extern int default_cpu_present_to_apicid(int mps_cpu); +extern int default_check_phys_apicid_present(int boot_cpu_physical_apicid); +#endif + +static inline void default_wait_for_init_deassert(atomic_t *deassert) +{ + while (!atomic_read(deassert)) + cpu_relax(); + return; +} + +extern void generic_bigsmp_probe(void); + + +#ifdef CONFIG_X86_LOCAL_APIC + +#include + +#define APIC_DFR_VALUE (APIC_DFR_FLAT) + +static inline const struct cpumask *default_target_cpus(void) +{ +#ifdef CONFIG_SMP + return cpu_online_mask; +#else + return cpumask_of(0); +#endif +} + +DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid); + + +static inline unsigned int read_apic_id(void) +{ + unsigned int reg; + + reg = apic_read(APIC_ID); + + return apic->get_apic_id(reg); +} + +extern void default_setup_apic_routing(void); + +#ifdef CONFIG_X86_32 +/* + * Set up the logical destination ID. + * + * Intel recommends to set DFR, LDR and TPR before enabling + * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel + * document number 292116). So here it goes... + */ +extern void default_init_apic_ldr(void); + +static inline int default_apic_id_registered(void) +{ + return physid_isset(read_apic_id(), phys_cpu_present_map); +} + +static inline unsigned int +default_cpu_mask_to_apicid(const struct cpumask *cpumask) +{ + return cpumask_bits(cpumask)[0]; +} + +static inline unsigned int +default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, + const struct cpumask *andmask) +{ + unsigned long mask1 = cpumask_bits(cpumask)[0]; + unsigned long mask2 = cpumask_bits(andmask)[0]; + unsigned long mask3 = cpumask_bits(cpu_online_mask)[0]; + + return (unsigned int)(mask1 & mask2 & mask3); +} + +static inline int default_phys_pkg_id(int cpuid_apic, int index_msb) +{ + return cpuid_apic >> index_msb; +} + +extern int default_apicid_to_node(int logical_apicid); + +#endif + +static inline unsigned long default_check_apicid_used(physid_mask_t bitmap, int apicid) +{ + return physid_isset(apicid, bitmap); +} + +static inline unsigned long default_check_apicid_present(int bit) +{ + return physid_isset(bit, phys_cpu_present_map); +} + +static inline physid_mask_t default_ioapic_phys_id_map(physid_mask_t phys_map) +{ + return phys_map; +} + +/* Mapping from cpu number to logical apicid */ +static inline int default_cpu_to_logical_apicid(int cpu) +{ + return 1 << cpu; +} + +static inline int __default_cpu_present_to_apicid(int mps_cpu) +{ + if (mps_cpu < nr_cpu_ids && cpu_present(mps_cpu)) + return (int)per_cpu(x86_bios_cpu_apicid, mps_cpu); + else + return BAD_APICID; +} + +static inline int +__default_check_phys_apicid_present(int boot_cpu_physical_apicid) +{ + return physid_isset(boot_cpu_physical_apicid, phys_cpu_present_map); +} + +#ifdef CONFIG_X86_32 +static inline int default_cpu_present_to_apicid(int mps_cpu) +{ + return __default_cpu_present_to_apicid(mps_cpu); +} + +static inline int +default_check_phys_apicid_present(int boot_cpu_physical_apicid) +{ + return __default_check_phys_apicid_present(boot_cpu_physical_apicid); +} +#else +extern int default_cpu_present_to_apicid(int mps_cpu); +extern int default_check_phys_apicid_present(int boot_cpu_physical_apicid); +#endif + +static inline physid_mask_t default_apicid_to_cpu_present(int phys_apicid) +{ + return physid_mask_of_physid(phys_apicid); +} + +#endif /* CONFIG_X86_LOCAL_APIC */ + #endif /* _ASM_X86_APIC_H */ diff --git a/arch/x86/include/asm/genapic.h b/arch/x86/include/asm/genapic.h index 9b874a38683..4b8b98fa7f2 100644 --- a/arch/x86/include/asm/genapic.h +++ b/arch/x86/include/asm/genapic.h @@ -1,313 +1 @@ -#ifndef _ASM_X86_GENAPIC_H -#define _ASM_X86_GENAPIC_H - -#include - -#include -#include #include - -/* - * Copyright 2004 James Cleverdon, IBM. - * Subject to the GNU Public License, v.2 - * - * Generic APIC sub-arch data struct. - * - * Hacked for x86-64 by James Cleverdon from i386 architecture code by - * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and - * James Cleverdon. - */ -struct genapic { - char *name; - - int (*probe)(void); - int (*acpi_madt_oem_check)(char *oem_id, char *oem_table_id); - int (*apic_id_registered)(void); - - u32 irq_delivery_mode; - u32 irq_dest_mode; - - const struct cpumask *(*target_cpus)(void); - - int disable_esr; - - int dest_logical; - unsigned long (*check_apicid_used)(physid_mask_t bitmap, int apicid); - unsigned long (*check_apicid_present)(int apicid); - - void (*vector_allocation_domain)(int cpu, struct cpumask *retmask); - void (*init_apic_ldr)(void); - - physid_mask_t (*ioapic_phys_id_map)(physid_mask_t map); - - void (*setup_apic_routing)(void); - int (*multi_timer_check)(int apic, int irq); - int (*apicid_to_node)(int logical_apicid); - int (*cpu_to_logical_apicid)(int cpu); - int (*cpu_present_to_apicid)(int mps_cpu); - physid_mask_t (*apicid_to_cpu_present)(int phys_apicid); - void (*setup_portio_remap)(void); - int (*check_phys_apicid_present)(int boot_cpu_physical_apicid); - void (*enable_apic_mode)(void); - int (*phys_pkg_id)(int cpuid_apic, int index_msb); - - /* - * When one of the next two hooks returns 1 the genapic - * is switched to this. Essentially they are additional - * probe functions: - */ - int (*mps_oem_check)(struct mpc_table *mpc, char *oem, char *productid); - - unsigned int (*get_apic_id)(unsigned long x); - unsigned long (*set_apic_id)(unsigned int id); - unsigned long apic_id_mask; - - unsigned int (*cpu_mask_to_apicid)(const struct cpumask *cpumask); - unsigned int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask, - const struct cpumask *andmask); - - /* ipi */ - void (*send_IPI_mask)(const struct cpumask *mask, int vector); - void (*send_IPI_mask_allbutself)(const struct cpumask *mask, - int vector); - void (*send_IPI_allbutself)(int vector); - void (*send_IPI_all)(int vector); - void (*send_IPI_self)(int vector); - - /* wakeup_secondary_cpu */ - int (*wakeup_cpu)(int apicid, unsigned long start_eip); - - int trampoline_phys_low; - int trampoline_phys_high; - - void (*wait_for_init_deassert)(atomic_t *deassert); - void (*smp_callin_clear_local_apic)(void); - void (*store_NMI_vector)(unsigned short *high, unsigned short *low); - void (*inquire_remote_apic)(int apicid); - - /* apic ops */ - u32 (*read)(u32 reg); - void (*write)(u32 reg, u32 v); - u64 (*icr_read)(void); - void (*icr_write)(u32 low, u32 high); - void (*wait_icr_idle)(void); - u32 (*safe_wait_icr_idle)(void); -}; - -extern struct genapic *apic; - -static inline u32 apic_read(u32 reg) -{ - return apic->read(reg); -} - -static inline void apic_write(u32 reg, u32 val) -{ - apic->write(reg, val); -} - -static inline u64 apic_icr_read(void) -{ - return apic->icr_read(); -} - -static inline void apic_icr_write(u32 low, u32 high) -{ - apic->icr_write(low, high); -} - -static inline void apic_wait_icr_idle(void) -{ - apic->wait_icr_idle(); -} - -static inline u32 safe_apic_wait_icr_idle(void) -{ - return apic->safe_wait_icr_idle(); -} - - -static inline void ack_APIC_irq(void) -{ - /* - * ack_APIC_irq() actually gets compiled as a single instruction - * ... yummie. - */ - - /* Docs say use 0 for future compatibility */ - apic_write(APIC_EOI, 0); -} - -static inline unsigned default_get_apic_id(unsigned long x) -{ - unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR)); - - if (APIC_XAPIC(ver)) - return (x >> 24) & 0xFF; - else - return (x >> 24) & 0x0F; -} - -/* - * Warm reset vector default position: - */ -#define DEFAULT_TRAMPOLINE_PHYS_LOW 0x467 -#define DEFAULT_TRAMPOLINE_PHYS_HIGH 0x469 - -#ifdef CONFIG_X86_32 -extern void es7000_update_genapic_to_cluster(void); -#else -extern struct genapic apic_flat; -extern struct genapic apic_physflat; -extern struct genapic apic_x2apic_cluster; -extern struct genapic apic_x2apic_phys; -extern int default_acpi_madt_oem_check(char *, char *); - -extern void apic_send_IPI_self(int vector); - -extern struct genapic apic_x2apic_uv_x; -DECLARE_PER_CPU(int, x2apic_extra_bits); - -extern int default_cpu_present_to_apicid(int mps_cpu); -extern int default_check_phys_apicid_present(int boot_cpu_physical_apicid); -#endif - -static inline void default_wait_for_init_deassert(atomic_t *deassert) -{ - while (!atomic_read(deassert)) - cpu_relax(); - return; -} - -extern void generic_bigsmp_probe(void); - - -#ifdef CONFIG_X86_LOCAL_APIC - -#include - -#define APIC_DFR_VALUE (APIC_DFR_FLAT) - -static inline const struct cpumask *default_target_cpus(void) -{ -#ifdef CONFIG_SMP - return cpu_online_mask; -#else - return cpumask_of(0); -#endif -} - -DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid); - - -static inline unsigned int read_apic_id(void) -{ - unsigned int reg; - - reg = apic_read(APIC_ID); - - return apic->get_apic_id(reg); -} - -extern void default_setup_apic_routing(void); - -#ifdef CONFIG_X86_32 -/* - * Set up the logical destination ID. - * - * Intel recommends to set DFR, LDR and TPR before enabling - * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel - * document number 292116). So here it goes... - */ -extern void default_init_apic_ldr(void); - -static inline int default_apic_id_registered(void) -{ - return physid_isset(read_apic_id(), phys_cpu_present_map); -} - -static inline unsigned int -default_cpu_mask_to_apicid(const struct cpumask *cpumask) -{ - return cpumask_bits(cpumask)[0]; -} - -static inline unsigned int -default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask) -{ - unsigned long mask1 = cpumask_bits(cpumask)[0]; - unsigned long mask2 = cpumask_bits(andmask)[0]; - unsigned long mask3 = cpumask_bits(cpu_online_mask)[0]; - - return (unsigned int)(mask1 & mask2 & mask3); -} - -static inline int default_phys_pkg_id(int cpuid_apic, int index_msb) -{ - return cpuid_apic >> index_msb; -} - -extern int default_apicid_to_node(int logical_apicid); - -#endif - -static inline unsigned long default_check_apicid_used(physid_mask_t bitmap, int apicid) -{ - return physid_isset(apicid, bitmap); -} - -static inline unsigned long default_check_apicid_present(int bit) -{ - return physid_isset(bit, phys_cpu_present_map); -} - -static inline physid_mask_t default_ioapic_phys_id_map(physid_mask_t phys_map) -{ - return phys_map; -} - -/* Mapping from cpu number to logical apicid */ -static inline int default_cpu_to_logical_apicid(int cpu) -{ - return 1 << cpu; -} - -static inline int __default_cpu_present_to_apicid(int mps_cpu) -{ - if (mps_cpu < nr_cpu_ids && cpu_present(mps_cpu)) - return (int)per_cpu(x86_bios_cpu_apicid, mps_cpu); - else - return BAD_APICID; -} - -static inline int -__default_check_phys_apicid_present(int boot_cpu_physical_apicid) -{ - return physid_isset(boot_cpu_physical_apicid, phys_cpu_present_map); -} - -#ifdef CONFIG_X86_32 -static inline int default_cpu_present_to_apicid(int mps_cpu) -{ - return __default_cpu_present_to_apicid(mps_cpu); -} - -static inline int -default_check_phys_apicid_present(int boot_cpu_physical_apicid) -{ - return __default_check_phys_apicid_present(boot_cpu_physical_apicid); -} -#else -extern int default_cpu_present_to_apicid(int mps_cpu); -extern int default_check_phys_apicid_present(int boot_cpu_physical_apicid); -#endif - -static inline physid_mask_t default_apicid_to_cpu_present(int phys_apicid) -{ - return physid_mask_of_physid(phys_apicid); -} - -#endif /* CONFIG_X86_LOCAL_APIC */ - -#endif /* _ASM_X86_GENAPIC_64_H */ -- cgit From 7b6aa335ca1a845c2262ec7a595b4521bca0f79d Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 17 Feb 2009 13:58:15 +0100 Subject: x86, apic: remove genapic.h Impact: cleanup Remove genapic.h and remove all references to it. Signed-off-by: Ingo Molnar --- arch/x86/include/asm/ipi.h | 2 +- arch/x86/kernel/acpi/boot.c | 2 +- arch/x86/kernel/apic.c | 2 +- arch/x86/kernel/bigsmp_32.c | 2 +- arch/x86/kernel/cpu/addon_cpuid_features.c | 2 +- arch/x86/kernel/cpu/amd.c | 2 +- arch/x86/kernel/cpu/common.c | 4 ++-- arch/x86/kernel/cpu/intel.c | 2 +- arch/x86/kernel/cpu/mcheck/mce_amd_64.c | 2 +- arch/x86/kernel/cpu/mcheck/mce_intel_64.c | 2 +- arch/x86/kernel/cpu/mcheck/p4.c | 2 +- arch/x86/kernel/crash.c | 2 +- arch/x86/kernel/es7000_32.c | 4 ++-- arch/x86/kernel/genapic_64.c | 2 +- arch/x86/kernel/genapic_flat_64.c | 2 +- arch/x86/kernel/genx2apic_cluster.c | 2 +- arch/x86/kernel/genx2apic_phys.c | 2 +- arch/x86/kernel/genx2apic_uv_x.c | 2 +- arch/x86/kernel/io_apic.c | 2 +- arch/x86/kernel/ipi.c | 2 +- arch/x86/kernel/irq.c | 2 +- arch/x86/kernel/irq_32.c | 2 +- arch/x86/kernel/kgdb.c | 2 +- arch/x86/kernel/mpparse.c | 2 +- arch/x86/kernel/nmi.c | 2 +- arch/x86/kernel/numaq_32.c | 4 ++-- arch/x86/kernel/probe_32.c | 8 ++++---- arch/x86/kernel/reboot.c | 2 +- arch/x86/kernel/setup.c | 2 +- arch/x86/kernel/smp.c | 2 +- arch/x86/kernel/smpboot.c | 4 ++-- arch/x86/kernel/summit_32.c | 2 +- arch/x86/kernel/tlb_uv.c | 4 ++-- arch/x86/kernel/uv_irq.c | 2 +- arch/x86/kernel/visws_quirks.c | 4 ++-- arch/x86/kernel/vmi_32.c | 2 +- arch/x86/kernel/vmiclock_32.c | 2 +- arch/x86/lguest/boot.c | 2 +- arch/x86/mm/srat_64.c | 2 +- arch/x86/mm/tlb.c | 2 +- arch/x86/oprofile/nmi_int.c | 2 +- arch/x86/oprofile/op_model_p4.c | 2 +- arch/x86/oprofile/op_model_ppro.c | 2 +- arch/x86/pci/numaq_32.c | 2 +- arch/x86/xen/enlighten.c | 2 +- 45 files changed, 54 insertions(+), 54 deletions(-) diff --git a/arch/x86/include/asm/ipi.h b/arch/x86/include/asm/ipi.h index 5f2efc5d992..3395c680a97 100644 --- a/arch/x86/include/asm/ipi.h +++ b/arch/x86/include/asm/ipi.h @@ -123,7 +123,7 @@ extern void default_send_IPI_mask_sequence_phys(const struct cpumask *mask, int vector); extern void default_send_IPI_mask_allbutself_phys(const struct cpumask *mask, int vector); -#include +#include extern void default_send_IPI_mask_sequence_logical(const struct cpumask *mask, int vector); diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 956c1dee6fb..42814152c94 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c index af494bad885..7db03a9b61d 100644 --- a/arch/x86/kernel/apic.c +++ b/arch/x86/kernel/apic.c @@ -36,7 +36,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/x86/kernel/bigsmp_32.c b/arch/x86/kernel/bigsmp_32.c index 9eeb714c5de..72f4e534051 100644 --- a/arch/x86/kernel/bigsmp_32.c +++ b/arch/x86/kernel/bigsmp_32.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/kernel/cpu/addon_cpuid_features.c b/arch/x86/kernel/cpu/addon_cpuid_features.c index e48640cfac0..6882a735d9c 100644 --- a/arch/x86/kernel/cpu/addon_cpuid_features.c +++ b/arch/x86/kernel/cpu/addon_cpuid_features.c @@ -7,7 +7,7 @@ #include #include -#include +#include struct cpuid_bit { u16 feature; diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index ff4d7b9e32e..c94ba9311e6 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -12,7 +12,7 @@ # include #endif -#include +#include #include "cpu.h" diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 4b5d13e472d..41f3788ec9b 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -26,8 +26,8 @@ #ifdef CONFIG_X86_LOCAL_APIC #include #include -#include -#include +#include +#include #include #endif diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 1f137a87d4b..290f92e2b7c 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -24,7 +24,7 @@ #ifdef CONFIG_X86_LOCAL_APIC #include #include -#include +#include #endif static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c index e22d6ed26e6..4772e91e824 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c index 42f090702f0..5e8c79e748a 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/kernel/cpu/mcheck/p4.c b/arch/x86/kernel/cpu/mcheck/p4.c index f9c92b66dfb..9b60fce09f7 100644 --- a/arch/x86/kernel/cpu/mcheck/p4.c +++ b/arch/x86/kernel/cpu/mcheck/p4.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index ad7f2a696f4..3340cc0f244 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c @@ -28,7 +28,7 @@ #include #include -#include +#include #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) diff --git a/arch/x86/kernel/es7000_32.c b/arch/x86/kernel/es7000_32.c index 23f1df4ce18..6cdfb3e4dc3 100644 --- a/arch/x86/kernel/es7000_32.c +++ b/arch/x86/kernel/es7000_32.c @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include /* @@ -387,7 +387,7 @@ void __init es7000_enable_apic_mode(void) #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/kernel/genapic_64.c b/arch/x86/kernel/genapic_64.c index ef788635324..91cae6f6e73 100644 --- a/arch/x86/kernel/genapic_64.c +++ b/arch/x86/kernel/genapic_64.c @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include diff --git a/arch/x86/kernel/genapic_flat_64.c b/arch/x86/kernel/genapic_flat_64.c index 36ee760fd13..a7d84763648 100644 --- a/arch/x86/kernel/genapic_flat_64.c +++ b/arch/x86/kernel/genapic_flat_64.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #ifdef CONFIG_ACPI diff --git a/arch/x86/kernel/genx2apic_cluster.c b/arch/x86/kernel/genx2apic_cluster.c index dd6e8d68542..f5e02cffa26 100644 --- a/arch/x86/kernel/genx2apic_cluster.c +++ b/arch/x86/kernel/genx2apic_cluster.c @@ -7,7 +7,7 @@ #include #include -#include +#include #include DEFINE_PER_CPU(u32, x86_cpu_to_logical_apicid); diff --git a/arch/x86/kernel/genx2apic_phys.c b/arch/x86/kernel/genx2apic_phys.c index eb1486bb002..11eb4cb7ca3 100644 --- a/arch/x86/kernel/genx2apic_phys.c +++ b/arch/x86/kernel/genx2apic_phys.c @@ -7,7 +7,7 @@ #include #include -#include +#include #include static int x2apic_phys; diff --git a/arch/x86/kernel/genx2apic_uv_x.c b/arch/x86/kernel/genx2apic_uv_x.c index 9ae4a92fac8..c1746a198bd 100644 --- a/arch/x86/kernel/genx2apic_uv_x.c +++ b/arch/x86/kernel/genx2apic_uv_x.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c index a89878e08a4..00e6071cefc 100644 --- a/arch/x86/kernel/io_apic.c +++ b/arch/x86/kernel/io_apic.c @@ -62,7 +62,7 @@ #include #include -#include +#include #define __apicdebuginit(type) static type __init diff --git a/arch/x86/kernel/ipi.c b/arch/x86/kernel/ipi.c index 1326272cae4..dbf5445727a 100644 --- a/arch/x86/kernel/ipi.c +++ b/arch/x86/kernel/ipi.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 3957776b193..f13ca1650aa 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c index 4beb9a13873..e4ac7c80e2d 100644 --- a/arch/x86/kernel/irq_32.c +++ b/arch/x86/kernel/irq_32.c @@ -212,7 +212,7 @@ bool handle_irq(unsigned irq, struct pt_regs *regs) } #ifdef CONFIG_HOTPLUG_CPU -#include +#include /* A cpu has been removed from cpu_online_mask. Reset irq affinities. */ void fixup_irqs(void) diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index 5c4f5548384..eedfaebe106 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c @@ -46,7 +46,7 @@ #include #include -#include +#include /* * Put the error code here just in case the user cares: diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 20076445319..7f4d2586972 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c @@ -29,7 +29,7 @@ #include #include -#include +#include /* * Checksum an MP configuration block. */ diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c index 48b9ca5e088..bdfad80c3cf 100644 --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c @@ -11,7 +11,7 @@ * Mikael Pettersson : PM converted to driver model. Disable/enable API. */ -#include +#include #include #include diff --git a/arch/x86/kernel/numaq_32.c b/arch/x86/kernel/numaq_32.c index f0f0c2f0596..5a2d75d1fd4 100644 --- a/arch/x86/kernel/numaq_32.c +++ b/arch/x86/kernel/numaq_32.c @@ -31,7 +31,7 @@ #include #include -#include +#include #include #include #include @@ -301,7 +301,7 @@ int __init get_memcfg_numaq(void) #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/kernel/probe_32.c b/arch/x86/kernel/probe_32.c index b3d5d74e522..be0d554984a 100644 --- a/arch/x86/kernel/probe_32.c +++ b/arch/x86/kernel/probe_32.c @@ -17,20 +17,20 @@ #include #include #include -#include +#include #include #include #include #include -#include +#include #include #include #include #include #include #include -#include +#include #include #include @@ -41,7 +41,7 @@ #include #include -#include +#include #ifdef CONFIG_HOTPLUG_CPU #define DEFAULT_SEND_IPI (1) diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 32e8f0af292..7c8cd447d5e 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -24,7 +24,7 @@ # include #endif -#include +#include /* * Power off function, if any diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 43d964411c0..deaafd2693e 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -97,7 +97,7 @@ #include #include -#include +#include #include #include diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c index eaaffae31cc..13f33ea8cca 100644 --- a/arch/x86/kernel/smp.c +++ b/arch/x86/kernel/smp.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include /* * Some notes on x86 processor bugs affecting SMP operation: * diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index b5f2b698973..562a9fc3bc3 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -60,12 +60,12 @@ #include #include #include -#include +#include #include #include #include -#include +#include #include #ifdef CONFIG_X86_32 diff --git a/arch/x86/kernel/summit_32.c b/arch/x86/kernel/summit_32.c index 1cf32c325d1..eb31ba276bb 100644 --- a/arch/x86/kernel/summit_32.c +++ b/arch/x86/kernel/summit_32.c @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c index f396e61bcb3..1a7dfa7cb52 100644 --- a/arch/x86/kernel/tlb_uv.c +++ b/arch/x86/kernel/tlb_uv.c @@ -15,12 +15,12 @@ #include #include #include -#include +#include #include #include #include -#include +#include static struct bau_control **uv_bau_table_bases __read_mostly; static int uv_bau_retry_limit __read_mostly; diff --git a/arch/x86/kernel/uv_irq.c b/arch/x86/kernel/uv_irq.c index 75eb5ec5dd2..aeef529917e 100644 --- a/arch/x86/kernel/uv_irq.c +++ b/arch/x86/kernel/uv_irq.c @@ -11,7 +11,7 @@ #include #include -#include +#include #include static void uv_noop(unsigned int irq) diff --git a/arch/x86/kernel/visws_quirks.c b/arch/x86/kernel/visws_quirks.c index 4fd646e6dd4..5264fea6c28 100644 --- a/arch/x86/kernel/visws_quirks.c +++ b/arch/x86/kernel/visws_quirks.c @@ -32,9 +32,9 @@ #include #include -#include +#include -#include +#include #include diff --git a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c index a1c7b71dc0d..2cc4a90e2cb 100644 --- a/arch/x86/kernel/vmi_32.c +++ b/arch/x86/kernel/vmi_32.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/kernel/vmiclock_32.c b/arch/x86/kernel/vmiclock_32.c index 2a5e0e6a7c0..a4791ef412d 100644 --- a/arch/x86/kernel/vmiclock_32.c +++ b/arch/x86/kernel/vmiclock_32.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index bc9893f2c38..f3a5305b8ad 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c @@ -55,7 +55,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index 15df1baee10..574c8bc95ef 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include int acpi_numa __initdata; diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 14c5af4d11e..b641349fe07 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -14,7 +14,7 @@ DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) = { &init_mm, 0, }; -#include +#include /* * Smarter SMP flushing macros. * c/o Linus Torvalds. diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index a32a5c7a8ef..202864ad49a 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include "op_counter.h" #include "op_x86_model.h" diff --git a/arch/x86/oprofile/op_model_p4.c b/arch/x86/oprofile/op_model_p4.c index 09a237bc9ef..4c4a51c90bc 100644 --- a/arch/x86/oprofile/op_model_p4.c +++ b/arch/x86/oprofile/op_model_p4.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include "op_x86_model.h" diff --git a/arch/x86/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c index 5ebd8f605d7..e9f80c744cf 100644 --- a/arch/x86/oprofile/op_model_ppro.c +++ b/arch/x86/oprofile/op_model_ppro.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/x86/pci/numaq_32.c b/arch/x86/pci/numaq_32.c index 5601e829c38..8eb295e116f 100644 --- a/arch/x86/pci/numaq_32.c +++ b/arch/x86/pci/numaq_32.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index e3dd3fb6729..86497d5f44c 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -36,7 +36,7 @@ #include #include -#include +#include #include #include #include -- cgit From e641f5f525acb163ba71d92de79c9c7366deae03 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 17 Feb 2009 14:02:01 +0100 Subject: x86, apic: remove duplicate asm/apic.h inclusions Impact: cleanup Signed-off-by: Ingo Molnar --- arch/x86/include/asm/ipi.h | 2 -- arch/x86/kernel/acpi/boot.c | 1 - arch/x86/kernel/apic.c | 1 - arch/x86/kernel/cpu/amd.c | 2 -- arch/x86/kernel/cpu/common.c | 6 ++---- arch/x86/kernel/cpu/intel.c | 1 - arch/x86/kernel/crash.c | 2 -- arch/x86/kernel/es7000_32.c | 1 - arch/x86/kernel/irq_32.c | 1 - arch/x86/kernel/numaq_32.c | 1 - arch/x86/kernel/probe_32.c | 4 ---- arch/x86/kernel/reboot.c | 2 -- arch/x86/kernel/setup.c | 1 - arch/x86/kernel/smpboot.c | 1 - arch/x86/kernel/summit_32.c | 1 - arch/x86/kernel/tlb_uv.c | 2 -- arch/x86/kernel/visws_quirks.c | 7 +------ arch/x86/mm/tlb.c | 1 - 18 files changed, 3 insertions(+), 34 deletions(-) diff --git a/arch/x86/include/asm/ipi.h b/arch/x86/include/asm/ipi.h index 3395c680a97..0b7228268a6 100644 --- a/arch/x86/include/asm/ipi.h +++ b/arch/x86/include/asm/ipi.h @@ -123,8 +123,6 @@ extern void default_send_IPI_mask_sequence_phys(const struct cpumask *mask, int vector); extern void default_send_IPI_mask_allbutself_phys(const struct cpumask *mask, int vector); -#include - extern void default_send_IPI_mask_sequence_logical(const struct cpumask *mask, int vector); extern void default_send_IPI_mask_allbutself_logical(const struct cpumask *mask, diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 42814152c94..a18eb7ce223 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c index 7db03a9b61d..c12823eb55b 100644 --- a/arch/x86/kernel/apic.c +++ b/arch/x86/kernel/apic.c @@ -36,7 +36,6 @@ #include #include -#include #include #include #include diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index c94ba9311e6..25423a5b80e 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -12,8 +12,6 @@ # include #endif -#include - #include "cpu.h" #ifdef CONFIG_X86_32 diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 41f3788ec9b..826d5c87627 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -23,11 +23,9 @@ #include #include #include -#ifdef CONFIG_X86_LOCAL_APIC -#include -#include -#include #include + +#ifdef CONFIG_X86_LOCAL_APIC #include #endif diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 290f92e2b7c..7aeef1d327b 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -24,7 +24,6 @@ #ifdef CONFIG_X86_LOCAL_APIC #include #include -#include #endif static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index 3340cc0f244..ff958248e61 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c @@ -28,8 +28,6 @@ #include #include -#include - #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) diff --git a/arch/x86/kernel/es7000_32.c b/arch/x86/kernel/es7000_32.c index 6cdfb3e4dc3..352d870e5d5 100644 --- a/arch/x86/kernel/es7000_32.c +++ b/arch/x86/kernel/es7000_32.c @@ -387,7 +387,6 @@ void __init es7000_enable_apic_mode(void) #include #include #include -#include #include #include #include diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c index e4ac7c80e2d..9dc6b2b2427 100644 --- a/arch/x86/kernel/irq_32.c +++ b/arch/x86/kernel/irq_32.c @@ -212,7 +212,6 @@ bool handle_irq(unsigned irq, struct pt_regs *regs) } #ifdef CONFIG_HOTPLUG_CPU -#include /* A cpu has been removed from cpu_online_mask. Reset irq affinities. */ void fixup_irqs(void) diff --git a/arch/x86/kernel/numaq_32.c b/arch/x86/kernel/numaq_32.c index 5a2d75d1fd4..40400a58845 100644 --- a/arch/x86/kernel/numaq_32.c +++ b/arch/x86/kernel/numaq_32.c @@ -301,7 +301,6 @@ int __init get_memcfg_numaq(void) #include #include #include -#include #include #include #include diff --git a/arch/x86/kernel/probe_32.c b/arch/x86/kernel/probe_32.c index be0d554984a..fd1352ac909 100644 --- a/arch/x86/kernel/probe_32.c +++ b/arch/x86/kernel/probe_32.c @@ -23,14 +23,12 @@ #include #include #include -#include #include #include #include #include #include #include -#include #include #include @@ -41,8 +39,6 @@ #include #include -#include - #ifdef CONFIG_HOTPLUG_CPU #define DEFAULT_SEND_IPI (1) #else diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 7c8cd447d5e..1cc18d439bb 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -24,8 +24,6 @@ # include #endif -#include - /* * Power off function, if any */ diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index deaafd2693e..b2da0b1d15e 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -97,7 +97,6 @@ #include #include -#include #include #include diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 562a9fc3bc3..09e73876a44 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -65,7 +65,6 @@ #include #include -#include #include #ifdef CONFIG_X86_32 diff --git a/arch/x86/kernel/summit_32.c b/arch/x86/kernel/summit_32.c index eb31ba276bb..577b0bd8e53 100644 --- a/arch/x86/kernel/summit_32.c +++ b/arch/x86/kernel/summit_32.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c index 1a7dfa7cb52..f04549afcfe 100644 --- a/arch/x86/kernel/tlb_uv.c +++ b/arch/x86/kernel/tlb_uv.c @@ -20,8 +20,6 @@ #include #include -#include - static struct bau_control **uv_bau_table_bases __read_mostly; static int uv_bau_retry_limit __read_mostly; diff --git a/arch/x86/kernel/visws_quirks.c b/arch/x86/kernel/visws_quirks.c index 5264fea6c28..34199d30ff4 100644 --- a/arch/x86/kernel/visws_quirks.c +++ b/arch/x86/kernel/visws_quirks.c @@ -29,13 +29,10 @@ #include #include #include +#include #include #include -#include - -#include - #include #include @@ -49,8 +46,6 @@ extern int no_broadcast; -#include - char visws_board_type = -1; char visws_board_rev = -1; diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index b641349fe07..a654d59e448 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -14,7 +14,6 @@ DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) = { &init_mm, 0, }; -#include /* * Smarter SMP flushing macros. * c/o Linus Torvalds. -- cgit From 5c615feb90ce63f2293a7ac7809f320f46c75e0a Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 17 Feb 2009 14:04:24 +0100 Subject: x86, apic: remove stale references to APIC_DEFINITION Impact: cleanup APIC_DEFINITION was a hack from the x86 subarch times, it has no meaning anymore - remove it. Signed-off-by: Ingo Molnar --- arch/x86/kernel/bigsmp_32.c | 1 - arch/x86/kernel/es7000_32.c | 1 - arch/x86/kernel/numaq_32.c | 1 - arch/x86/kernel/summit_32.c | 1 - 4 files changed, 4 deletions(-) diff --git a/arch/x86/kernel/bigsmp_32.c b/arch/x86/kernel/bigsmp_32.c index 72f4e534051..f49af36351f 100644 --- a/arch/x86/kernel/bigsmp_32.c +++ b/arch/x86/kernel/bigsmp_32.c @@ -2,7 +2,6 @@ * APIC driver for "bigsmp" XAPIC machines with more than 8 virtual CPUs. * Drives the local APIC in "clustered mode". */ -#define APIC_DEFINITION 1 #include #include #include diff --git a/arch/x86/kernel/es7000_32.c b/arch/x86/kernel/es7000_32.c index 352d870e5d5..cf53a98dbf1 100644 --- a/arch/x86/kernel/es7000_32.c +++ b/arch/x86/kernel/es7000_32.c @@ -383,7 +383,6 @@ void __init es7000_enable_apic_mode(void) /* * APIC driver for the Unisys ES7000 chipset. */ -#define APIC_DEFINITION 1 #include #include #include diff --git a/arch/x86/kernel/numaq_32.c b/arch/x86/kernel/numaq_32.c index 40400a58845..dcf22f50827 100644 --- a/arch/x86/kernel/numaq_32.c +++ b/arch/x86/kernel/numaq_32.c @@ -297,7 +297,6 @@ int __init get_memcfg_numaq(void) /* * APIC driver for the IBM NUMAQ chipset. */ -#define APIC_DEFINITION 1 #include #include #include diff --git a/arch/x86/kernel/summit_32.c b/arch/x86/kernel/summit_32.c index 577b0bd8e53..30597778914 100644 --- a/arch/x86/kernel/summit_32.c +++ b/arch/x86/kernel/summit_32.c @@ -34,7 +34,6 @@ /* * APIC driver for the IBM "Summit" chipset. */ -#define APIC_DEFINITION 1 #include #include #include -- cgit From 77313190d121dd1fffa965aff6e9f0782a307bb8 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 17 Feb 2009 14:09:20 +0100 Subject: x86, apic: clean up arch/x86/kernel/bigsmp_32.c Impact: cleanup - remove unnecessary indirections that were artifacts of the subarch code - clean up include file section - clean up various small details Signed-off-by: Ingo Molnar --- arch/x86/kernel/bigsmp_32.c | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/arch/x86/kernel/bigsmp_32.c b/arch/x86/kernel/bigsmp_32.c index f49af36351f..41732abd700 100644 --- a/arch/x86/kernel/bigsmp_32.c +++ b/arch/x86/kernel/bigsmp_32.c @@ -1,27 +1,26 @@ /* - * APIC driver for "bigsmp" XAPIC machines with more than 8 virtual CPUs. + * APIC driver for "bigsmp" xAPIC machines with more than 8 virtual CPUs. + * * Drives the local APIC in "clustered mode". */ #include #include -#include -#include -#include -#include -#include #include #include #include #include +#include +#include +#include +#include +#include static inline unsigned bigsmp_get_apic_id(unsigned long x) { return (x >> 24) & 0xFF; } -#define xapic_phys_to_log_apicid(cpu) (per_cpu(x86_bios_cpu_apicid, cpu)) - static inline int bigsmp_apic_id_registered(void) { return 1; @@ -36,8 +35,6 @@ static inline const cpumask_t *bigsmp_target_cpus(void) #endif } -#define APIC_DFR_VALUE (APIC_DFR_FLAT) - static inline unsigned long bigsmp_check_apicid_used(physid_mask_t bitmap, int apicid) { @@ -52,9 +49,11 @@ static inline unsigned long bigsmp_check_apicid_present(int bit) static inline unsigned long calculate_ldr(int cpu) { unsigned long val, id; + val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; - id = xapic_phys_to_log_apicid(cpu); + id = per_cpu(x86_bios_cpu_apicid, cpu); val |= SET_APIC_LOGICAL_ID(id); + return val; } @@ -70,15 +69,16 @@ static inline void bigsmp_init_apic_ldr(void) unsigned long val; int cpu = smp_processor_id(); - apic_write(APIC_DFR, APIC_DFR_VALUE); + apic_write(APIC_DFR, APIC_DFR_FLAT); val = calculate_ldr(cpu); apic_write(APIC_LDR, val); } static inline void bigsmp_setup_apic_routing(void) { - printk("Enabling APIC mode: %s. Using %d I/O APICs\n", - "Physflat", nr_ioapics); + printk(KERN_INFO + "Enabling APIC mode: Physflat. Using %d I/O APICs\n", + nr_ioapics); } static inline int bigsmp_apicid_to_node(int logical_apicid) @@ -100,6 +100,7 @@ static inline physid_mask_t bigsmp_apicid_to_cpu_present(int phys_apicid) } extern u8 cpu_2_logical_apicid[]; + /* Mapping from cpu number to logical apicid */ static inline int bigsmp_cpu_to_logical_apicid(int cpu) { @@ -175,21 +176,24 @@ static int hp_ht_bigsmp(const struct dmi_system_id *d) { printk(KERN_NOTICE "%s detected: force use of apic=bigsmp\n", d->ident); dmi_bigsmp = 1; + return 0; } static const struct dmi_system_id bigsmp_dmi_table[] = { { hp_ht_bigsmp, "HP ProLiant DL760 G2", - { DMI_MATCH(DMI_BIOS_VENDOR, "HP"), - DMI_MATCH(DMI_BIOS_VERSION, "P44-"),} + { DMI_MATCH(DMI_BIOS_VENDOR, "HP"), + DMI_MATCH(DMI_BIOS_VERSION, "P44-"), + } }, { hp_ht_bigsmp, "HP ProLiant DL740", - { DMI_MATCH(DMI_BIOS_VENDOR, "HP"), - DMI_MATCH(DMI_BIOS_VERSION, "P47-"),} + { DMI_MATCH(DMI_BIOS_VENDOR, "HP"), + DMI_MATCH(DMI_BIOS_VERSION, "P47-"), + } }, - { } + { } /* NULL entry stops DMI scanning */ }; static void bigsmp_vector_allocation_domain(int cpu, cpumask_t *retmask) @@ -204,6 +208,7 @@ static int probe_bigsmp(void) dmi_bigsmp = 1; else dmi_check_system(bigsmp_dmi_table); + return dmi_bigsmp; } -- cgit From 2f205bc47f615b7bd0c7aba817d67ce25760eaf1 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 17 Feb 2009 14:45:30 +0100 Subject: x86, apic: clean up the cpu_2_logical_apiciddeclaration extern declarations were scattered in 4 files - consolidate them into apic.h. Signed-off-by: Ingo Molnar --- arch/x86/include/asm/apic.h | 4 ++++ arch/x86/kernel/bigsmp_32.c | 2 -- arch/x86/kernel/es7000_32.c | 3 +-- arch/x86/kernel/numaq_32.c | 5 +---- arch/x86/kernel/summit_32.c | 4 +--- 5 files changed, 7 insertions(+), 11 deletions(-) diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index c07f5fbf43c..2cdd19e4536 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -541,4 +541,8 @@ static inline physid_mask_t default_apicid_to_cpu_present(int phys_apicid) #endif /* CONFIG_X86_LOCAL_APIC */ +#ifdef CONFIG_X86_32 +extern u8 cpu_2_logical_apicid[NR_CPUS]; +#endif + #endif /* _ASM_X86_APIC_H */ diff --git a/arch/x86/kernel/bigsmp_32.c b/arch/x86/kernel/bigsmp_32.c index 41732abd700..0de9eed7c60 100644 --- a/arch/x86/kernel/bigsmp_32.c +++ b/arch/x86/kernel/bigsmp_32.c @@ -99,8 +99,6 @@ static inline physid_mask_t bigsmp_apicid_to_cpu_present(int phys_apicid) return physid_mask_of_physid(phys_apicid); } -extern u8 cpu_2_logical_apicid[]; - /* Mapping from cpu number to logical apicid */ static inline int bigsmp_cpu_to_logical_apicid(int cpu) { diff --git a/arch/x86/kernel/es7000_32.c b/arch/x86/kernel/es7000_32.c index cf53a98dbf1..3dc48831eb9 100644 --- a/arch/x86/kernel/es7000_32.c +++ b/arch/x86/kernel/es7000_32.c @@ -403,7 +403,6 @@ void __init es7000_enable_apic_mode(void) extern void es7000_enable_apic_mode(void); extern int apic_version [MAX_APICS]; -extern u8 cpu_2_logical_apicid[]; extern unsigned int boot_cpu_physical_apicid; extern int parse_unisys_oem (char *oemptr); @@ -570,7 +569,7 @@ static int es7000_cpu_to_logical_apicid(int cpu) #ifdef CONFIG_SMP if (cpu >= nr_cpu_ids) return BAD_APICID; - return (int)cpu_2_logical_apicid[cpu]; + return cpu_2_logical_apicid[cpu]; #else return logical_smp_processor_id(); #endif diff --git a/arch/x86/kernel/numaq_32.c b/arch/x86/kernel/numaq_32.c index dcf22f50827..9abaacde72e 100644 --- a/arch/x86/kernel/numaq_32.c +++ b/arch/x86/kernel/numaq_32.c @@ -408,14 +408,11 @@ static inline physid_mask_t numaq_ioapic_phys_id_map(physid_mask_t phys_map) return physids_promote(0xFUL); } -/* Mapping from cpu number to logical apicid */ -extern u8 cpu_2_logical_apicid[]; - static inline int numaq_cpu_to_logical_apicid(int cpu) { if (cpu >= nr_cpu_ids) return BAD_APICID; - return (int)cpu_2_logical_apicid[cpu]; + return cpu_2_logical_apicid[cpu]; } /* diff --git a/arch/x86/kernel/summit_32.c b/arch/x86/kernel/summit_32.c index 30597778914..7a1db1f2356 100644 --- a/arch/x86/kernel/summit_32.c +++ b/arch/x86/kernel/summit_32.c @@ -209,8 +209,6 @@ static inline unsigned long summit_check_apicid_present(int bit) #define apicid_cluster(apicid) ((apicid) & XAPIC_DEST_CLUSTER_MASK) -extern u8 cpu_2_logical_apicid[]; - static inline void summit_init_apic_ldr(void) { unsigned long val, id; @@ -264,7 +262,7 @@ static inline int summit_cpu_to_logical_apicid(int cpu) #ifdef CONFIG_SMP if (cpu >= nr_cpu_ids) return BAD_APICID; - return (int)cpu_2_logical_apicid[cpu]; + return cpu_2_logical_apicid[cpu]; #else return logical_smp_processor_id(); #endif -- cgit From 2c4ce18c95d632c9227ebcc6d45da11a9ef1ec70 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 17 Feb 2009 14:57:16 +0100 Subject: x86, es7000: clean up No code changed: arch/x86/kernel/es7000_32.o: text data bss dec hex filename 2813 192 44 3049 be9 es7000_32.o.before 2813 192 44 3049 be9 es7000_32.o.after md5: a593d98a882bf534622c70d9568497ac es7000_32.o.before.asm a593d98a882bf534622c70d9568497ac es7000_32.o.after.asm Signed-off-by: Ingo Molnar --- arch/x86/kernel/es7000_32.c | 241 +++++++++++++++++++++----------------------- 1 file changed, 113 insertions(+), 128 deletions(-) diff --git a/arch/x86/kernel/es7000_32.c b/arch/x86/kernel/es7000_32.c index 3dc48831eb9..c7cc9776cca 100644 --- a/arch/x86/kernel/es7000_32.c +++ b/arch/x86/kernel/es7000_32.c @@ -24,90 +24,96 @@ * http://www.unisys.com */ -#include -#include +#include +#include +#include +#include #include -#include +#include +#include #include -#include +#include #include -#include -#include -#include #include -#include -#include -#include -#include +#include +#include + #include -#include +#include +#include +#include #include +#include +#include +#include +#include +#include /* * ES7000 chipsets */ -#define NON_UNISYS 0 -#define ES7000_CLASSIC 1 -#define ES7000_ZORRO 2 +#define NON_UNISYS 0 +#define ES7000_CLASSIC 1 +#define ES7000_ZORRO 2 +#define MIP_REG 1 +#define MIP_PSAI_REG 4 -#define MIP_REG 1 -#define MIP_PSAI_REG 4 +#define MIP_BUSY 1 +#define MIP_SPIN 0xf0000 +#define MIP_VALID 0x0100000000000000ULL -#define MIP_BUSY 1 -#define MIP_SPIN 0xf0000 -#define MIP_VALID 0x0100000000000000ULL -#define MIP_PORT(VALUE) ((VALUE >> 32) & 0xffff) +#define MIP_PORT(val) ((val >> 32) & 0xffff) -#define MIP_RD_LO(VALUE) (VALUE & 0xffffffff) +#define MIP_RD_LO(val) (val & 0xffffffff) struct mip_reg_info { - unsigned long long mip_info; - unsigned long long delivery_info; - unsigned long long host_reg; - unsigned long long mip_reg; + unsigned long long mip_info; + unsigned long long delivery_info; + unsigned long long host_reg; + unsigned long long mip_reg; }; struct part_info { - unsigned char type; - unsigned char length; - unsigned char part_id; - unsigned char apic_mode; - unsigned long snum; - char ptype[16]; - char sname[64]; - char pname[64]; + unsigned char type; + unsigned char length; + unsigned char part_id; + unsigned char apic_mode; + unsigned long snum; + char ptype[16]; + char sname[64]; + char pname[64]; }; struct psai { - unsigned long long entry_type; - unsigned long long addr; - unsigned long long bep_addr; + unsigned long long entry_type; + unsigned long long addr; + unsigned long long bep_addr; }; struct es7000_mem_info { - unsigned char type; - unsigned char length; - unsigned char resv[6]; - unsigned long long start; - unsigned long long size; + unsigned char type; + unsigned char length; + unsigned char resv[6]; + unsigned long long start; + unsigned long long size; }; struct es7000_oem_table { - unsigned long long hdr; - struct mip_reg_info mip; - struct part_info pif; - struct es7000_mem_info shm; - struct psai psai; + unsigned long long hdr; + struct mip_reg_info mip; + struct part_info pif; + struct es7000_mem_info shm; + struct psai psai; }; #ifdef CONFIG_ACPI struct oem_table { - struct acpi_table_header Header; - u32 OEMTableAddr; - u32 OEMTableSize; + struct acpi_table_header Header; + u32 OEMTableAddr; + u32 OEMTableSize; }; extern int find_unisys_acpi_oem_table(unsigned long *oem_addr); @@ -115,36 +121,50 @@ extern void unmap_unisys_acpi_oem_table(unsigned long oem_addr); #endif struct mip_reg { - unsigned long long off_0; - unsigned long long off_8; - unsigned long long off_10; - unsigned long long off_18; - unsigned long long off_20; - unsigned long long off_28; - unsigned long long off_30; - unsigned long long off_38; + unsigned long long off_0x00; + unsigned long long off_0x08; + unsigned long long off_0x10; + unsigned long long off_0x18; + unsigned long long off_0x20; + unsigned long long off_0x28; + unsigned long long off_0x30; + unsigned long long off_0x38; }; -#define MIP_SW_APIC 0x1020b -#define MIP_FUNC(VALUE) (VALUE & 0xff) +#define MIP_SW_APIC 0x1020b +#define MIP_FUNC(VALUE) (VALUE & 0xff) + +#define APIC_DFR_VALUE_CLUSTER (APIC_DFR_CLUSTER) +#define INT_DELIVERY_MODE_CLUSTER (dest_LowestPrio) +#define INT_DEST_MODE_CLUSTER (1) /* logical delivery broadcast to all procs */ + +#define APIC_DFR_VALUE (APIC_DFR_FLAT) + +extern void es7000_enable_apic_mode(void); +extern int parse_unisys_oem (char *oemptr); +extern int find_unisys_acpi_oem_table(unsigned long *oem_addr); +extern void unmap_unisys_acpi_oem_table(unsigned long oem_addr); +extern void setup_unisys(void); + +#define apicid_cluster(apicid) (apicid & 0xF0) /* * ES7000 Globals */ -static volatile unsigned long *psai = NULL; -static struct mip_reg *mip_reg; -static struct mip_reg *host_reg; -static int mip_port; -static unsigned long mip_addr, host_addr; +static volatile unsigned long *psai = NULL; +static struct mip_reg *mip_reg; +static struct mip_reg *host_reg; +static int mip_port; +static unsigned long mip_addr, host_addr; -int es7000_plat; +int es7000_plat; /* * GSI override for ES7000 platforms. */ -static unsigned int base; +static unsigned int base; static int es7000_rename_gsi(int ioapic, int gsi) @@ -160,6 +180,7 @@ es7000_rename_gsi(int ioapic, int gsi) if (!ioapic && (gsi < 16)) gsi += base; + return gsi; } @@ -196,8 +217,7 @@ static int __init es7000_update_genapic(void) return 0; } -void __init -setup_unisys(void) +void __init setup_unisys(void) { /* * Determine the generation of the ES7000 currently running. @@ -219,8 +239,7 @@ setup_unisys(void) * Parse the OEM Table */ -int __init -parse_unisys_oem (char *oemptr) +int __init parse_unisys_oem (char *oemptr) { int i; int success = 0; @@ -277,12 +296,15 @@ parse_unisys_oem (char *oemptr) es7000_plat = NON_UNISYS; } else setup_unisys(); + return es7000_plat; } #ifdef CONFIG_ACPI -static unsigned long oem_addrX; -static unsigned long oem_size; + +static unsigned long oem_addrX; +static unsigned long oem_size; + int __init find_unisys_acpi_oem_table(unsigned long *oem_addr) { struct acpi_table_header *header = NULL; @@ -315,8 +337,7 @@ void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr) } #endif -static void -es7000_spin(int n) +static void es7000_spin(int n) { int i = 0; @@ -327,16 +348,15 @@ es7000_spin(int n) static int __init es7000_mip_write(struct mip_reg *mip_reg) { - int status = 0; - int spin; + int status = 0; + int spin; spin = MIP_SPIN; - while (((unsigned long long)host_reg->off_38 & - (unsigned long long)MIP_VALID) != 0) { - if (--spin <= 0) { - printk("es7000_mip_write: Timeout waiting for Host Valid Flag"); - return -1; - } + while ((host_reg->off_0x38 & MIP_VALID) != 0) { + if (--spin <= 0) { + printk("es7000_mip_write: Timeout waiting for Host Valid Flag"); + return -1; + } es7000_spin(MIP_SPIN); } @@ -345,8 +365,7 @@ es7000_mip_write(struct mip_reg *mip_reg) spin = MIP_SPIN; - while (((unsigned long long)mip_reg->off_38 & - (unsigned long long)MIP_VALID) == 0) { + while ((mip_reg->off_0x38 & MIP_VALID) == 0) { if (--spin <= 0) { printk("es7000_mip_write: Timeout waiting for MIP Valid Flag"); return -1; @@ -354,10 +373,9 @@ es7000_mip_write(struct mip_reg *mip_reg) es7000_spin(MIP_SPIN); } - status = ((unsigned long long)mip_reg->off_0 & - (unsigned long long)0xffff0000000000ULL) >> 48; - mip_reg->off_38 = ((unsigned long long)mip_reg->off_38 & - (unsigned long long)~MIP_VALID); + status = (mip_reg->off_0x00 & 0xffff0000000000ULL) >> 48; + mip_reg->off_0x38 &= ~MIP_VALID; + return status; } @@ -371,8 +389,8 @@ void __init es7000_enable_apic_mode(void) printk("ES7000: Enabling APIC mode.\n"); memset(&es7000_mip_reg, 0, sizeof(struct mip_reg)); - es7000_mip_reg.off_0 = MIP_SW_APIC; - es7000_mip_reg.off_38 = MIP_VALID; + es7000_mip_reg.off_0x00 = MIP_SW_APIC; + es7000_mip_reg.off_0x38 = MIP_VALID; while ((mip_status = es7000_mip_write(&es7000_mip_reg)) != 0) { printk("es7000_enable_apic_mode: command failed, status = %x\n", @@ -380,39 +398,6 @@ void __init es7000_enable_apic_mode(void) } } -/* - * APIC driver for the Unisys ES7000 chipset. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define APIC_DFR_VALUE_CLUSTER (APIC_DFR_CLUSTER) -#define INT_DELIVERY_MODE_CLUSTER (dest_LowestPrio) -#define INT_DEST_MODE_CLUSTER (1) /* logical delivery broadcast to all procs */ - -#define APIC_DFR_VALUE (APIC_DFR_FLAT) - -extern void es7000_enable_apic_mode(void); -extern int apic_version [MAX_APICS]; -extern unsigned int boot_cpu_physical_apicid; - -extern int parse_unisys_oem (char *oemptr); -extern int find_unisys_acpi_oem_table(unsigned long *oem_addr); -extern void unmap_unisys_acpi_oem_table(unsigned long oem_addr); -extern void setup_unisys(void); - -#define apicid_cluster(apicid) (apicid & 0xF0) -#define xapic_phys_to_log_apicid(cpu) per_cpu(x86_bios_cpu_apicid, cpu) - static void es7000_vector_allocation_domain(int cpu, cpumask_t *retmask) { /* Careful. Some cpus do not strictly honor the set of cpus @@ -495,9 +480,9 @@ static unsigned long es7000_check_apicid_present(int bit) static unsigned long calculate_ldr(int cpu) { - unsigned long id = xapic_phys_to_log_apicid(cpu); + unsigned long id = per_cpu(x86_bios_cpu_apicid, cpu); - return (SET_APIC_LOGICAL_ID(id)); + return SET_APIC_LOGICAL_ID(id); } /* @@ -547,7 +532,7 @@ static int es7000_cpu_present_to_apicid(int mps_cpu) if (!mps_cpu) return boot_cpu_physical_apicid; else if (mps_cpu < nr_cpu_ids) - return (int) per_cpu(x86_bios_cpu_apicid, mps_cpu); + return per_cpu(x86_bios_cpu_apicid, mps_cpu); else return BAD_APICID; } @@ -584,7 +569,7 @@ static physid_mask_t es7000_ioapic_phys_id_map(physid_mask_t phys_map) static int es7000_check_phys_apicid_present(int cpu_physical_apicid) { boot_cpu_physical_apicid = read_apic_id(); - return (1); + return 1; } static unsigned int -- cgit From b9e0d1aa9767707cad24db32d8ce0409df16d491 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 17 Feb 2009 15:09:08 +0100 Subject: x86, apic: remove apicid_cluster() There were multiple definitions of apicid_cluster() scattered around in APIC drivers - but the definitions are equivalent to the already existing generic APIC_CLUSTER() method. So remove apicid_cluster() and change all users to APIC_CLUSTER(). No code changed: md5: 1b8244ba8d3d6a454593ce10f09dfa58 summit_32.o.before.asm 1b8244ba8d3d6a454593ce10f09dfa58 summit_32.o.after.asm md5: a593d98a882bf534622c70d9568497ac es7000_32.o.before.asm a593d98a882bf534622c70d9568497ac es7000_32.o.after.asm Signed-off-by: Ingo Molnar --- arch/x86/kernel/es7000_32.c | 8 ++------ arch/x86/kernel/numaq_32.c | 2 -- arch/x86/kernel/summit_32.c | 9 +++------ 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/arch/x86/kernel/es7000_32.c b/arch/x86/kernel/es7000_32.c index c7cc9776cca..8a20866b2a3 100644 --- a/arch/x86/kernel/es7000_32.c +++ b/arch/x86/kernel/es7000_32.c @@ -146,8 +146,6 @@ extern int find_unisys_acpi_oem_table(unsigned long *oem_addr); extern void unmap_unisys_acpi_oem_table(unsigned long oem_addr); extern void setup_unisys(void); -#define apicid_cluster(apicid) (apicid & 0xF0) - /* * ES7000 Globals */ @@ -595,8 +593,7 @@ es7000_cpu_mask_to_apicid_cluster(const struct cpumask *cpumask) if (cpumask_test_cpu(cpu, cpumask)) { int new_apicid = es7000_cpu_to_logical_apicid(cpu); - if (apicid_cluster(apicid) != - apicid_cluster(new_apicid)) { + if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { printk ("%s: Not a valid mask!\n", __func__); return 0xFF; @@ -630,8 +627,7 @@ static unsigned int es7000_cpu_mask_to_apicid(const cpumask_t *cpumask) if (cpu_isset(cpu, *cpumask)) { int new_apicid = es7000_cpu_to_logical_apicid(cpu); - if (apicid_cluster(apicid) != - apicid_cluster(new_apicid)) { + if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { printk ("%s: Not a valid mask!\n", __func__); return es7000_cpu_to_logical_apicid(0); diff --git a/arch/x86/kernel/numaq_32.c b/arch/x86/kernel/numaq_32.c index 9abaacde72e..15328500de6 100644 --- a/arch/x86/kernel/numaq_32.c +++ b/arch/x86/kernel/numaq_32.c @@ -375,8 +375,6 @@ static inline unsigned long numaq_check_apicid_present(int bit) return physid_isset(bit, phys_cpu_present_map); } -#define apicid_cluster(apicid) (apicid & 0xF0) - static inline int numaq_apic_id_registered(void) { return 1; diff --git a/arch/x86/kernel/summit_32.c b/arch/x86/kernel/summit_32.c index 7a1db1f2356..c4690349a54 100644 --- a/arch/x86/kernel/summit_32.c +++ b/arch/x86/kernel/summit_32.c @@ -207,14 +207,12 @@ static inline unsigned long summit_check_apicid_present(int bit) return 1; } -#define apicid_cluster(apicid) ((apicid) & XAPIC_DEST_CLUSTER_MASK) - static inline void summit_init_apic_ldr(void) { unsigned long val, id; int count = 0; u8 my_id = (u8)hard_smp_processor_id(); - u8 my_cluster = (u8)apicid_cluster(my_id); + u8 my_cluster = APIC_CLUSTER(my_id); #ifdef CONFIG_SMP u8 lid; int i; @@ -222,7 +220,7 @@ static inline void summit_init_apic_ldr(void) /* Create logical APIC IDs by counting CPUs already in cluster. */ for (count = 0, i = nr_cpu_ids; --i >= 0; ) { lid = cpu_2_logical_apicid[i]; - if (lid != BAD_APICID && apicid_cluster(lid) == my_cluster) + if (lid != BAD_APICID && APIC_CLUSTER(lid) == my_cluster) ++count; } #endif @@ -319,8 +317,7 @@ static inline unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask) if (cpu_isset(cpu, *cpumask)) { int new_apicid = summit_cpu_to_logical_apicid(cpu); - if (apicid_cluster(apicid) != - apicid_cluster(new_apicid)) { + if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { printk ("%s: Not a valid mask!\n", __func__); return 0xFF; -- cgit From d3185b37df05e9ad7ce987a9a0419ffe1af9d23f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 17 Feb 2009 15:13:05 +0100 Subject: x86, es7000: remove externs Impact: cleanup In the subarch times there were a number of externs between various bits of the ES7000 code. Now that there's a single es7000-platform support file, the externs can be removed and the functions can be changed the statics. Beyond the cleanup factor, this also shrinks the size of the kernel image a bit: arch/x86/kernel/es7000_32.o: text data bss dec hex filename 2813 192 44 3049 be9 es7000_32.o.before 2693 192 44 2929 b71 es7000_32.o.after Signed-off-by: Ingo Molnar --- arch/x86/kernel/es7000_32.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/arch/x86/kernel/es7000_32.c b/arch/x86/kernel/es7000_32.c index 8a20866b2a3..d5c3894a983 100644 --- a/arch/x86/kernel/es7000_32.c +++ b/arch/x86/kernel/es7000_32.c @@ -116,8 +116,6 @@ struct oem_table { u32 OEMTableSize; }; -extern int find_unisys_acpi_oem_table(unsigned long *oem_addr); -extern void unmap_unisys_acpi_oem_table(unsigned long oem_addr); #endif struct mip_reg { @@ -140,12 +138,6 @@ struct mip_reg { #define APIC_DFR_VALUE (APIC_DFR_FLAT) -extern void es7000_enable_apic_mode(void); -extern int parse_unisys_oem (char *oemptr); -extern int find_unisys_acpi_oem_table(unsigned long *oem_addr); -extern void unmap_unisys_acpi_oem_table(unsigned long oem_addr); -extern void setup_unisys(void); - /* * ES7000 Globals */ @@ -215,7 +207,7 @@ static int __init es7000_update_genapic(void) return 0; } -void __init setup_unisys(void) +static void __init setup_unisys(void) { /* * Determine the generation of the ES7000 currently running. @@ -234,10 +226,9 @@ void __init setup_unisys(void) } /* - * Parse the OEM Table + * Parse the OEM Table: */ - -int __init parse_unisys_oem (char *oemptr) +static int __init parse_unisys_oem (char *oemptr) { int i; int success = 0; @@ -290,9 +281,9 @@ int __init parse_unisys_oem (char *oemptr) tp += size; } - if (success < 2) { + if (success < 2) es7000_plat = NON_UNISYS; - } else + else setup_unisys(); return es7000_plat; @@ -303,7 +294,7 @@ int __init parse_unisys_oem (char *oemptr) static unsigned long oem_addrX; static unsigned long oem_size; -int __init find_unisys_acpi_oem_table(unsigned long *oem_addr) +static int __init find_unisys_acpi_oem_table(unsigned long *oem_addr) { struct acpi_table_header *header = NULL; int i = 0; @@ -326,7 +317,7 @@ int __init find_unisys_acpi_oem_table(unsigned long *oem_addr) return -1; } -void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr) +static void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr) { if (!oem_addr) return; @@ -377,7 +368,7 @@ es7000_mip_write(struct mip_reg *mip_reg) return status; } -void __init es7000_enable_apic_mode(void) +static void __init es7000_enable_apic_mode(void) { struct mip_reg es7000_mip_reg; int mip_status; @@ -706,9 +697,9 @@ static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id) check_dsdt = es7000_check_dsdt(); if (!find_unisys_acpi_oem_table(&oem_addr)) { - if (check_dsdt) + if (check_dsdt) { ret = parse_unisys_oem((char *)oem_addr); - else { + } else { setup_unisys(); ret = 1; } -- cgit From 352887d1c9d99d4c2f0fbac6176ef0cd4fe7a820 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 17 Feb 2009 15:17:55 +0100 Subject: x86, es7000: remove dead code, clean up Impact: cleanup - a number of structure definitions were stale - remove needless wrappers around apic definitions - fix details noticed by checkpatch No code changed: md5: 029d8fde0aaf6e934ea63bd8b36430fd es7000_32.o.before.asm 029d8fde0aaf6e934ea63bd8b36430fd es7000_32.o.after.asm Signed-off-by: Ingo Molnar --- arch/x86/kernel/es7000_32.c | 103 ++++++++++++++------------------------------ 1 file changed, 33 insertions(+), 70 deletions(-) diff --git a/arch/x86/kernel/es7000_32.c b/arch/x86/kernel/es7000_32.c index d5c3894a983..03acbe95d2b 100644 --- a/arch/x86/kernel/es7000_32.c +++ b/arch/x86/kernel/es7000_32.c @@ -23,7 +23,6 @@ * * http://www.unisys.com */ - #include #include #include @@ -63,11 +62,23 @@ #define MIP_BUSY 1 #define MIP_SPIN 0xf0000 #define MIP_VALID 0x0100000000000000ULL +#define MIP_SW_APIC 0x1020b #define MIP_PORT(val) ((val >> 32) & 0xffff) #define MIP_RD_LO(val) (val & 0xffffffff) +struct mip_reg { + unsigned long long off_0x00; + unsigned long long off_0x08; + unsigned long long off_0x10; + unsigned long long off_0x18; + unsigned long long off_0x20; + unsigned long long off_0x28; + unsigned long long off_0x30; + unsigned long long off_0x38; +}; + struct mip_reg_info { unsigned long long mip_info; unsigned long long delivery_info; @@ -75,69 +86,20 @@ struct mip_reg_info { unsigned long long mip_reg; }; -struct part_info { - unsigned char type; - unsigned char length; - unsigned char part_id; - unsigned char apic_mode; - unsigned long snum; - char ptype[16]; - char sname[64]; - char pname[64]; -}; - struct psai { unsigned long long entry_type; unsigned long long addr; unsigned long long bep_addr; }; -struct es7000_mem_info { - unsigned char type; - unsigned char length; - unsigned char resv[6]; - unsigned long long start; - unsigned long long size; -}; - -struct es7000_oem_table { - unsigned long long hdr; - struct mip_reg_info mip; - struct part_info pif; - struct es7000_mem_info shm; - struct psai psai; -}; - #ifdef CONFIG_ACPI - -struct oem_table { +struct es7000_oem_table { struct acpi_table_header Header; u32 OEMTableAddr; u32 OEMTableSize; }; - #endif -struct mip_reg { - unsigned long long off_0x00; - unsigned long long off_0x08; - unsigned long long off_0x10; - unsigned long long off_0x18; - unsigned long long off_0x20; - unsigned long long off_0x28; - unsigned long long off_0x30; - unsigned long long off_0x38; -}; - -#define MIP_SW_APIC 0x1020b -#define MIP_FUNC(VALUE) (VALUE & 0xff) - -#define APIC_DFR_VALUE_CLUSTER (APIC_DFR_CLUSTER) -#define INT_DELIVERY_MODE_CLUSTER (dest_LowestPrio) -#define INT_DEST_MODE_CLUSTER (1) /* logical delivery broadcast to all procs */ - -#define APIC_DFR_VALUE (APIC_DFR_FLAT) - /* * ES7000 Globals */ @@ -228,14 +190,14 @@ static void __init setup_unisys(void) /* * Parse the OEM Table: */ -static int __init parse_unisys_oem (char *oemptr) +static int __init parse_unisys_oem(char *oemptr) { - int i; + int i; int success = 0; - unsigned char type, size; - unsigned long val; - char *tp = NULL; - struct psai *psaip = NULL; + unsigned char type, size; + unsigned long val; + char *tp = NULL; + struct psai *psaip = NULL; struct mip_reg_info *mi; struct mip_reg *host, *mip; @@ -243,7 +205,7 @@ static int __init parse_unisys_oem (char *oemptr) tp += 8; - for (i=0; i <= 6; i++) { + for (i = 0; i <= 6; i++) { type = *tp++; size = *tp++; tp -= 2; @@ -302,7 +264,7 @@ static int __init find_unisys_acpi_oem_table(unsigned long *oem_addr) while (ACPI_SUCCESS(acpi_get_table_with_size("OEM1", i++, &header, &tbl_size))) { if (!memcmp((char *) &header->oem_id, "UNISYS", 6)) { - struct oem_table *t = (struct oem_table *)header; + struct es7000_oem_table *t = (void *)header; oem_addrX = t->OEMTableAddr; oem_size = t->OEMTableSize; @@ -377,11 +339,11 @@ static void __init es7000_enable_apic_mode(void) return; printk("ES7000: Enabling APIC mode.\n"); - memset(&es7000_mip_reg, 0, sizeof(struct mip_reg)); - es7000_mip_reg.off_0x00 = MIP_SW_APIC; - es7000_mip_reg.off_0x38 = MIP_VALID; + memset(&es7000_mip_reg, 0, sizeof(struct mip_reg)); + es7000_mip_reg.off_0x00 = MIP_SW_APIC; + es7000_mip_reg.off_0x38 = MIP_VALID; - while ((mip_status = es7000_mip_write(&es7000_mip_reg)) != 0) { + while ((mip_status = es7000_mip_write(&es7000_mip_reg)) != 0) { printk("es7000_enable_apic_mode: command failed, status = %x\n", mip_status); } @@ -444,7 +406,7 @@ static void es7000_send_IPI_all(int vector) static int es7000_apic_id_registered(void) { - return 1; + return 1; } static const cpumask_t *target_cpus_cluster(void) @@ -486,7 +448,7 @@ static void es7000_init_apic_ldr_cluster(void) unsigned long val; int cpu = smp_processor_id(); - apic_write(APIC_DFR, APIC_DFR_VALUE_CLUSTER); + apic_write(APIC_DFR, APIC_DFR_CLUSTER); val = calculate_ldr(cpu); apic_write(APIC_LDR, val); } @@ -496,7 +458,7 @@ static void es7000_init_apic_ldr(void) unsigned long val; int cpu = smp_processor_id(); - apic_write(APIC_DFR, APIC_DFR_VALUE); + apic_write(APIC_DFR, APIC_DFR_FLAT); val = calculate_ldr(cpu); apic_write(APIC_LDR, val); } @@ -585,7 +547,7 @@ es7000_cpu_mask_to_apicid_cluster(const struct cpumask *cpumask) int new_apicid = es7000_cpu_to_logical_apicid(cpu); if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { - printk ("%s: Not a valid mask!\n", __func__); + printk("%s: Not a valid mask!\n", __func__); return 0xFF; } @@ -619,7 +581,7 @@ static unsigned int es7000_cpu_mask_to_apicid(const cpumask_t *cpumask) int new_apicid = es7000_cpu_to_logical_apicid(cpu); if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { - printk ("%s: Not a valid mask!\n", __func__); + printk("%s: Not a valid mask!\n", __func__); return es7000_cpu_to_logical_apicid(0); } @@ -658,8 +620,9 @@ static int es7000_phys_pkg_id(int cpuid_apic, int index_msb) void __init es7000_update_genapic_to_cluster(void) { apic->target_cpus = target_cpus_cluster; - apic->irq_delivery_mode = INT_DELIVERY_MODE_CLUSTER; - apic->irq_dest_mode = INT_DEST_MODE_CLUSTER; + apic->irq_delivery_mode = dest_LowestPrio; + /* logical delivery broadcast to all procs: */ + apic->irq_dest_mode = 1; apic->init_apic_ldr = es7000_init_apic_ldr_cluster; -- cgit From 7da18ed924b182f8174de243c55a323c56398675 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 17 Feb 2009 15:29:30 +0100 Subject: x86, es7000: misc cleanups These are cleanups that change the md5 signature: - asm/ => linux/ include conversion - simplify the code flow of find_unisys_acpi_oem_table() - move ACPI methods into one #ifdef block - remove 0/NULL initialization of statics - simplify/standardize printouts - update copyrights - more cleanups, pointed out by checkpatch arch/x86/kernel/es7000_32.o: text data bss dec hex filename 2693 192 44 2929 b71 es7000_32.o.before 2688 192 44 2924 b6c es7000_32.o.after Signed-off-by: Ingo Molnar --- arch/x86/kernel/es7000_32.c | 170 +++++++++++++++++++++++--------------------- 1 file changed, 90 insertions(+), 80 deletions(-) diff --git a/arch/x86/kernel/es7000_32.c b/arch/x86/kernel/es7000_32.c index 03acbe95d2b..3519f8cab70 100644 --- a/arch/x86/kernel/es7000_32.c +++ b/arch/x86/kernel/es7000_32.c @@ -1,10 +1,14 @@ /* * Written by: Garry Forsgren, Unisys Corporation * Natalie Protasevich, Unisys Corporation + * * This file contains the code to configure and interface * with Unisys ES7000 series hardware system manager. * - * Copyright (c) 2003 Unisys Corporation. All Rights Reserved. + * Copyright (c) 2003 Unisys Corporation. + * Copyright (C) 2009, Red Hat, Inc., Ingo Molnar + * + * All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -35,7 +39,9 @@ #include #include #include +#include #include +#include #include #include @@ -44,9 +50,6 @@ #include #include #include -#include -#include -#include /* * ES7000 chipsets @@ -93,22 +96,28 @@ struct psai { }; #ifdef CONFIG_ACPI + struct es7000_oem_table { struct acpi_table_header Header; u32 OEMTableAddr; u32 OEMTableSize; }; + +static unsigned long oem_addrX; +static unsigned long oem_size; + #endif /* * ES7000 Globals */ -static volatile unsigned long *psai = NULL; +static volatile unsigned long *psai; static struct mip_reg *mip_reg; static struct mip_reg *host_reg; static int mip_port; -static unsigned long mip_addr, host_addr; +static unsigned long mip_addr; +static unsigned long host_addr; int es7000_plat; @@ -252,31 +261,35 @@ static int __init parse_unisys_oem(char *oemptr) } #ifdef CONFIG_ACPI - -static unsigned long oem_addrX; -static unsigned long oem_size; - static int __init find_unisys_acpi_oem_table(unsigned long *oem_addr) { struct acpi_table_header *header = NULL; - int i = 0; + struct es7000_oem_table *table; acpi_size tbl_size; + acpi_status ret; + int i = 0; - while (ACPI_SUCCESS(acpi_get_table_with_size("OEM1", i++, &header, &tbl_size))) { - if (!memcmp((char *) &header->oem_id, "UNISYS", 6)) { - struct es7000_oem_table *t = (void *)header; + for (;;) { + ret = acpi_get_table_with_size("OEM1", i++, &header, &tbl_size); + if (!ACPI_SUCCESS(ret)) + return -1; - oem_addrX = t->OEMTableAddr; - oem_size = t->OEMTableSize; - early_acpi_os_unmap_memory(header, tbl_size); + if (!memcmp((char *) &header->oem_id, "UNISYS", 6)) + break; - *oem_addr = (unsigned long)__acpi_map_table(oem_addrX, - oem_size); - return 0; - } early_acpi_os_unmap_memory(header, tbl_size); } - return -1; + + table = (void *)header; + + oem_addrX = table->OEMTableAddr; + oem_size = table->OEMTableSize; + + early_acpi_os_unmap_memory(header, tbl_size); + + *oem_addr = (unsigned long)__acpi_map_table(oem_addrX, oem_size); + + return 0; } static void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr) @@ -286,7 +299,47 @@ static void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr) __acpi_unmap_table((char *)oem_addr, oem_size); } -#endif + +static int es7000_check_dsdt(void) +{ + struct acpi_table_header header; + + if (ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_DSDT, 0, &header)) && + !strncmp(header.oem_id, "UNISYS", 6)) + return 1; + return 0; +} + +/* Hook from generic ACPI tables.c */ +static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id) +{ + unsigned long oem_addr = 0; + int check_dsdt; + int ret = 0; + + /* check dsdt at first to avoid clear fix_map for oem_addr */ + check_dsdt = es7000_check_dsdt(); + + if (!find_unisys_acpi_oem_table(&oem_addr)) { + if (check_dsdt) { + ret = parse_unisys_oem((char *)oem_addr); + } else { + setup_unisys(); + ret = 1; + } + /* + * we need to unmap it + */ + unmap_unisys_acpi_oem_table(oem_addr); + } + return ret; +} +#else /* !CONFIG_ACPI: */ +static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id) +{ + return 0; +} +#endif /* !CONFIG_ACPI */ static void es7000_spin(int n) { @@ -305,7 +358,7 @@ es7000_mip_write(struct mip_reg *mip_reg) spin = MIP_SPIN; while ((host_reg->off_0x38 & MIP_VALID) != 0) { if (--spin <= 0) { - printk("es7000_mip_write: Timeout waiting for Host Valid Flag"); + WARN(1, "Timeout waiting for Host Valid Flag\n"); return -1; } es7000_spin(MIP_SPIN); @@ -318,7 +371,7 @@ es7000_mip_write(struct mip_reg *mip_reg) while ((mip_reg->off_0x38 & MIP_VALID) == 0) { if (--spin <= 0) { - printk("es7000_mip_write: Timeout waiting for MIP Valid Flag"); + WARN(1, "Timeout waiting for MIP Valid Flag\n"); return -1; } es7000_spin(MIP_SPIN); @@ -338,15 +391,13 @@ static void __init es7000_enable_apic_mode(void) if (!es7000_plat) return; - printk("ES7000: Enabling APIC mode.\n"); + printk(KERN_INFO "ES7000: Enabling APIC mode.\n"); memset(&es7000_mip_reg, 0, sizeof(struct mip_reg)); es7000_mip_reg.off_0x00 = MIP_SW_APIC; es7000_mip_reg.off_0x38 = MIP_VALID; - while ((mip_status = es7000_mip_write(&es7000_mip_reg)) != 0) { - printk("es7000_enable_apic_mode: command failed, status = %x\n", - mip_status); - } + while ((mip_status = es7000_mip_write(&es7000_mip_reg)) != 0) + WARN(1, "Command failed, status = %x\n", mip_status); } static void es7000_vector_allocation_domain(int cpu, cpumask_t *retmask) @@ -377,18 +428,6 @@ static unsigned int es7000_get_apic_id(unsigned long x) return (x >> 24) & 0xFF; } -#ifdef CONFIG_ACPI -static int es7000_check_dsdt(void) -{ - struct acpi_table_header header; - - if (ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_DSDT, 0, &header)) && - !strncmp(header.oem_id, "UNISYS", 6)) - return 1; - return 0; -} -#endif - static void es7000_send_IPI_mask(const struct cpumask *mask, int vector) { default_send_IPI_mask_sequence_phys(mask, vector); @@ -466,10 +505,12 @@ static void es7000_init_apic_ldr(void) static void es7000_setup_apic_routing(void) { int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id()); - printk("Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n", + + printk(KERN_INFO + "Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n", (apic_version[apic] == 0x14) ? "Physical Cluster" : "Logical Cluster", - nr_ioapics, cpus_addr(*es7000_target_cpus())[0]); + nr_ioapics, cpus_addr(*es7000_target_cpus())[0]); } static int es7000_apicid_to_node(int logical_apicid) @@ -488,13 +529,14 @@ static int es7000_cpu_present_to_apicid(int mps_cpu) return BAD_APICID; } +static int cpu_id; + static physid_mask_t es7000_apicid_to_cpu_present(int phys_apicid) { - static int id = 0; physid_mask_t mask; - mask = physid_mask_of_physid(id); - ++id; + mask = physid_mask_of_physid(cpu_id); + ++cpu_id; return mask; } @@ -547,7 +589,7 @@ es7000_cpu_mask_to_apicid_cluster(const struct cpumask *cpumask) int new_apicid = es7000_cpu_to_logical_apicid(cpu); if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { - printk("%s: Not a valid mask!\n", __func__); + WARN(1, "Not a valid mask!"); return 0xFF; } @@ -648,38 +690,6 @@ es7000_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) return 0; } -#ifdef CONFIG_ACPI -/* Hook from generic ACPI tables.c */ -static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id) -{ - unsigned long oem_addr = 0; - int check_dsdt; - int ret = 0; - - /* check dsdt at first to avoid clear fix_map for oem_addr */ - check_dsdt = es7000_check_dsdt(); - - if (!find_unisys_acpi_oem_table(&oem_addr)) { - if (check_dsdt) { - ret = parse_unisys_oem((char *)oem_addr); - } else { - setup_unisys(); - ret = 1; - } - /* - * we need to unmap it - */ - unmap_unisys_acpi_oem_table(oem_addr); - } - return ret; -} -#else -static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id) -{ - return 0; -} -#endif - struct genapic apic_es7000 = { -- cgit From 36afc3af04f4d3dfa709f7659fcadb3336d66ed2 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 17 Feb 2009 15:50:25 +0100 Subject: x86, numaq_32: clean up Impact: cleanup - refactor smp_dump_qct() - tidy up include files, remove duplicates - misc other cleanups, pointed out by checkpatch No code changed: md5: 9c0bc01a53558c77df0f2ebcda7e11a9 numaq_32.o.before.asm 9c0bc01a53558c77df0f2ebcda7e11a9 numaq_32.o.after.asm Signed-off-by: Ingo Molnar --- arch/x86/kernel/numaq_32.c | 195 +++++++++++++++++++++++---------------------- 1 file changed, 100 insertions(+), 95 deletions(-) diff --git a/arch/x86/kernel/numaq_32.c b/arch/x86/kernel/numaq_32.c index 15328500de6..a4ea08a9ac9 100644 --- a/arch/x86/kernel/numaq_32.c +++ b/arch/x86/kernel/numaq_32.c @@ -22,21 +22,54 @@ * * Send feedback to */ - #include #include +#include +#include +#include #include #include +#include +#include +#include +#include #include #include #include -#include +#include +#include #include #include +#include #include +#include +#include -#define MB_TO_PAGES(addr) ((addr) << (20 - PAGE_SHIFT)) +#define MB_TO_PAGES(addr) ((addr) << (20 - PAGE_SHIFT)) + +static inline void numaq_register_node(int node, struct sys_cfg_data *scd) +{ + struct eachquadmem *eq = scd->eq + node; + + node_set_online(node); + + /* Convert to pages */ + node_start_pfn[node] = + MB_TO_PAGES(eq->hi_shrd_mem_start - eq->priv_mem_size); + + node_end_pfn[node] = + MB_TO_PAGES(eq->hi_shrd_mem_start + eq->hi_shrd_mem_size); + + e820_register_active_regions(node, node_start_pfn[node], + node_end_pfn[node]); + + memory_present(node, node_start_pfn[node], node_end_pfn[node]); + + node_remap_size[node] = node_memmap_size_bytes(node, + node_start_pfn[node], + node_end_pfn[node]); +} /* * Function: smp_dump_qct() @@ -46,34 +79,18 @@ */ static void __init smp_dump_qct(void) { + struct sys_cfg_data *scd; int node; - struct eachquadmem *eq; - struct sys_cfg_data *scd = - (struct sys_cfg_data *)__va(SYS_CFG_DATA_PRIV_ADDR); + + scd = (void *)__va(SYS_CFG_DATA_PRIV_ADDR); nodes_clear(node_online_map); for_each_node(node) { - if (scd->quads_present31_0 & (1 << node)) { - node_set_online(node); - eq = &scd->eq[node]; - /* Convert to pages */ - node_start_pfn[node] = MB_TO_PAGES( - eq->hi_shrd_mem_start - eq->priv_mem_size); - node_end_pfn[node] = MB_TO_PAGES( - eq->hi_shrd_mem_start + eq->hi_shrd_mem_size); - - e820_register_active_regions(node, node_start_pfn[node], - node_end_pfn[node]); - memory_present(node, - node_start_pfn[node], node_end_pfn[node]); - node_remap_size[node] = node_memmap_size_bytes(node, - node_start_pfn[node], - node_end_pfn[node]); - } + if (scd->quads_present31_0 & (1 << node)) + numaq_register_node(node, scd); } } - void __cpuinit numaq_tsc_disable(void) { if (!found_numaq) @@ -98,20 +115,20 @@ int found_numaq; * hence the mpc_record variable .... can't see a less disgusting way of * doing this .... */ -struct mpc_config_translation { - unsigned char mpc_type; - unsigned char trans_len; - unsigned char trans_type; - unsigned char trans_quad; - unsigned char trans_global; - unsigned char trans_local; - unsigned short trans_reserved; +struct mpc_trans { + unsigned char mpc_type; + unsigned char trans_len; + unsigned char trans_type; + unsigned char trans_quad; + unsigned char trans_global; + unsigned char trans_local; + unsigned short trans_reserved; }; /* x86_quirks member */ -static int mpc_record; -static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] - __cpuinitdata; +static int mpc_record; + +static __cpuinitdata struct mpc_trans *translation_table[MAX_MPC_ENTRY]; static inline int generate_logical_apicid(int quad, int phys_apicid) { @@ -124,10 +141,12 @@ static int mpc_apic_id(struct mpc_cpu *m) int quad = translation_table[mpc_record]->trans_quad; int logical_apicid = generate_logical_apicid(quad, m->apicid); - printk(KERN_DEBUG "Processor #%d %u:%u APIC version %d (quad %d, apic %d)\n", - m->apicid, (m->cpufeature & CPU_FAMILY_MASK) >> 8, - (m->cpufeature & CPU_MODEL_MASK) >> 4, - m->apicver, quad, logical_apicid); + printk(KERN_DEBUG + "Processor #%d %u:%u APIC version %d (quad %d, apic %d)\n", + m->apicid, (m->cpufeature & CPU_FAMILY_MASK) >> 8, + (m->cpufeature & CPU_MODEL_MASK) >> 4, + m->apicver, quad, logical_apicid); + return logical_apicid; } @@ -143,11 +162,11 @@ static void mpc_oem_bus_info(struct mpc_bus *m, char *name) mp_bus_id_to_node[m->busid] = quad; mp_bus_id_to_local[m->busid] = local; - printk(KERN_INFO "Bus #%d is %s (node %d)\n", - m->busid, name, quad); + + printk(KERN_INFO "Bus #%d is %s (node %d)\n", m->busid, name, quad); } -int quad_local_to_mp_bus_id [NR_CPUS/4][4]; +int quad_local_to_mp_bus_id[NR_CPUS/4][4]; /* x86_quirks member */ static void mpc_oem_pci_bus(struct mpc_bus *m) @@ -158,7 +177,7 @@ static void mpc_oem_pci_bus(struct mpc_bus *m) quad_local_to_mp_bus_id[quad][local] = m->busid; } -static void __init MP_translation_info(struct mpc_config_translation *m) +static void __init MP_translation_info(struct mpc_trans *m) { printk(KERN_INFO "Translation: record %d, type %d, quad %d, global %d, local %d\n", @@ -168,7 +187,8 @@ static void __init MP_translation_info(struct mpc_config_translation *m) if (mpc_record >= MAX_MPC_ENTRY) printk(KERN_ERR "MAX_MPC_ENTRY exceeded!\n"); else - translation_table[mpc_record] = m; /* stash this for later */ + translation_table[mpc_record] = m; /* stash this for later */ + if (m->trans_quad < MAX_NUMNODES && !node_online(m->trans_quad)) node_set_online(m->trans_quad); } @@ -186,16 +206,16 @@ static int __init mpf_checksum(unsigned char *mp, int len) /* * Read/parse the MPC oem tables */ - -static void __init smp_read_mpc_oem(struct mpc_oemtable *oemtable, - unsigned short oemsize) +static void __init + smp_read_mpc_oem(struct mpc_oemtable *oemtable, unsigned short oemsize) { int count = sizeof(*oemtable); /* the header size */ unsigned char *oemptr = ((unsigned char *)oemtable) + count; mpc_record = 0; - printk(KERN_INFO "Found an OEM MPC table at %8p - parsing it ... \n", - oemtable); + printk(KERN_INFO + "Found an OEM MPC table at %8p - parsing it ... \n", oemtable); + if (memcmp(oemtable->signature, MPC_OEM_SIGNATURE, 4)) { printk(KERN_WARNING "SMP mpc oemtable: bad signature [%c%c%c%c]!\n", @@ -203,16 +223,18 @@ static void __init smp_read_mpc_oem(struct mpc_oemtable *oemtable, oemtable->signature[2], oemtable->signature[3]); return; } + if (mpf_checksum((unsigned char *)oemtable, oemtable->length)) { printk(KERN_WARNING "SMP oem mptable: checksum error!\n"); return; } + while (count < oemtable->length) { switch (*oemptr) { case MP_TRANSLATION: { - struct mpc_config_translation *m = - (struct mpc_config_translation *)oemptr; + struct mpc_trans *m = (void *)oemptr; + MP_translation_info(m); oemptr += sizeof(*m); count += sizeof(*m); @@ -220,12 +242,10 @@ static void __init smp_read_mpc_oem(struct mpc_oemtable *oemtable, break; } default: - { - printk(KERN_WARNING - "Unrecognised OEM table entry type! - %d\n", - (int)*oemptr); - return; - } + printk(KERN_WARNING + "Unrecognised OEM table entry type! - %d\n", + (int)*oemptr); + return; } } } @@ -244,21 +264,21 @@ static int __init numaq_update_genapic(void) } static struct x86_quirks numaq_x86_quirks __initdata = { - .arch_pre_time_init = numaq_pre_time_init, - .arch_time_init = NULL, - .arch_pre_intr_init = NULL, - .arch_memory_setup = NULL, - .arch_intr_init = NULL, - .arch_trap_init = NULL, - .mach_get_smp_config = NULL, - .mach_find_smp_config = NULL, - .mpc_record = &mpc_record, - .mpc_apic_id = mpc_apic_id, - .mpc_oem_bus_info = mpc_oem_bus_info, - .mpc_oem_pci_bus = mpc_oem_pci_bus, - .smp_read_mpc_oem = smp_read_mpc_oem, - .setup_ioapic_ids = numaq_setup_ioapic_ids, - .update_genapic = numaq_update_genapic, + .arch_pre_time_init = numaq_pre_time_init, + .arch_time_init = NULL, + .arch_pre_intr_init = NULL, + .arch_memory_setup = NULL, + .arch_intr_init = NULL, + .arch_trap_init = NULL, + .mach_get_smp_config = NULL, + .mach_find_smp_config = NULL, + .mpc_record = &mpc_record, + .mpc_apic_id = mpc_apic_id, + .mpc_oem_bus_info = mpc_oem_bus_info, + .mpc_oem_pci_bus = mpc_oem_pci_bus, + .smp_read_mpc_oem = smp_read_mpc_oem, + .setup_ioapic_ids = numaq_setup_ioapic_ids, + .update_genapic = numaq_update_genapic, }; void numaq_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) @@ -275,6 +295,7 @@ static __init void early_check_numaq(void) * Find possible boot-time SMP configuration: */ early_find_smp_config(); + /* * get boot-time SMP configuration: */ @@ -291,28 +312,10 @@ int __init get_memcfg_numaq(void) if (!found_numaq) return 0; smp_dump_qct(); + return 1; } -/* - * APIC driver for the IBM NUMAQ chipset. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #define NUMAQ_APIC_DFR_VALUE (APIC_DFR_CLUSTER) static inline unsigned int numaq_get_apic_id(unsigned long x) @@ -337,8 +340,8 @@ static inline void numaq_send_IPI_all(int vector) extern void numaq_mps_oem_check(struct mpc_table *, char *, char *); -#define NUMAQ_TRAMPOLINE_PHYS_LOW (0x8) -#define NUMAQ_TRAMPOLINE_PHYS_HIGH (0xa) +#define NUMAQ_TRAMPOLINE_PHYS_LOW (0x8) +#define NUMAQ_TRAMPOLINE_PHYS_HIGH (0xa) /* * Because we use NMIs rather than the INIT-STARTUP sequence to @@ -426,7 +429,7 @@ static inline int numaq_cpu_present_to_apicid(int mps_cpu) return BAD_APICID; } -static inline int numaq_apicid_to_node(int logical_apicid) +static inline int numaq_apicid_to_node(int logical_apicid) { return logical_apicid >> 4; } @@ -468,7 +471,9 @@ static inline int numaq_phys_pkg_id(int cpuid_apic, int index_msb) { return cpuid_apic >> index_msb; } -static int __numaq_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) + +static int +__numaq_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) { numaq_mps_oem_check(mpc, oem, productid); return found_numaq; -- cgit From cb81eaedf12d3e5e6e3dcf3320089660f7fb7464 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 17 Feb 2009 17:53:54 +0100 Subject: x86, numaq_32: clean up, misc Impact: cleanup - misc other cleanups that change the md5 signature - consolidate global variables - remove unnecessary __numaq_mps_oem_check() wrapper - make numaq_mps_oem_check static - update copyrights - misc other cleanups pointed out by checkpatch Signed-off-by: Ingo Molnar --- arch/x86/include/asm/mpspec.h | 2 - arch/x86/kernel/numaq_32.c | 97 +++++++++++++++++++++---------------------- 2 files changed, 48 insertions(+), 51 deletions(-) diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h index 5916c8df09d..642fc7fc8cd 100644 --- a/arch/x86/include/asm/mpspec.h +++ b/arch/x86/include/asm/mpspec.h @@ -167,6 +167,4 @@ extern int generic_mps_oem_check(struct mpc_table *, char *, char *); extern int default_acpi_madt_oem_check(char *, char *); -extern void numaq_mps_oem_check(struct mpc_table *, char *, char *); - #endif /* _ASM_X86_MPSPEC_H */ diff --git a/arch/x86/kernel/numaq_32.c b/arch/x86/kernel/numaq_32.c index a4ea08a9ac9..62f9274a2ed 100644 --- a/arch/x86/kernel/numaq_32.c +++ b/arch/x86/kernel/numaq_32.c @@ -2,6 +2,7 @@ * Written by: Patricia Gaughen, IBM Corporation * * Copyright (C) 2002, IBM Corp. + * Copyright (C) 2009, Red Hat, Inc., Ingo Molnar * * All rights reserved. * @@ -23,6 +24,7 @@ * Send feedback to */ #include +#include #include #include #include @@ -33,10 +35,10 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -44,10 +46,36 @@ #include #include #include -#include #define MB_TO_PAGES(addr) ((addr) << (20 - PAGE_SHIFT)) +int found_numaq; + +/* + * Have to match translation table entries to main table entries by counter + * hence the mpc_record variable .... can't see a less disgusting way of + * doing this .... + */ +struct mpc_trans { + unsigned char mpc_type; + unsigned char trans_len; + unsigned char trans_type; + unsigned char trans_quad; + unsigned char trans_global; + unsigned char trans_local; + unsigned short trans_reserved; +}; + +/* x86_quirks member */ +static int mpc_record; + +static __cpuinitdata struct mpc_trans *translation_table[MAX_MPC_ENTRY]; + +int mp_bus_id_to_node[MAX_MP_BUSSES]; +int mp_bus_id_to_local[MAX_MP_BUSSES]; +int quad_local_to_mp_bus_id[NR_CPUS/4][4]; + + static inline void numaq_register_node(int node, struct sys_cfg_data *scd) { struct eachquadmem *eq = scd->eq + node; @@ -108,28 +136,6 @@ static int __init numaq_pre_time_init(void) return 0; } -int found_numaq; - -/* - * Have to match translation table entries to main table entries by counter - * hence the mpc_record variable .... can't see a less disgusting way of - * doing this .... - */ -struct mpc_trans { - unsigned char mpc_type; - unsigned char trans_len; - unsigned char trans_type; - unsigned char trans_quad; - unsigned char trans_global; - unsigned char trans_local; - unsigned short trans_reserved; -}; - -/* x86_quirks member */ -static int mpc_record; - -static __cpuinitdata struct mpc_trans *translation_table[MAX_MPC_ENTRY]; - static inline int generate_logical_apicid(int quad, int phys_apicid) { return (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1); @@ -150,10 +156,6 @@ static int mpc_apic_id(struct mpc_cpu *m) return logical_apicid; } -int mp_bus_id_to_node[MAX_MP_BUSSES]; - -int mp_bus_id_to_local[MAX_MP_BUSSES]; - /* x86_quirks member */ static void mpc_oem_bus_info(struct mpc_bus *m, char *name) { @@ -166,8 +168,6 @@ static void mpc_oem_bus_info(struct mpc_bus *m, char *name) printk(KERN_INFO "Bus #%d is %s (node %d)\n", m->busid, name, quad); } -int quad_local_to_mp_bus_id[NR_CPUS/4][4]; - /* x86_quirks member */ static void mpc_oem_pci_bus(struct mpc_bus *m) { @@ -180,7 +180,7 @@ static void mpc_oem_pci_bus(struct mpc_bus *m) static void __init MP_translation_info(struct mpc_trans *m) { printk(KERN_INFO - "Translation: record %d, type %d, quad %d, global %d, local %d\n", + "Translation: record %d, type %d, quad %d, global %d, local %d\n", mpc_record, m->trans_type, m->trans_quad, m->trans_global, m->trans_local); @@ -281,14 +281,6 @@ static struct x86_quirks numaq_x86_quirks __initdata = { .update_genapic = numaq_update_genapic, }; -void numaq_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) -{ - if (strncmp(oem, "IBM NUMA", 8)) - printk("Warning! Not a NUMA-Q system!\n"); - else - found_numaq = 1; -} - static __init void early_check_numaq(void) { /* @@ -338,8 +330,6 @@ static inline void numaq_send_IPI_all(int vector) numaq_send_IPI_mask(cpu_online_mask, vector); } -extern void numaq_mps_oem_check(struct mpc_table *, char *, char *); - #define NUMAQ_TRAMPOLINE_PHYS_LOW (0x8) #define NUMAQ_TRAMPOLINE_PHYS_HIGH (0xa) @@ -355,7 +345,7 @@ static inline void numaq_smp_callin_clear_local_apic(void) static inline void numaq_store_NMI_vector(unsigned short *high, unsigned short *low) { - printk("Storing NMI vector\n"); + printk(KERN_ERR "Storing NMI vector\n"); *high = *((volatile unsigned short *)phys_to_virt(NUMAQ_TRAMPOLINE_PHYS_HIGH)); *low = @@ -390,8 +380,9 @@ static inline void numaq_init_apic_ldr(void) static inline void numaq_setup_apic_routing(void) { - printk("Enabling APIC mode: %s. Using %d I/O APICs\n", - "NUMA-Q", nr_ioapics); + printk(KERN_INFO + "Enabling APIC mode: NUMA-Q. Using %d I/O APICs\n", + nr_ioapics); } /* @@ -473,9 +464,13 @@ static inline int numaq_phys_pkg_id(int cpuid_apic, int index_msb) } static int -__numaq_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) +numaq_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) { - numaq_mps_oem_check(mpc, oem, productid); + if (strncmp(oem, "IBM NUMA", 8)) + printk(KERN_ERR "Warning! Not a NUMA-Q system!\n"); + else + found_numaq = 1; + return found_numaq; } @@ -505,9 +500,13 @@ static void numaq_setup_portio_remap(void) if (num_quads <= 1) return; - printk("Remapping cross-quad port I/O for %d quads\n", num_quads); + printk(KERN_INFO + "Remapping cross-quad port I/O for %d quads\n", num_quads); + xquad_portio = ioremap(XQUAD_PORTIO_BASE, num_quads*XQUAD_PORTIO_QUAD); - printk("xquad_portio vaddr 0x%08lx, len %08lx\n", + + printk(KERN_INFO + "xquad_portio vaddr 0x%08lx, len %08lx\n", (u_long) xquad_portio, (u_long) num_quads*XQUAD_PORTIO_QUAD); } @@ -542,7 +541,7 @@ struct genapic apic_numaq = { .check_phys_apicid_present = numaq_check_phys_apicid_present, .enable_apic_mode = NULL, .phys_pkg_id = numaq_phys_pkg_id, - .mps_oem_check = __numaq_mps_oem_check, + .mps_oem_check = numaq_mps_oem_check, .get_apic_id = numaq_get_apic_id, .set_apic_id = NULL, -- cgit From ab6fb7c0b03e2c3286f316c840347be8b9ee3d9f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 17 Feb 2009 16:22:09 +0100 Subject: x86, apic: remove ->store_NMI_vector() Impact: cleanup It's not used by anything anymore. Signed-off-by: Ingo Molnar --- arch/x86/include/asm/apic.h | 1 - arch/x86/kernel/bigsmp_32.c | 1 - arch/x86/kernel/es7000_32.c | 1 - arch/x86/kernel/genapic_flat_64.c | 2 -- arch/x86/kernel/genx2apic_cluster.c | 1 - arch/x86/kernel/genx2apic_phys.c | 1 - arch/x86/kernel/genx2apic_uv_x.c | 1 - arch/x86/kernel/numaq_32.c | 11 ----------- arch/x86/kernel/probe_32.c | 1 - arch/x86/kernel/smpboot.c | 13 +++++-------- arch/x86/kernel/summit_32.c | 1 - 11 files changed, 5 insertions(+), 29 deletions(-) diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 2cdd19e4536..122d8eda275 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -313,7 +313,6 @@ struct genapic { void (*wait_for_init_deassert)(atomic_t *deassert); void (*smp_callin_clear_local_apic)(void); - void (*store_NMI_vector)(unsigned short *high, unsigned short *low); void (*inquire_remote_apic)(int apicid); /* apic ops */ diff --git a/arch/x86/kernel/bigsmp_32.c b/arch/x86/kernel/bigsmp_32.c index 0de9eed7c60..17c25bc26a5 100644 --- a/arch/x86/kernel/bigsmp_32.c +++ b/arch/x86/kernel/bigsmp_32.c @@ -263,7 +263,6 @@ struct genapic apic_bigsmp = { .wait_for_init_deassert = default_wait_for_init_deassert, .smp_callin_clear_local_apic = NULL, - .store_NMI_vector = NULL, .inquire_remote_apic = default_inquire_remote_apic, .read = native_apic_mem_read, diff --git a/arch/x86/kernel/es7000_32.c b/arch/x86/kernel/es7000_32.c index 3519f8cab70..1d6e99a8edc 100644 --- a/arch/x86/kernel/es7000_32.c +++ b/arch/x86/kernel/es7000_32.c @@ -746,7 +746,6 @@ struct genapic apic_es7000 = { /* Nothing to do for most platforms, since cleared by the INIT cycle: */ .smp_callin_clear_local_apic = NULL, - .store_NMI_vector = NULL, .inquire_remote_apic = default_inquire_remote_apic, .read = native_apic_mem_read, diff --git a/arch/x86/kernel/genapic_flat_64.c b/arch/x86/kernel/genapic_flat_64.c index a7d84763648..27b81208009 100644 --- a/arch/x86/kernel/genapic_flat_64.c +++ b/arch/x86/kernel/genapic_flat_64.c @@ -227,7 +227,6 @@ struct genapic apic_flat = { .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, .wait_for_init_deassert = NULL, .smp_callin_clear_local_apic = NULL, - .store_NMI_vector = NULL, .inquire_remote_apic = NULL, .read = native_apic_mem_read, @@ -379,7 +378,6 @@ struct genapic apic_physflat = { .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, .wait_for_init_deassert = NULL, .smp_callin_clear_local_apic = NULL, - .store_NMI_vector = NULL, .inquire_remote_apic = NULL, .read = native_apic_mem_read, diff --git a/arch/x86/kernel/genx2apic_cluster.c b/arch/x86/kernel/genx2apic_cluster.c index f5e02cffa26..b9ef0091c4d 100644 --- a/arch/x86/kernel/genx2apic_cluster.c +++ b/arch/x86/kernel/genx2apic_cluster.c @@ -232,7 +232,6 @@ struct genapic apic_x2apic_cluster = { .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, .wait_for_init_deassert = NULL, .smp_callin_clear_local_apic = NULL, - .store_NMI_vector = NULL, .inquire_remote_apic = NULL, .read = native_apic_msr_read, diff --git a/arch/x86/kernel/genx2apic_phys.c b/arch/x86/kernel/genx2apic_phys.c index 11eb4cb7ca3..bb752015776 100644 --- a/arch/x86/kernel/genx2apic_phys.c +++ b/arch/x86/kernel/genx2apic_phys.c @@ -218,7 +218,6 @@ struct genapic apic_x2apic_phys = { .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, .wait_for_init_deassert = NULL, .smp_callin_clear_local_apic = NULL, - .store_NMI_vector = NULL, .inquire_remote_apic = NULL, .read = native_apic_msr_read, diff --git a/arch/x86/kernel/genx2apic_uv_x.c b/arch/x86/kernel/genx2apic_uv_x.c index c1746a198bd..dcb8c14287d 100644 --- a/arch/x86/kernel/genx2apic_uv_x.c +++ b/arch/x86/kernel/genx2apic_uv_x.c @@ -290,7 +290,6 @@ struct genapic apic_x2apic_uv_x = { .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, .wait_for_init_deassert = NULL, .smp_callin_clear_local_apic = NULL, - .store_NMI_vector = NULL, .inquire_remote_apic = NULL, .read = native_apic_msr_read, diff --git a/arch/x86/kernel/numaq_32.c b/arch/x86/kernel/numaq_32.c index 62f9274a2ed..a709de87819 100644 --- a/arch/x86/kernel/numaq_32.c +++ b/arch/x86/kernel/numaq_32.c @@ -342,16 +342,6 @@ static inline void numaq_smp_callin_clear_local_apic(void) clear_local_APIC(); } -static inline void -numaq_store_NMI_vector(unsigned short *high, unsigned short *low) -{ - printk(KERN_ERR "Storing NMI vector\n"); - *high = - *((volatile unsigned short *)phys_to_virt(NUMAQ_TRAMPOLINE_PHYS_HIGH)); - *low = - *((volatile unsigned short *)phys_to_virt(NUMAQ_TRAMPOLINE_PHYS_LOW)); -} - static inline const cpumask_t *numaq_target_cpus(void) { return &CPU_MASK_ALL; @@ -564,7 +554,6 @@ struct genapic apic_numaq = { .wait_for_init_deassert = NULL, .smp_callin_clear_local_apic = numaq_smp_callin_clear_local_apic, - .store_NMI_vector = numaq_store_NMI_vector, .inquire_remote_apic = NULL, .read = native_apic_mem_read, diff --git a/arch/x86/kernel/probe_32.c b/arch/x86/kernel/probe_32.c index fd1352ac909..5914ffb6e40 100644 --- a/arch/x86/kernel/probe_32.c +++ b/arch/x86/kernel/probe_32.c @@ -131,7 +131,6 @@ struct genapic apic_default = { .wait_for_init_deassert = default_wait_for_init_deassert, .smp_callin_clear_local_apic = NULL, - .store_NMI_vector = NULL, .inquire_remote_apic = default_inquire_remote_apic, .read = native_apic_mem_read, diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 09e73876a44..9ce666387f3 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -745,21 +745,21 @@ static void __cpuinit do_fork_idle(struct work_struct *work) complete(&c_idle->done); } -static int __cpuinit do_boot_cpu(int apicid, int cpu) /* * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad * (ie clustered apic addressing mode), this is a LOGICAL apic ID. * Returns zero if CPU booted OK, else error code from ->wakeup_cpu. */ +static int __cpuinit do_boot_cpu(int apicid, int cpu) { unsigned long boot_error = 0; - int timeout; unsigned long start_ip; - unsigned short nmi_high = 0, nmi_low = 0; + int timeout; struct create_idle c_idle = { - .cpu = cpu, - .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done), + .cpu = cpu, + .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done), }; + INIT_WORK(&c_idle.work, do_fork_idle); alternatives_smp_switch(1); @@ -824,9 +824,6 @@ do_rest: pr_debug("Setting warm reset code and vector.\n"); - if (apic->store_NMI_vector) - apic->store_NMI_vector(&nmi_high, &nmi_low); - smpboot_setup_warm_reset_vector(start_ip); /* * Be paranoid about clearing APIC errors. diff --git a/arch/x86/kernel/summit_32.c b/arch/x86/kernel/summit_32.c index c4690349a54..8f1a11b072a 100644 --- a/arch/x86/kernel/summit_32.c +++ b/arch/x86/kernel/summit_32.c @@ -590,7 +590,6 @@ struct genapic apic_summit = { .wait_for_init_deassert = default_wait_for_init_deassert, .smp_callin_clear_local_apic = NULL, - .store_NMI_vector = NULL, .inquire_remote_apic = default_inquire_remote_apic, .read = native_apic_mem_read, -- cgit From be163a159b223e94b3180afdd47a8d468eb9a492 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 17 Feb 2009 16:28:46 +0100 Subject: x86, apic: rename 'genapic' to 'apic' Impact: cleanup Now that all APIC code is consolidated there's nothing 'gen' about apics anymore - so rename 'struct genapic' to 'struct apic'. This shortens the code and is nicer to read as well. Signed-off-by: Ingo Molnar --- arch/x86/include/asm/apic.h | 18 +++++++++--------- arch/x86/include/asm/setup.h | 2 +- arch/x86/kernel/bigsmp_32.c | 2 +- arch/x86/kernel/es7000_32.c | 10 +++++----- arch/x86/kernel/genapic_64.c | 18 +++++++++--------- arch/x86/kernel/genapic_flat_64.c | 4 ++-- arch/x86/kernel/genx2apic_cluster.c | 2 +- arch/x86/kernel/genx2apic_phys.c | 2 +- arch/x86/kernel/genx2apic_uv_x.c | 2 +- arch/x86/kernel/numaq_32.c | 6 +++--- arch/x86/kernel/probe_32.c | 36 ++++++++++++++++++------------------ arch/x86/kernel/setup.c | 4 ++-- arch/x86/kernel/summit_32.c | 2 +- 13 files changed, 54 insertions(+), 54 deletions(-) diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 122d8eda275..dce1bf696cc 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -248,7 +248,7 @@ static inline void disable_local_APIC(void) { } * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and * James Cleverdon. */ -struct genapic { +struct apic { char *name; int (*probe)(void); @@ -283,7 +283,7 @@ struct genapic { int (*phys_pkg_id)(int cpuid_apic, int index_msb); /* - * When one of the next two hooks returns 1 the genapic + * When one of the next two hooks returns 1 the apic * is switched to this. Essentially they are additional * probe functions: */ @@ -324,7 +324,7 @@ struct genapic { u32 (*safe_wait_icr_idle)(void); }; -extern struct genapic *apic; +extern struct apic *apic; static inline u32 apic_read(u32 reg) { @@ -385,17 +385,17 @@ static inline unsigned default_get_apic_id(unsigned long x) #define DEFAULT_TRAMPOLINE_PHYS_HIGH 0x469 #ifdef CONFIG_X86_32 -extern void es7000_update_genapic_to_cluster(void); +extern void es7000_update_apic_to_cluster(void); #else -extern struct genapic apic_flat; -extern struct genapic apic_physflat; -extern struct genapic apic_x2apic_cluster; -extern struct genapic apic_x2apic_phys; +extern struct apic apic_flat; +extern struct apic apic_physflat; +extern struct apic apic_x2apic_cluster; +extern struct apic apic_x2apic_phys; extern int default_acpi_madt_oem_check(char *, char *); extern void apic_send_IPI_self(int vector); -extern struct genapic apic_x2apic_uv_x; +extern struct apic apic_x2apic_uv_x; DECLARE_PER_CPU(int, x2apic_extra_bits); extern int default_cpu_present_to_apicid(int mps_cpu); diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h index c230189462a..8029369cd6f 100644 --- a/arch/x86/include/asm/setup.h +++ b/arch/x86/include/asm/setup.h @@ -30,7 +30,7 @@ struct x86_quirks { void (*smp_read_mpc_oem)(struct mpc_oemtable *oemtable, unsigned short oemsize); int (*setup_ioapic_ids)(void); - int (*update_genapic)(void); + int (*update_apic)(void); }; #endif /* __ASSEMBLY__ */ diff --git a/arch/x86/kernel/bigsmp_32.c b/arch/x86/kernel/bigsmp_32.c index 17c25bc26a5..0b1093394fd 100644 --- a/arch/x86/kernel/bigsmp_32.c +++ b/arch/x86/kernel/bigsmp_32.c @@ -210,7 +210,7 @@ static int probe_bigsmp(void) return dmi_bigsmp; } -struct genapic apic_bigsmp = { +struct apic apic_bigsmp = { .name = "bigsmp", .probe = probe_bigsmp, diff --git a/arch/x86/kernel/es7000_32.c b/arch/x86/kernel/es7000_32.c index 1d6e99a8edc..320f2d2e4e5 100644 --- a/arch/x86/kernel/es7000_32.c +++ b/arch/x86/kernel/es7000_32.c @@ -163,14 +163,14 @@ static int wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip) return 0; } -static int __init es7000_update_genapic(void) +static int __init es7000_update_apic(void) { apic->wakeup_cpu = wakeup_secondary_cpu_via_mip; /* MPENTIUMIII */ if (boot_cpu_data.x86 == 6 && (boot_cpu_data.x86_model >= 7 || boot_cpu_data.x86_model <= 11)) { - es7000_update_genapic_to_cluster(); + es7000_update_apic_to_cluster(); apic->wait_for_init_deassert = NULL; apic->wakeup_cpu = wakeup_secondary_cpu_via_mip; } @@ -193,7 +193,7 @@ static void __init setup_unisys(void) es7000_plat = ES7000_CLASSIC; ioapic_renumber_irq = es7000_rename_gsi; - x86_quirks->update_genapic = es7000_update_genapic; + x86_quirks->update_apic = es7000_update_apic; } /* @@ -659,7 +659,7 @@ static int es7000_phys_pkg_id(int cpuid_apic, int index_msb) return cpuid_apic >> index_msb; } -void __init es7000_update_genapic_to_cluster(void) +void __init es7000_update_apic_to_cluster(void) { apic->target_cpus = target_cpus_cluster; apic->irq_delivery_mode = dest_LowestPrio; @@ -691,7 +691,7 @@ es7000_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) } -struct genapic apic_es7000 = { +struct apic apic_es7000 = { .name = "es7000", .probe = probe_es7000, diff --git a/arch/x86/kernel/genapic_64.c b/arch/x86/kernel/genapic_64.c index 91cae6f6e73..70935dd904d 100644 --- a/arch/x86/kernel/genapic_64.c +++ b/arch/x86/kernel/genapic_64.c @@ -23,16 +23,16 @@ #include #include -extern struct genapic apic_flat; -extern struct genapic apic_physflat; -extern struct genapic apic_x2xpic_uv_x; -extern struct genapic apic_x2apic_phys; -extern struct genapic apic_x2apic_cluster; +extern struct apic apic_flat; +extern struct apic apic_physflat; +extern struct apic apic_x2xpic_uv_x; +extern struct apic apic_x2apic_phys; +extern struct apic apic_x2apic_cluster; -struct genapic __read_mostly *apic = &apic_flat; +struct apic __read_mostly *apic = &apic_flat; EXPORT_SYMBOL_GPL(apic); -static struct genapic *apic_probe[] __initdata = { +static struct apic *apic_probe[] __initdata = { #ifdef CONFIG_X86_UV &apic_x2apic_uv_x, #endif @@ -62,8 +62,8 @@ void __init default_setup_apic_routing(void) printk(KERN_INFO "Setting APIC routing to %s\n", apic->name); } - if (x86_quirks->update_genapic) - x86_quirks->update_genapic(); + if (x86_quirks->update_apic) + x86_quirks->update_apic(); } /* Same for both flat and physical. */ diff --git a/arch/x86/kernel/genapic_flat_64.c b/arch/x86/kernel/genapic_flat_64.c index 27b81208009..3b002995e14 100644 --- a/arch/x86/kernel/genapic_flat_64.c +++ b/arch/x86/kernel/genapic_flat_64.c @@ -178,7 +178,7 @@ static int flat_phys_pkg_id(int initial_apic_id, int index_msb) return hard_smp_processor_id() >> index_msb; } -struct genapic apic_flat = { +struct apic apic_flat = { .name = "flat", .probe = NULL, .acpi_madt_oem_check = flat_acpi_madt_oem_check, @@ -327,7 +327,7 @@ physflat_cpu_mask_to_apicid_and(const struct cpumask *cpumask, return BAD_APICID; } -struct genapic apic_physflat = { +struct apic apic_physflat = { .name = "physical flat", .probe = NULL, diff --git a/arch/x86/kernel/genx2apic_cluster.c b/arch/x86/kernel/genx2apic_cluster.c index b9ef0091c4d..4e39d9ad4d5 100644 --- a/arch/x86/kernel/genx2apic_cluster.c +++ b/arch/x86/kernel/genx2apic_cluster.c @@ -182,7 +182,7 @@ static void init_x2apic_ldr(void) per_cpu(x86_cpu_to_logical_apicid, cpu) = apic_read(APIC_LDR); } -struct genapic apic_x2apic_cluster = { +struct apic apic_x2apic_cluster = { .name = "cluster x2apic", .probe = NULL, diff --git a/arch/x86/kernel/genx2apic_phys.c b/arch/x86/kernel/genx2apic_phys.c index bb752015776..d2d52eb9f7e 100644 --- a/arch/x86/kernel/genx2apic_phys.c +++ b/arch/x86/kernel/genx2apic_phys.c @@ -168,7 +168,7 @@ static void init_x2apic_ldr(void) { } -struct genapic apic_x2apic_phys = { +struct apic apic_x2apic_phys = { .name = "physical x2apic", .probe = NULL, diff --git a/arch/x86/kernel/genx2apic_uv_x.c b/arch/x86/kernel/genx2apic_uv_x.c index dcb8c14287d..20b4ad07c3a 100644 --- a/arch/x86/kernel/genx2apic_uv_x.c +++ b/arch/x86/kernel/genx2apic_uv_x.c @@ -240,7 +240,7 @@ static void uv_send_IPI_self(int vector) apic_write(APIC_SELF_IPI, vector); } -struct genapic apic_x2apic_uv_x = { +struct apic apic_x2apic_uv_x = { .name = "UV large system", .probe = NULL, diff --git a/arch/x86/kernel/numaq_32.c b/arch/x86/kernel/numaq_32.c index a709de87819..d9d6d61eed8 100644 --- a/arch/x86/kernel/numaq_32.c +++ b/arch/x86/kernel/numaq_32.c @@ -256,7 +256,7 @@ static int __init numaq_setup_ioapic_ids(void) return 1; } -static int __init numaq_update_genapic(void) +static int __init numaq_update_apic(void) { apic->wakeup_cpu = wakeup_secondary_cpu_via_nmi; @@ -278,7 +278,7 @@ static struct x86_quirks numaq_x86_quirks __initdata = { .mpc_oem_pci_bus = mpc_oem_pci_bus, .smp_read_mpc_oem = smp_read_mpc_oem, .setup_ioapic_ids = numaq_setup_ioapic_ids, - .update_genapic = numaq_update_genapic, + .update_apic = numaq_update_apic, }; static __init void early_check_numaq(void) @@ -500,7 +500,7 @@ static void numaq_setup_portio_remap(void) (u_long) xquad_portio, (u_long) num_quads*XQUAD_PORTIO_QUAD); } -struct genapic apic_numaq = { +struct apic apic_numaq = { .name = "NUMAQ", .probe = probe_numaq, diff --git a/arch/x86/kernel/probe_32.c b/arch/x86/kernel/probe_32.c index 5914ffb6e40..5fa48332c5c 100644 --- a/arch/x86/kernel/probe_32.c +++ b/arch/x86/kernel/probe_32.c @@ -78,7 +78,7 @@ static int probe_default(void) return 1; } -struct genapic apic_default = { +struct apic apic_default = { .name = "default", .probe = probe_default, @@ -141,16 +141,16 @@ struct genapic apic_default = { .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, }; -extern struct genapic apic_numaq; -extern struct genapic apic_summit; -extern struct genapic apic_bigsmp; -extern struct genapic apic_es7000; -extern struct genapic apic_default; +extern struct apic apic_numaq; +extern struct apic apic_summit; +extern struct apic apic_bigsmp; +extern struct apic apic_es7000; +extern struct apic apic_default; -struct genapic *apic = &apic_default; +struct apic *apic = &apic_default; EXPORT_SYMBOL_GPL(apic); -static struct genapic *apic_probe[] __initdata = { +static struct apic *apic_probe[] __initdata = { #ifdef CONFIG_X86_NUMAQ &apic_numaq, #endif @@ -183,8 +183,8 @@ static int __init parse_apic(char *arg) } } - if (x86_quirks->update_genapic) - x86_quirks->update_genapic(); + if (x86_quirks->update_apic) + x86_quirks->update_apic(); /* Parsed again by __setup for debug/verbose */ return 0; @@ -204,8 +204,8 @@ void __init generic_bigsmp_probe(void) if (!cmdline_apic && apic == &apic_default) { if (apic_bigsmp.probe()) { apic = &apic_bigsmp; - if (x86_quirks->update_genapic) - x86_quirks->update_genapic(); + if (x86_quirks->update_apic) + x86_quirks->update_apic(); printk(KERN_INFO "Overriding APIC driver with %s\n", apic->name); } @@ -227,8 +227,8 @@ void __init generic_apic_probe(void) if (!apic_probe[i]) panic("Didn't find an APIC driver"); - if (x86_quirks->update_genapic) - x86_quirks->update_genapic(); + if (x86_quirks->update_apic) + x86_quirks->update_apic(); } printk(KERN_INFO "Using APIC driver %s\n", apic->name); } @@ -248,8 +248,8 @@ generic_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) if (!cmdline_apic) { apic = apic_probe[i]; - if (x86_quirks->update_genapic) - x86_quirks->update_genapic(); + if (x86_quirks->update_apic) + x86_quirks->update_apic(); printk(KERN_INFO "Switched to APIC driver `%s'.\n", apic->name); } @@ -270,8 +270,8 @@ int __init default_acpi_madt_oem_check(char *oem_id, char *oem_table_id) if (!cmdline_apic) { apic = apic_probe[i]; - if (x86_quirks->update_genapic) - x86_quirks->update_genapic(); + if (x86_quirks->update_apic) + x86_quirks->update_apic(); printk(KERN_INFO "Switched to APIC driver `%s'.\n", apic->name); } diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index b2da0b1d15e..6b588d6b388 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -599,7 +599,7 @@ static int __init setup_elfcorehdr(char *arg) early_param("elfcorehdr", setup_elfcorehdr); #endif -static int __init default_update_genapic(void) +static int __init default_update_apic(void) { #ifdef CONFIG_SMP if (!apic->wakeup_cpu) @@ -610,7 +610,7 @@ static int __init default_update_genapic(void) } static struct x86_quirks default_x86_quirks __initdata = { - .update_genapic = default_update_genapic, + .update_apic = default_update_apic, }; struct x86_quirks *x86_quirks __initdata = &default_x86_quirks; diff --git a/arch/x86/kernel/summit_32.c b/arch/x86/kernel/summit_32.c index 8f1a11b072a..cfe7b09015d 100644 --- a/arch/x86/kernel/summit_32.c +++ b/arch/x86/kernel/summit_32.c @@ -537,7 +537,7 @@ void __init setup_summit(void) } #endif -struct genapic apic_summit = { +struct apic apic_summit = { .name = "summit", .probe = probe_summit, -- cgit From f62bae5009c1ba596cd475cafbc83e0570a36e26 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 17 Feb 2009 18:09:24 +0100 Subject: x86, apic: move APIC drivers to arch/x86/kernel/apic/* arch/x86/kernel/ is getting a bit crowded, and the APIC drivers are scattered into various different files. Move them to arch/x86/kernel/apic/*, and also remove the 'gen' prefix from those which had it. Also move APIC related functionality: the IO-APIC driver, the NMI and the IPI code. Signed-off-by: Ingo Molnar --- arch/x86/kernel/Makefile | 27 +- arch/x86/kernel/apic.c | 2212 ------------------ arch/x86/kernel/apic/Makefile | 15 + arch/x86/kernel/apic/apic.c | 2212 ++++++++++++++++++ arch/x86/kernel/apic/apic_64.c | 89 + arch/x86/kernel/apic/apic_flat_64.c | 389 +++ arch/x86/kernel/apic/io_apic.c | 4160 +++++++++++++++++++++++++++++++++ arch/x86/kernel/apic/ipi.c | 164 ++ arch/x86/kernel/apic/nmi.c | 564 +++++ arch/x86/kernel/apic/x2apic_cluster.c | 243 ++ arch/x86/kernel/apic/x2apic_phys.c | 229 ++ arch/x86/kernel/apic/x2apic_uv_x.c | 643 +++++ arch/x86/kernel/genapic_64.c | 89 - arch/x86/kernel/genapic_flat_64.c | 389 --- arch/x86/kernel/genx2apic_cluster.c | 243 -- arch/x86/kernel/genx2apic_phys.c | 229 -- arch/x86/kernel/genx2apic_uv_x.c | 643 ----- arch/x86/kernel/io_apic.c | 4160 --------------------------------- arch/x86/kernel/ipi.c | 164 -- arch/x86/kernel/nmi.c | 564 ----- 20 files changed, 8719 insertions(+), 8709 deletions(-) delete mode 100644 arch/x86/kernel/apic.c create mode 100644 arch/x86/kernel/apic/Makefile create mode 100644 arch/x86/kernel/apic/apic.c create mode 100644 arch/x86/kernel/apic/apic_64.c create mode 100644 arch/x86/kernel/apic/apic_flat_64.c create mode 100644 arch/x86/kernel/apic/io_apic.c create mode 100644 arch/x86/kernel/apic/ipi.c create mode 100644 arch/x86/kernel/apic/nmi.c create mode 100644 arch/x86/kernel/apic/x2apic_cluster.c create mode 100644 arch/x86/kernel/apic/x2apic_phys.c create mode 100644 arch/x86/kernel/apic/x2apic_uv_x.c delete mode 100644 arch/x86/kernel/genapic_64.c delete mode 100644 arch/x86/kernel/genapic_flat_64.c delete mode 100644 arch/x86/kernel/genx2apic_cluster.c delete mode 100644 arch/x86/kernel/genx2apic_phys.c delete mode 100644 arch/x86/kernel/genx2apic_uv_x.c delete mode 100644 arch/x86/kernel/io_apic.c delete mode 100644 arch/x86/kernel/ipi.c delete mode 100644 arch/x86/kernel/nmi.c diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 1cefd218f76..9139ff69471 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -58,13 +58,12 @@ obj-$(CONFIG_PCI) += early-quirks.o apm-y := apm_32.o obj-$(CONFIG_APM) += apm.o obj-$(CONFIG_SMP) += smp.o -obj-$(CONFIG_SMP) += smpboot.o tsc_sync.o ipi.o +obj-$(CONFIG_SMP) += smpboot.o tsc_sync.o obj-$(CONFIG_SMP) += setup_percpu.o obj-$(CONFIG_X86_64_SMP) += tsc_sync.o obj-$(CONFIG_X86_TRAMPOLINE) += trampoline_$(BITS).o obj-$(CONFIG_X86_MPPARSE) += mpparse.o -obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o ipi.o -obj-$(CONFIG_X86_IO_APIC) += io_apic.o +obj-$(CONFIG_X86_LOCAL_APIC) += apic/ obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o @@ -116,17 +115,13 @@ obj-$(CONFIG_SWIOTLB) += pci-swiotlb_64.o # NB rename without _64 ### # 64 bit specific files ifeq ($(CONFIG_X86_64),y) - obj-y += genapic_64.o genapic_flat_64.o - obj-$(CONFIG_X86_X2APIC) += genx2apic_cluster.o - obj-$(CONFIG_X86_X2APIC) += genx2apic_phys.o - obj-$(CONFIG_X86_UV) += genx2apic_uv_x.o tlb_uv.o - obj-$(CONFIG_X86_UV) += bios_uv.o uv_irq.o uv_sysfs.o - obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o - obj-$(CONFIG_AUDIT) += audit_64.o - - obj-$(CONFIG_GART_IOMMU) += pci-gart_64.o aperture_64.o - obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary_64.o tce_64.o - obj-$(CONFIG_AMD_IOMMU) += amd_iommu_init.o amd_iommu.o - - obj-$(CONFIG_PCI_MMCONFIG) += mmconf-fam10h_64.o + obj-$(CONFIG_X86_UV) += tlb_uv.o bios_uv.o uv_irq.o uv_sysfs.o + obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o + obj-$(CONFIG_AUDIT) += audit_64.o + + obj-$(CONFIG_GART_IOMMU) += pci-gart_64.o aperture_64.o + obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary_64.o tce_64.o + obj-$(CONFIG_AMD_IOMMU) += amd_iommu_init.o amd_iommu.o + + obj-$(CONFIG_PCI_MMCONFIG) += mmconf-fam10h_64.o endif diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c deleted file mode 100644 index c12823eb55b..00000000000 --- a/arch/x86/kernel/apic.c +++ /dev/null @@ -1,2212 +0,0 @@ -/* - * Local APIC handling, local APIC timers - * - * (c) 1999, 2000, 2009 Ingo Molnar - * - * Fixes - * Maciej W. Rozycki : Bits for genuine 82489DX APICs; - * thanks to Eric Gilmore - * and Rolf G. Tews - * for testing these extensively. - * Maciej W. Rozycki : Various updates and fixes. - * Mikael Pettersson : Power Management for UP-APIC. - * Pavel Machek and - * Mikael Pettersson : PM converted to driver model. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -unsigned int num_processors; - -unsigned disabled_cpus __cpuinitdata; - -/* Processor that is doing the boot up */ -unsigned int boot_cpu_physical_apicid = -1U; - -/* - * The highest APIC ID seen during enumeration. - * - * This determines the messaging protocol we can use: if all APIC IDs - * are in the 0 ... 7 range, then we can use logical addressing which - * has some performance advantages (better broadcasting). - * - * If there's an APIC ID above 8, we use physical addressing. - */ -unsigned int max_physical_apicid; - -/* - * Bitmask of physically existing CPUs: - */ -physid_mask_t phys_cpu_present_map; - -/* - * Map cpu index to physical APIC ID - */ -DEFINE_EARLY_PER_CPU(u16, x86_cpu_to_apicid, BAD_APICID); -DEFINE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid, BAD_APICID); -EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_apicid); -EXPORT_EARLY_PER_CPU_SYMBOL(x86_bios_cpu_apicid); - -#ifdef CONFIG_X86_32 -/* - * Knob to control our willingness to enable the local APIC. - * - * +1=force-enable - */ -static int force_enable_local_apic; -/* - * APIC command line parameters - */ -static int __init parse_lapic(char *arg) -{ - force_enable_local_apic = 1; - return 0; -} -early_param("lapic", parse_lapic); -/* Local APIC was disabled by the BIOS and enabled by the kernel */ -static int enabled_via_apicbase; - -#endif - -#ifdef CONFIG_X86_64 -static int apic_calibrate_pmtmr __initdata; -static __init int setup_apicpmtimer(char *s) -{ - apic_calibrate_pmtmr = 1; - notsc_setup(NULL); - return 0; -} -__setup("apicpmtimer", setup_apicpmtimer); -#endif - -#ifdef CONFIG_X86_X2APIC -int x2apic; -/* x2apic enabled before OS handover */ -static int x2apic_preenabled; -static int disable_x2apic; -static __init int setup_nox2apic(char *str) -{ - disable_x2apic = 1; - setup_clear_cpu_cap(X86_FEATURE_X2APIC); - return 0; -} -early_param("nox2apic", setup_nox2apic); -#endif - -unsigned long mp_lapic_addr; -int disable_apic; -/* Disable local APIC timer from the kernel commandline or via dmi quirk */ -static int disable_apic_timer __cpuinitdata; -/* Local APIC timer works in C2 */ -int local_apic_timer_c2_ok; -EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok); - -int first_system_vector = 0xfe; - -/* - * Debug level, exported for io_apic.c - */ -unsigned int apic_verbosity; - -int pic_mode; - -/* Have we found an MP table */ -int smp_found_config; - -static struct resource lapic_resource = { - .name = "Local APIC", - .flags = IORESOURCE_MEM | IORESOURCE_BUSY, -}; - -static unsigned int calibration_result; - -static int lapic_next_event(unsigned long delta, - struct clock_event_device *evt); -static void lapic_timer_setup(enum clock_event_mode mode, - struct clock_event_device *evt); -static void lapic_timer_broadcast(const struct cpumask *mask); -static void apic_pm_activate(void); - -/* - * The local apic timer can be used for any function which is CPU local. - */ -static struct clock_event_device lapic_clockevent = { - .name = "lapic", - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT - | CLOCK_EVT_FEAT_C3STOP | CLOCK_EVT_FEAT_DUMMY, - .shift = 32, - .set_mode = lapic_timer_setup, - .set_next_event = lapic_next_event, - .broadcast = lapic_timer_broadcast, - .rating = 100, - .irq = -1, -}; -static DEFINE_PER_CPU(struct clock_event_device, lapic_events); - -static unsigned long apic_phys; - -/* - * Get the LAPIC version - */ -static inline int lapic_get_version(void) -{ - return GET_APIC_VERSION(apic_read(APIC_LVR)); -} - -/* - * Check, if the APIC is integrated or a separate chip - */ -static inline int lapic_is_integrated(void) -{ -#ifdef CONFIG_X86_64 - return 1; -#else - return APIC_INTEGRATED(lapic_get_version()); -#endif -} - -/* - * Check, whether this is a modern or a first generation APIC - */ -static int modern_apic(void) -{ - /* AMD systems use old APIC versions, so check the CPU */ - if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && - boot_cpu_data.x86 >= 0xf) - return 1; - return lapic_get_version() >= 0x14; -} - -void native_apic_wait_icr_idle(void) -{ - while (apic_read(APIC_ICR) & APIC_ICR_BUSY) - cpu_relax(); -} - -u32 native_safe_apic_wait_icr_idle(void) -{ - u32 send_status; - int timeout; - - timeout = 0; - do { - send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; - if (!send_status) - break; - udelay(100); - } while (timeout++ < 1000); - - return send_status; -} - -void native_apic_icr_write(u32 low, u32 id) -{ - apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(id)); - apic_write(APIC_ICR, low); -} - -u64 native_apic_icr_read(void) -{ - u32 icr1, icr2; - - icr2 = apic_read(APIC_ICR2); - icr1 = apic_read(APIC_ICR); - - return icr1 | ((u64)icr2 << 32); -} - -/** - * enable_NMI_through_LVT0 - enable NMI through local vector table 0 - */ -void __cpuinit enable_NMI_through_LVT0(void) -{ - unsigned int v; - - /* unmask and set to NMI */ - v = APIC_DM_NMI; - - /* Level triggered for 82489DX (32bit mode) */ - if (!lapic_is_integrated()) - v |= APIC_LVT_LEVEL_TRIGGER; - - apic_write(APIC_LVT0, v); -} - -#ifdef CONFIG_X86_32 -/** - * get_physical_broadcast - Get number of physical broadcast IDs - */ -int get_physical_broadcast(void) -{ - return modern_apic() ? 0xff : 0xf; -} -#endif - -/** - * lapic_get_maxlvt - get the maximum number of local vector table entries - */ -int lapic_get_maxlvt(void) -{ - unsigned int v; - - v = apic_read(APIC_LVR); - /* - * - we always have APIC integrated on 64bit mode - * - 82489DXs do not report # of LVT entries - */ - return APIC_INTEGRATED(GET_APIC_VERSION(v)) ? GET_APIC_MAXLVT(v) : 2; -} - -/* - * Local APIC timer - */ - -/* Clock divisor */ -#define APIC_DIVISOR 16 - -/* - * This function sets up the local APIC timer, with a timeout of - * 'clocks' APIC bus clock. During calibration we actually call - * this function twice on the boot CPU, once with a bogus timeout - * value, second time for real. The other (noncalibrating) CPUs - * call this function only once, with the real, calibrated value. - * - * We do reads before writes even if unnecessary, to get around the - * P5 APIC double write bug. - */ -static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) -{ - unsigned int lvtt_value, tmp_value; - - lvtt_value = LOCAL_TIMER_VECTOR; - if (!oneshot) - lvtt_value |= APIC_LVT_TIMER_PERIODIC; - if (!lapic_is_integrated()) - lvtt_value |= SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV); - - if (!irqen) - lvtt_value |= APIC_LVT_MASKED; - - apic_write(APIC_LVTT, lvtt_value); - - /* - * Divide PICLK by 16 - */ - tmp_value = apic_read(APIC_TDCR); - apic_write(APIC_TDCR, - (tmp_value & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE)) | - APIC_TDR_DIV_16); - - if (!oneshot) - apic_write(APIC_TMICT, clocks / APIC_DIVISOR); -} - -/* - * Setup extended LVT, AMD specific (K8, family 10h) - * - * Vector mappings are hard coded. On K8 only offset 0 (APIC500) and - * MCE interrupts are supported. Thus MCE offset must be set to 0. - * - * If mask=1, the LVT entry does not generate interrupts while mask=0 - * enables the vector. See also the BKDGs. - */ - -#define APIC_EILVT_LVTOFF_MCE 0 -#define APIC_EILVT_LVTOFF_IBS 1 - -static void setup_APIC_eilvt(u8 lvt_off, u8 vector, u8 msg_type, u8 mask) -{ - unsigned long reg = (lvt_off << 4) + APIC_EILVT0; - unsigned int v = (mask << 16) | (msg_type << 8) | vector; - - apic_write(reg, v); -} - -u8 setup_APIC_eilvt_mce(u8 vector, u8 msg_type, u8 mask) -{ - setup_APIC_eilvt(APIC_EILVT_LVTOFF_MCE, vector, msg_type, mask); - return APIC_EILVT_LVTOFF_MCE; -} - -u8 setup_APIC_eilvt_ibs(u8 vector, u8 msg_type, u8 mask) -{ - setup_APIC_eilvt(APIC_EILVT_LVTOFF_IBS, vector, msg_type, mask); - return APIC_EILVT_LVTOFF_IBS; -} -EXPORT_SYMBOL_GPL(setup_APIC_eilvt_ibs); - -/* - * Program the next event, relative to now - */ -static int lapic_next_event(unsigned long delta, - struct clock_event_device *evt) -{ - apic_write(APIC_TMICT, delta); - return 0; -} - -/* - * Setup the lapic timer in periodic or oneshot mode - */ -static void lapic_timer_setup(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - unsigned long flags; - unsigned int v; - - /* Lapic used as dummy for broadcast ? */ - if (evt->features & CLOCK_EVT_FEAT_DUMMY) - return; - - local_irq_save(flags); - - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - case CLOCK_EVT_MODE_ONESHOT: - __setup_APIC_LVTT(calibration_result, - mode != CLOCK_EVT_MODE_PERIODIC, 1); - break; - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_SHUTDOWN: - v = apic_read(APIC_LVTT); - v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); - apic_write(APIC_LVTT, v); - apic_write(APIC_TMICT, 0xffffffff); - break; - case CLOCK_EVT_MODE_RESUME: - /* Nothing to do here */ - break; - } - - local_irq_restore(flags); -} - -/* - * Local APIC timer broadcast function - */ -static void lapic_timer_broadcast(const struct cpumask *mask) -{ -#ifdef CONFIG_SMP - apic->send_IPI_mask(mask, LOCAL_TIMER_VECTOR); -#endif -} - -/* - * Setup the local APIC timer for this CPU. Copy the initilized values - * of the boot CPU and register the clock event in the framework. - */ -static void __cpuinit setup_APIC_timer(void) -{ - struct clock_event_device *levt = &__get_cpu_var(lapic_events); - - memcpy(levt, &lapic_clockevent, sizeof(*levt)); - levt->cpumask = cpumask_of(smp_processor_id()); - - clockevents_register_device(levt); -} - -/* - * In this functions we calibrate APIC bus clocks to the external timer. - * - * We want to do the calibration only once since we want to have local timer - * irqs syncron. CPUs connected by the same APIC bus have the very same bus - * frequency. - * - * This was previously done by reading the PIT/HPET and waiting for a wrap - * around to find out, that a tick has elapsed. I have a box, where the PIT - * readout is broken, so it never gets out of the wait loop again. This was - * also reported by others. - * - * Monitoring the jiffies value is inaccurate and the clockevents - * infrastructure allows us to do a simple substitution of the interrupt - * handler. - * - * The calibration routine also uses the pm_timer when possible, as the PIT - * happens to run way too slow (factor 2.3 on my VAIO CoreDuo, which goes - * back to normal later in the boot process). - */ - -#define LAPIC_CAL_LOOPS (HZ/10) - -static __initdata int lapic_cal_loops = -1; -static __initdata long lapic_cal_t1, lapic_cal_t2; -static __initdata unsigned long long lapic_cal_tsc1, lapic_cal_tsc2; -static __initdata unsigned long lapic_cal_pm1, lapic_cal_pm2; -static __initdata unsigned long lapic_cal_j1, lapic_cal_j2; - -/* - * Temporary interrupt handler. - */ -static void __init lapic_cal_handler(struct clock_event_device *dev) -{ - unsigned long long tsc = 0; - long tapic = apic_read(APIC_TMCCT); - unsigned long pm = acpi_pm_read_early(); - - if (cpu_has_tsc) - rdtscll(tsc); - - switch (lapic_cal_loops++) { - case 0: - lapic_cal_t1 = tapic; - lapic_cal_tsc1 = tsc; - lapic_cal_pm1 = pm; - lapic_cal_j1 = jiffies; - break; - - case LAPIC_CAL_LOOPS: - lapic_cal_t2 = tapic; - lapic_cal_tsc2 = tsc; - if (pm < lapic_cal_pm1) - pm += ACPI_PM_OVRRUN; - lapic_cal_pm2 = pm; - lapic_cal_j2 = jiffies; - break; - } -} - -static int __init -calibrate_by_pmtimer(long deltapm, long *delta, long *deltatsc) -{ - const long pm_100ms = PMTMR_TICKS_PER_SEC / 10; - const long pm_thresh = pm_100ms / 100; - unsigned long mult; - u64 res; - -#ifndef CONFIG_X86_PM_TIMER - return -1; -#endif - - apic_printk(APIC_VERBOSE, "... PM-Timer delta = %ld\n", deltapm); - - /* Check, if the PM timer is available */ - if (!deltapm) - return -1; - - mult = clocksource_hz2mult(PMTMR_TICKS_PER_SEC, 22); - - if (deltapm > (pm_100ms - pm_thresh) && - deltapm < (pm_100ms + pm_thresh)) { - apic_printk(APIC_VERBOSE, "... PM-Timer result ok\n"); - return 0; - } - - res = (((u64)deltapm) * mult) >> 22; - do_div(res, 1000000); - pr_warning("APIC calibration not consistent " - "with PM-Timer: %ldms instead of 100ms\n",(long)res); - - /* Correct the lapic counter value */ - res = (((u64)(*delta)) * pm_100ms); - do_div(res, deltapm); - pr_info("APIC delta adjusted to PM-Timer: " - "%lu (%ld)\n", (unsigned long)res, *delta); - *delta = (long)res; - - /* Correct the tsc counter value */ - if (cpu_has_tsc) { - res = (((u64)(*deltatsc)) * pm_100ms); - do_div(res, deltapm); - apic_printk(APIC_VERBOSE, "TSC delta adjusted to " - "PM-Timer: %lu (%ld) \n", - (unsigned long)res, *deltatsc); - *deltatsc = (long)res; - } - - return 0; -} - -static int __init calibrate_APIC_clock(void) -{ - struct clock_event_device *levt = &__get_cpu_var(lapic_events); - void (*real_handler)(struct clock_event_device *dev); - unsigned long deltaj; - long delta, deltatsc; - int pm_referenced = 0; - - local_irq_disable(); - - /* Replace the global interrupt handler */ - real_handler = global_clock_event->event_handler; - global_clock_event->event_handler = lapic_cal_handler; - - /* - * Setup the APIC counter to maximum. There is no way the lapic - * can underflow in the 100ms detection time frame - */ - __setup_APIC_LVTT(0xffffffff, 0, 0); - - /* Let the interrupts run */ - local_irq_enable(); - - while (lapic_cal_loops <= LAPIC_CAL_LOOPS) - cpu_relax(); - - local_irq_disable(); - - /* Restore the real event handler */ - global_clock_event->event_handler = real_handler; - - /* Build delta t1-t2 as apic timer counts down */ - delta = lapic_cal_t1 - lapic_cal_t2; - apic_printk(APIC_VERBOSE, "... lapic delta = %ld\n", delta); - - deltatsc = (long)(lapic_cal_tsc2 - lapic_cal_tsc1); - - /* we trust the PM based calibration if possible */ - pm_referenced = !calibrate_by_pmtimer(lapic_cal_pm2 - lapic_cal_pm1, - &delta, &deltatsc); - - /* Calculate the scaled math multiplication factor */ - lapic_clockevent.mult = div_sc(delta, TICK_NSEC * LAPIC_CAL_LOOPS, - lapic_clockevent.shift); - lapic_clockevent.max_delta_ns = - clockevent_delta2ns(0x7FFFFF, &lapic_clockevent); - lapic_clockevent.min_delta_ns = - clockevent_delta2ns(0xF, &lapic_clockevent); - - calibration_result = (delta * APIC_DIVISOR) / LAPIC_CAL_LOOPS; - - apic_printk(APIC_VERBOSE, "..... delta %ld\n", delta); - apic_printk(APIC_VERBOSE, "..... mult: %ld\n", lapic_clockevent.mult); - apic_printk(APIC_VERBOSE, "..... calibration result: %u\n", - calibration_result); - - if (cpu_has_tsc) { - apic_printk(APIC_VERBOSE, "..... CPU clock speed is " - "%ld.%04ld MHz.\n", - (deltatsc / LAPIC_CAL_LOOPS) / (1000000 / HZ), - (deltatsc / LAPIC_CAL_LOOPS) % (1000000 / HZ)); - } - - apic_printk(APIC_VERBOSE, "..... host bus clock speed is " - "%u.%04u MHz.\n", - calibration_result / (1000000 / HZ), - calibration_result % (1000000 / HZ)); - - /* - * Do a sanity check on the APIC calibration result - */ - if (calibration_result < (1000000 / HZ)) { - local_irq_enable(); - pr_warning("APIC frequency too slow, disabling apic timer\n"); - return -1; - } - - levt->features &= ~CLOCK_EVT_FEAT_DUMMY; - - /* - * PM timer calibration failed or not turned on - * so lets try APIC timer based calibration - */ - if (!pm_referenced) { - apic_printk(APIC_VERBOSE, "... verify APIC timer\n"); - - /* - * Setup the apic timer manually - */ - levt->event_handler = lapic_cal_handler; - lapic_timer_setup(CLOCK_EVT_MODE_PERIODIC, levt); - lapic_cal_loops = -1; - - /* Let the interrupts run */ - local_irq_enable(); - - while (lapic_cal_loops <= LAPIC_CAL_LOOPS) - cpu_relax(); - - /* Stop the lapic timer */ - lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, levt); - - /* Jiffies delta */ - deltaj = lapic_cal_j2 - lapic_cal_j1; - apic_printk(APIC_VERBOSE, "... jiffies delta = %lu\n", deltaj); - - /* Check, if the jiffies result is consistent */ - if (deltaj >= LAPIC_CAL_LOOPS-2 && deltaj <= LAPIC_CAL_LOOPS+2) - apic_printk(APIC_VERBOSE, "... jiffies result ok\n"); - else - levt->features |= CLOCK_EVT_FEAT_DUMMY; - } else - local_irq_enable(); - - if (levt->features & CLOCK_EVT_FEAT_DUMMY) { - pr_warning("APIC timer disabled due to verification failure\n"); - return -1; - } - - return 0; -} - -/* - * Setup the boot APIC - * - * Calibrate and verify the result. - */ -void __init setup_boot_APIC_clock(void) -{ - /* - * The local apic timer can be disabled via the kernel - * commandline or from the CPU detection code. Register the lapic - * timer as a dummy clock event source on SMP systems, so the - * broadcast mechanism is used. On UP systems simply ignore it. - */ - if (disable_apic_timer) { - pr_info("Disabling APIC timer\n"); - /* No broadcast on UP ! */ - if (num_possible_cpus() > 1) { - lapic_clockevent.mult = 1; - setup_APIC_timer(); - } - return; - } - - apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n" - "calibrating APIC timer ...\n"); - - if (calibrate_APIC_clock()) { - /* No broadcast on UP ! */ - if (num_possible_cpus() > 1) - setup_APIC_timer(); - return; - } - - /* - * If nmi_watchdog is set to IO_APIC, we need the - * PIT/HPET going. Otherwise register lapic as a dummy - * device. - */ - if (nmi_watchdog != NMI_IO_APIC) - lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY; - else - pr_warning("APIC timer registered as dummy," - " due to nmi_watchdog=%d!\n", nmi_watchdog); - - /* Setup the lapic or request the broadcast */ - setup_APIC_timer(); -} - -void __cpuinit setup_secondary_APIC_clock(void) -{ - setup_APIC_timer(); -} - -/* - * The guts of the apic timer interrupt - */ -static void local_apic_timer_interrupt(void) -{ - int cpu = smp_processor_id(); - struct clock_event_device *evt = &per_cpu(lapic_events, cpu); - - /* - * Normally we should not be here till LAPIC has been initialized but - * in some cases like kdump, its possible that there is a pending LAPIC - * timer interrupt from previous kernel's context and is delivered in - * new kernel the moment interrupts are enabled. - * - * Interrupts are enabled early and LAPIC is setup much later, hence - * its possible that when we get here evt->event_handler is NULL. - * Check for event_handler being NULL and discard the interrupt as - * spurious. - */ - if (!evt->event_handler) { - pr_warning("Spurious LAPIC timer interrupt on cpu %d\n", cpu); - /* Switch it off */ - lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, evt); - return; - } - - /* - * the NMI deadlock-detector uses this. - */ - inc_irq_stat(apic_timer_irqs); - - evt->event_handler(evt); -} - -/* - * Local APIC timer interrupt. This is the most natural way for doing - * local interrupts, but local timer interrupts can be emulated by - * broadcast interrupts too. [in case the hw doesn't support APIC timers] - * - * [ if a single-CPU system runs an SMP kernel then we call the local - * interrupt as well. Thus we cannot inline the local irq ... ] - */ -void __irq_entry smp_apic_timer_interrupt(struct pt_regs *regs) -{ - struct pt_regs *old_regs = set_irq_regs(regs); - - /* - * NOTE! We'd better ACK the irq immediately, - * because timer handling can be slow. - */ - ack_APIC_irq(); - /* - * update_process_times() expects us to have done irq_enter(). - * Besides, if we don't timer interrupts ignore the global - * interrupt lock, which is the WrongThing (tm) to do. - */ - exit_idle(); - irq_enter(); - local_apic_timer_interrupt(); - irq_exit(); - - set_irq_regs(old_regs); -} - -int setup_profiling_timer(unsigned int multiplier) -{ - return -EINVAL; -} - -/* - * Local APIC start and shutdown - */ - -/** - * clear_local_APIC - shutdown the local APIC - * - * This is called, when a CPU is disabled and before rebooting, so the state of - * the local APIC has no dangling leftovers. Also used to cleanout any BIOS - * leftovers during boot. - */ -void clear_local_APIC(void) -{ - int maxlvt; - u32 v; - - /* APIC hasn't been mapped yet */ - if (!apic_phys) - return; - - maxlvt = lapic_get_maxlvt(); - /* - * Masking an LVT entry can trigger a local APIC error - * if the vector is zero. Mask LVTERR first to prevent this. - */ - if (maxlvt >= 3) { - v = ERROR_APIC_VECTOR; /* any non-zero vector will do */ - apic_write(APIC_LVTERR, v | APIC_LVT_MASKED); - } - /* - * Careful: we have to set masks only first to deassert - * any level-triggered sources. - */ - v = apic_read(APIC_LVTT); - apic_write(APIC_LVTT, v | APIC_LVT_MASKED); - v = apic_read(APIC_LVT0); - apic_write(APIC_LVT0, v | APIC_LVT_MASKED); - v = apic_read(APIC_LVT1); - apic_write(APIC_LVT1, v | APIC_LVT_MASKED); - if (maxlvt >= 4) { - v = apic_read(APIC_LVTPC); - apic_write(APIC_LVTPC, v | APIC_LVT_MASKED); - } - - /* lets not touch this if we didn't frob it */ -#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(X86_MCE_INTEL) - if (maxlvt >= 5) { - v = apic_read(APIC_LVTTHMR); - apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED); - } -#endif - /* - * Clean APIC state for other OSs: - */ - apic_write(APIC_LVTT, APIC_LVT_MASKED); - apic_write(APIC_LVT0, APIC_LVT_MASKED); - apic_write(APIC_LVT1, APIC_LVT_MASKED); - if (maxlvt >= 3) - apic_write(APIC_LVTERR, APIC_LVT_MASKED); - if (maxlvt >= 4) - apic_write(APIC_LVTPC, APIC_LVT_MASKED); - - /* Integrated APIC (!82489DX) ? */ - if (lapic_is_integrated()) { - if (maxlvt > 3) - /* Clear ESR due to Pentium errata 3AP and 11AP */ - apic_write(APIC_ESR, 0); - apic_read(APIC_ESR); - } -} - -/** - * disable_local_APIC - clear and disable the local APIC - */ -void disable_local_APIC(void) -{ - unsigned int value; - - /* APIC hasn't been mapped yet */ - if (!apic_phys) - return; - - clear_local_APIC(); - - /* - * Disable APIC (implies clearing of registers - * for 82489DX!). - */ - value = apic_read(APIC_SPIV); - value &= ~APIC_SPIV_APIC_ENABLED; - apic_write(APIC_SPIV, value); - -#ifdef CONFIG_X86_32 - /* - * When LAPIC was disabled by the BIOS and enabled by the kernel, - * restore the disabled state. - */ - if (enabled_via_apicbase) { - unsigned int l, h; - - rdmsr(MSR_IA32_APICBASE, l, h); - l &= ~MSR_IA32_APICBASE_ENABLE; - wrmsr(MSR_IA32_APICBASE, l, h); - } -#endif -} - -/* - * If Linux enabled the LAPIC against the BIOS default disable it down before - * re-entering the BIOS on shutdown. Otherwise the BIOS may get confused and - * not power-off. Additionally clear all LVT entries before disable_local_APIC - * for the case where Linux didn't enable the LAPIC. - */ -void lapic_shutdown(void) -{ - unsigned long flags; - - if (!cpu_has_apic) - return; - - local_irq_save(flags); - -#ifdef CONFIG_X86_32 - if (!enabled_via_apicbase) - clear_local_APIC(); - else -#endif - disable_local_APIC(); - - - local_irq_restore(flags); -} - -/* - * This is to verify that we're looking at a real local APIC. - * Check these against your board if the CPUs aren't getting - * started for no apparent reason. - */ -int __init verify_local_APIC(void) -{ - unsigned int reg0, reg1; - - /* - * The version register is read-only in a real APIC. - */ - reg0 = apic_read(APIC_LVR); - apic_printk(APIC_DEBUG, "Getting VERSION: %x\n", reg0); - apic_write(APIC_LVR, reg0 ^ APIC_LVR_MASK); - reg1 = apic_read(APIC_LVR); - apic_printk(APIC_DEBUG, "Getting VERSION: %x\n", reg1); - - /* - * The two version reads above should print the same - * numbers. If the second one is different, then we - * poke at a non-APIC. - */ - if (reg1 != reg0) - return 0; - - /* - * Check if the version looks reasonably. - */ - reg1 = GET_APIC_VERSION(reg0); - if (reg1 == 0x00 || reg1 == 0xff) - return 0; - reg1 = lapic_get_maxlvt(); - if (reg1 < 0x02 || reg1 == 0xff) - return 0; - - /* - * The ID register is read/write in a real APIC. - */ - reg0 = apic_read(APIC_ID); - apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg0); - apic_write(APIC_ID, reg0 ^ apic->apic_id_mask); - reg1 = apic_read(APIC_ID); - apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg1); - apic_write(APIC_ID, reg0); - if (reg1 != (reg0 ^ apic->apic_id_mask)) - return 0; - - /* - * The next two are just to see if we have sane values. - * They're only really relevant if we're in Virtual Wire - * compatibility mode, but most boxes are anymore. - */ - reg0 = apic_read(APIC_LVT0); - apic_printk(APIC_DEBUG, "Getting LVT0: %x\n", reg0); - reg1 = apic_read(APIC_LVT1); - apic_printk(APIC_DEBUG, "Getting LVT1: %x\n", reg1); - - return 1; -} - -/** - * sync_Arb_IDs - synchronize APIC bus arbitration IDs - */ -void __init sync_Arb_IDs(void) -{ - /* - * Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 And not - * needed on AMD. - */ - if (modern_apic() || boot_cpu_data.x86_vendor == X86_VENDOR_AMD) - return; - - /* - * Wait for idle. - */ - apic_wait_icr_idle(); - - apic_printk(APIC_DEBUG, "Synchronizing Arb IDs.\n"); - apic_write(APIC_ICR, APIC_DEST_ALLINC | - APIC_INT_LEVELTRIG | APIC_DM_INIT); -} - -/* - * An initial setup of the virtual wire mode. - */ -void __init init_bsp_APIC(void) -{ - unsigned int value; - - /* - * Don't do the setup now if we have a SMP BIOS as the - * through-I/O-APIC virtual wire mode might be active. - */ - if (smp_found_config || !cpu_has_apic) - return; - - /* - * Do not trust the local APIC being empty at bootup. - */ - clear_local_APIC(); - - /* - * Enable APIC. - */ - value = apic_read(APIC_SPIV); - value &= ~APIC_VECTOR_MASK; - value |= APIC_SPIV_APIC_ENABLED; - -#ifdef CONFIG_X86_32 - /* This bit is reserved on P4/Xeon and should be cleared */ - if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && - (boot_cpu_data.x86 == 15)) - value &= ~APIC_SPIV_FOCUS_DISABLED; - else -#endif - value |= APIC_SPIV_FOCUS_DISABLED; - value |= SPURIOUS_APIC_VECTOR; - apic_write(APIC_SPIV, value); - - /* - * Set up the virtual wire mode. - */ - apic_write(APIC_LVT0, APIC_DM_EXTINT); - value = APIC_DM_NMI; - if (!lapic_is_integrated()) /* 82489DX */ - value |= APIC_LVT_LEVEL_TRIGGER; - apic_write(APIC_LVT1, value); -} - -static void __cpuinit lapic_setup_esr(void) -{ - unsigned int oldvalue, value, maxlvt; - - if (!lapic_is_integrated()) { - pr_info("No ESR for 82489DX.\n"); - return; - } - - if (apic->disable_esr) { - /* - * Something untraceable is creating bad interrupts on - * secondary quads ... for the moment, just leave the - * ESR disabled - we can't do anything useful with the - * errors anyway - mbligh - */ - pr_info("Leaving ESR disabled.\n"); - return; - } - - maxlvt = lapic_get_maxlvt(); - if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ - apic_write(APIC_ESR, 0); - oldvalue = apic_read(APIC_ESR); - - /* enables sending errors */ - value = ERROR_APIC_VECTOR; - apic_write(APIC_LVTERR, value); - - /* - * spec says clear errors after enabling vector. - */ - if (maxlvt > 3) - apic_write(APIC_ESR, 0); - value = apic_read(APIC_ESR); - if (value != oldvalue) - apic_printk(APIC_VERBOSE, "ESR value before enabling " - "vector: 0x%08x after: 0x%08x\n", - oldvalue, value); -} - - -/** - * setup_local_APIC - setup the local APIC - */ -void __cpuinit setup_local_APIC(void) -{ - unsigned int value; - int i, j; - - if (disable_apic) { - arch_disable_smp_support(); - return; - } - -#ifdef CONFIG_X86_32 - /* Pound the ESR really hard over the head with a big hammer - mbligh */ - if (lapic_is_integrated() && apic->disable_esr) { - apic_write(APIC_ESR, 0); - apic_write(APIC_ESR, 0); - apic_write(APIC_ESR, 0); - apic_write(APIC_ESR, 0); - } -#endif - - preempt_disable(); - - /* - * Double-check whether this APIC is really registered. - * This is meaningless in clustered apic mode, so we skip it. - */ - if (!apic->apic_id_registered()) - BUG(); - - /* - * Intel recommends to set DFR, LDR and TPR before enabling - * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel - * document number 292116). So here it goes... - */ - apic->init_apic_ldr(); - - /* - * Set Task Priority to 'accept all'. We never change this - * later on. - */ - value = apic_read(APIC_TASKPRI); - value &= ~APIC_TPRI_MASK; - apic_write(APIC_TASKPRI, value); - - /* - * After a crash, we no longer service the interrupts and a pending - * interrupt from previous kernel might still have ISR bit set. - * - * Most probably by now CPU has serviced that pending interrupt and - * it might not have done the ack_APIC_irq() because it thought, - * interrupt came from i8259 as ExtInt. LAPIC did not get EOI so it - * does not clear the ISR bit and cpu thinks it has already serivced - * the interrupt. Hence a vector might get locked. It was noticed - * for timer irq (vector 0x31). Issue an extra EOI to clear ISR. - */ - for (i = APIC_ISR_NR - 1; i >= 0; i--) { - value = apic_read(APIC_ISR + i*0x10); - for (j = 31; j >= 0; j--) { - if (value & (1< 1) || - (boot_cpu_data.x86 >= 15)) - break; - goto no_apic; - case X86_VENDOR_INTEL: - if (boot_cpu_data.x86 == 6 || boot_cpu_data.x86 == 15 || - (boot_cpu_data.x86 == 5 && cpu_has_apic)) - break; - goto no_apic; - default: - goto no_apic; - } - - if (!cpu_has_apic) { - /* - * Over-ride BIOS and try to enable the local APIC only if - * "lapic" specified. - */ - if (!force_enable_local_apic) { - pr_info("Local APIC disabled by BIOS -- " - "you can enable it with \"lapic\"\n"); - return -1; - } - /* - * Some BIOSes disable the local APIC in the APIC_BASE - * MSR. This can only be done in software for Intel P6 or later - * and AMD K7 (Model > 1) or later. - */ - rdmsr(MSR_IA32_APICBASE, l, h); - if (!(l & MSR_IA32_APICBASE_ENABLE)) { - pr_info("Local APIC disabled by BIOS -- reenabling.\n"); - l &= ~MSR_IA32_APICBASE_BASE; - l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE; - wrmsr(MSR_IA32_APICBASE, l, h); - enabled_via_apicbase = 1; - } - } - /* - * The APIC feature bit should now be enabled - * in `cpuid' - */ - features = cpuid_edx(1); - if (!(features & (1 << X86_FEATURE_APIC))) { - pr_warning("Could not enable APIC!\n"); - return -1; - } - set_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC); - mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; - - /* The BIOS may have set up the APIC at some other address */ - rdmsr(MSR_IA32_APICBASE, l, h); - if (l & MSR_IA32_APICBASE_ENABLE) - mp_lapic_addr = l & MSR_IA32_APICBASE_BASE; - - pr_info("Found and enabled local APIC!\n"); - - apic_pm_activate(); - - return 0; - -no_apic: - pr_info("No local APIC present or hardware disabled\n"); - return -1; -} -#endif - -#ifdef CONFIG_X86_64 -void __init early_init_lapic_mapping(void) -{ - unsigned long phys_addr; - - /* - * If no local APIC can be found then go out - * : it means there is no mpatable and MADT - */ - if (!smp_found_config) - return; - - phys_addr = mp_lapic_addr; - - set_fixmap_nocache(FIX_APIC_BASE, phys_addr); - apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n", - APIC_BASE, phys_addr); - - /* - * Fetch the APIC ID of the BSP in case we have a - * default configuration (or the MP table is broken). - */ - boot_cpu_physical_apicid = read_apic_id(); -} -#endif - -/** - * init_apic_mappings - initialize APIC mappings - */ -void __init init_apic_mappings(void) -{ -#ifdef CONFIG_X86_X2APIC - if (x2apic) { - boot_cpu_physical_apicid = read_apic_id(); - return; - } -#endif - - /* - * If no local APIC can be found then set up a fake all - * zeroes page to simulate the local APIC and another - * one for the IO-APIC. - */ - if (!smp_found_config && detect_init_APIC()) { - apic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE); - apic_phys = __pa(apic_phys); - } else - apic_phys = mp_lapic_addr; - - set_fixmap_nocache(FIX_APIC_BASE, apic_phys); - apic_printk(APIC_VERBOSE, "mapped APIC to %08lx (%08lx)\n", - APIC_BASE, apic_phys); - - /* - * Fetch the APIC ID of the BSP in case we have a - * default configuration (or the MP table is broken). - */ - if (boot_cpu_physical_apicid == -1U) - boot_cpu_physical_apicid = read_apic_id(); -} - -/* - * This initializes the IO-APIC and APIC hardware if this is - * a UP kernel. - */ -int apic_version[MAX_APICS]; - -int __init APIC_init_uniprocessor(void) -{ - if (disable_apic) { - pr_info("Apic disabled\n"); - return -1; - } -#ifdef CONFIG_X86_64 - if (!cpu_has_apic) { - disable_apic = 1; - pr_info("Apic disabled by BIOS\n"); - return -1; - } -#else - if (!smp_found_config && !cpu_has_apic) - return -1; - - /* - * Complain if the BIOS pretends there is one. - */ - if (!cpu_has_apic && - APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { - pr_err("BIOS bug, local APIC 0x%x not detected!...\n", - boot_cpu_physical_apicid); - clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC); - return -1; - } -#endif - - enable_IR_x2apic(); -#ifdef CONFIG_X86_64 - default_setup_apic_routing(); -#endif - - verify_local_APIC(); - connect_bsp_APIC(); - -#ifdef CONFIG_X86_64 - apic_write(APIC_ID, SET_APIC_ID(boot_cpu_physical_apicid)); -#else - /* - * Hack: In case of kdump, after a crash, kernel might be booting - * on a cpu with non-zero lapic id. But boot_cpu_physical_apicid - * might be zero if read from MP tables. Get it from LAPIC. - */ -# ifdef CONFIG_CRASH_DUMP - boot_cpu_physical_apicid = read_apic_id(); -# endif -#endif - physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map); - setup_local_APIC(); - -#ifdef CONFIG_X86_IO_APIC - /* - * Now enable IO-APICs, actually call clear_IO_APIC - * We need clear_IO_APIC before enabling error vector - */ - if (!skip_ioapic_setup && nr_ioapics) - enable_IO_APIC(); -#endif - - end_local_APIC_setup(); - -#ifdef CONFIG_X86_IO_APIC - if (smp_found_config && !skip_ioapic_setup && nr_ioapics) - setup_IO_APIC(); - else { - nr_ioapics = 0; - localise_nmi_watchdog(); - } -#else - localise_nmi_watchdog(); -#endif - - setup_boot_clock(); -#ifdef CONFIG_X86_64 - check_nmi_watchdog(); -#endif - - return 0; -} - -/* - * Local APIC interrupts - */ - -/* - * This interrupt should _never_ happen with our APIC/SMP architecture - */ -void smp_spurious_interrupt(struct pt_regs *regs) -{ - u32 v; - - exit_idle(); - irq_enter(); - /* - * Check if this really is a spurious interrupt and ACK it - * if it is a vectored one. Just in case... - * Spurious interrupts should not be ACKed. - */ - v = apic_read(APIC_ISR + ((SPURIOUS_APIC_VECTOR & ~0x1f) >> 1)); - if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f))) - ack_APIC_irq(); - - inc_irq_stat(irq_spurious_count); - - /* see sw-dev-man vol 3, chapter 7.4.13.5 */ - pr_info("spurious APIC interrupt on CPU#%d, " - "should never happen.\n", smp_processor_id()); - irq_exit(); -} - -/* - * This interrupt should never happen with our APIC/SMP architecture - */ -void smp_error_interrupt(struct pt_regs *regs) -{ - u32 v, v1; - - exit_idle(); - irq_enter(); - /* First tickle the hardware, only then report what went on. -- REW */ - v = apic_read(APIC_ESR); - apic_write(APIC_ESR, 0); - v1 = apic_read(APIC_ESR); - ack_APIC_irq(); - atomic_inc(&irq_err_count); - - /* - * Here is what the APIC error bits mean: - * 0: Send CS error - * 1: Receive CS error - * 2: Send accept error - * 3: Receive accept error - * 4: Reserved - * 5: Send illegal vector - * 6: Received illegal vector - * 7: Illegal register address - */ - pr_debug("APIC error on CPU%d: %02x(%02x)\n", - smp_processor_id(), v , v1); - irq_exit(); -} - -/** - * connect_bsp_APIC - attach the APIC to the interrupt system - */ -void __init connect_bsp_APIC(void) -{ -#ifdef CONFIG_X86_32 - if (pic_mode) { - /* - * Do not trust the local APIC being empty at bootup. - */ - clear_local_APIC(); - /* - * PIC mode, enable APIC mode in the IMCR, i.e. connect BSP's - * local APIC to INT and NMI lines. - */ - apic_printk(APIC_VERBOSE, "leaving PIC mode, " - "enabling APIC mode.\n"); - outb(0x70, 0x22); - outb(0x01, 0x23); - } -#endif - if (apic->enable_apic_mode) - apic->enable_apic_mode(); -} - -/** - * disconnect_bsp_APIC - detach the APIC from the interrupt system - * @virt_wire_setup: indicates, whether virtual wire mode is selected - * - * Virtual wire mode is necessary to deliver legacy interrupts even when the - * APIC is disabled. - */ -void disconnect_bsp_APIC(int virt_wire_setup) -{ - unsigned int value; - -#ifdef CONFIG_X86_32 - if (pic_mode) { - /* - * Put the board back into PIC mode (has an effect only on - * certain older boards). Note that APIC interrupts, including - * IPIs, won't work beyond this point! The only exception are - * INIT IPIs. - */ - apic_printk(APIC_VERBOSE, "disabling APIC mode, " - "entering PIC mode.\n"); - outb(0x70, 0x22); - outb(0x00, 0x23); - return; - } -#endif - - /* Go back to Virtual Wire compatibility mode */ - - /* For the spurious interrupt use vector F, and enable it */ - value = apic_read(APIC_SPIV); - value &= ~APIC_VECTOR_MASK; - value |= APIC_SPIV_APIC_ENABLED; - value |= 0xf; - apic_write(APIC_SPIV, value); - - if (!virt_wire_setup) { - /* - * For LVT0 make it edge triggered, active high, - * external and enabled - */ - value = apic_read(APIC_LVT0); - value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING | - APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | - APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED); - value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; - value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT); - apic_write(APIC_LVT0, value); - } else { - /* Disable LVT0 */ - apic_write(APIC_LVT0, APIC_LVT_MASKED); - } - - /* - * For LVT1 make it edge triggered, active high, - * nmi and enabled - */ - value = apic_read(APIC_LVT1); - value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING | - APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | - APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED); - value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; - value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI); - apic_write(APIC_LVT1, value); -} - -void __cpuinit generic_processor_info(int apicid, int version) -{ - int cpu; - - /* - * Validate version - */ - if (version == 0x0) { - pr_warning("BIOS bug, APIC version is 0 for CPU#%d! " - "fixing up to 0x10. (tell your hw vendor)\n", - version); - version = 0x10; - } - apic_version[apicid] = version; - - if (num_processors >= nr_cpu_ids) { - int max = nr_cpu_ids; - int thiscpu = max + disabled_cpus; - - pr_warning( - "ACPI: NR_CPUS/possible_cpus limit of %i reached." - " Processor %d/0x%x ignored.\n", max, thiscpu, apicid); - - disabled_cpus++; - return; - } - - num_processors++; - cpu = cpumask_next_zero(-1, cpu_present_mask); - - if (version != apic_version[boot_cpu_physical_apicid]) - WARN_ONCE(1, - "ACPI: apic version mismatch, bootcpu: %x cpu %d: %x\n", - apic_version[boot_cpu_physical_apicid], cpu, version); - - physid_set(apicid, phys_cpu_present_map); - if (apicid == boot_cpu_physical_apicid) { - /* - * x86_bios_cpu_apicid is required to have processors listed - * in same order as logical cpu numbers. Hence the first - * entry is BSP, and so on. - */ - cpu = 0; - } - if (apicid > max_physical_apicid) - max_physical_apicid = apicid; - -#ifdef CONFIG_X86_32 - /* - * Would be preferable to switch to bigsmp when CONFIG_HOTPLUG_CPU=y - * but we need to work other dependencies like SMP_SUSPEND etc - * before this can be done without some confusion. - * if (CPU_HOTPLUG_ENABLED || num_processors > 8) - * - Ashok Raj - */ - if (max_physical_apicid >= 8) { - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_INTEL: - if (!APIC_XAPIC(version)) { - def_to_bigsmp = 0; - break; - } - /* If P4 and above fall through */ - case X86_VENDOR_AMD: - def_to_bigsmp = 1; - } - } -#endif - -#if defined(CONFIG_SMP) || defined(CONFIG_X86_64) - early_per_cpu(x86_cpu_to_apicid, cpu) = apicid; - early_per_cpu(x86_bios_cpu_apicid, cpu) = apicid; -#endif - - set_cpu_possible(cpu, true); - set_cpu_present(cpu, true); -} - -int hard_smp_processor_id(void) -{ - return read_apic_id(); -} - -void default_init_apic_ldr(void) -{ - unsigned long val; - - apic_write(APIC_DFR, APIC_DFR_VALUE); - val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; - val |= SET_APIC_LOGICAL_ID(1UL << smp_processor_id()); - apic_write(APIC_LDR, val); -} - -#ifdef CONFIG_X86_32 -int default_apicid_to_node(int logical_apicid) -{ -#ifdef CONFIG_SMP - return apicid_2_node[hard_smp_processor_id()]; -#else - return 0; -#endif -} -#endif - -/* - * Power management - */ -#ifdef CONFIG_PM - -static struct { - /* - * 'active' is true if the local APIC was enabled by us and - * not the BIOS; this signifies that we are also responsible - * for disabling it before entering apm/acpi suspend - */ - int active; - /* r/w apic fields */ - unsigned int apic_id; - unsigned int apic_taskpri; - unsigned int apic_ldr; - unsigned int apic_dfr; - unsigned int apic_spiv; - unsigned int apic_lvtt; - unsigned int apic_lvtpc; - unsigned int apic_lvt0; - unsigned int apic_lvt1; - unsigned int apic_lvterr; - unsigned int apic_tmict; - unsigned int apic_tdcr; - unsigned int apic_thmr; -} apic_pm_state; - -static int lapic_suspend(struct sys_device *dev, pm_message_t state) -{ - unsigned long flags; - int maxlvt; - - if (!apic_pm_state.active) - return 0; - - maxlvt = lapic_get_maxlvt(); - - apic_pm_state.apic_id = apic_read(APIC_ID); - apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI); - apic_pm_state.apic_ldr = apic_read(APIC_LDR); - apic_pm_state.apic_dfr = apic_read(APIC_DFR); - apic_pm_state.apic_spiv = apic_read(APIC_SPIV); - apic_pm_state.apic_lvtt = apic_read(APIC_LVTT); - if (maxlvt >= 4) - apic_pm_state.apic_lvtpc = apic_read(APIC_LVTPC); - apic_pm_state.apic_lvt0 = apic_read(APIC_LVT0); - apic_pm_state.apic_lvt1 = apic_read(APIC_LVT1); - apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR); - apic_pm_state.apic_tmict = apic_read(APIC_TMICT); - apic_pm_state.apic_tdcr = apic_read(APIC_TDCR); -#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL) - if (maxlvt >= 5) - apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); -#endif - - local_irq_save(flags); - disable_local_APIC(); - local_irq_restore(flags); - return 0; -} - -static int lapic_resume(struct sys_device *dev) -{ - unsigned int l, h; - unsigned long flags; - int maxlvt; - - if (!apic_pm_state.active) - return 0; - - maxlvt = lapic_get_maxlvt(); - - local_irq_save(flags); - -#ifdef CONFIG_X86_X2APIC - if (x2apic) - enable_x2apic(); - else -#endif - { - /* - * Make sure the APICBASE points to the right address - * - * FIXME! This will be wrong if we ever support suspend on - * SMP! We'll need to do this as part of the CPU restore! - */ - rdmsr(MSR_IA32_APICBASE, l, h); - l &= ~MSR_IA32_APICBASE_BASE; - l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr; - wrmsr(MSR_IA32_APICBASE, l, h); - } - - apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED); - apic_write(APIC_ID, apic_pm_state.apic_id); - apic_write(APIC_DFR, apic_pm_state.apic_dfr); - apic_write(APIC_LDR, apic_pm_state.apic_ldr); - apic_write(APIC_TASKPRI, apic_pm_state.apic_taskpri); - apic_write(APIC_SPIV, apic_pm_state.apic_spiv); - apic_write(APIC_LVT0, apic_pm_state.apic_lvt0); - apic_write(APIC_LVT1, apic_pm_state.apic_lvt1); -#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL) - if (maxlvt >= 5) - apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr); -#endif - if (maxlvt >= 4) - apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc); - apic_write(APIC_LVTT, apic_pm_state.apic_lvtt); - apic_write(APIC_TDCR, apic_pm_state.apic_tdcr); - apic_write(APIC_TMICT, apic_pm_state.apic_tmict); - apic_write(APIC_ESR, 0); - apic_read(APIC_ESR); - apic_write(APIC_LVTERR, apic_pm_state.apic_lvterr); - apic_write(APIC_ESR, 0); - apic_read(APIC_ESR); - - local_irq_restore(flags); - - return 0; -} - -/* - * This device has no shutdown method - fully functioning local APICs - * are needed on every CPU up until machine_halt/restart/poweroff. - */ - -static struct sysdev_class lapic_sysclass = { - .name = "lapic", - .resume = lapic_resume, - .suspend = lapic_suspend, -}; - -static struct sys_device device_lapic = { - .id = 0, - .cls = &lapic_sysclass, -}; - -static void __cpuinit apic_pm_activate(void) -{ - apic_pm_state.active = 1; -} - -static int __init init_lapic_sysfs(void) -{ - int error; - - if (!cpu_has_apic) - return 0; - /* XXX: remove suspend/resume procs if !apic_pm_state.active? */ - - error = sysdev_class_register(&lapic_sysclass); - if (!error) - error = sysdev_register(&device_lapic); - return error; -} -device_initcall(init_lapic_sysfs); - -#else /* CONFIG_PM */ - -static void apic_pm_activate(void) { } - -#endif /* CONFIG_PM */ - -#ifdef CONFIG_X86_64 -/* - * apic_is_clustered_box() -- Check if we can expect good TSC - * - * Thus far, the major user of this is IBM's Summit2 series: - * - * Clustered boxes may have unsynced TSC problems if they are - * multi-chassis. Use available data to take a good guess. - * If in doubt, go HPET. - */ -__cpuinit int apic_is_clustered_box(void) -{ - int i, clusters, zeros; - unsigned id; - u16 *bios_cpu_apicid; - DECLARE_BITMAP(clustermap, NUM_APIC_CLUSTERS); - - /* - * there is not this kind of box with AMD CPU yet. - * Some AMD box with quadcore cpu and 8 sockets apicid - * will be [4, 0x23] or [8, 0x27] could be thought to - * vsmp box still need checking... - */ - if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && !is_vsmp_box()) - return 0; - - bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid); - bitmap_zero(clustermap, NUM_APIC_CLUSTERS); - - for (i = 0; i < nr_cpu_ids; i++) { - /* are we being called early in kernel startup? */ - if (bios_cpu_apicid) { - id = bios_cpu_apicid[i]; - } else if (i < nr_cpu_ids) { - if (cpu_present(i)) - id = per_cpu(x86_bios_cpu_apicid, i); - else - continue; - } else - break; - - if (id != BAD_APICID) - __set_bit(APIC_CLUSTERID(id), clustermap); - } - - /* Problem: Partially populated chassis may not have CPUs in some of - * the APIC clusters they have been allocated. Only present CPUs have - * x86_bios_cpu_apicid entries, thus causing zeroes in the bitmap. - * Since clusters are allocated sequentially, count zeros only if - * they are bounded by ones. - */ - clusters = 0; - zeros = 0; - for (i = 0; i < NUM_APIC_CLUSTERS; i++) { - if (test_bit(i, clustermap)) { - clusters += 1 + zeros; - zeros = 0; - } else - ++zeros; - } - - /* ScaleMP vSMPowered boxes have one cluster per board and TSCs are - * not guaranteed to be synced between boards - */ - if (is_vsmp_box() && clusters > 1) - return 1; - - /* - * If clusters > 2, then should be multi-chassis. - * May have to revisit this when multi-core + hyperthreaded CPUs come - * out, but AFAIK this will work even for them. - */ - return (clusters > 2); -} -#endif - -/* - * APIC command line parameters - */ -static int __init setup_disableapic(char *arg) -{ - disable_apic = 1; - setup_clear_cpu_cap(X86_FEATURE_APIC); - return 0; -} -early_param("disableapic", setup_disableapic); - -/* same as disableapic, for compatibility */ -static int __init setup_nolapic(char *arg) -{ - return setup_disableapic(arg); -} -early_param("nolapic", setup_nolapic); - -static int __init parse_lapic_timer_c2_ok(char *arg) -{ - local_apic_timer_c2_ok = 1; - return 0; -} -early_param("lapic_timer_c2_ok", parse_lapic_timer_c2_ok); - -static int __init parse_disable_apic_timer(char *arg) -{ - disable_apic_timer = 1; - return 0; -} -early_param("noapictimer", parse_disable_apic_timer); - -static int __init parse_nolapic_timer(char *arg) -{ - disable_apic_timer = 1; - return 0; -} -early_param("nolapic_timer", parse_nolapic_timer); - -static int __init apic_set_verbosity(char *arg) -{ - if (!arg) { -#ifdef CONFIG_X86_64 - skip_ioapic_setup = 0; - return 0; -#endif - return -EINVAL; - } - - if (strcmp("debug", arg) == 0) - apic_verbosity = APIC_DEBUG; - else if (strcmp("verbose", arg) == 0) - apic_verbosity = APIC_VERBOSE; - else { - pr_warning("APIC Verbosity level %s not recognised" - " use apic=verbose or apic=debug\n", arg); - return -EINVAL; - } - - return 0; -} -early_param("apic", apic_set_verbosity); - -static int __init lapic_insert_resource(void) -{ - if (!apic_phys) - return -1; - - /* Put local APIC into the resource map. */ - lapic_resource.start = apic_phys; - lapic_resource.end = lapic_resource.start + PAGE_SIZE - 1; - insert_resource(&iomem_resource, &lapic_resource); - - return 0; -} - -/* - * need call insert after e820_reserve_resources() - * that is using request_resource - */ -late_initcall(lapic_insert_resource); diff --git a/arch/x86/kernel/apic/Makefile b/arch/x86/kernel/apic/Makefile new file mode 100644 index 00000000000..da20b70c400 --- /dev/null +++ b/arch/x86/kernel/apic/Makefile @@ -0,0 +1,15 @@ +# +# Makefile for local APIC drivers and for the IO-APIC code +# + +obj-y := apic.o ipi.o nmi.o +obj-$(CONFIG_X86_IO_APIC) += io_apic.o +obj-$(CONFIG_SMP) += ipi.o + +ifeq ($(CONFIG_X86_64),y) +obj-y += apic_64.o apic_flat_64.o +obj-$(CONFIG_X86_X2APIC) += x2apic_cluster.o +obj-$(CONFIG_X86_X2APIC) += x2apic_phys.o +obj-$(CONFIG_X86_UV) += x2apic_uv_x.o +endif + diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c new file mode 100644 index 00000000000..c12823eb55b --- /dev/null +++ b/arch/x86/kernel/apic/apic.c @@ -0,0 +1,2212 @@ +/* + * Local APIC handling, local APIC timers + * + * (c) 1999, 2000, 2009 Ingo Molnar + * + * Fixes + * Maciej W. Rozycki : Bits for genuine 82489DX APICs; + * thanks to Eric Gilmore + * and Rolf G. Tews + * for testing these extensively. + * Maciej W. Rozycki : Various updates and fixes. + * Mikael Pettersson : Power Management for UP-APIC. + * Pavel Machek and + * Mikael Pettersson : PM converted to driver model. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +unsigned int num_processors; + +unsigned disabled_cpus __cpuinitdata; + +/* Processor that is doing the boot up */ +unsigned int boot_cpu_physical_apicid = -1U; + +/* + * The highest APIC ID seen during enumeration. + * + * This determines the messaging protocol we can use: if all APIC IDs + * are in the 0 ... 7 range, then we can use logical addressing which + * has some performance advantages (better broadcasting). + * + * If there's an APIC ID above 8, we use physical addressing. + */ +unsigned int max_physical_apicid; + +/* + * Bitmask of physically existing CPUs: + */ +physid_mask_t phys_cpu_present_map; + +/* + * Map cpu index to physical APIC ID + */ +DEFINE_EARLY_PER_CPU(u16, x86_cpu_to_apicid, BAD_APICID); +DEFINE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid, BAD_APICID); +EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_apicid); +EXPORT_EARLY_PER_CPU_SYMBOL(x86_bios_cpu_apicid); + +#ifdef CONFIG_X86_32 +/* + * Knob to control our willingness to enable the local APIC. + * + * +1=force-enable + */ +static int force_enable_local_apic; +/* + * APIC command line parameters + */ +static int __init parse_lapic(char *arg) +{ + force_enable_local_apic = 1; + return 0; +} +early_param("lapic", parse_lapic); +/* Local APIC was disabled by the BIOS and enabled by the kernel */ +static int enabled_via_apicbase; + +#endif + +#ifdef CONFIG_X86_64 +static int apic_calibrate_pmtmr __initdata; +static __init int setup_apicpmtimer(char *s) +{ + apic_calibrate_pmtmr = 1; + notsc_setup(NULL); + return 0; +} +__setup("apicpmtimer", setup_apicpmtimer); +#endif + +#ifdef CONFIG_X86_X2APIC +int x2apic; +/* x2apic enabled before OS handover */ +static int x2apic_preenabled; +static int disable_x2apic; +static __init int setup_nox2apic(char *str) +{ + disable_x2apic = 1; + setup_clear_cpu_cap(X86_FEATURE_X2APIC); + return 0; +} +early_param("nox2apic", setup_nox2apic); +#endif + +unsigned long mp_lapic_addr; +int disable_apic; +/* Disable local APIC timer from the kernel commandline or via dmi quirk */ +static int disable_apic_timer __cpuinitdata; +/* Local APIC timer works in C2 */ +int local_apic_timer_c2_ok; +EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok); + +int first_system_vector = 0xfe; + +/* + * Debug level, exported for io_apic.c + */ +unsigned int apic_verbosity; + +int pic_mode; + +/* Have we found an MP table */ +int smp_found_config; + +static struct resource lapic_resource = { + .name = "Local APIC", + .flags = IORESOURCE_MEM | IORESOURCE_BUSY, +}; + +static unsigned int calibration_result; + +static int lapic_next_event(unsigned long delta, + struct clock_event_device *evt); +static void lapic_timer_setup(enum clock_event_mode mode, + struct clock_event_device *evt); +static void lapic_timer_broadcast(const struct cpumask *mask); +static void apic_pm_activate(void); + +/* + * The local apic timer can be used for any function which is CPU local. + */ +static struct clock_event_device lapic_clockevent = { + .name = "lapic", + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT + | CLOCK_EVT_FEAT_C3STOP | CLOCK_EVT_FEAT_DUMMY, + .shift = 32, + .set_mode = lapic_timer_setup, + .set_next_event = lapic_next_event, + .broadcast = lapic_timer_broadcast, + .rating = 100, + .irq = -1, +}; +static DEFINE_PER_CPU(struct clock_event_device, lapic_events); + +static unsigned long apic_phys; + +/* + * Get the LAPIC version + */ +static inline int lapic_get_version(void) +{ + return GET_APIC_VERSION(apic_read(APIC_LVR)); +} + +/* + * Check, if the APIC is integrated or a separate chip + */ +static inline int lapic_is_integrated(void) +{ +#ifdef CONFIG_X86_64 + return 1; +#else + return APIC_INTEGRATED(lapic_get_version()); +#endif +} + +/* + * Check, whether this is a modern or a first generation APIC + */ +static int modern_apic(void) +{ + /* AMD systems use old APIC versions, so check the CPU */ + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && + boot_cpu_data.x86 >= 0xf) + return 1; + return lapic_get_version() >= 0x14; +} + +void native_apic_wait_icr_idle(void) +{ + while (apic_read(APIC_ICR) & APIC_ICR_BUSY) + cpu_relax(); +} + +u32 native_safe_apic_wait_icr_idle(void) +{ + u32 send_status; + int timeout; + + timeout = 0; + do { + send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; + if (!send_status) + break; + udelay(100); + } while (timeout++ < 1000); + + return send_status; +} + +void native_apic_icr_write(u32 low, u32 id) +{ + apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(id)); + apic_write(APIC_ICR, low); +} + +u64 native_apic_icr_read(void) +{ + u32 icr1, icr2; + + icr2 = apic_read(APIC_ICR2); + icr1 = apic_read(APIC_ICR); + + return icr1 | ((u64)icr2 << 32); +} + +/** + * enable_NMI_through_LVT0 - enable NMI through local vector table 0 + */ +void __cpuinit enable_NMI_through_LVT0(void) +{ + unsigned int v; + + /* unmask and set to NMI */ + v = APIC_DM_NMI; + + /* Level triggered for 82489DX (32bit mode) */ + if (!lapic_is_integrated()) + v |= APIC_LVT_LEVEL_TRIGGER; + + apic_write(APIC_LVT0, v); +} + +#ifdef CONFIG_X86_32 +/** + * get_physical_broadcast - Get number of physical broadcast IDs + */ +int get_physical_broadcast(void) +{ + return modern_apic() ? 0xff : 0xf; +} +#endif + +/** + * lapic_get_maxlvt - get the maximum number of local vector table entries + */ +int lapic_get_maxlvt(void) +{ + unsigned int v; + + v = apic_read(APIC_LVR); + /* + * - we always have APIC integrated on 64bit mode + * - 82489DXs do not report # of LVT entries + */ + return APIC_INTEGRATED(GET_APIC_VERSION(v)) ? GET_APIC_MAXLVT(v) : 2; +} + +/* + * Local APIC timer + */ + +/* Clock divisor */ +#define APIC_DIVISOR 16 + +/* + * This function sets up the local APIC timer, with a timeout of + * 'clocks' APIC bus clock. During calibration we actually call + * this function twice on the boot CPU, once with a bogus timeout + * value, second time for real. The other (noncalibrating) CPUs + * call this function only once, with the real, calibrated value. + * + * We do reads before writes even if unnecessary, to get around the + * P5 APIC double write bug. + */ +static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) +{ + unsigned int lvtt_value, tmp_value; + + lvtt_value = LOCAL_TIMER_VECTOR; + if (!oneshot) + lvtt_value |= APIC_LVT_TIMER_PERIODIC; + if (!lapic_is_integrated()) + lvtt_value |= SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV); + + if (!irqen) + lvtt_value |= APIC_LVT_MASKED; + + apic_write(APIC_LVTT, lvtt_value); + + /* + * Divide PICLK by 16 + */ + tmp_value = apic_read(APIC_TDCR); + apic_write(APIC_TDCR, + (tmp_value & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE)) | + APIC_TDR_DIV_16); + + if (!oneshot) + apic_write(APIC_TMICT, clocks / APIC_DIVISOR); +} + +/* + * Setup extended LVT, AMD specific (K8, family 10h) + * + * Vector mappings are hard coded. On K8 only offset 0 (APIC500) and + * MCE interrupts are supported. Thus MCE offset must be set to 0. + * + * If mask=1, the LVT entry does not generate interrupts while mask=0 + * enables the vector. See also the BKDGs. + */ + +#define APIC_EILVT_LVTOFF_MCE 0 +#define APIC_EILVT_LVTOFF_IBS 1 + +static void setup_APIC_eilvt(u8 lvt_off, u8 vector, u8 msg_type, u8 mask) +{ + unsigned long reg = (lvt_off << 4) + APIC_EILVT0; + unsigned int v = (mask << 16) | (msg_type << 8) | vector; + + apic_write(reg, v); +} + +u8 setup_APIC_eilvt_mce(u8 vector, u8 msg_type, u8 mask) +{ + setup_APIC_eilvt(APIC_EILVT_LVTOFF_MCE, vector, msg_type, mask); + return APIC_EILVT_LVTOFF_MCE; +} + +u8 setup_APIC_eilvt_ibs(u8 vector, u8 msg_type, u8 mask) +{ + setup_APIC_eilvt(APIC_EILVT_LVTOFF_IBS, vector, msg_type, mask); + return APIC_EILVT_LVTOFF_IBS; +} +EXPORT_SYMBOL_GPL(setup_APIC_eilvt_ibs); + +/* + * Program the next event, relative to now + */ +static int lapic_next_event(unsigned long delta, + struct clock_event_device *evt) +{ + apic_write(APIC_TMICT, delta); + return 0; +} + +/* + * Setup the lapic timer in periodic or oneshot mode + */ +static void lapic_timer_setup(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + unsigned long flags; + unsigned int v; + + /* Lapic used as dummy for broadcast ? */ + if (evt->features & CLOCK_EVT_FEAT_DUMMY) + return; + + local_irq_save(flags); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + case CLOCK_EVT_MODE_ONESHOT: + __setup_APIC_LVTT(calibration_result, + mode != CLOCK_EVT_MODE_PERIODIC, 1); + break; + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + v = apic_read(APIC_LVTT); + v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); + apic_write(APIC_LVTT, v); + apic_write(APIC_TMICT, 0xffffffff); + break; + case CLOCK_EVT_MODE_RESUME: + /* Nothing to do here */ + break; + } + + local_irq_restore(flags); +} + +/* + * Local APIC timer broadcast function + */ +static void lapic_timer_broadcast(const struct cpumask *mask) +{ +#ifdef CONFIG_SMP + apic->send_IPI_mask(mask, LOCAL_TIMER_VECTOR); +#endif +} + +/* + * Setup the local APIC timer for this CPU. Copy the initilized values + * of the boot CPU and register the clock event in the framework. + */ +static void __cpuinit setup_APIC_timer(void) +{ + struct clock_event_device *levt = &__get_cpu_var(lapic_events); + + memcpy(levt, &lapic_clockevent, sizeof(*levt)); + levt->cpumask = cpumask_of(smp_processor_id()); + + clockevents_register_device(levt); +} + +/* + * In this functions we calibrate APIC bus clocks to the external timer. + * + * We want to do the calibration only once since we want to have local timer + * irqs syncron. CPUs connected by the same APIC bus have the very same bus + * frequency. + * + * This was previously done by reading the PIT/HPET and waiting for a wrap + * around to find out, that a tick has elapsed. I have a box, where the PIT + * readout is broken, so it never gets out of the wait loop again. This was + * also reported by others. + * + * Monitoring the jiffies value is inaccurate and the clockevents + * infrastructure allows us to do a simple substitution of the interrupt + * handler. + * + * The calibration routine also uses the pm_timer when possible, as the PIT + * happens to run way too slow (factor 2.3 on my VAIO CoreDuo, which goes + * back to normal later in the boot process). + */ + +#define LAPIC_CAL_LOOPS (HZ/10) + +static __initdata int lapic_cal_loops = -1; +static __initdata long lapic_cal_t1, lapic_cal_t2; +static __initdata unsigned long long lapic_cal_tsc1, lapic_cal_tsc2; +static __initdata unsigned long lapic_cal_pm1, lapic_cal_pm2; +static __initdata unsigned long lapic_cal_j1, lapic_cal_j2; + +/* + * Temporary interrupt handler. + */ +static void __init lapic_cal_handler(struct clock_event_device *dev) +{ + unsigned long long tsc = 0; + long tapic = apic_read(APIC_TMCCT); + unsigned long pm = acpi_pm_read_early(); + + if (cpu_has_tsc) + rdtscll(tsc); + + switch (lapic_cal_loops++) { + case 0: + lapic_cal_t1 = tapic; + lapic_cal_tsc1 = tsc; + lapic_cal_pm1 = pm; + lapic_cal_j1 = jiffies; + break; + + case LAPIC_CAL_LOOPS: + lapic_cal_t2 = tapic; + lapic_cal_tsc2 = tsc; + if (pm < lapic_cal_pm1) + pm += ACPI_PM_OVRRUN; + lapic_cal_pm2 = pm; + lapic_cal_j2 = jiffies; + break; + } +} + +static int __init +calibrate_by_pmtimer(long deltapm, long *delta, long *deltatsc) +{ + const long pm_100ms = PMTMR_TICKS_PER_SEC / 10; + const long pm_thresh = pm_100ms / 100; + unsigned long mult; + u64 res; + +#ifndef CONFIG_X86_PM_TIMER + return -1; +#endif + + apic_printk(APIC_VERBOSE, "... PM-Timer delta = %ld\n", deltapm); + + /* Check, if the PM timer is available */ + if (!deltapm) + return -1; + + mult = clocksource_hz2mult(PMTMR_TICKS_PER_SEC, 22); + + if (deltapm > (pm_100ms - pm_thresh) && + deltapm < (pm_100ms + pm_thresh)) { + apic_printk(APIC_VERBOSE, "... PM-Timer result ok\n"); + return 0; + } + + res = (((u64)deltapm) * mult) >> 22; + do_div(res, 1000000); + pr_warning("APIC calibration not consistent " + "with PM-Timer: %ldms instead of 100ms\n",(long)res); + + /* Correct the lapic counter value */ + res = (((u64)(*delta)) * pm_100ms); + do_div(res, deltapm); + pr_info("APIC delta adjusted to PM-Timer: " + "%lu (%ld)\n", (unsigned long)res, *delta); + *delta = (long)res; + + /* Correct the tsc counter value */ + if (cpu_has_tsc) { + res = (((u64)(*deltatsc)) * pm_100ms); + do_div(res, deltapm); + apic_printk(APIC_VERBOSE, "TSC delta adjusted to " + "PM-Timer: %lu (%ld) \n", + (unsigned long)res, *deltatsc); + *deltatsc = (long)res; + } + + return 0; +} + +static int __init calibrate_APIC_clock(void) +{ + struct clock_event_device *levt = &__get_cpu_var(lapic_events); + void (*real_handler)(struct clock_event_device *dev); + unsigned long deltaj; + long delta, deltatsc; + int pm_referenced = 0; + + local_irq_disable(); + + /* Replace the global interrupt handler */ + real_handler = global_clock_event->event_handler; + global_clock_event->event_handler = lapic_cal_handler; + + /* + * Setup the APIC counter to maximum. There is no way the lapic + * can underflow in the 100ms detection time frame + */ + __setup_APIC_LVTT(0xffffffff, 0, 0); + + /* Let the interrupts run */ + local_irq_enable(); + + while (lapic_cal_loops <= LAPIC_CAL_LOOPS) + cpu_relax(); + + local_irq_disable(); + + /* Restore the real event handler */ + global_clock_event->event_handler = real_handler; + + /* Build delta t1-t2 as apic timer counts down */ + delta = lapic_cal_t1 - lapic_cal_t2; + apic_printk(APIC_VERBOSE, "... lapic delta = %ld\n", delta); + + deltatsc = (long)(lapic_cal_tsc2 - lapic_cal_tsc1); + + /* we trust the PM based calibration if possible */ + pm_referenced = !calibrate_by_pmtimer(lapic_cal_pm2 - lapic_cal_pm1, + &delta, &deltatsc); + + /* Calculate the scaled math multiplication factor */ + lapic_clockevent.mult = div_sc(delta, TICK_NSEC * LAPIC_CAL_LOOPS, + lapic_clockevent.shift); + lapic_clockevent.max_delta_ns = + clockevent_delta2ns(0x7FFFFF, &lapic_clockevent); + lapic_clockevent.min_delta_ns = + clockevent_delta2ns(0xF, &lapic_clockevent); + + calibration_result = (delta * APIC_DIVISOR) / LAPIC_CAL_LOOPS; + + apic_printk(APIC_VERBOSE, "..... delta %ld\n", delta); + apic_printk(APIC_VERBOSE, "..... mult: %ld\n", lapic_clockevent.mult); + apic_printk(APIC_VERBOSE, "..... calibration result: %u\n", + calibration_result); + + if (cpu_has_tsc) { + apic_printk(APIC_VERBOSE, "..... CPU clock speed is " + "%ld.%04ld MHz.\n", + (deltatsc / LAPIC_CAL_LOOPS) / (1000000 / HZ), + (deltatsc / LAPIC_CAL_LOOPS) % (1000000 / HZ)); + } + + apic_printk(APIC_VERBOSE, "..... host bus clock speed is " + "%u.%04u MHz.\n", + calibration_result / (1000000 / HZ), + calibration_result % (1000000 / HZ)); + + /* + * Do a sanity check on the APIC calibration result + */ + if (calibration_result < (1000000 / HZ)) { + local_irq_enable(); + pr_warning("APIC frequency too slow, disabling apic timer\n"); + return -1; + } + + levt->features &= ~CLOCK_EVT_FEAT_DUMMY; + + /* + * PM timer calibration failed or not turned on + * so lets try APIC timer based calibration + */ + if (!pm_referenced) { + apic_printk(APIC_VERBOSE, "... verify APIC timer\n"); + + /* + * Setup the apic timer manually + */ + levt->event_handler = lapic_cal_handler; + lapic_timer_setup(CLOCK_EVT_MODE_PERIODIC, levt); + lapic_cal_loops = -1; + + /* Let the interrupts run */ + local_irq_enable(); + + while (lapic_cal_loops <= LAPIC_CAL_LOOPS) + cpu_relax(); + + /* Stop the lapic timer */ + lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, levt); + + /* Jiffies delta */ + deltaj = lapic_cal_j2 - lapic_cal_j1; + apic_printk(APIC_VERBOSE, "... jiffies delta = %lu\n", deltaj); + + /* Check, if the jiffies result is consistent */ + if (deltaj >= LAPIC_CAL_LOOPS-2 && deltaj <= LAPIC_CAL_LOOPS+2) + apic_printk(APIC_VERBOSE, "... jiffies result ok\n"); + else + levt->features |= CLOCK_EVT_FEAT_DUMMY; + } else + local_irq_enable(); + + if (levt->features & CLOCK_EVT_FEAT_DUMMY) { + pr_warning("APIC timer disabled due to verification failure\n"); + return -1; + } + + return 0; +} + +/* + * Setup the boot APIC + * + * Calibrate and verify the result. + */ +void __init setup_boot_APIC_clock(void) +{ + /* + * The local apic timer can be disabled via the kernel + * commandline or from the CPU detection code. Register the lapic + * timer as a dummy clock event source on SMP systems, so the + * broadcast mechanism is used. On UP systems simply ignore it. + */ + if (disable_apic_timer) { + pr_info("Disabling APIC timer\n"); + /* No broadcast on UP ! */ + if (num_possible_cpus() > 1) { + lapic_clockevent.mult = 1; + setup_APIC_timer(); + } + return; + } + + apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n" + "calibrating APIC timer ...\n"); + + if (calibrate_APIC_clock()) { + /* No broadcast on UP ! */ + if (num_possible_cpus() > 1) + setup_APIC_timer(); + return; + } + + /* + * If nmi_watchdog is set to IO_APIC, we need the + * PIT/HPET going. Otherwise register lapic as a dummy + * device. + */ + if (nmi_watchdog != NMI_IO_APIC) + lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY; + else + pr_warning("APIC timer registered as dummy," + " due to nmi_watchdog=%d!\n", nmi_watchdog); + + /* Setup the lapic or request the broadcast */ + setup_APIC_timer(); +} + +void __cpuinit setup_secondary_APIC_clock(void) +{ + setup_APIC_timer(); +} + +/* + * The guts of the apic timer interrupt + */ +static void local_apic_timer_interrupt(void) +{ + int cpu = smp_processor_id(); + struct clock_event_device *evt = &per_cpu(lapic_events, cpu); + + /* + * Normally we should not be here till LAPIC has been initialized but + * in some cases like kdump, its possible that there is a pending LAPIC + * timer interrupt from previous kernel's context and is delivered in + * new kernel the moment interrupts are enabled. + * + * Interrupts are enabled early and LAPIC is setup much later, hence + * its possible that when we get here evt->event_handler is NULL. + * Check for event_handler being NULL and discard the interrupt as + * spurious. + */ + if (!evt->event_handler) { + pr_warning("Spurious LAPIC timer interrupt on cpu %d\n", cpu); + /* Switch it off */ + lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, evt); + return; + } + + /* + * the NMI deadlock-detector uses this. + */ + inc_irq_stat(apic_timer_irqs); + + evt->event_handler(evt); +} + +/* + * Local APIC timer interrupt. This is the most natural way for doing + * local interrupts, but local timer interrupts can be emulated by + * broadcast interrupts too. [in case the hw doesn't support APIC timers] + * + * [ if a single-CPU system runs an SMP kernel then we call the local + * interrupt as well. Thus we cannot inline the local irq ... ] + */ +void __irq_entry smp_apic_timer_interrupt(struct pt_regs *regs) +{ + struct pt_regs *old_regs = set_irq_regs(regs); + + /* + * NOTE! We'd better ACK the irq immediately, + * because timer handling can be slow. + */ + ack_APIC_irq(); + /* + * update_process_times() expects us to have done irq_enter(). + * Besides, if we don't timer interrupts ignore the global + * interrupt lock, which is the WrongThing (tm) to do. + */ + exit_idle(); + irq_enter(); + local_apic_timer_interrupt(); + irq_exit(); + + set_irq_regs(old_regs); +} + +int setup_profiling_timer(unsigned int multiplier) +{ + return -EINVAL; +} + +/* + * Local APIC start and shutdown + */ + +/** + * clear_local_APIC - shutdown the local APIC + * + * This is called, when a CPU is disabled and before rebooting, so the state of + * the local APIC has no dangling leftovers. Also used to cleanout any BIOS + * leftovers during boot. + */ +void clear_local_APIC(void) +{ + int maxlvt; + u32 v; + + /* APIC hasn't been mapped yet */ + if (!apic_phys) + return; + + maxlvt = lapic_get_maxlvt(); + /* + * Masking an LVT entry can trigger a local APIC error + * if the vector is zero. Mask LVTERR first to prevent this. + */ + if (maxlvt >= 3) { + v = ERROR_APIC_VECTOR; /* any non-zero vector will do */ + apic_write(APIC_LVTERR, v | APIC_LVT_MASKED); + } + /* + * Careful: we have to set masks only first to deassert + * any level-triggered sources. + */ + v = apic_read(APIC_LVTT); + apic_write(APIC_LVTT, v | APIC_LVT_MASKED); + v = apic_read(APIC_LVT0); + apic_write(APIC_LVT0, v | APIC_LVT_MASKED); + v = apic_read(APIC_LVT1); + apic_write(APIC_LVT1, v | APIC_LVT_MASKED); + if (maxlvt >= 4) { + v = apic_read(APIC_LVTPC); + apic_write(APIC_LVTPC, v | APIC_LVT_MASKED); + } + + /* lets not touch this if we didn't frob it */ +#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(X86_MCE_INTEL) + if (maxlvt >= 5) { + v = apic_read(APIC_LVTTHMR); + apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED); + } +#endif + /* + * Clean APIC state for other OSs: + */ + apic_write(APIC_LVTT, APIC_LVT_MASKED); + apic_write(APIC_LVT0, APIC_LVT_MASKED); + apic_write(APIC_LVT1, APIC_LVT_MASKED); + if (maxlvt >= 3) + apic_write(APIC_LVTERR, APIC_LVT_MASKED); + if (maxlvt >= 4) + apic_write(APIC_LVTPC, APIC_LVT_MASKED); + + /* Integrated APIC (!82489DX) ? */ + if (lapic_is_integrated()) { + if (maxlvt > 3) + /* Clear ESR due to Pentium errata 3AP and 11AP */ + apic_write(APIC_ESR, 0); + apic_read(APIC_ESR); + } +} + +/** + * disable_local_APIC - clear and disable the local APIC + */ +void disable_local_APIC(void) +{ + unsigned int value; + + /* APIC hasn't been mapped yet */ + if (!apic_phys) + return; + + clear_local_APIC(); + + /* + * Disable APIC (implies clearing of registers + * for 82489DX!). + */ + value = apic_read(APIC_SPIV); + value &= ~APIC_SPIV_APIC_ENABLED; + apic_write(APIC_SPIV, value); + +#ifdef CONFIG_X86_32 + /* + * When LAPIC was disabled by the BIOS and enabled by the kernel, + * restore the disabled state. + */ + if (enabled_via_apicbase) { + unsigned int l, h; + + rdmsr(MSR_IA32_APICBASE, l, h); + l &= ~MSR_IA32_APICBASE_ENABLE; + wrmsr(MSR_IA32_APICBASE, l, h); + } +#endif +} + +/* + * If Linux enabled the LAPIC against the BIOS default disable it down before + * re-entering the BIOS on shutdown. Otherwise the BIOS may get confused and + * not power-off. Additionally clear all LVT entries before disable_local_APIC + * for the case where Linux didn't enable the LAPIC. + */ +void lapic_shutdown(void) +{ + unsigned long flags; + + if (!cpu_has_apic) + return; + + local_irq_save(flags); + +#ifdef CONFIG_X86_32 + if (!enabled_via_apicbase) + clear_local_APIC(); + else +#endif + disable_local_APIC(); + + + local_irq_restore(flags); +} + +/* + * This is to verify that we're looking at a real local APIC. + * Check these against your board if the CPUs aren't getting + * started for no apparent reason. + */ +int __init verify_local_APIC(void) +{ + unsigned int reg0, reg1; + + /* + * The version register is read-only in a real APIC. + */ + reg0 = apic_read(APIC_LVR); + apic_printk(APIC_DEBUG, "Getting VERSION: %x\n", reg0); + apic_write(APIC_LVR, reg0 ^ APIC_LVR_MASK); + reg1 = apic_read(APIC_LVR); + apic_printk(APIC_DEBUG, "Getting VERSION: %x\n", reg1); + + /* + * The two version reads above should print the same + * numbers. If the second one is different, then we + * poke at a non-APIC. + */ + if (reg1 != reg0) + return 0; + + /* + * Check if the version looks reasonably. + */ + reg1 = GET_APIC_VERSION(reg0); + if (reg1 == 0x00 || reg1 == 0xff) + return 0; + reg1 = lapic_get_maxlvt(); + if (reg1 < 0x02 || reg1 == 0xff) + return 0; + + /* + * The ID register is read/write in a real APIC. + */ + reg0 = apic_read(APIC_ID); + apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg0); + apic_write(APIC_ID, reg0 ^ apic->apic_id_mask); + reg1 = apic_read(APIC_ID); + apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg1); + apic_write(APIC_ID, reg0); + if (reg1 != (reg0 ^ apic->apic_id_mask)) + return 0; + + /* + * The next two are just to see if we have sane values. + * They're only really relevant if we're in Virtual Wire + * compatibility mode, but most boxes are anymore. + */ + reg0 = apic_read(APIC_LVT0); + apic_printk(APIC_DEBUG, "Getting LVT0: %x\n", reg0); + reg1 = apic_read(APIC_LVT1); + apic_printk(APIC_DEBUG, "Getting LVT1: %x\n", reg1); + + return 1; +} + +/** + * sync_Arb_IDs - synchronize APIC bus arbitration IDs + */ +void __init sync_Arb_IDs(void) +{ + /* + * Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 And not + * needed on AMD. + */ + if (modern_apic() || boot_cpu_data.x86_vendor == X86_VENDOR_AMD) + return; + + /* + * Wait for idle. + */ + apic_wait_icr_idle(); + + apic_printk(APIC_DEBUG, "Synchronizing Arb IDs.\n"); + apic_write(APIC_ICR, APIC_DEST_ALLINC | + APIC_INT_LEVELTRIG | APIC_DM_INIT); +} + +/* + * An initial setup of the virtual wire mode. + */ +void __init init_bsp_APIC(void) +{ + unsigned int value; + + /* + * Don't do the setup now if we have a SMP BIOS as the + * through-I/O-APIC virtual wire mode might be active. + */ + if (smp_found_config || !cpu_has_apic) + return; + + /* + * Do not trust the local APIC being empty at bootup. + */ + clear_local_APIC(); + + /* + * Enable APIC. + */ + value = apic_read(APIC_SPIV); + value &= ~APIC_VECTOR_MASK; + value |= APIC_SPIV_APIC_ENABLED; + +#ifdef CONFIG_X86_32 + /* This bit is reserved on P4/Xeon and should be cleared */ + if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && + (boot_cpu_data.x86 == 15)) + value &= ~APIC_SPIV_FOCUS_DISABLED; + else +#endif + value |= APIC_SPIV_FOCUS_DISABLED; + value |= SPURIOUS_APIC_VECTOR; + apic_write(APIC_SPIV, value); + + /* + * Set up the virtual wire mode. + */ + apic_write(APIC_LVT0, APIC_DM_EXTINT); + value = APIC_DM_NMI; + if (!lapic_is_integrated()) /* 82489DX */ + value |= APIC_LVT_LEVEL_TRIGGER; + apic_write(APIC_LVT1, value); +} + +static void __cpuinit lapic_setup_esr(void) +{ + unsigned int oldvalue, value, maxlvt; + + if (!lapic_is_integrated()) { + pr_info("No ESR for 82489DX.\n"); + return; + } + + if (apic->disable_esr) { + /* + * Something untraceable is creating bad interrupts on + * secondary quads ... for the moment, just leave the + * ESR disabled - we can't do anything useful with the + * errors anyway - mbligh + */ + pr_info("Leaving ESR disabled.\n"); + return; + } + + maxlvt = lapic_get_maxlvt(); + if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ + apic_write(APIC_ESR, 0); + oldvalue = apic_read(APIC_ESR); + + /* enables sending errors */ + value = ERROR_APIC_VECTOR; + apic_write(APIC_LVTERR, value); + + /* + * spec says clear errors after enabling vector. + */ + if (maxlvt > 3) + apic_write(APIC_ESR, 0); + value = apic_read(APIC_ESR); + if (value != oldvalue) + apic_printk(APIC_VERBOSE, "ESR value before enabling " + "vector: 0x%08x after: 0x%08x\n", + oldvalue, value); +} + + +/** + * setup_local_APIC - setup the local APIC + */ +void __cpuinit setup_local_APIC(void) +{ + unsigned int value; + int i, j; + + if (disable_apic) { + arch_disable_smp_support(); + return; + } + +#ifdef CONFIG_X86_32 + /* Pound the ESR really hard over the head with a big hammer - mbligh */ + if (lapic_is_integrated() && apic->disable_esr) { + apic_write(APIC_ESR, 0); + apic_write(APIC_ESR, 0); + apic_write(APIC_ESR, 0); + apic_write(APIC_ESR, 0); + } +#endif + + preempt_disable(); + + /* + * Double-check whether this APIC is really registered. + * This is meaningless in clustered apic mode, so we skip it. + */ + if (!apic->apic_id_registered()) + BUG(); + + /* + * Intel recommends to set DFR, LDR and TPR before enabling + * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel + * document number 292116). So here it goes... + */ + apic->init_apic_ldr(); + + /* + * Set Task Priority to 'accept all'. We never change this + * later on. + */ + value = apic_read(APIC_TASKPRI); + value &= ~APIC_TPRI_MASK; + apic_write(APIC_TASKPRI, value); + + /* + * After a crash, we no longer service the interrupts and a pending + * interrupt from previous kernel might still have ISR bit set. + * + * Most probably by now CPU has serviced that pending interrupt and + * it might not have done the ack_APIC_irq() because it thought, + * interrupt came from i8259 as ExtInt. LAPIC did not get EOI so it + * does not clear the ISR bit and cpu thinks it has already serivced + * the interrupt. Hence a vector might get locked. It was noticed + * for timer irq (vector 0x31). Issue an extra EOI to clear ISR. + */ + for (i = APIC_ISR_NR - 1; i >= 0; i--) { + value = apic_read(APIC_ISR + i*0x10); + for (j = 31; j >= 0; j--) { + if (value & (1< 1) || + (boot_cpu_data.x86 >= 15)) + break; + goto no_apic; + case X86_VENDOR_INTEL: + if (boot_cpu_data.x86 == 6 || boot_cpu_data.x86 == 15 || + (boot_cpu_data.x86 == 5 && cpu_has_apic)) + break; + goto no_apic; + default: + goto no_apic; + } + + if (!cpu_has_apic) { + /* + * Over-ride BIOS and try to enable the local APIC only if + * "lapic" specified. + */ + if (!force_enable_local_apic) { + pr_info("Local APIC disabled by BIOS -- " + "you can enable it with \"lapic\"\n"); + return -1; + } + /* + * Some BIOSes disable the local APIC in the APIC_BASE + * MSR. This can only be done in software for Intel P6 or later + * and AMD K7 (Model > 1) or later. + */ + rdmsr(MSR_IA32_APICBASE, l, h); + if (!(l & MSR_IA32_APICBASE_ENABLE)) { + pr_info("Local APIC disabled by BIOS -- reenabling.\n"); + l &= ~MSR_IA32_APICBASE_BASE; + l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE; + wrmsr(MSR_IA32_APICBASE, l, h); + enabled_via_apicbase = 1; + } + } + /* + * The APIC feature bit should now be enabled + * in `cpuid' + */ + features = cpuid_edx(1); + if (!(features & (1 << X86_FEATURE_APIC))) { + pr_warning("Could not enable APIC!\n"); + return -1; + } + set_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC); + mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; + + /* The BIOS may have set up the APIC at some other address */ + rdmsr(MSR_IA32_APICBASE, l, h); + if (l & MSR_IA32_APICBASE_ENABLE) + mp_lapic_addr = l & MSR_IA32_APICBASE_BASE; + + pr_info("Found and enabled local APIC!\n"); + + apic_pm_activate(); + + return 0; + +no_apic: + pr_info("No local APIC present or hardware disabled\n"); + return -1; +} +#endif + +#ifdef CONFIG_X86_64 +void __init early_init_lapic_mapping(void) +{ + unsigned long phys_addr; + + /* + * If no local APIC can be found then go out + * : it means there is no mpatable and MADT + */ + if (!smp_found_config) + return; + + phys_addr = mp_lapic_addr; + + set_fixmap_nocache(FIX_APIC_BASE, phys_addr); + apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n", + APIC_BASE, phys_addr); + + /* + * Fetch the APIC ID of the BSP in case we have a + * default configuration (or the MP table is broken). + */ + boot_cpu_physical_apicid = read_apic_id(); +} +#endif + +/** + * init_apic_mappings - initialize APIC mappings + */ +void __init init_apic_mappings(void) +{ +#ifdef CONFIG_X86_X2APIC + if (x2apic) { + boot_cpu_physical_apicid = read_apic_id(); + return; + } +#endif + + /* + * If no local APIC can be found then set up a fake all + * zeroes page to simulate the local APIC and another + * one for the IO-APIC. + */ + if (!smp_found_config && detect_init_APIC()) { + apic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE); + apic_phys = __pa(apic_phys); + } else + apic_phys = mp_lapic_addr; + + set_fixmap_nocache(FIX_APIC_BASE, apic_phys); + apic_printk(APIC_VERBOSE, "mapped APIC to %08lx (%08lx)\n", + APIC_BASE, apic_phys); + + /* + * Fetch the APIC ID of the BSP in case we have a + * default configuration (or the MP table is broken). + */ + if (boot_cpu_physical_apicid == -1U) + boot_cpu_physical_apicid = read_apic_id(); +} + +/* + * This initializes the IO-APIC and APIC hardware if this is + * a UP kernel. + */ +int apic_version[MAX_APICS]; + +int __init APIC_init_uniprocessor(void) +{ + if (disable_apic) { + pr_info("Apic disabled\n"); + return -1; + } +#ifdef CONFIG_X86_64 + if (!cpu_has_apic) { + disable_apic = 1; + pr_info("Apic disabled by BIOS\n"); + return -1; + } +#else + if (!smp_found_config && !cpu_has_apic) + return -1; + + /* + * Complain if the BIOS pretends there is one. + */ + if (!cpu_has_apic && + APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { + pr_err("BIOS bug, local APIC 0x%x not detected!...\n", + boot_cpu_physical_apicid); + clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC); + return -1; + } +#endif + + enable_IR_x2apic(); +#ifdef CONFIG_X86_64 + default_setup_apic_routing(); +#endif + + verify_local_APIC(); + connect_bsp_APIC(); + +#ifdef CONFIG_X86_64 + apic_write(APIC_ID, SET_APIC_ID(boot_cpu_physical_apicid)); +#else + /* + * Hack: In case of kdump, after a crash, kernel might be booting + * on a cpu with non-zero lapic id. But boot_cpu_physical_apicid + * might be zero if read from MP tables. Get it from LAPIC. + */ +# ifdef CONFIG_CRASH_DUMP + boot_cpu_physical_apicid = read_apic_id(); +# endif +#endif + physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map); + setup_local_APIC(); + +#ifdef CONFIG_X86_IO_APIC + /* + * Now enable IO-APICs, actually call clear_IO_APIC + * We need clear_IO_APIC before enabling error vector + */ + if (!skip_ioapic_setup && nr_ioapics) + enable_IO_APIC(); +#endif + + end_local_APIC_setup(); + +#ifdef CONFIG_X86_IO_APIC + if (smp_found_config && !skip_ioapic_setup && nr_ioapics) + setup_IO_APIC(); + else { + nr_ioapics = 0; + localise_nmi_watchdog(); + } +#else + localise_nmi_watchdog(); +#endif + + setup_boot_clock(); +#ifdef CONFIG_X86_64 + check_nmi_watchdog(); +#endif + + return 0; +} + +/* + * Local APIC interrupts + */ + +/* + * This interrupt should _never_ happen with our APIC/SMP architecture + */ +void smp_spurious_interrupt(struct pt_regs *regs) +{ + u32 v; + + exit_idle(); + irq_enter(); + /* + * Check if this really is a spurious interrupt and ACK it + * if it is a vectored one. Just in case... + * Spurious interrupts should not be ACKed. + */ + v = apic_read(APIC_ISR + ((SPURIOUS_APIC_VECTOR & ~0x1f) >> 1)); + if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f))) + ack_APIC_irq(); + + inc_irq_stat(irq_spurious_count); + + /* see sw-dev-man vol 3, chapter 7.4.13.5 */ + pr_info("spurious APIC interrupt on CPU#%d, " + "should never happen.\n", smp_processor_id()); + irq_exit(); +} + +/* + * This interrupt should never happen with our APIC/SMP architecture + */ +void smp_error_interrupt(struct pt_regs *regs) +{ + u32 v, v1; + + exit_idle(); + irq_enter(); + /* First tickle the hardware, only then report what went on. -- REW */ + v = apic_read(APIC_ESR); + apic_write(APIC_ESR, 0); + v1 = apic_read(APIC_ESR); + ack_APIC_irq(); + atomic_inc(&irq_err_count); + + /* + * Here is what the APIC error bits mean: + * 0: Send CS error + * 1: Receive CS error + * 2: Send accept error + * 3: Receive accept error + * 4: Reserved + * 5: Send illegal vector + * 6: Received illegal vector + * 7: Illegal register address + */ + pr_debug("APIC error on CPU%d: %02x(%02x)\n", + smp_processor_id(), v , v1); + irq_exit(); +} + +/** + * connect_bsp_APIC - attach the APIC to the interrupt system + */ +void __init connect_bsp_APIC(void) +{ +#ifdef CONFIG_X86_32 + if (pic_mode) { + /* + * Do not trust the local APIC being empty at bootup. + */ + clear_local_APIC(); + /* + * PIC mode, enable APIC mode in the IMCR, i.e. connect BSP's + * local APIC to INT and NMI lines. + */ + apic_printk(APIC_VERBOSE, "leaving PIC mode, " + "enabling APIC mode.\n"); + outb(0x70, 0x22); + outb(0x01, 0x23); + } +#endif + if (apic->enable_apic_mode) + apic->enable_apic_mode(); +} + +/** + * disconnect_bsp_APIC - detach the APIC from the interrupt system + * @virt_wire_setup: indicates, whether virtual wire mode is selected + * + * Virtual wire mode is necessary to deliver legacy interrupts even when the + * APIC is disabled. + */ +void disconnect_bsp_APIC(int virt_wire_setup) +{ + unsigned int value; + +#ifdef CONFIG_X86_32 + if (pic_mode) { + /* + * Put the board back into PIC mode (has an effect only on + * certain older boards). Note that APIC interrupts, including + * IPIs, won't work beyond this point! The only exception are + * INIT IPIs. + */ + apic_printk(APIC_VERBOSE, "disabling APIC mode, " + "entering PIC mode.\n"); + outb(0x70, 0x22); + outb(0x00, 0x23); + return; + } +#endif + + /* Go back to Virtual Wire compatibility mode */ + + /* For the spurious interrupt use vector F, and enable it */ + value = apic_read(APIC_SPIV); + value &= ~APIC_VECTOR_MASK; + value |= APIC_SPIV_APIC_ENABLED; + value |= 0xf; + apic_write(APIC_SPIV, value); + + if (!virt_wire_setup) { + /* + * For LVT0 make it edge triggered, active high, + * external and enabled + */ + value = apic_read(APIC_LVT0); + value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING | + APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | + APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED); + value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; + value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT); + apic_write(APIC_LVT0, value); + } else { + /* Disable LVT0 */ + apic_write(APIC_LVT0, APIC_LVT_MASKED); + } + + /* + * For LVT1 make it edge triggered, active high, + * nmi and enabled + */ + value = apic_read(APIC_LVT1); + value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING | + APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | + APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED); + value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; + value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI); + apic_write(APIC_LVT1, value); +} + +void __cpuinit generic_processor_info(int apicid, int version) +{ + int cpu; + + /* + * Validate version + */ + if (version == 0x0) { + pr_warning("BIOS bug, APIC version is 0 for CPU#%d! " + "fixing up to 0x10. (tell your hw vendor)\n", + version); + version = 0x10; + } + apic_version[apicid] = version; + + if (num_processors >= nr_cpu_ids) { + int max = nr_cpu_ids; + int thiscpu = max + disabled_cpus; + + pr_warning( + "ACPI: NR_CPUS/possible_cpus limit of %i reached." + " Processor %d/0x%x ignored.\n", max, thiscpu, apicid); + + disabled_cpus++; + return; + } + + num_processors++; + cpu = cpumask_next_zero(-1, cpu_present_mask); + + if (version != apic_version[boot_cpu_physical_apicid]) + WARN_ONCE(1, + "ACPI: apic version mismatch, bootcpu: %x cpu %d: %x\n", + apic_version[boot_cpu_physical_apicid], cpu, version); + + physid_set(apicid, phys_cpu_present_map); + if (apicid == boot_cpu_physical_apicid) { + /* + * x86_bios_cpu_apicid is required to have processors listed + * in same order as logical cpu numbers. Hence the first + * entry is BSP, and so on. + */ + cpu = 0; + } + if (apicid > max_physical_apicid) + max_physical_apicid = apicid; + +#ifdef CONFIG_X86_32 + /* + * Would be preferable to switch to bigsmp when CONFIG_HOTPLUG_CPU=y + * but we need to work other dependencies like SMP_SUSPEND etc + * before this can be done without some confusion. + * if (CPU_HOTPLUG_ENABLED || num_processors > 8) + * - Ashok Raj + */ + if (max_physical_apicid >= 8) { + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_INTEL: + if (!APIC_XAPIC(version)) { + def_to_bigsmp = 0; + break; + } + /* If P4 and above fall through */ + case X86_VENDOR_AMD: + def_to_bigsmp = 1; + } + } +#endif + +#if defined(CONFIG_SMP) || defined(CONFIG_X86_64) + early_per_cpu(x86_cpu_to_apicid, cpu) = apicid; + early_per_cpu(x86_bios_cpu_apicid, cpu) = apicid; +#endif + + set_cpu_possible(cpu, true); + set_cpu_present(cpu, true); +} + +int hard_smp_processor_id(void) +{ + return read_apic_id(); +} + +void default_init_apic_ldr(void) +{ + unsigned long val; + + apic_write(APIC_DFR, APIC_DFR_VALUE); + val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; + val |= SET_APIC_LOGICAL_ID(1UL << smp_processor_id()); + apic_write(APIC_LDR, val); +} + +#ifdef CONFIG_X86_32 +int default_apicid_to_node(int logical_apicid) +{ +#ifdef CONFIG_SMP + return apicid_2_node[hard_smp_processor_id()]; +#else + return 0; +#endif +} +#endif + +/* + * Power management + */ +#ifdef CONFIG_PM + +static struct { + /* + * 'active' is true if the local APIC was enabled by us and + * not the BIOS; this signifies that we are also responsible + * for disabling it before entering apm/acpi suspend + */ + int active; + /* r/w apic fields */ + unsigned int apic_id; + unsigned int apic_taskpri; + unsigned int apic_ldr; + unsigned int apic_dfr; + unsigned int apic_spiv; + unsigned int apic_lvtt; + unsigned int apic_lvtpc; + unsigned int apic_lvt0; + unsigned int apic_lvt1; + unsigned int apic_lvterr; + unsigned int apic_tmict; + unsigned int apic_tdcr; + unsigned int apic_thmr; +} apic_pm_state; + +static int lapic_suspend(struct sys_device *dev, pm_message_t state) +{ + unsigned long flags; + int maxlvt; + + if (!apic_pm_state.active) + return 0; + + maxlvt = lapic_get_maxlvt(); + + apic_pm_state.apic_id = apic_read(APIC_ID); + apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI); + apic_pm_state.apic_ldr = apic_read(APIC_LDR); + apic_pm_state.apic_dfr = apic_read(APIC_DFR); + apic_pm_state.apic_spiv = apic_read(APIC_SPIV); + apic_pm_state.apic_lvtt = apic_read(APIC_LVTT); + if (maxlvt >= 4) + apic_pm_state.apic_lvtpc = apic_read(APIC_LVTPC); + apic_pm_state.apic_lvt0 = apic_read(APIC_LVT0); + apic_pm_state.apic_lvt1 = apic_read(APIC_LVT1); + apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR); + apic_pm_state.apic_tmict = apic_read(APIC_TMICT); + apic_pm_state.apic_tdcr = apic_read(APIC_TDCR); +#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL) + if (maxlvt >= 5) + apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); +#endif + + local_irq_save(flags); + disable_local_APIC(); + local_irq_restore(flags); + return 0; +} + +static int lapic_resume(struct sys_device *dev) +{ + unsigned int l, h; + unsigned long flags; + int maxlvt; + + if (!apic_pm_state.active) + return 0; + + maxlvt = lapic_get_maxlvt(); + + local_irq_save(flags); + +#ifdef CONFIG_X86_X2APIC + if (x2apic) + enable_x2apic(); + else +#endif + { + /* + * Make sure the APICBASE points to the right address + * + * FIXME! This will be wrong if we ever support suspend on + * SMP! We'll need to do this as part of the CPU restore! + */ + rdmsr(MSR_IA32_APICBASE, l, h); + l &= ~MSR_IA32_APICBASE_BASE; + l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr; + wrmsr(MSR_IA32_APICBASE, l, h); + } + + apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED); + apic_write(APIC_ID, apic_pm_state.apic_id); + apic_write(APIC_DFR, apic_pm_state.apic_dfr); + apic_write(APIC_LDR, apic_pm_state.apic_ldr); + apic_write(APIC_TASKPRI, apic_pm_state.apic_taskpri); + apic_write(APIC_SPIV, apic_pm_state.apic_spiv); + apic_write(APIC_LVT0, apic_pm_state.apic_lvt0); + apic_write(APIC_LVT1, apic_pm_state.apic_lvt1); +#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL) + if (maxlvt >= 5) + apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr); +#endif + if (maxlvt >= 4) + apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc); + apic_write(APIC_LVTT, apic_pm_state.apic_lvtt); + apic_write(APIC_TDCR, apic_pm_state.apic_tdcr); + apic_write(APIC_TMICT, apic_pm_state.apic_tmict); + apic_write(APIC_ESR, 0); + apic_read(APIC_ESR); + apic_write(APIC_LVTERR, apic_pm_state.apic_lvterr); + apic_write(APIC_ESR, 0); + apic_read(APIC_ESR); + + local_irq_restore(flags); + + return 0; +} + +/* + * This device has no shutdown method - fully functioning local APICs + * are needed on every CPU up until machine_halt/restart/poweroff. + */ + +static struct sysdev_class lapic_sysclass = { + .name = "lapic", + .resume = lapic_resume, + .suspend = lapic_suspend, +}; + +static struct sys_device device_lapic = { + .id = 0, + .cls = &lapic_sysclass, +}; + +static void __cpuinit apic_pm_activate(void) +{ + apic_pm_state.active = 1; +} + +static int __init init_lapic_sysfs(void) +{ + int error; + + if (!cpu_has_apic) + return 0; + /* XXX: remove suspend/resume procs if !apic_pm_state.active? */ + + error = sysdev_class_register(&lapic_sysclass); + if (!error) + error = sysdev_register(&device_lapic); + return error; +} +device_initcall(init_lapic_sysfs); + +#else /* CONFIG_PM */ + +static void apic_pm_activate(void) { } + +#endif /* CONFIG_PM */ + +#ifdef CONFIG_X86_64 +/* + * apic_is_clustered_box() -- Check if we can expect good TSC + * + * Thus far, the major user of this is IBM's Summit2 series: + * + * Clustered boxes may have unsynced TSC problems if they are + * multi-chassis. Use available data to take a good guess. + * If in doubt, go HPET. + */ +__cpuinit int apic_is_clustered_box(void) +{ + int i, clusters, zeros; + unsigned id; + u16 *bios_cpu_apicid; + DECLARE_BITMAP(clustermap, NUM_APIC_CLUSTERS); + + /* + * there is not this kind of box with AMD CPU yet. + * Some AMD box with quadcore cpu and 8 sockets apicid + * will be [4, 0x23] or [8, 0x27] could be thought to + * vsmp box still need checking... + */ + if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && !is_vsmp_box()) + return 0; + + bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid); + bitmap_zero(clustermap, NUM_APIC_CLUSTERS); + + for (i = 0; i < nr_cpu_ids; i++) { + /* are we being called early in kernel startup? */ + if (bios_cpu_apicid) { + id = bios_cpu_apicid[i]; + } else if (i < nr_cpu_ids) { + if (cpu_present(i)) + id = per_cpu(x86_bios_cpu_apicid, i); + else + continue; + } else + break; + + if (id != BAD_APICID) + __set_bit(APIC_CLUSTERID(id), clustermap); + } + + /* Problem: Partially populated chassis may not have CPUs in some of + * the APIC clusters they have been allocated. Only present CPUs have + * x86_bios_cpu_apicid entries, thus causing zeroes in the bitmap. + * Since clusters are allocated sequentially, count zeros only if + * they are bounded by ones. + */ + clusters = 0; + zeros = 0; + for (i = 0; i < NUM_APIC_CLUSTERS; i++) { + if (test_bit(i, clustermap)) { + clusters += 1 + zeros; + zeros = 0; + } else + ++zeros; + } + + /* ScaleMP vSMPowered boxes have one cluster per board and TSCs are + * not guaranteed to be synced between boards + */ + if (is_vsmp_box() && clusters > 1) + return 1; + + /* + * If clusters > 2, then should be multi-chassis. + * May have to revisit this when multi-core + hyperthreaded CPUs come + * out, but AFAIK this will work even for them. + */ + return (clusters > 2); +} +#endif + +/* + * APIC command line parameters + */ +static int __init setup_disableapic(char *arg) +{ + disable_apic = 1; + setup_clear_cpu_cap(X86_FEATURE_APIC); + return 0; +} +early_param("disableapic", setup_disableapic); + +/* same as disableapic, for compatibility */ +static int __init setup_nolapic(char *arg) +{ + return setup_disableapic(arg); +} +early_param("nolapic", setup_nolapic); + +static int __init parse_lapic_timer_c2_ok(char *arg) +{ + local_apic_timer_c2_ok = 1; + return 0; +} +early_param("lapic_timer_c2_ok", parse_lapic_timer_c2_ok); + +static int __init parse_disable_apic_timer(char *arg) +{ + disable_apic_timer = 1; + return 0; +} +early_param("noapictimer", parse_disable_apic_timer); + +static int __init parse_nolapic_timer(char *arg) +{ + disable_apic_timer = 1; + return 0; +} +early_param("nolapic_timer", parse_nolapic_timer); + +static int __init apic_set_verbosity(char *arg) +{ + if (!arg) { +#ifdef CONFIG_X86_64 + skip_ioapic_setup = 0; + return 0; +#endif + return -EINVAL; + } + + if (strcmp("debug", arg) == 0) + apic_verbosity = APIC_DEBUG; + else if (strcmp("verbose", arg) == 0) + apic_verbosity = APIC_VERBOSE; + else { + pr_warning("APIC Verbosity level %s not recognised" + " use apic=verbose or apic=debug\n", arg); + return -EINVAL; + } + + return 0; +} +early_param("apic", apic_set_verbosity); + +static int __init lapic_insert_resource(void) +{ + if (!apic_phys) + return -1; + + /* Put local APIC into the resource map. */ + lapic_resource.start = apic_phys; + lapic_resource.end = lapic_resource.start + PAGE_SIZE - 1; + insert_resource(&iomem_resource, &lapic_resource); + + return 0; +} + +/* + * need call insert after e820_reserve_resources() + * that is using request_resource + */ +late_initcall(lapic_insert_resource); diff --git a/arch/x86/kernel/apic/apic_64.c b/arch/x86/kernel/apic/apic_64.c new file mode 100644 index 00000000000..70935dd904d --- /dev/null +++ b/arch/x86/kernel/apic/apic_64.c @@ -0,0 +1,89 @@ +/* + * Copyright 2004 James Cleverdon, IBM. + * Subject to the GNU Public License, v.2 + * + * Generic APIC sub-arch probe layer. + * + * Hacked for x86-64 by James Cleverdon from i386 architecture code by + * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and + * James Cleverdon. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +extern struct apic apic_flat; +extern struct apic apic_physflat; +extern struct apic apic_x2xpic_uv_x; +extern struct apic apic_x2apic_phys; +extern struct apic apic_x2apic_cluster; + +struct apic __read_mostly *apic = &apic_flat; +EXPORT_SYMBOL_GPL(apic); + +static struct apic *apic_probe[] __initdata = { +#ifdef CONFIG_X86_UV + &apic_x2apic_uv_x, +#endif +#ifdef CONFIG_X86_X2APIC + &apic_x2apic_phys, + &apic_x2apic_cluster, +#endif + &apic_physflat, + NULL, +}; + +/* + * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. + */ +void __init default_setup_apic_routing(void) +{ +#ifdef CONFIG_X86_X2APIC + if (apic == &apic_x2apic_phys || apic == &apic_x2apic_cluster) { + if (!intr_remapping_enabled) + apic = &apic_flat; + } +#endif + + if (apic == &apic_flat) { + if (max_physical_apicid >= 8) + apic = &apic_physflat; + printk(KERN_INFO "Setting APIC routing to %s\n", apic->name); + } + + if (x86_quirks->update_apic) + x86_quirks->update_apic(); +} + +/* Same for both flat and physical. */ + +void apic_send_IPI_self(int vector) +{ + __default_send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL); +} + +int __init default_acpi_madt_oem_check(char *oem_id, char *oem_table_id) +{ + int i; + + for (i = 0; apic_probe[i]; ++i) { + if (apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id)) { + apic = apic_probe[i]; + printk(KERN_INFO "Setting APIC routing to %s.\n", + apic->name); + return 1; + } + } + return 0; +} diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c new file mode 100644 index 00000000000..3b002995e14 --- /dev/null +++ b/arch/x86/kernel/apic/apic_flat_64.c @@ -0,0 +1,389 @@ +/* + * Copyright 2004 James Cleverdon, IBM. + * Subject to the GNU Public License, v.2 + * + * Flat APIC subarch code. + * + * Hacked for x86-64 by James Cleverdon from i386 architecture code by + * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and + * James Cleverdon. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_ACPI +#include +#endif + +static int flat_acpi_madt_oem_check(char *oem_id, char *oem_table_id) +{ + return 1; +} + +static const struct cpumask *flat_target_cpus(void) +{ + return cpu_online_mask; +} + +static void flat_vector_allocation_domain(int cpu, struct cpumask *retmask) +{ + /* Careful. Some cpus do not strictly honor the set of cpus + * specified in the interrupt destination when using lowest + * priority interrupt delivery mode. + * + * In particular there was a hyperthreading cpu observed to + * deliver interrupts to the wrong hyperthread when only one + * hyperthread was specified in the interrupt desitination. + */ + cpumask_clear(retmask); + cpumask_bits(retmask)[0] = APIC_ALL_CPUS; +} + +/* + * Set up the logical destination ID. + * + * Intel recommends to set DFR, LDR and TPR before enabling + * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel + * document number 292116). So here it goes... + */ +static void flat_init_apic_ldr(void) +{ + unsigned long val; + unsigned long num, id; + + num = smp_processor_id(); + id = 1UL << num; + apic_write(APIC_DFR, APIC_DFR_FLAT); + val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; + val |= SET_APIC_LOGICAL_ID(id); + apic_write(APIC_LDR, val); +} + +static inline void _flat_send_IPI_mask(unsigned long mask, int vector) +{ + unsigned long flags; + + local_irq_save(flags); + __default_send_IPI_dest_field(mask, vector, apic->dest_logical); + local_irq_restore(flags); +} + +static void flat_send_IPI_mask(const struct cpumask *cpumask, int vector) +{ + unsigned long mask = cpumask_bits(cpumask)[0]; + + _flat_send_IPI_mask(mask, vector); +} + +static void + flat_send_IPI_mask_allbutself(const struct cpumask *cpumask, int vector) +{ + unsigned long mask = cpumask_bits(cpumask)[0]; + int cpu = smp_processor_id(); + + if (cpu < BITS_PER_LONG) + clear_bit(cpu, &mask); + + _flat_send_IPI_mask(mask, vector); +} + +static void flat_send_IPI_allbutself(int vector) +{ + int cpu = smp_processor_id(); +#ifdef CONFIG_HOTPLUG_CPU + int hotplug = 1; +#else + int hotplug = 0; +#endif + if (hotplug || vector == NMI_VECTOR) { + if (!cpumask_equal(cpu_online_mask, cpumask_of(cpu))) { + unsigned long mask = cpumask_bits(cpu_online_mask)[0]; + + if (cpu < BITS_PER_LONG) + clear_bit(cpu, &mask); + + _flat_send_IPI_mask(mask, vector); + } + } else if (num_online_cpus() > 1) { + __default_send_IPI_shortcut(APIC_DEST_ALLBUT, + vector, apic->dest_logical); + } +} + +static void flat_send_IPI_all(int vector) +{ + if (vector == NMI_VECTOR) { + flat_send_IPI_mask(cpu_online_mask, vector); + } else { + __default_send_IPI_shortcut(APIC_DEST_ALLINC, + vector, apic->dest_logical); + } +} + +static unsigned int flat_get_apic_id(unsigned long x) +{ + unsigned int id; + + id = (((x)>>24) & 0xFFu); + + return id; +} + +static unsigned long set_apic_id(unsigned int id) +{ + unsigned long x; + + x = ((id & 0xFFu)<<24); + return x; +} + +static unsigned int read_xapic_id(void) +{ + unsigned int id; + + id = flat_get_apic_id(apic_read(APIC_ID)); + return id; +} + +static int flat_apic_id_registered(void) +{ + return physid_isset(read_xapic_id(), phys_cpu_present_map); +} + +static unsigned int flat_cpu_mask_to_apicid(const struct cpumask *cpumask) +{ + return cpumask_bits(cpumask)[0] & APIC_ALL_CPUS; +} + +static unsigned int flat_cpu_mask_to_apicid_and(const struct cpumask *cpumask, + const struct cpumask *andmask) +{ + unsigned long mask1 = cpumask_bits(cpumask)[0] & APIC_ALL_CPUS; + unsigned long mask2 = cpumask_bits(andmask)[0] & APIC_ALL_CPUS; + + return mask1 & mask2; +} + +static int flat_phys_pkg_id(int initial_apic_id, int index_msb) +{ + return hard_smp_processor_id() >> index_msb; +} + +struct apic apic_flat = { + .name = "flat", + .probe = NULL, + .acpi_madt_oem_check = flat_acpi_madt_oem_check, + .apic_id_registered = flat_apic_id_registered, + + .irq_delivery_mode = dest_LowestPrio, + .irq_dest_mode = 1, /* logical */ + + .target_cpus = flat_target_cpus, + .disable_esr = 0, + .dest_logical = APIC_DEST_LOGICAL, + .check_apicid_used = NULL, + .check_apicid_present = NULL, + + .vector_allocation_domain = flat_vector_allocation_domain, + .init_apic_ldr = flat_init_apic_ldr, + + .ioapic_phys_id_map = NULL, + .setup_apic_routing = NULL, + .multi_timer_check = NULL, + .apicid_to_node = NULL, + .cpu_to_logical_apicid = NULL, + .cpu_present_to_apicid = default_cpu_present_to_apicid, + .apicid_to_cpu_present = NULL, + .setup_portio_remap = NULL, + .check_phys_apicid_present = default_check_phys_apicid_present, + .enable_apic_mode = NULL, + .phys_pkg_id = flat_phys_pkg_id, + .mps_oem_check = NULL, + + .get_apic_id = flat_get_apic_id, + .set_apic_id = set_apic_id, + .apic_id_mask = 0xFFu << 24, + + .cpu_mask_to_apicid = flat_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and, + + .send_IPI_mask = flat_send_IPI_mask, + .send_IPI_mask_allbutself = flat_send_IPI_mask_allbutself, + .send_IPI_allbutself = flat_send_IPI_allbutself, + .send_IPI_all = flat_send_IPI_all, + .send_IPI_self = apic_send_IPI_self, + + .wakeup_cpu = NULL, + .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, + .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, + .wait_for_init_deassert = NULL, + .smp_callin_clear_local_apic = NULL, + .inquire_remote_apic = NULL, + + .read = native_apic_mem_read, + .write = native_apic_mem_write, + .icr_read = native_apic_icr_read, + .icr_write = native_apic_icr_write, + .wait_icr_idle = native_apic_wait_icr_idle, + .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, +}; + +/* + * Physflat mode is used when there are more than 8 CPUs on a AMD system. + * We cannot use logical delivery in this case because the mask + * overflows, so use physical mode. + */ +static int physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id) +{ +#ifdef CONFIG_ACPI + /* + * Quirk: some x86_64 machines can only use physical APIC mode + * regardless of how many processors are present (x86_64 ES7000 + * is an example). + */ + if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID && + (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL)) { + printk(KERN_DEBUG "system APIC only can use physical flat"); + return 1; + } +#endif + + return 0; +} + +static const struct cpumask *physflat_target_cpus(void) +{ + return cpu_online_mask; +} + +static void physflat_vector_allocation_domain(int cpu, struct cpumask *retmask) +{ + cpumask_clear(retmask); + cpumask_set_cpu(cpu, retmask); +} + +static void physflat_send_IPI_mask(const struct cpumask *cpumask, int vector) +{ + default_send_IPI_mask_sequence_phys(cpumask, vector); +} + +static void physflat_send_IPI_mask_allbutself(const struct cpumask *cpumask, + int vector) +{ + default_send_IPI_mask_allbutself_phys(cpumask, vector); +} + +static void physflat_send_IPI_allbutself(int vector) +{ + default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector); +} + +static void physflat_send_IPI_all(int vector) +{ + physflat_send_IPI_mask(cpu_online_mask, vector); +} + +static unsigned int physflat_cpu_mask_to_apicid(const struct cpumask *cpumask) +{ + int cpu; + + /* + * We're using fixed IRQ delivery, can only return one phys APIC ID. + * May as well be the first. + */ + cpu = cpumask_first(cpumask); + if ((unsigned)cpu < nr_cpu_ids) + return per_cpu(x86_cpu_to_apicid, cpu); + else + return BAD_APICID; +} + +static unsigned int +physflat_cpu_mask_to_apicid_and(const struct cpumask *cpumask, + const struct cpumask *andmask) +{ + int cpu; + + /* + * We're using fixed IRQ delivery, can only return one phys APIC ID. + * May as well be the first. + */ + for_each_cpu_and(cpu, cpumask, andmask) { + if (cpumask_test_cpu(cpu, cpu_online_mask)) + break; + } + if (cpu < nr_cpu_ids) + return per_cpu(x86_cpu_to_apicid, cpu); + + return BAD_APICID; +} + +struct apic apic_physflat = { + + .name = "physical flat", + .probe = NULL, + .acpi_madt_oem_check = physflat_acpi_madt_oem_check, + .apic_id_registered = flat_apic_id_registered, + + .irq_delivery_mode = dest_Fixed, + .irq_dest_mode = 0, /* physical */ + + .target_cpus = physflat_target_cpus, + .disable_esr = 0, + .dest_logical = 0, + .check_apicid_used = NULL, + .check_apicid_present = NULL, + + .vector_allocation_domain = physflat_vector_allocation_domain, + /* not needed, but shouldn't hurt: */ + .init_apic_ldr = flat_init_apic_ldr, + + .ioapic_phys_id_map = NULL, + .setup_apic_routing = NULL, + .multi_timer_check = NULL, + .apicid_to_node = NULL, + .cpu_to_logical_apicid = NULL, + .cpu_present_to_apicid = default_cpu_present_to_apicid, + .apicid_to_cpu_present = NULL, + .setup_portio_remap = NULL, + .check_phys_apicid_present = default_check_phys_apicid_present, + .enable_apic_mode = NULL, + .phys_pkg_id = flat_phys_pkg_id, + .mps_oem_check = NULL, + + .get_apic_id = flat_get_apic_id, + .set_apic_id = set_apic_id, + .apic_id_mask = 0xFFu << 24, + + .cpu_mask_to_apicid = physflat_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = physflat_cpu_mask_to_apicid_and, + + .send_IPI_mask = physflat_send_IPI_mask, + .send_IPI_mask_allbutself = physflat_send_IPI_mask_allbutself, + .send_IPI_allbutself = physflat_send_IPI_allbutself, + .send_IPI_all = physflat_send_IPI_all, + .send_IPI_self = apic_send_IPI_self, + + .wakeup_cpu = NULL, + .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, + .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, + .wait_for_init_deassert = NULL, + .smp_callin_clear_local_apic = NULL, + .inquire_remote_apic = NULL, + + .read = native_apic_mem_read, + .write = native_apic_mem_write, + .icr_read = native_apic_icr_read, + .icr_write = native_apic_icr_write, + .wait_icr_idle = native_apic_wait_icr_idle, + .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, +}; diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c new file mode 100644 index 00000000000..00e6071cefc --- /dev/null +++ b/arch/x86/kernel/apic/io_apic.c @@ -0,0 +1,4160 @@ +/* + * Intel IO-APIC support for multi-Pentium hosts. + * + * Copyright (C) 1997, 1998, 1999, 2000, 2009 Ingo Molnar, Hajnalka Szabo + * + * Many thanks to Stig Venaas for trying out countless experimental + * patches and reporting/debugging problems patiently! + * + * (c) 1999, Multiple IO-APIC support, developed by + * Ken-ichi Yaku and + * Hidemi Kishimoto , + * further tested and cleaned up by Zach Brown + * and Ingo Molnar + * + * Fixes + * Maciej W. Rozycki : Bits for genuine 82489DX APICs; + * thanks to Eric Gilmore + * and Rolf G. Tews + * for testing these extensively + * Paul Diefenbaugh : Added full ACPI support + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* time_after() */ +#ifdef CONFIG_ACPI +#include +#endif +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define __apicdebuginit(type) static type __init + +/* + * Is the SiS APIC rmw bug present ? + * -1 = don't know, 0 = no, 1 = yes + */ +int sis_apic_bug = -1; + +static DEFINE_SPINLOCK(ioapic_lock); +static DEFINE_SPINLOCK(vector_lock); + +/* + * # of IRQ routing registers + */ +int nr_ioapic_registers[MAX_IO_APICS]; + +/* I/O APIC entries */ +struct mpc_ioapic mp_ioapics[MAX_IO_APICS]; +int nr_ioapics; + +/* MP IRQ source entries */ +struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES]; + +/* # of MP IRQ source entries */ +int mp_irq_entries; + +#if defined (CONFIG_MCA) || defined (CONFIG_EISA) +int mp_bus_id_to_type[MAX_MP_BUSSES]; +#endif + +DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES); + +int skip_ioapic_setup; + +void arch_disable_smp_support(void) +{ +#ifdef CONFIG_PCI + noioapicquirk = 1; + noioapicreroute = -1; +#endif + skip_ioapic_setup = 1; +} + +static int __init parse_noapic(char *str) +{ + /* disable IO-APIC */ + arch_disable_smp_support(); + return 0; +} +early_param("noapic", parse_noapic); + +struct irq_pin_list; + +/* + * This is performance-critical, we want to do it O(1) + * + * the indexing order of this array favors 1:1 mappings + * between pins and IRQs. + */ + +struct irq_pin_list { + int apic, pin; + struct irq_pin_list *next; +}; + +static struct irq_pin_list *get_one_free_irq_2_pin(int cpu) +{ + struct irq_pin_list *pin; + int node; + + node = cpu_to_node(cpu); + + pin = kzalloc_node(sizeof(*pin), GFP_ATOMIC, node); + + return pin; +} + +struct irq_cfg { + struct irq_pin_list *irq_2_pin; + cpumask_var_t domain; + cpumask_var_t old_domain; + unsigned move_cleanup_count; + u8 vector; + u8 move_in_progress : 1; +#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC + u8 move_desc_pending : 1; +#endif +}; + +/* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */ +#ifdef CONFIG_SPARSE_IRQ +static struct irq_cfg irq_cfgx[] = { +#else +static struct irq_cfg irq_cfgx[NR_IRQS] = { +#endif + [0] = { .vector = IRQ0_VECTOR, }, + [1] = { .vector = IRQ1_VECTOR, }, + [2] = { .vector = IRQ2_VECTOR, }, + [3] = { .vector = IRQ3_VECTOR, }, + [4] = { .vector = IRQ4_VECTOR, }, + [5] = { .vector = IRQ5_VECTOR, }, + [6] = { .vector = IRQ6_VECTOR, }, + [7] = { .vector = IRQ7_VECTOR, }, + [8] = { .vector = IRQ8_VECTOR, }, + [9] = { .vector = IRQ9_VECTOR, }, + [10] = { .vector = IRQ10_VECTOR, }, + [11] = { .vector = IRQ11_VECTOR, }, + [12] = { .vector = IRQ12_VECTOR, }, + [13] = { .vector = IRQ13_VECTOR, }, + [14] = { .vector = IRQ14_VECTOR, }, + [15] = { .vector = IRQ15_VECTOR, }, +}; + +int __init arch_early_irq_init(void) +{ + struct irq_cfg *cfg; + struct irq_desc *desc; + int count; + int i; + + cfg = irq_cfgx; + count = ARRAY_SIZE(irq_cfgx); + + for (i = 0; i < count; i++) { + desc = irq_to_desc(i); + desc->chip_data = &cfg[i]; + alloc_bootmem_cpumask_var(&cfg[i].domain); + alloc_bootmem_cpumask_var(&cfg[i].old_domain); + if (i < NR_IRQS_LEGACY) + cpumask_setall(cfg[i].domain); + } + + return 0; +} + +#ifdef CONFIG_SPARSE_IRQ +static struct irq_cfg *irq_cfg(unsigned int irq) +{ + struct irq_cfg *cfg = NULL; + struct irq_desc *desc; + + desc = irq_to_desc(irq); + if (desc) + cfg = desc->chip_data; + + return cfg; +} + +static struct irq_cfg *get_one_free_irq_cfg(int cpu) +{ + struct irq_cfg *cfg; + int node; + + node = cpu_to_node(cpu); + + cfg = kzalloc_node(sizeof(*cfg), GFP_ATOMIC, node); + if (cfg) { + if (!alloc_cpumask_var_node(&cfg->domain, GFP_ATOMIC, node)) { + kfree(cfg); + cfg = NULL; + } else if (!alloc_cpumask_var_node(&cfg->old_domain, + GFP_ATOMIC, node)) { + free_cpumask_var(cfg->domain); + kfree(cfg); + cfg = NULL; + } else { + cpumask_clear(cfg->domain); + cpumask_clear(cfg->old_domain); + } + } + + return cfg; +} + +int arch_init_chip_data(struct irq_desc *desc, int cpu) +{ + struct irq_cfg *cfg; + + cfg = desc->chip_data; + if (!cfg) { + desc->chip_data = get_one_free_irq_cfg(cpu); + if (!desc->chip_data) { + printk(KERN_ERR "can not alloc irq_cfg\n"); + BUG_ON(1); + } + } + + return 0; +} + +#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC + +static void +init_copy_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg, int cpu) +{ + struct irq_pin_list *old_entry, *head, *tail, *entry; + + cfg->irq_2_pin = NULL; + old_entry = old_cfg->irq_2_pin; + if (!old_entry) + return; + + entry = get_one_free_irq_2_pin(cpu); + if (!entry) + return; + + entry->apic = old_entry->apic; + entry->pin = old_entry->pin; + head = entry; + tail = entry; + old_entry = old_entry->next; + while (old_entry) { + entry = get_one_free_irq_2_pin(cpu); + if (!entry) { + entry = head; + while (entry) { + head = entry->next; + kfree(entry); + entry = head; + } + /* still use the old one */ + return; + } + entry->apic = old_entry->apic; + entry->pin = old_entry->pin; + tail->next = entry; + tail = entry; + old_entry = old_entry->next; + } + + tail->next = NULL; + cfg->irq_2_pin = head; +} + +static void free_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg) +{ + struct irq_pin_list *entry, *next; + + if (old_cfg->irq_2_pin == cfg->irq_2_pin) + return; + + entry = old_cfg->irq_2_pin; + + while (entry) { + next = entry->next; + kfree(entry); + entry = next; + } + old_cfg->irq_2_pin = NULL; +} + +void arch_init_copy_chip_data(struct irq_desc *old_desc, + struct irq_desc *desc, int cpu) +{ + struct irq_cfg *cfg; + struct irq_cfg *old_cfg; + + cfg = get_one_free_irq_cfg(cpu); + + if (!cfg) + return; + + desc->chip_data = cfg; + + old_cfg = old_desc->chip_data; + + memcpy(cfg, old_cfg, sizeof(struct irq_cfg)); + + init_copy_irq_2_pin(old_cfg, cfg, cpu); +} + +static void free_irq_cfg(struct irq_cfg *old_cfg) +{ + kfree(old_cfg); +} + +void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc) +{ + struct irq_cfg *old_cfg, *cfg; + + old_cfg = old_desc->chip_data; + cfg = desc->chip_data; + + if (old_cfg == cfg) + return; + + if (old_cfg) { + free_irq_2_pin(old_cfg, cfg); + free_irq_cfg(old_cfg); + old_desc->chip_data = NULL; + } +} + +static void +set_extra_move_desc(struct irq_desc *desc, const struct cpumask *mask) +{ + struct irq_cfg *cfg = desc->chip_data; + + if (!cfg->move_in_progress) { + /* it means that domain is not changed */ + if (!cpumask_intersects(desc->affinity, mask)) + cfg->move_desc_pending = 1; + } +} +#endif + +#else +static struct irq_cfg *irq_cfg(unsigned int irq) +{ + return irq < nr_irqs ? irq_cfgx + irq : NULL; +} + +#endif + +#ifndef CONFIG_NUMA_MIGRATE_IRQ_DESC +static inline void +set_extra_move_desc(struct irq_desc *desc, const struct cpumask *mask) +{ +} +#endif + +struct io_apic { + unsigned int index; + unsigned int unused[3]; + unsigned int data; +}; + +static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx) +{ + return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx) + + (mp_ioapics[idx].apicaddr & ~PAGE_MASK); +} + +static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg) +{ + struct io_apic __iomem *io_apic = io_apic_base(apic); + writel(reg, &io_apic->index); + return readl(&io_apic->data); +} + +static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value) +{ + struct io_apic __iomem *io_apic = io_apic_base(apic); + writel(reg, &io_apic->index); + writel(value, &io_apic->data); +} + +/* + * Re-write a value: to be used for read-modify-write + * cycles where the read already set up the index register. + * + * Older SiS APIC requires we rewrite the index register + */ +static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value) +{ + struct io_apic __iomem *io_apic = io_apic_base(apic); + + if (sis_apic_bug) + writel(reg, &io_apic->index); + writel(value, &io_apic->data); +} + +static bool io_apic_level_ack_pending(struct irq_cfg *cfg) +{ + struct irq_pin_list *entry; + unsigned long flags; + + spin_lock_irqsave(&ioapic_lock, flags); + entry = cfg->irq_2_pin; + for (;;) { + unsigned int reg; + int pin; + + if (!entry) + break; + pin = entry->pin; + reg = io_apic_read(entry->apic, 0x10 + pin*2); + /* Is the remote IRR bit set? */ + if (reg & IO_APIC_REDIR_REMOTE_IRR) { + spin_unlock_irqrestore(&ioapic_lock, flags); + return true; + } + if (!entry->next) + break; + entry = entry->next; + } + spin_unlock_irqrestore(&ioapic_lock, flags); + + return false; +} + +union entry_union { + struct { u32 w1, w2; }; + struct IO_APIC_route_entry entry; +}; + +static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin) +{ + union entry_union eu; + unsigned long flags; + spin_lock_irqsave(&ioapic_lock, flags); + eu.w1 = io_apic_read(apic, 0x10 + 2 * pin); + eu.w2 = io_apic_read(apic, 0x11 + 2 * pin); + spin_unlock_irqrestore(&ioapic_lock, flags); + return eu.entry; +} + +/* + * When we write a new IO APIC routing entry, we need to write the high + * word first! If the mask bit in the low word is clear, we will enable + * the interrupt, and we need to make sure the entry is fully populated + * before that happens. + */ +static void +__ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) +{ + union entry_union eu; + eu.entry = e; + io_apic_write(apic, 0x11 + 2*pin, eu.w2); + io_apic_write(apic, 0x10 + 2*pin, eu.w1); +} + +void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) +{ + unsigned long flags; + spin_lock_irqsave(&ioapic_lock, flags); + __ioapic_write_entry(apic, pin, e); + spin_unlock_irqrestore(&ioapic_lock, flags); +} + +/* + * When we mask an IO APIC routing entry, we need to write the low + * word first, in order to set the mask bit before we change the + * high bits! + */ +static void ioapic_mask_entry(int apic, int pin) +{ + unsigned long flags; + union entry_union eu = { .entry.mask = 1 }; + + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(apic, 0x10 + 2*pin, eu.w1); + io_apic_write(apic, 0x11 + 2*pin, eu.w2); + spin_unlock_irqrestore(&ioapic_lock, flags); +} + +#ifdef CONFIG_SMP +static void send_cleanup_vector(struct irq_cfg *cfg) +{ + cpumask_var_t cleanup_mask; + + if (unlikely(!alloc_cpumask_var(&cleanup_mask, GFP_ATOMIC))) { + unsigned int i; + cfg->move_cleanup_count = 0; + for_each_cpu_and(i, cfg->old_domain, cpu_online_mask) + cfg->move_cleanup_count++; + for_each_cpu_and(i, cfg->old_domain, cpu_online_mask) + apic->send_IPI_mask(cpumask_of(i), IRQ_MOVE_CLEANUP_VECTOR); + } else { + cpumask_and(cleanup_mask, cfg->old_domain, cpu_online_mask); + cfg->move_cleanup_count = cpumask_weight(cleanup_mask); + apic->send_IPI_mask(cleanup_mask, IRQ_MOVE_CLEANUP_VECTOR); + free_cpumask_var(cleanup_mask); + } + cfg->move_in_progress = 0; +} + +static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq_cfg *cfg) +{ + int apic, pin; + struct irq_pin_list *entry; + u8 vector = cfg->vector; + + entry = cfg->irq_2_pin; + for (;;) { + unsigned int reg; + + if (!entry) + break; + + apic = entry->apic; + pin = entry->pin; +#ifdef CONFIG_INTR_REMAP + /* + * With interrupt-remapping, destination information comes + * from interrupt-remapping table entry. + */ + if (!irq_remapped(irq)) + io_apic_write(apic, 0x11 + pin*2, dest); +#else + io_apic_write(apic, 0x11 + pin*2, dest); +#endif + reg = io_apic_read(apic, 0x10 + pin*2); + reg &= ~IO_APIC_REDIR_VECTOR_MASK; + reg |= vector; + io_apic_modify(apic, 0x10 + pin*2, reg); + if (!entry->next) + break; + entry = entry->next; + } +} + +static int +assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask); + +/* + * Either sets desc->affinity to a valid value, and returns + * ->cpu_mask_to_apicid of that, or returns BAD_APICID and + * leaves desc->affinity untouched. + */ +static unsigned int +set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask) +{ + struct irq_cfg *cfg; + unsigned int irq; + + if (!cpumask_intersects(mask, cpu_online_mask)) + return BAD_APICID; + + irq = desc->irq; + cfg = desc->chip_data; + if (assign_irq_vector(irq, cfg, mask)) + return BAD_APICID; + + cpumask_and(desc->affinity, cfg->domain, mask); + set_extra_move_desc(desc, mask); + + return apic->cpu_mask_to_apicid_and(desc->affinity, cpu_online_mask); +} + +static void +set_ioapic_affinity_irq_desc(struct irq_desc *desc, const struct cpumask *mask) +{ + struct irq_cfg *cfg; + unsigned long flags; + unsigned int dest; + unsigned int irq; + + irq = desc->irq; + cfg = desc->chip_data; + + spin_lock_irqsave(&ioapic_lock, flags); + dest = set_desc_affinity(desc, mask); + if (dest != BAD_APICID) { + /* Only the high 8 bits are valid. */ + dest = SET_APIC_LOGICAL_ID(dest); + __target_IO_APIC_irq(irq, dest, cfg); + } + spin_unlock_irqrestore(&ioapic_lock, flags); +} + +static void +set_ioapic_affinity_irq(unsigned int irq, const struct cpumask *mask) +{ + struct irq_desc *desc; + + desc = irq_to_desc(irq); + + set_ioapic_affinity_irq_desc(desc, mask); +} +#endif /* CONFIG_SMP */ + +/* + * The common case is 1:1 IRQ<->pin mappings. Sometimes there are + * shared ISA-space IRQs, so we have to support them. We are super + * fast in the common case, and fast for shared ISA-space IRQs. + */ +static void add_pin_to_irq_cpu(struct irq_cfg *cfg, int cpu, int apic, int pin) +{ + struct irq_pin_list *entry; + + entry = cfg->irq_2_pin; + if (!entry) { + entry = get_one_free_irq_2_pin(cpu); + if (!entry) { + printk(KERN_ERR "can not alloc irq_2_pin to add %d - %d\n", + apic, pin); + return; + } + cfg->irq_2_pin = entry; + entry->apic = apic; + entry->pin = pin; + return; + } + + while (entry->next) { + /* not again, please */ + if (entry->apic == apic && entry->pin == pin) + return; + + entry = entry->next; + } + + entry->next = get_one_free_irq_2_pin(cpu); + entry = entry->next; + entry->apic = apic; + entry->pin = pin; +} + +/* + * Reroute an IRQ to a different pin. + */ +static void __init replace_pin_at_irq_cpu(struct irq_cfg *cfg, int cpu, + int oldapic, int oldpin, + int newapic, int newpin) +{ + struct irq_pin_list *entry = cfg->irq_2_pin; + int replaced = 0; + + while (entry) { + if (entry->apic == oldapic && entry->pin == oldpin) { + entry->apic = newapic; + entry->pin = newpin; + replaced = 1; + /* every one is different, right? */ + break; + } + entry = entry->next; + } + + /* why? call replace before add? */ + if (!replaced) + add_pin_to_irq_cpu(cfg, cpu, newapic, newpin); +} + +static inline void io_apic_modify_irq(struct irq_cfg *cfg, + int mask_and, int mask_or, + void (*final)(struct irq_pin_list *entry)) +{ + int pin; + struct irq_pin_list *entry; + + for (entry = cfg->irq_2_pin; entry != NULL; entry = entry->next) { + unsigned int reg; + pin = entry->pin; + reg = io_apic_read(entry->apic, 0x10 + pin * 2); + reg &= mask_and; + reg |= mask_or; + io_apic_modify(entry->apic, 0x10 + pin * 2, reg); + if (final) + final(entry); + } +} + +static void __unmask_IO_APIC_irq(struct irq_cfg *cfg) +{ + io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED, 0, NULL); +} + +#ifdef CONFIG_X86_64 +static void io_apic_sync(struct irq_pin_list *entry) +{ + /* + * Synchronize the IO-APIC and the CPU by doing + * a dummy read from the IO-APIC + */ + struct io_apic __iomem *io_apic; + io_apic = io_apic_base(entry->apic); + readl(&io_apic->data); +} + +static void __mask_IO_APIC_irq(struct irq_cfg *cfg) +{ + io_apic_modify_irq(cfg, ~0, IO_APIC_REDIR_MASKED, &io_apic_sync); +} +#else /* CONFIG_X86_32 */ +static void __mask_IO_APIC_irq(struct irq_cfg *cfg) +{ + io_apic_modify_irq(cfg, ~0, IO_APIC_REDIR_MASKED, NULL); +} + +static void __mask_and_edge_IO_APIC_irq(struct irq_cfg *cfg) +{ + io_apic_modify_irq(cfg, ~IO_APIC_REDIR_LEVEL_TRIGGER, + IO_APIC_REDIR_MASKED, NULL); +} + +static void __unmask_and_level_IO_APIC_irq(struct irq_cfg *cfg) +{ + io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED, + IO_APIC_REDIR_LEVEL_TRIGGER, NULL); +} +#endif /* CONFIG_X86_32 */ + +static void mask_IO_APIC_irq_desc(struct irq_desc *desc) +{ + struct irq_cfg *cfg = desc->chip_data; + unsigned long flags; + + BUG_ON(!cfg); + + spin_lock_irqsave(&ioapic_lock, flags); + __mask_IO_APIC_irq(cfg); + spin_unlock_irqrestore(&ioapic_lock, flags); +} + +static void unmask_IO_APIC_irq_desc(struct irq_desc *desc) +{ + struct irq_cfg *cfg = desc->chip_data; + unsigned long flags; + + spin_lock_irqsave(&ioapic_lock, flags); + __unmask_IO_APIC_irq(cfg); + spin_unlock_irqrestore(&ioapic_lock, flags); +} + +static void mask_IO_APIC_irq(unsigned int irq) +{ + struct irq_desc *desc = irq_to_desc(irq); + + mask_IO_APIC_irq_desc(desc); +} +static void unmask_IO_APIC_irq(unsigned int irq) +{ + struct irq_desc *desc = irq_to_desc(irq); + + unmask_IO_APIC_irq_desc(desc); +} + +static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) +{ + struct IO_APIC_route_entry entry; + + /* Check delivery_mode to be sure we're not clearing an SMI pin */ + entry = ioapic_read_entry(apic, pin); + if (entry.delivery_mode == dest_SMI) + return; + /* + * Disable it in the IO-APIC irq-routing table: + */ + ioapic_mask_entry(apic, pin); +} + +static void clear_IO_APIC (void) +{ + int apic, pin; + + for (apic = 0; apic < nr_ioapics; apic++) + for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) + clear_IO_APIC_pin(apic, pin); +} + +#ifdef CONFIG_X86_32 +/* + * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to + * specific CPU-side IRQs. + */ + +#define MAX_PIRQS 8 +static int pirq_entries[MAX_PIRQS] = { + [0 ... MAX_PIRQS - 1] = -1 +}; + +static int __init ioapic_pirq_setup(char *str) +{ + int i, max; + int ints[MAX_PIRQS+1]; + + get_options(str, ARRAY_SIZE(ints), ints); + + apic_printk(APIC_VERBOSE, KERN_INFO + "PIRQ redirection, working around broken MP-BIOS.\n"); + max = MAX_PIRQS; + if (ints[0] < MAX_PIRQS) + max = ints[0]; + + for (i = 0; i < max; i++) { + apic_printk(APIC_VERBOSE, KERN_DEBUG + "... PIRQ%d -> IRQ %d\n", i, ints[i+1]); + /* + * PIRQs are mapped upside down, usually. + */ + pirq_entries[MAX_PIRQS-i-1] = ints[i+1]; + } + return 1; +} + +__setup("pirq=", ioapic_pirq_setup); +#endif /* CONFIG_X86_32 */ + +#ifdef CONFIG_INTR_REMAP +/* I/O APIC RTE contents at the OS boot up */ +static struct IO_APIC_route_entry *early_ioapic_entries[MAX_IO_APICS]; + +/* + * Saves and masks all the unmasked IO-APIC RTE's + */ +int save_mask_IO_APIC_setup(void) +{ + union IO_APIC_reg_01 reg_01; + unsigned long flags; + int apic, pin; + + /* + * The number of IO-APIC IRQ registers (== #pins): + */ + for (apic = 0; apic < nr_ioapics; apic++) { + spin_lock_irqsave(&ioapic_lock, flags); + reg_01.raw = io_apic_read(apic, 1); + spin_unlock_irqrestore(&ioapic_lock, flags); + nr_ioapic_registers[apic] = reg_01.bits.entries+1; + } + + for (apic = 0; apic < nr_ioapics; apic++) { + early_ioapic_entries[apic] = + kzalloc(sizeof(struct IO_APIC_route_entry) * + nr_ioapic_registers[apic], GFP_KERNEL); + if (!early_ioapic_entries[apic]) + goto nomem; + } + + for (apic = 0; apic < nr_ioapics; apic++) + for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { + struct IO_APIC_route_entry entry; + + entry = early_ioapic_entries[apic][pin] = + ioapic_read_entry(apic, pin); + if (!entry.mask) { + entry.mask = 1; + ioapic_write_entry(apic, pin, entry); + } + } + + return 0; + +nomem: + while (apic >= 0) + kfree(early_ioapic_entries[apic--]); + memset(early_ioapic_entries, 0, + ARRAY_SIZE(early_ioapic_entries)); + + return -ENOMEM; +} + +void restore_IO_APIC_setup(void) +{ + int apic, pin; + + for (apic = 0; apic < nr_ioapics; apic++) { + if (!early_ioapic_entries[apic]) + break; + for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) + ioapic_write_entry(apic, pin, + early_ioapic_entries[apic][pin]); + kfree(early_ioapic_entries[apic]); + early_ioapic_entries[apic] = NULL; + } +} + +void reinit_intr_remapped_IO_APIC(int intr_remapping) +{ + /* + * for now plain restore of previous settings. + * TBD: In the case of OS enabling interrupt-remapping, + * IO-APIC RTE's need to be setup to point to interrupt-remapping + * table entries. for now, do a plain restore, and wait for + * the setup_IO_APIC_irqs() to do proper initialization. + */ + restore_IO_APIC_setup(); +} +#endif + +/* + * Find the IRQ entry number of a certain pin. + */ +static int find_irq_entry(int apic, int pin, int type) +{ + int i; + + for (i = 0; i < mp_irq_entries; i++) + if (mp_irqs[i].irqtype == type && + (mp_irqs[i].dstapic == mp_ioapics[apic].apicid || + mp_irqs[i].dstapic == MP_APIC_ALL) && + mp_irqs[i].dstirq == pin) + return i; + + return -1; +} + +/* + * Find the pin to which IRQ[irq] (ISA) is connected + */ +static int __init find_isa_irq_pin(int irq, int type) +{ + int i; + + for (i = 0; i < mp_irq_entries; i++) { + int lbus = mp_irqs[i].srcbus; + + if (test_bit(lbus, mp_bus_not_pci) && + (mp_irqs[i].irqtype == type) && + (mp_irqs[i].srcbusirq == irq)) + + return mp_irqs[i].dstirq; + } + return -1; +} + +static int __init find_isa_irq_apic(int irq, int type) +{ + int i; + + for (i = 0; i < mp_irq_entries; i++) { + int lbus = mp_irqs[i].srcbus; + + if (test_bit(lbus, mp_bus_not_pci) && + (mp_irqs[i].irqtype == type) && + (mp_irqs[i].srcbusirq == irq)) + break; + } + if (i < mp_irq_entries) { + int apic; + for(apic = 0; apic < nr_ioapics; apic++) { + if (mp_ioapics[apic].apicid == mp_irqs[i].dstapic) + return apic; + } + } + + return -1; +} + +/* + * Find a specific PCI IRQ entry. + * Not an __init, possibly needed by modules + */ +static int pin_2_irq(int idx, int apic, int pin); + +int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin) +{ + int apic, i, best_guess = -1; + + apic_printk(APIC_DEBUG, "querying PCI -> IRQ mapping bus:%d, slot:%d, pin:%d.\n", + bus, slot, pin); + if (test_bit(bus, mp_bus_not_pci)) { + apic_printk(APIC_VERBOSE, "PCI BIOS passed nonexistent PCI bus %d!\n", bus); + return -1; + } + for (i = 0; i < mp_irq_entries; i++) { + int lbus = mp_irqs[i].srcbus; + + for (apic = 0; apic < nr_ioapics; apic++) + if (mp_ioapics[apic].apicid == mp_irqs[i].dstapic || + mp_irqs[i].dstapic == MP_APIC_ALL) + break; + + if (!test_bit(lbus, mp_bus_not_pci) && + !mp_irqs[i].irqtype && + (bus == lbus) && + (slot == ((mp_irqs[i].srcbusirq >> 2) & 0x1f))) { + int irq = pin_2_irq(i, apic, mp_irqs[i].dstirq); + + if (!(apic || IO_APIC_IRQ(irq))) + continue; + + if (pin == (mp_irqs[i].srcbusirq & 3)) + return irq; + /* + * Use the first all-but-pin matching entry as a + * best-guess fuzzy result for broken mptables. + */ + if (best_guess < 0) + best_guess = irq; + } + } + return best_guess; +} + +EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector); + +#if defined(CONFIG_EISA) || defined(CONFIG_MCA) +/* + * EISA Edge/Level control register, ELCR + */ +static int EISA_ELCR(unsigned int irq) +{ + if (irq < NR_IRQS_LEGACY) { + unsigned int port = 0x4d0 + (irq >> 3); + return (inb(port) >> (irq & 7)) & 1; + } + apic_printk(APIC_VERBOSE, KERN_INFO + "Broken MPtable reports ISA irq %d\n", irq); + return 0; +} + +#endif + +/* ISA interrupts are always polarity zero edge triggered, + * when listed as conforming in the MP table. */ + +#define default_ISA_trigger(idx) (0) +#define default_ISA_polarity(idx) (0) + +/* EISA interrupts are always polarity zero and can be edge or level + * trigger depending on the ELCR value. If an interrupt is listed as + * EISA conforming in the MP table, that means its trigger type must + * be read in from the ELCR */ + +#define default_EISA_trigger(idx) (EISA_ELCR(mp_irqs[idx].srcbusirq)) +#define default_EISA_polarity(idx) default_ISA_polarity(idx) + +/* PCI interrupts are always polarity one level triggered, + * when listed as conforming in the MP table. */ + +#define default_PCI_trigger(idx) (1) +#define default_PCI_polarity(idx) (1) + +/* MCA interrupts are always polarity zero level triggered, + * when listed as conforming in the MP table. */ + +#define default_MCA_trigger(idx) (1) +#define default_MCA_polarity(idx) default_ISA_polarity(idx) + +static int MPBIOS_polarity(int idx) +{ + int bus = mp_irqs[idx].srcbus; + int polarity; + + /* + * Determine IRQ line polarity (high active or low active): + */ + switch (mp_irqs[idx].irqflag & 3) + { + case 0: /* conforms, ie. bus-type dependent polarity */ + if (test_bit(bus, mp_bus_not_pci)) + polarity = default_ISA_polarity(idx); + else + polarity = default_PCI_polarity(idx); + break; + case 1: /* high active */ + { + polarity = 0; + break; + } + case 2: /* reserved */ + { + printk(KERN_WARNING "broken BIOS!!\n"); + polarity = 1; + break; + } + case 3: /* low active */ + { + polarity = 1; + break; + } + default: /* invalid */ + { + printk(KERN_WARNING "broken BIOS!!\n"); + polarity = 1; + break; + } + } + return polarity; +} + +static int MPBIOS_trigger(int idx) +{ + int bus = mp_irqs[idx].srcbus; + int trigger; + + /* + * Determine IRQ trigger mode (edge or level sensitive): + */ + switch ((mp_irqs[idx].irqflag>>2) & 3) + { + case 0: /* conforms, ie. bus-type dependent */ + if (test_bit(bus, mp_bus_not_pci)) + trigger = default_ISA_trigger(idx); + else + trigger = default_PCI_trigger(idx); +#if defined(CONFIG_EISA) || defined(CONFIG_MCA) + switch (mp_bus_id_to_type[bus]) { + case MP_BUS_ISA: /* ISA pin */ + { + /* set before the switch */ + break; + } + case MP_BUS_EISA: /* EISA pin */ + { + trigger = default_EISA_trigger(idx); + break; + } + case MP_BUS_PCI: /* PCI pin */ + { + /* set before the switch */ + break; + } + case MP_BUS_MCA: /* MCA pin */ + { + trigger = default_MCA_trigger(idx); + break; + } + default: + { + printk(KERN_WARNING "broken BIOS!!\n"); + trigger = 1; + break; + } + } +#endif + break; + case 1: /* edge */ + { + trigger = 0; + break; + } + case 2: /* reserved */ + { + printk(KERN_WARNING "broken BIOS!!\n"); + trigger = 1; + break; + } + case 3: /* level */ + { + trigger = 1; + break; + } + default: /* invalid */ + { + printk(KERN_WARNING "broken BIOS!!\n"); + trigger = 0; + break; + } + } + return trigger; +} + +static inline int irq_polarity(int idx) +{ + return MPBIOS_polarity(idx); +} + +static inline int irq_trigger(int idx) +{ + return MPBIOS_trigger(idx); +} + +int (*ioapic_renumber_irq)(int ioapic, int irq); +static int pin_2_irq(int idx, int apic, int pin) +{ + int irq, i; + int bus = mp_irqs[idx].srcbus; + + /* + * Debugging check, we are in big trouble if this message pops up! + */ + if (mp_irqs[idx].dstirq != pin) + printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n"); + + if (test_bit(bus, mp_bus_not_pci)) { + irq = mp_irqs[idx].srcbusirq; + } else { + /* + * PCI IRQs are mapped in order + */ + i = irq = 0; + while (i < apic) + irq += nr_ioapic_registers[i++]; + irq += pin; + /* + * For MPS mode, so far only needed by ES7000 platform + */ + if (ioapic_renumber_irq) + irq = ioapic_renumber_irq(apic, irq); + } + +#ifdef CONFIG_X86_32 + /* + * PCI IRQ command line redirection. Yes, limits are hardcoded. + */ + if ((pin >= 16) && (pin <= 23)) { + if (pirq_entries[pin-16] != -1) { + if (!pirq_entries[pin-16]) { + apic_printk(APIC_VERBOSE, KERN_DEBUG + "disabling PIRQ%d\n", pin-16); + } else { + irq = pirq_entries[pin-16]; + apic_printk(APIC_VERBOSE, KERN_DEBUG + "using PIRQ%d -> IRQ %d\n", + pin-16, irq); + } + } + } +#endif + + return irq; +} + +void lock_vector_lock(void) +{ + /* Used to the online set of cpus does not change + * during assign_irq_vector. + */ + spin_lock(&vector_lock); +} + +void unlock_vector_lock(void) +{ + spin_unlock(&vector_lock); +} + +static int +__assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask) +{ + /* + * NOTE! The local APIC isn't very good at handling + * multiple interrupts at the same interrupt level. + * As the interrupt level is determined by taking the + * vector number and shifting that right by 4, we + * want to spread these out a bit so that they don't + * all fall in the same interrupt level. + * + * Also, we've got to be careful not to trash gate + * 0x80, because int 0x80 is hm, kind of importantish. ;) + */ + static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0; + unsigned int old_vector; + int cpu, err; + cpumask_var_t tmp_mask; + + if ((cfg->move_in_progress) || cfg->move_cleanup_count) + return -EBUSY; + + if (!alloc_cpumask_var(&tmp_mask, GFP_ATOMIC)) + return -ENOMEM; + + old_vector = cfg->vector; + if (old_vector) { + cpumask_and(tmp_mask, mask, cpu_online_mask); + cpumask_and(tmp_mask, cfg->domain, tmp_mask); + if (!cpumask_empty(tmp_mask)) { + free_cpumask_var(tmp_mask); + return 0; + } + } + + /* Only try and allocate irqs on cpus that are present */ + err = -ENOSPC; + for_each_cpu_and(cpu, mask, cpu_online_mask) { + int new_cpu; + int vector, offset; + + apic->vector_allocation_domain(cpu, tmp_mask); + + vector = current_vector; + offset = current_offset; +next: + vector += 8; + if (vector >= first_system_vector) { + /* If out of vectors on large boxen, must share them. */ + offset = (offset + 1) % 8; + vector = FIRST_DEVICE_VECTOR + offset; + } + if (unlikely(current_vector == vector)) + continue; + + if (test_bit(vector, used_vectors)) + goto next; + + for_each_cpu_and(new_cpu, tmp_mask, cpu_online_mask) + if (per_cpu(vector_irq, new_cpu)[vector] != -1) + goto next; + /* Found one! */ + current_vector = vector; + current_offset = offset; + if (old_vector) { + cfg->move_in_progress = 1; + cpumask_copy(cfg->old_domain, cfg->domain); + } + for_each_cpu_and(new_cpu, tmp_mask, cpu_online_mask) + per_cpu(vector_irq, new_cpu)[vector] = irq; + cfg->vector = vector; + cpumask_copy(cfg->domain, tmp_mask); + err = 0; + break; + } + free_cpumask_var(tmp_mask); + return err; +} + +static int +assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask) +{ + int err; + unsigned long flags; + + spin_lock_irqsave(&vector_lock, flags); + err = __assign_irq_vector(irq, cfg, mask); + spin_unlock_irqrestore(&vector_lock, flags); + return err; +} + +static void __clear_irq_vector(int irq, struct irq_cfg *cfg) +{ + int cpu, vector; + + BUG_ON(!cfg->vector); + + vector = cfg->vector; + for_each_cpu_and(cpu, cfg->domain, cpu_online_mask) + per_cpu(vector_irq, cpu)[vector] = -1; + + cfg->vector = 0; + cpumask_clear(cfg->domain); + + if (likely(!cfg->move_in_progress)) + return; + for_each_cpu_and(cpu, cfg->old_domain, cpu_online_mask) { + for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; + vector++) { + if (per_cpu(vector_irq, cpu)[vector] != irq) + continue; + per_cpu(vector_irq, cpu)[vector] = -1; + break; + } + } + cfg->move_in_progress = 0; +} + +void __setup_vector_irq(int cpu) +{ + /* Initialize vector_irq on a new cpu */ + /* This function must be called with vector_lock held */ + int irq, vector; + struct irq_cfg *cfg; + struct irq_desc *desc; + + /* Mark the inuse vectors */ + for_each_irq_desc(irq, desc) { + cfg = desc->chip_data; + if (!cpumask_test_cpu(cpu, cfg->domain)) + continue; + vector = cfg->vector; + per_cpu(vector_irq, cpu)[vector] = irq; + } + /* Mark the free vectors */ + for (vector = 0; vector < NR_VECTORS; ++vector) { + irq = per_cpu(vector_irq, cpu)[vector]; + if (irq < 0) + continue; + + cfg = irq_cfg(irq); + if (!cpumask_test_cpu(cpu, cfg->domain)) + per_cpu(vector_irq, cpu)[vector] = -1; + } +} + +static struct irq_chip ioapic_chip; +#ifdef CONFIG_INTR_REMAP +static struct irq_chip ir_ioapic_chip; +#endif + +#define IOAPIC_AUTO -1 +#define IOAPIC_EDGE 0 +#define IOAPIC_LEVEL 1 + +#ifdef CONFIG_X86_32 +static inline int IO_APIC_irq_trigger(int irq) +{ + int apic, idx, pin; + + for (apic = 0; apic < nr_ioapics; apic++) { + for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { + idx = find_irq_entry(apic, pin, mp_INT); + if ((idx != -1) && (irq == pin_2_irq(idx, apic, pin))) + return irq_trigger(idx); + } + } + /* + * nonexistent IRQs are edge default + */ + return 0; +} +#else +static inline int IO_APIC_irq_trigger(int irq) +{ + return 1; +} +#endif + +static void ioapic_register_intr(int irq, struct irq_desc *desc, unsigned long trigger) +{ + + if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || + trigger == IOAPIC_LEVEL) + desc->status |= IRQ_LEVEL; + else + desc->status &= ~IRQ_LEVEL; + +#ifdef CONFIG_INTR_REMAP + if (irq_remapped(irq)) { + desc->status |= IRQ_MOVE_PCNTXT; + if (trigger) + set_irq_chip_and_handler_name(irq, &ir_ioapic_chip, + handle_fasteoi_irq, + "fasteoi"); + else + set_irq_chip_and_handler_name(irq, &ir_ioapic_chip, + handle_edge_irq, "edge"); + return; + } +#endif + if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || + trigger == IOAPIC_LEVEL) + set_irq_chip_and_handler_name(irq, &ioapic_chip, + handle_fasteoi_irq, + "fasteoi"); + else + set_irq_chip_and_handler_name(irq, &ioapic_chip, + handle_edge_irq, "edge"); +} + +int setup_ioapic_entry(int apic_id, int irq, + struct IO_APIC_route_entry *entry, + unsigned int destination, int trigger, + int polarity, int vector) +{ + /* + * add it to the IO-APIC irq-routing table: + */ + memset(entry,0,sizeof(*entry)); + +#ifdef CONFIG_INTR_REMAP + if (intr_remapping_enabled) { + struct intel_iommu *iommu = map_ioapic_to_ir(apic_id); + struct irte irte; + struct IR_IO_APIC_route_entry *ir_entry = + (struct IR_IO_APIC_route_entry *) entry; + int index; + + if (!iommu) + panic("No mapping iommu for ioapic %d\n", apic_id); + + index = alloc_irte(iommu, irq, 1); + if (index < 0) + panic("Failed to allocate IRTE for ioapic %d\n", apic_id); + + memset(&irte, 0, sizeof(irte)); + + irte.present = 1; + irte.dst_mode = apic->irq_dest_mode; + irte.trigger_mode = trigger; + irte.dlvry_mode = apic->irq_delivery_mode; + irte.vector = vector; + irte.dest_id = IRTE_DEST(destination); + + modify_irte(irq, &irte); + + ir_entry->index2 = (index >> 15) & 0x1; + ir_entry->zero = 0; + ir_entry->format = 1; + ir_entry->index = (index & 0x7fff); + } else +#endif + { + entry->delivery_mode = apic->irq_delivery_mode; + entry->dest_mode = apic->irq_dest_mode; + entry->dest = destination; + } + + entry->mask = 0; /* enable IRQ */ + entry->trigger = trigger; + entry->polarity = polarity; + entry->vector = vector; + + /* Mask level triggered irqs. + * Use IRQ_DELAYED_DISABLE for edge triggered irqs. + */ + if (trigger) + entry->mask = 1; + return 0; +} + +static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq_desc *desc, + int trigger, int polarity) +{ + struct irq_cfg *cfg; + struct IO_APIC_route_entry entry; + unsigned int dest; + + if (!IO_APIC_IRQ(irq)) + return; + + cfg = desc->chip_data; + + if (assign_irq_vector(irq, cfg, apic->target_cpus())) + return; + + dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); + + apic_printk(APIC_VERBOSE,KERN_DEBUG + "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> " + "IRQ %d Mode:%i Active:%i)\n", + apic_id, mp_ioapics[apic_id].apicid, pin, cfg->vector, + irq, trigger, polarity); + + + if (setup_ioapic_entry(mp_ioapics[apic_id].apicid, irq, &entry, + dest, trigger, polarity, cfg->vector)) { + printk("Failed to setup ioapic entry for ioapic %d, pin %d\n", + mp_ioapics[apic_id].apicid, pin); + __clear_irq_vector(irq, cfg); + return; + } + + ioapic_register_intr(irq, desc, trigger); + if (irq < NR_IRQS_LEGACY) + disable_8259A_irq(irq); + + ioapic_write_entry(apic_id, pin, entry); +} + +static void __init setup_IO_APIC_irqs(void) +{ + int apic_id, pin, idx, irq; + int notcon = 0; + struct irq_desc *desc; + struct irq_cfg *cfg; + int cpu = boot_cpu_id; + + apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n"); + + for (apic_id = 0; apic_id < nr_ioapics; apic_id++) { + for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) { + + idx = find_irq_entry(apic_id, pin, mp_INT); + if (idx == -1) { + if (!notcon) { + notcon = 1; + apic_printk(APIC_VERBOSE, + KERN_DEBUG " %d-%d", + mp_ioapics[apic_id].apicid, pin); + } else + apic_printk(APIC_VERBOSE, " %d-%d", + mp_ioapics[apic_id].apicid, pin); + continue; + } + if (notcon) { + apic_printk(APIC_VERBOSE, + " (apicid-pin) not connected\n"); + notcon = 0; + } + + irq = pin_2_irq(idx, apic_id, pin); + + /* + * Skip the timer IRQ if there's a quirk handler + * installed and if it returns 1: + */ + if (apic->multi_timer_check && + apic->multi_timer_check(apic_id, irq)) + continue; + + desc = irq_to_desc_alloc_cpu(irq, cpu); + if (!desc) { + printk(KERN_INFO "can not get irq_desc for %d\n", irq); + continue; + } + cfg = desc->chip_data; + add_pin_to_irq_cpu(cfg, cpu, apic_id, pin); + + setup_IO_APIC_irq(apic_id, pin, irq, desc, + irq_trigger(idx), irq_polarity(idx)); + } + } + + if (notcon) + apic_printk(APIC_VERBOSE, + " (apicid-pin) not connected\n"); +} + +/* + * Set up the timer pin, possibly with the 8259A-master behind. + */ +static void __init setup_timer_IRQ0_pin(unsigned int apic_id, unsigned int pin, + int vector) +{ + struct IO_APIC_route_entry entry; + +#ifdef CONFIG_INTR_REMAP + if (intr_remapping_enabled) + return; +#endif + + memset(&entry, 0, sizeof(entry)); + + /* + * We use logical delivery to get the timer IRQ + * to the first CPU. + */ + entry.dest_mode = apic->irq_dest_mode; + entry.mask = 0; /* don't mask IRQ for edge */ + entry.dest = apic->cpu_mask_to_apicid(apic->target_cpus()); + entry.delivery_mode = apic->irq_delivery_mode; + entry.polarity = 0; + entry.trigger = 0; + entry.vector = vector; + + /* + * The timer IRQ doesn't have to know that behind the + * scene we may have a 8259A-master in AEOI mode ... + */ + set_irq_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, "edge"); + + /* + * Add it to the IO-APIC irq-routing table: + */ + ioapic_write_entry(apic_id, pin, entry); +} + + +__apicdebuginit(void) print_IO_APIC(void) +{ + int apic, i; + union IO_APIC_reg_00 reg_00; + union IO_APIC_reg_01 reg_01; + union IO_APIC_reg_02 reg_02; + union IO_APIC_reg_03 reg_03; + unsigned long flags; + struct irq_cfg *cfg; + struct irq_desc *desc; + unsigned int irq; + + if (apic_verbosity == APIC_QUIET) + return; + + printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries); + for (i = 0; i < nr_ioapics; i++) + printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n", + mp_ioapics[i].apicid, nr_ioapic_registers[i]); + + /* + * We are a bit conservative about what we expect. We have to + * know about every hardware change ASAP. + */ + printk(KERN_INFO "testing the IO APIC.......................\n"); + + for (apic = 0; apic < nr_ioapics; apic++) { + + spin_lock_irqsave(&ioapic_lock, flags); + reg_00.raw = io_apic_read(apic, 0); + reg_01.raw = io_apic_read(apic, 1); + if (reg_01.bits.version >= 0x10) + reg_02.raw = io_apic_read(apic, 2); + if (reg_01.bits.version >= 0x20) + reg_03.raw = io_apic_read(apic, 3); + spin_unlock_irqrestore(&ioapic_lock, flags); + + printk("\n"); + printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].apicid); + printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw); + printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID); + printk(KERN_DEBUG "....... : Delivery Type: %X\n", reg_00.bits.delivery_type); + printk(KERN_DEBUG "....... : LTS : %X\n", reg_00.bits.LTS); + + printk(KERN_DEBUG ".... register #01: %08X\n", *(int *)®_01); + printk(KERN_DEBUG "....... : max redirection entries: %04X\n", reg_01.bits.entries); + + printk(KERN_DEBUG "....... : PRQ implemented: %X\n", reg_01.bits.PRQ); + printk(KERN_DEBUG "....... : IO APIC version: %04X\n", reg_01.bits.version); + + /* + * Some Intel chipsets with IO APIC VERSION of 0x1? don't have reg_02, + * but the value of reg_02 is read as the previous read register + * value, so ignore it if reg_02 == reg_01. + */ + if (reg_01.bits.version >= 0x10 && reg_02.raw != reg_01.raw) { + printk(KERN_DEBUG ".... register #02: %08X\n", reg_02.raw); + printk(KERN_DEBUG "....... : arbitration: %02X\n", reg_02.bits.arbitration); + } + + /* + * Some Intel chipsets with IO APIC VERSION of 0x2? don't have reg_02 + * or reg_03, but the value of reg_0[23] is read as the previous read + * register value, so ignore it if reg_03 == reg_0[12]. + */ + if (reg_01.bits.version >= 0x20 && reg_03.raw != reg_02.raw && + reg_03.raw != reg_01.raw) { + printk(KERN_DEBUG ".... register #03: %08X\n", reg_03.raw); + printk(KERN_DEBUG "....... : Boot DT : %X\n", reg_03.bits.boot_DT); + } + + printk(KERN_DEBUG ".... IRQ redirection table:\n"); + + printk(KERN_DEBUG " NR Dst Mask Trig IRR Pol" + " Stat Dmod Deli Vect: \n"); + + for (i = 0; i <= reg_01.bits.entries; i++) { + struct IO_APIC_route_entry entry; + + entry = ioapic_read_entry(apic, i); + + printk(KERN_DEBUG " %02x %03X ", + i, + entry.dest + ); + + printk("%1d %1d %1d %1d %1d %1d %1d %02X\n", + entry.mask, + entry.trigger, + entry.irr, + entry.polarity, + entry.delivery_status, + entry.dest_mode, + entry.delivery_mode, + entry.vector + ); + } + } + printk(KERN_DEBUG "IRQ to pin mappings:\n"); + for_each_irq_desc(irq, desc) { + struct irq_pin_list *entry; + + cfg = desc->chip_data; + entry = cfg->irq_2_pin; + if (!entry) + continue; + printk(KERN_DEBUG "IRQ%d ", irq); + for (;;) { + printk("-> %d:%d", entry->apic, entry->pin); + if (!entry->next) + break; + entry = entry->next; + } + printk("\n"); + } + + printk(KERN_INFO ".................................... done.\n"); + + return; +} + +__apicdebuginit(void) print_APIC_bitfield(int base) +{ + unsigned int v; + int i, j; + + if (apic_verbosity == APIC_QUIET) + return; + + printk(KERN_DEBUG "0123456789abcdef0123456789abcdef\n" KERN_DEBUG); + for (i = 0; i < 8; i++) { + v = apic_read(base + i*0x10); + for (j = 0; j < 32; j++) { + if (v & (1< 3) /* Due to the Pentium erratum 3AP. */ + apic_write(APIC_ESR, 0); + + v = apic_read(APIC_ESR); + printk(KERN_DEBUG "... APIC ESR: %08x\n", v); + } + + icr = apic_icr_read(); + printk(KERN_DEBUG "... APIC ICR: %08x\n", (u32)icr); + printk(KERN_DEBUG "... APIC ICR2: %08x\n", (u32)(icr >> 32)); + + v = apic_read(APIC_LVTT); + printk(KERN_DEBUG "... APIC LVTT: %08x\n", v); + + if (maxlvt > 3) { /* PC is LVT#4. */ + v = apic_read(APIC_LVTPC); + printk(KERN_DEBUG "... APIC LVTPC: %08x\n", v); + } + v = apic_read(APIC_LVT0); + printk(KERN_DEBUG "... APIC LVT0: %08x\n", v); + v = apic_read(APIC_LVT1); + printk(KERN_DEBUG "... APIC LVT1: %08x\n", v); + + if (maxlvt > 2) { /* ERR is LVT#3. */ + v = apic_read(APIC_LVTERR); + printk(KERN_DEBUG "... APIC LVTERR: %08x\n", v); + } + + v = apic_read(APIC_TMICT); + printk(KERN_DEBUG "... APIC TMICT: %08x\n", v); + v = apic_read(APIC_TMCCT); + printk(KERN_DEBUG "... APIC TMCCT: %08x\n", v); + v = apic_read(APIC_TDCR); + printk(KERN_DEBUG "... APIC TDCR: %08x\n", v); + printk("\n"); +} + +__apicdebuginit(void) print_all_local_APICs(void) +{ + int cpu; + + preempt_disable(); + for_each_online_cpu(cpu) + smp_call_function_single(cpu, print_local_APIC, NULL, 1); + preempt_enable(); +} + +__apicdebuginit(void) print_PIC(void) +{ + unsigned int v; + unsigned long flags; + + if (apic_verbosity == APIC_QUIET) + return; + + printk(KERN_DEBUG "\nprinting PIC contents\n"); + + spin_lock_irqsave(&i8259A_lock, flags); + + v = inb(0xa1) << 8 | inb(0x21); + printk(KERN_DEBUG "... PIC IMR: %04x\n", v); + + v = inb(0xa0) << 8 | inb(0x20); + printk(KERN_DEBUG "... PIC IRR: %04x\n", v); + + outb(0x0b,0xa0); + outb(0x0b,0x20); + v = inb(0xa0) << 8 | inb(0x20); + outb(0x0a,0xa0); + outb(0x0a,0x20); + + spin_unlock_irqrestore(&i8259A_lock, flags); + + printk(KERN_DEBUG "... PIC ISR: %04x\n", v); + + v = inb(0x4d1) << 8 | inb(0x4d0); + printk(KERN_DEBUG "... PIC ELCR: %04x\n", v); +} + +__apicdebuginit(int) print_all_ICs(void) +{ + print_PIC(); + print_all_local_APICs(); + print_IO_APIC(); + + return 0; +} + +fs_initcall(print_all_ICs); + + +/* Where if anywhere is the i8259 connect in external int mode */ +static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; + +void __init enable_IO_APIC(void) +{ + union IO_APIC_reg_01 reg_01; + int i8259_apic, i8259_pin; + int apic; + unsigned long flags; + + /* + * The number of IO-APIC IRQ registers (== #pins): + */ + for (apic = 0; apic < nr_ioapics; apic++) { + spin_lock_irqsave(&ioapic_lock, flags); + reg_01.raw = io_apic_read(apic, 1); + spin_unlock_irqrestore(&ioapic_lock, flags); + nr_ioapic_registers[apic] = reg_01.bits.entries+1; + } + for(apic = 0; apic < nr_ioapics; apic++) { + int pin; + /* See if any of the pins is in ExtINT mode */ + for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { + struct IO_APIC_route_entry entry; + entry = ioapic_read_entry(apic, pin); + + /* If the interrupt line is enabled and in ExtInt mode + * I have found the pin where the i8259 is connected. + */ + if ((entry.mask == 0) && (entry.delivery_mode == dest_ExtINT)) { + ioapic_i8259.apic = apic; + ioapic_i8259.pin = pin; + goto found_i8259; + } + } + } + found_i8259: + /* Look to see what if the MP table has reported the ExtINT */ + /* If we could not find the appropriate pin by looking at the ioapic + * the i8259 probably is not connected the ioapic but give the + * mptable a chance anyway. + */ + i8259_pin = find_isa_irq_pin(0, mp_ExtINT); + i8259_apic = find_isa_irq_apic(0, mp_ExtINT); + /* Trust the MP table if nothing is setup in the hardware */ + if ((ioapic_i8259.pin == -1) && (i8259_pin >= 0)) { + printk(KERN_WARNING "ExtINT not setup in hardware but reported by MP table\n"); + ioapic_i8259.pin = i8259_pin; + ioapic_i8259.apic = i8259_apic; + } + /* Complain if the MP table and the hardware disagree */ + if (((ioapic_i8259.apic != i8259_apic) || (ioapic_i8259.pin != i8259_pin)) && + (i8259_pin >= 0) && (ioapic_i8259.pin >= 0)) + { + printk(KERN_WARNING "ExtINT in hardware and MP table differ\n"); + } + + /* + * Do not trust the IO-APIC being empty at bootup + */ + clear_IO_APIC(); +} + +/* + * Not an __init, needed by the reboot code + */ +void disable_IO_APIC(void) +{ + /* + * Clear the IO-APIC before rebooting: + */ + clear_IO_APIC(); + + /* + * If the i8259 is routed through an IOAPIC + * Put that IOAPIC in virtual wire mode + * so legacy interrupts can be delivered. + */ + if (ioapic_i8259.pin != -1) { + struct IO_APIC_route_entry entry; + + memset(&entry, 0, sizeof(entry)); + entry.mask = 0; /* Enabled */ + entry.trigger = 0; /* Edge */ + entry.irr = 0; + entry.polarity = 0; /* High */ + entry.delivery_status = 0; + entry.dest_mode = 0; /* Physical */ + entry.delivery_mode = dest_ExtINT; /* ExtInt */ + entry.vector = 0; + entry.dest = read_apic_id(); + + /* + * Add it to the IO-APIC irq-routing table: + */ + ioapic_write_entry(ioapic_i8259.apic, ioapic_i8259.pin, entry); + } + + disconnect_bsp_APIC(ioapic_i8259.pin != -1); +} + +#ifdef CONFIG_X86_32 +/* + * function to set the IO-APIC physical IDs based on the + * values stored in the MPC table. + * + * by Matt Domsch Tue Dec 21 12:25:05 CST 1999 + */ + +static void __init setup_ioapic_ids_from_mpc(void) +{ + union IO_APIC_reg_00 reg_00; + physid_mask_t phys_id_present_map; + int apic_id; + int i; + unsigned char old_id; + unsigned long flags; + + if (x86_quirks->setup_ioapic_ids && x86_quirks->setup_ioapic_ids()) + return; + + /* + * Don't check I/O APIC IDs for xAPIC systems. They have + * no meaning without the serial APIC bus. + */ + if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) + || APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) + return; + /* + * This is broken; anything with a real cpu count has to + * circumvent this idiocy regardless. + */ + phys_id_present_map = apic->ioapic_phys_id_map(phys_cpu_present_map); + + /* + * Set the IOAPIC ID to the value stored in the MPC table. + */ + for (apic_id = 0; apic_id < nr_ioapics; apic_id++) { + + /* Read the register 0 value */ + spin_lock_irqsave(&ioapic_lock, flags); + reg_00.raw = io_apic_read(apic_id, 0); + spin_unlock_irqrestore(&ioapic_lock, flags); + + old_id = mp_ioapics[apic_id].apicid; + + if (mp_ioapics[apic_id].apicid >= get_physical_broadcast()) { + printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n", + apic_id, mp_ioapics[apic_id].apicid); + printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", + reg_00.bits.ID); + mp_ioapics[apic_id].apicid = reg_00.bits.ID; + } + + /* + * Sanity check, is the ID really free? Every APIC in a + * system must have a unique ID or we get lots of nice + * 'stuck on smp_invalidate_needed IPI wait' messages. + */ + if (apic->check_apicid_used(phys_id_present_map, + mp_ioapics[apic_id].apicid)) { + printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n", + apic_id, mp_ioapics[apic_id].apicid); + for (i = 0; i < get_physical_broadcast(); i++) + if (!physid_isset(i, phys_id_present_map)) + break; + if (i >= get_physical_broadcast()) + panic("Max APIC ID exceeded!\n"); + printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", + i); + physid_set(i, phys_id_present_map); + mp_ioapics[apic_id].apicid = i; + } else { + physid_mask_t tmp; + tmp = apic->apicid_to_cpu_present(mp_ioapics[apic_id].apicid); + apic_printk(APIC_VERBOSE, "Setting %d in the " + "phys_id_present_map\n", + mp_ioapics[apic_id].apicid); + physids_or(phys_id_present_map, phys_id_present_map, tmp); + } + + + /* + * We need to adjust the IRQ routing table + * if the ID changed. + */ + if (old_id != mp_ioapics[apic_id].apicid) + for (i = 0; i < mp_irq_entries; i++) + if (mp_irqs[i].dstapic == old_id) + mp_irqs[i].dstapic + = mp_ioapics[apic_id].apicid; + + /* + * Read the right value from the MPC table and + * write it into the ID register. + */ + apic_printk(APIC_VERBOSE, KERN_INFO + "...changing IO-APIC physical APIC ID to %d ...", + mp_ioapics[apic_id].apicid); + + reg_00.bits.ID = mp_ioapics[apic_id].apicid; + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(apic_id, 0, reg_00.raw); + spin_unlock_irqrestore(&ioapic_lock, flags); + + /* + * Sanity check + */ + spin_lock_irqsave(&ioapic_lock, flags); + reg_00.raw = io_apic_read(apic_id, 0); + spin_unlock_irqrestore(&ioapic_lock, flags); + if (reg_00.bits.ID != mp_ioapics[apic_id].apicid) + printk("could not set ID!\n"); + else + apic_printk(APIC_VERBOSE, " ok.\n"); + } +} +#endif + +int no_timer_check __initdata; + +static int __init notimercheck(char *s) +{ + no_timer_check = 1; + return 1; +} +__setup("no_timer_check", notimercheck); + +/* + * There is a nasty bug in some older SMP boards, their mptable lies + * about the timer IRQ. We do the following to work around the situation: + * + * - timer IRQ defaults to IO-APIC IRQ + * - if this function detects that timer IRQs are defunct, then we fall + * back to ISA timer IRQs + */ +static int __init timer_irq_works(void) +{ + unsigned long t1 = jiffies; + unsigned long flags; + + if (no_timer_check) + return 1; + + local_save_flags(flags); + local_irq_enable(); + /* Let ten ticks pass... */ + mdelay((10 * 1000) / HZ); + local_irq_restore(flags); + + /* + * Expect a few ticks at least, to be sure some possible + * glue logic does not lock up after one or two first + * ticks in a non-ExtINT mode. Also the local APIC + * might have cached one ExtINT interrupt. Finally, at + * least one tick may be lost due to delays. + */ + + /* jiffies wrap? */ + if (time_after(jiffies, t1 + 4)) + return 1; + return 0; +} + +/* + * In the SMP+IOAPIC case it might happen that there are an unspecified + * number of pending IRQ events unhandled. These cases are very rare, + * so we 'resend' these IRQs via IPIs, to the same CPU. It's much + * better to do it this way as thus we do not have to be aware of + * 'pending' interrupts in the IRQ path, except at this point. + */ +/* + * Edge triggered needs to resend any interrupt + * that was delayed but this is now handled in the device + * independent code. + */ + +/* + * Starting up a edge-triggered IO-APIC interrupt is + * nasty - we need to make sure that we get the edge. + * If it is already asserted for some reason, we need + * return 1 to indicate that is was pending. + * + * This is not complete - we should be able to fake + * an edge even if it isn't on the 8259A... + */ + +static unsigned int startup_ioapic_irq(unsigned int irq) +{ + int was_pending = 0; + unsigned long flags; + struct irq_cfg *cfg; + + spin_lock_irqsave(&ioapic_lock, flags); + if (irq < NR_IRQS_LEGACY) { + disable_8259A_irq(irq); + if (i8259A_irq_pending(irq)) + was_pending = 1; + } + cfg = irq_cfg(irq); + __unmask_IO_APIC_irq(cfg); + spin_unlock_irqrestore(&ioapic_lock, flags); + + return was_pending; +} + +#ifdef CONFIG_X86_64 +static int ioapic_retrigger_irq(unsigned int irq) +{ + + struct irq_cfg *cfg = irq_cfg(irq); + unsigned long flags; + + spin_lock_irqsave(&vector_lock, flags); + apic->send_IPI_mask(cpumask_of(cpumask_first(cfg->domain)), cfg->vector); + spin_unlock_irqrestore(&vector_lock, flags); + + return 1; +} +#else +static int ioapic_retrigger_irq(unsigned int irq) +{ + apic->send_IPI_self(irq_cfg(irq)->vector); + + return 1; +} +#endif + +/* + * Level and edge triggered IO-APIC interrupts need different handling, + * so we use two separate IRQ descriptors. Edge triggered IRQs can be + * handled with the level-triggered descriptor, but that one has slightly + * more overhead. Level-triggered interrupts cannot be handled with the + * edge-triggered handler, without risking IRQ storms and other ugly + * races. + */ + +#ifdef CONFIG_SMP + +#ifdef CONFIG_INTR_REMAP +static void ir_irq_migration(struct work_struct *work); + +static DECLARE_DELAYED_WORK(ir_migration_work, ir_irq_migration); + +/* + * Migrate the IO-APIC irq in the presence of intr-remapping. + * + * For edge triggered, irq migration is a simple atomic update(of vector + * and cpu destination) of IRTE and flush the hardware cache. + * + * For level triggered, we need to modify the io-apic RTE aswell with the update + * vector information, along with modifying IRTE with vector and destination. + * So irq migration for level triggered is little bit more complex compared to + * edge triggered migration. But the good news is, we use the same algorithm + * for level triggered migration as we have today, only difference being, + * we now initiate the irq migration from process context instead of the + * interrupt context. + * + * In future, when we do a directed EOI (combined with cpu EOI broadcast + * suppression) to the IO-APIC, level triggered irq migration will also be + * as simple as edge triggered migration and we can do the irq migration + * with a simple atomic update to IO-APIC RTE. + */ +static void +migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask) +{ + struct irq_cfg *cfg; + struct irte irte; + int modify_ioapic_rte; + unsigned int dest; + unsigned long flags; + unsigned int irq; + + if (!cpumask_intersects(mask, cpu_online_mask)) + return; + + irq = desc->irq; + if (get_irte(irq, &irte)) + return; + + cfg = desc->chip_data; + if (assign_irq_vector(irq, cfg, mask)) + return; + + set_extra_move_desc(desc, mask); + + dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask); + + modify_ioapic_rte = desc->status & IRQ_LEVEL; + if (modify_ioapic_rte) { + spin_lock_irqsave(&ioapic_lock, flags); + __target_IO_APIC_irq(irq, dest, cfg); + spin_unlock_irqrestore(&ioapic_lock, flags); + } + + irte.vector = cfg->vector; + irte.dest_id = IRTE_DEST(dest); + + /* + * Modified the IRTE and flushes the Interrupt entry cache. + */ + modify_irte(irq, &irte); + + if (cfg->move_in_progress) + send_cleanup_vector(cfg); + + cpumask_copy(desc->affinity, mask); +} + +static int migrate_irq_remapped_level_desc(struct irq_desc *desc) +{ + int ret = -1; + struct irq_cfg *cfg = desc->chip_data; + + mask_IO_APIC_irq_desc(desc); + + if (io_apic_level_ack_pending(cfg)) { + /* + * Interrupt in progress. Migrating irq now will change the + * vector information in the IO-APIC RTE and that will confuse + * the EOI broadcast performed by cpu. + * So, delay the irq migration to the next instance. + */ + schedule_delayed_work(&ir_migration_work, 1); + goto unmask; + } + + /* everthing is clear. we have right of way */ + migrate_ioapic_irq_desc(desc, desc->pending_mask); + + ret = 0; + desc->status &= ~IRQ_MOVE_PENDING; + cpumask_clear(desc->pending_mask); + +unmask: + unmask_IO_APIC_irq_desc(desc); + + return ret; +} + +static void ir_irq_migration(struct work_struct *work) +{ + unsigned int irq; + struct irq_desc *desc; + + for_each_irq_desc(irq, desc) { + if (desc->status & IRQ_MOVE_PENDING) { + unsigned long flags; + + spin_lock_irqsave(&desc->lock, flags); + if (!desc->chip->set_affinity || + !(desc->status & IRQ_MOVE_PENDING)) { + desc->status &= ~IRQ_MOVE_PENDING; + spin_unlock_irqrestore(&desc->lock, flags); + continue; + } + + desc->chip->set_affinity(irq, desc->pending_mask); + spin_unlock_irqrestore(&desc->lock, flags); + } + } +} + +/* + * Migrates the IRQ destination in the process context. + */ +static void set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc, + const struct cpumask *mask) +{ + if (desc->status & IRQ_LEVEL) { + desc->status |= IRQ_MOVE_PENDING; + cpumask_copy(desc->pending_mask, mask); + migrate_irq_remapped_level_desc(desc); + return; + } + + migrate_ioapic_irq_desc(desc, mask); +} +static void set_ir_ioapic_affinity_irq(unsigned int irq, + const struct cpumask *mask) +{ + struct irq_desc *desc = irq_to_desc(irq); + + set_ir_ioapic_affinity_irq_desc(desc, mask); +} +#endif + +asmlinkage void smp_irq_move_cleanup_interrupt(void) +{ + unsigned vector, me; + + ack_APIC_irq(); + exit_idle(); + irq_enter(); + + me = smp_processor_id(); + for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) { + unsigned int irq; + struct irq_desc *desc; + struct irq_cfg *cfg; + irq = __get_cpu_var(vector_irq)[vector]; + + if (irq == -1) + continue; + + desc = irq_to_desc(irq); + if (!desc) + continue; + + cfg = irq_cfg(irq); + spin_lock(&desc->lock); + if (!cfg->move_cleanup_count) + goto unlock; + + if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) + goto unlock; + + __get_cpu_var(vector_irq)[vector] = -1; + cfg->move_cleanup_count--; +unlock: + spin_unlock(&desc->lock); + } + + irq_exit(); +} + +static void irq_complete_move(struct irq_desc **descp) +{ + struct irq_desc *desc = *descp; + struct irq_cfg *cfg = desc->chip_data; + unsigned vector, me; + + if (likely(!cfg->move_in_progress)) { +#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC + if (likely(!cfg->move_desc_pending)) + return; + + /* domain has not changed, but affinity did */ + me = smp_processor_id(); + if (cpumask_test_cpu(me, desc->affinity)) { + *descp = desc = move_irq_desc(desc, me); + /* get the new one */ + cfg = desc->chip_data; + cfg->move_desc_pending = 0; + } +#endif + return; + } + + vector = ~get_irq_regs()->orig_ax; + me = smp_processor_id(); + + if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) { +#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC + *descp = desc = move_irq_desc(desc, me); + /* get the new one */ + cfg = desc->chip_data; +#endif + send_cleanup_vector(cfg); + } +} +#else +static inline void irq_complete_move(struct irq_desc **descp) {} +#endif + +#ifdef CONFIG_INTR_REMAP +static void ack_x2apic_level(unsigned int irq) +{ + ack_x2APIC_irq(); +} + +static void ack_x2apic_edge(unsigned int irq) +{ + ack_x2APIC_irq(); +} + +#endif + +static void ack_apic_edge(unsigned int irq) +{ + struct irq_desc *desc = irq_to_desc(irq); + + irq_complete_move(&desc); + move_native_irq(irq); + ack_APIC_irq(); +} + +atomic_t irq_mis_count; + +static void ack_apic_level(unsigned int irq) +{ + struct irq_desc *desc = irq_to_desc(irq); + +#ifdef CONFIG_X86_32 + unsigned long v; + int i; +#endif + struct irq_cfg *cfg; + int do_unmask_irq = 0; + + irq_complete_move(&desc); +#ifdef CONFIG_GENERIC_PENDING_IRQ + /* If we are moving the irq we need to mask it */ + if (unlikely(desc->status & IRQ_MOVE_PENDING)) { + do_unmask_irq = 1; + mask_IO_APIC_irq_desc(desc); + } +#endif + +#ifdef CONFIG_X86_32 + /* + * It appears there is an erratum which affects at least version 0x11 + * of I/O APIC (that's the 82093AA and cores integrated into various + * chipsets). Under certain conditions a level-triggered interrupt is + * erroneously delivered as edge-triggered one but the respective IRR + * bit gets set nevertheless. As a result the I/O unit expects an EOI + * message but it will never arrive and further interrupts are blocked + * from the source. The exact reason is so far unknown, but the + * phenomenon was observed when two consecutive interrupt requests + * from a given source get delivered to the same CPU and the source is + * temporarily disabled in between. + * + * A workaround is to simulate an EOI message manually. We achieve it + * by setting the trigger mode to edge and then to level when the edge + * trigger mode gets detected in the TMR of a local APIC for a + * level-triggered interrupt. We mask the source for the time of the + * operation to prevent an edge-triggered interrupt escaping meanwhile. + * The idea is from Manfred Spraul. --macro + */ + cfg = desc->chip_data; + i = cfg->vector; + + v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1)); +#endif + + /* + * We must acknowledge the irq before we move it or the acknowledge will + * not propagate properly. + */ + ack_APIC_irq(); + + /* Now we can move and renable the irq */ + if (unlikely(do_unmask_irq)) { + /* Only migrate the irq if the ack has been received. + * + * On rare occasions the broadcast level triggered ack gets + * delayed going to ioapics, and if we reprogram the + * vector while Remote IRR is still set the irq will never + * fire again. + * + * To prevent this scenario we read the Remote IRR bit + * of the ioapic. This has two effects. + * - On any sane system the read of the ioapic will + * flush writes (and acks) going to the ioapic from + * this cpu. + * - We get to see if the ACK has actually been delivered. + * + * Based on failed experiments of reprogramming the + * ioapic entry from outside of irq context starting + * with masking the ioapic entry and then polling until + * Remote IRR was clear before reprogramming the + * ioapic I don't trust the Remote IRR bit to be + * completey accurate. + * + * However there appears to be no other way to plug + * this race, so if the Remote IRR bit is not + * accurate and is causing problems then it is a hardware bug + * and you can go talk to the chipset vendor about it. + */ + cfg = desc->chip_data; + if (!io_apic_level_ack_pending(cfg)) + move_masked_irq(irq); + unmask_IO_APIC_irq_desc(desc); + } + +#ifdef CONFIG_X86_32 + if (!(v & (1 << (i & 0x1f)))) { + atomic_inc(&irq_mis_count); + spin_lock(&ioapic_lock); + __mask_and_edge_IO_APIC_irq(cfg); + __unmask_and_level_IO_APIC_irq(cfg); + spin_unlock(&ioapic_lock); + } +#endif +} + +static struct irq_chip ioapic_chip __read_mostly = { + .name = "IO-APIC", + .startup = startup_ioapic_irq, + .mask = mask_IO_APIC_irq, + .unmask = unmask_IO_APIC_irq, + .ack = ack_apic_edge, + .eoi = ack_apic_level, +#ifdef CONFIG_SMP + .set_affinity = set_ioapic_affinity_irq, +#endif + .retrigger = ioapic_retrigger_irq, +}; + +#ifdef CONFIG_INTR_REMAP +static struct irq_chip ir_ioapic_chip __read_mostly = { + .name = "IR-IO-APIC", + .startup = startup_ioapic_irq, + .mask = mask_IO_APIC_irq, + .unmask = unmask_IO_APIC_irq, + .ack = ack_x2apic_edge, + .eoi = ack_x2apic_level, +#ifdef CONFIG_SMP + .set_affinity = set_ir_ioapic_affinity_irq, +#endif + .retrigger = ioapic_retrigger_irq, +}; +#endif + +static inline void init_IO_APIC_traps(void) +{ + int irq; + struct irq_desc *desc; + struct irq_cfg *cfg; + + /* + * NOTE! The local APIC isn't very good at handling + * multiple interrupts at the same interrupt level. + * As the interrupt level is determined by taking the + * vector number and shifting that right by 4, we + * want to spread these out a bit so that they don't + * all fall in the same interrupt level. + * + * Also, we've got to be careful not to trash gate + * 0x80, because int 0x80 is hm, kind of importantish. ;) + */ + for_each_irq_desc(irq, desc) { + cfg = desc->chip_data; + if (IO_APIC_IRQ(irq) && cfg && !cfg->vector) { + /* + * Hmm.. We don't have an entry for this, + * so default to an old-fashioned 8259 + * interrupt if we can.. + */ + if (irq < NR_IRQS_LEGACY) + make_8259A_irq(irq); + else + /* Strange. Oh, well.. */ + desc->chip = &no_irq_chip; + } + } +} + +/* + * The local APIC irq-chip implementation: + */ + +static void mask_lapic_irq(unsigned int irq) +{ + unsigned long v; + + v = apic_read(APIC_LVT0); + apic_write(APIC_LVT0, v | APIC_LVT_MASKED); +} + +static void unmask_lapic_irq(unsigned int irq) +{ + unsigned long v; + + v = apic_read(APIC_LVT0); + apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED); +} + +static void ack_lapic_irq(unsigned int irq) +{ + ack_APIC_irq(); +} + +static struct irq_chip lapic_chip __read_mostly = { + .name = "local-APIC", + .mask = mask_lapic_irq, + .unmask = unmask_lapic_irq, + .ack = ack_lapic_irq, +}; + +static void lapic_register_intr(int irq, struct irq_desc *desc) +{ + desc->status &= ~IRQ_LEVEL; + set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq, + "edge"); +} + +static void __init setup_nmi(void) +{ + /* + * Dirty trick to enable the NMI watchdog ... + * We put the 8259A master into AEOI mode and + * unmask on all local APICs LVT0 as NMI. + * + * The idea to use the 8259A in AEOI mode ('8259A Virtual Wire') + * is from Maciej W. Rozycki - so we do not have to EOI from + * the NMI handler or the timer interrupt. + */ + apic_printk(APIC_VERBOSE, KERN_INFO "activating NMI Watchdog ..."); + + enable_NMI_through_LVT0(); + + apic_printk(APIC_VERBOSE, " done.\n"); +} + +/* + * This looks a bit hackish but it's about the only one way of sending + * a few INTA cycles to 8259As and any associated glue logic. ICR does + * not support the ExtINT mode, unfortunately. We need to send these + * cycles as some i82489DX-based boards have glue logic that keeps the + * 8259A interrupt line asserted until INTA. --macro + */ +static inline void __init unlock_ExtINT_logic(void) +{ + int apic, pin, i; + struct IO_APIC_route_entry entry0, entry1; + unsigned char save_control, save_freq_select; + + pin = find_isa_irq_pin(8, mp_INT); + if (pin == -1) { + WARN_ON_ONCE(1); + return; + } + apic = find_isa_irq_apic(8, mp_INT); + if (apic == -1) { + WARN_ON_ONCE(1); + return; + } + + entry0 = ioapic_read_entry(apic, pin); + clear_IO_APIC_pin(apic, pin); + + memset(&entry1, 0, sizeof(entry1)); + + entry1.dest_mode = 0; /* physical delivery */ + entry1.mask = 0; /* unmask IRQ now */ + entry1.dest = hard_smp_processor_id(); + entry1.delivery_mode = dest_ExtINT; + entry1.polarity = entry0.polarity; + entry1.trigger = 0; + entry1.vector = 0; + + ioapic_write_entry(apic, pin, entry1); + + save_control = CMOS_READ(RTC_CONTROL); + save_freq_select = CMOS_READ(RTC_FREQ_SELECT); + CMOS_WRITE((save_freq_select & ~RTC_RATE_SELECT) | 0x6, + RTC_FREQ_SELECT); + CMOS_WRITE(save_control | RTC_PIE, RTC_CONTROL); + + i = 100; + while (i-- > 0) { + mdelay(10); + if ((CMOS_READ(RTC_INTR_FLAGS) & RTC_PF) == RTC_PF) + i -= 10; + } + + CMOS_WRITE(save_control, RTC_CONTROL); + CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); + clear_IO_APIC_pin(apic, pin); + + ioapic_write_entry(apic, pin, entry0); +} + +static int disable_timer_pin_1 __initdata; +/* Actually the next is obsolete, but keep it for paranoid reasons -AK */ +static int __init disable_timer_pin_setup(char *arg) +{ + disable_timer_pin_1 = 1; + return 0; +} +early_param("disable_timer_pin_1", disable_timer_pin_setup); + +int timer_through_8259 __initdata; + +/* + * This code may look a bit paranoid, but it's supposed to cooperate with + * a wide range of boards and BIOS bugs. Fortunately only the timer IRQ + * is so screwy. Thanks to Brian Perkins for testing/hacking this beast + * fanatically on his truly buggy board. + * + * FIXME: really need to revamp this for all platforms. + */ +static inline void __init check_timer(void) +{ + struct irq_desc *desc = irq_to_desc(0); + struct irq_cfg *cfg = desc->chip_data; + int cpu = boot_cpu_id; + int apic1, pin1, apic2, pin2; + unsigned long flags; + int no_pin1 = 0; + + local_irq_save(flags); + + /* + * get/set the timer IRQ vector: + */ + disable_8259A_irq(0); + assign_irq_vector(0, cfg, apic->target_cpus()); + + /* + * As IRQ0 is to be enabled in the 8259A, the virtual + * wire has to be disabled in the local APIC. Also + * timer interrupts need to be acknowledged manually in + * the 8259A for the i82489DX when using the NMI + * watchdog as that APIC treats NMIs as level-triggered. + * The AEOI mode will finish them in the 8259A + * automatically. + */ + apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); + init_8259A(1); +#ifdef CONFIG_X86_32 + { + unsigned int ver; + + ver = apic_read(APIC_LVR); + ver = GET_APIC_VERSION(ver); + timer_ack = (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver)); + } +#endif + + pin1 = find_isa_irq_pin(0, mp_INT); + apic1 = find_isa_irq_apic(0, mp_INT); + pin2 = ioapic_i8259.pin; + apic2 = ioapic_i8259.apic; + + apic_printk(APIC_QUIET, KERN_INFO "..TIMER: vector=0x%02X " + "apic1=%d pin1=%d apic2=%d pin2=%d\n", + cfg->vector, apic1, pin1, apic2, pin2); + + /* + * Some BIOS writers are clueless and report the ExtINTA + * I/O APIC input from the cascaded 8259A as the timer + * interrupt input. So just in case, if only one pin + * was found above, try it both directly and through the + * 8259A. + */ + if (pin1 == -1) { +#ifdef CONFIG_INTR_REMAP + if (intr_remapping_enabled) + panic("BIOS bug: timer not connected to IO-APIC"); +#endif + pin1 = pin2; + apic1 = apic2; + no_pin1 = 1; + } else if (pin2 == -1) { + pin2 = pin1; + apic2 = apic1; + } + + if (pin1 != -1) { + /* + * Ok, does IRQ0 through the IOAPIC work? + */ + if (no_pin1) { + add_pin_to_irq_cpu(cfg, cpu, apic1, pin1); + setup_timer_IRQ0_pin(apic1, pin1, cfg->vector); + } else { + /* for edge trigger, setup_IO_APIC_irq already + * leave it unmasked. + * so only need to unmask if it is level-trigger + * do we really have level trigger timer? + */ + int idx; + idx = find_irq_entry(apic1, pin1, mp_INT); + if (idx != -1 && irq_trigger(idx)) + unmask_IO_APIC_irq_desc(desc); + } + if (timer_irq_works()) { + if (nmi_watchdog == NMI_IO_APIC) { + setup_nmi(); + enable_8259A_irq(0); + } + if (disable_timer_pin_1 > 0) + clear_IO_APIC_pin(0, pin1); + goto out; + } +#ifdef CONFIG_INTR_REMAP + if (intr_remapping_enabled) + panic("timer doesn't work through Interrupt-remapped IO-APIC"); +#endif + local_irq_disable(); + clear_IO_APIC_pin(apic1, pin1); + if (!no_pin1) + apic_printk(APIC_QUIET, KERN_ERR "..MP-BIOS bug: " + "8254 timer not connected to IO-APIC\n"); + + apic_printk(APIC_QUIET, KERN_INFO "...trying to set up timer " + "(IRQ0) through the 8259A ...\n"); + apic_printk(APIC_QUIET, KERN_INFO + "..... (found apic %d pin %d) ...\n", apic2, pin2); + /* + * legacy devices should be connected to IO APIC #0 + */ + replace_pin_at_irq_cpu(cfg, cpu, apic1, pin1, apic2, pin2); + setup_timer_IRQ0_pin(apic2, pin2, cfg->vector); + enable_8259A_irq(0); + if (timer_irq_works()) { + apic_printk(APIC_QUIET, KERN_INFO "....... works.\n"); + timer_through_8259 = 1; + if (nmi_watchdog == NMI_IO_APIC) { + disable_8259A_irq(0); + setup_nmi(); + enable_8259A_irq(0); + } + goto out; + } + /* + * Cleanup, just in case ... + */ + local_irq_disable(); + disable_8259A_irq(0); + clear_IO_APIC_pin(apic2, pin2); + apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n"); + } + + if (nmi_watchdog == NMI_IO_APIC) { + apic_printk(APIC_QUIET, KERN_WARNING "timer doesn't work " + "through the IO-APIC - disabling NMI Watchdog!\n"); + nmi_watchdog = NMI_NONE; + } +#ifdef CONFIG_X86_32 + timer_ack = 0; +#endif + + apic_printk(APIC_QUIET, KERN_INFO + "...trying to set up timer as Virtual Wire IRQ...\n"); + + lapic_register_intr(0, desc); + apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector); /* Fixed mode */ + enable_8259A_irq(0); + + if (timer_irq_works()) { + apic_printk(APIC_QUIET, KERN_INFO "..... works.\n"); + goto out; + } + local_irq_disable(); + disable_8259A_irq(0); + apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector); + apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n"); + + apic_printk(APIC_QUIET, KERN_INFO + "...trying to set up timer as ExtINT IRQ...\n"); + + init_8259A(0); + make_8259A_irq(0); + apic_write(APIC_LVT0, APIC_DM_EXTINT); + + unlock_ExtINT_logic(); + + if (timer_irq_works()) { + apic_printk(APIC_QUIET, KERN_INFO "..... works.\n"); + goto out; + } + local_irq_disable(); + apic_printk(APIC_QUIET, KERN_INFO "..... failed :(.\n"); + panic("IO-APIC + timer doesn't work! Boot with apic=debug and send a " + "report. Then try booting with the 'noapic' option.\n"); +out: + local_irq_restore(flags); +} + +/* + * Traditionally ISA IRQ2 is the cascade IRQ, and is not available + * to devices. However there may be an I/O APIC pin available for + * this interrupt regardless. The pin may be left unconnected, but + * typically it will be reused as an ExtINT cascade interrupt for + * the master 8259A. In the MPS case such a pin will normally be + * reported as an ExtINT interrupt in the MP table. With ACPI + * there is no provision for ExtINT interrupts, and in the absence + * of an override it would be treated as an ordinary ISA I/O APIC + * interrupt, that is edge-triggered and unmasked by default. We + * used to do this, but it caused problems on some systems because + * of the NMI watchdog and sometimes IRQ0 of the 8254 timer using + * the same ExtINT cascade interrupt to drive the local APIC of the + * bootstrap processor. Therefore we refrain from routing IRQ2 to + * the I/O APIC in all cases now. No actual device should request + * it anyway. --macro + */ +#define PIC_IRQS (1 << PIC_CASCADE_IR) + +void __init setup_IO_APIC(void) +{ + + /* + * calling enable_IO_APIC() is moved to setup_local_APIC for BP + */ + + io_apic_irqs = ~PIC_IRQS; + + apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n"); + /* + * Set up IO-APIC IRQ routing. + */ +#ifdef CONFIG_X86_32 + if (!acpi_ioapic) + setup_ioapic_ids_from_mpc(); +#endif + sync_Arb_IDs(); + setup_IO_APIC_irqs(); + init_IO_APIC_traps(); + check_timer(); +} + +/* + * Called after all the initialization is done. If we didnt find any + * APIC bugs then we can allow the modify fast path + */ + +static int __init io_apic_bug_finalize(void) +{ + if (sis_apic_bug == -1) + sis_apic_bug = 0; + return 0; +} + +late_initcall(io_apic_bug_finalize); + +struct sysfs_ioapic_data { + struct sys_device dev; + struct IO_APIC_route_entry entry[0]; +}; +static struct sysfs_ioapic_data * mp_ioapic_data[MAX_IO_APICS]; + +static int ioapic_suspend(struct sys_device *dev, pm_message_t state) +{ + struct IO_APIC_route_entry *entry; + struct sysfs_ioapic_data *data; + int i; + + data = container_of(dev, struct sysfs_ioapic_data, dev); + entry = data->entry; + for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) + *entry = ioapic_read_entry(dev->id, i); + + return 0; +} + +static int ioapic_resume(struct sys_device *dev) +{ + struct IO_APIC_route_entry *entry; + struct sysfs_ioapic_data *data; + unsigned long flags; + union IO_APIC_reg_00 reg_00; + int i; + + data = container_of(dev, struct sysfs_ioapic_data, dev); + entry = data->entry; + + spin_lock_irqsave(&ioapic_lock, flags); + reg_00.raw = io_apic_read(dev->id, 0); + if (reg_00.bits.ID != mp_ioapics[dev->id].apicid) { + reg_00.bits.ID = mp_ioapics[dev->id].apicid; + io_apic_write(dev->id, 0, reg_00.raw); + } + spin_unlock_irqrestore(&ioapic_lock, flags); + for (i = 0; i < nr_ioapic_registers[dev->id]; i++) + ioapic_write_entry(dev->id, i, entry[i]); + + return 0; +} + +static struct sysdev_class ioapic_sysdev_class = { + .name = "ioapic", + .suspend = ioapic_suspend, + .resume = ioapic_resume, +}; + +static int __init ioapic_init_sysfs(void) +{ + struct sys_device * dev; + int i, size, error; + + error = sysdev_class_register(&ioapic_sysdev_class); + if (error) + return error; + + for (i = 0; i < nr_ioapics; i++ ) { + size = sizeof(struct sys_device) + nr_ioapic_registers[i] + * sizeof(struct IO_APIC_route_entry); + mp_ioapic_data[i] = kzalloc(size, GFP_KERNEL); + if (!mp_ioapic_data[i]) { + printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i); + continue; + } + dev = &mp_ioapic_data[i]->dev; + dev->id = i; + dev->cls = &ioapic_sysdev_class; + error = sysdev_register(dev); + if (error) { + kfree(mp_ioapic_data[i]); + mp_ioapic_data[i] = NULL; + printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i); + continue; + } + } + + return 0; +} + +device_initcall(ioapic_init_sysfs); + +static int nr_irqs_gsi = NR_IRQS_LEGACY; +/* + * Dynamic irq allocate and deallocation + */ +unsigned int create_irq_nr(unsigned int irq_want) +{ + /* Allocate an unused irq */ + unsigned int irq; + unsigned int new; + unsigned long flags; + struct irq_cfg *cfg_new = NULL; + int cpu = boot_cpu_id; + struct irq_desc *desc_new = NULL; + + irq = 0; + if (irq_want < nr_irqs_gsi) + irq_want = nr_irqs_gsi; + + spin_lock_irqsave(&vector_lock, flags); + for (new = irq_want; new < nr_irqs; new++) { + desc_new = irq_to_desc_alloc_cpu(new, cpu); + if (!desc_new) { + printk(KERN_INFO "can not get irq_desc for %d\n", new); + continue; + } + cfg_new = desc_new->chip_data; + + if (cfg_new->vector != 0) + continue; + if (__assign_irq_vector(new, cfg_new, apic->target_cpus()) == 0) + irq = new; + break; + } + spin_unlock_irqrestore(&vector_lock, flags); + + if (irq > 0) { + dynamic_irq_init(irq); + /* restore it, in case dynamic_irq_init clear it */ + if (desc_new) + desc_new->chip_data = cfg_new; + } + return irq; +} + +int create_irq(void) +{ + unsigned int irq_want; + int irq; + + irq_want = nr_irqs_gsi; + irq = create_irq_nr(irq_want); + + if (irq == 0) + irq = -1; + + return irq; +} + +void destroy_irq(unsigned int irq) +{ + unsigned long flags; + struct irq_cfg *cfg; + struct irq_desc *desc; + + /* store it, in case dynamic_irq_cleanup clear it */ + desc = irq_to_desc(irq); + cfg = desc->chip_data; + dynamic_irq_cleanup(irq); + /* connect back irq_cfg */ + if (desc) + desc->chip_data = cfg; + +#ifdef CONFIG_INTR_REMAP + free_irte(irq); +#endif + spin_lock_irqsave(&vector_lock, flags); + __clear_irq_vector(irq, cfg); + spin_unlock_irqrestore(&vector_lock, flags); +} + +/* + * MSI message composition + */ +#ifdef CONFIG_PCI_MSI +static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg) +{ + struct irq_cfg *cfg; + int err; + unsigned dest; + + if (disable_apic) + return -ENXIO; + + cfg = irq_cfg(irq); + err = assign_irq_vector(irq, cfg, apic->target_cpus()); + if (err) + return err; + + dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); + +#ifdef CONFIG_INTR_REMAP + if (irq_remapped(irq)) { + struct irte irte; + int ir_index; + u16 sub_handle; + + ir_index = map_irq_to_irte_handle(irq, &sub_handle); + BUG_ON(ir_index == -1); + + memset (&irte, 0, sizeof(irte)); + + irte.present = 1; + irte.dst_mode = apic->irq_dest_mode; + irte.trigger_mode = 0; /* edge */ + irte.dlvry_mode = apic->irq_delivery_mode; + irte.vector = cfg->vector; + irte.dest_id = IRTE_DEST(dest); + + modify_irte(irq, &irte); + + msg->address_hi = MSI_ADDR_BASE_HI; + msg->data = sub_handle; + msg->address_lo = MSI_ADDR_BASE_LO | MSI_ADDR_IR_EXT_INT | + MSI_ADDR_IR_SHV | + MSI_ADDR_IR_INDEX1(ir_index) | + MSI_ADDR_IR_INDEX2(ir_index); + } else +#endif + { + msg->address_hi = MSI_ADDR_BASE_HI; + msg->address_lo = + MSI_ADDR_BASE_LO | + ((apic->irq_dest_mode == 0) ? + MSI_ADDR_DEST_MODE_PHYSICAL: + MSI_ADDR_DEST_MODE_LOGICAL) | + ((apic->irq_delivery_mode != dest_LowestPrio) ? + MSI_ADDR_REDIRECTION_CPU: + MSI_ADDR_REDIRECTION_LOWPRI) | + MSI_ADDR_DEST_ID(dest); + + msg->data = + MSI_DATA_TRIGGER_EDGE | + MSI_DATA_LEVEL_ASSERT | + ((apic->irq_delivery_mode != dest_LowestPrio) ? + MSI_DATA_DELIVERY_FIXED: + MSI_DATA_DELIVERY_LOWPRI) | + MSI_DATA_VECTOR(cfg->vector); + } + return err; +} + +#ifdef CONFIG_SMP +static void set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask) +{ + struct irq_desc *desc = irq_to_desc(irq); + struct irq_cfg *cfg; + struct msi_msg msg; + unsigned int dest; + + dest = set_desc_affinity(desc, mask); + if (dest == BAD_APICID) + return; + + cfg = desc->chip_data; + + read_msi_msg_desc(desc, &msg); + + msg.data &= ~MSI_DATA_VECTOR_MASK; + msg.data |= MSI_DATA_VECTOR(cfg->vector); + msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK; + msg.address_lo |= MSI_ADDR_DEST_ID(dest); + + write_msi_msg_desc(desc, &msg); +} +#ifdef CONFIG_INTR_REMAP +/* + * Migrate the MSI irq to another cpumask. This migration is + * done in the process context using interrupt-remapping hardware. + */ +static void +ir_set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask) +{ + struct irq_desc *desc = irq_to_desc(irq); + struct irq_cfg *cfg = desc->chip_data; + unsigned int dest; + struct irte irte; + + if (get_irte(irq, &irte)) + return; + + dest = set_desc_affinity(desc, mask); + if (dest == BAD_APICID) + return; + + irte.vector = cfg->vector; + irte.dest_id = IRTE_DEST(dest); + + /* + * atomically update the IRTE with the new destination and vector. + */ + modify_irte(irq, &irte); + + /* + * After this point, all the interrupts will start arriving + * at the new destination. So, time to cleanup the previous + * vector allocation. + */ + if (cfg->move_in_progress) + send_cleanup_vector(cfg); +} + +#endif +#endif /* CONFIG_SMP */ + +/* + * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices, + * which implement the MSI or MSI-X Capability Structure. + */ +static struct irq_chip msi_chip = { + .name = "PCI-MSI", + .unmask = unmask_msi_irq, + .mask = mask_msi_irq, + .ack = ack_apic_edge, +#ifdef CONFIG_SMP + .set_affinity = set_msi_irq_affinity, +#endif + .retrigger = ioapic_retrigger_irq, +}; + +#ifdef CONFIG_INTR_REMAP +static struct irq_chip msi_ir_chip = { + .name = "IR-PCI-MSI", + .unmask = unmask_msi_irq, + .mask = mask_msi_irq, + .ack = ack_x2apic_edge, +#ifdef CONFIG_SMP + .set_affinity = ir_set_msi_irq_affinity, +#endif + .retrigger = ioapic_retrigger_irq, +}; + +/* + * Map the PCI dev to the corresponding remapping hardware unit + * and allocate 'nvec' consecutive interrupt-remapping table entries + * in it. + */ +static int msi_alloc_irte(struct pci_dev *dev, int irq, int nvec) +{ + struct intel_iommu *iommu; + int index; + + iommu = map_dev_to_ir(dev); + if (!iommu) { + printk(KERN_ERR + "Unable to map PCI %s to iommu\n", pci_name(dev)); + return -ENOENT; + } + + index = alloc_irte(iommu, irq, nvec); + if (index < 0) { + printk(KERN_ERR + "Unable to allocate %d IRTE for PCI %s\n", nvec, + pci_name(dev)); + return -ENOSPC; + } + return index; +} +#endif + +static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq) +{ + int ret; + struct msi_msg msg; + + ret = msi_compose_msg(dev, irq, &msg); + if (ret < 0) + return ret; + + set_irq_msi(irq, msidesc); + write_msi_msg(irq, &msg); + +#ifdef CONFIG_INTR_REMAP + if (irq_remapped(irq)) { + struct irq_desc *desc = irq_to_desc(irq); + /* + * irq migration in process context + */ + desc->status |= IRQ_MOVE_PCNTXT; + set_irq_chip_and_handler_name(irq, &msi_ir_chip, handle_edge_irq, "edge"); + } else +#endif + set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge"); + + dev_printk(KERN_DEBUG, &dev->dev, "irq %d for MSI/MSI-X\n", irq); + + return 0; +} + +int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) +{ + unsigned int irq; + int ret, sub_handle; + struct msi_desc *msidesc; + unsigned int irq_want; + +#ifdef CONFIG_INTR_REMAP + struct intel_iommu *iommu = 0; + int index = 0; +#endif + + irq_want = nr_irqs_gsi; + sub_handle = 0; + list_for_each_entry(msidesc, &dev->msi_list, list) { + irq = create_irq_nr(irq_want); + if (irq == 0) + return -1; + irq_want = irq + 1; +#ifdef CONFIG_INTR_REMAP + if (!intr_remapping_enabled) + goto no_ir; + + if (!sub_handle) { + /* + * allocate the consecutive block of IRTE's + * for 'nvec' + */ + index = msi_alloc_irte(dev, irq, nvec); + if (index < 0) { + ret = index; + goto error; + } + } else { + iommu = map_dev_to_ir(dev); + if (!iommu) { + ret = -ENOENT; + goto error; + } + /* + * setup the mapping between the irq and the IRTE + * base index, the sub_handle pointing to the + * appropriate interrupt remap table entry. + */ + set_irte_irq(irq, iommu, index, sub_handle); + } +no_ir: +#endif + ret = setup_msi_irq(dev, msidesc, irq); + if (ret < 0) + goto error; + sub_handle++; + } + return 0; + +error: + destroy_irq(irq); + return ret; +} + +void arch_teardown_msi_irq(unsigned int irq) +{ + destroy_irq(irq); +} + +#ifdef CONFIG_DMAR +#ifdef CONFIG_SMP +static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask) +{ + struct irq_desc *desc = irq_to_desc(irq); + struct irq_cfg *cfg; + struct msi_msg msg; + unsigned int dest; + + dest = set_desc_affinity(desc, mask); + if (dest == BAD_APICID) + return; + + cfg = desc->chip_data; + + dmar_msi_read(irq, &msg); + + msg.data &= ~MSI_DATA_VECTOR_MASK; + msg.data |= MSI_DATA_VECTOR(cfg->vector); + msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK; + msg.address_lo |= MSI_ADDR_DEST_ID(dest); + + dmar_msi_write(irq, &msg); +} + +#endif /* CONFIG_SMP */ + +struct irq_chip dmar_msi_type = { + .name = "DMAR_MSI", + .unmask = dmar_msi_unmask, + .mask = dmar_msi_mask, + .ack = ack_apic_edge, +#ifdef CONFIG_SMP + .set_affinity = dmar_msi_set_affinity, +#endif + .retrigger = ioapic_retrigger_irq, +}; + +int arch_setup_dmar_msi(unsigned int irq) +{ + int ret; + struct msi_msg msg; + + ret = msi_compose_msg(NULL, irq, &msg); + if (ret < 0) + return ret; + dmar_msi_write(irq, &msg); + set_irq_chip_and_handler_name(irq, &dmar_msi_type, handle_edge_irq, + "edge"); + return 0; +} +#endif + +#ifdef CONFIG_HPET_TIMER + +#ifdef CONFIG_SMP +static void hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask) +{ + struct irq_desc *desc = irq_to_desc(irq); + struct irq_cfg *cfg; + struct msi_msg msg; + unsigned int dest; + + dest = set_desc_affinity(desc, mask); + if (dest == BAD_APICID) + return; + + cfg = desc->chip_data; + + hpet_msi_read(irq, &msg); + + msg.data &= ~MSI_DATA_VECTOR_MASK; + msg.data |= MSI_DATA_VECTOR(cfg->vector); + msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK; + msg.address_lo |= MSI_ADDR_DEST_ID(dest); + + hpet_msi_write(irq, &msg); +} + +#endif /* CONFIG_SMP */ + +struct irq_chip hpet_msi_type = { + .name = "HPET_MSI", + .unmask = hpet_msi_unmask, + .mask = hpet_msi_mask, + .ack = ack_apic_edge, +#ifdef CONFIG_SMP + .set_affinity = hpet_msi_set_affinity, +#endif + .retrigger = ioapic_retrigger_irq, +}; + +int arch_setup_hpet_msi(unsigned int irq) +{ + int ret; + struct msi_msg msg; + + ret = msi_compose_msg(NULL, irq, &msg); + if (ret < 0) + return ret; + + hpet_msi_write(irq, &msg); + set_irq_chip_and_handler_name(irq, &hpet_msi_type, handle_edge_irq, + "edge"); + + return 0; +} +#endif + +#endif /* CONFIG_PCI_MSI */ +/* + * Hypertransport interrupt support + */ +#ifdef CONFIG_HT_IRQ + +#ifdef CONFIG_SMP + +static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector) +{ + struct ht_irq_msg msg; + fetch_ht_irq_msg(irq, &msg); + + msg.address_lo &= ~(HT_IRQ_LOW_VECTOR_MASK | HT_IRQ_LOW_DEST_ID_MASK); + msg.address_hi &= ~(HT_IRQ_HIGH_DEST_ID_MASK); + + msg.address_lo |= HT_IRQ_LOW_VECTOR(vector) | HT_IRQ_LOW_DEST_ID(dest); + msg.address_hi |= HT_IRQ_HIGH_DEST_ID(dest); + + write_ht_irq_msg(irq, &msg); +} + +static void set_ht_irq_affinity(unsigned int irq, const struct cpumask *mask) +{ + struct irq_desc *desc = irq_to_desc(irq); + struct irq_cfg *cfg; + unsigned int dest; + + dest = set_desc_affinity(desc, mask); + if (dest == BAD_APICID) + return; + + cfg = desc->chip_data; + + target_ht_irq(irq, dest, cfg->vector); +} + +#endif + +static struct irq_chip ht_irq_chip = { + .name = "PCI-HT", + .mask = mask_ht_irq, + .unmask = unmask_ht_irq, + .ack = ack_apic_edge, +#ifdef CONFIG_SMP + .set_affinity = set_ht_irq_affinity, +#endif + .retrigger = ioapic_retrigger_irq, +}; + +int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) +{ + struct irq_cfg *cfg; + int err; + + if (disable_apic) + return -ENXIO; + + cfg = irq_cfg(irq); + err = assign_irq_vector(irq, cfg, apic->target_cpus()); + if (!err) { + struct ht_irq_msg msg; + unsigned dest; + + dest = apic->cpu_mask_to_apicid_and(cfg->domain, + apic->target_cpus()); + + msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest); + + msg.address_lo = + HT_IRQ_LOW_BASE | + HT_IRQ_LOW_DEST_ID(dest) | + HT_IRQ_LOW_VECTOR(cfg->vector) | + ((apic->irq_dest_mode == 0) ? + HT_IRQ_LOW_DM_PHYSICAL : + HT_IRQ_LOW_DM_LOGICAL) | + HT_IRQ_LOW_RQEOI_EDGE | + ((apic->irq_delivery_mode != dest_LowestPrio) ? + HT_IRQ_LOW_MT_FIXED : + HT_IRQ_LOW_MT_ARBITRATED) | + HT_IRQ_LOW_IRQ_MASKED; + + write_ht_irq_msg(irq, &msg); + + set_irq_chip_and_handler_name(irq, &ht_irq_chip, + handle_edge_irq, "edge"); + + dev_printk(KERN_DEBUG, &dev->dev, "irq %d for HT\n", irq); + } + return err; +} +#endif /* CONFIG_HT_IRQ */ + +#ifdef CONFIG_X86_UV +/* + * Re-target the irq to the specified CPU and enable the specified MMR located + * on the specified blade to allow the sending of MSIs to the specified CPU. + */ +int arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, + unsigned long mmr_offset) +{ + const struct cpumask *eligible_cpu = cpumask_of(cpu); + struct irq_cfg *cfg; + int mmr_pnode; + unsigned long mmr_value; + struct uv_IO_APIC_route_entry *entry; + unsigned long flags; + int err; + + cfg = irq_cfg(irq); + + err = assign_irq_vector(irq, cfg, eligible_cpu); + if (err != 0) + return err; + + spin_lock_irqsave(&vector_lock, flags); + set_irq_chip_and_handler_name(irq, &uv_irq_chip, handle_percpu_irq, + irq_name); + spin_unlock_irqrestore(&vector_lock, flags); + + mmr_value = 0; + entry = (struct uv_IO_APIC_route_entry *)&mmr_value; + BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long)); + + entry->vector = cfg->vector; + entry->delivery_mode = apic->irq_delivery_mode; + entry->dest_mode = apic->irq_dest_mode; + entry->polarity = 0; + entry->trigger = 0; + entry->mask = 0; + entry->dest = apic->cpu_mask_to_apicid(eligible_cpu); + + mmr_pnode = uv_blade_to_pnode(mmr_blade); + uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value); + + return irq; +} + +/* + * Disable the specified MMR located on the specified blade so that MSIs are + * longer allowed to be sent. + */ +void arch_disable_uv_irq(int mmr_blade, unsigned long mmr_offset) +{ + unsigned long mmr_value; + struct uv_IO_APIC_route_entry *entry; + int mmr_pnode; + + mmr_value = 0; + entry = (struct uv_IO_APIC_route_entry *)&mmr_value; + BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long)); + + entry->mask = 1; + + mmr_pnode = uv_blade_to_pnode(mmr_blade); + uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value); +} +#endif /* CONFIG_X86_64 */ + +int __init io_apic_get_redir_entries (int ioapic) +{ + union IO_APIC_reg_01 reg_01; + unsigned long flags; + + spin_lock_irqsave(&ioapic_lock, flags); + reg_01.raw = io_apic_read(ioapic, 1); + spin_unlock_irqrestore(&ioapic_lock, flags); + + return reg_01.bits.entries; +} + +void __init probe_nr_irqs_gsi(void) +{ + int nr = 0; + + nr = acpi_probe_gsi(); + if (nr > nr_irqs_gsi) { + nr_irqs_gsi = nr; + } else { + /* for acpi=off or acpi is not compiled in */ + int idx; + + nr = 0; + for (idx = 0; idx < nr_ioapics; idx++) + nr += io_apic_get_redir_entries(idx) + 1; + + if (nr > nr_irqs_gsi) + nr_irqs_gsi = nr; + } + + printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi); +} + +#ifdef CONFIG_SPARSE_IRQ +int __init arch_probe_nr_irqs(void) +{ + int nr; + + if (nr_irqs > (NR_VECTORS * nr_cpu_ids)) + nr_irqs = NR_VECTORS * nr_cpu_ids; + + nr = nr_irqs_gsi + 8 * nr_cpu_ids; +#if defined(CONFIG_PCI_MSI) || defined(CONFIG_HT_IRQ) + /* + * for MSI and HT dyn irq + */ + nr += nr_irqs_gsi * 16; +#endif + if (nr < nr_irqs) + nr_irqs = nr; + + return 0; +} +#endif + +/* -------------------------------------------------------------------------- + ACPI-based IOAPIC Configuration + -------------------------------------------------------------------------- */ + +#ifdef CONFIG_ACPI + +#ifdef CONFIG_X86_32 +int __init io_apic_get_unique_id(int ioapic, int apic_id) +{ + union IO_APIC_reg_00 reg_00; + static physid_mask_t apic_id_map = PHYSID_MASK_NONE; + physid_mask_t tmp; + unsigned long flags; + int i = 0; + + /* + * The P4 platform supports up to 256 APIC IDs on two separate APIC + * buses (one for LAPICs, one for IOAPICs), where predecessors only + * supports up to 16 on one shared APIC bus. + * + * TBD: Expand LAPIC/IOAPIC support on P4-class systems to take full + * advantage of new APIC bus architecture. + */ + + if (physids_empty(apic_id_map)) + apic_id_map = apic->ioapic_phys_id_map(phys_cpu_present_map); + + spin_lock_irqsave(&ioapic_lock, flags); + reg_00.raw = io_apic_read(ioapic, 0); + spin_unlock_irqrestore(&ioapic_lock, flags); + + if (apic_id >= get_physical_broadcast()) { + printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying " + "%d\n", ioapic, apic_id, reg_00.bits.ID); + apic_id = reg_00.bits.ID; + } + + /* + * Every APIC in a system must have a unique ID or we get lots of nice + * 'stuck on smp_invalidate_needed IPI wait' messages. + */ + if (apic->check_apicid_used(apic_id_map, apic_id)) { + + for (i = 0; i < get_physical_broadcast(); i++) { + if (!apic->check_apicid_used(apic_id_map, i)) + break; + } + + if (i == get_physical_broadcast()) + panic("Max apic_id exceeded!\n"); + + printk(KERN_WARNING "IOAPIC[%d]: apic_id %d already used, " + "trying %d\n", ioapic, apic_id, i); + + apic_id = i; + } + + tmp = apic->apicid_to_cpu_present(apic_id); + physids_or(apic_id_map, apic_id_map, tmp); + + if (reg_00.bits.ID != apic_id) { + reg_00.bits.ID = apic_id; + + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(ioapic, 0, reg_00.raw); + reg_00.raw = io_apic_read(ioapic, 0); + spin_unlock_irqrestore(&ioapic_lock, flags); + + /* Sanity check */ + if (reg_00.bits.ID != apic_id) { + printk("IOAPIC[%d]: Unable to change apic_id!\n", ioapic); + return -1; + } + } + + apic_printk(APIC_VERBOSE, KERN_INFO + "IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id); + + return apic_id; +} + +int __init io_apic_get_version(int ioapic) +{ + union IO_APIC_reg_01 reg_01; + unsigned long flags; + + spin_lock_irqsave(&ioapic_lock, flags); + reg_01.raw = io_apic_read(ioapic, 1); + spin_unlock_irqrestore(&ioapic_lock, flags); + + return reg_01.bits.version; +} +#endif + +int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int polarity) +{ + struct irq_desc *desc; + struct irq_cfg *cfg; + int cpu = boot_cpu_id; + + if (!IO_APIC_IRQ(irq)) { + apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n", + ioapic); + return -EINVAL; + } + + desc = irq_to_desc_alloc_cpu(irq, cpu); + if (!desc) { + printk(KERN_INFO "can not get irq_desc %d\n", irq); + return 0; + } + + /* + * IRQs < 16 are already in the irq_2_pin[] map + */ + if (irq >= NR_IRQS_LEGACY) { + cfg = desc->chip_data; + add_pin_to_irq_cpu(cfg, cpu, ioapic, pin); + } + + setup_IO_APIC_irq(ioapic, pin, irq, desc, triggering, polarity); + + return 0; +} + + +int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity) +{ + int i; + + if (skip_ioapic_setup) + return -1; + + for (i = 0; i < mp_irq_entries; i++) + if (mp_irqs[i].irqtype == mp_INT && + mp_irqs[i].srcbusirq == bus_irq) + break; + if (i >= mp_irq_entries) + return -1; + + *trigger = irq_trigger(i); + *polarity = irq_polarity(i); + return 0; +} + +#endif /* CONFIG_ACPI */ + +/* + * This function currently is only a helper for the i386 smp boot process where + * we need to reprogram the ioredtbls to cater for the cpus which have come online + * so mask in all cases should simply be apic->target_cpus() + */ +#ifdef CONFIG_SMP +void __init setup_ioapic_dest(void) +{ + int pin, ioapic, irq, irq_entry; + struct irq_desc *desc; + struct irq_cfg *cfg; + const struct cpumask *mask; + + if (skip_ioapic_setup == 1) + return; + + for (ioapic = 0; ioapic < nr_ioapics; ioapic++) { + for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) { + irq_entry = find_irq_entry(ioapic, pin, mp_INT); + if (irq_entry == -1) + continue; + irq = pin_2_irq(irq_entry, ioapic, pin); + + /* setup_IO_APIC_irqs could fail to get vector for some device + * when you have too many devices, because at that time only boot + * cpu is online. + */ + desc = irq_to_desc(irq); + cfg = desc->chip_data; + if (!cfg->vector) { + setup_IO_APIC_irq(ioapic, pin, irq, desc, + irq_trigger(irq_entry), + irq_polarity(irq_entry)); + continue; + + } + + /* + * Honour affinities which have been set in early boot + */ + if (desc->status & + (IRQ_NO_BALANCING | IRQ_AFFINITY_SET)) + mask = desc->affinity; + else + mask = apic->target_cpus(); + +#ifdef CONFIG_INTR_REMAP + if (intr_remapping_enabled) + set_ir_ioapic_affinity_irq_desc(desc, mask); + else +#endif + set_ioapic_affinity_irq_desc(desc, mask); + } + + } +} +#endif + +#define IOAPIC_RESOURCE_NAME_SIZE 11 + +static struct resource *ioapic_resources; + +static struct resource * __init ioapic_setup_resources(void) +{ + unsigned long n; + struct resource *res; + char *mem; + int i; + + if (nr_ioapics <= 0) + return NULL; + + n = IOAPIC_RESOURCE_NAME_SIZE + sizeof(struct resource); + n *= nr_ioapics; + + mem = alloc_bootmem(n); + res = (void *)mem; + + if (mem != NULL) { + mem += sizeof(struct resource) * nr_ioapics; + + for (i = 0; i < nr_ioapics; i++) { + res[i].name = mem; + res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY; + sprintf(mem, "IOAPIC %u", i); + mem += IOAPIC_RESOURCE_NAME_SIZE; + } + } + + ioapic_resources = res; + + return res; +} + +void __init ioapic_init_mappings(void) +{ + unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0; + struct resource *ioapic_res; + int i; + + ioapic_res = ioapic_setup_resources(); + for (i = 0; i < nr_ioapics; i++) { + if (smp_found_config) { + ioapic_phys = mp_ioapics[i].apicaddr; +#ifdef CONFIG_X86_32 + if (!ioapic_phys) { + printk(KERN_ERR + "WARNING: bogus zero IO-APIC " + "address found in MPTABLE, " + "disabling IO/APIC support!\n"); + smp_found_config = 0; + skip_ioapic_setup = 1; + goto fake_ioapic_page; + } +#endif + } else { +#ifdef CONFIG_X86_32 +fake_ioapic_page: +#endif + ioapic_phys = (unsigned long) + alloc_bootmem_pages(PAGE_SIZE); + ioapic_phys = __pa(ioapic_phys); + } + set_fixmap_nocache(idx, ioapic_phys); + apic_printk(APIC_VERBOSE, + "mapped IOAPIC to %08lx (%08lx)\n", + __fix_to_virt(idx), ioapic_phys); + idx++; + + if (ioapic_res != NULL) { + ioapic_res->start = ioapic_phys; + ioapic_res->end = ioapic_phys + (4 * 1024) - 1; + ioapic_res++; + } + } +} + +static int __init ioapic_insert_resources(void) +{ + int i; + struct resource *r = ioapic_resources; + + if (!r) { + printk(KERN_ERR + "IO APIC resources could be not be allocated.\n"); + return -1; + } + + for (i = 0; i < nr_ioapics; i++) { + insert_resource(&iomem_resource, r); + r++; + } + + return 0; +} + +/* Insert the IO APIC resources after PCI initialization has occured to handle + * IO APICS that are mapped in on a BAR in PCI space. */ +late_initcall(ioapic_insert_resources); diff --git a/arch/x86/kernel/apic/ipi.c b/arch/x86/kernel/apic/ipi.c new file mode 100644 index 00000000000..dbf5445727a --- /dev/null +++ b/arch/x86/kernel/apic/ipi.c @@ -0,0 +1,164 @@ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +void default_send_IPI_mask_sequence_phys(const struct cpumask *mask, int vector) +{ + unsigned long query_cpu; + unsigned long flags; + + /* + * Hack. The clustered APIC addressing mode doesn't allow us to send + * to an arbitrary mask, so I do a unicast to each CPU instead. + * - mbligh + */ + local_irq_save(flags); + for_each_cpu(query_cpu, mask) { + __default_send_IPI_dest_field(per_cpu(x86_cpu_to_apicid, + query_cpu), vector, APIC_DEST_PHYSICAL); + } + local_irq_restore(flags); +} + +void default_send_IPI_mask_allbutself_phys(const struct cpumask *mask, + int vector) +{ + unsigned int this_cpu = smp_processor_id(); + unsigned int query_cpu; + unsigned long flags; + + /* See Hack comment above */ + + local_irq_save(flags); + for_each_cpu(query_cpu, mask) { + if (query_cpu == this_cpu) + continue; + __default_send_IPI_dest_field(per_cpu(x86_cpu_to_apicid, + query_cpu), vector, APIC_DEST_PHYSICAL); + } + local_irq_restore(flags); +} + +void default_send_IPI_mask_sequence_logical(const struct cpumask *mask, + int vector) +{ + unsigned long flags; + unsigned int query_cpu; + + /* + * Hack. The clustered APIC addressing mode doesn't allow us to send + * to an arbitrary mask, so I do a unicasts to each CPU instead. This + * should be modified to do 1 message per cluster ID - mbligh + */ + + local_irq_save(flags); + for_each_cpu(query_cpu, mask) + __default_send_IPI_dest_field( + apic->cpu_to_logical_apicid(query_cpu), vector, + apic->dest_logical); + local_irq_restore(flags); +} + +void default_send_IPI_mask_allbutself_logical(const struct cpumask *mask, + int vector) +{ + unsigned long flags; + unsigned int query_cpu; + unsigned int this_cpu = smp_processor_id(); + + /* See Hack comment above */ + + local_irq_save(flags); + for_each_cpu(query_cpu, mask) { + if (query_cpu == this_cpu) + continue; + __default_send_IPI_dest_field( + apic->cpu_to_logical_apicid(query_cpu), vector, + apic->dest_logical); + } + local_irq_restore(flags); +} + +#ifdef CONFIG_X86_32 + +/* + * This is only used on smaller machines. + */ +void default_send_IPI_mask_logical(const struct cpumask *cpumask, int vector) +{ + unsigned long mask = cpumask_bits(cpumask)[0]; + unsigned long flags; + + local_irq_save(flags); + WARN_ON(mask & ~cpumask_bits(cpu_online_mask)[0]); + __default_send_IPI_dest_field(mask, vector, apic->dest_logical); + local_irq_restore(flags); +} + +void default_send_IPI_allbutself(int vector) +{ + /* + * if there are no other CPUs in the system then we get an APIC send + * error if we try to broadcast, thus avoid sending IPIs in this case. + */ + if (!(num_online_cpus() > 1)) + return; + + __default_local_send_IPI_allbutself(vector); +} + +void default_send_IPI_all(int vector) +{ + __default_local_send_IPI_all(vector); +} + +void default_send_IPI_self(int vector) +{ + __default_send_IPI_shortcut(APIC_DEST_SELF, vector, apic->dest_logical); +} + +/* must come after the send_IPI functions above for inlining */ +static int convert_apicid_to_cpu(int apic_id) +{ + int i; + + for_each_possible_cpu(i) { + if (per_cpu(x86_cpu_to_apicid, i) == apic_id) + return i; + } + return -1; +} + +int safe_smp_processor_id(void) +{ + int apicid, cpuid; + + if (!boot_cpu_has(X86_FEATURE_APIC)) + return 0; + + apicid = hard_smp_processor_id(); + if (apicid == BAD_APICID) + return 0; + + cpuid = convert_apicid_to_cpu(apicid); + + return cpuid >= 0 ? cpuid : 0; +} +#endif diff --git a/arch/x86/kernel/apic/nmi.c b/arch/x86/kernel/apic/nmi.c new file mode 100644 index 00000000000..bdfad80c3cf --- /dev/null +++ b/arch/x86/kernel/apic/nmi.c @@ -0,0 +1,564 @@ +/* + * NMI watchdog support on APIC systems + * + * Started by Ingo Molnar + * + * Fixes: + * Mikael Pettersson : AMD K7 support for local APIC NMI watchdog. + * Mikael Pettersson : Power Management for local APIC NMI watchdog. + * Mikael Pettersson : Pentium 4 support for local APIC NMI watchdog. + * Pavel Machek and + * Mikael Pettersson : PM converted to driver model. Disable/enable API. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include + +int unknown_nmi_panic; +int nmi_watchdog_enabled; + +static cpumask_t backtrace_mask = CPU_MASK_NONE; + +/* nmi_active: + * >0: the lapic NMI watchdog is active, but can be disabled + * <0: the lapic NMI watchdog has not been set up, and cannot + * be enabled + * 0: the lapic NMI watchdog is disabled, but can be enabled + */ +atomic_t nmi_active = ATOMIC_INIT(0); /* oprofile uses this */ +EXPORT_SYMBOL(nmi_active); + +unsigned int nmi_watchdog = NMI_NONE; +EXPORT_SYMBOL(nmi_watchdog); + +static int panic_on_timeout; + +static unsigned int nmi_hz = HZ; +static DEFINE_PER_CPU(short, wd_enabled); +static int endflag __initdata; + +static inline unsigned int get_nmi_count(int cpu) +{ + return per_cpu(irq_stat, cpu).__nmi_count; +} + +static inline int mce_in_progress(void) +{ +#if defined(CONFIG_X86_64) && defined(CONFIG_X86_MCE) + return atomic_read(&mce_entry) > 0; +#endif + return 0; +} + +/* + * Take the local apic timer and PIT/HPET into account. We don't + * know which one is active, when we have highres/dyntick on + */ +static inline unsigned int get_timer_irqs(int cpu) +{ + return per_cpu(irq_stat, cpu).apic_timer_irqs + + per_cpu(irq_stat, cpu).irq0_irqs; +} + +#ifdef CONFIG_SMP +/* + * The performance counters used by NMI_LOCAL_APIC don't trigger when + * the CPU is idle. To make sure the NMI watchdog really ticks on all + * CPUs during the test make them busy. + */ +static __init void nmi_cpu_busy(void *data) +{ + local_irq_enable_in_hardirq(); + /* + * Intentionally don't use cpu_relax here. This is + * to make sure that the performance counter really ticks, + * even if there is a simulator or similar that catches the + * pause instruction. On a real HT machine this is fine because + * all other CPUs are busy with "useless" delay loops and don't + * care if they get somewhat less cycles. + */ + while (endflag == 0) + mb(); +} +#endif + +static void report_broken_nmi(int cpu, int *prev_nmi_count) +{ + printk(KERN_CONT "\n"); + + printk(KERN_WARNING + "WARNING: CPU#%d: NMI appears to be stuck (%d->%d)!\n", + cpu, prev_nmi_count[cpu], get_nmi_count(cpu)); + + printk(KERN_WARNING + "Please report this to bugzilla.kernel.org,\n"); + printk(KERN_WARNING + "and attach the output of the 'dmesg' command.\n"); + + per_cpu(wd_enabled, cpu) = 0; + atomic_dec(&nmi_active); +} + +static void __acpi_nmi_disable(void *__unused) +{ + apic_write(APIC_LVT0, APIC_DM_NMI | APIC_LVT_MASKED); +} + +int __init check_nmi_watchdog(void) +{ + unsigned int *prev_nmi_count; + int cpu; + + if (!nmi_watchdog_active() || !atomic_read(&nmi_active)) + return 0; + + prev_nmi_count = kmalloc(nr_cpu_ids * sizeof(int), GFP_KERNEL); + if (!prev_nmi_count) + goto error; + + printk(KERN_INFO "Testing NMI watchdog ... "); + +#ifdef CONFIG_SMP + if (nmi_watchdog == NMI_LOCAL_APIC) + smp_call_function(nmi_cpu_busy, (void *)&endflag, 0); +#endif + + for_each_possible_cpu(cpu) + prev_nmi_count[cpu] = get_nmi_count(cpu); + local_irq_enable(); + mdelay((20 * 1000) / nmi_hz); /* wait 20 ticks */ + + for_each_online_cpu(cpu) { + if (!per_cpu(wd_enabled, cpu)) + continue; + if (get_nmi_count(cpu) - prev_nmi_count[cpu] <= 5) + report_broken_nmi(cpu, prev_nmi_count); + } + endflag = 1; + if (!atomic_read(&nmi_active)) { + kfree(prev_nmi_count); + atomic_set(&nmi_active, -1); + goto error; + } + printk("OK.\n"); + + /* + * now that we know it works we can reduce NMI frequency to + * something more reasonable; makes a difference in some configs + */ + if (nmi_watchdog == NMI_LOCAL_APIC) + nmi_hz = lapic_adjust_nmi_hz(1); + + kfree(prev_nmi_count); + return 0; +error: + if (nmi_watchdog == NMI_IO_APIC) { + if (!timer_through_8259) + disable_8259A_irq(0); + on_each_cpu(__acpi_nmi_disable, NULL, 1); + } + +#ifdef CONFIG_X86_32 + timer_ack = 0; +#endif + return -1; +} + +static int __init setup_nmi_watchdog(char *str) +{ + unsigned int nmi; + + if (!strncmp(str, "panic", 5)) { + panic_on_timeout = 1; + str = strchr(str, ','); + if (!str) + return 1; + ++str; + } + + if (!strncmp(str, "lapic", 5)) + nmi_watchdog = NMI_LOCAL_APIC; + else if (!strncmp(str, "ioapic", 6)) + nmi_watchdog = NMI_IO_APIC; + else { + get_option(&str, &nmi); + if (nmi >= NMI_INVALID) + return 0; + nmi_watchdog = nmi; + } + + return 1; +} +__setup("nmi_watchdog=", setup_nmi_watchdog); + +/* + * Suspend/resume support + */ +#ifdef CONFIG_PM + +static int nmi_pm_active; /* nmi_active before suspend */ + +static int lapic_nmi_suspend(struct sys_device *dev, pm_message_t state) +{ + /* only CPU0 goes here, other CPUs should be offline */ + nmi_pm_active = atomic_read(&nmi_active); + stop_apic_nmi_watchdog(NULL); + BUG_ON(atomic_read(&nmi_active) != 0); + return 0; +} + +static int lapic_nmi_resume(struct sys_device *dev) +{ + /* only CPU0 goes here, other CPUs should be offline */ + if (nmi_pm_active > 0) { + setup_apic_nmi_watchdog(NULL); + touch_nmi_watchdog(); + } + return 0; +} + +static struct sysdev_class nmi_sysclass = { + .name = "lapic_nmi", + .resume = lapic_nmi_resume, + .suspend = lapic_nmi_suspend, +}; + +static struct sys_device device_lapic_nmi = { + .id = 0, + .cls = &nmi_sysclass, +}; + +static int __init init_lapic_nmi_sysfs(void) +{ + int error; + + /* + * should really be a BUG_ON but b/c this is an + * init call, it just doesn't work. -dcz + */ + if (nmi_watchdog != NMI_LOCAL_APIC) + return 0; + + if (atomic_read(&nmi_active) < 0) + return 0; + + error = sysdev_class_register(&nmi_sysclass); + if (!error) + error = sysdev_register(&device_lapic_nmi); + return error; +} + +/* must come after the local APIC's device_initcall() */ +late_initcall(init_lapic_nmi_sysfs); + +#endif /* CONFIG_PM */ + +static void __acpi_nmi_enable(void *__unused) +{ + apic_write(APIC_LVT0, APIC_DM_NMI); +} + +/* + * Enable timer based NMIs on all CPUs: + */ +void acpi_nmi_enable(void) +{ + if (atomic_read(&nmi_active) && nmi_watchdog == NMI_IO_APIC) + on_each_cpu(__acpi_nmi_enable, NULL, 1); +} + +/* + * Disable timer based NMIs on all CPUs: + */ +void acpi_nmi_disable(void) +{ + if (atomic_read(&nmi_active) && nmi_watchdog == NMI_IO_APIC) + on_each_cpu(__acpi_nmi_disable, NULL, 1); +} + +/* + * This function is called as soon the LAPIC NMI watchdog driver has everything + * in place and it's ready to check if the NMIs belong to the NMI watchdog + */ +void cpu_nmi_set_wd_enabled(void) +{ + __get_cpu_var(wd_enabled) = 1; +} + +void setup_apic_nmi_watchdog(void *unused) +{ + if (__get_cpu_var(wd_enabled)) + return; + + /* cheap hack to support suspend/resume */ + /* if cpu0 is not active neither should the other cpus */ + if (smp_processor_id() != 0 && atomic_read(&nmi_active) <= 0) + return; + + switch (nmi_watchdog) { + case NMI_LOCAL_APIC: + if (lapic_watchdog_init(nmi_hz) < 0) { + __get_cpu_var(wd_enabled) = 0; + return; + } + /* FALL THROUGH */ + case NMI_IO_APIC: + __get_cpu_var(wd_enabled) = 1; + atomic_inc(&nmi_active); + } +} + +void stop_apic_nmi_watchdog(void *unused) +{ + /* only support LOCAL and IO APICs for now */ + if (!nmi_watchdog_active()) + return; + if (__get_cpu_var(wd_enabled) == 0) + return; + if (nmi_watchdog == NMI_LOCAL_APIC) + lapic_watchdog_stop(); + else + __acpi_nmi_disable(NULL); + __get_cpu_var(wd_enabled) = 0; + atomic_dec(&nmi_active); +} + +/* + * the best way to detect whether a CPU has a 'hard lockup' problem + * is to check it's local APIC timer IRQ counts. If they are not + * changing then that CPU has some problem. + * + * as these watchdog NMI IRQs are generated on every CPU, we only + * have to check the current processor. + * + * since NMIs don't listen to _any_ locks, we have to be extremely + * careful not to rely on unsafe variables. The printk might lock + * up though, so we have to break up any console locks first ... + * [when there will be more tty-related locks, break them up here too!] + */ + +static DEFINE_PER_CPU(unsigned, last_irq_sum); +static DEFINE_PER_CPU(local_t, alert_counter); +static DEFINE_PER_CPU(int, nmi_touch); + +void touch_nmi_watchdog(void) +{ + if (nmi_watchdog_active()) { + unsigned cpu; + + /* + * Tell other CPUs to reset their alert counters. We cannot + * do it ourselves because the alert count increase is not + * atomic. + */ + for_each_present_cpu(cpu) { + if (per_cpu(nmi_touch, cpu) != 1) + per_cpu(nmi_touch, cpu) = 1; + } + } + + /* + * Tickle the softlockup detector too: + */ + touch_softlockup_watchdog(); +} +EXPORT_SYMBOL(touch_nmi_watchdog); + +notrace __kprobes int +nmi_watchdog_tick(struct pt_regs *regs, unsigned reason) +{ + /* + * Since current_thread_info()-> is always on the stack, and we + * always switch the stack NMI-atomically, it's safe to use + * smp_processor_id(). + */ + unsigned int sum; + int touched = 0; + int cpu = smp_processor_id(); + int rc = 0; + + /* check for other users first */ + if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) + == NOTIFY_STOP) { + rc = 1; + touched = 1; + } + + sum = get_timer_irqs(cpu); + + if (__get_cpu_var(nmi_touch)) { + __get_cpu_var(nmi_touch) = 0; + touched = 1; + } + + if (cpu_isset(cpu, backtrace_mask)) { + static DEFINE_SPINLOCK(lock); /* Serialise the printks */ + + spin_lock(&lock); + printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu); + dump_stack(); + spin_unlock(&lock); + cpu_clear(cpu, backtrace_mask); + } + + /* Could check oops_in_progress here too, but it's safer not to */ + if (mce_in_progress()) + touched = 1; + + /* if the none of the timers isn't firing, this cpu isn't doing much */ + if (!touched && __get_cpu_var(last_irq_sum) == sum) { + /* + * Ayiee, looks like this CPU is stuck ... + * wait a few IRQs (5 seconds) before doing the oops ... + */ + local_inc(&__get_cpu_var(alert_counter)); + if (local_read(&__get_cpu_var(alert_counter)) == 5 * nmi_hz) + /* + * die_nmi will return ONLY if NOTIFY_STOP happens.. + */ + die_nmi("BUG: NMI Watchdog detected LOCKUP", + regs, panic_on_timeout); + } else { + __get_cpu_var(last_irq_sum) = sum; + local_set(&__get_cpu_var(alert_counter), 0); + } + + /* see if the nmi watchdog went off */ + if (!__get_cpu_var(wd_enabled)) + return rc; + switch (nmi_watchdog) { + case NMI_LOCAL_APIC: + rc |= lapic_wd_event(nmi_hz); + break; + case NMI_IO_APIC: + /* + * don't know how to accurately check for this. + * just assume it was a watchdog timer interrupt + * This matches the old behaviour. + */ + rc = 1; + break; + } + return rc; +} + +#ifdef CONFIG_SYSCTL + +static void enable_ioapic_nmi_watchdog_single(void *unused) +{ + __get_cpu_var(wd_enabled) = 1; + atomic_inc(&nmi_active); + __acpi_nmi_enable(NULL); +} + +static void enable_ioapic_nmi_watchdog(void) +{ + on_each_cpu(enable_ioapic_nmi_watchdog_single, NULL, 1); + touch_nmi_watchdog(); +} + +static void disable_ioapic_nmi_watchdog(void) +{ + on_each_cpu(stop_apic_nmi_watchdog, NULL, 1); +} + +static int __init setup_unknown_nmi_panic(char *str) +{ + unknown_nmi_panic = 1; + return 1; +} +__setup("unknown_nmi_panic", setup_unknown_nmi_panic); + +static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu) +{ + unsigned char reason = get_nmi_reason(); + char buf[64]; + + sprintf(buf, "NMI received for unknown reason %02x\n", reason); + die_nmi(buf, regs, 1); /* Always panic here */ + return 0; +} + +/* + * proc handler for /proc/sys/kernel/nmi + */ +int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, + void __user *buffer, size_t *length, loff_t *ppos) +{ + int old_state; + + nmi_watchdog_enabled = (atomic_read(&nmi_active) > 0) ? 1 : 0; + old_state = nmi_watchdog_enabled; + proc_dointvec(table, write, file, buffer, length, ppos); + if (!!old_state == !!nmi_watchdog_enabled) + return 0; + + if (atomic_read(&nmi_active) < 0 || !nmi_watchdog_active()) { + printk(KERN_WARNING + "NMI watchdog is permanently disabled\n"); + return -EIO; + } + + if (nmi_watchdog == NMI_LOCAL_APIC) { + if (nmi_watchdog_enabled) + enable_lapic_nmi_watchdog(); + else + disable_lapic_nmi_watchdog(); + } else if (nmi_watchdog == NMI_IO_APIC) { + if (nmi_watchdog_enabled) + enable_ioapic_nmi_watchdog(); + else + disable_ioapic_nmi_watchdog(); + } else { + printk(KERN_WARNING + "NMI watchdog doesn't know what hardware to touch\n"); + return -EIO; + } + return 0; +} + +#endif /* CONFIG_SYSCTL */ + +int do_nmi_callback(struct pt_regs *regs, int cpu) +{ +#ifdef CONFIG_SYSCTL + if (unknown_nmi_panic) + return unknown_nmi_panic_callback(regs, cpu); +#endif + return 0; +} + +void __trigger_all_cpu_backtrace(void) +{ + int i; + + backtrace_mask = cpu_online_map; + /* Wait for up to 10 seconds for all CPUs to do the backtrace */ + for (i = 0; i < 10 * 1000; i++) { + if (cpus_empty(backtrace_mask)) + break; + mdelay(1); + } +} diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c new file mode 100644 index 00000000000..4e39d9ad4d5 --- /dev/null +++ b/arch/x86/kernel/apic/x2apic_cluster.c @@ -0,0 +1,243 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +DEFINE_PER_CPU(u32, x86_cpu_to_logical_apicid); + +static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id) +{ + if (cpu_has_x2apic) + return 1; + + return 0; +} + +/* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */ + +static const struct cpumask *x2apic_target_cpus(void) +{ + return cpumask_of(0); +} + +/* + * for now each logical cpu is in its own vector allocation domain. + */ +static void x2apic_vector_allocation_domain(int cpu, struct cpumask *retmask) +{ + cpumask_clear(retmask); + cpumask_set_cpu(cpu, retmask); +} + +static void + __x2apic_send_IPI_dest(unsigned int apicid, int vector, unsigned int dest) +{ + unsigned long cfg; + + cfg = __prepare_ICR(0, vector, dest); + + /* + * send the IPI. + */ + native_x2apic_icr_write(cfg, apicid); +} + +/* + * for now, we send the IPI's one by one in the cpumask. + * TBD: Based on the cpu mask, we can send the IPI's to the cluster group + * at once. We have 16 cpu's in a cluster. This will minimize IPI register + * writes. + */ +static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector) +{ + unsigned long query_cpu; + unsigned long flags; + + local_irq_save(flags); + for_each_cpu(query_cpu, mask) { + __x2apic_send_IPI_dest( + per_cpu(x86_cpu_to_logical_apicid, query_cpu), + vector, apic->dest_logical); + } + local_irq_restore(flags); +} + +static void + x2apic_send_IPI_mask_allbutself(const struct cpumask *mask, int vector) +{ + unsigned long this_cpu = smp_processor_id(); + unsigned long query_cpu; + unsigned long flags; + + local_irq_save(flags); + for_each_cpu(query_cpu, mask) { + if (query_cpu == this_cpu) + continue; + __x2apic_send_IPI_dest( + per_cpu(x86_cpu_to_logical_apicid, query_cpu), + vector, apic->dest_logical); + } + local_irq_restore(flags); +} + +static void x2apic_send_IPI_allbutself(int vector) +{ + unsigned long this_cpu = smp_processor_id(); + unsigned long query_cpu; + unsigned long flags; + + local_irq_save(flags); + for_each_online_cpu(query_cpu) { + if (query_cpu == this_cpu) + continue; + __x2apic_send_IPI_dest( + per_cpu(x86_cpu_to_logical_apicid, query_cpu), + vector, apic->dest_logical); + } + local_irq_restore(flags); +} + +static void x2apic_send_IPI_all(int vector) +{ + x2apic_send_IPI_mask(cpu_online_mask, vector); +} + +static int x2apic_apic_id_registered(void) +{ + return 1; +} + +static unsigned int x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask) +{ + /* + * We're using fixed IRQ delivery, can only return one logical APIC ID. + * May as well be the first. + */ + int cpu = cpumask_first(cpumask); + + if ((unsigned)cpu < nr_cpu_ids) + return per_cpu(x86_cpu_to_logical_apicid, cpu); + else + return BAD_APICID; +} + +static unsigned int +x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, + const struct cpumask *andmask) +{ + int cpu; + + /* + * We're using fixed IRQ delivery, can only return one logical APIC ID. + * May as well be the first. + */ + for_each_cpu_and(cpu, cpumask, andmask) { + if (cpumask_test_cpu(cpu, cpu_online_mask)) + break; + } + + if (cpu < nr_cpu_ids) + return per_cpu(x86_cpu_to_logical_apicid, cpu); + + return BAD_APICID; +} + +static unsigned int x2apic_cluster_phys_get_apic_id(unsigned long x) +{ + unsigned int id; + + id = x; + return id; +} + +static unsigned long set_apic_id(unsigned int id) +{ + unsigned long x; + + x = id; + return x; +} + +static int x2apic_cluster_phys_pkg_id(int initial_apicid, int index_msb) +{ + return current_cpu_data.initial_apicid >> index_msb; +} + +static void x2apic_send_IPI_self(int vector) +{ + apic_write(APIC_SELF_IPI, vector); +} + +static void init_x2apic_ldr(void) +{ + int cpu = smp_processor_id(); + + per_cpu(x86_cpu_to_logical_apicid, cpu) = apic_read(APIC_LDR); +} + +struct apic apic_x2apic_cluster = { + + .name = "cluster x2apic", + .probe = NULL, + .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, + .apic_id_registered = x2apic_apic_id_registered, + + .irq_delivery_mode = dest_LowestPrio, + .irq_dest_mode = 1, /* logical */ + + .target_cpus = x2apic_target_cpus, + .disable_esr = 0, + .dest_logical = APIC_DEST_LOGICAL, + .check_apicid_used = NULL, + .check_apicid_present = NULL, + + .vector_allocation_domain = x2apic_vector_allocation_domain, + .init_apic_ldr = init_x2apic_ldr, + + .ioapic_phys_id_map = NULL, + .setup_apic_routing = NULL, + .multi_timer_check = NULL, + .apicid_to_node = NULL, + .cpu_to_logical_apicid = NULL, + .cpu_present_to_apicid = default_cpu_present_to_apicid, + .apicid_to_cpu_present = NULL, + .setup_portio_remap = NULL, + .check_phys_apicid_present = default_check_phys_apicid_present, + .enable_apic_mode = NULL, + .phys_pkg_id = x2apic_cluster_phys_pkg_id, + .mps_oem_check = NULL, + + .get_apic_id = x2apic_cluster_phys_get_apic_id, + .set_apic_id = set_apic_id, + .apic_id_mask = 0xFFFFFFFFu, + + .cpu_mask_to_apicid = x2apic_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = x2apic_cpu_mask_to_apicid_and, + + .send_IPI_mask = x2apic_send_IPI_mask, + .send_IPI_mask_allbutself = x2apic_send_IPI_mask_allbutself, + .send_IPI_allbutself = x2apic_send_IPI_allbutself, + .send_IPI_all = x2apic_send_IPI_all, + .send_IPI_self = x2apic_send_IPI_self, + + .wakeup_cpu = NULL, + .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, + .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, + .wait_for_init_deassert = NULL, + .smp_callin_clear_local_apic = NULL, + .inquire_remote_apic = NULL, + + .read = native_apic_msr_read, + .write = native_apic_msr_write, + .icr_read = native_x2apic_icr_read, + .icr_write = native_x2apic_icr_write, + .wait_icr_idle = native_x2apic_wait_icr_idle, + .safe_wait_icr_idle = native_safe_x2apic_wait_icr_idle, +}; diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c new file mode 100644 index 00000000000..d2d52eb9f7e --- /dev/null +++ b/arch/x86/kernel/apic/x2apic_phys.c @@ -0,0 +1,229 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static int x2apic_phys; + +static int set_x2apic_phys_mode(char *arg) +{ + x2apic_phys = 1; + return 0; +} +early_param("x2apic_phys", set_x2apic_phys_mode); + +static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id) +{ + if (cpu_has_x2apic && x2apic_phys) + return 1; + + return 0; +} + +/* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */ + +static const struct cpumask *x2apic_target_cpus(void) +{ + return cpumask_of(0); +} + +static void x2apic_vector_allocation_domain(int cpu, struct cpumask *retmask) +{ + cpumask_clear(retmask); + cpumask_set_cpu(cpu, retmask); +} + +static void __x2apic_send_IPI_dest(unsigned int apicid, int vector, + unsigned int dest) +{ + unsigned long cfg; + + cfg = __prepare_ICR(0, vector, dest); + + /* + * send the IPI. + */ + native_x2apic_icr_write(cfg, apicid); +} + +static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector) +{ + unsigned long query_cpu; + unsigned long flags; + + local_irq_save(flags); + for_each_cpu(query_cpu, mask) { + __x2apic_send_IPI_dest(per_cpu(x86_cpu_to_apicid, query_cpu), + vector, APIC_DEST_PHYSICAL); + } + local_irq_restore(flags); +} + +static void + x2apic_send_IPI_mask_allbutself(const struct cpumask *mask, int vector) +{ + unsigned long this_cpu = smp_processor_id(); + unsigned long query_cpu; + unsigned long flags; + + local_irq_save(flags); + for_each_cpu(query_cpu, mask) { + if (query_cpu != this_cpu) + __x2apic_send_IPI_dest( + per_cpu(x86_cpu_to_apicid, query_cpu), + vector, APIC_DEST_PHYSICAL); + } + local_irq_restore(flags); +} + +static void x2apic_send_IPI_allbutself(int vector) +{ + unsigned long this_cpu = smp_processor_id(); + unsigned long query_cpu; + unsigned long flags; + + local_irq_save(flags); + for_each_online_cpu(query_cpu) { + if (query_cpu == this_cpu) + continue; + __x2apic_send_IPI_dest(per_cpu(x86_cpu_to_apicid, query_cpu), + vector, APIC_DEST_PHYSICAL); + } + local_irq_restore(flags); +} + +static void x2apic_send_IPI_all(int vector) +{ + x2apic_send_IPI_mask(cpu_online_mask, vector); +} + +static int x2apic_apic_id_registered(void) +{ + return 1; +} + +static unsigned int x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask) +{ + /* + * We're using fixed IRQ delivery, can only return one phys APIC ID. + * May as well be the first. + */ + int cpu = cpumask_first(cpumask); + + if ((unsigned)cpu < nr_cpu_ids) + return per_cpu(x86_cpu_to_apicid, cpu); + else + return BAD_APICID; +} + +static unsigned int +x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, + const struct cpumask *andmask) +{ + int cpu; + + /* + * We're using fixed IRQ delivery, can only return one phys APIC ID. + * May as well be the first. + */ + for_each_cpu_and(cpu, cpumask, andmask) { + if (cpumask_test_cpu(cpu, cpu_online_mask)) + break; + } + + if (cpu < nr_cpu_ids) + return per_cpu(x86_cpu_to_apicid, cpu); + + return BAD_APICID; +} + +static unsigned int x2apic_phys_get_apic_id(unsigned long x) +{ + return x; +} + +static unsigned long set_apic_id(unsigned int id) +{ + return id; +} + +static int x2apic_phys_pkg_id(int initial_apicid, int index_msb) +{ + return current_cpu_data.initial_apicid >> index_msb; +} + +static void x2apic_send_IPI_self(int vector) +{ + apic_write(APIC_SELF_IPI, vector); +} + +static void init_x2apic_ldr(void) +{ +} + +struct apic apic_x2apic_phys = { + + .name = "physical x2apic", + .probe = NULL, + .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, + .apic_id_registered = x2apic_apic_id_registered, + + .irq_delivery_mode = dest_Fixed, + .irq_dest_mode = 0, /* physical */ + + .target_cpus = x2apic_target_cpus, + .disable_esr = 0, + .dest_logical = 0, + .check_apicid_used = NULL, + .check_apicid_present = NULL, + + .vector_allocation_domain = x2apic_vector_allocation_domain, + .init_apic_ldr = init_x2apic_ldr, + + .ioapic_phys_id_map = NULL, + .setup_apic_routing = NULL, + .multi_timer_check = NULL, + .apicid_to_node = NULL, + .cpu_to_logical_apicid = NULL, + .cpu_present_to_apicid = default_cpu_present_to_apicid, + .apicid_to_cpu_present = NULL, + .setup_portio_remap = NULL, + .check_phys_apicid_present = default_check_phys_apicid_present, + .enable_apic_mode = NULL, + .phys_pkg_id = x2apic_phys_pkg_id, + .mps_oem_check = NULL, + + .get_apic_id = x2apic_phys_get_apic_id, + .set_apic_id = set_apic_id, + .apic_id_mask = 0xFFFFFFFFu, + + .cpu_mask_to_apicid = x2apic_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = x2apic_cpu_mask_to_apicid_and, + + .send_IPI_mask = x2apic_send_IPI_mask, + .send_IPI_mask_allbutself = x2apic_send_IPI_mask_allbutself, + .send_IPI_allbutself = x2apic_send_IPI_allbutself, + .send_IPI_all = x2apic_send_IPI_all, + .send_IPI_self = x2apic_send_IPI_self, + + .wakeup_cpu = NULL, + .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, + .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, + .wait_for_init_deassert = NULL, + .smp_callin_clear_local_apic = NULL, + .inquire_remote_apic = NULL, + + .read = native_apic_msr_read, + .write = native_apic_msr_write, + .icr_read = native_x2apic_icr_read, + .icr_write = native_x2apic_icr_write, + .wait_icr_idle = native_x2apic_wait_icr_idle, + .safe_wait_icr_idle = native_safe_x2apic_wait_icr_idle, +}; diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c new file mode 100644 index 00000000000..20b4ad07c3a --- /dev/null +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -0,0 +1,643 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * SGI UV APIC functions (note: not an Intel compatible APIC) + * + * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DEFINE_PER_CPU(int, x2apic_extra_bits); + +static enum uv_system_type uv_system_type; + +static int uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id) +{ + if (!strcmp(oem_id, "SGI")) { + if (!strcmp(oem_table_id, "UVL")) + uv_system_type = UV_LEGACY_APIC; + else if (!strcmp(oem_table_id, "UVX")) + uv_system_type = UV_X2APIC; + else if (!strcmp(oem_table_id, "UVH")) { + uv_system_type = UV_NON_UNIQUE_APIC; + return 1; + } + } + return 0; +} + +enum uv_system_type get_uv_system_type(void) +{ + return uv_system_type; +} + +int is_uv_system(void) +{ + return uv_system_type != UV_NONE; +} +EXPORT_SYMBOL_GPL(is_uv_system); + +DEFINE_PER_CPU(struct uv_hub_info_s, __uv_hub_info); +EXPORT_PER_CPU_SYMBOL_GPL(__uv_hub_info); + +struct uv_blade_info *uv_blade_info; +EXPORT_SYMBOL_GPL(uv_blade_info); + +short *uv_node_to_blade; +EXPORT_SYMBOL_GPL(uv_node_to_blade); + +short *uv_cpu_to_blade; +EXPORT_SYMBOL_GPL(uv_cpu_to_blade); + +short uv_possible_blades; +EXPORT_SYMBOL_GPL(uv_possible_blades); + +unsigned long sn_rtc_cycles_per_second; +EXPORT_SYMBOL(sn_rtc_cycles_per_second); + +/* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */ + +static const struct cpumask *uv_target_cpus(void) +{ + return cpumask_of(0); +} + +static void uv_vector_allocation_domain(int cpu, struct cpumask *retmask) +{ + cpumask_clear(retmask); + cpumask_set_cpu(cpu, retmask); +} + +int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip) +{ + unsigned long val; + int pnode; + + pnode = uv_apicid_to_pnode(phys_apicid); + val = (1UL << UVH_IPI_INT_SEND_SHFT) | + (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) | + (((long)start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) | + APIC_DM_INIT; + uv_write_global_mmr64(pnode, UVH_IPI_INT, val); + mdelay(10); + + val = (1UL << UVH_IPI_INT_SEND_SHFT) | + (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) | + (((long)start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) | + APIC_DM_STARTUP; + uv_write_global_mmr64(pnode, UVH_IPI_INT, val); + return 0; +} + +static void uv_send_IPI_one(int cpu, int vector) +{ + unsigned long val, apicid; + int pnode; + + apicid = per_cpu(x86_cpu_to_apicid, cpu); + pnode = uv_apicid_to_pnode(apicid); + + val = (1UL << UVH_IPI_INT_SEND_SHFT) | + (apicid << UVH_IPI_INT_APIC_ID_SHFT) | + (vector << UVH_IPI_INT_VECTOR_SHFT); + + uv_write_global_mmr64(pnode, UVH_IPI_INT, val); +} + +static void uv_send_IPI_mask(const struct cpumask *mask, int vector) +{ + unsigned int cpu; + + for_each_cpu(cpu, mask) + uv_send_IPI_one(cpu, vector); +} + +static void uv_send_IPI_mask_allbutself(const struct cpumask *mask, int vector) +{ + unsigned int this_cpu = smp_processor_id(); + unsigned int cpu; + + for_each_cpu(cpu, mask) { + if (cpu != this_cpu) + uv_send_IPI_one(cpu, vector); + } +} + +static void uv_send_IPI_allbutself(int vector) +{ + unsigned int this_cpu = smp_processor_id(); + unsigned int cpu; + + for_each_online_cpu(cpu) { + if (cpu != this_cpu) + uv_send_IPI_one(cpu, vector); + } +} + +static void uv_send_IPI_all(int vector) +{ + uv_send_IPI_mask(cpu_online_mask, vector); +} + +static int uv_apic_id_registered(void) +{ + return 1; +} + +static void uv_init_apic_ldr(void) +{ +} + +static unsigned int uv_cpu_mask_to_apicid(const struct cpumask *cpumask) +{ + /* + * We're using fixed IRQ delivery, can only return one phys APIC ID. + * May as well be the first. + */ + int cpu = cpumask_first(cpumask); + + if ((unsigned)cpu < nr_cpu_ids) + return per_cpu(x86_cpu_to_apicid, cpu); + else + return BAD_APICID; +} + +static unsigned int +uv_cpu_mask_to_apicid_and(const struct cpumask *cpumask, + const struct cpumask *andmask) +{ + int cpu; + + /* + * We're using fixed IRQ delivery, can only return one phys APIC ID. + * May as well be the first. + */ + for_each_cpu_and(cpu, cpumask, andmask) { + if (cpumask_test_cpu(cpu, cpu_online_mask)) + break; + } + if (cpu < nr_cpu_ids) + return per_cpu(x86_cpu_to_apicid, cpu); + + return BAD_APICID; +} + +static unsigned int x2apic_get_apic_id(unsigned long x) +{ + unsigned int id; + + WARN_ON(preemptible() && num_online_cpus() > 1); + id = x | __get_cpu_var(x2apic_extra_bits); + + return id; +} + +static unsigned long set_apic_id(unsigned int id) +{ + unsigned long x; + + /* maskout x2apic_extra_bits ? */ + x = id; + return x; +} + +static unsigned int uv_read_apic_id(void) +{ + + return x2apic_get_apic_id(apic_read(APIC_ID)); +} + +static int uv_phys_pkg_id(int initial_apicid, int index_msb) +{ + return uv_read_apic_id() >> index_msb; +} + +static void uv_send_IPI_self(int vector) +{ + apic_write(APIC_SELF_IPI, vector); +} + +struct apic apic_x2apic_uv_x = { + + .name = "UV large system", + .probe = NULL, + .acpi_madt_oem_check = uv_acpi_madt_oem_check, + .apic_id_registered = uv_apic_id_registered, + + .irq_delivery_mode = dest_Fixed, + .irq_dest_mode = 1, /* logical */ + + .target_cpus = uv_target_cpus, + .disable_esr = 0, + .dest_logical = APIC_DEST_LOGICAL, + .check_apicid_used = NULL, + .check_apicid_present = NULL, + + .vector_allocation_domain = uv_vector_allocation_domain, + .init_apic_ldr = uv_init_apic_ldr, + + .ioapic_phys_id_map = NULL, + .setup_apic_routing = NULL, + .multi_timer_check = NULL, + .apicid_to_node = NULL, + .cpu_to_logical_apicid = NULL, + .cpu_present_to_apicid = default_cpu_present_to_apicid, + .apicid_to_cpu_present = NULL, + .setup_portio_remap = NULL, + .check_phys_apicid_present = default_check_phys_apicid_present, + .enable_apic_mode = NULL, + .phys_pkg_id = uv_phys_pkg_id, + .mps_oem_check = NULL, + + .get_apic_id = x2apic_get_apic_id, + .set_apic_id = set_apic_id, + .apic_id_mask = 0xFFFFFFFFu, + + .cpu_mask_to_apicid = uv_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = uv_cpu_mask_to_apicid_and, + + .send_IPI_mask = uv_send_IPI_mask, + .send_IPI_mask_allbutself = uv_send_IPI_mask_allbutself, + .send_IPI_allbutself = uv_send_IPI_allbutself, + .send_IPI_all = uv_send_IPI_all, + .send_IPI_self = uv_send_IPI_self, + + .wakeup_cpu = NULL, + .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, + .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, + .wait_for_init_deassert = NULL, + .smp_callin_clear_local_apic = NULL, + .inquire_remote_apic = NULL, + + .read = native_apic_msr_read, + .write = native_apic_msr_write, + .icr_read = native_x2apic_icr_read, + .icr_write = native_x2apic_icr_write, + .wait_icr_idle = native_x2apic_wait_icr_idle, + .safe_wait_icr_idle = native_safe_x2apic_wait_icr_idle, +}; + +static __cpuinit void set_x2apic_extra_bits(int pnode) +{ + __get_cpu_var(x2apic_extra_bits) = (pnode << 6); +} + +/* + * Called on boot cpu. + */ +static __init int boot_pnode_to_blade(int pnode) +{ + int blade; + + for (blade = 0; blade < uv_num_possible_blades(); blade++) + if (pnode == uv_blade_info[blade].pnode) + return blade; + BUG(); +} + +struct redir_addr { + unsigned long redirect; + unsigned long alias; +}; + +#define DEST_SHIFT UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT + +static __initdata struct redir_addr redir_addrs[] = { + {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR, UVH_SI_ALIAS0_OVERLAY_CONFIG}, + {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR, UVH_SI_ALIAS1_OVERLAY_CONFIG}, + {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR, UVH_SI_ALIAS2_OVERLAY_CONFIG}, +}; + +static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size) +{ + union uvh_si_alias0_overlay_config_u alias; + union uvh_rh_gam_alias210_redirect_config_2_mmr_u redirect; + int i; + + for (i = 0; i < ARRAY_SIZE(redir_addrs); i++) { + alias.v = uv_read_local_mmr(redir_addrs[i].alias); + if (alias.s.base == 0) { + *size = (1UL << alias.s.m_alias); + redirect.v = uv_read_local_mmr(redir_addrs[i].redirect); + *base = (unsigned long)redirect.s.dest_base << DEST_SHIFT; + return; + } + } + BUG(); +} + +static __init void map_low_mmrs(void) +{ + init_extra_mapping_uc(UV_GLOBAL_MMR32_BASE, UV_GLOBAL_MMR32_SIZE); + init_extra_mapping_uc(UV_LOCAL_MMR_BASE, UV_LOCAL_MMR_SIZE); +} + +enum map_type {map_wb, map_uc}; + +static __init void map_high(char *id, unsigned long base, int shift, + int max_pnode, enum map_type map_type) +{ + unsigned long bytes, paddr; + + paddr = base << shift; + bytes = (1UL << shift) * (max_pnode + 1); + printk(KERN_INFO "UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr, + paddr + bytes); + if (map_type == map_uc) + init_extra_mapping_uc(paddr, bytes); + else + init_extra_mapping_wb(paddr, bytes); + +} +static __init void map_gru_high(int max_pnode) +{ + union uvh_rh_gam_gru_overlay_config_mmr_u gru; + int shift = UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT; + + gru.v = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR); + if (gru.s.enable) + map_high("GRU", gru.s.base, shift, max_pnode, map_wb); +} + +static __init void map_config_high(int max_pnode) +{ + union uvh_rh_gam_cfg_overlay_config_mmr_u cfg; + int shift = UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_BASE_SHFT; + + cfg.v = uv_read_local_mmr(UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR); + if (cfg.s.enable) + map_high("CONFIG", cfg.s.base, shift, max_pnode, map_uc); +} + +static __init void map_mmr_high(int max_pnode) +{ + union uvh_rh_gam_mmr_overlay_config_mmr_u mmr; + int shift = UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT; + + mmr.v = uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR); + if (mmr.s.enable) + map_high("MMR", mmr.s.base, shift, max_pnode, map_uc); +} + +static __init void map_mmioh_high(int max_pnode) +{ + union uvh_rh_gam_mmioh_overlay_config_mmr_u mmioh; + int shift = UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT; + + mmioh.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR); + if (mmioh.s.enable) + map_high("MMIOH", mmioh.s.base, shift, max_pnode, map_uc); +} + +static __init void uv_rtc_init(void) +{ + long status; + u64 ticks_per_sec; + + status = uv_bios_freq_base(BIOS_FREQ_BASE_REALTIME_CLOCK, + &ticks_per_sec); + if (status != BIOS_STATUS_SUCCESS || ticks_per_sec < 100000) { + printk(KERN_WARNING + "unable to determine platform RTC clock frequency, " + "guessing.\n"); + /* BIOS gives wrong value for clock freq. so guess */ + sn_rtc_cycles_per_second = 1000000000000UL / 30000UL; + } else + sn_rtc_cycles_per_second = ticks_per_sec; +} + +/* + * percpu heartbeat timer + */ +static void uv_heartbeat(unsigned long ignored) +{ + struct timer_list *timer = &uv_hub_info->scir.timer; + unsigned char bits = uv_hub_info->scir.state; + + /* flip heartbeat bit */ + bits ^= SCIR_CPU_HEARTBEAT; + + /* is this cpu idle? */ + if (idle_cpu(raw_smp_processor_id())) + bits &= ~SCIR_CPU_ACTIVITY; + else + bits |= SCIR_CPU_ACTIVITY; + + /* update system controller interface reg */ + uv_set_scir_bits(bits); + + /* enable next timer period */ + mod_timer(timer, jiffies + SCIR_CPU_HB_INTERVAL); +} + +static void __cpuinit uv_heartbeat_enable(int cpu) +{ + if (!uv_cpu_hub_info(cpu)->scir.enabled) { + struct timer_list *timer = &uv_cpu_hub_info(cpu)->scir.timer; + + uv_set_cpu_scir_bits(cpu, SCIR_CPU_HEARTBEAT|SCIR_CPU_ACTIVITY); + setup_timer(timer, uv_heartbeat, cpu); + timer->expires = jiffies + SCIR_CPU_HB_INTERVAL; + add_timer_on(timer, cpu); + uv_cpu_hub_info(cpu)->scir.enabled = 1; + } + + /* check boot cpu */ + if (!uv_cpu_hub_info(0)->scir.enabled) + uv_heartbeat_enable(0); +} + +#ifdef CONFIG_HOTPLUG_CPU +static void __cpuinit uv_heartbeat_disable(int cpu) +{ + if (uv_cpu_hub_info(cpu)->scir.enabled) { + uv_cpu_hub_info(cpu)->scir.enabled = 0; + del_timer(&uv_cpu_hub_info(cpu)->scir.timer); + } + uv_set_cpu_scir_bits(cpu, 0xff); +} + +/* + * cpu hotplug notifier + */ +static __cpuinit int uv_scir_cpu_notify(struct notifier_block *self, + unsigned long action, void *hcpu) +{ + long cpu = (long)hcpu; + + switch (action) { + case CPU_ONLINE: + uv_heartbeat_enable(cpu); + break; + case CPU_DOWN_PREPARE: + uv_heartbeat_disable(cpu); + break; + default: + break; + } + return NOTIFY_OK; +} + +static __init void uv_scir_register_cpu_notifier(void) +{ + hotcpu_notifier(uv_scir_cpu_notify, 0); +} + +#else /* !CONFIG_HOTPLUG_CPU */ + +static __init void uv_scir_register_cpu_notifier(void) +{ +} + +static __init int uv_init_heartbeat(void) +{ + int cpu; + + if (is_uv_system()) + for_each_online_cpu(cpu) + uv_heartbeat_enable(cpu); + return 0; +} + +late_initcall(uv_init_heartbeat); + +#endif /* !CONFIG_HOTPLUG_CPU */ + +/* + * Called on each cpu to initialize the per_cpu UV data area. + * ZZZ hotplug not supported yet + */ +void __cpuinit uv_cpu_init(void) +{ + /* CPU 0 initilization will be done via uv_system_init. */ + if (!uv_blade_info) + return; + + uv_blade_info[uv_numa_blade_id()].nr_online_cpus++; + + if (get_uv_system_type() == UV_NON_UNIQUE_APIC) + set_x2apic_extra_bits(uv_hub_info->pnode); +} + + +void __init uv_system_init(void) +{ + union uvh_si_addr_map_config_u m_n_config; + union uvh_node_id_u node_id; + unsigned long gnode_upper, lowmem_redir_base, lowmem_redir_size; + int bytes, nid, cpu, lcpu, pnode, blade, i, j, m_val, n_val; + int max_pnode = 0; + unsigned long mmr_base, present; + + map_low_mmrs(); + + m_n_config.v = uv_read_local_mmr(UVH_SI_ADDR_MAP_CONFIG); + m_val = m_n_config.s.m_skt; + n_val = m_n_config.s.n_skt; + mmr_base = + uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR) & + ~UV_MMR_ENABLE; + printk(KERN_DEBUG "UV: global MMR base 0x%lx\n", mmr_base); + + for(i = 0; i < UVH_NODE_PRESENT_TABLE_DEPTH; i++) + uv_possible_blades += + hweight64(uv_read_local_mmr( UVH_NODE_PRESENT_TABLE + i * 8)); + printk(KERN_DEBUG "UV: Found %d blades\n", uv_num_possible_blades()); + + bytes = sizeof(struct uv_blade_info) * uv_num_possible_blades(); + uv_blade_info = kmalloc(bytes, GFP_KERNEL); + + get_lowmem_redirect(&lowmem_redir_base, &lowmem_redir_size); + + bytes = sizeof(uv_node_to_blade[0]) * num_possible_nodes(); + uv_node_to_blade = kmalloc(bytes, GFP_KERNEL); + memset(uv_node_to_blade, 255, bytes); + + bytes = sizeof(uv_cpu_to_blade[0]) * num_possible_cpus(); + uv_cpu_to_blade = kmalloc(bytes, GFP_KERNEL); + memset(uv_cpu_to_blade, 255, bytes); + + blade = 0; + for (i = 0; i < UVH_NODE_PRESENT_TABLE_DEPTH; i++) { + present = uv_read_local_mmr(UVH_NODE_PRESENT_TABLE + i * 8); + for (j = 0; j < 64; j++) { + if (!test_bit(j, &present)) + continue; + uv_blade_info[blade].pnode = (i * 64 + j); + uv_blade_info[blade].nr_possible_cpus = 0; + uv_blade_info[blade].nr_online_cpus = 0; + blade++; + } + } + + node_id.v = uv_read_local_mmr(UVH_NODE_ID); + gnode_upper = (((unsigned long)node_id.s.node_id) & + ~((1 << n_val) - 1)) << m_val; + + uv_bios_init(); + uv_bios_get_sn_info(0, &uv_type, &sn_partition_id, + &sn_coherency_id, &sn_region_size); + uv_rtc_init(); + + for_each_present_cpu(cpu) { + nid = cpu_to_node(cpu); + pnode = uv_apicid_to_pnode(per_cpu(x86_cpu_to_apicid, cpu)); + blade = boot_pnode_to_blade(pnode); + lcpu = uv_blade_info[blade].nr_possible_cpus; + uv_blade_info[blade].nr_possible_cpus++; + + uv_cpu_hub_info(cpu)->lowmem_remap_base = lowmem_redir_base; + uv_cpu_hub_info(cpu)->lowmem_remap_top = lowmem_redir_size; + uv_cpu_hub_info(cpu)->m_val = m_val; + uv_cpu_hub_info(cpu)->n_val = m_val; + uv_cpu_hub_info(cpu)->numa_blade_id = blade; + uv_cpu_hub_info(cpu)->blade_processor_id = lcpu; + uv_cpu_hub_info(cpu)->pnode = pnode; + uv_cpu_hub_info(cpu)->pnode_mask = (1 << n_val) - 1; + uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1; + uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper; + uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base; + uv_cpu_hub_info(cpu)->coherency_domain_number = sn_coherency_id; + uv_cpu_hub_info(cpu)->scir.offset = SCIR_LOCAL_MMR_BASE + lcpu; + uv_node_to_blade[nid] = blade; + uv_cpu_to_blade[cpu] = blade; + max_pnode = max(pnode, max_pnode); + + printk(KERN_DEBUG "UV: cpu %d, apicid 0x%x, pnode %d, nid %d, " + "lcpu %d, blade %d\n", + cpu, per_cpu(x86_cpu_to_apicid, cpu), pnode, nid, + lcpu, blade); + } + + map_gru_high(max_pnode); + map_mmr_high(max_pnode); + map_config_high(max_pnode); + map_mmioh_high(max_pnode); + + uv_cpu_init(); + uv_scir_register_cpu_notifier(); + proc_mkdir("sgi_uv", NULL); +} diff --git a/arch/x86/kernel/genapic_64.c b/arch/x86/kernel/genapic_64.c deleted file mode 100644 index 70935dd904d..00000000000 --- a/arch/x86/kernel/genapic_64.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2004 James Cleverdon, IBM. - * Subject to the GNU Public License, v.2 - * - * Generic APIC sub-arch probe layer. - * - * Hacked for x86-64 by James Cleverdon from i386 architecture code by - * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and - * James Cleverdon. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -extern struct apic apic_flat; -extern struct apic apic_physflat; -extern struct apic apic_x2xpic_uv_x; -extern struct apic apic_x2apic_phys; -extern struct apic apic_x2apic_cluster; - -struct apic __read_mostly *apic = &apic_flat; -EXPORT_SYMBOL_GPL(apic); - -static struct apic *apic_probe[] __initdata = { -#ifdef CONFIG_X86_UV - &apic_x2apic_uv_x, -#endif -#ifdef CONFIG_X86_X2APIC - &apic_x2apic_phys, - &apic_x2apic_cluster, -#endif - &apic_physflat, - NULL, -}; - -/* - * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. - */ -void __init default_setup_apic_routing(void) -{ -#ifdef CONFIG_X86_X2APIC - if (apic == &apic_x2apic_phys || apic == &apic_x2apic_cluster) { - if (!intr_remapping_enabled) - apic = &apic_flat; - } -#endif - - if (apic == &apic_flat) { - if (max_physical_apicid >= 8) - apic = &apic_physflat; - printk(KERN_INFO "Setting APIC routing to %s\n", apic->name); - } - - if (x86_quirks->update_apic) - x86_quirks->update_apic(); -} - -/* Same for both flat and physical. */ - -void apic_send_IPI_self(int vector) -{ - __default_send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL); -} - -int __init default_acpi_madt_oem_check(char *oem_id, char *oem_table_id) -{ - int i; - - for (i = 0; apic_probe[i]; ++i) { - if (apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id)) { - apic = apic_probe[i]; - printk(KERN_INFO "Setting APIC routing to %s.\n", - apic->name); - return 1; - } - } - return 0; -} diff --git a/arch/x86/kernel/genapic_flat_64.c b/arch/x86/kernel/genapic_flat_64.c deleted file mode 100644 index 3b002995e14..00000000000 --- a/arch/x86/kernel/genapic_flat_64.c +++ /dev/null @@ -1,389 +0,0 @@ -/* - * Copyright 2004 James Cleverdon, IBM. - * Subject to the GNU Public License, v.2 - * - * Flat APIC subarch code. - * - * Hacked for x86-64 by James Cleverdon from i386 architecture code by - * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and - * James Cleverdon. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_ACPI -#include -#endif - -static int flat_acpi_madt_oem_check(char *oem_id, char *oem_table_id) -{ - return 1; -} - -static const struct cpumask *flat_target_cpus(void) -{ - return cpu_online_mask; -} - -static void flat_vector_allocation_domain(int cpu, struct cpumask *retmask) -{ - /* Careful. Some cpus do not strictly honor the set of cpus - * specified in the interrupt destination when using lowest - * priority interrupt delivery mode. - * - * In particular there was a hyperthreading cpu observed to - * deliver interrupts to the wrong hyperthread when only one - * hyperthread was specified in the interrupt desitination. - */ - cpumask_clear(retmask); - cpumask_bits(retmask)[0] = APIC_ALL_CPUS; -} - -/* - * Set up the logical destination ID. - * - * Intel recommends to set DFR, LDR and TPR before enabling - * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel - * document number 292116). So here it goes... - */ -static void flat_init_apic_ldr(void) -{ - unsigned long val; - unsigned long num, id; - - num = smp_processor_id(); - id = 1UL << num; - apic_write(APIC_DFR, APIC_DFR_FLAT); - val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; - val |= SET_APIC_LOGICAL_ID(id); - apic_write(APIC_LDR, val); -} - -static inline void _flat_send_IPI_mask(unsigned long mask, int vector) -{ - unsigned long flags; - - local_irq_save(flags); - __default_send_IPI_dest_field(mask, vector, apic->dest_logical); - local_irq_restore(flags); -} - -static void flat_send_IPI_mask(const struct cpumask *cpumask, int vector) -{ - unsigned long mask = cpumask_bits(cpumask)[0]; - - _flat_send_IPI_mask(mask, vector); -} - -static void - flat_send_IPI_mask_allbutself(const struct cpumask *cpumask, int vector) -{ - unsigned long mask = cpumask_bits(cpumask)[0]; - int cpu = smp_processor_id(); - - if (cpu < BITS_PER_LONG) - clear_bit(cpu, &mask); - - _flat_send_IPI_mask(mask, vector); -} - -static void flat_send_IPI_allbutself(int vector) -{ - int cpu = smp_processor_id(); -#ifdef CONFIG_HOTPLUG_CPU - int hotplug = 1; -#else - int hotplug = 0; -#endif - if (hotplug || vector == NMI_VECTOR) { - if (!cpumask_equal(cpu_online_mask, cpumask_of(cpu))) { - unsigned long mask = cpumask_bits(cpu_online_mask)[0]; - - if (cpu < BITS_PER_LONG) - clear_bit(cpu, &mask); - - _flat_send_IPI_mask(mask, vector); - } - } else if (num_online_cpus() > 1) { - __default_send_IPI_shortcut(APIC_DEST_ALLBUT, - vector, apic->dest_logical); - } -} - -static void flat_send_IPI_all(int vector) -{ - if (vector == NMI_VECTOR) { - flat_send_IPI_mask(cpu_online_mask, vector); - } else { - __default_send_IPI_shortcut(APIC_DEST_ALLINC, - vector, apic->dest_logical); - } -} - -static unsigned int flat_get_apic_id(unsigned long x) -{ - unsigned int id; - - id = (((x)>>24) & 0xFFu); - - return id; -} - -static unsigned long set_apic_id(unsigned int id) -{ - unsigned long x; - - x = ((id & 0xFFu)<<24); - return x; -} - -static unsigned int read_xapic_id(void) -{ - unsigned int id; - - id = flat_get_apic_id(apic_read(APIC_ID)); - return id; -} - -static int flat_apic_id_registered(void) -{ - return physid_isset(read_xapic_id(), phys_cpu_present_map); -} - -static unsigned int flat_cpu_mask_to_apicid(const struct cpumask *cpumask) -{ - return cpumask_bits(cpumask)[0] & APIC_ALL_CPUS; -} - -static unsigned int flat_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask) -{ - unsigned long mask1 = cpumask_bits(cpumask)[0] & APIC_ALL_CPUS; - unsigned long mask2 = cpumask_bits(andmask)[0] & APIC_ALL_CPUS; - - return mask1 & mask2; -} - -static int flat_phys_pkg_id(int initial_apic_id, int index_msb) -{ - return hard_smp_processor_id() >> index_msb; -} - -struct apic apic_flat = { - .name = "flat", - .probe = NULL, - .acpi_madt_oem_check = flat_acpi_madt_oem_check, - .apic_id_registered = flat_apic_id_registered, - - .irq_delivery_mode = dest_LowestPrio, - .irq_dest_mode = 1, /* logical */ - - .target_cpus = flat_target_cpus, - .disable_esr = 0, - .dest_logical = APIC_DEST_LOGICAL, - .check_apicid_used = NULL, - .check_apicid_present = NULL, - - .vector_allocation_domain = flat_vector_allocation_domain, - .init_apic_ldr = flat_init_apic_ldr, - - .ioapic_phys_id_map = NULL, - .setup_apic_routing = NULL, - .multi_timer_check = NULL, - .apicid_to_node = NULL, - .cpu_to_logical_apicid = NULL, - .cpu_present_to_apicid = default_cpu_present_to_apicid, - .apicid_to_cpu_present = NULL, - .setup_portio_remap = NULL, - .check_phys_apicid_present = default_check_phys_apicid_present, - .enable_apic_mode = NULL, - .phys_pkg_id = flat_phys_pkg_id, - .mps_oem_check = NULL, - - .get_apic_id = flat_get_apic_id, - .set_apic_id = set_apic_id, - .apic_id_mask = 0xFFu << 24, - - .cpu_mask_to_apicid = flat_cpu_mask_to_apicid, - .cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and, - - .send_IPI_mask = flat_send_IPI_mask, - .send_IPI_mask_allbutself = flat_send_IPI_mask_allbutself, - .send_IPI_allbutself = flat_send_IPI_allbutself, - .send_IPI_all = flat_send_IPI_all, - .send_IPI_self = apic_send_IPI_self, - - .wakeup_cpu = NULL, - .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, - .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, - .wait_for_init_deassert = NULL, - .smp_callin_clear_local_apic = NULL, - .inquire_remote_apic = NULL, - - .read = native_apic_mem_read, - .write = native_apic_mem_write, - .icr_read = native_apic_icr_read, - .icr_write = native_apic_icr_write, - .wait_icr_idle = native_apic_wait_icr_idle, - .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, -}; - -/* - * Physflat mode is used when there are more than 8 CPUs on a AMD system. - * We cannot use logical delivery in this case because the mask - * overflows, so use physical mode. - */ -static int physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id) -{ -#ifdef CONFIG_ACPI - /* - * Quirk: some x86_64 machines can only use physical APIC mode - * regardless of how many processors are present (x86_64 ES7000 - * is an example). - */ - if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID && - (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL)) { - printk(KERN_DEBUG "system APIC only can use physical flat"); - return 1; - } -#endif - - return 0; -} - -static const struct cpumask *physflat_target_cpus(void) -{ - return cpu_online_mask; -} - -static void physflat_vector_allocation_domain(int cpu, struct cpumask *retmask) -{ - cpumask_clear(retmask); - cpumask_set_cpu(cpu, retmask); -} - -static void physflat_send_IPI_mask(const struct cpumask *cpumask, int vector) -{ - default_send_IPI_mask_sequence_phys(cpumask, vector); -} - -static void physflat_send_IPI_mask_allbutself(const struct cpumask *cpumask, - int vector) -{ - default_send_IPI_mask_allbutself_phys(cpumask, vector); -} - -static void physflat_send_IPI_allbutself(int vector) -{ - default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector); -} - -static void physflat_send_IPI_all(int vector) -{ - physflat_send_IPI_mask(cpu_online_mask, vector); -} - -static unsigned int physflat_cpu_mask_to_apicid(const struct cpumask *cpumask) -{ - int cpu; - - /* - * We're using fixed IRQ delivery, can only return one phys APIC ID. - * May as well be the first. - */ - cpu = cpumask_first(cpumask); - if ((unsigned)cpu < nr_cpu_ids) - return per_cpu(x86_cpu_to_apicid, cpu); - else - return BAD_APICID; -} - -static unsigned int -physflat_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask) -{ - int cpu; - - /* - * We're using fixed IRQ delivery, can only return one phys APIC ID. - * May as well be the first. - */ - for_each_cpu_and(cpu, cpumask, andmask) { - if (cpumask_test_cpu(cpu, cpu_online_mask)) - break; - } - if (cpu < nr_cpu_ids) - return per_cpu(x86_cpu_to_apicid, cpu); - - return BAD_APICID; -} - -struct apic apic_physflat = { - - .name = "physical flat", - .probe = NULL, - .acpi_madt_oem_check = physflat_acpi_madt_oem_check, - .apic_id_registered = flat_apic_id_registered, - - .irq_delivery_mode = dest_Fixed, - .irq_dest_mode = 0, /* physical */ - - .target_cpus = physflat_target_cpus, - .disable_esr = 0, - .dest_logical = 0, - .check_apicid_used = NULL, - .check_apicid_present = NULL, - - .vector_allocation_domain = physflat_vector_allocation_domain, - /* not needed, but shouldn't hurt: */ - .init_apic_ldr = flat_init_apic_ldr, - - .ioapic_phys_id_map = NULL, - .setup_apic_routing = NULL, - .multi_timer_check = NULL, - .apicid_to_node = NULL, - .cpu_to_logical_apicid = NULL, - .cpu_present_to_apicid = default_cpu_present_to_apicid, - .apicid_to_cpu_present = NULL, - .setup_portio_remap = NULL, - .check_phys_apicid_present = default_check_phys_apicid_present, - .enable_apic_mode = NULL, - .phys_pkg_id = flat_phys_pkg_id, - .mps_oem_check = NULL, - - .get_apic_id = flat_get_apic_id, - .set_apic_id = set_apic_id, - .apic_id_mask = 0xFFu << 24, - - .cpu_mask_to_apicid = physflat_cpu_mask_to_apicid, - .cpu_mask_to_apicid_and = physflat_cpu_mask_to_apicid_and, - - .send_IPI_mask = physflat_send_IPI_mask, - .send_IPI_mask_allbutself = physflat_send_IPI_mask_allbutself, - .send_IPI_allbutself = physflat_send_IPI_allbutself, - .send_IPI_all = physflat_send_IPI_all, - .send_IPI_self = apic_send_IPI_self, - - .wakeup_cpu = NULL, - .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, - .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, - .wait_for_init_deassert = NULL, - .smp_callin_clear_local_apic = NULL, - .inquire_remote_apic = NULL, - - .read = native_apic_mem_read, - .write = native_apic_mem_write, - .icr_read = native_apic_icr_read, - .icr_write = native_apic_icr_write, - .wait_icr_idle = native_apic_wait_icr_idle, - .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, -}; diff --git a/arch/x86/kernel/genx2apic_cluster.c b/arch/x86/kernel/genx2apic_cluster.c deleted file mode 100644 index 4e39d9ad4d5..00000000000 --- a/arch/x86/kernel/genx2apic_cluster.c +++ /dev/null @@ -1,243 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -DEFINE_PER_CPU(u32, x86_cpu_to_logical_apicid); - -static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id) -{ - if (cpu_has_x2apic) - return 1; - - return 0; -} - -/* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */ - -static const struct cpumask *x2apic_target_cpus(void) -{ - return cpumask_of(0); -} - -/* - * for now each logical cpu is in its own vector allocation domain. - */ -static void x2apic_vector_allocation_domain(int cpu, struct cpumask *retmask) -{ - cpumask_clear(retmask); - cpumask_set_cpu(cpu, retmask); -} - -static void - __x2apic_send_IPI_dest(unsigned int apicid, int vector, unsigned int dest) -{ - unsigned long cfg; - - cfg = __prepare_ICR(0, vector, dest); - - /* - * send the IPI. - */ - native_x2apic_icr_write(cfg, apicid); -} - -/* - * for now, we send the IPI's one by one in the cpumask. - * TBD: Based on the cpu mask, we can send the IPI's to the cluster group - * at once. We have 16 cpu's in a cluster. This will minimize IPI register - * writes. - */ -static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector) -{ - unsigned long query_cpu; - unsigned long flags; - - local_irq_save(flags); - for_each_cpu(query_cpu, mask) { - __x2apic_send_IPI_dest( - per_cpu(x86_cpu_to_logical_apicid, query_cpu), - vector, apic->dest_logical); - } - local_irq_restore(flags); -} - -static void - x2apic_send_IPI_mask_allbutself(const struct cpumask *mask, int vector) -{ - unsigned long this_cpu = smp_processor_id(); - unsigned long query_cpu; - unsigned long flags; - - local_irq_save(flags); - for_each_cpu(query_cpu, mask) { - if (query_cpu == this_cpu) - continue; - __x2apic_send_IPI_dest( - per_cpu(x86_cpu_to_logical_apicid, query_cpu), - vector, apic->dest_logical); - } - local_irq_restore(flags); -} - -static void x2apic_send_IPI_allbutself(int vector) -{ - unsigned long this_cpu = smp_processor_id(); - unsigned long query_cpu; - unsigned long flags; - - local_irq_save(flags); - for_each_online_cpu(query_cpu) { - if (query_cpu == this_cpu) - continue; - __x2apic_send_IPI_dest( - per_cpu(x86_cpu_to_logical_apicid, query_cpu), - vector, apic->dest_logical); - } - local_irq_restore(flags); -} - -static void x2apic_send_IPI_all(int vector) -{ - x2apic_send_IPI_mask(cpu_online_mask, vector); -} - -static int x2apic_apic_id_registered(void) -{ - return 1; -} - -static unsigned int x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask) -{ - /* - * We're using fixed IRQ delivery, can only return one logical APIC ID. - * May as well be the first. - */ - int cpu = cpumask_first(cpumask); - - if ((unsigned)cpu < nr_cpu_ids) - return per_cpu(x86_cpu_to_logical_apicid, cpu); - else - return BAD_APICID; -} - -static unsigned int -x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask) -{ - int cpu; - - /* - * We're using fixed IRQ delivery, can only return one logical APIC ID. - * May as well be the first. - */ - for_each_cpu_and(cpu, cpumask, andmask) { - if (cpumask_test_cpu(cpu, cpu_online_mask)) - break; - } - - if (cpu < nr_cpu_ids) - return per_cpu(x86_cpu_to_logical_apicid, cpu); - - return BAD_APICID; -} - -static unsigned int x2apic_cluster_phys_get_apic_id(unsigned long x) -{ - unsigned int id; - - id = x; - return id; -} - -static unsigned long set_apic_id(unsigned int id) -{ - unsigned long x; - - x = id; - return x; -} - -static int x2apic_cluster_phys_pkg_id(int initial_apicid, int index_msb) -{ - return current_cpu_data.initial_apicid >> index_msb; -} - -static void x2apic_send_IPI_self(int vector) -{ - apic_write(APIC_SELF_IPI, vector); -} - -static void init_x2apic_ldr(void) -{ - int cpu = smp_processor_id(); - - per_cpu(x86_cpu_to_logical_apicid, cpu) = apic_read(APIC_LDR); -} - -struct apic apic_x2apic_cluster = { - - .name = "cluster x2apic", - .probe = NULL, - .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, - .apic_id_registered = x2apic_apic_id_registered, - - .irq_delivery_mode = dest_LowestPrio, - .irq_dest_mode = 1, /* logical */ - - .target_cpus = x2apic_target_cpus, - .disable_esr = 0, - .dest_logical = APIC_DEST_LOGICAL, - .check_apicid_used = NULL, - .check_apicid_present = NULL, - - .vector_allocation_domain = x2apic_vector_allocation_domain, - .init_apic_ldr = init_x2apic_ldr, - - .ioapic_phys_id_map = NULL, - .setup_apic_routing = NULL, - .multi_timer_check = NULL, - .apicid_to_node = NULL, - .cpu_to_logical_apicid = NULL, - .cpu_present_to_apicid = default_cpu_present_to_apicid, - .apicid_to_cpu_present = NULL, - .setup_portio_remap = NULL, - .check_phys_apicid_present = default_check_phys_apicid_present, - .enable_apic_mode = NULL, - .phys_pkg_id = x2apic_cluster_phys_pkg_id, - .mps_oem_check = NULL, - - .get_apic_id = x2apic_cluster_phys_get_apic_id, - .set_apic_id = set_apic_id, - .apic_id_mask = 0xFFFFFFFFu, - - .cpu_mask_to_apicid = x2apic_cpu_mask_to_apicid, - .cpu_mask_to_apicid_and = x2apic_cpu_mask_to_apicid_and, - - .send_IPI_mask = x2apic_send_IPI_mask, - .send_IPI_mask_allbutself = x2apic_send_IPI_mask_allbutself, - .send_IPI_allbutself = x2apic_send_IPI_allbutself, - .send_IPI_all = x2apic_send_IPI_all, - .send_IPI_self = x2apic_send_IPI_self, - - .wakeup_cpu = NULL, - .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, - .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, - .wait_for_init_deassert = NULL, - .smp_callin_clear_local_apic = NULL, - .inquire_remote_apic = NULL, - - .read = native_apic_msr_read, - .write = native_apic_msr_write, - .icr_read = native_x2apic_icr_read, - .icr_write = native_x2apic_icr_write, - .wait_icr_idle = native_x2apic_wait_icr_idle, - .safe_wait_icr_idle = native_safe_x2apic_wait_icr_idle, -}; diff --git a/arch/x86/kernel/genx2apic_phys.c b/arch/x86/kernel/genx2apic_phys.c deleted file mode 100644 index d2d52eb9f7e..00000000000 --- a/arch/x86/kernel/genx2apic_phys.c +++ /dev/null @@ -1,229 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static int x2apic_phys; - -static int set_x2apic_phys_mode(char *arg) -{ - x2apic_phys = 1; - return 0; -} -early_param("x2apic_phys", set_x2apic_phys_mode); - -static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id) -{ - if (cpu_has_x2apic && x2apic_phys) - return 1; - - return 0; -} - -/* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */ - -static const struct cpumask *x2apic_target_cpus(void) -{ - return cpumask_of(0); -} - -static void x2apic_vector_allocation_domain(int cpu, struct cpumask *retmask) -{ - cpumask_clear(retmask); - cpumask_set_cpu(cpu, retmask); -} - -static void __x2apic_send_IPI_dest(unsigned int apicid, int vector, - unsigned int dest) -{ - unsigned long cfg; - - cfg = __prepare_ICR(0, vector, dest); - - /* - * send the IPI. - */ - native_x2apic_icr_write(cfg, apicid); -} - -static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector) -{ - unsigned long query_cpu; - unsigned long flags; - - local_irq_save(flags); - for_each_cpu(query_cpu, mask) { - __x2apic_send_IPI_dest(per_cpu(x86_cpu_to_apicid, query_cpu), - vector, APIC_DEST_PHYSICAL); - } - local_irq_restore(flags); -} - -static void - x2apic_send_IPI_mask_allbutself(const struct cpumask *mask, int vector) -{ - unsigned long this_cpu = smp_processor_id(); - unsigned long query_cpu; - unsigned long flags; - - local_irq_save(flags); - for_each_cpu(query_cpu, mask) { - if (query_cpu != this_cpu) - __x2apic_send_IPI_dest( - per_cpu(x86_cpu_to_apicid, query_cpu), - vector, APIC_DEST_PHYSICAL); - } - local_irq_restore(flags); -} - -static void x2apic_send_IPI_allbutself(int vector) -{ - unsigned long this_cpu = smp_processor_id(); - unsigned long query_cpu; - unsigned long flags; - - local_irq_save(flags); - for_each_online_cpu(query_cpu) { - if (query_cpu == this_cpu) - continue; - __x2apic_send_IPI_dest(per_cpu(x86_cpu_to_apicid, query_cpu), - vector, APIC_DEST_PHYSICAL); - } - local_irq_restore(flags); -} - -static void x2apic_send_IPI_all(int vector) -{ - x2apic_send_IPI_mask(cpu_online_mask, vector); -} - -static int x2apic_apic_id_registered(void) -{ - return 1; -} - -static unsigned int x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask) -{ - /* - * We're using fixed IRQ delivery, can only return one phys APIC ID. - * May as well be the first. - */ - int cpu = cpumask_first(cpumask); - - if ((unsigned)cpu < nr_cpu_ids) - return per_cpu(x86_cpu_to_apicid, cpu); - else - return BAD_APICID; -} - -static unsigned int -x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask) -{ - int cpu; - - /* - * We're using fixed IRQ delivery, can only return one phys APIC ID. - * May as well be the first. - */ - for_each_cpu_and(cpu, cpumask, andmask) { - if (cpumask_test_cpu(cpu, cpu_online_mask)) - break; - } - - if (cpu < nr_cpu_ids) - return per_cpu(x86_cpu_to_apicid, cpu); - - return BAD_APICID; -} - -static unsigned int x2apic_phys_get_apic_id(unsigned long x) -{ - return x; -} - -static unsigned long set_apic_id(unsigned int id) -{ - return id; -} - -static int x2apic_phys_pkg_id(int initial_apicid, int index_msb) -{ - return current_cpu_data.initial_apicid >> index_msb; -} - -static void x2apic_send_IPI_self(int vector) -{ - apic_write(APIC_SELF_IPI, vector); -} - -static void init_x2apic_ldr(void) -{ -} - -struct apic apic_x2apic_phys = { - - .name = "physical x2apic", - .probe = NULL, - .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, - .apic_id_registered = x2apic_apic_id_registered, - - .irq_delivery_mode = dest_Fixed, - .irq_dest_mode = 0, /* physical */ - - .target_cpus = x2apic_target_cpus, - .disable_esr = 0, - .dest_logical = 0, - .check_apicid_used = NULL, - .check_apicid_present = NULL, - - .vector_allocation_domain = x2apic_vector_allocation_domain, - .init_apic_ldr = init_x2apic_ldr, - - .ioapic_phys_id_map = NULL, - .setup_apic_routing = NULL, - .multi_timer_check = NULL, - .apicid_to_node = NULL, - .cpu_to_logical_apicid = NULL, - .cpu_present_to_apicid = default_cpu_present_to_apicid, - .apicid_to_cpu_present = NULL, - .setup_portio_remap = NULL, - .check_phys_apicid_present = default_check_phys_apicid_present, - .enable_apic_mode = NULL, - .phys_pkg_id = x2apic_phys_pkg_id, - .mps_oem_check = NULL, - - .get_apic_id = x2apic_phys_get_apic_id, - .set_apic_id = set_apic_id, - .apic_id_mask = 0xFFFFFFFFu, - - .cpu_mask_to_apicid = x2apic_cpu_mask_to_apicid, - .cpu_mask_to_apicid_and = x2apic_cpu_mask_to_apicid_and, - - .send_IPI_mask = x2apic_send_IPI_mask, - .send_IPI_mask_allbutself = x2apic_send_IPI_mask_allbutself, - .send_IPI_allbutself = x2apic_send_IPI_allbutself, - .send_IPI_all = x2apic_send_IPI_all, - .send_IPI_self = x2apic_send_IPI_self, - - .wakeup_cpu = NULL, - .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, - .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, - .wait_for_init_deassert = NULL, - .smp_callin_clear_local_apic = NULL, - .inquire_remote_apic = NULL, - - .read = native_apic_msr_read, - .write = native_apic_msr_write, - .icr_read = native_x2apic_icr_read, - .icr_write = native_x2apic_icr_write, - .wait_icr_idle = native_x2apic_wait_icr_idle, - .safe_wait_icr_idle = native_safe_x2apic_wait_icr_idle, -}; diff --git a/arch/x86/kernel/genx2apic_uv_x.c b/arch/x86/kernel/genx2apic_uv_x.c deleted file mode 100644 index 20b4ad07c3a..00000000000 --- a/arch/x86/kernel/genx2apic_uv_x.c +++ /dev/null @@ -1,643 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * SGI UV APIC functions (note: not an Intel compatible APIC) - * - * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -DEFINE_PER_CPU(int, x2apic_extra_bits); - -static enum uv_system_type uv_system_type; - -static int uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id) -{ - if (!strcmp(oem_id, "SGI")) { - if (!strcmp(oem_table_id, "UVL")) - uv_system_type = UV_LEGACY_APIC; - else if (!strcmp(oem_table_id, "UVX")) - uv_system_type = UV_X2APIC; - else if (!strcmp(oem_table_id, "UVH")) { - uv_system_type = UV_NON_UNIQUE_APIC; - return 1; - } - } - return 0; -} - -enum uv_system_type get_uv_system_type(void) -{ - return uv_system_type; -} - -int is_uv_system(void) -{ - return uv_system_type != UV_NONE; -} -EXPORT_SYMBOL_GPL(is_uv_system); - -DEFINE_PER_CPU(struct uv_hub_info_s, __uv_hub_info); -EXPORT_PER_CPU_SYMBOL_GPL(__uv_hub_info); - -struct uv_blade_info *uv_blade_info; -EXPORT_SYMBOL_GPL(uv_blade_info); - -short *uv_node_to_blade; -EXPORT_SYMBOL_GPL(uv_node_to_blade); - -short *uv_cpu_to_blade; -EXPORT_SYMBOL_GPL(uv_cpu_to_blade); - -short uv_possible_blades; -EXPORT_SYMBOL_GPL(uv_possible_blades); - -unsigned long sn_rtc_cycles_per_second; -EXPORT_SYMBOL(sn_rtc_cycles_per_second); - -/* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */ - -static const struct cpumask *uv_target_cpus(void) -{ - return cpumask_of(0); -} - -static void uv_vector_allocation_domain(int cpu, struct cpumask *retmask) -{ - cpumask_clear(retmask); - cpumask_set_cpu(cpu, retmask); -} - -int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip) -{ - unsigned long val; - int pnode; - - pnode = uv_apicid_to_pnode(phys_apicid); - val = (1UL << UVH_IPI_INT_SEND_SHFT) | - (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) | - (((long)start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) | - APIC_DM_INIT; - uv_write_global_mmr64(pnode, UVH_IPI_INT, val); - mdelay(10); - - val = (1UL << UVH_IPI_INT_SEND_SHFT) | - (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) | - (((long)start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) | - APIC_DM_STARTUP; - uv_write_global_mmr64(pnode, UVH_IPI_INT, val); - return 0; -} - -static void uv_send_IPI_one(int cpu, int vector) -{ - unsigned long val, apicid; - int pnode; - - apicid = per_cpu(x86_cpu_to_apicid, cpu); - pnode = uv_apicid_to_pnode(apicid); - - val = (1UL << UVH_IPI_INT_SEND_SHFT) | - (apicid << UVH_IPI_INT_APIC_ID_SHFT) | - (vector << UVH_IPI_INT_VECTOR_SHFT); - - uv_write_global_mmr64(pnode, UVH_IPI_INT, val); -} - -static void uv_send_IPI_mask(const struct cpumask *mask, int vector) -{ - unsigned int cpu; - - for_each_cpu(cpu, mask) - uv_send_IPI_one(cpu, vector); -} - -static void uv_send_IPI_mask_allbutself(const struct cpumask *mask, int vector) -{ - unsigned int this_cpu = smp_processor_id(); - unsigned int cpu; - - for_each_cpu(cpu, mask) { - if (cpu != this_cpu) - uv_send_IPI_one(cpu, vector); - } -} - -static void uv_send_IPI_allbutself(int vector) -{ - unsigned int this_cpu = smp_processor_id(); - unsigned int cpu; - - for_each_online_cpu(cpu) { - if (cpu != this_cpu) - uv_send_IPI_one(cpu, vector); - } -} - -static void uv_send_IPI_all(int vector) -{ - uv_send_IPI_mask(cpu_online_mask, vector); -} - -static int uv_apic_id_registered(void) -{ - return 1; -} - -static void uv_init_apic_ldr(void) -{ -} - -static unsigned int uv_cpu_mask_to_apicid(const struct cpumask *cpumask) -{ - /* - * We're using fixed IRQ delivery, can only return one phys APIC ID. - * May as well be the first. - */ - int cpu = cpumask_first(cpumask); - - if ((unsigned)cpu < nr_cpu_ids) - return per_cpu(x86_cpu_to_apicid, cpu); - else - return BAD_APICID; -} - -static unsigned int -uv_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask) -{ - int cpu; - - /* - * We're using fixed IRQ delivery, can only return one phys APIC ID. - * May as well be the first. - */ - for_each_cpu_and(cpu, cpumask, andmask) { - if (cpumask_test_cpu(cpu, cpu_online_mask)) - break; - } - if (cpu < nr_cpu_ids) - return per_cpu(x86_cpu_to_apicid, cpu); - - return BAD_APICID; -} - -static unsigned int x2apic_get_apic_id(unsigned long x) -{ - unsigned int id; - - WARN_ON(preemptible() && num_online_cpus() > 1); - id = x | __get_cpu_var(x2apic_extra_bits); - - return id; -} - -static unsigned long set_apic_id(unsigned int id) -{ - unsigned long x; - - /* maskout x2apic_extra_bits ? */ - x = id; - return x; -} - -static unsigned int uv_read_apic_id(void) -{ - - return x2apic_get_apic_id(apic_read(APIC_ID)); -} - -static int uv_phys_pkg_id(int initial_apicid, int index_msb) -{ - return uv_read_apic_id() >> index_msb; -} - -static void uv_send_IPI_self(int vector) -{ - apic_write(APIC_SELF_IPI, vector); -} - -struct apic apic_x2apic_uv_x = { - - .name = "UV large system", - .probe = NULL, - .acpi_madt_oem_check = uv_acpi_madt_oem_check, - .apic_id_registered = uv_apic_id_registered, - - .irq_delivery_mode = dest_Fixed, - .irq_dest_mode = 1, /* logical */ - - .target_cpus = uv_target_cpus, - .disable_esr = 0, - .dest_logical = APIC_DEST_LOGICAL, - .check_apicid_used = NULL, - .check_apicid_present = NULL, - - .vector_allocation_domain = uv_vector_allocation_domain, - .init_apic_ldr = uv_init_apic_ldr, - - .ioapic_phys_id_map = NULL, - .setup_apic_routing = NULL, - .multi_timer_check = NULL, - .apicid_to_node = NULL, - .cpu_to_logical_apicid = NULL, - .cpu_present_to_apicid = default_cpu_present_to_apicid, - .apicid_to_cpu_present = NULL, - .setup_portio_remap = NULL, - .check_phys_apicid_present = default_check_phys_apicid_present, - .enable_apic_mode = NULL, - .phys_pkg_id = uv_phys_pkg_id, - .mps_oem_check = NULL, - - .get_apic_id = x2apic_get_apic_id, - .set_apic_id = set_apic_id, - .apic_id_mask = 0xFFFFFFFFu, - - .cpu_mask_to_apicid = uv_cpu_mask_to_apicid, - .cpu_mask_to_apicid_and = uv_cpu_mask_to_apicid_and, - - .send_IPI_mask = uv_send_IPI_mask, - .send_IPI_mask_allbutself = uv_send_IPI_mask_allbutself, - .send_IPI_allbutself = uv_send_IPI_allbutself, - .send_IPI_all = uv_send_IPI_all, - .send_IPI_self = uv_send_IPI_self, - - .wakeup_cpu = NULL, - .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, - .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, - .wait_for_init_deassert = NULL, - .smp_callin_clear_local_apic = NULL, - .inquire_remote_apic = NULL, - - .read = native_apic_msr_read, - .write = native_apic_msr_write, - .icr_read = native_x2apic_icr_read, - .icr_write = native_x2apic_icr_write, - .wait_icr_idle = native_x2apic_wait_icr_idle, - .safe_wait_icr_idle = native_safe_x2apic_wait_icr_idle, -}; - -static __cpuinit void set_x2apic_extra_bits(int pnode) -{ - __get_cpu_var(x2apic_extra_bits) = (pnode << 6); -} - -/* - * Called on boot cpu. - */ -static __init int boot_pnode_to_blade(int pnode) -{ - int blade; - - for (blade = 0; blade < uv_num_possible_blades(); blade++) - if (pnode == uv_blade_info[blade].pnode) - return blade; - BUG(); -} - -struct redir_addr { - unsigned long redirect; - unsigned long alias; -}; - -#define DEST_SHIFT UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT - -static __initdata struct redir_addr redir_addrs[] = { - {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR, UVH_SI_ALIAS0_OVERLAY_CONFIG}, - {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR, UVH_SI_ALIAS1_OVERLAY_CONFIG}, - {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR, UVH_SI_ALIAS2_OVERLAY_CONFIG}, -}; - -static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size) -{ - union uvh_si_alias0_overlay_config_u alias; - union uvh_rh_gam_alias210_redirect_config_2_mmr_u redirect; - int i; - - for (i = 0; i < ARRAY_SIZE(redir_addrs); i++) { - alias.v = uv_read_local_mmr(redir_addrs[i].alias); - if (alias.s.base == 0) { - *size = (1UL << alias.s.m_alias); - redirect.v = uv_read_local_mmr(redir_addrs[i].redirect); - *base = (unsigned long)redirect.s.dest_base << DEST_SHIFT; - return; - } - } - BUG(); -} - -static __init void map_low_mmrs(void) -{ - init_extra_mapping_uc(UV_GLOBAL_MMR32_BASE, UV_GLOBAL_MMR32_SIZE); - init_extra_mapping_uc(UV_LOCAL_MMR_BASE, UV_LOCAL_MMR_SIZE); -} - -enum map_type {map_wb, map_uc}; - -static __init void map_high(char *id, unsigned long base, int shift, - int max_pnode, enum map_type map_type) -{ - unsigned long bytes, paddr; - - paddr = base << shift; - bytes = (1UL << shift) * (max_pnode + 1); - printk(KERN_INFO "UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr, - paddr + bytes); - if (map_type == map_uc) - init_extra_mapping_uc(paddr, bytes); - else - init_extra_mapping_wb(paddr, bytes); - -} -static __init void map_gru_high(int max_pnode) -{ - union uvh_rh_gam_gru_overlay_config_mmr_u gru; - int shift = UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT; - - gru.v = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR); - if (gru.s.enable) - map_high("GRU", gru.s.base, shift, max_pnode, map_wb); -} - -static __init void map_config_high(int max_pnode) -{ - union uvh_rh_gam_cfg_overlay_config_mmr_u cfg; - int shift = UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_BASE_SHFT; - - cfg.v = uv_read_local_mmr(UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR); - if (cfg.s.enable) - map_high("CONFIG", cfg.s.base, shift, max_pnode, map_uc); -} - -static __init void map_mmr_high(int max_pnode) -{ - union uvh_rh_gam_mmr_overlay_config_mmr_u mmr; - int shift = UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT; - - mmr.v = uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR); - if (mmr.s.enable) - map_high("MMR", mmr.s.base, shift, max_pnode, map_uc); -} - -static __init void map_mmioh_high(int max_pnode) -{ - union uvh_rh_gam_mmioh_overlay_config_mmr_u mmioh; - int shift = UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT; - - mmioh.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR); - if (mmioh.s.enable) - map_high("MMIOH", mmioh.s.base, shift, max_pnode, map_uc); -} - -static __init void uv_rtc_init(void) -{ - long status; - u64 ticks_per_sec; - - status = uv_bios_freq_base(BIOS_FREQ_BASE_REALTIME_CLOCK, - &ticks_per_sec); - if (status != BIOS_STATUS_SUCCESS || ticks_per_sec < 100000) { - printk(KERN_WARNING - "unable to determine platform RTC clock frequency, " - "guessing.\n"); - /* BIOS gives wrong value for clock freq. so guess */ - sn_rtc_cycles_per_second = 1000000000000UL / 30000UL; - } else - sn_rtc_cycles_per_second = ticks_per_sec; -} - -/* - * percpu heartbeat timer - */ -static void uv_heartbeat(unsigned long ignored) -{ - struct timer_list *timer = &uv_hub_info->scir.timer; - unsigned char bits = uv_hub_info->scir.state; - - /* flip heartbeat bit */ - bits ^= SCIR_CPU_HEARTBEAT; - - /* is this cpu idle? */ - if (idle_cpu(raw_smp_processor_id())) - bits &= ~SCIR_CPU_ACTIVITY; - else - bits |= SCIR_CPU_ACTIVITY; - - /* update system controller interface reg */ - uv_set_scir_bits(bits); - - /* enable next timer period */ - mod_timer(timer, jiffies + SCIR_CPU_HB_INTERVAL); -} - -static void __cpuinit uv_heartbeat_enable(int cpu) -{ - if (!uv_cpu_hub_info(cpu)->scir.enabled) { - struct timer_list *timer = &uv_cpu_hub_info(cpu)->scir.timer; - - uv_set_cpu_scir_bits(cpu, SCIR_CPU_HEARTBEAT|SCIR_CPU_ACTIVITY); - setup_timer(timer, uv_heartbeat, cpu); - timer->expires = jiffies + SCIR_CPU_HB_INTERVAL; - add_timer_on(timer, cpu); - uv_cpu_hub_info(cpu)->scir.enabled = 1; - } - - /* check boot cpu */ - if (!uv_cpu_hub_info(0)->scir.enabled) - uv_heartbeat_enable(0); -} - -#ifdef CONFIG_HOTPLUG_CPU -static void __cpuinit uv_heartbeat_disable(int cpu) -{ - if (uv_cpu_hub_info(cpu)->scir.enabled) { - uv_cpu_hub_info(cpu)->scir.enabled = 0; - del_timer(&uv_cpu_hub_info(cpu)->scir.timer); - } - uv_set_cpu_scir_bits(cpu, 0xff); -} - -/* - * cpu hotplug notifier - */ -static __cpuinit int uv_scir_cpu_notify(struct notifier_block *self, - unsigned long action, void *hcpu) -{ - long cpu = (long)hcpu; - - switch (action) { - case CPU_ONLINE: - uv_heartbeat_enable(cpu); - break; - case CPU_DOWN_PREPARE: - uv_heartbeat_disable(cpu); - break; - default: - break; - } - return NOTIFY_OK; -} - -static __init void uv_scir_register_cpu_notifier(void) -{ - hotcpu_notifier(uv_scir_cpu_notify, 0); -} - -#else /* !CONFIG_HOTPLUG_CPU */ - -static __init void uv_scir_register_cpu_notifier(void) -{ -} - -static __init int uv_init_heartbeat(void) -{ - int cpu; - - if (is_uv_system()) - for_each_online_cpu(cpu) - uv_heartbeat_enable(cpu); - return 0; -} - -late_initcall(uv_init_heartbeat); - -#endif /* !CONFIG_HOTPLUG_CPU */ - -/* - * Called on each cpu to initialize the per_cpu UV data area. - * ZZZ hotplug not supported yet - */ -void __cpuinit uv_cpu_init(void) -{ - /* CPU 0 initilization will be done via uv_system_init. */ - if (!uv_blade_info) - return; - - uv_blade_info[uv_numa_blade_id()].nr_online_cpus++; - - if (get_uv_system_type() == UV_NON_UNIQUE_APIC) - set_x2apic_extra_bits(uv_hub_info->pnode); -} - - -void __init uv_system_init(void) -{ - union uvh_si_addr_map_config_u m_n_config; - union uvh_node_id_u node_id; - unsigned long gnode_upper, lowmem_redir_base, lowmem_redir_size; - int bytes, nid, cpu, lcpu, pnode, blade, i, j, m_val, n_val; - int max_pnode = 0; - unsigned long mmr_base, present; - - map_low_mmrs(); - - m_n_config.v = uv_read_local_mmr(UVH_SI_ADDR_MAP_CONFIG); - m_val = m_n_config.s.m_skt; - n_val = m_n_config.s.n_skt; - mmr_base = - uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR) & - ~UV_MMR_ENABLE; - printk(KERN_DEBUG "UV: global MMR base 0x%lx\n", mmr_base); - - for(i = 0; i < UVH_NODE_PRESENT_TABLE_DEPTH; i++) - uv_possible_blades += - hweight64(uv_read_local_mmr( UVH_NODE_PRESENT_TABLE + i * 8)); - printk(KERN_DEBUG "UV: Found %d blades\n", uv_num_possible_blades()); - - bytes = sizeof(struct uv_blade_info) * uv_num_possible_blades(); - uv_blade_info = kmalloc(bytes, GFP_KERNEL); - - get_lowmem_redirect(&lowmem_redir_base, &lowmem_redir_size); - - bytes = sizeof(uv_node_to_blade[0]) * num_possible_nodes(); - uv_node_to_blade = kmalloc(bytes, GFP_KERNEL); - memset(uv_node_to_blade, 255, bytes); - - bytes = sizeof(uv_cpu_to_blade[0]) * num_possible_cpus(); - uv_cpu_to_blade = kmalloc(bytes, GFP_KERNEL); - memset(uv_cpu_to_blade, 255, bytes); - - blade = 0; - for (i = 0; i < UVH_NODE_PRESENT_TABLE_DEPTH; i++) { - present = uv_read_local_mmr(UVH_NODE_PRESENT_TABLE + i * 8); - for (j = 0; j < 64; j++) { - if (!test_bit(j, &present)) - continue; - uv_blade_info[blade].pnode = (i * 64 + j); - uv_blade_info[blade].nr_possible_cpus = 0; - uv_blade_info[blade].nr_online_cpus = 0; - blade++; - } - } - - node_id.v = uv_read_local_mmr(UVH_NODE_ID); - gnode_upper = (((unsigned long)node_id.s.node_id) & - ~((1 << n_val) - 1)) << m_val; - - uv_bios_init(); - uv_bios_get_sn_info(0, &uv_type, &sn_partition_id, - &sn_coherency_id, &sn_region_size); - uv_rtc_init(); - - for_each_present_cpu(cpu) { - nid = cpu_to_node(cpu); - pnode = uv_apicid_to_pnode(per_cpu(x86_cpu_to_apicid, cpu)); - blade = boot_pnode_to_blade(pnode); - lcpu = uv_blade_info[blade].nr_possible_cpus; - uv_blade_info[blade].nr_possible_cpus++; - - uv_cpu_hub_info(cpu)->lowmem_remap_base = lowmem_redir_base; - uv_cpu_hub_info(cpu)->lowmem_remap_top = lowmem_redir_size; - uv_cpu_hub_info(cpu)->m_val = m_val; - uv_cpu_hub_info(cpu)->n_val = m_val; - uv_cpu_hub_info(cpu)->numa_blade_id = blade; - uv_cpu_hub_info(cpu)->blade_processor_id = lcpu; - uv_cpu_hub_info(cpu)->pnode = pnode; - uv_cpu_hub_info(cpu)->pnode_mask = (1 << n_val) - 1; - uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1; - uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper; - uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base; - uv_cpu_hub_info(cpu)->coherency_domain_number = sn_coherency_id; - uv_cpu_hub_info(cpu)->scir.offset = SCIR_LOCAL_MMR_BASE + lcpu; - uv_node_to_blade[nid] = blade; - uv_cpu_to_blade[cpu] = blade; - max_pnode = max(pnode, max_pnode); - - printk(KERN_DEBUG "UV: cpu %d, apicid 0x%x, pnode %d, nid %d, " - "lcpu %d, blade %d\n", - cpu, per_cpu(x86_cpu_to_apicid, cpu), pnode, nid, - lcpu, blade); - } - - map_gru_high(max_pnode); - map_mmr_high(max_pnode); - map_config_high(max_pnode); - map_mmioh_high(max_pnode); - - uv_cpu_init(); - uv_scir_register_cpu_notifier(); - proc_mkdir("sgi_uv", NULL); -} diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c deleted file mode 100644 index 00e6071cefc..00000000000 --- a/arch/x86/kernel/io_apic.c +++ /dev/null @@ -1,4160 +0,0 @@ -/* - * Intel IO-APIC support for multi-Pentium hosts. - * - * Copyright (C) 1997, 1998, 1999, 2000, 2009 Ingo Molnar, Hajnalka Szabo - * - * Many thanks to Stig Venaas for trying out countless experimental - * patches and reporting/debugging problems patiently! - * - * (c) 1999, Multiple IO-APIC support, developed by - * Ken-ichi Yaku and - * Hidemi Kishimoto , - * further tested and cleaned up by Zach Brown - * and Ingo Molnar - * - * Fixes - * Maciej W. Rozycki : Bits for genuine 82489DX APICs; - * thanks to Eric Gilmore - * and Rolf G. Tews - * for testing these extensively - * Paul Diefenbaugh : Added full ACPI support - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* time_after() */ -#ifdef CONFIG_ACPI -#include -#endif -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define __apicdebuginit(type) static type __init - -/* - * Is the SiS APIC rmw bug present ? - * -1 = don't know, 0 = no, 1 = yes - */ -int sis_apic_bug = -1; - -static DEFINE_SPINLOCK(ioapic_lock); -static DEFINE_SPINLOCK(vector_lock); - -/* - * # of IRQ routing registers - */ -int nr_ioapic_registers[MAX_IO_APICS]; - -/* I/O APIC entries */ -struct mpc_ioapic mp_ioapics[MAX_IO_APICS]; -int nr_ioapics; - -/* MP IRQ source entries */ -struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES]; - -/* # of MP IRQ source entries */ -int mp_irq_entries; - -#if defined (CONFIG_MCA) || defined (CONFIG_EISA) -int mp_bus_id_to_type[MAX_MP_BUSSES]; -#endif - -DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES); - -int skip_ioapic_setup; - -void arch_disable_smp_support(void) -{ -#ifdef CONFIG_PCI - noioapicquirk = 1; - noioapicreroute = -1; -#endif - skip_ioapic_setup = 1; -} - -static int __init parse_noapic(char *str) -{ - /* disable IO-APIC */ - arch_disable_smp_support(); - return 0; -} -early_param("noapic", parse_noapic); - -struct irq_pin_list; - -/* - * This is performance-critical, we want to do it O(1) - * - * the indexing order of this array favors 1:1 mappings - * between pins and IRQs. - */ - -struct irq_pin_list { - int apic, pin; - struct irq_pin_list *next; -}; - -static struct irq_pin_list *get_one_free_irq_2_pin(int cpu) -{ - struct irq_pin_list *pin; - int node; - - node = cpu_to_node(cpu); - - pin = kzalloc_node(sizeof(*pin), GFP_ATOMIC, node); - - return pin; -} - -struct irq_cfg { - struct irq_pin_list *irq_2_pin; - cpumask_var_t domain; - cpumask_var_t old_domain; - unsigned move_cleanup_count; - u8 vector; - u8 move_in_progress : 1; -#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC - u8 move_desc_pending : 1; -#endif -}; - -/* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */ -#ifdef CONFIG_SPARSE_IRQ -static struct irq_cfg irq_cfgx[] = { -#else -static struct irq_cfg irq_cfgx[NR_IRQS] = { -#endif - [0] = { .vector = IRQ0_VECTOR, }, - [1] = { .vector = IRQ1_VECTOR, }, - [2] = { .vector = IRQ2_VECTOR, }, - [3] = { .vector = IRQ3_VECTOR, }, - [4] = { .vector = IRQ4_VECTOR, }, - [5] = { .vector = IRQ5_VECTOR, }, - [6] = { .vector = IRQ6_VECTOR, }, - [7] = { .vector = IRQ7_VECTOR, }, - [8] = { .vector = IRQ8_VECTOR, }, - [9] = { .vector = IRQ9_VECTOR, }, - [10] = { .vector = IRQ10_VECTOR, }, - [11] = { .vector = IRQ11_VECTOR, }, - [12] = { .vector = IRQ12_VECTOR, }, - [13] = { .vector = IRQ13_VECTOR, }, - [14] = { .vector = IRQ14_VECTOR, }, - [15] = { .vector = IRQ15_VECTOR, }, -}; - -int __init arch_early_irq_init(void) -{ - struct irq_cfg *cfg; - struct irq_desc *desc; - int count; - int i; - - cfg = irq_cfgx; - count = ARRAY_SIZE(irq_cfgx); - - for (i = 0; i < count; i++) { - desc = irq_to_desc(i); - desc->chip_data = &cfg[i]; - alloc_bootmem_cpumask_var(&cfg[i].domain); - alloc_bootmem_cpumask_var(&cfg[i].old_domain); - if (i < NR_IRQS_LEGACY) - cpumask_setall(cfg[i].domain); - } - - return 0; -} - -#ifdef CONFIG_SPARSE_IRQ -static struct irq_cfg *irq_cfg(unsigned int irq) -{ - struct irq_cfg *cfg = NULL; - struct irq_desc *desc; - - desc = irq_to_desc(irq); - if (desc) - cfg = desc->chip_data; - - return cfg; -} - -static struct irq_cfg *get_one_free_irq_cfg(int cpu) -{ - struct irq_cfg *cfg; - int node; - - node = cpu_to_node(cpu); - - cfg = kzalloc_node(sizeof(*cfg), GFP_ATOMIC, node); - if (cfg) { - if (!alloc_cpumask_var_node(&cfg->domain, GFP_ATOMIC, node)) { - kfree(cfg); - cfg = NULL; - } else if (!alloc_cpumask_var_node(&cfg->old_domain, - GFP_ATOMIC, node)) { - free_cpumask_var(cfg->domain); - kfree(cfg); - cfg = NULL; - } else { - cpumask_clear(cfg->domain); - cpumask_clear(cfg->old_domain); - } - } - - return cfg; -} - -int arch_init_chip_data(struct irq_desc *desc, int cpu) -{ - struct irq_cfg *cfg; - - cfg = desc->chip_data; - if (!cfg) { - desc->chip_data = get_one_free_irq_cfg(cpu); - if (!desc->chip_data) { - printk(KERN_ERR "can not alloc irq_cfg\n"); - BUG_ON(1); - } - } - - return 0; -} - -#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC - -static void -init_copy_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg, int cpu) -{ - struct irq_pin_list *old_entry, *head, *tail, *entry; - - cfg->irq_2_pin = NULL; - old_entry = old_cfg->irq_2_pin; - if (!old_entry) - return; - - entry = get_one_free_irq_2_pin(cpu); - if (!entry) - return; - - entry->apic = old_entry->apic; - entry->pin = old_entry->pin; - head = entry; - tail = entry; - old_entry = old_entry->next; - while (old_entry) { - entry = get_one_free_irq_2_pin(cpu); - if (!entry) { - entry = head; - while (entry) { - head = entry->next; - kfree(entry); - entry = head; - } - /* still use the old one */ - return; - } - entry->apic = old_entry->apic; - entry->pin = old_entry->pin; - tail->next = entry; - tail = entry; - old_entry = old_entry->next; - } - - tail->next = NULL; - cfg->irq_2_pin = head; -} - -static void free_irq_2_pin(struct irq_cfg *old_cfg, struct irq_cfg *cfg) -{ - struct irq_pin_list *entry, *next; - - if (old_cfg->irq_2_pin == cfg->irq_2_pin) - return; - - entry = old_cfg->irq_2_pin; - - while (entry) { - next = entry->next; - kfree(entry); - entry = next; - } - old_cfg->irq_2_pin = NULL; -} - -void arch_init_copy_chip_data(struct irq_desc *old_desc, - struct irq_desc *desc, int cpu) -{ - struct irq_cfg *cfg; - struct irq_cfg *old_cfg; - - cfg = get_one_free_irq_cfg(cpu); - - if (!cfg) - return; - - desc->chip_data = cfg; - - old_cfg = old_desc->chip_data; - - memcpy(cfg, old_cfg, sizeof(struct irq_cfg)); - - init_copy_irq_2_pin(old_cfg, cfg, cpu); -} - -static void free_irq_cfg(struct irq_cfg *old_cfg) -{ - kfree(old_cfg); -} - -void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc) -{ - struct irq_cfg *old_cfg, *cfg; - - old_cfg = old_desc->chip_data; - cfg = desc->chip_data; - - if (old_cfg == cfg) - return; - - if (old_cfg) { - free_irq_2_pin(old_cfg, cfg); - free_irq_cfg(old_cfg); - old_desc->chip_data = NULL; - } -} - -static void -set_extra_move_desc(struct irq_desc *desc, const struct cpumask *mask) -{ - struct irq_cfg *cfg = desc->chip_data; - - if (!cfg->move_in_progress) { - /* it means that domain is not changed */ - if (!cpumask_intersects(desc->affinity, mask)) - cfg->move_desc_pending = 1; - } -} -#endif - -#else -static struct irq_cfg *irq_cfg(unsigned int irq) -{ - return irq < nr_irqs ? irq_cfgx + irq : NULL; -} - -#endif - -#ifndef CONFIG_NUMA_MIGRATE_IRQ_DESC -static inline void -set_extra_move_desc(struct irq_desc *desc, const struct cpumask *mask) -{ -} -#endif - -struct io_apic { - unsigned int index; - unsigned int unused[3]; - unsigned int data; -}; - -static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx) -{ - return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx) - + (mp_ioapics[idx].apicaddr & ~PAGE_MASK); -} - -static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg) -{ - struct io_apic __iomem *io_apic = io_apic_base(apic); - writel(reg, &io_apic->index); - return readl(&io_apic->data); -} - -static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value) -{ - struct io_apic __iomem *io_apic = io_apic_base(apic); - writel(reg, &io_apic->index); - writel(value, &io_apic->data); -} - -/* - * Re-write a value: to be used for read-modify-write - * cycles where the read already set up the index register. - * - * Older SiS APIC requires we rewrite the index register - */ -static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value) -{ - struct io_apic __iomem *io_apic = io_apic_base(apic); - - if (sis_apic_bug) - writel(reg, &io_apic->index); - writel(value, &io_apic->data); -} - -static bool io_apic_level_ack_pending(struct irq_cfg *cfg) -{ - struct irq_pin_list *entry; - unsigned long flags; - - spin_lock_irqsave(&ioapic_lock, flags); - entry = cfg->irq_2_pin; - for (;;) { - unsigned int reg; - int pin; - - if (!entry) - break; - pin = entry->pin; - reg = io_apic_read(entry->apic, 0x10 + pin*2); - /* Is the remote IRR bit set? */ - if (reg & IO_APIC_REDIR_REMOTE_IRR) { - spin_unlock_irqrestore(&ioapic_lock, flags); - return true; - } - if (!entry->next) - break; - entry = entry->next; - } - spin_unlock_irqrestore(&ioapic_lock, flags); - - return false; -} - -union entry_union { - struct { u32 w1, w2; }; - struct IO_APIC_route_entry entry; -}; - -static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin) -{ - union entry_union eu; - unsigned long flags; - spin_lock_irqsave(&ioapic_lock, flags); - eu.w1 = io_apic_read(apic, 0x10 + 2 * pin); - eu.w2 = io_apic_read(apic, 0x11 + 2 * pin); - spin_unlock_irqrestore(&ioapic_lock, flags); - return eu.entry; -} - -/* - * When we write a new IO APIC routing entry, we need to write the high - * word first! If the mask bit in the low word is clear, we will enable - * the interrupt, and we need to make sure the entry is fully populated - * before that happens. - */ -static void -__ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) -{ - union entry_union eu; - eu.entry = e; - io_apic_write(apic, 0x11 + 2*pin, eu.w2); - io_apic_write(apic, 0x10 + 2*pin, eu.w1); -} - -void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) -{ - unsigned long flags; - spin_lock_irqsave(&ioapic_lock, flags); - __ioapic_write_entry(apic, pin, e); - spin_unlock_irqrestore(&ioapic_lock, flags); -} - -/* - * When we mask an IO APIC routing entry, we need to write the low - * word first, in order to set the mask bit before we change the - * high bits! - */ -static void ioapic_mask_entry(int apic, int pin) -{ - unsigned long flags; - union entry_union eu = { .entry.mask = 1 }; - - spin_lock_irqsave(&ioapic_lock, flags); - io_apic_write(apic, 0x10 + 2*pin, eu.w1); - io_apic_write(apic, 0x11 + 2*pin, eu.w2); - spin_unlock_irqrestore(&ioapic_lock, flags); -} - -#ifdef CONFIG_SMP -static void send_cleanup_vector(struct irq_cfg *cfg) -{ - cpumask_var_t cleanup_mask; - - if (unlikely(!alloc_cpumask_var(&cleanup_mask, GFP_ATOMIC))) { - unsigned int i; - cfg->move_cleanup_count = 0; - for_each_cpu_and(i, cfg->old_domain, cpu_online_mask) - cfg->move_cleanup_count++; - for_each_cpu_and(i, cfg->old_domain, cpu_online_mask) - apic->send_IPI_mask(cpumask_of(i), IRQ_MOVE_CLEANUP_VECTOR); - } else { - cpumask_and(cleanup_mask, cfg->old_domain, cpu_online_mask); - cfg->move_cleanup_count = cpumask_weight(cleanup_mask); - apic->send_IPI_mask(cleanup_mask, IRQ_MOVE_CLEANUP_VECTOR); - free_cpumask_var(cleanup_mask); - } - cfg->move_in_progress = 0; -} - -static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq_cfg *cfg) -{ - int apic, pin; - struct irq_pin_list *entry; - u8 vector = cfg->vector; - - entry = cfg->irq_2_pin; - for (;;) { - unsigned int reg; - - if (!entry) - break; - - apic = entry->apic; - pin = entry->pin; -#ifdef CONFIG_INTR_REMAP - /* - * With interrupt-remapping, destination information comes - * from interrupt-remapping table entry. - */ - if (!irq_remapped(irq)) - io_apic_write(apic, 0x11 + pin*2, dest); -#else - io_apic_write(apic, 0x11 + pin*2, dest); -#endif - reg = io_apic_read(apic, 0x10 + pin*2); - reg &= ~IO_APIC_REDIR_VECTOR_MASK; - reg |= vector; - io_apic_modify(apic, 0x10 + pin*2, reg); - if (!entry->next) - break; - entry = entry->next; - } -} - -static int -assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask); - -/* - * Either sets desc->affinity to a valid value, and returns - * ->cpu_mask_to_apicid of that, or returns BAD_APICID and - * leaves desc->affinity untouched. - */ -static unsigned int -set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask) -{ - struct irq_cfg *cfg; - unsigned int irq; - - if (!cpumask_intersects(mask, cpu_online_mask)) - return BAD_APICID; - - irq = desc->irq; - cfg = desc->chip_data; - if (assign_irq_vector(irq, cfg, mask)) - return BAD_APICID; - - cpumask_and(desc->affinity, cfg->domain, mask); - set_extra_move_desc(desc, mask); - - return apic->cpu_mask_to_apicid_and(desc->affinity, cpu_online_mask); -} - -static void -set_ioapic_affinity_irq_desc(struct irq_desc *desc, const struct cpumask *mask) -{ - struct irq_cfg *cfg; - unsigned long flags; - unsigned int dest; - unsigned int irq; - - irq = desc->irq; - cfg = desc->chip_data; - - spin_lock_irqsave(&ioapic_lock, flags); - dest = set_desc_affinity(desc, mask); - if (dest != BAD_APICID) { - /* Only the high 8 bits are valid. */ - dest = SET_APIC_LOGICAL_ID(dest); - __target_IO_APIC_irq(irq, dest, cfg); - } - spin_unlock_irqrestore(&ioapic_lock, flags); -} - -static void -set_ioapic_affinity_irq(unsigned int irq, const struct cpumask *mask) -{ - struct irq_desc *desc; - - desc = irq_to_desc(irq); - - set_ioapic_affinity_irq_desc(desc, mask); -} -#endif /* CONFIG_SMP */ - -/* - * The common case is 1:1 IRQ<->pin mappings. Sometimes there are - * shared ISA-space IRQs, so we have to support them. We are super - * fast in the common case, and fast for shared ISA-space IRQs. - */ -static void add_pin_to_irq_cpu(struct irq_cfg *cfg, int cpu, int apic, int pin) -{ - struct irq_pin_list *entry; - - entry = cfg->irq_2_pin; - if (!entry) { - entry = get_one_free_irq_2_pin(cpu); - if (!entry) { - printk(KERN_ERR "can not alloc irq_2_pin to add %d - %d\n", - apic, pin); - return; - } - cfg->irq_2_pin = entry; - entry->apic = apic; - entry->pin = pin; - return; - } - - while (entry->next) { - /* not again, please */ - if (entry->apic == apic && entry->pin == pin) - return; - - entry = entry->next; - } - - entry->next = get_one_free_irq_2_pin(cpu); - entry = entry->next; - entry->apic = apic; - entry->pin = pin; -} - -/* - * Reroute an IRQ to a different pin. - */ -static void __init replace_pin_at_irq_cpu(struct irq_cfg *cfg, int cpu, - int oldapic, int oldpin, - int newapic, int newpin) -{ - struct irq_pin_list *entry = cfg->irq_2_pin; - int replaced = 0; - - while (entry) { - if (entry->apic == oldapic && entry->pin == oldpin) { - entry->apic = newapic; - entry->pin = newpin; - replaced = 1; - /* every one is different, right? */ - break; - } - entry = entry->next; - } - - /* why? call replace before add? */ - if (!replaced) - add_pin_to_irq_cpu(cfg, cpu, newapic, newpin); -} - -static inline void io_apic_modify_irq(struct irq_cfg *cfg, - int mask_and, int mask_or, - void (*final)(struct irq_pin_list *entry)) -{ - int pin; - struct irq_pin_list *entry; - - for (entry = cfg->irq_2_pin; entry != NULL; entry = entry->next) { - unsigned int reg; - pin = entry->pin; - reg = io_apic_read(entry->apic, 0x10 + pin * 2); - reg &= mask_and; - reg |= mask_or; - io_apic_modify(entry->apic, 0x10 + pin * 2, reg); - if (final) - final(entry); - } -} - -static void __unmask_IO_APIC_irq(struct irq_cfg *cfg) -{ - io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED, 0, NULL); -} - -#ifdef CONFIG_X86_64 -static void io_apic_sync(struct irq_pin_list *entry) -{ - /* - * Synchronize the IO-APIC and the CPU by doing - * a dummy read from the IO-APIC - */ - struct io_apic __iomem *io_apic; - io_apic = io_apic_base(entry->apic); - readl(&io_apic->data); -} - -static void __mask_IO_APIC_irq(struct irq_cfg *cfg) -{ - io_apic_modify_irq(cfg, ~0, IO_APIC_REDIR_MASKED, &io_apic_sync); -} -#else /* CONFIG_X86_32 */ -static void __mask_IO_APIC_irq(struct irq_cfg *cfg) -{ - io_apic_modify_irq(cfg, ~0, IO_APIC_REDIR_MASKED, NULL); -} - -static void __mask_and_edge_IO_APIC_irq(struct irq_cfg *cfg) -{ - io_apic_modify_irq(cfg, ~IO_APIC_REDIR_LEVEL_TRIGGER, - IO_APIC_REDIR_MASKED, NULL); -} - -static void __unmask_and_level_IO_APIC_irq(struct irq_cfg *cfg) -{ - io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED, - IO_APIC_REDIR_LEVEL_TRIGGER, NULL); -} -#endif /* CONFIG_X86_32 */ - -static void mask_IO_APIC_irq_desc(struct irq_desc *desc) -{ - struct irq_cfg *cfg = desc->chip_data; - unsigned long flags; - - BUG_ON(!cfg); - - spin_lock_irqsave(&ioapic_lock, flags); - __mask_IO_APIC_irq(cfg); - spin_unlock_irqrestore(&ioapic_lock, flags); -} - -static void unmask_IO_APIC_irq_desc(struct irq_desc *desc) -{ - struct irq_cfg *cfg = desc->chip_data; - unsigned long flags; - - spin_lock_irqsave(&ioapic_lock, flags); - __unmask_IO_APIC_irq(cfg); - spin_unlock_irqrestore(&ioapic_lock, flags); -} - -static void mask_IO_APIC_irq(unsigned int irq) -{ - struct irq_desc *desc = irq_to_desc(irq); - - mask_IO_APIC_irq_desc(desc); -} -static void unmask_IO_APIC_irq(unsigned int irq) -{ - struct irq_desc *desc = irq_to_desc(irq); - - unmask_IO_APIC_irq_desc(desc); -} - -static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) -{ - struct IO_APIC_route_entry entry; - - /* Check delivery_mode to be sure we're not clearing an SMI pin */ - entry = ioapic_read_entry(apic, pin); - if (entry.delivery_mode == dest_SMI) - return; - /* - * Disable it in the IO-APIC irq-routing table: - */ - ioapic_mask_entry(apic, pin); -} - -static void clear_IO_APIC (void) -{ - int apic, pin; - - for (apic = 0; apic < nr_ioapics; apic++) - for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) - clear_IO_APIC_pin(apic, pin); -} - -#ifdef CONFIG_X86_32 -/* - * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to - * specific CPU-side IRQs. - */ - -#define MAX_PIRQS 8 -static int pirq_entries[MAX_PIRQS] = { - [0 ... MAX_PIRQS - 1] = -1 -}; - -static int __init ioapic_pirq_setup(char *str) -{ - int i, max; - int ints[MAX_PIRQS+1]; - - get_options(str, ARRAY_SIZE(ints), ints); - - apic_printk(APIC_VERBOSE, KERN_INFO - "PIRQ redirection, working around broken MP-BIOS.\n"); - max = MAX_PIRQS; - if (ints[0] < MAX_PIRQS) - max = ints[0]; - - for (i = 0; i < max; i++) { - apic_printk(APIC_VERBOSE, KERN_DEBUG - "... PIRQ%d -> IRQ %d\n", i, ints[i+1]); - /* - * PIRQs are mapped upside down, usually. - */ - pirq_entries[MAX_PIRQS-i-1] = ints[i+1]; - } - return 1; -} - -__setup("pirq=", ioapic_pirq_setup); -#endif /* CONFIG_X86_32 */ - -#ifdef CONFIG_INTR_REMAP -/* I/O APIC RTE contents at the OS boot up */ -static struct IO_APIC_route_entry *early_ioapic_entries[MAX_IO_APICS]; - -/* - * Saves and masks all the unmasked IO-APIC RTE's - */ -int save_mask_IO_APIC_setup(void) -{ - union IO_APIC_reg_01 reg_01; - unsigned long flags; - int apic, pin; - - /* - * The number of IO-APIC IRQ registers (== #pins): - */ - for (apic = 0; apic < nr_ioapics; apic++) { - spin_lock_irqsave(&ioapic_lock, flags); - reg_01.raw = io_apic_read(apic, 1); - spin_unlock_irqrestore(&ioapic_lock, flags); - nr_ioapic_registers[apic] = reg_01.bits.entries+1; - } - - for (apic = 0; apic < nr_ioapics; apic++) { - early_ioapic_entries[apic] = - kzalloc(sizeof(struct IO_APIC_route_entry) * - nr_ioapic_registers[apic], GFP_KERNEL); - if (!early_ioapic_entries[apic]) - goto nomem; - } - - for (apic = 0; apic < nr_ioapics; apic++) - for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { - struct IO_APIC_route_entry entry; - - entry = early_ioapic_entries[apic][pin] = - ioapic_read_entry(apic, pin); - if (!entry.mask) { - entry.mask = 1; - ioapic_write_entry(apic, pin, entry); - } - } - - return 0; - -nomem: - while (apic >= 0) - kfree(early_ioapic_entries[apic--]); - memset(early_ioapic_entries, 0, - ARRAY_SIZE(early_ioapic_entries)); - - return -ENOMEM; -} - -void restore_IO_APIC_setup(void) -{ - int apic, pin; - - for (apic = 0; apic < nr_ioapics; apic++) { - if (!early_ioapic_entries[apic]) - break; - for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) - ioapic_write_entry(apic, pin, - early_ioapic_entries[apic][pin]); - kfree(early_ioapic_entries[apic]); - early_ioapic_entries[apic] = NULL; - } -} - -void reinit_intr_remapped_IO_APIC(int intr_remapping) -{ - /* - * for now plain restore of previous settings. - * TBD: In the case of OS enabling interrupt-remapping, - * IO-APIC RTE's need to be setup to point to interrupt-remapping - * table entries. for now, do a plain restore, and wait for - * the setup_IO_APIC_irqs() to do proper initialization. - */ - restore_IO_APIC_setup(); -} -#endif - -/* - * Find the IRQ entry number of a certain pin. - */ -static int find_irq_entry(int apic, int pin, int type) -{ - int i; - - for (i = 0; i < mp_irq_entries; i++) - if (mp_irqs[i].irqtype == type && - (mp_irqs[i].dstapic == mp_ioapics[apic].apicid || - mp_irqs[i].dstapic == MP_APIC_ALL) && - mp_irqs[i].dstirq == pin) - return i; - - return -1; -} - -/* - * Find the pin to which IRQ[irq] (ISA) is connected - */ -static int __init find_isa_irq_pin(int irq, int type) -{ - int i; - - for (i = 0; i < mp_irq_entries; i++) { - int lbus = mp_irqs[i].srcbus; - - if (test_bit(lbus, mp_bus_not_pci) && - (mp_irqs[i].irqtype == type) && - (mp_irqs[i].srcbusirq == irq)) - - return mp_irqs[i].dstirq; - } - return -1; -} - -static int __init find_isa_irq_apic(int irq, int type) -{ - int i; - - for (i = 0; i < mp_irq_entries; i++) { - int lbus = mp_irqs[i].srcbus; - - if (test_bit(lbus, mp_bus_not_pci) && - (mp_irqs[i].irqtype == type) && - (mp_irqs[i].srcbusirq == irq)) - break; - } - if (i < mp_irq_entries) { - int apic; - for(apic = 0; apic < nr_ioapics; apic++) { - if (mp_ioapics[apic].apicid == mp_irqs[i].dstapic) - return apic; - } - } - - return -1; -} - -/* - * Find a specific PCI IRQ entry. - * Not an __init, possibly needed by modules - */ -static int pin_2_irq(int idx, int apic, int pin); - -int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin) -{ - int apic, i, best_guess = -1; - - apic_printk(APIC_DEBUG, "querying PCI -> IRQ mapping bus:%d, slot:%d, pin:%d.\n", - bus, slot, pin); - if (test_bit(bus, mp_bus_not_pci)) { - apic_printk(APIC_VERBOSE, "PCI BIOS passed nonexistent PCI bus %d!\n", bus); - return -1; - } - for (i = 0; i < mp_irq_entries; i++) { - int lbus = mp_irqs[i].srcbus; - - for (apic = 0; apic < nr_ioapics; apic++) - if (mp_ioapics[apic].apicid == mp_irqs[i].dstapic || - mp_irqs[i].dstapic == MP_APIC_ALL) - break; - - if (!test_bit(lbus, mp_bus_not_pci) && - !mp_irqs[i].irqtype && - (bus == lbus) && - (slot == ((mp_irqs[i].srcbusirq >> 2) & 0x1f))) { - int irq = pin_2_irq(i, apic, mp_irqs[i].dstirq); - - if (!(apic || IO_APIC_IRQ(irq))) - continue; - - if (pin == (mp_irqs[i].srcbusirq & 3)) - return irq; - /* - * Use the first all-but-pin matching entry as a - * best-guess fuzzy result for broken mptables. - */ - if (best_guess < 0) - best_guess = irq; - } - } - return best_guess; -} - -EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector); - -#if defined(CONFIG_EISA) || defined(CONFIG_MCA) -/* - * EISA Edge/Level control register, ELCR - */ -static int EISA_ELCR(unsigned int irq) -{ - if (irq < NR_IRQS_LEGACY) { - unsigned int port = 0x4d0 + (irq >> 3); - return (inb(port) >> (irq & 7)) & 1; - } - apic_printk(APIC_VERBOSE, KERN_INFO - "Broken MPtable reports ISA irq %d\n", irq); - return 0; -} - -#endif - -/* ISA interrupts are always polarity zero edge triggered, - * when listed as conforming in the MP table. */ - -#define default_ISA_trigger(idx) (0) -#define default_ISA_polarity(idx) (0) - -/* EISA interrupts are always polarity zero and can be edge or level - * trigger depending on the ELCR value. If an interrupt is listed as - * EISA conforming in the MP table, that means its trigger type must - * be read in from the ELCR */ - -#define default_EISA_trigger(idx) (EISA_ELCR(mp_irqs[idx].srcbusirq)) -#define default_EISA_polarity(idx) default_ISA_polarity(idx) - -/* PCI interrupts are always polarity one level triggered, - * when listed as conforming in the MP table. */ - -#define default_PCI_trigger(idx) (1) -#define default_PCI_polarity(idx) (1) - -/* MCA interrupts are always polarity zero level triggered, - * when listed as conforming in the MP table. */ - -#define default_MCA_trigger(idx) (1) -#define default_MCA_polarity(idx) default_ISA_polarity(idx) - -static int MPBIOS_polarity(int idx) -{ - int bus = mp_irqs[idx].srcbus; - int polarity; - - /* - * Determine IRQ line polarity (high active or low active): - */ - switch (mp_irqs[idx].irqflag & 3) - { - case 0: /* conforms, ie. bus-type dependent polarity */ - if (test_bit(bus, mp_bus_not_pci)) - polarity = default_ISA_polarity(idx); - else - polarity = default_PCI_polarity(idx); - break; - case 1: /* high active */ - { - polarity = 0; - break; - } - case 2: /* reserved */ - { - printk(KERN_WARNING "broken BIOS!!\n"); - polarity = 1; - break; - } - case 3: /* low active */ - { - polarity = 1; - break; - } - default: /* invalid */ - { - printk(KERN_WARNING "broken BIOS!!\n"); - polarity = 1; - break; - } - } - return polarity; -} - -static int MPBIOS_trigger(int idx) -{ - int bus = mp_irqs[idx].srcbus; - int trigger; - - /* - * Determine IRQ trigger mode (edge or level sensitive): - */ - switch ((mp_irqs[idx].irqflag>>2) & 3) - { - case 0: /* conforms, ie. bus-type dependent */ - if (test_bit(bus, mp_bus_not_pci)) - trigger = default_ISA_trigger(idx); - else - trigger = default_PCI_trigger(idx); -#if defined(CONFIG_EISA) || defined(CONFIG_MCA) - switch (mp_bus_id_to_type[bus]) { - case MP_BUS_ISA: /* ISA pin */ - { - /* set before the switch */ - break; - } - case MP_BUS_EISA: /* EISA pin */ - { - trigger = default_EISA_trigger(idx); - break; - } - case MP_BUS_PCI: /* PCI pin */ - { - /* set before the switch */ - break; - } - case MP_BUS_MCA: /* MCA pin */ - { - trigger = default_MCA_trigger(idx); - break; - } - default: - { - printk(KERN_WARNING "broken BIOS!!\n"); - trigger = 1; - break; - } - } -#endif - break; - case 1: /* edge */ - { - trigger = 0; - break; - } - case 2: /* reserved */ - { - printk(KERN_WARNING "broken BIOS!!\n"); - trigger = 1; - break; - } - case 3: /* level */ - { - trigger = 1; - break; - } - default: /* invalid */ - { - printk(KERN_WARNING "broken BIOS!!\n"); - trigger = 0; - break; - } - } - return trigger; -} - -static inline int irq_polarity(int idx) -{ - return MPBIOS_polarity(idx); -} - -static inline int irq_trigger(int idx) -{ - return MPBIOS_trigger(idx); -} - -int (*ioapic_renumber_irq)(int ioapic, int irq); -static int pin_2_irq(int idx, int apic, int pin) -{ - int irq, i; - int bus = mp_irqs[idx].srcbus; - - /* - * Debugging check, we are in big trouble if this message pops up! - */ - if (mp_irqs[idx].dstirq != pin) - printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n"); - - if (test_bit(bus, mp_bus_not_pci)) { - irq = mp_irqs[idx].srcbusirq; - } else { - /* - * PCI IRQs are mapped in order - */ - i = irq = 0; - while (i < apic) - irq += nr_ioapic_registers[i++]; - irq += pin; - /* - * For MPS mode, so far only needed by ES7000 platform - */ - if (ioapic_renumber_irq) - irq = ioapic_renumber_irq(apic, irq); - } - -#ifdef CONFIG_X86_32 - /* - * PCI IRQ command line redirection. Yes, limits are hardcoded. - */ - if ((pin >= 16) && (pin <= 23)) { - if (pirq_entries[pin-16] != -1) { - if (!pirq_entries[pin-16]) { - apic_printk(APIC_VERBOSE, KERN_DEBUG - "disabling PIRQ%d\n", pin-16); - } else { - irq = pirq_entries[pin-16]; - apic_printk(APIC_VERBOSE, KERN_DEBUG - "using PIRQ%d -> IRQ %d\n", - pin-16, irq); - } - } - } -#endif - - return irq; -} - -void lock_vector_lock(void) -{ - /* Used to the online set of cpus does not change - * during assign_irq_vector. - */ - spin_lock(&vector_lock); -} - -void unlock_vector_lock(void) -{ - spin_unlock(&vector_lock); -} - -static int -__assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask) -{ - /* - * NOTE! The local APIC isn't very good at handling - * multiple interrupts at the same interrupt level. - * As the interrupt level is determined by taking the - * vector number and shifting that right by 4, we - * want to spread these out a bit so that they don't - * all fall in the same interrupt level. - * - * Also, we've got to be careful not to trash gate - * 0x80, because int 0x80 is hm, kind of importantish. ;) - */ - static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0; - unsigned int old_vector; - int cpu, err; - cpumask_var_t tmp_mask; - - if ((cfg->move_in_progress) || cfg->move_cleanup_count) - return -EBUSY; - - if (!alloc_cpumask_var(&tmp_mask, GFP_ATOMIC)) - return -ENOMEM; - - old_vector = cfg->vector; - if (old_vector) { - cpumask_and(tmp_mask, mask, cpu_online_mask); - cpumask_and(tmp_mask, cfg->domain, tmp_mask); - if (!cpumask_empty(tmp_mask)) { - free_cpumask_var(tmp_mask); - return 0; - } - } - - /* Only try and allocate irqs on cpus that are present */ - err = -ENOSPC; - for_each_cpu_and(cpu, mask, cpu_online_mask) { - int new_cpu; - int vector, offset; - - apic->vector_allocation_domain(cpu, tmp_mask); - - vector = current_vector; - offset = current_offset; -next: - vector += 8; - if (vector >= first_system_vector) { - /* If out of vectors on large boxen, must share them. */ - offset = (offset + 1) % 8; - vector = FIRST_DEVICE_VECTOR + offset; - } - if (unlikely(current_vector == vector)) - continue; - - if (test_bit(vector, used_vectors)) - goto next; - - for_each_cpu_and(new_cpu, tmp_mask, cpu_online_mask) - if (per_cpu(vector_irq, new_cpu)[vector] != -1) - goto next; - /* Found one! */ - current_vector = vector; - current_offset = offset; - if (old_vector) { - cfg->move_in_progress = 1; - cpumask_copy(cfg->old_domain, cfg->domain); - } - for_each_cpu_and(new_cpu, tmp_mask, cpu_online_mask) - per_cpu(vector_irq, new_cpu)[vector] = irq; - cfg->vector = vector; - cpumask_copy(cfg->domain, tmp_mask); - err = 0; - break; - } - free_cpumask_var(tmp_mask); - return err; -} - -static int -assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask) -{ - int err; - unsigned long flags; - - spin_lock_irqsave(&vector_lock, flags); - err = __assign_irq_vector(irq, cfg, mask); - spin_unlock_irqrestore(&vector_lock, flags); - return err; -} - -static void __clear_irq_vector(int irq, struct irq_cfg *cfg) -{ - int cpu, vector; - - BUG_ON(!cfg->vector); - - vector = cfg->vector; - for_each_cpu_and(cpu, cfg->domain, cpu_online_mask) - per_cpu(vector_irq, cpu)[vector] = -1; - - cfg->vector = 0; - cpumask_clear(cfg->domain); - - if (likely(!cfg->move_in_progress)) - return; - for_each_cpu_and(cpu, cfg->old_domain, cpu_online_mask) { - for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; - vector++) { - if (per_cpu(vector_irq, cpu)[vector] != irq) - continue; - per_cpu(vector_irq, cpu)[vector] = -1; - break; - } - } - cfg->move_in_progress = 0; -} - -void __setup_vector_irq(int cpu) -{ - /* Initialize vector_irq on a new cpu */ - /* This function must be called with vector_lock held */ - int irq, vector; - struct irq_cfg *cfg; - struct irq_desc *desc; - - /* Mark the inuse vectors */ - for_each_irq_desc(irq, desc) { - cfg = desc->chip_data; - if (!cpumask_test_cpu(cpu, cfg->domain)) - continue; - vector = cfg->vector; - per_cpu(vector_irq, cpu)[vector] = irq; - } - /* Mark the free vectors */ - for (vector = 0; vector < NR_VECTORS; ++vector) { - irq = per_cpu(vector_irq, cpu)[vector]; - if (irq < 0) - continue; - - cfg = irq_cfg(irq); - if (!cpumask_test_cpu(cpu, cfg->domain)) - per_cpu(vector_irq, cpu)[vector] = -1; - } -} - -static struct irq_chip ioapic_chip; -#ifdef CONFIG_INTR_REMAP -static struct irq_chip ir_ioapic_chip; -#endif - -#define IOAPIC_AUTO -1 -#define IOAPIC_EDGE 0 -#define IOAPIC_LEVEL 1 - -#ifdef CONFIG_X86_32 -static inline int IO_APIC_irq_trigger(int irq) -{ - int apic, idx, pin; - - for (apic = 0; apic < nr_ioapics; apic++) { - for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { - idx = find_irq_entry(apic, pin, mp_INT); - if ((idx != -1) && (irq == pin_2_irq(idx, apic, pin))) - return irq_trigger(idx); - } - } - /* - * nonexistent IRQs are edge default - */ - return 0; -} -#else -static inline int IO_APIC_irq_trigger(int irq) -{ - return 1; -} -#endif - -static void ioapic_register_intr(int irq, struct irq_desc *desc, unsigned long trigger) -{ - - if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || - trigger == IOAPIC_LEVEL) - desc->status |= IRQ_LEVEL; - else - desc->status &= ~IRQ_LEVEL; - -#ifdef CONFIG_INTR_REMAP - if (irq_remapped(irq)) { - desc->status |= IRQ_MOVE_PCNTXT; - if (trigger) - set_irq_chip_and_handler_name(irq, &ir_ioapic_chip, - handle_fasteoi_irq, - "fasteoi"); - else - set_irq_chip_and_handler_name(irq, &ir_ioapic_chip, - handle_edge_irq, "edge"); - return; - } -#endif - if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || - trigger == IOAPIC_LEVEL) - set_irq_chip_and_handler_name(irq, &ioapic_chip, - handle_fasteoi_irq, - "fasteoi"); - else - set_irq_chip_and_handler_name(irq, &ioapic_chip, - handle_edge_irq, "edge"); -} - -int setup_ioapic_entry(int apic_id, int irq, - struct IO_APIC_route_entry *entry, - unsigned int destination, int trigger, - int polarity, int vector) -{ - /* - * add it to the IO-APIC irq-routing table: - */ - memset(entry,0,sizeof(*entry)); - -#ifdef CONFIG_INTR_REMAP - if (intr_remapping_enabled) { - struct intel_iommu *iommu = map_ioapic_to_ir(apic_id); - struct irte irte; - struct IR_IO_APIC_route_entry *ir_entry = - (struct IR_IO_APIC_route_entry *) entry; - int index; - - if (!iommu) - panic("No mapping iommu for ioapic %d\n", apic_id); - - index = alloc_irte(iommu, irq, 1); - if (index < 0) - panic("Failed to allocate IRTE for ioapic %d\n", apic_id); - - memset(&irte, 0, sizeof(irte)); - - irte.present = 1; - irte.dst_mode = apic->irq_dest_mode; - irte.trigger_mode = trigger; - irte.dlvry_mode = apic->irq_delivery_mode; - irte.vector = vector; - irte.dest_id = IRTE_DEST(destination); - - modify_irte(irq, &irte); - - ir_entry->index2 = (index >> 15) & 0x1; - ir_entry->zero = 0; - ir_entry->format = 1; - ir_entry->index = (index & 0x7fff); - } else -#endif - { - entry->delivery_mode = apic->irq_delivery_mode; - entry->dest_mode = apic->irq_dest_mode; - entry->dest = destination; - } - - entry->mask = 0; /* enable IRQ */ - entry->trigger = trigger; - entry->polarity = polarity; - entry->vector = vector; - - /* Mask level triggered irqs. - * Use IRQ_DELAYED_DISABLE for edge triggered irqs. - */ - if (trigger) - entry->mask = 1; - return 0; -} - -static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq_desc *desc, - int trigger, int polarity) -{ - struct irq_cfg *cfg; - struct IO_APIC_route_entry entry; - unsigned int dest; - - if (!IO_APIC_IRQ(irq)) - return; - - cfg = desc->chip_data; - - if (assign_irq_vector(irq, cfg, apic->target_cpus())) - return; - - dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); - - apic_printk(APIC_VERBOSE,KERN_DEBUG - "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> " - "IRQ %d Mode:%i Active:%i)\n", - apic_id, mp_ioapics[apic_id].apicid, pin, cfg->vector, - irq, trigger, polarity); - - - if (setup_ioapic_entry(mp_ioapics[apic_id].apicid, irq, &entry, - dest, trigger, polarity, cfg->vector)) { - printk("Failed to setup ioapic entry for ioapic %d, pin %d\n", - mp_ioapics[apic_id].apicid, pin); - __clear_irq_vector(irq, cfg); - return; - } - - ioapic_register_intr(irq, desc, trigger); - if (irq < NR_IRQS_LEGACY) - disable_8259A_irq(irq); - - ioapic_write_entry(apic_id, pin, entry); -} - -static void __init setup_IO_APIC_irqs(void) -{ - int apic_id, pin, idx, irq; - int notcon = 0; - struct irq_desc *desc; - struct irq_cfg *cfg; - int cpu = boot_cpu_id; - - apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n"); - - for (apic_id = 0; apic_id < nr_ioapics; apic_id++) { - for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) { - - idx = find_irq_entry(apic_id, pin, mp_INT); - if (idx == -1) { - if (!notcon) { - notcon = 1; - apic_printk(APIC_VERBOSE, - KERN_DEBUG " %d-%d", - mp_ioapics[apic_id].apicid, pin); - } else - apic_printk(APIC_VERBOSE, " %d-%d", - mp_ioapics[apic_id].apicid, pin); - continue; - } - if (notcon) { - apic_printk(APIC_VERBOSE, - " (apicid-pin) not connected\n"); - notcon = 0; - } - - irq = pin_2_irq(idx, apic_id, pin); - - /* - * Skip the timer IRQ if there's a quirk handler - * installed and if it returns 1: - */ - if (apic->multi_timer_check && - apic->multi_timer_check(apic_id, irq)) - continue; - - desc = irq_to_desc_alloc_cpu(irq, cpu); - if (!desc) { - printk(KERN_INFO "can not get irq_desc for %d\n", irq); - continue; - } - cfg = desc->chip_data; - add_pin_to_irq_cpu(cfg, cpu, apic_id, pin); - - setup_IO_APIC_irq(apic_id, pin, irq, desc, - irq_trigger(idx), irq_polarity(idx)); - } - } - - if (notcon) - apic_printk(APIC_VERBOSE, - " (apicid-pin) not connected\n"); -} - -/* - * Set up the timer pin, possibly with the 8259A-master behind. - */ -static void __init setup_timer_IRQ0_pin(unsigned int apic_id, unsigned int pin, - int vector) -{ - struct IO_APIC_route_entry entry; - -#ifdef CONFIG_INTR_REMAP - if (intr_remapping_enabled) - return; -#endif - - memset(&entry, 0, sizeof(entry)); - - /* - * We use logical delivery to get the timer IRQ - * to the first CPU. - */ - entry.dest_mode = apic->irq_dest_mode; - entry.mask = 0; /* don't mask IRQ for edge */ - entry.dest = apic->cpu_mask_to_apicid(apic->target_cpus()); - entry.delivery_mode = apic->irq_delivery_mode; - entry.polarity = 0; - entry.trigger = 0; - entry.vector = vector; - - /* - * The timer IRQ doesn't have to know that behind the - * scene we may have a 8259A-master in AEOI mode ... - */ - set_irq_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, "edge"); - - /* - * Add it to the IO-APIC irq-routing table: - */ - ioapic_write_entry(apic_id, pin, entry); -} - - -__apicdebuginit(void) print_IO_APIC(void) -{ - int apic, i; - union IO_APIC_reg_00 reg_00; - union IO_APIC_reg_01 reg_01; - union IO_APIC_reg_02 reg_02; - union IO_APIC_reg_03 reg_03; - unsigned long flags; - struct irq_cfg *cfg; - struct irq_desc *desc; - unsigned int irq; - - if (apic_verbosity == APIC_QUIET) - return; - - printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries); - for (i = 0; i < nr_ioapics; i++) - printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n", - mp_ioapics[i].apicid, nr_ioapic_registers[i]); - - /* - * We are a bit conservative about what we expect. We have to - * know about every hardware change ASAP. - */ - printk(KERN_INFO "testing the IO APIC.......................\n"); - - for (apic = 0; apic < nr_ioapics; apic++) { - - spin_lock_irqsave(&ioapic_lock, flags); - reg_00.raw = io_apic_read(apic, 0); - reg_01.raw = io_apic_read(apic, 1); - if (reg_01.bits.version >= 0x10) - reg_02.raw = io_apic_read(apic, 2); - if (reg_01.bits.version >= 0x20) - reg_03.raw = io_apic_read(apic, 3); - spin_unlock_irqrestore(&ioapic_lock, flags); - - printk("\n"); - printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].apicid); - printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw); - printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID); - printk(KERN_DEBUG "....... : Delivery Type: %X\n", reg_00.bits.delivery_type); - printk(KERN_DEBUG "....... : LTS : %X\n", reg_00.bits.LTS); - - printk(KERN_DEBUG ".... register #01: %08X\n", *(int *)®_01); - printk(KERN_DEBUG "....... : max redirection entries: %04X\n", reg_01.bits.entries); - - printk(KERN_DEBUG "....... : PRQ implemented: %X\n", reg_01.bits.PRQ); - printk(KERN_DEBUG "....... : IO APIC version: %04X\n", reg_01.bits.version); - - /* - * Some Intel chipsets with IO APIC VERSION of 0x1? don't have reg_02, - * but the value of reg_02 is read as the previous read register - * value, so ignore it if reg_02 == reg_01. - */ - if (reg_01.bits.version >= 0x10 && reg_02.raw != reg_01.raw) { - printk(KERN_DEBUG ".... register #02: %08X\n", reg_02.raw); - printk(KERN_DEBUG "....... : arbitration: %02X\n", reg_02.bits.arbitration); - } - - /* - * Some Intel chipsets with IO APIC VERSION of 0x2? don't have reg_02 - * or reg_03, but the value of reg_0[23] is read as the previous read - * register value, so ignore it if reg_03 == reg_0[12]. - */ - if (reg_01.bits.version >= 0x20 && reg_03.raw != reg_02.raw && - reg_03.raw != reg_01.raw) { - printk(KERN_DEBUG ".... register #03: %08X\n", reg_03.raw); - printk(KERN_DEBUG "....... : Boot DT : %X\n", reg_03.bits.boot_DT); - } - - printk(KERN_DEBUG ".... IRQ redirection table:\n"); - - printk(KERN_DEBUG " NR Dst Mask Trig IRR Pol" - " Stat Dmod Deli Vect: \n"); - - for (i = 0; i <= reg_01.bits.entries; i++) { - struct IO_APIC_route_entry entry; - - entry = ioapic_read_entry(apic, i); - - printk(KERN_DEBUG " %02x %03X ", - i, - entry.dest - ); - - printk("%1d %1d %1d %1d %1d %1d %1d %02X\n", - entry.mask, - entry.trigger, - entry.irr, - entry.polarity, - entry.delivery_status, - entry.dest_mode, - entry.delivery_mode, - entry.vector - ); - } - } - printk(KERN_DEBUG "IRQ to pin mappings:\n"); - for_each_irq_desc(irq, desc) { - struct irq_pin_list *entry; - - cfg = desc->chip_data; - entry = cfg->irq_2_pin; - if (!entry) - continue; - printk(KERN_DEBUG "IRQ%d ", irq); - for (;;) { - printk("-> %d:%d", entry->apic, entry->pin); - if (!entry->next) - break; - entry = entry->next; - } - printk("\n"); - } - - printk(KERN_INFO ".................................... done.\n"); - - return; -} - -__apicdebuginit(void) print_APIC_bitfield(int base) -{ - unsigned int v; - int i, j; - - if (apic_verbosity == APIC_QUIET) - return; - - printk(KERN_DEBUG "0123456789abcdef0123456789abcdef\n" KERN_DEBUG); - for (i = 0; i < 8; i++) { - v = apic_read(base + i*0x10); - for (j = 0; j < 32; j++) { - if (v & (1< 3) /* Due to the Pentium erratum 3AP. */ - apic_write(APIC_ESR, 0); - - v = apic_read(APIC_ESR); - printk(KERN_DEBUG "... APIC ESR: %08x\n", v); - } - - icr = apic_icr_read(); - printk(KERN_DEBUG "... APIC ICR: %08x\n", (u32)icr); - printk(KERN_DEBUG "... APIC ICR2: %08x\n", (u32)(icr >> 32)); - - v = apic_read(APIC_LVTT); - printk(KERN_DEBUG "... APIC LVTT: %08x\n", v); - - if (maxlvt > 3) { /* PC is LVT#4. */ - v = apic_read(APIC_LVTPC); - printk(KERN_DEBUG "... APIC LVTPC: %08x\n", v); - } - v = apic_read(APIC_LVT0); - printk(KERN_DEBUG "... APIC LVT0: %08x\n", v); - v = apic_read(APIC_LVT1); - printk(KERN_DEBUG "... APIC LVT1: %08x\n", v); - - if (maxlvt > 2) { /* ERR is LVT#3. */ - v = apic_read(APIC_LVTERR); - printk(KERN_DEBUG "... APIC LVTERR: %08x\n", v); - } - - v = apic_read(APIC_TMICT); - printk(KERN_DEBUG "... APIC TMICT: %08x\n", v); - v = apic_read(APIC_TMCCT); - printk(KERN_DEBUG "... APIC TMCCT: %08x\n", v); - v = apic_read(APIC_TDCR); - printk(KERN_DEBUG "... APIC TDCR: %08x\n", v); - printk("\n"); -} - -__apicdebuginit(void) print_all_local_APICs(void) -{ - int cpu; - - preempt_disable(); - for_each_online_cpu(cpu) - smp_call_function_single(cpu, print_local_APIC, NULL, 1); - preempt_enable(); -} - -__apicdebuginit(void) print_PIC(void) -{ - unsigned int v; - unsigned long flags; - - if (apic_verbosity == APIC_QUIET) - return; - - printk(KERN_DEBUG "\nprinting PIC contents\n"); - - spin_lock_irqsave(&i8259A_lock, flags); - - v = inb(0xa1) << 8 | inb(0x21); - printk(KERN_DEBUG "... PIC IMR: %04x\n", v); - - v = inb(0xa0) << 8 | inb(0x20); - printk(KERN_DEBUG "... PIC IRR: %04x\n", v); - - outb(0x0b,0xa0); - outb(0x0b,0x20); - v = inb(0xa0) << 8 | inb(0x20); - outb(0x0a,0xa0); - outb(0x0a,0x20); - - spin_unlock_irqrestore(&i8259A_lock, flags); - - printk(KERN_DEBUG "... PIC ISR: %04x\n", v); - - v = inb(0x4d1) << 8 | inb(0x4d0); - printk(KERN_DEBUG "... PIC ELCR: %04x\n", v); -} - -__apicdebuginit(int) print_all_ICs(void) -{ - print_PIC(); - print_all_local_APICs(); - print_IO_APIC(); - - return 0; -} - -fs_initcall(print_all_ICs); - - -/* Where if anywhere is the i8259 connect in external int mode */ -static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; - -void __init enable_IO_APIC(void) -{ - union IO_APIC_reg_01 reg_01; - int i8259_apic, i8259_pin; - int apic; - unsigned long flags; - - /* - * The number of IO-APIC IRQ registers (== #pins): - */ - for (apic = 0; apic < nr_ioapics; apic++) { - spin_lock_irqsave(&ioapic_lock, flags); - reg_01.raw = io_apic_read(apic, 1); - spin_unlock_irqrestore(&ioapic_lock, flags); - nr_ioapic_registers[apic] = reg_01.bits.entries+1; - } - for(apic = 0; apic < nr_ioapics; apic++) { - int pin; - /* See if any of the pins is in ExtINT mode */ - for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { - struct IO_APIC_route_entry entry; - entry = ioapic_read_entry(apic, pin); - - /* If the interrupt line is enabled and in ExtInt mode - * I have found the pin where the i8259 is connected. - */ - if ((entry.mask == 0) && (entry.delivery_mode == dest_ExtINT)) { - ioapic_i8259.apic = apic; - ioapic_i8259.pin = pin; - goto found_i8259; - } - } - } - found_i8259: - /* Look to see what if the MP table has reported the ExtINT */ - /* If we could not find the appropriate pin by looking at the ioapic - * the i8259 probably is not connected the ioapic but give the - * mptable a chance anyway. - */ - i8259_pin = find_isa_irq_pin(0, mp_ExtINT); - i8259_apic = find_isa_irq_apic(0, mp_ExtINT); - /* Trust the MP table if nothing is setup in the hardware */ - if ((ioapic_i8259.pin == -1) && (i8259_pin >= 0)) { - printk(KERN_WARNING "ExtINT not setup in hardware but reported by MP table\n"); - ioapic_i8259.pin = i8259_pin; - ioapic_i8259.apic = i8259_apic; - } - /* Complain if the MP table and the hardware disagree */ - if (((ioapic_i8259.apic != i8259_apic) || (ioapic_i8259.pin != i8259_pin)) && - (i8259_pin >= 0) && (ioapic_i8259.pin >= 0)) - { - printk(KERN_WARNING "ExtINT in hardware and MP table differ\n"); - } - - /* - * Do not trust the IO-APIC being empty at bootup - */ - clear_IO_APIC(); -} - -/* - * Not an __init, needed by the reboot code - */ -void disable_IO_APIC(void) -{ - /* - * Clear the IO-APIC before rebooting: - */ - clear_IO_APIC(); - - /* - * If the i8259 is routed through an IOAPIC - * Put that IOAPIC in virtual wire mode - * so legacy interrupts can be delivered. - */ - if (ioapic_i8259.pin != -1) { - struct IO_APIC_route_entry entry; - - memset(&entry, 0, sizeof(entry)); - entry.mask = 0; /* Enabled */ - entry.trigger = 0; /* Edge */ - entry.irr = 0; - entry.polarity = 0; /* High */ - entry.delivery_status = 0; - entry.dest_mode = 0; /* Physical */ - entry.delivery_mode = dest_ExtINT; /* ExtInt */ - entry.vector = 0; - entry.dest = read_apic_id(); - - /* - * Add it to the IO-APIC irq-routing table: - */ - ioapic_write_entry(ioapic_i8259.apic, ioapic_i8259.pin, entry); - } - - disconnect_bsp_APIC(ioapic_i8259.pin != -1); -} - -#ifdef CONFIG_X86_32 -/* - * function to set the IO-APIC physical IDs based on the - * values stored in the MPC table. - * - * by Matt Domsch Tue Dec 21 12:25:05 CST 1999 - */ - -static void __init setup_ioapic_ids_from_mpc(void) -{ - union IO_APIC_reg_00 reg_00; - physid_mask_t phys_id_present_map; - int apic_id; - int i; - unsigned char old_id; - unsigned long flags; - - if (x86_quirks->setup_ioapic_ids && x86_quirks->setup_ioapic_ids()) - return; - - /* - * Don't check I/O APIC IDs for xAPIC systems. They have - * no meaning without the serial APIC bus. - */ - if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) - || APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) - return; - /* - * This is broken; anything with a real cpu count has to - * circumvent this idiocy regardless. - */ - phys_id_present_map = apic->ioapic_phys_id_map(phys_cpu_present_map); - - /* - * Set the IOAPIC ID to the value stored in the MPC table. - */ - for (apic_id = 0; apic_id < nr_ioapics; apic_id++) { - - /* Read the register 0 value */ - spin_lock_irqsave(&ioapic_lock, flags); - reg_00.raw = io_apic_read(apic_id, 0); - spin_unlock_irqrestore(&ioapic_lock, flags); - - old_id = mp_ioapics[apic_id].apicid; - - if (mp_ioapics[apic_id].apicid >= get_physical_broadcast()) { - printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n", - apic_id, mp_ioapics[apic_id].apicid); - printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", - reg_00.bits.ID); - mp_ioapics[apic_id].apicid = reg_00.bits.ID; - } - - /* - * Sanity check, is the ID really free? Every APIC in a - * system must have a unique ID or we get lots of nice - * 'stuck on smp_invalidate_needed IPI wait' messages. - */ - if (apic->check_apicid_used(phys_id_present_map, - mp_ioapics[apic_id].apicid)) { - printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n", - apic_id, mp_ioapics[apic_id].apicid); - for (i = 0; i < get_physical_broadcast(); i++) - if (!physid_isset(i, phys_id_present_map)) - break; - if (i >= get_physical_broadcast()) - panic("Max APIC ID exceeded!\n"); - printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", - i); - physid_set(i, phys_id_present_map); - mp_ioapics[apic_id].apicid = i; - } else { - physid_mask_t tmp; - tmp = apic->apicid_to_cpu_present(mp_ioapics[apic_id].apicid); - apic_printk(APIC_VERBOSE, "Setting %d in the " - "phys_id_present_map\n", - mp_ioapics[apic_id].apicid); - physids_or(phys_id_present_map, phys_id_present_map, tmp); - } - - - /* - * We need to adjust the IRQ routing table - * if the ID changed. - */ - if (old_id != mp_ioapics[apic_id].apicid) - for (i = 0; i < mp_irq_entries; i++) - if (mp_irqs[i].dstapic == old_id) - mp_irqs[i].dstapic - = mp_ioapics[apic_id].apicid; - - /* - * Read the right value from the MPC table and - * write it into the ID register. - */ - apic_printk(APIC_VERBOSE, KERN_INFO - "...changing IO-APIC physical APIC ID to %d ...", - mp_ioapics[apic_id].apicid); - - reg_00.bits.ID = mp_ioapics[apic_id].apicid; - spin_lock_irqsave(&ioapic_lock, flags); - io_apic_write(apic_id, 0, reg_00.raw); - spin_unlock_irqrestore(&ioapic_lock, flags); - - /* - * Sanity check - */ - spin_lock_irqsave(&ioapic_lock, flags); - reg_00.raw = io_apic_read(apic_id, 0); - spin_unlock_irqrestore(&ioapic_lock, flags); - if (reg_00.bits.ID != mp_ioapics[apic_id].apicid) - printk("could not set ID!\n"); - else - apic_printk(APIC_VERBOSE, " ok.\n"); - } -} -#endif - -int no_timer_check __initdata; - -static int __init notimercheck(char *s) -{ - no_timer_check = 1; - return 1; -} -__setup("no_timer_check", notimercheck); - -/* - * There is a nasty bug in some older SMP boards, their mptable lies - * about the timer IRQ. We do the following to work around the situation: - * - * - timer IRQ defaults to IO-APIC IRQ - * - if this function detects that timer IRQs are defunct, then we fall - * back to ISA timer IRQs - */ -static int __init timer_irq_works(void) -{ - unsigned long t1 = jiffies; - unsigned long flags; - - if (no_timer_check) - return 1; - - local_save_flags(flags); - local_irq_enable(); - /* Let ten ticks pass... */ - mdelay((10 * 1000) / HZ); - local_irq_restore(flags); - - /* - * Expect a few ticks at least, to be sure some possible - * glue logic does not lock up after one or two first - * ticks in a non-ExtINT mode. Also the local APIC - * might have cached one ExtINT interrupt. Finally, at - * least one tick may be lost due to delays. - */ - - /* jiffies wrap? */ - if (time_after(jiffies, t1 + 4)) - return 1; - return 0; -} - -/* - * In the SMP+IOAPIC case it might happen that there are an unspecified - * number of pending IRQ events unhandled. These cases are very rare, - * so we 'resend' these IRQs via IPIs, to the same CPU. It's much - * better to do it this way as thus we do not have to be aware of - * 'pending' interrupts in the IRQ path, except at this point. - */ -/* - * Edge triggered needs to resend any interrupt - * that was delayed but this is now handled in the device - * independent code. - */ - -/* - * Starting up a edge-triggered IO-APIC interrupt is - * nasty - we need to make sure that we get the edge. - * If it is already asserted for some reason, we need - * return 1 to indicate that is was pending. - * - * This is not complete - we should be able to fake - * an edge even if it isn't on the 8259A... - */ - -static unsigned int startup_ioapic_irq(unsigned int irq) -{ - int was_pending = 0; - unsigned long flags; - struct irq_cfg *cfg; - - spin_lock_irqsave(&ioapic_lock, flags); - if (irq < NR_IRQS_LEGACY) { - disable_8259A_irq(irq); - if (i8259A_irq_pending(irq)) - was_pending = 1; - } - cfg = irq_cfg(irq); - __unmask_IO_APIC_irq(cfg); - spin_unlock_irqrestore(&ioapic_lock, flags); - - return was_pending; -} - -#ifdef CONFIG_X86_64 -static int ioapic_retrigger_irq(unsigned int irq) -{ - - struct irq_cfg *cfg = irq_cfg(irq); - unsigned long flags; - - spin_lock_irqsave(&vector_lock, flags); - apic->send_IPI_mask(cpumask_of(cpumask_first(cfg->domain)), cfg->vector); - spin_unlock_irqrestore(&vector_lock, flags); - - return 1; -} -#else -static int ioapic_retrigger_irq(unsigned int irq) -{ - apic->send_IPI_self(irq_cfg(irq)->vector); - - return 1; -} -#endif - -/* - * Level and edge triggered IO-APIC interrupts need different handling, - * so we use two separate IRQ descriptors. Edge triggered IRQs can be - * handled with the level-triggered descriptor, but that one has slightly - * more overhead. Level-triggered interrupts cannot be handled with the - * edge-triggered handler, without risking IRQ storms and other ugly - * races. - */ - -#ifdef CONFIG_SMP - -#ifdef CONFIG_INTR_REMAP -static void ir_irq_migration(struct work_struct *work); - -static DECLARE_DELAYED_WORK(ir_migration_work, ir_irq_migration); - -/* - * Migrate the IO-APIC irq in the presence of intr-remapping. - * - * For edge triggered, irq migration is a simple atomic update(of vector - * and cpu destination) of IRTE and flush the hardware cache. - * - * For level triggered, we need to modify the io-apic RTE aswell with the update - * vector information, along with modifying IRTE with vector and destination. - * So irq migration for level triggered is little bit more complex compared to - * edge triggered migration. But the good news is, we use the same algorithm - * for level triggered migration as we have today, only difference being, - * we now initiate the irq migration from process context instead of the - * interrupt context. - * - * In future, when we do a directed EOI (combined with cpu EOI broadcast - * suppression) to the IO-APIC, level triggered irq migration will also be - * as simple as edge triggered migration and we can do the irq migration - * with a simple atomic update to IO-APIC RTE. - */ -static void -migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask) -{ - struct irq_cfg *cfg; - struct irte irte; - int modify_ioapic_rte; - unsigned int dest; - unsigned long flags; - unsigned int irq; - - if (!cpumask_intersects(mask, cpu_online_mask)) - return; - - irq = desc->irq; - if (get_irte(irq, &irte)) - return; - - cfg = desc->chip_data; - if (assign_irq_vector(irq, cfg, mask)) - return; - - set_extra_move_desc(desc, mask); - - dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask); - - modify_ioapic_rte = desc->status & IRQ_LEVEL; - if (modify_ioapic_rte) { - spin_lock_irqsave(&ioapic_lock, flags); - __target_IO_APIC_irq(irq, dest, cfg); - spin_unlock_irqrestore(&ioapic_lock, flags); - } - - irte.vector = cfg->vector; - irte.dest_id = IRTE_DEST(dest); - - /* - * Modified the IRTE and flushes the Interrupt entry cache. - */ - modify_irte(irq, &irte); - - if (cfg->move_in_progress) - send_cleanup_vector(cfg); - - cpumask_copy(desc->affinity, mask); -} - -static int migrate_irq_remapped_level_desc(struct irq_desc *desc) -{ - int ret = -1; - struct irq_cfg *cfg = desc->chip_data; - - mask_IO_APIC_irq_desc(desc); - - if (io_apic_level_ack_pending(cfg)) { - /* - * Interrupt in progress. Migrating irq now will change the - * vector information in the IO-APIC RTE and that will confuse - * the EOI broadcast performed by cpu. - * So, delay the irq migration to the next instance. - */ - schedule_delayed_work(&ir_migration_work, 1); - goto unmask; - } - - /* everthing is clear. we have right of way */ - migrate_ioapic_irq_desc(desc, desc->pending_mask); - - ret = 0; - desc->status &= ~IRQ_MOVE_PENDING; - cpumask_clear(desc->pending_mask); - -unmask: - unmask_IO_APIC_irq_desc(desc); - - return ret; -} - -static void ir_irq_migration(struct work_struct *work) -{ - unsigned int irq; - struct irq_desc *desc; - - for_each_irq_desc(irq, desc) { - if (desc->status & IRQ_MOVE_PENDING) { - unsigned long flags; - - spin_lock_irqsave(&desc->lock, flags); - if (!desc->chip->set_affinity || - !(desc->status & IRQ_MOVE_PENDING)) { - desc->status &= ~IRQ_MOVE_PENDING; - spin_unlock_irqrestore(&desc->lock, flags); - continue; - } - - desc->chip->set_affinity(irq, desc->pending_mask); - spin_unlock_irqrestore(&desc->lock, flags); - } - } -} - -/* - * Migrates the IRQ destination in the process context. - */ -static void set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc, - const struct cpumask *mask) -{ - if (desc->status & IRQ_LEVEL) { - desc->status |= IRQ_MOVE_PENDING; - cpumask_copy(desc->pending_mask, mask); - migrate_irq_remapped_level_desc(desc); - return; - } - - migrate_ioapic_irq_desc(desc, mask); -} -static void set_ir_ioapic_affinity_irq(unsigned int irq, - const struct cpumask *mask) -{ - struct irq_desc *desc = irq_to_desc(irq); - - set_ir_ioapic_affinity_irq_desc(desc, mask); -} -#endif - -asmlinkage void smp_irq_move_cleanup_interrupt(void) -{ - unsigned vector, me; - - ack_APIC_irq(); - exit_idle(); - irq_enter(); - - me = smp_processor_id(); - for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) { - unsigned int irq; - struct irq_desc *desc; - struct irq_cfg *cfg; - irq = __get_cpu_var(vector_irq)[vector]; - - if (irq == -1) - continue; - - desc = irq_to_desc(irq); - if (!desc) - continue; - - cfg = irq_cfg(irq); - spin_lock(&desc->lock); - if (!cfg->move_cleanup_count) - goto unlock; - - if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) - goto unlock; - - __get_cpu_var(vector_irq)[vector] = -1; - cfg->move_cleanup_count--; -unlock: - spin_unlock(&desc->lock); - } - - irq_exit(); -} - -static void irq_complete_move(struct irq_desc **descp) -{ - struct irq_desc *desc = *descp; - struct irq_cfg *cfg = desc->chip_data; - unsigned vector, me; - - if (likely(!cfg->move_in_progress)) { -#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC - if (likely(!cfg->move_desc_pending)) - return; - - /* domain has not changed, but affinity did */ - me = smp_processor_id(); - if (cpumask_test_cpu(me, desc->affinity)) { - *descp = desc = move_irq_desc(desc, me); - /* get the new one */ - cfg = desc->chip_data; - cfg->move_desc_pending = 0; - } -#endif - return; - } - - vector = ~get_irq_regs()->orig_ax; - me = smp_processor_id(); - - if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) { -#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC - *descp = desc = move_irq_desc(desc, me); - /* get the new one */ - cfg = desc->chip_data; -#endif - send_cleanup_vector(cfg); - } -} -#else -static inline void irq_complete_move(struct irq_desc **descp) {} -#endif - -#ifdef CONFIG_INTR_REMAP -static void ack_x2apic_level(unsigned int irq) -{ - ack_x2APIC_irq(); -} - -static void ack_x2apic_edge(unsigned int irq) -{ - ack_x2APIC_irq(); -} - -#endif - -static void ack_apic_edge(unsigned int irq) -{ - struct irq_desc *desc = irq_to_desc(irq); - - irq_complete_move(&desc); - move_native_irq(irq); - ack_APIC_irq(); -} - -atomic_t irq_mis_count; - -static void ack_apic_level(unsigned int irq) -{ - struct irq_desc *desc = irq_to_desc(irq); - -#ifdef CONFIG_X86_32 - unsigned long v; - int i; -#endif - struct irq_cfg *cfg; - int do_unmask_irq = 0; - - irq_complete_move(&desc); -#ifdef CONFIG_GENERIC_PENDING_IRQ - /* If we are moving the irq we need to mask it */ - if (unlikely(desc->status & IRQ_MOVE_PENDING)) { - do_unmask_irq = 1; - mask_IO_APIC_irq_desc(desc); - } -#endif - -#ifdef CONFIG_X86_32 - /* - * It appears there is an erratum which affects at least version 0x11 - * of I/O APIC (that's the 82093AA and cores integrated into various - * chipsets). Under certain conditions a level-triggered interrupt is - * erroneously delivered as edge-triggered one but the respective IRR - * bit gets set nevertheless. As a result the I/O unit expects an EOI - * message but it will never arrive and further interrupts are blocked - * from the source. The exact reason is so far unknown, but the - * phenomenon was observed when two consecutive interrupt requests - * from a given source get delivered to the same CPU and the source is - * temporarily disabled in between. - * - * A workaround is to simulate an EOI message manually. We achieve it - * by setting the trigger mode to edge and then to level when the edge - * trigger mode gets detected in the TMR of a local APIC for a - * level-triggered interrupt. We mask the source for the time of the - * operation to prevent an edge-triggered interrupt escaping meanwhile. - * The idea is from Manfred Spraul. --macro - */ - cfg = desc->chip_data; - i = cfg->vector; - - v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1)); -#endif - - /* - * We must acknowledge the irq before we move it or the acknowledge will - * not propagate properly. - */ - ack_APIC_irq(); - - /* Now we can move and renable the irq */ - if (unlikely(do_unmask_irq)) { - /* Only migrate the irq if the ack has been received. - * - * On rare occasions the broadcast level triggered ack gets - * delayed going to ioapics, and if we reprogram the - * vector while Remote IRR is still set the irq will never - * fire again. - * - * To prevent this scenario we read the Remote IRR bit - * of the ioapic. This has two effects. - * - On any sane system the read of the ioapic will - * flush writes (and acks) going to the ioapic from - * this cpu. - * - We get to see if the ACK has actually been delivered. - * - * Based on failed experiments of reprogramming the - * ioapic entry from outside of irq context starting - * with masking the ioapic entry and then polling until - * Remote IRR was clear before reprogramming the - * ioapic I don't trust the Remote IRR bit to be - * completey accurate. - * - * However there appears to be no other way to plug - * this race, so if the Remote IRR bit is not - * accurate and is causing problems then it is a hardware bug - * and you can go talk to the chipset vendor about it. - */ - cfg = desc->chip_data; - if (!io_apic_level_ack_pending(cfg)) - move_masked_irq(irq); - unmask_IO_APIC_irq_desc(desc); - } - -#ifdef CONFIG_X86_32 - if (!(v & (1 << (i & 0x1f)))) { - atomic_inc(&irq_mis_count); - spin_lock(&ioapic_lock); - __mask_and_edge_IO_APIC_irq(cfg); - __unmask_and_level_IO_APIC_irq(cfg); - spin_unlock(&ioapic_lock); - } -#endif -} - -static struct irq_chip ioapic_chip __read_mostly = { - .name = "IO-APIC", - .startup = startup_ioapic_irq, - .mask = mask_IO_APIC_irq, - .unmask = unmask_IO_APIC_irq, - .ack = ack_apic_edge, - .eoi = ack_apic_level, -#ifdef CONFIG_SMP - .set_affinity = set_ioapic_affinity_irq, -#endif - .retrigger = ioapic_retrigger_irq, -}; - -#ifdef CONFIG_INTR_REMAP -static struct irq_chip ir_ioapic_chip __read_mostly = { - .name = "IR-IO-APIC", - .startup = startup_ioapic_irq, - .mask = mask_IO_APIC_irq, - .unmask = unmask_IO_APIC_irq, - .ack = ack_x2apic_edge, - .eoi = ack_x2apic_level, -#ifdef CONFIG_SMP - .set_affinity = set_ir_ioapic_affinity_irq, -#endif - .retrigger = ioapic_retrigger_irq, -}; -#endif - -static inline void init_IO_APIC_traps(void) -{ - int irq; - struct irq_desc *desc; - struct irq_cfg *cfg; - - /* - * NOTE! The local APIC isn't very good at handling - * multiple interrupts at the same interrupt level. - * As the interrupt level is determined by taking the - * vector number and shifting that right by 4, we - * want to spread these out a bit so that they don't - * all fall in the same interrupt level. - * - * Also, we've got to be careful not to trash gate - * 0x80, because int 0x80 is hm, kind of importantish. ;) - */ - for_each_irq_desc(irq, desc) { - cfg = desc->chip_data; - if (IO_APIC_IRQ(irq) && cfg && !cfg->vector) { - /* - * Hmm.. We don't have an entry for this, - * so default to an old-fashioned 8259 - * interrupt if we can.. - */ - if (irq < NR_IRQS_LEGACY) - make_8259A_irq(irq); - else - /* Strange. Oh, well.. */ - desc->chip = &no_irq_chip; - } - } -} - -/* - * The local APIC irq-chip implementation: - */ - -static void mask_lapic_irq(unsigned int irq) -{ - unsigned long v; - - v = apic_read(APIC_LVT0); - apic_write(APIC_LVT0, v | APIC_LVT_MASKED); -} - -static void unmask_lapic_irq(unsigned int irq) -{ - unsigned long v; - - v = apic_read(APIC_LVT0); - apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED); -} - -static void ack_lapic_irq(unsigned int irq) -{ - ack_APIC_irq(); -} - -static struct irq_chip lapic_chip __read_mostly = { - .name = "local-APIC", - .mask = mask_lapic_irq, - .unmask = unmask_lapic_irq, - .ack = ack_lapic_irq, -}; - -static void lapic_register_intr(int irq, struct irq_desc *desc) -{ - desc->status &= ~IRQ_LEVEL; - set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq, - "edge"); -} - -static void __init setup_nmi(void) -{ - /* - * Dirty trick to enable the NMI watchdog ... - * We put the 8259A master into AEOI mode and - * unmask on all local APICs LVT0 as NMI. - * - * The idea to use the 8259A in AEOI mode ('8259A Virtual Wire') - * is from Maciej W. Rozycki - so we do not have to EOI from - * the NMI handler or the timer interrupt. - */ - apic_printk(APIC_VERBOSE, KERN_INFO "activating NMI Watchdog ..."); - - enable_NMI_through_LVT0(); - - apic_printk(APIC_VERBOSE, " done.\n"); -} - -/* - * This looks a bit hackish but it's about the only one way of sending - * a few INTA cycles to 8259As and any associated glue logic. ICR does - * not support the ExtINT mode, unfortunately. We need to send these - * cycles as some i82489DX-based boards have glue logic that keeps the - * 8259A interrupt line asserted until INTA. --macro - */ -static inline void __init unlock_ExtINT_logic(void) -{ - int apic, pin, i; - struct IO_APIC_route_entry entry0, entry1; - unsigned char save_control, save_freq_select; - - pin = find_isa_irq_pin(8, mp_INT); - if (pin == -1) { - WARN_ON_ONCE(1); - return; - } - apic = find_isa_irq_apic(8, mp_INT); - if (apic == -1) { - WARN_ON_ONCE(1); - return; - } - - entry0 = ioapic_read_entry(apic, pin); - clear_IO_APIC_pin(apic, pin); - - memset(&entry1, 0, sizeof(entry1)); - - entry1.dest_mode = 0; /* physical delivery */ - entry1.mask = 0; /* unmask IRQ now */ - entry1.dest = hard_smp_processor_id(); - entry1.delivery_mode = dest_ExtINT; - entry1.polarity = entry0.polarity; - entry1.trigger = 0; - entry1.vector = 0; - - ioapic_write_entry(apic, pin, entry1); - - save_control = CMOS_READ(RTC_CONTROL); - save_freq_select = CMOS_READ(RTC_FREQ_SELECT); - CMOS_WRITE((save_freq_select & ~RTC_RATE_SELECT) | 0x6, - RTC_FREQ_SELECT); - CMOS_WRITE(save_control | RTC_PIE, RTC_CONTROL); - - i = 100; - while (i-- > 0) { - mdelay(10); - if ((CMOS_READ(RTC_INTR_FLAGS) & RTC_PF) == RTC_PF) - i -= 10; - } - - CMOS_WRITE(save_control, RTC_CONTROL); - CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); - clear_IO_APIC_pin(apic, pin); - - ioapic_write_entry(apic, pin, entry0); -} - -static int disable_timer_pin_1 __initdata; -/* Actually the next is obsolete, but keep it for paranoid reasons -AK */ -static int __init disable_timer_pin_setup(char *arg) -{ - disable_timer_pin_1 = 1; - return 0; -} -early_param("disable_timer_pin_1", disable_timer_pin_setup); - -int timer_through_8259 __initdata; - -/* - * This code may look a bit paranoid, but it's supposed to cooperate with - * a wide range of boards and BIOS bugs. Fortunately only the timer IRQ - * is so screwy. Thanks to Brian Perkins for testing/hacking this beast - * fanatically on his truly buggy board. - * - * FIXME: really need to revamp this for all platforms. - */ -static inline void __init check_timer(void) -{ - struct irq_desc *desc = irq_to_desc(0); - struct irq_cfg *cfg = desc->chip_data; - int cpu = boot_cpu_id; - int apic1, pin1, apic2, pin2; - unsigned long flags; - int no_pin1 = 0; - - local_irq_save(flags); - - /* - * get/set the timer IRQ vector: - */ - disable_8259A_irq(0); - assign_irq_vector(0, cfg, apic->target_cpus()); - - /* - * As IRQ0 is to be enabled in the 8259A, the virtual - * wire has to be disabled in the local APIC. Also - * timer interrupts need to be acknowledged manually in - * the 8259A for the i82489DX when using the NMI - * watchdog as that APIC treats NMIs as level-triggered. - * The AEOI mode will finish them in the 8259A - * automatically. - */ - apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); - init_8259A(1); -#ifdef CONFIG_X86_32 - { - unsigned int ver; - - ver = apic_read(APIC_LVR); - ver = GET_APIC_VERSION(ver); - timer_ack = (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver)); - } -#endif - - pin1 = find_isa_irq_pin(0, mp_INT); - apic1 = find_isa_irq_apic(0, mp_INT); - pin2 = ioapic_i8259.pin; - apic2 = ioapic_i8259.apic; - - apic_printk(APIC_QUIET, KERN_INFO "..TIMER: vector=0x%02X " - "apic1=%d pin1=%d apic2=%d pin2=%d\n", - cfg->vector, apic1, pin1, apic2, pin2); - - /* - * Some BIOS writers are clueless and report the ExtINTA - * I/O APIC input from the cascaded 8259A as the timer - * interrupt input. So just in case, if only one pin - * was found above, try it both directly and through the - * 8259A. - */ - if (pin1 == -1) { -#ifdef CONFIG_INTR_REMAP - if (intr_remapping_enabled) - panic("BIOS bug: timer not connected to IO-APIC"); -#endif - pin1 = pin2; - apic1 = apic2; - no_pin1 = 1; - } else if (pin2 == -1) { - pin2 = pin1; - apic2 = apic1; - } - - if (pin1 != -1) { - /* - * Ok, does IRQ0 through the IOAPIC work? - */ - if (no_pin1) { - add_pin_to_irq_cpu(cfg, cpu, apic1, pin1); - setup_timer_IRQ0_pin(apic1, pin1, cfg->vector); - } else { - /* for edge trigger, setup_IO_APIC_irq already - * leave it unmasked. - * so only need to unmask if it is level-trigger - * do we really have level trigger timer? - */ - int idx; - idx = find_irq_entry(apic1, pin1, mp_INT); - if (idx != -1 && irq_trigger(idx)) - unmask_IO_APIC_irq_desc(desc); - } - if (timer_irq_works()) { - if (nmi_watchdog == NMI_IO_APIC) { - setup_nmi(); - enable_8259A_irq(0); - } - if (disable_timer_pin_1 > 0) - clear_IO_APIC_pin(0, pin1); - goto out; - } -#ifdef CONFIG_INTR_REMAP - if (intr_remapping_enabled) - panic("timer doesn't work through Interrupt-remapped IO-APIC"); -#endif - local_irq_disable(); - clear_IO_APIC_pin(apic1, pin1); - if (!no_pin1) - apic_printk(APIC_QUIET, KERN_ERR "..MP-BIOS bug: " - "8254 timer not connected to IO-APIC\n"); - - apic_printk(APIC_QUIET, KERN_INFO "...trying to set up timer " - "(IRQ0) through the 8259A ...\n"); - apic_printk(APIC_QUIET, KERN_INFO - "..... (found apic %d pin %d) ...\n", apic2, pin2); - /* - * legacy devices should be connected to IO APIC #0 - */ - replace_pin_at_irq_cpu(cfg, cpu, apic1, pin1, apic2, pin2); - setup_timer_IRQ0_pin(apic2, pin2, cfg->vector); - enable_8259A_irq(0); - if (timer_irq_works()) { - apic_printk(APIC_QUIET, KERN_INFO "....... works.\n"); - timer_through_8259 = 1; - if (nmi_watchdog == NMI_IO_APIC) { - disable_8259A_irq(0); - setup_nmi(); - enable_8259A_irq(0); - } - goto out; - } - /* - * Cleanup, just in case ... - */ - local_irq_disable(); - disable_8259A_irq(0); - clear_IO_APIC_pin(apic2, pin2); - apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n"); - } - - if (nmi_watchdog == NMI_IO_APIC) { - apic_printk(APIC_QUIET, KERN_WARNING "timer doesn't work " - "through the IO-APIC - disabling NMI Watchdog!\n"); - nmi_watchdog = NMI_NONE; - } -#ifdef CONFIG_X86_32 - timer_ack = 0; -#endif - - apic_printk(APIC_QUIET, KERN_INFO - "...trying to set up timer as Virtual Wire IRQ...\n"); - - lapic_register_intr(0, desc); - apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector); /* Fixed mode */ - enable_8259A_irq(0); - - if (timer_irq_works()) { - apic_printk(APIC_QUIET, KERN_INFO "..... works.\n"); - goto out; - } - local_irq_disable(); - disable_8259A_irq(0); - apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector); - apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n"); - - apic_printk(APIC_QUIET, KERN_INFO - "...trying to set up timer as ExtINT IRQ...\n"); - - init_8259A(0); - make_8259A_irq(0); - apic_write(APIC_LVT0, APIC_DM_EXTINT); - - unlock_ExtINT_logic(); - - if (timer_irq_works()) { - apic_printk(APIC_QUIET, KERN_INFO "..... works.\n"); - goto out; - } - local_irq_disable(); - apic_printk(APIC_QUIET, KERN_INFO "..... failed :(.\n"); - panic("IO-APIC + timer doesn't work! Boot with apic=debug and send a " - "report. Then try booting with the 'noapic' option.\n"); -out: - local_irq_restore(flags); -} - -/* - * Traditionally ISA IRQ2 is the cascade IRQ, and is not available - * to devices. However there may be an I/O APIC pin available for - * this interrupt regardless. The pin may be left unconnected, but - * typically it will be reused as an ExtINT cascade interrupt for - * the master 8259A. In the MPS case such a pin will normally be - * reported as an ExtINT interrupt in the MP table. With ACPI - * there is no provision for ExtINT interrupts, and in the absence - * of an override it would be treated as an ordinary ISA I/O APIC - * interrupt, that is edge-triggered and unmasked by default. We - * used to do this, but it caused problems on some systems because - * of the NMI watchdog and sometimes IRQ0 of the 8254 timer using - * the same ExtINT cascade interrupt to drive the local APIC of the - * bootstrap processor. Therefore we refrain from routing IRQ2 to - * the I/O APIC in all cases now. No actual device should request - * it anyway. --macro - */ -#define PIC_IRQS (1 << PIC_CASCADE_IR) - -void __init setup_IO_APIC(void) -{ - - /* - * calling enable_IO_APIC() is moved to setup_local_APIC for BP - */ - - io_apic_irqs = ~PIC_IRQS; - - apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n"); - /* - * Set up IO-APIC IRQ routing. - */ -#ifdef CONFIG_X86_32 - if (!acpi_ioapic) - setup_ioapic_ids_from_mpc(); -#endif - sync_Arb_IDs(); - setup_IO_APIC_irqs(); - init_IO_APIC_traps(); - check_timer(); -} - -/* - * Called after all the initialization is done. If we didnt find any - * APIC bugs then we can allow the modify fast path - */ - -static int __init io_apic_bug_finalize(void) -{ - if (sis_apic_bug == -1) - sis_apic_bug = 0; - return 0; -} - -late_initcall(io_apic_bug_finalize); - -struct sysfs_ioapic_data { - struct sys_device dev; - struct IO_APIC_route_entry entry[0]; -}; -static struct sysfs_ioapic_data * mp_ioapic_data[MAX_IO_APICS]; - -static int ioapic_suspend(struct sys_device *dev, pm_message_t state) -{ - struct IO_APIC_route_entry *entry; - struct sysfs_ioapic_data *data; - int i; - - data = container_of(dev, struct sysfs_ioapic_data, dev); - entry = data->entry; - for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) - *entry = ioapic_read_entry(dev->id, i); - - return 0; -} - -static int ioapic_resume(struct sys_device *dev) -{ - struct IO_APIC_route_entry *entry; - struct sysfs_ioapic_data *data; - unsigned long flags; - union IO_APIC_reg_00 reg_00; - int i; - - data = container_of(dev, struct sysfs_ioapic_data, dev); - entry = data->entry; - - spin_lock_irqsave(&ioapic_lock, flags); - reg_00.raw = io_apic_read(dev->id, 0); - if (reg_00.bits.ID != mp_ioapics[dev->id].apicid) { - reg_00.bits.ID = mp_ioapics[dev->id].apicid; - io_apic_write(dev->id, 0, reg_00.raw); - } - spin_unlock_irqrestore(&ioapic_lock, flags); - for (i = 0; i < nr_ioapic_registers[dev->id]; i++) - ioapic_write_entry(dev->id, i, entry[i]); - - return 0; -} - -static struct sysdev_class ioapic_sysdev_class = { - .name = "ioapic", - .suspend = ioapic_suspend, - .resume = ioapic_resume, -}; - -static int __init ioapic_init_sysfs(void) -{ - struct sys_device * dev; - int i, size, error; - - error = sysdev_class_register(&ioapic_sysdev_class); - if (error) - return error; - - for (i = 0; i < nr_ioapics; i++ ) { - size = sizeof(struct sys_device) + nr_ioapic_registers[i] - * sizeof(struct IO_APIC_route_entry); - mp_ioapic_data[i] = kzalloc(size, GFP_KERNEL); - if (!mp_ioapic_data[i]) { - printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i); - continue; - } - dev = &mp_ioapic_data[i]->dev; - dev->id = i; - dev->cls = &ioapic_sysdev_class; - error = sysdev_register(dev); - if (error) { - kfree(mp_ioapic_data[i]); - mp_ioapic_data[i] = NULL; - printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i); - continue; - } - } - - return 0; -} - -device_initcall(ioapic_init_sysfs); - -static int nr_irqs_gsi = NR_IRQS_LEGACY; -/* - * Dynamic irq allocate and deallocation - */ -unsigned int create_irq_nr(unsigned int irq_want) -{ - /* Allocate an unused irq */ - unsigned int irq; - unsigned int new; - unsigned long flags; - struct irq_cfg *cfg_new = NULL; - int cpu = boot_cpu_id; - struct irq_desc *desc_new = NULL; - - irq = 0; - if (irq_want < nr_irqs_gsi) - irq_want = nr_irqs_gsi; - - spin_lock_irqsave(&vector_lock, flags); - for (new = irq_want; new < nr_irqs; new++) { - desc_new = irq_to_desc_alloc_cpu(new, cpu); - if (!desc_new) { - printk(KERN_INFO "can not get irq_desc for %d\n", new); - continue; - } - cfg_new = desc_new->chip_data; - - if (cfg_new->vector != 0) - continue; - if (__assign_irq_vector(new, cfg_new, apic->target_cpus()) == 0) - irq = new; - break; - } - spin_unlock_irqrestore(&vector_lock, flags); - - if (irq > 0) { - dynamic_irq_init(irq); - /* restore it, in case dynamic_irq_init clear it */ - if (desc_new) - desc_new->chip_data = cfg_new; - } - return irq; -} - -int create_irq(void) -{ - unsigned int irq_want; - int irq; - - irq_want = nr_irqs_gsi; - irq = create_irq_nr(irq_want); - - if (irq == 0) - irq = -1; - - return irq; -} - -void destroy_irq(unsigned int irq) -{ - unsigned long flags; - struct irq_cfg *cfg; - struct irq_desc *desc; - - /* store it, in case dynamic_irq_cleanup clear it */ - desc = irq_to_desc(irq); - cfg = desc->chip_data; - dynamic_irq_cleanup(irq); - /* connect back irq_cfg */ - if (desc) - desc->chip_data = cfg; - -#ifdef CONFIG_INTR_REMAP - free_irte(irq); -#endif - spin_lock_irqsave(&vector_lock, flags); - __clear_irq_vector(irq, cfg); - spin_unlock_irqrestore(&vector_lock, flags); -} - -/* - * MSI message composition - */ -#ifdef CONFIG_PCI_MSI -static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg) -{ - struct irq_cfg *cfg; - int err; - unsigned dest; - - if (disable_apic) - return -ENXIO; - - cfg = irq_cfg(irq); - err = assign_irq_vector(irq, cfg, apic->target_cpus()); - if (err) - return err; - - dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); - -#ifdef CONFIG_INTR_REMAP - if (irq_remapped(irq)) { - struct irte irte; - int ir_index; - u16 sub_handle; - - ir_index = map_irq_to_irte_handle(irq, &sub_handle); - BUG_ON(ir_index == -1); - - memset (&irte, 0, sizeof(irte)); - - irte.present = 1; - irte.dst_mode = apic->irq_dest_mode; - irte.trigger_mode = 0; /* edge */ - irte.dlvry_mode = apic->irq_delivery_mode; - irte.vector = cfg->vector; - irte.dest_id = IRTE_DEST(dest); - - modify_irte(irq, &irte); - - msg->address_hi = MSI_ADDR_BASE_HI; - msg->data = sub_handle; - msg->address_lo = MSI_ADDR_BASE_LO | MSI_ADDR_IR_EXT_INT | - MSI_ADDR_IR_SHV | - MSI_ADDR_IR_INDEX1(ir_index) | - MSI_ADDR_IR_INDEX2(ir_index); - } else -#endif - { - msg->address_hi = MSI_ADDR_BASE_HI; - msg->address_lo = - MSI_ADDR_BASE_LO | - ((apic->irq_dest_mode == 0) ? - MSI_ADDR_DEST_MODE_PHYSICAL: - MSI_ADDR_DEST_MODE_LOGICAL) | - ((apic->irq_delivery_mode != dest_LowestPrio) ? - MSI_ADDR_REDIRECTION_CPU: - MSI_ADDR_REDIRECTION_LOWPRI) | - MSI_ADDR_DEST_ID(dest); - - msg->data = - MSI_DATA_TRIGGER_EDGE | - MSI_DATA_LEVEL_ASSERT | - ((apic->irq_delivery_mode != dest_LowestPrio) ? - MSI_DATA_DELIVERY_FIXED: - MSI_DATA_DELIVERY_LOWPRI) | - MSI_DATA_VECTOR(cfg->vector); - } - return err; -} - -#ifdef CONFIG_SMP -static void set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask) -{ - struct irq_desc *desc = irq_to_desc(irq); - struct irq_cfg *cfg; - struct msi_msg msg; - unsigned int dest; - - dest = set_desc_affinity(desc, mask); - if (dest == BAD_APICID) - return; - - cfg = desc->chip_data; - - read_msi_msg_desc(desc, &msg); - - msg.data &= ~MSI_DATA_VECTOR_MASK; - msg.data |= MSI_DATA_VECTOR(cfg->vector); - msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK; - msg.address_lo |= MSI_ADDR_DEST_ID(dest); - - write_msi_msg_desc(desc, &msg); -} -#ifdef CONFIG_INTR_REMAP -/* - * Migrate the MSI irq to another cpumask. This migration is - * done in the process context using interrupt-remapping hardware. - */ -static void -ir_set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask) -{ - struct irq_desc *desc = irq_to_desc(irq); - struct irq_cfg *cfg = desc->chip_data; - unsigned int dest; - struct irte irte; - - if (get_irte(irq, &irte)) - return; - - dest = set_desc_affinity(desc, mask); - if (dest == BAD_APICID) - return; - - irte.vector = cfg->vector; - irte.dest_id = IRTE_DEST(dest); - - /* - * atomically update the IRTE with the new destination and vector. - */ - modify_irte(irq, &irte); - - /* - * After this point, all the interrupts will start arriving - * at the new destination. So, time to cleanup the previous - * vector allocation. - */ - if (cfg->move_in_progress) - send_cleanup_vector(cfg); -} - -#endif -#endif /* CONFIG_SMP */ - -/* - * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices, - * which implement the MSI or MSI-X Capability Structure. - */ -static struct irq_chip msi_chip = { - .name = "PCI-MSI", - .unmask = unmask_msi_irq, - .mask = mask_msi_irq, - .ack = ack_apic_edge, -#ifdef CONFIG_SMP - .set_affinity = set_msi_irq_affinity, -#endif - .retrigger = ioapic_retrigger_irq, -}; - -#ifdef CONFIG_INTR_REMAP -static struct irq_chip msi_ir_chip = { - .name = "IR-PCI-MSI", - .unmask = unmask_msi_irq, - .mask = mask_msi_irq, - .ack = ack_x2apic_edge, -#ifdef CONFIG_SMP - .set_affinity = ir_set_msi_irq_affinity, -#endif - .retrigger = ioapic_retrigger_irq, -}; - -/* - * Map the PCI dev to the corresponding remapping hardware unit - * and allocate 'nvec' consecutive interrupt-remapping table entries - * in it. - */ -static int msi_alloc_irte(struct pci_dev *dev, int irq, int nvec) -{ - struct intel_iommu *iommu; - int index; - - iommu = map_dev_to_ir(dev); - if (!iommu) { - printk(KERN_ERR - "Unable to map PCI %s to iommu\n", pci_name(dev)); - return -ENOENT; - } - - index = alloc_irte(iommu, irq, nvec); - if (index < 0) { - printk(KERN_ERR - "Unable to allocate %d IRTE for PCI %s\n", nvec, - pci_name(dev)); - return -ENOSPC; - } - return index; -} -#endif - -static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq) -{ - int ret; - struct msi_msg msg; - - ret = msi_compose_msg(dev, irq, &msg); - if (ret < 0) - return ret; - - set_irq_msi(irq, msidesc); - write_msi_msg(irq, &msg); - -#ifdef CONFIG_INTR_REMAP - if (irq_remapped(irq)) { - struct irq_desc *desc = irq_to_desc(irq); - /* - * irq migration in process context - */ - desc->status |= IRQ_MOVE_PCNTXT; - set_irq_chip_and_handler_name(irq, &msi_ir_chip, handle_edge_irq, "edge"); - } else -#endif - set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge"); - - dev_printk(KERN_DEBUG, &dev->dev, "irq %d for MSI/MSI-X\n", irq); - - return 0; -} - -int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) -{ - unsigned int irq; - int ret, sub_handle; - struct msi_desc *msidesc; - unsigned int irq_want; - -#ifdef CONFIG_INTR_REMAP - struct intel_iommu *iommu = 0; - int index = 0; -#endif - - irq_want = nr_irqs_gsi; - sub_handle = 0; - list_for_each_entry(msidesc, &dev->msi_list, list) { - irq = create_irq_nr(irq_want); - if (irq == 0) - return -1; - irq_want = irq + 1; -#ifdef CONFIG_INTR_REMAP - if (!intr_remapping_enabled) - goto no_ir; - - if (!sub_handle) { - /* - * allocate the consecutive block of IRTE's - * for 'nvec' - */ - index = msi_alloc_irte(dev, irq, nvec); - if (index < 0) { - ret = index; - goto error; - } - } else { - iommu = map_dev_to_ir(dev); - if (!iommu) { - ret = -ENOENT; - goto error; - } - /* - * setup the mapping between the irq and the IRTE - * base index, the sub_handle pointing to the - * appropriate interrupt remap table entry. - */ - set_irte_irq(irq, iommu, index, sub_handle); - } -no_ir: -#endif - ret = setup_msi_irq(dev, msidesc, irq); - if (ret < 0) - goto error; - sub_handle++; - } - return 0; - -error: - destroy_irq(irq); - return ret; -} - -void arch_teardown_msi_irq(unsigned int irq) -{ - destroy_irq(irq); -} - -#ifdef CONFIG_DMAR -#ifdef CONFIG_SMP -static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask) -{ - struct irq_desc *desc = irq_to_desc(irq); - struct irq_cfg *cfg; - struct msi_msg msg; - unsigned int dest; - - dest = set_desc_affinity(desc, mask); - if (dest == BAD_APICID) - return; - - cfg = desc->chip_data; - - dmar_msi_read(irq, &msg); - - msg.data &= ~MSI_DATA_VECTOR_MASK; - msg.data |= MSI_DATA_VECTOR(cfg->vector); - msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK; - msg.address_lo |= MSI_ADDR_DEST_ID(dest); - - dmar_msi_write(irq, &msg); -} - -#endif /* CONFIG_SMP */ - -struct irq_chip dmar_msi_type = { - .name = "DMAR_MSI", - .unmask = dmar_msi_unmask, - .mask = dmar_msi_mask, - .ack = ack_apic_edge, -#ifdef CONFIG_SMP - .set_affinity = dmar_msi_set_affinity, -#endif - .retrigger = ioapic_retrigger_irq, -}; - -int arch_setup_dmar_msi(unsigned int irq) -{ - int ret; - struct msi_msg msg; - - ret = msi_compose_msg(NULL, irq, &msg); - if (ret < 0) - return ret; - dmar_msi_write(irq, &msg); - set_irq_chip_and_handler_name(irq, &dmar_msi_type, handle_edge_irq, - "edge"); - return 0; -} -#endif - -#ifdef CONFIG_HPET_TIMER - -#ifdef CONFIG_SMP -static void hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask) -{ - struct irq_desc *desc = irq_to_desc(irq); - struct irq_cfg *cfg; - struct msi_msg msg; - unsigned int dest; - - dest = set_desc_affinity(desc, mask); - if (dest == BAD_APICID) - return; - - cfg = desc->chip_data; - - hpet_msi_read(irq, &msg); - - msg.data &= ~MSI_DATA_VECTOR_MASK; - msg.data |= MSI_DATA_VECTOR(cfg->vector); - msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK; - msg.address_lo |= MSI_ADDR_DEST_ID(dest); - - hpet_msi_write(irq, &msg); -} - -#endif /* CONFIG_SMP */ - -struct irq_chip hpet_msi_type = { - .name = "HPET_MSI", - .unmask = hpet_msi_unmask, - .mask = hpet_msi_mask, - .ack = ack_apic_edge, -#ifdef CONFIG_SMP - .set_affinity = hpet_msi_set_affinity, -#endif - .retrigger = ioapic_retrigger_irq, -}; - -int arch_setup_hpet_msi(unsigned int irq) -{ - int ret; - struct msi_msg msg; - - ret = msi_compose_msg(NULL, irq, &msg); - if (ret < 0) - return ret; - - hpet_msi_write(irq, &msg); - set_irq_chip_and_handler_name(irq, &hpet_msi_type, handle_edge_irq, - "edge"); - - return 0; -} -#endif - -#endif /* CONFIG_PCI_MSI */ -/* - * Hypertransport interrupt support - */ -#ifdef CONFIG_HT_IRQ - -#ifdef CONFIG_SMP - -static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector) -{ - struct ht_irq_msg msg; - fetch_ht_irq_msg(irq, &msg); - - msg.address_lo &= ~(HT_IRQ_LOW_VECTOR_MASK | HT_IRQ_LOW_DEST_ID_MASK); - msg.address_hi &= ~(HT_IRQ_HIGH_DEST_ID_MASK); - - msg.address_lo |= HT_IRQ_LOW_VECTOR(vector) | HT_IRQ_LOW_DEST_ID(dest); - msg.address_hi |= HT_IRQ_HIGH_DEST_ID(dest); - - write_ht_irq_msg(irq, &msg); -} - -static void set_ht_irq_affinity(unsigned int irq, const struct cpumask *mask) -{ - struct irq_desc *desc = irq_to_desc(irq); - struct irq_cfg *cfg; - unsigned int dest; - - dest = set_desc_affinity(desc, mask); - if (dest == BAD_APICID) - return; - - cfg = desc->chip_data; - - target_ht_irq(irq, dest, cfg->vector); -} - -#endif - -static struct irq_chip ht_irq_chip = { - .name = "PCI-HT", - .mask = mask_ht_irq, - .unmask = unmask_ht_irq, - .ack = ack_apic_edge, -#ifdef CONFIG_SMP - .set_affinity = set_ht_irq_affinity, -#endif - .retrigger = ioapic_retrigger_irq, -}; - -int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) -{ - struct irq_cfg *cfg; - int err; - - if (disable_apic) - return -ENXIO; - - cfg = irq_cfg(irq); - err = assign_irq_vector(irq, cfg, apic->target_cpus()); - if (!err) { - struct ht_irq_msg msg; - unsigned dest; - - dest = apic->cpu_mask_to_apicid_and(cfg->domain, - apic->target_cpus()); - - msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest); - - msg.address_lo = - HT_IRQ_LOW_BASE | - HT_IRQ_LOW_DEST_ID(dest) | - HT_IRQ_LOW_VECTOR(cfg->vector) | - ((apic->irq_dest_mode == 0) ? - HT_IRQ_LOW_DM_PHYSICAL : - HT_IRQ_LOW_DM_LOGICAL) | - HT_IRQ_LOW_RQEOI_EDGE | - ((apic->irq_delivery_mode != dest_LowestPrio) ? - HT_IRQ_LOW_MT_FIXED : - HT_IRQ_LOW_MT_ARBITRATED) | - HT_IRQ_LOW_IRQ_MASKED; - - write_ht_irq_msg(irq, &msg); - - set_irq_chip_and_handler_name(irq, &ht_irq_chip, - handle_edge_irq, "edge"); - - dev_printk(KERN_DEBUG, &dev->dev, "irq %d for HT\n", irq); - } - return err; -} -#endif /* CONFIG_HT_IRQ */ - -#ifdef CONFIG_X86_UV -/* - * Re-target the irq to the specified CPU and enable the specified MMR located - * on the specified blade to allow the sending of MSIs to the specified CPU. - */ -int arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, - unsigned long mmr_offset) -{ - const struct cpumask *eligible_cpu = cpumask_of(cpu); - struct irq_cfg *cfg; - int mmr_pnode; - unsigned long mmr_value; - struct uv_IO_APIC_route_entry *entry; - unsigned long flags; - int err; - - cfg = irq_cfg(irq); - - err = assign_irq_vector(irq, cfg, eligible_cpu); - if (err != 0) - return err; - - spin_lock_irqsave(&vector_lock, flags); - set_irq_chip_and_handler_name(irq, &uv_irq_chip, handle_percpu_irq, - irq_name); - spin_unlock_irqrestore(&vector_lock, flags); - - mmr_value = 0; - entry = (struct uv_IO_APIC_route_entry *)&mmr_value; - BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long)); - - entry->vector = cfg->vector; - entry->delivery_mode = apic->irq_delivery_mode; - entry->dest_mode = apic->irq_dest_mode; - entry->polarity = 0; - entry->trigger = 0; - entry->mask = 0; - entry->dest = apic->cpu_mask_to_apicid(eligible_cpu); - - mmr_pnode = uv_blade_to_pnode(mmr_blade); - uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value); - - return irq; -} - -/* - * Disable the specified MMR located on the specified blade so that MSIs are - * longer allowed to be sent. - */ -void arch_disable_uv_irq(int mmr_blade, unsigned long mmr_offset) -{ - unsigned long mmr_value; - struct uv_IO_APIC_route_entry *entry; - int mmr_pnode; - - mmr_value = 0; - entry = (struct uv_IO_APIC_route_entry *)&mmr_value; - BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long)); - - entry->mask = 1; - - mmr_pnode = uv_blade_to_pnode(mmr_blade); - uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value); -} -#endif /* CONFIG_X86_64 */ - -int __init io_apic_get_redir_entries (int ioapic) -{ - union IO_APIC_reg_01 reg_01; - unsigned long flags; - - spin_lock_irqsave(&ioapic_lock, flags); - reg_01.raw = io_apic_read(ioapic, 1); - spin_unlock_irqrestore(&ioapic_lock, flags); - - return reg_01.bits.entries; -} - -void __init probe_nr_irqs_gsi(void) -{ - int nr = 0; - - nr = acpi_probe_gsi(); - if (nr > nr_irqs_gsi) { - nr_irqs_gsi = nr; - } else { - /* for acpi=off or acpi is not compiled in */ - int idx; - - nr = 0; - for (idx = 0; idx < nr_ioapics; idx++) - nr += io_apic_get_redir_entries(idx) + 1; - - if (nr > nr_irqs_gsi) - nr_irqs_gsi = nr; - } - - printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi); -} - -#ifdef CONFIG_SPARSE_IRQ -int __init arch_probe_nr_irqs(void) -{ - int nr; - - if (nr_irqs > (NR_VECTORS * nr_cpu_ids)) - nr_irqs = NR_VECTORS * nr_cpu_ids; - - nr = nr_irqs_gsi + 8 * nr_cpu_ids; -#if defined(CONFIG_PCI_MSI) || defined(CONFIG_HT_IRQ) - /* - * for MSI and HT dyn irq - */ - nr += nr_irqs_gsi * 16; -#endif - if (nr < nr_irqs) - nr_irqs = nr; - - return 0; -} -#endif - -/* -------------------------------------------------------------------------- - ACPI-based IOAPIC Configuration - -------------------------------------------------------------------------- */ - -#ifdef CONFIG_ACPI - -#ifdef CONFIG_X86_32 -int __init io_apic_get_unique_id(int ioapic, int apic_id) -{ - union IO_APIC_reg_00 reg_00; - static physid_mask_t apic_id_map = PHYSID_MASK_NONE; - physid_mask_t tmp; - unsigned long flags; - int i = 0; - - /* - * The P4 platform supports up to 256 APIC IDs on two separate APIC - * buses (one for LAPICs, one for IOAPICs), where predecessors only - * supports up to 16 on one shared APIC bus. - * - * TBD: Expand LAPIC/IOAPIC support on P4-class systems to take full - * advantage of new APIC bus architecture. - */ - - if (physids_empty(apic_id_map)) - apic_id_map = apic->ioapic_phys_id_map(phys_cpu_present_map); - - spin_lock_irqsave(&ioapic_lock, flags); - reg_00.raw = io_apic_read(ioapic, 0); - spin_unlock_irqrestore(&ioapic_lock, flags); - - if (apic_id >= get_physical_broadcast()) { - printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying " - "%d\n", ioapic, apic_id, reg_00.bits.ID); - apic_id = reg_00.bits.ID; - } - - /* - * Every APIC in a system must have a unique ID or we get lots of nice - * 'stuck on smp_invalidate_needed IPI wait' messages. - */ - if (apic->check_apicid_used(apic_id_map, apic_id)) { - - for (i = 0; i < get_physical_broadcast(); i++) { - if (!apic->check_apicid_used(apic_id_map, i)) - break; - } - - if (i == get_physical_broadcast()) - panic("Max apic_id exceeded!\n"); - - printk(KERN_WARNING "IOAPIC[%d]: apic_id %d already used, " - "trying %d\n", ioapic, apic_id, i); - - apic_id = i; - } - - tmp = apic->apicid_to_cpu_present(apic_id); - physids_or(apic_id_map, apic_id_map, tmp); - - if (reg_00.bits.ID != apic_id) { - reg_00.bits.ID = apic_id; - - spin_lock_irqsave(&ioapic_lock, flags); - io_apic_write(ioapic, 0, reg_00.raw); - reg_00.raw = io_apic_read(ioapic, 0); - spin_unlock_irqrestore(&ioapic_lock, flags); - - /* Sanity check */ - if (reg_00.bits.ID != apic_id) { - printk("IOAPIC[%d]: Unable to change apic_id!\n", ioapic); - return -1; - } - } - - apic_printk(APIC_VERBOSE, KERN_INFO - "IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id); - - return apic_id; -} - -int __init io_apic_get_version(int ioapic) -{ - union IO_APIC_reg_01 reg_01; - unsigned long flags; - - spin_lock_irqsave(&ioapic_lock, flags); - reg_01.raw = io_apic_read(ioapic, 1); - spin_unlock_irqrestore(&ioapic_lock, flags); - - return reg_01.bits.version; -} -#endif - -int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int polarity) -{ - struct irq_desc *desc; - struct irq_cfg *cfg; - int cpu = boot_cpu_id; - - if (!IO_APIC_IRQ(irq)) { - apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n", - ioapic); - return -EINVAL; - } - - desc = irq_to_desc_alloc_cpu(irq, cpu); - if (!desc) { - printk(KERN_INFO "can not get irq_desc %d\n", irq); - return 0; - } - - /* - * IRQs < 16 are already in the irq_2_pin[] map - */ - if (irq >= NR_IRQS_LEGACY) { - cfg = desc->chip_data; - add_pin_to_irq_cpu(cfg, cpu, ioapic, pin); - } - - setup_IO_APIC_irq(ioapic, pin, irq, desc, triggering, polarity); - - return 0; -} - - -int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity) -{ - int i; - - if (skip_ioapic_setup) - return -1; - - for (i = 0; i < mp_irq_entries; i++) - if (mp_irqs[i].irqtype == mp_INT && - mp_irqs[i].srcbusirq == bus_irq) - break; - if (i >= mp_irq_entries) - return -1; - - *trigger = irq_trigger(i); - *polarity = irq_polarity(i); - return 0; -} - -#endif /* CONFIG_ACPI */ - -/* - * This function currently is only a helper for the i386 smp boot process where - * we need to reprogram the ioredtbls to cater for the cpus which have come online - * so mask in all cases should simply be apic->target_cpus() - */ -#ifdef CONFIG_SMP -void __init setup_ioapic_dest(void) -{ - int pin, ioapic, irq, irq_entry; - struct irq_desc *desc; - struct irq_cfg *cfg; - const struct cpumask *mask; - - if (skip_ioapic_setup == 1) - return; - - for (ioapic = 0; ioapic < nr_ioapics; ioapic++) { - for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) { - irq_entry = find_irq_entry(ioapic, pin, mp_INT); - if (irq_entry == -1) - continue; - irq = pin_2_irq(irq_entry, ioapic, pin); - - /* setup_IO_APIC_irqs could fail to get vector for some device - * when you have too many devices, because at that time only boot - * cpu is online. - */ - desc = irq_to_desc(irq); - cfg = desc->chip_data; - if (!cfg->vector) { - setup_IO_APIC_irq(ioapic, pin, irq, desc, - irq_trigger(irq_entry), - irq_polarity(irq_entry)); - continue; - - } - - /* - * Honour affinities which have been set in early boot - */ - if (desc->status & - (IRQ_NO_BALANCING | IRQ_AFFINITY_SET)) - mask = desc->affinity; - else - mask = apic->target_cpus(); - -#ifdef CONFIG_INTR_REMAP - if (intr_remapping_enabled) - set_ir_ioapic_affinity_irq_desc(desc, mask); - else -#endif - set_ioapic_affinity_irq_desc(desc, mask); - } - - } -} -#endif - -#define IOAPIC_RESOURCE_NAME_SIZE 11 - -static struct resource *ioapic_resources; - -static struct resource * __init ioapic_setup_resources(void) -{ - unsigned long n; - struct resource *res; - char *mem; - int i; - - if (nr_ioapics <= 0) - return NULL; - - n = IOAPIC_RESOURCE_NAME_SIZE + sizeof(struct resource); - n *= nr_ioapics; - - mem = alloc_bootmem(n); - res = (void *)mem; - - if (mem != NULL) { - mem += sizeof(struct resource) * nr_ioapics; - - for (i = 0; i < nr_ioapics; i++) { - res[i].name = mem; - res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY; - sprintf(mem, "IOAPIC %u", i); - mem += IOAPIC_RESOURCE_NAME_SIZE; - } - } - - ioapic_resources = res; - - return res; -} - -void __init ioapic_init_mappings(void) -{ - unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0; - struct resource *ioapic_res; - int i; - - ioapic_res = ioapic_setup_resources(); - for (i = 0; i < nr_ioapics; i++) { - if (smp_found_config) { - ioapic_phys = mp_ioapics[i].apicaddr; -#ifdef CONFIG_X86_32 - if (!ioapic_phys) { - printk(KERN_ERR - "WARNING: bogus zero IO-APIC " - "address found in MPTABLE, " - "disabling IO/APIC support!\n"); - smp_found_config = 0; - skip_ioapic_setup = 1; - goto fake_ioapic_page; - } -#endif - } else { -#ifdef CONFIG_X86_32 -fake_ioapic_page: -#endif - ioapic_phys = (unsigned long) - alloc_bootmem_pages(PAGE_SIZE); - ioapic_phys = __pa(ioapic_phys); - } - set_fixmap_nocache(idx, ioapic_phys); - apic_printk(APIC_VERBOSE, - "mapped IOAPIC to %08lx (%08lx)\n", - __fix_to_virt(idx), ioapic_phys); - idx++; - - if (ioapic_res != NULL) { - ioapic_res->start = ioapic_phys; - ioapic_res->end = ioapic_phys + (4 * 1024) - 1; - ioapic_res++; - } - } -} - -static int __init ioapic_insert_resources(void) -{ - int i; - struct resource *r = ioapic_resources; - - if (!r) { - printk(KERN_ERR - "IO APIC resources could be not be allocated.\n"); - return -1; - } - - for (i = 0; i < nr_ioapics; i++) { - insert_resource(&iomem_resource, r); - r++; - } - - return 0; -} - -/* Insert the IO APIC resources after PCI initialization has occured to handle - * IO APICS that are mapped in on a BAR in PCI space. */ -late_initcall(ioapic_insert_resources); diff --git a/arch/x86/kernel/ipi.c b/arch/x86/kernel/ipi.c deleted file mode 100644 index dbf5445727a..00000000000 --- a/arch/x86/kernel/ipi.c +++ /dev/null @@ -1,164 +0,0 @@ -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -void default_send_IPI_mask_sequence_phys(const struct cpumask *mask, int vector) -{ - unsigned long query_cpu; - unsigned long flags; - - /* - * Hack. The clustered APIC addressing mode doesn't allow us to send - * to an arbitrary mask, so I do a unicast to each CPU instead. - * - mbligh - */ - local_irq_save(flags); - for_each_cpu(query_cpu, mask) { - __default_send_IPI_dest_field(per_cpu(x86_cpu_to_apicid, - query_cpu), vector, APIC_DEST_PHYSICAL); - } - local_irq_restore(flags); -} - -void default_send_IPI_mask_allbutself_phys(const struct cpumask *mask, - int vector) -{ - unsigned int this_cpu = smp_processor_id(); - unsigned int query_cpu; - unsigned long flags; - - /* See Hack comment above */ - - local_irq_save(flags); - for_each_cpu(query_cpu, mask) { - if (query_cpu == this_cpu) - continue; - __default_send_IPI_dest_field(per_cpu(x86_cpu_to_apicid, - query_cpu), vector, APIC_DEST_PHYSICAL); - } - local_irq_restore(flags); -} - -void default_send_IPI_mask_sequence_logical(const struct cpumask *mask, - int vector) -{ - unsigned long flags; - unsigned int query_cpu; - - /* - * Hack. The clustered APIC addressing mode doesn't allow us to send - * to an arbitrary mask, so I do a unicasts to each CPU instead. This - * should be modified to do 1 message per cluster ID - mbligh - */ - - local_irq_save(flags); - for_each_cpu(query_cpu, mask) - __default_send_IPI_dest_field( - apic->cpu_to_logical_apicid(query_cpu), vector, - apic->dest_logical); - local_irq_restore(flags); -} - -void default_send_IPI_mask_allbutself_logical(const struct cpumask *mask, - int vector) -{ - unsigned long flags; - unsigned int query_cpu; - unsigned int this_cpu = smp_processor_id(); - - /* See Hack comment above */ - - local_irq_save(flags); - for_each_cpu(query_cpu, mask) { - if (query_cpu == this_cpu) - continue; - __default_send_IPI_dest_field( - apic->cpu_to_logical_apicid(query_cpu), vector, - apic->dest_logical); - } - local_irq_restore(flags); -} - -#ifdef CONFIG_X86_32 - -/* - * This is only used on smaller machines. - */ -void default_send_IPI_mask_logical(const struct cpumask *cpumask, int vector) -{ - unsigned long mask = cpumask_bits(cpumask)[0]; - unsigned long flags; - - local_irq_save(flags); - WARN_ON(mask & ~cpumask_bits(cpu_online_mask)[0]); - __default_send_IPI_dest_field(mask, vector, apic->dest_logical); - local_irq_restore(flags); -} - -void default_send_IPI_allbutself(int vector) -{ - /* - * if there are no other CPUs in the system then we get an APIC send - * error if we try to broadcast, thus avoid sending IPIs in this case. - */ - if (!(num_online_cpus() > 1)) - return; - - __default_local_send_IPI_allbutself(vector); -} - -void default_send_IPI_all(int vector) -{ - __default_local_send_IPI_all(vector); -} - -void default_send_IPI_self(int vector) -{ - __default_send_IPI_shortcut(APIC_DEST_SELF, vector, apic->dest_logical); -} - -/* must come after the send_IPI functions above for inlining */ -static int convert_apicid_to_cpu(int apic_id) -{ - int i; - - for_each_possible_cpu(i) { - if (per_cpu(x86_cpu_to_apicid, i) == apic_id) - return i; - } - return -1; -} - -int safe_smp_processor_id(void) -{ - int apicid, cpuid; - - if (!boot_cpu_has(X86_FEATURE_APIC)) - return 0; - - apicid = hard_smp_processor_id(); - if (apicid == BAD_APICID) - return 0; - - cpuid = convert_apicid_to_cpu(apicid); - - return cpuid >= 0 ? cpuid : 0; -} -#endif diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c deleted file mode 100644 index bdfad80c3cf..00000000000 --- a/arch/x86/kernel/nmi.c +++ /dev/null @@ -1,564 +0,0 @@ -/* - * NMI watchdog support on APIC systems - * - * Started by Ingo Molnar - * - * Fixes: - * Mikael Pettersson : AMD K7 support for local APIC NMI watchdog. - * Mikael Pettersson : Power Management for local APIC NMI watchdog. - * Mikael Pettersson : Pentium 4 support for local APIC NMI watchdog. - * Pavel Machek and - * Mikael Pettersson : PM converted to driver model. Disable/enable API. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include - -int unknown_nmi_panic; -int nmi_watchdog_enabled; - -static cpumask_t backtrace_mask = CPU_MASK_NONE; - -/* nmi_active: - * >0: the lapic NMI watchdog is active, but can be disabled - * <0: the lapic NMI watchdog has not been set up, and cannot - * be enabled - * 0: the lapic NMI watchdog is disabled, but can be enabled - */ -atomic_t nmi_active = ATOMIC_INIT(0); /* oprofile uses this */ -EXPORT_SYMBOL(nmi_active); - -unsigned int nmi_watchdog = NMI_NONE; -EXPORT_SYMBOL(nmi_watchdog); - -static int panic_on_timeout; - -static unsigned int nmi_hz = HZ; -static DEFINE_PER_CPU(short, wd_enabled); -static int endflag __initdata; - -static inline unsigned int get_nmi_count(int cpu) -{ - return per_cpu(irq_stat, cpu).__nmi_count; -} - -static inline int mce_in_progress(void) -{ -#if defined(CONFIG_X86_64) && defined(CONFIG_X86_MCE) - return atomic_read(&mce_entry) > 0; -#endif - return 0; -} - -/* - * Take the local apic timer and PIT/HPET into account. We don't - * know which one is active, when we have highres/dyntick on - */ -static inline unsigned int get_timer_irqs(int cpu) -{ - return per_cpu(irq_stat, cpu).apic_timer_irqs + - per_cpu(irq_stat, cpu).irq0_irqs; -} - -#ifdef CONFIG_SMP -/* - * The performance counters used by NMI_LOCAL_APIC don't trigger when - * the CPU is idle. To make sure the NMI watchdog really ticks on all - * CPUs during the test make them busy. - */ -static __init void nmi_cpu_busy(void *data) -{ - local_irq_enable_in_hardirq(); - /* - * Intentionally don't use cpu_relax here. This is - * to make sure that the performance counter really ticks, - * even if there is a simulator or similar that catches the - * pause instruction. On a real HT machine this is fine because - * all other CPUs are busy with "useless" delay loops and don't - * care if they get somewhat less cycles. - */ - while (endflag == 0) - mb(); -} -#endif - -static void report_broken_nmi(int cpu, int *prev_nmi_count) -{ - printk(KERN_CONT "\n"); - - printk(KERN_WARNING - "WARNING: CPU#%d: NMI appears to be stuck (%d->%d)!\n", - cpu, prev_nmi_count[cpu], get_nmi_count(cpu)); - - printk(KERN_WARNING - "Please report this to bugzilla.kernel.org,\n"); - printk(KERN_WARNING - "and attach the output of the 'dmesg' command.\n"); - - per_cpu(wd_enabled, cpu) = 0; - atomic_dec(&nmi_active); -} - -static void __acpi_nmi_disable(void *__unused) -{ - apic_write(APIC_LVT0, APIC_DM_NMI | APIC_LVT_MASKED); -} - -int __init check_nmi_watchdog(void) -{ - unsigned int *prev_nmi_count; - int cpu; - - if (!nmi_watchdog_active() || !atomic_read(&nmi_active)) - return 0; - - prev_nmi_count = kmalloc(nr_cpu_ids * sizeof(int), GFP_KERNEL); - if (!prev_nmi_count) - goto error; - - printk(KERN_INFO "Testing NMI watchdog ... "); - -#ifdef CONFIG_SMP - if (nmi_watchdog == NMI_LOCAL_APIC) - smp_call_function(nmi_cpu_busy, (void *)&endflag, 0); -#endif - - for_each_possible_cpu(cpu) - prev_nmi_count[cpu] = get_nmi_count(cpu); - local_irq_enable(); - mdelay((20 * 1000) / nmi_hz); /* wait 20 ticks */ - - for_each_online_cpu(cpu) { - if (!per_cpu(wd_enabled, cpu)) - continue; - if (get_nmi_count(cpu) - prev_nmi_count[cpu] <= 5) - report_broken_nmi(cpu, prev_nmi_count); - } - endflag = 1; - if (!atomic_read(&nmi_active)) { - kfree(prev_nmi_count); - atomic_set(&nmi_active, -1); - goto error; - } - printk("OK.\n"); - - /* - * now that we know it works we can reduce NMI frequency to - * something more reasonable; makes a difference in some configs - */ - if (nmi_watchdog == NMI_LOCAL_APIC) - nmi_hz = lapic_adjust_nmi_hz(1); - - kfree(prev_nmi_count); - return 0; -error: - if (nmi_watchdog == NMI_IO_APIC) { - if (!timer_through_8259) - disable_8259A_irq(0); - on_each_cpu(__acpi_nmi_disable, NULL, 1); - } - -#ifdef CONFIG_X86_32 - timer_ack = 0; -#endif - return -1; -} - -static int __init setup_nmi_watchdog(char *str) -{ - unsigned int nmi; - - if (!strncmp(str, "panic", 5)) { - panic_on_timeout = 1; - str = strchr(str, ','); - if (!str) - return 1; - ++str; - } - - if (!strncmp(str, "lapic", 5)) - nmi_watchdog = NMI_LOCAL_APIC; - else if (!strncmp(str, "ioapic", 6)) - nmi_watchdog = NMI_IO_APIC; - else { - get_option(&str, &nmi); - if (nmi >= NMI_INVALID) - return 0; - nmi_watchdog = nmi; - } - - return 1; -} -__setup("nmi_watchdog=", setup_nmi_watchdog); - -/* - * Suspend/resume support - */ -#ifdef CONFIG_PM - -static int nmi_pm_active; /* nmi_active before suspend */ - -static int lapic_nmi_suspend(struct sys_device *dev, pm_message_t state) -{ - /* only CPU0 goes here, other CPUs should be offline */ - nmi_pm_active = atomic_read(&nmi_active); - stop_apic_nmi_watchdog(NULL); - BUG_ON(atomic_read(&nmi_active) != 0); - return 0; -} - -static int lapic_nmi_resume(struct sys_device *dev) -{ - /* only CPU0 goes here, other CPUs should be offline */ - if (nmi_pm_active > 0) { - setup_apic_nmi_watchdog(NULL); - touch_nmi_watchdog(); - } - return 0; -} - -static struct sysdev_class nmi_sysclass = { - .name = "lapic_nmi", - .resume = lapic_nmi_resume, - .suspend = lapic_nmi_suspend, -}; - -static struct sys_device device_lapic_nmi = { - .id = 0, - .cls = &nmi_sysclass, -}; - -static int __init init_lapic_nmi_sysfs(void) -{ - int error; - - /* - * should really be a BUG_ON but b/c this is an - * init call, it just doesn't work. -dcz - */ - if (nmi_watchdog != NMI_LOCAL_APIC) - return 0; - - if (atomic_read(&nmi_active) < 0) - return 0; - - error = sysdev_class_register(&nmi_sysclass); - if (!error) - error = sysdev_register(&device_lapic_nmi); - return error; -} - -/* must come after the local APIC's device_initcall() */ -late_initcall(init_lapic_nmi_sysfs); - -#endif /* CONFIG_PM */ - -static void __acpi_nmi_enable(void *__unused) -{ - apic_write(APIC_LVT0, APIC_DM_NMI); -} - -/* - * Enable timer based NMIs on all CPUs: - */ -void acpi_nmi_enable(void) -{ - if (atomic_read(&nmi_active) && nmi_watchdog == NMI_IO_APIC) - on_each_cpu(__acpi_nmi_enable, NULL, 1); -} - -/* - * Disable timer based NMIs on all CPUs: - */ -void acpi_nmi_disable(void) -{ - if (atomic_read(&nmi_active) && nmi_watchdog == NMI_IO_APIC) - on_each_cpu(__acpi_nmi_disable, NULL, 1); -} - -/* - * This function is called as soon the LAPIC NMI watchdog driver has everything - * in place and it's ready to check if the NMIs belong to the NMI watchdog - */ -void cpu_nmi_set_wd_enabled(void) -{ - __get_cpu_var(wd_enabled) = 1; -} - -void setup_apic_nmi_watchdog(void *unused) -{ - if (__get_cpu_var(wd_enabled)) - return; - - /* cheap hack to support suspend/resume */ - /* if cpu0 is not active neither should the other cpus */ - if (smp_processor_id() != 0 && atomic_read(&nmi_active) <= 0) - return; - - switch (nmi_watchdog) { - case NMI_LOCAL_APIC: - if (lapic_watchdog_init(nmi_hz) < 0) { - __get_cpu_var(wd_enabled) = 0; - return; - } - /* FALL THROUGH */ - case NMI_IO_APIC: - __get_cpu_var(wd_enabled) = 1; - atomic_inc(&nmi_active); - } -} - -void stop_apic_nmi_watchdog(void *unused) -{ - /* only support LOCAL and IO APICs for now */ - if (!nmi_watchdog_active()) - return; - if (__get_cpu_var(wd_enabled) == 0) - return; - if (nmi_watchdog == NMI_LOCAL_APIC) - lapic_watchdog_stop(); - else - __acpi_nmi_disable(NULL); - __get_cpu_var(wd_enabled) = 0; - atomic_dec(&nmi_active); -} - -/* - * the best way to detect whether a CPU has a 'hard lockup' problem - * is to check it's local APIC timer IRQ counts. If they are not - * changing then that CPU has some problem. - * - * as these watchdog NMI IRQs are generated on every CPU, we only - * have to check the current processor. - * - * since NMIs don't listen to _any_ locks, we have to be extremely - * careful not to rely on unsafe variables. The printk might lock - * up though, so we have to break up any console locks first ... - * [when there will be more tty-related locks, break them up here too!] - */ - -static DEFINE_PER_CPU(unsigned, last_irq_sum); -static DEFINE_PER_CPU(local_t, alert_counter); -static DEFINE_PER_CPU(int, nmi_touch); - -void touch_nmi_watchdog(void) -{ - if (nmi_watchdog_active()) { - unsigned cpu; - - /* - * Tell other CPUs to reset their alert counters. We cannot - * do it ourselves because the alert count increase is not - * atomic. - */ - for_each_present_cpu(cpu) { - if (per_cpu(nmi_touch, cpu) != 1) - per_cpu(nmi_touch, cpu) = 1; - } - } - - /* - * Tickle the softlockup detector too: - */ - touch_softlockup_watchdog(); -} -EXPORT_SYMBOL(touch_nmi_watchdog); - -notrace __kprobes int -nmi_watchdog_tick(struct pt_regs *regs, unsigned reason) -{ - /* - * Since current_thread_info()-> is always on the stack, and we - * always switch the stack NMI-atomically, it's safe to use - * smp_processor_id(). - */ - unsigned int sum; - int touched = 0; - int cpu = smp_processor_id(); - int rc = 0; - - /* check for other users first */ - if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) - == NOTIFY_STOP) { - rc = 1; - touched = 1; - } - - sum = get_timer_irqs(cpu); - - if (__get_cpu_var(nmi_touch)) { - __get_cpu_var(nmi_touch) = 0; - touched = 1; - } - - if (cpu_isset(cpu, backtrace_mask)) { - static DEFINE_SPINLOCK(lock); /* Serialise the printks */ - - spin_lock(&lock); - printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu); - dump_stack(); - spin_unlock(&lock); - cpu_clear(cpu, backtrace_mask); - } - - /* Could check oops_in_progress here too, but it's safer not to */ - if (mce_in_progress()) - touched = 1; - - /* if the none of the timers isn't firing, this cpu isn't doing much */ - if (!touched && __get_cpu_var(last_irq_sum) == sum) { - /* - * Ayiee, looks like this CPU is stuck ... - * wait a few IRQs (5 seconds) before doing the oops ... - */ - local_inc(&__get_cpu_var(alert_counter)); - if (local_read(&__get_cpu_var(alert_counter)) == 5 * nmi_hz) - /* - * die_nmi will return ONLY if NOTIFY_STOP happens.. - */ - die_nmi("BUG: NMI Watchdog detected LOCKUP", - regs, panic_on_timeout); - } else { - __get_cpu_var(last_irq_sum) = sum; - local_set(&__get_cpu_var(alert_counter), 0); - } - - /* see if the nmi watchdog went off */ - if (!__get_cpu_var(wd_enabled)) - return rc; - switch (nmi_watchdog) { - case NMI_LOCAL_APIC: - rc |= lapic_wd_event(nmi_hz); - break; - case NMI_IO_APIC: - /* - * don't know how to accurately check for this. - * just assume it was a watchdog timer interrupt - * This matches the old behaviour. - */ - rc = 1; - break; - } - return rc; -} - -#ifdef CONFIG_SYSCTL - -static void enable_ioapic_nmi_watchdog_single(void *unused) -{ - __get_cpu_var(wd_enabled) = 1; - atomic_inc(&nmi_active); - __acpi_nmi_enable(NULL); -} - -static void enable_ioapic_nmi_watchdog(void) -{ - on_each_cpu(enable_ioapic_nmi_watchdog_single, NULL, 1); - touch_nmi_watchdog(); -} - -static void disable_ioapic_nmi_watchdog(void) -{ - on_each_cpu(stop_apic_nmi_watchdog, NULL, 1); -} - -static int __init setup_unknown_nmi_panic(char *str) -{ - unknown_nmi_panic = 1; - return 1; -} -__setup("unknown_nmi_panic", setup_unknown_nmi_panic); - -static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu) -{ - unsigned char reason = get_nmi_reason(); - char buf[64]; - - sprintf(buf, "NMI received for unknown reason %02x\n", reason); - die_nmi(buf, regs, 1); /* Always panic here */ - return 0; -} - -/* - * proc handler for /proc/sys/kernel/nmi - */ -int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, - void __user *buffer, size_t *length, loff_t *ppos) -{ - int old_state; - - nmi_watchdog_enabled = (atomic_read(&nmi_active) > 0) ? 1 : 0; - old_state = nmi_watchdog_enabled; - proc_dointvec(table, write, file, buffer, length, ppos); - if (!!old_state == !!nmi_watchdog_enabled) - return 0; - - if (atomic_read(&nmi_active) < 0 || !nmi_watchdog_active()) { - printk(KERN_WARNING - "NMI watchdog is permanently disabled\n"); - return -EIO; - } - - if (nmi_watchdog == NMI_LOCAL_APIC) { - if (nmi_watchdog_enabled) - enable_lapic_nmi_watchdog(); - else - disable_lapic_nmi_watchdog(); - } else if (nmi_watchdog == NMI_IO_APIC) { - if (nmi_watchdog_enabled) - enable_ioapic_nmi_watchdog(); - else - disable_ioapic_nmi_watchdog(); - } else { - printk(KERN_WARNING - "NMI watchdog doesn't know what hardware to touch\n"); - return -EIO; - } - return 0; -} - -#endif /* CONFIG_SYSCTL */ - -int do_nmi_callback(struct pt_regs *regs, int cpu) -{ -#ifdef CONFIG_SYSCTL - if (unknown_nmi_panic) - return unknown_nmi_panic_callback(regs, cpu); -#endif - return 0; -} - -void __trigger_all_cpu_backtrace(void) -{ - int i; - - backtrace_mask = cpu_online_map; - /* Wait for up to 10 seconds for all CPUs to do the backtrace */ - for (i = 0; i < 10 * 1000; i++) { - if (cpus_empty(backtrace_mask)) - break; - mdelay(1); - } -} -- cgit From 5b058bcde961bf28678a70e44c079107313543b6 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Tue, 17 Feb 2009 18:35:34 +0100 Subject: tracing/function-graph-tracer: trace the idle tasks When the function graph tracer is activated, it iterates over the task_list to allocate a stack to store the return addresses. But the per cpu idle tasks are not iterated by using do_each_thread / while_each_thread. So we have to iterate on them manually. This fixes somes weirdness in the traces and many losses of traces. Examples on two cpus: 0) Xorg-4287 | 2.906 us | } 0) Xorg-4287 | 3.965 us | } 0) Xorg-4287 | 5.302 us | } ------------------------------------------ 0) Xorg-4287 => -0 ------------------------------------------ 0) -0 | 2.861 us | } 0) -0 | 0.526 us | set_normalized_timespec(); 0) -0 | 7.201 us | } 0) -0 | 8.214 us | } 0) -0 | | clockevents_program_event() { 0) -0 | | lapic_next_event() { 0) -0 | 0.510 us | native_apic_mem_write(); 0) -0 | 1.546 us | } 0) -0 | 2.583 us | } 0) -0 | + 12.435 us | } 0) -0 | + 13.470 us | } 0) -0 | 0.608 us | _spin_unlock_irqrestore(); 0) -0 | + 23.270 us | } 0) -0 | + 24.336 us | } 0) -0 | + 25.417 us | } 0) -0 | 0.593 us | _spin_unlock(); 0) -0 | + 41.869 us | } 0) -0 | + 42.906 us | } 0) -0 | + 95.035 us | } 0) -0 | 0.540 us | menu_reflect(); 0) -0 | ! 100.404 us | } 0) -0 | 0.564 us | mce_idle_callback(); 0) -0 | | enter_idle() { 0) -0 | 0.526 us | mce_idle_callback(); 0) -0 | 1.757 us | } 0) -0 | | cpuidle_idle_call() { 0) -0 | | menu_select() { 0) -0 | 0.525 us | pm_qos_requirement(); 0) -0 | 0.518 us | tick_nohz_get_sleep_length(); 0) -0 | 2.621 us | } [...] 1) -0 | 0.518 us | touch_softlockup_watchdog(); 1) -0 | + 14.355 us | } 1) -0 | + 22.840 us | } 1) -0 | + 25.949 us | } 1) -0 | | handle_irq() { 1) -0 | 0.511 us | irq_to_desc(); 1) -0 | | handle_edge_irq() { 1) -0 | 0.638 us | _spin_lock(); 1) -0 | | ack_apic_edge() { 1) -0 | 0.510 us | irq_to_desc(); 1) -0 | | move_native_irq() { 1) -0 | 0.510 us | irq_to_desc(); 1) -0 | 1.532 us | } 1) -0 | 0.511 us | native_apic_mem_write(); ------------------------------------------ 1) -0 => cat-5073 ------------------------------------------ 1) cat-5073 | 3.731 us | } 1) cat-5073 | | run_local_timers() { 1) cat-5073 | 0.533 us | hrtimer_run_queues(); 1) cat-5073 | | raise_softirq() { 1) cat-5073 | | __raise_softirq_irqoff() { 1) cat-5073 | | /* nr: 1 */ 1) cat-5073 | 2.718 us | } 1) cat-5073 | 3.814 us | } Signed-off-by: Frederic Weisbecker Cc: Steven Rostedt Cc: Arnaldo Carvalho de Melo Signed-off-by: Ingo Molnar --- kernel/trace/ftrace.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 9a236ffe2aa..fdf913dfc7e 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -2033,7 +2033,7 @@ free: static int start_graph_tracing(void) { struct ftrace_ret_stack **ret_stack_list; - int ret; + int ret, cpu; ret_stack_list = kmalloc(FTRACE_RETSTACK_ALLOC_SIZE * sizeof(struct ftrace_ret_stack *), @@ -2042,6 +2042,10 @@ static int start_graph_tracing(void) if (!ret_stack_list) return -ENOMEM; + /* The cpu_boot init_task->ret_stack will never be freed */ + for_each_online_cpu(cpu) + ftrace_graph_init_task(idle_task(cpu)); + do { ret = alloc_retstack_tasklist(ret_stack_list); } while (ret == -EAGAIN); -- cgit From 603eaa1bdd3e0402085e815cc531bb0a32827a9e Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 17 Feb 2009 19:59:54 +0100 Subject: hwmon: (f71882fg) Hide misleading error message If the F71882FG chip is at address 0x4e, then the probe at 0x2e will fail with the following message in the logs: f71882fg: Not a Fintek device This is misleading because there is a Fintek device, just at a different address. So I propose to degrade this message to a debug message. Signed-off-by: Jean Delvare Acked-by: Hans de Goede --- drivers/hwmon/f71882fg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 609cafff86b..367f6cb1166 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c @@ -1872,7 +1872,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, devid = superio_inw(sioaddr, SIO_REG_MANID); if (devid != SIO_FINTEK_ID) { - printk(KERN_INFO DRVNAME ": Not a Fintek device\n"); + pr_debug(DRVNAME ": Not a Fintek device\n"); goto exit; } -- cgit From 18632f84fac770125c0982dfadec6b551e82144e Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 17 Feb 2009 19:59:54 +0100 Subject: hwmon: Fix ACPI resource check error handling This patch fixes a number of cases where things were not properly cleaned up when acpi_check_resource_conflict() returned an error, causing oopses such as the one reported here: https://bugzilla.redhat.com/show_bug.cgi?id=483208 Signed-off-by: Hans de Goede Signed-off-by: Jean Delvare --- drivers/hwmon/f71882fg.c | 2 +- drivers/hwmon/vt1211.c | 2 +- drivers/hwmon/w83627ehf.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 367f6cb1166..5f81ddf7150 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c @@ -1932,7 +1932,7 @@ static int __init f71882fg_device_add(unsigned short address, res.name = f71882fg_pdev->name; err = acpi_check_resource_conflict(&res); if (err) - return err; + goto exit_device_put; err = platform_device_add_resources(f71882fg_pdev, &res, 1); if (err) { diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c index b0ce3785228..73f77a9b8b1 100644 --- a/drivers/hwmon/vt1211.c +++ b/drivers/hwmon/vt1211.c @@ -1262,7 +1262,7 @@ static int __init vt1211_device_add(unsigned short address) res.name = pdev->name; err = acpi_check_resource_conflict(&res); if (err) - goto EXIT; + goto EXIT_DEV_PUT; err = platform_device_add_resources(pdev, &res, 1); if (err) { diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index cb808d01536..feae743ba99 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c @@ -1548,7 +1548,7 @@ static int __init sensors_w83627ehf_init(void) err = acpi_check_resource_conflict(&res); if (err) - goto exit; + goto exit_device_put; err = platform_device_add_resources(pdev, &res, 1); if (err) { -- cgit From 211e3e0e1b116b10ba707db2fec972909fa647fd Mon Sep 17 00:00:00 2001 From: Frank Seidel Date: Tue, 17 Feb 2009 19:59:54 +0100 Subject: MAINTAINERS: Switch hdaps to Frank Seidel As Rovert Love doesn't any more seem to be realy active on hdaps driver i'll happily take it over. Signed-off-by: Frank Seidel Cc: Robert Love Signed-off-by: Jean Delvare --- MAINTAINERS | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index db65b4e6d13..a654c5b9c27 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1905,10 +1905,10 @@ W: http://gigaset307x.sourceforge.net/ S: Maintained HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER -P: Robert Love -M: rlove@rlove.org -M: linux-kernel@vger.kernel.org -W: http://www.kernel.org/pub/linux/kernel/people/rml/hdaps/ +P: Frank Seidel +M: frank@f-seidel.de +L: lm-sensors@lm-sensors.org +W: http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/ S: Maintained GSPCA FINEPIX SUBDRIVER -- cgit From 2a05180fe2e5b414f0cb2ccfc80e6c90563e3c67 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 17 Feb 2009 20:35:16 +0100 Subject: x86, apic: move remaining APIC drivers to arch/x86/kernel/apic/* Move the 32-bit extended-arch APIC drivers to arch/x86/kernel/apic/ too, and rename apic_64.c to probe_64.c. Signed-off-by: Ingo Molnar --- arch/x86/kernel/Makefile | 6 +- arch/x86/kernel/apic/Makefile | 9 +- arch/x86/kernel/apic/apic_64.c | 89 ----- arch/x86/kernel/apic/bigsmp_32.c | 274 ++++++++++++++ arch/x86/kernel/apic/es7000_32.c | 757 +++++++++++++++++++++++++++++++++++++++ arch/x86/kernel/apic/numaq_32.c | 565 +++++++++++++++++++++++++++++ arch/x86/kernel/apic/probe_32.c | 424 ++++++++++++++++++++++ arch/x86/kernel/apic/probe_64.c | 89 +++++ arch/x86/kernel/apic/summit_32.c | 601 +++++++++++++++++++++++++++++++ arch/x86/kernel/bigsmp_32.c | 274 -------------- arch/x86/kernel/es7000_32.c | 757 --------------------------------------- arch/x86/kernel/numaq_32.c | 565 ----------------------------- arch/x86/kernel/probe_32.c | 424 ---------------------- arch/x86/kernel/summit_32.c | 601 ------------------------------- 14 files changed, 2718 insertions(+), 2717 deletions(-) delete mode 100644 arch/x86/kernel/apic/apic_64.c create mode 100644 arch/x86/kernel/apic/bigsmp_32.c create mode 100644 arch/x86/kernel/apic/es7000_32.c create mode 100644 arch/x86/kernel/apic/numaq_32.c create mode 100644 arch/x86/kernel/apic/probe_32.c create mode 100644 arch/x86/kernel/apic/probe_64.c create mode 100644 arch/x86/kernel/apic/summit_32.c delete mode 100644 arch/x86/kernel/bigsmp_32.c delete mode 100644 arch/x86/kernel/es7000_32.c delete mode 100644 arch/x86/kernel/numaq_32.c delete mode 100644 arch/x86/kernel/probe_32.c delete mode 100644 arch/x86/kernel/summit_32.c diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 9139ff69471..c70537d8c15 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -30,7 +30,7 @@ obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o obj-y += time_$(BITS).o ioport.o ldt.o dumpstack.o obj-y += setup.o i8259.o irqinit_$(BITS).o obj-$(CONFIG_X86_VISWS) += visws_quirks.o -obj-$(CONFIG_X86_32) += probe_32.o probe_roms_32.o +obj-$(CONFIG_X86_32) += probe_roms_32.o obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o obj-$(CONFIG_X86_64) += syscall_64.o vsyscall_64.o @@ -70,10 +70,6 @@ obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o -obj-$(CONFIG_X86_BIGSMP) += bigsmp_32.o -obj-$(CONFIG_X86_NUMAQ) += numaq_32.o -obj-$(CONFIG_X86_ES7000) += es7000_32.o -obj-$(CONFIG_X86_SUMMIT) += summit_32.o obj-y += vsmp_64.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_MODULES) += module_$(BITS).o diff --git a/arch/x86/kernel/apic/Makefile b/arch/x86/kernel/apic/Makefile index da20b70c400..97f558db5c3 100644 --- a/arch/x86/kernel/apic/Makefile +++ b/arch/x86/kernel/apic/Makefile @@ -2,14 +2,19 @@ # Makefile for local APIC drivers and for the IO-APIC code # -obj-y := apic.o ipi.o nmi.o +obj-y := apic.o probe_$(BITS).o ipi.o nmi.o obj-$(CONFIG_X86_IO_APIC) += io_apic.o obj-$(CONFIG_SMP) += ipi.o +obj-$ ifeq ($(CONFIG_X86_64),y) -obj-y += apic_64.o apic_flat_64.o +obj-y += apic_flat_64.o obj-$(CONFIG_X86_X2APIC) += x2apic_cluster.o obj-$(CONFIG_X86_X2APIC) += x2apic_phys.o obj-$(CONFIG_X86_UV) += x2apic_uv_x.o endif +obj-$(CONFIG_X86_BIGSMP) += bigsmp_32.o +obj-$(CONFIG_X86_NUMAQ) += numaq_32.o +obj-$(CONFIG_X86_ES7000) += es7000_32.o +obj-$(CONFIG_X86_SUMMIT) += summit_32.o diff --git a/arch/x86/kernel/apic/apic_64.c b/arch/x86/kernel/apic/apic_64.c deleted file mode 100644 index 70935dd904d..00000000000 --- a/arch/x86/kernel/apic/apic_64.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2004 James Cleverdon, IBM. - * Subject to the GNU Public License, v.2 - * - * Generic APIC sub-arch probe layer. - * - * Hacked for x86-64 by James Cleverdon from i386 architecture code by - * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and - * James Cleverdon. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -extern struct apic apic_flat; -extern struct apic apic_physflat; -extern struct apic apic_x2xpic_uv_x; -extern struct apic apic_x2apic_phys; -extern struct apic apic_x2apic_cluster; - -struct apic __read_mostly *apic = &apic_flat; -EXPORT_SYMBOL_GPL(apic); - -static struct apic *apic_probe[] __initdata = { -#ifdef CONFIG_X86_UV - &apic_x2apic_uv_x, -#endif -#ifdef CONFIG_X86_X2APIC - &apic_x2apic_phys, - &apic_x2apic_cluster, -#endif - &apic_physflat, - NULL, -}; - -/* - * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. - */ -void __init default_setup_apic_routing(void) -{ -#ifdef CONFIG_X86_X2APIC - if (apic == &apic_x2apic_phys || apic == &apic_x2apic_cluster) { - if (!intr_remapping_enabled) - apic = &apic_flat; - } -#endif - - if (apic == &apic_flat) { - if (max_physical_apicid >= 8) - apic = &apic_physflat; - printk(KERN_INFO "Setting APIC routing to %s\n", apic->name); - } - - if (x86_quirks->update_apic) - x86_quirks->update_apic(); -} - -/* Same for both flat and physical. */ - -void apic_send_IPI_self(int vector) -{ - __default_send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL); -} - -int __init default_acpi_madt_oem_check(char *oem_id, char *oem_table_id) -{ - int i; - - for (i = 0; apic_probe[i]; ++i) { - if (apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id)) { - apic = apic_probe[i]; - printk(KERN_INFO "Setting APIC routing to %s.\n", - apic->name); - return 1; - } - } - return 0; -} diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c new file mode 100644 index 00000000000..0b1093394fd --- /dev/null +++ b/arch/x86/kernel/apic/bigsmp_32.c @@ -0,0 +1,274 @@ +/* + * APIC driver for "bigsmp" xAPIC machines with more than 8 virtual CPUs. + * + * Drives the local APIC in "clustered mode". + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static inline unsigned bigsmp_get_apic_id(unsigned long x) +{ + return (x >> 24) & 0xFF; +} + +static inline int bigsmp_apic_id_registered(void) +{ + return 1; +} + +static inline const cpumask_t *bigsmp_target_cpus(void) +{ +#ifdef CONFIG_SMP + return &cpu_online_map; +#else + return &cpumask_of_cpu(0); +#endif +} + +static inline unsigned long +bigsmp_check_apicid_used(physid_mask_t bitmap, int apicid) +{ + return 0; +} + +static inline unsigned long bigsmp_check_apicid_present(int bit) +{ + return 1; +} + +static inline unsigned long calculate_ldr(int cpu) +{ + unsigned long val, id; + + val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; + id = per_cpu(x86_bios_cpu_apicid, cpu); + val |= SET_APIC_LOGICAL_ID(id); + + return val; +} + +/* + * Set up the logical destination ID. + * + * Intel recommends to set DFR, LDR and TPR before enabling + * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel + * document number 292116). So here it goes... + */ +static inline void bigsmp_init_apic_ldr(void) +{ + unsigned long val; + int cpu = smp_processor_id(); + + apic_write(APIC_DFR, APIC_DFR_FLAT); + val = calculate_ldr(cpu); + apic_write(APIC_LDR, val); +} + +static inline void bigsmp_setup_apic_routing(void) +{ + printk(KERN_INFO + "Enabling APIC mode: Physflat. Using %d I/O APICs\n", + nr_ioapics); +} + +static inline int bigsmp_apicid_to_node(int logical_apicid) +{ + return apicid_2_node[hard_smp_processor_id()]; +} + +static inline int bigsmp_cpu_present_to_apicid(int mps_cpu) +{ + if (mps_cpu < nr_cpu_ids) + return (int) per_cpu(x86_bios_cpu_apicid, mps_cpu); + + return BAD_APICID; +} + +static inline physid_mask_t bigsmp_apicid_to_cpu_present(int phys_apicid) +{ + return physid_mask_of_physid(phys_apicid); +} + +/* Mapping from cpu number to logical apicid */ +static inline int bigsmp_cpu_to_logical_apicid(int cpu) +{ + if (cpu >= nr_cpu_ids) + return BAD_APICID; + return cpu_physical_id(cpu); +} + +static inline physid_mask_t bigsmp_ioapic_phys_id_map(physid_mask_t phys_map) +{ + /* For clustered we don't have a good way to do this yet - hack */ + return physids_promote(0xFFL); +} + +static inline void bigsmp_setup_portio_remap(void) +{ +} + +static inline int bigsmp_check_phys_apicid_present(int boot_cpu_physical_apicid) +{ + return 1; +} + +/* As we are using single CPU as destination, pick only one CPU here */ +static inline unsigned int bigsmp_cpu_mask_to_apicid(const cpumask_t *cpumask) +{ + return bigsmp_cpu_to_logical_apicid(first_cpu(*cpumask)); +} + +static inline unsigned int +bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask, + const struct cpumask *andmask) +{ + int cpu; + + /* + * We're using fixed IRQ delivery, can only return one phys APIC ID. + * May as well be the first. + */ + for_each_cpu_and(cpu, cpumask, andmask) { + if (cpumask_test_cpu(cpu, cpu_online_mask)) + break; + } + if (cpu < nr_cpu_ids) + return bigsmp_cpu_to_logical_apicid(cpu); + + return BAD_APICID; +} + +static inline int bigsmp_phys_pkg_id(int cpuid_apic, int index_msb) +{ + return cpuid_apic >> index_msb; +} + +static inline void bigsmp_send_IPI_mask(const struct cpumask *mask, int vector) +{ + default_send_IPI_mask_sequence_phys(mask, vector); +} + +static inline void bigsmp_send_IPI_allbutself(int vector) +{ + default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector); +} + +static inline void bigsmp_send_IPI_all(int vector) +{ + bigsmp_send_IPI_mask(cpu_online_mask, vector); +} + +static int dmi_bigsmp; /* can be set by dmi scanners */ + +static int hp_ht_bigsmp(const struct dmi_system_id *d) +{ + printk(KERN_NOTICE "%s detected: force use of apic=bigsmp\n", d->ident); + dmi_bigsmp = 1; + + return 0; +} + + +static const struct dmi_system_id bigsmp_dmi_table[] = { + { hp_ht_bigsmp, "HP ProLiant DL760 G2", + { DMI_MATCH(DMI_BIOS_VENDOR, "HP"), + DMI_MATCH(DMI_BIOS_VERSION, "P44-"), + } + }, + + { hp_ht_bigsmp, "HP ProLiant DL740", + { DMI_MATCH(DMI_BIOS_VENDOR, "HP"), + DMI_MATCH(DMI_BIOS_VERSION, "P47-"), + } + }, + { } /* NULL entry stops DMI scanning */ +}; + +static void bigsmp_vector_allocation_domain(int cpu, cpumask_t *retmask) +{ + cpus_clear(*retmask); + cpu_set(cpu, *retmask); +} + +static int probe_bigsmp(void) +{ + if (def_to_bigsmp) + dmi_bigsmp = 1; + else + dmi_check_system(bigsmp_dmi_table); + + return dmi_bigsmp; +} + +struct apic apic_bigsmp = { + + .name = "bigsmp", + .probe = probe_bigsmp, + .acpi_madt_oem_check = NULL, + .apic_id_registered = bigsmp_apic_id_registered, + + .irq_delivery_mode = dest_Fixed, + /* phys delivery to target CPU: */ + .irq_dest_mode = 0, + + .target_cpus = bigsmp_target_cpus, + .disable_esr = 1, + .dest_logical = 0, + .check_apicid_used = bigsmp_check_apicid_used, + .check_apicid_present = bigsmp_check_apicid_present, + + .vector_allocation_domain = bigsmp_vector_allocation_domain, + .init_apic_ldr = bigsmp_init_apic_ldr, + + .ioapic_phys_id_map = bigsmp_ioapic_phys_id_map, + .setup_apic_routing = bigsmp_setup_apic_routing, + .multi_timer_check = NULL, + .apicid_to_node = bigsmp_apicid_to_node, + .cpu_to_logical_apicid = bigsmp_cpu_to_logical_apicid, + .cpu_present_to_apicid = bigsmp_cpu_present_to_apicid, + .apicid_to_cpu_present = bigsmp_apicid_to_cpu_present, + .setup_portio_remap = NULL, + .check_phys_apicid_present = bigsmp_check_phys_apicid_present, + .enable_apic_mode = NULL, + .phys_pkg_id = bigsmp_phys_pkg_id, + .mps_oem_check = NULL, + + .get_apic_id = bigsmp_get_apic_id, + .set_apic_id = NULL, + .apic_id_mask = 0xFF << 24, + + .cpu_mask_to_apicid = bigsmp_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = bigsmp_cpu_mask_to_apicid_and, + + .send_IPI_mask = bigsmp_send_IPI_mask, + .send_IPI_mask_allbutself = NULL, + .send_IPI_allbutself = bigsmp_send_IPI_allbutself, + .send_IPI_all = bigsmp_send_IPI_all, + .send_IPI_self = default_send_IPI_self, + + .wakeup_cpu = NULL, + .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, + .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, + + .wait_for_init_deassert = default_wait_for_init_deassert, + + .smp_callin_clear_local_apic = NULL, + .inquire_remote_apic = default_inquire_remote_apic, + + .read = native_apic_mem_read, + .write = native_apic_mem_write, + .icr_read = native_apic_icr_read, + .icr_write = native_apic_icr_write, + .wait_icr_idle = native_apic_wait_icr_idle, + .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, +}; diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c new file mode 100644 index 00000000000..320f2d2e4e5 --- /dev/null +++ b/arch/x86/kernel/apic/es7000_32.c @@ -0,0 +1,757 @@ +/* + * Written by: Garry Forsgren, Unisys Corporation + * Natalie Protasevich, Unisys Corporation + * + * This file contains the code to configure and interface + * with Unisys ES7000 series hardware system manager. + * + * Copyright (c) 2003 Unisys Corporation. + * Copyright (C) 2009, Red Hat, Inc., Ingo Molnar + * + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Unisys Corporation, Township Line & Union Meeting + * Roads-A, Unisys Way, Blue Bell, Pennsylvania, 19424, or: + * + * http://www.unisys.com + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* + * ES7000 chipsets + */ + +#define NON_UNISYS 0 +#define ES7000_CLASSIC 1 +#define ES7000_ZORRO 2 + +#define MIP_REG 1 +#define MIP_PSAI_REG 4 + +#define MIP_BUSY 1 +#define MIP_SPIN 0xf0000 +#define MIP_VALID 0x0100000000000000ULL +#define MIP_SW_APIC 0x1020b + +#define MIP_PORT(val) ((val >> 32) & 0xffff) + +#define MIP_RD_LO(val) (val & 0xffffffff) + +struct mip_reg { + unsigned long long off_0x00; + unsigned long long off_0x08; + unsigned long long off_0x10; + unsigned long long off_0x18; + unsigned long long off_0x20; + unsigned long long off_0x28; + unsigned long long off_0x30; + unsigned long long off_0x38; +}; + +struct mip_reg_info { + unsigned long long mip_info; + unsigned long long delivery_info; + unsigned long long host_reg; + unsigned long long mip_reg; +}; + +struct psai { + unsigned long long entry_type; + unsigned long long addr; + unsigned long long bep_addr; +}; + +#ifdef CONFIG_ACPI + +struct es7000_oem_table { + struct acpi_table_header Header; + u32 OEMTableAddr; + u32 OEMTableSize; +}; + +static unsigned long oem_addrX; +static unsigned long oem_size; + +#endif + +/* + * ES7000 Globals + */ + +static volatile unsigned long *psai; +static struct mip_reg *mip_reg; +static struct mip_reg *host_reg; +static int mip_port; +static unsigned long mip_addr; +static unsigned long host_addr; + +int es7000_plat; + +/* + * GSI override for ES7000 platforms. + */ + +static unsigned int base; + +static int +es7000_rename_gsi(int ioapic, int gsi) +{ + if (es7000_plat == ES7000_ZORRO) + return gsi; + + if (!base) { + int i; + for (i = 0; i < nr_ioapics; i++) + base += nr_ioapic_registers[i]; + } + + if (!ioapic && (gsi < 16)) + gsi += base; + + return gsi; +} + +static int wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip) +{ + unsigned long vect = 0, psaival = 0; + + if (psai == NULL) + return -1; + + vect = ((unsigned long)__pa(eip)/0x1000) << 16; + psaival = (0x1000000 | vect | cpu); + + while (*psai & 0x1000000) + ; + + *psai = psaival; + + return 0; +} + +static int __init es7000_update_apic(void) +{ + apic->wakeup_cpu = wakeup_secondary_cpu_via_mip; + + /* MPENTIUMIII */ + if (boot_cpu_data.x86 == 6 && + (boot_cpu_data.x86_model >= 7 || boot_cpu_data.x86_model <= 11)) { + es7000_update_apic_to_cluster(); + apic->wait_for_init_deassert = NULL; + apic->wakeup_cpu = wakeup_secondary_cpu_via_mip; + } + + return 0; +} + +static void __init setup_unisys(void) +{ + /* + * Determine the generation of the ES7000 currently running. + * + * es7000_plat = 1 if the machine is a 5xx ES7000 box + * es7000_plat = 2 if the machine is a x86_64 ES7000 box + * + */ + if (!(boot_cpu_data.x86 <= 15 && boot_cpu_data.x86_model <= 2)) + es7000_plat = ES7000_ZORRO; + else + es7000_plat = ES7000_CLASSIC; + ioapic_renumber_irq = es7000_rename_gsi; + + x86_quirks->update_apic = es7000_update_apic; +} + +/* + * Parse the OEM Table: + */ +static int __init parse_unisys_oem(char *oemptr) +{ + int i; + int success = 0; + unsigned char type, size; + unsigned long val; + char *tp = NULL; + struct psai *psaip = NULL; + struct mip_reg_info *mi; + struct mip_reg *host, *mip; + + tp = oemptr; + + tp += 8; + + for (i = 0; i <= 6; i++) { + type = *tp++; + size = *tp++; + tp -= 2; + switch (type) { + case MIP_REG: + mi = (struct mip_reg_info *)tp; + val = MIP_RD_LO(mi->host_reg); + host_addr = val; + host = (struct mip_reg *)val; + host_reg = __va(host); + val = MIP_RD_LO(mi->mip_reg); + mip_port = MIP_PORT(mi->mip_info); + mip_addr = val; + mip = (struct mip_reg *)val; + mip_reg = __va(mip); + pr_debug("es7000_mipcfg: host_reg = 0x%lx \n", + (unsigned long)host_reg); + pr_debug("es7000_mipcfg: mip_reg = 0x%lx \n", + (unsigned long)mip_reg); + success++; + break; + case MIP_PSAI_REG: + psaip = (struct psai *)tp; + if (tp != NULL) { + if (psaip->addr) + psai = __va(psaip->addr); + else + psai = NULL; + success++; + } + break; + default: + break; + } + tp += size; + } + + if (success < 2) + es7000_plat = NON_UNISYS; + else + setup_unisys(); + + return es7000_plat; +} + +#ifdef CONFIG_ACPI +static int __init find_unisys_acpi_oem_table(unsigned long *oem_addr) +{ + struct acpi_table_header *header = NULL; + struct es7000_oem_table *table; + acpi_size tbl_size; + acpi_status ret; + int i = 0; + + for (;;) { + ret = acpi_get_table_with_size("OEM1", i++, &header, &tbl_size); + if (!ACPI_SUCCESS(ret)) + return -1; + + if (!memcmp((char *) &header->oem_id, "UNISYS", 6)) + break; + + early_acpi_os_unmap_memory(header, tbl_size); + } + + table = (void *)header; + + oem_addrX = table->OEMTableAddr; + oem_size = table->OEMTableSize; + + early_acpi_os_unmap_memory(header, tbl_size); + + *oem_addr = (unsigned long)__acpi_map_table(oem_addrX, oem_size); + + return 0; +} + +static void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr) +{ + if (!oem_addr) + return; + + __acpi_unmap_table((char *)oem_addr, oem_size); +} + +static int es7000_check_dsdt(void) +{ + struct acpi_table_header header; + + if (ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_DSDT, 0, &header)) && + !strncmp(header.oem_id, "UNISYS", 6)) + return 1; + return 0; +} + +/* Hook from generic ACPI tables.c */ +static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id) +{ + unsigned long oem_addr = 0; + int check_dsdt; + int ret = 0; + + /* check dsdt at first to avoid clear fix_map for oem_addr */ + check_dsdt = es7000_check_dsdt(); + + if (!find_unisys_acpi_oem_table(&oem_addr)) { + if (check_dsdt) { + ret = parse_unisys_oem((char *)oem_addr); + } else { + setup_unisys(); + ret = 1; + } + /* + * we need to unmap it + */ + unmap_unisys_acpi_oem_table(oem_addr); + } + return ret; +} +#else /* !CONFIG_ACPI: */ +static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id) +{ + return 0; +} +#endif /* !CONFIG_ACPI */ + +static void es7000_spin(int n) +{ + int i = 0; + + while (i++ < n) + rep_nop(); +} + +static int __init +es7000_mip_write(struct mip_reg *mip_reg) +{ + int status = 0; + int spin; + + spin = MIP_SPIN; + while ((host_reg->off_0x38 & MIP_VALID) != 0) { + if (--spin <= 0) { + WARN(1, "Timeout waiting for Host Valid Flag\n"); + return -1; + } + es7000_spin(MIP_SPIN); + } + + memcpy(host_reg, mip_reg, sizeof(struct mip_reg)); + outb(1, mip_port); + + spin = MIP_SPIN; + + while ((mip_reg->off_0x38 & MIP_VALID) == 0) { + if (--spin <= 0) { + WARN(1, "Timeout waiting for MIP Valid Flag\n"); + return -1; + } + es7000_spin(MIP_SPIN); + } + + status = (mip_reg->off_0x00 & 0xffff0000000000ULL) >> 48; + mip_reg->off_0x38 &= ~MIP_VALID; + + return status; +} + +static void __init es7000_enable_apic_mode(void) +{ + struct mip_reg es7000_mip_reg; + int mip_status; + + if (!es7000_plat) + return; + + printk(KERN_INFO "ES7000: Enabling APIC mode.\n"); + memset(&es7000_mip_reg, 0, sizeof(struct mip_reg)); + es7000_mip_reg.off_0x00 = MIP_SW_APIC; + es7000_mip_reg.off_0x38 = MIP_VALID; + + while ((mip_status = es7000_mip_write(&es7000_mip_reg)) != 0) + WARN(1, "Command failed, status = %x\n", mip_status); +} + +static void es7000_vector_allocation_domain(int cpu, cpumask_t *retmask) +{ + /* Careful. Some cpus do not strictly honor the set of cpus + * specified in the interrupt destination when using lowest + * priority interrupt delivery mode. + * + * In particular there was a hyperthreading cpu observed to + * deliver interrupts to the wrong hyperthread when only one + * hyperthread was specified in the interrupt desitination. + */ + *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } }; +} + + +static void es7000_wait_for_init_deassert(atomic_t *deassert) +{ +#ifndef CONFIG_ES7000_CLUSTERED_APIC + while (!atomic_read(deassert)) + cpu_relax(); +#endif + return; +} + +static unsigned int es7000_get_apic_id(unsigned long x) +{ + return (x >> 24) & 0xFF; +} + +static void es7000_send_IPI_mask(const struct cpumask *mask, int vector) +{ + default_send_IPI_mask_sequence_phys(mask, vector); +} + +static void es7000_send_IPI_allbutself(int vector) +{ + default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector); +} + +static void es7000_send_IPI_all(int vector) +{ + es7000_send_IPI_mask(cpu_online_mask, vector); +} + +static int es7000_apic_id_registered(void) +{ + return 1; +} + +static const cpumask_t *target_cpus_cluster(void) +{ + return &CPU_MASK_ALL; +} + +static const cpumask_t *es7000_target_cpus(void) +{ + return &cpumask_of_cpu(smp_processor_id()); +} + +static unsigned long +es7000_check_apicid_used(physid_mask_t bitmap, int apicid) +{ + return 0; +} +static unsigned long es7000_check_apicid_present(int bit) +{ + return physid_isset(bit, phys_cpu_present_map); +} + +static unsigned long calculate_ldr(int cpu) +{ + unsigned long id = per_cpu(x86_bios_cpu_apicid, cpu); + + return SET_APIC_LOGICAL_ID(id); +} + +/* + * Set up the logical destination ID. + * + * Intel recommends to set DFR, LdR and TPR before enabling + * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel + * document number 292116). So here it goes... + */ +static void es7000_init_apic_ldr_cluster(void) +{ + unsigned long val; + int cpu = smp_processor_id(); + + apic_write(APIC_DFR, APIC_DFR_CLUSTER); + val = calculate_ldr(cpu); + apic_write(APIC_LDR, val); +} + +static void es7000_init_apic_ldr(void) +{ + unsigned long val; + int cpu = smp_processor_id(); + + apic_write(APIC_DFR, APIC_DFR_FLAT); + val = calculate_ldr(cpu); + apic_write(APIC_LDR, val); +} + +static void es7000_setup_apic_routing(void) +{ + int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id()); + + printk(KERN_INFO + "Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n", + (apic_version[apic] == 0x14) ? + "Physical Cluster" : "Logical Cluster", + nr_ioapics, cpus_addr(*es7000_target_cpus())[0]); +} + +static int es7000_apicid_to_node(int logical_apicid) +{ + return 0; +} + + +static int es7000_cpu_present_to_apicid(int mps_cpu) +{ + if (!mps_cpu) + return boot_cpu_physical_apicid; + else if (mps_cpu < nr_cpu_ids) + return per_cpu(x86_bios_cpu_apicid, mps_cpu); + else + return BAD_APICID; +} + +static int cpu_id; + +static physid_mask_t es7000_apicid_to_cpu_present(int phys_apicid) +{ + physid_mask_t mask; + + mask = physid_mask_of_physid(cpu_id); + ++cpu_id; + + return mask; +} + +/* Mapping from cpu number to logical apicid */ +static int es7000_cpu_to_logical_apicid(int cpu) +{ +#ifdef CONFIG_SMP + if (cpu >= nr_cpu_ids) + return BAD_APICID; + return cpu_2_logical_apicid[cpu]; +#else + return logical_smp_processor_id(); +#endif +} + +static physid_mask_t es7000_ioapic_phys_id_map(physid_mask_t phys_map) +{ + /* For clustered we don't have a good way to do this yet - hack */ + return physids_promote(0xff); +} + +static int es7000_check_phys_apicid_present(int cpu_physical_apicid) +{ + boot_cpu_physical_apicid = read_apic_id(); + return 1; +} + +static unsigned int +es7000_cpu_mask_to_apicid_cluster(const struct cpumask *cpumask) +{ + int cpus_found = 0; + int num_bits_set; + int apicid; + int cpu; + + num_bits_set = cpumask_weight(cpumask); + /* Return id to all */ + if (num_bits_set == nr_cpu_ids) + return 0xFF; + /* + * The cpus in the mask must all be on the apic cluster. If are not + * on the same apicid cluster return default value of target_cpus(): + */ + cpu = cpumask_first(cpumask); + apicid = es7000_cpu_to_logical_apicid(cpu); + + while (cpus_found < num_bits_set) { + if (cpumask_test_cpu(cpu, cpumask)) { + int new_apicid = es7000_cpu_to_logical_apicid(cpu); + + if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { + WARN(1, "Not a valid mask!"); + + return 0xFF; + } + apicid = new_apicid; + cpus_found++; + } + cpu++; + } + return apicid; +} + +static unsigned int es7000_cpu_mask_to_apicid(const cpumask_t *cpumask) +{ + int cpus_found = 0; + int num_bits_set; + int apicid; + int cpu; + + num_bits_set = cpus_weight(*cpumask); + /* Return id to all */ + if (num_bits_set == nr_cpu_ids) + return es7000_cpu_to_logical_apicid(0); + /* + * The cpus in the mask must all be on the apic cluster. If are not + * on the same apicid cluster return default value of target_cpus(): + */ + cpu = first_cpu(*cpumask); + apicid = es7000_cpu_to_logical_apicid(cpu); + while (cpus_found < num_bits_set) { + if (cpu_isset(cpu, *cpumask)) { + int new_apicid = es7000_cpu_to_logical_apicid(cpu); + + if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { + printk("%s: Not a valid mask!\n", __func__); + + return es7000_cpu_to_logical_apicid(0); + } + apicid = new_apicid; + cpus_found++; + } + cpu++; + } + return apicid; +} + +static unsigned int +es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask, + const struct cpumask *andmask) +{ + int apicid = es7000_cpu_to_logical_apicid(0); + cpumask_var_t cpumask; + + if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC)) + return apicid; + + cpumask_and(cpumask, inmask, andmask); + cpumask_and(cpumask, cpumask, cpu_online_mask); + apicid = es7000_cpu_mask_to_apicid(cpumask); + + free_cpumask_var(cpumask); + + return apicid; +} + +static int es7000_phys_pkg_id(int cpuid_apic, int index_msb) +{ + return cpuid_apic >> index_msb; +} + +void __init es7000_update_apic_to_cluster(void) +{ + apic->target_cpus = target_cpus_cluster; + apic->irq_delivery_mode = dest_LowestPrio; + /* logical delivery broadcast to all procs: */ + apic->irq_dest_mode = 1; + + apic->init_apic_ldr = es7000_init_apic_ldr_cluster; + + apic->cpu_mask_to_apicid = es7000_cpu_mask_to_apicid_cluster; +} + +static int probe_es7000(void) +{ + /* probed later in mptable/ACPI hooks */ + return 0; +} + +static __init int +es7000_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) +{ + if (mpc->oemptr) { + struct mpc_oemtable *oem_table = + (struct mpc_oemtable *)mpc->oemptr; + + if (!strncmp(oem, "UNISYS", 6)) + return parse_unisys_oem((char *)oem_table); + } + return 0; +} + + +struct apic apic_es7000 = { + + .name = "es7000", + .probe = probe_es7000, + .acpi_madt_oem_check = es7000_acpi_madt_oem_check, + .apic_id_registered = es7000_apic_id_registered, + + .irq_delivery_mode = dest_Fixed, + /* phys delivery to target CPUs: */ + .irq_dest_mode = 0, + + .target_cpus = es7000_target_cpus, + .disable_esr = 1, + .dest_logical = 0, + .check_apicid_used = es7000_check_apicid_used, + .check_apicid_present = es7000_check_apicid_present, + + .vector_allocation_domain = es7000_vector_allocation_domain, + .init_apic_ldr = es7000_init_apic_ldr, + + .ioapic_phys_id_map = es7000_ioapic_phys_id_map, + .setup_apic_routing = es7000_setup_apic_routing, + .multi_timer_check = NULL, + .apicid_to_node = es7000_apicid_to_node, + .cpu_to_logical_apicid = es7000_cpu_to_logical_apicid, + .cpu_present_to_apicid = es7000_cpu_present_to_apicid, + .apicid_to_cpu_present = es7000_apicid_to_cpu_present, + .setup_portio_remap = NULL, + .check_phys_apicid_present = es7000_check_phys_apicid_present, + .enable_apic_mode = es7000_enable_apic_mode, + .phys_pkg_id = es7000_phys_pkg_id, + .mps_oem_check = es7000_mps_oem_check, + + .get_apic_id = es7000_get_apic_id, + .set_apic_id = NULL, + .apic_id_mask = 0xFF << 24, + + .cpu_mask_to_apicid = es7000_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = es7000_cpu_mask_to_apicid_and, + + .send_IPI_mask = es7000_send_IPI_mask, + .send_IPI_mask_allbutself = NULL, + .send_IPI_allbutself = es7000_send_IPI_allbutself, + .send_IPI_all = es7000_send_IPI_all, + .send_IPI_self = default_send_IPI_self, + + .wakeup_cpu = NULL, + + .trampoline_phys_low = 0x467, + .trampoline_phys_high = 0x469, + + .wait_for_init_deassert = es7000_wait_for_init_deassert, + + /* Nothing to do for most platforms, since cleared by the INIT cycle: */ + .smp_callin_clear_local_apic = NULL, + .inquire_remote_apic = default_inquire_remote_apic, + + .read = native_apic_mem_read, + .write = native_apic_mem_write, + .icr_read = native_apic_icr_read, + .icr_write = native_apic_icr_write, + .wait_icr_idle = native_apic_wait_icr_idle, + .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, +}; diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c new file mode 100644 index 00000000000..d9d6d61eed8 --- /dev/null +++ b/arch/x86/kernel/apic/numaq_32.c @@ -0,0 +1,565 @@ +/* + * Written by: Patricia Gaughen, IBM Corporation + * + * Copyright (C) 2002, IBM Corp. + * Copyright (C) 2009, Red Hat, Inc., Ingo Molnar + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Send feedback to + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MB_TO_PAGES(addr) ((addr) << (20 - PAGE_SHIFT)) + +int found_numaq; + +/* + * Have to match translation table entries to main table entries by counter + * hence the mpc_record variable .... can't see a less disgusting way of + * doing this .... + */ +struct mpc_trans { + unsigned char mpc_type; + unsigned char trans_len; + unsigned char trans_type; + unsigned char trans_quad; + unsigned char trans_global; + unsigned char trans_local; + unsigned short trans_reserved; +}; + +/* x86_quirks member */ +static int mpc_record; + +static __cpuinitdata struct mpc_trans *translation_table[MAX_MPC_ENTRY]; + +int mp_bus_id_to_node[MAX_MP_BUSSES]; +int mp_bus_id_to_local[MAX_MP_BUSSES]; +int quad_local_to_mp_bus_id[NR_CPUS/4][4]; + + +static inline void numaq_register_node(int node, struct sys_cfg_data *scd) +{ + struct eachquadmem *eq = scd->eq + node; + + node_set_online(node); + + /* Convert to pages */ + node_start_pfn[node] = + MB_TO_PAGES(eq->hi_shrd_mem_start - eq->priv_mem_size); + + node_end_pfn[node] = + MB_TO_PAGES(eq->hi_shrd_mem_start + eq->hi_shrd_mem_size); + + e820_register_active_regions(node, node_start_pfn[node], + node_end_pfn[node]); + + memory_present(node, node_start_pfn[node], node_end_pfn[node]); + + node_remap_size[node] = node_memmap_size_bytes(node, + node_start_pfn[node], + node_end_pfn[node]); +} + +/* + * Function: smp_dump_qct() + * + * Description: gets memory layout from the quad config table. This + * function also updates node_online_map with the nodes (quads) present. + */ +static void __init smp_dump_qct(void) +{ + struct sys_cfg_data *scd; + int node; + + scd = (void *)__va(SYS_CFG_DATA_PRIV_ADDR); + + nodes_clear(node_online_map); + for_each_node(node) { + if (scd->quads_present31_0 & (1 << node)) + numaq_register_node(node, scd); + } +} + +void __cpuinit numaq_tsc_disable(void) +{ + if (!found_numaq) + return; + + if (num_online_nodes() > 1) { + printk(KERN_DEBUG "NUMAQ: disabling TSC\n"); + setup_clear_cpu_cap(X86_FEATURE_TSC); + } +} + +static int __init numaq_pre_time_init(void) +{ + numaq_tsc_disable(); + return 0; +} + +static inline int generate_logical_apicid(int quad, int phys_apicid) +{ + return (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1); +} + +/* x86_quirks member */ +static int mpc_apic_id(struct mpc_cpu *m) +{ + int quad = translation_table[mpc_record]->trans_quad; + int logical_apicid = generate_logical_apicid(quad, m->apicid); + + printk(KERN_DEBUG + "Processor #%d %u:%u APIC version %d (quad %d, apic %d)\n", + m->apicid, (m->cpufeature & CPU_FAMILY_MASK) >> 8, + (m->cpufeature & CPU_MODEL_MASK) >> 4, + m->apicver, quad, logical_apicid); + + return logical_apicid; +} + +/* x86_quirks member */ +static void mpc_oem_bus_info(struct mpc_bus *m, char *name) +{ + int quad = translation_table[mpc_record]->trans_quad; + int local = translation_table[mpc_record]->trans_local; + + mp_bus_id_to_node[m->busid] = quad; + mp_bus_id_to_local[m->busid] = local; + + printk(KERN_INFO "Bus #%d is %s (node %d)\n", m->busid, name, quad); +} + +/* x86_quirks member */ +static void mpc_oem_pci_bus(struct mpc_bus *m) +{ + int quad = translation_table[mpc_record]->trans_quad; + int local = translation_table[mpc_record]->trans_local; + + quad_local_to_mp_bus_id[quad][local] = m->busid; +} + +static void __init MP_translation_info(struct mpc_trans *m) +{ + printk(KERN_INFO + "Translation: record %d, type %d, quad %d, global %d, local %d\n", + mpc_record, m->trans_type, m->trans_quad, m->trans_global, + m->trans_local); + + if (mpc_record >= MAX_MPC_ENTRY) + printk(KERN_ERR "MAX_MPC_ENTRY exceeded!\n"); + else + translation_table[mpc_record] = m; /* stash this for later */ + + if (m->trans_quad < MAX_NUMNODES && !node_online(m->trans_quad)) + node_set_online(m->trans_quad); +} + +static int __init mpf_checksum(unsigned char *mp, int len) +{ + int sum = 0; + + while (len--) + sum += *mp++; + + return sum & 0xFF; +} + +/* + * Read/parse the MPC oem tables + */ +static void __init + smp_read_mpc_oem(struct mpc_oemtable *oemtable, unsigned short oemsize) +{ + int count = sizeof(*oemtable); /* the header size */ + unsigned char *oemptr = ((unsigned char *)oemtable) + count; + + mpc_record = 0; + printk(KERN_INFO + "Found an OEM MPC table at %8p - parsing it ... \n", oemtable); + + if (memcmp(oemtable->signature, MPC_OEM_SIGNATURE, 4)) { + printk(KERN_WARNING + "SMP mpc oemtable: bad signature [%c%c%c%c]!\n", + oemtable->signature[0], oemtable->signature[1], + oemtable->signature[2], oemtable->signature[3]); + return; + } + + if (mpf_checksum((unsigned char *)oemtable, oemtable->length)) { + printk(KERN_WARNING "SMP oem mptable: checksum error!\n"); + return; + } + + while (count < oemtable->length) { + switch (*oemptr) { + case MP_TRANSLATION: + { + struct mpc_trans *m = (void *)oemptr; + + MP_translation_info(m); + oemptr += sizeof(*m); + count += sizeof(*m); + ++mpc_record; + break; + } + default: + printk(KERN_WARNING + "Unrecognised OEM table entry type! - %d\n", + (int)*oemptr); + return; + } + } +} + +static int __init numaq_setup_ioapic_ids(void) +{ + /* so can skip it */ + return 1; +} + +static int __init numaq_update_apic(void) +{ + apic->wakeup_cpu = wakeup_secondary_cpu_via_nmi; + + return 0; +} + +static struct x86_quirks numaq_x86_quirks __initdata = { + .arch_pre_time_init = numaq_pre_time_init, + .arch_time_init = NULL, + .arch_pre_intr_init = NULL, + .arch_memory_setup = NULL, + .arch_intr_init = NULL, + .arch_trap_init = NULL, + .mach_get_smp_config = NULL, + .mach_find_smp_config = NULL, + .mpc_record = &mpc_record, + .mpc_apic_id = mpc_apic_id, + .mpc_oem_bus_info = mpc_oem_bus_info, + .mpc_oem_pci_bus = mpc_oem_pci_bus, + .smp_read_mpc_oem = smp_read_mpc_oem, + .setup_ioapic_ids = numaq_setup_ioapic_ids, + .update_apic = numaq_update_apic, +}; + +static __init void early_check_numaq(void) +{ + /* + * Find possible boot-time SMP configuration: + */ + early_find_smp_config(); + + /* + * get boot-time SMP configuration: + */ + if (smp_found_config) + early_get_smp_config(); + + if (found_numaq) + x86_quirks = &numaq_x86_quirks; +} + +int __init get_memcfg_numaq(void) +{ + early_check_numaq(); + if (!found_numaq) + return 0; + smp_dump_qct(); + + return 1; +} + +#define NUMAQ_APIC_DFR_VALUE (APIC_DFR_CLUSTER) + +static inline unsigned int numaq_get_apic_id(unsigned long x) +{ + return (x >> 24) & 0x0F; +} + +static inline void numaq_send_IPI_mask(const struct cpumask *mask, int vector) +{ + default_send_IPI_mask_sequence_logical(mask, vector); +} + +static inline void numaq_send_IPI_allbutself(int vector) +{ + default_send_IPI_mask_allbutself_logical(cpu_online_mask, vector); +} + +static inline void numaq_send_IPI_all(int vector) +{ + numaq_send_IPI_mask(cpu_online_mask, vector); +} + +#define NUMAQ_TRAMPOLINE_PHYS_LOW (0x8) +#define NUMAQ_TRAMPOLINE_PHYS_HIGH (0xa) + +/* + * Because we use NMIs rather than the INIT-STARTUP sequence to + * bootstrap the CPUs, the APIC may be in a weird state. Kick it: + */ +static inline void numaq_smp_callin_clear_local_apic(void) +{ + clear_local_APIC(); +} + +static inline const cpumask_t *numaq_target_cpus(void) +{ + return &CPU_MASK_ALL; +} + +static inline unsigned long +numaq_check_apicid_used(physid_mask_t bitmap, int apicid) +{ + return physid_isset(apicid, bitmap); +} + +static inline unsigned long numaq_check_apicid_present(int bit) +{ + return physid_isset(bit, phys_cpu_present_map); +} + +static inline int numaq_apic_id_registered(void) +{ + return 1; +} + +static inline void numaq_init_apic_ldr(void) +{ + /* Already done in NUMA-Q firmware */ +} + +static inline void numaq_setup_apic_routing(void) +{ + printk(KERN_INFO + "Enabling APIC mode: NUMA-Q. Using %d I/O APICs\n", + nr_ioapics); +} + +/* + * Skip adding the timer int on secondary nodes, which causes + * a small but painful rift in the time-space continuum. + */ +static inline int numaq_multi_timer_check(int apic, int irq) +{ + return apic != 0 && irq == 0; +} + +static inline physid_mask_t numaq_ioapic_phys_id_map(physid_mask_t phys_map) +{ + /* We don't have a good way to do this yet - hack */ + return physids_promote(0xFUL); +} + +static inline int numaq_cpu_to_logical_apicid(int cpu) +{ + if (cpu >= nr_cpu_ids) + return BAD_APICID; + return cpu_2_logical_apicid[cpu]; +} + +/* + * Supporting over 60 cpus on NUMA-Q requires a locality-dependent + * cpu to APIC ID relation to properly interact with the intelligent + * mode of the cluster controller. + */ +static inline int numaq_cpu_present_to_apicid(int mps_cpu) +{ + if (mps_cpu < 60) + return ((mps_cpu >> 2) << 4) | (1 << (mps_cpu & 0x3)); + else + return BAD_APICID; +} + +static inline int numaq_apicid_to_node(int logical_apicid) +{ + return logical_apicid >> 4; +} + +static inline physid_mask_t numaq_apicid_to_cpu_present(int logical_apicid) +{ + int node = numaq_apicid_to_node(logical_apicid); + int cpu = __ffs(logical_apicid & 0xf); + + return physid_mask_of_physid(cpu + 4*node); +} + +/* Where the IO area was mapped on multiquad, always 0 otherwise */ +void *xquad_portio; + +static inline int numaq_check_phys_apicid_present(int boot_cpu_physical_apicid) +{ + return 1; +} + +/* + * We use physical apicids here, not logical, so just return the default + * physical broadcast to stop people from breaking us + */ +static inline unsigned int numaq_cpu_mask_to_apicid(const cpumask_t *cpumask) +{ + return 0x0F; +} + +static inline unsigned int +numaq_cpu_mask_to_apicid_and(const struct cpumask *cpumask, + const struct cpumask *andmask) +{ + return 0x0F; +} + +/* No NUMA-Q box has a HT CPU, but it can't hurt to use the default code. */ +static inline int numaq_phys_pkg_id(int cpuid_apic, int index_msb) +{ + return cpuid_apic >> index_msb; +} + +static int +numaq_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) +{ + if (strncmp(oem, "IBM NUMA", 8)) + printk(KERN_ERR "Warning! Not a NUMA-Q system!\n"); + else + found_numaq = 1; + + return found_numaq; +} + +static int probe_numaq(void) +{ + /* already know from get_memcfg_numaq() */ + return found_numaq; +} + +static void numaq_vector_allocation_domain(int cpu, cpumask_t *retmask) +{ + /* Careful. Some cpus do not strictly honor the set of cpus + * specified in the interrupt destination when using lowest + * priority interrupt delivery mode. + * + * In particular there was a hyperthreading cpu observed to + * deliver interrupts to the wrong hyperthread when only one + * hyperthread was specified in the interrupt desitination. + */ + *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } }; +} + +static void numaq_setup_portio_remap(void) +{ + int num_quads = num_online_nodes(); + + if (num_quads <= 1) + return; + + printk(KERN_INFO + "Remapping cross-quad port I/O for %d quads\n", num_quads); + + xquad_portio = ioremap(XQUAD_PORTIO_BASE, num_quads*XQUAD_PORTIO_QUAD); + + printk(KERN_INFO + "xquad_portio vaddr 0x%08lx, len %08lx\n", + (u_long) xquad_portio, (u_long) num_quads*XQUAD_PORTIO_QUAD); +} + +struct apic apic_numaq = { + + .name = "NUMAQ", + .probe = probe_numaq, + .acpi_madt_oem_check = NULL, + .apic_id_registered = numaq_apic_id_registered, + + .irq_delivery_mode = dest_LowestPrio, + /* physical delivery on LOCAL quad: */ + .irq_dest_mode = 0, + + .target_cpus = numaq_target_cpus, + .disable_esr = 1, + .dest_logical = APIC_DEST_LOGICAL, + .check_apicid_used = numaq_check_apicid_used, + .check_apicid_present = numaq_check_apicid_present, + + .vector_allocation_domain = numaq_vector_allocation_domain, + .init_apic_ldr = numaq_init_apic_ldr, + + .ioapic_phys_id_map = numaq_ioapic_phys_id_map, + .setup_apic_routing = numaq_setup_apic_routing, + .multi_timer_check = numaq_multi_timer_check, + .apicid_to_node = numaq_apicid_to_node, + .cpu_to_logical_apicid = numaq_cpu_to_logical_apicid, + .cpu_present_to_apicid = numaq_cpu_present_to_apicid, + .apicid_to_cpu_present = numaq_apicid_to_cpu_present, + .setup_portio_remap = numaq_setup_portio_remap, + .check_phys_apicid_present = numaq_check_phys_apicid_present, + .enable_apic_mode = NULL, + .phys_pkg_id = numaq_phys_pkg_id, + .mps_oem_check = numaq_mps_oem_check, + + .get_apic_id = numaq_get_apic_id, + .set_apic_id = NULL, + .apic_id_mask = 0x0F << 24, + + .cpu_mask_to_apicid = numaq_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = numaq_cpu_mask_to_apicid_and, + + .send_IPI_mask = numaq_send_IPI_mask, + .send_IPI_mask_allbutself = NULL, + .send_IPI_allbutself = numaq_send_IPI_allbutself, + .send_IPI_all = numaq_send_IPI_all, + .send_IPI_self = default_send_IPI_self, + + .wakeup_cpu = NULL, + .trampoline_phys_low = NUMAQ_TRAMPOLINE_PHYS_LOW, + .trampoline_phys_high = NUMAQ_TRAMPOLINE_PHYS_HIGH, + + /* We don't do anything here because we use NMI's to boot instead */ + .wait_for_init_deassert = NULL, + + .smp_callin_clear_local_apic = numaq_smp_callin_clear_local_apic, + .inquire_remote_apic = NULL, + + .read = native_apic_mem_read, + .write = native_apic_mem_write, + .icr_read = native_apic_icr_read, + .icr_write = native_apic_icr_write, + .wait_icr_idle = native_apic_wait_icr_idle, + .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, +}; diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c new file mode 100644 index 00000000000..5fa48332c5c --- /dev/null +++ b/arch/x86/kernel/apic/probe_32.c @@ -0,0 +1,424 @@ +/* + * Default generic APIC driver. This handles up to 8 CPUs. + * + * Copyright 2003 Andi Kleen, SuSE Labs. + * Subject to the GNU Public License, v.2 + * + * Generic x86 APIC driver probe layer. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_HOTPLUG_CPU +#define DEFAULT_SEND_IPI (1) +#else +#define DEFAULT_SEND_IPI (0) +#endif + +int no_broadcast = DEFAULT_SEND_IPI; + +#ifdef CONFIG_X86_LOCAL_APIC + +void default_setup_apic_routing(void) +{ +#ifdef CONFIG_X86_IO_APIC + printk(KERN_INFO + "Enabling APIC mode: Flat. Using %d I/O APICs\n", + nr_ioapics); +#endif +} + +static void default_vector_allocation_domain(int cpu, struct cpumask *retmask) +{ + /* + * Careful. Some cpus do not strictly honor the set of cpus + * specified in the interrupt destination when using lowest + * priority interrupt delivery mode. + * + * In particular there was a hyperthreading cpu observed to + * deliver interrupts to the wrong hyperthread when only one + * hyperthread was specified in the interrupt desitination. + */ + *retmask = (cpumask_t) { { [0] = APIC_ALL_CPUS } }; +} + +/* should be called last. */ +static int probe_default(void) +{ + return 1; +} + +struct apic apic_default = { + + .name = "default", + .probe = probe_default, + .acpi_madt_oem_check = NULL, + .apic_id_registered = default_apic_id_registered, + + .irq_delivery_mode = dest_LowestPrio, + /* logical delivery broadcast to all CPUs: */ + .irq_dest_mode = 1, + + .target_cpus = default_target_cpus, + .disable_esr = 0, + .dest_logical = APIC_DEST_LOGICAL, + .check_apicid_used = default_check_apicid_used, + .check_apicid_present = default_check_apicid_present, + + .vector_allocation_domain = default_vector_allocation_domain, + .init_apic_ldr = default_init_apic_ldr, + + .ioapic_phys_id_map = default_ioapic_phys_id_map, + .setup_apic_routing = default_setup_apic_routing, + .multi_timer_check = NULL, + .apicid_to_node = default_apicid_to_node, + .cpu_to_logical_apicid = default_cpu_to_logical_apicid, + .cpu_present_to_apicid = default_cpu_present_to_apicid, + .apicid_to_cpu_present = default_apicid_to_cpu_present, + .setup_portio_remap = NULL, + .check_phys_apicid_present = default_check_phys_apicid_present, + .enable_apic_mode = NULL, + .phys_pkg_id = default_phys_pkg_id, + .mps_oem_check = NULL, + + .get_apic_id = default_get_apic_id, + .set_apic_id = NULL, + .apic_id_mask = 0x0F << 24, + + .cpu_mask_to_apicid = default_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, + + .send_IPI_mask = default_send_IPI_mask_logical, + .send_IPI_mask_allbutself = default_send_IPI_mask_allbutself_logical, + .send_IPI_allbutself = default_send_IPI_allbutself, + .send_IPI_all = default_send_IPI_all, + .send_IPI_self = default_send_IPI_self, + + .wakeup_cpu = NULL, + .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, + .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, + + .wait_for_init_deassert = default_wait_for_init_deassert, + + .smp_callin_clear_local_apic = NULL, + .inquire_remote_apic = default_inquire_remote_apic, + + .read = native_apic_mem_read, + .write = native_apic_mem_write, + .icr_read = native_apic_icr_read, + .icr_write = native_apic_icr_write, + .wait_icr_idle = native_apic_wait_icr_idle, + .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, +}; + +extern struct apic apic_numaq; +extern struct apic apic_summit; +extern struct apic apic_bigsmp; +extern struct apic apic_es7000; +extern struct apic apic_default; + +struct apic *apic = &apic_default; +EXPORT_SYMBOL_GPL(apic); + +static struct apic *apic_probe[] __initdata = { +#ifdef CONFIG_X86_NUMAQ + &apic_numaq, +#endif +#ifdef CONFIG_X86_SUMMIT + &apic_summit, +#endif +#ifdef CONFIG_X86_BIGSMP + &apic_bigsmp, +#endif +#ifdef CONFIG_X86_ES7000 + &apic_es7000, +#endif + &apic_default, /* must be last */ + NULL, +}; + +static int cmdline_apic __initdata; +static int __init parse_apic(char *arg) +{ + int i; + + if (!arg) + return -EINVAL; + + for (i = 0; apic_probe[i]; i++) { + if (!strcmp(apic_probe[i]->name, arg)) { + apic = apic_probe[i]; + cmdline_apic = 1; + return 0; + } + } + + if (x86_quirks->update_apic) + x86_quirks->update_apic(); + + /* Parsed again by __setup for debug/verbose */ + return 0; +} +early_param("apic", parse_apic); + +void __init generic_bigsmp_probe(void) +{ +#ifdef CONFIG_X86_BIGSMP + /* + * This routine is used to switch to bigsmp mode when + * - There is no apic= option specified by the user + * - generic_apic_probe() has chosen apic_default as the sub_arch + * - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support + */ + + if (!cmdline_apic && apic == &apic_default) { + if (apic_bigsmp.probe()) { + apic = &apic_bigsmp; + if (x86_quirks->update_apic) + x86_quirks->update_apic(); + printk(KERN_INFO "Overriding APIC driver with %s\n", + apic->name); + } + } +#endif +} + +void __init generic_apic_probe(void) +{ + if (!cmdline_apic) { + int i; + for (i = 0; apic_probe[i]; i++) { + if (apic_probe[i]->probe()) { + apic = apic_probe[i]; + break; + } + } + /* Not visible without early console */ + if (!apic_probe[i]) + panic("Didn't find an APIC driver"); + + if (x86_quirks->update_apic) + x86_quirks->update_apic(); + } + printk(KERN_INFO "Using APIC driver %s\n", apic->name); +} + +/* These functions can switch the APIC even after the initial ->probe() */ + +int __init +generic_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) +{ + int i; + + for (i = 0; apic_probe[i]; ++i) { + if (!apic_probe[i]->mps_oem_check) + continue; + if (!apic_probe[i]->mps_oem_check(mpc, oem, productid)) + continue; + + if (!cmdline_apic) { + apic = apic_probe[i]; + if (x86_quirks->update_apic) + x86_quirks->update_apic(); + printk(KERN_INFO "Switched to APIC driver `%s'.\n", + apic->name); + } + return 1; + } + return 0; +} + +int __init default_acpi_madt_oem_check(char *oem_id, char *oem_table_id) +{ + int i; + + for (i = 0; apic_probe[i]; ++i) { + if (!apic_probe[i]->acpi_madt_oem_check) + continue; + if (!apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id)) + continue; + + if (!cmdline_apic) { + apic = apic_probe[i]; + if (x86_quirks->update_apic) + x86_quirks->update_apic(); + printk(KERN_INFO "Switched to APIC driver `%s'.\n", + apic->name); + } + return 1; + } + return 0; +} + +#endif /* CONFIG_X86_LOCAL_APIC */ + +/** + * pre_intr_init_hook - initialisation prior to setting up interrupt vectors + * + * Description: + * Perform any necessary interrupt initialisation prior to setting up + * the "ordinary" interrupt call gates. For legacy reasons, the ISA + * interrupts should be initialised here if the machine emulates a PC + * in any way. + **/ +void __init pre_intr_init_hook(void) +{ + if (x86_quirks->arch_pre_intr_init) { + if (x86_quirks->arch_pre_intr_init()) + return; + } + init_ISA_irqs(); +} + +/** + * intr_init_hook - post gate setup interrupt initialisation + * + * Description: + * Fill in any interrupts that may have been left out by the general + * init_IRQ() routine. interrupts having to do with the machine rather + * than the devices on the I/O bus (like APIC interrupts in intel MP + * systems) are started here. + **/ +void __init intr_init_hook(void) +{ + if (x86_quirks->arch_intr_init) { + if (x86_quirks->arch_intr_init()) + return; + } +} + +/** + * pre_setup_arch_hook - hook called prior to any setup_arch() execution + * + * Description: + * generally used to activate any machine specific identification + * routines that may be needed before setup_arch() runs. On Voyager + * this is used to get the board revision and type. + **/ +void __init pre_setup_arch_hook(void) +{ +} + +/** + * trap_init_hook - initialise system specific traps + * + * Description: + * Called as the final act of trap_init(). Used in VISWS to initialise + * the various board specific APIC traps. + **/ +void __init trap_init_hook(void) +{ + if (x86_quirks->arch_trap_init) { + if (x86_quirks->arch_trap_init()) + return; + } +} + +static struct irqaction irq0 = { + .handler = timer_interrupt, + .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL, + .mask = CPU_MASK_NONE, + .name = "timer" +}; + +/** + * pre_time_init_hook - do any specific initialisations before. + * + **/ +void __init pre_time_init_hook(void) +{ + if (x86_quirks->arch_pre_time_init) + x86_quirks->arch_pre_time_init(); +} + +/** + * time_init_hook - do any specific initialisations for the system timer. + * + * Description: + * Must plug the system timer interrupt source at HZ into the IRQ listed + * in irq_vectors.h:TIMER_IRQ + **/ +void __init time_init_hook(void) +{ + if (x86_quirks->arch_time_init) { + /* + * A nonzero return code does not mean failure, it means + * that the architecture quirk does not want any + * generic (timer) setup to be performed after this: + */ + if (x86_quirks->arch_time_init()) + return; + } + + irq0.mask = cpumask_of_cpu(0); + setup_irq(0, &irq0); +} + +#ifdef CONFIG_MCA +/** + * mca_nmi_hook - hook into MCA specific NMI chain + * + * Description: + * The MCA (Microchannel Architecture) has an NMI chain for NMI sources + * along the MCA bus. Use this to hook into that chain if you will need + * it. + **/ +void mca_nmi_hook(void) +{ + /* + * If I recall correctly, there's a whole bunch of other things that + * we can do to check for NMI problems, but that's all I know about + * at the moment. + */ + pr_warning("NMI generated from unknown source!\n"); +} +#endif + +static __init int no_ipi_broadcast(char *str) +{ + get_option(&str, &no_broadcast); + pr_info("Using %s mode\n", + no_broadcast ? "No IPI Broadcast" : "IPI Broadcast"); + return 1; +} +__setup("no_ipi_broadcast=", no_ipi_broadcast); + +static int __init print_ipi_mode(void) +{ + pr_info("Using IPI %s mode\n", + no_broadcast ? "No-Shortcut" : "Shortcut"); + return 0; +} + +late_initcall(print_ipi_mode); + diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c new file mode 100644 index 00000000000..70935dd904d --- /dev/null +++ b/arch/x86/kernel/apic/probe_64.c @@ -0,0 +1,89 @@ +/* + * Copyright 2004 James Cleverdon, IBM. + * Subject to the GNU Public License, v.2 + * + * Generic APIC sub-arch probe layer. + * + * Hacked for x86-64 by James Cleverdon from i386 architecture code by + * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and + * James Cleverdon. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +extern struct apic apic_flat; +extern struct apic apic_physflat; +extern struct apic apic_x2xpic_uv_x; +extern struct apic apic_x2apic_phys; +extern struct apic apic_x2apic_cluster; + +struct apic __read_mostly *apic = &apic_flat; +EXPORT_SYMBOL_GPL(apic); + +static struct apic *apic_probe[] __initdata = { +#ifdef CONFIG_X86_UV + &apic_x2apic_uv_x, +#endif +#ifdef CONFIG_X86_X2APIC + &apic_x2apic_phys, + &apic_x2apic_cluster, +#endif + &apic_physflat, + NULL, +}; + +/* + * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. + */ +void __init default_setup_apic_routing(void) +{ +#ifdef CONFIG_X86_X2APIC + if (apic == &apic_x2apic_phys || apic == &apic_x2apic_cluster) { + if (!intr_remapping_enabled) + apic = &apic_flat; + } +#endif + + if (apic == &apic_flat) { + if (max_physical_apicid >= 8) + apic = &apic_physflat; + printk(KERN_INFO "Setting APIC routing to %s\n", apic->name); + } + + if (x86_quirks->update_apic) + x86_quirks->update_apic(); +} + +/* Same for both flat and physical. */ + +void apic_send_IPI_self(int vector) +{ + __default_send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL); +} + +int __init default_acpi_madt_oem_check(char *oem_id, char *oem_table_id) +{ + int i; + + for (i = 0; apic_probe[i]; ++i) { + if (apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id)) { + apic = apic_probe[i]; + printk(KERN_INFO "Setting APIC routing to %s.\n", + apic->name); + return 1; + } + } + return 0; +} diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c new file mode 100644 index 00000000000..cfe7b09015d --- /dev/null +++ b/arch/x86/kernel/apic/summit_32.c @@ -0,0 +1,601 @@ +/* + * IBM Summit-Specific Code + * + * Written By: Matthew Dobson, IBM Corporation + * + * Copyright (c) 2003 IBM Corp. + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program 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, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Send feedback to + * + */ + +#include +#include +#include +#include + +/* + * APIC driver for the IBM "Summit" chipset. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static inline unsigned summit_get_apic_id(unsigned long x) +{ + return (x >> 24) & 0xFF; +} + +static inline void summit_send_IPI_mask(const cpumask_t *mask, int vector) +{ + default_send_IPI_mask_sequence_logical(mask, vector); +} + +static inline void summit_send_IPI_allbutself(int vector) +{ + cpumask_t mask = cpu_online_map; + cpu_clear(smp_processor_id(), mask); + + if (!cpus_empty(mask)) + summit_send_IPI_mask(&mask, vector); +} + +static inline void summit_send_IPI_all(int vector) +{ + summit_send_IPI_mask(&cpu_online_map, vector); +} + +#include + +extern int use_cyclone; + +#ifdef CONFIG_X86_SUMMIT_NUMA +extern void setup_summit(void); +#else +#define setup_summit() {} +#endif + +static inline int +summit_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) +{ + if (!strncmp(oem, "IBM ENSW", 8) && + (!strncmp(productid, "VIGIL SMP", 9) + || !strncmp(productid, "EXA", 3) + || !strncmp(productid, "RUTHLESS SMP", 12))){ + mark_tsc_unstable("Summit based system"); + use_cyclone = 1; /*enable cyclone-timer*/ + setup_summit(); + return 1; + } + return 0; +} + +/* Hook from generic ACPI tables.c */ +static inline int summit_acpi_madt_oem_check(char *oem_id, char *oem_table_id) +{ + if (!strncmp(oem_id, "IBM", 3) && + (!strncmp(oem_table_id, "SERVIGIL", 8) + || !strncmp(oem_table_id, "EXA", 3))){ + mark_tsc_unstable("Summit based system"); + use_cyclone = 1; /*enable cyclone-timer*/ + setup_summit(); + return 1; + } + return 0; +} + +struct rio_table_hdr { + unsigned char version; /* Version number of this data structure */ + /* Version 3 adds chassis_num & WP_index */ + unsigned char num_scal_dev; /* # of Scalability devices (Twisters for Vigil) */ + unsigned char num_rio_dev; /* # of RIO I/O devices (Cyclones and Winnipegs) */ +} __attribute__((packed)); + +struct scal_detail { + unsigned char node_id; /* Scalability Node ID */ + unsigned long CBAR; /* Address of 1MB register space */ + unsigned char port0node; /* Node ID port connected to: 0xFF=None */ + unsigned char port0port; /* Port num port connected to: 0,1,2, or 0xFF=None */ + unsigned char port1node; /* Node ID port connected to: 0xFF = None */ + unsigned char port1port; /* Port num port connected to: 0,1,2, or 0xFF=None */ + unsigned char port2node; /* Node ID port connected to: 0xFF = None */ + unsigned char port2port; /* Port num port connected to: 0,1,2, or 0xFF=None */ + unsigned char chassis_num; /* 1 based Chassis number (1 = boot node) */ +} __attribute__((packed)); + +struct rio_detail { + unsigned char node_id; /* RIO Node ID */ + unsigned long BBAR; /* Address of 1MB register space */ + unsigned char type; /* Type of device */ + unsigned char owner_id; /* For WPEG: Node ID of Cyclone that owns this WPEG*/ + /* For CYC: Node ID of Twister that owns this CYC */ + unsigned char port0node; /* Node ID port connected to: 0xFF=None */ + unsigned char port0port; /* Port num port connected to: 0,1,2, or 0xFF=None */ + unsigned char port1node; /* Node ID port connected to: 0xFF=None */ + unsigned char port1port; /* Port num port connected to: 0,1,2, or 0xFF=None */ + unsigned char first_slot; /* For WPEG: Lowest slot number below this WPEG */ + /* For CYC: 0 */ + unsigned char status; /* For WPEG: Bit 0 = 1 : the XAPIC is used */ + /* = 0 : the XAPIC is not used, ie:*/ + /* ints fwded to another XAPIC */ + /* Bits1:7 Reserved */ + /* For CYC: Bits0:7 Reserved */ + unsigned char WP_index; /* For WPEG: WPEG instance index - lower ones have */ + /* lower slot numbers/PCI bus numbers */ + /* For CYC: No meaning */ + unsigned char chassis_num; /* 1 based Chassis number */ + /* For LookOut WPEGs this field indicates the */ + /* Expansion Chassis #, enumerated from Boot */ + /* Node WPEG external port, then Boot Node CYC */ + /* external port, then Next Vigil chassis WPEG */ + /* external port, etc. */ + /* Shared Lookouts have only 1 chassis number (the */ + /* first one assigned) */ +} __attribute__((packed)); + + +typedef enum { + CompatTwister = 0, /* Compatibility Twister */ + AltTwister = 1, /* Alternate Twister of internal 8-way */ + CompatCyclone = 2, /* Compatibility Cyclone */ + AltCyclone = 3, /* Alternate Cyclone of internal 8-way */ + CompatWPEG = 4, /* Compatibility WPEG */ + AltWPEG = 5, /* Second Planar WPEG */ + LookOutAWPEG = 6, /* LookOut WPEG */ + LookOutBWPEG = 7, /* LookOut WPEG */ +} node_type; + +static inline int is_WPEG(struct rio_detail *rio){ + return (rio->type == CompatWPEG || rio->type == AltWPEG || + rio->type == LookOutAWPEG || rio->type == LookOutBWPEG); +} + + +/* In clustered mode, the high nibble of APIC ID is a cluster number. + * The low nibble is a 4-bit bitmap. */ +#define XAPIC_DEST_CPUS_SHIFT 4 +#define XAPIC_DEST_CPUS_MASK ((1u << XAPIC_DEST_CPUS_SHIFT) - 1) +#define XAPIC_DEST_CLUSTER_MASK (XAPIC_DEST_CPUS_MASK << XAPIC_DEST_CPUS_SHIFT) + +#define SUMMIT_APIC_DFR_VALUE (APIC_DFR_CLUSTER) + +static inline const cpumask_t *summit_target_cpus(void) +{ + /* CPU_MASK_ALL (0xff) has undefined behaviour with + * dest_LowestPrio mode logical clustered apic interrupt routing + * Just start on cpu 0. IRQ balancing will spread load + */ + return &cpumask_of_cpu(0); +} + +static inline unsigned long +summit_check_apicid_used(physid_mask_t bitmap, int apicid) +{ + return 0; +} + +/* we don't use the phys_cpu_present_map to indicate apicid presence */ +static inline unsigned long summit_check_apicid_present(int bit) +{ + return 1; +} + +static inline void summit_init_apic_ldr(void) +{ + unsigned long val, id; + int count = 0; + u8 my_id = (u8)hard_smp_processor_id(); + u8 my_cluster = APIC_CLUSTER(my_id); +#ifdef CONFIG_SMP + u8 lid; + int i; + + /* Create logical APIC IDs by counting CPUs already in cluster. */ + for (count = 0, i = nr_cpu_ids; --i >= 0; ) { + lid = cpu_2_logical_apicid[i]; + if (lid != BAD_APICID && APIC_CLUSTER(lid) == my_cluster) + ++count; + } +#endif + /* We only have a 4 wide bitmap in cluster mode. If a deranged + * BIOS puts 5 CPUs in one APIC cluster, we're hosed. */ + BUG_ON(count >= XAPIC_DEST_CPUS_SHIFT); + id = my_cluster | (1UL << count); + apic_write(APIC_DFR, SUMMIT_APIC_DFR_VALUE); + val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; + val |= SET_APIC_LOGICAL_ID(id); + apic_write(APIC_LDR, val); +} + +static inline int summit_apic_id_registered(void) +{ + return 1; +} + +static inline void summit_setup_apic_routing(void) +{ + printk("Enabling APIC mode: Summit. Using %d I/O APICs\n", + nr_ioapics); +} + +static inline int summit_apicid_to_node(int logical_apicid) +{ +#ifdef CONFIG_SMP + return apicid_2_node[hard_smp_processor_id()]; +#else + return 0; +#endif +} + +/* Mapping from cpu number to logical apicid */ +static inline int summit_cpu_to_logical_apicid(int cpu) +{ +#ifdef CONFIG_SMP + if (cpu >= nr_cpu_ids) + return BAD_APICID; + return cpu_2_logical_apicid[cpu]; +#else + return logical_smp_processor_id(); +#endif +} + +static inline int summit_cpu_present_to_apicid(int mps_cpu) +{ + if (mps_cpu < nr_cpu_ids) + return (int)per_cpu(x86_bios_cpu_apicid, mps_cpu); + else + return BAD_APICID; +} + +static inline physid_mask_t +summit_ioapic_phys_id_map(physid_mask_t phys_id_map) +{ + /* For clustered we don't have a good way to do this yet - hack */ + return physids_promote(0x0F); +} + +static inline physid_mask_t summit_apicid_to_cpu_present(int apicid) +{ + return physid_mask_of_physid(0); +} + +static inline void summit_setup_portio_remap(void) +{ +} + +static inline int summit_check_phys_apicid_present(int boot_cpu_physical_apicid) +{ + return 1; +} + +static inline unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask) +{ + int cpus_found = 0; + int num_bits_set; + int apicid; + int cpu; + + num_bits_set = cpus_weight(*cpumask); + /* Return id to all */ + if (num_bits_set >= nr_cpu_ids) + return 0xFF; + /* + * The cpus in the mask must all be on the apic cluster. If are not + * on the same apicid cluster return default value of target_cpus(): + */ + cpu = first_cpu(*cpumask); + apicid = summit_cpu_to_logical_apicid(cpu); + + while (cpus_found < num_bits_set) { + if (cpu_isset(cpu, *cpumask)) { + int new_apicid = summit_cpu_to_logical_apicid(cpu); + + if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { + printk ("%s: Not a valid mask!\n", __func__); + + return 0xFF; + } + apicid = apicid | new_apicid; + cpus_found++; + } + cpu++; + } + return apicid; +} + +static inline unsigned int +summit_cpu_mask_to_apicid_and(const struct cpumask *inmask, + const struct cpumask *andmask) +{ + int apicid = summit_cpu_to_logical_apicid(0); + cpumask_var_t cpumask; + + if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC)) + return apicid; + + cpumask_and(cpumask, inmask, andmask); + cpumask_and(cpumask, cpumask, cpu_online_mask); + apicid = summit_cpu_mask_to_apicid(cpumask); + + free_cpumask_var(cpumask); + + return apicid; +} + +/* + * cpuid returns the value latched in the HW at reset, not the APIC ID + * register's value. For any box whose BIOS changes APIC IDs, like + * clustered APIC systems, we must use hard_smp_processor_id. + * + * See Intel's IA-32 SW Dev's Manual Vol2 under CPUID. + */ +static inline int summit_phys_pkg_id(int cpuid_apic, int index_msb) +{ + return hard_smp_processor_id() >> index_msb; +} + +static int probe_summit(void) +{ + /* probed later in mptable/ACPI hooks */ + return 0; +} + +static void summit_vector_allocation_domain(int cpu, cpumask_t *retmask) +{ + /* Careful. Some cpus do not strictly honor the set of cpus + * specified in the interrupt destination when using lowest + * priority interrupt delivery mode. + * + * In particular there was a hyperthreading cpu observed to + * deliver interrupts to the wrong hyperthread when only one + * hyperthread was specified in the interrupt desitination. + */ + *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } }; +} + +#ifdef CONFIG_X86_SUMMIT_NUMA +static struct rio_table_hdr *rio_table_hdr __initdata; +static struct scal_detail *scal_devs[MAX_NUMNODES] __initdata; +static struct rio_detail *rio_devs[MAX_NUMNODES*4] __initdata; + +#ifndef CONFIG_X86_NUMAQ +static int mp_bus_id_to_node[MAX_MP_BUSSES] __initdata; +#endif + +static int __init setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus) +{ + int twister = 0, node = 0; + int i, bus, num_buses; + + for (i = 0; i < rio_table_hdr->num_rio_dev; i++) { + if (rio_devs[i]->node_id == rio_devs[wpeg_num]->owner_id) { + twister = rio_devs[i]->owner_id; + break; + } + } + if (i == rio_table_hdr->num_rio_dev) { + printk(KERN_ERR "%s: Couldn't find owner Cyclone for Winnipeg!\n", __func__); + return last_bus; + } + + for (i = 0; i < rio_table_hdr->num_scal_dev; i++) { + if (scal_devs[i]->node_id == twister) { + node = scal_devs[i]->node_id; + break; + } + } + if (i == rio_table_hdr->num_scal_dev) { + printk(KERN_ERR "%s: Couldn't find owner Twister for Cyclone!\n", __func__); + return last_bus; + } + + switch (rio_devs[wpeg_num]->type) { + case CompatWPEG: + /* + * The Compatibility Winnipeg controls the 2 legacy buses, + * the 66MHz PCI bus [2 slots] and the 2 "extra" buses in case + * a PCI-PCI bridge card is used in either slot: total 5 buses. + */ + num_buses = 5; + break; + case AltWPEG: + /* + * The Alternate Winnipeg controls the 2 133MHz buses [1 slot + * each], their 2 "extra" buses, the 100MHz bus [2 slots] and + * the "extra" buses for each of those slots: total 7 buses. + */ + num_buses = 7; + break; + case LookOutAWPEG: + case LookOutBWPEG: + /* + * A Lookout Winnipeg controls 3 100MHz buses [2 slots each] + * & the "extra" buses for each of those slots: total 9 buses. + */ + num_buses = 9; + break; + default: + printk(KERN_INFO "%s: Unsupported Winnipeg type!\n", __func__); + return last_bus; + } + + for (bus = last_bus; bus < last_bus + num_buses; bus++) + mp_bus_id_to_node[bus] = node; + return bus; +} + +static int __init build_detail_arrays(void) +{ + unsigned long ptr; + int i, scal_detail_size, rio_detail_size; + + if (rio_table_hdr->num_scal_dev > MAX_NUMNODES) { + printk(KERN_WARNING "%s: MAX_NUMNODES too low! Defined as %d, but system has %d nodes.\n", __func__, MAX_NUMNODES, rio_table_hdr->num_scal_dev); + return 0; + } + + switch (rio_table_hdr->version) { + default: + printk(KERN_WARNING "%s: Invalid Rio Grande Table Version: %d\n", __func__, rio_table_hdr->version); + return 0; + case 2: + scal_detail_size = 11; + rio_detail_size = 13; + break; + case 3: + scal_detail_size = 12; + rio_detail_size = 15; + break; + } + + ptr = (unsigned long)rio_table_hdr + 3; + for (i = 0; i < rio_table_hdr->num_scal_dev; i++, ptr += scal_detail_size) + scal_devs[i] = (struct scal_detail *)ptr; + + for (i = 0; i < rio_table_hdr->num_rio_dev; i++, ptr += rio_detail_size) + rio_devs[i] = (struct rio_detail *)ptr; + + return 1; +} + +void __init setup_summit(void) +{ + unsigned long ptr; + unsigned short offset; + int i, next_wpeg, next_bus = 0; + + /* The pointer to the EBDA is stored in the word @ phys 0x40E(40:0E) */ + ptr = get_bios_ebda(); + ptr = (unsigned long)phys_to_virt(ptr); + + rio_table_hdr = NULL; + offset = 0x180; + while (offset) { + /* The block id is stored in the 2nd word */ + if (*((unsigned short *)(ptr + offset + 2)) == 0x4752) { + /* set the pointer past the offset & block id */ + rio_table_hdr = (struct rio_table_hdr *)(ptr + offset + 4); + break; + } + /* The next offset is stored in the 1st word. 0 means no more */ + offset = *((unsigned short *)(ptr + offset)); + } + if (!rio_table_hdr) { + printk(KERN_ERR "%s: Unable to locate Rio Grande Table in EBDA - bailing!\n", __func__); + return; + } + + if (!build_detail_arrays()) + return; + + /* The first Winnipeg we're looking for has an index of 0 */ + next_wpeg = 0; + do { + for (i = 0; i < rio_table_hdr->num_rio_dev; i++) { + if (is_WPEG(rio_devs[i]) && rio_devs[i]->WP_index == next_wpeg) { + /* It's the Winnipeg we're looking for! */ + next_bus = setup_pci_node_map_for_wpeg(i, next_bus); + next_wpeg++; + break; + } + } + /* + * If we go through all Rio devices and don't find one with + * the next index, it means we've found all the Winnipegs, + * and thus all the PCI buses. + */ + if (i == rio_table_hdr->num_rio_dev) + next_wpeg = 0; + } while (next_wpeg != 0); +} +#endif + +struct apic apic_summit = { + + .name = "summit", + .probe = probe_summit, + .acpi_madt_oem_check = summit_acpi_madt_oem_check, + .apic_id_registered = summit_apic_id_registered, + + .irq_delivery_mode = dest_LowestPrio, + /* logical delivery broadcast to all CPUs: */ + .irq_dest_mode = 1, + + .target_cpus = summit_target_cpus, + .disable_esr = 1, + .dest_logical = APIC_DEST_LOGICAL, + .check_apicid_used = summit_check_apicid_used, + .check_apicid_present = summit_check_apicid_present, + + .vector_allocation_domain = summit_vector_allocation_domain, + .init_apic_ldr = summit_init_apic_ldr, + + .ioapic_phys_id_map = summit_ioapic_phys_id_map, + .setup_apic_routing = summit_setup_apic_routing, + .multi_timer_check = NULL, + .apicid_to_node = summit_apicid_to_node, + .cpu_to_logical_apicid = summit_cpu_to_logical_apicid, + .cpu_present_to_apicid = summit_cpu_present_to_apicid, + .apicid_to_cpu_present = summit_apicid_to_cpu_present, + .setup_portio_remap = NULL, + .check_phys_apicid_present = summit_check_phys_apicid_present, + .enable_apic_mode = NULL, + .phys_pkg_id = summit_phys_pkg_id, + .mps_oem_check = summit_mps_oem_check, + + .get_apic_id = summit_get_apic_id, + .set_apic_id = NULL, + .apic_id_mask = 0xFF << 24, + + .cpu_mask_to_apicid = summit_cpu_mask_to_apicid, + .cpu_mask_to_apicid_and = summit_cpu_mask_to_apicid_and, + + .send_IPI_mask = summit_send_IPI_mask, + .send_IPI_mask_allbutself = NULL, + .send_IPI_allbutself = summit_send_IPI_allbutself, + .send_IPI_all = summit_send_IPI_all, + .send_IPI_self = default_send_IPI_self, + + .wakeup_cpu = NULL, + .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, + .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, + + .wait_for_init_deassert = default_wait_for_init_deassert, + + .smp_callin_clear_local_apic = NULL, + .inquire_remote_apic = default_inquire_remote_apic, + + .read = native_apic_mem_read, + .write = native_apic_mem_write, + .icr_read = native_apic_icr_read, + .icr_write = native_apic_icr_write, + .wait_icr_idle = native_apic_wait_icr_idle, + .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, +}; diff --git a/arch/x86/kernel/bigsmp_32.c b/arch/x86/kernel/bigsmp_32.c deleted file mode 100644 index 0b1093394fd..00000000000 --- a/arch/x86/kernel/bigsmp_32.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * APIC driver for "bigsmp" xAPIC machines with more than 8 virtual CPUs. - * - * Drives the local APIC in "clustered mode". - */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -static inline unsigned bigsmp_get_apic_id(unsigned long x) -{ - return (x >> 24) & 0xFF; -} - -static inline int bigsmp_apic_id_registered(void) -{ - return 1; -} - -static inline const cpumask_t *bigsmp_target_cpus(void) -{ -#ifdef CONFIG_SMP - return &cpu_online_map; -#else - return &cpumask_of_cpu(0); -#endif -} - -static inline unsigned long -bigsmp_check_apicid_used(physid_mask_t bitmap, int apicid) -{ - return 0; -} - -static inline unsigned long bigsmp_check_apicid_present(int bit) -{ - return 1; -} - -static inline unsigned long calculate_ldr(int cpu) -{ - unsigned long val, id; - - val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; - id = per_cpu(x86_bios_cpu_apicid, cpu); - val |= SET_APIC_LOGICAL_ID(id); - - return val; -} - -/* - * Set up the logical destination ID. - * - * Intel recommends to set DFR, LDR and TPR before enabling - * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel - * document number 292116). So here it goes... - */ -static inline void bigsmp_init_apic_ldr(void) -{ - unsigned long val; - int cpu = smp_processor_id(); - - apic_write(APIC_DFR, APIC_DFR_FLAT); - val = calculate_ldr(cpu); - apic_write(APIC_LDR, val); -} - -static inline void bigsmp_setup_apic_routing(void) -{ - printk(KERN_INFO - "Enabling APIC mode: Physflat. Using %d I/O APICs\n", - nr_ioapics); -} - -static inline int bigsmp_apicid_to_node(int logical_apicid) -{ - return apicid_2_node[hard_smp_processor_id()]; -} - -static inline int bigsmp_cpu_present_to_apicid(int mps_cpu) -{ - if (mps_cpu < nr_cpu_ids) - return (int) per_cpu(x86_bios_cpu_apicid, mps_cpu); - - return BAD_APICID; -} - -static inline physid_mask_t bigsmp_apicid_to_cpu_present(int phys_apicid) -{ - return physid_mask_of_physid(phys_apicid); -} - -/* Mapping from cpu number to logical apicid */ -static inline int bigsmp_cpu_to_logical_apicid(int cpu) -{ - if (cpu >= nr_cpu_ids) - return BAD_APICID; - return cpu_physical_id(cpu); -} - -static inline physid_mask_t bigsmp_ioapic_phys_id_map(physid_mask_t phys_map) -{ - /* For clustered we don't have a good way to do this yet - hack */ - return physids_promote(0xFFL); -} - -static inline void bigsmp_setup_portio_remap(void) -{ -} - -static inline int bigsmp_check_phys_apicid_present(int boot_cpu_physical_apicid) -{ - return 1; -} - -/* As we are using single CPU as destination, pick only one CPU here */ -static inline unsigned int bigsmp_cpu_mask_to_apicid(const cpumask_t *cpumask) -{ - return bigsmp_cpu_to_logical_apicid(first_cpu(*cpumask)); -} - -static inline unsigned int -bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask) -{ - int cpu; - - /* - * We're using fixed IRQ delivery, can only return one phys APIC ID. - * May as well be the first. - */ - for_each_cpu_and(cpu, cpumask, andmask) { - if (cpumask_test_cpu(cpu, cpu_online_mask)) - break; - } - if (cpu < nr_cpu_ids) - return bigsmp_cpu_to_logical_apicid(cpu); - - return BAD_APICID; -} - -static inline int bigsmp_phys_pkg_id(int cpuid_apic, int index_msb) -{ - return cpuid_apic >> index_msb; -} - -static inline void bigsmp_send_IPI_mask(const struct cpumask *mask, int vector) -{ - default_send_IPI_mask_sequence_phys(mask, vector); -} - -static inline void bigsmp_send_IPI_allbutself(int vector) -{ - default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector); -} - -static inline void bigsmp_send_IPI_all(int vector) -{ - bigsmp_send_IPI_mask(cpu_online_mask, vector); -} - -static int dmi_bigsmp; /* can be set by dmi scanners */ - -static int hp_ht_bigsmp(const struct dmi_system_id *d) -{ - printk(KERN_NOTICE "%s detected: force use of apic=bigsmp\n", d->ident); - dmi_bigsmp = 1; - - return 0; -} - - -static const struct dmi_system_id bigsmp_dmi_table[] = { - { hp_ht_bigsmp, "HP ProLiant DL760 G2", - { DMI_MATCH(DMI_BIOS_VENDOR, "HP"), - DMI_MATCH(DMI_BIOS_VERSION, "P44-"), - } - }, - - { hp_ht_bigsmp, "HP ProLiant DL740", - { DMI_MATCH(DMI_BIOS_VENDOR, "HP"), - DMI_MATCH(DMI_BIOS_VERSION, "P47-"), - } - }, - { } /* NULL entry stops DMI scanning */ -}; - -static void bigsmp_vector_allocation_domain(int cpu, cpumask_t *retmask) -{ - cpus_clear(*retmask); - cpu_set(cpu, *retmask); -} - -static int probe_bigsmp(void) -{ - if (def_to_bigsmp) - dmi_bigsmp = 1; - else - dmi_check_system(bigsmp_dmi_table); - - return dmi_bigsmp; -} - -struct apic apic_bigsmp = { - - .name = "bigsmp", - .probe = probe_bigsmp, - .acpi_madt_oem_check = NULL, - .apic_id_registered = bigsmp_apic_id_registered, - - .irq_delivery_mode = dest_Fixed, - /* phys delivery to target CPU: */ - .irq_dest_mode = 0, - - .target_cpus = bigsmp_target_cpus, - .disable_esr = 1, - .dest_logical = 0, - .check_apicid_used = bigsmp_check_apicid_used, - .check_apicid_present = bigsmp_check_apicid_present, - - .vector_allocation_domain = bigsmp_vector_allocation_domain, - .init_apic_ldr = bigsmp_init_apic_ldr, - - .ioapic_phys_id_map = bigsmp_ioapic_phys_id_map, - .setup_apic_routing = bigsmp_setup_apic_routing, - .multi_timer_check = NULL, - .apicid_to_node = bigsmp_apicid_to_node, - .cpu_to_logical_apicid = bigsmp_cpu_to_logical_apicid, - .cpu_present_to_apicid = bigsmp_cpu_present_to_apicid, - .apicid_to_cpu_present = bigsmp_apicid_to_cpu_present, - .setup_portio_remap = NULL, - .check_phys_apicid_present = bigsmp_check_phys_apicid_present, - .enable_apic_mode = NULL, - .phys_pkg_id = bigsmp_phys_pkg_id, - .mps_oem_check = NULL, - - .get_apic_id = bigsmp_get_apic_id, - .set_apic_id = NULL, - .apic_id_mask = 0xFF << 24, - - .cpu_mask_to_apicid = bigsmp_cpu_mask_to_apicid, - .cpu_mask_to_apicid_and = bigsmp_cpu_mask_to_apicid_and, - - .send_IPI_mask = bigsmp_send_IPI_mask, - .send_IPI_mask_allbutself = NULL, - .send_IPI_allbutself = bigsmp_send_IPI_allbutself, - .send_IPI_all = bigsmp_send_IPI_all, - .send_IPI_self = default_send_IPI_self, - - .wakeup_cpu = NULL, - .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, - .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, - - .wait_for_init_deassert = default_wait_for_init_deassert, - - .smp_callin_clear_local_apic = NULL, - .inquire_remote_apic = default_inquire_remote_apic, - - .read = native_apic_mem_read, - .write = native_apic_mem_write, - .icr_read = native_apic_icr_read, - .icr_write = native_apic_icr_write, - .wait_icr_idle = native_apic_wait_icr_idle, - .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, -}; diff --git a/arch/x86/kernel/es7000_32.c b/arch/x86/kernel/es7000_32.c deleted file mode 100644 index 320f2d2e4e5..00000000000 --- a/arch/x86/kernel/es7000_32.c +++ /dev/null @@ -1,757 +0,0 @@ -/* - * Written by: Garry Forsgren, Unisys Corporation - * Natalie Protasevich, Unisys Corporation - * - * This file contains the code to configure and interface - * with Unisys ES7000 series hardware system manager. - * - * Copyright (c) 2003 Unisys Corporation. - * Copyright (C) 2009, Red Hat, Inc., Ingo Molnar - * - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * Contact information: Unisys Corporation, Township Line & Union Meeting - * Roads-A, Unisys Way, Blue Bell, Pennsylvania, 19424, or: - * - * http://www.unisys.com - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* - * ES7000 chipsets - */ - -#define NON_UNISYS 0 -#define ES7000_CLASSIC 1 -#define ES7000_ZORRO 2 - -#define MIP_REG 1 -#define MIP_PSAI_REG 4 - -#define MIP_BUSY 1 -#define MIP_SPIN 0xf0000 -#define MIP_VALID 0x0100000000000000ULL -#define MIP_SW_APIC 0x1020b - -#define MIP_PORT(val) ((val >> 32) & 0xffff) - -#define MIP_RD_LO(val) (val & 0xffffffff) - -struct mip_reg { - unsigned long long off_0x00; - unsigned long long off_0x08; - unsigned long long off_0x10; - unsigned long long off_0x18; - unsigned long long off_0x20; - unsigned long long off_0x28; - unsigned long long off_0x30; - unsigned long long off_0x38; -}; - -struct mip_reg_info { - unsigned long long mip_info; - unsigned long long delivery_info; - unsigned long long host_reg; - unsigned long long mip_reg; -}; - -struct psai { - unsigned long long entry_type; - unsigned long long addr; - unsigned long long bep_addr; -}; - -#ifdef CONFIG_ACPI - -struct es7000_oem_table { - struct acpi_table_header Header; - u32 OEMTableAddr; - u32 OEMTableSize; -}; - -static unsigned long oem_addrX; -static unsigned long oem_size; - -#endif - -/* - * ES7000 Globals - */ - -static volatile unsigned long *psai; -static struct mip_reg *mip_reg; -static struct mip_reg *host_reg; -static int mip_port; -static unsigned long mip_addr; -static unsigned long host_addr; - -int es7000_plat; - -/* - * GSI override for ES7000 platforms. - */ - -static unsigned int base; - -static int -es7000_rename_gsi(int ioapic, int gsi) -{ - if (es7000_plat == ES7000_ZORRO) - return gsi; - - if (!base) { - int i; - for (i = 0; i < nr_ioapics; i++) - base += nr_ioapic_registers[i]; - } - - if (!ioapic && (gsi < 16)) - gsi += base; - - return gsi; -} - -static int wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip) -{ - unsigned long vect = 0, psaival = 0; - - if (psai == NULL) - return -1; - - vect = ((unsigned long)__pa(eip)/0x1000) << 16; - psaival = (0x1000000 | vect | cpu); - - while (*psai & 0x1000000) - ; - - *psai = psaival; - - return 0; -} - -static int __init es7000_update_apic(void) -{ - apic->wakeup_cpu = wakeup_secondary_cpu_via_mip; - - /* MPENTIUMIII */ - if (boot_cpu_data.x86 == 6 && - (boot_cpu_data.x86_model >= 7 || boot_cpu_data.x86_model <= 11)) { - es7000_update_apic_to_cluster(); - apic->wait_for_init_deassert = NULL; - apic->wakeup_cpu = wakeup_secondary_cpu_via_mip; - } - - return 0; -} - -static void __init setup_unisys(void) -{ - /* - * Determine the generation of the ES7000 currently running. - * - * es7000_plat = 1 if the machine is a 5xx ES7000 box - * es7000_plat = 2 if the machine is a x86_64 ES7000 box - * - */ - if (!(boot_cpu_data.x86 <= 15 && boot_cpu_data.x86_model <= 2)) - es7000_plat = ES7000_ZORRO; - else - es7000_plat = ES7000_CLASSIC; - ioapic_renumber_irq = es7000_rename_gsi; - - x86_quirks->update_apic = es7000_update_apic; -} - -/* - * Parse the OEM Table: - */ -static int __init parse_unisys_oem(char *oemptr) -{ - int i; - int success = 0; - unsigned char type, size; - unsigned long val; - char *tp = NULL; - struct psai *psaip = NULL; - struct mip_reg_info *mi; - struct mip_reg *host, *mip; - - tp = oemptr; - - tp += 8; - - for (i = 0; i <= 6; i++) { - type = *tp++; - size = *tp++; - tp -= 2; - switch (type) { - case MIP_REG: - mi = (struct mip_reg_info *)tp; - val = MIP_RD_LO(mi->host_reg); - host_addr = val; - host = (struct mip_reg *)val; - host_reg = __va(host); - val = MIP_RD_LO(mi->mip_reg); - mip_port = MIP_PORT(mi->mip_info); - mip_addr = val; - mip = (struct mip_reg *)val; - mip_reg = __va(mip); - pr_debug("es7000_mipcfg: host_reg = 0x%lx \n", - (unsigned long)host_reg); - pr_debug("es7000_mipcfg: mip_reg = 0x%lx \n", - (unsigned long)mip_reg); - success++; - break; - case MIP_PSAI_REG: - psaip = (struct psai *)tp; - if (tp != NULL) { - if (psaip->addr) - psai = __va(psaip->addr); - else - psai = NULL; - success++; - } - break; - default: - break; - } - tp += size; - } - - if (success < 2) - es7000_plat = NON_UNISYS; - else - setup_unisys(); - - return es7000_plat; -} - -#ifdef CONFIG_ACPI -static int __init find_unisys_acpi_oem_table(unsigned long *oem_addr) -{ - struct acpi_table_header *header = NULL; - struct es7000_oem_table *table; - acpi_size tbl_size; - acpi_status ret; - int i = 0; - - for (;;) { - ret = acpi_get_table_with_size("OEM1", i++, &header, &tbl_size); - if (!ACPI_SUCCESS(ret)) - return -1; - - if (!memcmp((char *) &header->oem_id, "UNISYS", 6)) - break; - - early_acpi_os_unmap_memory(header, tbl_size); - } - - table = (void *)header; - - oem_addrX = table->OEMTableAddr; - oem_size = table->OEMTableSize; - - early_acpi_os_unmap_memory(header, tbl_size); - - *oem_addr = (unsigned long)__acpi_map_table(oem_addrX, oem_size); - - return 0; -} - -static void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr) -{ - if (!oem_addr) - return; - - __acpi_unmap_table((char *)oem_addr, oem_size); -} - -static int es7000_check_dsdt(void) -{ - struct acpi_table_header header; - - if (ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_DSDT, 0, &header)) && - !strncmp(header.oem_id, "UNISYS", 6)) - return 1; - return 0; -} - -/* Hook from generic ACPI tables.c */ -static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id) -{ - unsigned long oem_addr = 0; - int check_dsdt; - int ret = 0; - - /* check dsdt at first to avoid clear fix_map for oem_addr */ - check_dsdt = es7000_check_dsdt(); - - if (!find_unisys_acpi_oem_table(&oem_addr)) { - if (check_dsdt) { - ret = parse_unisys_oem((char *)oem_addr); - } else { - setup_unisys(); - ret = 1; - } - /* - * we need to unmap it - */ - unmap_unisys_acpi_oem_table(oem_addr); - } - return ret; -} -#else /* !CONFIG_ACPI: */ -static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id) -{ - return 0; -} -#endif /* !CONFIG_ACPI */ - -static void es7000_spin(int n) -{ - int i = 0; - - while (i++ < n) - rep_nop(); -} - -static int __init -es7000_mip_write(struct mip_reg *mip_reg) -{ - int status = 0; - int spin; - - spin = MIP_SPIN; - while ((host_reg->off_0x38 & MIP_VALID) != 0) { - if (--spin <= 0) { - WARN(1, "Timeout waiting for Host Valid Flag\n"); - return -1; - } - es7000_spin(MIP_SPIN); - } - - memcpy(host_reg, mip_reg, sizeof(struct mip_reg)); - outb(1, mip_port); - - spin = MIP_SPIN; - - while ((mip_reg->off_0x38 & MIP_VALID) == 0) { - if (--spin <= 0) { - WARN(1, "Timeout waiting for MIP Valid Flag\n"); - return -1; - } - es7000_spin(MIP_SPIN); - } - - status = (mip_reg->off_0x00 & 0xffff0000000000ULL) >> 48; - mip_reg->off_0x38 &= ~MIP_VALID; - - return status; -} - -static void __init es7000_enable_apic_mode(void) -{ - struct mip_reg es7000_mip_reg; - int mip_status; - - if (!es7000_plat) - return; - - printk(KERN_INFO "ES7000: Enabling APIC mode.\n"); - memset(&es7000_mip_reg, 0, sizeof(struct mip_reg)); - es7000_mip_reg.off_0x00 = MIP_SW_APIC; - es7000_mip_reg.off_0x38 = MIP_VALID; - - while ((mip_status = es7000_mip_write(&es7000_mip_reg)) != 0) - WARN(1, "Command failed, status = %x\n", mip_status); -} - -static void es7000_vector_allocation_domain(int cpu, cpumask_t *retmask) -{ - /* Careful. Some cpus do not strictly honor the set of cpus - * specified in the interrupt destination when using lowest - * priority interrupt delivery mode. - * - * In particular there was a hyperthreading cpu observed to - * deliver interrupts to the wrong hyperthread when only one - * hyperthread was specified in the interrupt desitination. - */ - *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } }; -} - - -static void es7000_wait_for_init_deassert(atomic_t *deassert) -{ -#ifndef CONFIG_ES7000_CLUSTERED_APIC - while (!atomic_read(deassert)) - cpu_relax(); -#endif - return; -} - -static unsigned int es7000_get_apic_id(unsigned long x) -{ - return (x >> 24) & 0xFF; -} - -static void es7000_send_IPI_mask(const struct cpumask *mask, int vector) -{ - default_send_IPI_mask_sequence_phys(mask, vector); -} - -static void es7000_send_IPI_allbutself(int vector) -{ - default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector); -} - -static void es7000_send_IPI_all(int vector) -{ - es7000_send_IPI_mask(cpu_online_mask, vector); -} - -static int es7000_apic_id_registered(void) -{ - return 1; -} - -static const cpumask_t *target_cpus_cluster(void) -{ - return &CPU_MASK_ALL; -} - -static const cpumask_t *es7000_target_cpus(void) -{ - return &cpumask_of_cpu(smp_processor_id()); -} - -static unsigned long -es7000_check_apicid_used(physid_mask_t bitmap, int apicid) -{ - return 0; -} -static unsigned long es7000_check_apicid_present(int bit) -{ - return physid_isset(bit, phys_cpu_present_map); -} - -static unsigned long calculate_ldr(int cpu) -{ - unsigned long id = per_cpu(x86_bios_cpu_apicid, cpu); - - return SET_APIC_LOGICAL_ID(id); -} - -/* - * Set up the logical destination ID. - * - * Intel recommends to set DFR, LdR and TPR before enabling - * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel - * document number 292116). So here it goes... - */ -static void es7000_init_apic_ldr_cluster(void) -{ - unsigned long val; - int cpu = smp_processor_id(); - - apic_write(APIC_DFR, APIC_DFR_CLUSTER); - val = calculate_ldr(cpu); - apic_write(APIC_LDR, val); -} - -static void es7000_init_apic_ldr(void) -{ - unsigned long val; - int cpu = smp_processor_id(); - - apic_write(APIC_DFR, APIC_DFR_FLAT); - val = calculate_ldr(cpu); - apic_write(APIC_LDR, val); -} - -static void es7000_setup_apic_routing(void) -{ - int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id()); - - printk(KERN_INFO - "Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n", - (apic_version[apic] == 0x14) ? - "Physical Cluster" : "Logical Cluster", - nr_ioapics, cpus_addr(*es7000_target_cpus())[0]); -} - -static int es7000_apicid_to_node(int logical_apicid) -{ - return 0; -} - - -static int es7000_cpu_present_to_apicid(int mps_cpu) -{ - if (!mps_cpu) - return boot_cpu_physical_apicid; - else if (mps_cpu < nr_cpu_ids) - return per_cpu(x86_bios_cpu_apicid, mps_cpu); - else - return BAD_APICID; -} - -static int cpu_id; - -static physid_mask_t es7000_apicid_to_cpu_present(int phys_apicid) -{ - physid_mask_t mask; - - mask = physid_mask_of_physid(cpu_id); - ++cpu_id; - - return mask; -} - -/* Mapping from cpu number to logical apicid */ -static int es7000_cpu_to_logical_apicid(int cpu) -{ -#ifdef CONFIG_SMP - if (cpu >= nr_cpu_ids) - return BAD_APICID; - return cpu_2_logical_apicid[cpu]; -#else - return logical_smp_processor_id(); -#endif -} - -static physid_mask_t es7000_ioapic_phys_id_map(physid_mask_t phys_map) -{ - /* For clustered we don't have a good way to do this yet - hack */ - return physids_promote(0xff); -} - -static int es7000_check_phys_apicid_present(int cpu_physical_apicid) -{ - boot_cpu_physical_apicid = read_apic_id(); - return 1; -} - -static unsigned int -es7000_cpu_mask_to_apicid_cluster(const struct cpumask *cpumask) -{ - int cpus_found = 0; - int num_bits_set; - int apicid; - int cpu; - - num_bits_set = cpumask_weight(cpumask); - /* Return id to all */ - if (num_bits_set == nr_cpu_ids) - return 0xFF; - /* - * The cpus in the mask must all be on the apic cluster. If are not - * on the same apicid cluster return default value of target_cpus(): - */ - cpu = cpumask_first(cpumask); - apicid = es7000_cpu_to_logical_apicid(cpu); - - while (cpus_found < num_bits_set) { - if (cpumask_test_cpu(cpu, cpumask)) { - int new_apicid = es7000_cpu_to_logical_apicid(cpu); - - if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { - WARN(1, "Not a valid mask!"); - - return 0xFF; - } - apicid = new_apicid; - cpus_found++; - } - cpu++; - } - return apicid; -} - -static unsigned int es7000_cpu_mask_to_apicid(const cpumask_t *cpumask) -{ - int cpus_found = 0; - int num_bits_set; - int apicid; - int cpu; - - num_bits_set = cpus_weight(*cpumask); - /* Return id to all */ - if (num_bits_set == nr_cpu_ids) - return es7000_cpu_to_logical_apicid(0); - /* - * The cpus in the mask must all be on the apic cluster. If are not - * on the same apicid cluster return default value of target_cpus(): - */ - cpu = first_cpu(*cpumask); - apicid = es7000_cpu_to_logical_apicid(cpu); - while (cpus_found < num_bits_set) { - if (cpu_isset(cpu, *cpumask)) { - int new_apicid = es7000_cpu_to_logical_apicid(cpu); - - if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { - printk("%s: Not a valid mask!\n", __func__); - - return es7000_cpu_to_logical_apicid(0); - } - apicid = new_apicid; - cpus_found++; - } - cpu++; - } - return apicid; -} - -static unsigned int -es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask, - const struct cpumask *andmask) -{ - int apicid = es7000_cpu_to_logical_apicid(0); - cpumask_var_t cpumask; - - if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC)) - return apicid; - - cpumask_and(cpumask, inmask, andmask); - cpumask_and(cpumask, cpumask, cpu_online_mask); - apicid = es7000_cpu_mask_to_apicid(cpumask); - - free_cpumask_var(cpumask); - - return apicid; -} - -static int es7000_phys_pkg_id(int cpuid_apic, int index_msb) -{ - return cpuid_apic >> index_msb; -} - -void __init es7000_update_apic_to_cluster(void) -{ - apic->target_cpus = target_cpus_cluster; - apic->irq_delivery_mode = dest_LowestPrio; - /* logical delivery broadcast to all procs: */ - apic->irq_dest_mode = 1; - - apic->init_apic_ldr = es7000_init_apic_ldr_cluster; - - apic->cpu_mask_to_apicid = es7000_cpu_mask_to_apicid_cluster; -} - -static int probe_es7000(void) -{ - /* probed later in mptable/ACPI hooks */ - return 0; -} - -static __init int -es7000_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) -{ - if (mpc->oemptr) { - struct mpc_oemtable *oem_table = - (struct mpc_oemtable *)mpc->oemptr; - - if (!strncmp(oem, "UNISYS", 6)) - return parse_unisys_oem((char *)oem_table); - } - return 0; -} - - -struct apic apic_es7000 = { - - .name = "es7000", - .probe = probe_es7000, - .acpi_madt_oem_check = es7000_acpi_madt_oem_check, - .apic_id_registered = es7000_apic_id_registered, - - .irq_delivery_mode = dest_Fixed, - /* phys delivery to target CPUs: */ - .irq_dest_mode = 0, - - .target_cpus = es7000_target_cpus, - .disable_esr = 1, - .dest_logical = 0, - .check_apicid_used = es7000_check_apicid_used, - .check_apicid_present = es7000_check_apicid_present, - - .vector_allocation_domain = es7000_vector_allocation_domain, - .init_apic_ldr = es7000_init_apic_ldr, - - .ioapic_phys_id_map = es7000_ioapic_phys_id_map, - .setup_apic_routing = es7000_setup_apic_routing, - .multi_timer_check = NULL, - .apicid_to_node = es7000_apicid_to_node, - .cpu_to_logical_apicid = es7000_cpu_to_logical_apicid, - .cpu_present_to_apicid = es7000_cpu_present_to_apicid, - .apicid_to_cpu_present = es7000_apicid_to_cpu_present, - .setup_portio_remap = NULL, - .check_phys_apicid_present = es7000_check_phys_apicid_present, - .enable_apic_mode = es7000_enable_apic_mode, - .phys_pkg_id = es7000_phys_pkg_id, - .mps_oem_check = es7000_mps_oem_check, - - .get_apic_id = es7000_get_apic_id, - .set_apic_id = NULL, - .apic_id_mask = 0xFF << 24, - - .cpu_mask_to_apicid = es7000_cpu_mask_to_apicid, - .cpu_mask_to_apicid_and = es7000_cpu_mask_to_apicid_and, - - .send_IPI_mask = es7000_send_IPI_mask, - .send_IPI_mask_allbutself = NULL, - .send_IPI_allbutself = es7000_send_IPI_allbutself, - .send_IPI_all = es7000_send_IPI_all, - .send_IPI_self = default_send_IPI_self, - - .wakeup_cpu = NULL, - - .trampoline_phys_low = 0x467, - .trampoline_phys_high = 0x469, - - .wait_for_init_deassert = es7000_wait_for_init_deassert, - - /* Nothing to do for most platforms, since cleared by the INIT cycle: */ - .smp_callin_clear_local_apic = NULL, - .inquire_remote_apic = default_inquire_remote_apic, - - .read = native_apic_mem_read, - .write = native_apic_mem_write, - .icr_read = native_apic_icr_read, - .icr_write = native_apic_icr_write, - .wait_icr_idle = native_apic_wait_icr_idle, - .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, -}; diff --git a/arch/x86/kernel/numaq_32.c b/arch/x86/kernel/numaq_32.c deleted file mode 100644 index d9d6d61eed8..00000000000 --- a/arch/x86/kernel/numaq_32.c +++ /dev/null @@ -1,565 +0,0 @@ -/* - * Written by: Patricia Gaughen, IBM Corporation - * - * Copyright (C) 2002, IBM Corp. - * Copyright (C) 2009, Red Hat, Inc., Ingo Molnar - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Send feedback to - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#define MB_TO_PAGES(addr) ((addr) << (20 - PAGE_SHIFT)) - -int found_numaq; - -/* - * Have to match translation table entries to main table entries by counter - * hence the mpc_record variable .... can't see a less disgusting way of - * doing this .... - */ -struct mpc_trans { - unsigned char mpc_type; - unsigned char trans_len; - unsigned char trans_type; - unsigned char trans_quad; - unsigned char trans_global; - unsigned char trans_local; - unsigned short trans_reserved; -}; - -/* x86_quirks member */ -static int mpc_record; - -static __cpuinitdata struct mpc_trans *translation_table[MAX_MPC_ENTRY]; - -int mp_bus_id_to_node[MAX_MP_BUSSES]; -int mp_bus_id_to_local[MAX_MP_BUSSES]; -int quad_local_to_mp_bus_id[NR_CPUS/4][4]; - - -static inline void numaq_register_node(int node, struct sys_cfg_data *scd) -{ - struct eachquadmem *eq = scd->eq + node; - - node_set_online(node); - - /* Convert to pages */ - node_start_pfn[node] = - MB_TO_PAGES(eq->hi_shrd_mem_start - eq->priv_mem_size); - - node_end_pfn[node] = - MB_TO_PAGES(eq->hi_shrd_mem_start + eq->hi_shrd_mem_size); - - e820_register_active_regions(node, node_start_pfn[node], - node_end_pfn[node]); - - memory_present(node, node_start_pfn[node], node_end_pfn[node]); - - node_remap_size[node] = node_memmap_size_bytes(node, - node_start_pfn[node], - node_end_pfn[node]); -} - -/* - * Function: smp_dump_qct() - * - * Description: gets memory layout from the quad config table. This - * function also updates node_online_map with the nodes (quads) present. - */ -static void __init smp_dump_qct(void) -{ - struct sys_cfg_data *scd; - int node; - - scd = (void *)__va(SYS_CFG_DATA_PRIV_ADDR); - - nodes_clear(node_online_map); - for_each_node(node) { - if (scd->quads_present31_0 & (1 << node)) - numaq_register_node(node, scd); - } -} - -void __cpuinit numaq_tsc_disable(void) -{ - if (!found_numaq) - return; - - if (num_online_nodes() > 1) { - printk(KERN_DEBUG "NUMAQ: disabling TSC\n"); - setup_clear_cpu_cap(X86_FEATURE_TSC); - } -} - -static int __init numaq_pre_time_init(void) -{ - numaq_tsc_disable(); - return 0; -} - -static inline int generate_logical_apicid(int quad, int phys_apicid) -{ - return (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1); -} - -/* x86_quirks member */ -static int mpc_apic_id(struct mpc_cpu *m) -{ - int quad = translation_table[mpc_record]->trans_quad; - int logical_apicid = generate_logical_apicid(quad, m->apicid); - - printk(KERN_DEBUG - "Processor #%d %u:%u APIC version %d (quad %d, apic %d)\n", - m->apicid, (m->cpufeature & CPU_FAMILY_MASK) >> 8, - (m->cpufeature & CPU_MODEL_MASK) >> 4, - m->apicver, quad, logical_apicid); - - return logical_apicid; -} - -/* x86_quirks member */ -static void mpc_oem_bus_info(struct mpc_bus *m, char *name) -{ - int quad = translation_table[mpc_record]->trans_quad; - int local = translation_table[mpc_record]->trans_local; - - mp_bus_id_to_node[m->busid] = quad; - mp_bus_id_to_local[m->busid] = local; - - printk(KERN_INFO "Bus #%d is %s (node %d)\n", m->busid, name, quad); -} - -/* x86_quirks member */ -static void mpc_oem_pci_bus(struct mpc_bus *m) -{ - int quad = translation_table[mpc_record]->trans_quad; - int local = translation_table[mpc_record]->trans_local; - - quad_local_to_mp_bus_id[quad][local] = m->busid; -} - -static void __init MP_translation_info(struct mpc_trans *m) -{ - printk(KERN_INFO - "Translation: record %d, type %d, quad %d, global %d, local %d\n", - mpc_record, m->trans_type, m->trans_quad, m->trans_global, - m->trans_local); - - if (mpc_record >= MAX_MPC_ENTRY) - printk(KERN_ERR "MAX_MPC_ENTRY exceeded!\n"); - else - translation_table[mpc_record] = m; /* stash this for later */ - - if (m->trans_quad < MAX_NUMNODES && !node_online(m->trans_quad)) - node_set_online(m->trans_quad); -} - -static int __init mpf_checksum(unsigned char *mp, int len) -{ - int sum = 0; - - while (len--) - sum += *mp++; - - return sum & 0xFF; -} - -/* - * Read/parse the MPC oem tables - */ -static void __init - smp_read_mpc_oem(struct mpc_oemtable *oemtable, unsigned short oemsize) -{ - int count = sizeof(*oemtable); /* the header size */ - unsigned char *oemptr = ((unsigned char *)oemtable) + count; - - mpc_record = 0; - printk(KERN_INFO - "Found an OEM MPC table at %8p - parsing it ... \n", oemtable); - - if (memcmp(oemtable->signature, MPC_OEM_SIGNATURE, 4)) { - printk(KERN_WARNING - "SMP mpc oemtable: bad signature [%c%c%c%c]!\n", - oemtable->signature[0], oemtable->signature[1], - oemtable->signature[2], oemtable->signature[3]); - return; - } - - if (mpf_checksum((unsigned char *)oemtable, oemtable->length)) { - printk(KERN_WARNING "SMP oem mptable: checksum error!\n"); - return; - } - - while (count < oemtable->length) { - switch (*oemptr) { - case MP_TRANSLATION: - { - struct mpc_trans *m = (void *)oemptr; - - MP_translation_info(m); - oemptr += sizeof(*m); - count += sizeof(*m); - ++mpc_record; - break; - } - default: - printk(KERN_WARNING - "Unrecognised OEM table entry type! - %d\n", - (int)*oemptr); - return; - } - } -} - -static int __init numaq_setup_ioapic_ids(void) -{ - /* so can skip it */ - return 1; -} - -static int __init numaq_update_apic(void) -{ - apic->wakeup_cpu = wakeup_secondary_cpu_via_nmi; - - return 0; -} - -static struct x86_quirks numaq_x86_quirks __initdata = { - .arch_pre_time_init = numaq_pre_time_init, - .arch_time_init = NULL, - .arch_pre_intr_init = NULL, - .arch_memory_setup = NULL, - .arch_intr_init = NULL, - .arch_trap_init = NULL, - .mach_get_smp_config = NULL, - .mach_find_smp_config = NULL, - .mpc_record = &mpc_record, - .mpc_apic_id = mpc_apic_id, - .mpc_oem_bus_info = mpc_oem_bus_info, - .mpc_oem_pci_bus = mpc_oem_pci_bus, - .smp_read_mpc_oem = smp_read_mpc_oem, - .setup_ioapic_ids = numaq_setup_ioapic_ids, - .update_apic = numaq_update_apic, -}; - -static __init void early_check_numaq(void) -{ - /* - * Find possible boot-time SMP configuration: - */ - early_find_smp_config(); - - /* - * get boot-time SMP configuration: - */ - if (smp_found_config) - early_get_smp_config(); - - if (found_numaq) - x86_quirks = &numaq_x86_quirks; -} - -int __init get_memcfg_numaq(void) -{ - early_check_numaq(); - if (!found_numaq) - return 0; - smp_dump_qct(); - - return 1; -} - -#define NUMAQ_APIC_DFR_VALUE (APIC_DFR_CLUSTER) - -static inline unsigned int numaq_get_apic_id(unsigned long x) -{ - return (x >> 24) & 0x0F; -} - -static inline void numaq_send_IPI_mask(const struct cpumask *mask, int vector) -{ - default_send_IPI_mask_sequence_logical(mask, vector); -} - -static inline void numaq_send_IPI_allbutself(int vector) -{ - default_send_IPI_mask_allbutself_logical(cpu_online_mask, vector); -} - -static inline void numaq_send_IPI_all(int vector) -{ - numaq_send_IPI_mask(cpu_online_mask, vector); -} - -#define NUMAQ_TRAMPOLINE_PHYS_LOW (0x8) -#define NUMAQ_TRAMPOLINE_PHYS_HIGH (0xa) - -/* - * Because we use NMIs rather than the INIT-STARTUP sequence to - * bootstrap the CPUs, the APIC may be in a weird state. Kick it: - */ -static inline void numaq_smp_callin_clear_local_apic(void) -{ - clear_local_APIC(); -} - -static inline const cpumask_t *numaq_target_cpus(void) -{ - return &CPU_MASK_ALL; -} - -static inline unsigned long -numaq_check_apicid_used(physid_mask_t bitmap, int apicid) -{ - return physid_isset(apicid, bitmap); -} - -static inline unsigned long numaq_check_apicid_present(int bit) -{ - return physid_isset(bit, phys_cpu_present_map); -} - -static inline int numaq_apic_id_registered(void) -{ - return 1; -} - -static inline void numaq_init_apic_ldr(void) -{ - /* Already done in NUMA-Q firmware */ -} - -static inline void numaq_setup_apic_routing(void) -{ - printk(KERN_INFO - "Enabling APIC mode: NUMA-Q. Using %d I/O APICs\n", - nr_ioapics); -} - -/* - * Skip adding the timer int on secondary nodes, which causes - * a small but painful rift in the time-space continuum. - */ -static inline int numaq_multi_timer_check(int apic, int irq) -{ - return apic != 0 && irq == 0; -} - -static inline physid_mask_t numaq_ioapic_phys_id_map(physid_mask_t phys_map) -{ - /* We don't have a good way to do this yet - hack */ - return physids_promote(0xFUL); -} - -static inline int numaq_cpu_to_logical_apicid(int cpu) -{ - if (cpu >= nr_cpu_ids) - return BAD_APICID; - return cpu_2_logical_apicid[cpu]; -} - -/* - * Supporting over 60 cpus on NUMA-Q requires a locality-dependent - * cpu to APIC ID relation to properly interact with the intelligent - * mode of the cluster controller. - */ -static inline int numaq_cpu_present_to_apicid(int mps_cpu) -{ - if (mps_cpu < 60) - return ((mps_cpu >> 2) << 4) | (1 << (mps_cpu & 0x3)); - else - return BAD_APICID; -} - -static inline int numaq_apicid_to_node(int logical_apicid) -{ - return logical_apicid >> 4; -} - -static inline physid_mask_t numaq_apicid_to_cpu_present(int logical_apicid) -{ - int node = numaq_apicid_to_node(logical_apicid); - int cpu = __ffs(logical_apicid & 0xf); - - return physid_mask_of_physid(cpu + 4*node); -} - -/* Where the IO area was mapped on multiquad, always 0 otherwise */ -void *xquad_portio; - -static inline int numaq_check_phys_apicid_present(int boot_cpu_physical_apicid) -{ - return 1; -} - -/* - * We use physical apicids here, not logical, so just return the default - * physical broadcast to stop people from breaking us - */ -static inline unsigned int numaq_cpu_mask_to_apicid(const cpumask_t *cpumask) -{ - return 0x0F; -} - -static inline unsigned int -numaq_cpu_mask_to_apicid_and(const struct cpumask *cpumask, - const struct cpumask *andmask) -{ - return 0x0F; -} - -/* No NUMA-Q box has a HT CPU, but it can't hurt to use the default code. */ -static inline int numaq_phys_pkg_id(int cpuid_apic, int index_msb) -{ - return cpuid_apic >> index_msb; -} - -static int -numaq_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) -{ - if (strncmp(oem, "IBM NUMA", 8)) - printk(KERN_ERR "Warning! Not a NUMA-Q system!\n"); - else - found_numaq = 1; - - return found_numaq; -} - -static int probe_numaq(void) -{ - /* already know from get_memcfg_numaq() */ - return found_numaq; -} - -static void numaq_vector_allocation_domain(int cpu, cpumask_t *retmask) -{ - /* Careful. Some cpus do not strictly honor the set of cpus - * specified in the interrupt destination when using lowest - * priority interrupt delivery mode. - * - * In particular there was a hyperthreading cpu observed to - * deliver interrupts to the wrong hyperthread when only one - * hyperthread was specified in the interrupt desitination. - */ - *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } }; -} - -static void numaq_setup_portio_remap(void) -{ - int num_quads = num_online_nodes(); - - if (num_quads <= 1) - return; - - printk(KERN_INFO - "Remapping cross-quad port I/O for %d quads\n", num_quads); - - xquad_portio = ioremap(XQUAD_PORTIO_BASE, num_quads*XQUAD_PORTIO_QUAD); - - printk(KERN_INFO - "xquad_portio vaddr 0x%08lx, len %08lx\n", - (u_long) xquad_portio, (u_long) num_quads*XQUAD_PORTIO_QUAD); -} - -struct apic apic_numaq = { - - .name = "NUMAQ", - .probe = probe_numaq, - .acpi_madt_oem_check = NULL, - .apic_id_registered = numaq_apic_id_registered, - - .irq_delivery_mode = dest_LowestPrio, - /* physical delivery on LOCAL quad: */ - .irq_dest_mode = 0, - - .target_cpus = numaq_target_cpus, - .disable_esr = 1, - .dest_logical = APIC_DEST_LOGICAL, - .check_apicid_used = numaq_check_apicid_used, - .check_apicid_present = numaq_check_apicid_present, - - .vector_allocation_domain = numaq_vector_allocation_domain, - .init_apic_ldr = numaq_init_apic_ldr, - - .ioapic_phys_id_map = numaq_ioapic_phys_id_map, - .setup_apic_routing = numaq_setup_apic_routing, - .multi_timer_check = numaq_multi_timer_check, - .apicid_to_node = numaq_apicid_to_node, - .cpu_to_logical_apicid = numaq_cpu_to_logical_apicid, - .cpu_present_to_apicid = numaq_cpu_present_to_apicid, - .apicid_to_cpu_present = numaq_apicid_to_cpu_present, - .setup_portio_remap = numaq_setup_portio_remap, - .check_phys_apicid_present = numaq_check_phys_apicid_present, - .enable_apic_mode = NULL, - .phys_pkg_id = numaq_phys_pkg_id, - .mps_oem_check = numaq_mps_oem_check, - - .get_apic_id = numaq_get_apic_id, - .set_apic_id = NULL, - .apic_id_mask = 0x0F << 24, - - .cpu_mask_to_apicid = numaq_cpu_mask_to_apicid, - .cpu_mask_to_apicid_and = numaq_cpu_mask_to_apicid_and, - - .send_IPI_mask = numaq_send_IPI_mask, - .send_IPI_mask_allbutself = NULL, - .send_IPI_allbutself = numaq_send_IPI_allbutself, - .send_IPI_all = numaq_send_IPI_all, - .send_IPI_self = default_send_IPI_self, - - .wakeup_cpu = NULL, - .trampoline_phys_low = NUMAQ_TRAMPOLINE_PHYS_LOW, - .trampoline_phys_high = NUMAQ_TRAMPOLINE_PHYS_HIGH, - - /* We don't do anything here because we use NMI's to boot instead */ - .wait_for_init_deassert = NULL, - - .smp_callin_clear_local_apic = numaq_smp_callin_clear_local_apic, - .inquire_remote_apic = NULL, - - .read = native_apic_mem_read, - .write = native_apic_mem_write, - .icr_read = native_apic_icr_read, - .icr_write = native_apic_icr_write, - .wait_icr_idle = native_apic_wait_icr_idle, - .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, -}; diff --git a/arch/x86/kernel/probe_32.c b/arch/x86/kernel/probe_32.c deleted file mode 100644 index 5fa48332c5c..00000000000 --- a/arch/x86/kernel/probe_32.c +++ /dev/null @@ -1,424 +0,0 @@ -/* - * Default generic APIC driver. This handles up to 8 CPUs. - * - * Copyright 2003 Andi Kleen, SuSE Labs. - * Subject to the GNU Public License, v.2 - * - * Generic x86 APIC driver probe layer. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_HOTPLUG_CPU -#define DEFAULT_SEND_IPI (1) -#else -#define DEFAULT_SEND_IPI (0) -#endif - -int no_broadcast = DEFAULT_SEND_IPI; - -#ifdef CONFIG_X86_LOCAL_APIC - -void default_setup_apic_routing(void) -{ -#ifdef CONFIG_X86_IO_APIC - printk(KERN_INFO - "Enabling APIC mode: Flat. Using %d I/O APICs\n", - nr_ioapics); -#endif -} - -static void default_vector_allocation_domain(int cpu, struct cpumask *retmask) -{ - /* - * Careful. Some cpus do not strictly honor the set of cpus - * specified in the interrupt destination when using lowest - * priority interrupt delivery mode. - * - * In particular there was a hyperthreading cpu observed to - * deliver interrupts to the wrong hyperthread when only one - * hyperthread was specified in the interrupt desitination. - */ - *retmask = (cpumask_t) { { [0] = APIC_ALL_CPUS } }; -} - -/* should be called last. */ -static int probe_default(void) -{ - return 1; -} - -struct apic apic_default = { - - .name = "default", - .probe = probe_default, - .acpi_madt_oem_check = NULL, - .apic_id_registered = default_apic_id_registered, - - .irq_delivery_mode = dest_LowestPrio, - /* logical delivery broadcast to all CPUs: */ - .irq_dest_mode = 1, - - .target_cpus = default_target_cpus, - .disable_esr = 0, - .dest_logical = APIC_DEST_LOGICAL, - .check_apicid_used = default_check_apicid_used, - .check_apicid_present = default_check_apicid_present, - - .vector_allocation_domain = default_vector_allocation_domain, - .init_apic_ldr = default_init_apic_ldr, - - .ioapic_phys_id_map = default_ioapic_phys_id_map, - .setup_apic_routing = default_setup_apic_routing, - .multi_timer_check = NULL, - .apicid_to_node = default_apicid_to_node, - .cpu_to_logical_apicid = default_cpu_to_logical_apicid, - .cpu_present_to_apicid = default_cpu_present_to_apicid, - .apicid_to_cpu_present = default_apicid_to_cpu_present, - .setup_portio_remap = NULL, - .check_phys_apicid_present = default_check_phys_apicid_present, - .enable_apic_mode = NULL, - .phys_pkg_id = default_phys_pkg_id, - .mps_oem_check = NULL, - - .get_apic_id = default_get_apic_id, - .set_apic_id = NULL, - .apic_id_mask = 0x0F << 24, - - .cpu_mask_to_apicid = default_cpu_mask_to_apicid, - .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, - - .send_IPI_mask = default_send_IPI_mask_logical, - .send_IPI_mask_allbutself = default_send_IPI_mask_allbutself_logical, - .send_IPI_allbutself = default_send_IPI_allbutself, - .send_IPI_all = default_send_IPI_all, - .send_IPI_self = default_send_IPI_self, - - .wakeup_cpu = NULL, - .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, - .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, - - .wait_for_init_deassert = default_wait_for_init_deassert, - - .smp_callin_clear_local_apic = NULL, - .inquire_remote_apic = default_inquire_remote_apic, - - .read = native_apic_mem_read, - .write = native_apic_mem_write, - .icr_read = native_apic_icr_read, - .icr_write = native_apic_icr_write, - .wait_icr_idle = native_apic_wait_icr_idle, - .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, -}; - -extern struct apic apic_numaq; -extern struct apic apic_summit; -extern struct apic apic_bigsmp; -extern struct apic apic_es7000; -extern struct apic apic_default; - -struct apic *apic = &apic_default; -EXPORT_SYMBOL_GPL(apic); - -static struct apic *apic_probe[] __initdata = { -#ifdef CONFIG_X86_NUMAQ - &apic_numaq, -#endif -#ifdef CONFIG_X86_SUMMIT - &apic_summit, -#endif -#ifdef CONFIG_X86_BIGSMP - &apic_bigsmp, -#endif -#ifdef CONFIG_X86_ES7000 - &apic_es7000, -#endif - &apic_default, /* must be last */ - NULL, -}; - -static int cmdline_apic __initdata; -static int __init parse_apic(char *arg) -{ - int i; - - if (!arg) - return -EINVAL; - - for (i = 0; apic_probe[i]; i++) { - if (!strcmp(apic_probe[i]->name, arg)) { - apic = apic_probe[i]; - cmdline_apic = 1; - return 0; - } - } - - if (x86_quirks->update_apic) - x86_quirks->update_apic(); - - /* Parsed again by __setup for debug/verbose */ - return 0; -} -early_param("apic", parse_apic); - -void __init generic_bigsmp_probe(void) -{ -#ifdef CONFIG_X86_BIGSMP - /* - * This routine is used to switch to bigsmp mode when - * - There is no apic= option specified by the user - * - generic_apic_probe() has chosen apic_default as the sub_arch - * - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support - */ - - if (!cmdline_apic && apic == &apic_default) { - if (apic_bigsmp.probe()) { - apic = &apic_bigsmp; - if (x86_quirks->update_apic) - x86_quirks->update_apic(); - printk(KERN_INFO "Overriding APIC driver with %s\n", - apic->name); - } - } -#endif -} - -void __init generic_apic_probe(void) -{ - if (!cmdline_apic) { - int i; - for (i = 0; apic_probe[i]; i++) { - if (apic_probe[i]->probe()) { - apic = apic_probe[i]; - break; - } - } - /* Not visible without early console */ - if (!apic_probe[i]) - panic("Didn't find an APIC driver"); - - if (x86_quirks->update_apic) - x86_quirks->update_apic(); - } - printk(KERN_INFO "Using APIC driver %s\n", apic->name); -} - -/* These functions can switch the APIC even after the initial ->probe() */ - -int __init -generic_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) -{ - int i; - - for (i = 0; apic_probe[i]; ++i) { - if (!apic_probe[i]->mps_oem_check) - continue; - if (!apic_probe[i]->mps_oem_check(mpc, oem, productid)) - continue; - - if (!cmdline_apic) { - apic = apic_probe[i]; - if (x86_quirks->update_apic) - x86_quirks->update_apic(); - printk(KERN_INFO "Switched to APIC driver `%s'.\n", - apic->name); - } - return 1; - } - return 0; -} - -int __init default_acpi_madt_oem_check(char *oem_id, char *oem_table_id) -{ - int i; - - for (i = 0; apic_probe[i]; ++i) { - if (!apic_probe[i]->acpi_madt_oem_check) - continue; - if (!apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id)) - continue; - - if (!cmdline_apic) { - apic = apic_probe[i]; - if (x86_quirks->update_apic) - x86_quirks->update_apic(); - printk(KERN_INFO "Switched to APIC driver `%s'.\n", - apic->name); - } - return 1; - } - return 0; -} - -#endif /* CONFIG_X86_LOCAL_APIC */ - -/** - * pre_intr_init_hook - initialisation prior to setting up interrupt vectors - * - * Description: - * Perform any necessary interrupt initialisation prior to setting up - * the "ordinary" interrupt call gates. For legacy reasons, the ISA - * interrupts should be initialised here if the machine emulates a PC - * in any way. - **/ -void __init pre_intr_init_hook(void) -{ - if (x86_quirks->arch_pre_intr_init) { - if (x86_quirks->arch_pre_intr_init()) - return; - } - init_ISA_irqs(); -} - -/** - * intr_init_hook - post gate setup interrupt initialisation - * - * Description: - * Fill in any interrupts that may have been left out by the general - * init_IRQ() routine. interrupts having to do with the machine rather - * than the devices on the I/O bus (like APIC interrupts in intel MP - * systems) are started here. - **/ -void __init intr_init_hook(void) -{ - if (x86_quirks->arch_intr_init) { - if (x86_quirks->arch_intr_init()) - return; - } -} - -/** - * pre_setup_arch_hook - hook called prior to any setup_arch() execution - * - * Description: - * generally used to activate any machine specific identification - * routines that may be needed before setup_arch() runs. On Voyager - * this is used to get the board revision and type. - **/ -void __init pre_setup_arch_hook(void) -{ -} - -/** - * trap_init_hook - initialise system specific traps - * - * Description: - * Called as the final act of trap_init(). Used in VISWS to initialise - * the various board specific APIC traps. - **/ -void __init trap_init_hook(void) -{ - if (x86_quirks->arch_trap_init) { - if (x86_quirks->arch_trap_init()) - return; - } -} - -static struct irqaction irq0 = { - .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL, - .mask = CPU_MASK_NONE, - .name = "timer" -}; - -/** - * pre_time_init_hook - do any specific initialisations before. - * - **/ -void __init pre_time_init_hook(void) -{ - if (x86_quirks->arch_pre_time_init) - x86_quirks->arch_pre_time_init(); -} - -/** - * time_init_hook - do any specific initialisations for the system timer. - * - * Description: - * Must plug the system timer interrupt source at HZ into the IRQ listed - * in irq_vectors.h:TIMER_IRQ - **/ -void __init time_init_hook(void) -{ - if (x86_quirks->arch_time_init) { - /* - * A nonzero return code does not mean failure, it means - * that the architecture quirk does not want any - * generic (timer) setup to be performed after this: - */ - if (x86_quirks->arch_time_init()) - return; - } - - irq0.mask = cpumask_of_cpu(0); - setup_irq(0, &irq0); -} - -#ifdef CONFIG_MCA -/** - * mca_nmi_hook - hook into MCA specific NMI chain - * - * Description: - * The MCA (Microchannel Architecture) has an NMI chain for NMI sources - * along the MCA bus. Use this to hook into that chain if you will need - * it. - **/ -void mca_nmi_hook(void) -{ - /* - * If I recall correctly, there's a whole bunch of other things that - * we can do to check for NMI problems, but that's all I know about - * at the moment. - */ - pr_warning("NMI generated from unknown source!\n"); -} -#endif - -static __init int no_ipi_broadcast(char *str) -{ - get_option(&str, &no_broadcast); - pr_info("Using %s mode\n", - no_broadcast ? "No IPI Broadcast" : "IPI Broadcast"); - return 1; -} -__setup("no_ipi_broadcast=", no_ipi_broadcast); - -static int __init print_ipi_mode(void) -{ - pr_info("Using IPI %s mode\n", - no_broadcast ? "No-Shortcut" : "Shortcut"); - return 0; -} - -late_initcall(print_ipi_mode); - diff --git a/arch/x86/kernel/summit_32.c b/arch/x86/kernel/summit_32.c deleted file mode 100644 index cfe7b09015d..00000000000 --- a/arch/x86/kernel/summit_32.c +++ /dev/null @@ -1,601 +0,0 @@ -/* - * IBM Summit-Specific Code - * - * Written By: Matthew Dobson, IBM Corporation - * - * Copyright (c) 2003 IBM Corp. - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program 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, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Send feedback to - * - */ - -#include -#include -#include -#include - -/* - * APIC driver for the IBM "Summit" chipset. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static inline unsigned summit_get_apic_id(unsigned long x) -{ - return (x >> 24) & 0xFF; -} - -static inline void summit_send_IPI_mask(const cpumask_t *mask, int vector) -{ - default_send_IPI_mask_sequence_logical(mask, vector); -} - -static inline void summit_send_IPI_allbutself(int vector) -{ - cpumask_t mask = cpu_online_map; - cpu_clear(smp_processor_id(), mask); - - if (!cpus_empty(mask)) - summit_send_IPI_mask(&mask, vector); -} - -static inline void summit_send_IPI_all(int vector) -{ - summit_send_IPI_mask(&cpu_online_map, vector); -} - -#include - -extern int use_cyclone; - -#ifdef CONFIG_X86_SUMMIT_NUMA -extern void setup_summit(void); -#else -#define setup_summit() {} -#endif - -static inline int -summit_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) -{ - if (!strncmp(oem, "IBM ENSW", 8) && - (!strncmp(productid, "VIGIL SMP", 9) - || !strncmp(productid, "EXA", 3) - || !strncmp(productid, "RUTHLESS SMP", 12))){ - mark_tsc_unstable("Summit based system"); - use_cyclone = 1; /*enable cyclone-timer*/ - setup_summit(); - return 1; - } - return 0; -} - -/* Hook from generic ACPI tables.c */ -static inline int summit_acpi_madt_oem_check(char *oem_id, char *oem_table_id) -{ - if (!strncmp(oem_id, "IBM", 3) && - (!strncmp(oem_table_id, "SERVIGIL", 8) - || !strncmp(oem_table_id, "EXA", 3))){ - mark_tsc_unstable("Summit based system"); - use_cyclone = 1; /*enable cyclone-timer*/ - setup_summit(); - return 1; - } - return 0; -} - -struct rio_table_hdr { - unsigned char version; /* Version number of this data structure */ - /* Version 3 adds chassis_num & WP_index */ - unsigned char num_scal_dev; /* # of Scalability devices (Twisters for Vigil) */ - unsigned char num_rio_dev; /* # of RIO I/O devices (Cyclones and Winnipegs) */ -} __attribute__((packed)); - -struct scal_detail { - unsigned char node_id; /* Scalability Node ID */ - unsigned long CBAR; /* Address of 1MB register space */ - unsigned char port0node; /* Node ID port connected to: 0xFF=None */ - unsigned char port0port; /* Port num port connected to: 0,1,2, or 0xFF=None */ - unsigned char port1node; /* Node ID port connected to: 0xFF = None */ - unsigned char port1port; /* Port num port connected to: 0,1,2, or 0xFF=None */ - unsigned char port2node; /* Node ID port connected to: 0xFF = None */ - unsigned char port2port; /* Port num port connected to: 0,1,2, or 0xFF=None */ - unsigned char chassis_num; /* 1 based Chassis number (1 = boot node) */ -} __attribute__((packed)); - -struct rio_detail { - unsigned char node_id; /* RIO Node ID */ - unsigned long BBAR; /* Address of 1MB register space */ - unsigned char type; /* Type of device */ - unsigned char owner_id; /* For WPEG: Node ID of Cyclone that owns this WPEG*/ - /* For CYC: Node ID of Twister that owns this CYC */ - unsigned char port0node; /* Node ID port connected to: 0xFF=None */ - unsigned char port0port; /* Port num port connected to: 0,1,2, or 0xFF=None */ - unsigned char port1node; /* Node ID port connected to: 0xFF=None */ - unsigned char port1port; /* Port num port connected to: 0,1,2, or 0xFF=None */ - unsigned char first_slot; /* For WPEG: Lowest slot number below this WPEG */ - /* For CYC: 0 */ - unsigned char status; /* For WPEG: Bit 0 = 1 : the XAPIC is used */ - /* = 0 : the XAPIC is not used, ie:*/ - /* ints fwded to another XAPIC */ - /* Bits1:7 Reserved */ - /* For CYC: Bits0:7 Reserved */ - unsigned char WP_index; /* For WPEG: WPEG instance index - lower ones have */ - /* lower slot numbers/PCI bus numbers */ - /* For CYC: No meaning */ - unsigned char chassis_num; /* 1 based Chassis number */ - /* For LookOut WPEGs this field indicates the */ - /* Expansion Chassis #, enumerated from Boot */ - /* Node WPEG external port, then Boot Node CYC */ - /* external port, then Next Vigil chassis WPEG */ - /* external port, etc. */ - /* Shared Lookouts have only 1 chassis number (the */ - /* first one assigned) */ -} __attribute__((packed)); - - -typedef enum { - CompatTwister = 0, /* Compatibility Twister */ - AltTwister = 1, /* Alternate Twister of internal 8-way */ - CompatCyclone = 2, /* Compatibility Cyclone */ - AltCyclone = 3, /* Alternate Cyclone of internal 8-way */ - CompatWPEG = 4, /* Compatibility WPEG */ - AltWPEG = 5, /* Second Planar WPEG */ - LookOutAWPEG = 6, /* LookOut WPEG */ - LookOutBWPEG = 7, /* LookOut WPEG */ -} node_type; - -static inline int is_WPEG(struct rio_detail *rio){ - return (rio->type == CompatWPEG || rio->type == AltWPEG || - rio->type == LookOutAWPEG || rio->type == LookOutBWPEG); -} - - -/* In clustered mode, the high nibble of APIC ID is a cluster number. - * The low nibble is a 4-bit bitmap. */ -#define XAPIC_DEST_CPUS_SHIFT 4 -#define XAPIC_DEST_CPUS_MASK ((1u << XAPIC_DEST_CPUS_SHIFT) - 1) -#define XAPIC_DEST_CLUSTER_MASK (XAPIC_DEST_CPUS_MASK << XAPIC_DEST_CPUS_SHIFT) - -#define SUMMIT_APIC_DFR_VALUE (APIC_DFR_CLUSTER) - -static inline const cpumask_t *summit_target_cpus(void) -{ - /* CPU_MASK_ALL (0xff) has undefined behaviour with - * dest_LowestPrio mode logical clustered apic interrupt routing - * Just start on cpu 0. IRQ balancing will spread load - */ - return &cpumask_of_cpu(0); -} - -static inline unsigned long -summit_check_apicid_used(physid_mask_t bitmap, int apicid) -{ - return 0; -} - -/* we don't use the phys_cpu_present_map to indicate apicid presence */ -static inline unsigned long summit_check_apicid_present(int bit) -{ - return 1; -} - -static inline void summit_init_apic_ldr(void) -{ - unsigned long val, id; - int count = 0; - u8 my_id = (u8)hard_smp_processor_id(); - u8 my_cluster = APIC_CLUSTER(my_id); -#ifdef CONFIG_SMP - u8 lid; - int i; - - /* Create logical APIC IDs by counting CPUs already in cluster. */ - for (count = 0, i = nr_cpu_ids; --i >= 0; ) { - lid = cpu_2_logical_apicid[i]; - if (lid != BAD_APICID && APIC_CLUSTER(lid) == my_cluster) - ++count; - } -#endif - /* We only have a 4 wide bitmap in cluster mode. If a deranged - * BIOS puts 5 CPUs in one APIC cluster, we're hosed. */ - BUG_ON(count >= XAPIC_DEST_CPUS_SHIFT); - id = my_cluster | (1UL << count); - apic_write(APIC_DFR, SUMMIT_APIC_DFR_VALUE); - val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; - val |= SET_APIC_LOGICAL_ID(id); - apic_write(APIC_LDR, val); -} - -static inline int summit_apic_id_registered(void) -{ - return 1; -} - -static inline void summit_setup_apic_routing(void) -{ - printk("Enabling APIC mode: Summit. Using %d I/O APICs\n", - nr_ioapics); -} - -static inline int summit_apicid_to_node(int logical_apicid) -{ -#ifdef CONFIG_SMP - return apicid_2_node[hard_smp_processor_id()]; -#else - return 0; -#endif -} - -/* Mapping from cpu number to logical apicid */ -static inline int summit_cpu_to_logical_apicid(int cpu) -{ -#ifdef CONFIG_SMP - if (cpu >= nr_cpu_ids) - return BAD_APICID; - return cpu_2_logical_apicid[cpu]; -#else - return logical_smp_processor_id(); -#endif -} - -static inline int summit_cpu_present_to_apicid(int mps_cpu) -{ - if (mps_cpu < nr_cpu_ids) - return (int)per_cpu(x86_bios_cpu_apicid, mps_cpu); - else - return BAD_APICID; -} - -static inline physid_mask_t -summit_ioapic_phys_id_map(physid_mask_t phys_id_map) -{ - /* For clustered we don't have a good way to do this yet - hack */ - return physids_promote(0x0F); -} - -static inline physid_mask_t summit_apicid_to_cpu_present(int apicid) -{ - return physid_mask_of_physid(0); -} - -static inline void summit_setup_portio_remap(void) -{ -} - -static inline int summit_check_phys_apicid_present(int boot_cpu_physical_apicid) -{ - return 1; -} - -static inline unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask) -{ - int cpus_found = 0; - int num_bits_set; - int apicid; - int cpu; - - num_bits_set = cpus_weight(*cpumask); - /* Return id to all */ - if (num_bits_set >= nr_cpu_ids) - return 0xFF; - /* - * The cpus in the mask must all be on the apic cluster. If are not - * on the same apicid cluster return default value of target_cpus(): - */ - cpu = first_cpu(*cpumask); - apicid = summit_cpu_to_logical_apicid(cpu); - - while (cpus_found < num_bits_set) { - if (cpu_isset(cpu, *cpumask)) { - int new_apicid = summit_cpu_to_logical_apicid(cpu); - - if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { - printk ("%s: Not a valid mask!\n", __func__); - - return 0xFF; - } - apicid = apicid | new_apicid; - cpus_found++; - } - cpu++; - } - return apicid; -} - -static inline unsigned int -summit_cpu_mask_to_apicid_and(const struct cpumask *inmask, - const struct cpumask *andmask) -{ - int apicid = summit_cpu_to_logical_apicid(0); - cpumask_var_t cpumask; - - if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC)) - return apicid; - - cpumask_and(cpumask, inmask, andmask); - cpumask_and(cpumask, cpumask, cpu_online_mask); - apicid = summit_cpu_mask_to_apicid(cpumask); - - free_cpumask_var(cpumask); - - return apicid; -} - -/* - * cpuid returns the value latched in the HW at reset, not the APIC ID - * register's value. For any box whose BIOS changes APIC IDs, like - * clustered APIC systems, we must use hard_smp_processor_id. - * - * See Intel's IA-32 SW Dev's Manual Vol2 under CPUID. - */ -static inline int summit_phys_pkg_id(int cpuid_apic, int index_msb) -{ - return hard_smp_processor_id() >> index_msb; -} - -static int probe_summit(void) -{ - /* probed later in mptable/ACPI hooks */ - return 0; -} - -static void summit_vector_allocation_domain(int cpu, cpumask_t *retmask) -{ - /* Careful. Some cpus do not strictly honor the set of cpus - * specified in the interrupt destination when using lowest - * priority interrupt delivery mode. - * - * In particular there was a hyperthreading cpu observed to - * deliver interrupts to the wrong hyperthread when only one - * hyperthread was specified in the interrupt desitination. - */ - *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } }; -} - -#ifdef CONFIG_X86_SUMMIT_NUMA -static struct rio_table_hdr *rio_table_hdr __initdata; -static struct scal_detail *scal_devs[MAX_NUMNODES] __initdata; -static struct rio_detail *rio_devs[MAX_NUMNODES*4] __initdata; - -#ifndef CONFIG_X86_NUMAQ -static int mp_bus_id_to_node[MAX_MP_BUSSES] __initdata; -#endif - -static int __init setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus) -{ - int twister = 0, node = 0; - int i, bus, num_buses; - - for (i = 0; i < rio_table_hdr->num_rio_dev; i++) { - if (rio_devs[i]->node_id == rio_devs[wpeg_num]->owner_id) { - twister = rio_devs[i]->owner_id; - break; - } - } - if (i == rio_table_hdr->num_rio_dev) { - printk(KERN_ERR "%s: Couldn't find owner Cyclone for Winnipeg!\n", __func__); - return last_bus; - } - - for (i = 0; i < rio_table_hdr->num_scal_dev; i++) { - if (scal_devs[i]->node_id == twister) { - node = scal_devs[i]->node_id; - break; - } - } - if (i == rio_table_hdr->num_scal_dev) { - printk(KERN_ERR "%s: Couldn't find owner Twister for Cyclone!\n", __func__); - return last_bus; - } - - switch (rio_devs[wpeg_num]->type) { - case CompatWPEG: - /* - * The Compatibility Winnipeg controls the 2 legacy buses, - * the 66MHz PCI bus [2 slots] and the 2 "extra" buses in case - * a PCI-PCI bridge card is used in either slot: total 5 buses. - */ - num_buses = 5; - break; - case AltWPEG: - /* - * The Alternate Winnipeg controls the 2 133MHz buses [1 slot - * each], their 2 "extra" buses, the 100MHz bus [2 slots] and - * the "extra" buses for each of those slots: total 7 buses. - */ - num_buses = 7; - break; - case LookOutAWPEG: - case LookOutBWPEG: - /* - * A Lookout Winnipeg controls 3 100MHz buses [2 slots each] - * & the "extra" buses for each of those slots: total 9 buses. - */ - num_buses = 9; - break; - default: - printk(KERN_INFO "%s: Unsupported Winnipeg type!\n", __func__); - return last_bus; - } - - for (bus = last_bus; bus < last_bus + num_buses; bus++) - mp_bus_id_to_node[bus] = node; - return bus; -} - -static int __init build_detail_arrays(void) -{ - unsigned long ptr; - int i, scal_detail_size, rio_detail_size; - - if (rio_table_hdr->num_scal_dev > MAX_NUMNODES) { - printk(KERN_WARNING "%s: MAX_NUMNODES too low! Defined as %d, but system has %d nodes.\n", __func__, MAX_NUMNODES, rio_table_hdr->num_scal_dev); - return 0; - } - - switch (rio_table_hdr->version) { - default: - printk(KERN_WARNING "%s: Invalid Rio Grande Table Version: %d\n", __func__, rio_table_hdr->version); - return 0; - case 2: - scal_detail_size = 11; - rio_detail_size = 13; - break; - case 3: - scal_detail_size = 12; - rio_detail_size = 15; - break; - } - - ptr = (unsigned long)rio_table_hdr + 3; - for (i = 0; i < rio_table_hdr->num_scal_dev; i++, ptr += scal_detail_size) - scal_devs[i] = (struct scal_detail *)ptr; - - for (i = 0; i < rio_table_hdr->num_rio_dev; i++, ptr += rio_detail_size) - rio_devs[i] = (struct rio_detail *)ptr; - - return 1; -} - -void __init setup_summit(void) -{ - unsigned long ptr; - unsigned short offset; - int i, next_wpeg, next_bus = 0; - - /* The pointer to the EBDA is stored in the word @ phys 0x40E(40:0E) */ - ptr = get_bios_ebda(); - ptr = (unsigned long)phys_to_virt(ptr); - - rio_table_hdr = NULL; - offset = 0x180; - while (offset) { - /* The block id is stored in the 2nd word */ - if (*((unsigned short *)(ptr + offset + 2)) == 0x4752) { - /* set the pointer past the offset & block id */ - rio_table_hdr = (struct rio_table_hdr *)(ptr + offset + 4); - break; - } - /* The next offset is stored in the 1st word. 0 means no more */ - offset = *((unsigned short *)(ptr + offset)); - } - if (!rio_table_hdr) { - printk(KERN_ERR "%s: Unable to locate Rio Grande Table in EBDA - bailing!\n", __func__); - return; - } - - if (!build_detail_arrays()) - return; - - /* The first Winnipeg we're looking for has an index of 0 */ - next_wpeg = 0; - do { - for (i = 0; i < rio_table_hdr->num_rio_dev; i++) { - if (is_WPEG(rio_devs[i]) && rio_devs[i]->WP_index == next_wpeg) { - /* It's the Winnipeg we're looking for! */ - next_bus = setup_pci_node_map_for_wpeg(i, next_bus); - next_wpeg++; - break; - } - } - /* - * If we go through all Rio devices and don't find one with - * the next index, it means we've found all the Winnipegs, - * and thus all the PCI buses. - */ - if (i == rio_table_hdr->num_rio_dev) - next_wpeg = 0; - } while (next_wpeg != 0); -} -#endif - -struct apic apic_summit = { - - .name = "summit", - .probe = probe_summit, - .acpi_madt_oem_check = summit_acpi_madt_oem_check, - .apic_id_registered = summit_apic_id_registered, - - .irq_delivery_mode = dest_LowestPrio, - /* logical delivery broadcast to all CPUs: */ - .irq_dest_mode = 1, - - .target_cpus = summit_target_cpus, - .disable_esr = 1, - .dest_logical = APIC_DEST_LOGICAL, - .check_apicid_used = summit_check_apicid_used, - .check_apicid_present = summit_check_apicid_present, - - .vector_allocation_domain = summit_vector_allocation_domain, - .init_apic_ldr = summit_init_apic_ldr, - - .ioapic_phys_id_map = summit_ioapic_phys_id_map, - .setup_apic_routing = summit_setup_apic_routing, - .multi_timer_check = NULL, - .apicid_to_node = summit_apicid_to_node, - .cpu_to_logical_apicid = summit_cpu_to_logical_apicid, - .cpu_present_to_apicid = summit_cpu_present_to_apicid, - .apicid_to_cpu_present = summit_apicid_to_cpu_present, - .setup_portio_remap = NULL, - .check_phys_apicid_present = summit_check_phys_apicid_present, - .enable_apic_mode = NULL, - .phys_pkg_id = summit_phys_pkg_id, - .mps_oem_check = summit_mps_oem_check, - - .get_apic_id = summit_get_apic_id, - .set_apic_id = NULL, - .apic_id_mask = 0xFF << 24, - - .cpu_mask_to_apicid = summit_cpu_mask_to_apicid, - .cpu_mask_to_apicid_and = summit_cpu_mask_to_apicid_and, - - .send_IPI_mask = summit_send_IPI_mask, - .send_IPI_mask_allbutself = NULL, - .send_IPI_allbutself = summit_send_IPI_allbutself, - .send_IPI_all = summit_send_IPI_all, - .send_IPI_self = default_send_IPI_self, - - .wakeup_cpu = NULL, - .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, - .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, - - .wait_for_init_deassert = default_wait_for_init_deassert, - - .smp_callin_clear_local_apic = NULL, - .inquire_remote_apic = default_inquire_remote_apic, - - .read = native_apic_mem_read, - .write = native_apic_mem_write, - .icr_read = native_apic_icr_read, - .icr_write = native_apic_icr_write, - .wait_icr_idle = native_apic_wait_icr_idle, - .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, -}; -- cgit From a7eb518998529c08cc53fef17756d9fe433b0c23 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 17 Feb 2009 13:01:51 -0800 Subject: x86: truncate ISA addresses to unsigned int Impact: Cleanup; fix inappropriate macro use ISA addresses on x86 are mapped 1:1 with the physical address space. Since the ISA address space is only 24 bits (32 for VLB or LPC) it will always fit in an unsigned int, and at least in the aha1542 driver using a wider type would cause an undesirable promotion. Hence explicitly cast the ISA bus addresses to unsigned int. Signed-off-by: H. Peter Anvin Cc: James Bottomley --- arch/x86/include/asm/io.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index 4f8e820cf38..683d0b4c00f 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h @@ -124,10 +124,15 @@ static inline void *phys_to_virt(phys_addr_t address) /* * ISA I/O bus memory addresses are 1:1 with the physical address. + * However, we truncate the address to unsigned int to avoid undesirable + * promitions in legacy drivers. */ -#define isa_virt_to_bus (unsigned long)virt_to_phys -#define isa_page_to_bus page_to_phys -#define isa_bus_to_virt phys_to_virt +static inline unsigned int isa_virt_to_bus(volatile void *address) +{ + return (unsigned int)virt_to_phys(address); +} +#define isa_page_to_bus(page) ((unsigned int)page_to_phys(page)) +#define isa_bus_to_virt phys_to_virt /* * However PCI ones are not necessarily 1:1 and therefore these interfaces -- cgit From bf51935f3e988e0ed6f34b55593e5912f990750a Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Tue, 17 Feb 2009 06:01:30 -0800 Subject: x86, rcu: fix strange load average and ksoftirqd behavior Damien Wyart reported high ksoftirqd CPU usage (20%) on an otherwise idle system. The function-graph trace Damien provided: > 799.521187 | 1) -0 | | rcu_check_callbacks() { > 799.521371 | 1) -0 | | rcu_check_callbacks() { > 799.521555 | 1) -0 | | rcu_check_callbacks() { > 799.521738 | 1) -0 | | rcu_check_callbacks() { > 799.521934 | 1) -0 | | rcu_check_callbacks() { > 799.522068 | 1) ksoftir-2324 | | rcu_check_callbacks() { > 799.522208 | 1) -0 | | rcu_check_callbacks() { > 799.522392 | 1) -0 | | rcu_check_callbacks() { > 799.522575 | 1) -0 | | rcu_check_callbacks() { > 799.522759 | 1) -0 | | rcu_check_callbacks() { > 799.522956 | 1) -0 | | rcu_check_callbacks() { > 799.523074 | 1) ksoftir-2324 | | rcu_check_callbacks() { > 799.523214 | 1) -0 | | rcu_check_callbacks() { > 799.523397 | 1) -0 | | rcu_check_callbacks() { > 799.523579 | 1) -0 | | rcu_check_callbacks() { > 799.523762 | 1) -0 | | rcu_check_callbacks() { > 799.523960 | 1) -0 | | rcu_check_callbacks() { > 799.524079 | 1) ksoftir-2324 | | rcu_check_callbacks() { > 799.524220 | 1) -0 | | rcu_check_callbacks() { > 799.524403 | 1) -0 | | rcu_check_callbacks() { > 799.524587 | 1) -0 | | rcu_check_callbacks() { > 799.524770 | 1) -0 | | rcu_check_callbacks() { > [ . . . ] Shows rcu_check_callbacks() being invoked way too often. It should be called once per jiffy, and here it is called no less than 22 times in about 3.5 milliseconds, meaning one call every 160 microseconds or so. Why do we need to call rcu_pending() and rcu_check_callbacks() from the idle loop of 32-bit x86, especially given that no other architecture does this? The following patch removes the call to rcu_pending() and rcu_check_callbacks() from the x86 32-bit idle loop in order to reduce the softirq load on idle systems. Reported-by: Damien Wyart Signed-off-by: Paul E. McKenney Signed-off-by: Ingo Molnar --- arch/x86/kernel/process_32.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index a546f55c77b..bd4da2af08a 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -104,9 +104,6 @@ void cpu_idle(void) check_pgt_cache(); rmb(); - if (rcu_pending(cpu)) - rcu_check_callbacks(cpu, 0); - if (cpu_is_offline(cpu)) play_dead(); -- cgit From 1a88b5364b535edaa321d70a566e358390ff0872 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 16 Feb 2009 02:38:12 +0000 Subject: Fix incomplete __mntput locking Getting this wrong caused WARNING: at fs/namespace.c:636 mntput_no_expire+0xac/0xf2() due to optimistically checking cpu_writer->mnt outside the spinlock. Here's what we really want: * we know that nobody will set cpu_writer->mnt to mnt from now on * all changes to that sucker are done under cpu_writer->lock * we want the laziest equivalent of spin_lock(&cpu_writer->lock); if (likely(cpu_writer->mnt != mnt)) { spin_unlock(&cpu_writer->lock); continue; } /* do stuff */ that would make sure we won't miss earlier setting of ->mnt done by another CPU. Anyway, for now we just move the spin_lock() earlier and move the test into the properly locked region. Signed-off-by: Al Viro Reported-and-tested-by: Li Zefan Signed-off-by: Linus Torvalds --- fs/namespace.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index 228d8c4bfd1..06f8e63f6cb 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -614,9 +614,11 @@ static inline void __mntput(struct vfsmount *mnt) */ for_each_possible_cpu(cpu) { struct mnt_writer *cpu_writer = &per_cpu(mnt_writers, cpu); - if (cpu_writer->mnt != mnt) - continue; spin_lock(&cpu_writer->lock); + if (cpu_writer->mnt != mnt) { + spin_unlock(&cpu_writer->lock); + continue; + } atomic_add(cpu_writer->count, &mnt->__mnt_writers); cpu_writer->count = 0; /* -- cgit From ca77fde8e62cecb2c0769052228d15b901367af8 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 13 Feb 2009 23:18:03 +0000 Subject: Fix Intel IOMMU write-buffer flushing This is the cause of the DMA faults and disk corruption that people have been seeing. Some chipsets neglect to report the RWBF "capability" -- the flag which says that we need to flush the chipset write-buffer when changing the DMA page tables, to ensure that the change is visible to the IOMMU. Override that bit on the affected chipsets, and everything is happy again. Thanks to Chris and Bhavesh and others for helping to debug. Signed-off-by: David Woodhouse Tested-by: Chris Wright Reviewed-by: Bhavesh Davda Signed-off-by: Linus Torvalds --- drivers/pci/intel-iommu.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index f4b7c79023f..fa9e41626bf 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -61,6 +61,8 @@ /* global iommu list, set NULL for ignored DMAR units */ static struct intel_iommu **g_iommus; +static int rwbf_quirk = 0; + /* * 0: Present * 1-11: Reserved @@ -785,7 +787,7 @@ static void iommu_flush_write_buffer(struct intel_iommu *iommu) u32 val; unsigned long flag; - if (!cap_rwbf(iommu->cap)) + if (!rwbf_quirk && !cap_rwbf(iommu->cap)) return; val = iommu->gcmd | DMA_GCMD_WBF; @@ -3137,3 +3139,13 @@ static struct iommu_ops intel_iommu_ops = { .unmap = intel_iommu_unmap_range, .iova_to_phys = intel_iommu_iova_to_phys, }; + +static void __devinit quirk_iommu_rwbf(struct pci_dev *dev) +{ + /* Mobile 4 Series Chipset neglects to set RWBF capability, + but needs it */ + printk(KERN_INFO "DMAR: Forcing write-buffer flush capability\n"); + rwbf_quirk = 1; +} + +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf); -- cgit From 2f6097129af5625db2fb5e601f89e5bf55cd1dcd Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Mon, 16 Feb 2009 12:49:16 +0000 Subject: FRV: __pte_to_swp_entry doesn't expand correctly The macro doesn't expand correctly when its parameter isn't 'pte'. Signed-off-by: Roel Kluin Signed-off-by: David Howells Signed-off-by: Linus Torvalds --- include/asm-frv/pgtable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-frv/pgtable.h b/include/asm-frv/pgtable.h index 83c51aba534..e16fdb1f4f4 100644 --- a/include/asm-frv/pgtable.h +++ b/include/asm-frv/pgtable.h @@ -478,7 +478,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) #define __swp_type(x) (((x).val >> 2) & 0x1f) #define __swp_offset(x) ((x).val >> 8) #define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 8) }) -#define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte }) +#define __pte_to_swp_entry(_pte) ((swp_entry_t) { (_pte).pte }) #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) static inline int pte_file(pte_t pte) -- cgit From 9be1b56a3e718aa998772019c57c398dbb19e258 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 17 Feb 2009 23:12:48 +0100 Subject: x86, apic: separate 32-bit setup functionality out of apic_32.c Impact: build fix, cleanup A couple of arch setup callbacks were mistakenly in apic_32.c, breaking the build. Also simplify the code a bit. Signed-off-by: Ingo Molnar --- arch/x86/kernel/Makefile | 2 +- arch/x86/kernel/apic/Makefile | 3 +- arch/x86/kernel/apic/probe_32.c | 160 ++++------------------------------------ arch/x86/kernel/setup.c | 124 +++++++++++++++++++++++++++++++ 4 files changed, 142 insertions(+), 147 deletions(-) diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index c70537d8c15..de5657c039e 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -63,7 +63,7 @@ obj-$(CONFIG_SMP) += setup_percpu.o obj-$(CONFIG_X86_64_SMP) += tsc_sync.o obj-$(CONFIG_X86_TRAMPOLINE) += trampoline_$(BITS).o obj-$(CONFIG_X86_MPPARSE) += mpparse.o -obj-$(CONFIG_X86_LOCAL_APIC) += apic/ +obj-y += apic/ obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o diff --git a/arch/x86/kernel/apic/Makefile b/arch/x86/kernel/apic/Makefile index 97f558db5c3..da7b7b9f8bd 100644 --- a/arch/x86/kernel/apic/Makefile +++ b/arch/x86/kernel/apic/Makefile @@ -2,10 +2,9 @@ # Makefile for local APIC drivers and for the IO-APIC code # -obj-y := apic.o probe_$(BITS).o ipi.o nmi.o +obj-$(CONFIG_X86_LOCAL_APIC) += apic.o probe_$(BITS).o ipi.o nmi.o obj-$(CONFIG_X86_IO_APIC) += io_apic.o obj-$(CONFIG_SMP) += ipi.o -obj-$ ifeq ($(CONFIG_X86_64),y) obj-y += apic_flat_64.o diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c index 5fa48332c5c..c9ec90742e9 100644 --- a/arch/x86/kernel/apic/probe_32.c +++ b/arch/x86/kernel/apic/probe_32.c @@ -47,7 +47,22 @@ int no_broadcast = DEFAULT_SEND_IPI; -#ifdef CONFIG_X86_LOCAL_APIC +static __init int no_ipi_broadcast(char *str) +{ + get_option(&str, &no_broadcast); + pr_info("Using %s mode\n", + no_broadcast ? "No IPI Broadcast" : "IPI Broadcast"); + return 1; +} +__setup("no_ipi_broadcast=", no_ipi_broadcast); + +static int __init print_ipi_mode(void) +{ + pr_info("Using IPI %s mode\n", + no_broadcast ? "No-Shortcut" : "Shortcut"); + return 0; +} +late_initcall(print_ipi_mode); void default_setup_apic_routing(void) { @@ -279,146 +294,3 @@ int __init default_acpi_madt_oem_check(char *oem_id, char *oem_table_id) } return 0; } - -#endif /* CONFIG_X86_LOCAL_APIC */ - -/** - * pre_intr_init_hook - initialisation prior to setting up interrupt vectors - * - * Description: - * Perform any necessary interrupt initialisation prior to setting up - * the "ordinary" interrupt call gates. For legacy reasons, the ISA - * interrupts should be initialised here if the machine emulates a PC - * in any way. - **/ -void __init pre_intr_init_hook(void) -{ - if (x86_quirks->arch_pre_intr_init) { - if (x86_quirks->arch_pre_intr_init()) - return; - } - init_ISA_irqs(); -} - -/** - * intr_init_hook - post gate setup interrupt initialisation - * - * Description: - * Fill in any interrupts that may have been left out by the general - * init_IRQ() routine. interrupts having to do with the machine rather - * than the devices on the I/O bus (like APIC interrupts in intel MP - * systems) are started here. - **/ -void __init intr_init_hook(void) -{ - if (x86_quirks->arch_intr_init) { - if (x86_quirks->arch_intr_init()) - return; - } -} - -/** - * pre_setup_arch_hook - hook called prior to any setup_arch() execution - * - * Description: - * generally used to activate any machine specific identification - * routines that may be needed before setup_arch() runs. On Voyager - * this is used to get the board revision and type. - **/ -void __init pre_setup_arch_hook(void) -{ -} - -/** - * trap_init_hook - initialise system specific traps - * - * Description: - * Called as the final act of trap_init(). Used in VISWS to initialise - * the various board specific APIC traps. - **/ -void __init trap_init_hook(void) -{ - if (x86_quirks->arch_trap_init) { - if (x86_quirks->arch_trap_init()) - return; - } -} - -static struct irqaction irq0 = { - .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL, - .mask = CPU_MASK_NONE, - .name = "timer" -}; - -/** - * pre_time_init_hook - do any specific initialisations before. - * - **/ -void __init pre_time_init_hook(void) -{ - if (x86_quirks->arch_pre_time_init) - x86_quirks->arch_pre_time_init(); -} - -/** - * time_init_hook - do any specific initialisations for the system timer. - * - * Description: - * Must plug the system timer interrupt source at HZ into the IRQ listed - * in irq_vectors.h:TIMER_IRQ - **/ -void __init time_init_hook(void) -{ - if (x86_quirks->arch_time_init) { - /* - * A nonzero return code does not mean failure, it means - * that the architecture quirk does not want any - * generic (timer) setup to be performed after this: - */ - if (x86_quirks->arch_time_init()) - return; - } - - irq0.mask = cpumask_of_cpu(0); - setup_irq(0, &irq0); -} - -#ifdef CONFIG_MCA -/** - * mca_nmi_hook - hook into MCA specific NMI chain - * - * Description: - * The MCA (Microchannel Architecture) has an NMI chain for NMI sources - * along the MCA bus. Use this to hook into that chain if you will need - * it. - **/ -void mca_nmi_hook(void) -{ - /* - * If I recall correctly, there's a whole bunch of other things that - * we can do to check for NMI problems, but that's all I know about - * at the moment. - */ - pr_warning("NMI generated from unknown source!\n"); -} -#endif - -static __init int no_ipi_broadcast(char *str) -{ - get_option(&str, &no_broadcast); - pr_info("Using %s mode\n", - no_broadcast ? "No IPI Broadcast" : "IPI Broadcast"); - return 1; -} -__setup("no_ipi_broadcast=", no_ipi_broadcast); - -static int __init print_ipi_mode(void) -{ - pr_info("Using IPI %s mode\n", - no_broadcast ? "No-Shortcut" : "Shortcut"); - return 0; -} - -late_initcall(print_ipi_mode); - diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 6b588d6b388..ebef8005579 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -985,4 +985,128 @@ void __init setup_arch(char **cmdline_p) #endif } +#ifdef CONFIG_X86_32 + +/** + * pre_intr_init_hook - initialisation prior to setting up interrupt vectors + * + * Description: + * Perform any necessary interrupt initialisation prior to setting up + * the "ordinary" interrupt call gates. For legacy reasons, the ISA + * interrupts should be initialised here if the machine emulates a PC + * in any way. + **/ +void __init pre_intr_init_hook(void) +{ + if (x86_quirks->arch_pre_intr_init) { + if (x86_quirks->arch_pre_intr_init()) + return; + } + init_ISA_irqs(); +} + +/** + * intr_init_hook - post gate setup interrupt initialisation + * + * Description: + * Fill in any interrupts that may have been left out by the general + * init_IRQ() routine. interrupts having to do with the machine rather + * than the devices on the I/O bus (like APIC interrupts in intel MP + * systems) are started here. + **/ +void __init intr_init_hook(void) +{ + if (x86_quirks->arch_intr_init) { + if (x86_quirks->arch_intr_init()) + return; + } +} + +/** + * pre_setup_arch_hook - hook called prior to any setup_arch() execution + * + * Description: + * generally used to activate any machine specific identification + * routines that may be needed before setup_arch() runs. On Voyager + * this is used to get the board revision and type. + **/ +void __init pre_setup_arch_hook(void) +{ +} + +/** + * trap_init_hook - initialise system specific traps + * + * Description: + * Called as the final act of trap_init(). Used in VISWS to initialise + * the various board specific APIC traps. + **/ +void __init trap_init_hook(void) +{ + if (x86_quirks->arch_trap_init) { + if (x86_quirks->arch_trap_init()) + return; + } +} + +static struct irqaction irq0 = { + .handler = timer_interrupt, + .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL, + .mask = CPU_MASK_NONE, + .name = "timer" +}; + +/** + * pre_time_init_hook - do any specific initialisations before. + * + **/ +void __init pre_time_init_hook(void) +{ + if (x86_quirks->arch_pre_time_init) + x86_quirks->arch_pre_time_init(); +} + +/** + * time_init_hook - do any specific initialisations for the system timer. + * + * Description: + * Must plug the system timer interrupt source at HZ into the IRQ listed + * in irq_vectors.h:TIMER_IRQ + **/ +void __init time_init_hook(void) +{ + if (x86_quirks->arch_time_init) { + /* + * A nonzero return code does not mean failure, it means + * that the architecture quirk does not want any + * generic (timer) setup to be performed after this: + */ + if (x86_quirks->arch_time_init()) + return; + } + + irq0.mask = cpumask_of_cpu(0); + setup_irq(0, &irq0); +} + +#ifdef CONFIG_MCA +/** + * mca_nmi_hook - hook into MCA specific NMI chain + * + * Description: + * The MCA (Microchannel Architecture) has an NMI chain for NMI sources + * along the MCA bus. Use this to hook into that chain if you will need + * it. + **/ +void mca_nmi_hook(void) +{ + /* + * If I recall correctly, there's a whole bunch of other things that + * we can do to check for NMI problems, but that's all I know about + * at the moment. + */ + pr_warning("NMI generated from unknown source!\n"); +} +#endif /* CONFIG_MCA */ +#endif /* CONFIG_X86_32 */ -- cgit From fd4b9b3650076ffadbdd6e360eb198f5d61747c0 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Tue, 17 Feb 2009 20:45:50 +0100 Subject: [ARM] 5401/1: Orion: fix edge triggered GPIO interrupt support The GPIO interrupts can be configured as either level triggered or edge triggered, with a default of level triggered. When an edge triggered interrupt is requested, the gpio_irq_set_type method is called which currently switches the given IRQ descriptor between two struct irq_chip instances: orion_gpio_irq_level_chip and orion_gpio_irq_edge_chip. This happens via __setup_irq() which also calls irq_chip_set_defaults() to assign default methods to uninitialized ones. The problem is that irq_chip_set_defaults() is called before the irq_chip reference is switched, leaving the new irq_chip (orion_gpio_irq_edge_chip in this case) with uninitialized methods such as chip->startup() causing a kernel oops. Many solutions are possible, such as making irq_chip_set_defaults() global and calling it from gpio_irq_set_type(), or calling __irq_set_trigger() before irq_chip_set_defaults() in __setup_irq(). But those require modifications to the generic IRQ code which might have adverse effect on other architectures, and that would still be a fragile arrangement. Manually copying the missing methods from within gpio_irq_set_type() would be really ugly and it would break again the day new methods with automatic defaults are added. A better solution is to have a single irq_chip instance which can deal with both edge and level triggered interrupts. It is also a good idea to switch the IRQ handler instead, as the edge IRQ handler allows for one edge IRQ event to be queued as the IRQ is actually masked only when that second IRQ is received, at which point the hardware can queue an additional IRQ event, making edge triggered interrupts a bit more reliable. Tested-by: Martin Michlmayr Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/mach-kirkwood/irq.c | 2 +- arch/arm/mach-mv78xx0/irq.c | 2 +- arch/arm/mach-orion5x/irq.c | 2 +- arch/arm/plat-orion/gpio.c | 73 +++++++++++---------------------- arch/arm/plat-orion/include/plat/gpio.h | 3 +- 5 files changed, 29 insertions(+), 53 deletions(-) diff --git a/arch/arm/mach-kirkwood/irq.c b/arch/arm/mach-kirkwood/irq.c index efb86b70027..06083b23bb4 100644 --- a/arch/arm/mach-kirkwood/irq.c +++ b/arch/arm/mach-kirkwood/irq.c @@ -42,7 +42,7 @@ void __init kirkwood_init_irq(void) writel(0, GPIO_EDGE_CAUSE(32)); for (i = IRQ_KIRKWOOD_GPIO_START; i < NR_IRQS; i++) { - set_irq_chip(i, &orion_gpio_irq_level_chip); + set_irq_chip(i, &orion_gpio_irq_chip); set_irq_handler(i, handle_level_irq); irq_desc[i].status |= IRQ_LEVEL; set_irq_flags(i, IRQF_VALID); diff --git a/arch/arm/mach-mv78xx0/irq.c b/arch/arm/mach-mv78xx0/irq.c index e273418797b..30b7e4bcdbc 100644 --- a/arch/arm/mach-mv78xx0/irq.c +++ b/arch/arm/mach-mv78xx0/irq.c @@ -40,7 +40,7 @@ void __init mv78xx0_init_irq(void) writel(0, GPIO_EDGE_CAUSE(0)); for (i = IRQ_MV78XX0_GPIO_START; i < NR_IRQS; i++) { - set_irq_chip(i, &orion_gpio_irq_level_chip); + set_irq_chip(i, &orion_gpio_irq_chip); set_irq_handler(i, handle_level_irq); irq_desc[i].status |= IRQ_LEVEL; set_irq_flags(i, IRQF_VALID); diff --git a/arch/arm/mach-orion5x/irq.c b/arch/arm/mach-orion5x/irq.c index 0caae43301e..e03f7b45cb0 100644 --- a/arch/arm/mach-orion5x/irq.c +++ b/arch/arm/mach-orion5x/irq.c @@ -44,7 +44,7 @@ void __init orion5x_init_irq(void) * User can use set_type() if he wants to use edge types handlers. */ for (i = IRQ_ORION5X_GPIO_START; i < NR_IRQS; i++) { - set_irq_chip(i, &orion_gpio_irq_level_chip); + set_irq_chip(i, &orion_gpio_irq_chip); set_irq_handler(i, handle_level_irq); irq_desc[i].status |= IRQ_LEVEL; set_irq_flags(i, IRQF_VALID); diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c index 967186425ca..0d12c216476 100644 --- a/arch/arm/plat-orion/gpio.c +++ b/arch/arm/plat-orion/gpio.c @@ -265,51 +265,36 @@ EXPORT_SYMBOL(orion_gpio_set_blink); * polarity LEVEL mask * ****************************************************************************/ -static void gpio_irq_edge_ack(u32 irq) -{ - int pin = irq_to_gpio(irq); - - writel(~(1 << (pin & 31)), GPIO_EDGE_CAUSE(pin)); -} - -static void gpio_irq_edge_mask(u32 irq) -{ - int pin = irq_to_gpio(irq); - u32 u; - - u = readl(GPIO_EDGE_MASK(pin)); - u &= ~(1 << (pin & 31)); - writel(u, GPIO_EDGE_MASK(pin)); -} -static void gpio_irq_edge_unmask(u32 irq) +static void gpio_irq_ack(u32 irq) { - int pin = irq_to_gpio(irq); - u32 u; - - u = readl(GPIO_EDGE_MASK(pin)); - u |= 1 << (pin & 31); - writel(u, GPIO_EDGE_MASK(pin)); + int type = irq_desc[irq].status & IRQ_TYPE_SENSE_MASK; + if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { + int pin = irq_to_gpio(irq); + writel(~(1 << (pin & 31)), GPIO_EDGE_CAUSE(pin)); + } } -static void gpio_irq_level_mask(u32 irq) +static void gpio_irq_mask(u32 irq) { int pin = irq_to_gpio(irq); - u32 u; - - u = readl(GPIO_LEVEL_MASK(pin)); + int type = irq_desc[irq].status & IRQ_TYPE_SENSE_MASK; + u32 reg = (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) ? + GPIO_EDGE_MASK(pin) : GPIO_LEVEL_MASK(pin); + u32 u = readl(reg); u &= ~(1 << (pin & 31)); - writel(u, GPIO_LEVEL_MASK(pin)); + writel(u, reg); } -static void gpio_irq_level_unmask(u32 irq) +static void gpio_irq_unmask(u32 irq) { int pin = irq_to_gpio(irq); - u32 u; - - u = readl(GPIO_LEVEL_MASK(pin)); + int type = irq_desc[irq].status & IRQ_TYPE_SENSE_MASK; + u32 reg = (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) ? + GPIO_EDGE_MASK(pin) : GPIO_LEVEL_MASK(pin); + u32 u = readl(reg); u |= 1 << (pin & 31); - writel(u, GPIO_LEVEL_MASK(pin)); + writel(u, reg); } static int gpio_irq_set_type(u32 irq, u32 type) @@ -331,9 +316,9 @@ static int gpio_irq_set_type(u32 irq, u32 type) * Set edge/level type. */ if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { - desc->chip = &orion_gpio_irq_edge_chip; + desc->handle_irq = handle_edge_irq; } else if (type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { - desc->chip = &orion_gpio_irq_level_chip; + desc->handle_irq = handle_level_irq; } else { printk(KERN_ERR "failed to set irq=%d (type=%d)\n", irq, type); return -EINVAL; @@ -371,19 +356,11 @@ static int gpio_irq_set_type(u32 irq, u32 type) return 0; } -struct irq_chip orion_gpio_irq_edge_chip = { - .name = "orion_gpio_irq_edge", - .ack = gpio_irq_edge_ack, - .mask = gpio_irq_edge_mask, - .unmask = gpio_irq_edge_unmask, - .set_type = gpio_irq_set_type, -}; - -struct irq_chip orion_gpio_irq_level_chip = { - .name = "orion_gpio_irq_level", - .mask = gpio_irq_level_mask, - .mask_ack = gpio_irq_level_mask, - .unmask = gpio_irq_level_unmask, +struct irq_chip orion_gpio_irq_chip = { + .name = "orion_gpio", + .ack = gpio_irq_ack, + .mask = gpio_irq_mask, + .unmask = gpio_irq_unmask, .set_type = gpio_irq_set_type, }; diff --git a/arch/arm/plat-orion/include/plat/gpio.h b/arch/arm/plat-orion/include/plat/gpio.h index 54deaf274b5..ec743e82c87 100644 --- a/arch/arm/plat-orion/include/plat/gpio.h +++ b/arch/arm/plat-orion/include/plat/gpio.h @@ -31,8 +31,7 @@ void orion_gpio_set_blink(unsigned pin, int blink); /* * GPIO interrupt handling. */ -extern struct irq_chip orion_gpio_irq_edge_chip; -extern struct irq_chip orion_gpio_irq_level_chip; +extern struct irq_chip orion_gpio_irq_chip; void orion_gpio_irq_handler(int irqoff); -- cgit From 6ec68bff3c81e776a455f6aca95c8c5f1d630198 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 12 Feb 2009 13:39:26 +0100 Subject: x86, mce: reinitialize per cpu features on resume Impact: Bug fix This fixes a long standing bug in the machine check code. On resume the boot CPU wouldn't get its vendor specific state like thermal handling reinitialized. This means the boot cpu wouldn't ever get any thermal events reported again. Call the respective initialization functions on resume v2: Remove ancient init because they don't have a resume device anyways. Pointed out by Thomas Gleixner. v3: Now fix the Subject too to reflect v2 change Signed-off-by: Andi Kleen Acked-by: Thomas Gleixner Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/mcheck/mce_64.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index 1c838032fd3..1f184efb6bc 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -734,6 +734,7 @@ __setup("mce=", mcheck_enable); static int mce_resume(struct sys_device *dev) { mce_init(NULL); + mce_cpu_features(¤t_cpu_data); return 0; } -- cgit From 380851bc6b1b4107c61dfa2997f9095dcf779336 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 12 Feb 2009 13:39:33 +0100 Subject: x86, mce: use force_sig_info to kill process in machine check Impact: bug fix (with tolerant == 3) do_exit cannot be called directly from the exception handler because it can sleep and the exception handler runs on the exception stack. Use force_sig() instead. Based on a earlier patch by Ying Huang who debugged the problem. Signed-off-by: Andi Kleen Acked-by: Thomas Gleixner Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/mcheck/mce_64.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index 1f184efb6bc..25cf624eccb 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -295,11 +295,11 @@ void do_machine_check(struct pt_regs * regs, long error_code) * If we know that the error was in user space, send a * SIGBUS. Otherwise, panic if tolerance is low. * - * do_exit() takes an awful lot of locks and has a slight + * force_sig() takes an awful lot of locks and has a slight * risk of deadlocking. */ if (user_space) { - do_exit(SIGBUS); + force_sig(SIGBUS, current); } else if (panic_on_oops || tolerant < 2) { mce_panic("Uncorrected machine check", &panicm, mcestart); -- cgit From 07db1c140eb233971341396e492cc73d4280e698 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 12 Feb 2009 13:39:35 +0100 Subject: x86, mce: fix ifdef for 64bit thermal apic vector clear on shutdown Impact: Bugfix The ifdef for the apic clear on shutdown for the 64bit intel thermal vector was incorrect and never triggered. Fix that. Signed-off-by: Andi Kleen Acked-by: Thomas Gleixner Signed-off-by: H. Peter Anvin --- arch/x86/kernel/apic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c index 115449f869e..570f36e44e5 100644 --- a/arch/x86/kernel/apic.c +++ b/arch/x86/kernel/apic.c @@ -862,7 +862,7 @@ void clear_local_APIC(void) } /* lets not touch this if we didn't frob it */ -#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(X86_MCE_INTEL) +#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL) if (maxlvt >= 5) { v = apic_read(APIC_LVTTHMR); apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED); -- cgit From 973a2dd1d50a11d380086601f14e59116f93e8c5 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 12 Feb 2009 13:39:32 +0100 Subject: x86, mce: disable machine checks on suspend Impact: Bug fix During suspend it is not reliable to process machine check exceptions, because CPUs disappear but can still get machine check broadcasts. Also the system is slightly more likely to machine check them, but the handler is typically not a position to handle them in a meaningfull way. So disable them during suspend and enable them during resume. Also make sure they are always disabled on hot-unplugged CPUs. This new code assumes that suspend always hotunplugs all non BP CPUs. v2: Remove the WARN_ONs Thomas objected to. Signed-off-by: Andi Kleen Acked-by: Thomas Gleixner Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/mcheck/mce_64.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index 25cf624eccb..5ed80991ab9 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -728,6 +728,29 @@ __setup("mce=", mcheck_enable); * Sysfs support */ +/* + * Disable machine checks on suspend and shutdown. We can't really handle + * them later. + */ +static int mce_disable(void) +{ + int i; + + for (i = 0; i < banks; i++) + wrmsrl(MSR_IA32_MC0_CTL + i*4, 0); + return 0; +} + +static int mce_suspend(struct sys_device *dev, pm_message_t state) +{ + return mce_disable(); +} + +static int mce_shutdown(struct sys_device *dev) +{ + return mce_disable(); +} + /* On resume clear all MCE state. Don't want to see leftovers from the BIOS. Only one CPU is active at this time, the others get readded later using CPU hotplug. */ @@ -752,6 +775,8 @@ static void mce_restart(void) } static struct sysdev_class mce_sysclass = { + .suspend = mce_suspend, + .shutdown = mce_shutdown, .resume = mce_resume, .name = "machinecheck", }; -- cgit From 123aa76ec0cab5d4881cd8509faed43231e68801 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 12 Feb 2009 13:39:27 +0100 Subject: x86, mce: don't disable machine checks during code patching Impact: low priority bug fix This removes part of a a patch I added myself some time ago. After some consideration the patch was a bad idea. In particular it stopped machine check exceptions during code patching. To quote the comment: * MCEs only happen when something got corrupted and in this * case we must do something about the corruption. * Ignoring it is worse than a unlikely patching race. * Also machine checks tend to be broadcast and if one CPU * goes into machine check the others follow quickly, so we don't * expect a machine check to cause undue problems during to code * patching. So undo the machine check related parts of 8f4e956b313dcccbc7be6f10808952345e3b638c NMIs are still disabled. This only removes code, the only additions are a new comment. Signed-off-by: Andi Kleen Acked-by: Thomas Gleixner Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/mce.h | 2 -- arch/x86/kernel/alternative.c | 17 +++++++++++------ arch/x86/kernel/cpu/mcheck/mce_32.c | 14 -------------- arch/x86/kernel/cpu/mcheck/mce_64.c | 14 -------------- 4 files changed, 11 insertions(+), 36 deletions(-) diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index 32c6e17b960..5522273a3ad 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h @@ -120,8 +120,6 @@ extern void mcheck_init(struct cpuinfo_x86 *c); #else #define mcheck_init(c) do { } while (0) #endif -extern void stop_mce(void); -extern void restart_mce(void); #endif /* __KERNEL__ */ #endif /* _ASM_X86_MCE_H */ diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index a84ac7b570e..5b8394a3a6b 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -414,9 +414,17 @@ void __init alternative_instructions(void) that might execute the to be patched code. Other CPUs are not running. */ stop_nmi(); -#ifdef CONFIG_X86_MCE - stop_mce(); -#endif + + /* + * Don't stop machine check exceptions while patching. + * MCEs only happen when something got corrupted and in this + * case we must do something about the corruption. + * Ignoring it is worse than a unlikely patching race. + * Also machine checks tend to be broadcast and if one CPU + * goes into machine check the others follow quickly, so we don't + * expect a machine check to cause undue problems during to code + * patching. + */ apply_alternatives(__alt_instructions, __alt_instructions_end); @@ -456,9 +464,6 @@ void __init alternative_instructions(void) (unsigned long)__smp_locks_end); restart_nmi(); -#ifdef CONFIG_X86_MCE - restart_mce(); -#endif } /** diff --git a/arch/x86/kernel/cpu/mcheck/mce_32.c b/arch/x86/kernel/cpu/mcheck/mce_32.c index dfaebce3633..3552119b091 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_32.c +++ b/arch/x86/kernel/cpu/mcheck/mce_32.c @@ -60,20 +60,6 @@ void mcheck_init(struct cpuinfo_x86 *c) } } -static unsigned long old_cr4 __initdata; - -void __init stop_mce(void) -{ - old_cr4 = read_cr4(); - clear_in_cr4(X86_CR4_MCE); -} - -void __init restart_mce(void) -{ - if (old_cr4 & X86_CR4_MCE) - set_in_cr4(X86_CR4_MCE); -} - static int __init mcheck_disable(char *str) { mce_disabled = 1; diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index 5ed80991ab9..25ccdbec86e 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -680,20 +680,6 @@ static struct miscdevice mce_log_device = { &mce_chrdev_ops, }; -static unsigned long old_cr4 __initdata; - -void __init stop_mce(void) -{ - old_cr4 = read_cr4(); - clear_in_cr4(X86_CR4_MCE); -} - -void __init restart_mce(void) -{ - if (old_cr4 & X86_CR4_MCE) - set_in_cr4(X86_CR4_MCE); -} - /* * Old style boot options parsing. Only for compatibility. */ -- cgit From 9bd984058088d6ef7af6946591a207e51a2f4890 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 12 Feb 2009 13:39:28 +0100 Subject: x86, mce: always use separate work queue to run trigger Impact: Needed for bug fix in next patch This relaxes the requirement that mce_notify_user has to run in process context. Useful for future changes, but also leads to cleaner behaviour now. Now instead mce_notify_user can be called directly from interrupt (but not NMI) context. The work queue only uses a single global work struct, which can be done safely because it is always free to reuse before the trigger function is executed. This way no events can be lost. Signed-off-by: Andi Kleen Acked-by: Thomas Gleixner Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/mcheck/mce_64.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index 25ccdbec86e..18b379cf061 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -380,11 +380,17 @@ static void mcheck_timer(struct work_struct *work) schedule_delayed_work(&mcheck_work, next_interval); } +static void mce_do_trigger(struct work_struct *work) +{ + call_usermodehelper(trigger, trigger_argv, NULL, UMH_NO_WAIT); +} + +static DECLARE_WORK(mce_trigger_work, mce_do_trigger); + /* - * This is only called from process context. This is where we do - * anything we need to alert userspace about new MCEs. This is called - * directly from the poller and also from entry.S and idle, thanks to - * TIF_MCE_NOTIFY. + * Notify the user(s) about new machine check events. + * Can be called from interrupt context, but not from machine check/NMI + * context. */ int mce_notify_user(void) { @@ -394,9 +400,14 @@ int mce_notify_user(void) unsigned long now = jiffies; wake_up_interruptible(&mce_wait); - if (trigger[0]) - call_usermodehelper(trigger, trigger_argv, NULL, - UMH_NO_WAIT); + + /* + * There is no risk of missing notifications because + * work_pending is always cleared before the function is + * executed. + */ + if (trigger[0] && !work_pending(&mce_trigger_work)) + schedule_work(&mce_trigger_work); if (time_after_eq(now, last_print + (check_interval*HZ))) { last_print = now; -- cgit From 52d168e28bc11dd026b620fe1767cadde5a747cd Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 12 Feb 2009 13:39:29 +0100 Subject: x86, mce: switch machine check polling to per CPU timer Impact: Higher priority bug fix The machine check poller runs a single timer and then broadcasted an IPI to all CPUs to check them. This leads to unnecessary synchronization between CPUs. The original CPU running the timer has to wait potentially a long time for all other CPUs answering. This is also real time unfriendly and in general inefficient. This was especially a problem on systems with a lot of events where the poller run with a higher frequency after processing some events. There could be more and more CPU time wasted with this, to the point of significantly slowing down machines. The machine check polling is actually fully independent per CPU, so there's no reason to not just do this all with per CPU timers. This patch implements that. Also switch the poller also to use standard timers instead of work queues. It was using work queues to be able to execute a user program on a event, but mce_notify_user() handles this case now with a separate callback. So instead always run the poll code in in a standard per CPU timer, which means that in the common case of not having to execute a trigger there will be less overhead. This allows to clean up the initialization significantly, because standard timers are already up when machine checks get init'ed. No multiple initialization functions. Thanks to Thomas Gleixner for some help. Cc: thockin@google.com v2: Use del_timer_sync() on cpu shutdown and don't try to handle migrated timers. v3: Add WARN_ON for timer running on unexpected CPU Signed-off-by: Andi Kleen Acked-by: Thomas Gleixner Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/mcheck/mce_64.c | 68 ++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 23 deletions(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index 18b379cf061..3f0550d16f3 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -353,18 +353,17 @@ void mce_log_therm_throt_event(unsigned int cpu, __u64 status) static int check_interval = 5 * 60; /* 5 minutes */ static int next_interval; /* in jiffies */ -static void mcheck_timer(struct work_struct *work); -static DECLARE_DELAYED_WORK(mcheck_work, mcheck_timer); +static void mcheck_timer(unsigned long); +static DEFINE_PER_CPU(struct timer_list, mce_timer); -static void mcheck_check_cpu(void *info) +static void mcheck_timer(unsigned long data) { + struct timer_list *t = &per_cpu(mce_timer, data); + + WARN_ON(smp_processor_id() != data); + if (mce_available(¤t_cpu_data)) do_machine_check(NULL, 0); -} - -static void mcheck_timer(struct work_struct *work) -{ - on_each_cpu(mcheck_check_cpu, NULL, 1); /* * Alert userspace if needed. If we logged an MCE, reduce the @@ -377,7 +376,8 @@ static void mcheck_timer(struct work_struct *work) (int)round_jiffies_relative(check_interval*HZ)); } - schedule_delayed_work(&mcheck_work, next_interval); + t->expires = jiffies + next_interval; + add_timer(t); } static void mce_do_trigger(struct work_struct *work) @@ -436,16 +436,11 @@ static struct notifier_block mce_idle_notifier = { static __init int periodic_mcheck_init(void) { - next_interval = check_interval * HZ; - if (next_interval) - schedule_delayed_work(&mcheck_work, - round_jiffies_relative(next_interval)); - idle_notifier_register(&mce_idle_notifier); - return 0; + idle_notifier_register(&mce_idle_notifier); + return 0; } __initcall(periodic_mcheck_init); - /* * Initialize Machine Checks for a CPU. */ @@ -515,6 +510,20 @@ static void __cpuinit mce_cpu_features(struct cpuinfo_x86 *c) } } +static void mce_init_timer(void) +{ + struct timer_list *t = &__get_cpu_var(mce_timer); + + /* data race harmless because everyone sets to the same value */ + if (!next_interval) + next_interval = check_interval * HZ; + if (!next_interval) + return; + setup_timer(t, mcheck_timer, smp_processor_id()); + t->expires = round_jiffies_relative(jiffies + next_interval); + add_timer(t); +} + /* * Called for each booted CPU to set up machine checks. * Must be called with preempt off. @@ -529,6 +538,7 @@ void __cpuinit mcheck_init(struct cpuinfo_x86 *c) mce_init(NULL); mce_cpu_features(c); + mce_init_timer(); } /* @@ -758,17 +768,19 @@ static int mce_resume(struct sys_device *dev) return 0; } +static void mce_cpu_restart(void *data) +{ + del_timer_sync(&__get_cpu_var(mce_timer)); + if (mce_available(¤t_cpu_data)) + mce_init(NULL); + mce_init_timer(); +} + /* Reinit MCEs after user configuration changes */ static void mce_restart(void) { - if (next_interval) - cancel_delayed_work(&mcheck_work); - /* Timer race is harmless here */ - on_each_cpu(mce_init, NULL, 1); next_interval = check_interval * HZ; - if (next_interval) - schedule_delayed_work(&mcheck_work, - round_jiffies_relative(next_interval)); + on_each_cpu(mce_cpu_restart, NULL, 1); } static struct sysdev_class mce_sysclass = { @@ -899,6 +911,7 @@ static int __cpuinit mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; + struct timer_list *t = &per_cpu(mce_timer, cpu); switch (action) { case CPU_ONLINE: @@ -913,6 +926,15 @@ static int __cpuinit mce_cpu_callback(struct notifier_block *nfb, threshold_cpu_callback(action, cpu); mce_remove_device(cpu); break; + case CPU_DOWN_PREPARE: + case CPU_DOWN_PREPARE_FROZEN: + del_timer_sync(t); + break; + case CPU_DOWN_FAILED: + case CPU_DOWN_FAILED_FROZEN: + t->expires = round_jiffies_relative(jiffies + next_interval); + add_timer_on(t, cpu); + break; } return NOTIFY_OK; } -- cgit From 5b4408fdaa62474dd9485cddb9126370d90d4b82 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 12 Feb 2009 13:39:30 +0100 Subject: x86, mce: don't set up mce sysdev devices with mce=off Impact: bug fix, in this case the resume handler shouldn't run which avoids incorrectly reenabling machine checks on resume When MCEs are completely disabled on the command line don't set up the sysdev devices for them either. Includes a comment fix from Thomas Gleixner. Signed-off-by: Andi Kleen Acked-by: Thomas Gleixner Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/mcheck/mce_64.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index 3f0550d16f3..4e2b1bc5131 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -151,6 +151,8 @@ static void mce_panic(char *msg, struct mce *backup, unsigned long start) static int mce_available(struct cpuinfo_x86 *c) { + if (mce_dont_init) + return 0; return cpu_has(c, X86_FEATURE_MCE) && cpu_has(c, X86_FEATURE_MCA); } @@ -532,8 +534,7 @@ void __cpuinit mcheck_init(struct cpuinfo_x86 *c) { mce_cpu_quirks(c); - if (mce_dont_init || - !mce_available(c)) + if (!mce_available(c)) return; mce_init(NULL); @@ -710,8 +711,7 @@ static int __init mcheck_disable(char *str) return 1; } -/* mce=off disables machine check. Note you can re-enable it later - using sysfs. +/* mce=off disables machine check. mce=TOLERANCELEVEL (number, see above) mce=bootlog Log MCEs from before booting. Disabled by default on AMD. mce=nobootlog Don't log MCEs from before booting. */ -- cgit From d6b75584a3eaab8cb2ab3e8cf90c5e57c1928a85 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 12 Feb 2009 13:39:31 +0100 Subject: x86, mce: disable machine checks on offlined CPUs Impact: Lower priority bug fix Offlined CPUs could still get machine checks, but the machine check handler cannot handle them properly, leading to an unconditional crash. Disable machine checks on CPUs that are going down. Signed-off-by: Andi Kleen Acked-by: Thomas Gleixner Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/mcheck/mce_64.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index 4e2b1bc5131..1db94c0d5aa 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -906,6 +906,27 @@ static __cpuinit void mce_remove_device(unsigned int cpu) cpu_clear(cpu, mce_device_initialized); } +/* Make sure there are no machine checks on offlined CPUs. */ +static void __cpuexit mce_disable_cpu(void *h) +{ + int i; + + if (!mce_available(¤t_cpu_data)) + return; + for (i = 0; i < banks; i++) + wrmsrl(MSR_IA32_MC0_CTL + i*4, 0); +} + +static void __cpuexit mce_reenable_cpu(void *h) +{ + int i; + + if (!mce_available(¤t_cpu_data)) + return; + for (i = 0; i < banks; i++) + wrmsrl(MSR_IA32_MC0_CTL + i*4, bank[i]); +} + /* Get notified when a cpu comes on/off. Be hotplug friendly. */ static int __cpuinit mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) @@ -929,11 +950,13 @@ static int __cpuinit mce_cpu_callback(struct notifier_block *nfb, case CPU_DOWN_PREPARE: case CPU_DOWN_PREPARE_FROZEN: del_timer_sync(t); + smp_call_function_single(cpu, mce_disable_cpu, NULL, 1); break; case CPU_DOWN_FAILED: case CPU_DOWN_FAILED_FROZEN: t->expires = round_jiffies_relative(jiffies + next_interval); add_timer_on(t, cpu); + smp_call_function_single(cpu, mce_reenable_cpu, NULL, 1); break; } return NOTIFY_OK; -- cgit From ef41df4344ff952c79746d44a6126bd2cf7ed2bc Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Thu, 12 Feb 2009 13:39:34 +0100 Subject: x86, mce: fix a race condition in mce_read() Impact: bugfix Considering the situation as follow: before: mcelog.next == 1, mcelog.entry[0].finished = 1 +-------------------------------------------------------------------------- R W1 W2 W3 read mcelog.next (1) mcelog.next++ (2) (working on entry 1, finished == 0) mcelog.next = 0 mcelog.next++ (1) (working on entry 0) mcelog.next++ (2) (working on entry 1) <----------------- race ----------------> (done on entry 1, finished = 1) (done on entry 1, finished = 1) To fix the race condition, a cmpxchg loop is added to mce_read() to ensure no new MCE record can be added between mcelog.next reading and mcelog.next = 0. Signed-off-by: Huang Ying Signed-off-by: Andi Kleen Acked-by: Thomas Gleixner Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/mcheck/mce_64.c | 41 ++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index 1db94c0d5aa..870d08deccf 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -595,7 +595,7 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, { unsigned long *cpu_tsc; static DEFINE_MUTEX(mce_read_mutex); - unsigned next; + unsigned prev, next; char __user *buf = ubuf; int i, err; @@ -614,25 +614,32 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, } err = 0; - for (i = 0; i < next; i++) { - unsigned long start = jiffies; - - while (!mcelog.entry[i].finished) { - if (time_after_eq(jiffies, start + 2)) { - memset(mcelog.entry + i,0, sizeof(struct mce)); - goto timeout; + prev = 0; + do { + for (i = prev; i < next; i++) { + unsigned long start = jiffies; + + while (!mcelog.entry[i].finished) { + if (time_after_eq(jiffies, start + 2)) { + memset(mcelog.entry + i, 0, + sizeof(struct mce)); + goto timeout; + } + cpu_relax(); } - cpu_relax(); + smp_rmb(); + err |= copy_to_user(buf, mcelog.entry + i, + sizeof(struct mce)); + buf += sizeof(struct mce); +timeout: + ; } - smp_rmb(); - err |= copy_to_user(buf, mcelog.entry + i, sizeof(struct mce)); - buf += sizeof(struct mce); - timeout: - ; - } - memset(mcelog.entry, 0, next * sizeof(struct mce)); - mcelog.next = 0; + memset(mcelog.entry + prev, 0, + (next - prev) * sizeof(struct mce)); + prev = next; + next = cmpxchg(&mcelog.next, prev, 0); + } while (next != prev); synchronize_sched(); -- cgit From 3494252d5644993f407a45f01c3e8ad5ae38f93c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 13 Feb 2009 23:41:12 +0100 Subject: USB/PCI: Fix resume breakage of controllers behind cardbus bridges If a USB PCI controller is behind a cardbus bridge, we are trying to restore its configuration registers too early, before the cardbus bridge is operational. To fix this, call pci_restore_state() from usb_hcd_pci_resume() and remove usb_hcd_pci_resume_early() which is no longer necessary (the configuration spaces of USB controllers that are not behind cardbus bridges will be restored by the PCI PM core with interrupts disabled anyway). This patch fixes the regression from 2.6.28 tracked as http://bugzilla.kernel.org/show_bug.cgi?id=12659 [ Side note: the proper long-term fix is probably to just force the unplug event at suspend time instead of doing a plug/unplug at resume time, but this patch is fine regardless - Linus ] Signed-off-by: Rafael J. Wysocki Reported-by: Miles Lane Signed-off-by: Linus Torvalds --- drivers/usb/core/hcd-pci.c | 15 ++------------- drivers/usb/core/hcd.h | 1 - drivers/usb/host/ehci-pci.c | 1 - drivers/usb/host/ohci-pci.c | 1 - drivers/usb/host/uhci-hcd.c | 1 - 5 files changed, 2 insertions(+), 17 deletions(-) diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index c54fc40458b..a4301dc02d2 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -297,19 +297,6 @@ int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t message) } EXPORT_SYMBOL_GPL(usb_hcd_pci_suspend); -/** - * usb_hcd_pci_resume_early - resume a PCI-based HCD before IRQs are enabled - * @dev: USB Host Controller being resumed - * - * Store this function in the HCD's struct pci_driver as .resume_early. - */ -int usb_hcd_pci_resume_early(struct pci_dev *dev) -{ - pci_restore_state(dev); - return 0; -} -EXPORT_SYMBOL_GPL(usb_hcd_pci_resume_early); - /** * usb_hcd_pci_resume - power management resume of a PCI-based HCD * @dev: USB Host Controller being resumed @@ -333,6 +320,8 @@ int usb_hcd_pci_resume(struct pci_dev *dev) } #endif + pci_restore_state(dev); + hcd = pci_get_drvdata(dev); if (hcd->state != HC_STATE_SUSPENDED) { dev_dbg(hcd->self.controller, diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 5b94a56bec2..f750eb1ab59 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -257,7 +257,6 @@ extern void usb_hcd_pci_remove(struct pci_dev *dev); #ifdef CONFIG_PM extern int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t msg); -extern int usb_hcd_pci_resume_early(struct pci_dev *dev); extern int usb_hcd_pci_resume(struct pci_dev *dev); #endif /* CONFIG_PM */ diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index bb21fb0a496..abb9a7706ec 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -432,7 +432,6 @@ static struct pci_driver ehci_pci_driver = { #ifdef CONFIG_PM .suspend = usb_hcd_pci_suspend, - .resume_early = usb_hcd_pci_resume_early, .resume = usb_hcd_pci_resume, #endif .shutdown = usb_hcd_pci_shutdown, diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 5d625c3fd42..f9961b4c0da 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -487,7 +487,6 @@ static struct pci_driver ohci_pci_driver = { #ifdef CONFIG_PM .suspend = usb_hcd_pci_suspend, - .resume_early = usb_hcd_pci_resume_early, .resume = usb_hcd_pci_resume, #endif diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 944f7e0ca4d..cf5e4cf7ea4 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -942,7 +942,6 @@ static struct pci_driver uhci_pci_driver = { #ifdef CONFIG_PM .suspend = usb_hcd_pci_suspend, - .resume_early = usb_hcd_pci_resume_early, .resume = usb_hcd_pci_resume, #endif /* PM */ }; -- cgit From 5955c7a2cfb6a35429adea5dc480002b15ca8cfc Mon Sep 17 00:00:00 2001 From: Zlatko Calusic Date: Wed, 18 Feb 2009 01:33:34 +0100 Subject: Add support for VT6415 PCIE PATA IDE Host Controller Signed-off-by: Zlatko Calusic Signed-off-by: Linus Torvalds --- drivers/ata/pata_via.c | 4 +++- include/linux/pci_ids.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index 79a6c9a0b72..ba556d3e696 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -110,7 +110,8 @@ static const struct via_isa_bridge { { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA }, - { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES}, + { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES }, + { "vt6415", PCI_DEVICE_ID_VIA_6415, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES }, { "vt8237a", PCI_DEVICE_ID_VIA_8237A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, @@ -593,6 +594,7 @@ static int via_reinit_one(struct pci_dev *pdev) #endif static const struct pci_device_id via[] = { + { PCI_VDEVICE(VIA, 0x0415), }, { PCI_VDEVICE(VIA, 0x0571), }, { PCI_VDEVICE(VIA, 0x0581), }, { PCI_VDEVICE(VIA, 0x1571), }, diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 52a9fe08451..918391b4b10 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1312,6 +1312,7 @@ #define PCI_DEVICE_ID_VIA_VT3351 0x0351 #define PCI_DEVICE_ID_VIA_VT3364 0x0364 #define PCI_DEVICE_ID_VIA_8371_0 0x0391 +#define PCI_DEVICE_ID_VIA_6415 0x0415 #define PCI_DEVICE_ID_VIA_8501_0 0x0501 #define PCI_DEVICE_ID_VIA_82C561 0x0561 #define PCI_DEVICE_ID_VIA_82C586_1 0x0571 -- cgit From 92a0acce186cde8ead56c6915d9479773673ea1a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 17 Feb 2009 21:24:05 -0800 Subject: net: Kill skb_truesize_check(), it only catches false-positives. A long time ago we had bugs, primarily in TCP, where we would modify skb->truesize (for TSO queue collapsing) in ways which would corrupt the socket memory accounting. skb_truesize_check() was added in order to try and catch this error more systematically. However this debugging check has morphed into a Frankenstein of sorts and these days it does nothing other than catch false-positives. Signed-off-by: David S. Miller --- include/linux/skbuff.h | 9 --------- include/net/sock.h | 1 - net/core/skbuff.c | 8 -------- net/core/sock.c | 1 - 4 files changed, 19 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index cf2cb50f77d..9dcf956ad18 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -416,15 +416,6 @@ extern void skb_over_panic(struct sk_buff *skb, int len, void *here); extern void skb_under_panic(struct sk_buff *skb, int len, void *here); -extern void skb_truesize_bug(struct sk_buff *skb); - -static inline void skb_truesize_check(struct sk_buff *skb) -{ - int len = sizeof(struct sk_buff) + skb->len; - - if (unlikely((int)skb->truesize < len)) - skb_truesize_bug(skb); -} extern int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb, int getfrag(void *from, char *to, int offset, diff --git a/include/net/sock.h b/include/net/sock.h index ce3b5b62268..eefeeaf7fc4 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -860,7 +860,6 @@ static inline void sk_mem_uncharge(struct sock *sk, int size) static inline void sk_wmem_free_skb(struct sock *sk, struct sk_buff *skb) { - skb_truesize_check(skb); sock_set_flag(sk, SOCK_QUEUE_SHRUNK); sk->sk_wmem_queued -= skb->truesize; sk_mem_uncharge(sk, skb->truesize); diff --git a/net/core/skbuff.c b/net/core/skbuff.c index da74b844f4e..c6a6b166f8d 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -143,14 +143,6 @@ void skb_under_panic(struct sk_buff *skb, int sz, void *here) BUG(); } -void skb_truesize_bug(struct sk_buff *skb) -{ - WARN(net_ratelimit(), KERN_ERR "SKB BUG: Invalid truesize (%u) " - "len=%u, sizeof(sk_buff)=%Zd\n", - skb->truesize, skb->len, sizeof(struct sk_buff)); -} -EXPORT_SYMBOL(skb_truesize_bug); - /* Allocate a new skbuff. We do this ourselves so we can fill in a few * 'private' fields and also do memory statistics to find all the * [BEEP] leaks. diff --git a/net/core/sock.c b/net/core/sock.c index 6f2e1337975..6e4f14d1ef8 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1137,7 +1137,6 @@ void sock_rfree(struct sk_buff *skb) { struct sock *sk = skb->sk; - skb_truesize_check(skb); atomic_sub(skb->truesize, &sk->sk_rmem_alloc); sk_mem_uncharge(skb->sk, skb->truesize); } -- cgit From 444122fd58fdc83c96877a92b3f6288cafddb08d Mon Sep 17 00:00:00 2001 From: Yi Li Date: Thu, 5 Feb 2009 15:31:57 +0800 Subject: MMC: fix bug - SDHC card capacity not correct Signed-off-by: Yi Li Signed-off-by: Bryan Wu Signed-off-by: Pierre Ossman --- drivers/mmc/card/block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 45b1f430685..513eb09a638 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -584,7 +584,7 @@ static int mmc_blk_probe(struct mmc_card *card) if (err) goto out; - string_get_size(get_capacity(md->disk) << 9, STRING_UNITS_2, + string_get_size((u64)get_capacity(md->disk) << 9, STRING_UNITS_2, cap_str, sizeof(cap_str)); printk(KERN_INFO "%s: %s %s %s %s\n", md->disk->disk_name, mmc_card_id(card), mmc_card_name(card), -- cgit From 86a6a8749d5b8fd5c2b544fe9fd11101e3d0550f Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 2 Feb 2009 21:13:49 +0100 Subject: Revert "sdhci: force high speed capability on some controllers" This reverts commit a4b76193774b463b922cab2f92450efb20d29ef0. It turned out that the controller had problem running at the higher speed, so go back to trusting the hardware capability bits. Signed-off-by: Pierre Ossman --- drivers/mmc/host/sdhci-pci.c | 3 +-- drivers/mmc/host/sdhci.c | 3 +-- drivers/mmc/host/sdhci.h | 2 -- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index f07255cb17e..8cff5f5e7f8 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -144,8 +144,7 @@ static int jmicron_probe(struct sdhci_pci_chip *chip) SDHCI_QUIRK_32BIT_DMA_SIZE | SDHCI_QUIRK_32BIT_ADMA_SIZE | SDHCI_QUIRK_RESET_AFTER_REQUEST | - SDHCI_QUIRK_BROKEN_SMALL_PIO | - SDHCI_QUIRK_FORCE_HIGHSPEED; + SDHCI_QUIRK_BROKEN_SMALL_PIO; } /* diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 6b2d1f99af6..24d7414a331 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1636,8 +1636,7 @@ int sdhci_add_host(struct sdhci_host *host) mmc->f_max = host->max_clk; mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; - if ((caps & SDHCI_CAN_DO_HISPD) || - (host->quirks & SDHCI_QUIRK_FORCE_HIGHSPEED)) + if (caps & SDHCI_CAN_DO_HISPD) mmc->caps |= MMC_CAP_SD_HIGHSPEED; mmc->ocr_avail = 0; diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 3efba236394..ffeab227d95 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -208,8 +208,6 @@ struct sdhci_host { #define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL (1<<12) /* Controller has an issue with buffer bits for small transfers */ #define SDHCI_QUIRK_BROKEN_SMALL_PIO (1<<13) -/* Controller supports high speed but doesn't have the caps bit set */ -#define SDHCI_QUIRK_FORCE_HIGHSPEED (1<<14) int irq; /* Device IRQ */ void __iomem * ioaddr; /* Mapped address */ -- cgit From c1c201200a359cf3b6e2e36a4236cdca77a3cd8e Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Tue, 3 Feb 2009 07:47:29 +0100 Subject: bsg: Fix sense buffer bug in SG_IO When submitting requests via SG_IO, which does a sync io, a bsg_command is not allocated. So an in-Kernel sense_buffer was not set. However when calling blk_execute_rq() with no sense buffer one is provided from the stack. Now bsg at blk_complete_sgv4_hdr_rq() would check if rq->sense_len and a sense was requested by sg_io_v4 the rq->sense was copy_user() back, but by now it is already mangled stack memory. I have fixed that by forcing a sense_buffer when calling bsg_map_hdr(). The bsg_command->sense is provided in the write/read path like before, and on-the-stack buffer is provided when doing SG_IO. I have also fixed a dprintk message to print rq->errors in hex because of the scsi bit-field use of this member. For other block devices it does not matter anyway. Signed-off-by: Boaz Harrosh Acked-by: FUJITA Tomonori Signed-off-by: Jens Axboe --- block/bsg.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/block/bsg.c b/block/bsg.c index d414bb5607e..0ce8806dd0c 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -244,7 +244,8 @@ bsg_validate_sgv4_hdr(struct request_queue *q, struct sg_io_v4 *hdr, int *rw) * map sg_io_v4 to a request. */ static struct request * -bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm) +bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm, + u8 *sense) { struct request_queue *q = bd->queue; struct request *rq, *next_rq = NULL; @@ -306,6 +307,10 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm) if (ret) goto out; } + + rq->sense = sense; + rq->sense_len = 0; + return rq; out: if (rq->cmd != rq->__cmd) @@ -348,9 +353,6 @@ static void bsg_rq_end_io(struct request *rq, int uptodate) static void bsg_add_command(struct bsg_device *bd, struct request_queue *q, struct bsg_command *bc, struct request *rq) { - rq->sense = bc->sense; - rq->sense_len = 0; - /* * add bc command to busy queue and submit rq for io */ @@ -419,7 +421,7 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, { int ret = 0; - dprintk("rq %p bio %p %u\n", rq, bio, rq->errors); + dprintk("rq %p bio %p 0x%x\n", rq, bio, rq->errors); /* * fill in all the output members */ @@ -635,7 +637,7 @@ static int __bsg_write(struct bsg_device *bd, const char __user *buf, /* * get a request, fill in the blanks, and add to request queue */ - rq = bsg_map_hdr(bd, &bc->hdr, has_write_perm); + rq = bsg_map_hdr(bd, &bc->hdr, has_write_perm, bc->sense); if (IS_ERR(rq)) { ret = PTR_ERR(rq); rq = NULL; @@ -922,11 +924,12 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) struct request *rq; struct bio *bio, *bidi_bio = NULL; struct sg_io_v4 hdr; + u8 sense[SCSI_SENSE_BUFFERSIZE]; if (copy_from_user(&hdr, uarg, sizeof(hdr))) return -EFAULT; - rq = bsg_map_hdr(bd, &hdr, file->f_mode & FMODE_WRITE); + rq = bsg_map_hdr(bd, &hdr, file->f_mode & FMODE_WRITE, sense); if (IS_ERR(rq)) return PTR_ERR(rq); -- cgit From 93dbb393503d53cd226e5e1f0088fe8f4dbaa2b8 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 16 Feb 2009 10:25:40 +0100 Subject: block: fix bad definition of BIO_RW_SYNC We can't OR shift values, so get rid of BIO_RW_SYNC and use BIO_RW_SYNCIO and BIO_RW_UNPLUG explicitly. This brings back the behaviour from before 213d9417fec62ef4c3675621b9364a667954d4dd. Signed-off-by: Jens Axboe --- block/blktrace.c | 2 +- drivers/md/dm-io.c | 2 +- drivers/md/dm-kcopyd.c | 2 +- drivers/md/md.c | 4 ++-- include/linux/bio.h | 2 -- include/linux/blktrace_api.h | 1 + include/linux/fs.h | 6 +++--- kernel/power/swap.c | 5 +++-- mm/page_io.c | 2 +- 9 files changed, 13 insertions(+), 13 deletions(-) diff --git a/block/blktrace.c b/block/blktrace.c index 39cc3bfe56e..7cf9d1ff45a 100644 --- a/block/blktrace.c +++ b/block/blktrace.c @@ -142,7 +142,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, what |= ddir_act[rw & WRITE]; what |= MASK_TC_BIT(rw, BARRIER); - what |= MASK_TC_BIT(rw, SYNC); + what |= MASK_TC_BIT(rw, SYNCIO); what |= MASK_TC_BIT(rw, AHEAD); what |= MASK_TC_BIT(rw, META); what |= MASK_TC_BIT(rw, DISCARD); diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index a34338567a2..f14813be4ef 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c @@ -328,7 +328,7 @@ static void dispatch_io(int rw, unsigned int num_regions, struct dpages old_pages = *dp; if (sync) - rw |= (1 << BIO_RW_SYNC); + rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG); /* * For multiple regions we need to be careful to rewind diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c index 3073618269e..0a225da2127 100644 --- a/drivers/md/dm-kcopyd.c +++ b/drivers/md/dm-kcopyd.c @@ -344,7 +344,7 @@ static int run_io_job(struct kcopyd_job *job) { int r; struct dm_io_request io_req = { - .bi_rw = job->rw | (1 << BIO_RW_SYNC), + .bi_rw = job->rw | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG), .mem.type = DM_IO_PAGE_LIST, .mem.ptr.pl = job->pages, .mem.offset = job->offset, diff --git a/drivers/md/md.c b/drivers/md/md.c index 4495104f6c9..03b4cd0a634 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -474,7 +474,7 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, * causes ENOTSUPP, we allocate a spare bio... */ struct bio *bio = bio_alloc(GFP_NOIO, 1); - int rw = (1<bi_bdev = rdev->bdev; bio->bi_sector = sector; @@ -531,7 +531,7 @@ int sync_page_io(struct block_device *bdev, sector_t sector, int size, struct completion event; int ret; - rw |= (1 << BIO_RW_SYNC); + rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG); bio->bi_bdev = bdev; bio->bi_sector = sector; diff --git a/include/linux/bio.h b/include/linux/bio.h index 2aa283ab062..1b16108a541 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -171,8 +171,6 @@ struct bio { #define BIO_RW_FAILFAST_TRANSPORT 8 #define BIO_RW_FAILFAST_DRIVER 9 -#define BIO_RW_SYNC (BIO_RW_SYNCIO | BIO_RW_UNPLUG) - #define bio_rw_flagged(bio, flag) ((bio)->bi_rw & (1 << (flag))) /* diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h index 25379cba237..6e915878e88 100644 --- a/include/linux/blktrace_api.h +++ b/include/linux/blktrace_api.h @@ -15,6 +15,7 @@ enum blktrace_cat { BLK_TC_WRITE = 1 << 1, /* writes */ BLK_TC_BARRIER = 1 << 2, /* barrier */ BLK_TC_SYNC = 1 << 3, /* sync IO */ + BLK_TC_SYNCIO = BLK_TC_SYNC, BLK_TC_QUEUE = 1 << 4, /* queueing/merging */ BLK_TC_REQUEUE = 1 << 5, /* requeueing */ BLK_TC_ISSUE = 1 << 6, /* issue */ diff --git a/include/linux/fs.h b/include/linux/fs.h index 6022f44043f..67857dc1636 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -87,10 +87,10 @@ struct inodes_stat_t { #define WRITE 1 #define READA 2 /* read-ahead - don't block if no resources */ #define SWRITE 3 /* for ll_rw_block() - wait for buffer lock */ -#define READ_SYNC (READ | (1 << BIO_RW_SYNC)) +#define READ_SYNC (READ | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG)) #define READ_META (READ | (1 << BIO_RW_META)) -#define WRITE_SYNC (WRITE | (1 << BIO_RW_SYNC)) -#define SWRITE_SYNC (SWRITE | (1 << BIO_RW_SYNC)) +#define WRITE_SYNC (WRITE | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG)) +#define SWRITE_SYNC (SWRITE | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG)) #define WRITE_BARRIER (WRITE | (1 << BIO_RW_BARRIER)) #define DISCARD_NOBARRIER (1 << BIO_RW_DISCARD) #define DISCARD_BARRIER ((1 << BIO_RW_DISCARD) | (1 << BIO_RW_BARRIER)) diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 6da14358537..505f319e489 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c @@ -60,6 +60,7 @@ static struct block_device *resume_bdev; static int submit(int rw, pgoff_t page_off, struct page *page, struct bio **bio_chain) { + const int bio_rw = rw | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG); struct bio *bio; bio = bio_alloc(__GFP_WAIT | __GFP_HIGH, 1); @@ -80,7 +81,7 @@ static int submit(int rw, pgoff_t page_off, struct page *page, bio_get(bio); if (bio_chain == NULL) { - submit_bio(rw | (1 << BIO_RW_SYNC), bio); + submit_bio(bio_rw, bio); wait_on_page_locked(page); if (rw == READ) bio_set_pages_dirty(bio); @@ -90,7 +91,7 @@ static int submit(int rw, pgoff_t page_off, struct page *page, get_page(page); /* These pages are freed later */ bio->bi_private = *bio_chain; *bio_chain = bio; - submit_bio(rw | (1 << BIO_RW_SYNC), bio); + submit_bio(bio_rw, bio); } return 0; } diff --git a/mm/page_io.c b/mm/page_io.c index dc6ce0afbde..3023c475e04 100644 --- a/mm/page_io.c +++ b/mm/page_io.c @@ -111,7 +111,7 @@ int swap_writepage(struct page *page, struct writeback_control *wbc) goto out; } if (wbc->sync_mode == WB_SYNC_ALL) - rw |= (1 << BIO_RW_SYNC); + rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG); count_vm_event(PSWPOUT); set_page_writeback(page); unlock_page(page); -- cgit From a60e78e57a17d55bbd5a96da16fe9649d364b987 Mon Sep 17 00:00:00 2001 From: Subhash Peddamallu Date: Mon, 16 Feb 2009 10:27:07 +0100 Subject: fs/bio: bio_alloc_bioset: pass right object ptr to mempool_free When freeing from bio pool use right ptr to account for bs->front_pad, instead of bio ptr, Signed-off-by: Subhash Peddamallu Signed-off-by: Jens Axboe --- fs/bio.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/bio.c b/fs/bio.c index 062299acbcc..72ab251cdb9 100644 --- a/fs/bio.c +++ b/fs/bio.c @@ -302,9 +302,10 @@ void bio_init(struct bio *bio) struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) { struct bio *bio = NULL; + void *p; if (bs) { - void *p = mempool_alloc(bs->bio_pool, gfp_mask); + p = mempool_alloc(bs->bio_pool, gfp_mask); if (p) bio = p + bs->front_pad; @@ -329,7 +330,7 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) } if (unlikely(!bvl)) { if (bs) - mempool_free(bio, bs->bio_pool); + mempool_free(p, bs->bio_pool); else kfree(bio); bio = NULL; -- cgit From c8cbec6bdf6329279fd14696020f6b59d1d3124d Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Mon, 16 Feb 2009 13:11:55 +0100 Subject: paride/pg.c: xs(): &&/|| confusion &&/|| confusion Signed-off-by: Roel Kluin Cc: Bartlomiej Zolnierkiewicz Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- drivers/block/paride/pg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c index 9dfa2716300..c397b3ddba9 100644 --- a/drivers/block/paride/pg.c +++ b/drivers/block/paride/pg.c @@ -422,7 +422,7 @@ static void xs(char *buf, char *targ, int len) for (k = 0; k < len; k++) { char c = *buf++; - if (c != ' ' || c != l) + if (c != ' ' && c != l) l = *targ++ = c; } if (l == ' ') -- cgit From 82eb03cfd862a65363fa2826de0dbd5474cfe5e2 Mon Sep 17 00:00:00 2001 From: Chip Coldwell Date: Mon, 16 Feb 2009 13:11:56 +0100 Subject: cciss: PCI power management reset for kexec The kexec kernel resets the CCISS hardware in three steps: 1. Use PCI power management states to reset the controller in the kexec kernel. 2. Clear the MSI/MSI-X bits in PCI configuration space so that MSI initialization in the kexec kernel doesn't fail. 3. Use the CCISS "No-op" message to determine when the controller firmware has recovered from the PCI PM reset. [akpm@linux-foundation.org: cleanups] Signed-off-by: Mike Miller Cc: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 215 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 01e69383d9c..d2cb67b6117 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -3390,6 +3390,203 @@ static void free_hba(int i) kfree(p); } +/* Send a message CDB to the firmware. */ +static __devinit int cciss_message(struct pci_dev *pdev, unsigned char opcode, unsigned char type) +{ + typedef struct { + CommandListHeader_struct CommandHeader; + RequestBlock_struct Request; + ErrDescriptor_struct ErrorDescriptor; + } Command; + static const size_t cmd_sz = sizeof(Command) + sizeof(ErrorInfo_struct); + Command *cmd; + dma_addr_t paddr64; + uint32_t paddr32, tag; + void __iomem *vaddr; + int i, err; + + vaddr = ioremap_nocache(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); + if (vaddr == NULL) + return -ENOMEM; + + /* The Inbound Post Queue only accepts 32-bit physical addresses for the + CCISS commands, so they must be allocated from the lower 4GiB of + memory. */ + err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); + if (err) { + iounmap(vaddr); + return -ENOMEM; + } + + cmd = pci_alloc_consistent(pdev, cmd_sz, &paddr64); + if (cmd == NULL) { + iounmap(vaddr); + return -ENOMEM; + } + + /* This must fit, because of the 32-bit consistent DMA mask. Also, + although there's no guarantee, we assume that the address is at + least 4-byte aligned (most likely, it's page-aligned). */ + paddr32 = paddr64; + + cmd->CommandHeader.ReplyQueue = 0; + cmd->CommandHeader.SGList = 0; + cmd->CommandHeader.SGTotal = 0; + cmd->CommandHeader.Tag.lower = paddr32; + cmd->CommandHeader.Tag.upper = 0; + memset(&cmd->CommandHeader.LUN.LunAddrBytes, 0, 8); + + cmd->Request.CDBLen = 16; + cmd->Request.Type.Type = TYPE_MSG; + cmd->Request.Type.Attribute = ATTR_HEADOFQUEUE; + cmd->Request.Type.Direction = XFER_NONE; + cmd->Request.Timeout = 0; /* Don't time out */ + cmd->Request.CDB[0] = opcode; + cmd->Request.CDB[1] = type; + memset(&cmd->Request.CDB[2], 0, 14); /* the rest of the CDB is reserved */ + + cmd->ErrorDescriptor.Addr.lower = paddr32 + sizeof(Command); + cmd->ErrorDescriptor.Addr.upper = 0; + cmd->ErrorDescriptor.Len = sizeof(ErrorInfo_struct); + + writel(paddr32, vaddr + SA5_REQUEST_PORT_OFFSET); + + for (i = 0; i < 10; i++) { + tag = readl(vaddr + SA5_REPLY_PORT_OFFSET); + if ((tag & ~3) == paddr32) + break; + schedule_timeout_uninterruptible(HZ); + } + + iounmap(vaddr); + + /* we leak the DMA buffer here ... no choice since the controller could + still complete the command. */ + if (i == 10) { + printk(KERN_ERR "cciss: controller message %02x:%02x timed out\n", + opcode, type); + return -ETIMEDOUT; + } + + pci_free_consistent(pdev, cmd_sz, cmd, paddr64); + + if (tag & 2) { + printk(KERN_ERR "cciss: controller message %02x:%02x failed\n", + opcode, type); + return -EIO; + } + + printk(KERN_INFO "cciss: controller message %02x:%02x succeeded\n", + opcode, type); + return 0; +} + +#define cciss_soft_reset_controller(p) cciss_message(p, 1, 0) +#define cciss_noop(p) cciss_message(p, 3, 0) + +static __devinit int cciss_reset_msi(struct pci_dev *pdev) +{ +/* the #defines are stolen from drivers/pci/msi.h. */ +#define msi_control_reg(base) (base + PCI_MSI_FLAGS) +#define PCI_MSIX_FLAGS_ENABLE (1 << 15) + + int pos; + u16 control = 0; + + pos = pci_find_capability(pdev, PCI_CAP_ID_MSI); + if (pos) { + pci_read_config_word(pdev, msi_control_reg(pos), &control); + if (control & PCI_MSI_FLAGS_ENABLE) { + printk(KERN_INFO "cciss: resetting MSI\n"); + pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSI_FLAGS_ENABLE); + } + } + + pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); + if (pos) { + pci_read_config_word(pdev, msi_control_reg(pos), &control); + if (control & PCI_MSIX_FLAGS_ENABLE) { + printk(KERN_INFO "cciss: resetting MSI-X\n"); + pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSIX_FLAGS_ENABLE); + } + } + + return 0; +} + +/* This does a hard reset of the controller using PCI power management + * states. */ +static __devinit int cciss_hard_reset_controller(struct pci_dev *pdev) +{ + u16 pmcsr, saved_config_space[32]; + int i, pos; + + printk(KERN_INFO "cciss: using PCI PM to reset controller\n"); + + /* This is very nearly the same thing as + + pci_save_state(pci_dev); + pci_set_power_state(pci_dev, PCI_D3hot); + pci_set_power_state(pci_dev, PCI_D0); + pci_restore_state(pci_dev); + + but we can't use these nice canned kernel routines on + kexec, because they also check the MSI/MSI-X state in PCI + configuration space and do the wrong thing when it is + set/cleared. Also, the pci_save/restore_state functions + violate the ordering requirements for restoring the + configuration space from the CCISS document (see the + comment below). So we roll our own .... */ + + for (i = 0; i < 32; i++) + pci_read_config_word(pdev, 2*i, &saved_config_space[i]); + + pos = pci_find_capability(pdev, PCI_CAP_ID_PM); + if (pos == 0) { + printk(KERN_ERR "cciss_reset_controller: PCI PM not supported\n"); + return -ENODEV; + } + + /* Quoting from the Open CISS Specification: "The Power + * Management Control/Status Register (CSR) controls the power + * state of the device. The normal operating state is D0, + * CSR=00h. The software off state is D3, CSR=03h. To reset + * the controller, place the interface device in D3 then to + * D0, this causes a secondary PCI reset which will reset the + * controller." */ + + /* enter the D3hot power management state */ + pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr); + pmcsr &= ~PCI_PM_CTRL_STATE_MASK; + pmcsr |= PCI_D3hot; + pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); + + schedule_timeout_uninterruptible(HZ >> 1); + + /* enter the D0 power management state */ + pmcsr &= ~PCI_PM_CTRL_STATE_MASK; + pmcsr |= PCI_D0; + pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); + + schedule_timeout_uninterruptible(HZ >> 1); + + /* Restore the PCI configuration space. The Open CISS + * Specification says, "Restore the PCI Configuration + * Registers, offsets 00h through 60h. It is important to + * restore the command register, 16-bits at offset 04h, + * last. Do not restore the configuration status register, + * 16-bits at offset 06h." Note that the offset is 2*i. */ + for (i = 0; i < 32; i++) { + if (i == 2 || i == 3) + continue; + pci_write_config_word(pdev, 2*i, saved_config_space[i]); + } + wmb(); + pci_write_config_word(pdev, 4, saved_config_space[2]); + + return 0; +} + /* * This is it. Find all the controllers and register them. I really hate * stealing all these major device numbers. @@ -3404,6 +3601,24 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, int dac, return_code; InquiryData_struct *inq_buff = NULL; + if (reset_devices) { + /* Reset the controller with a PCI power-cycle */ + if (cciss_hard_reset_controller(pdev) || cciss_reset_msi(pdev)) + return -ENODEV; + + /* Some devices (notably the HP Smart Array 5i Controller) + need a little pause here */ + schedule_timeout_uninterruptible(30*HZ); + + /* Now try to get the controller to respond to a no-op */ + for (i=0; i<12; i++) { + if (cciss_noop(pdev) == 0) + break; + else + printk("cciss: no-op failed%s\n", (i < 11 ? "; re-trying" : "")); + } + } + i = alloc_cciss_hba(); if (i < 0) return -1; -- cgit From 78f707bfc723552e8309b7c38a8d0cc51012e813 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 17 Feb 2009 13:59:08 +0100 Subject: block: revert part of 18ce3751ccd488c78d3827e9f6bf54e6322676fb The above commit added WRITE_SYNC and switched various places to using that for committing writes that will be waited upon immediately after submission. However, this causes a performance regression with AS and CFQ for ext3 at least, since sync_dirty_buffer() will submit some writes with WRITE_SYNC while ext3 has sumitted others dependent writes without the sync flag set. This causes excessive anticipation/idling in the IO scheduler because sync and async writes get interleaved, causing a big performance regression for the below test case (which is meant to simulate sqlite like behaviour). ---- test case ---- int main(int argc, char **argv) { int fdes, i; FILE *fp; struct timeval start; struct timeval end; struct timeval res; gettimeofday(&start, NULL); for (i=0; i --- fs/buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/buffer.c b/fs/buffer.c index 665d446b25b..62b57e330b6 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -3108,7 +3108,7 @@ int sync_dirty_buffer(struct buffer_head *bh) if (test_clear_buffer_dirty(bh)) { get_bh(bh); bh->b_end_io = end_buffer_write_sync; - ret = submit_bh(WRITE_SYNC, bh); + ret = submit_bh(WRITE, bh); wait_on_buffer(bh); if (buffer_eopnotsupp(bh)) { clear_buffer_eopnotsupp(bh); -- cgit From 41b8c853a495438208faa5be03bbb0050859163b Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Wed, 18 Feb 2009 10:33:59 +0100 Subject: block: fix booting from partitioned md array Hi Tejun, it looks like your commit: block: don't depend on consecutive minor space f331c0296f2a9fee0d396a70598b954062603015 broke a particular case for booting from partitioned md/raid devices. That is the second time this has been broken recently. The previous time was fixed by block: do_mounts - accept root= 30f2f0eb4bd2c43d10a8b0d872c6e5ad8f31c9a0 Because the data isn't available when an md device is first created (we add disks and set it up after creation), the initial partition scan finds nothing. It is not until the device is opened that another partition scan happens and finds something. So at the point where the kernel parameter "root=/dev/md_d0p1" is being parsed, md_d0 exists, but md_d0p1 does not. However if we let blk_lookup_devt return the correct device number even though the device doesn't exist, then the attempt to mount it will successfully find the partition. I have tried in the past to find a way to get the partition table to be read as soon as the array is assembled but that proved impossible (at the time). I don't remember the details, and could possibly revisit it. However it would be really nice if blk_lookup_devt could be adjusted to again accept non existant partitions. Signed-off-by: Jens Axboe --- block/genhd.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/block/genhd.c b/block/genhd.c index 397960cf26a..e1eadcc9546 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -1087,6 +1087,14 @@ dev_t blk_lookup_devt(const char *name, int partno) if (strcmp(dev_name(dev), name)) continue; + if (partno < disk->minors) { + /* We need to return the right devno, even + * if the partition doesn't exist yet. + */ + devt = MKDEV(MAJOR(dev->devt), + MINOR(dev->devt) + partno); + break; + } part = disk_get_part(disk, partno); if (part) { devt = part_devt(part); -- cgit From be987fdb55a4726e2fcbab7501f89276bdb57288 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 18 Feb 2009 10:30:15 +0100 Subject: block: fix deadlock in blk_abort_queue() for drivers that readd to timeout list blk_abort_queue() iterates the timeout list and aborts each request on the list, but if the driver error handling readds a request to the timeout list during this processing, we could be looping forever. Fix this by splicing current entries to a local list and run over that list instead. Signed-off-by: Jens Axboe --- block/blk-timeout.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/block/blk-timeout.c b/block/blk-timeout.c index a09535377a9..bbbdc4b8ccf 100644 --- a/block/blk-timeout.c +++ b/block/blk-timeout.c @@ -209,12 +209,19 @@ void blk_abort_queue(struct request_queue *q) { unsigned long flags; struct request *rq, *tmp; + LIST_HEAD(list); spin_lock_irqsave(q->queue_lock, flags); elv_abort_queue(q); - list_for_each_entry_safe(rq, tmp, &q->timeout_list, timeout_list) + /* + * Splice entries to local list, to avoid deadlocking if entries + * get readded to the timeout list by error handling + */ + list_splice_init(&q->timeout_list, &list); + + list_for_each_entry_safe(rq, tmp, &list, timeout_list) blk_abort_request(rq); spin_unlock_irqrestore(q->queue_lock, flags); -- cgit From 4aa3b2ee1945ed082430ae1fb988d60eef64ca07 Mon Sep 17 00:00:00 2001 From: Eric Leblond Date: Wed, 18 Feb 2009 15:28:46 +0100 Subject: netfilter: nf_conntrack_ipv6: fix nf_log_packet message in icmpv6 conntrack This patch fixes a trivial typo that was adding a new line at end of the nf_log_packet() prefix. It also make the logging conditionnal by adding a LOG_INVALID test. Signed-off-by: Eric Leblond Signed-off-by: Patrick McHardy --- net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index c323643ffcf..72dbb6d1a6b 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c @@ -201,8 +201,9 @@ icmpv6_error(struct net *net, struct sk_buff *skb, unsigned int dataoff, if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING && nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) { - nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, - "nf_ct_icmpv6: ICMPv6 checksum failed\n"); + if (LOG_INVALID(net, IPPROTO_ICMPV6)) + nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, + "nf_ct_icmpv6: ICMPv6 checksum failed "); return -NF_ACCEPT; } -- cgit From 5ca431f9ae8db8c6edb9c64bebe6d6521077afd6 Mon Sep 17 00:00:00 2001 From: Eric Leblond Date: Wed, 18 Feb 2009 15:29:23 +0100 Subject: netfilter: nfnetlink_log: fix per-rule qthreshold override In NFLOG the per-rule qthreshold should overrides per-instance only it is set. With current code, the per-rule qthreshold is 1 if not set and it overrides the per-instance qthreshold. This patch modifies the default xt_NFLOG threshold from 1 to 0. Thus a value of 0 means there is no per-rule setting and the instance parameter has to apply. Signed-off-by: Eric Leblond Signed-off-by: Patrick McHardy --- include/linux/netfilter/xt_NFLOG.h | 2 +- net/netfilter/nfnetlink_log.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/linux/netfilter/xt_NFLOG.h b/include/linux/netfilter/xt_NFLOG.h index cdcd0ed58f7..4b36aeb46a1 100644 --- a/include/linux/netfilter/xt_NFLOG.h +++ b/include/linux/netfilter/xt_NFLOG.h @@ -2,7 +2,7 @@ #define _XT_NFLOG_TARGET #define XT_NFLOG_DEFAULT_GROUP 0x1 -#define XT_NFLOG_DEFAULT_THRESHOLD 1 +#define XT_NFLOG_DEFAULT_THRESHOLD 0 #define XT_NFLOG_MASK 0x0 diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index fa49dc7fe10..580b837e44d 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -590,8 +590,10 @@ nfulnl_log_packet(u_int8_t pf, qthreshold = inst->qthreshold; /* per-rule qthreshold overrides per-instance */ - if (qthreshold > li->u.ulog.qthreshold) - qthreshold = li->u.ulog.qthreshold; + if (li->u.ulog.qthreshold) + if (qthreshold > li->u.ulog.qthreshold) + qthreshold = li->u.ulog.qthreshold; + switch (inst->copy_mode) { case NFULNL_COPY_META: -- cgit From 2c6764b743f9d25dd0806a417f06920dcbd0f599 Mon Sep 17 00:00:00 2001 From: Eric Leblond Date: Wed, 18 Feb 2009 15:29:49 +0100 Subject: netfilter: nfnetlink_log: fix timeout handling NFLOG timeout was computed in timer by doing: flushtimeout*HZ/100 Default value of flushtimeout was HZ (for 1 second delay). This was wrong for non 100HZ computer. This patch modify the default delay by using 100 instead of HZ. Signed-off-by: Eric Leblond Signed-off-by: Patrick McHardy --- net/netfilter/nfnetlink_log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 580b837e44d..c712e9fc6bb 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -39,7 +39,7 @@ #endif #define NFULNL_NLBUFSIZ_DEFAULT NLMSG_GOODSIZE -#define NFULNL_TIMEOUT_DEFAULT HZ /* every second */ +#define NFULNL_TIMEOUT_DEFAULT 100 /* every second */ #define NFULNL_QTHRESH_DEFAULT 100 /* 100 packets */ #define NFULNL_COPY_RANGE_MAX 0xFFFF /* max packet size is limited by 16-bit struct nfattr nfa_len field */ -- cgit From 5962fc6d5fff09c8e6fb8cadcb18327a0f4277f7 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 18 Feb 2009 15:30:34 +0100 Subject: netfilter: nf_conntrack: don't try to deliver events for untracked connections The untracked conntrack actually does usually have events marked for delivery as its not special-cased in that part of the code. Skip the actual delivery since it impacts performance noticeably. Signed-off-by: Patrick McHardy --- include/net/netfilter/nf_conntrack_core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h index e78afe7f28e..c25068e3851 100644 --- a/include/net/netfilter/nf_conntrack_core.h +++ b/include/net/netfilter/nf_conntrack_core.h @@ -59,7 +59,7 @@ static inline int nf_conntrack_confirm(struct sk_buff *skb) struct nf_conn *ct = (struct nf_conn *)skb->nfct; int ret = NF_ACCEPT; - if (ct) { + if (ct && ct != &nf_conntrack_untracked) { if (!nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) ret = __nf_conntrack_confirm(skb); nf_ct_deliver_cached_events(ct); -- cgit From eb132205ca2f7ad44d8c8c482815b6911200b6a0 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 18 Feb 2009 16:42:19 +0100 Subject: netfilter: make proc/net/ip* print names from foreign NFPROTO When extensions were moved to the NFPROTO_UNSPEC wildcard in ab4f21e6fb1c09b13c4c3cb8357babe8223471bd, they disappeared from the procfs files. Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy --- net/netfilter/x_tables.c | 199 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 142 insertions(+), 57 deletions(-) diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index bfbf521f6ea..5baccfa5a0d 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -827,59 +827,143 @@ static const struct file_operations xt_table_ops = { .release = seq_release_net, }; -static void *xt_match_seq_start(struct seq_file *seq, loff_t *pos) +/* + * Traverse state for ip{,6}_{tables,matches} for helping crossing + * the multi-AF mutexes. + */ +struct nf_mttg_trav { + struct list_head *head, *curr; + uint8_t class, nfproto; +}; + +enum { + MTTG_TRAV_INIT, + MTTG_TRAV_NFP_UNSPEC, + MTTG_TRAV_NFP_SPEC, + MTTG_TRAV_DONE, +}; + +static void *xt_mttg_seq_next(struct seq_file *seq, void *v, loff_t *ppos, + bool is_target) { - struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private; - u_int16_t af = (unsigned long)pde->data; + static const uint8_t next_class[] = { + [MTTG_TRAV_NFP_UNSPEC] = MTTG_TRAV_NFP_SPEC, + [MTTG_TRAV_NFP_SPEC] = MTTG_TRAV_DONE, + }; + struct nf_mttg_trav *trav = seq->private; + + switch (trav->class) { + case MTTG_TRAV_INIT: + trav->class = MTTG_TRAV_NFP_UNSPEC; + mutex_lock(&xt[NFPROTO_UNSPEC].mutex); + trav->head = trav->curr = is_target ? + &xt[NFPROTO_UNSPEC].target : &xt[NFPROTO_UNSPEC].match; + break; + case MTTG_TRAV_NFP_UNSPEC: + trav->curr = trav->curr->next; + if (trav->curr != trav->head) + break; + mutex_unlock(&xt[NFPROTO_UNSPEC].mutex); + mutex_lock(&xt[trav->nfproto].mutex); + trav->head = trav->curr = is_target ? + &xt[trav->nfproto].target : &xt[trav->nfproto].match; + trav->class = next_class[trav->class]; + break; + case MTTG_TRAV_NFP_SPEC: + trav->curr = trav->curr->next; + if (trav->curr != trav->head) + break; + /* fallthru, _stop will unlock */ + default: + return NULL; + } - mutex_lock(&xt[af].mutex); - return seq_list_start(&xt[af].match, *pos); + if (ppos != NULL) + ++*ppos; + return trav; } -static void *xt_match_seq_next(struct seq_file *seq, void *v, loff_t *pos) +static void *xt_mttg_seq_start(struct seq_file *seq, loff_t *pos, + bool is_target) { - struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private; - u_int16_t af = (unsigned long)pde->data; + struct nf_mttg_trav *trav = seq->private; + unsigned int j; - return seq_list_next(v, &xt[af].match, pos); + trav->class = MTTG_TRAV_INIT; + for (j = 0; j < *pos; ++j) + if (xt_mttg_seq_next(seq, NULL, NULL, is_target) == NULL) + return NULL; + return trav; } -static void xt_match_seq_stop(struct seq_file *seq, void *v) +static void xt_mttg_seq_stop(struct seq_file *seq, void *v) { - struct proc_dir_entry *pde = seq->private; - u_int16_t af = (unsigned long)pde->data; + struct nf_mttg_trav *trav = seq->private; + + switch (trav->class) { + case MTTG_TRAV_NFP_UNSPEC: + mutex_unlock(&xt[NFPROTO_UNSPEC].mutex); + break; + case MTTG_TRAV_NFP_SPEC: + mutex_unlock(&xt[trav->nfproto].mutex); + break; + } +} - mutex_unlock(&xt[af].mutex); +static void *xt_match_seq_start(struct seq_file *seq, loff_t *pos) +{ + return xt_mttg_seq_start(seq, pos, false); } -static int xt_match_seq_show(struct seq_file *seq, void *v) +static void *xt_match_seq_next(struct seq_file *seq, void *v, loff_t *ppos) { - struct xt_match *match = list_entry(v, struct xt_match, list); + return xt_mttg_seq_next(seq, v, ppos, false); +} - if (strlen(match->name)) - return seq_printf(seq, "%s\n", match->name); - else - return 0; +static int xt_match_seq_show(struct seq_file *seq, void *v) +{ + const struct nf_mttg_trav *trav = seq->private; + const struct xt_match *match; + + switch (trav->class) { + case MTTG_TRAV_NFP_UNSPEC: + case MTTG_TRAV_NFP_SPEC: + if (trav->curr == trav->head) + return 0; + match = list_entry(trav->curr, struct xt_match, list); + return (*match->name == '\0') ? 0 : + seq_printf(seq, "%s\n", match->name); + } + return 0; } static const struct seq_operations xt_match_seq_ops = { .start = xt_match_seq_start, .next = xt_match_seq_next, - .stop = xt_match_seq_stop, + .stop = xt_mttg_seq_stop, .show = xt_match_seq_show, }; static int xt_match_open(struct inode *inode, struct file *file) { + struct seq_file *seq; + struct nf_mttg_trav *trav; int ret; - ret = seq_open(file, &xt_match_seq_ops); - if (!ret) { - struct seq_file *seq = file->private_data; + trav = kmalloc(sizeof(*trav), GFP_KERNEL); + if (trav == NULL) + return -ENOMEM; - seq->private = PDE(inode); + ret = seq_open(file, &xt_match_seq_ops); + if (ret < 0) { + kfree(trav); + return ret; } - return ret; + + seq = file->private_data; + seq->private = trav; + trav->nfproto = (unsigned long)PDE(inode)->data; + return 0; } static const struct file_operations xt_match_ops = { @@ -887,62 +971,63 @@ static const struct file_operations xt_match_ops = { .open = xt_match_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = seq_release_private, }; static void *xt_target_seq_start(struct seq_file *seq, loff_t *pos) { - struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private; - u_int16_t af = (unsigned long)pde->data; - - mutex_lock(&xt[af].mutex); - return seq_list_start(&xt[af].target, *pos); + return xt_mttg_seq_start(seq, pos, true); } -static void *xt_target_seq_next(struct seq_file *seq, void *v, loff_t *pos) +static void *xt_target_seq_next(struct seq_file *seq, void *v, loff_t *ppos) { - struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private; - u_int16_t af = (unsigned long)pde->data; - - return seq_list_next(v, &xt[af].target, pos); -} - -static void xt_target_seq_stop(struct seq_file *seq, void *v) -{ - struct proc_dir_entry *pde = seq->private; - u_int16_t af = (unsigned long)pde->data; - - mutex_unlock(&xt[af].mutex); + return xt_mttg_seq_next(seq, v, ppos, true); } static int xt_target_seq_show(struct seq_file *seq, void *v) { - struct xt_target *target = list_entry(v, struct xt_target, list); - - if (strlen(target->name)) - return seq_printf(seq, "%s\n", target->name); - else - return 0; + const struct nf_mttg_trav *trav = seq->private; + const struct xt_target *target; + + switch (trav->class) { + case MTTG_TRAV_NFP_UNSPEC: + case MTTG_TRAV_NFP_SPEC: + if (trav->curr == trav->head) + return 0; + target = list_entry(trav->curr, struct xt_target, list); + return (*target->name == '\0') ? 0 : + seq_printf(seq, "%s\n", target->name); + } + return 0; } static const struct seq_operations xt_target_seq_ops = { .start = xt_target_seq_start, .next = xt_target_seq_next, - .stop = xt_target_seq_stop, + .stop = xt_mttg_seq_stop, .show = xt_target_seq_show, }; static int xt_target_open(struct inode *inode, struct file *file) { + struct seq_file *seq; + struct nf_mttg_trav *trav; int ret; - ret = seq_open(file, &xt_target_seq_ops); - if (!ret) { - struct seq_file *seq = file->private_data; + trav = kmalloc(sizeof(*trav), GFP_KERNEL); + if (trav == NULL) + return -ENOMEM; - seq->private = PDE(inode); + ret = seq_open(file, &xt_target_seq_ops); + if (ret < 0) { + kfree(trav); + return ret; } - return ret; + + seq = file->private_data; + seq->private = trav; + trav->nfproto = (unsigned long)PDE(inode)->data; + return 0; } static const struct file_operations xt_target_ops = { @@ -950,7 +1035,7 @@ static const struct file_operations xt_target_ops = { .open = xt_target_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = seq_release_private, }; #define FORMAT_TABLES "_tables_names" -- cgit From 2678f60d2bc05a12580b93eb36f089f0e55693e0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 18 Feb 2009 16:46:27 +0100 Subject: ALSA: jack - Use card->shortname for input name Currently the jack layer refers to card->longname as a part of its input device name string. However, longname is often really long and way too ugly as an identifier, such as, "HDA Intel at 0xf8400000 irq 21". This patch changes the code to use card->shortname instead. The shortname string contains usually the h/w vendor and product names but without messy I/O port or IRQ numbers. Signed-off-by: Takashi Iwai --- sound/core/jack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/core/jack.c b/sound/core/jack.c index dd4a12dc09a..077a85262c1 100644 --- a/sound/core/jack.c +++ b/sound/core/jack.c @@ -47,7 +47,7 @@ static int snd_jack_dev_register(struct snd_device *device) int err; snprintf(jack->name, sizeof(jack->name), "%s %s", - card->longname, jack->id); + card->shortname, jack->id); jack->input_dev->name = jack->name; /* Default to the sound card device. */ -- cgit From e0ae4f5503235ba4449ffb5bcb4189edcef4d584 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 17 Feb 2009 20:40:09 -0800 Subject: PCI quirk: enable MSI on 8132 David reported that LSI SAS doesn't work with MSI. It turns out that his BIOS doesn't enable it, but the HT MSI 8132 does support HT MSI. Add quirk to enable it Cc: stable@kernel.org Reported-by: David Lang Signed-off-by: Yinghai Lu Signed-off-by: Jesse Barnes --- drivers/pci/quirks.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index baad093aafe..a21e1c292ee 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1981,7 +1981,6 @@ static void __devinit quirk_msi_ht_cap(struct pci_dev *dev) DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE, quirk_msi_ht_cap); - /* The nVidia CK804 chipset may have 2 HT MSI mappings. * MSI are supported if the MSI capability set in any of these mappings. */ @@ -2032,6 +2031,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB, ht_enable_msi_mapping); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8132_BRIDGE, + ht_enable_msi_mapping); + /* The P5N32-SLI Premium motherboard from Asus has a problem with msi * for the MCP55 NIC. It is not yet determined whether the msi problem * also affects other devices. As for now, turn off msi for this device. -- cgit From 994244883739e4044bef76d4e5d7a9b66dc6c7b6 Mon Sep 17 00:00:00 2001 From: Yauhen Kharuzhy Date: Wed, 11 Feb 2009 13:25:52 -0800 Subject: s3cmci: Fix hangup in do_pio_write() This commit fixes the regression what was added by commit 088a78af978d0c8e339071a9b2bca1f4cb368f30 "s3cmci: Support transfers which are not multiple of 32 bits." fifo_free() now returns amount of available space in FIFO buffer in bytes. But do_pio_write() writes to FIFO 32-bit words. Condition for return from cycle is (fifo_free() == 0), but when fifo has 1..3 bytes of free space then this condition will never be true and system hangs. This patch changes condition in the while() to (fifo_free() > 3). Signed-off-by: Yauhen Kharuzhy Signed-off-by: Andrew Morton Signed-off-by: Pierre Ossman --- drivers/mmc/host/s3cmci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 35a98eec741..f4a67c65d30 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -329,7 +329,7 @@ static void do_pio_write(struct s3cmci_host *host) to_ptr = host->base + host->sdidata; - while ((fifo = fifo_free(host))) { + while ((fifo = fifo_free(host)) > 3) { if (!host->pio_bytes) { res = get_data_buffer(host, &host->pio_bytes, &host->pio_ptr); -- cgit From 58a5dd3e0e77029d3db1f8fa75d0b54b38169d5d Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Fri, 13 Feb 2009 22:55:26 +0530 Subject: mmc_test: fix basic read test Due to a typo in the Basic Read test, it's currently identical to the Basic Write test. Fix this. Signed-off-by: Rabin Vincent Signed-off-by: Pierre Ossman --- drivers/mmc/card/mmc_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index b92b172074e..b9f1e84897c 100644 --- a/drivers/mmc/card/mmc_test.c +++ b/drivers/mmc/card/mmc_test.c @@ -494,7 +494,7 @@ static int mmc_test_basic_read(struct mmc_test_card *test) sg_init_one(&sg, test->buffer, 512); - ret = mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 1); + ret = mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 0); if (ret) return ret; -- cgit From 5dbace0c9ba110c1a3810a89fa6bf12b7574b5a3 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sat, 14 Feb 2009 16:22:39 +0100 Subject: sdhci: fix led naming Fix the led device naming for the sdhci driver. The led class documentation defines the led name to have the form "devicename:colour:function" while not applicable sections should be left blank. To comply with the documentation the led device name is changed from "mmc*" to "mmc*::". Signed-off-by: Helmut Schaa Signed-off-by: Pierre Ossman --- drivers/mmc/host/sdhci.c | 4 +++- drivers/mmc/host/sdhci.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 24d7414a331..f52f3053ed9 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1722,7 +1722,9 @@ int sdhci_add_host(struct sdhci_host *host) #endif #ifdef SDHCI_USE_LEDS_CLASS - host->led.name = mmc_hostname(mmc); + snprintf(host->led_name, sizeof(host->led_name), + "%s::", mmc_hostname(mmc)); + host->led.name = host->led_name; host->led.brightness = LED_OFF; host->led.default_trigger = mmc_hostname(mmc); host->led.brightness_set = sdhci_led_control; diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index ffeab227d95..ebb83657e27 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -220,6 +220,7 @@ struct sdhci_host { #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) struct led_classdev led; /* LED control */ + char led_name[32]; #endif spinlock_t lock; /* Mutex */ -- cgit From 249d0fa9d59b6165ecc224720d9ce9b7267cf1b8 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 4 Feb 2009 14:42:03 -0800 Subject: omap_hsmmc: card detect irq bugfix Work around lockdep issue when card detect IRQ handlers run in thread context ... it forces IRQF_DISABLED, which prevents all access to twl4030 card detect signals. Signed-off-by: David Brownell Acked-by: Tony Lindgren Signed-off-by: Pierre Ossman --- drivers/mmc/host/omap_hsmmc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index db37490f67e..4dba48642e6 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -517,6 +517,9 @@ static void mmc_omap_detect(struct work_struct *work) { struct mmc_omap_host *host = container_of(work, struct mmc_omap_host, mmc_carddetect_work); + struct omap_mmc_slot_data *slot = &mmc_slot(host); + + host->carddetect = slot->card_detect(slot->card_detect_irq); sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch"); if (host->carddetect) { @@ -538,7 +541,6 @@ static irqreturn_t omap_mmc_cd_handler(int irq, void *dev_id) { struct mmc_omap_host *host = (struct mmc_omap_host *)dev_id; - host->carddetect = mmc_slot(host).card_detect(irq); schedule_work(&host->mmc_carddetect_work); return IRQ_HANDLED; -- cgit From eb25082657be3e7639e349fc926afdcbb0a4dc65 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Tue, 17 Feb 2009 14:49:01 -0800 Subject: omap_hsmmc: only MMC1 allows HCTL.SDVS != 1.8V Based on a patch from Tony Lindgren ... after initialization, never change HCTL.SDVS except for MMC1. The other controller instances only support 1.8V in that field, although they can suport other card/SDIO/eMMC/... voltages with level shifting solutions such as external transceivers. MMC2 behavior sanity tested on Overo/WLAN, OMAP3430 SDP, and custom hardware. MMC1 also sanity tested on those platforms plus Beagle. This also fixes a bug preventing MMC2 (and also presumably MMC3) from powering down when requested. Signed-off-by: David Brownell Acked-by: Tony Lindgren Signed-off-by: Pierre Ossman --- drivers/mmc/host/omap_hsmmc.c | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 4dba48642e6..3bfd0facb79 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -55,6 +55,7 @@ #define VS30 (1 << 25) #define SDVS18 (0x5 << 9) #define SDVS30 (0x6 << 9) +#define SDVS33 (0x7 << 9) #define SDVSCLR 0xFFFFF1FF #define SDVSDET 0x00000400 #define AUTOIDLE 0x1 @@ -456,13 +457,20 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) } /* - * Switch MMC operating voltage + * Switch MMC interface voltage ... only relevant for MMC1. + * + * MMC2 and MMC3 use fixed 1.8V levels, and maybe a transceiver. + * The MMC2 transceiver controls are used instead of DAT4..DAT7. + * Some chips, like eMMC ones, use internal transceivers. */ static int omap_mmc_switch_opcond(struct mmc_omap_host *host, int vdd) { u32 reg_val = 0; int ret; + if (host->id != OMAP_MMC1_DEVID) + return 0; + /* Disable the clocks */ clk_disable(host->fclk); clk_disable(host->iclk); @@ -485,19 +493,26 @@ static int omap_mmc_switch_opcond(struct mmc_omap_host *host, int vdd) OMAP_HSMMC_WRITE(host->base, HCTL, OMAP_HSMMC_READ(host->base, HCTL) & SDVSCLR); reg_val = OMAP_HSMMC_READ(host->base, HCTL); + /* * If a MMC dual voltage card is detected, the set_ios fn calls * this fn with VDD bit set for 1.8V. Upon card removal from the * slot, omap_mmc_set_ios sets the VDD back to 3V on MMC_POWER_OFF. * - * Only MMC1 supports 3.0V. MMC2 will not function if SDVS30 is - * set in HCTL. + * Cope with a bit of slop in the range ... per data sheets: + * - "1.8V" for vdds_mmc1/vdds_mmc1a can be up to 2.45V max, + * but recommended values are 1.71V to 1.89V + * - "3.0V" for vdds_mmc1/vdds_mmc1a can be up to 3.5V max, + * but recommended values are 2.7V to 3.3V + * + * Board setup code shouldn't permit anything very out-of-range. + * TWL4030-family VMMC1 and VSIM regulators are fine (avoiding the + * middle range) but VSIM can't power DAT4..DAT7 at more than 3V. */ - if (host->id == OMAP_MMC1_DEVID && (((1 << vdd) == MMC_VDD_32_33) || - ((1 << vdd) == MMC_VDD_33_34))) - reg_val |= SDVS30; - if ((1 << vdd) == MMC_VDD_165_195) + if ((1 << vdd) <= MMC_VDD_23_24) reg_val |= SDVS18; + else + reg_val |= SDVS30; OMAP_HSMMC_WRITE(host->base, HCTL, reg_val); @@ -759,10 +774,14 @@ static void omap_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) case MMC_POWER_OFF: mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0); /* - * Reset bus voltage to 3V if it got set to 1.8V earlier. + * Reset interface voltage to 3V if it's 1.8V now; + * only relevant on MMC-1, the others always use 1.8V. + * * REVISIT: If we are able to detect cards after unplugging * a 1.8V card, this code should not be needed. */ + if (host->id != OMAP_MMC1_DEVID) + break; if (!(OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET)) { int vdd = fls(host->mmc->ocr_avail) - 1; if (omap_mmc_switch_opcond(host, vdd) != 0) @@ -786,7 +805,9 @@ static void omap_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) } if (host->id == OMAP_MMC1_DEVID) { - /* Only MMC1 can operate at 3V/1.8V */ + /* Only MMC1 can interface at 3V without some flavor + * of external transceiver; but they all handle 1.8V. + */ if ((OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET) && (ios->vdd == DUAL_VOLT_OCR_BIT)) { /* @@ -1139,7 +1160,9 @@ static int omap_mmc_suspend(struct platform_device *pdev, pm_message_t state) " level suspend\n"); } - if (!(OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET)) { + if (host->id == OMAP_MMC1_DEVID + && !(OMAP_HSMMC_READ(host->base, HCTL) + & SDVSDET)) { OMAP_HSMMC_WRITE(host->base, HCTL, OMAP_HSMMC_READ(host->base, HCTL) & SDVSCLR); -- cgit From c232f457e409b34417166596ea3daf298ace95c9 Mon Sep 17 00:00:00 2001 From: Jean Pihet Date: Wed, 11 Feb 2009 13:11:39 -0800 Subject: omap_hsmmc: recover from transfer failures Timeouts during a command that has a data phase can result in the next command issued after the command that failed not being processed, i.e. no interrupt ever occurs to indicate the command has completed. This failure can result in a deadlock. This patch resets the data state machine to clear the error in case of a command timeout. Tested on OMAP3430 chip and intensive MMC/SD device removal while transferring data. Signed-off-by: Andy Lowe Signed-off-by: Jean Pihet Signed-off-by: Adrian Hunter Signed-off-by: Andrew Morton Acked-by: Tony Lindgren Signed-off-by: Pierre Ossman --- drivers/mmc/host/omap_hsmmc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 3bfd0facb79..8d21a07f63d 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -417,8 +417,15 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) } end_cmd = 1; } - if (host->data) + if (host->data) { mmc_dma_cleanup(host); + OMAP_HSMMC_WRITE(host->base, SYSCTL, + OMAP_HSMMC_READ(host->base, + SYSCTL) | SRD); + while (OMAP_HSMMC_READ(host->base, + SYSCTL) & SRD) + ; + } } if ((status & DATA_TIMEOUT) || (status & DATA_CRC)) { -- cgit From 3ebf74b1de9f94da4291db3ea1ae11c5bedb5784 Mon Sep 17 00:00:00 2001 From: Jean Pihet Date: Fri, 6 Feb 2009 16:42:51 +0100 Subject: omap_hsmmc: Change while(); loops with finite version Replace the infinite 'while() ;' loops with a finite loop version. Signed-off-by: Jean Pihet Acked-by: Tony Lindgren Signed-off-by: Pierre Ossman --- drivers/mmc/host/omap_hsmmc.c | 54 ++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 8d21a07f63d..a631c81dce1 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -376,6 +376,32 @@ static void mmc_omap_report_irq(struct mmc_omap_host *host, u32 status) } #endif /* CONFIG_MMC_DEBUG */ +/* + * MMC controller internal state machines reset + * + * Used to reset command or data internal state machines, using respectively + * SRC or SRD bit of SYSCTL register + * Can be called from interrupt context + */ +static inline void mmc_omap_reset_controller_fsm(struct mmc_omap_host *host, + unsigned long bit) +{ + unsigned long i = 0; + unsigned long limit = (loops_per_jiffy * + msecs_to_jiffies(MMC_TIMEOUT_MS)); + + OMAP_HSMMC_WRITE(host->base, SYSCTL, + OMAP_HSMMC_READ(host->base, SYSCTL) | bit); + + while ((OMAP_HSMMC_READ(host->base, SYSCTL) & bit) && + (i++ < limit)) + cpu_relax(); + + if (OMAP_HSMMC_READ(host->base, SYSCTL) & bit) + dev_err(mmc_dev(host->mmc), + "Timeout waiting on controller reset in %s\n", + __func__); +} /* * MMC controller IRQ handler @@ -404,13 +430,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) (status & CMD_CRC)) { if (host->cmd) { if (status & CMD_TIMEOUT) { - OMAP_HSMMC_WRITE(host->base, SYSCTL, - OMAP_HSMMC_READ(host->base, - SYSCTL) | SRC); - while (OMAP_HSMMC_READ(host->base, - SYSCTL) & SRC) - ; - + mmc_omap_reset_controller_fsm(host, SRC); host->cmd->error = -ETIMEDOUT; } else { host->cmd->error = -EILSEQ; @@ -419,12 +439,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) } if (host->data) { mmc_dma_cleanup(host); - OMAP_HSMMC_WRITE(host->base, SYSCTL, - OMAP_HSMMC_READ(host->base, - SYSCTL) | SRD); - while (OMAP_HSMMC_READ(host->base, - SYSCTL) & SRD) - ; + mmc_omap_reset_controller_fsm(host, SRD); } } if ((status & DATA_TIMEOUT) || @@ -434,12 +449,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) mmc_dma_cleanup(host); else host->data->error = -EILSEQ; - OMAP_HSMMC_WRITE(host->base, SYSCTL, - OMAP_HSMMC_READ(host->base, - SYSCTL) | SRD); - while (OMAP_HSMMC_READ(host->base, - SYSCTL) & SRD) - ; + mmc_omap_reset_controller_fsm(host, SRD); end_trans = 1; } } @@ -547,11 +557,7 @@ static void mmc_omap_detect(struct work_struct *work) if (host->carddetect) { mmc_detect_change(host->mmc, (HZ * 200) / 1000); } else { - OMAP_HSMMC_WRITE(host->base, SYSCTL, - OMAP_HSMMC_READ(host->base, SYSCTL) | SRD); - while (OMAP_HSMMC_READ(host->base, SYSCTL) & SRD) - ; - + mmc_omap_reset_controller_fsm(host, SRD); mmc_detect_change(host->mmc, (HZ * 50) / 1000); } } -- cgit From c296861291669f305deef19b78042330d7135017 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 18 Feb 2009 14:48:12 -0800 Subject: vmalloc: add __get_vm_area_caller() We have get_vm_area_caller() and __get_vm_area() but not __get_vm_area_caller() On powerpc, I use __get_vm_area() to separate the ranges of addresses given to vmalloc vs. ioremap (various good reasons for that) so in order to be able to implement the new caller tracking in /proc/vmallocinfo, I need a "_caller" variant of it. (akpm: needed for ongoing powerpc development, so merge it early) [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Benjamin Herrenschmidt Reviewed-by: KOSAKI Motohiro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/vmalloc.h | 4 ++++ mm/vmalloc.c | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 506e7620a98..9c0890c7a06 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -84,6 +84,10 @@ extern struct vm_struct *get_vm_area_caller(unsigned long size, unsigned long flags, void *caller); extern struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags, unsigned long start, unsigned long end); +extern struct vm_struct *__get_vm_area_caller(unsigned long size, + unsigned long flags, + unsigned long start, unsigned long end, + void *caller); extern struct vm_struct *get_vm_area_node(unsigned long size, unsigned long flags, int node, gfp_t gfp_mask); diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 75f49d312e8..4dd2636d0b9 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -1106,6 +1106,14 @@ struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags, } EXPORT_SYMBOL_GPL(__get_vm_area); +struct vm_struct *__get_vm_area_caller(unsigned long size, unsigned long flags, + unsigned long start, unsigned long end, + void *caller) +{ + return __get_vm_area_node(size, flags, start, end, -1, GFP_KERNEL, + caller); +} + /** * get_vm_area - reserve a contiguous kernel virtual area * @size: size of the area -- cgit From b6d6c5175809934e04a606d9193ef04924a7a7d9 Mon Sep 17 00:00:00 2001 From: Ed Cashin Date: Wed, 18 Feb 2009 14:48:13 -0800 Subject: aoe: ignore vendor extension AoE responses The Welland ME-747K-SI AoE target generates unsolicited AoE responses that are marked as vendor extensions. Instead of ignoring these packets, the aoe driver was generating kernel messages for each unrecognized response received. This patch corrects the behavior. Signed-off-by: Ed Cashin Reported-by: Tested-by: Cc: Cc: Alex Buell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/aoe/aoe.h | 1 + drivers/block/aoe/aoenet.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h index c237527b1aa..5e41e6dd657 100644 --- a/drivers/block/aoe/aoe.h +++ b/drivers/block/aoe/aoe.h @@ -18,6 +18,7 @@ enum { AOECMD_ATA, AOECMD_CFG, + AOECMD_VEND_MIN = 0xf0, AOEFL_RSP = (1<<3), AOEFL_ERR = (1<<2), diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c index 30de5b1c647..c6099ba9a4b 100644 --- a/drivers/block/aoe/aoenet.c +++ b/drivers/block/aoe/aoenet.c @@ -142,6 +142,8 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt, aoecmd_cfg_rsp(skb); break; default: + if (h->cmd >= AOECMD_VEND_MIN) + break; /* don't complain about vendor commands */ printk(KERN_INFO "aoe: unknown cmd %d\n", h->cmd); } exit: -- cgit From b851ee7921fabdd7dfc96ffc4e9609f5062bd12b Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Wed, 18 Feb 2009 14:48:14 -0800 Subject: cgroups: update documentation about css_set hash table The css_set hash table was introduced in 2.6.26, so update the documentation accordingly. Signed-off-by: Li Zefan Acked-by: Paul Menage Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/cgroups/cgroups.txt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Documentation/cgroups/cgroups.txt b/Documentation/cgroups/cgroups.txt index d9e5d6f41b9..93feb844448 100644 --- a/Documentation/cgroups/cgroups.txt +++ b/Documentation/cgroups/cgroups.txt @@ -252,10 +252,8 @@ cgroup file system directories. When a task is moved from one cgroup to another, it gets a new css_set pointer - if there's an already existing css_set with the desired collection of cgroups then that group is reused, else a new -css_set is allocated. Note that the current implementation uses a -linear search to locate an appropriate existing css_set, so isn't -very efficient. A future version will use a hash table for better -performance. +css_set is allocated. The appropriate existing css_set is located by +looking into a hash table. To allow access from a cgroup to the css_sets (and hence tasks) that comprise it, a set of cg_cgroup_link objects form a lattice; -- cgit From 55ec82176eca52e4e0530a82a0eb59160a1a95a1 Mon Sep 17 00:00:00 2001 From: Paul Turner Date: Wed, 18 Feb 2009 14:48:15 -0800 Subject: vfs: separate FMODE_PREAD/FMODE_PWRITE into separate flags Separate FMODE_PREAD and FMODE_PWRITE into separate flags to reflect the reality that the read and write paths may have independent restrictions. A git grep verifies that these flags are always cleared together so this new behavior will only apply to interfaces that change to clear flags individually. This is required for "seq_file: properly cope with pread", a post-2.6.25 regression fix. [akpm@linux-foundation.org: add comment] Signed-off-by: Paul Turner Cc: Eric Biederman Cc: Alexey Dobriyan Cc: Al Viro Cc: [2.6.25.x, 2.6.26.x, 2.6.27.x, 2.6.28.x] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fs.h | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/include/linux/fs.h b/include/linux/fs.h index 6022f44043f..5852bd6afbe 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -54,24 +54,30 @@ struct inodes_stat_t { #define MAY_ACCESS 16 #define MAY_OPEN 32 +/* + * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond + * to O_WRONLY and O_RDWR via the strange trick in __dentry_open() + */ + /* file is open for reading */ #define FMODE_READ ((__force fmode_t)1) /* file is open for writing */ #define FMODE_WRITE ((__force fmode_t)2) /* file is seekable */ #define FMODE_LSEEK ((__force fmode_t)4) -/* file can be accessed using pread/pwrite */ +/* file can be accessed using pread */ #define FMODE_PREAD ((__force fmode_t)8) -#define FMODE_PWRITE FMODE_PREAD /* These go hand in hand */ +/* file can be accessed using pwrite */ +#define FMODE_PWRITE ((__force fmode_t)16) /* File is opened for execution with sys_execve / sys_uselib */ -#define FMODE_EXEC ((__force fmode_t)16) +#define FMODE_EXEC ((__force fmode_t)32) /* File is opened with O_NDELAY (only set for block devices) */ -#define FMODE_NDELAY ((__force fmode_t)32) +#define FMODE_NDELAY ((__force fmode_t)64) /* File is opened with O_EXCL (only set for block devices) */ -#define FMODE_EXCL ((__force fmode_t)64) +#define FMODE_EXCL ((__force fmode_t)128) /* File is opened using open(.., 3, ..) and is writeable only for ioctls (specialy hack for floppy.c) */ -#define FMODE_WRITE_IOCTL ((__force fmode_t)128) +#define FMODE_WRITE_IOCTL ((__force fmode_t)256) /* * Don't update ctime and mtime. -- cgit From 8f19d472935c83d823fa4cf02bcc0a7b9952db30 Mon Sep 17 00:00:00 2001 From: Eric Biederman Date: Wed, 18 Feb 2009 14:48:16 -0800 Subject: seq_file: properly cope with pread Currently seq_read assumes that the offset passed to it is always the offset it passed to user space. In the case pread this assumption is broken and we do the wrong thing when presented with pread. To solve this I introduce an offset cache inside of struct seq_file so we know where our logical file position is. Then in seq_read if we try to read from another offset we reset our data structures and attempt to go to the offset user space wanted. [akpm@linux-foundation.org: restore FMODE_PWRITE] [pjt@google.com: seq_open needs its fmode opened up to take advantage of this] Signed-off-by: Eric Biederman Cc: Alexey Dobriyan Cc: Al Viro Cc: Paul Turner Cc: [2.6.25.x, 2.6.26.x, 2.6.27.x, 2.6.28.x] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/seq_file.c | 36 ++++++++++++++++++++++++++++++++---- include/linux/seq_file.h | 1 + 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/fs/seq_file.c b/fs/seq_file.c index 5267098532b..a1a4cfe1921 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c @@ -48,8 +48,16 @@ int seq_open(struct file *file, const struct seq_operations *op) */ file->f_version = 0; - /* SEQ files support lseek, but not pread/pwrite */ - file->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE); + /* + * seq_files support lseek() and pread(). They do not implement + * write() at all, but we clear FMODE_PWRITE here for historical + * reasons. + * + * If a client of seq_files a) implements file.write() and b) wishes to + * support pwrite() then that client will need to implement its own + * file.open() which calls seq_open() and then sets FMODE_PWRITE. + */ + file->f_mode &= ~FMODE_PWRITE; return 0; } EXPORT_SYMBOL(seq_open); @@ -131,6 +139,22 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) int err = 0; mutex_lock(&m->lock); + + /* Don't assume *ppos is where we left it */ + if (unlikely(*ppos != m->read_pos)) { + m->read_pos = *ppos; + while ((err = traverse(m, *ppos)) == -EAGAIN) + ; + if (err) { + /* With prejudice... */ + m->read_pos = 0; + m->version = 0; + m->index = 0; + m->count = 0; + goto Done; + } + } + /* * seq_file->op->..m_start/m_stop/m_next may do special actions * or optimisations based on the file->f_version, so we want to @@ -230,8 +254,10 @@ Fill: Done: if (!copied) copied = err; - else + else { *ppos += copied; + m->read_pos += copied; + } file->f_version = m->version; mutex_unlock(&m->lock); return copied; @@ -266,16 +292,18 @@ loff_t seq_lseek(struct file *file, loff_t offset, int origin) if (offset < 0) break; retval = offset; - if (offset != file->f_pos) { + if (offset != m->read_pos) { while ((retval=traverse(m, offset)) == -EAGAIN) ; if (retval) { /* with extreme prejudice... */ file->f_pos = 0; + m->read_pos = 0; m->version = 0; m->index = 0; m->count = 0; } else { + m->read_pos = offset; retval = file->f_pos = offset; } } diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index 40ea5058c2e..f616f31576d 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h @@ -19,6 +19,7 @@ struct seq_file { size_t from; size_t count; loff_t index; + loff_t read_pos; u64 version; struct mutex lock; const struct seq_operations *op; -- cgit From ef35ce231b3cb2a4b1808e826da263bf37ccb38a Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Wed, 18 Feb 2009 14:48:16 -0800 Subject: Pavel has moved My @suse.cz address will stop working some day, so put working one into MAINTAINERS/CREDITS. It would be cool to get this to 2.6.29... it should not really break anything. Signed-off-by: Pavel Machek Cc: Jiri Kosina Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- CREDITS | 1 - MAINTAINERS | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CREDITS b/CREDITS index 2b39168c06a..5e0736722af 100644 --- a/CREDITS +++ b/CREDITS @@ -2166,7 +2166,6 @@ D: Initial implementation of VC's, pty's and select() N: Pavel Machek E: pavel@ucw.cz -E: pavel@suse.cz D: Softcursor for vga, hypertech cdrom support, vcsa bugfix, nbd D: sun4/330 port, capabilities for elf, speedup for rm on ext2, USB, D: work on suspend-to-ram/disk, killing duplicates from ioctl32 diff --git a/MAINTAINERS b/MAINTAINERS index e784b358b33..a2008bd587c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2001,7 +2001,7 @@ S: Maintained HIBERNATION (aka Software Suspend, aka swsusp) P: Pavel Machek -M: pavel@suse.cz +M: pavel@ucw.cz P: Rafael J. Wysocki M: rjw@sisk.pl L: linux-pm@lists.linux-foundation.org @@ -4172,7 +4172,7 @@ SUSPEND TO RAM P: Len Brown M: len.brown@intel.com P: Pavel Machek -M: pavel@suse.cz +M: pavel@ucw.cz P: Rafael J. Wysocki M: rjw@sisk.pl L: linux-pm@lists.linux-foundation.org -- cgit From 610d18f4128ebbd88845d0fc60cce67b49af881e Mon Sep 17 00:00:00 2001 From: Davide Libenzi Date: Wed, 18 Feb 2009 14:48:18 -0800 Subject: timerfd: add flags check As requested by Michael, add a missing check for valid flags in timerfd_settime(), and make it return EINVAL in case some extra bits are set. Michael said: If this is to be any use to userland apps that want to check flag support (perhaps it is too late already), then the sooner we get it into the kernel the better: 2.6.29 would be good; earlier stables as well would be even better. [akpm@linux-foundation.org: remove unused TFD_FLAGS_SET] Acked-by: Michael Kerrisk Signed-off-by: Davide Libenzi Cc: [2.6.27.x, 2.6.28.x] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/timerfd.c | 12 ++++++------ include/linux/timerfd.h | 16 ++++++++++++---- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/fs/timerfd.c b/fs/timerfd.c index 6a123b8ff3f..b042bd7034b 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c @@ -186,10 +186,9 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) BUILD_BUG_ON(TFD_CLOEXEC != O_CLOEXEC); BUILD_BUG_ON(TFD_NONBLOCK != O_NONBLOCK); - if (flags & ~(TFD_CLOEXEC | TFD_NONBLOCK)) - return -EINVAL; - if (clockid != CLOCK_MONOTONIC && - clockid != CLOCK_REALTIME) + if ((flags & ~TFD_CREATE_FLAGS) || + (clockid != CLOCK_MONOTONIC && + clockid != CLOCK_REALTIME)) return -EINVAL; ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); @@ -201,7 +200,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) hrtimer_init(&ctx->tmr, clockid, HRTIMER_MODE_ABS); ufd = anon_inode_getfd("[timerfd]", &timerfd_fops, ctx, - flags & (O_CLOEXEC | O_NONBLOCK)); + flags & TFD_SHARED_FCNTL_FLAGS); if (ufd < 0) kfree(ctx); @@ -219,7 +218,8 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, if (copy_from_user(&ktmr, utmr, sizeof(ktmr))) return -EFAULT; - if (!timespec_valid(&ktmr.it_value) || + if ((flags & ~TFD_SETTIME_FLAGS) || + !timespec_valid(&ktmr.it_value) || !timespec_valid(&ktmr.it_interval)) return -EINVAL; diff --git a/include/linux/timerfd.h b/include/linux/timerfd.h index 86cb0501d3e..2d0792983f8 100644 --- a/include/linux/timerfd.h +++ b/include/linux/timerfd.h @@ -11,13 +11,21 @@ /* For O_CLOEXEC and O_NONBLOCK */ #include -/* Flags for timerfd_settime. */ +/* + * CAREFUL: Check include/asm-generic/fcntl.h when defining + * new flags, since they might collide with O_* ones. We want + * to re-use O_* flags that couldn't possibly have a meaning + * from eventfd, in order to leave a free define-space for + * shared O_* flags. + */ #define TFD_TIMER_ABSTIME (1 << 0) - -/* Flags for timerfd_create. */ #define TFD_CLOEXEC O_CLOEXEC #define TFD_NONBLOCK O_NONBLOCK +#define TFD_SHARED_FCNTL_FLAGS (TFD_CLOEXEC | TFD_NONBLOCK) +/* Flags for timerfd_create. */ +#define TFD_CREATE_FLAGS TFD_SHARED_FCNTL_FLAGS +/* Flags for timerfd_settime. */ +#define TFD_SETTIME_FLAGS TFD_TIMER_ABSTIME #endif /* _LINUX_TIMERFD_H */ - -- cgit From 1cf6e7d83bf334cc5916137862c920a97aabc018 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Wed, 18 Feb 2009 14:48:18 -0800 Subject: mm: task dirty accounting fix YAMAMOTO-san noticed that task_dirty_inc doesn't seem to be called properly for cases where set_page_dirty is not used to dirty a page (eg. mark_buffer_dirty). Additionally, there is some inconsistency about when task_dirty_inc is called. It is used for dirty balancing, however it even gets called for __set_page_dirty_no_writeback. So rather than increment it in a set_page_dirty wrapper, move it down to exactly where the dirty page accounting stats are incremented. Cc: YAMAMOTO Takashi Signed-off-by: Nick Piggin Acked-by: Peter Zijlstra Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/buffer.c | 1 + include/linux/mm.h | 1 + mm/page-writeback.c | 13 +++---------- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/fs/buffer.c b/fs/buffer.c index 665d446b25b..ff4d1cdd779 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -777,6 +777,7 @@ static int __set_page_dirty(struct page *page, __inc_zone_page_state(page, NR_FILE_DIRTY); __inc_bdi_stat(mapping->backing_dev_info, BDI_RECLAIMABLE); + task_dirty_inc(current); task_io_account_write(PAGE_CACHE_SIZE); } radix_tree_tag_set(&mapping->page_tree, diff --git a/include/linux/mm.h b/include/linux/mm.h index 7dc04ff5ab8..10074212a35 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1159,6 +1159,7 @@ extern int filemap_fault(struct vm_area_struct *, struct vm_fault *); /* mm/page-writeback.c */ int write_one_page(struct page *page, int wait); +void task_dirty_inc(struct task_struct *tsk); /* readahead.c */ #define VM_MAX_READAHEAD 128 /* kbytes */ diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 3c84128596b..74dc57c7434 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -240,7 +240,7 @@ void bdi_writeout_inc(struct backing_dev_info *bdi) } EXPORT_SYMBOL_GPL(bdi_writeout_inc); -static inline void task_dirty_inc(struct task_struct *tsk) +void task_dirty_inc(struct task_struct *tsk) { prop_inc_single(&vm_dirties, &tsk->dirties); } @@ -1230,6 +1230,7 @@ int __set_page_dirty_nobuffers(struct page *page) __inc_zone_page_state(page, NR_FILE_DIRTY); __inc_bdi_stat(mapping->backing_dev_info, BDI_RECLAIMABLE); + task_dirty_inc(current); task_io_account_write(PAGE_CACHE_SIZE); } radix_tree_tag_set(&mapping->page_tree, @@ -1262,7 +1263,7 @@ EXPORT_SYMBOL(redirty_page_for_writepage); * If the mapping doesn't provide a set_page_dirty a_op, then * just fall through and assume that it wants buffer_heads. */ -static int __set_page_dirty(struct page *page) +int set_page_dirty(struct page *page) { struct address_space *mapping = page_mapping(page); @@ -1280,14 +1281,6 @@ static int __set_page_dirty(struct page *page) } return 0; } - -int set_page_dirty(struct page *page) -{ - int ret = __set_page_dirty(page); - if (ret) - task_dirty_inc(current); - return ret; -} EXPORT_SYMBOL(set_page_dirty); /* -- cgit From 67e055d144c5b2acdc1c63811fde031263bf92c5 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Wed, 18 Feb 2009 14:48:20 -0800 Subject: cgroups: fix possible use after free In cgroup_kill_sb(), root is freed before sb is detached from the list, so another sget() may find this sb and call cgroup_test_super(), which will access the root that has been freed. Reported-by: Al Viro Signed-off-by: Li Zefan Acked-by: Paul Menage Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/cgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/cgroup.c b/kernel/cgroup.c index e14db9c089b..9edb5c4b79b 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -1122,8 +1122,8 @@ static void cgroup_kill_sb(struct super_block *sb) { mutex_unlock(&cgroup_mutex); - kfree(root); kill_litter_super(sb); + kfree(root); } static struct file_system_type cgroup_fs_type = { -- cgit From 42f5e039c3f6512271636928ddc4e7f7a0371672 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 18 Feb 2009 14:48:21 -0800 Subject: pm: fix build for CONFIG_PM unset Compilation of kprobes.c with CONFIG_PM unset is broken due to some broken config dependncies. Fix that. Signed-off-by: Rafael J. Wysocki Reported-by: Ingo Molnar Tested-by: Masami Hiramatsu Cc: Len Brown Acked-by: Pavel Machek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/Makefile | 1 + kernel/power/Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/Makefile b/kernel/Makefile index 170a9213c1b..e4791b3ba55 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -51,6 +51,7 @@ obj-$(CONFIG_UID16) += uid16.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_KALLSYMS) += kallsyms.o obj-$(CONFIG_PM) += power/ +obj-$(CONFIG_FREEZER) += power/ obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o obj-$(CONFIG_KEXEC) += kexec.o obj-$(CONFIG_BACKTRACE_SELF_TEST) += backtracetest.o diff --git a/kernel/power/Makefile b/kernel/power/Makefile index d7a10167a25..720ea4f781b 100644 --- a/kernel/power/Makefile +++ b/kernel/power/Makefile @@ -3,7 +3,7 @@ ifeq ($(CONFIG_PM_DEBUG),y) EXTRA_CFLAGS += -DDEBUG endif -obj-y := main.o +obj-$(CONFIG_PM) += main.o obj-$(CONFIG_PM_SLEEP) += console.o obj-$(CONFIG_FREEZER) += process.o obj-$(CONFIG_HIBERNATION) += swsusp.o disk.o snapshot.o swap.o user.o -- cgit From 3a5093ee6728c8cbe9c039e685fc1fca8f965048 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Wed, 18 Feb 2009 14:48:22 -0800 Subject: eeepc: should depend on INPUT Otherwise with INPUT=m, EEEPC_LAPTOP=y one gets drivers/built-in.o: In function `input_sync': eeepc-laptop.c:(.text+0x18ce51): undefined reference to `input_event' drivers/built-in.o: In function `input_report_key': eeepc-laptop.c:(.text+0x18ce73): undefined reference to `input_event' drivers/built-in.o: In function `eeepc_hotk_check': eeepc-laptop.c:(.text+0x18d05f): undefined reference to `input_allocate_device' eeepc-laptop.c:(.text+0x18d10f): undefined reference to `input_register_device' eeepc-laptop.c:(.text+0x18d131): undefined reference to `input_free_device' drivers/built-in.o: In function `eeepc_backlight_exit': eeepc-laptop.c:(.text+0x18d546): undefined reference to `input_unregister_device' Signed-off-by: Alexey Dobriyan Cc: Len Brown Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/platform/x86/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 94363115a42..6bce56c2262 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -301,6 +301,7 @@ config INTEL_MENLOW config EEEPC_LAPTOP tristate "Eee PC Hotkey Driver (EXPERIMENTAL)" depends on ACPI + depends on INPUT depends on EXPERIMENTAL select BACKLIGHT_CLASS_DEVICE select HWMON -- cgit From ef2cfc790bf5f0ff189b01eabc0f4feb5e8524df Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Wed, 18 Feb 2009 14:48:23 -0800 Subject: hp accelerometer: add freefall detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds freefall handling to hp_accel driver. According to HP, it should just work, without us having to set the chip up by hand. hpfall.c is example .c program that parks the disk when accelerometer detects free fall. It should work; for now, it uses fixed 20seconds protection period. Signed-off-by: Pavel Machek Cc: Thomas Renninger Cc: Éric Piel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/hwmon/hpfall.c | 101 +++++++++++++++++++++++++ Documentation/hwmon/lis3lv02d | 8 ++ drivers/hwmon/hp_accel.c | 27 +++++++ drivers/hwmon/lis3lv02d.c | 172 +++++++++++++++++++++++++++++++++++++----- drivers/hwmon/lis3lv02d.h | 5 ++ 5 files changed, 296 insertions(+), 17 deletions(-) create mode 100644 Documentation/hwmon/hpfall.c diff --git a/Documentation/hwmon/hpfall.c b/Documentation/hwmon/hpfall.c new file mode 100644 index 00000000000..bbea1ccfd46 --- /dev/null +++ b/Documentation/hwmon/hpfall.c @@ -0,0 +1,101 @@ +/* Disk protection for HP machines. + * + * Copyright 2008 Eric Piel + * Copyright 2009 Pavel Machek + * + * GPLv2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void write_int(char *path, int i) +{ + char buf[1024]; + int fd = open(path, O_RDWR); + if (fd < 0) { + perror("open"); + exit(1); + } + sprintf(buf, "%d", i); + if (write(fd, buf, strlen(buf)) != strlen(buf)) { + perror("write"); + exit(1); + } + close(fd); +} + +void set_led(int on) +{ + write_int("/sys/class/leds/hp::hddprotect/brightness", on); +} + +void protect(int seconds) +{ + write_int("/sys/block/sda/device/unload_heads", seconds*1000); +} + +int on_ac(void) +{ +// /sys/class/power_supply/AC0/online +} + +int lid_open(void) +{ +// /proc/acpi/button/lid/LID/state +} + +void ignore_me(void) +{ + protect(0); + set_led(0); + +} + +int main(int argc, char* argv[]) +{ + int fd, ret; + + fd = open("/dev/freefall", O_RDONLY); + if (fd < 0) { + perror("open"); + return EXIT_FAILURE; + } + + signal(SIGALRM, ignore_me); + + for (;;) { + unsigned char count; + + ret = read(fd, &count, sizeof(count)); + alarm(0); + if ((ret == -1) && (errno == EINTR)) { + /* Alarm expired, time to unpark the heads */ + continue; + } + + if (ret != sizeof(count)) { + perror("read"); + break; + } + + protect(21); + set_led(1); + if (1 || on_ac() || lid_open()) { + alarm(2); + } else { + alarm(20); + } + } + + close(fd); + return EXIT_SUCCESS; +} diff --git a/Documentation/hwmon/lis3lv02d b/Documentation/hwmon/lis3lv02d index 0fcfc4a7ccd..287f8c90265 100644 --- a/Documentation/hwmon/lis3lv02d +++ b/Documentation/hwmon/lis3lv02d @@ -33,6 +33,14 @@ rate - reports the sampling rate of the accelerometer device in HZ This driver also provides an absolute input class device, allowing the laptop to act as a pinball machine-esque joystick. +Another feature of the driver is misc device called "freefall" that +acts similar to /dev/rtc and reacts on free-fall interrupts received +from the device. It supports blocking operations, poll/select and +fasync operation modes. You must read 1 bytes from the device. The +result is number of free-fall interrupts since the last successful +read (or 255 if number of interrupts would not fit). + + Axes orientation ---------------- diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c index abf4dfc8ec2..dcefe1d2adb 100644 --- a/drivers/hwmon/hp_accel.c +++ b/drivers/hwmon/hp_accel.c @@ -213,6 +213,30 @@ static struct delayed_led_classdev hpled_led = { .set_brightness = hpled_set, }; +static acpi_status +lis3lv02d_get_resource(struct acpi_resource *resource, void *context) +{ + if (resource->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) { + struct acpi_resource_extended_irq *irq; + u32 *device_irq = context; + + irq = &resource->data.extended_irq; + *device_irq = irq->interrupts[0]; + } + + return AE_OK; +} + +static void lis3lv02d_enum_resources(struct acpi_device *device) +{ + acpi_status status; + + status = acpi_walk_resources(device->handle, METHOD_NAME__CRS, + lis3lv02d_get_resource, &adev.irq); + if (ACPI_FAILURE(status)) + printk(KERN_DEBUG DRIVER_NAME ": Error getting resources\n"); +} + static int lis3lv02d_add(struct acpi_device *device) { u8 val; @@ -247,6 +271,9 @@ static int lis3lv02d_add(struct acpi_device *device) if (ret) return ret; + /* obtain IRQ number of our device from ACPI */ + lis3lv02d_enum_resources(adev.device); + ret = lis3lv02d_init_device(&adev); if (ret) { flush_work(&hpled_led.work); diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c index 219d2d0d5a6..3afa3afc77f 100644 --- a/drivers/hwmon/lis3lv02d.c +++ b/drivers/hwmon/lis3lv02d.c @@ -3,7 +3,7 @@ * * Copyright (C) 2007-2008 Yan Burman * Copyright (C) 2008 Eric Piel - * Copyright (C) 2008 Pavel Machek + * Copyright (C) 2008-2009 Pavel Machek * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include "lis3lv02d.h" @@ -55,7 +56,10 @@ /* Maximum value our axis may get for the input device (signed 12 bits) */ #define MDPS_MAX_VAL 2048 -struct acpi_lis3lv02d adev; +struct acpi_lis3lv02d adev = { + .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(adev.misc_wait), +}; + EXPORT_SYMBOL_GPL(adev); static int lis3lv02d_add_fs(struct acpi_device *device); @@ -110,26 +114,13 @@ static void lis3lv02d_get_xyz(acpi_handle handle, int *x, int *y, int *z) void lis3lv02d_poweroff(acpi_handle handle) { adev.is_on = 0; - /* disable X,Y,Z axis and power down */ - adev.write(handle, CTRL_REG1, 0x00); } EXPORT_SYMBOL_GPL(lis3lv02d_poweroff); void lis3lv02d_poweron(acpi_handle handle) { - u8 val; - adev.is_on = 1; adev.init(handle); - adev.write(handle, FF_WU_CFG, 0); - /* - * BDU: LSB and MSB values are not updated until both have been read. - * So the value read will always be correct. - * IEN: Interrupt for free-fall and DD, not for data-ready. - */ - adev.read(handle, CTRL_REG2, &val); - val |= CTRL2_BDU | CTRL2_IEN; - adev.write(handle, CTRL_REG2, val); } EXPORT_SYMBOL_GPL(lis3lv02d_poweron); @@ -162,6 +153,140 @@ static void lis3lv02d_decrease_use(struct acpi_lis3lv02d *dev) mutex_unlock(&dev->lock); } +static irqreturn_t lis302dl_interrupt(int irq, void *dummy) +{ + /* + * Be careful: on some HP laptops the bios force DD when on battery and + * the lid is closed. This leads to interrupts as soon as a little move + * is done. + */ + atomic_inc(&adev.count); + + wake_up_interruptible(&adev.misc_wait); + kill_fasync(&adev.async_queue, SIGIO, POLL_IN); + return IRQ_HANDLED; +} + +static int lis3lv02d_misc_open(struct inode *inode, struct file *file) +{ + int ret; + + if (test_and_set_bit(0, &adev.misc_opened)) + return -EBUSY; /* already open */ + + atomic_set(&adev.count, 0); + + /* + * The sensor can generate interrupts for free-fall and direction + * detection (distinguishable with FF_WU_SRC and DD_SRC) but to keep + * the things simple and _fast_ we activate it only for free-fall, so + * no need to read register (very slow with ACPI). For the same reason, + * we forbid shared interrupts. + * + * IRQF_TRIGGER_RISING seems pointless on HP laptops because the + * io-apic is not configurable (and generates a warning) but I keep it + * in case of support for other hardware. + */ + ret = request_irq(adev.irq, lis302dl_interrupt, IRQF_TRIGGER_RISING, + DRIVER_NAME, &adev); + + if (ret) { + clear_bit(0, &adev.misc_opened); + printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", adev.irq); + return -EBUSY; + } + lis3lv02d_increase_use(&adev); + printk("lis3: registered interrupt %d\n", adev.irq); + return 0; +} + +static int lis3lv02d_misc_release(struct inode *inode, struct file *file) +{ + fasync_helper(-1, file, 0, &adev.async_queue); + lis3lv02d_decrease_use(&adev); + free_irq(adev.irq, &adev); + clear_bit(0, &adev.misc_opened); /* release the device */ + return 0; +} + +static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf, + size_t count, loff_t *pos) +{ + DECLARE_WAITQUEUE(wait, current); + u32 data; + unsigned char byte_data; + ssize_t retval = 1; + + if (count < 1) + return -EINVAL; + + add_wait_queue(&adev.misc_wait, &wait); + while (true) { + set_current_state(TASK_INTERRUPTIBLE); + data = atomic_xchg(&adev.count, 0); + if (data) + break; + + if (file->f_flags & O_NONBLOCK) { + retval = -EAGAIN; + goto out; + } + + if (signal_pending(current)) { + retval = -ERESTARTSYS; + goto out; + } + + schedule(); + } + + if (data < 255) + byte_data = data; + else + byte_data = 255; + + /* make sure we are not going into copy_to_user() with + * TASK_INTERRUPTIBLE state */ + set_current_state(TASK_RUNNING); + if (copy_to_user(buf, &byte_data, sizeof(byte_data))) + retval = -EFAULT; + +out: + __set_current_state(TASK_RUNNING); + remove_wait_queue(&adev.misc_wait, &wait); + + return retval; +} + +static unsigned int lis3lv02d_misc_poll(struct file *file, poll_table *wait) +{ + poll_wait(file, &adev.misc_wait, wait); + if (atomic_read(&adev.count)) + return POLLIN | POLLRDNORM; + return 0; +} + +static int lis3lv02d_misc_fasync(int fd, struct file *file, int on) +{ + return fasync_helper(fd, file, on, &adev.async_queue); +} + +static const struct file_operations lis3lv02d_misc_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .read = lis3lv02d_misc_read, + .open = lis3lv02d_misc_open, + .release = lis3lv02d_misc_release, + .poll = lis3lv02d_misc_poll, + .fasync = lis3lv02d_misc_fasync, +}; + +static struct miscdevice lis3lv02d_misc_device = { + .minor = MISC_DYNAMIC_MINOR, + .name = "freefall", + .fops = &lis3lv02d_misc_fops, +}; + /** * lis3lv02d_joystick_kthread - Kthread polling function * @data: unused - here to conform to threadfn prototype @@ -203,7 +328,6 @@ static void lis3lv02d_joystick_close(struct input_dev *input) lis3lv02d_decrease_use(&adev); } - static inline void lis3lv02d_calibrate_joystick(void) { lis3lv02d_get_xyz(adev.device->handle, &adev.xcalib, &adev.ycalib, &adev.zcalib); @@ -250,6 +374,7 @@ void lis3lv02d_joystick_disable(void) if (!adev.idev) return; + misc_deregister(&lis3lv02d_misc_device); input_unregister_device(adev.idev); adev.idev = NULL; } @@ -268,6 +393,19 @@ int lis3lv02d_init_device(struct acpi_lis3lv02d *dev) if (lis3lv02d_joystick_enable()) printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n"); + printk("lis3_init_device: irq %d\n", dev->irq); + + /* if we did not get an IRQ from ACPI - we have nothing more to do */ + if (!dev->irq) { + printk(KERN_ERR DRIVER_NAME + ": No IRQ in ACPI. Disabling /dev/freefall\n"); + goto out; + } + + printk("lis3: registering device\n"); + if (misc_register(&lis3lv02d_misc_device)) + printk(KERN_ERR DRIVER_NAME ": misc_register failed\n"); +out: lis3lv02d_decrease_use(dev); return 0; } @@ -351,6 +489,6 @@ int lis3lv02d_remove_fs(void) EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs); MODULE_DESCRIPTION("ST LIS3LV02Dx three-axis digital accelerometer driver"); -MODULE_AUTHOR("Yan Burman and Eric Piel"); +MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek"); MODULE_LICENSE("GPL"); diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h index 223f1c0763b..2e7597c42d8 100644 --- a/drivers/hwmon/lis3lv02d.h +++ b/drivers/hwmon/lis3lv02d.h @@ -170,6 +170,11 @@ struct acpi_lis3lv02d { unsigned char is_on; /* whether the device is on or off */ unsigned char usage; /* usage counter */ struct axis_conversion ac; /* hw -> logical axis */ + + u32 irq; /* IRQ number */ + struct fasync_struct *async_queue; /* queue for the misc device */ + wait_queue_head_t misc_wait; /* Wait queue for the misc device */ + unsigned long misc_opened; /* bit0: whether the device is open */ }; int lis3lv02d_init_device(struct acpi_lis3lv02d *dev); -- cgit From 137bad32342a613586347341d1307c2b9812ef44 Mon Sep 17 00:00:00 2001 From: Giuseppe Bilotta Date: Wed, 18 Feb 2009 14:48:24 -0800 Subject: lis3lv02d: support both one- and two-byte sensors Sensors responding with 0x3B to WHO_AM_I only have one data register per direction, thus returning a signed byte from the position which is occupied by the MSB in sensors responding with 0x3A. Since multiple sensors share the reply to WHO_AM_I, we rename the defines to better indicate what they identify (family of single and double precision sensors). We support both kind of sensors by checking for the sensor type on init and defining appropriate data-access routines and sensor limits (for the joystick) depending on what we find. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Giuseppe Bilotta Acked-by: Eric Piel Cc: Pavel Machek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/hwmon/hp_accel.c | 36 ++++++++++++++++++++++++++++++++---- drivers/hwmon/lis3lv02d.c | 25 ++++++------------------- drivers/hwmon/lis3lv02d.h | 16 +++++++++++++--- 3 files changed, 51 insertions(+), 26 deletions(-) diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c index dcefe1d2adb..6b16566c4e6 100644 --- a/drivers/hwmon/hp_accel.c +++ b/drivers/hwmon/hp_accel.c @@ -237,9 +237,25 @@ static void lis3lv02d_enum_resources(struct acpi_device *device) printk(KERN_DEBUG DRIVER_NAME ": Error getting resources\n"); } +static s16 lis3lv02d_read_16(acpi_handle handle, int reg) +{ + u8 lo, hi; + + adev.read(handle, reg - 1, &lo); + adev.read(handle, reg, &hi); + /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */ + return (s16)((hi << 8) | lo); +} + +static s16 lis3lv02d_read_8(acpi_handle handle, int reg) +{ + s8 lo; + adev.read(handle, reg, &lo); + return lo; +} + static int lis3lv02d_add(struct acpi_device *device) { - u8 val; int ret; if (!device) @@ -253,10 +269,22 @@ static int lis3lv02d_add(struct acpi_device *device) strcpy(acpi_device_class(device), ACPI_MDPS_CLASS); device->driver_data = &adev; - lis3lv02d_acpi_read(device->handle, WHO_AM_I, &val); - if ((val != LIS3LV02DL_ID) && (val != LIS302DL_ID)) { + lis3lv02d_acpi_read(device->handle, WHO_AM_I, &adev.whoami); + switch (adev.whoami) { + case LIS_DOUBLE_ID: + printk(KERN_INFO DRIVER_NAME ": 2-byte sensor found\n"); + adev.read_data = lis3lv02d_read_16; + adev.mdps_max_val = 2048; + break; + case LIS_SINGLE_ID: + printk(KERN_INFO DRIVER_NAME ": 1-byte sensor found\n"); + adev.read_data = lis3lv02d_read_8; + adev.mdps_max_val = 128; + break; + default: printk(KERN_ERR DRIVER_NAME - ": Accelerometer chip not LIS3LV02D{L,Q}\n"); + ": unknown sensor type 0x%X\n", adev.whoami); + return -EINVAL; } /* If possible use a "standard" axes order */ diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c index 3afa3afc77f..8bb2158f045 100644 --- a/drivers/hwmon/lis3lv02d.c +++ b/drivers/hwmon/lis3lv02d.c @@ -53,9 +53,6 @@ * joystick. */ -/* Maximum value our axis may get for the input device (signed 12 bits) */ -#define MDPS_MAX_VAL 2048 - struct acpi_lis3lv02d adev = { .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(adev.misc_wait), }; @@ -64,16 +61,6 @@ EXPORT_SYMBOL_GPL(adev); static int lis3lv02d_add_fs(struct acpi_device *device); -static s16 lis3lv02d_read_16(acpi_handle handle, int reg) -{ - u8 lo, hi; - - adev.read(handle, reg, &lo); - adev.read(handle, reg + 1, &hi); - /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */ - return (s16)((hi << 8) | lo); -} - /** * lis3lv02d_get_axis - For the given axis, give the value converted * @axis: 1,2,3 - can also be negative @@ -102,9 +89,9 @@ static void lis3lv02d_get_xyz(acpi_handle handle, int *x, int *y, int *z) { int position[3]; - position[0] = lis3lv02d_read_16(handle, OUTX_L); - position[1] = lis3lv02d_read_16(handle, OUTY_L); - position[2] = lis3lv02d_read_16(handle, OUTZ_L); + position[0] = adev.read_data(handle, OUTX); + position[1] = adev.read_data(handle, OUTY); + position[2] = adev.read_data(handle, OUTZ); *x = lis3lv02d_get_axis(adev.ac.x, position); *y = lis3lv02d_get_axis(adev.ac.y, position); @@ -355,9 +342,9 @@ int lis3lv02d_joystick_enable(void) adev.idev->close = lis3lv02d_joystick_close; set_bit(EV_ABS, adev.idev->evbit); - input_set_abs_params(adev.idev, ABS_X, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3); - input_set_abs_params(adev.idev, ABS_Y, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3); - input_set_abs_params(adev.idev, ABS_Z, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3); + input_set_abs_params(adev.idev, ABS_X, -adev.mdps_max_val, adev.mdps_max_val, 3, 3); + input_set_abs_params(adev.idev, ABS_Y, -adev.mdps_max_val, adev.mdps_max_val, 3, 3); + input_set_abs_params(adev.idev, ABS_Z, -adev.mdps_max_val, adev.mdps_max_val, 3, 3); err = input_register_device(adev.idev); if (err) { diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h index 2e7597c42d8..75972bf372f 100644 --- a/drivers/hwmon/lis3lv02d.h +++ b/drivers/hwmon/lis3lv02d.h @@ -22,12 +22,15 @@ /* * The actual chip is STMicroelectronics LIS3LV02DL or LIS3LV02DQ that seems to * be connected via SPI. There exists also several similar chips (such as LIS302DL or - * LIS3L02DQ) but not in the HP laptops and they have slightly different registers. + * LIS3L02DQ) and they have slightly different registers, but we can provide a + * common interface for all of them. * They can also be connected via I²C. */ -#define LIS3LV02DL_ID 0x3A /* Also the LIS3LV02DQ */ -#define LIS302DL_ID 0x3B /* Also the LIS202DL! */ +/* 2-byte registers */ +#define LIS_DOUBLE_ID 0x3A /* LIS3LV02D[LQ] */ +/* 1-byte registers */ +#define LIS_SINGLE_ID 0x3B /* LIS[32]02DL and others */ enum lis3lv02d_reg { WHO_AM_I = 0x0F, @@ -44,10 +47,13 @@ enum lis3lv02d_reg { STATUS_REG = 0x27, OUTX_L = 0x28, OUTX_H = 0x29, + OUTX = 0x29, OUTY_L = 0x2A, OUTY_H = 0x2B, + OUTY = 0x2B, OUTZ_L = 0x2C, OUTZ_H = 0x2D, + OUTZ = 0x2D, FF_WU_CFG = 0x30, FF_WU_SRC = 0x31, FF_WU_ACK = 0x32, @@ -159,6 +165,10 @@ struct acpi_lis3lv02d { acpi_status (*write) (acpi_handle handle, int reg, u8 val); acpi_status (*read) (acpi_handle handle, int reg, u8 *ret); + u8 whoami; /* 3Ah: 2-byte registries, 3Bh: 1-byte registries */ + s16 (*read_data) (acpi_handle handle, int reg); + int mdps_max_val; + struct input_dev *idev; /* input device */ struct task_struct *kthread; /* kthread for input */ struct mutex lock; -- cgit From 9ccf3b5e8409927835c4d38cb2f380c9e4349e76 Mon Sep 17 00:00:00 2001 From: Giuseppe Bilotta Date: Wed, 18 Feb 2009 14:48:25 -0800 Subject: lis3lv02d: add axes knowledge of HP Pavilion dv5 models Add support for HP Pavilion dv5. Since Intel-based models have an inverted x axis, while AMD-based models have an inverted y axis, we introduce a new macro that special-cases axis orientation based on two DMI entries: HP dv5 axis configuration is then based on both the PRODUCT and BOARD name. Signed-off-by: Giuseppe Bilotta Cc: Eric Piel Cc: Pavel Machek Tested-by: Palatis Tseng Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/hwmon/hp_accel.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c index 6b16566c4e6..29c83b5b969 100644 --- a/drivers/hwmon/hp_accel.c +++ b/drivers/hwmon/hp_accel.c @@ -166,6 +166,18 @@ static struct axis_conversion lis3lv02d_axis_xy_swap_yz_inverted = {2, -1, -3}; }, \ .driver_data = &lis3lv02d_axis_##_axis \ } + +#define AXIS_DMI_MATCH2(_ident, _class1, _name1, \ + _class2, _name2, \ + _axis) { \ + .ident = _ident, \ + .callback = lis3lv02d_dmi_matched, \ + .matches = { \ + DMI_MATCH(DMI_##_class1, _name1), \ + DMI_MATCH(DMI_##_class2, _name2), \ + }, \ + .driver_data = &lis3lv02d_axis_##_axis \ +} static struct dmi_system_id lis3lv02d_dmi_ids[] = { /* product names are truncated to match all kinds of a same model */ AXIS_DMI_MATCH("NC64x0", "HP Compaq nc64", x_inverted), @@ -179,6 +191,16 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = { AXIS_DMI_MATCH("NC673x", "HP Compaq 673", xy_rotated_left_usd), AXIS_DMI_MATCH("NC651xx", "HP Compaq 651", xy_rotated_right), AXIS_DMI_MATCH("NC671xx", "HP Compaq 671", xy_swap_yz_inverted), + /* Intel-based HP Pavilion dv5 */ + AXIS_DMI_MATCH2("HPDV5_I", + PRODUCT_NAME, "HP Pavilion dv5", + BOARD_NAME, "3603", + x_inverted), + /* AMD-based HP Pavilion dv5 */ + AXIS_DMI_MATCH2("HPDV5_A", + PRODUCT_NAME, "HP Pavilion dv5", + BOARD_NAME, "3600", + y_inverted), { NULL, } /* Laptop models without axis info (yet): * "NC6910" "HP Compaq 6910" -- cgit From 287d859222e0adbc67666a6154aaf42d7d5bbb54 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 18 Feb 2009 14:48:26 -0800 Subject: atmel-mci: fix initialization of dma slave data The conversion of atmel-mci to dma_request_channel missed the initialization of the channel dma_slave information. The filter_fn passed to dma_request_channel is responsible for initializing the channel's private data. This implementation has the additional benefit of enabling a generic client-channel data passing mechanism. Reviewed-by: Atsushi Nemoto Signed-off-by: Dan Williams Acked-by: Haavard Skinnemoen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/dma/dmaengine.c | 2 ++ drivers/dma/dw_dmac.c | 5 ++--- drivers/dma/dw_dmac_regs.h | 2 -- drivers/mmc/host/atmel-mci.c | 5 +++-- include/linux/dmaengine.h | 2 ++ 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index a58993011ed..280a9d263eb 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -518,6 +518,7 @@ struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, v dma_chan_name(chan), err); else break; + chan->private = NULL; chan = NULL; } } @@ -536,6 +537,7 @@ void dma_release_channel(struct dma_chan *chan) WARN_ONCE(chan->client_count != 1, "chan reference count %d != 1\n", chan->client_count); dma_chan_put(chan); + chan->private = NULL; mutex_unlock(&dma_list_mutex); } EXPORT_SYMBOL_GPL(dma_release_channel); diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index 6b702cc46b3..a97c07eef7e 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -560,7 +560,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, unsigned long flags) { struct dw_dma_chan *dwc = to_dw_dma_chan(chan); - struct dw_dma_slave *dws = dwc->dws; + struct dw_dma_slave *dws = chan->private; struct dw_desc *prev; struct dw_desc *first; u32 ctllo; @@ -790,7 +790,7 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan) cfghi = DWC_CFGH_FIFO_MODE; cfglo = 0; - dws = dwc->dws; + dws = chan->private; if (dws) { /* * We need controller-specific data to set up slave @@ -866,7 +866,6 @@ static void dwc_free_chan_resources(struct dma_chan *chan) spin_lock_bh(&dwc->lock); list_splice_init(&dwc->free_list, &list); dwc->descs_allocated = 0; - dwc->dws = NULL; /* Disable interrupts */ channel_clear_bit(dw, MASK.XFER, dwc->mask); diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw_dmac_regs.h index 00fdd187bb0..b252b202c5c 100644 --- a/drivers/dma/dw_dmac_regs.h +++ b/drivers/dma/dw_dmac_regs.h @@ -139,8 +139,6 @@ struct dw_dma_chan { struct list_head queue; struct list_head free_list; - struct dw_dma_slave *dws; - unsigned int descs_allocated; }; diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 76bfe16c09b..2b1196e6142 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -1548,9 +1548,10 @@ static bool filter(struct dma_chan *chan, void *slave) { struct dw_dma_slave *dws = slave; - if (dws->dma_dev == chan->device->dev) + if (dws->dma_dev == chan->device->dev) { + chan->private = dws; return true; - else + } else return false; } #endif diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 3e68469c188..f0413845f20 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -121,6 +121,7 @@ struct dma_chan_percpu { * @local: per-cpu pointer to a struct dma_chan_percpu * @client-count: how many clients are using this channel * @table_count: number of appearances in the mem-to-mem allocation table + * @private: private data for certain client-channel associations */ struct dma_chan { struct dma_device *device; @@ -134,6 +135,7 @@ struct dma_chan { struct dma_chan_percpu *local; int client_count; int table_count; + void *private; }; /** -- cgit From 27c0c8e511fa9e2389503926840fac606d90a049 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Wed, 18 Feb 2009 14:48:28 -0800 Subject: atmel_serial might lose modem status change I found a problem of handling of modem status of atmel_serial driver. With the commit 1ecc26 ("atmel_serial: split the interrupt handler"), handling of modem status signal was splitted into two parts. The atmel_tasklet_func() compares new status with irq_status_prev, but irq_status_prev is not correct if signal status was changed while the port is closed. Here is a sequence to cause problem: 1. Remote side sets CTS (and DSR). 2. Local side close the port. 3. Local side clears RTS and DTR. 4. Remote side clears CTS and DSR. 5. Local side reopen the port. hw_stopped becomes 1. 6. Local side sets RTS and DTR. 7. Remote side sets CTS and DSR. Then CTS change interrupt can be received, but since CTS bit in irq_status_prev and new status is same, uart_handle_cts_change() will not be called (so hw_stopped will not be cleared, i.e. cannot send any data). I suppose irq_status_prev should be initialized at somewhere in open sequence. Itai Levi pointed out that we need to initialize atmel_port->irq_status as well here. His analysis is as follows: > Regarding the second part of the patch (which resets irq_status_prev), > it turns out that both versions of the patch (mine and Atsushi's) > still leave enough room for faulty behavior when opening the port. > > This is because we are not resetting both irq_status_prev and > irq_status in atmel_startup() to CSR, which leads faulty behavior in > the following sequences: > > First case: > 1. closing the port while CTS line = 1 (TX not allowed) > 2. setting CTS line = 0 (TX allowed) > 3. opening the port > 4. transmitting one char > 5. Cannot transmit more chars, although CTS line is 0 > > Second case: > 1. closing the port while CTS line = 0 (TX allowed) > 2. setting CTS line = 1 (TX not allowed) > 3. opening the port > 4. receiving some chars > 5. Now we can transmit, although CTS line is 1 > > This reason for this is that the tasklet is scheduled as a result of > TX or RX interrupts (not a status change!), in steps 4 above. Inside > the tasklet, the atmel_port->irq_status (which holds the value from > the previous session) is compared to atmel_port->irq_status_prev. > Hence, a status-change of the CTS line is faultily detected. > > Both cases were verified on 9260 hardware. [haavard.skinnemoen@atmel.com: folded with patch from Itai Levi] Signed-off-by: Atsushi Nemoto Signed-off-by: Haavard Skinnemoen Cc: Remy Bohmer Cc: Marc Pignat Cc: Itai Levi Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/atmel_serial.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c index 89362d733d6..8f58f7ff0dd 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/serial/atmel_serial.c @@ -877,6 +877,10 @@ static int atmel_startup(struct uart_port *port) } } + /* Save current CSR for comparison in atmel_tasklet_func() */ + atmel_port->irq_status_prev = UART_GET_CSR(port); + atmel_port->irq_status = atmel_port->irq_status_prev; + /* * Finally, enable the serial port */ -- cgit From ada723dcd681e2dffd7d73345cc8fda0eb0df9bd Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 18 Feb 2009 14:48:30 -0800 Subject: fs/super.c: add lockdep annotation to s_umount Li Zefan said: Thread 1: for ((; ;)) { mount -t cpuset xxx /mnt > /dev/null 2>&1 cat /mnt/cpus > /dev/null 2>&1 umount /mnt > /dev/null 2>&1 } Thread 2: for ((; ;)) { mount -t cpuset xxx /mnt > /dev/null 2>&1 umount /mnt > /dev/null 2>&1 } (Note: It is irrelevant which cgroup subsys is used.) After a while a lockdep warning showed up: ============================================= [ INFO: possible recursive locking detected ] 2.6.28 #479 --------------------------------------------- mount/13554 is trying to acquire lock: (&type->s_umount_key#19){--..}, at: [] sget+0x5e/0x321 but task is already holding lock: (&type->s_umount_key#19){--..}, at: [] sget+0x1e2/0x321 other info that might help us debug this: 1 lock held by mount/13554: #0: (&type->s_umount_key#19){--..}, at: [] sget+0x1e2/0x321 stack backtrace: Pid: 13554, comm: mount Not tainted 2.6.28-mc #479 Call Trace: [] validate_chain+0x4c6/0xbbd [] __lock_acquire+0x676/0x700 [] lock_acquire+0x5d/0x7a [] ? sget+0x5e/0x321 [] down_write+0x34/0x50 [] ? sget+0x5e/0x321 [] sget+0x5e/0x321 [] ? cgroup_set_super+0x0/0x3e [] ? cgroup_test_super+0x0/0x2f [] cgroup_get_sb+0x98/0x2e7 [] cpuset_get_sb+0x4a/0x5f [] vfs_kern_mount+0x40/0x7b [] do_kern_mount+0x37/0xbf [] do_mount+0x5c3/0x61a [] ? copy_mount_options+0x2c/0x111 [] sys_mount+0x69/0xa0 [] sysenter_do_call+0x12/0x31 The cause is after alloc_super() and then retry, an old entry in list fs_supers is found, so grab_super(old) is called, but both functions hold s_umount lock: struct super_block *sget(...) { ... retry: spin_lock(&sb_lock); if (test) { list_for_each_entry(old, &type->fs_supers, s_instances) { if (!test(old, data)) continue; if (!grab_super(old)) <--- 2nd: down_write(&old->s_umount); goto retry; if (s) destroy_super(s); return old; } } if (!s) { spin_unlock(&sb_lock); s = alloc_super(type); <--- 1th: down_write(&s->s_umount) if (!s) return ERR_PTR(-ENOMEM); goto retry; } ... } It seems like a false positive, and seems like VFS but not cgroup needs to be fixed. Peter said: We can simply put the new s_umount instance in a but lockdep doesn't particularly cares about subclass order. If there's any issue with the callers of sget() assuming the s_umount lock being of sublcass 0, then there is another annotation we can use to fix that, but lets not bother with that if this is sufficient. Addresses http://bugzilla.kernel.org/show_bug.cgi?id=12673 Signed-off-by: Peter Zijlstra Tested-by: Li Zefan Reported-by: Li Zefan Cc: Al Viro Cc: Paul Menage Cc: Arjan van de Ven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/super.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/fs/super.c b/fs/super.c index 61dce001dd5..8349ed6b141 100644 --- a/fs/super.c +++ b/fs/super.c @@ -82,7 +82,22 @@ static struct super_block *alloc_super(struct file_system_type *type) * lock ordering than usbfs: */ lockdep_set_class(&s->s_lock, &type->s_lock_key); - down_write(&s->s_umount); + /* + * sget() can have s_umount recursion. + * + * When it cannot find a suitable sb, it allocates a new + * one (this one), and tries again to find a suitable old + * one. + * + * In case that succeeds, it will acquire the s_umount + * lock of the old one. Since these are clearly distrinct + * locks, and this object isn't exposed yet, there's no + * risk of deadlocks. + * + * Annotate this by putting this lock in a different + * subclass. + */ + down_write_nested(&s->s_umount, SINGLE_DEPTH_NESTING); s->s_count = S_BIAS; atomic_set(&s->s_active, 1); mutex_init(&s->s_vfs_rename_mutex); -- cgit From f2dbcfa738368c8a40d4a5f0b65dc9879577cb21 Mon Sep 17 00:00:00 2001 From: KAMEZAWA Hiroyuki Date: Wed, 18 Feb 2009 14:48:32 -0800 Subject: mm: clean up for early_pfn_to_nid() What's happening is that the assertion in mm/page_alloc.c:move_freepages() is triggering: BUG_ON(page_zone(start_page) != page_zone(end_page)); Once I knew this is what was happening, I added some annotations: if (unlikely(page_zone(start_page) != page_zone(end_page))) { printk(KERN_ERR "move_freepages: Bogus zones: " "start_page[%p] end_page[%p] zone[%p]\n", start_page, end_page, zone); printk(KERN_ERR "move_freepages: " "start_zone[%p] end_zone[%p]\n", page_zone(start_page), page_zone(end_page)); printk(KERN_ERR "move_freepages: " "start_pfn[0x%lx] end_pfn[0x%lx]\n", page_to_pfn(start_page), page_to_pfn(end_page)); printk(KERN_ERR "move_freepages: " "start_nid[%d] end_nid[%d]\n", page_to_nid(start_page), page_to_nid(end_page)); ... And here's what I got: move_freepages: Bogus zones: start_page[2207d0000] end_page[2207dffc0] zone[fffff8103effcb00] move_freepages: start_zone[fffff8103effcb00] end_zone[fffff8003fffeb00] move_freepages: start_pfn[0x81f600] end_pfn[0x81f7ff] move_freepages: start_nid[1] end_nid[0] My memory layout on this box is: [ 0.000000] Zone PFN ranges: [ 0.000000] Normal 0x00000000 -> 0x0081ff5d [ 0.000000] Movable zone start PFN for each node [ 0.000000] early_node_map[8] active PFN ranges [ 0.000000] 0: 0x00000000 -> 0x00020000 [ 0.000000] 1: 0x00800000 -> 0x0081f7ff [ 0.000000] 1: 0x0081f800 -> 0x0081fe50 [ 0.000000] 1: 0x0081fed1 -> 0x0081fed8 [ 0.000000] 1: 0x0081feda -> 0x0081fedb [ 0.000000] 1: 0x0081fedd -> 0x0081fee5 [ 0.000000] 1: 0x0081fee7 -> 0x0081ff51 [ 0.000000] 1: 0x0081ff59 -> 0x0081ff5d So it's a block move in that 0x81f600-->0x81f7ff region which triggers the problem. This patch: Declaration of early_pfn_to_nid() is scattered over per-arch include files, and it seems it's complicated to know when the declaration is used. I think it makes fix-for-memmap-init not easy. This patch moves all declaration to include/linux/mm.h After this, if !CONFIG_NODES_POPULATES_NODE_MAP && !CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID -> Use static definition in include/linux/mm.h else if !CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID -> Use generic definition in mm/page_alloc.c else -> per-arch back end function will be called. Signed-off-by: KAMEZAWA Hiroyuki Tested-by: KOSAKI Motohiro Reported-by: David Miller Cc: Mel Gorman Cc: Heiko Carstens Cc: [2.6.25.x, 2.6.26.x, 2.6.27.x, 2.6.28.x] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/include/asm/mmzone.h | 4 ---- arch/ia64/mm/numa.c | 2 +- arch/x86/include/asm/mmzone_32.h | 2 -- arch/x86/include/asm/mmzone_64.h | 2 -- arch/x86/mm/numa_64.c | 2 +- include/linux/mm.h | 19 ++++++++++++++++--- mm/page_alloc.c | 8 +++++++- 7 files changed, 25 insertions(+), 14 deletions(-) diff --git a/arch/ia64/include/asm/mmzone.h b/arch/ia64/include/asm/mmzone.h index 34efe88eb84..f2ca32069b3 100644 --- a/arch/ia64/include/asm/mmzone.h +++ b/arch/ia64/include/asm/mmzone.h @@ -31,10 +31,6 @@ static inline int pfn_to_nid(unsigned long pfn) #endif } -#ifdef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID -extern int early_pfn_to_nid(unsigned long pfn); -#endif - #ifdef CONFIG_IA64_DIG /* DIG systems are small */ # define MAX_PHYSNODE_ID 8 # define NR_NODE_MEMBLKS (MAX_NUMNODES * 8) diff --git a/arch/ia64/mm/numa.c b/arch/ia64/mm/numa.c index b73bf1838e5..5061c3fb679 100644 --- a/arch/ia64/mm/numa.c +++ b/arch/ia64/mm/numa.c @@ -58,7 +58,7 @@ paddr_to_nid(unsigned long paddr) * SPARSEMEM to allocate the SPARSEMEM sectionmap on the NUMA node where * the section resides. */ -int early_pfn_to_nid(unsigned long pfn) +int __meminit __early_pfn_to_nid(unsigned long pfn) { int i, section = pfn >> PFN_SECTION_SHIFT, ssec, esec; diff --git a/arch/x86/include/asm/mmzone_32.h b/arch/x86/include/asm/mmzone_32.h index 07f1af494ca..105fb90a063 100644 --- a/arch/x86/include/asm/mmzone_32.h +++ b/arch/x86/include/asm/mmzone_32.h @@ -32,8 +32,6 @@ static inline void get_memcfg_numa(void) get_memcfg_numa_flat(); } -extern int early_pfn_to_nid(unsigned long pfn); - extern void resume_map_numa_kva(pgd_t *pgd); #else /* !CONFIG_NUMA */ diff --git a/arch/x86/include/asm/mmzone_64.h b/arch/x86/include/asm/mmzone_64.h index a5b3817d4b9..a29f48c2a32 100644 --- a/arch/x86/include/asm/mmzone_64.h +++ b/arch/x86/include/asm/mmzone_64.h @@ -40,8 +40,6 @@ static inline __attribute__((pure)) int phys_to_nid(unsigned long addr) #define node_end_pfn(nid) (NODE_DATA(nid)->node_start_pfn + \ NODE_DATA(nid)->node_spanned_pages) -extern int early_pfn_to_nid(unsigned long pfn); - #ifdef CONFIG_NUMA_EMU #define FAKE_NODE_MIN_SIZE (64 * 1024 * 1024) #define FAKE_NODE_MIN_HASH_MASK (~(FAKE_NODE_MIN_SIZE - 1UL)) diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c index 71a14f89f89..f3516da035d 100644 --- a/arch/x86/mm/numa_64.c +++ b/arch/x86/mm/numa_64.c @@ -145,7 +145,7 @@ int __init compute_hash_shift(struct bootnode *nodes, int numnodes, return shift; } -int early_pfn_to_nid(unsigned long pfn) +int __meminit __early_pfn_to_nid(unsigned long pfn) { return phys_to_nid(pfn << PAGE_SHIFT); } diff --git a/include/linux/mm.h b/include/linux/mm.h index 10074212a35..065cdf8c09f 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1041,10 +1041,23 @@ extern void free_bootmem_with_active_regions(int nid, typedef int (*work_fn_t)(unsigned long, unsigned long, void *); extern void work_with_active_regions(int nid, work_fn_t work_fn, void *data); extern void sparse_memory_present_with_active_regions(int nid); -#ifndef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID -extern int early_pfn_to_nid(unsigned long pfn); -#endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */ #endif /* CONFIG_ARCH_POPULATES_NODE_MAP */ + +#if !defined(CONFIG_ARCH_POPULATES_NODE_MAP) && \ + !defined(CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID) +static inline int __early_pfn_to_nid(unsigned long pfn) +{ + return 0; +} +#else +/* please see mm/page_alloc.c */ +extern int __meminit early_pfn_to_nid(unsigned long pfn); +#ifdef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID +/* there is a per-arch backend function. */ +extern int __meminit __early_pfn_to_nid(unsigned long pfn); +#endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */ +#endif + extern void set_dma_reserve(unsigned long new_dma_reserve); extern void memmap_init_zone(unsigned long, int, unsigned long, unsigned long, enum memmap_context); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 5675b307385..c5dd74602ef 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2989,7 +2989,7 @@ static int __meminit next_active_region_index_in_nid(int index, int nid) * was used and there are no special requirements, this is a convenient * alternative */ -int __meminit early_pfn_to_nid(unsigned long pfn) +int __meminit __early_pfn_to_nid(unsigned long pfn) { int i; @@ -3005,6 +3005,12 @@ int __meminit early_pfn_to_nid(unsigned long pfn) } #endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */ +int __meminit early_pfn_to_nid(unsigned long pfn) +{ + return __early_pfn_to_nid(pfn); +} + + /* Basic iterator support to walk early_node_map[] */ #define for_each_active_range_index_in_nid(i, nid) \ for (i = first_active_region_index_in_nid(nid); i != -1; \ -- cgit From cc2559bccc72767cb446f79b071d96c30c26439b Mon Sep 17 00:00:00 2001 From: KAMEZAWA Hiroyuki Date: Wed, 18 Feb 2009 14:48:33 -0800 Subject: mm: fix memmap init for handling memory hole Now, early_pfn_in_nid(PFN, NID) may returns false if PFN is a hole. and memmap initialization was not done. This was a trouble for sparc boot. To fix this, the PFN should be initialized and marked as PG_reserved. This patch changes early_pfn_in_nid() return true if PFN is a hole. Signed-off-by: KAMEZAWA Hiroyuki Reported-by: David Miller Tested-by: KOSAKI Motohiro Cc: Mel Gorman Cc: Heiko Carstens Cc: [2.6.25.x, 2.6.26.x, 2.6.27.x, 2.6.28.x] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/mm/numa.c | 2 +- include/linux/mmzone.h | 2 +- mm/page_alloc.c | 23 ++++++++++++++++++++--- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/arch/ia64/mm/numa.c b/arch/ia64/mm/numa.c index 5061c3fb679..3efea7d0a35 100644 --- a/arch/ia64/mm/numa.c +++ b/arch/ia64/mm/numa.c @@ -70,7 +70,7 @@ int __meminit __early_pfn_to_nid(unsigned long pfn) return node_memblk[i].nid; } - return 0; + return -1; } #ifdef CONFIG_MEMORY_HOTPLUG diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 09c14e213b6..1aca6cebbb7 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -1071,7 +1071,7 @@ void sparse_init(void); #endif /* CONFIG_SPARSEMEM */ #ifdef CONFIG_NODES_SPAN_OTHER_NODES -#define early_pfn_in_nid(pfn, nid) (early_pfn_to_nid(pfn) == (nid)) +bool early_pfn_in_nid(unsigned long pfn, int nid); #else #define early_pfn_in_nid(pfn, nid) (1) #endif diff --git a/mm/page_alloc.c b/mm/page_alloc.c index c5dd74602ef..5c44ed49ca9 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -3000,16 +3000,33 @@ int __meminit __early_pfn_to_nid(unsigned long pfn) if (start_pfn <= pfn && pfn < end_pfn) return early_node_map[i].nid; } - - return 0; + /* This is a memory hole */ + return -1; } #endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */ int __meminit early_pfn_to_nid(unsigned long pfn) { - return __early_pfn_to_nid(pfn); + int nid; + + nid = __early_pfn_to_nid(pfn); + if (nid >= 0) + return nid; + /* just returns 0 */ + return 0; } +#ifdef CONFIG_NODES_SPAN_OTHER_NODES +bool __meminit early_pfn_in_nid(unsigned long pfn, int node) +{ + int nid; + + nid = __early_pfn_to_nid(pfn); + if (nid >= 0 && nid != node) + return false; + return true; +} +#endif /* Basic iterator support to walk early_node_map[] */ #define for_each_active_range_index_in_nid(i, nid) \ -- cgit From ffa7525c13eb3db0fd19a3e1cffe2ce6f561f5f3 Mon Sep 17 00:00:00 2001 From: Adam Lackorzynski Date: Wed, 18 Feb 2009 14:48:34 -0800 Subject: jsm: additional device support I have a Digi Neo 8 PCI card (114f:00b1) Serial controller: Digi International Digi Neo 8 (rev 05) that works with the jsm driver after using the following patch. Signed-off-by: Adam Lackorzynski Cc: Scott H Kilau Cc: Wendy Xiong Acked-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/jsm/jsm_driver.c | 3 +++ include/linux/pci_ids.h | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/serial/jsm/jsm_driver.c index 92187e28608..ac79cbe4c2c 100644 --- a/drivers/serial/jsm/jsm_driver.c +++ b/drivers/serial/jsm/jsm_driver.c @@ -84,6 +84,8 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) brd->pci_dev = pdev; if (pdev->device == PCIE_DEVICE_ID_NEO_4_IBM) brd->maxports = 4; + else if (pdev->device == PCI_DEVICE_ID_DIGI_NEO_8) + brd->maxports = 8; else brd->maxports = 2; @@ -212,6 +214,7 @@ static struct pci_device_id jsm_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2RJ45), 0, 0, 2 }, { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2RJ45PRI), 0, 0, 3 }, { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_4_IBM), 0, 0, 4 }, + { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_NEO_8), 0, 0, 5 }, { 0, } }; MODULE_DEVICE_TABLE(pci, jsm_pci_tbl); diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 918391b4b10..114b8192eab 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1445,6 +1445,7 @@ #define PCI_DEVICE_ID_DIGI_DF_M_E 0x0071 #define PCI_DEVICE_ID_DIGI_DF_M_IOM2_A 0x0072 #define PCI_DEVICE_ID_DIGI_DF_M_A 0x0073 +#define PCI_DEVICE_ID_DIGI_NEO_8 0x00B1 #define PCI_DEVICE_ID_NEO_2DB9 0x00C8 #define PCI_DEVICE_ID_NEO_2DB9PRI 0x00C9 #define PCI_DEVICE_ID_NEO_2RJ45 0x00CA -- cgit From 5a74db06cc8d36a325913aa4968ae169f997a466 Mon Sep 17 00:00:00 2001 From: Philippe De Muyter Date: Wed, 18 Feb 2009 14:48:36 -0800 Subject: floppy: request and release only the ports we actually use The floppy driver requests an I/O port it doesn't need, and sometimes this causes a conflict with a motherboard device reported by PNPBIOS. This patch makes the floppy driver request and release only the ports it actually uses. It also factors out the request/release stuff and the io-ports list so they're all in one place now. The current floppy driver uses only these ports: 0x3f2 (FD_DOR) 0x3f4 (FD_STATUS) 0x3f5 (FD_DATA) 0x3f7 (FD_DCR/FD_DIR) but it requests 0x3f2-0x3f5 and 0x3f7, which includes the unused port 0x3f3. Some BIOSes report 0x3f3 as a motherboard resource. The PNP system driver reserves that, which causes a conflict when the floppy driver requests 0x3f2-0x3f5 later. Philippe reported that this conflict broke the floppy driver between 2.6.11 and 2.6.22. His PNPBIOS reports these devices: $ cat 00:07/id 00:07/resources # motherboard device PNP0c02 state = active io 0x80-0x80 io 0x10-0x1f io 0x22-0x3f io 0x44-0x5f io 0x90-0x9f io 0xa2-0xbf io 0x3f0-0x3f1 io 0x3f3-0x3f3 $ cat 00:03/id 00:03/resources # floppy device PNP0700 state = active io 0x3f4-0x3f5 io 0x3f2-0x3f2 Reference: http://lkml.org/lkml/2009/1/31/162 Signed-off-by: Bjorn Helgaas Signed-off-by: Philippe De Muyter Reported-by: Philippe De Muyter Tested-by: Philippe De Muyter Cc: Adam M Belay Cc: Robert Hancock Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/floppy.c | 79 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 27 deletions(-) diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index cf29cc4e6ab..83d8ed39433 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -558,6 +558,8 @@ static void process_fd_request(void); static void recalibrate_floppy(void); static void floppy_shutdown(unsigned long); +static int floppy_request_regions(int); +static void floppy_release_regions(int); static int floppy_grab_irq_and_dma(void); static void floppy_release_irq_and_dma(void); @@ -4274,8 +4276,7 @@ static int __init floppy_init(void) FDCS->rawcmd = 2; if (user_reset_fdc(-1, FD_RESET_ALWAYS, 0)) { /* free ioports reserved by floppy_grab_irq_and_dma() */ - release_region(FDCS->address + 2, 4); - release_region(FDCS->address + 7, 1); + floppy_release_regions(fdc); FDCS->address = -1; FDCS->version = FDC_NONE; continue; @@ -4284,8 +4285,7 @@ static int __init floppy_init(void) FDCS->version = get_fdc_version(); if (FDCS->version == FDC_NONE) { /* free ioports reserved by floppy_grab_irq_and_dma() */ - release_region(FDCS->address + 2, 4); - release_region(FDCS->address + 7, 1); + floppy_release_regions(fdc); FDCS->address = -1; continue; } @@ -4358,6 +4358,47 @@ out_put_disk: static DEFINE_SPINLOCK(floppy_usage_lock); +static const struct io_region { + int offset; + int size; +} io_regions[] = { + { 2, 1 }, + /* address + 3 is sometimes reserved by pnp bios for motherboard */ + { 4, 2 }, + /* address + 6 is reserved, and may be taken by IDE. + * Unfortunately, Adaptec doesn't know this :-(, */ + { 7, 1 }, +}; + +static void floppy_release_allocated_regions(int fdc, const struct io_region *p) +{ + while (p != io_regions) { + p--; + release_region(FDCS->address + p->offset, p->size); + } +} + +#define ARRAY_END(X) (&((X)[ARRAY_SIZE(X)])) + +static int floppy_request_regions(int fdc) +{ + const struct io_region *p; + + for (p = io_regions; p < ARRAY_END(io_regions); p++) { + if (!request_region(FDCS->address + p->offset, p->size, "floppy")) { + DPRINT("Floppy io-port 0x%04lx in use\n", FDCS->address + p->offset); + floppy_release_allocated_regions(fdc, p); + return -EBUSY; + } + } + return 0; +} + +static void floppy_release_regions(int fdc) +{ + floppy_release_allocated_regions(fdc, ARRAY_END(io_regions)); +} + static int floppy_grab_irq_and_dma(void) { unsigned long flags; @@ -4399,18 +4440,8 @@ static int floppy_grab_irq_and_dma(void) for (fdc = 0; fdc < N_FDC; fdc++) { if (FDCS->address != -1) { - if (!request_region(FDCS->address + 2, 4, "floppy")) { - DPRINT("Floppy io-port 0x%04lx in use\n", - FDCS->address + 2); - goto cleanup1; - } - if (!request_region(FDCS->address + 7, 1, "floppy DIR")) { - DPRINT("Floppy io-port 0x%04lx in use\n", - FDCS->address + 7); - goto cleanup2; - } - /* address + 6 is reserved, and may be taken by IDE. - * Unfortunately, Adaptec doesn't know this :-(, */ + if (floppy_request_regions(fdc)) + goto cleanup; } } for (fdc = 0; fdc < N_FDC; fdc++) { @@ -4432,15 +4463,11 @@ static int floppy_grab_irq_and_dma(void) fdc = 0; irqdma_allocated = 1; return 0; -cleanup2: - release_region(FDCS->address + 2, 4); -cleanup1: +cleanup: fd_free_irq(); fd_free_dma(); - while (--fdc >= 0) { - release_region(FDCS->address + 2, 4); - release_region(FDCS->address + 7, 1); - } + while (--fdc >= 0) + floppy_release_regions(fdc); spin_lock_irqsave(&floppy_usage_lock, flags); usage_count--; spin_unlock_irqrestore(&floppy_usage_lock, flags); @@ -4501,10 +4528,8 @@ static void floppy_release_irq_and_dma(void) #endif old_fdc = fdc; for (fdc = 0; fdc < N_FDC; fdc++) - if (FDCS->address != -1) { - release_region(FDCS->address + 2, 4); - release_region(FDCS->address + 7, 1); - } + if (FDCS->address != -1) + floppy_release_regions(fdc); fdc = old_fdc; } -- cgit From a1a5c3b9237662f326cc730e167e7524b5d05a36 Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Wed, 18 Feb 2009 14:48:38 -0800 Subject: fbdev/drm: fix Kconfig submenu mess in "Graphics support" Submenus of the graphics support "Support for frame buffer devices" and "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)" are broken in half after latest changes for Intel 915 mode setting support. The DRM subsection is broken because one option is put outside the choice section it depends on. The frame buffers part is broken then due to circular dependency. Fix this by make Intel frame buffers depend on CONFIG_INTEL_AGP. Kconfigs are broken by d2f59357700487a8b944f4f7777d1e97cf5ea2ed ("drm/i915: select framebuffer support automatically"). This is probably not only way to fix this. Signed-off-by: Krzysztof Helt Cc: Ingo Molnar Cc: Dave Airlie Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/gpu/drm/Kconfig | 13 ++++++------- drivers/video/Kconfig | 10 ++-------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 4be3acbaaf9..3a22eb9be37 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -80,18 +80,17 @@ config DRM_I915 XFree86 4.4 and above. If unsure, build this and i830 as modules and the X server will load the correct one. -endchoice - config DRM_I915_KMS bool "Enable modesetting on intel by default" depends on DRM_I915 help - Choose this option if you want kernel modesetting enabled by default, - and you have a new enough userspace to support this. Running old - userspaces with this enabled will cause pain. Note that this causes - the driver to bind to PCI devices, which precludes loading things - like intelfb. + Choose this option if you want kernel modesetting enabled by default, + and you have a new enough userspace to support this. Running old + userspaces with this enabled will cause pain. Note that this causes + the driver to bind to PCI devices, which precludes loading things + like intelfb. +endchoice config DRM_MGA tristate "Matrox g200/g400" diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index bf0af660df8..fb19803060c 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -1054,10 +1054,7 @@ config FB_RIVA_BACKLIGHT config FB_I810 tristate "Intel 810/815 support (EXPERIMENTAL)" - depends on EXPERIMENTAL && PCI && X86_32 - select AGP - select AGP_INTEL - select FB + depends on EXPERIMENTAL && FB && PCI && X86_32 && AGP_INTEL select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA @@ -1120,10 +1117,7 @@ config FB_CARILLO_RANCH config FB_INTEL tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support (EXPERIMENTAL)" - depends on EXPERIMENTAL && PCI && X86 - select FB - select AGP - select AGP_INTEL + depends on EXPERIMENTAL && FB && PCI && X86 && AGP_INTEL select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA -- cgit From 2db69a9340da12a4db44edb7506dd68799aeff55 Mon Sep 17 00:00:00 2001 From: Bill Nottingham Date: Wed, 18 Feb 2009 14:48:39 -0800 Subject: vt: Declare PIO_CMAP/GIO_CMAP as compatbile ioctls. Otherwise, these don't work when called from 32-bit userspace on 64-bit kernels. Cc: Jiri Kosina Cc: Alan Cox Cc: [2.6.25.x, 2.6.26.x, 2.6.27.x, 2.6.28.x] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/compat_ioctl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 9c6d815dd19..39bd4d38e88 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -1938,6 +1938,8 @@ ULONG_IOCTL(SET_BITMAP_FILE) /* Big K */ COMPATIBLE_IOCTL(PIO_FONT) COMPATIBLE_IOCTL(GIO_FONT) +COMPATIBLE_IOCTL(PIO_CMAP) +COMPATIBLE_IOCTL(GIO_CMAP) ULONG_IOCTL(KDSIGACCEPT) COMPATIBLE_IOCTL(KDGETKEYCODE) COMPATIBLE_IOCTL(KDSETKEYCODE) -- cgit From 310d8c93f9f07499cd7ca82d7997774a89de00e7 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 18 Feb 2009 14:48:39 -0800 Subject: x86: dell-laptop: depends on POWER_SUPPLY Build breaks when DELL_LAPTOP=y and POWER_SUPPLY=m. DELL_LAPTOP needs to depend on POWER_SUPPLY. dell-laptop.c:(.text+0x1ef3c4): undefined reference to `power_supply_is_system_supplied' dell-laptop.c:(.text+0x1ef45e): undefined reference to `power_supply_is_system_supplied' Signed-off-by: Randy Dunlap Cc: Matthew Garrett Cc: Ingo Molnar Cc: Thomas Gleixner Cc: "H. Peter Anvin" Cc: Len Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/platform/x86/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 6bce56c2262..b3866ad5022 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -62,6 +62,7 @@ config DELL_LAPTOP depends on EXPERIMENTAL depends on BACKLIGHT_CLASS_DEVICE depends on RFKILL + depends on POWER_SUPPLY default n ---help--- This driver adds support for rfkill and backlight control to Dell -- cgit From 97bef7dd05563807539122c488a5dd93ed327722 Mon Sep 17 00:00:00 2001 From: Bernhard Walle Date: Wed, 18 Feb 2009 14:48:40 -0800 Subject: Bernhard has moved Since I don't work for SUSE any more and the bwalle@suse.de address is invalid, correct it in the copyright headers and documentation. Signed-off-by: Bernhard Walle Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/ABI/testing/sysfs-firmware-memmap | 2 +- drivers/firmware/memmap.c | 2 +- include/linux/firmware-map.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-firmware-memmap b/Documentation/ABI/testing/sysfs-firmware-memmap index 0d99ee6ae02..eca0d65087d 100644 --- a/Documentation/ABI/testing/sysfs-firmware-memmap +++ b/Documentation/ABI/testing/sysfs-firmware-memmap @@ -1,6 +1,6 @@ What: /sys/firmware/memmap/ Date: June 2008 -Contact: Bernhard Walle +Contact: Bernhard Walle Description: On all platforms, the firmware provides a memory map which the kernel reads. The resources from that memory map are registered diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c index 261b9aa3f24..05aa2d406ac 100644 --- a/drivers/firmware/memmap.c +++ b/drivers/firmware/memmap.c @@ -1,7 +1,7 @@ /* * linux/drivers/firmware/memmap.c * Copyright (C) 2008 SUSE LINUX Products GmbH - * by Bernhard Walle + * by Bernhard Walle * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License v2.0 as published by diff --git a/include/linux/firmware-map.h b/include/linux/firmware-map.h index 6e199c8dfac..cca686b3912 100644 --- a/include/linux/firmware-map.h +++ b/include/linux/firmware-map.h @@ -1,7 +1,7 @@ /* * include/linux/firmware-map.h: * Copyright (C) 2008 SUSE LINUX Products GmbH - * by Bernhard Walle + * by Bernhard Walle * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License v2.0 as published by -- cgit From be50344e604f956891fc0013f1ba78823a758124 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Wed, 18 Feb 2009 14:48:41 -0800 Subject: spi-gpio: sanitize MISO bitvalue gpio_get_value() returns 0 or nonzero, but getmiso() expects 0 or 1. Sanitize the value to a 0/1 boolean. Signed-off-by: Michael Buesch Acked-by: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/spi/spi_gpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi_gpio.c b/drivers/spi/spi_gpio.c index 49698cabc30..f5ed9721aab 100644 --- a/drivers/spi/spi_gpio.c +++ b/drivers/spi/spi_gpio.c @@ -114,7 +114,7 @@ static inline void setmosi(const struct spi_device *spi, int is_on) static inline int getmiso(const struct spi_device *spi) { - return gpio_get_value(SPI_MISO_GPIO); + return !!gpio_get_value(SPI_MISO_GPIO); } #undef pdata -- cgit From f04b30de3c82528f1ab4c58b3dd4c975f5341901 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 18 Feb 2009 14:48:43 -0800 Subject: inotify: fix GFP_KERNEL related deadlock Enhanced lockdep coverage of __GFP_NOFS turned up this new lockdep assert: [ 1093.677775] [ 1093.677781] ================================= [ 1093.680031] [ INFO: inconsistent lock state ] [ 1093.680031] 2.6.29-rc5-tip-01504-gb49eca1-dirty #1 [ 1093.680031] --------------------------------- [ 1093.680031] inconsistent {RECLAIM_FS-ON-W} -> {IN-RECLAIM_FS-W} usage. [ 1093.680031] kswapd0/308 [HC0[0]:SC0[0]:HE1:SE1] takes: [ 1093.680031] (&inode->inotify_mutex){+.+.?.}, at: [] inotify_inode_is_dead+0x20/0x80 [ 1093.680031] {RECLAIM_FS-ON-W} state was registered at: [ 1093.680031] [] mark_held_locks+0x43/0x5b [ 1093.680031] [] lockdep_trace_alloc+0x6c/0x6e [ 1093.680031] [] kmem_cache_alloc+0x20/0x150 [ 1093.680031] [] idr_pre_get+0x27/0x6c [ 1093.680031] [] inotify_handle_get_wd+0x25/0xad [ 1093.680031] [] inotify_add_watch+0x7a/0x129 [ 1093.680031] [] sys_inotify_add_watch+0x20f/0x250 [ 1093.680031] [] sysenter_do_call+0x12/0x35 [ 1093.680031] [] 0xffffffff [ 1093.680031] irq event stamp: 60417 [ 1093.680031] hardirqs last enabled at (60417): [] call_rcu+0x53/0x59 [ 1093.680031] hardirqs last disabled at (60416): [] call_rcu+0x17/0x59 [ 1093.680031] softirqs last enabled at (59656): [] __do_softirq+0x157/0x16b [ 1093.680031] softirqs last disabled at (59651): [] do_softirq+0x74/0x15d [ 1093.680031] [ 1093.680031] other info that might help us debug this: [ 1093.680031] 2 locks held by kswapd0/308: [ 1093.680031] #0: (shrinker_rwsem){++++..}, at: [] shrink_slab+0x36/0x189 [ 1093.680031] #1: (&type->s_umount_key#4){+++++.}, at: [] shrink_dcache_memory+0x110/0x1fb [ 1093.680031] [ 1093.680031] stack backtrace: [ 1093.680031] Pid: 308, comm: kswapd0 Not tainted 2.6.29-rc5-tip-01504-gb49eca1-dirty #1 [ 1093.680031] Call Trace: [ 1093.680031] [] valid_state+0x12a/0x13d [ 1093.680031] [] mark_lock+0xc1/0x1e9 [ 1093.680031] [] ? check_usage_forwards+0x0/0x3f [ 1093.680031] [] __lock_acquire+0x2c6/0xac8 [ 1093.680031] [] ? register_lock_class+0x17/0x228 [ 1093.680031] [] lock_acquire+0x5d/0x7a [ 1093.680031] [] ? inotify_inode_is_dead+0x20/0x80 [ 1093.680031] [] __mutex_lock_common+0x3a/0x4cb [ 1093.680031] [] ? inotify_inode_is_dead+0x20/0x80 [ 1093.680031] [] mutex_lock_nested+0x2e/0x36 [ 1093.680031] [] ? inotify_inode_is_dead+0x20/0x80 [ 1093.680031] [] inotify_inode_is_dead+0x20/0x80 [ 1093.680031] [] dentry_iput+0x90/0xc2 [ 1093.680031] [] d_kill+0x21/0x45 [ 1093.680031] [] __shrink_dcache_sb+0x27f/0x355 [ 1093.680031] [] shrink_dcache_memory+0x15e/0x1fb [ 1093.680031] [] shrink_slab+0x121/0x189 [ 1093.680031] [] kswapd+0x39f/0x561 [ 1093.680031] [] ? isolate_pages_global+0x0/0x233 [ 1093.680031] [] ? autoremove_wake_function+0x0/0x43 [ 1093.680031] [] ? kswapd+0x0/0x561 [ 1093.680031] [] kthread+0x41/0x82 [ 1093.680031] [] ? kthread+0x0/0x82 [ 1093.680031] [] kernel_thread_helper+0x7/0x10 inotify_handle_get_wd() does idr_pre_get() which does a kmem_cache_alloc() without __GFP_FS - and is hence deadlockable under extreme MM pressure. Signed-off-by: Ingo Molnar Acked-by: Peter Zijlstra Cc: MinChan Kim Cc: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/notify/inotify/inotify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/notify/inotify/inotify.c b/fs/notify/inotify/inotify.c index dae3f28f30d..331f2e88e28 100644 --- a/fs/notify/inotify/inotify.c +++ b/fs/notify/inotify/inotify.c @@ -156,7 +156,7 @@ static int inotify_handle_get_wd(struct inotify_handle *ih, int ret; do { - if (unlikely(!idr_pre_get(&ih->idr, GFP_KERNEL))) + if (unlikely(!idr_pre_get(&ih->idr, GFP_NOFS))) return -ENOSPC; ret = idr_get_new_above(&ih->idr, watch, ih->last_wd+1, &watch->wd); } while (ret == -EAGAIN); -- cgit From 43250ddd75a35d1f7926d989a10fefd30c37eaa7 Mon Sep 17 00:00:00 2001 From: Jie Yang Date: Wed, 18 Feb 2009 17:24:15 -0800 Subject: atl1c: Atheros L1C Gigabit Ethernet driver Supporting AR8131, and AR8132. Signed-off-by: Jie Yang Signed-off-by: David S. Miller --- drivers/net/Kconfig | 11 + drivers/net/Makefile | 1 + drivers/net/atl1c/Makefile | 2 + drivers/net/atl1c/atl1c.h | 606 ++++++++ drivers/net/atl1c/atl1c_ethtool.c | 317 +++++ drivers/net/atl1c/atl1c_hw.c | 527 +++++++ drivers/net/atl1c/atl1c_hw.h | 859 ++++++++++++ drivers/net/atl1c/atl1c_main.c | 2797 +++++++++++++++++++++++++++++++++++++ 8 files changed, 5120 insertions(+) create mode 100644 drivers/net/atl1c/Makefile create mode 100644 drivers/net/atl1c/atl1c.h create mode 100644 drivers/net/atl1c/atl1c_ethtool.c create mode 100644 drivers/net/atl1c/atl1c_hw.c create mode 100644 drivers/net/atl1c/atl1c_hw.h create mode 100644 drivers/net/atl1c/atl1c_main.c diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 6bdfd47d679..a2f185fd707 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2342,6 +2342,17 @@ config ATL1E To compile this driver as a module, choose M here. The module will be called atl1e. +config ATL1C + tristate "Atheros L1C Gigabit Ethernet support (EXPERIMENTAL)" + depends on PCI && EXPERIMENTAL + select CRC32 + select MII + help + This driver supports the Atheros L1C gigabit ethernet adapter. + + To compile this driver as a module, choose M here. The module + will be called atl1c. + config JME tristate "JMicron(R) PCI-Express Gigabit Ethernet support" depends on PCI diff --git a/drivers/net/Makefile b/drivers/net/Makefile index a3c5c002f22..aca8492db65 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_BONDING) += bonding/ obj-$(CONFIG_ATL1) += atlx/ obj-$(CONFIG_ATL2) += atlx/ obj-$(CONFIG_ATL1E) += atl1e/ +obj-$(CONFIG_ATL1C) += atl1c/ obj-$(CONFIG_GIANFAR) += gianfar_driver.o obj-$(CONFIG_TEHUTI) += tehuti.o obj-$(CONFIG_ENIC) += enic/ diff --git a/drivers/net/atl1c/Makefile b/drivers/net/atl1c/Makefile new file mode 100644 index 00000000000..c37d966952e --- /dev/null +++ b/drivers/net/atl1c/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_ATL1C) += atl1c.o +atl1c-objs := atl1c_main.o atl1c_hw.o atl1c_ethtool.o diff --git a/drivers/net/atl1c/atl1c.h b/drivers/net/atl1c/atl1c.h new file mode 100644 index 00000000000..ac11b84b837 --- /dev/null +++ b/drivers/net/atl1c/atl1c.h @@ -0,0 +1,606 @@ +/* + * Copyright(c) 2008 - 2009 Atheros Corporation. All rights reserved. + * + * Derived from Intel e1000 driver + * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _ATL1C_H_ +#define _ATL1C_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "atl1c_hw.h" + +/* Wake Up Filter Control */ +#define AT_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */ +#define AT_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */ +#define AT_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */ +#define AT_WUFC_MC 0x00000008 /* Multicast Wakeup Enable */ +#define AT_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */ + +#define AT_VLAN_TO_TAG(_vlan, _tag) \ + _tag = ((((_vlan) >> 8) & 0xFF) |\ + (((_vlan) & 0xFF) << 8)) + +#define AT_TAG_TO_VLAN(_tag, _vlan) \ + _vlan = ((((_tag) >> 8) & 0xFF) |\ + (((_tag) & 0xFF) << 8)) + +#define SPEED_0 0xffff +#define HALF_DUPLEX 1 +#define FULL_DUPLEX 2 + +#define AT_RX_BUF_SIZE (ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN) +#define MAX_JUMBO_FRAME_SIZE (9*1024) +#define MAX_TX_OFFLOAD_THRESH (9*1024) + +#define AT_MAX_RECEIVE_QUEUE 4 +#define AT_DEF_RECEIVE_QUEUE 1 +#define AT_MAX_TRANSMIT_QUEUE 2 + +#define AT_DMA_HI_ADDR_MASK 0xffffffff00000000ULL +#define AT_DMA_LO_ADDR_MASK 0x00000000ffffffffULL + +#define AT_TX_WATCHDOG (5 * HZ) +#define AT_MAX_INT_WORK 5 +#define AT_TWSI_EEPROM_TIMEOUT 100 +#define AT_HW_MAX_IDLE_DELAY 10 +#define AT_SUSPEND_LINK_TIMEOUT 28 + +#define AT_ASPM_L0S_TIMER 6 +#define AT_ASPM_L1_TIMER 12 + +#define ATL1C_PCIE_L0S_L1_DISABLE 0x01 +#define ATL1C_PCIE_PHY_RESET 0x02 + +#define ATL1C_ASPM_L0s_ENABLE 0x0001 +#define ATL1C_ASPM_L1_ENABLE 0x0002 + +#define AT_REGS_LEN (75 * sizeof(u32)) +#define AT_EEPROM_LEN 512 + +#define ATL1C_GET_DESC(R, i, type) (&(((type *)((R)->desc))[i])) +#define ATL1C_RFD_DESC(R, i) ATL1C_GET_DESC(R, i, struct atl1c_rx_free_desc) +#define ATL1C_TPD_DESC(R, i) ATL1C_GET_DESC(R, i, struct atl1c_tpd_desc) +#define ATL1C_RRD_DESC(R, i) ATL1C_GET_DESC(R, i, struct atl1c_recv_ret_status) + +/* tpd word 1 bit 0:7 General Checksum task offload */ +#define TPD_L4HDR_OFFSET_MASK 0x00FF +#define TPD_L4HDR_OFFSET_SHIFT 0 + +/* tpd word 1 bit 0:7 Large Send task offload (IPv4/IPV6) */ +#define TPD_TCPHDR_OFFSET_MASK 0x00FF +#define TPD_TCPHDR_OFFSET_SHIFT 0 + +/* tpd word 1 bit 0:7 Custom Checksum task offload */ +#define TPD_PLOADOFFSET_MASK 0x00FF +#define TPD_PLOADOFFSET_SHIFT 0 + +/* tpd word 1 bit 8:17 */ +#define TPD_CCSUM_EN_MASK 0x0001 +#define TPD_CCSUM_EN_SHIFT 8 +#define TPD_IP_CSUM_MASK 0x0001 +#define TPD_IP_CSUM_SHIFT 9 +#define TPD_TCP_CSUM_MASK 0x0001 +#define TPD_TCP_CSUM_SHIFT 10 +#define TPD_UDP_CSUM_MASK 0x0001 +#define TPD_UDP_CSUM_SHIFT 11 +#define TPD_LSO_EN_MASK 0x0001 /* TCP Large Send Offload */ +#define TPD_LSO_EN_SHIFT 12 +#define TPD_LSO_VER_MASK 0x0001 +#define TPD_LSO_VER_SHIFT 13 /* 0 : ipv4; 1 : ipv4/ipv6 */ +#define TPD_CON_VTAG_MASK 0x0001 +#define TPD_CON_VTAG_SHIFT 14 +#define TPD_INS_VTAG_MASK 0x0001 +#define TPD_INS_VTAG_SHIFT 15 +#define TPD_IPV4_PACKET_MASK 0x0001 /* valid when LSO VER is 1 */ +#define TPD_IPV4_PACKET_SHIFT 16 +#define TPD_ETH_TYPE_MASK 0x0001 +#define TPD_ETH_TYPE_SHIFT 17 /* 0 : 802.3 frame; 1 : Ethernet */ + +/* tpd word 18:25 Custom Checksum task offload */ +#define TPD_CCSUM_OFFSET_MASK 0x00FF +#define TPD_CCSUM_OFFSET_SHIFT 18 +#define TPD_CCSUM_EPAD_MASK 0x0001 +#define TPD_CCSUM_EPAD_SHIFT 30 + +/* tpd word 18:30 Large Send task offload (IPv4/IPV6) */ +#define TPD_MSS_MASK 0x1FFF +#define TPD_MSS_SHIFT 18 + +#define TPD_EOP_MASK 0x0001 +#define TPD_EOP_SHIFT 31 + +struct atl1c_tpd_desc { + __le16 buffer_len; /* include 4-byte CRC */ + __le16 vlan_tag; + __le32 word1; + __le64 buffer_addr; +}; + +struct atl1c_tpd_ext_desc { + u32 reservd_0; + __le32 word1; + __le32 pkt_len; + u32 reservd_1; +}; +/* rrs word 0 bit 0:31 */ +#define RRS_RX_CSUM_MASK 0xFFFF +#define RRS_RX_CSUM_SHIFT 0 +#define RRS_RX_RFD_CNT_MASK 0x000F +#define RRS_RX_RFD_CNT_SHIFT 16 +#define RRS_RX_RFD_INDEX_MASK 0x0FFF +#define RRS_RX_RFD_INDEX_SHIFT 20 + +/* rrs flag bit 0:16 */ +#define RRS_HEAD_LEN_MASK 0x00FF +#define RRS_HEAD_LEN_SHIFT 0 +#define RRS_HDS_TYPE_MASK 0x0003 +#define RRS_HDS_TYPE_SHIFT 8 +#define RRS_CPU_NUM_MASK 0x0003 +#define RRS_CPU_NUM_SHIFT 10 +#define RRS_HASH_FLG_MASK 0x000F +#define RRS_HASH_FLG_SHIFT 12 + +#define RRS_HDS_TYPE_HEAD 1 +#define RRS_HDS_TYPE_DATA 2 + +#define RRS_IS_NO_HDS_TYPE(flag) \ + (((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK == 0) + +#define RRS_IS_HDS_HEAD(flag) \ + (((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK == \ + RRS_HDS_TYPE_HEAD) + +#define RRS_IS_HDS_DATA(flag) \ + (((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK == \ + RRS_HDS_TYPE_DATA) + +/* rrs word 3 bit 0:31 */ +#define RRS_PKT_SIZE_MASK 0x3FFF +#define RRS_PKT_SIZE_SHIFT 0 +#define RRS_ERR_L4_CSUM_MASK 0x0001 +#define RRS_ERR_L4_CSUM_SHIFT 14 +#define RRS_ERR_IP_CSUM_MASK 0x0001 +#define RRS_ERR_IP_CSUM_SHIFT 15 +#define RRS_VLAN_INS_MASK 0x0001 +#define RRS_VLAN_INS_SHIFT 16 +#define RRS_PROT_ID_MASK 0x0007 +#define RRS_PROT_ID_SHIFT 17 +#define RRS_RX_ERR_SUM_MASK 0x0001 +#define RRS_RX_ERR_SUM_SHIFT 20 +#define RRS_RX_ERR_CRC_MASK 0x0001 +#define RRS_RX_ERR_CRC_SHIFT 21 +#define RRS_RX_ERR_FAE_MASK 0x0001 +#define RRS_RX_ERR_FAE_SHIFT 22 +#define RRS_RX_ERR_TRUNC_MASK 0x0001 +#define RRS_RX_ERR_TRUNC_SHIFT 23 +#define RRS_RX_ERR_RUNC_MASK 0x0001 +#define RRS_RX_ERR_RUNC_SHIFT 24 +#define RRS_RX_ERR_ICMP_MASK 0x0001 +#define RRS_RX_ERR_ICMP_SHIFT 25 +#define RRS_PACKET_BCAST_MASK 0x0001 +#define RRS_PACKET_BCAST_SHIFT 26 +#define RRS_PACKET_MCAST_MASK 0x0001 +#define RRS_PACKET_MCAST_SHIFT 27 +#define RRS_PACKET_TYPE_MASK 0x0001 +#define RRS_PACKET_TYPE_SHIFT 28 +#define RRS_FIFO_FULL_MASK 0x0001 +#define RRS_FIFO_FULL_SHIFT 29 +#define RRS_802_3_LEN_ERR_MASK 0x0001 +#define RRS_802_3_LEN_ERR_SHIFT 30 +#define RRS_RXD_UPDATED_MASK 0x0001 +#define RRS_RXD_UPDATED_SHIFT 31 + +#define RRS_ERR_L4_CSUM 0x00004000 +#define RRS_ERR_IP_CSUM 0x00008000 +#define RRS_VLAN_INS 0x00010000 +#define RRS_RX_ERR_SUM 0x00100000 +#define RRS_RX_ERR_CRC 0x00200000 +#define RRS_802_3_LEN_ERR 0x40000000 +#define RRS_RXD_UPDATED 0x80000000 + +#define RRS_PACKET_TYPE_802_3 1 +#define RRS_PACKET_TYPE_ETH 0 +#define RRS_PACKET_IS_ETH(word) \ + (((word) >> RRS_PACKET_TYPE_SHIFT) & RRS_PACKET_TYPE_MASK == \ + RRS_PACKET_TYPE_ETH) +#define RRS_RXD_IS_VALID(word) \ + ((((word) >> RRS_RXD_UPDATED_SHIFT) & RRS_RXD_UPDATED_MASK) == 1) + +#define RRS_PACKET_PROT_IS_IPV4_ONLY(word) \ + ((((word) >> RRS_PROT_ID_SHIFT) & RRS_PROT_ID_MASK) == 1) +#define RRS_PACKET_PROT_IS_IPV6_ONLY(word) \ + ((((word) >> RRS_PROT_ID_SHIFT) & RRS_PROT_ID_MASK) == 6) + +struct atl1c_recv_ret_status { + __le32 word0; + __le32 rss_hash; + __le16 vlan_tag; + __le16 flag; + __le32 word3; +}; + +/* RFD desciptor */ +struct atl1c_rx_free_desc { + __le64 buffer_addr; +}; + +/* DMA Order Settings */ +enum atl1c_dma_order { + atl1c_dma_ord_in = 1, + atl1c_dma_ord_enh = 2, + atl1c_dma_ord_out = 4 +}; + +enum atl1c_dma_rcb { + atl1c_rcb_64 = 0, + atl1c_rcb_128 = 1 +}; + +enum atl1c_mac_speed { + atl1c_mac_speed_0 = 0, + atl1c_mac_speed_10_100 = 1, + atl1c_mac_speed_1000 = 2 +}; + +enum atl1c_dma_req_block { + atl1c_dma_req_128 = 0, + atl1c_dma_req_256 = 1, + atl1c_dma_req_512 = 2, + atl1c_dma_req_1024 = 3, + atl1c_dma_req_2048 = 4, + atl1c_dma_req_4096 = 5 +}; + +enum atl1c_rss_mode { + atl1c_rss_mode_disable = 0, + atl1c_rss_sig_que = 1, + atl1c_rss_mul_que_sig_int = 2, + atl1c_rss_mul_que_mul_int = 4, +}; + +enum atl1c_rss_type { + atl1c_rss_disable = 0, + atl1c_rss_ipv4 = 1, + atl1c_rss_ipv4_tcp = 2, + atl1c_rss_ipv6 = 4, + atl1c_rss_ipv6_tcp = 8 +}; + +enum atl1c_nic_type { + athr_l1c = 0, + athr_l2c = 1, +}; + +enum atl1c_trans_queue { + atl1c_trans_normal = 0, + atl1c_trans_high = 1 +}; + +struct atl1c_hw_stats { + /* rx */ + unsigned long rx_ok; /* The number of good packet received. */ + unsigned long rx_bcast; /* The number of good broadcast packet received. */ + unsigned long rx_mcast; /* The number of good multicast packet received. */ + unsigned long rx_pause; /* The number of Pause packet received. */ + unsigned long rx_ctrl; /* The number of Control packet received other than Pause frame. */ + unsigned long rx_fcs_err; /* The number of packets with bad FCS. */ + unsigned long rx_len_err; /* The number of packets with mismatch of length field and actual size. */ + unsigned long rx_byte_cnt; /* The number of bytes of good packet received. FCS is NOT included. */ + unsigned long rx_runt; /* The number of packets received that are less than 64 byte long and with good FCS. */ + unsigned long rx_frag; /* The number of packets received that are less than 64 byte long and with bad FCS. */ + unsigned long rx_sz_64; /* The number of good and bad packets received that are 64 byte long. */ + unsigned long rx_sz_65_127; /* The number of good and bad packets received that are between 65 and 127-byte long. */ + unsigned long rx_sz_128_255; /* The number of good and bad packets received that are between 128 and 255-byte long. */ + unsigned long rx_sz_256_511; /* The number of good and bad packets received that are between 256 and 511-byte long. */ + unsigned long rx_sz_512_1023; /* The number of good and bad packets received that are between 512 and 1023-byte long. */ + unsigned long rx_sz_1024_1518; /* The number of good and bad packets received that are between 1024 and 1518-byte long. */ + unsigned long rx_sz_1519_max; /* The number of good and bad packets received that are between 1519-byte and MTU. */ + unsigned long rx_sz_ov; /* The number of good and bad packets received that are more than MTU size truncated by Selene. */ + unsigned long rx_rxf_ov; /* The number of frame dropped due to occurrence of RX FIFO overflow. */ + unsigned long rx_rrd_ov; /* The number of frame dropped due to occurrence of RRD overflow. */ + unsigned long rx_align_err; /* Alignment Error */ + unsigned long rx_bcast_byte_cnt; /* The byte count of broadcast packet received, excluding FCS. */ + unsigned long rx_mcast_byte_cnt; /* The byte count of multicast packet received, excluding FCS. */ + unsigned long rx_err_addr; /* The number of packets dropped due to address filtering. */ + + /* tx */ + unsigned long tx_ok; /* The number of good packet transmitted. */ + unsigned long tx_bcast; /* The number of good broadcast packet transmitted. */ + unsigned long tx_mcast; /* The number of good multicast packet transmitted. */ + unsigned long tx_pause; /* The number of Pause packet transmitted. */ + unsigned long tx_exc_defer; /* The number of packets transmitted with excessive deferral. */ + unsigned long tx_ctrl; /* The number of packets transmitted is a control frame, excluding Pause frame. */ + unsigned long tx_defer; /* The number of packets transmitted that is deferred. */ + unsigned long tx_byte_cnt; /* The number of bytes of data transmitted. FCS is NOT included. */ + unsigned long tx_sz_64; /* The number of good and bad packets transmitted that are 64 byte long. */ + unsigned long tx_sz_65_127; /* The number of good and bad packets transmitted that are between 65 and 127-byte long. */ + unsigned long tx_sz_128_255; /* The number of good and bad packets transmitted that are between 128 and 255-byte long. */ + unsigned long tx_sz_256_511; /* The number of good and bad packets transmitted that are between 256 and 511-byte long. */ + unsigned long tx_sz_512_1023; /* The number of good and bad packets transmitted that are between 512 and 1023-byte long. */ + unsigned long tx_sz_1024_1518; /* The number of good and bad packets transmitted that are between 1024 and 1518-byte long. */ + unsigned long tx_sz_1519_max; /* The number of good and bad packets transmitted that are between 1519-byte and MTU. */ + unsigned long tx_1_col; /* The number of packets subsequently transmitted successfully with a single prior collision. */ + unsigned long tx_2_col; /* The number of packets subsequently transmitted successfully with multiple prior collisions. */ + unsigned long tx_late_col; /* The number of packets transmitted with late collisions. */ + unsigned long tx_abort_col; /* The number of transmit packets aborted due to excessive collisions. */ + unsigned long tx_underrun; /* The number of transmit packets aborted due to transmit FIFO underrun, or TRD FIFO underrun */ + unsigned long tx_rd_eop; /* The number of times that read beyond the EOP into the next frame area when TRD was not written timely */ + unsigned long tx_len_err; /* The number of transmit packets with length field does NOT match the actual frame size. */ + unsigned long tx_trunc; /* The number of transmit packets truncated due to size exceeding MTU. */ + unsigned long tx_bcast_byte; /* The byte count of broadcast packet transmitted, excluding FCS. */ + unsigned long tx_mcast_byte; /* The byte count of multicast packet transmitted, excluding FCS. */ +}; + +struct atl1c_hw { + u8 __iomem *hw_addr; /* inner register address */ + struct atl1c_adapter *adapter; + enum atl1c_nic_type nic_type; + enum atl1c_dma_order dma_order; + enum atl1c_dma_rcb rcb_value; + enum atl1c_dma_req_block dmar_block; + enum atl1c_dma_req_block dmaw_block; + + u16 device_id; + u16 vendor_id; + u16 subsystem_id; + u16 subsystem_vendor_id; + u8 revision_id; + + u32 intr_mask; + u8 dmaw_dly_cnt; + u8 dmar_dly_cnt; + + u8 preamble_len; + u16 max_frame_size; + u16 min_frame_size; + + enum atl1c_mac_speed mac_speed; + bool mac_duplex; + bool hibernate; + u16 media_type; +#define MEDIA_TYPE_AUTO_SENSOR 0 +#define MEDIA_TYPE_100M_FULL 1 +#define MEDIA_TYPE_100M_HALF 2 +#define MEDIA_TYPE_10M_FULL 3 +#define MEDIA_TYPE_10M_HALF 4 + + u16 autoneg_advertised; + u16 mii_autoneg_adv_reg; + u16 mii_1000t_ctrl_reg; + + u16 tx_imt; /* TX Interrupt Moderator timer ( 2us resolution) */ + u16 rx_imt; /* RX Interrupt Moderator timer ( 2us resolution) */ + u16 ict; /* Interrupt Clear timer (2us resolution) */ + u16 ctrl_flags; +#define ATL1C_INTR_CLEAR_ON_READ 0x0001 +#define ATL1C_INTR_MODRT_ENABLE 0x0002 +#define ATL1C_CMB_ENABLE 0x0004 +#define ATL1C_SMB_ENABLE 0x0010 +#define ATL1C_TXQ_MODE_ENHANCE 0x0020 +#define ATL1C_RX_IPV6_CHKSUM 0x0040 +#define ATL1C_ASPM_L0S_SUPPORT 0x0080 +#define ATL1C_ASPM_L1_SUPPORT 0x0100 +#define ATL1C_ASPM_CTRL_MON 0x0200 +#define ATL1C_HIB_DISABLE 0x0400 +#define ATL1C_LINK_CAP_1000M 0x0800 +#define ATL1C_FPGA_VERSION 0x8000 + u16 cmb_tpd; + u16 cmb_rrd; + u16 cmb_rx_timer; /* 2us resolution */ + u16 cmb_tx_timer; + u32 smb_timer; + + u16 rrd_thresh; /* Threshold of number of RRD produced to trigger + interrupt request */ + u16 tpd_thresh; + u8 tpd_burst; /* Number of TPD to prefetch in cache-aligned burst. */ + u8 rfd_burst; + enum atl1c_rss_type rss_type; + enum atl1c_rss_mode rss_mode; + u8 rss_hash_bits; + u32 base_cpu; + u32 indirect_tab; + u8 mac_addr[ETH_ALEN]; + u8 perm_mac_addr[ETH_ALEN]; + + bool phy_configured; + bool re_autoneg; + bool emi_ca; +}; + +/* + * atl1c_ring_header represents a single, contiguous block of DMA space + * mapped for the three descriptor rings (tpd, rfd, rrd) and the two + * message blocks (cmb, smb) described below + */ +struct atl1c_ring_header { + void *desc; /* virtual address */ + dma_addr_t dma; /* physical address*/ + unsigned int size; /* length in bytes */ +}; + +/* + * atl1c_buffer is wrapper around a pointer to a socket buffer + * so a DMA handle can be stored along with the skb + */ +struct atl1c_buffer { + struct sk_buff *skb; /* socket buffer */ + u16 length; /* rx buffer length */ + u16 state; /* state of buffer */ +#define ATL1_BUFFER_FREE 0 +#define ATL1_BUFFER_BUSY 1 + dma_addr_t dma; +}; + +/* transimit packet descriptor (tpd) ring */ +struct atl1c_tpd_ring { + void *desc; /* descriptor ring virtual address */ + dma_addr_t dma; /* descriptor ring physical address */ + u16 size; /* descriptor ring length in bytes */ + u16 count; /* number of descriptors in the ring */ + u16 next_to_use; /* this is protectd by adapter->tx_lock */ + atomic_t next_to_clean; + struct atl1c_buffer *buffer_info; +}; + +/* receive free descriptor (rfd) ring */ +struct atl1c_rfd_ring { + void *desc; /* descriptor ring virtual address */ + dma_addr_t dma; /* descriptor ring physical address */ + u16 size; /* descriptor ring length in bytes */ + u16 count; /* number of descriptors in the ring */ + u16 next_to_use; + u16 next_to_clean; + struct atl1c_buffer *buffer_info; +}; + +/* receive return desciptor (rrd) ring */ +struct atl1c_rrd_ring { + void *desc; /* descriptor ring virtual address */ + dma_addr_t dma; /* descriptor ring physical address */ + u16 size; /* descriptor ring length in bytes */ + u16 count; /* number of descriptors in the ring */ + u16 next_to_use; + u16 next_to_clean; +}; + +struct atl1c_cmb { + void *cmb; + dma_addr_t dma; +}; + +struct atl1c_smb { + void *smb; + dma_addr_t dma; +}; + +/* board specific private data structure */ +struct atl1c_adapter { + struct net_device *netdev; + struct pci_dev *pdev; + struct vlan_group *vlgrp; + struct napi_struct napi; + struct atl1c_hw hw; + struct atl1c_hw_stats hw_stats; + struct net_device_stats net_stats; + struct mii_if_info mii; /* MII interface info */ + u16 rx_buffer_len; + + unsigned long flags; +#define __AT_TESTING 0x0001 +#define __AT_RESETTING 0x0002 +#define __AT_DOWN 0x0003 + u32 msg_enable; + + bool have_msi; + u32 wol; + u16 link_speed; + u16 link_duplex; + + spinlock_t mdio_lock; + spinlock_t tx_lock; + atomic_t irq_sem; + + struct work_struct reset_task; + struct work_struct link_chg_task; + struct timer_list watchdog_timer; + struct timer_list phy_config_timer; + + /* All Descriptor memory */ + struct atl1c_ring_header ring_header; + struct atl1c_tpd_ring tpd_ring[AT_MAX_TRANSMIT_QUEUE]; + struct atl1c_rfd_ring rfd_ring[AT_MAX_RECEIVE_QUEUE]; + struct atl1c_rrd_ring rrd_ring[AT_MAX_RECEIVE_QUEUE]; + struct atl1c_cmb cmb; + struct atl1c_smb smb; + int num_rx_queues; + u32 bd_number; /* board number;*/ +}; + +#define AT_WRITE_REG(a, reg, value) ( \ + writel((value), ((a)->hw_addr + reg))) + +#define AT_WRITE_FLUSH(a) (\ + readl((a)->hw_addr)) + +#define AT_READ_REG(a, reg, pdata) do { \ + if (unlikely((a)->hibernate)) { \ + readl((a)->hw_addr + reg); \ + *(u32 *)pdata = readl((a)->hw_addr + reg); \ + } else { \ + *(u32 *)pdata = readl((a)->hw_addr + reg); \ + } \ + } while (0) + +#define AT_WRITE_REGB(a, reg, value) (\ + writeb((value), ((a)->hw_addr + reg))) + +#define AT_READ_REGB(a, reg) (\ + readb((a)->hw_addr + reg)) + +#define AT_WRITE_REGW(a, reg, value) (\ + writew((value), ((a)->hw_addr + reg))) + +#define AT_READ_REGW(a, reg) (\ + readw((a)->hw_addr + reg)) + +#define AT_WRITE_REG_ARRAY(a, reg, offset, value) ( \ + writel((value), (((a)->hw_addr + reg) + ((offset) << 2)))) + +#define AT_READ_REG_ARRAY(a, reg, offset) ( \ + readl(((a)->hw_addr + reg) + ((offset) << 2))) + +extern char atl1c_driver_name[]; +extern char atl1c_driver_version[]; + +extern int atl1c_up(struct atl1c_adapter *adapter); +extern void atl1c_down(struct atl1c_adapter *adapter); +extern void atl1c_reinit_locked(struct atl1c_adapter *adapter); +extern s32 atl1c_reset_hw(struct atl1c_hw *hw); +extern void atl1c_set_ethtool_ops(struct net_device *netdev); +#endif /* _ATL1C_H_ */ diff --git a/drivers/net/atl1c/atl1c_ethtool.c b/drivers/net/atl1c/atl1c_ethtool.c new file mode 100644 index 00000000000..45c5b7332cd --- /dev/null +++ b/drivers/net/atl1c/atl1c_ethtool.c @@ -0,0 +1,317 @@ +/* + * Copyright(c) 2009 - 2009 Atheros Corporation. All rights reserved. + * + * Derived from Intel e1000 driver + * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "atl1c.h" + +static int atl1c_get_settings(struct net_device *netdev, + struct ethtool_cmd *ecmd) +{ + struct atl1c_adapter *adapter = netdev_priv(netdev); + struct atl1c_hw *hw = &adapter->hw; + + ecmd->supported = (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_Autoneg | + SUPPORTED_TP); + if (hw->ctrl_flags & ATL1C_LINK_CAP_1000M) + ecmd->supported |= SUPPORTED_1000baseT_Full; + + ecmd->advertising = ADVERTISED_TP; + + ecmd->advertising |= hw->autoneg_advertised; + + ecmd->port = PORT_TP; + ecmd->phy_address = 0; + ecmd->transceiver = XCVR_INTERNAL; + + if (adapter->link_speed != SPEED_0) { + ecmd->speed = adapter->link_speed; + if (adapter->link_duplex == FULL_DUPLEX) + ecmd->duplex = DUPLEX_FULL; + else + ecmd->duplex = DUPLEX_HALF; + } else { + ecmd->speed = -1; + ecmd->duplex = -1; + } + + ecmd->autoneg = AUTONEG_ENABLE; + return 0; +} + +static int atl1c_set_settings(struct net_device *netdev, + struct ethtool_cmd *ecmd) +{ + struct atl1c_adapter *adapter = netdev_priv(netdev); + struct atl1c_hw *hw = &adapter->hw; + u16 autoneg_advertised; + + while (test_and_set_bit(__AT_RESETTING, &adapter->flags)) + msleep(1); + + if (ecmd->autoneg == AUTONEG_ENABLE) { + autoneg_advertised = ADVERTISED_Autoneg; + } else { + if (ecmd->speed == SPEED_1000) { + if (ecmd->duplex != DUPLEX_FULL) { + if (netif_msg_link(adapter)) + dev_warn(&adapter->pdev->dev, + "1000M half is invalid\n"); + clear_bit(__AT_RESETTING, &adapter->flags); + return -EINVAL; + } + autoneg_advertised = ADVERTISED_1000baseT_Full; + } else if (ecmd->speed == SPEED_100) { + if (ecmd->duplex == DUPLEX_FULL) + autoneg_advertised = ADVERTISED_100baseT_Full; + else + autoneg_advertised = ADVERTISED_100baseT_Half; + } else { + if (ecmd->duplex == DUPLEX_FULL) + autoneg_advertised = ADVERTISED_10baseT_Full; + else + autoneg_advertised = ADVERTISED_10baseT_Half; + } + } + + if (hw->autoneg_advertised != autoneg_advertised) { + hw->autoneg_advertised = autoneg_advertised; + if (atl1c_restart_autoneg(hw) != 0) { + if (netif_msg_link(adapter)) + dev_warn(&adapter->pdev->dev, + "ethtool speed/duplex setting failed\n"); + clear_bit(__AT_RESETTING, &adapter->flags); + return -EINVAL; + } + } + clear_bit(__AT_RESETTING, &adapter->flags); + return 0; +} + +static u32 atl1c_get_tx_csum(struct net_device *netdev) +{ + return (netdev->features & NETIF_F_HW_CSUM) != 0; +} + +static u32 atl1c_get_msglevel(struct net_device *netdev) +{ + struct atl1c_adapter *adapter = netdev_priv(netdev); + return adapter->msg_enable; +} + +static void atl1c_set_msglevel(struct net_device *netdev, u32 data) +{ + struct atl1c_adapter *adapter = netdev_priv(netdev); + adapter->msg_enable = data; +} + +static int atl1c_get_regs_len(struct net_device *netdev) +{ + return AT_REGS_LEN; +} + +static void atl1c_get_regs(struct net_device *netdev, + struct ethtool_regs *regs, void *p) +{ + struct atl1c_adapter *adapter = netdev_priv(netdev); + struct atl1c_hw *hw = &adapter->hw; + u32 *regs_buff = p; + u16 phy_data; + + memset(p, 0, AT_REGS_LEN); + + regs->version = 0; + AT_READ_REG(hw, REG_VPD_CAP, p++); + AT_READ_REG(hw, REG_PM_CTRL, p++); + AT_READ_REG(hw, REG_MAC_HALF_DUPLX_CTRL, p++); + AT_READ_REG(hw, REG_TWSI_CTRL, p++); + AT_READ_REG(hw, REG_PCIE_DEV_MISC_CTRL, p++); + AT_READ_REG(hw, REG_MASTER_CTRL, p++); + AT_READ_REG(hw, REG_MANUAL_TIMER_INIT, p++); + AT_READ_REG(hw, REG_IRQ_MODRT_TIMER_INIT, p++); + AT_READ_REG(hw, REG_GPHY_CTRL, p++); + AT_READ_REG(hw, REG_LINK_CTRL, p++); + AT_READ_REG(hw, REG_IDLE_STATUS, p++); + AT_READ_REG(hw, REG_MDIO_CTRL, p++); + AT_READ_REG(hw, REG_SERDES_LOCK, p++); + AT_READ_REG(hw, REG_MAC_CTRL, p++); + AT_READ_REG(hw, REG_MAC_IPG_IFG, p++); + AT_READ_REG(hw, REG_MAC_STA_ADDR, p++); + AT_READ_REG(hw, REG_MAC_STA_ADDR+4, p++); + AT_READ_REG(hw, REG_RX_HASH_TABLE, p++); + AT_READ_REG(hw, REG_RX_HASH_TABLE+4, p++); + AT_READ_REG(hw, REG_RXQ_CTRL, p++); + AT_READ_REG(hw, REG_TXQ_CTRL, p++); + AT_READ_REG(hw, REG_MTU, p++); + AT_READ_REG(hw, REG_WOL_CTRL, p++); + + atl1c_read_phy_reg(hw, MII_BMCR, &phy_data); + regs_buff[73] = (u32) phy_data; + atl1c_read_phy_reg(hw, MII_BMSR, &phy_data); + regs_buff[74] = (u32) phy_data; +} + +static int atl1c_get_eeprom_len(struct net_device *netdev) +{ + struct atl1c_adapter *adapter = netdev_priv(netdev); + + if (atl1c_check_eeprom_exist(&adapter->hw)) + return AT_EEPROM_LEN; + else + return 0; +} + +static int atl1c_get_eeprom(struct net_device *netdev, + struct ethtool_eeprom *eeprom, u8 *bytes) +{ + struct atl1c_adapter *adapter = netdev_priv(netdev); + struct atl1c_hw *hw = &adapter->hw; + u32 *eeprom_buff; + int first_dword, last_dword; + int ret_val = 0; + int i; + + if (eeprom->len == 0) + return -EINVAL; + + if (!atl1c_check_eeprom_exist(hw)) /* not exist */ + return -EINVAL; + + eeprom->magic = adapter->pdev->vendor | + (adapter->pdev->device << 16); + + first_dword = eeprom->offset >> 2; + last_dword = (eeprom->offset + eeprom->len - 1) >> 2; + + eeprom_buff = kmalloc(sizeof(u32) * + (last_dword - first_dword + 1), GFP_KERNEL); + if (eeprom_buff == NULL) + return -ENOMEM; + + for (i = first_dword; i < last_dword; i++) { + if (!atl1c_read_eeprom(hw, i * 4, &(eeprom_buff[i-first_dword]))) { + kfree(eeprom_buff); + return -EIO; + } + } + + memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3), + eeprom->len); + kfree(eeprom_buff); + + return ret_val; + return 0; +} + +static void atl1c_get_drvinfo(struct net_device *netdev, + struct ethtool_drvinfo *drvinfo) +{ + struct atl1c_adapter *adapter = netdev_priv(netdev); + + strncpy(drvinfo->driver, atl1c_driver_name, sizeof(drvinfo->driver)); + strncpy(drvinfo->version, atl1c_driver_version, + sizeof(drvinfo->version)); + strncpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version)); + strncpy(drvinfo->bus_info, pci_name(adapter->pdev), + sizeof(drvinfo->bus_info)); + drvinfo->n_stats = 0; + drvinfo->testinfo_len = 0; + drvinfo->regdump_len = atl1c_get_regs_len(netdev); + drvinfo->eedump_len = atl1c_get_eeprom_len(netdev); +} + +static void atl1c_get_wol(struct net_device *netdev, + struct ethtool_wolinfo *wol) +{ + struct atl1c_adapter *adapter = netdev_priv(netdev); + + wol->supported = WAKE_MAGIC | WAKE_PHY; + wol->wolopts = 0; + + if (adapter->wol & AT_WUFC_EX) + wol->wolopts |= WAKE_UCAST; + if (adapter->wol & AT_WUFC_MC) + wol->wolopts |= WAKE_MCAST; + if (adapter->wol & AT_WUFC_BC) + wol->wolopts |= WAKE_BCAST; + if (adapter->wol & AT_WUFC_MAG) + wol->wolopts |= WAKE_MAGIC; + if (adapter->wol & AT_WUFC_LNKC) + wol->wolopts |= WAKE_PHY; + + return; +} + +static int atl1c_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) +{ + struct atl1c_adapter *adapter = netdev_priv(netdev); + + if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE | + WAKE_MCAST | WAKE_BCAST | WAKE_MCAST)) + return -EOPNOTSUPP; + /* these settings will always override what we currently have */ + adapter->wol = 0; + + if (wol->wolopts & WAKE_MAGIC) + adapter->wol |= AT_WUFC_MAG; + if (wol->wolopts & WAKE_PHY) + adapter->wol |= AT_WUFC_LNKC; + + return 0; +} + +static int atl1c_nway_reset(struct net_device *netdev) +{ + struct atl1c_adapter *adapter = netdev_priv(netdev); + if (netif_running(netdev)) + atl1c_reinit_locked(adapter); + return 0; +} + +static struct ethtool_ops atl1c_ethtool_ops = { + .get_settings = atl1c_get_settings, + .set_settings = atl1c_set_settings, + .get_drvinfo = atl1c_get_drvinfo, + .get_regs_len = atl1c_get_regs_len, + .get_regs = atl1c_get_regs, + .get_wol = atl1c_get_wol, + .set_wol = atl1c_set_wol, + .get_msglevel = atl1c_get_msglevel, + .set_msglevel = atl1c_set_msglevel, + .nway_reset = atl1c_nway_reset, + .get_link = ethtool_op_get_link, + .get_eeprom_len = atl1c_get_eeprom_len, + .get_eeprom = atl1c_get_eeprom, + .get_tx_csum = atl1c_get_tx_csum, + .get_sg = ethtool_op_get_sg, + .set_sg = ethtool_op_set_sg, +}; + +void atl1c_set_ethtool_ops(struct net_device *netdev) +{ + SET_ETHTOOL_OPS(netdev, &atl1c_ethtool_ops); +} diff --git a/drivers/net/atl1c/atl1c_hw.c b/drivers/net/atl1c/atl1c_hw.c new file mode 100644 index 00000000000..3e69b940b8f --- /dev/null +++ b/drivers/net/atl1c/atl1c_hw.c @@ -0,0 +1,527 @@ +/* + * Copyright(c) 2007 Atheros Corporation. All rights reserved. + * + * Derived from Intel e1000 driver + * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include +#include +#include +#include + +#include "atl1c.h" + +/* + * check_eeprom_exist + * return 1 if eeprom exist + */ +int atl1c_check_eeprom_exist(struct atl1c_hw *hw) +{ + u32 data; + + AT_READ_REG(hw, REG_TWSI_DEBUG, &data); + if (data & TWSI_DEBUG_DEV_EXIST) + return 1; + + return 0; +} + +void atl1c_hw_set_mac_addr(struct atl1c_hw *hw) +{ + u32 value; + /* + * 00-0B-6A-F6-00-DC + * 0: 6AF600DC 1: 000B + * low dword + */ + value = (((u32)hw->mac_addr[2]) << 24) | + (((u32)hw->mac_addr[3]) << 16) | + (((u32)hw->mac_addr[4]) << 8) | + (((u32)hw->mac_addr[5])) ; + AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 0, value); + /* hight dword */ + value = (((u32)hw->mac_addr[0]) << 8) | + (((u32)hw->mac_addr[1])) ; + AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 1, value); +} + +/* + * atl1c_get_permanent_address + * return 0 if get valid mac address, + */ +static int atl1c_get_permanent_address(struct atl1c_hw *hw) +{ + u32 addr[2]; + u32 i; + u32 otp_ctrl_data; + u32 twsi_ctrl_data; + u8 eth_addr[ETH_ALEN]; + + /* init */ + addr[0] = addr[1] = 0; + AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data); + if (atl1c_check_eeprom_exist(hw)) { + /* Enable OTP CLK */ + if (!(otp_ctrl_data & OTP_CTRL_CLK_EN)) { + otp_ctrl_data |= OTP_CTRL_CLK_EN; + AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data); + AT_WRITE_FLUSH(hw); + msleep(1); + } + + AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data); + twsi_ctrl_data |= TWSI_CTRL_SW_LDSTART; + AT_WRITE_REG(hw, REG_TWSI_CTRL, twsi_ctrl_data); + for (i = 0; i < AT_TWSI_EEPROM_TIMEOUT; i++) { + msleep(10); + AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data); + if ((twsi_ctrl_data & TWSI_CTRL_SW_LDSTART) == 0) + break; + } + if (i >= AT_TWSI_EEPROM_TIMEOUT) + return -1; + } + /* Disable OTP_CLK */ + if (otp_ctrl_data & OTP_CTRL_CLK_EN) { + otp_ctrl_data &= ~OTP_CTRL_CLK_EN; + AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data); + AT_WRITE_FLUSH(hw); + msleep(1); + } + + /* maybe MAC-address is from BIOS */ + AT_READ_REG(hw, REG_MAC_STA_ADDR, &addr[0]); + AT_READ_REG(hw, REG_MAC_STA_ADDR + 4, &addr[1]); + *(u32 *) ð_addr[2] = swab32(addr[0]); + *(u16 *) ð_addr[0] = swab16(*(u16 *)&addr[1]); + + if (is_valid_ether_addr(eth_addr)) { + memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN); + return 0; + } + + return -1; +} + +bool atl1c_read_eeprom(struct atl1c_hw *hw, u32 offset, u32 *p_value) +{ + int i; + int ret = false; + u32 otp_ctrl_data; + u32 control; + u32 data; + + if (offset & 3) + return ret; /* address do not align */ + + AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data); + if (!(otp_ctrl_data & OTP_CTRL_CLK_EN)) + AT_WRITE_REG(hw, REG_OTP_CTRL, + (otp_ctrl_data | OTP_CTRL_CLK_EN)); + + AT_WRITE_REG(hw, REG_EEPROM_DATA_LO, 0); + control = (offset & EEPROM_CTRL_ADDR_MASK) << EEPROM_CTRL_ADDR_SHIFT; + AT_WRITE_REG(hw, REG_EEPROM_CTRL, control); + + for (i = 0; i < 10; i++) { + udelay(100); + AT_READ_REG(hw, REG_EEPROM_CTRL, &control); + if (control & EEPROM_CTRL_RW) + break; + } + if (control & EEPROM_CTRL_RW) { + AT_READ_REG(hw, REG_EEPROM_CTRL, &data); + AT_READ_REG(hw, REG_EEPROM_DATA_LO, p_value); + data = data & 0xFFFF; + *p_value = swab32((data << 16) | (*p_value >> 16)); + ret = true; + } + if (!(otp_ctrl_data & OTP_CTRL_CLK_EN)) + AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data); + + return ret; +} +/* + * Reads the adapter's MAC address from the EEPROM + * + * hw - Struct containing variables accessed by shared code + */ +int atl1c_read_mac_addr(struct atl1c_hw *hw) +{ + int err = 0; + + err = atl1c_get_permanent_address(hw); + if (err) + random_ether_addr(hw->perm_mac_addr); + + memcpy(hw->mac_addr, hw->perm_mac_addr, sizeof(hw->perm_mac_addr)); + return 0; +} + +/* + * atl1c_hash_mc_addr + * purpose + * set hash value for a multicast address + * hash calcu processing : + * 1. calcu 32bit CRC for multicast address + * 2. reverse crc with MSB to LSB + */ +u32 atl1c_hash_mc_addr(struct atl1c_hw *hw, u8 *mc_addr) +{ + u32 crc32; + u32 value = 0; + int i; + + crc32 = ether_crc_le(6, mc_addr); + for (i = 0; i < 32; i++) + value |= (((crc32 >> i) & 1) << (31 - i)); + + return value; +} + +/* + * Sets the bit in the multicast table corresponding to the hash value. + * hw - Struct containing variables accessed by shared code + * hash_value - Multicast address hash value + */ +void atl1c_hash_set(struct atl1c_hw *hw, u32 hash_value) +{ + u32 hash_bit, hash_reg; + u32 mta; + + /* + * The HASH Table is a register array of 2 32-bit registers. + * It is treated like an array of 64 bits. We want to set + * bit BitArray[hash_value]. So we figure out what register + * the bit is in, read it, OR in the new bit, then write + * back the new value. The register is determined by the + * upper bit of the hash value and the bit within that + * register are determined by the lower 5 bits of the value. + */ + hash_reg = (hash_value >> 31) & 0x1; + hash_bit = (hash_value >> 26) & 0x1F; + + mta = AT_READ_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg); + + mta |= (1 << hash_bit); + + AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg, mta); +} + +/* + * Reads the value from a PHY register + * hw - Struct containing variables accessed by shared code + * reg_addr - address of the PHY register to read + */ +int atl1c_read_phy_reg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data) +{ + u32 val; + int i; + + val = ((u32)(reg_addr & MDIO_REG_ADDR_MASK)) << MDIO_REG_ADDR_SHIFT | + MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW | + MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT; + + AT_WRITE_REG(hw, REG_MDIO_CTRL, val); + + for (i = 0; i < MDIO_WAIT_TIMES; i++) { + udelay(2); + AT_READ_REG(hw, REG_MDIO_CTRL, &val); + if (!(val & (MDIO_START | MDIO_BUSY))) + break; + } + if (!(val & (MDIO_START | MDIO_BUSY))) { + *phy_data = (u16)val; + return 0; + } + + return -1; +} + +/* + * Writes a value to a PHY register + * hw - Struct containing variables accessed by shared code + * reg_addr - address of the PHY register to write + * data - data to write to the PHY + */ +int atl1c_write_phy_reg(struct atl1c_hw *hw, u32 reg_addr, u16 phy_data) +{ + int i; + u32 val; + + val = ((u32)(phy_data & MDIO_DATA_MASK)) << MDIO_DATA_SHIFT | + (reg_addr & MDIO_REG_ADDR_MASK) << MDIO_REG_ADDR_SHIFT | + MDIO_SUP_PREAMBLE | MDIO_START | + MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT; + + AT_WRITE_REG(hw, REG_MDIO_CTRL, val); + + for (i = 0; i < MDIO_WAIT_TIMES; i++) { + udelay(2); + AT_READ_REG(hw, REG_MDIO_CTRL, &val); + if (!(val & (MDIO_START | MDIO_BUSY))) + break; + } + + if (!(val & (MDIO_START | MDIO_BUSY))) + return 0; + + return -1; +} + +/* + * Configures PHY autoneg and flow control advertisement settings + * + * hw - Struct containing variables accessed by shared code + */ +static int atl1c_phy_setup_adv(struct atl1c_hw *hw) +{ + u16 mii_adv_data = ADVERTISE_DEFAULT_CAP & ~ADVERTISE_SPEED_MASK; + u16 mii_giga_ctrl_data = GIGA_CR_1000T_DEFAULT_CAP & + ~GIGA_CR_1000T_SPEED_MASK; + + if (hw->autoneg_advertised & ADVERTISED_10baseT_Half) + mii_adv_data |= ADVERTISE_10HALF; + if (hw->autoneg_advertised & ADVERTISED_10baseT_Full) + mii_adv_data |= ADVERTISE_10FULL; + if (hw->autoneg_advertised & ADVERTISED_100baseT_Half) + mii_adv_data |= ADVERTISE_100HALF; + if (hw->autoneg_advertised & ADVERTISED_100baseT_Full) + mii_adv_data |= ADVERTISE_100FULL; + + if (hw->autoneg_advertised & ADVERTISED_Autoneg) + mii_adv_data |= ADVERTISE_10HALF | ADVERTISE_10FULL | + ADVERTISE_100HALF | ADVERTISE_100FULL; + + if (hw->ctrl_flags & ATL1C_LINK_CAP_1000M) { + if (hw->autoneg_advertised & ADVERTISED_1000baseT_Half) + mii_giga_ctrl_data |= ADVERTISE_1000HALF; + if (hw->autoneg_advertised & ADVERTISED_1000baseT_Full) + mii_giga_ctrl_data |= ADVERTISE_1000FULL; + if (hw->autoneg_advertised & ADVERTISED_Autoneg) + mii_giga_ctrl_data |= ADVERTISE_1000HALF | + ADVERTISE_1000FULL; + } + + if (atl1c_write_phy_reg(hw, MII_ADVERTISE, mii_adv_data) != 0 || + atl1c_write_phy_reg(hw, MII_GIGA_CR, mii_giga_ctrl_data) != 0) + return -1; + return 0; +} + +void atl1c_phy_disable(struct atl1c_hw *hw) +{ + AT_WRITE_REGW(hw, REG_GPHY_CTRL, + GPHY_CTRL_PW_WOL_DIS | GPHY_CTRL_EXT_RESET); +} + +static void atl1c_phy_magic_data(struct atl1c_hw *hw) +{ + u16 data; + + data = ANA_LOOP_SEL_10BT | ANA_EN_MASK_TB | ANA_EN_10BT_IDLE | + ((1 & ANA_INTERVAL_SEL_TIMER_MASK) << + ANA_INTERVAL_SEL_TIMER_SHIFT); + + atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_18); + atl1c_write_phy_reg(hw, MII_DBG_DATA, data); + + data = (2 & ANA_SERDES_CDR_BW_MASK) | ANA_MS_PAD_DBG | + ANA_SERDES_EN_DEEM | ANA_SERDES_SEL_HSP | ANA_SERDES_EN_PLL | + ANA_SERDES_EN_LCKDT; + + atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_5); + atl1c_write_phy_reg(hw, MII_DBG_DATA, data); + + data = (44 & ANA_LONG_CABLE_TH_100_MASK) | + ((33 & ANA_SHORT_CABLE_TH_100_MASK) << + ANA_SHORT_CABLE_TH_100_SHIFT) | ANA_BP_BAD_LINK_ACCUM | + ANA_BP_SMALL_BW; + + atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_54); + atl1c_write_phy_reg(hw, MII_DBG_DATA, data); + + data = (11 & ANA_IECHO_ADJ_MASK) | ((11 & ANA_IECHO_ADJ_MASK) << + ANA_IECHO_ADJ_2_SHIFT) | ((8 & ANA_IECHO_ADJ_MASK) << + ANA_IECHO_ADJ_1_SHIFT) | ((8 & ANA_IECHO_ADJ_MASK) << + ANA_IECHO_ADJ_0_SHIFT); + + atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_4); + atl1c_write_phy_reg(hw, MII_DBG_DATA, data); + + data = ANA_RESTART_CAL | ((7 & ANA_MANUL_SWICH_ON_MASK) << + ANA_MANUL_SWICH_ON_SHIFT) | ANA_MAN_ENABLE | + ANA_SEL_HSP | ANA_EN_HB | ANA_OEN_125M; + + atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_0); + atl1c_write_phy_reg(hw, MII_DBG_DATA, data); + + if (hw->ctrl_flags & ATL1C_HIB_DISABLE) { + atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_41); + if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &data) != 0) + return; + data &= ~ANA_TOP_PS_EN; + atl1c_write_phy_reg(hw, MII_DBG_DATA, data); + + atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_11); + if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &data) != 0) + return; + data &= ~ANA_PS_HIB_EN; + atl1c_write_phy_reg(hw, MII_DBG_DATA, data); + } +} + +int atl1c_phy_reset(struct atl1c_hw *hw) +{ + struct atl1c_adapter *adapter = hw->adapter; + struct pci_dev *pdev = adapter->pdev; + u32 phy_ctrl_data = GPHY_CTRL_DEFAULT; + u32 mii_ier_data = IER_LINK_UP | IER_LINK_DOWN; + int err; + + if (hw->ctrl_flags & ATL1C_HIB_DISABLE) + phy_ctrl_data &= ~GPHY_CTRL_HIB_EN; + + AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl_data); + AT_WRITE_FLUSH(hw); + msleep(40); + phy_ctrl_data |= GPHY_CTRL_EXT_RESET; + AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl_data); + AT_WRITE_FLUSH(hw); + msleep(10); + + /*Enable PHY LinkChange Interrupt */ + err = atl1c_write_phy_reg(hw, MII_IER, mii_ier_data); + if (err) { + if (netif_msg_hw(adapter)) + dev_err(&pdev->dev, + "Error enable PHY linkChange Interrupt\n"); + return err; + } + if (!(hw->ctrl_flags & ATL1C_FPGA_VERSION)) + atl1c_phy_magic_data(hw); + return 0; +} + +int atl1c_phy_init(struct atl1c_hw *hw) +{ + struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter; + struct pci_dev *pdev = adapter->pdev; + int ret_val; + u16 mii_bmcr_data = BMCR_RESET; + u16 phy_id1, phy_id2; + + if ((atl1c_read_phy_reg(hw, MII_PHYSID1, &phy_id1) != 0) || + (atl1c_read_phy_reg(hw, MII_PHYSID2, &phy_id2) != 0)) { + if (netif_msg_link(adapter)) + dev_err(&pdev->dev, "Error get phy ID\n"); + return -1; + } + switch (hw->media_type) { + case MEDIA_TYPE_AUTO_SENSOR: + ret_val = atl1c_phy_setup_adv(hw); + if (ret_val) { + if (netif_msg_link(adapter)) + dev_err(&pdev->dev, + "Error Setting up Auto-Negotiation\n"); + return ret_val; + } + mii_bmcr_data |= BMCR_AUTO_NEG_EN | BMCR_RESTART_AUTO_NEG; + break; + case MEDIA_TYPE_100M_FULL: + mii_bmcr_data |= BMCR_SPEED_100 | BMCR_FULL_DUPLEX; + break; + case MEDIA_TYPE_100M_HALF: + mii_bmcr_data |= BMCR_SPEED_100; + break; + case MEDIA_TYPE_10M_FULL: + mii_bmcr_data |= BMCR_SPEED_10 | BMCR_FULL_DUPLEX; + break; + case MEDIA_TYPE_10M_HALF: + mii_bmcr_data |= BMCR_SPEED_10; + break; + default: + if (netif_msg_link(adapter)) + dev_err(&pdev->dev, "Wrong Media type %d\n", + hw->media_type); + return -1; + break; + } + + ret_val = atl1c_write_phy_reg(hw, MII_BMCR, mii_bmcr_data); + if (ret_val) + return ret_val; + hw->phy_configured = true; + + return 0; +} + +/* + * Detects the current speed and duplex settings of the hardware. + * + * hw - Struct containing variables accessed by shared code + * speed - Speed of the connection + * duplex - Duplex setting of the connection + */ +int atl1c_get_speed_and_duplex(struct atl1c_hw *hw, u16 *speed, u16 *duplex) +{ + int err; + u16 phy_data; + + /* Read PHY Specific Status Register (17) */ + err = atl1c_read_phy_reg(hw, MII_GIGA_PSSR, &phy_data); + if (err) + return err; + + if (!(phy_data & GIGA_PSSR_SPD_DPLX_RESOLVED)) + return -1; + + switch (phy_data & GIGA_PSSR_SPEED) { + case GIGA_PSSR_1000MBS: + *speed = SPEED_1000; + break; + case GIGA_PSSR_100MBS: + *speed = SPEED_100; + break; + case GIGA_PSSR_10MBS: + *speed = SPEED_10; + break; + default: + return -1; + break; + } + + if (phy_data & GIGA_PSSR_DPLX) + *duplex = FULL_DUPLEX; + else + *duplex = HALF_DUPLEX; + + return 0; +} + +int atl1c_restart_autoneg(struct atl1c_hw *hw) +{ + int err = 0; + u16 mii_bmcr_data = BMCR_RESET; + + err = atl1c_phy_setup_adv(hw); + if (err) + return err; + mii_bmcr_data |= BMCR_AUTO_NEG_EN | BMCR_RESTART_AUTO_NEG; + + return atl1c_write_phy_reg(hw, MII_BMCR, mii_bmcr_data); +} diff --git a/drivers/net/atl1c/atl1c_hw.h b/drivers/net/atl1c/atl1c_hw.h new file mode 100644 index 00000000000..c2c738df5c6 --- /dev/null +++ b/drivers/net/atl1c/atl1c_hw.h @@ -0,0 +1,859 @@ +/* + * Copyright(c) 2008 - 2009 Atheros Corporation. All rights reserved. + * + * Derived from Intel e1000 driver + * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _ATL1C_HW_H_ +#define _ATL1C_HW_H_ + +#include +#include + +struct atl1c_adapter; +struct atl1c_hw; + +/* function prototype */ +void atl1c_phy_disable(struct atl1c_hw *hw); +void atl1c_hw_set_mac_addr(struct atl1c_hw *hw); +int atl1c_phy_reset(struct atl1c_hw *hw); +int atl1c_read_mac_addr(struct atl1c_hw *hw); +int atl1c_get_speed_and_duplex(struct atl1c_hw *hw, u16 *speed, u16 *duplex); +u32 atl1c_hash_mc_addr(struct atl1c_hw *hw, u8 *mc_addr); +void atl1c_hash_set(struct atl1c_hw *hw, u32 hash_value); +int atl1c_read_phy_reg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data); +int atl1c_write_phy_reg(struct atl1c_hw *hw, u32 reg_addr, u16 phy_data); +bool atl1c_read_eeprom(struct atl1c_hw *hw, u32 offset, u32 *p_value); +int atl1c_phy_init(struct atl1c_hw *hw); +int atl1c_check_eeprom_exist(struct atl1c_hw *hw); +int atl1c_restart_autoneg(struct atl1c_hw *hw); + +/* register definition */ +#define REG_DEVICE_CAP 0x5C +#define DEVICE_CAP_MAX_PAYLOAD_MASK 0x7 +#define DEVICE_CAP_MAX_PAYLOAD_SHIFT 0 + +#define REG_DEVICE_CTRL 0x60 +#define DEVICE_CTRL_MAX_PAYLOAD_MASK 0x7 +#define DEVICE_CTRL_MAX_PAYLOAD_SHIFT 5 +#define DEVICE_CTRL_MAX_RREQ_SZ_MASK 0x7 +#define DEVICE_CTRL_MAX_RREQ_SZ_SHIFT 12 + +#define REG_LINK_CTRL 0x68 +#define LINK_CTRL_L0S_EN 0x01 +#define LINK_CTRL_L1_EN 0x02 + +#define REG_VPD_CAP 0x6C +#define VPD_CAP_ID_MASK 0xff +#define VPD_CAP_ID_SHIFT 0 +#define VPD_CAP_NEXT_PTR_MASK 0xFF +#define VPD_CAP_NEXT_PTR_SHIFT 8 +#define VPD_CAP_VPD_ADDR_MASK 0x7FFF +#define VPD_CAP_VPD_ADDR_SHIFT 16 +#define VPD_CAP_VPD_FLAG 0x80000000 + +#define REG_VPD_DATA 0x70 + +#define REG_PCIE_UC_SEVERITY 0x10C +#define PCIE_UC_SERVRITY_TRN 0x00000001 +#define PCIE_UC_SERVRITY_DLP 0x00000010 +#define PCIE_UC_SERVRITY_PSN_TLP 0x00001000 +#define PCIE_UC_SERVRITY_FCP 0x00002000 +#define PCIE_UC_SERVRITY_CPL_TO 0x00004000 +#define PCIE_UC_SERVRITY_CA 0x00008000 +#define PCIE_UC_SERVRITY_UC 0x00010000 +#define PCIE_UC_SERVRITY_ROV 0x00020000 +#define PCIE_UC_SERVRITY_MLFP 0x00040000 +#define PCIE_UC_SERVRITY_ECRC 0x00080000 +#define PCIE_UC_SERVRITY_UR 0x00100000 + +#define REG_DEV_SERIALNUM_CTRL 0x200 +#define REG_DEV_MAC_SEL_MASK 0x0 /* 0:EUI; 1:MAC */ +#define REG_DEV_MAC_SEL_SHIFT 0 +#define REG_DEV_SERIAL_NUM_EN_MASK 0x1 +#define REG_DEV_SERIAL_NUM_EN_SHIFT 1 + +#define REG_TWSI_CTRL 0x218 +#define TWSI_CTRL_LD_OFFSET_MASK 0xFF +#define TWSI_CTRL_LD_OFFSET_SHIFT 0 +#define TWSI_CTRL_LD_SLV_ADDR_MASK 0x7 +#define TWSI_CTRL_LD_SLV_ADDR_SHIFT 8 +#define TWSI_CTRL_SW_LDSTART 0x800 +#define TWSI_CTRL_HW_LDSTART 0x1000 +#define TWSI_CTRL_SMB_SLV_ADDR_MASK 0x7F +#define TWSI_CTRL_SMB_SLV_ADDR_SHIFT 15 +#define TWSI_CTRL_LD_EXIST 0x400000 +#define TWSI_CTRL_READ_FREQ_SEL_MASK 0x3 +#define TWSI_CTRL_READ_FREQ_SEL_SHIFT 23 +#define TWSI_CTRL_FREQ_SEL_100K 0 +#define TWSI_CTRL_FREQ_SEL_200K 1 +#define TWSI_CTRL_FREQ_SEL_300K 2 +#define TWSI_CTRL_FREQ_SEL_400K 3 +#define TWSI_CTRL_SMB_SLV_ADDR +#define TWSI_CTRL_WRITE_FREQ_SEL_MASK 0x3 +#define TWSI_CTRL_WRITE_FREQ_SEL_SHIFT 24 + + +#define REG_PCIE_DEV_MISC_CTRL 0x21C +#define PCIE_DEV_MISC_EXT_PIPE 0x2 +#define PCIE_DEV_MISC_RETRY_BUFDIS 0x1 +#define PCIE_DEV_MISC_SPIROM_EXIST 0x4 +#define PCIE_DEV_MISC_SERDES_ENDIAN 0x8 +#define PCIE_DEV_MISC_SERDES_SEL_DIN 0x10 + +#define REG_PCIE_PHYMISC 0x1000 +#define PCIE_PHYMISC_FORCE_RCV_DET 0x4 + +#define REG_TWSI_DEBUG 0x1108 +#define TWSI_DEBUG_DEV_EXIST 0x20000000 + +#define REG_EEPROM_CTRL 0x12C0 +#define EEPROM_CTRL_DATA_HI_MASK 0xFFFF +#define EEPROM_CTRL_DATA_HI_SHIFT 0 +#define EEPROM_CTRL_ADDR_MASK 0x3FF +#define EEPROM_CTRL_ADDR_SHIFT 16 +#define EEPROM_CTRL_ACK 0x40000000 +#define EEPROM_CTRL_RW 0x80000000 + +#define REG_EEPROM_DATA_LO 0x12C4 + +#define REG_OTP_CTRL 0x12F0 +#define OTP_CTRL_CLK_EN 0x0002 + +#define REG_PM_CTRL 0x12F8 +#define PM_CTRL_SDES_EN 0x00000001 +#define PM_CTRL_RBER_EN 0x00000002 +#define PM_CTRL_CLK_REQ_EN 0x00000004 +#define PM_CTRL_ASPM_L1_EN 0x00000008 +#define PM_CTRL_SERDES_L1_EN 0x00000010 +#define PM_CTRL_SERDES_PLL_L1_EN 0x00000020 +#define PM_CTRL_SERDES_PD_EX_L1 0x00000040 +#define PM_CTRL_SERDES_BUDS_RX_L1_EN 0x00000080 +#define PM_CTRL_L0S_ENTRY_TIMER_MASK 0xF +#define PM_CTRL_L0S_ENTRY_TIMER_SHIFT 8 +#define PM_CTRL_ASPM_L0S_EN 0x00001000 +#define PM_CTRL_CLK_SWH_L1 0x00002000 +#define PM_CTRL_CLK_PWM_VER1_1 0x00004000 +#define PM_CTRL_PCIE_RECV 0x00008000 +#define PM_CTRL_L1_ENTRY_TIMER_MASK 0xF +#define PM_CTRL_L1_ENTRY_TIMER_SHIFT 16 +#define PM_CTRL_PM_REQ_TIMER_MASK 0xF +#define PM_CTRL_PM_REQ_TIMER_SHIFT 20 +#define PM_CTRL_LCKDET_TIMER_MASK 0x3F +#define PM_CTRL_LCKDET_TIMER_SHIFT 24 +#define PM_CTRL_MAC_ASPM_CHK 0x40000000 +#define PM_CTRL_HOTRST 0x80000000 + +/* Selene Master Control Register */ +#define REG_MASTER_CTRL 0x1400 +#define MASTER_CTRL_SOFT_RST 0x1 +#define MASTER_CTRL_TEST_MODE_MASK 0x3 +#define MASTER_CTRL_TEST_MODE_SHIFT 2 +#define MASTER_CTRL_BERT_START 0x10 +#define MASTER_CTRL_MTIMER_EN 0x100 +#define MASTER_CTRL_MANUAL_INT 0x200 +#define MASTER_CTRL_TX_ITIMER_EN 0x400 +#define MASTER_CTRL_RX_ITIMER_EN 0x800 +#define MASTER_CTRL_CLK_SEL_DIS 0x1000 +#define MASTER_CTRL_CLK_SWH_MODE 0x2000 +#define MASTER_CTRL_INT_RDCLR 0x4000 +#define MASTER_CTRL_REV_NUM_SHIFT 16 +#define MASTER_CTRL_REV_NUM_MASK 0xff +#define MASTER_CTRL_DEV_ID_SHIFT 24 +#define MASTER_CTRL_DEV_ID_MASK 0x7f +#define MASTER_CTRL_OTP_SEL 0x80000000 + +/* Timer Initial Value Register */ +#define REG_MANUAL_TIMER_INIT 0x1404 + +/* IRQ ModeratorTimer Initial Value Register */ +#define REG_IRQ_MODRT_TIMER_INIT 0x1408 +#define IRQ_MODRT_TIMER_MASK 0xffff +#define IRQ_MODRT_TX_TIMER_SHIFT 0 +#define IRQ_MODRT_RX_TIMER_SHIFT 16 + +#define REG_GPHY_CTRL 0x140C +#define GPHY_CTRL_EXT_RESET 0x1 +#define GPHY_CTRL_RTL_MODE 0x2 +#define GPHY_CTRL_LED_MODE 0x4 +#define GPHY_CTRL_ANEG_NOW 0x8 +#define GPHY_CTRL_REV_ANEG 0x10 +#define GPHY_CTRL_GATE_25M_EN 0x20 +#define GPHY_CTRL_LPW_EXIT 0x40 +#define GPHY_CTRL_PHY_IDDQ 0x80 +#define GPHY_CTRL_PHY_IDDQ_DIS 0x100 +#define GPHY_CTRL_GIGA_DIS 0x200 +#define GPHY_CTRL_HIB_EN 0x400 +#define GPHY_CTRL_HIB_PULSE 0x800 +#define GPHY_CTRL_SEL_ANA_RST 0x1000 +#define GPHY_CTRL_PHY_PLL_ON 0x2000 +#define GPHY_CTRL_PWDOWN_HW 0x4000 +#define GPHY_CTRL_PHY_PLL_BYPASS 0x8000 + +#define GPHY_CTRL_DEFAULT ( \ + GPHY_CTRL_SEL_ANA_RST |\ + GPHY_CTRL_HIB_PULSE |\ + GPHY_CTRL_HIB_EN) + +#define GPHY_CTRL_PW_WOL_DIS ( \ + GPHY_CTRL_SEL_ANA_RST |\ + GPHY_CTRL_HIB_PULSE |\ + GPHY_CTRL_HIB_EN |\ + GPHY_CTRL_PWDOWN_HW |\ + GPHY_CTRL_PHY_IDDQ) + +/* Block IDLE Status Register */ +#define REG_IDLE_STATUS 0x1410 +#define IDLE_STATUS_MASK 0x00FF +#define IDLE_STATUS_RXMAC_NO_IDLE 0x1 +#define IDLE_STATUS_TXMAC_NO_IDLE 0x2 +#define IDLE_STATUS_RXQ_NO_IDLE 0x4 +#define IDLE_STATUS_TXQ_NO_IDLE 0x8 +#define IDLE_STATUS_DMAR_NO_IDLE 0x10 +#define IDLE_STATUS_DMAW_NO_IDLE 0x20 +#define IDLE_STATUS_SMB_NO_IDLE 0x40 +#define IDLE_STATUS_CMB_NO_IDLE 0x80 + +/* MDIO Control Register */ +#define REG_MDIO_CTRL 0x1414 +#define MDIO_DATA_MASK 0xffff /* On MDIO write, the 16-bit + * control data to write to PHY + * MII management register */ +#define MDIO_DATA_SHIFT 0 /* On MDIO read, the 16-bit + * status data that was read + * from the PHY MII management register */ +#define MDIO_REG_ADDR_MASK 0x1f /* MDIO register address */ +#define MDIO_REG_ADDR_SHIFT 16 +#define MDIO_RW 0x200000 /* 1: read, 0: write */ +#define MDIO_SUP_PREAMBLE 0x400000 /* Suppress preamble */ +#define MDIO_START 0x800000 /* Write 1 to initiate the MDIO + * master. And this bit is self + * cleared after one cycle */ +#define MDIO_CLK_SEL_SHIFT 24 +#define MDIO_CLK_25_4 0 +#define MDIO_CLK_25_6 2 +#define MDIO_CLK_25_8 3 +#define MDIO_CLK_25_10 4 +#define MDIO_CLK_25_14 5 +#define MDIO_CLK_25_20 6 +#define MDIO_CLK_25_28 7 +#define MDIO_BUSY 0x8000000 +#define MDIO_AP_EN 0x10000000 +#define MDIO_WAIT_TIMES 10 + +/* MII PHY Status Register */ +#define REG_PHY_STATUS 0x1418 +#define PHY_GENERAL_STATUS_MASK 0xFFFF +#define PHY_STATUS_RECV_ENABLE 0x0001 +#define PHY_OE_PWSP_STATUS_MASK 0x07FF +#define PHY_OE_PWSP_STATUS_SHIFT 16 +#define PHY_STATUS_LPW_STATE 0x80000000 +/* BIST Control and Status Register0 (for the Packet Memory) */ +#define REG_BIST0_CTRL 0x141c +#define BIST0_NOW 0x1 +#define BIST0_SRAM_FAIL 0x2 /* 1: The SRAM failure is + * un-repairable because + * it has address decoder + * failure or more than 1 cell + * stuck-to-x failure */ +#define BIST0_FUSE_FLAG 0x4 + +/* BIST Control and Status Register1(for the retry buffer of PCI Express) */ +#define REG_BIST1_CTRL 0x1420 +#define BIST1_NOW 0x1 +#define BIST1_SRAM_FAIL 0x2 +#define BIST1_FUSE_FLAG 0x4 + +/* SerDes Lock Detect Control and Status Register */ +#define REG_SERDES_LOCK 0x1424 +#define SERDES_LOCK_DETECT 0x1 /* SerDes lock detected. This signal + * comes from Analog SerDes */ +#define SERDES_LOCK_DETECT_EN 0x2 /* 1: Enable SerDes Lock detect function */ + +/* MAC Control Register */ +#define REG_MAC_CTRL 0x1480 +#define MAC_CTRL_TX_EN 0x1 +#define MAC_CTRL_RX_EN 0x2 +#define MAC_CTRL_TX_FLOW 0x4 +#define MAC_CTRL_RX_FLOW 0x8 +#define MAC_CTRL_LOOPBACK 0x10 +#define MAC_CTRL_DUPLX 0x20 +#define MAC_CTRL_ADD_CRC 0x40 +#define MAC_CTRL_PAD 0x80 +#define MAC_CTRL_LENCHK 0x100 +#define MAC_CTRL_HUGE_EN 0x200 +#define MAC_CTRL_PRMLEN_SHIFT 10 +#define MAC_CTRL_PRMLEN_MASK 0xf +#define MAC_CTRL_RMV_VLAN 0x4000 +#define MAC_CTRL_PROMIS_EN 0x8000 +#define MAC_CTRL_TX_PAUSE 0x10000 +#define MAC_CTRL_SCNT 0x20000 +#define MAC_CTRL_SRST_TX 0x40000 +#define MAC_CTRL_TX_SIMURST 0x80000 +#define MAC_CTRL_SPEED_SHIFT 20 +#define MAC_CTRL_SPEED_MASK 0x3 +#define MAC_CTRL_DBG_TX_BKPRESURE 0x400000 +#define MAC_CTRL_TX_HUGE 0x800000 +#define MAC_CTRL_RX_CHKSUM_EN 0x1000000 +#define MAC_CTRL_MC_ALL_EN 0x2000000 +#define MAC_CTRL_BC_EN 0x4000000 +#define MAC_CTRL_DBG 0x8000000 +#define MAC_CTRL_SINGLE_PAUSE_EN 0x10000000 + +/* MAC IPG/IFG Control Register */ +#define REG_MAC_IPG_IFG 0x1484 +#define MAC_IPG_IFG_IPGT_SHIFT 0 /* Desired back to back + * inter-packet gap. The + * default is 96-bit time */ +#define MAC_IPG_IFG_IPGT_MASK 0x7f +#define MAC_IPG_IFG_MIFG_SHIFT 8 /* Minimum number of IFG to + * enforce in between RX frames */ +#define MAC_IPG_IFG_MIFG_MASK 0xff /* Frame gap below such IFP is dropped */ +#define MAC_IPG_IFG_IPGR1_SHIFT 16 /* 64bit Carrier-Sense window */ +#define MAC_IPG_IFG_IPGR1_MASK 0x7f +#define MAC_IPG_IFG_IPGR2_SHIFT 24 /* 96-bit IPG window */ +#define MAC_IPG_IFG_IPGR2_MASK 0x7f + +/* MAC STATION ADDRESS */ +#define REG_MAC_STA_ADDR 0x1488 + +/* Hash table for multicast address */ +#define REG_RX_HASH_TABLE 0x1490 + +/* MAC Half-Duplex Control Register */ +#define REG_MAC_HALF_DUPLX_CTRL 0x1498 +#define MAC_HALF_DUPLX_CTRL_LCOL_SHIFT 0 /* Collision Window */ +#define MAC_HALF_DUPLX_CTRL_LCOL_MASK 0x3ff +#define MAC_HALF_DUPLX_CTRL_RETRY_SHIFT 12 +#define MAC_HALF_DUPLX_CTRL_RETRY_MASK 0xf +#define MAC_HALF_DUPLX_CTRL_EXC_DEF_EN 0x10000 +#define MAC_HALF_DUPLX_CTRL_NO_BACK_C 0x20000 +#define MAC_HALF_DUPLX_CTRL_NO_BACK_P 0x40000 /* No back-off on backpressure, + * immediately start the + * transmission after back pressure */ +#define MAC_HALF_DUPLX_CTRL_ABEBE 0x80000 /* 1: Alternative Binary Exponential Back-off Enabled */ +#define MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT 20 /* Maximum binary exponential number */ +#define MAC_HALF_DUPLX_CTRL_ABEBT_MASK 0xf +#define MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT 24 /* IPG to start JAM for collision based flow control in half-duplex */ +#define MAC_HALF_DUPLX_CTRL_JAMIPG_MASK 0xf /* mode. In unit of 8-bit time */ + +/* Maximum Frame Length Control Register */ +#define REG_MTU 0x149c + +/* Wake-On-Lan control register */ +#define REG_WOL_CTRL 0x14a0 +#define WOL_PATTERN_EN 0x00000001 +#define WOL_PATTERN_PME_EN 0x00000002 +#define WOL_MAGIC_EN 0x00000004 +#define WOL_MAGIC_PME_EN 0x00000008 +#define WOL_LINK_CHG_EN 0x00000010 +#define WOL_LINK_CHG_PME_EN 0x00000020 +#define WOL_PATTERN_ST 0x00000100 +#define WOL_MAGIC_ST 0x00000200 +#define WOL_LINKCHG_ST 0x00000400 +#define WOL_CLK_SWITCH_EN 0x00008000 +#define WOL_PT0_EN 0x00010000 +#define WOL_PT1_EN 0x00020000 +#define WOL_PT2_EN 0x00040000 +#define WOL_PT3_EN 0x00080000 +#define WOL_PT4_EN 0x00100000 +#define WOL_PT5_EN 0x00200000 +#define WOL_PT6_EN 0x00400000 + +/* WOL Length ( 2 DWORD ) */ +#define REG_WOL_PATTERN_LEN 0x14a4 +#define WOL_PT_LEN_MASK 0x7f +#define WOL_PT0_LEN_SHIFT 0 +#define WOL_PT1_LEN_SHIFT 8 +#define WOL_PT2_LEN_SHIFT 16 +#define WOL_PT3_LEN_SHIFT 24 +#define WOL_PT4_LEN_SHIFT 0 +#define WOL_PT5_LEN_SHIFT 8 +#define WOL_PT6_LEN_SHIFT 16 + +/* Internal SRAM Partition Register */ +#define RFDX_HEAD_ADDR_MASK 0x03FF +#define RFDX_HARD_ADDR_SHIFT 0 +#define RFDX_TAIL_ADDR_MASK 0x03FF +#define RFDX_TAIL_ADDR_SHIFT 16 + +#define REG_SRAM_RFD0_INFO 0x1500 +#define REG_SRAM_RFD1_INFO 0x1504 +#define REG_SRAM_RFD2_INFO 0x1508 +#define REG_SRAM_RFD3_INFO 0x150C + +#define REG_RFD_NIC_LEN 0x1510 /* In 8-bytes */ +#define RFD_NIC_LEN_MASK 0x03FF + +#define REG_SRAM_TRD_ADDR 0x1518 +#define TPD_HEAD_ADDR_MASK 0x03FF +#define TPD_HEAD_ADDR_SHIFT 0 +#define TPD_TAIL_ADDR_MASK 0x03FF +#define TPD_TAIL_ADDR_SHIFT 16 + +#define REG_SRAM_TRD_LEN 0x151C /* In 8-bytes */ +#define TPD_NIC_LEN_MASK 0x03FF + +#define REG_SRAM_RXF_ADDR 0x1520 +#define REG_SRAM_RXF_LEN 0x1524 +#define REG_SRAM_TXF_ADDR 0x1528 +#define REG_SRAM_TXF_LEN 0x152C +#define REG_SRAM_TCPH_ADDR 0x1530 +#define REG_SRAM_PKTH_ADDR 0x1532 + +/* + * Load Ptr Register + * Software sets this bit after the initialization of the head and tail */ +#define REG_LOAD_PTR 0x1534 + +/* + * addresses of all descriptors, as well as the following descriptor + * control register, which triggers each function block to load the head + * pointer to prepare for the operation. This bit is then self-cleared + * after one cycle. + */ +#define REG_RX_BASE_ADDR_HI 0x1540 +#define REG_TX_BASE_ADDR_HI 0x1544 +#define REG_SMB_BASE_ADDR_HI 0x1548 +#define REG_SMB_BASE_ADDR_LO 0x154C +#define REG_RFD0_HEAD_ADDR_LO 0x1550 +#define REG_RFD1_HEAD_ADDR_LO 0x1554 +#define REG_RFD2_HEAD_ADDR_LO 0x1558 +#define REG_RFD3_HEAD_ADDR_LO 0x155C +#define REG_RFD_RING_SIZE 0x1560 +#define RFD_RING_SIZE_MASK 0x0FFF +#define REG_RX_BUF_SIZE 0x1564 +#define RX_BUF_SIZE_MASK 0xFFFF +#define REG_RRD0_HEAD_ADDR_LO 0x1568 +#define REG_RRD1_HEAD_ADDR_LO 0x156C +#define REG_RRD2_HEAD_ADDR_LO 0x1570 +#define REG_RRD3_HEAD_ADDR_LO 0x1574 +#define REG_RRD_RING_SIZE 0x1578 +#define RRD_RING_SIZE_MASK 0x0FFF +#define REG_HTPD_HEAD_ADDR_LO 0x157C +#define REG_NTPD_HEAD_ADDR_LO 0x1580 +#define REG_TPD_RING_SIZE 0x1584 +#define TPD_RING_SIZE_MASK 0xFFFF +#define REG_CMB_BASE_ADDR_LO 0x1588 + +/* RSS about */ +#define REG_RSS_KEY0 0x14B0 +#define REG_RSS_KEY1 0x14B4 +#define REG_RSS_KEY2 0x14B8 +#define REG_RSS_KEY3 0x14BC +#define REG_RSS_KEY4 0x14C0 +#define REG_RSS_KEY5 0x14C4 +#define REG_RSS_KEY6 0x14C8 +#define REG_RSS_KEY7 0x14CC +#define REG_RSS_KEY8 0x14D0 +#define REG_RSS_KEY9 0x14D4 +#define REG_IDT_TABLE0 0x14E0 +#define REG_IDT_TABLE1 0x14E4 +#define REG_IDT_TABLE2 0x14E8 +#define REG_IDT_TABLE3 0x14EC +#define REG_IDT_TABLE4 0x14F0 +#define REG_IDT_TABLE5 0x14F4 +#define REG_IDT_TABLE6 0x14F8 +#define REG_IDT_TABLE7 0x14FC +#define REG_IDT_TABLE REG_IDT_TABLE0 +#define REG_RSS_HASH_VALUE 0x15B0 +#define REG_RSS_HASH_FLAG 0x15B4 +#define REG_BASE_CPU_NUMBER 0x15B8 + +/* TXQ Control Register */ +#define REG_TXQ_CTRL 0x1590 +#define TXQ_NUM_TPD_BURST_MASK 0xF +#define TXQ_NUM_TPD_BURST_SHIFT 0 +#define TXQ_CTRL_IP_OPTION_EN 0x10 +#define TXQ_CTRL_EN 0x20 +#define TXQ_CTRL_ENH_MODE 0x40 +#define TXQ_CTRL_LS_8023_EN 0x80 +#define TXQ_TXF_BURST_NUM_SHIFT 16 +#define TXQ_TXF_BURST_NUM_MASK 0xFFFF + +/* Jumbo packet Threshold for task offload */ +#define REG_TX_TSO_OFFLOAD_THRESH 0x1594 /* In 8-bytes */ +#define TX_TSO_OFFLOAD_THRESH_MASK 0x07FF + +#define REG_TXF_WATER_MARK 0x1598 /* In 8-bytes */ +#define TXF_WATER_MARK_MASK 0x0FFF +#define TXF_LOW_WATER_MARK_SHIFT 0 +#define TXF_HIGH_WATER_MARK_SHIFT 16 +#define TXQ_CTRL_BURST_MODE_EN 0x80000000 + +#define REG_THRUPUT_MON_CTRL 0x159C +#define THRUPUT_MON_RATE_MASK 0x3 +#define THRUPUT_MON_RATE_SHIFT 0 +#define THRUPUT_MON_EN 0x80 + +/* RXQ Control Register */ +#define REG_RXQ_CTRL 0x15A0 +#define ASPM_THRUPUT_LIMIT_MASK 0x3 +#define ASPM_THRUPUT_LIMIT_SHIFT 0 +#define ASPM_THRUPUT_LIMIT_NO 0x00 +#define ASPM_THRUPUT_LIMIT_1M 0x01 +#define ASPM_THRUPUT_LIMIT_10M 0x02 +#define ASPM_THRUPUT_LIMIT_100M 0x04 +#define RXQ1_CTRL_EN 0x10 +#define RXQ2_CTRL_EN 0x20 +#define RXQ3_CTRL_EN 0x40 +#define IPV6_CHKSUM_CTRL_EN 0x80 +#define RSS_HASH_BITS_MASK 0x00FF +#define RSS_HASH_BITS_SHIFT 8 +#define RSS_HASH_IPV4 0x10000 +#define RSS_HASH_IPV4_TCP 0x20000 +#define RSS_HASH_IPV6 0x40000 +#define RSS_HASH_IPV6_TCP 0x80000 +#define RXQ_RFD_BURST_NUM_MASK 0x003F +#define RXQ_RFD_BURST_NUM_SHIFT 20 +#define RSS_MODE_MASK 0x0003 +#define RSS_MODE_SHIFT 26 +#define RSS_NIP_QUEUE_SEL_MASK 0x1 +#define RSS_NIP_QUEUE_SEL_SHIFT 28 +#define RRS_HASH_CTRL_EN 0x20000000 +#define RX_CUT_THRU_EN 0x40000000 +#define RXQ_CTRL_EN 0x80000000 + +#define REG_RFD_FREE_THRESH 0x15A4 +#define RFD_FREE_THRESH_MASK 0x003F +#define RFD_FREE_HI_THRESH_SHIFT 0 +#define RFD_FREE_LO_THRESH_SHIFT 6 + +/* RXF flow control register */ +#define REG_RXQ_RXF_PAUSE_THRESH 0x15A8 +#define RXQ_RXF_PAUSE_TH_HI_SHIFT 0 +#define RXQ_RXF_PAUSE_TH_HI_MASK 0x0FFF +#define RXQ_RXF_PAUSE_TH_LO_SHIFT 16 +#define RXQ_RXF_PAUSE_TH_LO_MASK 0x0FFF + +#define REG_RXD_DMA_CTRL 0x15AC +#define RXD_DMA_THRESH_MASK 0x0FFF /* In 8-bytes */ +#define RXD_DMA_THRESH_SHIFT 0 +#define RXD_DMA_DOWN_TIMER_MASK 0xFFFF +#define RXD_DMA_DOWN_TIMER_SHIFT 16 + +/* DMA Engine Control Register */ +#define REG_DMA_CTRL 0x15C0 +#define DMA_CTRL_DMAR_IN_ORDER 0x1 +#define DMA_CTRL_DMAR_ENH_ORDER 0x2 +#define DMA_CTRL_DMAR_OUT_ORDER 0x4 +#define DMA_CTRL_RCB_VALUE 0x8 +#define DMA_CTRL_DMAR_BURST_LEN_MASK 0x0007 +#define DMA_CTRL_DMAR_BURST_LEN_SHIFT 4 +#define DMA_CTRL_DMAW_BURST_LEN_MASK 0x0007 +#define DMA_CTRL_DMAW_BURST_LEN_SHIFT 7 +#define DMA_CTRL_DMAR_REQ_PRI 0x400 +#define DMA_CTRL_DMAR_DLY_CNT_MASK 0x001F +#define DMA_CTRL_DMAR_DLY_CNT_SHIFT 11 +#define DMA_CTRL_DMAW_DLY_CNT_MASK 0x000F +#define DMA_CTRL_DMAW_DLY_CNT_SHIFT 16 +#define DMA_CTRL_CMB_EN 0x100000 +#define DMA_CTRL_SMB_EN 0x200000 +#define DMA_CTRL_CMB_NOW 0x400000 +#define MAC_CTRL_SMB_DIS 0x1000000 +#define DMA_CTRL_SMB_NOW 0x80000000 + +/* CMB/SMB Control Register */ +#define REG_SMB_STAT_TIMER 0x15C4 /* 2us resolution */ +#define SMB_STAT_TIMER_MASK 0xFFFFFF +#define REG_CMB_TPD_THRESH 0x15C8 +#define CMB_TPD_THRESH_MASK 0xFFFF +#define REG_CMB_TX_TIMER 0x15CC /* 2us resolution */ +#define CMB_TX_TIMER_MASK 0xFFFF + +/* Mail box */ +#define MB_RFDX_PROD_IDX_MASK 0xFFFF +#define REG_MB_RFD0_PROD_IDX 0x15E0 +#define REG_MB_RFD1_PROD_IDX 0x15E4 +#define REG_MB_RFD2_PROD_IDX 0x15E8 +#define REG_MB_RFD3_PROD_IDX 0x15EC + +#define MB_PRIO_PROD_IDX_MASK 0xFFFF +#define REG_MB_PRIO_PROD_IDX 0x15F0 +#define MB_HTPD_PROD_IDX_SHIFT 0 +#define MB_NTPD_PROD_IDX_SHIFT 16 + +#define MB_PRIO_CONS_IDX_MASK 0xFFFF +#define REG_MB_PRIO_CONS_IDX 0x15F4 +#define MB_HTPD_CONS_IDX_SHIFT 0 +#define MB_NTPD_CONS_IDX_SHIFT 16 + +#define REG_MB_RFD01_CONS_IDX 0x15F8 +#define MB_RFD0_CONS_IDX_MASK 0x0000FFFF +#define MB_RFD1_CONS_IDX_MASK 0xFFFF0000 +#define REG_MB_RFD23_CONS_IDX 0x15FC +#define MB_RFD2_CONS_IDX_MASK 0x0000FFFF +#define MB_RFD3_CONS_IDX_MASK 0xFFFF0000 + +/* Interrupt Status Register */ +#define REG_ISR 0x1600 +#define ISR_SMB 0x00000001 +#define ISR_TIMER 0x00000002 +/* + * Software manual interrupt, for debug. Set when SW_MAN_INT_EN is set + * in Table 51 Selene Master Control Register (Offset 0x1400). + */ +#define ISR_MANUAL 0x00000004 +#define ISR_HW_RXF_OV 0x00000008 /* RXF overflow interrupt */ +#define ISR_RFD0_UR 0x00000010 /* RFD0 under run */ +#define ISR_RFD1_UR 0x00000020 +#define ISR_RFD2_UR 0x00000040 +#define ISR_RFD3_UR 0x00000080 +#define ISR_TXF_UR 0x00000100 +#define ISR_DMAR_TO_RST 0x00000200 +#define ISR_DMAW_TO_RST 0x00000400 +#define ISR_TX_CREDIT 0x00000800 +#define ISR_GPHY 0x00001000 +/* GPHY low power state interrupt */ +#define ISR_GPHY_LPW 0x00002000 +#define ISR_TXQ_TO_RST 0x00004000 +#define ISR_TX_PKT 0x00008000 +#define ISR_RX_PKT_0 0x00010000 +#define ISR_RX_PKT_1 0x00020000 +#define ISR_RX_PKT_2 0x00040000 +#define ISR_RX_PKT_3 0x00080000 +#define ISR_MAC_RX 0x00100000 +#define ISR_MAC_TX 0x00200000 +#define ISR_UR_DETECTED 0x00400000 +#define ISR_FERR_DETECTED 0x00800000 +#define ISR_NFERR_DETECTED 0x01000000 +#define ISR_CERR_DETECTED 0x02000000 +#define ISR_PHY_LINKDOWN 0x04000000 +#define ISR_DIS_INT 0x80000000 + +/* Interrupt Mask Register */ +#define REG_IMR 0x1604 + +#define IMR_NORMAL_MASK (\ + ISR_MANUAL |\ + ISR_HW_RXF_OV |\ + ISR_RFD0_UR |\ + ISR_TXF_UR |\ + ISR_DMAR_TO_RST |\ + ISR_TXQ_TO_RST |\ + ISR_DMAW_TO_RST |\ + ISR_GPHY |\ + ISR_TX_PKT |\ + ISR_RX_PKT_0 |\ + ISR_GPHY_LPW |\ + ISR_PHY_LINKDOWN) + +#define ISR_RX_PKT (\ + ISR_RX_PKT_0 |\ + ISR_RX_PKT_1 |\ + ISR_RX_PKT_2 |\ + ISR_RX_PKT_3) + +#define ISR_OVER (\ + ISR_RFD0_UR |\ + ISR_RFD1_UR |\ + ISR_RFD2_UR |\ + ISR_RFD3_UR |\ + ISR_HW_RXF_OV |\ + ISR_TXF_UR) + +#define ISR_ERROR (\ + ISR_DMAR_TO_RST |\ + ISR_TXQ_TO_RST |\ + ISR_DMAW_TO_RST |\ + ISR_PHY_LINKDOWN) + +#define REG_INT_RETRIG_TIMER 0x1608 +#define INT_RETRIG_TIMER_MASK 0xFFFF + +#define REG_HDS_CTRL 0x160C +#define HDS_CTRL_EN 0x0001 +#define HDS_CTRL_BACKFILLSIZE_SHIFT 8 +#define HDS_CTRL_BACKFILLSIZE_MASK 0x0FFF +#define HDS_CTRL_MAX_HDRSIZE_SHIFT 20 +#define HDS_CTRL_MAC_HDRSIZE_MASK 0x0FFF + +#define REG_MAC_RX_STATUS_BIN 0x1700 +#define REG_MAC_RX_STATUS_END 0x175c +#define REG_MAC_TX_STATUS_BIN 0x1760 +#define REG_MAC_TX_STATUS_END 0x17c0 + +/* DEBUG ADDR */ +#define REG_DEBUG_DATA0 0x1900 +#define REG_DEBUG_DATA1 0x1904 + +/* PHY Control Register */ +#define MII_BMCR 0x00 +#define BMCR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */ +#define BMCR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */ +#define BMCR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */ +#define BMCR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */ +#define BMCR_ISOLATE 0x0400 /* Isolate PHY from MII */ +#define BMCR_POWER_DOWN 0x0800 /* Power down */ +#define BMCR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */ +#define BMCR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */ +#define BMCR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */ +#define BMCR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */ +#define BMCR_SPEED_MASK 0x2040 +#define BMCR_SPEED_1000 0x0040 +#define BMCR_SPEED_100 0x2000 +#define BMCR_SPEED_10 0x0000 + +/* PHY Status Register */ +#define MII_BMSR 0x01 +#define BMMSR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */ +#define BMSR_JABBER_DETECT 0x0002 /* Jabber Detected */ +#define BMSR_LINK_STATUS 0x0004 /* Link Status 1 = link */ +#define BMSR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */ +#define BMSR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */ +#define BMSR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */ +#define BMSR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */ +#define BMSR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */ +#define BMSR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */ +#define BMSR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */ +#define BMSR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */ +#define BMSR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */ +#define BMSR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */ +#define BMMII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */ +#define BMMII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */ + +#define MII_PHYSID1 0x02 +#define MII_PHYSID2 0x03 + +/* Autoneg Advertisement Register */ +#define MII_ADVERTISE 0x04 +#define ADVERTISE_SPEED_MASK 0x01E0 +#define ADVERTISE_DEFAULT_CAP 0x0DE0 + +/* 1000BASE-T Control Register */ +#define MII_GIGA_CR 0x09 +#define GIGA_CR_1000T_REPEATER_DTE 0x0400 /* 1=Repeater/switch device port 0=DTE device */ + +#define GIGA_CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master 0=Configure PHY as Slave */ +#define GIGA_CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value 0=Automatic Master/Slave config */ +#define GIGA_CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */ +#define GIGA_CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */ +#define GIGA_CR_1000T_TEST_MODE_2 0x4000 /* Master Transmit Jitter test */ +#define GIGA_CR_1000T_TEST_MODE_3 0x6000 /* Slave Transmit Jitter test */ +#define GIGA_CR_1000T_TEST_MODE_4 0x8000 /* Transmitter Distortion test */ +#define GIGA_CR_1000T_SPEED_MASK 0x0300 +#define GIGA_CR_1000T_DEFAULT_CAP 0x0300 + +/* PHY Specific Status Register */ +#define MII_GIGA_PSSR 0x11 +#define GIGA_PSSR_SPD_DPLX_RESOLVED 0x0800 /* 1=Speed & Duplex resolved */ +#define GIGA_PSSR_DPLX 0x2000 /* 1=Duplex 0=Half Duplex */ +#define GIGA_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */ +#define GIGA_PSSR_10MBS 0x0000 /* 00=10Mbs */ +#define GIGA_PSSR_100MBS 0x4000 /* 01=100Mbs */ +#define GIGA_PSSR_1000MBS 0x8000 /* 10=1000Mbs */ + +/* PHY Interrupt Enable Register */ +#define MII_IER 0x12 +#define IER_LINK_UP 0x0400 +#define IER_LINK_DOWN 0x0800 + +/* PHY Interrupt Status Register */ +#define MII_ISR 0x13 +#define ISR_LINK_UP 0x0400 +#define ISR_LINK_DOWN 0x0800 + +/* Cable-Detect-Test Control Register */ +#define MII_CDTC 0x16 +#define CDTC_EN_OFF 0 /* sc */ +#define CDTC_EN_BITS 1 +#define CDTC_PAIR_OFF 8 +#define CDTC_PAIR_BIT 2 + +/* Cable-Detect-Test Status Register */ +#define MII_CDTS 0x1C +#define CDTS_STATUS_OFF 8 +#define CDTS_STATUS_BITS 2 +#define CDTS_STATUS_NORMAL 0 +#define CDTS_STATUS_SHORT 1 +#define CDTS_STATUS_OPEN 2 +#define CDTS_STATUS_INVALID 3 + +#define MII_DBG_ADDR 0x1D +#define MII_DBG_DATA 0x1E + +#define MII_ANA_CTRL_0 0x0 +#define ANA_RESTART_CAL 0x0001 +#define ANA_MANUL_SWICH_ON_SHIFT 0x1 +#define ANA_MANUL_SWICH_ON_MASK 0xF +#define ANA_MAN_ENABLE 0x0020 +#define ANA_SEL_HSP 0x0040 +#define ANA_EN_HB 0x0080 +#define ANA_EN_HBIAS 0x0100 +#define ANA_OEN_125M 0x0200 +#define ANA_EN_LCKDT 0x0400 +#define ANA_LCKDT_PHY 0x0800 +#define ANA_AFE_MODE 0x1000 +#define ANA_VCO_SLOW 0x2000 +#define ANA_VCO_FAST 0x4000 +#define ANA_SEL_CLK125M_DSP 0x8000 + +#define MII_ANA_CTRL_4 0x4 +#define ANA_IECHO_ADJ_MASK 0xF +#define ANA_IECHO_ADJ_3_SHIFT 0 +#define ANA_IECHO_ADJ_2_SHIFT 4 +#define ANA_IECHO_ADJ_1_SHIFT 8 +#define ANA_IECHO_ADJ_0_SHIFT 12 + +#define MII_ANA_CTRL_5 0x5 +#define ANA_SERDES_CDR_BW_SHIFT 0 +#define ANA_SERDES_CDR_BW_MASK 0x3 +#define ANA_MS_PAD_DBG 0x0004 +#define ANA_SPEEDUP_DBG 0x0008 +#define ANA_SERDES_TH_LOS_SHIFT 4 +#define ANA_SERDES_TH_LOS_MASK 0x3 +#define ANA_SERDES_EN_DEEM 0x0040 +#define ANA_SERDES_TXELECIDLE 0x0080 +#define ANA_SERDES_BEACON 0x0100 +#define ANA_SERDES_HALFTXDR 0x0200 +#define ANA_SERDES_SEL_HSP 0x0400 +#define ANA_SERDES_EN_PLL 0x0800 +#define ANA_SERDES_EN 0x1000 +#define ANA_SERDES_EN_LCKDT 0x2000 + +#define MII_ANA_CTRL_11 0xB +#define ANA_PS_HIB_EN 0x8000 + +#define MII_ANA_CTRL_18 0x12 +#define ANA_TEST_MODE_10BT_01SHIFT 0 +#define ANA_TEST_MODE_10BT_01MASK 0x3 +#define ANA_LOOP_SEL_10BT 0x0004 +#define ANA_RGMII_MODE_SW 0x0008 +#define ANA_EN_LONGECABLE 0x0010 +#define ANA_TEST_MODE_10BT_2 0x0020 +#define ANA_EN_10BT_IDLE 0x0400 +#define ANA_EN_MASK_TB 0x0800 +#define ANA_TRIGGER_SEL_TIMER_SHIFT 12 +#define ANA_TRIGGER_SEL_TIMER_MASK 0x3 +#define ANA_INTERVAL_SEL_TIMER_SHIFT 14 +#define ANA_INTERVAL_SEL_TIMER_MASK 0x3 + +#define MII_ANA_CTRL_41 0x29 +#define ANA_TOP_PS_EN 0x8000 + +#define MII_ANA_CTRL_54 0x36 +#define ANA_LONG_CABLE_TH_100_SHIFT 0 +#define ANA_LONG_CABLE_TH_100_MASK 0x3F +#define ANA_DESERVED 0x0040 +#define ANA_EN_LIT_CH 0x0080 +#define ANA_SHORT_CABLE_TH_100_SHIFT 8 +#define ANA_SHORT_CABLE_TH_100_MASK 0x3F +#define ANA_BP_BAD_LINK_ACCUM 0x4000 +#define ANA_BP_SMALL_BW 0x8000 + +#endif /*_ATL1C_HW_H_*/ diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c new file mode 100644 index 00000000000..deb7b53167e --- /dev/null +++ b/drivers/net/atl1c/atl1c_main.c @@ -0,0 +1,2797 @@ +/* + * Copyright(c) 2008 - 2009 Atheros Corporation. All rights reserved. + * + * Derived from Intel e1000 driver + * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "atl1c.h" + +#define ATL1C_DRV_VERSION "1.0.0.1-NAPI" +char atl1c_driver_name[] = "atl1c"; +char atl1c_driver_version[] = ATL1C_DRV_VERSION; +#define PCI_DEVICE_ID_ATTANSIC_L2C 0x1062 +#define PCI_DEVICE_ID_ATTANSIC_L1C 0x1063 +/* + * atl1c_pci_tbl - PCI Device ID Table + * + * Wildcard entries (PCI_ANY_ID) should come last + * Last entry must be all 0s + * + * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, + * Class, Class Mask, private data (not used) } + */ +static struct pci_device_id atl1c_pci_tbl[] = { + {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1C)}, + {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L2C)}, + /* required last entry */ + { 0 } +}; +MODULE_DEVICE_TABLE(pci, atl1c_pci_tbl); + +MODULE_AUTHOR("Jie Yang "); +MODULE_DESCRIPTION("Atheros 1000M Ethernet Network Driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(ATL1C_DRV_VERSION); + +static int atl1c_stop_mac(struct atl1c_hw *hw); +static void atl1c_enable_rx_ctrl(struct atl1c_hw *hw); +static void atl1c_enable_tx_ctrl(struct atl1c_hw *hw); +static void atl1c_disable_l0s_l1(struct atl1c_hw *hw); +static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup); +static void atl1c_setup_mac_ctrl(struct atl1c_adapter *adapter); +static void atl1c_clean_rx_irq(struct atl1c_adapter *adapter, u8 que, + int *work_done, int work_to_do); + +static const u16 atl1c_pay_load_size[] = { + 128, 256, 512, 1024, 2048, 4096, +}; + +static const u16 atl1c_rfd_prod_idx_regs[AT_MAX_RECEIVE_QUEUE] = +{ + REG_MB_RFD0_PROD_IDX, + REG_MB_RFD1_PROD_IDX, + REG_MB_RFD2_PROD_IDX, + REG_MB_RFD3_PROD_IDX +}; + +static const u16 atl1c_rfd_addr_lo_regs[AT_MAX_RECEIVE_QUEUE] = +{ + REG_RFD0_HEAD_ADDR_LO, + REG_RFD1_HEAD_ADDR_LO, + REG_RFD2_HEAD_ADDR_LO, + REG_RFD3_HEAD_ADDR_LO +}; + +static const u16 atl1c_rrd_addr_lo_regs[AT_MAX_RECEIVE_QUEUE] = +{ + REG_RRD0_HEAD_ADDR_LO, + REG_RRD1_HEAD_ADDR_LO, + REG_RRD2_HEAD_ADDR_LO, + REG_RRD3_HEAD_ADDR_LO +}; + +static const u32 atl1c_default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | + NETIF_MSG_LINK | NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP; + +/* + * atl1c_init_pcie - init PCIE module + */ +static void atl1c_reset_pcie(struct atl1c_hw *hw, u32 flag) +{ + u32 data; + u32 pci_cmd; + struct pci_dev *pdev = hw->adapter->pdev; + + AT_READ_REG(hw, PCI_COMMAND, &pci_cmd); + pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; + pci_cmd |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | + PCI_COMMAND_IO); + AT_WRITE_REG(hw, PCI_COMMAND, pci_cmd); + + /* + * Clear any PowerSaveing Settings + */ + pci_enable_wake(pdev, PCI_D3hot, 0); + pci_enable_wake(pdev, PCI_D3cold, 0); + + /* + * Mask some pcie error bits + */ + AT_READ_REG(hw, REG_PCIE_UC_SEVERITY, &data); + data &= ~PCIE_UC_SERVRITY_DLP; + data &= ~PCIE_UC_SERVRITY_FCP; + AT_WRITE_REG(hw, REG_PCIE_UC_SEVERITY, data); + + if (flag & ATL1C_PCIE_L0S_L1_DISABLE) + atl1c_disable_l0s_l1(hw); + if (flag & ATL1C_PCIE_PHY_RESET) + AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT); + else + AT_WRITE_REG(hw, REG_GPHY_CTRL, + GPHY_CTRL_DEFAULT | GPHY_CTRL_EXT_RESET); + + msleep(1); +} + +/* + * atl1c_irq_enable - Enable default interrupt generation settings + * @adapter: board private structure + */ +static inline void atl1c_irq_enable(struct atl1c_adapter *adapter) +{ + if (likely(atomic_dec_and_test(&adapter->irq_sem))) { + AT_WRITE_REG(&adapter->hw, REG_ISR, 0x7FFFFFFF); + AT_WRITE_REG(&adapter->hw, REG_IMR, adapter->hw.intr_mask); + AT_WRITE_FLUSH(&adapter->hw); + } +} + +/* + * atl1c_irq_disable - Mask off interrupt generation on the NIC + * @adapter: board private structure + */ +static inline void atl1c_irq_disable(struct atl1c_adapter *adapter) +{ + atomic_inc(&adapter->irq_sem); + AT_WRITE_REG(&adapter->hw, REG_IMR, 0); + AT_WRITE_FLUSH(&adapter->hw); + synchronize_irq(adapter->pdev->irq); +} + +/* + * atl1c_irq_reset - reset interrupt confiure on the NIC + * @adapter: board private structure + */ +static inline void atl1c_irq_reset(struct atl1c_adapter *adapter) +{ + atomic_set(&adapter->irq_sem, 1); + atl1c_irq_enable(adapter); +} + +/* + * atl1c_phy_config - Timer Call-back + * @data: pointer to netdev cast into an unsigned long + */ +static void atl1c_phy_config(unsigned long data) +{ + struct atl1c_adapter *adapter = (struct atl1c_adapter *) data; + struct atl1c_hw *hw = &adapter->hw; + unsigned long flags; + + spin_lock_irqsave(&adapter->mdio_lock, flags); + atl1c_restart_autoneg(hw); + spin_unlock_irqrestore(&adapter->mdio_lock, flags); +} + +void atl1c_reinit_locked(struct atl1c_adapter *adapter) +{ + + WARN_ON(in_interrupt()); + atl1c_down(adapter); + atl1c_up(adapter); + clear_bit(__AT_RESETTING, &adapter->flags); +} + +static void atl1c_reset_task(struct work_struct *work) +{ + struct atl1c_adapter *adapter; + struct net_device *netdev; + + adapter = container_of(work, struct atl1c_adapter, reset_task); + netdev = adapter->netdev; + + netif_device_detach(netdev); + atl1c_down(adapter); + atl1c_up(adapter); + netif_device_attach(netdev); +} + +static void atl1c_check_link_status(struct atl1c_adapter *adapter) +{ + struct atl1c_hw *hw = &adapter->hw; + struct net_device *netdev = adapter->netdev; + struct pci_dev *pdev = adapter->pdev; + int err; + unsigned long flags; + u16 speed, duplex, phy_data; + + spin_lock_irqsave(&adapter->mdio_lock, flags); + /* MII_BMSR must read twise */ + atl1c_read_phy_reg(hw, MII_BMSR, &phy_data); + atl1c_read_phy_reg(hw, MII_BMSR, &phy_data); + spin_unlock_irqrestore(&adapter->mdio_lock, flags); + + if ((phy_data & BMSR_LSTATUS) == 0) { + /* link down */ + if (netif_carrier_ok(netdev)) { + hw->hibernate = true; + atl1c_set_aspm(hw, false); + if (atl1c_stop_mac(hw) != 0) + if (netif_msg_hw(adapter)) + dev_warn(&pdev->dev, + "stop mac failed\n"); + } + netif_carrier_off(netdev); + } else { + /* Link Up */ + hw->hibernate = false; + spin_lock_irqsave(&adapter->mdio_lock, flags); + err = atl1c_get_speed_and_duplex(hw, &speed, &duplex); + spin_unlock_irqrestore(&adapter->mdio_lock, flags); + if (unlikely(err)) + return; + /* link result is our setting */ + if (adapter->link_speed != speed || + adapter->link_duplex != duplex) { + adapter->link_speed = speed; + adapter->link_duplex = duplex; + atl1c_enable_tx_ctrl(hw); + atl1c_enable_rx_ctrl(hw); + atl1c_setup_mac_ctrl(adapter); + atl1c_set_aspm(hw, true); + if (netif_msg_link(adapter)) + dev_info(&pdev->dev, + "%s: %s NIC Link is Up<%d Mbps %s>\n", + atl1c_driver_name, netdev->name, + adapter->link_speed, + adapter->link_duplex == FULL_DUPLEX ? + "Full Duplex" : "Half Duplex"); + } + if (!netif_carrier_ok(netdev)) + netif_carrier_on(netdev); + } +} + +/* + * atl1c_link_chg_task - deal with link change event Out of interrupt context + * @netdev: network interface device structure + */ +static void atl1c_link_chg_task(struct work_struct *work) +{ + struct atl1c_adapter *adapter; + + adapter = container_of(work, struct atl1c_adapter, link_chg_task); + atl1c_check_link_status(adapter); +} + +static void atl1c_link_chg_event(struct atl1c_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + struct pci_dev *pdev = adapter->pdev; + u16 phy_data; + u16 link_up; + + spin_lock(&adapter->mdio_lock); + atl1c_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data); + atl1c_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data); + spin_unlock(&adapter->mdio_lock); + link_up = phy_data & BMSR_LSTATUS; + /* notify upper layer link down ASAP */ + if (!link_up) { + if (netif_carrier_ok(netdev)) { + /* old link state: Up */ + netif_carrier_off(netdev); + if (netif_msg_link(adapter)) + dev_info(&pdev->dev, + "%s: %s NIC Link is Down\n", + atl1c_driver_name, netdev->name); + adapter->link_speed = SPEED_0; + } + } + schedule_work(&adapter->link_chg_task); +} + +static void atl1c_del_timer(struct atl1c_adapter *adapter) +{ + del_timer_sync(&adapter->phy_config_timer); +} + +static void atl1c_cancel_work(struct atl1c_adapter *adapter) +{ + cancel_work_sync(&adapter->reset_task); + cancel_work_sync(&adapter->link_chg_task); +} + +/* + * atl1c_tx_timeout - Respond to a Tx Hang + * @netdev: network interface device structure + */ +static void atl1c_tx_timeout(struct net_device *netdev) +{ + struct atl1c_adapter *adapter = netdev_priv(netdev); + + /* Do the reset outside of interrupt context */ + schedule_work(&adapter->reset_task); +} + +/* + * atl1c_set_multi - Multicast and Promiscuous mode set + * @netdev: network interface device structure + * + * The set_multi entry point is called whenever the multicast address + * list or the network interface flags are updated. This routine is + * responsible for configuring the hardware for proper multicast, + * promiscuous mode, and all-multi behavior. + */ +static void atl1c_set_multi(struct net_device *netdev) +{ + struct atl1c_adapter *adapter = netdev_priv(netdev); + struct atl1c_hw *hw = &adapter->hw; + struct dev_mc_list *mc_ptr; + u32 mac_ctrl_data; + u32 hash_value; + + /* Check for Promiscuous and All Multicast modes */ + AT_READ_REG(hw, REG_MAC_CTRL, &mac_ctrl_data); + + if (netdev->flags & IFF_PROMISC) { + mac_ctrl_data |= MAC_CTRL_PROMIS_EN; + } else if (netdev->flags & IFF_ALLMULTI) { + mac_ctrl_data |= MAC_CTRL_MC_ALL_EN; + mac_ctrl_data &= ~MAC_CTRL_PROMIS_EN; + } else { + mac_ctrl_data &= ~(MAC_CTRL_PROMIS_EN | MAC_CTRL_MC_ALL_EN); + } + + AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data); + + /* clear the old settings from the multicast hash table */ + AT_WRITE_REG(hw, REG_RX_HASH_TABLE, 0); + AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0); + + /* comoute mc addresses' hash value ,and put it into hash table */ + for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) { + hash_value = atl1c_hash_mc_addr(hw, mc_ptr->dmi_addr); + atl1c_hash_set(hw, hash_value); + } +} + +static void atl1c_vlan_rx_register(struct net_device *netdev, + struct vlan_group *grp) +{ + struct atl1c_adapter *adapter = netdev_priv(netdev); + struct pci_dev *pdev = adapter->pdev; + u32 mac_ctrl_data = 0; + + if (netif_msg_pktdata(adapter)) + dev_dbg(&pdev->dev, "atl1c_vlan_rx_register\n"); + + atl1c_irq_disable(adapter); + + adapter->vlgrp = grp; + AT_READ_REG(&adapter->hw, REG_MAC_CTRL, &mac_ctrl_data); + + if (grp) { + /* enable VLAN tag insert/strip */ + mac_ctrl_data |= MAC_CTRL_RMV_VLAN; + } else { + /* disable VLAN tag insert/strip */ + mac_ctrl_data &= ~MAC_CTRL_RMV_VLAN; + } + + AT_WRITE_REG(&adapter->hw, REG_MAC_CTRL, mac_ctrl_data); + atl1c_irq_enable(adapter); +} + +static void atl1c_restore_vlan(struct atl1c_adapter *adapter) +{ + struct pci_dev *pdev = adapter->pdev; + + if (netif_msg_pktdata(adapter)) + dev_dbg(&pdev->dev, "atl1c_restore_vlan !"); + atl1c_vlan_rx_register(adapter->netdev, adapter->vlgrp); +} +/* + * atl1c_set_mac - Change the Ethernet Address of the NIC + * @netdev: network interface device structure + * @p: pointer to an address structure + * + * Returns 0 on success, negative on failure + */ +static int atl1c_set_mac_addr(struct net_device *netdev, void *p) +{ + struct atl1c_adapter *adapter = netdev_priv(netdev); + struct sockaddr *addr = p; + + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + + if (netif_running(netdev)) + return -EBUSY; + + memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); + memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len); + + atl1c_hw_set_mac_addr(&adapter->hw); + + return 0; +} + +static void atl1c_set_rxbufsize(struct atl1c_adapter *adapter, + struct net_device *dev) +{ + int mtu = dev->mtu; + + adapter->rx_buffer_len = mtu > AT_RX_BUF_SIZE ? + roundup(mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN, 8) : AT_RX_BUF_SIZE; +} +/* + * atl1c_change_mtu - Change the Maximum Transfer Unit + * @netdev: network interface device structure + * @new_mtu: new value for maximum frame size + * + * Returns 0 on success, negative on failure + */ +static int atl1c_change_mtu(struct net_device *netdev, int new_mtu) +{ + struct atl1c_adapter *adapter = netdev_priv(netdev); + int old_mtu = netdev->mtu; + int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN; + + if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) || + (max_frame > MAX_JUMBO_FRAME_SIZE)) { + if (netif_msg_link(adapter)) + dev_warn(&adapter->pdev->dev, "invalid MTU setting\n"); + return -EINVAL; + } + /* set MTU */ + if (old_mtu != new_mtu && netif_running(netdev)) { + while (test_and_set_bit(__AT_RESETTING, &adapter->flags)) + msleep(1); + netdev->mtu = new_mtu; + adapter->hw.max_frame_size = new_mtu; + atl1c_set_rxbufsize(adapter, netdev); + atl1c_down(adapter); + atl1c_up(adapter); + clear_bit(__AT_RESETTING, &adapter->flags); + if (adapter->hw.ctrl_flags & ATL1C_FPGA_VERSION) { + u32 phy_data; + + AT_READ_REG(&adapter->hw, 0x1414, &phy_data); + phy_data |= 0x10000000; + AT_WRITE_REG(&adapter->hw, 0x1414, phy_data); + } + + } + return 0; +} + +/* + * caller should hold mdio_lock + */ +static int atl1c_mdio_read(struct net_device *netdev, int phy_id, int reg_num) +{ + struct atl1c_adapter *adapter = netdev_priv(netdev); + u16 result; + + atl1c_read_phy_reg(&adapter->hw, reg_num & MDIO_REG_ADDR_MASK, &result); + return result; +} + +static void atl1c_mdio_write(struct net_device *netdev, int phy_id, + int reg_num, int val) +{ + struct atl1c_adapter *adapter = netdev_priv(netdev); + + atl1c_write_phy_reg(&adapter->hw, reg_num & MDIO_REG_ADDR_MASK, val); +} + +/* + * atl1c_mii_ioctl - + * @netdev: + * @ifreq: + * @cmd: + */ +static int atl1c_mii_ioctl(struct net_device *netdev, + struct ifreq *ifr, int cmd) +{ + struct atl1c_adapter *adapter = netdev_priv(netdev); + struct pci_dev *pdev = adapter->pdev; + struct mii_ioctl_data *data = if_mii(ifr); + unsigned long flags; + int retval = 0; + + if (!netif_running(netdev)) + return -EINVAL; + + spin_lock_irqsave(&adapter->mdio_lock, flags); + switch (cmd) { + case SIOCGMIIPHY: + data->phy_id = 0; + break; + + case SIOCGMIIREG: + if (!capable(CAP_NET_ADMIN)) { + retval = -EPERM; + goto out; + } + if (atl1c_read_phy_reg(&adapter->hw, data->reg_num & 0x1F, + &data->val_out)) { + retval = -EIO; + goto out; + } + break; + + case SIOCSMIIREG: + if (!capable(CAP_NET_ADMIN)) { + retval = -EPERM; + goto out; + } + if (data->reg_num & ~(0x1F)) { + retval = -EFAULT; + goto out; + } + + dev_dbg(&pdev->dev, " write %x %x", + data->reg_num, data->val_in); + if (atl1c_write_phy_reg(&adapter->hw, + data->reg_num, data->val_in)) { + retval = -EIO; + goto out; + } + break; + + default: + retval = -EOPNOTSUPP; + break; + } +out: + spin_unlock_irqrestore(&adapter->mdio_lock, flags); + return retval; +} + +/* + * atl1c_ioctl - + * @netdev: + * @ifreq: + * @cmd: + */ +static int atl1c_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) +{ + switch (cmd) { + case SIOCGMIIPHY: + case SIOCGMIIREG: + case SIOCSMIIREG: + return atl1c_mii_ioctl(netdev, ifr, cmd); + default: + return -EOPNOTSUPP; + } +} + +/* + * atl1c_alloc_queues - Allocate memory for all rings + * @adapter: board private structure to initialize + * + */ +static int __devinit atl1c_alloc_queues(struct atl1c_adapter *adapter) +{ + return 0; +} + +static void atl1c_set_mac_type(struct atl1c_hw *hw) +{ + switch (hw->device_id) { + case PCI_DEVICE_ID_ATTANSIC_L2C: + hw->nic_type = athr_l2c; + break; + + case PCI_DEVICE_ID_ATTANSIC_L1C: + hw->nic_type = athr_l1c; + break; + + default: + break; + } +} + +static int atl1c_setup_mac_funcs(struct atl1c_hw *hw) +{ + u32 phy_status_data; + u32 link_ctrl_data; + + atl1c_set_mac_type(hw); + AT_READ_REG(hw, REG_PHY_STATUS, &phy_status_data); + AT_READ_REG(hw, REG_LINK_CTRL, &link_ctrl_data); + + hw->ctrl_flags = ATL1C_INTR_CLEAR_ON_READ | + ATL1C_INTR_MODRT_ENABLE | + ATL1C_RX_IPV6_CHKSUM | + ATL1C_TXQ_MODE_ENHANCE; + if (link_ctrl_data & LINK_CTRL_L0S_EN) + hw->ctrl_flags |= ATL1C_ASPM_L0S_SUPPORT; + if (link_ctrl_data & LINK_CTRL_L1_EN) + hw->ctrl_flags |= ATL1C_ASPM_L1_SUPPORT; + + if (hw->nic_type == athr_l1c) { + hw->ctrl_flags |= ATL1C_ASPM_CTRL_MON; + hw->ctrl_flags |= ATL1C_LINK_CAP_1000M; + } + return 0; +} +/* + * atl1c_sw_init - Initialize general software structures (struct atl1c_adapter) + * @adapter: board private structure to initialize + * + * atl1c_sw_init initializes the Adapter private data structure. + * Fields are initialized based on PCI device information and + * OS network device settings (MTU size). + */ +static int __devinit atl1c_sw_init(struct atl1c_adapter *adapter) +{ + struct atl1c_hw *hw = &adapter->hw; + struct pci_dev *pdev = adapter->pdev; + + adapter->wol = 0; + adapter->link_speed = SPEED_0; + adapter->link_duplex = FULL_DUPLEX; + adapter->num_rx_queues = AT_DEF_RECEIVE_QUEUE; + adapter->tpd_ring[0].count = 1024; + adapter->rfd_ring[0].count = 512; + + hw->vendor_id = pdev->vendor; + hw->device_id = pdev->device; + hw->subsystem_vendor_id = pdev->subsystem_vendor; + hw->subsystem_id = pdev->subsystem_device; + + /* before link up, we assume hibernate is true */ + hw->hibernate = true; + hw->media_type = MEDIA_TYPE_AUTO_SENSOR; + if (atl1c_setup_mac_funcs(hw) != 0) { + dev_err(&pdev->dev, "set mac function pointers failed\n"); + return -1; + } + hw->intr_mask = IMR_NORMAL_MASK; + hw->phy_configured = false; + hw->preamble_len = 7; + hw->max_frame_size = adapter->netdev->mtu; + if (adapter->num_rx_queues < 2) { + hw->rss_type = atl1c_rss_disable; + hw->rss_mode = atl1c_rss_mode_disable; + } else { + hw->rss_type = atl1c_rss_ipv4; + hw->rss_mode = atl1c_rss_mul_que_mul_int; + hw->rss_hash_bits = 16; + } + hw->autoneg_advertised = ADVERTISED_Autoneg; + hw->indirect_tab = 0xE4E4E4E4; + hw->base_cpu = 0; + + hw->ict = 50000; /* 100ms */ + hw->smb_timer = 200000; /* 400ms */ + hw->cmb_tpd = 4; + hw->cmb_tx_timer = 1; /* 2 us */ + hw->rx_imt = 200; + hw->tx_imt = 1000; + + hw->tpd_burst = 5; + hw->rfd_burst = 8; + hw->dma_order = atl1c_dma_ord_out; + hw->dmar_block = atl1c_dma_req_1024; + hw->dmaw_block = atl1c_dma_req_1024; + hw->dmar_dly_cnt = 15; + hw->dmaw_dly_cnt = 4; + + if (atl1c_alloc_queues(adapter)) { + dev_err(&pdev->dev, "Unable to allocate memory for queues\n"); + return -ENOMEM; + } + /* TODO */ + atl1c_set_rxbufsize(adapter, adapter->netdev); + atomic_set(&adapter->irq_sem, 1); + spin_lock_init(&adapter->mdio_lock); + spin_lock_init(&adapter->tx_lock); + set_bit(__AT_DOWN, &adapter->flags); + + return 0; +} + +/* + * atl1c_clean_tx_ring - Free Tx-skb + * @adapter: board private structure + */ +static void atl1c_clean_tx_ring(struct atl1c_adapter *adapter, + enum atl1c_trans_queue type) +{ + struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type]; + struct atl1c_buffer *buffer_info; + struct pci_dev *pdev = adapter->pdev; + u16 index, ring_count; + + ring_count = tpd_ring->count; + for (index = 0; index < ring_count; index++) { + buffer_info = &tpd_ring->buffer_info[index]; + if (buffer_info->state == ATL1_BUFFER_FREE) + continue; + if (buffer_info->dma) + pci_unmap_single(pdev, buffer_info->dma, + buffer_info->length, + PCI_DMA_TODEVICE); + if (buffer_info->skb) + dev_kfree_skb(buffer_info->skb); + buffer_info->dma = 0; + buffer_info->skb = NULL; + buffer_info->state = ATL1_BUFFER_FREE; + } + + /* Zero out Tx-buffers */ + memset(tpd_ring->desc, 0, sizeof(struct atl1c_tpd_desc) * + ring_count); + atomic_set(&tpd_ring->next_to_clean, 0); + tpd_ring->next_to_use = 0; +} + +/* + * atl1c_clean_rx_ring - Free rx-reservation skbs + * @adapter: board private structure + */ +static void atl1c_clean_rx_ring(struct atl1c_adapter *adapter) +{ + struct atl1c_rfd_ring *rfd_ring = adapter->rfd_ring; + struct atl1c_rrd_ring *rrd_ring = adapter->rrd_ring; + struct atl1c_buffer *buffer_info; + struct pci_dev *pdev = adapter->pdev; + int i, j; + + for (i = 0; i < adapter->num_rx_queues; i++) { + for (j = 0; j < rfd_ring[i].count; j++) { + buffer_info = &rfd_ring[i].buffer_info[j]; + if (buffer_info->state == ATL1_BUFFER_FREE) + continue; + if (buffer_info->dma) + pci_unmap_single(pdev, buffer_info->dma, + buffer_info->length, + PCI_DMA_FROMDEVICE); + if (buffer_info->skb) + dev_kfree_skb(buffer_info->skb); + buffer_info->state = ATL1_BUFFER_FREE; + buffer_info->skb = NULL; + } + /* zero out the descriptor ring */ + memset(rfd_ring[i].desc, 0, rfd_ring[i].size); + rfd_ring[i].next_to_clean = 0; + rfd_ring[i].next_to_use = 0; + rrd_ring[i].next_to_use = 0; + rrd_ring[i].next_to_clean = 0; + } +} + +/* + * Read / Write Ptr Initialize: + */ +static void atl1c_init_ring_ptrs(struct atl1c_adapter *adapter) +{ + struct atl1c_tpd_ring *tpd_ring = adapter->tpd_ring; + struct atl1c_rfd_ring *rfd_ring = adapter->rfd_ring; + struct atl1c_rrd_ring *rrd_ring = adapter->rrd_ring; + struct atl1c_buffer *buffer_info; + int i, j; + + for (i = 0; i < AT_MAX_TRANSMIT_QUEUE; i++) { + tpd_ring[i].next_to_use = 0; + atomic_set(&tpd_ring[i].next_to_clean, 0); + buffer_info = tpd_ring[i].buffer_info; + for (j = 0; j < tpd_ring->count; j++) + buffer_info[i].state = ATL1_BUFFER_FREE; + } + for (i = 0; i < adapter->num_rx_queues; i++) { + rfd_ring[i].next_to_use = 0; + rfd_ring[i].next_to_clean = 0; + rrd_ring[i].next_to_use = 0; + rrd_ring[i].next_to_clean = 0; + for (j = 0; j < rfd_ring[i].count; j++) { + buffer_info = &rfd_ring[i].buffer_info[j]; + buffer_info->state = ATL1_BUFFER_FREE; + } + } +} + +/* + * atl1c_free_ring_resources - Free Tx / RX descriptor Resources + * @adapter: board private structure + * + * Free all transmit software resources + */ +static void atl1c_free_ring_resources(struct atl1c_adapter *adapter) +{ + struct pci_dev *pdev = adapter->pdev; + + pci_free_consistent(pdev, adapter->ring_header.size, + adapter->ring_header.desc, + adapter->ring_header.dma); + adapter->ring_header.desc = NULL; + + /* Note: just free tdp_ring.buffer_info, + * it contain rfd_ring.buffer_info, do not double free */ + if (adapter->tpd_ring[0].buffer_info) { + kfree(adapter->tpd_ring[0].buffer_info); + adapter->tpd_ring[0].buffer_info = NULL; + } +} + +/* + * atl1c_setup_mem_resources - allocate Tx / RX descriptor resources + * @adapter: board private structure + * + * Return 0 on success, negative on failure + */ +static int atl1c_setup_ring_resources(struct atl1c_adapter *adapter) +{ + struct pci_dev *pdev = adapter->pdev; + struct atl1c_tpd_ring *tpd_ring = adapter->tpd_ring; + struct atl1c_rfd_ring *rfd_ring = adapter->rfd_ring; + struct atl1c_rrd_ring *rrd_ring = adapter->rrd_ring; + struct atl1c_ring_header *ring_header = &adapter->ring_header; + int num_rx_queues = adapter->num_rx_queues; + int size; + int i; + int count = 0; + int rx_desc_count = 0; + u32 offset = 0; + + rrd_ring[0].count = rfd_ring[0].count; + for (i = 1; i < AT_MAX_TRANSMIT_QUEUE; i++) + tpd_ring[i].count = tpd_ring[0].count; + + for (i = 1; i < adapter->num_rx_queues; i++) + rfd_ring[i].count = rrd_ring[i].count = rfd_ring[0].count; + + /* 2 tpd queue, one high priority queue, + * another normal priority queue */ + size = sizeof(struct atl1c_buffer) * (tpd_ring->count * 2 + + rfd_ring->count * num_rx_queues); + tpd_ring->buffer_info = kzalloc(size, GFP_KERNEL); + if (unlikely(!tpd_ring->buffer_info)) { + dev_err(&pdev->dev, "kzalloc failed, size = %d\n", + size); + goto err_nomem; + } + for (i = 0; i < AT_MAX_TRANSMIT_QUEUE; i++) { + tpd_ring[i].buffer_info = + (struct atl1c_buffer *) (tpd_ring->buffer_info + count); + count += tpd_ring[i].count; + } + + for (i = 0; i < num_rx_queues; i++) { + rfd_ring[i].buffer_info = + (struct atl1c_buffer *) (tpd_ring->buffer_info + count); + count += rfd_ring[i].count; + rx_desc_count += rfd_ring[i].count; + } + /* + * real ring DMA buffer + * each ring/block may need up to 8 bytes for alignment, hence the + * additional bytes tacked onto the end. + */ + ring_header->size = size = + sizeof(struct atl1c_tpd_desc) * tpd_ring->count * 2 + + sizeof(struct atl1c_rx_free_desc) * rx_desc_count + + sizeof(struct atl1c_recv_ret_status) * rx_desc_count + + sizeof(struct atl1c_hw_stats) + + 8 * 4 + 8 * 2 * num_rx_queues; + + ring_header->desc = pci_alloc_consistent(pdev, ring_header->size, + &ring_header->dma); + if (unlikely(!ring_header->desc)) { + dev_err(&pdev->dev, "pci_alloc_consistend failed\n"); + goto err_nomem; + } + memset(ring_header->desc, 0, ring_header->size); + /* init TPD ring */ + + tpd_ring[0].dma = roundup(ring_header->dma, 8); + offset = tpd_ring[0].dma - ring_header->dma; + for (i = 0; i < AT_MAX_TRANSMIT_QUEUE; i++) { + tpd_ring[i].dma = ring_header->dma + offset; + tpd_ring[i].desc = (u8 *) ring_header->desc + offset; + tpd_ring[i].size = + sizeof(struct atl1c_tpd_desc) * tpd_ring[i].count; + offset += roundup(tpd_ring[i].size, 8); + } + /* init RFD ring */ + for (i = 0; i < num_rx_queues; i++) { + rfd_ring[i].dma = ring_header->dma + offset; + rfd_ring[i].desc = (u8 *) ring_header->desc + offset; + rfd_ring[i].size = sizeof(struct atl1c_rx_free_desc) * + rfd_ring[i].count; + offset += roundup(rfd_ring[i].size, 8); + } + + /* init RRD ring */ + for (i = 0; i < num_rx_queues; i++) { + rrd_ring[i].dma = ring_header->dma + offset; + rrd_ring[i].desc = (u8 *) ring_header->desc + offset; + rrd_ring[i].size = sizeof(struct atl1c_recv_ret_status) * + rrd_ring[i].count; + offset += roundup(rrd_ring[i].size, 8); + } + + adapter->smb.dma = ring_header->dma + offset; + adapter->smb.smb = (u8 *)ring_header->desc + offset; + return 0; + +err_nomem: + kfree(tpd_ring->buffer_info); + return -ENOMEM; +} + +static void atl1c_configure_des_ring(struct atl1c_adapter *adapter) +{ + struct atl1c_hw *hw = &adapter->hw; + struct atl1c_rfd_ring *rfd_ring = (struct atl1c_rfd_ring *) + adapter->rfd_ring; + struct atl1c_rrd_ring *rrd_ring = (struct atl1c_rrd_ring *) + adapter->rrd_ring; + struct atl1c_tpd_ring *tpd_ring = (struct atl1c_tpd_ring *) + adapter->tpd_ring; + struct atl1c_cmb *cmb = (struct atl1c_cmb *) &adapter->cmb; + struct atl1c_smb *smb = (struct atl1c_smb *) &adapter->smb; + int i; + + /* TPD */ + AT_WRITE_REG(hw, REG_TX_BASE_ADDR_HI, + (u32)((tpd_ring[atl1c_trans_normal].dma & + AT_DMA_HI_ADDR_MASK) >> 32)); + /* just enable normal priority TX queue */ + AT_WRITE_REG(hw, REG_NTPD_HEAD_ADDR_LO, + (u32)(tpd_ring[atl1c_trans_normal].dma & + AT_DMA_LO_ADDR_MASK)); + AT_WRITE_REG(hw, REG_HTPD_HEAD_ADDR_LO, + (u32)(tpd_ring[atl1c_trans_high].dma & + AT_DMA_LO_ADDR_MASK)); + AT_WRITE_REG(hw, REG_TPD_RING_SIZE, + (u32)(tpd_ring[0].count & TPD_RING_SIZE_MASK)); + + + /* RFD */ + AT_WRITE_REG(hw, REG_RX_BASE_ADDR_HI, + (u32)((rfd_ring[0].dma & AT_DMA_HI_ADDR_MASK) >> 32)); + for (i = 0; i < adapter->num_rx_queues; i++) + AT_WRITE_REG(hw, atl1c_rfd_addr_lo_regs[i], + (u32)(rfd_ring[i].dma & AT_DMA_LO_ADDR_MASK)); + + AT_WRITE_REG(hw, REG_RFD_RING_SIZE, + rfd_ring[0].count & RFD_RING_SIZE_MASK); + AT_WRITE_REG(hw, REG_RX_BUF_SIZE, + adapter->rx_buffer_len & RX_BUF_SIZE_MASK); + + /* RRD */ + for (i = 0; i < adapter->num_rx_queues; i++) + AT_WRITE_REG(hw, atl1c_rrd_addr_lo_regs[i], + (u32)(rrd_ring[i].dma & AT_DMA_LO_ADDR_MASK)); + AT_WRITE_REG(hw, REG_RRD_RING_SIZE, + (rrd_ring[0].count & RRD_RING_SIZE_MASK)); + + /* CMB */ + AT_WRITE_REG(hw, REG_CMB_BASE_ADDR_LO, cmb->dma & AT_DMA_LO_ADDR_MASK); + + /* SMB */ + AT_WRITE_REG(hw, REG_SMB_BASE_ADDR_HI, + (u32)((smb->dma & AT_DMA_HI_ADDR_MASK) >> 32)); + AT_WRITE_REG(hw, REG_SMB_BASE_ADDR_LO, + (u32)(smb->dma & AT_DMA_LO_ADDR_MASK)); + /* Load all of base address above */ + AT_WRITE_REG(hw, REG_LOAD_PTR, 1); +} + +static void atl1c_configure_tx(struct atl1c_adapter *adapter) +{ + struct atl1c_hw *hw = &adapter->hw; + u32 dev_ctrl_data; + u32 max_pay_load; + u16 tx_offload_thresh; + u32 txq_ctrl_data; + u32 extra_size = 0; /* Jumbo frame threshold in QWORD unit */ + + extra_size = ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN; + tx_offload_thresh = MAX_TX_OFFLOAD_THRESH; + AT_WRITE_REG(hw, REG_TX_TSO_OFFLOAD_THRESH, + (tx_offload_thresh >> 3) & TX_TSO_OFFLOAD_THRESH_MASK); + AT_READ_REG(hw, REG_DEVICE_CTRL, &dev_ctrl_data); + max_pay_load = (dev_ctrl_data >> DEVICE_CTRL_MAX_PAYLOAD_SHIFT) & + DEVICE_CTRL_MAX_PAYLOAD_MASK; + hw->dmaw_block = min(max_pay_load, hw->dmaw_block); + max_pay_load = (dev_ctrl_data >> DEVICE_CTRL_MAX_RREQ_SZ_SHIFT) & + DEVICE_CTRL_MAX_RREQ_SZ_MASK; + hw->dmar_block = min(max_pay_load, hw->dmar_block); + + txq_ctrl_data = (hw->tpd_burst & TXQ_NUM_TPD_BURST_MASK) << + TXQ_NUM_TPD_BURST_SHIFT; + if (hw->ctrl_flags & ATL1C_TXQ_MODE_ENHANCE) + txq_ctrl_data |= TXQ_CTRL_ENH_MODE; + txq_ctrl_data |= (atl1c_pay_load_size[hw->dmar_block] & + TXQ_TXF_BURST_NUM_MASK) << TXQ_TXF_BURST_NUM_SHIFT; + + AT_WRITE_REG(hw, REG_TXQ_CTRL, txq_ctrl_data); +} + +static void atl1c_configure_rx(struct atl1c_adapter *adapter) +{ + struct atl1c_hw *hw = &adapter->hw; + u32 rxq_ctrl_data; + + rxq_ctrl_data = (hw->rfd_burst & RXQ_RFD_BURST_NUM_MASK) << + RXQ_RFD_BURST_NUM_SHIFT; + + if (hw->ctrl_flags & ATL1C_RX_IPV6_CHKSUM) + rxq_ctrl_data |= IPV6_CHKSUM_CTRL_EN; + if (hw->rss_type == atl1c_rss_ipv4) + rxq_ctrl_data |= RSS_HASH_IPV4; + if (hw->rss_type == atl1c_rss_ipv4_tcp) + rxq_ctrl_data |= RSS_HASH_IPV4_TCP; + if (hw->rss_type == atl1c_rss_ipv6) + rxq_ctrl_data |= RSS_HASH_IPV6; + if (hw->rss_type == atl1c_rss_ipv6_tcp) + rxq_ctrl_data |= RSS_HASH_IPV6_TCP; + if (hw->rss_type != atl1c_rss_disable) + rxq_ctrl_data |= RRS_HASH_CTRL_EN; + + rxq_ctrl_data |= (hw->rss_mode & RSS_MODE_MASK) << + RSS_MODE_SHIFT; + rxq_ctrl_data |= (hw->rss_hash_bits & RSS_HASH_BITS_MASK) << + RSS_HASH_BITS_SHIFT; + if (hw->ctrl_flags & ATL1C_ASPM_CTRL_MON) + rxq_ctrl_data |= (ASPM_THRUPUT_LIMIT_100M & + ASPM_THRUPUT_LIMIT_MASK) << ASPM_THRUPUT_LIMIT_SHIFT; + + AT_WRITE_REG(hw, REG_RXQ_CTRL, rxq_ctrl_data); +} + +static void atl1c_configure_rss(struct atl1c_adapter *adapter) +{ + struct atl1c_hw *hw = &adapter->hw; + + AT_WRITE_REG(hw, REG_IDT_TABLE, hw->indirect_tab); + AT_WRITE_REG(hw, REG_BASE_CPU_NUMBER, hw->base_cpu); +} + +static void atl1c_configure_dma(struct atl1c_adapter *adapter) +{ + struct atl1c_hw *hw = &adapter->hw; + u32 dma_ctrl_data; + + dma_ctrl_data = DMA_CTRL_DMAR_REQ_PRI; + if (hw->ctrl_flags & ATL1C_CMB_ENABLE) + dma_ctrl_data |= DMA_CTRL_CMB_EN; + if (hw->ctrl_flags & ATL1C_SMB_ENABLE) + dma_ctrl_data |= DMA_CTRL_SMB_EN; + else + dma_ctrl_data |= MAC_CTRL_SMB_DIS; + + switch (hw->dma_order) { + case atl1c_dma_ord_in: + dma_ctrl_data |= DMA_CTRL_DMAR_IN_ORDER; + break; + case atl1c_dma_ord_enh: + dma_ctrl_data |= DMA_CTRL_DMAR_ENH_ORDER; + break; + case atl1c_dma_ord_out: + dma_ctrl_data |= DMA_CTRL_DMAR_OUT_ORDER; + break; + default: + break; + } + + dma_ctrl_data |= (((u32)hw->dmar_block) & DMA_CTRL_DMAR_BURST_LEN_MASK) + << DMA_CTRL_DMAR_BURST_LEN_SHIFT; + dma_ctrl_data |= (((u32)hw->dmaw_block) & DMA_CTRL_DMAW_BURST_LEN_MASK) + << DMA_CTRL_DMAW_BURST_LEN_SHIFT; + dma_ctrl_data |= (((u32)hw->dmar_dly_cnt) & DMA_CTRL_DMAR_DLY_CNT_MASK) + << DMA_CTRL_DMAR_DLY_CNT_SHIFT; + dma_ctrl_data |= (((u32)hw->dmaw_dly_cnt) & DMA_CTRL_DMAW_DLY_CNT_MASK) + << DMA_CTRL_DMAW_DLY_CNT_SHIFT; + + AT_WRITE_REG(hw, REG_DMA_CTRL, dma_ctrl_data); +} + +/* + * Stop the mac, transmit and receive units + * hw - Struct containing variables accessed by shared code + * return : 0 or idle status (if error) + */ +static int atl1c_stop_mac(struct atl1c_hw *hw) +{ + u32 data; + int timeout; + + AT_READ_REG(hw, REG_RXQ_CTRL, &data); + data &= ~(RXQ1_CTRL_EN | RXQ2_CTRL_EN | + RXQ3_CTRL_EN | RXQ_CTRL_EN); + AT_WRITE_REG(hw, REG_RXQ_CTRL, data); + + AT_READ_REG(hw, REG_TXQ_CTRL, &data); + data &= ~TXQ_CTRL_EN; + AT_WRITE_REG(hw, REG_TWSI_CTRL, data); + + for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) { + AT_READ_REG(hw, REG_IDLE_STATUS, &data); + if ((data & (IDLE_STATUS_RXQ_NO_IDLE | + IDLE_STATUS_TXQ_NO_IDLE)) == 0) + break; + msleep(1); + } + + AT_READ_REG(hw, REG_MAC_CTRL, &data); + data &= ~(MAC_CTRL_TX_EN | MAC_CTRL_RX_EN); + AT_WRITE_REG(hw, REG_MAC_CTRL, data); + + for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) { + AT_READ_REG(hw, REG_IDLE_STATUS, &data); + if ((data & IDLE_STATUS_MASK) == 0) + return 0; + msleep(1); + } + return data; +} + +static void atl1c_enable_rx_ctrl(struct atl1c_hw *hw) +{ + u32 data; + + AT_READ_REG(hw, REG_RXQ_CTRL, &data); + switch (hw->adapter->num_rx_queues) { + case 4: + data |= (RXQ3_CTRL_EN | RXQ2_CTRL_EN | RXQ1_CTRL_EN); + break; + case 3: + data |= (RXQ2_CTRL_EN | RXQ1_CTRL_EN); + break; + case 2: + data |= RXQ1_CTRL_EN; + break; + default: + break; + } + data |= RXQ_CTRL_EN; + AT_WRITE_REG(hw, REG_RXQ_CTRL, data); +} + +static void atl1c_enable_tx_ctrl(struct atl1c_hw *hw) +{ + u32 data; + + AT_READ_REG(hw, REG_TXQ_CTRL, &data); + data |= TXQ_CTRL_EN; + AT_WRITE_REG(hw, REG_TXQ_CTRL, data); +} + +/* + * Reset the transmit and receive units; mask and clear all interrupts. + * hw - Struct containing variables accessed by shared code + * return : 0 or idle status (if error) + */ +static int atl1c_reset_mac(struct atl1c_hw *hw) +{ + struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter; + struct pci_dev *pdev = adapter->pdev; + u32 idle_status_data = 0; + int timeout = 0; + int ret; + + AT_WRITE_REG(hw, REG_IMR, 0); + AT_WRITE_REG(hw, REG_ISR, ISR_DIS_INT); + + ret = atl1c_stop_mac(hw); + if (ret) + return ret; + /* + * Issue Soft Reset to the MAC. This will reset the chip's + * transmit, receive, DMA. It will not effect + * the current PCI configuration. The global reset bit is self- + * clearing, and should clear within a microsecond. + */ + AT_WRITE_REGW(hw, REG_MASTER_CTRL, MASTER_CTRL_SOFT_RST); + AT_WRITE_FLUSH(hw); + msleep(10); + /* Wait at least 10ms for All module to be Idle */ + for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) { + AT_READ_REG(hw, REG_IDLE_STATUS, &idle_status_data); + if ((idle_status_data & IDLE_STATUS_MASK) == 0) + break; + msleep(1); + } + if (timeout >= AT_HW_MAX_IDLE_DELAY) { + dev_err(&pdev->dev, + "MAC state machine cann't be idle since" + " disabled for 10ms second\n"); + return -1; + } + return 0; +} + +static void atl1c_disable_l0s_l1(struct atl1c_hw *hw) +{ + u32 pm_ctrl_data; + + AT_READ_REG(hw, REG_PM_CTRL, &pm_ctrl_data); + pm_ctrl_data &= ~(PM_CTRL_L1_ENTRY_TIMER_MASK << + PM_CTRL_L1_ENTRY_TIMER_SHIFT); + pm_ctrl_data &= ~PM_CTRL_CLK_SWH_L1; + pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN; + pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN; + pm_ctrl_data &= ~PM_CTRL_MAC_ASPM_CHK; + pm_ctrl_data &= ~PM_CTRL_SERDES_PD_EX_L1; + + pm_ctrl_data |= PM_CTRL_SERDES_BUDS_RX_L1_EN; + pm_ctrl_data |= PM_CTRL_SERDES_PLL_L1_EN; + pm_ctrl_data |= PM_CTRL_SERDES_L1_EN; + AT_WRITE_REG(hw, REG_PM_CTRL, pm_ctrl_data); +} + +/* + * Set ASPM state. + * Enable/disable L0s/L1 depend on link state. + */ +static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup) +{ + u32 pm_ctrl_data; + + AT_READ_REG(hw, REG_PM_CTRL, &pm_ctrl_data); + + pm_ctrl_data &= PM_CTRL_SERDES_PD_EX_L1; + pm_ctrl_data |= ~PM_CTRL_SERDES_BUDS_RX_L1_EN; + pm_ctrl_data |= ~PM_CTRL_SERDES_L1_EN; + pm_ctrl_data &= ~(PM_CTRL_L1_ENTRY_TIMER_MASK << + PM_CTRL_L1_ENTRY_TIMER_SHIFT); + + pm_ctrl_data |= PM_CTRL_MAC_ASPM_CHK; + + if (linkup) { + pm_ctrl_data |= PM_CTRL_SERDES_PLL_L1_EN; + pm_ctrl_data &= ~PM_CTRL_CLK_SWH_L1; + + if (hw->ctrl_flags & ATL1C_ASPM_L1_SUPPORT) { + pm_ctrl_data |= AT_ASPM_L1_TIMER << + PM_CTRL_L1_ENTRY_TIMER_SHIFT; + pm_ctrl_data |= PM_CTRL_ASPM_L1_EN; + } else + pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN; + + if (hw->ctrl_flags & ATL1C_ASPM_L0S_SUPPORT) + pm_ctrl_data |= PM_CTRL_ASPM_L0S_EN; + else + pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN; + + } else { + pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN; + pm_ctrl_data &= ~PM_CTRL_SERDES_PLL_L1_EN; + + pm_ctrl_data |= PM_CTRL_CLK_SWH_L1; + + if (hw->ctrl_flags & ATL1C_ASPM_L1_SUPPORT) + pm_ctrl_data |= PM_CTRL_ASPM_L1_EN; + else + pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN; + } + + AT_WRITE_REG(hw, REG_PM_CTRL, pm_ctrl_data); +} + +static void atl1c_setup_mac_ctrl(struct atl1c_adapter *adapter) +{ + struct atl1c_hw *hw = &adapter->hw; + struct net_device *netdev = adapter->netdev; + u32 mac_ctrl_data; + + mac_ctrl_data = MAC_CTRL_TX_EN | MAC_CTRL_RX_EN; + mac_ctrl_data |= (MAC_CTRL_TX_FLOW | MAC_CTRL_RX_FLOW); + + if (adapter->link_duplex == FULL_DUPLEX) { + hw->mac_duplex = true; + mac_ctrl_data |= MAC_CTRL_DUPLX; + } + + if (adapter->link_speed == SPEED_1000) + hw->mac_speed = atl1c_mac_speed_1000; + else + hw->mac_speed = atl1c_mac_speed_10_100; + + mac_ctrl_data |= (hw->mac_speed & MAC_CTRL_SPEED_MASK) << + MAC_CTRL_SPEED_SHIFT; + + mac_ctrl_data |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD); + mac_ctrl_data |= ((hw->preamble_len & MAC_CTRL_PRMLEN_MASK) << + MAC_CTRL_PRMLEN_SHIFT); + + if (adapter->vlgrp) + mac_ctrl_data |= MAC_CTRL_RMV_VLAN; + + mac_ctrl_data |= MAC_CTRL_BC_EN; + if (netdev->flags & IFF_PROMISC) + mac_ctrl_data |= MAC_CTRL_PROMIS_EN; + if (netdev->flags & IFF_ALLMULTI) + mac_ctrl_data |= MAC_CTRL_MC_ALL_EN; + + mac_ctrl_data |= MAC_CTRL_SINGLE_PAUSE_EN; + AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data); +} + +/* + * atl1c_configure - Configure Transmit&Receive Unit after Reset + * @adapter: board private structure + * + * Configure the Tx /Rx unit of the MAC after a reset. + */ +static int atl1c_configure(struct atl1c_adapter *adapter) +{ + struct atl1c_hw *hw = &adapter->hw; + u32 master_ctrl_data = 0; + u32 intr_modrt_data; + + /* clear interrupt status */ + AT_WRITE_REG(hw, REG_ISR, 0xFFFFFFFF); + /* Clear any WOL status */ + AT_WRITE_REG(hw, REG_WOL_CTRL, 0); + /* set Interrupt Clear Timer + * HW will enable self to assert interrupt event to system after + * waiting x-time for software to notify it accept interrupt. + */ + AT_WRITE_REG(hw, REG_INT_RETRIG_TIMER, + hw->ict & INT_RETRIG_TIMER_MASK); + + atl1c_configure_des_ring(adapter); + + if (hw->ctrl_flags & ATL1C_INTR_MODRT_ENABLE) { + intr_modrt_data = (hw->tx_imt & IRQ_MODRT_TIMER_MASK) << + IRQ_MODRT_TX_TIMER_SHIFT; + intr_modrt_data |= (hw->rx_imt & IRQ_MODRT_TIMER_MASK) << + IRQ_MODRT_RX_TIMER_SHIFT; + AT_WRITE_REG(hw, REG_IRQ_MODRT_TIMER_INIT, intr_modrt_data); + master_ctrl_data |= + MASTER_CTRL_TX_ITIMER_EN | MASTER_CTRL_RX_ITIMER_EN; + } + + if (hw->ctrl_flags & ATL1C_INTR_CLEAR_ON_READ) + master_ctrl_data |= MASTER_CTRL_INT_RDCLR; + + AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl_data); + + if (hw->ctrl_flags & ATL1C_CMB_ENABLE) { + AT_WRITE_REG(hw, REG_CMB_TPD_THRESH, + hw->cmb_tpd & CMB_TPD_THRESH_MASK); + AT_WRITE_REG(hw, REG_CMB_TX_TIMER, + hw->cmb_tx_timer & CMB_TX_TIMER_MASK); + } + + if (hw->ctrl_flags & ATL1C_SMB_ENABLE) + AT_WRITE_REG(hw, REG_SMB_STAT_TIMER, + hw->smb_timer & SMB_STAT_TIMER_MASK); + /* set MTU */ + AT_WRITE_REG(hw, REG_MTU, hw->max_frame_size + ETH_HLEN + + VLAN_HLEN + ETH_FCS_LEN); + /* HDS, disable */ + AT_WRITE_REG(hw, REG_HDS_CTRL, 0); + + atl1c_configure_tx(adapter); + atl1c_configure_rx(adapter); + atl1c_configure_rss(adapter); + atl1c_configure_dma(adapter); + + return 0; +} + +static void atl1c_update_hw_stats(struct atl1c_adapter *adapter) +{ + u16 hw_reg_addr = 0; + unsigned long *stats_item = NULL; + u32 data; + + /* update rx status */ + hw_reg_addr = REG_MAC_RX_STATUS_BIN; + stats_item = &adapter->hw_stats.rx_ok; + while (hw_reg_addr <= REG_MAC_RX_STATUS_END) { + AT_READ_REG(&adapter->hw, hw_reg_addr, &data); + *stats_item += data; + stats_item++; + hw_reg_addr += 4; + } +/* update tx status */ + hw_reg_addr = REG_MAC_TX_STATUS_BIN; + stats_item = &adapter->hw_stats.tx_ok; + while (hw_reg_addr <= REG_MAC_TX_STATUS_END) { + AT_READ_REG(&adapter->hw, hw_reg_addr, &data); + *stats_item += data; + stats_item++; + hw_reg_addr += 4; + } +} + +/* + * atl1c_get_stats - Get System Network Statistics + * @netdev: network interface device structure + * + * Returns the address of the device statistics structure. + * The statistics are actually updated from the timer callback. + */ +static struct net_device_stats *atl1c_get_stats(struct net_device *netdev) +{ + struct atl1c_adapter *adapter = netdev_priv(netdev); + struct atl1c_hw_stats *hw_stats = &adapter->hw_stats; + struct net_device_stats *net_stats = &adapter->net_stats; + + atl1c_update_hw_stats(adapter); + net_stats->rx_packets = hw_stats->rx_ok; + net_stats->tx_packets = hw_stats->tx_ok; + net_stats->rx_bytes = hw_stats->rx_byte_cnt; + net_stats->tx_bytes = hw_stats->tx_byte_cnt; + net_stats->multicast = hw_stats->rx_mcast; + net_stats->collisions = hw_stats->tx_1_col + + hw_stats->tx_2_col * 2 + + hw_stats->tx_late_col + hw_stats->tx_abort_col; + net_stats->rx_errors = hw_stats->rx_frag + hw_stats->rx_fcs_err + + hw_stats->rx_len_err + hw_stats->rx_sz_ov + + hw_stats->rx_rrd_ov + hw_stats->rx_align_err; + net_stats->rx_fifo_errors = hw_stats->rx_rxf_ov; + net_stats->rx_length_errors = hw_stats->rx_len_err; + net_stats->rx_crc_errors = hw_stats->rx_fcs_err; + net_stats->rx_frame_errors = hw_stats->rx_align_err; + net_stats->rx_over_errors = hw_stats->rx_rrd_ov + hw_stats->rx_rxf_ov; + + net_stats->rx_missed_errors = hw_stats->rx_rrd_ov + hw_stats->rx_rxf_ov; + + net_stats->tx_errors = hw_stats->tx_late_col + hw_stats->tx_abort_col + + hw_stats->tx_underrun + hw_stats->tx_trunc; + net_stats->tx_fifo_errors = hw_stats->tx_underrun; + net_stats->tx_aborted_errors = hw_stats->tx_abort_col; + net_stats->tx_window_errors = hw_stats->tx_late_col; + + return &adapter->net_stats; +} + +static inline void atl1c_clear_phy_int(struct atl1c_adapter *adapter) +{ + u16 phy_data; + + spin_lock(&adapter->mdio_lock); + atl1c_read_phy_reg(&adapter->hw, MII_ISR, &phy_data); + spin_unlock(&adapter->mdio_lock); +} + +static bool atl1c_clean_tx_irq(struct atl1c_adapter *adapter, + enum atl1c_trans_queue type) +{ + struct atl1c_tpd_ring *tpd_ring = (struct atl1c_tpd_ring *) + &adapter->tpd_ring[type]; + struct atl1c_buffer *buffer_info; + u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean); + u16 hw_next_to_clean; + u16 shift; + u32 data; + + if (type == atl1c_trans_high) + shift = MB_HTPD_CONS_IDX_SHIFT; + else + shift = MB_NTPD_CONS_IDX_SHIFT; + + AT_READ_REG(&adapter->hw, REG_MB_PRIO_CONS_IDX, &data); + hw_next_to_clean = (data >> shift) & MB_PRIO_PROD_IDX_MASK; + + while (next_to_clean != hw_next_to_clean) { + buffer_info = &tpd_ring->buffer_info[next_to_clean]; + if (buffer_info->state == ATL1_BUFFER_BUSY) { + pci_unmap_page(adapter->pdev, buffer_info->dma, + buffer_info->length, PCI_DMA_TODEVICE); + buffer_info->dma = 0; + if (buffer_info->skb) { + dev_kfree_skb_irq(buffer_info->skb); + buffer_info->skb = NULL; + } + buffer_info->state = ATL1_BUFFER_FREE; + } + if (++next_to_clean == tpd_ring->count) + next_to_clean = 0; + atomic_set(&tpd_ring->next_to_clean, next_to_clean); + } + + if (netif_queue_stopped(adapter->netdev) && + netif_carrier_ok(adapter->netdev)) { + netif_wake_queue(adapter->netdev); + } + + return true; +} + +/* + * atl1c_intr - Interrupt Handler + * @irq: interrupt number + * @data: pointer to a network interface device structure + * @pt_regs: CPU registers structure + */ +static irqreturn_t atl1c_intr(int irq, void *data) +{ + struct net_device *netdev = data; + struct atl1c_adapter *adapter = netdev_priv(netdev); + struct pci_dev *pdev = adapter->pdev; + struct atl1c_hw *hw = &adapter->hw; + int max_ints = AT_MAX_INT_WORK; + int handled = IRQ_NONE; + u32 status; + u32 reg_data; + + do { + AT_READ_REG(hw, REG_ISR, ®_data); + status = reg_data & hw->intr_mask; + + if (status == 0 || (status & ISR_DIS_INT) != 0) { + if (max_ints != AT_MAX_INT_WORK) + handled = IRQ_HANDLED; + break; + } + /* link event */ + if (status & ISR_GPHY) + atl1c_clear_phy_int(adapter); + /* Ack ISR */ + AT_WRITE_REG(hw, REG_ISR, status | ISR_DIS_INT); + if (status & ISR_RX_PKT) { + if (likely(napi_schedule_prep(&adapter->napi))) { + hw->intr_mask &= ~ISR_RX_PKT; + AT_WRITE_REG(hw, REG_IMR, hw->intr_mask); + __napi_schedule(&adapter->napi); + } + } + if (status & ISR_TX_PKT) + atl1c_clean_tx_irq(adapter, atl1c_trans_normal); + + handled = IRQ_HANDLED; + /* check if PCIE PHY Link down */ + if (status & ISR_ERROR) { + if (netif_msg_hw(adapter)) + dev_err(&pdev->dev, + "atl1c hardware error (status = 0x%x)\n", + status & ISR_ERROR); + /* reset MAC */ + hw->intr_mask &= ~ISR_ERROR; + AT_WRITE_REG(hw, REG_IMR, hw->intr_mask); + schedule_work(&adapter->reset_task); + break; + } + + if (status & ISR_OVER) + if (netif_msg_intr(adapter)) + dev_warn(&pdev->dev, + "TX/RX over flow (status = 0x%x)\n", + status & ISR_OVER); + + /* link event */ + if (status & (ISR_GPHY | ISR_MANUAL)) { + adapter->net_stats.tx_carrier_errors++; + atl1c_link_chg_event(adapter); + break; + } + + } while (--max_ints > 0); + /* re-enable Interrupt*/ + AT_WRITE_REG(&adapter->hw, REG_ISR, 0); + return handled; +} + +static inline void atl1c_rx_checksum(struct atl1c_adapter *adapter, + struct sk_buff *skb, struct atl1c_recv_ret_status *prrs) +{ + /* + * The pid field in RRS in not correct sometimes, so we + * cannot figure out if the packet is fragmented or not, + * so we tell the KERNEL CHECKSUM_NONE + */ + skb->ip_summed = CHECKSUM_NONE; +} + +static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, const int ringid) +{ + struct atl1c_rfd_ring *rfd_ring = &adapter->rfd_ring[ringid]; + struct pci_dev *pdev = adapter->pdev; + struct atl1c_buffer *buffer_info, *next_info; + struct sk_buff *skb; + void *vir_addr = NULL; + u16 num_alloc = 0; + u16 rfd_next_to_use, next_next; + struct atl1c_rx_free_desc *rfd_desc; + + next_next = rfd_next_to_use = rfd_ring->next_to_use; + if (++next_next == rfd_ring->count) + next_next = 0; + buffer_info = &rfd_ring->buffer_info[rfd_next_to_use]; + next_info = &rfd_ring->buffer_info[next_next]; + + while (next_info->state == ATL1_BUFFER_FREE) { + rfd_desc = ATL1C_RFD_DESC(rfd_ring, rfd_next_to_use); + + skb = dev_alloc_skb(adapter->rx_buffer_len); + if (unlikely(!skb)) { + if (netif_msg_rx_err(adapter)) + dev_warn(&pdev->dev, "alloc rx buffer failed\n"); + break; + } + + /* + * Make buffer alignment 2 beyond a 16 byte boundary + * this will result in a 16 byte aligned IP header after + * the 14 byte MAC header is removed + */ + vir_addr = skb->data; + buffer_info->state = ATL1_BUFFER_BUSY; + buffer_info->skb = skb; + buffer_info->length = adapter->rx_buffer_len; + buffer_info->dma = pci_map_single(pdev, vir_addr, + buffer_info->length, + PCI_DMA_FROMDEVICE); + rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma); + rfd_next_to_use = next_next; + if (++next_next == rfd_ring->count) + next_next = 0; + buffer_info = &rfd_ring->buffer_info[rfd_next_to_use]; + next_info = &rfd_ring->buffer_info[next_next]; + num_alloc++; + } + + if (num_alloc) { + /* TODO: update mailbox here */ + wmb(); + rfd_ring->next_to_use = rfd_next_to_use; + AT_WRITE_REG(&adapter->hw, atl1c_rfd_prod_idx_regs[ringid], + rfd_ring->next_to_use & MB_RFDX_PROD_IDX_MASK); + } + + return num_alloc; +} + +static void atl1c_clean_rrd(struct atl1c_rrd_ring *rrd_ring, + struct atl1c_recv_ret_status *rrs, u16 num) +{ + u16 i; + /* the relationship between rrd and rfd is one map one */ + for (i = 0; i < num; i++, rrs = ATL1C_RRD_DESC(rrd_ring, + rrd_ring->next_to_clean)) { + rrs->word3 &= ~RRS_RXD_UPDATED; + if (++rrd_ring->next_to_clean == rrd_ring->count) + rrd_ring->next_to_clean = 0; + } +} + +static void atl1c_clean_rfd(struct atl1c_rfd_ring *rfd_ring, + struct atl1c_recv_ret_status *rrs, u16 num) +{ + u16 i; + u16 rfd_index; + struct atl1c_buffer *buffer_info = rfd_ring->buffer_info; + + rfd_index = (rrs->word0 >> RRS_RX_RFD_INDEX_SHIFT) & + RRS_RX_RFD_INDEX_MASK; + for (i = 0; i < num; i++) { + buffer_info[rfd_index].skb = NULL; + buffer_info[rfd_index].state = ATL1_BUFFER_FREE; + if (++rfd_index == rfd_ring->count) + rfd_index = 0; + } + rfd_ring->next_to_clean = rfd_index; +} + +static void atl1c_clean_rx_irq(struct atl1c_adapter *adapter, u8 que, + int *work_done, int work_to_do) +{ + u16 rfd_num, rfd_index; + u16 count = 0; + u16 length; + struct pci_dev *pdev = adapter->pdev; + struct net_device *netdev = adapter->netdev; + struct atl1c_rfd_ring *rfd_ring = &adapter->rfd_ring[que]; + struct atl1c_rrd_ring *rrd_ring = &adapter->rrd_ring[que]; + struct sk_buff *skb; + struct atl1c_recv_ret_status *rrs; + struct atl1c_buffer *buffer_info; + + while (1) { + if (*work_done >= work_to_do) + break; + rrs = ATL1C_RRD_DESC(rrd_ring, rrd_ring->next_to_clean); + if (likely(RRS_RXD_IS_VALID(rrs->word3))) { + rfd_num = (rrs->word0 >> RRS_RX_RFD_CNT_SHIFT) & + RRS_RX_RFD_CNT_MASK; + if (unlikely(rfd_num) != 1) + /* TODO support mul rfd*/ + if (netif_msg_rx_err(adapter)) + dev_warn(&pdev->dev, + "Multi rfd not support yet!\n"); + goto rrs_checked; + } else { + break; + } +rrs_checked: + atl1c_clean_rrd(rrd_ring, rrs, rfd_num); + if (rrs->word3 & (RRS_RX_ERR_SUM | RRS_802_3_LEN_ERR)) { + atl1c_clean_rfd(rfd_ring, rrs, rfd_num); + if (netif_msg_rx_err(adapter)) + dev_warn(&pdev->dev, + "wrong packet! rrs word3 is %x\n", + rrs->word3); + continue; + } + + length = le16_to_cpu((rrs->word3 >> RRS_PKT_SIZE_SHIFT) & + RRS_PKT_SIZE_MASK); + /* Good Receive */ + if (likely(rfd_num == 1)) { + rfd_index = (rrs->word0 >> RRS_RX_RFD_INDEX_SHIFT) & + RRS_RX_RFD_INDEX_MASK; + buffer_info = &rfd_ring->buffer_info[rfd_index]; + pci_unmap_single(pdev, buffer_info->dma, + buffer_info->length, PCI_DMA_FROMDEVICE); + skb = buffer_info->skb; + } else { + /* TODO */ + if (netif_msg_rx_err(adapter)) + dev_warn(&pdev->dev, + "Multi rfd not support yet!\n"); + break; + } + atl1c_clean_rfd(rfd_ring, rrs, rfd_num); + skb_put(skb, length - ETH_FCS_LEN); + skb->protocol = eth_type_trans(skb, netdev); + skb->dev = netdev; + atl1c_rx_checksum(adapter, skb, rrs); + if (unlikely(adapter->vlgrp) && rrs->word3 & RRS_VLAN_INS) { + u16 vlan; + + AT_TAG_TO_VLAN(rrs->vlan_tag, vlan); + vlan = le16_to_cpu(vlan); + vlan_hwaccel_receive_skb(skb, adapter->vlgrp, vlan); + } else + netif_receive_skb(skb); + + netdev->last_rx = jiffies; + (*work_done)++; + count++; + } + if (count) + atl1c_alloc_rx_buffer(adapter, que); +} + +/* + * atl1c_clean - NAPI Rx polling callback + * @adapter: board private structure + */ +static int atl1c_clean(struct napi_struct *napi, int budget) +{ + struct atl1c_adapter *adapter = + container_of(napi, struct atl1c_adapter, napi); + int work_done = 0; + + /* Keep link state information with original netdev */ + if (!netif_carrier_ok(adapter->netdev)) + goto quit_polling; + /* just enable one RXQ */ + atl1c_clean_rx_irq(adapter, 0, &work_done, budget); + + if (work_done < budget) { +quit_polling: + napi_complete(napi); + adapter->hw.intr_mask |= ISR_RX_PKT; + AT_WRITE_REG(&adapter->hw, REG_IMR, adapter->hw.intr_mask); + } + return work_done; +} + +#ifdef CONFIG_NET_POLL_CONTROLLER + +/* + * Polling 'interrupt' - used by things like netconsole to send skbs + * without having to re-enable interrupts. It's not called while + * the interrupt routine is executing. + */ +static void atl1c_netpoll(struct net_device *netdev) +{ + struct atl1c_adapter *adapter = netdev_priv(netdev); + + disable_irq(adapter->pdev->irq); + atl1c_intr(adapter->pdev->irq, netdev); + enable_irq(adapter->pdev->irq); +} +#endif + +static inline u16 atl1c_tpd_avail(struct atl1c_adapter *adapter, enum atl1c_trans_queue type) +{ + struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type]; + u16 next_to_use = 0; + u16 next_to_clean = 0; + + next_to_clean = atomic_read(&tpd_ring->next_to_clean); + next_to_use = tpd_ring->next_to_use; + + return (u16)(next_to_clean > next_to_use) ? + (next_to_clean - next_to_use - 1) : + (tpd_ring->count + next_to_clean - next_to_use - 1); +} + +/* + * get next usable tpd + * Note: should call atl1c_tdp_avail to make sure + * there is enough tpd to use + */ +static struct atl1c_tpd_desc *atl1c_get_tpd(struct atl1c_adapter *adapter, + enum atl1c_trans_queue type) +{ + struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type]; + struct atl1c_tpd_desc *tpd_desc; + u16 next_to_use = 0; + + next_to_use = tpd_ring->next_to_use; + if (++tpd_ring->next_to_use == tpd_ring->count) + tpd_ring->next_to_use = 0; + tpd_desc = ATL1C_TPD_DESC(tpd_ring, next_to_use); + memset(tpd_desc, 0, sizeof(struct atl1c_tpd_desc)); + return tpd_desc; +} + +static struct atl1c_buffer * +atl1c_get_tx_buffer(struct atl1c_adapter *adapter, struct atl1c_tpd_desc *tpd) +{ + struct atl1c_tpd_ring *tpd_ring = adapter->tpd_ring; + + return &tpd_ring->buffer_info[tpd - + (struct atl1c_tpd_desc *)tpd_ring->desc]; +} + +/* Calculate the transmit packet descript needed*/ +static u16 atl1c_cal_tpd_req(const struct sk_buff *skb) +{ + u16 tpd_req; + u16 proto_hdr_len = 0; + + tpd_req = skb_shinfo(skb)->nr_frags + 1; + + if (skb_is_gso(skb)) { + proto_hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); + if (proto_hdr_len < skb_headlen(skb)) + tpd_req++; + if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) + tpd_req++; + } + return tpd_req; +} + +static int atl1c_tso_csum(struct atl1c_adapter *adapter, + struct sk_buff *skb, + struct atl1c_tpd_desc **tpd, + enum atl1c_trans_queue type) +{ + struct pci_dev *pdev = adapter->pdev; + u8 hdr_len; + u32 real_len; + unsigned short offload_type; + int err; + + if (skb_is_gso(skb)) { + if (skb_header_cloned(skb)) { + err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); + if (unlikely(err)) + return -1; + } + offload_type = skb_shinfo(skb)->gso_type; + + if (offload_type & SKB_GSO_TCPV4) { + real_len = (((unsigned char *)ip_hdr(skb) - skb->data) + + ntohs(ip_hdr(skb)->tot_len)); + + if (real_len < skb->len) + pskb_trim(skb, real_len); + + hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb)); + if (unlikely(skb->len == hdr_len)) { + /* only xsum need */ + if (netif_msg_tx_queued(adapter)) + dev_warn(&pdev->dev, + "IPV4 tso with zero data??\n"); + goto check_sum; + } else { + ip_hdr(skb)->check = 0; + tcp_hdr(skb)->check = ~csum_tcpudp_magic( + ip_hdr(skb)->saddr, + ip_hdr(skb)->daddr, + 0, IPPROTO_TCP, 0); + (*tpd)->word1 |= 1 << TPD_IPV4_PACKET_SHIFT; + } + } + + if (offload_type & SKB_GSO_TCPV6) { + struct atl1c_tpd_ext_desc *etpd = + *(struct atl1c_tpd_ext_desc **)(tpd); + + memset(etpd, 0, sizeof(struct atl1c_tpd_ext_desc)); + *tpd = atl1c_get_tpd(adapter, type); + ipv6_hdr(skb)->payload_len = 0; + /* check payload == 0 byte ? */ + hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb)); + if (unlikely(skb->len == hdr_len)) { + /* only xsum need */ + if (netif_msg_tx_queued(adapter)) + dev_warn(&pdev->dev, + "IPV6 tso with zero data??\n"); + goto check_sum; + } else + tcp_hdr(skb)->check = ~csum_ipv6_magic( + &ipv6_hdr(skb)->saddr, + &ipv6_hdr(skb)->daddr, + 0, IPPROTO_TCP, 0); + etpd->word1 |= 1 << TPD_LSO_EN_SHIFT; + etpd->word1 |= 1 << TPD_LSO_VER_SHIFT; + etpd->pkt_len = cpu_to_le32(skb->len); + (*tpd)->word1 |= 1 << TPD_LSO_VER_SHIFT; + } + + (*tpd)->word1 |= 1 << TPD_LSO_EN_SHIFT; + (*tpd)->word1 |= (skb_transport_offset(skb) & TPD_TCPHDR_OFFSET_MASK) << + TPD_TCPHDR_OFFSET_SHIFT; + (*tpd)->word1 |= (skb_shinfo(skb)->gso_size & TPD_MSS_MASK) << + TPD_MSS_SHIFT; + return 0; + } + +check_sum: + if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) { + u8 css, cso; + cso = skb_transport_offset(skb); + + if (unlikely(cso & 0x1)) { + if (netif_msg_tx_err(adapter)) + dev_err(&adapter->pdev->dev, + "payload offset should not an event number\n"); + return -1; + } else { + css = cso + skb->csum_offset; + + (*tpd)->word1 |= ((cso >> 1) & TPD_PLOADOFFSET_MASK) << + TPD_PLOADOFFSET_SHIFT; + (*tpd)->word1 |= ((css >> 1) & TPD_CCSUM_OFFSET_MASK) << + TPD_CCSUM_OFFSET_SHIFT; + (*tpd)->word1 |= 1 << TPD_CCSUM_EN_SHIFT; + } + } + return 0; +} + +static void atl1c_tx_map(struct atl1c_adapter *adapter, + struct sk_buff *skb, struct atl1c_tpd_desc *tpd, + enum atl1c_trans_queue type) +{ + struct atl1c_tpd_desc *use_tpd = NULL; + struct atl1c_buffer *buffer_info = NULL; + u16 buf_len = skb_headlen(skb); + u16 map_len = 0; + u16 mapped_len = 0; + u16 hdr_len = 0; + u16 nr_frags; + u16 f; + int tso; + + nr_frags = skb_shinfo(skb)->nr_frags; + tso = (tpd->word1 >> TPD_LSO_EN_SHIFT) & TPD_LSO_EN_MASK; + if (tso) { + /* TSO */ + map_len = hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); + use_tpd = tpd; + + buffer_info = atl1c_get_tx_buffer(adapter, use_tpd); + buffer_info->length = map_len; + buffer_info->dma = pci_map_single(adapter->pdev, + skb->data, hdr_len, PCI_DMA_TODEVICE); + buffer_info->state = ATL1_BUFFER_BUSY; + mapped_len += map_len; + use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma); + use_tpd->buffer_len = cpu_to_le16(buffer_info->length); + } + + if (mapped_len < buf_len) { + /* mapped_len == 0, means we should use the first tpd, + which is given by caller */ + if (mapped_len == 0) + use_tpd = tpd; + else { + use_tpd = atl1c_get_tpd(adapter, type); + memcpy(use_tpd, tpd, sizeof(struct atl1c_tpd_desc)); + use_tpd = atl1c_get_tpd(adapter, type); + memcpy(use_tpd, tpd, sizeof(struct atl1c_tpd_desc)); + } + buffer_info = atl1c_get_tx_buffer(adapter, use_tpd); + buffer_info->length = buf_len - mapped_len; + buffer_info->dma = + pci_map_single(adapter->pdev, skb->data + mapped_len, + buffer_info->length, PCI_DMA_TODEVICE); + buffer_info->state = ATL1_BUFFER_BUSY; + + use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma); + use_tpd->buffer_len = cpu_to_le16(buffer_info->length); + } + + for (f = 0; f < nr_frags; f++) { + struct skb_frag_struct *frag; + + frag = &skb_shinfo(skb)->frags[f]; + + use_tpd = atl1c_get_tpd(adapter, type); + memcpy(use_tpd, tpd, sizeof(struct atl1c_tpd_desc)); + + buffer_info = atl1c_get_tx_buffer(adapter, use_tpd); + buffer_info->length = frag->size; + buffer_info->dma = + pci_map_page(adapter->pdev, frag->page, + frag->page_offset, + buffer_info->length, + PCI_DMA_TODEVICE); + buffer_info->state = ATL1_BUFFER_BUSY; + + use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma); + use_tpd->buffer_len = cpu_to_le16(buffer_info->length); + } + + /* The last tpd */ + use_tpd->word1 |= 1 << TPD_EOP_SHIFT; + /* The last buffer info contain the skb address, + so it will be free after unmap */ + buffer_info->skb = skb; +} + +static void atl1c_tx_queue(struct atl1c_adapter *adapter, struct sk_buff *skb, + struct atl1c_tpd_desc *tpd, enum atl1c_trans_queue type) +{ + struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type]; + u32 prod_data; + + AT_READ_REG(&adapter->hw, REG_MB_PRIO_PROD_IDX, &prod_data); + switch (type) { + case atl1c_trans_high: + prod_data &= 0xFFFF0000; + prod_data |= tpd_ring->next_to_use & 0xFFFF; + break; + case atl1c_trans_normal: + prod_data &= 0x0000FFFF; + prod_data |= (tpd_ring->next_to_use & 0xFFFF) << 16; + break; + default: + break; + } + wmb(); + AT_WRITE_REG(&adapter->hw, REG_MB_PRIO_PROD_IDX, prod_data); +} + +static int atl1c_xmit_frame(struct sk_buff *skb, struct net_device *netdev) +{ + struct atl1c_adapter *adapter = netdev_priv(netdev); + unsigned long flags; + u16 tpd_req = 1; + struct atl1c_tpd_desc *tpd; + enum atl1c_trans_queue type = atl1c_trans_normal; + + if (test_bit(__AT_DOWN, &adapter->flags)) { + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; + } + + tpd_req = atl1c_cal_tpd_req(skb); + if (!spin_trylock_irqsave(&adapter->tx_lock, flags)) { + if (netif_msg_pktdata(adapter)) + dev_info(&adapter->pdev->dev, "tx locked\n"); + return NETDEV_TX_LOCKED; + } + if (skb->mark == 0x01) + type = atl1c_trans_high; + else + type = atl1c_trans_normal; + + if (atl1c_tpd_avail(adapter, type) < tpd_req) { + /* no enough descriptor, just stop queue */ + netif_stop_queue(netdev); + spin_unlock_irqrestore(&adapter->tx_lock, flags); + return NETDEV_TX_BUSY; + } + + tpd = atl1c_get_tpd(adapter, type); + + /* do TSO and check sum */ + if (atl1c_tso_csum(adapter, skb, &tpd, type) != 0) { + spin_unlock_irqrestore(&adapter->tx_lock, flags); + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; + } + + if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) { + u16 vlan = vlan_tx_tag_get(skb); + __le16 tag; + + vlan = cpu_to_le16(vlan); + AT_VLAN_TO_TAG(vlan, tag); + tpd->word1 |= 1 << TPD_INS_VTAG_SHIFT; + tpd->vlan_tag = tag; + } + + if (skb_network_offset(skb) != ETH_HLEN) + tpd->word1 |= 1 << TPD_ETH_TYPE_SHIFT; /* Ethernet frame */ + + atl1c_tx_map(adapter, skb, tpd, type); + atl1c_tx_queue(adapter, skb, tpd, type); + + netdev->trans_start = jiffies; + spin_unlock_irqrestore(&adapter->tx_lock, flags); + return NETDEV_TX_OK; +} + +static void atl1c_free_irq(struct atl1c_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + + free_irq(adapter->pdev->irq, netdev); + + if (adapter->have_msi) + pci_disable_msi(adapter->pdev); +} + +static int atl1c_request_irq(struct atl1c_adapter *adapter) +{ + struct pci_dev *pdev = adapter->pdev; + struct net_device *netdev = adapter->netdev; + int flags = 0; + int err = 0; + + adapter->have_msi = true; + err = pci_enable_msi(adapter->pdev); + if (err) { + if (netif_msg_ifup(adapter)) + dev_err(&pdev->dev, + "Unable to allocate MSI interrupt Error: %d\n", + err); + adapter->have_msi = false; + } else + netdev->irq = pdev->irq; + + if (!adapter->have_msi) + flags |= IRQF_SHARED; + err = request_irq(adapter->pdev->irq, &atl1c_intr, flags, + netdev->name, netdev); + if (err) { + if (netif_msg_ifup(adapter)) + dev_err(&pdev->dev, + "Unable to allocate interrupt Error: %d\n", + err); + if (adapter->have_msi) + pci_disable_msi(adapter->pdev); + return err; + } + if (netif_msg_ifup(adapter)) + dev_dbg(&pdev->dev, "atl1c_request_irq OK\n"); + return err; +} + +int atl1c_up(struct atl1c_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + int num; + int err; + int i; + + netif_carrier_off(netdev); + atl1c_init_ring_ptrs(adapter); + atl1c_set_multi(netdev); + atl1c_restore_vlan(adapter); + + for (i = 0; i < adapter->num_rx_queues; i++) { + num = atl1c_alloc_rx_buffer(adapter, i); + if (unlikely(num == 0)) { + err = -ENOMEM; + goto err_alloc_rx; + } + } + + if (atl1c_configure(adapter)) { + err = -EIO; + goto err_up; + } + + err = atl1c_request_irq(adapter); + if (unlikely(err)) + goto err_up; + + clear_bit(__AT_DOWN, &adapter->flags); + napi_enable(&adapter->napi); + atl1c_irq_enable(adapter); + atl1c_check_link_status(adapter); + netif_start_queue(netdev); + return err; + +err_up: +err_alloc_rx: + atl1c_clean_rx_ring(adapter); + return err; +} + +void atl1c_down(struct atl1c_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + + atl1c_del_timer(adapter); + atl1c_cancel_work(adapter); + + /* signal that we're down so the interrupt handler does not + * reschedule our watchdog timer */ + set_bit(__AT_DOWN, &adapter->flags); + netif_carrier_off(netdev); + napi_disable(&adapter->napi); + atl1c_irq_disable(adapter); + atl1c_free_irq(adapter); + AT_WRITE_REG(&adapter->hw, REG_ISR, ISR_DIS_INT); + /* reset MAC to disable all RX/TX */ + atl1c_reset_mac(&adapter->hw); + msleep(1); + + adapter->link_speed = SPEED_0; + adapter->link_duplex = -1; + atl1c_clean_tx_ring(adapter, atl1c_trans_normal); + atl1c_clean_tx_ring(adapter, atl1c_trans_high); + atl1c_clean_rx_ring(adapter); +} + +/* + * atl1c_open - Called when a network interface is made active + * @netdev: network interface device structure + * + * Returns 0 on success, negative value on failure + * + * The open entry point is called when a network interface is made + * active by the system (IFF_UP). At this point all resources needed + * for transmit and receive operations are allocated, the interrupt + * handler is registered with the OS, the watchdog timer is started, + * and the stack is notified that the interface is ready. + */ +static int atl1c_open(struct net_device *netdev) +{ + struct atl1c_adapter *adapter = netdev_priv(netdev); + int err; + + /* disallow open during test */ + if (test_bit(__AT_TESTING, &adapter->flags)) + return -EBUSY; + + /* allocate rx/tx dma buffer & descriptors */ + err = atl1c_setup_ring_resources(adapter); + if (unlikely(err)) + return err; + + err = atl1c_up(adapter); + if (unlikely(err)) + goto err_up; + + if (adapter->hw.ctrl_flags & ATL1C_FPGA_VERSION) { + u32 phy_data; + + AT_READ_REG(&adapter->hw, REG_MDIO_CTRL, &phy_data); + phy_data |= MDIO_AP_EN; + AT_WRITE_REG(&adapter->hw, REG_MDIO_CTRL, phy_data); + } + return 0; + +err_up: + atl1c_free_irq(adapter); + atl1c_free_ring_resources(adapter); + atl1c_reset_mac(&adapter->hw); + return err; +} + +/* + * atl1c_close - Disables a network interface + * @netdev: network interface device structure + * + * Returns 0, this is not allowed to fail + * + * The close entry point is called when an interface is de-activated + * by the OS. The hardware is still under the drivers control, but + * needs to be disabled. A global MAC reset is issued to stop the + * hardware, and all transmit and receive resources are freed. + */ +static int atl1c_close(struct net_device *netdev) +{ + struct atl1c_adapter *adapter = netdev_priv(netdev); + + WARN_ON(test_bit(__AT_RESETTING, &adapter->flags)); + atl1c_down(adapter); + atl1c_free_ring_resources(adapter); + return 0; +} + +static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct atl1c_adapter *adapter = netdev_priv(netdev); + struct atl1c_hw *hw = &adapter->hw; + u32 ctrl; + u32 mac_ctrl_data; + u32 master_ctrl_data; + u32 wol_ctrl_data; + u16 mii_bmsr_data; + u16 save_autoneg_advertised; + u16 mii_intr_status_data; + u32 wufc = adapter->wol; + u32 i; + int retval = 0; + + if (netif_running(netdev)) { + WARN_ON(test_bit(__AT_RESETTING, &adapter->flags)); + atl1c_down(adapter); + } + netif_device_detach(netdev); + atl1c_disable_l0s_l1(hw); + retval = pci_save_state(pdev); + if (retval) + return retval; + if (wufc) { + AT_READ_REG(hw, REG_MASTER_CTRL, &master_ctrl_data); + master_ctrl_data &= ~MASTER_CTRL_CLK_SEL_DIS; + + /* get link status */ + atl1c_read_phy_reg(hw, MII_BMSR, (u16 *)&mii_bmsr_data); + atl1c_read_phy_reg(hw, MII_BMSR, (u16 *)&mii_bmsr_data); + save_autoneg_advertised = hw->autoneg_advertised; + hw->autoneg_advertised = ADVERTISED_10baseT_Half; + if (atl1c_restart_autoneg(hw) != 0) + if (netif_msg_link(adapter)) + dev_warn(&pdev->dev, "phy autoneg failed\n"); + hw->phy_configured = false; /* re-init PHY when resume */ + hw->autoneg_advertised = save_autoneg_advertised; + /* turn on magic packet wol */ + if (wufc & AT_WUFC_MAG) + wol_ctrl_data = WOL_MAGIC_EN | WOL_MAGIC_PME_EN; + + if (wufc & AT_WUFC_LNKC) { + for (i = 0; i < AT_SUSPEND_LINK_TIMEOUT; i++) { + msleep(100); + atl1c_read_phy_reg(hw, MII_BMSR, + (u16 *)&mii_bmsr_data); + if (mii_bmsr_data & BMSR_LSTATUS) + break; + } + if ((mii_bmsr_data & BMSR_LSTATUS) == 0) + if (netif_msg_link(adapter)) + dev_warn(&pdev->dev, + "%s: Link may change" + "when suspend\n", + atl1c_driver_name); + wol_ctrl_data |= WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN; + /* only link up can wake up */ + if (atl1c_write_phy_reg(hw, MII_IER, IER_LINK_UP) != 0) { + if (netif_msg_link(adapter)) + dev_err(&pdev->dev, + "%s: read write phy " + "register failed.\n", + atl1c_driver_name); + goto wol_dis; + } + } + /* clear phy interrupt */ + atl1c_read_phy_reg(hw, MII_ISR, &mii_intr_status_data); + /* Config MAC Ctrl register */ + mac_ctrl_data = MAC_CTRL_RX_EN; + /* set to 10/100M halt duplex */ + mac_ctrl_data |= atl1c_mac_speed_10_100 << MAC_CTRL_SPEED_SHIFT; + mac_ctrl_data |= (((u32)adapter->hw.preamble_len & + MAC_CTRL_PRMLEN_MASK) << + MAC_CTRL_PRMLEN_SHIFT); + + if (adapter->vlgrp) + mac_ctrl_data |= MAC_CTRL_RMV_VLAN; + + /* magic packet maybe Broadcast&multicast&Unicast frame */ + if (wufc & AT_WUFC_MAG) + mac_ctrl_data |= MAC_CTRL_BC_EN; + + if (netif_msg_hw(adapter)) + dev_dbg(&pdev->dev, + "%s: suspend MAC=0x%x\n", + atl1c_driver_name, mac_ctrl_data); + AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl_data); + AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl_data); + AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data); + + /* pcie patch */ + AT_READ_REG(hw, REG_PCIE_PHYMISC, &ctrl); + ctrl |= PCIE_PHYMISC_FORCE_RCV_DET; + AT_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl); + + pci_enable_wake(pdev, pci_choose_state(pdev, state), 1); + goto suspend_exit; + } +wol_dis: + + /* WOL disabled */ + AT_WRITE_REG(hw, REG_WOL_CTRL, 0); + + /* pcie patch */ + AT_READ_REG(hw, REG_PCIE_PHYMISC, &ctrl); + ctrl |= PCIE_PHYMISC_FORCE_RCV_DET; + AT_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl); + + atl1c_phy_disable(hw); + hw->phy_configured = false; /* re-init PHY when resume */ + + pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); +suspend_exit: + + pci_disable_device(pdev); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); + + return 0; +} + +static int atl1c_resume(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct atl1c_adapter *adapter = netdev_priv(netdev); + + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + pci_enable_wake(pdev, PCI_D3hot, 0); + pci_enable_wake(pdev, PCI_D3cold, 0); + + AT_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0); + + atl1c_phy_reset(&adapter->hw); + atl1c_reset_mac(&adapter->hw); + netif_device_attach(netdev); + if (netif_running(netdev)) + atl1c_up(adapter); + + return 0; +} + +static void atl1c_shutdown(struct pci_dev *pdev) +{ + atl1c_suspend(pdev, PMSG_SUSPEND); +} + +static const struct net_device_ops atl1c_netdev_ops = { + .ndo_open = atl1c_open, + .ndo_stop = atl1c_close, + .ndo_validate_addr = eth_validate_addr, + .ndo_start_xmit = atl1c_xmit_frame, + .ndo_set_mac_address = atl1c_set_mac_addr, + .ndo_set_multicast_list = atl1c_set_multi, + .ndo_change_mtu = atl1c_change_mtu, + .ndo_do_ioctl = atl1c_ioctl, + .ndo_tx_timeout = atl1c_tx_timeout, + .ndo_get_stats = atl1c_get_stats, + .ndo_vlan_rx_register = atl1c_vlan_rx_register, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = atl1c_netpoll, +#endif +}; + +static int atl1c_init_netdev(struct net_device *netdev, struct pci_dev *pdev) +{ + SET_NETDEV_DEV(netdev, &pdev->dev); + pci_set_drvdata(pdev, netdev); + + netdev->irq = pdev->irq; + netdev->netdev_ops = &atl1c_netdev_ops; + netdev->watchdog_timeo = AT_TX_WATCHDOG; + atl1c_set_ethtool_ops(netdev); + + /* TODO: add when ready */ + netdev->features = NETIF_F_SG | + NETIF_F_HW_CSUM | + NETIF_F_HW_VLAN_TX | + NETIF_F_HW_VLAN_RX | + NETIF_F_TSO | + NETIF_F_TSO6; + return 0; +} + +/* + * atl1c_probe - Device Initialization Routine + * @pdev: PCI device information struct + * @ent: entry in atl1c_pci_tbl + * + * Returns 0 on success, negative on failure + * + * atl1c_probe initializes an adapter identified by a pci_dev structure. + * The OS initialization, configuring of the adapter private structure, + * and a hardware reset occur. + */ +static int __devinit atl1c_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct net_device *netdev; + struct atl1c_adapter *adapter; + static int cards_found; + + int err = 0; + + /* enable device (incl. PCI PM wakeup and hotplug setup) */ + err = pci_enable_device_mem(pdev); + if (err) { + dev_err(&pdev->dev, "cannot enable PCI device\n"); + return err; + } + + /* + * The atl1c chip can DMA to 64-bit addresses, but it uses a single + * shared register for the high 32 bits, so only a single, aligned, + * 4 GB physical address range can be used at a time. + * + * Supporting 64-bit DMA on this hardware is more trouble than it's + * worth. It is far easier to limit to 32-bit DMA than update + * various kernel subsystems to support the mechanics required by a + * fixed-high-32-bit system. + */ + if ((pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) || + (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK) != 0)) { + dev_err(&pdev->dev, "No usable DMA configuration,aborting\n"); + goto err_dma; + } + + err = pci_request_regions(pdev, atl1c_driver_name); + if (err) { + dev_err(&pdev->dev, "cannot obtain PCI resources\n"); + goto err_pci_reg; + } + + pci_set_master(pdev); + + netdev = alloc_etherdev(sizeof(struct atl1c_adapter)); + if (netdev == NULL) { + err = -ENOMEM; + dev_err(&pdev->dev, "etherdev alloc failed\n"); + goto err_alloc_etherdev; + } + + err = atl1c_init_netdev(netdev, pdev); + if (err) { + dev_err(&pdev->dev, "init netdevice failed\n"); + goto err_init_netdev; + } + adapter = netdev_priv(netdev); + adapter->bd_number = cards_found; + adapter->netdev = netdev; + adapter->pdev = pdev; + adapter->hw.adapter = adapter; + adapter->msg_enable = netif_msg_init(-1, atl1c_default_msg); + adapter->hw.hw_addr = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); + if (!adapter->hw.hw_addr) { + err = -EIO; + dev_err(&pdev->dev, "cannot map device registers\n"); + goto err_ioremap; + } + netdev->base_addr = (unsigned long)adapter->hw.hw_addr; + + /* init mii data */ + adapter->mii.dev = netdev; + adapter->mii.mdio_read = atl1c_mdio_read; + adapter->mii.mdio_write = atl1c_mdio_write; + adapter->mii.phy_id_mask = 0x1f; + adapter->mii.reg_num_mask = MDIO_REG_ADDR_MASK; + netif_napi_add(netdev, &adapter->napi, atl1c_clean, 64); + setup_timer(&adapter->phy_config_timer, atl1c_phy_config, + (unsigned long)adapter); + /* setup the private structure */ + err = atl1c_sw_init(adapter); + if (err) { + dev_err(&pdev->dev, "net device private data init failed\n"); + goto err_sw_init; + } + atl1c_reset_pcie(&adapter->hw, ATL1C_PCIE_L0S_L1_DISABLE | + ATL1C_PCIE_PHY_RESET); + + /* Init GPHY as early as possible due to power saving issue */ + atl1c_phy_reset(&adapter->hw); + + err = atl1c_reset_mac(&adapter->hw); + if (err) { + err = -EIO; + goto err_reset; + } + + device_init_wakeup(&pdev->dev, 1); + /* reset the controller to + * put the device in a known good starting state */ + err = atl1c_phy_init(&adapter->hw); + if (err) { + err = -EIO; + goto err_reset; + } + if (atl1c_read_mac_addr(&adapter->hw) != 0) { + err = -EIO; + dev_err(&pdev->dev, "get mac address failed\n"); + goto err_eeprom; + } + memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len); + memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len); + if (netif_msg_probe(adapter)) + dev_dbg(&pdev->dev, + "mac address : %02x-%02x-%02x-%02x-%02x-%02x\n", + adapter->hw.mac_addr[0], adapter->hw.mac_addr[1], + adapter->hw.mac_addr[2], adapter->hw.mac_addr[3], + adapter->hw.mac_addr[4], adapter->hw.mac_addr[5]); + + atl1c_hw_set_mac_addr(&adapter->hw); + INIT_WORK(&adapter->reset_task, atl1c_reset_task); + INIT_WORK(&adapter->link_chg_task, atl1c_link_chg_task); + err = register_netdev(netdev); + if (err) { + dev_err(&pdev->dev, "register netdevice failed\n"); + goto err_register; + } + + if (netif_msg_probe(adapter)) + dev_info(&pdev->dev, "version %s\n", ATL1C_DRV_VERSION); + cards_found++; + return 0; + +err_reset: +err_register: +err_sw_init: +err_eeprom: + iounmap(adapter->hw.hw_addr); +err_init_netdev: +err_ioremap: + free_netdev(netdev); +err_alloc_etherdev: + pci_release_regions(pdev); +err_pci_reg: +err_dma: + pci_disable_device(pdev); + return err; +} + +/* + * atl1c_remove - Device Removal Routine + * @pdev: PCI device information struct + * + * atl1c_remove is called by the PCI subsystem to alert the driver + * that it should release a PCI device. The could be caused by a + * Hot-Plug event, or because the driver is going to be removed from + * memory. + */ +static void __devexit atl1c_remove(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct atl1c_adapter *adapter = netdev_priv(netdev); + + unregister_netdev(netdev); + atl1c_phy_disable(&adapter->hw); + + iounmap(adapter->hw.hw_addr); + + pci_release_regions(pdev); + pci_disable_device(pdev); + free_netdev(netdev); +} + +/* + * atl1c_io_error_detected - called when PCI error is detected + * @pdev: Pointer to PCI device + * @state: The current pci connection state + * + * This function is called after a PCI bus error affecting + * this device has been detected. + */ +static pci_ers_result_t atl1c_io_error_detected(struct pci_dev *pdev, + pci_channel_state_t state) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct atl1c_adapter *adapter = netdev_priv(netdev); + + netif_device_detach(netdev); + + if (netif_running(netdev)) + atl1c_down(adapter); + + pci_disable_device(pdev); + + /* Request a slot slot reset. */ + return PCI_ERS_RESULT_NEED_RESET; +} + +/* + * atl1c_io_slot_reset - called after the pci bus has been reset. + * @pdev: Pointer to PCI device + * + * Restart the card from scratch, as if from a cold-boot. Implementation + * resembles the first-half of the e1000_resume routine. + */ +static pci_ers_result_t atl1c_io_slot_reset(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct atl1c_adapter *adapter = netdev_priv(netdev); + + if (pci_enable_device(pdev)) { + if (netif_msg_hw(adapter)) + dev_err(&pdev->dev, + "Cannot re-enable PCI device after reset\n"); + return PCI_ERS_RESULT_DISCONNECT; + } + pci_set_master(pdev); + + pci_enable_wake(pdev, PCI_D3hot, 0); + pci_enable_wake(pdev, PCI_D3cold, 0); + + atl1c_reset_mac(&adapter->hw); + + return PCI_ERS_RESULT_RECOVERED; +} + +/* + * atl1c_io_resume - called when traffic can start flowing again. + * @pdev: Pointer to PCI device + * + * This callback is called when the error recovery driver tells us that + * its OK to resume normal operation. Implementation resembles the + * second-half of the atl1c_resume routine. + */ +static void atl1c_io_resume(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct atl1c_adapter *adapter = netdev_priv(netdev); + + if (netif_running(netdev)) { + if (atl1c_up(adapter)) { + if (netif_msg_hw(adapter)) + dev_err(&pdev->dev, + "Cannot bring device back up after reset\n"); + return; + } + } + + netif_device_attach(netdev); +} + +static struct pci_error_handlers atl1c_err_handler = { + .error_detected = atl1c_io_error_detected, + .slot_reset = atl1c_io_slot_reset, + .resume = atl1c_io_resume, +}; + +static struct pci_driver atl1c_driver = { + .name = atl1c_driver_name, + .id_table = atl1c_pci_tbl, + .probe = atl1c_probe, + .remove = __devexit_p(atl1c_remove), + /* Power Managment Hooks */ + .suspend = atl1c_suspend, + .resume = atl1c_resume, + .shutdown = atl1c_shutdown, + .err_handler = &atl1c_err_handler +}; + +/* + * atl1c_init_module - Driver Registration Routine + * + * atl1c_init_module is the first routine called when the driver is + * loaded. All it does is register with the PCI subsystem. + */ +static int __init atl1c_init_module(void) +{ + return pci_register_driver(&atl1c_driver); +} + +/* + * atl1c_exit_module - Driver Exit Cleanup Routine + * + * atl1c_exit_module is called just before the driver is removed + * from memory. + */ +static void __exit atl1c_exit_module(void) +{ + pci_unregister_driver(&atl1c_driver); +} + +module_init(atl1c_init_module); +module_exit(atl1c_exit_module); -- cgit From 82a5bd6a7b1b60b5d357e2e4b93b914f57314016 Mon Sep 17 00:00:00 2001 From: Sebastian Siewior Date: Sat, 14 Feb 2009 23:26:18 +0000 Subject: net/mv643xx: use GFP_ATOMIC while atomic dev_set_rx_mode() grabs netif_addr_lock_bh(): |BUG: sleeping function called from invalid context at /home/bigeasy/git/cryptodev-2.6/mm/slub.c:1599 |in_atomic(): 1, irqs_disabled(): 0, pid: 859, name: ifconfig |2 locks held by ifconfig/859: | #0: (rtnl_mutex){--..}, at: [] rtnl_lock+0x18/0x20 | #1: (_xmit_ETHER){-...}, at: [] dev_set_rx_mode+0x1c/0x30 |[] (dump_stack+0x0/0x14) from [] (__might_sleep+0x11c/0x13c) |[] (__might_sleep+0x0/0x13c) from [] (kmem_cache_alloc+0x30/0xd4) | r5:c78093a0 r4:c034a47c |[] (kmem_cache_alloc+0x0/0xd4) from [] (mv643xx_eth_set_rx_mode+0x70/0x188) |[] (mv643xx_eth_set_rx_mode+0x0/0x188) from [] (__dev_set_rx_mode+0x40/0xac) |[] (__dev_set_rx_mode+0x0/0xac) from [] (dev_set_rx_mode+0x24/0x30) | r6:00001043 r5:c78090f8 r4:c7809000 |[] (dev_set_rx_mode+0x0/0x30) from [] (dev_open+0xe4/0x114) | r5:c7809350 r4:c7809000 |[] (dev_open+0x0/0x114) from [] (dev_change_flags+0xb0/0x190) | r5:00000041 r4:c7809000 |[] (dev_change_flags+0x0/0x190) from [] (devinet_ioctl+0x2f0/0x710) | r7:c7221e70 r6:c7aadb00 r5:00000000 r4:00000001 |[] (devinet_ioctl+0x0/0x710) from [] (inet_ioctl+0xd4/0x110) |[] (inet_ioctl+0x0/0x110) from [] (sock_ioctl+0x1f4/0x254) | r4:c7242b40 |[] (sock_ioctl+0x0/0x254) from [] (vfs_ioctl+0x38/0x98) | r6:beec9bb8 r5:00008914 r4:c7242b40 |[] (vfs_ioctl+0x0/0x98) from [] (do_vfs_ioctl+0x484/0x4d4) | r6:00008914 r5:c7242b40 r4:c74db1c0 |[] (do_vfs_ioctl+0x0/0x4d4) from [] (sys_ioctl+0x40/0x64) |[] (sys_ioctl+0x0/0x64) from [] (ret_fast_syscall+0x0/0x2c) |[42949399.520000] r7:00000036 r6:beec9c80 r5:00000041 r4:beec9bb8 Signed-off-by: Sebastian Andrzej Siewior Acked-by: Lennert Buytenhek Signed-off-by: David S. Miller --- drivers/net/mv643xx_eth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 5f31bbb614a..b6ab46942b9 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -1575,7 +1575,7 @@ oom: return; } - mc_spec = kmalloc(0x200, GFP_KERNEL); + mc_spec = kmalloc(0x200, GFP_ATOMIC); if (mc_spec == NULL) goto oom; mc_other = mc_spec + (0x100 >> 2); -- cgit From 57e8f26a10ac4af488292199bb0435555f6723f3 Mon Sep 17 00:00:00 2001 From: Sebastian Siewior Date: Mon, 16 Feb 2009 11:28:15 +0000 Subject: net/mv643xx: don't disable the mib timer too early and lock properly mib_counters_update() also restarts the timer. So the timer is dequeued, the stats are read and then the timer is enqueued again. This is "okay" unless someone unloads the module. The locking here is also broken: mib_counters_update() grabs just a simple spinlock. The only thing the lock is good for is to protect the timer func against other callers namely mv643xx_eth_stop() && mv643xx_eth_get_ethtool_stats(). That means if the spinlock is taken via the ethtool path and than the timer kicks in then the box will lock up. Signed-off-by: Sebastian Andrzej Siewior Acked-by: Lennert Buytenhek Signed-off-by: David S. Miller --- drivers/net/mv643xx_eth.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index b6ab46942b9..13f11f402a9 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -1175,7 +1175,7 @@ static void mib_counters_update(struct mv643xx_eth_private *mp) { struct mib_counters *p = &mp->mib_counters; - spin_lock(&mp->mib_counters_lock); + spin_lock_bh(&mp->mib_counters_lock); p->good_octets_received += mib_read(mp, 0x00); p->good_octets_received += (u64)mib_read(mp, 0x04) << 32; p->bad_octets_received += mib_read(mp, 0x08); @@ -1208,7 +1208,7 @@ static void mib_counters_update(struct mv643xx_eth_private *mp) p->bad_crc_event += mib_read(mp, 0x74); p->collision += mib_read(mp, 0x78); p->late_collision += mib_read(mp, 0x7c); - spin_unlock(&mp->mib_counters_lock); + spin_unlock_bh(&mp->mib_counters_lock); mod_timer(&mp->mib_counters_timer, jiffies + 30 * HZ); } @@ -2216,8 +2216,6 @@ static int mv643xx_eth_stop(struct net_device *dev) wrlp(mp, INT_MASK, 0x00000000); rdlp(mp, INT_MASK); - del_timer_sync(&mp->mib_counters_timer); - napi_disable(&mp->napi); del_timer_sync(&mp->rx_oom); @@ -2229,6 +2227,7 @@ static int mv643xx_eth_stop(struct net_device *dev) port_reset(mp); mv643xx_eth_get_stats(dev); mib_counters_update(mp); + del_timer_sync(&mp->mib_counters_timer); skb_queue_purge(&mp->rx_recycle); -- cgit From 858671f80ae5db68d6bcd2c6d3a13e366040ba9b Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Wed, 18 Feb 2009 17:41:38 -0800 Subject: ATM: misplaced parentheses? Add missing parentheses Signed-off-by: Roel Kluin Signed-off-by: David S. Miller --- drivers/atm/lanai.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c index 144a49f1522..8733a2ea04c 100644 --- a/drivers/atm/lanai.c +++ b/drivers/atm/lanai.c @@ -901,7 +901,7 @@ static int __devinit eeprom_read(struct lanai_dev *lanai) clock_l(); udelay(5); for (i = 128; i != 0; i >>= 1) { /* write command out */ tmp = (lanai->conf1 & ~CONFIG1_PROMDATA) | - (data & i) ? CONFIG1_PROMDATA : 0; + ((data & i) ? CONFIG1_PROMDATA : 0); if (lanai->conf1 != tmp) { set_config1(tmp); udelay(5); /* Let new data settle */ -- cgit From f72b534961ac38dde17824d7693292eeaadf10e8 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Wed, 18 Feb 2009 17:42:42 -0800 Subject: TG3: &&/|| confusion phyid Can't be both TG3_PHY_OUI_1 and TG3_PHY_OUI_2 and TG3_PHY_OUI_3. Signed-off-by: Roel Kluin Acked-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 4595962fb8e..b080f9493d8 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -2237,8 +2237,8 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) phyid = phydev->drv->phy_id & phydev->drv->phy_id_mask; if (phyid != TG3_PHY_ID_BCMAC131) { phyid &= TG3_PHY_OUI_MASK; - if (phyid == TG3_PHY_OUI_1 && - phyid == TG3_PHY_OUI_2 && + if (phyid == TG3_PHY_OUI_1 || + phyid == TG3_PHY_OUI_2 || phyid == TG3_PHY_OUI_3) do_low_power = true; } -- cgit From 5209921cf15452cbe43097afce11d2846630cb51 Mon Sep 17 00:00:00 2001 From: Ilpo Järvinen Date: Wed, 18 Feb 2009 17:45:44 -0800 Subject: tcp: remove obsoleted comment about different passes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is obsolete since the passes got combined. Signed-off-by: Ilpo Järvinen Signed-off-by: David S. Miller --- net/ipv4/tcp_output.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index dda42f0bd7a..da2c3b8794f 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -2023,7 +2023,6 @@ void tcp_xmit_retransmit_queue(struct sock *sk) last_lost = tp->snd_una; } - /* First pass: retransmit lost packets. */ tcp_for_write_queue_from(skb, sk) { __u8 sacked = TCP_SKB_CB(skb)->sacked; -- cgit From ce03aaddd4d67371494b36c8e8a57bc789e934d6 Mon Sep 17 00:00:00 2001 From: Divy Le Ray Date: Wed, 18 Feb 2009 17:47:57 -0800 Subject: cxgb3: Add support for PCI ID 0x35. Add support for adapters with a PCI id equal to 0x35. Signed-off-by: Divy Le Ray Signed-off-by: David S. Miller --- drivers/net/cxgb3/cxgb3_main.c | 1 + drivers/net/cxgb3/t3_hw.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 0089746b8d0..bab8a934c33 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -90,6 +90,7 @@ static const struct pci_device_id cxgb3_pci_tbl[] = { CH_DEVICE(0x30, 2), /* T3B10 */ CH_DEVICE(0x31, 3), /* T3B20 */ CH_DEVICE(0x32, 1), /* T3B02 */ + CH_DEVICE(0x35, 6), /* T3C20-derived T3C10 */ {0,} }; diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index 2d1433077a8..ac2a974dfe3 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c @@ -512,6 +512,13 @@ static const struct adapter_info t3_adap_info[] = { F_GPIO5_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, { S_GPIO9, S_GPIO3 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI, &mi1_mdio_ext_ops, "Chelsio T320"}, + {}, + {}, + {1, 0, + F_GPIO1_OEN | F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO6_OEN | F_GPIO7_OEN | + F_GPIO10_OEN | F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, + { S_GPIO9 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI, + &mi1_mdio_ext_ops, "Chelsio T310" }, }; /* -- cgit From 0c5119c1e655e0719a69601b1049acdd5ec1c125 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 18 Feb 2009 18:33:57 -0500 Subject: tracing: disable tracing while testing ring buffer Impact: fix to prevent hard lockup on self tests If one of the tracers are broken and is constantly filling the ring buffer while the test of the ring buffer is running, it will hang the box. The reason is that the test is a consumer that will not stop till the ring buffer is empty. But if the tracer is broken and is constantly producing input to the buffer, this test will never end. The result is a lockup of the box. This happened when KALLSYMS was not defined and the dynamic ftrace test constantly filled the ring buffer, because the filter failed and all functions were being traced. Something was being called that constantly filled the buffer. Signed-off-by: Steven Rostedt --- kernel/trace/trace_selftest.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 88c8eb70f54..a7e0ef662f9 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -57,11 +57,20 @@ static int trace_test_buffer(struct trace_array *tr, unsigned long *count) cnt = ring_buffer_entries(tr->buffer); + /* + * The trace_test_buffer_cpu runs a while loop to consume all data. + * If the calling tracer is broken, and is constantly filling + * the buffer, this will run forever, and hard lock the box. + * We disable the ring buffer while we do this test to prevent + * a hard lock up. + */ + tracing_off(); for_each_possible_cpu(cpu) { ret = trace_test_buffer_cpu(tr, cpu); if (ret) break; } + tracing_on(); __raw_spin_unlock(&ftrace_max_lock); local_irq_restore(flags); -- cgit From 4d7a077c0c7bfdba04cf0aa0b79053cf4ebaacf8 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 18 Feb 2009 22:06:18 -0500 Subject: tracing: have function trace select kallsyms Impact: fix output of function tracer to be useful The function tracer is pretty useless if KALLSYMS is not configured. Unless you are good at reading hex values, the function tracer should select the KALLSYMS configuration. Also, the dynamic function tracer will fail its self test if KALLSYMS is not selected. Signed-off-by: Steven Rostedt --- kernel/trace/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 58a93fbd68a..34e707e5ab8 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -52,6 +52,7 @@ config FUNCTION_TRACER depends on HAVE_FUNCTION_TRACER depends on DEBUG_KERNEL select FRAME_POINTER + select KALLSYMS select TRACING select CONTEXT_SWITCH_TRACER help @@ -238,6 +239,7 @@ config STACK_TRACER depends on DEBUG_KERNEL select FUNCTION_TRACER select STACKTRACE + select KALLSYMS help This special tracer records the maximum stack footprint of the kernel and displays it in debugfs/tracing/stack_trace. -- cgit From 4b3e3d228429c75d398f1aa24532e468d3220c49 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 18 Feb 2009 22:50:01 -0500 Subject: tracing: limit the number of loops the ring buffer self test can make Impact: prevent deadlock if ring buffer gets corrupted This patch adds a paranoid check to make sure the ring buffer consumer does not go into an infinite loop. Since the ring buffer has been set to read only, the consumer should not loop for more than the ring buffer size. A check is added to make sure the consumer does not loop more than the ring buffer size. Signed-off-by: Steven Rostedt --- kernel/trace/trace_selftest.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index a7e0ef662f9..bc8e80a86bc 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -23,10 +23,20 @@ static int trace_test_buffer_cpu(struct trace_array *tr, int cpu) { struct ring_buffer_event *event; struct trace_entry *entry; + unsigned int loops = 0; while ((event = ring_buffer_consume(tr->buffer, cpu, NULL))) { entry = ring_buffer_event_data(event); + /* + * The ring buffer is a size of trace_buf_size, if + * we loop more than the size, there's something wrong + * with the ring buffer. + */ + if (loops++ > trace_buf_size) { + printk(KERN_CONT ".. bad ring buffer "); + goto failed; + } if (!trace_valid_entry(entry)) { printk(KERN_CONT ".. invalid entry %d ", entry->type); -- cgit From bb402f16ecf9bcdb944b8fa730f0e43cae519673 Mon Sep 17 00:00:00 2001 From: Lee Nipper Date: Thu, 19 Feb 2009 14:46:26 +0800 Subject: crypto: ahash - Fix digest size in /proc/crypto crypto_ahash_show changed to use cra_ahash for digestsize reference. Signed-off-by: Lee Nipper Signed-off-by: Herbert Xu --- crypto/ahash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/ahash.c b/crypto/ahash.c index ba5292d69eb..b2d1ee32cfe 100644 --- a/crypto/ahash.c +++ b/crypto/ahash.c @@ -214,7 +214,7 @@ static void crypto_ahash_show(struct seq_file *m, struct crypto_alg *alg) seq_printf(m, "async : %s\n", alg->cra_flags & CRYPTO_ALG_ASYNC ? "yes" : "no"); seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); - seq_printf(m, "digestsize : %u\n", alg->cra_hash.digestsize); + seq_printf(m, "digestsize : %u\n", alg->cra_ahash.digestsize); } const struct crypto_type crypto_ahash_type = { -- cgit From e4dd61882e2cfe47ea72ecd825671e8e5ae29038 Mon Sep 17 00:00:00 2001 From: Jarek Poplawski Date: Wed, 18 Feb 2009 23:31:11 -0800 Subject: vlan: Update skb->mac_header in __vlan_put_tag(). After moving mac addresses in __vlan_put_tag() skb->mac_header needs to be updated. Reported-by: Karl Hiramoto Signed-off-by: Jarek Poplawski Signed-off-by: David S. Miller --- include/linux/if_vlan.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index f8ff918c208..e1ff5b14310 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -210,6 +210,7 @@ static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb, u16 vlan_tci) /* Move the mac addresses to the beginning of the new header. */ memmove(skb->data, skb->data + VLAN_HLEN, 2 * VLAN_ETH_ALEN); + skb->mac_header -= VLAN_HLEN; /* first, the ethernet type */ veth->h_vlan_proto = htons(ETH_P_8021Q); -- cgit From de5483029b8f18e23395d8fd4f4ef6ae15beb809 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Thu, 19 Feb 2009 12:20:17 +0530 Subject: x86: include/asm/processor.h remove double declaration of print_cpu_info Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/include/asm/processor.h | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index dabab1a19dd..72914d0315e 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -403,7 +403,6 @@ DECLARE_PER_CPU(unsigned long, stack_canary); #endif #endif /* X86_64 */ -extern void print_cpu_info(struct cpuinfo_x86 *); extern unsigned int xstate_size; extern void free_thread_xstate(struct task_struct *); extern struct kmem_cache *task_xstate_cachep; -- cgit From 6ce6c473a7fd742fdb0db95841e2c4c6b37337c5 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 17 Feb 2009 09:50:30 +0100 Subject: sound: virtuoso: revert "do not overwrite EEPROM on Xonar D2/D2X" This reverts commit 7e86c0e6850504ec9516b953f316a47277825e33 ("do not overwrite EEPROM on Xonar D2/D2X") because it did not actually help with the problem. More user reports show that the overwriting of the EEPROM is not triggered by using this driver but by installing Linux, and that the installation of any other operating system (even one without any CMI8788 driver) has the same effect. In other words, the presence of this driver does not have any effect on the occurrence of the error. (So far, the available evidence seems to point to a BIOS bug.) Furthermore, it turns out that the EEPROM chip is protected against stray write commands by the command format and by requiring a separate write-enable command, so the error scenario in the previous commit (that SPI writes can be misinterpreted as an EEPROM write command) is not even theoretically possible. The mixer control that was removed as a consequence of the previous commit can only be partially emulated in userspace, which also means it cannot be seen be the in-kernel OSS API emulation, so it is better to revert that change. Signed-off-by: Clemens Ladisch Cc: Signed-off-by: Takashi Iwai --- sound/pci/oxygen/virtuoso.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 18c7c91786b..6c870c12a17 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -26,7 +26,7 @@ * SPI 0 -> 1st PCM1796 (front) * SPI 1 -> 2nd PCM1796 (surround) * SPI 2 -> 3rd PCM1796 (center/LFE) - * SPI 4 -> 4th PCM1796 (back) and EEPROM self-destruct (do not use!) + * SPI 4 -> 4th PCM1796 (back) * * GPIO 2 -> M0 of CS5381 * GPIO 3 -> M1 of CS5381 @@ -207,12 +207,6 @@ static void xonar_gpio_changed(struct oxygen *chip); static inline void pcm1796_write_spi(struct oxygen *chip, unsigned int codec, u8 reg, u8 value) { - /* - * We don't want to do writes on SPI 4 because the EEPROM, which shares - * the same pin, might get confused and broken. We'd better take care - * that the driver works with the default register values ... - */ -#if 0 /* maps ALSA channel pair number to SPI output */ static const u8 codec_map[4] = { 0, 1, 2, 4 @@ -223,7 +217,6 @@ static inline void pcm1796_write_spi(struct oxygen *chip, unsigned int codec, (codec_map[codec] << OXYGEN_SPI_CODEC_SHIFT) | OXYGEN_SPI_CEN_LATCH_CLOCK_HI, (reg << 8) | value); -#endif } static inline void pcm1796_write_i2c(struct oxygen *chip, unsigned int codec, @@ -757,9 +750,6 @@ static const DECLARE_TLV_DB_SCALE(cs4362a_db_scale, -12700, 100, 0); static int xonar_d2_control_filter(struct snd_kcontrol_new *template) { - if (!strncmp(template->name, "Master Playback ", 16)) - /* disable volume/mute because they would require SPI writes */ - return 1; if (!strncmp(template->name, "CD Capture ", 11)) /* CD in is actually connected to the video in pin */ template->private_value ^= AC97_CD ^ AC97_VIDEO; @@ -850,8 +840,9 @@ static const struct oxygen_model model_xonar_d2 = { .dac_volume_min = 0x0f, .dac_volume_max = 0xff, .misc_flags = OXYGEN_MISC_MIDI, - .function_flags = OXYGEN_FUNCTION_SPI, - .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S, + .function_flags = OXYGEN_FUNCTION_SPI | + OXYGEN_FUNCTION_ENABLE_SPI_4_5, + .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; -- cgit From 3fd9825c42c784a59b3b90bdf073f49d4bb42a8d Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Wed, 18 Feb 2009 22:29:22 +0100 Subject: [ARM] 5402/1: fix a case of wrap-around in sanity_check_meminfo() In the non highmem case, if two memory banks of 1GB each are provided, the second bank would evade suppression since its virtual base would be 0. Fix this by disallowing any memory bank which virtual base address is found to be lower than PAGE_OFFSET. Reported-by: Lennert Buytenhek Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/mm/mmu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 9b36c5cb5e9..d4d082c5c2d 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -693,7 +693,8 @@ static void __init sanity_check_meminfo(void) * Check whether this memory bank would entirely overlap * the vmalloc area. */ - if (__va(bank->start) >= VMALLOC_MIN) { + if (__va(bank->start) >= VMALLOC_MIN || + __va(bank->start) < PAGE_OFFSET) { printk(KERN_NOTICE "Ignoring RAM at %.8lx-%.8lx " "(vmalloc region overlap).\n", bank->start, bank->start + bank->size - 1); -- cgit From 22eb36f49e24e922ca6594a99157a3fcb92d3824 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Thu, 19 Feb 2009 11:57:46 +0100 Subject: [ARM] 5403/1: pxa25x_ep_fifo_flush() *ep->reg_udccs always set to 0 *ep->reg_udccs is always set to 0. Signed-off-by: Roel Kluin Acked-by: Eric Miao Signed-off-by: Russell King --- drivers/usb/gadget/pxa25x_udc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index 9b36205c575..0ce4e281984 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -904,8 +904,8 @@ static void pxa25x_ep_fifo_flush(struct usb_ep *_ep) /* most IN status is the same, but ISO can't stall */ *ep->reg_udccs = UDCCS_BI_TPC|UDCCS_BI_FTF|UDCCS_BI_TUR - | (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) - ? 0 : UDCCS_BI_SST; + | (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC + ? 0 : UDCCS_BI_SST); } -- cgit From 71d8f9784a99991a7571dd20226f5f450dda7f34 Mon Sep 17 00:00:00 2001 From: Hiroshi Shimamoto Date: Wed, 18 Feb 2009 11:07:52 -0800 Subject: x86: syscalls.h: remove asmlinkage from declaration of sys_rt_sigreturn() Impact: cleanup asmlinkage for sys_rt_sigreturn() no longer exists in arch/x86/kernel/signal.c. Signed-off-by: Hiroshi Shimamoto Signed-off-by: Ingo Molnar --- arch/x86/include/asm/syscalls.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h index 258ef730aaa..7043408f690 100644 --- a/arch/x86/include/asm/syscalls.h +++ b/arch/x86/include/asm/syscalls.h @@ -82,7 +82,7 @@ asmlinkage long sys_iopl(unsigned int, struct pt_regs *); /* kernel/signal_64.c */ asmlinkage long sys_sigaltstack(const stack_t __user *, stack_t __user *, struct pt_regs *); -asmlinkage long sys_rt_sigreturn(struct pt_regs *); +long sys_rt_sigreturn(struct pt_regs *); /* kernel/sys_x86_64.c */ asmlinkage long sys_mmap(unsigned long, unsigned long, unsigned long, -- cgit From 41f3103fcfffff096c34f5267d7c9a26b44d89d3 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 19 Feb 2009 13:25:16 +0000 Subject: [ARM] omap: fix clock reparenting in omap2_clk_set_parent() When changing the parent of a clock, it is necessary to keep the clock use counts balanced otherwise things the parent state will get corrupted. Since we already disable and re-enable the clock, we might as well use the recursive versions instead. Signed-off-by: Russell King --- arch/arm/mach-omap2/clock.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index e64549e4e32..ce4d46a4a83 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -746,7 +746,7 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent) return -EINVAL; if (clk->usecount > 0) - _omap2_clk_disable(clk); + omap2_clk_disable(clk); /* Set new source value (previous dividers if any in effect) */ reg_val = __raw_readl(src_addr) & ~field_mask; @@ -759,11 +759,11 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent) wmb(); } - if (clk->usecount > 0) - _omap2_clk_enable(clk); - clk->parent = new_parent; + if (clk->usecount > 0) + omap2_clk_enable(clk); + /* CLKSEL clocks follow their parents' rates, divided by a divisor */ clk->rate = new_parent->rate; -- cgit From e2e5a0f2b100a5204d27def8bbf73333d1710be2 Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Thu, 19 Feb 2009 15:18:59 +0100 Subject: [S390] sclp: handle empty event buffers Handle a malformed hardware response which some versions of the Support Element (SE) may present during SE restart and which otherwise would result in an endless loop in function sclp_dispatch_evbufs. Signed-off-by: Peter Oberparleiter Signed-off-by: Martin Schwidefsky --- drivers/s390/char/sclp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index 1fd8f2193ed..4377e93a43d 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c @@ -280,8 +280,11 @@ sclp_dispatch_evbufs(struct sccb_header *sccb) rc = 0; for (offset = sizeof(struct sccb_header); offset < sccb->length; offset += evbuf->length) { - /* Search for event handler */ evbuf = (struct evbuf_header *) ((addr_t) sccb + offset); + /* Check for malformed hardware response */ + if (evbuf->length == 0) + break; + /* Search for event handler */ reg = NULL; list_for_each(l, &sclp_reg_list) { reg = list_entry(l, struct sclp_register, list); -- cgit From d5cd0343d2878b66e25e044f644563c6bf708833 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Thu, 19 Feb 2009 15:19:00 +0100 Subject: [S390] Fix timeval regression on s390 commit aa5e97ce4bbc9d5daeec16b1d15bb3f6b7b4f4d4 [PATCH] improve precision of process accounting. Introduced a timing regression: -bash-3.2# time ls real 0m0.006s user 0m1.754s sys 0m1.094s The problem was introduced by an error in cputime_to_timeval. Cputime is now 1/4096 microsecond, therefore, we have to divide the remainder with 4096 to get the microseconds. Signed-off-by: Christian Borntraeger Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/cputime.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/include/asm/cputime.h b/arch/s390/include/asm/cputime.h index 521726430af..95b0f7db3c6 100644 --- a/arch/s390/include/asm/cputime.h +++ b/arch/s390/include/asm/cputime.h @@ -145,7 +145,7 @@ cputime_to_timeval(const cputime_t cputime, struct timeval *value) value->tv_usec = rp.subreg.even / 4096; value->tv_sec = rp.subreg.odd; #else - value->tv_usec = cputime % 4096000000ULL; + value->tv_usec = (cputime % 4096000000ULL) / 4096; value->tv_sec = cputime / 4096000000ULL; #endif } -- cgit From 23d75d9cadd79bc9fd6553857d57c679cf18d4cb Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 19 Feb 2009 15:19:01 +0100 Subject: [S390] fix "mem=" handling in case of standby memory Standby memory detected with the sclp interface gets always registered with add_memory calls without considering the limitationt that the "mem=" kernel paramater implies. So fix this and only register standby memory that is below the specified limit. This fixes zfcpdump since it uses "mem=32M". In case there is appr. 2GB standby memory present all of usable memory would be used for the struct pages needed for standby memory. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/setup.h | 2 ++ arch/s390/kernel/setup.c | 9 +++++++-- drivers/s390/char/sclp_cmd.c | 5 +++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index 2bd9faeb391..e8bd6ac22c9 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h @@ -43,6 +43,8 @@ struct mem_chunk { extern struct mem_chunk memory_chunk[]; extern unsigned long real_memory_size; +extern int memory_end_set; +extern unsigned long memory_end; void detect_memory_layout(struct mem_chunk chunk[]); diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index d825f4950e4..c5cfb6185ea 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -82,7 +82,9 @@ char elf_platform[ELF_PLATFORM_SIZE]; struct mem_chunk __initdata memory_chunk[MEMORY_CHUNKS]; volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ -static unsigned long __initdata memory_end; + +int __initdata memory_end_set; +unsigned long __initdata memory_end; /* * This is set up by the setup-routine at boot-time @@ -281,6 +283,7 @@ void (*pm_power_off)(void) = machine_power_off; static int __init early_parse_mem(char *p) { memory_end = memparse(p, &p); + memory_end_set = 1; return 0; } early_param("mem", early_parse_mem); @@ -508,8 +511,10 @@ static void __init setup_memory_end(void) int i; #if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE) - if (ipl_info.type == IPL_TYPE_FCP_DUMP) + if (ipl_info.type == IPL_TYPE_FCP_DUMP) { memory_end = ZFCPDUMP_HSA_SIZE; + memory_end_set = 1; + } #endif memory_size = 0; memory_end &= PAGE_MASK; diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index 50639049641..77ab6e34a10 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "sclp.h" @@ -474,6 +475,10 @@ static void __init add_memory_merged(u16 rn) goto skip_add; if (start + size > VMEM_MAX_PHYS) size = VMEM_MAX_PHYS - start; + if (memory_end_set && (start >= memory_end)) + goto skip_add; + if (memory_end_set && (start + size > memory_end)) + size = memory_end - start; add_memory(0, start, size); skip_add: first_rn = rn; -- cgit From 9da616fb9946c8d65387052e5a538b8f54ddb292 Mon Sep 17 00:00:00 2001 From: Makito SHIOKAWA Date: Thu, 19 Feb 2009 15:34:59 +0100 Subject: [ARM] 5404/1: Fix condition in arm_elf_read_implies_exec() to set READ_IMPLIES_EXEC READ_IMPLIES_EXEC must be set when: o binary _is_ an executable stack (i.e. not EXSTACK_DISABLE_X) o processor architecture is _under_ ARMv6 (XN bit is supported from ARMv6) Signed-off-by: Makito SHIOKAWA Signed-off-by: Russell King --- arch/arm/kernel/elf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/kernel/elf.c b/arch/arm/kernel/elf.c index 84849098c8e..d4a0da1e48f 100644 --- a/arch/arm/kernel/elf.c +++ b/arch/arm/kernel/elf.c @@ -74,9 +74,9 @@ EXPORT_SYMBOL(elf_set_personality); */ int arm_elf_read_implies_exec(const struct elf32_hdr *x, int executable_stack) { - if (executable_stack != EXSTACK_ENABLE_X) + if (executable_stack != EXSTACK_DISABLE_X) return 1; - if (cpu_architecture() <= CPU_ARCH_ARMv6) + if (cpu_architecture() < CPU_ARCH_ARMv6) return 1; return 0; } -- cgit From 95695547a7db44b88a7ee36cf5df188de267e99e Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Sat, 14 Feb 2009 00:50:18 +0300 Subject: x86: asm linkage - introduce GLOBAL macro If the code is time critical and this entry is called from other places we use ENTRY to have it globally defined and especially aligned. Contrary we have some snippets which are size critical. So we use plane ".globl name; name:" directive. Introduce GLOBAL macro for this. Signed-off-by: Cyrill Gorcunov Signed-off-by: Ingo Molnar --- arch/x86/include/asm/linkage.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/include/asm/linkage.h b/arch/x86/include/asm/linkage.h index 5d98d0b68ff..2ecf0f6fc9e 100644 --- a/arch/x86/include/asm/linkage.h +++ b/arch/x86/include/asm/linkage.h @@ -52,6 +52,10 @@ #endif +#define GLOBAL(name) \ + .globl name; \ + name: + #ifdef CONFIG_X86_ALIGNMENT_16 #define __ALIGN .align 16,0x90 #define __ALIGN_STR ".align 16,0x90" -- cgit From 1b25f3b4e18d1acffeb41258a18f13db71da9a7a Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Sat, 14 Feb 2009 00:50:19 +0300 Subject: x86: linkage - get rid of _X86 macros Impact: cleanup There was an attempt to bring build-time checking for missed ENTRY_X86/END_X86 and KPROBE... pairs. Using them will add messy in code. Get just rid of them. This commit could be easily restored if the need appear in future. Signed-off-by: Cyrill Gorcunov Signed-off-by: Ingo Molnar --- arch/x86/include/asm/linkage.h | 60 ------------------------------------------ 1 file changed, 60 deletions(-) diff --git a/arch/x86/include/asm/linkage.h b/arch/x86/include/asm/linkage.h index 2ecf0f6fc9e..9320e2a8a26 100644 --- a/arch/x86/include/asm/linkage.h +++ b/arch/x86/include/asm/linkage.h @@ -61,65 +61,5 @@ #define __ALIGN_STR ".align 16,0x90" #endif -/* - * to check ENTRY_X86/END_X86 and - * KPROBE_ENTRY_X86/KPROBE_END_X86 - * unbalanced-missed-mixed appearance - */ -#define __set_entry_x86 .set ENTRY_X86_IN, 0 -#define __unset_entry_x86 .set ENTRY_X86_IN, 1 -#define __set_kprobe_x86 .set KPROBE_X86_IN, 0 -#define __unset_kprobe_x86 .set KPROBE_X86_IN, 1 - -#define __macro_err_x86 .error "ENTRY_X86/KPROBE_X86 unbalanced,missed,mixed" - -#define __check_entry_x86 \ - .ifdef ENTRY_X86_IN; \ - .ifeq ENTRY_X86_IN; \ - __macro_err_x86; \ - .abort; \ - .endif; \ - .endif - -#define __check_kprobe_x86 \ - .ifdef KPROBE_X86_IN; \ - .ifeq KPROBE_X86_IN; \ - __macro_err_x86; \ - .abort; \ - .endif; \ - .endif - -#define __check_entry_kprobe_x86 \ - __check_entry_x86; \ - __check_kprobe_x86 - -#define ENTRY_KPROBE_FINAL_X86 __check_entry_kprobe_x86 - -#define ENTRY_X86(name) \ - __check_entry_kprobe_x86; \ - __set_entry_x86; \ - .globl name; \ - __ALIGN; \ - name: - -#define END_X86(name) \ - __unset_entry_x86; \ - __check_entry_kprobe_x86; \ - .size name, .-name - -#define KPROBE_ENTRY_X86(name) \ - __check_entry_kprobe_x86; \ - __set_kprobe_x86; \ - .pushsection .kprobes.text, "ax"; \ - .globl name; \ - __ALIGN; \ - name: - -#define KPROBE_END_X86(name) \ - __unset_kprobe_x86; \ - __check_entry_kprobe_x86; \ - .size name, .-name; \ - .popsection - #endif /* _ASM_X86_LINKAGE_H */ -- cgit From 2f7955509710fd378a1ac96e19d29d5a0e3301fd Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Sat, 14 Feb 2009 00:50:20 +0300 Subject: x86: copy.S - use GLOBAL,ENDPROC macros Impact: cleanup Signed-off-by: Cyrill Gorcunov Signed-off-by: Ingo Molnar --- arch/x86/boot/copy.S | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/arch/x86/boot/copy.S b/arch/x86/boot/copy.S index ef50c84e8b4..11f272c6f5e 100644 --- a/arch/x86/boot/copy.S +++ b/arch/x86/boot/copy.S @@ -8,6 +8,8 @@ * * ----------------------------------------------------------------------- */ +#include + /* * Memory copy routines */ @@ -15,9 +17,7 @@ .code16gcc .text - .globl memcpy - .type memcpy, @function -memcpy: +GLOBAL(memcpy) pushw %si pushw %di movw %ax, %di @@ -31,11 +31,9 @@ memcpy: popw %di popw %si ret - .size memcpy, .-memcpy +ENDPROC(memcpy) - .globl memset - .type memset, @function -memset: +GLOBAL(memset) pushw %di movw %ax, %di movzbl %dl, %eax @@ -48,52 +46,42 @@ memset: rep; stosb popw %di ret - .size memset, .-memset +ENDPROC(memset) - .globl copy_from_fs - .type copy_from_fs, @function -copy_from_fs: +GLOBAL(copy_from_fs) pushw %ds pushw %fs popw %ds call memcpy popw %ds ret - .size copy_from_fs, .-copy_from_fs +ENDPROC(copy_from_fs) - .globl copy_to_fs - .type copy_to_fs, @function -copy_to_fs: +GLOBAL(copy_to_fs) pushw %es pushw %fs popw %es call memcpy popw %es ret - .size copy_to_fs, .-copy_to_fs +ENDPROC(copy_to_fs) #if 0 /* Not currently used, but can be enabled as needed */ - - .globl copy_from_gs - .type copy_from_gs, @function -copy_from_gs: +GLOBAL(copy_from_gs) pushw %ds pushw %gs popw %ds call memcpy popw %ds ret - .size copy_from_gs, .-copy_from_gs - .globl copy_to_gs +ENDPROC(copy_from_gs) - .type copy_to_gs, @function -copy_to_gs: +GLOBAL(copy_to_gs) pushw %es pushw %gs popw %es call memcpy popw %es ret - .size copy_to_gs, .-copy_to_gs - +ENDPROC(copy_to_gs) #endif -- cgit From 324bda9e47f53aebec1376ee89bba8128c8455e2 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Sat, 14 Feb 2009 00:50:21 +0300 Subject: x86: pmjump - use GLOBAL,ENDPROC macros Impact: cleanup We are in setup stage so we use GLOBAL instead of ENTRY and do not increase code size. Signed-off-by: Cyrill Gorcunov Signed-off-by: Ingo Molnar --- arch/x86/boot/pmjump.S | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/arch/x86/boot/pmjump.S b/arch/x86/boot/pmjump.S index 141b6e20ed3..019c17a7585 100644 --- a/arch/x86/boot/pmjump.S +++ b/arch/x86/boot/pmjump.S @@ -15,18 +15,15 @@ #include #include #include +#include .text - - .globl protected_mode_jump - .type protected_mode_jump, @function - .code16 /* * void protected_mode_jump(u32 entrypoint, u32 bootparams); */ -protected_mode_jump: +GLOBAL(protected_mode_jump) movl %edx, %esi # Pointer to boot_params table xorl %ebx, %ebx @@ -47,12 +44,10 @@ protected_mode_jump: .byte 0x66, 0xea # ljmpl opcode 2: .long in_pm32 # offset .word __BOOT_CS # segment - - .size protected_mode_jump, .-protected_mode_jump +ENDPROC(protected_mode_jump) .code32 - .type in_pm32, @function -in_pm32: +GLOBAL(in_pm32) # Set up data segments for flat 32-bit mode movl %ecx, %ds movl %ecx, %es @@ -78,5 +73,4 @@ in_pm32: lldt %cx jmpl *%eax # Jump to the 32-bit entrypoint - - .size in_pm32, .-in_pm32 +ENDPROC(in_pm32) -- cgit From 2d4eeecb98ade6a736940d43311275b7d32dab21 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Sat, 14 Feb 2009 00:50:22 +0300 Subject: x86: compressed head_64 - use ENTRY,ENDPROC macros Impact: clenaup Linker script will put startup_32 at predefined address so using ENTRY will not bloat the code size. Signed-off-by: Cyrill Gorcunov Signed-off-by: Ingo Molnar --- arch/x86/boot/compressed/head_64.S | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index 1d5dff4123e..ba9229ba7f0 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S @@ -35,9 +35,7 @@ .section ".text.head" .code32 - .globl startup_32 - -startup_32: +ENTRY(startup_32) cld /* test KEEP_SEGMENTS flag to see if the bootloader is asking * us to not reload segments */ @@ -176,6 +174,7 @@ startup_32: /* Jump from 32bit compatibility mode into 64bit mode. */ lret +ENDPROC(startup_32) no_longmode: /* This isn't an x86-64 CPU so hang */ @@ -295,7 +294,6 @@ relocated: call decompress_kernel popq %rsi - /* * Jump to the decompressed kernel. */ -- cgit From cb425afd2183e90a481bb211ff49361a117a3ecc Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Sat, 14 Feb 2009 00:50:23 +0300 Subject: x86: compressed head_32 - use ENTRY,ENDPROC macros Impact: clenaup Linker script will put startup_32 at predefined address so using startup_32 will not bloat the code size. Signed-off-by: Cyrill Gorcunov Signed-off-by: Ingo Molnar --- arch/x86/boot/compressed/head_32.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index 29c5fbf0839..9f20d379406 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S @@ -30,9 +30,7 @@ #include .section ".text.head","ax",@progbits - .globl startup_32 - -startup_32: +ENTRY(startup_32) cld /* test KEEP_SEGMENTS flag to see if the bootloader is asking * us to not reload segments */ @@ -113,6 +111,8 @@ startup_32: */ leal relocated(%ebx), %eax jmp *%eax +ENDPROC(startup_32) + .section ".text" relocated: -- cgit From 9dd446f657ebebb209274878be5d01103fcfe988 Mon Sep 17 00:00:00 2001 From: Hartley Sweeten Date: Thu, 19 Feb 2009 17:09:04 +0100 Subject: [ARM] 5405/1: ep93xx: remove unused gesbc9312.h header Remove the gesbc9312.h header since it is unused. Signed-off-by: H Hartley Sweeten Signed-off-by: Russell King --- arch/arm/mach-ep93xx/include/mach/gesbc9312.h | 3 --- arch/arm/mach-ep93xx/include/mach/hardware.h | 1 - 2 files changed, 4 deletions(-) delete mode 100644 arch/arm/mach-ep93xx/include/mach/gesbc9312.h diff --git a/arch/arm/mach-ep93xx/include/mach/gesbc9312.h b/arch/arm/mach-ep93xx/include/mach/gesbc9312.h deleted file mode 100644 index 21fe2b922aa..00000000000 --- a/arch/arm/mach-ep93xx/include/mach/gesbc9312.h +++ /dev/null @@ -1,3 +0,0 @@ -/* - * arch/arm/mach-ep93xx/include/mach/gesbc9312.h - */ diff --git a/arch/arm/mach-ep93xx/include/mach/hardware.h b/arch/arm/mach-ep93xx/include/mach/hardware.h index 529807d182b..2866297310b 100644 --- a/arch/arm/mach-ep93xx/include/mach/hardware.h +++ b/arch/arm/mach-ep93xx/include/mach/hardware.h @@ -10,7 +10,6 @@ #include "platform.h" -#include "gesbc9312.h" #include "ts72xx.h" #endif -- cgit From 7fdf582447aa01658b624adc0a51a31e4278b68c Mon Sep 17 00:00:00 2001 From: Felix Blyakher Date: Wed, 18 Feb 2009 15:41:28 -0600 Subject: Revert "[XFS] use scalable vmap API" This reverts commit 95f8e302c04c0b0c6de35ab399a5551605eeb006. This commit caused regression. We'll try to fix use of new vmap API for next release. Signed-off-by: Christoph Hellwig Signed-off-by: Felix Blyakher --- fs/xfs/linux-2.6/xfs_buf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index d71dc44e21e..0b2177a9fbd 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -264,7 +264,7 @@ xfs_buf_free( uint i; if ((bp->b_flags & XBF_MAPPED) && (bp->b_page_count > 1)) - vm_unmap_ram(bp->b_addr - bp->b_offset, bp->b_page_count); + vunmap(bp->b_addr - bp->b_offset); for (i = 0; i < bp->b_page_count; i++) { struct page *page = bp->b_pages[i]; @@ -386,8 +386,8 @@ _xfs_buf_map_pages( bp->b_addr = page_address(bp->b_pages[0]) + bp->b_offset; bp->b_flags |= XBF_MAPPED; } else if (flags & XBF_MAPPED) { - bp->b_addr = vm_map_ram(bp->b_pages, bp->b_page_count, - -1, PAGE_KERNEL); + bp->b_addr = vmap(bp->b_pages, bp->b_page_count, + VM_MAP, PAGE_KERNEL); if (unlikely(bp->b_addr == NULL)) return -ENOMEM; bp->b_addr += bp->b_offset; -- cgit From 27e88bf6af7d42adf790f7b2ed7d65475f191cf2 Mon Sep 17 00:00:00 2001 From: Felix Blyakher Date: Wed, 18 Feb 2009 15:56:51 -0600 Subject: Revert "[XFS] remove old vmap cache" This reverts commit d2859751cd0bf586941ffa7308635a293f943c17. This commit caused regression. We'll try to fix use of new vmap API for next release. Signed-off-by: Christoph Hellwig Signed-off-by: Felix Blyakher --- fs/xfs/linux-2.6/xfs_buf.c | 75 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 0b2177a9fbd..cb329edc925 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -165,6 +165,75 @@ test_page_region( return (mask && (page_private(page) & mask) == mask); } +/* + * Mapping of multi-page buffers into contiguous virtual space + */ + +typedef struct a_list { + void *vm_addr; + struct a_list *next; +} a_list_t; + +static a_list_t *as_free_head; +static int as_list_len; +static DEFINE_SPINLOCK(as_lock); + +/* + * Try to batch vunmaps because they are costly. + */ +STATIC void +free_address( + void *addr) +{ + a_list_t *aentry; + +#ifdef CONFIG_XEN + /* + * Xen needs to be able to make sure it can get an exclusive + * RO mapping of pages it wants to turn into a pagetable. If + * a newly allocated page is also still being vmap()ed by xfs, + * it will cause pagetable construction to fail. This is a + * quick workaround to always eagerly unmap pages so that Xen + * is happy. + */ + vunmap(addr); + return; +#endif + + aentry = kmalloc(sizeof(a_list_t), GFP_NOWAIT); + if (likely(aentry)) { + spin_lock(&as_lock); + aentry->next = as_free_head; + aentry->vm_addr = addr; + as_free_head = aentry; + as_list_len++; + spin_unlock(&as_lock); + } else { + vunmap(addr); + } +} + +STATIC void +purge_addresses(void) +{ + a_list_t *aentry, *old; + + if (as_free_head == NULL) + return; + + spin_lock(&as_lock); + aentry = as_free_head; + as_free_head = NULL; + as_list_len = 0; + spin_unlock(&as_lock); + + while ((old = aentry) != NULL) { + vunmap(aentry->vm_addr); + aentry = aentry->next; + kfree(old); + } +} + /* * Internal xfs_buf_t object manipulation */ @@ -264,7 +333,7 @@ xfs_buf_free( uint i; if ((bp->b_flags & XBF_MAPPED) && (bp->b_page_count > 1)) - vunmap(bp->b_addr - bp->b_offset); + free_address(bp->b_addr - bp->b_offset); for (i = 0; i < bp->b_page_count; i++) { struct page *page = bp->b_pages[i]; @@ -386,6 +455,8 @@ _xfs_buf_map_pages( bp->b_addr = page_address(bp->b_pages[0]) + bp->b_offset; bp->b_flags |= XBF_MAPPED; } else if (flags & XBF_MAPPED) { + if (as_list_len > 64) + purge_addresses(); bp->b_addr = vmap(bp->b_pages, bp->b_page_count, VM_MAP, PAGE_KERNEL); if (unlikely(bp->b_addr == NULL)) @@ -1672,6 +1743,8 @@ xfsbufd( count++; } + if (as_list_len > 0) + purge_addresses(); if (count) blk_run_address_space(target->bt_mapping); -- cgit From 334f85b647bc46ff4d27ace55aa65f44d6a2f4db Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Thu, 19 Feb 2009 11:22:36 -0800 Subject: [IA64] Build fix for __early_pfn_to_nid() undefined link error ia64 only defines __early_pfn_to_nid() for SPARSEMEM && NUMA configurations, so the recent: commit: f2dbcfa738368c8a40d4a5f0b65dc9879577cb21 mm: clean up for early_pfn_to_nid() ends up with some link problems for certain configuration files. Fix arch/ia64/Kconfig to only define HAVE_ARCH_EARLY_PFN_TO_NID in the cases where we do provide this function. Signed-off-by: Tony Luck --- arch/ia64/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 6183aeccecf..20d6d28ca73 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -479,8 +479,7 @@ config HOLES_IN_ZONE default y if VIRTUAL_MEM_MAP config HAVE_ARCH_EARLY_PFN_TO_NID - def_bool y - depends on NEED_MULTIPLE_NODES + def_bool NUMA && SPARSEMEM config HAVE_ARCH_NODEDATA_EXTENSION def_bool y -- cgit From 39d481cba27809598e755e184bc0d8ae1d22423e Mon Sep 17 00:00:00 2001 From: Robin Holt Date: Tue, 3 Feb 2009 18:40:59 -0600 Subject: [IA64] bte_copy of BTE_MAX_XFER trips BUG_ON. BTE_MAX_XFER is wrong. It is one greater than the number of cache lines the BTE is actually able to transfer. If you request a transfer of exactly BTE_MAX_XFER size, you trip a very cryptic BUG_ON() which should certainly be made more clear. This patch fixes that constant and also cleans up the BUG_ON()s in arch/ia64/sn/kernel/bte.c to test one condition per line. Signed-off-by: Robin Holt Signed-off-by: Tony Luck --- arch/ia64/include/asm/sn/bte.h | 2 +- arch/ia64/sn/kernel/bte.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/ia64/include/asm/sn/bte.h b/arch/ia64/include/asm/sn/bte.h index 5efecf06c9a..96798d2da7c 100644 --- a/arch/ia64/include/asm/sn/bte.h +++ b/arch/ia64/include/asm/sn/bte.h @@ -39,7 +39,7 @@ /* BTE status register only supports 16 bits for length field */ #define BTE_LEN_BITS (16) #define BTE_LEN_MASK ((1 << BTE_LEN_BITS) - 1) -#define BTE_MAX_XFER ((1 << BTE_LEN_BITS) * L1_CACHE_BYTES) +#define BTE_MAX_XFER (BTE_LEN_MASK << L1_CACHE_SHIFT) /* Define hardware */ diff --git a/arch/ia64/sn/kernel/bte.c b/arch/ia64/sn/kernel/bte.c index 9456d403402..c6d6b62db66 100644 --- a/arch/ia64/sn/kernel/bte.c +++ b/arch/ia64/sn/kernel/bte.c @@ -97,9 +97,10 @@ bte_result_t bte_copy(u64 src, u64 dest, u64 len, u64 mode, void *notification) return BTE_SUCCESS; } - BUG_ON((len & L1_CACHE_MASK) || - (src & L1_CACHE_MASK) || (dest & L1_CACHE_MASK)); - BUG_ON(!(len < ((BTE_LEN_MASK + 1) << L1_CACHE_SHIFT))); + BUG_ON(len & L1_CACHE_MASK); + BUG_ON(src & L1_CACHE_MASK); + BUG_ON(dest & L1_CACHE_MASK); + BUG_ON(len > BTE_MAX_XFER); /* * Start with interface corresponding to cpu number -- cgit From 66db2e6331612bbec193a358885854330596a92a Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Mon, 9 Feb 2009 11:16:16 -0700 Subject: [IA64] Revert "prevent ia64 from invoking irq handlers on offline CPUs" This reverts commit e7b140365b86aaf94374214c6f4e6decbee2eb0a. Commit e7b14036 removes the targetted disabled CPU from the cpu_online_map after calls to migrate_platform_irqs and fixup_irqs. Paul McKenney states that the reasoning behind the patch was to prevent irq handlers from running on CPUs marked offline because: RCU happily ignores CPUs that don't have their bits set in cpu_online_map, so if there are RCU read-side critical sections in the irq handlers being run, RCU will ignore them. If the other CPUs were running, they might sequence through the RCU state machine, which could result in data structures being yanked out from under those irq handlers, which in turn could result in oopses or worse. Unfortunately, both ia64 functions above look at cpu_online_map to find a new CPU to migrate interrupts onto. This means we can potentially migrate an interrupt off ourself back to... ourself. Uh oh. This causes an oops when we finally try to process pending interrupts on the CPU we want to disable. The oops results from calling __do_IRQ with a NULL pt_regs: Unable to handle kernel NULL pointer dereference (address 0000000000000040) Call Trace: [] show_stack+0x50/0xa0 sp=e0000009c922fa00 bsp=e0000009c92214d0 [] show_regs+0x820/0x860 sp=e0000009c922fbd0 bsp=e0000009c9221478 [] die+0x1a0/0x2e0 sp=e0000009c922fbd0 bsp=e0000009c9221438 [] ia64_do_page_fault+0x950/0xa80 sp=e0000009c922fbd0 bsp=e0000009c92213d8 [] ia64_native_leave_kernel+0x0/0x270 sp=e0000009c922fc60 bsp=e0000009c92213d8 [] profile_tick+0xd0/0x1c0 sp=e0000009c922fe30 bsp=e0000009c9221398 [] timer_interrupt+0x170/0x3e0 sp=e0000009c922fe30 bsp=e0000009c9221330 [] handle_IRQ_event+0x80/0x120 sp=e0000009c922fe30 bsp=e0000009c92212f8 [] __do_IRQ+0x160/0x4a0 sp=e0000009c922fe30 bsp=e0000009c9221290 [] ia64_process_pending_intr+0x2b0/0x360 sp=e0000009c922fe30 bsp=e0000009c9221208 [] fixup_irqs+0xf0/0x2a0 sp=e0000009c922fe30 bsp=e0000009c92211a8 [] __cpu_disable+0x140/0x240 sp=e0000009c922fe30 bsp=e0000009c9221168 [] take_cpu_down+0x50/0xa0 sp=e0000009c922fe30 bsp=e0000009c9221148 [] stop_cpu+0xd0/0x200 sp=e0000009c922fe30 bsp=e0000009c92210f0 [] kthread+0xc0/0x140 sp=e0000009c922fe30 bsp=e0000009c92210c8 [] kernel_thread_helper+0xd0/0x100 sp=e0000009c922fe30 bsp=e0000009c92210a0 [] start_kernel_thread+0x20/0x40 sp=e0000009c922fe30 bsp=e0000009c92210a0 I don't like this revert because it is fragile. ia64 is getting lucky because we seem to only ever process timer interrupts in this path, but if we ever race with an IPI here, we definitely use RCU and have the potential of hitting an oops that Paul describes above. Patching ia64's timer_interrupt() to check for NULL pt_regs is insufficient though, as we still hit the above oops. As a short term solution, I do think that this revert is the right answer. The revert hold up under repeated testing (24+ hour test runs) with this setup: - 8-way rx6600 - randomly toggling CPU online/offline state every 2 seconds - running CPU exercisers, memory hog, disk exercisers, and network stressors - average system load around ~160 In the long term, we really need to figure out why we set pt_regs = NULL in ia64_process_pending_intr(). If it turns out that it is unnecessary to do so, then we could safely re-introduce e7b14036 (along with some other logic to be smarter about migrating interrupts). One final note: x86 also removes the disabled CPU from cpu_online_map and then re-enables interrupts for 1ms, presumably to handle any pending interrupts: arch/x86/kernel/irq_32.c (and irq_64.c): cpu_disable_common: [remove cpu from cpu_online_map] fixup_irqs(): for_each_irq: [break CPU affinities] local_irq_enable(); mdelay(1); local_irq_disable(); So they are doing implicitly what ia64 is doing explicitly. Signed-off-by: Alex Chiang Signed-off-by: Tony Luck --- arch/ia64/kernel/smpboot.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 11463994a7d..2ec5bbff461 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -736,14 +736,16 @@ int __cpu_disable(void) return -EBUSY; } + cpu_clear(cpu, cpu_online_map); + if (migrate_platform_irqs(cpu)) { cpu_set(cpu, cpu_online_map); return (-EBUSY); } remove_siblinginfo(cpu); - fixup_irqs(); cpu_clear(cpu, cpu_online_map); + fixup_irqs(); local_flush_tlb_all(); cpu_clear(cpu, cpu_callin_map); return 0; -- cgit From c0acdea21437eff134cc3486bdc52907d9086af1 Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Mon, 9 Feb 2009 11:16:57 -0700 Subject: [IA64] Remove redundant cpu_clear() in __cpu_disable path The second call to cpu_clear() is redundant, as we've already removed the CPU from cpu_online_map before calling migrate_platform_irqs(). Signed-off-by: Alex Chiang Signed-off-by: Tony Luck --- arch/ia64/kernel/smpboot.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 2ec5bbff461..52290547c85 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -740,11 +740,10 @@ int __cpu_disable(void) if (migrate_platform_irqs(cpu)) { cpu_set(cpu, cpu_online_map); - return (-EBUSY); + return -EBUSY; } remove_siblinginfo(cpu); - cpu_clear(cpu, cpu_online_map); fixup_irqs(); local_flush_tlb_all(); cpu_clear(cpu, cpu_callin_map); -- cgit From 1d5b20f490f61f36a58e6ecf1713a49a43620666 Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Fri, 16 Jan 2009 12:17:30 +0900 Subject: [IA64] fixes configs and add default config for ia64 xen domU This patch fixes xen related Kconfigs and add default config file for ia64 xen domU. Signed-off-by: Isaku Yamahata Signed-off-by: Tony Luck --- arch/ia64/Kconfig | 4 + arch/ia64/configs/xen_domu_defconfig | 1601 ++++++++++++++++++++++++++++++++++ arch/ia64/xen/Kconfig | 3 +- 3 files changed, 1606 insertions(+), 2 deletions(-) create mode 100644 arch/ia64/configs/xen_domu_defconfig diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 20d6d28ca73..4eb45c01249 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -221,7 +221,11 @@ config IA64_HP_SIM config IA64_XEN_GUEST bool "Xen guest" + select SWIOTLB depends on XEN + help + Build a kernel that runs on Xen guest domain. At this moment only + 16KB page size in supported. endchoice diff --git a/arch/ia64/configs/xen_domu_defconfig b/arch/ia64/configs/xen_domu_defconfig new file mode 100644 index 00000000000..0bb0714dc19 --- /dev/null +++ b/arch/ia64/configs/xen_domu_defconfig @@ -0,0 +1,1601 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.29-rc1 +# Fri Jan 16 11:49:59 2009 +# +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=20 +CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y +# CONFIG_GROUP_SCHED is not set + +# +# Control Group support +# +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +# CONFIG_EMBEDDED is not set +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +CONFIG_KALLSYMS_STRIP_GENERATED=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_COMPAT_BRK=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_PCI_QUIRKS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_USE_GENERIC_SMP_HELPERS=y +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_STOP_MACHINE=y +CONFIG_BLOCK=y +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set +CONFIG_FREEZER=y + +# +# Processor type and features +# +CONFIG_IA64=y +CONFIG_64BIT=y +CONFIG_ZONE_DMA=y +CONFIG_QUICKLIST=y +CONFIG_MMU=y +CONFIG_SWIOTLB=y +CONFIG_IOMMU_HELPER=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_HAVE_SETUP_PER_CPU_AREA=y +CONFIG_DMI=y +CONFIG_EFI=y +CONFIG_GENERIC_IOMAP=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_AUDIT_ARCH=y +CONFIG_PARAVIRT_GUEST=y +CONFIG_PARAVIRT=y +CONFIG_XEN=y +CONFIG_XEN_XENCOMM=y +CONFIG_NO_IDLE_HZ=y +# CONFIG_IA64_GENERIC is not set +# CONFIG_IA64_DIG is not set +# CONFIG_IA64_DIG_VTD is not set +# CONFIG_IA64_HP_ZX1 is not set +# CONFIG_IA64_HP_ZX1_SWIOTLB is not set +# CONFIG_IA64_SGI_SN2 is not set +# CONFIG_IA64_SGI_UV is not set +# CONFIG_IA64_HP_SIM is not set +CONFIG_IA64_XEN_GUEST=y +# CONFIG_ITANIUM is not set +CONFIG_MCKINLEY=y +# CONFIG_IA64_PAGE_SIZE_4KB is not set +# CONFIG_IA64_PAGE_SIZE_8KB is not set +CONFIG_IA64_PAGE_SIZE_16KB=y +# CONFIG_IA64_PAGE_SIZE_64KB is not set +CONFIG_PGTABLE_3=y +# CONFIG_PGTABLE_4 is not set +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_SCHED_HRTICK is not set +CONFIG_IA64_L1_CACHE_SHIFT=7 +CONFIG_IA64_CYCLONE=y +CONFIG_IOSAPIC=y +CONFIG_FORCE_MAX_ZONEORDER=17 +# CONFIG_VIRT_CPU_ACCOUNTING is not set +CONFIG_SMP=y +CONFIG_NR_CPUS=16 +CONFIG_HOTPLUG_CPU=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +# CONFIG_SCHED_SMT is not set +CONFIG_PERMIT_BSP_REMOVE=y +CONFIG_FORCE_CPEI_RETARGET=y +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_MIGRATION=y +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_NR_QUICK=1 +CONFIG_VIRT_TO_BUS=y +CONFIG_UNEVICTABLE_LRU=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_DISCONTIGMEM_ENABLE=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_VIRTUAL_MEM_MAP=y +CONFIG_HOLES_IN_ZONE=y +# CONFIG_IA32_SUPPORT is not set +# CONFIG_COMPAT_FOR_U64_ALIGNMENT is not set +CONFIG_IA64_MCA_RECOVERY=y +CONFIG_PERFMON=y +CONFIG_IA64_PALINFO=y +# CONFIG_IA64_MC_ERR_INJECT is not set +# CONFIG_IA64_ESI is not set +# CONFIG_IA64_HP_AML_NFW is not set +CONFIG_KEXEC=y +# CONFIG_CRASH_DUMP is not set + +# +# Firmware Drivers +# +# CONFIG_FIRMWARE_MEMMAP is not set +CONFIG_EFI_VARS=y +CONFIG_EFI_PCDP=y +CONFIG_DMIID=y +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set +CONFIG_BINFMT_MISC=m + +# +# Power management and ACPI options +# +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_ACPI=y +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_PROCFS=y +CONFIG_ACPI_PROCFS_POWER=y +CONFIG_ACPI_SYSFS_POWER=y +CONFIG_ACPI_PROC_EVENT=y +CONFIG_ACPI_BUTTON=m +CONFIG_ACPI_FAN=m +# CONFIG_ACPI_DOCK is not set +CONFIG_ACPI_PROCESSOR=m +CONFIG_ACPI_HOTPLUG_CPU=y +CONFIG_ACPI_THERMAL=m +# CONFIG_ACPI_CUSTOM_DSDT is not set +CONFIG_ACPI_BLACKLIST_YEAR=0 +# CONFIG_ACPI_DEBUG is not set +# CONFIG_ACPI_PCI_SLOT is not set +CONFIG_ACPI_SYSTEM=y +CONFIG_ACPI_CONTAINER=m + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# Bus options (PCI, PCMCIA) +# +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_SYSCALL=y +# CONFIG_PCIEPORTBUS is not set +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_PCI_MSI is not set +CONFIG_PCI_LEGACY=y +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_STUB is not set +CONFIG_HOTPLUG_PCI=m +# CONFIG_HOTPLUG_PCI_FAKE is not set +CONFIG_HOTPLUG_PCI_ACPI=m +# CONFIG_HOTPLUG_PCI_ACPI_IBM is not set +# CONFIG_HOTPLUG_PCI_CPCI is not set +# CONFIG_HOTPLUG_PCI_SHPC is not set +# CONFIG_PCCARD is not set +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NET_NS is not set +CONFIG_COMPAT_NET_DEV_OPS=y +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +CONFIG_ARPD=y +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_PHONET is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +CONFIG_PNP=y +CONFIG_PNP_DEBUG_MESSAGES=y + +# +# Protocols +# +CONFIG_PNPACPI=y +CONFIG_BLK_DEV=y +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_NBD=m +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_XEN_BLKDEV_FRONTEND=y +# CONFIG_BLK_DEV_HD is not set +CONFIG_MISC_DEVICES=y +# CONFIG_PHANTOM is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_HP_ILO is not set +# CONFIG_C2PORT is not set +CONFIG_HAVE_IDE=y +CONFIG_IDE=y + +# +# Please see Documentation/ide/ide.txt for help/info on IDE drives +# +CONFIG_IDE_TIMINGS=y +CONFIG_IDE_ATAPI=y +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_IDE_GD=y +CONFIG_IDE_GD_ATA=y +# CONFIG_IDE_GD_ATAPI is not set +CONFIG_BLK_DEV_IDECD=y +CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEACPI is not set +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_PROC_FS=y + +# +# IDE chipset support/bugfixes +# +# CONFIG_IDE_GENERIC is not set +# CONFIG_BLK_DEV_PLATFORM is not set +# CONFIG_BLK_DEV_IDEPNP is not set +CONFIG_BLK_DEV_IDEDMA_SFF=y + +# +# PCI IDE chipsets support +# +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_PCIBUS_ORDER=y +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +CONFIG_BLK_DEV_CMD64X=y +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_JMICRON is not set +# CONFIG_BLK_DEV_SC1200 is not set +CONFIG_BLK_DEV_PIIX=y +# CONFIG_BLK_DEV_IT8172 is not set +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_BLK_DEV_TC86C001 is not set +CONFIG_BLK_DEV_IDEDMA=y + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +CONFIG_SCSI_NETLINK=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=m +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=m +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +CONFIG_SCSI_SPI_ATTRS=y +CONFIG_SCSI_FC_ATTRS=y +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_CXGB3_ISCSI is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_LIBFC is not set +# CONFIG_FCOE is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_MVSAS is not set +# CONFIG_SCSI_STEX is not set +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_QLOGIC_1280=y +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_DH is not set +# CONFIG_ATA is not set +CONFIG_MD=y +CONFIG_BLK_DEV_MD=m +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +# CONFIG_MD_RAID10 is not set +# CONFIG_MD_RAID456 is not set +CONFIG_MD_MULTIPATH=m +# CONFIG_MD_FAULTY is not set +CONFIG_BLK_DEV_DM=m +# CONFIG_DM_DEBUG is not set +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_DELAY is not set +# CONFIG_DM_UEVENT is not set +CONFIG_FUSION=y +CONFIG_FUSION_SPI=y +CONFIG_FUSION_FC=y +# CONFIG_FUSION_SAS is not set +CONFIG_FUSION_MAX_SGE=128 +CONFIG_FUSION_CTL=y +# CONFIG_FUSION_LOGGING is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# Enable only one of the two stacks, unless you know what you are doing +# +# CONFIG_FIREWIRE is not set +# CONFIG_IEEE1394 is not set +# CONFIG_I2O is not set +CONFIG_NETDEVICES=y +CONFIG_DUMMY=m +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_NET_SB1000 is not set +# CONFIG_ARCNET is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=m +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +CONFIG_NET_TULIP=y +# CONFIG_DE2104X is not set +CONFIG_TULIP=m +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_NAPI is not set +# CONFIG_DE4X5 is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_DM9102 is not set +# CONFIG_ULI526X is not set +# CONFIG_HP100 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +CONFIG_E100=m +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_R6040 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SMSC9420 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_SC92031 is not set +# CONFIG_ATL2 is not set +CONFIG_NETDEV_1000=y +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +CONFIG_E1000=y +# CONFIG_E1000E is not set +# CONFIG_IP1000 is not set +# CONFIG_IGB is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_VIA_VELOCITY is not set +CONFIG_TIGON3=y +# CONFIG_BNX2 is not set +# CONFIG_QLA3XXX is not set +# CONFIG_ATL1 is not set +# CONFIG_ATL1E is not set +# CONFIG_JME is not set +CONFIG_NETDEV_10000=y +# CONFIG_CHELSIO_T1 is not set +CONFIG_CHELSIO_T3_DEPENDS=y +# CONFIG_CHELSIO_T3 is not set +# CONFIG_ENIC is not set +# CONFIG_IXGBE is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_NIU is not set +# CONFIG_MLX4_EN is not set +# CONFIG_MLX4_CORE is not set +# CONFIG_TEHUTI is not set +# CONFIG_BNX2X is not set +# CONFIG_QLGE is not set +# CONFIG_SFC is not set +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_WAN is not set +CONFIG_XEN_NETDEV_FRONTEND=y +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +CONFIG_NETCONSOLE=y +# CONFIG_NETCONSOLE_DYNAMIC is not set +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_ELANTECH is not set +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_BCM5974 is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +CONFIG_GAMEPORT=m +# CONFIG_GAMEPORT_NS558 is not set +# CONFIG_GAMEPORT_L4 is not set +# CONFIG_GAMEPORT_EMU10K1 is not set +# CONFIG_GAMEPORT_FM801 is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_SYNCLINK_GT is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_NOZOMI is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_PNP=y +CONFIG_SERIAL_8250_NR_UARTS=6 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_RSA is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_HVC_DRIVER=y +CONFIG_HVC_IRQ=y +CONFIG_HVC_XEN=y +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +CONFIG_EFI_RTC=y +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +CONFIG_RAW_DRIVER=m +CONFIG_MAX_RAW_DEVS=256 +CONFIG_HPET=y +CONFIG_HPET_MMAP=y +# CONFIG_HANGCHECK_TIMER is not set +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +CONFIG_I2C=m +CONFIG_I2C_BOARDINFO=y +# CONFIG_I2C_CHARDEV is not set +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=m + +# +# I2C Hardware Bus support +# + +# +# PC SMBus host controller drivers +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_ISCH is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Graphics adapter I2C/DDC channel drivers +# +# CONFIG_I2C_VOODOO3 is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +# CONFIG_AT24 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_PCF8575 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_SPI is not set +# CONFIG_W1 is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_BATTERY_DS2760 is not set +# CONFIG_BATTERY_BQ27x00 is not set +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7473 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_I5K_AMB is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_SENSORS_LIS3LV02D is not set +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_THERMAL=m +# CONFIG_THERMAL_HWMON is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_REGULATOR is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# +CONFIG_DAB=y +# CONFIG_USB_DABUSB is not set + +# +# Graphics support +# +CONFIG_AGP=m +CONFIG_DRM=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_MGA=m +CONFIG_DRM_SIS=m +# CONFIG_DRM_VIA is not set +# CONFIG_DRM_SAVAGE is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +# CONFIG_VGACON_SOFT_SCROLLBACK is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +# CONFIG_USB_HIDDEV is not set + +# +# Special HID drivers +# +CONFIG_HID_COMPAT=y +CONFIG_HID_A4TECH=y +CONFIG_HID_APPLE=y +CONFIG_HID_BELKIN=y +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +CONFIG_HID_CYPRESS=y +CONFIG_HID_EZKEY=y +CONFIG_HID_GYRATION=y +CONFIG_HID_LOGITECH=y +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MONTEREY=y +CONFIG_HID_NTRIG=y +CONFIG_HID_PANTHERLORD=y +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=y +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SONY=y +CONFIG_HID_SUNPLUS=y +# CONFIG_GREENASIA_FF is not set +CONFIG_HID_TOPSEED=y +# CONFIG_THRUSTMASTER_FF is not set +# CONFIG_ZEROPLUS_FF is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_EHCI_HCD=m +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_UHCI_HCD=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_WHCI_HCD is not set +# CONFIG_USB_HWA_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; +# + +# +# see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_VST is not set +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +# CONFIG_UWB is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_UIO is not set +CONFIG_XEN_BALLOON=y +CONFIG_XEN_SCRUB_PAGES=y +CONFIG_XENFS=y +CONFIG_XEN_COMPAT_XENFS=y +# CONFIG_STAGING is not set +# CONFIG_MSPEC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=y +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_FILE_LOCKING=y +CONFIG_XFS_FS=y +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_DEBUG is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +# CONFIG_NTFS_RW is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +CONFIG_NFSD_V4=y +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +# CONFIG_SUNRPC_REGISTER_V4 is not set +CONFIG_RPCSEC_GSS_KRB5=m +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +CONFIG_SMB_NLS_DEFAULT=y +CONFIG_SMB_NLS_REMOTE="cp437" +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=2048 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set + +# +# Tracers +# +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_IA64_GRANULE_16MB=y +# CONFIG_IA64_GRANULE_64MB is not set +# CONFIG_IA64_PRINT_HAZARDS is not set +# CONFIG_DISABLE_VHPT is not set +# CONFIG_IA64_DEBUG_CMPXCHG is not set +# CONFIG_IA64_DEBUG_IRQ is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_MANAGER=m +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=m +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=m +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=m +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set +CONFIG_HAVE_KVM=y +CONFIG_VIRTUALIZATION=y +# CONFIG_KVM is not set +# CONFIG_VIRTIO_PCI is not set +# CONFIG_VIRTIO_BALLOON is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_IRQ_PER_CPU=y +# CONFIG_IOMMU_API is not set diff --git a/arch/ia64/xen/Kconfig b/arch/ia64/xen/Kconfig index f1683a20275..515e0826803 100644 --- a/arch/ia64/xen/Kconfig +++ b/arch/ia64/xen/Kconfig @@ -8,8 +8,7 @@ config XEN depends on PARAVIRT && MCKINLEY && IA64_PAGE_SIZE_16KB && EXPERIMENTAL select XEN_XENCOMM select NO_IDLE_HZ - - # those are required to save/restore. + # followings are required to save/restore. select ARCH_SUSPEND_POSSIBLE select SUSPEND select PM_SLEEP -- cgit From ec8148de85a73a3be397a59b6d8f4f32cf2dd254 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Thu, 19 Feb 2009 12:05:00 -0800 Subject: [IA64] xen_domu build fix arch/ia64/xen/xen_pv_ops.c:156: error: xen_init_ops causes a section type conflict arch/ia64/xen/xen_pv_ops.c:340: error: xen_iosapic_ops causes a section type conflict Signed-off-by: Tony Luck --- arch/ia64/xen/xen_pv_ops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/ia64/xen/xen_pv_ops.c b/arch/ia64/xen/xen_pv_ops.c index 04cd1235045..936cff3c96e 100644 --- a/arch/ia64/xen/xen_pv_ops.c +++ b/arch/ia64/xen/xen_pv_ops.c @@ -153,7 +153,7 @@ xen_post_smp_prepare_boot_cpu(void) xen_setup_vcpu_info_placement(); } -static const struct pv_init_ops xen_init_ops __initdata = { +static const struct pv_init_ops xen_init_ops __initconst = { .banner = xen_banner, .reserve_memory = xen_reserve_memory, @@ -337,7 +337,7 @@ xen_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val) HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op); } -static const struct pv_iosapic_ops xen_iosapic_ops __initdata = { +static const struct pv_iosapic_ops xen_iosapic_ops __initconst = { .pcat_compat_init = xen_pcat_compat_init, .__get_irq_chip = xen_iosapic_get_irq_chip, -- cgit From e4aa7ca5a2e6d44f07ceb87d9448113f5b48a334 Mon Sep 17 00:00:00 2001 From: Alain Knaff Date: Thu, 19 Feb 2009 13:36:55 -0800 Subject: bzip2/lzma: don't stop search at first unconfigured compression Impact: Bugfix, avoids kernels which build but panic on boot Fix a bug in decompress.c : only scanned until the first non-configured compressor (with disastrous result especially if that was gzip.) Signed-off-by: Alain Knaff Signed-off-by: H. Peter Anvin --- lib/decompress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/decompress.c b/lib/decompress.c index 961f367320f..d2842f57167 100644 --- a/lib/decompress.c +++ b/lib/decompress.c @@ -43,7 +43,7 @@ decompress_fn decompress_method(const unsigned char *inbuf, int len, if (len < 2) return NULL; /* Need at least this much... */ - for (cf = compressed_formats; cf->decompressor; cf++) { + for (cf = compressed_formats; cf->name; cf++) { if (!memcmp(inbuf, cf->magic, 2)) break; -- cgit From ab59d3b70f7a47987f80e153d828363faec643fe Mon Sep 17 00:00:00 2001 From: Alain Knaff Date: Thu, 19 Feb 2009 13:39:21 -0800 Subject: bzip2/lzma: don't leave empty files around on failure Impact: Bugfix, silent build failures Fix a bug in gen_initramfs_list.sh: in case of failure, it left an empty output file behind, messing up the next make. Signed-off-by: Alain Knaff Signed-off-by: H. Peter Anvin --- scripts/gen_initramfs_list.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh index 41041e4923f..3eea8f15131 100644 --- a/scripts/gen_initramfs_list.sh +++ b/scripts/gen_initramfs_list.sh @@ -292,7 +292,8 @@ if [ ! -z ${output_file} ]; then if [ "${is_cpio_compressed}" = "compressed" ]; then cat ${cpio_tfile} > ${output_file} else - cat ${cpio_tfile} | ${compr} - > ${output_file} + (cat ${cpio_tfile} | ${compr} - > ${output_file}) \ + || (rm -f ${output_file} ; false) fi [ -z ${cpio_file} ] && rm ${cpio_tfile} fi -- cgit From ab76f3d771590d5c89faa3219559c5d3fc0ce0c2 Mon Sep 17 00:00:00 2001 From: Alain Knaff Date: Thu, 19 Feb 2009 13:43:51 -0800 Subject: bzip2/lzma: make internal initramfs compression configurable Impact: Avoids silent environment dependency Make builtin initramfs compression an explicit configurable. The previous version would pick a compression based on the binaries which were installed on the system, which could lead to unexpected results. It is now explicitly configured, and not having the appropriate binaries installed on the build host is simply an error. Signed-off-by: Alain Knaff Signed-off-by: H. Peter Anvin --- usr/Kconfig | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ usr/Makefile | 18 ++++++------------ 2 files changed, 68 insertions(+), 12 deletions(-) diff --git a/usr/Kconfig b/usr/Kconfig index a691a8f5898..43a3a0fe8f2 100644 --- a/usr/Kconfig +++ b/usr/Kconfig @@ -71,3 +71,65 @@ config RD_LZMA help Support loading of a lzma encoded initial ramdisk or cpio buffer If unsure, say N. + +choice + prompt "Built-in initramfs compression mode" + help + This setting is only meaningful if the INITRAMFS_SOURCE is + set. It decides by which algorithm the INITRAMFS_SOURCE will + be compressed. + Several compression algorithms are available, which differ + in efficiency, compression and decompression speed. + Compression speed is only relevant when building a kernel. + Decompression speed is relevant at each boot. + + If you have any problems with bzip2 or lzma compressed + initramfs, mail me (Alain Knaff) . + + High compression options are mostly useful for users who + are low on disk space (embedded systems), but for whom ram + size matters less. + + If in doubt, select 'gzip' + +config INITRAMFS_COMPRESSION_NONE + bool "None" + help + Do not compress the built-in initramfs at all. This may + sound wasteful in space, but, you should be aware that the + built-in initramfs will be compressed at a later stage + anyways along with the rest of the kernel, on those + architectures that support this. + However, not compressing the initramfs may lead to slightly + higher memory consumption during a short time at boot, while + both the cpio image and the unpacked filesystem image will + be present in memory simultaneously + +config INITRAMFS_COMPRESSION_GZIP + bool "Gzip" + depends on RD_GZIP + help + The old and tried gzip compression. Its compression ratio is + the poorest among the 3 choices; however its speed (both + compression and decompression) is the fastest. + +config INITRAMFS_COMPRESSION_BZIP2 + bool "Bzip2" + depends on RD_BZIP2 + help + Its compression ratio and speed is intermediate. + Decompression speed is slowest among the three. The initramfs + size is about 10% smaller with bzip2, in comparison to gzip. + Bzip2 uses a large amount of memory. For modern kernels you + will need at least 8MB RAM or more for booting. + +config INITRAMFS_COMPRESSION_LZMA + bool "LZMA" + depends on RD_LZMA + help + The most recent compression algorithm. + Its ratio is best, decompression speed is between the other + two. Compression is slowest. The initramfs size is about 33% + smaller with LZMA in comparison to gzip. + +endchoice diff --git a/usr/Makefile b/usr/Makefile index 451cdff7dff..b84894b3929 100644 --- a/usr/Makefile +++ b/usr/Makefile @@ -5,24 +5,18 @@ klibcdirs:; PHONY += klibcdirs -# Find out "preferred" ramdisk compressor. Order of preference is -# 1. bzip2 efficient, and likely to be present -# 2. gzip former default -# 3. lzma -# 4. none -# None of the above -suffix_y = - -# Lzma, but no gzip nor bzip2 -suffix_$(CONFIG_RD_LZMA) = .lzma +# No compression +suffix_$(CONFIG_INITRAMFS_COMPRESSION_NONE) = # Gzip, but no bzip2 -suffix_$(CONFIG_RD_GZIP) = .gz +suffix_$(CONFIG_INITRAMFS_COMPRESSION_GZIP) = .gz # Bzip2 -suffix_$(CONFIG_RD_BZIP2) = .bz2 +suffix_$(CONFIG_INITRAMFS_COMPRESSION_BZIP2) = .bz2 +# Lzma +suffix_$(CONFIG_INITRAMFS_COMPRESSION_LZMA) = .lzma # Generate builtin.o based on initramfs_data.o obj-$(CONFIG_BLK_DEV_INITRD) := initramfs_data$(suffix_y).o -- cgit From e35849e910a6543d37c0d13648ef166678d03565 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 12 Feb 2009 13:43:20 +0100 Subject: x86, mce: enable machine checks in 64-bit defconfig Impact: Low priority fix The 32-bit defconfig already had it enabled. And it's a pretty fundamental feature, so better enable it on 64 bits too. Signed-off-by: Andi Kleen Signed-off-by: H. Peter Anvin --- arch/x86/configs/x86_64_defconfig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig index 322dd2748fc..786ce5ac2ac 100644 --- a/arch/x86/configs/x86_64_defconfig +++ b/arch/x86/configs/x86_64_defconfig @@ -247,7 +247,10 @@ CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y -# CONFIG_X86_MCE is not set +CONFIG_X86_MCE=y +CONFIG_X86_NEW_MCE=y +CONFIG_X86_MCE_INTEL=y +CONFIG_X86_MCE_AMD=y # CONFIG_I8K is not set CONFIG_MICROCODE=y CONFIG_MICROCODE_OLD_INTERFACE=y -- cgit From 0d7482e3d76522157c9d741d79fce22c401fa0c5 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 17 Feb 2009 23:07:13 +0100 Subject: x86, mce: implement dynamic machine check banks support Impact: cleanup; making code future proof; memory saving on small systems This patch replaces the hardcoded max number of machine check banks with dynamic allocation depending on what the CPU reports. The sysfs data structures and the banks array are dynamically allocated. There is still a hard bank limit (128) because the mcelog protocol uses banks >= 128 as pseudo banks to escape other events. But we expect that 128 banks is beyond any reasonable CPU for now. This supersedes an earlier patch by Venki, but it solves the problem more completely by making the limit fully dynamic (up to the 128 boundary). This saves some memory on machines with less than 6 banks because they won't need sysdevs for unused ones and also allows to use sysfs to control these banks on possible future CPUs with more than 6 banks. This is an updated patch addressing Venki's comments. I also added in another patch from Thomas which fixed the error allocation path (that patch was previously separated) Cc: Venki Pallipadi Signed-off-by: Andi Kleen Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/mcheck/mce_64.c | 147 ++++++++++++++++++++++++++++-------- 1 file changed, 115 insertions(+), 32 deletions(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index 870d08deccf..2297730bb51 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include #include @@ -32,7 +34,12 @@ #include #define MISC_MCELOG_MINOR 227 -#define NR_SYSFS_BANKS 6 + +/* + * To support more than 128 would need to escape the predefined + * Linux defined extended banks first. + */ +#define MAX_NR_BANKS (MCE_EXTENDED_BANK - 1) atomic_t mce_entry; @@ -47,7 +54,7 @@ static int mce_dont_init; */ static int tolerant = 1; static int banks; -static unsigned long bank[NR_SYSFS_BANKS] = { [0 ... NR_SYSFS_BANKS-1] = ~0UL }; +static u64 *bank; static unsigned long notify_user; static int rip_msr; static int mce_bootlog = -1; @@ -212,7 +219,7 @@ void do_machine_check(struct pt_regs * regs, long error_code) barrier(); for (i = 0; i < banks; i++) { - if (i < NR_SYSFS_BANKS && !bank[i]) + if (!bank[i]) continue; m.misc = 0; @@ -446,37 +453,54 @@ __initcall(periodic_mcheck_init); /* * Initialize Machine Checks for a CPU. */ -static void mce_init(void *dummy) +static int mce_cap_init(void) { u64 cap; - int i; + unsigned b; rdmsrl(MSR_IA32_MCG_CAP, cap); - banks = cap & 0xff; - if (banks > MCE_EXTENDED_BANK) { - banks = MCE_EXTENDED_BANK; - printk(KERN_INFO "MCE: warning: using only %d banks\n", - MCE_EXTENDED_BANK); + b = cap & 0xff; + if (b > MAX_NR_BANKS) { + printk(KERN_WARNING + "MCE: Using only %u machine check banks out of %u\n", + MAX_NR_BANKS, b); + b = MAX_NR_BANKS; + } + + /* Don't support asymmetric configurations today */ + WARN_ON(banks != 0 && b != banks); + banks = b; + if (!bank) { + bank = kmalloc(banks * sizeof(u64), GFP_KERNEL); + if (!bank) + return -ENOMEM; + memset(bank, 0xff, banks * sizeof(u64)); } + /* Use accurate RIP reporting if available. */ if ((cap & (1<<9)) && ((cap >> 16) & 0xff) >= 9) rip_msr = MSR_IA32_MCG_EIP; + return 0; +} + +static void mce_init(void *dummy) +{ + u64 cap; + int i; + /* Log the machine checks left over from the previous reset. This also clears all registers */ do_machine_check(NULL, mce_bootlog ? -1 : -2); set_in_cr4(X86_CR4_MCE); + rdmsrl(MSR_IA32_MCG_CAP, cap); if (cap & MCG_CTL_P) wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff); for (i = 0; i < banks; i++) { - if (i < NR_SYSFS_BANKS) - wrmsrl(MSR_IA32_MC0_CTL+4*i, bank[i]); - else - wrmsrl(MSR_IA32_MC0_CTL+4*i, ~0UL); - + wrmsrl(MSR_IA32_MC0_CTL+4*i, bank[i]); wrmsrl(MSR_IA32_MC0_STATUS+4*i, 0); } } @@ -486,10 +510,10 @@ static void __cpuinit mce_cpu_quirks(struct cpuinfo_x86 *c) { /* This should be disabled by the BIOS, but isn't always */ if (c->x86_vendor == X86_VENDOR_AMD) { - if(c->x86 == 15) + if (c->x86 == 15 && banks > 4) /* disable GART TBL walk error reporting, which trips off incorrectly with the IOMMU & 3ware & Cerberus. */ - clear_bit(10, &bank[4]); + clear_bit(10, (unsigned long *)&bank[4]); if(c->x86 <= 17 && mce_bootlog < 0) /* Lots of broken BIOS around that don't clear them by default and leave crap in there. Don't log. */ @@ -532,11 +556,15 @@ static void mce_init_timer(void) */ void __cpuinit mcheck_init(struct cpuinfo_x86 *c) { - mce_cpu_quirks(c); - if (!mce_available(c)) return; + if (mce_cap_init() < 0) { + mce_dont_init = 1; + return; + } + mce_cpu_quirks(c); + mce_init(NULL); mce_cpu_features(c); mce_init_timer(); @@ -819,16 +847,26 @@ void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu) __cpuinit } \ static SYSDEV_ATTR(name, 0644, show_ ## name, set_ ## name); -/* - * TBD should generate these dynamically based on number of available banks. - * Have only 6 contol banks in /sysfs until then. - */ -ACCESSOR(bank0ctl,bank[0],mce_restart()) -ACCESSOR(bank1ctl,bank[1],mce_restart()) -ACCESSOR(bank2ctl,bank[2],mce_restart()) -ACCESSOR(bank3ctl,bank[3],mce_restart()) -ACCESSOR(bank4ctl,bank[4],mce_restart()) -ACCESSOR(bank5ctl,bank[5],mce_restart()) +static struct sysdev_attribute *bank_attrs; + +static ssize_t show_bank(struct sys_device *s, struct sysdev_attribute *attr, + char *buf) +{ + u64 b = bank[attr - bank_attrs]; + return sprintf(buf, "%Lx\n", b); +} + +static ssize_t set_bank(struct sys_device *s, struct sysdev_attribute *attr, + const char *buf, size_t siz) +{ + char *end; + u64 new = simple_strtoull(buf, &end, 0); + if (end == buf) + return -EINVAL; + bank[attr - bank_attrs] = new; + mce_restart(); + return end-buf; +} static ssize_t show_trigger(struct sys_device *s, struct sysdev_attribute *attr, char *buf) @@ -855,8 +893,6 @@ static SYSDEV_ATTR(trigger, 0644, show_trigger, set_trigger); static SYSDEV_INT_ATTR(tolerant, 0644, tolerant); ACCESSOR(check_interval,check_interval,mce_restart()) static struct sysdev_attribute *mce_attributes[] = { - &attr_bank0ctl, &attr_bank1ctl, &attr_bank2ctl, - &attr_bank3ctl, &attr_bank4ctl, &attr_bank5ctl, &attr_tolerant.attr, &attr_check_interval, &attr_trigger, NULL }; @@ -886,11 +922,22 @@ static __cpuinit int mce_create_device(unsigned int cpu) if (err) goto error; } + for (i = 0; i < banks; i++) { + err = sysdev_create_file(&per_cpu(device_mce, cpu), + &bank_attrs[i]); + if (err) + goto error2; + } cpu_set(cpu, mce_device_initialized); return 0; +error2: + while (--i >= 0) { + sysdev_remove_file(&per_cpu(device_mce, cpu), + &bank_attrs[i]); + } error: - while (i--) { + while (--i >= 0) { sysdev_remove_file(&per_cpu(device_mce,cpu), mce_attributes[i]); } @@ -909,6 +956,9 @@ static __cpuinit void mce_remove_device(unsigned int cpu) for (i = 0; mce_attributes[i]; i++) sysdev_remove_file(&per_cpu(device_mce,cpu), mce_attributes[i]); + for (i = 0; i < banks; i++) + sysdev_remove_file(&per_cpu(device_mce, cpu), + &bank_attrs[i]); sysdev_unregister(&per_cpu(device_mce,cpu)); cpu_clear(cpu, mce_device_initialized); } @@ -973,6 +1023,34 @@ static struct notifier_block mce_cpu_notifier __cpuinitdata = { .notifier_call = mce_cpu_callback, }; +static __init int mce_init_banks(void) +{ + int i; + + bank_attrs = kzalloc(sizeof(struct sysdev_attribute) * banks, + GFP_KERNEL); + if (!bank_attrs) + return -ENOMEM; + + for (i = 0; i < banks; i++) { + struct sysdev_attribute *a = &bank_attrs[i]; + a->attr.name = kasprintf(GFP_KERNEL, "bank%d", i); + if (!a->attr.name) + goto nomem; + a->attr.mode = 0644; + a->show = show_bank; + a->store = set_bank; + } + return 0; + +nomem: + while (--i >= 0) + kfree(bank_attrs[i].attr.name); + kfree(bank_attrs); + bank_attrs = NULL; + return -ENOMEM; +} + static __init int mce_init_device(void) { int err; @@ -980,6 +1058,11 @@ static __init int mce_init_device(void) if (!mce_available(&boot_cpu_data)) return -EIO; + + err = mce_init_banks(); + if (err) + return err; + err = sysdev_class_register(&mce_sysclass); if (err) return err; -- cgit From b5f2fa4ea00a179ac1c2ff342ceeee261dd75e53 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 12 Feb 2009 13:43:22 +0100 Subject: x86, mce: factor out duplicated struct mce setup into one function Impact: cleanup This merely factors out duplicated code to set up the initial struct mce state into a single function. Signed-off-by: Andi Kleen Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/mce.h | 3 ++- arch/x86/kernel/cpu/mcheck/mce_64.c | 23 ++++++++++++++--------- arch/x86/kernel/cpu/mcheck/mce_amd_64.c | 4 +--- arch/x86/kernel/cpu/mcheck/mce_intel_64.c | 2 +- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index 5522273a3ad..048b71d9387 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h @@ -90,6 +90,7 @@ extern int mce_disabled; #include +void mce_setup(struct mce *m); void mce_log(struct mce *m); DECLARE_PER_CPU(struct sys_device, device_mce); extern void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu); @@ -106,7 +107,7 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c); static inline void mce_amd_feature_init(struct cpuinfo_x86 *c) { } #endif -void mce_log_therm_throt_event(unsigned int cpu, __u64 status); +void mce_log_therm_throt_event(__u64 status); extern atomic_t mce_entry; diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index 2297730bb51..fed875742b1 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -65,6 +65,14 @@ static char *trigger_argv[2] = { trigger, NULL }; static DECLARE_WAIT_QUEUE_HEAD(mce_wait); +/* Do initial initialization of a struct mce */ +void mce_setup(struct mce *m) +{ + memset(m, 0, sizeof(struct mce)); + m->cpu = smp_processor_id(); + rdtscll(m->tsc); +} + /* * Lockless MCE logging infrastructure. * This avoids deadlocks on printk locks without having to break locks. Also @@ -208,8 +216,8 @@ void do_machine_check(struct pt_regs * regs, long error_code) || !banks) goto out2; - memset(&m, 0, sizeof(struct mce)); - m.cpu = smp_processor_id(); + mce_setup(&m); + rdmsrl(MSR_IA32_MCG_STATUS, m.mcgstatus); /* if the restart IP is not valid, we're done for */ if (!(m.mcgstatus & MCG_STATUS_RIPV)) @@ -225,7 +233,6 @@ void do_machine_check(struct pt_regs * regs, long error_code) m.misc = 0; m.addr = 0; m.bank = i; - m.tsc = 0; rdmsrl(MSR_IA32_MC0_STATUS + i*4, m.status); if ((m.status & MCI_STATUS_VAL) == 0) @@ -252,8 +259,8 @@ void do_machine_check(struct pt_regs * regs, long error_code) rdmsrl(MSR_IA32_MC0_ADDR + i*4, m.addr); mce_get_rip(&m, regs); - if (error_code >= 0) - rdtscll(m.tsc); + if (error_code < 0) + m.tsc = 0; if (error_code != -2) mce_log(&m); @@ -341,15 +348,13 @@ void do_machine_check(struct pt_regs * regs, long error_code) * and historically has been the register value of the * MSR_IA32_THERMAL_STATUS (Intel) msr. */ -void mce_log_therm_throt_event(unsigned int cpu, __u64 status) +void mce_log_therm_throt_event(__u64 status) { struct mce m; - memset(&m, 0, sizeof(m)); - m.cpu = cpu; + mce_setup(&m); m.bank = MCE_THERMAL_BANK; m.status = status; - rdtscll(m.tsc); mce_log(&m); } #endif /* CONFIG_X86_MCE_INTEL */ diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c index 8ae8c4ff094..75d9dd25e3d 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c @@ -197,9 +197,7 @@ asmlinkage void mce_threshold_interrupt(void) exit_idle(); irq_enter(); - memset(&m, 0, sizeof(m)); - rdtscll(m.tsc); - m.cpu = smp_processor_id(); + mce_setup(&m); /* assume first bank caused it */ for (bank = 0; bank < NR_BANKS; ++bank) { diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c index 4b48f251fd3..7f7f1015ef1 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c @@ -24,7 +24,7 @@ asmlinkage void smp_thermal_interrupt(void) rdmsrl(MSR_IA32_THERM_STATUS, msr_val); if (therm_throt_process(msr_val & 1)) - mce_log_therm_throt_event(smp_processor_id(), msr_val); + mce_log_therm_throt_event(msr_val); inc_irq_stat(irq_thermal_count); irq_exit(); -- cgit From b79109c3bbcf52cac5103979b283b9e5df4e796c Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 12 Feb 2009 13:43:23 +0100 Subject: x86, mce: separate correct machine check poller and fatal exception handler Impact: cleanup, performance enhancement The machine check poller is diverging more and more from the fatal exception handler. Instead of adding more special cases separate the code paths completely. The corrected poll path is actually quite simple, and this doesn't result in much code duplication. This makes both handlers much easier to read and results in cleaner code flow. The exception handler now only needs to care about uncorrected errors, which also simplifies the handling of multiple errors. The corrected poller also now always runs in standard interrupt context and does not need to do anything special to handle NMI context. Minor behaviour changes: - MCG status is now not cleared on polling. - Only the banks which had corrected errors get cleared on polling - The exception handler only clears banks with errors now v2: Forward port to new patch order. Add "uc" argument. Signed-off-by: Andi Kleen Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/mce.h | 7 ++ arch/x86/kernel/cpu/mcheck/mce_64.c | 129 ++++++++++++++++++++++++++------ arch/x86/kernel/cpu/mcheck/mce_amd_64.c | 2 +- 3 files changed, 116 insertions(+), 22 deletions(-) diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index 048b71d9387..225cdb5d2bf 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h @@ -112,6 +112,13 @@ void mce_log_therm_throt_event(__u64 status); extern atomic_t mce_entry; extern void do_machine_check(struct pt_regs *, long); + +enum mcp_flags { + MCP_TIMESTAMP = (1 << 0), /* log time stamp */ + MCP_UC = (1 << 1), /* log uncorrected errors */ +}; +extern void machine_check_poll(enum mcp_flags flags); + extern int mce_notify_user(void); #endif /* !CONFIG_X86_32 */ diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index fed875742b1..268b05edade 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -3,6 +3,8 @@ * K8 parts Copyright 2002,2003 Andi Kleen, SuSE Labs. * Rest from unknown author(s). * 2004 Andi Kleen. Rewrote most of it. + * Copyright 2008 Intel Corporation + * Author: Andi Kleen */ #include @@ -189,7 +191,77 @@ static inline void mce_get_rip(struct mce *m, struct pt_regs *regs) } /* - * The actual machine check handler + * Poll for corrected events or events that happened before reset. + * Those are just logged through /dev/mcelog. + * + * This is executed in standard interrupt context. + */ +void machine_check_poll(enum mcp_flags flags) +{ + struct mce m; + int i; + + mce_setup(&m); + + rdmsrl(MSR_IA32_MCG_STATUS, m.mcgstatus); + for (i = 0; i < banks; i++) { + if (!bank[i]) + continue; + + m.misc = 0; + m.addr = 0; + m.bank = i; + m.tsc = 0; + + barrier(); + rdmsrl(MSR_IA32_MC0_STATUS + i*4, m.status); + if (!(m.status & MCI_STATUS_VAL)) + continue; + + /* + * Uncorrected events are handled by the exception handler + * when it is enabled. But when the exception is disabled log + * everything. + * + * TBD do the same check for MCI_STATUS_EN here? + */ + if ((m.status & MCI_STATUS_UC) && !(flags & MCP_UC)) + continue; + + if (m.status & MCI_STATUS_MISCV) + rdmsrl(MSR_IA32_MC0_MISC + i*4, m.misc); + if (m.status & MCI_STATUS_ADDRV) + rdmsrl(MSR_IA32_MC0_ADDR + i*4, m.addr); + + if (!(flags & MCP_TIMESTAMP)) + m.tsc = 0; + /* + * Don't get the IP here because it's unlikely to + * have anything to do with the actual error location. + */ + + mce_log(&m); + add_taint(TAINT_MACHINE_CHECK); + + /* + * Clear state for this bank. + */ + wrmsrl(MSR_IA32_MC0_STATUS+4*i, 0); + } + + /* + * Don't clear MCG_STATUS here because it's only defined for + * exceptions. + */ +} + +/* + * The actual machine check handler. This only handles real + * exceptions when something got corrupted coming in through int 18. + * + * This is executed in NMI context not subject to normal locking rules. This + * implies that most kernel services cannot be safely used. Don't even + * think about putting a printk in there! */ void do_machine_check(struct pt_regs * regs, long error_code) { @@ -207,13 +279,14 @@ void do_machine_check(struct pt_regs * regs, long error_code) * error. */ int kill_it = 0; + DECLARE_BITMAP(toclear, MAX_NR_BANKS); atomic_inc(&mce_entry); - if ((regs - && notify_die(DIE_NMI, "machine check", regs, error_code, + if (notify_die(DIE_NMI, "machine check", regs, error_code, 18, SIGKILL) == NOTIFY_STOP) - || !banks) + goto out2; + if (!banks) goto out2; mce_setup(&m); @@ -227,6 +300,7 @@ void do_machine_check(struct pt_regs * regs, long error_code) barrier(); for (i = 0; i < banks; i++) { + __clear_bit(i, toclear); if (!bank[i]) continue; @@ -238,6 +312,20 @@ void do_machine_check(struct pt_regs * regs, long error_code) if ((m.status & MCI_STATUS_VAL) == 0) continue; + /* + * Non uncorrected errors are handled by machine_check_poll + * Leave them alone. + */ + if ((m.status & MCI_STATUS_UC) == 0) + continue; + + /* + * Set taint even when machine check was not enabled. + */ + add_taint(TAINT_MACHINE_CHECK); + + __set_bit(i, toclear); + if (m.status & MCI_STATUS_EN) { /* if PCC was set, there's no way out */ no_way_out |= !!(m.status & MCI_STATUS_PCC); @@ -251,6 +339,12 @@ void do_machine_check(struct pt_regs * regs, long error_code) no_way_out = 1; kill_it = 1; } + } else { + /* + * Machine check event was not enabled. Clear, but + * ignore. + */ + continue; } if (m.status & MCI_STATUS_MISCV) @@ -259,10 +353,7 @@ void do_machine_check(struct pt_regs * regs, long error_code) rdmsrl(MSR_IA32_MC0_ADDR + i*4, m.addr); mce_get_rip(&m, regs); - if (error_code < 0) - m.tsc = 0; - if (error_code != -2) - mce_log(&m); + mce_log(&m); /* Did this bank cause the exception? */ /* Assume that the bank with uncorrectable errors did it, @@ -271,14 +362,8 @@ void do_machine_check(struct pt_regs * regs, long error_code) panicm = m; panicm_found = 1; } - - add_taint(TAINT_MACHINE_CHECK); } - /* Never do anything final in the polling timer */ - if (!regs) - goto out; - /* If we didn't find an uncorrectable error, pick the last one (shouldn't happen, just being safe). */ if (!panicm_found) @@ -325,10 +410,11 @@ void do_machine_check(struct pt_regs * regs, long error_code) /* notify userspace ASAP */ set_thread_flag(TIF_MCE_NOTIFY); - out: /* the last thing we do is clear state */ - for (i = 0; i < banks; i++) - wrmsrl(MSR_IA32_MC0_STATUS+4*i, 0); + for (i = 0; i < banks; i++) { + if (test_bit(i, toclear)) + wrmsrl(MSR_IA32_MC0_STATUS+4*i, 0); + } wrmsrl(MSR_IA32_MCG_STATUS, 0); out2: atomic_dec(&mce_entry); @@ -377,7 +463,7 @@ static void mcheck_timer(unsigned long data) WARN_ON(smp_processor_id() != data); if (mce_available(¤t_cpu_data)) - do_machine_check(NULL, 0); + machine_check_poll(MCP_TIMESTAMP); /* * Alert userspace if needed. If we logged an MCE, reduce the @@ -494,9 +580,10 @@ static void mce_init(void *dummy) u64 cap; int i; - /* Log the machine checks left over from the previous reset. - This also clears all registers */ - do_machine_check(NULL, mce_bootlog ? -1 : -2); + /* + * Log the machine checks left over from the previous reset. + */ + machine_check_poll(MCP_UC); set_in_cr4(X86_CR4_MCE); diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c index 75d9dd25e3d..0069c653f4e 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c @@ -231,7 +231,7 @@ asmlinkage void mce_threshold_interrupt(void) /* Log the machine check that caused the threshold event. */ - do_machine_check(NULL, 0); + machine_check_poll(MCP_TIMESTAMP); if (high & MASK_OVERFLOW_HI) { rdmsrl(address, m.misc); -- cgit From f6d1826dfad0d15fd14a455facc80b91f2ee642f Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 19 Feb 2009 15:44:58 -0800 Subject: x86, mce: use %ll instead of %L for 64-bit numbers Impact: Cleanup The standard spelling of a printf pattern for long long is "ll", not "L", which is for long double. Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/mcheck/mce_64.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index 268b05edade..60a114ca14f 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -136,11 +136,11 @@ static void print_mce(struct mce *m) print_symbol("{%s}", m->ip); printk("\n"); } - printk(KERN_EMERG "TSC %Lx ", m->tsc); + printk(KERN_EMERG "TSC %llx ", m->tsc); if (m->addr) - printk("ADDR %Lx ", m->addr); + printk("ADDR %llx ", m->addr); if (m->misc) - printk("MISC %Lx ", m->misc); + printk("MISC %llx ", m->misc); printk("\n"); printk(KERN_EMERG "This is not a software problem!\n"); printk(KERN_EMERG "Run through mcelog --ascii to decode " @@ -945,7 +945,7 @@ static ssize_t show_bank(struct sys_device *s, struct sysdev_attribute *attr, char *buf) { u64 b = bank[attr - bank_attrs]; - return sprintf(buf, "%Lx\n", b); + return sprintf(buf, "%llx\n", b); } static ssize_t set_bank(struct sys_device *s, struct sysdev_attribute *attr, -- cgit From 005568be363b90c9333c3bcbc1e7a53922816322 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Mon, 9 Feb 2009 22:02:42 +0100 Subject: drm/i915: Storage class should be before const qualifier The C99 specification states in section 6.11.5: The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature. Signed-off-by: Tobias Klauser Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/intel_sdvo.c | 2 +- drivers/gpu/drm/i915/intel_tv.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index a30508b639b..fbe6f3931b1 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -193,7 +193,7 @@ static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, #define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd} /** Mapping of command numbers to names, for debug output */ -const static struct _sdvo_cmd_name { +static const struct _sdvo_cmd_name { u8 cmd; char *name; } sdvo_cmd_names[] = { diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index fbb35dc56f5..56485d67369 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -411,7 +411,7 @@ struct tv_mode { * These values account for -1s required. */ -const static struct tv_mode tv_modes[] = { +static const struct tv_mode tv_modes[] = { { .name = "NTSC-M", .clock = 107520, -- cgit From ad45aa9e6e010283bbd8cf0c6309866233e113f2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 9 Feb 2009 11:31:41 +0000 Subject: drm: Potential use-after-free on error path. Remove the member from the hash table before we free the structure! Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 6915fb82d0b..308fe1e207f 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -104,8 +104,8 @@ drm_gem_init(struct drm_device *dev) if (drm_mm_init(&mm->offset_manager, DRM_FILE_PAGE_OFFSET_START, DRM_FILE_PAGE_OFFSET_SIZE)) { - drm_free(mm, sizeof(struct drm_gem_mm), DRM_MEM_MM); drm_ht_remove(&mm->offset_hash); + drm_free(mm, sizeof(struct drm_gem_mm), DRM_MEM_MM); return -ENOMEM; } -- cgit From 3e49c4f4cf786b70bbc369b99e590de4bebac1b3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 9 Feb 2009 11:31:41 +0000 Subject: drm: Free the object ref on error. Ensure that the object is unreferenced if we fail to allocate during drm_gem_flink_ioctl(). Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_gem.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 308fe1e207f..e5a8ebf9a66 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -295,8 +295,10 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data, return -EBADF; again: - if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0) - return -ENOMEM; + if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0) { + ret = -ENOMEM; + goto err; + } spin_lock(&dev->object_name_lock); if (obj->name) { @@ -310,12 +312,8 @@ again: if (ret == -EAGAIN) goto again; - if (ret != 0) { - mutex_lock(&dev->struct_mutex); - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - return ret; - } + if (ret != 0) + goto err; /* * Leave the reference from the lookup around as the @@ -324,6 +322,12 @@ again: args->name = (uint64_t) obj->name; return 0; + +err: + mutex_lock(&dev->struct_mutex); + drm_gem_object_unreference(obj); + mutex_unlock(&dev->struct_mutex); + return ret; } /** -- cgit From a198bc80ae59cf7c6da93bc8bd017b2198148ed7 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 6 Feb 2009 16:55:20 +0000 Subject: drm/i915: Cleanup trivial leak on execbuffer error path. Also spotted by Owain Ainsworth. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/i915_gem.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 81857665409..b79ced8f3c6 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2480,13 +2480,15 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, if (dev_priv->mm.wedged) { DRM_ERROR("Execbuf while wedged\n"); mutex_unlock(&dev->struct_mutex); - return -EIO; + ret = -EIO; + goto pre_mutex_err; } if (dev_priv->mm.suspended) { DRM_ERROR("Execbuf while VT-switched.\n"); mutex_unlock(&dev->struct_mutex); - return -EBUSY; + ret = -EBUSY; + goto pre_mutex_err; } /* Look up object handles */ -- cgit From d6873102fd36c577f88174d8bd50f1d51645fc51 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 8 Feb 2009 19:07:51 +0000 Subject: drm/i915: hold mutex for unreference() in i915_gem_tiling.c Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/i915_gem_tiling.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index fa1685cba84..7fb4191ef93 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -299,9 +299,8 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, } obj_priv->stride = args->stride; - mutex_unlock(&dev->struct_mutex); - drm_gem_object_unreference(obj); + mutex_unlock(&dev->struct_mutex); return 0; } @@ -340,9 +339,8 @@ i915_gem_get_tiling(struct drm_device *dev, void *data, DRM_ERROR("unknown tiling mode\n"); } - mutex_unlock(&dev->struct_mutex); - drm_gem_object_unreference(obj); + mutex_unlock(&dev->struct_mutex); return 0; } -- cgit From 96dec61d563fb8dff2c8427fdf85327a95b65c74 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 8 Feb 2009 19:08:04 +0000 Subject: drm/i915: refleak along pin() error path. A missing unreference if the user calls pin() a second time on a pinned buffer. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/i915_gem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b79ced8f3c6..55f4c060fa0 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2755,6 +2755,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data, if (obj_priv->pin_filp != NULL && obj_priv->pin_filp != file_priv) { DRM_ERROR("Already pinned in i915_gem_pin_ioctl(): %d\n", args->handle); + drm_gem_object_unreference(obj); mutex_unlock(&dev->struct_mutex); return -EINVAL; } -- cgit From a35f2e2b83a789e189a501ebd722bc9a1310eb05 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 6 Feb 2009 17:48:09 -0800 Subject: drm/i915: Fix potential AB-BA deadlock in i915_gem_execbuffer() Lockdep warns that i915_gem_execbuffer() can trigger a page fault (which takes mmap_sem) while holding dev->struct_mutex, while drm_vm_open() (which is called with mmap_sem already held) takes dev->struct_mutex. So this is a potential AB-BA deadlock. The way that i915_gem_execbuffer() triggers a page fault is by doing copy_to_user() when returning new buffer offsets back to userspace; however there is no reason to hold the struct_mutex when doing this copy, since what is being copied is the contents of an array private to i915_gem_execbuffer() anyway. So we can fix the potential deadlock (and get rid of the lockdep warning) by simply moving the copy_to_user() outside of where struct_mutex is held. This fixes . Reported-by: Jesse Brandeburg Tested-by: Jesse Brandeburg Signed-off-by: Roland Dreier Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/i915_gem.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 55f4c060fa0..ff0d94dd355 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2634,15 +2634,6 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, i915_verify_inactive(dev, __FILE__, __LINE__); - /* Copy the new buffer offsets back to the user's exec list. */ - ret = copy_to_user((struct drm_i915_relocation_entry __user *) - (uintptr_t) args->buffers_ptr, - exec_list, - sizeof(*exec_list) * args->buffer_count); - if (ret) - DRM_ERROR("failed to copy %d exec entries " - "back to user (%d)\n", - args->buffer_count, ret); err: for (i = 0; i < pinned; i++) i915_gem_object_unpin(object_list[i]); @@ -2652,6 +2643,18 @@ err: mutex_unlock(&dev->struct_mutex); + if (!ret) { + /* Copy the new buffer offsets back to the user's exec list. */ + ret = copy_to_user((struct drm_i915_relocation_entry __user *) + (uintptr_t) args->buffers_ptr, + exec_list, + sizeof(*exec_list) * args->buffer_count); + if (ret) + DRM_ERROR("failed to copy %d exec entries " + "back to user (%d)\n", + args->buffer_count, ret); + } + pre_mutex_err: drm_free(object_list, sizeof(*object_list) * args->buffer_count, DRM_MEM_DRIVER); -- cgit From 8d59bae5d9aae10ab230561519bfb97962509bcb Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 11 Feb 2009 14:26:28 +0000 Subject: drm: Do not leak a new reference for flink() on an existing name The name table should only hold a single reference, so avoid leaking additional references for secondary calls to flink(). Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_gem.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index e5a8ebf9a66..5dad6b9d0de 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -301,27 +301,25 @@ again: } spin_lock(&dev->object_name_lock); - if (obj->name) { - args->name = obj->name; + if (!obj->name) { + ret = idr_get_new_above(&dev->object_name_idr, obj, 1, + &obj->name); + args->name = (uint64_t) obj->name; spin_unlock(&dev->object_name_lock); - return 0; - } - ret = idr_get_new_above(&dev->object_name_idr, obj, 1, - &obj->name); - spin_unlock(&dev->object_name_lock); - if (ret == -EAGAIN) - goto again; - if (ret != 0) - goto err; + if (ret == -EAGAIN) + goto again; - /* - * Leave the reference from the lookup around as the - * name table now holds one - */ - args->name = (uint64_t) obj->name; + if (ret != 0) + goto err; - return 0; + /* Allocate a reference for the name table. */ + drm_gem_object_reference(obj); + } else { + args->name = (uint64_t) obj->name; + spin_unlock(&dev->object_name_lock); + ret = 0; + } err: mutex_lock(&dev->struct_mutex); @@ -452,6 +450,7 @@ drm_gem_object_handle_free(struct kref *kref) spin_lock(&dev->object_name_lock); if (obj->name) { idr_remove(&dev->object_name_idr, obj->name); + obj->name = 0; spin_unlock(&dev->object_name_lock); /* * The object name held a reference to this object, drop -- cgit From 2ebed176a7ee126448d34fc336afb2ea0238c280 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 11 Feb 2009 14:26:30 +0000 Subject: drm/i915: Set framebuffer alignment based upon the fence constraints. Set the request alignment to 0, and leave it up to i915_gem_object_pin() to set the appropriate alignment to match the fence covering the object. Eric Anholt mentioned that the pinning code is meant to choose the maximum of the request alignment and that of the fence covering the object... However currently, the pinning code will only apply the fence constraints if the supplied alignment is 0. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/intel_display.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index bbdd72909a1..a440d0db5cc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -377,10 +377,8 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, alignment = 64 * 1024; break; case I915_TILING_X: - if (IS_I9XX(dev)) - alignment = 1024 * 1024; - else - alignment = 512 * 1024; + /* pin() will align the object as required by fence */ + alignment = 0; break; case I915_TILING_Y: /* FIXME: Is this true? */ -- cgit From 13af10627676879d1b20ee3cdba9a28f0906dd98 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 11 Feb 2009 14:26:31 +0000 Subject: drm/i915: Release and unlock on mmap_gtt error path. We failed to unlock the mutex after failing to create the mmap offset. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/i915_gem.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index ff0d94dd355..f565b6afe41 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -758,8 +758,11 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, if (!obj_priv->mmap_offset) { ret = i915_gem_create_mmap_offset(obj); - if (ret) + if (ret) { + drm_gem_object_unreference(obj); + mutex_unlock(&dev->struct_mutex); return ret; + } } args->offset = obj_priv->mmap_offset; -- cgit From 491152b8778d7d290579c989e8607892accde920 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 11 Feb 2009 14:26:32 +0000 Subject: drm/i915: unpin for an invalid memory domain. A missing unreference and unpin after rejecting the relocation for an invalid memory domain. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/i915_gem.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index f565b6afe41..0bec4e6d336 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2254,6 +2254,8 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, (int) reloc.offset, reloc.read_domains, reloc.write_domain); + drm_gem_object_unreference(target_obj); + i915_gem_object_unpin(obj); return -EINVAL; } -- cgit From 47ed185a777632063d2748f59d14ec6fdeb26f67 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 11 Feb 2009 14:26:33 +0000 Subject: drm/i915: Unpin the ringbuffer if we fail to ioremap it. A missing unpin on the error path. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/i915_gem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0bec4e6d336..e5fc664337f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3159,6 +3159,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev) if (ring->map.handle == NULL) { DRM_ERROR("Failed to map ringbuffer.\n"); memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); + i915_gem_object_unpin(obj); drm_gem_object_unreference(obj); return -EINVAL; } -- cgit From 3eb2ee77b0b6b7b2c10308d7b46d2a459fb5be10 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 11 Feb 2009 14:26:34 +0000 Subject: drm/i915: Unpin the hws if we fail to kmap. A missing unpin on the error path. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/i915_gem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e5fc664337f..fd4b4e268a2 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3106,6 +3106,7 @@ i915_gem_init_hws(struct drm_device *dev) if (dev_priv->hw_status_page == NULL) { DRM_ERROR("Failed to map status page.\n"); memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); + i915_gem_object_unpin(obj); drm_gem_object_unreference(obj); return -EINVAL; } -- cgit From b4476f52e43fadcb9402723a1a55ba1308757525 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 11 Feb 2009 14:26:36 +0000 Subject: drm/i915: Unpin the fb on error during construction. If we fail whilst constructing the fb, then we need to unpin it as well. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/intel_fb.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index afd1217b8a0..b7f0ebe9f81 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c @@ -473,7 +473,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, ret = intel_framebuffer_create(dev, &mode_cmd, &fb, fbo); if (ret) { DRM_ERROR("failed to allocate fb.\n"); - goto out_unref; + goto out_unpin; } list_add(&fb->filp_head, &dev->mode_config.fb_kernel_list); @@ -484,7 +484,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, info = framebuffer_alloc(sizeof(struct intelfb_par), device); if (!info) { ret = -ENOMEM; - goto out_unref; + goto out_unpin; } par = info->par; @@ -513,7 +513,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, size); if (!info->screen_base) { ret = -ENOSPC; - goto out_unref; + goto out_unpin; } info->screen_size = size; @@ -608,6 +608,8 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, mutex_unlock(&dev->struct_mutex); return 0; +out_unpin: + i915_gem_object_unpin(fbo); out_unref: drm_gem_object_unreference(fbo); mutex_unlock(&dev->struct_mutex); -- cgit From ea39f835168f60b01e59d0f348da25d297e7cf94 Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Thu, 12 Feb 2009 14:37:56 -0500 Subject: drm: Release user fbs in drm_release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoids leaking fbs and associated buffers on release. Signed-off-by: Kristian Høgsberg Tested-by: Tested-by: Chris Wilson Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc.c | 3 +-- drivers/gpu/drm/drm_fops.c | 3 +++ include/drm/drm_crtc.h | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index bfce0992fef..94a76887173 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1741,9 +1741,8 @@ out: * RETURNS: * Zero on success, errno on failure. */ -void drm_fb_release(struct file *filp) +void drm_fb_release(struct drm_file *priv) { - struct drm_file *priv = filp->private_data; struct drm_device *dev = priv->minor->dev; struct drm_framebuffer *fb, *tfb; diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index b06a5371585..6c020fe5431 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -457,6 +457,9 @@ int drm_release(struct inode *inode, struct file *filp) if (dev->driver->driver_features & DRIVER_GEM) drm_gem_release(dev, file_priv); + if (dev->driver->driver_features & DRIVER_MODESET) + drm_fb_release(file_priv); + mutex_lock(&dev->ctxlist_mutex); if (!list_empty(&dev->ctxlist)) { struct drm_ctx_list *pos, *n; diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index d54de24bf37..5ded1acfb54 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -609,7 +609,7 @@ extern char *drm_get_dvi_i_subconnector_name(int val); extern char *drm_get_dvi_i_select_name(int val); extern char *drm_get_tv_subconnector_name(int val); extern char *drm_get_tv_select_name(int val); -extern void drm_fb_release(struct file *filp); +extern void drm_fb_release(struct drm_file *file_priv); extern int drm_mode_group_init_legacy_group(struct drm_device *dev, struct drm_mode_group *group); extern struct edid *drm_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter); -- cgit From 67eabc0553a32c491fdb392ff2358a0384562050 Mon Sep 17 00:00:00 2001 From: Steve Aarnio Date: Thu, 12 Feb 2009 11:34:02 -0800 Subject: drm/i915: Don't add panel_fixed_mode to the probed modes list at LVDS init. In the case where no EDID data is read from the device, adding the panel_fixed_mode pointer to the probed modes list causes data corruption. If the panel_fixed_mode pointer is added to the probed modes list at init time, a copy of the mode is added again at drm_get_modes() request time. Then, the panel_fixed_mode pointer is freed because it is seen as a duplicate mode. Unfortunately, this pointer is still stored and used in mode_fixup(). Because the panel_fixed_mode data is copied and returned at drm_get_modes() time, it is unnecessary to add this information at init time. Signed-off-by: Steve Aarnio Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/intel_lvds.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 6d4f9126535..0d211af9885 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -481,8 +481,6 @@ void intel_lvds_init(struct drm_device *dev) if (dev_priv->panel_fixed_mode) { dev_priv->panel_fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; - drm_mode_probed_add(connector, - dev_priv->panel_fixed_mode); goto out; } } -- cgit From 85a7bb98582b60b7e9130159d2464eb0bbac13f7 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 11 Feb 2009 14:52:44 +0000 Subject: drm/i915: Cleanup the hws on ringbuffer constrution failure. If we fail to create the ringbuffer, then we need to cleanup the allocated hws. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/i915_gem.c | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index fd4b4e268a2..07885817883 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3119,6 +3119,27 @@ i915_gem_init_hws(struct drm_device *dev) return 0; } +static void +i915_gem_cleanup_hws(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_gem_object *obj = dev_priv->hws_obj; + struct drm_i915_gem_object *obj_priv = obj->driver_private; + + if (dev_priv->hws_obj == NULL) + return; + + kunmap(obj_priv->page_list[0]); + i915_gem_object_unpin(obj); + drm_gem_object_unreference(obj); + dev_priv->hws_obj = NULL; + memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); + dev_priv->hw_status_page = NULL; + + /* Write high address into HWS_PGA when disabling. */ + I915_WRITE(HWS_PGA, 0x1ffff000); +} + int i915_gem_init_ringbuffer(struct drm_device *dev) { @@ -3136,6 +3157,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev) obj = drm_gem_object_alloc(dev, 128 * 1024); if (obj == NULL) { DRM_ERROR("Failed to allocate ringbuffer\n"); + i915_gem_cleanup_hws(dev); return -ENOMEM; } obj_priv = obj->driver_private; @@ -3143,6 +3165,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev) ret = i915_gem_object_pin(obj, 4096); if (ret != 0) { drm_gem_object_unreference(obj); + i915_gem_cleanup_hws(dev); return ret; } @@ -3162,6 +3185,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev) memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); i915_gem_object_unpin(obj); drm_gem_object_unreference(obj); + i915_gem_cleanup_hws(dev); return -EINVAL; } ring->ring_obj = obj; @@ -3241,20 +3265,7 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev) dev_priv->ring.ring_obj = NULL; memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); - if (dev_priv->hws_obj != NULL) { - struct drm_gem_object *obj = dev_priv->hws_obj; - struct drm_i915_gem_object *obj_priv = obj->driver_private; - - kunmap(obj_priv->page_list[0]); - i915_gem_object_unpin(obj); - drm_gem_object_unreference(obj); - dev_priv->hws_obj = NULL; - memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); - dev_priv->hw_status_page = NULL; - - /* Write high address into HWS_PGA when disabling. */ - I915_WRITE(HWS_PGA, 0x1ffff000); - } + i915_gem_cleanup_hws(dev); } int -- cgit From e62fb64e6187ea9d8bcedb17ccaa045ed92d4b55 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 11 Feb 2009 16:39:21 +0000 Subject: drm: Check for a NULL encoder when reverting on error path We need to skip the connectors with a NULL encoder to match the success path and avoid an OOPS. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc_helper.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 964c5eb1fad..8ba22c039a1 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -775,8 +775,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) fail_set_mode: set->crtc->enabled = save_enabled; count = 0; - list_for_each_entry(connector, &dev->mode_config.connector_list, head) + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + if (!connector->encoder) + continue; + connector->encoder->crtc = save_crtcs[count++]; + } fail_no_encoder: kfree(save_crtcs); count = 0; -- cgit From 5c3b82e2b229e78eb32f4ea12d16f3ebeeab3fc7 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 11 Feb 2009 13:25:09 +0000 Subject: drm: Propagate failure from setting crtc base. Check the error paths within intel_pipe_set_base() to first cleanup and then report back the error. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc_helper.c | 15 +++++-- drivers/gpu/drm/i915/intel_display.c | 84 +++++++++++++++++++++++------------- include/drm/drm_crtc_helper.h | 10 ++--- 3 files changed, 69 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 8ba22c039a1..733028b4d45 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -512,8 +512,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, if (drm_mode_equal(&saved_mode, &crtc->mode)) { if (saved_x != crtc->x || saved_y != crtc->y || depth_changed || bpp_changed) { - crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y, - old_fb); + ret = !crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y, + old_fb); goto done; } } @@ -552,7 +552,9 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, /* Set up the DPLL and any encoders state that needs to adjust or depend * on the DPLL. */ - crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb); + ret = !crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb); + if (!ret) + goto done; list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { @@ -752,6 +754,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) if (!drm_crtc_helper_set_mode(set->crtc, set->mode, set->x, set->y, old_fb)) { + DRM_ERROR("failed to set mode on crtc %p\n", + set->crtc); ret = -EINVAL; goto fail_set_mode; } @@ -765,7 +769,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) old_fb = set->crtc->fb; if (set->crtc->fb != set->fb) set->crtc->fb = set->fb; - crtc_funcs->mode_set_base(set->crtc, set->x, set->y, old_fb); + ret = crtc_funcs->mode_set_base(set->crtc, + set->x, set->y, old_fb); + if (ret != 0) + goto fail_set_mode; } kfree(save_encoders); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a440d0db5cc..ac92799fa8a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -343,7 +343,7 @@ intel_wait_for_vblank(struct drm_device *dev) udelay(20000); } -static void +static int intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb) { @@ -361,11 +361,21 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE; int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; u32 dspcntr, alignment; + int ret; /* no fb bound */ if (!crtc->fb) { DRM_DEBUG("No FB bound\n"); - return; + return 0; + } + + switch (pipe) { + case 0: + case 1: + break; + default: + DRM_ERROR("Can't update pipe %d in SAREA\n", pipe); + return -EINVAL; } intel_fb = to_intel_framebuffer(crtc->fb); @@ -383,20 +393,24 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, case I915_TILING_Y: /* FIXME: Is this true? */ DRM_ERROR("Y tiled not allowed for scan out buffers\n"); - return; + return -EINVAL; default: BUG(); } - if (i915_gem_object_pin(intel_fb->obj, alignment)) - return; - - i915_gem_object_set_to_gtt_domain(intel_fb->obj, 1); - - Start = obj_priv->gtt_offset; - Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8); + mutex_lock(&dev->struct_mutex); + ret = i915_gem_object_pin(intel_fb->obj, alignment); + if (ret != 0) { + mutex_unlock(&dev->struct_mutex); + return ret; + } - I915_WRITE(dspstride, crtc->fb->pitch); + ret = i915_gem_object_set_to_gtt_domain(intel_fb->obj, 1); + if (ret != 0) { + i915_gem_object_unpin(intel_fb->obj); + mutex_unlock(&dev->struct_mutex); + return ret; + } dspcntr = I915_READ(dspcntr_reg); /* Mask out pixel format bits in case we change it */ @@ -417,11 +431,17 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, break; default: DRM_ERROR("Unknown color depth\n"); - return; + i915_gem_object_unpin(intel_fb->obj); + mutex_unlock(&dev->struct_mutex); + return -EINVAL; } I915_WRITE(dspcntr_reg, dspcntr); + Start = obj_priv->gtt_offset; + Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8); + DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y); + I915_WRITE(dspstride, crtc->fb->pitch); if (IS_I965G(dev)) { I915_WRITE(dspbase, Offset); I915_READ(dspbase); @@ -438,27 +458,24 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, intel_fb = to_intel_framebuffer(old_fb); i915_gem_object_unpin(intel_fb->obj); } + mutex_unlock(&dev->struct_mutex); if (!dev->primary->master) - return; + return 0; master_priv = dev->primary->master->driver_priv; if (!master_priv->sarea_priv) - return; + return 0; - switch (pipe) { - case 0: - master_priv->sarea_priv->pipeA_x = x; - master_priv->sarea_priv->pipeA_y = y; - break; - case 1: + if (pipe) { master_priv->sarea_priv->pipeB_x = x; master_priv->sarea_priv->pipeB_y = y; - break; - default: - DRM_ERROR("Can't update pipe %d in SAREA\n", pipe); - break; + } else { + master_priv->sarea_priv->pipeA_x = x; + master_priv->sarea_priv->pipeA_y = y; } + + return 0; } @@ -706,11 +723,11 @@ static int intel_panel_fitter_pipe (struct drm_device *dev) return 1; } -static void intel_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, - struct drm_framebuffer *old_fb) +static int intel_crtc_mode_set(struct drm_crtc *crtc, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode, + int x, int y, + struct drm_framebuffer *old_fb) { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -737,6 +754,7 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc, bool is_crt = false, is_lvds = false, is_tv = false; struct drm_mode_config *mode_config = &dev->mode_config; struct drm_connector *connector; + int ret; drm_vblank_pre_modeset(dev, pipe); @@ -777,7 +795,7 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc, ok = intel_find_best_PLL(crtc, adjusted_mode->clock, refclk, &clock); if (!ok) { DRM_ERROR("Couldn't find PLL settings for mode!\n"); - return; + return -EINVAL; } fp = clock.n << 16 | clock.m1 << 8 | clock.m2; @@ -948,9 +966,13 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc, I915_WRITE(dspcntr_reg, dspcntr); /* Flush the plane changes */ - intel_pipe_set_base(crtc, x, y, old_fb); + ret = intel_pipe_set_base(crtc, x, y, old_fb); + if (ret != 0) + return ret; drm_vblank_post_modeset(dev, pipe); + + return 0; } /** Loads the palette/gamma unit for the CRTC with the prepared values */ diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index 0c6f0e11b41..0b0d236c215 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h @@ -54,13 +54,13 @@ struct drm_crtc_helper_funcs { struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode); /* Actually set the mode */ - void (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, int x, int y, - struct drm_framebuffer *old_fb); + int (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode, int x, int y, + struct drm_framebuffer *old_fb); /* Move the crtc on the current fb to the given position *optional* */ - void (*mode_set_base)(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb); + int (*mode_set_base)(struct drm_crtc *crtc, int x, int y, + struct drm_framebuffer *old_fb); }; struct drm_encoder_helper_funcs { -- cgit From 7f9872e06d749afdc2029aa6b7ffe88cb3b8c5c2 Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Fri, 13 Feb 2009 20:56:49 -0500 Subject: drm: Add locking around cursor gem operations. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to hold the struct_mutex around pinning and the phys object operations. Signed-off-by: Kristian Høgsberg Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/intel_display.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ac92799fa8a..94c7c098c4f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1043,18 +1043,19 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, } /* we only need to pin inside GTT if cursor is non-phy */ + mutex_lock(&dev->struct_mutex); if (!dev_priv->cursor_needs_physical) { ret = i915_gem_object_pin(bo, PAGE_SIZE); if (ret) { DRM_ERROR("failed to pin cursor bo\n"); - goto fail; + goto fail_locked; } addr = obj_priv->gtt_offset; } else { ret = i915_gem_attach_phys_object(dev, bo, (pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1); if (ret) { DRM_ERROR("failed to attach phys object\n"); - goto fail; + goto fail_locked; } addr = obj_priv->phys_obj->handle->busaddr; } @@ -1074,10 +1075,9 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo); } else i915_gem_object_unpin(intel_crtc->cursor_bo); - mutex_lock(&dev->struct_mutex); drm_gem_object_unreference(intel_crtc->cursor_bo); - mutex_unlock(&dev->struct_mutex); } + mutex_unlock(&dev->struct_mutex); intel_crtc->cursor_addr = addr; intel_crtc->cursor_bo = bo; @@ -1085,6 +1085,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, return 0; fail: mutex_lock(&dev->struct_mutex); +fail_locked: drm_gem_object_unreference(bo); mutex_unlock(&dev->struct_mutex); return ret; -- cgit From f3cade5c037054ce5f57651fe0b64eaa9781c753 Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Fri, 13 Feb 2009 20:56:50 -0500 Subject: drm: Bring PLL limits in sync with DDX values. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kristian Høgsberg Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/intel_display.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 94c7c098c4f..4f54ac55f32 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -90,12 +90,12 @@ typedef struct { #define I9XX_DOT_MAX 400000 #define I9XX_VCO_MIN 1400000 #define I9XX_VCO_MAX 2800000 -#define I9XX_N_MIN 3 -#define I9XX_N_MAX 8 +#define I9XX_N_MIN 1 +#define I9XX_N_MAX 6 #define I9XX_M_MIN 70 #define I9XX_M_MAX 120 #define I9XX_M1_MIN 10 -#define I9XX_M1_MAX 20 +#define I9XX_M1_MAX 22 #define I9XX_M2_MIN 5 #define I9XX_M2_MAX 9 #define I9XX_P_SDVO_DAC_MIN 5 -- cgit From a29f5ca3d691995266a4b1df313e32ff0509a03c Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Fri, 13 Feb 2009 20:56:51 -0500 Subject: drm: Collapse identical i8xx_clock() and i9xx_clock(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They used to be different. Now they're identical. Signed-off-by: Kristian Høgsberg Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/intel_display.c | 33 ++++++--------------------------- 1 file changed, 6 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4f54ac55f32..8b203870626 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -189,19 +189,7 @@ static const intel_limit_t *intel_limit(struct drm_crtc *crtc) return limit; } -/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */ - -static void i8xx_clock(int refclk, intel_clock_t *clock) -{ - clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); - clock->p = clock->p1 * clock->p2; - clock->vco = refclk * clock->m / (clock->n + 2); - clock->dot = clock->vco / clock->p; -} - -/** Derive the pixel clock for the given refclk and divisors for 9xx chips. */ - -static void i9xx_clock(int refclk, intel_clock_t *clock) +static void intel_clock(int refclk, intel_clock_t *clock) { clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); clock->p = clock->p1 * clock->p2; @@ -209,15 +197,6 @@ static void i9xx_clock(int refclk, intel_clock_t *clock) clock->dot = clock->vco / clock->p; } -static void intel_clock(struct drm_device *dev, int refclk, - intel_clock_t *clock) -{ - if (IS_I9XX(dev)) - i9xx_clock (refclk, clock); - else - i8xx_clock (refclk, clock); -} - /** * Returns whether any output on the specified pipe is of the specified type */ @@ -318,7 +297,7 @@ static bool intel_find_best_PLL(struct drm_crtc *crtc, int target, clock.p1 <= limit->p1.max; clock.p1++) { int this_err; - intel_clock(dev, refclk, &clock); + intel_clock(refclk, &clock); if (!intel_PLL_is_valid(crtc, &clock)) continue; @@ -1313,7 +1292,7 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) } /* XXX: Handle the 100Mhz refclk */ - i9xx_clock(96000, &clock); + intel_clock(96000, &clock); } else { bool is_lvds = (pipe == 1) && (I915_READ(LVDS) & LVDS_PORT_EN); @@ -1325,9 +1304,9 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) if ((dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN) { /* XXX: might not be 66MHz */ - i8xx_clock(66000, &clock); + intel_clock(66000, &clock); } else - i8xx_clock(48000, &clock); + intel_clock(48000, &clock); } else { if (dpll & PLL_P1_DIVIDE_BY_TWO) clock.p1 = 2; @@ -1340,7 +1319,7 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) else clock.p2 = 2; - i8xx_clock(48000, &clock); + intel_clock(48000, &clock); } } -- cgit From 43565a0648e664744ac9201c199681451355edcc Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Fri, 13 Feb 2009 20:56:52 -0500 Subject: drm: Use spread spectrum when the bios tells us it's ok. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lifted from the DDX modesetting. Signed-off-by: Kristian Høgsberg Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/intel_bios.c | 8 ++++++++ drivers/gpu/drm/i915/intel_display.c | 20 ++++++++++++++------ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7325363164f..135a08f615c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -184,6 +184,8 @@ typedef struct drm_i915_private { unsigned int lvds_dither:1; unsigned int lvds_vbt:1; unsigned int int_crt_support:1; + unsigned int lvds_use_ssc:1; + int lvds_ssc_freq; struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 4ca82a02552..65be30dccc7 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -135,6 +135,14 @@ parse_general_features(struct drm_i915_private *dev_priv, if (general) { dev_priv->int_tv_support = general->int_tv_support; dev_priv->int_crt_support = general->int_crt_support; + dev_priv->lvds_use_ssc = general->enable_ssc; + + if (dev_priv->lvds_use_ssc) { + if (IS_I855(dev_priv->dev)) + dev_priv->lvds_ssc_freq = general->ssc_freq ? 66 : 48; + else + dev_priv->lvds_ssc_freq = general->ssc_freq ? 100 : 96; + } } } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8b203870626..13f9b6667c9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -217,7 +217,7 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type) return false; } -#define INTELPllInvalid(s) { /* ErrorF (s) */; return false; } +#define INTELPllInvalid(s) do { DRM_DEBUG(s); return false; } while (0) /** * Returns whether the given set of divisors are valid for a given refclk with * the given connectors. @@ -726,7 +726,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE; int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS; int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; - int refclk; + int refclk, num_outputs = 0; intel_clock_t clock; u32 dpll = 0, fp = 0, dspcntr, pipeconf; bool ok, is_sdvo = false, is_dvo = false; @@ -763,9 +763,14 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, is_crt = true; break; } + + num_outputs++; } - if (IS_I9XX(dev)) { + if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) { + refclk = dev_priv->lvds_ssc_freq * 1000; + DRM_DEBUG("using SSC reference clock of %d MHz\n", refclk / 1000); + } else if (IS_I9XX(dev)) { refclk = 96000; } else { refclk = 48000; @@ -824,11 +829,14 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, } } - if (is_tv) { + if (is_sdvo && is_tv) + dpll |= PLL_REF_INPUT_TVCLKINBC; + else if (is_tv) /* XXX: just matching BIOS for now */ -/* dpll |= PLL_REF_INPUT_TVCLKINBC; */ + /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ dpll |= 3; - } + else if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) + dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; else dpll |= PLL_REF_INPUT_DREFCLK; -- cgit From 496818f08a78476abdb307e241911536221239fc Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 11 Feb 2009 13:28:14 -0800 Subject: drm/i915: take struct mutex around fb unref Need to do this in case the unref ends up doing a free. Signed-off-by: Jesse Barnes Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/intel_display.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 13f9b6667c9..4d2baf7b00b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1606,7 +1606,9 @@ intel_user_framebuffer_create(struct drm_device *dev, ret = intel_framebuffer_create(dev, mode_cmd, &fb, obj); if (ret) { + mutex_lock(&dev->struct_mutex); drm_gem_object_unreference(obj); + mutex_unlock(&dev->struct_mutex); return NULL; } -- cgit From ab00b3e5210954cbaff9207db874a9f03197e3ba Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 11 Feb 2009 14:01:46 -0800 Subject: drm/i915: Keep refs on the object over the lifetime of vmas for GTT mmap. This fixes potential fault at fault time if the object was unreferenced while the mapping still existed. Now, while the mmap_offset only lives for the lifetime of the object, the object also stays alive while a vma exists that needs it. Signed-off-by: Jesse Barnes Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_gem.c | 28 +++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_drv.c | 2 ++ drivers/gpu/drm/i915/i915_gem.c | 43 ++++++++++++++++++++++++----------------- include/drm/drmP.h | 2 ++ 4 files changed, 57 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 5dad6b9d0de..88d3368ffdd 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -463,6 +463,26 @@ drm_gem_object_handle_free(struct kref *kref) } EXPORT_SYMBOL(drm_gem_object_handle_free); +void drm_gem_vm_open(struct vm_area_struct *vma) +{ + struct drm_gem_object *obj = vma->vm_private_data; + + drm_gem_object_reference(obj); +} +EXPORT_SYMBOL(drm_gem_vm_open); + +void drm_gem_vm_close(struct vm_area_struct *vma) +{ + struct drm_gem_object *obj = vma->vm_private_data; + struct drm_device *dev = obj->dev; + + mutex_lock(&dev->struct_mutex); + drm_gem_object_unreference(obj); + mutex_unlock(&dev->struct_mutex); +} +EXPORT_SYMBOL(drm_gem_vm_close); + + /** * drm_gem_mmap - memory map routine for GEM objects * @filp: DRM file pointer @@ -524,6 +544,14 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) #endif vma->vm_page_prot = __pgprot(prot); + /* Take a ref for this mapping of the object, so that the fault + * handler can dereference the mmap offset's pointer to the object. + * This reference is cleaned up by the corresponding vm_close + * (which should happen whether the vma was created by this call, or + * by a vm_open due to mremap or partial unmap or whatever). + */ + drm_gem_object_reference(obj); + vma->vm_file = filp; /* Needed for drm_vm_open() */ drm_vm_open_locked(vma); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index aac12ee31a4..a31cbdbc3c5 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -94,6 +94,8 @@ static int i915_resume(struct drm_device *dev) static struct vm_operations_struct i915_gem_vm_ops = { .fault = i915_gem_fault, + .open = drm_gem_vm_open, + .close = drm_gem_vm_close, }; static struct drm_driver driver = { diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 07885817883..ac534c9a2f8 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -607,8 +607,6 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) case -EAGAIN: return VM_FAULT_OOM; case -EFAULT: - case -EBUSY: - DRM_ERROR("can't insert pfn?? fault or busy...\n"); return VM_FAULT_SIGBUS; default: return VM_FAULT_NOPAGE; @@ -684,6 +682,30 @@ out_free_list: return ret; } +static void +i915_gem_free_mmap_offset(struct drm_gem_object *obj) +{ + struct drm_device *dev = obj->dev; + struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_gem_mm *mm = dev->mm_private; + struct drm_map_list *list; + + list = &obj->map_list; + drm_ht_remove_item(&mm->offset_hash, &list->hash); + + if (list->file_offset_node) { + drm_mm_put_block(list->file_offset_node); + list->file_offset_node = NULL; + } + + if (list->map) { + drm_free(list->map, sizeof(struct drm_map), DRM_MEM_DRIVER); + list->map = NULL; + } + + obj_priv->mmap_offset = 0; +} + /** * i915_gem_get_gtt_alignment - return required GTT alignment for an object * @obj: object to check @@ -2896,9 +2918,6 @@ int i915_gem_init_object(struct drm_gem_object *obj) void i915_gem_free_object(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; - struct drm_gem_mm *mm = dev->mm_private; - struct drm_map_list *list; - struct drm_map *map; struct drm_i915_gem_object *obj_priv = obj->driver_private; while (obj_priv->pin_count > 0) @@ -2909,19 +2928,7 @@ void i915_gem_free_object(struct drm_gem_object *obj) i915_gem_object_unbind(obj); - list = &obj->map_list; - drm_ht_remove_item(&mm->offset_hash, &list->hash); - - if (list->file_offset_node) { - drm_mm_put_block(list->file_offset_node); - list->file_offset_node = NULL; - } - - map = list->map; - if (map) { - drm_free(map, sizeof(*map), DRM_MEM_DRIVER); - list->map = NULL; - } + i915_gem_free_mmap_offset(obj); drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER); drm_free(obj->driver_private, 1, DRM_MEM_DRIVER); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 8190b9bcc2d..e5f4ae989ab 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1321,6 +1321,8 @@ void drm_gem_object_free(struct kref *kref); struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev, size_t size); void drm_gem_object_handle_free(struct kref *kref); +void drm_gem_vm_open(struct vm_area_struct *vma); +void drm_gem_vm_close(struct vm_area_struct *vma); int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); static inline void -- cgit From 3d16118dc825a654043dfe3e14371fdf2976994d Mon Sep 17 00:00:00 2001 From: etienne Date: Fri, 20 Feb 2009 09:44:45 +1000 Subject: drm/radeon: update sarea copies of last_ variables on resume. This fixes a regression reported in bug #12613. [airlied: not I tweaked the patch slightly and fixed it by etienne did all the hardwork so gets authorship] Signed-off-by: etienne Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_cp.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index df4cf97e5d9..92965dbb3c1 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c @@ -557,8 +557,10 @@ static int radeon_do_engine_reset(struct drm_device * dev) } static void radeon_cp_init_ring_buffer(struct drm_device * dev, - drm_radeon_private_t * dev_priv) + drm_radeon_private_t *dev_priv, + struct drm_file *file_priv) { + struct drm_radeon_master_private *master_priv; u32 ring_start, cur_read_ptr; u32 tmp; @@ -677,6 +679,14 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, dev_priv->scratch[2] = 0; RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0); + /* reset sarea copies of these */ + master_priv = file_priv->master->driver_priv; + if (master_priv->sarea_priv) { + master_priv->sarea_priv->last_frame = 0; + master_priv->sarea_priv->last_dispatch = 0; + master_priv->sarea_priv->last_clear = 0; + } + radeon_do_wait_for_idle(dev_priv); /* Sync everything up */ @@ -1215,7 +1225,7 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, } radeon_cp_load_microcode(dev_priv); - radeon_cp_init_ring_buffer(dev, dev_priv); + radeon_cp_init_ring_buffer(dev, dev_priv, file_priv); dev_priv->last_buf = 0; @@ -1281,7 +1291,7 @@ static int radeon_do_cleanup_cp(struct drm_device * dev) * * Charl P. Botha */ -static int radeon_do_resume_cp(struct drm_device * dev) +static int radeon_do_resume_cp(struct drm_device *dev, struct drm_file *file_priv) { drm_radeon_private_t *dev_priv = dev->dev_private; @@ -1304,7 +1314,7 @@ static int radeon_do_resume_cp(struct drm_device * dev) } radeon_cp_load_microcode(dev_priv); - radeon_cp_init_ring_buffer(dev, dev_priv); + radeon_cp_init_ring_buffer(dev, dev_priv, file_priv); radeon_do_engine_reset(dev); radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); @@ -1479,8 +1489,7 @@ int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_pri */ int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv) { - - return radeon_do_resume_cp(dev); + return radeon_do_resume_cp(dev, file_priv); } int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) -- cgit From 48ffc70b675aa7798a52a2e92e20f6cce9140b3d Mon Sep 17 00:00:00 2001 From: Alok N Kataria Date: Wed, 18 Feb 2009 12:33:55 -0800 Subject: x86, vmi: TSC going backwards check in vmi clocksource Impact: fix time warps under vmware Similar to the check for TSC going backwards in the TSC clocksource, we also need this check for VMI clocksource. Signed-off-by: Alok N Kataria Cc: Zachary Amsden Signed-off-by: Ingo Molnar Cc: stable@kernel.org --- arch/x86/kernel/vmiclock_32.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/vmiclock_32.c b/arch/x86/kernel/vmiclock_32.c index c4c1f9e0940..bde106cae0a 100644 --- a/arch/x86/kernel/vmiclock_32.c +++ b/arch/x86/kernel/vmiclock_32.c @@ -283,10 +283,13 @@ void __devinit vmi_time_ap_init(void) #endif /** vmi clocksource */ +static struct clocksource clocksource_vmi; static cycle_t read_real_cycles(void) { - return vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL); + cycle_t ret = (cycle_t)vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL); + return ret >= clocksource_vmi.cycle_last ? + ret : clocksource_vmi.cycle_last; } static struct clocksource clocksource_vmi = { -- cgit From e32740d9786b8a6c54f6e3d670567d9ef57b3b8c Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Thu, 19 Feb 2009 11:58:37 -0800 Subject: ALSA: pcxhr.h replace signed one-bit bitfields The usage and comments make it clear values of 1/0 were intended rather than -1/0 Noticed by sparse: sound/pci/pcxhr/pcxhr.h:100:20: error: dubious one-bit signed bitfield sound/pci/pcxhr/pcxhr.h:101:22: error: dubious one-bit signed bitfield sound/pci/pcxhr/pcxhr.h:102:24: error: dubious one-bit signed bitfield sound/pci/pcxhr/pcxhr.h:103:21: error: dubious one-bit signed bitfield sound/pci/pcxhr/pcxhr.h:104:25: error: dubious one-bit signed bitfield sound/pci/pcxhr/pcxhr.h:105:20: error: dubious one-bit signed bitfield Signed-off-by: Harvey Harrison Signed-off-by: Takashi Iwai --- sound/pci/pcxhr/pcxhr.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/pci/pcxhr/pcxhr.h b/sound/pci/pcxhr/pcxhr.h index 84131a916c9..69d87dee699 100644 --- a/sound/pci/pcxhr/pcxhr.h +++ b/sound/pci/pcxhr/pcxhr.h @@ -97,12 +97,12 @@ struct pcxhr_mgr { int capture_chips; int fw_file_set; int firmware_num; - int is_hr_stereo:1; - int board_has_aes1:1; /* if 1 board has AES1 plug and SRC */ - int board_has_analog:1; /* if 0 the board is digital only */ - int board_has_mic:1; /* if 1 the board has microphone input */ - int board_aes_in_192k:1;/* if 1 the aes input plugs do support 192kHz */ - int mono_capture:1; /* if 1 the board does mono capture */ + unsigned int is_hr_stereo:1; + unsigned int board_has_aes1:1; /* if 1 board has AES1 plug and SRC */ + unsigned int board_has_analog:1; /* if 0 the board is digital only */ + unsigned int board_has_mic:1; /* if 1 the board has microphone input */ + unsigned int board_aes_in_192k:1;/* if 1 the aes input plugs do support 192kHz */ + unsigned int mono_capture:1; /* if 1 the board does mono capture */ struct snd_dma_buffer hostport; -- cgit From 42f8faecf7a88371de0f30aebb052d1ae51762c0 Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Tue, 17 Feb 2009 11:46:42 +0800 Subject: x86: use percpu data for 4k hardirq and softirq stacks Impact: economize memory for large NR_CPUS percpu data is setup earlier than irq, we can use percpu data to economize memory. Signed-off-by: Lai Jiangshan Signed-off-by: Tejun Heo --- arch/x86/kernel/irq_32.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c index e0f29be8ab0..90cd94aba69 100644 --- a/arch/x86/kernel/irq_32.c +++ b/arch/x86/kernel/irq_32.c @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -55,13 +56,13 @@ static inline void print_stack_overflow(void) { } union irq_ctx { struct thread_info tinfo; u32 stack[THREAD_SIZE/sizeof(u32)]; -}; +} __attribute__((aligned(PAGE_SIZE))); -static union irq_ctx *hardirq_ctx[NR_CPUS] __read_mostly; -static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly; +static DEFINE_PER_CPU(union irq_ctx *, hardirq_ctx); +static DEFINE_PER_CPU(union irq_ctx *, softirq_ctx); -static char softirq_stack[NR_CPUS * THREAD_SIZE] __page_aligned_bss; -static char hardirq_stack[NR_CPUS * THREAD_SIZE] __page_aligned_bss; +static DEFINE_PER_CPU_PAGE_ALIGNED(union irq_ctx, hardirq_stack); +static DEFINE_PER_CPU_PAGE_ALIGNED(union irq_ctx, softirq_stack); static void call_on_stack(void *func, void *stack) { @@ -81,7 +82,7 @@ execute_on_irq_stack(int overflow, struct irq_desc *desc, int irq) u32 *isp, arg1, arg2; curctx = (union irq_ctx *) current_thread_info(); - irqctx = hardirq_ctx[smp_processor_id()]; + irqctx = __get_cpu_var(hardirq_ctx); /* * this is where we switch to the IRQ stack. However, if we are @@ -125,34 +126,34 @@ void __cpuinit irq_ctx_init(int cpu) { union irq_ctx *irqctx; - if (hardirq_ctx[cpu]) + if (per_cpu(hardirq_ctx, cpu)) return; - irqctx = (union irq_ctx*) &hardirq_stack[cpu*THREAD_SIZE]; + irqctx = &per_cpu(hardirq_stack, cpu); irqctx->tinfo.task = NULL; irqctx->tinfo.exec_domain = NULL; irqctx->tinfo.cpu = cpu; irqctx->tinfo.preempt_count = HARDIRQ_OFFSET; irqctx->tinfo.addr_limit = MAKE_MM_SEG(0); - hardirq_ctx[cpu] = irqctx; + per_cpu(hardirq_ctx, cpu) = irqctx; - irqctx = (union irq_ctx *) &softirq_stack[cpu*THREAD_SIZE]; + irqctx = &per_cpu(softirq_stack, cpu); irqctx->tinfo.task = NULL; irqctx->tinfo.exec_domain = NULL; irqctx->tinfo.cpu = cpu; irqctx->tinfo.preempt_count = 0; irqctx->tinfo.addr_limit = MAKE_MM_SEG(0); - softirq_ctx[cpu] = irqctx; + per_cpu(softirq_ctx, cpu) = irqctx; printk(KERN_DEBUG "CPU %u irqstacks, hard=%p soft=%p\n", - cpu, hardirq_ctx[cpu], softirq_ctx[cpu]); + cpu, per_cpu(hardirq_ctx, cpu), per_cpu(softirq_ctx, cpu)); } void irq_ctx_exit(int cpu) { - hardirq_ctx[cpu] = NULL; + per_cpu(hardirq_ctx, cpu) = NULL; } asmlinkage void do_softirq(void) @@ -169,7 +170,7 @@ asmlinkage void do_softirq(void) if (local_softirq_pending()) { curctx = current_thread_info(); - irqctx = softirq_ctx[smp_processor_id()]; + irqctx = __get_cpu_var(softirq_ctx); irqctx->tinfo.task = curctx->task; irqctx->tinfo.previous_esp = current_stack_pointer; -- cgit From 734269521e320ad14ed39ae9b64d482b9028dcd2 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 20 Feb 2009 16:29:07 +0900 Subject: vmalloc: call flush_cache_vunmap() from unmap_kernel_range() Impact: proper vcache flush on unmap_kernel_range() flush_cache_vunmap() should be called before pages are unmapped. Add a call to it in unmap_kernel_range(). Signed-off-by: Tejun Heo --- mm/vmalloc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 75f49d312e8..c37924a2ee3 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -1012,6 +1012,8 @@ void __init vmalloc_init(void) void unmap_kernel_range(unsigned long addr, unsigned long size) { unsigned long end = addr + size; + + flush_cache_vunmap(addr, end); vunmap_page_range(addr, end); flush_tlb_kernel_range(addr, end); } -- cgit From 6b588c18f8dacfa6d7957c33c5ff832096e752d3 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 20 Feb 2009 16:29:07 +0900 Subject: module: reorder module pcpu related functions Impact: cleanup Move percpu_modinit() upwards. This is to ease further changes. Signed-off-by: Tejun Heo --- kernel/module.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/kernel/module.c b/kernel/module.c index ba22484a987..52b3497b874 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -480,21 +480,6 @@ static void percpu_modfree(void *freeme) } } -static unsigned int find_pcpusec(Elf_Ehdr *hdr, - Elf_Shdr *sechdrs, - const char *secstrings) -{ - return find_sec(hdr, sechdrs, secstrings, ".data.percpu"); -} - -static void percpu_modcopy(void *pcpudest, const void *from, unsigned long size) -{ - int cpu; - - for_each_possible_cpu(cpu) - memcpy(pcpudest + per_cpu_offset(cpu), from, size); -} - static int percpu_modinit(void) { pcpu_num_used = 2; @@ -513,7 +498,24 @@ static int percpu_modinit(void) return 0; } __initcall(percpu_modinit); + +static unsigned int find_pcpusec(Elf_Ehdr *hdr, + Elf_Shdr *sechdrs, + const char *secstrings) +{ + return find_sec(hdr, sechdrs, secstrings, ".data.percpu"); +} + +static void percpu_modcopy(void *pcpudest, const void *from, unsigned long size) +{ + int cpu; + + for_each_possible_cpu(cpu) + memcpy(pcpudest + per_cpu_offset(cpu), from, size); +} + #else /* ... !CONFIG_SMP */ + static inline void *percpu_modalloc(unsigned long size, unsigned long align, const char *name) { @@ -535,6 +537,7 @@ static inline void percpu_modcopy(void *pcpudst, const void *src, /* pcpusec should be 0, and size of that section should be 0. */ BUG_ON(size != 0); } + #endif /* CONFIG_SMP */ #define MODINFO_ATTR(field) \ -- cgit From b36128c830a8f5bd7d4981f5b0b69950f5928ee6 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 20 Feb 2009 16:29:08 +0900 Subject: alloc_percpu: change percpu_ptr to per_cpu_ptr Impact: cleanup There are two allocated per-cpu accessor macros with almost identical spelling. The original and far more popular is per_cpu_ptr (44 files), so change over the other 4 files. tj: kill percpu_ptr() and update UP too Signed-off-by: Rusty Russell Cc: mingo@redhat.com Cc: lenb@kernel.org Cc: cpufreq@vger.kernel.org Signed-off-by: Tejun Heo --- arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 2 +- drivers/acpi/processor_perflib.c | 4 ++-- include/linux/percpu.h | 23 +++++++++++------------ kernel/sched.c | 6 +++--- kernel/stop_machine.c | 2 +- 5 files changed, 18 insertions(+), 19 deletions(-) diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index 4b1c319d30c..22590cf688a 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -601,7 +601,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) if (!data) return -ENOMEM; - data->acpi_data = percpu_ptr(acpi_perf_data, cpu); + data->acpi_data = per_cpu_ptr(acpi_perf_data, cpu); per_cpu(drv_data, cpu) = data; if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 9cc769b587f..68fd3d29279 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -516,12 +516,12 @@ int acpi_processor_preregister_performance( continue; } - if (!performance || !percpu_ptr(performance, i)) { + if (!performance || !per_cpu_ptr(performance, i)) { retval = -EINVAL; continue; } - pr->performance = percpu_ptr(performance, i); + pr->performance = per_cpu_ptr(performance, i); cpumask_set_cpu(i, pr->performance->shared_cpu_map); if (acpi_processor_get_psd(pr)) { retval = -EINVAL; diff --git a/include/linux/percpu.h b/include/linux/percpu.h index 3577ffd90d4..c80cfe1260e 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -81,23 +81,13 @@ struct percpu_data { }; #define __percpu_disguise(pdata) (struct percpu_data *)~(unsigned long)(pdata) -/* - * Use this to get to a cpu's version of the per-cpu object dynamically - * allocated. Non-atomic access to the current CPU's version should - * probably be combined with get_cpu()/put_cpu(). - */ -#define percpu_ptr(ptr, cpu) \ -({ \ - struct percpu_data *__p = __percpu_disguise(ptr); \ - (__typeof__(ptr))__p->ptrs[(cpu)]; \ -}) extern void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask); extern void percpu_free(void *__pdata); #else /* CONFIG_SMP */ -#define percpu_ptr(ptr, cpu) ({ (void)(cpu); (ptr); }) +#define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); (ptr); }) static __always_inline void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask) { @@ -122,6 +112,15 @@ static inline void percpu_free(void *__pdata) cpu_possible_map) #define alloc_percpu(type) (type *)__alloc_percpu(sizeof(type)) #define free_percpu(ptr) percpu_free((ptr)) -#define per_cpu_ptr(ptr, cpu) percpu_ptr((ptr), (cpu)) +/* + * Use this to get to a cpu's version of the per-cpu object dynamically + * allocated. Non-atomic access to the current CPU's version should + * probably be combined with get_cpu()/put_cpu(). + */ +#define per_cpu_ptr(ptr, cpu) \ +({ \ + struct percpu_data *__p = __percpu_disguise(ptr); \ + (__typeof__(ptr))__p->ptrs[(cpu)]; \ +}) #endif /* __LINUX_PERCPU_H */ diff --git a/kernel/sched.c b/kernel/sched.c index fc17fd91ab5..9d30ac95632 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -9472,7 +9472,7 @@ cpuacct_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp) static u64 cpuacct_cpuusage_read(struct cpuacct *ca, int cpu) { - u64 *cpuusage = percpu_ptr(ca->cpuusage, cpu); + u64 *cpuusage = per_cpu_ptr(ca->cpuusage, cpu); u64 data; #ifndef CONFIG_64BIT @@ -9491,7 +9491,7 @@ static u64 cpuacct_cpuusage_read(struct cpuacct *ca, int cpu) static void cpuacct_cpuusage_write(struct cpuacct *ca, int cpu, u64 val) { - u64 *cpuusage = percpu_ptr(ca->cpuusage, cpu); + u64 *cpuusage = per_cpu_ptr(ca->cpuusage, cpu); #ifndef CONFIG_64BIT /* @@ -9587,7 +9587,7 @@ static void cpuacct_charge(struct task_struct *tsk, u64 cputime) ca = task_ca(tsk); for (; ca; ca = ca->parent) { - u64 *cpuusage = percpu_ptr(ca->cpuusage, cpu); + u64 *cpuusage = per_cpu_ptr(ca->cpuusage, cpu); *cpuusage += cputime; } } diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c index 0cd415ee62a..74541ca4953 100644 --- a/kernel/stop_machine.c +++ b/kernel/stop_machine.c @@ -170,7 +170,7 @@ int __stop_machine(int (*fn)(void *), void *data, const struct cpumask *cpus) * doesn't hit this CPU until we're ready. */ get_cpu(); for_each_online_cpu(i) { - sm_work = percpu_ptr(stop_machine_work, i); + sm_work = per_cpu_ptr(stop_machine_work, i); INIT_WORK(sm_work, stop_cpu); queue_work_on(i, stop_machine_wq, sm_work); } -- cgit From 313e458f81ec3852106c5a83830fe0d4f405a71a Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 20 Feb 2009 16:29:08 +0900 Subject: alloc_percpu: add align argument to __alloc_percpu. This prepares for a real __alloc_percpu, by adding an alignment argument. Only one place uses __alloc_percpu directly, and that's for a string. tj: af_inet also uses __alloc_percpu(), update it. Signed-off-by: Rusty Russell Cc: Christoph Lameter Cc: Jens Axboe --- block/blktrace.c | 2 +- include/linux/percpu.h | 5 +++-- net/ipv4/af_inet.c | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/block/blktrace.c b/block/blktrace.c index 39cc3bfe56e..487766237d2 100644 --- a/block/blktrace.c +++ b/block/blktrace.c @@ -363,7 +363,7 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, if (!bt->sequence) goto err; - bt->msg_data = __alloc_percpu(BLK_TN_MAX_MSG); + bt->msg_data = __alloc_percpu(BLK_TN_MAX_MSG, __alignof__(char)); if (!bt->msg_data) goto err; diff --git a/include/linux/percpu.h b/include/linux/percpu.h index c80cfe1260e..1fdaee93c04 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -108,9 +108,10 @@ static inline void percpu_free(void *__pdata) /* (legacy) interface for use without CPU hotplug handling */ -#define __alloc_percpu(size) percpu_alloc_mask((size), GFP_KERNEL, \ +#define __alloc_percpu(size, align) percpu_alloc_mask((size), GFP_KERNEL, \ cpu_possible_map) -#define alloc_percpu(type) (type *)__alloc_percpu(sizeof(type)) +#define alloc_percpu(type) (type *)__alloc_percpu(sizeof(type), \ + __alignof__(type)) #define free_percpu(ptr) percpu_free((ptr)) /* * Use this to get to a cpu's version of the per-cpu object dynamically diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 743f5542d65..3a3dad80135 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1375,10 +1375,10 @@ EXPORT_SYMBOL_GPL(snmp_fold_field); int snmp_mib_init(void *ptr[2], size_t mibsize) { BUG_ON(ptr == NULL); - ptr[0] = __alloc_percpu(mibsize); + ptr[0] = __alloc_percpu(mibsize, __alignof__(unsigned long long)); if (!ptr[0]) goto err0; - ptr[1] = __alloc_percpu(mibsize); + ptr[1] = __alloc_percpu(mibsize, __alignof__(unsigned long long)); if (!ptr[1]) goto err1; return 0; -- cgit From f2a8205c4ef1af917d175c36a4097ae5587791c8 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 20 Feb 2009 16:29:08 +0900 Subject: percpu: kill percpu_alloc() and friends Impact: kill unused functions percpu_alloc() and its friends never saw much action. It was supposed to replace the cpu-mask unaware __alloc_percpu() but it never happened and in fact __percpu_alloc_mask() itself never really grew proper up/down handling interface either (no exported interface for populate/depopulate). percpu allocation is about to go through major reimplementation and there's no reason to carry this unused interface around. Replace it with __alloc_percpu() and free_percpu(). Signed-off-by: Tejun Heo --- include/linux/percpu.h | 47 ++++++++++++++++++++++------------------------- mm/allocpercpu.c | 32 +++++++++++++++++++------------- 2 files changed, 41 insertions(+), 38 deletions(-) diff --git a/include/linux/percpu.h b/include/linux/percpu.h index 1fdaee93c04..d99e24ae181 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -82,46 +82,43 @@ struct percpu_data { #define __percpu_disguise(pdata) (struct percpu_data *)~(unsigned long)(pdata) -extern void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask); -extern void percpu_free(void *__pdata); +/* + * Use this to get to a cpu's version of the per-cpu object + * dynamically allocated. Non-atomic access to the current CPU's + * version should probably be combined with get_cpu()/put_cpu(). + */ +#define per_cpu_ptr(ptr, cpu) \ +({ \ + struct percpu_data *__p = __percpu_disguise(ptr); \ + (__typeof__(ptr))__p->ptrs[(cpu)]; \ +}) + +extern void *__alloc_percpu(size_t size, size_t align); +extern void free_percpu(void *__pdata); #else /* CONFIG_SMP */ #define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); (ptr); }) -static __always_inline void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask) +static inline void *__alloc_percpu(size_t size, size_t align) { + /* + * Can't easily make larger alignment work with kmalloc. WARN + * on it. Larger alignment should only be used for module + * percpu sections on SMP for which this path isn't used. + */ + WARN_ON_ONCE(align > __alignof__(unsigned long long)); return kzalloc(size, gfp); } -static inline void percpu_free(void *__pdata) +static inline void free_percpu(void *p) { - kfree(__pdata); + kfree(p); } #endif /* CONFIG_SMP */ -#define percpu_alloc_mask(size, gfp, mask) \ - __percpu_alloc_mask((size), (gfp), &(mask)) - -#define percpu_alloc(size, gfp) percpu_alloc_mask((size), (gfp), cpu_online_map) - -/* (legacy) interface for use without CPU hotplug handling */ - -#define __alloc_percpu(size, align) percpu_alloc_mask((size), GFP_KERNEL, \ - cpu_possible_map) #define alloc_percpu(type) (type *)__alloc_percpu(sizeof(type), \ __alignof__(type)) -#define free_percpu(ptr) percpu_free((ptr)) -/* - * Use this to get to a cpu's version of the per-cpu object dynamically - * allocated. Non-atomic access to the current CPU's version should - * probably be combined with get_cpu()/put_cpu(). - */ -#define per_cpu_ptr(ptr, cpu) \ -({ \ - struct percpu_data *__p = __percpu_disguise(ptr); \ - (__typeof__(ptr))__p->ptrs[(cpu)]; \ -}) #endif /* __LINUX_PERCPU_H */ diff --git a/mm/allocpercpu.c b/mm/allocpercpu.c index 4297bc41bfd..3653c570232 100644 --- a/mm/allocpercpu.c +++ b/mm/allocpercpu.c @@ -99,45 +99,51 @@ static int __percpu_populate_mask(void *__pdata, size_t size, gfp_t gfp, __percpu_populate_mask((__pdata), (size), (gfp), &(mask)) /** - * percpu_alloc_mask - initial setup of per-cpu data + * alloc_percpu - initial setup of per-cpu data * @size: size of per-cpu object - * @gfp: may sleep or not etc. - * @mask: populate per-data for cpu's selected through mask bits + * @align: alignment * - * Populating per-cpu data for all online cpu's would be a typical use case, - * which is simplified by the percpu_alloc() wrapper. - * Per-cpu objects are populated with zeroed buffers. + * Allocate dynamic percpu area. Percpu objects are populated with + * zeroed buffers. */ -void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask) +void *__alloc_percpu(size_t size, size_t align) { /* * We allocate whole cache lines to avoid false sharing */ size_t sz = roundup(nr_cpu_ids * sizeof(void *), cache_line_size()); - void *pdata = kzalloc(sz, gfp); + void *pdata = kzalloc(sz, GFP_KERNEL); void *__pdata = __percpu_disguise(pdata); + /* + * Can't easily make larger alignment work with kmalloc. WARN + * on it. Larger alignment should only be used for module + * percpu sections on SMP for which this path isn't used. + */ + WARN_ON_ONCE(align > __alignof__(unsigned long long)); + if (unlikely(!pdata)) return NULL; - if (likely(!__percpu_populate_mask(__pdata, size, gfp, mask))) + if (likely(!__percpu_populate_mask(__pdata, size, GFP_KERNEL, + &cpu_possible_map))) return __pdata; kfree(pdata); return NULL; } -EXPORT_SYMBOL_GPL(__percpu_alloc_mask); +EXPORT_SYMBOL_GPL(__alloc_percpu); /** - * percpu_free - final cleanup of per-cpu data + * free_percpu - final cleanup of per-cpu data * @__pdata: object to clean up * * We simply clean up any per-cpu object left. No need for the client to * track and specify through a bis mask which per-cpu objects are to free. */ -void percpu_free(void *__pdata) +void free_percpu(void *__pdata) { if (unlikely(!__pdata)) return; __percpu_depopulate_mask(__pdata, &cpu_possible_map); kfree(__percpu_disguise(__pdata)); } -EXPORT_SYMBOL_GPL(percpu_free); +EXPORT_SYMBOL_GPL(free_percpu); -- cgit From f0aa6617903648077dffe5cfcf7c4458f4610fa7 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 20 Feb 2009 16:29:08 +0900 Subject: vmalloc: implement vm_area_register_early() Impact: allow multiple early vm areas There are places where kernel VM area needs to be allocated before vmalloc is initialized. This is done by allocating static vm_struct, initializing several fields and linking it to vmlist and later vmalloc initialization picking up these from vmlist. This is currently done manually and if there's more than one such areas, there's no defined way to arbitrate who gets which address. This patch implements vm_area_register_early(), which takes vm_area struct with flags and size initialized, assigns address to it and puts it on the vmlist. This way, multiple early vm areas can determine which addresses they should use. The only current user - alpha mm init - is converted to use it. Signed-off-by: Tejun Heo --- arch/alpha/mm/init.c | 20 +++++++++++++------- include/linux/vmalloc.h | 1 + mm/vmalloc.c | 24 ++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c index 5d7a16eab31..df6df025ded 100644 --- a/arch/alpha/mm/init.c +++ b/arch/alpha/mm/init.c @@ -189,9 +189,21 @@ callback_init(void * kernel_end) if (alpha_using_srm) { static struct vm_struct console_remap_vm; - unsigned long vaddr = VMALLOC_START; + unsigned long nr_pages = 0; + unsigned long vaddr; unsigned long i, j; + /* calculate needed size */ + for (i = 0; i < crb->map_entries; ++i) + nr_pages += crb->map[i].count; + + /* register the vm area */ + console_remap_vm.flags = VM_ALLOC; + console_remap_vm.size = nr_pages << PAGE_SHIFT; + vm_area_register_early(&console_remap_vm); + + vaddr = (unsigned long)consle_remap_vm.addr; + /* Set up the third level PTEs and update the virtual addresses of the CRB entries. */ for (i = 0; i < crb->map_entries; ++i) { @@ -213,12 +225,6 @@ callback_init(void * kernel_end) vaddr += PAGE_SIZE; } } - - /* Let vmalloc know that we've allocated some space. */ - console_remap_vm.flags = VM_ALLOC; - console_remap_vm.addr = (void *) VMALLOC_START; - console_remap_vm.size = vaddr - VMALLOC_START; - vmlist = &console_remap_vm; } callback_init_done = 1; diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 506e7620a98..bbc05139229 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -106,5 +106,6 @@ extern long vwrite(char *buf, char *addr, unsigned long count); */ extern rwlock_t vmlist_lock; extern struct vm_struct *vmlist; +extern __init void vm_area_register_early(struct vm_struct *vm); #endif /* _LINUX_VMALLOC_H */ diff --git a/mm/vmalloc.c b/mm/vmalloc.c index c37924a2ee3..d206261ad9e 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -982,6 +983,29 @@ void *vm_map_ram(struct page **pages, unsigned int count, int node, pgprot_t pro } EXPORT_SYMBOL(vm_map_ram); +/** + * vm_area_register_early - register vmap area early during boot + * @vm: vm_struct to register + * @size: size of area to register + * + * This function is used to register kernel vm area before + * vmalloc_init() is called. @vm->size and @vm->flags should contain + * proper values on entry and other fields should be zero. On return, + * vm->addr contains the allocated address. + * + * DO NOT USE THIS FUNCTION UNLESS YOU KNOW WHAT YOU'RE DOING. + */ +void __init vm_area_register_early(struct vm_struct *vm) +{ + static size_t vm_init_off __initdata; + + vm->addr = (void *)VMALLOC_START + vm_init_off; + vm_init_off = PFN_ALIGN(vm_init_off + vm->size); + + vm->next = vmlist; + vmlist = vm; +} + void __init vmalloc_init(void) { struct vmap_area *va; -- cgit From 8fc48985006da4ceba24508db64ec77fc0dfe3bb Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 20 Feb 2009 16:29:08 +0900 Subject: vmalloc: add un/map_kernel_range_noflush() Impact: two more public map/unmap functions Implement map_kernel_range_noflush() and unmap_kernel_range_noflush(). These functions respectively map and unmap address range in kernel VM area but doesn't do any vcache or tlb flushing. These will be used by new percpu allocator. Signed-off-by: Tejun Heo Cc: Nick Piggin --- include/linux/vmalloc.h | 3 +++ mm/vmalloc.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index bbc05139229..599ba798431 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -91,6 +91,9 @@ extern struct vm_struct *remove_vm_area(const void *addr); extern int map_vm_area(struct vm_struct *area, pgprot_t prot, struct page ***pages); +extern int map_kernel_range_noflush(unsigned long start, unsigned long size, + pgprot_t prot, struct page **pages); +extern void unmap_kernel_range_noflush(unsigned long addr, unsigned long size); extern void unmap_kernel_range(unsigned long addr, unsigned long size); /* Allocate/destroy a 'vmalloc' VM area. */ diff --git a/mm/vmalloc.c b/mm/vmalloc.c index d206261ad9e..224eca9650a 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -153,8 +153,8 @@ static int vmap_pud_range(pgd_t *pgd, unsigned long addr, * * Ie. pte at addr+N*PAGE_SIZE shall point to pfn corresponding to pages[N] */ -static int vmap_page_range(unsigned long start, unsigned long end, - pgprot_t prot, struct page **pages) +static int vmap_page_range_noflush(unsigned long start, unsigned long end, + pgprot_t prot, struct page **pages) { pgd_t *pgd; unsigned long next; @@ -170,13 +170,22 @@ static int vmap_page_range(unsigned long start, unsigned long end, if (err) break; } while (pgd++, addr = next, addr != end); - flush_cache_vmap(start, end); if (unlikely(err)) return err; return nr; } +static int vmap_page_range(unsigned long start, unsigned long end, + pgprot_t prot, struct page **pages) +{ + int ret; + + ret = vmap_page_range_noflush(start, end, prot, pages); + flush_cache_vmap(start, end); + return ret; +} + static inline int is_vmalloc_or_module_addr(const void *x) { /* @@ -1033,6 +1042,58 @@ void __init vmalloc_init(void) vmap_initialized = true; } +/** + * map_kernel_range_noflush - map kernel VM area with the specified pages + * @addr: start of the VM area to map + * @size: size of the VM area to map + * @prot: page protection flags to use + * @pages: pages to map + * + * Map PFN_UP(@size) pages at @addr. The VM area @addr and @size + * specify should have been allocated using get_vm_area() and its + * friends. + * + * NOTE: + * This function does NOT do any cache flushing. The caller is + * responsible for calling flush_cache_vmap() on to-be-mapped areas + * before calling this function. + * + * RETURNS: + * The number of pages mapped on success, -errno on failure. + */ +int map_kernel_range_noflush(unsigned long addr, unsigned long size, + pgprot_t prot, struct page **pages) +{ + return vmap_page_range_noflush(addr, addr + size, prot, pages); +} + +/** + * unmap_kernel_range_noflush - unmap kernel VM area + * @addr: start of the VM area to unmap + * @size: size of the VM area to unmap + * + * Unmap PFN_UP(@size) pages at @addr. The VM area @addr and @size + * specify should have been allocated using get_vm_area() and its + * friends. + * + * NOTE: + * This function does NOT do any cache flushing. The caller is + * responsible for calling flush_cache_vunmap() on to-be-mapped areas + * before calling this function and flush_tlb_kernel_range() after. + */ +void unmap_kernel_range_noflush(unsigned long addr, unsigned long size) +{ + vunmap_page_range(addr, addr + size); +} + +/** + * unmap_kernel_range - unmap kernel VM area and flush cache and TLB + * @addr: start of the VM area to unmap + * @size: size of the VM area to unmap + * + * Similar to unmap_kernel_range_noflush() but flushes vcache before + * the unmapping and tlb after. + */ void unmap_kernel_range(unsigned long addr, unsigned long size) { unsigned long end = addr + size; -- cgit From fbf59bc9d74d1fb30b8e0630743aff2806eafcea Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 20 Feb 2009 16:29:08 +0900 Subject: percpu: implement new dynamic percpu allocator Impact: new scalable dynamic percpu allocator which allows dynamic percpu areas to be accessed the same way as static ones Implement scalable dynamic percpu allocator which can be used for both static and dynamic percpu areas. This will allow static and dynamic areas to share faster direct access methods. This feature is optional and enabled only when CONFIG_HAVE_DYNAMIC_PER_CPU_AREA is defined by arch. Please read comment on top of mm/percpu.c for details. Signed-off-by: Tejun Heo Cc: Andrew Morton --- include/linux/percpu.h | 22 +- kernel/module.c | 31 ++ mm/Makefile | 4 + mm/percpu.c | 890 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 943 insertions(+), 4 deletions(-) create mode 100644 mm/percpu.c diff --git a/include/linux/percpu.h b/include/linux/percpu.h index d99e24ae181..18080995ff3 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -76,23 +76,37 @@ #ifdef CONFIG_SMP -struct percpu_data { - void *ptrs[1]; -}; +#ifdef CONFIG_HAVE_DYNAMIC_PER_CPU_AREA -#define __percpu_disguise(pdata) (struct percpu_data *)~(unsigned long)(pdata) +extern void *pcpu_base_addr; +typedef void (*pcpu_populate_pte_fn_t)(unsigned long addr); + +extern size_t __init pcpu_setup_static(pcpu_populate_pte_fn_t populate_pte_fn, + struct page **pages, size_t cpu_size); /* * Use this to get to a cpu's version of the per-cpu object * dynamically allocated. Non-atomic access to the current CPU's * version should probably be combined with get_cpu()/put_cpu(). */ +#define per_cpu_ptr(ptr, cpu) SHIFT_PERCPU_PTR((ptr), per_cpu_offset((cpu))) + +#else /* CONFIG_HAVE_DYNAMIC_PER_CPU_AREA */ + +struct percpu_data { + void *ptrs[1]; +}; + +#define __percpu_disguise(pdata) (struct percpu_data *)~(unsigned long)(pdata) + #define per_cpu_ptr(ptr, cpu) \ ({ \ struct percpu_data *__p = __percpu_disguise(ptr); \ (__typeof__(ptr))__p->ptrs[(cpu)]; \ }) +#endif /* CONFIG_HAVE_DYNAMIC_PER_CPU_AREA */ + extern void *__alloc_percpu(size_t size, size_t align); extern void free_percpu(void *__pdata); diff --git a/kernel/module.c b/kernel/module.c index 52b3497b874..1f0657ae555 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -51,6 +51,7 @@ #include #include #include +#include #if 0 #define DEBUGP printk @@ -366,6 +367,34 @@ static struct module *find_module(const char *name) } #ifdef CONFIG_SMP + +#ifdef CONFIG_HAVE_DYNAMIC_PER_CPU_AREA + +static void *percpu_modalloc(unsigned long size, unsigned long align, + const char *name) +{ + void *ptr; + + if (align > PAGE_SIZE) { + printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n", + name, align, PAGE_SIZE); + align = PAGE_SIZE; + } + + ptr = __alloc_percpu(size, align); + if (!ptr) + printk(KERN_WARNING + "Could not allocate %lu bytes percpu data\n", size); + return ptr; +} + +static void percpu_modfree(void *freeme) +{ + free_percpu(freeme); +} + +#else /* ... !CONFIG_HAVE_DYNAMIC_PER_CPU_AREA */ + /* Number of blocks used and allocated. */ static unsigned int pcpu_num_used, pcpu_num_allocated; /* Size of each block. -ve means used. */ @@ -499,6 +528,8 @@ static int percpu_modinit(void) } __initcall(percpu_modinit); +#endif /* CONFIG_HAVE_DYNAMIC_PER_CPU_AREA */ + static unsigned int find_pcpusec(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, const char *secstrings) diff --git a/mm/Makefile b/mm/Makefile index 72255be57f8..818569b68f4 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -30,6 +30,10 @@ obj-$(CONFIG_FAILSLAB) += failslab.o obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o obj-$(CONFIG_FS_XIP) += filemap_xip.o obj-$(CONFIG_MIGRATION) += migrate.o +ifdef CONFIG_HAVE_DYNAMIC_PER_CPU_AREA +obj-$(CONFIG_SMP) += percpu.o +else obj-$(CONFIG_SMP) += allocpercpu.o +endif obj-$(CONFIG_QUICKLIST) += quicklist.o obj-$(CONFIG_CGROUP_MEM_RES_CTLR) += memcontrol.o page_cgroup.o diff --git a/mm/percpu.c b/mm/percpu.c new file mode 100644 index 00000000000..4617d97e877 --- /dev/null +++ b/mm/percpu.c @@ -0,0 +1,890 @@ +/* + * linux/mm/percpu.c - percpu memory allocator + * + * Copyright (C) 2009 SUSE Linux Products GmbH + * Copyright (C) 2009 Tejun Heo + * + * This file is released under the GPLv2. + * + * This is percpu allocator which can handle both static and dynamic + * areas. Percpu areas are allocated in chunks in vmalloc area. Each + * chunk is consisted of num_possible_cpus() units and the first chunk + * is used for static percpu variables in the kernel image (special + * boot time alloc/init handling necessary as these areas need to be + * brought up before allocation services are running). Unit grows as + * necessary and all units grow or shrink in unison. When a chunk is + * filled up, another chunk is allocated. ie. in vmalloc area + * + * c0 c1 c2 + * ------------------- ------------------- ------------ + * | u0 | u1 | u2 | u3 | | u0 | u1 | u2 | u3 | | u0 | u1 | u + * ------------------- ...... ------------------- .... ------------ + * + * Allocation is done in offset-size areas of single unit space. Ie, + * an area of 512 bytes at 6k in c1 occupies 512 bytes at 6k of c1:u0, + * c1:u1, c1:u2 and c1:u3. Percpu access can be done by configuring + * percpu base registers UNIT_SIZE apart. + * + * There are usually many small percpu allocations many of them as + * small as 4 bytes. The allocator organizes chunks into lists + * according to free size and tries to allocate from the fullest one. + * Each chunk keeps the maximum contiguous area size hint which is + * guaranteed to be eqaul to or larger than the maximum contiguous + * area in the chunk. This helps the allocator not to iterate the + * chunk maps unnecessarily. + * + * Allocation state in each chunk is kept using an array of integers + * on chunk->map. A positive value in the map represents a free + * region and negative allocated. Allocation inside a chunk is done + * by scanning this map sequentially and serving the first matching + * entry. This is mostly copied from the percpu_modalloc() allocator. + * Chunks are also linked into a rb tree to ease address to chunk + * mapping during free. + * + * To use this allocator, arch code should do the followings. + * + * - define CONFIG_HAVE_DYNAMIC_PER_CPU_AREA + * + * - define __addr_to_pcpu_ptr() and __pcpu_ptr_to_addr() to translate + * regular address to percpu pointer and back + * + * - use pcpu_setup_static() during percpu area initialization to + * setup kernel static percpu area + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define PCPU_MIN_UNIT_PAGES_SHIFT 4 /* also max alloc size */ +#define PCPU_SLOT_BASE_SHIFT 5 /* 1-31 shares the same slot */ +#define PCPU_DFL_MAP_ALLOC 16 /* start a map with 16 ents */ + +struct pcpu_chunk { + struct list_head list; /* linked to pcpu_slot lists */ + struct rb_node rb_node; /* key is chunk->vm->addr */ + int free_size; /* free bytes in the chunk */ + int contig_hint; /* max contiguous size hint */ + struct vm_struct *vm; /* mapped vmalloc region */ + int map_used; /* # of map entries used */ + int map_alloc; /* # of map entries allocated */ + int *map; /* allocation map */ + struct page *page[]; /* #cpus * UNIT_PAGES */ +}; + +static int pcpu_unit_pages_shift; +static int pcpu_unit_pages; +static int pcpu_unit_shift; +static int pcpu_unit_size; +static int pcpu_chunk_size; +static int pcpu_nr_slots; +static size_t pcpu_chunk_struct_size; + +/* the address of the first chunk which starts with the kernel static area */ +void *pcpu_base_addr; +EXPORT_SYMBOL_GPL(pcpu_base_addr); + +/* the size of kernel static area */ +static int pcpu_static_size; + +/* + * One mutex to rule them all. + * + * The following mutex is grabbed in the outermost public alloc/free + * interface functions and released only when the operation is + * complete. As such, every function in this file other than the + * outermost functions are called under pcpu_mutex. + * + * It can easily be switched to use spinlock such that only the area + * allocation and page population commit are protected with it doing + * actual [de]allocation without holding any lock. However, given + * what this allocator does, I think it's better to let them run + * sequentially. + */ +static DEFINE_MUTEX(pcpu_mutex); + +static struct list_head *pcpu_slot; /* chunk list slots */ +static struct rb_root pcpu_addr_root = RB_ROOT; /* chunks by address */ + +static int pcpu_size_to_slot(int size) +{ + int highbit = fls(size); + return max(highbit - PCPU_SLOT_BASE_SHIFT + 2, 1); +} + +static int pcpu_chunk_slot(const struct pcpu_chunk *chunk) +{ + if (chunk->free_size < sizeof(int) || chunk->contig_hint < sizeof(int)) + return 0; + + return pcpu_size_to_slot(chunk->free_size); +} + +static int pcpu_page_idx(unsigned int cpu, int page_idx) +{ + return (cpu << pcpu_unit_pages_shift) + page_idx; +} + +static struct page **pcpu_chunk_pagep(struct pcpu_chunk *chunk, + unsigned int cpu, int page_idx) +{ + return &chunk->page[pcpu_page_idx(cpu, page_idx)]; +} + +static unsigned long pcpu_chunk_addr(struct pcpu_chunk *chunk, + unsigned int cpu, int page_idx) +{ + return (unsigned long)chunk->vm->addr + + (pcpu_page_idx(cpu, page_idx) << PAGE_SHIFT); +} + +static bool pcpu_chunk_page_occupied(struct pcpu_chunk *chunk, + int page_idx) +{ + return *pcpu_chunk_pagep(chunk, 0, page_idx) != NULL; +} + +/** + * pcpu_realloc - versatile realloc + * @p: the current pointer (can be NULL for new allocations) + * @size: the current size (can be 0 for new allocations) + * @new_size: the wanted new size (can be 0 for free) + * + * More robust realloc which can be used to allocate, resize or free a + * memory area of arbitrary size. If the needed size goes over + * PAGE_SIZE, kernel VM is used. + * + * RETURNS: + * The new pointer on success, NULL on failure. + */ +static void *pcpu_realloc(void *p, size_t size, size_t new_size) +{ + void *new; + + if (new_size <= PAGE_SIZE) + new = kmalloc(new_size, GFP_KERNEL); + else + new = vmalloc(new_size); + if (new_size && !new) + return NULL; + + memcpy(new, p, min(size, new_size)); + if (new_size > size) + memset(new + size, 0, new_size - size); + + if (size <= PAGE_SIZE) + kfree(p); + else + vfree(p); + + return new; +} + +/** + * pcpu_chunk_relocate - put chunk in the appropriate chunk slot + * @chunk: chunk of interest + * @oslot: the previous slot it was on + * + * This function is called after an allocation or free changed @chunk. + * New slot according to the changed state is determined and @chunk is + * moved to the slot. + */ +static void pcpu_chunk_relocate(struct pcpu_chunk *chunk, int oslot) +{ + int nslot = pcpu_chunk_slot(chunk); + + if (oslot != nslot) { + if (oslot < nslot) + list_move(&chunk->list, &pcpu_slot[nslot]); + else + list_move_tail(&chunk->list, &pcpu_slot[nslot]); + } +} + +static struct rb_node **pcpu_chunk_rb_search(void *addr, + struct rb_node **parentp) +{ + struct rb_node **p = &pcpu_addr_root.rb_node; + struct rb_node *parent = NULL; + struct pcpu_chunk *chunk; + + while (*p) { + parent = *p; + chunk = rb_entry(parent, struct pcpu_chunk, rb_node); + + if (addr < chunk->vm->addr) + p = &(*p)->rb_left; + else if (addr > chunk->vm->addr) + p = &(*p)->rb_right; + else + break; + } + + if (parentp) + *parentp = parent; + return p; +} + +/** + * pcpu_chunk_addr_search - search for chunk containing specified address + * @addr: address to search for + * + * Look for chunk which might contain @addr. More specifically, it + * searchs for the chunk with the highest start address which isn't + * beyond @addr. + * + * RETURNS: + * The address of the found chunk. + */ +static struct pcpu_chunk *pcpu_chunk_addr_search(void *addr) +{ + struct rb_node *n, *parent; + struct pcpu_chunk *chunk; + + n = *pcpu_chunk_rb_search(addr, &parent); + if (!n) { + /* no exactly matching chunk, the parent is the closest */ + n = parent; + BUG_ON(!n); + } + chunk = rb_entry(n, struct pcpu_chunk, rb_node); + + if (addr < chunk->vm->addr) { + /* the parent was the next one, look for the previous one */ + n = rb_prev(n); + BUG_ON(!n); + chunk = rb_entry(n, struct pcpu_chunk, rb_node); + } + + return chunk; +} + +/** + * pcpu_chunk_addr_insert - insert chunk into address rb tree + * @new: chunk to insert + * + * Insert @new into address rb tree. + */ +static void pcpu_chunk_addr_insert(struct pcpu_chunk *new) +{ + struct rb_node **p, *parent; + + p = pcpu_chunk_rb_search(new->vm->addr, &parent); + BUG_ON(*p); + rb_link_node(&new->rb_node, parent, p); + rb_insert_color(&new->rb_node, &pcpu_addr_root); +} + +/** + * pcpu_split_block - split a map block + * @chunk: chunk of interest + * @i: index of map block to split + * @head: head size (can be 0) + * @tail: tail size (can be 0) + * + * Split the @i'th map block into two or three blocks. If @head is + * non-zero, @head bytes block is inserted before block @i moving it + * to @i+1 and reducing its size by @head bytes. + * + * If @tail is non-zero, the target block, which can be @i or @i+1 + * depending on @head, is reduced by @tail bytes and @tail byte block + * is inserted after the target block. + * + * RETURNS: + * 0 on success, -errno on failure. + */ +static int pcpu_split_block(struct pcpu_chunk *chunk, int i, int head, int tail) +{ + int nr_extra = !!head + !!tail; + int target = chunk->map_used + nr_extra; + + /* reallocation required? */ + if (chunk->map_alloc < target) { + int new_alloc = chunk->map_alloc; + int *new; + + while (new_alloc < target) + new_alloc *= 2; + + new = pcpu_realloc(chunk->map, + chunk->map_alloc * sizeof(new[0]), + new_alloc * sizeof(new[0])); + if (!new) + return -ENOMEM; + + chunk->map_alloc = new_alloc; + chunk->map = new; + } + + /* insert a new subblock */ + memmove(&chunk->map[i + nr_extra], &chunk->map[i], + sizeof(chunk->map[0]) * (chunk->map_used - i)); + chunk->map_used += nr_extra; + + if (head) { + chunk->map[i + 1] = chunk->map[i] - head; + chunk->map[i++] = head; + } + if (tail) { + chunk->map[i++] -= tail; + chunk->map[i] = tail; + } + return 0; +} + +/** + * pcpu_alloc_area - allocate area from a pcpu_chunk + * @chunk: chunk of interest + * @size: wanted size + * @align: wanted align + * + * Try to allocate @size bytes area aligned at @align from @chunk. + * Note that this function only allocates the offset. It doesn't + * populate or map the area. + * + * RETURNS: + * Allocated offset in @chunk on success, -errno on failure. + */ +static int pcpu_alloc_area(struct pcpu_chunk *chunk, int size, int align) +{ + int oslot = pcpu_chunk_slot(chunk); + int max_contig = 0; + int i, off; + + /* + * The static chunk initially doesn't have map attached + * because kmalloc wasn't available during init. Give it one. + */ + if (unlikely(!chunk->map)) { + chunk->map = pcpu_realloc(NULL, 0, + PCPU_DFL_MAP_ALLOC * sizeof(chunk->map[0])); + if (!chunk->map) + return -ENOMEM; + + chunk->map_alloc = PCPU_DFL_MAP_ALLOC; + chunk->map[chunk->map_used++] = -pcpu_static_size; + if (chunk->free_size) + chunk->map[chunk->map_used++] = chunk->free_size; + } + + for (i = 0, off = 0; i < chunk->map_used; off += abs(chunk->map[i++])) { + bool is_last = i + 1 == chunk->map_used; + int head, tail; + + /* extra for alignment requirement */ + head = ALIGN(off, align) - off; + BUG_ON(i == 0 && head != 0); + + if (chunk->map[i] < 0) + continue; + if (chunk->map[i] < head + size) { + max_contig = max(chunk->map[i], max_contig); + continue; + } + + /* + * If head is small or the previous block is free, + * merge'em. Note that 'small' is defined as smaller + * than sizeof(int), which is very small but isn't too + * uncommon for percpu allocations. + */ + if (head && (head < sizeof(int) || chunk->map[i - 1] > 0)) { + if (chunk->map[i - 1] > 0) + chunk->map[i - 1] += head; + else { + chunk->map[i - 1] -= head; + chunk->free_size -= head; + } + chunk->map[i] -= head; + off += head; + head = 0; + } + + /* if tail is small, just keep it around */ + tail = chunk->map[i] - head - size; + if (tail < sizeof(int)) + tail = 0; + + /* split if warranted */ + if (head || tail) { + if (pcpu_split_block(chunk, i, head, tail)) + return -ENOMEM; + if (head) { + i++; + off += head; + max_contig = max(chunk->map[i - 1], max_contig); + } + if (tail) + max_contig = max(chunk->map[i + 1], max_contig); + } + + /* update hint and mark allocated */ + if (is_last) + chunk->contig_hint = max_contig; /* fully scanned */ + else + chunk->contig_hint = max(chunk->contig_hint, + max_contig); + + chunk->free_size -= chunk->map[i]; + chunk->map[i] = -chunk->map[i]; + + pcpu_chunk_relocate(chunk, oslot); + return off; + } + + chunk->contig_hint = max_contig; /* fully scanned */ + pcpu_chunk_relocate(chunk, oslot); + + /* + * Tell the upper layer that this chunk has no area left. + * Note that this is not an error condition but a notification + * to upper layer that it needs to look at other chunks. + * -ENOSPC is chosen as it isn't used in memory subsystem and + * matches the meaning in a way. + */ + return -ENOSPC; +} + +/** + * pcpu_free_area - free area to a pcpu_chunk + * @chunk: chunk of interest + * @freeme: offset of area to free + * + * Free area starting from @freeme to @chunk. Note that this function + * only modifies the allocation map. It doesn't depopulate or unmap + * the area. + */ +static void pcpu_free_area(struct pcpu_chunk *chunk, int freeme) +{ + int oslot = pcpu_chunk_slot(chunk); + int i, off; + + for (i = 0, off = 0; i < chunk->map_used; off += abs(chunk->map[i++])) + if (off == freeme) + break; + BUG_ON(off != freeme); + BUG_ON(chunk->map[i] > 0); + + chunk->map[i] = -chunk->map[i]; + chunk->free_size += chunk->map[i]; + + /* merge with previous? */ + if (i > 0 && chunk->map[i - 1] >= 0) { + chunk->map[i - 1] += chunk->map[i]; + chunk->map_used--; + memmove(&chunk->map[i], &chunk->map[i + 1], + (chunk->map_used - i) * sizeof(chunk->map[0])); + i--; + } + /* merge with next? */ + if (i + 1 < chunk->map_used && chunk->map[i + 1] >= 0) { + chunk->map[i] += chunk->map[i + 1]; + chunk->map_used--; + memmove(&chunk->map[i + 1], &chunk->map[i + 2], + (chunk->map_used - (i + 1)) * sizeof(chunk->map[0])); + } + + chunk->contig_hint = max(chunk->map[i], chunk->contig_hint); + pcpu_chunk_relocate(chunk, oslot); +} + +/** + * pcpu_unmap - unmap pages out of a pcpu_chunk + * @chunk: chunk of interest + * @page_start: page index of the first page to unmap + * @page_end: page index of the last page to unmap + 1 + * @flush: whether to flush cache and tlb or not + * + * For each cpu, unmap pages [@page_start,@page_end) out of @chunk. + * If @flush is true, vcache is flushed before unmapping and tlb + * after. + */ +static void pcpu_unmap(struct pcpu_chunk *chunk, int page_start, int page_end, + bool flush) +{ + unsigned int last = num_possible_cpus() - 1; + unsigned int cpu; + + /* + * Each flushing trial can be very expensive, issue flush on + * the whole region at once rather than doing it for each cpu. + * This could be an overkill but is more scalable. + */ + if (flush) + flush_cache_vunmap(pcpu_chunk_addr(chunk, 0, page_start), + pcpu_chunk_addr(chunk, last, page_end)); + + for_each_possible_cpu(cpu) + unmap_kernel_range_noflush( + pcpu_chunk_addr(chunk, cpu, page_start), + (page_end - page_start) << PAGE_SHIFT); + + /* ditto as flush_cache_vunmap() */ + if (flush) + flush_tlb_kernel_range(pcpu_chunk_addr(chunk, 0, page_start), + pcpu_chunk_addr(chunk, last, page_end)); +} + +/** + * pcpu_depopulate_chunk - depopulate and unmap an area of a pcpu_chunk + * @chunk: chunk to depopulate + * @off: offset to the area to depopulate + * @size: size of the area to depopulate + * @flush: whether to flush cache and tlb or not + * + * For each cpu, depopulate and unmap pages [@page_start,@page_end) + * from @chunk. If @flush is true, vcache is flushed before unmapping + * and tlb after. + */ +static void pcpu_depopulate_chunk(struct pcpu_chunk *chunk, size_t off, + size_t size, bool flush) +{ + int page_start = PFN_DOWN(off); + int page_end = PFN_UP(off + size); + int unmap_start = -1; + int uninitialized_var(unmap_end); + unsigned int cpu; + int i; + + for (i = page_start; i < page_end; i++) { + for_each_possible_cpu(cpu) { + struct page **pagep = pcpu_chunk_pagep(chunk, cpu, i); + + if (!*pagep) + continue; + + __free_page(*pagep); + + /* + * If it's partial depopulation, it might get + * populated or depopulated again. Mark the + * page gone. + */ + *pagep = NULL; + + unmap_start = unmap_start < 0 ? i : unmap_start; + unmap_end = i + 1; + } + } + + if (unmap_start >= 0) + pcpu_unmap(chunk, unmap_start, unmap_end, flush); +} + +/** + * pcpu_map - map pages into a pcpu_chunk + * @chunk: chunk of interest + * @page_start: page index of the first page to map + * @page_end: page index of the last page to map + 1 + * + * For each cpu, map pages [@page_start,@page_end) into @chunk. + * vcache is flushed afterwards. + */ +static int pcpu_map(struct pcpu_chunk *chunk, int page_start, int page_end) +{ + unsigned int last = num_possible_cpus() - 1; + unsigned int cpu; + int err; + + for_each_possible_cpu(cpu) { + err = map_kernel_range_noflush( + pcpu_chunk_addr(chunk, cpu, page_start), + (page_end - page_start) << PAGE_SHIFT, + PAGE_KERNEL, + pcpu_chunk_pagep(chunk, cpu, page_start)); + if (err < 0) + return err; + } + + /* flush at once, please read comments in pcpu_unmap() */ + flush_cache_vmap(pcpu_chunk_addr(chunk, 0, page_start), + pcpu_chunk_addr(chunk, last, page_end)); + return 0; +} + +/** + * pcpu_populate_chunk - populate and map an area of a pcpu_chunk + * @chunk: chunk of interest + * @off: offset to the area to populate + * @size: size of the area to populate + * + * For each cpu, populate and map pages [@page_start,@page_end) into + * @chunk. The area is cleared on return. + */ +static int pcpu_populate_chunk(struct pcpu_chunk *chunk, int off, int size) +{ + const gfp_t alloc_mask = GFP_KERNEL | __GFP_HIGHMEM | __GFP_COLD; + int page_start = PFN_DOWN(off); + int page_end = PFN_UP(off + size); + int map_start = -1; + int map_end; + unsigned int cpu; + int i; + + for (i = page_start; i < page_end; i++) { + if (pcpu_chunk_page_occupied(chunk, i)) { + if (map_start >= 0) { + if (pcpu_map(chunk, map_start, map_end)) + goto err; + map_start = -1; + } + continue; + } + + map_start = map_start < 0 ? i : map_start; + map_end = i + 1; + + for_each_possible_cpu(cpu) { + struct page **pagep = pcpu_chunk_pagep(chunk, cpu, i); + + *pagep = alloc_pages_node(cpu_to_node(cpu), + alloc_mask, 0); + if (!*pagep) + goto err; + } + } + + if (map_start >= 0 && pcpu_map(chunk, map_start, map_end)) + goto err; + + for_each_possible_cpu(cpu) + memset(chunk->vm->addr + (cpu << pcpu_unit_shift) + off, 0, + size); + + return 0; +err: + /* likely under heavy memory pressure, give memory back */ + pcpu_depopulate_chunk(chunk, off, size, true); + return -ENOMEM; +} + +static void free_pcpu_chunk(struct pcpu_chunk *chunk) +{ + if (!chunk) + return; + if (chunk->vm) + free_vm_area(chunk->vm); + pcpu_realloc(chunk->map, chunk->map_alloc * sizeof(chunk->map[0]), 0); + kfree(chunk); +} + +static struct pcpu_chunk *alloc_pcpu_chunk(void) +{ + struct pcpu_chunk *chunk; + + chunk = kzalloc(pcpu_chunk_struct_size, GFP_KERNEL); + if (!chunk) + return NULL; + + chunk->map = pcpu_realloc(NULL, 0, + PCPU_DFL_MAP_ALLOC * sizeof(chunk->map[0])); + chunk->map_alloc = PCPU_DFL_MAP_ALLOC; + chunk->map[chunk->map_used++] = pcpu_unit_size; + + chunk->vm = get_vm_area(pcpu_chunk_size, GFP_KERNEL); + if (!chunk->vm) { + free_pcpu_chunk(chunk); + return NULL; + } + + INIT_LIST_HEAD(&chunk->list); + chunk->free_size = pcpu_unit_size; + chunk->contig_hint = pcpu_unit_size; + + return chunk; +} + +/** + * __alloc_percpu - allocate percpu area + * @size: size of area to allocate + * @align: alignment of area (max PAGE_SIZE) + * + * Allocate percpu area of @size bytes aligned at @align. Might + * sleep. Might trigger writeouts. + * + * RETURNS: + * Percpu pointer to the allocated area on success, NULL on failure. + */ +void *__alloc_percpu(size_t size, size_t align) +{ + void *ptr = NULL; + struct pcpu_chunk *chunk; + int slot, off; + + if (unlikely(!size || size > PAGE_SIZE << PCPU_MIN_UNIT_PAGES_SHIFT || + align > PAGE_SIZE)) { + WARN(true, "illegal size (%zu) or align (%zu) for " + "percpu allocation\n", size, align); + return NULL; + } + + mutex_lock(&pcpu_mutex); + + /* allocate area */ + for (slot = pcpu_size_to_slot(size); slot < pcpu_nr_slots; slot++) { + list_for_each_entry(chunk, &pcpu_slot[slot], list) { + if (size > chunk->contig_hint) + continue; + off = pcpu_alloc_area(chunk, size, align); + if (off >= 0) + goto area_found; + if (off != -ENOSPC) + goto out_unlock; + } + } + + /* hmmm... no space left, create a new chunk */ + chunk = alloc_pcpu_chunk(); + if (!chunk) + goto out_unlock; + pcpu_chunk_relocate(chunk, -1); + pcpu_chunk_addr_insert(chunk); + + off = pcpu_alloc_area(chunk, size, align); + if (off < 0) + goto out_unlock; + +area_found: + /* populate, map and clear the area */ + if (pcpu_populate_chunk(chunk, off, size)) { + pcpu_free_area(chunk, off); + goto out_unlock; + } + + ptr = __addr_to_pcpu_ptr(chunk->vm->addr + off); +out_unlock: + mutex_unlock(&pcpu_mutex); + return ptr; +} +EXPORT_SYMBOL_GPL(__alloc_percpu); + +static void pcpu_kill_chunk(struct pcpu_chunk *chunk) +{ + pcpu_depopulate_chunk(chunk, 0, pcpu_unit_size, false); + list_del(&chunk->list); + rb_erase(&chunk->rb_node, &pcpu_addr_root); + free_pcpu_chunk(chunk); +} + +/** + * free_percpu - free percpu area + * @ptr: pointer to area to free + * + * Free percpu area @ptr. Might sleep. + */ +void free_percpu(void *ptr) +{ + void *addr = __pcpu_ptr_to_addr(ptr); + struct pcpu_chunk *chunk; + int off; + + if (!ptr) + return; + + mutex_lock(&pcpu_mutex); + + chunk = pcpu_chunk_addr_search(addr); + off = addr - chunk->vm->addr; + + pcpu_free_area(chunk, off); + + /* the chunk became fully free, kill one if there are other free ones */ + if (chunk->free_size == pcpu_unit_size) { + struct pcpu_chunk *pos; + + list_for_each_entry(pos, + &pcpu_slot[pcpu_chunk_slot(chunk)], list) + if (pos != chunk) { + pcpu_kill_chunk(pos); + break; + } + } + + mutex_unlock(&pcpu_mutex); +} +EXPORT_SYMBOL_GPL(free_percpu); + +/** + * pcpu_setup_static - initialize kernel static percpu area + * @populate_pte_fn: callback to allocate pagetable + * @pages: num_possible_cpus() * PFN_UP(cpu_size) pages + * + * Initialize kernel static percpu area. The caller should allocate + * all the necessary pages and pass them in @pages. + * @populate_pte_fn() is called on each page to be used for percpu + * mapping and is responsible for making sure all the necessary page + * tables for the page is allocated. + * + * RETURNS: + * The determined pcpu_unit_size which can be used to initialize + * percpu access. + */ +size_t __init pcpu_setup_static(pcpu_populate_pte_fn_t populate_pte_fn, + struct page **pages, size_t cpu_size) +{ + static struct vm_struct static_vm; + struct pcpu_chunk *static_chunk; + int nr_cpu_pages = DIV_ROUND_UP(cpu_size, PAGE_SIZE); + unsigned int cpu; + int err, i; + + pcpu_unit_pages_shift = max_t(int, PCPU_MIN_UNIT_PAGES_SHIFT, + order_base_2(cpu_size) - PAGE_SHIFT); + + pcpu_static_size = cpu_size; + pcpu_unit_pages = 1 << pcpu_unit_pages_shift; + pcpu_unit_shift = PAGE_SHIFT + pcpu_unit_pages_shift; + pcpu_unit_size = 1 << pcpu_unit_shift; + pcpu_chunk_size = num_possible_cpus() * pcpu_unit_size; + pcpu_nr_slots = pcpu_size_to_slot(pcpu_unit_size) + 1; + pcpu_chunk_struct_size = sizeof(struct pcpu_chunk) + + (1 << pcpu_unit_pages_shift) * sizeof(struct page *); + + /* allocate chunk slots */ + pcpu_slot = alloc_bootmem(pcpu_nr_slots * sizeof(pcpu_slot[0])); + for (i = 0; i < pcpu_nr_slots; i++) + INIT_LIST_HEAD(&pcpu_slot[i]); + + /* init and register vm area */ + static_vm.flags = VM_ALLOC; + static_vm.size = pcpu_chunk_size; + vm_area_register_early(&static_vm); + + /* init static_chunk */ + static_chunk = alloc_bootmem(pcpu_chunk_struct_size); + INIT_LIST_HEAD(&static_chunk->list); + static_chunk->vm = &static_vm; + static_chunk->free_size = pcpu_unit_size - pcpu_static_size; + static_chunk->contig_hint = static_chunk->free_size; + + /* assign pages and map them */ + for_each_possible_cpu(cpu) { + for (i = 0; i < nr_cpu_pages; i++) { + *pcpu_chunk_pagep(static_chunk, cpu, i) = *pages++; + populate_pte_fn(pcpu_chunk_addr(static_chunk, cpu, i)); + } + } + + err = pcpu_map(static_chunk, 0, nr_cpu_pages); + if (err) + panic("failed to setup static percpu area, err=%d\n", err); + + /* link static_chunk in */ + pcpu_chunk_relocate(static_chunk, -1); + pcpu_chunk_addr_insert(static_chunk); + + /* we're done */ + pcpu_base_addr = (void *)pcpu_chunk_addr(static_chunk, 0, 0); + return pcpu_unit_size; +} -- cgit From 11124411aa95827404d6bfdfc14c908e1b54513c Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 20 Feb 2009 16:29:09 +0900 Subject: x86: convert to the new dynamic percpu allocator Impact: use new dynamic allocator, unified access to static/dynamic percpu memory Convert to the new dynamic percpu allocator. * implement populate_extra_pte() for both 32 and 64 * update setup_per_cpu_areas() to use pcpu_setup_static() * define __addr_to_pcpu_ptr() and __pcpu_ptr_to_addr() * define config HAVE_DYNAMIC_PER_CPU_AREA Signed-off-by: Tejun Heo --- arch/x86/Kconfig | 3 ++ arch/x86/include/asm/percpu.h | 8 ++++++ arch/x86/include/asm/pgtable.h | 1 + arch/x86/kernel/setup_percpu.c | 62 +++++++++++++++++++++++++++--------------- arch/x86/mm/init_32.c | 10 +++++++ arch/x86/mm/init_64.c | 19 +++++++++++++ 6 files changed, 81 insertions(+), 22 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index f760a22f95d..d3f6eadfd4b 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -135,6 +135,9 @@ config ARCH_HAS_CACHE_LINE_SIZE config HAVE_SETUP_PER_CPU_AREA def_bool y +config HAVE_DYNAMIC_PER_CPU_AREA + def_bool y + config HAVE_CPUMASK_OF_CPU_MAP def_bool X86_64_SMP diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index aee103b26d0..8f1d2fbec1d 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h @@ -43,6 +43,14 @@ #else /* ...!ASSEMBLY */ #include +#include + +#define __addr_to_pcpu_ptr(addr) \ + (void *)((unsigned long)(addr) - (unsigned long)pcpu_base_addr \ + + (unsigned long)__per_cpu_start) +#define __pcpu_ptr_to_addr(ptr) \ + (void *)((unsigned long)(ptr) + (unsigned long)pcpu_base_addr \ + - (unsigned long)__per_cpu_start) #ifdef CONFIG_SMP #define __percpu_arg(x) "%%"__stringify(__percpu_seg)":%P" #x diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 6f7c102018b..dd91c2515c6 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -402,6 +402,7 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, /* Install a pte for a particular vaddr in kernel space. */ void set_pte_vaddr(unsigned long vaddr, pte_t pte); +void populate_extra_pte(unsigned long vaddr); #ifdef CONFIG_X86_32 extern void native_pagetable_setup_start(pgd_t *base); diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index d992e6cff73..2dce4355821 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -61,38 +61,56 @@ static inline void setup_percpu_segment(int cpu) */ void __init setup_per_cpu_areas(void) { - ssize_t size; - char *ptr; - int cpu; - - /* Copy section for each CPU (we discard the original) */ - size = roundup(PERCPU_ENOUGH_ROOM, PAGE_SIZE); + ssize_t size = __per_cpu_end - __per_cpu_start; + unsigned int nr_cpu_pages = DIV_ROUND_UP(size, PAGE_SIZE); + static struct page **pages; + size_t pages_size; + unsigned int cpu, i, j; + unsigned long delta; + size_t pcpu_unit_size; pr_info("NR_CPUS:%d nr_cpumask_bits:%d nr_cpu_ids:%d nr_node_ids:%d\n", NR_CPUS, nr_cpumask_bits, nr_cpu_ids, nr_node_ids); + pr_info("PERCPU: Allocating %zd bytes for static per cpu data\n", size); - pr_info("PERCPU: Allocating %zd bytes of per cpu data\n", size); + pages_size = nr_cpu_pages * num_possible_cpus() * sizeof(pages[0]); + pages = alloc_bootmem(pages_size); + j = 0; for_each_possible_cpu(cpu) { + void *ptr; + + for (i = 0; i < nr_cpu_pages; i++) { #ifndef CONFIG_NEED_MULTIPLE_NODES - ptr = alloc_bootmem_pages(size); + ptr = alloc_bootmem_pages(PAGE_SIZE); #else - int node = early_cpu_to_node(cpu); - if (!node_online(node) || !NODE_DATA(node)) { - ptr = alloc_bootmem_pages(size); - pr_info("cpu %d has no node %d or node-local memory\n", - cpu, node); - pr_debug("per cpu data for cpu%d at %016lx\n", - cpu, __pa(ptr)); - } else { - ptr = alloc_bootmem_pages_node(NODE_DATA(node), size); - pr_debug("per cpu data for cpu%d on node%d at %016lx\n", - cpu, node, __pa(ptr)); - } + int node = early_cpu_to_node(cpu); + + if (!node_online(node) || !NODE_DATA(node)) { + ptr = alloc_bootmem_pages(PAGE_SIZE); + pr_info("cpu %d has no node %d or node-local " + "memory\n", cpu, node); + pr_debug("per cpu data for cpu%d at %016lx\n", + cpu, __pa(ptr)); + } else { + ptr = alloc_bootmem_pages_node(NODE_DATA(node), + PAGE_SIZE); + pr_debug("per cpu data for cpu%d on node%d " + "at %016lx\n", cpu, node, __pa(ptr)); + } #endif + memcpy(ptr, __per_cpu_load + i * PAGE_SIZE, PAGE_SIZE); + pages[j++] = virt_to_page(ptr); + } + } + + pcpu_unit_size = pcpu_setup_static(populate_extra_pte, pages, size); - memcpy(ptr, __per_cpu_load, __per_cpu_end - __per_cpu_start); - per_cpu_offset(cpu) = ptr - __per_cpu_start; + free_bootmem(__pa(pages), pages_size); + + delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start; + for_each_possible_cpu(cpu) { + per_cpu_offset(cpu) = delta + cpu * pcpu_unit_size; per_cpu(this_cpu_off, cpu) = per_cpu_offset(cpu); per_cpu(cpu_number, cpu) = cpu; setup_percpu_segment(cpu); diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index 00263bf07a8..8b1a0ef7f87 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c @@ -137,6 +137,16 @@ static pte_t * __init one_page_table_init(pmd_t *pmd) return pte_offset_kernel(pmd, 0); } +void __init populate_extra_pte(unsigned long vaddr) +{ + int pgd_idx = pgd_index(vaddr); + int pmd_idx = pmd_index(vaddr); + pmd_t *pmd; + + pmd = one_md_table_init(swapper_pg_dir + pgd_idx); + one_page_table_init(pmd + pmd_idx); +} + static pte_t *__init page_table_kmap_check(pte_t *pte, pmd_t *pmd, unsigned long vaddr, pte_t *lastpte) { diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index e6d36b49025..7f91e2cdc4c 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -223,6 +223,25 @@ set_pte_vaddr(unsigned long vaddr, pte_t pteval) set_pte_vaddr_pud(pud_page, vaddr, pteval); } +void __init populate_extra_pte(unsigned long vaddr) +{ + pgd_t *pgd; + pud_t *pud; + + pgd = pgd_offset_k(vaddr); + if (pgd_none(*pgd)) { + pud = (pud_t *)spp_getpage(); + pgd_populate(&init_mm, pgd, pud); + if (pud != pud_offset(pgd, 0)) { + printk(KERN_ERR "PAGETABLE BUG #00! %p <-> %p\n", + pud, pud_offset(pgd, 0)); + return; + } + } + + set_pte_vaddr_pud((pud_t *)pgd_page_vaddr(*pgd), vaddr, __pte(0)); +} + /* * Create large page table mappings for a range of physical addresses. */ -- cgit From 07a66d7c53a538e1a9759954a82bb6c07365eff9 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 20 Feb 2009 08:04:13 +0100 Subject: x86: use the right protections for split-up pagetables Steven Rostedt found a bug in where in his modified kernel ftrace was unable to modify the kernel text, due to the PMD itself having been marked read-only as well in split_large_page(). The fix, suggested by Linus, is to not try to 'clone' the reference protection of a huge-page, but to use the standard (and permissive) page protection bits of KERNPG_TABLE. The 'cloning' makes sense for the ptes but it's a confused and incorrect concept at the page table level - because the pagetable entry is a set of all ptes and hence cannot 'clone' any single protection attribute - the ptes can be any mixture of protections. With the permissive KERNPG_TABLE, even if the pte protections get changed after this point (due to ftrace doing code-patching or other similar activities like kprobes), the resulting combined protections will still be correct and the pte's restrictive (or permissive) protections will control it. Also update the comment. This bug was there for a long time but has not caused visible problems before as it needs a rather large read-only area to trigger. Steve possibly hacked his kernel with some really large arrays or so. Anyway, the bug is definitely worth fixing. [ Huang Ying also experienced problems in this area when writing the EFI code, but the real bug in split_large_page() was not realized back then. ] Reported-by: Steven Rostedt Reported-by: Huang Ying Acked-by: Linus Torvalds Signed-off-by: Ingo Molnar --- arch/x86/mm/pageattr.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 8ca0d8566fc..7be47d1a97e 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -508,18 +508,13 @@ static int split_large_page(pte_t *kpte, unsigned long address) #endif /* - * Install the new, split up pagetable. Important details here: + * Install the new, split up pagetable. * - * On Intel the NX bit of all levels must be cleared to make a - * page executable. See section 4.13.2 of Intel 64 and IA-32 - * Architectures Software Developer's Manual). - * - * Mark the entry present. The current mapping might be - * set to not present, which we preserved above. + * We use the standard kernel pagetable protections for the new + * pagetable protections, the actual ptes set above control the + * primary protection behavior: */ - ref_prot = pte_pgprot(pte_mkexec(pte_clrhuge(*kpte))); - pgprot_val(ref_prot) |= _PAGE_PRESENT; - __set_pmd_pte(kpte, address, mk_pte(base, ref_prot)); + __set_pmd_pte(kpte, address, mk_pte(base, __pgprot(_KERNPG_TABLE))); base = NULL; out_unlock: -- cgit From 494ef10ebacc23679350a17483879366d8bafebd Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Thu, 19 Feb 2009 14:40:29 -0800 Subject: wimax/i2400m: driver loads firmware v1.4 instead of v1.3 This is a one liner change to have the driver use by default the v1.4 of the i2400m firmware instead of v1.3. The v1.4 version of the firmware has been submitted to David Woodhouse for inclusion in the linux-firmware tree and it is already available at http://linuxwimax.org/Download. The reason for this change is that the 1.3 release of the user space software and firmware has a few issues that will make it difficult to use with currently deployed commercial networks such as Xohm and Clearwire. As well, the new 1.4 release of the user space software (which matches the 1.4 firmware) has intermitent issues with the 1.3 firmware. The 1.4 release in http://linuxwimax.org/Download has been widely deployed and tested with the codebase in 2.6.29-rc, the 1.4 firmware and the 1.4 user space components. We understand it is quite late in the rc process for such a change, but would like to ask for the change to be taken into consideration. Alternatively, a user could always force feed a 1.4 firmware into a driver that doesn't have this modification by: $ cd /lib/firmware $ mv i2400m-fw-usb-1.3.sbcf i2400m-fw-usb-1.3.real.sbcf $ ln -sf i2400m-fw-usb-1.4.sbc i2400m-fw-usb-1.3.sbcf Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: David S. Miller --- drivers/net/wimax/i2400m/i2400m.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h index 067c871cc22..3b9d27ea295 100644 --- a/drivers/net/wimax/i2400m/i2400m.h +++ b/drivers/net/wimax/i2400m/i2400m.h @@ -157,7 +157,7 @@ enum { /* Firmware version we request when pulling the fw image file */ -#define I2400M_FW_VERSION "1.3" +#define I2400M_FW_VERSION "1.4" /** -- cgit From 9df8f4e3ee760c14211a5f484e9ee4f0bc0c566b Mon Sep 17 00:00:00 2001 From: Steve Glendinning Date: Mon, 16 Feb 2009 07:46:06 +0000 Subject: smsc9420: fix another postfixed timeout Roel Kluin recently fixed several instances where variables reach -1, but 0 is tested afterwards. This patch fixes another, so the timeout will be correctly detected and a warning printed. Signed-off-by: Steve Glendinning Signed-off-by: David S. Miller --- drivers/net/smsc9420.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c index a1e4b3895b3..83938e1953b 100644 --- a/drivers/net/smsc9420.c +++ b/drivers/net/smsc9420.c @@ -341,7 +341,7 @@ static int smsc9420_eeprom_send_cmd(struct smsc9420_pdata *pd, u32 op) do { msleep(1); e2cmd = smsc9420_reg_read(pd, E2P_CMD); - } while ((e2cmd & E2P_CMD_EPC_BUSY_) && (timeout--)); + } while ((e2cmd & E2P_CMD_EPC_BUSY_) && (--timeout)); if (!timeout) { smsc_info(HW, "TIMED OUT"); -- cgit From 62660e28084df3d8067ab855f326d3027808c569 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Wed, 18 Feb 2009 10:19:50 +0100 Subject: sundance: missing parentheses? Signed-off-by: Roel Kluin Signed-off-by: David S. Miller --- drivers/net/sundance.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index feaf0e0577d..43695b76606 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -909,7 +909,7 @@ static void check_duplex(struct net_device *dev) printk(KERN_INFO "%s: Setting %s-duplex based on MII #%d " "negotiated capability %4.4x.\n", dev->name, duplex ? "full" : "half", np->phys[0], negotiated); - iowrite16(ioread16(ioaddr + MACCtrl0) | duplex ? 0x20 : 0, ioaddr + MACCtrl0); + iowrite16(ioread16(ioaddr + MACCtrl0) | (duplex ? 0x20 : 0), ioaddr + MACCtrl0); } } -- cgit From 196b7e1b9cca9e187bb61fa7d60f04f4ab2c0592 Mon Sep 17 00:00:00 2001 From: Steve Glendinning Date: Sun, 15 Feb 2009 22:55:01 +0000 Subject: smsc9420: handle magic field of ethtool_eeprom ethtool.h says the driver should set the magic field in get_eeprom and verify it in set_eeprom. This patch adds this functionality using an arbitary driver-specific magic value constant (0x9420). Signed-off-by: Steve Glendinning Signed-off-by: David S. Miller --- drivers/net/smsc9420.c | 4 ++++ drivers/net/smsc9420.h | 1 + 2 files changed, 5 insertions(+) diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c index 83938e1953b..4e15ae068b3 100644 --- a/drivers/net/smsc9420.c +++ b/drivers/net/smsc9420.c @@ -413,6 +413,7 @@ static int smsc9420_ethtool_get_eeprom(struct net_device *dev, } memcpy(data, &eeprom_data[eeprom->offset], len); + eeprom->magic = SMSC9420_EEPROM_MAGIC; eeprom->len = len; return 0; } @@ -423,6 +424,9 @@ static int smsc9420_ethtool_set_eeprom(struct net_device *dev, struct smsc9420_pdata *pd = netdev_priv(dev); int ret; + if (eeprom->magic != SMSC9420_EEPROM_MAGIC) + return -EINVAL; + smsc9420_eeprom_enable_access(pd); smsc9420_eeprom_send_cmd(pd, E2P_CMD_EPC_CMD_EWEN_); ret = smsc9420_eeprom_write_location(pd, eeprom->offset, *data); diff --git a/drivers/net/smsc9420.h b/drivers/net/smsc9420.h index 69c351f93f8..e441402f77a 100644 --- a/drivers/net/smsc9420.h +++ b/drivers/net/smsc9420.h @@ -44,6 +44,7 @@ #define LAN_REGISTER_EXTENT (0x400) #define SMSC9420_EEPROM_SIZE ((u32)11) +#define SMSC9420_EEPROM_MAGIC (0x9420) #define PKT_BUF_SZ (VLAN_ETH_FRAME_LEN + NET_IP_ALIGN + 4) -- cgit From 2cf0dbed27af3f827a96db98c2535002902f6af0 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Fri, 20 Feb 2009 00:52:19 -0800 Subject: SMSC: timeout reaches -1 With a postfix decrement timeouts will reach -1 rather than 0, so the error path does not appear. Signed-off-by: Roel Kluin Signed-off-by: David S. Miller --- drivers/net/smsc911x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index 783c1a7b869..9a78daec2fe 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -1624,7 +1624,7 @@ static int smsc911x_eeprom_send_cmd(struct smsc911x_data *pdata, u32 op) do { msleep(1); e2cmd = smsc911x_reg_read(pdata, E2P_CMD); - } while ((e2cmd & E2P_CMD_EPC_BUSY_) && (timeout--)); + } while ((e2cmd & E2P_CMD_EPC_BUSY_) && (--timeout)); if (!timeout) { SMSC_TRACE(DRV, "TIMED OUT"); -- cgit From 0d5048a96fc51d976ac777e3d78762b4dd241693 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 20 Feb 2009 00:54:44 -0800 Subject: ISDN: fix sc/shmem printk format warning Fix isdn/sc/shmem.c printk format warning: drivers/isdn/sc/shmem.c:57: warning: format '%d' expects type 'int', but argument 3 has type 'size_t' Signed-off-by: Randy Dunlap Signed-off-by: David S. Miller --- drivers/isdn/sc/shmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/isdn/sc/shmem.c b/drivers/isdn/sc/shmem.c index 712220cef13..7f16d75d2d8 100644 --- a/drivers/isdn/sc/shmem.c +++ b/drivers/isdn/sc/shmem.c @@ -54,7 +54,7 @@ void memcpy_toshmem(int card, void *dest, const void *src, size_t n) spin_unlock_irqrestore(&sc_adapter[card]->lock, flags); pr_debug("%s: set page to %#x\n",sc_adapter[card]->devicename, ((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80); - pr_debug("%s: copying %d bytes from %#lx to %#lx\n", + pr_debug("%s: copying %zu bytes from %#lx to %#lx\n", sc_adapter[card]->devicename, n, (unsigned long) src, sc_adapter[card]->rambase + ((unsigned long) dest %0x4000)); -- cgit From d13c11f6f7324b4fe61720910ee54184c38d2fea Mon Sep 17 00:00:00 2001 From: roel kluin Date: Mon, 16 Feb 2009 04:02:04 +0000 Subject: sungem: another error printed one too early Another error was printed one too early. Signed-off-by: Roel Kluin Signed-off-by: David S. Miller --- drivers/net/sungem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 49187634106..8d64b1da046 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -1157,7 +1157,7 @@ static void gem_pcs_reset(struct gem *gp) if (limit-- <= 0) break; } - if (limit <= 0) + if (limit < 0) printk(KERN_WARNING "%s: PCS reset bit would not clear.\n", gp->dev->name); } -- cgit From ecab22aa6dc9d42ca52de2cad0854b4c6bd85ac9 Mon Sep 17 00:00:00 2001 From: Vegard Nossum Date: Fri, 20 Feb 2009 11:56:38 +0100 Subject: x86: use symbolic constants for MSR_IA32_MISC_ENABLE bits Impact: Cleanup. No functional changes. Signed-off-by: Vegard Nossum Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/cpufreq/e_powersaver.c | 6 +++--- arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c | 6 +++--- arch/x86/kernel/cpu/intel.c | 4 ++-- arch/x86/kernel/cpu/mcheck/mce_intel_64.c | 6 +++--- arch/x86/kernel/cpu/mcheck/p4.c | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/x86/kernel/cpu/cpufreq/e_powersaver.c b/arch/x86/kernel/cpu/cpufreq/e_powersaver.c index c2f930d8664..41ab3f064cb 100644 --- a/arch/x86/kernel/cpu/cpufreq/e_powersaver.c +++ b/arch/x86/kernel/cpu/cpufreq/e_powersaver.c @@ -204,12 +204,12 @@ static int eps_cpu_init(struct cpufreq_policy *policy) } /* Enable Enhanced PowerSaver */ rdmsrl(MSR_IA32_MISC_ENABLE, val); - if (!(val & 1 << 16)) { - val |= 1 << 16; + if (!(val & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) { + val |= MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP; wrmsrl(MSR_IA32_MISC_ENABLE, val); /* Can be locked at 0 */ rdmsrl(MSR_IA32_MISC_ENABLE, val); - if (!(val & 1 << 16)) { + if (!(val & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) { printk(KERN_INFO "eps: Can't enable Enhanced PowerSaver\n"); return -ENODEV; } diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c index f08998278a3..c9f1fdc0283 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c @@ -390,14 +390,14 @@ static int centrino_cpu_init(struct cpufreq_policy *policy) enable it if not. */ rdmsr(MSR_IA32_MISC_ENABLE, l, h); - if (!(l & (1<<16))) { - l |= (1<<16); + if (!(l & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) { + l |= MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP; dprintk("trying to enable Enhanced SpeedStep (%x)\n", l); wrmsr(MSR_IA32_MISC_ENABLE, l, h); /* check to see if it stuck */ rdmsr(MSR_IA32_MISC_ENABLE, l, h); - if (!(l & (1<<16))) { + if (!(l & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) { printk(KERN_INFO PFX "couldn't enable Enhanced SpeedStep\n"); return -ENODEV; diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 1f137a87d4b..c8ff69a4668 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -147,10 +147,10 @@ static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c) */ if ((c->x86 == 15) && (c->x86_model == 1) && (c->x86_mask == 1)) { rdmsr(MSR_IA32_MISC_ENABLE, lo, hi); - if ((lo & (1<<9)) == 0) { + if ((lo & MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE) == 0) { printk (KERN_INFO "CPU: C0 stepping P4 Xeon detected.\n"); printk (KERN_INFO "CPU: Disabling hardware prefetching (Errata 037)\n"); - lo |= (1<<9); /* Disable hw prefetching */ + lo |= MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE; wrmsr (MSR_IA32_MISC_ENABLE, lo, hi); } } diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c index 5e8c79e748a..ae00938ea50 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c @@ -49,13 +49,13 @@ static void __cpuinit intel_init_thermal(struct cpuinfo_x86 *c) */ rdmsr(MSR_IA32_MISC_ENABLE, l, h); h = apic_read(APIC_LVTTHMR); - if ((l & (1 << 3)) && (h & APIC_DM_SMI)) { + if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) { printk(KERN_DEBUG "CPU%d: Thermal monitoring handled by SMI\n", cpu); return; } - if (cpu_has(c, X86_FEATURE_TM2) && (l & (1 << 13))) + if (cpu_has(c, X86_FEATURE_TM2) && (l & MSR_IA32_MISC_ENABLE_TM2)) tm2 = 1; if (h & APIC_VECTOR_MASK) { @@ -73,7 +73,7 @@ static void __cpuinit intel_init_thermal(struct cpuinfo_x86 *c) wrmsr(MSR_IA32_THERM_INTERRUPT, l | 0x03, h); rdmsr(MSR_IA32_MISC_ENABLE, l, h); - wrmsr(MSR_IA32_MISC_ENABLE, l | (1 << 3), h); + wrmsr(MSR_IA32_MISC_ENABLE, l | MSR_IA32_MISC_ENABLE_TM1, h); l = apic_read(APIC_LVTTHMR); apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED); diff --git a/arch/x86/kernel/cpu/mcheck/p4.c b/arch/x86/kernel/cpu/mcheck/p4.c index 9b60fce09f7..f53bdcbaf38 100644 --- a/arch/x86/kernel/cpu/mcheck/p4.c +++ b/arch/x86/kernel/cpu/mcheck/p4.c @@ -85,7 +85,7 @@ static void intel_init_thermal(struct cpuinfo_x86 *c) */ rdmsr(MSR_IA32_MISC_ENABLE, l, h); h = apic_read(APIC_LVTTHMR); - if ((l & (1<<3)) && (h & APIC_DM_SMI)) { + if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) { printk(KERN_DEBUG "CPU%d: Thermal monitoring handled by SMI\n", cpu); return; /* -EBUSY */ @@ -111,7 +111,7 @@ static void intel_init_thermal(struct cpuinfo_x86 *c) vendor_thermal_interrupt = intel_thermal_interrupt; rdmsr(MSR_IA32_MISC_ENABLE, l, h); - wrmsr(MSR_IA32_MISC_ENABLE, l | (1<<3), h); + wrmsr(MSR_IA32_MISC_ENABLE, l | MSR_IA32_MISC_ENABLE_TM1, h); l = apic_read(APIC_LVTTHMR); apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED); -- cgit From 55290e1932102f57ea17e7cff895914c2dbdb4c4 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 20 Feb 2009 15:59:01 +0100 Subject: ALSA: hda - Fix parse of init_verbs sysfs entry Fixed the parse of init_verbs hwdep sysfs entry. Simplieied using sscanf. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_hwdep.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c index 482fb0304ca..4ae51dcb81a 100644 --- a/sound/pci/hda/hda_hwdep.c +++ b/sound/pci/hda/hda_hwdep.c @@ -277,18 +277,19 @@ static ssize_t init_verbs_store(struct device *dev, { struct snd_hwdep *hwdep = dev_get_drvdata(dev); struct hda_codec *codec = hwdep->private_data; - char *p; - struct hda_verb verb, *v; + struct hda_verb *v; + int nid, verb, param; - verb.nid = simple_strtoul(buf, &p, 0); - verb.verb = simple_strtoul(p, &p, 0); - verb.param = simple_strtoul(p, &p, 0); - if (!verb.nid || !verb.verb || !verb.param) + if (sscanf(buf, "%i %i %i", &nid, &verb, ¶m) != 3) + return -EINVAL; + if (!nid || !verb) return -EINVAL; v = snd_array_new(&codec->init_verbs); if (!v) return -ENOMEM; - *v = verb; + v->nid = nid; + v->verb = verb; + v->param = param; return count; } -- cgit From 2cfbd50b536c878e58ab3681c4e944fa3d99b415 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Fri, 20 Feb 2009 10:55:10 -0500 Subject: Btrfs: check file pointer in btrfs_sync_file fsync can be called by NFS with a null file pointer, and btrfs was oopsing in this case. Signed-off-by: Chris Mason --- fs/btrfs/file.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 3e8023efaff..872f104576e 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1222,7 +1222,7 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) /* * ok we haven't committed the transaction yet, lets do a commit */ - if (file->private_data) + if (file && file->private_data) btrfs_ioctl_trans_end(file); trans = btrfs_start_transaction(root, 1); @@ -1231,7 +1231,7 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) goto out; } - ret = btrfs_log_dentry_safe(trans, root, file->f_dentry); + ret = btrfs_log_dentry_safe(trans, root, dentry); if (ret < 0) goto out; @@ -1245,7 +1245,7 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) * file again, but that will end up using the synchronization * inside btrfs_sync_log to keep things safe. */ - mutex_unlock(&file->f_dentry->d_inode->i_mutex); + mutex_unlock(&dentry->d_inode->i_mutex); if (ret > 0) { ret = btrfs_commit_transaction(trans, root); @@ -1253,7 +1253,7 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) btrfs_sync_log(trans, root); ret = btrfs_end_transaction(trans, root); } - mutex_lock(&file->f_dentry->d_inode->i_mutex); + mutex_lock(&dentry->d_inode->i_mutex); out: return ret > 0 ? EIO : ret; } -- cgit From 6a63209fc02d5483371f07e4913ee8abad608051 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Fri, 20 Feb 2009 11:00:09 -0500 Subject: Btrfs: add better -ENOSPC handling This is a step in the direction of better -ENOSPC handling. Instead of checking the global bytes counter we check the space_info bytes counters to make sure we have enough space. If we don't we go ahead and try to allocate a new chunk, and then if that fails we return -ENOSPC. This patch adds two counters to btrfs_space_info, bytes_delalloc and bytes_may_use. bytes_delalloc account for extents we've actually setup for delalloc and will be allocated at some point down the line. bytes_may_use is to keep track of how many bytes we may use for delalloc at some point. When we actually set the extent_bit for the delalloc bytes we subtract the reserved bytes from the bytes_may_use counter. This keeps us from not actually being able to allocate space for any delalloc bytes. Signed-off-by: Josef Bacik --- fs/btrfs/btrfs_inode.h | 8 ++ fs/btrfs/ctree.h | 40 ++++++--- fs/btrfs/extent-tree.c | 215 +++++++++++++++++++++++++++++++++++++++++++++---- fs/btrfs/file.c | 16 +++- fs/btrfs/inode.c | 62 ++++---------- fs/btrfs/ioctl.c | 6 +- 6 files changed, 271 insertions(+), 76 deletions(-) diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index a8c9693b75a..72677ce2b74 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h @@ -66,6 +66,9 @@ struct btrfs_inode { */ struct list_head delalloc_inodes; + /* the space_info for where this inode's data allocations are done */ + struct btrfs_space_info *space_info; + /* full 64 bit generation number, struct vfs_inode doesn't have a big * enough field for this. */ @@ -94,6 +97,11 @@ struct btrfs_inode { */ u64 delalloc_bytes; + /* total number of bytes that may be used for this inode for + * delalloc + */ + u64 reserved_bytes; + /* * the size of the file stored in the metadata on disk. data=ordered * means the in-memory i_size might be larger than the size on disk diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 766b31ae318..82491ba8fa4 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -596,13 +596,27 @@ struct btrfs_block_group_item { struct btrfs_space_info { u64 flags; - u64 total_bytes; - u64 bytes_used; - u64 bytes_pinned; - u64 bytes_reserved; - u64 bytes_readonly; - int full; - int force_alloc; + + u64 total_bytes; /* total bytes in the space */ + u64 bytes_used; /* total bytes used on disk */ + u64 bytes_pinned; /* total bytes pinned, will be freed when the + transaction finishes */ + u64 bytes_reserved; /* total bytes the allocator has reserved for + current allocations */ + u64 bytes_readonly; /* total bytes that are read only */ + + /* delalloc accounting */ + u64 bytes_delalloc; /* number of bytes reserved for allocation, + this space is not necessarily reserved yet + by the allocator */ + u64 bytes_may_use; /* number of bytes that may be used for + delalloc */ + + int full; /* indicates that we cannot allocate any more + chunks for this space */ + int force_alloc; /* set if we need to force a chunk alloc for + this space */ + struct list_head list; /* for block groups in our same type */ @@ -1782,6 +1796,16 @@ int btrfs_add_dead_reloc_root(struct btrfs_root *root); int btrfs_cleanup_reloc_trees(struct btrfs_root *root); int btrfs_reloc_clone_csums(struct inode *inode, u64 file_pos, u64 len); u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags); +void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *ionde); +int btrfs_check_metadata_free_space(struct btrfs_root *root); +int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode, + u64 bytes); +void btrfs_free_reserved_data_space(struct btrfs_root *root, + struct inode *inode, u64 bytes); +void btrfs_delalloc_reserve_space(struct btrfs_root *root, struct inode *inode, + u64 bytes); +void btrfs_delalloc_free_space(struct btrfs_root *root, struct inode *inode, + u64 bytes); /* ctree.c */ int btrfs_previous_item(struct btrfs_root *root, struct btrfs_path *path, u64 min_objectid, @@ -2027,8 +2051,6 @@ int btrfs_merge_bio_hook(struct page *page, unsigned long offset, unsigned long btrfs_force_ra(struct address_space *mapping, struct file_ra_state *ra, struct file *file, pgoff_t offset, pgoff_t last_index); -int btrfs_check_free_space(struct btrfs_root *root, u64 num_required, - int for_del); int btrfs_page_mkwrite(struct vm_area_struct *vma, struct page *page); int btrfs_readpage(struct file *file, struct page *page); void btrfs_delete_inode(struct inode *inode); diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 0a5d796c9f7..e11875e97c2 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -60,6 +60,10 @@ static int update_block_group(struct btrfs_trans_handle *trans, u64 bytenr, u64 num_bytes, int alloc, int mark_free); +static int do_chunk_alloc(struct btrfs_trans_handle *trans, + struct btrfs_root *extent_root, u64 alloc_bytes, + u64 flags, int force); + static int block_group_bits(struct btrfs_block_group_cache *cache, u64 bits) { return (cache->flags & bits) == bits; @@ -1909,6 +1913,7 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags, found->bytes_pinned = 0; found->bytes_reserved = 0; found->bytes_readonly = 0; + found->bytes_delalloc = 0; found->full = 0; found->force_alloc = 0; *space_info = found; @@ -1972,6 +1977,196 @@ u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags) return flags; } +static u64 btrfs_get_alloc_profile(struct btrfs_root *root, u64 data) +{ + struct btrfs_fs_info *info = root->fs_info; + u64 alloc_profile; + + if (data) { + alloc_profile = info->avail_data_alloc_bits & + info->data_alloc_profile; + data = BTRFS_BLOCK_GROUP_DATA | alloc_profile; + } else if (root == root->fs_info->chunk_root) { + alloc_profile = info->avail_system_alloc_bits & + info->system_alloc_profile; + data = BTRFS_BLOCK_GROUP_SYSTEM | alloc_profile; + } else { + alloc_profile = info->avail_metadata_alloc_bits & + info->metadata_alloc_profile; + data = BTRFS_BLOCK_GROUP_METADATA | alloc_profile; + } + + return btrfs_reduce_alloc_profile(root, data); +} + +void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *inode) +{ + u64 alloc_target; + + alloc_target = btrfs_get_alloc_profile(root, 1); + BTRFS_I(inode)->space_info = __find_space_info(root->fs_info, + alloc_target); +} + +/* + * for now this just makes sure we have at least 5% of our metadata space free + * for use. + */ +int btrfs_check_metadata_free_space(struct btrfs_root *root) +{ + struct btrfs_fs_info *info = root->fs_info; + struct btrfs_space_info *meta_sinfo; + u64 alloc_target, thresh; + + /* get the space info for where the metadata will live */ + alloc_target = btrfs_get_alloc_profile(root, 0); + meta_sinfo = __find_space_info(info, alloc_target); + + /* + * if the metadata area isn't maxed out then there is no sense in + * checking how much is used, since we can always allocate a new chunk + */ + if (!meta_sinfo->full) + return 0; + + spin_lock(&meta_sinfo->lock); + thresh = meta_sinfo->total_bytes * 95; + + do_div(thresh, 100); + + if (meta_sinfo->bytes_used + meta_sinfo->bytes_reserved + + meta_sinfo->bytes_pinned + meta_sinfo->bytes_readonly > thresh) { + spin_unlock(&meta_sinfo->lock); + return -ENOSPC; + } + spin_unlock(&meta_sinfo->lock); + + return 0; +} + +/* + * This will check the space that the inode allocates from to make sure we have + * enough space for bytes. + */ +int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode, + u64 bytes) +{ + struct btrfs_space_info *data_sinfo; + int ret = 0; + + /* make sure bytes are sectorsize aligned */ + bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); + + data_sinfo = BTRFS_I(inode)->space_info; +again: + /* make sure we have enough space to handle the data first */ + spin_lock(&data_sinfo->lock); + if (data_sinfo->total_bytes - data_sinfo->bytes_used - + data_sinfo->bytes_delalloc - data_sinfo->bytes_reserved - + data_sinfo->bytes_pinned - data_sinfo->bytes_readonly - + data_sinfo->bytes_may_use < bytes) { + /* + * if we don't have enough free bytes in this space then we need + * to alloc a new chunk. + */ + if (!data_sinfo->full) { + u64 alloc_target; + struct btrfs_trans_handle *trans; + + data_sinfo->force_alloc = 1; + spin_unlock(&data_sinfo->lock); + + alloc_target = btrfs_get_alloc_profile(root, 1); + trans = btrfs_start_transaction(root, 1); + if (!trans) + return -ENOMEM; + + ret = do_chunk_alloc(trans, root->fs_info->extent_root, + bytes + 2 * 1024 * 1024, + alloc_target, 0); + btrfs_end_transaction(trans, root); + if (ret) + return ret; + goto again; + } + spin_unlock(&data_sinfo->lock); + printk(KERN_ERR "no space left, need %llu, %llu delalloc bytes" + ", %llu bytes_used, %llu bytes_reserved, " + "%llu bytes_pinned, %llu bytes_readonly, %llu may use" + "%llu total\n", bytes, data_sinfo->bytes_delalloc, + data_sinfo->bytes_used, data_sinfo->bytes_reserved, + data_sinfo->bytes_pinned, data_sinfo->bytes_readonly, + data_sinfo->bytes_may_use, data_sinfo->total_bytes); + return -ENOSPC; + } + data_sinfo->bytes_may_use += bytes; + BTRFS_I(inode)->reserved_bytes += bytes; + spin_unlock(&data_sinfo->lock); + + return btrfs_check_metadata_free_space(root); +} + +/* + * if there was an error for whatever reason after calling + * btrfs_check_data_free_space, call this so we can cleanup the counters. + */ +void btrfs_free_reserved_data_space(struct btrfs_root *root, + struct inode *inode, u64 bytes) +{ + struct btrfs_space_info *data_sinfo; + + /* make sure bytes are sectorsize aligned */ + bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); + + data_sinfo = BTRFS_I(inode)->space_info; + spin_lock(&data_sinfo->lock); + data_sinfo->bytes_may_use -= bytes; + BTRFS_I(inode)->reserved_bytes -= bytes; + spin_unlock(&data_sinfo->lock); +} + +/* called when we are adding a delalloc extent to the inode's io_tree */ +void btrfs_delalloc_reserve_space(struct btrfs_root *root, struct inode *inode, + u64 bytes) +{ + struct btrfs_space_info *data_sinfo; + + /* get the space info for where this inode will be storing its data */ + data_sinfo = BTRFS_I(inode)->space_info; + + /* make sure we have enough space to handle the data first */ + spin_lock(&data_sinfo->lock); + data_sinfo->bytes_delalloc += bytes; + + /* + * we are adding a delalloc extent without calling + * btrfs_check_data_free_space first. This happens on a weird + * writepage condition, but shouldn't hurt our accounting + */ + if (unlikely(bytes > BTRFS_I(inode)->reserved_bytes)) { + data_sinfo->bytes_may_use -= BTRFS_I(inode)->reserved_bytes; + BTRFS_I(inode)->reserved_bytes = 0; + } else { + data_sinfo->bytes_may_use -= bytes; + BTRFS_I(inode)->reserved_bytes -= bytes; + } + + spin_unlock(&data_sinfo->lock); +} + +/* called when we are clearing an delalloc extent from the inode's io_tree */ +void btrfs_delalloc_free_space(struct btrfs_root *root, struct inode *inode, + u64 bytes) +{ + struct btrfs_space_info *info; + + info = BTRFS_I(inode)->space_info; + + spin_lock(&info->lock); + info->bytes_delalloc -= bytes; + spin_unlock(&info->lock); +} + static int do_chunk_alloc(struct btrfs_trans_handle *trans, struct btrfs_root *extent_root, u64 alloc_bytes, u64 flags, int force) @@ -3105,6 +3300,10 @@ static void dump_space_info(struct btrfs_space_info *info, u64 bytes) (unsigned long long)(info->total_bytes - info->bytes_used - info->bytes_pinned - info->bytes_reserved), (info->full) ? "" : "not "); + printk(KERN_INFO "space_info total=%llu, pinned=%llu, delalloc=%llu," + " may_use=%llu, used=%llu\n", info->total_bytes, + info->bytes_pinned, info->bytes_delalloc, info->bytes_may_use, + info->bytes_used); down_read(&info->groups_sem); list_for_each_entry(cache, &info->block_groups, list) { @@ -3131,24 +3330,10 @@ static int __btrfs_reserve_extent(struct btrfs_trans_handle *trans, { int ret; u64 search_start = 0; - u64 alloc_profile; struct btrfs_fs_info *info = root->fs_info; - if (data) { - alloc_profile = info->avail_data_alloc_bits & - info->data_alloc_profile; - data = BTRFS_BLOCK_GROUP_DATA | alloc_profile; - } else if (root == root->fs_info->chunk_root) { - alloc_profile = info->avail_system_alloc_bits & - info->system_alloc_profile; - data = BTRFS_BLOCK_GROUP_SYSTEM | alloc_profile; - } else { - alloc_profile = info->avail_metadata_alloc_bits & - info->metadata_alloc_profile; - data = BTRFS_BLOCK_GROUP_METADATA | alloc_profile; - } + data = btrfs_get_alloc_profile(root, data); again: - data = btrfs_reduce_alloc_profile(root, data); /* * the only place that sets empty_size is btrfs_realloc_node, which * is not called recursively on allocations diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 872f104576e..dc78954861b 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1091,19 +1091,24 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, WARN_ON(num_pages > nrptrs); memset(pages, 0, sizeof(struct page *) * nrptrs); - ret = btrfs_check_free_space(root, write_bytes, 0); + ret = btrfs_check_data_free_space(root, inode, write_bytes); if (ret) goto out; ret = prepare_pages(root, file, pages, num_pages, pos, first_index, last_index, write_bytes); - if (ret) + if (ret) { + btrfs_free_reserved_data_space(root, inode, + write_bytes); goto out; + } ret = btrfs_copy_from_user(pos, num_pages, write_bytes, pages, buf); if (ret) { + btrfs_free_reserved_data_space(root, inode, + write_bytes); btrfs_drop_pages(pages, num_pages); goto out; } @@ -1111,8 +1116,11 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, ret = dirty_and_release_pages(NULL, root, file, pages, num_pages, pos, write_bytes); btrfs_drop_pages(pages, num_pages); - if (ret) + if (ret) { + btrfs_free_reserved_data_space(root, inode, + write_bytes); goto out; + } if (will_write) { btrfs_fdatawrite_range(inode->i_mapping, pos, @@ -1136,6 +1144,8 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, } out: mutex_unlock(&inode->i_mutex); + if (ret) + err = ret; out_nolock: kfree(pages); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 3cee77ae03c..7d4f948bc22 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -101,34 +101,6 @@ static int btrfs_init_inode_security(struct inode *inode, struct inode *dir) return err; } -/* - * a very lame attempt at stopping writes when the FS is 85% full. There - * are countless ways this is incorrect, but it is better than nothing. - */ -int btrfs_check_free_space(struct btrfs_root *root, u64 num_required, - int for_del) -{ - u64 total; - u64 used; - u64 thresh; - int ret = 0; - - spin_lock(&root->fs_info->delalloc_lock); - total = btrfs_super_total_bytes(&root->fs_info->super_copy); - used = btrfs_super_bytes_used(&root->fs_info->super_copy); - if (for_del) - thresh = total * 90; - else - thresh = total * 85; - - do_div(thresh, 100); - - if (used + root->fs_info->delalloc_bytes + num_required > thresh) - ret = -ENOSPC; - spin_unlock(&root->fs_info->delalloc_lock); - return ret; -} - /* * this does all the hard work for inserting an inline extent into * the btree. The caller should have done a btrfs_drop_extents so that @@ -1190,6 +1162,7 @@ static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end, */ if (!(old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) { struct btrfs_root *root = BTRFS_I(inode)->root; + btrfs_delalloc_reserve_space(root, inode, end - start + 1); spin_lock(&root->fs_info->delalloc_lock); BTRFS_I(inode)->delalloc_bytes += end - start + 1; root->fs_info->delalloc_bytes += end - start + 1; @@ -1223,9 +1196,12 @@ static int btrfs_clear_bit_hook(struct inode *inode, u64 start, u64 end, (unsigned long long)end - start + 1, (unsigned long long) root->fs_info->delalloc_bytes); + btrfs_delalloc_free_space(root, inode, (u64)-1); root->fs_info->delalloc_bytes = 0; BTRFS_I(inode)->delalloc_bytes = 0; } else { + btrfs_delalloc_free_space(root, inode, + end - start + 1); root->fs_info->delalloc_bytes -= end - start + 1; BTRFS_I(inode)->delalloc_bytes -= end - start + 1; } @@ -2245,10 +2221,6 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) root = BTRFS_I(dir)->root; - ret = btrfs_check_free_space(root, 1, 1); - if (ret) - goto fail; - trans = btrfs_start_transaction(root, 1); btrfs_set_trans_block_group(trans, dir); @@ -2261,7 +2233,6 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) nr = trans->blocks_used; btrfs_end_transaction_throttle(trans, root); -fail: btrfs_btree_balance_dirty(root, nr); return ret; } @@ -2284,10 +2255,6 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) return -ENOTEMPTY; } - ret = btrfs_check_free_space(root, 1, 1); - if (ret) - goto fail; - trans = btrfs_start_transaction(root, 1); btrfs_set_trans_block_group(trans, dir); @@ -2304,7 +2271,6 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) fail_trans: nr = trans->blocks_used; ret = btrfs_end_transaction_throttle(trans, root); -fail: btrfs_btree_balance_dirty(root, nr); if (ret && !err) @@ -2818,7 +2784,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t size) if (size <= hole_start) return 0; - err = btrfs_check_free_space(root, 1, 0); + err = btrfs_check_metadata_free_space(root); if (err) return err; @@ -3014,6 +2980,7 @@ static noinline void init_btrfs_i(struct inode *inode) bi->last_trans = 0; bi->logged_trans = 0; bi->delalloc_bytes = 0; + bi->reserved_bytes = 0; bi->disk_i_size = 0; bi->flags = 0; bi->index_cnt = (u64)-1; @@ -3035,6 +3002,7 @@ static int btrfs_init_locked_inode(struct inode *inode, void *p) inode->i_ino = args->ino; init_btrfs_i(inode); BTRFS_I(inode)->root = args->root; + btrfs_set_inode_space_info(args->root, inode); return 0; } @@ -3455,6 +3423,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, BTRFS_I(inode)->index_cnt = 2; BTRFS_I(inode)->root = root; BTRFS_I(inode)->generation = trans->transid; + btrfs_set_inode_space_info(root, inode); if (mode & S_IFDIR) owner = 0; @@ -3602,7 +3571,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, if (!new_valid_dev(rdev)) return -EINVAL; - err = btrfs_check_free_space(root, 1, 0); + err = btrfs_check_metadata_free_space(root); if (err) goto fail; @@ -3665,7 +3634,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, u64 objectid; u64 index = 0; - err = btrfs_check_free_space(root, 1, 0); + err = btrfs_check_metadata_free_space(root); if (err) goto fail; trans = btrfs_start_transaction(root, 1); @@ -3733,7 +3702,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, return -ENOENT; btrfs_inc_nlink(inode); - err = btrfs_check_free_space(root, 1, 0); + err = btrfs_check_metadata_free_space(root); if (err) goto fail; err = btrfs_set_inode_index(dir, &index); @@ -3779,7 +3748,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) u64 index = 0; unsigned long nr = 1; - err = btrfs_check_free_space(root, 1, 0); + err = btrfs_check_metadata_free_space(root); if (err) goto out_unlock; @@ -4336,7 +4305,7 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct page *page) u64 page_start; u64 page_end; - ret = btrfs_check_free_space(root, PAGE_CACHE_SIZE, 0); + ret = btrfs_check_data_free_space(root, inode, PAGE_CACHE_SIZE); if (ret) goto out; @@ -4349,6 +4318,7 @@ again: if ((page->mapping != inode->i_mapping) || (page_start >= size)) { + btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE); /* page got truncated out from underneath us */ goto out_unlock; } @@ -4631,7 +4601,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) return -EXDEV; - ret = btrfs_check_free_space(root, 1, 0); + ret = btrfs_check_metadata_free_space(root); if (ret) goto out_unlock; @@ -4749,7 +4719,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, if (name_len > BTRFS_MAX_INLINE_DATA_SIZE(root)) return -ENAMETOOLONG; - err = btrfs_check_free_space(root, 1, 0); + err = btrfs_check_metadata_free_space(root); if (err) goto out_fail; diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 988fdc8b49e..bca729fc80c 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -70,7 +70,7 @@ static noinline int create_subvol(struct btrfs_root *root, u64 index = 0; unsigned long nr = 1; - ret = btrfs_check_free_space(root, 1, 0); + ret = btrfs_check_metadata_free_space(root); if (ret) goto fail_commit; @@ -203,7 +203,7 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, if (!root->ref_cows) return -EINVAL; - ret = btrfs_check_free_space(root, 1, 0); + ret = btrfs_check_metadata_free_space(root); if (ret) goto fail_unlock; @@ -374,7 +374,7 @@ static int btrfs_defrag_file(struct file *file) unsigned long i; int ret; - ret = btrfs_check_free_space(root, inode->i_size, 0); + ret = btrfs_check_data_free_space(root, inode, inode->i_size); if (ret) return -ENOSPC; -- cgit From 4e06bdd6cbd5105376e7caf4e683ed131e777389 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Fri, 20 Feb 2009 10:59:53 -0500 Subject: Btrfs: try committing transaction before returning ENOSPC This fixes a problem where we could return -ENOSPC when we may actually have plenty of space, the space is just pinned. Instead of returning -ENOSPC immediately, commit the transaction first and then try and do the allocation again. This patch also does chunk allocation for metadata if we pass the 80% threshold for metadata space. This will help with stack usage since the chunk allocation will happen early on, instead of when the allocation is happening. Signed-off-by: Josef Bacik --- fs/btrfs/extent-tree.c | 57 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index e11875e97c2..6b5966aacf4 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -2017,26 +2017,49 @@ int btrfs_check_metadata_free_space(struct btrfs_root *root) struct btrfs_fs_info *info = root->fs_info; struct btrfs_space_info *meta_sinfo; u64 alloc_target, thresh; + int committed = 0, ret; /* get the space info for where the metadata will live */ alloc_target = btrfs_get_alloc_profile(root, 0); meta_sinfo = __find_space_info(info, alloc_target); - /* - * if the metadata area isn't maxed out then there is no sense in - * checking how much is used, since we can always allocate a new chunk - */ - if (!meta_sinfo->full) - return 0; - +again: spin_lock(&meta_sinfo->lock); - thresh = meta_sinfo->total_bytes * 95; + if (!meta_sinfo->full) + thresh = meta_sinfo->total_bytes * 80; + else + thresh = meta_sinfo->total_bytes * 95; do_div(thresh, 100); if (meta_sinfo->bytes_used + meta_sinfo->bytes_reserved + meta_sinfo->bytes_pinned + meta_sinfo->bytes_readonly > thresh) { + struct btrfs_trans_handle *trans; + if (!meta_sinfo->full) { + meta_sinfo->force_alloc = 1; + spin_unlock(&meta_sinfo->lock); + + trans = btrfs_start_transaction(root, 1); + if (!trans) + return -ENOMEM; + + ret = do_chunk_alloc(trans, root->fs_info->extent_root, + 2 * 1024 * 1024, alloc_target, 0); + btrfs_end_transaction(trans, root); + goto again; + } spin_unlock(&meta_sinfo->lock); + + if (!committed) { + committed = 1; + trans = btrfs_join_transaction(root, 1); + if (!trans) + return -ENOMEM; + ret = btrfs_commit_transaction(trans, root); + if (ret) + return ret; + goto again; + } return -ENOSPC; } spin_unlock(&meta_sinfo->lock); @@ -2052,7 +2075,7 @@ int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode, u64 bytes) { struct btrfs_space_info *data_sinfo; - int ret = 0; + int ret = 0, committed = 0; /* make sure bytes are sectorsize aligned */ bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); @@ -2065,13 +2088,14 @@ again: data_sinfo->bytes_delalloc - data_sinfo->bytes_reserved - data_sinfo->bytes_pinned - data_sinfo->bytes_readonly - data_sinfo->bytes_may_use < bytes) { + struct btrfs_trans_handle *trans; + /* * if we don't have enough free bytes in this space then we need * to alloc a new chunk. */ if (!data_sinfo->full) { u64 alloc_target; - struct btrfs_trans_handle *trans; data_sinfo->force_alloc = 1; spin_unlock(&data_sinfo->lock); @@ -2090,6 +2114,19 @@ again: goto again; } spin_unlock(&data_sinfo->lock); + + /* commit the current transaction and try again */ + if (!committed) { + committed = 1; + trans = btrfs_join_transaction(root, 1); + if (!trans) + return -ENOMEM; + ret = btrfs_commit_transaction(trans, root); + if (ret) + return ret; + goto again; + } + printk(KERN_ERR "no space left, need %llu, %llu delalloc bytes" ", %llu bytes_used, %llu bytes_reserved, " "%llu bytes_pinned, %llu bytes_readonly, %llu may use" -- cgit From 3c3e5694add02e665bbbd0fecfbbdcc0b903097a Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 19 Feb 2009 11:46:36 -0500 Subject: x86: check PMD in spurious_fault handler Impact: fix to prevent hard lockup on bad PMD permissions If the PMD does not have the correct permissions for a page access, but the PTE does, the spurious fault handler will mistake the fault as a lazy TLB transaction. This will result in an infinite loop of: fault -> spurious_fault check (pass) -> return to code -> fault This patch adds a check and a warn on if the PTE passes the permissions but the PMD does not. [ Updated: Ingo Molnar suggested using WARN_ONCE with some text ] Signed-off-by: Steven Rostedt --- arch/x86/mm/fault.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index c76ef1d701c..278d645d108 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -455,6 +455,7 @@ static int spurious_fault(unsigned long address, pud_t *pud; pmd_t *pmd; pte_t *pte; + int ret; /* Reserved-bit violation or user access to kernel space? */ if (error_code & (PF_USER | PF_RSVD)) @@ -482,7 +483,17 @@ static int spurious_fault(unsigned long address, if (!pte_present(*pte)) return 0; - return spurious_fault_check(error_code, pte); + ret = spurious_fault_check(error_code, pte); + if (!ret) + return 0; + + /* + * Make sure we have permissions in PMD + * If not, then there's a bug in the page tables. + */ + ret = spurious_fault_check(error_code, (pte_t *) pmd); + WARN_ONCE(!ret, "PMD has incorrect permission bits\n"); + return ret; } /* -- cgit From 7a5714e0186030676d79a7b4b9830c8e45c3b0a1 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 20 Feb 2009 17:44:21 +0100 Subject: x86, pat: add large-PAT check to split_large_page() Impact: future-proof the split_large_page() function Linus noticed that split_large_page() is not safe wrt. the PAT bit: it is bit 12 on the 1GB and 2MB page table level (_PAGE_BIT_PAT_LARGE), and it is bit 7 on the 4K page table level (_PAGE_BIT_PAT). Currently it is not a problem because we never set _PAGE_BIT_PAT_LARGE on any of the large-page mappings - but should this happen in the future the split_large_page() would silently lift bit 12 into the lowlevel 4K pte and would start corrupting the physical page frame offset. Not fun. So add a debug warning, to make sure if something ever sets the PAT bit then this function gets updated too. Cc: Linus Torvalds Signed-off-by: Ingo Molnar --- arch/x86/mm/pageattr.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 7be47d1a97e..8253bc97587 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -482,6 +482,13 @@ static int split_large_page(pte_t *kpte, unsigned long address) pbase = (pte_t *)page_address(base); paravirt_alloc_pte(&init_mm, page_to_pfn(base)); ref_prot = pte_pgprot(pte_clrhuge(*kpte)); + /* + * If we ever want to utilize the PAT bit, we need to + * update this function to make sure it's converted from + * bit 12 to bit 7 when we cross from the 2MB level to + * the 4K level: + */ + WARN_ON_ONCE(pgprot_val(ref_prot) & _PAGE_PAT_LARGE); #ifdef CONFIG_X86_64 if (level == PG_LEVEL_1G) { -- cgit From fdb17aeb28aaad3eae5ef57e70cb287d34d1049d Mon Sep 17 00:00:00 2001 From: Alok Kataria Date: Fri, 20 Feb 2009 10:23:18 -0800 Subject: x86, vmi: TSC going backwards check in vmi clocksource, cleanup clean up vmi_read_cycles to use max() Reported-b: Andrew Morton Signed-off-by: Alok N Kataria Cc: Zach Amsden Signed-off-by: Ingo Molnar --- arch/x86/kernel/vmiclock_32.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/x86/kernel/vmiclock_32.c b/arch/x86/kernel/vmiclock_32.c index 9cd28c04952..b77ad5789af 100644 --- a/arch/x86/kernel/vmiclock_32.c +++ b/arch/x86/kernel/vmiclock_32.c @@ -288,8 +288,7 @@ static struct clocksource clocksource_vmi; static cycle_t read_real_cycles(void) { cycle_t ret = (cycle_t)vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL); - return ret >= clocksource_vmi.cycle_last ? - ret : clocksource_vmi.cycle_last; + return max(ret, clocksource_vmi.cycle_last); } static struct clocksource clocksource_vmi = { -- cgit From 8cbb5bc374522a5f359e34856829732a7ed458a4 Mon Sep 17 00:00:00 2001 From: Zachary Amsden Date: Fri, 20 Feb 2009 11:27:46 -0800 Subject: MAINTAINERS: paravirt-ops maintainers update Welcome to Alok Kataria, our new paravirt-ops maintainer. Cc: Chris Wright Cc: Alok Kataria Cc: Rusty Russell Signed-off-by: Ingo Molnar --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 06e03913d2d..59fd2d1d94a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3334,8 +3334,8 @@ P: Jeremy Fitzhardinge M: jeremy@xensource.com P: Chris Wright M: chrisw@sous-sol.org -P: Zachary Amsden -M: zach@vmware.com +P: Alok Kataria +M: akataria@vmware.com P: Rusty Russell M: rusty@rustcorp.com.au L: virtualization@lists.osdl.org -- cgit From 2d4a71676f4d89418a0d53e60b89e8b804b390b2 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 20 Feb 2009 19:56:40 +0100 Subject: x86, mm: fault.c cleanup Impact: cleanup, no code changed Clean up various small details, which can be correctness checked automatically: - tidy up the include file section - eliminate unnecessary includes - introduce show_signal_msg() to clean up code flow - standardize the code flow - standardize comments and other style details - more cleanups, pointed out by checkpatch No code changed on either 32-bit nor 64-bit: arch/x86/mm/fault.o: text data bss dec hex filename 4632 32 24 4688 1250 fault.o.before 4632 32 24 4688 1250 fault.o.after the md5 changed due to a change in a single instruction: 2e8a8241e7f0d69706776a5a26c90bc0 fault.o.before.asm c5c3d36e725586eb74f0e10692f0193e fault.o.after.asm Because a __LINE__ reference in a WARN_ONCE() has changed. On 32-bit a few stack offsets changed - no code size difference nor any functionality difference. Cc: Linus Torvalds Signed-off-by: Ingo Molnar --- arch/x86/mm/fault.c | 546 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 331 insertions(+), 215 deletions(-) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index e4b9fc5001c..351d679bf97 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -1,56 +1,59 @@ /* * Copyright (C) 1995 Linus Torvalds - * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs. + * Copyright (C) 2001, 2002 Andi Kleen, SuSE Labs. */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include /* For unblank_screen() */ +#include +#include #include #include -#include /* for max_low_pfn */ -#include -#include #include #include +#include +#include +#include +#include +#include +#include +#include #include +#include #include +#include +#include +#include +#include +#include +#include +#include + +#include -#include -#include -#include -#include -#include #include +#include +#include +#include #include -#include #include +#include /* - * Page fault error code bits - * bit 0 == 0 means no page found, 1 means protection fault - * bit 1 == 0 means read, 1 means write - * bit 2 == 0 means kernel, 1 means user-mode - * bit 3 == 1 means use of reserved bit detected - * bit 4 == 1 means fault was an instruction fetch + * Page fault error code bits: + * + * bit 0 == 0: no page found 1: protection fault + * bit 1 == 0: read access 1: write access + * bit 2 == 0: kernel-mode access 1: user-mode access + * bit 3 == 1: use of reserved bit detected + * bit 4 == 1: fault was an instruction fetch */ -#define PF_PROT (1<<0) -#define PF_WRITE (1<<1) -#define PF_USER (1<<2) -#define PF_RSVD (1<<3) -#define PF_INSTR (1<<4) +enum x86_pf_error_code { + + PF_PROT = 1 << 0, + PF_WRITE = 1 << 1, + PF_USER = 1 << 2, + PF_RSVD = 1 << 3, + PF_INSTR = 1 << 4, +}; static inline int kmmio_fault(struct pt_regs *regs, unsigned long addr) { @@ -82,23 +85,27 @@ static inline int notify_page_fault(struct pt_regs *regs) } /* - * X86_32 - * Sometimes AMD Athlon/Opteron CPUs report invalid exceptions on prefetch. - * Check that here and ignore it. + * Prefetch quirks: + * + * 32-bit mode: + * + * Sometimes AMD Athlon/Opteron CPUs report invalid exceptions on prefetch. + * Check that here and ignore it. * - * X86_64 - * Sometimes the CPU reports invalid exceptions on prefetch. - * Check that here and ignore it. + * 64-bit mode: * - * Opcode checker based on code by Richard Brunner + * Sometimes the CPU reports invalid exceptions on prefetch. + * Check that here and ignore it. + * + * Opcode checker based on code by Richard Brunner. */ -static int is_prefetch(struct pt_regs *regs, unsigned long error_code, - unsigned long addr) +static int +is_prefetch(struct pt_regs *regs, unsigned long error_code, unsigned long addr) { + unsigned char *max_instr; unsigned char *instr; int scan_more = 1; int prefetch = 0; - unsigned char *max_instr; /* * If it was a exec (instruction fetch) fault on NX page, then @@ -114,9 +121,9 @@ static int is_prefetch(struct pt_regs *regs, unsigned long error_code, return 0; while (scan_more && instr < max_instr) { - unsigned char opcode; unsigned char instr_hi; unsigned char instr_lo; + unsigned char opcode; if (probe_kernel_address(instr, opcode)) break; @@ -173,15 +180,17 @@ static int is_prefetch(struct pt_regs *regs, unsigned long error_code, return prefetch; } -static void force_sig_info_fault(int si_signo, int si_code, - unsigned long address, struct task_struct *tsk) +static void +force_sig_info_fault(int si_signo, int si_code, unsigned long address, + struct task_struct *tsk) { siginfo_t info; - info.si_signo = si_signo; - info.si_errno = 0; - info.si_code = si_code; - info.si_addr = (void __user *)address; + info.si_signo = si_signo; + info.si_errno = 0; + info.si_code = si_code; + info.si_addr = (void __user *)address; + force_sig_info(si_signo, &info, tsk); } @@ -189,6 +198,7 @@ static void force_sig_info_fault(int si_signo, int si_code, static int bad_address(void *p) { unsigned long dummy; + return probe_kernel_address((unsigned long *)p, dummy); } #endif @@ -200,13 +210,14 @@ static void dump_pagetable(unsigned long address) page = read_cr3(); page = ((__typeof__(page) *) __va(page))[address >> PGDIR_SHIFT]; + #ifdef CONFIG_X86_PAE printk("*pdpt = %016Lx ", page); if ((page >> PAGE_SHIFT) < max_low_pfn && page & _PAGE_PRESENT) { page &= PAGE_MASK; page = ((__typeof__(page) *) __va(page))[(address >> PMD_SHIFT) - & (PTRS_PER_PMD - 1)]; + & (PTRS_PER_PMD - 1)]; printk(KERN_CONT "*pde = %016Lx ", page); page &= ~_PAGE_NX; } @@ -218,14 +229,15 @@ static void dump_pagetable(unsigned long address) * We must not directly access the pte in the highpte * case if the page table is located in highmem. * And let's rather not kmap-atomic the pte, just in case - * it's allocated already. + * it's allocated already: */ if ((page >> PAGE_SHIFT) < max_low_pfn && (page & _PAGE_PRESENT) && !(page & _PAGE_PSE)) { + page &= PAGE_MASK; page = ((__typeof__(page) *) __va(page))[(address >> PAGE_SHIFT) - & (PTRS_PER_PTE - 1)]; + & (PTRS_PER_PTE - 1)]; printk("*pte = %0*Lx ", sizeof(page)*2, (u64)page); } @@ -239,26 +251,38 @@ static void dump_pagetable(unsigned long address) pgd = (pgd_t *)read_cr3(); pgd = __va((unsigned long)pgd & PHYSICAL_PAGE_MASK); + pgd += pgd_index(address); - if (bad_address(pgd)) goto bad; + if (bad_address(pgd)) + goto bad; + printk("PGD %lx ", pgd_val(*pgd)); - if (!pgd_present(*pgd)) goto ret; + + if (!pgd_present(*pgd)) + goto out; pud = pud_offset(pgd, address); - if (bad_address(pud)) goto bad; + if (bad_address(pud)) + goto bad; + printk("PUD %lx ", pud_val(*pud)); if (!pud_present(*pud) || pud_large(*pud)) - goto ret; + goto out; pmd = pmd_offset(pud, address); - if (bad_address(pmd)) goto bad; + if (bad_address(pmd)) + goto bad; + printk("PMD %lx ", pmd_val(*pmd)); - if (!pmd_present(*pmd) || pmd_large(*pmd)) goto ret; + if (!pmd_present(*pmd) || pmd_large(*pmd)) + goto out; pte = pte_offset_kernel(pmd, address); - if (bad_address(pte)) goto bad; + if (bad_address(pte)) + goto bad; + printk("PTE %lx", pte_val(*pte)); -ret: +out: printk("\n"); return; bad: @@ -285,7 +309,6 @@ static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address) * and redundant with the set_pmd() on non-PAE. As would * set_pud. */ - pud = pud_offset(pgd, address); pud_k = pud_offset(pgd_k, address); if (!pud_present(*pud_k)) @@ -295,11 +318,14 @@ static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address) pmd_k = pmd_offset(pud_k, address); if (!pmd_present(*pmd_k)) return NULL; + if (!pmd_present(*pmd)) { set_pmd(pmd, *pmd_k); arch_flush_lazy_mmu_mode(); - } else + } else { BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k)); + } + return pmd_k; } #endif @@ -312,29 +338,37 @@ KERN_ERR "******* Please consider a BIOS update.\n" KERN_ERR "******* Disabling USB legacy in the BIOS may also help.\n"; #endif -/* Workaround for K8 erratum #93 & buggy BIOS. - BIOS SMM functions are required to use a specific workaround - to avoid corruption of the 64bit RIP register on C stepping K8. - A lot of BIOS that didn't get tested properly miss this. - The OS sees this as a page fault with the upper 32bits of RIP cleared. - Try to work around it here. - Note we only handle faults in kernel here. - Does nothing for X86_32 +/* + * Workaround for K8 erratum #93 & buggy BIOS. + * + * BIOS SMM functions are required to use a specific workaround + * to avoid corruption of the 64bit RIP register on C stepping K8. + * + * A lot of BIOS that didn't get tested properly miss this. + * + * The OS sees this as a page fault with the upper 32bits of RIP cleared. + * Try to work around it here. + * + * Note we only handle faults in kernel here. + * Does nothing on 32-bit. */ static int is_errata93(struct pt_regs *regs, unsigned long address) { #ifdef CONFIG_X86_64 - static int warned; + static int once; + if (address != regs->ip) return 0; + if ((address >> 32) != 0) return 0; + address |= 0xffffffffUL << 32; if ((address >= (u64)_stext && address <= (u64)_etext) || (address >= MODULES_VADDR && address <= MODULES_END)) { - if (!warned) { + if (!once) { printk(errata93_warning); - warned = 1; + once = 1; } regs->ip = address; return 1; @@ -344,16 +378,17 @@ static int is_errata93(struct pt_regs *regs, unsigned long address) } /* - * Work around K8 erratum #100 K8 in compat mode occasionally jumps to illegal - * addresses >4GB. We catch this in the page fault handler because these - * addresses are not reachable. Just detect this case and return. Any code + * Work around K8 erratum #100 K8 in compat mode occasionally jumps + * to illegal addresses >4GB. + * + * We catch this in the page fault handler because these addresses + * are not reachable. Just detect this case and return. Any code * segment in LDT is compatibility mode. */ static int is_errata100(struct pt_regs *regs, unsigned long address) { #ifdef CONFIG_X86_64 - if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) && - (address >> 32)) + if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) && (address >> 32)) return 1; #endif return 0; @@ -363,8 +398,9 @@ static int is_f00f_bug(struct pt_regs *regs, unsigned long address) { #ifdef CONFIG_X86_F00F_BUG unsigned long nr; + /* - * Pentium F0 0F C7 C8 bug workaround. + * Pentium F0 0F C7 C8 bug workaround: */ if (boot_cpu_data.f00f_bug) { nr = (address - idt_descr.address) >> 3; @@ -378,8 +414,9 @@ static int is_f00f_bug(struct pt_regs *regs, unsigned long address) return 0; } -static void show_fault_oops(struct pt_regs *regs, unsigned long error_code, - unsigned long address) +static void +show_fault_oops(struct pt_regs *regs, unsigned long error_code, + unsigned long address) { #ifdef CONFIG_X86_32 if (!oops_may_print()) @@ -389,12 +426,14 @@ static void show_fault_oops(struct pt_regs *regs, unsigned long error_code, #ifdef CONFIG_X86_PAE if (error_code & PF_INSTR) { unsigned int level; + pte_t *pte = lookup_address(address, &level); - if (pte && pte_present(*pte) && !pte_exec(*pte)) + if (pte && pte_present(*pte) && !pte_exec(*pte)) { printk(KERN_CRIT "kernel tried to execute " "NX-protected page - exploit attempt? " "(uid: %d)\n", current_uid()); + } } #endif @@ -403,34 +442,45 @@ static void show_fault_oops(struct pt_regs *regs, unsigned long error_code, printk(KERN_CONT "NULL pointer dereference"); else printk(KERN_CONT "paging request"); + printk(KERN_CONT " at %p\n", (void *) address); printk(KERN_ALERT "IP:"); printk_address(regs->ip, 1); + dump_pagetable(address); } #ifdef CONFIG_X86_64 -static noinline void pgtable_bad(struct pt_regs *regs, - unsigned long error_code, unsigned long address) +static noinline void +pgtable_bad(struct pt_regs *regs, unsigned long error_code, + unsigned long address) { - unsigned long flags = oops_begin(); - int sig = SIGKILL; - struct task_struct *tsk = current; + struct task_struct *tsk; + unsigned long flags; + int sig; + + flags = oops_begin(); + tsk = current; + sig = SIGKILL; printk(KERN_ALERT "%s: Corrupted page table at address %lx\n", tsk->comm, address); dump_pagetable(address); - tsk->thread.cr2 = address; - tsk->thread.trap_no = 14; - tsk->thread.error_code = error_code; + + tsk->thread.cr2 = address; + tsk->thread.trap_no = 14; + tsk->thread.error_code = error_code; + if (__die("Bad pagetable", regs, error_code)) sig = 0; + oops_end(flags, regs, sig); } #endif -static noinline void no_context(struct pt_regs *regs, - unsigned long error_code, unsigned long address) +static noinline void +no_context(struct pt_regs *regs, unsigned long error_code, + unsigned long address) { struct task_struct *tsk = current; unsigned long *stackend; @@ -440,18 +490,20 @@ static noinline void no_context(struct pt_regs *regs, int sig; #endif - /* Are we prepared to handle this kernel fault? */ + /* Are we prepared to handle this kernel fault? */ if (fixup_exception(regs)) return; /* - * X86_32 - * Valid to do another page fault here, because if this fault - * had been triggered by is_prefetch fixup_exception would have - * handled it. + * 32-bit: + * + * Valid to do another page fault here, because if this fault + * had been triggered by is_prefetch fixup_exception would have + * handled it. + * + * 64-bit: * - * X86_64 - * Hall of shame of CPU/BIOS bugs. + * Hall of shame of CPU/BIOS bugs. */ if (is_prefetch(regs, error_code, address)) return; @@ -461,7 +513,7 @@ static noinline void no_context(struct pt_regs *regs, /* * Oops. The kernel tried to access some bad page. We'll have to - * terminate things with extreme prejudice. + * terminate things with extreme prejudice: */ #ifdef CONFIG_X86_32 bust_spinlocks(1); @@ -471,7 +523,7 @@ static noinline void no_context(struct pt_regs *regs, show_fault_oops(regs, error_code, address); - stackend = end_of_stack(tsk); + stackend = end_of_stack(tsk); if (*stackend != STACK_END_MAGIC) printk(KERN_ALERT "Thread overran stack, or stack corrupted\n"); @@ -487,28 +539,54 @@ static noinline void no_context(struct pt_regs *regs, sig = SIGKILL; if (__die("Oops", regs, error_code)) sig = 0; + /* Executive summary in case the body of the oops scrolled away */ printk(KERN_EMERG "CR2: %016lx\n", address); + oops_end(flags, regs, sig); #endif } -static void __bad_area_nosemaphore(struct pt_regs *regs, - unsigned long error_code, unsigned long address, - int si_code) +/* + * Print out info about fatal segfaults, if the show_unhandled_signals + * sysctl is set: + */ +static inline void +show_signal_msg(struct pt_regs *regs, unsigned long error_code, + unsigned long address, struct task_struct *tsk) +{ + if (!unhandled_signal(tsk, SIGSEGV)) + return; + + if (!printk_ratelimit()) + return; + + printk(KERN_CONT "%s%s[%d]: segfault at %lx ip %p sp %p error %lx", + task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, + tsk->comm, task_pid_nr(tsk), address, + (void *)regs->ip, (void *)regs->sp, error_code); + + print_vma_addr(KERN_CONT " in ", regs->ip); + + printk(KERN_CONT "\n"); +} + +static void +__bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, + unsigned long address, int si_code) { struct task_struct *tsk = current; /* User mode accesses just cause a SIGSEGV */ if (error_code & PF_USER) { /* - * It's possible to have interrupts off here. + * It's possible to have interrupts off here: */ local_irq_enable(); /* * Valid to do another page fault here because this one came - * from user space. + * from user space: */ if (is_prefetch(regs, error_code, address)) return; @@ -516,22 +594,16 @@ static void __bad_area_nosemaphore(struct pt_regs *regs, if (is_errata100(regs, address)) return; - if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && - printk_ratelimit()) { - printk( - "%s%s[%d]: segfault at %lx ip %p sp %p error %lx", - task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, - tsk->comm, task_pid_nr(tsk), address, - (void *) regs->ip, (void *) regs->sp, error_code); - print_vma_addr(" in ", regs->ip); - printk("\n"); - } + if (unlikely(show_unhandled_signals)) + show_signal_msg(regs, error_code, address, tsk); + + /* Kernel addresses are always protection faults: */ + tsk->thread.cr2 = address; + tsk->thread.error_code = error_code | (address >= TASK_SIZE); + tsk->thread.trap_no = 14; - tsk->thread.cr2 = address; - /* Kernel addresses are always protection faults */ - tsk->thread.error_code = error_code | (address >= TASK_SIZE); - tsk->thread.trap_no = 14; force_sig_info_fault(SIGSEGV, si_code, address, tsk); + return; } @@ -541,15 +613,16 @@ static void __bad_area_nosemaphore(struct pt_regs *regs, no_context(regs, error_code, address); } -static noinline void bad_area_nosemaphore(struct pt_regs *regs, - unsigned long error_code, unsigned long address) +static noinline void +bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, + unsigned long address) { __bad_area_nosemaphore(regs, error_code, address, SEGV_MAPERR); } -static void __bad_area(struct pt_regs *regs, - unsigned long error_code, unsigned long address, - int si_code) +static void +__bad_area(struct pt_regs *regs, unsigned long error_code, + unsigned long address, int si_code) { struct mm_struct *mm = current->mm; @@ -562,67 +635,77 @@ static void __bad_area(struct pt_regs *regs, __bad_area_nosemaphore(regs, error_code, address, si_code); } -static noinline void bad_area(struct pt_regs *regs, - unsigned long error_code, unsigned long address) +static noinline void +bad_area(struct pt_regs *regs, unsigned long error_code, unsigned long address) { __bad_area(regs, error_code, address, SEGV_MAPERR); } -static noinline void bad_area_access_error(struct pt_regs *regs, - unsigned long error_code, unsigned long address) +static noinline void +bad_area_access_error(struct pt_regs *regs, unsigned long error_code, + unsigned long address) { __bad_area(regs, error_code, address, SEGV_ACCERR); } /* TODO: fixup for "mm-invoke-oom-killer-from-page-fault.patch" */ -static void out_of_memory(struct pt_regs *regs, - unsigned long error_code, unsigned long address) +static void +out_of_memory(struct pt_regs *regs, unsigned long error_code, + unsigned long address) { /* * We ran out of memory, call the OOM killer, and return the userspace - * (which will retry the fault, or kill us if we got oom-killed). + * (which will retry the fault, or kill us if we got oom-killed): */ up_read(¤t->mm->mmap_sem); + pagefault_out_of_memory(); } -static void do_sigbus(struct pt_regs *regs, - unsigned long error_code, unsigned long address) +static void +do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address) { struct task_struct *tsk = current; struct mm_struct *mm = tsk->mm; up_read(&mm->mmap_sem); - /* Kernel mode? Handle exceptions or die */ + /* Kernel mode? Handle exceptions or die: */ if (!(error_code & PF_USER)) no_context(regs, error_code, address); + #ifdef CONFIG_X86_32 - /* User space => ok to do another page fault */ + /* User space => ok to do another page fault: */ if (is_prefetch(regs, error_code, address)) return; #endif - tsk->thread.cr2 = address; - tsk->thread.error_code = error_code; - tsk->thread.trap_no = 14; + + tsk->thread.cr2 = address; + tsk->thread.error_code = error_code; + tsk->thread.trap_no = 14; + force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk); } -static noinline void mm_fault_error(struct pt_regs *regs, - unsigned long error_code, unsigned long address, unsigned int fault) +static noinline void +mm_fault_error(struct pt_regs *regs, unsigned long error_code, + unsigned long address, unsigned int fault) { - if (fault & VM_FAULT_OOM) + if (fault & VM_FAULT_OOM) { out_of_memory(regs, error_code, address); - else if (fault & VM_FAULT_SIGBUS) - do_sigbus(regs, error_code, address); - else - BUG(); + } else { + if (fault & VM_FAULT_SIGBUS) + do_sigbus(regs, error_code, address); + else + BUG(); + } } static int spurious_fault_check(unsigned long error_code, pte_t *pte) { if ((error_code & PF_WRITE) && !pte_write(*pte)) return 0; + if ((error_code & PF_INSTR) && !pte_exec(*pte)) return 0; @@ -630,16 +713,19 @@ static int spurious_fault_check(unsigned long error_code, pte_t *pte) } /* - * Handle a spurious fault caused by a stale TLB entry. This allows - * us to lazily refresh the TLB when increasing the permissions of a - * kernel page (RO -> RW or NX -> X). Doing it eagerly is very - * expensive since that implies doing a full cross-processor TLB - * flush, even if no stale TLB entries exist on other processors. + * Handle a spurious fault caused by a stale TLB entry. + * + * This allows us to lazily refresh the TLB when increasing the + * permissions of a kernel page (RO -> RW or NX -> X). Doing it + * eagerly is very expensive since that implies doing a full + * cross-processor TLB flush, even if no stale TLB entries exist + * on other processors. + * * There are no security implications to leaving a stale TLB when * increasing the permissions on a page. */ -static noinline int spurious_fault(unsigned long error_code, - unsigned long address) +static noinline int +spurious_fault(unsigned long error_code, unsigned long address) { pgd_t *pgd; pud_t *pud; @@ -678,20 +764,23 @@ static noinline int spurious_fault(unsigned long error_code, return 0; /* - * Make sure we have permissions in PMD - * If not, then there's a bug in the page tables. + * Make sure we have permissions in PMD. + * If not, then there's a bug in the page tables: */ ret = spurious_fault_check(error_code, (pte_t *) pmd); WARN_ONCE(!ret, "PMD has incorrect permission bits\n"); + return ret; } /* - * X86_32 - * Handle a fault on the vmalloc or module mapping area + * 32-bit: + * + * Handle a fault on the vmalloc or module mapping area * - * X86_64 - * Handle a fault on the vmalloc area + * 64-bit: + * + * Handle a fault on the vmalloc area * * This assumes no large pages in there. */ @@ -702,7 +791,7 @@ static noinline int vmalloc_fault(unsigned long address) pmd_t *pmd_k; pte_t *pte_k; - /* Make sure we are in vmalloc area */ + /* Make sure we are in vmalloc area: */ if (!(address >= VMALLOC_START && address < VMALLOC_END)) return -1; @@ -717,9 +806,11 @@ static noinline int vmalloc_fault(unsigned long address) pmd_k = vmalloc_sync_one(__va(pgd_paddr), address); if (!pmd_k) return -1; + pte_k = pte_offset_kernel(pmd_k, address); if (!pte_present(*pte_k)) return -1; + return 0; #else pgd_t *pgd, *pgd_ref; @@ -727,69 +818,84 @@ static noinline int vmalloc_fault(unsigned long address) pmd_t *pmd, *pmd_ref; pte_t *pte, *pte_ref; - /* Make sure we are in vmalloc area */ + /* Make sure we are in vmalloc area: */ if (!(address >= VMALLOC_START && address < VMALLOC_END)) return -1; - /* Copy kernel mappings over when needed. This can also - happen within a race in page table update. In the later - case just flush. */ - + /* + * Copy kernel mappings over when needed. This can also + * happen within a race in page table update. In the later + * case just flush: + */ pgd = pgd_offset(current->active_mm, address); pgd_ref = pgd_offset_k(address); if (pgd_none(*pgd_ref)) return -1; + if (pgd_none(*pgd)) set_pgd(pgd, *pgd_ref); else BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref)); - /* Below here mismatches are bugs because these lower tables - are shared */ + /* + * Below here mismatches are bugs because these lower tables + * are shared: + */ pud = pud_offset(pgd, address); pud_ref = pud_offset(pgd_ref, address); if (pud_none(*pud_ref)) return -1; + if (pud_none(*pud) || pud_page_vaddr(*pud) != pud_page_vaddr(*pud_ref)) BUG(); + pmd = pmd_offset(pud, address); pmd_ref = pmd_offset(pud_ref, address); if (pmd_none(*pmd_ref)) return -1; + if (pmd_none(*pmd) || pmd_page(*pmd) != pmd_page(*pmd_ref)) BUG(); + pte_ref = pte_offset_kernel(pmd_ref, address); if (!pte_present(*pte_ref)) return -1; + pte = pte_offset_kernel(pmd, address); - /* Don't use pte_page here, because the mappings can point - outside mem_map, and the NUMA hash lookup cannot handle - that. */ + + /* + * Don't use pte_page here, because the mappings can point + * outside mem_map, and the NUMA hash lookup cannot handle + * that: + */ if (!pte_present(*pte) || pte_pfn(*pte) != pte_pfn(*pte_ref)) BUG(); + return 0; #endif } int show_unhandled_signals = 1; -static inline int access_error(unsigned long error_code, int write, - struct vm_area_struct *vma) +static inline int +access_error(unsigned long error_code, int write, struct vm_area_struct *vma) { if (write) { - /* write, present and write, not present */ + /* write, present and write, not present: */ if (unlikely(!(vma->vm_flags & VM_WRITE))) return 1; - } else if (unlikely(error_code & PF_PROT)) { - /* read, present */ - return 1; - } else { - /* read, not present */ - if (unlikely(!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))) - return 1; + return 0; } + /* read, present: */ + if (unlikely(error_code & PF_PROT)) + return 1; + + /* read, not present: */ + if (unlikely(!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))) + return 1; + return 0; } @@ -797,9 +903,9 @@ static int fault_in_kernel_space(unsigned long address) { #ifdef CONFIG_X86_32 return address >= TASK_SIZE; -#else /* !CONFIG_X86_32 */ +#else return address >= TASK_SIZE64; -#endif /* CONFIG_X86_32 */ +#endif } /* @@ -812,18 +918,19 @@ asmlinkage #endif void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) { - unsigned long address; + struct vm_area_struct *vma; struct task_struct *tsk; + unsigned long address; struct mm_struct *mm; - struct vm_area_struct *vma; int write; int fault; tsk = current; mm = tsk->mm; + prefetchw(&mm->mmap_sem); - /* get the address */ + /* Get the faulting address: */ address = read_cr2(); if (unlikely(kmmio_fault(regs, address))) @@ -847,22 +954,23 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) vmalloc_fault(address) >= 0) return; - /* Can handle a stale RO->RW TLB */ + /* Can handle a stale RO->RW TLB: */ if (spurious_fault(error_code, address)) return; - /* kprobes don't want to hook the spurious faults. */ + /* kprobes don't want to hook the spurious faults: */ if (notify_page_fault(regs)) return; /* * Don't take the mm semaphore here. If we fixup a prefetch - * fault we could otherwise deadlock. + * fault we could otherwise deadlock: */ bad_area_nosemaphore(regs, error_code, address); + return; } - /* kprobes don't want to hook the spurious faults. */ + /* kprobes don't want to hook the spurious faults: */ if (unlikely(notify_page_fault(regs))) return; /* @@ -870,13 +978,15 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) * vmalloc fault has been handled. * * User-mode registers count as a user access even for any - * potential system fault or CPU buglet. + * potential system fault or CPU buglet: */ if (user_mode_vm(regs)) { local_irq_enable(); error_code |= PF_USER; - } else if (regs->flags & X86_EFLAGS_IF) - local_irq_enable(); + } else { + if (regs->flags & X86_EFLAGS_IF) + local_irq_enable(); + } #ifdef CONFIG_X86_64 if (unlikely(error_code & PF_RSVD)) @@ -884,8 +994,8 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) #endif /* - * If we're in an interrupt, have no user context or are running in an - * atomic region then we must not take the fault. + * If we're in an interrupt, have no user context or are running + * in an atomic region then we must not take the fault: */ if (unlikely(in_atomic() || !mm)) { bad_area_nosemaphore(regs, error_code, address); @@ -894,19 +1004,19 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) /* * When running in the kernel we expect faults to occur only to - * addresses in user space. All other faults represent errors in the - * kernel and should generate an OOPS. Unfortunately, in the case of an - * erroneous fault occurring in a code path which already holds mmap_sem - * we will deadlock attempting to validate the fault against the - * address space. Luckily the kernel only validly references user - * space from well defined areas of code, which are listed in the - * exceptions table. + * addresses in user space. All other faults represent errors in + * the kernel and should generate an OOPS. Unfortunately, in the + * case of an erroneous fault occurring in a code path which already + * holds mmap_sem we will deadlock attempting to validate the fault + * against the address space. Luckily the kernel only validly + * references user space from well defined areas of code, which are + * listed in the exceptions table. * * As the vast majority of faults will be valid we will only perform - * the source reference check when there is a possibility of a deadlock. - * Attempt to lock the address space, if we cannot we then validate the - * source. If this is invalid we can skip the address space check, - * thus avoiding the deadlock. + * the source reference check when there is a possibility of a + * deadlock. Attempt to lock the address space, if we cannot we then + * validate the source. If this is invalid we can skip the address + * space check, thus avoiding the deadlock: */ if (unlikely(!down_read_trylock(&mm->mmap_sem))) { if ((error_code & PF_USER) == 0 && @@ -917,8 +1027,9 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) down_read(&mm->mmap_sem); } else { /* - * The above down_read_trylock() might have succeeded in which - * case we'll have missed the might_sleep() from down_read(). + * The above down_read_trylock() might have succeeded in + * which case we'll have missed the might_sleep() from + * down_read(): */ might_sleep(); } @@ -938,7 +1049,7 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) /* * Accessing the stack below %sp is always a bug. * The large cushion allows instructions like enter - * and pusha to work. ("enter $65535,$31" pushes + * and pusha to work. ("enter $65535, $31" pushes * 32 pointers and then decrements %sp by 65535.) */ if (unlikely(address + 65536 + 32 * sizeof(unsigned long) < regs->sp)) { @@ -957,6 +1068,7 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) */ good_area: write = error_code & PF_WRITE; + if (unlikely(access_error(error_code, write, vma))) { bad_area_access_error(regs, error_code, address); return; @@ -965,13 +1077,15 @@ good_area: /* * If for any reason at all we couldn't handle the fault, * make sure we exit gracefully rather than endlessly redo - * the fault. + * the fault: */ fault = handle_mm_fault(mm, vma, address, write); + if (unlikely(fault & VM_FAULT_ERROR)) { mm_fault_error(regs, error_code, address, fault); return; } + if (fault & VM_FAULT_MAJOR) tsk->maj_flt++; else @@ -1004,13 +1118,13 @@ void vmalloc_sync_all(void) for (address = VMALLOC_START & PMD_MASK; address >= TASK_SIZE && address < FIXADDR_TOP; address += PMD_SIZE) { + unsigned long flags; struct page *page; spin_lock_irqsave(&pgd_lock, flags); list_for_each_entry(page, &pgd_list, lru) { - if (!vmalloc_sync_one(page_address(page), - address)) + if (!vmalloc_sync_one(page_address(page), address)) break; } spin_unlock_irqrestore(&pgd_lock, flags); @@ -1018,12 +1132,14 @@ void vmalloc_sync_all(void) #else /* CONFIG_X86_64 */ for (address = VMALLOC_START & PGDIR_MASK; address <= VMALLOC_END; address += PGDIR_SIZE) { + const pgd_t *pgd_ref = pgd_offset_k(address); unsigned long flags; struct page *page; if (pgd_none(*pgd_ref)) continue; + spin_lock_irqsave(&pgd_lock, flags); list_for_each_entry(page, &pgd_list, lru) { pgd_t *pgd; -- cgit From 107a03678cac0dd6cf7095f81442a4fa477e4700 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 20 Feb 2009 20:37:05 +0100 Subject: x86, mm: fault.c, refactor/simplify the is_prefetch() code Impact: no functionality changed Factor out the opcode checker into a helper inline. The code got a tiny bit smaller: text data bss dec hex filename 4632 32 24 4688 1250 fault.o.before 4618 32 24 4674 1242 fault.o.after And it got cleaner / easier to review as well. Cc: Linus Torvalds Signed-off-by: Ingo Molnar --- arch/x86/mm/fault.c | 100 ++++++++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 351d679bf97..72973c7682b 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -99,12 +99,58 @@ static inline int notify_page_fault(struct pt_regs *regs) * * Opcode checker based on code by Richard Brunner. */ +static inline int +check_prefetch_opcode(struct pt_regs *regs, unsigned char *instr, + unsigned char opcode, int *prefetch) +{ + unsigned char instr_hi = opcode & 0xf0; + unsigned char instr_lo = opcode & 0x0f; + + switch (instr_hi) { + case 0x20: + case 0x30: + /* + * Values 0x26,0x2E,0x36,0x3E are valid x86 prefixes. + * In X86_64 long mode, the CPU will signal invalid + * opcode if some of these prefixes are present so + * X86_64 will never get here anyway + */ + return ((instr_lo & 7) == 0x6); +#ifdef CONFIG_X86_64 + case 0x40: + /* + * In AMD64 long mode 0x40..0x4F are valid REX prefixes + * Need to figure out under what instruction mode the + * instruction was issued. Could check the LDT for lm, + * but for now it's good enough to assume that long + * mode only uses well known segments or kernel. + */ + return (!user_mode(regs)) || (regs->cs == __USER_CS); +#endif + case 0x60: + /* 0x64 thru 0x67 are valid prefixes in all modes. */ + return (instr_lo & 0xC) == 0x4; + case 0xF0: + /* 0xF0, 0xF2, 0xF3 are valid prefixes in all modes. */ + return !instr_lo || (instr_lo>>1) == 1; + case 0x00: + /* Prefetch instruction is 0x0F0D or 0x0F18 */ + if (probe_kernel_address(instr, opcode)) + return 0; + + *prefetch = (instr_lo == 0xF) && + (opcode == 0x0D || opcode == 0x18); + return 0; + default: + return 0; + } +} + static int is_prefetch(struct pt_regs *regs, unsigned long error_code, unsigned long addr) { unsigned char *max_instr; unsigned char *instr; - int scan_more = 1; int prefetch = 0; /* @@ -114,68 +160,22 @@ is_prefetch(struct pt_regs *regs, unsigned long error_code, unsigned long addr) if (error_code & PF_INSTR) return 0; - instr = (unsigned char *)convert_ip_to_linear(current, regs); + instr = (void *)convert_ip_to_linear(current, regs); max_instr = instr + 15; if (user_mode(regs) && instr >= (unsigned char *)TASK_SIZE) return 0; - while (scan_more && instr < max_instr) { - unsigned char instr_hi; - unsigned char instr_lo; + while (instr < max_instr) { unsigned char opcode; if (probe_kernel_address(instr, opcode)) break; - instr_hi = opcode & 0xf0; - instr_lo = opcode & 0x0f; instr++; - switch (instr_hi) { - case 0x20: - case 0x30: - /* - * Values 0x26,0x2E,0x36,0x3E are valid x86 prefixes. - * In X86_64 long mode, the CPU will signal invalid - * opcode if some of these prefixes are present so - * X86_64 will never get here anyway - */ - scan_more = ((instr_lo & 7) == 0x6); - break; -#ifdef CONFIG_X86_64 - case 0x40: - /* - * In AMD64 long mode 0x40..0x4F are valid REX prefixes - * Need to figure out under what instruction mode the - * instruction was issued. Could check the LDT for lm, - * but for now it's good enough to assume that long - * mode only uses well known segments or kernel. - */ - scan_more = (!user_mode(regs)) || (regs->cs == __USER_CS); - break; -#endif - case 0x60: - /* 0x64 thru 0x67 are valid prefixes in all modes. */ - scan_more = (instr_lo & 0xC) == 0x4; + if (!check_prefetch_opcode(regs, instr, opcode, &prefetch)) break; - case 0xF0: - /* 0xF0, 0xF2, 0xF3 are valid prefixes in all modes. */ - scan_more = !instr_lo || (instr_lo>>1) == 1; - break; - case 0x00: - /* Prefetch instruction is 0x0F0D or 0x0F18 */ - scan_more = 0; - - if (probe_kernel_address(instr, opcode)) - break; - prefetch = (instr_lo == 0xF) && - (opcode == 0x0D || opcode == 0x18); - break; - default: - scan_more = 0; - break; - } } return prefetch; } -- cgit From 8c938f9fae887f6e180bf802aa1c33cf74712aff Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 20 Feb 2009 22:12:18 +0100 Subject: x86, mm: fault.c, factor out the vm86 fault check Impact: cleanup Instead of an ugly, open-coded, #ifdef-ed vm86 related legacy check in do_page_fault(), put it into the check_v8086_mode() helper function and merge it with an existing #ifdef. Also, simplify the code flow a tiny bit in the helper. No code changed: arch/x86/mm/fault.o: text data bss dec hex filename 2711 12 12 2735 aaf fault.o.before 2711 12 12 2735 aaf fault.o.after Cc: Linus Torvalds Signed-off-by: Ingo Molnar --- arch/x86/mm/fault.c | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 72973c7682b..7dc0615c3cf 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -328,14 +328,41 @@ static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address) return pmd_k; } -#endif -#ifdef CONFIG_X86_64 +/* + * Did it hit the DOS screen memory VA from vm86 mode? + */ +static inline void +check_v8086_mode(struct pt_regs *regs, unsigned long address, + struct task_struct *tsk) +{ + unsigned long bit; + + if (!v8086_mode(regs)) + return; + + bit = (address - 0xA0000) >> PAGE_SHIFT; + if (bit < 32) + tsk->thread.screen_bitmap |= 1 << bit; +} + +#else /* CONFIG_X86_64: */ + static const char errata93_warning[] = KERN_ERR "******* Your BIOS seems to not contain a fix for K8 errata #93\n" KERN_ERR "******* Working around it, but it may cause SEGVs or burn power.\n" KERN_ERR "******* Please consider a BIOS update.\n" KERN_ERR "******* Disabling USB legacy in the BIOS may also help.\n"; + +/* + * No vm86 mode in 64-bit mode: + */ +static inline void +check_v8086_mode(struct pt_regs *regs, unsigned long address, + struct task_struct *tsk) +{ +} + #endif /* @@ -1091,16 +1118,8 @@ good_area: else tsk->min_flt++; -#ifdef CONFIG_X86_32 - /* - * Did it hit the DOS screen memory VA from vm86 mode? - */ - if (v8086_mode(regs)) { - unsigned long bit = (address - 0xA0000) >> PAGE_SHIFT; - if (bit < 32) - tsk->thread.screen_bitmap |= 1 << bit; - } -#endif + check_v8086_mode(regs, address, tsk); + up_read(&mm->mmap_sem); } -- cgit From 121d5d0a7e5808fbcfda484efd7ba840ac93450f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 20 Feb 2009 22:18:08 +0100 Subject: x86, mm: fault.c, enable PF_RSVD checks on 32-bit too Impact: improve page fault handling robustness The 'PF_RSVD' flag (bit 3) of the page-fault error_code is a relatively recent addition to x86 CPUs, so the 32-bit do_fault() implementation never had it. This flag gets set when the CPU detects nonzero values in any reserved bits of the page directory entries. Extend the existing 64-bit check for PF_RSVD in do_page_fault() to 32-bit too. If we detect such a fault then we print a more informative oops and the pagetables. This unifies the code some more, removes an ugly #ifdef and improves the 32-bit page fault code robustness a bit. It slightly increases the 32-bit kernel text size. Cc: Linus Torvalds Signed-off-by: Ingo Molnar --- arch/x86/mm/fault.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 7dc0615c3cf..3e366146273 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -477,7 +477,6 @@ show_fault_oops(struct pt_regs *regs, unsigned long error_code, dump_pagetable(address); } -#ifdef CONFIG_X86_64 static noinline void pgtable_bad(struct pt_regs *regs, unsigned long error_code, unsigned long address) @@ -503,7 +502,6 @@ pgtable_bad(struct pt_regs *regs, unsigned long error_code, oops_end(flags, regs, sig); } -#endif static noinline void no_context(struct pt_regs *regs, unsigned long error_code, @@ -1015,10 +1013,8 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) local_irq_enable(); } -#ifdef CONFIG_X86_64 if (unlikely(error_code & PF_RSVD)) pgtable_bad(regs, error_code, address); -#endif /* * If we're in an interrupt, have no user context or are running -- cgit From b814d41f0987c7648d7ed07471258101c95c026b Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 20 Feb 2009 22:32:10 +0100 Subject: x86, mm: fault.c, simplify kmmio_fault() Impact: cleanup Remove an #ifdef from kmmio_fault() - we can do this by providing default implementations for is_kmmio_active() and kmmio_handler(). The compiler optimizes it all away in the !CONFIG_MMIOTRACE case. Also, while at it, clean up mmiotrace.h a bit: - standard header guards - standard vertical spaces for structure definitions No code changed (both with mmiotrace on and off in the config): text data bss dec hex filename 2947 12 12 2971 b9b fault.o.before 2947 12 12 2971 b9b fault.o.after Cc: Pekka Paalanen Cc: Linus Torvalds Signed-off-by: Ingo Molnar --- arch/x86/mm/fault.c | 5 +-- include/linux/mmiotrace.h | 78 ++++++++++++++++++++++++++++------------------- 2 files changed, 50 insertions(+), 33 deletions(-) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 3e366146273..fe99af4b86d 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -55,13 +55,14 @@ enum x86_pf_error_code { PF_INSTR = 1 << 4, }; +/* + * (returns 0 if mmiotrace is disabled) + */ static inline int kmmio_fault(struct pt_regs *regs, unsigned long addr) { -#ifdef CONFIG_MMIOTRACE if (unlikely(is_kmmio_active())) if (kmmio_handler(regs, addr) == 1) return -1; -#endif return 0; } diff --git a/include/linux/mmiotrace.h b/include/linux/mmiotrace.h index 139d7c88d9c..3d1b7bde128 100644 --- a/include/linux/mmiotrace.h +++ b/include/linux/mmiotrace.h @@ -1,5 +1,5 @@ -#ifndef MMIOTRACE_H -#define MMIOTRACE_H +#ifndef _LINUX_MMIOTRACE_H +#define _LINUX_MMIOTRACE_H #include #include @@ -13,28 +13,34 @@ typedef void (*kmmio_post_handler_t)(struct kmmio_probe *, unsigned long condition, struct pt_regs *); struct kmmio_probe { - struct list_head list; /* kmmio internal list */ - unsigned long addr; /* start location of the probe point */ - unsigned long len; /* length of the probe region */ - kmmio_pre_handler_t pre_handler; /* Called before addr is executed. */ - kmmio_post_handler_t post_handler; /* Called after addr is executed */ - void *private; + /* kmmio internal list: */ + struct list_head list; + /* start location of the probe point: */ + unsigned long addr; + /* length of the probe region: */ + unsigned long len; + /* Called before addr is executed: */ + kmmio_pre_handler_t pre_handler; + /* Called after addr is executed: */ + kmmio_post_handler_t post_handler; + void *private; }; +extern unsigned int kmmio_count; + +extern int register_kmmio_probe(struct kmmio_probe *p); +extern void unregister_kmmio_probe(struct kmmio_probe *p); + +#ifdef CONFIG_MMIOTRACE /* kmmio is active by some kmmio_probes? */ static inline int is_kmmio_active(void) { - extern unsigned int kmmio_count; return kmmio_count; } -extern int register_kmmio_probe(struct kmmio_probe *p); -extern void unregister_kmmio_probe(struct kmmio_probe *p); - /* Called from page fault handler. */ extern int kmmio_handler(struct pt_regs *regs, unsigned long addr); -#ifdef CONFIG_MMIOTRACE /* Called from ioremap.c */ extern void mmiotrace_ioremap(resource_size_t offset, unsigned long size, void __iomem *addr); @@ -43,7 +49,17 @@ extern void mmiotrace_iounmap(volatile void __iomem *addr); /* For anyone to insert markers. Remember trailing newline. */ extern int mmiotrace_printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); -#else +#else /* !CONFIG_MMIOTRACE: */ +static inline int is_kmmio_active(void) +{ + return 0; +} + +static inline int kmmio_handler(struct pt_regs *regs, unsigned long addr) +{ + return 0; +} + static inline void mmiotrace_ioremap(resource_size_t offset, unsigned long size, void __iomem *addr) { @@ -63,28 +79,28 @@ static inline int mmiotrace_printk(const char *fmt, ...) #endif /* CONFIG_MMIOTRACE */ enum mm_io_opcode { - MMIO_READ = 0x1, /* struct mmiotrace_rw */ - MMIO_WRITE = 0x2, /* struct mmiotrace_rw */ - MMIO_PROBE = 0x3, /* struct mmiotrace_map */ - MMIO_UNPROBE = 0x4, /* struct mmiotrace_map */ - MMIO_UNKNOWN_OP = 0x5, /* struct mmiotrace_rw */ + MMIO_READ = 0x1, /* struct mmiotrace_rw */ + MMIO_WRITE = 0x2, /* struct mmiotrace_rw */ + MMIO_PROBE = 0x3, /* struct mmiotrace_map */ + MMIO_UNPROBE = 0x4, /* struct mmiotrace_map */ + MMIO_UNKNOWN_OP = 0x5, /* struct mmiotrace_rw */ }; struct mmiotrace_rw { - resource_size_t phys; /* PCI address of register */ - unsigned long value; - unsigned long pc; /* optional program counter */ - int map_id; - unsigned char opcode; /* one of MMIO_{READ,WRITE,UNKNOWN_OP} */ - unsigned char width; /* size of register access in bytes */ + resource_size_t phys; /* PCI address of register */ + unsigned long value; + unsigned long pc; /* optional program counter */ + int map_id; + unsigned char opcode; /* one of MMIO_{READ,WRITE,UNKNOWN_OP} */ + unsigned char width; /* size of register access in bytes */ }; struct mmiotrace_map { - resource_size_t phys; /* base address in PCI space */ - unsigned long virt; /* base virtual address */ - unsigned long len; /* mapping size */ - int map_id; - unsigned char opcode; /* MMIO_PROBE or MMIO_UNPROBE */ + resource_size_t phys; /* base address in PCI space */ + unsigned long virt; /* base virtual address */ + unsigned long len; /* mapping size */ + int map_id; + unsigned char opcode; /* MMIO_PROBE or MMIO_UNPROBE */ }; /* in kernel/trace/trace_mmiotrace.c */ @@ -94,4 +110,4 @@ extern void mmio_trace_rw(struct mmiotrace_rw *rw); extern void mmio_trace_mapping(struct mmiotrace_map *map); extern int mmio_trace_printk(const char *fmt, va_list args); -#endif /* MMIOTRACE_H */ +#endif /* _LINUX_MMIOTRACE_H */ -- cgit From b18018126f422f5b706fd750373425e10e84b486 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 20 Feb 2009 22:42:57 +0100 Subject: x86, mm, kprobes: fault.c, simplify notify_page_fault() Impact: cleanup Remove an #ifdef from notify_page_fault(). The function still compiles to nothing in the !CONFIG_KPROBES case. Introduce kprobes_built_in() and kprobe_fault_handler() helpers to allow this - they returns 0 if !CONFIG_KPROBES. No code changed: text data bss dec hex filename 4618 32 24 4674 1242 fault.o.before 4618 32 24 4674 1242 fault.o.after Cc: Masami Hiramatsu Cc: Andrew Morton Cc: Linus Torvalds Signed-off-by: Ingo Molnar --- arch/x86/mm/fault.c | 6 +----- include/linux/kprobes.h | 22 +++++++++++++++++++--- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index fe99af4b86d..379beaec6ca 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -68,11 +68,10 @@ static inline int kmmio_fault(struct pt_regs *regs, unsigned long addr) static inline int notify_page_fault(struct pt_regs *regs) { -#ifdef CONFIG_KPROBES int ret = 0; /* kprobe_running() needs smp_processor_id() */ - if (!user_mode_vm(regs)) { + if (kprobes_built_in() && !user_mode_vm(regs)) { preempt_disable(); if (kprobe_running() && kprobe_fault_handler(regs, 14)) ret = 1; @@ -80,9 +79,6 @@ static inline int notify_page_fault(struct pt_regs *regs) } return ret; -#else - return 0; -#endif } /* diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index 32851eef48f..2ec6cc14a11 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h @@ -182,6 +182,14 @@ struct kprobe_blackpoint { DECLARE_PER_CPU(struct kprobe *, current_kprobe); DECLARE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); +/* + * For #ifdef avoidance: + */ +static inline int kprobes_built_in(void) +{ + return 1; +} + #ifdef CONFIG_KRETPROBES extern void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs); @@ -271,8 +279,16 @@ void unregister_kretprobes(struct kretprobe **rps, int num); void kprobe_flush_task(struct task_struct *tk); void recycle_rp_inst(struct kretprobe_instance *ri, struct hlist_head *head); -#else /* CONFIG_KPROBES */ +#else /* !CONFIG_KPROBES: */ +static inline int kprobes_built_in(void) +{ + return 0; +} +static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) +{ + return 0; +} static inline struct kprobe *get_kprobe(void *addr) { return NULL; @@ -329,5 +345,5 @@ static inline void unregister_kretprobes(struct kretprobe **rps, int num) static inline void kprobe_flush_task(struct task_struct *tk) { } -#endif /* CONFIG_KPROBES */ -#endif /* _LINUX_KPROBES_H */ +#endif /* CONFIG_KPROBES */ +#endif /* _LINUX_KPROBES_H */ -- cgit From f2f13a8535174dbb813a0607a9d4737cfba98f6c Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 20 Feb 2009 22:50:24 +0100 Subject: x86, mm: fault.c, reorder functions Impact: cleanup Avoid a couple more #ifdefs by moving fundamentally non-unifiable functions into a single #ifdef 32-bit / #else / #endif block in fault.c: vmalloc*(), dump_pagetable(), check_vm8086_mode(). No code changed: text data bss dec hex filename 4618 32 24 4674 1242 fault.o.before 4618 32 24 4674 1242 fault.o.after Cc: Linus Torvalds Signed-off-by: Ingo Molnar --- arch/x86/mm/fault.c | 474 ++++++++++++++++++++++++++-------------------------- 1 file changed, 239 insertions(+), 235 deletions(-) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 379beaec6ca..4ce62fb80da 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -191,18 +191,124 @@ force_sig_info_fault(int si_signo, int si_code, unsigned long address, force_sig_info(si_signo, &info, tsk); } -#ifdef CONFIG_X86_64 -static int bad_address(void *p) +DEFINE_SPINLOCK(pgd_lock); +LIST_HEAD(pgd_list); + +#ifdef CONFIG_X86_32 +static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address) { - unsigned long dummy; + unsigned index = pgd_index(address); + pgd_t *pgd_k; + pud_t *pud, *pud_k; + pmd_t *pmd, *pmd_k; - return probe_kernel_address((unsigned long *)p, dummy); + pgd += index; + pgd_k = init_mm.pgd + index; + + if (!pgd_present(*pgd_k)) + return NULL; + + /* + * set_pgd(pgd, *pgd_k); here would be useless on PAE + * and redundant with the set_pmd() on non-PAE. As would + * set_pud. + */ + pud = pud_offset(pgd, address); + pud_k = pud_offset(pgd_k, address); + if (!pud_present(*pud_k)) + return NULL; + + pmd = pmd_offset(pud, address); + pmd_k = pmd_offset(pud_k, address); + if (!pmd_present(*pmd_k)) + return NULL; + + if (!pmd_present(*pmd)) { + set_pmd(pmd, *pmd_k); + arch_flush_lazy_mmu_mode(); + } else { + BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k)); + } + + return pmd_k; +} + +void vmalloc_sync_all(void) +{ + unsigned long address; + + if (SHARED_KERNEL_PMD) + return; + + for (address = VMALLOC_START & PMD_MASK; + address >= TASK_SIZE && address < FIXADDR_TOP; + address += PMD_SIZE) { + + unsigned long flags; + struct page *page; + + spin_lock_irqsave(&pgd_lock, flags); + list_for_each_entry(page, &pgd_list, lru) { + if (!vmalloc_sync_one(page_address(page), address)) + break; + } + spin_unlock_irqrestore(&pgd_lock, flags); + } +} + +/* + * 32-bit: + * + * Handle a fault on the vmalloc or module mapping area + */ +static noinline int vmalloc_fault(unsigned long address) +{ + unsigned long pgd_paddr; + pmd_t *pmd_k; + pte_t *pte_k; + + /* Make sure we are in vmalloc area: */ + if (!(address >= VMALLOC_START && address < VMALLOC_END)) + return -1; + + /* + * Synchronize this task's top level page-table + * with the 'reference' page table. + * + * Do _not_ use "current" here. We might be inside + * an interrupt in the middle of a task switch.. + */ + pgd_paddr = read_cr3(); + pmd_k = vmalloc_sync_one(__va(pgd_paddr), address); + if (!pmd_k) + return -1; + + pte_k = pte_offset_kernel(pmd_k, address); + if (!pte_present(*pte_k)) + return -1; + + return 0; +} + +/* + * Did it hit the DOS screen memory VA from vm86 mode? + */ +static inline void +check_v8086_mode(struct pt_regs *regs, unsigned long address, + struct task_struct *tsk) +{ + unsigned long bit; + + if (!v8086_mode(regs)) + return; + + bit = (address - 0xA0000) >> PAGE_SHIFT; + if (bit < 32) + tsk->thread.screen_bitmap |= 1 << bit; } -#endif static void dump_pagetable(unsigned long address) { -#ifdef CONFIG_X86_32 __typeof__(pte_val(__pte(0))) page; page = read_cr3(); @@ -239,7 +345,132 @@ static void dump_pagetable(unsigned long address) } printk("\n"); -#else /* CONFIG_X86_64 */ +} + +#else /* CONFIG_X86_64: */ + +void vmalloc_sync_all(void) +{ + unsigned long address; + + for (address = VMALLOC_START & PGDIR_MASK; address <= VMALLOC_END; + address += PGDIR_SIZE) { + + const pgd_t *pgd_ref = pgd_offset_k(address); + unsigned long flags; + struct page *page; + + if (pgd_none(*pgd_ref)) + continue; + + spin_lock_irqsave(&pgd_lock, flags); + list_for_each_entry(page, &pgd_list, lru) { + pgd_t *pgd; + pgd = (pgd_t *)page_address(page) + pgd_index(address); + if (pgd_none(*pgd)) + set_pgd(pgd, *pgd_ref); + else + BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref)); + } + spin_unlock_irqrestore(&pgd_lock, flags); + } +} + +/* + * 64-bit: + * + * Handle a fault on the vmalloc area + * + * This assumes no large pages in there. + */ +static noinline int vmalloc_fault(unsigned long address) +{ + pgd_t *pgd, *pgd_ref; + pud_t *pud, *pud_ref; + pmd_t *pmd, *pmd_ref; + pte_t *pte, *pte_ref; + + /* Make sure we are in vmalloc area: */ + if (!(address >= VMALLOC_START && address < VMALLOC_END)) + return -1; + + /* + * Copy kernel mappings over when needed. This can also + * happen within a race in page table update. In the later + * case just flush: + */ + pgd = pgd_offset(current->active_mm, address); + pgd_ref = pgd_offset_k(address); + if (pgd_none(*pgd_ref)) + return -1; + + if (pgd_none(*pgd)) + set_pgd(pgd, *pgd_ref); + else + BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref)); + + /* + * Below here mismatches are bugs because these lower tables + * are shared: + */ + + pud = pud_offset(pgd, address); + pud_ref = pud_offset(pgd_ref, address); + if (pud_none(*pud_ref)) + return -1; + + if (pud_none(*pud) || pud_page_vaddr(*pud) != pud_page_vaddr(*pud_ref)) + BUG(); + + pmd = pmd_offset(pud, address); + pmd_ref = pmd_offset(pud_ref, address); + if (pmd_none(*pmd_ref)) + return -1; + + if (pmd_none(*pmd) || pmd_page(*pmd) != pmd_page(*pmd_ref)) + BUG(); + + pte_ref = pte_offset_kernel(pmd_ref, address); + if (!pte_present(*pte_ref)) + return -1; + + pte = pte_offset_kernel(pmd, address); + + /* + * Don't use pte_page here, because the mappings can point + * outside mem_map, and the NUMA hash lookup cannot handle + * that: + */ + if (!pte_present(*pte) || pte_pfn(*pte) != pte_pfn(*pte_ref)) + BUG(); + + return 0; +} + +static const char errata93_warning[] = +KERN_ERR "******* Your BIOS seems to not contain a fix for K8 errata #93\n" +KERN_ERR "******* Working around it, but it may cause SEGVs or burn power.\n" +KERN_ERR "******* Please consider a BIOS update.\n" +KERN_ERR "******* Disabling USB legacy in the BIOS may also help.\n"; + +/* + * No vm86 mode in 64-bit mode: + */ +static inline void +check_v8086_mode(struct pt_regs *regs, unsigned long address, + struct task_struct *tsk) +{ +} + +static int bad_address(void *p) +{ + unsigned long dummy; + + return probe_kernel_address((unsigned long *)p, dummy); +} + +static void dump_pagetable(unsigned long address) +{ pgd_t *pgd; pud_t *pud; pmd_t *pmd; @@ -284,83 +515,9 @@ out: return; bad: printk("BAD\n"); -#endif -} - -#ifdef CONFIG_X86_32 -static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address) -{ - unsigned index = pgd_index(address); - pgd_t *pgd_k; - pud_t *pud, *pud_k; - pmd_t *pmd, *pmd_k; - - pgd += index; - pgd_k = init_mm.pgd + index; - - if (!pgd_present(*pgd_k)) - return NULL; - - /* - * set_pgd(pgd, *pgd_k); here would be useless on PAE - * and redundant with the set_pmd() on non-PAE. As would - * set_pud. - */ - pud = pud_offset(pgd, address); - pud_k = pud_offset(pgd_k, address); - if (!pud_present(*pud_k)) - return NULL; - - pmd = pmd_offset(pud, address); - pmd_k = pmd_offset(pud_k, address); - if (!pmd_present(*pmd_k)) - return NULL; - - if (!pmd_present(*pmd)) { - set_pmd(pmd, *pmd_k); - arch_flush_lazy_mmu_mode(); - } else { - BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k)); - } - - return pmd_k; -} - -/* - * Did it hit the DOS screen memory VA from vm86 mode? - */ -static inline void -check_v8086_mode(struct pt_regs *regs, unsigned long address, - struct task_struct *tsk) -{ - unsigned long bit; - - if (!v8086_mode(regs)) - return; - - bit = (address - 0xA0000) >> PAGE_SHIFT; - if (bit < 32) - tsk->thread.screen_bitmap |= 1 << bit; -} - -#else /* CONFIG_X86_64: */ - -static const char errata93_warning[] = -KERN_ERR "******* Your BIOS seems to not contain a fix for K8 errata #93\n" -KERN_ERR "******* Working around it, but it may cause SEGVs or burn power.\n" -KERN_ERR "******* Please consider a BIOS update.\n" -KERN_ERR "******* Disabling USB legacy in the BIOS may also help.\n"; - -/* - * No vm86 mode in 64-bit mode: - */ -static inline void -check_v8086_mode(struct pt_regs *regs, unsigned long address, - struct task_struct *tsk) -{ } -#endif +#endif /* CONFIG_X86_64 */ /* * Workaround for K8 erratum #93 & buggy BIOS. @@ -795,109 +952,6 @@ spurious_fault(unsigned long error_code, unsigned long address) return ret; } -/* - * 32-bit: - * - * Handle a fault on the vmalloc or module mapping area - * - * 64-bit: - * - * Handle a fault on the vmalloc area - * - * This assumes no large pages in there. - */ -static noinline int vmalloc_fault(unsigned long address) -{ -#ifdef CONFIG_X86_32 - unsigned long pgd_paddr; - pmd_t *pmd_k; - pte_t *pte_k; - - /* Make sure we are in vmalloc area: */ - if (!(address >= VMALLOC_START && address < VMALLOC_END)) - return -1; - - /* - * Synchronize this task's top level page-table - * with the 'reference' page table. - * - * Do _not_ use "current" here. We might be inside - * an interrupt in the middle of a task switch.. - */ - pgd_paddr = read_cr3(); - pmd_k = vmalloc_sync_one(__va(pgd_paddr), address); - if (!pmd_k) - return -1; - - pte_k = pte_offset_kernel(pmd_k, address); - if (!pte_present(*pte_k)) - return -1; - - return 0; -#else - pgd_t *pgd, *pgd_ref; - pud_t *pud, *pud_ref; - pmd_t *pmd, *pmd_ref; - pte_t *pte, *pte_ref; - - /* Make sure we are in vmalloc area: */ - if (!(address >= VMALLOC_START && address < VMALLOC_END)) - return -1; - - /* - * Copy kernel mappings over when needed. This can also - * happen within a race in page table update. In the later - * case just flush: - */ - pgd = pgd_offset(current->active_mm, address); - pgd_ref = pgd_offset_k(address); - if (pgd_none(*pgd_ref)) - return -1; - - if (pgd_none(*pgd)) - set_pgd(pgd, *pgd_ref); - else - BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref)); - - /* - * Below here mismatches are bugs because these lower tables - * are shared: - */ - - pud = pud_offset(pgd, address); - pud_ref = pud_offset(pgd_ref, address); - if (pud_none(*pud_ref)) - return -1; - - if (pud_none(*pud) || pud_page_vaddr(*pud) != pud_page_vaddr(*pud_ref)) - BUG(); - - pmd = pmd_offset(pud, address); - pmd_ref = pmd_offset(pud_ref, address); - if (pmd_none(*pmd_ref)) - return -1; - - if (pmd_none(*pmd) || pmd_page(*pmd) != pmd_page(*pmd_ref)) - BUG(); - - pte_ref = pte_offset_kernel(pmd_ref, address); - if (!pte_present(*pte_ref)) - return -1; - - pte = pte_offset_kernel(pmd, address); - - /* - * Don't use pte_page here, because the mappings can point - * outside mem_map, and the NUMA hash lookup cannot handle - * that: - */ - if (!pte_present(*pte) || pte_pfn(*pte) != pte_pfn(*pte_ref)) - BUG(); - - return 0; -#endif -} - int show_unhandled_signals = 1; static inline int @@ -1115,53 +1169,3 @@ good_area: up_read(&mm->mmap_sem); } - -DEFINE_SPINLOCK(pgd_lock); -LIST_HEAD(pgd_list); - -void vmalloc_sync_all(void) -{ - unsigned long address; - -#ifdef CONFIG_X86_32 - if (SHARED_KERNEL_PMD) - return; - - for (address = VMALLOC_START & PMD_MASK; - address >= TASK_SIZE && address < FIXADDR_TOP; - address += PMD_SIZE) { - - unsigned long flags; - struct page *page; - - spin_lock_irqsave(&pgd_lock, flags); - list_for_each_entry(page, &pgd_list, lru) { - if (!vmalloc_sync_one(page_address(page), address)) - break; - } - spin_unlock_irqrestore(&pgd_lock, flags); - } -#else /* CONFIG_X86_64 */ - for (address = VMALLOC_START & PGDIR_MASK; address <= VMALLOC_END; - address += PGDIR_SIZE) { - - const pgd_t *pgd_ref = pgd_offset_k(address); - unsigned long flags; - struct page *page; - - if (pgd_none(*pgd_ref)) - continue; - - spin_lock_irqsave(&pgd_lock, flags); - list_for_each_entry(page, &pgd_list, lru) { - pgd_t *pgd; - pgd = (pgd_t *)page_address(page) + pgd_index(address); - if (pgd_none(*pgd)) - set_pgd(pgd, *pgd_ref); - else - BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref)); - } - spin_unlock_irqrestore(&pgd_lock, flags); - } -#endif -} -- cgit From 8f7661496cece8320137d5e26808825498fd2b26 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 20 Feb 2009 23:00:29 +0100 Subject: x86, mm: fault.c, unify oops printing Impact: refine/extend page fault related oops printing on 64-bit - honor the pause_on_oops logic on 64-bit too - print out NX fault warnings on 64-bit as well - factor out the NX fault message to make it git-greppable and readable Note that this means that we do the PF_INSTR check on 32-bit non-PAE as well where it should not occur ... normally. Cannot hurt. Cc: Linus Torvalds Signed-off-by: Ingo Molnar --- arch/x86/mm/fault.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 4ce62fb80da..ebfaca3bbb1 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -595,28 +595,24 @@ static int is_f00f_bug(struct pt_regs *regs, unsigned long address) return 0; } +static const char nx_warning[] = KERN_CRIT +"kernel tried to execute NX-protected page - exploit attempt? (uid: %d)\n"; + static void show_fault_oops(struct pt_regs *regs, unsigned long error_code, unsigned long address) { -#ifdef CONFIG_X86_32 if (!oops_may_print()) return; -#endif -#ifdef CONFIG_X86_PAE if (error_code & PF_INSTR) { unsigned int level; pte_t *pte = lookup_address(address, &level); - if (pte && pte_present(*pte) && !pte_exec(*pte)) { - printk(KERN_CRIT "kernel tried to execute " - "NX-protected page - exploit attempt? " - "(uid: %d)\n", current_uid()); - } + if (pte && pte_present(*pte) && !pte_exec(*pte)) + printk(nx_warning, current_uid()); } -#endif printk(KERN_ALERT "BUG: unable to handle kernel "); if (address < PAGE_SIZE) -- cgit From 1cc99544dde9e48602979f16b9309fade6e93051 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 20 Feb 2009 23:07:48 +0100 Subject: x86, mm: fault.c, unify oops handling Impact: add oops-recursion check to 32-bit Unify the oops state-machine, to the 64-bit version. It is slightly more careful in that it does a recursion check in oops_begin(), and is thus more likely to show the relevant oops. It also means that 32-bit will print one more line at the end of pagefault triggered oopses: printk(KERN_EMERG "CR2: %016lx\n", address); Which is generally good information to be seen in partial-dump digital-camera jpegs ;-) The downside is the somewhat more complex critical path. Both variants have been tested well meanwhile by kernel developers crashing their boxes so i dont think this is a practical worry. This removes 3 ugly #ifdefs from no_context() and makes the function a lot nicer read. Cc: Linus Torvalds Signed-off-by: Ingo Molnar --- arch/x86/mm/fault.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index ebfaca3bbb1..8fe2dd254df 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -659,11 +659,8 @@ no_context(struct pt_regs *regs, unsigned long error_code, { struct task_struct *tsk = current; unsigned long *stackend; - -#ifdef CONFIG_X86_64 unsigned long flags; int sig; -#endif /* Are we prepared to handle this kernel fault? */ if (fixup_exception(regs)) @@ -690,11 +687,7 @@ no_context(struct pt_regs *regs, unsigned long error_code, * Oops. The kernel tried to access some bad page. We'll have to * terminate things with extreme prejudice: */ -#ifdef CONFIG_X86_32 - bust_spinlocks(1); -#else flags = oops_begin(); -#endif show_fault_oops(regs, error_code, address); @@ -702,15 +695,10 @@ no_context(struct pt_regs *regs, unsigned long error_code, if (*stackend != STACK_END_MAGIC) printk(KERN_ALERT "Thread overran stack, or stack corrupted\n"); - tsk->thread.cr2 = address; - tsk->thread.trap_no = 14; - tsk->thread.error_code = error_code; + tsk->thread.cr2 = address; + tsk->thread.trap_no = 14; + tsk->thread.error_code = error_code; -#ifdef CONFIG_X86_32 - die("Oops", regs, error_code); - bust_spinlocks(0); - do_exit(SIGKILL); -#else sig = SIGKILL; if (__die("Oops", regs, error_code)) sig = 0; @@ -719,7 +707,6 @@ no_context(struct pt_regs *regs, unsigned long error_code, printk(KERN_EMERG "CR2: %016lx\n", address); oops_end(flags, regs, sig); -#endif } /* -- cgit From c3731c68668325abddee8665018c74c7156a57be Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 20 Feb 2009 23:22:34 +0100 Subject: x86, mm: fault.c, remove #ifdef from do_page_fault() Impact: cleanup do_page_fault() has this ugly #ifdef in its prototype: #ifdef CONFIG_X86_64 asmlinkage #endif void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) Replace it with 'dotraplinkage' which maps to exactly the above construct: nothing on 32-bit and asmlinkage on 64-bit. Cc: Linus Torvalds Signed-off-by: Ingo Molnar --- arch/x86/mm/fault.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 8fe2dd254df..9c2dc5d7953 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -972,10 +972,8 @@ static int fault_in_kernel_space(unsigned long address) * and the problem, and then passes it off to one of the appropriate * routines. */ -#ifdef CONFIG_X86_64 -asmlinkage -#endif -void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) +dotraplinkage void __kprobes +do_page_fault(struct pt_regs *regs, unsigned long error_code) { struct vm_area_struct *vma; struct task_struct *tsk; -- cgit From d951734654f76a370a89b4e531af9b765bd13541 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 20 Feb 2009 23:32:28 +0100 Subject: x86, mm: rename TASK_SIZE64 => TASK_SIZE_MAX Impact: cleanup Rename TASK_SIZE64 to TASK_SIZE_MAX, and provide the define on 32-bit too. (mapped to TASK_SIZE) This allows 32-bit code to make use of the (former-) TASK_SIZE64 symbol as well, in a clean way. Cc: Linus Torvalds Signed-off-by: Ingo Molnar --- arch/x86/include/asm/processor.h | 9 +++++---- arch/x86/kernel/ptrace.c | 2 +- arch/x86/mm/fault.c | 2 +- arch/x86/vdso/vma.c | 4 ++-- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 72914d0315e..c7a98f73821 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -861,6 +861,7 @@ static inline void spin_lock_prefetch(const void *x) * User space process size: 3GB (default). */ #define TASK_SIZE PAGE_OFFSET +#define TASK_SIZE_MAX TASK_SIZE #define STACK_TOP TASK_SIZE #define STACK_TOP_MAX STACK_TOP @@ -920,7 +921,7 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk); /* * User space process size. 47bits minus one guard page. */ -#define TASK_SIZE64 ((1UL << 47) - PAGE_SIZE) +#define TASK_SIZE_MAX ((1UL << 47) - PAGE_SIZE) /* This decides where the kernel will search for a free chunk of vm * space during mmap's. @@ -929,12 +930,12 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk); 0xc0000000 : 0xFFFFe000) #define TASK_SIZE (test_thread_flag(TIF_IA32) ? \ - IA32_PAGE_OFFSET : TASK_SIZE64) + IA32_PAGE_OFFSET : TASK_SIZE_MAX) #define TASK_SIZE_OF(child) ((test_tsk_thread_flag(child, TIF_IA32)) ? \ - IA32_PAGE_OFFSET : TASK_SIZE64) + IA32_PAGE_OFFSET : TASK_SIZE_MAX) #define STACK_TOP TASK_SIZE -#define STACK_TOP_MAX TASK_SIZE64 +#define STACK_TOP_MAX TASK_SIZE_MAX #define INIT_THREAD { \ .sp0 = (unsigned long)&init_stack + sizeof(init_stack) \ diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index d2f7cd5b2c8..fb2159a5c81 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -268,7 +268,7 @@ static unsigned long debugreg_addr_limit(struct task_struct *task) if (test_tsk_thread_flag(task, TIF_IA32)) return IA32_PAGE_OFFSET - 3; #endif - return TASK_SIZE64 - 7; + return TASK_SIZE_MAX - 7; } #endif /* CONFIG_X86_32 */ diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 9c2dc5d7953..6fa9f175cba 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -963,7 +963,7 @@ static int fault_in_kernel_space(unsigned long address) #ifdef CONFIG_X86_32 return address >= TASK_SIZE; #else - return address >= TASK_SIZE64; + return address >= TASK_SIZE_MAX; #endif } diff --git a/arch/x86/vdso/vma.c b/arch/x86/vdso/vma.c index 9c98cc6ba97..7133cdf9098 100644 --- a/arch/x86/vdso/vma.c +++ b/arch/x86/vdso/vma.c @@ -85,8 +85,8 @@ static unsigned long vdso_addr(unsigned long start, unsigned len) unsigned long addr, end; unsigned offset; end = (start + PMD_SIZE - 1) & PMD_MASK; - if (end >= TASK_SIZE64) - end = TASK_SIZE64; + if (end >= TASK_SIZE_MAX) + end = TASK_SIZE_MAX; end -= len; /* This loses some more bits than a modulo, but is cheaper */ offset = get_random_int() & (PTRS_PER_PTE - 1); -- cgit From 7c178a26d3e753d2a4346d3e4b8aa549d387f698 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 20 Feb 2009 23:27:29 +0100 Subject: x86, mm: fault.c, remove #ifdef from fault_in_kernel_space() Impact: cleanup Removal of an #ifdef in fault_in_kernel_space(), by making use of the new TASK_SIZE_MAX symbol which is now available on 32-bit too. Cc: Linus Torvalds Signed-off-by: Ingo Molnar --- arch/x86/mm/fault.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 6fa9f175cba..f195691ec26 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -960,11 +960,7 @@ access_error(unsigned long error_code, int write, struct vm_area_struct *vma) static int fault_in_kernel_space(unsigned long address) { -#ifdef CONFIG_X86_32 - return address >= TASK_SIZE; -#else return address >= TASK_SIZE_MAX; -#endif } /* -- cgit From cd1b68f08f6328737928e5b8ba8ef80394680ff0 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 20 Feb 2009 23:39:02 +0100 Subject: x86, mm: fault.c, give another attempt at prefetch handing before SIGBUS Impact: extend prefetch handling on 64-bit Currently there's an extra is_prefetch() check done in do_sigbus(), which we only do on 32 bits. This is a last-ditch check before we terminate a task, so it's worth giving prefetch instructions another chance - should none of our existing quirks have caught a prefetch instruction related spurious fault. The only risk is if a prefetch causes a real sigbus, in that case we'll not OOM but try another fault. But this code has been on 32-bit for a long time, so it should be fine in practice. So do this on 64-bit too - and thus remove one more #ifdef. Cc: Linus Torvalds Signed-off-by: Ingo Molnar --- arch/x86/mm/fault.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index f195691ec26..413e835e4a8 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -836,11 +836,9 @@ do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address) if (!(error_code & PF_USER)) no_context(regs, error_code, address); -#ifdef CONFIG_X86_32 - /* User space => ok to do another page fault: */ + /* User-space => ok to do another page fault: */ if (is_prefetch(regs, error_code, address)) return; -#endif tsk->thread.cr2 = address; tsk->thread.error_code = error_code; -- cgit From f8eeb2e6be367d79be3617f0a12646bced8b2fe6 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 20 Feb 2009 23:13:36 +0100 Subject: x86, mm: fault.c, update copyrights Signed-off-by: Ingo Molnar --- arch/x86/mm/fault.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 413e835e4a8..9bb07d331c3 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -1,6 +1,7 @@ /* * Copyright (C) 1995 Linus Torvalds * Copyright (C) 2001, 2002 Andi Kleen, SuSE Labs. + * Copyright (C) 2008-2009, Red Hat Inc., Ingo Molnar */ #include #include -- cgit From 41a9e64ca4d60dc412cfcd42d5be5dec1f1ed427 Mon Sep 17 00:00:00 2001 From: Luca Bigliardi Date: Fri, 20 Feb 2009 15:38:36 -0800 Subject: uml: fix vde network backend in user mode linux * Replace kmalloc() with uml_kmalloc() (fix build failure) * Remove unnecessary UM_KERN_INFO in printk() (don't display '<6>' while printing info) Signed-off-by: Luca Bigliardi Cc: Jiri Kosina Reviewed-by: WANG Cong Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/vde_user.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/um/drivers/vde_user.c b/arch/um/drivers/vde_user.c index 56533db2534..c5c43253e6c 100644 --- a/arch/um/drivers/vde_user.c +++ b/arch/um/drivers/vde_user.c @@ -78,7 +78,7 @@ void vde_init_libstuff(struct vde_data *vpri, struct vde_init *init) { struct vde_open_args *args; - vpri->args = kmalloc(sizeof(struct vde_open_args), UM_GFP_KERNEL); + vpri->args = uml_kmalloc(sizeof(struct vde_open_args), UM_GFP_KERNEL); if (vpri->args == NULL) { printk(UM_KERN_ERR "vde_init_libstuff - vde_open_args " "allocation failed"); @@ -91,8 +91,8 @@ void vde_init_libstuff(struct vde_data *vpri, struct vde_init *init) args->group = init->group; args->mode = init->mode ? init->mode : 0700; - args->port ? printk(UM_KERN_INFO "port %d", args->port) : - printk(UM_KERN_INFO "undefined port"); + args->port ? printk("port %d", args->port) : + printk("undefined port"); } int vde_user_read(void *conn, void *buf, int len) -- cgit From 58bafe72ad937ec0813109254a154cf32be25fc4 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 20 Feb 2009 15:38:38 -0800 Subject: mn10300: fix oprofile oprofile for MN10300 seems to have been broken by the advent of the new tracing framework. Signed-off-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mn10300/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig index 9a9f4335887..41d16822e61 100644 --- a/arch/mn10300/Kconfig +++ b/arch/mn10300/Kconfig @@ -7,6 +7,7 @@ mainmenu "Linux Kernel Configuration" config MN10300 def_bool y + select HAVE_OPROFILE config AM33 def_bool y -- cgit From d9190913b71831f5e3d04de62cfb1fd069a9db35 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 20 Feb 2009 15:38:40 -0800 Subject: mn10300: fix typo && -> || in arch/mn10300/unit-asb2305/pci.c Fix the typo && -> ||. Signed-off-by: Wei Yongjun Signed-off-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mn10300/unit-asb2305/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mn10300/unit-asb2305/pci.c b/arch/mn10300/unit-asb2305/pci.c index 1a86425fec4..07dbbcda3b2 100644 --- a/arch/mn10300/unit-asb2305/pci.c +++ b/arch/mn10300/unit-asb2305/pci.c @@ -173,7 +173,7 @@ static int pci_ampci_write_config_byte(struct pci_bus *bus, unsigned int devfn, BRIDGEREGB(where) = value; } else { if (bus->number == 0 && - (devfn == PCI_DEVFN(2, 0) && devfn == PCI_DEVFN(3, 0)) + (devfn == PCI_DEVFN(2, 0) || devfn == PCI_DEVFN(3, 0)) ) __pcidebug("<= %02x", bus, devfn, where, value); CONFIG_ADDRESS = CONFIG_CMD(bus, devfn, where); -- cgit From 3ef0e5ba467366125f04b423f4638baca54a4fc1 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Fri, 20 Feb 2009 15:38:41 -0800 Subject: slab: introduce kzfree() kzfree() is a wrapper for kfree() that additionally zeroes the underlying memory before releasing it to the slab allocator. Currently there is code which memset()s the memory region of an object before releasing it back to the slab allocator to make sure security-sensitive data are really zeroed out after use. These callsites can then just use kzfree() which saves some code, makes users greppable and allows for a stupid destructor that isn't necessarily aware of the actual object size. Signed-off-by: Johannes Weiner Reviewed-by: Pekka Enberg Cc: Matt Mackall Acked-by: Christoph Lameter Cc: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/slab.h | 1 + mm/util.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/include/linux/slab.h b/include/linux/slab.h index f96d13c281e..24c5602bee9 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -127,6 +127,7 @@ int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr); void * __must_check __krealloc(const void *, size_t, gfp_t); void * __must_check krealloc(const void *, size_t, gfp_t); void kfree(const void *); +void kzfree(const void *); size_t ksize(const void *); /* diff --git a/mm/util.c b/mm/util.c index cb00b748ce4..37eaccdf305 100644 --- a/mm/util.c +++ b/mm/util.c @@ -129,6 +129,26 @@ void *krealloc(const void *p, size_t new_size, gfp_t flags) } EXPORT_SYMBOL(krealloc); +/** + * kzfree - like kfree but zero memory + * @p: object to free memory of + * + * The memory of the object @p points to is zeroed before freed. + * If @p is %NULL, kzfree() does nothing. + */ +void kzfree(const void *p) +{ + size_t ks; + void *mem = (void *)p; + + if (unlikely(ZERO_OR_NULL_PTR(mem))) + return; + ks = ksize(mem); + memset(mem, 0, ks); + kfree(mem); +} +EXPORT_SYMBOL(kzfree); + /* * strndup_user - duplicate an existing string from user space * @s: The string to duplicate -- cgit From ad444684b78f12fb3f45a733722e2cbfe102d25c Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Fri, 20 Feb 2009 15:38:43 -0800 Subject: README: fix a wrong filename It should be Documentation/build/kconfig.txt. Introduced by commit 2af238e455ef5fd31c2f7a06c2db3f13d843b9bf ("kbuild: make *config usage docs"). Signed-off-by: Li Zefan Cc: Sam Ravnborg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 90a07658ede..d6c6c742c1d 100644 --- a/README +++ b/README @@ -188,7 +188,7 @@ CONFIGURING the kernel: values to random values. You can find more information on using the Linux kernel config tools - in Documentation/kbuild/make-configs.txt. + in Documentation/kbuild/kconfig.txt. NOTES on "make config": - having unnecessary drivers will make the kernel bigger, and can -- cgit From 9b6d25100ace1dcf9750803ff08f6b61f840be79 Mon Sep 17 00:00:00 2001 From: Ilpo Järvinen Date: Fri, 20 Feb 2009 15:38:45 -0800 Subject: sx.c: fix dbl statement if - add missing braces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Caused by 736d54533aed (sx.c: fix missed unlock_kernel() on error path in sx_fw_ioctl()). You guys keep breaking things this way in every single kernel release in at least couple of places... :-( Signed-off-by: Ilpo Järvinen Acked-by: Dan Carpenter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/sx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/char/sx.c b/drivers/char/sx.c index f146e90404f..d7c416566bd 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c @@ -1746,9 +1746,10 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd, sx_dprintk(SX_DEBUG_FIRMWARE, "returning type= %ld\n", rc); break; case SXIO_DO_RAMTEST: - if (sx_initialized) /* Already initialized: better not ramtest the board. */ + if (sx_initialized) { /* Already initialized: better not ramtest the board. */ rc = -EPERM; break; + } if (IS_SX_BOARD(board)) { rc = do_memtest(board, 0, 0x7000); if (!rc) -- cgit From b28fe28f2a07ee325834179174a95495d2786561 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 20 Feb 2009 15:38:46 -0800 Subject: sx.c: avoid referencing freed memory if copy_from_user() fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "break" would just result in reusing a free'd pointer. I don't have the cards myself to test it though. :/ Signed-off-by: Dan Carpenter Cc: Ilpo Järvinen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/sx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/sx.c b/drivers/char/sx.c index d7c416566bd..518f2a25d91 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c @@ -1789,7 +1789,7 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd, nbytes - i : SX_CHUNK_SIZE)) { kfree(tmp); rc = -EFAULT; - break; + goto out; } memcpy_toio(board->base2 + offset + i, tmp, (i + SX_CHUNK_SIZE > nbytes) ? -- cgit From 152de30bced150617e5731a9fe2364c9d04fe26c Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 20 Feb 2009 15:38:47 -0800 Subject: docsrc: use config instead of menuconfig BUILD_DOCSRC should be controlled by "config" instead of "menuconfig". I have no idea how I managed to use "menuconfig" here. Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/Kconfig.debug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 29044f50026..1bcf9cd4baa 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -838,7 +838,7 @@ config FIREWIRE_OHCI_REMOTE_DMA If unsure, say N. -menuconfig BUILD_DOCSRC +config BUILD_DOCSRC bool "Build targets in Documentation/ tree" depends on HEADERS_CHECK help -- cgit From 3fd076dd955a34c35dc456f4ef676e03cdced044 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Fri, 20 Feb 2009 15:38:48 -0800 Subject: cpuset: various documentation fixes and updates I noticed the old commit 8f5aa26c75b7722e80c0c5c5bb833d41865d7019 ("cpusets: update_cpumask documentation fix") is not a complete fix, resulting in inconsistent paragraphs. This patch fixes it and does other fixes and updates: - s/migrate_all_tasks()/migrate_live_tasks()/ - describe more cpuset control files - s/cpumask_t/struct cpumask/ - document cpu hotplug and change of 'sched_relax_domain_level' may cause domain rebuild - document various ways to query and modify cpusets - the equivalent of "mount -t cpuset" is "mount -t cgroup -o cpuset,noprefix" Signed-off-by: Li Zefan Acked-by: Randy Dunlap Cc: Paul Menage Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/cgroups/cpusets.txt | 65 ++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/Documentation/cgroups/cpusets.txt b/Documentation/cgroups/cpusets.txt index 5c86c258c79..0611e9528c7 100644 --- a/Documentation/cgroups/cpusets.txt +++ b/Documentation/cgroups/cpusets.txt @@ -142,7 +142,7 @@ into the rest of the kernel, none in performance critical paths: - in fork and exit, to attach and detach a task from its cpuset. - in sched_setaffinity, to mask the requested CPUs by what's allowed in that tasks cpuset. - - in sched.c migrate_all_tasks(), to keep migrating tasks within + - in sched.c migrate_live_tasks(), to keep migrating tasks within the CPUs allowed by their cpuset, if possible. - in the mbind and set_mempolicy system calls, to mask the requested Memory Nodes by what's allowed in that tasks cpuset. @@ -175,6 +175,10 @@ files describing that cpuset: - mem_exclusive flag: is memory placement exclusive? - mem_hardwall flag: is memory allocation hardwalled - memory_pressure: measure of how much paging pressure in cpuset + - memory_spread_page flag: if set, spread page cache evenly on allowed nodes + - memory_spread_slab flag: if set, spread slab cache evenly on allowed nodes + - sched_load_balance flag: if set, load balance within CPUs on that cpuset + - sched_relax_domain_level: the searching range when migrating tasks In addition, the root cpuset only has the following file: - memory_pressure_enabled flag: compute memory_pressure? @@ -252,7 +256,7 @@ is causing. This is useful both on tightly managed systems running a wide mix of submitted jobs, which may choose to terminate or re-prioritize jobs that -are trying to use more memory than allowed on the nodes assigned them, +are trying to use more memory than allowed on the nodes assigned to them, and with tightly coupled, long running, massively parallel scientific computing jobs that will dramatically fail to meet required performance goals if they start to use more memory than allowed to them. @@ -378,7 +382,7 @@ as cpusets and sched_setaffinity. The algorithmic cost of load balancing and its impact on key shared kernel data structures such as the task list increases more than linearly with the number of CPUs being balanced. So the scheduler -has support to partition the systems CPUs into a number of sched +has support to partition the systems CPUs into a number of sched domains such that it only load balances within each sched domain. Each sched domain covers some subset of the CPUs in the system; no two sched domains overlap; some CPUs might not be in any sched @@ -485,17 +489,22 @@ of CPUs allowed to a cpuset having 'sched_load_balance' enabled. The internal kernel cpuset to scheduler interface passes from the cpuset code to the scheduler code a partition of the load balanced CPUs in the system. This partition is a set of subsets (represented -as an array of cpumask_t) of CPUs, pairwise disjoint, that cover all -the CPUs that must be load balanced. - -Whenever the 'sched_load_balance' flag changes, or CPUs come or go -from a cpuset with this flag enabled, or a cpuset with this flag -enabled is removed, the cpuset code builds a new such partition and -passes it to the scheduler sched domain setup code, to have the sched -domains rebuilt as necessary. +as an array of struct cpumask) of CPUs, pairwise disjoint, that cover +all the CPUs that must be load balanced. + +The cpuset code builds a new such partition and passes it to the +scheduler sched domain setup code, to have the sched domains rebuilt +as necessary, whenever: + - the 'sched_load_balance' flag of a cpuset with non-empty CPUs changes, + - or CPUs come or go from a cpuset with this flag enabled, + - or 'sched_relax_domain_level' value of a cpuset with non-empty CPUs + and with this flag enabled changes, + - or a cpuset with non-empty CPUs and with this flag enabled is removed, + - or a cpu is offlined/onlined. This partition exactly defines what sched domains the scheduler should -setup - one sched domain for each element (cpumask_t) in the partition. +setup - one sched domain for each element (struct cpumask) in the +partition. The scheduler remembers the currently active sched domain partitions. When the scheduler routine partition_sched_domains() is invoked from @@ -559,7 +568,7 @@ domain, the largest value among those is used. Be careful, if one requests 0 and others are -1 then 0 is used. Note that modifying this file will have both good and bad effects, -and whether it is acceptable or not will be depend on your situation. +and whether it is acceptable or not depends on your situation. Don't modify this file if you are not sure. If your situation is: @@ -600,19 +609,15 @@ to allocate a page of memory for that task. If a cpuset has its 'cpus' modified, then each task in that cpuset will have its allowed CPU placement changed immediately. Similarly, -if a tasks pid is written to a cpusets 'tasks' file, in either its -current cpuset or another cpuset, then its allowed CPU placement is -changed immediately. If such a task had been bound to some subset -of its cpuset using the sched_setaffinity() call, the task will be -allowed to run on any CPU allowed in its new cpuset, negating the -affect of the prior sched_setaffinity() call. +if a tasks pid is written to another cpusets 'tasks' file, then its +allowed CPU placement is changed immediately. If such a task had been +bound to some subset of its cpuset using the sched_setaffinity() call, +the task will be allowed to run on any CPU allowed in its new cpuset, +negating the effect of the prior sched_setaffinity() call. In summary, the memory placement of a task whose cpuset is changed is updated by the kernel, on the next allocation of a page for that task, -but the processor placement is not updated, until that tasks pid is -rewritten to the 'tasks' file of its cpuset. This is done to avoid -impacting the scheduler code in the kernel with a check for changes -in a tasks processor placement. +and the processor placement is updated immediately. Normally, once a page is allocated (given a physical page of main memory) then that page stays on whatever node it @@ -681,10 +686,14 @@ and then start a subshell 'sh' in that cpuset: # The next line should display '/Charlie' cat /proc/self/cpuset -In the future, a C library interface to cpusets will likely be -available. For now, the only way to query or modify cpusets is -via the cpuset file system, using the various cd, mkdir, echo, cat, -rmdir commands from the shell, or their equivalent from C. +There are ways to query or modify cpusets: + - via the cpuset file system directly, using the various cd, mkdir, echo, + cat, rmdir commands from the shell, or their equivalent from C. + - via the C library libcpuset. + - via the C library libcgroup. + (http://sourceforge.net/proects/libcg/) + - via the python application cset. + (http://developer.novell.com/wiki/index.php/Cpuset) The sched_setaffinity calls can also be done at the shell prompt using SGI's runon or Robert Love's taskset. The mbind and set_mempolicy @@ -756,7 +765,7 @@ mount -t cpuset X /dev/cpuset is equivalent to -mount -t cgroup -ocpuset X /dev/cpuset +mount -t cgroup -ocpuset,noprefix X /dev/cpuset echo "/sbin/cpuset_release_agent" > /dev/cpuset/release_agent 2.2 Adding/removing cpus -- cgit From f6fcba7014f9cc535fa75ef98c008b24e49e2212 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 20 Feb 2009 15:38:48 -0800 Subject: vmalloc: call flush_cache_vunmap() from unmap_kernel_range() Impact: proper vcache flush on unmap_kernel_range() flush_cache_vunmap() should be called before pages are unmapped. Add a call to it in unmap_kernel_range(). Signed-off-by: Tejun Heo Acked-by: Nick Piggin Acked-by: David S. Miller Cc: [2.6.28.x] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmalloc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 4dd2636d0b9..903cad46e79 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -1012,6 +1012,8 @@ void __init vmalloc_init(void) void unmap_kernel_range(unsigned long addr, unsigned long size) { unsigned long end = addr + size; + + flush_cache_vunmap(addr, end); vunmap_page_range(addr, end); flush_tlb_kernel_range(addr, end); } -- cgit From 01b24fee285b098c74318a8be801ef3711ec18d7 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Fri, 20 Feb 2009 15:38:49 -0800 Subject: spi_bitbang: add more lowlevel function documentation This adds more documentation of the lowlevel API to avoid future bugs. Signed-off-by: Michael Buesch Acked-by: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/spi/spi_bitbang.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/linux/spi/spi_bitbang.h b/include/linux/spi/spi_bitbang.h index bf8de281b4e..eed4254bd50 100644 --- a/include/linux/spi/spi_bitbang.h +++ b/include/linux/spi/spi_bitbang.h @@ -83,6 +83,13 @@ extern int spi_bitbang_stop(struct spi_bitbang *spi); * int getmiso(struct spi_device *); * void spidelay(unsigned); * + * setsck()'s is_on parameter is a zero/nonzero boolean. + * + * setmosi()'s is_on parameter is a zero/nonzero boolean. + * + * getmiso() is required to return 0 or 1 only. Any other value is invalid + * and will result in improper operation. + * * A non-inlined routine would call bitbang_txrx_*() routines. The * main loop could easily compile down to a handful of instructions, * especially if the delay is a NOP (to run at peak speed). -- cgit From 3cf311409d37d904335eb720e8a6b2c17bee6698 Mon Sep 17 00:00:00 2001 From: Yang Hongyang Date: Fri, 20 Feb 2009 15:38:51 -0800 Subject: atyfb: remove unused local variable `pwr_command' Signed-off-by: Yang Hongyang Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/aty/aty128fb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index e6e299feb51..2181ce4d7eb 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c @@ -2365,7 +2365,6 @@ static void fbcon_aty128_bmove(struct display *p, int sy, int sx, int dy, int dx static void aty128_set_suspend(struct aty128fb_par *par, int suspend) { u32 pmgt; - u16 pwr_command; struct pci_dev *pdev = par->pdev; if (!par->pm_reg) -- cgit From b6adea334c6c89d5e6c94f9196bbf3a279cb53bd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 20 Feb 2009 15:38:52 -0800 Subject: 8250: fix boot hang with serial console when using with Serial Over Lan port Intel 8257x Ethernet boards have a feature called Serial Over Lan. This feature works by emulating a serial port, and it is detected by kernel as a normal 8250 port. However, this emulation is not perfect, as also noticed on changeset 7500b1f602aad75901774a67a687ee985d85893f. Before this patch, the kernel were trying to check if the serial TX is capable of work using IRQ's. This were done with a code similar this: serial_outp(up, UART_IER, UART_IER_THRI); lsr = serial_in(up, UART_LSR); iir = serial_in(up, UART_IIR); serial_outp(up, UART_IER, 0); if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) up->bugs |= UART_BUG_TXEN; This works fine for other 8250 ports, but, on 8250-emulated SoL port, the chip is a little lazy to down UART_IIR_NO_INT at UART_IIR register. Due to that, UART_BUG_TXEN is sometimes enabled. However, as TX IRQ keeps working, and the TX polling is now enabled, the driver miss-interprets the IRQ received later, hanging up the machine until a key is pressed at the serial console. This is the 6 version of this patch. Previous versions were trying to introduce a large enough delay between serial_outp and serial_in(up, UART_IIR), but not taking forever. However, the needed delay couldn't be safely determined. At the experimental tests, a delay of 1us solves most of the cases, but still hangs sometimes. Increasing the delay to 5us was better, but still doesn't solve. A very high delay of 50 ms seemed to work every time. However, poking around with delays and pray for it to be enough doesn't seem to be a good approach, even for a quirk. So, instead of playing with random large arbitrary delays, let's just disable UART_BUG_TXEN for all SoL ports. [akpm@linux-foundation.org: fix warnings] Signed-off-by: Mauro Carvalho Chehab Cc: Alan Cox Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/8250.c | 15 +++++++++++++++ drivers/serial/8250_pci.c | 36 ++++++++++++++++++++++++++++++++++++ include/linux/pci_ids.h | 3 +++ include/linux/serial_core.h | 1 + 4 files changed, 55 insertions(+) diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 0d934bfbdd9..b4b39811b44 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -2083,6 +2083,20 @@ static int serial8250_startup(struct uart_port *port) serial8250_set_mctrl(&up->port, up->port.mctrl); + /* Serial over Lan (SoL) hack: + Intel 8257x Gigabit ethernet chips have a + 16550 emulation, to be used for Serial Over Lan. + Those chips take a longer time than a normal + serial device to signalize that a transmission + data was queued. Due to that, the above test generally + fails. One solution would be to delay the reading of + iir. However, this is not reliable, since the timeout + is variable. So, let's just don't test if we receive + TX irq. This way, we'll never enable UART_BUG_TXEN. + */ + if (up->port.flags & UPF_NO_TXEN_TEST) + goto dont_test_tx_en; + /* * Do a quick test to see if we receive an * interrupt when we enable the TX irq. @@ -2102,6 +2116,7 @@ static int serial8250_startup(struct uart_port *port) up->bugs &= ~UART_BUG_TXEN; } +dont_test_tx_en: spin_unlock_irqrestore(&up->port.lock, flags); /* diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index 536d8e510f6..533f82025ad 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c @@ -798,6 +798,21 @@ pci_default_setup(struct serial_private *priv, return setup_port(priv, port, bar, offset, board->reg_shift); } +static int skip_tx_en_setup(struct serial_private *priv, + const struct pciserial_board *board, + struct uart_port *port, int idx) +{ + port->flags |= UPF_NO_TXEN_TEST; + printk(KERN_DEBUG "serial8250: skipping TxEn test for device " + "[%04x:%04x] subsystem [%04x:%04x]\n", + priv->dev->vendor, + priv->dev->device, + priv->dev->subsystem_vendor, + priv->dev->subsystem_device); + + return pci_default_setup(priv, board, port, idx); +} + /* This should be in linux/pci_ids.h */ #define PCI_VENDOR_ID_SBSMODULARIO 0x124B #define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B @@ -864,6 +879,27 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .init = pci_inteli960ni_init, .setup = pci_default_setup, }, + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_8257X_SOL, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .setup = skip_tx_en_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82573L_SOL, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .setup = skip_tx_en_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82573E_SOL, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .setup = skip_tx_en_setup, + }, /* * ITE */ diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 114b8192eab..aca8c458aa8 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2323,6 +2323,9 @@ #define PCI_DEVICE_ID_INTEL_82378 0x0484 #define PCI_DEVICE_ID_INTEL_I960 0x0960 #define PCI_DEVICE_ID_INTEL_I960RM 0x0962 +#define PCI_DEVICE_ID_INTEL_8257X_SOL 0x1062 +#define PCI_DEVICE_ID_INTEL_82573E_SOL 0x1085 +#define PCI_DEVICE_ID_INTEL_82573L_SOL 0x108F #define PCI_DEVICE_ID_INTEL_82815_MC 0x1130 #define PCI_DEVICE_ID_INTEL_82815_CGC 0x1132 #define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221 diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 90bbbf0b116..df9245c7bd3 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -296,6 +296,7 @@ struct uart_port { #define UPF_HARDPPS_CD ((__force upf_t) (1 << 11)) #define UPF_LOW_LATENCY ((__force upf_t) (1 << 13)) #define UPF_BUGGY_UART ((__force upf_t) (1 << 14)) +#define UPF_NO_TXEN_TEST ((__force upf_t) (1 << 15)) #define UPF_MAGIC_MULTIPLIER ((__force upf_t) (1 << 16)) #define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24)) -- cgit From e4cce94c9c8797b08faf6a79396df4d175e377fa Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Tue, 10 Feb 2009 14:10:26 +0300 Subject: [CIFS] Prevent OOPs when mounting with remote prefixpath. Fixes OOPs with message 'kernel BUG at fs/cifs/cifs_dfs_ref.c:274!'. Checks if the prefixpath in an accesible while we are still in cifs_mount and fails with reporting a error if we can't access the prefixpath Should fix Samba bugs 6086 and 5861 and kernel bug 12192 Signed-off-by: Igor Mammedov Acked-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/cifsproto.h | 1 + fs/cifs/connect.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ fs/cifs/inode.c | 4 ++-- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 382ba629880..ec9f9c1c7d8 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -42,6 +42,7 @@ extern void _FreeXid(unsigned int); #define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__func__, xid,current_fsuid())); #define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__func__,curr_xid,(int)rc));} extern char *build_path_from_dentry(struct dentry *); +extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb); extern char *build_wildcard_path_from_dentry(struct dentry *direntry); /* extern void renew_parental_timestamps(struct dentry *direntry);*/ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *, diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 005df85219a..da0f4ffa061 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2180,6 +2180,33 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info, "mount option supported")); } +static int +is_path_accessible(int xid, struct cifsTconInfo *tcon, + struct cifs_sb_info *cifs_sb, const char *full_path) +{ + int rc; + __u64 inode_num; + FILE_ALL_INFO *pfile_info; + + rc = CIFSGetSrvInodeNumber(xid, tcon, full_path, &inode_num, + cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); + if (rc != -EOPNOTSUPP) + return rc; + + pfile_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); + if (pfile_info == NULL) + return -ENOMEM; + + rc = CIFSSMBQPathInfo(xid, tcon, full_path, pfile_info, + 0 /* not legacy */, cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); + kfree(pfile_info); + return rc; +} + int cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, char *mount_data, const char *devname) @@ -2190,6 +2217,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, struct cifsSesInfo *pSesInfo = NULL; struct cifsTconInfo *tcon = NULL; struct TCP_Server_Info *srvTcp = NULL; + char *full_path; xid = GetXid(); @@ -2426,6 +2454,23 @@ mount_fail_check: cifs_sb->rsize = min(cifs_sb->rsize, (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)); + if (!rc && cifs_sb->prepathlen) { + /* build_path_to_root works only when we have a valid tcon */ + full_path = cifs_build_path_to_root(cifs_sb); + if (full_path == NULL) { + rc = -ENOMEM; + goto mount_fail_check; + } + rc = is_path_accessible(xid, tcon, cifs_sb, full_path); + if (rc) { + cERROR(1, ("Path %s in not accessible: %d", + full_path, rc)); + kfree(full_path); + goto mount_fail_check; + } + kfree(full_path); + } + /* volume_info->password is freed above when existing session found (in which case it is not needed anymore) but when new sesion is created the password ptr is put in the new session structure (in which case the diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index bcf7b518466..7342bfb02ae 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -621,7 +621,7 @@ static const struct inode_operations cifs_ipc_inode_ops = { .lookup = cifs_lookup, }; -static char *build_path_to_root(struct cifs_sb_info *cifs_sb) +char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb) { int pplen = cifs_sb->prepathlen; int dfsplen; @@ -678,7 +678,7 @@ struct inode *cifs_iget(struct super_block *sb, unsigned long ino) return inode; cifs_sb = CIFS_SB(inode->i_sb); - full_path = build_path_to_root(cifs_sb); + full_path = cifs_build_path_to_root(cifs_sb); if (full_path == NULL) return ERR_PTR(-ENOMEM); -- cgit From 132ac7b77cc95a22d6118d327c96586759fbf006 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 10 Feb 2009 07:33:57 -0500 Subject: cifs: refactor new_inode() calls and inode initialization Move new inode creation into a separate routine and refactor the callers to take advantage of it. Signed-off-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/cifsproto.h | 2 ++ fs/cifs/inode.c | 96 +++++++++++++++++++++++++++++++++-------------------- fs/cifs/readdir.c | 54 ++++++++++++++---------------- 3 files changed, 86 insertions(+), 66 deletions(-) diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index ec9f9c1c7d8..62fd5bd499f 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -92,6 +92,8 @@ extern u64 cifs_UnixTimeToNT(struct timespec); extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time); extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time); +extern struct inode *cifs_new_inode(struct super_block *sb, + unsigned long *inum); extern int cifs_get_inode_info(struct inode **pinode, const unsigned char *search_path, FILE_ALL_INFO *pfile_info, diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 7342bfb02ae..c7674f595ad 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -199,6 +199,49 @@ static void fill_fake_finddataunix(FILE_UNIX_BASIC_INFO *pfnd_dat, pfnd_dat->Gid = cpu_to_le64(pinode->i_gid); } +/** + * cifs_new inode - create new inode, initialize, and hash it + * @sb - pointer to superblock + * @inum - if valid pointer and serverino is enabled, replace i_ino with val + * + * Create a new inode, initialize it for CIFS and hash it. Returns the new + * inode or NULL if one couldn't be allocated. + * + * If the share isn't mounted with "serverino" or inum is a NULL pointer then + * we'll just use the inode number assigned by new_inode(). Note that this can + * mean i_ino collisions since the i_ino assigned by new_inode is not + * guaranteed to be unique. + */ +struct inode * +cifs_new_inode(struct super_block *sb, unsigned long *inum) +{ + struct inode *inode; + + inode = new_inode(sb); + if (inode == NULL) + return NULL; + + /* + * BB: Is i_ino == 0 legal? Here, we assume that it is. If it isn't we + * stop passing inum as ptr. Are there sanity checks we can use to + * ensure that the server is really filling in that field? Also, + * if serverino is disabled, perhaps we should be using iunique()? + */ + if (inum && (CIFS_SB(sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) + inode->i_ino = *inum; + + /* + * must set this here instead of cifs_alloc_inode since VFS will + * clobber i_flags + */ + if (sb->s_flags & MS_NOATIME) + inode->i_flags |= S_NOATIME | S_NOCMTIME; + + insert_inode_hash(inode); + + return inode; +} + int cifs_get_inode_info_unix(struct inode **pinode, const unsigned char *full_path, struct super_block *sb, int xid) { @@ -233,22 +276,12 @@ int cifs_get_inode_info_unix(struct inode **pinode, /* get new inode */ if (*pinode == NULL) { - *pinode = new_inode(sb); + *pinode = cifs_new_inode(sb, (unsigned long *) + &find_data.UniqueId); if (*pinode == NULL) { rc = -ENOMEM; goto cgiiu_exit; } - /* Is an i_ino of zero legal? */ - /* note ino incremented to unique num in new_inode */ - /* Are there sanity checks we can use to ensure that - the server is really filling in that field? */ - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) - (*pinode)->i_ino = (unsigned long)find_data.UniqueId; - - if (sb->s_flags & MS_NOATIME) - (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME; - - insert_inode_hash(*pinode); } inode = *pinode; @@ -465,11 +498,8 @@ int cifs_get_inode_info(struct inode **pinode, /* get new inode */ if (*pinode == NULL) { - *pinode = new_inode(sb); - if (*pinode == NULL) { - rc = -ENOMEM; - goto cgii_exit; - } + __u64 inode_num; + /* Is an i_ino of zero legal? Can we use that to check if the server supports returning inode numbers? Are there other sanity checks we can use to ensure that @@ -486,7 +516,6 @@ int cifs_get_inode_info(struct inode **pinode, if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { int rc1 = 0; - __u64 inode_num; rc1 = CIFSGetSrvInodeNumber(xid, pTcon, full_path, &inode_num, @@ -496,12 +525,17 @@ int cifs_get_inode_info(struct inode **pinode, if (rc1) { cFYI(1, ("GetSrvInodeNum rc %d", rc1)); /* BB EOPNOSUPP disable SERVER_INUM? */ - } else /* do we need cast or hash to ino? */ - (*pinode)->i_ino = inode_num; - } /* else ino incremented to unique num in new_inode*/ - if (sb->s_flags & MS_NOATIME) - (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME; - insert_inode_hash(*pinode); + } + *pinode = cifs_new_inode(sb, (unsigned long *) + &inode_num); + } else { + *pinode = cifs_new_inode(sb, NULL); + } + + if (*pinode == NULL) { + rc = -ENOMEM; + goto cgii_exit; + } } inode = *pinode; cifsInfo = CIFS_I(inode); @@ -1114,24 +1148,14 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) else direntry->d_op = &cifs_dentry_ops; - newinode = new_inode(inode->i_sb); + newinode = cifs_new_inode(inode->i_sb, (unsigned long *) + &pInfo->UniqueId); if (newinode == NULL) { kfree(pInfo); goto mkdir_get_info; } - /* Is an i_ino of zero legal? */ - /* Are there sanity checks we can use to ensure that - the server is really filling in that field? */ - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { - newinode->i_ino = - (unsigned long)pInfo->UniqueId; - } /* note ino incremented to unique num in new_inode */ - if (inode->i_sb->s_flags & MS_NOATIME) - newinode->i_flags |= S_NOATIME | S_NOCMTIME; newinode->i_nlink = 2; - - insert_inode_hash(newinode); d_instantiate(direntry, newinode); /* we already checked in POSIXCreate whether diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 9f51f9bf029..02a20221e84 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -56,35 +56,34 @@ static inline void dump_cifs_file_struct(struct file *file, char *label) } #endif /* DEBUG2 */ -/* Returns one if new inode created (which therefore needs to be hashed) */ +/* Returns 1 if new inode created, 2 if both dentry and inode were */ /* Might check in the future if inode number changed so we can rehash inode */ -static int construct_dentry(struct qstr *qstring, struct file *file, - struct inode **ptmp_inode, struct dentry **pnew_dentry) +static int +construct_dentry(struct qstr *qstring, struct file *file, + struct inode **ptmp_inode, struct dentry **pnew_dentry, + unsigned long *inum) { - struct dentry *tmp_dentry; - struct cifs_sb_info *cifs_sb; - struct cifsTconInfo *pTcon; + struct dentry *tmp_dentry = NULL; + struct super_block *sb = file->f_path.dentry->d_sb; int rc = 0; cFYI(1, ("For %s", qstring->name)); - cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); - pTcon = cifs_sb->tcon; qstring->hash = full_name_hash(qstring->name, qstring->len); tmp_dentry = d_lookup(file->f_path.dentry, qstring); if (tmp_dentry) { + /* BB: overwrite old name? i.e. tmp_dentry->d_name and + * tmp_dentry->d_name.len?? + */ cFYI(0, ("existing dentry with inode 0x%p", tmp_dentry->d_inode)); *ptmp_inode = tmp_dentry->d_inode; -/* BB overwrite old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len??*/ if (*ptmp_inode == NULL) { - *ptmp_inode = new_inode(file->f_path.dentry->d_sb); + *ptmp_inode = cifs_new_inode(sb, inum); if (*ptmp_inode == NULL) return rc; rc = 1; } - if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME) - (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME; } else { tmp_dentry = d_alloc(file->f_path.dentry, qstring); if (tmp_dentry == NULL) { @@ -93,15 +92,14 @@ static int construct_dentry(struct qstr *qstring, struct file *file, return rc; } - *ptmp_inode = new_inode(file->f_path.dentry->d_sb); - if (pTcon->nocase) + if (CIFS_SB(sb)->tcon->nocase) tmp_dentry->d_op = &cifs_ci_dentry_ops; else tmp_dentry->d_op = &cifs_dentry_ops; + + *ptmp_inode = cifs_new_inode(sb, inum); if (*ptmp_inode == NULL) return rc; - if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME) - (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME; rc = 2; } @@ -842,9 +840,7 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst, len = strnlen(filename, PATH_MAX); } - /* BB fixme - hash low and high 32 bits if not 64 bit arch BB */ - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) - *pinum = pFindData->UniqueId; + *pinum = pFindData->UniqueId; } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) { FILE_DIRECTORY_INFO *pFindData = (FILE_DIRECTORY_INFO *)current_entry; @@ -940,20 +936,18 @@ static int cifs_filldir(char *pfindEntry, struct file *file, if (rc) return rc; - rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry); + /* only these two infolevels return valid inode numbers */ + if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX || + pCifsF->srch_inf.info_level == SMB_FIND_FILE_ID_FULL_DIR_INFO) + rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry, + &inum); + else + rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry, + NULL); + if ((tmp_inode == NULL) || (tmp_dentry == NULL)) return -ENOMEM; - if (rc) { - /* inode created, we need to hash it with right inode number */ - if (inum != 0) { - /* BB fixme - hash the 2 32 quantities bits together if - * necessary BB */ - tmp_inode->i_ino = inum; - } - insert_inode_hash(tmp_inode); - } - /* we pass in rc below, indicating whether it is a new inode, so we can figure out whether to invalidate the inode cached data if the file has changed */ -- cgit From 950ec52880fab89b957c7dc45e8b8476dd63741f Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Wed, 11 Feb 2009 08:08:26 -0500 Subject: cifs: properly handle case where CIFSGetSrvInodeNumber fails ...if it does then we pass a pointer to an unintialized variable for the inode number to cifs_new_inode. Have it pass a NULL pointer instead. Also tweak the function prototypes to reduce the amount of casting. Signed-off-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/cifsproto.h | 3 +-- fs/cifs/inode.c | 20 ++++++++++---------- fs/cifs/readdir.c | 6 +++--- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 62fd5bd499f..446e62cbece 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -92,8 +92,7 @@ extern u64 cifs_UnixTimeToNT(struct timespec); extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time); extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time); -extern struct inode *cifs_new_inode(struct super_block *sb, - unsigned long *inum); +extern struct inode *cifs_new_inode(struct super_block *sb, __u64 *inum); extern int cifs_get_inode_info(struct inode **pinode, const unsigned char *search_path, FILE_ALL_INFO *pfile_info, diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index c7674f595ad..475115c7cc7 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -213,7 +213,7 @@ static void fill_fake_finddataunix(FILE_UNIX_BASIC_INFO *pfnd_dat, * guaranteed to be unique. */ struct inode * -cifs_new_inode(struct super_block *sb, unsigned long *inum) +cifs_new_inode(struct super_block *sb, __u64 *inum) { struct inode *inode; @@ -228,7 +228,7 @@ cifs_new_inode(struct super_block *sb, unsigned long *inum) * if serverino is disabled, perhaps we should be using iunique()? */ if (inum && (CIFS_SB(sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) - inode->i_ino = *inum; + inode->i_ino = (unsigned long) *inum; /* * must set this here instead of cifs_alloc_inode since VFS will @@ -276,8 +276,7 @@ int cifs_get_inode_info_unix(struct inode **pinode, /* get new inode */ if (*pinode == NULL) { - *pinode = cifs_new_inode(sb, (unsigned long *) - &find_data.UniqueId); + *pinode = cifs_new_inode(sb, &find_data.UniqueId); if (*pinode == NULL) { rc = -ENOMEM; goto cgiiu_exit; @@ -499,6 +498,7 @@ int cifs_get_inode_info(struct inode **pinode, /* get new inode */ if (*pinode == NULL) { __u64 inode_num; + __u64 *pinum = &inode_num; /* Is an i_ino of zero legal? Can we use that to check if the server supports returning inode numbers? Are @@ -518,20 +518,20 @@ int cifs_get_inode_info(struct inode **pinode, int rc1 = 0; rc1 = CIFSGetSrvInodeNumber(xid, pTcon, - full_path, &inode_num, + full_path, pinum, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (rc1) { cFYI(1, ("GetSrvInodeNum rc %d", rc1)); + pinum = NULL; /* BB EOPNOSUPP disable SERVER_INUM? */ } - *pinode = cifs_new_inode(sb, (unsigned long *) - &inode_num); } else { - *pinode = cifs_new_inode(sb, NULL); + pinum = NULL; } + *pinode = cifs_new_inode(sb, pinum); if (*pinode == NULL) { rc = -ENOMEM; goto cgii_exit; @@ -1148,8 +1148,8 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) else direntry->d_op = &cifs_dentry_ops; - newinode = cifs_new_inode(inode->i_sb, (unsigned long *) - &pInfo->UniqueId); + newinode = cifs_new_inode(inode->i_sb, + &pInfo->UniqueId); if (newinode == NULL) { kfree(pInfo); goto mkdir_get_info; diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 02a20221e84..c2c01ff4c32 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -61,7 +61,7 @@ static inline void dump_cifs_file_struct(struct file *file, char *label) static int construct_dentry(struct qstr *qstring, struct file *file, struct inode **ptmp_inode, struct dentry **pnew_dentry, - unsigned long *inum) + __u64 *inum) { struct dentry *tmp_dentry = NULL; struct super_block *sb = file->f_path.dentry->d_sb; @@ -820,7 +820,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, /* inode num, inode type and filename returned */ static int cifs_get_name_from_search_buf(struct qstr *pqst, char *current_entry, __u16 level, unsigned int unicode, - struct cifs_sb_info *cifs_sb, int max_len, ino_t *pinum) + struct cifs_sb_info *cifs_sb, int max_len, __u64 *pinum) { int rc = 0; unsigned int len = 0; @@ -903,7 +903,7 @@ static int cifs_filldir(char *pfindEntry, struct file *file, struct qstr qstring; struct cifsFileInfo *pCifsF; unsigned int obj_type; - ino_t inum; + __u64 inum; struct cifs_sb_info *cifs_sb; struct inode *tmp_inode; struct dentry *tmp_dentry; -- cgit From 44f68fadd865bb288ebdcea2b602f0b1cab27a0c Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Wed, 11 Feb 2009 08:08:28 -0500 Subject: cifs: posix fill in inode needed by posix open function needed to prepare for posix open Signed-off-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/cifsproto.h | 2 ++ fs/cifs/inode.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 446e62cbece..083dfc57c7a 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -92,6 +92,8 @@ extern u64 cifs_UnixTimeToNT(struct timespec); extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time); extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time); +extern void posix_fill_in_inode(struct inode *tmp_inode, + FILE_UNIX_BASIC_INFO *pData, int isNewInode); extern struct inode *cifs_new_inode(struct super_block *sb, __u64 *inum); extern int cifs_get_inode_info(struct inode **pinode, const unsigned char *search_path, diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 475115c7cc7..4690a360c85 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -1051,7 +1051,7 @@ out_reval: return rc; } -static void posix_fill_in_inode(struct inode *tmp_inode, +void posix_fill_in_inode(struct inode *tmp_inode, FILE_UNIX_BASIC_INFO *pData, int isNewInode) { struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode); -- cgit From 69765529d701c838df19ea1f5ad2f33a528261ae Mon Sep 17 00:00:00 2001 From: Steve French Date: Tue, 17 Feb 2009 01:29:40 +0000 Subject: [CIFS] Fix oops in cifs_strfromUCS_le mounting to servers which do not specify their OS Fixes kernel bug #10451 http://bugzilla.kernel.org/show_bug.cgi?id=10451 Certain NAS appliances do not set the operating system or network operating system fields in the session setup response on the wire. cifs was oopsing on the unexpected zero length response fields (when trying to null terminate a zero length field). This fixes the oops. Acked-by: Jeff Layton CC: stable Signed-off-by: Steve French --- fs/cifs/CHANGES | 3 ++- fs/cifs/sess.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 73ac7ebd1df..1cfa72ef1f3 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -7,7 +7,8 @@ specified and user does not have access to query information about the top of the share. Fix problem in 2.6.28 resolving DFS paths to Samba servers (worked to Windows). Fix rmdir so that pending search (readdir) requests do not get invalid results which include the now -removed directory. +removed directory. Fix oops in cifs_dfs_ref.c when prefixpath is not reachable +when using DFS. Version 1.55 ------------ diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 5f22de7b79a..b234407a300 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -228,7 +228,7 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft, kfree(ses->serverOS); /* UTF-8 string will not grow more than four times as big as UCS-16 */ - ses->serverOS = kzalloc(4 * len, GFP_KERNEL); + ses->serverOS = kzalloc((4 * len) + 2 /* trailing null */, GFP_KERNEL); if (ses->serverOS != NULL) cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp); data += 2 * (len + 1); @@ -241,7 +241,7 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft, return rc; kfree(ses->serverNOS); - ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */ + ses->serverNOS = kzalloc((4 * len) + 2 /* trailing null */, GFP_KERNEL); if (ses->serverNOS != NULL) { cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len, nls_cp); -- cgit From c3b2a0c640bff7df85d79fb4f89674949a267ec2 Mon Sep 17 00:00:00 2001 From: Steve French Date: Fri, 20 Feb 2009 04:32:45 +0000 Subject: [CIFS] improve posix semantics of file create Samba server added support for a new posix open/create/mkdir operation a year or so ago, and we added support to cifs for mkdir to use it, but had not added the corresponding code to file create. The following patch helps improve the performance of the cifs create path (to Samba and servers which support the cifs posix protocol extensions). Using Connectathon basic test1, with 2000 files, the performance improved about 15%, and also helped reduce network traffic (17% fewer SMBs sent over the wire) due to saving a network round trip for the SetPathInfo on every file create. It should also help the semantics (and probably the performance) of write (e.g. when posix byte range locks are on the file) on file handles opened with posix create, and adds support for a few flags which would have to be ignored otherwise. Signed-off-by: Steve French --- fs/cifs/CHANGES | 4 +- fs/cifs/dir.c | 307 +++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 208 insertions(+), 103 deletions(-) diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 1cfa72ef1f3..72063f5e56b 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -8,7 +8,9 @@ top of the share. Fix problem in 2.6.28 resolving DFS paths to Samba servers (worked to Windows). Fix rmdir so that pending search (readdir) requests do not get invalid results which include the now removed directory. Fix oops in cifs_dfs_ref.c when prefixpath is not reachable -when using DFS. +when using DFS. Add better file create support to servers which support +the CIFS POSIX protocol extensions (this adds support for new flags +on create, and improves semantics for write of locked ranges). Version 1.55 ------------ diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 964aad03c5a..89fb7283265 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -3,7 +3,7 @@ * * vfs operations that deal with dentries * - * Copyright (C) International Business Machines Corp., 2002,2008 + * Copyright (C) International Business Machines Corp., 2002,2009 * Author(s): Steve French (sfrench@us.ibm.com) * * This library is free software; you can redistribute it and/or modify @@ -129,6 +129,78 @@ cifs_bp_rename_retry: return full_path; } +static int cifs_posix_open(char *full_path, struct inode **pinode, + struct super_block *sb, int mode, int oflags, + int *poplock, __u16 *pnetfid, int xid) +{ + int rc; + __u32 oplock; + FILE_UNIX_BASIC_INFO *presp_data; + __u32 posix_flags = 0; + struct cifs_sb_info *cifs_sb = CIFS_SB(sb); + + cFYI(1, ("posix open %s", full_path)); + + presp_data = kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); + if (presp_data == NULL) + return -ENOMEM; + +/* So far cifs posix extensions can only map the following flags. + There are other valid fmode oflags such as FMODE_LSEEK, FMODE_PREAD, but + so far we do not seem to need them, and we can treat them as local only */ + if ((oflags & (FMODE_READ | FMODE_WRITE)) == + (FMODE_READ | FMODE_WRITE)) + posix_flags = SMB_O_RDWR; + else if (oflags & FMODE_READ) + posix_flags = SMB_O_RDONLY; + else if (oflags & FMODE_WRITE) + posix_flags = SMB_O_WRONLY; + if (oflags & O_CREAT) + posix_flags |= SMB_O_CREAT; + if (oflags & O_EXCL) + posix_flags |= SMB_O_EXCL; + if (oflags & O_TRUNC) + posix_flags |= SMB_O_TRUNC; + if (oflags & O_APPEND) + posix_flags |= SMB_O_APPEND; + if (oflags & O_SYNC) + posix_flags |= SMB_O_SYNC; + if (oflags & O_DIRECTORY) + posix_flags |= SMB_O_DIRECTORY; + if (oflags & O_NOFOLLOW) + posix_flags |= SMB_O_NOFOLLOW; + if (oflags & O_DIRECT) + posix_flags |= SMB_O_DIRECT; + + + rc = CIFSPOSIXCreate(xid, cifs_sb->tcon, posix_flags, mode, + pnetfid, presp_data, &oplock, full_path, + cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); + if (rc) + goto posix_open_ret; + + if (presp_data->Type == cpu_to_le32(-1)) + goto posix_open_ret; /* open ok, caller does qpathinfo */ + + /* get new inode and set it up */ + if (!pinode) + goto posix_open_ret; /* caller does not need info */ + + *pinode = cifs_new_inode(sb, &presp_data->UniqueId); + + /* We do not need to close the file if new_inode fails since + the caller will retry qpathinfo as long as inode is null */ + if (*pinode == NULL) + goto posix_open_ret; + + posix_fill_in_inode(*pinode, presp_data, 1); + +posix_open_ret: + kfree(presp_data); + return rc; +} + static void setup_cifs_dentry(struct cifsTconInfo *tcon, struct dentry *direntry, struct inode *newinode) @@ -150,7 +222,14 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, int xid; int create_options = CREATE_NOT_DIR; int oplock = 0; - /* BB below access is too much for the mknod to request */ + int oflags; + /* + * BB below access is probably too much for mknod to request + * but we have to do query and setpathinfo so requesting + * less could fail (unless we want to request getatr and setatr + * permissions (only). At least for POSIX we do not have to + * request so much. + */ int desiredAccess = GENERIC_READ | GENERIC_WRITE; __u16 fileHandle; struct cifs_sb_info *cifs_sb; @@ -174,13 +253,43 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, } mode &= ~current->fs->umask; + if (oplockEnabled) + oplock = REQ_OPLOCK; - if (nd && (nd->flags & LOOKUP_OPEN)) { - int oflags = nd->intent.open.flags; + if (nd && (nd->flags & LOOKUP_OPEN)) + oflags = nd->intent.open.flags; + else + oflags = FMODE_READ; + + if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) && + (CIFS_UNIX_POSIX_PATH_OPS_CAP & + le64_to_cpu(tcon->fsUnixInfo.Capability))) { + rc = cifs_posix_open(full_path, &newinode, inode->i_sb, + mode, oflags, &oplock, &fileHandle, xid); + /* EIO could indicate that (posix open) operation is not + supported, despite what server claimed in capability + negotation. EREMOTE indicates DFS junction, which is not + handled in posix open */ + + if ((rc == 0) && (newinode == NULL)) + goto cifs_create_get_file_info; /* query inode info */ + else if (rc == 0) /* success, no need to query */ + goto cifs_create_set_dentry; + else if ((rc != -EIO) && (rc != -EREMOTE) && + (rc != -EOPNOTSUPP)) /* path not found or net err */ + goto cifs_create_out; + /* else fallthrough to retry, using older open call, this is + case where server does not support this SMB level, and + falsely claims capability (also get here for DFS case + which should be rare for path not covered on files) */ + } + if (nd && (nd->flags & LOOKUP_OPEN)) { + /* if the file is going to stay open, then we + need to set the desired access properly */ desiredAccess = 0; if (oflags & FMODE_READ) - desiredAccess |= GENERIC_READ; + desiredAccess |= GENERIC_READ; /* is this too little? */ if (oflags & FMODE_WRITE) { desiredAccess |= GENERIC_WRITE; if (!(oflags & FMODE_READ)) @@ -199,8 +308,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, /* BB add processing to set equivalent of mode - e.g. via CreateX with ACLs */ - if (oplockEnabled) - oplock = REQ_OPLOCK; buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); if (buf == NULL) { @@ -233,116 +340,112 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, } if (rc) { cFYI(1, ("cifs_create returned 0x%x", rc)); - } else { - /* If Open reported that we actually created a file - then we now have to set the mode if possible */ - if ((tcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) { - struct cifs_unix_set_info_args args = { + goto cifs_create_out; + } + + /* If Open reported that we actually created a file + then we now have to set the mode if possible */ + if ((tcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) { + struct cifs_unix_set_info_args args = { .mode = mode, .ctime = NO_CHANGE_64, .atime = NO_CHANGE_64, .mtime = NO_CHANGE_64, .device = 0, - }; + }; - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { - args.uid = (__u64) current_fsuid(); - if (inode->i_mode & S_ISGID) - args.gid = (__u64) inode->i_gid; - else - args.gid = (__u64) current_fsgid(); - } else { - args.uid = NO_CHANGE_64; - args.gid = NO_CHANGE_64; - } - CIFSSMBUnixSetInfo(xid, tcon, full_path, &args, - cifs_sb->local_nls, - cifs_sb->mnt_cifs_flags & - CIFS_MOUNT_MAP_SPECIAL_CHR); + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { + args.uid = (__u64) current_fsuid(); + if (inode->i_mode & S_ISGID) + args.gid = (__u64) inode->i_gid; + else + args.gid = (__u64) current_fsgid(); } else { - /* BB implement mode setting via Windows security - descriptors e.g. */ - /* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/ - - /* Could set r/o dos attribute if mode & 0222 == 0 */ + args.uid = NO_CHANGE_64; + args.gid = NO_CHANGE_64; } + CIFSSMBUnixSetInfo(xid, tcon, full_path, &args, + cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); + } else { + /* BB implement mode setting via Windows security + descriptors e.g. */ + /* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/ - /* server might mask mode so we have to query for it */ - if (tcon->unix_ext) - rc = cifs_get_inode_info_unix(&newinode, full_path, - inode->i_sb, xid); - else { - rc = cifs_get_inode_info(&newinode, full_path, - buf, inode->i_sb, xid, - &fileHandle); - if (newinode) { - if (cifs_sb->mnt_cifs_flags & - CIFS_MOUNT_DYNPERM) - newinode->i_mode = mode; - if ((oplock & CIFS_CREATE_ACTION) && - (cifs_sb->mnt_cifs_flags & - CIFS_MOUNT_SET_UID)) { - newinode->i_uid = current_fsuid(); - if (inode->i_mode & S_ISGID) - newinode->i_gid = - inode->i_gid; - else - newinode->i_gid = - current_fsgid(); - } + /* Could set r/o dos attribute if mode & 0222 == 0 */ + } + +cifs_create_get_file_info: + /* server might mask mode so we have to query for it */ + if (tcon->unix_ext) + rc = cifs_get_inode_info_unix(&newinode, full_path, + inode->i_sb, xid); + else { + rc = cifs_get_inode_info(&newinode, full_path, buf, + inode->i_sb, xid, &fileHandle); + if (newinode) { + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) + newinode->i_mode = mode; + if ((oplock & CIFS_CREATE_ACTION) && + (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) { + newinode->i_uid = current_fsuid(); + if (inode->i_mode & S_ISGID) + newinode->i_gid = inode->i_gid; + else + newinode->i_gid = current_fsgid(); } } + } - if (rc != 0) { - cFYI(1, ("Create worked, get_inode_info failed rc = %d", - rc)); - } else - setup_cifs_dentry(tcon, direntry, newinode); - - if ((nd == NULL /* nfsd case - nfs srv does not set nd */) || - (!(nd->flags & LOOKUP_OPEN))) { - /* mknod case - do not leave file open */ - CIFSSMBClose(xid, tcon, fileHandle); - } else if (newinode) { - struct cifsFileInfo *pCifsFile = - kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); - - if (pCifsFile == NULL) - goto cifs_create_out; - pCifsFile->netfid = fileHandle; - pCifsFile->pid = current->tgid; - pCifsFile->pInode = newinode; - pCifsFile->invalidHandle = false; - pCifsFile->closePend = false; - init_MUTEX(&pCifsFile->fh_sem); - mutex_init(&pCifsFile->lock_mutex); - INIT_LIST_HEAD(&pCifsFile->llist); - atomic_set(&pCifsFile->wrtPending, 0); - - /* set the following in open now +cifs_create_set_dentry: + if (rc == 0) + setup_cifs_dentry(tcon, direntry, newinode); + else + cFYI(1, ("Create worked, get_inode_info failed rc = %d", rc)); + + /* nfsd case - nfs srv does not set nd */ + if ((nd == NULL) || (!(nd->flags & LOOKUP_OPEN))) { + /* mknod case - do not leave file open */ + CIFSSMBClose(xid, tcon, fileHandle); + } else if (newinode) { + struct cifsFileInfo *pCifsFile = + kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); + + if (pCifsFile == NULL) + goto cifs_create_out; + pCifsFile->netfid = fileHandle; + pCifsFile->pid = current->tgid; + pCifsFile->pInode = newinode; + pCifsFile->invalidHandle = false; + pCifsFile->closePend = false; + init_MUTEX(&pCifsFile->fh_sem); + mutex_init(&pCifsFile->lock_mutex); + INIT_LIST_HEAD(&pCifsFile->llist); + atomic_set(&pCifsFile->wrtPending, 0); + + /* set the following in open now pCifsFile->pfile = file; */ - write_lock(&GlobalSMBSeslock); - list_add(&pCifsFile->tlist, &tcon->openFileList); - pCifsInode = CIFS_I(newinode); - if (pCifsInode) { - /* if readable file instance put first in list*/ - if (write_only) { - list_add_tail(&pCifsFile->flist, - &pCifsInode->openFileList); - } else { - list_add(&pCifsFile->flist, - &pCifsInode->openFileList); - } - if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { - pCifsInode->clientCanCacheAll = true; - pCifsInode->clientCanCacheRead = true; - cFYI(1, ("Exclusive Oplock inode %p", - newinode)); - } else if ((oplock & 0xF) == OPLOCK_READ) - pCifsInode->clientCanCacheRead = true; + write_lock(&GlobalSMBSeslock); + list_add(&pCifsFile->tlist, &tcon->openFileList); + pCifsInode = CIFS_I(newinode); + if (pCifsInode) { + /* if readable file instance put first in list*/ + if (write_only) { + list_add_tail(&pCifsFile->flist, + &pCifsInode->openFileList); + } else { + list_add(&pCifsFile->flist, + &pCifsInode->openFileList); } - write_unlock(&GlobalSMBSeslock); + if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { + pCifsInode->clientCanCacheAll = true; + pCifsInode->clientCanCacheRead = true; + cFYI(1, ("Exclusive Oplock inode %p", + newinode)); + } else if ((oplock & 0xF) == OPLOCK_READ) + pCifsInode->clientCanCacheRead = true; } + write_unlock(&GlobalSMBSeslock); } cifs_create_out: kfree(buf); -- cgit From eca6acf91552a9b2e997cc76339115c95eac0217 Mon Sep 17 00:00:00 2001 From: Steve French Date: Fri, 20 Feb 2009 05:43:09 +0000 Subject: [CIFS] Fix multiuser mounts so server does not invalidate earlier security contexts When two different users mount the same Windows 2003 Server share using CIFS, the first session mounted can be invalidated. Some servers invalidate the first smb session when a second similar user (e.g. two users who get mapped by server to "guest") authenticates an smb session from the same client. By making sure that we set the 2nd and subsequent vc numbers to nonzero values, this ensures that we will not have this problem. Fixes Samba bug 6004, problem description follows: How to reproduce: - configure an "open share" (full permissions to Guest user) on Windows 2003 Server (I couldn't reproduce the problem with Samba server or Windows older than 2003) - mount the share twice with different users who will be authenticated as guest. noacl,noperm,user=john,dir_mode=0700,domain=DOMAIN,rw noacl,noperm,user=jeff,dir_mode=0700,domain=DOMAIN,rw Result: - just the mount point mounted last is accessible: Signed-off-by: Steve French --- fs/cifs/CHANGES | 10 +++++++ fs/cifs/cifsfs.h | 2 +- fs/cifs/cifsglob.h | 6 +++- fs/cifs/cifssmb.c | 7 +++-- fs/cifs/sess.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 105 insertions(+), 7 deletions(-) diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 72063f5e56b..851388fafc7 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -1,3 +1,13 @@ +Version 1.57 +------------ +Improve support for multiple security contexts to the same server. We +used to use the same "vcnumber" for all connections which could cause +the server to treat subsequent connections, especially those that +are authenticated as guest, as reconnections, invalidating the earlier +user's smb session. This fix allows cifs to mount multiple times to the +same server with different userids without risking invalidating earlier +established security contexts. + Version 1.56 ------------ Add "forcemandatorylock" mount option to allow user to use mandatory diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 7ac481841f8..2b1d28a9ee2 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -100,5 +100,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); extern const struct export_operations cifs_export_ops; #endif /* EXPERIMENTAL */ -#define CIFS_VERSION "1.56" +#define CIFS_VERSION "1.57" #endif /* _CIFSFS_H */ diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 94c1ca0ec95..e004f6db5fc 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -164,9 +164,12 @@ struct TCP_Server_Info { /* multiplexed reads or writes */ unsigned int maxBuf; /* maxBuf specifies the maximum */ /* message size the server can send or receive for non-raw SMBs */ - unsigned int maxRw; /* maxRw specifies the maximum */ + unsigned int max_rw; /* maxRw specifies the maximum */ /* message size the server can send or receive for */ /* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */ + unsigned int max_vcs; /* maximum number of smb sessions, at least + those that can be specified uniquely with + vcnumbers */ char sessid[4]; /* unique token id for this session */ /* (returned on Negotiate */ int capabilities; /* allow selective disabling of caps by smb sess */ @@ -210,6 +213,7 @@ struct cifsSesInfo { unsigned overrideSecFlg; /* if non-zero override global sec flags */ __u16 ipc_tid; /* special tid for connection to IPC share */ __u16 flags; + __u16 vcnum; char *serverOS; /* name of operating system underlying server */ char *serverNOS; /* name of network operating system of server */ char *serverDomain; /* security realm of server */ diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 552642a507c..939e2f76b95 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -528,14 +528,15 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) server->maxReq = le16_to_cpu(rsp->MaxMpxCount); server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize), (__u32)CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); + server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs); GETU32(server->sessid) = le32_to_cpu(rsp->SessionKey); /* even though we do not use raw we might as well set this accurately, in case we ever find a need for it */ if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) { - server->maxRw = 0xFF00; + server->max_rw = 0xFF00; server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE; } else { - server->maxRw = 0;/* we do not need to use raw anyway */ + server->max_rw = 0;/* do not need to use raw anyway */ server->capabilities = CAP_MPX_MODE; } tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone); @@ -638,7 +639,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) /* probably no need to store and check maxvcs */ server->maxBuf = min(le32_to_cpu(pSMBr->MaxBufferSize), (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); - server->maxRw = le32_to_cpu(pSMBr->MaxRawSize); + server->max_rw = le32_to_cpu(pSMBr->MaxRawSize); cFYI(DBG2, ("Max buf = %d", ses->server->maxBuf)); GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey); server->capabilities = le32_to_cpu(pSMBr->Capabilities); diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index b234407a300..5c68b4282be 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -34,15 +34,99 @@ extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); +/* Checks if this is the first smb session to be reconnected after + the socket has been reestablished (so we know whether to use vc 0). + Called while holding the cifs_tcp_ses_lock, so do not block */ +static bool is_first_ses_reconnect(struct cifsSesInfo *ses) +{ + struct list_head *tmp; + struct cifsSesInfo *tmp_ses; + + list_for_each(tmp, &ses->server->smb_ses_list) { + tmp_ses = list_entry(tmp, struct cifsSesInfo, + smb_ses_list); + if (tmp_ses->need_reconnect == false) + return false; + } + /* could not find a session that was already connected, + this must be the first one we are reconnecting */ + return true; +} + +/* + * vc number 0 is treated specially by some servers, and should be the + * first one we request. After that we can use vcnumbers up to maxvcs, + * one for each smb session (some Windows versions set maxvcs incorrectly + * so maxvc=1 can be ignored). If we have too many vcs, we can reuse + * any vc but zero (some servers reset the connection on vcnum zero) + * + */ +static __le16 get_next_vcnum(struct cifsSesInfo *ses) +{ + __u16 vcnum = 0; + struct list_head *tmp; + struct cifsSesInfo *tmp_ses; + __u16 max_vcs = ses->server->max_vcs; + __u16 i; + int free_vc_found = 0; + + /* Quoting the MS-SMB specification: "Windows-based SMB servers set this + field to one but do not enforce this limit, which allows an SMB client + to establish more virtual circuits than allowed by this value ... but + other server implementations can enforce this limit." */ + if (max_vcs < 2) + max_vcs = 0xFFFF; + + write_lock(&cifs_tcp_ses_lock); + if ((ses->need_reconnect) && is_first_ses_reconnect(ses)) + goto get_vc_num_exit; /* vcnum will be zero */ + for (i = ses->server->srv_count - 1; i < max_vcs; i++) { + if (i == 0) /* this is the only connection, use vc 0 */ + break; + + free_vc_found = 1; + + list_for_each(tmp, &ses->server->smb_ses_list) { + tmp_ses = list_entry(tmp, struct cifsSesInfo, + smb_ses_list); + if (tmp_ses->vcnum == i) { + free_vc_found = 0; + break; /* found duplicate, try next vcnum */ + } + } + if (free_vc_found) + break; /* we found a vcnumber that will work - use it */ + } + + if (i == 0) + vcnum = 0; /* for most common case, ie if one smb session, use + vc zero. Also for case when no free vcnum, zero + is safest to send (some clients only send zero) */ + else if (free_vc_found == 0) + vcnum = 1; /* we can not reuse vc=0 safely, since some servers + reset all uids on that, but 1 is ok. */ + else + vcnum = i; + ses->vcnum = vcnum; +get_vc_num_exit: + write_unlock(&cifs_tcp_ses_lock); + + return le16_to_cpu(vcnum); +} + static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB) { __u32 capabilities = 0; /* init fields common to all four types of SessSetup */ - /* note that header is initialized to zero in header_assemble */ + /* Note that offsets for first seven fields in req struct are same */ + /* in CIFS Specs so does not matter which of 3 forms of struct */ + /* that we use in next few lines */ + /* Note that header is initialized to zero in header_assemble */ pSMB->req.AndXCommand = 0xFF; pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); + pSMB->req.VcNumber = get_next_vcnum(ses); /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */ @@ -71,7 +155,6 @@ static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB) if (ses->capabilities & CAP_UNIX) capabilities |= CAP_UNIX; - /* BB check whether to init vcnum BB */ return capabilities; } -- cgit From cc3ca22063784076bd240fda87217387a8f2ae92 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 20 Feb 2009 23:35:51 -0800 Subject: x86, mce: remove incorrect __cpuinit for mce_cpu_features() Impact: Bug fix on UP Checkin 6ec68bff3c81e776a455f6aca95c8c5f1d630198: x86, mce: reinitialize per cpu features on resume introduced a call to mce_cpu_features() in the resume path, in order for the MCE machinery to get properly reinitialized after a resume. However, this function (and its successors) was flagged __cpuinit, which becomes __init on UP configurations (on SMP suspend/resume requires CPU hotplug and so this would not be seen.) Remove the offending __cpuinit annotations for mce_cpu_features() and its successor functions. Cc: Andi Kleen Cc: Linus Torvalds Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/mcheck/mce_64.c | 2 +- arch/x86/kernel/cpu/mcheck/mce_amd_64.c | 2 +- arch/x86/kernel/cpu/mcheck/mce_intel_64.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index 25cf624eccb..fe79985ce0f 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -490,7 +490,7 @@ static void __cpuinit mce_cpu_quirks(struct cpuinfo_x86 *c) } -static void __cpuinit mce_cpu_features(struct cpuinfo_x86 *c) +static void mce_cpu_features(struct cpuinfo_x86 *c) { switch (c->x86_vendor) { case X86_VENDOR_INTEL: diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c index 8ae8c4ff094..f2ee0ae29bd 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c @@ -121,7 +121,7 @@ static long threshold_restart_bank(void *_tr) } /* cpu init entry point, called from mce.c with preempt off */ -void __cpuinit mce_amd_feature_init(struct cpuinfo_x86 *c) +void mce_amd_feature_init(struct cpuinfo_x86 *c) { unsigned int bank, block; unsigned int cpu = smp_processor_id(); diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c index 4b48f251fd3..f44c3662436 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c @@ -30,7 +30,7 @@ asmlinkage void smp_thermal_interrupt(void) irq_exit(); } -static void __cpuinit intel_init_thermal(struct cpuinfo_x86 *c) +static void intel_init_thermal(struct cpuinfo_x86 *c) { u32 l, h; int tm2 = 0; @@ -84,7 +84,7 @@ static void __cpuinit intel_init_thermal(struct cpuinfo_x86 *c) return; } -void __cpuinit mce_intel_feature_init(struct cpuinfo_x86 *c) +void mce_intel_feature_init(struct cpuinfo_x86 *c) { intel_init_thermal(c); } -- cgit From cae3aeb83fef5a7c9c8ac40e653e59dd9a35469c Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 21 Feb 2009 16:56:23 +0900 Subject: percpu: clean up size usage Andrew was concerned about the unit of variables named or have suffix size. Every usage in percpu allocator is in bytes but make it super clear by adding comments. While at it, make pcpu_depopulate_chunk() take int @off and @size like everyone else. Signed-off-by: Tejun Heo Cc: Andrew Morton --- mm/percpu.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/mm/percpu.c b/mm/percpu.c index 4617d97e877..997724c2ea2 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -119,7 +119,7 @@ static struct rb_root pcpu_addr_root = RB_ROOT; /* chunks by address */ static int pcpu_size_to_slot(int size) { - int highbit = fls(size); + int highbit = fls(size); /* size is in bytes */ return max(highbit - PCPU_SLOT_BASE_SHIFT + 2, 1); } @@ -158,8 +158,8 @@ static bool pcpu_chunk_page_occupied(struct pcpu_chunk *chunk, /** * pcpu_realloc - versatile realloc * @p: the current pointer (can be NULL for new allocations) - * @size: the current size (can be 0 for new allocations) - * @new_size: the wanted new size (can be 0 for free) + * @size: the current size in bytes (can be 0 for new allocations) + * @new_size: the wanted new size in bytes (can be 0 for free) * * More robust realloc which can be used to allocate, resize or free a * memory area of arbitrary size. If the needed size goes over @@ -290,8 +290,8 @@ static void pcpu_chunk_addr_insert(struct pcpu_chunk *new) * pcpu_split_block - split a map block * @chunk: chunk of interest * @i: index of map block to split - * @head: head size (can be 0) - * @tail: tail size (can be 0) + * @head: head size in bytes (can be 0) + * @tail: tail size in bytes (can be 0) * * Split the @i'th map block into two or three blocks. If @head is * non-zero, @head bytes block is inserted before block @i moving it @@ -346,7 +346,7 @@ static int pcpu_split_block(struct pcpu_chunk *chunk, int i, int head, int tail) /** * pcpu_alloc_area - allocate area from a pcpu_chunk * @chunk: chunk of interest - * @size: wanted size + * @size: wanted size in bytes * @align: wanted align * * Try to allocate @size bytes area aligned at @align from @chunk. @@ -540,15 +540,15 @@ static void pcpu_unmap(struct pcpu_chunk *chunk, int page_start, int page_end, * pcpu_depopulate_chunk - depopulate and unmap an area of a pcpu_chunk * @chunk: chunk to depopulate * @off: offset to the area to depopulate - * @size: size of the area to depopulate + * @size: size of the area to depopulate in bytes * @flush: whether to flush cache and tlb or not * * For each cpu, depopulate and unmap pages [@page_start,@page_end) * from @chunk. If @flush is true, vcache is flushed before unmapping * and tlb after. */ -static void pcpu_depopulate_chunk(struct pcpu_chunk *chunk, size_t off, - size_t size, bool flush) +static void pcpu_depopulate_chunk(struct pcpu_chunk *chunk, int off, int size, + bool flush) { int page_start = PFN_DOWN(off); int page_end = PFN_UP(off + size); @@ -617,7 +617,7 @@ static int pcpu_map(struct pcpu_chunk *chunk, int page_start, int page_end) * pcpu_populate_chunk - populate and map an area of a pcpu_chunk * @chunk: chunk of interest * @off: offset to the area to populate - * @size: size of the area to populate + * @size: size of the area to populate in bytes * * For each cpu, populate and map pages [@page_start,@page_end) into * @chunk. The area is cleared on return. @@ -707,7 +707,7 @@ static struct pcpu_chunk *alloc_pcpu_chunk(void) /** * __alloc_percpu - allocate percpu area - * @size: size of area to allocate + * @size: size of area to allocate in bytes * @align: alignment of area (max PAGE_SIZE) * * Allocate percpu area of @size bytes aligned at @align. Might @@ -819,6 +819,7 @@ EXPORT_SYMBOL_GPL(free_percpu); * pcpu_setup_static - initialize kernel static percpu area * @populate_pte_fn: callback to allocate pagetable * @pages: num_possible_cpus() * PFN_UP(cpu_size) pages + * @cpu_size: the size of static percpu area in bytes * * Initialize kernel static percpu area. The caller should allocate * all the necessary pages and pass them in @pages. -- cgit From 4c41bd0ec953954158f92bed5d3062645062b98e Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 16 Feb 2009 21:29:31 +0100 Subject: [JFFS2] fix mount crash caused by removed nodes At scan time we observed following scenario: node A inserted node B inserted node C inserted -> sets overlapped flag on node B node A is removed due to CRC failure -> overlapped flag on node B remains while (tn->overlapped) tn = tn_prev(tn); ==> crash, when tn_prev(B) is referenced. When the ultimate node is removed at scan time and the overlapped flag is set on the penultimate node, then nothing updates the overlapped flag of that node. The overlapped iterators blindly expect that the ultimate node does not have the overlapped flag set, which causes the scan code to crash. It would be a huge overhead to go through the node chain on node removal and fix up the overlapped flags, so detecting such a case on the fly in the overlapped iterators is a simpler and reliable solution. Cc: stable@kernel.org Signed-off-by: Thomas Gleixner Signed-off-by: David Woodhouse --- fs/jffs2/readinode.c | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index 6ca08ad887c..1fc1e92356e 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c @@ -220,7 +220,7 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info *tn) { uint32_t fn_end = tn->fn->ofs + tn->fn->size; - struct jffs2_tmp_dnode_info *this; + struct jffs2_tmp_dnode_info *this, *ptn; dbg_readinode("insert fragment %#04x-%#04x, ver %u at %08x\n", tn->fn->ofs, fn_end, tn->version, ref_offset(tn->fn->raw)); @@ -251,11 +251,18 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, if (this) { /* If the node is coincident with another at a lower address, back up until the other node is found. It may be relevant */ - while (this->overlapped) - this = tn_prev(this); - - /* First node should never be marked overlapped */ - BUG_ON(!this); + while (this->overlapped) { + ptn = tn_prev(this); + if (!ptn) { + /* + * We killed a node which set the overlapped + * flags during the scan. Fix it up. + */ + this->overlapped = 0; + break; + } + this = ptn; + } dbg_readinode("'this' found %#04x-%#04x (%s)\n", this->fn->ofs, this->fn->ofs + this->fn->size, this->fn ? "data" : "hole"); } @@ -360,7 +367,17 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, } if (!this->overlapped) break; - this = tn_prev(this); + + ptn = tn_prev(this); + if (!ptn) { + /* + * We killed a node which set the overlapped + * flags during the scan. Fix it up. + */ + this->overlapped = 0; + break; + } + this = ptn; } } @@ -456,8 +473,15 @@ static int jffs2_build_inode_fragtree(struct jffs2_sb_info *c, eat_last(&rii->tn_root, &last->rb); ver_insert(&ver_root, last); - if (unlikely(last->overlapped)) - continue; + if (unlikely(last->overlapped)) { + if (pen) + continue; + /* + * We killed a node which set the overlapped + * flags during the scan. Fix it up. + */ + last->overlapped = 0; + } /* Now we have a bunch of nodes in reverse version order, in the tree at ver_root. Most of the time, -- cgit From 05bf9e839d9de4e8a094274a0a2fd07beb47eaf1 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 21 Feb 2009 12:13:24 -0500 Subject: ext4: Add fallback for find_group_flex This is a workaround for find_group_flex() which badly needs to be replaced. One of its problems (besides ignoring the Orlov algorithm) is that it is a bit hyperactive about returning failure under suspicious circumstances. This can lead to spurious ENOSPC failures even when there are inodes still available. Work around this for now by retrying the search using find_group_other() if find_group_flex() returns -1. If find_group_other() succeeds when find_group_flex() has failed, log a warning message. A better block/inode allocator that will fix this problem for real has been queued up for the next merge window. Signed-off-by: "Theodore Ts'o" --- fs/ext4/ialloc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 4fb86a0061d..f18a919be70 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -715,6 +715,13 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) if (sbi->s_log_groups_per_flex) { ret2 = find_group_flex(sb, dir, &group); + if (ret2 == -1) { + ret2 = find_group_other(sb, dir, &group); + if (ret2 == 0 && printk_ratelimit()) + printk(KERN_NOTICE "ext4: find_group_flex " + "failed, fallback succeeded dir %lu\n", + dir->i_ino); + } goto got_group; } -- cgit From 5423a0cb3f74c16e90683f8ee1cec6c240a9556e Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Sat, 21 Feb 2009 12:18:13 -0500 Subject: ACPI: EC: Add delay for slow MSI controller http://bugzilla.kernel.org/show_bug.cgi?id=12011 Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/ec.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 5c2f5d343be..2fe15060dcd 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -120,6 +120,8 @@ static struct acpi_ec { spinlock_t curr_lock; } *boot_ec, *first_ec; +static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ + /* -------------------------------------------------------------------------- Transaction Management -------------------------------------------------------------------------- */ @@ -259,6 +261,8 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); acpi_disable_gpe(NULL, ec->gpe); } + if (EC_FLAGS_MSI) + udelay(ACPI_EC_DELAY); /* start transaction */ spin_lock_irqsave(&ec->curr_lock, tmp); /* following two actions should be kept atomic */ @@ -967,6 +971,11 @@ int __init acpi_ec_ecdt_probe(void) /* * Generate a boot ec context */ + if (dmi_name_in_vendors("Micro-Star") || + dmi_name_in_vendors("Notebook")) { + pr_info(PREFIX "Enabling special treatment for EC from MSI.\n"); + EC_FLAGS_MSI = 1; + } status = acpi_get_table(ACPI_SIG_ECDT, 1, (struct acpi_table_header **)&ecdt_ptr); if (ACPI_SUCCESS(status)) { -- cgit From 56f382a08722186623400180adbb9d1be1721cee Mon Sep 17 00:00:00 2001 From: Richard Hughes Date: Sun, 25 Jan 2009 15:05:50 +0000 Subject: battery: don't assume we are fully charged when not charging or discharging On hardware like the T61 it can take a couple of seconds for the battery to start charging after the power is connected, and we incorrectly tell userspace that we are fully charged, and then go back to charging. Only mark a battery as fully charged when the preset charge matches either the last full charge, or the design charge. http://bugzilla.kernel.org/show_bug.cgi?id=12632 Signed-off-by: Richard Hughes Acked-by: Alexey Starikovskiy Acked-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- drivers/acpi/battery.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 65132f92045..69cbc57c2d1 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -138,6 +138,29 @@ static int acpi_battery_technology(struct acpi_battery *battery) static int acpi_battery_get_state(struct acpi_battery *battery); +static int acpi_battery_is_charged(struct acpi_battery *battery) +{ + /* either charging or discharging */ + if (battery->state != 0) + return 0; + + /* battery not reporting charge */ + if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN || + battery->capacity_now == 0) + return 0; + + /* good batteries update full_charge as the batteries degrade */ + if (battery->full_charge_capacity == battery->capacity_now) + return 1; + + /* fallback to using design values for broken batteries */ + if (battery->design_capacity == battery->capacity_now) + return 1; + + /* we don't do any sort of metric based on percentages */ + return 0; +} + static int acpi_battery_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) @@ -155,7 +178,7 @@ static int acpi_battery_get_property(struct power_supply *psy, val->intval = POWER_SUPPLY_STATUS_DISCHARGING; else if (battery->state & 0x02) val->intval = POWER_SUPPLY_STATUS_CHARGING; - else if (battery->state == 0) + else if (acpi_battery_is_charged(battery)) val->intval = POWER_SUPPLY_STATUS_FULL; else val->intval = POWER_SUPPLY_STATUS_UNKNOWN; -- cgit From 216773a787c3c46ef26bf1742c1fdba37d26be45 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Sat, 14 Feb 2009 01:59:06 +0100 Subject: Consolidate driver_probe_done() loops into one place there's a few places that currently loop over driver_probe_done(), and I'm about to add another one. This patch abstracts it into a helper to reduce duplication. Signed-off-by: Arjan van de Ven Signed-off-by: Rafael J. Wysocki Cc: Len Brown Acked-by: Greg KH Signed-off-by: Linus Torvalds --- drivers/base/dd.c | 17 +++++++++++++++++ include/linux/device.h | 2 ++ init/do_mounts.c | 13 +++++++++---- init/do_mounts_md.c | 5 +++-- 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 315bed8d5e7..13523123910 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -18,9 +18,11 @@ */ #include +#include #include #include #include +#include #include "base.h" #include "power/power.h" @@ -167,6 +169,21 @@ int driver_probe_done(void) return 0; } +/** + * wait_for_device_probe + * Wait for device probing to be completed. + * + * Note: this function polls at 100 msec intervals. + */ +int wait_for_device_probe(void) +{ + /* wait for the known devices to complete their probing */ + while (driver_probe_done() != 0) + msleep(100); + async_synchronize_full(); + return 0; +} + /** * driver_probe_device - attempt to bind device & driver together * @drv: driver to bind a device to diff --git a/include/linux/device.h b/include/linux/device.h index 45e5b1921fb..47f343c7bdd 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -147,6 +147,8 @@ extern void put_driver(struct device_driver *drv); extern struct device_driver *driver_find(const char *name, struct bus_type *bus); extern int driver_probe_done(void); +extern int wait_for_device_probe(void); + /* sysfs interface for exporting driver attributes */ diff --git a/init/do_mounts.c b/init/do_mounts.c index 708105e163d..8d4ff5afc1d 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -370,10 +370,14 @@ void __init prepare_namespace(void) ssleep(root_delay); } - /* wait for the known devices to complete their probing */ - while (driver_probe_done() != 0) - msleep(100); - async_synchronize_full(); + /* + * wait for the known devices to complete their probing + * + * Note: this is a potential source of long boot delays. + * For example, it is not atypical to wait 5 seconds here + * for the touchpad of a laptop to initialize. + */ + wait_for_device_probe(); md_run_setup(); @@ -399,6 +403,7 @@ void __init prepare_namespace(void) while (driver_probe_done() != 0 || (ROOT_DEV = name_to_dev_t(saved_root_name)) == 0) msleep(100); + async_synchronize_full(); } is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR; diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c index ff95e319288..9bdddbcb3d6 100644 --- a/init/do_mounts_md.c +++ b/init/do_mounts_md.c @@ -281,8 +281,9 @@ static void __init autodetect_raid(void) */ printk(KERN_INFO "md: Waiting for all devices to be available before autodetect\n"); printk(KERN_INFO "md: If you don't use raid, use raid=noautodetect\n"); - while (driver_probe_done() < 0) - msleep(100); + + wait_for_device_probe(); + fd = sys_open("/dev/md0", 0, 0); if (fd >= 0) { sys_ioctl(fd, RAID_AUTORUN, raid_autopart); -- cgit From eed3ee08292d821282169708e5e8e89a0d0a0c63 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Sat, 14 Feb 2009 02:00:19 +0100 Subject: PM/resume: wait for device probing to finish the resume code does not currently wait for device probing to finish. Even without async function calls this is dicey and not correct, but with async function calls during the boot sequence this is going to get hit more... This patch adds the synchronization using the newly introduced helper. Signed-off-by: Arjan van de Ven Signed-off-by: Rafael J. Wysocki Cc: Len Brown Acked-by: Greg KH Signed-off-by: Linus Torvalds --- kernel/power/disk.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/kernel/power/disk.c b/kernel/power/disk.c index 432ee575c9e..7b40e94b1d4 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c @@ -594,6 +594,12 @@ static int software_resume(void) int error; unsigned int flags; + /* + * If the user said "noresume".. bail out early. + */ + if (noresume) + return 0; + /* * name_to_dev_t() below takes a sysfs buffer mutex when sysfs * is configured into the kernel. Since the regular hibernate @@ -610,6 +616,11 @@ static int software_resume(void) mutex_unlock(&pm_mutex); return -ENOENT; } + /* + * Some device discovery might still be in progress; we need + * to wait for this to finish. + */ + wait_for_device_probe(); swsusp_resume_device = name_to_dev_t(resume_file); pr_debug("PM: Resume from partition %s\n", resume_file); } else { -- cgit From a1bb7d61233ba5fb5cd865f907a9ddcc8f8c02bd Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Sat, 14 Feb 2009 02:01:14 +0100 Subject: PM/hibernate: fix "swap breaks after hibernation failures" http://bugzilla.kernel.org/show_bug.cgi?id=12239 The image writing code dropped a reference to the current swap device. This doesn't show up if the hibernation succeeds - because it doesn't affect the image which gets resumed. But it means multiple _failed_ hibernations end up freeing the swap device while it is still use! swsusp_write() finds the block device for the swap file using swap_type_of(). It then uses blkdev_get() / blkdev_put() to open and close the block device. Unfortunately, blkdev_get() assumes ownership of the inode of the block_device passed to it. So blkdev_put() calls iput() on the inode. This is by design and other callers expect this behaviour. The fix is for swap_type_of() to take a reference on the inode using bdget(). Signed-off-by: Alan Jenkins Signed-off-by: Rafael J. Wysocki Cc: Len Brown Cc: Greg KH Signed-off-by: Linus Torvalds --- mm/swapfile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm/swapfile.c b/mm/swapfile.c index 7e6304dfafa..312fafe0ab6 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -635,7 +635,7 @@ int swap_type_of(dev_t device, sector_t offset, struct block_device **bdev_p) if (!bdev) { if (bdev_p) - *bdev_p = sis->bdev; + *bdev_p = bdget(sis->bdev->bd_dev); spin_unlock(&swap_lock); return i; @@ -647,7 +647,7 @@ int swap_type_of(dev_t device, sector_t offset, struct block_device **bdev_p) struct swap_extent, list); if (se->start_block == offset) { if (bdev_p) - *bdev_p = sis->bdev; + *bdev_p = bdget(sis->bdev->bd_dev); spin_unlock(&swap_lock); bdput(bdev); -- cgit From 09664fda48c5dd63277f1f42888ca9d5dca6037a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 14 Feb 2009 02:02:16 +0100 Subject: PM: fix build for CONFIG_PM unset Compilation of kprobes.c with CONFIG_PM unset is broken due to some broken config dependncies. Fix that. Signed-off-by: Rafael J. Wysocki Cc: Len Brown Cc: Greg KH Reported-by: Ingo Molnar Tested-by: Masami Hiramatsu Signed-off-by: Linus Torvalds --- kernel/Makefile | 1 + kernel/power/Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/Makefile b/kernel/Makefile index 170a9213c1b..e4791b3ba55 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -51,6 +51,7 @@ obj-$(CONFIG_UID16) += uid16.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_KALLSYMS) += kallsyms.o obj-$(CONFIG_PM) += power/ +obj-$(CONFIG_FREEZER) += power/ obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o obj-$(CONFIG_KEXEC) += kexec.o obj-$(CONFIG_BACKTRACE_SELF_TEST) += backtracetest.o diff --git a/kernel/power/Makefile b/kernel/power/Makefile index d7a10167a25..720ea4f781b 100644 --- a/kernel/power/Makefile +++ b/kernel/power/Makefile @@ -3,7 +3,7 @@ ifeq ($(CONFIG_PM_DEBUG),y) EXTRA_CFLAGS += -DDEBUG endif -obj-y := main.o +obj-$(CONFIG_PM) += main.o obj-$(CONFIG_PM_SLEEP) += console.o obj-$(CONFIG_FREEZER) += process.o obj-$(CONFIG_HIBERNATION) += swsusp.o disk.o snapshot.o swap.o user.o -- cgit From 3049103ddfc9aac111916bd2f39ac6976c431517 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Sat, 14 Feb 2009 02:03:08 +0100 Subject: swsusp: dont fiddle with swappiness sc.swappiness is not used in the swsusp memory shrinking path, do not set it. Signed-off-by: Johannes Weiner Reviewed-by: KOSAKI Motohiro Signed-off-by: Rafael J. Wysocki Cc: Len Brown Cc: Greg KH Signed-off-by: Linus Torvalds --- mm/vmscan.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 9a27c44aa32..550e8695070 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -2112,7 +2112,6 @@ unsigned long shrink_all_memory(unsigned long nr_pages) .may_swap = 0, .swap_cluster_max = nr_pages, .may_writepage = 1, - .swappiness = vm_swappiness, .isolate_pages = isolate_pages_global, }; @@ -2146,10 +2145,8 @@ unsigned long shrink_all_memory(unsigned long nr_pages) int prio; /* Force reclaiming mapped pages in the passes #3 and #4 */ - if (pass > 2) { + if (pass > 2) sc.may_swap = 1; - sc.swappiness = 100; - } for (prio = DEF_PRIORITY; prio >= 0; prio--) { unsigned long nr_to_scan = nr_pages - ret; -- cgit From 0cb57258fe01e9b21076b6a15b6aec7a24168228 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Sat, 14 Feb 2009 02:04:10 +0100 Subject: swsusp: clean up shrink_all_zones() Move local variables to innermost possible scopes and use local variables to cache calculations/reads done more than once. No change in functionality (intended). Signed-off-by: Johannes Weiner Reviewed-by: KOSAKI Motohiro Signed-off-by: Rafael J. Wysocki Cc: Len Brown Cc: Greg KH Acked-by: Pavel Machek Signed-off-by: Linus Torvalds --- mm/vmscan.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 550e8695070..6177e3bcd66 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -2057,31 +2057,31 @@ static unsigned long shrink_all_zones(unsigned long nr_pages, int prio, int pass, struct scan_control *sc) { struct zone *zone; - unsigned long nr_to_scan, ret = 0; - enum lru_list l; + unsigned long ret = 0; for_each_zone(zone) { + enum lru_list l; if (!populated_zone(zone)) continue; - if (zone_is_all_unreclaimable(zone) && prio != DEF_PRIORITY) continue; for_each_evictable_lru(l) { + enum zone_stat_item ls = NR_LRU_BASE + l; + unsigned long lru_pages = zone_page_state(zone, ls); + /* For pass = 0, we don't shrink the active list */ - if (pass == 0 && - (l == LRU_ACTIVE || l == LRU_ACTIVE_FILE)) + if (pass == 0 && (l == LRU_ACTIVE_ANON || + l == LRU_ACTIVE_FILE)) continue; - zone->lru[l].nr_scan += - (zone_page_state(zone, NR_LRU_BASE + l) - >> prio) + 1; + zone->lru[l].nr_scan += (lru_pages >> prio) + 1; if (zone->lru[l].nr_scan >= nr_pages || pass > 3) { + unsigned long nr_to_scan; + zone->lru[l].nr_scan = 0; - nr_to_scan = min(nr_pages, - zone_page_state(zone, - NR_LRU_BASE + l)); + nr_to_scan = min(nr_pages, lru_pages); ret += shrink_list(l, nr_to_scan, zone, sc, prio); if (ret >= nr_pages) @@ -2089,7 +2089,6 @@ static unsigned long shrink_all_zones(unsigned long nr_pages, int prio, } } } - return ret; } -- cgit From ebae2604f2c3693717d9dc687c84578f0526480c Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Sat, 14 Feb 2009 02:05:14 +0100 Subject: PM: Fix pm_notifiers during user mode hibernation Snapshot device is opened with O_RDONLY during suspend and O_WRONLY durig resume. Make sure we also call notifiers with correct parameter telling them what we are really doing. Signed-off-by: Andrey Borzenkov Signed-off-by: Rafael J. Wysocki Cc: Len Brown Cc: Greg KH Acked-by: Pavel Machek Signed-off-by: Linus Torvalds --- kernel/power/user.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/power/user.c b/kernel/power/user.c index 005b93d839b..6c85359364f 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c @@ -95,15 +95,15 @@ static int snapshot_open(struct inode *inode, struct file *filp) data->swap = swsusp_resume_device ? swap_type_of(swsusp_resume_device, 0, NULL) : -1; data->mode = O_RDONLY; - error = pm_notifier_call_chain(PM_RESTORE_PREPARE); + error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE); if (error) - pm_notifier_call_chain(PM_POST_RESTORE); + pm_notifier_call_chain(PM_POST_HIBERNATION); } else { data->swap = -1; data->mode = O_WRONLY; - error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE); + error = pm_notifier_call_chain(PM_RESTORE_PREPARE); if (error) - pm_notifier_call_chain(PM_POST_HIBERNATION); + pm_notifier_call_chain(PM_POST_RESTORE); } if (error) atomic_inc(&snapshot_device_available); -- cgit From b090f9fa53d51c8a33370071de9e391919ee1fa7 Mon Sep 17 00:00:00 2001 From: Arve Hjønnevåg Date: Sat, 14 Feb 2009 02:06:17 +0100 Subject: PM: Wait for console in resume MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoids later waking up to a blinking cursor if the device woke up and returned to sleep before the console switch happened. Signed-off-by: Brian Swetland Signed-off-by: Arve Hjønnevåg Signed-off-by: Rafael J. Wysocki Cc: Len Brown Cc: Greg KH Signed-off-by: Linus Torvalds --- kernel/power/console.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kernel/power/console.c b/kernel/power/console.c index b8628be2a46..a3961b205de 100644 --- a/kernel/power/console.c +++ b/kernel/power/console.c @@ -78,6 +78,12 @@ void pm_restore_console(void) } set_console(orig_fgconsole); release_console_sem(); + + if (vt_waitactive(orig_fgconsole)) { + pr_debug("Resume: Can't switch VCs."); + return; + } + kmsg_redirect = orig_kmsg; } #endif -- cgit From 403f307576396f3362fbb65af190885b6036c72c Mon Sep 17 00:00:00 2001 From: Arve Hjønnevåg Date: Sat, 14 Feb 2009 02:07:24 +0100 Subject: PM: Fix suspend_console and resume_console to use only one semaphore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a race where a thread acquires the console while the console is suspended, and the console is resumed before this thread releases it. In this case, the secondary console semaphore would be left locked, and the primary semaphore would be released twice. This in turn would cause the console switch on suspend or resume to hang forever. Note that suspend_console does not actually lock the console for clients that use acquire_console_sem, it only locks it for clients that use try_acquire_console_sem. If we change suspend_console to fully lock the console, then the kernel may deadlock on suspend. One client of try_acquire_console_sem is acquire_console_semaphore_for_printk, which uses it to prevent printk from using the console while it is suspended. Signed-off-by: Arve Hjønnevåg Signed-off-by: Rafael J. Wysocki Cc: Len Brown Cc: Greg KH Signed-off-by: Linus Torvalds --- kernel/printk.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/kernel/printk.c b/kernel/printk.c index 69188f226a9..e3602d0755b 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -73,7 +73,6 @@ EXPORT_SYMBOL(oops_in_progress); * driver system. */ static DECLARE_MUTEX(console_sem); -static DECLARE_MUTEX(secondary_console_sem); struct console *console_drivers; EXPORT_SYMBOL_GPL(console_drivers); @@ -891,12 +890,14 @@ void suspend_console(void) printk("Suspending console(s) (use no_console_suspend to debug)\n"); acquire_console_sem(); console_suspended = 1; + up(&console_sem); } void resume_console(void) { if (!console_suspend_enabled) return; + down(&console_sem); console_suspended = 0; release_console_sem(); } @@ -912,11 +913,9 @@ void resume_console(void) void acquire_console_sem(void) { BUG_ON(in_interrupt()); - if (console_suspended) { - down(&secondary_console_sem); - return; - } down(&console_sem); + if (console_suspended) + return; console_locked = 1; console_may_schedule = 1; } @@ -926,6 +925,10 @@ int try_acquire_console_sem(void) { if (down_trylock(&console_sem)) return -1; + if (console_suspended) { + up(&console_sem); + return -1; + } console_locked = 1; console_may_schedule = 0; return 0; @@ -979,7 +982,7 @@ void release_console_sem(void) unsigned wake_klogd = 0; if (console_suspended) { - up(&secondary_console_sem); + up(&console_sem); return; } -- cgit From b73a77494292b930642fbf87de3e3196593f7593 Mon Sep 17 00:00:00 2001 From: HighPoint Linux Team Date: Thu, 12 Feb 2009 11:28:31 +0800 Subject: [SCSI] hptiop: Add new PCI device ID Signed-off-by: HighPoint Linux Team Signed-off-by: James Bottomley --- drivers/scsi/hptiop.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c index a48e4990fe1..34be88d7afa 100644 --- a/drivers/scsi/hptiop.c +++ b/drivers/scsi/hptiop.c @@ -1251,6 +1251,7 @@ static struct pci_device_id hptiop_id_table[] = { { PCI_VDEVICE(TTI, 0x3530), (kernel_ulong_t)&hptiop_itl_ops }, { PCI_VDEVICE(TTI, 0x3560), (kernel_ulong_t)&hptiop_itl_ops }, { PCI_VDEVICE(TTI, 0x4322), (kernel_ulong_t)&hptiop_itl_ops }, + { PCI_VDEVICE(TTI, 0x4321), (kernel_ulong_t)&hptiop_itl_ops }, { PCI_VDEVICE(TTI, 0x4210), (kernel_ulong_t)&hptiop_itl_ops }, { PCI_VDEVICE(TTI, 0x4211), (kernel_ulong_t)&hptiop_itl_ops }, { PCI_VDEVICE(TTI, 0x4310), (kernel_ulong_t)&hptiop_itl_ops }, -- cgit From 1648b11ea7cec5b95e5a71364ac1f40bfef702d0 Mon Sep 17 00:00:00 2001 From: Karen Xie Date: Fri, 13 Feb 2009 21:38:44 -0800 Subject: [SCSI] cxgb3i: transmit work-request fixes - resize the work-request credit array to be based on skb's MAX_SKB_FRAGS. - split the skb cb into tx and rx portion - increase the default transmit window to 128K. - stop queueing up the outgoing pdus if transmit window is full. Signed-off-by: Karen Xie Reviewed-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/cxgb3i/cxgb3i_offload.c | 146 ++++++++++++++++++++++++----------- drivers/scsi/cxgb3i/cxgb3i_offload.h | 28 ++++--- 2 files changed, 121 insertions(+), 53 deletions(-) diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.c b/drivers/scsi/cxgb3i/cxgb3i_offload.c index a865f1fefe8..de3b3b614cc 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_offload.c +++ b/drivers/scsi/cxgb3i/cxgb3i_offload.c @@ -23,19 +23,19 @@ #include "cxgb3i_ddp.h" #ifdef __DEBUG_C3CN_CONN__ -#define c3cn_conn_debug cxgb3i_log_info +#define c3cn_conn_debug cxgb3i_log_debug #else #define c3cn_conn_debug(fmt...) #endif #ifdef __DEBUG_C3CN_TX__ -#define c3cn_tx_debug cxgb3i_log_debug +#define c3cn_tx_debug cxgb3i_log_debug #else #define c3cn_tx_debug(fmt...) #endif #ifdef __DEBUG_C3CN_RX__ -#define c3cn_rx_debug cxgb3i_log_debug +#define c3cn_rx_debug cxgb3i_log_debug #else #define c3cn_rx_debug(fmt...) #endif @@ -47,9 +47,9 @@ static int cxgb3_rcv_win = 256 * 1024; module_param(cxgb3_rcv_win, int, 0644); MODULE_PARM_DESC(cxgb3_rcv_win, "TCP receive window in bytes (default=256KB)"); -static int cxgb3_snd_win = 64 * 1024; +static int cxgb3_snd_win = 128 * 1024; module_param(cxgb3_snd_win, int, 0644); -MODULE_PARM_DESC(cxgb3_snd_win, "TCP send window in bytes (default=64KB)"); +MODULE_PARM_DESC(cxgb3_snd_win, "TCP send window in bytes (default=128KB)"); static int cxgb3_rx_credit_thres = 10 * 1024; module_param(cxgb3_rx_credit_thres, int, 0644); @@ -301,8 +301,8 @@ static void act_open_req_arp_failure(struct t3cdev *dev, struct sk_buff *skb) static void skb_entail(struct s3_conn *c3cn, struct sk_buff *skb, int flags) { - CXGB3_SKB_CB(skb)->seq = c3cn->write_seq; - CXGB3_SKB_CB(skb)->flags = flags; + skb_tcp_seq(skb) = c3cn->write_seq; + skb_flags(skb) = flags; __skb_queue_tail(&c3cn->write_queue, skb); } @@ -457,12 +457,9 @@ static unsigned int wrlen __read_mostly; * The number of WRs needed for an skb depends on the number of fragments * in the skb and whether it has any payload in its main body. This maps the * length of the gather list represented by an skb into the # of necessary WRs. - * - * The max. length of an skb is controlled by the max pdu size which is ~16K. - * Also, assume the min. fragment length is the sector size (512), then add - * extra fragment counts for iscsi bhs and payload padding. + * The extra two fragments are for iscsi bhs and payload padding. */ -#define SKB_WR_LIST_SIZE (16384/512 + 3) +#define SKB_WR_LIST_SIZE (MAX_SKB_FRAGS + 2) static unsigned int skb_wrs[SKB_WR_LIST_SIZE] __read_mostly; static void s3_init_wr_tab(unsigned int wr_len) @@ -485,7 +482,7 @@ static void s3_init_wr_tab(unsigned int wr_len) static inline void reset_wr_list(struct s3_conn *c3cn) { - c3cn->wr_pending_head = NULL; + c3cn->wr_pending_head = c3cn->wr_pending_tail = NULL; } /* @@ -496,7 +493,7 @@ static inline void reset_wr_list(struct s3_conn *c3cn) static inline void enqueue_wr(struct s3_conn *c3cn, struct sk_buff *skb) { - skb_wr_data(skb) = NULL; + skb_tx_wr_next(skb) = NULL; /* * We want to take an extra reference since both us and the driver @@ -509,10 +506,22 @@ static inline void enqueue_wr(struct s3_conn *c3cn, if (!c3cn->wr_pending_head) c3cn->wr_pending_head = skb; else - skb_wr_data(skb) = skb; + skb_tx_wr_next(c3cn->wr_pending_tail) = skb; c3cn->wr_pending_tail = skb; } +static int count_pending_wrs(struct s3_conn *c3cn) +{ + int n = 0; + const struct sk_buff *skb = c3cn->wr_pending_head; + + while (skb) { + n += skb->csum; + skb = skb_tx_wr_next(skb); + } + return n; +} + static inline struct sk_buff *peek_wr(const struct s3_conn *c3cn) { return c3cn->wr_pending_head; @@ -529,8 +538,8 @@ static inline struct sk_buff *dequeue_wr(struct s3_conn *c3cn) if (likely(skb)) { /* Don't bother clearing the tail */ - c3cn->wr_pending_head = skb_wr_data(skb); - skb_wr_data(skb) = NULL; + c3cn->wr_pending_head = skb_tx_wr_next(skb); + skb_tx_wr_next(skb) = NULL; } return skb; } @@ -543,13 +552,14 @@ static void purge_wr_queue(struct s3_conn *c3cn) } static inline void make_tx_data_wr(struct s3_conn *c3cn, struct sk_buff *skb, - int len) + int len, int req_completion) { struct tx_data_wr *req; skb_reset_transport_header(skb); req = (struct tx_data_wr *)__skb_push(skb, sizeof(*req)); - req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)); + req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA) | + (req_completion ? F_WR_COMPL : 0)); req->wr_lo = htonl(V_WR_TID(c3cn->tid)); req->sndseq = htonl(c3cn->snd_nxt); /* len includes the length of any HW ULP additions */ @@ -592,7 +602,7 @@ static int c3cn_push_tx_frames(struct s3_conn *c3cn, int req_completion) if (unlikely(c3cn->state == C3CN_STATE_CONNECTING || c3cn->state == C3CN_STATE_CLOSE_WAIT_1 || - c3cn->state == C3CN_STATE_ABORTING)) { + c3cn->state >= C3CN_STATE_ABORTING)) { c3cn_tx_debug("c3cn 0x%p, in closing state %u.\n", c3cn, c3cn->state); return 0; @@ -615,7 +625,7 @@ static int c3cn_push_tx_frames(struct s3_conn *c3cn, int req_completion) if (c3cn->wr_avail < wrs_needed) { c3cn_tx_debug("c3cn 0x%p, skb len %u/%u, frag %u, " "wr %d < %u.\n", - c3cn, skb->len, skb->datalen, frags, + c3cn, skb->len, skb->data_len, frags, wrs_needed, c3cn->wr_avail); break; } @@ -627,20 +637,24 @@ static int c3cn_push_tx_frames(struct s3_conn *c3cn, int req_completion) c3cn->wr_unacked += wrs_needed; enqueue_wr(c3cn, skb); - if (likely(CXGB3_SKB_CB(skb)->flags & C3CB_FLAG_NEED_HDR)) { - len += ulp_extra_len(skb); - make_tx_data_wr(c3cn, skb, len); - c3cn->snd_nxt += len; - if ((req_completion - && c3cn->wr_unacked == wrs_needed) - || (CXGB3_SKB_CB(skb)->flags & C3CB_FLAG_COMPL) - || c3cn->wr_unacked >= c3cn->wr_max / 2) { - struct work_request_hdr *wr = cplhdr(skb); + c3cn_tx_debug("c3cn 0x%p, enqueue, skb len %u/%u, frag %u, " + "wr %d, left %u, unack %u.\n", + c3cn, skb->len, skb->data_len, frags, + wrs_needed, c3cn->wr_avail, c3cn->wr_unacked); + - wr->wr_hi |= htonl(F_WR_COMPL); + if (likely(skb_flags(skb) & C3CB_FLAG_NEED_HDR)) { + if ((req_completion && + c3cn->wr_unacked == wrs_needed) || + (skb_flags(skb) & C3CB_FLAG_COMPL) || + c3cn->wr_unacked >= c3cn->wr_max / 2) { + req_completion = 1; c3cn->wr_unacked = 0; } - CXGB3_SKB_CB(skb)->flags &= ~C3CB_FLAG_NEED_HDR; + len += ulp_extra_len(skb); + make_tx_data_wr(c3cn, skb, len, req_completion); + c3cn->snd_nxt += len; + skb_flags(skb) &= ~C3CB_FLAG_NEED_HDR; } total_size += skb->truesize; @@ -735,8 +749,11 @@ static void process_act_establish(struct s3_conn *c3cn, struct sk_buff *skb) if (unlikely(c3cn_flag(c3cn, C3CN_ACTIVE_CLOSE_NEEDED))) /* upper layer has requested closing */ send_abort_req(c3cn); - else if (c3cn_push_tx_frames(c3cn, 1)) + else { + if (skb_queue_len(&c3cn->write_queue)) + c3cn_push_tx_frames(c3cn, 1); cxgb3i_conn_tx_open(c3cn); + } } static int do_act_establish(struct t3cdev *cdev, struct sk_buff *skb, @@ -1082,8 +1099,8 @@ static void process_rx_iscsi_hdr(struct s3_conn *c3cn, struct sk_buff *skb) return; } - CXGB3_SKB_CB(skb)->seq = ntohl(hdr_cpl->seq); - CXGB3_SKB_CB(skb)->flags = 0; + skb_tcp_seq(skb) = ntohl(hdr_cpl->seq); + skb_flags(skb) = 0; skb_reset_transport_header(skb); __skb_pull(skb, sizeof(struct cpl_iscsi_hdr)); @@ -1103,12 +1120,12 @@ static void process_rx_iscsi_hdr(struct s3_conn *c3cn, struct sk_buff *skb) goto abort_conn; skb_ulp_mode(skb) = ULP2_FLAG_DATA_READY; - skb_ulp_pdulen(skb) = ntohs(ddp_cpl.len); - skb_ulp_ddigest(skb) = ntohl(ddp_cpl.ulp_crc); + skb_rx_pdulen(skb) = ntohs(ddp_cpl.len); + skb_rx_ddigest(skb) = ntohl(ddp_cpl.ulp_crc); status = ntohl(ddp_cpl.ddp_status); c3cn_rx_debug("rx skb 0x%p, len %u, pdulen %u, ddp status 0x%x.\n", - skb, skb->len, skb_ulp_pdulen(skb), status); + skb, skb->len, skb_rx_pdulen(skb), status); if (status & (1 << RX_DDP_STATUS_HCRC_SHIFT)) skb_ulp_mode(skb) |= ULP2_FLAG_HCRC_ERROR; @@ -1126,7 +1143,7 @@ static void process_rx_iscsi_hdr(struct s3_conn *c3cn, struct sk_buff *skb) } else if (status & (1 << RX_DDP_STATUS_DDP_SHIFT)) skb_ulp_mode(skb) |= ULP2_FLAG_DATA_DDPED; - c3cn->rcv_nxt = ntohl(ddp_cpl.seq) + skb_ulp_pdulen(skb); + c3cn->rcv_nxt = ntohl(ddp_cpl.seq) + skb_rx_pdulen(skb); __pskb_trim(skb, len); __skb_queue_tail(&c3cn->receive_queue, skb); cxgb3i_conn_pdu_ready(c3cn); @@ -1151,12 +1168,27 @@ static int do_iscsi_hdr(struct t3cdev *t3dev, struct sk_buff *skb, void *ctx) * Process an acknowledgment of WR completion. Advance snd_una and send the * next batch of work requests from the write queue. */ +static void check_wr_invariants(struct s3_conn *c3cn) +{ + int pending = count_pending_wrs(c3cn); + + if (unlikely(c3cn->wr_avail + pending != c3cn->wr_max)) + cxgb3i_log_error("TID %u: credit imbalance: avail %u, " + "pending %u, total should be %u\n", + c3cn->tid, c3cn->wr_avail, pending, + c3cn->wr_max); +} + static void process_wr_ack(struct s3_conn *c3cn, struct sk_buff *skb) { struct cpl_wr_ack *hdr = cplhdr(skb); unsigned int credits = ntohs(hdr->credits); u32 snd_una = ntohl(hdr->snd_una); + c3cn_tx_debug("%u WR credits, avail %u, unack %u, TID %u, state %u.\n", + credits, c3cn->wr_avail, c3cn->wr_unacked, + c3cn->tid, c3cn->state); + c3cn->wr_avail += credits; if (c3cn->wr_unacked > c3cn->wr_max - c3cn->wr_avail) c3cn->wr_unacked = c3cn->wr_max - c3cn->wr_avail; @@ -1171,6 +1203,17 @@ static void process_wr_ack(struct s3_conn *c3cn, struct sk_buff *skb) break; } if (unlikely(credits < p->csum)) { + struct tx_data_wr *w = cplhdr(p); + cxgb3i_log_error("TID %u got %u WR credits need %u, " + "len %u, main body %u, frags %u, " + "seq # %u, ACK una %u, ACK nxt %u, " + "WR_AVAIL %u, WRs pending %u\n", + c3cn->tid, credits, p->csum, p->len, + p->len - p->data_len, + skb_shinfo(p)->nr_frags, + ntohl(w->sndseq), snd_una, + ntohl(hdr->snd_nxt), c3cn->wr_avail, + count_pending_wrs(c3cn) - credits); p->csum -= credits; break; } else { @@ -1180,15 +1223,24 @@ static void process_wr_ack(struct s3_conn *c3cn, struct sk_buff *skb) } } - if (unlikely(before(snd_una, c3cn->snd_una))) + check_wr_invariants(c3cn); + + if (unlikely(before(snd_una, c3cn->snd_una))) { + cxgb3i_log_error("TID %u, unexpected sequence # %u in WR_ACK " + "snd_una %u\n", + c3cn->tid, snd_una, c3cn->snd_una); goto out_free; + } if (c3cn->snd_una != snd_una) { c3cn->snd_una = snd_una; dst_confirm(c3cn->dst_cache); } - if (skb_queue_len(&c3cn->write_queue) && c3cn_push_tx_frames(c3cn, 0)) + if (skb_queue_len(&c3cn->write_queue)) { + if (c3cn_push_tx_frames(c3cn, 0)) + cxgb3i_conn_tx_open(c3cn); + } else cxgb3i_conn_tx_open(c3cn); out_free: __kfree_skb(skb); @@ -1452,7 +1504,7 @@ static void init_offload_conn(struct s3_conn *c3cn, struct dst_entry *dst) { BUG_ON(c3cn->cdev != cdev); - c3cn->wr_max = c3cn->wr_avail = T3C_DATA(cdev)->max_wrs; + c3cn->wr_max = c3cn->wr_avail = T3C_DATA(cdev)->max_wrs - 1; c3cn->wr_unacked = 0; c3cn->mss_idx = select_mss(c3cn, dst_mtu(dst)); @@ -1671,9 +1723,17 @@ int cxgb3i_c3cn_send_pdus(struct s3_conn *c3cn, struct sk_buff *skb) goto out_err; } - err = -EPIPE; if (c3cn->err) { c3cn_tx_debug("c3cn 0x%p, err %d.\n", c3cn, c3cn->err); + err = -EPIPE; + goto out_err; + } + + if (c3cn->write_seq - c3cn->snd_una >= cxgb3_snd_win) { + c3cn_tx_debug("c3cn 0x%p, snd %u - %u > %u.\n", + c3cn, c3cn->write_seq, c3cn->snd_una, + cxgb3_snd_win); + err = -EAGAIN; goto out_err; } diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.h b/drivers/scsi/cxgb3i/cxgb3i_offload.h index d23156907ff..df1eae0ee4b 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_offload.h +++ b/drivers/scsi/cxgb3i/cxgb3i_offload.h @@ -178,25 +178,33 @@ void cxgb3i_c3cn_release(struct s3_conn *); * @flag: see C3CB_FLAG_* below * @ulp_mode: ULP mode/submode of sk_buff * @seq: tcp sequence number - * @ddigest: pdu data digest - * @pdulen: recovered pdu length - * @wr_data: scratch area for tx wr */ +struct cxgb3_skb_rx_cb { + __u32 ddigest; /* data digest */ + __u32 pdulen; /* recovered pdu length */ +}; + +struct cxgb3_skb_tx_cb { + struct sk_buff *wr_next; /* next wr */ +}; + struct cxgb3_skb_cb { __u8 flags; __u8 ulp_mode; __u32 seq; - __u32 ddigest; - __u32 pdulen; - struct sk_buff *wr_data; + union { + struct cxgb3_skb_rx_cb rx; + struct cxgb3_skb_tx_cb tx; + }; }; #define CXGB3_SKB_CB(skb) ((struct cxgb3_skb_cb *)&((skb)->cb[0])) - +#define skb_flags(skb) (CXGB3_SKB_CB(skb)->flags) #define skb_ulp_mode(skb) (CXGB3_SKB_CB(skb)->ulp_mode) -#define skb_ulp_ddigest(skb) (CXGB3_SKB_CB(skb)->ddigest) -#define skb_ulp_pdulen(skb) (CXGB3_SKB_CB(skb)->pdulen) -#define skb_wr_data(skb) (CXGB3_SKB_CB(skb)->wr_data) +#define skb_tcp_seq(skb) (CXGB3_SKB_CB(skb)->seq) +#define skb_rx_ddigest(skb) (CXGB3_SKB_CB(skb)->rx.ddigest) +#define skb_rx_pdulen(skb) (CXGB3_SKB_CB(skb)->rx.pdulen) +#define skb_tx_wr_next(skb) (CXGB3_SKB_CB(skb)->tx.wr_next) enum c3cb_flags { C3CB_FLAG_NEED_HDR = 1 << 0, /* packet needs a TX_DATA_WR header */ -- cgit From 949847d195d2bb86f61c289a57edb9207c4a3bbf Mon Sep 17 00:00:00 2001 From: Karen Xie Date: Fri, 13 Feb 2009 21:38:49 -0800 Subject: [SCSI] cxgb3i: added per-task data to track transmit progress added per-task struct cxgb3i_task_data to track the data transmiting progress and the state of the pdus to be transmitted. Signed-off-by: Karen Xie Reviewed-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/cxgb3i/cxgb3i.h | 21 +++++++++++++++++++++ drivers/scsi/cxgb3i/cxgb3i_iscsi.c | 5 +++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/cxgb3i/cxgb3i.h b/drivers/scsi/cxgb3i/cxgb3i.h index fde6e4c634e..a7cf550b9cc 100644 --- a/drivers/scsi/cxgb3i/cxgb3i.h +++ b/drivers/scsi/cxgb3i/cxgb3i.h @@ -20,6 +20,7 @@ #include #include #include +#include #include /* from cxgb3 LLD */ @@ -113,6 +114,26 @@ struct cxgb3i_endpoint { struct cxgb3i_conn *cconn; }; +/** + * struct cxgb3i_task_data - private iscsi task data + * + * @nr_frags: # of coalesced page frags (from scsi sgl) + * @frags: coalesced page frags (from scsi sgl) + * @skb: tx pdu skb + * @offset: data offset for the next pdu + * @count: max. possible pdu payload + * @sgoffset: offset to the first sg entry for a given offset + */ +#define MAX_PDU_FRAGS ((ULP2_MAX_PDU_PAYLOAD + 512 - 1) / 512) +struct cxgb3i_task_data { + unsigned short nr_frags; + skb_frag_t frags[MAX_PDU_FRAGS]; + struct sk_buff *skb; + unsigned int offset; + unsigned int count; + unsigned int sgoffset; +}; + int cxgb3i_iscsi_init(void); void cxgb3i_iscsi_cleanup(void); diff --git a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c index d83464b9b3f..f0434b74554 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c +++ b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c @@ -364,7 +364,8 @@ cxgb3i_session_create(struct iscsi_endpoint *ep, u16 cmds_max, u16 qdepth, cls_session = iscsi_session_setup(&cxgb3i_iscsi_transport, shost, cmds_max, - sizeof(struct iscsi_tcp_task), + sizeof(struct iscsi_tcp_task) + + sizeof(struct cxgb3i_task_data), initial_cmdsn, ISCSI_MAX_TARGET); if (!cls_session) return NULL; @@ -844,7 +845,7 @@ static struct scsi_host_template cxgb3i_host_template = { .proc_name = "cxgb3i", .queuecommand = iscsi_queuecommand, .change_queue_depth = iscsi_change_queue_depth, - .can_queue = 128 * (ISCSI_DEF_XMIT_CMDS_MAX - 1), + .can_queue = CXGB3I_SCSI_QDEPTH_DFLT - 1, .sg_tablesize = SG_ALL, .max_sectors = 0xFFFF, .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, -- cgit From f62d0896e67195d4407ef81c6f77a92f72a63e88 Mon Sep 17 00:00:00 2001 From: Karen Xie Date: Fri, 13 Feb 2009 21:38:54 -0800 Subject: [SCSI] cxgb3i: Outgoing pdus need to observe skb's MAX_SKB_FRAGS Need to make sure the outgoing pdu can fit into a single skb. When calulating the max. outgoing pdu payload size, take into consideration of - data can be held in the skb's fragment list, assume 512 bytes per fragment, and - data can be held in the headroom. Signed-off-by: Karen Xie Reviewed-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/cxgb3i/cxgb3i_ddp.c | 19 ++- drivers/scsi/cxgb3i/cxgb3i_ddp.h | 3 +- drivers/scsi/cxgb3i/cxgb3i_iscsi.c | 17 +-- drivers/scsi/cxgb3i/cxgb3i_offload.h | 1 + drivers/scsi/cxgb3i/cxgb3i_pdu.c | 275 +++++++++++++++++++++++------------ drivers/scsi/cxgb3i/cxgb3i_pdu.h | 2 +- 6 files changed, 205 insertions(+), 112 deletions(-) diff --git a/drivers/scsi/cxgb3i/cxgb3i_ddp.c b/drivers/scsi/cxgb3i/cxgb3i_ddp.c index 08f3a09d923..a83d36e4926 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_ddp.c +++ b/drivers/scsi/cxgb3i/cxgb3i_ddp.c @@ -639,10 +639,11 @@ static int ddp_init(struct t3cdev *tdev) write_unlock(&cxgb3i_ddp_rwlock); ddp_log_info("nppods %u (0x%x ~ 0x%x), bits %u, mask 0x%x,0x%x " - "pkt %u,%u.\n", + "pkt %u/%u, %u/%u.\n", ppmax, ddp->llimit, ddp->ulimit, ddp->idx_bits, ddp->idx_mask, ddp->rsvd_tag_mask, - ddp->max_txsz, ddp->max_rxsz); + ddp->max_txsz, uinfo.max_txsz, + ddp->max_rxsz, uinfo.max_rxsz); return 0; free_ddp_map: @@ -654,8 +655,8 @@ free_ddp_map: * cxgb3i_adapter_ddp_init - initialize the adapter's ddp resource * @tdev: t3cdev adapter * @tformat: tag format - * @txsz: max tx pkt size, filled in by this func. - * @rxsz: max rx pkt size, filled in by this func. + * @txsz: max tx pdu payload size, filled in by this func. + * @rxsz: max rx pdu payload size, filled in by this func. * initialize the ddp pagepod manager for a given adapter if needed and * setup the tag format for a given iscsi entity */ @@ -685,10 +686,12 @@ int cxgb3i_adapter_ddp_init(struct t3cdev *tdev, tformat->sw_bits, tformat->rsvd_bits, tformat->rsvd_shift, tformat->rsvd_mask); - *txsz = ddp->max_txsz; - *rxsz = ddp->max_rxsz; - ddp_log_info("ddp max pkt size: %u, %u.\n", - ddp->max_txsz, ddp->max_rxsz); + *txsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD, + ddp->max_txsz - ISCSI_PDU_NONPAYLOAD_LEN); + *rxsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD, + ddp->max_rxsz - ISCSI_PDU_NONPAYLOAD_LEN); + ddp_log_info("max payload size: %u/%u, %u/%u.\n", + *txsz, ddp->max_txsz, *rxsz, ddp->max_rxsz); return 0; } EXPORT_SYMBOL_GPL(cxgb3i_adapter_ddp_init); diff --git a/drivers/scsi/cxgb3i/cxgb3i_ddp.h b/drivers/scsi/cxgb3i/cxgb3i_ddp.h index 5c7c4d95c49..99d7014d614 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_ddp.h +++ b/drivers/scsi/cxgb3i/cxgb3i_ddp.h @@ -85,8 +85,9 @@ struct cxgb3i_ddp_info { struct sk_buff **gl_skb; }; +#define ISCSI_PDU_NONPAYLOAD_LEN 312 /* bhs(48) + ahs(256) + digest(8) */ #define ULP2_MAX_PKT_SIZE 16224 -#define ULP2_MAX_PDU_PAYLOAD (ULP2_MAX_PKT_SIZE - ISCSI_PDU_NONPAYLOAD_MAX) +#define ULP2_MAX_PDU_PAYLOAD (ULP2_MAX_PKT_SIZE - ISCSI_PDU_NONPAYLOAD_LEN) #define PPOD_PAGES_MAX 4 #define PPOD_PAGES_SHIFT 2 /* 4 pages per pod */ diff --git a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c index f0434b74554..fa2a44f37b3 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c +++ b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c @@ -403,17 +403,15 @@ static inline int cxgb3i_conn_max_xmit_dlength(struct iscsi_conn *conn) { struct iscsi_tcp_conn *tcp_conn = conn->dd_data; struct cxgb3i_conn *cconn = tcp_conn->dd_data; - unsigned int max = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD, - cconn->hba->snic->tx_max_size - - ISCSI_PDU_NONPAYLOAD_MAX); + unsigned int max = max(512 * MAX_SKB_FRAGS, SKB_TX_HEADROOM); + max = min(cconn->hba->snic->tx_max_size, max); if (conn->max_xmit_dlength) - conn->max_xmit_dlength = min_t(unsigned int, - conn->max_xmit_dlength, max); + conn->max_xmit_dlength = min(conn->max_xmit_dlength, max); else conn->max_xmit_dlength = max; align_pdu_size(conn->max_xmit_dlength); - cxgb3i_log_info("conn 0x%p, max xmit %u.\n", + cxgb3i_api_debug("conn 0x%p, max xmit %u.\n", conn, conn->max_xmit_dlength); return 0; } @@ -428,9 +426,7 @@ static inline int cxgb3i_conn_max_recv_dlength(struct iscsi_conn *conn) { struct iscsi_tcp_conn *tcp_conn = conn->dd_data; struct cxgb3i_conn *cconn = tcp_conn->dd_data; - unsigned int max = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD, - cconn->hba->snic->rx_max_size - - ISCSI_PDU_NONPAYLOAD_MAX); + unsigned int max = cconn->hba->snic->rx_max_size; align_pdu_size(max); if (conn->max_recv_dlength) { @@ -440,8 +436,7 @@ static inline int cxgb3i_conn_max_recv_dlength(struct iscsi_conn *conn) conn->max_recv_dlength, max); return -EINVAL; } - conn->max_recv_dlength = min_t(unsigned int, - conn->max_recv_dlength, max); + conn->max_recv_dlength = min(conn->max_recv_dlength, max); align_pdu_size(conn->max_recv_dlength); } else conn->max_recv_dlength = max; diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.h b/drivers/scsi/cxgb3i/cxgb3i_offload.h index df1eae0ee4b..6344b9eb258 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_offload.h +++ b/drivers/scsi/cxgb3i/cxgb3i_offload.h @@ -225,6 +225,7 @@ struct sge_opaque_hdr { /* for TX: a skb must have a headroom of at least TX_HEADER_LEN bytes */ #define TX_HEADER_LEN \ (sizeof(struct tx_data_wr) + sizeof(struct sge_opaque_hdr)) +#define SKB_TX_HEADROOM SKB_MAX_HEAD(TX_HEADER_LEN) /* * get and set private ip for iscsi traffic diff --git a/drivers/scsi/cxgb3i/cxgb3i_pdu.c b/drivers/scsi/cxgb3i/cxgb3i_pdu.c index ce7ce8c6094..17115c230d6 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_pdu.c +++ b/drivers/scsi/cxgb3i/cxgb3i_pdu.c @@ -32,6 +32,10 @@ #define cxgb3i_tx_debug(fmt...) #endif +/* always allocate rooms for AHS */ +#define SKB_TX_PDU_HEADER_LEN \ + (sizeof(struct iscsi_hdr) + ISCSI_MAX_AHS_SIZE) +static unsigned int skb_extra_headroom; static struct page *pad_page; /* @@ -146,12 +150,13 @@ static inline void tx_skb_setmode(struct sk_buff *skb, int hcrc, int dcrc) void cxgb3i_conn_cleanup_task(struct iscsi_task *task) { - struct iscsi_tcp_task *tcp_task = task->dd_data; + struct cxgb3i_task_data *tdata = task->dd_data + + sizeof(struct iscsi_tcp_task); /* never reached the xmit task callout */ - if (tcp_task->dd_data) - kfree_skb(tcp_task->dd_data); - tcp_task->dd_data = NULL; + if (tdata->skb) + __kfree_skb(tdata->skb); + memset(tdata, 0, sizeof(struct cxgb3i_task_data)); /* MNC - Do we need a check in case this is called but * cxgb3i_conn_alloc_pdu has never been called on the task */ @@ -159,28 +164,102 @@ void cxgb3i_conn_cleanup_task(struct iscsi_task *task) iscsi_tcp_cleanup_task(task); } -/* - * We do not support ahs yet - */ +static int sgl_seek_offset(struct scatterlist *sgl, unsigned int sgcnt, + unsigned int offset, unsigned int *off, + struct scatterlist **sgp) +{ + int i; + struct scatterlist *sg; + + for_each_sg(sgl, sg, sgcnt, i) { + if (offset < sg->length) { + *off = offset; + *sgp = sg; + return 0; + } + offset -= sg->length; + } + return -EFAULT; +} + +static int sgl_read_to_frags(struct scatterlist *sg, unsigned int sgoffset, + unsigned int dlen, skb_frag_t *frags, + int frag_max) +{ + unsigned int datalen = dlen; + unsigned int sglen = sg->length - sgoffset; + struct page *page = sg_page(sg); + int i; + + i = 0; + do { + unsigned int copy; + + if (!sglen) { + sg = sg_next(sg); + if (!sg) { + cxgb3i_log_error("%s, sg NULL, len %u/%u.\n", + __func__, datalen, dlen); + return -EINVAL; + } + sgoffset = 0; + sglen = sg->length; + page = sg_page(sg); + + } + copy = min(datalen, sglen); + if (i && page == frags[i - 1].page && + sgoffset + sg->offset == + frags[i - 1].page_offset + frags[i - 1].size) { + frags[i - 1].size += copy; + } else { + if (i >= frag_max) { + cxgb3i_log_error("%s, too many pages %u, " + "dlen %u.\n", __func__, + frag_max, dlen); + return -EINVAL; + } + + frags[i].page = page; + frags[i].page_offset = sg->offset + sgoffset; + frags[i].size = copy; + i++; + } + datalen -= copy; + sgoffset += copy; + sglen -= copy; + } while (datalen); + + return i; +} + int cxgb3i_conn_alloc_pdu(struct iscsi_task *task, u8 opcode) { + struct iscsi_conn *conn = task->conn; struct iscsi_tcp_task *tcp_task = task->dd_data; - struct sk_buff *skb; + struct cxgb3i_task_data *tdata = task->dd_data + sizeof(*tcp_task); + struct scsi_cmnd *sc = task->sc; + int headroom = SKB_TX_PDU_HEADER_LEN; + tcp_task->dd_data = tdata; task->hdr = NULL; - /* always allocate rooms for AHS */ - skb = alloc_skb(sizeof(struct iscsi_hdr) + ISCSI_MAX_AHS_SIZE + - TX_HEADER_LEN, GFP_ATOMIC); - if (!skb) + + /* write command, need to send data pdus */ + if (skb_extra_headroom && (opcode == ISCSI_OP_SCSI_DATA_OUT || + (opcode == ISCSI_OP_SCSI_CMD && + (scsi_bidi_cmnd(sc) || sc->sc_data_direction == DMA_TO_DEVICE)))) + headroom += min(skb_extra_headroom, conn->max_xmit_dlength); + + tdata->skb = alloc_skb(TX_HEADER_LEN + headroom, GFP_ATOMIC); + if (!tdata->skb) return -ENOMEM; + skb_reserve(tdata->skb, TX_HEADER_LEN); cxgb3i_tx_debug("task 0x%p, opcode 0x%x, skb 0x%p.\n", - task, opcode, skb); + task, opcode, tdata->skb); - tcp_task->dd_data = skb; - skb_reserve(skb, TX_HEADER_LEN); - task->hdr = (struct iscsi_hdr *)skb->data; - task->hdr_max = sizeof(struct iscsi_hdr); + task->hdr = (struct iscsi_hdr *)tdata->skb->data; + task->hdr_max = SKB_TX_PDU_HEADER_LEN; /* data_out uses scsi_cmd's itt */ if (opcode != ISCSI_OP_SCSI_DATA_OUT) @@ -192,13 +271,13 @@ int cxgb3i_conn_alloc_pdu(struct iscsi_task *task, u8 opcode) int cxgb3i_conn_init_pdu(struct iscsi_task *task, unsigned int offset, unsigned int count) { - struct iscsi_tcp_task *tcp_task = task->dd_data; - struct sk_buff *skb = tcp_task->dd_data; struct iscsi_conn *conn = task->conn; - struct page *pg; + struct iscsi_tcp_task *tcp_task = task->dd_data; + struct cxgb3i_task_data *tdata = tcp_task->dd_data; + struct sk_buff *skb = tdata->skb; unsigned int datalen = count; int i, padlen = iscsi_padding(count); - skb_frag_t *frag; + struct page *pg; cxgb3i_tx_debug("task 0x%p,0x%p, offset %u, count %u, skb 0x%p.\n", task, task->sc, offset, count, skb); @@ -209,90 +288,94 @@ int cxgb3i_conn_init_pdu(struct iscsi_task *task, unsigned int offset, return 0; if (task->sc) { - struct scatterlist *sg; - struct scsi_data_buffer *sdb; - unsigned int sgoffset = offset; - struct page *sgpg; - unsigned int sglen; - - sdb = scsi_out(task->sc); - sg = sdb->table.sgl; - - for_each_sg(sdb->table.sgl, sg, sdb->table.nents, i) { - cxgb3i_tx_debug("sg %d, page 0x%p, len %u offset %u\n", - i, sg_page(sg), sg->length, sg->offset); - - if (sgoffset < sg->length) - break; - sgoffset -= sg->length; + struct scsi_data_buffer *sdb = scsi_out(task->sc); + struct scatterlist *sg = NULL; + int err; + + tdata->offset = offset; + tdata->count = count; + err = sgl_seek_offset(sdb->table.sgl, sdb->table.nents, + tdata->offset, &tdata->sgoffset, &sg); + if (err < 0) { + cxgb3i_log_warn("tpdu, sgl %u, bad offset %u/%u.\n", + sdb->table.nents, tdata->offset, + sdb->length); + return err; } - sgpg = sg_page(sg); - sglen = sg->length - sgoffset; - - do { - int j = skb_shinfo(skb)->nr_frags; - unsigned int copy; - - if (!sglen) { - sg = sg_next(sg); - sgpg = sg_page(sg); - sgoffset = 0; - sglen = sg->length; - ++i; + err = sgl_read_to_frags(sg, tdata->sgoffset, tdata->count, + tdata->frags, MAX_PDU_FRAGS); + if (err < 0) { + cxgb3i_log_warn("tpdu, sgl %u, bad offset %u + %u.\n", + sdb->table.nents, tdata->offset, + tdata->count); + return err; + } + tdata->nr_frags = err; + + if (tdata->nr_frags > MAX_SKB_FRAGS || + (padlen && tdata->nr_frags == MAX_SKB_FRAGS)) { + char *dst = skb->data + task->hdr_len; + skb_frag_t *frag = tdata->frags; + + /* data fits in the skb's headroom */ + for (i = 0; i < tdata->nr_frags; i++, frag++) { + char *src = kmap_atomic(frag->page, + KM_SOFTIRQ0); + + memcpy(dst, src+frag->page_offset, frag->size); + dst += frag->size; + kunmap_atomic(src, KM_SOFTIRQ0); } - copy = min(sglen, datalen); - if (j && skb_can_coalesce(skb, j, sgpg, - sg->offset + sgoffset)) { - skb_shinfo(skb)->frags[j - 1].size += copy; - } else { - get_page(sgpg); - skb_fill_page_desc(skb, j, sgpg, - sg->offset + sgoffset, copy); + if (padlen) { + memset(dst, 0, padlen); + padlen = 0; } - sgoffset += copy; - sglen -= copy; - datalen -= copy; - } while (datalen); + skb_put(skb, count + padlen); + } else { + /* data fit into frag_list */ + for (i = 0; i < tdata->nr_frags; i++) + get_page(tdata->frags[i].page); + + memcpy(skb_shinfo(skb)->frags, tdata->frags, + sizeof(skb_frag_t) * tdata->nr_frags); + skb_shinfo(skb)->nr_frags = tdata->nr_frags; + skb->len += count; + skb->data_len += count; + skb->truesize += count; + } + } else { pg = virt_to_page(task->data); - while (datalen) { - i = skb_shinfo(skb)->nr_frags; - frag = &skb_shinfo(skb)->frags[i]; - - get_page(pg); - frag->page = pg; - frag->page_offset = 0; - frag->size = min((unsigned int)PAGE_SIZE, datalen); - - skb_shinfo(skb)->nr_frags++; - datalen -= frag->size; - pg++; - } + get_page(pg); + skb_fill_page_desc(skb, 0, pg, offset_in_page(task->data), + count); + skb->len += count; + skb->data_len += count; + skb->truesize += count; } if (padlen) { i = skb_shinfo(skb)->nr_frags; - frag = &skb_shinfo(skb)->frags[i]; - frag->page = pad_page; - frag->page_offset = 0; - frag->size = padlen; - skb_shinfo(skb)->nr_frags++; + get_page(pad_page); + skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, pad_page, 0, + padlen); + + skb->data_len += padlen; + skb->truesize += padlen; + skb->len += padlen; } - datalen = count + padlen; - skb->data_len += datalen; - skb->truesize += datalen; - skb->len += datalen; return 0; } int cxgb3i_conn_xmit_pdu(struct iscsi_task *task) { - struct iscsi_tcp_task *tcp_task = task->dd_data; - struct sk_buff *skb = tcp_task->dd_data; struct iscsi_tcp_conn *tcp_conn = task->conn->dd_data; struct cxgb3i_conn *cconn = tcp_conn->dd_data; + struct iscsi_tcp_task *tcp_task = task->dd_data; + struct cxgb3i_task_data *tdata = tcp_task->dd_data; + struct sk_buff *skb = tdata->skb; unsigned int datalen; int err; @@ -300,13 +383,14 @@ int cxgb3i_conn_xmit_pdu(struct iscsi_task *task) return 0; datalen = skb->data_len; - tcp_task->dd_data = NULL; + tdata->skb = NULL; err = cxgb3i_c3cn_send_pdus(cconn->cep->c3cn, skb); - cxgb3i_tx_debug("task 0x%p, skb 0x%p, len %u/%u, rv %d.\n", - task, skb, skb->len, skb->data_len, err); if (err > 0) { int pdulen = err; + cxgb3i_tx_debug("task 0x%p, skb 0x%p, len %u/%u, rv %d.\n", + task, skb, skb->len, skb->data_len, err); + if (task->conn->hdrdgst_en) pdulen += ISCSI_DIGEST_SIZE; if (datalen && task->conn->datadgst_en) @@ -325,12 +409,14 @@ int cxgb3i_conn_xmit_pdu(struct iscsi_task *task) return err; } /* reset skb to send when we are called again */ - tcp_task->dd_data = skb; + tdata->skb = skb; return -EAGAIN; } int cxgb3i_pdu_init(void) { + if (SKB_TX_HEADROOM > (512 * MAX_SKB_FRAGS)) + skb_extra_headroom = SKB_TX_HEADROOM; pad_page = alloc_page(GFP_KERNEL); if (!pad_page) return -ENOMEM; @@ -366,7 +452,9 @@ void cxgb3i_conn_pdu_ready(struct s3_conn *c3cn) skb = skb_peek(&c3cn->receive_queue); while (!err && skb) { __skb_unlink(skb, &c3cn->receive_queue); - read += skb_ulp_pdulen(skb); + read += skb_rx_pdulen(skb); + cxgb3i_rx_debug("conn 0x%p, cn 0x%p, rx skb 0x%p, pdulen %u.\n", + conn, c3cn, skb, skb_rx_pdulen(skb)); err = cxgb3i_conn_read_pdu_skb(conn, skb); __kfree_skb(skb); skb = skb_peek(&c3cn->receive_queue); @@ -377,6 +465,11 @@ void cxgb3i_conn_pdu_ready(struct s3_conn *c3cn) cxgb3i_c3cn_rx_credits(c3cn, read); } conn->rxdata_octets += read; + + if (err) { + cxgb3i_log_info("conn 0x%p rx failed err %d.\n", conn, err); + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); + } } void cxgb3i_conn_tx_open(struct s3_conn *c3cn) diff --git a/drivers/scsi/cxgb3i/cxgb3i_pdu.h b/drivers/scsi/cxgb3i/cxgb3i_pdu.h index a3f685cc236..0770b23d90d 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_pdu.h +++ b/drivers/scsi/cxgb3i/cxgb3i_pdu.h @@ -53,7 +53,7 @@ struct cpl_rx_data_ddp_norss { #define ULP2_FLAG_DCRC_ERROR 0x20 #define ULP2_FLAG_PAD_ERROR 0x40 -void cxgb3i_conn_closing(struct s3_conn *); +void cxgb3i_conn_closing(struct s3_conn *c3cn); void cxgb3i_conn_pdu_ready(struct s3_conn *c3cn); void cxgb3i_conn_tx_open(struct s3_conn *c3cn); #endif -- cgit From 992040f54069c96a59343976950f174448f4a351 Mon Sep 17 00:00:00 2001 From: Karen Xie Date: Fri, 13 Feb 2009 21:38:59 -0800 Subject: [SCSI] cxgb3i: added missing include in cxgb3i_ddp.h Signed-off-by: Karen Xie Reviewed-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/cxgb3i/cxgb3i_ddp.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/scsi/cxgb3i/cxgb3i_ddp.h b/drivers/scsi/cxgb3i/cxgb3i_ddp.h index 99d7014d614..3faae7831c8 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_ddp.h +++ b/drivers/scsi/cxgb3i/cxgb3i_ddp.h @@ -13,6 +13,8 @@ #ifndef __CXGB3I_ULP2_DDP_H__ #define __CXGB3I_ULP2_DDP_H__ +#include + /** * struct cxgb3i_tag_format - cxgb3i ulp tag format for an iscsi entity * -- cgit From 802d52734adf0f288c49c05ed433872d7559c932 Mon Sep 17 00:00:00 2001 From: Karen Xie Date: Fri, 13 Feb 2009 21:39:04 -0800 Subject: [SCSI] cxgb3i: Fix spelling errors in documentation Signed-off-by: Karen Xie Signed-off-by: James Bottomley --- Documentation/scsi/cxgb3i.txt | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Documentation/scsi/cxgb3i.txt b/Documentation/scsi/cxgb3i.txt index 8141fa01978..7ac8032ee9b 100644 --- a/Documentation/scsi/cxgb3i.txt +++ b/Documentation/scsi/cxgb3i.txt @@ -4,7 +4,7 @@ Introduction ============ The Chelsio T3 ASIC based Adapters (S310, S320, S302, S304, Mezz cards, etc. -series of products) supports iSCSI acceleration and iSCSI Direct Data Placement +series of products) support iSCSI acceleration and iSCSI Direct Data Placement (DDP) where the hardware handles the expensive byte touching operations, such as CRC computation and verification, and direct DMA to the final host memory destination: @@ -31,9 +31,9 @@ destination: the TCP segments onto the wire. It handles TCP retransmission if needed. - On receving, S3 h/w recovers the iSCSI PDU by reassembling TCP + On receiving, S3 h/w recovers the iSCSI PDU by reassembling TCP segments, separating the header and data, calculating and verifying - the digests, then forwards the header to the host. The payload data, + the digests, then forwarding the header to the host. The payload data, if possible, will be directly placed into the pre-posted host DDP buffer. Otherwise, the payload data will be sent to the host too. @@ -68,9 +68,8 @@ The following steps need to be taken to accelerates the open-iscsi initiator: sure the ip address is unique in the network. 3. edit /etc/iscsi/iscsid.conf - The default setting for MaxRecvDataSegmentLength (131072) is too big, - replace "node.conn[0].iscsi.MaxRecvDataSegmentLength" to be a value no - bigger than 15360 (for example 8192): + The default setting for MaxRecvDataSegmentLength (131072) is too big; + replace with a value no bigger than 15360 (for example 8192): node.conn[0].iscsi.MaxRecvDataSegmentLength = 8192 -- cgit From b7e7bd34465518f3527bf47a8055f35077d40c6c Mon Sep 17 00:00:00 2001 From: Karen Xie Date: Fri, 13 Feb 2009 21:39:09 -0800 Subject: [SCSI] cxgb3i: update the driver version to 1.0.1 Signed-off-by: Karen Xie Signed-off-by: James Bottomley --- drivers/scsi/cxgb3i/cxgb3i_init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/cxgb3i/cxgb3i_init.c b/drivers/scsi/cxgb3i/cxgb3i_init.c index 091ecb4d9f3..1ce9f244e46 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_init.c +++ b/drivers/scsi/cxgb3i/cxgb3i_init.c @@ -12,8 +12,8 @@ #include "cxgb3i.h" #define DRV_MODULE_NAME "cxgb3i" -#define DRV_MODULE_VERSION "1.0.0" -#define DRV_MODULE_RELDATE "Jun. 1, 2008" +#define DRV_MODULE_VERSION "1.0.1" +#define DRV_MODULE_RELDATE "Jan. 2009" static char version[] = "Chelsio S3xx iSCSI Driver " DRV_MODULE_NAME -- cgit From 4034cc68157bfa0b6622efe368488d3d3e20f4e6 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 21 Feb 2009 11:04:45 +0900 Subject: [SCSI] sd: revive sd_index_lock Commit f27bac2761cab5a2e212dea602d22457a9aa6943 which converted sd to use ida instead of idr incorrectly removed sd_index_lock around id allocation and free. idr/ida do have internal locks but they protect their free object lists not the allocation itself. The caller is responsible for that. This missing synchronization led to the same id being assigned to multiple devices leading to oops. Reported and tracked down by Stuart Hayes of Dell. Signed-off-by: Tejun Heo Cc: Stable Tree Signed-off-by: James Bottomley --- drivers/scsi/sd.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index d57566b8be0..55310dbc10a 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -107,6 +107,7 @@ static void scsi_disk_release(struct device *cdev); static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); static void sd_print_result(struct scsi_disk *, int); +static DEFINE_SPINLOCK(sd_index_lock); static DEFINE_IDA(sd_index_ida); /* This semaphore is used to mediate the 0->1 reference get in the @@ -1914,7 +1915,9 @@ static int sd_probe(struct device *dev) if (!ida_pre_get(&sd_index_ida, GFP_KERNEL)) goto out_put; + spin_lock(&sd_index_lock); error = ida_get_new(&sd_index_ida, &index); + spin_unlock(&sd_index_lock); } while (error == -EAGAIN); if (error) @@ -1936,7 +1939,9 @@ static int sd_probe(struct device *dev) return 0; out_free_index: + spin_lock(&sd_index_lock); ida_remove(&sd_index_ida, index); + spin_unlock(&sd_index_lock); out_put: put_disk(gd); out_free: @@ -1986,7 +1991,9 @@ static void scsi_disk_release(struct device *dev) struct scsi_disk *sdkp = to_scsi_disk(dev); struct gendisk *disk = sdkp->disk; + spin_lock(&sd_index_lock); ida_remove(&sd_index_ida, sdkp->index); + spin_unlock(&sd_index_lock); disk->private_data = NULL; put_disk(disk); -- cgit From 126c098296c8f96cf7f6ca0fdb47265ac7994f00 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Thu, 19 Feb 2009 21:48:54 +0000 Subject: [SCSI] fix ABORTED_COMMAND looping forever problem Instead of terminating after five retries, commands terminated by ABORTED_COMMAND sense are retrying forever. The problem was introduced by: commit b60af5b0adf0da24c673598c8d3fb4d4189a15ce Author: Alan Stern Date: Mon Nov 3 15:56:47 2008 -0500 [SCSI] simplify scsi_io_completion() Which introduced an error whereby ABORTED_COMMAND now gets erroneously retried in scsi_io_completion. Fix this by returning the behaviour back to the default no retry. Reported-by: Sitsofe Wheeler Tested-by: Sitsofe Wheeler Signed-off-by: James Bottomley --- drivers/scsi/scsi_lib.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 940dc32ff0d..b82ffd90632 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1040,12 +1040,11 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) action = ACTION_FAIL; break; case ABORTED_COMMAND: + action = ACTION_FAIL; if (sshdr.asc == 0x10) { /* DIF */ description = "Target Data Integrity Failure"; - action = ACTION_FAIL; error = -EILSEQ; - } else - action = ACTION_RETRY; + } break; case NOT_READY: /* If the device is in the process of becoming -- cgit From e6bd6760c92dc8475c79c4c4a8a16ac313c0b93d Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Sun, 15 Feb 2009 22:45:49 +0100 Subject: x86_64: acpi/wakeup_64 cleanup - remove %ds re-set, it's already set in wakeup_long64 - remove double labels and alignment (ENTRY already adds both) - use meaningful resume point labelname - skip alignment while jumping from wakeup_long64 to the resume point - remove .size, .type and unused labels [v2] - added ENDPROCs Signed-off-by: Jiri Slaby Acked-by: Cyrill Gorcunov Acked-by: Pavel Machek Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown --- arch/x86/kernel/acpi/wakeup_64.S | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/arch/x86/kernel/acpi/wakeup_64.S b/arch/x86/kernel/acpi/wakeup_64.S index bcc293423a7..b5dee6a0de3 100644 --- a/arch/x86/kernel/acpi/wakeup_64.S +++ b/arch/x86/kernel/acpi/wakeup_64.S @@ -13,7 +13,6 @@ * Hooray, we are in Long 64-bit mode (but still running in low memory) */ ENTRY(wakeup_long64) -wakeup_long64: movq saved_magic, %rax movq $0x123456789abcdef0, %rdx cmpq %rdx, %rax @@ -34,16 +33,12 @@ wakeup_long64: movq saved_rip, %rax jmp *%rax +ENDPROC(wakeup_long64) bogus_64_magic: jmp bogus_64_magic - .align 2 - .p2align 4,,15 -.globl do_suspend_lowlevel - .type do_suspend_lowlevel,@function -do_suspend_lowlevel: -.LFB5: +ENTRY(do_suspend_lowlevel) subq $8, %rsp xorl %eax, %eax call save_processor_state @@ -67,7 +62,7 @@ do_suspend_lowlevel: pushfq popq pt_regs_flags(%rax) - movq $.L97, saved_rip(%rip) + movq $resume_point, saved_rip(%rip) movq %rsp, saved_rsp movq %rbp, saved_rbp @@ -79,13 +74,9 @@ do_suspend_lowlevel: movl $3, %edi xorl %eax, %eax jmp acpi_enter_sleep_state -.L97: - .p2align 4,,7 -.L99: - .align 4 - movl $24, %eax - movw %ax, %ds + .align 4 +resume_point: /* We don't restore %rax, it must be 0 anyway */ movq $saved_context, %rax movq saved_context_cr4(%rax), %rbx @@ -117,12 +108,9 @@ do_suspend_lowlevel: xorl %eax, %eax addq $8, %rsp jmp restore_processor_state -.LFE5: -.Lfe5: - .size do_suspend_lowlevel, .Lfe5-do_suspend_lowlevel - +ENDPROC(do_suspend_lowlevel) + .data -ALIGN ENTRY(saved_rbp) .quad 0 ENTRY(saved_rsi) .quad 0 ENTRY(saved_rdi) .quad 0 -- cgit From 6defa2fe2019f3729933516fba5cfd75eecd07de Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Sun, 15 Feb 2009 22:46:45 +0100 Subject: x86_64: Fix S3 fail path As acpi_enter_sleep_state can fail, take this into account in do_suspend_lowlevel and don't return to the do_suspend_lowlevel's caller. This would break (currently) fpu status and preempt count. Technically, this means use `call' instead of `jmp' and `jmp' to the `resume_point' after the `call' (i.e. if acpi_enter_sleep_state returns=fails). `resume_point' will handle the restore of fpu and preempt count gracefully. Signed-off-by: Jiri Slaby Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown --- arch/x86/kernel/acpi/wakeup_64.S | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/acpi/wakeup_64.S b/arch/x86/kernel/acpi/wakeup_64.S index b5dee6a0de3..96258d9dc97 100644 --- a/arch/x86/kernel/acpi/wakeup_64.S +++ b/arch/x86/kernel/acpi/wakeup_64.S @@ -73,7 +73,9 @@ ENTRY(do_suspend_lowlevel) addq $8, %rsp movl $3, %edi xorl %eax, %eax - jmp acpi_enter_sleep_state + call acpi_enter_sleep_state + /* in case something went wrong, restore the machine status and go on */ + jmp resume_point .align 4 resume_point: -- cgit From 4898c2b2f04051e19f4230683c0f0b15f71af887 Mon Sep 17 00:00:00 2001 From: Tony Vroon Date: Mon, 2 Feb 2009 11:11:10 +0000 Subject: fujitsu-laptop: Use RFKILL support bitmask from firmware Up until now, we polled the rfkill status for every incoming FUJ02E3 ACPI event. It turns out that the firmware has a bitmask which indicates what rfkill-related state it can report. The rfkill_supported bitmask is now used to avoid polling for rfkill at all in the notification handler if there is no support. Also, it is used in the platform device callbacks. As before we register all callbacks and report "unknown" if the firmware does not give us status updates for that particular bit. This was fed through checkpatch.pl and tested on the S6420, S7020 and P8010 platforms. Signed-off-by: Tony Vroon Tested-by: Stephen Gildea Acked-by: Jonathan Woithe Signed-off-by: Len Brown --- drivers/platform/x86/fujitsu-laptop.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index 65dc41540c6..45940f31fe9 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c @@ -166,6 +166,7 @@ struct fujitsu_hotkey_t { struct platform_device *pf_device; struct kfifo *fifo; spinlock_t fifo_lock; + int rfkill_supported; int rfkill_state; int logolamp_registered; int kblamps_registered; @@ -526,7 +527,7 @@ static ssize_t show_lid_state(struct device *dev, struct device_attribute *attr, char *buf) { - if (fujitsu_hotkey->rfkill_state == UNSUPPORTED_CMD) + if (!(fujitsu_hotkey->rfkill_supported & 0x100)) return sprintf(buf, "unknown\n"); if (fujitsu_hotkey->rfkill_state & 0x100) return sprintf(buf, "open\n"); @@ -538,7 +539,7 @@ static ssize_t show_dock_state(struct device *dev, struct device_attribute *attr, char *buf) { - if (fujitsu_hotkey->rfkill_state == UNSUPPORTED_CMD) + if (!(fujitsu_hotkey->rfkill_supported & 0x200)) return sprintf(buf, "unknown\n"); if (fujitsu_hotkey->rfkill_state & 0x200) return sprintf(buf, "docked\n"); @@ -550,7 +551,7 @@ static ssize_t show_radios_state(struct device *dev, struct device_attribute *attr, char *buf) { - if (fujitsu_hotkey->rfkill_state == UNSUPPORTED_CMD) + if (!(fujitsu_hotkey->rfkill_supported & 0x20)) return sprintf(buf, "unknown\n"); if (fujitsu_hotkey->rfkill_state & 0x20) return sprintf(buf, "on\n"); @@ -928,8 +929,17 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) ; /* No action, result is discarded */ vdbg_printk(FUJLAPTOP_DBG_INFO, "Discarded %i ringbuffer entries\n", i); - fujitsu_hotkey->rfkill_state = - call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0); + fujitsu_hotkey->rfkill_supported = + call_fext_func(FUNC_RFKILL, 0x0, 0x0, 0x0); + + /* Make sure our bitmask of supported functions is cleared if the + RFKILL function block is not implemented, like on the S7020. */ + if (fujitsu_hotkey->rfkill_supported == UNSUPPORTED_CMD) + fujitsu_hotkey->rfkill_supported = 0; + + if (fujitsu_hotkey->rfkill_supported) + fujitsu_hotkey->rfkill_state = + call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0); /* Suspect this is a keymap of the application panel, print it */ printk(KERN_INFO "fujitsu-laptop: BTNI: [0x%x]\n", @@ -1005,8 +1015,9 @@ static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event, input = fujitsu_hotkey->input; - fujitsu_hotkey->rfkill_state = - call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0); + if (fujitsu_hotkey->rfkill_supported) + fujitsu_hotkey->rfkill_state = + call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0); switch (event) { case ACPI_FUJITSU_NOTIFY_CODE1: -- cgit From ba193d64abfe644e8752affa310a368eda01f46e Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 19 Feb 2009 12:56:16 -0700 Subject: ACPI: remove CONFIG_ACPI_SYSTEM Remove CONFIG_ACPI_SYSTEM. It was always set the same as CONFIG_ACPI, and it had no menu label, so there was no way to set it to anything other than "y". Some things under CONFIG_ACPI_SYSTEM (acpi_irq_handled, acpi_os_gpe_count(), event_is_open, register_acpi_notifier(), etc.) are used unconditionally by the CA, the OSPM, and drivers, so we depend on them always being present. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown --- drivers/acpi/Kconfig | 7 ------- drivers/acpi/Makefile | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index a7799a99f2d..8a851d0f438 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -254,13 +254,6 @@ config ACPI_PCI_SLOT help you correlate PCI bus addresses with the physical geography of your slots. If you are unsure, say N. -config ACPI_SYSTEM - bool - default y - help - This driver will enable your system to shut down using ACPI, and - dump your ACPI DSDT table using /proc/acpi/dsdt. - config X86_PM_TIMER bool "Power Management Timer Support" if EMBEDDED depends on X86 diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 65d90c720b5..b130ea0d075 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -52,7 +52,7 @@ obj-$(CONFIG_ACPI_PROCESSOR) += processor.o obj-$(CONFIG_ACPI_CONTAINER) += container.o obj-$(CONFIG_ACPI_THERMAL) += thermal.o obj-y += power.o -obj-$(CONFIG_ACPI_SYSTEM) += system.o event.o +obj-y += system.o event.o obj-$(CONFIG_ACPI_DEBUG) += debug.o obj-$(CONFIG_ACPI_NUMA) += numa.o obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o -- cgit From b956d41162b1f2c4b446107e9910e4719cbc75f4 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Sat, 21 Feb 2009 23:46:36 -0800 Subject: sunlance: Beyond ARRAY_SIZE of ib->btx_ring Do not go beyond ARRAY_SIZE of ib->btx_ring Signed-off-by: Roel Kluin Signed-off-by: David S. Miller --- drivers/net/sunlance.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 28137328175..16c528db725 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -343,7 +343,7 @@ static void lance_init_ring_dvma(struct net_device *dev) ib->phys_addr [5] = dev->dev_addr [4]; /* Setup the Tx ring entries */ - for (i = 0; i <= TX_RING_SIZE; i++) { + for (i = 0; i < TX_RING_SIZE; i++) { leptr = LANCE_ADDR(aib + libbuff_offset(tx_buf, i)); ib->btx_ring [i].tmd0 = leptr; ib->btx_ring [i].tmd1_hadr = leptr >> 16; @@ -399,7 +399,7 @@ static void lance_init_ring_pio(struct net_device *dev) sbus_writeb(dev->dev_addr[4], &ib->phys_addr[5]); /* Setup the Tx ring entries */ - for (i = 0; i <= TX_RING_SIZE; i++) { + for (i = 0; i < TX_RING_SIZE; i++) { leptr = libbuff_offset(tx_buf, i); sbus_writew(leptr, &ib->btx_ring [i].tmd0); sbus_writeb(leptr >> 16,&ib->btx_ring [i].tmd1_hadr); -- cgit From ee923623177249cf22c43419ad0e8ff926dd1f58 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Sun, 22 Feb 2009 00:04:45 -0800 Subject: veth : add the set_mac_address capability Fix lost set_mac_address capability. Signed-off-by: Daniel Lezcano Signed-off-by: David S. Miller --- drivers/net/veth.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 852d0e7c4e6..108bbbeacfb 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -263,10 +263,11 @@ static void veth_dev_free(struct net_device *dev) } static const struct net_device_ops veth_netdev_ops = { - .ndo_init = veth_dev_init, - .ndo_open = veth_open, - .ndo_start_xmit = veth_xmit, - .ndo_get_stats = veth_get_stats, + .ndo_init = veth_dev_init, + .ndo_open = veth_open, + .ndo_start_xmit = veth_xmit, + .ndo_get_stats = veth_get_stats, + .ndo_set_mac_address = eth_mac_addr, }; static void veth_setup(struct net_device *dev) -- cgit From 486a87f1e5624096bd1c09e9e716239597d48dca Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Sun, 22 Feb 2009 00:07:53 -0800 Subject: netns: fix double free at netns creation This patch fix a double free when a network namespace fails. The previous code does a kfree of the net_generic structure when one of the init subsystem initialization fails. The 'setup_net' function does kfree(ng) and returns an error. The caller, 'copy_net_ns', call net_free on error, and this one calls kfree(net->gen), making this pointer freed twice. This patch make the code symetric, the net_alloc does the net_generic allocation and the net_free frees the net_generic. Signed-off-by: Daniel Lezcano Signed-off-by: David S. Miller --- net/core/net_namespace.c | 86 +++++++++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 31 deletions(-) diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 55151faaf90..b0767abf23e 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -32,24 +32,14 @@ static __net_init int setup_net(struct net *net) { /* Must be called with net_mutex held */ struct pernet_operations *ops; - int error; - struct net_generic *ng; + int error = 0; atomic_set(&net->count, 1); + #ifdef NETNS_REFCNT_DEBUG atomic_set(&net->use_count, 0); #endif - error = -ENOMEM; - ng = kzalloc(sizeof(struct net_generic) + - INITIAL_NET_GEN_PTRS * sizeof(void *), GFP_KERNEL); - if (ng == NULL) - goto out; - - ng->len = INITIAL_NET_GEN_PTRS; - rcu_assign_pointer(net->gen, ng); - - error = 0; list_for_each_entry(ops, &pernet_list, list) { if (ops->init) { error = ops->init(net); @@ -70,7 +60,6 @@ out_undo: } rcu_barrier(); - kfree(ng); goto out; } @@ -78,16 +67,43 @@ out_undo: static struct kmem_cache *net_cachep; static struct workqueue_struct *netns_wq; -static struct net *net_alloc(void) +static struct net_generic *net_alloc_generic(void) { - return kmem_cache_zalloc(net_cachep, GFP_KERNEL); + struct net_generic *ng; + size_t generic_size = sizeof(struct net_generic) + + INITIAL_NET_GEN_PTRS * sizeof(void *); + + ng = kzalloc(generic_size, GFP_KERNEL); + if (ng) + ng->len = INITIAL_NET_GEN_PTRS; + + return ng; } -static void net_free(struct net *net) +static struct net *net_alloc(void) { + struct net *net = NULL; + struct net_generic *ng; + + ng = net_alloc_generic(); + if (!ng) + goto out; + + net = kmem_cache_zalloc(net_cachep, GFP_KERNEL); if (!net) - return; + goto out_free; + + rcu_assign_pointer(net->gen, ng); +out: + return net; + +out_free: + kfree(ng); + goto out; +} +static void net_free(struct net *net) +{ #ifdef NETNS_REFCNT_DEBUG if (unlikely(atomic_read(&net->use_count) != 0)) { printk(KERN_EMERG "network namespace not free! Usage: %d\n", @@ -112,27 +128,28 @@ struct net *copy_net_ns(unsigned long flags, struct net *old_net) err = -ENOMEM; new_net = net_alloc(); if (!new_net) - goto out; + goto out_err; mutex_lock(&net_mutex); err = setup_net(new_net); - if (err) - goto out_unlock; - - rtnl_lock(); - list_add_tail(&new_net->list, &net_namespace_list); - rtnl_unlock(); - - -out_unlock: + if (!err) { + rtnl_lock(); + list_add_tail(&new_net->list, &net_namespace_list); + rtnl_unlock(); + } mutex_unlock(&net_mutex); + + if (err) + goto out_free; out: put_net(old_net); - if (err) { - net_free(new_net); - new_net = ERR_PTR(err); - } return new_net; + +out_free: + net_free(new_net); +out_err: + new_net = ERR_PTR(err); + goto out; } static void cleanup_net(struct work_struct *work) @@ -188,6 +205,7 @@ struct net *copy_net_ns(unsigned long flags, struct net *old_net) static int __init net_ns_init(void) { + struct net_generic *ng; int err; printk(KERN_INFO "net_namespace: %zd bytes\n", sizeof(struct net)); @@ -202,6 +220,12 @@ static int __init net_ns_init(void) panic("Could not create netns workq"); #endif + ng = net_alloc_generic(); + if (!ng) + panic("Could not allocate generic netns"); + + rcu_assign_pointer(init_net.gen, ng); + mutex_lock(&net_mutex); err = setup_net(&init_net); -- cgit From fc6fcdfbb8f1b2553255170f221cd57a4108591f Mon Sep 17 00:00:00 2001 From: Hannes Eder Date: Sun, 22 Feb 2009 01:00:57 +0100 Subject: x86: kexec/i386: fix sparse warnings: Using plain integer as NULL pointer Fix these sparse warnings: arch/x86/kernel/machine_kexec_32.c:124:22: warning: Using plain integer as NULL pointer arch/x86/kernel/traps.c:950:24: warning: Using plain integer as NULL pointer Signed-off-by: Hannes Eder Cc: trivial@kernel.org Signed-off-by: Ingo Molnar --- arch/x86/kernel/machine_kexec_32.c | 2 +- arch/x86/kernel/traps.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c index 37f420018a4..f5fc8c781a6 100644 --- a/arch/x86/kernel/machine_kexec_32.c +++ b/arch/x86/kernel/machine_kexec_32.c @@ -121,7 +121,7 @@ static void machine_kexec_page_table_set_one( static void machine_kexec_prepare_page_tables(struct kimage *image) { void *control_page; - pmd_t *pmd = 0; + pmd_t *pmd = NULL; control_page = page_address(image->control_code_page); #ifdef CONFIG_X86_PAE diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index acb8c0585ab..2df927b5003 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -942,7 +942,7 @@ dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code) info.si_signo = SIGILL; info.si_errno = 0; info.si_code = ILL_BADSTK; - info.si_addr = 0; + info.si_addr = NULL; if (notify_die(DIE_TRAP, "iret exception", regs, error_code, 32, SIGILL) == NOTIFY_STOP) return; -- cgit From 2366c298b5afe52e635afd5604b69ce9fd4471fc Mon Sep 17 00:00:00 2001 From: Hannes Eder Date: Sun, 22 Feb 2009 01:01:13 +0100 Subject: x86: numa_32.c: fix sparse warning: Using plain integer as NULL pointer Fix this sparse warning: arch/x86/mm/numa_32.c:197:24: warning: Using plain integer as NULL pointer Signed-off-by: Hannes Eder Cc: trivial@kernel.org Signed-off-by: Ingo Molnar --- arch/x86/mm/numa_32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/mm/numa_32.c b/arch/x86/mm/numa_32.c index d1f7439d173..3957cd6d645 100644 --- a/arch/x86/mm/numa_32.c +++ b/arch/x86/mm/numa_32.c @@ -194,7 +194,7 @@ void *alloc_remap(int nid, unsigned long size) size = ALIGN(size, L1_CACHE_BYTES); if (!allocation || (allocation + size) >= node_remap_end_vaddr[nid]) - return 0; + return NULL; node_remap_alloc_vaddr[nid] += size; memset(allocation, 0, size); -- cgit From b319eed0aa0a6d710887350a3cb734c572aa64c4 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 22 Feb 2009 10:24:18 +0100 Subject: x86, mm: fault.c, simplify kmmio_fault(), cleanup Clarify the kmmio_fault() comment. Acked-by: Pekka Paalanen Signed-off-by: Ingo Molnar --- arch/x86/mm/fault.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 9bb07d331c3..a03b7279efa 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -57,7 +57,8 @@ enum x86_pf_error_code { }; /* - * (returns 0 if mmiotrace is disabled) + * Returns 0 if mmiotrace is disabled, or if the fault is not + * handled by mmiotrace: */ static inline int kmmio_fault(struct pt_regs *regs, unsigned long addr) { -- cgit From 8cfd9e923be54ef66ce174a93f4592b444b96407 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 22 Feb 2009 12:36:55 +0000 Subject: [ARM] RiscPC: Fix etherh oops The 8390 driver was structured by Al Viro to allow the flexibility required by platforms. lib8390.c contains the core code which drivers explicitly include: - 8390.c includes lib8390.c to provide the standard ISA based driver. - etherh.c includes it with the accessors defined for RiscPC platforms, where it is addressed via the MMIO accessors with a device dependent register spacing. Other platform drivers do something similar. However, b9a9b4b caused the kernel to contain not only the etherh private build of lib8390 (included in etherh.c) but also lib8390.c itself, and referred the new net_device_ops methods to the ISA version. The result of this is is not pretty: Unable to handle kernel paging request at virtual address 12032030 pgd = c8330000 [12032030] *pgd=00000000 Internal error: Oops: 18331805 [#1] Modules linked in: ipv6 CPU: 0 Not tainted (2.6.29-rc3 #167) PC is at do_set_multicast_list+0xd0/0x190 LR is at bitrev32+0x28/0x34 pc : [] lr : [] psr: a0000093 sp : c8321d9c ip : c8321d84 fp : c8321dbc r10: c80c6800 r9 : 00000000 r8 : c80c6b60 r7 : c80c6b80 r6 : cc80c800 r5 : c80c6800 r4 : 00000000 r3 : cc80c80c r2 : 00000004 r1 : 00000007 r0 : e0000000 Flags: NzCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment user ... Fix up b9a9b4b by making etherh's net_device_ops refer to the internal lib8390 functions, and remove the build of the ISA 8390.c driver. Acked-by: David S. Miller Signed-off-by: Russell King --- drivers/net/arm/Makefile | 2 +- drivers/net/arm/etherh.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/arm/Makefile b/drivers/net/arm/Makefile index c69c0cdba4a..811a3ccd14c 100644 --- a/drivers/net/arm/Makefile +++ b/drivers/net/arm/Makefile @@ -4,7 +4,7 @@ # obj-$(CONFIG_ARM_AM79C961A) += am79c961a.o -obj-$(CONFIG_ARM_ETHERH) += etherh.o ../8390.o +obj-$(CONFIG_ARM_ETHERH) += etherh.o obj-$(CONFIG_ARM_ETHER3) += ether3.o obj-$(CONFIG_ARM_ETHER1) += ether1.o obj-$(CONFIG_ARM_AT91_ETHER) += at91_ether.o diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c index 54b52e5b182..f52f668c49b 100644 --- a/drivers/net/arm/etherh.c +++ b/drivers/net/arm/etherh.c @@ -641,15 +641,15 @@ static const struct net_device_ops etherh_netdev_ops = { .ndo_open = etherh_open, .ndo_stop = etherh_close, .ndo_set_config = etherh_set_config, - .ndo_start_xmit = ei_start_xmit, - .ndo_tx_timeout = ei_tx_timeout, - .ndo_get_stats = ei_get_stats, - .ndo_set_multicast_list = ei_set_multicast_list, + .ndo_start_xmit = __ei_start_xmit, + .ndo_tx_timeout = __ei_tx_timeout, + .ndo_get_stats = __ei_get_stats, + .ndo_set_multicast_list = __ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = ei_poll, + .ndo_poll_controller = __ei_poll, #endif }; -- cgit From 5ce7868e159a3ee4ddf95f8522643991fea97cf2 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 18 Feb 2009 11:25:32 -0800 Subject: [SCSI] mpt: fix disable lsi sas to use msi as default Impact: fix bug the third param in module_param(,,) is perm instead of default value. we still need to assign default at first. Also, the default is now zero not one, so fix the parameter text to reflect that. Signed-off-by: Yinghai Lu Acked-by: Kashyap Desai Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 96ac88317b8..ea3aafbbda4 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -91,9 +91,9 @@ MODULE_PARM_DESC(mpt_msi_enable_fc, " Enable MSI Support for FC \ controllers (default=0)"); static int mpt_msi_enable_sas; -module_param(mpt_msi_enable_sas, int, 1); +module_param(mpt_msi_enable_sas, int, 0); MODULE_PARM_DESC(mpt_msi_enable_sas, " Enable MSI Support for SAS \ - controllers (default=1)"); + controllers (default=0)"); static int mpt_channel_mapping; -- cgit From a47e3ec197f515e25c77805f02d26f9e86456f65 Mon Sep 17 00:00:00 2001 From: Hiroshi Shimamoto Date: Fri, 20 Feb 2009 18:57:58 -0800 Subject: x86: ia32_signal: remove unused debug code Impact: cleanup DEBUG_SIG will not be used. Signed-off-by: Hiroshi Shimamoto Signed-off-by: Ingo Molnar --- arch/x86/ia32/ia32_signal.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c index dd77ac0cac4..adc63f81cb8 100644 --- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/ia32/ia32_signal.c @@ -33,8 +33,6 @@ #include #include -#define DEBUG_SIG 0 - #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) #define FIX_EFLAGS (X86_EFLAGS_AC | X86_EFLAGS_OF | \ @@ -220,12 +218,6 @@ static int ia32_restore_sigcontext(struct pt_regs *regs, /* Always make any pending restarted system calls return -EINTR */ current_thread_info()->restart_block.fn = do_no_restart_syscall; -#if DEBUG_SIG - printk(KERN_DEBUG "SIG restore_sigcontext: " - "sc=%p err(%x) eip(%x) cs(%x) flg(%x)\n", - sc, sc->err, sc->ip, sc->cs, sc->flags); -#endif - get_user_try { /* * Reload fs and gs if they have changed in the signal @@ -488,11 +480,6 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka, regs->cs = __USER32_CS; regs->ss = __USER32_DS; -#if DEBUG_SIG - printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n", - current->comm, current->pid, frame, regs->ip, frame->pretcode); -#endif - return 0; } @@ -574,10 +561,5 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, regs->cs = __USER32_CS; regs->ss = __USER32_DS; -#if DEBUG_SIG - printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n", - current->comm, current->pid, frame, regs->ip, frame->pretcode); -#endif - return 0; } -- cgit From 8801ead40caa8ba9c7d47a06ff1247c166cbfd5a Mon Sep 17 00:00:00 2001 From: Hiroshi Shimamoto Date: Fri, 20 Feb 2009 19:00:13 -0800 Subject: x86: ia32_signal: introduce GET_SEG() macro Impact: cleanup introduce GET_SEG() macro like arch/x86/kernel/signal.c. Signed-off-by: Hiroshi Shimamoto Signed-off-by: Ingo Molnar --- arch/x86/ia32/ia32_signal.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c index adc63f81cb8..8dd0903da08 100644 --- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/ia32/ia32_signal.c @@ -192,11 +192,15 @@ asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr, get_user_ex(regs->x, &sc->x); \ } -#define COPY_SEG_CPL3(seg) { \ - unsigned short tmp; \ - get_user_ex(tmp, &sc->seg); \ - regs->seg = tmp | 3; \ -} +#define GET_SEG(seg) ({ \ + unsigned short tmp; \ + get_user_ex(tmp, &sc->seg); \ + tmp; \ +}) + +#define COPY_SEG_CPL3(seg) do { \ + regs->seg = GET_SEG(seg) | 3; \ +} while (0) #define RELOAD_SEG(seg) { \ unsigned int cur, pre; \ -- cgit From a967bb3fbe640056bacb0357722f51676bb06e3c Mon Sep 17 00:00:00 2001 From: Hiroshi Shimamoto Date: Fri, 20 Feb 2009 19:00:54 -0800 Subject: x86: ia32_signal: introduce {get|set}_user_seg() Impact: cleanup Introduce {get|set}_user_seg() and loadsegment_xx() macros to make code clean. Signed-off-by: Hiroshi Shimamoto Signed-off-by: Ingo Molnar --- arch/x86/ia32/ia32_signal.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c index 8dd0903da08..588a7aa937e 100644 --- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/ia32/ia32_signal.c @@ -188,6 +188,14 @@ asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr, /* * Do a signal return; undo the signal stack. */ +#define loadsegment_gs(v) load_gs_index(v) +#define loadsegment_fs(v) loadsegment(fs, v) +#define loadsegment_ds(v) loadsegment(ds, v) +#define loadsegment_es(v) loadsegment(es, v) + +#define get_user_seg(seg) ({ unsigned int v; savesegment(seg, v); v; }) +#define set_user_seg(seg, v) loadsegment_##seg(v) + #define COPY(x) { \ get_user_ex(regs->x, &sc->x); \ } @@ -203,19 +211,18 @@ asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr, } while (0) #define RELOAD_SEG(seg) { \ - unsigned int cur, pre; \ - get_user_ex(pre, &sc->seg); \ - savesegment(seg, cur); \ + unsigned int pre = GET_SEG(seg); \ + unsigned int cur = get_user_seg(seg); \ pre |= 3; \ if (pre != cur) \ - loadsegment(seg, pre); \ + set_user_seg(seg, pre); \ } static int ia32_restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 __user *sc, unsigned int *pax) { - unsigned int tmpflags, gs, oldgs, err = 0; + unsigned int tmpflags, err = 0; void __user *buf; u32 tmp; @@ -229,12 +236,7 @@ static int ia32_restore_sigcontext(struct pt_regs *regs, * the handler, but does not clobber them at least in the * normal case. */ - get_user_ex(gs, &sc->gs); - gs |= 3; - savesegment(gs, oldgs); - if (gs != oldgs) - load_gs_index(gs); - + RELOAD_SEG(gs); RELOAD_SEG(fs); RELOAD_SEG(ds); RELOAD_SEG(es); @@ -333,17 +335,13 @@ static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, void __user *fpstate, struct pt_regs *regs, unsigned int mask) { - int tmp, err = 0; + int err = 0; put_user_try { - savesegment(gs, tmp); - put_user_ex(tmp, (unsigned int __user *)&sc->gs); - savesegment(fs, tmp); - put_user_ex(tmp, (unsigned int __user *)&sc->fs); - savesegment(ds, tmp); - put_user_ex(tmp, (unsigned int __user *)&sc->ds); - savesegment(es, tmp); - put_user_ex(tmp, (unsigned int __user *)&sc->es); + put_user_ex(get_user_seg(gs), (unsigned int __user *)&sc->gs); + put_user_ex(get_user_seg(fs), (unsigned int __user *)&sc->fs); + put_user_ex(get_user_seg(ds), (unsigned int __user *)&sc->ds); + put_user_ex(get_user_seg(es), (unsigned int __user *)&sc->es); put_user_ex(regs->di, &sc->di); put_user_ex(regs->si, &sc->si); -- cgit From ef1f87aa7ba6224bef1b750b3272ba281d8f43ed Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Sat, 21 Feb 2009 14:23:21 -0800 Subject: x86: select x2apic ops in early apic probe only if x2apic mode is enabled If BIOS hands over the control to OS in legacy xapic mode, select legacy xapic related ops in the early apic probe and shift to x2apic ops later in the boot sequence, only after enabling x2apic mode. If BIOS hands over the control in x2apic mode, select x2apic related ops in the early apic probe. This fixes the early boot panic, where we were selecting x2apic ops, while the cpu is still in legacy xapic mode. Signed-off-by: Suresh Siddha Cc: Yinghai Lu Cc: Andrew Morton Signed-off-by: Ingo Molnar --- arch/x86/include/asm/apic.h | 2 +- arch/x86/kernel/apic/apic.c | 9 +-------- arch/x86/kernel/apic/probe_64.c | 13 ++++++++++--- arch/x86/kernel/apic/x2apic_cluster.c | 5 +---- arch/x86/kernel/apic/x2apic_phys.c | 10 +++++----- 5 files changed, 18 insertions(+), 21 deletions(-) diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index dce1bf696cc..a6208dc7463 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -146,7 +146,7 @@ static inline u64 native_x2apic_icr_read(void) return val; } -extern int x2apic; +extern int x2apic, x2apic_phys; extern void check_x2apic(void); extern void enable_x2apic(void); extern void enable_IR_x2apic(void); diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index c12823eb55b..47c2d12e5cf 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -1265,14 +1265,7 @@ void __cpuinit end_local_APIC_setup(void) #ifdef CONFIG_X86_X2APIC void check_x2apic(void) { - int msr, msr2; - - if (!cpu_has_x2apic) - return; - - rdmsr(MSR_IA32_APICBASE, msr, msr2); - - if (msr & X2APIC_ENABLE) { + if (x2apic_enabled()) { pr_info("x2apic enabled by BIOS, switching to x2apic ops\n"); x2apic_preenabled = x2apic = 1; } diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c index 70935dd904d..e7c163661c7 100644 --- a/arch/x86/kernel/apic/probe_64.c +++ b/arch/x86/kernel/apic/probe_64.c @@ -50,9 +50,16 @@ static struct apic *apic_probe[] __initdata = { void __init default_setup_apic_routing(void) { #ifdef CONFIG_X86_X2APIC - if (apic == &apic_x2apic_phys || apic == &apic_x2apic_cluster) { - if (!intr_remapping_enabled) - apic = &apic_flat; + if (x2apic && (apic != &apic_x2apic_phys && +#ifdef CONFIG_X86_UV + apic != &apic_x2apic_uv_x && +#endif + apic != &apic_x2apic_cluster)) { + if (x2apic_phys) + apic = &apic_x2apic_phys; + else + apic = &apic_x2apic_cluster; + printk(KERN_INFO "Setting APIC routing to %s\n", apic->name); } #endif diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index 4e39d9ad4d5..354b9c45601 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c @@ -14,10 +14,7 @@ DEFINE_PER_CPU(u32, x86_cpu_to_logical_apicid); static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id) { - if (cpu_has_x2apic) - return 1; - - return 0; + return x2apic_enabled(); } /* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */ diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c index d2d52eb9f7e..5bcb174409b 100644 --- a/arch/x86/kernel/apic/x2apic_phys.c +++ b/arch/x86/kernel/apic/x2apic_phys.c @@ -10,7 +10,7 @@ #include #include -static int x2apic_phys; +int x2apic_phys; static int set_x2apic_phys_mode(char *arg) { @@ -21,10 +21,10 @@ early_param("x2apic_phys", set_x2apic_phys_mode); static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id) { - if (cpu_has_x2apic && x2apic_phys) - return 1; - - return 0; + if (x2apic_phys) + return x2apic_enabled(); + else + return 0; } /* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */ -- cgit From 3d92e8f3ae9ba21cac30370eb254ed9dc20df043 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 22 Feb 2009 09:38:47 +0100 Subject: m68k: atari - Rename "mfp" to "st_mfp" http://kisskb.ellerman.id.au/kisskb/buildresult/72115/: | net/mac80211/ieee80211_i.h:327: error: syntax error before 'volatile' | net/mac80211/ieee80211_i.h:350: error: syntax error before '}' token | net/mac80211/ieee80211_i.h:455: error: field 'sta' has incomplete type | distcc[19430] ERROR: compile net/mac80211/main.c on sprygo/32 failed This is caused by | # define mfp ((*(volatile struct MFP*)MFP_BAS)) in arch/m68k/include/asm/atarihw.h, which conflicts with the new "mfp" enum in net/mac80211/ieee80211_i.h. Rename "mfp" to "st_mfp", as it's a way too generic name for a global #define. Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/atari/ataints.c | 16 ++++++++-------- arch/m68k/atari/atakeyb.c | 4 ++-- arch/m68k/atari/config.c | 2 +- arch/m68k/atari/debug.c | 22 +++++++++++----------- arch/m68k/atari/time.c | 8 ++++---- arch/m68k/include/asm/atarihw.h | 4 ++-- arch/m68k/include/asm/atariints.h | 6 +++--- drivers/block/ataflop.c | 4 ++-- drivers/char/scc.h | 2 +- drivers/parport/parport_atari.c | 6 +++--- drivers/video/atafb.c | 22 +++++++++++----------- sound/oss/dmasound/dmasound_atari.c | 16 ++++++++-------- 12 files changed, 56 insertions(+), 56 deletions(-) diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c index dba4afabb44..39478dd08e6 100644 --- a/arch/m68k/atari/ataints.c +++ b/arch/m68k/atari/ataints.c @@ -187,8 +187,8 @@ __asm__ (__ALIGN_STR "\n" \ " jbra ret_from_interrupt\n" \ : : "i" (&kstat_cpu(0).irqs[n+8]), "i" (&irq_handler[n+8]), \ "n" (PT_OFF_SR), "n" (n), \ - "i" (n & 8 ? (n & 16 ? &tt_mfp.int_mk_a : &mfp.int_mk_a) \ - : (n & 16 ? &tt_mfp.int_mk_b : &mfp.int_mk_b)), \ + "i" (n & 8 ? (n & 16 ? &tt_mfp.int_mk_a : &st_mfp.int_mk_a) \ + : (n & 16 ? &tt_mfp.int_mk_b : &st_mfp.int_mk_b)), \ "m" (preempt_count()), "di" (HARDIRQ_OFFSET) \ ); \ for (;;); /* fake noreturn */ \ @@ -366,14 +366,14 @@ void __init atari_init_IRQ(void) /* Initialize the MFP(s) */ #ifdef ATARI_USE_SOFTWARE_EOI - mfp.vec_adr = 0x48; /* Software EOI-Mode */ + st_mfp.vec_adr = 0x48; /* Software EOI-Mode */ #else - mfp.vec_adr = 0x40; /* Automatic EOI-Mode */ + st_mfp.vec_adr = 0x40; /* Automatic EOI-Mode */ #endif - mfp.int_en_a = 0x00; /* turn off MFP-Ints */ - mfp.int_en_b = 0x00; - mfp.int_mk_a = 0xff; /* no Masking */ - mfp.int_mk_b = 0xff; + st_mfp.int_en_a = 0x00; /* turn off MFP-Ints */ + st_mfp.int_en_b = 0x00; + st_mfp.int_mk_a = 0xff; /* no Masking */ + st_mfp.int_mk_b = 0xff; if (ATARIHW_PRESENT(TT_MFP)) { #ifdef ATARI_USE_SOFTWARE_EOI diff --git a/arch/m68k/atari/atakeyb.c b/arch/m68k/atari/atakeyb.c index a5f33c05997..4add96d13b1 100644 --- a/arch/m68k/atari/atakeyb.c +++ b/arch/m68k/atari/atakeyb.c @@ -609,10 +609,10 @@ int atari_keyb_init(void) ACIA_RHTID : 0); /* make sure the interrupt line is up */ - } while ((mfp.par_dt_reg & 0x10) == 0); + } while ((st_mfp.par_dt_reg & 0x10) == 0); /* enable ACIA Interrupts */ - mfp.active_edge &= ~0x10; + st_mfp.active_edge &= ~0x10; atari_turnon_irq(IRQ_MFP_ACIA); ikbd_self_test = 1; diff --git a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c index 49c28cdbea5..ae2d96e5d61 100644 --- a/arch/m68k/atari/config.c +++ b/arch/m68k/atari/config.c @@ -258,7 +258,7 @@ void __init config_atari(void) printk("STND_SHIFTER "); } } - if (hwreg_present(&mfp.par_dt_reg)) { + if (hwreg_present(&st_mfp.par_dt_reg)) { ATARIHW_SET(ST_MFP); printk("ST_MFP "); } diff --git a/arch/m68k/atari/debug.c b/arch/m68k/atari/debug.c index 702b15ccfab..28efdc33c1a 100644 --- a/arch/m68k/atari/debug.c +++ b/arch/m68k/atari/debug.c @@ -34,9 +34,9 @@ static struct console atari_console_driver = { static inline void ata_mfp_out(char c) { - while (!(mfp.trn_stat & 0x80)) /* wait for tx buf empty */ + while (!(st_mfp.trn_stat & 0x80)) /* wait for tx buf empty */ barrier(); - mfp.usart_dta = c; + st_mfp.usart_dta = c; } static void atari_mfp_console_write(struct console *co, const char *str, @@ -91,7 +91,7 @@ static int ata_par_out(char c) /* This a some-seconds timeout in case no printer is connected */ unsigned long i = loops_per_jiffy > 1 ? loops_per_jiffy : 10000000/HZ; - while ((mfp.par_dt_reg & 1) && --i) /* wait for BUSY == L */ + while ((st_mfp.par_dt_reg & 1) && --i) /* wait for BUSY == L */ ; if (!i) return 0; @@ -131,9 +131,9 @@ static void atari_par_console_write(struct console *co, const char *str, #if 0 int atari_mfp_console_wait_key(struct console *co) { - while (!(mfp.rcv_stat & 0x80)) /* wait for rx buf filled */ + while (!(st_mfp.rcv_stat & 0x80)) /* wait for rx buf filled */ barrier(); - return mfp.usart_dta; + return st_mfp.usart_dta; } int atari_scc_console_wait_key(struct console *co) @@ -175,12 +175,12 @@ static void __init atari_init_mfp_port(int cflag) baud = B9600; /* use default 9600bps for non-implemented rates */ baud -= B1200; /* baud_table[] starts at 1200bps */ - mfp.trn_stat &= ~0x01; /* disable TX */ - mfp.usart_ctr = parity | csize | 0x88; /* 1:16 clk mode, 1 stop bit */ - mfp.tim_ct_cd &= 0x70; /* stop timer D */ - mfp.tim_dt_d = baud_table[baud]; - mfp.tim_ct_cd |= 0x01; /* start timer D, 1:4 */ - mfp.trn_stat |= 0x01; /* enable TX */ + st_mfp.trn_stat &= ~0x01; /* disable TX */ + st_mfp.usart_ctr = parity | csize | 0x88; /* 1:16 clk mode, 1 stop bit */ + st_mfp.tim_ct_cd &= 0x70; /* stop timer D */ + st_mfp.tim_dt_d = baud_table[baud]; + st_mfp.tim_ct_cd |= 0x01; /* start timer D, 1:4 */ + st_mfp.trn_stat |= 0x01; /* enable TX */ } #define SCC_WRITE(reg, val) \ diff --git a/arch/m68k/atari/time.c b/arch/m68k/atari/time.c index d076ff8d1b3..a0531f34c61 100644 --- a/arch/m68k/atari/time.c +++ b/arch/m68k/atari/time.c @@ -27,9 +27,9 @@ void __init atari_sched_init(irq_handler_t timer_routine) { /* set Timer C data Register */ - mfp.tim_dt_c = INT_TICKS; + st_mfp.tim_dt_c = INT_TICKS; /* start timer C, div = 1:100 */ - mfp.tim_ct_cd = (mfp.tim_ct_cd & 15) | 0x60; + st_mfp.tim_ct_cd = (st_mfp.tim_ct_cd & 15) | 0x60; /* install interrupt service routine for MFP Timer C */ if (request_irq(IRQ_MFP_TIMC, timer_routine, IRQ_TYPE_SLOW, "timer", timer_routine)) @@ -46,11 +46,11 @@ unsigned long atari_gettimeoffset (void) unsigned long ticks, offset = 0; /* read MFP timer C current value */ - ticks = mfp.tim_dt_c; + ticks = st_mfp.tim_dt_c; /* The probability of underflow is less than 2% */ if (ticks > INT_TICKS - INT_TICKS / 50) /* Check for pending timer interrupt */ - if (mfp.int_pn_b & (1 << 5)) + if (st_mfp.int_pn_b & (1 << 5)) offset = TICK_SIZE; ticks = INT_TICKS - ticks; diff --git a/arch/m68k/include/asm/atarihw.h b/arch/m68k/include/asm/atarihw.h index 1412b4ab202..a714e1aa072 100644 --- a/arch/m68k/include/asm/atarihw.h +++ b/arch/m68k/include/asm/atarihw.h @@ -113,7 +113,7 @@ extern struct atari_hw_present atari_hw_present; * of nops on various machines. Somebody claimed that the tstb takes 600 ns. */ #define MFPDELAY() \ - __asm__ __volatile__ ( "tstb %0" : : "m" (mfp.par_dt_reg) : "cc" ); + __asm__ __volatile__ ( "tstb %0" : : "m" (st_mfp.par_dt_reg) : "cc" ); /* Do cache push/invalidate for DMA read/write. This function obeys the * snooping on some machines (Medusa) and processors: The Medusa itself can @@ -565,7 +565,7 @@ struct MFP u_char char_dummy23; u_char usart_dta; }; -# define mfp ((*(volatile struct MFP*)MFP_BAS)) +# define st_mfp ((*(volatile struct MFP*)MFP_BAS)) /* TT's second MFP */ diff --git a/arch/m68k/include/asm/atariints.h b/arch/m68k/include/asm/atariints.h index 5748e99f4e2..f597892e43a 100644 --- a/arch/m68k/include/asm/atariints.h +++ b/arch/m68k/include/asm/atariints.h @@ -113,7 +113,7 @@ static inline int get_mfp_bit( unsigned irq, int type ) { unsigned char mask, *reg; mask = 1 << (irq & 7); - reg = (unsigned char *)&mfp.int_en_a + type*4 + + reg = (unsigned char *)&st_mfp.int_en_a + type*4 + ((irq & 8) >> 2) + (((irq-8) & 16) << 3); return( *reg & mask ); } @@ -123,7 +123,7 @@ static inline void set_mfp_bit( unsigned irq, int type ) { unsigned char mask, *reg; mask = 1 << (irq & 7); - reg = (unsigned char *)&mfp.int_en_a + type*4 + + reg = (unsigned char *)&st_mfp.int_en_a + type*4 + ((irq & 8) >> 2) + (((irq-8) & 16) << 3); __asm__ __volatile__ ( "orb %0,%1" : : "di" (mask), "m" (*reg) : "memory" ); @@ -134,7 +134,7 @@ static inline void clear_mfp_bit( unsigned irq, int type ) { unsigned char mask, *reg; mask = ~(1 << (irq & 7)); - reg = (unsigned char *)&mfp.int_en_a + type*4 + + reg = (unsigned char *)&st_mfp.int_en_a + type*4 + ((irq & 8) >> 2) + (((irq-8) & 16) << 3); if (type == MFP_PENDING || type == MFP_SERVICE) __asm__ __volatile__ ( "moveb %0,%1" diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index 69e1df7dfa1..4234c11c1e4 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -1730,7 +1730,7 @@ static int __init fd_test_drive_present( int drive ) timeout = jiffies + 2*HZ+HZ/2; while (time_before(jiffies, timeout)) - if (!(mfp.par_dt_reg & 0x20)) + if (!(st_mfp.par_dt_reg & 0x20)) break; status = FDC_READ( FDCREG_STATUS ); @@ -1747,7 +1747,7 @@ static int __init fd_test_drive_present( int drive ) /* dummy seek command to make WP bit accessible */ FDC_WRITE( FDCREG_DATA, 0 ); FDC_WRITE( FDCREG_CMD, FDCCMD_SEEK ); - while( mfp.par_dt_reg & 0x20 ) + while( st_mfp.par_dt_reg & 0x20 ) ; status = FDC_READ( FDCREG_STATUS ); } diff --git a/drivers/char/scc.h b/drivers/char/scc.h index 93998f5baff..341b1142bea 100644 --- a/drivers/char/scc.h +++ b/drivers/char/scc.h @@ -387,7 +387,7 @@ struct scc_port { /* The SCC needs 3.5 PCLK cycles recovery time between to register * accesses. PCLK runs with 8 MHz on an Atari, so this delay is 3.5 * * 125 ns = 437.5 ns. This is too short for udelay(). - * 10/16/95: A tstb mfp.par_dt_reg takes 600ns (sure?) and thus should be + * 10/16/95: A tstb st_mfp.par_dt_reg takes 600ns (sure?) and thus should be * quite right */ diff --git a/drivers/parport/parport_atari.c b/drivers/parport/parport_atari.c index ad4cdd25613..0b28fccec03 100644 --- a/drivers/parport/parport_atari.c +++ b/drivers/parport/parport_atari.c @@ -84,7 +84,7 @@ parport_atari_frob_control(struct parport *p, unsigned char mask, static unsigned char parport_atari_read_status(struct parport *p) { - return ((mfp.par_dt_reg & 1 ? 0 : PARPORT_STATUS_BUSY) | + return ((st_mfp.par_dt_reg & 1 ? 0 : PARPORT_STATUS_BUSY) | PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR); } @@ -193,9 +193,9 @@ static int __init parport_atari_init(void) sound_ym.wd_data = sound_ym.rd_data_reg_sel | (1 << 5); local_irq_restore(flags); /* MFP port I0 as input. */ - mfp.data_dir &= ~1; + st_mfp.data_dir &= ~1; /* MFP port I0 interrupt on high->low edge. */ - mfp.active_edge &= ~1; + st_mfp.active_edge &= ~1; p = parport_register_port((unsigned long)&sound_ym.wd_data, IRQ_MFP_BUSY, PARPORT_DMA_NONE, &parport_atari_ops); diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c index 8058572a742..018850c116c 100644 --- a/drivers/video/atafb.c +++ b/drivers/video/atafb.c @@ -841,7 +841,7 @@ static int tt_detect(void) tt_dmasnd.ctrl = DMASND_CTRL_OFF; udelay(20); /* wait a while for things to settle down */ } - mono_moni = (mfp.par_dt_reg & 0x80) == 0; + mono_moni = (st_mfp.par_dt_reg & 0x80) == 0; tt_get_par(&par); tt_encode_var(&atafb_predefined[0], &par); @@ -2035,7 +2035,7 @@ static int stste_detect(void) tt_dmasnd.ctrl = DMASND_CTRL_OFF; udelay(20); /* wait a while for things to settle down */ } - mono_moni = (mfp.par_dt_reg & 0x80) == 0; + mono_moni = (st_mfp.par_dt_reg & 0x80) == 0; stste_get_par(&par); stste_encode_var(&atafb_predefined[0], &par); @@ -2086,20 +2086,20 @@ static void st_ovsc_switch(void) return; local_irq_save(flags); - mfp.tim_ct_b = 0x10; - mfp.active_edge |= 8; - mfp.tim_ct_b = 0; - mfp.tim_dt_b = 0xf0; - mfp.tim_ct_b = 8; - while (mfp.tim_dt_b > 1) /* TOS does it this way, don't ask why */ + st_mfp.tim_ct_b = 0x10; + st_mfp.active_edge |= 8; + st_mfp.tim_ct_b = 0; + st_mfp.tim_dt_b = 0xf0; + st_mfp.tim_ct_b = 8; + while (st_mfp.tim_dt_b > 1) /* TOS does it this way, don't ask why */ ; - new = mfp.tim_dt_b; + new = st_mfp.tim_dt_b; do { udelay(LINE_DELAY); old = new; - new = mfp.tim_dt_b; + new = st_mfp.tim_dt_b; } while (old != new); - mfp.tim_ct_b = 0x10; + st_mfp.tim_ct_b = 0x10; udelay(SYNC_DELAY); if (atari_switches & ATARI_SWITCH_OVSC_IKBD) diff --git a/sound/oss/dmasound/dmasound_atari.c b/sound/oss/dmasound/dmasound_atari.c index 57d9f154c88..38931f2f696 100644 --- a/sound/oss/dmasound/dmasound_atari.c +++ b/sound/oss/dmasound/dmasound_atari.c @@ -847,23 +847,23 @@ static int __init AtaIrqInit(void) of events. So all we need to keep the music playing is to provide the sound hardware with new data upon an interrupt from timer A. */ - mfp.tim_ct_a = 0; /* ++roman: Stop timer before programming! */ - mfp.tim_dt_a = 1; /* Cause interrupt after first event. */ - mfp.tim_ct_a = 8; /* Turn on event counting. */ + st_mfp.tim_ct_a = 0; /* ++roman: Stop timer before programming! */ + st_mfp.tim_dt_a = 1; /* Cause interrupt after first event. */ + st_mfp.tim_ct_a = 8; /* Turn on event counting. */ /* Register interrupt handler. */ if (request_irq(IRQ_MFP_TIMA, AtaInterrupt, IRQ_TYPE_SLOW, "DMA sound", AtaInterrupt)) return 0; - mfp.int_en_a |= 0x20; /* Turn interrupt on. */ - mfp.int_mk_a |= 0x20; + st_mfp.int_en_a |= 0x20; /* Turn interrupt on. */ + st_mfp.int_mk_a |= 0x20; return 1; } #ifdef MODULE static void AtaIrqCleanUp(void) { - mfp.tim_ct_a = 0; /* stop timer */ - mfp.int_en_a &= ~0x20; /* turn interrupt off */ + st_mfp.tim_ct_a = 0; /* stop timer */ + st_mfp.int_en_a &= ~0x20; /* turn interrupt off */ free_irq(IRQ_MFP_TIMA, AtaInterrupt); } #endif /* MODULE */ @@ -1599,7 +1599,7 @@ static int __init dmasound_atari_init(void) is_falcon = 0; } else return -ENODEV; - if ((mfp.int_en_a & mfp.int_mk_a & 0x20) == 0) + if ((st_mfp.int_en_a & st_mfp.int_mk_a & 0x20) == 0) return dmasound_init(); else { printk("DMA sound driver: Timer A interrupt already in use\n"); -- cgit From 245127dbe9ea1e5a93aae0d3ede09992f1e99f53 Mon Sep 17 00:00:00 2001 From: Mike Murphy Date: Sun, 22 Feb 2009 01:17:14 -0500 Subject: PATCH [1/2] Documentation/driver-model/device.txt: fix struct device_attribute Fix the presented definition of struct device_attribute to match the actual definition in include/linux/device.h Signed-off-by: Mike Murphy Signed-off-by: Linus Torvalds --- Documentation/driver-model/device.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Documentation/driver-model/device.txt b/Documentation/driver-model/device.txt index a05ec50f800..a7cbfff40d0 100644 --- a/Documentation/driver-model/device.txt +++ b/Documentation/driver-model/device.txt @@ -127,9 +127,11 @@ void unlock_device(struct device * dev); Attributes ~~~~~~~~~~ struct device_attribute { - struct attribute attr; - ssize_t (*show)(struct device * dev, char * buf, size_t count, loff_t off); - ssize_t (*store)(struct device * dev, const char * buf, size_t count, loff_t off); + struct attribute attr; + ssize_t (*show)(struct device *dev, struct device_attribute *attr, + char *buf); + ssize_t (*store)(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count); }; Attributes of devices can be exported via drivers using a simple -- cgit From f8a1af6bbc63218cabce742a7a291ac7c08bbd00 Mon Sep 17 00:00:00 2001 From: Mike Murphy Date: Sun, 22 Feb 2009 01:19:23 -0500 Subject: PATCH [2/2] Documentation/filesystems/sysfs.txt: fix descriptions of device attributes Fix descriptions of device attributes to be consistent with the actual implementations in include/linux/device.h Signed-off-by: Mike Murphy Signed-off-by: Linus Torvalds --- Documentation/filesystems/sysfs.txt | 50 +++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/Documentation/filesystems/sysfs.txt b/Documentation/filesystems/sysfs.txt index 9e9c348275a..7e81e37c0b1 100644 --- a/Documentation/filesystems/sysfs.txt +++ b/Documentation/filesystems/sysfs.txt @@ -2,8 +2,10 @@ sysfs - _The_ filesystem for exporting kernel objects. Patrick Mochel +Mike Murphy -10 January 2003 +Revised: 22 February 2009 +Original: 10 January 2003 What it is: @@ -64,12 +66,13 @@ An attribute definition is simply: struct attribute { char * name; + struct module *owner; mode_t mode; }; -int sysfs_create_file(struct kobject * kobj, struct attribute * attr); -void sysfs_remove_file(struct kobject * kobj, struct attribute * attr); +int sysfs_create_file(struct kobject * kobj, const struct attribute * attr); +void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr); A bare attribute contains no means to read or write the value of the @@ -80,9 +83,11 @@ a specific object type. For example, the driver model defines struct device_attribute like: struct device_attribute { - struct attribute attr; - ssize_t (*show)(struct device * dev, char * buf); - ssize_t (*store)(struct device * dev, const char * buf); + struct attribute attr; + ssize_t (*show)(struct device *dev, struct device_attribute *attr, + char *buf); + ssize_t (*store)(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count); }; int device_create_file(struct device *, struct device_attribute *); @@ -90,12 +95,8 @@ void device_remove_file(struct device *, struct device_attribute *); It also defines this helper for defining device attributes: -#define DEVICE_ATTR(_name, _mode, _show, _store) \ -struct device_attribute dev_attr_##_name = { \ - .attr = {.name = __stringify(_name) , .mode = _mode }, \ - .show = _show, \ - .store = _store, \ -}; +#define DEVICE_ATTR(_name, _mode, _show, _store) \ +struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store) For example, declaring @@ -107,9 +108,9 @@ static struct device_attribute dev_attr_foo = { .attr = { .name = "foo", .mode = S_IWUSR | S_IRUGO, + .show = show_foo, + .store = store_foo, }, - .show = show_foo, - .store = store_foo, }; @@ -161,10 +162,12 @@ To read or write attributes, show() or store() methods must be specified when declaring the attribute. The method types should be as simple as those defined for device attributes: - ssize_t (*show)(struct device * dev, char * buf); - ssize_t (*store)(struct device * dev, const char * buf); +ssize_t (*show)(struct device * dev, struct device_attribute * attr, + char * buf); +ssize_t (*store)(struct device * dev, struct device_attribute * attr, + const char * buf); -IOW, they should take only an object and a buffer as parameters. +IOW, they should take only an object, an attribute, and a buffer as parameters. sysfs allocates a buffer of size (PAGE_SIZE) and passes it to the @@ -299,14 +302,16 @@ The following interface layers currently exist in sysfs: Structure: struct device_attribute { - struct attribute attr; - ssize_t (*show)(struct device * dev, char * buf); - ssize_t (*store)(struct device * dev, const char * buf); + struct attribute attr; + ssize_t (*show)(struct device *dev, struct device_attribute *attr, + char *buf); + ssize_t (*store)(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count); }; Declaring: -DEVICE_ATTR(_name, _str, _mode, _show, _store); +DEVICE_ATTR(_name, _mode, _show, _store); Creation/Removal: @@ -342,7 +347,8 @@ Structure: struct driver_attribute { struct attribute attr; ssize_t (*show)(struct device_driver *, char * buf); - ssize_t (*store)(struct device_driver *, const char * buf); + ssize_t (*store)(struct device_driver *, const char * buf, + size_t count); }; Declaring: -- cgit From 936577c61d0c10b8929608a92c98d839b22053bc Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 22 Feb 2009 10:27:49 -0800 Subject: x86: Add IRQF_TIMER to legacy x86 timer interrupt descriptors Right now nobody cares, but the suspend/resume code will eventually want to suspend device interrupts without suspending the timer, and will depend on this flag to know. The modern x86 timer infrastructure uses the local APIC timers and never shows up as a device interrupt at all, so it isn't affected and doesn't need any of this. Cc: Rafael J. Wysocki Cc: Ingo Molnar Signed-off-by: Linus Torvalds --- arch/x86/kernel/time_64.c | 2 +- arch/x86/kernel/vmiclock_32.c | 2 +- arch/x86/mach-default/setup.c | 2 +- arch/x86/mach-voyager/setup.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/time_64.c b/arch/x86/kernel/time_64.c index e6e695acd72..241ec3923f6 100644 --- a/arch/x86/kernel/time_64.c +++ b/arch/x86/kernel/time_64.c @@ -115,7 +115,7 @@ unsigned long __init calibrate_cpu(void) static struct irqaction irq0 = { .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING, + .flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING | IRQF_TIMER, .mask = CPU_MASK_NONE, .name = "timer" }; diff --git a/arch/x86/kernel/vmiclock_32.c b/arch/x86/kernel/vmiclock_32.c index bde106cae0a..e5b088fffa4 100644 --- a/arch/x86/kernel/vmiclock_32.c +++ b/arch/x86/kernel/vmiclock_32.c @@ -202,7 +202,7 @@ static irqreturn_t vmi_timer_interrupt(int irq, void *dev_id) static struct irqaction vmi_clock_action = { .name = "vmi-timer", .handler = vmi_timer_interrupt, - .flags = IRQF_DISABLED | IRQF_NOBALANCING, + .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER, .mask = CPU_MASK_ALL, }; diff --git a/arch/x86/mach-default/setup.c b/arch/x86/mach-default/setup.c index a265a7c6319..50b59187112 100644 --- a/arch/x86/mach-default/setup.c +++ b/arch/x86/mach-default/setup.c @@ -96,7 +96,7 @@ void __init trap_init_hook(void) static struct irqaction irq0 = { .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER, .mask = CPU_MASK_NONE, .name = "timer" }; diff --git a/arch/x86/mach-voyager/setup.c b/arch/x86/mach-voyager/setup.c index d914a7996a6..8e5118371f0 100644 --- a/arch/x86/mach-voyager/setup.c +++ b/arch/x86/mach-voyager/setup.c @@ -56,7 +56,7 @@ void __init trap_init_hook(void) static struct irqaction irq0 = { .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER, .mask = CPU_MASK_NONE, .name = "timer" }; -- cgit From 770824bdc421ff58a64db608294323571c949f4c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 22 Feb 2009 18:38:50 +0100 Subject: PM: Split up sysdev_[suspend|resume] from device_power_[down|up] Move the sysdev_suspend/resume from the callee to the callers, with no real change in semantics, so that we can rework the disabling of interrupts during suspend/hibernation. This is based on an earlier patch from Linus. Signed-off-by: Rafael J. Wysocki Signed-off-by: Linus Torvalds --- arch/x86/kernel/apm_32.c | 4 ++++ drivers/base/base.h | 2 -- drivers/base/power/main.c | 3 --- drivers/xen/manage.c | 8 ++++++++ include/linux/pm.h | 2 ++ kernel/kexec.c | 7 +++++++ kernel/power/disk.c | 11 +++++++++++ kernel/power/main.c | 8 ++++++-- 8 files changed, 38 insertions(+), 7 deletions(-) diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index 98807bb095a..266ec6c18b6 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c @@ -1192,6 +1192,7 @@ static int suspend(int vetoable) device_suspend(PMSG_SUSPEND); local_irq_disable(); device_power_down(PMSG_SUSPEND); + sysdev_suspend(PMSG_SUSPEND); local_irq_enable(); @@ -1208,6 +1209,7 @@ static int suspend(int vetoable) if (err != APM_SUCCESS) apm_error("suspend", err); err = (err == APM_SUCCESS) ? 0 : -EIO; + sysdev_resume(); device_power_up(PMSG_RESUME); local_irq_enable(); device_resume(PMSG_RESUME); @@ -1228,6 +1230,7 @@ static void standby(void) local_irq_disable(); device_power_down(PMSG_SUSPEND); + sysdev_suspend(PMSG_SUSPEND); local_irq_enable(); err = set_system_power_state(APM_STATE_STANDBY); @@ -1235,6 +1238,7 @@ static void standby(void) apm_error("standby", err); local_irq_disable(); + sysdev_resume(); device_power_up(PMSG_RESUME); local_irq_enable(); } diff --git a/drivers/base/base.h b/drivers/base/base.h index 0a5f055dffb..9f50f1b545d 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -88,8 +88,6 @@ extern void driver_detach(struct device_driver *drv); extern int driver_probe_device(struct device_driver *drv, struct device *dev); extern void sysdev_shutdown(void); -extern int sysdev_suspend(pm_message_t state); -extern int sysdev_resume(void); extern char *make_class_name(const char *name, struct kobject *kobj); diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 670c9d6c140..2d14f4ae6c0 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -333,7 +333,6 @@ static void dpm_power_up(pm_message_t state) */ void device_power_up(pm_message_t state) { - sysdev_resume(); dpm_power_up(state); } EXPORT_SYMBOL_GPL(device_power_up); @@ -577,8 +576,6 @@ int device_power_down(pm_message_t state) } dev->power.status = DPM_OFF_IRQ; } - if (!error) - error = sysdev_suspend(state); if (error) dpm_power_up(resume_event(state)); return error; diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 9b91617b958..56892a142ee 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -45,6 +45,13 @@ static int xen_suspend(void *data) err); return err; } + err = sysdev_suspend(PMSG_SUSPEND); + if (err) { + printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n", + err); + device_power_up(PMSG_RESUME); + return err; + } xen_mm_pin_all(); gnttab_suspend(); @@ -61,6 +68,7 @@ static int xen_suspend(void *data) gnttab_resume(); xen_mm_unpin_all(); + sysdev_resume(); device_power_up(PMSG_RESUME); if (!*cancelled) { diff --git a/include/linux/pm.h b/include/linux/pm.h index de2e0a8f672..24ba5f67b3a 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -381,10 +381,12 @@ struct dev_pm_info { #ifdef CONFIG_PM_SLEEP extern void device_pm_lock(void); +extern int sysdev_resume(void); extern void device_power_up(pm_message_t state); extern void device_resume(pm_message_t state); extern void device_pm_unlock(void); +extern int sysdev_suspend(pm_message_t state); extern int device_power_down(pm_message_t state); extern int device_suspend(pm_message_t state); extern int device_prepare_suspend(pm_message_t state); diff --git a/kernel/kexec.c b/kernel/kexec.c index 8a6d7b08864..48389957825 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -1465,6 +1465,11 @@ int kernel_kexec(void) error = device_power_down(PMSG_FREEZE); if (error) goto Enable_irqs; + + /* Suspend system devices */ + error = sysdev_suspend(PMSG_FREEZE); + if (error) + goto Power_up_devices; } else #endif { @@ -1477,6 +1482,8 @@ int kernel_kexec(void) #ifdef CONFIG_KEXEC_JUMP if (kexec_image->preserve_context) { + sysdev_resume(); + Power_up_devices: device_power_up(PMSG_RESTORE); Enable_irqs: local_irq_enable(); diff --git a/kernel/power/disk.c b/kernel/power/disk.c index 7b40e94b1d4..4a4a206b197 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c @@ -227,6 +227,12 @@ static int create_image(int platform_mode) "aborting hibernation\n"); goto Enable_irqs; } + sysdev_suspend(PMSG_FREEZE); + if (error) { + printk(KERN_ERR "PM: Some devices failed to power down, " + "aborting hibernation\n"); + goto Power_up_devices; + } if (hibernation_test(TEST_CORE)) goto Power_up; @@ -242,9 +248,11 @@ static int create_image(int platform_mode) if (!in_suspend) platform_leave(platform_mode); Power_up: + sysdev_resume(); /* NOTE: device_power_up() is just a resume() for devices * that suspended with irqs off ... no overall powerup. */ + Power_up_devices: device_power_up(in_suspend ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); Enable_irqs: @@ -335,6 +343,7 @@ static int resume_target_kernel(void) "aborting resume\n"); goto Enable_irqs; } + sysdev_suspend(PMSG_QUIESCE); /* We'll ignore saved state, but this gets preempt count (etc) right */ save_processor_state(); error = restore_highmem(); @@ -357,6 +366,7 @@ static int resume_target_kernel(void) swsusp_free(); restore_processor_state(); touch_softlockup_watchdog(); + sysdev_resume(); device_power_up(PMSG_RECOVER); Enable_irqs: local_irq_enable(); @@ -440,6 +450,7 @@ int hibernation_platform_enter(void) local_irq_disable(); error = device_power_down(PMSG_HIBERNATE); if (!error) { + sysdev_suspend(PMSG_HIBERNATE); hibernation_ops->enter(); /* We should never get here */ while (1); diff --git a/kernel/power/main.c b/kernel/power/main.c index b4d219016b6..c9632f841f6 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -298,8 +298,12 @@ static int suspend_enter(suspend_state_t state) goto Done; } - if (!suspend_test(TEST_CORE)) - error = suspend_ops->enter(state); + error = sysdev_suspend(PMSG_SUSPEND); + if (!error) { + if (!suspend_test(TEST_CORE)) + error = suspend_ops->enter(state); + sysdev_resume(); + } device_power_up(PMSG_RESUME); Done: -- cgit From 8425091ff8af2addae118fc510a523b84ce51115 Mon Sep 17 00:00:00 2001 From: Ravikiran G Thirumalai Date: Fri, 20 Feb 2009 16:59:11 -0800 Subject: x86: improve the help text of X86_EXTENDED_PLATFORM Change the CONFIG_X86_EXTENDED_PLATFORM help text to display the 32bit/64bit extended platform list. This is as suggested by Ingo. Signed-off-by: Ravikiran Thirumalai Cc: shai@scalex86.org Cc: "Benzi Galili (Benzi@ScaleMP.com)" Signed-off-by: Ingo Molnar --- arch/x86/Kconfig | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 8955262caa3..35efba546e0 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -285,6 +285,7 @@ config X86_BIGSMP ---help--- This option is needed for the systems that have more than 8 CPUs +if X86_32 config X86_EXTENDED_PLATFORM bool "Support for extended (non-PC) x86 platforms" default y @@ -293,12 +294,37 @@ config X86_EXTENDED_PLATFORM standard PC platforms. (which covers the vast majority of systems out there.) - If you enable this option then you'll be able to select a number - of non-PC x86 platforms. + If you enable this option then you'll be able to select support + for the following (non-PC) 32 bit x86 platforms: + AMD Elan + NUMAQ (IBM/Sequent) + RDC R-321x SoC + SGI 320/540 (Visual Workstation) + Summit/EXA (IBM x440) + Unisys ES7000 IA32 series + Voyager (NCR) If you have one of these systems, or if you want to build a generic distribution kernel, say Y here - otherwise say N. +endif + +if X86_64 +config X86_EXTENDED_PLATFORM + bool "Support for extended (non-PC) x86 platforms" + default y + ---help--- + If you disable this option then the kernel will only support + standard PC platforms. (which covers the vast majority of + systems out there.) + + If you enable this option then you'll be able to select support + for the following (non-PC) 64 bit x86 platforms: + ScaleMP vSMP + SGI Ultraviolet + If you have one of these systems, or if you want to build a + generic distribution kernel, say Y here - otherwise say N. +endif # This is an alphabetically sorted list of 64 bit extended platforms # Please maintain the alphabetic order if and when there are additions -- cgit From f7f84f38cd916552c175f1f3d09cb6e85c1b29fc Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 22 Feb 2009 12:15:45 -0800 Subject: docbook: split kernel-api for device-drivers The kernel-api docbook was much larger than any of the others, so processing it took longer and needed some docbook extras in some cases, so split it into kernel-api (infrastructure etc.) and device drivers/device subsystems. This allows these docbooks to be generated in parallel. (This reduced the docbook processing time on my 4-proc system with make -j4 from about 5min:16sec to about 2min:01sec.) The chapters that were moved from kernel-api to device-drivers are: Driver Basics Device drivers infrastructure Parallel Port Devices Message-based devices Sound Devices 16x50 UART Driver Frame Buffer Library Input Subsystem Serial Peripheral Interface (SPI) I2C and SMBus Subsystem Signed-off-by: Randy Dunlap Acked-by: Sam Ravnborg Signed-off-by: Linus Torvalds --- Documentation/DocBook/Makefile | 2 +- Documentation/DocBook/device-drivers.tmpl | 418 ++++++++++++++++++++++++++++++ Documentation/DocBook/kernel-api.tmpl | 377 --------------------------- 3 files changed, 419 insertions(+), 378 deletions(-) create mode 100644 Documentation/DocBook/device-drivers.tmpl diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index dc3154e4927..1462ed86d40 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile @@ -6,7 +6,7 @@ # To add a new book the only step required is to add the book to the # list of DOCBOOKS. -DOCBOOKS := z8530book.xml mcabook.xml \ +DOCBOOKS := z8530book.xml mcabook.xml device-drivers.xml \ kernel-hacking.xml kernel-locking.xml deviceiobook.xml \ procfs-guide.xml writing_usb_driver.xml networking.xml \ kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \ diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl new file mode 100644 index 00000000000..94a20fe8fed --- /dev/null +++ b/Documentation/DocBook/device-drivers.tmpl @@ -0,0 +1,418 @@ + + + + + + Linux Device Drivers + + + + This documentation is free software; you can redistribute + it and/or modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later + version. + + + + This program 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 General Public License for more details. + + + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, + MA 02111-1307 USA + + + + For more details see the file COPYING in the source + distribution of Linux. + + + + + + + + Driver Basics + Driver Entry and Exit points +!Iinclude/linux/init.h + + + Atomic and pointer manipulation +!Iarch/x86/include/asm/atomic_32.h +!Iarch/x86/include/asm/unaligned.h + + + Delaying, scheduling, and timer routines +!Iinclude/linux/sched.h +!Ekernel/sched.c +!Ekernel/timer.c + + High-resolution timers +!Iinclude/linux/ktime.h +!Iinclude/linux/hrtimer.h +!Ekernel/hrtimer.c + + Workqueues and Kevents +!Ekernel/workqueue.c + + Internal Functions +!Ikernel/exit.c +!Ikernel/signal.c +!Iinclude/linux/kthread.h +!Ekernel/kthread.c + + + Kernel objects manipulation + +!Elib/kobject.c + + + Kernel utility functions +!Iinclude/linux/kernel.h +!Ekernel/printk.c +!Ekernel/panic.c +!Ekernel/sys.c +!Ekernel/rcupdate.c + + + Device Resource Management +!Edrivers/base/devres.c + + + + + + Device drivers infrastructure + Device Drivers Base + +!Edrivers/base/driver.c +!Edrivers/base/core.c +!Edrivers/base/class.c +!Edrivers/base/firmware_class.c +!Edrivers/base/transport_class.c + +!Edrivers/base/sys.c + +!Edrivers/base/platform.c +!Edrivers/base/bus.c + + Device Drivers Power Management +!Edrivers/base/power/main.c + + Device Drivers ACPI Support + +!Edrivers/acpi/scan.c +!Idrivers/acpi/scan.c + + + Device drivers PnP support +!Idrivers/pnp/core.c + +!Edrivers/pnp/card.c +!Idrivers/pnp/driver.c +!Edrivers/pnp/manager.c +!Edrivers/pnp/support.c + + Userspace IO devices +!Edrivers/uio/uio.c +!Iinclude/linux/uio_driver.h + + + + + Parallel Port Devices +!Iinclude/linux/parport.h +!Edrivers/parport/ieee1284.c +!Edrivers/parport/share.c +!Idrivers/parport/daisy.c + + + + Message-based devices + Fusion message devices +!Edrivers/message/fusion/mptbase.c +!Idrivers/message/fusion/mptbase.c +!Edrivers/message/fusion/mptscsih.c +!Idrivers/message/fusion/mptscsih.c +!Idrivers/message/fusion/mptctl.c +!Idrivers/message/fusion/mptspi.c +!Idrivers/message/fusion/mptfc.c +!Idrivers/message/fusion/mptlan.c + + I2O message devices +!Iinclude/linux/i2o.h +!Idrivers/message/i2o/core.h +!Edrivers/message/i2o/iop.c +!Idrivers/message/i2o/iop.c +!Idrivers/message/i2o/config-osm.c +!Edrivers/message/i2o/exec-osm.c +!Idrivers/message/i2o/exec-osm.c +!Idrivers/message/i2o/bus-osm.c +!Edrivers/message/i2o/device.c +!Idrivers/message/i2o/device.c +!Idrivers/message/i2o/driver.c +!Idrivers/message/i2o/pci.c +!Idrivers/message/i2o/i2o_block.c +!Idrivers/message/i2o/i2o_scsi.c +!Idrivers/message/i2o/i2o_proc.c + + + + + Sound Devices +!Iinclude/sound/core.h +!Esound/sound_core.c +!Iinclude/sound/pcm.h +!Esound/core/pcm.c +!Esound/core/device.c +!Esound/core/info.c +!Esound/core/rawmidi.c +!Esound/core/sound.c +!Esound/core/memory.c +!Esound/core/pcm_memory.c +!Esound/core/init.c +!Esound/core/isadma.c +!Esound/core/control.c +!Esound/core/pcm_lib.c +!Esound/core/hwdep.c +!Esound/core/pcm_native.c +!Esound/core/memalloc.c + + + + + 16x50 UART Driver +!Iinclude/linux/serial_core.h +!Edrivers/serial/serial_core.c +!Edrivers/serial/8250.c + + + + Frame Buffer Library + + + The frame buffer drivers depend heavily on four data structures. + These structures are declared in include/linux/fb.h. They are + fb_info, fb_var_screeninfo, fb_fix_screeninfo and fb_monospecs. + The last three can be made available to and from userland. + + + + fb_info defines the current state of a particular video card. + Inside fb_info, there exists a fb_ops structure which is a + collection of needed functions to make fbdev and fbcon work. + fb_info is only visible to the kernel. + + + + fb_var_screeninfo is used to describe the features of a video card + that are user defined. With fb_var_screeninfo, things such as + depth and the resolution may be defined. + + + + The next structure is fb_fix_screeninfo. This defines the + properties of a card that are created when a mode is set and can't + be changed otherwise. A good example of this is the start of the + frame buffer memory. This "locks" the address of the frame buffer + memory, so that it cannot be changed or moved. + + + + The last structure is fb_monospecs. In the old API, there was + little importance for fb_monospecs. This allowed for forbidden things + such as setting a mode of 800x600 on a fix frequency monitor. With + the new API, fb_monospecs prevents such things, and if used + correctly, can prevent a monitor from being cooked. fb_monospecs + will not be useful until kernels 2.5.x. + + + Frame Buffer Memory +!Edrivers/video/fbmem.c + + + Frame Buffer Colormap +!Edrivers/video/fbcmap.c + + + Frame Buffer Video Mode Database +!Idrivers/video/modedb.c +!Edrivers/video/modedb.c + + Frame Buffer Macintosh Video Mode Database +!Edrivers/video/macmodes.c + + Frame Buffer Fonts + + Refer to the file drivers/video/console/fonts.c for more information. + + + + + + + Input Subsystem +!Iinclude/linux/input.h +!Edrivers/input/input.c +!Edrivers/input/ff-core.c +!Edrivers/input/ff-memless.c + + + + Serial Peripheral Interface (SPI) + + SPI is the "Serial Peripheral Interface", widely used with + embedded systems because it is a simple and efficient + interface: basically a multiplexed shift register. + Its three signal wires hold a clock (SCK, often in the range + of 1-20 MHz), a "Master Out, Slave In" (MOSI) data line, and + a "Master In, Slave Out" (MISO) data line. + SPI is a full duplex protocol; for each bit shifted out the + MOSI line (one per clock) another is shifted in on the MISO line. + Those bits are assembled into words of various sizes on the + way to and from system memory. + An additional chipselect line is usually active-low (nCS); + four signals are normally used for each peripheral, plus + sometimes an interrupt. + + + The SPI bus facilities listed here provide a generalized + interface to declare SPI busses and devices, manage them + according to the standard Linux driver model, and perform + input/output operations. + At this time, only "master" side interfaces are supported, + where Linux talks to SPI peripherals and does not implement + such a peripheral itself. + (Interfaces to support implementing SPI slaves would + necessarily look different.) + + + The programming interface is structured around two kinds of driver, + and two kinds of device. + A "Controller Driver" abstracts the controller hardware, which may + be as simple as a set of GPIO pins or as complex as a pair of FIFOs + connected to dual DMA engines on the other side of the SPI shift + register (maximizing throughput). Such drivers bridge between + whatever bus they sit on (often the platform bus) and SPI, and + expose the SPI side of their device as a + struct spi_master. + SPI devices are children of that master, represented as a + struct spi_device and manufactured from + struct spi_board_info descriptors which + are usually provided by board-specific initialization code. + A struct spi_driver is called a + "Protocol Driver", and is bound to a spi_device using normal + driver model calls. + + + The I/O model is a set of queued messages. Protocol drivers + submit one or more struct spi_message + objects, which are processed and completed asynchronously. + (There are synchronous wrappers, however.) Messages are + built from one or more struct spi_transfer + objects, each of which wraps a full duplex SPI transfer. + A variety of protocol tweaking options are needed, because + different chips adopt very different policies for how they + use the bits transferred with SPI. + +!Iinclude/linux/spi/spi.h +!Fdrivers/spi/spi.c spi_register_board_info +!Edrivers/spi/spi.c + + + + I<superscript>2</superscript>C and SMBus Subsystem + + + I2C (or without fancy typography, "I2C") + is an acronym for the "Inter-IC" bus, a simple bus protocol which is + widely used where low data rate communications suffice. + Since it's also a licensed trademark, some vendors use another + name (such as "Two-Wire Interface", TWI) for the same bus. + I2C only needs two signals (SCL for clock, SDA for data), conserving + board real estate and minimizing signal quality issues. + Most I2C devices use seven bit addresses, and bus speeds of up + to 400 kHz; there's a high speed extension (3.4 MHz) that's not yet + found wide use. + I2C is a multi-master bus; open drain signaling is used to + arbitrate between masters, as well as to handshake and to + synchronize clocks from slower clients. + + + + The Linux I2C programming interfaces support only the master + side of bus interactions, not the slave side. + The programming interface is structured around two kinds of driver, + and two kinds of device. + An I2C "Adapter Driver" abstracts the controller hardware; it binds + to a physical device (perhaps a PCI device or platform_device) and + exposes a struct i2c_adapter representing + each I2C bus segment it manages. + On each I2C bus segment will be I2C devices represented by a + struct i2c_client. Those devices will + be bound to a struct i2c_driver, + which should follow the standard Linux driver model. + (At this writing, a legacy model is more widely used.) + There are functions to perform various I2C protocol operations; at + this writing all such functions are usable only from task context. + + + + The System Management Bus (SMBus) is a sibling protocol. Most SMBus + systems are also I2C conformant. The electrical constraints are + tighter for SMBus, and it standardizes particular protocol messages + and idioms. Controllers that support I2C can also support most + SMBus operations, but SMBus controllers don't support all the protocol + options that an I2C controller will. + There are functions to perform various SMBus protocol operations, + either using I2C primitives or by issuing SMBus commands to + i2c_adapter devices which don't support those I2C operations. + + +!Iinclude/linux/i2c.h +!Fdrivers/i2c/i2c-boardinfo.c i2c_register_board_info +!Edrivers/i2c/i2c-core.c + + + diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl index 5818ff75786..bc962cda650 100644 --- a/Documentation/DocBook/kernel-api.tmpl +++ b/Documentation/DocBook/kernel-api.tmpl @@ -38,58 +38,6 @@ - - Driver Basics - Driver Entry and Exit points -!Iinclude/linux/init.h - - - Atomic and pointer manipulation -!Iarch/x86/include/asm/atomic_32.h -!Iarch/x86/include/asm/unaligned.h - - - Delaying, scheduling, and timer routines -!Iinclude/linux/sched.h -!Ekernel/sched.c -!Ekernel/timer.c - - High-resolution timers -!Iinclude/linux/ktime.h -!Iinclude/linux/hrtimer.h -!Ekernel/hrtimer.c - - Workqueues and Kevents -!Ekernel/workqueue.c - - Internal Functions -!Ikernel/exit.c -!Ikernel/signal.c -!Iinclude/linux/kthread.h -!Ekernel/kthread.c - - - Kernel objects manipulation - -!Elib/kobject.c - - - Kernel utility functions -!Iinclude/linux/kernel.h -!Ekernel/printk.c -!Ekernel/panic.c -!Ekernel/sys.c -!Ekernel/rcupdate.c - - - Device Resource Management -!Edrivers/base/devres.c - - - - Data Types Doubly Linked Lists @@ -298,62 +246,6 @@ X!Earch/x86/kernel/mca_32.c !Ikernel/acct.c - - Device drivers infrastructure - Device Drivers Base - -!Edrivers/base/driver.c -!Edrivers/base/core.c -!Edrivers/base/class.c -!Edrivers/base/firmware_class.c -!Edrivers/base/transport_class.c - -!Edrivers/base/sys.c - -!Edrivers/base/platform.c -!Edrivers/base/bus.c - - Device Drivers Power Management -!Edrivers/base/power/main.c - - Device Drivers ACPI Support - -!Edrivers/acpi/scan.c -!Idrivers/acpi/scan.c - - - Device drivers PnP support -!Idrivers/pnp/core.c - -!Edrivers/pnp/card.c -!Idrivers/pnp/driver.c -!Edrivers/pnp/manager.c -!Edrivers/pnp/support.c - - Userspace IO devices -!Edrivers/uio/uio.c -!Iinclude/linux/uio_driver.h - - - Block Devices !Eblock/blk-core.c @@ -381,275 +273,6 @@ X!Edrivers/pnp/system.c !Edrivers/char/misc.c - - Parallel Port Devices -!Iinclude/linux/parport.h -!Edrivers/parport/ieee1284.c -!Edrivers/parport/share.c -!Idrivers/parport/daisy.c - - - - Message-based devices - Fusion message devices -!Edrivers/message/fusion/mptbase.c -!Idrivers/message/fusion/mptbase.c -!Edrivers/message/fusion/mptscsih.c -!Idrivers/message/fusion/mptscsih.c -!Idrivers/message/fusion/mptctl.c -!Idrivers/message/fusion/mptspi.c -!Idrivers/message/fusion/mptfc.c -!Idrivers/message/fusion/mptlan.c - - I2O message devices -!Iinclude/linux/i2o.h -!Idrivers/message/i2o/core.h -!Edrivers/message/i2o/iop.c -!Idrivers/message/i2o/iop.c -!Idrivers/message/i2o/config-osm.c -!Edrivers/message/i2o/exec-osm.c -!Idrivers/message/i2o/exec-osm.c -!Idrivers/message/i2o/bus-osm.c -!Edrivers/message/i2o/device.c -!Idrivers/message/i2o/device.c -!Idrivers/message/i2o/driver.c -!Idrivers/message/i2o/pci.c -!Idrivers/message/i2o/i2o_block.c -!Idrivers/message/i2o/i2o_scsi.c -!Idrivers/message/i2o/i2o_proc.c - - - - - Sound Devices -!Iinclude/sound/core.h -!Esound/sound_core.c -!Iinclude/sound/pcm.h -!Esound/core/pcm.c -!Esound/core/device.c -!Esound/core/info.c -!Esound/core/rawmidi.c -!Esound/core/sound.c -!Esound/core/memory.c -!Esound/core/pcm_memory.c -!Esound/core/init.c -!Esound/core/isadma.c -!Esound/core/control.c -!Esound/core/pcm_lib.c -!Esound/core/hwdep.c -!Esound/core/pcm_native.c -!Esound/core/memalloc.c - - - - - 16x50 UART Driver -!Iinclude/linux/serial_core.h -!Edrivers/serial/serial_core.c -!Edrivers/serial/8250.c - - - - Frame Buffer Library - - - The frame buffer drivers depend heavily on four data structures. - These structures are declared in include/linux/fb.h. They are - fb_info, fb_var_screeninfo, fb_fix_screeninfo and fb_monospecs. - The last three can be made available to and from userland. - - - - fb_info defines the current state of a particular video card. - Inside fb_info, there exists a fb_ops structure which is a - collection of needed functions to make fbdev and fbcon work. - fb_info is only visible to the kernel. - - - - fb_var_screeninfo is used to describe the features of a video card - that are user defined. With fb_var_screeninfo, things such as - depth and the resolution may be defined. - - - - The next structure is fb_fix_screeninfo. This defines the - properties of a card that are created when a mode is set and can't - be changed otherwise. A good example of this is the start of the - frame buffer memory. This "locks" the address of the frame buffer - memory, so that it cannot be changed or moved. - - - - The last structure is fb_monospecs. In the old API, there was - little importance for fb_monospecs. This allowed for forbidden things - such as setting a mode of 800x600 on a fix frequency monitor. With - the new API, fb_monospecs prevents such things, and if used - correctly, can prevent a monitor from being cooked. fb_monospecs - will not be useful until kernels 2.5.x. - - - Frame Buffer Memory -!Edrivers/video/fbmem.c - - - Frame Buffer Colormap -!Edrivers/video/fbcmap.c - - - Frame Buffer Video Mode Database -!Idrivers/video/modedb.c -!Edrivers/video/modedb.c - - Frame Buffer Macintosh Video Mode Database -!Edrivers/video/macmodes.c - - Frame Buffer Fonts - - Refer to the file drivers/video/console/fonts.c for more information. - - - - - - - Input Subsystem -!Iinclude/linux/input.h -!Edrivers/input/input.c -!Edrivers/input/ff-core.c -!Edrivers/input/ff-memless.c - - - - Serial Peripheral Interface (SPI) - - SPI is the "Serial Peripheral Interface", widely used with - embedded systems because it is a simple and efficient - interface: basically a multiplexed shift register. - Its three signal wires hold a clock (SCK, often in the range - of 1-20 MHz), a "Master Out, Slave In" (MOSI) data line, and - a "Master In, Slave Out" (MISO) data line. - SPI is a full duplex protocol; for each bit shifted out the - MOSI line (one per clock) another is shifted in on the MISO line. - Those bits are assembled into words of various sizes on the - way to and from system memory. - An additional chipselect line is usually active-low (nCS); - four signals are normally used for each peripheral, plus - sometimes an interrupt. - - - The SPI bus facilities listed here provide a generalized - interface to declare SPI busses and devices, manage them - according to the standard Linux driver model, and perform - input/output operations. - At this time, only "master" side interfaces are supported, - where Linux talks to SPI peripherals and does not implement - such a peripheral itself. - (Interfaces to support implementing SPI slaves would - necessarily look different.) - - - The programming interface is structured around two kinds of driver, - and two kinds of device. - A "Controller Driver" abstracts the controller hardware, which may - be as simple as a set of GPIO pins or as complex as a pair of FIFOs - connected to dual DMA engines on the other side of the SPI shift - register (maximizing throughput). Such drivers bridge between - whatever bus they sit on (often the platform bus) and SPI, and - expose the SPI side of their device as a - struct spi_master. - SPI devices are children of that master, represented as a - struct spi_device and manufactured from - struct spi_board_info descriptors which - are usually provided by board-specific initialization code. - A struct spi_driver is called a - "Protocol Driver", and is bound to a spi_device using normal - driver model calls. - - - The I/O model is a set of queued messages. Protocol drivers - submit one or more struct spi_message - objects, which are processed and completed asynchronously. - (There are synchronous wrappers, however.) Messages are - built from one or more struct spi_transfer - objects, each of which wraps a full duplex SPI transfer. - A variety of protocol tweaking options are needed, because - different chips adopt very different policies for how they - use the bits transferred with SPI. - -!Iinclude/linux/spi/spi.h -!Fdrivers/spi/spi.c spi_register_board_info -!Edrivers/spi/spi.c - - - - I<superscript>2</superscript>C and SMBus Subsystem - - - I2C (or without fancy typography, "I2C") - is an acronym for the "Inter-IC" bus, a simple bus protocol which is - widely used where low data rate communications suffice. - Since it's also a licensed trademark, some vendors use another - name (such as "Two-Wire Interface", TWI) for the same bus. - I2C only needs two signals (SCL for clock, SDA for data), conserving - board real estate and minimizing signal quality issues. - Most I2C devices use seven bit addresses, and bus speeds of up - to 400 kHz; there's a high speed extension (3.4 MHz) that's not yet - found wide use. - I2C is a multi-master bus; open drain signaling is used to - arbitrate between masters, as well as to handshake and to - synchronize clocks from slower clients. - - - - The Linux I2C programming interfaces support only the master - side of bus interactions, not the slave side. - The programming interface is structured around two kinds of driver, - and two kinds of device. - An I2C "Adapter Driver" abstracts the controller hardware; it binds - to a physical device (perhaps a PCI device or platform_device) and - exposes a struct i2c_adapter representing - each I2C bus segment it manages. - On each I2C bus segment will be I2C devices represented by a - struct i2c_client. Those devices will - be bound to a struct i2c_driver, - which should follow the standard Linux driver model. - (At this writing, a legacy model is more widely used.) - There are functions to perform various I2C protocol operations; at - this writing all such functions are usable only from task context. - - - - The System Management Bus (SMBus) is a sibling protocol. Most SMBus - systems are also I2C conformant. The electrical constraints are - tighter for SMBus, and it standardizes particular protocol messages - and idioms. Controllers that support I2C can also support most - SMBus operations, but SMBus controllers don't support all the protocol - options that an I2C controller will. - There are functions to perform various SMBus protocol operations, - either using I2C primitives or by issuing SMBus commands to - i2c_adapter devices which don't support those I2C operations. - - -!Iinclude/linux/i2c.h -!Fdrivers/i2c/i2c-boardinfo.c i2c_register_board_info -!Edrivers/i2c/i2c-core.c - - Clock Framework -- cgit From 0f99fed4606dcbcbe813df831a39fd8f9653ef54 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 22 Feb 2009 22:07:03 +0100 Subject: PM: Split up sysdev_[suspend|resume] from device_power_[down|up], fix Impact: module build fix Fix: ERROR: "sysdev_resume" [arch/x86/kernel/apm.ko] undefined! ERROR: "sysdev_suspend" [arch/x86/kernel/apm.ko] undefined! As these APIs are now used by the APM driver, which can be built as a module. Also fix a few extra (and inconsistent) newlines in comment blocks preceding these functions. Signed-off-by: Ingo Molnar --- drivers/base/sys.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/base/sys.c b/drivers/base/sys.c index c98c31ec2f7..b428c8c4bc6 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c @@ -303,7 +303,6 @@ void sysdev_unregister(struct sys_device * sysdev) * is guaranteed by virtue of the fact that child devices are registered * after their parents. */ - void sysdev_shutdown(void) { struct sysdev_class * cls; @@ -363,7 +362,6 @@ static void __sysdev_resume(struct sys_device *dev) * This is only called by the device PM core, so we let them handle * all synchronization. */ - int sysdev_suspend(pm_message_t state) { struct sysdev_class * cls; @@ -432,7 +430,7 @@ aux_driver: } return ret; } - +EXPORT_SYMBOL_GPL(sysdev_suspend); /** * sysdev_resume - Bring system devices back to life. @@ -442,7 +440,6 @@ aux_driver: * * Note: Interrupts are disabled when called. */ - int sysdev_resume(void) { struct sysdev_class * cls; @@ -463,7 +460,7 @@ int sysdev_resume(void) } return 0; } - +EXPORT_SYMBOL_GPL(sysdev_resume); int __init system_bus_init(void) { -- cgit From d82ad6d6833ee8248e6c34e1b9fc3c4e61e3f035 Mon Sep 17 00:00:00 2001 From: Andrei Birjukov Date: Sun, 22 Feb 2009 22:37:21 +0000 Subject: [ARM] at91: fix for Atmel AT91 powersaving We've discovered that our AT91SAM9260 board consumed too much power when returning from a slowclock low-power mode. RAM self-refresh is enabled in a bootloader in our case, this is how we saw a difference. Estimated ca. 30mA more on 4V battery than the same state before powersaving. After a small research we found that there seems to be a bogus sdram_selfrefresh_disable() call at the end of at91_pm_enter() call, which overwrites the LPR register with uninitialized value. Please find the suggested patch attached. This patch fixes correct restoring of LPR register of the Atmel AT91 SDRAM controller when returning from a power saving mode. Signed-off-by: Andrei Birjukov Acked-by: Andrew Victor Signed-off-by: Andrew Morton Signed-off-by: Russell King --- arch/arm/mach-at91/pm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 9bb4f043aa2..7ac812dc055 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -332,7 +332,6 @@ static int at91_pm_enter(suspend_state_t state) at91_sys_read(AT91_AIC_IPR) & at91_sys_read(AT91_AIC_IMR)); error: - sdram_selfrefresh_disable(); target_state = PM_SUSPEND_ON; at91_irq_resume(); at91_gpio_resume(); -- cgit From 586c25003707067f074043d80fb2071671c58db0 Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Fri, 20 Feb 2009 16:32:55 -0500 Subject: cipso: Fix documentation comment The CIPSO protocol engine incorrectly stated that the FIPS-188 specification could be found in the kernel's Documentation directory. This patch corrects that by removing the comment and directing users to the FIPS-188 documented hosted online. For the sake of completeness I've also included a link to the CIPSO draft specification on the NetLabel website. Thanks to Randy Dunlap for spotting the error and letting me know. Signed-off-by: Paul Moore Signed-off-by: James Morris --- net/ipv4/cipso_ipv4.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 6bb2635b5de..7bc992976d2 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -3,11 +3,16 @@ * * This is an implementation of the CIPSO 2.2 protocol as specified in * draft-ietf-cipso-ipsecurity-01.txt with additional tag types as found in - * FIPS-188, copies of both documents can be found in the Documentation - * directory. While CIPSO never became a full IETF RFC standard many vendors + * FIPS-188. While CIPSO never became a full IETF RFC standard many vendors * have chosen to adopt the protocol and over the years it has become a * de-facto standard for labeled networking. * + * The CIPSO draft specification can be found in the kernel's Documentation + * directory as well as the following URL: + * http://netlabel.sourceforge.net/files/draft-ietf-cipso-ipsecurity-01.txt + * The FIPS-188 specification can be found at the following URL: + * http://www.itl.nist.gov/fipspubs/fip188.htm + * * Author: Paul Moore * */ -- cgit From 09c50b4a52c01a1f450b8eec819089e228655bfb Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Fri, 20 Feb 2009 16:33:02 -0500 Subject: selinux: Fix the NetLabel glue code for setsockopt() At some point we (okay, I) managed to break the ability for users to use the setsockopt() syscall to set IPv4 options when NetLabel was not active on the socket in question. The problem was noticed by someone trying to use the "-R" (record route) option of ping: # ping -R 10.0.0.1 ping: record route: No message of desired type The solution is relatively simple, we catch the unlabeled socket case and clear the error code, allowing the operation to succeed. Please note that we still deny users the ability to override IPv4 options on socket's which have NetLabel labeling active; this is done to ensure the labeling remains intact. Signed-off-by: Paul Moore Signed-off-by: James Morris --- security/selinux/netlabel.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index f58701a7b72..3f4b2664738 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c @@ -490,8 +490,10 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock, lock_sock(sk); rc = netlbl_sock_getattr(sk, &secattr); release_sock(sk); - if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) + if (rc == 0) rc = -EACCES; + else if (rc == -ENOMSG) + rc = 0; netlbl_secattr_destroy(&secattr); } -- cgit From 965c7ecaf2e2b083d711a01ab33735a4bdeee1a4 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 22 Feb 2009 23:19:12 +0100 Subject: x86: remove the Voyager 32-bit subarch Impact: remove unused/broken code The Voyager subarch last built successfully on the v2.6.26 kernel and has been stale since then and does not build on the v2.6.27, v2.6.28 and v2.6.29-rc5 kernels. No actual users beyond the maintainer reported this breakage. Patches were sent and most of the fixes were accepted but the discussion around how to do a few remaining issues cleanly fizzled out with no resolution and the code remained broken. In the v2.6.30 x86 tree development cycle 32-bit subarch support has been reworked and removed - and the Voyager code, beyond the build problems already known, needs serious and significant changes and probably a rewrite to support it. CONFIG_X86_VOYAGER has been marked BROKEN then. The maintainer has been notified but no patches have been sent so far to fix it. While all other subarchs have been converted to the new scheme, voyager is still broken. We'd prefer to receive patches which clean up the current situation in a constructive way, but even in case of removal there is no obstacle to add that support back after the issues have been sorted out in a mutually acceptable fashion. So remove this inactive code for now. Signed-off-by: Ingo Molnar --- arch/x86/Kconfig | 14 - arch/x86/boot/Makefile | 1 - arch/x86/boot/a20.c | 6 - arch/x86/boot/boot.h | 3 - arch/x86/boot/main.c | 5 - arch/x86/boot/voyager.c | 40 - arch/x86/configs/i386_defconfig | 1 - arch/x86/configs/x86_64_defconfig | 1 - arch/x86/include/asm/mach-voyager/do_timer.h | 17 - arch/x86/include/asm/mach-voyager/entry_arch.h | 26 - arch/x86/include/asm/mach-voyager/setup_arch.h | 12 - arch/x86/include/asm/vic.h | 61 - arch/x86/include/asm/voyager.h | 571 -------- arch/x86/lguest/Kconfig | 1 - arch/x86/mach-voyager/Makefile | 8 - arch/x86/mach-voyager/setup.c | 119 -- arch/x86/mach-voyager/voyager_basic.c | 317 ----- arch/x86/mach-voyager/voyager_cat.c | 1197 ---------------- arch/x86/mach-voyager/voyager_smp.c | 1805 ------------------------ arch/x86/mach-voyager/voyager_thread.c | 128 -- arch/x86/xen/Kconfig | 2 +- drivers/lguest/Kconfig | 2 +- 22 files changed, 2 insertions(+), 4335 deletions(-) delete mode 100644 arch/x86/boot/voyager.c delete mode 100644 arch/x86/include/asm/mach-voyager/do_timer.h delete mode 100644 arch/x86/include/asm/mach-voyager/entry_arch.h delete mode 100644 arch/x86/include/asm/mach-voyager/setup_arch.h delete mode 100644 arch/x86/include/asm/vic.h delete mode 100644 arch/x86/include/asm/voyager.h delete mode 100644 arch/x86/mach-voyager/Makefile delete mode 100644 arch/x86/mach-voyager/setup.c delete mode 100644 arch/x86/mach-voyager/voyager_basic.c delete mode 100644 arch/x86/mach-voyager/voyager_cat.c delete mode 100644 arch/x86/mach-voyager/voyager_smp.c delete mode 100644 arch/x86/mach-voyager/voyager_thread.c diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 35efba546e0..5e2919c0ff9 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -302,7 +302,6 @@ config X86_EXTENDED_PLATFORM SGI 320/540 (Visual Workstation) Summit/EXA (IBM x440) Unisys ES7000 IA32 series - Voyager (NCR) If you have one of these systems, or if you want to build a generic distribution kernel, say Y here - otherwise say N. @@ -423,19 +422,6 @@ config X86_ES7000 Support for Unisys ES7000 systems. Say 'Y' here if this kernel is supposed to run on an IA32-based Unisys ES7000 system. -config X86_VOYAGER - bool "Voyager (NCR)" - depends on SMP && !PCI && BROKEN - depends on X86_32_NON_STANDARD - ---help--- - Voyager is an MCA-based 32-way capable SMP architecture proprietary - to NCR Corp. Machine classes 345x/35xx/4100/51xx are Voyager-based. - - *** WARNING *** - - If you do not specifically know you have a Voyager based machine, - say N here, otherwise the kernel you build will not be bootable. - config SCHED_OMIT_FRAME_POINTER def_bool y prompt "Single-depth WCHAN output" diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile index cd48c721001..c70eff69a1f 100644 --- a/arch/x86/boot/Makefile +++ b/arch/x86/boot/Makefile @@ -32,7 +32,6 @@ setup-y += a20.o cmdline.o copy.o cpu.o cpucheck.o edd.o setup-y += header.o main.o mca.o memory.o pm.o pmjump.o setup-y += printf.o string.o tty.o video.o video-mode.o version.o setup-$(CONFIG_X86_APM_BOOT) += apm.o -setup-$(CONFIG_X86_VOYAGER) += voyager.o # The link order of the video-*.o modules can matter. In particular, # video-vga.o *must* be listed first, followed by video-vesa.o. diff --git a/arch/x86/boot/a20.c b/arch/x86/boot/a20.c index fba8e9c6a50..7c19ce8c244 100644 --- a/arch/x86/boot/a20.c +++ b/arch/x86/boot/a20.c @@ -126,11 +126,6 @@ static void enable_a20_fast(void) int enable_a20(void) { -#ifdef CONFIG_X86_VOYAGER - /* On Voyager, a20_test() is unsafe? */ - enable_a20_kbc(); - return 0; -#else int loops = A20_ENABLE_LOOPS; int kbc_err; @@ -164,5 +159,4 @@ int enable_a20(void) } return -1; -#endif } diff --git a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h index cc0ef13fba7..7b2692e897e 100644 --- a/arch/x86/boot/boot.h +++ b/arch/x86/boot/boot.h @@ -302,9 +302,6 @@ void probe_cards(int unsafe); /* video-vesa.c */ void vesa_store_edid(void); -/* voyager.c */ -int query_voyager(void); - #endif /* __ASSEMBLY__ */ #endif /* BOOT_BOOT_H */ diff --git a/arch/x86/boot/main.c b/arch/x86/boot/main.c index 197421db1af..58f0415d3ae 100644 --- a/arch/x86/boot/main.c +++ b/arch/x86/boot/main.c @@ -149,11 +149,6 @@ void main(void) /* Query MCA information */ query_mca(); - /* Voyager */ -#ifdef CONFIG_X86_VOYAGER - query_voyager(); -#endif - /* Query Intel SpeedStep (IST) information */ query_ist(); diff --git a/arch/x86/boot/voyager.c b/arch/x86/boot/voyager.c deleted file mode 100644 index 433909d61e5..00000000000 --- a/arch/x86/boot/voyager.c +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- linux-c -*- ------------------------------------------------------- * - * - * Copyright (C) 1991, 1992 Linus Torvalds - * Copyright 2007 rPath, Inc. - All Rights Reserved - * - * This file is part of the Linux kernel, and is made available under - * the terms of the GNU General Public License version 2. - * - * ----------------------------------------------------------------------- */ - -/* - * Get the Voyager config information - */ - -#include "boot.h" - -int query_voyager(void) -{ - u8 err; - u16 es, di; - /* Abuse the apm_bios_info area for this */ - u8 *data_ptr = (u8 *)&boot_params.apm_bios_info; - - data_ptr[0] = 0xff; /* Flag on config not found(?) */ - - asm("pushw %%es ; " - "int $0x15 ; " - "setc %0 ; " - "movw %%es, %1 ; " - "popw %%es" - : "=q" (err), "=r" (es), "=D" (di) - : "a" (0xffc0)); - - if (err) - return -1; /* Not Voyager */ - - set_fs(es); - copy_from_fs(data_ptr, di, 7); /* Table is 7 bytes apparently */ - return 0; -} diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig index 096dd5359cd..5c023f6f652 100644 --- a/arch/x86/configs/i386_defconfig +++ b/arch/x86/configs/i386_defconfig @@ -197,7 +197,6 @@ CONFIG_SPARSE_IRQ=y CONFIG_X86_FIND_SMP_CONFIG=y CONFIG_X86_MPPARSE=y # CONFIG_X86_ELAN is not set -# CONFIG_X86_VOYAGER is not set # CONFIG_X86_GENERICARCH is not set # CONFIG_X86_VSMP is not set # CONFIG_X86_RDC321X is not set diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig index 2efb5d5063f..4157cc4a2bd 100644 --- a/arch/x86/configs/x86_64_defconfig +++ b/arch/x86/configs/x86_64_defconfig @@ -199,7 +199,6 @@ CONFIG_SPARSE_IRQ=y CONFIG_X86_FIND_SMP_CONFIG=y CONFIG_X86_MPPARSE=y # CONFIG_X86_ELAN is not set -# CONFIG_X86_VOYAGER is not set # CONFIG_X86_GENERICARCH is not set # CONFIG_X86_VSMP is not set CONFIG_SCHED_OMIT_FRAME_POINTER=y diff --git a/arch/x86/include/asm/mach-voyager/do_timer.h b/arch/x86/include/asm/mach-voyager/do_timer.h deleted file mode 100644 index 9e5a459fd15..00000000000 --- a/arch/x86/include/asm/mach-voyager/do_timer.h +++ /dev/null @@ -1,17 +0,0 @@ -/* defines for inline arch setup functions */ -#include - -#include -#include - -/** - * do_timer_interrupt_hook - hook into timer tick - * - * Call the pit clock event handler. see asm/i8253.h - **/ -static inline void do_timer_interrupt_hook(void) -{ - global_clock_event->event_handler(global_clock_event); - voyager_timer_interrupt(); -} - diff --git a/arch/x86/include/asm/mach-voyager/entry_arch.h b/arch/x86/include/asm/mach-voyager/entry_arch.h deleted file mode 100644 index ae52624b593..00000000000 --- a/arch/x86/include/asm/mach-voyager/entry_arch.h +++ /dev/null @@ -1,26 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8 -*- */ - -/* Copyright (C) 2002 - * - * Author: James.Bottomley@HansenPartnership.com - * - * linux/arch/i386/voyager/entry_arch.h - * - * This file builds the VIC and QIC CPI gates - */ - -/* initialise the voyager interrupt gates - * - * This uses the macros in irq.h to set up assembly jump gates. The - * calls are then redirected to the same routine with smp_ prefixed */ -BUILD_INTERRUPT(vic_sys_interrupt, VIC_SYS_INT) -BUILD_INTERRUPT(vic_cmn_interrupt, VIC_CMN_INT) -BUILD_INTERRUPT(vic_cpi_interrupt, VIC_CPI_LEVEL0); - -/* do all the QIC interrupts */ -BUILD_INTERRUPT(qic_timer_interrupt, QIC_TIMER_CPI); -BUILD_INTERRUPT(qic_invalidate_interrupt, QIC_INVALIDATE_CPI); -BUILD_INTERRUPT(qic_reschedule_interrupt, QIC_RESCHEDULE_CPI); -BUILD_INTERRUPT(qic_enable_irq_interrupt, QIC_ENABLE_IRQ_CPI); -BUILD_INTERRUPT(qic_call_function_interrupt, QIC_CALL_FUNCTION_CPI); -BUILD_INTERRUPT(qic_call_function_single_interrupt, QIC_CALL_FUNCTION_SINGLE_CPI); diff --git a/arch/x86/include/asm/mach-voyager/setup_arch.h b/arch/x86/include/asm/mach-voyager/setup_arch.h deleted file mode 100644 index 71729ca05cd..00000000000 --- a/arch/x86/include/asm/mach-voyager/setup_arch.h +++ /dev/null @@ -1,12 +0,0 @@ -#include -#include -#define VOYAGER_BIOS_INFO ((struct voyager_bios_info *) \ - (&boot_params.apm_bios_info)) - -/* Hook to call BIOS initialisation function */ - -/* for voyager, pass the voyager BIOS/SUS info area to the detection - * routines */ - -#define ARCH_SETUP voyager_detect(VOYAGER_BIOS_INFO); - diff --git a/arch/x86/include/asm/vic.h b/arch/x86/include/asm/vic.h deleted file mode 100644 index 53100f35361..00000000000 --- a/arch/x86/include/asm/vic.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (C) 1999,2001 - * - * Author: J.E.J.Bottomley@HansenPartnership.com - * - * Standard include definitions for the NCR Voyager Interrupt Controller */ - -/* The eight CPI vectors. To activate a CPI, you write a bit mask - * corresponding to the processor set to be interrupted into the - * relevant register. That set of CPUs will then be interrupted with - * the CPI */ -static const int VIC_CPI_Registers[] = - {0xFC00, 0xFC01, 0xFC08, 0xFC09, - 0xFC10, 0xFC11, 0xFC18, 0xFC19 }; - -#define VIC_PROC_WHO_AM_I 0xfc29 -# define QUAD_IDENTIFIER 0xC0 -# define EIGHT_SLOT_IDENTIFIER 0xE0 -#define QIC_EXTENDED_PROCESSOR_SELECT 0xFC72 -#define VIC_CPI_BASE_REGISTER 0xFC41 -#define VIC_PROCESSOR_ID 0xFC21 -# define VIC_CPU_MASQUERADE_ENABLE 0x8 - -#define VIC_CLAIM_REGISTER_0 0xFC38 -#define VIC_CLAIM_REGISTER_1 0xFC39 -#define VIC_REDIRECT_REGISTER_0 0xFC60 -#define VIC_REDIRECT_REGISTER_1 0xFC61 -#define VIC_PRIORITY_REGISTER 0xFC20 - -#define VIC_PRIMARY_MC_BASE 0xFC48 -#define VIC_SECONDARY_MC_BASE 0xFC49 - -#define QIC_PROCESSOR_ID 0xFC71 -# define QIC_CPUID_ENABLE 0x08 - -#define QIC_VIC_CPI_BASE_REGISTER 0xFC79 -#define QIC_CPI_BASE_REGISTER 0xFC7A - -#define QIC_MASK_REGISTER0 0xFC80 -/* NOTE: these are masked high, enabled low */ -# define QIC_PERF_TIMER 0x01 -# define QIC_LPE 0x02 -# define QIC_SYS_INT 0x04 -# define QIC_CMN_INT 0x08 -/* at the moment, just enable CMN_INT, disable SYS_INT */ -# define QIC_DEFAULT_MASK0 (~(QIC_CMN_INT /* | VIC_SYS_INT */)) -#define QIC_MASK_REGISTER1 0xFC81 -# define QIC_BOOT_CPI_MASK 0xFE -/* Enable CPI's 1-6 inclusive */ -# define QIC_CPI_ENABLE 0x81 - -#define QIC_INTERRUPT_CLEAR0 0xFC8A -#define QIC_INTERRUPT_CLEAR1 0xFC8B - -/* this is where we place the CPI vectors */ -#define VIC_DEFAULT_CPI_BASE 0xC0 -/* this is where we place the QIC CPI vectors */ -#define QIC_DEFAULT_CPI_BASE 0xD0 - -#define VIC_BOOT_INTERRUPT_MASK 0xfe - -extern void smp_vic_timer_interrupt(void); diff --git a/arch/x86/include/asm/voyager.h b/arch/x86/include/asm/voyager.h deleted file mode 100644 index c1635d43616..00000000000 --- a/arch/x86/include/asm/voyager.h +++ /dev/null @@ -1,571 +0,0 @@ -/* Copyright (C) 1999,2001 - * - * Author: J.E.J.Bottomley@HansenPartnership.com - * - * Standard include definitions for the NCR Voyager system */ - -#undef VOYAGER_DEBUG -#undef VOYAGER_CAT_DEBUG - -#ifdef VOYAGER_DEBUG -#define VDEBUG(x) printk x -#else -#define VDEBUG(x) -#endif - -/* There are three levels of voyager machine: 3,4 and 5. The rule is - * if it's less than 3435 it's a Level 3 except for a 3360 which is - * a level 4. A 3435 or above is a Level 5 */ -#define VOYAGER_LEVEL5_AND_ABOVE 0x3435 -#define VOYAGER_LEVEL4 0x3360 - -/* The L4 DINO ASIC */ -#define VOYAGER_DINO 0x43 - -/* voyager ports in standard I/O space */ -#define VOYAGER_MC_SETUP 0x96 - - -#define VOYAGER_CAT_CONFIG_PORT 0x97 -# define VOYAGER_CAT_DESELECT 0xff -#define VOYAGER_SSPB_RELOCATION_PORT 0x98 - -/* Valid CAT controller commands */ -/* start instruction register cycle */ -#define VOYAGER_CAT_IRCYC 0x01 -/* start data register cycle */ -#define VOYAGER_CAT_DRCYC 0x02 -/* move to execute state */ -#define VOYAGER_CAT_RUN 0x0F -/* end operation */ -#define VOYAGER_CAT_END 0x80 -/* hold in idle state */ -#define VOYAGER_CAT_HOLD 0x90 -/* single step an "intest" vector */ -#define VOYAGER_CAT_STEP 0xE0 -/* return cat controller to CLEMSON mode */ -#define VOYAGER_CAT_CLEMSON 0xFF - -/* the default cat command header */ -#define VOYAGER_CAT_HEADER 0x7F - -/* the range of possible CAT module ids in the system */ -#define VOYAGER_MIN_MODULE 0x10 -#define VOYAGER_MAX_MODULE 0x1f - -/* The voyager registers per asic */ -#define VOYAGER_ASIC_ID_REG 0x00 -#define VOYAGER_ASIC_TYPE_REG 0x01 -/* the sub address registers can be made auto incrementing on reads */ -#define VOYAGER_AUTO_INC_REG 0x02 -# define VOYAGER_AUTO_INC 0x04 -# define VOYAGER_NO_AUTO_INC 0xfb -#define VOYAGER_SUBADDRDATA 0x03 -#define VOYAGER_SCANPATH 0x05 -# define VOYAGER_CONNECT_ASIC 0x01 -# define VOYAGER_DISCONNECT_ASIC 0xfe -#define VOYAGER_SUBADDRLO 0x06 -#define VOYAGER_SUBADDRHI 0x07 -#define VOYAGER_SUBMODSELECT 0x08 -#define VOYAGER_SUBMODPRESENT 0x09 - -#define VOYAGER_SUBADDR_LO 0xff -#define VOYAGER_SUBADDR_HI 0xffff - -/* the maximum size of a scan path -- used to form instructions */ -#define VOYAGER_MAX_SCAN_PATH 0x100 -/* the biggest possible register size (in bytes) */ -#define VOYAGER_MAX_REG_SIZE 4 - -/* Total number of possible modules (including submodules) */ -#define VOYAGER_MAX_MODULES 16 -/* Largest number of asics per module */ -#define VOYAGER_MAX_ASICS_PER_MODULE 7 - -/* the CAT asic of each module is always the first one */ -#define VOYAGER_CAT_ID 0 -#define VOYAGER_PSI 0x1a - -/* voyager instruction operations and registers */ -#define VOYAGER_READ_CONFIG 0x1 -#define VOYAGER_WRITE_CONFIG 0x2 -#define VOYAGER_BYPASS 0xff - -typedef struct voyager_asic { - __u8 asic_addr; /* ASIC address; Level 4 */ - __u8 asic_type; /* ASIC type */ - __u8 asic_id; /* ASIC id */ - __u8 jtag_id[4]; /* JTAG id */ - __u8 asic_location; /* Location within scan path; start w/ 0 */ - __u8 bit_location; /* Location within bit stream; start w/ 0 */ - __u8 ireg_length; /* Instruction register length */ - __u16 subaddr; /* Amount of sub address space */ - struct voyager_asic *next; /* Next asic in linked list */ -} voyager_asic_t; - -typedef struct voyager_module { - __u8 module_addr; /* Module address */ - __u8 scan_path_connected; /* Scan path connected */ - __u16 ee_size; /* Size of the EEPROM */ - __u16 num_asics; /* Number of Asics */ - __u16 inst_bits; /* Instruction bits in the scan path */ - __u16 largest_reg; /* Largest register in the scan path */ - __u16 smallest_reg; /* Smallest register in the scan path */ - voyager_asic_t *asic; /* First ASIC in scan path (CAT_I) */ - struct voyager_module *submodule; /* Submodule pointer */ - struct voyager_module *next; /* Next module in linked list */ -} voyager_module_t; - -typedef struct voyager_eeprom_hdr { - __u8 module_id[4]; - __u8 version_id; - __u8 config_id; - __u16 boundry_id; /* boundary scan id */ - __u16 ee_size; /* size of EEPROM */ - __u8 assembly[11]; /* assembly # */ - __u8 assembly_rev; /* assembly rev */ - __u8 tracer[4]; /* tracer number */ - __u16 assembly_cksum; /* asm checksum */ - __u16 power_consump; /* pwr requirements */ - __u16 num_asics; /* number of asics */ - __u16 bist_time; /* min. bist time */ - __u16 err_log_offset; /* error log offset */ - __u16 scan_path_offset;/* scan path offset */ - __u16 cct_offset; - __u16 log_length; /* length of err log */ - __u16 xsum_end; /* offset to end of - checksum */ - __u8 reserved[4]; - __u8 sflag; /* starting sentinal */ - __u8 part_number[13]; /* prom part number */ - __u8 version[10]; /* version number */ - __u8 signature[8]; - __u16 eeprom_chksum; - __u32 data_stamp_offset; - __u8 eflag ; /* ending sentinal */ -} __attribute__((packed)) voyager_eprom_hdr_t; - - - -#define VOYAGER_EPROM_SIZE_OFFSET \ - ((__u16)(&(((voyager_eprom_hdr_t *)0)->ee_size))) -#define VOYAGER_XSUM_END_OFFSET 0x2a - -/* the following three definitions are for internal table layouts - * in the module EPROMs. We really only care about the IDs and - * offsets */ -typedef struct voyager_sp_table { - __u8 asic_id; - __u8 bypass_flag; - __u16 asic_data_offset; - __u16 config_data_offset; -} __attribute__((packed)) voyager_sp_table_t; - -typedef struct voyager_jtag_table { - __u8 icode[4]; - __u8 runbist[4]; - __u8 intest[4]; - __u8 samp_preld[4]; - __u8 ireg_len; -} __attribute__((packed)) voyager_jtt_t; - -typedef struct voyager_asic_data_table { - __u8 jtag_id[4]; - __u16 length_bsr; - __u16 length_bist_reg; - __u32 bist_clk; - __u16 subaddr_bits; - __u16 seed_bits; - __u16 sig_bits; - __u16 jtag_offset; -} __attribute__((packed)) voyager_at_t; - -/* Voyager Interrupt Controller (VIC) registers */ - -/* Base to add to Cross Processor Interrupts (CPIs) when triggering - * the CPU IRQ line */ -/* register defines for the WCBICs (one per processor) */ -#define VOYAGER_WCBIC0 0x41 /* bus A node P1 processor 0 */ -#define VOYAGER_WCBIC1 0x49 /* bus A node P1 processor 1 */ -#define VOYAGER_WCBIC2 0x51 /* bus A node P2 processor 0 */ -#define VOYAGER_WCBIC3 0x59 /* bus A node P2 processor 1 */ -#define VOYAGER_WCBIC4 0x61 /* bus B node P1 processor 0 */ -#define VOYAGER_WCBIC5 0x69 /* bus B node P1 processor 1 */ -#define VOYAGER_WCBIC6 0x71 /* bus B node P2 processor 0 */ -#define VOYAGER_WCBIC7 0x79 /* bus B node P2 processor 1 */ - - -/* top of memory registers */ -#define VOYAGER_WCBIC_TOM_L 0x4 -#define VOYAGER_WCBIC_TOM_H 0x5 - -/* register defines for Voyager Memory Contol (VMC) - * these are present on L4 machines only */ -#define VOYAGER_VMC1 0x81 -#define VOYAGER_VMC2 0x91 -#define VOYAGER_VMC3 0xa1 -#define VOYAGER_VMC4 0xb1 - -/* VMC Ports */ -#define VOYAGER_VMC_MEMORY_SETUP 0x9 -# define VMC_Interleaving 0x01 -# define VMC_4Way 0x02 -# define VMC_EvenCacheLines 0x04 -# define VMC_HighLine 0x08 -# define VMC_Start0_Enable 0x20 -# define VMC_Start1_Enable 0x40 -# define VMC_Vremap 0x80 -#define VOYAGER_VMC_BANK_DENSITY 0xa -# define VMC_BANK_EMPTY 0 -# define VMC_BANK_4MB 1 -# define VMC_BANK_16MB 2 -# define VMC_BANK_64MB 3 -# define VMC_BANK0_MASK 0x03 -# define VMC_BANK1_MASK 0x0C -# define VMC_BANK2_MASK 0x30 -# define VMC_BANK3_MASK 0xC0 - -/* Magellan Memory Controller (MMC) defines - present on L5 */ -#define VOYAGER_MMC_ASIC_ID 1 -/* the two memory modules corresponding to memory cards in the system */ -#define VOYAGER_MMC_MEMORY0_MODULE 0x14 -#define VOYAGER_MMC_MEMORY1_MODULE 0x15 -/* the Magellan Memory Address (MMA) defines */ -#define VOYAGER_MMA_ASIC_ID 2 - -/* Submodule number for the Quad Baseboard */ -#define VOYAGER_QUAD_BASEBOARD 1 - -/* ASIC defines for the Quad Baseboard */ -#define VOYAGER_QUAD_QDATA0 1 -#define VOYAGER_QUAD_QDATA1 2 -#define VOYAGER_QUAD_QABC 3 - -/* Useful areas in extended CMOS */ -#define VOYAGER_PROCESSOR_PRESENT_MASK 0x88a -#define VOYAGER_MEMORY_CLICKMAP 0xa23 -#define VOYAGER_DUMP_LOCATION 0xb1a - -/* SUS In Control bit - used to tell SUS that we don't need to be - * babysat anymore */ -#define VOYAGER_SUS_IN_CONTROL_PORT 0x3ff -# define VOYAGER_IN_CONTROL_FLAG 0x80 - -/* Voyager PSI defines */ -#define VOYAGER_PSI_STATUS_REG 0x08 -# define PSI_DC_FAIL 0x01 -# define PSI_MON 0x02 -# define PSI_FAULT 0x04 -# define PSI_ALARM 0x08 -# define PSI_CURRENT 0x10 -# define PSI_DVM 0x20 -# define PSI_PSCFAULT 0x40 -# define PSI_STAT_CHG 0x80 - -#define VOYAGER_PSI_SUPPLY_REG 0x8000 - /* read */ -# define PSI_FAIL_DC 0x01 -# define PSI_FAIL_AC 0x02 -# define PSI_MON_INT 0x04 -# define PSI_SWITCH_OFF 0x08 -# define PSI_HX_OFF 0x10 -# define PSI_SECURITY 0x20 -# define PSI_CMOS_BATT_LOW 0x40 -# define PSI_CMOS_BATT_FAIL 0x80 - /* write */ -# define PSI_CLR_SWITCH_OFF 0x13 -# define PSI_CLR_HX_OFF 0x14 -# define PSI_CLR_CMOS_BATT_FAIL 0x17 - -#define VOYAGER_PSI_MASK 0x8001 -# define PSI_MASK_MASK 0x10 - -#define VOYAGER_PSI_AC_FAIL_REG 0x8004 -#define AC_FAIL_STAT_CHANGE 0x80 - -#define VOYAGER_PSI_GENERAL_REG 0x8007 - /* read */ -# define PSI_SWITCH_ON 0x01 -# define PSI_SWITCH_ENABLED 0x02 -# define PSI_ALARM_ENABLED 0x08 -# define PSI_SECURE_ENABLED 0x10 -# define PSI_COLD_RESET 0x20 -# define PSI_COLD_START 0x80 - /* write */ -# define PSI_POWER_DOWN 0x10 -# define PSI_SWITCH_DISABLE 0x01 -# define PSI_SWITCH_ENABLE 0x11 -# define PSI_CLEAR 0x12 -# define PSI_ALARM_DISABLE 0x03 -# define PSI_ALARM_ENABLE 0x13 -# define PSI_CLEAR_COLD_RESET 0x05 -# define PSI_SET_COLD_RESET 0x15 -# define PSI_CLEAR_COLD_START 0x07 -# define PSI_SET_COLD_START 0x17 - - - -struct voyager_bios_info { - __u8 len; - __u8 major; - __u8 minor; - __u8 debug; - __u8 num_classes; - __u8 class_1; - __u8 class_2; -}; - -/* The following structures and definitions are for the Kernel/SUS - * interface these are needed to find out how SUS initialised any Quad - * boards in the system */ - -#define NUMBER_OF_MC_BUSSES 2 -#define SLOTS_PER_MC_BUS 8 -#define MAX_CPUS 16 /* 16 way CPU system */ -#define MAX_PROCESSOR_BOARDS 4 /* 4 processor slot system */ -#define MAX_CACHE_LEVELS 4 /* # of cache levels supported */ -#define MAX_SHARED_CPUS 4 /* # of CPUs that can share a LARC */ -#define NUMBER_OF_POS_REGS 8 - -typedef struct { - __u8 MC_Slot; - __u8 POS_Values[NUMBER_OF_POS_REGS]; -} __attribute__((packed)) MC_SlotInformation_t; - -struct QuadDescription { - __u8 Type; /* for type 0 (DYADIC or MONADIC) all fields - * will be zero except for slot */ - __u8 StructureVersion; - __u32 CPI_BaseAddress; - __u32 LARC_BankSize; - __u32 LocalMemoryStateBits; - __u8 Slot; /* Processor slots 1 - 4 */ -} __attribute__((packed)); - -struct ProcBoardInfo { - __u8 Type; - __u8 StructureVersion; - __u8 NumberOfBoards; - struct QuadDescription QuadData[MAX_PROCESSOR_BOARDS]; -} __attribute__((packed)); - -struct CacheDescription { - __u8 Level; - __u32 TotalSize; - __u16 LineSize; - __u8 Associativity; - __u8 CacheType; - __u8 WriteType; - __u8 Number_CPUs_SharedBy; - __u8 Shared_CPUs_Hardware_IDs[MAX_SHARED_CPUS]; - -} __attribute__((packed)); - -struct CPU_Description { - __u8 CPU_HardwareId; - char *FRU_String; - __u8 NumberOfCacheLevels; - struct CacheDescription CacheLevelData[MAX_CACHE_LEVELS]; -} __attribute__((packed)); - -struct CPU_Info { - __u8 Type; - __u8 StructureVersion; - __u8 NumberOf_CPUs; - struct CPU_Description CPU_Data[MAX_CPUS]; -} __attribute__((packed)); - - -/* - * This structure will be used by SUS and the OS. - * The assumption about this structure is that no blank space is - * packed in it by our friend the compiler. - */ -typedef struct { - __u8 Mailbox_SUS; /* Written to by SUS to give - commands/response to the OS */ - __u8 Mailbox_OS; /* Written to by the OS to give - commands/response to SUS */ - __u8 SUS_MailboxVersion; /* Tells the OS which iteration of the - interface SUS supports */ - __u8 OS_MailboxVersion; /* Tells SUS which iteration of the - interface the OS supports */ - __u32 OS_Flags; /* Flags set by the OS as info for - SUS */ - __u32 SUS_Flags; /* Flags set by SUS as info - for the OS */ - __u32 WatchDogPeriod; /* Watchdog period (in seconds) which - the DP uses to see if the OS - is dead */ - __u32 WatchDogCount; /* Updated by the OS on every tic. */ - __u32 MemoryFor_SUS_ErrorLog; /* Flat 32 bit address which tells SUS - where to stuff the SUS error log - on a dump */ - MC_SlotInformation_t MC_SlotInfo[NUMBER_OF_MC_BUSSES*SLOTS_PER_MC_BUS]; - /* Storage for MCA POS data */ - /* All new SECOND_PASS_INTERFACE fields added from this point */ - struct ProcBoardInfo *BoardData; - struct CPU_Info *CPU_Data; - /* All new fields must be added from this point */ -} Voyager_KernelSUS_Mbox_t; - -/* structure for finding the right memory address to send a QIC CPI to */ -struct voyager_qic_cpi { - /* Each cache line (32 bytes) can trigger a cpi. The cpi - * read/write may occur anywhere in the cache line---pick the - * middle to be safe */ - struct { - __u32 pad1[3]; - __u32 cpi; - __u32 pad2[4]; - } qic_cpi[8]; -}; - -struct voyager_status { - __u32 power_fail:1; - __u32 switch_off:1; - __u32 request_from_kernel:1; -}; - -struct voyager_psi_regs { - __u8 cat_id; - __u8 cat_dev; - __u8 cat_control; - __u8 subaddr; - __u8 dummy4; - __u8 checkbit; - __u8 subaddr_low; - __u8 subaddr_high; - __u8 intstatus; - __u8 stat1; - __u8 stat3; - __u8 fault; - __u8 tms; - __u8 gen; - __u8 sysconf; - __u8 dummy15; -}; - -struct voyager_psi_subregs { - __u8 supply; - __u8 mask; - __u8 present; - __u8 DCfail; - __u8 ACfail; - __u8 fail; - __u8 UPSfail; - __u8 genstatus; -}; - -struct voyager_psi { - struct voyager_psi_regs regs; - struct voyager_psi_subregs subregs; -}; - -struct voyager_SUS { -#define VOYAGER_DUMP_BUTTON_NMI 0x1 -#define VOYAGER_SUS_VALID 0x2 -#define VOYAGER_SYSINT_COMPLETE 0x3 - __u8 SUS_mbox; -#define VOYAGER_NO_COMMAND 0x0 -#define VOYAGER_IGNORE_DUMP 0x1 -#define VOYAGER_DO_DUMP 0x2 -#define VOYAGER_SYSINT_HANDSHAKE 0x3 -#define VOYAGER_DO_MEM_DUMP 0x4 -#define VOYAGER_SYSINT_WAS_RECOVERED 0x5 - __u8 kernel_mbox; -#define VOYAGER_MAILBOX_VERSION 0x10 - __u8 SUS_version; - __u8 kernel_version; -#define VOYAGER_OS_HAS_SYSINT 0x1 -#define VOYAGER_OS_IN_PROGRESS 0x2 -#define VOYAGER_UPDATING_WDPERIOD 0x4 - __u32 kernel_flags; -#define VOYAGER_SUS_BOOTING 0x1 -#define VOYAGER_SUS_IN_PROGRESS 0x2 - __u32 SUS_flags; - __u32 watchdog_period; - __u32 watchdog_count; - __u32 SUS_errorlog; - /* lots of system configuration stuff under here */ -}; - -/* Variables exported by voyager_smp */ -extern __u32 voyager_extended_vic_processors; -extern __u32 voyager_allowed_boot_processors; -extern __u32 voyager_quad_processors; -extern struct voyager_qic_cpi *voyager_quad_cpi_addr[NR_CPUS]; -extern struct voyager_SUS *voyager_SUS; - -/* variables exported always */ -extern struct task_struct *voyager_thread; -extern int voyager_level; -extern struct voyager_status voyager_status; - -/* functions exported by the voyager and voyager_smp modules */ -extern int voyager_cat_readb(__u8 module, __u8 asic, int reg); -extern void voyager_cat_init(void); -extern void voyager_detect(struct voyager_bios_info *); -extern void voyager_trap_init(void); -extern void voyager_setup_irqs(void); -extern int voyager_memory_detect(int region, __u32 *addr, __u32 *length); -extern void voyager_smp_intr_init(void); -extern __u8 voyager_extended_cmos_read(__u16 cmos_address); -extern void voyager_smp_dump(void); -extern void voyager_timer_interrupt(void); -extern void smp_local_timer_interrupt(void); -extern void voyager_power_off(void); -extern void smp_voyager_power_off(void *dummy); -extern void voyager_restart(void); -extern void voyager_cat_power_off(void); -extern void voyager_cat_do_common_interrupt(void); -extern void voyager_handle_nmi(void); -extern void voyager_smp_intr_init(void); -/* Commands for the following are */ -#define VOYAGER_PSI_READ 0 -#define VOYAGER_PSI_WRITE 1 -#define VOYAGER_PSI_SUBREAD 2 -#define VOYAGER_PSI_SUBWRITE 3 -extern void voyager_cat_psi(__u8, __u16, __u8 *); - -/* These define the CPIs we use in linux */ -#define VIC_CPI_LEVEL0 0 -#define VIC_CPI_LEVEL1 1 -/* now the fake CPIs */ -#define VIC_TIMER_CPI 2 -#define VIC_INVALIDATE_CPI 3 -#define VIC_RESCHEDULE_CPI 4 -#define VIC_ENABLE_IRQ_CPI 5 -#define VIC_CALL_FUNCTION_CPI 6 -#define VIC_CALL_FUNCTION_SINGLE_CPI 7 - -/* Now the QIC CPIs: Since we don't need the two initial levels, - * these are 2 less than the VIC CPIs */ -#define QIC_CPI_OFFSET 1 -#define QIC_TIMER_CPI (VIC_TIMER_CPI - QIC_CPI_OFFSET) -#define QIC_INVALIDATE_CPI (VIC_INVALIDATE_CPI - QIC_CPI_OFFSET) -#define QIC_RESCHEDULE_CPI (VIC_RESCHEDULE_CPI - QIC_CPI_OFFSET) -#define QIC_ENABLE_IRQ_CPI (VIC_ENABLE_IRQ_CPI - QIC_CPI_OFFSET) -#define QIC_CALL_FUNCTION_CPI (VIC_CALL_FUNCTION_CPI - QIC_CPI_OFFSET) -#define QIC_CALL_FUNCTION_SINGLE_CPI (VIC_CALL_FUNCTION_SINGLE_CPI - QIC_CPI_OFFSET) - -#define VIC_START_FAKE_CPI VIC_TIMER_CPI -#define VIC_END_FAKE_CPI VIC_CALL_FUNCTION_SINGLE_CPI - -/* this is the SYS_INT CPI. */ -#define VIC_SYS_INT 8 -#define VIC_CMN_INT 15 - -/* This is the boot CPI for alternate processors. It gets overwritten - * by the above once the system has activated all available processors */ -#define VIC_CPU_BOOT_CPI VIC_CPI_LEVEL0 -#define VIC_CPU_BOOT_ERRATA_CPI (VIC_CPI_LEVEL0 + 8) - -extern asmlinkage void vic_cpi_interrupt(void); -extern asmlinkage void vic_sys_interrupt(void); -extern asmlinkage void vic_cmn_interrupt(void); -extern asmlinkage void qic_timer_interrupt(void); -extern asmlinkage void qic_invalidate_interrupt(void); -extern asmlinkage void qic_reschedule_interrupt(void); -extern asmlinkage void qic_enable_irq_interrupt(void); -extern asmlinkage void qic_call_function_interrupt(void); diff --git a/arch/x86/lguest/Kconfig b/arch/x86/lguest/Kconfig index c70e12b1a63..8dab8f7844d 100644 --- a/arch/x86/lguest/Kconfig +++ b/arch/x86/lguest/Kconfig @@ -3,7 +3,6 @@ config LGUEST_GUEST select PARAVIRT depends on X86_32 depends on !X86_PAE - depends on !X86_VOYAGER select VIRTIO select VIRTIO_RING select VIRTIO_CONSOLE diff --git a/arch/x86/mach-voyager/Makefile b/arch/x86/mach-voyager/Makefile deleted file mode 100644 index 15c250b371d..00000000000 --- a/arch/x86/mach-voyager/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Makefile for the linux kernel. -# - -EXTRA_CFLAGS := -Iarch/x86/kernel -obj-y := setup.o voyager_basic.o voyager_thread.o - -obj-$(CONFIG_SMP) += voyager_smp.o voyager_cat.o diff --git a/arch/x86/mach-voyager/setup.c b/arch/x86/mach-voyager/setup.c deleted file mode 100644 index 88c3c555634..00000000000 --- a/arch/x86/mach-voyager/setup.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Machine specific setup for generic - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -void __init pre_intr_init_hook(void) -{ - init_ISA_irqs(); -} - -/* - * IRQ2 is cascade interrupt to second interrupt controller - */ -static struct irqaction irq2 = { - .handler = no_action, - .mask = CPU_MASK_NONE, - .name = "cascade", -}; - -void __init intr_init_hook(void) -{ -#ifdef CONFIG_SMP - voyager_smp_intr_init(); -#endif - - setup_irq(2, &irq2); -} - -static void voyager_disable_tsc(void) -{ - /* Voyagers run their CPUs from independent clocks, so disable - * the TSC code because we can't sync them */ - setup_clear_cpu_cap(X86_FEATURE_TSC); -} - -void __init pre_setup_arch_hook(void) -{ - voyager_disable_tsc(); -} - -void __init pre_time_init_hook(void) -{ - voyager_disable_tsc(); -} - -void __init trap_init_hook(void) -{ -} - -static struct irqaction irq0 = { - .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER, - .mask = CPU_MASK_NONE, - .name = "timer" -}; - -void __init time_init_hook(void) -{ - irq0.mask = cpumask_of_cpu(safe_smp_processor_id()); - setup_irq(0, &irq0); -} - -/* Hook for machine specific memory setup. */ - -char *__init machine_specific_memory_setup(void) -{ - char *who; - int new_nr; - - who = "NOT VOYAGER"; - - if (voyager_level == 5) { - __u32 addr, length; - int i; - - who = "Voyager-SUS"; - - e820.nr_map = 0; - for (i = 0; voyager_memory_detect(i, &addr, &length); i++) { - e820_add_region(addr, length, E820_RAM); - } - return who; - } else if (voyager_level == 4) { - __u32 tom; - __u16 catbase = inb(VOYAGER_SSPB_RELOCATION_PORT) << 8; - /* select the DINO config space */ - outb(VOYAGER_DINO, VOYAGER_CAT_CONFIG_PORT); - /* Read DINO top of memory register */ - tom = ((inb(catbase + 0x4) & 0xf0) << 16) - + ((inb(catbase + 0x5) & 0x7f) << 24); - - if (inb(catbase) != VOYAGER_DINO) { - printk(KERN_ERR - "Voyager: Failed to get DINO for L4, setting tom to EXT_MEM_K\n"); - tom = (boot_params.screen_info.ext_mem_k) << 10; - } - who = "Voyager-TOM"; - e820_add_region(0, 0x9f000, E820_RAM); - /* map from 1M to top of memory */ - e820_add_region(1 * 1024 * 1024, tom - 1 * 1024 * 1024, - E820_RAM); - /* FIXME: Should check the ASICs to see if I need to - * take out the 8M window. Just do it at the moment - * */ - e820_add_region(8 * 1024 * 1024, 8 * 1024 * 1024, - E820_RESERVED); - return who; - } - - return default_machine_specific_memory_setup(); -} diff --git a/arch/x86/mach-voyager/voyager_basic.c b/arch/x86/mach-voyager/voyager_basic.c deleted file mode 100644 index 46d6f806769..00000000000 --- a/arch/x86/mach-voyager/voyager_basic.c +++ /dev/null @@ -1,317 +0,0 @@ -/* Copyright (C) 1999,2001 - * - * Author: J.E.J.Bottomley@HansenPartnership.com - * - * This file contains all the voyager specific routines for getting - * initialisation of the architecture to function. For additional - * features see: - * - * voyager_cat.c - Voyager CAT bus interface - * voyager_smp.c - Voyager SMP hal (emulates linux smp.c) - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Power off function, if any - */ -void (*pm_power_off) (void); -EXPORT_SYMBOL(pm_power_off); - -int voyager_level = 0; - -struct voyager_SUS *voyager_SUS = NULL; - -#ifdef CONFIG_SMP -static void voyager_dump(int dummy1, struct tty_struct *dummy3) -{ - /* get here via a sysrq */ - voyager_smp_dump(); -} - -static struct sysrq_key_op sysrq_voyager_dump_op = { - .handler = voyager_dump, - .help_msg = "Voyager", - .action_msg = "Dump Voyager Status", -}; -#endif - -void voyager_detect(struct voyager_bios_info *bios) -{ - if (bios->len != 0xff) { - int class = (bios->class_1 << 8) - | (bios->class_2 & 0xff); - - printk("Voyager System detected.\n" - " Class %x, Revision %d.%d\n", - class, bios->major, bios->minor); - if (class == VOYAGER_LEVEL4) - voyager_level = 4; - else if (class < VOYAGER_LEVEL5_AND_ABOVE) - voyager_level = 3; - else - voyager_level = 5; - printk(" Architecture Level %d\n", voyager_level); - if (voyager_level < 4) - printk - ("\n**WARNING**: Voyager HAL only supports Levels 4 and 5 Architectures at the moment\n\n"); - /* install the power off handler */ - pm_power_off = voyager_power_off; -#ifdef CONFIG_SMP - register_sysrq_key('v', &sysrq_voyager_dump_op); -#endif - } else { - printk("\n\n**WARNING**: No Voyager Subsystem Found\n"); - } -} - -void voyager_system_interrupt(int cpl, void *dev_id) -{ - printk("Voyager: detected system interrupt\n"); -} - -/* Routine to read information from the extended CMOS area */ -__u8 voyager_extended_cmos_read(__u16 addr) -{ - outb(addr & 0xff, 0x74); - outb((addr >> 8) & 0xff, 0x75); - return inb(0x76); -} - -/* internal definitions for the SUS Click Map of memory */ - -#define CLICK_ENTRIES 16 -#define CLICK_SIZE 4096 /* click to byte conversion for Length */ - -typedef struct ClickMap { - struct Entry { - __u32 Address; - __u32 Length; - } Entry[CLICK_ENTRIES]; -} ClickMap_t; - -/* This routine is pretty much an awful hack to read the bios clickmap by - * mapping it into page 0. There are usually three regions in the map: - * Base Memory - * Extended Memory - * zero length marker for end of map - * - * Returns are 0 for failure and 1 for success on extracting region. - */ -int __init voyager_memory_detect(int region, __u32 * start, __u32 * length) -{ - int i; - int retval = 0; - __u8 cmos[4]; - ClickMap_t *map; - unsigned long map_addr; - unsigned long old; - - if (region >= CLICK_ENTRIES) { - printk("Voyager: Illegal ClickMap region %d\n", region); - return 0; - } - - for (i = 0; i < sizeof(cmos); i++) - cmos[i] = - voyager_extended_cmos_read(VOYAGER_MEMORY_CLICKMAP + i); - - map_addr = *(unsigned long *)cmos; - - /* steal page 0 for this */ - old = pg0[0]; - pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT); - local_flush_tlb(); - /* now clear everything out but page 0 */ - map = (ClickMap_t *) (map_addr & (~PAGE_MASK)); - - /* zero length is the end of the clickmap */ - if (map->Entry[region].Length != 0) { - *length = map->Entry[region].Length * CLICK_SIZE; - *start = map->Entry[region].Address; - retval = 1; - } - - /* replace the mapping */ - pg0[0] = old; - local_flush_tlb(); - return retval; -} - -/* voyager specific handling code for timer interrupts. Used to hand - * off the timer tick to the SMP code, since the VIC doesn't have an - * internal timer (The QIC does, but that's another story). */ -void voyager_timer_interrupt(void) -{ - if ((jiffies & 0x3ff) == 0) { - - /* There seems to be something flaky in either - * hardware or software that is resetting the timer 0 - * count to something much higher than it should be - * This seems to occur in the boot sequence, just - * before root is mounted. Therefore, every 10 - * seconds or so, we sanity check the timer zero count - * and kick it back to where it should be. - * - * FIXME: This is the most awful hack yet seen. I - * should work out exactly what is interfering with - * the timer count settings early in the boot sequence - * and swiftly introduce it to something sharp and - * pointy. */ - __u16 val; - - spin_lock(&i8253_lock); - - outb_p(0x00, 0x43); - val = inb_p(0x40); - val |= inb(0x40) << 8; - spin_unlock(&i8253_lock); - - if (val > LATCH) { - printk - ("\nVOYAGER: countdown timer value too high (%d), resetting\n\n", - val); - spin_lock(&i8253_lock); - outb(0x34, 0x43); - outb_p(LATCH & 0xff, 0x40); /* LSB */ - outb(LATCH >> 8, 0x40); /* MSB */ - spin_unlock(&i8253_lock); - } - } -#ifdef CONFIG_SMP - smp_vic_timer_interrupt(); -#endif -} - -void voyager_power_off(void) -{ - printk("VOYAGER Power Off\n"); - - if (voyager_level == 5) { - voyager_cat_power_off(); - } else if (voyager_level == 4) { - /* This doesn't apparently work on most L4 machines, - * but the specs say to do this to get automatic power - * off. Unfortunately, if it doesn't power off the - * machine, it ends up doing a cold restart, which - * isn't really intended, so comment out the code */ -#if 0 - int port; - - /* enable the voyager Configuration Space */ - outb((inb(VOYAGER_MC_SETUP) & 0xf0) | 0x8, VOYAGER_MC_SETUP); - /* the port for the power off flag is an offset from the - floating base */ - port = (inb(VOYAGER_SSPB_RELOCATION_PORT) << 8) + 0x21; - /* set the power off flag */ - outb(inb(port) | 0x1, port); -#endif - } - /* and wait for it to happen */ - local_irq_disable(); - for (;;) - halt(); -} - -/* copied from process.c */ -static inline void kb_wait(void) -{ - int i; - - for (i = 0; i < 0x10000; i++) - if ((inb_p(0x64) & 0x02) == 0) - break; -} - -void machine_shutdown(void) -{ - /* Architecture specific shutdown needed before a kexec */ -} - -void machine_restart(char *cmd) -{ - printk("Voyager Warm Restart\n"); - kb_wait(); - - if (voyager_level == 5) { - /* write magic values to the RTC to inform system that - * shutdown is beginning */ - outb(0x8f, 0x70); - outb(0x5, 0x71); - - udelay(50); - outb(0xfe, 0x64); /* pull reset low */ - } else if (voyager_level == 4) { - __u16 catbase = inb(VOYAGER_SSPB_RELOCATION_PORT) << 8; - __u8 basebd = inb(VOYAGER_MC_SETUP); - - outb(basebd | 0x08, VOYAGER_MC_SETUP); - outb(0x02, catbase + 0x21); - } - local_irq_disable(); - for (;;) - halt(); -} - -void machine_emergency_restart(void) -{ - /*for now, just hook this to a warm restart */ - machine_restart(NULL); -} - -void mca_nmi_hook(void) -{ - __u8 dumpval __maybe_unused = inb(0xf823); - __u8 swnmi __maybe_unused = inb(0xf813); - - /* FIXME: assume dump switch pressed */ - /* check to see if the dump switch was pressed */ - VDEBUG(("VOYAGER: dumpval = 0x%x, swnmi = 0x%x\n", dumpval, swnmi)); - /* clear swnmi */ - outb(0xff, 0xf813); - /* tell SUS to ignore dump */ - if (voyager_level == 5 && voyager_SUS != NULL) { - if (voyager_SUS->SUS_mbox == VOYAGER_DUMP_BUTTON_NMI) { - voyager_SUS->kernel_mbox = VOYAGER_NO_COMMAND; - voyager_SUS->kernel_flags |= VOYAGER_OS_IN_PROGRESS; - udelay(1000); - voyager_SUS->kernel_mbox = VOYAGER_IGNORE_DUMP; - voyager_SUS->kernel_flags &= ~VOYAGER_OS_IN_PROGRESS; - } - } - printk(KERN_ERR - "VOYAGER: Dump switch pressed, printing CPU%d tracebacks\n", - smp_processor_id()); - show_stack(NULL, NULL); - show_state(); -} - -void machine_halt(void) -{ - /* treat a halt like a power off */ - machine_power_off(); -} - -void machine_power_off(void) -{ - if (pm_power_off) - pm_power_off(); -} diff --git a/arch/x86/mach-voyager/voyager_cat.c b/arch/x86/mach-voyager/voyager_cat.c deleted file mode 100644 index 2ad598c104a..00000000000 --- a/arch/x86/mach-voyager/voyager_cat.c +++ /dev/null @@ -1,1197 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8 -*- */ - -/* Copyright (C) 1999,2001 - * - * Author: J.E.J.Bottomley@HansenPartnership.com - * - * This file contains all the logic for manipulating the CAT bus - * in a level 5 machine. - * - * The CAT bus is a serial configuration and test bus. Its primary - * uses are to probe the initial configuration of the system and to - * diagnose error conditions when a system interrupt occurs. The low - * level interface is fairly primitive, so most of this file consists - * of bit shift manipulations to send and receive packets on the - * serial bus */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef VOYAGER_CAT_DEBUG -#define CDEBUG(x) printk x -#else -#define CDEBUG(x) -#endif - -/* the CAT command port */ -#define CAT_CMD (sspb + 0xe) -/* the CAT data port */ -#define CAT_DATA (sspb + 0xd) - -/* the internal cat functions */ -static void cat_pack(__u8 * msg, __u16 start_bit, __u8 * data, __u16 num_bits); -static void cat_unpack(__u8 * msg, __u16 start_bit, __u8 * data, - __u16 num_bits); -static void cat_build_header(__u8 * header, const __u16 len, - const __u16 smallest_reg_bits, - const __u16 longest_reg_bits); -static int cat_sendinst(voyager_module_t * modp, voyager_asic_t * asicp, - __u8 reg, __u8 op); -static int cat_getdata(voyager_module_t * modp, voyager_asic_t * asicp, - __u8 reg, __u8 * value); -static int cat_shiftout(__u8 * data, __u16 data_bytes, __u16 header_bytes, - __u8 pad_bits); -static int cat_write(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg, - __u8 value); -static int cat_read(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg, - __u8 * value); -static int cat_subread(voyager_module_t * modp, voyager_asic_t * asicp, - __u16 offset, __u16 len, void *buf); -static int cat_senddata(voyager_module_t * modp, voyager_asic_t * asicp, - __u8 reg, __u8 value); -static int cat_disconnect(voyager_module_t * modp, voyager_asic_t * asicp); -static int cat_connect(voyager_module_t * modp, voyager_asic_t * asicp); - -static inline const char *cat_module_name(int module_id) -{ - switch (module_id) { - case 0x10: - return "Processor Slot 0"; - case 0x11: - return "Processor Slot 1"; - case 0x12: - return "Processor Slot 2"; - case 0x13: - return "Processor Slot 4"; - case 0x14: - return "Memory Slot 0"; - case 0x15: - return "Memory Slot 1"; - case 0x18: - return "Primary Microchannel"; - case 0x19: - return "Secondary Microchannel"; - case 0x1a: - return "Power Supply Interface"; - case 0x1c: - return "Processor Slot 5"; - case 0x1d: - return "Processor Slot 6"; - case 0x1e: - return "Processor Slot 7"; - case 0x1f: - return "Processor Slot 8"; - default: - return "Unknown Module"; - } -} - -static int sspb = 0; /* stores the super port location */ -int voyager_8slot = 0; /* set to true if a 51xx monster */ - -voyager_module_t *voyager_cat_list; - -/* the I/O port assignments for the VIC and QIC */ -static struct resource vic_res = { - .name = "Voyager Interrupt Controller", - .start = 0xFC00, - .end = 0xFC6F -}; -static struct resource qic_res = { - .name = "Quad Interrupt Controller", - .start = 0xFC70, - .end = 0xFCFF -}; - -/* This function is used to pack a data bit stream inside a message. - * It writes num_bits of the data buffer in msg starting at start_bit. - * Note: This function assumes that any unused bit in the data stream - * is set to zero so that the ors will work correctly */ -static void -cat_pack(__u8 * msg, const __u16 start_bit, __u8 * data, const __u16 num_bits) -{ - /* compute initial shift needed */ - const __u16 offset = start_bit % BITS_PER_BYTE; - __u16 len = num_bits / BITS_PER_BYTE; - __u16 byte = start_bit / BITS_PER_BYTE; - __u16 residue = (num_bits % BITS_PER_BYTE) + offset; - int i; - - /* adjust if we have more than a byte of residue */ - if (residue >= BITS_PER_BYTE) { - residue -= BITS_PER_BYTE; - len++; - } - - /* clear out the bits. We assume here that if len==0 then - * residue >= offset. This is always true for the catbus - * operations */ - msg[byte] &= 0xff << (BITS_PER_BYTE - offset); - msg[byte++] |= data[0] >> offset; - if (len == 0) - return; - for (i = 1; i < len; i++) - msg[byte++] = (data[i - 1] << (BITS_PER_BYTE - offset)) - | (data[i] >> offset); - if (residue != 0) { - __u8 mask = 0xff >> residue; - __u8 last_byte = data[i - 1] << (BITS_PER_BYTE - offset) - | (data[i] >> offset); - - last_byte &= ~mask; - msg[byte] &= mask; - msg[byte] |= last_byte; - } - return; -} - -/* unpack the data again (same arguments as cat_pack()). data buffer - * must be zero populated. - * - * Function: given a message string move to start_bit and copy num_bits into - * data (starting at bit 0 in data). - */ -static void -cat_unpack(__u8 * msg, const __u16 start_bit, __u8 * data, const __u16 num_bits) -{ - /* compute initial shift needed */ - const __u16 offset = start_bit % BITS_PER_BYTE; - __u16 len = num_bits / BITS_PER_BYTE; - const __u8 last_bits = num_bits % BITS_PER_BYTE; - __u16 byte = start_bit / BITS_PER_BYTE; - int i; - - if (last_bits != 0) - len++; - - /* special case: want < 8 bits from msg and we can get it from - * a single byte of the msg */ - if (len == 0 && BITS_PER_BYTE - offset >= num_bits) { - data[0] = msg[byte] << offset; - data[0] &= 0xff >> (BITS_PER_BYTE - num_bits); - return; - } - for (i = 0; i < len; i++) { - /* this annoying if has to be done just in case a read of - * msg one beyond the array causes a panic */ - if (offset != 0) { - data[i] = msg[byte++] << offset; - data[i] |= msg[byte] >> (BITS_PER_BYTE - offset); - } else { - data[i] = msg[byte++]; - } - } - /* do we need to truncate the final byte */ - if (last_bits != 0) { - data[i - 1] &= 0xff << (BITS_PER_BYTE - last_bits); - } - return; -} - -static void -cat_build_header(__u8 * header, const __u16 len, const __u16 smallest_reg_bits, - const __u16 longest_reg_bits) -{ - int i; - __u16 start_bit = (smallest_reg_bits - 1) % BITS_PER_BYTE; - __u8 *last_byte = &header[len - 1]; - - if (start_bit == 0) - start_bit = 1; /* must have at least one bit in the hdr */ - - for (i = 0; i < len; i++) - header[i] = 0; - - for (i = start_bit; i > 0; i--) - *last_byte = ((*last_byte) << 1) + 1; - -} - -static int -cat_sendinst(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg, __u8 op) -{ - __u8 parity, inst, inst_buf[4] = { 0 }; - __u8 iseq[VOYAGER_MAX_SCAN_PATH], hseq[VOYAGER_MAX_REG_SIZE]; - __u16 ibytes, hbytes, padbits; - int i; - - /* - * Parity is the parity of the register number + 1 (READ_REGISTER - * and WRITE_REGISTER always add '1' to the number of bits == 1) - */ - parity = (__u8) (1 + (reg & 0x01) + - ((__u8) (reg & 0x02) >> 1) + - ((__u8) (reg & 0x04) >> 2) + - ((__u8) (reg & 0x08) >> 3)) % 2; - - inst = ((parity << 7) | (reg << 2) | op); - - outb(VOYAGER_CAT_IRCYC, CAT_CMD); - if (!modp->scan_path_connected) { - if (asicp->asic_id != VOYAGER_CAT_ID) { - printk - ("**WARNING***: cat_sendinst has disconnected scan path not to CAT asic\n"); - return 1; - } - outb(VOYAGER_CAT_HEADER, CAT_DATA); - outb(inst, CAT_DATA); - if (inb(CAT_DATA) != VOYAGER_CAT_HEADER) { - CDEBUG(("VOYAGER CAT: cat_sendinst failed to get CAT_HEADER\n")); - return 1; - } - return 0; - } - ibytes = modp->inst_bits / BITS_PER_BYTE; - if ((padbits = modp->inst_bits % BITS_PER_BYTE) != 0) { - padbits = BITS_PER_BYTE - padbits; - ibytes++; - } - hbytes = modp->largest_reg / BITS_PER_BYTE; - if (modp->largest_reg % BITS_PER_BYTE) - hbytes++; - CDEBUG(("cat_sendinst: ibytes=%d, hbytes=%d\n", ibytes, hbytes)); - /* initialise the instruction sequence to 0xff */ - for (i = 0; i < ibytes + hbytes; i++) - iseq[i] = 0xff; - cat_build_header(hseq, hbytes, modp->smallest_reg, modp->largest_reg); - cat_pack(iseq, modp->inst_bits, hseq, hbytes * BITS_PER_BYTE); - inst_buf[0] = inst; - inst_buf[1] = 0xFF >> (modp->largest_reg % BITS_PER_BYTE); - cat_pack(iseq, asicp->bit_location, inst_buf, asicp->ireg_length); -#ifdef VOYAGER_CAT_DEBUG - printk("ins = 0x%x, iseq: ", inst); - for (i = 0; i < ibytes + hbytes; i++) - printk("0x%x ", iseq[i]); - printk("\n"); -#endif - if (cat_shiftout(iseq, ibytes, hbytes, padbits)) { - CDEBUG(("VOYAGER CAT: cat_sendinst: cat_shiftout failed\n")); - return 1; - } - CDEBUG(("CAT SHIFTOUT DONE\n")); - return 0; -} - -static int -cat_getdata(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg, - __u8 * value) -{ - if (!modp->scan_path_connected) { - if (asicp->asic_id != VOYAGER_CAT_ID) { - CDEBUG(("VOYAGER CAT: ERROR: cat_getdata to CAT asic with scan path connected\n")); - return 1; - } - if (reg > VOYAGER_SUBADDRHI) - outb(VOYAGER_CAT_RUN, CAT_CMD); - outb(VOYAGER_CAT_DRCYC, CAT_CMD); - outb(VOYAGER_CAT_HEADER, CAT_DATA); - *value = inb(CAT_DATA); - outb(0xAA, CAT_DATA); - if (inb(CAT_DATA) != VOYAGER_CAT_HEADER) { - CDEBUG(("cat_getdata: failed to get VOYAGER_CAT_HEADER\n")); - return 1; - } - return 0; - } else { - __u16 sbits = modp->num_asics - 1 + asicp->ireg_length; - __u16 sbytes = sbits / BITS_PER_BYTE; - __u16 tbytes; - __u8 string[VOYAGER_MAX_SCAN_PATH], - trailer[VOYAGER_MAX_REG_SIZE]; - __u8 padbits; - int i; - - outb(VOYAGER_CAT_DRCYC, CAT_CMD); - - if ((padbits = sbits % BITS_PER_BYTE) != 0) { - padbits = BITS_PER_BYTE - padbits; - sbytes++; - } - tbytes = asicp->ireg_length / BITS_PER_BYTE; - if (asicp->ireg_length % BITS_PER_BYTE) - tbytes++; - CDEBUG(("cat_getdata: tbytes = %d, sbytes = %d, padbits = %d\n", - tbytes, sbytes, padbits)); - cat_build_header(trailer, tbytes, 1, asicp->ireg_length); - - for (i = tbytes - 1; i >= 0; i--) { - outb(trailer[i], CAT_DATA); - string[sbytes + i] = inb(CAT_DATA); - } - - for (i = sbytes - 1; i >= 0; i--) { - outb(0xaa, CAT_DATA); - string[i] = inb(CAT_DATA); - } - *value = 0; - cat_unpack(string, - padbits + (tbytes * BITS_PER_BYTE) + - asicp->asic_location, value, asicp->ireg_length); -#ifdef VOYAGER_CAT_DEBUG - printk("value=0x%x, string: ", *value); - for (i = 0; i < tbytes + sbytes; i++) - printk("0x%x ", string[i]); - printk("\n"); -#endif - - /* sanity check the rest of the return */ - for (i = 0; i < tbytes; i++) { - __u8 input = 0; - - cat_unpack(string, padbits + (i * BITS_PER_BYTE), - &input, BITS_PER_BYTE); - if (trailer[i] != input) { - CDEBUG(("cat_getdata: failed to sanity check rest of ret(%d) 0x%x != 0x%x\n", i, input, trailer[i])); - return 1; - } - } - CDEBUG(("cat_getdata DONE\n")); - return 0; - } -} - -static int -cat_shiftout(__u8 * data, __u16 data_bytes, __u16 header_bytes, __u8 pad_bits) -{ - int i; - - for (i = data_bytes + header_bytes - 1; i >= header_bytes; i--) - outb(data[i], CAT_DATA); - - for (i = header_bytes - 1; i >= 0; i--) { - __u8 header = 0; - __u8 input; - - outb(data[i], CAT_DATA); - input = inb(CAT_DATA); - CDEBUG(("cat_shiftout: returned 0x%x\n", input)); - cat_unpack(data, ((data_bytes + i) * BITS_PER_BYTE) - pad_bits, - &header, BITS_PER_BYTE); - if (input != header) { - CDEBUG(("VOYAGER CAT: cat_shiftout failed to return header 0x%x != 0x%x\n", input, header)); - return 1; - } - } - return 0; -} - -static int -cat_senddata(voyager_module_t * modp, voyager_asic_t * asicp, - __u8 reg, __u8 value) -{ - outb(VOYAGER_CAT_DRCYC, CAT_CMD); - if (!modp->scan_path_connected) { - if (asicp->asic_id != VOYAGER_CAT_ID) { - CDEBUG(("VOYAGER CAT: ERROR: scan path disconnected when asic != CAT\n")); - return 1; - } - outb(VOYAGER_CAT_HEADER, CAT_DATA); - outb(value, CAT_DATA); - if (inb(CAT_DATA) != VOYAGER_CAT_HEADER) { - CDEBUG(("cat_senddata: failed to get correct header response to sent data\n")); - return 1; - } - if (reg > VOYAGER_SUBADDRHI) { - outb(VOYAGER_CAT_RUN, CAT_CMD); - outb(VOYAGER_CAT_END, CAT_CMD); - outb(VOYAGER_CAT_RUN, CAT_CMD); - } - - return 0; - } else { - __u16 hbytes = asicp->ireg_length / BITS_PER_BYTE; - __u16 dbytes = - (modp->num_asics - 1 + asicp->ireg_length) / BITS_PER_BYTE; - __u8 padbits, dseq[VOYAGER_MAX_SCAN_PATH], - hseq[VOYAGER_MAX_REG_SIZE]; - int i; - - if ((padbits = (modp->num_asics - 1 - + asicp->ireg_length) % BITS_PER_BYTE) != 0) { - padbits = BITS_PER_BYTE - padbits; - dbytes++; - } - if (asicp->ireg_length % BITS_PER_BYTE) - hbytes++; - - cat_build_header(hseq, hbytes, 1, asicp->ireg_length); - - for (i = 0; i < dbytes + hbytes; i++) - dseq[i] = 0xff; - CDEBUG(("cat_senddata: dbytes=%d, hbytes=%d, padbits=%d\n", - dbytes, hbytes, padbits)); - cat_pack(dseq, modp->num_asics - 1 + asicp->ireg_length, - hseq, hbytes * BITS_PER_BYTE); - cat_pack(dseq, asicp->asic_location, &value, - asicp->ireg_length); -#ifdef VOYAGER_CAT_DEBUG - printk("dseq "); - for (i = 0; i < hbytes + dbytes; i++) { - printk("0x%x ", dseq[i]); - } - printk("\n"); -#endif - return cat_shiftout(dseq, dbytes, hbytes, padbits); - } -} - -static int -cat_write(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg, __u8 value) -{ - if (cat_sendinst(modp, asicp, reg, VOYAGER_WRITE_CONFIG)) - return 1; - return cat_senddata(modp, asicp, reg, value); -} - -static int -cat_read(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg, - __u8 * value) -{ - if (cat_sendinst(modp, asicp, reg, VOYAGER_READ_CONFIG)) - return 1; - return cat_getdata(modp, asicp, reg, value); -} - -static int -cat_subaddrsetup(voyager_module_t * modp, voyager_asic_t * asicp, __u16 offset, - __u16 len) -{ - __u8 val; - - if (len > 1) { - /* set auto increment */ - __u8 newval; - - if (cat_read(modp, asicp, VOYAGER_AUTO_INC_REG, &val)) { - CDEBUG(("cat_subaddrsetup: read of VOYAGER_AUTO_INC_REG failed\n")); - return 1; - } - CDEBUG(("cat_subaddrsetup: VOYAGER_AUTO_INC_REG = 0x%x\n", - val)); - newval = val | VOYAGER_AUTO_INC; - if (newval != val) { - if (cat_write(modp, asicp, VOYAGER_AUTO_INC_REG, val)) { - CDEBUG(("cat_subaddrsetup: write to VOYAGER_AUTO_INC_REG failed\n")); - return 1; - } - } - } - if (cat_write(modp, asicp, VOYAGER_SUBADDRLO, (__u8) (offset & 0xff))) { - CDEBUG(("cat_subaddrsetup: write to SUBADDRLO failed\n")); - return 1; - } - if (asicp->subaddr > VOYAGER_SUBADDR_LO) { - if (cat_write - (modp, asicp, VOYAGER_SUBADDRHI, (__u8) (offset >> 8))) { - CDEBUG(("cat_subaddrsetup: write to SUBADDRHI failed\n")); - return 1; - } - cat_read(modp, asicp, VOYAGER_SUBADDRHI, &val); - CDEBUG(("cat_subaddrsetup: offset = %d, hi = %d\n", offset, - val)); - } - cat_read(modp, asicp, VOYAGER_SUBADDRLO, &val); - CDEBUG(("cat_subaddrsetup: offset = %d, lo = %d\n", offset, val)); - return 0; -} - -static int -cat_subwrite(voyager_module_t * modp, voyager_asic_t * asicp, __u16 offset, - __u16 len, void *buf) -{ - int i, retval; - - /* FIXME: need special actions for VOYAGER_CAT_ID here */ - if (asicp->asic_id == VOYAGER_CAT_ID) { - CDEBUG(("cat_subwrite: ATTEMPT TO WRITE TO CAT ASIC\n")); - /* FIXME -- This is supposed to be handled better - * There is a problem writing to the cat asic in the - * PSI. The 30us delay seems to work, though */ - udelay(30); - } - - if ((retval = cat_subaddrsetup(modp, asicp, offset, len)) != 0) { - printk("cat_subwrite: cat_subaddrsetup FAILED\n"); - return retval; - } - - if (cat_sendinst - (modp, asicp, VOYAGER_SUBADDRDATA, VOYAGER_WRITE_CONFIG)) { - printk("cat_subwrite: cat_sendinst FAILED\n"); - return 1; - } - for (i = 0; i < len; i++) { - if (cat_senddata(modp, asicp, 0xFF, ((__u8 *) buf)[i])) { - printk - ("cat_subwrite: cat_sendata element at %d FAILED\n", - i); - return 1; - } - } - return 0; -} -static int -cat_subread(voyager_module_t * modp, voyager_asic_t * asicp, __u16 offset, - __u16 len, void *buf) -{ - int i, retval; - - if ((retval = cat_subaddrsetup(modp, asicp, offset, len)) != 0) { - CDEBUG(("cat_subread: cat_subaddrsetup FAILED\n")); - return retval; - } - - if (cat_sendinst(modp, asicp, VOYAGER_SUBADDRDATA, VOYAGER_READ_CONFIG)) { - CDEBUG(("cat_subread: cat_sendinst failed\n")); - return 1; - } - for (i = 0; i < len; i++) { - if (cat_getdata(modp, asicp, 0xFF, &((__u8 *) buf)[i])) { - CDEBUG(("cat_subread: cat_getdata element %d failed\n", - i)); - return 1; - } - } - return 0; -} - -/* buffer for storing EPROM data read in during initialisation */ -static __initdata __u8 eprom_buf[0xFFFF]; -static voyager_module_t *voyager_initial_module; - -/* Initialise the cat bus components. We assume this is called by the - * boot cpu *after* all memory initialisation has been done (so we can - * use kmalloc) but before smp initialisation, so we can probe the SMP - * configuration and pick up necessary information. */ -void __init voyager_cat_init(void) -{ - voyager_module_t **modpp = &voyager_initial_module; - voyager_asic_t **asicpp; - voyager_asic_t *qabc_asic = NULL; - int i, j; - unsigned long qic_addr = 0; - __u8 qabc_data[0x20]; - __u8 num_submodules, val; - voyager_eprom_hdr_t *eprom_hdr = (voyager_eprom_hdr_t *) & eprom_buf[0]; - - __u8 cmos[4]; - unsigned long addr; - - /* initiallise the SUS mailbox */ - for (i = 0; i < sizeof(cmos); i++) - cmos[i] = voyager_extended_cmos_read(VOYAGER_DUMP_LOCATION + i); - addr = *(unsigned long *)cmos; - if ((addr & 0xff000000) != 0xff000000) { - printk(KERN_ERR - "Voyager failed to get SUS mailbox (addr = 0x%lx\n", - addr); - } else { - static struct resource res; - - res.name = "voyager SUS"; - res.start = addr; - res.end = addr + 0x3ff; - - request_resource(&iomem_resource, &res); - voyager_SUS = (struct voyager_SUS *) - ioremap(addr, 0x400); - printk(KERN_NOTICE "Voyager SUS mailbox version 0x%x\n", - voyager_SUS->SUS_version); - voyager_SUS->kernel_version = VOYAGER_MAILBOX_VERSION; - voyager_SUS->kernel_flags = VOYAGER_OS_HAS_SYSINT; - } - - /* clear the processor counts */ - voyager_extended_vic_processors = 0; - voyager_quad_processors = 0; - - printk("VOYAGER: beginning CAT bus probe\n"); - /* set up the SuperSet Port Block which tells us where the - * CAT communication port is */ - sspb = inb(VOYAGER_SSPB_RELOCATION_PORT) * 0x100; - VDEBUG(("VOYAGER DEBUG: sspb = 0x%x\n", sspb)); - - /* now find out if were 8 slot or normal */ - if ((inb(VIC_PROC_WHO_AM_I) & EIGHT_SLOT_IDENTIFIER) - == EIGHT_SLOT_IDENTIFIER) { - voyager_8slot = 1; - printk(KERN_NOTICE - "Voyager: Eight slot 51xx configuration detected\n"); - } - - for (i = VOYAGER_MIN_MODULE; i <= VOYAGER_MAX_MODULE; i++) { - __u8 input; - int asic; - __u16 eprom_size; - __u16 sp_offset; - - outb(VOYAGER_CAT_DESELECT, VOYAGER_CAT_CONFIG_PORT); - outb(i, VOYAGER_CAT_CONFIG_PORT); - - /* check the presence of the module */ - outb(VOYAGER_CAT_RUN, CAT_CMD); - outb(VOYAGER_CAT_IRCYC, CAT_CMD); - outb(VOYAGER_CAT_HEADER, CAT_DATA); - /* stream series of alternating 1's and 0's to stimulate - * response */ - outb(0xAA, CAT_DATA); - input = inb(CAT_DATA); - outb(VOYAGER_CAT_END, CAT_CMD); - if (input != VOYAGER_CAT_HEADER) { - continue; - } - CDEBUG(("VOYAGER DEBUG: found module id 0x%x, %s\n", i, - cat_module_name(i))); - *modpp = kmalloc(sizeof(voyager_module_t), GFP_KERNEL); /*&voyager_module_storage[cat_count++]; */ - if (*modpp == NULL) { - printk("**WARNING** kmalloc failure in cat_init\n"); - continue; - } - memset(*modpp, 0, sizeof(voyager_module_t)); - /* need temporary asic for cat_subread. It will be - * filled in correctly later */ - (*modpp)->asic = kmalloc(sizeof(voyager_asic_t), GFP_KERNEL); /*&voyager_asic_storage[asic_count]; */ - if ((*modpp)->asic == NULL) { - printk("**WARNING** kmalloc failure in cat_init\n"); - continue; - } - memset((*modpp)->asic, 0, sizeof(voyager_asic_t)); - (*modpp)->asic->asic_id = VOYAGER_CAT_ID; - (*modpp)->asic->subaddr = VOYAGER_SUBADDR_HI; - (*modpp)->module_addr = i; - (*modpp)->scan_path_connected = 0; - if (i == VOYAGER_PSI) { - /* Exception leg for modules with no EEPROM */ - printk("Module \"%s\"\n", cat_module_name(i)); - continue; - } - - CDEBUG(("cat_init: Reading eeprom for module 0x%x at offset %d\n", i, VOYAGER_XSUM_END_OFFSET)); - outb(VOYAGER_CAT_RUN, CAT_CMD); - cat_disconnect(*modpp, (*modpp)->asic); - if (cat_subread(*modpp, (*modpp)->asic, - VOYAGER_XSUM_END_OFFSET, sizeof(eprom_size), - &eprom_size)) { - printk - ("**WARNING**: Voyager couldn't read EPROM size for module 0x%x\n", - i); - outb(VOYAGER_CAT_END, CAT_CMD); - continue; - } - if (eprom_size > sizeof(eprom_buf)) { - printk - ("**WARNING**: Voyager insufficient size to read EPROM data, module 0x%x. Need %d\n", - i, eprom_size); - outb(VOYAGER_CAT_END, CAT_CMD); - continue; - } - outb(VOYAGER_CAT_END, CAT_CMD); - outb(VOYAGER_CAT_RUN, CAT_CMD); - CDEBUG(("cat_init: module 0x%x, eeprom_size %d\n", i, - eprom_size)); - if (cat_subread - (*modpp, (*modpp)->asic, 0, eprom_size, eprom_buf)) { - outb(VOYAGER_CAT_END, CAT_CMD); - continue; - } - outb(VOYAGER_CAT_END, CAT_CMD); - printk("Module \"%s\", version 0x%x, tracer 0x%x, asics %d\n", - cat_module_name(i), eprom_hdr->version_id, - *((__u32 *) eprom_hdr->tracer), eprom_hdr->num_asics); - (*modpp)->ee_size = eprom_hdr->ee_size; - (*modpp)->num_asics = eprom_hdr->num_asics; - asicpp = &((*modpp)->asic); - sp_offset = eprom_hdr->scan_path_offset; - /* All we really care about are the Quad cards. We - * identify them because they are in a processor slot - * and have only four asics */ - if ((i < 0x10 || (i >= 0x14 && i < 0x1c) || i > 0x1f)) { - modpp = &((*modpp)->next); - continue; - } - /* Now we know it's in a processor slot, does it have - * a quad baseboard submodule */ - outb(VOYAGER_CAT_RUN, CAT_CMD); - cat_read(*modpp, (*modpp)->asic, VOYAGER_SUBMODPRESENT, - &num_submodules); - /* lowest two bits, active low */ - num_submodules = ~(0xfc | num_submodules); - CDEBUG(("VOYAGER CAT: %d submodules present\n", - num_submodules)); - if (num_submodules == 0) { - /* fill in the dyadic extended processors */ - __u8 cpu = i & 0x07; - - printk("Module \"%s\": Dyadic Processor Card\n", - cat_module_name(i)); - voyager_extended_vic_processors |= (1 << cpu); - cpu += 4; - voyager_extended_vic_processors |= (1 << cpu); - outb(VOYAGER_CAT_END, CAT_CMD); - continue; - } - - /* now we want to read the asics on the first submodule, - * which should be the quad base board */ - - cat_read(*modpp, (*modpp)->asic, VOYAGER_SUBMODSELECT, &val); - CDEBUG(("cat_init: SUBMODSELECT value = 0x%x\n", val)); - val = (val & 0x7c) | VOYAGER_QUAD_BASEBOARD; - cat_write(*modpp, (*modpp)->asic, VOYAGER_SUBMODSELECT, val); - - outb(VOYAGER_CAT_END, CAT_CMD); - - CDEBUG(("cat_init: Reading eeprom for module 0x%x at offset %d\n", i, VOYAGER_XSUM_END_OFFSET)); - outb(VOYAGER_CAT_RUN, CAT_CMD); - cat_disconnect(*modpp, (*modpp)->asic); - if (cat_subread(*modpp, (*modpp)->asic, - VOYAGER_XSUM_END_OFFSET, sizeof(eprom_size), - &eprom_size)) { - printk - ("**WARNING**: Voyager couldn't read EPROM size for module 0x%x\n", - i); - outb(VOYAGER_CAT_END, CAT_CMD); - continue; - } - if (eprom_size > sizeof(eprom_buf)) { - printk - ("**WARNING**: Voyager insufficient size to read EPROM data, module 0x%x. Need %d\n", - i, eprom_size); - outb(VOYAGER_CAT_END, CAT_CMD); - continue; - } - outb(VOYAGER_CAT_END, CAT_CMD); - outb(VOYAGER_CAT_RUN, CAT_CMD); - CDEBUG(("cat_init: module 0x%x, eeprom_size %d\n", i, - eprom_size)); - if (cat_subread - (*modpp, (*modpp)->asic, 0, eprom_size, eprom_buf)) { - outb(VOYAGER_CAT_END, CAT_CMD); - continue; - } - outb(VOYAGER_CAT_END, CAT_CMD); - /* Now do everything for the QBB submodule 1 */ - (*modpp)->ee_size = eprom_hdr->ee_size; - (*modpp)->num_asics = eprom_hdr->num_asics; - asicpp = &((*modpp)->asic); - sp_offset = eprom_hdr->scan_path_offset; - /* get rid of the dummy CAT asic and read the real one */ - kfree((*modpp)->asic); - for (asic = 0; asic < (*modpp)->num_asics; asic++) { - int j; - voyager_asic_t *asicp = *asicpp = kzalloc(sizeof(voyager_asic_t), GFP_KERNEL); /*&voyager_asic_storage[asic_count++]; */ - voyager_sp_table_t *sp_table; - voyager_at_t *asic_table; - voyager_jtt_t *jtag_table; - - if (asicp == NULL) { - printk - ("**WARNING** kmalloc failure in cat_init\n"); - continue; - } - asicpp = &(asicp->next); - asicp->asic_location = asic; - sp_table = - (voyager_sp_table_t *) (eprom_buf + sp_offset); - asicp->asic_id = sp_table->asic_id; - asic_table = - (voyager_at_t *) (eprom_buf + - sp_table->asic_data_offset); - for (j = 0; j < 4; j++) - asicp->jtag_id[j] = asic_table->jtag_id[j]; - jtag_table = - (voyager_jtt_t *) (eprom_buf + - asic_table->jtag_offset); - asicp->ireg_length = jtag_table->ireg_len; - asicp->bit_location = (*modpp)->inst_bits; - (*modpp)->inst_bits += asicp->ireg_length; - if (asicp->ireg_length > (*modpp)->largest_reg) - (*modpp)->largest_reg = asicp->ireg_length; - if (asicp->ireg_length < (*modpp)->smallest_reg || - (*modpp)->smallest_reg == 0) - (*modpp)->smallest_reg = asicp->ireg_length; - CDEBUG(("asic 0x%x, ireg_length=%d, bit_location=%d\n", - asicp->asic_id, asicp->ireg_length, - asicp->bit_location)); - if (asicp->asic_id == VOYAGER_QUAD_QABC) { - CDEBUG(("VOYAGER CAT: QABC ASIC found\n")); - qabc_asic = asicp; - } - sp_offset += sizeof(voyager_sp_table_t); - } - CDEBUG(("Module inst_bits = %d, largest_reg = %d, smallest_reg=%d\n", (*modpp)->inst_bits, (*modpp)->largest_reg, (*modpp)->smallest_reg)); - /* OK, now we have the QUAD ASICs set up, use them. - * we need to: - * - * 1. Find the Memory area for the Quad CPIs. - * 2. Find the Extended VIC processor - * 3. Configure a second extended VIC processor (This - * cannot be done for the 51xx. - * */ - outb(VOYAGER_CAT_RUN, CAT_CMD); - cat_connect(*modpp, (*modpp)->asic); - CDEBUG(("CAT CONNECTED!!\n")); - cat_subread(*modpp, qabc_asic, 0, sizeof(qabc_data), qabc_data); - qic_addr = qabc_data[5] << 8; - qic_addr = (qic_addr | qabc_data[6]) << 8; - qic_addr = (qic_addr | qabc_data[7]) << 8; - printk - ("Module \"%s\": Quad Processor Card; CPI 0x%lx, SET=0x%x\n", - cat_module_name(i), qic_addr, qabc_data[8]); -#if 0 /* plumbing fails---FIXME */ - if ((qabc_data[8] & 0xf0) == 0) { - /* FIXME: 32 way 8 CPU slot monster cannot be - * plumbed this way---need to check for it */ - - printk("Plumbing second Extended Quad Processor\n"); - /* second VIC line hardwired to Quad CPU 1 */ - qabc_data[8] |= 0x20; - cat_subwrite(*modpp, qabc_asic, 8, 1, &qabc_data[8]); -#ifdef VOYAGER_CAT_DEBUG - /* verify plumbing */ - cat_subread(*modpp, qabc_asic, 8, 1, &qabc_data[8]); - if ((qabc_data[8] & 0xf0) == 0) { - CDEBUG(("PLUMBING FAILED: 0x%x\n", - qabc_data[8])); - } -#endif - } -#endif - - { - struct resource *res = - kzalloc(sizeof(struct resource), GFP_KERNEL); - res->name = kmalloc(128, GFP_KERNEL); - sprintf((char *)res->name, "Voyager %s Quad CPI", - cat_module_name(i)); - res->start = qic_addr; - res->end = qic_addr + 0x3ff; - request_resource(&iomem_resource, res); - } - - qic_addr = (unsigned long)ioremap_cache(qic_addr, 0x400); - - for (j = 0; j < 4; j++) { - __u8 cpu; - - if (voyager_8slot) { - /* 8 slot has a different mapping, - * each slot has only one vic line, so - * 1 cpu in each slot must be < 8 */ - cpu = (i & 0x07) + j * 8; - } else { - cpu = (i & 0x03) + j * 4; - } - if ((qabc_data[8] & (1 << j))) { - voyager_extended_vic_processors |= (1 << cpu); - } - if (qabc_data[8] & (1 << (j + 4))) { - /* Second SET register plumbed: Quad - * card has two VIC connected CPUs. - * Secondary cannot be booted as a VIC - * CPU */ - voyager_extended_vic_processors |= (1 << cpu); - voyager_allowed_boot_processors &= - (~(1 << cpu)); - } - - voyager_quad_processors |= (1 << cpu); - voyager_quad_cpi_addr[cpu] = (struct voyager_qic_cpi *) - (qic_addr + (j << 8)); - CDEBUG(("CPU%d: CPI address 0x%lx\n", cpu, - (unsigned long)voyager_quad_cpi_addr[cpu])); - } - outb(VOYAGER_CAT_END, CAT_CMD); - - *asicpp = NULL; - modpp = &((*modpp)->next); - } - *modpp = NULL; - printk - ("CAT Bus Initialisation finished: extended procs 0x%x, quad procs 0x%x, allowed vic boot = 0x%x\n", - voyager_extended_vic_processors, voyager_quad_processors, - voyager_allowed_boot_processors); - request_resource(&ioport_resource, &vic_res); - if (voyager_quad_processors) - request_resource(&ioport_resource, &qic_res); - /* set up the front power switch */ -} - -int voyager_cat_readb(__u8 module, __u8 asic, int reg) -{ - return 0; -} - -static int cat_disconnect(voyager_module_t * modp, voyager_asic_t * asicp) -{ - __u8 val; - int err = 0; - - if (!modp->scan_path_connected) - return 0; - if (asicp->asic_id != VOYAGER_CAT_ID) { - CDEBUG(("cat_disconnect: ASIC is not CAT\n")); - return 1; - } - err = cat_read(modp, asicp, VOYAGER_SCANPATH, &val); - if (err) { - CDEBUG(("cat_disconnect: failed to read SCANPATH\n")); - return err; - } - val &= VOYAGER_DISCONNECT_ASIC; - err = cat_write(modp, asicp, VOYAGER_SCANPATH, val); - if (err) { - CDEBUG(("cat_disconnect: failed to write SCANPATH\n")); - return err; - } - outb(VOYAGER_CAT_END, CAT_CMD); - outb(VOYAGER_CAT_RUN, CAT_CMD); - modp->scan_path_connected = 0; - - return 0; -} - -static int cat_connect(voyager_module_t * modp, voyager_asic_t * asicp) -{ - __u8 val; - int err = 0; - - if (modp->scan_path_connected) - return 0; - if (asicp->asic_id != VOYAGER_CAT_ID) { - CDEBUG(("cat_connect: ASIC is not CAT\n")); - return 1; - } - - err = cat_read(modp, asicp, VOYAGER_SCANPATH, &val); - if (err) { - CDEBUG(("cat_connect: failed to read SCANPATH\n")); - return err; - } - val |= VOYAGER_CONNECT_ASIC; - err = cat_write(modp, asicp, VOYAGER_SCANPATH, val); - if (err) { - CDEBUG(("cat_connect: failed to write SCANPATH\n")); - return err; - } - outb(VOYAGER_CAT_END, CAT_CMD); - outb(VOYAGER_CAT_RUN, CAT_CMD); - modp->scan_path_connected = 1; - - return 0; -} - -void voyager_cat_power_off(void) -{ - /* Power the machine off by writing to the PSI over the CAT - * bus */ - __u8 data; - voyager_module_t psi = { 0 }; - voyager_asic_t psi_asic = { 0 }; - - psi.asic = &psi_asic; - psi.asic->asic_id = VOYAGER_CAT_ID; - psi.asic->subaddr = VOYAGER_SUBADDR_HI; - psi.module_addr = VOYAGER_PSI; - psi.scan_path_connected = 0; - - outb(VOYAGER_CAT_END, CAT_CMD); - /* Connect the PSI to the CAT Bus */ - outb(VOYAGER_CAT_DESELECT, VOYAGER_CAT_CONFIG_PORT); - outb(VOYAGER_PSI, VOYAGER_CAT_CONFIG_PORT); - outb(VOYAGER_CAT_RUN, CAT_CMD); - cat_disconnect(&psi, &psi_asic); - /* Read the status */ - cat_subread(&psi, &psi_asic, VOYAGER_PSI_GENERAL_REG, 1, &data); - outb(VOYAGER_CAT_END, CAT_CMD); - CDEBUG(("PSI STATUS 0x%x\n", data)); - /* These two writes are power off prep and perform */ - data = PSI_CLEAR; - outb(VOYAGER_CAT_RUN, CAT_CMD); - cat_subwrite(&psi, &psi_asic, VOYAGER_PSI_GENERAL_REG, 1, &data); - outb(VOYAGER_CAT_END, CAT_CMD); - data = PSI_POWER_DOWN; - outb(VOYAGER_CAT_RUN, CAT_CMD); - cat_subwrite(&psi, &psi_asic, VOYAGER_PSI_GENERAL_REG, 1, &data); - outb(VOYAGER_CAT_END, CAT_CMD); -} - -struct voyager_status voyager_status = { 0 }; - -void voyager_cat_psi(__u8 cmd, __u16 reg, __u8 * data) -{ - voyager_module_t psi = { 0 }; - voyager_asic_t psi_asic = { 0 }; - - psi.asic = &psi_asic; - psi.asic->asic_id = VOYAGER_CAT_ID; - psi.asic->subaddr = VOYAGER_SUBADDR_HI; - psi.module_addr = VOYAGER_PSI; - psi.scan_path_connected = 0; - - outb(VOYAGER_CAT_END, CAT_CMD); - /* Connect the PSI to the CAT Bus */ - outb(VOYAGER_CAT_DESELECT, VOYAGER_CAT_CONFIG_PORT); - outb(VOYAGER_PSI, VOYAGER_CAT_CONFIG_PORT); - outb(VOYAGER_CAT_RUN, CAT_CMD); - cat_disconnect(&psi, &psi_asic); - switch (cmd) { - case VOYAGER_PSI_READ: - cat_read(&psi, &psi_asic, reg, data); - break; - case VOYAGER_PSI_WRITE: - cat_write(&psi, &psi_asic, reg, *data); - break; - case VOYAGER_PSI_SUBREAD: - cat_subread(&psi, &psi_asic, reg, 1, data); - break; - case VOYAGER_PSI_SUBWRITE: - cat_subwrite(&psi, &psi_asic, reg, 1, data); - break; - default: - printk(KERN_ERR "Voyager PSI, unrecognised command %d\n", cmd); - break; - } - outb(VOYAGER_CAT_END, CAT_CMD); -} - -void voyager_cat_do_common_interrupt(void) -{ - /* This is caused either by a memory parity error or something - * in the PSI */ - __u8 data; - voyager_module_t psi = { 0 }; - voyager_asic_t psi_asic = { 0 }; - struct voyager_psi psi_reg; - int i; - re_read: - psi.asic = &psi_asic; - psi.asic->asic_id = VOYAGER_CAT_ID; - psi.asic->subaddr = VOYAGER_SUBADDR_HI; - psi.module_addr = VOYAGER_PSI; - psi.scan_path_connected = 0; - - outb(VOYAGER_CAT_END, CAT_CMD); - /* Connect the PSI to the CAT Bus */ - outb(VOYAGER_CAT_DESELECT, VOYAGER_CAT_CONFIG_PORT); - outb(VOYAGER_PSI, VOYAGER_CAT_CONFIG_PORT); - outb(VOYAGER_CAT_RUN, CAT_CMD); - cat_disconnect(&psi, &psi_asic); - /* Read the status. NOTE: Need to read *all* the PSI regs here - * otherwise the cmn int will be reasserted */ - for (i = 0; i < sizeof(psi_reg.regs); i++) { - cat_read(&psi, &psi_asic, i, &((__u8 *) & psi_reg.regs)[i]); - } - outb(VOYAGER_CAT_END, CAT_CMD); - if ((psi_reg.regs.checkbit & 0x02) == 0) { - psi_reg.regs.checkbit |= 0x02; - cat_write(&psi, &psi_asic, 5, psi_reg.regs.checkbit); - printk("VOYAGER RE-READ PSI\n"); - goto re_read; - } - outb(VOYAGER_CAT_RUN, CAT_CMD); - for (i = 0; i < sizeof(psi_reg.subregs); i++) { - /* This looks strange, but the PSI doesn't do auto increment - * correctly */ - cat_subread(&psi, &psi_asic, VOYAGER_PSI_SUPPLY_REG + i, - 1, &((__u8 *) & psi_reg.subregs)[i]); - } - outb(VOYAGER_CAT_END, CAT_CMD); -#ifdef VOYAGER_CAT_DEBUG - printk("VOYAGER PSI: "); - for (i = 0; i < sizeof(psi_reg.regs); i++) - printk("%02x ", ((__u8 *) & psi_reg.regs)[i]); - printk("\n "); - for (i = 0; i < sizeof(psi_reg.subregs); i++) - printk("%02x ", ((__u8 *) & psi_reg.subregs)[i]); - printk("\n"); -#endif - if (psi_reg.regs.intstatus & PSI_MON) { - /* switch off or power fail */ - - if (psi_reg.subregs.supply & PSI_SWITCH_OFF) { - if (voyager_status.switch_off) { - printk(KERN_ERR - "Voyager front panel switch turned off again---Immediate power off!\n"); - voyager_cat_power_off(); - /* not reached */ - } else { - printk(KERN_ERR - "Voyager front panel switch turned off\n"); - voyager_status.switch_off = 1; - voyager_status.request_from_kernel = 1; - wake_up_process(voyager_thread); - } - /* Tell the hardware we're taking care of the - * shutdown, otherwise it will power the box off - * within 3 seconds of the switch being pressed and, - * which is much more important to us, continue to - * assert the common interrupt */ - data = PSI_CLR_SWITCH_OFF; - outb(VOYAGER_CAT_RUN, CAT_CMD); - cat_subwrite(&psi, &psi_asic, VOYAGER_PSI_SUPPLY_REG, - 1, &data); - outb(VOYAGER_CAT_END, CAT_CMD); - } else { - - VDEBUG(("Voyager ac fail reg 0x%x\n", - psi_reg.subregs.ACfail)); - if ((psi_reg.subregs.ACfail & AC_FAIL_STAT_CHANGE) == 0) { - /* No further update */ - return; - } -#if 0 - /* Don't bother trying to find out who failed. - * FIXME: This probably makes the code incorrect on - * anything other than a 345x */ - for (i = 0; i < 5; i++) { - if (psi_reg.subregs.ACfail & (1 << i)) { - break; - } - } - printk(KERN_NOTICE "AC FAIL IN SUPPLY %d\n", i); -#endif - /* DON'T do this: it shuts down the AC PSI - outb(VOYAGER_CAT_RUN, CAT_CMD); - data = PSI_MASK_MASK | i; - cat_subwrite(&psi, &psi_asic, VOYAGER_PSI_MASK, - 1, &data); - outb(VOYAGER_CAT_END, CAT_CMD); - */ - printk(KERN_ERR "Voyager AC power failure\n"); - outb(VOYAGER_CAT_RUN, CAT_CMD); - data = PSI_COLD_START; - cat_subwrite(&psi, &psi_asic, VOYAGER_PSI_GENERAL_REG, - 1, &data); - outb(VOYAGER_CAT_END, CAT_CMD); - voyager_status.power_fail = 1; - voyager_status.request_from_kernel = 1; - wake_up_process(voyager_thread); - } - - } else if (psi_reg.regs.intstatus & PSI_FAULT) { - /* Major fault! */ - printk(KERN_ERR - "Voyager PSI Detected major fault, immediate power off!\n"); - voyager_cat_power_off(); - /* not reached */ - } else if (psi_reg.regs.intstatus & (PSI_DC_FAIL | PSI_ALARM - | PSI_CURRENT | PSI_DVM - | PSI_PSCFAULT | PSI_STAT_CHG)) { - /* other psi fault */ - - printk(KERN_WARNING "Voyager PSI status 0x%x\n", data); - /* clear the PSI fault */ - outb(VOYAGER_CAT_RUN, CAT_CMD); - cat_write(&psi, &psi_asic, VOYAGER_PSI_STATUS_REG, 0); - outb(VOYAGER_CAT_END, CAT_CMD); - } -} diff --git a/arch/x86/mach-voyager/voyager_smp.c b/arch/x86/mach-voyager/voyager_smp.c deleted file mode 100644 index 98e3c2bc756..00000000000 --- a/arch/x86/mach-voyager/voyager_smp.c +++ /dev/null @@ -1,1805 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8 -*- */ - -/* Copyright (C) 1999,2001 - * - * Author: J.E.J.Bottomley@HansenPartnership.com - * - * This file provides all the same external entries as smp.c but uses - * the voyager hal to provide the functionality - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* TLB state -- visible externally, indexed physically */ -DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) = { &init_mm, 0 }; - -/* CPU IRQ affinity -- set to all ones initially */ -static unsigned long cpu_irq_affinity[NR_CPUS] __cacheline_aligned = - {[0 ... NR_CPUS-1] = ~0UL }; - -/* per CPU data structure (for /proc/cpuinfo et al), visible externally - * indexed physically */ -DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info); -EXPORT_PER_CPU_SYMBOL(cpu_info); - -/* physical ID of the CPU used to boot the system */ -unsigned char boot_cpu_id; - -/* The memory line addresses for the Quad CPIs */ -struct voyager_qic_cpi *voyager_quad_cpi_addr[NR_CPUS] __cacheline_aligned; - -/* The masks for the Extended VIC processors, filled in by cat_init */ -__u32 voyager_extended_vic_processors = 0; - -/* Masks for the extended Quad processors which cannot be VIC booted */ -__u32 voyager_allowed_boot_processors = 0; - -/* The mask for the Quad Processors (both extended and non-extended) */ -__u32 voyager_quad_processors = 0; - -/* Total count of live CPUs, used in process.c to display - * the CPU information and in irq.c for the per CPU irq - * activity count. Finally exported by i386_ksyms.c */ -static int voyager_extended_cpus = 1; - -/* Used for the invalidate map that's also checked in the spinlock */ -static volatile unsigned long smp_invalidate_needed; - -/* Bitmask of CPUs present in the system - exported by i386_syms.c, used - * by scheduler but indexed physically */ -cpumask_t phys_cpu_present_map = CPU_MASK_NONE; - -/* The internal functions */ -static void send_CPI(__u32 cpuset, __u8 cpi); -static void ack_CPI(__u8 cpi); -static int ack_QIC_CPI(__u8 cpi); -static void ack_special_QIC_CPI(__u8 cpi); -static void ack_VIC_CPI(__u8 cpi); -static void send_CPI_allbutself(__u8 cpi); -static void mask_vic_irq(unsigned int irq); -static void unmask_vic_irq(unsigned int irq); -static unsigned int startup_vic_irq(unsigned int irq); -static void enable_local_vic_irq(unsigned int irq); -static void disable_local_vic_irq(unsigned int irq); -static void before_handle_vic_irq(unsigned int irq); -static void after_handle_vic_irq(unsigned int irq); -static void set_vic_irq_affinity(unsigned int irq, const struct cpumask *mask); -static void ack_vic_irq(unsigned int irq); -static void vic_enable_cpi(void); -static void do_boot_cpu(__u8 cpuid); -static void do_quad_bootstrap(void); -static void initialize_secondary(void); - -int hard_smp_processor_id(void); -int safe_smp_processor_id(void); - -/* Inline functions */ -static inline void send_one_QIC_CPI(__u8 cpu, __u8 cpi) -{ - voyager_quad_cpi_addr[cpu]->qic_cpi[cpi].cpi = - (smp_processor_id() << 16) + cpi; -} - -static inline void send_QIC_CPI(__u32 cpuset, __u8 cpi) -{ - int cpu; - - for_each_online_cpu(cpu) { - if (cpuset & (1 << cpu)) { -#ifdef VOYAGER_DEBUG - if (!cpu_online(cpu)) - VDEBUG(("CPU%d sending cpi %d to CPU%d not in " - "cpu_online_map\n", - hard_smp_processor_id(), cpi, cpu)); -#endif - send_one_QIC_CPI(cpu, cpi - QIC_CPI_OFFSET); - } - } -} - -static inline void wrapper_smp_local_timer_interrupt(void) -{ - irq_enter(); - smp_local_timer_interrupt(); - irq_exit(); -} - -static inline void send_one_CPI(__u8 cpu, __u8 cpi) -{ - if (voyager_quad_processors & (1 << cpu)) - send_one_QIC_CPI(cpu, cpi - QIC_CPI_OFFSET); - else - send_CPI(1 << cpu, cpi); -} - -static inline void send_CPI_allbutself(__u8 cpi) -{ - __u8 cpu = smp_processor_id(); - __u32 mask = cpus_addr(cpu_online_map)[0] & ~(1 << cpu); - send_CPI(mask, cpi); -} - -static inline int is_cpu_quad(void) -{ - __u8 cpumask = inb(VIC_PROC_WHO_AM_I); - return ((cpumask & QUAD_IDENTIFIER) == QUAD_IDENTIFIER); -} - -static inline int is_cpu_extended(void) -{ - __u8 cpu = hard_smp_processor_id(); - - return (voyager_extended_vic_processors & (1 << cpu)); -} - -static inline int is_cpu_vic_boot(void) -{ - __u8 cpu = hard_smp_processor_id(); - - return (voyager_extended_vic_processors - & voyager_allowed_boot_processors & (1 << cpu)); -} - -static inline void ack_CPI(__u8 cpi) -{ - switch (cpi) { - case VIC_CPU_BOOT_CPI: - if (is_cpu_quad() && !is_cpu_vic_boot()) - ack_QIC_CPI(cpi); - else - ack_VIC_CPI(cpi); - break; - case VIC_SYS_INT: - case VIC_CMN_INT: - /* These are slightly strange. Even on the Quad card, - * They are vectored as VIC CPIs */ - if (is_cpu_quad()) - ack_special_QIC_CPI(cpi); - else - ack_VIC_CPI(cpi); - break; - default: - printk("VOYAGER ERROR: CPI%d is in common CPI code\n", cpi); - break; - } -} - -/* local variables */ - -/* The VIC IRQ descriptors -- these look almost identical to the - * 8259 IRQs except that masks and things must be kept per processor - */ -static struct irq_chip vic_chip = { - .name = "VIC", - .startup = startup_vic_irq, - .mask = mask_vic_irq, - .unmask = unmask_vic_irq, - .set_affinity = set_vic_irq_affinity, -}; - -/* used to count up as CPUs are brought on line (starts at 0) */ -static int cpucount = 0; - -/* The per cpu profile stuff - used in smp_local_timer_interrupt */ -static DEFINE_PER_CPU(int, prof_multiplier) = 1; -static DEFINE_PER_CPU(int, prof_old_multiplier) = 1; -static DEFINE_PER_CPU(int, prof_counter) = 1; - -/* the map used to check if a CPU has booted */ -static __u32 cpu_booted_map; - -/* the synchronize flag used to hold all secondary CPUs spinning in - * a tight loop until the boot sequence is ready for them */ -static cpumask_t smp_commenced_mask = CPU_MASK_NONE; - -/* This is for the new dynamic CPU boot code */ - -/* The per processor IRQ masks (these are usually kept in sync) */ -static __u16 vic_irq_mask[NR_CPUS] __cacheline_aligned; - -/* the list of IRQs to be enabled by the VIC_ENABLE_IRQ_CPI */ -static __u16 vic_irq_enable_mask[NR_CPUS] __cacheline_aligned = { 0 }; - -/* Lock for enable/disable of VIC interrupts */ -static __cacheline_aligned DEFINE_SPINLOCK(vic_irq_lock); - -/* The boot processor is correctly set up in PC mode when it - * comes up, but the secondaries need their master/slave 8259 - * pairs initializing correctly */ - -/* Interrupt counters (per cpu) and total - used to try to - * even up the interrupt handling routines */ -static long vic_intr_total = 0; -static long vic_intr_count[NR_CPUS] __cacheline_aligned = { 0 }; -static unsigned long vic_tick[NR_CPUS] __cacheline_aligned = { 0 }; - -/* Since we can only use CPI0, we fake all the other CPIs */ -static unsigned long vic_cpi_mailbox[NR_CPUS] __cacheline_aligned; - -/* debugging routine to read the isr of the cpu's pic */ -static inline __u16 vic_read_isr(void) -{ - __u16 isr; - - outb(0x0b, 0xa0); - isr = inb(0xa0) << 8; - outb(0x0b, 0x20); - isr |= inb(0x20); - - return isr; -} - -static __init void qic_setup(void) -{ - if (!is_cpu_quad()) { - /* not a quad, no setup */ - return; - } - outb(QIC_DEFAULT_MASK0, QIC_MASK_REGISTER0); - outb(QIC_CPI_ENABLE, QIC_MASK_REGISTER1); - - if (is_cpu_extended()) { - /* the QIC duplicate of the VIC base register */ - outb(VIC_DEFAULT_CPI_BASE, QIC_VIC_CPI_BASE_REGISTER); - outb(QIC_DEFAULT_CPI_BASE, QIC_CPI_BASE_REGISTER); - - /* FIXME: should set up the QIC timer and memory parity - * error vectors here */ - } -} - -static __init void vic_setup_pic(void) -{ - outb(1, VIC_REDIRECT_REGISTER_1); - /* clear the claim registers for dynamic routing */ - outb(0, VIC_CLAIM_REGISTER_0); - outb(0, VIC_CLAIM_REGISTER_1); - - outb(0, VIC_PRIORITY_REGISTER); - /* Set the Primary and Secondary Microchannel vector - * bases to be the same as the ordinary interrupts - * - * FIXME: This would be more efficient using separate - * vectors. */ - outb(FIRST_EXTERNAL_VECTOR, VIC_PRIMARY_MC_BASE); - outb(FIRST_EXTERNAL_VECTOR, VIC_SECONDARY_MC_BASE); - /* Now initiallise the master PIC belonging to this CPU by - * sending the four ICWs */ - - /* ICW1: level triggered, ICW4 needed */ - outb(0x19, 0x20); - - /* ICW2: vector base */ - outb(FIRST_EXTERNAL_VECTOR, 0x21); - - /* ICW3: slave at line 2 */ - outb(0x04, 0x21); - - /* ICW4: 8086 mode */ - outb(0x01, 0x21); - - /* now the same for the slave PIC */ - - /* ICW1: level trigger, ICW4 needed */ - outb(0x19, 0xA0); - - /* ICW2: slave vector base */ - outb(FIRST_EXTERNAL_VECTOR + 8, 0xA1); - - /* ICW3: slave ID */ - outb(0x02, 0xA1); - - /* ICW4: 8086 mode */ - outb(0x01, 0xA1); -} - -static void do_quad_bootstrap(void) -{ - if (is_cpu_quad() && is_cpu_vic_boot()) { - int i; - unsigned long flags; - __u8 cpuid = hard_smp_processor_id(); - - local_irq_save(flags); - - for (i = 0; i < 4; i++) { - /* FIXME: this would be >>3 &0x7 on the 32 way */ - if (((cpuid >> 2) & 0x03) == i) - /* don't lower our own mask! */ - continue; - - /* masquerade as local Quad CPU */ - outb(QIC_CPUID_ENABLE | i, QIC_PROCESSOR_ID); - /* enable the startup CPI */ - outb(QIC_BOOT_CPI_MASK, QIC_MASK_REGISTER1); - /* restore cpu id */ - outb(0, QIC_PROCESSOR_ID); - } - local_irq_restore(flags); - } -} - -void prefill_possible_map(void) -{ - /* This is empty on voyager because we need a much - * earlier detection which is done in find_smp_config */ -} - -/* Set up all the basic stuff: read the SMP config and make all the - * SMP information reflect only the boot cpu. All others will be - * brought on-line later. */ -void __init find_smp_config(void) -{ - int i; - - boot_cpu_id = hard_smp_processor_id(); - - printk("VOYAGER SMP: Boot cpu is %d\n", boot_cpu_id); - - /* initialize the CPU structures (moved from smp_boot_cpus) */ - for (i = 0; i < nr_cpu_ids; i++) - cpu_irq_affinity[i] = ~0; - cpu_online_map = cpumask_of_cpu(boot_cpu_id); - - /* The boot CPU must be extended */ - voyager_extended_vic_processors = 1 << boot_cpu_id; - /* initially, all of the first 8 CPUs can boot */ - voyager_allowed_boot_processors = 0xff; - /* set up everything for just this CPU, we can alter - * this as we start the other CPUs later */ - /* now get the CPU disposition from the extended CMOS */ - cpus_addr(phys_cpu_present_map)[0] = - voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK); - cpus_addr(phys_cpu_present_map)[0] |= - voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 1) << 8; - cpus_addr(phys_cpu_present_map)[0] |= - voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + - 2) << 16; - cpus_addr(phys_cpu_present_map)[0] |= - voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + - 3) << 24; - init_cpu_possible(&phys_cpu_present_map); - printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n", - cpus_addr(phys_cpu_present_map)[0]); - /* Here we set up the VIC to enable SMP */ - /* enable the CPIs by writing the base vector to their register */ - outb(VIC_DEFAULT_CPI_BASE, VIC_CPI_BASE_REGISTER); - outb(1, VIC_REDIRECT_REGISTER_1); - /* set the claim registers for static routing --- Boot CPU gets - * all interrupts untill all other CPUs started */ - outb(0xff, VIC_CLAIM_REGISTER_0); - outb(0xff, VIC_CLAIM_REGISTER_1); - /* Set the Primary and Secondary Microchannel vector - * bases to be the same as the ordinary interrupts - * - * FIXME: This would be more efficient using separate - * vectors. */ - outb(FIRST_EXTERNAL_VECTOR, VIC_PRIMARY_MC_BASE); - outb(FIRST_EXTERNAL_VECTOR, VIC_SECONDARY_MC_BASE); - - /* Finally tell the firmware that we're driving */ - outb(inb(VOYAGER_SUS_IN_CONTROL_PORT) | VOYAGER_IN_CONTROL_FLAG, - VOYAGER_SUS_IN_CONTROL_PORT); - - current_thread_info()->cpu = boot_cpu_id; - percpu_write(cpu_number, boot_cpu_id); -} - -/* - * The bootstrap kernel entry code has set these up. Save them - * for a given CPU, id is physical */ -void __init smp_store_cpu_info(int id) -{ - struct cpuinfo_x86 *c = &cpu_data(id); - - *c = boot_cpu_data; - c->cpu_index = id; - - identify_secondary_cpu(c); -} - -/* Routine initially called when a non-boot CPU is brought online */ -static void __init start_secondary(void *unused) -{ - __u8 cpuid = hard_smp_processor_id(); - - cpu_init(); - - /* OK, we're in the routine */ - ack_CPI(VIC_CPU_BOOT_CPI); - - /* setup the 8259 master slave pair belonging to this CPU --- - * we won't actually receive any until the boot CPU - * relinquishes it's static routing mask */ - vic_setup_pic(); - - qic_setup(); - - if (is_cpu_quad() && !is_cpu_vic_boot()) { - /* clear the boot CPI */ - __u8 dummy; - - dummy = - voyager_quad_cpi_addr[cpuid]->qic_cpi[VIC_CPU_BOOT_CPI].cpi; - printk("read dummy %d\n", dummy); - } - - /* lower the mask to receive CPIs */ - vic_enable_cpi(); - - VDEBUG(("VOYAGER SMP: CPU%d, stack at about %p\n", cpuid, &cpuid)); - - notify_cpu_starting(cpuid); - - /* enable interrupts */ - local_irq_enable(); - - /* get our bogomips */ - calibrate_delay(); - - /* save our processor parameters */ - smp_store_cpu_info(cpuid); - - /* if we're a quad, we may need to bootstrap other CPUs */ - do_quad_bootstrap(); - - /* FIXME: this is rather a poor hack to prevent the CPU - * activating softirqs while it's supposed to be waiting for - * permission to proceed. Without this, the new per CPU stuff - * in the softirqs will fail */ - local_irq_disable(); - cpu_set(cpuid, cpu_callin_map); - - /* signal that we're done */ - cpu_booted_map = 1; - - while (!cpu_isset(cpuid, smp_commenced_mask)) - rep_nop(); - local_irq_enable(); - - local_flush_tlb(); - - cpu_set(cpuid, cpu_online_map); - wmb(); - cpu_idle(); -} - -/* Routine to kick start the given CPU and wait for it to report ready - * (or timeout in startup). When this routine returns, the requested - * CPU is either fully running and configured or known to be dead. - * - * We call this routine sequentially 1 CPU at a time, so no need for - * locking */ - -static void __init do_boot_cpu(__u8 cpu) -{ - struct task_struct *idle; - int timeout; - unsigned long flags; - int quad_boot = (1 << cpu) & voyager_quad_processors - & ~(voyager_extended_vic_processors - & voyager_allowed_boot_processors); - - /* This is the format of the CPI IDT gate (in real mode) which - * we're hijacking to boot the CPU */ - union IDTFormat { - struct seg { - __u16 Offset; - __u16 Segment; - } idt; - __u32 val; - } hijack_source; - - __u32 *hijack_vector; - __u32 start_phys_address = setup_trampoline(); - - /* There's a clever trick to this: The linux trampoline is - * compiled to begin at absolute location zero, so make the - * address zero but have the data segment selector compensate - * for the actual address */ - hijack_source.idt.Offset = start_phys_address & 0x000F; - hijack_source.idt.Segment = (start_phys_address >> 4) & 0xFFFF; - - cpucount++; - alternatives_smp_switch(1); - - idle = fork_idle(cpu); - if (IS_ERR(idle)) - panic("failed fork for CPU%d", cpu); - idle->thread.ip = (unsigned long)start_secondary; - /* init_tasks (in sched.c) is indexed logically */ - stack_start.sp = (void *)idle->thread.sp; - - per_cpu(current_task, cpu) = idle; - early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); - irq_ctx_init(cpu); - - /* Note: Don't modify initial ss override */ - VDEBUG(("VOYAGER SMP: Booting CPU%d at 0x%lx[%x:%x], stack %p\n", cpu, - (unsigned long)hijack_source.val, hijack_source.idt.Segment, - hijack_source.idt.Offset, stack_start.sp)); - - /* init lowmem identity mapping */ - clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY, - min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY)); - flush_tlb_all(); - - if (quad_boot) { - printk("CPU %d: non extended Quad boot\n", cpu); - hijack_vector = - (__u32 *) - phys_to_virt((VIC_CPU_BOOT_CPI + QIC_DEFAULT_CPI_BASE) * 4); - *hijack_vector = hijack_source.val; - } else { - printk("CPU%d: extended VIC boot\n", cpu); - hijack_vector = - (__u32 *) - phys_to_virt((VIC_CPU_BOOT_CPI + VIC_DEFAULT_CPI_BASE) * 4); - *hijack_vector = hijack_source.val; - /* VIC errata, may also receive interrupt at this address */ - hijack_vector = - (__u32 *) - phys_to_virt((VIC_CPU_BOOT_ERRATA_CPI + - VIC_DEFAULT_CPI_BASE) * 4); - *hijack_vector = hijack_source.val; - } - /* All non-boot CPUs start with interrupts fully masked. Need - * to lower the mask of the CPI we're about to send. We do - * this in the VIC by masquerading as the processor we're - * about to boot and lowering its interrupt mask */ - local_irq_save(flags); - if (quad_boot) { - send_one_QIC_CPI(cpu, VIC_CPU_BOOT_CPI); - } else { - outb(VIC_CPU_MASQUERADE_ENABLE | cpu, VIC_PROCESSOR_ID); - /* here we're altering registers belonging to `cpu' */ - - outb(VIC_BOOT_INTERRUPT_MASK, 0x21); - /* now go back to our original identity */ - outb(boot_cpu_id, VIC_PROCESSOR_ID); - - /* and boot the CPU */ - - send_CPI((1 << cpu), VIC_CPU_BOOT_CPI); - } - cpu_booted_map = 0; - local_irq_restore(flags); - - /* now wait for it to become ready (or timeout) */ - for (timeout = 0; timeout < 50000; timeout++) { - if (cpu_booted_map) - break; - udelay(100); - } - /* reset the page table */ - zap_low_mappings(); - - if (cpu_booted_map) { - VDEBUG(("CPU%d: Booted successfully, back in CPU %d\n", - cpu, smp_processor_id())); - - printk("CPU%d: ", cpu); - print_cpu_info(&cpu_data(cpu)); - wmb(); - cpu_set(cpu, cpu_callout_map); - cpu_set(cpu, cpu_present_map); - } else { - printk("CPU%d FAILED TO BOOT: ", cpu); - if (* - ((volatile unsigned char *)phys_to_virt(start_phys_address)) - == 0xA5) - printk("Stuck.\n"); - else - printk("Not responding.\n"); - - cpucount--; - } -} - -void __init smp_boot_cpus(void) -{ - int i; - - /* CAT BUS initialisation must be done after the memory */ - /* FIXME: The L4 has a catbus too, it just needs to be - * accessed in a totally different way */ - if (voyager_level == 5) { - voyager_cat_init(); - - /* now that the cat has probed the Voyager System Bus, sanity - * check the cpu map */ - if (((voyager_quad_processors | voyager_extended_vic_processors) - & cpus_addr(phys_cpu_present_map)[0]) != - cpus_addr(phys_cpu_present_map)[0]) { - /* should panic */ - printk("\n\n***WARNING*** " - "Sanity check of CPU present map FAILED\n"); - } - } else if (voyager_level == 4) - voyager_extended_vic_processors = - cpus_addr(phys_cpu_present_map)[0]; - - /* this sets up the idle task to run on the current cpu */ - voyager_extended_cpus = 1; - /* Remove the global_irq_holder setting, it triggers a BUG() on - * schedule at the moment */ - //global_irq_holder = boot_cpu_id; - - /* FIXME: Need to do something about this but currently only works - * on CPUs with a tsc which none of mine have. - smp_tune_scheduling(); - */ - smp_store_cpu_info(boot_cpu_id); - /* setup the jump vector */ - initial_code = (unsigned long)initialize_secondary; - printk("CPU%d: ", boot_cpu_id); - print_cpu_info(&cpu_data(boot_cpu_id)); - - if (is_cpu_quad()) { - /* booting on a Quad CPU */ - printk("VOYAGER SMP: Boot CPU is Quad\n"); - qic_setup(); - do_quad_bootstrap(); - } - - /* enable our own CPIs */ - vic_enable_cpi(); - - cpu_set(boot_cpu_id, cpu_online_map); - cpu_set(boot_cpu_id, cpu_callout_map); - - /* loop over all the extended VIC CPUs and boot them. The - * Quad CPUs must be bootstrapped by their extended VIC cpu */ - for (i = 0; i < nr_cpu_ids; i++) { - if (i == boot_cpu_id || !cpu_isset(i, phys_cpu_present_map)) - continue; - do_boot_cpu(i); - /* This udelay seems to be needed for the Quad boots - * don't remove unless you know what you're doing */ - udelay(1000); - } - /* we could compute the total bogomips here, but why bother?, - * Code added from smpboot.c */ - { - unsigned long bogosum = 0; - - for_each_online_cpu(i) - bogosum += cpu_data(i).loops_per_jiffy; - printk(KERN_INFO "Total of %d processors activated " - "(%lu.%02lu BogoMIPS).\n", - cpucount + 1, bogosum / (500000 / HZ), - (bogosum / (5000 / HZ)) % 100); - } - voyager_extended_cpus = hweight32(voyager_extended_vic_processors); - printk("VOYAGER: Extended (interrupt handling CPUs): " - "%d, non-extended: %d\n", voyager_extended_cpus, - num_booting_cpus() - voyager_extended_cpus); - /* that's it, switch to symmetric mode */ - outb(0, VIC_PRIORITY_REGISTER); - outb(0, VIC_CLAIM_REGISTER_0); - outb(0, VIC_CLAIM_REGISTER_1); - - VDEBUG(("VOYAGER SMP: Booted with %d CPUs\n", num_booting_cpus())); -} - -/* Reload the secondary CPUs task structure (this function does not - * return ) */ -static void __init initialize_secondary(void) -{ -#if 0 - // AC kernels only - set_current(hard_get_current()); -#endif - - /* - * We don't actually need to load the full TSS, - * basically just the stack pointer and the eip. - */ - - asm volatile ("movl %0,%%esp\n\t" - "jmp *%1"::"r" (current->thread.sp), - "r"(current->thread.ip)); -} - -/* handle a Voyager SYS_INT -- If we don't, the base board will - * panic the system. - * - * System interrupts occur because some problem was detected on the - * various busses. To find out what you have to probe all the - * hardware via the CAT bus. FIXME: At the moment we do nothing. */ -void smp_vic_sys_interrupt(struct pt_regs *regs) -{ - ack_CPI(VIC_SYS_INT); - printk("Voyager SYSTEM INTERRUPT\n"); -} - -/* Handle a voyager CMN_INT; These interrupts occur either because of - * a system status change or because a single bit memory error - * occurred. FIXME: At the moment, ignore all this. */ -void smp_vic_cmn_interrupt(struct pt_regs *regs) -{ - static __u8 in_cmn_int = 0; - static DEFINE_SPINLOCK(cmn_int_lock); - - /* common ints are broadcast, so make sure we only do this once */ - _raw_spin_lock(&cmn_int_lock); - if (in_cmn_int) - goto unlock_end; - - in_cmn_int++; - _raw_spin_unlock(&cmn_int_lock); - - VDEBUG(("Voyager COMMON INTERRUPT\n")); - - if (voyager_level == 5) - voyager_cat_do_common_interrupt(); - - _raw_spin_lock(&cmn_int_lock); - in_cmn_int = 0; - unlock_end: - _raw_spin_unlock(&cmn_int_lock); - ack_CPI(VIC_CMN_INT); -} - -/* - * Reschedule call back. Nothing to do, all the work is done - * automatically when we return from the interrupt. */ -static void smp_reschedule_interrupt(void) -{ - /* do nothing */ -} - -static struct mm_struct *flush_mm; -static unsigned long flush_va; -static DEFINE_SPINLOCK(tlbstate_lock); - -/* - * We cannot call mmdrop() because we are in interrupt context, - * instead update mm->cpu_vm_mask. - * - * We need to reload %cr3 since the page tables may be going - * away from under us.. - */ -static inline void voyager_leave_mm(unsigned long cpu) -{ - if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK) - BUG(); - cpu_clear(cpu, per_cpu(cpu_tlbstate, cpu).active_mm->cpu_vm_mask); - load_cr3(swapper_pg_dir); -} - -/* - * Invalidate call-back - */ -static void smp_invalidate_interrupt(void) -{ - __u8 cpu = smp_processor_id(); - - if (!test_bit(cpu, &smp_invalidate_needed)) - return; - /* This will flood messages. Don't uncomment unless you see - * Problems with cross cpu invalidation - VDEBUG(("VOYAGER SMP: CPU%d received INVALIDATE_CPI\n", - smp_processor_id())); - */ - - if (flush_mm == per_cpu(cpu_tlbstate, cpu).active_mm) { - if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK) { - if (flush_va == TLB_FLUSH_ALL) - local_flush_tlb(); - else - __flush_tlb_one(flush_va); - } else - voyager_leave_mm(cpu); - } - smp_mb__before_clear_bit(); - clear_bit(cpu, &smp_invalidate_needed); - smp_mb__after_clear_bit(); -} - -/* All the new flush operations for 2.4 */ - -/* This routine is called with a physical cpu mask */ -static void -voyager_flush_tlb_others(unsigned long cpumask, struct mm_struct *mm, - unsigned long va) -{ - int stuck = 50000; - - if (!cpumask) - BUG(); - if ((cpumask & cpus_addr(cpu_online_map)[0]) != cpumask) - BUG(); - if (cpumask & (1 << smp_processor_id())) - BUG(); - if (!mm) - BUG(); - - spin_lock(&tlbstate_lock); - - flush_mm = mm; - flush_va = va; - atomic_set_mask(cpumask, &smp_invalidate_needed); - /* - * We have to send the CPI only to - * CPUs affected. - */ - send_CPI(cpumask, VIC_INVALIDATE_CPI); - - while (smp_invalidate_needed) { - mb(); - if (--stuck == 0) { - printk("***WARNING*** Stuck doing invalidate CPI " - "(CPU%d)\n", smp_processor_id()); - break; - } - } - - /* Uncomment only to debug invalidation problems - VDEBUG(("VOYAGER SMP: Completed invalidate CPI (CPU%d)\n", cpu)); - */ - - flush_mm = NULL; - flush_va = 0; - spin_unlock(&tlbstate_lock); -} - -void flush_tlb_current_task(void) -{ - struct mm_struct *mm = current->mm; - unsigned long cpu_mask; - - preempt_disable(); - - cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id()); - local_flush_tlb(); - if (cpu_mask) - voyager_flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL); - - preempt_enable(); -} - -void flush_tlb_mm(struct mm_struct *mm) -{ - unsigned long cpu_mask; - - preempt_disable(); - - cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id()); - - if (current->active_mm == mm) { - if (current->mm) - local_flush_tlb(); - else - voyager_leave_mm(smp_processor_id()); - } - if (cpu_mask) - voyager_flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL); - - preempt_enable(); -} - -void flush_tlb_page(struct vm_area_struct *vma, unsigned long va) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long cpu_mask; - - preempt_disable(); - - cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id()); - if (current->active_mm == mm) { - if (current->mm) - __flush_tlb_one(va); - else - voyager_leave_mm(smp_processor_id()); - } - - if (cpu_mask) - voyager_flush_tlb_others(cpu_mask, mm, va); - - preempt_enable(); -} - -EXPORT_SYMBOL(flush_tlb_page); - -/* enable the requested IRQs */ -static void smp_enable_irq_interrupt(void) -{ - __u8 irq; - __u8 cpu = get_cpu(); - - VDEBUG(("VOYAGER SMP: CPU%d enabling irq mask 0x%x\n", cpu, - vic_irq_enable_mask[cpu])); - - spin_lock(&vic_irq_lock); - for (irq = 0; irq < 16; irq++) { - if (vic_irq_enable_mask[cpu] & (1 << irq)) - enable_local_vic_irq(irq); - } - vic_irq_enable_mask[cpu] = 0; - spin_unlock(&vic_irq_lock); - - put_cpu_no_resched(); -} - -/* - * CPU halt call-back - */ -static void smp_stop_cpu_function(void *dummy) -{ - VDEBUG(("VOYAGER SMP: CPU%d is STOPPING\n", smp_processor_id())); - cpu_clear(smp_processor_id(), cpu_online_map); - local_irq_disable(); - for (;;) - halt(); -} - -/* execute a thread on a new CPU. The function to be called must be - * previously set up. This is used to schedule a function for - * execution on all CPUs - set up the function then broadcast a - * function_interrupt CPI to come here on each CPU */ -static void smp_call_function_interrupt(void) -{ - irq_enter(); - generic_smp_call_function_interrupt(); - __get_cpu_var(irq_stat).irq_call_count++; - irq_exit(); -} - -static void smp_call_function_single_interrupt(void) -{ - irq_enter(); - generic_smp_call_function_single_interrupt(); - __get_cpu_var(irq_stat).irq_call_count++; - irq_exit(); -} - -/* Sorry about the name. In an APIC based system, the APICs - * themselves are programmed to send a timer interrupt. This is used - * by linux to reschedule the processor. Voyager doesn't have this, - * so we use the system clock to interrupt one processor, which in - * turn, broadcasts a timer CPI to all the others --- we receive that - * CPI here. We don't use this actually for counting so losing - * ticks doesn't matter - * - * FIXME: For those CPUs which actually have a local APIC, we could - * try to use it to trigger this interrupt instead of having to - * broadcast the timer tick. Unfortunately, all my pentium DYADs have - * no local APIC, so I can't do this - * - * This function is currently a placeholder and is unused in the code */ -void smp_apic_timer_interrupt(struct pt_regs *regs) -{ - struct pt_regs *old_regs = set_irq_regs(regs); - wrapper_smp_local_timer_interrupt(); - set_irq_regs(old_regs); -} - -/* All of the QUAD interrupt GATES */ -void smp_qic_timer_interrupt(struct pt_regs *regs) -{ - struct pt_regs *old_regs = set_irq_regs(regs); - ack_QIC_CPI(QIC_TIMER_CPI); - wrapper_smp_local_timer_interrupt(); - set_irq_regs(old_regs); -} - -void smp_qic_invalidate_interrupt(struct pt_regs *regs) -{ - ack_QIC_CPI(QIC_INVALIDATE_CPI); - smp_invalidate_interrupt(); -} - -void smp_qic_reschedule_interrupt(struct pt_regs *regs) -{ - ack_QIC_CPI(QIC_RESCHEDULE_CPI); - smp_reschedule_interrupt(); -} - -void smp_qic_enable_irq_interrupt(struct pt_regs *regs) -{ - ack_QIC_CPI(QIC_ENABLE_IRQ_CPI); - smp_enable_irq_interrupt(); -} - -void smp_qic_call_function_interrupt(struct pt_regs *regs) -{ - ack_QIC_CPI(QIC_CALL_FUNCTION_CPI); - smp_call_function_interrupt(); -} - -void smp_qic_call_function_single_interrupt(struct pt_regs *regs) -{ - ack_QIC_CPI(QIC_CALL_FUNCTION_SINGLE_CPI); - smp_call_function_single_interrupt(); -} - -void smp_vic_cpi_interrupt(struct pt_regs *regs) -{ - struct pt_regs *old_regs = set_irq_regs(regs); - __u8 cpu = smp_processor_id(); - - if (is_cpu_quad()) - ack_QIC_CPI(VIC_CPI_LEVEL0); - else - ack_VIC_CPI(VIC_CPI_LEVEL0); - - if (test_and_clear_bit(VIC_TIMER_CPI, &vic_cpi_mailbox[cpu])) - wrapper_smp_local_timer_interrupt(); - if (test_and_clear_bit(VIC_INVALIDATE_CPI, &vic_cpi_mailbox[cpu])) - smp_invalidate_interrupt(); - if (test_and_clear_bit(VIC_RESCHEDULE_CPI, &vic_cpi_mailbox[cpu])) - smp_reschedule_interrupt(); - if (test_and_clear_bit(VIC_ENABLE_IRQ_CPI, &vic_cpi_mailbox[cpu])) - smp_enable_irq_interrupt(); - if (test_and_clear_bit(VIC_CALL_FUNCTION_CPI, &vic_cpi_mailbox[cpu])) - smp_call_function_interrupt(); - if (test_and_clear_bit(VIC_CALL_FUNCTION_SINGLE_CPI, &vic_cpi_mailbox[cpu])) - smp_call_function_single_interrupt(); - set_irq_regs(old_regs); -} - -static void do_flush_tlb_all(void *info) -{ - unsigned long cpu = smp_processor_id(); - - __flush_tlb_all(); - if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_LAZY) - voyager_leave_mm(cpu); -} - -/* flush the TLB of every active CPU in the system */ -void flush_tlb_all(void) -{ - on_each_cpu(do_flush_tlb_all, 0, 1); -} - -/* send a reschedule CPI to one CPU by physical CPU number*/ -static void voyager_smp_send_reschedule(int cpu) -{ - send_one_CPI(cpu, VIC_RESCHEDULE_CPI); -} - -int hard_smp_processor_id(void) -{ - __u8 i; - __u8 cpumask = inb(VIC_PROC_WHO_AM_I); - if ((cpumask & QUAD_IDENTIFIER) == QUAD_IDENTIFIER) - return cpumask & 0x1F; - - for (i = 0; i < 8; i++) { - if (cpumask & (1 << i)) - return i; - } - printk("** WARNING ** Illegal cpuid returned by VIC: %d", cpumask); - return 0; -} - -int safe_smp_processor_id(void) -{ - return hard_smp_processor_id(); -} - -/* broadcast a halt to all other CPUs */ -static void voyager_smp_send_stop(void) -{ - smp_call_function(smp_stop_cpu_function, NULL, 1); -} - -/* this function is triggered in time.c when a clock tick fires - * we need to re-broadcast the tick to all CPUs */ -void smp_vic_timer_interrupt(void) -{ - send_CPI_allbutself(VIC_TIMER_CPI); - smp_local_timer_interrupt(); -} - -/* local (per CPU) timer interrupt. It does both profiling and - * process statistics/rescheduling. - * - * We do profiling in every local tick, statistics/rescheduling - * happen only every 'profiling multiplier' ticks. The default - * multiplier is 1 and it can be changed by writing the new multiplier - * value into /proc/profile. - */ -void smp_local_timer_interrupt(void) -{ - int cpu = smp_processor_id(); - long weight; - - profile_tick(CPU_PROFILING); - if (--per_cpu(prof_counter, cpu) <= 0) { - /* - * The multiplier may have changed since the last time we got - * to this point as a result of the user writing to - * /proc/profile. In this case we need to adjust the APIC - * timer accordingly. - * - * Interrupts are already masked off at this point. - */ - per_cpu(prof_counter, cpu) = per_cpu(prof_multiplier, cpu); - if (per_cpu(prof_counter, cpu) != - per_cpu(prof_old_multiplier, cpu)) { - /* FIXME: need to update the vic timer tick here */ - per_cpu(prof_old_multiplier, cpu) = - per_cpu(prof_counter, cpu); - } - - update_process_times(user_mode_vm(get_irq_regs())); - } - - if (((1 << cpu) & voyager_extended_vic_processors) == 0) - /* only extended VIC processors participate in - * interrupt distribution */ - return; - - /* - * We take the 'long' return path, and there every subsystem - * grabs the appropriate locks (kernel lock/ irq lock). - * - * we might want to decouple profiling from the 'long path', - * and do the profiling totally in assembly. - * - * Currently this isn't too much of an issue (performance wise), - * we can take more than 100K local irqs per second on a 100 MHz P5. - */ - - if ((++vic_tick[cpu] & 0x7) != 0) - return; - /* get here every 16 ticks (about every 1/6 of a second) */ - - /* Change our priority to give someone else a chance at getting - * the IRQ. The algorithm goes like this: - * - * In the VIC, the dynamically routed interrupt is always - * handled by the lowest priority eligible (i.e. receiving - * interrupts) CPU. If >1 eligible CPUs are equal lowest, the - * lowest processor number gets it. - * - * The priority of a CPU is controlled by a special per-CPU - * VIC priority register which is 3 bits wide 0 being lowest - * and 7 highest priority.. - * - * Therefore we subtract the average number of interrupts from - * the number we've fielded. If this number is negative, we - * lower the activity count and if it is positive, we raise - * it. - * - * I'm afraid this still leads to odd looking interrupt counts: - * the totals are all roughly equal, but the individual ones - * look rather skewed. - * - * FIXME: This algorithm is total crap when mixed with SMP - * affinity code since we now try to even up the interrupt - * counts when an affinity binding is keeping them on a - * particular CPU*/ - weight = (vic_intr_count[cpu] * voyager_extended_cpus - - vic_intr_total) >> 4; - weight += 4; - if (weight > 7) - weight = 7; - if (weight < 0) - weight = 0; - - outb((__u8) weight, VIC_PRIORITY_REGISTER); - -#ifdef VOYAGER_DEBUG - if ((vic_tick[cpu] & 0xFFF) == 0) { - /* print this message roughly every 25 secs */ - printk("VOYAGER SMP: vic_tick[%d] = %lu, weight = %ld\n", - cpu, vic_tick[cpu], weight); - } -#endif -} - -/* setup the profiling timer */ -int setup_profiling_timer(unsigned int multiplier) -{ - int i; - - if ((!multiplier)) - return -EINVAL; - - /* - * Set the new multiplier for each CPU. CPUs don't start using the - * new values until the next timer interrupt in which they do process - * accounting. - */ - for (i = 0; i < nr_cpu_ids; ++i) - per_cpu(prof_multiplier, i) = multiplier; - - return 0; -} - -/* This is a bit of a mess, but forced on us by the genirq changes - * there's no genirq handler that really does what voyager wants - * so hack it up with the simple IRQ handler */ -static void handle_vic_irq(unsigned int irq, struct irq_desc *desc) -{ - before_handle_vic_irq(irq); - handle_simple_irq(irq, desc); - after_handle_vic_irq(irq); -} - -/* The CPIs are handled in the per cpu 8259s, so they must be - * enabled to be received: FIX: enabling the CPIs in the early - * boot sequence interferes with bug checking; enable them later - * on in smp_init */ -#define VIC_SET_GATE(cpi, vector) \ - set_intr_gate((cpi) + VIC_DEFAULT_CPI_BASE, (vector)) -#define QIC_SET_GATE(cpi, vector) \ - set_intr_gate((cpi) + QIC_DEFAULT_CPI_BASE, (vector)) - -void __init voyager_smp_intr_init(void) -{ - int i; - - /* initialize the per cpu irq mask to all disabled */ - for (i = 0; i < nr_cpu_ids; i++) - vic_irq_mask[i] = 0xFFFF; - - VIC_SET_GATE(VIC_CPI_LEVEL0, vic_cpi_interrupt); - - VIC_SET_GATE(VIC_SYS_INT, vic_sys_interrupt); - VIC_SET_GATE(VIC_CMN_INT, vic_cmn_interrupt); - - QIC_SET_GATE(QIC_TIMER_CPI, qic_timer_interrupt); - QIC_SET_GATE(QIC_INVALIDATE_CPI, qic_invalidate_interrupt); - QIC_SET_GATE(QIC_RESCHEDULE_CPI, qic_reschedule_interrupt); - QIC_SET_GATE(QIC_ENABLE_IRQ_CPI, qic_enable_irq_interrupt); - QIC_SET_GATE(QIC_CALL_FUNCTION_CPI, qic_call_function_interrupt); - - /* now put the VIC descriptor into the first 48 IRQs - * - * This is for later: first 16 correspond to PC IRQs; next 16 - * are Primary MC IRQs and final 16 are Secondary MC IRQs */ - for (i = 0; i < 48; i++) - set_irq_chip_and_handler(i, &vic_chip, handle_vic_irq); -} - -/* send a CPI at level cpi to a set of cpus in cpuset (set 1 bit per - * processor to receive CPI */ -static void send_CPI(__u32 cpuset, __u8 cpi) -{ - int cpu; - __u32 quad_cpuset = (cpuset & voyager_quad_processors); - - if (cpi < VIC_START_FAKE_CPI) { - /* fake CPI are only used for booting, so send to the - * extended quads as well---Quads must be VIC booted */ - outb((__u8) (cpuset), VIC_CPI_Registers[cpi]); - return; - } - if (quad_cpuset) - send_QIC_CPI(quad_cpuset, cpi); - cpuset &= ~quad_cpuset; - cpuset &= 0xff; /* only first 8 CPUs vaild for VIC CPI */ - if (cpuset == 0) - return; - for_each_online_cpu(cpu) { - if (cpuset & (1 << cpu)) - set_bit(cpi, &vic_cpi_mailbox[cpu]); - } - if (cpuset) - outb((__u8) cpuset, VIC_CPI_Registers[VIC_CPI_LEVEL0]); -} - -/* Acknowledge receipt of CPI in the QIC, clear in QIC hardware and - * set the cache line to shared by reading it. - * - * DON'T make this inline otherwise the cache line read will be - * optimised away - * */ -static int ack_QIC_CPI(__u8 cpi) -{ - __u8 cpu = hard_smp_processor_id(); - - cpi &= 7; - - outb(1 << cpi, QIC_INTERRUPT_CLEAR1); - return voyager_quad_cpi_addr[cpu]->qic_cpi[cpi].cpi; -} - -static void ack_special_QIC_CPI(__u8 cpi) -{ - switch (cpi) { - case VIC_CMN_INT: - outb(QIC_CMN_INT, QIC_INTERRUPT_CLEAR0); - break; - case VIC_SYS_INT: - outb(QIC_SYS_INT, QIC_INTERRUPT_CLEAR0); - break; - } - /* also clear at the VIC, just in case (nop for non-extended proc) */ - ack_VIC_CPI(cpi); -} - -/* Acknowledge receipt of CPI in the VIC (essentially an EOI) */ -static void ack_VIC_CPI(__u8 cpi) -{ -#ifdef VOYAGER_DEBUG - unsigned long flags; - __u16 isr; - __u8 cpu = smp_processor_id(); - - local_irq_save(flags); - isr = vic_read_isr(); - if ((isr & (1 << (cpi & 7))) == 0) { - printk("VOYAGER SMP: CPU%d lost CPI%d\n", cpu, cpi); - } -#endif - /* send specific EOI; the two system interrupts have - * bit 4 set for a separate vector but behave as the - * corresponding 3 bit intr */ - outb_p(0x60 | (cpi & 7), 0x20); - -#ifdef VOYAGER_DEBUG - if ((vic_read_isr() & (1 << (cpi & 7))) != 0) { - printk("VOYAGER SMP: CPU%d still asserting CPI%d\n", cpu, cpi); - } - local_irq_restore(flags); -#endif -} - -/* cribbed with thanks from irq.c */ -#define __byte(x,y) (((unsigned char *)&(y))[x]) -#define cached_21(cpu) (__byte(0,vic_irq_mask[cpu])) -#define cached_A1(cpu) (__byte(1,vic_irq_mask[cpu])) - -static unsigned int startup_vic_irq(unsigned int irq) -{ - unmask_vic_irq(irq); - - return 0; -} - -/* The enable and disable routines. This is where we run into - * conflicting architectural philosophy. Fundamentally, the voyager - * architecture does not expect to have to disable interrupts globally - * (the IRQ controllers belong to each CPU). The processor masquerade - * which is used to start the system shouldn't be used in a running OS - * since it will cause great confusion if two separate CPUs drive to - * the same IRQ controller (I know, I've tried it). - * - * The solution is a variant on the NCR lazy SPL design: - * - * 1) To disable an interrupt, do nothing (other than set the - * IRQ_DISABLED flag). This dares the interrupt actually to arrive. - * - * 2) If the interrupt dares to come in, raise the local mask against - * it (this will result in all the CPU masks being raised - * eventually). - * - * 3) To enable the interrupt, lower the mask on the local CPU and - * broadcast an Interrupt enable CPI which causes all other CPUs to - * adjust their masks accordingly. */ - -static void unmask_vic_irq(unsigned int irq) -{ - /* linux doesn't to processor-irq affinity, so enable on - * all CPUs we know about */ - int cpu = smp_processor_id(), real_cpu; - __u16 mask = (1 << irq); - __u32 processorList = 0; - unsigned long flags; - - VDEBUG(("VOYAGER: unmask_vic_irq(%d) CPU%d affinity 0x%lx\n", - irq, cpu, cpu_irq_affinity[cpu])); - spin_lock_irqsave(&vic_irq_lock, flags); - for_each_online_cpu(real_cpu) { - if (!(voyager_extended_vic_processors & (1 << real_cpu))) - continue; - if (!(cpu_irq_affinity[real_cpu] & mask)) { - /* irq has no affinity for this CPU, ignore */ - continue; - } - if (real_cpu == cpu) { - enable_local_vic_irq(irq); - } else if (vic_irq_mask[real_cpu] & mask) { - vic_irq_enable_mask[real_cpu] |= mask; - processorList |= (1 << real_cpu); - } - } - spin_unlock_irqrestore(&vic_irq_lock, flags); - if (processorList) - send_CPI(processorList, VIC_ENABLE_IRQ_CPI); -} - -static void mask_vic_irq(unsigned int irq) -{ - /* lazy disable, do nothing */ -} - -static void enable_local_vic_irq(unsigned int irq) -{ - __u8 cpu = smp_processor_id(); - __u16 mask = ~(1 << irq); - __u16 old_mask = vic_irq_mask[cpu]; - - vic_irq_mask[cpu] &= mask; - if (vic_irq_mask[cpu] == old_mask) - return; - - VDEBUG(("VOYAGER DEBUG: Enabling irq %d in hardware on CPU %d\n", - irq, cpu)); - - if (irq & 8) { - outb_p(cached_A1(cpu), 0xA1); - (void)inb_p(0xA1); - } else { - outb_p(cached_21(cpu), 0x21); - (void)inb_p(0x21); - } -} - -static void disable_local_vic_irq(unsigned int irq) -{ - __u8 cpu = smp_processor_id(); - __u16 mask = (1 << irq); - __u16 old_mask = vic_irq_mask[cpu]; - - if (irq == 7) - return; - - vic_irq_mask[cpu] |= mask; - if (old_mask == vic_irq_mask[cpu]) - return; - - VDEBUG(("VOYAGER DEBUG: Disabling irq %d in hardware on CPU %d\n", - irq, cpu)); - - if (irq & 8) { - outb_p(cached_A1(cpu), 0xA1); - (void)inb_p(0xA1); - } else { - outb_p(cached_21(cpu), 0x21); - (void)inb_p(0x21); - } -} - -/* The VIC is level triggered, so the ack can only be issued after the - * interrupt completes. However, we do Voyager lazy interrupt - * handling here: It is an extremely expensive operation to mask an - * interrupt in the vic, so we merely set a flag (IRQ_DISABLED). If - * this interrupt actually comes in, then we mask and ack here to push - * the interrupt off to another CPU */ -static void before_handle_vic_irq(unsigned int irq) -{ - irq_desc_t *desc = irq_to_desc(irq); - __u8 cpu = smp_processor_id(); - - _raw_spin_lock(&vic_irq_lock); - vic_intr_total++; - vic_intr_count[cpu]++; - - if (!(cpu_irq_affinity[cpu] & (1 << irq))) { - /* The irq is not in our affinity mask, push it off - * onto another CPU */ - VDEBUG(("VOYAGER DEBUG: affinity triggered disable of irq %d " - "on cpu %d\n", irq, cpu)); - disable_local_vic_irq(irq); - /* set IRQ_INPROGRESS to prevent the handler in irq.c from - * actually calling the interrupt routine */ - desc->status |= IRQ_REPLAY | IRQ_INPROGRESS; - } else if (desc->status & IRQ_DISABLED) { - /* Damn, the interrupt actually arrived, do the lazy - * disable thing. The interrupt routine in irq.c will - * not handle a IRQ_DISABLED interrupt, so nothing more - * need be done here */ - VDEBUG(("VOYAGER DEBUG: lazy disable of irq %d on CPU %d\n", - irq, cpu)); - disable_local_vic_irq(irq); - desc->status |= IRQ_REPLAY; - } else { - desc->status &= ~IRQ_REPLAY; - } - - _raw_spin_unlock(&vic_irq_lock); -} - -/* Finish the VIC interrupt: basically mask */ -static void after_handle_vic_irq(unsigned int irq) -{ - irq_desc_t *desc = irq_to_desc(irq); - - _raw_spin_lock(&vic_irq_lock); - { - unsigned int status = desc->status & ~IRQ_INPROGRESS; -#ifdef VOYAGER_DEBUG - __u16 isr; -#endif - - desc->status = status; - if ((status & IRQ_DISABLED)) - disable_local_vic_irq(irq); -#ifdef VOYAGER_DEBUG - /* DEBUG: before we ack, check what's in progress */ - isr = vic_read_isr(); - if ((isr & (1 << irq) && !(status & IRQ_REPLAY)) == 0) { - int i; - __u8 cpu = smp_processor_id(); - __u8 real_cpu; - int mask; /* Um... initialize me??? --RR */ - - printk("VOYAGER SMP: CPU%d lost interrupt %d\n", - cpu, irq); - for_each_possible_cpu(real_cpu, mask) { - - outb(VIC_CPU_MASQUERADE_ENABLE | real_cpu, - VIC_PROCESSOR_ID); - isr = vic_read_isr(); - if (isr & (1 << irq)) { - printk - ("VOYAGER SMP: CPU%d ack irq %d\n", - real_cpu, irq); - ack_vic_irq(irq); - } - outb(cpu, VIC_PROCESSOR_ID); - } - } -#endif /* VOYAGER_DEBUG */ - /* as soon as we ack, the interrupt is eligible for - * receipt by another CPU so everything must be in - * order here */ - ack_vic_irq(irq); - if (status & IRQ_REPLAY) { - /* replay is set if we disable the interrupt - * in the before_handle_vic_irq() routine, so - * clear the in progress bit here to allow the - * next CPU to handle this correctly */ - desc->status &= ~(IRQ_REPLAY | IRQ_INPROGRESS); - } -#ifdef VOYAGER_DEBUG - isr = vic_read_isr(); - if ((isr & (1 << irq)) != 0) - printk("VOYAGER SMP: after_handle_vic_irq() after " - "ack irq=%d, isr=0x%x\n", irq, isr); -#endif /* VOYAGER_DEBUG */ - } - _raw_spin_unlock(&vic_irq_lock); - - /* All code after this point is out of the main path - the IRQ - * may be intercepted by another CPU if reasserted */ -} - -/* Linux processor - interrupt affinity manipulations. - * - * For each processor, we maintain a 32 bit irq affinity mask. - * Initially it is set to all 1's so every processor accepts every - * interrupt. In this call, we change the processor's affinity mask: - * - * Change from enable to disable: - * - * If the interrupt ever comes in to the processor, we will disable it - * and ack it to push it off to another CPU, so just accept the mask here. - * - * Change from disable to enable: - * - * change the mask and then do an interrupt enable CPI to re-enable on - * the selected processors */ - -void set_vic_irq_affinity(unsigned int irq, const struct cpumask *mask) -{ - /* Only extended processors handle interrupts */ - unsigned long real_mask; - unsigned long irq_mask = 1 << irq; - int cpu; - - real_mask = cpus_addr(*mask)[0] & voyager_extended_vic_processors; - - if (cpus_addr(*mask)[0] == 0) - /* can't have no CPUs to accept the interrupt -- extremely - * bad things will happen */ - return; - - if (irq == 0) - /* can't change the affinity of the timer IRQ. This - * is due to the constraint in the voyager - * architecture that the CPI also comes in on and IRQ - * line and we have chosen IRQ0 for this. If you - * raise the mask on this interrupt, the processor - * will no-longer be able to accept VIC CPIs */ - return; - - if (irq >= 32) - /* You can only have 32 interrupts in a voyager system - * (and 32 only if you have a secondary microchannel - * bus) */ - return; - - for_each_online_cpu(cpu) { - unsigned long cpu_mask = 1 << cpu; - - if (cpu_mask & real_mask) { - /* enable the interrupt for this cpu */ - cpu_irq_affinity[cpu] |= irq_mask; - } else { - /* disable the interrupt for this cpu */ - cpu_irq_affinity[cpu] &= ~irq_mask; - } - } - /* this is magic, we now have the correct affinity maps, so - * enable the interrupt. This will send an enable CPI to - * those CPUs who need to enable it in their local masks, - * causing them to correct for the new affinity . If the - * interrupt is currently globally disabled, it will simply be - * disabled again as it comes in (voyager lazy disable). If - * the affinity map is tightened to disable the interrupt on a - * cpu, it will be pushed off when it comes in */ - unmask_vic_irq(irq); -} - -static void ack_vic_irq(unsigned int irq) -{ - if (irq & 8) { - outb(0x62, 0x20); /* Specific EOI to cascade */ - outb(0x60 | (irq & 7), 0xA0); - } else { - outb(0x60 | (irq & 7), 0x20); - } -} - -/* enable the CPIs. In the VIC, the CPIs are delivered by the 8259 - * but are not vectored by it. This means that the 8259 mask must be - * lowered to receive them */ -static __init void vic_enable_cpi(void) -{ - __u8 cpu = smp_processor_id(); - - /* just take a copy of the current mask (nop for boot cpu) */ - vic_irq_mask[cpu] = vic_irq_mask[boot_cpu_id]; - - enable_local_vic_irq(VIC_CPI_LEVEL0); - enable_local_vic_irq(VIC_CPI_LEVEL1); - /* for sys int and cmn int */ - enable_local_vic_irq(7); - - if (is_cpu_quad()) { - outb(QIC_DEFAULT_MASK0, QIC_MASK_REGISTER0); - outb(QIC_CPI_ENABLE, QIC_MASK_REGISTER1); - VDEBUG(("VOYAGER SMP: QIC ENABLE CPI: CPU%d: MASK 0x%x\n", - cpu, QIC_CPI_ENABLE)); - } - - VDEBUG(("VOYAGER SMP: ENABLE CPI: CPU%d: MASK 0x%x\n", - cpu, vic_irq_mask[cpu])); -} - -void voyager_smp_dump() -{ - int old_cpu = smp_processor_id(), cpu; - - /* dump the interrupt masks of each processor */ - for_each_online_cpu(cpu) { - __u16 imr, isr, irr; - unsigned long flags; - - local_irq_save(flags); - outb(VIC_CPU_MASQUERADE_ENABLE | cpu, VIC_PROCESSOR_ID); - imr = (inb(0xa1) << 8) | inb(0x21); - outb(0x0a, 0xa0); - irr = inb(0xa0) << 8; - outb(0x0a, 0x20); - irr |= inb(0x20); - outb(0x0b, 0xa0); - isr = inb(0xa0) << 8; - outb(0x0b, 0x20); - isr |= inb(0x20); - outb(old_cpu, VIC_PROCESSOR_ID); - local_irq_restore(flags); - printk("\tCPU%d: mask=0x%x, IMR=0x%x, IRR=0x%x, ISR=0x%x\n", - cpu, vic_irq_mask[cpu], imr, irr, isr); -#if 0 - /* These lines are put in to try to unstick an un ack'd irq */ - if (isr != 0) { - int irq; - for (irq = 0; irq < 16; irq++) { - if (isr & (1 << irq)) { - printk("\tCPU%d: ack irq %d\n", - cpu, irq); - local_irq_save(flags); - outb(VIC_CPU_MASQUERADE_ENABLE | cpu, - VIC_PROCESSOR_ID); - ack_vic_irq(irq); - outb(old_cpu, VIC_PROCESSOR_ID); - local_irq_restore(flags); - } - } - } -#endif - } -} - -void smp_voyager_power_off(void *dummy) -{ - if (smp_processor_id() == boot_cpu_id) - voyager_power_off(); - else - smp_stop_cpu_function(NULL); -} - -static void __init voyager_smp_prepare_cpus(unsigned int max_cpus) -{ - /* FIXME: ignore max_cpus for now */ - smp_boot_cpus(); -} - -static void __cpuinit voyager_smp_prepare_boot_cpu(void) -{ - int cpu = smp_processor_id(); - switch_to_new_gdt(cpu); - - cpu_set(cpu, cpu_online_map); - cpu_set(cpu, cpu_callout_map); - cpu_set(cpu, cpu_possible_map); - cpu_set(cpu, cpu_present_map); - -} - -static int __cpuinit voyager_cpu_up(unsigned int cpu) -{ - /* This only works at boot for x86. See "rewrite" above. */ - if (cpu_isset(cpu, smp_commenced_mask)) - return -ENOSYS; - - /* In case one didn't come up */ - if (!cpu_isset(cpu, cpu_callin_map)) - return -EIO; - /* Unleash the CPU! */ - cpu_set(cpu, smp_commenced_mask); - while (!cpu_online(cpu)) - mb(); - return 0; -} - -static void __init voyager_smp_cpus_done(unsigned int max_cpus) -{ - zap_low_mappings(); -} - -void __init smp_setup_processor_id(void) -{ - current_thread_info()->cpu = hard_smp_processor_id(); -} - -static void voyager_send_call_func(const struct cpumask *callmask) -{ - __u32 mask = cpus_addr(*callmask)[0] & ~(1 << smp_processor_id()); - send_CPI(mask, VIC_CALL_FUNCTION_CPI); -} - -static void voyager_send_call_func_single(int cpu) -{ - send_CPI(1 << cpu, VIC_CALL_FUNCTION_SINGLE_CPI); -} - -struct smp_ops smp_ops = { - .smp_prepare_boot_cpu = voyager_smp_prepare_boot_cpu, - .smp_prepare_cpus = voyager_smp_prepare_cpus, - .cpu_up = voyager_cpu_up, - .smp_cpus_done = voyager_smp_cpus_done, - - .smp_send_stop = voyager_smp_send_stop, - .smp_send_reschedule = voyager_smp_send_reschedule, - - .send_call_func_ipi = voyager_send_call_func, - .send_call_func_single_ipi = voyager_send_call_func_single, -}; diff --git a/arch/x86/mach-voyager/voyager_thread.c b/arch/x86/mach-voyager/voyager_thread.c deleted file mode 100644 index 15464a20fb3..00000000000 --- a/arch/x86/mach-voyager/voyager_thread.c +++ /dev/null @@ -1,128 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8 -*- */ - -/* Copyright (C) 2001 - * - * Author: J.E.J.Bottomley@HansenPartnership.com - * - * This module provides the machine status monitor thread for the - * voyager architecture. This allows us to monitor the machine - * environment (temp, voltage, fan function) and the front panel and - * internal UPS. If a fault is detected, this thread takes corrective - * action (usually just informing init) - * */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct task_struct *voyager_thread; -static __u8 set_timeout; - -static int execute(const char *string) -{ - int ret; - - char *envp[] = { - "HOME=/", - "TERM=linux", - "PATH=/sbin:/usr/sbin:/bin:/usr/bin", - NULL, - }; - char *argv[] = { - "/bin/bash", - "-c", - (char *)string, - NULL, - }; - - if ((ret = - call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC)) != 0) { - printk(KERN_ERR "Voyager failed to run \"%s\": %i\n", string, - ret); - } - return ret; -} - -static void check_from_kernel(void) -{ - if (voyager_status.switch_off) { - - /* FIXME: This should be configurable via proc */ - execute("umask 600; echo 0 > /etc/initrunlvl; kill -HUP 1"); - } else if (voyager_status.power_fail) { - VDEBUG(("Voyager daemon detected AC power failure\n")); - - /* FIXME: This should be configureable via proc */ - execute("umask 600; echo F > /etc/powerstatus; kill -PWR 1"); - set_timeout = 1; - } -} - -static void check_continuing_condition(void) -{ - if (voyager_status.power_fail) { - __u8 data; - voyager_cat_psi(VOYAGER_PSI_SUBREAD, - VOYAGER_PSI_AC_FAIL_REG, &data); - if ((data & 0x1f) == 0) { - /* all power restored */ - printk(KERN_NOTICE - "VOYAGER AC power restored, cancelling shutdown\n"); - /* FIXME: should be user configureable */ - execute - ("umask 600; echo O > /etc/powerstatus; kill -PWR 1"); - set_timeout = 0; - } - } -} - -static int thread(void *unused) -{ - printk(KERN_NOTICE "Voyager starting monitor thread\n"); - - for (;;) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(set_timeout ? HZ : MAX_SCHEDULE_TIMEOUT); - - VDEBUG(("Voyager Daemon awoken\n")); - if (voyager_status.request_from_kernel == 0) { - /* probably awoken from timeout */ - check_continuing_condition(); - } else { - check_from_kernel(); - voyager_status.request_from_kernel = 0; - } - } -} - -static int __init voyager_thread_start(void) -{ - voyager_thread = kthread_run(thread, NULL, "kvoyagerd"); - if (IS_ERR(voyager_thread)) { - printk(KERN_ERR - "Voyager: Failed to create system monitor thread.\n"); - return PTR_ERR(voyager_thread); - } - return 0; -} - -static void __exit voyager_thread_stop(void) -{ - kthread_stop(voyager_thread); -} - -module_init(voyager_thread_start); -module_exit(voyager_thread_stop); diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig index 87b9ab16642..b83e119fbeb 100644 --- a/arch/x86/xen/Kconfig +++ b/arch/x86/xen/Kconfig @@ -6,7 +6,7 @@ config XEN bool "Xen guest support" select PARAVIRT select PARAVIRT_CLOCK - depends on X86_64 || (X86_32 && X86_PAE && !(X86_VISWS || X86_VOYAGER)) + depends on X86_64 || (X86_32 && X86_PAE && !X86_VISWS) depends on X86_CMPXCHG && X86_TSC help This is the Linux Xen port. Enabling this will allow the diff --git a/drivers/lguest/Kconfig b/drivers/lguest/Kconfig index 76f2b36881c..a3d3cbab359 100644 --- a/drivers/lguest/Kconfig +++ b/drivers/lguest/Kconfig @@ -1,6 +1,6 @@ config LGUEST tristate "Linux hypervisor example code" - depends on X86_32 && EXPERIMENTAL && !X86_PAE && FUTEX && !X86_VOYAGER + depends on X86_32 && EXPERIMENTAL && !X86_PAE && FUTEX select HVC_DRIVER ---help--- This is a very simple module which allows you to run -- cgit From d85a881d780cc7aaebe1b7aefcddbcb939acbe2d Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 23 Feb 2009 00:29:45 +0100 Subject: x86: remove various unused subarch hooks Impact: remove dead code Remove: - pre_setup_arch_hook() - mca_nmi_hook() If needed they can be added back via an x86_quirk handler. Signed-off-by: Ingo Molnar --- arch/x86/include/asm/arch_hooks.h | 6 +++--- arch/x86/kernel/mca_32.c | 4 +--- arch/x86/kernel/setup.c | 34 ---------------------------------- 3 files changed, 4 insertions(+), 40 deletions(-) diff --git a/arch/x86/include/asm/arch_hooks.h b/arch/x86/include/asm/arch_hooks.h index cbd4957838a..54248172be1 100644 --- a/arch/x86/include/asm/arch_hooks.h +++ b/arch/x86/include/asm/arch_hooks.h @@ -15,12 +15,12 @@ extern void init_ISA_irqs(void); extern irqreturn_t timer_interrupt(int irq, void *dev_id); /* these are the defined hooks */ -extern void intr_init_hook(void); extern void pre_intr_init_hook(void); -extern void pre_setup_arch_hook(void); +extern void intr_init_hook(void); + extern void trap_init_hook(void); + extern void pre_time_init_hook(void); extern void time_init_hook(void); -extern void mca_nmi_hook(void); #endif /* _ASM_X86_ARCH_HOOKS_H */ diff --git a/arch/x86/kernel/mca_32.c b/arch/x86/kernel/mca_32.c index 2dc183758be..f74eef52ab5 100644 --- a/arch/x86/kernel/mca_32.c +++ b/arch/x86/kernel/mca_32.c @@ -474,6 +474,4 @@ void __kprobes mca_handle_nmi(void) * adapter was responsible for the error. */ bus_for_each_dev(&mca_bus_type, NULL, NULL, mca_handle_nmi_callback); - - mca_nmi_hook(); -} /* mca_handle_nmi */ +} diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index d699811b3f7..d4de1e4c204 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -668,7 +668,6 @@ void __init setup_arch(char **cmdline_p) #ifdef CONFIG_X86_32 memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); visws_early_detect(); - pre_setup_arch_hook(); #else printk(KERN_INFO "Command line: %s\n", boot_command_line); #endif @@ -1022,18 +1021,6 @@ void __init intr_init_hook(void) } } -/** - * pre_setup_arch_hook - hook called prior to any setup_arch() execution - * - * Description: - * generally used to activate any machine specific identification - * routines that may be needed before setup_arch() runs. On Voyager - * this is used to get the board revision and type. - **/ -void __init pre_setup_arch_hook(void) -{ -} - /** * trap_init_hook - initialise system specific traps * @@ -1088,25 +1075,4 @@ void __init time_init_hook(void) irq0.mask = cpumask_of_cpu(0); setup_irq(0, &irq0); } - -#ifdef CONFIG_MCA -/** - * mca_nmi_hook - hook into MCA specific NMI chain - * - * Description: - * The MCA (Microchannel Architecture) has an NMI chain for NMI sources - * along the MCA bus. Use this to hook into that chain if you will need - * it. - **/ -void mca_nmi_hook(void) -{ - /* - * If I recall correctly, there's a whole bunch of other things that - * we can do to check for NMI problems, but that's all I know about - * at the moment. - */ - pr_warning("NMI generated from unknown source!\n"); -} -#endif /* CONFIG_MCA */ - #endif /* CONFIG_X86_32 */ -- cgit From 8e6dafd6c741cd4679b4de3c5d9698851e4fa59c Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 23 Feb 2009 00:34:39 +0100 Subject: x86: refactor x86_quirks support Impact: cleanup Make x86_quirks support more transparent. The highlevel methods are now named: extern void x86_quirk_pre_intr_init(void); extern void x86_quirk_intr_init(void); extern void x86_quirk_trap_init(void); extern void x86_quirk_pre_time_init(void); extern void x86_quirk_time_init(void); This makes it clear that if some platform extension has to do something here that it is considered ... weird, and is discouraged. Also remove arch_hooks.h and move it into setup.h (and other header files where appropriate). Signed-off-by: Ingo Molnar --- arch/x86/include/asm/arch_hooks.h | 26 -------------------------- arch/x86/include/asm/i8259.h | 4 ++++ arch/x86/include/asm/setup.h | 9 +++++++++ arch/x86/include/asm/timer.h | 2 ++ arch/x86/kernel/apic/apic.c | 1 - arch/x86/kernel/apic/probe_32.c | 1 - arch/x86/kernel/i8259.c | 1 - arch/x86/kernel/irqinit_32.c | 13 +++++++------ arch/x86/kernel/kvmclock.c | 1 - arch/x86/kernel/mca_32.c | 1 - arch/x86/kernel/paravirt.c | 1 - arch/x86/kernel/setup.c | 23 ++++++++++++----------- arch/x86/kernel/time_32.c | 6 +++--- arch/x86/kernel/traps.c | 4 ++-- arch/x86/kernel/visws_quirks.c | 1 - arch/x86/kernel/vmiclock_32.c | 1 - 16 files changed, 39 insertions(+), 56 deletions(-) delete mode 100644 arch/x86/include/asm/arch_hooks.h diff --git a/arch/x86/include/asm/arch_hooks.h b/arch/x86/include/asm/arch_hooks.h deleted file mode 100644 index 54248172be1..00000000000 --- a/arch/x86/include/asm/arch_hooks.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _ASM_X86_ARCH_HOOKS_H -#define _ASM_X86_ARCH_HOOKS_H - -#include - -/* - * linux/include/asm/arch_hooks.h - * - * define the architecture specific hooks - */ - -/* these aren't arch hooks, they are generic routines - * that can be used by the hooks */ -extern void init_ISA_irqs(void); -extern irqreturn_t timer_interrupt(int irq, void *dev_id); - -/* these are the defined hooks */ -extern void pre_intr_init_hook(void); -extern void intr_init_hook(void); - -extern void trap_init_hook(void); - -extern void pre_time_init_hook(void); -extern void time_init_hook(void); - -#endif /* _ASM_X86_ARCH_HOOKS_H */ diff --git a/arch/x86/include/asm/i8259.h b/arch/x86/include/asm/i8259.h index 58d7091eeb1..1a99e6c092a 100644 --- a/arch/x86/include/asm/i8259.h +++ b/arch/x86/include/asm/i8259.h @@ -60,4 +60,8 @@ extern struct irq_chip i8259A_chip; extern void mask_8259A(void); extern void unmask_8259A(void); +#ifdef CONFIG_X86_32 +extern void init_ISA_irqs(void); +#endif + #endif /* _ASM_X86_I8259_H */ diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h index 8029369cd6f..66801cb72f6 100644 --- a/arch/x86/include/asm/setup.h +++ b/arch/x86/include/asm/setup.h @@ -13,6 +13,7 @@ struct mpc_cpu; struct mpc_bus; struct mpc_oemtable; + struct x86_quirks { int (*arch_pre_time_init)(void); int (*arch_time_init)(void); @@ -33,6 +34,14 @@ struct x86_quirks { int (*update_apic)(void); }; +extern void x86_quirk_pre_intr_init(void); +extern void x86_quirk_intr_init(void); + +extern void x86_quirk_trap_init(void); + +extern void x86_quirk_pre_time_init(void); +extern void x86_quirk_time_init(void); + #endif /* __ASSEMBLY__ */ #ifdef __i386__ diff --git a/arch/x86/include/asm/timer.h b/arch/x86/include/asm/timer.h index 2bb6a835c45..a81195eaa2b 100644 --- a/arch/x86/include/asm/timer.h +++ b/arch/x86/include/asm/timer.h @@ -3,6 +3,7 @@ #include #include #include +#include #define TICK_SIZE (tick_nsec / 1000) @@ -12,6 +13,7 @@ unsigned long native_calibrate_tsc(void); #ifdef CONFIG_X86_32 extern int timer_ack; extern int recalibrate_cpu_khz(void); +extern irqreturn_t timer_interrupt(int irq, void *dev_id); #endif /* CONFIG_X86_32 */ extern int no_timer_check; diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index c6bd7710585..f9cecdfd05c 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -34,7 +34,6 @@ #include #include -#include #include #include #include diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c index c9ec90742e9..3a730fa574b 100644 --- a/arch/x86/kernel/apic/probe_32.c +++ b/arch/x86/kernel/apic/probe_32.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c index 11d5093eb28..df89102bef8 100644 --- a/arch/x86/kernel/i8259.c +++ b/arch/x86/kernel/i8259.c @@ -22,7 +22,6 @@ #include #include #include -#include #include /* diff --git a/arch/x86/kernel/irqinit_32.c b/arch/x86/kernel/irqinit_32.c index bf629cadec1..50b8c3a3006 100644 --- a/arch/x86/kernel/irqinit_32.c +++ b/arch/x86/kernel/irqinit_32.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include @@ -127,8 +127,8 @@ void __init native_init_IRQ(void) { int i; - /* all the set up before the call gates are initialised */ - pre_intr_init_hook(); + /* Execute any quirks before the call gates are initialised: */ + x86_quirk_pre_intr_init(); /* * Cover the whole vector space, no vector can escape @@ -188,10 +188,11 @@ void __init native_init_IRQ(void) if (!acpi_ioapic) setup_irq(2, &irq2); - /* setup after call gates are initialised (usually add in - * the architecture specific gates) + /* + * Call quirks after call gates are initialised (usually add in + * the architecture specific gates): */ - intr_init_hook(); + x86_quirk_intr_init(); /* * External FPU? Set up irq13 if so, for diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index 652fce6d2cc..137f2e8132d 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/x86/kernel/mca_32.c b/arch/x86/kernel/mca_32.c index f74eef52ab5..845d80ce1ef 100644 --- a/arch/x86/kernel/mca_32.c +++ b/arch/x86/kernel/mca_32.c @@ -51,7 +51,6 @@ #include #include #include -#include static unsigned char which_scsi; diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 6dc4dca255e..63dd358d8ee 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index d4de1e4c204..5b85759e797 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -74,8 +74,9 @@ #include #include #include -#include #include +#include +#include #include #include #include @@ -987,7 +988,7 @@ void __init setup_arch(char **cmdline_p) #ifdef CONFIG_X86_32 /** - * pre_intr_init_hook - initialisation prior to setting up interrupt vectors + * x86_quirk_pre_intr_init - initialisation prior to setting up interrupt vectors * * Description: * Perform any necessary interrupt initialisation prior to setting up @@ -995,7 +996,7 @@ void __init setup_arch(char **cmdline_p) * interrupts should be initialised here if the machine emulates a PC * in any way. **/ -void __init pre_intr_init_hook(void) +void __init x86_quirk_pre_intr_init(void) { if (x86_quirks->arch_pre_intr_init) { if (x86_quirks->arch_pre_intr_init()) @@ -1005,7 +1006,7 @@ void __init pre_intr_init_hook(void) } /** - * intr_init_hook - post gate setup interrupt initialisation + * x86_quirk_intr_init - post gate setup interrupt initialisation * * Description: * Fill in any interrupts that may have been left out by the general @@ -1013,7 +1014,7 @@ void __init pre_intr_init_hook(void) * than the devices on the I/O bus (like APIC interrupts in intel MP * systems) are started here. **/ -void __init intr_init_hook(void) +void __init x86_quirk_intr_init(void) { if (x86_quirks->arch_intr_init) { if (x86_quirks->arch_intr_init()) @@ -1022,13 +1023,13 @@ void __init intr_init_hook(void) } /** - * trap_init_hook - initialise system specific traps + * x86_quirk_trap_init - initialise system specific traps * * Description: * Called as the final act of trap_init(). Used in VISWS to initialise * the various board specific APIC traps. **/ -void __init trap_init_hook(void) +void __init x86_quirk_trap_init(void) { if (x86_quirks->arch_trap_init) { if (x86_quirks->arch_trap_init()) @@ -1044,23 +1045,23 @@ static struct irqaction irq0 = { }; /** - * pre_time_init_hook - do any specific initialisations before. + * x86_quirk_pre_time_init - do any specific initialisations before. * **/ -void __init pre_time_init_hook(void) +void __init x86_quirk_pre_time_init(void) { if (x86_quirks->arch_pre_time_init) x86_quirks->arch_pre_time_init(); } /** - * time_init_hook - do any specific initialisations for the system timer. + * x86_quirk_time_init - do any specific initialisations for the system timer. * * Description: * Must plug the system timer interrupt source at HZ into the IRQ listed * in irq_vectors.h:TIMER_IRQ **/ -void __init time_init_hook(void) +void __init x86_quirk_time_init(void) { if (x86_quirks->arch_time_init) { /* diff --git a/arch/x86/kernel/time_32.c b/arch/x86/kernel/time_32.c index 764c74e871f..5c5d87f0b2e 100644 --- a/arch/x86/kernel/time_32.c +++ b/arch/x86/kernel/time_32.c @@ -33,7 +33,7 @@ #include #include -#include +#include #include #include #include @@ -118,7 +118,7 @@ void __init hpet_time_init(void) { if (!hpet_enable()) setup_pit_timer(); - time_init_hook(); + x86_quirk_time_init(); } /* @@ -131,7 +131,7 @@ void __init hpet_time_init(void) */ void __init time_init(void) { - pre_time_init_hook(); + x86_quirk_pre_time_init(); tsc_init(); late_time_init = choose_time_init(); } diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index acb8c0585ab..c8c0a7e530b 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -61,7 +61,7 @@ #include #else #include -#include +#include #include #include "cpu/mcheck/mce.h" @@ -1026,6 +1026,6 @@ void __init trap_init(void) cpu_init(); #ifdef CONFIG_X86_32 - trap_init_hook(); + x86_quirk_trap_init(); #endif } diff --git a/arch/x86/kernel/visws_quirks.c b/arch/x86/kernel/visws_quirks.c index 34199d30ff4..191a876e9e8 100644 --- a/arch/x86/kernel/visws_quirks.c +++ b/arch/x86/kernel/visws_quirks.c @@ -24,7 +24,6 @@ #include #include -#include #include #include #include diff --git a/arch/x86/kernel/vmiclock_32.c b/arch/x86/kernel/vmiclock_32.c index 8c48b465059..49b4cd6707f 100644 --- a/arch/x86/kernel/vmiclock_32.c +++ b/arch/x86/kernel/vmiclock_32.c @@ -28,7 +28,6 @@ #include #include -#include #include #include #include -- cgit From 0d3a9cf5ab041c15691fd03dab3af0841af63606 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Sun, 22 Feb 2009 14:58:56 -0800 Subject: acpi: add some missing section markers early_acpi_os_unmap_memory() is an __init function, and acpi_os_unmap_memory() is allowed to access an __init function until acpi_gbl_permanent_mmap is set up. Signed-off-by: Jeremy Fitzhardinge Cc: Len Brown Signed-off-by: Ingo Molnar --- drivers/acpi/osl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index d1dd5160daa..2b6c5902825 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -272,7 +272,7 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size) } EXPORT_SYMBOL_GPL(acpi_os_map_memory); -void acpi_os_unmap_memory(void __iomem * virt, acpi_size size) +void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size) { if (acpi_gbl_permanent_mmap) iounmap(virt); @@ -281,7 +281,7 @@ void acpi_os_unmap_memory(void __iomem * virt, acpi_size size) } EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); -void early_acpi_os_unmap_memory(void __iomem * virt, acpi_size size) +void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size) { if (!acpi_gbl_permanent_mmap) __acpi_unmap_table(virt, size); -- cgit From 8b0e378a20e48c691d374f39d8b0596e63598cfc Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 19 Feb 2009 14:40:50 -0800 Subject: drm/i915: Cut two args to set_to_gpu_domain that confused this tricky path. While not strictly required, it helped while thinking about the following change. This change should be invariant. Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/i915_gem.c | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index ac534c9a2f8..02ef50d512d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -34,10 +34,6 @@ #define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) -static void -i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, - uint32_t read_domains, - uint32_t write_domain); static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); @@ -2021,30 +2017,28 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write) * drm_agp_chipset_flush */ static void -i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, - uint32_t read_domains, - uint32_t write_domain) +i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; struct drm_i915_gem_object *obj_priv = obj->driver_private; uint32_t invalidate_domains = 0; uint32_t flush_domains = 0; - BUG_ON(read_domains & I915_GEM_DOMAIN_CPU); - BUG_ON(write_domain == I915_GEM_DOMAIN_CPU); + BUG_ON(obj->pending_read_domains & I915_GEM_DOMAIN_CPU); + BUG_ON(obj->pending_write_domain == I915_GEM_DOMAIN_CPU); #if WATCH_BUF DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n", __func__, obj, - obj->read_domains, read_domains, - obj->write_domain, write_domain); + obj->read_domains, obj->pending_read_domains, + obj->write_domain, obj->pending_write_domain); #endif /* * If the object isn't moving to a new write domain, * let the object stay in multiple read domains */ - if (write_domain == 0) - read_domains |= obj->read_domains; + if (obj->pending_write_domain == 0) + obj->pending_read_domains |= obj->read_domains; else obj_priv->dirty = 1; @@ -2054,15 +2048,17 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, * any read domains which differ from the old * write domain */ - if (obj->write_domain && obj->write_domain != read_domains) { + if (obj->write_domain && + obj->write_domain != obj->pending_read_domains) { flush_domains |= obj->write_domain; - invalidate_domains |= read_domains & ~obj->write_domain; + invalidate_domains |= + obj->pending_read_domains & ~obj->write_domain; } /* * Invalidate any read caches which may have * stale data. That is, any new read domains. */ - invalidate_domains |= read_domains & ~obj->read_domains; + invalidate_domains |= obj->pending_read_domains & ~obj->read_domains; if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) { #if WATCH_BUF DRM_INFO("%s: CPU domain flush %08x invalidate %08x\n", @@ -2071,9 +2067,9 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, i915_gem_clflush_object(obj); } - if ((write_domain | flush_domains) != 0) - obj->write_domain = write_domain; - obj->read_domains = read_domains; + if ((obj->pending_write_domain | flush_domains) != 0) + obj->write_domain = obj->pending_write_domain; + obj->read_domains = obj->pending_read_domains; dev->invalidate_domains |= invalidate_domains; dev->flush_domains |= flush_domains; @@ -2583,9 +2579,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, struct drm_gem_object *obj = object_list[i]; /* Compute new gpu domains and update invalidate/flush */ - i915_gem_object_set_to_gpu_domain(obj, - obj->pending_read_domains, - obj->pending_write_domain); + i915_gem_object_set_to_gpu_domain(obj); } i915_verify_inactive(dev, __FILE__, __LINE__); -- cgit From efbeed96f7e20783b22d9529ef536b61f7ea8637 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 19 Feb 2009 14:54:51 -0800 Subject: drm/i915: Don't let a device flush to prepare buffers clear new write_domains. The problem was that object_set_to_gpu_domain would set the new write_domains that are getting set by this batchbuffer, then the accumulated flushes required for all the objects in preparation for this batchbuffer were posted, and the brand new write domain would get cleared by the flush being posted. Instead, hang on to the new (or old if we're not changing it) value and set it after the flush is queued. Results from this noticably included conformance test failures from reads shortly after writes (where the new write domain had been lost and thus not flushed and waited on), but is a suspected cause of hangs in some apps when a write domain is lost on a buffer that gets reused for instruction or commmand state. Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/i915_gem.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 02ef50d512d..0f50574076b 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2067,8 +2067,14 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) i915_gem_clflush_object(obj); } - if ((obj->pending_write_domain | flush_domains) != 0) - obj->write_domain = obj->pending_write_domain; + /* The actual obj->write_domain will be updated with + * pending_write_domain after we emit the accumulated flush for all + * of our domain changes in execbuffers (which clears objects' + * write_domains). So if we have a current write domain that we + * aren't changing, set pending_write_domain to that. + */ + if (flush_domains == 0 && obj->pending_write_domain == 0) + obj->pending_write_domain = obj->write_domain; obj->read_domains = obj->pending_read_domains; dev->invalidate_domains |= invalidate_domains; @@ -2598,6 +2604,12 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, (void)i915_add_request(dev, dev->flush_domains); } + for (i = 0; i < args->buffer_count; i++) { + struct drm_gem_object *obj = object_list[i]; + + obj->write_domain = obj->pending_write_domain; + } + i915_verify_inactive(dev, __FILE__, __LINE__); #if WATCH_COHERENCY -- cgit From 5669fcacc58bf3a7386057addffd280d75380858 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 17 Feb 2009 15:13:31 -0800 Subject: drm/i915: suspend/resume GEM when KMS is active In the KMS case, we need to suspend/resume GEM as well. So on suspend, make sure we idle GEM and stop any new rendering from coming in, and on resume, re-init the framebuffer and clear the suspended flag. Signed-off-by: Jesse Barnes Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/i915_drv.c | 23 ++++++++++++++++++++++- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem.c | 2 +- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index a31cbdbc3c5..0692622ee2b 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -27,6 +27,7 @@ * */ +#include #include "drmP.h" #include "drm.h" #include "i915_drm.h" @@ -66,6 +67,12 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) i915_save_state(dev); + /* If KMS is active, we do the leavevt stuff here */ + if (drm_core_check_feature(dev, DRIVER_MODESET) && i915_gem_idle(dev)) { + dev_err(&dev->pdev->dev, "GEM idle failed, aborting suspend\n"); + return -EBUSY; + } + intel_opregion_free(dev); if (state.event == PM_EVENT_SUSPEND) { @@ -79,6 +86,9 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) static int i915_resume(struct drm_device *dev) { + struct drm_i915_private *dev_priv = dev->dev_private; + int ret = 0; + pci_set_power_state(dev->pdev, PCI_D0); pci_restore_state(dev->pdev); if (pci_enable_device(dev->pdev)) @@ -89,7 +99,18 @@ static int i915_resume(struct drm_device *dev) intel_opregion_init(dev); - return 0; + /* KMS EnterVT equivalent */ + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + mutex_lock(&dev->struct_mutex); + dev_priv->mm.suspended = 0; + + ret = i915_gem_init_ringbuffer(dev); + if (ret != 0) + ret = -1; + mutex_unlock(&dev->struct_mutex); + } + + return ret; } static struct vm_operations_struct i915_gem_vm_ops = { diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 135a08f615c..17fa40858d2 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -618,6 +618,7 @@ int i915_gem_init_ringbuffer(struct drm_device *dev); void i915_gem_cleanup_ringbuffer(struct drm_device *dev); int i915_gem_do_init(struct drm_device *dev, unsigned long start, unsigned long end); +int i915_gem_idle(struct drm_device *dev); int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0f50574076b..58c789da95a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2973,7 +2973,7 @@ i915_gem_evict_from_list(struct drm_device *dev, struct list_head *head) return 0; } -static int +int i915_gem_idle(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; -- cgit From f21289b355cee8738d80c2ae5cbd272c3f7b5689 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 18 Feb 2009 09:44:56 -0800 Subject: drm/i915: Retire requests from i915_gem_busy_ioctl. This ensures that the user gets the latest information from the hardware on whether the buffer is busy, potentially reducing the working set of objects that the user chooses. Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/i915_gem.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 58c789da95a..8b50d482038 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2872,6 +2872,13 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, return -EBADF; } + /* Update the active list for the hardware's current position. + * Otherwise this only updates on a delayed timer or when irqs are + * actually unmasked, and our working set ends up being larger than + * required. + */ + i915_gem_retire_requests(dev); + obj_priv = obj->driver_private; /* Don't count being on the flushing list against the object being * done. Otherwise, a buffer left on the flushing list but not getting -- cgit From bab2d1f6531657e37dc84f26184f3f64e1e73ecd Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 20 Feb 2009 17:52:20 +0000 Subject: drm/i915: Fix regression in 95ca9d The object is dereferenced before the NULL check. Oops. Fixes http://bugs.freedesktop.org/show_bug.cgi?id=20235 Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/i915_gem.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 8b50d482038..25b337438ca 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3143,16 +3143,20 @@ static void i915_gem_cleanup_hws(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_gem_object *obj = dev_priv->hws_obj; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_gem_object *obj; + struct drm_i915_gem_object *obj_priv; if (dev_priv->hws_obj == NULL) return; + obj = dev_priv->hws_obj; + obj_priv = obj->driver_private; + kunmap(obj_priv->page_list[0]); i915_gem_object_unpin(obj); drm_gem_object_unreference(obj); dev_priv->hws_obj = NULL; + memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); dev_priv->hw_status_page = NULL; -- cgit From 6fb88588555a18792a27f483887fe1f2af5f9c9b Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 23 Feb 2009 10:08:21 +1000 Subject: drm/i915: fix WC mapping in non-GEM i915 code. [airlied - taken from mailing list posting] Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/i915_dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 81f1cff56fd..2d797ffe813 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -202,7 +202,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) dev_priv->ring.map.flags = 0; dev_priv->ring.map.mtrr = 0; - drm_core_ioremap(&dev_priv->ring.map, dev); + drm_core_ioremap_wc(&dev_priv->ring.map, dev); if (dev_priv->ring.map.handle == NULL) { i915_dma_cleanup(dev); -- cgit From 5004417d840e6dcb0052061fd04569b9c9f037a8 Mon Sep 17 00:00:00 2001 From: Pierre Willenbrock Date: Mon, 23 Feb 2009 10:12:15 +1000 Subject: drm/i915: Add missing mutex_lock(&dev->struct_mutex) there might be a nicer way to fix this but this is the simplest for now. Signed-off-by: Pierre Willenbrock Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/intel_display.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4d2baf7b00b..65b635ce28c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1008,6 +1008,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, temp = CURSOR_MODE_DISABLE; addr = 0; bo = NULL; + mutex_lock(&dev->struct_mutex); goto finish; } -- cgit From ebd3610b110bbb18ea6f9f2aeed1e1068c537227 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Sun, 22 Feb 2009 21:09:59 -0500 Subject: ext4: Fix deadlock in ext4_write_begin() and ext4_da_write_begin() Functions ext4_write_begin() and ext4_da_write_begin() call grab_cache_page_write_begin() without AOP_FLAG_NOFS. Thus it can happen that page reclaim is triggered in that function and it recurses back into the filesystem (or some other filesystem). But this can lead to various problems as a transaction is already started at that point. Add the necessary flag. http://bugzilla.kernel.org/show_bug.cgi?id=11688 Signed-off-by: Jan Kara Signed-off-by: "Theodore Ts'o" --- fs/ext4/inode.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index cbd2ca99d11..51cdd13e1c3 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1368,6 +1368,10 @@ retry: goto out; } + /* We cannot recurse into the filesystem as the transaction is already + * started */ + flags |= AOP_FLAG_NOFS; + page = grab_cache_page_write_begin(mapping, index, flags); if (!page) { ext4_journal_stop(handle); @@ -1377,7 +1381,7 @@ retry: *pagep = page; ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, - ext4_get_block); + ext4_get_block); if (!ret && ext4_should_journal_data(inode)) { ret = walk_page_buffers(handle, page_buffers(page), @@ -2667,6 +2671,9 @@ retry: ret = PTR_ERR(handle); goto out; } + /* We cannot recurse into the filesystem as the transaction is already + * started */ + flags |= AOP_FLAG_NOFS; page = grab_cache_page_write_begin(mapping, index, flags); if (!page) { -- cgit From af23f573e817642479fdd05e2b5da5b268eacfaf Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 22 Feb 2009 17:05:22 -0800 Subject: acpi/doc: add missing param value Add missing parameter value to list of available values for acpi=. Signed-off-by: Randy Dunlap Signed-off-by: Linus Torvalds --- Documentation/kernel-parameters.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index b182626739e..319785b6dcb 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -134,7 +134,7 @@ and is between 256 and 4096 characters. It is defined in the file acpi= [HW,ACPI,X86-64,i386] Advanced Configuration and Power Interface - Format: { force | off | ht | strict | noirq } + Format: { force | off | ht | strict | noirq | rsdt } force -- enable ACPI if default was off off -- disable ACPI if default was on noirq -- do not use ACPI for IRQ routing -- cgit From 20f4d6c3a2a23c5d7d9cc7f42fbb943ca7a03d1f Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 22 Feb 2009 20:19:40 -0800 Subject: Linux 2.6.29-rc6 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 59cf6dacec0..df6ce3e8009 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 29 -EXTRAVERSION = -rc5 +EXTRAVERSION = -rc6 NAME = Erotic Pickled Herring # *DOCUMENTATION* -- cgit From e8bf069c419c1dc0657e02636441fe1179a9db14 Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Sun, 22 Feb 2009 14:42:54 +0200 Subject: ALSA: aw2: do not grab every saa7146 based device Audiowerk2 driver snd-aw2 is bound to any saa7146 device as it does not check subsystem ids. Many DVB devices are saa7146 based, so aw2 driver grabs them as well. According to http://lkml.org/lkml/2008/10/15/311 aw2 devices have the subsystem ids set to 0, the saa7146 default. Fix conflicts with DVB devices by checking for subsystem ids = 0 specifically. Signed-off-by: Anssi Hannula Signed-off-by: Takashi Iwai --- sound/pci/aw2/aw2-alsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c index 3f00ddf450f..c7c54e7748e 100644 --- a/sound/pci/aw2/aw2-alsa.c +++ b/sound/pci/aw2/aw2-alsa.c @@ -165,7 +165,7 @@ module_param_array(enable, bool, NULL, 0444); MODULE_PARM_DESC(enable, "Enable Audiowerk2 soundcard."); static struct pci_device_id snd_aw2_ids[] = { - {PCI_VENDOR_ID_SAA7146, PCI_DEVICE_ID_SAA7146, PCI_ANY_ID, PCI_ANY_ID, + {PCI_VENDOR_ID_SAA7146, PCI_DEVICE_ID_SAA7146, 0, 0, 0, 0, 0}, {0} }; -- cgit From ecda06289f8202d4c6beb235f59ea464f4a91209 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sun, 22 Feb 2009 22:14:56 -0800 Subject: x86: check mptable physptr with max_low_pfn on 32bit Impact: fix early crash on LinuxBIOS systems Kevin O'Connor reported that Coreboot aka LinuxBIOS tries to put mptable somewhere very high, well above max_low_pfn (below which BIOSes generally put the mptable), causing a panic. The BIOS will probably be changed to be compatible with older Linus versions, but nevertheless the MP-spec does not forbid an MP-table in arbitrary system RAM, so make sure it all works even if the table is in an unexpected place. Check physptr with max_low_pfn * PAGE_SIZE. Reported-by: Kevin O'Connor Signed-off-by: Yinghai Lu Cc: Stefan Reinauer Cc: coreboot@coreboot.org Signed-off-by: Ingo Molnar --- arch/x86/kernel/mpparse.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 7f4d2586972..37cb1bda1ba 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c @@ -710,13 +710,22 @@ static int __init smp_scan_config(unsigned long base, unsigned long length, * of physical memory; so that simply reserving * PAGE_SIZE from mpf->physptr yields BUG() * in reserve_bootmem. + * also need to make sure physptr is below than + * max_low_pfn + * we don't need reserve the area above max_low_pfn */ unsigned long end = max_low_pfn * PAGE_SIZE; - if (mpf->physptr + size > end) - size = end - mpf->physptr; -#endif + + if (mpf->physptr < end) { + if (mpf->physptr + size > end) + size = end - mpf->physptr; + reserve_bootmem_generic(mpf->physptr, size, + BOOTMEM_DEFAULT); + } +#else reserve_bootmem_generic(mpf->physptr, size, BOOTMEM_DEFAULT); +#endif } return 1; -- cgit From 5370d96f85962769ea3df3a81cc885f257c51589 Mon Sep 17 00:00:00 2001 From: Steve Chen Date: Sat, 21 Feb 2009 08:05:04 -0600 Subject: ALSA: fix excessive background noise introduced by OSS emulation rate shrink Incorrect variable was used to get the next sample which caused S2 to be stuck with the same value resulting in loud background noise. Signed-off-by: Steve Chen Cc: Signed-off-by: Takashi Iwai --- sound/core/oss/rate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/core/oss/rate.c b/sound/core/oss/rate.c index a466443c4a2..2fa9299a440 100644 --- a/sound/core/oss/rate.c +++ b/sound/core/oss/rate.c @@ -157,7 +157,7 @@ static void resample_shrink(struct snd_pcm_plugin *plugin, while (dst_frames1 > 0) { S1 = S2; if (src_frames1-- > 0) { - S1 = *src; + S2 = *src; src += src_step; } if (pos & ~R_MASK) { -- cgit From 2d4663816064fabb68935f920bbd7ccdc7f9392d Mon Sep 17 00:00:00 2001 From: Luke Yelavich Date: Mon, 23 Feb 2009 13:00:33 +1100 Subject: ALSA: hda - add another MacBook Pro 3,1 SSID Reference: Ubuntu bug #33245 https://bugs.launchpad.net/bugs/332456 Signed-off-by: Luke Yelavich Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index ed8fcbd6000..f6571224b34 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -7017,6 +7017,7 @@ static int patch_alc882(struct hda_codec *codec) case 0x106b3e00: /* iMac 24 Aluminium */ board_config = ALC885_IMAC24; break; + case 0x106b00a0: /* MacBookPro3,1 - Another revision */ case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */ case 0x106b00a4: /* MacbookPro4,1 */ case 0x106b2c00: /* Macbook Pro rev3 */ -- cgit From cc374c477c9bf95f409fed16426856d86a97394f Mon Sep 17 00:00:00 2001 From: Juan Jesus Garcia de Soria Date: Mon, 23 Feb 2009 08:11:59 +0100 Subject: ALSA: hda - Quirk for Acer Aspire 6530G The Acer Aspire 6530G needs the 4930G "model" for the front mic to work properly. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f6571224b34..a680be0d453 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -8470,6 +8470,8 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { ALC888_ACER_ASPIRE_4930G), SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", ALC888_ACER_ASPIRE_4930G), + SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", + ALC888_ACER_ASPIRE_4930G), SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */ SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), -- cgit From 5c138dcee7d4a9e68cce546a45968bbf5dbfce80 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Sun, 15 Feb 2009 12:51:18 +0300 Subject: orinoco: do not resgister NULL pm_notifier function With DEBUG_NOTIFIERS it results in [11330.890966] WARNING: at /home/bor/src/linux-git/kernel/notifier.c:88 notifier_call_chain+0x91/0xa0() [11330.890977] Hardware name: PORTEGE 4000 [11330.890983] Invalid notifier called! ... Without DEBUG_NOTIFIERS it most likely crashes on NULL pointer. Signed-off-by: Andrey Borzenkov Acked-by: David Kilroy Signed-off-by: John W. Linville --- drivers/net/wireless/orinoco/orinoco.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/orinoco/orinoco.c b/drivers/net/wireless/orinoco/orinoco.c index 45a04faa781..067d1a9c728 100644 --- a/drivers/net/wireless/orinoco/orinoco.c +++ b/drivers/net/wireless/orinoco/orinoco.c @@ -3157,8 +3157,20 @@ static int orinoco_pm_notifier(struct notifier_block *notifier, return NOTIFY_DONE; } + +static void orinoco_register_pm_notifier(struct orinoco_private *priv) +{ + priv->pm_notifier.notifier_call = orinoco_pm_notifier; + register_pm_notifier(&priv->pm_notifier); +} + +static void orinoco_unregister_pm_notifier(struct orinoco_private *priv) +{ + unregister_pm_notifier(&priv->pm_notifier); +} #else /* !PM_SLEEP || HERMES_CACHE_FW_ON_INIT */ -#define orinoco_pm_notifier NULL +#define orinoco_register_pm_notifier(priv) do { } while(0) +#define orinoco_unregister_pm_notifier(priv) do { } while(0) #endif /********************************************************************/ @@ -3648,8 +3660,7 @@ struct net_device priv->cached_fw = NULL; /* Register PM notifiers */ - priv->pm_notifier.notifier_call = orinoco_pm_notifier; - register_pm_notifier(&priv->pm_notifier); + orinoco_register_pm_notifier(priv); return dev; } @@ -3673,7 +3684,7 @@ void free_orinocodev(struct net_device *dev) kfree(rx_data); } - unregister_pm_notifier(&priv->pm_notifier); + orinoco_unregister_pm_notifier(priv); orinoco_uncache_fw(priv); priv->wpa_ie_len = 0; -- cgit From 40b130a947672d0ca886b718bfc4bd7641b6b39d Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Mon, 16 Feb 2009 13:55:07 +0530 Subject: ath9k: Fix panic upon attach failure [246916.338046] [246916.338048] Pid: 29265, comm: insmod Not tainted (2.6.29-rc4-wl #64) 9461DUU [246916.338051] EIP: 0060:[] EFLAGS: 00010202 CPU: 0 [246916.338055] EIP is at rollback_registered+0x24/0x220 [246916.338057] EAX: 00000001 EBX: 00000000 ECX: 00000000 EDX: f122e8fc [246916.338059] ESI: 00000000 EDI: 00000000 EBP: f6595d30 ESP: f6595d1c [246916.338062] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 [246916.338064] Process insmod (pid: 29265, ti=f6594000 task=f7343fe0 task.ti=f6594000) [246916.338067] Stack: [246916.338068] c04a2920 22222222 f6595d48 00000000 f122f080 f6595d48 c02ca489 f122e8fc [246916.338076] f122e220 f122f080 f122e220 f6595d5c f8a03156 f122e220 f122f080 f122e220 [246916.338085] f6595d80 f87359af f122f080 00002000 f874e129 f122f150 f122f080 f6290000 [246916.338094] Call Trace: [246916.338096] [] ? unregister_netdevice+0x19/0x70 [246916.338100] [] ? ieee80211_unregister_hw+0x36/0xd0 [mac80211] [246916.338112] [] ? ath_detach+0xcf/0x250 [ath9k] [246916.338127] [] ? ath_attach+0x26c/0x740 [ath9k] [246916.338139] [] ? ath_pci_probe+0x13a/0x310 [ath9k] [246916.338151] [] ? _raw_spin_unlock+0x68/0x80 [246916.338158] [] ? local_pci_probe+0xe/0x10 [246916.338162] [] ? pci_device_probe+0x60/0x80 [246916.338169] [] ? driver_probe_device+0x82/0x1b0 [246916.338174] [] ? __driver_attach+0x89/0x90 [246916.338180] [] ? bus_for_each_dev+0x4b/0x70 [246916.338184] [] ? pci_device_remove+0x0/0x40 [246916.338190] [] ? driver_attach+0x19/0x20 [246916.338193] [] ? __driver_attach+0x0/0x90 [246916.338197] [] ? bus_add_driver+0x1b7/0x230 [246916.338203] [] ? pci_device_remove+0x0/0x40 [246916.338206] [] ? driver_register+0x69/0x140 [246916.338212] [] ? ath9k_init+0x0/0x54 [ath9k] [246916.338221] [] ? __pci_register_driver+0x4e/0x90 [246916.338225] [] ? ath9k_init+0x0/0x54 [ath9k] [246916.338232] [] ? ath_pci_init+0x17/0x19 [ath9k] [246916.338238] [] ? ath9k_init+0x17/0x54 [ath9k] [246916.338245] [] ? tracepoint_update_probe_range+0x7e/0xb0 [246916.338249] [] ? do_one_initcall+0x2a/0x170 [246916.338252] [] ? up_read+0x16/0x30 [246916.338256] [] ? __blocking_notifier_call_chain+0x4d/0x60 [246916.338265] [] ? sys_init_module+0x8a/0x1c0 [246916.338269] [] ? trace_hardirqs_on_thunk+0xc/0x10 [246916.338272] [] ? sysenter_do_call+0x12/0x43 [246916.338276] Code: 8d bc 27 00 00 00 00 55 89 e5 56 89 c6 53 83 ec 0c a1 74 27 4a c0 85 c0 0f 85 4b 01 00 00 e8 04 7d 00 00 85 c0 0f 84 c9 01 00 00 <8b> 86 18 03 00 00 85 c0 0f 84 86 01 00 00 83 e8 01 0f 85 71 01 [246916.338328] EIP: [] rollback_registered+0x24/0x220 SS:ESP 0068:f6595d1c [246916.338335] ---[ end trace 76357c56a75ea34e ]--- Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/main.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 727f067aca4..0e80990d8e8 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -1538,6 +1538,7 @@ bad2: bad: if (ah) ath9k_hw_detach(ah); + ath9k_exit_debug(sc); return error; } @@ -1545,7 +1546,7 @@ bad: static int ath_attach(u16 devid, struct ath_softc *sc) { struct ieee80211_hw *hw = sc->hw; - int error = 0; + int error = 0, i; DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n"); @@ -1589,11 +1590,11 @@ static int ath_attach(u16 devid, struct ath_softc *sc) /* initialize tx/rx engine */ error = ath_tx_init(sc, ATH_TXBUF); if (error != 0) - goto detach; + goto error_attach; error = ath_rx_init(sc, ATH_RXBUF); if (error != 0) - goto detach; + goto error_attach; #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) /* Initialze h/w Rfkill */ @@ -1601,8 +1602,9 @@ static int ath_attach(u16 devid, struct ath_softc *sc) INIT_DELAYED_WORK(&sc->rf_kill.rfkill_poll, ath_rfkill_poll); /* Initialize s/w rfkill */ - if (ath_init_sw_rfkill(sc)) - goto detach; + error = ath_init_sw_rfkill(sc); + if (error) + goto error_attach; #endif error = ieee80211_register_hw(hw); @@ -1611,8 +1613,16 @@ static int ath_attach(u16 devid, struct ath_softc *sc) ath_init_leds(sc); return 0; -detach: - ath_detach(sc); + +error_attach: + /* cleanup tx queues */ + for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) + if (ATH_TXQ_SETUP(sc, i)) + ath_tx_cleanupq(sc, &sc->tx.txq[i]); + + ath9k_hw_detach(sc->sc_ah); + ath9k_exit_debug(sc); + return error; } -- cgit From 046ee5d26ac91316a8ac0a29c0b33139dc9da20d Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Tue, 17 Feb 2009 14:31:12 -0600 Subject: rtl8187: New USB ID's for RTL8187L MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add new USB ID codes. These come from two postings on forums and mailing lists, and four are derived from the .inf that accompanies the latest Realtek Windows driver for the RTL8187L. Thanks to Viktor Ilijašić and Xose Vazquez Perez for reporting these new ID's. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187_dev.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 22bc07ef2f3..f4747a1134b 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -48,6 +48,10 @@ static struct usb_device_id rtl8187_table[] __devinitdata = { {USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B}, {USB_DEVICE(0x0bda, 0x8197), .driver_info = DEVICE_RTL8187B}, {USB_DEVICE(0x0bda, 0x8198), .driver_info = DEVICE_RTL8187B}, + /* Surecom */ + {USB_DEVICE(0x0769, 0x11F2), .driver_info = DEVICE_RTL8187}, + /* Logitech */ + {USB_DEVICE(0x0789, 0x010C), .driver_info = DEVICE_RTL8187}, /* Netgear */ {USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187}, {USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187}, @@ -57,8 +61,16 @@ static struct usb_device_id rtl8187_table[] __devinitdata = { /* Sitecom */ {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187}, {USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B}, + /* Sphairon Access Systems GmbH */ + {USB_DEVICE(0x114B, 0x0150), .driver_info = DEVICE_RTL8187}, + /* Dick Smith Electronics */ + {USB_DEVICE(0x1371, 0x9401), .driver_info = DEVICE_RTL8187}, /* Abocom */ {USB_DEVICE(0x13d1, 0xabe6), .driver_info = DEVICE_RTL8187}, + /* Qcom */ + {USB_DEVICE(0x18E8, 0x6232), .driver_info = DEVICE_RTL8187}, + /* AirLive */ + {USB_DEVICE(0x1b75, 0x8187), .driver_info = DEVICE_RTL8187}, {} }; -- cgit From bda3a89745d7bb88d3e735046c0cdc3d0eb2ac24 Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Mon, 23 Feb 2009 19:13:07 +0300 Subject: x86: minor cleanup in the espfix code Impact: Cleanup Checkin be44d2aabce2d62f72d5751d1871b6212bf7a1c7 eliminates the use of a 16-bit stack for espfix. However, at least one instruction remained that only operated on the low 16 bits of %esp. This is not a bug per se because the kernel stack is always an aligned 4K or 8K block. Therefore it cannot cross 64K boundaries; this code, in fact, relies strictly on that fact. However, it's a lot cleaner (and, for that matter, smaller) to operate on the entire 32-bit register. Signed-off-by: Stas Sergeev CC: Zachary Amsden CC: Chuck Ebbert Signed-off-by: H. Peter Anvin --- arch/x86/kernel/entry_32.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 999e827ef9c..899e8938e79 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -1359,7 +1359,7 @@ nmi_espfix_stack: CFI_ADJUST_CFA_OFFSET 4 pushl %esp CFI_ADJUST_CFA_OFFSET 4 - addw $4, (%esp) + addl $4, (%esp) /* copy the iret frame of 12 bytes */ .rept 3 pushl 16(%esp) -- cgit From ec5b3d32437571b8a742069a4cfd04edb6b6eda5 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Mon, 23 Feb 2009 14:01:04 -0800 Subject: x86, mce: remove invalid __cpuinit/__cpuexit annotations Impact: Bug fix when CPU hotplug is disabled Correct the following broken __cpuinit/__cpuexit annotations: - mce_cpu_features() is called from mce_resume(), and so cannot be __cpuinit. - mce_disable_cpu() and mce_reenable_cpu() are called from mce_cpu_callback(), and so cannot be __cpuexit(). Cc: Andi Kleen Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/mcheck/mce_64.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index 60a114ca14f..0625993bf95 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -598,7 +598,7 @@ static void mce_init(void *dummy) } /* Add per CPU specific workarounds here */ -static void __cpuinit mce_cpu_quirks(struct cpuinfo_x86 *c) +static void mce_cpu_quirks(struct cpuinfo_x86 *c) { /* This should be disabled by the BIOS, but isn't always */ if (c->x86_vendor == X86_VENDOR_AMD) { @@ -1056,7 +1056,7 @@ static __cpuinit void mce_remove_device(unsigned int cpu) } /* Make sure there are no machine checks on offlined CPUs. */ -static void __cpuexit mce_disable_cpu(void *h) +static void mce_disable_cpu(void *h) { int i; @@ -1066,7 +1066,7 @@ static void __cpuexit mce_disable_cpu(void *h) wrmsrl(MSR_IA32_MC0_CTL + i*4, 0); } -static void __cpuexit mce_reenable_cpu(void *h) +static void mce_reenable_cpu(void *h) { int i; -- cgit From 954a8b8162ecab1d5ddf6c5b993b2d4da3fcaef7 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Thu, 19 Feb 2009 16:48:14 -0500 Subject: x86, doc: fix references to Documentation/x86/i386/boot.txt Impact: Documentation fix The amazing dancing boot.txt file has jumped places again. It should never have been in Documentation/x86/i386, since it never was 32-bit-specific, but it unfortunately ended up there for a while. Signed-off-by: Kyle McMartin Signed-off-by: H. Peter Anvin --- Documentation/kernel-parameters.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 319785b6dcb..f6d5d5b9b2b 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -114,7 +114,7 @@ In addition, the following text indicates that the option: Parameters denoted with BOOT are actually interpreted by the boot loader, and have no meaning to the kernel directly. Do not modify the syntax of boot loader parameters without extreme -need or coordination with . +need or coordination with . There are also arch-specific kernel-parameters not documented here. See for example . @@ -2449,7 +2449,7 @@ and is between 256 and 4096 characters. It is defined in the file See Documentation/fb/modedb.txt. vga= [BOOT,X86-32] Select a particular video mode - See Documentation/x86/i386/boot.txt and + See Documentation/x86/boot.txt and Documentation/svga.txt. Use vga=ask for menu. This is actually a boot loader parameter; the value is -- cgit From ebe47d47b7b7fed72dabcce4717da727b4e2367d Mon Sep 17 00:00:00 2001 From: Clemens Noss Date: Mon, 23 Feb 2009 15:37:35 -0800 Subject: netns: build fix for net_alloc_generic net_alloc_generic was defined in #ifdef CONFIG_NET_NS, but used unconditionally. Move net_alloc_generic out of #ifdef. Signed-off-by: Clemens Noss Signed-off-by: David S. Miller --- net/core/net_namespace.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index b0767abf23e..2adb1a7d361 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -63,10 +63,6 @@ out_undo: goto out; } -#ifdef CONFIG_NET_NS -static struct kmem_cache *net_cachep; -static struct workqueue_struct *netns_wq; - static struct net_generic *net_alloc_generic(void) { struct net_generic *ng; @@ -80,6 +76,10 @@ static struct net_generic *net_alloc_generic(void) return ng; } +#ifdef CONFIG_NET_NS +static struct kmem_cache *net_cachep; +static struct workqueue_struct *netns_wq; + static struct net *net_alloc(void) { struct net *net = NULL; -- cgit From 50fee1dec5d71b8a14c1b82f2f42e16adc227f8b Mon Sep 17 00:00:00 2001 From: Eugene Teo Date: Mon, 23 Feb 2009 15:38:41 -0800 Subject: net: amend the fix for SO_BSDCOMPAT gsopt infoleak The fix for CVE-2009-0676 (upstream commit df0bca04) is incomplete. Note that the same problem of leaking kernel memory will reappear if someone on some architecture uses struct timeval with some internal padding (for example tv_sec 64-bit and tv_usec 32-bit) --- then, you are going to leak the padded bytes to userspace. Signed-off-by: Eugene Teo Reported-by: Mikulas Patocka Signed-off-by: David S. Miller --- net/core/sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/sock.c b/net/core/sock.c index 6e4f14d1ef8..5f97caa158e 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -696,7 +696,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, if (len < 0) return -EINVAL; - v.val = 0; + memset(&v, 0, sizeof(v)); switch(optname) { case SO_DEBUG: -- cgit From 6c0594a306790ab03db345086c0c6c922a900bf6 Mon Sep 17 00:00:00 2001 From: Karsten Wiese Date: Mon, 23 Feb 2009 15:07:57 +0100 Subject: Fix an oops in i915_gem_retire_requests() dev_priv->hw_status_page can be NULL, if i915_gem_retire_requests() is called from i915_gem_busy_ioctl(). Signed-off-by Karsten Wiese Signed-off-by: Linus Torvalds --- drivers/gpu/drm/i915/i915_gem.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 25b337438ca..28b726d07a0 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1051,6 +1051,9 @@ i915_gem_retire_requests(struct drm_device *dev) drm_i915_private_t *dev_priv = dev->dev_private; uint32_t seqno; + if (!dev_priv->hw_status_page) + return; + seqno = i915_get_gem_seqno(dev); while (!list_empty(&dev_priv->mm.request_list)) { -- cgit From 226485e9a91ee89c941d8cb7714f85644a8071d0 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 23 Feb 2009 15:41:09 -0800 Subject: i915: suspend/resume interrupt state In the KMS case, enter/leavevt won't fix up the interrupt handler for us, so we need to do it at suspend/resume time. Make sure we don't fail the resume if the chip is hung either. Signed-off-by: Jesse Barnes Signed-off-by: Linus Torvalds --- drivers/gpu/drm/i915/i915_drv.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 0692622ee2b..b293ef0bae7 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -68,9 +68,11 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) i915_save_state(dev); /* If KMS is active, we do the leavevt stuff here */ - if (drm_core_check_feature(dev, DRIVER_MODESET) && i915_gem_idle(dev)) { - dev_err(&dev->pdev->dev, "GEM idle failed, aborting suspend\n"); - return -EBUSY; + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + if (i915_gem_idle(dev)) + dev_err(&dev->pdev->dev, + "GEM idle failed, resume may fail\n"); + drm_irq_uninstall(dev); } intel_opregion_free(dev); @@ -108,6 +110,8 @@ static int i915_resume(struct drm_device *dev) if (ret != 0) ret = -1; mutex_unlock(&dev->struct_mutex); + + drm_irq_install(dev); } return ret; -- cgit From cac711211a039ae2e2dc6322ffb3c2279d093bf1 Mon Sep 17 00:00:00 2001 From: Krzysztof Sachanowicz Date: Mon, 23 Feb 2009 22:21:55 +0100 Subject: proc: proc_get_inode should de_put when inode already initialized de_get is called before every proc_get_inode, but corresponding de_put is called only when dropping last reference to an inode. This might cause something like remove_proc_entry: /proc/stats busy, count=14496 to be printed to the syslog. The fix is to call de_put in case of an already initialized inode in proc_get_inode. Signed-off-by: Krzysztof Sachanowicz Tested-by: Marcin Pilipczuk Acked-by: Al Viro Signed-off-by: Linus Torvalds --- fs/proc/inode.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 3e76bb9b3ad..d8bb5c671f4 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -485,8 +485,10 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino, } } unlock_new_inode(inode); - } else + } else { module_put(de->owner); + de_put(de); + } return inode; out_ino: -- cgit From cb83b42e23bd6c4bf91793a320fbe83787c13596 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 24 Feb 2009 11:57:20 +0900 Subject: percpu: fix pcpu_chunk_struct_size Impact: fix short allocation leading to memory corruption While dropping rvalue wrapping macros around global parameters, pcpu_chunk_struct_size was set incorrectly resulting in shorter page pointer array. Fix it. Signed-off-by: Tejun Heo --- mm/percpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/percpu.c b/mm/percpu.c index 997724c2ea2..ed92caa2aa3 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -850,7 +850,7 @@ size_t __init pcpu_setup_static(pcpu_populate_pte_fn_t populate_pte_fn, pcpu_chunk_size = num_possible_cpus() * pcpu_unit_size; pcpu_nr_slots = pcpu_size_to_slot(pcpu_unit_size) + 1; pcpu_chunk_struct_size = sizeof(struct pcpu_chunk) - + (1 << pcpu_unit_pages_shift) * sizeof(struct page *); + + num_possible_cpus() * pcpu_unit_pages * sizeof(struct page *); /* allocate chunk slots */ pcpu_slot = alloc_bootmem(pcpu_nr_slots * sizeof(pcpu_slot[0])); -- cgit From c132937556f56ee4b831ef4b23f1846e05fde102 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 24 Feb 2009 11:57:20 +0900 Subject: bootmem: clean up arch-specific bootmem wrapping Impact: cleaner and consistent bootmem wrapping By setting CONFIG_HAVE_ARCH_BOOTMEM_NODE, archs can define arch-specific wrappers for bootmem allocation. However, this is done a bit strangely in that only the high level convenience macros can be changed while lower level, but still exported, interface functions can't be wrapped. This not only is messy but also leads to strange situation where alloc_bootmem() does what the arch wants it to do but the equivalent __alloc_bootmem() call doesn't although they should be able to be used interchangeably. This patch updates bootmem such that archs can override / wrap the backend function - alloc_bootmem_core() instead of the highlevel interface functions to allow simpler and consistent wrapping. Also, HAVE_ARCH_BOOTMEM_NODE is renamed to HAVE_ARCH_BOOTMEM. Signed-off-by: Tejun Heo Cc: Johannes Weiner --- arch/avr32/Kconfig | 2 +- arch/x86/Kconfig | 2 +- arch/x86/include/asm/mmzone_32.h | 43 +++++----------------------------------- include/linux/bootmem.h | 10 ++++------ mm/bootmem.c | 14 ++++++++++--- 5 files changed, 22 insertions(+), 49 deletions(-) diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig index b189680d18b..05fe3053dca 100644 --- a/arch/avr32/Kconfig +++ b/arch/avr32/Kconfig @@ -181,7 +181,7 @@ source "kernel/Kconfig.preempt" config QUICKLIST def_bool y -config HAVE_ARCH_BOOTMEM_NODE +config HAVE_ARCH_BOOTMEM def_bool n config ARCH_HAVE_MEMORY_PRESENT diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index d3f6eadfd4b..6fd3b2302ed 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1111,7 +1111,7 @@ config NODES_SHIFT Specify the maximum number of NUMA Nodes available on the target system. Increases memory reserved to accomodate various tables. -config HAVE_ARCH_BOOTMEM_NODE +config HAVE_ARCH_BOOTMEM def_bool y depends on X86_32 && NUMA diff --git a/arch/x86/include/asm/mmzone_32.h b/arch/x86/include/asm/mmzone_32.h index 07f1af494ca..1e0fa9e63af 100644 --- a/arch/x86/include/asm/mmzone_32.h +++ b/arch/x86/include/asm/mmzone_32.h @@ -93,45 +93,12 @@ static inline int pfn_valid(int pfn) #endif /* CONFIG_DISCONTIGMEM */ #ifdef CONFIG_NEED_MULTIPLE_NODES - -/* - * Following are macros that are specific to this numa platform. - */ -#define reserve_bootmem(addr, size, flags) \ - reserve_bootmem_node(NODE_DATA(0), (addr), (size), (flags)) -#define alloc_bootmem(x) \ - __alloc_bootmem_node(NODE_DATA(0), (x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) -#define alloc_bootmem_nopanic(x) \ - __alloc_bootmem_node_nopanic(NODE_DATA(0), (x), SMP_CACHE_BYTES, \ - __pa(MAX_DMA_ADDRESS)) -#define alloc_bootmem_low(x) \ - __alloc_bootmem_node(NODE_DATA(0), (x), SMP_CACHE_BYTES, 0) -#define alloc_bootmem_pages(x) \ - __alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS)) -#define alloc_bootmem_pages_nopanic(x) \ - __alloc_bootmem_node_nopanic(NODE_DATA(0), (x), PAGE_SIZE, \ - __pa(MAX_DMA_ADDRESS)) -#define alloc_bootmem_low_pages(x) \ - __alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, 0) -#define alloc_bootmem_node(pgdat, x) \ -({ \ - struct pglist_data __maybe_unused \ - *__alloc_bootmem_node__pgdat = (pgdat); \ - __alloc_bootmem_node(NODE_DATA(0), (x), SMP_CACHE_BYTES, \ - __pa(MAX_DMA_ADDRESS)); \ -}) -#define alloc_bootmem_pages_node(pgdat, x) \ -({ \ - struct pglist_data __maybe_unused \ - *__alloc_bootmem_node__pgdat = (pgdat); \ - __alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, \ - __pa(MAX_DMA_ADDRESS)); \ -}) -#define alloc_bootmem_low_pages_node(pgdat, x) \ +/* always use node 0 for bootmem on this numa platform */ +#define alloc_bootmem_core(__bdata, size, align, goal, limit) \ ({ \ - struct pglist_data __maybe_unused \ - *__alloc_bootmem_node__pgdat = (pgdat); \ - __alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, 0); \ + bootmem_data_t __maybe_unused * __abm_bdata_dummy = (__bdata); \ + __alloc_bootmem_core(NODE_DATA(0)->bdata, \ + (size), (align), (goal), (limit)); \ }) #endif /* CONFIG_NEED_MULTIPLE_NODES */ diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h index 95837bfb525..3a87f93081e 100644 --- a/include/linux/bootmem.h +++ b/include/linux/bootmem.h @@ -69,10 +69,9 @@ extern int reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, unsigned long size, int flags); -#ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE -extern int reserve_bootmem(unsigned long addr, unsigned long size, int flags); -#endif - +extern int reserve_bootmem(unsigned long addr, + unsigned long size, + int flags); extern void *__alloc_bootmem_nopanic(unsigned long size, unsigned long align, unsigned long goal); @@ -94,7 +93,7 @@ extern void *__alloc_bootmem_low_node(pg_data_t *pgdat, unsigned long size, unsigned long align, unsigned long goal); -#ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE + #define alloc_bootmem(x) \ __alloc_bootmem(x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) #define alloc_bootmem_nopanic(x) \ @@ -113,7 +112,6 @@ extern void *__alloc_bootmem_low_node(pg_data_t *pgdat, __alloc_bootmem_node(pgdat, x, PAGE_SIZE, __pa(MAX_DMA_ADDRESS)) #define alloc_bootmem_low_pages_node(pgdat, x) \ __alloc_bootmem_low_node(pgdat, x, PAGE_SIZE, 0) -#endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */ extern int reserve_bootmem_generic(unsigned long addr, unsigned long size, int flags); diff --git a/mm/bootmem.c b/mm/bootmem.c index 51a0ccf61e0..d7140c008ba 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c @@ -37,6 +37,16 @@ static struct list_head bdata_list __initdata = LIST_HEAD_INIT(bdata_list); static int bootmem_debug; +/* + * If an arch needs to apply workarounds to bootmem allocation, it can + * set CONFIG_HAVE_ARCH_BOOTMEM and define a wrapper around + * __alloc_bootmem_core(). + */ +#ifndef CONFIG_HAVE_ARCH_BOOTMEM +#define alloc_bootmem_core(bdata, size, align, goal, limit) \ + __alloc_bootmem_core((bdata), (size), (align), (goal), (limit)) +#endif + static int __init bootmem_debug_setup(char *buf) { bootmem_debug = 1; @@ -382,7 +392,6 @@ int __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, return mark_bootmem_node(pgdat->bdata, start, end, 1, flags); } -#ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE /** * reserve_bootmem - mark a page range as usable * @addr: starting address of the range @@ -403,7 +412,6 @@ int __init reserve_bootmem(unsigned long addr, unsigned long size, return mark_bootmem(start, end, 1, flags); } -#endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */ static unsigned long align_idx(struct bootmem_data *bdata, unsigned long idx, unsigned long step) @@ -428,7 +436,7 @@ static unsigned long align_off(struct bootmem_data *bdata, unsigned long off, return ALIGN(base + off, align) - base; } -static void * __init alloc_bootmem_core(struct bootmem_data *bdata, +static void * __init __alloc_bootmem_core(struct bootmem_data *bdata, unsigned long size, unsigned long align, unsigned long goal, unsigned long limit) { -- cgit From 2d0aae41695257603fc281b519677131ab5a752b Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 24 Feb 2009 11:57:21 +0900 Subject: bootmem: reorder interface functions and add a missing one Impact: cleanup and addition of missing interface wrapper The interface functions in bootmem.h was ordered in not so orderly manner. Reorder them such that * functions allocating the same area group together - ie. alloc_bootmem group and alloc_bootmem_low group. * functions w/o node parameter come before the ones w/ node parameter. * nopanic variants are immediately below their panicky counterparts. While at it, add alloc_bootmem_pages_node_nopanic() which was missing. Signed-off-by: Tejun Heo Cc: Johannes Weiner --- include/linux/bootmem.h | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h index 3a87f93081e..455d83219fa 100644 --- a/include/linux/bootmem.h +++ b/include/linux/bootmem.h @@ -65,22 +65,20 @@ extern void free_bootmem(unsigned long addr, unsigned long size); #define BOOTMEM_DEFAULT 0 #define BOOTMEM_EXCLUSIVE (1<<0) -extern int reserve_bootmem_node(pg_data_t *pgdat, - unsigned long physaddr, - unsigned long size, - int flags); extern int reserve_bootmem(unsigned long addr, unsigned long size, int flags); -extern void *__alloc_bootmem_nopanic(unsigned long size, +extern int reserve_bootmem_node(pg_data_t *pgdat, + unsigned long physaddr, + unsigned long size, + int flags); + +extern void *__alloc_bootmem(unsigned long size, unsigned long align, unsigned long goal); -extern void *__alloc_bootmem(unsigned long size, +extern void *__alloc_bootmem_nopanic(unsigned long size, unsigned long align, unsigned long goal); -extern void *__alloc_bootmem_low(unsigned long size, - unsigned long align, - unsigned long goal); extern void *__alloc_bootmem_node(pg_data_t *pgdat, unsigned long size, unsigned long align, @@ -89,6 +87,9 @@ extern void *__alloc_bootmem_node_nopanic(pg_data_t *pgdat, unsigned long size, unsigned long align, unsigned long goal); +extern void *__alloc_bootmem_low(unsigned long size, + unsigned long align, + unsigned long goal); extern void *__alloc_bootmem_low_node(pg_data_t *pgdat, unsigned long size, unsigned long align, @@ -98,18 +99,21 @@ extern void *__alloc_bootmem_low_node(pg_data_t *pgdat, __alloc_bootmem(x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) #define alloc_bootmem_nopanic(x) \ __alloc_bootmem_nopanic(x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) -#define alloc_bootmem_low(x) \ - __alloc_bootmem_low(x, SMP_CACHE_BYTES, 0) #define alloc_bootmem_pages(x) \ __alloc_bootmem(x, PAGE_SIZE, __pa(MAX_DMA_ADDRESS)) #define alloc_bootmem_pages_nopanic(x) \ __alloc_bootmem_nopanic(x, PAGE_SIZE, __pa(MAX_DMA_ADDRESS)) -#define alloc_bootmem_low_pages(x) \ - __alloc_bootmem_low(x, PAGE_SIZE, 0) #define alloc_bootmem_node(pgdat, x) \ __alloc_bootmem_node(pgdat, x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) #define alloc_bootmem_pages_node(pgdat, x) \ __alloc_bootmem_node(pgdat, x, PAGE_SIZE, __pa(MAX_DMA_ADDRESS)) +#define alloc_bootmem_pages_node_nopanic(pgdat, x) \ + __alloc_bootmem_node_nopanic(pgdat, x, PAGE_SIZE, __pa(MAX_DMA_ADDRESS)) + +#define alloc_bootmem_low(x) \ + __alloc_bootmem_low(x, SMP_CACHE_BYTES, 0) +#define alloc_bootmem_low_pages(x) \ + __alloc_bootmem_low(x, PAGE_SIZE, 0) #define alloc_bootmem_low_pages_node(pgdat, x) \ __alloc_bootmem_low_node(pgdat, x, PAGE_SIZE, 0) -- cgit From c0c0a29379b5848aec2e8f1c58d853d3cb7118b8 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 24 Feb 2009 11:57:21 +0900 Subject: vmalloc: add @align to vm_area_register_early() Impact: allow larger alignment for early vmalloc area allocation Some early vmalloc users might want larger alignment, for example, for custom large page mapping. Add @align to vm_area_register_early(). While at it, drop docbook comment on non-existent @size. Signed-off-by: Tejun Heo Cc: Nick Piggin Cc: Ivan Kokshaysky --- arch/alpha/mm/init.c | 2 +- include/linux/vmalloc.h | 2 +- mm/percpu.c | 2 +- mm/vmalloc.c | 11 +++++++---- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c index df6df025ded..91eddd8505d 100644 --- a/arch/alpha/mm/init.c +++ b/arch/alpha/mm/init.c @@ -200,7 +200,7 @@ callback_init(void * kernel_end) /* register the vm area */ console_remap_vm.flags = VM_ALLOC; console_remap_vm.size = nr_pages << PAGE_SHIFT; - vm_area_register_early(&console_remap_vm); + vm_area_register_early(&console_remap_vm, PAGE_SIZE); vaddr = (unsigned long)consle_remap_vm.addr; diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 599ba798431..2f6994fdf0e 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -109,6 +109,6 @@ extern long vwrite(char *buf, char *addr, unsigned long count); */ extern rwlock_t vmlist_lock; extern struct vm_struct *vmlist; -extern __init void vm_area_register_early(struct vm_struct *vm); +extern __init void vm_area_register_early(struct vm_struct *vm, size_t align); #endif /* _LINUX_VMALLOC_H */ diff --git a/mm/percpu.c b/mm/percpu.c index ed92caa2aa3..41e7a5f5ab1 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -860,7 +860,7 @@ size_t __init pcpu_setup_static(pcpu_populate_pte_fn_t populate_pte_fn, /* init and register vm area */ static_vm.flags = VM_ALLOC; static_vm.size = pcpu_chunk_size; - vm_area_register_early(&static_vm); + vm_area_register_early(&static_vm, PAGE_SIZE); /* init static_chunk */ static_chunk = alloc_bootmem(pcpu_chunk_struct_size); diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 224eca9650a..366ae9ea6af 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -995,7 +995,7 @@ EXPORT_SYMBOL(vm_map_ram); /** * vm_area_register_early - register vmap area early during boot * @vm: vm_struct to register - * @size: size of area to register + * @align: requested alignment * * This function is used to register kernel vm area before * vmalloc_init() is called. @vm->size and @vm->flags should contain @@ -1004,12 +1004,15 @@ EXPORT_SYMBOL(vm_map_ram); * * DO NOT USE THIS FUNCTION UNLESS YOU KNOW WHAT YOU'RE DOING. */ -void __init vm_area_register_early(struct vm_struct *vm) +void __init vm_area_register_early(struct vm_struct *vm, size_t align) { static size_t vm_init_off __initdata; + unsigned long addr; + + addr = ALIGN(VMALLOC_START + vm_init_off, align); + vm_init_off = PFN_ALIGN(addr + vm->size) - VMALLOC_START; - vm->addr = (void *)VMALLOC_START + vm_init_off; - vm_init_off = PFN_ALIGN(vm_init_off + vm->size); + vm->addr = (void *)addr; vm->next = vmlist; vmlist = vm; -- cgit From 458a3e644c3327be529393982e24277eda8f1ac7 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 24 Feb 2009 11:57:21 +0900 Subject: x86: update populate_extra_pte() and add populate_extra_pmd() Impact: minor change to populate_extra_pte() and addition of pmd flavor Update populate_extra_pte() to return pointer to the pte_t for the specified address and add populate_extra_pmd() which only populates till the pmd and returns pointer to the pmd entry for the address. For 64bit, pud/pmd/pte fill functions are separated out from set_pte_vaddr[_pud]() and used for set_pte_vaddr[_pud]() and populate_extra_{pte|pmd}(). Signed-off-by: Tejun Heo --- arch/x86/include/asm/pgtable.h | 3 +- arch/x86/kernel/setup_percpu.c | 7 +++- arch/x86/mm/init_32.c | 13 ++++++-- arch/x86/mm/init_64.c | 75 +++++++++++++++++++++++++----------------- 4 files changed, 63 insertions(+), 35 deletions(-) diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index dd91c2515c6..46312eb0d68 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -402,7 +402,8 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, /* Install a pte for a particular vaddr in kernel space. */ void set_pte_vaddr(unsigned long vaddr, pte_t pte); -void populate_extra_pte(unsigned long vaddr); +pmd_t *populate_extra_pmd(unsigned long vaddr); +pte_t *populate_extra_pte(unsigned long vaddr); #ifdef CONFIG_X86_32 extern void native_pagetable_setup_start(pgd_t *base); diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 2dce4355821..671e6528a82 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -41,6 +41,11 @@ unsigned long __per_cpu_offset[NR_CPUS] __read_mostly = { }; EXPORT_SYMBOL(__per_cpu_offset); +static void __init pcpu4k_populate_pte(unsigned long addr) +{ + populate_extra_pte(addr); +} + static inline void setup_percpu_segment(int cpu) { #ifdef CONFIG_X86_32 @@ -104,7 +109,7 @@ void __init setup_per_cpu_areas(void) } } - pcpu_unit_size = pcpu_setup_static(populate_extra_pte, pages, size); + pcpu_unit_size = pcpu_setup_static(pcpu4k_populate_pte, pages, size); free_bootmem(__pa(pages), pages_size); diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index 8b1a0ef7f87..84a26883ab4 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c @@ -137,14 +137,21 @@ static pte_t * __init one_page_table_init(pmd_t *pmd) return pte_offset_kernel(pmd, 0); } -void __init populate_extra_pte(unsigned long vaddr) +pmd_t * __init populate_extra_pmd(unsigned long vaddr) { int pgd_idx = pgd_index(vaddr); int pmd_idx = pmd_index(vaddr); + + return one_md_table_init(swapper_pg_dir + pgd_idx) + pmd_idx; +} + +pte_t * __init populate_extra_pte(unsigned long vaddr) +{ + int pte_idx = pte_index(vaddr); pmd_t *pmd; - pmd = one_md_table_init(swapper_pg_dir + pgd_idx); - one_page_table_init(pmd + pmd_idx); + pmd = populate_extra_pmd(vaddr); + return one_page_table_init(pmd) + pte_idx; } static pte_t *__init page_table_kmap_check(pte_t *pte, pmd_t *pmd, diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 7f91e2cdc4c..7d4e76da336 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -168,34 +168,51 @@ static __ref void *spp_getpage(void) return ptr; } -void -set_pte_vaddr_pud(pud_t *pud_page, unsigned long vaddr, pte_t new_pte) +static pud_t * __init fill_pud(pgd_t *pgd, unsigned long vaddr) { - pud_t *pud; - pmd_t *pmd; - pte_t *pte; + if (pgd_none(*pgd)) { + pud_t *pud = (pud_t *)spp_getpage(); + pgd_populate(&init_mm, pgd, pud); + if (pud != pud_offset(pgd, 0)) + printk(KERN_ERR "PAGETABLE BUG #00! %p <-> %p\n", + pud, pud_offset(pgd, 0)); + } + return pud_offset(pgd, vaddr); +} - pud = pud_page + pud_index(vaddr); +static pmd_t * __init fill_pmd(pud_t *pud, unsigned long vaddr) +{ if (pud_none(*pud)) { - pmd = (pmd_t *) spp_getpage(); + pmd_t *pmd = (pmd_t *) spp_getpage(); pud_populate(&init_mm, pud, pmd); - if (pmd != pmd_offset(pud, 0)) { + if (pmd != pmd_offset(pud, 0)) printk(KERN_ERR "PAGETABLE BUG #01! %p <-> %p\n", - pmd, pmd_offset(pud, 0)); - return; - } + pmd, pmd_offset(pud, 0)); } - pmd = pmd_offset(pud, vaddr); + return pmd_offset(pud, vaddr); +} + +static pte_t * __init fill_pte(pmd_t *pmd, unsigned long vaddr) +{ if (pmd_none(*pmd)) { - pte = (pte_t *) spp_getpage(); + pte_t *pte = (pte_t *) spp_getpage(); pmd_populate_kernel(&init_mm, pmd, pte); - if (pte != pte_offset_kernel(pmd, 0)) { + if (pte != pte_offset_kernel(pmd, 0)) printk(KERN_ERR "PAGETABLE BUG #02!\n"); - return; - } } + return pte_offset_kernel(pmd, vaddr); +} + +void set_pte_vaddr_pud(pud_t *pud_page, unsigned long vaddr, pte_t new_pte) +{ + pud_t *pud; + pmd_t *pmd; + pte_t *pte; + + pud = pud_page + pud_index(vaddr); + pmd = fill_pmd(pud, vaddr); + pte = fill_pte(pmd, vaddr); - pte = pte_offset_kernel(pmd, vaddr); set_pte(pte, new_pte); /* @@ -205,8 +222,7 @@ set_pte_vaddr_pud(pud_t *pud_page, unsigned long vaddr, pte_t new_pte) __flush_tlb_one(vaddr); } -void -set_pte_vaddr(unsigned long vaddr, pte_t pteval) +void set_pte_vaddr(unsigned long vaddr, pte_t pteval) { pgd_t *pgd; pud_t *pud_page; @@ -223,23 +239,22 @@ set_pte_vaddr(unsigned long vaddr, pte_t pteval) set_pte_vaddr_pud(pud_page, vaddr, pteval); } -void __init populate_extra_pte(unsigned long vaddr) +pmd_t * __init populate_extra_pmd(unsigned long vaddr) { pgd_t *pgd; pud_t *pud; pgd = pgd_offset_k(vaddr); - if (pgd_none(*pgd)) { - pud = (pud_t *)spp_getpage(); - pgd_populate(&init_mm, pgd, pud); - if (pud != pud_offset(pgd, 0)) { - printk(KERN_ERR "PAGETABLE BUG #00! %p <-> %p\n", - pud, pud_offset(pgd, 0)); - return; - } - } + pud = fill_pud(pgd, vaddr); + return fill_pmd(pud, vaddr); +} + +pte_t * __init populate_extra_pte(unsigned long vaddr) +{ + pmd_t *pmd; - set_pte_vaddr_pud((pud_t *)pgd_page_vaddr(*pgd), vaddr, __pte(0)); + pmd = populate_extra_pmd(vaddr); + return fill_pte(pmd, vaddr); } /* -- cgit From d9b55eeb1d55ef2dc5a4fdbff9604c2c68cb5649 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 24 Feb 2009 11:57:21 +0900 Subject: percpu: remove unit_size power-of-2 restriction Impact: allow unit_size to be arbitrary multiple of PAGE_SIZE In dynamic percpu allocator, there is no reason the unit size should be power of two. Remove the restriction. As non-power-of-two unit size means that empty chunks fall into the same slot index as lightly occupied chunks which is bad for reclaming. Reserve an extra slot for empty chunks. Signed-off-by: Tejun Heo --- mm/percpu.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/mm/percpu.c b/mm/percpu.c index 41e7a5f5ab1..d9e6e5d1dbd 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -67,7 +67,7 @@ #include #include -#define PCPU_MIN_UNIT_PAGES_SHIFT 4 /* also max alloc size */ +#define PCPU_MIN_UNIT_PAGES 16 /* max alloc size in pages */ #define PCPU_SLOT_BASE_SHIFT 5 /* 1-31 shares the same slot */ #define PCPU_DFL_MAP_ALLOC 16 /* start a map with 16 ents */ @@ -83,9 +83,7 @@ struct pcpu_chunk { struct page *page[]; /* #cpus * UNIT_PAGES */ }; -static int pcpu_unit_pages_shift; static int pcpu_unit_pages; -static int pcpu_unit_shift; static int pcpu_unit_size; static int pcpu_chunk_size; static int pcpu_nr_slots; @@ -117,12 +115,19 @@ static DEFINE_MUTEX(pcpu_mutex); static struct list_head *pcpu_slot; /* chunk list slots */ static struct rb_root pcpu_addr_root = RB_ROOT; /* chunks by address */ -static int pcpu_size_to_slot(int size) +static int __pcpu_size_to_slot(int size) { int highbit = fls(size); /* size is in bytes */ return max(highbit - PCPU_SLOT_BASE_SHIFT + 2, 1); } +static int pcpu_size_to_slot(int size) +{ + if (size == pcpu_unit_size) + return pcpu_nr_slots - 1; + return __pcpu_size_to_slot(size); +} + static int pcpu_chunk_slot(const struct pcpu_chunk *chunk) { if (chunk->free_size < sizeof(int) || chunk->contig_hint < sizeof(int)) @@ -133,7 +138,7 @@ static int pcpu_chunk_slot(const struct pcpu_chunk *chunk) static int pcpu_page_idx(unsigned int cpu, int page_idx) { - return (cpu << pcpu_unit_pages_shift) + page_idx; + return cpu * pcpu_unit_pages + page_idx; } static struct page **pcpu_chunk_pagep(struct pcpu_chunk *chunk, @@ -659,7 +664,7 @@ static int pcpu_populate_chunk(struct pcpu_chunk *chunk, int off, int size) goto err; for_each_possible_cpu(cpu) - memset(chunk->vm->addr + (cpu << pcpu_unit_shift) + off, 0, + memset(chunk->vm->addr + cpu * pcpu_unit_size + off, 0, size); return 0; @@ -722,7 +727,7 @@ void *__alloc_percpu(size_t size, size_t align) struct pcpu_chunk *chunk; int slot, off; - if (unlikely(!size || size > PAGE_SIZE << PCPU_MIN_UNIT_PAGES_SHIFT || + if (unlikely(!size || size > PCPU_MIN_UNIT_PAGES * PAGE_SIZE || align > PAGE_SIZE)) { WARN(true, "illegal size (%zu) or align (%zu) for " "percpu allocation\n", size, align); @@ -840,19 +845,19 @@ size_t __init pcpu_setup_static(pcpu_populate_pte_fn_t populate_pte_fn, unsigned int cpu; int err, i; - pcpu_unit_pages_shift = max_t(int, PCPU_MIN_UNIT_PAGES_SHIFT, - order_base_2(cpu_size) - PAGE_SHIFT); + pcpu_unit_pages = max_t(int, PCPU_MIN_UNIT_PAGES, PFN_UP(cpu_size)); pcpu_static_size = cpu_size; - pcpu_unit_pages = 1 << pcpu_unit_pages_shift; - pcpu_unit_shift = PAGE_SHIFT + pcpu_unit_pages_shift; - pcpu_unit_size = 1 << pcpu_unit_shift; + pcpu_unit_size = pcpu_unit_pages << PAGE_SHIFT; pcpu_chunk_size = num_possible_cpus() * pcpu_unit_size; - pcpu_nr_slots = pcpu_size_to_slot(pcpu_unit_size) + 1; pcpu_chunk_struct_size = sizeof(struct pcpu_chunk) + num_possible_cpus() * pcpu_unit_pages * sizeof(struct page *); - /* allocate chunk slots */ + /* + * Allocate chunk slots. The additional last slot is for + * empty chunks. + */ + pcpu_nr_slots = __pcpu_size_to_slot(pcpu_unit_size) + 2; pcpu_slot = alloc_bootmem(pcpu_nr_slots * sizeof(pcpu_slot[0])); for (i = 0; i < pcpu_nr_slots; i++) INIT_LIST_HEAD(&pcpu_slot[i]); -- cgit From 8d408b4be37bc49c9086531f2ebe411cf5731746 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 24 Feb 2009 11:57:21 +0900 Subject: percpu: give more latitude to arch specific first chunk initialization Impact: more latitude for first percpu chunk allocation The first percpu chunk serves the kernel static percpu area and may or may not contain extra room for further dynamic allocation. Initialization of the first chunk needs to be done before normal memory allocation service is up, so it has its own init path - pcpu_setup_static(). It seems archs need more latitude while initializing the first chunk for example to take advantage of large page mapping. This patch makes the following changes to allow this. * Define PERCPU_DYNAMIC_RESERVE to give arch hint about how much space to reserve in the first chunk for further dynamic allocation. * Rename pcpu_setup_static() to pcpu_setup_first_chunk(). * Make pcpu_setup_first_chunk() much more flexible by fetching page pointer by callback and adding optional @unit_size, @free_size and @base_addr arguments which allow archs to selectively part of chunk initialization to their likings. Signed-off-by: Tejun Heo --- arch/x86/kernel/setup_percpu.c | 15 ++++- include/linux/percpu.h | 39 ++++++++++- mm/percpu.c | 149 ++++++++++++++++++++++++++++++++--------- 3 files changed, 167 insertions(+), 36 deletions(-) diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 671e6528a82..d928e888720 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -41,6 +41,16 @@ unsigned long __per_cpu_offset[NR_CPUS] __read_mostly = { }; EXPORT_SYMBOL(__per_cpu_offset); +static struct page **pcpu4k_pages __initdata; +static int pcpu4k_nr_static_pages __initdata; + +static struct page * __init pcpu4k_get_page(unsigned int cpu, int pageno) +{ + if (pageno < pcpu4k_nr_static_pages) + return pcpu4k_pages[cpu * pcpu4k_nr_static_pages + pageno]; + return NULL; +} + static void __init pcpu4k_populate_pte(unsigned long addr) { populate_extra_pte(addr); @@ -109,7 +119,10 @@ void __init setup_per_cpu_areas(void) } } - pcpu_unit_size = pcpu_setup_static(pcpu4k_populate_pte, pages, size); + pcpu4k_pages = pages; + pcpu4k_nr_static_pages = nr_cpu_pages; + pcpu_unit_size = pcpu_setup_first_chunk(pcpu4k_get_page, size, 0, 0, + NULL, pcpu4k_populate_pte); free_bootmem(__pa(pages), pages_size); diff --git a/include/linux/percpu.h b/include/linux/percpu.h index 18080995ff3..910beb0abea 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -78,12 +78,47 @@ #ifdef CONFIG_HAVE_DYNAMIC_PER_CPU_AREA +/* minimum unit size, also is the maximum supported allocation size */ +#define PCPU_MIN_UNIT_SIZE (16UL << PAGE_SHIFT) + +/* + * PERCPU_DYNAMIC_RESERVE indicates the amount of free area to piggy + * back on the first chunk if arch is manually allocating and mapping + * it for faster access (as a part of large page mapping for example). + * Note that dynamic percpu allocator covers both static and dynamic + * areas, so these values are bigger than PERCPU_MODULE_RESERVE. + * + * On typical configuration with modules, the following values leave + * about 8k of free space on the first chunk after boot on both x86_32 + * and 64 when module support is enabled. When module support is + * disabled, it's much tighter. + */ +#ifndef PERCPU_DYNAMIC_RESERVE +# if BITS_PER_LONG > 32 +# ifdef CONFIG_MODULES +# define PERCPU_DYNAMIC_RESERVE (6 << PAGE_SHIFT) +# else +# define PERCPU_DYNAMIC_RESERVE (4 << PAGE_SHIFT) +# endif +# else +# ifdef CONFIG_MODULES +# define PERCPU_DYNAMIC_RESERVE (4 << PAGE_SHIFT) +# else +# define PERCPU_DYNAMIC_RESERVE (2 << PAGE_SHIFT) +# endif +# endif +#endif /* PERCPU_DYNAMIC_RESERVE */ + extern void *pcpu_base_addr; +typedef struct page * (*pcpu_get_page_fn_t)(unsigned int cpu, int pageno); typedef void (*pcpu_populate_pte_fn_t)(unsigned long addr); -extern size_t __init pcpu_setup_static(pcpu_populate_pte_fn_t populate_pte_fn, - struct page **pages, size_t cpu_size); +extern size_t __init pcpu_setup_first_chunk(pcpu_get_page_fn_t get_page_fn, + size_t static_size, size_t unit_size, + size_t free_size, void *base_addr, + pcpu_populate_pte_fn_t populate_pte_fn); + /* * Use this to get to a cpu's version of the per-cpu object * dynamically allocated. Non-atomic access to the current CPU's diff --git a/mm/percpu.c b/mm/percpu.c index d9e6e5d1dbd..9ac01980cce 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -48,8 +48,8 @@ * - define __addr_to_pcpu_ptr() and __pcpu_ptr_to_addr() to translate * regular address to percpu pointer and back * - * - use pcpu_setup_static() during percpu area initialization to - * setup kernel static percpu area + * - use pcpu_setup_first_chunk() during percpu area initialization to + * setup the first chunk containing the kernel static percpu area */ #include @@ -67,7 +67,6 @@ #include #include -#define PCPU_MIN_UNIT_PAGES 16 /* max alloc size in pages */ #define PCPU_SLOT_BASE_SHIFT 5 /* 1-31 shares the same slot */ #define PCPU_DFL_MAP_ALLOC 16 /* start a map with 16 ents */ @@ -80,6 +79,7 @@ struct pcpu_chunk { int map_used; /* # of map entries used */ int map_alloc; /* # of map entries allocated */ int *map; /* allocation map */ + bool immutable; /* no [de]population allowed */ struct page *page[]; /* #cpus * UNIT_PAGES */ }; @@ -521,6 +521,9 @@ static void pcpu_unmap(struct pcpu_chunk *chunk, int page_start, int page_end, unsigned int last = num_possible_cpus() - 1; unsigned int cpu; + /* unmap must not be done on immutable chunk */ + WARN_ON(chunk->immutable); + /* * Each flushing trial can be very expensive, issue flush on * the whole region at once rather than doing it for each cpu. @@ -602,6 +605,9 @@ static int pcpu_map(struct pcpu_chunk *chunk, int page_start, int page_end) unsigned int cpu; int err; + /* map must not be done on immutable chunk */ + WARN_ON(chunk->immutable); + for_each_possible_cpu(cpu) { err = map_kernel_range_noflush( pcpu_chunk_addr(chunk, cpu, page_start), @@ -727,8 +733,7 @@ void *__alloc_percpu(size_t size, size_t align) struct pcpu_chunk *chunk; int slot, off; - if (unlikely(!size || size > PCPU_MIN_UNIT_PAGES * PAGE_SIZE || - align > PAGE_SIZE)) { + if (unlikely(!size || size > PCPU_MIN_UNIT_SIZE || align > PAGE_SIZE)) { WARN(true, "illegal size (%zu) or align (%zu) for " "percpu allocation\n", size, align); return NULL; @@ -776,6 +781,7 @@ EXPORT_SYMBOL_GPL(__alloc_percpu); static void pcpu_kill_chunk(struct pcpu_chunk *chunk) { + WARN_ON(chunk->immutable); pcpu_depopulate_chunk(chunk, 0, pcpu_unit_size, false); list_del(&chunk->list); rb_erase(&chunk->rb_node, &pcpu_addr_root); @@ -821,33 +827,73 @@ void free_percpu(void *ptr) EXPORT_SYMBOL_GPL(free_percpu); /** - * pcpu_setup_static - initialize kernel static percpu area - * @populate_pte_fn: callback to allocate pagetable - * @pages: num_possible_cpus() * PFN_UP(cpu_size) pages - * @cpu_size: the size of static percpu area in bytes - * - * Initialize kernel static percpu area. The caller should allocate - * all the necessary pages and pass them in @pages. - * @populate_pte_fn() is called on each page to be used for percpu - * mapping and is responsible for making sure all the necessary page - * tables for the page is allocated. + * pcpu_setup_first_chunk - initialize the first percpu chunk + * @get_page_fn: callback to fetch page pointer + * @static_size: the size of static percpu area in bytes + * @unit_size: unit size in bytes, must be multiple of PAGE_SIZE, 0 for auto + * @free_size: free size in bytes, 0 for auto + * @base_addr: mapped address, NULL for auto + * @populate_pte_fn: callback to allocate pagetable, NULL if unnecessary + * + * Initialize the first percpu chunk which contains the kernel static + * perpcu area. This function is to be called from arch percpu area + * setup path. The first two parameters are mandatory. The rest are + * optional. + * + * @get_page_fn() should return pointer to percpu page given cpu + * number and page number. It should at least return enough pages to + * cover the static area. The returned pages for static area should + * have been initialized with valid data. If @unit_size is specified, + * it can also return pages after the static area. NULL return + * indicates end of pages for the cpu. Note that @get_page_fn() must + * return the same number of pages for all cpus. + * + * @unit_size, if non-zero, determines unit size and must be aligned + * to PAGE_SIZE and equal to or larger than @static_size + @free_size. + * + * @free_size determines the number of free bytes after the static + * area in the first chunk. If zero, whatever left is available. + * Specifying non-zero value make percpu leave the area after + * @static_size + @free_size alone. + * + * Non-null @base_addr means that the caller already allocated virtual + * region for the first chunk and mapped it. percpu must not mess + * with the chunk. Note that @base_addr with 0 @unit_size or non-NULL + * @populate_pte_fn doesn't make any sense. + * + * @populate_pte_fn is used to populate the pagetable. NULL means the + * caller already populated the pagetable. * * RETURNS: * The determined pcpu_unit_size which can be used to initialize * percpu access. */ -size_t __init pcpu_setup_static(pcpu_populate_pte_fn_t populate_pte_fn, - struct page **pages, size_t cpu_size) +size_t __init pcpu_setup_first_chunk(pcpu_get_page_fn_t get_page_fn, + size_t static_size, size_t unit_size, + size_t free_size, void *base_addr, + pcpu_populate_pte_fn_t populate_pte_fn) { static struct vm_struct static_vm; struct pcpu_chunk *static_chunk; - int nr_cpu_pages = DIV_ROUND_UP(cpu_size, PAGE_SIZE); unsigned int cpu; + int nr_pages; int err, i; - pcpu_unit_pages = max_t(int, PCPU_MIN_UNIT_PAGES, PFN_UP(cpu_size)); + /* santiy checks */ + BUG_ON(!static_size); + BUG_ON(!unit_size && free_size); + BUG_ON(unit_size && unit_size < static_size + free_size); + BUG_ON(unit_size & ~PAGE_MASK); + BUG_ON(base_addr && !unit_size); + BUG_ON(base_addr && populate_pte_fn); - pcpu_static_size = cpu_size; + if (unit_size) + pcpu_unit_pages = unit_size >> PAGE_SHIFT; + else + pcpu_unit_pages = max_t(int, PCPU_MIN_UNIT_SIZE >> PAGE_SHIFT, + PFN_UP(static_size)); + + pcpu_static_size = static_size; pcpu_unit_size = pcpu_unit_pages << PAGE_SHIFT; pcpu_chunk_size = num_possible_cpus() * pcpu_unit_size; pcpu_chunk_struct_size = sizeof(struct pcpu_chunk) @@ -862,29 +908,66 @@ size_t __init pcpu_setup_static(pcpu_populate_pte_fn_t populate_pte_fn, for (i = 0; i < pcpu_nr_slots; i++) INIT_LIST_HEAD(&pcpu_slot[i]); - /* init and register vm area */ - static_vm.flags = VM_ALLOC; - static_vm.size = pcpu_chunk_size; - vm_area_register_early(&static_vm, PAGE_SIZE); - /* init static_chunk */ static_chunk = alloc_bootmem(pcpu_chunk_struct_size); INIT_LIST_HEAD(&static_chunk->list); static_chunk->vm = &static_vm; - static_chunk->free_size = pcpu_unit_size - pcpu_static_size; + + if (free_size) + static_chunk->free_size = free_size; + else + static_chunk->free_size = pcpu_unit_size - pcpu_static_size; + static_chunk->contig_hint = static_chunk->free_size; - /* assign pages and map them */ + /* allocate vm address */ + static_vm.flags = VM_ALLOC; + static_vm.size = pcpu_chunk_size; + + if (!base_addr) + vm_area_register_early(&static_vm, PAGE_SIZE); + else { + /* + * Pages already mapped. No need to remap into + * vmalloc area. In this case the static chunk can't + * be mapped or unmapped by percpu and is marked + * immutable. + */ + static_vm.addr = base_addr; + static_chunk->immutable = true; + } + + /* assign pages */ + nr_pages = -1; for_each_possible_cpu(cpu) { - for (i = 0; i < nr_cpu_pages; i++) { - *pcpu_chunk_pagep(static_chunk, cpu, i) = *pages++; - populate_pte_fn(pcpu_chunk_addr(static_chunk, cpu, i)); + for (i = 0; i < pcpu_unit_pages; i++) { + struct page *page = get_page_fn(cpu, i); + + if (!page) + break; + *pcpu_chunk_pagep(static_chunk, cpu, i) = page; } + + BUG_ON(i < PFN_UP(pcpu_static_size)); + + if (nr_pages < 0) + nr_pages = i; + else + BUG_ON(nr_pages != i); } - err = pcpu_map(static_chunk, 0, nr_cpu_pages); - if (err) - panic("failed to setup static percpu area, err=%d\n", err); + /* map them */ + if (populate_pte_fn) { + for_each_possible_cpu(cpu) + for (i = 0; i < nr_pages; i++) + populate_pte_fn(pcpu_chunk_addr(static_chunk, + cpu, i)); + + err = pcpu_map(static_chunk, 0, nr_pages); + if (err) + panic("failed to setup static percpu area, err=%d\n", + err); + } /* link static_chunk in */ pcpu_chunk_relocate(static_chunk, -1); -- cgit From 5f5d8405d1c50f5cf7e1dbfe9c9b44e2f015c8fd Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 24 Feb 2009 11:57:21 +0900 Subject: x86: separate out setup_pcpu_4k() from setup_per_cpu_areas() Impact: modularize percpu first chunk allocation x86 is gonna have a few different strategies for the first chunk allocation. Modularize it by separating out the current allocation mechanism into pcpu_alloc_bootmem() and setup_pcpu_4k(). Signed-off-by: Tejun Heo --- arch/x86/kernel/setup_percpu.c | 144 +++++++++++++++++++++++++++++------------ 1 file changed, 102 insertions(+), 42 deletions(-) diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index d928e888720..4a17c96f4f6 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,52 @@ unsigned long __per_cpu_offset[NR_CPUS] __read_mostly = { }; EXPORT_SYMBOL(__per_cpu_offset); +/** + * pcpu_alloc_bootmem - NUMA friendly alloc_bootmem wrapper for percpu + * @cpu: cpu to allocate for + * @size: size allocation in bytes + * @align: alignment + * + * Allocate @size bytes aligned at @align for cpu @cpu. This wrapper + * does the right thing for NUMA regardless of the current + * configuration. + * + * RETURNS: + * Pointer to the allocated area on success, NULL on failure. + */ +static void * __init pcpu_alloc_bootmem(unsigned int cpu, unsigned long size, + unsigned long align) +{ + const unsigned long goal = __pa(MAX_DMA_ADDRESS); +#ifdef CONFIG_NEED_MULTIPLE_NODES + int node = early_cpu_to_node(cpu); + void *ptr; + + if (!node_online(node) || !NODE_DATA(node)) { + ptr = __alloc_bootmem_nopanic(size, align, goal); + pr_info("cpu %d has no node %d or node-local memory\n", + cpu, node); + pr_debug("per cpu data for cpu%d %lu bytes at %016lx\n", + cpu, size, __pa(ptr)); + } else { + ptr = __alloc_bootmem_node_nopanic(NODE_DATA(node), + size, align, goal); + pr_debug("per cpu data for cpu%d %lu bytes on node%d at " + "%016lx\n", cpu, size, node, __pa(ptr)); + } + return ptr; +#else + return __alloc_bootmem_nopanic(size, align, goal); +#endif +} + +/* + * 4k page allocator + * + * This is the basic allocator. Static percpu area is allocated + * page-by-page and most of initialization is done by the generic + * setup function. + */ static struct page **pcpu4k_pages __initdata; static int pcpu4k_nr_static_pages __initdata; @@ -56,6 +103,51 @@ static void __init pcpu4k_populate_pte(unsigned long addr) populate_extra_pte(addr); } +static ssize_t __init setup_pcpu_4k(size_t static_size) +{ + size_t pages_size; + unsigned int cpu; + int i, j; + ssize_t ret; + + pcpu4k_nr_static_pages = PFN_UP(static_size); + + /* unaligned allocations can't be freed, round up to page size */ + pages_size = PFN_ALIGN(pcpu4k_nr_static_pages * num_possible_cpus() + * sizeof(pcpu4k_pages[0])); + pcpu4k_pages = alloc_bootmem(pages_size); + + /* allocate and copy */ + j = 0; + for_each_possible_cpu(cpu) + for (i = 0; i < pcpu4k_nr_static_pages; i++) { + void *ptr; + + ptr = pcpu_alloc_bootmem(cpu, PAGE_SIZE, PAGE_SIZE); + if (!ptr) + goto enomem; + + memcpy(ptr, __per_cpu_load + i * PAGE_SIZE, PAGE_SIZE); + pcpu4k_pages[j++] = virt_to_page(ptr); + } + + /* we're ready, commit */ + pr_info("PERCPU: Allocated %d 4k pages, static data %zu bytes\n", + pcpu4k_nr_static_pages, static_size); + + ret = pcpu_setup_first_chunk(pcpu4k_get_page, static_size, 0, 0, NULL, + pcpu4k_populate_pte); + goto out_free_ar; + +enomem: + while (--j >= 0) + free_bootmem(__pa(page_address(pcpu4k_pages[j])), PAGE_SIZE); + ret = -ENOMEM; +out_free_ar: + free_bootmem(__pa(pcpu4k_pages), pages_size); + return ret; +} + static inline void setup_percpu_segment(int cpu) { #ifdef CONFIG_X86_32 @@ -76,56 +168,24 @@ static inline void setup_percpu_segment(int cpu) */ void __init setup_per_cpu_areas(void) { - ssize_t size = __per_cpu_end - __per_cpu_start; - unsigned int nr_cpu_pages = DIV_ROUND_UP(size, PAGE_SIZE); - static struct page **pages; - size_t pages_size; - unsigned int cpu, i, j; + size_t static_size = __per_cpu_end - __per_cpu_start; + unsigned int cpu; unsigned long delta; size_t pcpu_unit_size; + ssize_t ret; pr_info("NR_CPUS:%d nr_cpumask_bits:%d nr_cpu_ids:%d nr_node_ids:%d\n", NR_CPUS, nr_cpumask_bits, nr_cpu_ids, nr_node_ids); - pr_info("PERCPU: Allocating %zd bytes for static per cpu data\n", size); - - pages_size = nr_cpu_pages * num_possible_cpus() * sizeof(pages[0]); - pages = alloc_bootmem(pages_size); - - j = 0; - for_each_possible_cpu(cpu) { - void *ptr; - - for (i = 0; i < nr_cpu_pages; i++) { -#ifndef CONFIG_NEED_MULTIPLE_NODES - ptr = alloc_bootmem_pages(PAGE_SIZE); -#else - int node = early_cpu_to_node(cpu); - - if (!node_online(node) || !NODE_DATA(node)) { - ptr = alloc_bootmem_pages(PAGE_SIZE); - pr_info("cpu %d has no node %d or node-local " - "memory\n", cpu, node); - pr_debug("per cpu data for cpu%d at %016lx\n", - cpu, __pa(ptr)); - } else { - ptr = alloc_bootmem_pages_node(NODE_DATA(node), - PAGE_SIZE); - pr_debug("per cpu data for cpu%d on node%d " - "at %016lx\n", cpu, node, __pa(ptr)); - } -#endif - memcpy(ptr, __per_cpu_load + i * PAGE_SIZE, PAGE_SIZE); - pages[j++] = virt_to_page(ptr); - } - } - pcpu4k_pages = pages; - pcpu4k_nr_static_pages = nr_cpu_pages; - pcpu_unit_size = pcpu_setup_first_chunk(pcpu4k_get_page, size, 0, 0, - NULL, pcpu4k_populate_pte); + /* allocate percpu area */ + ret = setup_pcpu_4k(static_size); + if (ret < 0) + panic("cannot allocate static percpu area (%zu bytes, err=%zd)", + static_size, ret); - free_bootmem(__pa(pages), pages_size); + pcpu_unit_size = ret; + /* alrighty, percpu areas up and running */ delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start; for_each_possible_cpu(cpu) { per_cpu_offset(cpu) = delta + cpu * pcpu_unit_size; -- cgit From 89c9215165ca609096e845926d9a18f1306176a4 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 24 Feb 2009 11:57:21 +0900 Subject: x86: add embedding percpu first chunk allocator Impact: add better first percpu allocation for !NUMA On !NUMA, we can simply allocate contiguous memory and use it for the first chunk without mapping it into vmalloc area. As the memory area is covered by the large page physical memory mapping, it allows the dynamic perpcu allocator to not add any TLB overhead for the static percpu area and whatever falls into the first chunk and the implementation is very simple too. Signed-off-by: Tejun Heo --- arch/x86/kernel/setup_percpu.c | 86 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 4a17c96f4f6..fd4c399675d 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -42,6 +42,35 @@ unsigned long __per_cpu_offset[NR_CPUS] __read_mostly = { }; EXPORT_SYMBOL(__per_cpu_offset); +/** + * pcpu_need_numa - determine percpu allocation needs to consider NUMA + * + * If NUMA is not configured or there is only one NUMA node available, + * there is no reason to consider NUMA. This function determines + * whether percpu allocation should consider NUMA or not. + * + * RETURNS: + * true if NUMA should be considered; otherwise, false. + */ +static bool __init pcpu_need_numa(void) +{ +#ifdef CONFIG_NEED_MULTIPLE_NODES + pg_data_t *last = NULL; + unsigned int cpu; + + for_each_possible_cpu(cpu) { + int node = early_cpu_to_node(cpu); + + if (node_online(node) && NODE_DATA(node) && + last && last != NODE_DATA(node)) + return true; + + last = NODE_DATA(node); + } +#endif + return false; +} + /** * pcpu_alloc_bootmem - NUMA friendly alloc_bootmem wrapper for percpu * @cpu: cpu to allocate for @@ -81,6 +110,59 @@ static void * __init pcpu_alloc_bootmem(unsigned int cpu, unsigned long size, #endif } +/* + * Embedding allocator + * + * The first chunk is sized to just contain the static area plus + * PERCPU_DYNAMIC_RESERVE and allocated as a contiguous area using + * bootmem allocator and used as-is without being mapped into vmalloc + * area. This enables the first chunk to piggy back on the linear + * physical PMD mapping and doesn't add any additional pressure to + * TLB. + */ +static void *pcpue_ptr __initdata; +static size_t pcpue_unit_size __initdata; + +static struct page * __init pcpue_get_page(unsigned int cpu, int pageno) +{ + return virt_to_page(pcpue_ptr + cpu * pcpue_unit_size + + ((size_t)pageno << PAGE_SHIFT)); +} + +static ssize_t __init setup_pcpu_embed(size_t static_size) +{ + unsigned int cpu; + + /* + * If large page isn't supported, there's no benefit in doing + * this. Also, embedding allocation doesn't play well with + * NUMA. + */ + if (!cpu_has_pse || pcpu_need_numa()) + return -EINVAL; + + /* allocate and copy */ + pcpue_unit_size = PFN_ALIGN(static_size + PERCPU_DYNAMIC_RESERVE); + pcpue_unit_size = max(pcpue_unit_size, PCPU_MIN_UNIT_SIZE); + pcpue_ptr = pcpu_alloc_bootmem(0, num_possible_cpus() * pcpue_unit_size, + PAGE_SIZE); + if (!pcpue_ptr) + return -ENOMEM; + + for_each_possible_cpu(cpu) + memcpy(pcpue_ptr + cpu * pcpue_unit_size, __per_cpu_load, + static_size); + + /* we're ready, commit */ + pr_info("PERCPU: Embedded %zu pages at %p, static data %zu bytes\n", + pcpue_unit_size >> PAGE_SHIFT, pcpue_ptr, static_size); + + return pcpu_setup_first_chunk(pcpue_get_page, static_size, + pcpue_unit_size, + pcpue_unit_size - static_size, pcpue_ptr, + NULL); +} + /* * 4k page allocator * @@ -178,7 +260,9 @@ void __init setup_per_cpu_areas(void) NR_CPUS, nr_cpumask_bits, nr_cpu_ids, nr_node_ids); /* allocate percpu area */ - ret = setup_pcpu_4k(static_size); + ret = setup_pcpu_embed(static_size); + if (ret < 0) + ret = setup_pcpu_4k(static_size); if (ret < 0) panic("cannot allocate static percpu area (%zu bytes, err=%zd)", static_size, ret); -- cgit From 8ac837571491e239e64bd87863c1679d8002e8a2 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 24 Feb 2009 11:57:22 +0900 Subject: x86: add remapping percpu first chunk allocator Impact: add better first percpu allocation for NUMA On NUMA, embedding allocator can't be used as different units can't be made to fall in the correct NUMA nodes. To use large page mapping, each unit needs to be remapped. However, percpu areas are usually much smaller than large page size and unused space hurts a lot as the number of cpus grow. This allocator remaps large pages for each chunk but gives back unused part to the bootmem allocator making the large pages mapped twice. This adds slightly to the TLB pressure but is much better than using 4k mappings while still being NUMA-friendly. Ingo suggested that this would be the correct approach for NUMA. Signed-off-by: Tejun Heo Cc: Ingo Molnar --- arch/x86/kernel/setup_percpu.c | 137 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 135 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index fd4c399675d..2d946a8f78b 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -110,6 +110,133 @@ static void * __init pcpu_alloc_bootmem(unsigned int cpu, unsigned long size, #endif } +/* + * Remap allocator + * + * This allocator uses PMD page as unit. A PMD page is allocated for + * each cpu and each is remapped into vmalloc area using PMD mapping. + * As PMD page is quite large, only part of it is used for the first + * chunk. Unused part is returned to the bootmem allocator. + * + * So, the PMD pages are mapped twice - once to the physical mapping + * and to the vmalloc area for the first percpu chunk. The double + * mapping does add one more PMD TLB entry pressure but still is much + * better than only using 4k mappings while still being NUMA friendly. + */ +#ifdef CONFIG_NEED_MULTIPLE_NODES +static size_t pcpur_size __initdata; +static void **pcpur_ptrs __initdata; + +static struct page * __init pcpur_get_page(unsigned int cpu, int pageno) +{ + size_t off = (size_t)pageno << PAGE_SHIFT; + + if (off >= pcpur_size) + return NULL; + + return virt_to_page(pcpur_ptrs[cpu] + off); +} + +static ssize_t __init setup_pcpu_remap(size_t static_size) +{ + static struct vm_struct vm; + pg_data_t *last; + size_t ptrs_size; + unsigned int cpu; + ssize_t ret; + + /* + * If large page isn't supported, there's no benefit in doing + * this. Also, on non-NUMA, embedding is better. + */ + if (!cpu_has_pse || pcpu_need_numa()) + return -EINVAL; + + last = NULL; + for_each_possible_cpu(cpu) { + int node = early_cpu_to_node(cpu); + + if (node_online(node) && NODE_DATA(node) && + last && last != NODE_DATA(node)) + goto proceed; + + last = NODE_DATA(node); + } + return -EINVAL; + +proceed: + /* + * Currently supports only single page. Supporting multiple + * pages won't be too difficult if it ever becomes necessary. + */ + pcpur_size = PFN_ALIGN(static_size + PERCPU_DYNAMIC_RESERVE); + if (pcpur_size > PMD_SIZE) { + pr_warning("PERCPU: static data is larger than large page, " + "can't use large page\n"); + return -EINVAL; + } + + /* allocate pointer array and alloc large pages */ + ptrs_size = PFN_ALIGN(num_possible_cpus() * sizeof(pcpur_ptrs[0])); + pcpur_ptrs = alloc_bootmem(ptrs_size); + + for_each_possible_cpu(cpu) { + pcpur_ptrs[cpu] = pcpu_alloc_bootmem(cpu, PMD_SIZE, PMD_SIZE); + if (!pcpur_ptrs[cpu]) + goto enomem; + + /* + * Only use pcpur_size bytes and give back the rest. + * + * Ingo: The 2MB up-rounding bootmem is needed to make + * sure the partial 2MB page is still fully RAM - it's + * not well-specified to have a PAT-incompatible area + * (unmapped RAM, device memory, etc.) in that hole. + */ + free_bootmem(__pa(pcpur_ptrs[cpu] + pcpur_size), + PMD_SIZE - pcpur_size); + + memcpy(pcpur_ptrs[cpu], __per_cpu_load, static_size); + } + + /* allocate address and map */ + vm.flags = VM_ALLOC; + vm.size = num_possible_cpus() * PMD_SIZE; + vm_area_register_early(&vm, PMD_SIZE); + + for_each_possible_cpu(cpu) { + pmd_t *pmd; + + pmd = populate_extra_pmd((unsigned long)vm.addr + + cpu * PMD_SIZE); + set_pmd(pmd, pfn_pmd(page_to_pfn(virt_to_page(pcpur_ptrs[cpu])), + PAGE_KERNEL_LARGE)); + } + + /* we're ready, commit */ + pr_info("PERCPU: Remapped at %p with large pages, static data " + "%zu bytes\n", vm.addr, static_size); + + ret = pcpu_setup_first_chunk(pcpur_get_page, static_size, PMD_SIZE, + pcpur_size - static_size, vm.addr, NULL); + goto out_free_ar; + +enomem: + for_each_possible_cpu(cpu) + if (pcpur_ptrs[cpu]) + free_bootmem(__pa(pcpur_ptrs[cpu]), PMD_SIZE); + ret = -ENOMEM; +out_free_ar: + free_bootmem(__pa(pcpur_ptrs), ptrs_size); + return ret; +} +#else +static ssize_t __init setup_pcpu_remap(size_t static_size) +{ + return -EINVAL; +} +#endif + /* * Embedding allocator * @@ -259,8 +386,14 @@ void __init setup_per_cpu_areas(void) pr_info("NR_CPUS:%d nr_cpumask_bits:%d nr_cpu_ids:%d nr_node_ids:%d\n", NR_CPUS, nr_cpumask_bits, nr_cpu_ids, nr_node_ids); - /* allocate percpu area */ - ret = setup_pcpu_embed(static_size); + /* + * Allocate percpu area. If PSE is supported, try to make use + * of large page mappings. Please read comments on top of + * each allocator for details. + */ + ret = setup_pcpu_remap(static_size); + if (ret < 0) + ret = setup_pcpu_embed(static_size); if (ret < 0) ret = setup_pcpu_4k(static_size); if (ret < 0) -- cgit From 40150d37be7f7949b2ec07d511244da856647d84 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 24 Feb 2009 12:32:28 +0900 Subject: percpu: add __read_mostly to variables which are mostly read only Most global variables in percpu allocator are initialized during boot and read only from that point on. Add __read_mostly as per Rusty's suggestion. Signed-off-by: Tejun Heo Cc: Rusty Russell --- mm/percpu.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/mm/percpu.c b/mm/percpu.c index 9ac01980cce..5954e7a9eb1 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -83,18 +83,18 @@ struct pcpu_chunk { struct page *page[]; /* #cpus * UNIT_PAGES */ }; -static int pcpu_unit_pages; -static int pcpu_unit_size; -static int pcpu_chunk_size; -static int pcpu_nr_slots; -static size_t pcpu_chunk_struct_size; +static int pcpu_unit_pages __read_mostly; +static int pcpu_unit_size __read_mostly; +static int pcpu_chunk_size __read_mostly; +static int pcpu_nr_slots __read_mostly; +static size_t pcpu_chunk_struct_size __read_mostly; /* the address of the first chunk which starts with the kernel static area */ -void *pcpu_base_addr; +void *pcpu_base_addr __read_mostly; EXPORT_SYMBOL_GPL(pcpu_base_addr); /* the size of kernel static area */ -static int pcpu_static_size; +static int pcpu_static_size __read_mostly; /* * One mutex to rule them all. @@ -112,7 +112,7 @@ static int pcpu_static_size; */ static DEFINE_MUTEX(pcpu_mutex); -static struct list_head *pcpu_slot; /* chunk list slots */ +static struct list_head *pcpu_slot __read_mostly; /* chunk list slots */ static struct rb_root pcpu_addr_root = RB_ROOT; /* chunks by address */ static int __pcpu_size_to_slot(int size) -- cgit From 0af98d37e85e6958eb84987b1f60da3b54008317 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Sun, 8 Feb 2009 16:44:42 +0100 Subject: [WATCHDOG] rc32434_wdt: fix watchdog driver The existing driver code wasn't working. Neither the timeout was set correctly, nor system reset was being triggered, as the driver seemed to keep the WDT alive himself. There was also some unnecessary code. Signed-off-by: Phil Sutter Signed-off-by: Wim Van Sebroeck Cc: stable --- drivers/watchdog/rc32434_wdt.c | 158 +++++++++++++++++------------------------ 1 file changed, 64 insertions(+), 94 deletions(-) diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c index 57027f4653c..f1f98cd757c 100644 --- a/drivers/watchdog/rc32434_wdt.c +++ b/drivers/watchdog/rc32434_wdt.c @@ -34,104 +34,89 @@ #include #include -#define MAX_TIMEOUT 20 -#define RC32434_WDT_INTERVAL (15 * HZ) - -#define VERSION "0.2" +#define VERSION "0.3" static struct { - struct completion stop; - int running; - struct timer_list timer; - int queue; - int default_ticks; unsigned long inuse; } rc32434_wdt_device; static struct integ __iomem *wdt_reg; -static int ticks = 100 * HZ; static int expect_close; -static int timeout; + +/* Board internal clock speed in Hz, + * the watchdog timer ticks at. */ +extern unsigned int idt_cpu_freq; + +/* translate wtcompare value to seconds and vice versa */ +#define WTCOMP2SEC(x) (x / idt_cpu_freq) +#define SEC2WTCOMP(x) (x * idt_cpu_freq) + +/* Use a default timeout of 20s. This should be + * safe for CPU clock speeds up to 400MHz, as + * ((2 ^ 32) - 1) / (400MHz / 2) = 21s. */ +#define WATCHDOG_TIMEOUT 20 + +static int timeout = WATCHDOG_TIMEOUT; static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); +/* apply or and nand masks to data read from addr and write back */ +#define SET_BITS(addr, or, nand) \ + writel((readl(&addr) | or) & ~nand, &addr) static void rc32434_wdt_start(void) { - u32 val; - - if (!rc32434_wdt_device.inuse) { - writel(0, &wdt_reg->wtcount); + u32 or, nand; - val = RC32434_ERR_WRE; - writel(readl(&wdt_reg->errcs) | val, &wdt_reg->errcs); + /* zero the counter before enabling */ + writel(0, &wdt_reg->wtcount); - val = RC32434_WTC_EN; - writel(readl(&wdt_reg->wtc) | val, &wdt_reg->wtc); - } - rc32434_wdt_device.running++; -} + /* don't generate a non-maskable interrupt, + * do a warm reset instead */ + nand = 1 << RC32434_ERR_WNE; + or = 1 << RC32434_ERR_WRE; -static void rc32434_wdt_stop(void) -{ - u32 val; + /* reset the ERRCS timeout bit in case it's set */ + nand |= 1 << RC32434_ERR_WTO; - if (rc32434_wdt_device.running) { + SET_BITS(wdt_reg->errcs, or, nand); - val = ~RC32434_WTC_EN; - writel(readl(&wdt_reg->wtc) & val, &wdt_reg->wtc); + /* reset WTC timeout bit and enable WDT */ + nand = 1 << RC32434_WTC_TO; + or = 1 << RC32434_WTC_EN; - val = ~RC32434_ERR_WRE; - writel(readl(&wdt_reg->errcs) & val, &wdt_reg->errcs); + SET_BITS(wdt_reg->wtc, or, nand); +} - rc32434_wdt_device.running = 0; - } +static void rc32434_wdt_stop(void) +{ + /* Disable WDT */ + SET_BITS(wdt_reg->wtc, 0, 1 << RC32434_WTC_EN); } -static void rc32434_wdt_set(int new_timeout) +static int rc32434_wdt_set(int new_timeout) { - u32 cmp = new_timeout * HZ; - u32 state, val; + int max_to = WTCOMP2SEC((u32)-1); + if (new_timeout < 0 || new_timeout > max_to) { + printk(KERN_ERR KBUILD_MODNAME + ": timeout value must be between 0 and %d", + max_to); + return -EINVAL; + } timeout = new_timeout; - /* - * store and disable WTC - */ - state = (u32)(readl(&wdt_reg->wtc) & RC32434_WTC_EN); - val = ~RC32434_WTC_EN; - writel(readl(&wdt_reg->wtc) & val, &wdt_reg->wtc); - - writel(0, &wdt_reg->wtcount); - writel(cmp, &wdt_reg->wtcompare); - - /* - * restore WTC - */ - - writel(readl(&wdt_reg->wtc) | state, &wdt_reg); -} + writel(SEC2WTCOMP(timeout), &wdt_reg->wtcompare); -static void rc32434_wdt_reset(void) -{ - ticks = rc32434_wdt_device.default_ticks; + return 0; } -static void rc32434_wdt_update(unsigned long unused) +static void rc32434_wdt_ping(void) { - if (rc32434_wdt_device.running) - ticks--; - writel(0, &wdt_reg->wtcount); - - if (rc32434_wdt_device.queue && ticks) - mod_timer(&rc32434_wdt_device.timer, - jiffies + RC32434_WDT_INTERVAL); - else - complete(&rc32434_wdt_device.stop); } static int rc32434_wdt_open(struct inode *inode, struct file *file) @@ -142,19 +127,23 @@ static int rc32434_wdt_open(struct inode *inode, struct file *file) if (nowayout) __module_get(THIS_MODULE); + rc32434_wdt_start(); + rc32434_wdt_ping(); + return nonseekable_open(inode, file); } static int rc32434_wdt_release(struct inode *inode, struct file *file) { - if (expect_close && nowayout == 0) { + if (expect_close == 42) { rc32434_wdt_stop(); printk(KERN_INFO KBUILD_MODNAME ": disabling watchdog timer\n"); module_put(THIS_MODULE); - } else + } else { printk(KERN_CRIT KBUILD_MODNAME ": device closed unexpectedly. WDT will not stop !\n"); - + rc32434_wdt_ping(); + } clear_bit(0, &rc32434_wdt_device.inuse); return 0; } @@ -174,10 +163,10 @@ static ssize_t rc32434_wdt_write(struct file *file, const char *data, if (get_user(c, data + i)) return -EFAULT; if (c == 'V') - expect_close = 1; + expect_close = 42; } } - rc32434_wdt_update(0); + rc32434_wdt_ping(); return len; } return 0; @@ -197,11 +186,11 @@ static long rc32434_wdt_ioctl(struct file *file, unsigned int cmd, }; switch (cmd) { case WDIOC_KEEPALIVE: - rc32434_wdt_reset(); + rc32434_wdt_ping(); break; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: - value = readl(&wdt_reg->wtcount); + value = 0; if (copy_to_user(argp, &value, sizeof(int))) return -EFAULT; break; @@ -218,6 +207,7 @@ static long rc32434_wdt_ioctl(struct file *file, unsigned int cmd, break; case WDIOS_DISABLECARD: rc32434_wdt_stop(); + break; default: return -EINVAL; } @@ -225,11 +215,9 @@ static long rc32434_wdt_ioctl(struct file *file, unsigned int cmd, case WDIOC_SETTIMEOUT: if (copy_from_user(&new_timeout, argp, sizeof(int))) return -EFAULT; - if (new_timeout < 1) + if (rc32434_wdt_set(new_timeout)) return -EINVAL; - if (new_timeout > MAX_TIMEOUT) - return -EINVAL; - rc32434_wdt_set(new_timeout); + /* Fall through */ case WDIOC_GETTIMEOUT: return copy_to_user(argp, &timeout, sizeof(int)); default: @@ -262,7 +250,7 @@ static int rc32434_wdt_probe(struct platform_device *pdev) int ret; struct resource *r; - r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rb500_wdt_res"); + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rb532_wdt_res"); if (!r) { printk(KERN_ERR KBUILD_MODNAME "failed to retrieve resources\n"); @@ -277,24 +265,12 @@ static int rc32434_wdt_probe(struct platform_device *pdev) } ret = misc_register(&rc32434_wdt_miscdev); - if (ret < 0) { printk(KERN_ERR KBUILD_MODNAME "failed to register watchdog device\n"); goto unmap; } - init_completion(&rc32434_wdt_device.stop); - rc32434_wdt_device.queue = 0; - - clear_bit(0, &rc32434_wdt_device.inuse); - - setup_timer(&rc32434_wdt_device.timer, rc32434_wdt_update, 0L); - - rc32434_wdt_device.default_ticks = ticks; - - rc32434_wdt_start(); - printk(banner, timeout); return 0; @@ -306,14 +282,8 @@ unmap: static int rc32434_wdt_remove(struct platform_device *pdev) { - if (rc32434_wdt_device.queue) { - rc32434_wdt_device.queue = 0; - wait_for_completion(&rc32434_wdt_device.stop); - } misc_deregister(&rc32434_wdt_miscdev); - iounmap(wdt_reg); - return 0; } -- cgit From d9a8798c4bab5ccd40e45e011f668099cfb3eb83 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Sun, 8 Feb 2009 16:44:42 +0100 Subject: [WATCHDOG] rc32434_wdt: fix sections Fix init and exit sections. Signed-off-by: Phil Sutter Signed-off-by: Wim Van Sebroeck Cc: stable --- drivers/watchdog/rc32434_wdt.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c index f1f98cd757c..f3553fa40b1 100644 --- a/drivers/watchdog/rc32434_wdt.c +++ b/drivers/watchdog/rc32434_wdt.c @@ -34,7 +34,7 @@ #include #include -#define VERSION "0.3" +#define VERSION "0.4" static struct { unsigned long inuse; @@ -242,10 +242,10 @@ static struct miscdevice rc32434_wdt_miscdev = { .fops = &rc32434_wdt_fops, }; -static char banner[] = KERN_INFO KBUILD_MODNAME +static char banner[] __devinitdata = KERN_INFO KBUILD_MODNAME ": Watchdog Timer version " VERSION ", timer margin: %d sec\n"; -static int rc32434_wdt_probe(struct platform_device *pdev) +static int __devinit rc32434_wdt_probe(struct platform_device *pdev) { int ret; struct resource *r; @@ -280,7 +280,7 @@ unmap: return ret; } -static int rc32434_wdt_remove(struct platform_device *pdev) +static int __devexit rc32434_wdt_remove(struct platform_device *pdev) { misc_deregister(&rc32434_wdt_miscdev); iounmap(wdt_reg); @@ -289,8 +289,8 @@ static int rc32434_wdt_remove(struct platform_device *pdev) static struct platform_driver rc32434_wdt = { .probe = rc32434_wdt_probe, - .remove = rc32434_wdt_remove, - .driver = { + .remove = __devexit_p(rc32434_wdt_remove), + .driver = { .name = "rc32434_wdt", } }; -- cgit From 044fad0dbb4e814c061916fe5a36851af2fd1135 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Tue, 24 Feb 2009 03:42:59 -0800 Subject: netxen: fix physical port mapping The PCI function to physical port mapping is valid only for old firmware. New firmware (4.0.0+) abstracts this. So driver should never try to access phy using invalid mapping. The behavior is unpredictable when PCI functions 4-7 are enabled on the same NIC. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic_main.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 9f33e442f40..f42581157f4 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -795,9 +795,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * See if the firmware gave us a virtual-physical port mapping. */ adapter->physical_port = adapter->portnum; - i = adapter->pci_read_normalize(adapter, CRB_V2P(adapter->portnum)); - if (i != 0x55555555) - adapter->physical_port = i; + if (adapter->fw_major < 4) { + i = adapter->pci_read_normalize(adapter, + CRB_V2P(adapter->portnum)); + if (i != 0x55555555) + adapter->physical_port = i; + } adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED); -- cgit From 028e1415a78733fcd2cba4b4c001826cc37a373e Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Tue, 24 Feb 2009 03:44:23 -0800 Subject: netxen: handle pci bar 0 mapping failure PCI bar 0 is used for memory mapped register access. If ioremap fails (returns NULL), register access results in crash. Use pci_ioremap_bar() instead of ioremap(), the latter fails on on 32 bit powerpc where pci resource address is > 32 bits. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic_main.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index f42581157f4..13087782ac4 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -588,7 +588,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->pci_mem_read = netxen_nic_pci_mem_read_2M; adapter->pci_mem_write = netxen_nic_pci_mem_write_2M; - mem_ptr0 = ioremap(mem_base, mem_len); + mem_ptr0 = pci_ioremap_bar(pdev, 0); + if (mem_ptr0 == NULL) { + dev_err(&pdev->dev, "failed to map PCI bar 0\n"); + return -EIO; + } + pci_len0 = mem_len; first_page_group_start = 0; first_page_group_end = 0; -- cgit From c81c8b68b46752721b0c1addfabb828da27e1489 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 6 Mar 2008 21:30:23 -0800 Subject: DVB: add firesat driver Original code written by Christian Dolzer Cleaned up by Greg. Major cleanup and reorg by Manu Abraham Additions also by Ben Backx Cc: Christian Dolzer Cc: Andreas Monitzer Cc: Manu Abraham Cc: Fabio De Lorenzo Cc: Robert Berger Signed-off-by: Ben Backx Signed-off-by: Greg Kroah-Hartman Added missing dependency to dvb/firesat/Kconfig, Reported-by: Randy Dunlap Tweaked dvb/Makefile. Signed-off-by: Stefan Richter --- drivers/media/dvb/Kconfig | 2 + drivers/media/dvb/Makefile | 2 + drivers/media/dvb/firesat/Kconfig | 11 + drivers/media/dvb/firesat/Makefile | 12 + drivers/media/dvb/firesat/avc_api.c | 848 +++++++++++++++++++++++++++++++ drivers/media/dvb/firesat/avc_api.h | 381 ++++++++++++++ drivers/media/dvb/firesat/cmp.c | 230 +++++++++ drivers/media/dvb/firesat/cmp.h | 9 + drivers/media/dvb/firesat/firesat-ci.c | 95 ++++ drivers/media/dvb/firesat/firesat-ci.h | 9 + drivers/media/dvb/firesat/firesat-rc.c | 84 +++ drivers/media/dvb/firesat/firesat-rc.h | 9 + drivers/media/dvb/firesat/firesat.h | 85 ++++ drivers/media/dvb/firesat/firesat_1394.c | 468 +++++++++++++++++ drivers/media/dvb/firesat/firesat_dvb.c | 350 +++++++++++++ drivers/media/dvb/firesat/firesat_fe.c | 263 ++++++++++ 16 files changed, 2858 insertions(+) create mode 100644 drivers/media/dvb/firesat/Kconfig create mode 100644 drivers/media/dvb/firesat/Makefile create mode 100644 drivers/media/dvb/firesat/avc_api.c create mode 100644 drivers/media/dvb/firesat/avc_api.h create mode 100644 drivers/media/dvb/firesat/cmp.c create mode 100644 drivers/media/dvb/firesat/cmp.h create mode 100644 drivers/media/dvb/firesat/firesat-ci.c create mode 100644 drivers/media/dvb/firesat/firesat-ci.h create mode 100644 drivers/media/dvb/firesat/firesat-rc.c create mode 100644 drivers/media/dvb/firesat/firesat-rc.h create mode 100644 drivers/media/dvb/firesat/firesat.h create mode 100644 drivers/media/dvb/firesat/firesat_1394.c create mode 100644 drivers/media/dvb/firesat/firesat_dvb.c create mode 100644 drivers/media/dvb/firesat/firesat_fe.c diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig index 40ebde53b3c..8a2d5f9713d 100644 --- a/drivers/media/dvb/Kconfig +++ b/drivers/media/dvb/Kconfig @@ -51,6 +51,8 @@ comment "Supported SDMC DM1105 Adapters" depends on DVB_CORE && PCI && I2C source "drivers/media/dvb/dm1105/Kconfig" +source "drivers/media/dvb/firesat/Kconfig" + comment "Supported DVB Frontends" depends on DVB_CORE source "drivers/media/dvb/frontends/Kconfig" diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile index f91e9eb15e5..41710554012 100644 --- a/drivers/media/dvb/Makefile +++ b/drivers/media/dvb/Makefile @@ -3,3 +3,5 @@ # obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/ + +obj-$(CONFIG_DVB_FIRESAT) += firesat/ diff --git a/drivers/media/dvb/firesat/Kconfig b/drivers/media/dvb/firesat/Kconfig new file mode 100644 index 00000000000..93f8de5ec3c --- /dev/null +++ b/drivers/media/dvb/firesat/Kconfig @@ -0,0 +1,11 @@ +config DVB_FIRESAT + tristate "FireSAT devices" + depends on DVB_CORE && IEEE1394 && INPUT + help + Support for external IEEE1394 adapters designed by Digital Everywhere and + produced by El Gato, shipped under the brand name 'FireDTV/FloppyDTV'. + + These devices don't have a MPEG decoder built in, so you need + an external software decoder to watch TV. + + Say Y if you own such a device and want to use it. diff --git a/drivers/media/dvb/firesat/Makefile b/drivers/media/dvb/firesat/Makefile new file mode 100644 index 00000000000..fdf86870f1f --- /dev/null +++ b/drivers/media/dvb/firesat/Makefile @@ -0,0 +1,12 @@ +firesat-objs := firesat_1394.o \ + firesat_dvb.o \ + firesat_fe.o \ + avc_api.o \ + cmp.o \ + firesat-rc.o \ + firesat-ci.o + +obj-$(CONFIG_DVB_FIRESAT) += firesat.o + +EXTRA_CFLAGS := -Idrivers/ieee1394 +EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core diff --git a/drivers/media/dvb/firesat/avc_api.c b/drivers/media/dvb/firesat/avc_api.c new file mode 100644 index 00000000000..d70795623fb --- /dev/null +++ b/drivers/media/dvb/firesat/avc_api.c @@ -0,0 +1,848 @@ +/* + * FireSAT AVC driver + * + * Copyright (c) 2004 Andreas Monitzer + * Copyright (c) 2008 Ben Backx + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#include "firesat.h" +#include +#include +#include +#include +#include "avc_api.h" +#include "firesat-rc.h" + +#define RESPONSE_REGISTER 0xFFFFF0000D00ULL +#define COMMAND_REGISTER 0xFFFFF0000B00ULL +#define PCR_BASE_ADDRESS 0xFFFFF0000900ULL + +static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal); + +/* Frees an allocated packet */ +static void avc_free_packet(struct hpsb_packet *packet) +{ + hpsb_free_tlabel(packet); + hpsb_free_packet(packet); +} + +/* + * Goofy routine that basically does a down_timeout function. + * Stolen from sbp2.c + */ +static int avc_down_timeout(atomic_t *done, int timeout) +{ + int i; + + for (i = timeout; (i > 0 && atomic_read(done) == 0); i-= HZ/10) { + set_current_state(TASK_INTERRUPTIBLE); + if (schedule_timeout(HZ/10)) /* 100ms */ + return(1); + } + return ((i > 0) ? 0:1); +} + +static int __AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) { + struct hpsb_packet *packet; + struct node_entry *ne; + + ne = firesat->nodeentry; + if(!ne) { + printk("%s: lost node!\n",__func__); + return -EIO; + } + + /* need all input data */ + if(!firesat || !ne || !CmdFrm) + return -EINVAL; + +// printk(KERN_INFO "AVCWrite command %x\n",CmdFrm->opcode); + +// for(k=0;klength;k++) +// printk(KERN_INFO "CmdFrm[%d] = %08x\n", k, ((quadlet_t*)CmdFrm)[k]); + + packet=hpsb_make_writepacket(ne->host, ne->nodeid, COMMAND_REGISTER, + (quadlet_t*)CmdFrm, CmdFrm->length); + + hpsb_set_packet_complete_task(packet, (void (*)(void*))avc_free_packet, + packet); + + hpsb_node_fill_packet(ne, packet); + + if(RspFrm) + atomic_set(&firesat->avc_reply_received, 0); + + if (hpsb_send_packet(packet) < 0) { + avc_free_packet(packet); + atomic_set(&firesat->avc_reply_received, 1); + return -EIO; + } + + if(RspFrm) { + if(avc_down_timeout(&firesat->avc_reply_received,HZ/2)) { + printk("%s: timeout waiting for avc response\n",__func__); + atomic_set(&firesat->avc_reply_received, 1); + return -ETIMEDOUT; + } + + memcpy(RspFrm,firesat->respfrm,firesat->resp_length); + } + + return 0; +} + +int AVCWrite(struct firesat*firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) { + int ret; + if(down_interruptible(&firesat->avc_sem)) + return -EINTR; + + ret = __AVCWrite(firesat, CmdFrm, RspFrm); + + up(&firesat->avc_sem); + return ret; +} + +static void do_schedule_remotecontrol(unsigned long ignored); +DECLARE_TASKLET(schedule_remotecontrol, do_schedule_remotecontrol, 0); + +static void do_schedule_remotecontrol(unsigned long ignored) { + struct firesat *firesat; + unsigned long flags; + + spin_lock_irqsave(&firesat_list_lock, flags); + list_for_each_entry(firesat,&firesat_list,list) { + if(atomic_read(&firesat->reschedule_remotecontrol) == 1) { + if(down_trylock(&firesat->avc_sem)) + tasklet_schedule(&schedule_remotecontrol); + else { + if(__AVCRegisterRemoteControl(firesat, 1) == 0) + atomic_set(&firesat->reschedule_remotecontrol, 0); + else + tasklet_schedule(&schedule_remotecontrol); + + up(&firesat->avc_sem); + } + } + } + spin_unlock_irqrestore(&firesat_list_lock, flags); +} + +int AVCRecv(struct firesat *firesat, u8 *data, size_t length) { +// printk(KERN_INFO "%s\n",__func__); + + // remote control handling + + AVCRspFrm *RspFrm = (AVCRspFrm*)data; + + if(/*RspFrm->length >= 8 && ###*/ + ((RspFrm->operand[0] == SFE_VENDOR_DE_COMPANYID_0 && + RspFrm->operand[1] == SFE_VENDOR_DE_COMPANYID_1 && + RspFrm->operand[2] == SFE_VENDOR_DE_COMPANYID_2)) && + RspFrm->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) { + if(RspFrm->resp == CHANGED) { +// printk(KERN_INFO "%s: code = %02x %02x\n",__func__,RspFrm->operand[4],RspFrm->operand[5]); + firesat_got_remotecontrolcode((((u16)RspFrm->operand[4]) << 8) | ((u16)RspFrm->operand[5])); + + // schedule + atomic_set(&firesat->reschedule_remotecontrol, 1); + tasklet_schedule(&schedule_remotecontrol); + } else if(RspFrm->resp != INTERIM) + printk(KERN_INFO "%s: remote control result = %d\n",__func__, RspFrm->resp); + return 0; + } + + if(atomic_read(&firesat->avc_reply_received) == 1) { + printk("%s: received out-of-order AVC response, ignored\n",__func__); + return -EINVAL; + } +// AVCRspFrm *resp=(AVCRspFrm *)data; +// int k; +/* + printk(KERN_INFO "resp=0x%x\n",resp->resp); + printk(KERN_INFO "cts=0x%x\n",resp->cts); + printk(KERN_INFO "suid=0x%x\n",resp->suid); + printk(KERN_INFO "sutyp=0x%x\n",resp->sutyp); + printk(KERN_INFO "opcode=0x%x\n",resp->opcode); + printk(KERN_INFO "length=%d\n",resp->length); +*/ +// for(k=0;k<2;k++) +// printk(KERN_INFO "operand[%d]=%02x\n",k,resp->operand[k]); + + memcpy(firesat->respfrm,data,length); + firesat->resp_length=length; + + atomic_set(&firesat->avc_reply_received, 1); + + return 0; +} + +// tuning command for setting the relative LNB frequency (not supported by the AVC standard) +static void AVCTuner_tuneQPSK(struct firesat *firesat, struct dvb_frontend_parameters *params, AVCCmdFrm *CmdFrm) { + memset(CmdFrm, 0, sizeof(AVCCmdFrm)); + + CmdFrm->cts = AVC; + CmdFrm->ctype = CONTROL; + CmdFrm->sutyp = 0x5; + CmdFrm->suid = firesat->subunit; + CmdFrm->opcode = VENDOR; + + CmdFrm->operand[0]=SFE_VENDOR_DE_COMPANYID_0; + CmdFrm->operand[1]=SFE_VENDOR_DE_COMPANYID_1; + CmdFrm->operand[2]=SFE_VENDOR_DE_COMPANYID_2; + CmdFrm->operand[3]=SFE_VENDOR_OPCODE_TUNE_QPSK; + + printk(KERN_INFO "%s: tuning to frequency %u\n",__func__,params->frequency); + + CmdFrm->operand[4] = (params->frequency >> 24) & 0xFF; + CmdFrm->operand[5] = (params->frequency >> 16) & 0xFF; + CmdFrm->operand[6] = (params->frequency >> 8) & 0xFF; + CmdFrm->operand[7] = params->frequency & 0xFF; + + printk(KERN_INFO "%s: symbol rate = %uBd\n",__func__,params->u.qpsk.symbol_rate); + + CmdFrm->operand[8] = ((params->u.qpsk.symbol_rate/1000) >> 8) & 0xFF; + CmdFrm->operand[9] = (params->u.qpsk.symbol_rate/1000) & 0xFF; + + switch(params->u.qpsk.fec_inner) { + case FEC_1_2: + CmdFrm->operand[10] = 0x1; + break; + case FEC_2_3: + CmdFrm->operand[10] = 0x2; + break; + case FEC_3_4: + CmdFrm->operand[10] = 0x3; + break; + case FEC_5_6: + CmdFrm->operand[10] = 0x4; + break; + case FEC_7_8: + CmdFrm->operand[10] = 0x5; + break; + case FEC_4_5: + case FEC_8_9: + case FEC_AUTO: + default: + CmdFrm->operand[10] = 0x0; + } + + if(firesat->voltage == 0xff) + CmdFrm->operand[11] = 0xff; + else + CmdFrm->operand[11] = (firesat->voltage==SEC_VOLTAGE_18)?0:1; // polarisation + if(firesat->tone == 0xff) + CmdFrm->operand[12] = 0xff; + else + CmdFrm->operand[12] = (firesat->tone==SEC_TONE_ON)?1:0; // band + + CmdFrm->length = 16; +} + +int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, BYTE *status) { + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + M_VALID_FLAGS flags; + int k; + +// printk(KERN_INFO "%s\n", __func__); + + if(firesat->type == FireSAT_DVB_S) + AVCTuner_tuneQPSK(firesat, params, &CmdFrm); + else { + if(firesat->type == FireSAT_DVB_T) { + flags.Bits_T.GuardInterval = (params->u.ofdm.guard_interval != GUARD_INTERVAL_AUTO); + flags.Bits_T.CodeRateLPStream = (params->u.ofdm.code_rate_LP != FEC_AUTO); + flags.Bits_T.CodeRateHPStream = (params->u.ofdm.code_rate_HP != FEC_AUTO); + flags.Bits_T.HierarchyInfo = (params->u.ofdm.hierarchy_information != HIERARCHY_AUTO); + flags.Bits_T.Constellation = (params->u.ofdm.constellation != QAM_AUTO); + flags.Bits_T.Bandwidth = (params->u.ofdm.bandwidth != BANDWIDTH_AUTO); + flags.Bits_T.CenterFrequency = 1; + flags.Bits_T.reserved1 = 0; + flags.Bits_T.reserved2 = 0; + flags.Bits_T.OtherFrequencyFlag = 0; + flags.Bits_T.TransmissionMode = (params->u.ofdm.transmission_mode != TRANSMISSION_MODE_AUTO); + flags.Bits_T.NetworkId = 0; + } else { + flags.Bits.Modulation = 0; + if(firesat->type == FireSAT_DVB_S) { + flags.Bits.FEC_inner = 1; + } else if(firesat->type == FireSAT_DVB_C) { + flags.Bits.FEC_inner = 0; + } + flags.Bits.FEC_outer = 0; + flags.Bits.Symbol_Rate = 1; + flags.Bits.Frequency = 1; + flags.Bits.Orbital_Pos = 0; + if(firesat->type == FireSAT_DVB_S) { + flags.Bits.Polarisation = 1; + } else if(firesat->type == FireSAT_DVB_C) { + flags.Bits.Polarisation = 0; + } + flags.Bits.reserved_fields = 0; + flags.Bits.reserved1 = 0; + flags.Bits.Network_ID = 0; + } + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + + CmdFrm.cts = AVC; + CmdFrm.ctype = CONTROL; + CmdFrm.sutyp = 0x5; + CmdFrm.suid = firesat->subunit; + CmdFrm.opcode = DSD; + + CmdFrm.operand[0] = 0; // source plug + CmdFrm.operand[1] = 0xD2; // subfunction replace + CmdFrm.operand[2] = 0x20; // system id = DVB + CmdFrm.operand[3] = 0x00; // antenna number + CmdFrm.operand[4] = (firesat->type == FireSAT_DVB_T)?0x0c:0x11; // system_specific_multiplex selection_length + CmdFrm.operand[5] = flags.Valid_Word.ByteHi; // valid_flags [0] + CmdFrm.operand[6] = flags.Valid_Word.ByteLo; // valid_flags [1] + + if(firesat->type == FireSAT_DVB_T) { + CmdFrm.operand[7] = 0x0; + CmdFrm.operand[8] = (params->frequency/10) >> 24; + CmdFrm.operand[9] = ((params->frequency/10) >> 16) & 0xFF; + CmdFrm.operand[10] = ((params->frequency/10) >> 8) & 0xFF; + CmdFrm.operand[11] = (params->frequency/10) & 0xFF; + switch(params->u.ofdm.bandwidth) { + case BANDWIDTH_7_MHZ: + CmdFrm.operand[12] = 0x20; + break; + case BANDWIDTH_8_MHZ: + case BANDWIDTH_6_MHZ: // not defined by AVC spec + case BANDWIDTH_AUTO: + default: + CmdFrm.operand[12] = 0x00; + } + switch(params->u.ofdm.constellation) { + case QAM_16: + CmdFrm.operand[13] = 1 << 6; + break; + case QAM_64: + CmdFrm.operand[13] = 2 << 6; + break; + case QPSK: + default: + CmdFrm.operand[13] = 0x00; + } + switch(params->u.ofdm.hierarchy_information) { + case HIERARCHY_1: + CmdFrm.operand[13] |= 1 << 3; + break; + case HIERARCHY_2: + CmdFrm.operand[13] |= 2 << 3; + break; + case HIERARCHY_4: + CmdFrm.operand[13] |= 3 << 3; + break; + case HIERARCHY_AUTO: + case HIERARCHY_NONE: + default: + break; + } + switch(params->u.ofdm.code_rate_HP) { + case FEC_2_3: + CmdFrm.operand[13] |= 1; + break; + case FEC_3_4: + CmdFrm.operand[13] |= 2; + break; + case FEC_5_6: + CmdFrm.operand[13] |= 3; + break; + case FEC_7_8: + CmdFrm.operand[13] |= 4; + break; + case FEC_1_2: + default: + break; + } + switch(params->u.ofdm.code_rate_LP) { + case FEC_2_3: + CmdFrm.operand[14] = 1 << 5; + break; + case FEC_3_4: + CmdFrm.operand[14] = 2 << 5; + break; + case FEC_5_6: + CmdFrm.operand[14] = 3 << 5; + break; + case FEC_7_8: + CmdFrm.operand[14] = 4 << 5; + break; + case FEC_1_2: + default: + CmdFrm.operand[14] = 0x00; + break; + } + switch(params->u.ofdm.guard_interval) { + case GUARD_INTERVAL_1_16: + CmdFrm.operand[14] |= 1 << 3; + break; + case GUARD_INTERVAL_1_8: + CmdFrm.operand[14] |= 2 << 3; + break; + case GUARD_INTERVAL_1_4: + CmdFrm.operand[14] |= 3 << 3; + break; + case GUARD_INTERVAL_1_32: + case GUARD_INTERVAL_AUTO: + default: + break; + } + switch(params->u.ofdm.transmission_mode) { + case TRANSMISSION_MODE_8K: + CmdFrm.operand[14] |= 1 << 1; + break; + case TRANSMISSION_MODE_2K: + case TRANSMISSION_MODE_AUTO: + default: + break; + } + + CmdFrm.operand[15] = 0x00; // network_ID[0] + CmdFrm.operand[16] = 0x00; // network_ID[1] + CmdFrm.operand[17] = 0x00; // Nr_of_dsd_sel_specs = 0 - > No PIDs are transmitted + + CmdFrm.length = 20; + } else { + CmdFrm.operand[7] = 0x00; + CmdFrm.operand[8] = (((firesat->voltage==SEC_VOLTAGE_18)?0:1)<<6); /* 0 = H, 1 = V */ + CmdFrm.operand[9] = 0x00; + CmdFrm.operand[10] = 0x00; + + if(firesat->type == FireSAT_DVB_S) { + /* ### relative frequency -> absolute frequency */ + CmdFrm.operand[11] = (((params->frequency/4) >> 16) & 0xFF) | (2 << 6); + CmdFrm.operand[12] = ((params->frequency/4) >> 8) & 0xFF; + CmdFrm.operand[13] = (params->frequency/4) & 0xFF; + } else if(firesat->type == FireSAT_DVB_C) { + CmdFrm.operand[11] = (((params->frequency/4000) >> 16) & 0xFF) | (2 << 6); + CmdFrm.operand[12] = ((params->frequency/4000) >> 8) & 0xFF; + CmdFrm.operand[13] = (params->frequency/4000) & 0xFF; + } + + CmdFrm.operand[14] = ((params->u.qpsk.symbol_rate/1000) >> 12) & 0xFF; + CmdFrm.operand[15] = ((params->u.qpsk.symbol_rate/1000) >> 4) & 0xFF; + CmdFrm.operand[16] = ((params->u.qpsk.symbol_rate/1000) << 4) & 0xF0; + + CmdFrm.operand[17] = 0x00; + switch(params->u.qpsk.fec_inner) { + case FEC_1_2: + CmdFrm.operand[18] = 0x1; + break; + case FEC_2_3: + CmdFrm.operand[18] = 0x2; + break; + case FEC_3_4: + CmdFrm.operand[18] = 0x3; + break; + case FEC_5_6: + CmdFrm.operand[18] = 0x4; + break; + case FEC_7_8: + CmdFrm.operand[18] = 0x5; + break; + case FEC_4_5: + case FEC_8_9: + case FEC_AUTO: + default: + CmdFrm.operand[18] = 0x0; + } + if(firesat->type == FireSAT_DVB_S) { + CmdFrm.operand[19] = 0x08; // modulation + } else if(firesat->type == FireSAT_DVB_C) { + switch(params->u.qam.modulation) { + case QAM_16: + CmdFrm.operand[19] = 0x08; // modulation + break; + case QAM_32: + CmdFrm.operand[19] = 0x10; // modulation + break; + case QAM_64: + CmdFrm.operand[19] = 0x18; // modulation + break; + case QAM_128: + CmdFrm.operand[19] = 0x20; // modulation + break; + case QAM_256: + CmdFrm.operand[19] = 0x28; // modulation + break; + case QAM_AUTO: + default: + CmdFrm.operand[19] = 0x00; // modulation + } + } + CmdFrm.operand[20] = 0x00; + CmdFrm.operand[21] = 0x00; + CmdFrm.operand[22] = 0x00; // Nr_of_dsd_sel_specs = 0 - > No PIDs are transmitted + + CmdFrm.length=28; + } + } // AVCTuner_DSD_direct + + if((k=AVCWrite(firesat,&CmdFrm,&RspFrm))) + return k; + +// msleep(250); + mdelay(500); + + if(status) + *status=RspFrm.operand[2]; + return 0; +} + +int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]) { + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + int pos,k; + + printk(KERN_INFO "%s\n", __func__); + + if(pidc > 16 && pidc != 0xFF) + return -EINVAL; + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + + CmdFrm.cts = AVC; + CmdFrm.ctype = CONTROL; + CmdFrm.sutyp = 0x5; + CmdFrm.suid = firesat->subunit; + CmdFrm.opcode = DSD; + + CmdFrm.operand[0] = 0; // source plug + CmdFrm.operand[1] = 0xD2; // subfunction replace + CmdFrm.operand[2] = 0x20; // system id = DVB + CmdFrm.operand[3] = 0x00; // antenna number + CmdFrm.operand[4] = 0x11; // system_specific_multiplex selection_length + CmdFrm.operand[5] = 0x00; // valid_flags [0] + CmdFrm.operand[6] = 0x00; // valid_flags [1] + + if(firesat->type == FireSAT_DVB_T) { +/* CmdFrm.operand[7] = 0x00; + CmdFrm.operand[8] = 0x00;//(params->frequency/10) >> 24; + CmdFrm.operand[9] = 0x00;//((params->frequency/10) >> 16) & 0xFF; + CmdFrm.operand[10] = 0x00;//((params->frequency/10) >> 8) & 0xFF; + CmdFrm.operand[11] = 0x00;//(params->frequency/10) & 0xFF; + CmdFrm.operand[12] = 0x00; + CmdFrm.operand[13] = 0x00; + CmdFrm.operand[14] = 0x00; + + CmdFrm.operand[15] = 0x00; // network_ID[0] + CmdFrm.operand[16] = 0x00; // network_ID[1] +*/ CmdFrm.operand[17] = pidc; // Nr_of_dsd_sel_specs + + pos=18; + } else { +/* CmdFrm.operand[7] = 0x00; + CmdFrm.operand[8] = 0x00; + CmdFrm.operand[9] = 0x00; + CmdFrm.operand[10] = 0x00; + + CmdFrm.operand[11] = 0x00;//(((params->frequency/4) >> 16) & 0xFF) | (2 << 6); + CmdFrm.operand[12] = 0x00;//((params->frequency/4) >> 8) & 0xFF; + CmdFrm.operand[13] = 0x00;//(params->frequency/4) & 0xFF; + + CmdFrm.operand[14] = 0x00;//((params->u.qpsk.symbol_rate/1000) >> 12) & 0xFF; + CmdFrm.operand[15] = 0x00;//((params->u.qpsk.symbol_rate/1000) >> 4) & 0xFF; + CmdFrm.operand[16] = 0x00;//((params->u.qpsk.symbol_rate/1000) << 4) & 0xF0; + + CmdFrm.operand[17] = 0x00; + CmdFrm.operand[18] = 0x00; + CmdFrm.operand[19] = 0x00; // modulation + CmdFrm.operand[20] = 0x00; + CmdFrm.operand[21] = 0x00;*/ + CmdFrm.operand[22] = pidc; // Nr_of_dsd_sel_specs + + pos=23; + } + if(pidc != 0xFF) + for(k=0;k PID + CmdFrm.operand[pos++] = (pid[k] >> 8) & 0x1F; + CmdFrm.operand[pos++] = pid[k] & 0xFF; + CmdFrm.operand[pos++] = 0x00; // tableID + CmdFrm.operand[pos++] = 0x00; // filter_length + } + + CmdFrm.length = pos+3; + + if((pos+3)%4) + CmdFrm.length += 4 - ((pos+3)%4); + + if((k=AVCWrite(firesat,&CmdFrm,&RspFrm))) + return k; + + mdelay(250); + + return 0; +} + +int AVCTuner_GetTS(struct firesat *firesat){ + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + int k; + + printk(KERN_INFO "%s\n", __func__); + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + + CmdFrm.cts = AVC; + CmdFrm.ctype = CONTROL; + CmdFrm.sutyp = 0x5; + CmdFrm.suid = firesat->subunit; + CmdFrm.opcode = DSIT; + + CmdFrm.operand[0] = 0; // source plug + CmdFrm.operand[1] = 0xD2; // subfunction replace + CmdFrm.operand[2] = 0xFF; //status + CmdFrm.operand[3] = 0x20; // system id = DVB + CmdFrm.operand[4] = 0x00; // antenna number + CmdFrm.operand[5] = 0x0; // system_specific_search_flags + CmdFrm.operand[6] = 0x11; // system_specific_multiplex selection_length + CmdFrm.operand[7] = 0x00; // valid_flags [0] + CmdFrm.operand[8] = 0x00; // valid_flags [1] + CmdFrm.operand[24] = 0x00; // nr_of_dsit_sel_specs (always 0) + + CmdFrm.length = 28; + + if((k=AVCWrite(firesat, &CmdFrm, &RspFrm))) return k; + + mdelay(250); + return 0; +} + +int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport, int *has_ci) { + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + + memset(&CmdFrm,0,sizeof(AVCCmdFrm)); + + CmdFrm.cts = AVC; + CmdFrm.ctype = CONTROL; + CmdFrm.sutyp = 0x5; // tuner + CmdFrm.suid = firesat->subunit; + CmdFrm.opcode = READ_DESCRIPTOR; + + CmdFrm.operand[0]=DESCRIPTOR_SUBUNIT_IDENTIFIER; + CmdFrm.operand[1]=0xff; + CmdFrm.operand[2]=0x00; + CmdFrm.operand[3]=0x00; // length highbyte + CmdFrm.operand[4]=0x08; // length lowbyte + CmdFrm.operand[5]=0x00; // offset highbyte + CmdFrm.operand[6]=0x0d; // offset lowbyte + + CmdFrm.length=12; + + if(AVCWrite(firesat,&CmdFrm,&RspFrm)<0) + return -EIO; + + if(RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) { + printk("%s: AVCWrite returned error code %d\n",__func__,RspFrm.resp); + return -EINVAL; + } + if(((RspFrm.operand[3] << 8) + RspFrm.operand[4]) != 8) { + printk("%s: Invalid response length\n",__func__); + return -EINVAL; + } + if(systemId) + *systemId = RspFrm.operand[7]; + if(transport) + *transport = RspFrm.operand[14] & 0x7; + switch(RspFrm.operand[14] & 0x7) { + case 1: + printk(KERN_INFO "%s: found DVB/S\n",__func__); + break; + case 2: + printk(KERN_INFO "%s: found DVB/C\n",__func__); + break; + case 3: + printk(KERN_INFO "%s: found DVB/T\n",__func__); + break; + default: + printk(KERN_INFO "%s: found unknown tuner id %u\n",__func__,RspFrm.operand[14] & 0x7); + } + if(has_ci) + *has_ci = (RspFrm.operand[14] >> 4) & 0x1; + return 0; +} + +int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_info) { + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + int length; + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + + CmdFrm.cts=AVC; + CmdFrm.ctype=CONTROL; + CmdFrm.sutyp=0x05; // tuner + CmdFrm.suid=firesat->subunit; + CmdFrm.opcode=READ_DESCRIPTOR; + + CmdFrm.operand[0]=DESCRIPTOR_TUNER_STATUS; + CmdFrm.operand[1]=0xff; + CmdFrm.operand[2]=0x00; + CmdFrm.operand[3]=sizeof(ANTENNA_INPUT_INFO) >> 8; + CmdFrm.operand[4]=sizeof(ANTENNA_INPUT_INFO) & 0xFF; + CmdFrm.operand[5]=0x00; + CmdFrm.operand[6]=0x03; + CmdFrm.length=12; + //Absenden des AVC request und warten auf response + if (AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) + return -EIO; + + if(RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) { + printk("%s: AVCWrite returned code %d\n",__func__,RspFrm.resp); + return -EINVAL; + } + + length = (RspFrm.operand[3] << 8) + RspFrm.operand[4]; + if(length == sizeof(ANTENNA_INPUT_INFO)) + { + memcpy(antenna_input_info,&RspFrm.operand[7],length); + return 0; + } + printk("%s: invalid info returned from AVC\n",__func__); + return -EINVAL; +} + +int AVCLNBControl(struct firesat *firesat, char voltage, char burst, + char conttone, char nrdiseq, + struct dvb_diseqc_master_cmd *diseqcmd) +{ + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + int i,j; + + printk(KERN_INFO "%s: voltage = %x, burst = %x, conttone = %x\n",__func__,voltage,burst,conttone); + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + + CmdFrm.cts=AVC; + CmdFrm.ctype=CONTROL; + CmdFrm.sutyp=0x05; + CmdFrm.suid=firesat->subunit; + CmdFrm.opcode=VENDOR; + + CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; + CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; + CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; + CmdFrm.operand[3]=SFE_VENDOR_OPCODE_LNB_CONTROL; + + CmdFrm.operand[4]=voltage; + CmdFrm.operand[5]=nrdiseq; + + i=6; + + for(j=0;j + +#define BYTE unsigned char +#define WORD unsigned short +#define DWORD unsigned long +#define ULONG unsigned long +#define LONG long + + +/************************************************************* + FCP Address range +**************************************************************/ + +#define RESPONSE_REGISTER 0xFFFFF0000D00ULL +#define COMMAND_REGISTER 0xFFFFF0000B00ULL +#define PCR_BASE_ADDRESS 0xFFFFF0000900ULL + + +/************************************************************ + definition of structures +*************************************************************/ +typedef struct { + int Nr_SourcePlugs; + int Nr_DestinationPlugs; +} TunerInfo; + + +/*********************************************** + + supported cts + +************************************************/ + +#define AVC 0x0 + +// FCP command frame with ctype = 0x0 is AVC command frame + +#ifdef __LITTLE_ENDIAN + +// Definition FCP Command Frame +typedef struct _AVCCmdFrm +{ + // AV/C command frame + BYTE ctype : 4 ; // command type + BYTE cts : 4 ; // always 0x0 for AVC + BYTE suid : 3 ; // subunit ID + BYTE sutyp : 5 ; // subunit_typ + BYTE opcode : 8 ; // opcode + BYTE operand[509] ; // array of operands [1-507] + int length; //length of the command frame +} AVCCmdFrm ; + +// Definition FCP Response Frame +typedef struct _AVCRspFrm +{ + // AV/C response frame + BYTE resp : 4 ; // response type + BYTE cts : 4 ; // always 0x0 for AVC + BYTE suid : 3 ; // subunit ID + BYTE sutyp : 5 ; // subunit_typ + BYTE opcode : 8 ; // opcode + BYTE operand[509] ; // array of operands [1-507] + int length; //length of the response frame +} AVCRspFrm ; + +#else + +typedef struct _AVCCmdFrm +{ + BYTE cts:4; + BYTE ctype:4; + BYTE sutyp:5; + BYTE suid:3; + BYTE opcode; + BYTE operand[509]; + int length; +} AVCCmdFrm; + +typedef struct _AVCRspFrm +{ + BYTE cts:4; + BYTE resp:4; + BYTE sutyp:5; + BYTE suid:3; + BYTE opcode; + BYTE operand[509]; + int length; +} AVCRspFrm; + +#endif + +/************************************************************* + AVC command types (ctype) +**************************************************************/// +#define CONTROL 0x00 +#define STATUS 0x01 +#define INQUIRY 0x02 +#define NOTIFY 0x03 + +/************************************************************* + AVC respond types +**************************************************************/// +#define NOT_IMPLEMENTED 0x8 +#define ACCEPTED 0x9 +#define REJECTED 0xA +#define STABLE 0xC +#define CHANGED 0xD +#define INTERIM 0xF + +/************************************************************* + AVC opcodes +**************************************************************/// +#define CONNECT 0x24 +#define DISCONNECT 0x25 +#define UNIT_INFO 0x30 +#define SUBUNIT_Info 0x31 +#define VENDOR 0x00 + +#define PLUG_INFO 0x02 +#define OPEN_DESCRIPTOR 0x08 +#define READ_DESCRIPTOR 0x09 +#define OBJECT_NUMBER_SELECT 0x0D + +/************************************************************* + AVCTuner opcodes +**************************************************************/ + +#define DSIT 0xC8 +#define DSD 0xCB +#define DESCRIPTOR_TUNER_STATUS 0x80 +#define DESCRIPTOR_SUBUNIT_IDENTIFIER 0x00 + +/************************************************************* + AVCTuner list types +**************************************************************/ +#define Multiplex_List 0x80 +#define Service_List 0x82 + +/************************************************************* + AVCTuner object entries +**************************************************************/ +#define Multiplex 0x80 +#define Service 0x82 +#define Service_with_specified_components 0x83 +#define Preferred_components 0x90 +#define Component 0x84 + +/************************************************************* + Vendor-specific commands +**************************************************************/ + +// digital everywhere vendor ID +#define SFE_VENDOR_DE_COMPANYID_0 0x00 +#define SFE_VENDOR_DE_COMPANYID_1 0x12 +#define SFE_VENDOR_DE_COMPANYID_2 0x87 + +#define SFE_VENDOR_MAX_NR_COMPONENTS 0x4 +#define SFE_VENDOR_MAX_NR_SERVICES 0x3 +#define SFE_VENDOR_MAX_NR_DSD_ELEMENTS 0x10 + +// vendor commands +#define SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL 0x0A +#define SFE_VENDOR_OPCODE_LNB_CONTROL 0x52 +#define SFE_VENDOR_OPCODE_TUNE_QPSK 0x58 // QPSK command for DVB-S + +// TODO: following vendor specific commands needs to be implemented +#define SFE_VENDOR_OPCODE_GET_FIRMWARE_VERSION 0x00 +#define SFE_VENDOR_OPCODE_HOST2CA 0x56 +#define SFE_VENDOR_OPCODE_CA2HOST 0x57 +#define SFE_VENDOR_OPCODE_CISTATUS 0x59 +#define SFE_VENDOR_OPCODE_TUNE_QPSK2 0x60 // QPSK command for DVB-S2 devices + + +//AVCTuner DVB identifier service_ID +#define DVB 0x20 + +/************************************************************* + AVC descriptor types +**************************************************************/ + +#define Subunit_Identifier_Descriptor 0x00 +#define Tuner_Status_Descriptor 0x80 + +typedef struct { + BYTE Subunit_Type; + BYTE Max_Subunit_ID; +} SUBUNIT_INFO; + +/************************************************************* + + AVCTuner DVB object IDs are 6 byte long + +**************************************************************/ + +typedef struct { + BYTE Byte0; + BYTE Byte1; + BYTE Byte2; + BYTE Byte3; + BYTE Byte4; + BYTE Byte5; +}OBJECT_ID; + +/************************************************************* + MULIPLEX Structs +**************************************************************/ +typedef struct +{ +#ifdef __LITTLE_ENDIAN + BYTE RF_frequency_hByte:6; + BYTE raster_Frequency:2;//Bit7,6 raster frequency +#else + BYTE raster_Frequency:2; + BYTE RF_frequency_hByte:6; +#endif + BYTE RF_frequency_mByte; + BYTE RF_frequency_lByte; + +}FREQUENCY; + +#ifdef __LITTLE_ENDIAN + +typedef struct +{ + BYTE Modulation :1; + BYTE FEC_inner :1; + BYTE FEC_outer :1; + BYTE Symbol_Rate :1; + BYTE Frequency :1; + BYTE Orbital_Pos :1; + BYTE Polarisation :1; + BYTE reserved_fields :1; + BYTE reserved1 :7; + BYTE Network_ID :1; + +}MULTIPLEX_VALID_FLAGS; + +typedef struct +{ + BYTE GuardInterval:1; + BYTE CodeRateLPStream:1; + BYTE CodeRateHPStream:1; + BYTE HierarchyInfo:1; + BYTE Constellation:1; + BYTE Bandwidth:1; + BYTE CenterFrequency:1; + BYTE reserved1:1; + BYTE reserved2:5; + BYTE OtherFrequencyFlag:1; + BYTE TransmissionMode:1; + BYTE NetworkId:1; +}MULTIPLEX_VALID_FLAGS_DVBT; + +#else + +typedef struct { + BYTE reserved_fields:1; + BYTE Polarisation:1; + BYTE Orbital_Pos:1; + BYTE Frequency:1; + BYTE Symbol_Rate:1; + BYTE FEC_outer:1; + BYTE FEC_inner:1; + BYTE Modulation:1; + BYTE Network_ID:1; + BYTE reserved1:7; +}MULTIPLEX_VALID_FLAGS; + +typedef struct { + BYTE reserved1:1; + BYTE CenterFrequency:1; + BYTE Bandwidth:1; + BYTE Constellation:1; + BYTE HierarchyInfo:1; + BYTE CodeRateHPStream:1; + BYTE CodeRateLPStream:1; + BYTE GuardInterval:1; + BYTE NetworkId:1; + BYTE TransmissionMode:1; + BYTE OtherFrequencyFlag:1; + BYTE reserved2:5; +}MULTIPLEX_VALID_FLAGS_DVBT; + +#endif + +typedef union { + MULTIPLEX_VALID_FLAGS Bits; + MULTIPLEX_VALID_FLAGS_DVBT Bits_T; + struct { + BYTE ByteHi; + BYTE ByteLo; + } Valid_Word; +} M_VALID_FLAGS; + +typedef struct +{ +#ifdef __LITTLE_ENDIAN + BYTE ActiveSystem; + BYTE reserved:5; + BYTE NoRF:1; + BYTE Moving:1; + BYTE Searching:1; + + BYTE SelectedAntenna:7; + BYTE Input:1; + + BYTE BER[4]; + + BYTE SignalStrength; + FREQUENCY Frequency; + + BYTE ManDepInfoLength; +#else + BYTE ActiveSystem; + BYTE Searching:1; + BYTE Moving:1; + BYTE NoRF:1; + BYTE reserved:5; + + BYTE Input:1; + BYTE SelectedAntenna:7; + + BYTE BER[4]; + + BYTE SignalStrength; + FREQUENCY Frequency; + + BYTE ManDepInfoLength; +#endif +} ANTENNA_INPUT_INFO; // 11 Byte + +#define LNBCONTROL_DONTCARE 0xff + + +extern int AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm); +extern int AVCRecv(struct firesat *firesat, u8 *data, size_t length); + +extern int AVCTuner_DSIT(struct firesat *firesat, + int Source_Plug, + struct dvb_frontend_parameters *params, + BYTE *status); + +extern int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_info); +extern int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, BYTE *status); +extern int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]); +extern int AVCTuner_GetTS(struct firesat *firesat); + +extern int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport, int *has_ci); +extern int AVCLNBControl(struct firesat *firesat, char voltage, char burst, char conttone, char nrdiseq, struct dvb_diseqc_master_cmd *diseqcmd); +extern int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount); +extern int AVCRegisterRemoteControl(struct firesat *firesat); + +#endif + diff --git a/drivers/media/dvb/firesat/cmp.c b/drivers/media/dvb/firesat/cmp.c new file mode 100644 index 00000000000..37b91f3f7ff --- /dev/null +++ b/drivers/media/dvb/firesat/cmp.c @@ -0,0 +1,230 @@ +#include "cmp.h" +#include +#include +#include +#include +#include +#include +#include +#include "avc_api.h" + +typedef struct _OPCR +{ + BYTE PTPConnCount : 6 ; // Point to point connect. counter + BYTE BrConnCount : 1 ; // Broadcast connection counter + BYTE OnLine : 1 ; // On Line + + BYTE ChNr : 6 ; // Channel number + BYTE Res : 2 ; // Reserved + + BYTE PayloadHi : 2 ; // Payoad high bits + BYTE OvhdID : 4 ; // Overhead ID + BYTE DataRate : 2 ; // Data Rate + + BYTE PayloadLo ; // Payoad low byte +} OPCR ; + +#define FIRESAT_SPEED IEEE1394_SPEED_400 + +/* hpsb_lock is being removed from the kernel-source, + * therefor we define our own 'firesat_hpsb_lock'*/ + +int send_packet_and_wait(struct hpsb_packet *packet); + +int firesat_hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation, + u64 addr, int extcode, quadlet_t * data, quadlet_t arg) { + + struct hpsb_packet *packet; + int retval = 0; + + BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet + + packet = hpsb_make_lockpacket(host, node, addr, extcode, data, arg); + if (!packet) + return -ENOMEM; + + packet->generation = generation; + retval = send_packet_and_wait(packet); + if (retval < 0) + goto hpsb_lock_fail; + + retval = hpsb_packet_success(packet); + + if (retval == 0) { + *data = packet->data[0]; + } + + hpsb_lock_fail: + hpsb_free_tlabel(packet); + hpsb_free_packet(packet); + + return retval; +} + + +static int cmp_read(struct firesat *firesat, void *buffer, u64 addr, size_t length) { + int ret; + if(down_interruptible(&firesat->avc_sem)) + return -EINTR; + + ret = hpsb_read(firesat->host, firesat->nodeentry->nodeid, firesat->nodeentry->generation, + addr, buffer, length); + + up(&firesat->avc_sem); + return ret; +} + +static int cmp_lock(struct firesat *firesat, quadlet_t *data, u64 addr, quadlet_t arg, int ext_tcode) { + int ret; + if(down_interruptible(&firesat->avc_sem)) + return -EINTR; + + ret = firesat_hpsb_lock(firesat->host, firesat->nodeentry->nodeid, firesat->nodeentry->generation, + addr, ext_tcode, data, arg); + + up(&firesat->avc_sem); + return ret; +} + +//try establishing a point-to-point connection (may be interrupted by a busreset +int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, int iso_channel) { + unsigned int BWU; //bandwidth to allocate + + quadlet_t old_oPCR,test_oPCR = 0x0; + u64 oPCR_address=0xfffff0000904ull+(output_plug << 2); + int result=cmp_read(firesat, &test_oPCR, oPCR_address, 4); + + printk(KERN_INFO "%s: nodeid = %d\n",__func__,firesat->nodeentry->nodeid); + + if (result < 0) { + printk("%s: cannot read oPCR\n", __func__); + return result; + } else { + printk(KERN_INFO "%s: oPCR = %08x\n",__func__,test_oPCR); + do { + OPCR *hilf= (OPCR*) &test_oPCR; + + if (!hilf->OnLine) { + printk("%s: Output offline; oPCR: %08x\n", __func__, test_oPCR); + return -EBUSY; + } else { + quadlet_t new_oPCR; + + old_oPCR=test_oPCR; + if (hilf->PTPConnCount) { + if (hilf->ChNr != iso_channel) { + printk("%s: Output plug has already connection on channel %u; cannot change it to channel %u\n",__func__,hilf->ChNr,iso_channel); + return -EBUSY; + } else + printk(KERN_INFO "%s: Overlaying existing connection; connection counter was: %u\n",__func__, hilf->PTPConnCount); + BWU=0; //we allocate no bandwidth (is this necessary?) + } else { + hilf->ChNr=iso_channel; + hilf->DataRate=FIRESAT_SPEED; + + hilf->OvhdID=0; //FIXME: that is for worst case -> optimize + BWU=hilf->OvhdID?hilf->OvhdID*32:512; + BWU += (hilf->PayloadLo + (hilf->PayloadHi << 8) +3) * (2 << (3-hilf->DataRate)); +/* if (allocate_1394_resources(iso_channel,BWU)) + { + cout << "Allocation of resources failed\n"; + return -2; + }*/ + } + + hilf->PTPConnCount++; + new_oPCR=test_oPCR; + printk(KERN_INFO "%s: trying compare_swap...\n",__func__); + printk(KERN_INFO "%s: oPCR_old: %08x, oPCR_new: %08x\n",__func__, old_oPCR, new_oPCR); + result=cmp_lock(firesat, &test_oPCR, oPCR_address, old_oPCR, 2); + + if (result < 0) { + printk("%s: cannot compare_swap oPCR\n",__func__); + return result; + } + if ((old_oPCR != test_oPCR) && (!((OPCR*) &old_oPCR)->PTPConnCount)) + { + printk("%s: change of oPCR failed -> freeing resources\n",__func__); +// hilf= (OPCR*) &new_oPCR; +// unsigned int BWU=hilf->OvhdID?hilf->OvhdID*32:512; +// BWU += (hilf->Payload+3) * (2 << (3-hilf->DataRate)); +/* if (deallocate_1394_resources(iso_channel,BWU)) + { + + cout << "Deallocation of resources failed\n"; + return -3; + }*/ + } + } + } + while (old_oPCR != test_oPCR); + } + return 0; +} + +//try breaking a point-to-point connection (may be interrupted by a busreset +int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug,int iso_channel) { + quadlet_t old_oPCR,test_oPCR; + + u64 oPCR_address=0xfffff0000904ull+(output_plug << 2); + int result=cmp_read(firesat, &test_oPCR, oPCR_address, 4); + + printk(KERN_INFO "%s\n",__func__); + + if (result < 0) { + printk("%s: cannot read oPCR\n", __func__); + return result; + } else { + do { + OPCR *hilf= (OPCR*) &test_oPCR; + + if (!hilf->OnLine || !hilf->PTPConnCount || hilf->ChNr != iso_channel) { + printk("%s: Output plug does not have PtP-connection on that channel; oPCR: %08x\n", __func__, test_oPCR); + return -EINVAL; + } else { + quadlet_t new_oPCR; + old_oPCR=test_oPCR; + hilf->PTPConnCount--; + new_oPCR=test_oPCR; + +// printk(KERN_INFO "%s: trying compare_swap...\n", __func__); + result=cmp_lock(firesat, &test_oPCR, oPCR_address, old_oPCR, 2); + if (result < 0) { + printk("%s: cannot compare_swap oPCR\n",__func__); + return result; + } + } + + } while (old_oPCR != test_oPCR); + +/* hilf = (OPCR*) &old_oPCR; + if (hilf->PTPConnCount == 1) { // if we were the last owner of this connection + cout << "deallocating 1394 resources\n"; + unsigned int BWU=hilf->OvhdID?hilf->OvhdID*32:512; + BWU += (hilf->PayloadLo + (hilf->PayloadHi << 8) +3) * (2 << (3-hilf->DataRate)); + if (deallocate_1394_resources(iso_channel,BWU)) + { + cout << "Deallocation of resources failed\n"; + return -3; + } + }*/ + } + return 0; +} + +static void complete_packet(void *data) { + complete((struct completion *) data); +} + +int send_packet_and_wait(struct hpsb_packet *packet) { + struct completion done; + int retval; + + init_completion(&done); + hpsb_set_packet_complete_task(packet, complete_packet, &done); + retval = hpsb_send_packet(packet); + if (retval == 0) + wait_for_completion(&done); + + return retval; +} diff --git a/drivers/media/dvb/firesat/cmp.h b/drivers/media/dvb/firesat/cmp.h new file mode 100644 index 00000000000..d43fbc29f26 --- /dev/null +++ b/drivers/media/dvb/firesat/cmp.h @@ -0,0 +1,9 @@ +#ifndef __FIRESAT__CMP_H_ +#define __FIRESAT__CMP_H_ + +#include "firesat.h" + +extern int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, int iso_channel); +extern int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug,int iso_channel); + +#endif diff --git a/drivers/media/dvb/firesat/firesat-ci.c b/drivers/media/dvb/firesat/firesat-ci.c new file mode 100644 index 00000000000..862d9553c5b --- /dev/null +++ b/drivers/media/dvb/firesat/firesat-ci.c @@ -0,0 +1,95 @@ +#include "firesat-ci.h" +#include "firesat.h" +#include "avc_api.h" + +#include +#include +/* +static int firesat_ca_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *parg) { + //struct firesat *firesat = (struct firesat*)((struct dvb_device*)file->private_data)->priv; + int err; + +// printk(KERN_INFO "%s: ioctl %d\n",__func__,cmd); + + switch(cmd) { + case CA_RESET: + // TODO: Needs to be implemented with new AVC Vendor commands + break; + case CA_GET_CAP: { + ca_caps_t *cap=(ca_caps_t*)parg; + cap->slot_num = 1; + cap->slot_type = CA_CI_LINK; + cap->descr_num = 1; + cap->descr_type = CA_DSS; + + err = 0; + break; + } + case CA_GET_SLOT_INFO: { + ca_slot_info_t *slot=(ca_slot_info_t*)parg; + if(slot->num == 0) { + slot->type = CA_CI | CA_CI_LINK | CA_DESCR; + slot->flags = CA_CI_MODULE_PRESENT | CA_CI_MODULE_READY; + } else { + slot->type = 0; + slot->flags = 0; + } + err = 0; + break; + } + default: + err=-EINVAL; + } + return err; +} +*/ + +static int firesat_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { + //return dvb_usercopy(inode, file, cmd, arg, firesat_ca_do_ioctl); + return dvb_generic_ioctl(inode, file, cmd, arg); +} + +static int firesat_ca_io_open(struct inode *inode, struct file *file) { + printk(KERN_INFO "%s!\n",__func__); + return dvb_generic_open(inode, file); +} + +static int firesat_ca_io_release(struct inode *inode, struct file *file) { + printk(KERN_INFO "%s!\n",__func__); + return dvb_generic_release(inode, file); +} + +static unsigned int firesat_ca_io_poll(struct file *file, poll_table *wait) { +// printk(KERN_INFO "%s!\n",__func__); + return POLLIN; +} + +static struct file_operations firesat_ca_fops = { + .owner = THIS_MODULE, + .read = NULL, // There is no low level read anymore + .write = NULL, // There is no low level write anymore + .ioctl = firesat_ca_ioctl, + .open = firesat_ca_io_open, + .release = firesat_ca_io_release, + .poll = firesat_ca_io_poll, +}; + +static struct dvb_device firesat_ca = { + .priv = NULL, + .users = 1, + .readers = 1, + .writers = 1, + .fops = &firesat_ca_fops, +}; + +int firesat_ca_init(struct firesat *firesat) { + int ret = dvb_register_device(firesat->adapter, &firesat->cadev, &firesat_ca, firesat, DVB_DEVICE_CA); + if(ret) return ret; + + // avoid unnecessary delays, we're not talking to the CI yet anyways + return 0; +} + +void firesat_ca_release(struct firesat *firesat) { + dvb_unregister_device(firesat->cadev); +} diff --git a/drivers/media/dvb/firesat/firesat-ci.h b/drivers/media/dvb/firesat/firesat-ci.h new file mode 100644 index 00000000000..dafe3f0f0cc --- /dev/null +++ b/drivers/media/dvb/firesat/firesat-ci.h @@ -0,0 +1,9 @@ +#ifndef __FIRESAT_CA_H +#define __FIRESAT_CA_H + +#include "firesat.h" + +int firesat_ca_init(struct firesat *firesat); +void firesat_ca_release(struct firesat *firesat); + +#endif diff --git a/drivers/media/dvb/firesat/firesat-rc.c b/drivers/media/dvb/firesat/firesat-rc.c new file mode 100644 index 00000000000..e300b81008a --- /dev/null +++ b/drivers/media/dvb/firesat/firesat-rc.c @@ -0,0 +1,84 @@ +#include "firesat.h" +#include "firesat-rc.h" + +#include + +static u16 firesat_irtable[] = { + KEY_ESC, + KEY_F9, + KEY_1, + KEY_2, + KEY_3, + KEY_4, + KEY_5, + KEY_6, + KEY_7, + KEY_8, + KEY_9, + KEY_I, + KEY_0, + KEY_ENTER, + KEY_RED, + KEY_UP, + KEY_GREEN, + KEY_F10, + KEY_SPACE, + KEY_F11, + KEY_YELLOW, + KEY_DOWN, + KEY_BLUE, + KEY_Z, + KEY_P, + KEY_PAGEDOWN, + KEY_LEFT, + KEY_W, + KEY_RIGHT, + KEY_P, + KEY_M, + KEY_R, + KEY_V, + KEY_C, + 0 +}; + +static struct input_dev firesat_idev; + +int firesat_register_rc(void) +{ + int index; + + memset(&firesat_idev, 0, sizeof(firesat_idev)); + + firesat_idev.evbit[0] = BIT(EV_KEY); + + for (index = 0; firesat_irtable[index] != 0; index++) + set_bit(firesat_irtable[index], firesat_idev.keybit); + + return input_register_device(&firesat_idev); +} + +int firesat_unregister_rc(void) +{ + input_unregister_device(&firesat_idev); + return 0; +} + +int firesat_got_remotecontrolcode(u16 code) +{ + u16 keycode; + + if (code > 0x4500 && code < 0x4520) + keycode = firesat_irtable[code - 0x4501]; + else if (code > 0x453f && code < 0x4543) + keycode = firesat_irtable[code - 0x4521]; + else { + printk(KERN_DEBUG "%s: invalid key code 0x%04x\n", __func__, + code); + return -EINVAL; + } + + input_report_key(&firesat_idev, keycode, 1); + input_report_key(&firesat_idev, keycode, 0); + + return 0; +} diff --git a/drivers/media/dvb/firesat/firesat-rc.h b/drivers/media/dvb/firesat/firesat-rc.h new file mode 100644 index 00000000000..e89a8069ba8 --- /dev/null +++ b/drivers/media/dvb/firesat/firesat-rc.h @@ -0,0 +1,9 @@ +#ifndef __FIRESAT_LIRC_H +#define __FIRESAT_LIRC_H + +extern int firesat_register_rc(void); +extern int firesat_unregister_rc(void); +extern int firesat_got_remotecontrolcode(u16 code); + +#endif + diff --git a/drivers/media/dvb/firesat/firesat.h b/drivers/media/dvb/firesat/firesat.h new file mode 100644 index 00000000000..f852a1ac774 --- /dev/null +++ b/drivers/media/dvb/firesat/firesat.h @@ -0,0 +1,85 @@ +#ifndef __FIRESAT_H +#define __FIRESAT_H + +#include "dvb_frontend.h" +#include "dmxdev.h" +#include "dvb_demux.h" +#include "dvb_net.h" + +#include +#include +#include + +enum model_type { + FireSAT_DVB_S = 1, + FireSAT_DVB_C = 2, + FireSAT_DVB_T = 3 +}; + +struct firesat { + struct dvb_demux dvb_demux; + char *model_name; + + /* DVB bits */ + struct dvb_adapter *adapter; + struct dmxdev dmxdev; + struct dvb_demux demux; + struct dmx_frontend frontend; + struct dvb_net dvbnet; + struct dvb_frontend_info *frontend_info; + struct dvb_frontend *fe; + + struct dvb_device *cadev; + int has_ci; + + struct semaphore avc_sem; + atomic_t avc_reply_received; + + atomic_t reschedule_remotecontrol; + + struct firesat_channel { + struct firesat *firesat; + struct dvb_demux_feed *dvbdmxfeed; + + int active; + int id; + int pid; + int type; /* 1 - TS, 2 - Filter */ + } channel[16]; + struct semaphore demux_sem; + + /* needed by avc_api */ + void *respfrm; + int resp_length; + +// nodeid_t nodeid; + struct hpsb_host *host; + u64 guid; /* GUID of this node */ + u32 guid_vendor_id; /* Top 24bits of guid */ + struct node_entry *nodeentry; + + enum model_type type; + char subunit; + fe_sec_voltage_t voltage; + fe_sec_tone_mode_t tone; + + int isochannel; + + struct list_head list; +}; + +extern struct list_head firesat_list; +extern spinlock_t firesat_list_lock; + +/* firesat_dvb.c */ +extern int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed); +extern int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed); +extern int firesat_dvbdev_init(struct firesat *firesat, + struct device *dev, + struct dvb_frontend *fe); + +/* firesat_fe.c */ +extern int firesat_frontend_attach(struct firesat *firesat, struct dvb_frontend *fe); + + +#endif diff --git a/drivers/media/dvb/firesat/firesat_1394.c b/drivers/media/dvb/firesat/firesat_1394.c new file mode 100644 index 00000000000..c7ccf633c24 --- /dev/null +++ b/drivers/media/dvb/firesat/firesat_1394.c @@ -0,0 +1,468 @@ +/* + * FireSAT DVB driver + * + * Copyright (c) 2004 Andreas Monitzer + * Copyright (c) 2007-2008 Ben Backx + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "firesat.h" +#include "avc_api.h" +#include "cmp.h" +#include "firesat-rc.h" +#include "firesat-ci.h" + +#define FIRESAT_Vendor_ID 0x001287 + +static struct ieee1394_device_id firesat_id_table[] = { + + { + /* FloppyDTV S/CI and FloppyDTV S2 */ + .match_flags = IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID, + .model_id = 0x000024, + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, + },{ + /* FloppyDTV T/CI */ + .match_flags = IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID, + .model_id = 0x000025, + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, + },{ + /* FloppyDTV C/CI */ + .match_flags = IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID, + .model_id = 0x000026, + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, + },{ + /* FireDTV S/CI and FloppyDTV S2 */ + .match_flags = IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID, + .model_id = 0x000034, + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, + },{ + /* FireDTV T/CI */ + .match_flags = IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID, + .model_id = 0x000035, + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, + },{ + /* FireDTV C/CI */ + .match_flags = IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID, + .model_id = 0x000036, + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, + }, { } +}; + +MODULE_DEVICE_TABLE(ieee1394, firesat_id_table); + +/* list of all firesat devices */ +LIST_HEAD(firesat_list); +spinlock_t firesat_list_lock = SPIN_LOCK_UNLOCKED; + +static void firesat_add_host(struct hpsb_host *host); +static void firesat_remove_host(struct hpsb_host *host); +static void firesat_host_reset(struct hpsb_host *host); + +/* +static void iso_receive(struct hpsb_host *host, int channel, quadlet_t *data, + size_t length); +*/ + +static void fcp_request(struct hpsb_host *host, + int nodeid, + int direction, + int cts, + u8 *data, + size_t length); + +static struct hpsb_highlevel firesat_highlevel = { + .name = "FireSAT", + .add_host = firesat_add_host, + .remove_host = firesat_remove_host, + .host_reset = firesat_host_reset, +// FIXME .iso_receive = iso_receive, + .fcp_request = fcp_request, +}; + +static void firesat_add_host (struct hpsb_host *host) +{ + struct ti_ohci *ohci = (struct ti_ohci *)host->hostdata; + + /* We only work with the OHCI-1394 driver */ + if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME)) + return; + + if (!hpsb_create_hostinfo(&firesat_highlevel, host, 0)) { + printk(KERN_ERR "Cannot allocate hostinfo\n"); + return; + } + + hpsb_set_hostinfo(&firesat_highlevel, host, ohci); + hpsb_set_hostinfo_key(&firesat_highlevel, host, ohci->host->id); +} + +static void firesat_remove_host (struct hpsb_host *host) +{ + +} + +static void firesat_host_reset(struct hpsb_host *host) +{ + printk(KERN_INFO "FireSAT host_reset (nodeid = 0x%x, hosts active = %d)\n",host->node_id,host->nodes_active); +} + +struct firewireheader { + union { + struct { + unsigned char tcode:4; + unsigned char sy:4; + unsigned char tag:2; + unsigned char channel:6; + + unsigned char length_l; + unsigned char length_h; + } hdr; + unsigned long val; + }; +}; + +struct CIPHeader { + union { + struct { + unsigned char syncbits:2; + unsigned char sid:6; + unsigned char dbs; + unsigned char fn:2; + unsigned char qpc:3; + unsigned char sph:1; + unsigned char rsv:2; + unsigned char dbc; + unsigned char syncbits2:2; + unsigned char fmt:6; + unsigned long fdf:24; + } cip; + unsigned long long val; + }; +}; + +struct MPEG2Header { + union { + struct { + unsigned char sync; // must be 0x47 + unsigned char transport_error_indicator:1; + unsigned char payload_unit_start_indicator:1; + unsigned char transport_priority:1; + unsigned short pid:13; + unsigned char transport_scrambling_control:2; + unsigned char adaption_field_control:2; + unsigned char continuity_counter:4; + } hdr; + unsigned long val; + }; +}; + +#if 0 +static void iso_receive(struct hpsb_host *host, + int channel, + quadlet_t *data, + size_t length) +{ + struct firesat *firesat = NULL; + struct firesat *firesat_entry; + unsigned long flags; + +// printk(KERN_INFO "FireSAT iso_receive: channel %d, length = %d\n", channel, length); + + if (length <= 12) + return; // ignore empty packets + else { + + spin_lock_irqsave(&firesat_list_lock, flags); + list_for_each_entry(firesat_entry,&firesat_list,list) { + if(firesat_entry->host == host && firesat_entry->isochannel == channel) { + firesat=firesat_entry; + break; + } + } + spin_unlock_irqrestore(&firesat_list_lock, flags); + + if (firesat) { + char *buf= ((char*)data) + sizeof(struct firewireheader)+sizeof(struct CIPHeader); + int count = (length-sizeof(struct CIPHeader)) / 192; + +// printk(KERN_INFO "%s: length = %u\n data[0] = %08x\n data[1] = %08x\n data[2] = %08x\n data[3] = %08x\n data[4] = %08x\n",__func__, length, data[0],data[1],data[2],data[3],data[4]); + + while (count--) { + + if (buf[sizeof(quadlet_t) /*timestamp*/] == 0x47) + dvb_dmx_swfilter_packets(&firesat->demux, &buf[sizeof(quadlet_t)], 1); + else + printk("%s: invalid packet, skipping\n", __func__); + buf += 188 + sizeof (quadlet_t) /* timestamp */; + } + } + } +} +#endif + +static void fcp_request(struct hpsb_host *host, + int nodeid, + int direction, + int cts, + u8 *data, + size_t length) +{ + struct firesat *firesat = NULL; + struct firesat *firesat_entry; + unsigned long flags; + + if (length > 0 && ((data[0] & 0xf0) >> 4) == 0) { + + spin_lock_irqsave(&firesat_list_lock, flags); + list_for_each_entry(firesat_entry,&firesat_list,list) { + if (firesat_entry->host == host && + firesat_entry->nodeentry->nodeid == nodeid && + (firesat_entry->subunit == (data[1]&0x7) || + (firesat_entry->subunit == 0 && + (data[1]&0x7) == 0x7))) { + firesat=firesat_entry; + break; + } + } + spin_unlock_irqrestore(&firesat_list_lock, flags); + + if (firesat) + AVCRecv(firesat,data,length); + else + printk("%s: received fcp request from unknown source, ignored\n", __func__); + } // else ignore +} + +static int firesat_probe(struct device *dev) +{ + struct unit_directory *ud = container_of(dev, struct unit_directory, device); + struct firesat *firesat; + struct dvb_frontend *fe; + unsigned long flags; + int result; + unsigned char subunitcount = 0xff, subunit; + struct firesat **firesats = kmalloc(sizeof (void*) * 2,GFP_KERNEL); + + if (!firesats) { + printk("%s: couldn't allocate memory.\n", __func__); + return -ENOMEM; + } + +// printk(KERN_INFO "FireSAT: Detected device with GUID %08lx%04lx%04lx\n",(unsigned long)((ud->ne->guid)>>32),(unsigned long)(ud->ne->guid & 0xFFFF),(unsigned long)ud->ne->guid_vendor_id); + printk(KERN_INFO "%s: loading device\n", __func__); + + firesats[0] = NULL; + firesats[1] = NULL; + + ud->device.driver_data = firesats; + + for (subunit = 0; subunit < subunitcount; subunit++) { + + if (!(firesat = kmalloc(sizeof (struct firesat), GFP_KERNEL)) || + !(fe = kmalloc(sizeof (struct dvb_frontend), GFP_KERNEL))) { + + printk("%s: couldn't allocate memory.\n", __func__); + kfree(firesats); + return -ENOMEM; + } + + memset(firesat, 0, sizeof (struct firesat)); + + firesat->host = ud->ne->host; + firesat->guid = ud->ne->guid; + firesat->guid_vendor_id = ud->ne->guid_vendor_id; + firesat->nodeentry = ud->ne; + firesat->isochannel = -1; + firesat->tone = 0xff; + firesat->voltage = 0xff; + + if (!(firesat->respfrm = kmalloc(sizeof (AVCRspFrm), GFP_KERNEL))) { + printk("%s: couldn't allocate memory.\n", __func__); + kfree(firesat); + return -ENOMEM; + } + + sema_init(&firesat->avc_sem, 1); + atomic_set(&firesat->avc_reply_received, 1); + sema_init(&firesat->demux_sem, 1); + atomic_set(&firesat->reschedule_remotecontrol, 0); + + spin_lock_irqsave(&firesat_list_lock, flags); + INIT_LIST_HEAD(&firesat->list); + list_add_tail(&firesat->list, &firesat_list); + spin_unlock_irqrestore(&firesat_list_lock, flags); + + if (subunit == 0) { + firesat->subunit = 0x7; // 0x7 = don't care + if (AVCSubUnitInfo(firesat, &subunitcount)) { + printk("%s: AVC subunit info command failed.\n",__func__); + spin_lock_irqsave(&firesat_list_lock, flags); + list_del(&firesat->list); + spin_unlock_irqrestore(&firesat_list_lock, flags); + kfree(firesat); + return -EIO; + } + } + + printk(KERN_INFO "%s: subunit count = %d\n", __func__, subunitcount); + + firesat->subunit = subunit; + + if (AVCIdentifySubunit(firesat, NULL, (int*)&firesat->type, &firesat->has_ci)) { + printk("%s: cannot identify subunit %d\n", __func__, subunit); + spin_lock_irqsave(&firesat_list_lock, flags); + list_del(&firesat->list); + spin_unlock_irqrestore(&firesat_list_lock, flags); + kfree(firesat); + continue; + } + +// ---- + firesat_dvbdev_init(firesat, dev, fe); +// ---- + firesats[subunit] = firesat; + } // loop for all tuners + + //beta ;-) Disable remote control stuff to avoid crashing + //if(firesats[0]) + // AVCRegisterRemoteControl(firesats[0]); + + return 0; +} + +static int firesat_remove(struct device *dev) +{ + struct unit_directory *ud = container_of(dev, struct unit_directory, device); + struct dvb_frontend* fe; + struct firesat **firesats = ud->device.driver_data; + int k; + unsigned long flags; + + if (firesats) { + for (k = 0; k < 2; k++) + if (firesats[k]) { + if (firesats[k]->has_ci) + firesat_ca_release(firesats[k]); + +#if 0 + if (!(fe = kmalloc(sizeof (struct dvb_frontend), GFP_KERNEL))) { + fe->ops = firesat_ops; + fe->dvb = firesats[k]->adapter; + + dvb_unregister_frontend(fe); + kfree(fe); + } +#endif + dvb_net_release(&firesats[k]->dvbnet); + firesats[k]->demux.dmx.close(&firesats[k]->demux.dmx); + firesats[k]->demux.dmx.remove_frontend(&firesats[k]->demux.dmx, &firesats[k]->frontend); + dvb_dmxdev_release(&firesats[k]->dmxdev); + dvb_dmx_release(&firesats[k]->demux); + dvb_unregister_adapter(firesats[k]->adapter); + + spin_lock_irqsave(&firesat_list_lock, flags); + list_del(&firesats[k]->list); + spin_unlock_irqrestore(&firesat_list_lock, flags); + + kfree(firesats[k]->adapter); + kfree(firesats[k]->respfrm); + kfree(firesats[k]); + } + kfree(firesats); + } else + printk("%s: can't get firesat handle\n", __func__); + + printk(KERN_INFO "FireSAT: Removing device with vendor id 0x%x, model id 0x%x.\n",ud->vendor_id,ud->model_id); + + return 0; +} + +static int firesat_update(struct unit_directory *ud) +{ + struct firesat **firesats = ud->device.driver_data; + int k; + // loop over subunits + + for (k = 0; k < 2; k++) + if (firesats[k]) { + firesats[k]->nodeentry = ud->ne; + + if (firesats[k]->isochannel >= 0) + try_CMPEstablishPPconnection(firesats[k], firesats[k]->subunit, firesats[k]->isochannel); + } + + return 0; +} + +static struct hpsb_protocol_driver firesat_driver = { + + .name = "FireSAT", + .id_table = firesat_id_table, + .update = firesat_update, + + .driver = { + //.name and .bus are filled in for us in more recent linux versions + //.name = "FireSAT", + //.bus = &ieee1394_bus_type, + .probe = firesat_probe, + .remove = firesat_remove, + }, +}; + +static int __init firesat_init(void) +{ + int ret; + + printk(KERN_INFO "FireSAT loaded\n"); + hpsb_register_highlevel(&firesat_highlevel); + ret = hpsb_register_protocol(&firesat_driver); + if (ret) { + printk(KERN_ERR "FireSAT: failed to register protocol\n"); + hpsb_unregister_highlevel(&firesat_highlevel); + return ret; + } + + //Crash in this function, just disable RC for the time being... + //Don't forget to uncomment in firesat_exit and firesat_probe when you enable this. + /*if((ret=firesat_register_rc())) + printk("%s: firesat_register_rc return error code %d (ignored)\n", __func__, ret);*/ + + return 0; +} + +static void __exit firesat_exit(void) +{ + hpsb_unregister_protocol(&firesat_driver); + hpsb_unregister_highlevel(&firesat_highlevel); + printk(KERN_INFO "FireSAT quit\n"); +} + +module_init(firesat_init); +module_exit(firesat_exit); + +MODULE_AUTHOR("Andreas Monitzer "); +MODULE_AUTHOR("Ben Backx "); +MODULE_DESCRIPTION("FireSAT DVB Driver"); +MODULE_LICENSE("GPL"); +MODULE_SUPPORTED_DEVICE("FireSAT DVB"); diff --git a/drivers/media/dvb/firesat/firesat_dvb.c b/drivers/media/dvb/firesat/firesat_dvb.c new file mode 100644 index 00000000000..38aad081288 --- /dev/null +++ b/drivers/media/dvb/firesat/firesat_dvb.c @@ -0,0 +1,350 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "firesat.h" +#include "avc_api.h" +#include "cmp.h" +#include "firesat-rc.h" +#include "firesat-ci.h" + +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + +static struct firesat_channel *firesat_channel_allocate(struct firesat *firesat) +{ + int k; + + printk(KERN_INFO "%s\n", __func__); + + if (down_interruptible(&firesat->demux_sem)) + return NULL; + + for (k = 0; k < 16; k++) { + printk(KERN_INFO "%s: channel %d: active = %d, pid = 0x%x\n",__func__,k,firesat->channel[k].active,firesat->channel[k].pid); + + if (firesat->channel[k].active == 0) { + firesat->channel[k].active = 1; + up(&firesat->demux_sem); + return &firesat->channel[k]; + } + } + + up(&firesat->demux_sem); + return NULL; // no more channels available +} + +static int firesat_channel_collect(struct firesat *firesat, int *pidc, u16 pid[]) +{ + int k, l = 0; + + if (down_interruptible(&firesat->demux_sem)) + return -EINTR; + + for (k = 0; k < 16; k++) + if (firesat->channel[k].active == 1) + pid[l++] = firesat->channel[k].pid; + + up(&firesat->demux_sem); + + *pidc = l; + + return 0; +} + +static int firesat_channel_release(struct firesat *firesat, + struct firesat_channel *channel) +{ + if (down_interruptible(&firesat->demux_sem)) + return -EINTR; + + channel->active = 0; + + up(&firesat->demux_sem); + return 0; +} + +int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed) +{ + struct firesat *firesat = (struct firesat*)dvbdmxfeed->demux->priv; + struct firesat_channel *channel; + int pidc,k; + u16 pids[16]; + + printk(KERN_INFO "%s (pid %u)\n",__func__,dvbdmxfeed->pid); + + switch (dvbdmxfeed->type) { + case DMX_TYPE_TS: + case DMX_TYPE_SEC: + break; + default: + printk("%s: invalid type %u\n",__func__,dvbdmxfeed->type); + return -EINVAL; + } + + if (dvbdmxfeed->type == DMX_TYPE_TS) { + switch (dvbdmxfeed->pes_type) { + case DMX_TS_PES_VIDEO: + case DMX_TS_PES_AUDIO: + case DMX_TS_PES_TELETEXT: + case DMX_TS_PES_PCR: + case DMX_TS_PES_OTHER: + //Dirty fix to keep firesat->channel pid-list up to date + for(k=0;k<16;k++){ + if(firesat->channel[k].active == 0) + firesat->channel[k].pid = + dvbdmxfeed->pid; + break; + } + channel = firesat_channel_allocate(firesat); + break; + default: + printk("%s: invalid pes type %u\n",__func__, dvbdmxfeed->pes_type); + return -EINVAL; + } + } else { + channel = firesat_channel_allocate(firesat); + } + + if (!channel) { + printk("%s: busy!\n", __func__); + return -EBUSY; + } + + dvbdmxfeed->priv = channel; + + channel->dvbdmxfeed = dvbdmxfeed; + channel->pid = dvbdmxfeed->pid; + channel->type = dvbdmxfeed->type; + channel->firesat = firesat; + + if (firesat_channel_collect(firesat, &pidc, pids)) { + firesat_channel_release(firesat, channel); + return -EINTR; + } + + if(dvbdmxfeed->pid == 8192) { + if((k=AVCTuner_GetTS(firesat))) { + firesat_channel_release(firesat, channel); + printk("%s: AVCTuner_GetTS failed with error %d\n", + __func__,k); + return k; + } + } + else { + if((k=AVCTuner_SetPIDs(firesat, pidc, pids))) { + firesat_channel_release(firesat, channel); + printk("%s: AVCTuner_SetPIDs failed with error %d\n", + __func__,k); + return k; + } + } + + return 0; +} + +int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed) +{ + struct dvb_demux *demux = dvbdmxfeed->demux; + struct firesat *firesat = (struct firesat*)demux->priv; + int k, l = 0; + u16 pids[16]; + + printk(KERN_INFO "%s (pid %u)\n", __func__, dvbdmxfeed->pid); + + if (dvbdmxfeed->type == DMX_TYPE_TS && !((dvbdmxfeed->ts_type & TS_PACKET) && + (demux->dmx.frontend->source != DMX_MEMORY_FE))) { + + if (dvbdmxfeed->ts_type & TS_DECODER) { + + if (dvbdmxfeed->pes_type >= DMX_TS_PES_OTHER || + !demux->pesfilter[dvbdmxfeed->pes_type]) + + return -EINVAL; + + demux->pids[dvbdmxfeed->pes_type] |= 0x8000; + demux->pesfilter[dvbdmxfeed->pes_type] = 0; + } + + if (!(dvbdmxfeed->ts_type & TS_DECODER && + dvbdmxfeed->pes_type < DMX_TS_PES_OTHER)) + + return 0; + } + + if (down_interruptible(&firesat->demux_sem)) + return -EINTR; + + + // list except channel to be removed + for (k = 0; k < 16; k++) + if (firesat->channel[k].active == 1) + if (&firesat->channel[k] != + (struct firesat_channel *)dvbdmxfeed->priv) + pids[l++] = firesat->channel[k].pid; + else + firesat->channel[k].active = 0; + + if ((k = AVCTuner_SetPIDs(firesat, l, pids))) { + up(&firesat->demux_sem); + return k; + } + + ((struct firesat_channel *)dvbdmxfeed->priv)->active = 0; + + up(&firesat->demux_sem); + + return 0; +} + +int firesat_dvbdev_init(struct firesat *firesat, + struct device *dev, + struct dvb_frontend *fe) +{ + int result; + + firesat->has_ci = 1; // TEMP workaround + +#if 0 + switch (firesat->type) { + case FireSAT_DVB_S: + firesat->model_name = "FireSAT DVB-S"; + firesat->frontend_info = &firesat_S_frontend_info; + break; + case FireSAT_DVB_C: + firesat->model_name = "FireSAT DVB-C"; + firesat->frontend_info = &firesat_C_frontend_info; + break; + case FireSAT_DVB_T: + firesat->model_name = "FireSAT DVB-T"; + firesat->frontend_info = &firesat_T_frontend_info; + break; + default: + printk("%s: unknown model type 0x%x on subunit %d!\n", + __func__, firesat->type,subunit); + firesat->model_name = "Unknown"; + firesat->frontend_info = NULL; + } +#endif +/* // ------- CRAP ----------- + if (!firesat->frontend_info) { + spin_lock_irqsave(&firesat_list_lock, flags); + list_del(&firesat->list); + spin_unlock_irqrestore(&firesat_list_lock, flags); + kfree(firesat); + continue; + } +*/ + //initialising firesat->adapter before calling dvb_register_adapter + if (!(firesat->adapter = kmalloc(sizeof (struct dvb_adapter), GFP_KERNEL))) { + printk("%s: couldn't allocate memory.\n", __func__); + kfree(firesat->adapter); + kfree(firesat); + return -ENOMEM; + } + + if ((result = dvb_register_adapter(firesat->adapter, + firesat->model_name, + THIS_MODULE, + dev, adapter_nr)) < 0) { + + printk("%s: dvb_register_adapter failed: error %d\n", __func__, result); +#if 0 + /* ### cleanup */ + spin_lock_irqsave(&firesat_list_lock, flags); + list_del(&firesat->list); + spin_unlock_irqrestore(&firesat_list_lock, flags); +#endif + kfree(firesat); + + return result; + } + + firesat->demux.dmx.capabilities = 0/*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/; + + firesat->demux.priv = (void *)firesat; + firesat->demux.filternum = 16; + firesat->demux.feednum = 16; + firesat->demux.start_feed = firesat_start_feed; + firesat->demux.stop_feed = firesat_stop_feed; + firesat->demux.write_to_decoder = NULL; + + if ((result = dvb_dmx_init(&firesat->demux)) < 0) { + printk("%s: dvb_dmx_init failed: error %d\n", __func__, + result); + + dvb_unregister_adapter(firesat->adapter); + + return result; + } + + firesat->dmxdev.filternum = 16; + firesat->dmxdev.demux = &firesat->demux.dmx; + firesat->dmxdev.capabilities = 0; + + if ((result = dvb_dmxdev_init(&firesat->dmxdev, firesat->adapter)) < 0) { + printk("%s: dvb_dmxdev_init failed: error %d\n", + __func__, result); + + dvb_dmx_release(&firesat->demux); + dvb_unregister_adapter(firesat->adapter); + + return result; + } + + firesat->frontend.source = DMX_FRONTEND_0; + + if ((result = firesat->demux.dmx.add_frontend(&firesat->demux.dmx, + &firesat->frontend)) < 0) { + printk("%s: dvb_dmx_init failed: error %d\n", __func__, + result); + + dvb_dmxdev_release(&firesat->dmxdev); + dvb_dmx_release(&firesat->demux); + dvb_unregister_adapter(firesat->adapter); + + return result; + } + + if ((result = firesat->demux.dmx.connect_frontend(&firesat->demux.dmx, + &firesat->frontend)) < 0) { + printk("%s: dvb_dmx_init failed: error %d\n", __func__, + result); + + firesat->demux.dmx.remove_frontend(&firesat->demux.dmx, &firesat->frontend); + dvb_dmxdev_release(&firesat->dmxdev); + dvb_dmx_release(&firesat->demux); + dvb_unregister_adapter(firesat->adapter); + + return result; + } + + dvb_net_init(firesat->adapter, &firesat->dvbnet, &firesat->demux.dmx); + +// fe->ops = firesat_ops; +// fe->dvb = firesat->adapter; + firesat_frontend_attach(firesat, fe); + + fe->sec_priv = firesat; //IMPORTANT, functions depend on this!!! + if ((result= dvb_register_frontend(firesat->adapter, fe)) < 0) { + printk("%s: dvb_register_frontend_new failed: error %d\n", __func__, result); + /* ### cleanup */ + return result; + } + + if (firesat->has_ci) + firesat_ca_init(firesat); + + return 0; +} diff --git a/drivers/media/dvb/firesat/firesat_fe.c b/drivers/media/dvb/firesat/firesat_fe.c new file mode 100644 index 00000000000..f7abd38f001 --- /dev/null +++ b/drivers/media/dvb/firesat/firesat_fe.c @@ -0,0 +1,263 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "firesat.h" +#include "avc_api.h" +#include "cmp.h" +#include "firesat-rc.h" +#include "firesat-ci.h" + +static int firesat_dvb_init(struct dvb_frontend *fe) +{ + struct firesat *firesat = fe->sec_priv; + printk("fdi: 1\n"); + firesat->isochannel = firesat->adapter->num; //<< 1 | (firesat->subunit & 0x1); // ### ask IRM + printk("fdi: 2\n"); + try_CMPEstablishPPconnection(firesat, firesat->subunit, firesat->isochannel); + printk("fdi: 3\n"); +//FIXME hpsb_listen_channel(&firesat_highlevel, firesat->host, firesat->isochannel); + printk("fdi: 4\n"); + return 0; +} + +static int firesat_sleep(struct dvb_frontend *fe) +{ + struct firesat *firesat = fe->sec_priv; + +//FIXME hpsb_unlisten_channel(&firesat_highlevel, firesat->host, firesat->isochannel); + try_CMPBreakPPconnection(firesat, firesat->subunit, firesat->isochannel); + firesat->isochannel = -1; + return 0; +} + +static int firesat_diseqc_send_master_cmd(struct dvb_frontend *fe, + struct dvb_diseqc_master_cmd *cmd) +{ + struct firesat *firesat = fe->sec_priv; + + return AVCLNBControl(firesat, LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, + LNBCONTROL_DONTCARE, 1, cmd); +} + +static int firesat_diseqc_send_burst(struct dvb_frontend *fe, + fe_sec_mini_cmd_t minicmd) +{ + return 0; +} + +static int firesat_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) +{ + struct firesat *firesat = fe->sec_priv; + + firesat->tone = tone; + return 0; +} + +static int firesat_set_voltage(struct dvb_frontend *fe, + fe_sec_voltage_t voltage) +{ + struct firesat *firesat = fe->sec_priv; + + firesat->voltage = voltage; + return 0; +} + +static int firesat_read_status (struct dvb_frontend *fe, fe_status_t *status) +{ + struct firesat *firesat = fe->sec_priv; + ANTENNA_INPUT_INFO info; + + if (AVCTunerStatus(firesat, &info)) + return -EINVAL; + + if (info.NoRF) + *status = 0; + else + *status = *status = FE_HAS_SIGNAL | + FE_HAS_VITERBI | + FE_HAS_SYNC | + FE_HAS_CARRIER | + FE_HAS_LOCK; + + return 0; +} + +static int firesat_read_ber (struct dvb_frontend *fe, u32 *ber) +{ + struct firesat *firesat = fe->sec_priv; + ANTENNA_INPUT_INFO info; + + if (AVCTunerStatus(firesat, &info)) + return -EINVAL; + + *ber = ((info.BER[0] << 24) & 0xff) | + ((info.BER[1] << 16) & 0xff) | + ((info.BER[2] << 8) & 0xff) | + (info.BER[3] & 0xff); + + return 0; +} + +static int firesat_read_signal_strength (struct dvb_frontend *fe, u16 *strength) +{ + struct firesat *firesat = fe->sec_priv; + ANTENNA_INPUT_INFO info; + u16 *signal = strength; + + if (AVCTunerStatus(firesat, &info)) + return -EINVAL; + + *signal = info.SignalStrength; + + return 0; +} + +static int firesat_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + return -EOPNOTSUPP; +} + +static int firesat_read_uncorrected_blocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + return -EOPNOTSUPP; +} + +static int firesat_set_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) +{ + struct firesat *firesat = fe->sec_priv; + + if (AVCTuner_DSD(firesat, params, NULL) != ACCEPTED) + return -EINVAL; + else + return 0; //not sure of this... +} + +static int firesat_get_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) +{ + return -EOPNOTSUPP; +} + +static struct dvb_frontend_info firesat_S_frontend_info; +static struct dvb_frontend_info firesat_C_frontend_info; +static struct dvb_frontend_info firesat_T_frontend_info; + +static struct dvb_frontend_ops firesat_ops = { + + .init = firesat_dvb_init, + .sleep = firesat_sleep, + + .set_frontend = firesat_set_frontend, + .get_frontend = firesat_get_frontend, + + .read_status = firesat_read_status, + .read_ber = firesat_read_ber, + .read_signal_strength = firesat_read_signal_strength, + .read_snr = firesat_read_snr, + .read_ucblocks = firesat_read_uncorrected_blocks, + + .diseqc_send_master_cmd = firesat_diseqc_send_master_cmd, + .diseqc_send_burst = firesat_diseqc_send_burst, + .set_tone = firesat_set_tone, + .set_voltage = firesat_set_voltage, +}; + +int firesat_frontend_attach(struct firesat *firesat, struct dvb_frontend *fe) +{ + switch (firesat->type) { + case FireSAT_DVB_S: + firesat->model_name = "FireSAT DVB-S"; + firesat->frontend_info = &firesat_S_frontend_info; + break; + case FireSAT_DVB_C: + firesat->model_name = "FireSAT DVB-C"; + firesat->frontend_info = &firesat_C_frontend_info; + break; + case FireSAT_DVB_T: + firesat->model_name = "FireSAT DVB-T"; + firesat->frontend_info = &firesat_T_frontend_info; + break; + default: +// printk("%s: unknown model type 0x%x on subunit %d!\n", +// __func__, firesat->type,subunit); + printk("%s: unknown model type 0x%x !\n", + __func__, firesat->type); + firesat->model_name = "Unknown"; + firesat->frontend_info = NULL; + } + fe->ops = firesat_ops; + fe->dvb = firesat->adapter; + + return 0; +} + +static struct dvb_frontend_info firesat_S_frontend_info = { + + .name = "FireSAT DVB-S Frontend", + .type = FE_QPSK, + + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_stepsize = 125, + .symbol_rate_min = 1000000, + .symbol_rate_max = 40000000, + + .caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_1_2 | + FE_CAN_FEC_2_3 | + FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | + FE_CAN_FEC_7_8 | + FE_CAN_FEC_AUTO | + FE_CAN_QPSK, +}; + +static struct dvb_frontend_info firesat_C_frontend_info = { + + .name = "FireSAT DVB-C Frontend", + .type = FE_QAM, + + .frequency_min = 47000000, + .frequency_max = 866000000, + .frequency_stepsize = 62500, + .symbol_rate_min = 870000, + .symbol_rate_max = 6900000, + + .caps = FE_CAN_INVERSION_AUTO | + FE_CAN_QAM_16 | + FE_CAN_QAM_32 | + FE_CAN_QAM_64 | + FE_CAN_QAM_128 | + FE_CAN_QAM_256 | + FE_CAN_QAM_AUTO, +}; + +static struct dvb_frontend_info firesat_T_frontend_info = { + + .name = "FireSAT DVB-T Frontend", + .type = FE_OFDM, + + .frequency_min = 49000000, + .frequency_max = 861000000, + .frequency_stepsize = 62500, + + .caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_2_3 | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_HIERARCHY_AUTO, +}; -- cgit From f1bbb43a667067f24a729df78dc050348b1c7846 Mon Sep 17 00:00:00 2001 From: Ben Backx Date: Sun, 22 Jun 2008 16:00:53 +0200 Subject: firesat: fix DVB-S2 device recognition This only makes sure that a DVB-S2 device is really recognized as a S2, nothing else is added yet. It's using the string containing the model that is stored in the configuration ROM, the older version was using some hardware revision dependent part of the ROM. Signed-off-by: Ben Backx Signed-off-by: Stefan Richter --- drivers/media/dvb/firesat/avc_api.c | 17 +---------------- drivers/media/dvb/firesat/firesat.h | 3 ++- drivers/media/dvb/firesat/firesat_1394.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/drivers/media/dvb/firesat/avc_api.c b/drivers/media/dvb/firesat/avc_api.c index d70795623fb..0ad6420e342 100644 --- a/drivers/media/dvb/firesat/avc_api.c +++ b/drivers/media/dvb/firesat/avc_api.c @@ -251,7 +251,7 @@ int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params // printk(KERN_INFO "%s\n", __func__); - if(firesat->type == FireSAT_DVB_S) + if (firesat->type == FireSAT_DVB_S || firesat->type == FireSAT_DVB_S2) AVCTuner_tuneQPSK(firesat, params, &CmdFrm); else { if(firesat->type == FireSAT_DVB_T) { @@ -654,21 +654,6 @@ int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *tr } if(systemId) *systemId = RspFrm.operand[7]; - if(transport) - *transport = RspFrm.operand[14] & 0x7; - switch(RspFrm.operand[14] & 0x7) { - case 1: - printk(KERN_INFO "%s: found DVB/S\n",__func__); - break; - case 2: - printk(KERN_INFO "%s: found DVB/C\n",__func__); - break; - case 3: - printk(KERN_INFO "%s: found DVB/T\n",__func__); - break; - default: - printk(KERN_INFO "%s: found unknown tuner id %u\n",__func__,RspFrm.operand[14] & 0x7); - } if(has_ci) *has_ci = (RspFrm.operand[14] >> 4) & 0x1; return 0; diff --git a/drivers/media/dvb/firesat/firesat.h b/drivers/media/dvb/firesat/firesat.h index f852a1ac774..d1e2ce37063 100644 --- a/drivers/media/dvb/firesat/firesat.h +++ b/drivers/media/dvb/firesat/firesat.h @@ -13,7 +13,8 @@ enum model_type { FireSAT_DVB_S = 1, FireSAT_DVB_C = 2, - FireSAT_DVB_T = 3 + FireSAT_DVB_T = 3, + FireSAT_DVB_S2 = 4 }; struct firesat { diff --git a/drivers/media/dvb/firesat/firesat_1394.c b/drivers/media/dvb/firesat/firesat_1394.c index c7ccf633c24..dcac70a2991 100644 --- a/drivers/media/dvb/firesat/firesat_1394.c +++ b/drivers/media/dvb/firesat/firesat_1394.c @@ -263,6 +263,8 @@ static int firesat_probe(struct device *dev) int result; unsigned char subunitcount = 0xff, subunit; struct firesat **firesats = kmalloc(sizeof (void*) * 2,GFP_KERNEL); + int kv_len; + char *kv_buf; if (!firesats) { printk("%s: couldn't allocate memory.\n", __func__); @@ -329,6 +331,32 @@ static int firesat_probe(struct device *dev) firesat->subunit = subunit; + /* Reading device model from ROM */ + kv_len = (ud->model_name_kv->value.leaf.len - 2) * + sizeof(quadlet_t); + kv_buf = kmalloc((sizeof(quadlet_t) * kv_len), GFP_KERNEL); + memcpy(kv_buf, + CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv), + kv_len); + while ((kv_buf + kv_len - 1) == '\0') kv_len--; + kv_buf[kv_len++] = '\0'; + + /* Determining the device model */ + if (strcmp(kv_buf, "FireDTV S/CI") == 0) { + printk(KERN_INFO "%s: found DVB/S\n", __func__); + firesat->type = 1; + } else if (strcmp(kv_buf, "FireDTV C/CI") == 0) { + printk(KERN_INFO "%s: found DVB/C\n", __func__); + firesat->type = 2; + } else if (strcmp(kv_buf, "FireDTV T/CI") == 0) { + printk(KERN_INFO "%s: found DVB/T\n", __func__); + firesat->type = 3; + } else if (strcmp(kv_buf, "FireDTV S2 ") == 0) { + printk(KERN_INFO "%s: found DVB/S2\n", __func__); + firesat->type = 4; + } + kfree(kv_buf); + if (AVCIdentifySubunit(firesat, NULL, (int*)&firesat->type, &firesat->has_ci)) { printk("%s: cannot identify subunit %d\n", __func__, subunit); spin_lock_irqsave(&firesat_list_lock, flags); -- cgit From 2c22861459f094e899c034515a9bb92ac307ceae Mon Sep 17 00:00:00 2001 From: Ben Backx Date: Sat, 9 Aug 2008 14:35:55 +0200 Subject: firesat: add DVB-S support for DVB-S2 devices ...so S2 owners now can at least watch DVB-S channels in linux. Signed-off-by: Ben Backx Signed-off-by: Stefan Richter --- drivers/media/dvb/firesat/avc_api.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/media/dvb/firesat/avc_api.c b/drivers/media/dvb/firesat/avc_api.c index 0ad6420e342..cd79c806ecc 100644 --- a/drivers/media/dvb/firesat/avc_api.c +++ b/drivers/media/dvb/firesat/avc_api.c @@ -240,6 +240,12 @@ static void AVCTuner_tuneQPSK(struct firesat *firesat, struct dvb_frontend_param else CmdFrm->operand[12] = (firesat->tone==SEC_TONE_ON)?1:0; // band + if (firesat->type == FireSAT_DVB_S2) { + CmdFrm->operand[13] = 0x1; + CmdFrm->operand[14] = 0xFF; + CmdFrm->operand[15] = 0xFF; + } + CmdFrm->length = 16; } -- cgit From df4846c35247a0d038c5359d502cddd59d04bc40 Mon Sep 17 00:00:00 2001 From: Henrik Kurelid Date: Fri, 1 Aug 2008 10:00:45 +0200 Subject: firesat: update isochronous interface, add CI support I have finally managed to get the CI support for the card working. The implementation is a bare minimum to get encrypted channels to work in kaffeine. It works fine with my T/CI card. Now and then I get an AVC timeout and have to retune a channel in order to get it to work. Once the CAM seemed to hang so I needed to remove and insert it again. I.e. there are a number of glitches. The latest version contains the following changes: - Implemented the new hpsb iso interface so that data can be received from the card - Reduced some timers for demux setup which caused scanning to timeout - Added possibility to unload driver - Added support for getting C/N ratio - Added two debug parameters to the driver; ca_debug and avc_comm_debug. - Added CI support that works for me in kaffeine - Started working on CI MMI support. It now supports: o Enter menu o Receiving MMI objects - Added support for 64-bit platforms - Corrected DVB-C modulations problems Signed-off-by: Henrik Kurelid Signed-off-by: Stefan Richter (rebased, whitespace) --- drivers/media/dvb/firesat/Makefile | 1 + drivers/media/dvb/firesat/avc_api.c | 770 +++++++++++++++++++++++++------ drivers/media/dvb/firesat/avc_api.h | 296 +++++++----- drivers/media/dvb/firesat/cmp.c | 40 +- drivers/media/dvb/firesat/firesat-ci.c | 342 ++++++++++++-- drivers/media/dvb/firesat/firesat.h | 174 ++++++- drivers/media/dvb/firesat/firesat_1394.c | 123 +---- drivers/media/dvb/firesat/firesat_dvb.c | 49 +- drivers/media/dvb/firesat/firesat_fe.c | 80 ++-- drivers/media/dvb/firesat/firesat_iso.c | 106 +++++ 10 files changed, 1487 insertions(+), 494 deletions(-) create mode 100644 drivers/media/dvb/firesat/firesat_iso.c diff --git a/drivers/media/dvb/firesat/Makefile b/drivers/media/dvb/firesat/Makefile index fdf86870f1f..be7701b817c 100644 --- a/drivers/media/dvb/firesat/Makefile +++ b/drivers/media/dvb/firesat/Makefile @@ -1,6 +1,7 @@ firesat-objs := firesat_1394.o \ firesat_dvb.o \ firesat_fe.o \ + firesat_iso.o \ avc_api.o \ cmp.o \ firesat-rc.o \ diff --git a/drivers/media/dvb/firesat/avc_api.c b/drivers/media/dvb/firesat/avc_api.c index cd79c806ecc..273c7235dd9 100644 --- a/drivers/media/dvb/firesat/avc_api.c +++ b/drivers/media/dvb/firesat/avc_api.c @@ -3,6 +3,7 @@ * * Copyright (c) 2004 Andreas Monitzer * Copyright (c) 2008 Ben Backx + * Copyright (c) 2008 Henrik Kurelid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -15,6 +16,7 @@ #include #include #include +#include #include "avc_api.h" #include "firesat-rc.h" @@ -22,6 +24,10 @@ #define COMMAND_REGISTER 0xFFFFF0000B00ULL #define PCR_BASE_ADDRESS 0xFFFFF0000900ULL +static unsigned int avc_comm_debug = 0; +module_param(avc_comm_debug, int, 0644); +MODULE_PARM_DESC(avc_comm_debug, "debug logging of AV/C communication, default is 0 (no)"); + static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal); /* Frees an allocated packet */ @@ -47,7 +53,124 @@ static int avc_down_timeout(atomic_t *done, int timeout) return ((i > 0) ? 0:1); } -static int __AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) { +static const char* get_ctype_string(__u8 ctype) +{ + switch(ctype) + { + case 0: + return "CONTROL"; + case 1: + return "STATUS"; + case 2: + return "SPECIFIC_INQUIRY"; + case 3: + return "NOTIFY"; + case 4: + return "GENERAL_INQUIRY"; + } + return "UNKNOWN"; +} + +static const char* get_resp_string(__u8 ctype) +{ + switch(ctype) + { + case 8: + return "NOT_IMPLEMENTED"; + case 9: + return "ACCEPTED"; + case 10: + return "REJECTED"; + case 11: + return "IN_TRANSITION"; + case 12: + return "IMPLEMENTED_STABLE"; + case 13: + return "CHANGED"; + case 15: + return "INTERIM"; + } + return "UNKNOWN"; +} + +static const char* get_subunit_address(__u8 subunit_id, __u8 subunit_type) +{ + if (subunit_id == 7 && subunit_type == 0x1F) + return "Unit"; + if (subunit_id == 0 && subunit_type == 0x05) + return "Tuner(0)"; + return "Unsupported"; +} + +static const char* get_opcode_string(__u8 opcode) +{ + switch(opcode) + { + case 0x02: + return "PlugInfo"; + case 0x08: + return "OpenDescriptor"; + case 0x09: + return "ReadDescriptor"; + case 0x18: + return "OutputPlugSignalFormat"; + case 0x31: + return "SubunitInfo"; + case 0x30: + return "UnitInfo"; + case 0xB2: + return "Power"; + case 0xC8: + return "DirectSelectInformationType"; + case 0xCB: + return "DirectSelectData"; + case 0x00: + return "Vendor"; + + } + return "Unknown"; +} + +static void log_command_frame(const AVCCmdFrm *CmdFrm) +{ + int k; + printk(KERN_INFO "AV/C Command Frame:\n"); + printk("CommandType=%s, Address=%s(0x%02X,0x%02X), opcode=%s(0x%02X), " + "length=%d\n", get_ctype_string(CmdFrm->ctype), + get_subunit_address(CmdFrm->suid, CmdFrm->sutyp), + CmdFrm->suid, CmdFrm->sutyp, get_opcode_string(CmdFrm->opcode), + CmdFrm->opcode, CmdFrm->length); + for(k = 0; k < CmdFrm->length - 3; k++) { + if (k % 5 != 0) + printk(", "); + else if (k != 0) + printk("\n"); + printk("operand[%d] = %02X", k, CmdFrm->operand[k]); + } + printk("\n"); +} + +static void log_response_frame(const AVCRspFrm *RspFrm) +{ + int k; + printk(KERN_INFO "AV/C Response Frame:\n"); + printk("Response=%s, Address=%s(0x%02X,0x%02X), opcode=%s(0x%02X), " + "length=%d\n", get_resp_string(RspFrm->resp), + get_subunit_address(RspFrm->suid, RspFrm->sutyp), + RspFrm->suid, RspFrm->sutyp, get_opcode_string(RspFrm->opcode), + RspFrm->opcode, RspFrm->length); + for(k = 0; k < RspFrm->length - 3; k++) { + if (k % 5 != 0) + printk(", "); + else if (k != 0) + printk("\n"); + printk("operand[%d] = %02X", k, RspFrm->operand[k]); + } + printk("\n"); +} + +static int __AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, + AVCRspFrm *RspFrm) { struct hpsb_packet *packet; struct node_entry *ne; @@ -58,39 +181,50 @@ static int __AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, AVCRspFr } /* need all input data */ - if(!firesat || !ne || !CmdFrm) + if(!firesat || !ne || !CmdFrm) { + printk("%s: missing input data!\n",__func__); return -EINVAL; + } -// printk(KERN_INFO "AVCWrite command %x\n",CmdFrm->opcode); - -// for(k=0;klength;k++) -// printk(KERN_INFO "CmdFrm[%d] = %08x\n", k, ((quadlet_t*)CmdFrm)[k]); - - packet=hpsb_make_writepacket(ne->host, ne->nodeid, COMMAND_REGISTER, - (quadlet_t*)CmdFrm, CmdFrm->length); - - hpsb_set_packet_complete_task(packet, (void (*)(void*))avc_free_packet, - packet); - - hpsb_node_fill_packet(ne, packet); + if (avc_comm_debug == 1) { + log_command_frame(CmdFrm); + } if(RspFrm) atomic_set(&firesat->avc_reply_received, 0); + packet=hpsb_make_writepacket(ne->host, ne->nodeid, + COMMAND_REGISTER, + (quadlet_t*)CmdFrm, + CmdFrm->length); + hpsb_set_packet_complete_task(packet, + (void (*)(void*))avc_free_packet, + packet); + hpsb_node_fill_packet(ne, packet); + if (hpsb_send_packet(packet) < 0) { avc_free_packet(packet); atomic_set(&firesat->avc_reply_received, 1); + printk("%s: send failed!\n",__func__); return -EIO; } if(RspFrm) { - if(avc_down_timeout(&firesat->avc_reply_received,HZ/2)) { - printk("%s: timeout waiting for avc response\n",__func__); + // AV/C specs say that answers should be send within + // 150 ms so let's time out after 200 ms + if(avc_down_timeout(&firesat->avc_reply_received, + HZ / 5)) { + printk("%s: timeout waiting for avc response\n", + __func__); atomic_set(&firesat->avc_reply_received, 1); - return -ETIMEDOUT; - } - - memcpy(RspFrm,firesat->respfrm,firesat->resp_length); + return -ETIMEDOUT; + } + memcpy(RspFrm, firesat->respfrm, + firesat->resp_length); + RspFrm->length = firesat->resp_length; + if (avc_comm_debug == 1) { + log_response_frame(RspFrm); + } } return 0; @@ -137,6 +271,7 @@ int AVCRecv(struct firesat *firesat, u8 *data, size_t length) { // remote control handling +#if 0 AVCRspFrm *RspFrm = (AVCRspFrm*)data; if(/*RspFrm->length >= 8 && ###*/ @@ -155,21 +290,21 @@ int AVCRecv(struct firesat *firesat, u8 *data, size_t length) { printk(KERN_INFO "%s: remote control result = %d\n",__func__, RspFrm->resp); return 0; } - +#endif if(atomic_read(&firesat->avc_reply_received) == 1) { printk("%s: received out-of-order AVC response, ignored\n",__func__); return -EINVAL; } // AVCRspFrm *resp=(AVCRspFrm *)data; // int k; -/* - printk(KERN_INFO "resp=0x%x\n",resp->resp); - printk(KERN_INFO "cts=0x%x\n",resp->cts); - printk(KERN_INFO "suid=0x%x\n",resp->suid); - printk(KERN_INFO "sutyp=0x%x\n",resp->sutyp); - printk(KERN_INFO "opcode=0x%x\n",resp->opcode); - printk(KERN_INFO "length=%d\n",resp->length); -*/ + +// printk(KERN_INFO "resp=0x%x\n",resp->resp); +// printk(KERN_INFO "cts=0x%x\n",resp->cts); +// printk(KERN_INFO "suid=0x%x\n",resp->suid); +// printk(KERN_INFO "sutyp=0x%x\n",resp->sutyp); +// printk(KERN_INFO "opcode=0x%x\n",resp->opcode); +// printk(KERN_INFO "length=%d\n",resp->length); + // for(k=0;k<2;k++) // printk(KERN_INFO "operand[%d]=%02x\n",k,resp->operand[k]); @@ -183,6 +318,7 @@ int AVCRecv(struct firesat *firesat, u8 *data, size_t length) { // tuning command for setting the relative LNB frequency (not supported by the AVC standard) static void AVCTuner_tuneQPSK(struct firesat *firesat, struct dvb_frontend_parameters *params, AVCCmdFrm *CmdFrm) { + memset(CmdFrm, 0, sizeof(AVCCmdFrm)); CmdFrm->cts = AVC; @@ -249,7 +385,7 @@ static void AVCTuner_tuneQPSK(struct firesat *firesat, struct dvb_frontend_param CmdFrm->length = 16; } -int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, BYTE *status) { +int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, __u8 *status) { AVCCmdFrm CmdFrm; AVCRspFrm RspFrm; M_VALID_FLAGS flags; @@ -274,21 +410,15 @@ int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params flags.Bits_T.TransmissionMode = (params->u.ofdm.transmission_mode != TRANSMISSION_MODE_AUTO); flags.Bits_T.NetworkId = 0; } else { - flags.Bits.Modulation = 0; - if(firesat->type == FireSAT_DVB_S) { - flags.Bits.FEC_inner = 1; - } else if(firesat->type == FireSAT_DVB_C) { - flags.Bits.FEC_inner = 0; - } + flags.Bits.Modulation = + (params->u.qam.modulation != QAM_AUTO); + flags.Bits.FEC_inner = + (params->u.qam.fec_inner != FEC_AUTO); flags.Bits.FEC_outer = 0; flags.Bits.Symbol_Rate = 1; flags.Bits.Frequency = 1; flags.Bits.Orbital_Pos = 0; - if(firesat->type == FireSAT_DVB_S) { - flags.Bits.Polarisation = 1; - } else if(firesat->type == FireSAT_DVB_C) { - flags.Bits.Polarisation = 0; - } + flags.Bits.Polarisation = 0; flags.Bits.reserved_fields = 0; flags.Bits.reserved1 = 0; flags.Bits.Network_ID = 0; @@ -306,15 +436,18 @@ int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params CmdFrm.operand[1] = 0xD2; // subfunction replace CmdFrm.operand[2] = 0x20; // system id = DVB CmdFrm.operand[3] = 0x00; // antenna number - CmdFrm.operand[4] = (firesat->type == FireSAT_DVB_T)?0x0c:0x11; // system_specific_multiplex selection_length + // system_specific_multiplex selection_length + CmdFrm.operand[4] = (firesat->type == FireSAT_DVB_T)?0x0c:0x11; CmdFrm.operand[5] = flags.Valid_Word.ByteHi; // valid_flags [0] CmdFrm.operand[6] = flags.Valid_Word.ByteLo; // valid_flags [1] if(firesat->type == FireSAT_DVB_T) { CmdFrm.operand[7] = 0x0; CmdFrm.operand[8] = (params->frequency/10) >> 24; - CmdFrm.operand[9] = ((params->frequency/10) >> 16) & 0xFF; - CmdFrm.operand[10] = ((params->frequency/10) >> 8) & 0xFF; + CmdFrm.operand[9] = + ((params->frequency/10) >> 16) & 0xFF; + CmdFrm.operand[10] = + ((params->frequency/10) >> 8) & 0xFF; CmdFrm.operand[11] = (params->frequency/10) & 0xFF; switch(params->u.ofdm.bandwidth) { case BANDWIDTH_7_MHZ: @@ -416,28 +549,24 @@ int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params CmdFrm.operand[16] = 0x00; // network_ID[1] CmdFrm.operand[17] = 0x00; // Nr_of_dsd_sel_specs = 0 - > No PIDs are transmitted - CmdFrm.length = 20; + CmdFrm.length = 24; } else { CmdFrm.operand[7] = 0x00; - CmdFrm.operand[8] = (((firesat->voltage==SEC_VOLTAGE_18)?0:1)<<6); /* 0 = H, 1 = V */ + CmdFrm.operand[8] = 0x00; CmdFrm.operand[9] = 0x00; CmdFrm.operand[10] = 0x00; - if(firesat->type == FireSAT_DVB_S) { - /* ### relative frequency -> absolute frequency */ - CmdFrm.operand[11] = (((params->frequency/4) >> 16) & 0xFF) | (2 << 6); - CmdFrm.operand[12] = ((params->frequency/4) >> 8) & 0xFF; - CmdFrm.operand[13] = (params->frequency/4) & 0xFF; - } else if(firesat->type == FireSAT_DVB_C) { - CmdFrm.operand[11] = (((params->frequency/4000) >> 16) & 0xFF) | (2 << 6); - CmdFrm.operand[12] = ((params->frequency/4000) >> 8) & 0xFF; - CmdFrm.operand[13] = (params->frequency/4000) & 0xFF; - } - - CmdFrm.operand[14] = ((params->u.qpsk.symbol_rate/1000) >> 12) & 0xFF; - CmdFrm.operand[15] = ((params->u.qpsk.symbol_rate/1000) >> 4) & 0xFF; - CmdFrm.operand[16] = ((params->u.qpsk.symbol_rate/1000) << 4) & 0xF0; - + CmdFrm.operand[11] = + (((params->frequency/4000) >> 16) & 0xFF) | (2 << 6); + CmdFrm.operand[12] = + ((params->frequency/4000) >> 8) & 0xFF; + CmdFrm.operand[13] = (params->frequency/4000) & 0xFF; + CmdFrm.operand[14] = + ((params->u.qpsk.symbol_rate/1000) >> 12) & 0xFF; + CmdFrm.operand[15] = + ((params->u.qpsk.symbol_rate/1000) >> 4) & 0xFF; + CmdFrm.operand[16] = + ((params->u.qpsk.symbol_rate/1000) << 4) & 0xF0; CmdFrm.operand[17] = 0x00; switch(params->u.qpsk.fec_inner) { case FEC_1_2: @@ -455,35 +584,35 @@ int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params case FEC_7_8: CmdFrm.operand[18] = 0x5; break; - case FEC_4_5: case FEC_8_9: + CmdFrm.operand[18] = 0x6; + break; + case FEC_4_5: + CmdFrm.operand[18] = 0x8; + break; case FEC_AUTO: default: CmdFrm.operand[18] = 0x0; } - if(firesat->type == FireSAT_DVB_S) { + switch(params->u.qam.modulation) { + case QAM_16: CmdFrm.operand[19] = 0x08; // modulation - } else if(firesat->type == FireSAT_DVB_C) { - switch(params->u.qam.modulation) { - case QAM_16: - CmdFrm.operand[19] = 0x08; // modulation - break; - case QAM_32: - CmdFrm.operand[19] = 0x10; // modulation - break; - case QAM_64: - CmdFrm.operand[19] = 0x18; // modulation - break; - case QAM_128: - CmdFrm.operand[19] = 0x20; // modulation - break; - case QAM_256: - CmdFrm.operand[19] = 0x28; // modulation - break; - case QAM_AUTO: - default: - CmdFrm.operand[19] = 0x00; // modulation - } + break; + case QAM_32: + CmdFrm.operand[19] = 0x10; // modulation + break; + case QAM_64: + CmdFrm.operand[19] = 0x18; // modulation + break; + case QAM_128: + CmdFrm.operand[19] = 0x20; // modulation + break; + case QAM_256: + CmdFrm.operand[19] = 0x28; // modulation + break; + case QAM_AUTO: + default: + CmdFrm.operand[19] = 0x00; // modulation } CmdFrm.operand[20] = 0x00; CmdFrm.operand[21] = 0x00; @@ -496,7 +625,6 @@ int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params if((k=AVCWrite(firesat,&CmdFrm,&RspFrm))) return k; -// msleep(250); mdelay(500); if(status) @@ -504,13 +632,12 @@ int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params return 0; } -int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]) { +int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]) +{ AVCCmdFrm CmdFrm; AVCRspFrm RspFrm; int pos,k; - printk(KERN_INFO "%s\n", __func__); - if(pidc > 16 && pidc != 0xFF) return -EINVAL; @@ -526,49 +653,11 @@ int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]) { CmdFrm.operand[1] = 0xD2; // subfunction replace CmdFrm.operand[2] = 0x20; // system id = DVB CmdFrm.operand[3] = 0x00; // antenna number - CmdFrm.operand[4] = 0x11; // system_specific_multiplex selection_length - CmdFrm.operand[5] = 0x00; // valid_flags [0] - CmdFrm.operand[6] = 0x00; // valid_flags [1] - - if(firesat->type == FireSAT_DVB_T) { -/* CmdFrm.operand[7] = 0x00; - CmdFrm.operand[8] = 0x00;//(params->frequency/10) >> 24; - CmdFrm.operand[9] = 0x00;//((params->frequency/10) >> 16) & 0xFF; - CmdFrm.operand[10] = 0x00;//((params->frequency/10) >> 8) & 0xFF; - CmdFrm.operand[11] = 0x00;//(params->frequency/10) & 0xFF; - CmdFrm.operand[12] = 0x00; - CmdFrm.operand[13] = 0x00; - CmdFrm.operand[14] = 0x00; - - CmdFrm.operand[15] = 0x00; // network_ID[0] - CmdFrm.operand[16] = 0x00; // network_ID[1] -*/ CmdFrm.operand[17] = pidc; // Nr_of_dsd_sel_specs - - pos=18; - } else { -/* CmdFrm.operand[7] = 0x00; - CmdFrm.operand[8] = 0x00; - CmdFrm.operand[9] = 0x00; - CmdFrm.operand[10] = 0x00; - - CmdFrm.operand[11] = 0x00;//(((params->frequency/4) >> 16) & 0xFF) | (2 << 6); - CmdFrm.operand[12] = 0x00;//((params->frequency/4) >> 8) & 0xFF; - CmdFrm.operand[13] = 0x00;//(params->frequency/4) & 0xFF; - - CmdFrm.operand[14] = 0x00;//((params->u.qpsk.symbol_rate/1000) >> 12) & 0xFF; - CmdFrm.operand[15] = 0x00;//((params->u.qpsk.symbol_rate/1000) >> 4) & 0xFF; - CmdFrm.operand[16] = 0x00;//((params->u.qpsk.symbol_rate/1000) << 4) & 0xF0; - - CmdFrm.operand[17] = 0x00; - CmdFrm.operand[18] = 0x00; - CmdFrm.operand[19] = 0x00; // modulation - CmdFrm.operand[20] = 0x00; - CmdFrm.operand[21] = 0x00;*/ - CmdFrm.operand[22] = pidc; // Nr_of_dsd_sel_specs - - pos=23; - } - if(pidc != 0xFF) + CmdFrm.operand[4] = 0x00; // system_specific_multiplex selection_length + CmdFrm.operand[5] = pidc; // Nr_of_dsd_sel_specs + + pos=6; + if(pidc != 0xFF) { for(k=0;k PID @@ -577,17 +666,16 @@ int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]) { CmdFrm.operand[pos++] = 0x00; // tableID CmdFrm.operand[pos++] = 0x00; // filter_length } + } CmdFrm.length = pos+3; - if((pos+3)%4) CmdFrm.length += 4 - ((pos+3)%4); if((k=AVCWrite(firesat,&CmdFrm,&RspFrm))) return k; - mdelay(250); - + mdelay(50); return 0; } @@ -596,7 +684,7 @@ int AVCTuner_GetTS(struct firesat *firesat){ AVCRspFrm RspFrm; int k; - printk(KERN_INFO "%s\n", __func__); + //printk(KERN_INFO "%s\n", __func__); memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); @@ -612,20 +700,21 @@ int AVCTuner_GetTS(struct firesat *firesat){ CmdFrm.operand[3] = 0x20; // system id = DVB CmdFrm.operand[4] = 0x00; // antenna number CmdFrm.operand[5] = 0x0; // system_specific_search_flags - CmdFrm.operand[6] = 0x11; // system_specific_multiplex selection_length + CmdFrm.operand[6] = (firesat->type == FireSAT_DVB_T)?0x0c:0x11; // system_specific_multiplex selection_length CmdFrm.operand[7] = 0x00; // valid_flags [0] CmdFrm.operand[8] = 0x00; // valid_flags [1] - CmdFrm.operand[24] = 0x00; // nr_of_dsit_sel_specs (always 0) + CmdFrm.operand[7 + (firesat->type == FireSAT_DVB_T)?0x0c:0x11] = 0x00; // nr_of_dsit_sel_specs (always 0) - CmdFrm.length = 28; + CmdFrm.length = (firesat->type == FireSAT_DVB_T)?24:28; - if((k=AVCWrite(firesat, &CmdFrm, &RspFrm))) return k; + if ((k=AVCWrite(firesat, &CmdFrm, &RspFrm))) + return k; mdelay(250); return 0; } -int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport, int *has_ci) { +int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport) { AVCCmdFrm CmdFrm; AVCRspFrm RspFrm; @@ -660,8 +749,6 @@ int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *tr } if(systemId) *systemId = RspFrm.operand[7]; - if(has_ci) - *has_ci = (RspFrm.operand[14] >> 4) & 0x1; return 0; } @@ -679,14 +766,13 @@ int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_in CmdFrm.opcode=READ_DESCRIPTOR; CmdFrm.operand[0]=DESCRIPTOR_TUNER_STATUS; - CmdFrm.operand[1]=0xff; - CmdFrm.operand[2]=0x00; - CmdFrm.operand[3]=sizeof(ANTENNA_INPUT_INFO) >> 8; - CmdFrm.operand[4]=sizeof(ANTENNA_INPUT_INFO) & 0xFF; + CmdFrm.operand[1]=0xff; //read_result_status + CmdFrm.operand[2]=0x00; // reserver + CmdFrm.operand[3]=0;//sizeof(ANTENNA_INPUT_INFO) >> 8; + CmdFrm.operand[4]=0;//sizeof(ANTENNA_INPUT_INFO) & 0xFF; CmdFrm.operand[5]=0x00; - CmdFrm.operand[6]=0x03; + CmdFrm.operand[6]=0x00; CmdFrm.length=12; - //Absenden des AVC request und warten auf response if (AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) return -EIO; @@ -695,10 +781,11 @@ int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_in return -EINVAL; } - length = (RspFrm.operand[3] << 8) + RspFrm.operand[4]; - if(length == sizeof(ANTENNA_INPUT_INFO)) + length = RspFrm.operand[9]; + if(RspFrm.operand[1] == 0x10 && length == sizeof(ANTENNA_INPUT_INFO)) { - memcpy(antenna_input_info,&RspFrm.operand[7],length); + memcpy(antenna_input_info, &RspFrm.operand[10], + sizeof(ANTENNA_INPUT_INFO)); return 0; } printk("%s: invalid info returned from AVC\n",__func__); @@ -837,3 +924,384 @@ int AVCRegisterRemoteControl(struct firesat*firesat) { return __AVCRegisterRemoteControl(firesat, 0); } + +int AVCTuner_Host2Ca(struct firesat *firesat) +{ + + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + CmdFrm.cts = AVC; + CmdFrm.ctype = CONTROL; + CmdFrm.sutyp = 0x5; + CmdFrm.suid = firesat->subunit; + CmdFrm.opcode = VENDOR; + + CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; + CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; + CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; + CmdFrm.operand[3]=SFE_VENDOR_OPCODE_HOST2CA; + CmdFrm.operand[4] = 0; // slot + CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; // ca tag + CmdFrm.operand[6] = 0; // more/last + CmdFrm.operand[7] = 0; // length + CmdFrm.length = 12; + + if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) + return -EIO; + + return 0; +} + +static int get_ca_object_pos(AVCRspFrm *RspFrm) +{ + int length = 1; + + // Check length of length field + if (RspFrm->operand[7] & 0x80) + length = (RspFrm->operand[7] & 0x7F) + 1; + return length + 7; +} + +static int get_ca_object_length(AVCRspFrm *RspFrm) +{ + int size = 0; + int i; + + if (RspFrm->operand[7] & 0x80) { + for (i = 0; i < (RspFrm->operand[7] & 0x7F); i++) { + size <<= 8; + size += RspFrm->operand[8 + i]; + } + } + return RspFrm->operand[7]; +} + +int avc_ca_app_info(struct firesat *firesat, char *app_info, int *length) +{ + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + int pos; + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + CmdFrm.cts = AVC; + CmdFrm.ctype = STATUS; + CmdFrm.sutyp = 0x5; + CmdFrm.suid = firesat->subunit; + CmdFrm.opcode = VENDOR; + + CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; + CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; + CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; + CmdFrm.operand[3]=SFE_VENDOR_OPCODE_CA2HOST; + CmdFrm.operand[4] = 0; // slot + CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; // ca tag + CmdFrm.length = 12; + + if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) + return -EIO; + + + pos = get_ca_object_pos(&RspFrm); + app_info[0] = (TAG_APP_INFO >> 16) & 0xFF; + app_info[1] = (TAG_APP_INFO >> 8) & 0xFF; + app_info[2] = (TAG_APP_INFO >> 0) & 0xFF; + app_info[3] = 6 + RspFrm.operand[pos + 4]; + app_info[4] = 0x01; + memcpy(&app_info[5], &RspFrm.operand[pos], 5 + RspFrm.operand[pos + 4]); + *length = app_info[3] + 4; + + return 0; +} + +int avc_ca_info(struct firesat *firesat, char *app_info, int *length) +{ + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + int pos; + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + CmdFrm.cts = AVC; + CmdFrm.ctype = STATUS; + CmdFrm.sutyp = 0x5; + CmdFrm.suid = firesat->subunit; + CmdFrm.opcode = VENDOR; + + CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; + CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; + CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; + CmdFrm.operand[3]=SFE_VENDOR_OPCODE_CA2HOST; + CmdFrm.operand[4] = 0; // slot + CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; // ca tag + CmdFrm.length = 12; + + if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) + return -EIO; + + pos = get_ca_object_pos(&RspFrm); + app_info[0] = (TAG_CA_INFO >> 16) & 0xFF; + app_info[1] = (TAG_CA_INFO >> 8) & 0xFF; + app_info[2] = (TAG_CA_INFO >> 0) & 0xFF; + app_info[3] = 2; + app_info[4] = app_info[5]; + app_info[5] = app_info[6]; + *length = app_info[3] + 4; + + return 0; +} + +int avc_ca_reset(struct firesat *firesat) +{ + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + CmdFrm.cts = AVC; + CmdFrm.ctype = CONTROL; + CmdFrm.sutyp = 0x5; + CmdFrm.suid = firesat->subunit; + CmdFrm.opcode = VENDOR; + + CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; + CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; + CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; + CmdFrm.operand[3]=SFE_VENDOR_OPCODE_HOST2CA; + CmdFrm.operand[4] = 0; // slot + CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_RESET; // ca tag + CmdFrm.operand[6] = 0; // more/last + CmdFrm.operand[7] = 1; // length + CmdFrm.operand[8] = 0; // force hardware reset + CmdFrm.length = 12; + + if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) + return -EIO; + + return 0; +} + +int avc_ca_pmt(struct firesat *firesat, char *msg, int length) +{ + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + int list_management; + int program_info_length; + int pmt_cmd_id; + int read_pos; + int write_pos; + int es_info_length; + int crc32_csum; + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + CmdFrm.cts = AVC; + CmdFrm.ctype = CONTROL; + CmdFrm.sutyp = 0x5; + CmdFrm.suid = firesat->subunit; + CmdFrm.opcode = VENDOR; + + if (msg[0] != LIST_MANAGEMENT_ONLY) { + printk(KERN_ERR "The only list_manasgement parameter that is " + "supported by the firesat driver is \"only\" (3)."); + return -EFAULT; + } + // We take the cmd_id from the programme level only! + list_management = msg[0]; + program_info_length = ((msg[4] & 0x0F) << 8) + msg[5]; + if (program_info_length > 0) + program_info_length--; // Remove pmt_cmd_id + pmt_cmd_id = msg[6]; + + CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; + CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; + CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; + CmdFrm.operand[3]=SFE_VENDOR_OPCODE_HOST2CA; + CmdFrm.operand[4] = 0; // slot + CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_PMT; // ca tag + CmdFrm.operand[6] = 0; // more/last + //CmdFrm.operand[7] = XXXprogram_info_length + 17; // length + CmdFrm.operand[8] = list_management; + CmdFrm.operand[9] = 0x01; // pmt_cmd=OK_descramble + + // TS program map table + + // Table id=2 + CmdFrm.operand[10] = 0x02; + // Section syntax + length + CmdFrm.operand[11] = 0x80; + //CmdFrm.operand[12] = XXXprogram_info_length + 12; + // Program number + CmdFrm.operand[13] = msg[1]; + CmdFrm.operand[14] = msg[2]; + // Version number=0 + current/next=1 + CmdFrm.operand[15] = 0x01; + // Section number=0 + CmdFrm.operand[16] = 0x00; + // Last section number=0 + CmdFrm.operand[17] = 0x00; + // PCR_PID=1FFF + CmdFrm.operand[18] = 0x1F; + CmdFrm.operand[19] = 0xFF; + // Program info length + CmdFrm.operand[20] = (program_info_length >> 8); + CmdFrm.operand[21] = (program_info_length & 0xFF); + // CA descriptors at programme level + read_pos = 6; + write_pos = 22; + if (program_info_length > 0) { +/* printk(KERN_INFO "Copying descriptors at programme level.\n"); */ + pmt_cmd_id = msg[read_pos++]; + if (pmt_cmd_id != 1 && pmt_cmd_id !=4) { + printk(KERN_ERR "Invalid pmt_cmd_id=%d.\n", + pmt_cmd_id); + } + memcpy(&CmdFrm.operand[write_pos], &msg[read_pos], + program_info_length); + read_pos += program_info_length; + write_pos += program_info_length; + } + while (read_pos < length) { +/* printk(KERN_INFO "Copying descriptors at stream level for " */ +/* "stream type %d.\n", msg[read_pos]); */ + CmdFrm.operand[write_pos++] = msg[read_pos++]; + CmdFrm.operand[write_pos++] = msg[read_pos++]; + CmdFrm.operand[write_pos++] = msg[read_pos++]; + es_info_length = + ((msg[read_pos] & 0x0F) << 8) + msg[read_pos + 1]; + read_pos += 2; + if (es_info_length > 0) + es_info_length--; // Remove pmt_cmd_id + CmdFrm.operand[write_pos++] = es_info_length >> 8; + CmdFrm.operand[write_pos++] = es_info_length & 0xFF; + if (es_info_length > 0) { + pmt_cmd_id = msg[read_pos++]; + if (pmt_cmd_id != 1 && pmt_cmd_id !=4) { + printk(KERN_ERR "Invalid pmt_cmd_id=%d at " + "stream level.\n", pmt_cmd_id); + } + memcpy(&CmdFrm.operand[write_pos], &msg[read_pos], + es_info_length); + read_pos += es_info_length; + write_pos += es_info_length; + } + } + + // CRC + CmdFrm.operand[write_pos++] = 0x00; + CmdFrm.operand[write_pos++] = 0x00; + CmdFrm.operand[write_pos++] = 0x00; + CmdFrm.operand[write_pos++] = 0x00; + + CmdFrm.operand[7] = write_pos - 8; + CmdFrm.operand[12] = write_pos - 13; + + crc32_csum = crc32_be(0, &CmdFrm.operand[10], + CmdFrm.operand[12] - 1); + CmdFrm.operand[write_pos - 4] = (crc32_csum >> 24) & 0xFF; + CmdFrm.operand[write_pos - 3] = (crc32_csum >> 16) & 0xFF; + CmdFrm.operand[write_pos - 2] = (crc32_csum >> 8) & 0xFF; + CmdFrm.operand[write_pos - 1] = (crc32_csum >> 0) & 0xFF; + + CmdFrm.length = write_pos + 3; + if ((write_pos + 3) % 4) + CmdFrm.length += 4 - ((write_pos + 3) % 4); + + if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) + return -EIO; + + if (RspFrm.resp != ACCEPTED) { + printk(KERN_ERR "Answer to CA PMT was %d\n", RspFrm.resp); + return -EFAULT; + } + + return 0; + +} + +int avc_ca_get_time_date(struct firesat *firesat, int *interval) +{ + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + CmdFrm.cts = AVC; + CmdFrm.ctype = STATUS; + CmdFrm.sutyp = 0x5; + CmdFrm.suid = firesat->subunit; + CmdFrm.opcode = VENDOR; + + CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; + CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; + CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; + CmdFrm.operand[3]=SFE_VENDOR_OPCODE_CA2HOST; + CmdFrm.operand[4] = 0; // slot + CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_DATE_TIME; // ca tag + CmdFrm.operand[6] = 0; // more/last + CmdFrm.operand[7] = 0; // length + CmdFrm.length = 12; + + if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) + return -EIO; + + *interval = RspFrm.operand[get_ca_object_pos(&RspFrm)]; + + return 0; +} + +int avc_ca_enter_menu(struct firesat *firesat) +{ + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + CmdFrm.cts = AVC; + CmdFrm.ctype = STATUS; + CmdFrm.sutyp = 0x5; + CmdFrm.suid = firesat->subunit; + CmdFrm.opcode = VENDOR; + + CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; + CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; + CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; + CmdFrm.operand[3]=SFE_VENDOR_OPCODE_HOST2CA; + CmdFrm.operand[4] = 0; // slot + CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_ENTER_MENU; + CmdFrm.operand[6] = 0; // more/last + CmdFrm.operand[7] = 0; // length + CmdFrm.length = 12; + + if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) + return -EIO; + + return 0; +} + +int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, int *length) +{ + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + CmdFrm.cts = AVC; + CmdFrm.ctype = STATUS; + CmdFrm.sutyp = 0x5; + CmdFrm.suid = firesat->subunit; + CmdFrm.opcode = VENDOR; + + CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; + CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; + CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; + CmdFrm.operand[3]=SFE_VENDOR_OPCODE_CA2HOST; + CmdFrm.operand[4] = 0; // slot + CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_MMI; + CmdFrm.operand[6] = 0; // more/last + CmdFrm.operand[7] = 0; // length + CmdFrm.length = 12; + + if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) + return -EIO; + + *length = get_ca_object_length(&RspFrm); + memcpy(mmi_object, &RspFrm.operand[get_ca_object_pos(&RspFrm)], *length); + + return 0; +} diff --git a/drivers/media/dvb/firesat/avc_api.h b/drivers/media/dvb/firesat/avc_api.h index f9a190adcd3..04166568590 100644 --- a/drivers/media/dvb/firesat/avc_api.h +++ b/drivers/media/dvb/firesat/avc_api.h @@ -4,6 +4,7 @@ begin : Wed May 1 2000 copyright : (C) 2000 by Manfred Weihs copyright : (C) 2003 by Philipp Gutgsell + copyright : (C) 2008 by Henrik Kurelid (henrik@kurelid.se) email : 0014guph@edu.fh-kaernten.ac.at ***************************************************************************/ @@ -27,12 +28,10 @@ #include -#define BYTE unsigned char -#define WORD unsigned short -#define DWORD unsigned long -#define ULONG unsigned long -#define LONG long - +/************************************************************* + Constants from EN510221 +**************************************************************/ +#define LIST_MANAGEMENT_ONLY 0x03 /************************************************************* FCP Address range @@ -68,12 +67,12 @@ typedef struct { typedef struct _AVCCmdFrm { // AV/C command frame - BYTE ctype : 4 ; // command type - BYTE cts : 4 ; // always 0x0 for AVC - BYTE suid : 3 ; // subunit ID - BYTE sutyp : 5 ; // subunit_typ - BYTE opcode : 8 ; // opcode - BYTE operand[509] ; // array of operands [1-507] + __u8 ctype : 4 ; // command type + __u8 cts : 4 ; // always 0x0 for AVC + __u8 suid : 3 ; // subunit ID + __u8 sutyp : 5 ; // subunit_typ + __u8 opcode : 8 ; // opcode + __u8 operand[509] ; // array of operands [1-507] int length; //length of the command frame } AVCCmdFrm ; @@ -81,12 +80,12 @@ typedef struct _AVCCmdFrm typedef struct _AVCRspFrm { // AV/C response frame - BYTE resp : 4 ; // response type - BYTE cts : 4 ; // always 0x0 for AVC - BYTE suid : 3 ; // subunit ID - BYTE sutyp : 5 ; // subunit_typ - BYTE opcode : 8 ; // opcode - BYTE operand[509] ; // array of operands [1-507] + __u8 resp : 4 ; // response type + __u8 cts : 4 ; // always 0x0 for AVC + __u8 suid : 3 ; // subunit ID + __u8 sutyp : 5 ; // subunit_typ + __u8 opcode : 8 ; // opcode + __u8 operand[509] ; // array of operands [1-507] int length; //length of the response frame } AVCRspFrm ; @@ -94,23 +93,23 @@ typedef struct _AVCRspFrm typedef struct _AVCCmdFrm { - BYTE cts:4; - BYTE ctype:4; - BYTE sutyp:5; - BYTE suid:3; - BYTE opcode; - BYTE operand[509]; + __u8 cts:4; + __u8 ctype:4; + __u8 sutyp:5; + __u8 suid:3; + __u8 opcode; + __u8 operand[509]; int length; } AVCCmdFrm; typedef struct _AVCRspFrm { - BYTE cts:4; - BYTE resp:4; - BYTE sutyp:5; - BYTE suid:3; - BYTE opcode; - BYTE operand[509]; + __u8 cts:4; + __u8 resp:4; + __u8 sutyp:5; + __u8 suid:3; + __u8 opcode; + __u8 operand[509]; int length; } AVCRspFrm; @@ -197,6 +196,14 @@ typedef struct _AVCRspFrm #define SFE_VENDOR_OPCODE_CISTATUS 0x59 #define SFE_VENDOR_OPCODE_TUNE_QPSK2 0x60 // QPSK command for DVB-S2 devices +// CA Tags +#define SFE_VENDOR_TAG_CA_RESET 0x00 +#define SFE_VENDOR_TAG_CA_APPLICATION_INFO 0x01 +#define SFE_VENDOR_TAG_CA_PMT 0x02 +#define SFE_VENDOR_TAG_CA_DATE_TIME 0x04 +#define SFE_VENDOR_TAG_CA_MMI 0x05 +#define SFE_VENDOR_TAG_CA_ENTER_MENU 0x07 + //AVCTuner DVB identifier service_ID #define DVB 0x20 @@ -209,8 +216,8 @@ typedef struct _AVCRspFrm #define Tuner_Status_Descriptor 0x80 typedef struct { - BYTE Subunit_Type; - BYTE Max_Subunit_ID; + __u8 Subunit_Type; + __u8 Max_Subunit_ID; } SUBUNIT_INFO; /************************************************************* @@ -220,12 +227,12 @@ typedef struct { **************************************************************/ typedef struct { - BYTE Byte0; - BYTE Byte1; - BYTE Byte2; - BYTE Byte3; - BYTE Byte4; - BYTE Byte5; + __u8 Byte0; + __u8 Byte1; + __u8 Byte2; + __u8 Byte3; + __u8 Byte4; + __u8 Byte5; }OBJECT_ID; /************************************************************* @@ -234,14 +241,14 @@ typedef struct { typedef struct { #ifdef __LITTLE_ENDIAN - BYTE RF_frequency_hByte:6; - BYTE raster_Frequency:2;//Bit7,6 raster frequency + __u8 RF_frequency_hByte:6; + __u8 raster_Frequency:2;//Bit7,6 raster frequency #else - BYTE raster_Frequency:2; - BYTE RF_frequency_hByte:6; + __u8 raster_Frequency:2; + __u8 RF_frequency_hByte:6; #endif - BYTE RF_frequency_mByte; - BYTE RF_frequency_lByte; + __u8 RF_frequency_mByte; + __u8 RF_frequency_lByte; }FREQUENCY; @@ -249,63 +256,63 @@ typedef struct typedef struct { - BYTE Modulation :1; - BYTE FEC_inner :1; - BYTE FEC_outer :1; - BYTE Symbol_Rate :1; - BYTE Frequency :1; - BYTE Orbital_Pos :1; - BYTE Polarisation :1; - BYTE reserved_fields :1; - BYTE reserved1 :7; - BYTE Network_ID :1; + __u8 Modulation :1; + __u8 FEC_inner :1; + __u8 FEC_outer :1; + __u8 Symbol_Rate :1; + __u8 Frequency :1; + __u8 Orbital_Pos :1; + __u8 Polarisation :1; + __u8 reserved_fields :1; + __u8 reserved1 :7; + __u8 Network_ID :1; }MULTIPLEX_VALID_FLAGS; typedef struct { - BYTE GuardInterval:1; - BYTE CodeRateLPStream:1; - BYTE CodeRateHPStream:1; - BYTE HierarchyInfo:1; - BYTE Constellation:1; - BYTE Bandwidth:1; - BYTE CenterFrequency:1; - BYTE reserved1:1; - BYTE reserved2:5; - BYTE OtherFrequencyFlag:1; - BYTE TransmissionMode:1; - BYTE NetworkId:1; + __u8 GuardInterval:1; + __u8 CodeRateLPStream:1; + __u8 CodeRateHPStream:1; + __u8 HierarchyInfo:1; + __u8 Constellation:1; + __u8 Bandwidth:1; + __u8 CenterFrequency:1; + __u8 reserved1:1; + __u8 reserved2:5; + __u8 OtherFrequencyFlag:1; + __u8 TransmissionMode:1; + __u8 NetworkId:1; }MULTIPLEX_VALID_FLAGS_DVBT; #else typedef struct { - BYTE reserved_fields:1; - BYTE Polarisation:1; - BYTE Orbital_Pos:1; - BYTE Frequency:1; - BYTE Symbol_Rate:1; - BYTE FEC_outer:1; - BYTE FEC_inner:1; - BYTE Modulation:1; - BYTE Network_ID:1; - BYTE reserved1:7; + __u8 reserved_fields:1; + __u8 Polarisation:1; + __u8 Orbital_Pos:1; + __u8 Frequency:1; + __u8 Symbol_Rate:1; + __u8 FEC_outer:1; + __u8 FEC_inner:1; + __u8 Modulation:1; + __u8 Network_ID:1; + __u8 reserved1:7; }MULTIPLEX_VALID_FLAGS; typedef struct { - BYTE reserved1:1; - BYTE CenterFrequency:1; - BYTE Bandwidth:1; - BYTE Constellation:1; - BYTE HierarchyInfo:1; - BYTE CodeRateHPStream:1; - BYTE CodeRateLPStream:1; - BYTE GuardInterval:1; - BYTE NetworkId:1; - BYTE TransmissionMode:1; - BYTE OtherFrequencyFlag:1; - BYTE reserved2:5; + __u8 reserved1:1; + __u8 CenterFrequency:1; + __u8 Bandwidth:1; + __u8 Constellation:1; + __u8 HierarchyInfo:1; + __u8 CodeRateHPStream:1; + __u8 CodeRateLPStream:1; + __u8 GuardInterval:1; + __u8 NetworkId:1; + __u8 TransmissionMode:1; + __u8 OtherFrequencyFlag:1; + __u8 reserved2:5; }MULTIPLEX_VALID_FLAGS_DVBT; #endif @@ -314,47 +321,98 @@ typedef union { MULTIPLEX_VALID_FLAGS Bits; MULTIPLEX_VALID_FLAGS_DVBT Bits_T; struct { - BYTE ByteHi; - BYTE ByteLo; + __u8 ByteHi; + __u8 ByteLo; } Valid_Word; } M_VALID_FLAGS; typedef struct { #ifdef __LITTLE_ENDIAN - BYTE ActiveSystem; - BYTE reserved:5; - BYTE NoRF:1; - BYTE Moving:1; - BYTE Searching:1; + __u8 ActiveSystem; + __u8 reserved:5; + __u8 NoRF:1; + __u8 Moving:1; + __u8 Searching:1; - BYTE SelectedAntenna:7; - BYTE Input:1; + __u8 SelectedAntenna:7; + __u8 Input:1; - BYTE BER[4]; + __u8 BER[4]; - BYTE SignalStrength; + __u8 SignalStrength; FREQUENCY Frequency; - BYTE ManDepInfoLength; + __u8 ManDepInfoLength; + + __u8 PowerSupply:1; + __u8 FrontEndPowerStatus:1; + __u8 reserved3:1; + __u8 AntennaError:1; + __u8 FrontEndError:1; + __u8 reserved2:3; + + __u8 CarrierNoiseRatio[2]; + __u8 reserved4[2]; + __u8 PowerSupplyVoltage; + __u8 AntennaVoltage; + __u8 FirewireBusVoltage; + + __u8 CaMmi:1; + __u8 reserved5:7; + + __u8 reserved6:1; + __u8 CaInitializationStatus:1; + __u8 CaErrorFlag:1; + __u8 CaDvbFlag:1; + __u8 CaModulePresentStatus:1; + __u8 CaApplicationInfo:1; + __u8 CaDateTimeRequest:1; + __u8 CaPmtReply:1; + #else - BYTE ActiveSystem; - BYTE Searching:1; - BYTE Moving:1; - BYTE NoRF:1; - BYTE reserved:5; + __u8 ActiveSystem; + __u8 Searching:1; + __u8 Moving:1; + __u8 NoRF:1; + __u8 reserved:5; - BYTE Input:1; - BYTE SelectedAntenna:7; + __u8 Input:1; + __u8 SelectedAntenna:7; - BYTE BER[4]; + __u8 BER[4]; - BYTE SignalStrength; + __u8 SignalStrength; FREQUENCY Frequency; - BYTE ManDepInfoLength; + __u8 ManDepInfoLength; + + __u8 reserved2:3; + __u8 FrontEndError:1; + __u8 AntennaError:1; + __u8 reserved3:1; + __u8 FrontEndPowerStatus:1; + __u8 PowerSupply:1; + + __u8 CarrierNoiseRatio[2]; + __u8 reserved4[2]; + __u8 PowerSupplyVoltage; + __u8 AntennaVoltage; + __u8 FirewireBusVoltage; + + __u8 reserved5:7; + __u8 CaMmi:1; + __u8 CaPmtReply:1; + __u8 CaDateTimeRequest:1; + __u8 CaApplicationInfo:1; + __u8 CaModulePresentStatus:1; + __u8 CaDvbFlag:1; + __u8 CaErrorFlag:1; + __u8 CaInitializationStatus:1; + __u8 reserved6:1; + #endif -} ANTENNA_INPUT_INFO; // 11 Byte +} ANTENNA_INPUT_INFO; // 22 Byte #define LNBCONTROL_DONTCARE 0xff @@ -365,17 +423,27 @@ extern int AVCRecv(struct firesat *firesat, u8 *data, size_t length); extern int AVCTuner_DSIT(struct firesat *firesat, int Source_Plug, struct dvb_frontend_parameters *params, - BYTE *status); + __u8 *status); extern int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_info); -extern int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, BYTE *status); +extern int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, __u8 *status); extern int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]); extern int AVCTuner_GetTS(struct firesat *firesat); -extern int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport, int *has_ci); +extern int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport); extern int AVCLNBControl(struct firesat *firesat, char voltage, char burst, char conttone, char nrdiseq, struct dvb_diseqc_master_cmd *diseqcmd); extern int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount); extern int AVCRegisterRemoteControl(struct firesat *firesat); +extern int AVCTuner_Host2Ca(struct firesat *firesat); +extern int avc_ca_app_info(struct firesat *firesat, char *app_info, + int *length); +extern int avc_ca_info(struct firesat *firesat, char *app_info, int *length); +extern int avc_ca_reset(struct firesat *firesat); +extern int avc_ca_pmt(struct firesat *firesat, char *app_info, int length); +extern int avc_ca_get_time_date(struct firesat *firesat, int *interval); +extern int avc_ca_enter_menu(struct firesat *firesat); +extern int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, + int *length); #endif diff --git a/drivers/media/dvb/firesat/cmp.c b/drivers/media/dvb/firesat/cmp.c index 37b91f3f7ff..a1291caa067 100644 --- a/drivers/media/dvb/firesat/cmp.c +++ b/drivers/media/dvb/firesat/cmp.c @@ -1,3 +1,15 @@ +/* + * FireSAT DVB driver + * + * Copyright (c) ? + * Copyright (c) 2008 Henrik Kurelid + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + #include "cmp.h" #include #include @@ -10,18 +22,18 @@ typedef struct _OPCR { - BYTE PTPConnCount : 6 ; // Point to point connect. counter - BYTE BrConnCount : 1 ; // Broadcast connection counter - BYTE OnLine : 1 ; // On Line + __u8 PTPConnCount : 6 ; // Point to point connect. counter + __u8 BrConnCount : 1 ; // Broadcast connection counter + __u8 OnLine : 1 ; // On Line - BYTE ChNr : 6 ; // Channel number - BYTE Res : 2 ; // Reserved + __u8 ChNr : 6 ; // Channel number + __u8 Res : 2 ; // Reserved - BYTE PayloadHi : 2 ; // Payoad high bits - BYTE OvhdID : 4 ; // Overhead ID - BYTE DataRate : 2 ; // Data Rate + __u8 PayloadHi : 2 ; // Payoad high bits + __u8 OvhdID : 4 ; // Overhead ID + __u8 DataRate : 2 ; // Data Rate - BYTE PayloadLo ; // Payoad low byte + __u8 PayloadLo ; // Payoad low byte } OPCR ; #define FIRESAT_SPEED IEEE1394_SPEED_400 @@ -94,13 +106,13 @@ int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, int i u64 oPCR_address=0xfffff0000904ull+(output_plug << 2); int result=cmp_read(firesat, &test_oPCR, oPCR_address, 4); - printk(KERN_INFO "%s: nodeid = %d\n",__func__,firesat->nodeentry->nodeid); +/* printk(KERN_INFO "%s: nodeid = %d\n",__func__,firesat->nodeentry->nodeid); */ if (result < 0) { printk("%s: cannot read oPCR\n", __func__); return result; } else { - printk(KERN_INFO "%s: oPCR = %08x\n",__func__,test_oPCR); +/* printk(KERN_INFO "%s: oPCR = %08x\n",__func__,test_oPCR); */ do { OPCR *hilf= (OPCR*) &test_oPCR; @@ -134,8 +146,8 @@ int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, int i hilf->PTPConnCount++; new_oPCR=test_oPCR; - printk(KERN_INFO "%s: trying compare_swap...\n",__func__); - printk(KERN_INFO "%s: oPCR_old: %08x, oPCR_new: %08x\n",__func__, old_oPCR, new_oPCR); +/* printk(KERN_INFO "%s: trying compare_swap...\n",__func__); */ +/* printk(KERN_INFO "%s: oPCR_old: %08x, oPCR_new: %08x\n",__func__, old_oPCR, new_oPCR); */ result=cmp_lock(firesat, &test_oPCR, oPCR_address, old_oPCR, 2); if (result < 0) { @@ -169,7 +181,7 @@ int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug,int iso_ch u64 oPCR_address=0xfffff0000904ull+(output_plug << 2); int result=cmp_read(firesat, &test_oPCR, oPCR_address, 4); - printk(KERN_INFO "%s\n",__func__); +/* printk(KERN_INFO "%s\n",__func__); */ if (result < 0) { printk("%s: cannot read oPCR\n", __func__); diff --git a/drivers/media/dvb/firesat/firesat-ci.c b/drivers/media/dvb/firesat/firesat-ci.c index 862d9553c5b..821048db283 100644 --- a/drivers/media/dvb/firesat/firesat-ci.c +++ b/drivers/media/dvb/firesat/firesat-ci.c @@ -1,66 +1,303 @@ +/* + * FireSAT DVB driver + * + * Copyright (c) 2008 Henrik Kurelid + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + #include "firesat-ci.h" #include "firesat.h" #include "avc_api.h" #include #include -/* -static int firesat_ca_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *parg) { - //struct firesat *firesat = (struct firesat*)((struct dvb_device*)file->private_data)->priv; - int err; -// printk(KERN_INFO "%s: ioctl %d\n",__func__,cmd); +static unsigned int ca_debug = 0; +module_param(ca_debug, int, 0644); +MODULE_PARM_DESC(ca_debug, "debug logging of ca system, default is 0 (no)"); - switch(cmd) { - case CA_RESET: - // TODO: Needs to be implemented with new AVC Vendor commands +static int firesat_ca_ready(ANTENNA_INPUT_INFO *info) +{ + if (ca_debug != 0) + printk("%s: CaMmi=%d, CaInit=%d, CaError=%d, CaDvb=%d, " + "CaModule=%d, CaAppInfo=%d, CaDateTime=%d, " + "CaPmt=%d\n", __func__, info->CaMmi, + info->CaInitializationStatus, info->CaErrorFlag, + info->CaDvbFlag, info->CaModulePresentStatus, + info->CaApplicationInfo, + info->CaDateTimeRequest, info->CaPmtReply); + return info->CaInitializationStatus == 1 && + info->CaErrorFlag == 0 && + info->CaDvbFlag == 1 && + info->CaModulePresentStatus == 1; +} + +static int firesat_get_ca_flags(ANTENNA_INPUT_INFO *info) +{ + int flags = 0; + if (info->CaModulePresentStatus == 1) + flags |= CA_CI_MODULE_PRESENT; + if (info->CaInitializationStatus == 1 && + info->CaErrorFlag == 0 && + info->CaDvbFlag == 1) + flags |= CA_CI_MODULE_READY; + return flags; +} + +static int firesat_ca_reset(struct firesat *firesat) +{ + if (ca_debug) + printk(KERN_INFO "%s: ioctl CA_RESET\n", __func__); + if (avc_ca_reset(firesat)) + return -EFAULT; + return 0; +} + +static int firesat_ca_get_caps(struct firesat *firesat, void *arg) +{ + struct ca_caps *cap_p = (struct ca_caps*)arg; + int err = 0; + + cap_p->slot_num = 1; + cap_p->slot_type = CA_CI; + cap_p->descr_num = 1; + cap_p->descr_type = CA_ECD; + if (ca_debug) + printk(KERN_INFO "%s: ioctl CA_GET_CAP\n", __func__); + return err; +} + +static int firesat_ca_get_slot_info(struct firesat *firesat, void *arg) +{ + ANTENNA_INPUT_INFO info; + struct ca_slot_info *slot_p = (struct ca_slot_info*)arg; + + if (ca_debug) + printk(KERN_INFO "%s: ioctl CA_GET_SLOT_INFO on slot %d.\n", + __func__, slot_p->num); + if (AVCTunerStatus(firesat, &info)) + return -EFAULT; + + if (slot_p->num == 0) { + slot_p->type = CA_CI; + slot_p->flags = firesat_get_ca_flags(&info); + } + else { + return -EFAULT; + } + return 0; +} + +static int firesat_ca_app_info(struct firesat *firesat, void *arg) +{ + struct ca_msg *reply_p = (struct ca_msg*)arg; + int i; + + if (avc_ca_app_info(firesat, reply_p->msg, &reply_p->length)) + return -EFAULT; + if (ca_debug) { + printk(KERN_INFO "%s: Creating TAG_APP_INFO message:", + __func__); + for (i = 0; i < reply_p->length; i++) + printk("0x%02X, ", (unsigned char)reply_p->msg[i]); + printk("\n"); + } + return 0; +} + +static int firesat_ca_info(struct firesat *firesat, void *arg) +{ + struct ca_msg *reply_p = (struct ca_msg*)arg; + int i; + + if (avc_ca_info(firesat, reply_p->msg, &reply_p->length)) + return -EFAULT; + if (ca_debug) { + printk(KERN_INFO "%s: Creating TAG_CA_INFO message:", + __func__); + for (i = 0; i < reply_p->length; i++) + printk("0x%02X, ", (unsigned char)reply_p->msg[i]); + printk("\n"); + } + return 0; +} + +static int firesat_ca_get_mmi(struct firesat *firesat, void *arg) +{ + struct ca_msg *reply_p = (struct ca_msg*)arg; + int i; + + if (avc_ca_get_mmi(firesat, reply_p->msg, &reply_p->length)) + return -EFAULT; + if (ca_debug) { + printk(KERN_INFO "%s: Creating MMI reply INFO message:", + __func__); + for (i = 0; i < reply_p->length; i++) + printk("0x%02X, ", (unsigned char)reply_p->msg[i]); + printk("\n"); + } + return 0; +} + +static int firesat_ca_get_msg(struct firesat *firesat, void *arg) +{ + int err; + ANTENNA_INPUT_INFO info; + + switch (firesat->ca_last_command) { + case TAG_APP_INFO_ENQUIRY: + err = firesat_ca_app_info(firesat, arg); + break; + case TAG_CA_INFO_ENQUIRY: + err = firesat_ca_info(firesat, arg); break; - case CA_GET_CAP: { - ca_caps_t *cap=(ca_caps_t*)parg; - cap->slot_num = 1; - cap->slot_type = CA_CI_LINK; - cap->descr_num = 1; - cap->descr_type = CA_DSS; + default: + if (AVCTunerStatus(firesat, &info)) + err = -EFAULT; + else if (info.CaMmi == 1) { + err = firesat_ca_get_mmi(firesat, arg); + } + else { + printk(KERN_INFO "%s: Unhandled message 0x%08X\n", + __func__, firesat->ca_last_command); + err = -EFAULT; + } + } + firesat->ca_last_command = 0; + return err; +} +static int firesat_ca_pmt(struct firesat *firesat, void *arg) +{ + struct ca_msg *msg_p = (struct ca_msg*)arg; + int data_pos; + + if (msg_p->msg[3] & 0x80) + data_pos = (msg_p->msg[4] && 0x7F) + 4; + else + data_pos = 4; + if (avc_ca_pmt(firesat, &msg_p->msg[data_pos], + msg_p->length - data_pos)) + return -EFAULT; + return 0; +} + +static int firesat_ca_send_msg(struct firesat *firesat, void *arg) +{ + int err; + struct ca_msg *msg_p = (struct ca_msg*)arg; + + // Do we need a semaphore for this? + firesat->ca_last_command = + (msg_p->msg[0] << 16) + (msg_p->msg[1] << 8) + msg_p->msg[2]; + switch (firesat->ca_last_command) { + case TAG_CA_PMT: + if (ca_debug != 0) + printk(KERN_INFO "%s: Message received: TAG_CA_PMT\n", + __func__); + err = firesat_ca_pmt(firesat, arg); + break; + case TAG_APP_INFO_ENQUIRY: + // This is all handled in ca_get_msg + if (ca_debug != 0) + printk(KERN_INFO "%s: Message received: " + "TAG_APP_INFO_ENQUIRY\n", __func__); err = 0; break; - } - case CA_GET_SLOT_INFO: { - ca_slot_info_t *slot=(ca_slot_info_t*)parg; - if(slot->num == 0) { - slot->type = CA_CI | CA_CI_LINK | CA_DESCR; - slot->flags = CA_CI_MODULE_PRESENT | CA_CI_MODULE_READY; - } else { - slot->type = 0; - slot->flags = 0; - } + case TAG_CA_INFO_ENQUIRY: + // This is all handled in ca_get_msg + if (ca_debug != 0) + printk(KERN_INFO "%s: Message received: " + "TAG_CA_APP_INFO_ENQUIRY\n", __func__); err = 0; break; + case TAG_ENTER_MENU: + if (ca_debug != 0) + printk(KERN_INFO "%s: Entering CA menu.\n", __func__); + err = avc_ca_enter_menu(firesat); + break; + default: + printk(KERN_ERR "%s: Unhandled unknown message 0x%08X\n", + __func__, firesat->ca_last_command); + err = -EFAULT; } + return err; +} + +static int firesat_ca_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, void *arg) +{ + struct dvb_device* dvbdev = (struct dvb_device*) file->private_data; + struct firesat *firesat = dvbdev->priv; + int err; + ANTENNA_INPUT_INFO info; + + switch(cmd) { + case CA_RESET: + err = firesat_ca_reset(firesat); + break; + case CA_GET_CAP: + err = firesat_ca_get_caps(firesat, arg); + break; + case CA_GET_SLOT_INFO: + err = firesat_ca_get_slot_info(firesat, arg); + break; + case CA_GET_MSG: + err = firesat_ca_get_msg(firesat, arg); + break; + case CA_SEND_MSG: + err = firesat_ca_send_msg(firesat, arg); + break; default: - err=-EINVAL; + printk(KERN_INFO "%s: Unhandled ioctl, command: %u\n",__func__, + cmd); + err = -EOPNOTSUPP; } + + if (AVCTunerStatus(firesat, &info)) + return err; + + firesat_ca_ready(&info); + return err; } -*/ -static int firesat_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - //return dvb_usercopy(inode, file, cmd, arg, firesat_ca_do_ioctl); - return dvb_generic_ioctl(inode, file, cmd, arg); +static int firesat_get_date_time_request(struct firesat *firesat) +{ + if (ca_debug) + printk(KERN_INFO "%s: Retrieving Time/Date request\n", + __func__); + if (avc_ca_get_time_date(firesat, &firesat->ca_time_interval)) + return -EFAULT; + if (ca_debug) + printk(KERN_INFO "%s: Time/Date interval is %d\n", + __func__, firesat->ca_time_interval); + + return 0; } -static int firesat_ca_io_open(struct inode *inode, struct file *file) { - printk(KERN_INFO "%s!\n",__func__); +static int firesat_ca_io_open(struct inode *inode, struct file *file) +{ + if (ca_debug != 0) + printk(KERN_INFO "%s\n",__func__); return dvb_generic_open(inode, file); } -static int firesat_ca_io_release(struct inode *inode, struct file *file) { - printk(KERN_INFO "%s!\n",__func__); +static int firesat_ca_io_release(struct inode *inode, struct file *file) +{ + if (ca_debug != 0) + printk(KERN_INFO "%s\n",__func__); return dvb_generic_release(inode, file); } -static unsigned int firesat_ca_io_poll(struct file *file, poll_table *wait) { -// printk(KERN_INFO "%s!\n",__func__); +static unsigned int firesat_ca_io_poll(struct file *file, poll_table *wait) +{ + if (ca_debug != 0) + printk(KERN_INFO "%s\n",__func__); return POLLIN; } @@ -68,7 +305,7 @@ static struct file_operations firesat_ca_fops = { .owner = THIS_MODULE, .read = NULL, // There is no low level read anymore .write = NULL, // There is no low level write anymore - .ioctl = firesat_ca_ioctl, + .ioctl = dvb_generic_ioctl, .open = firesat_ca_io_open, .release = firesat_ca_io_release, .poll = firesat_ca_io_poll, @@ -80,16 +317,37 @@ static struct dvb_device firesat_ca = { .readers = 1, .writers = 1, .fops = &firesat_ca_fops, + .kernel_ioctl = firesat_ca_ioctl, }; -int firesat_ca_init(struct firesat *firesat) { - int ret = dvb_register_device(firesat->adapter, &firesat->cadev, &firesat_ca, firesat, DVB_DEVICE_CA); - if(ret) return ret; +int firesat_ca_init(struct firesat *firesat) +{ + int err; + ANTENNA_INPUT_INFO info; - // avoid unnecessary delays, we're not talking to the CI yet anyways - return 0; + if (AVCTunerStatus(firesat, &info)) + return -EINVAL; + + if (firesat_ca_ready(&info)) { + err = dvb_register_device(firesat->adapter, + &firesat->cadev, + &firesat_ca, firesat, + DVB_DEVICE_CA); + + if (info.CaApplicationInfo == 0) + printk(KERN_ERR "%s: CaApplicationInfo is not set.\n", + __func__); + if (info.CaDateTimeRequest == 1) + firesat_get_date_time_request(firesat); + } + else + err = -EFAULT; + + return err; } -void firesat_ca_release(struct firesat *firesat) { +void firesat_ca_release(struct firesat *firesat) +{ + if (firesat->cadev) dvb_unregister_device(firesat->cadev); } diff --git a/drivers/media/dvb/firesat/firesat.h b/drivers/media/dvb/firesat/firesat.h index d1e2ce37063..1beed177d98 100644 --- a/drivers/media/dvb/firesat/firesat.h +++ b/drivers/media/dvb/firesat/firesat.h @@ -1,3 +1,15 @@ +/* + * FireSAT DVB driver + * + * Copyright (c) ? + * Copyright (c) 2008 Henrik Kurelid + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + #ifndef __FIRESAT_H #define __FIRESAT_H @@ -6,15 +18,108 @@ #include "dvb_demux.h" #include "dvb_net.h" +#include +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25) #include +#endif #include #include +#include + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25) +#define DVB_REGISTER_ADAPTER(x, y, z, w, v) dvb_register_adapter(x, y, z, w, v) +#else +#define DVB_REGISTER_ADAPTER(x, y, z, w, v) dvb_register_adapter(x, y, z, w) +#define DVB_DEFINE_MOD_OPT_ADAPTER_NR(x) +#endif + +/***************************************************************** + * CA message command constants from en50221_app_tags.h of libdvb + *****************************************************************/ +/* Resource Manager */ +#define TAG_PROFILE_ENQUIRY 0x9f8010 +#define TAG_PROFILE 0x9f8011 +#define TAG_PROFILE_CHANGE 0x9f8012 + +/* Application Info */ +#define TAG_APP_INFO_ENQUIRY 0x9f8020 +#define TAG_APP_INFO 0x9f8021 +#define TAG_ENTER_MENU 0x9f8022 + +/* CA Support */ +#define TAG_CA_INFO_ENQUIRY 0x9f8030 +#define TAG_CA_INFO 0x9f8031 +#define TAG_CA_PMT 0x9f8032 +#define TAG_CA_PMT_REPLY 0x9f8033 + +/* Host Control */ +#define TAG_TUNE 0x9f8400 +#define TAG_REPLACE 0x9f8401 +#define TAG_CLEAR_REPLACE 0x9f8402 +#define TAG_ASK_RELEASE 0x9f8403 + +/* Date and Time */ +#define TAG_DATE_TIME_ENQUIRY 0x9f8440 +#define TAG_DATE_TIME 0x9f8441 + +/* Man Machine Interface (MMI) */ +#define TAG_CLOSE_MMI 0x9f8800 +#define TAG_DISPLAY_CONTROL 0x9f8801 +#define TAG_DISPLAY_REPLY 0x9f8802 +#define TAG_TEXT_LAST 0x9f8803 +#define TAG_TEXT_MORE 0x9f8804 +#define TAG_KEYPAD_CONTROL 0x9f8805 +#define TAG_KEYPRESS 0x9f8806 +#define TAG_ENQUIRY 0x9f8807 +#define TAG_ANSWER 0x9f8808 +#define TAG_MENU_LAST 0x9f8809 +#define TAG_MENU_MORE 0x9f880a +#define TAG_MENU_ANSWER 0x9f880b +#define TAG_LIST_LAST 0x9f880c +#define TAG_LIST_MORE 0x9f880d +#define TAG_SUBTITLE_SEGMENT_LAST 0x9f880e +#define TAG_SUBTITLE_SEGMENT_MORE 0x9f880f +#define TAG_DISPLAY_MESSAGE 0x9f8810 +#define TAG_SCENE_END_MARK 0x9f8811 +#define TAG_SCENE_DONE 0x9f8812 +#define TAG_SCENE_CONTROL 0x9f8813 +#define TAG_SUBTITLE_DOWNLOAD_LAST 0x9f8814 +#define TAG_SUBTITLE_DOWNLOAD_MORE 0x9f8815 +#define TAG_FLUSH_DOWNLOAD 0x9f8816 +#define TAG_DOWNLOAD_REPLY 0x9f8817 + +/* Low Speed Communications */ +#define TAG_COMMS_COMMAND 0x9f8c00 +#define TAG_CONNECTION_DESCRIPTOR 0x9f8c01 +#define TAG_COMMS_REPLY 0x9f8c02 +#define TAG_COMMS_SEND_LAST 0x9f8c03 +#define TAG_COMMS_SEND_MORE 0x9f8c04 +#define TAG_COMMS_RECV_LAST 0x9f8c05 +#define TAG_COMMS_RECV_MORE 0x9f8c06 + +/* Authentication */ +#define TAG_AUTH_REQ 0x9f8200 +#define TAG_AUTH_RESP 0x9f8201 + +/* Teletext */ +#define TAG_TELETEXT_EBU 0x9f9000 + +/* Smartcard */ +#define TAG_SMARTCARD_COMMAND 0x9f8e00 +#define TAG_SMARTCARD_REPLY 0x9f8e01 +#define TAG_SMARTCARD_SEND 0x9f8e02 +#define TAG_SMARTCARD_RCV 0x9f8e03 + +/* EPG */ +#define TAG_EPG_ENQUIRY 0x9f8f00 +#define TAG_EPG_REPLY 0x9f8f01 + enum model_type { - FireSAT_DVB_S = 1, - FireSAT_DVB_C = 2, - FireSAT_DVB_T = 3, - FireSAT_DVB_S2 = 4 + FireSAT_DVB_S = 1, + FireSAT_DVB_C = 2, + FireSAT_DVB_T = 3, + FireSAT_DVB_S2 = 4 }; struct firesat { @@ -31,12 +136,13 @@ struct firesat { struct dvb_frontend *fe; struct dvb_device *cadev; - int has_ci; + int ca_last_command; + int ca_time_interval; struct semaphore avc_sem; - atomic_t avc_reply_received; + atomic_t avc_reply_received; - atomic_t reschedule_remotecontrol; + atomic_t reschedule_remotecontrol; struct firesat_channel { struct firesat *firesat; @@ -53,20 +159,54 @@ struct firesat { void *respfrm; int resp_length; -// nodeid_t nodeid; - struct hpsb_host *host; + struct hpsb_host *host; u64 guid; /* GUID of this node */ u32 guid_vendor_id; /* Top 24bits of guid */ struct node_entry *nodeentry; - enum model_type type; - char subunit; + enum model_type type; + char subunit; fe_sec_voltage_t voltage; fe_sec_tone_mode_t tone; int isochannel; + struct hpsb_iso *iso_handle; + + struct list_head list; +}; + +struct firewireheader { + union { + struct { + __u8 tcode:4; + __u8 sy:4; + __u8 tag:2; + __u8 channel:6; + + __u8 length_l; + __u8 length_h; + } hdr; + __u32 val; + }; +}; - struct list_head list; +struct CIPHeader { + union { + struct { + __u8 syncbits:2; + __u8 sid:6; + __u8 dbs; + __u8 fn:2; + __u8 qpc:3; + __u8 sph:1; + __u8 rsv:2; + __u8 dbc; + __u8 syncbits2:2; + __u8 fmt:6; + __u32 fdf:24; + } cip; + __u64 val; + }; }; extern struct list_head firesat_list; @@ -76,11 +216,15 @@ extern spinlock_t firesat_list_lock; extern int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed); extern int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed); extern int firesat_dvbdev_init(struct firesat *firesat, - struct device *dev, - struct dvb_frontend *fe); + struct device *dev, + struct dvb_frontend *fe); /* firesat_fe.c */ -extern int firesat_frontend_attach(struct firesat *firesat, struct dvb_frontend *fe); +extern int firesat_frontend_attach(struct firesat *firesat, + struct dvb_frontend *fe); +/* firesat_iso.c */ +extern int setup_iso_channel(struct firesat *firesat); +extern void tear_down_iso_channel(struct firesat *firesat); #endif diff --git a/drivers/media/dvb/firesat/firesat_1394.c b/drivers/media/dvb/firesat/firesat_1394.c index dcac70a2991..04ad31666fb 100644 --- a/drivers/media/dvb/firesat/firesat_1394.c +++ b/drivers/media/dvb/firesat/firesat_1394.c @@ -3,6 +3,7 @@ * * Copyright (c) 2004 Andreas Monitzer * Copyright (c) 2007-2008 Ben Backx + * Copyright (c) 2008 Henrik Kurelid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -18,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -79,11 +79,6 @@ static void firesat_add_host(struct hpsb_host *host); static void firesat_remove_host(struct hpsb_host *host); static void firesat_host_reset(struct hpsb_host *host); -/* -static void iso_receive(struct hpsb_host *host, int channel, quadlet_t *data, - size_t length); -*/ - static void fcp_request(struct hpsb_host *host, int nodeid, int direction, @@ -96,7 +91,6 @@ static struct hpsb_highlevel firesat_highlevel = { .add_host = firesat_add_host, .remove_host = firesat_remove_host, .host_reset = firesat_host_reset, -// FIXME .iso_receive = iso_receive, .fcp_request = fcp_request, }; @@ -127,100 +121,6 @@ static void firesat_host_reset(struct hpsb_host *host) printk(KERN_INFO "FireSAT host_reset (nodeid = 0x%x, hosts active = %d)\n",host->node_id,host->nodes_active); } -struct firewireheader { - union { - struct { - unsigned char tcode:4; - unsigned char sy:4; - unsigned char tag:2; - unsigned char channel:6; - - unsigned char length_l; - unsigned char length_h; - } hdr; - unsigned long val; - }; -}; - -struct CIPHeader { - union { - struct { - unsigned char syncbits:2; - unsigned char sid:6; - unsigned char dbs; - unsigned char fn:2; - unsigned char qpc:3; - unsigned char sph:1; - unsigned char rsv:2; - unsigned char dbc; - unsigned char syncbits2:2; - unsigned char fmt:6; - unsigned long fdf:24; - } cip; - unsigned long long val; - }; -}; - -struct MPEG2Header { - union { - struct { - unsigned char sync; // must be 0x47 - unsigned char transport_error_indicator:1; - unsigned char payload_unit_start_indicator:1; - unsigned char transport_priority:1; - unsigned short pid:13; - unsigned char transport_scrambling_control:2; - unsigned char adaption_field_control:2; - unsigned char continuity_counter:4; - } hdr; - unsigned long val; - }; -}; - -#if 0 -static void iso_receive(struct hpsb_host *host, - int channel, - quadlet_t *data, - size_t length) -{ - struct firesat *firesat = NULL; - struct firesat *firesat_entry; - unsigned long flags; - -// printk(KERN_INFO "FireSAT iso_receive: channel %d, length = %d\n", channel, length); - - if (length <= 12) - return; // ignore empty packets - else { - - spin_lock_irqsave(&firesat_list_lock, flags); - list_for_each_entry(firesat_entry,&firesat_list,list) { - if(firesat_entry->host == host && firesat_entry->isochannel == channel) { - firesat=firesat_entry; - break; - } - } - spin_unlock_irqrestore(&firesat_list_lock, flags); - - if (firesat) { - char *buf= ((char*)data) + sizeof(struct firewireheader)+sizeof(struct CIPHeader); - int count = (length-sizeof(struct CIPHeader)) / 192; - -// printk(KERN_INFO "%s: length = %u\n data[0] = %08x\n data[1] = %08x\n data[2] = %08x\n data[3] = %08x\n data[4] = %08x\n",__func__, length, data[0],data[1],data[2],data[3],data[4]); - - while (count--) { - - if (buf[sizeof(quadlet_t) /*timestamp*/] == 0x47) - dvb_dmx_swfilter_packets(&firesat->demux, &buf[sizeof(quadlet_t)], 1); - else - printk("%s: invalid packet, skipping\n", __func__); - buf += 188 + sizeof (quadlet_t) /* timestamp */; - } - } - } -} -#endif - static void fcp_request(struct hpsb_host *host, int nodeid, int direction, @@ -251,7 +151,9 @@ static void fcp_request(struct hpsb_host *host, AVCRecv(firesat,data,length); else printk("%s: received fcp request from unknown source, ignored\n", __func__); - } // else ignore + } + else + printk("%s: received invalid fcp request, ignored\n", __func__); } static int firesat_probe(struct device *dev) @@ -260,7 +162,6 @@ static int firesat_probe(struct device *dev) struct firesat *firesat; struct dvb_frontend *fe; unsigned long flags; - int result; unsigned char subunitcount = 0xff, subunit; struct firesat **firesats = kmalloc(sizeof (void*) * 2,GFP_KERNEL); int kv_len; @@ -298,6 +199,7 @@ static int firesat_probe(struct device *dev) firesat->isochannel = -1; firesat->tone = 0xff; firesat->voltage = 0xff; + firesat->fe = fe; if (!(firesat->respfrm = kmalloc(sizeof (AVCRspFrm), GFP_KERNEL))) { printk("%s: couldn't allocate memory.\n", __func__); @@ -357,7 +259,7 @@ static int firesat_probe(struct device *dev) } kfree(kv_buf); - if (AVCIdentifySubunit(firesat, NULL, (int*)&firesat->type, &firesat->has_ci)) { + if (AVCIdentifySubunit(firesat, NULL, (int*)&firesat->type)) { printk("%s: cannot identify subunit %d\n", __func__, subunit); spin_lock_irqsave(&firesat_list_lock, flags); list_del(&firesat->list); @@ -382,7 +284,6 @@ static int firesat_probe(struct device *dev) static int firesat_remove(struct device *dev) { struct unit_directory *ud = container_of(dev, struct unit_directory, device); - struct dvb_frontend* fe; struct firesat **firesats = ud->device.driver_data; int k; unsigned long flags; @@ -390,18 +291,9 @@ static int firesat_remove(struct device *dev) if (firesats) { for (k = 0; k < 2; k++) if (firesats[k]) { - if (firesats[k]->has_ci) firesat_ca_release(firesats[k]); -#if 0 - if (!(fe = kmalloc(sizeof (struct dvb_frontend), GFP_KERNEL))) { - fe->ops = firesat_ops; - fe->dvb = firesats[k]->adapter; - - dvb_unregister_frontend(fe); - kfree(fe); - } -#endif + dvb_unregister_frontend(firesats[k]->fe); dvb_net_release(&firesats[k]->dvbnet); firesats[k]->demux.dmx.close(&firesats[k]->demux.dmx); firesats[k]->demux.dmx.remove_frontend(&firesats[k]->demux.dmx, &firesats[k]->frontend); @@ -413,6 +305,7 @@ static int firesat_remove(struct device *dev) list_del(&firesats[k]->list); spin_unlock_irqrestore(&firesat_list_lock, flags); + kfree(firesats[k]->fe); kfree(firesats[k]->adapter); kfree(firesats[k]->respfrm); kfree(firesats[k]); diff --git a/drivers/media/dvb/firesat/firesat_dvb.c b/drivers/media/dvb/firesat/firesat_dvb.c index 38aad081288..9e87402289a 100644 --- a/drivers/media/dvb/firesat/firesat_dvb.c +++ b/drivers/media/dvb/firesat/firesat_dvb.c @@ -1,3 +1,15 @@ +/* + * FireSAT DVB driver + * + * Copyright (c) ? + * Copyright (c) 2008 Henrik Kurelid + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + #include #include #include @@ -6,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -26,13 +37,13 @@ static struct firesat_channel *firesat_channel_allocate(struct firesat *firesat) { int k; - printk(KERN_INFO "%s\n", __func__); + //printk(KERN_INFO "%s\n", __func__); if (down_interruptible(&firesat->demux_sem)) return NULL; for (k = 0; k < 16; k++) { - printk(KERN_INFO "%s: channel %d: active = %d, pid = 0x%x\n",__func__,k,firesat->channel[k].active,firesat->channel[k].pid); + //printk(KERN_INFO "%s: channel %d: active = %d, pid = 0x%x\n",__func__,k,firesat->channel[k].active,firesat->channel[k].pid); if (firesat->channel[k].active == 0) { firesat->channel[k].active = 1; @@ -82,14 +93,15 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed) int pidc,k; u16 pids[16]; - printk(KERN_INFO "%s (pid %u)\n",__func__,dvbdmxfeed->pid); +// printk(KERN_INFO "%s (pid %u)\n", __func__, dvbdmxfeed->pid); switch (dvbdmxfeed->type) { case DMX_TYPE_TS: case DMX_TYPE_SEC: break; default: - printk("%s: invalid type %u\n",__func__,dvbdmxfeed->type); + printk(KERN_ERR "%s: invalid type %u\n", + __func__, dvbdmxfeed->type); return -EINVAL; } @@ -110,7 +122,8 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed) channel = firesat_channel_allocate(firesat); break; default: - printk("%s: invalid pes type %u\n",__func__, dvbdmxfeed->pes_type); + printk(KERN_ERR "%s: invalid pes type %u\n", + __func__, dvbdmxfeed->pes_type); return -EINVAL; } } else { @@ -118,7 +131,7 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed) } if (!channel) { - printk("%s: busy!\n", __func__); + printk(KERN_ERR "%s: busy!\n", __func__); return -EBUSY; } @@ -131,22 +144,23 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed) if (firesat_channel_collect(firesat, &pidc, pids)) { firesat_channel_release(firesat, channel); + printk(KERN_ERR "%s: could not collect pids!\n", __func__); return -EINTR; } if(dvbdmxfeed->pid == 8192) { - if((k=AVCTuner_GetTS(firesat))) { + if((k = AVCTuner_GetTS(firesat))) { firesat_channel_release(firesat, channel); printk("%s: AVCTuner_GetTS failed with error %d\n", - __func__,k); + __func__, k); return k; } } else { - if((k=AVCTuner_SetPIDs(firesat, pidc, pids))) { + if((k = AVCTuner_SetPIDs(firesat, pidc, pids))) { firesat_channel_release(firesat, channel); printk("%s: AVCTuner_SetPIDs failed with error %d\n", - __func__,k); + __func__, k); return k; } } @@ -161,7 +175,7 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed) int k, l = 0; u16 pids[16]; - printk(KERN_INFO "%s (pid %u)\n", __func__, dvbdmxfeed->pid); + //printk(KERN_INFO "%s (pid %u)\n", __func__, dvbdmxfeed->pid); if (dvbdmxfeed->type == DMX_TYPE_TS && !((dvbdmxfeed->ts_type & TS_PACKET) && (demux->dmx.frontend->source != DMX_MEMORY_FE))) { @@ -189,12 +203,13 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed) // list except channel to be removed for (k = 0; k < 16; k++) - if (firesat->channel[k].active == 1) + if (firesat->channel[k].active == 1) { if (&firesat->channel[k] != (struct firesat_channel *)dvbdmxfeed->priv) pids[l++] = firesat->channel[k].pid; else firesat->channel[k].active = 0; + } if ((k = AVCTuner_SetPIDs(firesat, l, pids))) { up(&firesat->demux_sem); @@ -214,8 +229,6 @@ int firesat_dvbdev_init(struct firesat *firesat, { int result; - firesat->has_ci = 1; // TEMP workaround - #if 0 switch (firesat->type) { case FireSAT_DVB_S: @@ -254,7 +267,7 @@ int firesat_dvbdev_init(struct firesat *firesat, return -ENOMEM; } - if ((result = dvb_register_adapter(firesat->adapter, + if ((result = DVB_REGISTER_ADAPTER(firesat->adapter, firesat->model_name, THIS_MODULE, dev, adapter_nr)) < 0) { @@ -271,6 +284,7 @@ int firesat_dvbdev_init(struct firesat *firesat, return result; } + memset(&firesat->demux, 0, sizeof(struct dvb_demux)); firesat->demux.dmx.capabilities = 0/*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/; firesat->demux.priv = (void *)firesat; @@ -343,8 +357,9 @@ int firesat_dvbdev_init(struct firesat *firesat, return result; } - if (firesat->has_ci) firesat_ca_init(firesat); return 0; } + + diff --git a/drivers/media/dvb/firesat/firesat_fe.c b/drivers/media/dvb/firesat/firesat_fe.c index f7abd38f001..1c86c3e6137 100644 --- a/drivers/media/dvb/firesat/firesat_fe.c +++ b/drivers/media/dvb/firesat/firesat_fe.c @@ -1,3 +1,15 @@ +/* + * FireSAT DVB driver + * + * Copyright (c) ? + * Copyright (c) 2008 Henrik Kurelid + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + #include #include #include @@ -6,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -22,22 +33,29 @@ static int firesat_dvb_init(struct dvb_frontend *fe) { + int result; struct firesat *firesat = fe->sec_priv; - printk("fdi: 1\n"); +// printk("fdi: 1\n"); firesat->isochannel = firesat->adapter->num; //<< 1 | (firesat->subunit & 0x1); // ### ask IRM - printk("fdi: 2\n"); - try_CMPEstablishPPconnection(firesat, firesat->subunit, firesat->isochannel); - printk("fdi: 3\n"); -//FIXME hpsb_listen_channel(&firesat_highlevel, firesat->host, firesat->isochannel); - printk("fdi: 4\n"); - return 0; +// printk("fdi: 2\n"); + result = try_CMPEstablishPPconnection(firesat, firesat->subunit, firesat->isochannel); + if (result != 0) { + printk(KERN_ERR "Could not establish point to point " + "connection.\n"); + return -1; + } +// printk("fdi: 3\n"); + + result = setup_iso_channel(firesat); +// printk("fdi: 4. Result was %d\n", result); + return result; } static int firesat_sleep(struct dvb_frontend *fe) { struct firesat *firesat = fe->sec_priv; -//FIXME hpsb_unlisten_channel(&firesat_highlevel, firesat->host, firesat->isochannel); + tear_down_iso_channel(firesat); try_CMPBreakPPconnection(firesat, firesat->subunit, firesat->isochannel); firesat->isochannel = -1; return 0; @@ -83,19 +101,20 @@ static int firesat_read_status (struct dvb_frontend *fe, fe_status_t *status) if (AVCTunerStatus(firesat, &info)) return -EINVAL; - if (info.NoRF) + if (info.NoRF) { *status = 0; - else - *status = *status = FE_HAS_SIGNAL | - FE_HAS_VITERBI | - FE_HAS_SYNC | - FE_HAS_CARRIER | - FE_HAS_LOCK; + } else { + *status = FE_HAS_SIGNAL | + FE_HAS_VITERBI | + FE_HAS_SYNC | + FE_HAS_CARRIER | + FE_HAS_LOCK; + } return 0; } -static int firesat_read_ber (struct dvb_frontend *fe, u32 *ber) +static int firesat_read_ber(struct dvb_frontend *fe, u32 *ber) { struct firesat *firesat = fe->sec_priv; ANTENNA_INPUT_INFO info; @@ -103,10 +122,10 @@ static int firesat_read_ber (struct dvb_frontend *fe, u32 *ber) if (AVCTunerStatus(firesat, &info)) return -EINVAL; - *ber = ((info.BER[0] << 24) & 0xff) | - ((info.BER[1] << 16) & 0xff) | - ((info.BER[2] << 8) & 0xff) | - (info.BER[3] & 0xff); + *ber = (info.BER[0] << 24) | + (info.BER[1] << 16) | + (info.BER[2] << 8) | + info.BER[3]; return 0; } @@ -115,19 +134,29 @@ static int firesat_read_signal_strength (struct dvb_frontend *fe, u16 *strength) { struct firesat *firesat = fe->sec_priv; ANTENNA_INPUT_INFO info; - u16 *signal = strength; if (AVCTunerStatus(firesat, &info)) return -EINVAL; - *signal = info.SignalStrength; + *strength = info.SignalStrength << 8; return 0; } static int firesat_read_snr(struct dvb_frontend *fe, u16 *snr) { - return -EOPNOTSUPP; + struct firesat *firesat = fe->sec_priv; + ANTENNA_INPUT_INFO info; + + if (AVCTunerStatus(firesat, &info)) + return -EINVAL; + + *snr = (info.CarrierNoiseRatio[0] << 8) + + info.CarrierNoiseRatio[1]; + *snr *= 257; + // C/N[dB] = -10 * log10(snr / 65535) + + return 0; } static int firesat_read_uncorrected_blocks(struct dvb_frontend *fe, u32 *ucblocks) @@ -192,14 +221,13 @@ int firesat_frontend_attach(struct firesat *firesat, struct dvb_frontend *fe) firesat->frontend_info = &firesat_T_frontend_info; break; default: -// printk("%s: unknown model type 0x%x on subunit %d!\n", -// __func__, firesat->type,subunit); printk("%s: unknown model type 0x%x !\n", __func__, firesat->type); firesat->model_name = "Unknown"; firesat->frontend_info = NULL; } fe->ops = firesat_ops; + fe->ops.info = *(firesat->frontend_info); fe->dvb = firesat->adapter; return 0; diff --git a/drivers/media/dvb/firesat/firesat_iso.c b/drivers/media/dvb/firesat/firesat_iso.c new file mode 100644 index 00000000000..15e23cf7d50 --- /dev/null +++ b/drivers/media/dvb/firesat/firesat_iso.c @@ -0,0 +1,106 @@ +/* + * FireSAT DVB driver + * + * Copyright (c) 2008 Henrik Kurelid + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#include "firesat.h" + +static void rawiso_activity_cb(struct hpsb_iso *iso); + +void tear_down_iso_channel(struct firesat *firesat) +{ + if (firesat->iso_handle != NULL) { + hpsb_iso_stop(firesat->iso_handle); + hpsb_iso_shutdown(firesat->iso_handle); + } + firesat->iso_handle = NULL; +} + +int setup_iso_channel(struct firesat *firesat) +{ + int result; + firesat->iso_handle = + hpsb_iso_recv_init(firesat->host, + 256 * 200, //data_buf_size, + 256, //buf_packets, + firesat->isochannel, + HPSB_ISO_DMA_DEFAULT, //dma_mode, + -1, //stat.config.irq_interval, + rawiso_activity_cb); + if (firesat->iso_handle == NULL) { + printk(KERN_ERR "Cannot initialize iso receive.\n"); + return -EINVAL; + } + result = hpsb_iso_recv_start(firesat->iso_handle, -1, -1, 0); + if (result != 0) { + printk(KERN_ERR "Cannot start iso receive.\n"); + return -EINVAL; + } + return 0; +} + +static void rawiso_activity_cb(struct hpsb_iso *iso) +{ + unsigned int num; + unsigned int i; +/* unsigned int j; */ + unsigned int packet; + unsigned long flags; + struct firesat *firesat = NULL; + struct firesat *firesat_iterator; + + spin_lock_irqsave(&firesat_list_lock, flags); + list_for_each_entry(firesat_iterator, &firesat_list, list) { + if(firesat_iterator->iso_handle == iso) { + firesat = firesat_iterator; + break; + } + } + spin_unlock_irqrestore(&firesat_list_lock, flags); + + if (firesat) { + packet = iso->first_packet; + num = hpsb_iso_n_ready(iso); + for (i = 0; i < num; i++, + packet = (packet + 1) % iso->buf_packets) { + unsigned char *buf = + dma_region_i(&iso->data_buf, unsigned char, + iso->infos[packet].offset + + sizeof(struct CIPHeader)); + int count = (iso->infos[packet].len - + sizeof(struct CIPHeader)) / + (188 + sizeof(struct firewireheader)); + if (iso->infos[packet].len <= sizeof(struct CIPHeader)) + continue; // ignore empty packet +/* printk("%s: Handling packets (%d): ", __func__, */ +/* iso->infos[packet].len); */ +/* for (j = 0; j < iso->infos[packet].len - */ +/* sizeof(struct CIPHeader); j++) */ +/* printk("%02X,", buf[j]); */ +/* printk("\n"); */ + while (count --) { + if (buf[sizeof(struct firewireheader)] == 0x47) + dvb_dmx_swfilter_packets(&firesat->demux, + &buf[sizeof(struct firewireheader)], 1); + else + printk("%s: invalid packet, skipping\n", __func__); + buf += 188 + sizeof(struct firewireheader); + + } + + } + hpsb_iso_recv_release_packets(iso, num); + } + else { + printk("%s: packets for unknown iso channel, skipping\n", + __func__); + hpsb_iso_recv_release_packets(iso, hpsb_iso_n_ready(iso)); + } +} + -- cgit From 81c67b7f82769292a86b802590be5879413f9278 Mon Sep 17 00:00:00 2001 From: Henrik Kurelid Date: Sun, 24 Aug 2008 15:20:07 +0200 Subject: firesat: avc resend - Add resending of AVC message to the card if no answer is received - Replace the homebrewed event_wait function with a standard wait queue - Clean up of log/error messages - Increase debug level of avc communication Signed-off-by: Henrik Kurelid Signed-off-by: Stefan Richter --- drivers/media/dvb/firesat/avc_api.c | 173 +++++++++++++++++-------------- drivers/media/dvb/firesat/firesat.h | 1 + drivers/media/dvb/firesat/firesat_1394.c | 1 + 3 files changed, 95 insertions(+), 80 deletions(-) diff --git a/drivers/media/dvb/firesat/avc_api.c b/drivers/media/dvb/firesat/avc_api.c index 273c7235dd9..3c8e7e3dacc 100644 --- a/drivers/media/dvb/firesat/avc_api.c +++ b/drivers/media/dvb/firesat/avc_api.c @@ -26,7 +26,7 @@ static unsigned int avc_comm_debug = 0; module_param(avc_comm_debug, int, 0644); -MODULE_PARM_DESC(avc_comm_debug, "debug logging of AV/C communication, default is 0 (no)"); +MODULE_PARM_DESC(avc_comm_debug, "debug logging level [0..2] of AV/C communication, default is 0 (no)"); static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal); @@ -37,22 +37,6 @@ static void avc_free_packet(struct hpsb_packet *packet) hpsb_free_packet(packet); } -/* - * Goofy routine that basically does a down_timeout function. - * Stolen from sbp2.c - */ -static int avc_down_timeout(atomic_t *done, int timeout) -{ - int i; - - for (i = timeout; (i > 0 && atomic_read(done) == 0); i-= HZ/10) { - set_current_state(TASK_INTERRUPTIBLE); - if (schedule_timeout(HZ/10)) /* 100ms */ - return(1); - } - return ((i > 0) ? 0:1); -} - static const char* get_ctype_string(__u8 ctype) { switch(ctype) @@ -135,97 +119,115 @@ static void log_command_frame(const AVCCmdFrm *CmdFrm) { int k; printk(KERN_INFO "AV/C Command Frame:\n"); - printk("CommandType=%s, Address=%s(0x%02X,0x%02X), opcode=%s(0x%02X), " - "length=%d\n", get_ctype_string(CmdFrm->ctype), + printk(KERN_INFO "CommandType=%s, Address=%s(0x%02X,0x%02X), " + "opcode=%s(0x%02X), length=%d\n", + get_ctype_string(CmdFrm->ctype), get_subunit_address(CmdFrm->suid, CmdFrm->sutyp), CmdFrm->suid, CmdFrm->sutyp, get_opcode_string(CmdFrm->opcode), CmdFrm->opcode, CmdFrm->length); - for(k = 0; k < CmdFrm->length - 3; k++) { - if (k % 5 != 0) - printk(", "); - else if (k != 0) - printk("\n"); - printk("operand[%d] = %02X", k, CmdFrm->operand[k]); + if (avc_comm_debug > 1) { + for(k = 0; k < CmdFrm->length - 3; k++) { + if (k % 5 != 0) + printk(", "); + else if (k != 0) + printk("\n"); + printk(KERN_INFO "operand[%d] = %02X", k, + CmdFrm->operand[k]); + } + printk(KERN_INFO "\n"); } - printk("\n"); } static void log_response_frame(const AVCRspFrm *RspFrm) { int k; printk(KERN_INFO "AV/C Response Frame:\n"); - printk("Response=%s, Address=%s(0x%02X,0x%02X), opcode=%s(0x%02X), " - "length=%d\n", get_resp_string(RspFrm->resp), + printk(KERN_INFO "Response=%s, Address=%s(0x%02X,0x%02X), " + "opcode=%s(0x%02X), length=%d\n", get_resp_string(RspFrm->resp), get_subunit_address(RspFrm->suid, RspFrm->sutyp), RspFrm->suid, RspFrm->sutyp, get_opcode_string(RspFrm->opcode), RspFrm->opcode, RspFrm->length); - for(k = 0; k < RspFrm->length - 3; k++) { - if (k % 5 != 0) - printk(", "); - else if (k != 0) - printk("\n"); - printk("operand[%d] = %02X", k, RspFrm->operand[k]); + if (avc_comm_debug > 1) { + for(k = 0; k < RspFrm->length - 3; k++) { + if (k % 5 != 0) + printk(KERN_INFO ", "); + else if (k != 0) + printk(KERN_INFO "\n"); + printk(KERN_INFO "operand[%d] = %02X", k, + RspFrm->operand[k]); + } + printk(KERN_INFO "\n"); } - printk("\n"); } static int __AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) { struct hpsb_packet *packet; struct node_entry *ne; + int num_tries = 0; + int packet_ok = 0; ne = firesat->nodeentry; if(!ne) { - printk("%s: lost node!\n",__func__); + printk(KERN_ERR "%s: lost node!\n",__func__); return -EIO; } /* need all input data */ if(!firesat || !ne || !CmdFrm) { - printk("%s: missing input data!\n",__func__); + printk(KERN_ERR "%s: missing input data!\n",__func__); return -EINVAL; } - if (avc_comm_debug == 1) { + if (avc_comm_debug > 0) { log_command_frame(CmdFrm); } if(RspFrm) atomic_set(&firesat->avc_reply_received, 0); - packet=hpsb_make_writepacket(ne->host, ne->nodeid, - COMMAND_REGISTER, - (quadlet_t*)CmdFrm, - CmdFrm->length); - hpsb_set_packet_complete_task(packet, - (void (*)(void*))avc_free_packet, - packet); - hpsb_node_fill_packet(ne, packet); - - if (hpsb_send_packet(packet) < 0) { - avc_free_packet(packet); - atomic_set(&firesat->avc_reply_received, 1); - printk("%s: send failed!\n",__func__); - return -EIO; - } - - if(RspFrm) { - // AV/C specs say that answers should be send within - // 150 ms so let's time out after 200 ms - if(avc_down_timeout(&firesat->avc_reply_received, - HZ / 5)) { - printk("%s: timeout waiting for avc response\n", - __func__); + while (packet_ok == 0 && num_tries < 6) { + num_tries++; + packet_ok = 1; + packet = hpsb_make_writepacket(ne->host, ne->nodeid, + COMMAND_REGISTER, + (quadlet_t*)CmdFrm, + CmdFrm->length); + hpsb_set_packet_complete_task(packet, + (void (*)(void*))avc_free_packet, + packet); + hpsb_node_fill_packet(ne, packet); + + if (hpsb_send_packet(packet) < 0) { + avc_free_packet(packet); atomic_set(&firesat->avc_reply_received, 1); - return -ETIMEDOUT; + printk(KERN_ERR "%s: send failed!\n",__func__); + return -EIO; } - memcpy(RspFrm, firesat->respfrm, - firesat->resp_length); - RspFrm->length = firesat->resp_length; - if (avc_comm_debug == 1) { - log_response_frame(RspFrm); + + if(RspFrm) { + // AV/C specs say that answers should be send within + // 150 ms so let's time out after 200 ms + if (wait_event_timeout(firesat->avc_wait, + atomic_read(&firesat->avc_reply_received) == 1, + HZ / 5) == 0) { + packet_ok = 0; + } + else { + memcpy(RspFrm, firesat->respfrm, + firesat->resp_length); + RspFrm->length = firesat->resp_length; + if (avc_comm_debug > 0) { + log_response_frame(RspFrm); + } + } } } + if (packet_ok == 0) { + printk(KERN_ERR "%s: AV/C response timed out 6 times.\n", + __func__); + return -ETIMEDOUT; + } return 0; } @@ -292,7 +294,8 @@ int AVCRecv(struct firesat *firesat, u8 *data, size_t length) { } #endif if(atomic_read(&firesat->avc_reply_received) == 1) { - printk("%s: received out-of-order AVC response, ignored\n",__func__); + printk(KERN_ERR "%s: received out-of-order AVC response, " + "ignored\n",__func__); return -EINVAL; } // AVCRspFrm *resp=(AVCRspFrm *)data; @@ -312,6 +315,7 @@ int AVCRecv(struct firesat *firesat, u8 *data, size_t length) { firesat->resp_length=length; atomic_set(&firesat->avc_reply_received, 1); + wake_up(&firesat->avc_wait); return 0; } @@ -740,11 +744,12 @@ int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *tr return -EIO; if(RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) { - printk("%s: AVCWrite returned error code %d\n",__func__,RspFrm.resp); + printk(KERN_ERR "%s: AVCWrite returned error code %d\n", + __func__, RspFrm.resp); return -EINVAL; } if(((RspFrm.operand[3] << 8) + RspFrm.operand[4]) != 8) { - printk("%s: Invalid response length\n",__func__); + printk(KERN_ERR "%s: Invalid response length\n", __func__); return -EINVAL; } if(systemId) @@ -777,7 +782,8 @@ int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_in return -EIO; if(RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) { - printk("%s: AVCWrite returned code %d\n",__func__,RspFrm.resp); + printk(KERN_ERR "%s: AVCWrite returned code %d\n", + __func__, RspFrm.resp); return -EINVAL; } @@ -788,7 +794,8 @@ int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_in sizeof(ANTENNA_INPUT_INFO)); return 0; } - printk("%s: invalid info returned from AVC\n",__func__); + printk(KERN_ERR "%s: invalid tuner status (op=%d,length=%d) returned " + "from AVC\n", __func__, RspFrm.operand[1], length); return -EINVAL; } @@ -800,7 +807,8 @@ int AVCLNBControl(struct firesat *firesat, char voltage, char burst, AVCRspFrm RspFrm; int i,j; - printk(KERN_INFO "%s: voltage = %x, burst = %x, conttone = %x\n",__func__,voltage,burst,conttone); + printk(KERN_INFO "%s: voltage = %x, burst = %x, conttone = %x\n", + __func__, voltage, burst, conttone); memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); @@ -822,11 +830,13 @@ int AVCLNBControl(struct firesat *firesat, char voltage, char burst, for(j=0;javc_sem, 1); + init_waitqueue_head(&firesat->avc_wait); atomic_set(&firesat->avc_reply_received, 1); sema_init(&firesat->demux_sem, 1); atomic_set(&firesat->reschedule_remotecontrol, 0); -- cgit From 612262a53352af839a14b3395975a3440c95080a Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Tue, 26 Aug 2008 00:17:30 +0200 Subject: firesat: copyrights, rename to firedtv, API conversions, fix remote control input Combination of the following changes: Tue, 26 Aug 2008 00:17:30 +0200 (CEST) firedtv: fix remote control input and update the scancode-to-keycode mapping to a current model. Per default, various media key keycodes are emitted which closely match what is printed on the remote. Userland can modify the mapping by means of evdev ioctls. (Not tested.) The old scancode-to-keycode mapping is left in the driver but cannot be modified by ioctls. This preserves status quo for old remotes. Tue, 26 Aug 2008 00:11:28 +0200 (CEST) firedtv: replace tasklet by workqueue job Non-atomic context is a lot nicer to work with. Sun, 24 Aug 2008 23:30:00 +0200 (CEST) firedtv: move some code back to ieee1394 core Partially reverts "ieee1394: remove unused code" of Linux 2.6.25. Sun, 24 Aug 2008 23:29:30 +0200 (CEST) firedtv: replace semaphore by mutex firesat->avc_sem and ->demux_sem have been used exactly like a mutex. The only exception is the schedule_remotecontrol tasklet which did a down_trylock in atomic context. This is not possible with mutex_trylock; however the whole remote control related code is non-functional anyway at the moment. This should be fixed eventually, probably by turning the tasklet into a worqueue job. Convert everything else from semaphore to mutex. Also rewrite a few of the affected functions to unlock the mutex at a single exit point, instead of in several branches. Sun, 24 Aug 2008 23:28:45 +0200 (CEST) firedtv: some header cleanups Unify #ifndef/#define/#endif guards against multiple inclusion. Drop extern keyword from function declarations. Remove #include's into header files where struct declarations suffice. Remove unused ohci1394 interface and related unused ieee1394 interfaces. Add a few missing #include's and remove a few apparently obsolete ones. Sort them alphabetically. Sun, 24 Aug 2008 23:27:45 +0200 (CEST) firedtv: nicer registration message and some initialization fixes Print the correct name in dvb_register_adapter(). While we are at it, replace two switch cascades by one for loop, remove a superfluous member of struct firesat and of two unused arguments of AVCIdentifySubunit(), and fix bogus kfree's in firesat_dvbdev_init(). Tue, 26 Aug 2008 14:24:17 +0200 (CEST) firesat: rename to firedtv Suggested by Andreas Monitzer. Besides DVB-S/-S2 receivers, the driver also supports DVB-C and DVB-T receivers, hence the previous project name is too narrow now. Not yet done: Rename source directory, files, types, variables... Sun, 24 Aug 2008 23:26:23 +0200 (CEST) firesat: add missing copyright notes Reported by Andreas Monitzer and Christian Dolzer. Signed-off-by: Stefan Richter --- drivers/ieee1394/dma.h | 1 + drivers/ieee1394/ieee1394_core.c | 1 + drivers/ieee1394/ieee1394_transactions.c | 29 ++++++ drivers/ieee1394/ieee1394_transactions.h | 2 + drivers/ieee1394/iso.h | 1 + drivers/media/dvb/Makefile | 2 +- drivers/media/dvb/firesat/Kconfig | 13 +-- drivers/media/dvb/firesat/Makefile | 4 +- drivers/media/dvb/firesat/avc_api.c | 121 +++++++++-------------- drivers/media/dvb/firesat/avc_api.h | 115 +++++++++++----------- drivers/media/dvb/firesat/cmp.c | 99 ++++++------------- drivers/media/dvb/firesat/cmp.h | 14 +-- drivers/media/dvb/firesat/firesat-ci.c | 16 +-- drivers/media/dvb/firesat/firesat-ci.h | 8 +- drivers/media/dvb/firesat/firesat-rc.c | 147 +++++++++++++++++++++------ drivers/media/dvb/firesat/firesat-rc.h | 13 ++- drivers/media/dvb/firesat/firesat.h | 78 ++++++++------- drivers/media/dvb/firesat/firesat_1394.c | 164 +++++++++++++------------------ drivers/media/dvb/firesat/firesat_dvb.c | 147 +++++++++------------------ drivers/media/dvb/firesat/firesat_fe.c | 41 +++----- drivers/media/dvb/firesat/firesat_iso.c | 12 ++- 21 files changed, 502 insertions(+), 526 deletions(-) diff --git a/drivers/ieee1394/dma.h b/drivers/ieee1394/dma.h index 2727bcd2419..467373cab8e 100644 --- a/drivers/ieee1394/dma.h +++ b/drivers/ieee1394/dma.h @@ -12,6 +12,7 @@ #include +struct file; struct pci_dev; struct scatterlist; struct vm_area_struct; diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c index 2beb8d94f7b..1028e725a27 100644 --- a/drivers/ieee1394/ieee1394_core.c +++ b/drivers/ieee1394/ieee1394_core.c @@ -1314,6 +1314,7 @@ EXPORT_SYMBOL(hpsb_make_lock64packet); EXPORT_SYMBOL(hpsb_make_phypacket); EXPORT_SYMBOL(hpsb_read); EXPORT_SYMBOL(hpsb_write); +EXPORT_SYMBOL(hpsb_lock); EXPORT_SYMBOL(hpsb_packet_success); /** highlevel.c **/ diff --git a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c index 10c3d9f8c03..24021d2f0a7 100644 --- a/drivers/ieee1394/ieee1394_transactions.c +++ b/drivers/ieee1394/ieee1394_transactions.c @@ -570,3 +570,32 @@ int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation, return retval; } + +int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation, + u64 addr, int extcode, quadlet_t *data, quadlet_t arg) +{ + struct hpsb_packet *packet; + int retval = 0; + + BUG_ON(in_interrupt()); + + packet = hpsb_make_lockpacket(host, node, addr, extcode, data, arg); + if (!packet) + return -ENOMEM; + + packet->generation = generation; + retval = hpsb_send_packet_and_wait(packet); + if (retval < 0) + goto hpsb_lock_fail; + + retval = hpsb_packet_success(packet); + + if (retval == 0) + *data = packet->data[0]; + +hpsb_lock_fail: + hpsb_free_tlabel(packet); + hpsb_free_packet(packet); + + return retval; +} diff --git a/drivers/ieee1394/ieee1394_transactions.h b/drivers/ieee1394/ieee1394_transactions.h index d2d5bc3546d..20b693be14b 100644 --- a/drivers/ieee1394/ieee1394_transactions.h +++ b/drivers/ieee1394/ieee1394_transactions.h @@ -30,6 +30,8 @@ int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation, u64 addr, quadlet_t *buffer, size_t length); int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation, u64 addr, quadlet_t *buffer, size_t length); +int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation, + u64 addr, int extcode, quadlet_t *data, quadlet_t arg); #ifdef HPSB_DEBUG_TLABELS extern spinlock_t hpsb_tlabel_lock; diff --git a/drivers/ieee1394/iso.h b/drivers/ieee1394/iso.h index b5de5f21ef7..c2089c093aa 100644 --- a/drivers/ieee1394/iso.h +++ b/drivers/ieee1394/iso.h @@ -13,6 +13,7 @@ #define IEEE1394_ISO_H #include +#include #include #include diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile index 41710554012..cb765816f76 100644 --- a/drivers/media/dvb/Makefile +++ b/drivers/media/dvb/Makefile @@ -4,4 +4,4 @@ obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/ -obj-$(CONFIG_DVB_FIRESAT) += firesat/ +obj-$(CONFIG_DVB_FIREDTV) += firesat/ diff --git a/drivers/media/dvb/firesat/Kconfig b/drivers/media/dvb/firesat/Kconfig index 93f8de5ec3c..03d25ad1035 100644 --- a/drivers/media/dvb/firesat/Kconfig +++ b/drivers/media/dvb/firesat/Kconfig @@ -1,11 +1,12 @@ -config DVB_FIRESAT - tristate "FireSAT devices" +config DVB_FIREDTV + tristate "FireDTV (FireWire attached DVB receivers)" depends on DVB_CORE && IEEE1394 && INPUT help - Support for external IEEE1394 adapters designed by Digital Everywhere and - produced by El Gato, shipped under the brand name 'FireDTV/FloppyDTV'. + Support for DVB receivers from Digital Everywhere, known as FireDTV + and FloppyDTV, which are connected via IEEE 1394 (FireWire). - These devices don't have a MPEG decoder built in, so you need + These devices don't have an MPEG decoder built in, so you need an external software decoder to watch TV. - Say Y if you own such a device and want to use it. + To compile this driver as a module, say M here: the module will be + called firedtv. diff --git a/drivers/media/dvb/firesat/Makefile b/drivers/media/dvb/firesat/Makefile index be7701b817c..9e49edc7c49 100644 --- a/drivers/media/dvb/firesat/Makefile +++ b/drivers/media/dvb/firesat/Makefile @@ -1,4 +1,4 @@ -firesat-objs := firesat_1394.o \ +firedtv-objs := firesat_1394.o \ firesat_dvb.o \ firesat_fe.o \ firesat_iso.o \ @@ -7,7 +7,7 @@ firesat-objs := firesat_1394.o \ firesat-rc.o \ firesat-ci.o -obj-$(CONFIG_DVB_FIRESAT) += firesat.o +obj-$(CONFIG_DVB_FIREDTV) += firedtv.o EXTRA_CFLAGS := -Idrivers/ieee1394 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core diff --git a/drivers/media/dvb/firesat/avc_api.c b/drivers/media/dvb/firesat/avc_api.c index 3c8e7e3dacc..6337f9f21d0 100644 --- a/drivers/media/dvb/firesat/avc_api.c +++ b/drivers/media/dvb/firesat/avc_api.c @@ -1,9 +1,9 @@ /* - * FireSAT AVC driver + * FireDTV driver (formerly known as FireSAT) * - * Copyright (c) 2004 Andreas Monitzer - * Copyright (c) 2008 Ben Backx - * Copyright (c) 2008 Henrik Kurelid + * Copyright (C) 2004 Andreas Monitzer + * Copyright (C) 2008 Ben Backx + * Copyright (C) 2008 Henrik Kurelid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -11,13 +11,20 @@ * the License, or (at your option) any later version. */ -#include "firesat.h" +#include +#include +#include +#include +#include +#include +#include +#include + #include #include -#include -#include -#include + #include "avc_api.h" +#include "firesat.h" #include "firesat-rc.h" #define RESPONSE_REGISTER 0xFFFFF0000D00ULL @@ -28,8 +35,6 @@ static unsigned int avc_comm_debug = 0; module_param(avc_comm_debug, int, 0644); MODULE_PARM_DESC(avc_comm_debug, "debug logging level [0..2] of AV/C communication, default is 0 (no)"); -static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal); - /* Frees an allocated packet */ static void avc_free_packet(struct hpsb_packet *packet) { @@ -232,67 +237,39 @@ static int __AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, return 0; } -int AVCWrite(struct firesat*firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) { +int AVCWrite(struct firesat*firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) +{ int ret; - if(down_interruptible(&firesat->avc_sem)) + + if (mutex_lock_interruptible(&firesat->avc_mutex)) return -EINTR; ret = __AVCWrite(firesat, CmdFrm, RspFrm); - up(&firesat->avc_sem); + mutex_unlock(&firesat->avc_mutex); return ret; } -static void do_schedule_remotecontrol(unsigned long ignored); -DECLARE_TASKLET(schedule_remotecontrol, do_schedule_remotecontrol, 0); - -static void do_schedule_remotecontrol(unsigned long ignored) { - struct firesat *firesat; - unsigned long flags; - - spin_lock_irqsave(&firesat_list_lock, flags); - list_for_each_entry(firesat,&firesat_list,list) { - if(atomic_read(&firesat->reschedule_remotecontrol) == 1) { - if(down_trylock(&firesat->avc_sem)) - tasklet_schedule(&schedule_remotecontrol); - else { - if(__AVCRegisterRemoteControl(firesat, 1) == 0) - atomic_set(&firesat->reschedule_remotecontrol, 0); - else - tasklet_schedule(&schedule_remotecontrol); - - up(&firesat->avc_sem); - } +int AVCRecv(struct firesat *firesat, u8 *data, size_t length) +{ + AVCRspFrm *RspFrm = (AVCRspFrm *)data; + + if (length >= 8 && + RspFrm->operand[0] == SFE_VENDOR_DE_COMPANYID_0 && + RspFrm->operand[1] == SFE_VENDOR_DE_COMPANYID_1 && + RspFrm->operand[2] == SFE_VENDOR_DE_COMPANYID_2 && + RspFrm->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) { + if (RspFrm->resp == CHANGED) { + firesat_handle_rc(RspFrm->operand[4] << 8 | + RspFrm->operand[5]); + schedule_work(&firesat->remote_ctrl_work); + } else if (RspFrm->resp != INTERIM) { + printk(KERN_INFO "firedtv: remote control result = " + "%d\n", RspFrm->resp); } - } - spin_unlock_irqrestore(&firesat_list_lock, flags); -} - -int AVCRecv(struct firesat *firesat, u8 *data, size_t length) { -// printk(KERN_INFO "%s\n",__func__); - - // remote control handling - -#if 0 - AVCRspFrm *RspFrm = (AVCRspFrm*)data; - - if(/*RspFrm->length >= 8 && ###*/ - ((RspFrm->operand[0] == SFE_VENDOR_DE_COMPANYID_0 && - RspFrm->operand[1] == SFE_VENDOR_DE_COMPANYID_1 && - RspFrm->operand[2] == SFE_VENDOR_DE_COMPANYID_2)) && - RspFrm->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) { - if(RspFrm->resp == CHANGED) { -// printk(KERN_INFO "%s: code = %02x %02x\n",__func__,RspFrm->operand[4],RspFrm->operand[5]); - firesat_got_remotecontrolcode((((u16)RspFrm->operand[4]) << 8) | ((u16)RspFrm->operand[5])); - - // schedule - atomic_set(&firesat->reschedule_remotecontrol, 1); - tasklet_schedule(&schedule_remotecontrol); - } else if(RspFrm->resp != INTERIM) - printk(KERN_INFO "%s: remote control result = %d\n",__func__, RspFrm->resp); return 0; } -#endif + if(atomic_read(&firesat->avc_reply_received) == 1) { printk(KERN_ERR "%s: received out-of-order AVC response, " "ignored\n",__func__); @@ -718,7 +695,8 @@ int AVCTuner_GetTS(struct firesat *firesat){ return 0; } -int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport) { +int AVCIdentifySubunit(struct firesat *firesat) +{ AVCCmdFrm CmdFrm; AVCRspFrm RspFrm; @@ -752,8 +730,6 @@ int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *tr printk(KERN_ERR "%s: Invalid response length\n", __func__); return -EINVAL; } - if(systemId) - *systemId = RspFrm.operand[7]; return 0; } @@ -901,7 +877,7 @@ int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount) return 0; } -static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal) +int AVCRegisterRemoteControl(struct firesat *firesat) { AVCCmdFrm CmdFrm; @@ -922,19 +898,16 @@ static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal) CmdFrm.length = 8; - if(internal) { - if(__AVCWrite(firesat,&CmdFrm,NULL) < 0) - return -EIO; - } else - if(AVCWrite(firesat,&CmdFrm,NULL) < 0) - return -EIO; - - return 0; + return AVCWrite(firesat, &CmdFrm, NULL); } -int AVCRegisterRemoteControl(struct firesat*firesat) +void avc_remote_ctrl_work(struct work_struct *work) { - return __AVCRegisterRemoteControl(firesat, 0); + struct firesat *firesat = + container_of(work, struct firesat, remote_ctrl_work); + + /* Should it be rescheduled in failure cases? */ + AVCRegisterRemoteControl(firesat); } int AVCTuner_Host2Ca(struct firesat *firesat) diff --git a/drivers/media/dvb/firesat/avc_api.h b/drivers/media/dvb/firesat/avc_api.h index 04166568590..66f419a6f7c 100644 --- a/drivers/media/dvb/firesat/avc_api.h +++ b/drivers/media/dvb/firesat/avc_api.h @@ -1,32 +1,25 @@ -/*************************************************************************** - avc_api.h - description - ------------------- - begin : Wed May 1 2000 - copyright : (C) 2000 by Manfred Weihs - copyright : (C) 2003 by Philipp Gutgsell - copyright : (C) 2008 by Henrik Kurelid (henrik@kurelid.se) - email : 0014guph@edu.fh-kaernten.ac.at - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - /* - This is based on code written by Peter Halwachs, - Thomas Groiss and Andreas Monitzer. -*/ - - -#ifndef __AVC_API_H__ -#define __AVC_API_H__ - -#include + * AV/C API + * + * Copyright (C) 2000 Manfred Weihs + * Copyright (C) 2003 Philipp Gutgsell <0014guph@edu.fh-kaernten.ac.at> + * Copyright (C) 2004 Andreas Monitzer + * Copyright (C) 2008 Ben Backx + * Copyright (C) 2008 Henrik Kurelid + * + * This is based on code written by Peter Halwachs, Thomas Groiss and + * Andreas Monitzer. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#ifndef _AVC_API_H +#define _AVC_API_H + +#include /************************************************************* Constants from EN510221 @@ -416,34 +409,38 @@ typedef struct #define LNBCONTROL_DONTCARE 0xff - -extern int AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm); -extern int AVCRecv(struct firesat *firesat, u8 *data, size_t length); - -extern int AVCTuner_DSIT(struct firesat *firesat, - int Source_Plug, - struct dvb_frontend_parameters *params, - __u8 *status); - -extern int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_info); -extern int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, __u8 *status); -extern int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]); -extern int AVCTuner_GetTS(struct firesat *firesat); - -extern int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport); -extern int AVCLNBControl(struct firesat *firesat, char voltage, char burst, char conttone, char nrdiseq, struct dvb_diseqc_master_cmd *diseqcmd); -extern int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount); -extern int AVCRegisterRemoteControl(struct firesat *firesat); -extern int AVCTuner_Host2Ca(struct firesat *firesat); -extern int avc_ca_app_info(struct firesat *firesat, char *app_info, - int *length); -extern int avc_ca_info(struct firesat *firesat, char *app_info, int *length); -extern int avc_ca_reset(struct firesat *firesat); -extern int avc_ca_pmt(struct firesat *firesat, char *app_info, int length); -extern int avc_ca_get_time_date(struct firesat *firesat, int *interval); -extern int avc_ca_enter_menu(struct firesat *firesat); -extern int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, - int *length); - -#endif - +struct dvb_diseqc_master_cmd; +struct dvb_frontend_parameters; +struct firesat; + +int AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, + AVCRspFrm *RspFrm); +int AVCRecv(struct firesat *firesat, u8 *data, size_t length); + +int AVCTuner_DSIT(struct firesat *firesat, int Source_Plug, + struct dvb_frontend_parameters *params, __u8 *status); + +int AVCTunerStatus(struct firesat *firesat, + ANTENNA_INPUT_INFO *antenna_input_info); +int AVCTuner_DSD(struct firesat *firesat, + struct dvb_frontend_parameters *params, __u8 *status); +int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]); +int AVCTuner_GetTS(struct firesat *firesat); + +int AVCIdentifySubunit(struct firesat *firesat); +int AVCLNBControl(struct firesat *firesat, char voltage, char burst, + char conttone, char nrdiseq, + struct dvb_diseqc_master_cmd *diseqcmd); +int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount); +void avc_remote_ctrl_work(struct work_struct *work); +int AVCRegisterRemoteControl(struct firesat *firesat); +int AVCTuner_Host2Ca(struct firesat *firesat); +int avc_ca_app_info(struct firesat *firesat, char *app_info, int *length); +int avc_ca_info(struct firesat *firesat, char *app_info, int *length); +int avc_ca_reset(struct firesat *firesat); +int avc_ca_pmt(struct firesat *firesat, char *app_info, int length); +int avc_ca_get_time_date(struct firesat *firesat, int *interval); +int avc_ca_enter_menu(struct firesat *firesat); +int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, int *length); + +#endif /* _AVC_API_H */ diff --git a/drivers/media/dvb/firesat/cmp.c b/drivers/media/dvb/firesat/cmp.c index a1291caa067..d1bafba615e 100644 --- a/drivers/media/dvb/firesat/cmp.c +++ b/drivers/media/dvb/firesat/cmp.c @@ -1,8 +1,8 @@ /* - * FireSAT DVB driver + * FireDTV driver (formerly known as FireSAT) * - * Copyright (c) ? - * Copyright (c) 2008 Henrik Kurelid + * Copyright (C) 2004 Andreas Monitzer + * Copyright (C) 2008 Henrik Kurelid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -10,15 +10,19 @@ * the License, or (at your option) any later version. */ -#include "cmp.h" -#include -#include -#include -#include +#include +#include +#include + #include +#include #include #include +#include + #include "avc_api.h" +#include "cmp.h" +#include "firesat.h" typedef struct _OPCR { @@ -38,63 +42,33 @@ typedef struct _OPCR #define FIRESAT_SPEED IEEE1394_SPEED_400 -/* hpsb_lock is being removed from the kernel-source, - * therefor we define our own 'firesat_hpsb_lock'*/ - -int send_packet_and_wait(struct hpsb_packet *packet); - -int firesat_hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation, - u64 addr, int extcode, quadlet_t * data, quadlet_t arg) { - - struct hpsb_packet *packet; - int retval = 0; - - BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet - - packet = hpsb_make_lockpacket(host, node, addr, extcode, data, arg); - if (!packet) - return -ENOMEM; - - packet->generation = generation; - retval = send_packet_and_wait(packet); - if (retval < 0) - goto hpsb_lock_fail; - - retval = hpsb_packet_success(packet); - - if (retval == 0) { - *data = packet->data[0]; - } - - hpsb_lock_fail: - hpsb_free_tlabel(packet); - hpsb_free_packet(packet); - - return retval; -} - - -static int cmp_read(struct firesat *firesat, void *buffer, u64 addr, size_t length) { +static int cmp_read(struct firesat *firesat, void *buf, u64 addr, size_t len) +{ int ret; - if(down_interruptible(&firesat->avc_sem)) + + if (mutex_lock_interruptible(&firesat->avc_mutex)) return -EINTR; - ret = hpsb_read(firesat->host, firesat->nodeentry->nodeid, firesat->nodeentry->generation, - addr, buffer, length); + ret = hpsb_read(firesat->host, firesat->nodeentry->nodeid, + firesat->nodeentry->generation, addr, buf, len); - up(&firesat->avc_sem); + mutex_unlock(&firesat->avc_mutex); return ret; } -static int cmp_lock(struct firesat *firesat, quadlet_t *data, u64 addr, quadlet_t arg, int ext_tcode) { +static int cmp_lock(struct firesat *firesat, quadlet_t *data, u64 addr, + quadlet_t arg, int ext_tcode) +{ int ret; - if(down_interruptible(&firesat->avc_sem)) + + if (mutex_lock_interruptible(&firesat->avc_mutex)) return -EINTR; - ret = firesat_hpsb_lock(firesat->host, firesat->nodeentry->nodeid, firesat->nodeentry->generation, - addr, ext_tcode, data, arg); + ret = hpsb_lock(firesat->host, firesat->nodeentry->nodeid, + firesat->nodeentry->generation, + addr, ext_tcode, data, arg); - up(&firesat->avc_sem); + mutex_unlock(&firesat->avc_mutex); return ret; } @@ -223,20 +197,3 @@ int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug,int iso_ch } return 0; } - -static void complete_packet(void *data) { - complete((struct completion *) data); -} - -int send_packet_and_wait(struct hpsb_packet *packet) { - struct completion done; - int retval; - - init_completion(&done); - hpsb_set_packet_complete_task(packet, complete_packet, &done); - retval = hpsb_send_packet(packet); - if (retval == 0) - wait_for_completion(&done); - - return retval; -} diff --git a/drivers/media/dvb/firesat/cmp.h b/drivers/media/dvb/firesat/cmp.h index d43fbc29f26..600d5784dc7 100644 --- a/drivers/media/dvb/firesat/cmp.h +++ b/drivers/media/dvb/firesat/cmp.h @@ -1,9 +1,11 @@ -#ifndef __FIRESAT__CMP_H_ -#define __FIRESAT__CMP_H_ +#ifndef _CMP_H +#define _CMP_H -#include "firesat.h" +struct firesat; -extern int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, int iso_channel); -extern int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug,int iso_channel); +int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, + int iso_channel); +int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug, + int iso_channel); -#endif +#endif /* _CMP_H */ diff --git a/drivers/media/dvb/firesat/firesat-ci.c b/drivers/media/dvb/firesat/firesat-ci.c index 821048db283..3ef25cc4bfd 100644 --- a/drivers/media/dvb/firesat/firesat-ci.c +++ b/drivers/media/dvb/firesat/firesat-ci.c @@ -1,7 +1,8 @@ /* - * FireSAT DVB driver + * FireDTV driver (formerly known as FireSAT) * - * Copyright (c) 2008 Henrik Kurelid + * Copyright (C) 2004 Andreas Monitzer + * Copyright (C) 2008 Henrik Kurelid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -9,13 +10,16 @@ * the License, or (at your option) any later version. */ -#include "firesat-ci.h" -#include "firesat.h" -#include "avc_api.h" - #include +#include +#include + #include +#include "avc_api.h" +#include "firesat.h" +#include "firesat-ci.h" + static unsigned int ca_debug = 0; module_param(ca_debug, int, 0644); MODULE_PARM_DESC(ca_debug, "debug logging of ca system, default is 0 (no)"); diff --git a/drivers/media/dvb/firesat/firesat-ci.h b/drivers/media/dvb/firesat/firesat-ci.h index dafe3f0f0cc..04fe4061c77 100644 --- a/drivers/media/dvb/firesat/firesat-ci.h +++ b/drivers/media/dvb/firesat/firesat-ci.h @@ -1,9 +1,9 @@ -#ifndef __FIRESAT_CA_H -#define __FIRESAT_CA_H +#ifndef _FIREDTV_CI_H +#define _FIREDTV_CI_H -#include "firesat.h" +struct firesat; int firesat_ca_init(struct firesat *firesat); void firesat_ca_release(struct firesat *firesat); -#endif +#endif /* _FIREDTV_CI_H */ diff --git a/drivers/media/dvb/firesat/firesat-rc.c b/drivers/media/dvb/firesat/firesat-rc.c index e300b81008a..d3e08f9fe9f 100644 --- a/drivers/media/dvb/firesat/firesat-rc.c +++ b/drivers/media/dvb/firesat/firesat-rc.c @@ -1,9 +1,26 @@ -#include "firesat.h" -#include "firesat-rc.h" +/* + * FireDTV driver (formerly known as FireSAT) + * + * Copyright (C) 2004 Andreas Monitzer + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ +#include #include +#include +#include + +#include "firesat-rc.h" + +/* fixed table with older keycodes, geared towards MythTV */ +const static u16 oldtable[] = { + + /* code from device: 0x4501...0x451f */ -static u16 firesat_irtable[] = { KEY_ESC, KEY_F9, KEY_1, @@ -35,50 +52,124 @@ static u16 firesat_irtable[] = { KEY_RIGHT, KEY_P, KEY_M, + + /* code from device: 0x4540...0x4542 */ + KEY_R, KEY_V, KEY_C, - 0 }; -static struct input_dev firesat_idev; +/* user-modifiable table for a remote as sold in 2008 */ +static u16 keytable[] = { + + /* code from device: 0x0300...0x031f */ + + [0x00] = KEY_POWER, + [0x01] = KEY_SLEEP, + [0x02] = KEY_STOP, + [0x03] = KEY_OK, + [0x04] = KEY_RIGHT, + [0x05] = KEY_1, + [0x06] = KEY_2, + [0x07] = KEY_3, + [0x08] = KEY_LEFT, + [0x09] = KEY_4, + [0x0a] = KEY_5, + [0x0b] = KEY_6, + [0x0c] = KEY_UP, + [0x0d] = KEY_7, + [0x0e] = KEY_8, + [0x0f] = KEY_9, + [0x10] = KEY_DOWN, + [0x11] = KEY_TITLE, /* "OSD" - fixme */ + [0x12] = KEY_0, + [0x13] = KEY_F20, /* "16:9" - fixme */ + [0x14] = KEY_SCREEN, /* "FULL" - fixme */ + [0x15] = KEY_MUTE, + [0x16] = KEY_SUBTITLE, + [0x17] = KEY_RECORD, + [0x18] = KEY_TEXT, + [0x19] = KEY_AUDIO, + [0x1a] = KEY_RED, + [0x1b] = KEY_PREVIOUS, + [0x1c] = KEY_REWIND, + [0x1d] = KEY_PLAYPAUSE, + [0x1e] = KEY_NEXT, + [0x1f] = KEY_VOLUMEUP, + + /* code from device: 0x0340...0x0354 */ + + [0x20] = KEY_CHANNELUP, + [0x21] = KEY_F21, /* "4:3" - fixme */ + [0x22] = KEY_TV, + [0x23] = KEY_DVD, + [0x24] = KEY_VCR, + [0x25] = KEY_AUX, + [0x26] = KEY_GREEN, + [0x27] = KEY_YELLOW, + [0x28] = KEY_BLUE, + [0x29] = KEY_CHANNEL, /* "CH.LIST" */ + [0x2a] = KEY_VENDOR, /* "CI" - fixme */ + [0x2b] = KEY_VOLUMEDOWN, + [0x2c] = KEY_CHANNELDOWN, + [0x2d] = KEY_LAST, + [0x2e] = KEY_INFO, + [0x2f] = KEY_FORWARD, + [0x30] = KEY_LIST, + [0x31] = KEY_FAVORITES, + [0x32] = KEY_MENU, + [0x33] = KEY_EPG, + [0x34] = KEY_EXIT, +}; + +static struct input_dev *idev; int firesat_register_rc(void) { - int index; + int i, err; + + idev = input_allocate_device(); + if (!idev) + return -ENOMEM; - memset(&firesat_idev, 0, sizeof(firesat_idev)); + idev->name = "FireDTV remote control"; + idev->evbit[0] = BIT_MASK(EV_KEY); + idev->keycode = keytable; + idev->keycodesize = sizeof(keytable[0]); + idev->keycodemax = ARRAY_SIZE(keytable); - firesat_idev.evbit[0] = BIT(EV_KEY); + for (i = 0; i < ARRAY_SIZE(keytable); i++) + set_bit(keytable[i], idev->keybit); - for (index = 0; firesat_irtable[index] != 0; index++) - set_bit(firesat_irtable[index], firesat_idev.keybit); + err = input_register_device(idev); + if (err) + input_free_device(idev); - return input_register_device(&firesat_idev); + return err; } -int firesat_unregister_rc(void) +void firesat_unregister_rc(void) { - input_unregister_device(&firesat_idev); - return 0; + input_unregister_device(idev); } -int firesat_got_remotecontrolcode(u16 code) +void firesat_handle_rc(unsigned int code) { - u16 keycode; - - if (code > 0x4500 && code < 0x4520) - keycode = firesat_irtable[code - 0x4501]; - else if (code > 0x453f && code < 0x4543) - keycode = firesat_irtable[code - 0x4521]; + if (code >= 0x0300 && code <= 0x031f) + code = keytable[code - 0x0300]; + else if (code >= 0x0340 && code <= 0x0354) + code = keytable[code - 0x0320]; + else if (code >= 0x4501 && code <= 0x451f) + code = oldtable[code - 0x4501]; + else if (code >= 0x4540 && code <= 0x4542) + code = oldtable[code - 0x4521]; else { - printk(KERN_DEBUG "%s: invalid key code 0x%04x\n", __func__, - code); - return -EINVAL; + printk(KERN_DEBUG "firedtv: invalid key code 0x%04x " + "from remote control\n", code); + return; } - input_report_key(&firesat_idev, keycode, 1); - input_report_key(&firesat_idev, keycode, 0); - - return 0; + input_report_key(idev, code, 1); + input_report_key(idev, code, 0); } diff --git a/drivers/media/dvb/firesat/firesat-rc.h b/drivers/media/dvb/firesat/firesat-rc.h index e89a8069ba8..81f4fdec60f 100644 --- a/drivers/media/dvb/firesat/firesat-rc.h +++ b/drivers/media/dvb/firesat/firesat-rc.h @@ -1,9 +1,8 @@ -#ifndef __FIRESAT_LIRC_H -#define __FIRESAT_LIRC_H +#ifndef _FIREDTV_RC_H +#define _FIREDTV_RC_H -extern int firesat_register_rc(void); -extern int firesat_unregister_rc(void); -extern int firesat_got_remotecontrolcode(u16 code); - -#endif +int firesat_register_rc(void); +void firesat_unregister_rc(void); +void firesat_handle_rc(unsigned int code); +#endif /* _FIREDTV_RC_H */ diff --git a/drivers/media/dvb/firesat/firesat.h b/drivers/media/dvb/firesat/firesat.h index f0bac244783..5f0de88e41a 100644 --- a/drivers/media/dvb/firesat/firesat.h +++ b/drivers/media/dvb/firesat/firesat.h @@ -1,8 +1,8 @@ /* - * FireSAT DVB driver + * FireDTV driver (formerly known as FireSAT) * - * Copyright (c) ? - * Copyright (c) 2008 Henrik Kurelid + * Copyright (C) 2004 Andreas Monitzer + * Copyright (C) 2008 Henrik Kurelid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -10,22 +10,26 @@ * the License, or (at your option) any later version. */ -#ifndef __FIRESAT_H -#define __FIRESAT_H +#ifndef _FIREDTV_H +#define _FIREDTV_H -#include "dvb_frontend.h" -#include "dmxdev.h" -#include "dvb_demux.h" -#include "dvb_net.h" - -#include -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25) -#include -#endif -#include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25) #define DVB_REGISTER_ADAPTER(x, y, z, w, v) dvb_register_adapter(x, y, z, w, v) #else @@ -116,15 +120,19 @@ enum model_type { - FireSAT_DVB_S = 1, - FireSAT_DVB_C = 2, - FireSAT_DVB_T = 3, - FireSAT_DVB_S2 = 4 + FireSAT_UNKNOWN = 0, + FireSAT_DVB_S = 1, + FireSAT_DVB_C = 2, + FireSAT_DVB_T = 3, + FireSAT_DVB_S2 = 4, }; +struct hpsb_host; +struct hpsb_iso; +struct node_entry; + struct firesat { struct dvb_demux dvb_demux; - char *model_name; /* DVB bits */ struct dvb_adapter *adapter; @@ -139,11 +147,10 @@ struct firesat { int ca_last_command; int ca_time_interval; - struct semaphore avc_sem; + struct mutex avc_mutex; wait_queue_head_t avc_wait; atomic_t avc_reply_received; - - atomic_t reschedule_remotecontrol; + struct work_struct remote_ctrl_work; struct firesat_channel { struct firesat *firesat; @@ -154,7 +161,7 @@ struct firesat { int pid; int type; /* 1 - TS, 2 - Filter */ } channel[16]; - struct semaphore demux_sem; + struct mutex demux_mutex; /* needed by avc_api */ void *respfrm; @@ -210,22 +217,23 @@ struct CIPHeader { }; }; +extern const char *firedtv_model_names[]; extern struct list_head firesat_list; extern spinlock_t firesat_list_lock; +struct device; + /* firesat_dvb.c */ -extern int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed); -extern int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed); -extern int firesat_dvbdev_init(struct firesat *firesat, - struct device *dev, - struct dvb_frontend *fe); +int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed); +int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed); +int firesat_dvbdev_init(struct firesat *firesat, struct device *dev, + struct dvb_frontend *fe); /* firesat_fe.c */ -extern int firesat_frontend_attach(struct firesat *firesat, - struct dvb_frontend *fe); +int firesat_frontend_attach(struct firesat *firesat, struct dvb_frontend *fe); /* firesat_iso.c */ -extern int setup_iso_channel(struct firesat *firesat); -extern void tear_down_iso_channel(struct firesat *firesat); +int setup_iso_channel(struct firesat *firesat); +void tear_down_iso_channel(struct firesat *firesat); -#endif +#endif /* _FIREDTV_H */ diff --git a/drivers/media/dvb/firesat/firesat_1394.c b/drivers/media/dvb/firesat/firesat_1394.c index b19e59416b5..a13fbe6b3a3 100644 --- a/drivers/media/dvb/firesat/firesat_1394.c +++ b/drivers/media/dvb/firesat/firesat_1394.c @@ -1,9 +1,9 @@ /* - * FireSAT DVB driver + * FireDTV driver (formerly known as FireSAT) * - * Copyright (c) 2004 Andreas Monitzer - * Copyright (c) 2007-2008 Ben Backx - * Copyright (c) 2008 Henrik Kurelid + * Copyright (C) 2004 Andreas Monitzer + * Copyright (C) 2007-2008 Ben Backx + * Copyright (C) 2008 Henrik Kurelid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -11,26 +11,34 @@ * the License, or (at your option) any later version. */ -#include -#include -#include -#include -#include -#include +#include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include #include -#include #include -#include +#include +#include -#include "firesat.h" #include "avc_api.h" #include "cmp.h" -#include "firesat-rc.h" +#include "firesat.h" #include "firesat-ci.h" +#include "firesat-rc.h" #define FIRESAT_Vendor_ID 0x001287 @@ -75,52 +83,6 @@ MODULE_DEVICE_TABLE(ieee1394, firesat_id_table); LIST_HEAD(firesat_list); spinlock_t firesat_list_lock = SPIN_LOCK_UNLOCKED; -static void firesat_add_host(struct hpsb_host *host); -static void firesat_remove_host(struct hpsb_host *host); -static void firesat_host_reset(struct hpsb_host *host); - -static void fcp_request(struct hpsb_host *host, - int nodeid, - int direction, - int cts, - u8 *data, - size_t length); - -static struct hpsb_highlevel firesat_highlevel = { - .name = "FireSAT", - .add_host = firesat_add_host, - .remove_host = firesat_remove_host, - .host_reset = firesat_host_reset, - .fcp_request = fcp_request, -}; - -static void firesat_add_host (struct hpsb_host *host) -{ - struct ti_ohci *ohci = (struct ti_ohci *)host->hostdata; - - /* We only work with the OHCI-1394 driver */ - if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME)) - return; - - if (!hpsb_create_hostinfo(&firesat_highlevel, host, 0)) { - printk(KERN_ERR "Cannot allocate hostinfo\n"); - return; - } - - hpsb_set_hostinfo(&firesat_highlevel, host, ohci); - hpsb_set_hostinfo_key(&firesat_highlevel, host, ohci->host->id); -} - -static void firesat_remove_host (struct hpsb_host *host) -{ - -} - -static void firesat_host_reset(struct hpsb_host *host) -{ - printk(KERN_INFO "FireSAT host_reset (nodeid = 0x%x, hosts active = %d)\n",host->node_id,host->nodes_active); -} - static void fcp_request(struct hpsb_host *host, int nodeid, int direction, @@ -156,6 +118,14 @@ static void fcp_request(struct hpsb_host *host, printk("%s: received invalid fcp request, ignored\n", __func__); } +const char *firedtv_model_names[] = { + [FireSAT_UNKNOWN] = "unknown type", + [FireSAT_DVB_S] = "FireDTV S/CI", + [FireSAT_DVB_C] = "FireDTV C/CI", + [FireSAT_DVB_T] = "FireDTV T/CI", + [FireSAT_DVB_S2] = "FireDTV S2 ", +}; + static int firesat_probe(struct device *dev) { struct unit_directory *ud = container_of(dev, struct unit_directory, device); @@ -165,6 +135,7 @@ static int firesat_probe(struct device *dev) unsigned char subunitcount = 0xff, subunit; struct firesat **firesats = kmalloc(sizeof (void*) * 2,GFP_KERNEL); int kv_len; + int i; char *kv_buf; if (!firesats) { @@ -207,11 +178,11 @@ static int firesat_probe(struct device *dev) return -ENOMEM; } - sema_init(&firesat->avc_sem, 1); + mutex_init(&firesat->avc_mutex); init_waitqueue_head(&firesat->avc_wait); atomic_set(&firesat->avc_reply_received, 1); - sema_init(&firesat->demux_sem, 1); - atomic_set(&firesat->reschedule_remotecontrol, 0); + mutex_init(&firesat->demux_mutex); + INIT_WORK(&firesat->remote_ctrl_work, avc_remote_ctrl_work); spin_lock_irqsave(&firesat_list_lock, flags); INIT_LIST_HEAD(&firesat->list); @@ -244,23 +215,13 @@ static int firesat_probe(struct device *dev) while ((kv_buf + kv_len - 1) == '\0') kv_len--; kv_buf[kv_len++] = '\0'; - /* Determining the device model */ - if (strcmp(kv_buf, "FireDTV S/CI") == 0) { - printk(KERN_INFO "%s: found DVB/S\n", __func__); - firesat->type = 1; - } else if (strcmp(kv_buf, "FireDTV C/CI") == 0) { - printk(KERN_INFO "%s: found DVB/C\n", __func__); - firesat->type = 2; - } else if (strcmp(kv_buf, "FireDTV T/CI") == 0) { - printk(KERN_INFO "%s: found DVB/T\n", __func__); - firesat->type = 3; - } else if (strcmp(kv_buf, "FireDTV S2 ") == 0) { - printk(KERN_INFO "%s: found DVB/S2\n", __func__); - firesat->type = 4; - } + for (i = ARRAY_SIZE(firedtv_model_names); --i;) + if (strcmp(kv_buf, firedtv_model_names[i]) == 0) + break; + firesat->type = i; kfree(kv_buf); - if (AVCIdentifySubunit(firesat, NULL, (int*)&firesat->type)) { + if (AVCIdentifySubunit(firesat)) { printk("%s: cannot identify subunit %d\n", __func__, subunit); spin_lock_irqsave(&firesat_list_lock, flags); list_del(&firesat->list); @@ -270,14 +231,14 @@ static int firesat_probe(struct device *dev) } // ---- + /* FIXME: check for error return */ firesat_dvbdev_init(firesat, dev, fe); // ---- firesats[subunit] = firesat; } // loop for all tuners - //beta ;-) Disable remote control stuff to avoid crashing - //if(firesats[0]) - // AVCRegisterRemoteControl(firesats[0]); + if (firesats[0]) + AVCRegisterRemoteControl(firesats[0]); return 0; } @@ -306,6 +267,8 @@ static int firesat_remove(struct device *dev) list_del(&firesats[k]->list); spin_unlock_irqrestore(&firesat_list_lock, flags); + cancel_work_sync(&firesats[k]->remote_ctrl_work); + kfree(firesats[k]->fe); kfree(firesats[k]->adapter); kfree(firesats[k]->respfrm); @@ -339,7 +302,7 @@ static int firesat_update(struct unit_directory *ud) static struct hpsb_protocol_driver firesat_driver = { - .name = "FireSAT", + .name = "firedtv", .id_table = firesat_id_table, .update = firesat_update, @@ -352,32 +315,41 @@ static struct hpsb_protocol_driver firesat_driver = { }, }; +static struct hpsb_highlevel firesat_highlevel = { + .name = "firedtv", + .fcp_request = fcp_request, +}; + static int __init firesat_init(void) { int ret; - printk(KERN_INFO "FireSAT loaded\n"); hpsb_register_highlevel(&firesat_highlevel); ret = hpsb_register_protocol(&firesat_driver); if (ret) { - printk(KERN_ERR "FireSAT: failed to register protocol\n"); - hpsb_unregister_highlevel(&firesat_highlevel); - return ret; + printk(KERN_ERR "firedtv: failed to register protocol\n"); + goto fail; } - //Crash in this function, just disable RC for the time being... - //Don't forget to uncomment in firesat_exit and firesat_probe when you enable this. - /*if((ret=firesat_register_rc())) - printk("%s: firesat_register_rc return error code %d (ignored)\n", __func__, ret);*/ + ret = firesat_register_rc(); + if (ret) { + printk(KERN_ERR "firedtv: failed to register input device\n"); + goto fail_rc; + } return 0; +fail_rc: + hpsb_unregister_protocol(&firesat_driver); +fail: + hpsb_unregister_highlevel(&firesat_highlevel); + return ret; } static void __exit firesat_exit(void) { + firesat_unregister_rc(); hpsb_unregister_protocol(&firesat_driver); hpsb_unregister_highlevel(&firesat_highlevel); - printk(KERN_INFO "FireSAT quit\n"); } module_init(firesat_init); @@ -385,6 +357,6 @@ module_exit(firesat_exit); MODULE_AUTHOR("Andreas Monitzer "); MODULE_AUTHOR("Ben Backx "); -MODULE_DESCRIPTION("FireSAT DVB Driver"); +MODULE_DESCRIPTION("FireDTV DVB Driver"); MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("FireSAT DVB"); +MODULE_SUPPORTED_DEVICE("FireDTV DVB"); diff --git a/drivers/media/dvb/firesat/firesat_dvb.c b/drivers/media/dvb/firesat/firesat_dvb.c index 9e87402289a..e944cee19f0 100644 --- a/drivers/media/dvb/firesat/firesat_dvb.c +++ b/drivers/media/dvb/firesat/firesat_dvb.c @@ -1,8 +1,8 @@ /* - * FireSAT DVB driver + * FireDTV driver (formerly known as FireSAT) * - * Copyright (c) ? - * Copyright (c) 2008 Henrik Kurelid + * Copyright (C) 2004 Andreas Monitzer + * Copyright (C) 2008 Henrik Kurelid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -10,64 +10,52 @@ * the License, or (at your option) any later version. */ -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include + +#include +#include #include -#include "firesat.h" #include "avc_api.h" -#include "cmp.h" -#include "firesat-rc.h" +#include "firesat.h" #include "firesat-ci.h" DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); static struct firesat_channel *firesat_channel_allocate(struct firesat *firesat) { + struct firesat_channel *c = NULL; int k; - //printk(KERN_INFO "%s\n", __func__); - - if (down_interruptible(&firesat->demux_sem)) + if (mutex_lock_interruptible(&firesat->demux_mutex)) return NULL; - for (k = 0; k < 16; k++) { - //printk(KERN_INFO "%s: channel %d: active = %d, pid = 0x%x\n",__func__,k,firesat->channel[k].active,firesat->channel[k].pid); - + for (k = 0; k < 16; k++) if (firesat->channel[k].active == 0) { firesat->channel[k].active = 1; - up(&firesat->demux_sem); - return &firesat->channel[k]; + c = &firesat->channel[k]; + break; } - } - up(&firesat->demux_sem); - return NULL; // no more channels available + mutex_unlock(&firesat->demux_mutex); + return c; } static int firesat_channel_collect(struct firesat *firesat, int *pidc, u16 pid[]) { int k, l = 0; - if (down_interruptible(&firesat->demux_sem)) + if (mutex_lock_interruptible(&firesat->demux_mutex)) return -EINTR; for (k = 0; k < 16; k++) if (firesat->channel[k].active == 1) pid[l++] = firesat->channel[k].pid; - up(&firesat->demux_sem); + mutex_unlock(&firesat->demux_mutex); *pidc = l; @@ -77,12 +65,12 @@ static int firesat_channel_collect(struct firesat *firesat, int *pidc, u16 pid[] static int firesat_channel_release(struct firesat *firesat, struct firesat_channel *channel) { - if (down_interruptible(&firesat->demux_sem)) + if (mutex_lock_interruptible(&firesat->demux_mutex)) return -EINTR; channel->active = 0; - up(&firesat->demux_sem); + mutex_unlock(&firesat->demux_mutex); return 0; } @@ -172,7 +160,8 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed) { struct dvb_demux *demux = dvbdmxfeed->demux; struct firesat *firesat = (struct firesat*)demux->priv; - int k, l = 0; + struct firesat_channel *c = dvbdmxfeed->priv; + int k, l; u16 pids[16]; //printk(KERN_INFO "%s (pid %u)\n", __func__, dvbdmxfeed->pid); @@ -197,30 +186,24 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed) return 0; } - if (down_interruptible(&firesat->demux_sem)) + if (mutex_lock_interruptible(&firesat->demux_mutex)) return -EINTR; - - // list except channel to be removed - for (k = 0; k < 16; k++) + /* list except channel to be removed */ + for (k = 0, l = 0; k < 16; k++) if (firesat->channel[k].active == 1) { - if (&firesat->channel[k] != - (struct firesat_channel *)dvbdmxfeed->priv) + if (&firesat->channel[k] != c) pids[l++] = firesat->channel[k].pid; else firesat->channel[k].active = 0; } - if ((k = AVCTuner_SetPIDs(firesat, l, pids))) { - up(&firesat->demux_sem); - return k; - } + k = AVCTuner_SetPIDs(firesat, l, pids); + if (!k) + c->active = 0; - ((struct firesat_channel *)dvbdmxfeed->priv)->active = 0; - - up(&firesat->demux_sem); - - return 0; + mutex_unlock(&firesat->demux_mutex); + return k; } int firesat_dvbdev_init(struct firesat *firesat, @@ -229,60 +212,20 @@ int firesat_dvbdev_init(struct firesat *firesat, { int result; -#if 0 - switch (firesat->type) { - case FireSAT_DVB_S: - firesat->model_name = "FireSAT DVB-S"; - firesat->frontend_info = &firesat_S_frontend_info; - break; - case FireSAT_DVB_C: - firesat->model_name = "FireSAT DVB-C"; - firesat->frontend_info = &firesat_C_frontend_info; - break; - case FireSAT_DVB_T: - firesat->model_name = "FireSAT DVB-T"; - firesat->frontend_info = &firesat_T_frontend_info; - break; - default: - printk("%s: unknown model type 0x%x on subunit %d!\n", - __func__, firesat->type,subunit); - firesat->model_name = "Unknown"; - firesat->frontend_info = NULL; - } -#endif -/* // ------- CRAP ----------- - if (!firesat->frontend_info) { - spin_lock_irqsave(&firesat_list_lock, flags); - list_del(&firesat->list); - spin_unlock_irqrestore(&firesat_list_lock, flags); - kfree(firesat); - continue; - } -*/ - //initialising firesat->adapter before calling dvb_register_adapter - if (!(firesat->adapter = kmalloc(sizeof (struct dvb_adapter), GFP_KERNEL))) { - printk("%s: couldn't allocate memory.\n", __func__); - kfree(firesat->adapter); - kfree(firesat); - return -ENOMEM; - } - - if ((result = DVB_REGISTER_ADAPTER(firesat->adapter, - firesat->model_name, - THIS_MODULE, - dev, adapter_nr)) < 0) { - - printk("%s: dvb_register_adapter failed: error %d\n", __func__, result); -#if 0 - /* ### cleanup */ - spin_lock_irqsave(&firesat_list_lock, flags); - list_del(&firesat->list); - spin_unlock_irqrestore(&firesat_list_lock, flags); -#endif - kfree(firesat); + firesat->adapter = kmalloc(sizeof(*firesat->adapter), GFP_KERNEL); + if (!firesat->adapter) { + printk(KERN_ERR "firedtv: couldn't allocate memory\n"); + return -ENOMEM; + } - return result; - } + result = DVB_REGISTER_ADAPTER(firesat->adapter, + firedtv_model_names[firesat->type], + THIS_MODULE, dev, adapter_nr); + if (result < 0) { + printk(KERN_ERR "firedtv: dvb_register_adapter failed\n"); + kfree(firesat->adapter); + return result; + } memset(&firesat->demux, 0, sizeof(struct dvb_demux)); firesat->demux.dmx.capabilities = 0/*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/; diff --git a/drivers/media/dvb/firesat/firesat_fe.c b/drivers/media/dvb/firesat/firesat_fe.c index 1c86c3e6137..ec614ea8de2 100644 --- a/drivers/media/dvb/firesat/firesat_fe.c +++ b/drivers/media/dvb/firesat/firesat_fe.c @@ -1,8 +1,8 @@ /* - * FireSAT DVB driver + * FireDTV driver (formerly known as FireSAT) * - * Copyright (c) ? - * Copyright (c) 2008 Henrik Kurelid + * Copyright (C) 2004 Andreas Monitzer + * Copyright (C) 2008 Henrik Kurelid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -10,26 +10,15 @@ * the License, or (at your option) any later version. */ -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include + +#include -#include "firesat.h" #include "avc_api.h" #include "cmp.h" -#include "firesat-rc.h" -#include "firesat-ci.h" +#include "firesat.h" static int firesat_dvb_init(struct dvb_frontend *fe) { @@ -209,21 +198,17 @@ int firesat_frontend_attach(struct firesat *firesat, struct dvb_frontend *fe) { switch (firesat->type) { case FireSAT_DVB_S: - firesat->model_name = "FireSAT DVB-S"; firesat->frontend_info = &firesat_S_frontend_info; break; case FireSAT_DVB_C: - firesat->model_name = "FireSAT DVB-C"; firesat->frontend_info = &firesat_C_frontend_info; break; case FireSAT_DVB_T: - firesat->model_name = "FireSAT DVB-T"; firesat->frontend_info = &firesat_T_frontend_info; break; default: - printk("%s: unknown model type 0x%x !\n", - __func__, firesat->type); - firesat->model_name = "Unknown"; + printk(KERN_ERR "firedtv: no frontend for model type 0x%x\n", + firesat->type); firesat->frontend_info = NULL; } fe->ops = firesat_ops; @@ -235,7 +220,7 @@ int firesat_frontend_attach(struct firesat *firesat, struct dvb_frontend *fe) static struct dvb_frontend_info firesat_S_frontend_info = { - .name = "FireSAT DVB-S Frontend", + .name = "FireDTV DVB-S Frontend", .type = FE_QPSK, .frequency_min = 950000, @@ -256,7 +241,7 @@ static struct dvb_frontend_info firesat_S_frontend_info = { static struct dvb_frontend_info firesat_C_frontend_info = { - .name = "FireSAT DVB-C Frontend", + .name = "FireDTV DVB-C Frontend", .type = FE_QAM, .frequency_min = 47000000, @@ -276,7 +261,7 @@ static struct dvb_frontend_info firesat_C_frontend_info = { static struct dvb_frontend_info firesat_T_frontend_info = { - .name = "FireSAT DVB-T Frontend", + .name = "FireDTV DVB-T Frontend", .type = FE_OFDM, .frequency_min = 49000000, diff --git a/drivers/media/dvb/firesat/firesat_iso.c b/drivers/media/dvb/firesat/firesat_iso.c index 15e23cf7d50..bc94afe57f6 100644 --- a/drivers/media/dvb/firesat/firesat_iso.c +++ b/drivers/media/dvb/firesat/firesat_iso.c @@ -1,7 +1,7 @@ /* * FireSAT DVB driver * - * Copyright (c) 2008 Henrik Kurelid + * Copyright (C) 2008 Henrik Kurelid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -9,6 +9,16 @@ * the License, or (at your option) any later version. */ +#include +#include +#include +#include + +#include + +#include +#include + #include "firesat.h" static void rawiso_activity_cb(struct hpsb_iso *iso); -- cgit From 29f8ea8ab09bad0c3c0d67964559d27643e97903 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Wed, 27 Aug 2008 01:18:32 +0200 Subject: ieee1394: use correct barrier types between accesses of nodeid and generation A compiler barrier (explicit on the read side, implicit on the write side) is not quite enough for what has to be accomplished here. Use hardware memory barriers on systems which need them. (Of course a full fix of generation handling would require much more than this. The ieee1394 core's bus generation counter had to be tied to the controller's bus generation counter; cf. Kristian's stack. It's just that I have other current business with the code around these barrier()s, so why not do at least this small fix.) Signed-off-by: Stefan Richter --- drivers/ieee1394/nodemgr.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index 906c5a98d81..f47b6f69d2a 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c @@ -1265,7 +1265,8 @@ static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr, csr1212_destroy_csr(csr); } - /* Mark the node current */ + /* Finally, mark the node current */ + smp_wmb(); ne->generation = generation; if (ne->in_limbo) { @@ -1798,7 +1799,7 @@ void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *packet) { packet->host = ne->host; packet->generation = ne->generation; - barrier(); + smp_rmb(); packet->node_id = ne->nodeid; } @@ -1807,7 +1808,7 @@ int hpsb_node_write(struct node_entry *ne, u64 addr, { unsigned int generation = ne->generation; - barrier(); + smp_rmb(); return hpsb_write(ne->host, ne->nodeid, generation, addr, buffer, length); } -- cgit From b33fdd6ca576d6c476c6aebf350d4556294d74ac Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Wed, 27 Aug 2008 13:40:02 +0200 Subject: ieee1394: add hpsb_node_read() and hpsb_node_lock() These will be used by the firedtv driver. Like hpsb_node_write() they are much better APIs for high-level drivers than hpsb_write() and its siblings --- easier to use correctly and also terser. Unlike hspb_node_write(), the two new functions will only be used by one call site. Hence make them static inline instead of exported symbols. Signed-off-by: Stefan Richter --- drivers/ieee1394/nodemgr.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/ieee1394/nodemgr.h b/drivers/ieee1394/nodemgr.h index 15ea09733e8..ee5acdbd114 100644 --- a/drivers/ieee1394/nodemgr.h +++ b/drivers/ieee1394/nodemgr.h @@ -21,9 +21,11 @@ #define _IEEE1394_NODEMGR_H #include +#include #include #include "ieee1394_core.h" +#include "ieee1394_transactions.h" #include "ieee1394_types.h" struct csr1212_csr; @@ -154,6 +156,22 @@ static inline int hpsb_node_entry_valid(struct node_entry *ne) void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *packet); int hpsb_node_write(struct node_entry *ne, u64 addr, quadlet_t *buffer, size_t length); +static inline int hpsb_node_read(struct node_entry *ne, u64 addr, + quadlet_t *buffer, size_t length) +{ + unsigned int g = ne->generation; + + smp_rmb(); + return hpsb_read(ne->host, ne->nodeid, g, addr, buffer, length); +} +static inline int hpsb_node_lock(struct node_entry *ne, u64 addr, int extcode, + quadlet_t *buffer, quadlet_t arg) +{ + unsigned int g = ne->generation; + + smp_rmb(); + return hpsb_lock(ne->host, ne->nodeid, g, addr, extcode, buffer, arg); +} int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *)); int init_ieee1394_nodemgr(void); -- cgit From 9c939e4df432fe4ed17bdbf7bc14111ec51ef7c9 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Wed, 27 Aug 2008 01:24:25 +0200 Subject: ieee1394: inherit ud vendor_id from node vendor_id While Module_Vendor_ID in the configuration ROM's root directory is mandatory, there often aren't vendor IDs in unit directories. This affects the new firedtv driver which is meant to be auto-loaded and matched only for vendor-specific devices. We now always copy ne->vendor_id into ud->vendor_id before we scan a unit directory (and fill in a possibly present vendor ID from there). This way, the root directory's vendor ID is used as fallback in the "uevent" environment for modprobe'ing per module alias when a node was plugged in, and in the driver match routine when protocol drivers are bound to unit directories. It will however not be used as sysfs attribute of a unit directory device. Signed-off-by: Stefan Richter --- drivers/ieee1394/nodemgr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index f47b6f69d2a..53aada5bbe1 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c @@ -971,6 +971,9 @@ static struct unit_directory *nodemgr_process_unit_directory ud->ud_kv = ud_kv; ud->id = (*id)++; + /* inherit vendor_id from root directory if none exists in unit dir */ + ud->vendor_id = ne->vendor_id; + csr1212_for_each_dir_entry(ne->csr, kv, ud_kv, dentry) { switch (kv->key.id) { case CSR1212_KV_ID_VENDOR: -- cgit From 00fc3072e484c1c6fdbd9c3b1851f866000a6cb9 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Mon, 16 Feb 2009 23:42:31 +0100 Subject: ieee1394: remove superfluous assertions hpsb_read, hpsb_write, hpsb_lock are sleeping functions which nobody is in danger to use in atomic context. Besides, in_interrupt does not cover all types of atomic context. Signed-off-by: Stefan Richter --- drivers/ieee1394/ieee1394_transactions.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c index 24021d2f0a7..675b3135d5f 100644 --- a/drivers/ieee1394/ieee1394_transactions.c +++ b/drivers/ieee1394/ieee1394_transactions.c @@ -501,8 +501,6 @@ int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation, if (length == 0) return -EINVAL; - BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet - packet = hpsb_make_readpacket(host, node, addr, length); if (!packet) { @@ -550,8 +548,6 @@ int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation, if (length == 0) return -EINVAL; - BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet - packet = hpsb_make_writepacket(host, node, addr, buffer, length); if (!packet) @@ -577,8 +573,6 @@ int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation, struct hpsb_packet *packet; int retval = 0; - BUG_ON(in_interrupt()); - packet = hpsb_make_lockpacket(host, node, addr, extcode, data, arg); if (!packet) return -ENOMEM; -- cgit From 8ae83cdf3297d7da301af36bdb6ff45bd331c6d0 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 2 Nov 2008 13:45:00 +0100 Subject: firedtv: cleanups and minor fixes Combination of the following changes: Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: increase FCP frame length for DVB-S2 tune QSPK The last three bytes didn't go out to the wire. Effect of the fix not yet tested. Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: replace mdelay by msleep These functions can sleep (and in fact sleep for the duration of a whole FCP transaction). Hence msleep is more appropriate here. Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: trivial reorganization in avc_api Reduce nesting level by factoring code out of avc_tuner_dsd() into helper functions. Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: trivial cleanups in avc_api Use dev_err(), no CamelCase function names, adjust comment style, put #if 0 around unused code and add FIXME comments, standardize on lower-case hexadecimal constants, use ALIGN() for some frame length calculations, make a local function static... The code which writes FCP command frames and reads FCP response frames is not yet brought into canonical kernel coding style because this involves changes of typedefs (on-the-wire bitfields). Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: don't retry oPCR updates endlessly In the theoretical case that the target node wasn't handling the lock transactions as expected or there was continued interference by other initiating nodes, these functions wouldn't return for ages. Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: remove bitfield typedefs from cmp, fix for big endian CPUs Use macros/ inline functions/ standard byte order accessors to read and write oPCR register values (big endian bitfields, on-the-wire data). The new code may not be the ultimate optimum, but it doesn't occur in a hot path. This fixes the CMP code for big endian CPUs. So far I tested it only on a little endian CPU though. For now, include instead of because drivers/ieee1394/*.h also include the former. I will fix this in drivers/ieee1394 and firedtv later. Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: trivial cleanups in cmp Reduce nesting level by means of early exit and goto. Remove obsolete includes, use dev_err(), no CamelCase function names... Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: trivial cleanups in firesat-ci Whitespace, variable names, comment style... Also, use dvb_generic_open() and dvb_generic_release() directly as our hooks in struct file_operations because firedtv's wrappers merely called these generic functions. Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: remove CA debug code This looks like it is not necessary to have available for endusers who cannot patch kernels for bug reporting and tests of fixes. Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: remove AV/C debug code This looks like it is not necessary to have available for endusers who cannot patch kernels for bug reporting and tests of fixes. Sun, 2 Nov 2008 13:45:00 +0100 (CET) firedtv: remove various debug code Most of this was already commented out. And that which wasn't is not relevant in normal use. Mon, 29 Sep 2008 19:22:48 +0200 (CEST) firedtv: register input device as child of a FireWire device Instead of one virtual input device which exists for the whole lifetime of the driver and receives events from all connected FireDTVs, register one input device for each firedtv device. These input devices will show up as children of the respective firedtv devices in the sysfs hierarchy. However, the implementation falls short because of a bug in userspace: Udev's path_id script gets stuck with 100% CPU utilization, maybe because of an assumption about the maximum ieee1394 device hierarchy depth. To avoid this bug, we use the fw-host device instead of the proper unit_directory device as parent of the input device. There is hope that the port to the new firewire stack won't be inhibited by this userspace bug because there are no fw-host devices there. Mon, 29 Sep 2008 19:21:52 +0200 (CEST) firedtv: fix string comparison and a few sparse warnings Sparse found a bug: while ((kv_buf + kv_len - 1) == '\0') should have been while (kv_buf[kv_len - 1] == '\0') We fix it by a better implementation without a temporary copy. Also fix sparse warnings of 0 instead of NULL and signedness mismatches. Mon, 29 Sep 2008 19:21:20 +0200 (CEST) firedtv: remove unused struct members and redefine an int as a bool. Mon, 29 Sep 2008 19:20:36 +0200 (CEST) firedtv: fix initialization of dvb_frontend.ops There was a NULL pointer reference if no dvb_frontend_info was found. Also, don't directly assign struct typed values to struct typed variables. Instead write out assignments to individual strcut members. This reduces module size by about 1 kB. Mon, 29 Sep 2008 19:19:41 +0200 (CEST) firedtv: remove unused dual subunit code from initialization No FireDTVs with more than one subunit exists, hence simplify the initialization for the special case of one subunit. The driver was able to check for more than one subunit but was broken for more than two subunits. While we are at it, add several missing cleanups after failure, and include a few dynamically allocated structures diretly into struct firesat instead of allocating them separately. Mon, 29 Sep 2008 19:19:08 +0200 (CEST) firedtv: add vendor_id and version to driver match table Now that nodemgr was enhanced to match against the root directory's vendor ID if there isn't one in the unit directory, use this to prevent firedtv to be bound to wrong devices by accident. Also add the AV/C software version ID to the match flags for completeness; specifier ID and software only make sense as a pair. Mon, 29 Sep 2008 19:18:30 +0200 (CEST) firedtv: use hpsb_node_read(), _write(), _lock() because they are simpler and treat the node generation more correctly. While we are at it, clean up and simplify surrounding code. Signed-off-by: Stefan Richter --- drivers/media/dvb/firesat/avc_api.c | 1074 ++++++++++++------------------ drivers/media/dvb/firesat/avc_api.h | 38 +- drivers/media/dvb/firesat/cmp.c | 252 ++++--- drivers/media/dvb/firesat/cmp.h | 6 +- drivers/media/dvb/firesat/firesat-ci.c | 244 ++----- drivers/media/dvb/firesat/firesat-ci.h | 2 +- drivers/media/dvb/firesat/firesat-rc.c | 42 +- drivers/media/dvb/firesat/firesat-rc.h | 9 +- drivers/media/dvb/firesat/firesat.h | 68 +- drivers/media/dvb/firesat/firesat_1394.c | 301 ++++----- drivers/media/dvb/firesat/firesat_dvb.c | 178 ++--- drivers/media/dvb/firesat/firesat_fe.c | 223 +++---- drivers/media/dvb/firesat/firesat_iso.c | 11 +- 13 files changed, 964 insertions(+), 1484 deletions(-) diff --git a/drivers/media/dvb/firesat/avc_api.c b/drivers/media/dvb/firesat/avc_api.c index 6337f9f21d0..56911f3df7f 100644 --- a/drivers/media/dvb/firesat/avc_api.c +++ b/drivers/media/dvb/firesat/avc_api.c @@ -11,14 +11,16 @@ * the License, or (at your option) any later version. */ +#include #include #include +#include #include #include #include +#include #include #include -#include #include #include @@ -27,230 +29,61 @@ #include "firesat.h" #include "firesat-rc.h" -#define RESPONSE_REGISTER 0xFFFFF0000D00ULL -#define COMMAND_REGISTER 0xFFFFF0000B00ULL -#define PCR_BASE_ADDRESS 0xFFFFF0000900ULL +#define FCP_COMMAND_REGISTER 0xfffff0000b00ULL -static unsigned int avc_comm_debug = 0; -module_param(avc_comm_debug, int, 0644); -MODULE_PARM_DESC(avc_comm_debug, "debug logging level [0..2] of AV/C communication, default is 0 (no)"); - -/* Frees an allocated packet */ -static void avc_free_packet(struct hpsb_packet *packet) -{ - hpsb_free_tlabel(packet); - hpsb_free_packet(packet); -} - -static const char* get_ctype_string(__u8 ctype) -{ - switch(ctype) - { - case 0: - return "CONTROL"; - case 1: - return "STATUS"; - case 2: - return "SPECIFIC_INQUIRY"; - case 3: - return "NOTIFY"; - case 4: - return "GENERAL_INQUIRY"; - } - return "UNKNOWN"; -} - -static const char* get_resp_string(__u8 ctype) -{ - switch(ctype) - { - case 8: - return "NOT_IMPLEMENTED"; - case 9: - return "ACCEPTED"; - case 10: - return "REJECTED"; - case 11: - return "IN_TRANSITION"; - case 12: - return "IMPLEMENTED_STABLE"; - case 13: - return "CHANGED"; - case 15: - return "INTERIM"; - } - return "UNKNOWN"; -} - -static const char* get_subunit_address(__u8 subunit_id, __u8 subunit_type) -{ - if (subunit_id == 7 && subunit_type == 0x1F) - return "Unit"; - if (subunit_id == 0 && subunit_type == 0x05) - return "Tuner(0)"; - return "Unsupported"; -} - -static const char* get_opcode_string(__u8 opcode) -{ - switch(opcode) - { - case 0x02: - return "PlugInfo"; - case 0x08: - return "OpenDescriptor"; - case 0x09: - return "ReadDescriptor"; - case 0x18: - return "OutputPlugSignalFormat"; - case 0x31: - return "SubunitInfo"; - case 0x30: - return "UnitInfo"; - case 0xB2: - return "Power"; - case 0xC8: - return "DirectSelectInformationType"; - case 0xCB: - return "DirectSelectData"; - case 0x00: - return "Vendor"; - - } - return "Unknown"; -} - -static void log_command_frame(const AVCCmdFrm *CmdFrm) -{ - int k; - printk(KERN_INFO "AV/C Command Frame:\n"); - printk(KERN_INFO "CommandType=%s, Address=%s(0x%02X,0x%02X), " - "opcode=%s(0x%02X), length=%d\n", - get_ctype_string(CmdFrm->ctype), - get_subunit_address(CmdFrm->suid, CmdFrm->sutyp), - CmdFrm->suid, CmdFrm->sutyp, get_opcode_string(CmdFrm->opcode), - CmdFrm->opcode, CmdFrm->length); - if (avc_comm_debug > 1) { - for(k = 0; k < CmdFrm->length - 3; k++) { - if (k % 5 != 0) - printk(", "); - else if (k != 0) - printk("\n"); - printk(KERN_INFO "operand[%d] = %02X", k, - CmdFrm->operand[k]); - } - printk(KERN_INFO "\n"); - } -} - -static void log_response_frame(const AVCRspFrm *RspFrm) +static int __avc_write(struct firesat *firesat, + const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) { - int k; - printk(KERN_INFO "AV/C Response Frame:\n"); - printk(KERN_INFO "Response=%s, Address=%s(0x%02X,0x%02X), " - "opcode=%s(0x%02X), length=%d\n", get_resp_string(RspFrm->resp), - get_subunit_address(RspFrm->suid, RspFrm->sutyp), - RspFrm->suid, RspFrm->sutyp, get_opcode_string(RspFrm->opcode), - RspFrm->opcode, RspFrm->length); - if (avc_comm_debug > 1) { - for(k = 0; k < RspFrm->length - 3; k++) { - if (k % 5 != 0) - printk(KERN_INFO ", "); - else if (k != 0) - printk(KERN_INFO "\n"); - printk(KERN_INFO "operand[%d] = %02X", k, - RspFrm->operand[k]); + int err, retry; + + if (RspFrm) + firesat->avc_reply_received = false; + + for (retry = 0; retry < 6; retry++) { + err = hpsb_node_write(firesat->ud->ne, FCP_COMMAND_REGISTER, + (quadlet_t *)CmdFrm, CmdFrm->length); + if (err) { + firesat->avc_reply_received = true; + dev_err(&firesat->ud->device, + "FCP command write failed\n"); + return err; } - printk(KERN_INFO "\n"); - } -} - -static int __AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, - AVCRspFrm *RspFrm) { - struct hpsb_packet *packet; - struct node_entry *ne; - int num_tries = 0; - int packet_ok = 0; - - ne = firesat->nodeentry; - if(!ne) { - printk(KERN_ERR "%s: lost node!\n",__func__); - return -EIO; - } - - /* need all input data */ - if(!firesat || !ne || !CmdFrm) { - printk(KERN_ERR "%s: missing input data!\n",__func__); - return -EINVAL; - } - if (avc_comm_debug > 0) { - log_command_frame(CmdFrm); - } + if (!RspFrm) + return 0; - if(RspFrm) - atomic_set(&firesat->avc_reply_received, 0); - - while (packet_ok == 0 && num_tries < 6) { - num_tries++; - packet_ok = 1; - packet = hpsb_make_writepacket(ne->host, ne->nodeid, - COMMAND_REGISTER, - (quadlet_t*)CmdFrm, - CmdFrm->length); - hpsb_set_packet_complete_task(packet, - (void (*)(void*))avc_free_packet, - packet); - hpsb_node_fill_packet(ne, packet); - - if (hpsb_send_packet(packet) < 0) { - avc_free_packet(packet); - atomic_set(&firesat->avc_reply_received, 1); - printk(KERN_ERR "%s: send failed!\n",__func__); - return -EIO; - } + /* + * AV/C specs say that answers should be sent within 150 ms. + * Time out after 200 ms. + */ + if (wait_event_timeout(firesat->avc_wait, + firesat->avc_reply_received, + HZ / 5) != 0) { + memcpy(RspFrm, firesat->respfrm, firesat->resp_length); + RspFrm->length = firesat->resp_length; - if(RspFrm) { - // AV/C specs say that answers should be send within - // 150 ms so let's time out after 200 ms - if (wait_event_timeout(firesat->avc_wait, - atomic_read(&firesat->avc_reply_received) == 1, - HZ / 5) == 0) { - packet_ok = 0; - } - else { - memcpy(RspFrm, firesat->respfrm, - firesat->resp_length); - RspFrm->length = firesat->resp_length; - if (avc_comm_debug > 0) { - log_response_frame(RspFrm); - } - } + return 0; } } - if (packet_ok == 0) { - printk(KERN_ERR "%s: AV/C response timed out 6 times.\n", - __func__); - return -ETIMEDOUT; - } - - return 0; + dev_err(&firesat->ud->device, "FCP response timed out\n"); + return -ETIMEDOUT; } -int AVCWrite(struct firesat*firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) +static int avc_write(struct firesat *firesat, + const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) { int ret; if (mutex_lock_interruptible(&firesat->avc_mutex)) return -EINTR; - ret = __AVCWrite(firesat, CmdFrm, RspFrm); + ret = __avc_write(firesat, CmdFrm, RspFrm); mutex_unlock(&firesat->avc_mutex); return ret; } -int AVCRecv(struct firesat *firesat, u8 *data, size_t length) +int avc_recv(struct firesat *firesat, u8 *data, size_t length) { AVCRspFrm *RspFrm = (AVCRspFrm *)data; @@ -260,87 +93,64 @@ int AVCRecv(struct firesat *firesat, u8 *data, size_t length) RspFrm->operand[2] == SFE_VENDOR_DE_COMPANYID_2 && RspFrm->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) { if (RspFrm->resp == CHANGED) { - firesat_handle_rc(RspFrm->operand[4] << 8 | - RspFrm->operand[5]); + firesat_handle_rc(firesat, + RspFrm->operand[4] << 8 | RspFrm->operand[5]); schedule_work(&firesat->remote_ctrl_work); } else if (RspFrm->resp != INTERIM) { - printk(KERN_INFO "firedtv: remote control result = " - "%d\n", RspFrm->resp); + dev_info(&firesat->ud->device, + "remote control result = %d\n", RspFrm->resp); } return 0; } - if(atomic_read(&firesat->avc_reply_received) == 1) { - printk(KERN_ERR "%s: received out-of-order AVC response, " - "ignored\n",__func__); - return -EINVAL; + if (firesat->avc_reply_received) { + dev_err(&firesat->ud->device, + "received out-of-order AVC response, ignored\n"); + return -EIO; } -// AVCRspFrm *resp=(AVCRspFrm *)data; -// int k; - -// printk(KERN_INFO "resp=0x%x\n",resp->resp); -// printk(KERN_INFO "cts=0x%x\n",resp->cts); -// printk(KERN_INFO "suid=0x%x\n",resp->suid); -// printk(KERN_INFO "sutyp=0x%x\n",resp->sutyp); -// printk(KERN_INFO "opcode=0x%x\n",resp->opcode); -// printk(KERN_INFO "length=%d\n",resp->length); -// for(k=0;k<2;k++) -// printk(KERN_INFO "operand[%d]=%02x\n",k,resp->operand[k]); + memcpy(firesat->respfrm, data, length); + firesat->resp_length = length; - memcpy(firesat->respfrm,data,length); - firesat->resp_length=length; - - atomic_set(&firesat->avc_reply_received, 1); + firesat->avc_reply_received = true; wake_up(&firesat->avc_wait); return 0; } -// tuning command for setting the relative LNB frequency (not supported by the AVC standard) -static void AVCTuner_tuneQPSK(struct firesat *firesat, struct dvb_frontend_parameters *params, AVCCmdFrm *CmdFrm) { - - memset(CmdFrm, 0, sizeof(AVCCmdFrm)); - - CmdFrm->cts = AVC; - CmdFrm->ctype = CONTROL; - CmdFrm->sutyp = 0x5; - CmdFrm->suid = firesat->subunit; +/* + * tuning command for setting the relative LNB frequency + * (not supported by the AVC standard) + */ +static void avc_tuner_tuneqpsk(struct firesat *firesat, + struct dvb_frontend_parameters *params, AVCCmdFrm *CmdFrm) +{ CmdFrm->opcode = VENDOR; - CmdFrm->operand[0]=SFE_VENDOR_DE_COMPANYID_0; - CmdFrm->operand[1]=SFE_VENDOR_DE_COMPANYID_1; - CmdFrm->operand[2]=SFE_VENDOR_DE_COMPANYID_2; - CmdFrm->operand[3]=SFE_VENDOR_OPCODE_TUNE_QPSK; - - printk(KERN_INFO "%s: tuning to frequency %u\n",__func__,params->frequency); - - CmdFrm->operand[4] = (params->frequency >> 24) & 0xFF; - CmdFrm->operand[5] = (params->frequency >> 16) & 0xFF; - CmdFrm->operand[6] = (params->frequency >> 8) & 0xFF; - CmdFrm->operand[7] = params->frequency & 0xFF; + CmdFrm->operand[0] = SFE_VENDOR_DE_COMPANYID_0; + CmdFrm->operand[1] = SFE_VENDOR_DE_COMPANYID_1; + CmdFrm->operand[2] = SFE_VENDOR_DE_COMPANYID_2; + CmdFrm->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK; - printk(KERN_INFO "%s: symbol rate = %uBd\n",__func__,params->u.qpsk.symbol_rate); + CmdFrm->operand[4] = (params->frequency >> 24) & 0xff; + CmdFrm->operand[5] = (params->frequency >> 16) & 0xff; + CmdFrm->operand[6] = (params->frequency >> 8) & 0xff; + CmdFrm->operand[7] = params->frequency & 0xff; - CmdFrm->operand[8] = ((params->u.qpsk.symbol_rate/1000) >> 8) & 0xFF; - CmdFrm->operand[9] = (params->u.qpsk.symbol_rate/1000) & 0xFF; + CmdFrm->operand[8] = ((params->u.qpsk.symbol_rate / 1000) >> 8) & 0xff; + CmdFrm->operand[9] = (params->u.qpsk.symbol_rate / 1000) & 0xff; switch(params->u.qpsk.fec_inner) { case FEC_1_2: - CmdFrm->operand[10] = 0x1; - break; + CmdFrm->operand[10] = 0x1; break; case FEC_2_3: - CmdFrm->operand[10] = 0x2; - break; + CmdFrm->operand[10] = 0x2; break; case FEC_3_4: - CmdFrm->operand[10] = 0x3; - break; + CmdFrm->operand[10] = 0x3; break; case FEC_5_6: - CmdFrm->operand[10] = 0x4; - break; + CmdFrm->operand[10] = 0x4; break; case FEC_7_8: - CmdFrm->operand[10] = 0x5; - break; + CmdFrm->operand[10] = 0x5; break; case FEC_4_5: case FEC_8_9: case FEC_AUTO: @@ -348,278 +158,287 @@ static void AVCTuner_tuneQPSK(struct firesat *firesat, struct dvb_frontend_param CmdFrm->operand[10] = 0x0; } - if(firesat->voltage == 0xff) + if (firesat->voltage == 0xff) CmdFrm->operand[11] = 0xff; + else if (firesat->voltage == SEC_VOLTAGE_18) /* polarisation */ + CmdFrm->operand[11] = 0; else - CmdFrm->operand[11] = (firesat->voltage==SEC_VOLTAGE_18)?0:1; // polarisation - if(firesat->tone == 0xff) + CmdFrm->operand[11] = 1; + + if (firesat->tone == 0xff) CmdFrm->operand[12] = 0xff; + else if (firesat->tone == SEC_TONE_ON) /* band */ + CmdFrm->operand[12] = 1; else - CmdFrm->operand[12] = (firesat->tone==SEC_TONE_ON)?1:0; // band + CmdFrm->operand[12] = 0; if (firesat->type == FireSAT_DVB_S2) { CmdFrm->operand[13] = 0x1; - CmdFrm->operand[14] = 0xFF; - CmdFrm->operand[15] = 0xFF; + CmdFrm->operand[14] = 0xff; + CmdFrm->operand[15] = 0xff; + CmdFrm->length = 20; + } else { + CmdFrm->length = 16; } +} + +static void avc_tuner_dsd_dvb_c(struct dvb_frontend_parameters *params, + AVCCmdFrm *CmdFrm) +{ + M_VALID_FLAGS flags; - CmdFrm->length = 16; + flags.Bits.Modulation = params->u.qam.modulation != QAM_AUTO; + flags.Bits.FEC_inner = params->u.qam.fec_inner != FEC_AUTO; + flags.Bits.FEC_outer = 0; + flags.Bits.Symbol_Rate = 1; + flags.Bits.Frequency = 1; + flags.Bits.Orbital_Pos = 0; + flags.Bits.Polarisation = 0; + flags.Bits.reserved_fields = 0; + flags.Bits.reserved1 = 0; + flags.Bits.Network_ID = 0; + + CmdFrm->opcode = DSD; + + CmdFrm->operand[0] = 0; /* source plug */ + CmdFrm->operand[1] = 0xd2; /* subfunction replace */ + CmdFrm->operand[2] = 0x20; /* system id = DVB */ + CmdFrm->operand[3] = 0x00; /* antenna number */ + /* system_specific_multiplex selection_length */ + CmdFrm->operand[4] = 0x11; + CmdFrm->operand[5] = flags.Valid_Word.ByteHi; /* valid_flags [0] */ + CmdFrm->operand[6] = flags.Valid_Word.ByteLo; /* valid_flags [1] */ + CmdFrm->operand[7] = 0x00; + CmdFrm->operand[8] = 0x00; + CmdFrm->operand[9] = 0x00; + CmdFrm->operand[10] = 0x00; + + CmdFrm->operand[11] = + (((params->frequency / 4000) >> 16) & 0xff) | (2 << 6); + CmdFrm->operand[12] = + ((params->frequency / 4000) >> 8) & 0xff; + CmdFrm->operand[13] = (params->frequency / 4000) & 0xff; + CmdFrm->operand[14] = + ((params->u.qpsk.symbol_rate / 1000) >> 12) & 0xff; + CmdFrm->operand[15] = + ((params->u.qpsk.symbol_rate / 1000) >> 4) & 0xff; + CmdFrm->operand[16] = + ((params->u.qpsk.symbol_rate / 1000) << 4) & 0xf0; + CmdFrm->operand[17] = 0x00; + + switch (params->u.qpsk.fec_inner) { + case FEC_1_2: + CmdFrm->operand[18] = 0x1; break; + case FEC_2_3: + CmdFrm->operand[18] = 0x2; break; + case FEC_3_4: + CmdFrm->operand[18] = 0x3; break; + case FEC_5_6: + CmdFrm->operand[18] = 0x4; break; + case FEC_7_8: + CmdFrm->operand[18] = 0x5; break; + case FEC_8_9: + CmdFrm->operand[18] = 0x6; break; + case FEC_4_5: + CmdFrm->operand[18] = 0x8; break; + case FEC_AUTO: + default: + CmdFrm->operand[18] = 0x0; + } + switch (params->u.qam.modulation) { + case QAM_16: + CmdFrm->operand[19] = 0x08; break; + case QAM_32: + CmdFrm->operand[19] = 0x10; break; + case QAM_64: + CmdFrm->operand[19] = 0x18; break; + case QAM_128: + CmdFrm->operand[19] = 0x20; break; + case QAM_256: + CmdFrm->operand[19] = 0x28; break; + case QAM_AUTO: + default: + CmdFrm->operand[19] = 0x00; + } + CmdFrm->operand[20] = 0x00; + CmdFrm->operand[21] = 0x00; + /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */ + CmdFrm->operand[22] = 0x00; + + CmdFrm->length = 28; } -int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, __u8 *status) { +static void avc_tuner_dsd_dvb_t(struct dvb_frontend_parameters *params, + AVCCmdFrm *CmdFrm) +{ + M_VALID_FLAGS flags; + + flags.Bits_T.GuardInterval = + params->u.ofdm.guard_interval != GUARD_INTERVAL_AUTO; + flags.Bits_T.CodeRateLPStream = + params->u.ofdm.code_rate_LP != FEC_AUTO; + flags.Bits_T.CodeRateHPStream = + params->u.ofdm.code_rate_HP != FEC_AUTO; + flags.Bits_T.HierarchyInfo = + params->u.ofdm.hierarchy_information != HIERARCHY_AUTO; + flags.Bits_T.Constellation = + params->u.ofdm.constellation != QAM_AUTO; + flags.Bits_T.Bandwidth = + params->u.ofdm.bandwidth != BANDWIDTH_AUTO; + flags.Bits_T.CenterFrequency = 1; + flags.Bits_T.reserved1 = 0; + flags.Bits_T.reserved2 = 0; + flags.Bits_T.OtherFrequencyFlag = 0; + flags.Bits_T.TransmissionMode = + params->u.ofdm.transmission_mode != TRANSMISSION_MODE_AUTO; + flags.Bits_T.NetworkId = 0; + + CmdFrm->opcode = DSD; + + CmdFrm->operand[0] = 0; /* source plug */ + CmdFrm->operand[1] = 0xd2; /* subfunction replace */ + CmdFrm->operand[2] = 0x20; /* system id = DVB */ + CmdFrm->operand[3] = 0x00; /* antenna number */ + /* system_specific_multiplex selection_length */ + CmdFrm->operand[4] = 0x0c; + CmdFrm->operand[5] = flags.Valid_Word.ByteHi; /* valid_flags [0] */ + CmdFrm->operand[6] = flags.Valid_Word.ByteLo; /* valid_flags [1] */ + CmdFrm->operand[7] = 0x0; + CmdFrm->operand[8] = (params->frequency / 10) >> 24; + CmdFrm->operand[9] = ((params->frequency / 10) >> 16) & 0xff; + CmdFrm->operand[10] = ((params->frequency / 10) >> 8) & 0xff; + CmdFrm->operand[11] = (params->frequency / 10) & 0xff; + + switch (params->u.ofdm.bandwidth) { + case BANDWIDTH_7_MHZ: + CmdFrm->operand[12] = 0x20; break; + case BANDWIDTH_8_MHZ: + case BANDWIDTH_6_MHZ: /* not defined by AVC spec */ + case BANDWIDTH_AUTO: + default: + CmdFrm->operand[12] = 0x00; + } + switch (params->u.ofdm.constellation) { + case QAM_16: + CmdFrm->operand[13] = 1 << 6; break; + case QAM_64: + CmdFrm->operand[13] = 2 << 6; break; + case QPSK: + default: + CmdFrm->operand[13] = 0x00; + } + switch (params->u.ofdm.hierarchy_information) { + case HIERARCHY_1: + CmdFrm->operand[13] |= 1 << 3; break; + case HIERARCHY_2: + CmdFrm->operand[13] |= 2 << 3; break; + case HIERARCHY_4: + CmdFrm->operand[13] |= 3 << 3; break; + case HIERARCHY_AUTO: + case HIERARCHY_NONE: + default: + break; + } + switch (params->u.ofdm.code_rate_HP) { + case FEC_2_3: + CmdFrm->operand[13] |= 1; break; + case FEC_3_4: + CmdFrm->operand[13] |= 2; break; + case FEC_5_6: + CmdFrm->operand[13] |= 3; break; + case FEC_7_8: + CmdFrm->operand[13] |= 4; break; + case FEC_1_2: + default: + break; + } + switch (params->u.ofdm.code_rate_LP) { + case FEC_2_3: + CmdFrm->operand[14] = 1 << 5; break; + case FEC_3_4: + CmdFrm->operand[14] = 2 << 5; break; + case FEC_5_6: + CmdFrm->operand[14] = 3 << 5; break; + case FEC_7_8: + CmdFrm->operand[14] = 4 << 5; break; + case FEC_1_2: + default: + CmdFrm->operand[14] = 0x00; break; + } + switch (params->u.ofdm.guard_interval) { + case GUARD_INTERVAL_1_16: + CmdFrm->operand[14] |= 1 << 3; break; + case GUARD_INTERVAL_1_8: + CmdFrm->operand[14] |= 2 << 3; break; + case GUARD_INTERVAL_1_4: + CmdFrm->operand[14] |= 3 << 3; break; + case GUARD_INTERVAL_1_32: + case GUARD_INTERVAL_AUTO: + default: + break; + } + switch (params->u.ofdm.transmission_mode) { + case TRANSMISSION_MODE_8K: + CmdFrm->operand[14] |= 1 << 1; break; + case TRANSMISSION_MODE_2K: + case TRANSMISSION_MODE_AUTO: + default: + break; + } + + CmdFrm->operand[15] = 0x00; /* network_ID[0] */ + CmdFrm->operand[16] = 0x00; /* network_ID[1] */ + /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */ + CmdFrm->operand[17] = 0x00; + + CmdFrm->length = 24; +} + +int avc_tuner_dsd(struct firesat *firesat, + struct dvb_frontend_parameters *params) +{ AVCCmdFrm CmdFrm; AVCRspFrm RspFrm; - M_VALID_FLAGS flags; - int k; - -// printk(KERN_INFO "%s\n", __func__); - - if (firesat->type == FireSAT_DVB_S || firesat->type == FireSAT_DVB_S2) - AVCTuner_tuneQPSK(firesat, params, &CmdFrm); - else { - if(firesat->type == FireSAT_DVB_T) { - flags.Bits_T.GuardInterval = (params->u.ofdm.guard_interval != GUARD_INTERVAL_AUTO); - flags.Bits_T.CodeRateLPStream = (params->u.ofdm.code_rate_LP != FEC_AUTO); - flags.Bits_T.CodeRateHPStream = (params->u.ofdm.code_rate_HP != FEC_AUTO); - flags.Bits_T.HierarchyInfo = (params->u.ofdm.hierarchy_information != HIERARCHY_AUTO); - flags.Bits_T.Constellation = (params->u.ofdm.constellation != QAM_AUTO); - flags.Bits_T.Bandwidth = (params->u.ofdm.bandwidth != BANDWIDTH_AUTO); - flags.Bits_T.CenterFrequency = 1; - flags.Bits_T.reserved1 = 0; - flags.Bits_T.reserved2 = 0; - flags.Bits_T.OtherFrequencyFlag = 0; - flags.Bits_T.TransmissionMode = (params->u.ofdm.transmission_mode != TRANSMISSION_MODE_AUTO); - flags.Bits_T.NetworkId = 0; - } else { - flags.Bits.Modulation = - (params->u.qam.modulation != QAM_AUTO); - flags.Bits.FEC_inner = - (params->u.qam.fec_inner != FEC_AUTO); - flags.Bits.FEC_outer = 0; - flags.Bits.Symbol_Rate = 1; - flags.Bits.Frequency = 1; - flags.Bits.Orbital_Pos = 0; - flags.Bits.Polarisation = 0; - flags.Bits.reserved_fields = 0; - flags.Bits.reserved1 = 0; - flags.Bits.Network_ID = 0; - } - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - - CmdFrm.cts = AVC; - CmdFrm.ctype = CONTROL; - CmdFrm.sutyp = 0x5; - CmdFrm.suid = firesat->subunit; - CmdFrm.opcode = DSD; - - CmdFrm.operand[0] = 0; // source plug - CmdFrm.operand[1] = 0xD2; // subfunction replace - CmdFrm.operand[2] = 0x20; // system id = DVB - CmdFrm.operand[3] = 0x00; // antenna number - // system_specific_multiplex selection_length - CmdFrm.operand[4] = (firesat->type == FireSAT_DVB_T)?0x0c:0x11; - CmdFrm.operand[5] = flags.Valid_Word.ByteHi; // valid_flags [0] - CmdFrm.operand[6] = flags.Valid_Word.ByteLo; // valid_flags [1] - - if(firesat->type == FireSAT_DVB_T) { - CmdFrm.operand[7] = 0x0; - CmdFrm.operand[8] = (params->frequency/10) >> 24; - CmdFrm.operand[9] = - ((params->frequency/10) >> 16) & 0xFF; - CmdFrm.operand[10] = - ((params->frequency/10) >> 8) & 0xFF; - CmdFrm.operand[11] = (params->frequency/10) & 0xFF; - switch(params->u.ofdm.bandwidth) { - case BANDWIDTH_7_MHZ: - CmdFrm.operand[12] = 0x20; - break; - case BANDWIDTH_8_MHZ: - case BANDWIDTH_6_MHZ: // not defined by AVC spec - case BANDWIDTH_AUTO: - default: - CmdFrm.operand[12] = 0x00; - } - switch(params->u.ofdm.constellation) { - case QAM_16: - CmdFrm.operand[13] = 1 << 6; - break; - case QAM_64: - CmdFrm.operand[13] = 2 << 6; - break; - case QPSK: - default: - CmdFrm.operand[13] = 0x00; - } - switch(params->u.ofdm.hierarchy_information) { - case HIERARCHY_1: - CmdFrm.operand[13] |= 1 << 3; - break; - case HIERARCHY_2: - CmdFrm.operand[13] |= 2 << 3; - break; - case HIERARCHY_4: - CmdFrm.operand[13] |= 3 << 3; - break; - case HIERARCHY_AUTO: - case HIERARCHY_NONE: - default: - break; - } - switch(params->u.ofdm.code_rate_HP) { - case FEC_2_3: - CmdFrm.operand[13] |= 1; - break; - case FEC_3_4: - CmdFrm.operand[13] |= 2; - break; - case FEC_5_6: - CmdFrm.operand[13] |= 3; - break; - case FEC_7_8: - CmdFrm.operand[13] |= 4; - break; - case FEC_1_2: - default: - break; - } - switch(params->u.ofdm.code_rate_LP) { - case FEC_2_3: - CmdFrm.operand[14] = 1 << 5; - break; - case FEC_3_4: - CmdFrm.operand[14] = 2 << 5; - break; - case FEC_5_6: - CmdFrm.operand[14] = 3 << 5; - break; - case FEC_7_8: - CmdFrm.operand[14] = 4 << 5; - break; - case FEC_1_2: - default: - CmdFrm.operand[14] = 0x00; - break; - } - switch(params->u.ofdm.guard_interval) { - case GUARD_INTERVAL_1_16: - CmdFrm.operand[14] |= 1 << 3; - break; - case GUARD_INTERVAL_1_8: - CmdFrm.operand[14] |= 2 << 3; - break; - case GUARD_INTERVAL_1_4: - CmdFrm.operand[14] |= 3 << 3; - break; - case GUARD_INTERVAL_1_32: - case GUARD_INTERVAL_AUTO: - default: - break; - } - switch(params->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_8K: - CmdFrm.operand[14] |= 1 << 1; - break; - case TRANSMISSION_MODE_2K: - case TRANSMISSION_MODE_AUTO: - default: - break; - } - - CmdFrm.operand[15] = 0x00; // network_ID[0] - CmdFrm.operand[16] = 0x00; // network_ID[1] - CmdFrm.operand[17] = 0x00; // Nr_of_dsd_sel_specs = 0 - > No PIDs are transmitted - - CmdFrm.length = 24; - } else { - CmdFrm.operand[7] = 0x00; - CmdFrm.operand[8] = 0x00; - CmdFrm.operand[9] = 0x00; - CmdFrm.operand[10] = 0x00; - - CmdFrm.operand[11] = - (((params->frequency/4000) >> 16) & 0xFF) | (2 << 6); - CmdFrm.operand[12] = - ((params->frequency/4000) >> 8) & 0xFF; - CmdFrm.operand[13] = (params->frequency/4000) & 0xFF; - CmdFrm.operand[14] = - ((params->u.qpsk.symbol_rate/1000) >> 12) & 0xFF; - CmdFrm.operand[15] = - ((params->u.qpsk.symbol_rate/1000) >> 4) & 0xFF; - CmdFrm.operand[16] = - ((params->u.qpsk.symbol_rate/1000) << 4) & 0xF0; - CmdFrm.operand[17] = 0x00; - switch(params->u.qpsk.fec_inner) { - case FEC_1_2: - CmdFrm.operand[18] = 0x1; - break; - case FEC_2_3: - CmdFrm.operand[18] = 0x2; - break; - case FEC_3_4: - CmdFrm.operand[18] = 0x3; - break; - case FEC_5_6: - CmdFrm.operand[18] = 0x4; - break; - case FEC_7_8: - CmdFrm.operand[18] = 0x5; - break; - case FEC_8_9: - CmdFrm.operand[18] = 0x6; - break; - case FEC_4_5: - CmdFrm.operand[18] = 0x8; - break; - case FEC_AUTO: - default: - CmdFrm.operand[18] = 0x0; - } - switch(params->u.qam.modulation) { - case QAM_16: - CmdFrm.operand[19] = 0x08; // modulation - break; - case QAM_32: - CmdFrm.operand[19] = 0x10; // modulation - break; - case QAM_64: - CmdFrm.operand[19] = 0x18; // modulation - break; - case QAM_128: - CmdFrm.operand[19] = 0x20; // modulation - break; - case QAM_256: - CmdFrm.operand[19] = 0x28; // modulation - break; - case QAM_AUTO: - default: - CmdFrm.operand[19] = 0x00; // modulation - } - CmdFrm.operand[20] = 0x00; - CmdFrm.operand[21] = 0x00; - CmdFrm.operand[22] = 0x00; // Nr_of_dsd_sel_specs = 0 - > No PIDs are transmitted - - CmdFrm.length=28; - } - } // AVCTuner_DSD_direct + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - if((k=AVCWrite(firesat,&CmdFrm,&RspFrm))) - return k; + CmdFrm.cts = AVC; + CmdFrm.ctype = CONTROL; + CmdFrm.sutyp = 0x5; + CmdFrm.suid = firesat->subunit; - mdelay(500); + switch (firesat->type) { + case FireSAT_DVB_S: + case FireSAT_DVB_S2: + avc_tuner_tuneqpsk(firesat, params, &CmdFrm); break; + case FireSAT_DVB_C: + avc_tuner_dsd_dvb_c(params, &CmdFrm); break; + case FireSAT_DVB_T: + avc_tuner_dsd_dvb_t(params, &CmdFrm); break; + default: + BUG(); + } + if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) + return -EIO; + + msleep(500); +#if 0 + /* FIXME: */ + /* u8 *status was an out-parameter of avc_tuner_dsd, unused by caller */ if(status) *status=RspFrm.operand[2]; +#endif return 0; } -int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]) +int avc_tuner_set_pids(struct firesat *firesat, unsigned char pidc, u16 pid[]) { AVCCmdFrm CmdFrm; AVCRspFrm RspFrm; - int pos,k; + int pos, k; - if(pidc > 16 && pidc != 0xFF) + if (pidc > 16 && pidc != 0xff) return -EINVAL; memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); @@ -637,9 +456,9 @@ int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]) CmdFrm.operand[4] = 0x00; // system_specific_multiplex selection_length CmdFrm.operand[5] = pidc; // Nr_of_dsd_sel_specs - pos=6; - if(pidc != 0xFF) { - for(k=0;k PID CmdFrm.operand[pos++] = (pid[k] >> 8) & 0x1F; @@ -647,25 +466,20 @@ int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]) CmdFrm.operand[pos++] = 0x00; // tableID CmdFrm.operand[pos++] = 0x00; // filter_length } - } - CmdFrm.length = pos+3; - if((pos+3)%4) - CmdFrm.length += 4 - ((pos+3)%4); + CmdFrm.length = ALIGN(3 + pos, 4); - if((k=AVCWrite(firesat,&CmdFrm,&RspFrm))) - return k; + if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) + return -EIO; - mdelay(50); + msleep(50); return 0; } -int AVCTuner_GetTS(struct firesat *firesat){ +int avc_tuner_get_ts(struct firesat *firesat) +{ AVCCmdFrm CmdFrm; AVCRspFrm RspFrm; - int k; - - //printk(KERN_INFO "%s\n", __func__); memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); @@ -688,14 +502,14 @@ int AVCTuner_GetTS(struct firesat *firesat){ CmdFrm.length = (firesat->type == FireSAT_DVB_T)?24:28; - if ((k=AVCWrite(firesat, &CmdFrm, &RspFrm))) - return k; + if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) + return -EIO; - mdelay(250); + msleep(250); return 0; } -int AVCIdentifySubunit(struct firesat *firesat) +int avc_identify_subunit(struct firesat *firesat) { AVCCmdFrm CmdFrm; AVCRspFrm RspFrm; @@ -718,22 +532,21 @@ int AVCIdentifySubunit(struct firesat *firesat) CmdFrm.length=12; - if(AVCWrite(firesat,&CmdFrm,&RspFrm)<0) + if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) return -EIO; - if(RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) { - printk(KERN_ERR "%s: AVCWrite returned error code %d\n", - __func__, RspFrm.resp); - return -EINVAL; - } - if(((RspFrm.operand[3] << 8) + RspFrm.operand[4]) != 8) { - printk(KERN_ERR "%s: Invalid response length\n", __func__); + if ((RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) || + (RspFrm.operand[3] << 8) + RspFrm.operand[4] != 8) { + dev_err(&firesat->ud->device, + "cannot read subunit identifier\n"); return -EINVAL; } return 0; } -int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_info) { +int avc_tuner_status(struct firesat *firesat, + ANTENNA_INPUT_INFO *antenna_input_info) +{ AVCCmdFrm CmdFrm; AVCRspFrm RspFrm; int length; @@ -754,37 +567,32 @@ int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_in CmdFrm.operand[5]=0x00; CmdFrm.operand[6]=0x00; CmdFrm.length=12; - if (AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) + + if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) return -EIO; - if(RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) { - printk(KERN_ERR "%s: AVCWrite returned code %d\n", - __func__, RspFrm.resp); + if (RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) { + dev_err(&firesat->ud->device, "cannot read tuner status\n"); return -EINVAL; } length = RspFrm.operand[9]; - if(RspFrm.operand[1] == 0x10 && length == sizeof(ANTENNA_INPUT_INFO)) - { - memcpy(antenna_input_info, &RspFrm.operand[10], - sizeof(ANTENNA_INPUT_INFO)); - return 0; + if (RspFrm.operand[1] != 0x10 || length != sizeof(ANTENNA_INPUT_INFO)) { + dev_err(&firesat->ud->device, "got invalid tuner status\n"); + return -EINVAL; } - printk(KERN_ERR "%s: invalid tuner status (op=%d,length=%d) returned " - "from AVC\n", __func__, RspFrm.operand[1], length); - return -EINVAL; + + memcpy(antenna_input_info, &RspFrm.operand[10], length); + return 0; } -int AVCLNBControl(struct firesat *firesat, char voltage, char burst, - char conttone, char nrdiseq, - struct dvb_diseqc_master_cmd *diseqcmd) +int avc_lnb_control(struct firesat *firesat, char voltage, char burst, + char conttone, char nrdiseq, + struct dvb_diseqc_master_cmd *diseqcmd) { AVCCmdFrm CmdFrm; AVCRspFrm RspFrm; - int i,j; - - printk(KERN_INFO "%s: voltage = %x, burst = %x, conttone = %x\n", - __func__, voltage, burst, conttone); + int i, j, k; memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); @@ -804,85 +612,33 @@ int AVCLNBControl(struct firesat *firesat, char voltage, char burst, i=6; - for(j=0;jud->device, "LNB control failed\n"); return -EINVAL; } - if(subunitcount) - *subunitcount = (RspFrm.operand[1] & 0x7) + 1; - return 0; } -int AVCRegisterRemoteControl(struct firesat *firesat) +int avc_register_remote_control(struct firesat *firesat) { AVCCmdFrm CmdFrm; -// printk(KERN_INFO "%s\n",__func__); - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); CmdFrm.cts = AVC; @@ -898,7 +654,7 @@ int AVCRegisterRemoteControl(struct firesat *firesat) CmdFrm.length = 8; - return AVCWrite(firesat, &CmdFrm, NULL); + return avc_write(firesat, &CmdFrm, NULL); } void avc_remote_ctrl_work(struct work_struct *work) @@ -907,12 +663,12 @@ void avc_remote_ctrl_work(struct work_struct *work) container_of(work, struct firesat, remote_ctrl_work); /* Should it be rescheduled in failure cases? */ - AVCRegisterRemoteControl(firesat); + avc_register_remote_control(firesat); } -int AVCTuner_Host2Ca(struct firesat *firesat) +#if 0 /* FIXME: unused */ +int avc_tuner_host2ca(struct firesat *firesat) { - AVCCmdFrm CmdFrm; AVCRspFrm RspFrm; @@ -933,37 +689,39 @@ int AVCTuner_Host2Ca(struct firesat *firesat) CmdFrm.operand[7] = 0; // length CmdFrm.length = 12; - if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) + if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) return -EIO; return 0; } +#endif static int get_ca_object_pos(AVCRspFrm *RspFrm) { int length = 1; - // Check length of length field + /* Check length of length field */ if (RspFrm->operand[7] & 0x80) - length = (RspFrm->operand[7] & 0x7F) + 1; + length = (RspFrm->operand[7] & 0x7f) + 1; return length + 7; } static int get_ca_object_length(AVCRspFrm *RspFrm) { +#if 0 /* FIXME: unused */ int size = 0; int i; - if (RspFrm->operand[7] & 0x80) { - for (i = 0; i < (RspFrm->operand[7] & 0x7F); i++) { + if (RspFrm->operand[7] & 0x80) + for (i = 0; i < (RspFrm->operand[7] & 0x7f); i++) { size <<= 8; size += RspFrm->operand[8 + i]; } - } +#endif return RspFrm->operand[7]; } -int avc_ca_app_info(struct firesat *firesat, char *app_info, int *length) +int avc_ca_app_info(struct firesat *firesat, char *app_info, unsigned int *len) { AVCCmdFrm CmdFrm; AVCRspFrm RspFrm; @@ -984,9 +742,10 @@ int avc_ca_app_info(struct firesat *firesat, char *app_info, int *length) CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; // ca tag CmdFrm.length = 12; - if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) + if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) return -EIO; + /* FIXME: check response code and validate response data */ pos = get_ca_object_pos(&RspFrm); app_info[0] = (TAG_APP_INFO >> 16) & 0xFF; @@ -995,16 +754,16 @@ int avc_ca_app_info(struct firesat *firesat, char *app_info, int *length) app_info[3] = 6 + RspFrm.operand[pos + 4]; app_info[4] = 0x01; memcpy(&app_info[5], &RspFrm.operand[pos], 5 + RspFrm.operand[pos + 4]); - *length = app_info[3] + 4; + *len = app_info[3] + 4; return 0; } -int avc_ca_info(struct firesat *firesat, char *app_info, int *length) +int avc_ca_info(struct firesat *firesat, char *app_info, unsigned int *len) { AVCCmdFrm CmdFrm; AVCRspFrm RspFrm; - int pos; + /* int pos; FIXME: unused */ memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); CmdFrm.cts = AVC; @@ -1021,17 +780,17 @@ int avc_ca_info(struct firesat *firesat, char *app_info, int *length) CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; // ca tag CmdFrm.length = 12; - if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) + if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) return -EIO; - pos = get_ca_object_pos(&RspFrm); + /* pos = get_ca_object_pos(&RspFrm); FIXME: unused */ app_info[0] = (TAG_CA_INFO >> 16) & 0xFF; app_info[1] = (TAG_CA_INFO >> 8) & 0xFF; app_info[2] = (TAG_CA_INFO >> 0) & 0xFF; app_info[3] = 2; app_info[4] = app_info[5]; app_info[5] = app_info[6]; - *length = app_info[3] + 4; + *len = app_info[3] + 4; return 0; } @@ -1059,7 +818,7 @@ int avc_ca_reset(struct firesat *firesat) CmdFrm.operand[8] = 0; // force hardware reset CmdFrm.length = 12; - if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) + if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) return -EIO; return 0; @@ -1085,9 +844,8 @@ int avc_ca_pmt(struct firesat *firesat, char *msg, int length) CmdFrm.opcode = VENDOR; if (msg[0] != LIST_MANAGEMENT_ONLY) { - printk(KERN_INFO "%s: list_management %d not support. " - "Forcing list_management to \"only\" (3). \n", - __func__, msg[0]); + dev_info(&firesat->ud->device, + "forcing list_management to ONLY\n"); msg[0] = LIST_MANAGEMENT_ONLY; } // We take the cmd_id from the programme level only! @@ -1134,20 +892,17 @@ int avc_ca_pmt(struct firesat *firesat, char *msg, int length) read_pos = 6; write_pos = 22; if (program_info_length > 0) { -/* printk(KERN_INFO "Copying descriptors at programme level.\n"); */ pmt_cmd_id = msg[read_pos++]; - if (pmt_cmd_id != 1 && pmt_cmd_id !=4) { - printk(KERN_ERR "Invalid pmt_cmd_id=%d.\n", - pmt_cmd_id); - } + if (pmt_cmd_id != 1 && pmt_cmd_id != 4) + dev_err(&firesat->ud->device, + "invalid pmt_cmd_id %d\n", pmt_cmd_id); + memcpy(&CmdFrm.operand[write_pos], &msg[read_pos], program_info_length); read_pos += program_info_length; write_pos += program_info_length; } while (read_pos < length) { -/* printk(KERN_INFO "Copying descriptors at stream level for " */ -/* "stream type %d.\n", msg[read_pos]); */ CmdFrm.operand[write_pos++] = msg[read_pos++]; CmdFrm.operand[write_pos++] = msg[read_pos++]; CmdFrm.operand[write_pos++] = msg[read_pos++]; @@ -1160,10 +915,11 @@ int avc_ca_pmt(struct firesat *firesat, char *msg, int length) CmdFrm.operand[write_pos++] = es_info_length & 0xFF; if (es_info_length > 0) { pmt_cmd_id = msg[read_pos++]; - if (pmt_cmd_id != 1 && pmt_cmd_id !=4) { - printk(KERN_ERR "Invalid pmt_cmd_id=%d at " - "stream level.\n", pmt_cmd_id); - } + if (pmt_cmd_id != 1 && pmt_cmd_id != 4) + dev_err(&firesat->ud->device, + "invalid pmt_cmd_id %d " + "at stream level\n", pmt_cmd_id); + memcpy(&CmdFrm.operand[write_pos], &msg[read_pos], es_info_length); read_pos += es_info_length; @@ -1187,20 +943,18 @@ int avc_ca_pmt(struct firesat *firesat, char *msg, int length) CmdFrm.operand[write_pos - 2] = (crc32_csum >> 8) & 0xFF; CmdFrm.operand[write_pos - 1] = (crc32_csum >> 0) & 0xFF; - CmdFrm.length = write_pos + 3; - if ((write_pos + 3) % 4) - CmdFrm.length += 4 - ((write_pos + 3) % 4); + CmdFrm.length = ALIGN(3 + write_pos, 4); - if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) + if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) return -EIO; if (RspFrm.resp != ACCEPTED) { - printk(KERN_ERR "Answer to CA PMT was %d\n", RspFrm.resp); + dev_err(&firesat->ud->device, + "CA PMT failed with response 0x%x\n", RspFrm.resp); return -EFAULT; } return 0; - } int avc_ca_get_time_date(struct firesat *firesat, int *interval) @@ -1225,9 +979,11 @@ int avc_ca_get_time_date(struct firesat *firesat, int *interval) CmdFrm.operand[7] = 0; // length CmdFrm.length = 12; - if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) + if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) return -EIO; + /* FIXME: check response code and validate response data */ + *interval = RspFrm.operand[get_ca_object_pos(&RspFrm)]; return 0; @@ -1255,13 +1011,13 @@ int avc_ca_enter_menu(struct firesat *firesat) CmdFrm.operand[7] = 0; // length CmdFrm.length = 12; - if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) + if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) return -EIO; return 0; } -int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, int *length) +int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, unsigned int *len) { AVCCmdFrm CmdFrm; AVCRspFrm RspFrm; @@ -1283,11 +1039,13 @@ int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, int *length) CmdFrm.operand[7] = 0; // length CmdFrm.length = 12; - if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) + if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) return -EIO; - *length = get_ca_object_length(&RspFrm); - memcpy(mmi_object, &RspFrm.operand[get_ca_object_pos(&RspFrm)], *length); + /* FIXME: check response code and validate response data */ + + *len = get_ca_object_length(&RspFrm); + memcpy(mmi_object, &RspFrm.operand[get_ca_object_pos(&RspFrm)], *len); return 0; } diff --git a/drivers/media/dvb/firesat/avc_api.h b/drivers/media/dvb/firesat/avc_api.h index 66f419a6f7c..9d2efd8ff17 100644 --- a/drivers/media/dvb/firesat/avc_api.h +++ b/drivers/media/dvb/firesat/avc_api.h @@ -26,15 +26,6 @@ **************************************************************/ #define LIST_MANAGEMENT_ONLY 0x03 -/************************************************************* - FCP Address range -**************************************************************/ - -#define RESPONSE_REGISTER 0xFFFFF0000D00ULL -#define COMMAND_REGISTER 0xFFFFF0000B00ULL -#define PCR_BASE_ADDRESS 0xFFFFF0000900ULL - - /************************************************************ definition of structures *************************************************************/ @@ -413,34 +404,29 @@ struct dvb_diseqc_master_cmd; struct dvb_frontend_parameters; struct firesat; -int AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, - AVCRspFrm *RspFrm); -int AVCRecv(struct firesat *firesat, u8 *data, size_t length); +int avc_recv(struct firesat *firesat, u8 *data, size_t length); int AVCTuner_DSIT(struct firesat *firesat, int Source_Plug, struct dvb_frontend_parameters *params, __u8 *status); -int AVCTunerStatus(struct firesat *firesat, +int avc_tuner_status(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_info); -int AVCTuner_DSD(struct firesat *firesat, - struct dvb_frontend_parameters *params, __u8 *status); -int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]); -int AVCTuner_GetTS(struct firesat *firesat); - -int AVCIdentifySubunit(struct firesat *firesat); -int AVCLNBControl(struct firesat *firesat, char voltage, char burst, +int avc_tuner_dsd(struct firesat *firesat, + struct dvb_frontend_parameters *params); +int avc_tuner_set_pids(struct firesat *firesat, unsigned char pidc, u16 pid[]); +int avc_tuner_get_ts(struct firesat *firesat); +int avc_identify_subunit(struct firesat *firesat); +int avc_lnb_control(struct firesat *firesat, char voltage, char burst, char conttone, char nrdiseq, struct dvb_diseqc_master_cmd *diseqcmd); -int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount); void avc_remote_ctrl_work(struct work_struct *work); -int AVCRegisterRemoteControl(struct firesat *firesat); -int AVCTuner_Host2Ca(struct firesat *firesat); -int avc_ca_app_info(struct firesat *firesat, char *app_info, int *length); -int avc_ca_info(struct firesat *firesat, char *app_info, int *length); +int avc_register_remote_control(struct firesat *firesat); +int avc_ca_app_info(struct firesat *firesat, char *app_info, unsigned int *len); +int avc_ca_info(struct firesat *firesat, char *app_info, unsigned int *len); int avc_ca_reset(struct firesat *firesat); int avc_ca_pmt(struct firesat *firesat, char *app_info, int length); int avc_ca_get_time_date(struct firesat *firesat, int *interval); int avc_ca_enter_menu(struct firesat *firesat); -int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, int *length); +int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, unsigned int *len); #endif /* _AVC_API_H */ diff --git a/drivers/media/dvb/firesat/cmp.c b/drivers/media/dvb/firesat/cmp.c index d1bafba615e..8e98b814e43 100644 --- a/drivers/media/dvb/firesat/cmp.c +++ b/drivers/media/dvb/firesat/cmp.c @@ -10,37 +10,21 @@ * the License, or (at your option) any later version. */ +#include #include #include #include -#include +#include + #include -#include -#include #include #include "avc_api.h" #include "cmp.h" #include "firesat.h" -typedef struct _OPCR -{ - __u8 PTPConnCount : 6 ; // Point to point connect. counter - __u8 BrConnCount : 1 ; // Broadcast connection counter - __u8 OnLine : 1 ; // On Line - - __u8 ChNr : 6 ; // Channel number - __u8 Res : 2 ; // Reserved - - __u8 PayloadHi : 2 ; // Payoad high bits - __u8 OvhdID : 4 ; // Overhead ID - __u8 DataRate : 2 ; // Data Rate - - __u8 PayloadLo ; // Payoad low byte -} OPCR ; - -#define FIRESAT_SPEED IEEE1394_SPEED_400 +#define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL static int cmp_read(struct firesat *firesat, void *buf, u64 addr, size_t len) { @@ -49,151 +33,139 @@ static int cmp_read(struct firesat *firesat, void *buf, u64 addr, size_t len) if (mutex_lock_interruptible(&firesat->avc_mutex)) return -EINTR; - ret = hpsb_read(firesat->host, firesat->nodeentry->nodeid, - firesat->nodeentry->generation, addr, buf, len); + ret = hpsb_node_read(firesat->ud->ne, addr, buf, len); + if (ret < 0) + dev_err(&firesat->ud->device, "CMP: read I/O error\n"); mutex_unlock(&firesat->avc_mutex); return ret; } -static int cmp_lock(struct firesat *firesat, quadlet_t *data, u64 addr, - quadlet_t arg, int ext_tcode) +static int cmp_lock(struct firesat *firesat, void *data, u64 addr, __be32 arg, + int ext_tcode) { int ret; if (mutex_lock_interruptible(&firesat->avc_mutex)) return -EINTR; - ret = hpsb_lock(firesat->host, firesat->nodeentry->nodeid, - firesat->nodeentry->generation, - addr, ext_tcode, data, arg); + ret = hpsb_node_lock(firesat->ud->ne, addr, ext_tcode, data, + (__force quadlet_t)arg); + if (ret < 0) + dev_err(&firesat->ud->device, "CMP: lock I/O error\n"); mutex_unlock(&firesat->avc_mutex); return ret; } -//try establishing a point-to-point connection (may be interrupted by a busreset -int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, int iso_channel) { - unsigned int BWU; //bandwidth to allocate +static inline u32 get_opcr(__be32 opcr, u32 mask, u32 shift) +{ + return (be32_to_cpu(opcr) >> shift) & mask; +} + +static inline void set_opcr(__be32 *opcr, u32 value, u32 mask, u32 shift) +{ + *opcr &= ~cpu_to_be32(mask << shift); + *opcr |= cpu_to_be32((value & mask) << shift); +} - quadlet_t old_oPCR,test_oPCR = 0x0; - u64 oPCR_address=0xfffff0000904ull+(output_plug << 2); - int result=cmp_read(firesat, &test_oPCR, oPCR_address, 4); +#define get_opcr_online(v) get_opcr((v), 0x1, 31) +#define get_opcr_p2p_connections(v) get_opcr((v), 0x3f, 24) +#define get_opcr_channel(v) get_opcr((v), 0x3f, 16) -/* printk(KERN_INFO "%s: nodeid = %d\n",__func__,firesat->nodeentry->nodeid); */ +#define set_opcr_p2p_connections(p, v) set_opcr((p), (v), 0x3f, 24) +#define set_opcr_channel(p, v) set_opcr((p), (v), 0x3f, 16) +#define set_opcr_data_rate(p, v) set_opcr((p), (v), 0x3, 14) +#define set_opcr_overhead_id(p, v) set_opcr((p), (v), 0xf, 10) - if (result < 0) { - printk("%s: cannot read oPCR\n", __func__); - return result; - } else { -/* printk(KERN_INFO "%s: oPCR = %08x\n",__func__,test_oPCR); */ - do { - OPCR *hilf= (OPCR*) &test_oPCR; - - if (!hilf->OnLine) { - printk("%s: Output offline; oPCR: %08x\n", __func__, test_oPCR); - return -EBUSY; - } else { - quadlet_t new_oPCR; - - old_oPCR=test_oPCR; - if (hilf->PTPConnCount) { - if (hilf->ChNr != iso_channel) { - printk("%s: Output plug has already connection on channel %u; cannot change it to channel %u\n",__func__,hilf->ChNr,iso_channel); - return -EBUSY; - } else - printk(KERN_INFO "%s: Overlaying existing connection; connection counter was: %u\n",__func__, hilf->PTPConnCount); - BWU=0; //we allocate no bandwidth (is this necessary?) - } else { - hilf->ChNr=iso_channel; - hilf->DataRate=FIRESAT_SPEED; - - hilf->OvhdID=0; //FIXME: that is for worst case -> optimize - BWU=hilf->OvhdID?hilf->OvhdID*32:512; - BWU += (hilf->PayloadLo + (hilf->PayloadHi << 8) +3) * (2 << (3-hilf->DataRate)); -/* if (allocate_1394_resources(iso_channel,BWU)) - { - cout << "Allocation of resources failed\n"; - return -2; - }*/ - } - - hilf->PTPConnCount++; - new_oPCR=test_oPCR; -/* printk(KERN_INFO "%s: trying compare_swap...\n",__func__); */ -/* printk(KERN_INFO "%s: oPCR_old: %08x, oPCR_new: %08x\n",__func__, old_oPCR, new_oPCR); */ - result=cmp_lock(firesat, &test_oPCR, oPCR_address, old_oPCR, 2); - - if (result < 0) { - printk("%s: cannot compare_swap oPCR\n",__func__); - return result; - } - if ((old_oPCR != test_oPCR) && (!((OPCR*) &old_oPCR)->PTPConnCount)) - { - printk("%s: change of oPCR failed -> freeing resources\n",__func__); -// hilf= (OPCR*) &new_oPCR; -// unsigned int BWU=hilf->OvhdID?hilf->OvhdID*32:512; -// BWU += (hilf->Payload+3) * (2 << (3-hilf->DataRate)); -/* if (deallocate_1394_resources(iso_channel,BWU)) - { - - cout << "Deallocation of resources failed\n"; - return -3; - }*/ - } - } +int cmp_establish_pp_connection(struct firesat *firesat, int plug, int channel) +{ + __be32 old_opcr, opcr; + u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); + int attempts = 0; + int ret; + + ret = cmp_read(firesat, &opcr, opcr_address, 4); + if (ret < 0) + return ret; + +repeat: + if (!get_opcr_online(opcr)) { + dev_err(&firesat->ud->device, "CMP: output offline\n"); + return -EBUSY; + } + + old_opcr = opcr; + + if (get_opcr_p2p_connections(opcr)) { + if (get_opcr_channel(opcr) != channel) { + dev_err(&firesat->ud->device, + "CMP: cannot change channel\n"); + return -EBUSY; } - while (old_oPCR != test_oPCR); + dev_info(&firesat->ud->device, + "CMP: overlaying existing connection\n"); + + /* We don't allocate isochronous resources. */ + } else { + set_opcr_channel(&opcr, channel); + set_opcr_data_rate(&opcr, IEEE1394_SPEED_400); + + /* FIXME: this is for the worst case - optimize */ + set_opcr_overhead_id(&opcr, 0); + + /* FIXME: allocate isochronous channel and bandwidth at IRM */ } + + set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) + 1); + + ret = cmp_lock(firesat, &opcr, opcr_address, old_opcr, 2); + if (ret < 0) + return ret; + + if (old_opcr != opcr) { + /* + * FIXME: if old_opcr.P2P_Connections > 0, + * deallocate isochronous channel and bandwidth at IRM + */ + + if (++attempts < 6) /* arbitrary limit */ + goto repeat; + return -EBUSY; + } + return 0; } -//try breaking a point-to-point connection (may be interrupted by a busreset -int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug,int iso_channel) { - quadlet_t old_oPCR,test_oPCR; +void cmp_break_pp_connection(struct firesat *firesat, int plug, int channel) +{ + __be32 old_opcr, opcr; + u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); + int attempts = 0; + + if (cmp_read(firesat, &opcr, opcr_address, 4) < 0) + return; + +repeat: + if (!get_opcr_online(opcr) || !get_opcr_p2p_connections(opcr) || + get_opcr_channel(opcr) != channel) { + dev_err(&firesat->ud->device, "CMP: no connection to break\n"); + return; + } + + old_opcr = opcr; + set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) - 1); - u64 oPCR_address=0xfffff0000904ull+(output_plug << 2); - int result=cmp_read(firesat, &test_oPCR, oPCR_address, 4); + if (cmp_lock(firesat, &opcr, opcr_address, old_opcr, 2) < 0) + return; -/* printk(KERN_INFO "%s\n",__func__); */ + if (old_opcr != opcr) { + /* + * FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last + * owner, deallocate isochronous channel and bandwidth at IRM + */ - if (result < 0) { - printk("%s: cannot read oPCR\n", __func__); - return result; - } else { - do { - OPCR *hilf= (OPCR*) &test_oPCR; - - if (!hilf->OnLine || !hilf->PTPConnCount || hilf->ChNr != iso_channel) { - printk("%s: Output plug does not have PtP-connection on that channel; oPCR: %08x\n", __func__, test_oPCR); - return -EINVAL; - } else { - quadlet_t new_oPCR; - old_oPCR=test_oPCR; - hilf->PTPConnCount--; - new_oPCR=test_oPCR; - -// printk(KERN_INFO "%s: trying compare_swap...\n", __func__); - result=cmp_lock(firesat, &test_oPCR, oPCR_address, old_oPCR, 2); - if (result < 0) { - printk("%s: cannot compare_swap oPCR\n",__func__); - return result; - } - } - - } while (old_oPCR != test_oPCR); - -/* hilf = (OPCR*) &old_oPCR; - if (hilf->PTPConnCount == 1) { // if we were the last owner of this connection - cout << "deallocating 1394 resources\n"; - unsigned int BWU=hilf->OvhdID?hilf->OvhdID*32:512; - BWU += (hilf->PayloadLo + (hilf->PayloadHi << 8) +3) * (2 << (3-hilf->DataRate)); - if (deallocate_1394_resources(iso_channel,BWU)) - { - cout << "Deallocation of resources failed\n"; - return -3; - } - }*/ - } - return 0; + if (++attempts < 6) /* arbitrary limit */ + goto repeat; + } } diff --git a/drivers/media/dvb/firesat/cmp.h b/drivers/media/dvb/firesat/cmp.h index 600d5784dc7..d92f6c7fb5d 100644 --- a/drivers/media/dvb/firesat/cmp.h +++ b/drivers/media/dvb/firesat/cmp.h @@ -3,9 +3,7 @@ struct firesat; -int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, - int iso_channel); -int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug, - int iso_channel); +int cmp_establish_pp_connection(struct firesat *firesat, int plug, int channel); +void cmp_break_pp_connection(struct firesat *firesat, int plug, int channel); #endif /* _CMP_H */ diff --git a/drivers/media/dvb/firesat/firesat-ci.c b/drivers/media/dvb/firesat/firesat-ci.c index 3ef25cc4bfd..0deb47eefa1 100644 --- a/drivers/media/dvb/firesat/firesat-ci.c +++ b/drivers/media/dvb/firesat/firesat-ci.c @@ -20,29 +20,18 @@ #include "firesat.h" #include "firesat-ci.h" -static unsigned int ca_debug = 0; -module_param(ca_debug, int, 0644); -MODULE_PARM_DESC(ca_debug, "debug logging of ca system, default is 0 (no)"); - static int firesat_ca_ready(ANTENNA_INPUT_INFO *info) { - if (ca_debug != 0) - printk("%s: CaMmi=%d, CaInit=%d, CaError=%d, CaDvb=%d, " - "CaModule=%d, CaAppInfo=%d, CaDateTime=%d, " - "CaPmt=%d\n", __func__, info->CaMmi, - info->CaInitializationStatus, info->CaErrorFlag, - info->CaDvbFlag, info->CaModulePresentStatus, - info->CaApplicationInfo, - info->CaDateTimeRequest, info->CaPmtReply); return info->CaInitializationStatus == 1 && - info->CaErrorFlag == 0 && - info->CaDvbFlag == 1 && - info->CaModulePresentStatus == 1; + info->CaErrorFlag == 0 && + info->CaDvbFlag == 1 && + info->CaModulePresentStatus == 1; } static int firesat_get_ca_flags(ANTENNA_INPUT_INFO *info) { int flags = 0; + if (info->CaModulePresentStatus == 1) flags |= CA_CI_MODULE_PRESENT; if (info->CaInitializationStatus == 1 && @@ -54,103 +43,63 @@ static int firesat_get_ca_flags(ANTENNA_INPUT_INFO *info) static int firesat_ca_reset(struct firesat *firesat) { - if (ca_debug) - printk(KERN_INFO "%s: ioctl CA_RESET\n", __func__); - if (avc_ca_reset(firesat)) - return -EFAULT; - return 0; + return avc_ca_reset(firesat) ? -EFAULT : 0; } -static int firesat_ca_get_caps(struct firesat *firesat, void *arg) +static int firesat_ca_get_caps(void *arg) { - struct ca_caps *cap_p = (struct ca_caps*)arg; - int err = 0; - - cap_p->slot_num = 1; - cap_p->slot_type = CA_CI; - cap_p->descr_num = 1; - cap_p->descr_type = CA_ECD; - if (ca_debug) - printk(KERN_INFO "%s: ioctl CA_GET_CAP\n", __func__); - return err; + struct ca_caps *cap = arg; + + cap->slot_num = 1; + cap->slot_type = CA_CI; + cap->descr_num = 1; + cap->descr_type = CA_ECD; + return 0; } static int firesat_ca_get_slot_info(struct firesat *firesat, void *arg) { ANTENNA_INPUT_INFO info; - struct ca_slot_info *slot_p = (struct ca_slot_info*)arg; + struct ca_slot_info *slot = arg; - if (ca_debug) - printk(KERN_INFO "%s: ioctl CA_GET_SLOT_INFO on slot %d.\n", - __func__, slot_p->num); - if (AVCTunerStatus(firesat, &info)) + if (avc_tuner_status(firesat, &info)) return -EFAULT; - if (slot_p->num == 0) { - slot_p->type = CA_CI; - slot_p->flags = firesat_get_ca_flags(&info); - } - else { + if (slot->num != 0) return -EFAULT; - } + + slot->type = CA_CI; + slot->flags = firesat_get_ca_flags(&info); return 0; } static int firesat_ca_app_info(struct firesat *firesat, void *arg) { - struct ca_msg *reply_p = (struct ca_msg*)arg; - int i; + struct ca_msg *reply = arg; - if (avc_ca_app_info(firesat, reply_p->msg, &reply_p->length)) - return -EFAULT; - if (ca_debug) { - printk(KERN_INFO "%s: Creating TAG_APP_INFO message:", - __func__); - for (i = 0; i < reply_p->length; i++) - printk("0x%02X, ", (unsigned char)reply_p->msg[i]); - printk("\n"); - } - return 0; + return + avc_ca_app_info(firesat, reply->msg, &reply->length) ? -EFAULT : 0; } static int firesat_ca_info(struct firesat *firesat, void *arg) { - struct ca_msg *reply_p = (struct ca_msg*)arg; - int i; + struct ca_msg *reply = arg; - if (avc_ca_info(firesat, reply_p->msg, &reply_p->length)) - return -EFAULT; - if (ca_debug) { - printk(KERN_INFO "%s: Creating TAG_CA_INFO message:", - __func__); - for (i = 0; i < reply_p->length; i++) - printk("0x%02X, ", (unsigned char)reply_p->msg[i]); - printk("\n"); - } - return 0; + return avc_ca_info(firesat, reply->msg, &reply->length) ? -EFAULT : 0; } static int firesat_ca_get_mmi(struct firesat *firesat, void *arg) { - struct ca_msg *reply_p = (struct ca_msg*)arg; - int i; + struct ca_msg *reply = arg; - if (avc_ca_get_mmi(firesat, reply_p->msg, &reply_p->length)) - return -EFAULT; - if (ca_debug) { - printk(KERN_INFO "%s: Creating MMI reply INFO message:", - __func__); - for (i = 0; i < reply_p->length; i++) - printk("0x%02X, ", (unsigned char)reply_p->msg[i]); - printk("\n"); - } - return 0; + return + avc_ca_get_mmi(firesat, reply->msg, &reply->length) ? -EFAULT : 0; } static int firesat_ca_get_msg(struct firesat *firesat, void *arg) { - int err; ANTENNA_INPUT_INFO info; + int err; switch (firesat->ca_last_command) { case TAG_APP_INFO_ENQUIRY: @@ -160,11 +109,10 @@ static int firesat_ca_get_msg(struct firesat *firesat, void *arg) err = firesat_ca_info(firesat, arg); break; default: - if (AVCTunerStatus(firesat, &info)) + if (avc_tuner_status(firesat, &info)) err = -EFAULT; - else if (info.CaMmi == 1) { + else if (info.CaMmi == 1) err = firesat_ca_get_mmi(firesat, arg); - } else { printk(KERN_INFO "%s: Unhandled message 0x%08X\n", __func__, firesat->ca_last_command); @@ -177,51 +125,39 @@ static int firesat_ca_get_msg(struct firesat *firesat, void *arg) static int firesat_ca_pmt(struct firesat *firesat, void *arg) { - struct ca_msg *msg_p = (struct ca_msg*)arg; + struct ca_msg *msg = arg; int data_pos; - if (msg_p->msg[3] & 0x80) - data_pos = (msg_p->msg[4] && 0x7F) + 4; + if (msg->msg[3] & 0x80) + data_pos = (msg->msg[4] && 0x7F) + 4; else data_pos = 4; - if (avc_ca_pmt(firesat, &msg_p->msg[data_pos], - msg_p->length - data_pos)) - return -EFAULT; - return 0; + + return avc_ca_pmt(firesat, &msg->msg[data_pos], + msg->length - data_pos) ? -EFAULT : 0; } static int firesat_ca_send_msg(struct firesat *firesat, void *arg) { + struct ca_msg *msg = arg; int err; - struct ca_msg *msg_p = (struct ca_msg*)arg; - // Do we need a semaphore for this? + /* Do we need a semaphore for this? */ firesat->ca_last_command = - (msg_p->msg[0] << 16) + (msg_p->msg[1] << 8) + msg_p->msg[2]; + (msg->msg[0] << 16) + (msg->msg[1] << 8) + msg->msg[2]; switch (firesat->ca_last_command) { case TAG_CA_PMT: - if (ca_debug != 0) - printk(KERN_INFO "%s: Message received: TAG_CA_PMT\n", - __func__); err = firesat_ca_pmt(firesat, arg); break; case TAG_APP_INFO_ENQUIRY: - // This is all handled in ca_get_msg - if (ca_debug != 0) - printk(KERN_INFO "%s: Message received: " - "TAG_APP_INFO_ENQUIRY\n", __func__); + /* handled in ca_get_msg */ err = 0; break; case TAG_CA_INFO_ENQUIRY: - // This is all handled in ca_get_msg - if (ca_debug != 0) - printk(KERN_INFO "%s: Message received: " - "TAG_CA_APP_INFO_ENQUIRY\n", __func__); + /* handled in ca_get_msg */ err = 0; break; case TAG_ENTER_MENU: - if (ca_debug != 0) - printk(KERN_INFO "%s: Entering CA menu.\n", __func__); err = avc_ca_enter_menu(firesat); break; default: @@ -235,17 +171,17 @@ static int firesat_ca_send_msg(struct firesat *firesat, void *arg) static int firesat_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) { - struct dvb_device* dvbdev = (struct dvb_device*) file->private_data; + struct dvb_device *dvbdev = file->private_data; struct firesat *firesat = dvbdev->priv; - int err; ANTENNA_INPUT_INFO info; + int err; switch(cmd) { case CA_RESET: err = firesat_ca_reset(firesat); break; case CA_GET_CAP: - err = firesat_ca_get_caps(firesat, arg); + err = firesat_ca_get_caps(arg); break; case CA_GET_SLOT_INFO: err = firesat_ca_get_slot_info(firesat, arg); @@ -262,90 +198,52 @@ static int firesat_ca_ioctl(struct inode *inode, struct file *file, err = -EOPNOTSUPP; } - if (AVCTunerStatus(firesat, &info)) - return err; - - firesat_ca_ready(&info); + /* FIXME Is this necessary? */ + avc_tuner_status(firesat, &info); return err; } -static int firesat_get_date_time_request(struct firesat *firesat) -{ - if (ca_debug) - printk(KERN_INFO "%s: Retrieving Time/Date request\n", - __func__); - if (avc_ca_get_time_date(firesat, &firesat->ca_time_interval)) - return -EFAULT; - if (ca_debug) - printk(KERN_INFO "%s: Time/Date interval is %d\n", - __func__, firesat->ca_time_interval); - - return 0; -} - -static int firesat_ca_io_open(struct inode *inode, struct file *file) -{ - if (ca_debug != 0) - printk(KERN_INFO "%s\n",__func__); - return dvb_generic_open(inode, file); -} - -static int firesat_ca_io_release(struct inode *inode, struct file *file) -{ - if (ca_debug != 0) - printk(KERN_INFO "%s\n",__func__); - return dvb_generic_release(inode, file); -} - static unsigned int firesat_ca_io_poll(struct file *file, poll_table *wait) { - if (ca_debug != 0) - printk(KERN_INFO "%s\n",__func__); return POLLIN; } static struct file_operations firesat_ca_fops = { - .owner = THIS_MODULE, - .read = NULL, // There is no low level read anymore - .write = NULL, // There is no low level write anymore - .ioctl = dvb_generic_ioctl, - .open = firesat_ca_io_open, - .release = firesat_ca_io_release, - .poll = firesat_ca_io_poll, + .owner = THIS_MODULE, + .ioctl = dvb_generic_ioctl, + .open = dvb_generic_open, + .release = dvb_generic_release, + .poll = firesat_ca_io_poll, }; static struct dvb_device firesat_ca = { - .priv = NULL, - .users = 1, - .readers = 1, - .writers = 1, - .fops = &firesat_ca_fops, - .kernel_ioctl = firesat_ca_ioctl, + .users = 1, + .readers = 1, + .writers = 1, + .fops = &firesat_ca_fops, + .kernel_ioctl = firesat_ca_ioctl, }; -int firesat_ca_init(struct firesat *firesat) +int firesat_ca_register(struct firesat *firesat) { - int err; ANTENNA_INPUT_INFO info; + int err; - if (AVCTunerStatus(firesat, &info)) + if (avc_tuner_status(firesat, &info)) return -EINVAL; - if (firesat_ca_ready(&info)) { - err = dvb_register_device(firesat->adapter, - &firesat->cadev, - &firesat_ca, firesat, - DVB_DEVICE_CA); - - if (info.CaApplicationInfo == 0) - printk(KERN_ERR "%s: CaApplicationInfo is not set.\n", - __func__); - if (info.CaDateTimeRequest == 1) - firesat_get_date_time_request(firesat); - } - else - err = -EFAULT; + if (!firesat_ca_ready(&info)) + return -EFAULT; + + err = dvb_register_device(&firesat->adapter, &firesat->cadev, + &firesat_ca, firesat, DVB_DEVICE_CA); + + if (info.CaApplicationInfo == 0) + printk(KERN_ERR "%s: CaApplicationInfo is not set.\n", + __func__); + if (info.CaDateTimeRequest == 1) + avc_ca_get_time_date(firesat, &firesat->ca_time_interval); return err; } @@ -353,5 +251,5 @@ int firesat_ca_init(struct firesat *firesat) void firesat_ca_release(struct firesat *firesat) { if (firesat->cadev) - dvb_unregister_device(firesat->cadev); + dvb_unregister_device(firesat->cadev); } diff --git a/drivers/media/dvb/firesat/firesat-ci.h b/drivers/media/dvb/firesat/firesat-ci.h index 04fe4061c77..9c68cd2246a 100644 --- a/drivers/media/dvb/firesat/firesat-ci.h +++ b/drivers/media/dvb/firesat/firesat-ci.h @@ -3,7 +3,7 @@ struct firesat; -int firesat_ca_init(struct firesat *firesat); +int firesat_ca_register(struct firesat *firesat); void firesat_ca_release(struct firesat *firesat); #endif /* _FIREDTV_CI_H */ diff --git a/drivers/media/dvb/firesat/firesat-rc.c b/drivers/media/dvb/firesat/firesat-rc.c index d3e08f9fe9f..5f9de142ee3 100644 --- a/drivers/media/dvb/firesat/firesat-rc.c +++ b/drivers/media/dvb/firesat/firesat-rc.c @@ -12,9 +12,11 @@ #include #include #include +#include #include #include "firesat-rc.h" +#include "firesat.h" /* fixed table with older keycodes, geared towards MythTV */ const static u16 oldtable[] = { @@ -61,7 +63,7 @@ const static u16 oldtable[] = { }; /* user-modifiable table for a remote as sold in 2008 */ -static u16 keytable[] = { +const static u16 keytable[] = { /* code from device: 0x0300...0x031f */ @@ -123,19 +125,24 @@ static u16 keytable[] = { [0x34] = KEY_EXIT, }; -static struct input_dev *idev; - -int firesat_register_rc(void) +int firesat_register_rc(struct firesat *firesat, struct device *dev) { + struct input_dev *idev; int i, err; idev = input_allocate_device(); if (!idev) return -ENOMEM; + firesat->remote_ctrl_dev = idev; idev->name = "FireDTV remote control"; + idev->dev.parent = dev; idev->evbit[0] = BIT_MASK(EV_KEY); - idev->keycode = keytable; + idev->keycode = kmemdup(keytable, sizeof(keytable), GFP_KERNEL); + if (!idev->keycode) { + err = -ENOMEM; + goto fail; + } idev->keycodesize = sizeof(keytable[0]); idev->keycodemax = ARRAY_SIZE(keytable); @@ -144,22 +151,31 @@ int firesat_register_rc(void) err = input_register_device(idev); if (err) - input_free_device(idev); + goto fail_free_keymap; + return 0; + +fail_free_keymap: + kfree(idev->keycode); +fail: + input_free_device(idev); return err; } -void firesat_unregister_rc(void) +void firesat_unregister_rc(struct firesat *firesat) { - input_unregister_device(idev); + kfree(firesat->remote_ctrl_dev->keycode); + input_unregister_device(firesat->remote_ctrl_dev); } -void firesat_handle_rc(unsigned int code) +void firesat_handle_rc(struct firesat *firesat, unsigned int code) { + u16 *keycode = firesat->remote_ctrl_dev->keycode; + if (code >= 0x0300 && code <= 0x031f) - code = keytable[code - 0x0300]; + code = keycode[code - 0x0300]; else if (code >= 0x0340 && code <= 0x0354) - code = keytable[code - 0x0320]; + code = keycode[code - 0x0320]; else if (code >= 0x4501 && code <= 0x451f) code = oldtable[code - 0x4501]; else if (code >= 0x4540 && code <= 0x4542) @@ -170,6 +186,6 @@ void firesat_handle_rc(unsigned int code) return; } - input_report_key(idev, code, 1); - input_report_key(idev, code, 0); + input_report_key(firesat->remote_ctrl_dev, code, 1); + input_report_key(firesat->remote_ctrl_dev, code, 0); } diff --git a/drivers/media/dvb/firesat/firesat-rc.h b/drivers/media/dvb/firesat/firesat-rc.h index 81f4fdec60f..12c1c5c28b3 100644 --- a/drivers/media/dvb/firesat/firesat-rc.h +++ b/drivers/media/dvb/firesat/firesat-rc.h @@ -1,8 +1,11 @@ #ifndef _FIREDTV_RC_H #define _FIREDTV_RC_H -int firesat_register_rc(void); -void firesat_unregister_rc(void); -void firesat_handle_rc(unsigned int code); +struct firesat; +struct device; + +int firesat_register_rc(struct firesat *firesat, struct device *dev); +void firesat_unregister_rc(struct firesat *firesat); +void firesat_handle_rc(struct firesat *firesat, unsigned int code); #endif /* _FIREDTV_RC_H */ diff --git a/drivers/media/dvb/firesat/firesat.h b/drivers/media/dvb/firesat/firesat.h index 5f0de88e41a..51f64c0afcd 100644 --- a/drivers/media/dvb/firesat/firesat.h +++ b/drivers/media/dvb/firesat/firesat.h @@ -21,11 +21,11 @@ #include #include #include -#include #include #include #include +#include #include #include @@ -127,50 +127,35 @@ enum model_type { FireSAT_DVB_S2 = 4, }; -struct hpsb_host; +struct input_dev; struct hpsb_iso; -struct node_entry; +struct unit_directory; struct firesat { - struct dvb_demux dvb_demux; - - /* DVB bits */ - struct dvb_adapter *adapter; - struct dmxdev dmxdev; - struct dvb_demux demux; - struct dmx_frontend frontend; - struct dvb_net dvbnet; - struct dvb_frontend_info *frontend_info; - struct dvb_frontend *fe; - - struct dvb_device *cadev; - int ca_last_command; - int ca_time_interval; - - struct mutex avc_mutex; - wait_queue_head_t avc_wait; - atomic_t avc_reply_received; - struct work_struct remote_ctrl_work; + struct dvb_adapter adapter; + struct dmxdev dmxdev; + struct dvb_demux demux; + struct dmx_frontend frontend; + struct dvb_net dvbnet; + struct dvb_frontend fe; + + struct dvb_device *cadev; + int ca_last_command; + int ca_time_interval; + + struct mutex avc_mutex; + wait_queue_head_t avc_wait; + bool avc_reply_received; + struct work_struct remote_ctrl_work; + struct input_dev *remote_ctrl_dev; struct firesat_channel { - struct firesat *firesat; - struct dvb_demux_feed *dvbdmxfeed; - - int active; - int id; + bool active; int pid; - int type; /* 1 - TS, 2 - Filter */ } channel[16]; - struct mutex demux_mutex; - - /* needed by avc_api */ - void *respfrm; - int resp_length; + struct mutex demux_mutex; - struct hpsb_host *host; - u64 guid; /* GUID of this node */ - u32 guid_vendor_id; /* Top 24bits of guid */ - struct node_entry *nodeentry; + struct unit_directory *ud; enum model_type type; char subunit; @@ -181,6 +166,10 @@ struct firesat { struct hpsb_iso *iso_handle; struct list_head list; + + /* needed by avc_api */ + int resp_length; + u8 respfrm[512]; }; struct firewireheader { @@ -226,11 +215,10 @@ struct device; /* firesat_dvb.c */ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed); int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed); -int firesat_dvbdev_init(struct firesat *firesat, struct device *dev, - struct dvb_frontend *fe); +int firesat_dvbdev_init(struct firesat *firesat, struct device *dev); /* firesat_fe.c */ -int firesat_frontend_attach(struct firesat *firesat, struct dvb_frontend *fe); +void firesat_frontend_init(struct firesat *firesat); /* firesat_iso.c */ int setup_iso_channel(struct firesat *firesat); diff --git a/drivers/media/dvb/firesat/firesat_1394.c b/drivers/media/dvb/firesat/firesat_1394.c index a13fbe6b3a3..82bd9786571 100644 --- a/drivers/media/dvb/firesat/firesat_1394.c +++ b/drivers/media/dvb/firesat/firesat_1394.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include @@ -40,40 +39,54 @@ #include "firesat-ci.h" #include "firesat-rc.h" -#define FIRESAT_Vendor_ID 0x001287 +#define MATCH_FLAGS IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \ + IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION +#define DIGITAL_EVERYWHERE_OUI 0x001287 static struct ieee1394_device_id firesat_id_table[] = { { /* FloppyDTV S/CI and FloppyDTV S2 */ - .match_flags = IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID, - .model_id = 0x000024, - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, + .match_flags = MATCH_FLAGS, + .vendor_id = DIGITAL_EVERYWHERE_OUI, + .model_id = 0x000024, + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, + .version = AVC_SW_VERSION_ENTRY, },{ /* FloppyDTV T/CI */ - .match_flags = IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID, - .model_id = 0x000025, - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, + .match_flags = MATCH_FLAGS, + .vendor_id = DIGITAL_EVERYWHERE_OUI, + .model_id = 0x000025, + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, + .version = AVC_SW_VERSION_ENTRY, },{ /* FloppyDTV C/CI */ - .match_flags = IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID, - .model_id = 0x000026, - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, + .match_flags = MATCH_FLAGS, + .vendor_id = DIGITAL_EVERYWHERE_OUI, + .model_id = 0x000026, + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, + .version = AVC_SW_VERSION_ENTRY, },{ /* FireDTV S/CI and FloppyDTV S2 */ - .match_flags = IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID, - .model_id = 0x000034, - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, + .match_flags = MATCH_FLAGS, + .vendor_id = DIGITAL_EVERYWHERE_OUI, + .model_id = 0x000034, + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, + .version = AVC_SW_VERSION_ENTRY, },{ /* FireDTV T/CI */ - .match_flags = IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID, - .model_id = 0x000035, - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, + .match_flags = MATCH_FLAGS, + .vendor_id = DIGITAL_EVERYWHERE_OUI, + .model_id = 0x000035, + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, + .version = AVC_SW_VERSION_ENTRY, },{ /* FireDTV C/CI */ - .match_flags = IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID, - .model_id = 0x000036, - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, + .match_flags = MATCH_FLAGS, + .vendor_id = DIGITAL_EVERYWHERE_OUI, + .model_id = 0x000036, + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, + .version = AVC_SW_VERSION_ENTRY, }, { } }; @@ -98,8 +111,8 @@ static void fcp_request(struct hpsb_host *host, spin_lock_irqsave(&firesat_list_lock, flags); list_for_each_entry(firesat_entry,&firesat_list,list) { - if (firesat_entry->host == host && - firesat_entry->nodeentry->nodeid == nodeid && + if (firesat_entry->ud->ne->host == host && + firesat_entry->ud->ne->nodeid == nodeid && (firesat_entry->subunit == (data[1]&0x7) || (firesat_entry->subunit == 0 && (data[1]&0x7) == 0x7))) { @@ -110,12 +123,8 @@ static void fcp_request(struct hpsb_host *host, spin_unlock_irqrestore(&firesat_list_lock, flags); if (firesat) - AVCRecv(firesat,data,length); - else - printk("%s: received fcp request from unknown source, ignored\n", __func__); + avc_recv(firesat, data, length); } - else - printk("%s: received invalid fcp request, ignored\n", __func__); } const char *firedtv_model_names[] = { @@ -128,175 +137,108 @@ const char *firedtv_model_names[] = { static int firesat_probe(struct device *dev) { - struct unit_directory *ud = container_of(dev, struct unit_directory, device); + struct unit_directory *ud = + container_of(dev, struct unit_directory, device); struct firesat *firesat; - struct dvb_frontend *fe; unsigned long flags; - unsigned char subunitcount = 0xff, subunit; - struct firesat **firesats = kmalloc(sizeof (void*) * 2,GFP_KERNEL); int kv_len; + void *kv_str; int i; - char *kv_buf; + int err = -ENOMEM; - if (!firesats) { - printk("%s: couldn't allocate memory.\n", __func__); + firesat = kzalloc(sizeof(*firesat), GFP_KERNEL); + if (!firesat) return -ENOMEM; - } - -// printk(KERN_INFO "FireSAT: Detected device with GUID %08lx%04lx%04lx\n",(unsigned long)((ud->ne->guid)>>32),(unsigned long)(ud->ne->guid & 0xFFFF),(unsigned long)ud->ne->guid_vendor_id); - printk(KERN_INFO "%s: loading device\n", __func__); - - firesats[0] = NULL; - firesats[1] = NULL; - - ud->device.driver_data = firesats; - - for (subunit = 0; subunit < subunitcount; subunit++) { - - if (!(firesat = kmalloc(sizeof (struct firesat), GFP_KERNEL)) || - !(fe = kmalloc(sizeof (struct dvb_frontend), GFP_KERNEL))) { - - printk("%s: couldn't allocate memory.\n", __func__); - kfree(firesats); - return -ENOMEM; - } - - memset(firesat, 0, sizeof (struct firesat)); - - firesat->host = ud->ne->host; - firesat->guid = ud->ne->guid; - firesat->guid_vendor_id = ud->ne->guid_vendor_id; - firesat->nodeentry = ud->ne; - firesat->isochannel = -1; - firesat->tone = 0xff; - firesat->voltage = 0xff; - firesat->fe = fe; - - if (!(firesat->respfrm = kmalloc(sizeof (AVCRspFrm), GFP_KERNEL))) { - printk("%s: couldn't allocate memory.\n", __func__); - kfree(firesat); - return -ENOMEM; - } - - mutex_init(&firesat->avc_mutex); - init_waitqueue_head(&firesat->avc_wait); - atomic_set(&firesat->avc_reply_received, 1); - mutex_init(&firesat->demux_mutex); - INIT_WORK(&firesat->remote_ctrl_work, avc_remote_ctrl_work); - - spin_lock_irqsave(&firesat_list_lock, flags); - INIT_LIST_HEAD(&firesat->list); - list_add_tail(&firesat->list, &firesat_list); - spin_unlock_irqrestore(&firesat_list_lock, flags); - - if (subunit == 0) { - firesat->subunit = 0x7; // 0x7 = don't care - if (AVCSubUnitInfo(firesat, &subunitcount)) { - printk("%s: AVC subunit info command failed.\n",__func__); - spin_lock_irqsave(&firesat_list_lock, flags); - list_del(&firesat->list); - spin_unlock_irqrestore(&firesat_list_lock, flags); - kfree(firesat); - return -EIO; - } - } - - printk(KERN_INFO "%s: subunit count = %d\n", __func__, subunitcount); - - firesat->subunit = subunit; - - /* Reading device model from ROM */ - kv_len = (ud->model_name_kv->value.leaf.len - 2) * - sizeof(quadlet_t); - kv_buf = kmalloc((sizeof(quadlet_t) * kv_len), GFP_KERNEL); - memcpy(kv_buf, - CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv), - kv_len); - while ((kv_buf + kv_len - 1) == '\0') kv_len--; - kv_buf[kv_len++] = '\0'; - for (i = ARRAY_SIZE(firedtv_model_names); --i;) - if (strcmp(kv_buf, firedtv_model_names[i]) == 0) - break; - firesat->type = i; - kfree(kv_buf); - - if (AVCIdentifySubunit(firesat)) { - printk("%s: cannot identify subunit %d\n", __func__, subunit); - spin_lock_irqsave(&firesat_list_lock, flags); - list_del(&firesat->list); - spin_unlock_irqrestore(&firesat_list_lock, flags); - kfree(firesat); - continue; - } + dev->driver_data = firesat; + firesat->ud = ud; + firesat->subunit = 0; + firesat->isochannel = -1; + firesat->tone = 0xff; + firesat->voltage = 0xff; + + mutex_init(&firesat->avc_mutex); + init_waitqueue_head(&firesat->avc_wait); + firesat->avc_reply_received = true; + mutex_init(&firesat->demux_mutex); + INIT_WORK(&firesat->remote_ctrl_work, avc_remote_ctrl_work); + + /* Reading device model from ROM */ + kv_len = (ud->model_name_kv->value.leaf.len - 2) * sizeof(quadlet_t); + kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv); + for (i = ARRAY_SIZE(firedtv_model_names); --i;) + if (strlen(firedtv_model_names[i]) <= kv_len && + strncmp(kv_str, firedtv_model_names[i], kv_len) == 0) + break; + firesat->type = i; + + /* + * Work around a bug in udev's path_id script: Use the fw-host's dev + * instead of the unit directory's dev as parent of the input device. + */ + err = firesat_register_rc(firesat, dev->parent->parent); + if (err) + goto fail_free; + + INIT_LIST_HEAD(&firesat->list); + spin_lock_irqsave(&firesat_list_lock, flags); + list_add_tail(&firesat->list, &firesat_list); + spin_unlock_irqrestore(&firesat_list_lock, flags); + + err = avc_identify_subunit(firesat); + if (err) + goto fail; -// ---- - /* FIXME: check for error return */ - firesat_dvbdev_init(firesat, dev, fe); -// ---- - firesats[subunit] = firesat; - } // loop for all tuners + err = firesat_dvbdev_init(firesat, dev); + if (err) + goto fail; - if (firesats[0]) - AVCRegisterRemoteControl(firesats[0]); + avc_register_remote_control(firesat); + return 0; - return 0; +fail: + spin_lock_irqsave(&firesat_list_lock, flags); + list_del(&firesat->list); + spin_unlock_irqrestore(&firesat_list_lock, flags); + firesat_unregister_rc(firesat); +fail_free: + kfree(firesat); + return err; } static int firesat_remove(struct device *dev) { - struct unit_directory *ud = container_of(dev, struct unit_directory, device); - struct firesat **firesats = ud->device.driver_data; - int k; + struct firesat *firesat = dev->driver_data; unsigned long flags; - if (firesats) { - for (k = 0; k < 2; k++) - if (firesats[k]) { - firesat_ca_release(firesats[k]); - - dvb_unregister_frontend(firesats[k]->fe); - dvb_net_release(&firesats[k]->dvbnet); - firesats[k]->demux.dmx.close(&firesats[k]->demux.dmx); - firesats[k]->demux.dmx.remove_frontend(&firesats[k]->demux.dmx, &firesats[k]->frontend); - dvb_dmxdev_release(&firesats[k]->dmxdev); - dvb_dmx_release(&firesats[k]->demux); - dvb_unregister_adapter(firesats[k]->adapter); - - spin_lock_irqsave(&firesat_list_lock, flags); - list_del(&firesats[k]->list); - spin_unlock_irqrestore(&firesat_list_lock, flags); - - cancel_work_sync(&firesats[k]->remote_ctrl_work); - - kfree(firesats[k]->fe); - kfree(firesats[k]->adapter); - kfree(firesats[k]->respfrm); - kfree(firesats[k]); - } - kfree(firesats); - } else - printk("%s: can't get firesat handle\n", __func__); + firesat_ca_release(firesat); + dvb_unregister_frontend(&firesat->fe); + dvb_net_release(&firesat->dvbnet); + firesat->demux.dmx.close(&firesat->demux.dmx); + firesat->demux.dmx.remove_frontend(&firesat->demux.dmx, + &firesat->frontend); + dvb_dmxdev_release(&firesat->dmxdev); + dvb_dmx_release(&firesat->demux); + dvb_unregister_adapter(&firesat->adapter); + + spin_lock_irqsave(&firesat_list_lock, flags); + list_del(&firesat->list); + spin_unlock_irqrestore(&firesat_list_lock, flags); - printk(KERN_INFO "FireSAT: Removing device with vendor id 0x%x, model id 0x%x.\n",ud->vendor_id,ud->model_id); + cancel_work_sync(&firesat->remote_ctrl_work); + firesat_unregister_rc(firesat); + kfree(firesat); return 0; } static int firesat_update(struct unit_directory *ud) { - struct firesat **firesats = ud->device.driver_data; - int k; - // loop over subunits - - for (k = 0; k < 2; k++) - if (firesats[k]) { - firesats[k]->nodeentry = ud->ne; - - if (firesats[k]->isochannel >= 0) - try_CMPEstablishPPconnection(firesats[k], firesats[k]->subunit, firesats[k]->isochannel); - } + struct firesat *firesat = ud->device.driver_data; + if (firesat->isochannel >= 0) + cmp_establish_pp_connection(firesat, firesat->subunit, + firesat->isochannel); return 0; } @@ -328,26 +270,13 @@ static int __init firesat_init(void) ret = hpsb_register_protocol(&firesat_driver); if (ret) { printk(KERN_ERR "firedtv: failed to register protocol\n"); - goto fail; - } - - ret = firesat_register_rc(); - if (ret) { - printk(KERN_ERR "firedtv: failed to register input device\n"); - goto fail_rc; + hpsb_unregister_highlevel(&firesat_highlevel); } - - return 0; -fail_rc: - hpsb_unregister_protocol(&firesat_driver); -fail: - hpsb_unregister_highlevel(&firesat_highlevel); return ret; } static void __exit firesat_exit(void) { - firesat_unregister_rc(); hpsb_unregister_protocol(&firesat_driver); hpsb_unregister_highlevel(&firesat_highlevel); } diff --git a/drivers/media/dvb/firesat/firesat_dvb.c b/drivers/media/dvb/firesat/firesat_dvb.c index e944cee19f0..cfa3a2e8edd 100644 --- a/drivers/media/dvb/firesat/firesat_dvb.c +++ b/drivers/media/dvb/firesat/firesat_dvb.c @@ -34,8 +34,8 @@ static struct firesat_channel *firesat_channel_allocate(struct firesat *firesat) return NULL; for (k = 0; k < 16; k++) - if (firesat->channel[k].active == 0) { - firesat->channel[k].active = 1; + if (!firesat->channel[k].active) { + firesat->channel[k].active = true; c = &firesat->channel[k]; break; } @@ -52,7 +52,7 @@ static int firesat_channel_collect(struct firesat *firesat, int *pidc, u16 pid[] return -EINTR; for (k = 0; k < 16; k++) - if (firesat->channel[k].active == 1) + if (firesat->channel[k].active) pid[l++] = firesat->channel[k].pid; mutex_unlock(&firesat->demux_mutex); @@ -68,7 +68,7 @@ static int firesat_channel_release(struct firesat *firesat, if (mutex_lock_interruptible(&firesat->demux_mutex)) return -EINTR; - channel->active = 0; + channel->active = false; mutex_unlock(&firesat->demux_mutex); return 0; @@ -81,8 +81,6 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed) int pidc,k; u16 pids[16]; -// printk(KERN_INFO "%s (pid %u)\n", __func__, dvbdmxfeed->pid); - switch (dvbdmxfeed->type) { case DMX_TYPE_TS: case DMX_TYPE_SEC: @@ -102,7 +100,7 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed) case DMX_TS_PES_OTHER: //Dirty fix to keep firesat->channel pid-list up to date for(k=0;k<16;k++){ - if(firesat->channel[k].active == 0) + if (!firesat->channel[k].active) firesat->channel[k].pid = dvbdmxfeed->pid; break; @@ -124,11 +122,7 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed) } dvbdmxfeed->priv = channel; - - channel->dvbdmxfeed = dvbdmxfeed; channel->pid = dvbdmxfeed->pid; - channel->type = dvbdmxfeed->type; - channel->firesat = firesat; if (firesat_channel_collect(firesat, &pidc, pids)) { firesat_channel_release(firesat, channel); @@ -136,16 +130,17 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed) return -EINTR; } - if(dvbdmxfeed->pid == 8192) { - if((k = AVCTuner_GetTS(firesat))) { + if (dvbdmxfeed->pid == 8192) { + k = avc_tuner_get_ts(firesat); + if (k) { firesat_channel_release(firesat, channel); printk("%s: AVCTuner_GetTS failed with error %d\n", __func__, k); return k; } - } - else { - if((k = AVCTuner_SetPIDs(firesat, pidc, pids))) { + } else { + k = avc_tuner_set_pids(firesat, pidc, pids); + if (k) { firesat_channel_release(firesat, channel); printk("%s: AVCTuner_SetPIDs failed with error %d\n", __func__, k); @@ -164,8 +159,6 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed) int k, l; u16 pids[16]; - //printk(KERN_INFO "%s (pid %u)\n", __func__, dvbdmxfeed->pid); - if (dvbdmxfeed->type == DMX_TYPE_TS && !((dvbdmxfeed->ts_type & TS_PACKET) && (demux->dmx.frontend->source != DMX_MEMORY_FE))) { @@ -177,7 +170,7 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed) return -EINVAL; demux->pids[dvbdmxfeed->pes_type] |= 0x8000; - demux->pesfilter[dvbdmxfeed->pes_type] = 0; + demux->pesfilter[dvbdmxfeed->pes_type] = NULL; } if (!(dvbdmxfeed->ts_type & TS_DECODER && @@ -191,118 +184,93 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed) /* list except channel to be removed */ for (k = 0, l = 0; k < 16; k++) - if (firesat->channel[k].active == 1) { + if (firesat->channel[k].active) { if (&firesat->channel[k] != c) pids[l++] = firesat->channel[k].pid; else - firesat->channel[k].active = 0; + firesat->channel[k].active = false; } - k = AVCTuner_SetPIDs(firesat, l, pids); + k = avc_tuner_set_pids(firesat, l, pids); if (!k) - c->active = 0; + c->active = false; mutex_unlock(&firesat->demux_mutex); return k; } -int firesat_dvbdev_init(struct firesat *firesat, - struct device *dev, - struct dvb_frontend *fe) +int firesat_dvbdev_init(struct firesat *firesat, struct device *dev) { - int result; - - firesat->adapter = kmalloc(sizeof(*firesat->adapter), GFP_KERNEL); - if (!firesat->adapter) { - printk(KERN_ERR "firedtv: couldn't allocate memory\n"); - return -ENOMEM; - } - - result = DVB_REGISTER_ADAPTER(firesat->adapter, - firedtv_model_names[firesat->type], - THIS_MODULE, dev, adapter_nr); - if (result < 0) { - printk(KERN_ERR "firedtv: dvb_register_adapter failed\n"); - kfree(firesat->adapter); - return result; - } - - memset(&firesat->demux, 0, sizeof(struct dvb_demux)); - firesat->demux.dmx.capabilities = 0/*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/; - - firesat->demux.priv = (void *)firesat; - firesat->demux.filternum = 16; - firesat->demux.feednum = 16; - firesat->demux.start_feed = firesat_start_feed; - firesat->demux.stop_feed = firesat_stop_feed; - firesat->demux.write_to_decoder = NULL; + int err; - if ((result = dvb_dmx_init(&firesat->demux)) < 0) { - printk("%s: dvb_dmx_init failed: error %d\n", __func__, - result); + err = DVB_REGISTER_ADAPTER(&firesat->adapter, + firedtv_model_names[firesat->type], + THIS_MODULE, dev, adapter_nr); + if (err) + goto fail_log; - dvb_unregister_adapter(firesat->adapter); + /*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/ + firesat->demux.dmx.capabilities = 0; - return result; - } - - firesat->dmxdev.filternum = 16; - firesat->dmxdev.demux = &firesat->demux.dmx; - firesat->dmxdev.capabilities = 0; - - if ((result = dvb_dmxdev_init(&firesat->dmxdev, firesat->adapter)) < 0) { - printk("%s: dvb_dmxdev_init failed: error %d\n", - __func__, result); + firesat->demux.priv = (void *)firesat; + firesat->demux.filternum = 16; + firesat->demux.feednum = 16; + firesat->demux.start_feed = firesat_start_feed; + firesat->demux.stop_feed = firesat_stop_feed; + firesat->demux.write_to_decoder = NULL; - dvb_dmx_release(&firesat->demux); - dvb_unregister_adapter(firesat->adapter); + err = dvb_dmx_init(&firesat->demux); + if (err) + goto fail_unreg_adapter; - return result; - } + firesat->dmxdev.filternum = 16; + firesat->dmxdev.demux = &firesat->demux.dmx; + firesat->dmxdev.capabilities = 0; - firesat->frontend.source = DMX_FRONTEND_0; + err = dvb_dmxdev_init(&firesat->dmxdev, &firesat->adapter); + if (err) + goto fail_dmx_release; - if ((result = firesat->demux.dmx.add_frontend(&firesat->demux.dmx, - &firesat->frontend)) < 0) { - printk("%s: dvb_dmx_init failed: error %d\n", __func__, - result); + firesat->frontend.source = DMX_FRONTEND_0; - dvb_dmxdev_release(&firesat->dmxdev); - dvb_dmx_release(&firesat->demux); - dvb_unregister_adapter(firesat->adapter); + err = firesat->demux.dmx.add_frontend(&firesat->demux.dmx, + &firesat->frontend); + if (err) + goto fail_dmxdev_release; - return result; - } + err = firesat->demux.dmx.connect_frontend(&firesat->demux.dmx, + &firesat->frontend); + if (err) + goto fail_rem_frontend; - if ((result = firesat->demux.dmx.connect_frontend(&firesat->demux.dmx, - &firesat->frontend)) < 0) { - printk("%s: dvb_dmx_init failed: error %d\n", __func__, - result); + dvb_net_init(&firesat->adapter, &firesat->dvbnet, &firesat->demux.dmx); - firesat->demux.dmx.remove_frontend(&firesat->demux.dmx, &firesat->frontend); - dvb_dmxdev_release(&firesat->dmxdev); - dvb_dmx_release(&firesat->demux); - dvb_unregister_adapter(firesat->adapter); + firesat_frontend_init(firesat); + err = dvb_register_frontend(&firesat->adapter, &firesat->fe); + if (err) + goto fail_net_release; - return result; - } + err = firesat_ca_register(firesat); + if (err) + dev_info(dev, "Conditional Access Module not enabled\n"); - dvb_net_init(firesat->adapter, &firesat->dvbnet, &firesat->demux.dmx); - -// fe->ops = firesat_ops; -// fe->dvb = firesat->adapter; - firesat_frontend_attach(firesat, fe); - - fe->sec_priv = firesat; //IMPORTANT, functions depend on this!!! - if ((result= dvb_register_frontend(firesat->adapter, fe)) < 0) { - printk("%s: dvb_register_frontend_new failed: error %d\n", __func__, result); - /* ### cleanup */ - return result; - } - - firesat_ca_init(firesat); + return 0; - return 0; +fail_net_release: + dvb_net_release(&firesat->dvbnet); + firesat->demux.dmx.close(&firesat->demux.dmx); +fail_rem_frontend: + firesat->demux.dmx.remove_frontend(&firesat->demux.dmx, + &firesat->frontend); +fail_dmxdev_release: + dvb_dmxdev_release(&firesat->dmxdev); +fail_dmx_release: + dvb_dmx_release(&firesat->demux); +fail_unreg_adapter: + dvb_unregister_adapter(&firesat->adapter); +fail_log: + dev_err(dev, "DVB initialization failed\n"); + return err; } diff --git a/drivers/media/dvb/firesat/firesat_fe.c b/drivers/media/dvb/firesat/firesat_fe.c index ec614ea8de2..1ed972b7957 100644 --- a/drivers/media/dvb/firesat/firesat_fe.c +++ b/drivers/media/dvb/firesat/firesat_fe.c @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -22,22 +23,21 @@ static int firesat_dvb_init(struct dvb_frontend *fe) { - int result; struct firesat *firesat = fe->sec_priv; -// printk("fdi: 1\n"); - firesat->isochannel = firesat->adapter->num; //<< 1 | (firesat->subunit & 0x1); // ### ask IRM -// printk("fdi: 2\n"); - result = try_CMPEstablishPPconnection(firesat, firesat->subunit, firesat->isochannel); - if (result != 0) { + int err; + + /* FIXME - allocate free channel at IRM */ + firesat->isochannel = firesat->adapter.num; + + err = cmp_establish_pp_connection(firesat, firesat->subunit, + firesat->isochannel); + if (err) { printk(KERN_ERR "Could not establish point to point " "connection.\n"); - return -1; + return err; } -// printk("fdi: 3\n"); - result = setup_iso_channel(firesat); -// printk("fdi: 4. Result was %d\n", result); - return result; + return setup_iso_channel(firesat); } static int firesat_sleep(struct dvb_frontend *fe) @@ -45,7 +45,7 @@ static int firesat_sleep(struct dvb_frontend *fe) struct firesat *firesat = fe->sec_priv; tear_down_iso_channel(firesat); - try_CMPBreakPPconnection(firesat, firesat->subunit, firesat->isochannel); + cmp_break_pp_connection(firesat, firesat->subunit, firesat->isochannel); firesat->isochannel = -1; return 0; } @@ -55,8 +55,8 @@ static int firesat_diseqc_send_master_cmd(struct dvb_frontend *fe, { struct firesat *firesat = fe->sec_priv; - return AVCLNBControl(firesat, LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, - LNBCONTROL_DONTCARE, 1, cmd); + return avc_lnb_control(firesat, LNBCONTROL_DONTCARE, + LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, 1, cmd); } static int firesat_diseqc_send_burst(struct dvb_frontend *fe, @@ -82,24 +82,19 @@ static int firesat_set_voltage(struct dvb_frontend *fe, return 0; } -static int firesat_read_status (struct dvb_frontend *fe, fe_status_t *status) +static int firesat_read_status(struct dvb_frontend *fe, fe_status_t *status) { struct firesat *firesat = fe->sec_priv; ANTENNA_INPUT_INFO info; - if (AVCTunerStatus(firesat, &info)) + if (avc_tuner_status(firesat, &info)) return -EINVAL; - if (info.NoRF) { + if (info.NoRF) *status = 0; - } else { - *status = FE_HAS_SIGNAL | - FE_HAS_VITERBI | - FE_HAS_SYNC | - FE_HAS_CARRIER | - FE_HAS_LOCK; - } - + else + *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | FE_HAS_SYNC | + FE_HAS_CARRIER | FE_HAS_LOCK; return 0; } @@ -108,14 +103,11 @@ static int firesat_read_ber(struct dvb_frontend *fe, u32 *ber) struct firesat *firesat = fe->sec_priv; ANTENNA_INPUT_INFO info; - if (AVCTunerStatus(firesat, &info)) + if (avc_tuner_status(firesat, &info)) return -EINVAL; - *ber = (info.BER[0] << 24) | - (info.BER[1] << 16) | - (info.BER[2] << 8) | - info.BER[3]; - + *ber = info.BER[0] << 24 | info.BER[1] << 16 | + info.BER[2] << 8 | info.BER[3]; return 0; } @@ -124,11 +116,10 @@ static int firesat_read_signal_strength (struct dvb_frontend *fe, u16 *strength) struct firesat *firesat = fe->sec_priv; ANTENNA_INPUT_INFO info; - if (AVCTunerStatus(firesat, &info)) + if (avc_tuner_status(firesat, &info)) return -EINVAL; *strength = info.SignalStrength << 8; - return 0; } @@ -137,14 +128,12 @@ static int firesat_read_snr(struct dvb_frontend *fe, u16 *snr) struct firesat *firesat = fe->sec_priv; ANTENNA_INPUT_INFO info; - if (AVCTunerStatus(firesat, &info)) + if (avc_tuner_status(firesat, &info)) return -EINVAL; - *snr = (info.CarrierNoiseRatio[0] << 8) + - info.CarrierNoiseRatio[1]; + /* C/N[dB] = -10 * log10(snr / 65535) */ + *snr = (info.CarrierNoiseRatio[0] << 8) + info.CarrierNoiseRatio[1]; *snr *= 257; - // C/N[dB] = -10 * log10(snr / 65535) - return 0; } @@ -158,10 +147,11 @@ static int firesat_set_frontend(struct dvb_frontend *fe, { struct firesat *firesat = fe->sec_priv; - if (AVCTuner_DSD(firesat, params, NULL) != ACCEPTED) + /* FIXME: avc_tuner_dsd never returns ACCEPTED. Check status? */ + if (avc_tuner_dsd(firesat, params) != ACCEPTED) return -EINVAL; else - return 0; //not sure of this... + return 0; /* not sure of this... */ } static int firesat_get_frontend(struct dvb_frontend *fe, @@ -170,107 +160,86 @@ static int firesat_get_frontend(struct dvb_frontend *fe, return -EOPNOTSUPP; } -static struct dvb_frontend_info firesat_S_frontend_info; -static struct dvb_frontend_info firesat_C_frontend_info; -static struct dvb_frontend_info firesat_T_frontend_info; - -static struct dvb_frontend_ops firesat_ops = { +void firesat_frontend_init(struct firesat *firesat) +{ + struct dvb_frontend_ops *ops = &firesat->fe.ops; + struct dvb_frontend_info *fi = &ops->info; - .init = firesat_dvb_init, - .sleep = firesat_sleep, + ops->init = firesat_dvb_init; + ops->sleep = firesat_sleep; - .set_frontend = firesat_set_frontend, - .get_frontend = firesat_get_frontend, + ops->set_frontend = firesat_set_frontend; + ops->get_frontend = firesat_get_frontend; - .read_status = firesat_read_status, - .read_ber = firesat_read_ber, - .read_signal_strength = firesat_read_signal_strength, - .read_snr = firesat_read_snr, - .read_ucblocks = firesat_read_uncorrected_blocks, + ops->read_status = firesat_read_status; + ops->read_ber = firesat_read_ber; + ops->read_signal_strength = firesat_read_signal_strength; + ops->read_snr = firesat_read_snr; + ops->read_ucblocks = firesat_read_uncorrected_blocks; - .diseqc_send_master_cmd = firesat_diseqc_send_master_cmd, - .diseqc_send_burst = firesat_diseqc_send_burst, - .set_tone = firesat_set_tone, - .set_voltage = firesat_set_voltage, -}; + ops->diseqc_send_master_cmd = firesat_diseqc_send_master_cmd; + ops->diseqc_send_burst = firesat_diseqc_send_burst; + ops->set_tone = firesat_set_tone; + ops->set_voltage = firesat_set_voltage; -int firesat_frontend_attach(struct firesat *firesat, struct dvb_frontend *fe) -{ switch (firesat->type) { case FireSAT_DVB_S: - firesat->frontend_info = &firesat_S_frontend_info; + fi->type = FE_QPSK; + + fi->frequency_min = 950000; + fi->frequency_max = 2150000; + fi->frequency_stepsize = 125; + fi->symbol_rate_min = 1000000; + fi->symbol_rate_max = 40000000; + + fi->caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_1_2 | + FE_CAN_FEC_2_3 | + FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | + FE_CAN_FEC_7_8 | + FE_CAN_FEC_AUTO | + FE_CAN_QPSK; break; + case FireSAT_DVB_C: - firesat->frontend_info = &firesat_C_frontend_info; + fi->type = FE_QAM; + + fi->frequency_min = 47000000; + fi->frequency_max = 866000000; + fi->frequency_stepsize = 62500; + fi->symbol_rate_min = 870000; + fi->symbol_rate_max = 6900000; + + fi->caps = FE_CAN_INVERSION_AUTO | + FE_CAN_QAM_16 | + FE_CAN_QAM_32 | + FE_CAN_QAM_64 | + FE_CAN_QAM_128 | + FE_CAN_QAM_256 | + FE_CAN_QAM_AUTO; break; + case FireSAT_DVB_T: - firesat->frontend_info = &firesat_T_frontend_info; + fi->type = FE_OFDM; + + fi->frequency_min = 49000000; + fi->frequency_max = 861000000; + fi->frequency_stepsize = 62500; + + fi->caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_2_3 | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_HIERARCHY_AUTO; break; + default: - printk(KERN_ERR "firedtv: no frontend for model type 0x%x\n", + printk(KERN_ERR "FireDTV: no frontend for model type %d\n", firesat->type); - firesat->frontend_info = NULL; } - fe->ops = firesat_ops; - fe->ops.info = *(firesat->frontend_info); - fe->dvb = firesat->adapter; + strcpy(fi->name, firedtv_model_names[firesat->type]); - return 0; + firesat->fe.dvb = &firesat->adapter; + firesat->fe.sec_priv = firesat; } - -static struct dvb_frontend_info firesat_S_frontend_info = { - - .name = "FireDTV DVB-S Frontend", - .type = FE_QPSK, - - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 125, - .symbol_rate_min = 1000000, - .symbol_rate_max = 40000000, - - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | - FE_CAN_FEC_2_3 | - FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | - FE_CAN_FEC_7_8 | - FE_CAN_FEC_AUTO | - FE_CAN_QPSK, -}; - -static struct dvb_frontend_info firesat_C_frontend_info = { - - .name = "FireDTV DVB-C Frontend", - .type = FE_QAM, - - .frequency_min = 47000000, - .frequency_max = 866000000, - .frequency_stepsize = 62500, - .symbol_rate_min = 870000, - .symbol_rate_max = 6900000, - - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_QAM_16 | - FE_CAN_QAM_32 | - FE_CAN_QAM_64 | - FE_CAN_QAM_128 | - FE_CAN_QAM_256 | - FE_CAN_QAM_AUTO, -}; - -static struct dvb_frontend_info firesat_T_frontend_info = { - - .name = "FireDTV DVB-T Frontend", - .type = FE_OFDM, - - .frequency_min = 49000000, - .frequency_max = 861000000, - .frequency_stepsize = 62500, - - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_2_3 | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO, -}; diff --git a/drivers/media/dvb/firesat/firesat_iso.c b/drivers/media/dvb/firesat/firesat_iso.c index bc94afe57f6..b3c61f95fa9 100644 --- a/drivers/media/dvb/firesat/firesat_iso.c +++ b/drivers/media/dvb/firesat/firesat_iso.c @@ -18,6 +18,7 @@ #include #include +#include #include "firesat.h" @@ -36,7 +37,7 @@ int setup_iso_channel(struct firesat *firesat) { int result; firesat->iso_handle = - hpsb_iso_recv_init(firesat->host, + hpsb_iso_recv_init(firesat->ud->ne->host, 256 * 200, //data_buf_size, 256, //buf_packets, firesat->isochannel, @@ -59,7 +60,6 @@ static void rawiso_activity_cb(struct hpsb_iso *iso) { unsigned int num; unsigned int i; -/* unsigned int j; */ unsigned int packet; unsigned long flags; struct firesat *firesat = NULL; @@ -88,12 +88,7 @@ static void rawiso_activity_cb(struct hpsb_iso *iso) (188 + sizeof(struct firewireheader)); if (iso->infos[packet].len <= sizeof(struct CIPHeader)) continue; // ignore empty packet -/* printk("%s: Handling packets (%d): ", __func__, */ -/* iso->infos[packet].len); */ -/* for (j = 0; j < iso->infos[packet].len - */ -/* sizeof(struct CIPHeader); j++) */ -/* printk("%02X,", buf[j]); */ -/* printk("\n"); */ + while (count --) { if (buf[sizeof(struct firewireheader)] == 0x47) dvb_dmx_swfilter_packets(&firesat->demux, -- cgit From 096edfbf167ab277608d26ba8b7978da116a4996 Mon Sep 17 00:00:00 2001 From: Henrik Kurelid Date: Thu, 4 Dec 2008 22:40:52 +0100 Subject: firedtv: fix returned struct for ca_info The SystemId of the ca_info message was filled with garbage. It now returns what the card returns. Signed-off-by: Henrik Kurelid Signed-off-by: Stefan Richter --- drivers/media/dvb/firesat/avc_api.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/dvb/firesat/avc_api.c b/drivers/media/dvb/firesat/avc_api.c index 56911f3df7f..3a4da73f079 100644 --- a/drivers/media/dvb/firesat/avc_api.c +++ b/drivers/media/dvb/firesat/avc_api.c @@ -763,7 +763,7 @@ int avc_ca_info(struct firesat *firesat, char *app_info, unsigned int *len) { AVCCmdFrm CmdFrm; AVCRspFrm RspFrm; - /* int pos; FIXME: unused */ + int pos; memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); CmdFrm.cts = AVC; @@ -783,13 +783,13 @@ int avc_ca_info(struct firesat *firesat, char *app_info, unsigned int *len) if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) return -EIO; - /* pos = get_ca_object_pos(&RspFrm); FIXME: unused */ + pos = get_ca_object_pos(&RspFrm); app_info[0] = (TAG_CA_INFO >> 16) & 0xFF; app_info[1] = (TAG_CA_INFO >> 8) & 0xFF; app_info[2] = (TAG_CA_INFO >> 0) & 0xFF; app_info[3] = 2; - app_info[4] = app_info[5]; - app_info[5] = app_info[6]; + app_info[4] = RspFrm.operand[pos + 0]; + app_info[5] = RspFrm.operand[pos + 1]; *len = app_info[3] + 4; return 0; -- cgit From 7199e523ef71d24cd8030ea454fca00bb52d58f0 Mon Sep 17 00:00:00 2001 From: Henrik Kurelid Date: Fri, 5 Dec 2008 10:00:16 +0100 Subject: firedtv: use length_field() of PMT as length Parsed and used the length_field() of the PMT message instead of using the length field of the message struct, which does not seem to be filled correctly by e.g. MythTV. Signed-off-by: Henrik Kurelid Signed-off-by: Stefan Richter --- drivers/media/dvb/firesat/firesat-ci.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/media/dvb/firesat/firesat-ci.c b/drivers/media/dvb/firesat/firesat-ci.c index 0deb47eefa1..783ed200010 100644 --- a/drivers/media/dvb/firesat/firesat-ci.c +++ b/drivers/media/dvb/firesat/firesat-ci.c @@ -127,14 +127,20 @@ static int firesat_ca_pmt(struct firesat *firesat, void *arg) { struct ca_msg *msg = arg; int data_pos; + int data_length; + int i; + + data_pos = 4; + if (msg->msg[3] & 0x80) { + data_length = 0; + for (i = 0; i < (msg->msg[3] & 0x7F); i++) + data_length = (data_length << 8) + msg->msg[data_pos++]; + } else { + data_length = msg->msg[3]; + } - if (msg->msg[3] & 0x80) - data_pos = (msg->msg[4] && 0x7F) + 4; - else - data_pos = 4; - - return avc_ca_pmt(firesat, &msg->msg[data_pos], - msg->length - data_pos) ? -EFAULT : 0; + return avc_ca_pmt(firesat, &msg->msg[data_pos], data_length) ? + -EFAULT : 0; } static int firesat_ca_send_msg(struct firesat *firesat, void *arg) -- cgit From a40bf5591681f707afcf550cdcb4cc1697a29504 Mon Sep 17 00:00:00 2001 From: Henrik Kurelid Date: Mon, 15 Dec 2008 08:17:12 +0100 Subject: firedtv: fix registration - adapter number could only be zero There was a bug causing the initialization to fail if adapter number was greater than zero. The adapter was however registered which caused the driver to oops the second time initialization was tried. Signed-off-by: Henrik Kurelid Signed-off-by: Stefan Richter --- drivers/media/dvb/firesat/firesat_dvb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/dvb/firesat/firesat_dvb.c b/drivers/media/dvb/firesat/firesat_dvb.c index cfa3a2e8edd..cb36c031019 100644 --- a/drivers/media/dvb/firesat/firesat_dvb.c +++ b/drivers/media/dvb/firesat/firesat_dvb.c @@ -206,7 +206,7 @@ int firesat_dvbdev_init(struct firesat *firesat, struct device *dev) err = DVB_REGISTER_ADAPTER(&firesat->adapter, firedtv_model_names[firesat->type], THIS_MODULE, dev, adapter_nr); - if (err) + if (err < 0) goto fail_log; /*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/ -- cgit From 291f006efeebeeb2073289e44efb8f97cf157220 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 25 Dec 2008 15:34:25 +0100 Subject: firedtv: Use DEFINE_SPINLOCK SPIN_LOCK_UNLOCKED is deprecated. The following makes the change suggested in Documentation/spinlocks.txt Signed-off-by: Julia Lawall Signed-off-by: Stefan Richter --- drivers/media/dvb/firesat/firesat_1394.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/dvb/firesat/firesat_1394.c b/drivers/media/dvb/firesat/firesat_1394.c index 82bd9786571..11db6273025 100644 --- a/drivers/media/dvb/firesat/firesat_1394.c +++ b/drivers/media/dvb/firesat/firesat_1394.c @@ -94,7 +94,7 @@ MODULE_DEVICE_TABLE(ieee1394, firesat_id_table); /* list of all firesat devices */ LIST_HEAD(firesat_list); -spinlock_t firesat_list_lock = SPIN_LOCK_UNLOCKED; +DEFINE_SPINLOCK(firesat_list_lock); static void fcp_request(struct hpsb_host *host, int nodeid, -- cgit From a70f81c1c0dac113ac4705e7701e2676e67905cd Mon Sep 17 00:00:00 2001 From: Rambaldi Date: Sat, 17 Jan 2009 14:47:34 +0100 Subject: firedtv: rename files, variables, functions from firesat to firedtv Combination of the following changes: Sat, 17 Jan 2009 14:47:34 +0100 firedtv: rename variables and functions from firesat to firedtv Signed-off-by: Rambaldi Additional changes by Stefan Richter: Renamed struct firedtv *firedtv to struct firedtv *fdtv and firedtv_foo_bar() to fdtv_foo_bar() for brevity. Sat, 17 Jan 2009 13:07:44 +0100 firedtv: rename files from firesat to firedtv Signed-off-by: Rambaldi Additional changes by Stefan Richter: Name the directory "firewire" instead of "firedtv". Standardize on "-" instead of "_" in file names, because that's what drivers/firewire/ and drivers/media/dvb/dvb-usb/ use too. Build fix. Signed-off-by: Stefan Richter --- drivers/media/dvb/Kconfig | 2 +- drivers/media/dvb/Makefile | 2 +- drivers/media/dvb/firesat/Kconfig | 12 - drivers/media/dvb/firesat/Makefile | 13 - drivers/media/dvb/firesat/avc_api.c | 1051 ----------------------------- drivers/media/dvb/firesat/avc_api.h | 432 ------------ drivers/media/dvb/firesat/cmp.c | 171 ----- drivers/media/dvb/firesat/cmp.h | 9 - drivers/media/dvb/firesat/firesat-ci.c | 261 ------- drivers/media/dvb/firesat/firesat-ci.h | 9 - drivers/media/dvb/firesat/firesat-rc.c | 191 ------ drivers/media/dvb/firesat/firesat-rc.h | 11 - drivers/media/dvb/firesat/firesat.h | 227 ------- drivers/media/dvb/firesat/firesat_1394.c | 291 -------- drivers/media/dvb/firesat/firesat_dvb.c | 276 -------- drivers/media/dvb/firesat/firesat_fe.c | 245 ------- drivers/media/dvb/firesat/firesat_iso.c | 111 --- drivers/media/dvb/firewire/Kconfig | 12 + drivers/media/dvb/firewire/Makefile | 13 + drivers/media/dvb/firewire/avc.c | 1051 +++++++++++++++++++++++++++++ drivers/media/dvb/firewire/avc.h | 432 ++++++++++++ drivers/media/dvb/firewire/cmp.c | 171 +++++ drivers/media/dvb/firewire/cmp.h | 9 + drivers/media/dvb/firewire/firedtv-1394.c | 291 ++++++++ drivers/media/dvb/firewire/firedtv-ci.c | 261 +++++++ drivers/media/dvb/firewire/firedtv-ci.h | 9 + drivers/media/dvb/firewire/firedtv-dvb.c | 276 ++++++++ drivers/media/dvb/firewire/firedtv-fe.c | 245 +++++++ drivers/media/dvb/firewire/firedtv-iso.c | 111 +++ drivers/media/dvb/firewire/firedtv-rc.c | 191 ++++++ drivers/media/dvb/firewire/firedtv-rc.h | 11 + drivers/media/dvb/firewire/firedtv.h | 227 +++++++ 32 files changed, 3312 insertions(+), 3312 deletions(-) delete mode 100644 drivers/media/dvb/firesat/Kconfig delete mode 100644 drivers/media/dvb/firesat/Makefile delete mode 100644 drivers/media/dvb/firesat/avc_api.c delete mode 100644 drivers/media/dvb/firesat/avc_api.h delete mode 100644 drivers/media/dvb/firesat/cmp.c delete mode 100644 drivers/media/dvb/firesat/cmp.h delete mode 100644 drivers/media/dvb/firesat/firesat-ci.c delete mode 100644 drivers/media/dvb/firesat/firesat-ci.h delete mode 100644 drivers/media/dvb/firesat/firesat-rc.c delete mode 100644 drivers/media/dvb/firesat/firesat-rc.h delete mode 100644 drivers/media/dvb/firesat/firesat.h delete mode 100644 drivers/media/dvb/firesat/firesat_1394.c delete mode 100644 drivers/media/dvb/firesat/firesat_dvb.c delete mode 100644 drivers/media/dvb/firesat/firesat_fe.c delete mode 100644 drivers/media/dvb/firesat/firesat_iso.c create mode 100644 drivers/media/dvb/firewire/Kconfig create mode 100644 drivers/media/dvb/firewire/Makefile create mode 100644 drivers/media/dvb/firewire/avc.c create mode 100644 drivers/media/dvb/firewire/avc.h create mode 100644 drivers/media/dvb/firewire/cmp.c create mode 100644 drivers/media/dvb/firewire/cmp.h create mode 100644 drivers/media/dvb/firewire/firedtv-1394.c create mode 100644 drivers/media/dvb/firewire/firedtv-ci.c create mode 100644 drivers/media/dvb/firewire/firedtv-ci.h create mode 100644 drivers/media/dvb/firewire/firedtv-dvb.c create mode 100644 drivers/media/dvb/firewire/firedtv-fe.c create mode 100644 drivers/media/dvb/firewire/firedtv-iso.c create mode 100644 drivers/media/dvb/firewire/firedtv-rc.c create mode 100644 drivers/media/dvb/firewire/firedtv-rc.h create mode 100644 drivers/media/dvb/firewire/firedtv.h diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig index 8a2d5f9713d..5a74c5c62f1 100644 --- a/drivers/media/dvb/Kconfig +++ b/drivers/media/dvb/Kconfig @@ -51,7 +51,7 @@ comment "Supported SDMC DM1105 Adapters" depends on DVB_CORE && PCI && I2C source "drivers/media/dvb/dm1105/Kconfig" -source "drivers/media/dvb/firesat/Kconfig" +source "drivers/media/dvb/firewire/Kconfig" comment "Supported DVB Frontends" depends on DVB_CORE diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile index cb765816f76..6092a5bb5a7 100644 --- a/drivers/media/dvb/Makefile +++ b/drivers/media/dvb/Makefile @@ -4,4 +4,4 @@ obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/ -obj-$(CONFIG_DVB_FIREDTV) += firesat/ +obj-$(CONFIG_DVB_FIREDTV) += firewire/ diff --git a/drivers/media/dvb/firesat/Kconfig b/drivers/media/dvb/firesat/Kconfig deleted file mode 100644 index 03d25ad1035..00000000000 --- a/drivers/media/dvb/firesat/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -config DVB_FIREDTV - tristate "FireDTV (FireWire attached DVB receivers)" - depends on DVB_CORE && IEEE1394 && INPUT - help - Support for DVB receivers from Digital Everywhere, known as FireDTV - and FloppyDTV, which are connected via IEEE 1394 (FireWire). - - These devices don't have an MPEG decoder built in, so you need - an external software decoder to watch TV. - - To compile this driver as a module, say M here: the module will be - called firedtv. diff --git a/drivers/media/dvb/firesat/Makefile b/drivers/media/dvb/firesat/Makefile deleted file mode 100644 index 9e49edc7c49..00000000000 --- a/drivers/media/dvb/firesat/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -firedtv-objs := firesat_1394.o \ - firesat_dvb.o \ - firesat_fe.o \ - firesat_iso.o \ - avc_api.o \ - cmp.o \ - firesat-rc.o \ - firesat-ci.o - -obj-$(CONFIG_DVB_FIREDTV) += firedtv.o - -EXTRA_CFLAGS := -Idrivers/ieee1394 -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core diff --git a/drivers/media/dvb/firesat/avc_api.c b/drivers/media/dvb/firesat/avc_api.c deleted file mode 100644 index 3a4da73f079..00000000000 --- a/drivers/media/dvb/firesat/avc_api.c +++ /dev/null @@ -1,1051 +0,0 @@ -/* - * FireDTV driver (formerly known as FireSAT) - * - * Copyright (C) 2004 Andreas Monitzer - * Copyright (C) 2008 Ben Backx - * Copyright (C) 2008 Henrik Kurelid - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "avc_api.h" -#include "firesat.h" -#include "firesat-rc.h" - -#define FCP_COMMAND_REGISTER 0xfffff0000b00ULL - -static int __avc_write(struct firesat *firesat, - const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) -{ - int err, retry; - - if (RspFrm) - firesat->avc_reply_received = false; - - for (retry = 0; retry < 6; retry++) { - err = hpsb_node_write(firesat->ud->ne, FCP_COMMAND_REGISTER, - (quadlet_t *)CmdFrm, CmdFrm->length); - if (err) { - firesat->avc_reply_received = true; - dev_err(&firesat->ud->device, - "FCP command write failed\n"); - return err; - } - - if (!RspFrm) - return 0; - - /* - * AV/C specs say that answers should be sent within 150 ms. - * Time out after 200 ms. - */ - if (wait_event_timeout(firesat->avc_wait, - firesat->avc_reply_received, - HZ / 5) != 0) { - memcpy(RspFrm, firesat->respfrm, firesat->resp_length); - RspFrm->length = firesat->resp_length; - - return 0; - } - } - dev_err(&firesat->ud->device, "FCP response timed out\n"); - return -ETIMEDOUT; -} - -static int avc_write(struct firesat *firesat, - const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) -{ - int ret; - - if (mutex_lock_interruptible(&firesat->avc_mutex)) - return -EINTR; - - ret = __avc_write(firesat, CmdFrm, RspFrm); - - mutex_unlock(&firesat->avc_mutex); - return ret; -} - -int avc_recv(struct firesat *firesat, u8 *data, size_t length) -{ - AVCRspFrm *RspFrm = (AVCRspFrm *)data; - - if (length >= 8 && - RspFrm->operand[0] == SFE_VENDOR_DE_COMPANYID_0 && - RspFrm->operand[1] == SFE_VENDOR_DE_COMPANYID_1 && - RspFrm->operand[2] == SFE_VENDOR_DE_COMPANYID_2 && - RspFrm->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) { - if (RspFrm->resp == CHANGED) { - firesat_handle_rc(firesat, - RspFrm->operand[4] << 8 | RspFrm->operand[5]); - schedule_work(&firesat->remote_ctrl_work); - } else if (RspFrm->resp != INTERIM) { - dev_info(&firesat->ud->device, - "remote control result = %d\n", RspFrm->resp); - } - return 0; - } - - if (firesat->avc_reply_received) { - dev_err(&firesat->ud->device, - "received out-of-order AVC response, ignored\n"); - return -EIO; - } - - memcpy(firesat->respfrm, data, length); - firesat->resp_length = length; - - firesat->avc_reply_received = true; - wake_up(&firesat->avc_wait); - - return 0; -} - -/* - * tuning command for setting the relative LNB frequency - * (not supported by the AVC standard) - */ -static void avc_tuner_tuneqpsk(struct firesat *firesat, - struct dvb_frontend_parameters *params, AVCCmdFrm *CmdFrm) -{ - CmdFrm->opcode = VENDOR; - - CmdFrm->operand[0] = SFE_VENDOR_DE_COMPANYID_0; - CmdFrm->operand[1] = SFE_VENDOR_DE_COMPANYID_1; - CmdFrm->operand[2] = SFE_VENDOR_DE_COMPANYID_2; - CmdFrm->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK; - - CmdFrm->operand[4] = (params->frequency >> 24) & 0xff; - CmdFrm->operand[5] = (params->frequency >> 16) & 0xff; - CmdFrm->operand[6] = (params->frequency >> 8) & 0xff; - CmdFrm->operand[7] = params->frequency & 0xff; - - CmdFrm->operand[8] = ((params->u.qpsk.symbol_rate / 1000) >> 8) & 0xff; - CmdFrm->operand[9] = (params->u.qpsk.symbol_rate / 1000) & 0xff; - - switch(params->u.qpsk.fec_inner) { - case FEC_1_2: - CmdFrm->operand[10] = 0x1; break; - case FEC_2_3: - CmdFrm->operand[10] = 0x2; break; - case FEC_3_4: - CmdFrm->operand[10] = 0x3; break; - case FEC_5_6: - CmdFrm->operand[10] = 0x4; break; - case FEC_7_8: - CmdFrm->operand[10] = 0x5; break; - case FEC_4_5: - case FEC_8_9: - case FEC_AUTO: - default: - CmdFrm->operand[10] = 0x0; - } - - if (firesat->voltage == 0xff) - CmdFrm->operand[11] = 0xff; - else if (firesat->voltage == SEC_VOLTAGE_18) /* polarisation */ - CmdFrm->operand[11] = 0; - else - CmdFrm->operand[11] = 1; - - if (firesat->tone == 0xff) - CmdFrm->operand[12] = 0xff; - else if (firesat->tone == SEC_TONE_ON) /* band */ - CmdFrm->operand[12] = 1; - else - CmdFrm->operand[12] = 0; - - if (firesat->type == FireSAT_DVB_S2) { - CmdFrm->operand[13] = 0x1; - CmdFrm->operand[14] = 0xff; - CmdFrm->operand[15] = 0xff; - CmdFrm->length = 20; - } else { - CmdFrm->length = 16; - } -} - -static void avc_tuner_dsd_dvb_c(struct dvb_frontend_parameters *params, - AVCCmdFrm *CmdFrm) -{ - M_VALID_FLAGS flags; - - flags.Bits.Modulation = params->u.qam.modulation != QAM_AUTO; - flags.Bits.FEC_inner = params->u.qam.fec_inner != FEC_AUTO; - flags.Bits.FEC_outer = 0; - flags.Bits.Symbol_Rate = 1; - flags.Bits.Frequency = 1; - flags.Bits.Orbital_Pos = 0; - flags.Bits.Polarisation = 0; - flags.Bits.reserved_fields = 0; - flags.Bits.reserved1 = 0; - flags.Bits.Network_ID = 0; - - CmdFrm->opcode = DSD; - - CmdFrm->operand[0] = 0; /* source plug */ - CmdFrm->operand[1] = 0xd2; /* subfunction replace */ - CmdFrm->operand[2] = 0x20; /* system id = DVB */ - CmdFrm->operand[3] = 0x00; /* antenna number */ - /* system_specific_multiplex selection_length */ - CmdFrm->operand[4] = 0x11; - CmdFrm->operand[5] = flags.Valid_Word.ByteHi; /* valid_flags [0] */ - CmdFrm->operand[6] = flags.Valid_Word.ByteLo; /* valid_flags [1] */ - CmdFrm->operand[7] = 0x00; - CmdFrm->operand[8] = 0x00; - CmdFrm->operand[9] = 0x00; - CmdFrm->operand[10] = 0x00; - - CmdFrm->operand[11] = - (((params->frequency / 4000) >> 16) & 0xff) | (2 << 6); - CmdFrm->operand[12] = - ((params->frequency / 4000) >> 8) & 0xff; - CmdFrm->operand[13] = (params->frequency / 4000) & 0xff; - CmdFrm->operand[14] = - ((params->u.qpsk.symbol_rate / 1000) >> 12) & 0xff; - CmdFrm->operand[15] = - ((params->u.qpsk.symbol_rate / 1000) >> 4) & 0xff; - CmdFrm->operand[16] = - ((params->u.qpsk.symbol_rate / 1000) << 4) & 0xf0; - CmdFrm->operand[17] = 0x00; - - switch (params->u.qpsk.fec_inner) { - case FEC_1_2: - CmdFrm->operand[18] = 0x1; break; - case FEC_2_3: - CmdFrm->operand[18] = 0x2; break; - case FEC_3_4: - CmdFrm->operand[18] = 0x3; break; - case FEC_5_6: - CmdFrm->operand[18] = 0x4; break; - case FEC_7_8: - CmdFrm->operand[18] = 0x5; break; - case FEC_8_9: - CmdFrm->operand[18] = 0x6; break; - case FEC_4_5: - CmdFrm->operand[18] = 0x8; break; - case FEC_AUTO: - default: - CmdFrm->operand[18] = 0x0; - } - switch (params->u.qam.modulation) { - case QAM_16: - CmdFrm->operand[19] = 0x08; break; - case QAM_32: - CmdFrm->operand[19] = 0x10; break; - case QAM_64: - CmdFrm->operand[19] = 0x18; break; - case QAM_128: - CmdFrm->operand[19] = 0x20; break; - case QAM_256: - CmdFrm->operand[19] = 0x28; break; - case QAM_AUTO: - default: - CmdFrm->operand[19] = 0x00; - } - CmdFrm->operand[20] = 0x00; - CmdFrm->operand[21] = 0x00; - /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */ - CmdFrm->operand[22] = 0x00; - - CmdFrm->length = 28; -} - -static void avc_tuner_dsd_dvb_t(struct dvb_frontend_parameters *params, - AVCCmdFrm *CmdFrm) -{ - M_VALID_FLAGS flags; - - flags.Bits_T.GuardInterval = - params->u.ofdm.guard_interval != GUARD_INTERVAL_AUTO; - flags.Bits_T.CodeRateLPStream = - params->u.ofdm.code_rate_LP != FEC_AUTO; - flags.Bits_T.CodeRateHPStream = - params->u.ofdm.code_rate_HP != FEC_AUTO; - flags.Bits_T.HierarchyInfo = - params->u.ofdm.hierarchy_information != HIERARCHY_AUTO; - flags.Bits_T.Constellation = - params->u.ofdm.constellation != QAM_AUTO; - flags.Bits_T.Bandwidth = - params->u.ofdm.bandwidth != BANDWIDTH_AUTO; - flags.Bits_T.CenterFrequency = 1; - flags.Bits_T.reserved1 = 0; - flags.Bits_T.reserved2 = 0; - flags.Bits_T.OtherFrequencyFlag = 0; - flags.Bits_T.TransmissionMode = - params->u.ofdm.transmission_mode != TRANSMISSION_MODE_AUTO; - flags.Bits_T.NetworkId = 0; - - CmdFrm->opcode = DSD; - - CmdFrm->operand[0] = 0; /* source plug */ - CmdFrm->operand[1] = 0xd2; /* subfunction replace */ - CmdFrm->operand[2] = 0x20; /* system id = DVB */ - CmdFrm->operand[3] = 0x00; /* antenna number */ - /* system_specific_multiplex selection_length */ - CmdFrm->operand[4] = 0x0c; - CmdFrm->operand[5] = flags.Valid_Word.ByteHi; /* valid_flags [0] */ - CmdFrm->operand[6] = flags.Valid_Word.ByteLo; /* valid_flags [1] */ - CmdFrm->operand[7] = 0x0; - CmdFrm->operand[8] = (params->frequency / 10) >> 24; - CmdFrm->operand[9] = ((params->frequency / 10) >> 16) & 0xff; - CmdFrm->operand[10] = ((params->frequency / 10) >> 8) & 0xff; - CmdFrm->operand[11] = (params->frequency / 10) & 0xff; - - switch (params->u.ofdm.bandwidth) { - case BANDWIDTH_7_MHZ: - CmdFrm->operand[12] = 0x20; break; - case BANDWIDTH_8_MHZ: - case BANDWIDTH_6_MHZ: /* not defined by AVC spec */ - case BANDWIDTH_AUTO: - default: - CmdFrm->operand[12] = 0x00; - } - switch (params->u.ofdm.constellation) { - case QAM_16: - CmdFrm->operand[13] = 1 << 6; break; - case QAM_64: - CmdFrm->operand[13] = 2 << 6; break; - case QPSK: - default: - CmdFrm->operand[13] = 0x00; - } - switch (params->u.ofdm.hierarchy_information) { - case HIERARCHY_1: - CmdFrm->operand[13] |= 1 << 3; break; - case HIERARCHY_2: - CmdFrm->operand[13] |= 2 << 3; break; - case HIERARCHY_4: - CmdFrm->operand[13] |= 3 << 3; break; - case HIERARCHY_AUTO: - case HIERARCHY_NONE: - default: - break; - } - switch (params->u.ofdm.code_rate_HP) { - case FEC_2_3: - CmdFrm->operand[13] |= 1; break; - case FEC_3_4: - CmdFrm->operand[13] |= 2; break; - case FEC_5_6: - CmdFrm->operand[13] |= 3; break; - case FEC_7_8: - CmdFrm->operand[13] |= 4; break; - case FEC_1_2: - default: - break; - } - switch (params->u.ofdm.code_rate_LP) { - case FEC_2_3: - CmdFrm->operand[14] = 1 << 5; break; - case FEC_3_4: - CmdFrm->operand[14] = 2 << 5; break; - case FEC_5_6: - CmdFrm->operand[14] = 3 << 5; break; - case FEC_7_8: - CmdFrm->operand[14] = 4 << 5; break; - case FEC_1_2: - default: - CmdFrm->operand[14] = 0x00; break; - } - switch (params->u.ofdm.guard_interval) { - case GUARD_INTERVAL_1_16: - CmdFrm->operand[14] |= 1 << 3; break; - case GUARD_INTERVAL_1_8: - CmdFrm->operand[14] |= 2 << 3; break; - case GUARD_INTERVAL_1_4: - CmdFrm->operand[14] |= 3 << 3; break; - case GUARD_INTERVAL_1_32: - case GUARD_INTERVAL_AUTO: - default: - break; - } - switch (params->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_8K: - CmdFrm->operand[14] |= 1 << 1; break; - case TRANSMISSION_MODE_2K: - case TRANSMISSION_MODE_AUTO: - default: - break; - } - - CmdFrm->operand[15] = 0x00; /* network_ID[0] */ - CmdFrm->operand[16] = 0x00; /* network_ID[1] */ - /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */ - CmdFrm->operand[17] = 0x00; - - CmdFrm->length = 24; -} - -int avc_tuner_dsd(struct firesat *firesat, - struct dvb_frontend_parameters *params) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - - CmdFrm.cts = AVC; - CmdFrm.ctype = CONTROL; - CmdFrm.sutyp = 0x5; - CmdFrm.suid = firesat->subunit; - - switch (firesat->type) { - case FireSAT_DVB_S: - case FireSAT_DVB_S2: - avc_tuner_tuneqpsk(firesat, params, &CmdFrm); break; - case FireSAT_DVB_C: - avc_tuner_dsd_dvb_c(params, &CmdFrm); break; - case FireSAT_DVB_T: - avc_tuner_dsd_dvb_t(params, &CmdFrm); break; - default: - BUG(); - } - - if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) - return -EIO; - - msleep(500); -#if 0 - /* FIXME: */ - /* u8 *status was an out-parameter of avc_tuner_dsd, unused by caller */ - if(status) - *status=RspFrm.operand[2]; -#endif - return 0; -} - -int avc_tuner_set_pids(struct firesat *firesat, unsigned char pidc, u16 pid[]) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - int pos, k; - - if (pidc > 16 && pidc != 0xff) - return -EINVAL; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - - CmdFrm.cts = AVC; - CmdFrm.ctype = CONTROL; - CmdFrm.sutyp = 0x5; - CmdFrm.suid = firesat->subunit; - CmdFrm.opcode = DSD; - - CmdFrm.operand[0] = 0; // source plug - CmdFrm.operand[1] = 0xD2; // subfunction replace - CmdFrm.operand[2] = 0x20; // system id = DVB - CmdFrm.operand[3] = 0x00; // antenna number - CmdFrm.operand[4] = 0x00; // system_specific_multiplex selection_length - CmdFrm.operand[5] = pidc; // Nr_of_dsd_sel_specs - - pos = 6; - if (pidc != 0xff) - for (k = 0; k < pidc; k++) { - CmdFrm.operand[pos++] = 0x13; // flowfunction relay - CmdFrm.operand[pos++] = 0x80; // dsd_sel_spec_valid_flags -> PID - CmdFrm.operand[pos++] = (pid[k] >> 8) & 0x1F; - CmdFrm.operand[pos++] = pid[k] & 0xFF; - CmdFrm.operand[pos++] = 0x00; // tableID - CmdFrm.operand[pos++] = 0x00; // filter_length - } - - CmdFrm.length = ALIGN(3 + pos, 4); - - if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) - return -EIO; - - msleep(50); - return 0; -} - -int avc_tuner_get_ts(struct firesat *firesat) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - - CmdFrm.cts = AVC; - CmdFrm.ctype = CONTROL; - CmdFrm.sutyp = 0x5; - CmdFrm.suid = firesat->subunit; - CmdFrm.opcode = DSIT; - - CmdFrm.operand[0] = 0; // source plug - CmdFrm.operand[1] = 0xD2; // subfunction replace - CmdFrm.operand[2] = 0xFF; //status - CmdFrm.operand[3] = 0x20; // system id = DVB - CmdFrm.operand[4] = 0x00; // antenna number - CmdFrm.operand[5] = 0x0; // system_specific_search_flags - CmdFrm.operand[6] = (firesat->type == FireSAT_DVB_T)?0x0c:0x11; // system_specific_multiplex selection_length - CmdFrm.operand[7] = 0x00; // valid_flags [0] - CmdFrm.operand[8] = 0x00; // valid_flags [1] - CmdFrm.operand[7 + (firesat->type == FireSAT_DVB_T)?0x0c:0x11] = 0x00; // nr_of_dsit_sel_specs (always 0) - - CmdFrm.length = (firesat->type == FireSAT_DVB_T)?24:28; - - if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) - return -EIO; - - msleep(250); - return 0; -} - -int avc_identify_subunit(struct firesat *firesat) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - - memset(&CmdFrm,0,sizeof(AVCCmdFrm)); - - CmdFrm.cts = AVC; - CmdFrm.ctype = CONTROL; - CmdFrm.sutyp = 0x5; // tuner - CmdFrm.suid = firesat->subunit; - CmdFrm.opcode = READ_DESCRIPTOR; - - CmdFrm.operand[0]=DESCRIPTOR_SUBUNIT_IDENTIFIER; - CmdFrm.operand[1]=0xff; - CmdFrm.operand[2]=0x00; - CmdFrm.operand[3]=0x00; // length highbyte - CmdFrm.operand[4]=0x08; // length lowbyte - CmdFrm.operand[5]=0x00; // offset highbyte - CmdFrm.operand[6]=0x0d; // offset lowbyte - - CmdFrm.length=12; - - if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) - return -EIO; - - if ((RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) || - (RspFrm.operand[3] << 8) + RspFrm.operand[4] != 8) { - dev_err(&firesat->ud->device, - "cannot read subunit identifier\n"); - return -EINVAL; - } - return 0; -} - -int avc_tuner_status(struct firesat *firesat, - ANTENNA_INPUT_INFO *antenna_input_info) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - int length; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - - CmdFrm.cts=AVC; - CmdFrm.ctype=CONTROL; - CmdFrm.sutyp=0x05; // tuner - CmdFrm.suid=firesat->subunit; - CmdFrm.opcode=READ_DESCRIPTOR; - - CmdFrm.operand[0]=DESCRIPTOR_TUNER_STATUS; - CmdFrm.operand[1]=0xff; //read_result_status - CmdFrm.operand[2]=0x00; // reserver - CmdFrm.operand[3]=0;//sizeof(ANTENNA_INPUT_INFO) >> 8; - CmdFrm.operand[4]=0;//sizeof(ANTENNA_INPUT_INFO) & 0xFF; - CmdFrm.operand[5]=0x00; - CmdFrm.operand[6]=0x00; - CmdFrm.length=12; - - if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) - return -EIO; - - if (RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) { - dev_err(&firesat->ud->device, "cannot read tuner status\n"); - return -EINVAL; - } - - length = RspFrm.operand[9]; - if (RspFrm.operand[1] != 0x10 || length != sizeof(ANTENNA_INPUT_INFO)) { - dev_err(&firesat->ud->device, "got invalid tuner status\n"); - return -EINVAL; - } - - memcpy(antenna_input_info, &RspFrm.operand[10], length); - return 0; -} - -int avc_lnb_control(struct firesat *firesat, char voltage, char burst, - char conttone, char nrdiseq, - struct dvb_diseqc_master_cmd *diseqcmd) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - int i, j, k; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - - CmdFrm.cts=AVC; - CmdFrm.ctype=CONTROL; - CmdFrm.sutyp=0x05; - CmdFrm.suid=firesat->subunit; - CmdFrm.opcode=VENDOR; - - CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; - CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; - CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; - CmdFrm.operand[3]=SFE_VENDOR_OPCODE_LNB_CONTROL; - - CmdFrm.operand[4]=voltage; - CmdFrm.operand[5]=nrdiseq; - - i=6; - - for (j = 0; j < nrdiseq; j++) { - CmdFrm.operand[i++] = diseqcmd[j].msg_len; - - for (k = 0; k < diseqcmd[j].msg_len; k++) - CmdFrm.operand[i++] = diseqcmd[j].msg[k]; - } - - CmdFrm.operand[i++]=burst; - CmdFrm.operand[i++]=conttone; - - CmdFrm.length = ALIGN(3 + i, 4); - - if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) - return -EIO; - - if (RspFrm.resp != ACCEPTED) { - dev_err(&firesat->ud->device, "LNB control failed\n"); - return -EINVAL; - } - - return 0; -} - -int avc_register_remote_control(struct firesat *firesat) -{ - AVCCmdFrm CmdFrm; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - - CmdFrm.cts = AVC; - CmdFrm.ctype = NOTIFY; - CmdFrm.sutyp = 0x1f; - CmdFrm.suid = 0x7; - CmdFrm.opcode = VENDOR; - - CmdFrm.operand[0] = SFE_VENDOR_DE_COMPANYID_0; - CmdFrm.operand[1] = SFE_VENDOR_DE_COMPANYID_1; - CmdFrm.operand[2] = SFE_VENDOR_DE_COMPANYID_2; - CmdFrm.operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL; - - CmdFrm.length = 8; - - return avc_write(firesat, &CmdFrm, NULL); -} - -void avc_remote_ctrl_work(struct work_struct *work) -{ - struct firesat *firesat = - container_of(work, struct firesat, remote_ctrl_work); - - /* Should it be rescheduled in failure cases? */ - avc_register_remote_control(firesat); -} - -#if 0 /* FIXME: unused */ -int avc_tuner_host2ca(struct firesat *firesat) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - CmdFrm.cts = AVC; - CmdFrm.ctype = CONTROL; - CmdFrm.sutyp = 0x5; - CmdFrm.suid = firesat->subunit; - CmdFrm.opcode = VENDOR; - - CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; - CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; - CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; - CmdFrm.operand[3]=SFE_VENDOR_OPCODE_HOST2CA; - CmdFrm.operand[4] = 0; // slot - CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; // ca tag - CmdFrm.operand[6] = 0; // more/last - CmdFrm.operand[7] = 0; // length - CmdFrm.length = 12; - - if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) - return -EIO; - - return 0; -} -#endif - -static int get_ca_object_pos(AVCRspFrm *RspFrm) -{ - int length = 1; - - /* Check length of length field */ - if (RspFrm->operand[7] & 0x80) - length = (RspFrm->operand[7] & 0x7f) + 1; - return length + 7; -} - -static int get_ca_object_length(AVCRspFrm *RspFrm) -{ -#if 0 /* FIXME: unused */ - int size = 0; - int i; - - if (RspFrm->operand[7] & 0x80) - for (i = 0; i < (RspFrm->operand[7] & 0x7f); i++) { - size <<= 8; - size += RspFrm->operand[8 + i]; - } -#endif - return RspFrm->operand[7]; -} - -int avc_ca_app_info(struct firesat *firesat, char *app_info, unsigned int *len) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - int pos; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - CmdFrm.cts = AVC; - CmdFrm.ctype = STATUS; - CmdFrm.sutyp = 0x5; - CmdFrm.suid = firesat->subunit; - CmdFrm.opcode = VENDOR; - - CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; - CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; - CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; - CmdFrm.operand[3]=SFE_VENDOR_OPCODE_CA2HOST; - CmdFrm.operand[4] = 0; // slot - CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; // ca tag - CmdFrm.length = 12; - - if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) - return -EIO; - - /* FIXME: check response code and validate response data */ - - pos = get_ca_object_pos(&RspFrm); - app_info[0] = (TAG_APP_INFO >> 16) & 0xFF; - app_info[1] = (TAG_APP_INFO >> 8) & 0xFF; - app_info[2] = (TAG_APP_INFO >> 0) & 0xFF; - app_info[3] = 6 + RspFrm.operand[pos + 4]; - app_info[4] = 0x01; - memcpy(&app_info[5], &RspFrm.operand[pos], 5 + RspFrm.operand[pos + 4]); - *len = app_info[3] + 4; - - return 0; -} - -int avc_ca_info(struct firesat *firesat, char *app_info, unsigned int *len) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - int pos; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - CmdFrm.cts = AVC; - CmdFrm.ctype = STATUS; - CmdFrm.sutyp = 0x5; - CmdFrm.suid = firesat->subunit; - CmdFrm.opcode = VENDOR; - - CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; - CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; - CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; - CmdFrm.operand[3]=SFE_VENDOR_OPCODE_CA2HOST; - CmdFrm.operand[4] = 0; // slot - CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; // ca tag - CmdFrm.length = 12; - - if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) - return -EIO; - - pos = get_ca_object_pos(&RspFrm); - app_info[0] = (TAG_CA_INFO >> 16) & 0xFF; - app_info[1] = (TAG_CA_INFO >> 8) & 0xFF; - app_info[2] = (TAG_CA_INFO >> 0) & 0xFF; - app_info[3] = 2; - app_info[4] = RspFrm.operand[pos + 0]; - app_info[5] = RspFrm.operand[pos + 1]; - *len = app_info[3] + 4; - - return 0; -} - -int avc_ca_reset(struct firesat *firesat) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - CmdFrm.cts = AVC; - CmdFrm.ctype = CONTROL; - CmdFrm.sutyp = 0x5; - CmdFrm.suid = firesat->subunit; - CmdFrm.opcode = VENDOR; - - CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; - CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; - CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; - CmdFrm.operand[3]=SFE_VENDOR_OPCODE_HOST2CA; - CmdFrm.operand[4] = 0; // slot - CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_RESET; // ca tag - CmdFrm.operand[6] = 0; // more/last - CmdFrm.operand[7] = 1; // length - CmdFrm.operand[8] = 0; // force hardware reset - CmdFrm.length = 12; - - if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) - return -EIO; - - return 0; -} - -int avc_ca_pmt(struct firesat *firesat, char *msg, int length) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - int list_management; - int program_info_length; - int pmt_cmd_id; - int read_pos; - int write_pos; - int es_info_length; - int crc32_csum; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - CmdFrm.cts = AVC; - CmdFrm.ctype = CONTROL; - CmdFrm.sutyp = 0x5; - CmdFrm.suid = firesat->subunit; - CmdFrm.opcode = VENDOR; - - if (msg[0] != LIST_MANAGEMENT_ONLY) { - dev_info(&firesat->ud->device, - "forcing list_management to ONLY\n"); - msg[0] = LIST_MANAGEMENT_ONLY; - } - // We take the cmd_id from the programme level only! - list_management = msg[0]; - program_info_length = ((msg[4] & 0x0F) << 8) + msg[5]; - if (program_info_length > 0) - program_info_length--; // Remove pmt_cmd_id - pmt_cmd_id = msg[6]; - - CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; - CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; - CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; - CmdFrm.operand[3]=SFE_VENDOR_OPCODE_HOST2CA; - CmdFrm.operand[4] = 0; // slot - CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_PMT; // ca tag - CmdFrm.operand[6] = 0; // more/last - //CmdFrm.operand[7] = XXXprogram_info_length + 17; // length - CmdFrm.operand[8] = list_management; - CmdFrm.operand[9] = 0x01; // pmt_cmd=OK_descramble - - // TS program map table - - // Table id=2 - CmdFrm.operand[10] = 0x02; - // Section syntax + length - CmdFrm.operand[11] = 0x80; - //CmdFrm.operand[12] = XXXprogram_info_length + 12; - // Program number - CmdFrm.operand[13] = msg[1]; - CmdFrm.operand[14] = msg[2]; - // Version number=0 + current/next=1 - CmdFrm.operand[15] = 0x01; - // Section number=0 - CmdFrm.operand[16] = 0x00; - // Last section number=0 - CmdFrm.operand[17] = 0x00; - // PCR_PID=1FFF - CmdFrm.operand[18] = 0x1F; - CmdFrm.operand[19] = 0xFF; - // Program info length - CmdFrm.operand[20] = (program_info_length >> 8); - CmdFrm.operand[21] = (program_info_length & 0xFF); - // CA descriptors at programme level - read_pos = 6; - write_pos = 22; - if (program_info_length > 0) { - pmt_cmd_id = msg[read_pos++]; - if (pmt_cmd_id != 1 && pmt_cmd_id != 4) - dev_err(&firesat->ud->device, - "invalid pmt_cmd_id %d\n", pmt_cmd_id); - - memcpy(&CmdFrm.operand[write_pos], &msg[read_pos], - program_info_length); - read_pos += program_info_length; - write_pos += program_info_length; - } - while (read_pos < length) { - CmdFrm.operand[write_pos++] = msg[read_pos++]; - CmdFrm.operand[write_pos++] = msg[read_pos++]; - CmdFrm.operand[write_pos++] = msg[read_pos++]; - es_info_length = - ((msg[read_pos] & 0x0F) << 8) + msg[read_pos + 1]; - read_pos += 2; - if (es_info_length > 0) - es_info_length--; // Remove pmt_cmd_id - CmdFrm.operand[write_pos++] = es_info_length >> 8; - CmdFrm.operand[write_pos++] = es_info_length & 0xFF; - if (es_info_length > 0) { - pmt_cmd_id = msg[read_pos++]; - if (pmt_cmd_id != 1 && pmt_cmd_id != 4) - dev_err(&firesat->ud->device, - "invalid pmt_cmd_id %d " - "at stream level\n", pmt_cmd_id); - - memcpy(&CmdFrm.operand[write_pos], &msg[read_pos], - es_info_length); - read_pos += es_info_length; - write_pos += es_info_length; - } - } - - // CRC - CmdFrm.operand[write_pos++] = 0x00; - CmdFrm.operand[write_pos++] = 0x00; - CmdFrm.operand[write_pos++] = 0x00; - CmdFrm.operand[write_pos++] = 0x00; - - CmdFrm.operand[7] = write_pos - 8; - CmdFrm.operand[12] = write_pos - 13; - - crc32_csum = crc32_be(0, &CmdFrm.operand[10], - CmdFrm.operand[12] - 1); - CmdFrm.operand[write_pos - 4] = (crc32_csum >> 24) & 0xFF; - CmdFrm.operand[write_pos - 3] = (crc32_csum >> 16) & 0xFF; - CmdFrm.operand[write_pos - 2] = (crc32_csum >> 8) & 0xFF; - CmdFrm.operand[write_pos - 1] = (crc32_csum >> 0) & 0xFF; - - CmdFrm.length = ALIGN(3 + write_pos, 4); - - if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) - return -EIO; - - if (RspFrm.resp != ACCEPTED) { - dev_err(&firesat->ud->device, - "CA PMT failed with response 0x%x\n", RspFrm.resp); - return -EFAULT; - } - - return 0; -} - -int avc_ca_get_time_date(struct firesat *firesat, int *interval) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - CmdFrm.cts = AVC; - CmdFrm.ctype = STATUS; - CmdFrm.sutyp = 0x5; - CmdFrm.suid = firesat->subunit; - CmdFrm.opcode = VENDOR; - - CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; - CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; - CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; - CmdFrm.operand[3]=SFE_VENDOR_OPCODE_CA2HOST; - CmdFrm.operand[4] = 0; // slot - CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_DATE_TIME; // ca tag - CmdFrm.operand[6] = 0; // more/last - CmdFrm.operand[7] = 0; // length - CmdFrm.length = 12; - - if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) - return -EIO; - - /* FIXME: check response code and validate response data */ - - *interval = RspFrm.operand[get_ca_object_pos(&RspFrm)]; - - return 0; -} - -int avc_ca_enter_menu(struct firesat *firesat) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - CmdFrm.cts = AVC; - CmdFrm.ctype = STATUS; - CmdFrm.sutyp = 0x5; - CmdFrm.suid = firesat->subunit; - CmdFrm.opcode = VENDOR; - - CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; - CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; - CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; - CmdFrm.operand[3]=SFE_VENDOR_OPCODE_HOST2CA; - CmdFrm.operand[4] = 0; // slot - CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_ENTER_MENU; - CmdFrm.operand[6] = 0; // more/last - CmdFrm.operand[7] = 0; // length - CmdFrm.length = 12; - - if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) - return -EIO; - - return 0; -} - -int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, unsigned int *len) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - CmdFrm.cts = AVC; - CmdFrm.ctype = STATUS; - CmdFrm.sutyp = 0x5; - CmdFrm.suid = firesat->subunit; - CmdFrm.opcode = VENDOR; - - CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; - CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; - CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; - CmdFrm.operand[3]=SFE_VENDOR_OPCODE_CA2HOST; - CmdFrm.operand[4] = 0; // slot - CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_MMI; - CmdFrm.operand[6] = 0; // more/last - CmdFrm.operand[7] = 0; // length - CmdFrm.length = 12; - - if (avc_write(firesat, &CmdFrm, &RspFrm) < 0) - return -EIO; - - /* FIXME: check response code and validate response data */ - - *len = get_ca_object_length(&RspFrm); - memcpy(mmi_object, &RspFrm.operand[get_ca_object_pos(&RspFrm)], *len); - - return 0; -} diff --git a/drivers/media/dvb/firesat/avc_api.h b/drivers/media/dvb/firesat/avc_api.h deleted file mode 100644 index 9d2efd8ff17..00000000000 --- a/drivers/media/dvb/firesat/avc_api.h +++ /dev/null @@ -1,432 +0,0 @@ -/* - * AV/C API - * - * Copyright (C) 2000 Manfred Weihs - * Copyright (C) 2003 Philipp Gutgsell <0014guph@edu.fh-kaernten.ac.at> - * Copyright (C) 2004 Andreas Monitzer - * Copyright (C) 2008 Ben Backx - * Copyright (C) 2008 Henrik Kurelid - * - * This is based on code written by Peter Halwachs, Thomas Groiss and - * Andreas Monitzer. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - */ - -#ifndef _AVC_API_H -#define _AVC_API_H - -#include - -/************************************************************* - Constants from EN510221 -**************************************************************/ -#define LIST_MANAGEMENT_ONLY 0x03 - -/************************************************************ - definition of structures -*************************************************************/ -typedef struct { - int Nr_SourcePlugs; - int Nr_DestinationPlugs; -} TunerInfo; - - -/*********************************************** - - supported cts - -************************************************/ - -#define AVC 0x0 - -// FCP command frame with ctype = 0x0 is AVC command frame - -#ifdef __LITTLE_ENDIAN - -// Definition FCP Command Frame -typedef struct _AVCCmdFrm -{ - // AV/C command frame - __u8 ctype : 4 ; // command type - __u8 cts : 4 ; // always 0x0 for AVC - __u8 suid : 3 ; // subunit ID - __u8 sutyp : 5 ; // subunit_typ - __u8 opcode : 8 ; // opcode - __u8 operand[509] ; // array of operands [1-507] - int length; //length of the command frame -} AVCCmdFrm ; - -// Definition FCP Response Frame -typedef struct _AVCRspFrm -{ - // AV/C response frame - __u8 resp : 4 ; // response type - __u8 cts : 4 ; // always 0x0 for AVC - __u8 suid : 3 ; // subunit ID - __u8 sutyp : 5 ; // subunit_typ - __u8 opcode : 8 ; // opcode - __u8 operand[509] ; // array of operands [1-507] - int length; //length of the response frame -} AVCRspFrm ; - -#else - -typedef struct _AVCCmdFrm -{ - __u8 cts:4; - __u8 ctype:4; - __u8 sutyp:5; - __u8 suid:3; - __u8 opcode; - __u8 operand[509]; - int length; -} AVCCmdFrm; - -typedef struct _AVCRspFrm -{ - __u8 cts:4; - __u8 resp:4; - __u8 sutyp:5; - __u8 suid:3; - __u8 opcode; - __u8 operand[509]; - int length; -} AVCRspFrm; - -#endif - -/************************************************************* - AVC command types (ctype) -**************************************************************/// -#define CONTROL 0x00 -#define STATUS 0x01 -#define INQUIRY 0x02 -#define NOTIFY 0x03 - -/************************************************************* - AVC respond types -**************************************************************/// -#define NOT_IMPLEMENTED 0x8 -#define ACCEPTED 0x9 -#define REJECTED 0xA -#define STABLE 0xC -#define CHANGED 0xD -#define INTERIM 0xF - -/************************************************************* - AVC opcodes -**************************************************************/// -#define CONNECT 0x24 -#define DISCONNECT 0x25 -#define UNIT_INFO 0x30 -#define SUBUNIT_Info 0x31 -#define VENDOR 0x00 - -#define PLUG_INFO 0x02 -#define OPEN_DESCRIPTOR 0x08 -#define READ_DESCRIPTOR 0x09 -#define OBJECT_NUMBER_SELECT 0x0D - -/************************************************************* - AVCTuner opcodes -**************************************************************/ - -#define DSIT 0xC8 -#define DSD 0xCB -#define DESCRIPTOR_TUNER_STATUS 0x80 -#define DESCRIPTOR_SUBUNIT_IDENTIFIER 0x00 - -/************************************************************* - AVCTuner list types -**************************************************************/ -#define Multiplex_List 0x80 -#define Service_List 0x82 - -/************************************************************* - AVCTuner object entries -**************************************************************/ -#define Multiplex 0x80 -#define Service 0x82 -#define Service_with_specified_components 0x83 -#define Preferred_components 0x90 -#define Component 0x84 - -/************************************************************* - Vendor-specific commands -**************************************************************/ - -// digital everywhere vendor ID -#define SFE_VENDOR_DE_COMPANYID_0 0x00 -#define SFE_VENDOR_DE_COMPANYID_1 0x12 -#define SFE_VENDOR_DE_COMPANYID_2 0x87 - -#define SFE_VENDOR_MAX_NR_COMPONENTS 0x4 -#define SFE_VENDOR_MAX_NR_SERVICES 0x3 -#define SFE_VENDOR_MAX_NR_DSD_ELEMENTS 0x10 - -// vendor commands -#define SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL 0x0A -#define SFE_VENDOR_OPCODE_LNB_CONTROL 0x52 -#define SFE_VENDOR_OPCODE_TUNE_QPSK 0x58 // QPSK command for DVB-S - -// TODO: following vendor specific commands needs to be implemented -#define SFE_VENDOR_OPCODE_GET_FIRMWARE_VERSION 0x00 -#define SFE_VENDOR_OPCODE_HOST2CA 0x56 -#define SFE_VENDOR_OPCODE_CA2HOST 0x57 -#define SFE_VENDOR_OPCODE_CISTATUS 0x59 -#define SFE_VENDOR_OPCODE_TUNE_QPSK2 0x60 // QPSK command for DVB-S2 devices - -// CA Tags -#define SFE_VENDOR_TAG_CA_RESET 0x00 -#define SFE_VENDOR_TAG_CA_APPLICATION_INFO 0x01 -#define SFE_VENDOR_TAG_CA_PMT 0x02 -#define SFE_VENDOR_TAG_CA_DATE_TIME 0x04 -#define SFE_VENDOR_TAG_CA_MMI 0x05 -#define SFE_VENDOR_TAG_CA_ENTER_MENU 0x07 - - -//AVCTuner DVB identifier service_ID -#define DVB 0x20 - -/************************************************************* - AVC descriptor types -**************************************************************/ - -#define Subunit_Identifier_Descriptor 0x00 -#define Tuner_Status_Descriptor 0x80 - -typedef struct { - __u8 Subunit_Type; - __u8 Max_Subunit_ID; -} SUBUNIT_INFO; - -/************************************************************* - - AVCTuner DVB object IDs are 6 byte long - -**************************************************************/ - -typedef struct { - __u8 Byte0; - __u8 Byte1; - __u8 Byte2; - __u8 Byte3; - __u8 Byte4; - __u8 Byte5; -}OBJECT_ID; - -/************************************************************* - MULIPLEX Structs -**************************************************************/ -typedef struct -{ -#ifdef __LITTLE_ENDIAN - __u8 RF_frequency_hByte:6; - __u8 raster_Frequency:2;//Bit7,6 raster frequency -#else - __u8 raster_Frequency:2; - __u8 RF_frequency_hByte:6; -#endif - __u8 RF_frequency_mByte; - __u8 RF_frequency_lByte; - -}FREQUENCY; - -#ifdef __LITTLE_ENDIAN - -typedef struct -{ - __u8 Modulation :1; - __u8 FEC_inner :1; - __u8 FEC_outer :1; - __u8 Symbol_Rate :1; - __u8 Frequency :1; - __u8 Orbital_Pos :1; - __u8 Polarisation :1; - __u8 reserved_fields :1; - __u8 reserved1 :7; - __u8 Network_ID :1; - -}MULTIPLEX_VALID_FLAGS; - -typedef struct -{ - __u8 GuardInterval:1; - __u8 CodeRateLPStream:1; - __u8 CodeRateHPStream:1; - __u8 HierarchyInfo:1; - __u8 Constellation:1; - __u8 Bandwidth:1; - __u8 CenterFrequency:1; - __u8 reserved1:1; - __u8 reserved2:5; - __u8 OtherFrequencyFlag:1; - __u8 TransmissionMode:1; - __u8 NetworkId:1; -}MULTIPLEX_VALID_FLAGS_DVBT; - -#else - -typedef struct { - __u8 reserved_fields:1; - __u8 Polarisation:1; - __u8 Orbital_Pos:1; - __u8 Frequency:1; - __u8 Symbol_Rate:1; - __u8 FEC_outer:1; - __u8 FEC_inner:1; - __u8 Modulation:1; - __u8 Network_ID:1; - __u8 reserved1:7; -}MULTIPLEX_VALID_FLAGS; - -typedef struct { - __u8 reserved1:1; - __u8 CenterFrequency:1; - __u8 Bandwidth:1; - __u8 Constellation:1; - __u8 HierarchyInfo:1; - __u8 CodeRateHPStream:1; - __u8 CodeRateLPStream:1; - __u8 GuardInterval:1; - __u8 NetworkId:1; - __u8 TransmissionMode:1; - __u8 OtherFrequencyFlag:1; - __u8 reserved2:5; -}MULTIPLEX_VALID_FLAGS_DVBT; - -#endif - -typedef union { - MULTIPLEX_VALID_FLAGS Bits; - MULTIPLEX_VALID_FLAGS_DVBT Bits_T; - struct { - __u8 ByteHi; - __u8 ByteLo; - } Valid_Word; -} M_VALID_FLAGS; - -typedef struct -{ -#ifdef __LITTLE_ENDIAN - __u8 ActiveSystem; - __u8 reserved:5; - __u8 NoRF:1; - __u8 Moving:1; - __u8 Searching:1; - - __u8 SelectedAntenna:7; - __u8 Input:1; - - __u8 BER[4]; - - __u8 SignalStrength; - FREQUENCY Frequency; - - __u8 ManDepInfoLength; - - __u8 PowerSupply:1; - __u8 FrontEndPowerStatus:1; - __u8 reserved3:1; - __u8 AntennaError:1; - __u8 FrontEndError:1; - __u8 reserved2:3; - - __u8 CarrierNoiseRatio[2]; - __u8 reserved4[2]; - __u8 PowerSupplyVoltage; - __u8 AntennaVoltage; - __u8 FirewireBusVoltage; - - __u8 CaMmi:1; - __u8 reserved5:7; - - __u8 reserved6:1; - __u8 CaInitializationStatus:1; - __u8 CaErrorFlag:1; - __u8 CaDvbFlag:1; - __u8 CaModulePresentStatus:1; - __u8 CaApplicationInfo:1; - __u8 CaDateTimeRequest:1; - __u8 CaPmtReply:1; - -#else - __u8 ActiveSystem; - __u8 Searching:1; - __u8 Moving:1; - __u8 NoRF:1; - __u8 reserved:5; - - __u8 Input:1; - __u8 SelectedAntenna:7; - - __u8 BER[4]; - - __u8 SignalStrength; - FREQUENCY Frequency; - - __u8 ManDepInfoLength; - - __u8 reserved2:3; - __u8 FrontEndError:1; - __u8 AntennaError:1; - __u8 reserved3:1; - __u8 FrontEndPowerStatus:1; - __u8 PowerSupply:1; - - __u8 CarrierNoiseRatio[2]; - __u8 reserved4[2]; - __u8 PowerSupplyVoltage; - __u8 AntennaVoltage; - __u8 FirewireBusVoltage; - - __u8 reserved5:7; - __u8 CaMmi:1; - __u8 CaPmtReply:1; - __u8 CaDateTimeRequest:1; - __u8 CaApplicationInfo:1; - __u8 CaModulePresentStatus:1; - __u8 CaDvbFlag:1; - __u8 CaErrorFlag:1; - __u8 CaInitializationStatus:1; - __u8 reserved6:1; - -#endif -} ANTENNA_INPUT_INFO; // 22 Byte - -#define LNBCONTROL_DONTCARE 0xff - -struct dvb_diseqc_master_cmd; -struct dvb_frontend_parameters; -struct firesat; - -int avc_recv(struct firesat *firesat, u8 *data, size_t length); - -int AVCTuner_DSIT(struct firesat *firesat, int Source_Plug, - struct dvb_frontend_parameters *params, __u8 *status); - -int avc_tuner_status(struct firesat *firesat, - ANTENNA_INPUT_INFO *antenna_input_info); -int avc_tuner_dsd(struct firesat *firesat, - struct dvb_frontend_parameters *params); -int avc_tuner_set_pids(struct firesat *firesat, unsigned char pidc, u16 pid[]); -int avc_tuner_get_ts(struct firesat *firesat); -int avc_identify_subunit(struct firesat *firesat); -int avc_lnb_control(struct firesat *firesat, char voltage, char burst, - char conttone, char nrdiseq, - struct dvb_diseqc_master_cmd *diseqcmd); -void avc_remote_ctrl_work(struct work_struct *work); -int avc_register_remote_control(struct firesat *firesat); -int avc_ca_app_info(struct firesat *firesat, char *app_info, unsigned int *len); -int avc_ca_info(struct firesat *firesat, char *app_info, unsigned int *len); -int avc_ca_reset(struct firesat *firesat); -int avc_ca_pmt(struct firesat *firesat, char *app_info, int length); -int avc_ca_get_time_date(struct firesat *firesat, int *interval); -int avc_ca_enter_menu(struct firesat *firesat); -int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, unsigned int *len); - -#endif /* _AVC_API_H */ diff --git a/drivers/media/dvb/firesat/cmp.c b/drivers/media/dvb/firesat/cmp.c deleted file mode 100644 index 8e98b814e43..00000000000 --- a/drivers/media/dvb/firesat/cmp.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * FireDTV driver (formerly known as FireSAT) - * - * Copyright (C) 2004 Andreas Monitzer - * Copyright (C) 2008 Henrik Kurelid - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - */ - -#include -#include -#include -#include - -#include - -#include -#include - -#include "avc_api.h" -#include "cmp.h" -#include "firesat.h" - -#define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL - -static int cmp_read(struct firesat *firesat, void *buf, u64 addr, size_t len) -{ - int ret; - - if (mutex_lock_interruptible(&firesat->avc_mutex)) - return -EINTR; - - ret = hpsb_node_read(firesat->ud->ne, addr, buf, len); - if (ret < 0) - dev_err(&firesat->ud->device, "CMP: read I/O error\n"); - - mutex_unlock(&firesat->avc_mutex); - return ret; -} - -static int cmp_lock(struct firesat *firesat, void *data, u64 addr, __be32 arg, - int ext_tcode) -{ - int ret; - - if (mutex_lock_interruptible(&firesat->avc_mutex)) - return -EINTR; - - ret = hpsb_node_lock(firesat->ud->ne, addr, ext_tcode, data, - (__force quadlet_t)arg); - if (ret < 0) - dev_err(&firesat->ud->device, "CMP: lock I/O error\n"); - - mutex_unlock(&firesat->avc_mutex); - return ret; -} - -static inline u32 get_opcr(__be32 opcr, u32 mask, u32 shift) -{ - return (be32_to_cpu(opcr) >> shift) & mask; -} - -static inline void set_opcr(__be32 *opcr, u32 value, u32 mask, u32 shift) -{ - *opcr &= ~cpu_to_be32(mask << shift); - *opcr |= cpu_to_be32((value & mask) << shift); -} - -#define get_opcr_online(v) get_opcr((v), 0x1, 31) -#define get_opcr_p2p_connections(v) get_opcr((v), 0x3f, 24) -#define get_opcr_channel(v) get_opcr((v), 0x3f, 16) - -#define set_opcr_p2p_connections(p, v) set_opcr((p), (v), 0x3f, 24) -#define set_opcr_channel(p, v) set_opcr((p), (v), 0x3f, 16) -#define set_opcr_data_rate(p, v) set_opcr((p), (v), 0x3, 14) -#define set_opcr_overhead_id(p, v) set_opcr((p), (v), 0xf, 10) - -int cmp_establish_pp_connection(struct firesat *firesat, int plug, int channel) -{ - __be32 old_opcr, opcr; - u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); - int attempts = 0; - int ret; - - ret = cmp_read(firesat, &opcr, opcr_address, 4); - if (ret < 0) - return ret; - -repeat: - if (!get_opcr_online(opcr)) { - dev_err(&firesat->ud->device, "CMP: output offline\n"); - return -EBUSY; - } - - old_opcr = opcr; - - if (get_opcr_p2p_connections(opcr)) { - if (get_opcr_channel(opcr) != channel) { - dev_err(&firesat->ud->device, - "CMP: cannot change channel\n"); - return -EBUSY; - } - dev_info(&firesat->ud->device, - "CMP: overlaying existing connection\n"); - - /* We don't allocate isochronous resources. */ - } else { - set_opcr_channel(&opcr, channel); - set_opcr_data_rate(&opcr, IEEE1394_SPEED_400); - - /* FIXME: this is for the worst case - optimize */ - set_opcr_overhead_id(&opcr, 0); - - /* FIXME: allocate isochronous channel and bandwidth at IRM */ - } - - set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) + 1); - - ret = cmp_lock(firesat, &opcr, opcr_address, old_opcr, 2); - if (ret < 0) - return ret; - - if (old_opcr != opcr) { - /* - * FIXME: if old_opcr.P2P_Connections > 0, - * deallocate isochronous channel and bandwidth at IRM - */ - - if (++attempts < 6) /* arbitrary limit */ - goto repeat; - return -EBUSY; - } - - return 0; -} - -void cmp_break_pp_connection(struct firesat *firesat, int plug, int channel) -{ - __be32 old_opcr, opcr; - u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); - int attempts = 0; - - if (cmp_read(firesat, &opcr, opcr_address, 4) < 0) - return; - -repeat: - if (!get_opcr_online(opcr) || !get_opcr_p2p_connections(opcr) || - get_opcr_channel(opcr) != channel) { - dev_err(&firesat->ud->device, "CMP: no connection to break\n"); - return; - } - - old_opcr = opcr; - set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) - 1); - - if (cmp_lock(firesat, &opcr, opcr_address, old_opcr, 2) < 0) - return; - - if (old_opcr != opcr) { - /* - * FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last - * owner, deallocate isochronous channel and bandwidth at IRM - */ - - if (++attempts < 6) /* arbitrary limit */ - goto repeat; - } -} diff --git a/drivers/media/dvb/firesat/cmp.h b/drivers/media/dvb/firesat/cmp.h deleted file mode 100644 index d92f6c7fb5d..00000000000 --- a/drivers/media/dvb/firesat/cmp.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _CMP_H -#define _CMP_H - -struct firesat; - -int cmp_establish_pp_connection(struct firesat *firesat, int plug, int channel); -void cmp_break_pp_connection(struct firesat *firesat, int plug, int channel); - -#endif /* _CMP_H */ diff --git a/drivers/media/dvb/firesat/firesat-ci.c b/drivers/media/dvb/firesat/firesat-ci.c deleted file mode 100644 index 783ed200010..00000000000 --- a/drivers/media/dvb/firesat/firesat-ci.c +++ /dev/null @@ -1,261 +0,0 @@ -/* - * FireDTV driver (formerly known as FireSAT) - * - * Copyright (C) 2004 Andreas Monitzer - * Copyright (C) 2008 Henrik Kurelid - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - */ - -#include -#include -#include - -#include - -#include "avc_api.h" -#include "firesat.h" -#include "firesat-ci.h" - -static int firesat_ca_ready(ANTENNA_INPUT_INFO *info) -{ - return info->CaInitializationStatus == 1 && - info->CaErrorFlag == 0 && - info->CaDvbFlag == 1 && - info->CaModulePresentStatus == 1; -} - -static int firesat_get_ca_flags(ANTENNA_INPUT_INFO *info) -{ - int flags = 0; - - if (info->CaModulePresentStatus == 1) - flags |= CA_CI_MODULE_PRESENT; - if (info->CaInitializationStatus == 1 && - info->CaErrorFlag == 0 && - info->CaDvbFlag == 1) - flags |= CA_CI_MODULE_READY; - return flags; -} - -static int firesat_ca_reset(struct firesat *firesat) -{ - return avc_ca_reset(firesat) ? -EFAULT : 0; -} - -static int firesat_ca_get_caps(void *arg) -{ - struct ca_caps *cap = arg; - - cap->slot_num = 1; - cap->slot_type = CA_CI; - cap->descr_num = 1; - cap->descr_type = CA_ECD; - return 0; -} - -static int firesat_ca_get_slot_info(struct firesat *firesat, void *arg) -{ - ANTENNA_INPUT_INFO info; - struct ca_slot_info *slot = arg; - - if (avc_tuner_status(firesat, &info)) - return -EFAULT; - - if (slot->num != 0) - return -EFAULT; - - slot->type = CA_CI; - slot->flags = firesat_get_ca_flags(&info); - return 0; -} - -static int firesat_ca_app_info(struct firesat *firesat, void *arg) -{ - struct ca_msg *reply = arg; - - return - avc_ca_app_info(firesat, reply->msg, &reply->length) ? -EFAULT : 0; -} - -static int firesat_ca_info(struct firesat *firesat, void *arg) -{ - struct ca_msg *reply = arg; - - return avc_ca_info(firesat, reply->msg, &reply->length) ? -EFAULT : 0; -} - -static int firesat_ca_get_mmi(struct firesat *firesat, void *arg) -{ - struct ca_msg *reply = arg; - - return - avc_ca_get_mmi(firesat, reply->msg, &reply->length) ? -EFAULT : 0; -} - -static int firesat_ca_get_msg(struct firesat *firesat, void *arg) -{ - ANTENNA_INPUT_INFO info; - int err; - - switch (firesat->ca_last_command) { - case TAG_APP_INFO_ENQUIRY: - err = firesat_ca_app_info(firesat, arg); - break; - case TAG_CA_INFO_ENQUIRY: - err = firesat_ca_info(firesat, arg); - break; - default: - if (avc_tuner_status(firesat, &info)) - err = -EFAULT; - else if (info.CaMmi == 1) - err = firesat_ca_get_mmi(firesat, arg); - else { - printk(KERN_INFO "%s: Unhandled message 0x%08X\n", - __func__, firesat->ca_last_command); - err = -EFAULT; - } - } - firesat->ca_last_command = 0; - return err; -} - -static int firesat_ca_pmt(struct firesat *firesat, void *arg) -{ - struct ca_msg *msg = arg; - int data_pos; - int data_length; - int i; - - data_pos = 4; - if (msg->msg[3] & 0x80) { - data_length = 0; - for (i = 0; i < (msg->msg[3] & 0x7F); i++) - data_length = (data_length << 8) + msg->msg[data_pos++]; - } else { - data_length = msg->msg[3]; - } - - return avc_ca_pmt(firesat, &msg->msg[data_pos], data_length) ? - -EFAULT : 0; -} - -static int firesat_ca_send_msg(struct firesat *firesat, void *arg) -{ - struct ca_msg *msg = arg; - int err; - - /* Do we need a semaphore for this? */ - firesat->ca_last_command = - (msg->msg[0] << 16) + (msg->msg[1] << 8) + msg->msg[2]; - switch (firesat->ca_last_command) { - case TAG_CA_PMT: - err = firesat_ca_pmt(firesat, arg); - break; - case TAG_APP_INFO_ENQUIRY: - /* handled in ca_get_msg */ - err = 0; - break; - case TAG_CA_INFO_ENQUIRY: - /* handled in ca_get_msg */ - err = 0; - break; - case TAG_ENTER_MENU: - err = avc_ca_enter_menu(firesat); - break; - default: - printk(KERN_ERR "%s: Unhandled unknown message 0x%08X\n", - __func__, firesat->ca_last_command); - err = -EFAULT; - } - return err; -} - -static int firesat_ca_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) -{ - struct dvb_device *dvbdev = file->private_data; - struct firesat *firesat = dvbdev->priv; - ANTENNA_INPUT_INFO info; - int err; - - switch(cmd) { - case CA_RESET: - err = firesat_ca_reset(firesat); - break; - case CA_GET_CAP: - err = firesat_ca_get_caps(arg); - break; - case CA_GET_SLOT_INFO: - err = firesat_ca_get_slot_info(firesat, arg); - break; - case CA_GET_MSG: - err = firesat_ca_get_msg(firesat, arg); - break; - case CA_SEND_MSG: - err = firesat_ca_send_msg(firesat, arg); - break; - default: - printk(KERN_INFO "%s: Unhandled ioctl, command: %u\n",__func__, - cmd); - err = -EOPNOTSUPP; - } - - /* FIXME Is this necessary? */ - avc_tuner_status(firesat, &info); - - return err; -} - -static unsigned int firesat_ca_io_poll(struct file *file, poll_table *wait) -{ - return POLLIN; -} - -static struct file_operations firesat_ca_fops = { - .owner = THIS_MODULE, - .ioctl = dvb_generic_ioctl, - .open = dvb_generic_open, - .release = dvb_generic_release, - .poll = firesat_ca_io_poll, -}; - -static struct dvb_device firesat_ca = { - .users = 1, - .readers = 1, - .writers = 1, - .fops = &firesat_ca_fops, - .kernel_ioctl = firesat_ca_ioctl, -}; - -int firesat_ca_register(struct firesat *firesat) -{ - ANTENNA_INPUT_INFO info; - int err; - - if (avc_tuner_status(firesat, &info)) - return -EINVAL; - - if (!firesat_ca_ready(&info)) - return -EFAULT; - - err = dvb_register_device(&firesat->adapter, &firesat->cadev, - &firesat_ca, firesat, DVB_DEVICE_CA); - - if (info.CaApplicationInfo == 0) - printk(KERN_ERR "%s: CaApplicationInfo is not set.\n", - __func__); - if (info.CaDateTimeRequest == 1) - avc_ca_get_time_date(firesat, &firesat->ca_time_interval); - - return err; -} - -void firesat_ca_release(struct firesat *firesat) -{ - if (firesat->cadev) - dvb_unregister_device(firesat->cadev); -} diff --git a/drivers/media/dvb/firesat/firesat-ci.h b/drivers/media/dvb/firesat/firesat-ci.h deleted file mode 100644 index 9c68cd2246a..00000000000 --- a/drivers/media/dvb/firesat/firesat-ci.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _FIREDTV_CI_H -#define _FIREDTV_CI_H - -struct firesat; - -int firesat_ca_register(struct firesat *firesat); -void firesat_ca_release(struct firesat *firesat); - -#endif /* _FIREDTV_CI_H */ diff --git a/drivers/media/dvb/firesat/firesat-rc.c b/drivers/media/dvb/firesat/firesat-rc.c deleted file mode 100644 index 5f9de142ee3..00000000000 --- a/drivers/media/dvb/firesat/firesat-rc.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * FireDTV driver (formerly known as FireSAT) - * - * Copyright (C) 2004 Andreas Monitzer - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - */ - -#include -#include -#include -#include -#include - -#include "firesat-rc.h" -#include "firesat.h" - -/* fixed table with older keycodes, geared towards MythTV */ -const static u16 oldtable[] = { - - /* code from device: 0x4501...0x451f */ - - KEY_ESC, - KEY_F9, - KEY_1, - KEY_2, - KEY_3, - KEY_4, - KEY_5, - KEY_6, - KEY_7, - KEY_8, - KEY_9, - KEY_I, - KEY_0, - KEY_ENTER, - KEY_RED, - KEY_UP, - KEY_GREEN, - KEY_F10, - KEY_SPACE, - KEY_F11, - KEY_YELLOW, - KEY_DOWN, - KEY_BLUE, - KEY_Z, - KEY_P, - KEY_PAGEDOWN, - KEY_LEFT, - KEY_W, - KEY_RIGHT, - KEY_P, - KEY_M, - - /* code from device: 0x4540...0x4542 */ - - KEY_R, - KEY_V, - KEY_C, -}; - -/* user-modifiable table for a remote as sold in 2008 */ -const static u16 keytable[] = { - - /* code from device: 0x0300...0x031f */ - - [0x00] = KEY_POWER, - [0x01] = KEY_SLEEP, - [0x02] = KEY_STOP, - [0x03] = KEY_OK, - [0x04] = KEY_RIGHT, - [0x05] = KEY_1, - [0x06] = KEY_2, - [0x07] = KEY_3, - [0x08] = KEY_LEFT, - [0x09] = KEY_4, - [0x0a] = KEY_5, - [0x0b] = KEY_6, - [0x0c] = KEY_UP, - [0x0d] = KEY_7, - [0x0e] = KEY_8, - [0x0f] = KEY_9, - [0x10] = KEY_DOWN, - [0x11] = KEY_TITLE, /* "OSD" - fixme */ - [0x12] = KEY_0, - [0x13] = KEY_F20, /* "16:9" - fixme */ - [0x14] = KEY_SCREEN, /* "FULL" - fixme */ - [0x15] = KEY_MUTE, - [0x16] = KEY_SUBTITLE, - [0x17] = KEY_RECORD, - [0x18] = KEY_TEXT, - [0x19] = KEY_AUDIO, - [0x1a] = KEY_RED, - [0x1b] = KEY_PREVIOUS, - [0x1c] = KEY_REWIND, - [0x1d] = KEY_PLAYPAUSE, - [0x1e] = KEY_NEXT, - [0x1f] = KEY_VOLUMEUP, - - /* code from device: 0x0340...0x0354 */ - - [0x20] = KEY_CHANNELUP, - [0x21] = KEY_F21, /* "4:3" - fixme */ - [0x22] = KEY_TV, - [0x23] = KEY_DVD, - [0x24] = KEY_VCR, - [0x25] = KEY_AUX, - [0x26] = KEY_GREEN, - [0x27] = KEY_YELLOW, - [0x28] = KEY_BLUE, - [0x29] = KEY_CHANNEL, /* "CH.LIST" */ - [0x2a] = KEY_VENDOR, /* "CI" - fixme */ - [0x2b] = KEY_VOLUMEDOWN, - [0x2c] = KEY_CHANNELDOWN, - [0x2d] = KEY_LAST, - [0x2e] = KEY_INFO, - [0x2f] = KEY_FORWARD, - [0x30] = KEY_LIST, - [0x31] = KEY_FAVORITES, - [0x32] = KEY_MENU, - [0x33] = KEY_EPG, - [0x34] = KEY_EXIT, -}; - -int firesat_register_rc(struct firesat *firesat, struct device *dev) -{ - struct input_dev *idev; - int i, err; - - idev = input_allocate_device(); - if (!idev) - return -ENOMEM; - - firesat->remote_ctrl_dev = idev; - idev->name = "FireDTV remote control"; - idev->dev.parent = dev; - idev->evbit[0] = BIT_MASK(EV_KEY); - idev->keycode = kmemdup(keytable, sizeof(keytable), GFP_KERNEL); - if (!idev->keycode) { - err = -ENOMEM; - goto fail; - } - idev->keycodesize = sizeof(keytable[0]); - idev->keycodemax = ARRAY_SIZE(keytable); - - for (i = 0; i < ARRAY_SIZE(keytable); i++) - set_bit(keytable[i], idev->keybit); - - err = input_register_device(idev); - if (err) - goto fail_free_keymap; - - return 0; - -fail_free_keymap: - kfree(idev->keycode); -fail: - input_free_device(idev); - return err; -} - -void firesat_unregister_rc(struct firesat *firesat) -{ - kfree(firesat->remote_ctrl_dev->keycode); - input_unregister_device(firesat->remote_ctrl_dev); -} - -void firesat_handle_rc(struct firesat *firesat, unsigned int code) -{ - u16 *keycode = firesat->remote_ctrl_dev->keycode; - - if (code >= 0x0300 && code <= 0x031f) - code = keycode[code - 0x0300]; - else if (code >= 0x0340 && code <= 0x0354) - code = keycode[code - 0x0320]; - else if (code >= 0x4501 && code <= 0x451f) - code = oldtable[code - 0x4501]; - else if (code >= 0x4540 && code <= 0x4542) - code = oldtable[code - 0x4521]; - else { - printk(KERN_DEBUG "firedtv: invalid key code 0x%04x " - "from remote control\n", code); - return; - } - - input_report_key(firesat->remote_ctrl_dev, code, 1); - input_report_key(firesat->remote_ctrl_dev, code, 0); -} diff --git a/drivers/media/dvb/firesat/firesat-rc.h b/drivers/media/dvb/firesat/firesat-rc.h deleted file mode 100644 index 12c1c5c28b3..00000000000 --- a/drivers/media/dvb/firesat/firesat-rc.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _FIREDTV_RC_H -#define _FIREDTV_RC_H - -struct firesat; -struct device; - -int firesat_register_rc(struct firesat *firesat, struct device *dev); -void firesat_unregister_rc(struct firesat *firesat); -void firesat_handle_rc(struct firesat *firesat, unsigned int code); - -#endif /* _FIREDTV_RC_H */ diff --git a/drivers/media/dvb/firesat/firesat.h b/drivers/media/dvb/firesat/firesat.h deleted file mode 100644 index 51f64c0afcd..00000000000 --- a/drivers/media/dvb/firesat/firesat.h +++ /dev/null @@ -1,227 +0,0 @@ -/* - * FireDTV driver (formerly known as FireSAT) - * - * Copyright (C) 2004 Andreas Monitzer - * Copyright (C) 2008 Henrik Kurelid - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - */ - -#ifndef _FIREDTV_H -#define _FIREDTV_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25) -#define DVB_REGISTER_ADAPTER(x, y, z, w, v) dvb_register_adapter(x, y, z, w, v) -#else -#define DVB_REGISTER_ADAPTER(x, y, z, w, v) dvb_register_adapter(x, y, z, w) -#define DVB_DEFINE_MOD_OPT_ADAPTER_NR(x) -#endif - -/***************************************************************** - * CA message command constants from en50221_app_tags.h of libdvb - *****************************************************************/ -/* Resource Manager */ -#define TAG_PROFILE_ENQUIRY 0x9f8010 -#define TAG_PROFILE 0x9f8011 -#define TAG_PROFILE_CHANGE 0x9f8012 - -/* Application Info */ -#define TAG_APP_INFO_ENQUIRY 0x9f8020 -#define TAG_APP_INFO 0x9f8021 -#define TAG_ENTER_MENU 0x9f8022 - -/* CA Support */ -#define TAG_CA_INFO_ENQUIRY 0x9f8030 -#define TAG_CA_INFO 0x9f8031 -#define TAG_CA_PMT 0x9f8032 -#define TAG_CA_PMT_REPLY 0x9f8033 - -/* Host Control */ -#define TAG_TUNE 0x9f8400 -#define TAG_REPLACE 0x9f8401 -#define TAG_CLEAR_REPLACE 0x9f8402 -#define TAG_ASK_RELEASE 0x9f8403 - -/* Date and Time */ -#define TAG_DATE_TIME_ENQUIRY 0x9f8440 -#define TAG_DATE_TIME 0x9f8441 - -/* Man Machine Interface (MMI) */ -#define TAG_CLOSE_MMI 0x9f8800 -#define TAG_DISPLAY_CONTROL 0x9f8801 -#define TAG_DISPLAY_REPLY 0x9f8802 -#define TAG_TEXT_LAST 0x9f8803 -#define TAG_TEXT_MORE 0x9f8804 -#define TAG_KEYPAD_CONTROL 0x9f8805 -#define TAG_KEYPRESS 0x9f8806 -#define TAG_ENQUIRY 0x9f8807 -#define TAG_ANSWER 0x9f8808 -#define TAG_MENU_LAST 0x9f8809 -#define TAG_MENU_MORE 0x9f880a -#define TAG_MENU_ANSWER 0x9f880b -#define TAG_LIST_LAST 0x9f880c -#define TAG_LIST_MORE 0x9f880d -#define TAG_SUBTITLE_SEGMENT_LAST 0x9f880e -#define TAG_SUBTITLE_SEGMENT_MORE 0x9f880f -#define TAG_DISPLAY_MESSAGE 0x9f8810 -#define TAG_SCENE_END_MARK 0x9f8811 -#define TAG_SCENE_DONE 0x9f8812 -#define TAG_SCENE_CONTROL 0x9f8813 -#define TAG_SUBTITLE_DOWNLOAD_LAST 0x9f8814 -#define TAG_SUBTITLE_DOWNLOAD_MORE 0x9f8815 -#define TAG_FLUSH_DOWNLOAD 0x9f8816 -#define TAG_DOWNLOAD_REPLY 0x9f8817 - -/* Low Speed Communications */ -#define TAG_COMMS_COMMAND 0x9f8c00 -#define TAG_CONNECTION_DESCRIPTOR 0x9f8c01 -#define TAG_COMMS_REPLY 0x9f8c02 -#define TAG_COMMS_SEND_LAST 0x9f8c03 -#define TAG_COMMS_SEND_MORE 0x9f8c04 -#define TAG_COMMS_RECV_LAST 0x9f8c05 -#define TAG_COMMS_RECV_MORE 0x9f8c06 - -/* Authentication */ -#define TAG_AUTH_REQ 0x9f8200 -#define TAG_AUTH_RESP 0x9f8201 - -/* Teletext */ -#define TAG_TELETEXT_EBU 0x9f9000 - -/* Smartcard */ -#define TAG_SMARTCARD_COMMAND 0x9f8e00 -#define TAG_SMARTCARD_REPLY 0x9f8e01 -#define TAG_SMARTCARD_SEND 0x9f8e02 -#define TAG_SMARTCARD_RCV 0x9f8e03 - -/* EPG */ -#define TAG_EPG_ENQUIRY 0x9f8f00 -#define TAG_EPG_REPLY 0x9f8f01 - - -enum model_type { - FireSAT_UNKNOWN = 0, - FireSAT_DVB_S = 1, - FireSAT_DVB_C = 2, - FireSAT_DVB_T = 3, - FireSAT_DVB_S2 = 4, -}; - -struct input_dev; -struct hpsb_iso; -struct unit_directory; - -struct firesat { - struct dvb_adapter adapter; - struct dmxdev dmxdev; - struct dvb_demux demux; - struct dmx_frontend frontend; - struct dvb_net dvbnet; - struct dvb_frontend fe; - - struct dvb_device *cadev; - int ca_last_command; - int ca_time_interval; - - struct mutex avc_mutex; - wait_queue_head_t avc_wait; - bool avc_reply_received; - struct work_struct remote_ctrl_work; - struct input_dev *remote_ctrl_dev; - - struct firesat_channel { - bool active; - int pid; - } channel[16]; - struct mutex demux_mutex; - - struct unit_directory *ud; - - enum model_type type; - char subunit; - fe_sec_voltage_t voltage; - fe_sec_tone_mode_t tone; - - int isochannel; - struct hpsb_iso *iso_handle; - - struct list_head list; - - /* needed by avc_api */ - int resp_length; - u8 respfrm[512]; -}; - -struct firewireheader { - union { - struct { - __u8 tcode:4; - __u8 sy:4; - __u8 tag:2; - __u8 channel:6; - - __u8 length_l; - __u8 length_h; - } hdr; - __u32 val; - }; -}; - -struct CIPHeader { - union { - struct { - __u8 syncbits:2; - __u8 sid:6; - __u8 dbs; - __u8 fn:2; - __u8 qpc:3; - __u8 sph:1; - __u8 rsv:2; - __u8 dbc; - __u8 syncbits2:2; - __u8 fmt:6; - __u32 fdf:24; - } cip; - __u64 val; - }; -}; - -extern const char *firedtv_model_names[]; -extern struct list_head firesat_list; -extern spinlock_t firesat_list_lock; - -struct device; - -/* firesat_dvb.c */ -int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed); -int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed); -int firesat_dvbdev_init(struct firesat *firesat, struct device *dev); - -/* firesat_fe.c */ -void firesat_frontend_init(struct firesat *firesat); - -/* firesat_iso.c */ -int setup_iso_channel(struct firesat *firesat); -void tear_down_iso_channel(struct firesat *firesat); - -#endif /* _FIREDTV_H */ diff --git a/drivers/media/dvb/firesat/firesat_1394.c b/drivers/media/dvb/firesat/firesat_1394.c deleted file mode 100644 index 11db6273025..00000000000 --- a/drivers/media/dvb/firesat/firesat_1394.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - * FireDTV driver (formerly known as FireSAT) - * - * Copyright (C) 2004 Andreas Monitzer - * Copyright (C) 2007-2008 Ben Backx - * Copyright (C) 2008 Henrik Kurelid - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "avc_api.h" -#include "cmp.h" -#include "firesat.h" -#include "firesat-ci.h" -#include "firesat-rc.h" - -#define MATCH_FLAGS IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \ - IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION -#define DIGITAL_EVERYWHERE_OUI 0x001287 - -static struct ieee1394_device_id firesat_id_table[] = { - - { - /* FloppyDTV S/CI and FloppyDTV S2 */ - .match_flags = MATCH_FLAGS, - .vendor_id = DIGITAL_EVERYWHERE_OUI, - .model_id = 0x000024, - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, - .version = AVC_SW_VERSION_ENTRY, - },{ - /* FloppyDTV T/CI */ - .match_flags = MATCH_FLAGS, - .vendor_id = DIGITAL_EVERYWHERE_OUI, - .model_id = 0x000025, - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, - .version = AVC_SW_VERSION_ENTRY, - },{ - /* FloppyDTV C/CI */ - .match_flags = MATCH_FLAGS, - .vendor_id = DIGITAL_EVERYWHERE_OUI, - .model_id = 0x000026, - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, - .version = AVC_SW_VERSION_ENTRY, - },{ - /* FireDTV S/CI and FloppyDTV S2 */ - .match_flags = MATCH_FLAGS, - .vendor_id = DIGITAL_EVERYWHERE_OUI, - .model_id = 0x000034, - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, - .version = AVC_SW_VERSION_ENTRY, - },{ - /* FireDTV T/CI */ - .match_flags = MATCH_FLAGS, - .vendor_id = DIGITAL_EVERYWHERE_OUI, - .model_id = 0x000035, - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, - .version = AVC_SW_VERSION_ENTRY, - },{ - /* FireDTV C/CI */ - .match_flags = MATCH_FLAGS, - .vendor_id = DIGITAL_EVERYWHERE_OUI, - .model_id = 0x000036, - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, - .version = AVC_SW_VERSION_ENTRY, - }, { } -}; - -MODULE_DEVICE_TABLE(ieee1394, firesat_id_table); - -/* list of all firesat devices */ -LIST_HEAD(firesat_list); -DEFINE_SPINLOCK(firesat_list_lock); - -static void fcp_request(struct hpsb_host *host, - int nodeid, - int direction, - int cts, - u8 *data, - size_t length) -{ - struct firesat *firesat = NULL; - struct firesat *firesat_entry; - unsigned long flags; - - if (length > 0 && ((data[0] & 0xf0) >> 4) == 0) { - - spin_lock_irqsave(&firesat_list_lock, flags); - list_for_each_entry(firesat_entry,&firesat_list,list) { - if (firesat_entry->ud->ne->host == host && - firesat_entry->ud->ne->nodeid == nodeid && - (firesat_entry->subunit == (data[1]&0x7) || - (firesat_entry->subunit == 0 && - (data[1]&0x7) == 0x7))) { - firesat=firesat_entry; - break; - } - } - spin_unlock_irqrestore(&firesat_list_lock, flags); - - if (firesat) - avc_recv(firesat, data, length); - } -} - -const char *firedtv_model_names[] = { - [FireSAT_UNKNOWN] = "unknown type", - [FireSAT_DVB_S] = "FireDTV S/CI", - [FireSAT_DVB_C] = "FireDTV C/CI", - [FireSAT_DVB_T] = "FireDTV T/CI", - [FireSAT_DVB_S2] = "FireDTV S2 ", -}; - -static int firesat_probe(struct device *dev) -{ - struct unit_directory *ud = - container_of(dev, struct unit_directory, device); - struct firesat *firesat; - unsigned long flags; - int kv_len; - void *kv_str; - int i; - int err = -ENOMEM; - - firesat = kzalloc(sizeof(*firesat), GFP_KERNEL); - if (!firesat) - return -ENOMEM; - - dev->driver_data = firesat; - firesat->ud = ud; - firesat->subunit = 0; - firesat->isochannel = -1; - firesat->tone = 0xff; - firesat->voltage = 0xff; - - mutex_init(&firesat->avc_mutex); - init_waitqueue_head(&firesat->avc_wait); - firesat->avc_reply_received = true; - mutex_init(&firesat->demux_mutex); - INIT_WORK(&firesat->remote_ctrl_work, avc_remote_ctrl_work); - - /* Reading device model from ROM */ - kv_len = (ud->model_name_kv->value.leaf.len - 2) * sizeof(quadlet_t); - kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv); - for (i = ARRAY_SIZE(firedtv_model_names); --i;) - if (strlen(firedtv_model_names[i]) <= kv_len && - strncmp(kv_str, firedtv_model_names[i], kv_len) == 0) - break; - firesat->type = i; - - /* - * Work around a bug in udev's path_id script: Use the fw-host's dev - * instead of the unit directory's dev as parent of the input device. - */ - err = firesat_register_rc(firesat, dev->parent->parent); - if (err) - goto fail_free; - - INIT_LIST_HEAD(&firesat->list); - spin_lock_irqsave(&firesat_list_lock, flags); - list_add_tail(&firesat->list, &firesat_list); - spin_unlock_irqrestore(&firesat_list_lock, flags); - - err = avc_identify_subunit(firesat); - if (err) - goto fail; - - err = firesat_dvbdev_init(firesat, dev); - if (err) - goto fail; - - avc_register_remote_control(firesat); - return 0; - -fail: - spin_lock_irqsave(&firesat_list_lock, flags); - list_del(&firesat->list); - spin_unlock_irqrestore(&firesat_list_lock, flags); - firesat_unregister_rc(firesat); -fail_free: - kfree(firesat); - return err; -} - -static int firesat_remove(struct device *dev) -{ - struct firesat *firesat = dev->driver_data; - unsigned long flags; - - firesat_ca_release(firesat); - dvb_unregister_frontend(&firesat->fe); - dvb_net_release(&firesat->dvbnet); - firesat->demux.dmx.close(&firesat->demux.dmx); - firesat->demux.dmx.remove_frontend(&firesat->demux.dmx, - &firesat->frontend); - dvb_dmxdev_release(&firesat->dmxdev); - dvb_dmx_release(&firesat->demux); - dvb_unregister_adapter(&firesat->adapter); - - spin_lock_irqsave(&firesat_list_lock, flags); - list_del(&firesat->list); - spin_unlock_irqrestore(&firesat_list_lock, flags); - - cancel_work_sync(&firesat->remote_ctrl_work); - firesat_unregister_rc(firesat); - - kfree(firesat); - return 0; -} - -static int firesat_update(struct unit_directory *ud) -{ - struct firesat *firesat = ud->device.driver_data; - - if (firesat->isochannel >= 0) - cmp_establish_pp_connection(firesat, firesat->subunit, - firesat->isochannel); - return 0; -} - -static struct hpsb_protocol_driver firesat_driver = { - - .name = "firedtv", - .id_table = firesat_id_table, - .update = firesat_update, - - .driver = { - //.name and .bus are filled in for us in more recent linux versions - //.name = "FireSAT", - //.bus = &ieee1394_bus_type, - .probe = firesat_probe, - .remove = firesat_remove, - }, -}; - -static struct hpsb_highlevel firesat_highlevel = { - .name = "firedtv", - .fcp_request = fcp_request, -}; - -static int __init firesat_init(void) -{ - int ret; - - hpsb_register_highlevel(&firesat_highlevel); - ret = hpsb_register_protocol(&firesat_driver); - if (ret) { - printk(KERN_ERR "firedtv: failed to register protocol\n"); - hpsb_unregister_highlevel(&firesat_highlevel); - } - return ret; -} - -static void __exit firesat_exit(void) -{ - hpsb_unregister_protocol(&firesat_driver); - hpsb_unregister_highlevel(&firesat_highlevel); -} - -module_init(firesat_init); -module_exit(firesat_exit); - -MODULE_AUTHOR("Andreas Monitzer "); -MODULE_AUTHOR("Ben Backx "); -MODULE_DESCRIPTION("FireDTV DVB Driver"); -MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("FireDTV DVB"); diff --git a/drivers/media/dvb/firesat/firesat_dvb.c b/drivers/media/dvb/firesat/firesat_dvb.c deleted file mode 100644 index cb36c031019..00000000000 --- a/drivers/media/dvb/firesat/firesat_dvb.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * FireDTV driver (formerly known as FireSAT) - * - * Copyright (C) 2004 Andreas Monitzer - * Copyright (C) 2008 Henrik Kurelid - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - */ - -#include -#include -#include -#include - -#include -#include -#include - -#include "avc_api.h" -#include "firesat.h" -#include "firesat-ci.h" - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -static struct firesat_channel *firesat_channel_allocate(struct firesat *firesat) -{ - struct firesat_channel *c = NULL; - int k; - - if (mutex_lock_interruptible(&firesat->demux_mutex)) - return NULL; - - for (k = 0; k < 16; k++) - if (!firesat->channel[k].active) { - firesat->channel[k].active = true; - c = &firesat->channel[k]; - break; - } - - mutex_unlock(&firesat->demux_mutex); - return c; -} - -static int firesat_channel_collect(struct firesat *firesat, int *pidc, u16 pid[]) -{ - int k, l = 0; - - if (mutex_lock_interruptible(&firesat->demux_mutex)) - return -EINTR; - - for (k = 0; k < 16; k++) - if (firesat->channel[k].active) - pid[l++] = firesat->channel[k].pid; - - mutex_unlock(&firesat->demux_mutex); - - *pidc = l; - - return 0; -} - -static int firesat_channel_release(struct firesat *firesat, - struct firesat_channel *channel) -{ - if (mutex_lock_interruptible(&firesat->demux_mutex)) - return -EINTR; - - channel->active = false; - - mutex_unlock(&firesat->demux_mutex); - return 0; -} - -int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed) -{ - struct firesat *firesat = (struct firesat*)dvbdmxfeed->demux->priv; - struct firesat_channel *channel; - int pidc,k; - u16 pids[16]; - - switch (dvbdmxfeed->type) { - case DMX_TYPE_TS: - case DMX_TYPE_SEC: - break; - default: - printk(KERN_ERR "%s: invalid type %u\n", - __func__, dvbdmxfeed->type); - return -EINVAL; - } - - if (dvbdmxfeed->type == DMX_TYPE_TS) { - switch (dvbdmxfeed->pes_type) { - case DMX_TS_PES_VIDEO: - case DMX_TS_PES_AUDIO: - case DMX_TS_PES_TELETEXT: - case DMX_TS_PES_PCR: - case DMX_TS_PES_OTHER: - //Dirty fix to keep firesat->channel pid-list up to date - for(k=0;k<16;k++){ - if (!firesat->channel[k].active) - firesat->channel[k].pid = - dvbdmxfeed->pid; - break; - } - channel = firesat_channel_allocate(firesat); - break; - default: - printk(KERN_ERR "%s: invalid pes type %u\n", - __func__, dvbdmxfeed->pes_type); - return -EINVAL; - } - } else { - channel = firesat_channel_allocate(firesat); - } - - if (!channel) { - printk(KERN_ERR "%s: busy!\n", __func__); - return -EBUSY; - } - - dvbdmxfeed->priv = channel; - channel->pid = dvbdmxfeed->pid; - - if (firesat_channel_collect(firesat, &pidc, pids)) { - firesat_channel_release(firesat, channel); - printk(KERN_ERR "%s: could not collect pids!\n", __func__); - return -EINTR; - } - - if (dvbdmxfeed->pid == 8192) { - k = avc_tuner_get_ts(firesat); - if (k) { - firesat_channel_release(firesat, channel); - printk("%s: AVCTuner_GetTS failed with error %d\n", - __func__, k); - return k; - } - } else { - k = avc_tuner_set_pids(firesat, pidc, pids); - if (k) { - firesat_channel_release(firesat, channel); - printk("%s: AVCTuner_SetPIDs failed with error %d\n", - __func__, k); - return k; - } - } - - return 0; -} - -int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed) -{ - struct dvb_demux *demux = dvbdmxfeed->demux; - struct firesat *firesat = (struct firesat*)demux->priv; - struct firesat_channel *c = dvbdmxfeed->priv; - int k, l; - u16 pids[16]; - - if (dvbdmxfeed->type == DMX_TYPE_TS && !((dvbdmxfeed->ts_type & TS_PACKET) && - (demux->dmx.frontend->source != DMX_MEMORY_FE))) { - - if (dvbdmxfeed->ts_type & TS_DECODER) { - - if (dvbdmxfeed->pes_type >= DMX_TS_PES_OTHER || - !demux->pesfilter[dvbdmxfeed->pes_type]) - - return -EINVAL; - - demux->pids[dvbdmxfeed->pes_type] |= 0x8000; - demux->pesfilter[dvbdmxfeed->pes_type] = NULL; - } - - if (!(dvbdmxfeed->ts_type & TS_DECODER && - dvbdmxfeed->pes_type < DMX_TS_PES_OTHER)) - - return 0; - } - - if (mutex_lock_interruptible(&firesat->demux_mutex)) - return -EINTR; - - /* list except channel to be removed */ - for (k = 0, l = 0; k < 16; k++) - if (firesat->channel[k].active) { - if (&firesat->channel[k] != c) - pids[l++] = firesat->channel[k].pid; - else - firesat->channel[k].active = false; - } - - k = avc_tuner_set_pids(firesat, l, pids); - if (!k) - c->active = false; - - mutex_unlock(&firesat->demux_mutex); - return k; -} - -int firesat_dvbdev_init(struct firesat *firesat, struct device *dev) -{ - int err; - - err = DVB_REGISTER_ADAPTER(&firesat->adapter, - firedtv_model_names[firesat->type], - THIS_MODULE, dev, adapter_nr); - if (err < 0) - goto fail_log; - - /*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/ - firesat->demux.dmx.capabilities = 0; - - firesat->demux.priv = (void *)firesat; - firesat->demux.filternum = 16; - firesat->demux.feednum = 16; - firesat->demux.start_feed = firesat_start_feed; - firesat->demux.stop_feed = firesat_stop_feed; - firesat->demux.write_to_decoder = NULL; - - err = dvb_dmx_init(&firesat->demux); - if (err) - goto fail_unreg_adapter; - - firesat->dmxdev.filternum = 16; - firesat->dmxdev.demux = &firesat->demux.dmx; - firesat->dmxdev.capabilities = 0; - - err = dvb_dmxdev_init(&firesat->dmxdev, &firesat->adapter); - if (err) - goto fail_dmx_release; - - firesat->frontend.source = DMX_FRONTEND_0; - - err = firesat->demux.dmx.add_frontend(&firesat->demux.dmx, - &firesat->frontend); - if (err) - goto fail_dmxdev_release; - - err = firesat->demux.dmx.connect_frontend(&firesat->demux.dmx, - &firesat->frontend); - if (err) - goto fail_rem_frontend; - - dvb_net_init(&firesat->adapter, &firesat->dvbnet, &firesat->demux.dmx); - - firesat_frontend_init(firesat); - err = dvb_register_frontend(&firesat->adapter, &firesat->fe); - if (err) - goto fail_net_release; - - err = firesat_ca_register(firesat); - if (err) - dev_info(dev, "Conditional Access Module not enabled\n"); - - return 0; - -fail_net_release: - dvb_net_release(&firesat->dvbnet); - firesat->demux.dmx.close(&firesat->demux.dmx); -fail_rem_frontend: - firesat->demux.dmx.remove_frontend(&firesat->demux.dmx, - &firesat->frontend); -fail_dmxdev_release: - dvb_dmxdev_release(&firesat->dmxdev); -fail_dmx_release: - dvb_dmx_release(&firesat->demux); -fail_unreg_adapter: - dvb_unregister_adapter(&firesat->adapter); -fail_log: - dev_err(dev, "DVB initialization failed\n"); - return err; -} - - diff --git a/drivers/media/dvb/firesat/firesat_fe.c b/drivers/media/dvb/firesat/firesat_fe.c deleted file mode 100644 index 1ed972b7957..00000000000 --- a/drivers/media/dvb/firesat/firesat_fe.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * FireDTV driver (formerly known as FireSAT) - * - * Copyright (C) 2004 Andreas Monitzer - * Copyright (C) 2008 Henrik Kurelid - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - */ - -#include -#include -#include -#include - -#include - -#include "avc_api.h" -#include "cmp.h" -#include "firesat.h" - -static int firesat_dvb_init(struct dvb_frontend *fe) -{ - struct firesat *firesat = fe->sec_priv; - int err; - - /* FIXME - allocate free channel at IRM */ - firesat->isochannel = firesat->adapter.num; - - err = cmp_establish_pp_connection(firesat, firesat->subunit, - firesat->isochannel); - if (err) { - printk(KERN_ERR "Could not establish point to point " - "connection.\n"); - return err; - } - - return setup_iso_channel(firesat); -} - -static int firesat_sleep(struct dvb_frontend *fe) -{ - struct firesat *firesat = fe->sec_priv; - - tear_down_iso_channel(firesat); - cmp_break_pp_connection(firesat, firesat->subunit, firesat->isochannel); - firesat->isochannel = -1; - return 0; -} - -static int firesat_diseqc_send_master_cmd(struct dvb_frontend *fe, - struct dvb_diseqc_master_cmd *cmd) -{ - struct firesat *firesat = fe->sec_priv; - - return avc_lnb_control(firesat, LNBCONTROL_DONTCARE, - LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, 1, cmd); -} - -static int firesat_diseqc_send_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t minicmd) -{ - return 0; -} - -static int firesat_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) -{ - struct firesat *firesat = fe->sec_priv; - - firesat->tone = tone; - return 0; -} - -static int firesat_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) -{ - struct firesat *firesat = fe->sec_priv; - - firesat->voltage = voltage; - return 0; -} - -static int firesat_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct firesat *firesat = fe->sec_priv; - ANTENNA_INPUT_INFO info; - - if (avc_tuner_status(firesat, &info)) - return -EINVAL; - - if (info.NoRF) - *status = 0; - else - *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | FE_HAS_SYNC | - FE_HAS_CARRIER | FE_HAS_LOCK; - return 0; -} - -static int firesat_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct firesat *firesat = fe->sec_priv; - ANTENNA_INPUT_INFO info; - - if (avc_tuner_status(firesat, &info)) - return -EINVAL; - - *ber = info.BER[0] << 24 | info.BER[1] << 16 | - info.BER[2] << 8 | info.BER[3]; - return 0; -} - -static int firesat_read_signal_strength (struct dvb_frontend *fe, u16 *strength) -{ - struct firesat *firesat = fe->sec_priv; - ANTENNA_INPUT_INFO info; - - if (avc_tuner_status(firesat, &info)) - return -EINVAL; - - *strength = info.SignalStrength << 8; - return 0; -} - -static int firesat_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct firesat *firesat = fe->sec_priv; - ANTENNA_INPUT_INFO info; - - if (avc_tuner_status(firesat, &info)) - return -EINVAL; - - /* C/N[dB] = -10 * log10(snr / 65535) */ - *snr = (info.CarrierNoiseRatio[0] << 8) + info.CarrierNoiseRatio[1]; - *snr *= 257; - return 0; -} - -static int firesat_read_uncorrected_blocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - return -EOPNOTSUPP; -} - -static int firesat_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - struct firesat *firesat = fe->sec_priv; - - /* FIXME: avc_tuner_dsd never returns ACCEPTED. Check status? */ - if (avc_tuner_dsd(firesat, params) != ACCEPTED) - return -EINVAL; - else - return 0; /* not sure of this... */ -} - -static int firesat_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - return -EOPNOTSUPP; -} - -void firesat_frontend_init(struct firesat *firesat) -{ - struct dvb_frontend_ops *ops = &firesat->fe.ops; - struct dvb_frontend_info *fi = &ops->info; - - ops->init = firesat_dvb_init; - ops->sleep = firesat_sleep; - - ops->set_frontend = firesat_set_frontend; - ops->get_frontend = firesat_get_frontend; - - ops->read_status = firesat_read_status; - ops->read_ber = firesat_read_ber; - ops->read_signal_strength = firesat_read_signal_strength; - ops->read_snr = firesat_read_snr; - ops->read_ucblocks = firesat_read_uncorrected_blocks; - - ops->diseqc_send_master_cmd = firesat_diseqc_send_master_cmd; - ops->diseqc_send_burst = firesat_diseqc_send_burst; - ops->set_tone = firesat_set_tone; - ops->set_voltage = firesat_set_voltage; - - switch (firesat->type) { - case FireSAT_DVB_S: - fi->type = FE_QPSK; - - fi->frequency_min = 950000; - fi->frequency_max = 2150000; - fi->frequency_stepsize = 125; - fi->symbol_rate_min = 1000000; - fi->symbol_rate_max = 40000000; - - fi->caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | - FE_CAN_FEC_2_3 | - FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | - FE_CAN_FEC_7_8 | - FE_CAN_FEC_AUTO | - FE_CAN_QPSK; - break; - - case FireSAT_DVB_C: - fi->type = FE_QAM; - - fi->frequency_min = 47000000; - fi->frequency_max = 866000000; - fi->frequency_stepsize = 62500; - fi->symbol_rate_min = 870000; - fi->symbol_rate_max = 6900000; - - fi->caps = FE_CAN_INVERSION_AUTO | - FE_CAN_QAM_16 | - FE_CAN_QAM_32 | - FE_CAN_QAM_64 | - FE_CAN_QAM_128 | - FE_CAN_QAM_256 | - FE_CAN_QAM_AUTO; - break; - - case FireSAT_DVB_T: - fi->type = FE_OFDM; - - fi->frequency_min = 49000000; - fi->frequency_max = 861000000; - fi->frequency_stepsize = 62500; - - fi->caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_2_3 | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO; - break; - - default: - printk(KERN_ERR "FireDTV: no frontend for model type %d\n", - firesat->type); - } - strcpy(fi->name, firedtv_model_names[firesat->type]); - - firesat->fe.dvb = &firesat->adapter; - firesat->fe.sec_priv = firesat; -} diff --git a/drivers/media/dvb/firesat/firesat_iso.c b/drivers/media/dvb/firesat/firesat_iso.c deleted file mode 100644 index b3c61f95fa9..00000000000 --- a/drivers/media/dvb/firesat/firesat_iso.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * FireSAT DVB driver - * - * Copyright (C) 2008 Henrik Kurelid - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - */ - -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include "firesat.h" - -static void rawiso_activity_cb(struct hpsb_iso *iso); - -void tear_down_iso_channel(struct firesat *firesat) -{ - if (firesat->iso_handle != NULL) { - hpsb_iso_stop(firesat->iso_handle); - hpsb_iso_shutdown(firesat->iso_handle); - } - firesat->iso_handle = NULL; -} - -int setup_iso_channel(struct firesat *firesat) -{ - int result; - firesat->iso_handle = - hpsb_iso_recv_init(firesat->ud->ne->host, - 256 * 200, //data_buf_size, - 256, //buf_packets, - firesat->isochannel, - HPSB_ISO_DMA_DEFAULT, //dma_mode, - -1, //stat.config.irq_interval, - rawiso_activity_cb); - if (firesat->iso_handle == NULL) { - printk(KERN_ERR "Cannot initialize iso receive.\n"); - return -EINVAL; - } - result = hpsb_iso_recv_start(firesat->iso_handle, -1, -1, 0); - if (result != 0) { - printk(KERN_ERR "Cannot start iso receive.\n"); - return -EINVAL; - } - return 0; -} - -static void rawiso_activity_cb(struct hpsb_iso *iso) -{ - unsigned int num; - unsigned int i; - unsigned int packet; - unsigned long flags; - struct firesat *firesat = NULL; - struct firesat *firesat_iterator; - - spin_lock_irqsave(&firesat_list_lock, flags); - list_for_each_entry(firesat_iterator, &firesat_list, list) { - if(firesat_iterator->iso_handle == iso) { - firesat = firesat_iterator; - break; - } - } - spin_unlock_irqrestore(&firesat_list_lock, flags); - - if (firesat) { - packet = iso->first_packet; - num = hpsb_iso_n_ready(iso); - for (i = 0; i < num; i++, - packet = (packet + 1) % iso->buf_packets) { - unsigned char *buf = - dma_region_i(&iso->data_buf, unsigned char, - iso->infos[packet].offset + - sizeof(struct CIPHeader)); - int count = (iso->infos[packet].len - - sizeof(struct CIPHeader)) / - (188 + sizeof(struct firewireheader)); - if (iso->infos[packet].len <= sizeof(struct CIPHeader)) - continue; // ignore empty packet - - while (count --) { - if (buf[sizeof(struct firewireheader)] == 0x47) - dvb_dmx_swfilter_packets(&firesat->demux, - &buf[sizeof(struct firewireheader)], 1); - else - printk("%s: invalid packet, skipping\n", __func__); - buf += 188 + sizeof(struct firewireheader); - - } - - } - hpsb_iso_recv_release_packets(iso, num); - } - else { - printk("%s: packets for unknown iso channel, skipping\n", - __func__); - hpsb_iso_recv_release_packets(iso, hpsb_iso_n_ready(iso)); - } -} - diff --git a/drivers/media/dvb/firewire/Kconfig b/drivers/media/dvb/firewire/Kconfig new file mode 100644 index 00000000000..03d25ad1035 --- /dev/null +++ b/drivers/media/dvb/firewire/Kconfig @@ -0,0 +1,12 @@ +config DVB_FIREDTV + tristate "FireDTV (FireWire attached DVB receivers)" + depends on DVB_CORE && IEEE1394 && INPUT + help + Support for DVB receivers from Digital Everywhere, known as FireDTV + and FloppyDTV, which are connected via IEEE 1394 (FireWire). + + These devices don't have an MPEG decoder built in, so you need + an external software decoder to watch TV. + + To compile this driver as a module, say M here: the module will be + called firedtv. diff --git a/drivers/media/dvb/firewire/Makefile b/drivers/media/dvb/firewire/Makefile new file mode 100644 index 00000000000..628dacd10da --- /dev/null +++ b/drivers/media/dvb/firewire/Makefile @@ -0,0 +1,13 @@ +firedtv-objs := firedtv-1394.o \ + firedtv-dvb.o \ + firedtv-fe.o \ + firedtv-iso.o \ + avc.o \ + cmp.o \ + firedtv-rc.o \ + firedtv-ci.o + +obj-$(CONFIG_DVB_FIREDTV) += firedtv.o + +EXTRA_CFLAGS := -Idrivers/ieee1394 +EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core diff --git a/drivers/media/dvb/firewire/avc.c b/drivers/media/dvb/firewire/avc.c new file mode 100644 index 00000000000..847a537b1f5 --- /dev/null +++ b/drivers/media/dvb/firewire/avc.c @@ -0,0 +1,1051 @@ +/* + * FireDTV driver (formerly known as FireSAT) + * + * Copyright (C) 2004 Andreas Monitzer + * Copyright (C) 2008 Ben Backx + * Copyright (C) 2008 Henrik Kurelid + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "avc.h" +#include "firedtv.h" +#include "firedtv-rc.h" + +#define FCP_COMMAND_REGISTER 0xfffff0000b00ULL + +static int __avc_write(struct firedtv *fdtv, + const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) +{ + int err, retry; + + if (RspFrm) + fdtv->avc_reply_received = false; + + for (retry = 0; retry < 6; retry++) { + err = hpsb_node_write(fdtv->ud->ne, FCP_COMMAND_REGISTER, + (quadlet_t *)CmdFrm, CmdFrm->length); + if (err) { + fdtv->avc_reply_received = true; + dev_err(&fdtv->ud->device, + "FCP command write failed\n"); + return err; + } + + if (!RspFrm) + return 0; + + /* + * AV/C specs say that answers should be sent within 150 ms. + * Time out after 200 ms. + */ + if (wait_event_timeout(fdtv->avc_wait, + fdtv->avc_reply_received, + HZ / 5) != 0) { + memcpy(RspFrm, fdtv->respfrm, fdtv->resp_length); + RspFrm->length = fdtv->resp_length; + + return 0; + } + } + dev_err(&fdtv->ud->device, "FCP response timed out\n"); + return -ETIMEDOUT; +} + +static int avc_write(struct firedtv *fdtv, + const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) +{ + int ret; + + if (mutex_lock_interruptible(&fdtv->avc_mutex)) + return -EINTR; + + ret = __avc_write(fdtv, CmdFrm, RspFrm); + + mutex_unlock(&fdtv->avc_mutex); + return ret; +} + +int avc_recv(struct firedtv *fdtv, u8 *data, size_t length) +{ + AVCRspFrm *RspFrm = (AVCRspFrm *)data; + + if (length >= 8 && + RspFrm->operand[0] == SFE_VENDOR_DE_COMPANYID_0 && + RspFrm->operand[1] == SFE_VENDOR_DE_COMPANYID_1 && + RspFrm->operand[2] == SFE_VENDOR_DE_COMPANYID_2 && + RspFrm->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) { + if (RspFrm->resp == CHANGED) { + fdtv_handle_rc(fdtv, + RspFrm->operand[4] << 8 | RspFrm->operand[5]); + schedule_work(&fdtv->remote_ctrl_work); + } else if (RspFrm->resp != INTERIM) { + dev_info(&fdtv->ud->device, + "remote control result = %d\n", RspFrm->resp); + } + return 0; + } + + if (fdtv->avc_reply_received) { + dev_err(&fdtv->ud->device, + "received out-of-order AVC response, ignored\n"); + return -EIO; + } + + memcpy(fdtv->respfrm, data, length); + fdtv->resp_length = length; + + fdtv->avc_reply_received = true; + wake_up(&fdtv->avc_wait); + + return 0; +} + +/* + * tuning command for setting the relative LNB frequency + * (not supported by the AVC standard) + */ +static void avc_tuner_tuneqpsk(struct firedtv *fdtv, + struct dvb_frontend_parameters *params, AVCCmdFrm *CmdFrm) +{ + CmdFrm->opcode = VENDOR; + + CmdFrm->operand[0] = SFE_VENDOR_DE_COMPANYID_0; + CmdFrm->operand[1] = SFE_VENDOR_DE_COMPANYID_1; + CmdFrm->operand[2] = SFE_VENDOR_DE_COMPANYID_2; + CmdFrm->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK; + + CmdFrm->operand[4] = (params->frequency >> 24) & 0xff; + CmdFrm->operand[5] = (params->frequency >> 16) & 0xff; + CmdFrm->operand[6] = (params->frequency >> 8) & 0xff; + CmdFrm->operand[7] = params->frequency & 0xff; + + CmdFrm->operand[8] = ((params->u.qpsk.symbol_rate / 1000) >> 8) & 0xff; + CmdFrm->operand[9] = (params->u.qpsk.symbol_rate / 1000) & 0xff; + + switch(params->u.qpsk.fec_inner) { + case FEC_1_2: + CmdFrm->operand[10] = 0x1; break; + case FEC_2_3: + CmdFrm->operand[10] = 0x2; break; + case FEC_3_4: + CmdFrm->operand[10] = 0x3; break; + case FEC_5_6: + CmdFrm->operand[10] = 0x4; break; + case FEC_7_8: + CmdFrm->operand[10] = 0x5; break; + case FEC_4_5: + case FEC_8_9: + case FEC_AUTO: + default: + CmdFrm->operand[10] = 0x0; + } + + if (fdtv->voltage == 0xff) + CmdFrm->operand[11] = 0xff; + else if (fdtv->voltage == SEC_VOLTAGE_18) /* polarisation */ + CmdFrm->operand[11] = 0; + else + CmdFrm->operand[11] = 1; + + if (fdtv->tone == 0xff) + CmdFrm->operand[12] = 0xff; + else if (fdtv->tone == SEC_TONE_ON) /* band */ + CmdFrm->operand[12] = 1; + else + CmdFrm->operand[12] = 0; + + if (fdtv->type == FIREDTV_DVB_S2) { + CmdFrm->operand[13] = 0x1; + CmdFrm->operand[14] = 0xff; + CmdFrm->operand[15] = 0xff; + CmdFrm->length = 20; + } else { + CmdFrm->length = 16; + } +} + +static void avc_tuner_dsd_dvb_c(struct dvb_frontend_parameters *params, + AVCCmdFrm *CmdFrm) +{ + M_VALID_FLAGS flags; + + flags.Bits.Modulation = params->u.qam.modulation != QAM_AUTO; + flags.Bits.FEC_inner = params->u.qam.fec_inner != FEC_AUTO; + flags.Bits.FEC_outer = 0; + flags.Bits.Symbol_Rate = 1; + flags.Bits.Frequency = 1; + flags.Bits.Orbital_Pos = 0; + flags.Bits.Polarisation = 0; + flags.Bits.reserved_fields = 0; + flags.Bits.reserved1 = 0; + flags.Bits.Network_ID = 0; + + CmdFrm->opcode = DSD; + + CmdFrm->operand[0] = 0; /* source plug */ + CmdFrm->operand[1] = 0xd2; /* subfunction replace */ + CmdFrm->operand[2] = 0x20; /* system id = DVB */ + CmdFrm->operand[3] = 0x00; /* antenna number */ + /* system_specific_multiplex selection_length */ + CmdFrm->operand[4] = 0x11; + CmdFrm->operand[5] = flags.Valid_Word.ByteHi; /* valid_flags [0] */ + CmdFrm->operand[6] = flags.Valid_Word.ByteLo; /* valid_flags [1] */ + CmdFrm->operand[7] = 0x00; + CmdFrm->operand[8] = 0x00; + CmdFrm->operand[9] = 0x00; + CmdFrm->operand[10] = 0x00; + + CmdFrm->operand[11] = + (((params->frequency / 4000) >> 16) & 0xff) | (2 << 6); + CmdFrm->operand[12] = + ((params->frequency / 4000) >> 8) & 0xff; + CmdFrm->operand[13] = (params->frequency / 4000) & 0xff; + CmdFrm->operand[14] = + ((params->u.qpsk.symbol_rate / 1000) >> 12) & 0xff; + CmdFrm->operand[15] = + ((params->u.qpsk.symbol_rate / 1000) >> 4) & 0xff; + CmdFrm->operand[16] = + ((params->u.qpsk.symbol_rate / 1000) << 4) & 0xf0; + CmdFrm->operand[17] = 0x00; + + switch (params->u.qpsk.fec_inner) { + case FEC_1_2: + CmdFrm->operand[18] = 0x1; break; + case FEC_2_3: + CmdFrm->operand[18] = 0x2; break; + case FEC_3_4: + CmdFrm->operand[18] = 0x3; break; + case FEC_5_6: + CmdFrm->operand[18] = 0x4; break; + case FEC_7_8: + CmdFrm->operand[18] = 0x5; break; + case FEC_8_9: + CmdFrm->operand[18] = 0x6; break; + case FEC_4_5: + CmdFrm->operand[18] = 0x8; break; + case FEC_AUTO: + default: + CmdFrm->operand[18] = 0x0; + } + switch (params->u.qam.modulation) { + case QAM_16: + CmdFrm->operand[19] = 0x08; break; + case QAM_32: + CmdFrm->operand[19] = 0x10; break; + case QAM_64: + CmdFrm->operand[19] = 0x18; break; + case QAM_128: + CmdFrm->operand[19] = 0x20; break; + case QAM_256: + CmdFrm->operand[19] = 0x28; break; + case QAM_AUTO: + default: + CmdFrm->operand[19] = 0x00; + } + CmdFrm->operand[20] = 0x00; + CmdFrm->operand[21] = 0x00; + /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */ + CmdFrm->operand[22] = 0x00; + + CmdFrm->length = 28; +} + +static void avc_tuner_dsd_dvb_t(struct dvb_frontend_parameters *params, + AVCCmdFrm *CmdFrm) +{ + M_VALID_FLAGS flags; + + flags.Bits_T.GuardInterval = + params->u.ofdm.guard_interval != GUARD_INTERVAL_AUTO; + flags.Bits_T.CodeRateLPStream = + params->u.ofdm.code_rate_LP != FEC_AUTO; + flags.Bits_T.CodeRateHPStream = + params->u.ofdm.code_rate_HP != FEC_AUTO; + flags.Bits_T.HierarchyInfo = + params->u.ofdm.hierarchy_information != HIERARCHY_AUTO; + flags.Bits_T.Constellation = + params->u.ofdm.constellation != QAM_AUTO; + flags.Bits_T.Bandwidth = + params->u.ofdm.bandwidth != BANDWIDTH_AUTO; + flags.Bits_T.CenterFrequency = 1; + flags.Bits_T.reserved1 = 0; + flags.Bits_T.reserved2 = 0; + flags.Bits_T.OtherFrequencyFlag = 0; + flags.Bits_T.TransmissionMode = + params->u.ofdm.transmission_mode != TRANSMISSION_MODE_AUTO; + flags.Bits_T.NetworkId = 0; + + CmdFrm->opcode = DSD; + + CmdFrm->operand[0] = 0; /* source plug */ + CmdFrm->operand[1] = 0xd2; /* subfunction replace */ + CmdFrm->operand[2] = 0x20; /* system id = DVB */ + CmdFrm->operand[3] = 0x00; /* antenna number */ + /* system_specific_multiplex selection_length */ + CmdFrm->operand[4] = 0x0c; + CmdFrm->operand[5] = flags.Valid_Word.ByteHi; /* valid_flags [0] */ + CmdFrm->operand[6] = flags.Valid_Word.ByteLo; /* valid_flags [1] */ + CmdFrm->operand[7] = 0x0; + CmdFrm->operand[8] = (params->frequency / 10) >> 24; + CmdFrm->operand[9] = ((params->frequency / 10) >> 16) & 0xff; + CmdFrm->operand[10] = ((params->frequency / 10) >> 8) & 0xff; + CmdFrm->operand[11] = (params->frequency / 10) & 0xff; + + switch (params->u.ofdm.bandwidth) { + case BANDWIDTH_7_MHZ: + CmdFrm->operand[12] = 0x20; break; + case BANDWIDTH_8_MHZ: + case BANDWIDTH_6_MHZ: /* not defined by AVC spec */ + case BANDWIDTH_AUTO: + default: + CmdFrm->operand[12] = 0x00; + } + switch (params->u.ofdm.constellation) { + case QAM_16: + CmdFrm->operand[13] = 1 << 6; break; + case QAM_64: + CmdFrm->operand[13] = 2 << 6; break; + case QPSK: + default: + CmdFrm->operand[13] = 0x00; + } + switch (params->u.ofdm.hierarchy_information) { + case HIERARCHY_1: + CmdFrm->operand[13] |= 1 << 3; break; + case HIERARCHY_2: + CmdFrm->operand[13] |= 2 << 3; break; + case HIERARCHY_4: + CmdFrm->operand[13] |= 3 << 3; break; + case HIERARCHY_AUTO: + case HIERARCHY_NONE: + default: + break; + } + switch (params->u.ofdm.code_rate_HP) { + case FEC_2_3: + CmdFrm->operand[13] |= 1; break; + case FEC_3_4: + CmdFrm->operand[13] |= 2; break; + case FEC_5_6: + CmdFrm->operand[13] |= 3; break; + case FEC_7_8: + CmdFrm->operand[13] |= 4; break; + case FEC_1_2: + default: + break; + } + switch (params->u.ofdm.code_rate_LP) { + case FEC_2_3: + CmdFrm->operand[14] = 1 << 5; break; + case FEC_3_4: + CmdFrm->operand[14] = 2 << 5; break; + case FEC_5_6: + CmdFrm->operand[14] = 3 << 5; break; + case FEC_7_8: + CmdFrm->operand[14] = 4 << 5; break; + case FEC_1_2: + default: + CmdFrm->operand[14] = 0x00; break; + } + switch (params->u.ofdm.guard_interval) { + case GUARD_INTERVAL_1_16: + CmdFrm->operand[14] |= 1 << 3; break; + case GUARD_INTERVAL_1_8: + CmdFrm->operand[14] |= 2 << 3; break; + case GUARD_INTERVAL_1_4: + CmdFrm->operand[14] |= 3 << 3; break; + case GUARD_INTERVAL_1_32: + case GUARD_INTERVAL_AUTO: + default: + break; + } + switch (params->u.ofdm.transmission_mode) { + case TRANSMISSION_MODE_8K: + CmdFrm->operand[14] |= 1 << 1; break; + case TRANSMISSION_MODE_2K: + case TRANSMISSION_MODE_AUTO: + default: + break; + } + + CmdFrm->operand[15] = 0x00; /* network_ID[0] */ + CmdFrm->operand[16] = 0x00; /* network_ID[1] */ + /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */ + CmdFrm->operand[17] = 0x00; + + CmdFrm->length = 24; +} + +int avc_tuner_dsd(struct firedtv *fdtv, + struct dvb_frontend_parameters *params) +{ + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + + CmdFrm.cts = AVC; + CmdFrm.ctype = CONTROL; + CmdFrm.sutyp = 0x5; + CmdFrm.suid = fdtv->subunit; + + switch (fdtv->type) { + case FIREDTV_DVB_S: + case FIREDTV_DVB_S2: + avc_tuner_tuneqpsk(fdtv, params, &CmdFrm); break; + case FIREDTV_DVB_C: + avc_tuner_dsd_dvb_c(params, &CmdFrm); break; + case FIREDTV_DVB_T: + avc_tuner_dsd_dvb_t(params, &CmdFrm); break; + default: + BUG(); + } + + if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) + return -EIO; + + msleep(500); +#if 0 + /* FIXME: */ + /* u8 *status was an out-parameter of avc_tuner_dsd, unused by caller */ + if(status) + *status=RspFrm.operand[2]; +#endif + return 0; +} + +int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]) +{ + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + int pos, k; + + if (pidc > 16 && pidc != 0xff) + return -EINVAL; + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + + CmdFrm.cts = AVC; + CmdFrm.ctype = CONTROL; + CmdFrm.sutyp = 0x5; + CmdFrm.suid = fdtv->subunit; + CmdFrm.opcode = DSD; + + CmdFrm.operand[0] = 0; // source plug + CmdFrm.operand[1] = 0xD2; // subfunction replace + CmdFrm.operand[2] = 0x20; // system id = DVB + CmdFrm.operand[3] = 0x00; // antenna number + CmdFrm.operand[4] = 0x00; // system_specific_multiplex selection_length + CmdFrm.operand[5] = pidc; // Nr_of_dsd_sel_specs + + pos = 6; + if (pidc != 0xff) + for (k = 0; k < pidc; k++) { + CmdFrm.operand[pos++] = 0x13; // flowfunction relay + CmdFrm.operand[pos++] = 0x80; // dsd_sel_spec_valid_flags -> PID + CmdFrm.operand[pos++] = (pid[k] >> 8) & 0x1F; + CmdFrm.operand[pos++] = pid[k] & 0xFF; + CmdFrm.operand[pos++] = 0x00; // tableID + CmdFrm.operand[pos++] = 0x00; // filter_length + } + + CmdFrm.length = ALIGN(3 + pos, 4); + + if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) + return -EIO; + + msleep(50); + return 0; +} + +int avc_tuner_get_ts(struct firedtv *fdtv) +{ + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + + CmdFrm.cts = AVC; + CmdFrm.ctype = CONTROL; + CmdFrm.sutyp = 0x5; + CmdFrm.suid = fdtv->subunit; + CmdFrm.opcode = DSIT; + + CmdFrm.operand[0] = 0; // source plug + CmdFrm.operand[1] = 0xD2; // subfunction replace + CmdFrm.operand[2] = 0xFF; //status + CmdFrm.operand[3] = 0x20; // system id = DVB + CmdFrm.operand[4] = 0x00; // antenna number + CmdFrm.operand[5] = 0x0; // system_specific_search_flags + CmdFrm.operand[6] = (fdtv->type == FIREDTV_DVB_T)?0x0c:0x11; // system_specific_multiplex selection_length + CmdFrm.operand[7] = 0x00; // valid_flags [0] + CmdFrm.operand[8] = 0x00; // valid_flags [1] + CmdFrm.operand[7 + (fdtv->type == FIREDTV_DVB_T)?0x0c:0x11] = 0x00; // nr_of_dsit_sel_specs (always 0) + + CmdFrm.length = (fdtv->type == FIREDTV_DVB_T)?24:28; + + if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) + return -EIO; + + msleep(250); + return 0; +} + +int avc_identify_subunit(struct firedtv *fdtv) +{ + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + + memset(&CmdFrm,0,sizeof(AVCCmdFrm)); + + CmdFrm.cts = AVC; + CmdFrm.ctype = CONTROL; + CmdFrm.sutyp = 0x5; // tuner + CmdFrm.suid = fdtv->subunit; + CmdFrm.opcode = READ_DESCRIPTOR; + + CmdFrm.operand[0]=DESCRIPTOR_SUBUNIT_IDENTIFIER; + CmdFrm.operand[1]=0xff; + CmdFrm.operand[2]=0x00; + CmdFrm.operand[3]=0x00; // length highbyte + CmdFrm.operand[4]=0x08; // length lowbyte + CmdFrm.operand[5]=0x00; // offset highbyte + CmdFrm.operand[6]=0x0d; // offset lowbyte + + CmdFrm.length=12; + + if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) + return -EIO; + + if ((RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) || + (RspFrm.operand[3] << 8) + RspFrm.operand[4] != 8) { + dev_err(&fdtv->ud->device, + "cannot read subunit identifier\n"); + return -EINVAL; + } + return 0; +} + +int avc_tuner_status(struct firedtv *fdtv, + ANTENNA_INPUT_INFO *antenna_input_info) +{ + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + int length; + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + + CmdFrm.cts=AVC; + CmdFrm.ctype=CONTROL; + CmdFrm.sutyp=0x05; // tuner + CmdFrm.suid=fdtv->subunit; + CmdFrm.opcode=READ_DESCRIPTOR; + + CmdFrm.operand[0]=DESCRIPTOR_TUNER_STATUS; + CmdFrm.operand[1]=0xff; //read_result_status + CmdFrm.operand[2]=0x00; // reserver + CmdFrm.operand[3]=0;//sizeof(ANTENNA_INPUT_INFO) >> 8; + CmdFrm.operand[4]=0;//sizeof(ANTENNA_INPUT_INFO) & 0xFF; + CmdFrm.operand[5]=0x00; + CmdFrm.operand[6]=0x00; + CmdFrm.length=12; + + if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) + return -EIO; + + if (RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) { + dev_err(&fdtv->ud->device, "cannot read tuner status\n"); + return -EINVAL; + } + + length = RspFrm.operand[9]; + if (RspFrm.operand[1] != 0x10 || length != sizeof(ANTENNA_INPUT_INFO)) { + dev_err(&fdtv->ud->device, "got invalid tuner status\n"); + return -EINVAL; + } + + memcpy(antenna_input_info, &RspFrm.operand[10], length); + return 0; +} + +int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst, + char conttone, char nrdiseq, + struct dvb_diseqc_master_cmd *diseqcmd) +{ + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + int i, j, k; + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + + CmdFrm.cts=AVC; + CmdFrm.ctype=CONTROL; + CmdFrm.sutyp=0x05; + CmdFrm.suid=fdtv->subunit; + CmdFrm.opcode=VENDOR; + + CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; + CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; + CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; + CmdFrm.operand[3]=SFE_VENDOR_OPCODE_LNB_CONTROL; + + CmdFrm.operand[4]=voltage; + CmdFrm.operand[5]=nrdiseq; + + i=6; + + for (j = 0; j < nrdiseq; j++) { + CmdFrm.operand[i++] = diseqcmd[j].msg_len; + + for (k = 0; k < diseqcmd[j].msg_len; k++) + CmdFrm.operand[i++] = diseqcmd[j].msg[k]; + } + + CmdFrm.operand[i++]=burst; + CmdFrm.operand[i++]=conttone; + + CmdFrm.length = ALIGN(3 + i, 4); + + if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) + return -EIO; + + if (RspFrm.resp != ACCEPTED) { + dev_err(&fdtv->ud->device, "LNB control failed\n"); + return -EINVAL; + } + + return 0; +} + +int avc_register_remote_control(struct firedtv *fdtv) +{ + AVCCmdFrm CmdFrm; + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + + CmdFrm.cts = AVC; + CmdFrm.ctype = NOTIFY; + CmdFrm.sutyp = 0x1f; + CmdFrm.suid = 0x7; + CmdFrm.opcode = VENDOR; + + CmdFrm.operand[0] = SFE_VENDOR_DE_COMPANYID_0; + CmdFrm.operand[1] = SFE_VENDOR_DE_COMPANYID_1; + CmdFrm.operand[2] = SFE_VENDOR_DE_COMPANYID_2; + CmdFrm.operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL; + + CmdFrm.length = 8; + + return avc_write(fdtv, &CmdFrm, NULL); +} + +void avc_remote_ctrl_work(struct work_struct *work) +{ + struct firedtv *fdtv = + container_of(work, struct firedtv, remote_ctrl_work); + + /* Should it be rescheduled in failure cases? */ + avc_register_remote_control(fdtv); +} + +#if 0 /* FIXME: unused */ +int avc_tuner_host2ca(struct firedtv *fdtv) +{ + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + CmdFrm.cts = AVC; + CmdFrm.ctype = CONTROL; + CmdFrm.sutyp = 0x5; + CmdFrm.suid = fdtv->subunit; + CmdFrm.opcode = VENDOR; + + CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; + CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; + CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; + CmdFrm.operand[3]=SFE_VENDOR_OPCODE_HOST2CA; + CmdFrm.operand[4] = 0; // slot + CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; // ca tag + CmdFrm.operand[6] = 0; // more/last + CmdFrm.operand[7] = 0; // length + CmdFrm.length = 12; + + if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) + return -EIO; + + return 0; +} +#endif + +static int get_ca_object_pos(AVCRspFrm *RspFrm) +{ + int length = 1; + + /* Check length of length field */ + if (RspFrm->operand[7] & 0x80) + length = (RspFrm->operand[7] & 0x7f) + 1; + return length + 7; +} + +static int get_ca_object_length(AVCRspFrm *RspFrm) +{ +#if 0 /* FIXME: unused */ + int size = 0; + int i; + + if (RspFrm->operand[7] & 0x80) + for (i = 0; i < (RspFrm->operand[7] & 0x7f); i++) { + size <<= 8; + size += RspFrm->operand[8 + i]; + } +#endif + return RspFrm->operand[7]; +} + +int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len) +{ + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + int pos; + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + CmdFrm.cts = AVC; + CmdFrm.ctype = STATUS; + CmdFrm.sutyp = 0x5; + CmdFrm.suid = fdtv->subunit; + CmdFrm.opcode = VENDOR; + + CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; + CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; + CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; + CmdFrm.operand[3]=SFE_VENDOR_OPCODE_CA2HOST; + CmdFrm.operand[4] = 0; // slot + CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; // ca tag + CmdFrm.length = 12; + + if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) + return -EIO; + + /* FIXME: check response code and validate response data */ + + pos = get_ca_object_pos(&RspFrm); + app_info[0] = (TAG_APP_INFO >> 16) & 0xFF; + app_info[1] = (TAG_APP_INFO >> 8) & 0xFF; + app_info[2] = (TAG_APP_INFO >> 0) & 0xFF; + app_info[3] = 6 + RspFrm.operand[pos + 4]; + app_info[4] = 0x01; + memcpy(&app_info[5], &RspFrm.operand[pos], 5 + RspFrm.operand[pos + 4]); + *len = app_info[3] + 4; + + return 0; +} + +int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len) +{ + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + int pos; + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + CmdFrm.cts = AVC; + CmdFrm.ctype = STATUS; + CmdFrm.sutyp = 0x5; + CmdFrm.suid = fdtv->subunit; + CmdFrm.opcode = VENDOR; + + CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; + CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; + CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; + CmdFrm.operand[3]=SFE_VENDOR_OPCODE_CA2HOST; + CmdFrm.operand[4] = 0; // slot + CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; // ca tag + CmdFrm.length = 12; + + if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) + return -EIO; + + pos = get_ca_object_pos(&RspFrm); + app_info[0] = (TAG_CA_INFO >> 16) & 0xFF; + app_info[1] = (TAG_CA_INFO >> 8) & 0xFF; + app_info[2] = (TAG_CA_INFO >> 0) & 0xFF; + app_info[3] = 2; + app_info[4] = RspFrm.operand[pos + 0]; + app_info[5] = RspFrm.operand[pos + 1]; + *len = app_info[3] + 4; + + return 0; +} + +int avc_ca_reset(struct firedtv *fdtv) +{ + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + CmdFrm.cts = AVC; + CmdFrm.ctype = CONTROL; + CmdFrm.sutyp = 0x5; + CmdFrm.suid = fdtv->subunit; + CmdFrm.opcode = VENDOR; + + CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; + CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; + CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; + CmdFrm.operand[3]=SFE_VENDOR_OPCODE_HOST2CA; + CmdFrm.operand[4] = 0; // slot + CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_RESET; // ca tag + CmdFrm.operand[6] = 0; // more/last + CmdFrm.operand[7] = 1; // length + CmdFrm.operand[8] = 0; // force hardware reset + CmdFrm.length = 12; + + if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) + return -EIO; + + return 0; +} + +int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length) +{ + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + int list_management; + int program_info_length; + int pmt_cmd_id; + int read_pos; + int write_pos; + int es_info_length; + int crc32_csum; + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + CmdFrm.cts = AVC; + CmdFrm.ctype = CONTROL; + CmdFrm.sutyp = 0x5; + CmdFrm.suid = fdtv->subunit; + CmdFrm.opcode = VENDOR; + + if (msg[0] != LIST_MANAGEMENT_ONLY) { + dev_info(&fdtv->ud->device, + "forcing list_management to ONLY\n"); + msg[0] = LIST_MANAGEMENT_ONLY; + } + // We take the cmd_id from the programme level only! + list_management = msg[0]; + program_info_length = ((msg[4] & 0x0F) << 8) + msg[5]; + if (program_info_length > 0) + program_info_length--; // Remove pmt_cmd_id + pmt_cmd_id = msg[6]; + + CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; + CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; + CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; + CmdFrm.operand[3]=SFE_VENDOR_OPCODE_HOST2CA; + CmdFrm.operand[4] = 0; // slot + CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_PMT; // ca tag + CmdFrm.operand[6] = 0; // more/last + //CmdFrm.operand[7] = XXXprogram_info_length + 17; // length + CmdFrm.operand[8] = list_management; + CmdFrm.operand[9] = 0x01; // pmt_cmd=OK_descramble + + // TS program map table + + // Table id=2 + CmdFrm.operand[10] = 0x02; + // Section syntax + length + CmdFrm.operand[11] = 0x80; + //CmdFrm.operand[12] = XXXprogram_info_length + 12; + // Program number + CmdFrm.operand[13] = msg[1]; + CmdFrm.operand[14] = msg[2]; + // Version number=0 + current/next=1 + CmdFrm.operand[15] = 0x01; + // Section number=0 + CmdFrm.operand[16] = 0x00; + // Last section number=0 + CmdFrm.operand[17] = 0x00; + // PCR_PID=1FFF + CmdFrm.operand[18] = 0x1F; + CmdFrm.operand[19] = 0xFF; + // Program info length + CmdFrm.operand[20] = (program_info_length >> 8); + CmdFrm.operand[21] = (program_info_length & 0xFF); + // CA descriptors at programme level + read_pos = 6; + write_pos = 22; + if (program_info_length > 0) { + pmt_cmd_id = msg[read_pos++]; + if (pmt_cmd_id != 1 && pmt_cmd_id != 4) + dev_err(&fdtv->ud->device, + "invalid pmt_cmd_id %d\n", pmt_cmd_id); + + memcpy(&CmdFrm.operand[write_pos], &msg[read_pos], + program_info_length); + read_pos += program_info_length; + write_pos += program_info_length; + } + while (read_pos < length) { + CmdFrm.operand[write_pos++] = msg[read_pos++]; + CmdFrm.operand[write_pos++] = msg[read_pos++]; + CmdFrm.operand[write_pos++] = msg[read_pos++]; + es_info_length = + ((msg[read_pos] & 0x0F) << 8) + msg[read_pos + 1]; + read_pos += 2; + if (es_info_length > 0) + es_info_length--; // Remove pmt_cmd_id + CmdFrm.operand[write_pos++] = es_info_length >> 8; + CmdFrm.operand[write_pos++] = es_info_length & 0xFF; + if (es_info_length > 0) { + pmt_cmd_id = msg[read_pos++]; + if (pmt_cmd_id != 1 && pmt_cmd_id != 4) + dev_err(&fdtv->ud->device, + "invalid pmt_cmd_id %d " + "at stream level\n", pmt_cmd_id); + + memcpy(&CmdFrm.operand[write_pos], &msg[read_pos], + es_info_length); + read_pos += es_info_length; + write_pos += es_info_length; + } + } + + // CRC + CmdFrm.operand[write_pos++] = 0x00; + CmdFrm.operand[write_pos++] = 0x00; + CmdFrm.operand[write_pos++] = 0x00; + CmdFrm.operand[write_pos++] = 0x00; + + CmdFrm.operand[7] = write_pos - 8; + CmdFrm.operand[12] = write_pos - 13; + + crc32_csum = crc32_be(0, &CmdFrm.operand[10], + CmdFrm.operand[12] - 1); + CmdFrm.operand[write_pos - 4] = (crc32_csum >> 24) & 0xFF; + CmdFrm.operand[write_pos - 3] = (crc32_csum >> 16) & 0xFF; + CmdFrm.operand[write_pos - 2] = (crc32_csum >> 8) & 0xFF; + CmdFrm.operand[write_pos - 1] = (crc32_csum >> 0) & 0xFF; + + CmdFrm.length = ALIGN(3 + write_pos, 4); + + if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) + return -EIO; + + if (RspFrm.resp != ACCEPTED) { + dev_err(&fdtv->ud->device, + "CA PMT failed with response 0x%x\n", RspFrm.resp); + return -EFAULT; + } + + return 0; +} + +int avc_ca_get_time_date(struct firedtv *fdtv, int *interval) +{ + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + CmdFrm.cts = AVC; + CmdFrm.ctype = STATUS; + CmdFrm.sutyp = 0x5; + CmdFrm.suid = fdtv->subunit; + CmdFrm.opcode = VENDOR; + + CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; + CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; + CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; + CmdFrm.operand[3]=SFE_VENDOR_OPCODE_CA2HOST; + CmdFrm.operand[4] = 0; // slot + CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_DATE_TIME; // ca tag + CmdFrm.operand[6] = 0; // more/last + CmdFrm.operand[7] = 0; // length + CmdFrm.length = 12; + + if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) + return -EIO; + + /* FIXME: check response code and validate response data */ + + *interval = RspFrm.operand[get_ca_object_pos(&RspFrm)]; + + return 0; +} + +int avc_ca_enter_menu(struct firedtv *fdtv) +{ + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + CmdFrm.cts = AVC; + CmdFrm.ctype = STATUS; + CmdFrm.sutyp = 0x5; + CmdFrm.suid = fdtv->subunit; + CmdFrm.opcode = VENDOR; + + CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; + CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; + CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; + CmdFrm.operand[3]=SFE_VENDOR_OPCODE_HOST2CA; + CmdFrm.operand[4] = 0; // slot + CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_ENTER_MENU; + CmdFrm.operand[6] = 0; // more/last + CmdFrm.operand[7] = 0; // length + CmdFrm.length = 12; + + if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) + return -EIO; + + return 0; +} + +int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len) +{ + AVCCmdFrm CmdFrm; + AVCRspFrm RspFrm; + + memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); + CmdFrm.cts = AVC; + CmdFrm.ctype = STATUS; + CmdFrm.sutyp = 0x5; + CmdFrm.suid = fdtv->subunit; + CmdFrm.opcode = VENDOR; + + CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; + CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; + CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; + CmdFrm.operand[3]=SFE_VENDOR_OPCODE_CA2HOST; + CmdFrm.operand[4] = 0; // slot + CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_MMI; + CmdFrm.operand[6] = 0; // more/last + CmdFrm.operand[7] = 0; // length + CmdFrm.length = 12; + + if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) + return -EIO; + + /* FIXME: check response code and validate response data */ + + *len = get_ca_object_length(&RspFrm); + memcpy(mmi_object, &RspFrm.operand[get_ca_object_pos(&RspFrm)], *len); + + return 0; +} diff --git a/drivers/media/dvb/firewire/avc.h b/drivers/media/dvb/firewire/avc.h new file mode 100644 index 00000000000..168f371dbde --- /dev/null +++ b/drivers/media/dvb/firewire/avc.h @@ -0,0 +1,432 @@ +/* + * AV/C API + * + * Copyright (C) 2000 Manfred Weihs + * Copyright (C) 2003 Philipp Gutgsell <0014guph@edu.fh-kaernten.ac.at> + * Copyright (C) 2004 Andreas Monitzer + * Copyright (C) 2008 Ben Backx + * Copyright (C) 2008 Henrik Kurelid + * + * This is based on code written by Peter Halwachs, Thomas Groiss and + * Andreas Monitzer. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#ifndef _AVC_API_H +#define _AVC_API_H + +#include + +/************************************************************* + Constants from EN510221 +**************************************************************/ +#define LIST_MANAGEMENT_ONLY 0x03 + +/************************************************************ + definition of structures +*************************************************************/ +typedef struct { + int Nr_SourcePlugs; + int Nr_DestinationPlugs; +} TunerInfo; + + +/*********************************************** + + supported cts + +************************************************/ + +#define AVC 0x0 + +// FCP command frame with ctype = 0x0 is AVC command frame + +#ifdef __LITTLE_ENDIAN + +// Definition FCP Command Frame +typedef struct _AVCCmdFrm +{ + // AV/C command frame + __u8 ctype : 4 ; // command type + __u8 cts : 4 ; // always 0x0 for AVC + __u8 suid : 3 ; // subunit ID + __u8 sutyp : 5 ; // subunit_typ + __u8 opcode : 8 ; // opcode + __u8 operand[509] ; // array of operands [1-507] + int length; //length of the command frame +} AVCCmdFrm ; + +// Definition FCP Response Frame +typedef struct _AVCRspFrm +{ + // AV/C response frame + __u8 resp : 4 ; // response type + __u8 cts : 4 ; // always 0x0 for AVC + __u8 suid : 3 ; // subunit ID + __u8 sutyp : 5 ; // subunit_typ + __u8 opcode : 8 ; // opcode + __u8 operand[509] ; // array of operands [1-507] + int length; //length of the response frame +} AVCRspFrm ; + +#else + +typedef struct _AVCCmdFrm +{ + __u8 cts:4; + __u8 ctype:4; + __u8 sutyp:5; + __u8 suid:3; + __u8 opcode; + __u8 operand[509]; + int length; +} AVCCmdFrm; + +typedef struct _AVCRspFrm +{ + __u8 cts:4; + __u8 resp:4; + __u8 sutyp:5; + __u8 suid:3; + __u8 opcode; + __u8 operand[509]; + int length; +} AVCRspFrm; + +#endif + +/************************************************************* + AVC command types (ctype) +**************************************************************/// +#define CONTROL 0x00 +#define STATUS 0x01 +#define INQUIRY 0x02 +#define NOTIFY 0x03 + +/************************************************************* + AVC respond types +**************************************************************/// +#define NOT_IMPLEMENTED 0x8 +#define ACCEPTED 0x9 +#define REJECTED 0xA +#define STABLE 0xC +#define CHANGED 0xD +#define INTERIM 0xF + +/************************************************************* + AVC opcodes +**************************************************************/// +#define CONNECT 0x24 +#define DISCONNECT 0x25 +#define UNIT_INFO 0x30 +#define SUBUNIT_Info 0x31 +#define VENDOR 0x00 + +#define PLUG_INFO 0x02 +#define OPEN_DESCRIPTOR 0x08 +#define READ_DESCRIPTOR 0x09 +#define OBJECT_NUMBER_SELECT 0x0D + +/************************************************************* + AVCTuner opcodes +**************************************************************/ + +#define DSIT 0xC8 +#define DSD 0xCB +#define DESCRIPTOR_TUNER_STATUS 0x80 +#define DESCRIPTOR_SUBUNIT_IDENTIFIER 0x00 + +/************************************************************* + AVCTuner list types +**************************************************************/ +#define Multiplex_List 0x80 +#define Service_List 0x82 + +/************************************************************* + AVCTuner object entries +**************************************************************/ +#define Multiplex 0x80 +#define Service 0x82 +#define Service_with_specified_components 0x83 +#define Preferred_components 0x90 +#define Component 0x84 + +/************************************************************* + Vendor-specific commands +**************************************************************/ + +// digital everywhere vendor ID +#define SFE_VENDOR_DE_COMPANYID_0 0x00 +#define SFE_VENDOR_DE_COMPANYID_1 0x12 +#define SFE_VENDOR_DE_COMPANYID_2 0x87 + +#define SFE_VENDOR_MAX_NR_COMPONENTS 0x4 +#define SFE_VENDOR_MAX_NR_SERVICES 0x3 +#define SFE_VENDOR_MAX_NR_DSD_ELEMENTS 0x10 + +// vendor commands +#define SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL 0x0A +#define SFE_VENDOR_OPCODE_LNB_CONTROL 0x52 +#define SFE_VENDOR_OPCODE_TUNE_QPSK 0x58 // QPSK command for DVB-S + +// TODO: following vendor specific commands needs to be implemented +#define SFE_VENDOR_OPCODE_GET_FIRMWARE_VERSION 0x00 +#define SFE_VENDOR_OPCODE_HOST2CA 0x56 +#define SFE_VENDOR_OPCODE_CA2HOST 0x57 +#define SFE_VENDOR_OPCODE_CISTATUS 0x59 +#define SFE_VENDOR_OPCODE_TUNE_QPSK2 0x60 // QPSK command for DVB-S2 devices + +// CA Tags +#define SFE_VENDOR_TAG_CA_RESET 0x00 +#define SFE_VENDOR_TAG_CA_APPLICATION_INFO 0x01 +#define SFE_VENDOR_TAG_CA_PMT 0x02 +#define SFE_VENDOR_TAG_CA_DATE_TIME 0x04 +#define SFE_VENDOR_TAG_CA_MMI 0x05 +#define SFE_VENDOR_TAG_CA_ENTER_MENU 0x07 + + +//AVCTuner DVB identifier service_ID +#define DVB 0x20 + +/************************************************************* + AVC descriptor types +**************************************************************/ + +#define Subunit_Identifier_Descriptor 0x00 +#define Tuner_Status_Descriptor 0x80 + +typedef struct { + __u8 Subunit_Type; + __u8 Max_Subunit_ID; +} SUBUNIT_INFO; + +/************************************************************* + + AVCTuner DVB object IDs are 6 byte long + +**************************************************************/ + +typedef struct { + __u8 Byte0; + __u8 Byte1; + __u8 Byte2; + __u8 Byte3; + __u8 Byte4; + __u8 Byte5; +}OBJECT_ID; + +/************************************************************* + MULIPLEX Structs +**************************************************************/ +typedef struct +{ +#ifdef __LITTLE_ENDIAN + __u8 RF_frequency_hByte:6; + __u8 raster_Frequency:2;//Bit7,6 raster frequency +#else + __u8 raster_Frequency:2; + __u8 RF_frequency_hByte:6; +#endif + __u8 RF_frequency_mByte; + __u8 RF_frequency_lByte; + +}FREQUENCY; + +#ifdef __LITTLE_ENDIAN + +typedef struct +{ + __u8 Modulation :1; + __u8 FEC_inner :1; + __u8 FEC_outer :1; + __u8 Symbol_Rate :1; + __u8 Frequency :1; + __u8 Orbital_Pos :1; + __u8 Polarisation :1; + __u8 reserved_fields :1; + __u8 reserved1 :7; + __u8 Network_ID :1; + +}MULTIPLEX_VALID_FLAGS; + +typedef struct +{ + __u8 GuardInterval:1; + __u8 CodeRateLPStream:1; + __u8 CodeRateHPStream:1; + __u8 HierarchyInfo:1; + __u8 Constellation:1; + __u8 Bandwidth:1; + __u8 CenterFrequency:1; + __u8 reserved1:1; + __u8 reserved2:5; + __u8 OtherFrequencyFlag:1; + __u8 TransmissionMode:1; + __u8 NetworkId:1; +}MULTIPLEX_VALID_FLAGS_DVBT; + +#else + +typedef struct { + __u8 reserved_fields:1; + __u8 Polarisation:1; + __u8 Orbital_Pos:1; + __u8 Frequency:1; + __u8 Symbol_Rate:1; + __u8 FEC_outer:1; + __u8 FEC_inner:1; + __u8 Modulation:1; + __u8 Network_ID:1; + __u8 reserved1:7; +}MULTIPLEX_VALID_FLAGS; + +typedef struct { + __u8 reserved1:1; + __u8 CenterFrequency:1; + __u8 Bandwidth:1; + __u8 Constellation:1; + __u8 HierarchyInfo:1; + __u8 CodeRateHPStream:1; + __u8 CodeRateLPStream:1; + __u8 GuardInterval:1; + __u8 NetworkId:1; + __u8 TransmissionMode:1; + __u8 OtherFrequencyFlag:1; + __u8 reserved2:5; +}MULTIPLEX_VALID_FLAGS_DVBT; + +#endif + +typedef union { + MULTIPLEX_VALID_FLAGS Bits; + MULTIPLEX_VALID_FLAGS_DVBT Bits_T; + struct { + __u8 ByteHi; + __u8 ByteLo; + } Valid_Word; +} M_VALID_FLAGS; + +typedef struct +{ +#ifdef __LITTLE_ENDIAN + __u8 ActiveSystem; + __u8 reserved:5; + __u8 NoRF:1; + __u8 Moving:1; + __u8 Searching:1; + + __u8 SelectedAntenna:7; + __u8 Input:1; + + __u8 BER[4]; + + __u8 SignalStrength; + FREQUENCY Frequency; + + __u8 ManDepInfoLength; + + __u8 PowerSupply:1; + __u8 FrontEndPowerStatus:1; + __u8 reserved3:1; + __u8 AntennaError:1; + __u8 FrontEndError:1; + __u8 reserved2:3; + + __u8 CarrierNoiseRatio[2]; + __u8 reserved4[2]; + __u8 PowerSupplyVoltage; + __u8 AntennaVoltage; + __u8 FirewireBusVoltage; + + __u8 CaMmi:1; + __u8 reserved5:7; + + __u8 reserved6:1; + __u8 CaInitializationStatus:1; + __u8 CaErrorFlag:1; + __u8 CaDvbFlag:1; + __u8 CaModulePresentStatus:1; + __u8 CaApplicationInfo:1; + __u8 CaDateTimeRequest:1; + __u8 CaPmtReply:1; + +#else + __u8 ActiveSystem; + __u8 Searching:1; + __u8 Moving:1; + __u8 NoRF:1; + __u8 reserved:5; + + __u8 Input:1; + __u8 SelectedAntenna:7; + + __u8 BER[4]; + + __u8 SignalStrength; + FREQUENCY Frequency; + + __u8 ManDepInfoLength; + + __u8 reserved2:3; + __u8 FrontEndError:1; + __u8 AntennaError:1; + __u8 reserved3:1; + __u8 FrontEndPowerStatus:1; + __u8 PowerSupply:1; + + __u8 CarrierNoiseRatio[2]; + __u8 reserved4[2]; + __u8 PowerSupplyVoltage; + __u8 AntennaVoltage; + __u8 FirewireBusVoltage; + + __u8 reserved5:7; + __u8 CaMmi:1; + __u8 CaPmtReply:1; + __u8 CaDateTimeRequest:1; + __u8 CaApplicationInfo:1; + __u8 CaModulePresentStatus:1; + __u8 CaDvbFlag:1; + __u8 CaErrorFlag:1; + __u8 CaInitializationStatus:1; + __u8 reserved6:1; + +#endif +} ANTENNA_INPUT_INFO; // 22 Byte + +#define LNBCONTROL_DONTCARE 0xff + +struct dvb_diseqc_master_cmd; +struct dvb_frontend_parameters; +struct firedtv; + +int avc_recv(struct firedtv *fdtv, u8 *data, size_t length); + +int AVCTuner_DSIT(struct firedtv *fdtv, int Source_Plug, + struct dvb_frontend_parameters *params, __u8 *status); + +int avc_tuner_status(struct firedtv *fdtv, + ANTENNA_INPUT_INFO *antenna_input_info); +int avc_tuner_dsd(struct firedtv *fdtv, + struct dvb_frontend_parameters *params); +int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]); +int avc_tuner_get_ts(struct firedtv *fdtv); +int avc_identify_subunit(struct firedtv *fdtv); +int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst, + char conttone, char nrdiseq, + struct dvb_diseqc_master_cmd *diseqcmd); +void avc_remote_ctrl_work(struct work_struct *work); +int avc_register_remote_control(struct firedtv *fdtv); +int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len); +int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len); +int avc_ca_reset(struct firedtv *fdtv); +int avc_ca_pmt(struct firedtv *fdtv, char *app_info, int length); +int avc_ca_get_time_date(struct firedtv *fdtv, int *interval); +int avc_ca_enter_menu(struct firedtv *fdtv); +int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len); + +#endif /* _AVC_API_H */ diff --git a/drivers/media/dvb/firewire/cmp.c b/drivers/media/dvb/firewire/cmp.c new file mode 100644 index 00000000000..821e033d819 --- /dev/null +++ b/drivers/media/dvb/firewire/cmp.c @@ -0,0 +1,171 @@ +/* + * FireDTV driver (formerly known as FireSAT) + * + * Copyright (C) 2004 Andreas Monitzer + * Copyright (C) 2008 Henrik Kurelid + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#include +#include +#include +#include + +#include + +#include +#include + +#include "avc.h" +#include "cmp.h" +#include "firedtv.h" + +#define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL + +static int cmp_read(struct firedtv *fdtv, void *buf, u64 addr, size_t len) +{ + int ret; + + if (mutex_lock_interruptible(&fdtv->avc_mutex)) + return -EINTR; + + ret = hpsb_node_read(fdtv->ud->ne, addr, buf, len); + if (ret < 0) + dev_err(&fdtv->ud->device, "CMP: read I/O error\n"); + + mutex_unlock(&fdtv->avc_mutex); + return ret; +} + +static int cmp_lock(struct firedtv *fdtv, void *data, u64 addr, __be32 arg, + int ext_tcode) +{ + int ret; + + if (mutex_lock_interruptible(&fdtv->avc_mutex)) + return -EINTR; + + ret = hpsb_node_lock(fdtv->ud->ne, addr, ext_tcode, data, + (__force quadlet_t)arg); + if (ret < 0) + dev_err(&fdtv->ud->device, "CMP: lock I/O error\n"); + + mutex_unlock(&fdtv->avc_mutex); + return ret; +} + +static inline u32 get_opcr(__be32 opcr, u32 mask, u32 shift) +{ + return (be32_to_cpu(opcr) >> shift) & mask; +} + +static inline void set_opcr(__be32 *opcr, u32 value, u32 mask, u32 shift) +{ + *opcr &= ~cpu_to_be32(mask << shift); + *opcr |= cpu_to_be32((value & mask) << shift); +} + +#define get_opcr_online(v) get_opcr((v), 0x1, 31) +#define get_opcr_p2p_connections(v) get_opcr((v), 0x3f, 24) +#define get_opcr_channel(v) get_opcr((v), 0x3f, 16) + +#define set_opcr_p2p_connections(p, v) set_opcr((p), (v), 0x3f, 24) +#define set_opcr_channel(p, v) set_opcr((p), (v), 0x3f, 16) +#define set_opcr_data_rate(p, v) set_opcr((p), (v), 0x3, 14) +#define set_opcr_overhead_id(p, v) set_opcr((p), (v), 0xf, 10) + +int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel) +{ + __be32 old_opcr, opcr; + u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); + int attempts = 0; + int ret; + + ret = cmp_read(fdtv, &opcr, opcr_address, 4); + if (ret < 0) + return ret; + +repeat: + if (!get_opcr_online(opcr)) { + dev_err(&fdtv->ud->device, "CMP: output offline\n"); + return -EBUSY; + } + + old_opcr = opcr; + + if (get_opcr_p2p_connections(opcr)) { + if (get_opcr_channel(opcr) != channel) { + dev_err(&fdtv->ud->device, + "CMP: cannot change channel\n"); + return -EBUSY; + } + dev_info(&fdtv->ud->device, + "CMP: overlaying existing connection\n"); + + /* We don't allocate isochronous resources. */ + } else { + set_opcr_channel(&opcr, channel); + set_opcr_data_rate(&opcr, IEEE1394_SPEED_400); + + /* FIXME: this is for the worst case - optimize */ + set_opcr_overhead_id(&opcr, 0); + + /* FIXME: allocate isochronous channel and bandwidth at IRM */ + } + + set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) + 1); + + ret = cmp_lock(fdtv, &opcr, opcr_address, old_opcr, 2); + if (ret < 0) + return ret; + + if (old_opcr != opcr) { + /* + * FIXME: if old_opcr.P2P_Connections > 0, + * deallocate isochronous channel and bandwidth at IRM + */ + + if (++attempts < 6) /* arbitrary limit */ + goto repeat; + return -EBUSY; + } + + return 0; +} + +void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel) +{ + __be32 old_opcr, opcr; + u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); + int attempts = 0; + + if (cmp_read(fdtv, &opcr, opcr_address, 4) < 0) + return; + +repeat: + if (!get_opcr_online(opcr) || !get_opcr_p2p_connections(opcr) || + get_opcr_channel(opcr) != channel) { + dev_err(&fdtv->ud->device, "CMP: no connection to break\n"); + return; + } + + old_opcr = opcr; + set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) - 1); + + if (cmp_lock(fdtv, &opcr, opcr_address, old_opcr, 2) < 0) + return; + + if (old_opcr != opcr) { + /* + * FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last + * owner, deallocate isochronous channel and bandwidth at IRM + */ + + if (++attempts < 6) /* arbitrary limit */ + goto repeat; + } +} diff --git a/drivers/media/dvb/firewire/cmp.h b/drivers/media/dvb/firewire/cmp.h new file mode 100644 index 00000000000..17e182cf29a --- /dev/null +++ b/drivers/media/dvb/firewire/cmp.h @@ -0,0 +1,9 @@ +#ifndef _CMP_H +#define _CMP_H + +struct firedtv; + +int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel); +void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel); + +#endif /* _CMP_H */ diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c new file mode 100644 index 00000000000..953618246e8 --- /dev/null +++ b/drivers/media/dvb/firewire/firedtv-1394.c @@ -0,0 +1,291 @@ +/* + * FireDTV driver (formerly known as FireSAT) + * + * Copyright (C) 2004 Andreas Monitzer + * Copyright (C) 2007-2008 Ben Backx + * Copyright (C) 2008 Henrik Kurelid + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "avc.h" +#include "cmp.h" +#include "firedtv.h" +#include "firedtv-ci.h" +#include "firedtv-rc.h" + +#define MATCH_FLAGS IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \ + IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION +#define DIGITAL_EVERYWHERE_OUI 0x001287 + +static struct ieee1394_device_id fdtv_id_table[] = { + + { + /* FloppyDTV S/CI and FloppyDTV S2 */ + .match_flags = MATCH_FLAGS, + .vendor_id = DIGITAL_EVERYWHERE_OUI, + .model_id = 0x000024, + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, + .version = AVC_SW_VERSION_ENTRY, + },{ + /* FloppyDTV T/CI */ + .match_flags = MATCH_FLAGS, + .vendor_id = DIGITAL_EVERYWHERE_OUI, + .model_id = 0x000025, + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, + .version = AVC_SW_VERSION_ENTRY, + },{ + /* FloppyDTV C/CI */ + .match_flags = MATCH_FLAGS, + .vendor_id = DIGITAL_EVERYWHERE_OUI, + .model_id = 0x000026, + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, + .version = AVC_SW_VERSION_ENTRY, + },{ + /* FireDTV S/CI and FloppyDTV S2 */ + .match_flags = MATCH_FLAGS, + .vendor_id = DIGITAL_EVERYWHERE_OUI, + .model_id = 0x000034, + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, + .version = AVC_SW_VERSION_ENTRY, + },{ + /* FireDTV T/CI */ + .match_flags = MATCH_FLAGS, + .vendor_id = DIGITAL_EVERYWHERE_OUI, + .model_id = 0x000035, + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, + .version = AVC_SW_VERSION_ENTRY, + },{ + /* FireDTV C/CI */ + .match_flags = MATCH_FLAGS, + .vendor_id = DIGITAL_EVERYWHERE_OUI, + .model_id = 0x000036, + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, + .version = AVC_SW_VERSION_ENTRY, + }, { } +}; + +MODULE_DEVICE_TABLE(ieee1394, fdtv_id_table); + +/* list of all firedtv devices */ +LIST_HEAD(fdtv_list); +DEFINE_SPINLOCK(fdtv_list_lock); + +static void fcp_request(struct hpsb_host *host, + int nodeid, + int direction, + int cts, + u8 *data, + size_t length) +{ + struct firedtv *fdtv = NULL; + struct firedtv *fdtv_entry; + unsigned long flags; + + if (length > 0 && ((data[0] & 0xf0) >> 4) == 0) { + + spin_lock_irqsave(&fdtv_list_lock, flags); + list_for_each_entry(fdtv_entry,&fdtv_list,list) { + if (fdtv_entry->ud->ne->host == host && + fdtv_entry->ud->ne->nodeid == nodeid && + (fdtv_entry->subunit == (data[1]&0x7) || + (fdtv_entry->subunit == 0 && + (data[1]&0x7) == 0x7))) { + fdtv=fdtv_entry; + break; + } + } + spin_unlock_irqrestore(&fdtv_list_lock, flags); + + if (fdtv) + avc_recv(fdtv, data, length); + } +} + +const char *fdtv_model_names[] = { + [FIREDTV_UNKNOWN] = "unknown type", + [FIREDTV_DVB_S] = "FireDTV S/CI", + [FIREDTV_DVB_C] = "FireDTV C/CI", + [FIREDTV_DVB_T] = "FireDTV T/CI", + [FIREDTV_DVB_S2] = "FireDTV S2 ", +}; + +static int fdtv_probe(struct device *dev) +{ + struct unit_directory *ud = + container_of(dev, struct unit_directory, device); + struct firedtv *fdtv; + unsigned long flags; + int kv_len; + void *kv_str; + int i; + int err = -ENOMEM; + + fdtv = kzalloc(sizeof(*fdtv), GFP_KERNEL); + if (!fdtv) + return -ENOMEM; + + dev->driver_data = fdtv; + fdtv->ud = ud; + fdtv->subunit = 0; + fdtv->isochannel = -1; + fdtv->tone = 0xff; + fdtv->voltage = 0xff; + + mutex_init(&fdtv->avc_mutex); + init_waitqueue_head(&fdtv->avc_wait); + fdtv->avc_reply_received = true; + mutex_init(&fdtv->demux_mutex); + INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work); + + /* Reading device model from ROM */ + kv_len = (ud->model_name_kv->value.leaf.len - 2) * sizeof(quadlet_t); + kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv); + for (i = ARRAY_SIZE(fdtv_model_names); --i;) + if (strlen(fdtv_model_names[i]) <= kv_len && + strncmp(kv_str, fdtv_model_names[i], kv_len) == 0) + break; + fdtv->type = i; + + /* + * Work around a bug in udev's path_id script: Use the fw-host's dev + * instead of the unit directory's dev as parent of the input device. + */ + err = fdtv_register_rc(fdtv, dev->parent->parent); + if (err) + goto fail_free; + + INIT_LIST_HEAD(&fdtv->list); + spin_lock_irqsave(&fdtv_list_lock, flags); + list_add_tail(&fdtv->list, &fdtv_list); + spin_unlock_irqrestore(&fdtv_list_lock, flags); + + err = avc_identify_subunit(fdtv); + if (err) + goto fail; + + err = fdtv_dvbdev_init(fdtv, dev); + if (err) + goto fail; + + avc_register_remote_control(fdtv); + return 0; + +fail: + spin_lock_irqsave(&fdtv_list_lock, flags); + list_del(&fdtv->list); + spin_unlock_irqrestore(&fdtv_list_lock, flags); + fdtv_unregister_rc(fdtv); +fail_free: + kfree(fdtv); + return err; +} + +static int fdtv_remove(struct device *dev) +{ + struct firedtv *fdtv = dev->driver_data; + unsigned long flags; + + fdtv_ca_release(fdtv); + dvb_unregister_frontend(&fdtv->fe); + dvb_net_release(&fdtv->dvbnet); + fdtv->demux.dmx.close(&fdtv->demux.dmx); + fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, + &fdtv->frontend); + dvb_dmxdev_release(&fdtv->dmxdev); + dvb_dmx_release(&fdtv->demux); + dvb_unregister_adapter(&fdtv->adapter); + + spin_lock_irqsave(&fdtv_list_lock, flags); + list_del(&fdtv->list); + spin_unlock_irqrestore(&fdtv_list_lock, flags); + + cancel_work_sync(&fdtv->remote_ctrl_work); + fdtv_unregister_rc(fdtv); + + kfree(fdtv); + return 0; +} + +static int fdtv_update(struct unit_directory *ud) +{ + struct firedtv *fdtv = ud->device.driver_data; + + if (fdtv->isochannel >= 0) + cmp_establish_pp_connection(fdtv, fdtv->subunit, + fdtv->isochannel); + return 0; +} + +static struct hpsb_protocol_driver fdtv_driver = { + + .name = "firedtv", + .id_table = fdtv_id_table, + .update = fdtv_update, + + .driver = { + //.name and .bus are filled in for us in more recent linux versions + //.name = "FireDTV", + //.bus = &ieee1394_bus_type, + .probe = fdtv_probe, + .remove = fdtv_remove, + }, +}; + +static struct hpsb_highlevel fdtv_highlevel = { + .name = "firedtv", + .fcp_request = fcp_request, +}; + +static int __init fdtv_init(void) +{ + int ret; + + hpsb_register_highlevel(&fdtv_highlevel); + ret = hpsb_register_protocol(&fdtv_driver); + if (ret) { + printk(KERN_ERR "firedtv: failed to register protocol\n"); + hpsb_unregister_highlevel(&fdtv_highlevel); + } + return ret; +} + +static void __exit fdtv_exit(void) +{ + hpsb_unregister_protocol(&fdtv_driver); + hpsb_unregister_highlevel(&fdtv_highlevel); +} + +module_init(fdtv_init); +module_exit(fdtv_exit); + +MODULE_AUTHOR("Andreas Monitzer "); +MODULE_AUTHOR("Ben Backx "); +MODULE_DESCRIPTION("FireDTV DVB Driver"); +MODULE_LICENSE("GPL"); +MODULE_SUPPORTED_DEVICE("FireDTV DVB"); diff --git a/drivers/media/dvb/firewire/firedtv-ci.c b/drivers/media/dvb/firewire/firedtv-ci.c new file mode 100644 index 00000000000..6d87926b8bf --- /dev/null +++ b/drivers/media/dvb/firewire/firedtv-ci.c @@ -0,0 +1,261 @@ +/* + * FireDTV driver (formerly known as FireSAT) + * + * Copyright (C) 2004 Andreas Monitzer + * Copyright (C) 2008 Henrik Kurelid + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#include +#include +#include + +#include + +#include "avc.h" +#include "firedtv.h" +#include "firedtv-ci.h" + +static int fdtv_ca_ready(ANTENNA_INPUT_INFO *info) +{ + return info->CaInitializationStatus == 1 && + info->CaErrorFlag == 0 && + info->CaDvbFlag == 1 && + info->CaModulePresentStatus == 1; +} + +static int fdtv_get_ca_flags(ANTENNA_INPUT_INFO *info) +{ + int flags = 0; + + if (info->CaModulePresentStatus == 1) + flags |= CA_CI_MODULE_PRESENT; + if (info->CaInitializationStatus == 1 && + info->CaErrorFlag == 0 && + info->CaDvbFlag == 1) + flags |= CA_CI_MODULE_READY; + return flags; +} + +static int fdtv_ca_reset(struct firedtv *fdtv) +{ + return avc_ca_reset(fdtv) ? -EFAULT : 0; +} + +static int fdtv_ca_get_caps(void *arg) +{ + struct ca_caps *cap = arg; + + cap->slot_num = 1; + cap->slot_type = CA_CI; + cap->descr_num = 1; + cap->descr_type = CA_ECD; + return 0; +} + +static int fdtv_ca_get_slot_info(struct firedtv *fdtv, void *arg) +{ + ANTENNA_INPUT_INFO info; + struct ca_slot_info *slot = arg; + + if (avc_tuner_status(fdtv, &info)) + return -EFAULT; + + if (slot->num != 0) + return -EFAULT; + + slot->type = CA_CI; + slot->flags = fdtv_get_ca_flags(&info); + return 0; +} + +static int fdtv_ca_app_info(struct firedtv *fdtv, void *arg) +{ + struct ca_msg *reply = arg; + + return + avc_ca_app_info(fdtv, reply->msg, &reply->length) ? -EFAULT : 0; +} + +static int fdtv_ca_info(struct firedtv *fdtv, void *arg) +{ + struct ca_msg *reply = arg; + + return avc_ca_info(fdtv, reply->msg, &reply->length) ? -EFAULT : 0; +} + +static int fdtv_ca_get_mmi(struct firedtv *fdtv, void *arg) +{ + struct ca_msg *reply = arg; + + return + avc_ca_get_mmi(fdtv, reply->msg, &reply->length) ? -EFAULT : 0; +} + +static int fdtv_ca_get_msg(struct firedtv *fdtv, void *arg) +{ + ANTENNA_INPUT_INFO info; + int err; + + switch (fdtv->ca_last_command) { + case TAG_APP_INFO_ENQUIRY: + err = fdtv_ca_app_info(fdtv, arg); + break; + case TAG_CA_INFO_ENQUIRY: + err = fdtv_ca_info(fdtv, arg); + break; + default: + if (avc_tuner_status(fdtv, &info)) + err = -EFAULT; + else if (info.CaMmi == 1) + err = fdtv_ca_get_mmi(fdtv, arg); + else { + printk(KERN_INFO "%s: Unhandled message 0x%08X\n", + __func__, fdtv->ca_last_command); + err = -EFAULT; + } + } + fdtv->ca_last_command = 0; + return err; +} + +static int fdtv_ca_pmt(struct firedtv *fdtv, void *arg) +{ + struct ca_msg *msg = arg; + int data_pos; + int data_length; + int i; + + data_pos = 4; + if (msg->msg[3] & 0x80) { + data_length = 0; + for (i = 0; i < (msg->msg[3] & 0x7F); i++) + data_length = (data_length << 8) + msg->msg[data_pos++]; + } else { + data_length = msg->msg[3]; + } + + return avc_ca_pmt(fdtv, &msg->msg[data_pos], data_length) ? + -EFAULT : 0; +} + +static int fdtv_ca_send_msg(struct firedtv *fdtv, void *arg) +{ + struct ca_msg *msg = arg; + int err; + + /* Do we need a semaphore for this? */ + fdtv->ca_last_command = + (msg->msg[0] << 16) + (msg->msg[1] << 8) + msg->msg[2]; + switch (fdtv->ca_last_command) { + case TAG_CA_PMT: + err = fdtv_ca_pmt(fdtv, arg); + break; + case TAG_APP_INFO_ENQUIRY: + /* handled in ca_get_msg */ + err = 0; + break; + case TAG_CA_INFO_ENQUIRY: + /* handled in ca_get_msg */ + err = 0; + break; + case TAG_ENTER_MENU: + err = avc_ca_enter_menu(fdtv); + break; + default: + printk(KERN_ERR "%s: Unhandled unknown message 0x%08X\n", + __func__, fdtv->ca_last_command); + err = -EFAULT; + } + return err; +} + +static int fdtv_ca_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, void *arg) +{ + struct dvb_device *dvbdev = file->private_data; + struct firedtv *fdtv = dvbdev->priv; + ANTENNA_INPUT_INFO info; + int err; + + switch(cmd) { + case CA_RESET: + err = fdtv_ca_reset(fdtv); + break; + case CA_GET_CAP: + err = fdtv_ca_get_caps(arg); + break; + case CA_GET_SLOT_INFO: + err = fdtv_ca_get_slot_info(fdtv, arg); + break; + case CA_GET_MSG: + err = fdtv_ca_get_msg(fdtv, arg); + break; + case CA_SEND_MSG: + err = fdtv_ca_send_msg(fdtv, arg); + break; + default: + printk(KERN_INFO "%s: Unhandled ioctl, command: %u\n",__func__, + cmd); + err = -EOPNOTSUPP; + } + + /* FIXME Is this necessary? */ + avc_tuner_status(fdtv, &info); + + return err; +} + +static unsigned int fdtv_ca_io_poll(struct file *file, poll_table *wait) +{ + return POLLIN; +} + +static struct file_operations fdtv_ca_fops = { + .owner = THIS_MODULE, + .ioctl = dvb_generic_ioctl, + .open = dvb_generic_open, + .release = dvb_generic_release, + .poll = fdtv_ca_io_poll, +}; + +static struct dvb_device fdtv_ca = { + .users = 1, + .readers = 1, + .writers = 1, + .fops = &fdtv_ca_fops, + .kernel_ioctl = fdtv_ca_ioctl, +}; + +int fdtv_ca_register(struct firedtv *fdtv) +{ + ANTENNA_INPUT_INFO info; + int err; + + if (avc_tuner_status(fdtv, &info)) + return -EINVAL; + + if (!fdtv_ca_ready(&info)) + return -EFAULT; + + err = dvb_register_device(&fdtv->adapter, &fdtv->cadev, + &fdtv_ca, fdtv, DVB_DEVICE_CA); + + if (info.CaApplicationInfo == 0) + printk(KERN_ERR "%s: CaApplicationInfo is not set.\n", + __func__); + if (info.CaDateTimeRequest == 1) + avc_ca_get_time_date(fdtv, &fdtv->ca_time_interval); + + return err; +} + +void fdtv_ca_release(struct firedtv *fdtv) +{ + if (fdtv->cadev) + dvb_unregister_device(fdtv->cadev); +} diff --git a/drivers/media/dvb/firewire/firedtv-ci.h b/drivers/media/dvb/firewire/firedtv-ci.h new file mode 100644 index 00000000000..d6840f5dcba --- /dev/null +++ b/drivers/media/dvb/firewire/firedtv-ci.h @@ -0,0 +1,9 @@ +#ifndef _FIREDTV_CI_H +#define _FIREDTV_CI_H + +struct firedtv; + +int fdtv_ca_register(struct firedtv *fdtv); +void fdtv_ca_release(struct firedtv *fdtv); + +#endif /* _FIREDTV_CI_H */ diff --git a/drivers/media/dvb/firewire/firedtv-dvb.c b/drivers/media/dvb/firewire/firedtv-dvb.c new file mode 100644 index 00000000000..1823058696f --- /dev/null +++ b/drivers/media/dvb/firewire/firedtv-dvb.c @@ -0,0 +1,276 @@ +/* + * FireDTV driver (formerly known as FireSAT) + * + * Copyright (C) 2004 Andreas Monitzer + * Copyright (C) 2008 Henrik Kurelid + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "avc.h" +#include "firedtv.h" +#include "firedtv-ci.h" + +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + +static struct firedtv_channel *fdtv_channel_allocate(struct firedtv *fdtv) +{ + struct firedtv_channel *c = NULL; + int k; + + if (mutex_lock_interruptible(&fdtv->demux_mutex)) + return NULL; + + for (k = 0; k < 16; k++) + if (!fdtv->channel[k].active) { + fdtv->channel[k].active = true; + c = &fdtv->channel[k]; + break; + } + + mutex_unlock(&fdtv->demux_mutex); + return c; +} + +static int fdtv_channel_collect(struct firedtv *fdtv, int *pidc, u16 pid[]) +{ + int k, l = 0; + + if (mutex_lock_interruptible(&fdtv->demux_mutex)) + return -EINTR; + + for (k = 0; k < 16; k++) + if (fdtv->channel[k].active) + pid[l++] = fdtv->channel[k].pid; + + mutex_unlock(&fdtv->demux_mutex); + + *pidc = l; + + return 0; +} + +static int fdtv_channel_release(struct firedtv *fdtv, + struct firedtv_channel *channel) +{ + if (mutex_lock_interruptible(&fdtv->demux_mutex)) + return -EINTR; + + channel->active = false; + + mutex_unlock(&fdtv->demux_mutex); + return 0; +} + +int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed) +{ + struct firedtv *fdtv = (struct firedtv*)dvbdmxfeed->demux->priv; + struct firedtv_channel *channel; + int pidc,k; + u16 pids[16]; + + switch (dvbdmxfeed->type) { + case DMX_TYPE_TS: + case DMX_TYPE_SEC: + break; + default: + printk(KERN_ERR "%s: invalid type %u\n", + __func__, dvbdmxfeed->type); + return -EINVAL; + } + + if (dvbdmxfeed->type == DMX_TYPE_TS) { + switch (dvbdmxfeed->pes_type) { + case DMX_TS_PES_VIDEO: + case DMX_TS_PES_AUDIO: + case DMX_TS_PES_TELETEXT: + case DMX_TS_PES_PCR: + case DMX_TS_PES_OTHER: + //Dirty fix to keep fdtv->channel pid-list up to date + for(k=0;k<16;k++){ + if (!fdtv->channel[k].active) + fdtv->channel[k].pid = + dvbdmxfeed->pid; + break; + } + channel = fdtv_channel_allocate(fdtv); + break; + default: + printk(KERN_ERR "%s: invalid pes type %u\n", + __func__, dvbdmxfeed->pes_type); + return -EINVAL; + } + } else { + channel = fdtv_channel_allocate(fdtv); + } + + if (!channel) { + printk(KERN_ERR "%s: busy!\n", __func__); + return -EBUSY; + } + + dvbdmxfeed->priv = channel; + channel->pid = dvbdmxfeed->pid; + + if (fdtv_channel_collect(fdtv, &pidc, pids)) { + fdtv_channel_release(fdtv, channel); + printk(KERN_ERR "%s: could not collect pids!\n", __func__); + return -EINTR; + } + + if (dvbdmxfeed->pid == 8192) { + k = avc_tuner_get_ts(fdtv); + if (k) { + fdtv_channel_release(fdtv, channel); + printk("%s: AVCTuner_GetTS failed with error %d\n", + __func__, k); + return k; + } + } else { + k = avc_tuner_set_pids(fdtv, pidc, pids); + if (k) { + fdtv_channel_release(fdtv, channel); + printk("%s: AVCTuner_SetPIDs failed with error %d\n", + __func__, k); + return k; + } + } + + return 0; +} + +int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed) +{ + struct dvb_demux *demux = dvbdmxfeed->demux; + struct firedtv *fdtv = (struct firedtv*)demux->priv; + struct firedtv_channel *c = dvbdmxfeed->priv; + int k, l; + u16 pids[16]; + + if (dvbdmxfeed->type == DMX_TYPE_TS && !((dvbdmxfeed->ts_type & TS_PACKET) && + (demux->dmx.frontend->source != DMX_MEMORY_FE))) { + + if (dvbdmxfeed->ts_type & TS_DECODER) { + + if (dvbdmxfeed->pes_type >= DMX_TS_PES_OTHER || + !demux->pesfilter[dvbdmxfeed->pes_type]) + + return -EINVAL; + + demux->pids[dvbdmxfeed->pes_type] |= 0x8000; + demux->pesfilter[dvbdmxfeed->pes_type] = NULL; + } + + if (!(dvbdmxfeed->ts_type & TS_DECODER && + dvbdmxfeed->pes_type < DMX_TS_PES_OTHER)) + + return 0; + } + + if (mutex_lock_interruptible(&fdtv->demux_mutex)) + return -EINTR; + + /* list except channel to be removed */ + for (k = 0, l = 0; k < 16; k++) + if (fdtv->channel[k].active) { + if (&fdtv->channel[k] != c) + pids[l++] = fdtv->channel[k].pid; + else + fdtv->channel[k].active = false; + } + + k = avc_tuner_set_pids(fdtv, l, pids); + if (!k) + c->active = false; + + mutex_unlock(&fdtv->demux_mutex); + return k; +} + +int fdtv_dvbdev_init(struct firedtv *fdtv, struct device *dev) +{ + int err; + + err = DVB_REGISTER_ADAPTER(&fdtv->adapter, + fdtv_model_names[fdtv->type], + THIS_MODULE, dev, adapter_nr); + if (err < 0) + goto fail_log; + + /*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/ + fdtv->demux.dmx.capabilities = 0; + + fdtv->demux.priv = fdtv; + fdtv->demux.filternum = 16; + fdtv->demux.feednum = 16; + fdtv->demux.start_feed = fdtv_start_feed; + fdtv->demux.stop_feed = fdtv_stop_feed; + fdtv->demux.write_to_decoder = NULL; + + err = dvb_dmx_init(&fdtv->demux); + if (err) + goto fail_unreg_adapter; + + fdtv->dmxdev.filternum = 16; + fdtv->dmxdev.demux = &fdtv->demux.dmx; + fdtv->dmxdev.capabilities = 0; + + err = dvb_dmxdev_init(&fdtv->dmxdev, &fdtv->adapter); + if (err) + goto fail_dmx_release; + + fdtv->frontend.source = DMX_FRONTEND_0; + + err = fdtv->demux.dmx.add_frontend(&fdtv->demux.dmx, + &fdtv->frontend); + if (err) + goto fail_dmxdev_release; + + err = fdtv->demux.dmx.connect_frontend(&fdtv->demux.dmx, + &fdtv->frontend); + if (err) + goto fail_rem_frontend; + + dvb_net_init(&fdtv->adapter, &fdtv->dvbnet, &fdtv->demux.dmx); + + fdtv_frontend_init(fdtv); + err = dvb_register_frontend(&fdtv->adapter, &fdtv->fe); + if (err) + goto fail_net_release; + + err = fdtv_ca_register(fdtv); + if (err) + dev_info(dev, "Conditional Access Module not enabled\n"); + + return 0; + +fail_net_release: + dvb_net_release(&fdtv->dvbnet); + fdtv->demux.dmx.close(&fdtv->demux.dmx); +fail_rem_frontend: + fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, + &fdtv->frontend); +fail_dmxdev_release: + dvb_dmxdev_release(&fdtv->dmxdev); +fail_dmx_release: + dvb_dmx_release(&fdtv->demux); +fail_unreg_adapter: + dvb_unregister_adapter(&fdtv->adapter); +fail_log: + dev_err(dev, "DVB initialization failed\n"); + return err; +} + + diff --git a/drivers/media/dvb/firewire/firedtv-fe.c b/drivers/media/dvb/firewire/firedtv-fe.c new file mode 100644 index 00000000000..f8150f402bb --- /dev/null +++ b/drivers/media/dvb/firewire/firedtv-fe.c @@ -0,0 +1,245 @@ +/* + * FireDTV driver (formerly known as FireSAT) + * + * Copyright (C) 2004 Andreas Monitzer + * Copyright (C) 2008 Henrik Kurelid + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#include +#include +#include +#include + +#include + +#include "avc.h" +#include "cmp.h" +#include "firedtv.h" + +static int fdtv_dvb_init(struct dvb_frontend *fe) +{ + struct firedtv *fdtv = fe->sec_priv; + int err; + + /* FIXME - allocate free channel at IRM */ + fdtv->isochannel = fdtv->adapter.num; + + err = cmp_establish_pp_connection(fdtv, fdtv->subunit, + fdtv->isochannel); + if (err) { + printk(KERN_ERR "Could not establish point to point " + "connection.\n"); + return err; + } + + return setup_iso_channel(fdtv); +} + +static int fdtv_sleep(struct dvb_frontend *fe) +{ + struct firedtv *fdtv = fe->sec_priv; + + tear_down_iso_channel(fdtv); + cmp_break_pp_connection(fdtv, fdtv->subunit, fdtv->isochannel); + fdtv->isochannel = -1; + return 0; +} + +static int fdtv_diseqc_send_master_cmd(struct dvb_frontend *fe, + struct dvb_diseqc_master_cmd *cmd) +{ + struct firedtv *fdtv = fe->sec_priv; + + return avc_lnb_control(fdtv, LNBCONTROL_DONTCARE, + LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, 1, cmd); +} + +static int fdtv_diseqc_send_burst(struct dvb_frontend *fe, + fe_sec_mini_cmd_t minicmd) +{ + return 0; +} + +static int fdtv_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) +{ + struct firedtv *fdtv = fe->sec_priv; + + fdtv->tone = tone; + return 0; +} + +static int fdtv_set_voltage(struct dvb_frontend *fe, + fe_sec_voltage_t voltage) +{ + struct firedtv *fdtv = fe->sec_priv; + + fdtv->voltage = voltage; + return 0; +} + +static int fdtv_read_status(struct dvb_frontend *fe, fe_status_t *status) +{ + struct firedtv *fdtv = fe->sec_priv; + ANTENNA_INPUT_INFO info; + + if (avc_tuner_status(fdtv, &info)) + return -EINVAL; + + if (info.NoRF) + *status = 0; + else + *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | FE_HAS_SYNC | + FE_HAS_CARRIER | FE_HAS_LOCK; + return 0; +} + +static int fdtv_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + struct firedtv *fdtv = fe->sec_priv; + ANTENNA_INPUT_INFO info; + + if (avc_tuner_status(fdtv, &info)) + return -EINVAL; + + *ber = info.BER[0] << 24 | info.BER[1] << 16 | + info.BER[2] << 8 | info.BER[3]; + return 0; +} + +static int fdtv_read_signal_strength (struct dvb_frontend *fe, u16 *strength) +{ + struct firedtv *fdtv = fe->sec_priv; + ANTENNA_INPUT_INFO info; + + if (avc_tuner_status(fdtv, &info)) + return -EINVAL; + + *strength = info.SignalStrength << 8; + return 0; +} + +static int fdtv_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + struct firedtv *fdtv = fe->sec_priv; + ANTENNA_INPUT_INFO info; + + if (avc_tuner_status(fdtv, &info)) + return -EINVAL; + + /* C/N[dB] = -10 * log10(snr / 65535) */ + *snr = (info.CarrierNoiseRatio[0] << 8) + info.CarrierNoiseRatio[1]; + *snr *= 257; + return 0; +} + +static int fdtv_read_uncorrected_blocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + return -EOPNOTSUPP; +} + +static int fdtv_set_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) +{ + struct firedtv *fdtv = fe->sec_priv; + + /* FIXME: avc_tuner_dsd never returns ACCEPTED. Check status? */ + if (avc_tuner_dsd(fdtv, params) != ACCEPTED) + return -EINVAL; + else + return 0; /* not sure of this... */ +} + +static int fdtv_get_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) +{ + return -EOPNOTSUPP; +} + +void fdtv_frontend_init(struct firedtv *fdtv) +{ + struct dvb_frontend_ops *ops = &fdtv->fe.ops; + struct dvb_frontend_info *fi = &ops->info; + + ops->init = fdtv_dvb_init; + ops->sleep = fdtv_sleep; + + ops->set_frontend = fdtv_set_frontend; + ops->get_frontend = fdtv_get_frontend; + + ops->read_status = fdtv_read_status; + ops->read_ber = fdtv_read_ber; + ops->read_signal_strength = fdtv_read_signal_strength; + ops->read_snr = fdtv_read_snr; + ops->read_ucblocks = fdtv_read_uncorrected_blocks; + + ops->diseqc_send_master_cmd = fdtv_diseqc_send_master_cmd; + ops->diseqc_send_burst = fdtv_diseqc_send_burst; + ops->set_tone = fdtv_set_tone; + ops->set_voltage = fdtv_set_voltage; + + switch (fdtv->type) { + case FIREDTV_DVB_S: + fi->type = FE_QPSK; + + fi->frequency_min = 950000; + fi->frequency_max = 2150000; + fi->frequency_stepsize = 125; + fi->symbol_rate_min = 1000000; + fi->symbol_rate_max = 40000000; + + fi->caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_1_2 | + FE_CAN_FEC_2_3 | + FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | + FE_CAN_FEC_7_8 | + FE_CAN_FEC_AUTO | + FE_CAN_QPSK; + break; + + case FIREDTV_DVB_C: + fi->type = FE_QAM; + + fi->frequency_min = 47000000; + fi->frequency_max = 866000000; + fi->frequency_stepsize = 62500; + fi->symbol_rate_min = 870000; + fi->symbol_rate_max = 6900000; + + fi->caps = FE_CAN_INVERSION_AUTO | + FE_CAN_QAM_16 | + FE_CAN_QAM_32 | + FE_CAN_QAM_64 | + FE_CAN_QAM_128 | + FE_CAN_QAM_256 | + FE_CAN_QAM_AUTO; + break; + + case FIREDTV_DVB_T: + fi->type = FE_OFDM; + + fi->frequency_min = 49000000; + fi->frequency_max = 861000000; + fi->frequency_stepsize = 62500; + + fi->caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_2_3 | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_HIERARCHY_AUTO; + break; + + default: + printk(KERN_ERR "FireDTV: no frontend for model type %d\n", + fdtv->type); + } + strcpy(fi->name, fdtv_model_names[fdtv->type]); + + fdtv->fe.dvb = &fdtv->adapter; + fdtv->fe.sec_priv = fdtv; +} diff --git a/drivers/media/dvb/firewire/firedtv-iso.c b/drivers/media/dvb/firewire/firedtv-iso.c new file mode 100644 index 00000000000..a72df228e7d --- /dev/null +++ b/drivers/media/dvb/firewire/firedtv-iso.c @@ -0,0 +1,111 @@ +/* + * FireSAT DVB driver + * + * Copyright (C) 2008 Henrik Kurelid + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "firedtv.h" + +static void rawiso_activity_cb(struct hpsb_iso *iso); + +void tear_down_iso_channel(struct firedtv *fdtv) +{ + if (fdtv->iso_handle != NULL) { + hpsb_iso_stop(fdtv->iso_handle); + hpsb_iso_shutdown(fdtv->iso_handle); + } + fdtv->iso_handle = NULL; +} + +int setup_iso_channel(struct firedtv *fdtv) +{ + int result; + fdtv->iso_handle = + hpsb_iso_recv_init(fdtv->ud->ne->host, + 256 * 200, //data_buf_size, + 256, //buf_packets, + fdtv->isochannel, + HPSB_ISO_DMA_DEFAULT, //dma_mode, + -1, //stat.config.irq_interval, + rawiso_activity_cb); + if (fdtv->iso_handle == NULL) { + printk(KERN_ERR "Cannot initialize iso receive.\n"); + return -EINVAL; + } + result = hpsb_iso_recv_start(fdtv->iso_handle, -1, -1, 0); + if (result != 0) { + printk(KERN_ERR "Cannot start iso receive.\n"); + return -EINVAL; + } + return 0; +} + +static void rawiso_activity_cb(struct hpsb_iso *iso) +{ + unsigned int num; + unsigned int i; + unsigned int packet; + unsigned long flags; + struct firedtv *fdtv = NULL; + struct firedtv *fdtv_iterator; + + spin_lock_irqsave(&fdtv_list_lock, flags); + list_for_each_entry(fdtv_iterator, &fdtv_list, list) { + if(fdtv_iterator->iso_handle == iso) { + fdtv = fdtv_iterator; + break; + } + } + spin_unlock_irqrestore(&fdtv_list_lock, flags); + + if (fdtv) { + packet = iso->first_packet; + num = hpsb_iso_n_ready(iso); + for (i = 0; i < num; i++, + packet = (packet + 1) % iso->buf_packets) { + unsigned char *buf = + dma_region_i(&iso->data_buf, unsigned char, + iso->infos[packet].offset + + sizeof(struct CIPHeader)); + int count = (iso->infos[packet].len - + sizeof(struct CIPHeader)) / + (188 + sizeof(struct firewireheader)); + if (iso->infos[packet].len <= sizeof(struct CIPHeader)) + continue; // ignore empty packet + + while (count --) { + if (buf[sizeof(struct firewireheader)] == 0x47) + dvb_dmx_swfilter_packets(&fdtv->demux, + &buf[sizeof(struct firewireheader)], 1); + else + printk("%s: invalid packet, skipping\n", __func__); + buf += 188 + sizeof(struct firewireheader); + + } + + } + hpsb_iso_recv_release_packets(iso, num); + } + else { + printk("%s: packets for unknown iso channel, skipping\n", + __func__); + hpsb_iso_recv_release_packets(iso, hpsb_iso_n_ready(iso)); + } +} + diff --git a/drivers/media/dvb/firewire/firedtv-rc.c b/drivers/media/dvb/firewire/firedtv-rc.c new file mode 100644 index 00000000000..436c0c69a13 --- /dev/null +++ b/drivers/media/dvb/firewire/firedtv-rc.c @@ -0,0 +1,191 @@ +/* + * FireDTV driver (formerly known as FireSAT) + * + * Copyright (C) 2004 Andreas Monitzer + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include + +#include "firedtv-rc.h" +#include "firedtv.h" + +/* fixed table with older keycodes, geared towards MythTV */ +const static u16 oldtable[] = { + + /* code from device: 0x4501...0x451f */ + + KEY_ESC, + KEY_F9, + KEY_1, + KEY_2, + KEY_3, + KEY_4, + KEY_5, + KEY_6, + KEY_7, + KEY_8, + KEY_9, + KEY_I, + KEY_0, + KEY_ENTER, + KEY_RED, + KEY_UP, + KEY_GREEN, + KEY_F10, + KEY_SPACE, + KEY_F11, + KEY_YELLOW, + KEY_DOWN, + KEY_BLUE, + KEY_Z, + KEY_P, + KEY_PAGEDOWN, + KEY_LEFT, + KEY_W, + KEY_RIGHT, + KEY_P, + KEY_M, + + /* code from device: 0x4540...0x4542 */ + + KEY_R, + KEY_V, + KEY_C, +}; + +/* user-modifiable table for a remote as sold in 2008 */ +const static u16 keytable[] = { + + /* code from device: 0x0300...0x031f */ + + [0x00] = KEY_POWER, + [0x01] = KEY_SLEEP, + [0x02] = KEY_STOP, + [0x03] = KEY_OK, + [0x04] = KEY_RIGHT, + [0x05] = KEY_1, + [0x06] = KEY_2, + [0x07] = KEY_3, + [0x08] = KEY_LEFT, + [0x09] = KEY_4, + [0x0a] = KEY_5, + [0x0b] = KEY_6, + [0x0c] = KEY_UP, + [0x0d] = KEY_7, + [0x0e] = KEY_8, + [0x0f] = KEY_9, + [0x10] = KEY_DOWN, + [0x11] = KEY_TITLE, /* "OSD" - fixme */ + [0x12] = KEY_0, + [0x13] = KEY_F20, /* "16:9" - fixme */ + [0x14] = KEY_SCREEN, /* "FULL" - fixme */ + [0x15] = KEY_MUTE, + [0x16] = KEY_SUBTITLE, + [0x17] = KEY_RECORD, + [0x18] = KEY_TEXT, + [0x19] = KEY_AUDIO, + [0x1a] = KEY_RED, + [0x1b] = KEY_PREVIOUS, + [0x1c] = KEY_REWIND, + [0x1d] = KEY_PLAYPAUSE, + [0x1e] = KEY_NEXT, + [0x1f] = KEY_VOLUMEUP, + + /* code from device: 0x0340...0x0354 */ + + [0x20] = KEY_CHANNELUP, + [0x21] = KEY_F21, /* "4:3" - fixme */ + [0x22] = KEY_TV, + [0x23] = KEY_DVD, + [0x24] = KEY_VCR, + [0x25] = KEY_AUX, + [0x26] = KEY_GREEN, + [0x27] = KEY_YELLOW, + [0x28] = KEY_BLUE, + [0x29] = KEY_CHANNEL, /* "CH.LIST" */ + [0x2a] = KEY_VENDOR, /* "CI" - fixme */ + [0x2b] = KEY_VOLUMEDOWN, + [0x2c] = KEY_CHANNELDOWN, + [0x2d] = KEY_LAST, + [0x2e] = KEY_INFO, + [0x2f] = KEY_FORWARD, + [0x30] = KEY_LIST, + [0x31] = KEY_FAVORITES, + [0x32] = KEY_MENU, + [0x33] = KEY_EPG, + [0x34] = KEY_EXIT, +}; + +int fdtv_register_rc(struct firedtv *fdtv, struct device *dev) +{ + struct input_dev *idev; + int i, err; + + idev = input_allocate_device(); + if (!idev) + return -ENOMEM; + + fdtv->remote_ctrl_dev = idev; + idev->name = "FireDTV remote control"; + idev->dev.parent = dev; + idev->evbit[0] = BIT_MASK(EV_KEY); + idev->keycode = kmemdup(keytable, sizeof(keytable), GFP_KERNEL); + if (!idev->keycode) { + err = -ENOMEM; + goto fail; + } + idev->keycodesize = sizeof(keytable[0]); + idev->keycodemax = ARRAY_SIZE(keytable); + + for (i = 0; i < ARRAY_SIZE(keytable); i++) + set_bit(keytable[i], idev->keybit); + + err = input_register_device(idev); + if (err) + goto fail_free_keymap; + + return 0; + +fail_free_keymap: + kfree(idev->keycode); +fail: + input_free_device(idev); + return err; +} + +void fdtv_unregister_rc(struct firedtv *fdtv) +{ + kfree(fdtv->remote_ctrl_dev->keycode); + input_unregister_device(fdtv->remote_ctrl_dev); +} + +void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code) +{ + u16 *keycode = fdtv->remote_ctrl_dev->keycode; + + if (code >= 0x0300 && code <= 0x031f) + code = keycode[code - 0x0300]; + else if (code >= 0x0340 && code <= 0x0354) + code = keycode[code - 0x0320]; + else if (code >= 0x4501 && code <= 0x451f) + code = oldtable[code - 0x4501]; + else if (code >= 0x4540 && code <= 0x4542) + code = oldtable[code - 0x4521]; + else { + printk(KERN_DEBUG "firedtv: invalid key code 0x%04x " + "from remote control\n", code); + return; + } + + input_report_key(fdtv->remote_ctrl_dev, code, 1); + input_report_key(fdtv->remote_ctrl_dev, code, 0); +} diff --git a/drivers/media/dvb/firewire/firedtv-rc.h b/drivers/media/dvb/firewire/firedtv-rc.h new file mode 100644 index 00000000000..d3e14727d3d --- /dev/null +++ b/drivers/media/dvb/firewire/firedtv-rc.h @@ -0,0 +1,11 @@ +#ifndef _FIREDTV_RC_H +#define _FIREDTV_RC_H + +struct firedtv; +struct device; + +int fdtv_register_rc(struct firedtv *fdtv, struct device *dev); +void fdtv_unregister_rc(struct firedtv *fdtv); +void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code); + +#endif /* _FIREDTV_RC_H */ diff --git a/drivers/media/dvb/firewire/firedtv.h b/drivers/media/dvb/firewire/firedtv.h new file mode 100644 index 00000000000..2a34028ccbc --- /dev/null +++ b/drivers/media/dvb/firewire/firedtv.h @@ -0,0 +1,227 @@ +/* + * FireDTV driver (formerly known as FireSAT) + * + * Copyright (C) 2004 Andreas Monitzer + * Copyright (C) 2008 Henrik Kurelid + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#ifndef _FIREDTV_H +#define _FIREDTV_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25) +#define DVB_REGISTER_ADAPTER(x, y, z, w, v) dvb_register_adapter(x, y, z, w, v) +#else +#define DVB_REGISTER_ADAPTER(x, y, z, w, v) dvb_register_adapter(x, y, z, w) +#define DVB_DEFINE_MOD_OPT_ADAPTER_NR(x) +#endif + +/***************************************************************** + * CA message command constants from en50221_app_tags.h of libdvb + *****************************************************************/ +/* Resource Manager */ +#define TAG_PROFILE_ENQUIRY 0x9f8010 +#define TAG_PROFILE 0x9f8011 +#define TAG_PROFILE_CHANGE 0x9f8012 + +/* Application Info */ +#define TAG_APP_INFO_ENQUIRY 0x9f8020 +#define TAG_APP_INFO 0x9f8021 +#define TAG_ENTER_MENU 0x9f8022 + +/* CA Support */ +#define TAG_CA_INFO_ENQUIRY 0x9f8030 +#define TAG_CA_INFO 0x9f8031 +#define TAG_CA_PMT 0x9f8032 +#define TAG_CA_PMT_REPLY 0x9f8033 + +/* Host Control */ +#define TAG_TUNE 0x9f8400 +#define TAG_REPLACE 0x9f8401 +#define TAG_CLEAR_REPLACE 0x9f8402 +#define TAG_ASK_RELEASE 0x9f8403 + +/* Date and Time */ +#define TAG_DATE_TIME_ENQUIRY 0x9f8440 +#define TAG_DATE_TIME 0x9f8441 + +/* Man Machine Interface (MMI) */ +#define TAG_CLOSE_MMI 0x9f8800 +#define TAG_DISPLAY_CONTROL 0x9f8801 +#define TAG_DISPLAY_REPLY 0x9f8802 +#define TAG_TEXT_LAST 0x9f8803 +#define TAG_TEXT_MORE 0x9f8804 +#define TAG_KEYPAD_CONTROL 0x9f8805 +#define TAG_KEYPRESS 0x9f8806 +#define TAG_ENQUIRY 0x9f8807 +#define TAG_ANSWER 0x9f8808 +#define TAG_MENU_LAST 0x9f8809 +#define TAG_MENU_MORE 0x9f880a +#define TAG_MENU_ANSWER 0x9f880b +#define TAG_LIST_LAST 0x9f880c +#define TAG_LIST_MORE 0x9f880d +#define TAG_SUBTITLE_SEGMENT_LAST 0x9f880e +#define TAG_SUBTITLE_SEGMENT_MORE 0x9f880f +#define TAG_DISPLAY_MESSAGE 0x9f8810 +#define TAG_SCENE_END_MARK 0x9f8811 +#define TAG_SCENE_DONE 0x9f8812 +#define TAG_SCENE_CONTROL 0x9f8813 +#define TAG_SUBTITLE_DOWNLOAD_LAST 0x9f8814 +#define TAG_SUBTITLE_DOWNLOAD_MORE 0x9f8815 +#define TAG_FLUSH_DOWNLOAD 0x9f8816 +#define TAG_DOWNLOAD_REPLY 0x9f8817 + +/* Low Speed Communications */ +#define TAG_COMMS_COMMAND 0x9f8c00 +#define TAG_CONNECTION_DESCRIPTOR 0x9f8c01 +#define TAG_COMMS_REPLY 0x9f8c02 +#define TAG_COMMS_SEND_LAST 0x9f8c03 +#define TAG_COMMS_SEND_MORE 0x9f8c04 +#define TAG_COMMS_RECV_LAST 0x9f8c05 +#define TAG_COMMS_RECV_MORE 0x9f8c06 + +/* Authentication */ +#define TAG_AUTH_REQ 0x9f8200 +#define TAG_AUTH_RESP 0x9f8201 + +/* Teletext */ +#define TAG_TELETEXT_EBU 0x9f9000 + +/* Smartcard */ +#define TAG_SMARTCARD_COMMAND 0x9f8e00 +#define TAG_SMARTCARD_REPLY 0x9f8e01 +#define TAG_SMARTCARD_SEND 0x9f8e02 +#define TAG_SMARTCARD_RCV 0x9f8e03 + +/* EPG */ +#define TAG_EPG_ENQUIRY 0x9f8f00 +#define TAG_EPG_REPLY 0x9f8f01 + + +enum model_type { + FIREDTV_UNKNOWN = 0, + FIREDTV_DVB_S = 1, + FIREDTV_DVB_C = 2, + FIREDTV_DVB_T = 3, + FIREDTV_DVB_S2 = 4, +}; + +struct input_dev; +struct hpsb_iso; +struct unit_directory; + +struct firedtv { + struct dvb_adapter adapter; + struct dmxdev dmxdev; + struct dvb_demux demux; + struct dmx_frontend frontend; + struct dvb_net dvbnet; + struct dvb_frontend fe; + + struct dvb_device *cadev; + int ca_last_command; + int ca_time_interval; + + struct mutex avc_mutex; + wait_queue_head_t avc_wait; + bool avc_reply_received; + struct work_struct remote_ctrl_work; + struct input_dev *remote_ctrl_dev; + + struct firedtv_channel { + bool active; + int pid; + } channel[16]; + struct mutex demux_mutex; + + struct unit_directory *ud; + + enum model_type type; + char subunit; + fe_sec_voltage_t voltage; + fe_sec_tone_mode_t tone; + + int isochannel; + struct hpsb_iso *iso_handle; + + struct list_head list; + + /* needed by avc_api */ + int resp_length; + u8 respfrm[512]; +}; + +struct firewireheader { + union { + struct { + __u8 tcode:4; + __u8 sy:4; + __u8 tag:2; + __u8 channel:6; + + __u8 length_l; + __u8 length_h; + } hdr; + __u32 val; + }; +}; + +struct CIPHeader { + union { + struct { + __u8 syncbits:2; + __u8 sid:6; + __u8 dbs; + __u8 fn:2; + __u8 qpc:3; + __u8 sph:1; + __u8 rsv:2; + __u8 dbc; + __u8 syncbits2:2; + __u8 fmt:6; + __u32 fdf:24; + } cip; + __u64 val; + }; +}; + +extern const char *fdtv_model_names[]; +extern struct list_head fdtv_list; +extern spinlock_t fdtv_list_lock; + +struct device; + +/* firedtv-dvb.c */ +int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed); +int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed); +int fdtv_dvbdev_init(struct firedtv *fdtv, struct device *dev); + +/* firedtv-fe.c */ +void fdtv_frontend_init(struct firedtv *fdtv); + +/* firedtv-iso.c */ +int setup_iso_channel(struct firedtv *fdtv); +void tear_down_iso_channel(struct firedtv *fdtv); + +#endif /* _FIREDTV_H */ -- cgit From 154907957f9391b1af997b57507b16c018cc4995 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Mon, 23 Feb 2009 14:21:10 +0100 Subject: firedtv: massive refactoring Combination of the following changes: Mon, 23 Feb 2009 14:21:10 +0100 (CET) firedtv: reinstate debug logging option Henrik Kurelid tells me that FCP debug logging (which I removed during cleanups) is still useful when working on driver issues together with end users. So bring it back in an updated form with only 60% of the original code footprint. Logging can be enabled with # echo -1 > /sys/module/firedtv/parameters/debug 1 instead of -1 enables only FCP header logging, 2 instead of -1 enables only hexdumps of the entire FCP frames. 0 switches logging off again. Fri, 20 Feb 2009 20:54:27 +0100 (CET) firedtv: build fix for INPUT=m and DVB_FIREDTV=y Thu, 19 Feb 2009 20:40:39 +0100 firedtv: use msecs_to_jiffies Pointed out by Mauro Carvalho Chehab. Sun Feb 15 20:50:46 CET 2009 firedtv: some more housekeeping Fix an old checkpatch warning and a new compiler warning. Sun Feb 15 15:33:17 CET 2009 firedtv: rename a file once more At the moment, about a third of avc.c is specific to FireDTVs rather than generic AV/C code. Rename it to firedtv-avc.c. Sun Feb 15 15:33:17 CET 2009 firedtv: dvb demux: more compact channels backing store Replace struct firedtv_channel { bool active; int pid; } channel[16]; by unsigned long channel_active; u16 channel_pid[16];. Sun Feb 15 15:33:17 CET 2009 firedtv: dvb demux: some simplifications c->active was unnecessarily cleared twice. Also, by marking the channel inactive before the for loop, the loop becomes identical with fdtv_channel_collect(). Sun Feb 15 15:33:17 CET 2009 firedtv: dvb demux: remove a bogus loop This loop is unnecessary because - only active channel[].pid's will be sent to the device, - when a channel is activated, its pid is set to dvbdmxfeed->pid. Perhaps the original code was there because it was initially not fully covered by the fdtv->demux_mutex. Sun Feb 15 15:33:17 CET 2009 firedtv: dvb demux: fix mutex protection fdtv_start_feed() accessed the channel list unsafely. Fully serialize it with itself and fdtv_stop_feed(). Sun Feb 15 15:33:17 CET 2009 firedtv: dvb demux: fix missing braces Original code was: ... case DMX_TS_PES_OTHER: //Dirty fix to keep firesat->channel pid-list up to date for(k=0;k<16;k++){ if(firesat->channel[k].active == 0) firesat->channel[k].pid = dvbdmxfeed->pid; break; } channel = firesat_channel_allocate(firesat); break; default: ... Looks bogus in several respects. For now let's just add braces to the if because that seems to be what the author meant. Sun Feb 15 15:33:17 CET 2009 firedtv: allow build without input subsystem !CONFIG_INPUT is very unlikely on systems on which firedtv is of interest. But we can easily support it. Sun Feb 15 15:33:17 CET 2009 firedtv: replace EXTRA_CFLAGS by ccflags The former are deprecated. The latter can depend on Kconfig variables. Sun Feb 15 15:33:17 CET 2009 firedtv: concentrate ieee1394 dependencies Move the entire interface with drivers/ieee1394 to firedtv-1394.c. Move 1394-independent module initialization code to firedtv-dvb.c. This prepares interfacing with drivers/firewire. Sun Feb 15 15:33:17 CET 2009 firedtv: amend Kconfig menu prompt Sun Feb 15 15:33:17 CET 2009 firedtv: remove kernel version compatibility macro Sun Feb 15 15:33:17 CET 2009 firedtv: combine header files avc.h and firedtv-*.h are small and currently not shared with other drivers, hence concatenate them all into firedtv.h. Sun Feb 15 15:33:17 CET 2009 firedtv: misc style touch-ups Standardize on lower-case hexadecimal constants. Adjust whitespace. Omit unnecessary pointer type casts and an unnecessary list head initialization. Use dev_printk. Wed Feb 11 21:21:04 CET 2009 firedtv: avc, ci: remove unused constants Wed Feb 11 21:21:04 CET 2009 firedtv: avc: remove bitfields from read descriptor response operands Don't use bitfields in struct types of on-the-wire data. Wed Feb 11 21:21:04 CET 2009 firedtv: avc: remove bitfields from DSD command operands Don't use bitfields in struct types of on-the-wire data. Wed Feb 11 21:21:04 CET 2009 firedtv: avc: header file cleanup Remove unused constants and declarations. Move privately used constants into .c files. Wed Feb 11 21:21:04 CET 2009 firedtv: avc: remove bitfields from FCP frame types Don't use bitfields in struct types of on-the-wire data. Also move many privately used constants from avc.h to avc.c and remove some unused constants. Sun, 18 Jan 2009 16:30:00 +0100 (CET) firedtv: avc: fix offset in avc_tuner_get_ts The parentheses were wrong. It didn't matter though because this code only writes a 0 into an area which is already initialized to 0. Sun, 18 Jan 2009 16:30:00 +0100 (CET) firedtv: avc: reduce stack usage, remove two typedefs It is safe to share a memory buffer for command frame and response frame because the response data come in after the command frame was last used. Even less stack would be required if only the actual required frame size instead of the entire FCP register size was allocated. Also, rename the defined types AVCCmdFrm and AVCRspFrm to struct avc_command_frame and struct avc_response_frame. TODO: Remove the bitfields in these types. Sun, 18 Jan 2009 16:30:00 +0100 (CET) firedtv: cmp: move code to avc Sun, 18 Jan 2009 16:30:00 +0100 (CET) firedtv: iso: move code to firedtv-1394 Sun, 18 Jan 2009 16:30:00 +0100 (CET) firedtv: iso: remove unnecessary struct type definitions Sun, 18 Jan 2009 16:30:00 +0100 (CET) firedtv: iso: style changes and fixlets Add cleanup after failure in setup_iso_channel. Replace printk() by dv_err(). Decrease indentation level in rawiso_activity_cb(). Signed-off-by: Stefan Richter --- drivers/media/dvb/Kconfig | 2 + drivers/media/dvb/firewire/Kconfig | 26 +- drivers/media/dvb/firewire/Makefile | 17 +- drivers/media/dvb/firewire/avc.c | 1051 ----------------------- drivers/media/dvb/firewire/avc.h | 432 ---------- drivers/media/dvb/firewire/cmp.c | 171 ---- drivers/media/dvb/firewire/cmp.h | 9 - drivers/media/dvb/firewire/firedtv-1394.c | 332 ++++---- drivers/media/dvb/firewire/firedtv-avc.c | 1315 +++++++++++++++++++++++++++++ drivers/media/dvb/firewire/firedtv-ci.c | 93 +- drivers/media/dvb/firewire/firedtv-ci.h | 9 - drivers/media/dvb/firewire/firedtv-dvb.c | 328 ++++--- drivers/media/dvb/firewire/firedtv-fe.c | 61 +- drivers/media/dvb/firewire/firedtv-iso.c | 111 --- drivers/media/dvb/firewire/firedtv-rc.c | 1 - drivers/media/dvb/firewire/firedtv-rc.h | 11 - drivers/media/dvb/firewire/firedtv.h | 257 +++--- 17 files changed, 1895 insertions(+), 2331 deletions(-) delete mode 100644 drivers/media/dvb/firewire/avc.c delete mode 100644 drivers/media/dvb/firewire/avc.h delete mode 100644 drivers/media/dvb/firewire/cmp.c delete mode 100644 drivers/media/dvb/firewire/cmp.h create mode 100644 drivers/media/dvb/firewire/firedtv-avc.c delete mode 100644 drivers/media/dvb/firewire/firedtv-ci.h delete mode 100644 drivers/media/dvb/firewire/firedtv-iso.c delete mode 100644 drivers/media/dvb/firewire/firedtv-rc.h diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig index 5a74c5c62f1..b0198691892 100644 --- a/drivers/media/dvb/Kconfig +++ b/drivers/media/dvb/Kconfig @@ -51,6 +51,8 @@ comment "Supported SDMC DM1105 Adapters" depends on DVB_CORE && PCI && I2C source "drivers/media/dvb/dm1105/Kconfig" +comment "Supported FireWire (IEEE 1394) Adapters" + depends on DVB_CORE && IEEE1394 source "drivers/media/dvb/firewire/Kconfig" comment "Supported DVB Frontends" diff --git a/drivers/media/dvb/firewire/Kconfig b/drivers/media/dvb/firewire/Kconfig index 03d25ad1035..69028253e98 100644 --- a/drivers/media/dvb/firewire/Kconfig +++ b/drivers/media/dvb/firewire/Kconfig @@ -1,12 +1,22 @@ config DVB_FIREDTV - tristate "FireDTV (FireWire attached DVB receivers)" - depends on DVB_CORE && IEEE1394 && INPUT + tristate "FireDTV and FloppyDTV" + depends on DVB_CORE && IEEE1394 help - Support for DVB receivers from Digital Everywhere, known as FireDTV - and FloppyDTV, which are connected via IEEE 1394 (FireWire). + Support for DVB receivers from Digital Everywhere + which are connected via IEEE 1394 (FireWire). - These devices don't have an MPEG decoder built in, so you need - an external software decoder to watch TV. + These devices don't have an MPEG decoder built in, + so you need an external software decoder to watch TV. - To compile this driver as a module, say M here: the module will be - called firedtv. + To compile this driver as a module, say M here: + the module will be called firedtv. + +if DVB_FIREDTV + +config DVB_FIREDTV_IEEE1394 + def_bool IEEE1394 + +config DVB_FIREDTV_INPUT + def_bool INPUT = y || (INPUT = m && DVB_FIREDTV = m) + +endif # DVB_FIREDTV diff --git a/drivers/media/dvb/firewire/Makefile b/drivers/media/dvb/firewire/Makefile index 628dacd10da..2034695ba19 100644 --- a/drivers/media/dvb/firewire/Makefile +++ b/drivers/media/dvb/firewire/Makefile @@ -1,13 +1,8 @@ -firedtv-objs := firedtv-1394.o \ - firedtv-dvb.o \ - firedtv-fe.o \ - firedtv-iso.o \ - avc.o \ - cmp.o \ - firedtv-rc.o \ - firedtv-ci.o - obj-$(CONFIG_DVB_FIREDTV) += firedtv.o -EXTRA_CFLAGS := -Idrivers/ieee1394 -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core +firedtv-y := firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o +firedtv-$(CONFIG_DVB_FIREDTV_IEEE1394) += firedtv-1394.o +firedtv-$(CONFIG_DVB_FIREDTV_INPUT) += firedtv-rc.o + +ccflags-y += -Idrivers/media/dvb/dvb-core +ccflags-$(CONFIG_DVB_FIREDTV_IEEE1394) += -Idrivers/ieee1394 diff --git a/drivers/media/dvb/firewire/avc.c b/drivers/media/dvb/firewire/avc.c deleted file mode 100644 index 847a537b1f5..00000000000 --- a/drivers/media/dvb/firewire/avc.c +++ /dev/null @@ -1,1051 +0,0 @@ -/* - * FireDTV driver (formerly known as FireSAT) - * - * Copyright (C) 2004 Andreas Monitzer - * Copyright (C) 2008 Ben Backx - * Copyright (C) 2008 Henrik Kurelid - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "avc.h" -#include "firedtv.h" -#include "firedtv-rc.h" - -#define FCP_COMMAND_REGISTER 0xfffff0000b00ULL - -static int __avc_write(struct firedtv *fdtv, - const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) -{ - int err, retry; - - if (RspFrm) - fdtv->avc_reply_received = false; - - for (retry = 0; retry < 6; retry++) { - err = hpsb_node_write(fdtv->ud->ne, FCP_COMMAND_REGISTER, - (quadlet_t *)CmdFrm, CmdFrm->length); - if (err) { - fdtv->avc_reply_received = true; - dev_err(&fdtv->ud->device, - "FCP command write failed\n"); - return err; - } - - if (!RspFrm) - return 0; - - /* - * AV/C specs say that answers should be sent within 150 ms. - * Time out after 200 ms. - */ - if (wait_event_timeout(fdtv->avc_wait, - fdtv->avc_reply_received, - HZ / 5) != 0) { - memcpy(RspFrm, fdtv->respfrm, fdtv->resp_length); - RspFrm->length = fdtv->resp_length; - - return 0; - } - } - dev_err(&fdtv->ud->device, "FCP response timed out\n"); - return -ETIMEDOUT; -} - -static int avc_write(struct firedtv *fdtv, - const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) -{ - int ret; - - if (mutex_lock_interruptible(&fdtv->avc_mutex)) - return -EINTR; - - ret = __avc_write(fdtv, CmdFrm, RspFrm); - - mutex_unlock(&fdtv->avc_mutex); - return ret; -} - -int avc_recv(struct firedtv *fdtv, u8 *data, size_t length) -{ - AVCRspFrm *RspFrm = (AVCRspFrm *)data; - - if (length >= 8 && - RspFrm->operand[0] == SFE_VENDOR_DE_COMPANYID_0 && - RspFrm->operand[1] == SFE_VENDOR_DE_COMPANYID_1 && - RspFrm->operand[2] == SFE_VENDOR_DE_COMPANYID_2 && - RspFrm->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) { - if (RspFrm->resp == CHANGED) { - fdtv_handle_rc(fdtv, - RspFrm->operand[4] << 8 | RspFrm->operand[5]); - schedule_work(&fdtv->remote_ctrl_work); - } else if (RspFrm->resp != INTERIM) { - dev_info(&fdtv->ud->device, - "remote control result = %d\n", RspFrm->resp); - } - return 0; - } - - if (fdtv->avc_reply_received) { - dev_err(&fdtv->ud->device, - "received out-of-order AVC response, ignored\n"); - return -EIO; - } - - memcpy(fdtv->respfrm, data, length); - fdtv->resp_length = length; - - fdtv->avc_reply_received = true; - wake_up(&fdtv->avc_wait); - - return 0; -} - -/* - * tuning command for setting the relative LNB frequency - * (not supported by the AVC standard) - */ -static void avc_tuner_tuneqpsk(struct firedtv *fdtv, - struct dvb_frontend_parameters *params, AVCCmdFrm *CmdFrm) -{ - CmdFrm->opcode = VENDOR; - - CmdFrm->operand[0] = SFE_VENDOR_DE_COMPANYID_0; - CmdFrm->operand[1] = SFE_VENDOR_DE_COMPANYID_1; - CmdFrm->operand[2] = SFE_VENDOR_DE_COMPANYID_2; - CmdFrm->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK; - - CmdFrm->operand[4] = (params->frequency >> 24) & 0xff; - CmdFrm->operand[5] = (params->frequency >> 16) & 0xff; - CmdFrm->operand[6] = (params->frequency >> 8) & 0xff; - CmdFrm->operand[7] = params->frequency & 0xff; - - CmdFrm->operand[8] = ((params->u.qpsk.symbol_rate / 1000) >> 8) & 0xff; - CmdFrm->operand[9] = (params->u.qpsk.symbol_rate / 1000) & 0xff; - - switch(params->u.qpsk.fec_inner) { - case FEC_1_2: - CmdFrm->operand[10] = 0x1; break; - case FEC_2_3: - CmdFrm->operand[10] = 0x2; break; - case FEC_3_4: - CmdFrm->operand[10] = 0x3; break; - case FEC_5_6: - CmdFrm->operand[10] = 0x4; break; - case FEC_7_8: - CmdFrm->operand[10] = 0x5; break; - case FEC_4_5: - case FEC_8_9: - case FEC_AUTO: - default: - CmdFrm->operand[10] = 0x0; - } - - if (fdtv->voltage == 0xff) - CmdFrm->operand[11] = 0xff; - else if (fdtv->voltage == SEC_VOLTAGE_18) /* polarisation */ - CmdFrm->operand[11] = 0; - else - CmdFrm->operand[11] = 1; - - if (fdtv->tone == 0xff) - CmdFrm->operand[12] = 0xff; - else if (fdtv->tone == SEC_TONE_ON) /* band */ - CmdFrm->operand[12] = 1; - else - CmdFrm->operand[12] = 0; - - if (fdtv->type == FIREDTV_DVB_S2) { - CmdFrm->operand[13] = 0x1; - CmdFrm->operand[14] = 0xff; - CmdFrm->operand[15] = 0xff; - CmdFrm->length = 20; - } else { - CmdFrm->length = 16; - } -} - -static void avc_tuner_dsd_dvb_c(struct dvb_frontend_parameters *params, - AVCCmdFrm *CmdFrm) -{ - M_VALID_FLAGS flags; - - flags.Bits.Modulation = params->u.qam.modulation != QAM_AUTO; - flags.Bits.FEC_inner = params->u.qam.fec_inner != FEC_AUTO; - flags.Bits.FEC_outer = 0; - flags.Bits.Symbol_Rate = 1; - flags.Bits.Frequency = 1; - flags.Bits.Orbital_Pos = 0; - flags.Bits.Polarisation = 0; - flags.Bits.reserved_fields = 0; - flags.Bits.reserved1 = 0; - flags.Bits.Network_ID = 0; - - CmdFrm->opcode = DSD; - - CmdFrm->operand[0] = 0; /* source plug */ - CmdFrm->operand[1] = 0xd2; /* subfunction replace */ - CmdFrm->operand[2] = 0x20; /* system id = DVB */ - CmdFrm->operand[3] = 0x00; /* antenna number */ - /* system_specific_multiplex selection_length */ - CmdFrm->operand[4] = 0x11; - CmdFrm->operand[5] = flags.Valid_Word.ByteHi; /* valid_flags [0] */ - CmdFrm->operand[6] = flags.Valid_Word.ByteLo; /* valid_flags [1] */ - CmdFrm->operand[7] = 0x00; - CmdFrm->operand[8] = 0x00; - CmdFrm->operand[9] = 0x00; - CmdFrm->operand[10] = 0x00; - - CmdFrm->operand[11] = - (((params->frequency / 4000) >> 16) & 0xff) | (2 << 6); - CmdFrm->operand[12] = - ((params->frequency / 4000) >> 8) & 0xff; - CmdFrm->operand[13] = (params->frequency / 4000) & 0xff; - CmdFrm->operand[14] = - ((params->u.qpsk.symbol_rate / 1000) >> 12) & 0xff; - CmdFrm->operand[15] = - ((params->u.qpsk.symbol_rate / 1000) >> 4) & 0xff; - CmdFrm->operand[16] = - ((params->u.qpsk.symbol_rate / 1000) << 4) & 0xf0; - CmdFrm->operand[17] = 0x00; - - switch (params->u.qpsk.fec_inner) { - case FEC_1_2: - CmdFrm->operand[18] = 0x1; break; - case FEC_2_3: - CmdFrm->operand[18] = 0x2; break; - case FEC_3_4: - CmdFrm->operand[18] = 0x3; break; - case FEC_5_6: - CmdFrm->operand[18] = 0x4; break; - case FEC_7_8: - CmdFrm->operand[18] = 0x5; break; - case FEC_8_9: - CmdFrm->operand[18] = 0x6; break; - case FEC_4_5: - CmdFrm->operand[18] = 0x8; break; - case FEC_AUTO: - default: - CmdFrm->operand[18] = 0x0; - } - switch (params->u.qam.modulation) { - case QAM_16: - CmdFrm->operand[19] = 0x08; break; - case QAM_32: - CmdFrm->operand[19] = 0x10; break; - case QAM_64: - CmdFrm->operand[19] = 0x18; break; - case QAM_128: - CmdFrm->operand[19] = 0x20; break; - case QAM_256: - CmdFrm->operand[19] = 0x28; break; - case QAM_AUTO: - default: - CmdFrm->operand[19] = 0x00; - } - CmdFrm->operand[20] = 0x00; - CmdFrm->operand[21] = 0x00; - /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */ - CmdFrm->operand[22] = 0x00; - - CmdFrm->length = 28; -} - -static void avc_tuner_dsd_dvb_t(struct dvb_frontend_parameters *params, - AVCCmdFrm *CmdFrm) -{ - M_VALID_FLAGS flags; - - flags.Bits_T.GuardInterval = - params->u.ofdm.guard_interval != GUARD_INTERVAL_AUTO; - flags.Bits_T.CodeRateLPStream = - params->u.ofdm.code_rate_LP != FEC_AUTO; - flags.Bits_T.CodeRateHPStream = - params->u.ofdm.code_rate_HP != FEC_AUTO; - flags.Bits_T.HierarchyInfo = - params->u.ofdm.hierarchy_information != HIERARCHY_AUTO; - flags.Bits_T.Constellation = - params->u.ofdm.constellation != QAM_AUTO; - flags.Bits_T.Bandwidth = - params->u.ofdm.bandwidth != BANDWIDTH_AUTO; - flags.Bits_T.CenterFrequency = 1; - flags.Bits_T.reserved1 = 0; - flags.Bits_T.reserved2 = 0; - flags.Bits_T.OtherFrequencyFlag = 0; - flags.Bits_T.TransmissionMode = - params->u.ofdm.transmission_mode != TRANSMISSION_MODE_AUTO; - flags.Bits_T.NetworkId = 0; - - CmdFrm->opcode = DSD; - - CmdFrm->operand[0] = 0; /* source plug */ - CmdFrm->operand[1] = 0xd2; /* subfunction replace */ - CmdFrm->operand[2] = 0x20; /* system id = DVB */ - CmdFrm->operand[3] = 0x00; /* antenna number */ - /* system_specific_multiplex selection_length */ - CmdFrm->operand[4] = 0x0c; - CmdFrm->operand[5] = flags.Valid_Word.ByteHi; /* valid_flags [0] */ - CmdFrm->operand[6] = flags.Valid_Word.ByteLo; /* valid_flags [1] */ - CmdFrm->operand[7] = 0x0; - CmdFrm->operand[8] = (params->frequency / 10) >> 24; - CmdFrm->operand[9] = ((params->frequency / 10) >> 16) & 0xff; - CmdFrm->operand[10] = ((params->frequency / 10) >> 8) & 0xff; - CmdFrm->operand[11] = (params->frequency / 10) & 0xff; - - switch (params->u.ofdm.bandwidth) { - case BANDWIDTH_7_MHZ: - CmdFrm->operand[12] = 0x20; break; - case BANDWIDTH_8_MHZ: - case BANDWIDTH_6_MHZ: /* not defined by AVC spec */ - case BANDWIDTH_AUTO: - default: - CmdFrm->operand[12] = 0x00; - } - switch (params->u.ofdm.constellation) { - case QAM_16: - CmdFrm->operand[13] = 1 << 6; break; - case QAM_64: - CmdFrm->operand[13] = 2 << 6; break; - case QPSK: - default: - CmdFrm->operand[13] = 0x00; - } - switch (params->u.ofdm.hierarchy_information) { - case HIERARCHY_1: - CmdFrm->operand[13] |= 1 << 3; break; - case HIERARCHY_2: - CmdFrm->operand[13] |= 2 << 3; break; - case HIERARCHY_4: - CmdFrm->operand[13] |= 3 << 3; break; - case HIERARCHY_AUTO: - case HIERARCHY_NONE: - default: - break; - } - switch (params->u.ofdm.code_rate_HP) { - case FEC_2_3: - CmdFrm->operand[13] |= 1; break; - case FEC_3_4: - CmdFrm->operand[13] |= 2; break; - case FEC_5_6: - CmdFrm->operand[13] |= 3; break; - case FEC_7_8: - CmdFrm->operand[13] |= 4; break; - case FEC_1_2: - default: - break; - } - switch (params->u.ofdm.code_rate_LP) { - case FEC_2_3: - CmdFrm->operand[14] = 1 << 5; break; - case FEC_3_4: - CmdFrm->operand[14] = 2 << 5; break; - case FEC_5_6: - CmdFrm->operand[14] = 3 << 5; break; - case FEC_7_8: - CmdFrm->operand[14] = 4 << 5; break; - case FEC_1_2: - default: - CmdFrm->operand[14] = 0x00; break; - } - switch (params->u.ofdm.guard_interval) { - case GUARD_INTERVAL_1_16: - CmdFrm->operand[14] |= 1 << 3; break; - case GUARD_INTERVAL_1_8: - CmdFrm->operand[14] |= 2 << 3; break; - case GUARD_INTERVAL_1_4: - CmdFrm->operand[14] |= 3 << 3; break; - case GUARD_INTERVAL_1_32: - case GUARD_INTERVAL_AUTO: - default: - break; - } - switch (params->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_8K: - CmdFrm->operand[14] |= 1 << 1; break; - case TRANSMISSION_MODE_2K: - case TRANSMISSION_MODE_AUTO: - default: - break; - } - - CmdFrm->operand[15] = 0x00; /* network_ID[0] */ - CmdFrm->operand[16] = 0x00; /* network_ID[1] */ - /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */ - CmdFrm->operand[17] = 0x00; - - CmdFrm->length = 24; -} - -int avc_tuner_dsd(struct firedtv *fdtv, - struct dvb_frontend_parameters *params) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - - CmdFrm.cts = AVC; - CmdFrm.ctype = CONTROL; - CmdFrm.sutyp = 0x5; - CmdFrm.suid = fdtv->subunit; - - switch (fdtv->type) { - case FIREDTV_DVB_S: - case FIREDTV_DVB_S2: - avc_tuner_tuneqpsk(fdtv, params, &CmdFrm); break; - case FIREDTV_DVB_C: - avc_tuner_dsd_dvb_c(params, &CmdFrm); break; - case FIREDTV_DVB_T: - avc_tuner_dsd_dvb_t(params, &CmdFrm); break; - default: - BUG(); - } - - if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) - return -EIO; - - msleep(500); -#if 0 - /* FIXME: */ - /* u8 *status was an out-parameter of avc_tuner_dsd, unused by caller */ - if(status) - *status=RspFrm.operand[2]; -#endif - return 0; -} - -int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - int pos, k; - - if (pidc > 16 && pidc != 0xff) - return -EINVAL; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - - CmdFrm.cts = AVC; - CmdFrm.ctype = CONTROL; - CmdFrm.sutyp = 0x5; - CmdFrm.suid = fdtv->subunit; - CmdFrm.opcode = DSD; - - CmdFrm.operand[0] = 0; // source plug - CmdFrm.operand[1] = 0xD2; // subfunction replace - CmdFrm.operand[2] = 0x20; // system id = DVB - CmdFrm.operand[3] = 0x00; // antenna number - CmdFrm.operand[4] = 0x00; // system_specific_multiplex selection_length - CmdFrm.operand[5] = pidc; // Nr_of_dsd_sel_specs - - pos = 6; - if (pidc != 0xff) - for (k = 0; k < pidc; k++) { - CmdFrm.operand[pos++] = 0x13; // flowfunction relay - CmdFrm.operand[pos++] = 0x80; // dsd_sel_spec_valid_flags -> PID - CmdFrm.operand[pos++] = (pid[k] >> 8) & 0x1F; - CmdFrm.operand[pos++] = pid[k] & 0xFF; - CmdFrm.operand[pos++] = 0x00; // tableID - CmdFrm.operand[pos++] = 0x00; // filter_length - } - - CmdFrm.length = ALIGN(3 + pos, 4); - - if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) - return -EIO; - - msleep(50); - return 0; -} - -int avc_tuner_get_ts(struct firedtv *fdtv) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - - CmdFrm.cts = AVC; - CmdFrm.ctype = CONTROL; - CmdFrm.sutyp = 0x5; - CmdFrm.suid = fdtv->subunit; - CmdFrm.opcode = DSIT; - - CmdFrm.operand[0] = 0; // source plug - CmdFrm.operand[1] = 0xD2; // subfunction replace - CmdFrm.operand[2] = 0xFF; //status - CmdFrm.operand[3] = 0x20; // system id = DVB - CmdFrm.operand[4] = 0x00; // antenna number - CmdFrm.operand[5] = 0x0; // system_specific_search_flags - CmdFrm.operand[6] = (fdtv->type == FIREDTV_DVB_T)?0x0c:0x11; // system_specific_multiplex selection_length - CmdFrm.operand[7] = 0x00; // valid_flags [0] - CmdFrm.operand[8] = 0x00; // valid_flags [1] - CmdFrm.operand[7 + (fdtv->type == FIREDTV_DVB_T)?0x0c:0x11] = 0x00; // nr_of_dsit_sel_specs (always 0) - - CmdFrm.length = (fdtv->type == FIREDTV_DVB_T)?24:28; - - if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) - return -EIO; - - msleep(250); - return 0; -} - -int avc_identify_subunit(struct firedtv *fdtv) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - - memset(&CmdFrm,0,sizeof(AVCCmdFrm)); - - CmdFrm.cts = AVC; - CmdFrm.ctype = CONTROL; - CmdFrm.sutyp = 0x5; // tuner - CmdFrm.suid = fdtv->subunit; - CmdFrm.opcode = READ_DESCRIPTOR; - - CmdFrm.operand[0]=DESCRIPTOR_SUBUNIT_IDENTIFIER; - CmdFrm.operand[1]=0xff; - CmdFrm.operand[2]=0x00; - CmdFrm.operand[3]=0x00; // length highbyte - CmdFrm.operand[4]=0x08; // length lowbyte - CmdFrm.operand[5]=0x00; // offset highbyte - CmdFrm.operand[6]=0x0d; // offset lowbyte - - CmdFrm.length=12; - - if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) - return -EIO; - - if ((RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) || - (RspFrm.operand[3] << 8) + RspFrm.operand[4] != 8) { - dev_err(&fdtv->ud->device, - "cannot read subunit identifier\n"); - return -EINVAL; - } - return 0; -} - -int avc_tuner_status(struct firedtv *fdtv, - ANTENNA_INPUT_INFO *antenna_input_info) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - int length; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - - CmdFrm.cts=AVC; - CmdFrm.ctype=CONTROL; - CmdFrm.sutyp=0x05; // tuner - CmdFrm.suid=fdtv->subunit; - CmdFrm.opcode=READ_DESCRIPTOR; - - CmdFrm.operand[0]=DESCRIPTOR_TUNER_STATUS; - CmdFrm.operand[1]=0xff; //read_result_status - CmdFrm.operand[2]=0x00; // reserver - CmdFrm.operand[3]=0;//sizeof(ANTENNA_INPUT_INFO) >> 8; - CmdFrm.operand[4]=0;//sizeof(ANTENNA_INPUT_INFO) & 0xFF; - CmdFrm.operand[5]=0x00; - CmdFrm.operand[6]=0x00; - CmdFrm.length=12; - - if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) - return -EIO; - - if (RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) { - dev_err(&fdtv->ud->device, "cannot read tuner status\n"); - return -EINVAL; - } - - length = RspFrm.operand[9]; - if (RspFrm.operand[1] != 0x10 || length != sizeof(ANTENNA_INPUT_INFO)) { - dev_err(&fdtv->ud->device, "got invalid tuner status\n"); - return -EINVAL; - } - - memcpy(antenna_input_info, &RspFrm.operand[10], length); - return 0; -} - -int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst, - char conttone, char nrdiseq, - struct dvb_diseqc_master_cmd *diseqcmd) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - int i, j, k; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - - CmdFrm.cts=AVC; - CmdFrm.ctype=CONTROL; - CmdFrm.sutyp=0x05; - CmdFrm.suid=fdtv->subunit; - CmdFrm.opcode=VENDOR; - - CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; - CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; - CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; - CmdFrm.operand[3]=SFE_VENDOR_OPCODE_LNB_CONTROL; - - CmdFrm.operand[4]=voltage; - CmdFrm.operand[5]=nrdiseq; - - i=6; - - for (j = 0; j < nrdiseq; j++) { - CmdFrm.operand[i++] = diseqcmd[j].msg_len; - - for (k = 0; k < diseqcmd[j].msg_len; k++) - CmdFrm.operand[i++] = diseqcmd[j].msg[k]; - } - - CmdFrm.operand[i++]=burst; - CmdFrm.operand[i++]=conttone; - - CmdFrm.length = ALIGN(3 + i, 4); - - if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) - return -EIO; - - if (RspFrm.resp != ACCEPTED) { - dev_err(&fdtv->ud->device, "LNB control failed\n"); - return -EINVAL; - } - - return 0; -} - -int avc_register_remote_control(struct firedtv *fdtv) -{ - AVCCmdFrm CmdFrm; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - - CmdFrm.cts = AVC; - CmdFrm.ctype = NOTIFY; - CmdFrm.sutyp = 0x1f; - CmdFrm.suid = 0x7; - CmdFrm.opcode = VENDOR; - - CmdFrm.operand[0] = SFE_VENDOR_DE_COMPANYID_0; - CmdFrm.operand[1] = SFE_VENDOR_DE_COMPANYID_1; - CmdFrm.operand[2] = SFE_VENDOR_DE_COMPANYID_2; - CmdFrm.operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL; - - CmdFrm.length = 8; - - return avc_write(fdtv, &CmdFrm, NULL); -} - -void avc_remote_ctrl_work(struct work_struct *work) -{ - struct firedtv *fdtv = - container_of(work, struct firedtv, remote_ctrl_work); - - /* Should it be rescheduled in failure cases? */ - avc_register_remote_control(fdtv); -} - -#if 0 /* FIXME: unused */ -int avc_tuner_host2ca(struct firedtv *fdtv) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - CmdFrm.cts = AVC; - CmdFrm.ctype = CONTROL; - CmdFrm.sutyp = 0x5; - CmdFrm.suid = fdtv->subunit; - CmdFrm.opcode = VENDOR; - - CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; - CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; - CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; - CmdFrm.operand[3]=SFE_VENDOR_OPCODE_HOST2CA; - CmdFrm.operand[4] = 0; // slot - CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; // ca tag - CmdFrm.operand[6] = 0; // more/last - CmdFrm.operand[7] = 0; // length - CmdFrm.length = 12; - - if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) - return -EIO; - - return 0; -} -#endif - -static int get_ca_object_pos(AVCRspFrm *RspFrm) -{ - int length = 1; - - /* Check length of length field */ - if (RspFrm->operand[7] & 0x80) - length = (RspFrm->operand[7] & 0x7f) + 1; - return length + 7; -} - -static int get_ca_object_length(AVCRspFrm *RspFrm) -{ -#if 0 /* FIXME: unused */ - int size = 0; - int i; - - if (RspFrm->operand[7] & 0x80) - for (i = 0; i < (RspFrm->operand[7] & 0x7f); i++) { - size <<= 8; - size += RspFrm->operand[8 + i]; - } -#endif - return RspFrm->operand[7]; -} - -int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - int pos; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - CmdFrm.cts = AVC; - CmdFrm.ctype = STATUS; - CmdFrm.sutyp = 0x5; - CmdFrm.suid = fdtv->subunit; - CmdFrm.opcode = VENDOR; - - CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; - CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; - CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; - CmdFrm.operand[3]=SFE_VENDOR_OPCODE_CA2HOST; - CmdFrm.operand[4] = 0; // slot - CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; // ca tag - CmdFrm.length = 12; - - if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) - return -EIO; - - /* FIXME: check response code and validate response data */ - - pos = get_ca_object_pos(&RspFrm); - app_info[0] = (TAG_APP_INFO >> 16) & 0xFF; - app_info[1] = (TAG_APP_INFO >> 8) & 0xFF; - app_info[2] = (TAG_APP_INFO >> 0) & 0xFF; - app_info[3] = 6 + RspFrm.operand[pos + 4]; - app_info[4] = 0x01; - memcpy(&app_info[5], &RspFrm.operand[pos], 5 + RspFrm.operand[pos + 4]); - *len = app_info[3] + 4; - - return 0; -} - -int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - int pos; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - CmdFrm.cts = AVC; - CmdFrm.ctype = STATUS; - CmdFrm.sutyp = 0x5; - CmdFrm.suid = fdtv->subunit; - CmdFrm.opcode = VENDOR; - - CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; - CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; - CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; - CmdFrm.operand[3]=SFE_VENDOR_OPCODE_CA2HOST; - CmdFrm.operand[4] = 0; // slot - CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; // ca tag - CmdFrm.length = 12; - - if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) - return -EIO; - - pos = get_ca_object_pos(&RspFrm); - app_info[0] = (TAG_CA_INFO >> 16) & 0xFF; - app_info[1] = (TAG_CA_INFO >> 8) & 0xFF; - app_info[2] = (TAG_CA_INFO >> 0) & 0xFF; - app_info[3] = 2; - app_info[4] = RspFrm.operand[pos + 0]; - app_info[5] = RspFrm.operand[pos + 1]; - *len = app_info[3] + 4; - - return 0; -} - -int avc_ca_reset(struct firedtv *fdtv) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - CmdFrm.cts = AVC; - CmdFrm.ctype = CONTROL; - CmdFrm.sutyp = 0x5; - CmdFrm.suid = fdtv->subunit; - CmdFrm.opcode = VENDOR; - - CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; - CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; - CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; - CmdFrm.operand[3]=SFE_VENDOR_OPCODE_HOST2CA; - CmdFrm.operand[4] = 0; // slot - CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_RESET; // ca tag - CmdFrm.operand[6] = 0; // more/last - CmdFrm.operand[7] = 1; // length - CmdFrm.operand[8] = 0; // force hardware reset - CmdFrm.length = 12; - - if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) - return -EIO; - - return 0; -} - -int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - int list_management; - int program_info_length; - int pmt_cmd_id; - int read_pos; - int write_pos; - int es_info_length; - int crc32_csum; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - CmdFrm.cts = AVC; - CmdFrm.ctype = CONTROL; - CmdFrm.sutyp = 0x5; - CmdFrm.suid = fdtv->subunit; - CmdFrm.opcode = VENDOR; - - if (msg[0] != LIST_MANAGEMENT_ONLY) { - dev_info(&fdtv->ud->device, - "forcing list_management to ONLY\n"); - msg[0] = LIST_MANAGEMENT_ONLY; - } - // We take the cmd_id from the programme level only! - list_management = msg[0]; - program_info_length = ((msg[4] & 0x0F) << 8) + msg[5]; - if (program_info_length > 0) - program_info_length--; // Remove pmt_cmd_id - pmt_cmd_id = msg[6]; - - CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; - CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; - CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; - CmdFrm.operand[3]=SFE_VENDOR_OPCODE_HOST2CA; - CmdFrm.operand[4] = 0; // slot - CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_PMT; // ca tag - CmdFrm.operand[6] = 0; // more/last - //CmdFrm.operand[7] = XXXprogram_info_length + 17; // length - CmdFrm.operand[8] = list_management; - CmdFrm.operand[9] = 0x01; // pmt_cmd=OK_descramble - - // TS program map table - - // Table id=2 - CmdFrm.operand[10] = 0x02; - // Section syntax + length - CmdFrm.operand[11] = 0x80; - //CmdFrm.operand[12] = XXXprogram_info_length + 12; - // Program number - CmdFrm.operand[13] = msg[1]; - CmdFrm.operand[14] = msg[2]; - // Version number=0 + current/next=1 - CmdFrm.operand[15] = 0x01; - // Section number=0 - CmdFrm.operand[16] = 0x00; - // Last section number=0 - CmdFrm.operand[17] = 0x00; - // PCR_PID=1FFF - CmdFrm.operand[18] = 0x1F; - CmdFrm.operand[19] = 0xFF; - // Program info length - CmdFrm.operand[20] = (program_info_length >> 8); - CmdFrm.operand[21] = (program_info_length & 0xFF); - // CA descriptors at programme level - read_pos = 6; - write_pos = 22; - if (program_info_length > 0) { - pmt_cmd_id = msg[read_pos++]; - if (pmt_cmd_id != 1 && pmt_cmd_id != 4) - dev_err(&fdtv->ud->device, - "invalid pmt_cmd_id %d\n", pmt_cmd_id); - - memcpy(&CmdFrm.operand[write_pos], &msg[read_pos], - program_info_length); - read_pos += program_info_length; - write_pos += program_info_length; - } - while (read_pos < length) { - CmdFrm.operand[write_pos++] = msg[read_pos++]; - CmdFrm.operand[write_pos++] = msg[read_pos++]; - CmdFrm.operand[write_pos++] = msg[read_pos++]; - es_info_length = - ((msg[read_pos] & 0x0F) << 8) + msg[read_pos + 1]; - read_pos += 2; - if (es_info_length > 0) - es_info_length--; // Remove pmt_cmd_id - CmdFrm.operand[write_pos++] = es_info_length >> 8; - CmdFrm.operand[write_pos++] = es_info_length & 0xFF; - if (es_info_length > 0) { - pmt_cmd_id = msg[read_pos++]; - if (pmt_cmd_id != 1 && pmt_cmd_id != 4) - dev_err(&fdtv->ud->device, - "invalid pmt_cmd_id %d " - "at stream level\n", pmt_cmd_id); - - memcpy(&CmdFrm.operand[write_pos], &msg[read_pos], - es_info_length); - read_pos += es_info_length; - write_pos += es_info_length; - } - } - - // CRC - CmdFrm.operand[write_pos++] = 0x00; - CmdFrm.operand[write_pos++] = 0x00; - CmdFrm.operand[write_pos++] = 0x00; - CmdFrm.operand[write_pos++] = 0x00; - - CmdFrm.operand[7] = write_pos - 8; - CmdFrm.operand[12] = write_pos - 13; - - crc32_csum = crc32_be(0, &CmdFrm.operand[10], - CmdFrm.operand[12] - 1); - CmdFrm.operand[write_pos - 4] = (crc32_csum >> 24) & 0xFF; - CmdFrm.operand[write_pos - 3] = (crc32_csum >> 16) & 0xFF; - CmdFrm.operand[write_pos - 2] = (crc32_csum >> 8) & 0xFF; - CmdFrm.operand[write_pos - 1] = (crc32_csum >> 0) & 0xFF; - - CmdFrm.length = ALIGN(3 + write_pos, 4); - - if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) - return -EIO; - - if (RspFrm.resp != ACCEPTED) { - dev_err(&fdtv->ud->device, - "CA PMT failed with response 0x%x\n", RspFrm.resp); - return -EFAULT; - } - - return 0; -} - -int avc_ca_get_time_date(struct firedtv *fdtv, int *interval) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - CmdFrm.cts = AVC; - CmdFrm.ctype = STATUS; - CmdFrm.sutyp = 0x5; - CmdFrm.suid = fdtv->subunit; - CmdFrm.opcode = VENDOR; - - CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; - CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; - CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; - CmdFrm.operand[3]=SFE_VENDOR_OPCODE_CA2HOST; - CmdFrm.operand[4] = 0; // slot - CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_DATE_TIME; // ca tag - CmdFrm.operand[6] = 0; // more/last - CmdFrm.operand[7] = 0; // length - CmdFrm.length = 12; - - if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) - return -EIO; - - /* FIXME: check response code and validate response data */ - - *interval = RspFrm.operand[get_ca_object_pos(&RspFrm)]; - - return 0; -} - -int avc_ca_enter_menu(struct firedtv *fdtv) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - CmdFrm.cts = AVC; - CmdFrm.ctype = STATUS; - CmdFrm.sutyp = 0x5; - CmdFrm.suid = fdtv->subunit; - CmdFrm.opcode = VENDOR; - - CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; - CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; - CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; - CmdFrm.operand[3]=SFE_VENDOR_OPCODE_HOST2CA; - CmdFrm.operand[4] = 0; // slot - CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_ENTER_MENU; - CmdFrm.operand[6] = 0; // more/last - CmdFrm.operand[7] = 0; // length - CmdFrm.length = 12; - - if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) - return -EIO; - - return 0; -} - -int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len) -{ - AVCCmdFrm CmdFrm; - AVCRspFrm RspFrm; - - memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); - CmdFrm.cts = AVC; - CmdFrm.ctype = STATUS; - CmdFrm.sutyp = 0x5; - CmdFrm.suid = fdtv->subunit; - CmdFrm.opcode = VENDOR; - - CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0; - CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1; - CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2; - CmdFrm.operand[3]=SFE_VENDOR_OPCODE_CA2HOST; - CmdFrm.operand[4] = 0; // slot - CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_MMI; - CmdFrm.operand[6] = 0; // more/last - CmdFrm.operand[7] = 0; // length - CmdFrm.length = 12; - - if (avc_write(fdtv, &CmdFrm, &RspFrm) < 0) - return -EIO; - - /* FIXME: check response code and validate response data */ - - *len = get_ca_object_length(&RspFrm); - memcpy(mmi_object, &RspFrm.operand[get_ca_object_pos(&RspFrm)], *len); - - return 0; -} diff --git a/drivers/media/dvb/firewire/avc.h b/drivers/media/dvb/firewire/avc.h deleted file mode 100644 index 168f371dbde..00000000000 --- a/drivers/media/dvb/firewire/avc.h +++ /dev/null @@ -1,432 +0,0 @@ -/* - * AV/C API - * - * Copyright (C) 2000 Manfred Weihs - * Copyright (C) 2003 Philipp Gutgsell <0014guph@edu.fh-kaernten.ac.at> - * Copyright (C) 2004 Andreas Monitzer - * Copyright (C) 2008 Ben Backx - * Copyright (C) 2008 Henrik Kurelid - * - * This is based on code written by Peter Halwachs, Thomas Groiss and - * Andreas Monitzer. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - */ - -#ifndef _AVC_API_H -#define _AVC_API_H - -#include - -/************************************************************* - Constants from EN510221 -**************************************************************/ -#define LIST_MANAGEMENT_ONLY 0x03 - -/************************************************************ - definition of structures -*************************************************************/ -typedef struct { - int Nr_SourcePlugs; - int Nr_DestinationPlugs; -} TunerInfo; - - -/*********************************************** - - supported cts - -************************************************/ - -#define AVC 0x0 - -// FCP command frame with ctype = 0x0 is AVC command frame - -#ifdef __LITTLE_ENDIAN - -// Definition FCP Command Frame -typedef struct _AVCCmdFrm -{ - // AV/C command frame - __u8 ctype : 4 ; // command type - __u8 cts : 4 ; // always 0x0 for AVC - __u8 suid : 3 ; // subunit ID - __u8 sutyp : 5 ; // subunit_typ - __u8 opcode : 8 ; // opcode - __u8 operand[509] ; // array of operands [1-507] - int length; //length of the command frame -} AVCCmdFrm ; - -// Definition FCP Response Frame -typedef struct _AVCRspFrm -{ - // AV/C response frame - __u8 resp : 4 ; // response type - __u8 cts : 4 ; // always 0x0 for AVC - __u8 suid : 3 ; // subunit ID - __u8 sutyp : 5 ; // subunit_typ - __u8 opcode : 8 ; // opcode - __u8 operand[509] ; // array of operands [1-507] - int length; //length of the response frame -} AVCRspFrm ; - -#else - -typedef struct _AVCCmdFrm -{ - __u8 cts:4; - __u8 ctype:4; - __u8 sutyp:5; - __u8 suid:3; - __u8 opcode; - __u8 operand[509]; - int length; -} AVCCmdFrm; - -typedef struct _AVCRspFrm -{ - __u8 cts:4; - __u8 resp:4; - __u8 sutyp:5; - __u8 suid:3; - __u8 opcode; - __u8 operand[509]; - int length; -} AVCRspFrm; - -#endif - -/************************************************************* - AVC command types (ctype) -**************************************************************/// -#define CONTROL 0x00 -#define STATUS 0x01 -#define INQUIRY 0x02 -#define NOTIFY 0x03 - -/************************************************************* - AVC respond types -**************************************************************/// -#define NOT_IMPLEMENTED 0x8 -#define ACCEPTED 0x9 -#define REJECTED 0xA -#define STABLE 0xC -#define CHANGED 0xD -#define INTERIM 0xF - -/************************************************************* - AVC opcodes -**************************************************************/// -#define CONNECT 0x24 -#define DISCONNECT 0x25 -#define UNIT_INFO 0x30 -#define SUBUNIT_Info 0x31 -#define VENDOR 0x00 - -#define PLUG_INFO 0x02 -#define OPEN_DESCRIPTOR 0x08 -#define READ_DESCRIPTOR 0x09 -#define OBJECT_NUMBER_SELECT 0x0D - -/************************************************************* - AVCTuner opcodes -**************************************************************/ - -#define DSIT 0xC8 -#define DSD 0xCB -#define DESCRIPTOR_TUNER_STATUS 0x80 -#define DESCRIPTOR_SUBUNIT_IDENTIFIER 0x00 - -/************************************************************* - AVCTuner list types -**************************************************************/ -#define Multiplex_List 0x80 -#define Service_List 0x82 - -/************************************************************* - AVCTuner object entries -**************************************************************/ -#define Multiplex 0x80 -#define Service 0x82 -#define Service_with_specified_components 0x83 -#define Preferred_components 0x90 -#define Component 0x84 - -/************************************************************* - Vendor-specific commands -**************************************************************/ - -// digital everywhere vendor ID -#define SFE_VENDOR_DE_COMPANYID_0 0x00 -#define SFE_VENDOR_DE_COMPANYID_1 0x12 -#define SFE_VENDOR_DE_COMPANYID_2 0x87 - -#define SFE_VENDOR_MAX_NR_COMPONENTS 0x4 -#define SFE_VENDOR_MAX_NR_SERVICES 0x3 -#define SFE_VENDOR_MAX_NR_DSD_ELEMENTS 0x10 - -// vendor commands -#define SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL 0x0A -#define SFE_VENDOR_OPCODE_LNB_CONTROL 0x52 -#define SFE_VENDOR_OPCODE_TUNE_QPSK 0x58 // QPSK command for DVB-S - -// TODO: following vendor specific commands needs to be implemented -#define SFE_VENDOR_OPCODE_GET_FIRMWARE_VERSION 0x00 -#define SFE_VENDOR_OPCODE_HOST2CA 0x56 -#define SFE_VENDOR_OPCODE_CA2HOST 0x57 -#define SFE_VENDOR_OPCODE_CISTATUS 0x59 -#define SFE_VENDOR_OPCODE_TUNE_QPSK2 0x60 // QPSK command for DVB-S2 devices - -// CA Tags -#define SFE_VENDOR_TAG_CA_RESET 0x00 -#define SFE_VENDOR_TAG_CA_APPLICATION_INFO 0x01 -#define SFE_VENDOR_TAG_CA_PMT 0x02 -#define SFE_VENDOR_TAG_CA_DATE_TIME 0x04 -#define SFE_VENDOR_TAG_CA_MMI 0x05 -#define SFE_VENDOR_TAG_CA_ENTER_MENU 0x07 - - -//AVCTuner DVB identifier service_ID -#define DVB 0x20 - -/************************************************************* - AVC descriptor types -**************************************************************/ - -#define Subunit_Identifier_Descriptor 0x00 -#define Tuner_Status_Descriptor 0x80 - -typedef struct { - __u8 Subunit_Type; - __u8 Max_Subunit_ID; -} SUBUNIT_INFO; - -/************************************************************* - - AVCTuner DVB object IDs are 6 byte long - -**************************************************************/ - -typedef struct { - __u8 Byte0; - __u8 Byte1; - __u8 Byte2; - __u8 Byte3; - __u8 Byte4; - __u8 Byte5; -}OBJECT_ID; - -/************************************************************* - MULIPLEX Structs -**************************************************************/ -typedef struct -{ -#ifdef __LITTLE_ENDIAN - __u8 RF_frequency_hByte:6; - __u8 raster_Frequency:2;//Bit7,6 raster frequency -#else - __u8 raster_Frequency:2; - __u8 RF_frequency_hByte:6; -#endif - __u8 RF_frequency_mByte; - __u8 RF_frequency_lByte; - -}FREQUENCY; - -#ifdef __LITTLE_ENDIAN - -typedef struct -{ - __u8 Modulation :1; - __u8 FEC_inner :1; - __u8 FEC_outer :1; - __u8 Symbol_Rate :1; - __u8 Frequency :1; - __u8 Orbital_Pos :1; - __u8 Polarisation :1; - __u8 reserved_fields :1; - __u8 reserved1 :7; - __u8 Network_ID :1; - -}MULTIPLEX_VALID_FLAGS; - -typedef struct -{ - __u8 GuardInterval:1; - __u8 CodeRateLPStream:1; - __u8 CodeRateHPStream:1; - __u8 HierarchyInfo:1; - __u8 Constellation:1; - __u8 Bandwidth:1; - __u8 CenterFrequency:1; - __u8 reserved1:1; - __u8 reserved2:5; - __u8 OtherFrequencyFlag:1; - __u8 TransmissionMode:1; - __u8 NetworkId:1; -}MULTIPLEX_VALID_FLAGS_DVBT; - -#else - -typedef struct { - __u8 reserved_fields:1; - __u8 Polarisation:1; - __u8 Orbital_Pos:1; - __u8 Frequency:1; - __u8 Symbol_Rate:1; - __u8 FEC_outer:1; - __u8 FEC_inner:1; - __u8 Modulation:1; - __u8 Network_ID:1; - __u8 reserved1:7; -}MULTIPLEX_VALID_FLAGS; - -typedef struct { - __u8 reserved1:1; - __u8 CenterFrequency:1; - __u8 Bandwidth:1; - __u8 Constellation:1; - __u8 HierarchyInfo:1; - __u8 CodeRateHPStream:1; - __u8 CodeRateLPStream:1; - __u8 GuardInterval:1; - __u8 NetworkId:1; - __u8 TransmissionMode:1; - __u8 OtherFrequencyFlag:1; - __u8 reserved2:5; -}MULTIPLEX_VALID_FLAGS_DVBT; - -#endif - -typedef union { - MULTIPLEX_VALID_FLAGS Bits; - MULTIPLEX_VALID_FLAGS_DVBT Bits_T; - struct { - __u8 ByteHi; - __u8 ByteLo; - } Valid_Word; -} M_VALID_FLAGS; - -typedef struct -{ -#ifdef __LITTLE_ENDIAN - __u8 ActiveSystem; - __u8 reserved:5; - __u8 NoRF:1; - __u8 Moving:1; - __u8 Searching:1; - - __u8 SelectedAntenna:7; - __u8 Input:1; - - __u8 BER[4]; - - __u8 SignalStrength; - FREQUENCY Frequency; - - __u8 ManDepInfoLength; - - __u8 PowerSupply:1; - __u8 FrontEndPowerStatus:1; - __u8 reserved3:1; - __u8 AntennaError:1; - __u8 FrontEndError:1; - __u8 reserved2:3; - - __u8 CarrierNoiseRatio[2]; - __u8 reserved4[2]; - __u8 PowerSupplyVoltage; - __u8 AntennaVoltage; - __u8 FirewireBusVoltage; - - __u8 CaMmi:1; - __u8 reserved5:7; - - __u8 reserved6:1; - __u8 CaInitializationStatus:1; - __u8 CaErrorFlag:1; - __u8 CaDvbFlag:1; - __u8 CaModulePresentStatus:1; - __u8 CaApplicationInfo:1; - __u8 CaDateTimeRequest:1; - __u8 CaPmtReply:1; - -#else - __u8 ActiveSystem; - __u8 Searching:1; - __u8 Moving:1; - __u8 NoRF:1; - __u8 reserved:5; - - __u8 Input:1; - __u8 SelectedAntenna:7; - - __u8 BER[4]; - - __u8 SignalStrength; - FREQUENCY Frequency; - - __u8 ManDepInfoLength; - - __u8 reserved2:3; - __u8 FrontEndError:1; - __u8 AntennaError:1; - __u8 reserved3:1; - __u8 FrontEndPowerStatus:1; - __u8 PowerSupply:1; - - __u8 CarrierNoiseRatio[2]; - __u8 reserved4[2]; - __u8 PowerSupplyVoltage; - __u8 AntennaVoltage; - __u8 FirewireBusVoltage; - - __u8 reserved5:7; - __u8 CaMmi:1; - __u8 CaPmtReply:1; - __u8 CaDateTimeRequest:1; - __u8 CaApplicationInfo:1; - __u8 CaModulePresentStatus:1; - __u8 CaDvbFlag:1; - __u8 CaErrorFlag:1; - __u8 CaInitializationStatus:1; - __u8 reserved6:1; - -#endif -} ANTENNA_INPUT_INFO; // 22 Byte - -#define LNBCONTROL_DONTCARE 0xff - -struct dvb_diseqc_master_cmd; -struct dvb_frontend_parameters; -struct firedtv; - -int avc_recv(struct firedtv *fdtv, u8 *data, size_t length); - -int AVCTuner_DSIT(struct firedtv *fdtv, int Source_Plug, - struct dvb_frontend_parameters *params, __u8 *status); - -int avc_tuner_status(struct firedtv *fdtv, - ANTENNA_INPUT_INFO *antenna_input_info); -int avc_tuner_dsd(struct firedtv *fdtv, - struct dvb_frontend_parameters *params); -int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]); -int avc_tuner_get_ts(struct firedtv *fdtv); -int avc_identify_subunit(struct firedtv *fdtv); -int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst, - char conttone, char nrdiseq, - struct dvb_diseqc_master_cmd *diseqcmd); -void avc_remote_ctrl_work(struct work_struct *work); -int avc_register_remote_control(struct firedtv *fdtv); -int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len); -int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len); -int avc_ca_reset(struct firedtv *fdtv); -int avc_ca_pmt(struct firedtv *fdtv, char *app_info, int length); -int avc_ca_get_time_date(struct firedtv *fdtv, int *interval); -int avc_ca_enter_menu(struct firedtv *fdtv); -int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len); - -#endif /* _AVC_API_H */ diff --git a/drivers/media/dvb/firewire/cmp.c b/drivers/media/dvb/firewire/cmp.c deleted file mode 100644 index 821e033d819..00000000000 --- a/drivers/media/dvb/firewire/cmp.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * FireDTV driver (formerly known as FireSAT) - * - * Copyright (C) 2004 Andreas Monitzer - * Copyright (C) 2008 Henrik Kurelid - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - */ - -#include -#include -#include -#include - -#include - -#include -#include - -#include "avc.h" -#include "cmp.h" -#include "firedtv.h" - -#define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL - -static int cmp_read(struct firedtv *fdtv, void *buf, u64 addr, size_t len) -{ - int ret; - - if (mutex_lock_interruptible(&fdtv->avc_mutex)) - return -EINTR; - - ret = hpsb_node_read(fdtv->ud->ne, addr, buf, len); - if (ret < 0) - dev_err(&fdtv->ud->device, "CMP: read I/O error\n"); - - mutex_unlock(&fdtv->avc_mutex); - return ret; -} - -static int cmp_lock(struct firedtv *fdtv, void *data, u64 addr, __be32 arg, - int ext_tcode) -{ - int ret; - - if (mutex_lock_interruptible(&fdtv->avc_mutex)) - return -EINTR; - - ret = hpsb_node_lock(fdtv->ud->ne, addr, ext_tcode, data, - (__force quadlet_t)arg); - if (ret < 0) - dev_err(&fdtv->ud->device, "CMP: lock I/O error\n"); - - mutex_unlock(&fdtv->avc_mutex); - return ret; -} - -static inline u32 get_opcr(__be32 opcr, u32 mask, u32 shift) -{ - return (be32_to_cpu(opcr) >> shift) & mask; -} - -static inline void set_opcr(__be32 *opcr, u32 value, u32 mask, u32 shift) -{ - *opcr &= ~cpu_to_be32(mask << shift); - *opcr |= cpu_to_be32((value & mask) << shift); -} - -#define get_opcr_online(v) get_opcr((v), 0x1, 31) -#define get_opcr_p2p_connections(v) get_opcr((v), 0x3f, 24) -#define get_opcr_channel(v) get_opcr((v), 0x3f, 16) - -#define set_opcr_p2p_connections(p, v) set_opcr((p), (v), 0x3f, 24) -#define set_opcr_channel(p, v) set_opcr((p), (v), 0x3f, 16) -#define set_opcr_data_rate(p, v) set_opcr((p), (v), 0x3, 14) -#define set_opcr_overhead_id(p, v) set_opcr((p), (v), 0xf, 10) - -int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel) -{ - __be32 old_opcr, opcr; - u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); - int attempts = 0; - int ret; - - ret = cmp_read(fdtv, &opcr, opcr_address, 4); - if (ret < 0) - return ret; - -repeat: - if (!get_opcr_online(opcr)) { - dev_err(&fdtv->ud->device, "CMP: output offline\n"); - return -EBUSY; - } - - old_opcr = opcr; - - if (get_opcr_p2p_connections(opcr)) { - if (get_opcr_channel(opcr) != channel) { - dev_err(&fdtv->ud->device, - "CMP: cannot change channel\n"); - return -EBUSY; - } - dev_info(&fdtv->ud->device, - "CMP: overlaying existing connection\n"); - - /* We don't allocate isochronous resources. */ - } else { - set_opcr_channel(&opcr, channel); - set_opcr_data_rate(&opcr, IEEE1394_SPEED_400); - - /* FIXME: this is for the worst case - optimize */ - set_opcr_overhead_id(&opcr, 0); - - /* FIXME: allocate isochronous channel and bandwidth at IRM */ - } - - set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) + 1); - - ret = cmp_lock(fdtv, &opcr, opcr_address, old_opcr, 2); - if (ret < 0) - return ret; - - if (old_opcr != opcr) { - /* - * FIXME: if old_opcr.P2P_Connections > 0, - * deallocate isochronous channel and bandwidth at IRM - */ - - if (++attempts < 6) /* arbitrary limit */ - goto repeat; - return -EBUSY; - } - - return 0; -} - -void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel) -{ - __be32 old_opcr, opcr; - u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); - int attempts = 0; - - if (cmp_read(fdtv, &opcr, opcr_address, 4) < 0) - return; - -repeat: - if (!get_opcr_online(opcr) || !get_opcr_p2p_connections(opcr) || - get_opcr_channel(opcr) != channel) { - dev_err(&fdtv->ud->device, "CMP: no connection to break\n"); - return; - } - - old_opcr = opcr; - set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) - 1); - - if (cmp_lock(fdtv, &opcr, opcr_address, old_opcr, 2) < 0) - return; - - if (old_opcr != opcr) { - /* - * FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last - * owner, deallocate isochronous channel and bandwidth at IRM - */ - - if (++attempts < 6) /* arbitrary limit */ - goto repeat; - } -} diff --git a/drivers/media/dvb/firewire/cmp.h b/drivers/media/dvb/firewire/cmp.h deleted file mode 100644 index 17e182cf29a..00000000000 --- a/drivers/media/dvb/firewire/cmp.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _CMP_H -#define _CMP_H - -struct firedtv; - -int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel); -void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel); - -#endif /* _CMP_H */ diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c index 953618246e8..4e207658c5d 100644 --- a/drivers/media/dvb/firewire/firedtv-1394.c +++ b/drivers/media/dvb/firewire/firedtv-1394.c @@ -15,162 +15,181 @@ #include #include #include -#include -#include -#include #include -#include #include -#include -#include -#include -#include - +#include #include #include #include -#include +#include +#include #include -#include "avc.h" -#include "cmp.h" #include "firedtv.h" -#include "firedtv-ci.h" -#include "firedtv-rc.h" - -#define MATCH_FLAGS IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \ - IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION -#define DIGITAL_EVERYWHERE_OUI 0x001287 - -static struct ieee1394_device_id fdtv_id_table[] = { - - { - /* FloppyDTV S/CI and FloppyDTV S2 */ - .match_flags = MATCH_FLAGS, - .vendor_id = DIGITAL_EVERYWHERE_OUI, - .model_id = 0x000024, - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, - .version = AVC_SW_VERSION_ENTRY, - },{ - /* FloppyDTV T/CI */ - .match_flags = MATCH_FLAGS, - .vendor_id = DIGITAL_EVERYWHERE_OUI, - .model_id = 0x000025, - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, - .version = AVC_SW_VERSION_ENTRY, - },{ - /* FloppyDTV C/CI */ - .match_flags = MATCH_FLAGS, - .vendor_id = DIGITAL_EVERYWHERE_OUI, - .model_id = 0x000026, - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, - .version = AVC_SW_VERSION_ENTRY, - },{ - /* FireDTV S/CI and FloppyDTV S2 */ - .match_flags = MATCH_FLAGS, - .vendor_id = DIGITAL_EVERYWHERE_OUI, - .model_id = 0x000034, - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, - .version = AVC_SW_VERSION_ENTRY, - },{ - /* FireDTV T/CI */ - .match_flags = MATCH_FLAGS, - .vendor_id = DIGITAL_EVERYWHERE_OUI, - .model_id = 0x000035, - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, - .version = AVC_SW_VERSION_ENTRY, - },{ - /* FireDTV C/CI */ - .match_flags = MATCH_FLAGS, - .vendor_id = DIGITAL_EVERYWHERE_OUI, - .model_id = 0x000036, - .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, - .version = AVC_SW_VERSION_ENTRY, - }, { } -}; -MODULE_DEVICE_TABLE(ieee1394, fdtv_id_table); +static LIST_HEAD(node_list); +static DEFINE_SPINLOCK(node_list_lock); -/* list of all firedtv devices */ -LIST_HEAD(fdtv_list); -DEFINE_SPINLOCK(fdtv_list_lock); +#define FIREWIRE_HEADER_SIZE 4 +#define CIP_HEADER_SIZE 8 -static void fcp_request(struct hpsb_host *host, - int nodeid, - int direction, - int cts, - u8 *data, - size_t length) +static void rawiso_activity_cb(struct hpsb_iso *iso) { - struct firedtv *fdtv = NULL; - struct firedtv *fdtv_entry; + struct firedtv *f, *fdtv = NULL; + unsigned int i, num, packet; + unsigned char *buf; unsigned long flags; + int count; + + spin_lock_irqsave(&node_list_lock, flags); + list_for_each_entry(f, &node_list, list) + if (f->backend_data == iso) { + fdtv = f; + break; + } + spin_unlock_irqrestore(&node_list_lock, flags); + + packet = iso->first_packet; + num = hpsb_iso_n_ready(iso); + + if (!fdtv) { + dev_err(fdtv->device, "received at unknown iso channel\n"); + goto out; + } - if (length > 0 && ((data[0] & 0xf0) >> 4) == 0) { - - spin_lock_irqsave(&fdtv_list_lock, flags); - list_for_each_entry(fdtv_entry,&fdtv_list,list) { - if (fdtv_entry->ud->ne->host == host && - fdtv_entry->ud->ne->nodeid == nodeid && - (fdtv_entry->subunit == (data[1]&0x7) || - (fdtv_entry->subunit == 0 && - (data[1]&0x7) == 0x7))) { - fdtv=fdtv_entry; - break; - } + for (i = 0; i < num; i++, packet = (packet + 1) % iso->buf_packets) { + buf = dma_region_i(&iso->data_buf, unsigned char, + iso->infos[packet].offset + CIP_HEADER_SIZE); + count = (iso->infos[packet].len - CIP_HEADER_SIZE) / + (188 + FIREWIRE_HEADER_SIZE); + + /* ignore empty packet */ + if (iso->infos[packet].len <= CIP_HEADER_SIZE) + continue; + + while (count--) { + if (buf[FIREWIRE_HEADER_SIZE] == 0x47) + dvb_dmx_swfilter_packets(&fdtv->demux, + &buf[FIREWIRE_HEADER_SIZE], 1); + else + dev_err(fdtv->device, + "skipping invalid packet\n"); + buf += 188 + FIREWIRE_HEADER_SIZE; } - spin_unlock_irqrestore(&fdtv_list_lock, flags); + } +out: + hpsb_iso_recv_release_packets(iso, num); +} + +static inline struct node_entry *node_of(struct firedtv *fdtv) +{ + return container_of(fdtv->device, struct unit_directory, device)->ne; +} + +static int node_lock(struct firedtv *fdtv, u64 addr, void *data, __be32 arg) +{ + return hpsb_node_lock(node_of(fdtv), addr, EXTCODE_COMPARE_SWAP, data, + (__force quadlet_t)arg); +} + +static int node_read(struct firedtv *fdtv, u64 addr, void *data, size_t len) +{ + return hpsb_node_read(node_of(fdtv), addr, data, len); +} + +static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len) +{ + return hpsb_node_write(node_of(fdtv), addr, data, len); +} + +#define FDTV_ISO_BUFFER_PACKETS 256 +#define FDTV_ISO_BUFFER_SIZE (FDTV_ISO_BUFFER_PACKETS * 200) + +static int start_iso(struct firedtv *fdtv) +{ + struct hpsb_iso *iso_handle; + int ret; + + iso_handle = hpsb_iso_recv_init(node_of(fdtv)->host, + FDTV_ISO_BUFFER_SIZE, FDTV_ISO_BUFFER_PACKETS, + fdtv->isochannel, HPSB_ISO_DMA_DEFAULT, + -1, /* stat.config.irq_interval */ + rawiso_activity_cb); + if (iso_handle == NULL) { + dev_err(fdtv->device, "cannot initialize iso receive\n"); + return -ENOMEM; + } + fdtv->backend_data = iso_handle; + + ret = hpsb_iso_recv_start(iso_handle, -1, -1, 0); + if (ret != 0) { + dev_err(fdtv->device, "cannot start iso receive\n"); + hpsb_iso_shutdown(iso_handle); + fdtv->backend_data = NULL; + } + return ret; +} + +static void stop_iso(struct firedtv *fdtv) +{ + struct hpsb_iso *iso_handle = fdtv->backend_data; - if (fdtv) - avc_recv(fdtv, data, length); + if (iso_handle != NULL) { + hpsb_iso_stop(iso_handle); + hpsb_iso_shutdown(iso_handle); } + fdtv->backend_data = NULL; } -const char *fdtv_model_names[] = { - [FIREDTV_UNKNOWN] = "unknown type", - [FIREDTV_DVB_S] = "FireDTV S/CI", - [FIREDTV_DVB_C] = "FireDTV C/CI", - [FIREDTV_DVB_T] = "FireDTV T/CI", - [FIREDTV_DVB_S2] = "FireDTV S2 ", +static const struct firedtv_backend fdtv_1394_backend = { + .lock = node_lock, + .read = node_read, + .write = node_write, + .start_iso = start_iso, + .stop_iso = stop_iso, }; -static int fdtv_probe(struct device *dev) +static void fcp_request(struct hpsb_host *host, int nodeid, int direction, + int cts, u8 *data, size_t length) { - struct unit_directory *ud = - container_of(dev, struct unit_directory, device); - struct firedtv *fdtv; + struct firedtv *f, *fdtv = NULL; unsigned long flags; - int kv_len; - void *kv_str; - int i; - int err = -ENOMEM; + int su; - fdtv = kzalloc(sizeof(*fdtv), GFP_KERNEL); - if (!fdtv) - return -ENOMEM; + if (length == 0 || (data[0] & 0xf0) != 0) + return; - dev->driver_data = fdtv; - fdtv->ud = ud; - fdtv->subunit = 0; - fdtv->isochannel = -1; - fdtv->tone = 0xff; - fdtv->voltage = 0xff; + su = data[1] & 0x7; + + spin_lock_irqsave(&node_list_lock, flags); + list_for_each_entry(f, &node_list, list) + if (node_of(f)->host == host && + node_of(f)->nodeid == nodeid && + (f->subunit == su || (f->subunit == 0 && su == 0x7))) { + fdtv = f; + break; + } + spin_unlock_irqrestore(&node_list_lock, flags); - mutex_init(&fdtv->avc_mutex); - init_waitqueue_head(&fdtv->avc_wait); - fdtv->avc_reply_received = true; - mutex_init(&fdtv->demux_mutex); - INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work); + if (fdtv) + avc_recv(fdtv, data, length); +} + +static int node_probe(struct device *dev) +{ + struct unit_directory *ud = + container_of(dev, struct unit_directory, device); + struct firedtv *fdtv; + int kv_len, err; + void *kv_str; - /* Reading device model from ROM */ kv_len = (ud->model_name_kv->value.leaf.len - 2) * sizeof(quadlet_t); kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv); - for (i = ARRAY_SIZE(fdtv_model_names); --i;) - if (strlen(fdtv_model_names[i]) <= kv_len && - strncmp(kv_str, fdtv_model_names[i], kv_len) == 0) - break; - fdtv->type = i; + + fdtv = fdtv_alloc(dev, &fdtv_1394_backend, kv_str, kv_len); + if (!fdtv) + return -ENOMEM; /* * Work around a bug in udev's path_id script: Use the fw-host's dev @@ -180,50 +199,39 @@ static int fdtv_probe(struct device *dev) if (err) goto fail_free; - INIT_LIST_HEAD(&fdtv->list); - spin_lock_irqsave(&fdtv_list_lock, flags); - list_add_tail(&fdtv->list, &fdtv_list); - spin_unlock_irqrestore(&fdtv_list_lock, flags); + spin_lock_irq(&node_list_lock); + list_add_tail(&fdtv->list, &node_list); + spin_unlock_irq(&node_list_lock); err = avc_identify_subunit(fdtv); if (err) goto fail; - err = fdtv_dvbdev_init(fdtv, dev); + err = fdtv_dvb_register(fdtv); if (err) goto fail; avc_register_remote_control(fdtv); return 0; - fail: - spin_lock_irqsave(&fdtv_list_lock, flags); + spin_lock_irq(&node_list_lock); list_del(&fdtv->list); - spin_unlock_irqrestore(&fdtv_list_lock, flags); + spin_unlock_irq(&node_list_lock); fdtv_unregister_rc(fdtv); fail_free: kfree(fdtv); return err; } -static int fdtv_remove(struct device *dev) +static int node_remove(struct device *dev) { struct firedtv *fdtv = dev->driver_data; - unsigned long flags; - fdtv_ca_release(fdtv); - dvb_unregister_frontend(&fdtv->fe); - dvb_net_release(&fdtv->dvbnet); - fdtv->demux.dmx.close(&fdtv->demux.dmx); - fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, - &fdtv->frontend); - dvb_dmxdev_release(&fdtv->dmxdev); - dvb_dmx_release(&fdtv->demux); - dvb_unregister_adapter(&fdtv->adapter); - - spin_lock_irqsave(&fdtv_list_lock, flags); + fdtv_dvb_unregister(fdtv); + + spin_lock_irq(&node_list_lock); list_del(&fdtv->list); - spin_unlock_irqrestore(&fdtv_list_lock, flags); + spin_unlock_irq(&node_list_lock); cancel_work_sync(&fdtv->remote_ctrl_work); fdtv_unregister_rc(fdtv); @@ -232,7 +240,7 @@ static int fdtv_remove(struct device *dev) return 0; } -static int fdtv_update(struct unit_directory *ud) +static int node_update(struct unit_directory *ud) { struct firedtv *fdtv = ud->device.driver_data; @@ -243,17 +251,11 @@ static int fdtv_update(struct unit_directory *ud) } static struct hpsb_protocol_driver fdtv_driver = { - .name = "firedtv", - .id_table = fdtv_id_table, - .update = fdtv_update, - + .update = node_update, .driver = { - //.name and .bus are filled in for us in more recent linux versions - //.name = "FireDTV", - //.bus = &ieee1394_bus_type, - .probe = fdtv_probe, - .remove = fdtv_remove, + .probe = node_probe, + .remove = node_remove, }, }; @@ -262,11 +264,12 @@ static struct hpsb_highlevel fdtv_highlevel = { .fcp_request = fcp_request, }; -static int __init fdtv_init(void) +int __init fdtv_1394_init(struct ieee1394_device_id id_table[]) { int ret; hpsb_register_highlevel(&fdtv_highlevel); + fdtv_driver.id_table = id_table; ret = hpsb_register_protocol(&fdtv_driver); if (ret) { printk(KERN_ERR "firedtv: failed to register protocol\n"); @@ -275,17 +278,8 @@ static int __init fdtv_init(void) return ret; } -static void __exit fdtv_exit(void) +void __exit fdtv_1394_exit(void) { hpsb_unregister_protocol(&fdtv_driver); hpsb_unregister_highlevel(&fdtv_highlevel); } - -module_init(fdtv_init); -module_exit(fdtv_exit); - -MODULE_AUTHOR("Andreas Monitzer "); -MODULE_AUTHOR("Ben Backx "); -MODULE_DESCRIPTION("FireDTV DVB Driver"); -MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("FireDTV DVB"); diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c new file mode 100644 index 00000000000..b55d9ccaf33 --- /dev/null +++ b/drivers/media/dvb/firewire/firedtv-avc.c @@ -0,0 +1,1315 @@ +/* + * FireDTV driver (formerly known as FireSAT) + * + * Copyright (C) 2004 Andreas Monitzer + * Copyright (C) 2008 Ben Backx + * Copyright (C) 2008 Henrik Kurelid + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "firedtv.h" + +#define FCP_COMMAND_REGISTER 0xfffff0000b00ULL + +#define AVC_CTYPE_CONTROL 0x0 +#define AVC_CTYPE_STATUS 0x1 +#define AVC_CTYPE_NOTIFY 0x3 + +#define AVC_RESPONSE_ACCEPTED 0x9 +#define AVC_RESPONSE_STABLE 0xc +#define AVC_RESPONSE_CHANGED 0xd +#define AVC_RESPONSE_INTERIM 0xf + +#define AVC_SUBUNIT_TYPE_TUNER (0x05 << 3) +#define AVC_SUBUNIT_TYPE_UNIT (0x1f << 3) + +#define AVC_OPCODE_VENDOR 0x00 +#define AVC_OPCODE_READ_DESCRIPTOR 0x09 +#define AVC_OPCODE_DSIT 0xc8 +#define AVC_OPCODE_DSD 0xcb + +#define DESCRIPTOR_TUNER_STATUS 0x80 +#define DESCRIPTOR_SUBUNIT_IDENTIFIER 0x00 + +#define SFE_VENDOR_DE_COMPANYID_0 0x00 /* OUI of Digital Everywhere */ +#define SFE_VENDOR_DE_COMPANYID_1 0x12 +#define SFE_VENDOR_DE_COMPANYID_2 0x87 + +#define SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL 0x0a +#define SFE_VENDOR_OPCODE_LNB_CONTROL 0x52 +#define SFE_VENDOR_OPCODE_TUNE_QPSK 0x58 /* for DVB-S */ + +#define SFE_VENDOR_OPCODE_GET_FIRMWARE_VERSION 0x00 +#define SFE_VENDOR_OPCODE_HOST2CA 0x56 +#define SFE_VENDOR_OPCODE_CA2HOST 0x57 +#define SFE_VENDOR_OPCODE_CISTATUS 0x59 +#define SFE_VENDOR_OPCODE_TUNE_QPSK2 0x60 /* for DVB-S2 */ + +#define SFE_VENDOR_TAG_CA_RESET 0x00 +#define SFE_VENDOR_TAG_CA_APPLICATION_INFO 0x01 +#define SFE_VENDOR_TAG_CA_PMT 0x02 +#define SFE_VENDOR_TAG_CA_DATE_TIME 0x04 +#define SFE_VENDOR_TAG_CA_MMI 0x05 +#define SFE_VENDOR_TAG_CA_ENTER_MENU 0x07 + +#define EN50221_LIST_MANAGEMENT_ONLY 0x03 +#define EN50221_TAG_APP_INFO 0x9f8021 +#define EN50221_TAG_CA_INFO 0x9f8031 + +struct avc_command_frame { + int length; + u8 ctype; + u8 subunit; + u8 opcode; + u8 operand[509]; +}; + +struct avc_response_frame { + int length; + u8 response; + u8 subunit; + u8 opcode; + u8 operand[509]; +}; + +#define AVC_DEBUG_FCP_SUBACTIONS 1 +#define AVC_DEBUG_FCP_PAYLOADS 2 + +static int avc_debug; +module_param_named(debug, avc_debug, int, 0644); +MODULE_PARM_DESC(debug, "Verbose logging (default = 0" + ", FCP subactions = " __stringify(AVC_DEBUG_FCP_SUBACTIONS) + ", FCP payloads = " __stringify(AVC_DEBUG_FCP_PAYLOADS) + ", or all = -1)"); + +static const char *debug_fcp_ctype(unsigned int ctype) +{ + static const char *ctypes[] = { + [0x0] = "CONTROL", [0x1] = "STATUS", + [0x2] = "SPECIFIC INQUIRY", [0x3] = "NOTIFY", + [0x4] = "GENERAL INQUIRY", [0x8] = "NOT IMPLEMENTED", + [0x9] = "ACCEPTED", [0xa] = "REJECTED", + [0xb] = "IN TRANSITION", [0xc] = "IMPLEMENTED/STABLE", + [0xd] = "CHANGED", [0xf] = "INTERIM", + }; + const char *ret = ctype < ARRAY_SIZE(ctypes) ? ctypes[ctype] : NULL; + + return ret ? ret : "?"; +} + +static const char *debug_fcp_opcode(unsigned int opcode, + const u8 *data, size_t length) +{ + switch (opcode) { + case AVC_OPCODE_VENDOR: break; + case AVC_OPCODE_READ_DESCRIPTOR: return "ReadDescriptor"; + case AVC_OPCODE_DSIT: return "DirectSelectInfo.Type"; + case AVC_OPCODE_DSD: return "DirectSelectData"; + default: return "?"; + } + + if (length < 7 || + data[3] != SFE_VENDOR_DE_COMPANYID_0 || + data[4] != SFE_VENDOR_DE_COMPANYID_1 || + data[5] != SFE_VENDOR_DE_COMPANYID_2) + return "Vendor"; + + switch (data[6]) { + case SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL: return "RegisterRC"; + case SFE_VENDOR_OPCODE_LNB_CONTROL: return "LNBControl"; + case SFE_VENDOR_OPCODE_TUNE_QPSK: return "TuneQPSK"; + case SFE_VENDOR_OPCODE_HOST2CA: return "Host2CA"; + case SFE_VENDOR_OPCODE_CA2HOST: return "CA2Host"; + } + return "Vendor"; +} + +static void debug_fcp(const u8 *data, size_t length) +{ + unsigned int subunit_type, subunit_id, op; + const char *prefix = data[0] > 7 ? "FCP <- " : "FCP -> "; + + if (avc_debug & AVC_DEBUG_FCP_SUBACTIONS) { + subunit_type = data[1] >> 3; + subunit_id = data[1] & 7; + op = subunit_type == 0x1e || subunit_id == 5 ? ~0 : data[2]; + printk(KERN_INFO "%ssu=%x.%x l=%d: %-8s - %s\n", + prefix, subunit_type, subunit_id, length, + debug_fcp_ctype(data[0]), + debug_fcp_opcode(op, data, length)); + } + + if (avc_debug & AVC_DEBUG_FCP_PAYLOADS) + print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_NONE, 16, 1, + data, length, false); +} + +static int __avc_write(struct firedtv *fdtv, + const struct avc_command_frame *c, struct avc_response_frame *r) +{ + int err, retry; + + if (r) + fdtv->avc_reply_received = false; + + for (retry = 0; retry < 6; retry++) { + if (unlikely(avc_debug)) + debug_fcp(&c->ctype, c->length); + + err = fdtv->backend->write(fdtv, FCP_COMMAND_REGISTER, + (void *)&c->ctype, c->length); + if (err) { + fdtv->avc_reply_received = true; + dev_err(fdtv->device, "FCP command write failed\n"); + return err; + } + + if (!r) + return 0; + + /* + * AV/C specs say that answers should be sent within 150 ms. + * Time out after 200 ms. + */ + if (wait_event_timeout(fdtv->avc_wait, + fdtv->avc_reply_received, + msecs_to_jiffies(200)) != 0) { + r->length = fdtv->response_length; + memcpy(&r->response, fdtv->response, r->length); + + return 0; + } + } + dev_err(fdtv->device, "FCP response timed out\n"); + return -ETIMEDOUT; +} + +static int avc_write(struct firedtv *fdtv, + const struct avc_command_frame *c, struct avc_response_frame *r) +{ + int ret; + + if (mutex_lock_interruptible(&fdtv->avc_mutex)) + return -EINTR; + + ret = __avc_write(fdtv, c, r); + + mutex_unlock(&fdtv->avc_mutex); + return ret; +} + +int avc_recv(struct firedtv *fdtv, void *data, size_t length) +{ + struct avc_response_frame *r = + data - offsetof(struct avc_response_frame, response); + + if (unlikely(avc_debug)) + debug_fcp(data, length); + + if (length >= 8 && + r->operand[0] == SFE_VENDOR_DE_COMPANYID_0 && + r->operand[1] == SFE_VENDOR_DE_COMPANYID_1 && + r->operand[2] == SFE_VENDOR_DE_COMPANYID_2 && + r->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) { + if (r->response == AVC_RESPONSE_CHANGED) { + fdtv_handle_rc(fdtv, + r->operand[4] << 8 | r->operand[5]); + schedule_work(&fdtv->remote_ctrl_work); + } else if (r->response != AVC_RESPONSE_INTERIM) { + dev_info(fdtv->device, + "remote control result = %d\n", r->response); + } + return 0; + } + + if (fdtv->avc_reply_received) { + dev_err(fdtv->device, "out-of-order AVC response, ignored\n"); + return -EIO; + } + + memcpy(fdtv->response, data, length); + fdtv->response_length = length; + + fdtv->avc_reply_received = true; + wake_up(&fdtv->avc_wait); + + return 0; +} + +/* + * tuning command for setting the relative LNB frequency + * (not supported by the AVC standard) + */ +static void avc_tuner_tuneqpsk(struct firedtv *fdtv, + struct dvb_frontend_parameters *params, + struct avc_command_frame *c) +{ + c->opcode = AVC_OPCODE_VENDOR; + + c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; + c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; + c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; + c->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK; + + c->operand[4] = (params->frequency >> 24) & 0xff; + c->operand[5] = (params->frequency >> 16) & 0xff; + c->operand[6] = (params->frequency >> 8) & 0xff; + c->operand[7] = params->frequency & 0xff; + + c->operand[8] = ((params->u.qpsk.symbol_rate / 1000) >> 8) & 0xff; + c->operand[9] = (params->u.qpsk.symbol_rate / 1000) & 0xff; + + switch (params->u.qpsk.fec_inner) { + case FEC_1_2: c->operand[10] = 0x1; break; + case FEC_2_3: c->operand[10] = 0x2; break; + case FEC_3_4: c->operand[10] = 0x3; break; + case FEC_5_6: c->operand[10] = 0x4; break; + case FEC_7_8: c->operand[10] = 0x5; break; + case FEC_4_5: + case FEC_8_9: + case FEC_AUTO: + default: c->operand[10] = 0x0; + } + + if (fdtv->voltage == 0xff) + c->operand[11] = 0xff; + else if (fdtv->voltage == SEC_VOLTAGE_18) /* polarisation */ + c->operand[11] = 0; + else + c->operand[11] = 1; + + if (fdtv->tone == 0xff) + c->operand[12] = 0xff; + else if (fdtv->tone == SEC_TONE_ON) /* band */ + c->operand[12] = 1; + else + c->operand[12] = 0; + + if (fdtv->type == FIREDTV_DVB_S2) { + c->operand[13] = 0x1; + c->operand[14] = 0xff; + c->operand[15] = 0xff; + c->length = 20; + } else { + c->length = 16; + } +} + +static void avc_tuner_dsd_dvb_c(struct dvb_frontend_parameters *params, + struct avc_command_frame *c) +{ + c->opcode = AVC_OPCODE_DSD; + + c->operand[0] = 0; /* source plug */ + c->operand[1] = 0xd2; /* subfunction replace */ + c->operand[2] = 0x20; /* system id = DVB */ + c->operand[3] = 0x00; /* antenna number */ + c->operand[4] = 0x11; /* system_specific_multiplex selection_length */ + + /* multiplex_valid_flags, high byte */ + c->operand[5] = 0 << 7 /* reserved */ + | 0 << 6 /* Polarisation */ + | 0 << 5 /* Orbital_Pos */ + | 1 << 4 /* Frequency */ + | 1 << 3 /* Symbol_Rate */ + | 0 << 2 /* FEC_outer */ + | (params->u.qam.fec_inner != FEC_AUTO ? 1 << 1 : 0) + | (params->u.qam.modulation != QAM_AUTO ? 1 << 0 : 0); + + /* multiplex_valid_flags, low byte */ + c->operand[6] = 0 << 7 /* NetworkID */ + | 0 << 0 /* reserved */ ; + + c->operand[7] = 0x00; + c->operand[8] = 0x00; + c->operand[9] = 0x00; + c->operand[10] = 0x00; + + c->operand[11] = (((params->frequency / 4000) >> 16) & 0xff) | (2 << 6); + c->operand[12] = ((params->frequency / 4000) >> 8) & 0xff; + c->operand[13] = (params->frequency / 4000) & 0xff; + c->operand[14] = ((params->u.qpsk.symbol_rate / 1000) >> 12) & 0xff; + c->operand[15] = ((params->u.qpsk.symbol_rate / 1000) >> 4) & 0xff; + c->operand[16] = ((params->u.qpsk.symbol_rate / 1000) << 4) & 0xf0; + c->operand[17] = 0x00; + + switch (params->u.qpsk.fec_inner) { + case FEC_1_2: c->operand[18] = 0x1; break; + case FEC_2_3: c->operand[18] = 0x2; break; + case FEC_3_4: c->operand[18] = 0x3; break; + case FEC_5_6: c->operand[18] = 0x4; break; + case FEC_7_8: c->operand[18] = 0x5; break; + case FEC_8_9: c->operand[18] = 0x6; break; + case FEC_4_5: c->operand[18] = 0x8; break; + case FEC_AUTO: + default: c->operand[18] = 0x0; + } + + switch (params->u.qam.modulation) { + case QAM_16: c->operand[19] = 0x08; break; + case QAM_32: c->operand[19] = 0x10; break; + case QAM_64: c->operand[19] = 0x18; break; + case QAM_128: c->operand[19] = 0x20; break; + case QAM_256: c->operand[19] = 0x28; break; + case QAM_AUTO: + default: c->operand[19] = 0x00; + } + + c->operand[20] = 0x00; + c->operand[21] = 0x00; + /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */ + c->operand[22] = 0x00; + + c->length = 28; +} + +static void avc_tuner_dsd_dvb_t(struct dvb_frontend_parameters *params, + struct avc_command_frame *c) +{ + struct dvb_ofdm_parameters *ofdm = ¶ms->u.ofdm; + + c->opcode = AVC_OPCODE_DSD; + + c->operand[0] = 0; /* source plug */ + c->operand[1] = 0xd2; /* subfunction replace */ + c->operand[2] = 0x20; /* system id = DVB */ + c->operand[3] = 0x00; /* antenna number */ + c->operand[4] = 0x0c; /* system_specific_multiplex selection_length */ + + /* multiplex_valid_flags, high byte */ + c->operand[5] = + 0 << 7 /* reserved */ + | 1 << 6 /* CenterFrequency */ + | (ofdm->bandwidth != BANDWIDTH_AUTO ? 1 << 5 : 0) + | (ofdm->constellation != QAM_AUTO ? 1 << 4 : 0) + | (ofdm->hierarchy_information != HIERARCHY_AUTO ? 1 << 3 : 0) + | (ofdm->code_rate_HP != FEC_AUTO ? 1 << 2 : 0) + | (ofdm->code_rate_LP != FEC_AUTO ? 1 << 1 : 0) + | (ofdm->guard_interval != GUARD_INTERVAL_AUTO ? 1 << 0 : 0); + + /* multiplex_valid_flags, low byte */ + c->operand[6] = + 0 << 7 /* NetworkID */ + | (ofdm->transmission_mode != TRANSMISSION_MODE_AUTO ? 1 << 6 : 0) + | 0 << 5 /* OtherFrequencyFlag */ + | 0 << 0 /* reserved */ ; + + c->operand[7] = 0x0; + c->operand[8] = (params->frequency / 10) >> 24; + c->operand[9] = ((params->frequency / 10) >> 16) & 0xff; + c->operand[10] = ((params->frequency / 10) >> 8) & 0xff; + c->operand[11] = (params->frequency / 10) & 0xff; + + switch (ofdm->bandwidth) { + case BANDWIDTH_7_MHZ: c->operand[12] = 0x20; break; + case BANDWIDTH_8_MHZ: + case BANDWIDTH_6_MHZ: /* not defined by AVC spec */ + case BANDWIDTH_AUTO: + default: c->operand[12] = 0x00; + } + + switch (ofdm->constellation) { + case QAM_16: c->operand[13] = 1 << 6; break; + case QAM_64: c->operand[13] = 2 << 6; break; + case QPSK: + default: c->operand[13] = 0x00; + } + + switch (ofdm->hierarchy_information) { + case HIERARCHY_1: c->operand[13] |= 1 << 3; break; + case HIERARCHY_2: c->operand[13] |= 2 << 3; break; + case HIERARCHY_4: c->operand[13] |= 3 << 3; break; + case HIERARCHY_AUTO: + case HIERARCHY_NONE: + default: break; + } + + switch (ofdm->code_rate_HP) { + case FEC_2_3: c->operand[13] |= 1; break; + case FEC_3_4: c->operand[13] |= 2; break; + case FEC_5_6: c->operand[13] |= 3; break; + case FEC_7_8: c->operand[13] |= 4; break; + case FEC_1_2: + default: break; + } + + switch (ofdm->code_rate_LP) { + case FEC_2_3: c->operand[14] = 1 << 5; break; + case FEC_3_4: c->operand[14] = 2 << 5; break; + case FEC_5_6: c->operand[14] = 3 << 5; break; + case FEC_7_8: c->operand[14] = 4 << 5; break; + case FEC_1_2: + default: c->operand[14] = 0x00; break; + } + + switch (ofdm->guard_interval) { + case GUARD_INTERVAL_1_16: c->operand[14] |= 1 << 3; break; + case GUARD_INTERVAL_1_8: c->operand[14] |= 2 << 3; break; + case GUARD_INTERVAL_1_4: c->operand[14] |= 3 << 3; break; + case GUARD_INTERVAL_1_32: + case GUARD_INTERVAL_AUTO: + default: break; + } + + switch (ofdm->transmission_mode) { + case TRANSMISSION_MODE_8K: c->operand[14] |= 1 << 1; break; + case TRANSMISSION_MODE_2K: + case TRANSMISSION_MODE_AUTO: + default: break; + } + + c->operand[15] = 0x00; /* network_ID[0] */ + c->operand[16] = 0x00; /* network_ID[1] */ + /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */ + c->operand[17] = 0x00; + + c->length = 24; +} + +int avc_tuner_dsd(struct firedtv *fdtv, + struct dvb_frontend_parameters *params) +{ + char buffer[sizeof(struct avc_command_frame)]; + struct avc_command_frame *c = (void *)buffer; + struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ + + memset(c, 0, sizeof(*c)); + + c->ctype = AVC_CTYPE_CONTROL; + c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; + + switch (fdtv->type) { + case FIREDTV_DVB_S: + case FIREDTV_DVB_S2: avc_tuner_tuneqpsk(fdtv, params, c); break; + case FIREDTV_DVB_C: avc_tuner_dsd_dvb_c(params, c); break; + case FIREDTV_DVB_T: avc_tuner_dsd_dvb_t(params, c); break; + default: + BUG(); + } + + if (avc_write(fdtv, c, r) < 0) + return -EIO; + + msleep(500); +#if 0 + /* FIXME: */ + /* u8 *status was an out-parameter of avc_tuner_dsd, unused by caller */ + if (status) + *status = r->operand[2]; +#endif + return 0; +} + +int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]) +{ + char buffer[sizeof(struct avc_command_frame)]; + struct avc_command_frame *c = (void *)buffer; + struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ + int pos, k; + + if (pidc > 16 && pidc != 0xff) + return -EINVAL; + + memset(c, 0, sizeof(*c)); + + c->ctype = AVC_CTYPE_CONTROL; + c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; + c->opcode = AVC_OPCODE_DSD; + + c->operand[0] = 0; /* source plug */ + c->operand[1] = 0xd2; /* subfunction replace */ + c->operand[2] = 0x20; /* system id = DVB */ + c->operand[3] = 0x00; /* antenna number */ + c->operand[4] = 0x00; /* system_specific_multiplex selection_length */ + c->operand[5] = pidc; /* Nr_of_dsd_sel_specs */ + + pos = 6; + if (pidc != 0xff) + for (k = 0; k < pidc; k++) { + c->operand[pos++] = 0x13; /* flowfunction relay */ + c->operand[pos++] = 0x80; /* dsd_sel_spec_valid_flags -> PID */ + c->operand[pos++] = (pid[k] >> 8) & 0x1f; + c->operand[pos++] = pid[k] & 0xff; + c->operand[pos++] = 0x00; /* tableID */ + c->operand[pos++] = 0x00; /* filter_length */ + } + + c->length = ALIGN(3 + pos, 4); + + if (avc_write(fdtv, c, r) < 0) + return -EIO; + + msleep(50); + return 0; +} + +int avc_tuner_get_ts(struct firedtv *fdtv) +{ + char buffer[sizeof(struct avc_command_frame)]; + struct avc_command_frame *c = (void *)buffer; + struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ + int sl; + + memset(c, 0, sizeof(*c)); + + c->ctype = AVC_CTYPE_CONTROL; + c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; + c->opcode = AVC_OPCODE_DSIT; + + sl = fdtv->type == FIREDTV_DVB_T ? 0x0c : 0x11; + + c->operand[0] = 0; /* source plug */ + c->operand[1] = 0xd2; /* subfunction replace */ + c->operand[2] = 0xff; /* status */ + c->operand[3] = 0x20; /* system id = DVB */ + c->operand[4] = 0x00; /* antenna number */ + c->operand[5] = 0x0; /* system_specific_search_flags */ + c->operand[6] = sl; /* system_specific_multiplex selection_length */ + c->operand[7] = 0x00; /* valid_flags [0] */ + c->operand[8] = 0x00; /* valid_flags [1] */ + c->operand[7 + sl] = 0x00; /* nr_of_dsit_sel_specs (always 0) */ + + c->length = fdtv->type == FIREDTV_DVB_T ? 24 : 28; + + if (avc_write(fdtv, c, r) < 0) + return -EIO; + + msleep(250); + return 0; +} + +int avc_identify_subunit(struct firedtv *fdtv) +{ + char buffer[sizeof(struct avc_command_frame)]; + struct avc_command_frame *c = (void *)buffer; + struct avc_response_frame *r = (void *)buffer; + + memset(c, 0, sizeof(*c)); + + c->ctype = AVC_CTYPE_CONTROL; + c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; + c->opcode = AVC_OPCODE_READ_DESCRIPTOR; + + c->operand[0] = DESCRIPTOR_SUBUNIT_IDENTIFIER; + c->operand[1] = 0xff; + c->operand[2] = 0x00; + c->operand[3] = 0x00; /* length highbyte */ + c->operand[4] = 0x08; /* length lowbyte */ + c->operand[5] = 0x00; /* offset highbyte */ + c->operand[6] = 0x0d; /* offset lowbyte */ + + c->length = 12; + + if (avc_write(fdtv, c, r) < 0) + return -EIO; + + if ((r->response != AVC_RESPONSE_STABLE && + r->response != AVC_RESPONSE_ACCEPTED) || + (r->operand[3] << 8) + r->operand[4] != 8) { + dev_err(fdtv->device, "cannot read subunit identifier\n"); + return -EINVAL; + } + return 0; +} + +#define SIZEOF_ANTENNA_INPUT_INFO 22 + +int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat) +{ + char buffer[sizeof(struct avc_command_frame)]; + struct avc_command_frame *c = (void *)buffer; + struct avc_response_frame *r = (void *)buffer; + int length; + + memset(c, 0, sizeof(*c)); + + c->ctype = AVC_CTYPE_CONTROL; + c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; + c->opcode = AVC_OPCODE_READ_DESCRIPTOR; + + c->operand[0] = DESCRIPTOR_TUNER_STATUS; + c->operand[1] = 0xff; /* read_result_status */ + c->operand[2] = 0x00; /* reserved */ + c->operand[3] = 0; /* SIZEOF_ANTENNA_INPUT_INFO >> 8; */ + c->operand[4] = 0; /* SIZEOF_ANTENNA_INPUT_INFO & 0xff; */ + c->operand[5] = 0x00; + c->operand[6] = 0x00; + + c->length = 12; + + if (avc_write(fdtv, c, r) < 0) + return -EIO; + + if (r->response != AVC_RESPONSE_STABLE && + r->response != AVC_RESPONSE_ACCEPTED) { + dev_err(fdtv->device, "cannot read tuner status\n"); + return -EINVAL; + } + + length = r->operand[9]; + if (r->operand[1] != 0x10 || length != SIZEOF_ANTENNA_INPUT_INFO) { + dev_err(fdtv->device, "got invalid tuner status\n"); + return -EINVAL; + } + + stat->active_system = r->operand[10]; + stat->searching = r->operand[11] >> 7 & 1; + stat->moving = r->operand[11] >> 6 & 1; + stat->no_rf = r->operand[11] >> 5 & 1; + stat->input = r->operand[12] >> 7 & 1; + stat->selected_antenna = r->operand[12] & 0x7f; + stat->ber = r->operand[13] << 24 | + r->operand[14] << 16 | + r->operand[15] << 8 | + r->operand[16]; + stat->signal_strength = r->operand[17]; + stat->raster_frequency = r->operand[18] >> 6 & 2; + stat->rf_frequency = (r->operand[18] & 0x3f) << 16 | + r->operand[19] << 8 | + r->operand[20]; + stat->man_dep_info_length = r->operand[21]; + stat->front_end_error = r->operand[22] >> 4 & 1; + stat->antenna_error = r->operand[22] >> 3 & 1; + stat->front_end_power_status = r->operand[22] >> 1 & 1; + stat->power_supply = r->operand[22] & 1; + stat->carrier_noise_ratio = r->operand[23] << 8 | + r->operand[24]; + stat->power_supply_voltage = r->operand[27]; + stat->antenna_voltage = r->operand[28]; + stat->firewire_bus_voltage = r->operand[29]; + stat->ca_mmi = r->operand[30] & 1; + stat->ca_pmt_reply = r->operand[31] >> 7 & 1; + stat->ca_date_time_request = r->operand[31] >> 6 & 1; + stat->ca_application_info = r->operand[31] >> 5 & 1; + stat->ca_module_present_status = r->operand[31] >> 4 & 1; + stat->ca_dvb_flag = r->operand[31] >> 3 & 1; + stat->ca_error_flag = r->operand[31] >> 2 & 1; + stat->ca_initialization_status = r->operand[31] >> 1 & 1; + + return 0; +} + +int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst, + char conttone, char nrdiseq, + struct dvb_diseqc_master_cmd *diseqcmd) +{ + char buffer[sizeof(struct avc_command_frame)]; + struct avc_command_frame *c = (void *)buffer; + struct avc_response_frame *r = (void *)buffer; + int i, j, k; + + memset(c, 0, sizeof(*c)); + + c->ctype = AVC_CTYPE_CONTROL; + c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; + c->opcode = AVC_OPCODE_VENDOR; + + c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; + c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; + c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; + c->operand[3] = SFE_VENDOR_OPCODE_LNB_CONTROL; + + c->operand[4] = voltage; + c->operand[5] = nrdiseq; + + i = 6; + + for (j = 0; j < nrdiseq; j++) { + c->operand[i++] = diseqcmd[j].msg_len; + + for (k = 0; k < diseqcmd[j].msg_len; k++) + c->operand[i++] = diseqcmd[j].msg[k]; + } + + c->operand[i++] = burst; + c->operand[i++] = conttone; + + c->length = ALIGN(3 + i, 4); + + if (avc_write(fdtv, c, r) < 0) + return -EIO; + + if (r->response != AVC_RESPONSE_ACCEPTED) { + dev_err(fdtv->device, "LNB control failed\n"); + return -EINVAL; + } + + return 0; +} + +int avc_register_remote_control(struct firedtv *fdtv) +{ + char buffer[sizeof(struct avc_command_frame)]; + struct avc_command_frame *c = (void *)buffer; + + memset(c, 0, sizeof(*c)); + + c->ctype = AVC_CTYPE_NOTIFY; + c->subunit = AVC_SUBUNIT_TYPE_UNIT | 7; + c->opcode = AVC_OPCODE_VENDOR; + + c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; + c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; + c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; + c->operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL; + + c->length = 8; + + return avc_write(fdtv, c, NULL); +} + +void avc_remote_ctrl_work(struct work_struct *work) +{ + struct firedtv *fdtv = + container_of(work, struct firedtv, remote_ctrl_work); + + /* Should it be rescheduled in failure cases? */ + avc_register_remote_control(fdtv); +} + +#if 0 /* FIXME: unused */ +int avc_tuner_host2ca(struct firedtv *fdtv) +{ + char buffer[sizeof(struct avc_command_frame)]; + struct avc_command_frame *c = (void *)buffer; + struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ + + memset(c, 0, sizeof(*c)); + + c->ctype = AVC_CTYPE_CONTROL; + c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; + c->opcode = AVC_OPCODE_VENDOR; + + c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; + c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; + c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; + c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA; + c->operand[4] = 0; /* slot */ + c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ + c->operand[6] = 0; /* more/last */ + c->operand[7] = 0; /* length */ + + c->length = 12; + + if (avc_write(fdtv, c, r) < 0) + return -EIO; + + return 0; +} +#endif + +static int get_ca_object_pos(struct avc_response_frame *r) +{ + int length = 1; + + /* Check length of length field */ + if (r->operand[7] & 0x80) + length = (r->operand[7] & 0x7f) + 1; + return length + 7; +} + +static int get_ca_object_length(struct avc_response_frame *r) +{ +#if 0 /* FIXME: unused */ + int size = 0; + int i; + + if (r->operand[7] & 0x80) + for (i = 0; i < (r->operand[7] & 0x7f); i++) { + size <<= 8; + size += r->operand[8 + i]; + } +#endif + return r->operand[7]; +} + +int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len) +{ + char buffer[sizeof(struct avc_command_frame)]; + struct avc_command_frame *c = (void *)buffer; + struct avc_response_frame *r = (void *)buffer; + int pos; + + memset(c, 0, sizeof(*c)); + + c->ctype = AVC_CTYPE_STATUS; + c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; + c->opcode = AVC_OPCODE_VENDOR; + + c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; + c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; + c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; + c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; + c->operand[4] = 0; /* slot */ + c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ + + c->length = 12; + + if (avc_write(fdtv, c, r) < 0) + return -EIO; + + /* FIXME: check response code and validate response data */ + + pos = get_ca_object_pos(r); + app_info[0] = (EN50221_TAG_APP_INFO >> 16) & 0xff; + app_info[1] = (EN50221_TAG_APP_INFO >> 8) & 0xff; + app_info[2] = (EN50221_TAG_APP_INFO >> 0) & 0xff; + app_info[3] = 6 + r->operand[pos + 4]; + app_info[4] = 0x01; + memcpy(&app_info[5], &r->operand[pos], 5 + r->operand[pos + 4]); + *len = app_info[3] + 4; + + return 0; +} + +int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len) +{ + char buffer[sizeof(struct avc_command_frame)]; + struct avc_command_frame *c = (void *)buffer; + struct avc_response_frame *r = (void *)buffer; + int pos; + + memset(c, 0, sizeof(*c)); + + c->ctype = AVC_CTYPE_STATUS; + c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; + c->opcode = AVC_OPCODE_VENDOR; + + c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; + c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; + c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; + c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; + c->operand[4] = 0; /* slot */ + c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ + + c->length = 12; + + if (avc_write(fdtv, c, r) < 0) + return -EIO; + + pos = get_ca_object_pos(r); + app_info[0] = (EN50221_TAG_CA_INFO >> 16) & 0xff; + app_info[1] = (EN50221_TAG_CA_INFO >> 8) & 0xff; + app_info[2] = (EN50221_TAG_CA_INFO >> 0) & 0xff; + app_info[3] = 2; + app_info[4] = r->operand[pos + 0]; + app_info[5] = r->operand[pos + 1]; + *len = app_info[3] + 4; + + return 0; +} + +int avc_ca_reset(struct firedtv *fdtv) +{ + char buffer[sizeof(struct avc_command_frame)]; + struct avc_command_frame *c = (void *)buffer; + struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ + + memset(c, 0, sizeof(*c)); + + c->ctype = AVC_CTYPE_CONTROL; + c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; + c->opcode = AVC_OPCODE_VENDOR; + + c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; + c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; + c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; + c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA; + c->operand[4] = 0; /* slot */ + c->operand[5] = SFE_VENDOR_TAG_CA_RESET; /* ca tag */ + c->operand[6] = 0; /* more/last */ + c->operand[7] = 1; /* length */ + c->operand[8] = 0; /* force hardware reset */ + + c->length = 12; + + if (avc_write(fdtv, c, r) < 0) + return -EIO; + + return 0; +} + +int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length) +{ + char buffer[sizeof(struct avc_command_frame)]; + struct avc_command_frame *c = (void *)buffer; + struct avc_response_frame *r = (void *)buffer; + int list_management; + int program_info_length; + int pmt_cmd_id; + int read_pos; + int write_pos; + int es_info_length; + int crc32_csum; + + memset(c, 0, sizeof(*c)); + + c->ctype = AVC_CTYPE_CONTROL; + c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; + c->opcode = AVC_OPCODE_VENDOR; + + if (msg[0] != EN50221_LIST_MANAGEMENT_ONLY) { + dev_info(fdtv->device, "forcing list_management to ONLY\n"); + msg[0] = EN50221_LIST_MANAGEMENT_ONLY; + } + /* We take the cmd_id from the programme level only! */ + list_management = msg[0]; + program_info_length = ((msg[4] & 0x0f) << 8) + msg[5]; + if (program_info_length > 0) + program_info_length--; /* Remove pmt_cmd_id */ + pmt_cmd_id = msg[6]; + + c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; + c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; + c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; + c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA; + c->operand[4] = 0; /* slot */ + c->operand[5] = SFE_VENDOR_TAG_CA_PMT; /* ca tag */ + c->operand[6] = 0; /* more/last */ + /* c->operand[7] = XXXprogram_info_length + 17; */ /* length */ + c->operand[8] = list_management; + c->operand[9] = 0x01; /* pmt_cmd=OK_descramble */ + + /* TS program map table */ + + c->operand[10] = 0x02; /* Table id=2 */ + c->operand[11] = 0x80; /* Section syntax + length */ + /* c->operand[12] = XXXprogram_info_length + 12; */ + c->operand[13] = msg[1]; /* Program number */ + c->operand[14] = msg[2]; + c->operand[15] = 0x01; /* Version number=0 + current/next=1 */ + c->operand[16] = 0x00; /* Section number=0 */ + c->operand[17] = 0x00; /* Last section number=0 */ + c->operand[18] = 0x1f; /* PCR_PID=1FFF */ + c->operand[19] = 0xff; + c->operand[20] = (program_info_length >> 8); /* Program info length */ + c->operand[21] = (program_info_length & 0xff); + + /* CA descriptors at programme level */ + read_pos = 6; + write_pos = 22; + if (program_info_length > 0) { + pmt_cmd_id = msg[read_pos++]; + if (pmt_cmd_id != 1 && pmt_cmd_id != 4) + dev_err(fdtv->device, + "invalid pmt_cmd_id %d\n", pmt_cmd_id); + + memcpy(&c->operand[write_pos], &msg[read_pos], + program_info_length); + read_pos += program_info_length; + write_pos += program_info_length; + } + while (read_pos < length) { + c->operand[write_pos++] = msg[read_pos++]; + c->operand[write_pos++] = msg[read_pos++]; + c->operand[write_pos++] = msg[read_pos++]; + es_info_length = + ((msg[read_pos] & 0x0f) << 8) + msg[read_pos + 1]; + read_pos += 2; + if (es_info_length > 0) + es_info_length--; /* Remove pmt_cmd_id */ + c->operand[write_pos++] = es_info_length >> 8; + c->operand[write_pos++] = es_info_length & 0xff; + if (es_info_length > 0) { + pmt_cmd_id = msg[read_pos++]; + if (pmt_cmd_id != 1 && pmt_cmd_id != 4) + dev_err(fdtv->device, "invalid pmt_cmd_id %d " + "at stream level\n", pmt_cmd_id); + + memcpy(&c->operand[write_pos], &msg[read_pos], + es_info_length); + read_pos += es_info_length; + write_pos += es_info_length; + } + } + + /* CRC */ + c->operand[write_pos++] = 0x00; + c->operand[write_pos++] = 0x00; + c->operand[write_pos++] = 0x00; + c->operand[write_pos++] = 0x00; + + c->operand[7] = write_pos - 8; + c->operand[12] = write_pos - 13; + + crc32_csum = crc32_be(0, &c->operand[10], c->operand[12] - 1); + c->operand[write_pos - 4] = (crc32_csum >> 24) & 0xff; + c->operand[write_pos - 3] = (crc32_csum >> 16) & 0xff; + c->operand[write_pos - 2] = (crc32_csum >> 8) & 0xff; + c->operand[write_pos - 1] = (crc32_csum >> 0) & 0xff; + + c->length = ALIGN(3 + write_pos, 4); + + if (avc_write(fdtv, c, r) < 0) + return -EIO; + + if (r->response != AVC_RESPONSE_ACCEPTED) { + dev_err(fdtv->device, + "CA PMT failed with response 0x%x\n", r->response); + return -EFAULT; + } + + return 0; +} + +int avc_ca_get_time_date(struct firedtv *fdtv, int *interval) +{ + char buffer[sizeof(struct avc_command_frame)]; + struct avc_command_frame *c = (void *)buffer; + struct avc_response_frame *r = (void *)buffer; + + memset(c, 0, sizeof(*c)); + + c->ctype = AVC_CTYPE_STATUS; + c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; + c->opcode = AVC_OPCODE_VENDOR; + + c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; + c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; + c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; + c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; + c->operand[4] = 0; /* slot */ + c->operand[5] = SFE_VENDOR_TAG_CA_DATE_TIME; /* ca tag */ + c->operand[6] = 0; /* more/last */ + c->operand[7] = 0; /* length */ + + c->length = 12; + + if (avc_write(fdtv, c, r) < 0) + return -EIO; + + /* FIXME: check response code and validate response data */ + + *interval = r->operand[get_ca_object_pos(r)]; + + return 0; +} + +int avc_ca_enter_menu(struct firedtv *fdtv) +{ + char buffer[sizeof(struct avc_command_frame)]; + struct avc_command_frame *c = (void *)buffer; + struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ + + memset(c, 0, sizeof(*c)); + + c->ctype = AVC_CTYPE_STATUS; + c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; + c->opcode = AVC_OPCODE_VENDOR; + + c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; + c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; + c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; + c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA; + c->operand[4] = 0; /* slot */ + c->operand[5] = SFE_VENDOR_TAG_CA_ENTER_MENU; + c->operand[6] = 0; /* more/last */ + c->operand[7] = 0; /* length */ + + c->length = 12; + + if (avc_write(fdtv, c, r) < 0) + return -EIO; + + return 0; +} + +int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len) +{ + char buffer[sizeof(struct avc_command_frame)]; + struct avc_command_frame *c = (void *)buffer; + struct avc_response_frame *r = (void *)buffer; + + memset(c, 0, sizeof(*c)); + + c->ctype = AVC_CTYPE_STATUS; + c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; + c->opcode = AVC_OPCODE_VENDOR; + + c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; + c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; + c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; + c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; + c->operand[4] = 0; /* slot */ + c->operand[5] = SFE_VENDOR_TAG_CA_MMI; + c->operand[6] = 0; /* more/last */ + c->operand[7] = 0; /* length */ + + c->length = 12; + + if (avc_write(fdtv, c, r) < 0) + return -EIO; + + /* FIXME: check response code and validate response data */ + + *len = get_ca_object_length(r); + memcpy(mmi_object, &r->operand[get_ca_object_pos(r)], *len); + + return 0; +} + +#define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL + +static int cmp_read(struct firedtv *fdtv, void *buf, u64 addr, size_t len) +{ + int ret; + + if (mutex_lock_interruptible(&fdtv->avc_mutex)) + return -EINTR; + + ret = fdtv->backend->read(fdtv, addr, buf, len); + if (ret < 0) + dev_err(fdtv->device, "CMP: read I/O error\n"); + + mutex_unlock(&fdtv->avc_mutex); + return ret; +} + +static int cmp_lock(struct firedtv *fdtv, void *data, u64 addr, __be32 arg) +{ + int ret; + + if (mutex_lock_interruptible(&fdtv->avc_mutex)) + return -EINTR; + + ret = fdtv->backend->lock(fdtv, addr, data, arg); + if (ret < 0) + dev_err(fdtv->device, "CMP: lock I/O error\n"); + + mutex_unlock(&fdtv->avc_mutex); + return ret; +} + +static inline u32 get_opcr(__be32 opcr, u32 mask, u32 shift) +{ + return (be32_to_cpu(opcr) >> shift) & mask; +} + +static inline void set_opcr(__be32 *opcr, u32 value, u32 mask, u32 shift) +{ + *opcr &= ~cpu_to_be32(mask << shift); + *opcr |= cpu_to_be32((value & mask) << shift); +} + +#define get_opcr_online(v) get_opcr((v), 0x1, 31) +#define get_opcr_p2p_connections(v) get_opcr((v), 0x3f, 24) +#define get_opcr_channel(v) get_opcr((v), 0x3f, 16) + +#define set_opcr_p2p_connections(p, v) set_opcr((p), (v), 0x3f, 24) +#define set_opcr_channel(p, v) set_opcr((p), (v), 0x3f, 16) +#define set_opcr_data_rate(p, v) set_opcr((p), (v), 0x3, 14) +#define set_opcr_overhead_id(p, v) set_opcr((p), (v), 0xf, 10) + +int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel) +{ + __be32 old_opcr, opcr; + u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); + int attempts = 0; + int ret; + + ret = cmp_read(fdtv, &opcr, opcr_address, 4); + if (ret < 0) + return ret; + +repeat: + if (!get_opcr_online(opcr)) { + dev_err(fdtv->device, "CMP: output offline\n"); + return -EBUSY; + } + + old_opcr = opcr; + + if (get_opcr_p2p_connections(opcr)) { + if (get_opcr_channel(opcr) != channel) { + dev_err(fdtv->device, "CMP: cannot change channel\n"); + return -EBUSY; + } + dev_info(fdtv->device, "CMP: overlaying connection\n"); + + /* We don't allocate isochronous resources. */ + } else { + set_opcr_channel(&opcr, channel); + set_opcr_data_rate(&opcr, 2); /* S400 */ + + /* FIXME: this is for the worst case - optimize */ + set_opcr_overhead_id(&opcr, 0); + + /* + * FIXME: allocate isochronous channel and bandwidth at IRM + * fdtv->backend->alloc_resources(fdtv, channels_mask, bw); + */ + } + + set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) + 1); + + ret = cmp_lock(fdtv, &opcr, opcr_address, old_opcr); + if (ret < 0) + return ret; + + if (old_opcr != opcr) { + /* + * FIXME: if old_opcr.P2P_Connections > 0, + * deallocate isochronous channel and bandwidth at IRM + * if (...) + * fdtv->backend->dealloc_resources(fdtv, channel, bw); + */ + + if (++attempts < 6) /* arbitrary limit */ + goto repeat; + return -EBUSY; + } + + return 0; +} + +void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel) +{ + __be32 old_opcr, opcr; + u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); + int attempts = 0; + + if (cmp_read(fdtv, &opcr, opcr_address, 4) < 0) + return; + +repeat: + if (!get_opcr_online(opcr) || !get_opcr_p2p_connections(opcr) || + get_opcr_channel(opcr) != channel) { + dev_err(fdtv->device, "CMP: no connection to break\n"); + return; + } + + old_opcr = opcr; + set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) - 1); + + if (cmp_lock(fdtv, &opcr, opcr_address, old_opcr) < 0) + return; + + if (old_opcr != opcr) { + /* + * FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last + * owner, deallocate isochronous channel and bandwidth at IRM + * if (...) + * fdtv->backend->dealloc_resources(fdtv, channel, bw); + */ + + if (++attempts < 6) /* arbitrary limit */ + goto repeat; + } +} diff --git a/drivers/media/dvb/firewire/firedtv-ci.c b/drivers/media/dvb/firewire/firedtv-ci.c index 6d87926b8bf..eeb80d0ea3f 100644 --- a/drivers/media/dvb/firewire/firedtv-ci.c +++ b/drivers/media/dvb/firewire/firedtv-ci.c @@ -10,33 +10,37 @@ * the License, or (at your option) any later version. */ +#include #include #include #include #include -#include "avc.h" #include "firedtv.h" -#include "firedtv-ci.h" -static int fdtv_ca_ready(ANTENNA_INPUT_INFO *info) +#define EN50221_TAG_APP_INFO_ENQUIRY 0x9f8020 +#define EN50221_TAG_CA_INFO_ENQUIRY 0x9f8030 +#define EN50221_TAG_CA_PMT 0x9f8032 +#define EN50221_TAG_ENTER_MENU 0x9f8022 + +static int fdtv_ca_ready(struct firedtv_tuner_status *stat) { - return info->CaInitializationStatus == 1 && - info->CaErrorFlag == 0 && - info->CaDvbFlag == 1 && - info->CaModulePresentStatus == 1; + return stat->ca_initialization_status == 1 && + stat->ca_error_flag == 0 && + stat->ca_dvb_flag == 1 && + stat->ca_module_present_status == 1; } -static int fdtv_get_ca_flags(ANTENNA_INPUT_INFO *info) +static int fdtv_get_ca_flags(struct firedtv_tuner_status *stat) { int flags = 0; - if (info->CaModulePresentStatus == 1) + if (stat->ca_module_present_status == 1) flags |= CA_CI_MODULE_PRESENT; - if (info->CaInitializationStatus == 1 && - info->CaErrorFlag == 0 && - info->CaDvbFlag == 1) + if (stat->ca_initialization_status == 1 && + stat->ca_error_flag == 0 && + stat->ca_dvb_flag == 1) flags |= CA_CI_MODULE_READY; return flags; } @@ -59,17 +63,17 @@ static int fdtv_ca_get_caps(void *arg) static int fdtv_ca_get_slot_info(struct firedtv *fdtv, void *arg) { - ANTENNA_INPUT_INFO info; + struct firedtv_tuner_status stat; struct ca_slot_info *slot = arg; - if (avc_tuner_status(fdtv, &info)) + if (avc_tuner_status(fdtv, &stat)) return -EFAULT; if (slot->num != 0) return -EFAULT; slot->type = CA_CI; - slot->flags = fdtv_get_ca_flags(&info); + slot->flags = fdtv_get_ca_flags(&stat); return 0; } @@ -77,8 +81,7 @@ static int fdtv_ca_app_info(struct firedtv *fdtv, void *arg) { struct ca_msg *reply = arg; - return - avc_ca_app_info(fdtv, reply->msg, &reply->length) ? -EFAULT : 0; + return avc_ca_app_info(fdtv, reply->msg, &reply->length) ? -EFAULT : 0; } static int fdtv_ca_info(struct firedtv *fdtv, void *arg) @@ -92,30 +95,29 @@ static int fdtv_ca_get_mmi(struct firedtv *fdtv, void *arg) { struct ca_msg *reply = arg; - return - avc_ca_get_mmi(fdtv, reply->msg, &reply->length) ? -EFAULT : 0; + return avc_ca_get_mmi(fdtv, reply->msg, &reply->length) ? -EFAULT : 0; } static int fdtv_ca_get_msg(struct firedtv *fdtv, void *arg) { - ANTENNA_INPUT_INFO info; + struct firedtv_tuner_status stat; int err; switch (fdtv->ca_last_command) { - case TAG_APP_INFO_ENQUIRY: + case EN50221_TAG_APP_INFO_ENQUIRY: err = fdtv_ca_app_info(fdtv, arg); break; - case TAG_CA_INFO_ENQUIRY: + case EN50221_TAG_CA_INFO_ENQUIRY: err = fdtv_ca_info(fdtv, arg); break; default: - if (avc_tuner_status(fdtv, &info)) + if (avc_tuner_status(fdtv, &stat)) err = -EFAULT; - else if (info.CaMmi == 1) + else if (stat.ca_mmi == 1) err = fdtv_ca_get_mmi(fdtv, arg); else { - printk(KERN_INFO "%s: Unhandled message 0x%08X\n", - __func__, fdtv->ca_last_command); + dev_info(fdtv->device, "unhandled CA message 0x%08x\n", + fdtv->ca_last_command); err = -EFAULT; } } @@ -133,14 +135,13 @@ static int fdtv_ca_pmt(struct firedtv *fdtv, void *arg) data_pos = 4; if (msg->msg[3] & 0x80) { data_length = 0; - for (i = 0; i < (msg->msg[3] & 0x7F); i++) + for (i = 0; i < (msg->msg[3] & 0x7f); i++) data_length = (data_length << 8) + msg->msg[data_pos++]; } else { data_length = msg->msg[3]; } - return avc_ca_pmt(fdtv, &msg->msg[data_pos], data_length) ? - -EFAULT : 0; + return avc_ca_pmt(fdtv, &msg->msg[data_pos], data_length) ? -EFAULT : 0; } static int fdtv_ca_send_msg(struct firedtv *fdtv, void *arg) @@ -152,23 +153,23 @@ static int fdtv_ca_send_msg(struct firedtv *fdtv, void *arg) fdtv->ca_last_command = (msg->msg[0] << 16) + (msg->msg[1] << 8) + msg->msg[2]; switch (fdtv->ca_last_command) { - case TAG_CA_PMT: + case EN50221_TAG_CA_PMT: err = fdtv_ca_pmt(fdtv, arg); break; - case TAG_APP_INFO_ENQUIRY: + case EN50221_TAG_APP_INFO_ENQUIRY: /* handled in ca_get_msg */ err = 0; break; - case TAG_CA_INFO_ENQUIRY: + case EN50221_TAG_CA_INFO_ENQUIRY: /* handled in ca_get_msg */ err = 0; break; - case TAG_ENTER_MENU: + case EN50221_TAG_ENTER_MENU: err = avc_ca_enter_menu(fdtv); break; default: - printk(KERN_ERR "%s: Unhandled unknown message 0x%08X\n", - __func__, fdtv->ca_last_command); + dev_err(fdtv->device, "unhandled CA message 0x%08x\n", + fdtv->ca_last_command); err = -EFAULT; } return err; @@ -179,10 +180,10 @@ static int fdtv_ca_ioctl(struct inode *inode, struct file *file, { struct dvb_device *dvbdev = file->private_data; struct firedtv *fdtv = dvbdev->priv; - ANTENNA_INPUT_INFO info; + struct firedtv_tuner_status stat; int err; - switch(cmd) { + switch (cmd) { case CA_RESET: err = fdtv_ca_reset(fdtv); break; @@ -199,13 +200,12 @@ static int fdtv_ca_ioctl(struct inode *inode, struct file *file, err = fdtv_ca_send_msg(fdtv, arg); break; default: - printk(KERN_INFO "%s: Unhandled ioctl, command: %u\n",__func__, - cmd); + dev_info(fdtv->device, "unhandled CA ioctl %u\n", cmd); err = -EOPNOTSUPP; } /* FIXME Is this necessary? */ - avc_tuner_status(fdtv, &info); + avc_tuner_status(fdtv, &stat); return err; } @@ -233,22 +233,21 @@ static struct dvb_device fdtv_ca = { int fdtv_ca_register(struct firedtv *fdtv) { - ANTENNA_INPUT_INFO info; + struct firedtv_tuner_status stat; int err; - if (avc_tuner_status(fdtv, &info)) + if (avc_tuner_status(fdtv, &stat)) return -EINVAL; - if (!fdtv_ca_ready(&info)) + if (!fdtv_ca_ready(&stat)) return -EFAULT; err = dvb_register_device(&fdtv->adapter, &fdtv->cadev, &fdtv_ca, fdtv, DVB_DEVICE_CA); - if (info.CaApplicationInfo == 0) - printk(KERN_ERR "%s: CaApplicationInfo is not set.\n", - __func__); - if (info.CaDateTimeRequest == 1) + if (stat.ca_application_info == 0) + dev_err(fdtv->device, "CaApplicationInfo is not set\n"); + if (stat.ca_date_time_request == 1) avc_ca_get_time_date(fdtv, &fdtv->ca_time_interval); return err; diff --git a/drivers/media/dvb/firewire/firedtv-ci.h b/drivers/media/dvb/firewire/firedtv-ci.h deleted file mode 100644 index d6840f5dcba..00000000000 --- a/drivers/media/dvb/firewire/firedtv-ci.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _FIREDTV_CI_H -#define _FIREDTV_CI_H - -struct firedtv; - -int fdtv_ca_register(struct firedtv *fdtv); -void fdtv_ca_release(struct firedtv *fdtv); - -#endif /* _FIREDTV_CI_H */ diff --git a/drivers/media/dvb/firewire/firedtv-dvb.c b/drivers/media/dvb/firewire/firedtv-dvb.c index 1823058696f..9d308dd32a5 100644 --- a/drivers/media/dvb/firewire/firedtv-dvb.c +++ b/drivers/media/dvb/firewire/firedtv-dvb.c @@ -10,75 +10,55 @@ * the License, or (at your option) any later version. */ +#include +#include #include #include +#include +#include #include +#include +#include #include +#include +#include +#include #include -#include #include +#include -#include "avc.h" #include "firedtv.h" -#include "firedtv-ci.h" - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -static struct firedtv_channel *fdtv_channel_allocate(struct firedtv *fdtv) +static int alloc_channel(struct firedtv *fdtv) { - struct firedtv_channel *c = NULL; - int k; + int i; - if (mutex_lock_interruptible(&fdtv->demux_mutex)) - return NULL; - - for (k = 0; k < 16; k++) - if (!fdtv->channel[k].active) { - fdtv->channel[k].active = true; - c = &fdtv->channel[k]; + for (i = 0; i < 16; i++) + if (!__test_and_set_bit(i, &fdtv->channel_active)) break; - } - - mutex_unlock(&fdtv->demux_mutex); - return c; + return i; } -static int fdtv_channel_collect(struct firedtv *fdtv, int *pidc, u16 pid[]) +static void collect_channels(struct firedtv *fdtv, int *pidc, u16 pid[]) { - int k, l = 0; - - if (mutex_lock_interruptible(&fdtv->demux_mutex)) - return -EINTR; - - for (k = 0; k < 16; k++) - if (fdtv->channel[k].active) - pid[l++] = fdtv->channel[k].pid; - - mutex_unlock(&fdtv->demux_mutex); + int i, n; - *pidc = l; - - return 0; + for (i = 0, n = 0; i < 16; i++) + if (test_bit(i, &fdtv->channel_active)) + pid[n++] = fdtv->channel_pid[i]; + *pidc = n; } -static int fdtv_channel_release(struct firedtv *fdtv, - struct firedtv_channel *channel) +static inline void dealloc_channel(struct firedtv *fdtv, int i) { - if (mutex_lock_interruptible(&fdtv->demux_mutex)) - return -EINTR; - - channel->active = false; - - mutex_unlock(&fdtv->demux_mutex); - return 0; + __clear_bit(i, &fdtv->channel_active); } int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed) { - struct firedtv *fdtv = (struct firedtv*)dvbdmxfeed->demux->priv; - struct firedtv_channel *channel; - int pidc,k; + struct firedtv *fdtv = dvbdmxfeed->demux->priv; + int pidc, c, ret; u16 pids[16]; switch (dvbdmxfeed->type) { @@ -86,11 +66,14 @@ int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed) case DMX_TYPE_SEC: break; default: - printk(KERN_ERR "%s: invalid type %u\n", - __func__, dvbdmxfeed->type); + dev_err(fdtv->device, "can't start dmx feed: invalid type %u\n", + dvbdmxfeed->type); return -EINVAL; } + if (mutex_lock_interruptible(&fdtv->demux_mutex)) + return -EINTR; + if (dvbdmxfeed->type == DMX_TYPE_TS) { switch (dvbdmxfeed->pes_type) { case DMX_TS_PES_VIDEO: @@ -98,75 +81,64 @@ int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed) case DMX_TS_PES_TELETEXT: case DMX_TS_PES_PCR: case DMX_TS_PES_OTHER: - //Dirty fix to keep fdtv->channel pid-list up to date - for(k=0;k<16;k++){ - if (!fdtv->channel[k].active) - fdtv->channel[k].pid = - dvbdmxfeed->pid; - break; - } - channel = fdtv_channel_allocate(fdtv); + c = alloc_channel(fdtv); break; default: - printk(KERN_ERR "%s: invalid pes type %u\n", - __func__, dvbdmxfeed->pes_type); - return -EINVAL; + dev_err(fdtv->device, + "can't start dmx feed: invalid pes type %u\n", + dvbdmxfeed->pes_type); + ret = -EINVAL; + goto out; } } else { - channel = fdtv_channel_allocate(fdtv); + c = alloc_channel(fdtv); } - if (!channel) { - printk(KERN_ERR "%s: busy!\n", __func__); - return -EBUSY; + if (c > 15) { + dev_err(fdtv->device, "can't start dmx feed: busy\n"); + ret = -EBUSY; + goto out; } - dvbdmxfeed->priv = channel; - channel->pid = dvbdmxfeed->pid; - - if (fdtv_channel_collect(fdtv, &pidc, pids)) { - fdtv_channel_release(fdtv, channel); - printk(KERN_ERR "%s: could not collect pids!\n", __func__); - return -EINTR; - } + dvbdmxfeed->priv = (typeof(dvbdmxfeed->priv))(unsigned long)c; + fdtv->channel_pid[c] = dvbdmxfeed->pid; + collect_channels(fdtv, &pidc, pids); if (dvbdmxfeed->pid == 8192) { - k = avc_tuner_get_ts(fdtv); - if (k) { - fdtv_channel_release(fdtv, channel); - printk("%s: AVCTuner_GetTS failed with error %d\n", - __func__, k); - return k; + ret = avc_tuner_get_ts(fdtv); + if (ret) { + dealloc_channel(fdtv, c); + dev_err(fdtv->device, "can't get TS\n"); + goto out; } } else { - k = avc_tuner_set_pids(fdtv, pidc, pids); - if (k) { - fdtv_channel_release(fdtv, channel); - printk("%s: AVCTuner_SetPIDs failed with error %d\n", - __func__, k); - return k; + ret = avc_tuner_set_pids(fdtv, pidc, pids); + if (ret) { + dealloc_channel(fdtv, c); + dev_err(fdtv->device, "can't set PIDs\n"); + goto out; } } +out: + mutex_unlock(&fdtv->demux_mutex); - return 0; + return ret; } int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed) { struct dvb_demux *demux = dvbdmxfeed->demux; - struct firedtv *fdtv = (struct firedtv*)demux->priv; - struct firedtv_channel *c = dvbdmxfeed->priv; - int k, l; + struct firedtv *fdtv = demux->priv; + int pidc, c, ret; u16 pids[16]; - if (dvbdmxfeed->type == DMX_TYPE_TS && !((dvbdmxfeed->ts_type & TS_PACKET) && - (demux->dmx.frontend->source != DMX_MEMORY_FE))) { + if (dvbdmxfeed->type == DMX_TYPE_TS && + !((dvbdmxfeed->ts_type & TS_PACKET) && + (demux->dmx.frontend->source != DMX_MEMORY_FE))) { if (dvbdmxfeed->ts_type & TS_DECODER) { - if (dvbdmxfeed->pes_type >= DMX_TS_PES_OTHER || - !demux->pesfilter[dvbdmxfeed->pes_type]) - + !demux->pesfilter[dvbdmxfeed->pes_type]) return -EINVAL; demux->pids[dvbdmxfeed->pes_type] |= 0x8000; @@ -174,38 +146,32 @@ int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed) } if (!(dvbdmxfeed->ts_type & TS_DECODER && - dvbdmxfeed->pes_type < DMX_TS_PES_OTHER)) - + dvbdmxfeed->pes_type < DMX_TS_PES_OTHER)) return 0; } if (mutex_lock_interruptible(&fdtv->demux_mutex)) return -EINTR; - /* list except channel to be removed */ - for (k = 0, l = 0; k < 16; k++) - if (fdtv->channel[k].active) { - if (&fdtv->channel[k] != c) - pids[l++] = fdtv->channel[k].pid; - else - fdtv->channel[k].active = false; - } + c = (unsigned long)dvbdmxfeed->priv; + dealloc_channel(fdtv, c); + collect_channels(fdtv, &pidc, pids); - k = avc_tuner_set_pids(fdtv, l, pids); - if (!k) - c->active = false; + ret = avc_tuner_set_pids(fdtv, pidc, pids); mutex_unlock(&fdtv->demux_mutex); - return k; + + return ret; } -int fdtv_dvbdev_init(struct firedtv *fdtv, struct device *dev) +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + +int fdtv_dvb_register(struct firedtv *fdtv) { int err; - err = DVB_REGISTER_ADAPTER(&fdtv->adapter, - fdtv_model_names[fdtv->type], - THIS_MODULE, dev, adapter_nr); + err = dvb_register_adapter(&fdtv->adapter, fdtv_model_names[fdtv->type], + THIS_MODULE, fdtv->device, adapter_nr); if (err < 0) goto fail_log; @@ -223,9 +189,9 @@ int fdtv_dvbdev_init(struct firedtv *fdtv, struct device *dev) if (err) goto fail_unreg_adapter; - fdtv->dmxdev.filternum = 16; - fdtv->dmxdev.demux = &fdtv->demux.dmx; - fdtv->dmxdev.capabilities = 0; + fdtv->dmxdev.filternum = 16; + fdtv->dmxdev.demux = &fdtv->demux.dmx; + fdtv->dmxdev.capabilities = 0; err = dvb_dmxdev_init(&fdtv->dmxdev, &fdtv->adapter); if (err) @@ -233,13 +199,12 @@ int fdtv_dvbdev_init(struct firedtv *fdtv, struct device *dev) fdtv->frontend.source = DMX_FRONTEND_0; - err = fdtv->demux.dmx.add_frontend(&fdtv->demux.dmx, - &fdtv->frontend); + err = fdtv->demux.dmx.add_frontend(&fdtv->demux.dmx, &fdtv->frontend); if (err) goto fail_dmxdev_release; err = fdtv->demux.dmx.connect_frontend(&fdtv->demux.dmx, - &fdtv->frontend); + &fdtv->frontend); if (err) goto fail_rem_frontend; @@ -252,16 +217,15 @@ int fdtv_dvbdev_init(struct firedtv *fdtv, struct device *dev) err = fdtv_ca_register(fdtv); if (err) - dev_info(dev, "Conditional Access Module not enabled\n"); - + dev_info(fdtv->device, + "Conditional Access Module not enabled\n"); return 0; fail_net_release: dvb_net_release(&fdtv->dvbnet); fdtv->demux.dmx.close(&fdtv->demux.dmx); fail_rem_frontend: - fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, - &fdtv->frontend); + fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend); fail_dmxdev_release: dvb_dmxdev_release(&fdtv->dmxdev); fail_dmx_release: @@ -269,8 +233,132 @@ fail_dmx_release: fail_unreg_adapter: dvb_unregister_adapter(&fdtv->adapter); fail_log: - dev_err(dev, "DVB initialization failed\n"); + dev_err(fdtv->device, "DVB initialization failed\n"); return err; } +void fdtv_dvb_unregister(struct firedtv *fdtv) +{ + fdtv_ca_release(fdtv); + dvb_unregister_frontend(&fdtv->fe); + dvb_net_release(&fdtv->dvbnet); + fdtv->demux.dmx.close(&fdtv->demux.dmx); + fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend); + dvb_dmxdev_release(&fdtv->dmxdev); + dvb_dmx_release(&fdtv->demux); + dvb_unregister_adapter(&fdtv->adapter); +} + +const char *fdtv_model_names[] = { + [FIREDTV_UNKNOWN] = "unknown type", + [FIREDTV_DVB_S] = "FireDTV S/CI", + [FIREDTV_DVB_C] = "FireDTV C/CI", + [FIREDTV_DVB_T] = "FireDTV T/CI", + [FIREDTV_DVB_S2] = "FireDTV S2 ", +}; + +struct firedtv *fdtv_alloc(struct device *dev, + const struct firedtv_backend *backend, + const char *name, size_t name_len) +{ + struct firedtv *fdtv; + int i; + + fdtv = kzalloc(sizeof(*fdtv), GFP_KERNEL); + if (!fdtv) + return NULL; + + dev->driver_data = fdtv; + fdtv->device = dev; + fdtv->isochannel = -1; + fdtv->voltage = 0xff; + fdtv->tone = 0xff; + fdtv->backend = backend; + + mutex_init(&fdtv->avc_mutex); + init_waitqueue_head(&fdtv->avc_wait); + fdtv->avc_reply_received = true; + mutex_init(&fdtv->demux_mutex); + INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work); + + for (i = ARRAY_SIZE(fdtv_model_names); --i; ) + if (strlen(fdtv_model_names[i]) <= name_len && + strncmp(name, fdtv_model_names[i], name_len) == 0) + break; + fdtv->type = i; + + return fdtv; +} + +#define MATCH_FLAGS (IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \ + IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION) + +#define DIGITAL_EVERYWHERE_OUI 0x001287 +#define AVC_UNIT_SPEC_ID_ENTRY 0x00a02d +#define AVC_SW_VERSION_ENTRY 0x010001 + +static struct ieee1394_device_id fdtv_id_table[] = { + { + /* FloppyDTV S/CI and FloppyDTV S2 */ + .match_flags = MATCH_FLAGS, + .vendor_id = DIGITAL_EVERYWHERE_OUI, + .model_id = 0x000024, + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, + .version = AVC_SW_VERSION_ENTRY, + }, { + /* FloppyDTV T/CI */ + .match_flags = MATCH_FLAGS, + .vendor_id = DIGITAL_EVERYWHERE_OUI, + .model_id = 0x000025, + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, + .version = AVC_SW_VERSION_ENTRY, + }, { + /* FloppyDTV C/CI */ + .match_flags = MATCH_FLAGS, + .vendor_id = DIGITAL_EVERYWHERE_OUI, + .model_id = 0x000026, + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, + .version = AVC_SW_VERSION_ENTRY, + }, { + /* FireDTV S/CI and FloppyDTV S2 */ + .match_flags = MATCH_FLAGS, + .vendor_id = DIGITAL_EVERYWHERE_OUI, + .model_id = 0x000034, + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, + .version = AVC_SW_VERSION_ENTRY, + }, { + /* FireDTV T/CI */ + .match_flags = MATCH_FLAGS, + .vendor_id = DIGITAL_EVERYWHERE_OUI, + .model_id = 0x000035, + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, + .version = AVC_SW_VERSION_ENTRY, + }, { + /* FireDTV C/CI */ + .match_flags = MATCH_FLAGS, + .vendor_id = DIGITAL_EVERYWHERE_OUI, + .model_id = 0x000036, + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, + .version = AVC_SW_VERSION_ENTRY, + }, {} +}; +MODULE_DEVICE_TABLE(ieee1394, fdtv_id_table); + +static int __init fdtv_init(void) +{ + return fdtv_1394_init(fdtv_id_table); +} + +static void __exit fdtv_exit(void) +{ + fdtv_1394_exit(); +} + +module_init(fdtv_init); +module_exit(fdtv_exit); +MODULE_AUTHOR("Andreas Monitzer "); +MODULE_AUTHOR("Ben Backx "); +MODULE_DESCRIPTION("FireDTV DVB Driver"); +MODULE_LICENSE("GPL"); +MODULE_SUPPORTED_DEVICE("FireDTV DVB"); diff --git a/drivers/media/dvb/firewire/firedtv-fe.c b/drivers/media/dvb/firewire/firedtv-fe.c index f8150f402bb..9b9539c800f 100644 --- a/drivers/media/dvb/firewire/firedtv-fe.c +++ b/drivers/media/dvb/firewire/firedtv-fe.c @@ -10,6 +10,7 @@ * the License, or (at your option) any later version. */ +#include #include #include #include @@ -17,8 +18,6 @@ #include -#include "avc.h" -#include "cmp.h" #include "firedtv.h" static int fdtv_dvb_init(struct dvb_frontend *fe) @@ -32,35 +31,37 @@ static int fdtv_dvb_init(struct dvb_frontend *fe) err = cmp_establish_pp_connection(fdtv, fdtv->subunit, fdtv->isochannel); if (err) { - printk(KERN_ERR "Could not establish point to point " - "connection.\n"); + dev_err(fdtv->device, + "could not establish point to point connection\n"); return err; } - return setup_iso_channel(fdtv); + return fdtv->backend->start_iso(fdtv); } static int fdtv_sleep(struct dvb_frontend *fe) { struct firedtv *fdtv = fe->sec_priv; - tear_down_iso_channel(fdtv); + fdtv->backend->stop_iso(fdtv); cmp_break_pp_connection(fdtv, fdtv->subunit, fdtv->isochannel); fdtv->isochannel = -1; return 0; } +#define LNBCONTROL_DONTCARE 0xff + static int fdtv_diseqc_send_master_cmd(struct dvb_frontend *fe, - struct dvb_diseqc_master_cmd *cmd) + struct dvb_diseqc_master_cmd *cmd) { struct firedtv *fdtv = fe->sec_priv; - return avc_lnb_control(fdtv, LNBCONTROL_DONTCARE, - LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, 1, cmd); + return avc_lnb_control(fdtv, LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, + LNBCONTROL_DONTCARE, 1, cmd); } static int fdtv_diseqc_send_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t minicmd) + fe_sec_mini_cmd_t minicmd) { return 0; } @@ -74,7 +75,7 @@ static int fdtv_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) } static int fdtv_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) + fe_sec_voltage_t voltage) { struct firedtv *fdtv = fe->sec_priv; @@ -85,12 +86,12 @@ static int fdtv_set_voltage(struct dvb_frontend *fe, static int fdtv_read_status(struct dvb_frontend *fe, fe_status_t *status) { struct firedtv *fdtv = fe->sec_priv; - ANTENNA_INPUT_INFO info; + struct firedtv_tuner_status stat; - if (avc_tuner_status(fdtv, &info)) + if (avc_tuner_status(fdtv, &stat)) return -EINVAL; - if (info.NoRF) + if (stat.no_rf) *status = 0; else *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | FE_HAS_SYNC | @@ -101,39 +102,37 @@ static int fdtv_read_status(struct dvb_frontend *fe, fe_status_t *status) static int fdtv_read_ber(struct dvb_frontend *fe, u32 *ber) { struct firedtv *fdtv = fe->sec_priv; - ANTENNA_INPUT_INFO info; + struct firedtv_tuner_status stat; - if (avc_tuner_status(fdtv, &info)) + if (avc_tuner_status(fdtv, &stat)) return -EINVAL; - *ber = info.BER[0] << 24 | info.BER[1] << 16 | - info.BER[2] << 8 | info.BER[3]; + *ber = stat.ber; return 0; } -static int fdtv_read_signal_strength (struct dvb_frontend *fe, u16 *strength) +static int fdtv_read_signal_strength(struct dvb_frontend *fe, u16 *strength) { struct firedtv *fdtv = fe->sec_priv; - ANTENNA_INPUT_INFO info; + struct firedtv_tuner_status stat; - if (avc_tuner_status(fdtv, &info)) + if (avc_tuner_status(fdtv, &stat)) return -EINVAL; - *strength = info.SignalStrength << 8; + *strength = stat.signal_strength << 8; return 0; } static int fdtv_read_snr(struct dvb_frontend *fe, u16 *snr) { struct firedtv *fdtv = fe->sec_priv; - ANTENNA_INPUT_INFO info; + struct firedtv_tuner_status stat; - if (avc_tuner_status(fdtv, &info)) + if (avc_tuner_status(fdtv, &stat)) return -EINVAL; /* C/N[dB] = -10 * log10(snr / 65535) */ - *snr = (info.CarrierNoiseRatio[0] << 8) + info.CarrierNoiseRatio[1]; - *snr *= 257; + *snr = stat.carrier_noise_ratio * 257; return 0; } @@ -142,8 +141,10 @@ static int fdtv_read_uncorrected_blocks(struct dvb_frontend *fe, u32 *ucblocks) return -EOPNOTSUPP; } +#define ACCEPTED 0x9 + static int fdtv_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) + struct dvb_frontend_parameters *params) { struct firedtv *fdtv = fe->sec_priv; @@ -155,7 +156,7 @@ static int fdtv_set_frontend(struct dvb_frontend *fe, } static int fdtv_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) + struct dvb_frontend_parameters *params) { return -EOPNOTSUPP; } @@ -235,8 +236,8 @@ void fdtv_frontend_init(struct firedtv *fdtv) break; default: - printk(KERN_ERR "FireDTV: no frontend for model type %d\n", - fdtv->type); + dev_err(fdtv->device, "no frontend for model type %d\n", + fdtv->type); } strcpy(fi->name, fdtv_model_names[fdtv->type]); diff --git a/drivers/media/dvb/firewire/firedtv-iso.c b/drivers/media/dvb/firewire/firedtv-iso.c deleted file mode 100644 index a72df228e7d..00000000000 --- a/drivers/media/dvb/firewire/firedtv-iso.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * FireSAT DVB driver - * - * Copyright (C) 2008 Henrik Kurelid - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - */ - -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include "firedtv.h" - -static void rawiso_activity_cb(struct hpsb_iso *iso); - -void tear_down_iso_channel(struct firedtv *fdtv) -{ - if (fdtv->iso_handle != NULL) { - hpsb_iso_stop(fdtv->iso_handle); - hpsb_iso_shutdown(fdtv->iso_handle); - } - fdtv->iso_handle = NULL; -} - -int setup_iso_channel(struct firedtv *fdtv) -{ - int result; - fdtv->iso_handle = - hpsb_iso_recv_init(fdtv->ud->ne->host, - 256 * 200, //data_buf_size, - 256, //buf_packets, - fdtv->isochannel, - HPSB_ISO_DMA_DEFAULT, //dma_mode, - -1, //stat.config.irq_interval, - rawiso_activity_cb); - if (fdtv->iso_handle == NULL) { - printk(KERN_ERR "Cannot initialize iso receive.\n"); - return -EINVAL; - } - result = hpsb_iso_recv_start(fdtv->iso_handle, -1, -1, 0); - if (result != 0) { - printk(KERN_ERR "Cannot start iso receive.\n"); - return -EINVAL; - } - return 0; -} - -static void rawiso_activity_cb(struct hpsb_iso *iso) -{ - unsigned int num; - unsigned int i; - unsigned int packet; - unsigned long flags; - struct firedtv *fdtv = NULL; - struct firedtv *fdtv_iterator; - - spin_lock_irqsave(&fdtv_list_lock, flags); - list_for_each_entry(fdtv_iterator, &fdtv_list, list) { - if(fdtv_iterator->iso_handle == iso) { - fdtv = fdtv_iterator; - break; - } - } - spin_unlock_irqrestore(&fdtv_list_lock, flags); - - if (fdtv) { - packet = iso->first_packet; - num = hpsb_iso_n_ready(iso); - for (i = 0; i < num; i++, - packet = (packet + 1) % iso->buf_packets) { - unsigned char *buf = - dma_region_i(&iso->data_buf, unsigned char, - iso->infos[packet].offset + - sizeof(struct CIPHeader)); - int count = (iso->infos[packet].len - - sizeof(struct CIPHeader)) / - (188 + sizeof(struct firewireheader)); - if (iso->infos[packet].len <= sizeof(struct CIPHeader)) - continue; // ignore empty packet - - while (count --) { - if (buf[sizeof(struct firewireheader)] == 0x47) - dvb_dmx_swfilter_packets(&fdtv->demux, - &buf[sizeof(struct firewireheader)], 1); - else - printk("%s: invalid packet, skipping\n", __func__); - buf += 188 + sizeof(struct firewireheader); - - } - - } - hpsb_iso_recv_release_packets(iso, num); - } - else { - printk("%s: packets for unknown iso channel, skipping\n", - __func__); - hpsb_iso_recv_release_packets(iso, hpsb_iso_n_ready(iso)); - } -} - diff --git a/drivers/media/dvb/firewire/firedtv-rc.c b/drivers/media/dvb/firewire/firedtv-rc.c index 436c0c69a13..46a6324d7b7 100644 --- a/drivers/media/dvb/firewire/firedtv-rc.c +++ b/drivers/media/dvb/firewire/firedtv-rc.c @@ -15,7 +15,6 @@ #include #include -#include "firedtv-rc.h" #include "firedtv.h" /* fixed table with older keycodes, geared towards MythTV */ diff --git a/drivers/media/dvb/firewire/firedtv-rc.h b/drivers/media/dvb/firewire/firedtv-rc.h deleted file mode 100644 index d3e14727d3d..00000000000 --- a/drivers/media/dvb/firewire/firedtv-rc.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _FIREDTV_RC_H -#define _FIREDTV_RC_H - -struct firedtv; -struct device; - -int fdtv_register_rc(struct firedtv *fdtv, struct device *dev); -void fdtv_unregister_rc(struct firedtv *fdtv); -void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code); - -#endif /* _FIREDTV_RC_H */ diff --git a/drivers/media/dvb/firewire/firedtv.h b/drivers/media/dvb/firewire/firedtv.h index 2a34028ccbc..d48530b81e6 100644 --- a/drivers/media/dvb/firewire/firedtv.h +++ b/drivers/media/dvb/firewire/firedtv.h @@ -29,95 +29,35 @@ #include #include -#include -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25) -#define DVB_REGISTER_ADAPTER(x, y, z, w, v) dvb_register_adapter(x, y, z, w, v) -#else -#define DVB_REGISTER_ADAPTER(x, y, z, w, v) dvb_register_adapter(x, y, z, w) -#define DVB_DEFINE_MOD_OPT_ADAPTER_NR(x) -#endif - -/***************************************************************** - * CA message command constants from en50221_app_tags.h of libdvb - *****************************************************************/ -/* Resource Manager */ -#define TAG_PROFILE_ENQUIRY 0x9f8010 -#define TAG_PROFILE 0x9f8011 -#define TAG_PROFILE_CHANGE 0x9f8012 - -/* Application Info */ -#define TAG_APP_INFO_ENQUIRY 0x9f8020 -#define TAG_APP_INFO 0x9f8021 -#define TAG_ENTER_MENU 0x9f8022 - -/* CA Support */ -#define TAG_CA_INFO_ENQUIRY 0x9f8030 -#define TAG_CA_INFO 0x9f8031 -#define TAG_CA_PMT 0x9f8032 -#define TAG_CA_PMT_REPLY 0x9f8033 - -/* Host Control */ -#define TAG_TUNE 0x9f8400 -#define TAG_REPLACE 0x9f8401 -#define TAG_CLEAR_REPLACE 0x9f8402 -#define TAG_ASK_RELEASE 0x9f8403 - -/* Date and Time */ -#define TAG_DATE_TIME_ENQUIRY 0x9f8440 -#define TAG_DATE_TIME 0x9f8441 - -/* Man Machine Interface (MMI) */ -#define TAG_CLOSE_MMI 0x9f8800 -#define TAG_DISPLAY_CONTROL 0x9f8801 -#define TAG_DISPLAY_REPLY 0x9f8802 -#define TAG_TEXT_LAST 0x9f8803 -#define TAG_TEXT_MORE 0x9f8804 -#define TAG_KEYPAD_CONTROL 0x9f8805 -#define TAG_KEYPRESS 0x9f8806 -#define TAG_ENQUIRY 0x9f8807 -#define TAG_ANSWER 0x9f8808 -#define TAG_MENU_LAST 0x9f8809 -#define TAG_MENU_MORE 0x9f880a -#define TAG_MENU_ANSWER 0x9f880b -#define TAG_LIST_LAST 0x9f880c -#define TAG_LIST_MORE 0x9f880d -#define TAG_SUBTITLE_SEGMENT_LAST 0x9f880e -#define TAG_SUBTITLE_SEGMENT_MORE 0x9f880f -#define TAG_DISPLAY_MESSAGE 0x9f8810 -#define TAG_SCENE_END_MARK 0x9f8811 -#define TAG_SCENE_DONE 0x9f8812 -#define TAG_SCENE_CONTROL 0x9f8813 -#define TAG_SUBTITLE_DOWNLOAD_LAST 0x9f8814 -#define TAG_SUBTITLE_DOWNLOAD_MORE 0x9f8815 -#define TAG_FLUSH_DOWNLOAD 0x9f8816 -#define TAG_DOWNLOAD_REPLY 0x9f8817 - -/* Low Speed Communications */ -#define TAG_COMMS_COMMAND 0x9f8c00 -#define TAG_CONNECTION_DESCRIPTOR 0x9f8c01 -#define TAG_COMMS_REPLY 0x9f8c02 -#define TAG_COMMS_SEND_LAST 0x9f8c03 -#define TAG_COMMS_SEND_MORE 0x9f8c04 -#define TAG_COMMS_RECV_LAST 0x9f8c05 -#define TAG_COMMS_RECV_MORE 0x9f8c06 - -/* Authentication */ -#define TAG_AUTH_REQ 0x9f8200 -#define TAG_AUTH_RESP 0x9f8201 - -/* Teletext */ -#define TAG_TELETEXT_EBU 0x9f9000 - -/* Smartcard */ -#define TAG_SMARTCARD_COMMAND 0x9f8e00 -#define TAG_SMARTCARD_REPLY 0x9f8e01 -#define TAG_SMARTCARD_SEND 0x9f8e02 -#define TAG_SMARTCARD_RCV 0x9f8e03 - -/* EPG */ -#define TAG_EPG_ENQUIRY 0x9f8f00 -#define TAG_EPG_REPLY 0x9f8f01 - +struct firedtv_tuner_status { + unsigned active_system:8; + unsigned searching:1; + unsigned moving:1; + unsigned no_rf:1; + unsigned input:1; + unsigned selected_antenna:7; + unsigned ber:32; + unsigned signal_strength:8; + unsigned raster_frequency:2; + unsigned rf_frequency:22; + unsigned man_dep_info_length:8; + unsigned front_end_error:1; + unsigned antenna_error:1; + unsigned front_end_power_status:1; + unsigned power_supply:1; + unsigned carrier_noise_ratio:16; + unsigned power_supply_voltage:8; + unsigned antenna_voltage:8; + unsigned firewire_bus_voltage:8; + unsigned ca_mmi:1; + unsigned ca_pmt_reply:1; + unsigned ca_date_time_request:1; + unsigned ca_application_info:1; + unsigned ca_module_present_status:1; + unsigned ca_dvb_flag:1; + unsigned ca_error_flag:1; + unsigned ca_initialization_status:1; +}; enum model_type { FIREDTV_UNKNOWN = 0, @@ -127,11 +67,22 @@ enum model_type { FIREDTV_DVB_S2 = 4, }; +struct device; struct input_dev; -struct hpsb_iso; -struct unit_directory; +struct firedtv; + +struct firedtv_backend { + int (*lock)(struct firedtv *fdtv, u64 addr, void *data, __be32 arg); + int (*read)(struct firedtv *fdtv, u64 addr, void *data, size_t len); + int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len); + int (*start_iso)(struct firedtv *fdtv); + void (*stop_iso)(struct firedtv *fdtv); +}; struct firedtv { + struct device *device; + struct list_head list; + struct dvb_adapter adapter; struct dmxdev dmxdev; struct dvb_demux demux; @@ -149,79 +100,83 @@ struct firedtv { struct work_struct remote_ctrl_work; struct input_dev *remote_ctrl_dev; - struct firedtv_channel { - bool active; - int pid; - } channel[16]; - struct mutex demux_mutex; + enum model_type type; + char subunit; + char isochannel; + fe_sec_voltage_t voltage; + fe_sec_tone_mode_t tone; - struct unit_directory *ud; + const struct firedtv_backend *backend; + void *backend_data; - enum model_type type; - char subunit; - fe_sec_voltage_t voltage; - fe_sec_tone_mode_t tone; - - int isochannel; - struct hpsb_iso *iso_handle; - - struct list_head list; + struct mutex demux_mutex; + unsigned long channel_active; + u16 channel_pid[16]; - /* needed by avc_api */ - int resp_length; - u8 respfrm[512]; + size_t response_length; + u8 response[512]; }; -struct firewireheader { - union { - struct { - __u8 tcode:4; - __u8 sy:4; - __u8 tag:2; - __u8 channel:6; - - __u8 length_l; - __u8 length_h; - } hdr; - __u32 val; - }; -}; - -struct CIPHeader { - union { - struct { - __u8 syncbits:2; - __u8 sid:6; - __u8 dbs; - __u8 fn:2; - __u8 qpc:3; - __u8 sph:1; - __u8 rsv:2; - __u8 dbc; - __u8 syncbits2:2; - __u8 fmt:6; - __u32 fdf:24; - } cip; - __u64 val; - }; -}; - -extern const char *fdtv_model_names[]; -extern struct list_head fdtv_list; -extern spinlock_t fdtv_list_lock; +/* firedtv-1394.c */ +#ifdef CONFIG_DVB_FIREDTV_IEEE1394 +int fdtv_1394_init(struct ieee1394_device_id id_table[]); +void fdtv_1394_exit(void); +#else +static inline int fdtv_1394_init(struct ieee1394_device_id it[]) { return 0; } +static inline void fdtv_1394_exit(void) {} +#endif -struct device; +/* firedtv-avc.c */ +int avc_recv(struct firedtv *fdtv, void *data, size_t length); +int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat); +struct dvb_frontend_parameters; +int avc_tuner_dsd(struct firedtv *fdtv, struct dvb_frontend_parameters *params); +int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]); +int avc_tuner_get_ts(struct firedtv *fdtv); +int avc_identify_subunit(struct firedtv *fdtv); +struct dvb_diseqc_master_cmd; +int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst, + char conttone, char nrdiseq, + struct dvb_diseqc_master_cmd *diseqcmd); +void avc_remote_ctrl_work(struct work_struct *work); +int avc_register_remote_control(struct firedtv *fdtv); +int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len); +int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len); +int avc_ca_reset(struct firedtv *fdtv); +int avc_ca_pmt(struct firedtv *fdtv, char *app_info, int length); +int avc_ca_get_time_date(struct firedtv *fdtv, int *interval); +int avc_ca_enter_menu(struct firedtv *fdtv); +int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len); +int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel); +void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel); + +/* firedtv-ci.c */ +int fdtv_ca_register(struct firedtv *fdtv); +void fdtv_ca_release(struct firedtv *fdtv); /* firedtv-dvb.c */ int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed); int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed); -int fdtv_dvbdev_init(struct firedtv *fdtv, struct device *dev); +int fdtv_dvb_register(struct firedtv *fdtv); +void fdtv_dvb_unregister(struct firedtv *fdtv); +struct firedtv *fdtv_alloc(struct device *dev, + const struct firedtv_backend *backend, + const char *name, size_t name_len); +extern const char *fdtv_model_names[]; /* firedtv-fe.c */ void fdtv_frontend_init(struct firedtv *fdtv); -/* firedtv-iso.c */ -int setup_iso_channel(struct firedtv *fdtv); -void tear_down_iso_channel(struct firedtv *fdtv); +/* firedtv-rc.c */ +#ifdef CONFIG_DVB_FIREDTV_INPUT +int fdtv_register_rc(struct firedtv *fdtv, struct device *dev); +void fdtv_unregister_rc(struct firedtv *fdtv); +void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code); +#else +static inline int fdtv_register_rc(struct firedtv *fdtv, + struct device *dev) { return 0; } +static inline void fdtv_unregister_rc(struct firedtv *fdtv) {} +static inline void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code) {} +#endif #endif /* _FIREDTV_H */ -- cgit From 325fb5b4d26038cba665dd0d8ee09555321061f0 Mon Sep 17 00:00:00 2001 From: Josef Drexler Date: Tue, 24 Feb 2009 14:53:12 +0100 Subject: netfilter: xt_recent: fix proc-file addition/removal of IPv4 addresses Fix regression introduded by commit 079aa88 (netfilter: xt_recent: IPv6 support): From http://bugzilla.kernel.org/show_bug.cgi?id=12753: Problem Description: An uninitialized buffer causes IPv4 addresses added manually (via the +IP command to the proc interface) to never match any packets. Similarly, the -IP command fails to remove IPv4 addresses. Details: In the function recent_entry_lookup, the xt_recent module does comparisons of the entire nf_inet_addr union value, both for IPv4 and IPv6 addresses. For addresses initialized from actual packets the remaining 12 bytes not occupied by the IPv4 are zeroed so this works correctly. However when setting the nf_inet_addr addr variable in the recent_mt_proc_write function, only the IPv4 bytes are initialized and the remaining 12 bytes contain garbage. Hence addresses added in this way never match any packets, unless these uninitialized 12 bytes happened to be zero by coincidence. Similarly, addresses cannot consistently be removed using the proc interface due to mismatch of the garbage bytes (although it will sometimes work to remove an address that was added manually). Reading the /proc/net/xt_recent/ entries hides this problem because this only uses the first 4 bytes when displaying IPv4 addresses. Steps to reproduce: $ iptables -I INPUT -m recent --rcheck -j LOG $ echo +169.254.156.239 > /proc/net/xt_recent/DEFAULT $ cat /proc/net/xt_recent/DEFAULT src=169.254.156.239 ttl: 0 last_seen: 119910 oldest_pkt: 1 119910 [At this point no packets from 169.254.156.239 are being logged.] $ iptables -I INPUT -s 169.254.156.239 -m recent --set $ cat /proc/net/xt_recent/DEFAULT src=169.254.156.239 ttl: 0 last_seen: 119910 oldest_pkt: 1 119910 src=169.254.156.239 ttl: 255 last_seen: 126184 oldest_pkt: 4 125434, 125684, 125934, 126184 [At this point, adding the address via an iptables rule, packets are being logged correctly.] $ echo -169.254.156.239 > /proc/net/xt_recent/DEFAULT $ cat /proc/net/xt_recent/DEFAULT src=169.254.156.239 ttl: 0 last_seen: 119910 oldest_pkt: 1 119910 src=169.254.156.239 ttl: 255 last_seen: 126992 oldest_pkt: 10 125434, 125684, 125934, 126184, 126434, 126684, 126934, 126991, 126991, 126992 $ echo -169.254.156.239 > /proc/net/xt_recent/DEFAULT $ cat /proc/net/xt_recent/DEFAULT src=169.254.156.239 ttl: 0 last_seen: 119910 oldest_pkt: 1 119910 src=169.254.156.239 ttl: 255 last_seen: 126992 oldest_pkt: 10 125434, 125684, 125934, 126184, 126434, 126684, 126934, 126991, 126991, 126992 [Removing the address via /proc interface failed evidently.] Possible solutions: - initialize the addr variable in recent_mt_proc_write - compare only 4 bytes for IPv4 addresses in recent_entry_lookup Signed-off-by: Patrick McHardy --- net/netfilter/xt_recent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c index fe80b614a40..791e030ea90 100644 --- a/net/netfilter/xt_recent.c +++ b/net/netfilter/xt_recent.c @@ -542,7 +542,7 @@ recent_mt_proc_write(struct file *file, const char __user *input, struct recent_entry *e; char buf[sizeof("+b335:1d35:1e55:dead:c0de:1715:5afe:c0de")]; const char *c = buf; - union nf_inet_addr addr; + union nf_inet_addr addr = {}; u_int16_t family; bool add, succ; -- cgit From 1f9da5544073d38e05139f8ce9da24e78653c73e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 24 Feb 2009 15:31:02 +0100 Subject: ALSA: emu10k1 - Fix digital/analog switch on audigy2 ZS Fix the inverted logic of shared spdif switch. Reference: Novell bnc#478496 https://bugzilla.novell.com/show_bug.cgi?id=478496 Signed-off-by: Takashi Iwai --- sound/pci/emu10k1/emu10k1_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 7958006a1d6..101a1c13a20 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -1528,6 +1528,7 @@ static struct snd_emu_chip_details emu_chip_details[] = { .ca0151_chip = 1, .spk71 = 1, .spdif_bug = 1, + .invert_shared_spdif = 1, /* digital/analog switch swapped */ .ac97_chip = 1} , {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102, .driver = "Audigy2", .name = "SB Audigy 2 Platinum [SB0240P]", -- cgit From 30d697fa3a25fed809a873b17531a00282dc1234 Mon Sep 17 00:00:00 2001 From: Salman Qazi Date: Mon, 23 Feb 2009 18:03:04 -0800 Subject: x86: fix performance regression in write() syscall While the introduction of __copy_from_user_nocache (see commit: 0812a579c92fefa57506821fa08e90f47cb6dbdd) may have been an improvement for sufficiently large writes, there is evidence to show that it is deterimental for small writes. Unixbench's fstime test gives the following results for 256 byte writes with MAX_BLOCK of 2000: 2.6.29-rc6 ( 5 samples, each in KB/sec ): 283750, 295200, 294500, 293000, 293300 2.6.29-rc6 + this patch (5 samples, each in KB/sec): 313050, 3106750, 293350, 306300, 307900 2.6.18 395700, 342000, 399100, 366050, 359850 See w_test() in src/fstime.c in unixbench version 4.1.0. Basically, the above test consists of counting how much we can write in this manner: alarm(10); while (!sigalarm) { for (f_blocks = 0; f_blocks < 2000; ++f_blocks) { write(f, buf, 256); } lseek(f, 0L, 0); } Note, there are other components to the write syscall regression that are not addressed here. Signed-off-by: Salman Qazi Cc: Linus Torvalds Signed-off-by: Ingo Molnar --- arch/x86/include/asm/uaccess_64.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h index 84210c479fc..987a2c10fe2 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h @@ -192,14 +192,26 @@ static inline int __copy_from_user_nocache(void *dst, const void __user *src, unsigned size) { might_sleep(); - return __copy_user_nocache(dst, src, size, 1); + /* + * In practice this limit means that large file write()s + * which get chunked to 4K copies get handled via + * non-temporal stores here. Smaller writes get handled + * via regular __copy_from_user(): + */ + if (likely(size >= PAGE_SIZE)) + return __copy_user_nocache(dst, src, size, 1); + else + return __copy_from_user(dst, src, size); } static inline int __copy_from_user_inatomic_nocache(void *dst, const void __user *src, unsigned size) { - return __copy_user_nocache(dst, src, size, 0); + if (likely(size >= PAGE_SIZE)) + return __copy_user_nocache(dst, src, size, 0); + else + return __copy_from_user_inatomic(dst, src, size); } unsigned long -- cgit From e73bf9f135fe1e5db646e668676d22af3008e0c0 Mon Sep 17 00:00:00 2001 From: Beat Michel Liechti Date: Tue, 24 Feb 2009 15:52:49 +0100 Subject: firedtv: dvb_frontend_info for FireDTV S2, fix "frequency limits undefined" error I found that the function fdtv_frontend_init in the file firedtv-fe.c was missing a case for FIREDTV_DVB_S2 which resulted in "frequency limits undefined" errors in syslog. Signed-off-by: Beat Michel Liechti Change by Stefan R: combine it with case case FIREDTV_DVB_S as originally suggested by Beat Michel. This enables FE_CAN_FEC_AUTO also for FireDTV-S2 devices which is possible as long as only DVB-S channels are used. FE_CAN_FEC_AUTO would be wrong for DVB-S2 channels, but those cannot be used yet since the driver is not yet converted to S2API. Signed-off-by: Stefan Richter --- drivers/media/dvb/firewire/firedtv-fe.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/dvb/firewire/firedtv-fe.c b/drivers/media/dvb/firewire/firedtv-fe.c index 9b9539c800f..7ba43630a25 100644 --- a/drivers/media/dvb/firewire/firedtv-fe.c +++ b/drivers/media/dvb/firewire/firedtv-fe.c @@ -185,6 +185,7 @@ void fdtv_frontend_init(struct firedtv *fdtv) switch (fdtv->type) { case FIREDTV_DVB_S: + case FIREDTV_DVB_S2: fi->type = FE_QPSK; fi->frequency_min = 950000; -- cgit From 2a0b1001116de51f13b2969a9a52bd2bc294644f Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Mon, 23 Feb 2009 22:56:57 +0300 Subject: x86: head_64.S - remove useless balign Impact: cleanup NEXT_PAGE already has 'balign' so no need to keep this redundant one. Signed-off-by: Cyrill Gorcunov Cc: heukelum@fastmail.fm Signed-off-by: Ingo Molnar --- arch/x86/kernel/head_64.S | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 2e648e3a5ea..52c9af429dd 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -329,8 +329,6 @@ early_idt_ripmsg: #endif /* CONFIG_EARLY_PRINTK */ .previous -.balign PAGE_SIZE - #define NEXT_PAGE(name) \ .balign PAGE_SIZE; \ ENTRY(name) -- cgit From 5e112ae23b404ccba0a61630b82ec44f0d084880 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Mon, 23 Feb 2009 22:56:58 +0300 Subject: x86: head_64.S - use IDT_ENTRIES instead of hardcoded number Impact: cleanup Signed-off-by: Cyrill Gorcunov Cc: heukelum@fastmail.fm Cc: Cyrill Gorcunov Signed-off-by: Ingo Molnar --- arch/x86/kernel/head_64.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 52c9af429dd..54b29bb24e7 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -417,7 +417,7 @@ ENTRY(phys_base) .section .bss, "aw", @nobits .align L1_CACHE_BYTES ENTRY(idt_table) - .skip 256 * 16 + .skip IDT_ENTRIES * 16 .section .bss.page_aligned, "aw", @nobits .align PAGE_SIZE -- cgit From 57e372932cec8eb141cde039aaeaa91b69fceba2 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Mon, 23 Feb 2009 22:56:59 +0300 Subject: x86: invalid_vm86_irq -- use predefined macros Impact: cleanup Signed-off-by: Cyrill Gorcunov Cc: heukelum@fastmail.fm Cc: Cyrill Gorcunov Signed-off-by: Ingo Molnar --- arch/x86/include/asm/irq_vectors.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h index b07278c55e9..8a285f356f8 100644 --- a/arch/x86/include/asm/irq_vectors.h +++ b/arch/x86/include/asm/irq_vectors.h @@ -128,7 +128,7 @@ #ifndef __ASSEMBLY__ static inline int invalid_vm86_irq(int irq) { - return irq < 3 || irq > 15; + return irq < FIRST_VM86_IRQ || irq > LAST_VM86_IRQ; } #endif -- cgit From b3baaa138cd4223bffb6ca64b873d25cfb1d7c70 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Mon, 23 Feb 2009 22:57:00 +0300 Subject: x86: entry_64.S - add missing ENDPROC native_usergs_sysret64 is described as extern void native_usergs_sysret64(void) so lets add ENDPROC here Signed-off-by: Cyrill Gorcunov Cc: heukelum@fastmail.fm Cc: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar --- arch/x86/kernel/entry_64.S | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index fbcf96b295f..7cf8d798042 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -188,6 +188,7 @@ return_to_handler: ENTRY(native_usergs_sysret64) swapgs sysretq +ENDPROC(native_usergs_sysret64) #endif /* CONFIG_PARAVIRT */ -- cgit From bc8b2b9258488b932cd399112e01d5afffc4ee96 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Mon, 23 Feb 2009 22:57:01 +0300 Subject: x86: head_64.S - use GLOBAL macro Impact: cleanup Signed-off-by: Cyrill Gorcunov Cc: heukelum@fastmail.fm Signed-off-by: Ingo Molnar --- arch/x86/kernel/entry_64.S | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 7cf8d798042..8a6c7c63885 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -77,20 +77,17 @@ ENTRY(ftrace_caller) movq 8(%rbp), %rsi subq $MCOUNT_INSN_SIZE, %rdi -.globl ftrace_call -ftrace_call: +GLOBAL(ftrace_call) call ftrace_stub MCOUNT_RESTORE_FRAME #ifdef CONFIG_FUNCTION_GRAPH_TRACER -.globl ftrace_graph_call -ftrace_graph_call: +GLOBAL(ftrace_graph_call) jmp ftrace_stub #endif -.globl ftrace_stub -ftrace_stub: +GLOBAL(ftrace_stub) retq END(ftrace_caller) @@ -110,8 +107,7 @@ ENTRY(mcount) jnz ftrace_graph_caller #endif -.globl ftrace_stub -ftrace_stub: +GLOBAL(ftrace_stub) retq trace: @@ -148,9 +144,7 @@ ENTRY(ftrace_graph_caller) retq END(ftrace_graph_caller) - -.globl return_to_handler -return_to_handler: +GLOBAL(return_to_handler) subq $80, %rsp movq %rax, (%rsp) @@ -634,16 +628,14 @@ tracesys: * Syscall return path ending with IRET. * Has correct top of stack, but partial stack frame. */ - .globl int_ret_from_sys_call - .globl int_with_check -int_ret_from_sys_call: +GLOBAL(int_ret_from_sys_call) DISABLE_INTERRUPTS(CLBR_NONE) TRACE_IRQS_OFF testl $3,CS-ARGOFFSET(%rsp) je retint_restore_args movl $_TIF_ALLWORK_MASK,%edi /* edi: mask to check */ -int_with_check: +GLOBAL(int_with_check) LOCKDEP_SYS_EXIT_IRQ GET_THREAD_INFO(%rcx) movl TI_flags(%rcx),%edx -- cgit From 9f331119a4f95a44d918fe6d5e85998fabf99b72 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Mon, 23 Feb 2009 22:57:02 +0300 Subject: x86: efi_stub_32,64 - add missing ENDPROCs Signed-off-by: Cyrill Gorcunov Cc: heukelum@fastmail.fm Signed-off-by: Ingo Molnar --- arch/x86/kernel/efi_stub_32.S | 1 + arch/x86/kernel/efi_stub_64.S | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/arch/x86/kernel/efi_stub_32.S b/arch/x86/kernel/efi_stub_32.S index ef00bb77d7e..a206b946929 100644 --- a/arch/x86/kernel/efi_stub_32.S +++ b/arch/x86/kernel/efi_stub_32.S @@ -113,6 +113,7 @@ ENTRY(efi_call_phys) movl (%edx), %ecx pushl %ecx ret +ENDPROC(efi_call_phys) .previous .data diff --git a/arch/x86/kernel/efi_stub_64.S b/arch/x86/kernel/efi_stub_64.S index 99b47d48c9f..4c07ccab814 100644 --- a/arch/x86/kernel/efi_stub_64.S +++ b/arch/x86/kernel/efi_stub_64.S @@ -41,6 +41,7 @@ ENTRY(efi_call0) addq $32, %rsp RESTORE_XMM ret +ENDPROC(efi_call0) ENTRY(efi_call1) SAVE_XMM @@ -50,6 +51,7 @@ ENTRY(efi_call1) addq $32, %rsp RESTORE_XMM ret +ENDPROC(efi_call1) ENTRY(efi_call2) SAVE_XMM @@ -59,6 +61,7 @@ ENTRY(efi_call2) addq $32, %rsp RESTORE_XMM ret +ENDPROC(efi_call2) ENTRY(efi_call3) SAVE_XMM @@ -69,6 +72,7 @@ ENTRY(efi_call3) addq $32, %rsp RESTORE_XMM ret +ENDPROC(efi_call3) ENTRY(efi_call4) SAVE_XMM @@ -80,6 +84,7 @@ ENTRY(efi_call4) addq $32, %rsp RESTORE_XMM ret +ENDPROC(efi_call4) ENTRY(efi_call5) SAVE_XMM @@ -92,6 +97,7 @@ ENTRY(efi_call5) addq $48, %rsp RESTORE_XMM ret +ENDPROC(efi_call5) ENTRY(efi_call6) SAVE_XMM @@ -107,3 +113,4 @@ ENTRY(efi_call6) addq $48, %rsp RESTORE_XMM ret +ENDPROC(efi_call6) -- cgit From d22157b3d7a24d953ef5cce4515436be65b2e121 Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Mon, 23 Feb 2009 21:50:35 -0800 Subject: PCI: add some sysfs ABI docs Add sysfs ABI docs for driver entries bind, unbind and new_id. These entries are pretty old, from 2.6.0 onwards AFAIK, so this documents current behaviour. Signed-off-by: Chris Wright Acked-by: Greg Kroah-Hartman Signed-off-by: Jesse Barnes --- Documentation/ABI/testing/sysfs-bus-pci | 43 +++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci index ceddcff4082..e638e15a889 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci +++ b/Documentation/ABI/testing/sysfs-bus-pci @@ -1,3 +1,46 @@ +What: /sys/bus/pci/drivers/.../bind +Date: December 2003 +Contact: linux-pci@vger.kernel.org +Description: + Writing a device location to this file will cause + the driver to attempt to bind to the device found at + this location. This is useful for overriding default + bindings. The format for the location is: DDDD:BB:DD.F. + That is Domain:Bus:Device.Function and is the same as + found in /sys/bus/pci/devices/. For example: + # echo 0000:00:19.0 > /sys/bus/pci/drivers/foo/bind + (Note: kernels before 2.6.28 may require echo -n). + +What: /sys/bus/pci/drivers/.../unbind +Date: December 2003 +Contact: linux-pci@vger.kernel.org +Description: + Writing a device location to this file will cause the + driver to attempt to unbind from the device found at + this location. This may be useful when overriding default + bindings. The format for the location is: DDDD:BB:DD.F. + That is Domain:Bus:Device.Function and is the same as + found in /sys/bus/pci/devices/. For example: + # echo 0000:00:19.0 > /sys/bus/pci/drivers/foo/unbind + (Note: kernels before 2.6.28 may require echo -n). + +What: /sys/bus/pci/drivers/.../new_id +Date: December 2003 +Contact: linux-pci@vger.kernel.org +Description: + Writing a device ID to this file will attempt to + dynamically add a new device ID to a PCI device driver. + This may allow the driver to support more hardware than + was included in the driver's static device ID support + table at compile time. The format for the device ID is: + VVVV DDDD SVVV SDDD CCCC MMMM PPPP. That is Vendor ID, + Device ID, Subsystem Vendor ID, Subsystem Device ID, + Class, Class Mask, and Private Driver Data. The Vendor ID + and Device ID fields are required, the rest are optional. + Upon successfully adding an ID, the driver will probe + for the device and attempt to bind to it. For example: + # echo "8086 10f5" > /sys/bus/pci/drivers/foo/new_id + What: /sys/bus/pci/devices/.../vpd Date: February 2008 Contact: Ben Hutchings -- cgit From 1dec6b054dd1fc780e18b815068bf5677409eb2d Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 23 Feb 2009 11:51:59 -0800 Subject: PCI: don't enable too many HT MSI mappings Prakash reported that his c51-mcp51 ondie sound card doesn't work with MSI. But if he hacks out the HT-MSI quirk, MSI works fine. So this patch reworks the nv_msi_ht_cap_quirk(). It will now only enable ht_msi on own its root device, avoiding enabling it on devices following that root dev. Reported-by: Prakash Punnoor Tested-by: Prakash Punnoor Signed-off-by: Yinghai Lu Signed-off-by: Jesse Barnes --- drivers/pci/quirks.c | 115 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 100 insertions(+), 15 deletions(-) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index a21e1c292ee..a8523294e4a 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2050,10 +2050,100 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15, nvenet_msi_disable); -static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) +static void __devinit nv_ht_enable_msi_mapping(struct pci_dev *dev) { struct pci_dev *host_bridge; + int pos; + int i, dev_no; + int found = 0; + + dev_no = dev->devfn >> 3; + for (i = dev_no; i >= 0; i--) { + host_bridge = pci_get_slot(dev->bus, PCI_DEVFN(i, 0)); + if (!host_bridge) + continue; + + pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE); + if (pos != 0) { + found = 1; + break; + } + pci_dev_put(host_bridge); + } + + if (!found) + return; + + /* root did that ! */ + if (msi_ht_cap_enabled(host_bridge)) + goto out; + + ht_enable_msi_mapping(dev); + +out: + pci_dev_put(host_bridge); +} + +static void __devinit ht_disable_msi_mapping(struct pci_dev *dev) +{ + int pos, ttl = 48; + + pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); + while (pos && ttl--) { + u8 flags; + + if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, + &flags) == 0) { + dev_info(&dev->dev, "Enabling HT MSI Mapping\n"); + + pci_write_config_byte(dev, pos + HT_MSI_FLAGS, + flags & ~HT_MSI_FLAGS_ENABLE); + } + pos = pci_find_next_ht_capability(dev, pos, + HT_CAPTYPE_MSI_MAPPING); + } +} + +static int __devinit ht_check_msi_mapping(struct pci_dev *dev) +{ int pos, ttl = 48; + int found = 0; + + /* check if there is HT MSI cap or enabled on this device */ + pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); + while (pos && ttl--) { + u8 flags; + + if (found < 1) + found = 1; + if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, + &flags) == 0) { + if (flags & HT_MSI_FLAGS_ENABLE) { + if (found < 2) { + found = 2; + break; + } + } + } + pos = pci_find_next_ht_capability(dev, pos, + HT_CAPTYPE_MSI_MAPPING); + } + + return found; +} + +static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) +{ + struct pci_dev *host_bridge; + int pos; + int found; + + /* check if there is HT MSI cap or enabled on this device */ + found = ht_check_msi_mapping(dev); + + /* no HT MSI CAP */ + if (found == 0) + return; /* * HT MSI mapping should be disabled on devices that are below @@ -2069,24 +2159,19 @@ static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE); if (pos != 0) { /* Host bridge is to HT */ - ht_enable_msi_mapping(dev); + if (found == 1) { + /* it is not enabled, try to enable it */ + nv_ht_enable_msi_mapping(dev); + } return; } - /* Host bridge is not to HT, disable HT MSI mapping on this device */ - pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); - while (pos && ttl--) { - u8 flags; + /* HT MSI is not enabled */ + if (found == 1) + return; - if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, - &flags) == 0) { - dev_info(&dev->dev, "Disabling HT MSI mapping"); - pci_write_config_byte(dev, pos + HT_MSI_FLAGS, - flags & ~HT_MSI_FLAGS_ENABLE); - } - pos = pci_find_next_ht_capability(dev, pos, - HT_CAPTYPE_MSI_MAPPING); - } + /* Host bridge is not to HT, disable HT MSI mapping on this device */ + ht_disable_msi_mapping(dev); } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk); -- cgit From dbc7e1e567ef8cfc4b792ef6acb51d4ceb15746a Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 28 Jan 2009 19:31:18 -0800 Subject: PCI: pciehp: Handle interrupts that happen during initialization. Move the enabling of interrupts after all of the data structures are setup so that we can safely run the interrupt handler as soon as it is registered. Reviewed-by: Kenji Kaneshige Tested-by: Kenji Kaneshige Signed-off-by: Eric W. Biederman Signed-off-by: Jesse Barnes --- drivers/pci/hotplug/pciehp.h | 2 ++ drivers/pci/hotplug/pciehp_core.c | 7 +++++++ drivers/pci/hotplug/pciehp_hpc.c | 15 +++++++-------- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index db85284ffb6..39ae37589fd 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -111,6 +111,7 @@ struct controller { int cmd_busy; unsigned int no_cmd_complete:1; unsigned int link_active_reporting:1; + unsigned int notification_enabled:1; }; #define INT_BUTTON_IGNORE 0 @@ -170,6 +171,7 @@ extern int pciehp_configure_device(struct slot *p_slot); extern int pciehp_unconfigure_device(struct slot *p_slot); extern void pciehp_queue_pushbutton_work(struct work_struct *work); struct controller *pcie_init(struct pcie_device *dev); +int pcie_init_notification(struct controller *ctrl); int pciehp_enable_slot(struct slot *p_slot); int pciehp_disable_slot(struct slot *p_slot); int pcie_enable_notification(struct controller *ctrl); diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index c2485542f54..681e3912b82 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -434,6 +434,13 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ goto err_out_release_ctlr; } + /* Enable events after we have setup the data structures */ + rc = pcie_init_notification(ctrl); + if (rc) { + ctrl_err(ctrl, "Notification initialization failed\n"); + goto err_out_release_ctlr; + } + /* Check if slot is occupied */ t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); t_slot->hpc_ops->get_adapter_status(t_slot, &value); diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 71a8012886b..7a16c6897bb 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -934,7 +934,7 @@ static void pcie_disable_notification(struct controller *ctrl) ctrl_warn(ctrl, "Cannot disable software notification\n"); } -static int pcie_init_notification(struct controller *ctrl) +int pcie_init_notification(struct controller *ctrl) { if (pciehp_request_irq(ctrl)) return -1; @@ -942,13 +942,17 @@ static int pcie_init_notification(struct controller *ctrl) pciehp_free_irq(ctrl); return -1; } + ctrl->notification_enabled = 1; return 0; } static void pcie_shutdown_notification(struct controller *ctrl) { - pcie_disable_notification(ctrl); - pciehp_free_irq(ctrl); + if (ctrl->notification_enabled) { + pcie_disable_notification(ctrl); + pciehp_free_irq(ctrl); + ctrl->notification_enabled = 0; + } } static int pcie_init_slot(struct controller *ctrl) @@ -1110,13 +1114,8 @@ struct controller *pcie_init(struct pcie_device *dev) if (pcie_init_slot(ctrl)) goto abort_ctrl; - if (pcie_init_notification(ctrl)) - goto abort_slot; - return ctrl; -abort_slot: - pcie_cleanup_slot(ctrl); abort_ctrl: kfree(ctrl); abort: -- cgit From 1f9f13c8d59c1d8da1a602b71d1ab96d1d37d69e Mon Sep 17 00:00:00 2001 From: Andrew Patterson Date: Fri, 20 Feb 2009 16:04:59 -0700 Subject: PCI: Enable PCIe AER only after checking firmware support The PCIe port driver currently sets the PCIe AER error reporting bits for any root or switch port without first checking to see if firmware will grant control. This patch moves setting these bits to the AER service driver aer_enable_port routine. The bits are then set for the root port and any downstream switch ports after the check for firmware support (aer_osc_setup) is made. The patch also unsets the bits in a similar fashion when the AER service driver is unloaded. Reviewed-by: Alex Chiang Signed-off-by: Andrew Patterson Signed-off-by: Jesse Barnes --- drivers/pci/pcie/aer/aerdrv_core.c | 48 +++++++++++++++++++++++++++++++------- drivers/pci/pcie/portdrv_pci.c | 2 -- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index aac7006949f..d0c97368586 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -108,6 +108,34 @@ int pci_cleanup_aer_correct_error_status(struct pci_dev *dev) } #endif /* 0 */ + +static void set_device_error_reporting(struct pci_dev *dev, void *data) +{ + bool enable = *((bool *)data); + + if (dev->pcie_type != PCIE_RC_PORT && + dev->pcie_type != PCIE_SW_UPSTREAM_PORT && + dev->pcie_type != PCIE_SW_DOWNSTREAM_PORT) + return; + + if (enable) + pci_enable_pcie_error_reporting(dev); + else + pci_disable_pcie_error_reporting(dev); +} + +/** + * set_downstream_devices_error_reporting - enable/disable the error reporting bits on the root port and its downstream ports. + * @dev: pointer to root port's pci_dev data structure + * @enable: true = enable error reporting, false = disable error reporting. + */ +static void set_downstream_devices_error_reporting(struct pci_dev *dev, + bool enable) +{ + set_device_error_reporting(dev, &enable); + pci_walk_bus(dev->subordinate, set_device_error_reporting, &enable); +} + static int find_device_iter(struct device *device, void *data) { struct pci_dev *dev; @@ -525,15 +553,11 @@ void aer_enable_rootport(struct aer_rpc *rpc) pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, ®32); pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32); - /* Enable Root Port device reporting error itself */ - pci_read_config_word(pdev, pos+PCI_EXP_DEVCTL, ®16); - reg16 = reg16 | - PCI_EXP_DEVCTL_CERE | - PCI_EXP_DEVCTL_NFERE | - PCI_EXP_DEVCTL_FERE | - PCI_EXP_DEVCTL_URRE; - pci_write_config_word(pdev, pos+PCI_EXP_DEVCTL, - reg16); + /* + * Enable error reporting for the root port device and downstream port + * devices. + */ + set_downstream_devices_error_reporting(pdev, true); /* Enable Root Port's interrupt in response to error messages */ pci_write_config_dword(pdev, @@ -553,6 +577,12 @@ static void disable_root_aer(struct aer_rpc *rpc) u32 reg32; int pos; + /* + * Disable error reporting for the root port device and downstream port + * devices. + */ + set_downstream_devices_error_reporting(pdev, false); + pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); /* Disable Root's interrupt in response to error messages */ pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, 0); diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index f9b874eaeb9..248b4db9155 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c @@ -97,8 +97,6 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev, pcie_portdrv_save_config(dev); - pci_enable_pcie_error_reporting(dev); - return 0; } -- cgit From e07a4b9217d1e97d2f3a62b6b070efdc61212110 Mon Sep 17 00:00:00 2001 From: Helge Bahmann Date: Fri, 20 Feb 2009 16:24:12 +0300 Subject: proc: fix PG_locked reporting in /proc/kpageflags Expr always evaluates to zero. Cc: Matt Mackall Signed-off-by: Andrew Morton Signed-off-by: Alexey Dobriyan --- fs/proc/page.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/proc/page.c b/fs/proc/page.c index 767d95a6d1b..2d1345112a4 100644 --- a/fs/proc/page.c +++ b/fs/proc/page.c @@ -107,7 +107,7 @@ static ssize_t kpageflags_read(struct file *file, char __user *buf, else kflags = ppage->flags; - uflags = kpf_copy_bit(KPF_LOCKED, PG_locked, kflags) | + uflags = kpf_copy_bit(kflags, KPF_LOCKED, PG_locked) | kpf_copy_bit(kflags, KPF_ERROR, PG_error) | kpf_copy_bit(kflags, KPF_REFERENCED, PG_referenced) | kpf_copy_bit(kflags, KPF_UPTODATE, PG_uptodate) | -- cgit From f29d2e0275a4f03ef2fd158e484508dcb0c64efb Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Tue, 24 Feb 2009 19:19:48 +0100 Subject: i2c: Fix misplaced parentheses Fix misplaced parentheses. Signed-off-by: Roel Kluin Signed-off-by: Jean Delvare --- drivers/i2c/i2c-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index b1c9abe24c7..e7d984866de 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -1831,7 +1831,8 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, case I2C_SMBUS_QUICK: msg[0].len = 0; /* Special case: The read/write field is used as data */ - msg[0].flags = flags | (read_write==I2C_SMBUS_READ)?I2C_M_RD:0; + msg[0].flags = flags | (read_write == I2C_SMBUS_READ ? + I2C_M_RD : 0); num = 1; break; case I2C_SMBUS_BYTE: -- cgit From a746b578d8406b2db0e9f0d040061bc1f78433cf Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Tue, 24 Feb 2009 19:19:48 +0100 Subject: i2c: Timeouts reach -1 With a postfix decrement these timeouts reach -1 rather than 0, but after the loop it is tested whether they have become 0. As pointed out by Jean Delvare, the condition we are waiting for should also be tested before the timeout. With the current order, you could exit with a timeout error while the job is actually done. Signed-off-by: Roel Kluin Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-amd8111.c | 4 ++-- drivers/i2c/busses/i2c-pxa.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c index edab51973bf..a7c59908c45 100644 --- a/drivers/i2c/busses/i2c-amd8111.c +++ b/drivers/i2c/busses/i2c-amd8111.c @@ -72,7 +72,7 @@ static unsigned int amd_ec_wait_write(struct amd_smbus *smbus) { int timeout = 500; - while (timeout-- && (inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_IBF)) + while ((inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_IBF) && --timeout) udelay(1); if (!timeout) { @@ -88,7 +88,7 @@ static unsigned int amd_ec_wait_read(struct amd_smbus *smbus) { int timeout = 500; - while (timeout-- && (~inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_OBF)) + while ((~inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_OBF) && --timeout) udelay(1); if (!timeout) { diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 6af68146c34..bdb1f7510e9 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -644,7 +644,7 @@ static int i2c_pxa_do_pio_xfer(struct pxa_i2c *i2c, i2c_pxa_start_message(i2c); - while (timeout-- && i2c->msg_num > 0) { + while (i2c->msg_num > 0 && --timeout) { i2c_pxa_handler(0, i2c); udelay(10); } -- cgit From cd97f39b7cdf1c8a9c9f52865eec795b7f0c811d Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 24 Feb 2009 19:19:49 +0100 Subject: i2c-dev: Clarify the unit of ioctl I2C_TIMEOUT The unit in which user-space can set the bus timeout value is jiffies for historical reasons (back when HZ was always 100.) This is however not good because user-space doesn't know how long a jiffy lasts. The timeout value should instead be set in a fixed time unit. Given the original value of HZ, this unit should be 10 ms, for compatibility. Signed-off-by: Jean Delvare Acked-by: Wolfram Sang --- drivers/i2c/i2c-dev.c | 6 +++++- include/linux/i2c-dev.h | 2 +- include/linux/i2c.h | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index c171988a9f5..7e13d2df9af 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -35,6 +35,7 @@ #include #include #include +#include #include static struct i2c_driver i2cdev_driver; @@ -422,7 +423,10 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) client->adapter->retries = arg; break; case I2C_TIMEOUT: - client->adapter->timeout = arg; + /* For historical reasons, user-space sets the timeout + * value in units of 10 ms. + */ + client->adapter->timeout = msecs_to_jiffies(arg * 10); break; default: /* NOTE: returning a fault code here could cause trouble diff --git a/include/linux/i2c-dev.h b/include/linux/i2c-dev.h index 311315b56b6..fd53bfd2647 100644 --- a/include/linux/i2c-dev.h +++ b/include/linux/i2c-dev.h @@ -33,7 +33,7 @@ */ #define I2C_RETRIES 0x0701 /* number of times a device address should be polled when not acknowledging */ -#define I2C_TIMEOUT 0x0702 /* set timeout in jiffies - call with int */ +#define I2C_TIMEOUT 0x0702 /* set timeout in units of 10 ms */ /* NOTE: Slave address is 7 or 10 bits, but 10-bit addresses * are NOT supported! (due to code brokenness) diff --git a/include/linux/i2c.h b/include/linux/i2c.h index fcfbfea3af7..c86c3b07604 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -361,7 +361,7 @@ struct i2c_adapter { struct mutex bus_lock; struct mutex clist_lock; - int timeout; + int timeout; /* in jiffies */ int retries; struct device dev; /* the adapter device */ -- cgit From 082a4cf80966ebcd08bf775cd258171cdd85c1a1 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 24 Feb 2009 19:19:49 +0100 Subject: i2c: Make sure i2c_algo_bit_data.timeout is HZ-independent i2c_algo_bit_data.timeout is supposed to be in jiffies, so drivers should use set this value in terms of HZ. Ultimately I think this field should be discarded in favor of i2c_adapter.timeout, but that's left for a future patch. Signed-off-by: Jean Delvare Acked-by: Russell King Acked-by: Lennert Buytenhek Acked-by: Len Sorensen --- drivers/i2c/busses/i2c-acorn.c | 2 +- drivers/i2c/busses/i2c-ixp2000.c | 2 +- drivers/i2c/busses/scx200_i2c.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-acorn.c b/drivers/i2c/busses/i2c-acorn.c index 9fee3ca1734..dddccdd91f9 100644 --- a/drivers/i2c/busses/i2c-acorn.c +++ b/drivers/i2c/busses/i2c-acorn.c @@ -79,7 +79,7 @@ static struct i2c_algo_bit_data ioc_data = { .getsda = ioc_getsda, .getscl = ioc_getscl, .udelay = 80, - .timeout = 100 + .timeout = HZ, }; static struct i2c_adapter ioc_ops = { diff --git a/drivers/i2c/busses/i2c-ixp2000.c b/drivers/i2c/busses/i2c-ixp2000.c index 8e846797048..c016f7a2c5f 100644 --- a/drivers/i2c/busses/i2c-ixp2000.c +++ b/drivers/i2c/busses/i2c-ixp2000.c @@ -114,7 +114,7 @@ static int ixp2000_i2c_probe(struct platform_device *plat_dev) drv_data->algo_data.getsda = ixp2000_bit_getsda; drv_data->algo_data.getscl = ixp2000_bit_getscl; drv_data->algo_data.udelay = 6; - drv_data->algo_data.timeout = 100; + drv_data->algo_data.timeout = HZ; strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name, sizeof(drv_data->adapter.name)); diff --git a/drivers/i2c/busses/scx200_i2c.c b/drivers/i2c/busses/scx200_i2c.c index 162b74a0488..42df0eca43d 100644 --- a/drivers/i2c/busses/scx200_i2c.c +++ b/drivers/i2c/busses/scx200_i2c.c @@ -76,7 +76,7 @@ static struct i2c_algo_bit_data scx200_i2c_data = { .getsda = scx200_i2c_getsda, .getscl = scx200_i2c_getscl, .udelay = 10, - .timeout = 100, + .timeout = HZ, }; static struct i2c_adapter scx200_i2c_ops = { -- cgit From 531660ef5604c75de6fdead9da1304051af17c09 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 24 Feb 2009 19:19:50 +0100 Subject: Add i2c_board_info for RiscPC PCF8583 Add the necessary i2c_board_info structure to fix the lack of PCF8583 RTC on RiscPC. Signed-off-by: Russell King Signed-off-by: Jean Delvare Cc: Alessandro Zummo --- arch/arm/mach-rpc/riscpc.c | 6 ++++++ drivers/i2c/busses/i2c-acorn.c | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c index e88d417736a..c7fc01e9d1f 100644 --- a/arch/arm/mach-rpc/riscpc.c +++ b/arch/arm/mach-rpc/riscpc.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -201,8 +202,13 @@ static struct platform_device *devs[] __initdata = { &pata_device, }; +static struct i2c_board_info i2c_rtc = { + I2C_BOARD_INFO("pcf8583", 0x50) +}; + static int __init rpc_init(void) { + i2c_register_board_info(0, &i2c_rtc, 1); return platform_add_devices(devs, ARRAY_SIZE(devs)); } diff --git a/drivers/i2c/busses/i2c-acorn.c b/drivers/i2c/busses/i2c-acorn.c index dddccdd91f9..9aefb5e5864 100644 --- a/drivers/i2c/busses/i2c-acorn.c +++ b/drivers/i2c/busses/i2c-acorn.c @@ -83,6 +83,7 @@ static struct i2c_algo_bit_data ioc_data = { }; static struct i2c_adapter ioc_ops = { + .nr = 0, .algo_data = &ioc_data, }; @@ -90,7 +91,7 @@ static int __init i2c_ioc_init(void) { force_ones = FORCE_ONES | SCL | SDA; - return i2c_bit_add_bus(&ioc_ops); + return i2c_bit_add_numbered_bus(&ioc_ops); } module_init(i2c_ioc_init); -- cgit From c8532db7f2661b63f658b9a08cf4053a3e6abb78 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 24 Feb 2009 15:55:48 +0100 Subject: [ARM] 5411/1: S3C64XX: Fix EINT unmask Currently the unmask function for EINT interrupts was setting the mask bit rather than clearing it. This was also previously reported and fixed by Kyungmin Park and others. Acked-By: Ben Dooks Signed-off-by: Mark Brown Signed-off-by: Russell King --- arch/arm/plat-s3c64xx/irq-eint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/plat-s3c64xx/irq-eint.c b/arch/arm/plat-s3c64xx/irq-eint.c index 1f7cc0067f5..ebb305ce768 100644 --- a/arch/arm/plat-s3c64xx/irq-eint.c +++ b/arch/arm/plat-s3c64xx/irq-eint.c @@ -55,7 +55,7 @@ static void s3c_irq_eint_unmask(unsigned int irq) u32 mask; mask = __raw_readl(S3C64XX_EINT0MASK); - mask |= eint_irq_to_bit(irq); + mask &= ~eint_irq_to_bit(irq); __raw_writel(mask, S3C64XX_EINT0MASK); } -- cgit From ddf9499b3d1e655f212f22b0a703506fcac90b25 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Mon, 23 Feb 2009 21:34:47 +0000 Subject: x86, Voyager: fix compile by lifting the degeneracy of phys_cpu_present_map This was changed to a physmap_t giving a clashing symbol redefinition, but actually using a physmap_t consumes rather a lot of space on x86, so stick with a private copy renamed with a voyager_ prefix and made static. Nothing outside of the Voyager code uses it, anyway. Signed-off-by: James Bottomley Signed-off-by: H. Peter Anvin --- arch/x86/mach-voyager/voyager_smp.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/arch/x86/mach-voyager/voyager_smp.c b/arch/x86/mach-voyager/voyager_smp.c index 7ffcdeec463..b9cc84a2a4f 100644 --- a/arch/x86/mach-voyager/voyager_smp.c +++ b/arch/x86/mach-voyager/voyager_smp.c @@ -65,7 +65,7 @@ static volatile unsigned long smp_invalidate_needed; /* Bitmask of CPUs present in the system - exported by i386_syms.c, used * by scheduler but indexed physically */ -cpumask_t phys_cpu_present_map = CPU_MASK_NONE; +static cpumask_t voyager_phys_cpu_present_map = CPU_MASK_NONE; /* The internal functions */ static void send_CPI(__u32 cpuset, __u8 cpi); @@ -366,19 +366,19 @@ void __init find_smp_config(void) /* set up everything for just this CPU, we can alter * this as we start the other CPUs later */ /* now get the CPU disposition from the extended CMOS */ - cpus_addr(phys_cpu_present_map)[0] = + cpus_addr(voyager_phys_cpu_present_map)[0] = voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK); - cpus_addr(phys_cpu_present_map)[0] |= + cpus_addr(voyager_phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 1) << 8; - cpus_addr(phys_cpu_present_map)[0] |= + cpus_addr(voyager_phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 2) << 16; - cpus_addr(phys_cpu_present_map)[0] |= + cpus_addr(voyager_phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 3) << 24; - init_cpu_possible(&phys_cpu_present_map); - printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n", - cpus_addr(phys_cpu_present_map)[0]); + init_cpu_possible(&voyager_phys_cpu_present_map); + printk("VOYAGER SMP: voyager_phys_cpu_present_map = 0x%lx\n", + cpus_addr(voyager_phys_cpu_present_map)[0]); /* Here we set up the VIC to enable SMP */ /* enable the CPIs by writing the base vector to their register */ outb(VIC_DEFAULT_CPI_BASE, VIC_CPI_BASE_REGISTER); @@ -628,15 +628,15 @@ void __init smp_boot_cpus(void) /* now that the cat has probed the Voyager System Bus, sanity * check the cpu map */ if (((voyager_quad_processors | voyager_extended_vic_processors) - & cpus_addr(phys_cpu_present_map)[0]) != - cpus_addr(phys_cpu_present_map)[0]) { + & cpus_addr(voyager_phys_cpu_present_map)[0]) != + cpus_addr(voyager_phys_cpu_present_map)[0]) { /* should panic */ printk("\n\n***WARNING*** " "Sanity check of CPU present map FAILED\n"); } } else if (voyager_level == 4) voyager_extended_vic_processors = - cpus_addr(phys_cpu_present_map)[0]; + cpus_addr(voyager_phys_cpu_present_map)[0]; /* this sets up the idle task to run on the current cpu */ voyager_extended_cpus = 1; @@ -670,7 +670,7 @@ void __init smp_boot_cpus(void) /* loop over all the extended VIC CPUs and boot them. The * Quad CPUs must be bootstrapped by their extended VIC cpu */ for (i = 0; i < nr_cpu_ids; i++) { - if (i == boot_cpu_id || !cpu_isset(i, phys_cpu_present_map)) + if (i == boot_cpu_id || !cpu_isset(i, voyager_phys_cpu_present_map)) continue; do_boot_cpu(i); /* This udelay seems to be needed for the Quad boots -- cgit From 10b614eaa847447c2c8646030728309d14bd2d05 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 24 Feb 2009 21:41:32 +0100 Subject: x86_32: summit_32, use BAD_APICID Use BAD_APICID instead of 0xFF constants in summit_cpu_mask_to_apicid. Also remove bogus comments about what we actually return. Signed-off-by: Jiri Slaby Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic/summit_32.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c index cfe7b09015d..d02f4385707 100644 --- a/arch/x86/kernel/apic/summit_32.c +++ b/arch/x86/kernel/apic/summit_32.c @@ -303,12 +303,10 @@ static inline unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask) int cpu; num_bits_set = cpus_weight(*cpumask); - /* Return id to all */ if (num_bits_set >= nr_cpu_ids) - return 0xFF; + return BAD_APICID; /* - * The cpus in the mask must all be on the apic cluster. If are not - * on the same apicid cluster return default value of target_cpus(): + * The cpus in the mask must all be on the apic cluster. */ cpu = first_cpu(*cpumask); apicid = summit_cpu_to_logical_apicid(cpu); @@ -318,9 +316,9 @@ static inline unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask) int new_apicid = summit_cpu_to_logical_apicid(cpu); if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { - printk ("%s: Not a valid mask!\n", __func__); + printk("%s: Not a valid mask!\n", __func__); - return 0xFF; + return BAD_APICID; } apicid = apicid | new_apicid; cpus_found++; -- cgit From b5f26d05565d070b7b352dba56b1f96e10021980 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 24 Feb 2009 21:41:33 +0100 Subject: x86_32: summit_32, de-inline functions The ones which go only into struct genapic are de-inlined by compiler anyway, so remove the inline specifier from them. Afterwards, remove summit_setup_portio_remap completely as it is unused. Remove inline also from summit_cpu_mask_to_apicid, since it's not worth it (it is used in struct genapic too). Signed-off-by: Jiri Slaby Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic/summit_32.c | 47 +++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c index d02f4385707..32838b57a94 100644 --- a/arch/x86/kernel/apic/summit_32.c +++ b/arch/x86/kernel/apic/summit_32.c @@ -48,7 +48,7 @@ #include #include -static inline unsigned summit_get_apic_id(unsigned long x) +static unsigned summit_get_apic_id(unsigned long x) { return (x >> 24) & 0xFF; } @@ -58,7 +58,7 @@ static inline void summit_send_IPI_mask(const cpumask_t *mask, int vector) default_send_IPI_mask_sequence_logical(mask, vector); } -static inline void summit_send_IPI_allbutself(int vector) +static void summit_send_IPI_allbutself(int vector) { cpumask_t mask = cpu_online_map; cpu_clear(smp_processor_id(), mask); @@ -67,7 +67,7 @@ static inline void summit_send_IPI_allbutself(int vector) summit_send_IPI_mask(&mask, vector); } -static inline void summit_send_IPI_all(int vector) +static void summit_send_IPI_all(int vector) { summit_send_IPI_mask(&cpu_online_map, vector); } @@ -82,8 +82,8 @@ extern void setup_summit(void); #define setup_summit() {} #endif -static inline int -summit_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) +static int summit_mps_oem_check(struct mpc_table *mpc, char *oem, + char *productid) { if (!strncmp(oem, "IBM ENSW", 8) && (!strncmp(productid, "VIGIL SMP", 9) @@ -98,7 +98,7 @@ summit_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) } /* Hook from generic ACPI tables.c */ -static inline int summit_acpi_madt_oem_check(char *oem_id, char *oem_table_id) +static int summit_acpi_madt_oem_check(char *oem_id, char *oem_table_id) { if (!strncmp(oem_id, "IBM", 3) && (!strncmp(oem_table_id, "SERVIGIL", 8) @@ -186,7 +186,7 @@ static inline int is_WPEG(struct rio_detail *rio){ #define SUMMIT_APIC_DFR_VALUE (APIC_DFR_CLUSTER) -static inline const cpumask_t *summit_target_cpus(void) +static const cpumask_t *summit_target_cpus(void) { /* CPU_MASK_ALL (0xff) has undefined behaviour with * dest_LowestPrio mode logical clustered apic interrupt routing @@ -195,19 +195,18 @@ static inline const cpumask_t *summit_target_cpus(void) return &cpumask_of_cpu(0); } -static inline unsigned long -summit_check_apicid_used(physid_mask_t bitmap, int apicid) +static unsigned long summit_check_apicid_used(physid_mask_t bitmap, int apicid) { return 0; } /* we don't use the phys_cpu_present_map to indicate apicid presence */ -static inline unsigned long summit_check_apicid_present(int bit) +static unsigned long summit_check_apicid_present(int bit) { return 1; } -static inline void summit_init_apic_ldr(void) +static void summit_init_apic_ldr(void) { unsigned long val, id; int count = 0; @@ -234,18 +233,18 @@ static inline void summit_init_apic_ldr(void) apic_write(APIC_LDR, val); } -static inline int summit_apic_id_registered(void) +static int summit_apic_id_registered(void) { return 1; } -static inline void summit_setup_apic_routing(void) +static void summit_setup_apic_routing(void) { printk("Enabling APIC mode: Summit. Using %d I/O APICs\n", nr_ioapics); } -static inline int summit_apicid_to_node(int logical_apicid) +static int summit_apicid_to_node(int logical_apicid) { #ifdef CONFIG_SMP return apicid_2_node[hard_smp_processor_id()]; @@ -266,7 +265,7 @@ static inline int summit_cpu_to_logical_apicid(int cpu) #endif } -static inline int summit_cpu_present_to_apicid(int mps_cpu) +static int summit_cpu_present_to_apicid(int mps_cpu) { if (mps_cpu < nr_cpu_ids) return (int)per_cpu(x86_bios_cpu_apicid, mps_cpu); @@ -274,28 +273,23 @@ static inline int summit_cpu_present_to_apicid(int mps_cpu) return BAD_APICID; } -static inline physid_mask_t -summit_ioapic_phys_id_map(physid_mask_t phys_id_map) +static physid_mask_t summit_ioapic_phys_id_map(physid_mask_t phys_id_map) { /* For clustered we don't have a good way to do this yet - hack */ return physids_promote(0x0F); } -static inline physid_mask_t summit_apicid_to_cpu_present(int apicid) +static physid_mask_t summit_apicid_to_cpu_present(int apicid) { return physid_mask_of_physid(0); } -static inline void summit_setup_portio_remap(void) -{ -} - -static inline int summit_check_phys_apicid_present(int boot_cpu_physical_apicid) +static int summit_check_phys_apicid_present(int boot_cpu_physical_apicid) { return 1; } -static inline unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask) +static unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask) { int cpus_found = 0; int num_bits_set; @@ -328,8 +322,7 @@ static inline unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask) return apicid; } -static inline unsigned int -summit_cpu_mask_to_apicid_and(const struct cpumask *inmask, +static unsigned int summit_cpu_mask_to_apicid_and(const struct cpumask *inmask, const struct cpumask *andmask) { int apicid = summit_cpu_to_logical_apicid(0); @@ -354,7 +347,7 @@ summit_cpu_mask_to_apicid_and(const struct cpumask *inmask, * * See Intel's IA-32 SW Dev's Manual Vol2 under CPUID. */ -static inline int summit_phys_pkg_id(int cpuid_apic, int index_msb) +static int summit_phys_pkg_id(int cpuid_apic, int index_msb) { return hard_smp_processor_id() >> index_msb; } -- cgit From 41fdff322e26c4a86fe65cf577f2556a650cb7bc Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 12 Feb 2009 13:49:30 +0100 Subject: x86, mce, cmci: export MAX_NR_BANKS Impact: Cleanup (code movement) Move MAX_NR_BANKS into mce.h because it's needed there for followup patches. Signed-off-by: Andi Kleen Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/mce.h | 6 ++++++ arch/x86/kernel/cpu/mcheck/mce_64.c | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index 225cdb5d2bf..39136c497c5 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h @@ -95,6 +95,12 @@ void mce_log(struct mce *m); DECLARE_PER_CPU(struct sys_device, device_mce); extern void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu); +/* + * To support more than 128 would need to escape the predefined + * Linux defined extended banks first. + */ +#define MAX_NR_BANKS (MCE_EXTENDED_BANK - 1) + #ifdef CONFIG_X86_MCE_INTEL void mce_intel_feature_init(struct cpuinfo_x86 *c); #else diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index a4a7c686ce9..39f8bb525a7 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -37,12 +37,6 @@ #define MISC_MCELOG_MINOR 227 -/* - * To support more than 128 would need to escape the predefined - * Linux defined extended banks first. - */ -#define MAX_NR_BANKS (MCE_EXTENDED_BANK - 1) - atomic_t mce_entry; static int mce_dont_init; -- cgit From b276268631af3a1b0df871e10d19d492f0513d4b Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 12 Feb 2009 13:49:31 +0100 Subject: x86, mce, cmci: factor out threshold interrupt handler Impact: cleanup; preparation for feature The mce_amd_64 code has an own private MC threshold vector with an own interrupt handler. Since Intel needs a similar handler it makes sense to share the vector because both can not be active at the same time. I factored the common APIC handler code into a separate file which can be used by both the Intel or AMD MC code. This is needed for the next patch which adds an Intel specific CMCI handler. This patch should be a nop for AMD, it just moves some code around. Signed-off-by: Andi Kleen Signed-off-by: H. Peter Anvin --- arch/x86/Kconfig | 5 +++++ arch/x86/include/asm/mce.h | 2 ++ arch/x86/kernel/cpu/mcheck/Makefile | 1 + arch/x86/kernel/cpu/mcheck/mce_amd_64.c | 15 ++++++--------- arch/x86/kernel/cpu/mcheck/threshold.c | 24 ++++++++++++++++++++++++ 5 files changed, 38 insertions(+), 9 deletions(-) create mode 100644 arch/x86/kernel/cpu/mcheck/threshold.c diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 9c39095b33f..52d7013785f 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -751,6 +751,11 @@ config X86_MCE_AMD Additional support for AMD specific MCE features such as the DRAM Error Threshold. +config X86_MCE_THRESHOLD + depends on X86_MCE_AMD || X86_MCE_INTEL + bool + default y + config X86_MCE_NONFATAL tristate "Check for non-fatal errors on AMD Athlon/Duron / Intel Pentium 4" depends on X86_32 && X86_MCE diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index 39136c497c5..125cd871462 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h @@ -135,5 +135,7 @@ extern void mcheck_init(struct cpuinfo_x86 *c); #define mcheck_init(c) do { } while (0) #endif +extern void (*mce_threshold_vector)(void); + #endif /* __KERNEL__ */ #endif /* _ASM_X86_MCE_H */ diff --git a/arch/x86/kernel/cpu/mcheck/Makefile b/arch/x86/kernel/cpu/mcheck/Makefile index d7d2323bbb6..b2f89829bbe 100644 --- a/arch/x86/kernel/cpu/mcheck/Makefile +++ b/arch/x86/kernel/cpu/mcheck/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_X86_32) += k7.o p4.o p5.o p6.o winchip.o obj-$(CONFIG_X86_MCE_INTEL) += mce_intel_64.o obj-$(CONFIG_X86_MCE_AMD) += mce_amd_64.o obj-$(CONFIG_X86_MCE_NONFATAL) += non-fatal.o +obj-$(CONFIG_X86_MCE_THRESHOLD) += threshold.o diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c index e82c8208b81..49705be9820 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c @@ -79,6 +79,8 @@ static unsigned char shared_bank[NR_BANKS] = { static DEFINE_PER_CPU(unsigned char, bank_map); /* see which banks are on */ +static void amd_threshold_interrupt(void); + /* * CPU Initialization */ @@ -174,6 +176,8 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c) tr.reset = 0; tr.old_limit = 0; threshold_restart_bank(&tr); + + mce_threshold_vector = amd_threshold_interrupt; } } } @@ -187,16 +191,12 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c) * the interrupt goes off when error_count reaches threshold_limit. * the handler will simply log mcelog w/ software defined bank number. */ -asmlinkage void mce_threshold_interrupt(void) +static void amd_threshold_interrupt(void) { unsigned int bank, block; struct mce m; u32 low = 0, high = 0, address = 0; - ack_APIC_irq(); - exit_idle(); - irq_enter(); - mce_setup(&m); /* assume first bank caused it */ @@ -241,13 +241,10 @@ asmlinkage void mce_threshold_interrupt(void) + bank * NR_BLOCKS + block; mce_log(&m); - goto out; + return; } } } -out: - inc_irq_stat(irq_threshold_count); - irq_exit(); } /* diff --git a/arch/x86/kernel/cpu/mcheck/threshold.c b/arch/x86/kernel/cpu/mcheck/threshold.c new file mode 100644 index 00000000000..4319142413d --- /dev/null +++ b/arch/x86/kernel/cpu/mcheck/threshold.c @@ -0,0 +1,24 @@ +/* Common corrected MCE threshold handler code */ +#include +#include +#include +#include +#include + +static void default_threshold_interrupt(void) +{ + printk(KERN_ERR "Unexpected threshold interrupt at vector %x\n", + THRESHOLD_APIC_VECTOR); +} + +void (*mce_threshold_vector)(void) = default_threshold_interrupt; + +asmlinkage void mce_threshold_interrupt(void) +{ + ack_APIC_irq(); + exit_idle(); + irq_enter(); + inc_irq_stat(irq_threshold_count); + mce_threshold_vector(); + irq_exit(); +} -- cgit From f9695df42cdbca78530b4458c38ecfdd0bb90079 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 12 Feb 2009 13:49:32 +0100 Subject: x86, mce, cmci: avoid potential reentry of threshold interrupt Impact: minor bugfix The threshold handler on AMD (and soon on Intel) could be theoretically reentered by the hardware. This could lead to corrupted events because the machine check poll code assumes it is not reentered. Move the APIC ACK to the end of the interrupt handler to let the hardware avoid that. Signed-off-by: Andi Kleen Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/mcheck/threshold.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/mcheck/threshold.c b/arch/x86/kernel/cpu/mcheck/threshold.c index 4319142413d..e4b8a3833fc 100644 --- a/arch/x86/kernel/cpu/mcheck/threshold.c +++ b/arch/x86/kernel/cpu/mcheck/threshold.c @@ -15,10 +15,11 @@ void (*mce_threshold_vector)(void) = default_threshold_interrupt; asmlinkage void mce_threshold_interrupt(void) { - ack_APIC_irq(); exit_idle(); irq_enter(); inc_irq_stat(irq_threshold_count); mce_threshold_vector(); irq_exit(); + /* Ack only at the end to avoid potential reentry */ + ack_APIC_irq(); } -- cgit From 8457c84d68678cbfd4167a9073b89da58e48c037 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 12 Feb 2009 13:49:33 +0100 Subject: x86, mce: replace machine check events logged interval with ratelimit Impact: behavior change, use common code Use a standard leaky bucket ratelimit for the machine check warning print interval instead of waiting every check_interval. Also decrease the limit to twice per minute. This interacts better with threshold interrupts because they can happen more often than check_interval. Signed-off-by: Andi Kleen Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/mcheck/mce_64.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index 39f8bb525a7..9017609cadd 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -488,11 +489,11 @@ static DECLARE_WORK(mce_trigger_work, mce_do_trigger); */ int mce_notify_user(void) { + /* Not more than two messages every minute */ + static DEFINE_RATELIMIT_STATE(ratelimit, 60*HZ, 2); + clear_thread_flag(TIF_MCE_NOTIFY); if (test_and_clear_bit(0, ¬ify_user)) { - static unsigned long last_print; - unsigned long now = jiffies; - wake_up_interruptible(&mce_wait); /* @@ -503,10 +504,8 @@ int mce_notify_user(void) if (trigger[0] && !work_pending(&mce_trigger_work)) schedule_work(&mce_trigger_work); - if (time_after_eq(now, last_print + (check_interval*HZ))) { - last_print = now; + if (__ratelimit(&ratelimit)) printk(KERN_INFO "Machine check events logged\n"); - } return 1; } -- cgit From ee031c31d6381d004bfd386c2e45821211507499 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 12 Feb 2009 13:49:34 +0100 Subject: x86, mce, cmci: use polled banks bitmap in machine check poller Define a per cpu bitmap that contains the banks polled by the machine check poller. This is needed for the CMCI code in the next patches to be able to disable polling on specific banks. The bank by default contains all banks, so there is no behaviour change. Only future code will remove some banks from the polling set. Signed-off-by: Andi Kleen Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/mce.h | 5 ++++- arch/x86/kernel/cpu/mcheck/mce_64.c | 16 ++++++++++++---- arch/x86/kernel/cpu/mcheck/mce_amd_64.c | 3 ++- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index 125cd871462..9b9523699db 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h @@ -119,11 +119,14 @@ extern atomic_t mce_entry; extern void do_machine_check(struct pt_regs *, long); +typedef DECLARE_BITMAP(mce_banks_t, MAX_NR_BANKS); +DECLARE_PER_CPU(mce_banks_t, mce_poll_banks); + enum mcp_flags { MCP_TIMESTAMP = (1 << 0), /* log time stamp */ MCP_UC = (1 << 1), /* log uncorrected errors */ }; -extern void machine_check_poll(enum mcp_flags flags); +extern void machine_check_poll(enum mcp_flags flags, mce_banks_t *b); extern int mce_notify_user(void); diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index 9017609cadd..a8ff38bfa6e 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -62,6 +62,11 @@ static char *trigger_argv[2] = { trigger, NULL }; static DECLARE_WAIT_QUEUE_HEAD(mce_wait); +/* MCA banks polled by the period polling timer for corrected events */ +DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = { + [0 ... BITS_TO_LONGS(MAX_NR_BANKS)-1] = ~0UL +}; + /* Do initial initialization of a struct mce */ void mce_setup(struct mce *m) { @@ -191,7 +196,7 @@ static inline void mce_get_rip(struct mce *m, struct pt_regs *regs) * * This is executed in standard interrupt context. */ -void machine_check_poll(enum mcp_flags flags) +void machine_check_poll(enum mcp_flags flags, mce_banks_t *b) { struct mce m; int i; @@ -200,7 +205,7 @@ void machine_check_poll(enum mcp_flags flags) rdmsrl(MSR_IA32_MCG_STATUS, m.mcgstatus); for (i = 0; i < banks; i++) { - if (!bank[i]) + if (!bank[i] || !test_bit(i, *b)) continue; m.misc = 0; @@ -458,7 +463,8 @@ static void mcheck_timer(unsigned long data) WARN_ON(smp_processor_id() != data); if (mce_available(¤t_cpu_data)) - machine_check_poll(MCP_TIMESTAMP); + machine_check_poll(MCP_TIMESTAMP, + &__get_cpu_var(mce_poll_banks)); /* * Alert userspace if needed. If we logged an MCE, reduce the @@ -572,11 +578,13 @@ static void mce_init(void *dummy) { u64 cap; int i; + mce_banks_t all_banks; /* * Log the machine checks left over from the previous reset. */ - machine_check_poll(MCP_UC); + bitmap_fill(all_banks, MAX_NR_BANKS); + machine_check_poll(MCP_UC, &all_banks); set_in_cr4(X86_CR4_MCE); diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c index 49705be9820..ee8bfcd3aa3 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c @@ -231,7 +231,8 @@ static void amd_threshold_interrupt(void) /* Log the machine check that caused the threshold event. */ - machine_check_poll(MCP_TIMESTAMP); + machine_check_poll(MCP_TIMESTAMP, + &__get_cpu_var(mce_poll_banks)); if (high & MASK_OVERFLOW_HI) { rdmsrl(address, m.misc); -- cgit From 03195c6b40f2b4db92545921daa7c3a19b4e4c32 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 12 Feb 2009 13:49:35 +0100 Subject: x86, mce, cmci: define MSR names and fields for new CMCI registers Impact: New register definitions only CMCI means support for raising an interrupt on a corrected machine check event instead of having to poll for it. It's a new feature in Intel Nehalem CPUs available on some machine check banks. For details see the IA32 SDM Vol3a 14.5 Define the registers for it as a preparation for further patches. Signed-off-by: Andi Kleen Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/apicdef.h | 1 + arch/x86/include/asm/mce.h | 2 ++ arch/x86/include/asm/msr-index.h | 5 +++++ 3 files changed, 8 insertions(+) diff --git a/arch/x86/include/asm/apicdef.h b/arch/x86/include/asm/apicdef.h index 63134e31e8b..bc9514fb3b1 100644 --- a/arch/x86/include/asm/apicdef.h +++ b/arch/x86/include/asm/apicdef.h @@ -53,6 +53,7 @@ #define APIC_ESR_SENDILL 0x00020 #define APIC_ESR_RECVILL 0x00040 #define APIC_ESR_ILLREGA 0x00080 +#define APIC_LVTCMCI 0x2f0 #define APIC_ICR 0x300 #define APIC_DEST_SELF 0x40000 #define APIC_DEST_ALLINC 0x80000 diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index 9b9523699db..6fc5e07eca4 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h @@ -11,6 +11,8 @@ */ #define MCG_CTL_P (1UL<<8) /* MCG_CAP register available */ +#define MCG_EXT_P (1ULL<<9) /* Extended registers available */ +#define MCG_CMCI_P (1ULL<<10) /* CMCI supported */ #define MCG_STATUS_RIPV (1UL<<0) /* restart ip valid */ #define MCG_STATUS_EIPV (1UL<<1) /* ip points to correct instruction */ diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 358acc59ae0..2dbd2314139 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -77,6 +77,11 @@ #define MSR_IA32_MC0_ADDR 0x00000402 #define MSR_IA32_MC0_MISC 0x00000403 +/* These are consecutive and not in the normal 4er MCE bank block */ +#define MSR_IA32_MC0_CTL2 0x00000280 +#define CMCI_EN (1ULL << 30) +#define CMCI_THRESHOLD_MASK 0xffffULL + #define MSR_P6_PERFCTR0 0x000000c1 #define MSR_P6_PERFCTR1 0x000000c2 #define MSR_P6_EVNTSEL0 0x00000186 -- cgit From 88ccbedd9ca85d1aca6a6f99df48dce87b7c02d4 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 12 Feb 2009 13:49:36 +0100 Subject: x86, mce, cmci: add CMCI support Impact: Major new feature Intel CMCI (Corrected Machine Check Interrupt) is a new feature on Nehalem CPUs. It allows the CPU to trigger interrupts on corrected events, which allows faster reaction to them instead of with the traditional polling timer. Also use CMCI to discover shared banks. Machine check banks can be shared by CPU threads or even cores. Using the CMCI enable bit it is possible to detect the fact that another CPU already saw a specific bank. Use this to assign shared banks only to one CPU to avoid reporting duplicated events. On CPU hot unplug bank sharing is re discovered. This is done using a thread that cycles through all the CPUs. To avoid races between the poller and CMCI we only poll for banks that are not CMCI capable and only check CMCI owned banks on a interrupt. The shared banks ownership information is currently only used for CMCI interrupts, not polled banks. The sharing discovery code follows the algorithm recommended in the IA32 SDM Vol3a 14.5.2.1 The CMCI interrupt handler just calls the machine check poller to pick up the machine check event that caused the interrupt. I decided not to implement a separate threshold event like the AMD version has, because the threshold is always one currently and adding another event didn't seem to add any value. Some code inspired by Yunhong Jiang's Xen implementation, which was in term inspired by a earlier CMCI implementation by me. Signed-off-by: Andi Kleen Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/mce.h | 10 ++ arch/x86/kernel/cpu/mcheck/mce_64.c | 16 ++- arch/x86/kernel/cpu/mcheck/mce_intel_64.c | 205 ++++++++++++++++++++++++++++++ 3 files changed, 228 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index 6fc5e07eca4..563933e06a3 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h @@ -105,8 +105,16 @@ extern void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu); #ifdef CONFIG_X86_MCE_INTEL void mce_intel_feature_init(struct cpuinfo_x86 *c); +void cmci_clear(void); +void cmci_reenable(void); +void cmci_rediscover(int dying); +void cmci_recheck(void); #else static inline void mce_intel_feature_init(struct cpuinfo_x86 *c) { } +static inline void cmci_clear(void) {} +static inline void cmci_reenable(void) {} +static inline void cmci_rediscover(int dying) {} +static inline void cmci_recheck(void) {} #endif #ifdef CONFIG_X86_MCE_AMD @@ -115,6 +123,8 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c); static inline void mce_amd_feature_init(struct cpuinfo_x86 *c) { } #endif +extern int mce_available(struct cpuinfo_x86 *c); + void mce_log_therm_throt_event(__u64 status); extern atomic_t mce_entry; diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index a8ff38bfa6e..bfbd5323a63 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -166,7 +166,7 @@ static void mce_panic(char *msg, struct mce *backup, unsigned long start) panic(msg); } -static int mce_available(struct cpuinfo_x86 *c) +int mce_available(struct cpuinfo_x86 *c) { if (mce_dont_init) return 0; @@ -1060,9 +1060,12 @@ static __cpuinit void mce_remove_device(unsigned int cpu) static void mce_disable_cpu(void *h) { int i; + unsigned long action = *(unsigned long *)h; if (!mce_available(¤t_cpu_data)) return; + if (!(action & CPU_TASKS_FROZEN)) + cmci_clear(); for (i = 0; i < banks; i++) wrmsrl(MSR_IA32_MC0_CTL + i*4, 0); } @@ -1070,9 +1073,12 @@ static void mce_disable_cpu(void *h) static void mce_reenable_cpu(void *h) { int i; + unsigned long action = *(unsigned long *)h; if (!mce_available(¤t_cpu_data)) return; + if (!(action & CPU_TASKS_FROZEN)) + cmci_reenable(); for (i = 0; i < banks; i++) wrmsrl(MSR_IA32_MC0_CTL + i*4, bank[i]); } @@ -1100,13 +1106,17 @@ static int __cpuinit mce_cpu_callback(struct notifier_block *nfb, case CPU_DOWN_PREPARE: case CPU_DOWN_PREPARE_FROZEN: del_timer_sync(t); - smp_call_function_single(cpu, mce_disable_cpu, NULL, 1); + smp_call_function_single(cpu, mce_disable_cpu, &action, 1); break; case CPU_DOWN_FAILED: case CPU_DOWN_FAILED_FROZEN: t->expires = round_jiffies_relative(jiffies + next_interval); add_timer_on(t, cpu); - smp_call_function_single(cpu, mce_reenable_cpu, NULL, 1); + smp_call_function_single(cpu, mce_reenable_cpu, &action, 1); + break; + case CPU_POST_DEAD: + /* intentionally ignoring frozen here */ + cmci_rediscover(cpu); break; } return NOTIFY_OK; diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c index 1b1491a76b5..a518ec8c6f8 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c @@ -1,6 +1,8 @@ /* * Intel specific MCE features. * Copyright 2004 Zwane Mwaikambo + * Copyright (C) 2008, 2009 Intel Corporation + * Author: Andi Kleen */ #include @@ -12,6 +14,7 @@ #include #include #include +#include asmlinkage void smp_thermal_interrupt(void) { @@ -84,7 +87,209 @@ static void intel_init_thermal(struct cpuinfo_x86 *c) return; } +/* + * Support for Intel Correct Machine Check Interrupts. This allows + * the CPU to raise an interrupt when a corrected machine check happened. + * Normally we pick those up using a regular polling timer. + * Also supports reliable discovery of shared banks. + */ + +static DEFINE_PER_CPU(mce_banks_t, mce_banks_owned); + +/* + * cmci_discover_lock protects against parallel discovery attempts + * which could race against each other. + */ +static DEFINE_SPINLOCK(cmci_discover_lock); + +#define CMCI_THRESHOLD 1 + +static __cpuinit int cmci_supported(int *banks) +{ + u64 cap; + + /* + * Vendor check is not strictly needed, but the initial + * initialization is vendor keyed and this + * makes sure none of the backdoors are entered otherwise. + */ + if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) + return 0; + if (!cpu_has_apic || lapic_get_maxlvt() < 6) + return 0; + rdmsrl(MSR_IA32_MCG_CAP, cap); + *banks = min_t(unsigned, MAX_NR_BANKS, cap & 0xff); + return !!(cap & MCG_CMCI_P); +} + +/* + * The interrupt handler. This is called on every event. + * Just call the poller directly to log any events. + * This could in theory increase the threshold under high load, + * but doesn't for now. + */ +static void intel_threshold_interrupt(void) +{ + machine_check_poll(MCP_TIMESTAMP, &__get_cpu_var(mce_banks_owned)); + mce_notify_user(); +} + +static void print_update(char *type, int *hdr, int num) +{ + if (*hdr == 0) + printk(KERN_INFO "CPU %d MCA banks", smp_processor_id()); + *hdr = 1; + printk(KERN_CONT " %s:%d", type, num); +} + +/* + * Enable CMCI (Corrected Machine Check Interrupt) for available MCE banks + * on this CPU. Use the algorithm recommended in the SDM to discover shared + * banks. + */ +static __cpuinit void cmci_discover(int banks, int boot) +{ + unsigned long *owned = (void *)&__get_cpu_var(mce_banks_owned); + int hdr = 0; + int i; + + spin_lock(&cmci_discover_lock); + for (i = 0; i < banks; i++) { + u64 val; + + if (test_bit(i, owned)) + continue; + + rdmsrl(MSR_IA32_MC0_CTL2 + i, val); + + /* Already owned by someone else? */ + if (val & CMCI_EN) { + if (test_and_clear_bit(i, owned) || boot) + print_update("SHD", &hdr, i); + __clear_bit(i, __get_cpu_var(mce_poll_banks)); + continue; + } + + val |= CMCI_EN | CMCI_THRESHOLD; + wrmsrl(MSR_IA32_MC0_CTL2 + i, val); + rdmsrl(MSR_IA32_MC0_CTL2 + i, val); + + /* Did the enable bit stick? -- the bank supports CMCI */ + if (val & CMCI_EN) { + if (!test_and_set_bit(i, owned) || boot) + print_update("CMCI", &hdr, i); + __clear_bit(i, __get_cpu_var(mce_poll_banks)); + } else { + WARN_ON(!test_bit(i, __get_cpu_var(mce_poll_banks))); + } + } + spin_unlock(&cmci_discover_lock); + if (hdr) + printk(KERN_CONT "\n"); +} + +/* + * Just in case we missed an event during initialization check + * all the CMCI owned banks. + */ +__cpuinit void cmci_recheck(void) +{ + unsigned long flags; + int banks; + + if (!mce_available(¤t_cpu_data) || !cmci_supported(&banks)) + return; + local_irq_save(flags); + machine_check_poll(MCP_TIMESTAMP, &__get_cpu_var(mce_banks_owned)); + local_irq_restore(flags); +} + +/* + * Disable CMCI on this CPU for all banks it owns when it goes down. + * This allows other CPUs to claim the banks on rediscovery. + */ +void __cpuexit cmci_clear(void) +{ + int i; + int banks; + u64 val; + + if (!cmci_supported(&banks)) + return; + spin_lock(&cmci_discover_lock); + for (i = 0; i < banks; i++) { + if (!test_bit(i, __get_cpu_var(mce_banks_owned))) + continue; + /* Disable CMCI */ + rdmsrl(MSR_IA32_MC0_CTL2 + i, val); + val &= ~(CMCI_EN|CMCI_THRESHOLD_MASK); + wrmsrl(MSR_IA32_MC0_CTL2 + i, val); + __clear_bit(i, __get_cpu_var(mce_banks_owned)); + } + spin_unlock(&cmci_discover_lock); +} + +/* + * After a CPU went down cycle through all the others and rediscover + * Must run in process context. + */ +void __cpuexit cmci_rediscover(int dying) +{ + int banks; + int cpu; + cpumask_var_t old; + + if (!cmci_supported(&banks)) + return; + if (!alloc_cpumask_var(&old, GFP_KERNEL)) + return; + cpumask_copy(old, ¤t->cpus_allowed); + + for_each_online_cpu (cpu) { + if (cpu == dying) + continue; + if (set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu))) + continue; + /* Recheck banks in case CPUs don't all have the same */ + if (cmci_supported(&banks)) + cmci_discover(banks, 0); + } + + set_cpus_allowed_ptr(current, old); + free_cpumask_var(old); +} + +/* + * Reenable CMCI on this CPU in case a CPU down failed. + */ +void cmci_reenable(void) +{ + int banks; + if (cmci_supported(&banks)) + cmci_discover(banks, 0); +} + +static __cpuinit void intel_init_cmci(void) +{ + int banks; + + if (!cmci_supported(&banks)) + return; + + mce_threshold_vector = intel_threshold_interrupt; + cmci_discover(banks, 1); + /* + * For CPU #0 this runs with still disabled APIC, but that's + * ok because only the vector is set up. We still do another + * check for the banks later for CPU #0 just to make sure + * to not miss any events. + */ + apic_write(APIC_LVTCMCI, THRESHOLD_APIC_VECTOR|APIC_DM_FIXED); + cmci_recheck(); +} + void mce_intel_feature_init(struct cpuinfo_x86 *c) { intel_init_thermal(c); + intel_init_cmci(); } -- cgit From df20e2eb3e59b8625021a1bc8b1b53a4edc6008b Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 24 Feb 2009 13:19:02 -0800 Subject: x86, mce, cmci: remove incorrect __cpuinit/__cpuexit annotations Impact: Bug fix on UP The MCE code is reinitialized from resume, so we can't use __cpuinit/__cpuexit for most of the code. Remove those annotations for anything downstream of mce_init(). Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/mcheck/mce_intel_64.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c index a518ec8c6f8..7a2e10fcfa3 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c @@ -104,7 +104,7 @@ static DEFINE_SPINLOCK(cmci_discover_lock); #define CMCI_THRESHOLD 1 -static __cpuinit int cmci_supported(int *banks) +static int cmci_supported(int *banks) { u64 cap; @@ -147,7 +147,7 @@ static void print_update(char *type, int *hdr, int num) * on this CPU. Use the algorithm recommended in the SDM to discover shared * banks. */ -static __cpuinit void cmci_discover(int banks, int boot) +static void cmci_discover(int banks, int boot) { unsigned long *owned = (void *)&__get_cpu_var(mce_banks_owned); int hdr = 0; @@ -192,7 +192,7 @@ static __cpuinit void cmci_discover(int banks, int boot) * Just in case we missed an event during initialization check * all the CMCI owned banks. */ -__cpuinit void cmci_recheck(void) +void cmci_recheck(void) { unsigned long flags; int banks; @@ -208,7 +208,7 @@ __cpuinit void cmci_recheck(void) * Disable CMCI on this CPU for all banks it owns when it goes down. * This allows other CPUs to claim the banks on rediscovery. */ -void __cpuexit cmci_clear(void) +void cmci_clear(void) { int i; int banks; @@ -233,7 +233,7 @@ void __cpuexit cmci_clear(void) * After a CPU went down cycle through all the others and rediscover * Must run in process context. */ -void __cpuexit cmci_rediscover(int dying) +void cmci_rediscover(int dying) { int banks; int cpu; -- cgit From 5ca8681ca10f671427710f4954644359856581a3 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 12 Feb 2009 13:49:37 +0100 Subject: x86, mce, cmci: disable CMCI on rebooting Impact: Avoids confusing other OSes. Disable the CMCI vector on reboot to avoid confusing other OS. Signed-off-by: Andi Kleen Signed-off-by: H. Peter Anvin --- arch/x86/kernel/apic.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c index 570f36e44e5..648676f0b50 100644 --- a/arch/x86/kernel/apic.c +++ b/arch/x86/kernel/apic.c @@ -868,6 +868,14 @@ void clear_local_APIC(void) apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED); } #endif +#ifdef CONFIG_X86_MCE_INTEL + if (maxlvt >= 6) { + v = apic_read(APIC_LVTCMCI); + if (!(v & APIC_LVT_MASKED)) + apic_write(APIC_LVTCMCI, v | APIC_LVT_MASKED); + } +#endif + /* * Clean APIC state for other OSs: */ -- cgit From be71b8553d0522aba535a815baaebb1f0bb9a9ec Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 12 Feb 2009 13:49:38 +0100 Subject: x86, mce, cmci: recheck CMCI banks after APIC has been enabled on CPU #0 Impact: Fix marginal race condition One the first CPU the machine checks are enabled early before the local APIC is enabled. This could in theory lead to some lost CMCI events very early during boot because CMCIs cannot be delivered with disabled LAPIC. The poller also doesn't recover from this because it doesn't check CMCI banks. Add an explicit CMCI banks check after the LAPIC is enabled. This is only done for CPU #0, the other CPUs only initialize machine checks after the LAPIC is on. Signed-off-by: Andi Kleen Signed-off-by: H. Peter Anvin --- arch/x86/kernel/apic.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c index 648676f0b50..57b53774d98 100644 --- a/arch/x86/kernel/apic.c +++ b/arch/x86/kernel/apic.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -1270,6 +1271,12 @@ void __cpuinit setup_local_APIC(void) apic_write(APIC_LVT1, value); preempt_enable(); + +#ifdef CONFIG_X86_MCE_INTEL + /* Recheck CMCI information after local APIC is up on CPU #0 */ + if (smp_processor_id() == 0) + cmci_recheck(); +#endif } void __cpuinit end_local_APIC_setup(void) -- cgit From 46cb27f5169d37be38be8e5729b9a0100e989fa8 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 24 Feb 2009 13:12:43 -0800 Subject: x86: check range in reserve_early() Impact: cleanup one 32-bit system reports: BIOS-provided physical RAM map: BIOS-e820: 0000000000000000 - 000000000009fc00 (usable) BIOS-e820: 000000000009fc00 - 00000000000a0000 (reserved) BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved) BIOS-e820: 0000000000100000 - 000000001c000000 (usable) BIOS-e820: 00000000ffff0000 - 0000000100000000 (reserved) DMI 2.0 present. last_pfn = 0x1c000 max_arch_pfn = 0x100000 kernel direct mapping tables up to 1c000000 @ 7000-c000 .. RAMDISK: 1bc69000 - 1bfef4fa .. 0MB HIGHMEM available. 448MB LOWMEM available. mapped low ram: 0 - 1c000000 low ram: 00000000 - 1c000000 bootmap 00002000 - 00005800 (9 early reservations) ==> bootmem [0000000000 - 001c000000] #0 [0000000000 - 0000001000] BIOS data page ==> [0000000000 - 0000001000] #1 [0000001000 - 0000002000] EX TRAMPOLINE ==> [0000001000 - 0000002000] #2 [0000006000 - 0000007000] TRAMPOLINE ==> [0000006000 - 0000007000] #3 [0000400000 - 00009ed14c] TEXT DATA BSS ==> [0000400000 - 00009ed14c] #4 [001bc69000 - 001bfef4fa] RAMDISK ==> [001bc69000 - 001bfef4fa] #5 [00009ee000 - 00009f2000] INIT_PG_TABLE ==> [00009ee000 - 00009f2000] #6 [000009f400 - 0000100000] BIOS reserved ==> [000009f400 - 0000100000] #7 [0000007000 - 0000007000] PGTABLE #8 [0000002000 - 0000006000] BOOTMAP ==> [0000002000 - 0000006000] Notice the strange blank PGTABLE entry. The reason is init_pg_table is big enough, and zero range is called with init_memory_mapping/reserve_early(). So try to check the range in reserve_early() v2: fix the reversed compare Signed-off-by: Yinghai Lu Cc: nickpiggin@yahoo.com.au Cc: ink@jurassic.park.msu.ru Signed-off-by: Ingo Molnar --- arch/x86/kernel/e820.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index e85826829cf..508bec1cee2 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -858,6 +858,9 @@ void __init reserve_early_overlap_ok(u64 start, u64 end, char *name) */ void __init reserve_early(u64 start, u64 end, char *name) { + if (start >= end) + return; + drop_overlaps_that_are_ok(start, end); __reserve_early(start, end, name, 0); } -- cgit From 1250fbed1471b681f3e75e4938f356a1c0a92d5e Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 12 Feb 2009 13:43:20 +0100 Subject: x86, mce: enable machine checks in 64-bit defconfig Impact: defconfig change Enable MCE in the 64-bit defconfig. Signed-off-by: Andi Kleen Signed-off-by: H. Peter Anvin --- arch/x86/configs/x86_64_defconfig | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig index 10728fd91c6..9fd7d156a12 100644 --- a/arch/x86/configs/x86_64_defconfig +++ b/arch/x86/configs/x86_64_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.29-rc4 -# Thu Feb 12 12:57:29 2009 +# Tue Feb 24 15:44:16 2009 # CONFIG_64BIT=y # CONFIG_X86_32 is not set @@ -268,7 +268,9 @@ CONFIG_PREEMPT_VOLUNTARY=y CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y -# CONFIG_X86_MCE is not set +CONFIG_X86_MCE=y +CONFIG_X86_MCE_INTEL=y +CONFIG_X86_MCE_AMD=y # CONFIG_I8K is not set CONFIG_MICROCODE=y CONFIG_MICROCODE_INTEL=y -- cgit From 15d4fcd615989ed83fe848e6a3c7e9f0361cf0d0 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 24 Feb 2009 15:52:58 -0800 Subject: x86, mce: enable machine checks in 32-bit defconfig Impact: defconfig change Enable MCE in the 32-bit defconfig. Signed-off-by: H. Peter Anvin --- arch/x86/configs/i386_defconfig | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig index 8f40a80ccb5..c2cae417fab 100644 --- a/arch/x86/configs/i386_defconfig +++ b/arch/x86/configs/i386_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.29-rc4 -# Thu Feb 12 12:57:57 2009 +# Tue Feb 24 15:50:58 2009 # # CONFIG_64BIT is not set CONFIG_X86_32=y @@ -268,7 +268,9 @@ CONFIG_PREEMPT_VOLUNTARY=y CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y -# CONFIG_X86_MCE is not set +CONFIG_X86_MCE=y +CONFIG_X86_MCE_NONFATAL=y +CONFIG_X86_MCE_P4THERMAL=y CONFIG_VM86=y # CONFIG_TOSHIBA is not set # CONFIG_I8K is not set -- cgit From a52b8bd338630f78a6bfe39fe17cb8469d2679ae Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 24 Feb 2009 16:40:16 -0800 Subject: tcp_scalable: Update malformed & dead url Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- net/ipv4/tcp_scalable.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/tcp_scalable.c b/net/ipv4/tcp_scalable.c index 2747ec7bfb6..4660b088a8c 100644 --- a/net/ipv4/tcp_scalable.c +++ b/net/ipv4/tcp_scalable.c @@ -1,6 +1,6 @@ /* Tom Kelly's Scalable TCP * - * See htt://www-lce.eng.cam.ac.uk/~ctk21/scalable/ + * See http://www.deneholme.net/tom/scalable/ * * John Heffner */ -- cgit From 24ff954233ecfd45801383f831626f88937ebe6f Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 25 Feb 2009 10:38:10 +0900 Subject: x86, percpu: fix minor bugs in setup_percpu.c Recent changes in setup_percpu.c made a now meaningless DBG() statement fail to compile and introduced a comparison-of-different-types warning. Fix them. Compile failure is reported by Ingo Molnar. Signed-off-by: Tejun Heo Reported-by: Ingo Molnar --- arch/x86/kernel/setup_percpu.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 2d946a8f78b..c29f301d388 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -270,7 +270,7 @@ static ssize_t __init setup_pcpu_embed(size_t static_size) /* allocate and copy */ pcpue_unit_size = PFN_ALIGN(static_size + PERCPU_DYNAMIC_RESERVE); - pcpue_unit_size = max(pcpue_unit_size, PCPU_MIN_UNIT_SIZE); + pcpue_unit_size = max_t(size_t, pcpue_unit_size, PCPU_MIN_UNIT_SIZE); pcpue_ptr = pcpu_alloc_bootmem(0, num_possible_cpus() * pcpue_unit_size, PAGE_SIZE); if (!pcpue_ptr) @@ -438,8 +438,6 @@ void __init setup_per_cpu_areas(void) */ if (cpu == boot_cpu_id) switch_to_new_gdt(cpu); - - DBG("PERCPU: cpu %4d %p\n", cpu, ptr); } /* indicate the early static arrays will soon be gone */ -- cgit From d325100504f1d0c296a1fbfef558deaa655e2240 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 25 Feb 2009 11:01:40 +0900 Subject: x86: convert cacheflush macros inline functions Impact: cleanup Unused macro parameters cause spurious unused variable warnings. Convert all cacheflush macros to inline functions to avoid the warnings and achieve better type checking. Signed-off-by: Tejun Heo --- arch/x86/include/asm/cacheflush.h | 53 ++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/arch/x86/include/asm/cacheflush.h b/arch/x86/include/asm/cacheflush.h index 2f8466540fb..5b301b7ff5f 100644 --- a/arch/x86/include/asm/cacheflush.h +++ b/arch/x86/include/asm/cacheflush.h @@ -5,24 +5,43 @@ #include /* Caches aren't brain-dead on the intel. */ -#define flush_cache_all() do { } while (0) -#define flush_cache_mm(mm) do { } while (0) -#define flush_cache_dup_mm(mm) do { } while (0) -#define flush_cache_range(vma, start, end) do { } while (0) -#define flush_cache_page(vma, vmaddr, pfn) do { } while (0) -#define flush_dcache_page(page) do { } while (0) -#define flush_dcache_mmap_lock(mapping) do { } while (0) -#define flush_dcache_mmap_unlock(mapping) do { } while (0) -#define flush_icache_range(start, end) do { } while (0) -#define flush_icache_page(vma, pg) do { } while (0) -#define flush_icache_user_range(vma, pg, adr, len) do { } while (0) -#define flush_cache_vmap(start, end) do { } while (0) -#define flush_cache_vunmap(start, end) do { } while (0) +static inline void flush_cache_all(void) { } +static inline void flush_cache_mm(struct mm_struct *mm) { } +static inline void flush_cache_dup_mm(struct mm_struct *mm) { } +static inline void flush_cache_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) { } +static inline void flush_cache_page(struct vm_area_struct *vma, + unsigned long vmaddr, unsigned long pfn) { } +static inline void flush_dcache_page(struct page *page) { } +static inline void flush_dcache_mmap_lock(struct address_space *mapping) { } +static inline void flush_dcache_mmap_unlock(struct address_space *mapping) { } +static inline void flush_icache_range(unsigned long start, + unsigned long end) { } +static inline void flush_icache_page(struct vm_area_struct *vma, + struct page *page) { } +static inline void flush_icache_user_range(struct vm_area_struct *vma, + struct page *page, + unsigned long addr, + unsigned long len) { } +static inline void flush_cache_vmap(unsigned long start, unsigned long end) { } +static inline void flush_cache_vunmap(unsigned long start, + unsigned long end) { } -#define copy_to_user_page(vma, page, vaddr, dst, src, len) \ - memcpy((dst), (src), (len)) -#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ - memcpy((dst), (src), (len)) +static inline void copy_to_user_page(struct vm_area_struct *vma, + struct page *page, unsigned long vaddr, + void *dst, const void *src, + unsigned long len) +{ + memcpy(dst, src, len); +} + +static inline void copy_from_user_page(struct vm_area_struct *vma, + struct page *page, unsigned long vaddr, + void *dst, const void *src, + unsigned long len) +{ + memcpy(dst, src, len); +} #define PG_non_WB PG_arch_1 PAGEFLAG(NonWB, non_WB) -- cgit From 09b4068a7fe442efc40e9dcbcf5ff37c3338ab15 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 25 Feb 2009 13:18:47 +1100 Subject: md/raid10: Don't skip more than 1 bitmap-chunk at a time during recovery. When doing recovery on a raid10 with a write-intent bitmap, we only need to recovery chunks that are flagged in the bitmap. However if we choose to skip a chunk as it isn't flag, the code currently skips the whole raid10-chunk, thus it might not recovery some blocks that need recovering. This patch fixes it. In case that is confusing, it might help to understand that there is a 'raid10 chunk size' which guides how data is distributed across the devices, and a 'bitmap chunk size' which says how much data corresponds to a single bit in the bitmap. This bug only affects cases where the bitmap chunk size is smaller than the raid10 chunk size. Cc: stable@kernel.org Signed-off-by: NeilBrown --- drivers/md/raid10.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 6736d6dff98..118f89e716e 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -2010,13 +2010,13 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i /* There is nowhere to write, so all non-sync * drives must be failed, so try the next chunk... */ - { - sector_t sec = max_sector - sector_nr; - sectors_skipped += sec; + if (sector_nr + max_sync < max_sector) + max_sector = sector_nr + max_sync; + + sectors_skipped += (max_sector - sector_nr); chunks_skipped ++; sector_nr = max_sector; goto skipped; - } } static int run(mddev_t *mddev) -- cgit From 78200d45cde2a79c0d0ae0407883bb264caa3c18 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 25 Feb 2009 13:18:47 +1100 Subject: md/raid10: Don't call bitmap_cond_end_sync when we are doing recovery. For raid1/4/5/6, resync (fixing inconsistencies between devices) is very similar to recovery (rebuilding a failed device onto a spare). The both walk through the device addresses in order. For raid10 it can be quite different. resync follows the 'array' address, and makes sure all copies are the same. Recover walks through 'device' addresses and recreates each missing block. The 'bitmap_cond_end_sync' function allows the write-intent-bitmap (When present) to be updated to reflect a partially completed resync. It makes assumptions which mean that it does not work correctly for raid10 recovery at all. In particularly, it can cause bitmap-directed recovery of a raid10 to not recovery some of the blocks that need to be recovered. So move the call to bitmap_cond_end_sync into the resync path, rather than being in the common "resync or recovery" path. Cc: stable@kernel.org Signed-off-by: NeilBrown --- drivers/md/raid10.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 118f89e716e..e1feb87afc6 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1749,8 +1749,6 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i if (!go_faster && conf->nr_waiting) msleep_interruptible(1000); - bitmap_cond_end_sync(mddev->bitmap, sector_nr); - /* Again, very different code for resync and recovery. * Both must result in an r10bio with a list of bios that * have bi_end_io, bi_sector, bi_bdev set, @@ -1886,6 +1884,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i /* resync. Schedule a read for every block at this virt offset */ int count = 0; + bitmap_cond_end_sync(mddev->bitmap, sector_nr); + if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, mddev->degraded) && !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { -- cgit From 73d5c38a9536142e062c35997b044e89166e063b Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 25 Feb 2009 13:18:47 +1100 Subject: md: avoid races when stopping resync. There has been a race in raid10 and raid1 for a long time which has only recently started showing up due to a scheduler changed. When a sync_read request finishes, as soon as reschedule_retry is called, another thread can mark the resync request as having completed, so md_do_sync can finish, ->stop can be called, and ->conf can be freed. So using conf after reschedule_retry is not safe. Similarly, when finishing a sync_write, calling md_done_sync must be the last thing we do, as it allows a chain of events which will free conf and other data structures. The first of these requires action in raid10.c The second requires action in raid1.c and raid10.c Cc: stable@kernel.org Signed-off-by: NeilBrown --- drivers/md/raid1.c | 3 ++- drivers/md/raid10.c | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 01e3cffd03b..e2466425d9c 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1237,8 +1237,9 @@ static void end_sync_write(struct bio *bio, int error) update_head_pos(mirror, r1_bio); if (atomic_dec_and_test(&r1_bio->remaining)) { - md_done_sync(mddev, r1_bio->sectors, uptodate); + sector_t s = r1_bio->sectors; put_buf(r1_bio); + md_done_sync(mddev, s, uptodate); } } diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index e1feb87afc6..7301631abe0 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1236,6 +1236,7 @@ static void end_sync_read(struct bio *bio, int error) /* for reconstruct, we always reschedule after a read. * for resync, only after all reads */ + rdev_dec_pending(conf->mirrors[d].rdev, conf->mddev); if (test_bit(R10BIO_IsRecover, &r10_bio->state) || atomic_dec_and_test(&r10_bio->remaining)) { /* we have read all the blocks, @@ -1243,7 +1244,6 @@ static void end_sync_read(struct bio *bio, int error) */ reschedule_retry(r10_bio); } - rdev_dec_pending(conf->mirrors[d].rdev, conf->mddev); } static void end_sync_write(struct bio *bio, int error) @@ -1264,11 +1264,13 @@ static void end_sync_write(struct bio *bio, int error) update_head_pos(i, r10_bio); + rdev_dec_pending(conf->mirrors[d].rdev, mddev); while (atomic_dec_and_test(&r10_bio->remaining)) { if (r10_bio->master_bio == NULL) { /* the primary of several recovery bios */ - md_done_sync(mddev, r10_bio->sectors, 1); + sector_t s = r10_bio->sectors; put_buf(r10_bio); + md_done_sync(mddev, s, 1); break; } else { r10bio_t *r10_bio2 = (r10bio_t *)r10_bio->master_bio; @@ -1276,7 +1278,6 @@ static void end_sync_write(struct bio *bio, int error) r10_bio = r10_bio2; } } - rdev_dec_pending(conf->mirrors[d].rdev, mddev); } /* -- cgit From 7c04d1d97a8d918b7ae2ef478229862b71a65f06 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 23 Feb 2009 15:36:40 -0800 Subject: drm/i915: remove PLL debugging messages These are normal; we walk through different values looking for the right one, so why flood the screen with messages? Signed-off-by: Jesse Barnes Reviewed-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 65b635ce28c..a2834276cb3 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -217,7 +217,7 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type) return false; } -#define INTELPllInvalid(s) do { DRM_DEBUG(s); return false; } while (0) +#define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0) /** * Returns whether the given set of divisors are valid for a given refclk with * the given connectors. -- cgit From 37df96736bfe6f5fd9a141d62946e1083d73e712 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 23 Feb 2009 15:36:42 -0800 Subject: drm/i915: handle bogus VBT panel timing We've seen cases in the wild where the VBT sync data is wrong, so add some code to fix it up in that case, taking care to make sure that the total is greater than the sync end. Signed-off-by: Jesse Barnes Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/intel_bios.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 65be30dccc7..fc28e2bbd54 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -111,6 +111,12 @@ parse_panel_data(struct drm_i915_private *dev_priv, struct bdb_header *bdb) panel_fixed_mode->clock = dvo_timing->clock * 10; panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED; + /* Some VBTs have bogus h/vtotal values */ + if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal) + panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1; + if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal) + panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1; + drm_mode_set_name(panel_fixed_mode); dev_priv->vbt_mode = panel_fixed_mode; -- cgit From c8766ac5933d6ee75e7ce379a1eb5ceb451fcb83 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 23 Feb 2009 08:44:33 -0800 Subject: drm: Fix shifts of EDID vsync offset/width fields. Signed-off-by: Linus Torvalds Reviewed-by: Eric Anholt Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_edid.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 5a4d3244758..e902b1cefc0 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -320,10 +320,10 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, mode->htotal = mode->hdisplay + ((pt->hblank_hi << 8) | pt->hblank_lo); mode->vdisplay = (pt->vactive_hi << 8) | pt->vactive_lo; - mode->vsync_start = mode->vdisplay + ((pt->vsync_offset_hi << 8) | + mode->vsync_start = mode->vdisplay + ((pt->vsync_offset_hi << 4) | pt->vsync_offset_lo); mode->vsync_end = mode->vsync_start + - ((pt->vsync_pulse_width_hi << 8) | + ((pt->vsync_pulse_width_hi << 4) | pt->vsync_pulse_width_lo); mode->vtotal = mode->vdisplay + ((pt->vblank_hi << 8) | pt->vblank_lo); -- cgit From fe56cf45f951b3810313584605c1d8a4f20b33a4 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 23 Feb 2009 15:36:41 -0800 Subject: drm: Fix ordering of bit fields in EDID structure leading huge vsync values. Signed-off-by: Jesse Barnes Reviewed-by: Eric Anholt Signed-off-by: Dave Airlie --- include/drm/drm_edid.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index c707c15f516..ff8d27af478 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -58,10 +58,10 @@ struct detailed_pixel_timing { u8 hsync_pulse_width_lo; u8 vsync_pulse_width_lo:4; u8 vsync_offset_lo:4; - u8 hsync_pulse_width_hi:2; - u8 hsync_offset_hi:2; u8 vsync_pulse_width_hi:2; u8 vsync_offset_hi:2; + u8 hsync_pulse_width_hi:2; + u8 hsync_offset_hi:2; u8 width_mm_lo; u8 height_mm_lo; u8 height_mm_hi:4; -- cgit From 7bec756c74b1a5079d5074144bb77a6b3e7d7783 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 23 Feb 2009 16:09:34 -0800 Subject: drm: disable encoders before re-routing them MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In some cases we may receive a mode config that has a different CRTC<->encoder map that the current configuration. In that case, we need to disable any re-routed encoders before setting the mode, otherwise they may not pick up the new CRTC (if the output types are incompatible for example). Tested-by: Kristian Høgsberg Signed-off-by: Jesse Barnes Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc_helper.c | 76 ++++++++++++++++++++++++++++++++++++--- include/drm/drm_crtc_helper.h | 1 + 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 733028b4d45..1c3a8c55714 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -452,6 +452,59 @@ static void drm_setup_crtcs(struct drm_device *dev) kfree(modes); kfree(enabled); } + +/** + * drm_encoder_crtc_ok - can a given crtc drive a given encoder? + * @encoder: encoder to test + * @crtc: crtc to test + * + * Return false if @encoder can't be driven by @crtc, true otherwise. + */ +static bool drm_encoder_crtc_ok(struct drm_encoder *encoder, + struct drm_crtc *crtc) +{ + struct drm_device *dev; + struct drm_crtc *tmp; + int crtc_mask = 1; + + WARN(!crtc, "checking null crtc?"); + + dev = crtc->dev; + + list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) { + if (tmp == crtc) + break; + crtc_mask <<= 1; + } + + if (encoder->possible_crtcs & crtc_mask) + return true; + return false; +} + +/* + * Check the CRTC we're going to map each output to vs. its current + * CRTC. If they don't match, we have to disable the output and the CRTC + * since the driver will have to re-route things. + */ +static void +drm_crtc_prepare_encoders(struct drm_device *dev) +{ + struct drm_encoder_helper_funcs *encoder_funcs; + struct drm_encoder *encoder; + + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { + encoder_funcs = encoder->helper_private; + /* Disable unused encoders */ + if (encoder->crtc == NULL) + (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); + /* Disable encoders whose CRTC is about to change */ + if (encoder_funcs->get_crtc && + encoder->crtc != (*encoder_funcs->get_crtc)(encoder)) + (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); + } +} + /** * drm_crtc_set_mode - set a mode * @crtc: CRTC to program @@ -547,6 +600,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, encoder_funcs->prepare(encoder); } + drm_crtc_prepare_encoders(dev); + crtc_funcs->prepare(crtc); /* Set up the DPLL and any encoders state that needs to adjust or depend @@ -617,7 +672,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) struct drm_device *dev; struct drm_crtc **save_crtcs, *new_crtc; struct drm_encoder **save_encoders, *new_encoder; - struct drm_framebuffer *old_fb; + struct drm_framebuffer *old_fb = NULL; bool save_enabled; bool mode_changed = false; bool fb_changed = false; @@ -668,9 +723,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) * and then just flip_or_move it */ if (set->crtc->fb != set->fb) { /* If we have no fb then treat it as a full mode set */ - if (set->crtc->fb == NULL) + if (set->crtc->fb == NULL) { + DRM_DEBUG("crtc has no fb, full mode set\n"); mode_changed = true; - else if ((set->fb->bits_per_pixel != + } else if ((set->fb->bits_per_pixel != set->crtc->fb->bits_per_pixel) || set->fb->depth != set->crtc->fb->depth) fb_changed = true; @@ -682,7 +738,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) fb_changed = true; if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) { - DRM_DEBUG("modes are different\n"); + DRM_DEBUG("modes are different, full mode set\n"); drm_mode_debug_printmodeline(&set->crtc->mode); drm_mode_debug_printmodeline(set->mode); mode_changed = true; @@ -708,6 +764,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) } if (new_encoder != connector->encoder) { + DRM_DEBUG("encoder changed, full mode switch\n"); mode_changed = true; connector->encoder = new_encoder; } @@ -734,10 +791,20 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) if (set->connectors[ro] == connector) new_crtc = set->crtc; } + + /* Make sure the new CRTC will work with the encoder */ + if (new_crtc && + !drm_encoder_crtc_ok(connector->encoder, new_crtc)) { + ret = -EINVAL; + goto fail_set_mode; + } if (new_crtc != connector->encoder->crtc) { + DRM_DEBUG("crtc changed, full mode switch\n"); mode_changed = true; connector->encoder->crtc = new_crtc; } + DRM_DEBUG("setting connector %d crtc to %p\n", + connector->base.id, new_crtc); } /* mode_set_base is not a required function */ @@ -781,6 +848,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) fail_set_mode: set->crtc->enabled = save_enabled; + set->crtc->fb = old_fb; count = 0; list_for_each_entry(connector, &dev->mode_config.connector_list, head) { if (!connector->encoder) diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index 0b0d236c215..c7d4b2e606a 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h @@ -76,6 +76,7 @@ struct drm_encoder_helper_funcs { void (*mode_set)(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode); + struct drm_crtc *(*get_crtc)(struct drm_encoder *encoder); /* detect for DAC style encoders */ enum drm_connector_status (*detect)(struct drm_encoder *encoder, struct drm_connector *connector); -- cgit From b3f5e7329df1a508ac58ebe7509fb7a47b9eab6a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 19 Feb 2009 14:48:22 +0000 Subject: drm: Correct unbalanced drm_vblank_put() during mode setting. The first time we install a mode, the vblank will be disabled for a pipe and so drm_vblank_get() in drm_vblank_pre_modeset() will fail. As we unconditionally call drm_vblank_put() afterwards, the vblank reference counter becomes unbalanced. Signed-off-by: Chris Wilson Acked-by: Jesse Barnes Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_irq.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 3795dbc0f50..93e677a481f 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -435,6 +435,8 @@ EXPORT_SYMBOL(drm_vblank_get); */ void drm_vblank_put(struct drm_device *dev, int crtc) { + BUG_ON (atomic_read (&dev->vblank_refcount[crtc]) == 0); + /* Last user schedules interrupt disable */ if (atomic_dec_and_test(&dev->vblank_refcount[crtc])) mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ); @@ -460,8 +462,9 @@ void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) * so that interrupts remain enabled in the interim. */ if (!dev->vblank_inmodeset[crtc]) { - dev->vblank_inmodeset[crtc] = 1; - drm_vblank_get(dev, crtc); + dev->vblank_inmodeset[crtc] = 0x1; + if (drm_vblank_get(dev, crtc) == 0) + dev->vblank_inmodeset[crtc] |= 0x2; } } EXPORT_SYMBOL(drm_vblank_pre_modeset); @@ -473,9 +476,12 @@ void drm_vblank_post_modeset(struct drm_device *dev, int crtc) if (dev->vblank_inmodeset[crtc]) { spin_lock_irqsave(&dev->vbl_lock, irqflags); dev->vblank_disable_allowed = 1; - dev->vblank_inmodeset[crtc] = 0; spin_unlock_irqrestore(&dev->vbl_lock, irqflags); - drm_vblank_put(dev, crtc); + + if (dev->vblank_inmodeset[crtc] & 0x2) + drm_vblank_put(dev, crtc); + + dev->vblank_inmodeset[crtc] = 0; } } EXPORT_SYMBOL(drm_vblank_post_modeset); -- cgit From d61e7380b402a481ab1fa8027068a24918f701c8 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Tue, 24 Feb 2009 20:31:53 -0500 Subject: drm: edid revision 0 is valid edid->revision == 0 should be valid (at least, so the error message indicates. :) and wikipedia seems to indicate that EDID 1.0 existed. We can dump the entire check, since edid->revision is a u8, so it can't ever be less than 0. Marko reports in RH bz#476735 that his monitor claims to be EDID 1.0, and therefore hits the check and is stuck at 800x600 because of it. Reported-by: Marko Ristola Signed-off-by: Kyle McMartin Acked-by: Jesse Barnes Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_edid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index e902b1cefc0..a839a28d8ee 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -125,7 +125,7 @@ static bool edid_is_valid(struct edid *edid) DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version); goto bad; } - if (edid->revision <= 0 || edid->revision > 3) { + if (edid->revision > 3) { DRM_ERROR("EDID has minor version %d, which is not between 0-3\n", edid->revision); goto bad; } -- cgit From dd0910b3c71b253c08111110f0399b924a8d5853 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 25 Feb 2009 14:49:21 +1000 Subject: drm/i915: make hw page ioremap use ioremap_wc However we still have another issue with ioremap_wc not falling back properly or somehow doing something else stupid, this probably needs to be tracked down. Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/i915_dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 2d797ffe813..cc4649577a6 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -811,7 +811,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data, dev_priv->hws_map.flags = 0; dev_priv->hws_map.mtrr = 0; - drm_core_ioremap(&dev_priv->hws_map, dev); + drm_core_ioremap_wc(&dev_priv->hws_map, dev); if (dev_priv->hws_map.handle == NULL) { i915_dma_cleanup(dev); dev_priv->status_gfx_addr = 0; -- cgit From e08fb4f6d1dc95eff5b3fc1d0412bcb5afcae7f2 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 25 Feb 2009 14:52:30 +1000 Subject: drm/i915: convert DRM_ERROR to DRM_DEBUG in phys object pwrite path This snuck in when I wrote phys object support. Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/i915_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 28b726d07a0..85685bfd12d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3548,7 +3548,7 @@ i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, user_data = (char __user *) (uintptr_t) args->data_ptr; obj_addr = obj_priv->phys_obj->handle->vaddr + args->offset; - DRM_ERROR("obj_addr %p, %lld\n", obj_addr, args->size); + DRM_DEBUG("obj_addr %p, %lld\n", obj_addr, args->size); ret = copy_from_user(obj_addr, user_data, args->size); if (ret) return -EFAULT; -- cgit From fef7cc0893146550b286b13c0e6e914556142730 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 24 Feb 2009 23:52:24 -0800 Subject: asix: new device ids This patch adds two new device ids to the asix driver. One comes directly from the asix driver on their web site, the other was reported by Armani Liao as needed for the MSI X320 to get the driver to work properly for it. Reported-by: Armani Liao Signed-off-by: Greg Kroah-Hartman Signed-off-by: David S. Miller --- drivers/net/usb/asix.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index e009481c606..396f821b5ff 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -1451,6 +1451,14 @@ static const struct usb_device_id products [] = { // Cables-to-Go USB Ethernet Adapter USB_DEVICE(0x0b95, 0x772a), .driver_info = (unsigned long) &ax88772_info, +}, { + // ABOCOM for pci + USB_DEVICE(0x14ea, 0xab11), + .driver_info = (unsigned long) &ax88178_info, +}, { + // ASIX 88772a + USB_DEVICE(0x0db0, 0xa877), + .driver_info = (unsigned long) &ax88772_info, }, { }, // END }; -- cgit From 3255aa2eb636a508fc82a73fabbb8aaf2ff23c0f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 25 Feb 2009 08:21:52 +0100 Subject: x86, mm: pass in 'total' to __copy_from_user_*nocache() Impact: cleanup, enable future change Add a 'total bytes copied' parameter to __copy_from_user_*nocache(), and update all the callsites. The parameter is not used yet - architecture code can use it to more intelligently decide whether the copy should be cached or non-temporal. Cc: Salman Qazi Cc: Nick Piggin Cc: Linus Torvalds Signed-off-by: Ingo Molnar --- arch/x86/include/asm/uaccess_32.h | 4 ++-- arch/x86/include/asm/uaccess_64.h | 5 ++--- drivers/gpu/drm/i915/i915_gem.c | 2 +- include/linux/uaccess.h | 4 ++-- mm/filemap.c | 10 ++++++---- mm/filemap_xip.c | 2 +- 6 files changed, 14 insertions(+), 13 deletions(-) diff --git a/arch/x86/include/asm/uaccess_32.h b/arch/x86/include/asm/uaccess_32.h index 5e06259e90e..a0ba6138697 100644 --- a/arch/x86/include/asm/uaccess_32.h +++ b/arch/x86/include/asm/uaccess_32.h @@ -157,7 +157,7 @@ __copy_from_user(void *to, const void __user *from, unsigned long n) } static __always_inline unsigned long __copy_from_user_nocache(void *to, - const void __user *from, unsigned long n) + const void __user *from, unsigned long n, unsigned long total) { might_fault(); if (__builtin_constant_p(n)) { @@ -180,7 +180,7 @@ static __always_inline unsigned long __copy_from_user_nocache(void *to, static __always_inline unsigned long __copy_from_user_inatomic_nocache(void *to, const void __user *from, - unsigned long n) + unsigned long n, unsigned long total) { return __copy_from_user_ll_nocache_nozero(to, from, n); } diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h index 987a2c10fe2..a748253db0c 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h @@ -189,7 +189,7 @@ extern long __copy_user_nocache(void *dst, const void __user *src, unsigned size, int zerorest); static inline int __copy_from_user_nocache(void *dst, const void __user *src, - unsigned size) + unsigned size, unsigned long total) { might_sleep(); /* @@ -205,8 +205,7 @@ static inline int __copy_from_user_nocache(void *dst, const void __user *src, } static inline int __copy_from_user_inatomic_nocache(void *dst, - const void __user *src, - unsigned size) + const void __user *src, unsigned size, unsigned total) { if (likely(size >= PAGE_SIZE)) return __copy_user_nocache(dst, src, size, 0); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 81857665409..6b209db8370 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -215,7 +215,7 @@ fast_user_write(struct io_mapping *mapping, vaddr_atomic = io_mapping_map_atomic_wc(mapping, page_base); unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + page_offset, - user_data, length); + user_data, length, length); io_mapping_unmap_atomic(vaddr_atomic); if (unwritten) return -EFAULT; diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index 6b58367d145..6f3c603b0d6 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h @@ -41,13 +41,13 @@ static inline void pagefault_enable(void) #ifndef ARCH_HAS_NOCACHE_UACCESS static inline unsigned long __copy_from_user_inatomic_nocache(void *to, - const void __user *from, unsigned long n) + const void __user *from, unsigned long n, unsigned long total) { return __copy_from_user_inatomic(to, from, n); } static inline unsigned long __copy_from_user_nocache(void *to, - const void __user *from, unsigned long n) + const void __user *from, unsigned long n, unsigned long total) { return __copy_from_user(to, from, n); } diff --git a/mm/filemap.c b/mm/filemap.c index 23acefe5180..60fd56772cc 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1816,14 +1816,14 @@ EXPORT_SYMBOL(file_remove_suid); static size_t __iovec_copy_from_user_inatomic(char *vaddr, const struct iovec *iov, size_t base, size_t bytes) { - size_t copied = 0, left = 0; + size_t copied = 0, left = 0, total = bytes; while (bytes) { char __user *buf = iov->iov_base + base; int copy = min(bytes, iov->iov_len - base); base = 0; - left = __copy_from_user_inatomic_nocache(vaddr, buf, copy); + left = __copy_from_user_inatomic_nocache(vaddr, buf, copy, total); copied += copy; bytes -= copy; vaddr += copy; @@ -1851,8 +1851,9 @@ size_t iov_iter_copy_from_user_atomic(struct page *page, if (likely(i->nr_segs == 1)) { int left; char __user *buf = i->iov->iov_base + i->iov_offset; + left = __copy_from_user_inatomic_nocache(kaddr + offset, - buf, bytes); + buf, bytes, bytes); copied = bytes - left; } else { copied = __iovec_copy_from_user_inatomic(kaddr + offset, @@ -1880,7 +1881,8 @@ size_t iov_iter_copy_from_user(struct page *page, if (likely(i->nr_segs == 1)) { int left; char __user *buf = i->iov->iov_base + i->iov_offset; - left = __copy_from_user_nocache(kaddr + offset, buf, bytes); + + left = __copy_from_user_nocache(kaddr + offset, buf, bytes, bytes); copied = bytes - left; } else { copied = __iovec_copy_from_user_inatomic(kaddr + offset, diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c index 0c04615651b..bf54f8a2cf1 100644 --- a/mm/filemap_xip.c +++ b/mm/filemap_xip.c @@ -354,7 +354,7 @@ __xip_file_write(struct file *filp, const char __user *buf, break; copied = bytes - - __copy_from_user_nocache(xip_mem + offset, buf, bytes); + __copy_from_user_nocache(xip_mem + offset, buf, bytes, bytes); if (likely(copied > 0)) { status = copied; -- cgit From 95108fa34a83ffd97e0af959e4b28d7c62008781 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 25 Feb 2009 08:22:20 +0100 Subject: x86: usercopy: check for total size when deciding non-temporal cutoff Impact: make more types of copies non-temporal This change makes the following simple fix: 30d697f: x86: fix performance regression in write() syscall A bit more sophisticated: we check the 'total' number of bytes written to decide whether to copy in a cached or a non-temporal way. This will for example cause the tail (modulo 4096 bytes) chunk of a large write() to be non-temporal too - not just the page-sized chunks. Cc: Salman Qazi Cc: Nick Piggin Cc: Linus Torvalds Signed-off-by: Ingo Molnar --- arch/x86/include/asm/uaccess_64.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h index a748253db0c..dcaa0404cf7 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h @@ -198,7 +198,7 @@ static inline int __copy_from_user_nocache(void *dst, const void __user *src, * non-temporal stores here. Smaller writes get handled * via regular __copy_from_user(): */ - if (likely(size >= PAGE_SIZE)) + if (likely(total >= PAGE_SIZE)) return __copy_user_nocache(dst, src, size, 1); else return __copy_from_user(dst, src, size); @@ -207,7 +207,7 @@ static inline int __copy_from_user_nocache(void *dst, const void __user *src, static inline int __copy_from_user_inatomic_nocache(void *dst, const void __user *src, unsigned size, unsigned total) { - if (likely(size >= PAGE_SIZE)) + if (likely(total >= PAGE_SIZE)) return __copy_user_nocache(dst, src, size, 0); else return __copy_from_user_inatomic(dst, src, size); -- cgit From 40823f737e5bd186a1156fb1c28f360260e1e084 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Wed, 25 Feb 2009 11:26:18 +0100 Subject: x86: memtest: reuse test patterns when memtest parameter exceeds number of available patterns Impact: fix unexpected behaviour when pattern number is out of range Current implementation provides 4 patterns for memtest. The code doesn't check whether the memtest parameter value exceeds the maximum pattern number. Instead the memtest code pretends to test with non-existing patterns, e.g. when booting with memtest=10 I've observed the following ... early_memtest: pattern num 10 0000001000 - 0000006000 pattern 0 ... 0000001000 - 0000006000 pattern 1 ... 0000001000 - 0000006000 pattern 2 ... 0000001000 - 0000006000 pattern 3 ... 0000001000 - 0000006000 pattern 4 ... 0000001000 - 0000006000 pattern 5 ... 0000001000 - 0000006000 pattern 6 ... 0000001000 - 0000006000 pattern 7 ... 0000001000 - 0000006000 pattern 8 ... 0000001000 - 0000006000 pattern 9 ... But in fact Linux didn't test anything for patterns > 4 as the default case in memtest() is to leave the function. I suggest to use the memtest parameter as the number of tests to be performed and to re-iterate over all existing patterns. Signed-off-by: Andreas Herrmann Signed-off-by: Ingo Molnar --- arch/x86/mm/memtest.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/x86/mm/memtest.c b/arch/x86/mm/memtest.c index 9cab18b0b85..00b8bdc64c3 100644 --- a/arch/x86/mm/memtest.c +++ b/arch/x86/mm/memtest.c @@ -9,6 +9,8 @@ #include +#define _MAX_MEM_PATTERNS 4 + static void __init memtest(unsigned long start_phys, unsigned long size, unsigned pattern) { @@ -21,6 +23,8 @@ static void __init memtest(unsigned long start_phys, unsigned long size, unsigned long count; unsigned long incr; + pattern = pattern % _MAX_MEM_PATTERNS; + switch (pattern) { case 0: val = 0UL; @@ -110,8 +114,9 @@ void __init early_memtest(unsigned long start, unsigned long end) t_size = end - t_start; printk(KERN_CONT "\n %010llx - %010llx pattern %d", - (unsigned long long)t_start, - (unsigned long long)t_start + t_size, pattern); + (unsigned long long)t_start, + (unsigned long long)t_start + t_size, + pattern % _MAX_MEM_PATTERNS); memtest(t_start, t_size, pattern); -- cgit From 6d74171bf7315257d276aa35400c5a8d6a993f19 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Wed, 25 Feb 2009 11:27:27 +0100 Subject: x86: memtest: introduce array to select memtest patterns Impact: code cleanup Signed-off-by: Andreas Herrmann Signed-off-by: Ingo Molnar --- arch/x86/mm/memtest.c | 65 ++++++++++++++++++--------------------------------- 1 file changed, 23 insertions(+), 42 deletions(-) diff --git a/arch/x86/mm/memtest.c b/arch/x86/mm/memtest.c index 00b8bdc64c3..827f94044cf 100644 --- a/arch/x86/mm/memtest.c +++ b/arch/x86/mm/memtest.c @@ -9,48 +9,25 @@ #include -#define _MAX_MEM_PATTERNS 4 +static u64 patterns[] __initdata = { + 0, + 0xffffffffffffffffULL, + 0x5555555555555555ULL, + 0xaaaaaaaaaaaaaaaaULL, +}; static void __init memtest(unsigned long start_phys, unsigned long size, - unsigned pattern) + u64 pattern) { unsigned long i; - unsigned long *start; + u64 *start; unsigned long start_bad; unsigned long last_bad; - unsigned long val; unsigned long start_phys_aligned; unsigned long count; unsigned long incr; - pattern = pattern % _MAX_MEM_PATTERNS; - - switch (pattern) { - case 0: - val = 0UL; - break; - case 1: - val = -1UL; - break; - case 2: -#ifdef CONFIG_X86_64 - val = 0x5555555555555555UL; -#else - val = 0x55555555UL; -#endif - break; - case 3: -#ifdef CONFIG_X86_64 - val = 0xaaaaaaaaaaaaaaaaUL; -#else - val = 0xaaaaaaaaUL; -#endif - break; - default: - return; - } - - incr = sizeof(unsigned long); + incr = sizeof(pattern); start_phys_aligned = ALIGN(start_phys, incr); count = (size - (start_phys_aligned - start_phys))/incr; start = __va(start_phys_aligned); @@ -58,15 +35,16 @@ static void __init memtest(unsigned long start_phys, unsigned long size, last_bad = 0; for (i = 0; i < count; i++) - start[i] = val; + start[i] = pattern; for (i = 0; i < count; i++, start++, start_phys_aligned += incr) { - if (*start != val) { + if (*start != pattern) { if (start_phys_aligned == last_bad + incr) { last_bad += incr; } else { if (start_bad) { - printk(KERN_CONT "\n %016lx bad mem addr %010lx - %010lx reserved", - val, start_bad, last_bad + incr); + printk(KERN_CONT "\n %016llx bad mem addr %010lx - %010lx reserved", + (unsigned long long) pattern, + start_bad, last_bad + incr); reserve_early(start_bad, last_bad + incr, "BAD RAM"); } start_bad = last_bad = start_phys_aligned; @@ -74,8 +52,9 @@ static void __init memtest(unsigned long start_phys, unsigned long size, } } if (start_bad) { - printk(KERN_CONT "\n %016lx bad mem addr %010lx - %010lx reserved", - val, start_bad, last_bad + incr); + printk(KERN_CONT "\n %016llx bad mem addr %010lx - %010lx reserved", + (unsigned long long) pattern, start_bad, + last_bad + incr); reserve_early(start_bad, last_bad + incr, "BAD RAM"); } } @@ -95,13 +74,16 @@ early_param("memtest", parse_memtest); void __init early_memtest(unsigned long start, unsigned long end) { u64 t_start, t_size; - unsigned pattern; + unsigned int i; + u64 pattern; if (!memtest_pattern) return; printk(KERN_INFO "early_memtest: pattern num %d", memtest_pattern); - for (pattern = 0; pattern < memtest_pattern; pattern++) { + for (i = 0; i < memtest_pattern; i++) { + unsigned int idx = i % ARRAY_SIZE(patterns); + pattern = patterns[idx]; t_start = start; t_size = 0; while (t_start < end) { @@ -115,8 +97,7 @@ void __init early_memtest(unsigned long start, unsigned long end) printk(KERN_CONT "\n %010llx - %010llx pattern %d", (unsigned long long)t_start, - (unsigned long long)t_start + t_size, - pattern % _MAX_MEM_PATTERNS); + (unsigned long long)t_start + t_size, idx); memtest(t_start, t_size, pattern); -- cgit From 7dad169e57eda1f0aa6dc5ac43a898b4b0ced2c7 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Wed, 25 Feb 2009 11:28:07 +0100 Subject: x86: memtest: cleanup memtest function Impact: code cleanup Signed-off-by: Andreas Herrmann Signed-off-by: Ingo Molnar --- arch/x86/mm/memtest.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/arch/x86/mm/memtest.c b/arch/x86/mm/memtest.c index 827f94044cf..01a72d6825b 100644 --- a/arch/x86/mm/memtest.c +++ b/arch/x86/mm/memtest.c @@ -16,6 +16,15 @@ static u64 patterns[] __initdata = { 0xaaaaaaaaaaaaaaaaULL, }; +static void __init reserve_bad_mem(u64 pattern, unsigned long start_bad, + unsigned long end_bad) +{ + printk(KERN_CONT "\n %016llx bad mem addr " + "%010lx - %010lx reserved", + (unsigned long long) pattern, start_bad, end_bad); + reserve_early(start_bad, end_bad, "BAD RAM"); +} + static void __init memtest(unsigned long start_phys, unsigned long size, u64 pattern) { @@ -37,26 +46,18 @@ static void __init memtest(unsigned long start_phys, unsigned long size, for (i = 0; i < count; i++) start[i] = pattern; for (i = 0; i < count; i++, start++, start_phys_aligned += incr) { - if (*start != pattern) { - if (start_phys_aligned == last_bad + incr) { - last_bad += incr; - } else { - if (start_bad) { - printk(KERN_CONT "\n %016llx bad mem addr %010lx - %010lx reserved", - (unsigned long long) pattern, - start_bad, last_bad + incr); - reserve_early(start_bad, last_bad + incr, "BAD RAM"); - } - start_bad = last_bad = start_phys_aligned; - } + if (*start == pattern) + continue; + if (start_phys_aligned == last_bad + incr) { + last_bad += incr; + continue; } + if (start_bad) + reserve_bad_mem(pattern, start_bad, last_bad + incr); + start_bad = last_bad = start_phys_aligned; } - if (start_bad) { - printk(KERN_CONT "\n %016llx bad mem addr %010lx - %010lx reserved", - (unsigned long long) pattern, start_bad, - last_bad + incr); - reserve_early(start_bad, last_bad + incr, "BAD RAM"); - } + if (start_bad) + reserve_bad_mem(pattern, start_bad, last_bad + incr); } /* default is disabled */ -- cgit From 570c9e69aaa84689fb8ed2a3a4af39ca54ba7a47 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Wed, 25 Feb 2009 11:28:58 +0100 Subject: x86: memtest: adapt log messages - print test pattern instead of pattern number, - show pattern as stored in memory, - use proper priority flags, - consistent use of u64 throughout the code Signed-off-by: Andreas Herrmann Signed-off-by: Ingo Molnar --- arch/x86/mm/memtest.c | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/arch/x86/mm/memtest.c b/arch/x86/mm/memtest.c index 01a72d6825b..3232397783a 100644 --- a/arch/x86/mm/memtest.c +++ b/arch/x86/mm/memtest.c @@ -16,25 +16,22 @@ static u64 patterns[] __initdata = { 0xaaaaaaaaaaaaaaaaULL, }; -static void __init reserve_bad_mem(u64 pattern, unsigned long start_bad, - unsigned long end_bad) +static void __init reserve_bad_mem(u64 pattern, u64 start_bad, u64 end_bad) { - printk(KERN_CONT "\n %016llx bad mem addr " - "%010lx - %010lx reserved", - (unsigned long long) pattern, start_bad, end_bad); + printk(KERN_INFO " %016llx bad mem addr %010llx - %010llx reserved\n", + (unsigned long long) pattern, + (unsigned long long) start_bad, + (unsigned long long) end_bad); reserve_early(start_bad, end_bad, "BAD RAM"); } -static void __init memtest(unsigned long start_phys, unsigned long size, - u64 pattern) +static void __init memtest(u64 pattern, u64 start_phys, u64 size) { - unsigned long i; + u64 i, count; u64 *start; - unsigned long start_bad; - unsigned long last_bad; - unsigned long start_phys_aligned; - unsigned long count; - unsigned long incr; + u64 start_bad, last_bad; + u64 start_phys_aligned; + size_t incr; incr = sizeof(pattern); start_phys_aligned = ALIGN(start_phys, incr); @@ -81,7 +78,7 @@ void __init early_memtest(unsigned long start, unsigned long end) if (!memtest_pattern) return; - printk(KERN_INFO "early_memtest: pattern num %d", memtest_pattern); + printk(KERN_INFO "early_memtest: # of tests: %d\n", memtest_pattern); for (i = 0; i < memtest_pattern; i++) { unsigned int idx = i % ARRAY_SIZE(patterns); pattern = patterns[idx]; @@ -96,14 +93,13 @@ void __init early_memtest(unsigned long start, unsigned long end) if (t_start + t_size > end) t_size = end - t_start; - printk(KERN_CONT "\n %010llx - %010llx pattern %d", - (unsigned long long)t_start, - (unsigned long long)t_start + t_size, idx); - - memtest(t_start, t_size, pattern); + printk(KERN_INFO " %010llx - %010llx pattern %016llx\n", + (unsigned long long) t_start, + (unsigned long long) t_start + t_size, + (unsigned long long) cpu_to_be64(pattern)); + memtest(pattern, t_start, t_size); t_start += t_size; } } - printk(KERN_CONT "\n"); } -- cgit From bfb4dc0da45f8fddc76eba7e62919420c7d6dae2 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Wed, 25 Feb 2009 11:30:04 +0100 Subject: x86: memtest: wipe out test pattern from memory Signed-off-by: Andreas Herrmann Signed-off-by: Ingo Molnar --- arch/x86/mm/memtest.c | 56 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/arch/x86/mm/memtest.c b/arch/x86/mm/memtest.c index 3232397783a..9c52ef19e6f 100644 --- a/arch/x86/mm/memtest.c +++ b/arch/x86/mm/memtest.c @@ -57,6 +57,29 @@ static void __init memtest(u64 pattern, u64 start_phys, u64 size) reserve_bad_mem(pattern, start_bad, last_bad + incr); } +static void __init do_one_pass(u64 pattern, u64 start, u64 end) +{ + u64 size = 0; + + while (start < end) { + start = find_e820_area_size(start, &size, 1); + + /* done ? */ + if (start >= end) + break; + if (start + size > end) + size = end - start; + + printk(KERN_INFO " %010llx - %010llx pattern %016llx\n", + (unsigned long long) start, + (unsigned long long) start + size, + (unsigned long long) cpu_to_be64(pattern)); + memtest(pattern, start, size); + + start += size; + } +} + /* default is disabled */ static int memtest_pattern __initdata; @@ -71,35 +94,22 @@ early_param("memtest", parse_memtest); void __init early_memtest(unsigned long start, unsigned long end) { - u64 t_start, t_size; unsigned int i; - u64 pattern; + unsigned int idx = 0; if (!memtest_pattern) return; printk(KERN_INFO "early_memtest: # of tests: %d\n", memtest_pattern); for (i = 0; i < memtest_pattern; i++) { - unsigned int idx = i % ARRAY_SIZE(patterns); - pattern = patterns[idx]; - t_start = start; - t_size = 0; - while (t_start < end) { - t_start = find_e820_area_size(t_start, &t_size, 1); - - /* done ? */ - if (t_start >= end) - break; - if (t_start + t_size > end) - t_size = end - t_start; - - printk(KERN_INFO " %010llx - %010llx pattern %016llx\n", - (unsigned long long) t_start, - (unsigned long long) t_start + t_size, - (unsigned long long) cpu_to_be64(pattern)); - memtest(pattern, t_start, t_size); - - t_start += t_size; - } + idx = i % ARRAY_SIZE(patterns); + do_one_pass(patterns[idx], start, end); + } + + if (idx > 0) { + printk(KERN_INFO "early_memtest: wipe out " + "test pattern from memory\n"); + /* additional test with pattern 0 will do this */ + do_one_pass(0, start, end); } } -- cgit From 9e5f6cf5f755ca5c52071c317421fae19966a658 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Wed, 25 Feb 2009 11:30:45 +0100 Subject: x86: update description for memtest boot parameter Signed-off-by: Andreas Herrmann Signed-off-by: Ingo Molnar --- Documentation/kernel-parameters.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index f6d5d5b9b2b..10c4b8b75c9 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1308,8 +1308,13 @@ and is between 256 and 4096 characters. It is defined in the file memtest= [KNL,X86] Enable memtest Format: - range: 0,4 : pattern number default : 0 + Specifies the number of memtest passes to be + performed. Each pass selects another test + pattern from a given set of patterns. Memtest + fills the memory with this pattern, validates + memory contents and reserves bad memory + regions that are detected. meye.*= [HW] Set MotionEye Camera parameters See Documentation/video4linux/meye.txt. -- cgit From 63823126c221dd721ce7351b596b3b73aa943613 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Wed, 25 Feb 2009 11:31:49 +0100 Subject: x86: memtest: add additional (regular) test patterns Signed-off-by: Andreas Herrmann Signed-off-by: Ingo Molnar --- arch/x86/mm/memtest.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/x86/mm/memtest.c b/arch/x86/mm/memtest.c index 9c52ef19e6f..0bcd7883d03 100644 --- a/arch/x86/mm/memtest.c +++ b/arch/x86/mm/memtest.c @@ -14,6 +14,19 @@ static u64 patterns[] __initdata = { 0xffffffffffffffffULL, 0x5555555555555555ULL, 0xaaaaaaaaaaaaaaaaULL, + 0x1111111111111111ULL, + 0x2222222222222222ULL, + 0x4444444444444444ULL, + 0x8888888888888888ULL, + 0x3333333333333333ULL, + 0x6666666666666666ULL, + 0x9999999999999999ULL, + 0xccccccccccccccccULL, + 0x7777777777777777ULL, + 0xbbbbbbbbbbbbbbbbULL, + 0xddddddddddddddddULL, + 0xeeeeeeeeeeeeeeeeULL, + 0x7a6c7258554e494cULL, /* yeah ;-) */ }; static void __init reserve_bad_mem(u64 pattern, u64 start_bad, u64 end_bad) -- cgit From 6644107d57a8fa82b47e4c55da4d9d91a612f29c Mon Sep 17 00:00:00 2001 From: Venkatesh Pallipadi Date: Tue, 24 Feb 2009 17:35:11 -0800 Subject: gpu/drm, x86, PAT: Handle io_mapping_create_wc() errors in a clean way io_mapping_create_wc can return NULL on error and io_mapping_free() should be called on one of the error-cleanup path. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Suresh Siddha Cc: Dave Airlie Cc: Jesse Barnes Cc: Eric Anholt Cc: Keith Packard Signed-off-by: Ingo Molnar --- drivers/gpu/drm/i915/i915_dma.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 2d797ffe813..6949c2d58f1 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1090,6 +1090,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) dev_priv->mm.gtt_mapping = io_mapping_create_wc(dev->agp->base, dev->agp->agp_info.aper_size * 1024*1024); + if (dev_priv->mm.gtt_mapping == NULL) { + ret = -EIO; + goto out_rmmap; + } + /* Set up a WC MTRR for non-PAT systems. This is more common than * one would think, because the kernel disables PAT on first * generation Core chips because WC PAT gets overridden by a UC @@ -1122,7 +1127,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (!I915_NEED_GFX_HWS(dev)) { ret = i915_init_phys_hws(dev); if (ret != 0) - goto out_rmmap; + goto out_iomapfree; } /* On the 945G/GM, the chipset reports the MSI capability on the @@ -1161,6 +1166,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) return 0; +out_iomapfree: + io_mapping_free(dev_priv->mm.gtt_mapping); out_rmmap: iounmap(dev_priv->regs); free_priv: -- cgit From 7880f7464546842ee14179bef16a6e14381ea638 Mon Sep 17 00:00:00 2001 From: Venkatesh Pallipadi Date: Tue, 24 Feb 2009 17:35:13 -0800 Subject: gpu/drm, x86, PAT: routine to keep identity map in sync Add a function to check and keep identity maps in sync, when changing any memory type. One of the follow on patches will also use this routine. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Suresh Siddha Cc: Dave Airlie Cc: Jesse Barnes Cc: Eric Anholt Cc: Keith Packard Signed-off-by: Ingo Molnar --- arch/x86/include/asm/pat.h | 3 +++ arch/x86/mm/pat.c | 46 +++++++++++++++++++++++++++++----------------- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/arch/x86/include/asm/pat.h b/arch/x86/include/asm/pat.h index b8493b3b989..abb3c29fc9d 100644 --- a/arch/x86/include/asm/pat.h +++ b/arch/x86/include/asm/pat.h @@ -19,4 +19,7 @@ extern int free_memtype(u64 start, u64 end); extern void pat_disable(char *reason); +extern int kernel_map_sync_memtype(u64 base, unsigned long size, + unsigned long flag); + #endif /* _ASM_X86_PAT_H */ diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index aebbf67a79d..399383c6f61 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c @@ -624,6 +624,33 @@ void unmap_devmem(unsigned long pfn, unsigned long size, pgprot_t vma_prot) free_memtype(addr, addr + size); } +/* + * Change the memory type for the physial address range in kernel identity + * mapping space if that range is a part of identity map. + */ +int kernel_map_sync_memtype(u64 base, unsigned long size, unsigned long flags) +{ + unsigned long id_sz; + + if (!pat_enabled || base >= __pa(high_memory)) + return 0; + + id_sz = (__pa(high_memory) < base + size) ? + __pa(high_memory) - base : + size; + + if (ioremap_change_attr((unsigned long)__va(base), id_sz, flags) < 0) { + printk(KERN_INFO + "%s:%d ioremap_change_attr failed %s " + "for %Lx-%Lx\n", + current->comm, current->pid, + cattr_name(flags), + base, (unsigned long long)(base + size)); + return -EINVAL; + } + return 0; +} + /* * Internal interface to reserve a range of physical memory with prot. * Reserved non RAM regions only and after successful reserve_memtype, @@ -633,7 +660,7 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot, int strict_prot) { int is_ram = 0; - int id_sz, ret; + int ret; unsigned long flags; unsigned long want_flags = (pgprot_val(*vma_prot) & _PAGE_CACHE_MASK); @@ -670,23 +697,8 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot, flags); } - /* Need to keep identity mapping in sync */ - if (paddr >= __pa(high_memory)) - return 0; - - id_sz = (__pa(high_memory) < paddr + size) ? - __pa(high_memory) - paddr : - size; - - if (ioremap_change_attr((unsigned long)__va(paddr), id_sz, flags) < 0) { + if (kernel_map_sync_memtype(paddr, size, flags) < 0) { free_memtype(paddr, paddr + size); - printk(KERN_ERR - "%s:%d reserve_pfn_range ioremap_change_attr failed %s " - "for %Lx-%Lx\n", - current->comm, current->pid, - cattr_name(flags), - (unsigned long long)paddr, - (unsigned long long)(paddr + size)); return -EINVAL; } return 0; -- cgit From 4ab0d47d0ab311eb181532c1ecb6d02905685071 Mon Sep 17 00:00:00 2001 From: Venkatesh Pallipadi Date: Tue, 24 Feb 2009 17:35:12 -0800 Subject: gpu/drm, x86, PAT: io_mapping_create_wc and resource_size_t io_mapping_create_wc should take a resource_size_t parameter in place of unsigned long. With unsigned long, there will be no way to map greater than 4GB address in i386/32 bit. On x86, greater than 4GB addresses cannot be mapped on i386 without PAE. Return error for such a case. Patch also adds a structure for io_mapping, that saves the base, size and type on HAVE_ATOMIC_IOMAP archs, that can be used to verify the offset on io_mapping_map calls. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Suresh Siddha Cc: Dave Airlie Cc: Jesse Barnes Cc: Eric Anholt Cc: Keith Packard Signed-off-by: Ingo Molnar --- arch/x86/include/asm/iomap.h | 3 +++ arch/x86/mm/iomap_32.c | 18 +++++++++++++++++ include/linux/io-mapping.h | 46 +++++++++++++++++++++++++++++++++----------- 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/arch/x86/include/asm/iomap.h b/arch/x86/include/asm/iomap.h index c1f06289b14..86af26091d6 100644 --- a/arch/x86/include/asm/iomap.h +++ b/arch/x86/include/asm/iomap.h @@ -23,6 +23,9 @@ #include #include +int +is_io_mapping_possible(resource_size_t base, unsigned long size); + void * iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot); diff --git a/arch/x86/mm/iomap_32.c b/arch/x86/mm/iomap_32.c index ca53224fc56..6c2b1af1692 100644 --- a/arch/x86/mm/iomap_32.c +++ b/arch/x86/mm/iomap_32.c @@ -20,6 +20,24 @@ #include #include +#ifdef CONFIG_X86_PAE +int +is_io_mapping_possible(resource_size_t base, unsigned long size) +{ + return 1; +} +#else +int +is_io_mapping_possible(resource_size_t base, unsigned long size) +{ + /* There is no way to map greater than 1 << 32 address without PAE */ + if (base + size > 0x100000000ULL) + return 0; + + return 1; +} +#endif + /* Map 'pfn' using fixed map 'type' and protections 'prot' */ void * diff --git a/include/linux/io-mapping.h b/include/linux/io-mapping.h index 82df31726a5..cbc2f0cd631 100644 --- a/include/linux/io-mapping.h +++ b/include/linux/io-mapping.h @@ -30,11 +30,14 @@ * See Documentation/io_mapping.txt */ -/* this struct isn't actually defined anywhere */ -struct io_mapping; - #ifdef CONFIG_HAVE_ATOMIC_IOMAP +struct io_mapping { + resource_size_t base; + unsigned long size; + pgprot_t prot; +}; + /* * For small address space machines, mapping large objects * into the kernel virtual space isn't practical. Where @@ -43,23 +46,40 @@ struct io_mapping; */ static inline struct io_mapping * -io_mapping_create_wc(unsigned long base, unsigned long size) +io_mapping_create_wc(resource_size_t base, unsigned long size) { - return (struct io_mapping *) base; + struct io_mapping *iomap; + + if (!is_io_mapping_possible(base, size)) + return NULL; + + iomap = kmalloc(sizeof(*iomap), GFP_KERNEL); + if (!iomap) + return NULL; + + iomap->base = base; + iomap->size = size; + iomap->prot = pgprot_writecombine(__pgprot(__PAGE_KERNEL)); + return iomap; } static inline void io_mapping_free(struct io_mapping *mapping) { + kfree(mapping); } /* Atomic map/unmap */ static inline void * io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset) { - offset += (unsigned long) mapping; - return iomap_atomic_prot_pfn(offset >> PAGE_SHIFT, KM_USER0, - __pgprot(__PAGE_KERNEL_WC)); + resource_size_t phys_addr; + unsigned long pfn; + + BUG_ON(offset >= mapping->size); + phys_addr = mapping->base + offset; + pfn = (unsigned long) (phys_addr >> PAGE_SHIFT); + return iomap_atomic_prot_pfn(pfn, KM_USER0, mapping->prot); } static inline void @@ -71,8 +91,9 @@ io_mapping_unmap_atomic(void *vaddr) static inline void * io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset) { - offset += (unsigned long) mapping; - return ioremap_wc(offset, PAGE_SIZE); + BUG_ON(offset >= mapping->size); + resource_size_t phys_addr = mapping->base + offset; + return ioremap_wc(phys_addr, PAGE_SIZE); } static inline void @@ -83,9 +104,12 @@ io_mapping_unmap(void *vaddr) #else +/* this struct isn't actually defined anywhere */ +struct io_mapping; + /* Create the io_mapping object*/ static inline struct io_mapping * -io_mapping_create_wc(unsigned long base, unsigned long size) +io_mapping_create_wc(resource_size_t base, unsigned long size) { return (struct io_mapping *) ioremap_wc(base, size); } -- cgit From 17581ad812a9abb0182260374ef2e52d4a808a64 Mon Sep 17 00:00:00 2001 From: Venkatesh Pallipadi Date: Tue, 24 Feb 2009 17:35:14 -0800 Subject: gpu/drm, x86, PAT: PAT support for io_mapping_* Make io_mapping_create_wc and io_mapping_free go through PAT to make sure that there are no memory type aliases. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Suresh Siddha Cc: Dave Airlie Cc: Jesse Barnes Cc: Eric Anholt Cc: Keith Packard Signed-off-by: Ingo Molnar --- arch/x86/include/asm/iomap.h | 5 ++++- arch/x86/mm/iomap_32.c | 42 ++++++++++++++++++++++++++++++++++++++++-- include/linux/io-mapping.h | 6 ++++-- 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/arch/x86/include/asm/iomap.h b/arch/x86/include/asm/iomap.h index 86af26091d6..bd46495ff7d 100644 --- a/arch/x86/include/asm/iomap.h +++ b/arch/x86/include/asm/iomap.h @@ -24,7 +24,10 @@ #include int -is_io_mapping_possible(resource_size_t base, unsigned long size); +reserve_io_memtype_wc(u64 base, unsigned long size, pgprot_t *prot); + +void +free_io_memtype(u64 base, unsigned long size); void * iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot); diff --git a/arch/x86/mm/iomap_32.c b/arch/x86/mm/iomap_32.c index 6c2b1af1692..94596f794b1 100644 --- a/arch/x86/mm/iomap_32.c +++ b/arch/x86/mm/iomap_32.c @@ -21,13 +21,13 @@ #include #ifdef CONFIG_X86_PAE -int +static int is_io_mapping_possible(resource_size_t base, unsigned long size) { return 1; } #else -int +static int is_io_mapping_possible(resource_size_t base, unsigned long size) { /* There is no way to map greater than 1 << 32 address without PAE */ @@ -38,6 +38,44 @@ is_io_mapping_possible(resource_size_t base, unsigned long size) } #endif +int +reserve_io_memtype_wc(u64 base, unsigned long size, pgprot_t *prot) +{ + unsigned long ret_flag; + + if (!is_io_mapping_possible(base, size)) + goto out_err; + + if (!pat_enabled) { + *prot = pgprot_noncached(PAGE_KERNEL); + return 0; + } + + if (reserve_memtype(base, base + size, _PAGE_CACHE_WC, &ret_flag)) + goto out_err; + + if (ret_flag == _PAGE_CACHE_WB) + goto out_free; + + if (kernel_map_sync_memtype(base, size, ret_flag)) + goto out_free; + + *prot = __pgprot(__PAGE_KERNEL | ret_flag); + return 0; + +out_free: + free_memtype(base, base + size); +out_err: + return -EINVAL; +} + +void +free_io_memtype(u64 base, unsigned long size) +{ + if (pat_enabled) + free_memtype(base, base + size); +} + /* Map 'pfn' using fixed map 'type' and protections 'prot' */ void * diff --git a/include/linux/io-mapping.h b/include/linux/io-mapping.h index cbc2f0cd631..f1ed66c4378 100644 --- a/include/linux/io-mapping.h +++ b/include/linux/io-mapping.h @@ -49,8 +49,9 @@ static inline struct io_mapping * io_mapping_create_wc(resource_size_t base, unsigned long size) { struct io_mapping *iomap; + pgprot_t prot; - if (!is_io_mapping_possible(base, size)) + if (!reserve_io_memtype_wc(base, size, &prot)) return NULL; iomap = kmalloc(sizeof(*iomap), GFP_KERNEL); @@ -59,13 +60,14 @@ io_mapping_create_wc(resource_size_t base, unsigned long size) iomap->base = base; iomap->size = size; - iomap->prot = pgprot_writecombine(__pgprot(__PAGE_KERNEL)); + iomap->prot = prot; return iomap; } static inline void io_mapping_free(struct io_mapping *mapping) { + free_io_memtype(mapping->base, mapping->size); kfree(mapping); } -- cgit From 0dcec8c27ba44cd11c6e68c46d5fd553818a3837 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 25 Feb 2009 14:07:33 +0100 Subject: alloc_percpu: add align argument to __alloc_percpu, fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Impact: build fix API was changed, but not all usage sites were converted: net/ipv4/route.c: In function ‘ip_rt_init’: net/ipv4/route.c:3379: error: too few arguments to function ‘__alloc_percpu’ Cc: Rusty Russell Cc: Tejun Heo Signed-off-by: Ingo Molnar --- net/ipv4/route.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 97f71153584..bf895401218 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -3376,7 +3376,7 @@ int __init ip_rt_init(void) int rc = 0; #ifdef CONFIG_NET_CLS_ROUTE - ip_rt_acct = __alloc_percpu(256 * sizeof(struct ip_rt_acct)); + ip_rt_acct = __alloc_percpu(256 * sizeof(struct ip_rt_acct), __alignof__(struct ip_rt_acct)); if (!ip_rt_acct) panic("IP: failed to allocate ip_rt_acct\n"); #endif -- cgit From d2b0261506602bd969164879206027b30358ffdf Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 25 Feb 2009 14:36:45 +0100 Subject: alloc_percpu: fix UP build Impact: build fix the !SMP branch had a 'gfp' leftover: include/linux/percpu.h: In function '__alloc_percpu': include/linux/percpu.h:160: error: 'gfp' undeclared (first use in this function) include/linux/percpu.h:160: error: (Each undeclared identifier is reported only once include/linux/percpu.h:160: error: for each function it appears in.) Use GFP_KERNEL like the SMP version does. Cc: Rusty Russell Cc: Tejun Heo Signed-off-by: Ingo Molnar --- include/linux/percpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/percpu.h b/include/linux/percpu.h index 910beb0abea..d8e5a9abbce 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -157,7 +157,7 @@ static inline void *__alloc_percpu(size_t size, size_t align) * percpu sections on SMP for which this path isn't used. */ WARN_ON_ONCE(align > __alignof__(unsigned long long)); - return kzalloc(size, gfp); + return kzalloc(size, GFP_KERNEL); } static inline void free_percpu(void *p) -- cgit From 34754b69a6f87aa6aa2860525a82f12532f83afd Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 25 Feb 2009 16:04:03 +0100 Subject: x86: make vmap yell louder when it is used under irqs_disabled() Signed-off-by: Ingo Molnar --- arch/x86/kernel/alternative.c | 6 +++--- mm/vmalloc.c | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index a84ac7b570e..6907b8e85d5 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -498,12 +498,12 @@ void *text_poke_early(void *addr, const void *opcode, size_t len) */ void *__kprobes text_poke(void *addr, const void *opcode, size_t len) { - unsigned long flags; char *vaddr; int nr_pages = 2; struct page *pages[2]; int i; + might_sleep(); if (!core_kernel_text((unsigned long)addr)) { pages[0] = vmalloc_to_page(addr); pages[1] = vmalloc_to_page(addr + PAGE_SIZE); @@ -517,9 +517,9 @@ void *__kprobes text_poke(void *addr, const void *opcode, size_t len) nr_pages = 1; vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL); BUG_ON(!vaddr); - local_irq_save(flags); + local_irq_disable(); memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len); - local_irq_restore(flags); + local_irq_enable(); vunmap(vaddr); sync_core(); /* Could also do a CLFLUSH here to speed up CPU recovery; but diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 4dd2636d0b9..f83a70167b9 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -1257,6 +1257,7 @@ EXPORT_SYMBOL(vfree); void vunmap(const void *addr) { BUG_ON(in_interrupt()); + might_sleep(); __vunmap(addr, 0); } EXPORT_SYMBOL(vunmap); @@ -1276,6 +1277,8 @@ void *vmap(struct page **pages, unsigned int count, { struct vm_struct *area; + might_sleep(); + if (count > num_physpages) return NULL; -- cgit From 6aa03ab06978e97b3e0720f83280d7841051916b Mon Sep 17 00:00:00 2001 From: Fenghua Yu Date: Wed, 25 Feb 2009 14:06:26 +0900 Subject: Fix iwlan DMA mapping direction When iwlan runs on IOMMU, IOMMU generates a lot of PTE write faults because PTE write bit is not set on some of PTE's. This is because iwlan driver calls DMA mapping with PCI_DMA_TODEVICE which is read only in mapping PTE. But iwlan device actually writes to the mapped page to update its contents. This issue is not exposed in swiotlb. But VT-d hardware can capture this fault and stop the fault transaction. The following patch fixes the issue. Signed-off-by: Fenghua Yu Reviewed-by: Bhavesh Davda Tested-by: Chris Wright Acked-by: Tomas Winkler Signed-off-by: David Woodhouse Signed-off-by: Linus Torvalds --- drivers/net/wireless/iwlwifi/iwl-tx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index b0ee86c6268..ab13ff22a8c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -148,7 +148,7 @@ static void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) pci_unmap_single(dev, pci_unmap_addr(&txq->cmd[index]->meta, mapping), pci_unmap_len(&txq->cmd[index]->meta, len), - PCI_DMA_TODEVICE); + PCI_DMA_BIDIRECTIONAL); /* Unmap chunks, if any. */ for (i = 1; i < num_tbs; i++) { @@ -964,7 +964,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) * within command buffer array. */ txcmd_phys = pci_map_single(priv->pci_dev, out_cmd, sizeof(struct iwl_cmd), - PCI_DMA_TODEVICE); + PCI_DMA_BIDIRECTIONAL); pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys); pci_unmap_len_set(&out_cmd->meta, len, sizeof(struct iwl_cmd)); /* Add buffer containing Tx command and MAC(!) header to TFD's @@ -1115,7 +1115,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) IWL_MAX_SCAN_SIZE : sizeof(struct iwl_cmd); phys_addr = pci_map_single(priv->pci_dev, out_cmd, - len, PCI_DMA_TODEVICE); + len, PCI_DMA_BIDIRECTIONAL); pci_unmap_addr_set(&out_cmd->meta, mapping, phys_addr); pci_unmap_len_set(&out_cmd->meta, len, len); phys_addr += offsetof(struct iwl_cmd, hdr); @@ -1212,7 +1212,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, pci_unmap_single(priv->pci_dev, pci_unmap_addr(&txq->cmd[cmd_idx]->meta, mapping), pci_unmap_len(&txq->cmd[cmd_idx]->meta, len), - PCI_DMA_TODEVICE); + PCI_DMA_BIDIRECTIONAL); for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx; q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { -- cgit From 55d8085671863fe4ee6a17b7814bd38180a44e1d Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 25 Feb 2009 09:42:25 -0800 Subject: xen: disable interrupts early, as start_kernel expects This avoids a lockdep warning from: if (DEBUG_LOCKS_WARN_ON(unlikely(!early_boot_irqs_enabled))) return; in trace_hardirqs_on_caller(); Signed-off-by: Jeremy Fitzhardinge Cc: Mark McLoughlin Cc: Xen-devel Signed-off-by: Ingo Molnar --- arch/x86/xen/enlighten.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index bea215230b2..b58e9633814 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -1672,6 +1672,9 @@ asmlinkage void __init xen_start_kernel(void) possible map and a non-dummy shared_info. */ per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; + local_irq_disable(); + early_boot_irqs_off(); + xen_raw_console_write("mapping kernel into physical memory\n"); pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages); -- cgit From 0af80c04e2f2e45ae09fceb17df8050f828a5c40 Mon Sep 17 00:00:00 2001 From: David Fries Date: Wed, 25 Feb 2009 20:28:21 +0100 Subject: ide: ide.c 'clear' fix, update "ide=nodma" documentation Documentation/kernel-parameters.txt - ide=nodma is no longer valid. drivers/ide/Kconfig - The module is ide-core.ko not ide. drivers/ide/ide.c - It took me a while to figure out what the arguments %d.%d:%d to nodma module parameter ment, so I added a comment to each. - Added a comment to each of the sscanf lines. - There is a bug, if j is 0 it would previously clear all the other bits except the current device, changed in three different places. mask &= (1 << i) should be mask &= ~(1 << i). Signed-off-by: David Fries [bart: s/disk/device/ in ide.c, beautify patch description] Signed-off-by: Bartlomiej Zolnierkiewicz --- Documentation/kernel-parameters.txt | 6 ++++-- drivers/ide/Kconfig | 2 +- drivers/ide/ide.c | 11 ++++++++--- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 319785b6dcb..0ed3234125e 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -868,8 +868,10 @@ and is between 256 and 4096 characters. It is defined in the file icn= [HW,ISDN] Format: [,[,[,]]] - ide= [HW] (E)IDE subsystem - Format: ide=nodma or ide=doubler + ide-core.nodma= [HW] (E)IDE subsystem + Format: =0.0 to prevent dma on hda, =0.1 hdb =1.0 hdc + .vlb_clock .pci_clock .noflush .noprobe .nowerr .cdrom + .chs .ignore_cable are additional options See Documentation/ide/ide.txt. idebus= [HW] (E)IDE subsystem - VLB/PCI bus speed diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 3dad2299d9c..e072903b12f 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -46,7 +46,7 @@ menuconfig IDE SMART parameters from disk drives. To compile this driver as a module, choose M here: the - module will be called ide. + module will be called ide-core.ko. For further information, please read . diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 258805da15c..0920e3b0c96 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -337,6 +337,7 @@ static int ide_set_dev_param_mask(const char *s, struct kernel_param *kp) int a, b, i, j = 1; unsigned int *dev_param_mask = (unsigned int *)kp->arg; + /* controller . device (0 or 1) [ : 1 (set) | 0 (clear) ] */ if (sscanf(s, "%d.%d:%d", &a, &b, &j) != 3 && sscanf(s, "%d.%d", &a, &b) != 2) return -EINVAL; @@ -349,7 +350,7 @@ static int ide_set_dev_param_mask(const char *s, struct kernel_param *kp) if (j) *dev_param_mask |= (1 << i); else - *dev_param_mask &= (1 << i); + *dev_param_mask &= ~(1 << i); return 0; } @@ -392,6 +393,8 @@ static int ide_set_disk_chs(const char *str, struct kernel_param *kp) { int a, b, c = 0, h = 0, s = 0, i, j = 1; + /* controller . device (0 or 1) : Cylinders , Heads , Sectors */ + /* controller . device (0 or 1) : 1 (use CHS) | 0 (ignore CHS) */ if (sscanf(str, "%d.%d:%d,%d,%d", &a, &b, &c, &h, &s) != 5 && sscanf(str, "%d.%d:%d", &a, &b, &j) != 3) return -EINVAL; @@ -407,7 +410,7 @@ static int ide_set_disk_chs(const char *str, struct kernel_param *kp) if (j) ide_disks |= (1 << i); else - ide_disks &= (1 << i); + ide_disks &= ~(1 << i); ide_disks_chs[i].cyl = c; ide_disks_chs[i].head = h; @@ -469,6 +472,8 @@ static int ide_set_ignore_cable(const char *s, struct kernel_param *kp) { int i, j = 1; + /* controller (ignore) */ + /* controller : 1 (ignore) | 0 (use) */ if (sscanf(s, "%d:%d", &i, &j) != 2 && sscanf(s, "%d", &i) != 1) return -EINVAL; @@ -478,7 +483,7 @@ static int ide_set_ignore_cable(const char *s, struct kernel_param *kp) if (j) ide_ignore_cable |= (1 << i); else - ide_ignore_cable &= (1 << i); + ide_ignore_cable &= ~(1 << i); return 0; } -- cgit From 43a12216d3664a9fa6c8ceb398da6ef08fee7ff7 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Wed, 25 Feb 2009 20:28:22 +0100 Subject: amd74xx: device/vendor confusion Device and vendor ids were confused Signed-off-by: Roel Kluin Cc: Andrew Morton Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/amd74xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/amd74xx.c b/drivers/ide/amd74xx.c index 69660a431cd..77267c85996 100644 --- a/drivers/ide/amd74xx.c +++ b/drivers/ide/amd74xx.c @@ -166,7 +166,7 @@ static unsigned int init_chipset_amd74xx(struct pci_dev *dev) * Check for broken FIFO support. */ if (dev->vendor == PCI_VENDOR_ID_AMD && - dev->vendor == PCI_DEVICE_ID_AMD_VIPER_7411) + dev->device == PCI_DEVICE_ID_AMD_VIPER_7411) t &= 0x0f; else t |= 0xf0; -- cgit From f76bee16fc83f58d6c1b088977330f26ed7ae248 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Wed, 25 Feb 2009 20:28:22 +0100 Subject: atiixp: fix missing parentheses Fix missing parentheses so PIO/DMA timings for master device on the second channel are programmed correctly (IOW "8 0 24 16" offset values should be used instead of the current "8 0 16 16"). [ The bug went unnoticed because after PIO/DMA timings get programmed incorrectly for the third device they are overwritten with timings for the fourth device and since BIOS should also program timings for the third device everything should work fine until suspend/resume cycle or user requested transfer mode changes. ] Signed-off-by: Roel Kluin Cc: Sergei Shtylyov Cc: Andrew Morton [bart: update patch description] Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/atiixp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ide/atiixp.c b/drivers/ide/atiixp.c index b2735d28f5c..ecd1e62ca91 100644 --- a/drivers/ide/atiixp.c +++ b/drivers/ide/atiixp.c @@ -52,7 +52,7 @@ static void atiixp_set_pio_mode(ide_drive_t *drive, const u8 pio) { struct pci_dev *dev = to_pci_dev(drive->hwif->dev); unsigned long flags; - int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8; + int timing_shift = (drive->dn ^ 1) * 8; u32 pio_timing_data; u16 pio_mode_data; @@ -85,7 +85,7 @@ static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed) { struct pci_dev *dev = to_pci_dev(drive->hwif->dev); unsigned long flags; - int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8; + int timing_shift = (drive->dn ^ 1) * 8; u32 tmp32; u16 tmp16; u16 udma_ctl = 0; -- cgit From f38344b0a0898d2a8c13581ee61007719e16e1d7 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 25 Feb 2009 20:28:22 +0100 Subject: it821x: remove dead URL Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/it821x.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/ide/it821x.c b/drivers/ide/it821x.c index e1c4f543739..13b8153112e 100644 --- a/drivers/ide/it821x.c +++ b/drivers/ide/it821x.c @@ -5,9 +5,8 @@ * May be copied or modified under the terms of the GNU General Public License * Based in part on the ITE vendor provided SCSI driver. * - * Documentation available from - * http://www.ite.com.tw/pc/IT8212F_V04.pdf - * Some other documents are NDA. + * Documentation: + * Datasheet is freely available, some other documents under NDA. * * The ITE8212 isn't exactly a standard IDE controller. It has two * modes. In pass through mode then it is an IDE controller. In its smart -- cgit From d3dd7107f4d843d0f01d0f77d49a7c5449130577 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 25 Feb 2009 20:28:23 +0100 Subject: ide-cd: document capacity hack Just copy the comment from drivers/scsi/sr.c::sr_done() (from which the capacity hack has been originated). Cc: Borislav Petkov Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 0bfeb0c79d6..690475b834d 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -194,6 +194,14 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive, bio_sectors = max(bio_sectors(failed_command->bio), 4U); sector &= ~(bio_sectors - 1); + /* + * The SCSI specification allows for the value + * returned by READ CAPACITY to be up to 75 2K + * sectors past the last readable block. + * Therefore, if we hit a medium error within the + * last 75 2K sectors, we decrease the saved size + * value. + */ if (sector < get_capacity(info->disk) && drive->probed_capacity - sector < 4 * 75) set_capacity(info->disk, sector); -- cgit From 8fed43684174b68f04d01d1210fd00536af790df Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 25 Feb 2009 20:28:24 +0100 Subject: ide: fix refcounting in device drivers During host driver module removal del_gendisk() results in a final put on drive->gendev and freeing the drive by drive_release_dev(). Convert device drivers from using struct kref to use struct device so device driver's object holds reference on ->gendev and prevents drive from prematurely going away. Also fix ->remove methods to not erroneously drop reference on a host driver by using only put_device() instead of ide*_put(). Reported-by: Stanislaw Gruszka Tested-by: Stanislaw Gruszka Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 27 ++++++++++++++++++--------- drivers/ide/ide-cd.h | 2 +- drivers/ide/ide-gd.c | 26 +++++++++++++++++--------- drivers/ide/ide-gd.h | 2 +- drivers/ide/ide-tape.c | 29 +++++++++++++++++++---------- include/linux/ide.h | 2 +- 6 files changed, 57 insertions(+), 31 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 690475b834d..ddfbea41d29 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -55,7 +55,7 @@ static DEFINE_MUTEX(idecd_ref_mutex); -static void ide_cd_release(struct kref *); +static void ide_cd_release(struct device *); static struct cdrom_info *ide_cd_get(struct gendisk *disk) { @@ -67,7 +67,7 @@ static struct cdrom_info *ide_cd_get(struct gendisk *disk) if (ide_device_get(cd->drive)) cd = NULL; else - kref_get(&cd->kref); + get_device(&cd->dev); } mutex_unlock(&idecd_ref_mutex); @@ -79,7 +79,7 @@ static void ide_cd_put(struct cdrom_info *cd) ide_drive_t *drive = cd->drive; mutex_lock(&idecd_ref_mutex); - kref_put(&cd->kref, ide_cd_release); + put_device(&cd->dev); ide_device_put(drive); mutex_unlock(&idecd_ref_mutex); } @@ -1798,15 +1798,17 @@ static void ide_cd_remove(ide_drive_t *drive) ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); ide_proc_unregister_driver(drive, info->driver); - + device_del(&info->dev); del_gendisk(info->disk); - ide_cd_put(info); + mutex_lock(&idecd_ref_mutex); + put_device(&info->dev); + mutex_unlock(&idecd_ref_mutex); } -static void ide_cd_release(struct kref *kref) +static void ide_cd_release(struct device *dev) { - struct cdrom_info *info = to_ide_drv(kref, cdrom_info); + struct cdrom_info *info = to_ide_drv(dev, cdrom_info); struct cdrom_device_info *devinfo = &info->devinfo; ide_drive_t *drive = info->drive; struct gendisk *g = info->disk; @@ -2005,7 +2007,12 @@ static int ide_cd_probe(ide_drive_t *drive) ide_init_disk(g, drive); - kref_init(&info->kref); + info->dev.parent = &drive->gendev; + info->dev.release = ide_cd_release; + dev_set_name(&info->dev, dev_name(&drive->gendev)); + + if (device_register(&info->dev)) + goto out_free_disk; info->drive = drive; info->driver = &ide_cdrom_driver; @@ -2019,7 +2026,7 @@ static int ide_cd_probe(ide_drive_t *drive) g->driverfs_dev = &drive->gendev; g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE; if (ide_cdrom_setup(drive)) { - ide_cd_release(&info->kref); + put_device(&info->dev); goto failed; } @@ -2029,6 +2036,8 @@ static int ide_cd_probe(ide_drive_t *drive) add_disk(g); return 0; +out_free_disk: + put_disk(g); out_free_cd: kfree(info); failed: diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h index ac40d6cb90a..c878bfcf111 100644 --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h @@ -80,7 +80,7 @@ struct cdrom_info { ide_drive_t *drive; struct ide_driver *driver; struct gendisk *disk; - struct kref kref; + struct device dev; /* Buffer for table of contents. NULL if we haven't allocated a TOC buffer for this device yet. */ diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c index 7857b209c6d..04710941990 100644 --- a/drivers/ide/ide-gd.c +++ b/drivers/ide/ide-gd.c @@ -25,7 +25,7 @@ module_param(debug_mask, ulong, 0644); static DEFINE_MUTEX(ide_disk_ref_mutex); -static void ide_disk_release(struct kref *); +static void ide_disk_release(struct device *); static struct ide_disk_obj *ide_disk_get(struct gendisk *disk) { @@ -37,7 +37,7 @@ static struct ide_disk_obj *ide_disk_get(struct gendisk *disk) if (ide_device_get(idkp->drive)) idkp = NULL; else - kref_get(&idkp->kref); + get_device(&idkp->dev); } mutex_unlock(&ide_disk_ref_mutex); return idkp; @@ -48,7 +48,7 @@ static void ide_disk_put(struct ide_disk_obj *idkp) ide_drive_t *drive = idkp->drive; mutex_lock(&ide_disk_ref_mutex); - kref_put(&idkp->kref, ide_disk_release); + put_device(&idkp->dev); ide_device_put(drive); mutex_unlock(&ide_disk_ref_mutex); } @@ -66,17 +66,18 @@ static void ide_gd_remove(ide_drive_t *drive) struct gendisk *g = idkp->disk; ide_proc_unregister_driver(drive, idkp->driver); - + device_del(&idkp->dev); del_gendisk(g); - drive->disk_ops->flush(drive); - ide_disk_put(idkp); + mutex_lock(&ide_disk_ref_mutex); + put_device(&idkp->dev); + mutex_unlock(&ide_disk_ref_mutex); } -static void ide_disk_release(struct kref *kref) +static void ide_disk_release(struct device *dev) { - struct ide_disk_obj *idkp = to_ide_drv(kref, ide_disk_obj); + struct ide_disk_obj *idkp = to_ide_drv(dev, ide_disk_obj); ide_drive_t *drive = idkp->drive; struct gendisk *g = idkp->disk; @@ -348,7 +349,12 @@ static int ide_gd_probe(ide_drive_t *drive) ide_init_disk(g, drive); - kref_init(&idkp->kref); + idkp->dev.parent = &drive->gendev; + idkp->dev.release = ide_disk_release; + dev_set_name(&idkp->dev, dev_name(&drive->gendev)); + + if (device_register(&idkp->dev)) + goto out_free_disk; idkp->drive = drive; idkp->driver = &ide_gd_driver; @@ -373,6 +379,8 @@ static int ide_gd_probe(ide_drive_t *drive) add_disk(g); return 0; +out_free_disk: + put_disk(g); out_free_idkp: kfree(idkp); failed: diff --git a/drivers/ide/ide-gd.h b/drivers/ide/ide-gd.h index a86779f0756..b604bdd318a 100644 --- a/drivers/ide/ide-gd.h +++ b/drivers/ide/ide-gd.h @@ -17,7 +17,7 @@ struct ide_disk_obj { ide_drive_t *drive; struct ide_driver *driver; struct gendisk *disk; - struct kref kref; + struct device dev; unsigned int openers; /* protected by BKL for now */ /* Last failed packet command */ diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index d7ecd3c7975..bb450a7608c 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -169,7 +169,7 @@ typedef struct ide_tape_obj { ide_drive_t *drive; struct ide_driver *driver; struct gendisk *disk; - struct kref kref; + struct device dev; /* * failed_pc points to the last failed packet command, or contains @@ -267,7 +267,7 @@ static DEFINE_MUTEX(idetape_ref_mutex); static struct class *idetape_sysfs_class; -static void ide_tape_release(struct kref *); +static void ide_tape_release(struct device *); static struct ide_tape_obj *ide_tape_get(struct gendisk *disk) { @@ -279,7 +279,7 @@ static struct ide_tape_obj *ide_tape_get(struct gendisk *disk) if (ide_device_get(tape->drive)) tape = NULL; else - kref_get(&tape->kref); + get_device(&tape->dev); } mutex_unlock(&idetape_ref_mutex); return tape; @@ -290,7 +290,7 @@ static void ide_tape_put(struct ide_tape_obj *tape) ide_drive_t *drive = tape->drive; mutex_lock(&idetape_ref_mutex); - kref_put(&tape->kref, ide_tape_release); + put_device(&tape->dev); ide_device_put(drive); mutex_unlock(&idetape_ref_mutex); } @@ -308,7 +308,7 @@ static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i) mutex_lock(&idetape_ref_mutex); tape = idetape_devs[i]; if (tape) - kref_get(&tape->kref); + get_device(&tape->dev); mutex_unlock(&idetape_ref_mutex); return tape; } @@ -2256,15 +2256,17 @@ static void ide_tape_remove(ide_drive_t *drive) idetape_tape_t *tape = drive->driver_data; ide_proc_unregister_driver(drive, tape->driver); - + device_del(&tape->dev); ide_unregister_region(tape->disk); - ide_tape_put(tape); + mutex_lock(&idetape_ref_mutex); + put_device(&tape->dev); + mutex_unlock(&idetape_ref_mutex); } -static void ide_tape_release(struct kref *kref) +static void ide_tape_release(struct device *dev) { - struct ide_tape_obj *tape = to_ide_drv(kref, ide_tape_obj); + struct ide_tape_obj *tape = to_ide_drv(dev, ide_tape_obj); ide_drive_t *drive = tape->drive; struct gendisk *g = tape->disk; @@ -2407,7 +2409,12 @@ static int ide_tape_probe(ide_drive_t *drive) ide_init_disk(g, drive); - kref_init(&tape->kref); + tape->dev.parent = &drive->gendev; + tape->dev.release = ide_tape_release; + dev_set_name(&tape->dev, dev_name(&drive->gendev)); + + if (device_register(&tape->dev)) + goto out_free_disk; tape->drive = drive; tape->driver = &idetape_driver; @@ -2436,6 +2443,8 @@ static int ide_tape_probe(ide_drive_t *drive) return 0; +out_free_disk: + put_disk(g); out_free_tape: kfree(tape); failed: diff --git a/include/linux/ide.h b/include/linux/ide.h index 194da5a4b0d..fe235b65207 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -663,7 +663,7 @@ typedef struct ide_drive_s ide_drive_t; #define to_ide_device(dev) container_of(dev, ide_drive_t, gendev) #define to_ide_drv(obj, cont_type) \ - container_of(obj, struct cont_type, kref) + container_of(obj, struct cont_type, dev) #define ide_drv_g(disk, cont_type) \ container_of((disk)->private_data, struct cont_type, driver) -- cgit From 6b1ff036d4cde7834ef2f9dbea5747adaaac24e0 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Sat, 14 Feb 2009 04:11:29 -0500 Subject: [IA64] enable setting DMAR on by default The previous commit which introduced the DMAR_DEFAULT_ON setting in drivers/pci/dmar.c neglected to add the ability for ia64 to enable the IOMMU by default. Rectify that mistake, doh! Signed-off-by: Kyle McMartin Signed-off-by: Tony Luck --- arch/ia64/Kconfig | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 4eb45c01249..153e727a6e8 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -638,6 +638,17 @@ config DMAR and include PCI device scope covered by these DMA remapping devices. +config DMAR_DEFAULT_ON + def_bool y + prompt "Enable DMA Remapping Devices by default" + depends on DMAR + help + Selecting this option will enable a DMAR device at boot time if + one is found. If this option is not selected, DMAR support can + be enabled by passing intel_iommu=on to the kernel. It is + recommended you say N here while the DMAR code remains + experimental. + endmenu endif -- cgit From aa2f63c95439a11dfac35c60d9160dcd0189aed3 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Sun, 22 Feb 2009 02:33:28 +0100 Subject: [IA64] Do not go beyond ARRAY_SIZE of unw.hash static struct { ... :114 unsigned short hash[UNW_HASH_SIZE]; ... :2152 for (index = 0; index <= UNW_HASH_SIZE; ++index) { This is a bug, isn't it? s/<=/ Signed-off-by: Tony Luck --- arch/ia64/kernel/unwind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c index 67810b77d99..b6c0e63a0bf 100644 --- a/arch/ia64/kernel/unwind.c +++ b/arch/ia64/kernel/unwind.c @@ -2149,7 +2149,7 @@ unw_remove_unwind_table (void *handle) /* next, remove hash table entries for this table */ - for (index = 0; index <= UNW_HASH_SIZE; ++index) { + for (index = 0; index < UNW_HASH_SIZE; ++index) { tmp = unw.cache + unw.hash[index]; if (unw.hash[index] >= UNW_CACHE_SIZE || tmp->ip < table->start || tmp->ip >= table->end) -- cgit From 5b5923975f07836fc7a5388f9fa5f459828ae4ee Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Sat, 21 Feb 2009 23:40:27 +0100 Subject: [IA64] Don't go beyond iosapic_intr_info's arraysize vi arch/ia64/kernel/iosapic.c +142 static struct iosapic_intr_info { ... } iosapic_intr_info[NR_IRQS]; But at line 510 we have: for (i = 0; i <= NR_IRQS; i++) { s/<=/ Signed-off-by: Tony Luck --- arch/ia64/kernel/iosapic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index 5cfd3d91001..e13125058be 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c @@ -507,7 +507,7 @@ static int iosapic_find_sharable_irq(unsigned long trigger, unsigned long pol) if (trigger == IOSAPIC_EDGE) return -EINVAL; - for (i = 0; i <= NR_IRQS; i++) { + for (i = 0; i < NR_IRQS; i++) { info = &iosapic_intr_info[i]; if (info->trigger == trigger && info->polarity == pol && (info->dmode == IOSAPIC_FIXED || -- cgit From 0b0a0806b0d8635e046bf533225a25903b1cddce Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Tue, 24 Feb 2009 20:51:52 +0000 Subject: shmem: fix shared anonymous accounting Each time I exit Firefox, /proc/meminfo's Committed_AS goes down almost 400 kB: OVERCOMMIT_NEVER would be allowing overcommits it should prohibit. Commit fc8744adc870a8d4366908221508bb113d8b72ee "Stop playing silly games with the VM_ACCOUNT flag" changed shmem_file_setup() to set the shmem file's VM_ACCOUNT flag according to VM_NORESERVE not being set in the vma flags; but did so only _after_ the shmem_acct_size(flags, size) call which is expected to pre-account a shared anonymous object. It's all clearer if we switch shmem.c over to use VM_NORESERVE throughout in place of !VM_ACCOUNT. But I very nearly sent in a patch which mistakenly removed the accounting from tmpfs files: shmem_get_inode()'s memset was good for not setting VM_ACCOUNT, but now it needs to set VM_NORESERVE. Rather than setting that by default, then perhaps clearing it again in shmem_file_setup(), let's pass it as a flag to shmem_get_inode(): that allows us to remove the #ifdef CONFIG_SHMEM from shmem_file_setup(). Signed-off-by: Hugh Dickins Signed-off-by: Linus Torvalds --- mm/shmem.c | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/mm/shmem.c b/mm/shmem.c index 19d566ccdee..4103a239ce8 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -169,13 +169,13 @@ static inline struct shmem_sb_info *SHMEM_SB(struct super_block *sb) */ static inline int shmem_acct_size(unsigned long flags, loff_t size) { - return (flags & VM_ACCOUNT) ? - security_vm_enough_memory_kern(VM_ACCT(size)) : 0; + return (flags & VM_NORESERVE) ? + 0 : security_vm_enough_memory_kern(VM_ACCT(size)); } static inline void shmem_unacct_size(unsigned long flags, loff_t size) { - if (flags & VM_ACCOUNT) + if (!(flags & VM_NORESERVE)) vm_unacct_memory(VM_ACCT(size)); } @@ -187,13 +187,13 @@ static inline void shmem_unacct_size(unsigned long flags, loff_t size) */ static inline int shmem_acct_block(unsigned long flags) { - return (flags & VM_ACCOUNT) ? - 0 : security_vm_enough_memory_kern(VM_ACCT(PAGE_CACHE_SIZE)); + return (flags & VM_NORESERVE) ? + security_vm_enough_memory_kern(VM_ACCT(PAGE_CACHE_SIZE)) : 0; } static inline void shmem_unacct_blocks(unsigned long flags, long pages) { - if (!(flags & VM_ACCOUNT)) + if (flags & VM_NORESERVE) vm_unacct_memory(pages * VM_ACCT(PAGE_CACHE_SIZE)); } @@ -1515,8 +1515,8 @@ static int shmem_mmap(struct file *file, struct vm_area_struct *vma) return 0; } -static struct inode * -shmem_get_inode(struct super_block *sb, int mode, dev_t dev) +static struct inode *shmem_get_inode(struct super_block *sb, int mode, + dev_t dev, unsigned long flags) { struct inode *inode; struct shmem_inode_info *info; @@ -1537,6 +1537,7 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev) info = SHMEM_I(inode); memset(info, 0, (char *)inode - (char *)info); spin_lock_init(&info->lock); + info->flags = flags & VM_NORESERVE; INIT_LIST_HEAD(&info->swaplist); switch (mode & S_IFMT) { @@ -1779,9 +1780,10 @@ static int shmem_statfs(struct dentry *dentry, struct kstatfs *buf) static int shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) { - struct inode *inode = shmem_get_inode(dir->i_sb, mode, dev); + struct inode *inode; int error = -ENOSPC; + inode = shmem_get_inode(dir->i_sb, mode, dev, VM_NORESERVE); if (inode) { error = security_inode_init_security(inode, dir, NULL, NULL, NULL); @@ -1920,7 +1922,7 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s if (len > PAGE_CACHE_SIZE) return -ENAMETOOLONG; - inode = shmem_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0); + inode = shmem_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0, VM_NORESERVE); if (!inode) return -ENOSPC; @@ -2332,7 +2334,7 @@ static int shmem_fill_super(struct super_block *sb, sb->s_flags |= MS_POSIXACL; #endif - inode = shmem_get_inode(sb, S_IFDIR | sbinfo->mode, 0); + inode = shmem_get_inode(sb, S_IFDIR | sbinfo->mode, 0, VM_NORESERVE); if (!inode) goto failed; inode->i_uid = sbinfo->uid; @@ -2574,12 +2576,12 @@ int shmem_unuse(swp_entry_t entry, struct page *page) return 0; } -#define shmem_file_operations ramfs_file_operations -#define shmem_vm_ops generic_file_vm_ops -#define shmem_get_inode ramfs_get_inode -#define shmem_acct_size(a, b) 0 -#define shmem_unacct_size(a, b) do {} while (0) -#define SHMEM_MAX_BYTES LLONG_MAX +#define shmem_vm_ops generic_file_vm_ops +#define shmem_file_operations ramfs_file_operations +#define shmem_get_inode(sb, mode, dev, flags) ramfs_get_inode(sb, mode, dev) +#define shmem_acct_size(flags, size) 0 +#define shmem_unacct_size(flags, size) do {} while (0) +#define SHMEM_MAX_BYTES LLONG_MAX #endif /* CONFIG_SHMEM */ @@ -2589,7 +2591,7 @@ int shmem_unuse(swp_entry_t entry, struct page *page) * shmem_file_setup - get an unlinked file living in tmpfs * @name: name for dentry (to be seen in /proc//maps * @size: size to be set for the file - * @flags: vm_flags + * @flags: VM_NORESERVE suppresses pre-accounting of the entire object size */ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags) { @@ -2623,13 +2625,10 @@ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags) goto put_dentry; error = -ENOSPC; - inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0); + inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0, flags); if (!inode) goto close_file; -#ifdef CONFIG_SHMEM - SHMEM_I(inode)->flags = (flags & VM_NORESERVE) ? 0 : VM_ACCOUNT; -#endif d_instantiate(dentry, inode); inode->i_size = size; inode->i_nlink = 0; /* It is unlinked */ -- cgit From 7ba07d16bd62f931efec1fc8e63bf1aeebfe42a9 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Wed, 11 Feb 2009 13:08:43 -0800 Subject: pata_it821x: resume from hibernation fails with RAID volume Hibernation didn't work for me since I started to use IT8212 controller. I did some debugging (booting with no_console_suspend init=/bin/sh). Found that resume fails (2.6.28) with "serial number mismatch 'some garbage' != 'some other garbage'" and "revalidation failed" messages. That's because the controller firmware fills different serial number in the IDENTIFY every boot. The patch below fixes the resume simply clearing the serial number. The proper fix would be probably to fill in the serial number of the RAID volume instead. I assume that there must be something like that stored on the drives but I don't know where. Fix resume on pata_it821x RAID volume by clearing the serial number in IDENTIFY data, which is otherwise different on each boot. Signed-off-by: Ondrej Zary Acked-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/ata/pata_it821x.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index f1bb2f9fecb..b05b86a912c 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c @@ -557,6 +557,9 @@ static unsigned int it821x_read_id(struct ata_device *adev, id[83] |= 0x4400; /* Word 83 is valid and LBA48 */ id[86] |= 0x0400; /* LBA48 on */ id[ATA_ID_MAJOR_VER] |= 0x1F; + /* Clear the serial number because it's different each boot + which breaks validation on resume */ + memset(&id[ATA_ID_SERNO], 0x20, ATA_ID_SERNO_LEN); } return err_mask; } -- cgit From 6be96ac15e4d913e1f48299db083ada5321803b2 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Thu, 19 Feb 2009 10:38:04 -0500 Subject: sata_mv: fix SoC interrupt breakage For some reason, sata_mv doesn't clear interrupt status during init when it's running on an SoC host adapter. If the bootloader has touched the SATA controller before starting Linux, Linux can end up enabling the SATA interrupt with events pending, which will cause the interrupt to be marked as spurious and then be disabled, which then breaks all further accesses to the controller. This patch makes the SoC path clear interrupt status on init like in the non-SoC case. Signed-off-by: Lennert Buytenhek Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 4ae1a4138b4..7007edd2d45 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -3114,19 +3114,17 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS); } - if (!IS_SOC(hpriv)) { - /* Clear any currently outstanding host interrupt conditions */ - writelfl(0, mmio + hpriv->irq_cause_ofs); + /* Clear any currently outstanding host interrupt conditions */ + writelfl(0, mmio + hpriv->irq_cause_ofs); - /* and unmask interrupt generation for host regs */ - writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs); + /* and unmask interrupt generation for host regs */ + writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs); - /* - * enable only global host interrupts for now. - * The per-port interrupts get done later as ports are set up. - */ - mv_set_main_irq_mask(host, 0, PCI_ERR); - } + /* + * enable only global host interrupts for now. + * The per-port interrupts get done later as ports are set up. + */ + mv_set_main_irq_mask(host, 0, PCI_ERR); done: return rc; } -- cgit From c48052cc36e02fff6a9bb3cf83c4206b9127611f Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 11 Feb 2009 13:08:41 -0800 Subject: [libata] pata_amd: program FIFO With 32bit PIO we can use the posted write buffers, but only for 32bit I/O cycles. This means we must disable the FIFO for ATAPI where a final 16bit cycle may occur. Rework the FIFO logic so that we disable the FIFO then selectively re-enable it when we set the timings on AMD devices. Also fix a case where we scribbled on PCI config 0x41 of Nvidia chips when we shouldn't. Signed-off-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/ata/pata_amd.c | 76 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 59 insertions(+), 17 deletions(-) diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index 63719ab9ea4..115b1cd6dcf 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c @@ -24,7 +24,7 @@ #include #define DRV_NAME "pata_amd" -#define DRV_VERSION "0.3.11" +#define DRV_VERSION "0.4.1" /** * timing_setup - shared timing computation and load @@ -145,6 +145,13 @@ static int amd_pre_reset(struct ata_link *link, unsigned long deadline) return ata_sff_prereset(link, deadline); } +/** + * amd_cable_detect - report cable type + * @ap: port + * + * AMD controller/BIOS setups record the cable type in word 0x42 + */ + static int amd_cable_detect(struct ata_port *ap) { static const u32 bitmask[2] = {0x03, 0x0C}; @@ -157,6 +164,40 @@ static int amd_cable_detect(struct ata_port *ap) return ATA_CBL_PATA40; } +/** + * amd_fifo_setup - set the PIO FIFO for ATA/ATAPI + * @ap: ATA interface + * @adev: ATA device + * + * Set the PCI fifo for this device according to the devices present + * on the bus at this point in time. We need to turn the post write buffer + * off for ATAPI devices as we may need to issue a word sized write to the + * device as the final I/O + */ + +static void amd_fifo_setup(struct ata_port *ap) +{ + struct ata_device *adev; + struct pci_dev *pdev = to_pci_dev(ap->host->dev); + static const u8 fifobit[2] = { 0xC0, 0x30}; + u8 fifo = fifobit[ap->port_no]; + u8 r; + + + ata_for_each_dev(adev, &ap->link, ENABLED) { + if (adev->class == ATA_DEV_ATAPI) + fifo = 0; + } + if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7411) /* FIFO is broken */ + fifo = 0; + + /* On the later chips the read prefetch bits become no-op bits */ + pci_read_config_byte(pdev, 0x41, &r); + r &= ~fifobit[ap->port_no]; + r |= fifo; + pci_write_config_byte(pdev, 0x41, r); +} + /** * amd33_set_piomode - set initial PIO mode data * @ap: ATA interface @@ -167,21 +208,25 @@ static int amd_cable_detect(struct ata_port *ap) static void amd33_set_piomode(struct ata_port *ap, struct ata_device *adev) { + amd_fifo_setup(ap); timing_setup(ap, adev, 0x40, adev->pio_mode, 1); } static void amd66_set_piomode(struct ata_port *ap, struct ata_device *adev) { + amd_fifo_setup(ap); timing_setup(ap, adev, 0x40, adev->pio_mode, 2); } static void amd100_set_piomode(struct ata_port *ap, struct ata_device *adev) { + amd_fifo_setup(ap); timing_setup(ap, adev, 0x40, adev->pio_mode, 3); } static void amd133_set_piomode(struct ata_port *ap, struct ata_device *adev) { + amd_fifo_setup(ap); timing_setup(ap, adev, 0x40, adev->pio_mode, 4); } @@ -397,6 +442,16 @@ static struct ata_port_operations nv133_port_ops = { .set_dmamode = nv133_set_dmamode, }; +static void amd_clear_fifo(struct pci_dev *pdev) +{ + u8 fifo; + /* Disable the FIFO, the FIFO logic will re-enable it as + appropriate */ + pci_read_config_byte(pdev, 0x41, &fifo); + fifo &= 0x0F; + pci_write_config_byte(pdev, 0x41, fifo); +} + static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { static const struct ata_port_info info[10] = { @@ -503,14 +558,8 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) if (type < 3) ata_pci_bmdma_clear_simplex(pdev); - - /* Check for AMD7411 */ - if (type == 3) - /* FIFO is broken */ - pci_write_config_byte(pdev, 0x41, fifo & 0x0F); - else - pci_write_config_byte(pdev, 0x41, fifo | 0xF0); - + if (pdev->vendor == PCI_VENDOR_ID_AMD) + amd_clear_fifo(pdev); /* Cable detection on Nvidia chips doesn't work too well, * cache BIOS programmed UDMA mode. */ @@ -536,18 +585,11 @@ static int amd_reinit_one(struct pci_dev *pdev) return rc; if (pdev->vendor == PCI_VENDOR_ID_AMD) { - u8 fifo; - pci_read_config_byte(pdev, 0x41, &fifo); - if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7411) - /* FIFO is broken */ - pci_write_config_byte(pdev, 0x41, fifo & 0x0F); - else - pci_write_config_byte(pdev, 0x41, fifo | 0xF0); + amd_clear_fifo(pdev); if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7409 || pdev->device == PCI_DEVICE_ID_AMD_COBRA_7401) ata_pci_bmdma_clear_simplex(pdev); } - ata_host_resume(host); return 0; } -- cgit From c55af1f5abf606118b32e3ce9c3b1bbce5236e7e Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 11 Feb 2009 13:08:42 -0800 Subject: [libata] pata_legacy: for VLB 32bit PIO don't try tricks with slop These devices are generally used with ATA anyway and it seems that some ATAPI will need us to issue the right number of words. Therefore as we can't switch mid burst on VLB devices we should only use 32bit I/O for suitable block sizes. Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/ata/pata_legacy.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index 6c1d778b63a..e3bc1b43628 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c @@ -283,9 +283,10 @@ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev) static unsigned int pdc_data_xfer_vlb(struct ata_device *dev, unsigned char *buf, unsigned int buflen, int rw) { - if (ata_id_has_dword_io(dev->id)) { + int slop = buflen & 3; + /* 32bit I/O capable *and* we need to write a whole number of dwords */ + if (ata_id_has_dword_io(dev->id) && (slop == 0 || slop == 3)) { struct ata_port *ap = dev->link->ap; - int slop = buflen & 3; unsigned long flags; local_irq_save(flags); @@ -735,7 +736,7 @@ static unsigned int vlb32_data_xfer(struct ata_device *adev, unsigned char *buf, struct ata_port *ap = adev->link->ap; int slop = buflen & 3; - if (ata_id_has_dword_io(adev->id)) { + if (ata_id_has_dword_io(adev->id) && (slop == 0 || slop == 3)) { if (rw == WRITE) iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); else -- cgit From e317603694bfd17b28a40de9d65e1a4ec12f816e Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 26 Feb 2009 10:54:17 +0900 Subject: percpu: fix too low alignment restriction on UP UP __alloc_percpu() triggered WARN_ON_ONCE() if the requested alignment is larger than that of unsigned long long, which is too small for all the cacheline aligned allocations. Bump it up to SMP_CACHE_BYTES which kmalloc allocations generally guarantee. Signed-off-by: Tejun Heo Reported-by: Ingo Molnar --- include/linux/percpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/percpu.h b/include/linux/percpu.h index d8e5a9abbce..545b068bcb7 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -156,7 +156,7 @@ static inline void *__alloc_percpu(size_t size, size_t align) * on it. Larger alignment should only be used for module * percpu sections on SMP for which this path isn't used. */ - WARN_ON_ONCE(align > __alignof__(unsigned long long)); + WARN_ON_ONCE(align > SMP_CACHE_BYTES); return kzalloc(size, GFP_KERNEL); } -- cgit From 13093cb0e59053bf97910de3a24f07cdff71c62c Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 26 Feb 2009 03:16:47 +0100 Subject: gpu/drm, x86, PAT: PAT support for io_mapping_*, export symbols for modules Impact: build fix ERROR: "reserve_io_memtype_wc" [drivers/gpu/drm/i915/i915.ko] undefined! ERROR: "free_io_memtype" [drivers/gpu/drm/i915/i915.ko] undefined! Signed-off-by: Ingo Molnar --- arch/x86/mm/iomap_32.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/mm/iomap_32.c b/arch/x86/mm/iomap_32.c index 94596f794b1..d5e28424622 100644 --- a/arch/x86/mm/iomap_32.c +++ b/arch/x86/mm/iomap_32.c @@ -68,6 +68,7 @@ out_free: out_err: return -EINVAL; } +EXPORT_SYMBOL_GPL(reserve_io_memtype_wc); void free_io_memtype(u64 base, unsigned long size) @@ -75,6 +76,7 @@ free_io_memtype(u64 base, unsigned long size) if (pat_enabled) free_memtype(base, base + size); } +EXPORT_SYMBOL_GPL(free_io_memtype); /* Map 'pfn' using fixed map 'type' and protections 'prot' */ -- cgit From 49f297f8df9adb797334155470ea9ca68bdb041e Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Thu, 19 Feb 2009 18:52:20 +0000 Subject: powerpc: Fix load/store float double alignment handler When we introduced VSX, we changed the way FPRs are stored in the thread_struct. Unfortunately we missed the load/store float double alignment handler code when updating how we access FPRs in the thread_struct. Below fixes this and merges the little/big endian case. Signed-off-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/align.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index ada06924a42..73cb6a3229a 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c @@ -367,27 +367,24 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr, static int emulate_fp_pair(unsigned char __user *addr, unsigned int reg, unsigned int flags) { - char *ptr = (char *) ¤t->thread.TS_FPR(reg); - int i, ret; + char *ptr0 = (char *) ¤t->thread.TS_FPR(reg); + char *ptr1 = (char *) ¤t->thread.TS_FPR(reg+1); + int i, ret, sw = 0; if (!(flags & F)) return 0; if (reg & 1) return 0; /* invalid form: FRS/FRT must be even */ - if (!(flags & SW)) { - /* not byte-swapped - easy */ - if (!(flags & ST)) - ret = __copy_from_user(ptr, addr, 16); - else - ret = __copy_to_user(addr, ptr, 16); - } else { - /* each FPR value is byte-swapped separately */ - ret = 0; - for (i = 0; i < 16; ++i) { - if (!(flags & ST)) - ret |= __get_user(ptr[i^7], addr + i); - else - ret |= __put_user(ptr[i^7], addr + i); + if (flags & SW) + sw = 7; + ret = 0; + for (i = 0; i < 8; ++i) { + if (!(flags & ST)) { + ret |= __get_user(ptr0[i^sw], addr + i); + ret |= __get_user(ptr1[i^sw], addr + i + 8); + } else { + ret |= __put_user(ptr0[i^sw], addr + i); + ret |= __put_user(ptr1[i^sw], addr + i + 8); } } if (ret) -- cgit From e423b9ecd6aa434ce9ba72a21fdc61079e620e0a Mon Sep 17 00:00:00 2001 From: Mark Nelson Date: Wed, 25 Feb 2009 13:26:48 +0000 Subject: powerpc: Fix 64bit memcpy() regression This fixes a regression introduced by commit 25d6e2d7c58ddc4a3b614fc5381591c0cfe66556 ("powerpc: Update 64bit memcpy() using CPU_FTR_UNALIGNED_LD_STD"). This commit allowed CPUs that have the CPU_FTR_UNALIGNED_LD_STD CPU feature bit present to do the memcpy() with unaligned load doubles. But, along with this came a bug where our final load double would read bytes beyond a page boundary and into the next (unmapped) page. This was caught by enabling CONFIG_DEBUG_PAGEALLOC, The fix was to read only the number of bytes that we need to store rather than reading a full 8-byte doubleword and storing only a portion of that. In order to minimise the amount of existing code touched we use the original do_tail for the src_unaligned case. Below is an example of the regression, as reported by Sachin Sant: Unable to handle kernel paging request for data at address 0xc00000003f380000 Faulting instruction address: 0xc000000000039574 cpu 0x1: Vector: 300 (Data Access) at [c00000003baf3020] pc: c000000000039574: .memcpy+0x74/0x244 lr: d00000000244916c: .ext3_xattr_get+0x288/0x2f4 [ext3] sp: c00000003baf32a0 msr: 8000000000009032 dar: c00000003f380000 dsisr: 40000000 current = 0xc00000003e54b010 paca = 0xc000000000a53680 pid = 1840, comm = readahead enter ? for help [link register ] d00000000244916c .ext3_xattr_get+0x288/0x2f4 [ext3] [c00000003baf32a0] d000000002449104 .ext3_xattr_get+0x220/0x2f4 [ext3] (unreliab le) [c00000003baf3390] d00000000244a6e8 .ext3_xattr_security_get+0x40/0x5c [ext3] [c00000003baf3400] c000000000148154 .generic_getxattr+0x74/0x9c [c00000003baf34a0] c000000000333400 .inode_doinit_with_dentry+0x1c4/0x678 [c00000003baf3560] c00000000032c6b0 .security_d_instantiate+0x50/0x68 [c00000003baf35e0] c00000000013c818 .d_instantiate+0x78/0x9c [c00000003baf3680] c00000000013ced0 .d_splice_alias+0xf0/0x120 [c00000003baf3720] d00000000243e05c .ext3_lookup+0xec/0x134 [ext3] [c00000003baf37c0] c000000000131e74 .do_lookup+0x110/0x260 [c00000003baf3880] c000000000134ed0 .__link_path_walk+0xa98/0x1010 [c00000003baf3970] c0000000001354a0 .path_walk+0x58/0xc4 [c00000003baf3a20] c000000000135720 .do_path_lookup+0x138/0x1e4 [c00000003baf3ad0] c00000000013645c .path_lookup_open+0x6c/0xc8 [c00000003baf3b70] c000000000136780 .do_filp_open+0xcc/0x874 [c00000003baf3d10] c0000000001251e0 .do_sys_open+0x80/0x140 [c00000003baf3dc0] c00000000016aaec .compat_sys_open+0x24/0x38 [c00000003baf3e30] c00000000000855c syscall_exit+0x0/0x40 Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/lib/memcpy_64.S | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/lib/memcpy_64.S b/arch/powerpc/lib/memcpy_64.S index fe2d34e5332..e178922b2c2 100644 --- a/arch/powerpc/lib/memcpy_64.S +++ b/arch/powerpc/lib/memcpy_64.S @@ -53,18 +53,19 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) 3: std r8,8(r3) beq 3f addi r3,r3,16 - ld r9,8(r4) .Ldo_tail: bf cr7*4+1,1f - rotldi r9,r9,32 + lwz r9,8(r4) + addi r4,r4,4 stw r9,0(r3) addi r3,r3,4 1: bf cr7*4+2,2f - rotldi r9,r9,16 + lhz r9,8(r4) + addi r4,r4,2 sth r9,0(r3) addi r3,r3,2 2: bf cr7*4+3,3f - rotldi r9,r9,8 + lbz r9,8(r4) stb r9,0(r3) 3: ld r3,48(r1) /* return dest pointer */ blr @@ -133,11 +134,24 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) cmpwi cr1,r5,8 addi r3,r3,32 sld r9,r9,r10 - ble cr1,.Ldo_tail + ble cr1,6f ld r0,8(r4) srd r7,r0,r11 or r9,r7,r9 - b .Ldo_tail +6: + bf cr7*4+1,1f + rotldi r9,r9,32 + stw r9,0(r3) + addi r3,r3,4 +1: bf cr7*4+2,2f + rotldi r9,r9,16 + sth r9,0(r3) + addi r3,r3,2 +2: bf cr7*4+3,3f + rotldi r9,r9,8 + stb r9,0(r3) +3: ld r3,48(r1) /* return dest pointer */ + blr .Ldst_unaligned: PPC_MTOCRF 0x01,r6 # put #bytes to 8B bdry into cr7 -- cgit From f72b728bf100f276628e378e1fe6c6acd5d09401 Mon Sep 17 00:00:00 2001 From: Mark Nelson Date: Wed, 25 Feb 2009 13:46:24 +0000 Subject: powerpc: Fix 64bit __copy_tofrom_user() regression This fixes a regression introduced by commit a4e22f02f5b6518c1484faea1f88d81802b9feac ("powerpc: Update 64bit __copy_tofrom_user() using CPU_FTR_UNALIGNED_LD_STD"). The same bug that existed in the 64bit memcpy() also exists here so fix it here too. The fix is the same as that applied to memcpy() with the addition of fixes for the exception handling code required for __copy_tofrom_user(). This stops us reading beyond the end of the source region we were told to copy. Signed-off-by: Mark Nelson Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/lib/copyuser_64.S | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/lib/copyuser_64.S b/arch/powerpc/lib/copyuser_64.S index 70693a5c12a..693b14a778f 100644 --- a/arch/powerpc/lib/copyuser_64.S +++ b/arch/powerpc/lib/copyuser_64.S @@ -62,18 +62,19 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) 72: std r8,8(r3) beq+ 3f addi r3,r3,16 -23: ld r9,8(r4) .Ldo_tail: bf cr7*4+1,1f - rotldi r9,r9,32 +23: lwz r9,8(r4) + addi r4,r4,4 73: stw r9,0(r3) addi r3,r3,4 1: bf cr7*4+2,2f - rotldi r9,r9,16 +44: lhz r9,8(r4) + addi r4,r4,2 74: sth r9,0(r3) addi r3,r3,2 2: bf cr7*4+3,3f - rotldi r9,r9,8 +45: lbz r9,8(r4) 75: stb r9,0(r3) 3: li r3,0 blr @@ -141,11 +142,24 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) 6: cmpwi cr1,r5,8 addi r3,r3,32 sld r9,r9,r10 - ble cr1,.Ldo_tail + ble cr1,7f 34: ld r0,8(r4) srd r7,r0,r11 or r9,r7,r9 - b .Ldo_tail +7: + bf cr7*4+1,1f + rotldi r9,r9,32 +94: stw r9,0(r3) + addi r3,r3,4 +1: bf cr7*4+2,2f + rotldi r9,r9,16 +95: sth r9,0(r3) + addi r3,r3,2 +2: bf cr7*4+3,3f + rotldi r9,r9,8 +96: stb r9,0(r3) +3: li r3,0 + blr .Ldst_unaligned: PPC_MTOCRF 0x01,r6 /* put #bytes to 8B bdry into cr7 */ @@ -218,7 +232,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) 121: 132: addi r3,r3,8 -123: 134: 135: 138: @@ -226,6 +239,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) 140: 141: 142: +123: +144: +145: /* * here we have had a fault on a load and r3 points to the first @@ -309,6 +325,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) 187: 188: 189: +194: +195: +196: 1: ld r6,-24(r1) ld r5,-8(r1) @@ -329,7 +348,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) .llong 72b,172b .llong 23b,123b .llong 73b,173b + .llong 44b,144b .llong 74b,174b + .llong 45b,145b .llong 75b,175b .llong 24b,124b .llong 25b,125b @@ -347,6 +368,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) .llong 79b,179b .llong 80b,180b .llong 34b,134b + .llong 94b,194b + .llong 95b,195b + .llong 96b,196b .llong 35b,135b .llong 81b,181b .llong 36b,136b -- cgit From a682604838763981613e42015cd0e39f2989d6bb Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Wed, 25 Feb 2009 18:03:42 -0800 Subject: rcu: Teach RCU that idle task is not quiscent state at boot This patch fixes a bug located by Vegard Nossum with the aid of kmemcheck, updated based on review comments from Nick Piggin, Ingo Molnar, and Andrew Morton. And cleans up the variable-name and function-name language. ;-) The boot CPU runs in the context of its idle thread during boot-up. During this time, idle_cpu(0) will always return nonzero, which will fool Classic and Hierarchical RCU into deciding that a large chunk of the boot-up sequence is a big long quiescent state. This in turn causes RCU to prematurely end grace periods during this time. This patch changes the rcutree.c and rcuclassic.c rcu_check_callbacks() function to ignore the idle task as a quiescent state until the system has started up the scheduler in rest_init(), introducing a new non-API function rcu_idle_now_means_idle() to inform RCU of this transition. RCU maintains an internal rcu_idle_cpu_truthful variable to track this state, which is then used by rcu_check_callback() to determine if it should believe idle_cpu(). Because this patch has the effect of disallowing RCU grace periods during long stretches of the boot-up sequence, this patch also introduces Josh Triplett's UP-only optimization that makes synchronize_rcu() be a no-op if num_online_cpus() returns 1. This allows boot-time code that calls synchronize_rcu() to proceed normally. Note, however, that RCU callbacks registered by call_rcu() will likely queue up until later in the boot sequence. Although rcuclassic and rcutree can also use this same optimization after boot completes, rcupreempt must restrict its use of this optimization to the portion of the boot sequence before the scheduler starts up, given that an rcupreempt RCU read-side critical section may be preeempted. In addition, this patch takes Nick Piggin's suggestion to make the system_state global variable be __read_mostly. Changes since v4: o Changes the name of the introduced function and variable to be less emotional. ;-) Changes since v3: o WARN_ON(nr_context_switches() > 0) to verify that RCU switches out of boot-time mode before the first context switch, as suggested by Nick Piggin. Changes since v2: o Created rcu_blocking_is_gp() internal-to-RCU API that determines whether a call to synchronize_rcu() is itself a grace period. o The definition of rcu_blocking_is_gp() for rcuclassic and rcutree checks to see if but a single CPU is online. o The definition of rcu_blocking_is_gp() for rcupreempt checks to see both if but a single CPU is online and if the system is still in early boot. This allows rcupreempt to again work correctly if running on a single CPU after booting is complete. o Added check to rcupreempt's synchronize_sched() for there being but one online CPU. Tested all three variants both SMP and !SMP, booted fine, passed a short rcutorture test on both x86 and Power. Located-by: Vegard Nossum Tested-by: Vegard Nossum Tested-by: Paul E. McKenney Signed-off-by: Paul E. McKenney Signed-off-by: Ingo Molnar --- include/linux/rcuclassic.h | 6 ++++++ include/linux/rcupdate.h | 4 ++++ include/linux/rcupreempt.h | 15 +++++++++++++++ include/linux/rcutree.h | 6 ++++++ init/main.c | 3 ++- kernel/rcuclassic.c | 4 ++-- kernel/rcupdate.c | 12 ++++++++++++ kernel/rcupreempt.c | 3 +++ kernel/rcutree.c | 4 ++-- 9 files changed, 52 insertions(+), 5 deletions(-) diff --git a/include/linux/rcuclassic.h b/include/linux/rcuclassic.h index f3f697df1d7..80044a4f3ab 100644 --- a/include/linux/rcuclassic.h +++ b/include/linux/rcuclassic.h @@ -181,4 +181,10 @@ extern long rcu_batches_completed_bh(void); #define rcu_enter_nohz() do { } while (0) #define rcu_exit_nohz() do { } while (0) +/* A context switch is a grace period for rcuclassic. */ +static inline int rcu_blocking_is_gp(void) +{ + return num_online_cpus() == 1; +} + #endif /* __LINUX_RCUCLASSIC_H */ diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 921340a7b71..528343e6da5 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -52,6 +52,9 @@ struct rcu_head { void (*func)(struct rcu_head *head); }; +/* Internal to kernel, but needed by rcupreempt.h. */ +extern int rcu_scheduler_active; + #if defined(CONFIG_CLASSIC_RCU) #include #elif defined(CONFIG_TREE_RCU) @@ -265,6 +268,7 @@ extern void rcu_barrier_sched(void); /* Internal to kernel */ extern void rcu_init(void); +extern void rcu_scheduler_starting(void); extern int rcu_needs_cpu(int cpu); #endif /* __LINUX_RCUPDATE_H */ diff --git a/include/linux/rcupreempt.h b/include/linux/rcupreempt.h index 3e05c09b54a..74304b4538d 100644 --- a/include/linux/rcupreempt.h +++ b/include/linux/rcupreempt.h @@ -142,4 +142,19 @@ static inline void rcu_exit_nohz(void) #define rcu_exit_nohz() do { } while (0) #endif /* CONFIG_NO_HZ */ +/* + * A context switch is a grace period for rcupreempt synchronize_rcu() + * only during early boot, before the scheduler has been initialized. + * So, how the heck do we get a context switch? Well, if the caller + * invokes synchronize_rcu(), they are willing to accept a context + * switch, so we simply pretend that one happened. + * + * After boot, there might be a blocked or preempted task in an RCU + * read-side critical section, so we cannot then take the fastpath. + */ +static inline int rcu_blocking_is_gp(void) +{ + return num_online_cpus() == 1 && !rcu_scheduler_active; +} + #endif /* __LINUX_RCUPREEMPT_H */ diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h index d4368b7975c..a722fb67bb2 100644 --- a/include/linux/rcutree.h +++ b/include/linux/rcutree.h @@ -326,4 +326,10 @@ static inline void rcu_exit_nohz(void) } #endif /* CONFIG_NO_HZ */ +/* A context switch is a grace period for rcutree. */ +static inline int rcu_blocking_is_gp(void) +{ + return num_online_cpus() == 1; +} + #endif /* __LINUX_RCUTREE_H */ diff --git a/init/main.c b/init/main.c index 844209453c0..83697e160b3 100644 --- a/init/main.c +++ b/init/main.c @@ -97,7 +97,7 @@ static inline void mark_rodata_ro(void) { } extern void tc_init(void); #endif -enum system_states system_state; +enum system_states system_state __read_mostly; EXPORT_SYMBOL(system_state); /* @@ -463,6 +463,7 @@ static noinline void __init_refok rest_init(void) * at least once to get things moving: */ init_idle_bootup_task(current); + rcu_scheduler_starting(); preempt_enable_no_resched(); schedule(); preempt_disable(); diff --git a/kernel/rcuclassic.c b/kernel/rcuclassic.c index bd5a9003497..654c640a6b9 100644 --- a/kernel/rcuclassic.c +++ b/kernel/rcuclassic.c @@ -679,8 +679,8 @@ int rcu_needs_cpu(int cpu) void rcu_check_callbacks(int cpu, int user) { if (user || - (idle_cpu(cpu) && !in_softirq() && - hardirq_count() <= (1 << HARDIRQ_SHIFT))) { + (idle_cpu(cpu) && rcu_scheduler_active && + !in_softirq() && hardirq_count() <= (1 << HARDIRQ_SHIFT))) { /* * Get here if this CPU took its interrupt from user diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index d92a76a881a..cae8a059cf4 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -44,6 +44,7 @@ #include #include #include +#include enum rcu_barrier { RCU_BARRIER_STD, @@ -55,6 +56,7 @@ static DEFINE_PER_CPU(struct rcu_head, rcu_barrier_head) = {NULL}; static atomic_t rcu_barrier_cpu_count; static DEFINE_MUTEX(rcu_barrier_mutex); static struct completion rcu_barrier_completion; +int rcu_scheduler_active __read_mostly; /* * Awaken the corresponding synchronize_rcu() instance now that a @@ -80,6 +82,10 @@ void wakeme_after_rcu(struct rcu_head *head) void synchronize_rcu(void) { struct rcu_synchronize rcu; + + if (rcu_blocking_is_gp()) + return; + init_completion(&rcu.completion); /* Will wake me after RCU finished. */ call_rcu(&rcu.head, wakeme_after_rcu); @@ -175,3 +181,9 @@ void __init rcu_init(void) __rcu_init(); } +void rcu_scheduler_starting(void) +{ + WARN_ON(num_online_cpus() != 1); + WARN_ON(nr_context_switches() > 0); + rcu_scheduler_active = 1; +} diff --git a/kernel/rcupreempt.c b/kernel/rcupreempt.c index 33cfc50781f..5d59e850fb7 100644 --- a/kernel/rcupreempt.c +++ b/kernel/rcupreempt.c @@ -1181,6 +1181,9 @@ void __synchronize_sched(void) { struct rcu_synchronize rcu; + if (num_online_cpus() == 1) + return; /* blocking is gp if only one CPU! */ + init_completion(&rcu.completion); /* Will wake me after RCU finished. */ call_rcu_sched(&rcu.head, wakeme_after_rcu); diff --git a/kernel/rcutree.c b/kernel/rcutree.c index b2fd602a6f6..97ce31579ec 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -948,8 +948,8 @@ static void rcu_do_batch(struct rcu_data *rdp) void rcu_check_callbacks(int cpu, int user) { if (user || - (idle_cpu(cpu) && !in_softirq() && - hardirq_count() <= (1 << HARDIRQ_SHIFT))) { + (idle_cpu(cpu) && rcu_scheduler_active && + !in_softirq() && hardirq_count() <= (1 << HARDIRQ_SHIFT))) { /* * Get here if this CPU took its interrupt from user -- cgit From 2b6163bf5772644068694583816fa41e8474239f Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 25 Feb 2009 20:50:49 -0800 Subject: x86: remove update_apic from x86_quirks Impact: cleanup x86_quirks->update_apic() calling looks crazy. so try to remove it: 1. every apic take wakeup_cpu member directly 2. separate es7000_apic to es7000_apic_cluster 3. use uv_wakeup_cpu directly Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/include/asm/apic.h | 7 +- arch/x86/include/asm/setup.h | 3 - arch/x86/include/asm/uv/uv.h | 3 - arch/x86/kernel/apic/apic_flat_64.c | 4 +- arch/x86/kernel/apic/bigsmp_32.c | 2 +- arch/x86/kernel/apic/es7000_32.c | 127 ++++++++++++++++++++++++++-------- arch/x86/kernel/apic/numaq_32.c | 10 +-- arch/x86/kernel/apic/probe_32.c | 16 +---- arch/x86/kernel/apic/probe_64.c | 3 - arch/x86/kernel/apic/summit_32.c | 2 +- arch/x86/kernel/apic/x2apic_cluster.c | 2 +- arch/x86/kernel/apic/x2apic_phys.c | 2 +- arch/x86/kernel/apic/x2apic_uv_x.c | 11 +-- arch/x86/kernel/setup.c | 14 +--- arch/x86/kernel/smpboot.c | 8 +-- 15 files changed, 121 insertions(+), 93 deletions(-) diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index a6208dc7463..860504178e9 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -325,6 +325,9 @@ struct apic { }; extern struct apic *apic; +extern atomic_t init_deasserted; +extern int wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip); +extern int wakeup_secondary_cpu_via_init(int apicid, unsigned long start_eip); static inline u32 apic_read(u32 reg) { @@ -384,9 +387,7 @@ static inline unsigned default_get_apic_id(unsigned long x) #define DEFAULT_TRAMPOLINE_PHYS_LOW 0x467 #define DEFAULT_TRAMPOLINE_PHYS_HIGH 0x469 -#ifdef CONFIG_X86_32 -extern void es7000_update_apic_to_cluster(void); -#else +#ifdef CONFIG_X86_64 extern struct apic apic_flat; extern struct apic apic_physflat; extern struct apic apic_x2apic_cluster; diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h index 66801cb72f6..126877e502e 100644 --- a/arch/x86/include/asm/setup.h +++ b/arch/x86/include/asm/setup.h @@ -31,7 +31,6 @@ struct x86_quirks { void (*smp_read_mpc_oem)(struct mpc_oemtable *oemtable, unsigned short oemsize); int (*setup_ioapic_ids)(void); - int (*update_apic)(void); }; extern void x86_quirk_pre_intr_init(void); @@ -77,8 +76,6 @@ static inline void visws_early_detect(void) { } static inline int is_visws_box(void) { return 0; } #endif -extern int wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip); -extern int wakeup_secondary_cpu_via_init(int apicid, unsigned long start_eip); extern struct x86_quirks *x86_quirks; extern unsigned long saved_video_mode; diff --git a/arch/x86/include/asm/uv/uv.h b/arch/x86/include/asm/uv/uv.h index 8242bf96581..c0a01b5d985 100644 --- a/arch/x86/include/asm/uv/uv.h +++ b/arch/x86/include/asm/uv/uv.h @@ -12,7 +12,6 @@ extern enum uv_system_type get_uv_system_type(void); extern int is_uv_system(void); extern void uv_cpu_init(void); extern void uv_system_init(void); -extern int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip); extern const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, struct mm_struct *mm, unsigned long va, @@ -24,8 +23,6 @@ static inline enum uv_system_type get_uv_system_type(void) { return UV_NONE; } static inline int is_uv_system(void) { return 0; } static inline void uv_cpu_init(void) { } static inline void uv_system_init(void) { } -static inline int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip) -{ return 1; } static inline const struct cpumask * uv_flush_tlb_others(const struct cpumask *cpumask, struct mm_struct *mm, unsigned long va, unsigned int cpu) diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c index 3b002995e14..00595bc2da8 100644 --- a/arch/x86/kernel/apic/apic_flat_64.c +++ b/arch/x86/kernel/apic/apic_flat_64.c @@ -222,7 +222,7 @@ struct apic apic_flat = { .send_IPI_all = flat_send_IPI_all, .send_IPI_self = apic_send_IPI_self, - .wakeup_cpu = NULL, + .wakeup_cpu = wakeup_secondary_cpu_via_init, .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, .wait_for_init_deassert = NULL, @@ -373,7 +373,7 @@ struct apic apic_physflat = { .send_IPI_all = physflat_send_IPI_all, .send_IPI_self = apic_send_IPI_self, - .wakeup_cpu = NULL, + .wakeup_cpu = wakeup_secondary_cpu_via_init, .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, .wait_for_init_deassert = NULL, diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c index 0b1093394fd..8c25917b51a 100644 --- a/arch/x86/kernel/apic/bigsmp_32.c +++ b/arch/x86/kernel/apic/bigsmp_32.c @@ -256,7 +256,7 @@ struct apic apic_bigsmp = { .send_IPI_all = bigsmp_send_IPI_all, .send_IPI_self = default_send_IPI_self, - .wakeup_cpu = NULL, + .wakeup_cpu = wakeup_secondary_cpu_via_init, .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index 320f2d2e4e5..9f6102fc87a 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c @@ -163,17 +163,12 @@ static int wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip) return 0; } -static int __init es7000_update_apic(void) +static int __init es7000_apic_is_cluster(void) { - apic->wakeup_cpu = wakeup_secondary_cpu_via_mip; - /* MPENTIUMIII */ if (boot_cpu_data.x86 == 6 && - (boot_cpu_data.x86_model >= 7 || boot_cpu_data.x86_model <= 11)) { - es7000_update_apic_to_cluster(); - apic->wait_for_init_deassert = NULL; - apic->wakeup_cpu = wakeup_secondary_cpu_via_mip; - } + (boot_cpu_data.x86_model >= 7 || boot_cpu_data.x86_model <= 11)) + return 1; return 0; } @@ -192,8 +187,6 @@ static void __init setup_unisys(void) else es7000_plat = ES7000_CLASSIC; ioapic_renumber_irq = es7000_rename_gsi; - - x86_quirks->update_apic = es7000_update_apic; } /* @@ -310,6 +303,8 @@ static int es7000_check_dsdt(void) return 0; } +static int __initdata es7000_acpi_ret; + /* Hook from generic ACPI tables.c */ static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id) { @@ -332,8 +327,19 @@ static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id) */ unmap_unisys_acpi_oem_table(oem_addr); } - return ret; + + es7000_acpi_ret = ret; + + return ret && !es7000_apic_is_cluster(); } +static int __init es7000_acpi_madt_oem_check_cluster(char *oem_id, + char *oem_table_id) +{ + int ret = es7000_acpi_ret; + + return ret && es7000_apic_is_cluster(); +} + #else /* !CONFIG_ACPI: */ static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id) { @@ -416,11 +422,8 @@ static void es7000_vector_allocation_domain(int cpu, cpumask_t *retmask) static void es7000_wait_for_init_deassert(atomic_t *deassert) { -#ifndef CONFIG_ES7000_CLUSTERED_APIC while (!atomic_read(deassert)) cpu_relax(); -#endif - return; } static unsigned int es7000_get_apic_id(unsigned long x) @@ -659,37 +662,103 @@ static int es7000_phys_pkg_id(int cpuid_apic, int index_msb) return cpuid_apic >> index_msb; } -void __init es7000_update_apic_to_cluster(void) -{ - apic->target_cpus = target_cpus_cluster; - apic->irq_delivery_mode = dest_LowestPrio; - /* logical delivery broadcast to all procs: */ - apic->irq_dest_mode = 1; - - apic->init_apic_ldr = es7000_init_apic_ldr_cluster; - - apic->cpu_mask_to_apicid = es7000_cpu_mask_to_apicid_cluster; -} - static int probe_es7000(void) { /* probed later in mptable/ACPI hooks */ return 0; } +static int __initdata es7000_mps_ret; static __init int es7000_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) { + int ret = 0; + if (mpc->oemptr) { struct mpc_oemtable *oem_table = (struct mpc_oemtable *)mpc->oemptr; if (!strncmp(oem, "UNISYS", 6)) - return parse_unisys_oem((char *)oem_table); + ret = parse_unisys_oem((char *)oem_table); } - return 0; + + es7000_mps_ret = ret; + + return ret && !es7000_apic_is_cluster(); +} + +static __init int +es7000_mps_oem_check_cluster(struct mpc_table *mpc, char *oem, char *productid) +{ + int ret = es7000_mps_ret; + + return ret && es7000_apic_is_cluster(); } +struct apic apic_es7000_cluster = { + + .name = "es7000", + .probe = probe_es7000, + .acpi_madt_oem_check = es7000_acpi_madt_oem_check_cluster, + .apic_id_registered = es7000_apic_id_registered, + + .irq_delivery_mode = dest_LowestPrio, + /* logical delivery broadcast to all procs: */ + .irq_dest_mode = 1, + + .target_cpus = target_cpus_cluster, + .disable_esr = 1, + .dest_logical = 0, + .check_apicid_used = es7000_check_apicid_used, + .check_apicid_present = es7000_check_apicid_present, + + .vector_allocation_domain = es7000_vector_allocation_domain, + .init_apic_ldr = es7000_init_apic_ldr_cluster, + + .ioapic_phys_id_map = es7000_ioapic_phys_id_map, + .setup_apic_routing = es7000_setup_apic_routing, + .multi_timer_check = NULL, + .apicid_to_node = es7000_apicid_to_node, + .cpu_to_logical_apicid = es7000_cpu_to_logical_apicid, + .cpu_present_to_apicid = es7000_cpu_present_to_apicid, + .apicid_to_cpu_present = es7000_apicid_to_cpu_present, + .setup_portio_remap = NULL, + .check_phys_apicid_present = es7000_check_phys_apicid_present, + .enable_apic_mode = es7000_enable_apic_mode, + .phys_pkg_id = es7000_phys_pkg_id, + .mps_oem_check = es7000_mps_oem_check_cluster, + + .get_apic_id = es7000_get_apic_id, + .set_apic_id = NULL, + .apic_id_mask = 0xFF << 24, + + .cpu_mask_to_apicid = es7000_cpu_mask_to_apicid_cluster, + .cpu_mask_to_apicid_and = es7000_cpu_mask_to_apicid_and, + + .send_IPI_mask = es7000_send_IPI_mask, + .send_IPI_mask_allbutself = NULL, + .send_IPI_allbutself = es7000_send_IPI_allbutself, + .send_IPI_all = es7000_send_IPI_all, + .send_IPI_self = default_send_IPI_self, + + .wakeup_cpu = wakeup_secondary_cpu_via_mip, + + .trampoline_phys_low = 0x467, + .trampoline_phys_high = 0x469, + + .wait_for_init_deassert = NULL, + + /* Nothing to do for most platforms, since cleared by the INIT cycle: */ + .smp_callin_clear_local_apic = NULL, + .inquire_remote_apic = default_inquire_remote_apic, + + .read = native_apic_mem_read, + .write = native_apic_mem_write, + .icr_read = native_apic_icr_read, + .icr_write = native_apic_icr_write, + .wait_icr_idle = native_apic_wait_icr_idle, + .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, +}; struct apic apic_es7000 = { @@ -737,7 +806,7 @@ struct apic apic_es7000 = { .send_IPI_all = es7000_send_IPI_all, .send_IPI_self = default_send_IPI_self, - .wakeup_cpu = NULL, + .wakeup_cpu = wakeup_secondary_cpu_via_init, .trampoline_phys_low = 0x467, .trampoline_phys_high = 0x469, diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c index d9d6d61eed8..c503c1799d6 100644 --- a/arch/x86/kernel/apic/numaq_32.c +++ b/arch/x86/kernel/apic/numaq_32.c @@ -256,13 +256,6 @@ static int __init numaq_setup_ioapic_ids(void) return 1; } -static int __init numaq_update_apic(void) -{ - apic->wakeup_cpu = wakeup_secondary_cpu_via_nmi; - - return 0; -} - static struct x86_quirks numaq_x86_quirks __initdata = { .arch_pre_time_init = numaq_pre_time_init, .arch_time_init = NULL, @@ -278,7 +271,6 @@ static struct x86_quirks numaq_x86_quirks __initdata = { .mpc_oem_pci_bus = mpc_oem_pci_bus, .smp_read_mpc_oem = smp_read_mpc_oem, .setup_ioapic_ids = numaq_setup_ioapic_ids, - .update_apic = numaq_update_apic, }; static __init void early_check_numaq(void) @@ -546,7 +538,7 @@ struct apic apic_numaq = { .send_IPI_all = numaq_send_IPI_all, .send_IPI_self = default_send_IPI_self, - .wakeup_cpu = NULL, + .wakeup_cpu = wakeup_secondary_cpu_via_nmi, .trampoline_phys_low = NUMAQ_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = NUMAQ_TRAMPOLINE_PHYS_HIGH, diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c index 3a730fa574b..13c6fc7dff9 100644 --- a/arch/x86/kernel/apic/probe_32.c +++ b/arch/x86/kernel/apic/probe_32.c @@ -138,7 +138,7 @@ struct apic apic_default = { .send_IPI_all = default_send_IPI_all, .send_IPI_self = default_send_IPI_self, - .wakeup_cpu = NULL, + .wakeup_cpu = wakeup_secondary_cpu_via_init, .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, @@ -159,6 +159,7 @@ extern struct apic apic_numaq; extern struct apic apic_summit; extern struct apic apic_bigsmp; extern struct apic apic_es7000; +extern struct apic apic_es7000_cluster; extern struct apic apic_default; struct apic *apic = &apic_default; @@ -176,6 +177,7 @@ static struct apic *apic_probe[] __initdata = { #endif #ifdef CONFIG_X86_ES7000 &apic_es7000, + &apic_es7000_cluster, #endif &apic_default, /* must be last */ NULL, @@ -197,9 +199,6 @@ static int __init parse_apic(char *arg) } } - if (x86_quirks->update_apic) - x86_quirks->update_apic(); - /* Parsed again by __setup for debug/verbose */ return 0; } @@ -218,8 +217,6 @@ void __init generic_bigsmp_probe(void) if (!cmdline_apic && apic == &apic_default) { if (apic_bigsmp.probe()) { apic = &apic_bigsmp; - if (x86_quirks->update_apic) - x86_quirks->update_apic(); printk(KERN_INFO "Overriding APIC driver with %s\n", apic->name); } @@ -240,9 +237,6 @@ void __init generic_apic_probe(void) /* Not visible without early console */ if (!apic_probe[i]) panic("Didn't find an APIC driver"); - - if (x86_quirks->update_apic) - x86_quirks->update_apic(); } printk(KERN_INFO "Using APIC driver %s\n", apic->name); } @@ -262,8 +256,6 @@ generic_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) if (!cmdline_apic) { apic = apic_probe[i]; - if (x86_quirks->update_apic) - x86_quirks->update_apic(); printk(KERN_INFO "Switched to APIC driver `%s'.\n", apic->name); } @@ -284,8 +276,6 @@ int __init default_acpi_madt_oem_check(char *oem_id, char *oem_table_id) if (!cmdline_apic) { apic = apic_probe[i]; - if (x86_quirks->update_apic) - x86_quirks->update_apic(); printk(KERN_INFO "Switched to APIC driver `%s'.\n", apic->name); } diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c index e7c163661c7..8d7748efe6a 100644 --- a/arch/x86/kernel/apic/probe_64.c +++ b/arch/x86/kernel/apic/probe_64.c @@ -68,9 +68,6 @@ void __init default_setup_apic_routing(void) apic = &apic_physflat; printk(KERN_INFO "Setting APIC routing to %s\n", apic->name); } - - if (x86_quirks->update_apic) - x86_quirks->update_apic(); } /* Same for both flat and physical. */ diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c index 32838b57a94..5a75d563f67 100644 --- a/arch/x86/kernel/apic/summit_32.c +++ b/arch/x86/kernel/apic/summit_32.c @@ -574,7 +574,7 @@ struct apic apic_summit = { .send_IPI_all = summit_send_IPI_all, .send_IPI_self = default_send_IPI_self, - .wakeup_cpu = NULL, + .wakeup_cpu = wakeup_secondary_cpu_via_init, .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index 354b9c45601..561a6b1042a 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c @@ -224,7 +224,7 @@ struct apic apic_x2apic_cluster = { .send_IPI_all = x2apic_send_IPI_all, .send_IPI_self = x2apic_send_IPI_self, - .wakeup_cpu = NULL, + .wakeup_cpu = wakeup_secondary_cpu_via_init, .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, .wait_for_init_deassert = NULL, diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c index 5bcb174409b..785f8ee4b1d 100644 --- a/arch/x86/kernel/apic/x2apic_phys.c +++ b/arch/x86/kernel/apic/x2apic_phys.c @@ -213,7 +213,7 @@ struct apic apic_x2apic_phys = { .send_IPI_all = x2apic_send_IPI_all, .send_IPI_self = x2apic_send_IPI_self, - .wakeup_cpu = NULL, + .wakeup_cpu = wakeup_secondary_cpu_via_init, .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, .wait_for_init_deassert = NULL, diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 20b4ad07c3a..6d7b9d960dd 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -91,7 +91,7 @@ static void uv_vector_allocation_domain(int cpu, struct cpumask *retmask) cpumask_set_cpu(cpu, retmask); } -int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip) +static int uv_wakeup_secondary(int phys_apicid, unsigned long start_rip) { unsigned long val; int pnode; @@ -99,16 +99,19 @@ int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip) pnode = uv_apicid_to_pnode(phys_apicid); val = (1UL << UVH_IPI_INT_SEND_SHFT) | (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) | - (((long)start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) | + ((start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) | APIC_DM_INIT; uv_write_global_mmr64(pnode, UVH_IPI_INT, val); mdelay(10); val = (1UL << UVH_IPI_INT_SEND_SHFT) | (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) | - (((long)start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) | + ((start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) | APIC_DM_STARTUP; uv_write_global_mmr64(pnode, UVH_IPI_INT, val); + + atomic_set(&init_deasserted, 1); + return 0; } @@ -285,7 +288,7 @@ struct apic apic_x2apic_uv_x = { .send_IPI_all = uv_send_IPI_all, .send_IPI_self = uv_send_IPI_self, - .wakeup_cpu = NULL, + .wakeup_cpu = uv_wakeup_secondary, .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, .wait_for_init_deassert = NULL, diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 5b85759e797..2280d93c5b9 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -600,19 +600,7 @@ static int __init setup_elfcorehdr(char *arg) early_param("elfcorehdr", setup_elfcorehdr); #endif -static int __init default_update_apic(void) -{ -#ifdef CONFIG_SMP - if (!apic->wakeup_cpu) - apic->wakeup_cpu = wakeup_secondary_cpu_via_init; -#endif - - return 0; -} - -static struct x86_quirks default_x86_quirks __initdata = { - .update_apic = default_update_apic, -}; +static struct x86_quirks default_x86_quirks __initdata; struct x86_quirks *x86_quirks __initdata = &default_x86_quirks; diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 9ce666387f3..9b338aa03b4 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -112,7 +112,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_core_map); DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info); EXPORT_PER_CPU_SYMBOL(cpu_info); -static atomic_t init_deasserted; +atomic_t init_deasserted; /* Set if we find a B stepping CPU */ @@ -614,12 +614,6 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) unsigned long send_status, accept_status = 0; int maxlvt, num_starts, j; - if (get_uv_system_type() == UV_NON_UNIQUE_APIC) { - send_status = uv_wakeup_secondary(phys_apicid, start_eip); - atomic_set(&init_deasserted, 1); - return send_status; - } - maxlvt = lapic_get_maxlvt(); /* -- cgit From 129d8bc828e011bda0b7110a097bf3a0167f966e Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 25 Feb 2009 21:20:50 -0800 Subject: x86: don't compile vsmp_64 for 32bit Impact: cleanup that is only needed when CONFIG_X86_VSMP is defined with 64bit also remove dead code about PCI, because CONFIG_X86_VSMP depends on PCI Signed-off-by: Yinghai Lu Cc: Ravikiran Thirumalai Signed-off-by: Ingo Molnar --- arch/x86/include/asm/apic.h | 7 +++++++ arch/x86/include/asm/setup.h | 4 ++++ arch/x86/kernel/Makefile | 2 +- arch/x86/kernel/setup.c | 2 -- arch/x86/kernel/vsmp_64.c | 12 +----------- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 860504178e9..24e21273e30 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -75,7 +75,14 @@ static inline void default_inquire_remote_apic(int apicid) #define setup_secondary_clock setup_secondary_APIC_clock #endif +#ifdef CONFIG_X86_VSMP extern int is_vsmp_box(void); +#else +static inline int is_vsmp_box(void) +{ + return 0; +} +#endif extern void xapic_wait_icr_idle(void); extern u32 safe_xapic_wait_icr_idle(void); extern void xapic_icr_write(u32, u32); diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h index 126877e502e..05c6f6b11fd 100644 --- a/arch/x86/include/asm/setup.h +++ b/arch/x86/include/asm/setup.h @@ -64,7 +64,11 @@ extern void x86_quirk_time_init(void); #include /* Interrupt control for vSMPowered x86_64 systems */ +#ifdef CONFIG_X86_VSMP void vsmp_init(void); +#else +static inline void vsmp_init(void) { } +#endif void setup_bios_corruption_check(void); diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index de5657c039e..95f216bbfaf 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -70,7 +70,7 @@ obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o -obj-y += vsmp_64.o +obj-$(CONFIG_X86_VSMP) += vsmp_64.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_MODULES) += module_$(BITS).o obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 2280d93c5b9..4c54bc0d8ff 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -863,9 +863,7 @@ void __init setup_arch(char **cmdline_p) reserve_initrd(); -#ifdef CONFIG_X86_64 vsmp_init(); -#endif io_delay_init(); diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c index c609205df59..74de562812c 100644 --- a/arch/x86/kernel/vsmp_64.c +++ b/arch/x86/kernel/vsmp_64.c @@ -22,7 +22,7 @@ #include #include -#if defined CONFIG_PCI && defined CONFIG_PARAVIRT +#ifdef CONFIG_PARAVIRT /* * Interrupt control on vSMPowered systems: * ~AC is a shadow of IF. If IF is 'on' AC should be 'off' @@ -114,7 +114,6 @@ static void __init set_vsmp_pv_ops(void) } #endif -#ifdef CONFIG_PCI static int is_vsmp = -1; static void __init detect_vsmp_box(void) @@ -139,15 +138,6 @@ int is_vsmp_box(void) return 0; } } -#else -static void __init detect_vsmp_box(void) -{ -} -int is_vsmp_box(void) -{ - return 0; -} -#endif void __init vsmp_init(void) { -- cgit From 8b1a8ff8b321a9384304aeea4dbdb9747daf7ee8 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 28 Feb 2009 00:08:53 -0500 Subject: ext4: Remove duplicate call to ext4_commit_super() in ext4_freeze() Commit c4be0c1d added error checking to ext4_freeze() when calling ext4_commit_super(). Unfortunately the patch failed to remove the original call to ext4_commit_super(), with the net result that when freezing the filesystem, the superblock gets written twice, the first time without error checking. Signed-off-by: "Theodore Ts'o" --- fs/ext4/super.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index a5732c58f67..39d1993cfa1 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3091,7 +3091,6 @@ static int ext4_freeze(struct super_block *sb) /* Journal blocked and flushed, clear needs_recovery flag. */ EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); - ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1); error = ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1); if (error) goto out; -- cgit From d8ae4601a4b7ea1fa17fa395c3468c0e144d1275 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 28 Feb 2009 09:50:01 -0500 Subject: ext4: Reorder fs/Makefile so that ext2 root fs's are mounted using ext2 In fs/Makefile, ext3 was placed before ext2 so that a root filesystem that possessed a journal, it would be mounted as ext3 instead of ext2. This was necessary because a cleanly unmounted ext3 filesystem was fully backwards compatible with ext2, and could be mounted by ext2 --- but it was desirable that it be mounted with ext3 so that the journaling would be enabled. The ext4 filesystem supports new incompatible features, so there is no danger of an ext4 filesystem being mistaken for an ext2 filesystem. At that point, the relative ordering of ext4 with respect to ext2 didn't matter until ext4 gained the ability to mount filesystems without a journal starting in 2.6.29-rc1. Now that this is the case, given that ext4 is before ext2, it means that root filesystems that were using the plain-jane ext2 format are getting mounted using the ext4 filesystem driver, which is a change in behavior which could be surprising to users. It's doubtful that there are that many ext2-only root filesystem users that would also have ext4 compiled into the kernel, but to adhere to the principle of least surprise, the correct ordering in fs/Makefile is ext3, followed by ext2, and finally ext4. Signed-off-by: "Theodore Ts'o" --- fs/Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/Makefile b/fs/Makefile index 38bc735c67a..dc20db34867 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -69,10 +69,12 @@ obj-$(CONFIG_DLM) += dlm/ # Do not add any filesystems before this line obj-$(CONFIG_REISERFS_FS) += reiserfs/ obj-$(CONFIG_EXT3_FS) += ext3/ # Before ext2 so root fs can be ext3 -obj-$(CONFIG_EXT4_FS) += ext4/ # Before ext2 so root fs can be ext4 +obj-$(CONFIG_EXT2_FS) += ext2/ +# We place ext4 after ext2 so plain ext2 root fs's are mounted using ext2 +# unless explicitly requested by rootfstype +obj-$(CONFIG_EXT4_FS) += ext4/ obj-$(CONFIG_JBD) += jbd/ obj-$(CONFIG_JBD2) += jbd2/ -obj-$(CONFIG_EXT2_FS) += ext2/ obj-$(CONFIG_CRAMFS) += cramfs/ obj-$(CONFIG_SQUASHFS) += squashfs/ obj-y += ramfs/ -- cgit From 8f64b32eb73fbfe9f38c4123121b63ee409278a7 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Thu, 26 Feb 2009 00:57:35 -0500 Subject: ext4: don't call jbd2_journal_force_commit_nested without journal Running without a journal, I oopsed when I ran out of space, because we called jbd2_journal_force_commit_nested() from ext4_should_retry_alloc() without a journal. This should take care of it, I think. Signed-off-by: Eric Sandeen Signed-off-by: "Theodore Ts'o" --- fs/ext4/balloc.c | 4 +++- fs/ext4/inode.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 9a50b8052dc..de9459b4cb9 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -609,7 +609,9 @@ int ext4_claim_free_blocks(struct ext4_sb_info *sbi, */ int ext4_should_retry_alloc(struct super_block *sb, int *retries) { - if (!ext4_has_free_blocks(EXT4_SB(sb), 1) || (*retries)++ > 3) + if (!ext4_has_free_blocks(EXT4_SB(sb), 1) || + (*retries)++ > 3 || + !EXT4_SB(sb)->s_journal) return 0; jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 51cdd13e1c3..c7fed5b1874 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2544,7 +2544,7 @@ retry: ext4_journal_stop(handle); - if (mpd.retval == -ENOSPC) { + if ((mpd.retval == -ENOSPC) && sbi->s_journal) { /* commit the transaction which would * free blocks released in the transaction * and try again -- cgit From a760a6656e6f00bb0144a42a048cf0266646e22c Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 26 Feb 2009 14:06:31 +0800 Subject: crypto: api - Fix module load deadlock with fallback algorithms With the mandatory algorithm testing at registration, we have now created a deadlock with algorithms requiring fallbacks. This can happen if the module containing the algorithm requiring fallback is loaded first, without the fallback module being loaded first. The system will then try to test the new algorithm, find that it needs to load a fallback, and then try to load that. As both algorithms share the same module alias, it can attempt to load the original algorithm again and block indefinitely. As algorithms requiring fallbacks are a special case, we can fix this by giving them a different module alias than the rest. Then it's just a matter of using the right aliases according to what algorithms we're trying to find. Signed-off-by: Herbert Xu --- arch/s390/crypto/aes_s390.c | 2 +- crypto/api.c | 15 +++++++++++++-- drivers/crypto/padlock-aes.c | 2 +- drivers/crypto/padlock-sha.c | 4 ++-- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index c42cd898f68..6118890c946 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c @@ -556,7 +556,7 @@ static void __exit aes_s390_fini(void) module_init(aes_s390_init); module_exit(aes_s390_fini); -MODULE_ALIAS("aes"); +MODULE_ALIAS("aes-all"); MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm"); MODULE_LICENSE("GPL"); diff --git a/crypto/api.c b/crypto/api.c index efe77df6863..38a2bc02a98 100644 --- a/crypto/api.c +++ b/crypto/api.c @@ -215,8 +215,19 @@ struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask) mask &= ~(CRYPTO_ALG_LARVAL | CRYPTO_ALG_DEAD); type &= mask; - alg = try_then_request_module(crypto_alg_lookup(name, type, mask), - name); + alg = crypto_alg_lookup(name, type, mask); + if (!alg) { + char tmp[CRYPTO_MAX_ALG_NAME]; + + request_module(name); + + if (!((type ^ CRYPTO_ALG_NEED_FALLBACK) & mask) && + snprintf(tmp, sizeof(tmp), "%s-all", name) < sizeof(tmp)) + request_module(tmp); + + alg = crypto_alg_lookup(name, type, mask); + } + if (alg) return crypto_is_larval(alg) ? crypto_larval_wait(alg) : alg; diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index 856b3cc2558..3f0fdd18255 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c @@ -489,4 +489,4 @@ MODULE_DESCRIPTION("VIA PadLock AES algorithm support"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Michal Ludvig"); -MODULE_ALIAS("aes"); +MODULE_ALIAS("aes-all"); diff --git a/drivers/crypto/padlock-sha.c b/drivers/crypto/padlock-sha.c index a7fbadebf62..a2c8e8514b6 100644 --- a/drivers/crypto/padlock-sha.c +++ b/drivers/crypto/padlock-sha.c @@ -304,7 +304,7 @@ MODULE_DESCRIPTION("VIA PadLock SHA1/SHA256 algorithms support."); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Michal Ludvig"); -MODULE_ALIAS("sha1"); -MODULE_ALIAS("sha256"); +MODULE_ALIAS("sha1-all"); +MODULE_ALIAS("sha256-all"); MODULE_ALIAS("sha1-padlock"); MODULE_ALIAS("sha256-padlock"); -- cgit From b2bf96833c5782befc3e7700f791fde754a47b01 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 19 Feb 2009 08:50:26 +0100 Subject: block: fix bogus gcc warning for uninitialized var usage Newer gcc throw this warning: fs/bio.c: In function ?bio_alloc_bioset?: fs/bio.c:305: warning: ?p? may be used uninitialized in this function since it cannot figure out that 'p' is only ever used if 'bs' is non-NULL. Signed-off-by: Jens Axboe --- fs/bio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/bio.c b/fs/bio.c index 72ab251cdb9..124b95c4d58 100644 --- a/fs/bio.c +++ b/fs/bio.c @@ -302,7 +302,7 @@ void bio_init(struct bio *bio) struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) { struct bio *bio = NULL; - void *p; + void *uninitialized_var(p); if (bs) { p = mempool_alloc(bs->bio_pool, gfp_mask); -- cgit From 9e8c0bccdc944bd09361672d47660810c027bcaa Mon Sep 17 00:00:00 2001 From: Márton Németh Date: Fri, 20 Feb 2009 08:12:51 +0100 Subject: block: add documentation for register_blkdev() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add documentation for register_blkdev() function and for the parameters. Signed-off-by: Márton Németh Cc: Greg Kroah-Hartman Signed-off-by: Jens Axboe --- block/genhd.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/block/genhd.c b/block/genhd.c index e1eadcc9546..a9ec910974c 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -256,6 +256,22 @@ void blkdev_show(struct seq_file *seqf, off_t offset) } #endif /* CONFIG_PROC_FS */ +/** + * register_blkdev - register a new block device + * + * @major: the requested major device number [1..255]. If @major=0, try to + * allocate any unused major number. + * @name: the name of the new block device as a zero terminated string + * + * The @name must be unique within the system. + * + * The return value depends on the @major input parameter. + * - if a major device number was requested in range [1..255] then the + * function returns zero on success, or a negative error code + * - if any unused major number was requested with @major=0 parameter + * then the return value is the allocated major number in range + * [1..255] or a negative error code otherwise + */ int register_blkdev(unsigned int major, const char *name) { struct blk_major_name **n, *p; -- cgit From 5e4c91c84b194b26cf592779e451f4b5be777cba Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 23 Feb 2009 08:53:35 +0100 Subject: cciss: shorten 30s timeout on controller reset If reset_devices is set for kexec, then cciss will delay 30 seconds since the old 5i controller _may_ need that long to recover. Replace the long sleep with incremental sleep and tests to reduce the 30 seconds to worst case for 5i, so that other controllers will proceed quickly. Reviewed-by: Mike Miller Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index d2cb67b6117..b5a06111463 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -3611,11 +3611,15 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, schedule_timeout_uninterruptible(30*HZ); /* Now try to get the controller to respond to a no-op */ - for (i=0; i<12; i++) { + for (i=0; i<30; i++) { if (cciss_noop(pdev) == 0) break; - else - printk("cciss: no-op failed%s\n", (i < 11 ? "; re-trying" : "")); + + schedule_timeout_uninterruptible(HZ); + } + if (i == 30) { + printk(KERN_ERR "cciss: controller seems dead\n"); + return -EBUSY; } } -- cgit From 1e42807918d17e8c93bf14fbb74be84b141334c1 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 23 Feb 2009 09:03:10 +0100 Subject: block: reduce stack footprint of blk_recount_segments() blk_recalc_rq_segments() requires a request structure passed in, which we don't have from blk_recount_segments(). So the latter allocates one on the stack, using > 400 bytes of stack for that. This can cause us to spill over one page of stack from ext4 at least: 0) 4560 400 blk_recount_segments+0x43/0x62 1) 4160 32 bio_phys_segments+0x1c/0x24 2) 4128 32 blk_rq_bio_prep+0x2a/0xf9 3) 4096 32 init_request_from_bio+0xf9/0xfe 4) 4064 112 __make_request+0x33c/0x3f6 5) 3952 144 generic_make_request+0x2d1/0x321 6) 3808 64 submit_bio+0xb9/0xc3 7) 3744 48 submit_bh+0xea/0x10e 8) 3696 368 ext4_mb_init_cache+0x257/0xa6a [ext4] 9) 3328 288 ext4_mb_regular_allocator+0x421/0xcd9 [ext4] 10) 3040 160 ext4_mb_new_blocks+0x211/0x4b4 [ext4] 11) 2880 336 ext4_ext_get_blocks+0xb61/0xd45 [ext4] 12) 2544 96 ext4_get_blocks_wrap+0xf2/0x200 [ext4] 13) 2448 80 ext4_da_get_block_write+0x6e/0x16b [ext4] 14) 2368 352 mpage_da_map_blocks+0x7e/0x4b3 [ext4] 15) 2016 352 ext4_da_writepages+0x2ce/0x43c [ext4] 16) 1664 32 do_writepages+0x2d/0x3c 17) 1632 144 __writeback_single_inode+0x162/0x2cd 18) 1488 96 generic_sync_sb_inodes+0x1e3/0x32b 19) 1392 16 sync_sb_inodes+0xe/0x10 20) 1376 48 writeback_inodes+0x69/0xb3 21) 1328 208 balance_dirty_pages_ratelimited_nr+0x187/0x2f9 22) 1120 224 generic_file_buffered_write+0x1d4/0x2c4 23) 896 176 __generic_file_aio_write_nolock+0x35f/0x393 24) 720 80 generic_file_aio_write+0x6c/0xc8 25) 640 80 ext4_file_write+0xa9/0x137 [ext4] 26) 560 320 do_sync_write+0xf0/0x137 27) 240 48 vfs_write+0xb3/0x13c 28) 192 64 sys_write+0x4c/0x74 29) 128 128 system_call_fastpath+0x16/0x1b Split the segment counting out into a __blk_recalc_rq_segments() helper to avoid allocating an onstack request just for checking the physical segment count. Signed-off-by: Jens Axboe --- block/blk-merge.c | 94 ++++++++++++++++++++++++++++---------------------- include/linux/blkdev.h | 2 ++ 2 files changed, 55 insertions(+), 41 deletions(-) diff --git a/block/blk-merge.c b/block/blk-merge.c index b92f5b0866b..a104593e70c 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -38,72 +38,84 @@ void blk_recalc_rq_sectors(struct request *rq, int nsect) } } -void blk_recalc_rq_segments(struct request *rq) +static unsigned int __blk_recalc_rq_segments(struct request_queue *q, + struct bio *bio, + unsigned int *seg_size_ptr) { - int nr_phys_segs; unsigned int phys_size; struct bio_vec *bv, *bvprv = NULL; - int seg_size; - int cluster; - struct req_iterator iter; - int high, highprv = 1; - struct request_queue *q = rq->q; + int cluster, i, high, highprv = 1; + unsigned int seg_size, nr_phys_segs; + struct bio *fbio; - if (!rq->bio) - return; + if (!bio) + return 0; + fbio = bio; cluster = test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); seg_size = 0; phys_size = nr_phys_segs = 0; - rq_for_each_segment(bv, rq, iter) { - /* - * the trick here is making sure that a high page is never - * considered part of another segment, since that might - * change with the bounce page. - */ - high = page_to_pfn(bv->bv_page) > q->bounce_pfn; - if (high || highprv) - goto new_segment; - if (cluster) { - if (seg_size + bv->bv_len > q->max_segment_size) - goto new_segment; - if (!BIOVEC_PHYS_MERGEABLE(bvprv, bv)) - goto new_segment; - if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bv)) + for_each_bio(bio) { + bio_for_each_segment(bv, bio, i) { + /* + * the trick here is making sure that a high page is + * never considered part of another segment, since that + * might change with the bounce page. + */ + high = page_to_pfn(bv->bv_page) > q->bounce_pfn; + if (high || highprv) goto new_segment; + if (cluster) { + if (seg_size + bv->bv_len > q->max_segment_size) + goto new_segment; + if (!BIOVEC_PHYS_MERGEABLE(bvprv, bv)) + goto new_segment; + if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bv)) + goto new_segment; + + seg_size += bv->bv_len; + bvprv = bv; + continue; + } +new_segment: + if (nr_phys_segs == 1 && seg_size > + fbio->bi_seg_front_size) + fbio->bi_seg_front_size = seg_size; - seg_size += bv->bv_len; + nr_phys_segs++; bvprv = bv; - continue; + seg_size = bv->bv_len; + highprv = high; } -new_segment: - if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size) - rq->bio->bi_seg_front_size = seg_size; - - nr_phys_segs++; - bvprv = bv; - seg_size = bv->bv_len; - highprv = high; } - if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size) + if (seg_size_ptr) + *seg_size_ptr = seg_size; + + return nr_phys_segs; +} + +void blk_recalc_rq_segments(struct request *rq) +{ + unsigned int seg_size = 0, phys_segs; + + phys_segs = __blk_recalc_rq_segments(rq->q, rq->bio, &seg_size); + + if (phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size) rq->bio->bi_seg_front_size = seg_size; if (seg_size > rq->biotail->bi_seg_back_size) rq->biotail->bi_seg_back_size = seg_size; - rq->nr_phys_segments = nr_phys_segs; + rq->nr_phys_segments = phys_segs; } void blk_recount_segments(struct request_queue *q, struct bio *bio) { - struct request rq; struct bio *nxt = bio->bi_next; - rq.q = q; - rq.bio = rq.biotail = bio; + bio->bi_next = NULL; - blk_recalc_rq_segments(&rq); + bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, NULL); bio->bi_next = nxt; - bio->bi_phys_segments = rq.nr_phys_segments; bio->bi_flags |= (1 << BIO_SEG_VALID); } EXPORT_SYMBOL(blk_recount_segments); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index dcaa0fd84b0..465d6babc84 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -708,6 +708,8 @@ struct req_iterator { }; /* This should not be used directly - use rq_for_each_segment */ +#define for_each_bio(_bio) \ + for (; _bio; _bio = _bio->bi_next) #define __rq_for_each_bio(_bio, rq) \ if ((rq->bio)) \ for (_bio = (rq)->bio; _bio; _bio = _bio->bi_next) -- cgit From 9e973e64ac6dc504e6447d52193d4fff1a670156 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 24 Feb 2009 08:10:09 +0100 Subject: xen/blkfront: use blk_rq_map_sg to generate ring entries On occasion, the request will apparently have more segments than we fit into the ring. Jens says: > The second problem is that the block layer then appears to create one > too many segments, but from the dump it has rq->nr_phys_segments == > BLKIF_MAX_SEGMENTS_PER_REQUEST. I suspect the latter is due to > xen-blkfront not handling the merging on its own. It should check that > the new page doesn't form part of the previous page. The > rq_for_each_segment() iterates all single bits in the request, not dma > segments. The "easiest" way to do this is to call blk_rq_map_sg() and > then iterate the mapped sg list. That will give you what you are > looking for. > Here's a test patch, compiles but otherwise untested. I spent more > time figuring out how to enable XEN than to code it up, so YMMV! > Probably the sg list wants to be put inside the ring and only > initialized on allocation, then you can get rid of the sg on stack and > sg_init_table() loop call in the function. I'll leave that, and the > testing, to you. [Moved sg array into info structure, and initialize once. -J] Signed-off-by: Jens Axboe Signed-off-by: Jeremy Fitzhardinge --- drivers/block/xen-blkfront.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 918ef725de4..b6c8ce25435 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -82,6 +83,7 @@ struct blkfront_info enum blkif_state connected; int ring_ref; struct blkif_front_ring ring; + struct scatterlist sg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; unsigned int evtchn, irq; struct request_queue *rq; struct work_struct work; @@ -204,12 +206,11 @@ static int blkif_queue_request(struct request *req) struct blkfront_info *info = req->rq_disk->private_data; unsigned long buffer_mfn; struct blkif_request *ring_req; - struct req_iterator iter; - struct bio_vec *bvec; unsigned long id; unsigned int fsect, lsect; - int ref; + int i, ref; grant_ref_t gref_head; + struct scatterlist *sg; if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) return 1; @@ -238,12 +239,13 @@ static int blkif_queue_request(struct request *req) if (blk_barrier_rq(req)) ring_req->operation = BLKIF_OP_WRITE_BARRIER; - ring_req->nr_segments = 0; - rq_for_each_segment(bvec, req, iter) { - BUG_ON(ring_req->nr_segments == BLKIF_MAX_SEGMENTS_PER_REQUEST); - buffer_mfn = pfn_to_mfn(page_to_pfn(bvec->bv_page)); - fsect = bvec->bv_offset >> 9; - lsect = fsect + (bvec->bv_len >> 9) - 1; + ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg); + BUG_ON(ring_req->nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST); + + for_each_sg(info->sg, sg, ring_req->nr_segments, i) { + buffer_mfn = pfn_to_mfn(page_to_pfn(sg_page(sg))); + fsect = sg->offset >> 9; + lsect = fsect + (sg->length >> 9) - 1; /* install a grant reference. */ ref = gnttab_claim_grant_reference(&gref_head); BUG_ON(ref == -ENOSPC); @@ -254,16 +256,12 @@ static int blkif_queue_request(struct request *req) buffer_mfn, rq_data_dir(req) ); - info->shadow[id].frame[ring_req->nr_segments] = - mfn_to_pfn(buffer_mfn); - - ring_req->seg[ring_req->nr_segments] = + info->shadow[id].frame[i] = mfn_to_pfn(buffer_mfn); + ring_req->seg[i] = (struct blkif_request_segment) { .gref = ref, .first_sect = fsect, .last_sect = lsect }; - - ring_req->nr_segments++; } info->ring.req_prod_pvt++; @@ -622,6 +620,8 @@ static int setup_blkring(struct xenbus_device *dev, SHARED_RING_INIT(sring); FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE); + sg_init_table(info->sg, BLKIF_MAX_SEGMENTS_PER_REQUEST); + err = xenbus_grant_ring(dev, virt_to_mfn(info->ring.sring)); if (err < 0) { free_page((unsigned long)sring); -- cgit From 3f53a38131a4e7a053c0aa060aba0411242fb6b9 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Thu, 26 Feb 2009 03:35:13 -0800 Subject: ipv6: don't use tw net when accounting for recycled tw We already have a valid net in that place, but this is not just a cleanup - the tw pointer can be NULL there sometimes, thus causing an oops in NET_NS=y case. The same place in ipv4 code already works correctly using existing net, rather than tw's one. The bug exists since 2.6.27. Signed-off-by: Pavel Emelyanov Signed-off-by: David S. Miller --- net/ipv6/inet6_hashtables.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c index 8fe267feb81..1bcc3431859 100644 --- a/net/ipv6/inet6_hashtables.c +++ b/net/ipv6/inet6_hashtables.c @@ -258,11 +258,11 @@ unique: if (twp != NULL) { *twp = tw; - NET_INC_STATS_BH(twsk_net(tw), LINUX_MIB_TIMEWAITRECYCLED); + NET_INC_STATS_BH(net, LINUX_MIB_TIMEWAITRECYCLED); } else if (tw != NULL) { /* Silly. Should hash-dance instead... */ inet_twsk_deschedule(tw, death_row); - NET_INC_STATS_BH(twsk_net(tw), LINUX_MIB_TIMEWAITRECYCLED); + NET_INC_STATS_BH(net, LINUX_MIB_TIMEWAITRECYCLED); inet_twsk_put(tw); } -- cgit From 0917c01f8e793f57a53cf886533d4c75c67f6e89 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 26 Feb 2009 12:47:40 +0100 Subject: x86: remove update_apic from x86_quirks, fix Impact: build fix wakeup_secondary_cpu_via_init(), the default platform method for booting a secondary CPU, is always used on UP due to probe_32.c, if CONFIG_X86_LOCAL_APIC is enabled but SMP is off. So provide a UP wrapper inline as well. Cc: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/include/asm/apic.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 24e21273e30..0fbf6f1520f 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -331,10 +331,27 @@ struct apic { u32 (*safe_wait_icr_idle)(void); }; +/* + * Pointer to the local APIC driver in use on this system (there's + * always just one such driver in use - the kernel decides via an + * early probing process which one it picks - and then sticks to it): + */ extern struct apic *apic; + +/* + * APIC functionality to boot other CPUs - only used on SMP: + */ +#ifdef CONFIG_SMP extern atomic_t init_deasserted; extern int wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip); extern int wakeup_secondary_cpu_via_init(int apicid, unsigned long start_eip); +#else +static inline int +wakeup_secondary_cpu_via_init(int apicid, unsigned long start_eip) +{ + return 0; +} +#endif static inline u32 apic_read(u32 reg) { -- cgit From 1f5bcabf1b997d6b76a09114b5a79423495a1263 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 26 Feb 2009 13:51:40 +0100 Subject: x86: apic: simplify secondary CPU wakeup methods Impact: cleanup - rename apic->wakeup_cpu to apic->wakeup_secondary_cpu, to make it apparent that this is an SMP-only method - handle NULL ->wakeup_secondary_cpus to mean the default INIT wakeup sequence - this allows simplification of the APIC driver templates. Cc: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/include/asm/apic.h | 9 +-------- arch/x86/kernel/apic/apic_flat_64.c | 2 -- arch/x86/kernel/apic/bigsmp_32.c | 1 - arch/x86/kernel/apic/es7000_32.c | 4 +--- arch/x86/kernel/apic/numaq_32.c | 2 +- arch/x86/kernel/apic/probe_32.c | 1 - arch/x86/kernel/apic/summit_32.c | 1 - arch/x86/kernel/apic/x2apic_cluster.c | 1 - arch/x86/kernel/apic/x2apic_phys.c | 1 - arch/x86/kernel/apic/x2apic_uv_x.c | 2 +- arch/x86/kernel/smpboot.c | 11 ++++++++--- 11 files changed, 12 insertions(+), 23 deletions(-) diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 0fbf6f1520f..4ef949c1972 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -313,7 +313,7 @@ struct apic { void (*send_IPI_self)(int vector); /* wakeup_secondary_cpu */ - int (*wakeup_cpu)(int apicid, unsigned long start_eip); + int (*wakeup_secondary_cpu)(int apicid, unsigned long start_eip); int trampoline_phys_low; int trampoline_phys_high; @@ -344,13 +344,6 @@ extern struct apic *apic; #ifdef CONFIG_SMP extern atomic_t init_deasserted; extern int wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip); -extern int wakeup_secondary_cpu_via_init(int apicid, unsigned long start_eip); -#else -static inline int -wakeup_secondary_cpu_via_init(int apicid, unsigned long start_eip) -{ - return 0; -} #endif static inline u32 apic_read(u32 reg) diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c index 00595bc2da8..f933822dba1 100644 --- a/arch/x86/kernel/apic/apic_flat_64.c +++ b/arch/x86/kernel/apic/apic_flat_64.c @@ -222,7 +222,6 @@ struct apic apic_flat = { .send_IPI_all = flat_send_IPI_all, .send_IPI_self = apic_send_IPI_self, - .wakeup_cpu = wakeup_secondary_cpu_via_init, .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, .wait_for_init_deassert = NULL, @@ -373,7 +372,6 @@ struct apic apic_physflat = { .send_IPI_all = physflat_send_IPI_all, .send_IPI_self = apic_send_IPI_self, - .wakeup_cpu = wakeup_secondary_cpu_via_init, .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, .wait_for_init_deassert = NULL, diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c index 8c25917b51a..69c512e23a9 100644 --- a/arch/x86/kernel/apic/bigsmp_32.c +++ b/arch/x86/kernel/apic/bigsmp_32.c @@ -256,7 +256,6 @@ struct apic apic_bigsmp = { .send_IPI_all = bigsmp_send_IPI_all, .send_IPI_self = default_send_IPI_self, - .wakeup_cpu = wakeup_secondary_cpu_via_init, .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index 9f6102fc87a..b4838ed3f26 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c @@ -741,7 +741,7 @@ struct apic apic_es7000_cluster = { .send_IPI_all = es7000_send_IPI_all, .send_IPI_self = default_send_IPI_self, - .wakeup_cpu = wakeup_secondary_cpu_via_mip, + .wakeup_secondary_cpu = wakeup_secondary_cpu_via_mip, .trampoline_phys_low = 0x467, .trampoline_phys_high = 0x469, @@ -806,8 +806,6 @@ struct apic apic_es7000 = { .send_IPI_all = es7000_send_IPI_all, .send_IPI_self = default_send_IPI_self, - .wakeup_cpu = wakeup_secondary_cpu_via_init, - .trampoline_phys_low = 0x467, .trampoline_phys_high = 0x469, diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c index c503c1799d6..a7f711f5110 100644 --- a/arch/x86/kernel/apic/numaq_32.c +++ b/arch/x86/kernel/apic/numaq_32.c @@ -538,7 +538,7 @@ struct apic apic_numaq = { .send_IPI_all = numaq_send_IPI_all, .send_IPI_self = default_send_IPI_self, - .wakeup_cpu = wakeup_secondary_cpu_via_nmi, + .wakeup_secondary_cpu = wakeup_secondary_cpu_via_nmi, .trampoline_phys_low = NUMAQ_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = NUMAQ_TRAMPOLINE_PHYS_HIGH, diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c index 13c6fc7dff9..141c99a1c26 100644 --- a/arch/x86/kernel/apic/probe_32.c +++ b/arch/x86/kernel/apic/probe_32.c @@ -138,7 +138,6 @@ struct apic apic_default = { .send_IPI_all = default_send_IPI_all, .send_IPI_self = default_send_IPI_self, - .wakeup_cpu = wakeup_secondary_cpu_via_init, .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c index 5a75d563f67..0a1135c5a6d 100644 --- a/arch/x86/kernel/apic/summit_32.c +++ b/arch/x86/kernel/apic/summit_32.c @@ -574,7 +574,6 @@ struct apic apic_summit = { .send_IPI_all = summit_send_IPI_all, .send_IPI_self = default_send_IPI_self, - .wakeup_cpu = wakeup_secondary_cpu_via_init, .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index 561a6b1042a..8fb87b6dd63 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c @@ -224,7 +224,6 @@ struct apic apic_x2apic_cluster = { .send_IPI_all = x2apic_send_IPI_all, .send_IPI_self = x2apic_send_IPI_self, - .wakeup_cpu = wakeup_secondary_cpu_via_init, .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, .wait_for_init_deassert = NULL, diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c index 785f8ee4b1d..23625b9f98b 100644 --- a/arch/x86/kernel/apic/x2apic_phys.c +++ b/arch/x86/kernel/apic/x2apic_phys.c @@ -213,7 +213,6 @@ struct apic apic_x2apic_phys = { .send_IPI_all = x2apic_send_IPI_all, .send_IPI_self = x2apic_send_IPI_self, - .wakeup_cpu = wakeup_secondary_cpu_via_init, .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, .wait_for_init_deassert = NULL, diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 6d7b9d960dd..7151de74a39 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -288,7 +288,7 @@ struct apic apic_x2apic_uv_x = { .send_IPI_all = uv_send_IPI_all, .send_IPI_self = uv_send_IPI_self, - .wakeup_cpu = uv_wakeup_secondary, + .wakeup_secondary_cpu = uv_wakeup_secondary, .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, .wait_for_init_deassert = NULL, diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 9b338aa03b4..249334f5080 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -742,7 +742,8 @@ static void __cpuinit do_fork_idle(struct work_struct *work) /* * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad * (ie clustered apic addressing mode), this is a LOGICAL apic ID. - * Returns zero if CPU booted OK, else error code from ->wakeup_cpu. + * Returns zero if CPU booted OK, else error code from + * ->wakeup_secondary_cpu. */ static int __cpuinit do_boot_cpu(int apicid, int cpu) { @@ -829,9 +830,13 @@ do_rest: } /* - * Starting actual IPI sequence... + * Kick the secondary CPU. Use the method in the APIC driver + * if it's defined - or use an INIT boot APIC message otherwise: */ - boot_error = apic->wakeup_cpu(apicid, start_ip); + if (apic->wakeup_secondary_cpu) + boot_error = apic->wakeup_secondary_cpu(apicid, start_ip); + else + boot_error = wakeup_secondary_cpu_via_init(apicid, start_ip); if (!boot_error) { /* -- cgit From 0b1da1c8fc1a0cb71f17701efad06855a059f752 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 26 Feb 2009 14:10:10 +0100 Subject: x86: apic: simplify secondary CPU wakeup methods, fix Impact: build fix init_deasserted is only available on SMP. Make the secondary-wakeup function conditional on SMP. Also clean up the file some. Cc: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic/x2apic_uv_x.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 7151de74a39..1bd6da1f8fa 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -7,28 +7,28 @@ * * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved. */ - -#include -#include -#include #include +#include +#include +#include +#include +#include #include #include -#include #include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include + #include #include +#include +#include #include +#include +#include +#include +#include DEFINE_PER_CPU(int, x2apic_extra_bits); @@ -93,6 +93,7 @@ static void uv_vector_allocation_domain(int cpu, struct cpumask *retmask) static int uv_wakeup_secondary(int phys_apicid, unsigned long start_rip) { +#ifdef CONFIG_SMP unsigned long val; int pnode; @@ -111,7 +112,7 @@ static int uv_wakeup_secondary(int phys_apicid, unsigned long start_rip) uv_write_global_mmr64(pnode, UVH_IPI_INT, val); atomic_set(&init_deasserted, 1); - +#endif return 0; } @@ -368,7 +369,7 @@ static __init void map_high(char *id, unsigned long base, int shift, paddr = base << shift; bytes = (1UL << shift) * (max_pnode + 1); printk(KERN_INFO "UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr, - paddr + bytes); + paddr + bytes); if (map_type == map_uc) init_extra_mapping_uc(paddr, bytes); else @@ -531,7 +532,7 @@ late_initcall(uv_init_heartbeat); /* * Called on each cpu to initialize the per_cpu UV data area. - * ZZZ hotplug not supported yet + * FIXME: hotplug not supported yet */ void __cpuinit uv_cpu_init(void) { -- cgit From cac64d00c256e65776d575e82aaf540632b66178 Mon Sep 17 00:00:00 2001 From: Hiroshi Shimamoto Date: Wed, 25 Feb 2009 09:59:26 -0800 Subject: sched_rt: don't start timer when rt bandwidth disabled Impact: fix incorrect condition check No need to start rt bandwidth timer when rt bandwidth is disabled. If this timer starts, it may stop at sched_rt_period_timer() on the first time. Signed-off-by: Hiroshi Shimamoto Acked-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- kernel/sched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched.c b/kernel/sched.c index 410eec40413..c3baa9653d1 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -223,7 +223,7 @@ static void start_rt_bandwidth(struct rt_bandwidth *rt_b) { ktime_t now; - if (rt_bandwidth_enabled() && rt_b->rt_runtime == RUNTIME_INF) + if (!rt_bandwidth_enabled() || rt_b->rt_runtime == RUNTIME_INF) return; if (hrtimer_active(&rt_b->rt_period_timer)) -- cgit From 3b900d44190c7da8681101c57a5be6b354dab2c7 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 26 Feb 2009 14:34:08 +0100 Subject: x86: fix !ACPI build for es7000_32.c arch/x86/kernel/apic/es7000_32.c:702: error: 'es7000_acpi_madt_oem_check_cluster' undeclared here (not in a function) Provide a es7000_acpi_madt_oem_check_cluster() definition in the !ACPI case too. Cc: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic/es7000_32.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index b4838ed3f26..da37e2c59fe 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c @@ -332,8 +332,9 @@ static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id) return ret && !es7000_apic_is_cluster(); } -static int __init es7000_acpi_madt_oem_check_cluster(char *oem_id, - char *oem_table_id) + +static int __init +es7000_acpi_madt_oem_check_cluster(char *oem_id, char *oem_table_id) { int ret = es7000_acpi_ret; @@ -345,6 +346,12 @@ static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return 0; } + +static int __init +es7000_acpi_madt_oem_check_cluster(char *oem_id, char *oem_table_id) +{ + return 0; +} #endif /* !CONFIG_ACPI */ static void es7000_spin(int n) -- cgit From 86883c2736e9697a38080a31c2794fa1316fd68f Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 26 Feb 2009 10:32:31 -0800 Subject: Make ieee1394_init a fs-initcall It needs to happen before any firewire driver actually registers itself, and that was previously handled by having the Makefile list the core ieee1394 files before the drivers. But now there are firewire drivers in drivers/media, and the Makefile games aren't enough. So just make ieee1394_init happen earlier in the init sequence, the way all other bus layers already do. Reported-and-tested-by: Ingo Molnar Cc: Stefan Richter Cc: Henrik Kurelid Cc: Mauro Carvalho Chehab Cc: Ben Backx Signed-off-by: Linus Torvalds --- drivers/ieee1394/ieee1394_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c index 1028e725a27..87233800372 100644 --- a/drivers/ieee1394/ieee1394_core.c +++ b/drivers/ieee1394/ieee1394_core.c @@ -1275,7 +1275,7 @@ static void __exit ieee1394_cleanup(void) unregister_chrdev_region(IEEE1394_CORE_DEV, 256); } -module_init(ieee1394_init); +fs_initcall(ieee1394_init); module_exit(ieee1394_cleanup); /* Exported symbols */ -- cgit From 47be12e4eec84c1846f29af64fe25a396b57a026 Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Fri, 9 Jan 2009 07:32:48 +0800 Subject: ocfs2: Access and dirty the buffer_head in mark_written. In __ocfs2_mark_extent_written, when we meet with the situation of c_split_covers_rec, the old solution just replace the extent record and forget to access and dirty the buffer_head. This will cause a problem when the unwritten extent is in an extent block. So access and dirty it. Signed-off-by: Tao Ma Signed-off-by: Mark Fasheh --- fs/ocfs2/alloc.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 60fe74035db..3a9e5deed74 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c @@ -4796,6 +4796,29 @@ out: return ret; } +static int ocfs2_replace_extent_rec(struct inode *inode, + handle_t *handle, + struct ocfs2_path *path, + struct ocfs2_extent_list *el, + int split_index, + struct ocfs2_extent_rec *split_rec) +{ + int ret; + + ret = ocfs2_path_bh_journal_access(handle, inode, path, + path_num_items(path) - 1); + if (ret) { + mlog_errno(ret); + goto out; + } + + el->l_recs[split_index] = *split_rec; + + ocfs2_journal_dirty(handle, path_leaf_bh(path)); +out: + return ret; +} + /* * Mark part or all of the extent record at split_index in the leaf * pointed to by path as written. This removes the unwritten @@ -4885,7 +4908,9 @@ static int __ocfs2_mark_extent_written(struct inode *inode, if (ctxt.c_contig_type == CONTIG_NONE) { if (ctxt.c_split_covers_rec) - el->l_recs[split_index] = *split_rec; + ret = ocfs2_replace_extent_rec(inode, handle, + path, el, + split_index, split_rec); else ret = ocfs2_split_and_insert(inode, handle, path, et, &last_eb_bh, split_index, -- cgit From 7dc102b737e9f49dac426161294cb2d326a97d8e Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Tue, 3 Feb 2009 12:37:13 -0800 Subject: ocfs2/dlm: Retract fix for race between purge and migrate Mainline commit d4f7e650e55af6b235871126f747da88600e8040 attempts to delay the dlm_thread from sending the drop ref message if the lockres is being migrated. The problem is that we make the dlm_thread wait for the migration to complete. This causes a deadlock as dlm_thread also participates in the lockres migration process. A better fix for the original oss bugzilla#1012 is in testing. Signed-off-by: Sunil Mushran Acked-by: Joel Becker Signed-off-by: Mark Fasheh --- fs/ocfs2/dlm/dlmthread.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c index d1295203029..4060bb328bc 100644 --- a/fs/ocfs2/dlm/dlmthread.c +++ b/fs/ocfs2/dlm/dlmthread.c @@ -181,8 +181,7 @@ static int dlm_purge_lockres(struct dlm_ctxt *dlm, spin_lock(&res->spinlock); /* This ensures that clear refmap is sent after the set */ - __dlm_wait_on_lockres_flags(res, (DLM_LOCK_RES_SETREF_INPROG | - DLM_LOCK_RES_MIGRATING)); + __dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG); spin_unlock(&res->spinlock); /* clear our bit from the master's refmap, ignore errors */ -- cgit From c74ff8bb2235d848beb67fcfddae71ecbe3f92b1 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Tue, 3 Feb 2009 12:37:14 -0800 Subject: ocfs2: Cleanup the lockname print in dlmglue.c The dentry lock has a different format than other locks. This patch fixes ocfs2_log_dlm_error() macro to make it print the dentry lock correctly. Signed-off-by: Sunil Mushran Acked-by: Joel Becker Signed-off-by: Mark Fasheh --- fs/ocfs2/dlmglue.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 206a2370876..7219a86d34c 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c @@ -320,9 +320,14 @@ static void ocfs2_schedule_blocked_lock(struct ocfs2_super *osb, struct ocfs2_lock_res *lockres); static inline void ocfs2_recover_from_dlm_error(struct ocfs2_lock_res *lockres, int convert); -#define ocfs2_log_dlm_error(_func, _err, _lockres) do { \ - mlog(ML_ERROR, "DLM error %d while calling %s on resource %s\n", \ - _err, _func, _lockres->l_name); \ +#define ocfs2_log_dlm_error(_func, _err, _lockres) do { \ + if ((_lockres)->l_type != OCFS2_LOCK_TYPE_DENTRY) \ + mlog(ML_ERROR, "DLM error %d while calling %s on resource %s\n", \ + _err, _func, _lockres->l_name); \ + else \ + mlog(ML_ERROR, "DLM error %d while calling %s on resource %.*s%08x\n", \ + _err, _func, OCFS2_DENTRY_LOCK_INO_START - 1, (_lockres)->l_name, \ + (unsigned int)ocfs2_get_dentry_lock_ino(_lockres)); \ } while (0) static int ocfs2_downconvert_thread(void *arg); static void ocfs2_downconvert_on_unlock(struct ocfs2_super *osb, -- cgit From dabc47de7a23f57522dc762d9d2ad875700d3497 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Tue, 3 Feb 2009 12:37:15 -0800 Subject: ocfs2/dlm: Use ast_lock to protect ast_list The code was using dlm->spinlock instead of dlm->ast_lock to protect the ast_list. This patch fixes the issue. Signed-off-by: Sunil Mushran Acked-by: Joel Becker Signed-off-by: Mark Fasheh --- fs/ocfs2/dlm/dlmunlock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/ocfs2/dlm/dlmunlock.c b/fs/ocfs2/dlm/dlmunlock.c index 86ca085ef32..fcf879ed693 100644 --- a/fs/ocfs2/dlm/dlmunlock.c +++ b/fs/ocfs2/dlm/dlmunlock.c @@ -117,11 +117,11 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm, else BUG_ON(res->owner == dlm->node_num); - spin_lock(&dlm->spinlock); + spin_lock(&dlm->ast_lock); /* We want to be sure that we're not freeing a lock * that still has AST's pending... */ in_use = !list_empty(&lock->ast_list); - spin_unlock(&dlm->spinlock); + spin_unlock(&dlm->ast_lock); if (in_use) { mlog(ML_ERROR, "lockres %.*s: Someone is calling dlmunlock " "while waiting for an ast!", res->lockname.len, -- cgit From 53ecd25e148615e0ed2a72635cc76f4773f97f90 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Tue, 3 Feb 2009 12:37:16 -0800 Subject: ocfs2/dlm: Make dlm_assert_master_handler() kill itself instead of the asserter In dlm_assert_master_handler(), if we get an incorrect assert master from a node that, we reply with EINVAL asking the asserter to die. The problem is that an assert is sent after so many hoops, it is invariably the node that thinks the asserter is wrong, is actually wrong. So instead of killing the asserter, this patch kills the assertee. This patch papers over a race that is still being addressed. Signed-off-by: Sunil Mushran Acked-by: Joel Becker Signed-off-by: Mark Fasheh --- fs/ocfs2/dlm/dlmmaster.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 54e182a27ca..0a281394785 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c @@ -1849,12 +1849,12 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data, if (!mle) { if (res->owner != DLM_LOCK_RES_OWNER_UNKNOWN && res->owner != assert->node_idx) { - mlog(ML_ERROR, "assert_master from " - "%u, but current owner is " - "%u! (%.*s)\n", - assert->node_idx, res->owner, - namelen, name); - goto kill; + mlog(ML_ERROR, "DIE! Mastery assert from %u, " + "but current owner is %u! (%.*s)\n", + assert->node_idx, res->owner, namelen, + name); + __dlm_print_one_lock_resource(res); + BUG(); } } else if (mle->type != DLM_MLE_MIGRATION) { if (res->owner != DLM_LOCK_RES_OWNER_UNKNOWN) { -- cgit From 89a907afe073b8971a83d0ad54f391542b64d327 Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Tue, 17 Feb 2009 04:39:28 +0800 Subject: ocfs2: Use the right access_* method in ctime update of xattr. In ctime updating of xattr, it use the wrong type of access for inode, so use ocfs2_journal_access_di instead. Reported-and-Tested-by: Tristan Ye Signed-off-by: Tao Ma Acked-by: Joel Becker Signed-off-by: Mark Fasheh --- fs/ocfs2/xattr.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 915039fffe6..e3933158e1d 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c @@ -2592,8 +2592,9 @@ static int __ocfs2_xattr_set_handle(struct inode *inode, if (!ret) { /* Update inode ctime. */ - ret = ocfs2_journal_access(ctxt->handle, inode, xis->inode_bh, - OCFS2_JOURNAL_ACCESS_WRITE); + ret = ocfs2_journal_access_di(ctxt->handle, inode, + xis->inode_bh, + OCFS2_JOURNAL_ACCESS_WRITE); if (ret) { mlog_errno(ret); goto out; -- cgit From c8b9cf9a7cd25ba65166116d0a958f0bc709f0a7 Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Tue, 24 Feb 2009 17:40:26 -0800 Subject: ocfs2: lock the metaecc process for xattr bucket For other metadata in ocfs2, metaecc is checked in ocfs2_read_blocks with io_mutex held. While for xattr bucket, it is calculated by the whole buckets. So we have to add a spin_lock to prevent multiple processes calculating metaecc. Signed-off-by: Tao Ma Tested-by: Tristan Ye Signed-off-by: Mark Fasheh --- fs/ocfs2/ocfs2.h | 3 +++ fs/ocfs2/super.c | 1 + fs/ocfs2/xattr.c | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index 077384135f4..946d3c34b90 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h @@ -341,6 +341,9 @@ struct ocfs2_super struct ocfs2_node_map osb_recovering_orphan_dirs; unsigned int *osb_orphan_wipes; wait_queue_head_t osb_wipe_event; + + /* used to protect metaecc calculation check of xattr. */ + spinlock_t osb_xattr_lock; }; #define OCFS2_SB(sb) ((struct ocfs2_super *)(sb)->s_fs_info) diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index b1cb38fbe80..1c3acc4654d 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -1747,6 +1747,7 @@ static int ocfs2_initialize_super(struct super_block *sb, INIT_LIST_HEAD(&osb->blocked_lock_list); osb->blocked_lock_count = 0; spin_lock_init(&osb->osb_lock); + spin_lock_init(&osb->osb_xattr_lock); ocfs2_init_inode_steal_slot(osb); atomic_set(&osb->alloc_stats.moves, 0); diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index e3933158e1d..a7c167905c5 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c @@ -274,10 +274,12 @@ static int ocfs2_read_xattr_bucket(struct ocfs2_xattr_bucket *bucket, bucket->bu_blocks, bucket->bu_bhs, 0, NULL); if (!rc) { + spin_lock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock); rc = ocfs2_validate_meta_ecc_bhs(bucket->bu_inode->i_sb, bucket->bu_bhs, bucket->bu_blocks, &bucket_xh(bucket)->xh_check); + spin_unlock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock); if (rc) mlog_errno(rc); } @@ -310,9 +312,11 @@ static void ocfs2_xattr_bucket_journal_dirty(handle_t *handle, { int i; + spin_lock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock); ocfs2_compute_meta_ecc_bhs(bucket->bu_inode->i_sb, bucket->bu_bhs, bucket->bu_blocks, &bucket_xh(bucket)->xh_check); + spin_unlock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock); for (i = 0; i < bucket->bu_blocks; i++) ocfs2_journal_dirty(handle, bucket->bu_bhs[i]); -- cgit From 4442f518269c6b3686fcbcadad22dc4475309b16 Mon Sep 17 00:00:00 2001 From: Tiger Yang Date: Fri, 20 Feb 2009 11:11:50 +0800 Subject: ocfs2: set gap to seperate entry and value when xattr in bucket This patch set a gap (4 bytes) between xattr entry and name/value when xattr in bucket. This gap use to seperate entry and name/value when a bucket is full. It had already been set when xattr in inode/block. Signed-off-by: Tiger Yang Signed-off-by: Mark Fasheh --- fs/ocfs2/xattr.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index a7c167905c5..4ddd788add6 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c @@ -82,13 +82,14 @@ struct ocfs2_xattr_set_ctxt { #define OCFS2_XATTR_ROOT_SIZE (sizeof(struct ocfs2_xattr_def_value_root)) #define OCFS2_XATTR_INLINE_SIZE 80 +#define OCFS2_XATTR_HEADER_GAP 4 #define OCFS2_XATTR_FREE_IN_IBODY (OCFS2_MIN_XATTR_INLINE_SIZE \ - sizeof(struct ocfs2_xattr_header) \ - - sizeof(__u32)) + - OCFS2_XATTR_HEADER_GAP) #define OCFS2_XATTR_FREE_IN_BLOCK(ptr) ((ptr)->i_sb->s_blocksize \ - sizeof(struct ocfs2_xattr_block) \ - sizeof(struct ocfs2_xattr_header) \ - - sizeof(__u32)) + - OCFS2_XATTR_HEADER_GAP) static struct ocfs2_xattr_def_value_root def_xv = { .xv.xr_list.l_count = cpu_to_le16(1), @@ -1511,7 +1512,7 @@ static int ocfs2_xattr_set_entry(struct inode *inode, last += 1; } - free = min_offs - ((void *)last - xs->base) - sizeof(__u32); + free = min_offs - ((void *)last - xs->base) - OCFS2_XATTR_HEADER_GAP; if (free < 0) return -EIO; @@ -2194,7 +2195,7 @@ static int ocfs2_xattr_can_be_in_inode(struct inode *inode, last += 1; } - free = min_offs - ((void *)last - xs->base) - sizeof(__u32); + free = min_offs - ((void *)last - xs->base) - OCFS2_XATTR_HEADER_GAP; if (free < 0) return 0; @@ -5065,8 +5066,8 @@ try_again: xh_free_start = le16_to_cpu(xh->xh_free_start); header_size = sizeof(struct ocfs2_xattr_header) + count * sizeof(struct ocfs2_xattr_entry); - max_free = OCFS2_XATTR_BUCKET_SIZE - - le16_to_cpu(xh->xh_name_value_len) - header_size; + max_free = OCFS2_XATTR_BUCKET_SIZE - header_size - + le16_to_cpu(xh->xh_name_value_len) - OCFS2_XATTR_HEADER_GAP; mlog_bug_on_msg(header_size > blocksize, "bucket %llu has header size " "of %u which exceed block size\n", @@ -5099,7 +5100,7 @@ try_again: need = 0; } - free = xh_free_start - header_size; + free = xh_free_start - header_size - OCFS2_XATTR_HEADER_GAP; /* * We need to make sure the new name/value pair * can exist in the same block. @@ -5132,7 +5133,8 @@ try_again: } xh_free_start = le16_to_cpu(xh->xh_free_start); - free = xh_free_start - header_size; + free = xh_free_start - header_size + - OCFS2_XATTR_HEADER_GAP; if (xh_free_start % blocksize < need) free -= xh_free_start % blocksize; -- cgit From 28d57d437786eb3e44f1ca3f0f41e7cfe29c6dd4 Mon Sep 17 00:00:00 2001 From: wengang wang Date: Fri, 13 Feb 2009 10:11:47 +0800 Subject: ocfs2: add IO error check in ocfs2_get_sector() Check for IO error in ocfs2_get_sector(). Signed-off-by: Wengang Wang Signed-off-by: Mark Fasheh --- fs/ocfs2/super.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 1c3acc4654d..7ac83a81ee5 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -1537,6 +1537,13 @@ static int ocfs2_get_sector(struct super_block *sb, unlock_buffer(*bh); ll_rw_block(READ, 1, bh); wait_on_buffer(*bh); + if (!buffer_uptodate(*bh)) { + mlog_errno(-EIO); + brelse(*bh); + *bh = NULL; + return -EIO; + } + return 0; } -- cgit From b50be33e42e2c87812b30aee1a2b2a5ac6cb3ffa Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 27 Feb 2009 04:51:33 +0900 Subject: [MTD] [MAPS] Remove MODULE_DEVICE_TABLE() from ck804rom driver. We really don't want the BIOS flash mapping hacks to get automatically loaded. No idea why it isn't using pci_register_driver() though -- that should be fine... and is even _present_ but disabled by #if 0. Signed-off-by: David Woodhouse --- drivers/mtd/maps/ck804xrom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/maps/ck804xrom.c b/drivers/mtd/maps/ck804xrom.c index 5f7a245ed13..424f17d6ffd 100644 --- a/drivers/mtd/maps/ck804xrom.c +++ b/drivers/mtd/maps/ck804xrom.c @@ -342,9 +342,9 @@ static struct pci_device_id ck804xrom_pci_tbl[] = { { 0, } }; +#if 0 MODULE_DEVICE_TABLE(pci, ck804xrom_pci_tbl); -#if 0 static struct pci_driver ck804xrom_driver = { .name = MOD_NAME, .id_table = ck804xrom_pci_tbl, -- cgit From f6be37fdc62d0c0214bc49815d1180ebfbd716e2 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Thu, 26 Feb 2009 12:57:56 -0500 Subject: x86: enable DMAR by default Now that the obvious bugs have been worked out, specifically the iwlagn issue, and the write buffer errata, DMAR should be safe to turn back on by default. (We've had it on since those patches were first written a few weeks ago, without any noticeable bug reports (most have been due to the dma-api debug patchset.)) Signed-off-by: Kyle McMartin Acked-by: David Woodhouse Signed-off-by: Ingo Molnar --- arch/x86/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 9c39095b33f..bc2fbadff9f 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1803,7 +1803,7 @@ config DMAR remapping devices. config DMAR_DEFAULT_ON - def_bool n + def_bool y prompt "Enable DMA Remapping Devices by default" depends on DMAR help -- cgit From ab65f649d38d910f48843a275f3f0596cdbf28bf Mon Sep 17 00:00:00 2001 From: Kiran Divekar Date: Thu, 19 Feb 2009 19:32:39 -0500 Subject: libertas: fix misuse of netdev_priv() and dev->ml_priv The mesh and radiotap interfaces need to use the same private data as the main wifi interface. If the main wifi interface uses netdev_priv(), but the other interfaces ->ml_priv, there's no way to figure out where the private data actually is in the WEXT handlers and netdevice callbacks. So make everything use ->ml_priv. Fixes botched netdev_priv() conversion introduced by "netdevice libertas: Fix directly reference of netdev->priv", though admittedly libertas' use of ->priv was somewhat "special". Signed-off-by: Kiran Divekar Acked-by: Dan Williams Tested-by: Chris Ball Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/ethtool.c | 12 ++--- drivers/net/wireless/libertas/if_usb.c | 4 +- drivers/net/wireless/libertas/main.c | 31 ++++++------- drivers/net/wireless/libertas/persistcfg.c | 16 +++---- drivers/net/wireless/libertas/scan.c | 4 +- drivers/net/wireless/libertas/tx.c | 2 +- drivers/net/wireless/libertas/wext.c | 72 +++++++++++++++--------------- 7 files changed, 71 insertions(+), 70 deletions(-) diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c index 61d2f50470c..b118a35ec60 100644 --- a/drivers/net/wireless/libertas/ethtool.c +++ b/drivers/net/wireless/libertas/ethtool.c @@ -23,7 +23,7 @@ static const char * mesh_stat_strings[]= { static void lbs_ethtool_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; snprintf(info->fw_version, 32, "%u.%u.%u.p%u", priv->fwrelease >> 24 & 0xff, @@ -47,7 +47,7 @@ static int lbs_ethtool_get_eeprom_len(struct net_device *dev) static int lbs_ethtool_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 * bytes) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; struct cmd_ds_802_11_eeprom_access cmd; int ret; @@ -76,7 +76,7 @@ out: static void lbs_ethtool_get_stats(struct net_device *dev, struct ethtool_stats *stats, uint64_t *data) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; struct cmd_ds_mesh_access mesh_access; int ret; @@ -113,7 +113,7 @@ static void lbs_ethtool_get_stats(struct net_device *dev, static int lbs_ethtool_get_sset_count(struct net_device *dev, int sset) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; if (sset == ETH_SS_STATS && dev == priv->mesh_dev) return MESH_STATS_NUM; @@ -143,7 +143,7 @@ static void lbs_ethtool_get_strings(struct net_device *dev, static void lbs_ethtool_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; if (priv->wol_criteria == 0xffffffff) { /* Interface driver didn't configure wake */ @@ -166,7 +166,7 @@ static void lbs_ethtool_get_wol(struct net_device *dev, static int lbs_ethtool_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; uint32_t criteria = 0; if (priv->wol_criteria == 0xffffffff && wol->wolopts) diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index 2fc637ad85c..ea3dc038be7 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c @@ -59,7 +59,7 @@ static int if_usb_reset_device(struct if_usb_card *cardp); static ssize_t if_usb_firmware_set(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct lbs_private *priv = to_net_dev(dev)->ml_priv; struct if_usb_card *cardp = priv->card; char fwname[FIRMWARE_NAME_MAX]; int ret; @@ -86,7 +86,7 @@ static DEVICE_ATTR(lbs_flash_fw, 0200, NULL, if_usb_firmware_set); static ssize_t if_usb_boot2_set(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct lbs_private *priv = to_net_dev(dev)->ml_priv; struct if_usb_card *cardp = priv->card; char fwname[FIRMWARE_NAME_MAX]; int ret; diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 4e0007d2003..f76623e0ff9 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -222,7 +222,7 @@ u8 lbs_data_rate_to_fw_index(u32 rate) static ssize_t lbs_anycast_get(struct device *dev, struct device_attribute *attr, char * buf) { - struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct lbs_private *priv = to_net_dev(dev)->ml_priv; struct cmd_ds_mesh_access mesh_access; int ret; @@ -241,7 +241,7 @@ static ssize_t lbs_anycast_get(struct device *dev, static ssize_t lbs_anycast_set(struct device *dev, struct device_attribute *attr, const char * buf, size_t count) { - struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct lbs_private *priv = to_net_dev(dev)->ml_priv; struct cmd_ds_mesh_access mesh_access; uint32_t datum; int ret; @@ -263,7 +263,7 @@ static ssize_t lbs_anycast_set(struct device *dev, static ssize_t lbs_prb_rsp_limit_get(struct device *dev, struct device_attribute *attr, char *buf) { - struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct lbs_private *priv = to_net_dev(dev)->ml_priv; struct cmd_ds_mesh_access mesh_access; int ret; u32 retry_limit; @@ -286,7 +286,7 @@ static ssize_t lbs_prb_rsp_limit_get(struct device *dev, static ssize_t lbs_prb_rsp_limit_set(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct lbs_private *priv = to_net_dev(dev)->ml_priv; struct cmd_ds_mesh_access mesh_access; int ret; unsigned long retry_limit; @@ -321,7 +321,7 @@ static void lbs_remove_mesh(struct lbs_private *priv); static ssize_t lbs_rtap_get(struct device *dev, struct device_attribute *attr, char * buf) { - struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct lbs_private *priv = to_net_dev(dev)->ml_priv; return snprintf(buf, 5, "0x%X\n", priv->monitormode); } @@ -332,7 +332,7 @@ static ssize_t lbs_rtap_set(struct device *dev, struct device_attribute *attr, const char * buf, size_t count) { int monitor_mode; - struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct lbs_private *priv = to_net_dev(dev)->ml_priv; sscanf(buf, "%x", &monitor_mode); if (monitor_mode) { @@ -383,7 +383,7 @@ static DEVICE_ATTR(lbs_rtap, 0644, lbs_rtap_get, lbs_rtap_set ); static ssize_t lbs_mesh_get(struct device *dev, struct device_attribute *attr, char * buf) { - struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct lbs_private *priv = to_net_dev(dev)->ml_priv; return snprintf(buf, 5, "0x%X\n", !!priv->mesh_dev); } @@ -393,7 +393,7 @@ static ssize_t lbs_mesh_get(struct device *dev, static ssize_t lbs_mesh_set(struct device *dev, struct device_attribute *attr, const char * buf, size_t count) { - struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct lbs_private *priv = to_net_dev(dev)->ml_priv; int enable; int ret, action = CMD_ACT_MESH_CONFIG_STOP; @@ -452,7 +452,7 @@ static struct attribute_group lbs_mesh_attr_group = { */ static int lbs_dev_open(struct net_device *dev) { - struct lbs_private *priv = netdev_priv(dev) ; + struct lbs_private *priv = dev->ml_priv; int ret = 0; lbs_deb_enter(LBS_DEB_NET); @@ -521,7 +521,7 @@ static int lbs_mesh_stop(struct net_device *dev) */ static int lbs_eth_stop(struct net_device *dev) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; lbs_deb_enter(LBS_DEB_NET); @@ -538,7 +538,7 @@ static int lbs_eth_stop(struct net_device *dev) static void lbs_tx_timeout(struct net_device *dev) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; lbs_deb_enter(LBS_DEB_TX); @@ -590,7 +590,7 @@ EXPORT_SYMBOL_GPL(lbs_host_to_card_done); */ static struct net_device_stats *lbs_get_stats(struct net_device *dev) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; lbs_deb_enter(LBS_DEB_NET); return &priv->stats; @@ -599,7 +599,7 @@ static struct net_device_stats *lbs_get_stats(struct net_device *dev) static int lbs_set_mac_address(struct net_device *dev, void *addr) { int ret = 0; - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; struct sockaddr *phwaddr = addr; struct cmd_ds_802_11_mac_address cmd; @@ -732,7 +732,7 @@ static void lbs_set_mcast_worker(struct work_struct *work) static void lbs_set_multicast_list(struct net_device *dev) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; schedule_work(&priv->mcast_work); } @@ -748,7 +748,7 @@ static void lbs_set_multicast_list(struct net_device *dev) static int lbs_thread(void *data) { struct net_device *dev = data; - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; wait_queue_t wait; lbs_deb_enter(LBS_DEB_THREAD); @@ -1184,6 +1184,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev) goto done; } priv = netdev_priv(dev); + dev->ml_priv = priv; if (lbs_init_adapter(priv)) { lbs_pr_err("failed to initialize adapter structure.\n"); diff --git a/drivers/net/wireless/libertas/persistcfg.c b/drivers/net/wireless/libertas/persistcfg.c index d42b7a5a1b3..18fe29faf99 100644 --- a/drivers/net/wireless/libertas/persistcfg.c +++ b/drivers/net/wireless/libertas/persistcfg.c @@ -18,7 +18,7 @@ static int mesh_get_default_parameters(struct device *dev, struct mrvl_mesh_defaults *defs) { - struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct lbs_private *priv = to_net_dev(dev)->ml_priv; struct cmd_ds_mesh_config cmd; int ret; @@ -57,7 +57,7 @@ static ssize_t bootflag_get(struct device *dev, static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct lbs_private *priv = to_net_dev(dev)->ml_priv; struct cmd_ds_mesh_config cmd; uint32_t datum; int ret; @@ -100,7 +100,7 @@ static ssize_t boottime_get(struct device *dev, static ssize_t boottime_set(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct lbs_private *priv = to_net_dev(dev)->ml_priv; struct cmd_ds_mesh_config cmd; uint32_t datum; int ret; @@ -152,7 +152,7 @@ static ssize_t channel_get(struct device *dev, static ssize_t channel_set(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct lbs_private *priv = to_net_dev(dev)->ml_priv; struct cmd_ds_mesh_config cmd; uint32_t datum; int ret; @@ -210,7 +210,7 @@ static ssize_t mesh_id_set(struct device *dev, struct device_attribute *attr, struct cmd_ds_mesh_config cmd; struct mrvl_mesh_defaults defs; struct mrvl_meshie *ie; - struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct lbs_private *priv = to_net_dev(dev)->ml_priv; int len; int ret; @@ -269,7 +269,7 @@ static ssize_t protocol_id_set(struct device *dev, struct cmd_ds_mesh_config cmd; struct mrvl_mesh_defaults defs; struct mrvl_meshie *ie; - struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct lbs_private *priv = to_net_dev(dev)->ml_priv; uint32_t datum; int ret; @@ -323,7 +323,7 @@ static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr, struct cmd_ds_mesh_config cmd; struct mrvl_mesh_defaults defs; struct mrvl_meshie *ie; - struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct lbs_private *priv = to_net_dev(dev)->ml_priv; uint32_t datum; int ret; @@ -377,7 +377,7 @@ static ssize_t capability_set(struct device *dev, struct device_attribute *attr, struct cmd_ds_mesh_config cmd; struct mrvl_mesh_defaults defs; struct mrvl_meshie *ie; - struct lbs_private *priv = netdev_priv(to_net_dev(dev)); + struct lbs_private *priv = to_net_dev(dev)->ml_priv; uint32_t datum; int ret; diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index 57f6c12cda2..9014950f432 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c @@ -945,7 +945,7 @@ int lbs_set_scan(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { DECLARE_SSID_BUF(ssid); - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; int ret = 0; lbs_deb_enter(LBS_DEB_WEXT); @@ -1008,7 +1008,7 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra) { #define SCAN_ITEM_SIZE 128 - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; int err = 0; char *ev = extra; char *stop = ev + dwrq->length; diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c index dac46264117..68bec31ae03 100644 --- a/drivers/net/wireless/libertas/tx.c +++ b/drivers/net/wireless/libertas/tx.c @@ -60,7 +60,7 @@ static u32 convert_radiotap_rate_to_mv(u8 rate) int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { unsigned long flags; - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; struct txpd *txpd; char *p802x_hdr; uint16_t pkt_len; diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c index c6102e08179..f16d136ab4b 100644 --- a/drivers/net/wireless/libertas/wext.c +++ b/drivers/net/wireless/libertas/wext.c @@ -163,7 +163,7 @@ static int lbs_get_name(struct net_device *dev, struct iw_request_info *info, static int lbs_get_freq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *fwrq, char *extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; struct chan_freq_power *cfp; lbs_deb_enter(LBS_DEB_WEXT); @@ -189,7 +189,7 @@ static int lbs_get_freq(struct net_device *dev, struct iw_request_info *info, static int lbs_get_wap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *awrq, char *extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; lbs_deb_enter(LBS_DEB_WEXT); @@ -207,7 +207,7 @@ static int lbs_get_wap(struct net_device *dev, struct iw_request_info *info, static int lbs_set_nick(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; lbs_deb_enter(LBS_DEB_WEXT); @@ -231,7 +231,7 @@ static int lbs_set_nick(struct net_device *dev, struct iw_request_info *info, static int lbs_get_nick(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; lbs_deb_enter(LBS_DEB_WEXT); @@ -248,7 +248,7 @@ static int lbs_get_nick(struct net_device *dev, struct iw_request_info *info, static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; lbs_deb_enter(LBS_DEB_WEXT); @@ -273,7 +273,7 @@ static int lbs_set_rts(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { int ret = 0; - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; u32 val = vwrq->value; lbs_deb_enter(LBS_DEB_WEXT); @@ -293,7 +293,7 @@ static int lbs_set_rts(struct net_device *dev, struct iw_request_info *info, static int lbs_get_rts(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; int ret = 0; u16 val = 0; @@ -315,7 +315,7 @@ out: static int lbs_set_frag(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; int ret = 0; u32 val = vwrq->value; @@ -336,7 +336,7 @@ static int lbs_set_frag(struct net_device *dev, struct iw_request_info *info, static int lbs_get_frag(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; int ret = 0; u16 val = 0; @@ -359,7 +359,7 @@ out: static int lbs_get_mode(struct net_device *dev, struct iw_request_info *info, u32 * uwrq, char *extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; lbs_deb_enter(LBS_DEB_WEXT); @@ -385,7 +385,7 @@ static int lbs_get_txpow(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; s16 curlevel = 0; int ret = 0; @@ -418,7 +418,7 @@ out: static int lbs_set_retry(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; int ret = 0; u16 slimit = 0, llimit = 0; @@ -466,7 +466,7 @@ out: static int lbs_get_retry(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; int ret = 0; u16 val = 0; @@ -542,7 +542,7 @@ static int lbs_get_range(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra) { int i, j; - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; struct iw_range *range = (struct iw_range *)extra; struct chan_freq_power *cfp; u8 rates[MAX_RATES + 1]; @@ -708,7 +708,7 @@ out: static int lbs_set_power(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; lbs_deb_enter(LBS_DEB_WEXT); @@ -758,7 +758,7 @@ static int lbs_set_power(struct net_device *dev, struct iw_request_info *info, static int lbs_get_power(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; lbs_deb_enter(LBS_DEB_WEXT); @@ -781,7 +781,7 @@ static struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev) EXCELLENT = 95, PERFECT = 100 }; - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; u32 rssi_qual; u32 tx_qual; u32 quality = 0; @@ -886,7 +886,7 @@ static int lbs_set_freq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *fwrq, char *extra) { int ret = -EINVAL; - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; struct chan_freq_power *cfp; struct assoc_request * assoc_req; @@ -943,7 +943,7 @@ static int lbs_mesh_set_freq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *fwrq, char *extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; struct chan_freq_power *cfp; int ret = -EINVAL; @@ -994,7 +994,7 @@ out: static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; u8 new_rate = 0; int ret = -EINVAL; u8 rates[MAX_RATES + 1]; @@ -1054,7 +1054,7 @@ out: static int lbs_get_rate(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; lbs_deb_enter(LBS_DEB_WEXT); @@ -1079,7 +1079,7 @@ static int lbs_set_mode(struct net_device *dev, struct iw_request_info *info, u32 * uwrq, char *extra) { int ret = 0; - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; struct assoc_request * assoc_req; lbs_deb_enter(LBS_DEB_WEXT); @@ -1124,7 +1124,7 @@ static int lbs_get_encode(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, u8 * extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; lbs_deb_enter(LBS_DEB_WEXT); @@ -1319,7 +1319,7 @@ static int lbs_set_encode(struct net_device *dev, struct iw_point *dwrq, char *extra) { int ret = 0; - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; struct assoc_request * assoc_req; u16 is_default = 0, index = 0, set_tx_key = 0; @@ -1395,7 +1395,7 @@ static int lbs_get_encodeext(struct net_device *dev, char *extra) { int ret = -EINVAL; - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; int index, max_key_len; @@ -1501,7 +1501,7 @@ static int lbs_set_encodeext(struct net_device *dev, char *extra) { int ret = 0; - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; int alg = ext->alg; struct assoc_request * assoc_req; @@ -1639,7 +1639,7 @@ static int lbs_set_genie(struct net_device *dev, struct iw_point *dwrq, char *extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; int ret = 0; struct assoc_request * assoc_req; @@ -1685,7 +1685,7 @@ static int lbs_get_genie(struct net_device *dev, char *extra) { int ret = 0; - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; lbs_deb_enter(LBS_DEB_WEXT); @@ -1713,7 +1713,7 @@ static int lbs_set_auth(struct net_device *dev, struct iw_param *dwrq, char *extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; struct assoc_request * assoc_req; int ret = 0; int updated = 0; @@ -1816,7 +1816,7 @@ static int lbs_get_auth(struct net_device *dev, char *extra) { int ret = 0; - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; lbs_deb_enter(LBS_DEB_WEXT); @@ -1857,7 +1857,7 @@ static int lbs_set_txpow(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { int ret = 0; - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; s16 dbm = (s16) vwrq->value; lbs_deb_enter(LBS_DEB_WEXT); @@ -1936,7 +1936,7 @@ out: static int lbs_get_essid(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; lbs_deb_enter(LBS_DEB_WEXT); @@ -1971,7 +1971,7 @@ static int lbs_get_essid(struct net_device *dev, struct iw_request_info *info, static int lbs_set_essid(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; int ret = 0; u8 ssid[IW_ESSID_MAX_SIZE]; u8 ssid_len = 0; @@ -2040,7 +2040,7 @@ static int lbs_mesh_get_essid(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; lbs_deb_enter(LBS_DEB_WEXT); @@ -2058,7 +2058,7 @@ static int lbs_mesh_set_essid(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; int ret = 0; lbs_deb_enter(LBS_DEB_WEXT); @@ -2102,7 +2102,7 @@ static int lbs_mesh_set_essid(struct net_device *dev, static int lbs_set_wap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *awrq, char *extra) { - struct lbs_private *priv = netdev_priv(dev); + struct lbs_private *priv = dev->ml_priv; struct assoc_request * assoc_req; int ret = 0; -- cgit From bbe194433baeadc953f49e3795b41ffffc5486dd Mon Sep 17 00:00:00 2001 From: Stefan Assmann Date: Thu, 26 Feb 2009 10:46:48 -0800 Subject: PCI: AMD 813x B2 devices do not need boot interrupt quirk Turns out that the new AMD 813x devices do not need the quirk_disable_amd_813x_boot_interrupt quirk to be run on them. If it is, no interrupts are seen on the PCI-X adapter. From: Stefan Assmann Reported-by: Jamie Wellnitz Tested-by: Jamie Wellnitz Cc: stable Signed-off-by: Greg Kroah-Hartman Signed-off-by: Jesse Barnes --- drivers/pci/quirks.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index a8523294e4a..f20d55368ed 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1584,6 +1584,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_ */ #define AMD_813X_MISC 0x40 #define AMD_813X_NOIOAMODE (1<<0) +#define AMD_813X_REV_B2 0x13 static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) { @@ -1591,6 +1592,8 @@ static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) if (noioapicquirk) return; + if (dev->revision == AMD_813X_REV_B2) + return; pci_read_config_dword(dev, AMD_813X_MISC, &pci_config_dword); pci_config_dword &= ~AMD_813X_NOIOAMODE; -- cgit From 1ac00cc21337b0b667493d9af79d88537de90aa3 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sun, 1 Feb 2009 14:24:18 +0000 Subject: powerpc/44x: Fix address decoding setup of PCI 2.x cells The PCI 2.x cells used on some 44x SoCs only let us configure the decode for the low 32-bit of the incoming PLB addresses. The top 4 bits (this is a 36-bit bus) are hard wired to different values depending on the specific SoC in use. Our code used to work "by accident" until I added support for the ISA memory holes and while at it added more validity checking of the addresses. This patch should bring it back to working condition. It still relies on the device-tree being correct but that's somewhat a pre-requisite for anything to work anyway. Signed-off-by: Benjamin Herrenschmidt Acked-by: Geert Uytterhoeven Acked-by: Josh Boyer --- arch/powerpc/sysdev/ppc4xx_pci.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c index 77fae5f64f2..5558d932b4d 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/sysdev/ppc4xx_pci.c @@ -204,6 +204,23 @@ static int __init ppc4xx_setup_one_pci_PMM(struct pci_controller *hose, { u32 ma, pcila, pciha; + /* Hack warning ! The "old" PCI 2.x cell only let us configure the low + * 32-bit of incoming PLB addresses. The top 4 bits of the 36-bit + * address are actually hard wired to a value that appears to depend + * on the specific SoC. For example, it's 0 on 440EP and 1 on 440EPx. + * + * The trick here is we just crop those top bits and ignore them when + * programming the chip. That means the device-tree has to be right + * for the specific part used (we don't print a warning if it's wrong + * but on the other hand, you'll crash quickly enough), but at least + * this code should work whatever the hard coded value is + */ + plb_addr &= 0xffffffffull; + + /* Note: Due to the above hack, the test below doesn't actually test + * if you address is above 4G, but it tests that address and + * (address + size) are both contained in the same 4G + */ if ((plb_addr + size) > 0xffffffffull || !is_power_of_2(size) || size < 0x1000 || (plb_addr & (size - 1)) != 0) { printk(KERN_WARNING "%s: Resource out of range\n", -- cgit From 7662b00c378fe638e84a853418cd833303fc050c Mon Sep 17 00:00:00 2001 From: Nicola Soranzo Date: Thu, 19 Feb 2009 13:41:56 -0300 Subject: V4L/DVB (10659): em28xx: register device to soundcard for sysfs As explained in "Writing an ALSA driver" (T. Iwai), audio drivers should set the struct device for the card before registering the card instance. This will add the correct /sys/class/sound/cardN/device symlink, so HAL can see the device and ConsoleKit sets its ACL permissions for the logged-in user. For em28xx audio capture cards found e.g. in Hauppauge WinTV-HVR-900 (R2), this patch fixes errors like: ALSA lib pcm_hw.c:1429:(_snd_pcm_hw_open) Invalid value for card Error opening audio: Permission denied when running mplayer as a normal user. Signed-off-by: Nicola Soranzo Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-audio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c index 5d882a44e3e..2ac738fa6a0 100644 --- a/drivers/media/video/em28xx/em28xx-audio.c +++ b/drivers/media/video/em28xx/em28xx-audio.c @@ -463,6 +463,8 @@ static int em28xx_audio_init(struct em28xx *dev) pcm->info_flags = 0; pcm->private_data = dev; strcpy(pcm->name, "Empia 28xx Capture"); + + snd_card_set_dev(card, &dev->udev->dev); strcpy(card->driver, "Empia Em28xx Audio"); strcpy(card->shortname, "Em28xx Audio"); strcpy(card->longname, "Empia Em28xx Audio"); -- cgit From 0ad675eb4533402fd7b03b25d1d4a0ab7a43ae6d Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 23 Feb 2009 12:11:25 -0300 Subject: V4L/DVB (10663): soc-camera: fix S_CROP breakage on PXA and SuperH Recent format-negotiation patches caused S_CROP breakage in pxa_camera.c and sh_mobile_ceu_camera.c drivers, fix it. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pxa_camera.c | 26 +++++++++++++------------- drivers/media/video/sh_mobile_ceu_camera.c | 13 +++++-------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c index a1d6008efcb..07c334f25aa 100644 --- a/drivers/media/video/pxa_camera.c +++ b/drivers/media/video/pxa_camera.c @@ -1155,23 +1155,23 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, { struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct pxa_camera_dev *pcdev = ici->priv; - const struct soc_camera_data_format *host_fmt, *cam_fmt = NULL; - const struct soc_camera_format_xlate *xlate; + const struct soc_camera_data_format *cam_fmt = NULL; + const struct soc_camera_format_xlate *xlate = NULL; struct soc_camera_sense sense = { .master_clock = pcdev->mclk, .pixel_clock_max = pcdev->ciclk / 4, }; - int ret, buswidth; + int ret; - xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); - if (!xlate) { - dev_warn(&ici->dev, "Format %x not found\n", pixfmt); - return -EINVAL; - } + if (pixfmt) { + xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); + if (!xlate) { + dev_warn(&ici->dev, "Format %x not found\n", pixfmt); + return -EINVAL; + } - buswidth = xlate->buswidth; - host_fmt = xlate->host_fmt; - cam_fmt = xlate->cam_fmt; + cam_fmt = xlate->cam_fmt; + } /* If PCLK is used to latch data from the sensor, check sense */ if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) @@ -1201,8 +1201,8 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, } if (pixfmt && !ret) { - icd->buswidth = buswidth; - icd->current_fmt = host_fmt; + icd->buswidth = xlate->buswidth; + icd->current_fmt = xlate->host_fmt; } return ret; diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 9a2586b07a0..ddcb81d0b81 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c @@ -603,21 +603,18 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd, const struct soc_camera_format_xlate *xlate; int ret; + if (!pixfmt) + return icd->ops->set_fmt(icd, pixfmt, rect); + xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); if (!xlate) { dev_warn(&ici->dev, "Format %x not found\n", pixfmt); return -EINVAL; } - switch (pixfmt) { - case 0: /* Only geometry change */ - ret = icd->ops->set_fmt(icd, pixfmt, rect); - break; - default: - ret = icd->ops->set_fmt(icd, xlate->cam_fmt->fourcc, rect); - } + ret = icd->ops->set_fmt(icd, xlate->cam_fmt->fourcc, rect); - if (pixfmt && !ret) { + if (!ret) { icd->buswidth = xlate->buswidth; icd->current_fmt = xlate->host_fmt; pcdev->camera_fmt = xlate->cam_fmt; -- cgit From 382c5546d618f24dc7d6ae7ca33412083720efbf Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Mon, 23 Feb 2009 06:27:16 -0300 Subject: V4L/DVB (10694): [PATCH] software IRQ watchdog for Flexcop B2C2 DVB PCI cards With (some) Technisat cards you cannot run multiple DVB applications in parallel and switch the channel at the same time. There seems to be a problem on the interfaces or even inside the flexcop-device that can't handle interruption on the streaming interface. This patch adds a watchdog to check whether data is supposed to come in (streaming PIDs are requested) and if no data is seen within 400ms (default) it resets the streaming/pid-filtering hardware. This patch is urgently needed to support the rev 2.8 of the hardware and solves problem occassionally seen on older hardware. Signed-off-by: Uwe Bugla Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/b2c2/flexcop-hw-filter.c | 1 + drivers/media/dvb/b2c2/flexcop-pci.c | 65 +++++++++++++++++++----------- drivers/media/dvb/b2c2/flexcop.c | 3 +- 3 files changed, 44 insertions(+), 25 deletions(-) diff --git a/drivers/media/dvb/b2c2/flexcop-hw-filter.c b/drivers/media/dvb/b2c2/flexcop-hw-filter.c index b386cc66c6b..451974ba32f 100644 --- a/drivers/media/dvb/b2c2/flexcop-hw-filter.c +++ b/drivers/media/dvb/b2c2/flexcop-hw-filter.c @@ -192,6 +192,7 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d return 0; } +EXPORT_SYMBOL(flexcop_pid_feed_control); void flexcop_hw_filter_init(struct flexcop_device *fc) { diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c index 5b30dfc7846..76e37fd96bb 100644 --- a/drivers/media/dvb/b2c2/flexcop-pci.c +++ b/drivers/media/dvb/b2c2/flexcop-pci.c @@ -13,9 +13,9 @@ static int enable_pid_filtering = 1; module_param(enable_pid_filtering, int, 0444); MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1"); -static int irq_chk_intv; +static int irq_chk_intv = 100; module_param(irq_chk_intv, int, 0644); -MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ watchdog (currently just debugging)."); +MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ streaming watchdog."); #ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG #define dprintk(level,args...) \ @@ -34,7 +34,9 @@ MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ watchdog (currently jus static int debug; module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "set debug level (1=info,2=regs,4=TS,8=irqdma (|-able))." DEBSTATUS); +MODULE_PARM_DESC(debug, + "set debug level (1=info,2=regs,4=TS,8=irqdma,16=check (|-able))." + DEBSTATUS); #define DRIVER_VERSION "0.1" #define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver" @@ -58,6 +60,8 @@ struct flexcop_pci { int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */ u32 last_dma1_cur_pos; /* position of the pointer last time the timer/packet irq occured */ int count; + int count_prev; + int stream_problem; spinlock_t irq_lock; @@ -103,18 +107,32 @@ static void flexcop_pci_irq_check_work(struct work_struct *work) container_of(work, struct flexcop_pci, irq_check_work.work); struct flexcop_device *fc = fc_pci->fc_dev; - flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714); - - flexcop_dump_reg(fc_pci->fc_dev,dma1_000,4); - - if (v.sram_dest_reg_714.net_ovflow_error) - deb_chk("sram net_ovflow_error\n"); - if (v.sram_dest_reg_714.media_ovflow_error) - deb_chk("sram media_ovflow_error\n"); - if (v.sram_dest_reg_714.cai_ovflow_error) - deb_chk("sram cai_ovflow_error\n"); - if (v.sram_dest_reg_714.cai_ovflow_error) - deb_chk("sram cai_ovflow_error\n"); + if (fc->feedcount) { + + if (fc_pci->count == fc_pci->count_prev) { + deb_chk("no IRQ since the last check\n"); + if (fc_pci->stream_problem++ == 3) { + struct dvb_demux_feed *feed; + + spin_lock_irq(&fc->demux.lock); + list_for_each_entry(feed, &fc->demux.feed_list, + list_head) { + flexcop_pid_feed_control(fc, feed, 0); + } + + list_for_each_entry(feed, &fc->demux.feed_list, + list_head) { + flexcop_pid_feed_control(fc, feed, 1); + } + spin_unlock_irq(&fc->demux.lock); + + fc_pci->stream_problem = 0; + } + } else { + fc_pci->stream_problem = 0; + fc_pci->count_prev = fc_pci->count; + } + } schedule_delayed_work(&fc_pci->irq_check_work, msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv)); @@ -216,16 +234,12 @@ static int flexcop_pci_stream_control(struct flexcop_device *fc, int onoff) flexcop_dma_control_timer_irq(fc,FC_DMA_1,1); deb_irq("IRQ enabled\n"); + fc_pci->count_prev = fc_pci->count; + // fc_pci->active_dma1_addr = 0; // flexcop_dma_control_size_irq(fc,FC_DMA_1,1); - if (irq_chk_intv > 0) - schedule_delayed_work(&fc_pci->irq_check_work, - msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv)); } else { - if (irq_chk_intv > 0) - cancel_delayed_work(&fc_pci->irq_check_work); - flexcop_dma_control_timer_irq(fc,FC_DMA_1,0); deb_irq("IRQ disabled\n"); @@ -299,8 +313,6 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci) IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0) goto err_pci_iounmap; - - fc_pci->init_state |= FC_PCI_INIT; return ret; @@ -375,6 +387,10 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work); + if (irq_chk_intv > 0) + schedule_delayed_work(&fc_pci->irq_check_work, + msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv)); + return ret; err_fc_exit: @@ -393,6 +409,9 @@ static void flexcop_pci_remove(struct pci_dev *pdev) { struct flexcop_pci *fc_pci = pci_get_drvdata(pdev); + if (irq_chk_intv > 0) + cancel_delayed_work(&fc_pci->irq_check_work); + flexcop_pci_dma_exit(fc_pci); flexcop_device_exit(fc_pci->fc_dev); flexcop_pci_exit(fc_pci); diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c index 676413a915b..91068952b50 100644 --- a/drivers/media/dvb/b2c2/flexcop.c +++ b/drivers/media/dvb/b2c2/flexcop.c @@ -212,8 +212,7 @@ void flexcop_reset_block_300(struct flexcop_device *fc) v210.sw_reset_210.Block_reset_enable = 0xb2; fc->write_ibi_reg(fc,sw_reset_210,v210); - msleep(1); - + udelay(1000); fc->write_ibi_reg(fc,ctrl_208,v208_save); } -- cgit From f5a3258335eef2baf534243da00bcd0e760dd2b5 Mon Sep 17 00:00:00 2001 From: Uwe Bugla Date: Mon, 23 Feb 2009 10:54:20 -0300 Subject: V4L/DVB (10695): Update Technisat card documentation Fixes for documentation of Technisat-based cards Signed-off-by: Uwe Bugla Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- Documentation/dvb/technisat.txt | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/Documentation/dvb/technisat.txt b/Documentation/dvb/technisat.txt index cdf6ee4b2da..3f435ffb289 100644 --- a/Documentation/dvb/technisat.txt +++ b/Documentation/dvb/technisat.txt @@ -1,5 +1,5 @@ -How to set up the Technisat devices -=================================== +How to set up the Technisat/B2C2 Flexcop devices +================================================ 1) Find out what device you have ================================ @@ -16,54 +16,60 @@ DVB: registering frontend 0 (Conexant CX24123/CX24109)... If the Technisat is the only TV device in your box get rid of unnecessary modules and check this one: "Multimedia devices" => "Customise analog and hybrid tuner modules to build" -In this directory uncheck every driver which is activated there. +In this directory uncheck every driver which is activated there (except "Simple tuner support" for case 9 only). Then please activate: 2a) Main module part: a.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" -b.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC PCI" in case of a PCI card OR +b.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC PCI" in case of a PCI card +OR c.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC USB" in case of an USB 1.1 adapter d.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Enable debug for the B2C2 FlexCop drivers" Notice: d.) is helpful for troubleshooting 2b) Frontend module part: -1.) Revision 2.3: +1.) SkyStar DVB-S Revision 2.3: a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" b.)"Multimedia devices" => "Customise DVB frontends" => "Zarlink VP310/MT312/ZL10313 based" -2.) Revision 2.6: +2.) SkyStar DVB-S Revision 2.6: a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" b.)"Multimedia devices" => "Customise DVB frontends" => "ST STV0299 based" -3.) Revision 2.7: +3.) SkyStar DVB-S Revision 2.7: a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" b.)"Multimedia devices" => "Customise DVB frontends" => "Samsung S5H1420 based" c.)"Multimedia devices" => "Customise DVB frontends" => "Integrant ITD1000 Zero IF tuner for DVB-S/DSS" d.)"Multimedia devices" => "Customise DVB frontends" => "ISL6421 SEC controller" -4.) Revision 2.8: +4.) SkyStar DVB-S Revision 2.8: a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" b.)"Multimedia devices" => "Customise DVB frontends" => "Conexant CX24113/CX24128 tuner for DVB-S/DSS" c.)"Multimedia devices" => "Customise DVB frontends" => "Conexant CX24123 based" d.)"Multimedia devices" => "Customise DVB frontends" => "ISL6421 SEC controller" -5.) DVB-T card: +5.) AirStar DVB-T card: a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" b.)"Multimedia devices" => "Customise DVB frontends" => "Zarlink MT352 based" -6.) DVB-C card: +6.) CableStar DVB-C card: a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" b.)"Multimedia devices" => "Customise DVB frontends" => "ST STV0297 based" -7.) ATSC card 1st generation: +7.) AirStar ATSC card 1st generation: a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" b.)"Multimedia devices" => "Customise DVB frontends" => "Broadcom BCM3510" -8.) ATSC card 2nd generation: +8.) AirStar ATSC card 2nd generation: a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" b.)"Multimedia devices" => "Customise DVB frontends" => "NxtWave Communications NXT2002/NXT2004 based" -c.)"Multimedia devices" => "Customise DVB frontends" => "LG Electronics LGDT3302/LGDT3303 based" +c.)"Multimedia devices" => "Customise DVB frontends" => "Generic I2C PLL based tuners" -Author: Uwe Bugla December 2008 +9.) AirStar ATSC card 3rd generation: +a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" +b.)"Multimedia devices" => "Customise DVB frontends" => "LG Electronics LGDT3302/LGDT3303 based" +c.)"Multimedia devices" => "Customise analog and hybrid tuner modules to build" => "Simple tuner support" + +Author: Uwe Bugla February 2009 -- cgit From b391d0f08fb0858f7d2cc034ddcca6cd0545bd7d Mon Sep 17 00:00:00 2001 From: Uwe Bugla Date: Mon, 23 Feb 2009 10:56:11 -0300 Subject: V4L/DVB (10696): Remove outdated README for the flexcop-driver This patch removes an outdated README for the flexcop-driver. Signed-off-by: Uwe Bugla Signed-off-by: Patrick Boettcher Signed-off-by: Mauro Carvalho Chehab --- Documentation/dvb/README.flexcop | 205 --------------------------------------- 1 file changed, 205 deletions(-) delete mode 100644 Documentation/dvb/README.flexcop diff --git a/Documentation/dvb/README.flexcop b/Documentation/dvb/README.flexcop deleted file mode 100644 index 5515469de7c..00000000000 --- a/Documentation/dvb/README.flexcop +++ /dev/null @@ -1,205 +0,0 @@ -This README escorted the skystar2-driver rewriting procedure. It describes the -state of the new flexcop-driver set and some internals are written down here -too. - -This document hopefully describes things about the flexcop and its -device-offsprings. Goal was to write an easy-to-write and easy-to-read set of -drivers based on the skystar2.c and other information. - -Remark: flexcop-pci.c was a copy of skystar2.c, but every line has been -touched and rewritten. - -History & News -============== - 2005-04-01 - correct USB ISOC transfers (thanks to Vadim Catana) - - - - -General coding processing -========================= - -We should proceed as follows (as long as no one complains): - -0) Think before start writing code! - -1) rewriting the skystar2.c with the help of the flexcop register descriptions -and splitting up the files to a pci-bus-part and a flexcop-part. -The new driver will be called b2c2-flexcop-pci.ko/b2c2-flexcop-usb.ko for the -device-specific part and b2c2-flexcop.ko for the common flexcop-functions. - -2) Search for errors in the leftover of flexcop-pci.c (compare with pluto2.c -and other pci drivers) - -3) make some beautification (see 'Improvements when rewriting (refactoring) is -done') - -4) Testing the new driver and maybe substitute the skystar2.c with it, to reach -a wider tester audience. - -5) creating an usb-bus-part using the already written flexcop code for the pci -card. - -Idea: create a kernel-object for the flexcop and export all important -functions. This option saves kernel-memory, but maybe a lot of functions have -to be exported to kernel namespace. - - -Current situation -================= - -0) Done :) -1) Done (some minor issues left) -2) Done -3) Not ready yet, more information is necessary -4) next to be done (see the table below) -5) USB driver is working (yes, there are some minor issues) - -What seems to be ready? ------------------------ - -1) Rewriting -1a) i2c is cut off from the flexcop-pci.c and seems to work -1b) moved tuner and demod stuff from flexcop-pci.c to flexcop-tuner-fe.c -1c) moved lnb and diseqc stuff from flexcop-pci.c to flexcop-tuner-fe.c -1e) eeprom (reading MAC address) -1d) sram (no dynamic sll size detection (commented out) (using default as JJ told me)) -1f) misc. register accesses for reading parameters (e.g. resetting, revision) -1g) pid/mac filter (flexcop-hw-filter.c) -1i) dvb-stuff initialization in flexcop.c (done) -1h) dma stuff (now just using the size-irq, instead of all-together, to be done) -1j) remove flexcop initialization from flexcop-pci.c completely (done) -1l) use a well working dma IRQ method (done, see 'Known bugs and problems and TODO') -1k) cleanup flexcop-files (remove unused EXPORT_SYMBOLs, make static from -non-static where possible, moved code to proper places) - -2) Search for errors in the leftover of flexcop-pci.c (partially done) -5a) add MAC address reading -5c) feeding of ISOC data to the software demux (format of the isochronous data -and speed optimization, no real error) (thanks to Vadim Catana) - -What to do in the near future? --------------------------------------- -(no special order here) - -5) USB driver -5b) optimize isoc-transfer (submitting/killing isoc URBs when transfer is starting) - -Testing changes ---------------- - -O = item is working -P = item is partially working -X = item is not working -N = item does not apply here - = item need to be examined - - | PCI | USB -item | mt352 | nxt2002 | stv0299 | mt312 | mt352 | nxt2002 | stv0299 | mt312 --------+-------+---------+---------+-------+-------+---------+---------+------- -1a) | O | | | | N | N | N | N -1b) | O | | | | | | O | -1c) | N | N | | | N | N | O | -1d) | O | O -1e) | O | O -1f) | P -1g) | O -1h) | P | -1i) | O | N -1j) | O | N -1l) | O | N -2) | O | N -5a) | N | O -5b)* | N | -5c) | N | O - -* - not done yet - -Known bugs and problems and TODO --------------------------------- - -1g/h/l) when pid filtering is enabled on the pci card - -DMA usage currently: - The DMA is splitted in 2 equal-sized subbuffers. The Flexcop writes to first - address and triggers an IRQ when it's full and starts writing to the second - address. When the second address is full, the IRQ is triggered again, and - the flexcop writes to first address again, and so on. - The buffersize of each address is currently 640*188 bytes. - - Problem is, when using hw-pid-filtering and doing some low-bandwidth - operation (like scanning) the buffers won't be filled enough to trigger - the IRQ. That's why: - - When PID filtering is activated, the timer IRQ is used. Every 1.97 ms the IRQ - is triggered. Is the current write address of DMA1 different to the one - during the last IRQ, then the data is passed to the demuxer. - - There is an additional DMA-IRQ-method: packet count IRQ. This isn't - implemented correctly yet. - - The solution is to disable HW PID filtering, but I don't know how the DVB - API software demux behaves on slow systems with 45MBit/s TS. - -Solved bugs :) --------------- -1g) pid-filtering (somehow pid index 4 and 5 (EMM_PID and ECM_PID) aren't -working) -SOLUTION: also index 0 was affected, because net_translation is done for -these indexes by default - -5b) isochronous transfer does only work in the first attempt (for the Sky2PC -USB, Air2PC is working) SOLUTION: the flexcop was going asleep and never really -woke up again (don't know if this need fixes, see -flexcop-fe-tuner.c:flexcop_sleep) - -NEWS: when the driver is loaded and unloaded and loaded again (w/o doing -anything in the while the driver is loaded the first time), no transfers take -place anymore. - -Improvements when rewriting (refactoring) is done -================================================= - -- split sleeping of the flexcop (misc_204.ACPI3_sig = 1;) from lnb_control - (enable sleeping for other demods than dvb-s) -- add support for CableStar (stv0297 Microtune 203x/ALPS) (almost done, incompatibilities with the Nexus-CA) - -Debugging ---------- -- add verbose debugging to skystar2.c (dump the reg_dw_data) and compare it - with this flexcop, this is important, because i2c is now using the - flexcop_ibi_value union from flexcop-reg.h (do you have a better idea for - that, please tell us so). - -Everything which is identical in the following table, can be put into a common -flexcop-module. - - PCI USB -------------------------------------------------------------------------------- -Different: -Register access: accessing IO memory USB control message -I2C bus: I2C bus of the FC USB control message -Data transfer: DMA isochronous transfer -EEPROM transfer: through i2c bus not clear yet - -Identical: -Streaming: accessing registers -PID Filtering: accessing registers -Sram destinations: accessing registers -Tuner/Demod: I2C bus -DVB-stuff: can be written for common use - -Acknowledgements (just for the rewriting part) -================ - -Bjarne Steinsbo thought a lot in the first place of the pci part for this code -sharing idea. - -Andreas Oberritter for providing a recent PCI initialization template -(pluto2.c). - -Boleslaw Ciesielski for pointing out a problem with firmware loader. - -Vadim Catana for correcting the USB transfer. - -comments, critics and ideas to linux-dvb@linuxtv.org. -- cgit From 9b58027bc23a73a036877f28422dad7a0a199f95 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 26 Feb 2009 21:02:19 -0800 Subject: net: fix hp-plus build error hp-plus needs to call __alloc_eip_netdev() instead of __alloc_ei_netdev() since it is linked with 8390p.o. Fixes this build error: ERROR: "__alloc_ei_netdev" [drivers/net/hp-plus.ko] undefined! Signed-off-by: Randy Dunlap Signed-off-by: David S. Miller --- drivers/net/hp-plus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c index 5e070f44663..0486cbe01ad 100644 --- a/drivers/net/hp-plus.c +++ b/drivers/net/hp-plus.c @@ -467,7 +467,7 @@ init_module(void) if (this_dev != 0) break; /* only autoprobe 1st one */ printk(KERN_NOTICE "hp-plus.c: Presently autoprobing (not recommended) for a single card.\n"); } - dev = alloc_ei_netdev(); + dev = alloc_eip_netdev(); if (!dev) break; dev->irq = irq[this_dev]; -- cgit From f8af11af85fecbfa7b95fd79c043b16ae0ee0d55 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Thu, 26 Feb 2009 22:33:00 -0800 Subject: b44: Unconditionally enable interrupt routing on reset Unconditionally setup the IRQ routing on chip reset. It's safe to call ssb_pcicore_dev_irqvecs_enable() unconditionally, because it has internal checks for redundant calls. This fixes problems where hardware will not come up properly due to quirks in the enable-bit hardware. Reported-by: Pantelis Koukousoulas Signed-off-by: Michael Buesch Signed-off-by: David S. Miller --- drivers/net/b44.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/b44.c b/drivers/net/b44.c index c38512ebcea..6b8c39f2cf1 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -1264,8 +1264,14 @@ static void b44_clear_stats(struct b44 *bp) static void b44_chip_reset(struct b44 *bp, int reset_kind) { struct ssb_device *sdev = bp->sdev; + bool was_enabled; - if (ssb_device_is_enabled(bp->sdev)) { + was_enabled = ssb_device_is_enabled(bp->sdev); + + ssb_device_enable(bp->sdev, 0); + ssb_pcicore_dev_irqvecs_enable(&sdev->bus->pcicore, sdev); + + if (was_enabled) { bw32(bp, B44_RCV_LAZY, 0); bw32(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE); b44_wait_bit(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE, 200, 1); @@ -1277,10 +1283,8 @@ static void b44_chip_reset(struct b44 *bp, int reset_kind) } bw32(bp, B44_DMARX_CTRL, 0); bp->rx_prod = bp->rx_cons = 0; - } else - ssb_pcicore_dev_irqvecs_enable(&sdev->bus->pcicore, sdev); + } - ssb_device_enable(bp->sdev, 0); b44_clear_stats(bp); /* -- cgit From e92aa634a33739478958f4109d6bd35b36d13532 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Thu, 26 Feb 2009 22:35:02 -0800 Subject: b44: Disable device on shutdown Disable the SSB core on device shutdown. This has two advantages: 1) A clean device shutdown is always desired here, because we disable the device's global crystal in the next statement. 2) This fixes a bug where the device will come up with the enable-bit set on the next initialization (without a reboot inbetween). This causes breakage on the second initialization due to code that checks this bit (ssb_device_is_enabled() checks). Reported-by: Pantelis Koukousoulas Signed-off-by: Michael Buesch Signed-off-by: David S. Miller --- drivers/net/b44.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 6b8c39f2cf1..dc5f051005f 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -2240,6 +2240,7 @@ static void __devexit b44_remove_one(struct ssb_device *sdev) struct net_device *dev = ssb_get_drvdata(sdev); unregister_netdev(dev); + ssb_device_disable(sdev, 0); ssb_bus_may_powerdown(sdev->bus); free_netdev(dev); ssb_pcihost_set_power_state(sdev, PCI_D3hot); -- cgit From 08c2f5b4d76f83213e379b12df504269d21c9e7c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 27 Feb 2009 15:41:14 +0900 Subject: sh: ap325rxa: Revert ov772x support. This change depends on some v4l changes that have been pushed back to 2.6.30, so drop this and fall back on the old soc_camera code until then. Reported-by: Nobuhiro Iwamatsu Acked-by: Kuninori Morimoto Signed-off-by: Paul Mundt --- arch/sh/boards/board-ap325rxa.c | 53 +++-------------------------------------- 1 file changed, 3 insertions(+), 50 deletions(-) diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/board-ap325rxa.c index 7c35787d29b..72da416f616 100644 --- a/arch/sh/boards/board-ap325rxa.c +++ b/arch/sh/boards/board-ap325rxa.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include